diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000000..9ffc7f9619b --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,40 @@ +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +FROM mcr.microsoft.com/dotnet/core/sdk:3.1 + +# Avoid warnings by switching to noninteractive +ENV DEBIAN_FRONTEND=noninteractive + +# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" +# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs +# will be updated to match your local UID/GID (when using the dockerFile property). +# See https://aka.ms/vscode-remote/containers/non-root-user for details. +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Configure apt and install packages +RUN apt-get update \ + && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \ + # + # Verify git, process tools, lsb-release (common in install instructions for CLIs) installed + && apt-get -y install git openssh-client less iproute2 procps lsb-release \ + # + # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. + && groupadd --gid $USER_GID $USERNAME \ + && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ + # [Optional] Add sudo support for the non-root user + && apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ + && chmod 0440 /etc/sudoers.d/$USERNAME \ + # + # Clean up + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +# Switch back to dialog for any ad-hoc use of apt-get +ENV DEBIAN_FRONTEND=dialog diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..970a9ca1c00 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.108.0/containers/dotnetcore-3.1-fsharp +{ + "name": "F# (.NET Core 3.1)", + "dockerFile": "Dockerfile", + + // Set *default* container specific settings.json values on container create. + // + // .NET Core is now the default for F# in .NET Core 3.0+ + // However, .NET Core scripting is not the default yet. Set that to true. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "FSharp.useSdkScripts":true, + "editor.trimAutoWhitespace": false, + "files.trimTrailingWhitespace": false, + "FSharp.suggestGitignore": false, + "FSharp.workspacePath": "FSharp.sln" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "Ionide.Ionide-fsharp", + "ms-dotnettools.csharp" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "./build.sh", + + // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" +} diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 0a66fd8d385..1397683d28c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -8,13 +8,21 @@ assignees: '' --- **Is your feature request related to a problem? Please describe.** + A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** + A clear and concise description of what you want to happen. **Describe alternatives you've considered** + A clear and concise description of any alternative solutions or features you've considered. **Additional context** + +If the issue is about: +* improving a compiler error message, please mention "related: #1103" +* improving/adjusting the parser, please mention "related: #11481" + Add any other context or screenshots about the feature request here. diff --git a/.gitignore b/.gitignore index 7f3870c3d05..9dfe3200c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # output location artifacts/ +BenchmarkDotNet.Artifacts/ /tests/scripts/current .dotnet/ @@ -9,43 +10,21 @@ artifacts/ # Patches that may have been generated by scripts. # (These aren't generally useful to commit directly; if anything, they should be applied.) scripts/*.patch -/fcs/FSharp.Compiler.Service/illex.fs -/fcs/FSharp.Compiler.Service/ilpars.fs -/fcs/FSharp.Compiler.Service/ilpars.fsi -/fcs/FSharp.Compiler.Service/lex.fs -/fcs/FSharp.Compiler.Service/pars.fs -/fcs/FSharp.Compiler.Service/pars.fsi -/fcs/FSharp.Compiler.Service/pplex.fs -/fcs/FSharp.Compiler.Service/pppars.fs -/fcs/FSharp.Compiler.Service/pppars.fsi /src/*.userprefs /src/fsharp/FSStrings.resources /src/fsharp/FSharp.Build/*.resx -/src/fsharp/FSharp.Build-proto/*.resx -/src/fsharp/FSharp.Build-proto/*.resources -/src/fsharp/FSharp.Compiler-proto/*.resx -/src/fsharp/FSharp.Compiler-proto/*.resources -/src/fsharp/FSharp.Compiler-proto/*.sln -/src/fsharp/FSharp.Compiler-proto/*.userprefs /src/fsharp/fsi/*.resx /src/fsharp/FSharp.Compiler.Interactive.Settings/*.resx /src/fsharp/FSharp.Compiler.Server.Shared/*.resx /src/fsharp/fsi/Fsi.sln /src/fsharp/FSharp.Build/*.resources -/src/fsharp/FSharp.Compiler.Private/*.resx -/src/fsharp/FSharp.Compiler.Private/*.resources -/src/fsharp/FSharp.Compiler.Private/*.sln -/src/fsharp/FSharp.Compiler.Private/*.userprefs +/src/fsharp/FSharp.Compiler.Service/*.resx +/src/fsharp/FSharp.Compiler.Service/*.resources +/src/fsharp/FSharp.Compiler.Service/*.sln +/src/fsharp/FSharp.Compiler.Service/*.userprefs +/src/fsharp/FSharp.Compiler.Service/StandardOutput.txt +/src/fsharp/FSharp.Compiler.Service/StandardError.txt /src/*.log -/src/fsharp/Fsc-proto/illex.fs -/src/fsharp/Fsc-proto/ilpars.fs -/src/fsharp/Fsc-proto/ilpars.fsi -/src/fsharp/Fsc-proto/lex.fs -/src/fsharp/Fsc-proto/pars.fs -/src/fsharp/Fsc-proto/pars.fsi -/src/fsharp/Fsc-proto/pplex.fs -/src/fsharp/Fsc-proto/pppars.fs -/src/fsharp/Fsc-proto/pppars.fsi /src/fsharp/FSharp.LanguageService.Compiler/illex.* /src/fsharp/FSharp.LanguageService.Compiler/ilpars.* /src/fsharp/FSharp.LanguageService.Compiler/lex.* @@ -53,6 +32,7 @@ scripts/*.patch /src/fsharp/FSharp.LanguageService.Compiler/pplex.fs /src/fsharp/FSharp.LanguageService.Compiler/pppars.fs /src/fsharp/FSharp.LanguageService.Compiler/pppars.fsi +/src/fsharp/*/Properties/launchSettings.json /vsintegration/src/unittests/Unittests.fsi /tests/*FSharp_Failures.env /tests/*FSharp_Failures.lst @@ -130,3 +110,17 @@ msbuild.binlog /fcs/FSharp.Compiler.Service.netstandard/*.fsi /.ionide/ **/.DS_Store +/tests/fsharp/regression/5531/compilation.output.test.txt +/tests/fsharp/core/fsfromfsviacs/compilation.langversion.old.output.txt +/tests/fsharp/core/fsfromfsviacs/compilation.errors.output.txt +*ncrunch*.user +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +.idea +/tests/fsharp/core/members/set-only-property/vb.dll +/tests/fsharp/core/members/set-only-property/fs.dll +/tests/fsharp/core/members/set-only-property/cs.dll + +.fake \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 0546015eee9..00000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}/lkg/fsc/bin/Debug/netcoreapp1.0/fsc.dll", - "args": [], - "cwd": "${workspaceRoot}", - "externalConsole": false, - "stopAtEntry": false, - "internalConsoleOptions": "openOnSessionStart" - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "processId": "${command.pickProcess}" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..48e4d8b9fb2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.trimAutoWhitespace": false, + "files.trimTrailingWhitespace": false, + "FSharp.suggestGitignore": false, + "FSharp.workspacePath": "FSharp.sln", + "dotnet-test-explorer.testProjectPath": "tests/*Tests/" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 9c103be70d4..00000000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [ - "${workspaceRoot}/lkg/fsc/project.json" - ], - "isBuildCommand": true, - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/.vsconfig b/.vsconfig index 302d9808902..f08811fff53 100644 --- a/.vsconfig +++ b/.vsconfig @@ -8,8 +8,6 @@ "Microsoft.VisualStudio.Component.Roslyn.Compiler", "Microsoft.VisualStudio.Component.Roslyn.LanguageServices", "Microsoft.VisualStudio.Component.FSharp", - "Microsoft.Net.Core.Component.SDK.2.1", - "Microsoft.NetCore.ComponentGroup.DevelopmentTools.2.1", "Microsoft.Net.Component.4.7.2.SDK", "Microsoft.Net.Component.4.7.2.TargetingPack", "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites", diff --git a/BenchmarkDotNet.Artifacts/results/TaskPerf.Benchmarks-report-github.md b/BenchmarkDotNet.Artifacts/results/TaskPerf.Benchmarks-report-github.md new file mode 100644 index 00000000000..6cce7d6b240 --- /dev/null +++ b/BenchmarkDotNet.Artifacts/results/TaskPerf.Benchmarks-report-github.md @@ -0,0 +1,67 @@ +``` ini + +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +Intel Xeon CPU E5-1620 0 3.60GHz, 1 CPU, 8 logical and 4 physical cores +.NET Core SDK=5.0.104 + [Host] : .NET Core 5.0.6 (CoreCLR 5.0.621.22011, CoreFX 5.0.621.22011), X64 RyuJIT DEBUG + DefaultJob : .NET Core 5.0.6 (CoreCLR 5.0.621.22011, CoreFX 5.0.621.22011), X64 RyuJIT + + +``` +| Method | Categories | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------------------------------- |----------------------- |---------------:|--------------:|--------------:|---------------:|-------:|--------:|-----------:|--------:|------:|------------:| +| ManyWriteFile_CSharpTasks | ManyWriteFile | 4,186.6 μs | 81.32 μs | 201.00 μs | 4,187.4 μs | 1.00 | 0.00 | 15.6250 | - | - | 117288 B | +| ManyWriteFile_taskBuilder | ManyWriteFile | 5,744.5 μs | 124.34 μs | 356.76 μs | 5,712.3 μs | 1.38 | 0.11 | 62.5000 | - | - | 444882 B | +| ManyWriteFile_async | ManyWriteFile | 6,108.8 μs | 121.27 μs | 271.23 μs | 6,132.1 μs | 1.46 | 0.10 | 132.8125 | - | - | 704991 B | +| ManyWriteFile_task | ManyWriteFile | 5,014.3 μs | 100.18 μs | 204.65 μs | 4,973.0 μs | 1.19 | 0.07 | 15.6250 | - | - | 116996 B | +| ManyWriteFile_async2 | ManyWriteFile | 5,358.4 μs | 106.05 μs | 211.79 μs | 5,374.1 μs | 1.27 | 0.07 | 15.6250 | - | - | 117140 B | +| | | | | | | | | | | | | +| NonAsyncBinds_CSharpTasks | NonAsyncBinds | 17,444.8 μs | 374.32 μs | 1,097.80 μs | 17,030.4 μs | 1.00 | 0.00 | 15125.0000 | - | - | 79200000 B | +| NonAsyncBinds_taskBuilder | NonAsyncBinds | 26,000.1 μs | 440.68 μs | 880.09 μs | 25,621.3 μs | 1.47 | 0.09 | 22187.5000 | - | - | 116000000 B | +| NonAsyncBinds_async | NonAsyncBinds | 1,303,920.2 μs | 63,453.67 μs | 177,930.90 μs | 1,269,891.9 μs | 74.52 | 10.59 | 52000.0000 | - | - | 276000000 B | +| NonAsyncBinds_async2 | NonAsyncBinds | 24,213.0 μs | 191.23 μs | 178.88 μs | 24,168.6 μs | 1.38 | 0.09 | 18812.5000 | 62.5000 | - | 98400000 B | +| NonAsyncBinds_task | NonAsyncBinds | 16,693.5 μs | 302.84 μs | 759.75 μs | 16,586.1 μs | 0.95 | 0.07 | 15125.0000 | - | - | 79200000 B | +| | | | | | | | | | | | | +| AsyncBinds_CSharpTasks | AsyncBinds | 8,335.4 μs | 190.47 μs | 558.61 μs | 8,197.5 μs | 1.00 | 0.00 | 15.6250 | - | - | 112119 B | +| AsyncBinds_taskBuilder | AsyncBinds | 11,567.6 μs | 229.28 μs | 522.18 μs | 11,360.0 μs | 1.39 | 0.12 | 296.8750 | - | - | 1559252 B | +| AsyncBinds_async | AsyncBinds | 127,872.2 μs | 3,090.27 μs | 8,866.56 μs | 127,900.8 μs | 15.38 | 1.47 | 1333.3333 | - | - | 8312000 B | +| AsyncBinds_task | AsyncBinds | 9,897.9 μs | 314.55 μs | 927.46 μs | 10,058.4 μs | 1.19 | 0.15 | 31.2500 | - | - | 192096 B | +| AsyncBinds_async2 | AsyncBinds | 8,165.2 μs | 156.64 μs | 347.09 μs | 8,051.9 μs | 0.98 | 0.07 | 62.5000 | - | - | 352218 B | +| | | | | | | | | | | | | +| SingleSyncTask_CSharpTasks | SingleSyncTask | 8,668.5 μs | 170.65 μs | 233.59 μs | 8,595.4 μs | 1.00 | 0.00 | - | - | - | - | +| SingleSyncTask_taskBuilder | SingleSyncTask | 12,402.4 μs | 103.89 μs | 92.10 μs | 12,366.7 μs | 1.43 | 0.04 | 9171.8750 | - | - | 48000000 B | +| SingleSyncTask_async | SingleSyncTask | 3,659,569.1 μs | 109,062.88 μs | 298,557.86 μs | 3,576,228.4 μs | 409.11 | 38.68 | 91000.0000 | - | - | 475999216 B | +| SingleSyncTask_task | SingleSyncTask | 10,642.1 μs | 90.05 μs | 84.23 μs | 10,622.2 μs | 1.23 | 0.04 | - | - | - | - | +| SingleSyncTask_async2 | SingleSyncTask | 28,177.5 μs | 263.90 μs | 220.37 μs | 28,134.6 μs | 3.25 | 0.08 | 7625.0000 | - | - | 40000000 B | +| | | | | | | | | | | | | +| SyncBuilderLoop_NormalCode | sync | 81,206.3 μs | 1,598.95 μs | 1,570.38 μs | 80,813.7 μs | 1.00 | 0.00 | 36714.2857 | - | - | 192176000 B | +| SyncBuilderLoop_WorkflowCode | sync | 81,811.3 μs | 1,610.38 μs | 3,140.93 μs | 80,621.9 μs | 1.02 | 0.05 | 36714.2857 | - | - | 192176000 B | +| | | | | | | | | | | | | +| TinyVariableSizedList_Builtin | TinyVariableSizedList | 57,762.3 μs | 1,721.40 μs | 4,827.00 μs | 56,313.5 μs | 1.00 | 0.00 | 20375.0000 | - | - | 106666656 B | +| TinyVariableSizedList_NewBuilder | TinyVariableSizedList | 17,122.1 μs | 341.76 μs | 650.23 μs | 17,233.0 μs | 0.29 | 0.03 | 2031.2500 | - | - | 10666656 B | +| | | | | | | | | | | | | +| VariableSizedList_Builtin | VariableSizedList | 330,273.8 μs | 6,534.98 μs | 13,051.05 μs | 328,659.3 μs | 1.00 | 0.00 | 63000.0000 | - | - | 330666624 B | +| VariableSizedList_NewBuilder | VariableSizedList | 167,451.6 μs | 2,840.89 μs | 2,217.98 μs | 167,326.7 μs | 0.51 | 0.02 | 44750.0000 | - | - | 234666934 B | +| | | | | | | | | | | | | +| FixedSizeList_Builtin | FixedSizedList | 100,128.5 μs | 1,968.29 μs | 3,885.21 μs | 100,084.8 μs | 1.00 | 0.00 | 61166.6667 | - | - | 320000000 B | +| FixedSizeList_NewBuilder | FixedSizedList | 229,639.0 μs | 4,589.37 μs | 11,846.63 μs | 227,278.1 μs | 2.30 | 0.13 | 61000.0000 | - | - | 320000000 B | +| | | | | | | | | | | | | +| TinyVariableSizedArray_Builtin | TinyVariableSizedArray | 100,414.3 μs | 1,995.07 μs | 4,462.26 μs | 100,631.3 μs | 1.00 | 0.00 | 30000.0000 | - | - | 157333304 B | +| TinyVariableSizedArray_NewBuilder | TinyVariableSizedArray | 28,538.5 μs | 632.86 μs | 1,825.93 μs | 28,426.7 μs | 0.29 | 0.02 | 10687.5000 | - | - | 55999968 B | +| | | | | | | | | | | | | +| VariableSizedArray_Builtin | VariableSizedArray | 356,489.5 μs | 3,061.89 μs | 2,714.29 μs | 356,174.5 μs | 1.00 | 0.00 | 77000.0000 | - | - | 405333840 B | +| VariableSizedArray_NewBuilder | VariableSizedArray | 161,909.3 μs | 861.02 μs | 672.23 μs | 161,860.8 μs | 0.45 | 0.00 | 59000.0000 | - | - | 309333476 B | +| | | | | | | | | | | | | +| FixedSizeArray_Builtin | FixedSizedArray | 32,944.8 μs | 777.85 μs | 2,293.52 μs | 32,391.8 μs | 1.00 | 0.00 | 19875.0000 | - | - | 104000000 B | +| FixedSizeArray_NewBuilder | FixedSizedArray | 219,352.6 μs | 4,288.40 μs | 10,837.34 μs | 217,830.4 μs | 6.65 | 0.60 | 82333.3333 | - | - | 432000000 B | +| | | | | | | | | | | | | +| MultiStepOption_OldBuilder | MultiStepOption | 63,360.5 μs | 1,199.04 μs | 1,062.92 μs | 63,133.5 μs | 1.00 | 0.00 | 38750.0000 | - | - | 202666703 B | +| MultiStepOption_NewBuilder | MultiStepOption | 20,179.8 μs | 622.44 μs | 1,775.86 μs | 19,705.5 μs | 0.29 | 0.02 | 13437.5000 | - | - | 70399968 B | +| MultiStepOption_NoBuilder | MultiStepOption | 19,727.8 μs | 469.72 μs | 1,362.75 μs | 19,395.3 μs | 0.32 | 0.02 | 13437.5000 | - | - | 70399968 B | +| | | | | | | | | | | | | +| MultiStepValueOption_OldBuilder | MultiStepValueOption | 47,237.3 μs | 909.93 μs | 759.83 μs | 47,211.0 μs | 1.00 | 0.00 | 19090.9091 | - | - | 100266664 B | +| MultiStepValueOption_NewBuilder | MultiStepValueOption | 4,144.6 μs | 46.31 μs | 43.32 μs | 4,146.1 μs | 0.09 | 0.00 | - | - | - | - | +| MultiStepValueOption_NoBuilder | MultiStepValueOption | 3,824.0 μs | 75.26 μs | 73.92 μs | 3,806.3 μs | 0.08 | 0.00 | - | - | - | - | +| | | | | | | | | | | | | +| NestedForLoops_taskSeqUsingRawResumableCode | taskSeq | 983.7 μs | 18.23 μs | 17.90 μs | 984.7 μs | 1.61 | 0.04 | 54.6875 | - | - | 295641 B | +| NestedForLoops_CSharpAsyncEnumerable | taskSeq | 612.9 μs | 10.04 μs | 8.90 μs | 615.5 μs | 1.00 | 0.00 | 24.4141 | - | - | 131280 B | diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1c658245edb..775f221c98e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,46 +1,6 @@ -# Contributor Covenant Code of Conduct +# Code of Conduct -## Our Pledge +This project has adopted the code of conduct defined by the Contributor Covenant +to clarify expected behavior in our community. -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at opensource@microsoft.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version] - -[homepage]: https://contributor-covenant.org -[version]: https://contributor-covenant.org/version/1/4/ +For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). diff --git a/DEVGUIDE.md b/DEVGUIDE.md index 5c6f51c3c8e..a67b107d600 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -10,6 +10,11 @@ We recommend the following overall workflow when developing for this repository: * Always work in your fork * Always keep your fork up to date +Before updating your fork, run this command: +``` +git remote add upstream https://github.com/dotnet/fsharp.git +``` + This will make management of multiple forks and your own work easier over time. ## Updating your fork @@ -17,35 +22,37 @@ This will make management of multiple forks and your own work easier over time. We recommend the following commands to update your fork: ``` -git checkout master +git checkout main git clean -xdf git fetch upstream -git rebase upstream/master +git rebase upstream/main git push ``` Or more succinctly: ``` -git checkout master && git clean -xdf && git fetch upstream && git rebase upstream/master && git push +git checkout main && git clean -xdf && git fetch upstream && git rebase upstream/main && git push ``` This will update your fork with the latest from `dotnet/fsharp` on your machine and push those updates to your remote fork. ## Developing on Windows -Install the latest released [Visual Studio](https://www.visualstudio.com/downloads/), as that is what the `master` branch's tools are synced with. Select the following workloads: +Install the latest released [Visual Studio](https://www.visualstudio.com/downloads/), as that is what the `main` branch's tools are synced with. Select the following workloads: * .NET desktop development (also check F# desktop support, as this will install some legacy templates) * Visual Studio extension development +You will also need the latest .NET 5 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/5.0). + Building is simple: build.cmd Desktop tests can be run with: - build.cmd -test + build.cmd -test -c Release After you build the first time you can open and use this solution in Visual Studio: @@ -55,16 +62,6 @@ If you don't have everything installed yet, you'll get prompted by Visual Studio If you are just developing the core compiler and library then building ``FSharp.sln`` will be enough. -### Developing the F# Compiler (Linux/macOS) - -For Linux/Mac: - - ./build.sh - -Running tests: - - ./build.sh --test - We recommend installing the latest released Visual Studio and using that if you are on Windows. However, if you prefer not to do that, you will need to install the following: * [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472) @@ -90,15 +87,19 @@ You can then open `FSharp.sln` in your editor of choice. ## Testing from the command line -You can find all test options as separate flags. For example: +You can find all test options as separate flags. For example `build -testAll`: ``` -build -testDesktop -- test all net472 target frameworks -build -testCoreClr -- test all netstandard and netcoreapp target frameworks -build -testFSharpQA -- test all F# Cambridge tests -build -testVs -- test all VS integration points -build -testFcs -- test F# compiler service components -build -testAll -- all of the above + -testAll Run all tests + -testCambridge Run Cambridge tests + -testCompiler Run FSharpCompiler unit tests + -testCompilerService Run FSharpCompilerService unit tests + -testDesktop Run tests against full .NET Framework + -testCoreClr Run tests against CoreCLR + -testFSharpCore Run FSharpCore unit tests + -testFSharpQA Run F# Cambridge tests + -testScripting Run Scripting tests + -testVs Run F# editor unit tests ``` Running any of the above will build the latest changes and run tests against them. @@ -107,8 +108,8 @@ Running any of the above will build the latest changes and run tests against the If your changes involve modifying the list of language keywords in any way, (e.g. when implementing a new keyword), the XLF localization files need to be synced with the corresponding resx files. This can be done automatically by running - pushd src\fsharp\FSharp.Compiler.Private - msbuild FSharp.Compiler.Private.fsproj /t:UpdateXlf + pushd src\fsharp\FSharp.Compiler.Service + msbuild FSharp.Compiler.Service.fsproj /t:UpdateXlf popd This only works on Windows/.NETStandard framework, so changing this from any other platform requires editing and syncing all of the XLF files manually. @@ -121,7 +122,7 @@ See (DEVGUIDE.md#Developing on Windows) for instructions to install what is need ### Quickly see your changes locally -First, ensure that `VisualFSharpFull` is the startup project. +First, ensure that `VisualFSharpDebug` is the startup project. Then, use the **f5** or **ctrl+f5** keyboard shortcuts to test your tooling changes. The former will debug a new instance of Visual Studio. The latter will launch a new instance of Visual Studio, but with your changes installed. @@ -135,7 +136,7 @@ If you'd like to "run with your changes", you can produce a VSIX and install it ``` VSIXInstaller.exe /u:"VisualFSharp" -VSIXInstaller.exe artifacts\VSSetup\Release\VisualFSharpFull.vsix +VSIXInstaller.exe artifacts\VSSetup\Release\VisualFSharpDebug.vsix ``` It's important to use `Release` if you want to see if your changes have had a noticeable performance impact. @@ -161,7 +162,7 @@ Where `` corresponds to the latest Visual Studio version on your machin ## Additional resources -The primary technical guide to the core compiler code is [The F# Compiler Technical Guide](https://fsharp.github.io/2015/09/29/fsharp-compiler-guide.html). Please read and contribute to that guide. +The primary technical guide to the core compiler code is [The F# Compiler Technical Guide](https://github.com/dotnet/fsharp/blob/main/docs/compiler-guide.md). Please read and contribute to that guide. See the "Debugging The Compiler" section of this [article](https://medium.com/@willie.tetlow/f-mentorship-week-1-36f51d3812d4) for some examples. @@ -169,9 +170,4 @@ See the "Debugging The Compiler" section of this [article](https://medium.com/@w If you are behind a proxy server, NuGet client tool must be configured to use it: -``` -.nuget\nuget.exe config -set http_proxy=proxy.domain.com:8080 -ConfigFile NuGet.Config -.nuget\nuget.exe config -set http_proxy.user=user_name -ConfigFile NuGet.Config -.nuget\nuget.exe config -set http_proxy.password=user_password -ConfigFile NuGet.Config -``` -Where you should set proper proxy address, user name and password. +See the Nuget config file documention for use with a proxy server [https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file) diff --git a/Directory.Build.targets b/Directory.Build.targets index 08da3ab0966..7b7a6a7a80a 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -2,4 +2,15 @@ + + + + + + + + + + + diff --git a/FSharp.Profiles.props b/FSharp.Profiles.props index 65cfa205e64..260bccd3bf9 100644 --- a/FSharp.Profiles.props +++ b/FSharp.Profiles.props @@ -2,25 +2,28 @@ - - $(DefineConstants);CROSS_PLATFORM_COMPILER - $(DefineConstants);ENABLE_MONO_SUPPORT - - - - $(DefineConstants);NETSTANDARD - $(DefineConstants);FX_NO_APP_DOMAINS - $(DefineConstants);FX_NO_CORHOST_SIGNER - $(DefineConstants);FX_NO_PDB_READER - $(DefineConstants);FX_NO_PDB_WRITER - $(DefineConstants);FX_NO_SYMBOLSTORE - $(DefineConstants);FX_NO_SYSTEM_CONFIGURATION - $(DefineConstants);FX_NO_WIN_REGISTRY - $(DefineConstants);FX_NO_WINFORMS - $(DefineConstants);FX_NO_INDENTED_TEXT_WRITER - $(DefineConstants);FX_RESHAPED_REFEMIT - $(DefineConstants);FX_RESHAPED_MSBUILD - $(OtherFlags) --simpleresolution - + + + + $(DefineConstants);CROSS_PLATFORM_COMPILER + $(DefineConstants);ENABLE_MONO_SUPPORT + + + + + $(DefineConstants);NETSTANDARD + $(DefineConstants);FX_NO_APP_DOMAINS + $(DefineConstants);FX_NO_CORHOST_SIGNER + $(DefineConstants);FX_NO_PDB_READER + $(DefineConstants);FX_NO_PDB_WRITER + $(DefineConstants);FX_NO_SYMBOLSTORE + $(DefineConstants);FX_NO_SYSTEM_CONFIGURATION + $(DefineConstants);FX_NO_WIN_REGISTRY + $(DefineConstants);FX_NO_WINFORMS + $(DefineConstants);FX_RESHAPED_REFEMIT + $(OtherFlags) --simpleresolution + + + diff --git a/FSharp.sln b/FSharp.sln index 23375be628e..ad537855fac 100644 --- a/FSharp.sln +++ b/FSharp.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28729.10 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}" -EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Server.Shared", "src\fsharp\FSharp.Compiler.Server.Shared\FSharp.Compiler.Server.Shared.fsproj", "{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}" @@ -24,7 +22,14 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "fsiAnyCpu", "src\fsharp\fsi {649FA588-F02E-457C-9FCF-87E46407481E} = {649FA588-F02E-457C-9FCF-87E46407481E} EndProjectSection EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Test.Utilities", "tests\FSharp.Test.Utilities\FSharp.Test.Utilities.fsproj", "{60D275B0-B14A-41CB-A1B2-E815A7448FCB}" +EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharpSuite.Tests", "tests\fsharp\FSharpSuite.Tests.fsproj", "{C163E892-5BF7-4B59-AA99-B0E8079C67C4}" + ProjectSection(ProjectDependencies) = postProject + {D0E98C0D-490B-4C61-9329-0862F6E87645} = {D0E98C0D-490B-4C61-9329-0862F6E87645} + {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} = {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} + {C94C257C-3C0A-4858-B5D8-D746498D1F08} = {C94C257C-3C0A-4858-B5D8-D746498D1F08} + EndProjectSection EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.UnitTests", "tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj", "{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}" EndProject @@ -40,19 +45,41 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Build.UnitTests", "t EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Packages", "Packages", "{3840F2E7-3898-45F7-8CF7-1E6829E56DB8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler", "src\fsharp\FSharp.Compiler.nuget\Microsoft.FSharp.Compiler.csproj", "{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler", "src\fsharp\Microsoft.FSharp.Compiler\Microsoft.FSharp.Compiler.csproj", "{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager.Nuget", "src\fsharp\FSharp.DependencyManager.Nuget\FSharp.DependencyManager.Nuget.fsproj", "{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer.UnitTests", "tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj", "{C97819B0-B428-4B96-9CD7-497D2D1C738C}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting.UnitTests", "tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj", "{4FEDF286-0252-4EBC-9E75-879CCA3B85DC}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager", "src\fsharp\FSharp.DependencyManager\FSharp.DependencyManager.fsproj", "{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.ComponentTests", "tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj", "{FAC5A3BF-C0D6-437A-868A-E962AA00B418}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting", "src\fsharp\FSharp.Compiler.Private.Scripting\FSharp.Compiler.Private.Scripting.fsproj", "{6771860A-614D-4FDD-A655-4C70EBCC91B0}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fsharpqa", "fsharpqa", "{292C4F92-A313-4CAF-9552-731F39C6C21F}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting.UnitTests", "tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj", "{4FEDF286-0252-4EBC-9E75-879CCA3B85DC}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testenv", "testenv", "{FF76050A-415A-4FB4-A0E5-13CBF38D83E0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{07482B5E-4980-4285-B732-820F15870284}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PEVerify", "tests\fsharpqa\testenv\src\PEVerify\PEVerify.csproj", "{25568CD2-E654-4C8F-BE5B-59BABFC5BD20}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service.Tests", "tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj", "{DDFD06DC-D7F2-417F-9177-107764EEBCD8}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "src\fsharp\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{9B4CF83C-C215-4EA0-9F8B-B5A77090F634}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{CE70D631-C5DC-417E-9CDA-B16097BEF1AC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroPerfCSharp", "tests\benchmarks\MicroPerf\CS\MicroPerfCSharp.csproj", "{348DCC13-DD3E-4214-B040-5A74E8C6B782}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MicroPerf", "tests\benchmarks\MicroPerf\MicroPerf.fsproj", "{9735B522-37F7-478C-A0C6-6C60BCC53390}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TaskPerfCSharp", "tests\benchmarks\TaskPerfCSharp\TaskPerfCSharp.csproj", "{CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TaskPerf", "tests\benchmarks\TaskPerf\TaskPerf.fsproj", "{51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FSharp.Compiler.Service.Tests support", "FSharp.Compiler.Service.Tests support", "{452EED3C-AA87-471F-B9AC-0F4479C5820C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharp_Analysis", "tests\service\data\CSharp_Analysis\CSharp_Analysis.csproj", "{F8743670-C8D4-41B3-86BE-BBB1226C352F}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager.UnitTests", "tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj", "{388FFDAE-A659-422E-9407-6A9062E1986E}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TestTP", "tests\service\data\TestTP\TestTP.fsproj", "{7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -64,18 +91,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|x86.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|x86.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.Build.0 = Release|Any CPU {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.Build.0 = Debug|Any CPU {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -160,6 +175,18 @@ Global {8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|Any CPU.Build.0 = Release|Any CPU {8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|x86.ActiveCfg = Release|Any CPU {8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|x86.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|x86.ActiveCfg = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|x86.Build.0 = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|Any CPU.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|x86.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|x86.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|Any CPU.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|x86.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|x86.Build.0 = Release|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.Build.0 = Debug|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -220,30 +247,6 @@ Global {81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|Any CPU.Build.0 = Release|Any CPU {81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|x86.ActiveCfg = Release|Any CPU {81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|x86.Build.0 = Release|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|x86.ActiveCfg = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|x86.Build.0 = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|Any CPU.Build.0 = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|x86.ActiveCfg = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|x86.Build.0 = Debug|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|Any CPU.Build.0 = Release|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|x86.ActiveCfg = Release|Any CPU - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|x86.Build.0 = Release|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|x86.ActiveCfg = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|x86.Build.0 = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|Any CPU.Build.0 = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|x86.ActiveCfg = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|x86.Build.0 = Debug|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|Any CPU.Build.0 = Release|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|x86.ActiveCfg = Release|Any CPU - {C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|x86.Build.0 = Release|Any CPU {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -256,18 +259,6 @@ Global {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Release|Any CPU.Build.0 = Release|Any CPU {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Release|x86.ActiveCfg = Release|Any CPU {8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Release|x86.Build.0 = Release|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Debug|x86.ActiveCfg = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Debug|x86.Build.0 = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Proto|Any CPU.Build.0 = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Proto|x86.ActiveCfg = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Proto|x86.Build.0 = Debug|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Release|Any CPU.Build.0 = Release|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Release|x86.ActiveCfg = Release|Any CPU - {6771860A-614D-4FDD-A655-4C70EBCC91B0}.Release|x86.Build.0 = Release|Any CPU {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -280,41 +271,160 @@ Global {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Release|Any CPU.Build.0 = Release|Any CPU {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Release|x86.ActiveCfg = Release|Any CPU {4FEDF286-0252-4EBC-9E75-879CCA3B85DC}.Release|x86.Build.0 = Release|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Debug|x86.ActiveCfg = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Debug|x86.Build.0 = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Proto|Any CPU.Build.0 = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Proto|x86.ActiveCfg = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Proto|x86.Build.0 = Debug|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Release|Any CPU.Build.0 = Release|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Release|x86.ActiveCfg = Release|Any CPU - {388FFDAE-A659-422E-9407-6A9062E1986E}.Release|x86.Build.0 = Release|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Debug|x86.ActiveCfg = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Debug|x86.Build.0 = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Proto|Any CPU.Build.0 = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Proto|x86.ActiveCfg = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Proto|x86.Build.0 = Debug|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Release|Any CPU.Build.0 = Release|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Release|x86.ActiveCfg = Release|Any CPU + {FAC5A3BF-C0D6-437A-868A-E962AA00B418}.Release|x86.Build.0 = Release|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Debug|x86.ActiveCfg = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Debug|x86.Build.0 = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Proto|Any CPU.Build.0 = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Proto|x86.ActiveCfg = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Proto|x86.Build.0 = Debug|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Release|Any CPU.Build.0 = Release|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Release|x86.ActiveCfg = Release|Any CPU + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20}.Release|x86.Build.0 = Release|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Debug|x86.ActiveCfg = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Debug|x86.Build.0 = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Proto|Any CPU.Build.0 = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Proto|x86.ActiveCfg = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Proto|x86.Build.0 = Debug|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Release|Any CPU.Build.0 = Release|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Release|x86.ActiveCfg = Release|Any CPU + {DDFD06DC-D7F2-417F-9177-107764EEBCD8}.Release|x86.Build.0 = Release|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Debug|x86.ActiveCfg = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Debug|x86.Build.0 = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Proto|Any CPU.Build.0 = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Proto|x86.ActiveCfg = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Proto|x86.Build.0 = Debug|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Release|Any CPU.Build.0 = Release|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Release|x86.ActiveCfg = Release|Any CPU + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634}.Release|x86.Build.0 = Release|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Debug|Any CPU.Build.0 = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Debug|x86.ActiveCfg = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Debug|x86.Build.0 = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Proto|Any CPU.Build.0 = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Proto|x86.ActiveCfg = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Proto|x86.Build.0 = Debug|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Release|Any CPU.ActiveCfg = Release|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Release|Any CPU.Build.0 = Release|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Release|x86.ActiveCfg = Release|Any CPU + {348DCC13-DD3E-4214-B040-5A74E8C6B782}.Release|x86.Build.0 = Release|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Debug|x86.ActiveCfg = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Debug|x86.Build.0 = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Proto|Any CPU.Build.0 = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Proto|x86.ActiveCfg = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Proto|x86.Build.0 = Debug|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Release|Any CPU.Build.0 = Release|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Release|x86.ActiveCfg = Release|Any CPU + {9735B522-37F7-478C-A0C6-6C60BCC53390}.Release|x86.Build.0 = Release|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Debug|x86.ActiveCfg = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Debug|x86.Build.0 = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Proto|Any CPU.Build.0 = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Proto|x86.ActiveCfg = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Proto|x86.Build.0 = Debug|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Release|Any CPU.Build.0 = Release|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Release|x86.ActiveCfg = Release|Any CPU + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB}.Release|x86.Build.0 = Release|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Debug|x86.ActiveCfg = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Debug|x86.Build.0 = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Proto|Any CPU.Build.0 = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Proto|x86.ActiveCfg = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Proto|x86.Build.0 = Debug|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Release|Any CPU.Build.0 = Release|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Release|x86.ActiveCfg = Release|Any CPU + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4}.Release|x86.Build.0 = Release|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Debug|x86.ActiveCfg = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Debug|x86.Build.0 = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Proto|Any CPU.Build.0 = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Proto|x86.ActiveCfg = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Proto|x86.Build.0 = Debug|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Release|Any CPU.Build.0 = Release|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Release|x86.ActiveCfg = Release|Any CPU + {F8743670-C8D4-41B3-86BE-BBB1226C352F}.Release|x86.Build.0 = Release|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Debug|x86.ActiveCfg = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Debug|x86.Build.0 = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Proto|Any CPU.Build.0 = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Proto|x86.ActiveCfg = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Proto|x86.Build.0 = Debug|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Release|Any CPU.Build.0 = Release|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Release|x86.ActiveCfg = Release|Any CPU + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} + {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06} = {B8DDA694-7939-42E3-95E5-265C2217C142} {DED3BBD7-53F4-428A-8C9F-27968E768605} = {3058BC79-8E79-4645-B05D-48CC182FA8A6} {702A7979-BCF9-4C41-853E-3ADFC9897890} = {B8DDA694-7939-42E3-95E5-265C2217C142} {C94C257C-3C0A-4858-B5D8-D746498D1F08} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} {649FA588-F02E-457C-9FCF-87E46407481E} = {B8DDA694-7939-42E3-95E5-265C2217C142} {D0E98C0D-490B-4C61-9329-0862F6E87645} = {B8DDA694-7939-42E3-95E5-265C2217C142} {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} = {B8DDA694-7939-42E3-95E5-265C2217C142} + {60D275B0-B14A-41CB-A1B2-E815A7448FCB} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {C163E892-5BF7-4B59-AA99-B0E8079C67C4} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {88E2D422-6852-46E3-A740-83E391DC7973} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {53C0DAAD-158C-4658-8EC7-D7341530239F} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7} = {3840F2E7-3898-45F7-8CF7-1E6829E56DB8} - {99B3F4A5-80B4-41D9-A073-117DB6D7DBBA} = {B8DDA694-7939-42E3-95E5-265C2217C142} - {C97819B0-B428-4B96-9CD7-497D2D1C738C} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {8B7BF62E-7D8C-4928-BE40-4E392A9EE851} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} - {6771860A-614D-4FDD-A655-4C70EBCC91B0} = {B8DDA694-7939-42E3-95E5-265C2217C142} {4FEDF286-0252-4EBC-9E75-879CCA3B85DC} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} - {388FFDAE-A659-422E-9407-6A9062E1986E} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {FAC5A3BF-C0D6-437A-868A-E962AA00B418} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {292C4F92-A313-4CAF-9552-731F39C6C21F} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {FF76050A-415A-4FB4-A0E5-13CBF38D83E0} = {292C4F92-A313-4CAF-9552-731F39C6C21F} + {07482B5E-4980-4285-B732-820F15870284} = {FF76050A-415A-4FB4-A0E5-13CBF38D83E0} + {25568CD2-E654-4C8F-BE5B-59BABFC5BD20} = {07482B5E-4980-4285-B732-820F15870284} + {DDFD06DC-D7F2-417F-9177-107764EEBCD8} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {9B4CF83C-C215-4EA0-9F8B-B5A77090F634} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} + {348DCC13-DD3E-4214-B040-5A74E8C6B782} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} + {9735B522-37F7-478C-A0C6-6C60BCC53390} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} + {CF9F3F98-7BFB-4945-A4A5-668DF0AC65AB} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} + {51B569A8-17C5-4EBD-8AAC-240E0B3AD8C4} = {CE70D631-C5DC-417E-9CDA-B16097BEF1AC} + {452EED3C-AA87-471F-B9AC-0F4479C5820C} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {F8743670-C8D4-41B3-86BE-BBB1226C352F} = {452EED3C-AA87-471F-B9AC-0F4479C5820C} + {7BFA159A-BF9D-4489-BF46-1B83ACCEEE0F} = {452EED3C-AA87-471F-B9AC-0F4479C5820C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BD5177C7-1380-40E7-94D2-7768E1A8B1B8} diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props index 791850399b3..bcdbffa1c12 100644 --- a/FSharpBuild.Directory.Build.props +++ b/FSharpBuild.Directory.Build.props @@ -8,12 +8,19 @@ + + + true + + $(RepoRoot)src + $(RepoRoot)tests $(ArtifactsDir)\SymStore $(ArtifactsDir)\Bootstrap 4.4.0 1182;0025;$(WarningsAsErrors) + $(OtherFlags) --nowarn:3384 @@ -37,23 +44,6 @@ true - - - /usr - /Library/Frameworks/Mono.framework/Versions/Current - $(MonoRoot)/lib/mono - true - $(MonoLibFolder)/4.5-api - $(MonoLibFolder)/4.5.1-api - $(MonoLibFolder)/4.5.2-api - $(MonoLibFolder)/4.6-api - $(MonoLibFolder)/4.6.1-api - $(MonoLibFolder)/4.6.2-api - $(MonoLibFolder)/4.7-api - $(MonoLibFolder)/4.7.1-api - $(MonoLibFolder)/4.7.2-api - - Microsoft @@ -70,20 +60,9 @@ true - - - false + + false - https://github.com/Microsoft/visualfsharp - git - - - - <_DotGitDir>$(RepoRoot).git - <_HeadFileContent Condition="Exists('$(_DotGitDir)/HEAD')">$([System.IO.File]::ReadAllText('$(_DotGitDir)/HEAD').Trim()) - <_RefPath Condition="$(_HeadFileContent.StartsWith('ref: '))">$(_DotGitDir)/$(_HeadFileContent.Substring(5)) - $(BUILD_SOURCEVERSION) - $([System.IO.File]::ReadAllText('$(_RefPath)').Trim()) @@ -108,4 +87,13 @@ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Overrides.NetSdk.targets + + + diff --git a/FSharpBuild.Directory.Build.targets b/FSharpBuild.Directory.Build.targets index da6302ef036..2e521c5de2d 100644 --- a/FSharpBuild.Directory.Build.targets +++ b/FSharpBuild.Directory.Build.targets @@ -2,8 +2,8 @@ - + $([System.IO.File]::ReadAllText('%(NoneSubstituteText.FullPath)')) <_ReplacementText Condition="'%(NoneSubstituteText.Pattern1)' != ''">$(_ReplacementText.Replace('%(NoneSubstituteText.Pattern1)', '%(NoneSubstituteText.Replacement1)')) <_ReplacementText Condition="'%(NoneSubstituteText.Pattern2)' != ''">$(_ReplacementText.Replace('%(NoneSubstituteText.Pattern2)', '%(NoneSubstituteText.Replacement2)')) + <_ReplacementText Condition="'%(NoneSubstituteText.Pattern3)' != ''">$(_ReplacementText.Replace('%(NoneSubstituteText.Pattern3)', '%(NoneSubstituteText.Replacement3)')) <_CopyToOutputDirectory Condition="'%(NoneSubstituteText.CopyToOutputDirectory)' != ''">%(NoneSubstituteText.CopyToOutputDirectory) <_CopyToOutputDirectory Condition="'%(NoneSubstituteText.CopyToOutputDirectory)' == ''">Never @@ -61,32 +62,73 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - + + $(CoreBuildDependsOn);PrefixRepoToReleaseNotes + + + + + + <_GitUrl>$([System.Text.RegularExpressions.Regex]::Replace($(ScmRepositoryUrl), ".git$", "")) + $(_GitUrl)$(PackageReleaseNotes) + diff --git a/FSharpTests.Directory.Build.props b/FSharpTests.Directory.Build.props index 8a4730f8dd0..9d9983693af 100644 --- a/FSharpTests.Directory.Build.props +++ b/FSharpTests.Directory.Build.props @@ -22,18 +22,18 @@ $([System.IO.Path]::GetDirectoryName('$(DOTNET_HOST_PATH)')) dotnet.exe dotnet - $(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\netcoreapp3.0\fsc.exe + $(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\net5.0\fsc.dll $([System.IO.Path]::GetDirectoryName('$(DOTNET_HOST_PATH)')) dotnet.exe dotnet - $(MSBuildThisFileDirectory)artifacts\bin\fsi\$(Configuration)\netcoreapp3.0\fsi.exe + $(MSBuildThisFileDirectory)artifacts\bin\fsi\$(Configuration)\net5.0\fsi.dll <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'!='Core'">net472 - <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'=='Core'">netcoreapp3.0 + <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'=='Core'">net5.0 <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\$(_FSharpBuildTargetFramework) $(_FSharpBuildBinPath)\FSharp.Build.dll diff --git a/FSharpTests.Directory.Build.targets b/FSharpTests.Directory.Build.targets index 3768b5c726d..075321e3fb5 100644 --- a/FSharpTests.Directory.Build.targets +++ b/FSharpTests.Directory.Build.targets @@ -39,4 +39,5 @@ <_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" /> + diff --git a/INTERNAL.md b/INTERNAL.md index 15550dcedcd..2dbfdcd20e0 100644 --- a/INTERNAL.md +++ b/INTERNAL.md @@ -7,6 +7,10 @@ Note that usually only the most recent link in each section is interesting. Old The PR build definition can be found [here](https://dev.azure.com/dnceng/public/_build?definitionId=496) or by navigating through an existing PR. +There is also a duplicate scouting PR build that is identical to the normal PR build _except_ that it uses a different Windows +machine queue that always has the next preview build of Visual Studio installed. This is to hopefully get ahead of any breaking +API changes. That build definition is [here](https://dev.azure.com/dnceng/public/_build?definitionId=961). + ## Signed Build Definitions [VS 16.4 to current](https://dev.azure.com/dnceng/internal/_build?definitionId=499&_a=summary) @@ -17,6 +21,10 @@ navigating through an existing PR. [VS 15.0 to 15.5](https://dev.azure.com/devdiv/DevDiv/_build?definitionId=5037) +## Branch auto-merge definitions + +Branch auto-merge definitions are specified [here](https://github.com/dotnet/roslyn-tools/blob/master/src/GitHubCreateMergePRs/config.xml). + ## VS Insertion Generators VS 16.4 to current - part of the build definition. [See below](#vs-insertions-as-part-of-the-build-definition). @@ -42,19 +50,36 @@ insertion into VS will be created into the `insertTargetBranch` branch. The lin near the bottom of the build under the title 'Insert into VS'. Examine the log for 'Insert VS Payload' and near the bottom you'll see a line that looks like `Created request #xxxxxx at https://...`. -To see all insertions created this way (possibly including for other internal teams), check +Insertions generated to any `rel/*` branch will have to be manually verified and merged, and they'll be listed [here](https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequests?createdBy=122d5278-3e55-4868-9d40-1e28c2515fc4&_a=active). +Note that insertions for other teams will also be listed. + +Insertions to any other VS branch (e.g., `main`) will have the auto-merge flag set and should handle themselves, but +it's a good idea to check the previous link for any old or stalled insertions into VS `main`. ## Less interesting links -[Nightly VSIX (master) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=70). Uploads -a package from every build of `master` to the [Nightly VSIX feed](README.md#using-nightly-releases-in-visual-studio). +[FSharp.Core (Official NuGet Release)](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=72). +Uploads the final `FSharp.Core` package from the specified build to NuGet. This should only be run when we know for +certain which build produced the final offical package. + +[FSharp.Core (Preview NuGet Release)](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=92). +Uploads the preview `FSharp.Core.*-beta.*` package from the specified build to NuGet. This should be run every time +a new SDK preview is released. + +[FCS (Official NuGet Release)](https://dev.azure.com/dnceng/internal/_release?view=mine&_a=releases&definitionId=99). +Uploads the final `FSharp.Compiler.Service` package from the specified build to NuGet. Only builds from the `release/fcs` +branch can be selected. This should only be run when we're fairly certain that the package is complete. + +[FCS (Preview NuGet Release)](https://dev.azure.com/dnceng/internal/_release?view=mine&_a=releases&definitionId=98). +Uploads the preview `FSharp.Compiler.Service.*-preview.*` package from the specified build to NuGet. Only builds from the +`main` branch can be selected. This can be run whenever we think we're ready to preview a new FCS build. + +[Nightly VSIX (main) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=70). Uploads +a package from every build of `main` to the [Nightly VSIX feed](README.md#using-nightly-releases-in-visual-studio). [Nightly VSIX (preview) uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=71). Uploads a package from every build of the branch that corresponds to the current Visual Studio preview to the [Preview VSIX feed](README.md#using-nightly-releases-in-visual-studio). -[MyGet package uploader](https://dev.azure.com/dnceng/internal/_release?_a=releases&definitionId=69). Uploads various -packages for internal consumption. Feed URL is `https://dotnet.myget.org/F/fsharp/api/v3/index.json`. - [Internal source mirror](https://dev.azure.com/dnceng/internal/_git/dotnet-fsharp). diff --git a/Makefile b/Makefile deleted file mode 100644 index 51a47f4ff93..00000000000 --- a/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -Configuration ?= release -DotNetVersion = `cat DotnetCLIToolsVersion.txt` -DotNetToolPath = $(CURDIR)/artifacts/toolset/dotnet -DotNetExe = "$(DotNetToolPath)/dotnet" - -all: proto restore build test - -tools: - $(CURDIR)/scripts/dotnet-install.sh --version $(DotNetVersion) --install-dir "$(DotNetToolPath)" - -proto: tools - $(DotNetExe) build-server shutdown - $(DotNetExe) restore src/buildtools/buildtools.proj - $(DotNetExe) restore src/fsharp/FSharp.Build/FSharp.Build.fsproj - $(DotNetExe) restore src/fsharp/fsc/fsc.fsproj - $(DotNetExe) build src/buildtools/buildtools.proj -c Proto - $(DotNetExe) build src/fsharp/FSharp.Build/FSharp.Build.fsproj -f netstandard2.0 -c Proto - $(DotNetExe) build src/fsharp/fsc/fsc.fsproj -f netcoreapp3.0 -c Proto - -restore: - $(DotNetExe) restore src/fsharp/FSharp.Core/FSharp.Core.fsproj - $(DotNetExe) restore src/fsharp/FSharp.Build/FSharp.Build.fsproj - $(DotNetExe) restore src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj - $(DotNetExe) restore src/fsharp/fsc/fsc.fsproj - $(DotNetExe) restore src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj - $(DotNetExe) restore src/fsharp/fsi/fsi.fsproj - $(DotNetExe) restore tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj - $(DotNetExe) restore tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj - -build: proto restore - $(DotNetExe) build-server shutdown - $(DotNetExe) build -c $(Configuration) -f netstandard2.0 src/fsharp/FSharp.Core/FSharp.Core.fsproj - $(DotNetExe) build -c $(Configuration) -f netstandard2.0 src/fsharp/FSharp.Build/FSharp.Build.fsproj - $(DotNetExe) build -c $(Configuration) -f netstandard2.0 src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj - $(DotNetExe) build -c $(Configuration) -f netcoreapp3.0 src/fsharp/fsc/fsc.fsproj - $(DotNetExe) build -c $(Configuration) -f netstandard2.0 src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj - $(DotNetExe) build -c $(Configuration) -f netcoreapp3.0 src/fsharp/fsi/fsi.fsproj - $(DotNetExe) build -c $(Configuration) -f netcoreapp3.0 tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj - $(DotNetExe) build -c $(Configuration) -f netcoreapp3.0 tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj - -test: build - $(DotNetExe) test -f netcoreapp3.0 -c $(Configuration) --no-restore --no-build tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj -l "trx;LogFileName=$(CURDIR)/tests/TestResults/FSharp.Core.UnitTests.coreclr.trx" - $(DotNetExe) test -f netcoreapp3.0 -c $(Configuration) --no-restore --no-build tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj -l "trx;LogFileName=$(CURDIR)/tests/TestResults/FSharp.Build.UnitTests.coreclr.trx" - -clean: - rm -rf $(CURDIR)/artifacts diff --git a/NuGet.config b/NuGet.config index 26edd0d796c..7e6ce303990 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,28 +6,14 @@ - - - - - - - - - - - - + + + + - - - - - - - + diff --git a/README.md b/README.md index b82a64d086e..800baae73ce 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ You're invited to contribute to future releases of the F# compiler, core library, and tools. Development of this repository can be done on any OS supported by [.NET Core](https://dotnet.microsoft.com/). +You will also need the latest .NET 5 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/5.0). + ## Contributing ### Quickstart on Windows @@ -30,9 +32,15 @@ Build from the command line: After it's finished, open `FSharp.sln` in your editor of choice. -### More options and information +### Documentation for contributors + +See [DEVGUIDE.md](DEVGUIDE.md) for more details on configurations for building the codebase. In practice, you only really need to run `build.cmd`/`build.sh`. + +See [TESTGUIDE.md](TESTGUIDE.md) for information about the various test suites in this codebase and how to run them individually. -See [DEVGUIDE.md](DEVGUIDE.md) and [TESTGUIDE.md](TESTGUIDE.md) for more details on additional configurations for building and testing, how to update compiler error messages, and more. +See the [Compiler Guide](docs/compiler-guide.md) for an in-depth guide to the F# compiler. It is essential reading for any larger contributions to the F# compiler codebase. + +See [the F# Language Specification](https://fsharp.org/specs/language-spec/) for an in-depth description of the F# language. This is essential for understanding some behaviors of the F# compiler and some of the rules within the compiler codebase. For example, the order and way name resolution happens is specified here, which greatly impacts how the code in Name Resolutions works and why certain decisions are made. ### No contribution is too small @@ -42,41 +50,30 @@ Even if you find a single-character typo, we're happy to take the change! Althou | Branch | Status | |:------:|:------:| -|master|[![Build Status](https://dev.azure.com/dnceng/public/_apis/build/status/dotnet/fsharp/fsharp-ci?branchName=master)](https://dev.azure.com/dnceng/public/_build/latest?definitionId=496&branchName=master)| - -## Using nightly releases in Visual Studio - -You can use the latest `master` build of the F# compiler and tools for Visual Studio via our nightly releases if you are a Visual Studio user. See details on setup here: +|main|[![Build Status](https://dev.azure.com/dnceng/public/_apis/build/status/dotnet/fsharp/fsharp-ci?branchName=main)](https://dev.azure.com/dnceng/public/_build/latest?definitionId=496&branchName=main)| -https://blogs.msdn.microsoft.com/dotnet/2017/03/14/announcing-nightly-releases-for-the-visual-f-tools/ +## Per-build NuGet packages -### Even more nightly than the nightly - -Alternatively, if you _really_ want to live on the bleeding edge, you can set up a nightly feed for the Visual Studio preview releases, which use the latest commit in the preview branch. To do so, follow the same instructions as the above blog post, but instead with these links: - -* Set your feed to the preview feed: https://dotnet.myget.org/F/fsharp-preview/vsix -* Install a VSIX manually from the preview feed: https://dotnet.myget.org/feed/fsharp-preview/package/vsix/VisualFSharp +Per-build [versions](https://dev.azure.com/dnceng/public/_packaging?_a=package&feed=dotnet-tools&view=versions&package=FSharp.Compiler.Service&protocolType=NuGet) of our NuGet packages are available via this URL: `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json ` ## Branches These are the branches in use: -* `master` - - Most contributions go here. +* `main` + - Almost all contributions go here. - Able to be built, installed and used in the latest public Visual Studio release. - May contain updated F# features and logic. - Used to build nightly VSIX (see above). - - Gets integrated into https://github.com/fsharp/fsharp to form the basis of Mono releases - - Gets integrated into https://github.com/fsharp/FSharp.Compiler.Service to form the basis of FSharp.Compiler.Service releases -* `dev15.9` +* `release/dev15.9` - Long-term servicing branch for VS 2017 update 15.9.x. We do not expect to service that release, but if we do, that's where the changes will go. -* `dev16.x` +* `release/dev16.x` - Latest release branch for the particular point release of Visual Studio. - - Incorporates features and fixes from master up to a particular branch point, then selective cherry-picks. + - Incorporates features and fixes from main up to a particular branch point, then selective cherry-picks. - May contain new features that depend on new things or fixes in the corresponding forthcoming Visual Studio release. - - Gets integrated back into master once the corresponding Visual Studio release is made. + - Gets integrated back into main once the corresponding Visual Studio release is made. ## F# language and core library evolution @@ -86,13 +83,6 @@ Evolution of the F# language and core library follows a process spanning two add 2. Ideas that are "approved in principle" are eligible for a new RFC in the [F# language design repo](https://github.com/fsharp/fslang-design). This is where the technical specification and discussion of approved suggestions go. 3. Implementations and testing of an RFC are submitted to this repository. -## Additional project documentation - -The following links can help you get an overview of some technical aspects of the F# language and compiler: - -* [The F# Compiler Technical Guide](https://fsharp.github.io/2015/09/29/fsharp-compiler-guide.html) -* [The F# Language Specification](https://fsharp.org/specs/language-spec/) - ## License This project is subject to the MIT License. A copy of this license is in [License.txt](License.txt). @@ -115,3 +105,4 @@ If you're curious about F# itself, check out these links: * [Get started with F#](https://docs.microsoft.com/dotnet/fsharp/get-started/) * [F# Software Foundation](https://fsharp.org) * [F# Testimonials](https://fsharp.org/testimonials) + diff --git a/RoslynPackageVersion.txt b/RoslynPackageVersion.txt deleted file mode 100644 index cc99af67911..00000000000 --- a/RoslynPackageVersion.txt +++ /dev/null @@ -1 +0,0 @@ -3.2.0-beta4-19312-15 diff --git a/TESTGUIDE.md b/TESTGUIDE.md index f658b443c1d..503cf6dab91 100644 --- a/TESTGUIDE.md +++ b/TESTGUIDE.md @@ -1,20 +1,107 @@ # F# Compiler, Core Library and Visual F# Tools Tests +Where this guide mentions the command `build` it means either `build.cmd` in the root folder for Windows, or `build.sh` for Linux/MacOS. + +## In this guide + +* [Quick start: Running Tests](#quick-start-running-tests) +* [Prerequisites](#prerequisites) +* [Test Suites](#test-suites) +* [More details](#more-details) +* [Other Tips and gotchas](#other-tips-and-gotchas) +* [Solving common errors](#solving-common-errors) +* [Approximate running times](#approximate-running-times) + + ## Quick start: Running Tests -To run tests, use variations such as the following, depending on which test suite and build configuration you want: +Tests are grouped as noted below. Some test groups can only be run in `CI` configuration, for that, you need to pass the `-ci -bl` or `-ci -nobl` arguments. Some test groups can only be run in Release mode, this is indicated below. Some tests can only be run on Windows. + +To run tests, from a command prompt, use variations such as the following, depending on which test suite and build configuration you want. + +### Tests runnable in any configuration + +The following testsets can be run in Release or Debug mode, with or without the `-ci` argument. + +Run the tests in Release mode: + + build -testCompiler -c Release + build -testFSharpCore -c Release + build -testScripting -c Release + build -testVS -c Release + +Run the tests in Debug mode, add `-c Debug` or leave it out: + + build -testCompiler -c Debug + build -testFSharpCore -c Debug + build -testScripting -c Debug + build -testVS -c Debug + +### Tests that can be run on Linux and MacOS + +If you're using Linux or MacOS to develop, the group of tests that are known to succeed are all in `-testCoreClr`. Any other `-testXXX` argument will currently fail. An effort is underway to make testing and running tests easier on all systems. + +### Tests that can only be run in Release mode + +The following tests **must** be run in Release mode with `-c Release`: + + build -testAll -c Release + build -test -c Release + build -testDesktop -c Release + build -testCoreClr -c Release + +### Tests that can only run with `-ci` - build.cmd test - build.cmd net40 test - build.cmd coreclr test - build.cmd vs test - build.cmd all test +The following tests **must** be run in Release mode and **must** have the CI argument like `-ci -bl` or `-ci -nobl`: -You can also submit pull requests to https://github.com/dotnet/fsharp and run the tests via continuous integration. Most people do wholesale testing that way. + build -testCambridge -c Release -ci -nobl + build -testFSharpQA -c Release -ci -nobl + + +### Tests that open other windows + +The following testsets open other windows and may interfere with you using your workstation, or change focus while you're doing something else: + +* FSharpQA +* Cambridge + +### Tests grouping summary + +| Group name | OS | Description | +|------------|----|-------------| +| testDesktop | Windows | Runs all net472 tests in 32 bit processes, this includes tests from other groups | +| testCoreClr | Linux/Mac/Windows | Runs all .NetStandard and .NETCore tests in 64 bit processes, this includes tests from other groups | +| testFSharpCore | Windows | Runs all test for FSharp.Core.dll | +| testCambridge | Windows | Runs the Cambridge suite tests | +| testFSharpQA | Windows | Runs the FSharpQA tests, requires Perl | +| testVS | Windows + VS | Runs all VS integration tests | +| testCompiler | Windows | Runs a few quick compiler tests | +| testScripting | Windows | Runs scripting fsx and fsi commandline tests | +| test | Windows | Same as testDesktop | +| testAll | Windows | Runs all above tests | + +### Running tests online in CI + +You can also submit pull requests to https://github.com/dotnet/fsharp and run the tests via continuous integration. Most people do wholesale testing that way. A few notes: + +* Online, sometimes unrelated tests or builds may fail, a rerun may solve this +* A CI build can be restarted by closing/reopening the PR +* A new CI build will be started on each pushed commit +* CI builds that are not finished will be canceled on new commits. If you need to complete such runs, you can do so in the Checks tab of the PR by selecting the actual commit from the dropdown. + +#### Analyzing CI results + +Finding the logs in the online CI results can be tricky, a small video can be found below under "Test gotchas". ## Prerequisites -It is recommended that you run tests from an elevated command prompt, as there are a couple of test cases which require administrative privileges. +The prerequisites are the same as for building the `FSharp.sln`, plus, at a minimum: + +* An installation of Perl, required for running FSharpQA tests +* Run `git clean -xdf -e .vs` before running tests when: + * Making changes to the lexer or parser + * Between switching git branches + * When merging with latest `main` upstream branch. ## Test Suites @@ -48,7 +135,7 @@ There are also negative tests checking code expected to fail compilation. See no The FSharpQA suite relies on [Perl](http://www.perl.org/get.html), StrawberryPerl package from nuget is used automatically by the test suite. -These tests use the `RunAll.pl` framework to execute, however the easiest way to run them is via the `build.cmd` script, see [usage examples](https://github.com/Microsoft/visualfsharp/blob/master/build.cmd#L31). +These tests use the `RunAll.pl` framework to execute, however the easiest way to run them is via the `.\build` script, see [usage examples](#quick-start-running-tests). Tests are grouped in folders per area. Each folder contains a number of source code files and a single `env.lst` file. The `env.lst` file defines a series of test cases, one per line. @@ -66,7 +153,7 @@ For the FSharpQA suite, the list of test areas and their associated "tags" is st Tags are in the left column, paths to to corresponding test folders are in the right column. If no tags are specified, all tests will be run. -If you want to re-run a particular test area, the easiest way to do so is to set a temporary tag for that area in test.lst (e.g. "RERUN") and then pass that as an argument to `build.cmd`: `build.cmd test-net40-fsharpqa include RERUN`. +If you want to re-run a particular test area, the easiest way to do so is to set a temporary tag for that area in test.lst (e.g. "RERUN") and adjust `ttags` [run.fsharpqa.test.fsx script](tests/fsharpqa/run.fsharpqa.test.fsx) and run it. ### FSharp.Compiler.UnitTests, FSharp.Core.UnitTests, VisualFSharp.UnitTests @@ -87,11 +174,12 @@ All test execution logs and result files will be dropped into the `tests\TestRes net40-coreunit-suite-*.* vs-ideunit-suite-*.* -### Baselines +### Working with baseline tests -FSharp Test Suite works with couples of .bsl (or .bslpp) files considered "expected" and called baseline, those are matched against the actual output which resides under .err or .vserr files of same name at the during test execution. +FSharp Test Suite works with a couple of `.bsl` (or `.bslpp`) files describing "expected test results" and are called the _Baseline Tests_. Those are matched against the actual output that resides under `.err` or `.vserr` files of the same name during test execution. When doing so keep in mind to carefully review the diff before comitting updated baseline files. -.bslpp (baseline pre-process) files are specially designed to enable substitution of certain tokens to generate the .bsl file. You can look further about the pre-processing logic under [tests/fsharp/TypeProviderTests.fs](tests/fsharp/TypeProviderTests.fs), this is used only for type provider tests for now. + +The `.bslpp` (for: baseline pre-process) files are specially designed to enable substitution of certain tokens to generate the `.bsl` file. You can look further about the pre-processing logic under [tests/fsharp/TypeProviderTests.fs](tests/fsharp/TypeProviderTests.fs), this is used only for type provider tests for now. To update baselines use this: @@ -101,15 +189,93 @@ Use `-n` to dry-run: fsi tests\scripts\update-baselines.fsx -n -### Other Tips +## Other Tips and gotchas + +This section contains general tips, for solving errors see [next section](#solving-common-errors). + +### Close any open VisualFSharp.sln -#### Run as Administrator +If you have the `VisualFSharp.sln` open, or if you recently debugged it through `VisualFSharpFull` as start-up project, certain tests may fail because files will be in use. It's best to close Visual Studio and any debugging sessions during a test run. It is fine to have VS open on a different solution, or to have it open from a different F# repo folder. -Do this, or a handful of tests will fail. +### Finding the logs on CI -#### Making the tests run faster +Finding the proper logs in the CI system can be daunting, this video shows you where to look once you have an open PR. It shows you how to get the `FsharpQA` logs, but the same method applies to getting any other test logs. +![b51e0ea3-e12b-4ee8-b26a-3b98c11dae33](https://user-images.githubusercontent.com/16015770/91355183-1a6ff900-e7ee-11ea-8fb4-e3627cc9b811.gif) + +The console output of the CI runs do not contain output of the FSharpQA tests, but for most other tests the console output contains enough info and can be found by clicking Raw output in the CI window, or clicking download logs: + +![download logs](https://user-images.githubusercontent.com/6309070/89307267-b9596900-d625-11ea-86e9-a1657ce2a368.png) + +### Increase command screen line buffer on Windows + +You can increase the window buffer so that more lines of the console output can be scrolled back to, as opposed to them disappearing off the top. The default size on Windows is very small: + +* Click top-left icon of the command window +* Go to Properties then Layout +* Select a higher _Screen buffer size_ than the window size (this will add a scroll bar) +* You may want to increase the width and height as well +* Click OK. + +### Run as Administrator + +Running tests should now be possible without admin privileges. If you find tests that don't run unless you are an admin, please create an issue. + +### Running tests on other (feature) branches + +When you switch branches, certain temporary files, as well as the .NET version (downloaded to `.dotnet` folder) are likely to not be in sync anymore and can lead to curious build errors. Fix this by running `git clean` like this (this will leave your VS settings intact): + + git clean -xdf -e .vs + +If you get "file in use" errors during cleaning, make sure to close Visual Studio and any running `dotnet.exe` and `VBCSCompiler.exe`, esp those that show up at the bottom of [Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) without parent process. + +#### Running tests on release/dev16.6 etc branches + +Some tests are known to fail on these older branches when run using one of the `testXXXX` commandline arguments. However, `-test`, `-testAll`, `-testCoreClr` and `-testDesktop` are known to work on at least the `dev16.6` and `dev16.7` branches. + +### Making the tests run faster + +* Adding the `-norestore` flag to the commandline speeds up the build part a little bit. +* When using the `-ci` flag (mandatory for some testsets), adding the `-nobl` flag prevents creating the binary log files. * NGen-ing the F# bits (fsc, fsi, FSharp.Core, etc) will result in tests executing much faster. Make sure you run `src\update.cmd` with the `-ngen` flag before running tests. + +Some tests run in parallel by default, or use a hosted compiler to speed things up: + * The FSharp and FSharpQA suites will run test cases in parallel by default. You can comment out the relevant line (look for `PARALLEL_ARG`) to disable this. * By default, tests from the FSharpQA suite are run using a persistent, hosted version of the compiler. This speeds up test execution, as there is no need for the `fsc.exe` process to spin up repeatedly. To disable this, uncomment the relevant line (look for `HOSTED_COMPILER`). +## Solving common errors + +The following are common errors that users have encountered while running tests on their system. + +### Error that a file cannot be accessed + +The build often leaves dangling processes like `HostedCompilerServer.exe`, `VBCSCompiler.exe` or `MSBuild.exe`. In [Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer) you can see these processes having no parent process anymore. You can also use this to kill such processes. A typical error looks like and contains the process IDs (here 23152, 25252 and 24704): + +> C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(4364,5): error MSB3026: Could not copy "D:\Projects\FSharp\artifacts\bin\FSharp.Core\Debug\net45\FSharp.Core.dll" to "D:\Projects\FSharp\tests\fsharpqa\testenv\bin\FSharp.Core.dll". Beginning retry 1 in 1000ms. The process cannot access the file 'D:\Projects\FSharp\tests\fsharpqa\testenv\bin\FSharp.Core.dll' because it is being used by another process. The file is locked by: "HostedCompilerServer (23152), HostedCompilerServer (25252), HostedCompilerServer (24704)" [D:\Projects\OpenSource\FSharp\tests\fsharpqa\testenv\src\ILComparer\ILComparer.fsproj] + +### StackOverflow exception + +This usually happens when you try to run tests without specifying `-c Release`, or as `-c Debug` (which is the default). Run the same set with `-c Release` instead and the SOE should disappear. + +## Approximate running times + +Some tests can run for several minutes, this doesn't mean that your system froze: + +![image](https://user-images.githubusercontent.com/16015770/91359250-7dfd2500-e7f4-11ea-86bf-518c07ad61ab.png) + +To get an idea of how long it may take, or how much coffee you'll need while waiting, here are some rough indications from an older workstation run, using arguments `-c Release -nobl -norestore`: + +| Testset | Approx running time | Ngen'ed running time | +|-------|-------|-----| +| sln build time | 1 min* | n/a | +| `-testDesktop` | 5 min | ? | +| `-testCoreClr` | 36 min | ? | +| `-testCambridge` | 72 min | 35 min | +| `-testFSharpQA` | 13 min | ? | +| `-testCompiler` | 30 seconds | n/a | +| `-testFSharpCore` | 2 min | ? | +| `-testScripting` | 2 min | 1.5 min | +| `-testVS` | 13 min | ? | + +* This is the build time when a previous build with the same configuration succeeded, and without `-ci` present, which always rebuilds the solution. With `-norestore` the build part can go down to about 10-20 seconds, before tests are being run diff --git a/VisualFSharp.sln b/VisualFSharp.sln index 76bcf8369e7..fbc6ced66f3 100644 --- a/VisualFSharp.sln +++ b/VisualFSharp.sln @@ -22,16 +22,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ItemTemplates", "ItemTemplates", "{F6DAEE9A-8BE1-4C4A-BC83-09215517C7DA}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{D086C8C6-D00D-4C3B-9AB2-A4286C9F5922}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FSharp.Compiler.Service.tests Support", "FSharp.Compiler.Service.tests Support", "{35636A82-401A-4C3A-B2AB-EB7DC5E9C268}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Legacy", "Legacy", "{CCAB6E50-34C6-42AF-A6B0-567C29FCD91B}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.VS.FSI", "vsintegration\src\FSharp.VS.FSI\FSharp.VS.FSI.fsproj", "{991DCF75-C2EB-42B6-9A0D-AA1D2409D519}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualFSharpFull", "vsintegration\Vsix\VisualFSharpFull\VisualFSharpFull.csproj", "{59ADCE46-9740-4079-834D-9A03A3494EBC}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Server.Shared", "src\fsharp\FSharp.Compiler.Server.Shared\FSharp.Compiler.Server.Shared.fsproj", "{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}" @@ -44,11 +40,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.LanguageService.Base EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Editor", "vsintegration\src\FSharp.Editor\FSharp.Editor.fsproj", "{65E0E82A-EACE-4787-8994-888674C2FE87}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectSystem.Base", "vsintegration\src\FSharp.ProjectSystem.Base\Project\ProjectSystem.Base.csproj", "{B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.ProjectSystem.Base", "vsintegration\src\FSharp.ProjectSystem.Base\FSharp.ProjectSystem.Base.csproj", "{B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FSharp.PropertiesPages", "vsintegration\src\FSharp.ProjectSystem.PropertyPages\FSharp.PropertiesPages.vbproj", "{FCFB214C-462E-42B3-91CA-FC557EFEE74F}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "FSharp.ProjectSystem.PropertyPages", "vsintegration\src\FSharp.ProjectSystem.PropertyPages\FSharp.ProjectSystem.PropertyPages.vbproj", "{FCFB214C-462E-42B3-91CA-FC557EFEE74F}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ProjectSystem", "vsintegration\src\FSharp.ProjectSystem.FSharp\ProjectSystem.fsproj", "{6196B0F8-CAEA-4CF1-AF82-1B520F77FE44}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.ProjectSystem.FSharp", "vsintegration\src\FSharp.ProjectSystem.FSharp\FSharp.ProjectSystem.FSharp.fsproj", "{6196B0F8-CAEA-4CF1-AF82-1B520F77FE44}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "VisualFSharp.Salsa", "vsintegration\tests\Salsa\VisualFSharp.Salsa.fsproj", "{FBD4B354-DC6E-4032-8EC7-C81D8DFB1AF7}" EndProject @@ -88,37 +84,43 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "fsiAnyCpu", "src\fsharp\fsi EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "fsi", "src\fsharp\fsi\fsi.fsproj", "{D0E98C0D-490B-4C61-9329-0862F6E87645}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Test.Utilities", "tests\FSharp.Test.Utilities\FSharp.Test.Utilities.fsproj", "{60D275B0-B14A-41CB-A1B2-E815A7448FCB}" +EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharpSuite.Tests", "tests\fsharp\FSharpSuite.Tests.fsproj", "{C163E892-5BF7-4B59-AA99-B0E8079C67C4}" + ProjectSection(ProjectDependencies) = postProject + {D0E98C0D-490B-4C61-9329-0862F6E87645} = {D0E98C0D-490B-4C61-9329-0862F6E87645} + {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} = {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} + {2E60864A-E3FF-4BCC-810F-DC7C34E6B236} = {2E60864A-E3FF-4BCC-810F-DC7C34E6B236} + {C94C257C-3C0A-4858-B5D8-D746498D1F08} = {C94C257C-3C0A-4858-B5D8-D746498D1F08} + EndProjectSection EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.UnitTests", "tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj", "{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core.UnitTests", "tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj", "{88E2D422-6852-46E3-A740-83E391DC7973}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppConfig", "vsintegration\ItemTemplates\AppConfig\AppConfig.csproj", "{6BA13AA4-C25F-480F-856B-8E8000299A72}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppConfig", "vsintegration\ItemTemplates\AppConfig\AppConfig.csproj", "{6BA13AA4-C25F-480F-856B-8E8000299A72}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeFile", "vsintegration\ItemTemplates\CodeFile\CodeFile.csproj", "{12AC2813-E895-4AAA-AE6C-94E21DA09F64}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeFile", "vsintegration\ItemTemplates\CodeFile\CodeFile.csproj", "{12AC2813-E895-4AAA-AE6C-94E21DA09F64}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptFile", "vsintegration\ItemTemplates\ScriptFile\ScriptFile.csproj", "{A333B85A-DC23-49B6-9797-B89A7951E92D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptFile", "vsintegration\ItemTemplates\ScriptFile\ScriptFile.csproj", "{A333B85A-DC23-49B6-9797-B89A7951E92D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignatureFile", "vsintegration\ItemTemplates\SignatureFile\SignatureFile.csproj", "{E3FDD4AC-46B6-4B9F-B672-317D1202CC50}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SignatureFile", "vsintegration\ItemTemplates\SignatureFile\SignatureFile.csproj", "{E3FDD4AC-46B6-4B9F-B672-317D1202CC50}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextFile", "vsintegration\ItemTemplates\TextFile\TextFile.csproj", "{D11FC318-8F5D-4C8C-9287-AB40A016D13C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextFile", "vsintegration\ItemTemplates\TextFile\TextFile.csproj", "{D11FC318-8F5D-4C8C-9287-AB40A016D13C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XMLFile", "vsintegration\ItemTemplates\XMLFile\XMLFile.csproj", "{1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XMLFile", "vsintegration\ItemTemplates\XMLFile\XMLFile.csproj", "{1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "HostedCompilerServer", "tests\fsharpqa\testenv\src\HostedCompilerServer\HostedCompilerServer.fsproj", "{4239EFEA-E746-446A-BF7A-51FCBAB13946}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ILComparer", "tests\fsharpqa\testenv\src\ILComparer\ILComparer.fsproj", "{2E60864A-E3FF-4BCC-810F-DC7C34E6B236}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "LanguageServiceProfiling", "vsintegration\Utils\LanguageServiceProfiling\LanguageServiceProfiling.fsproj", "{E7FA3A71-51AF-4FCA-9C2F-7C853E515903}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.UIResources", "vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj", "{C4586A06-1402-48BC-8E35-A1B8642F895B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharp_Analysis", "tests\service\data\CSharp_Analysis\CSharp_Analysis.csproj", "{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TestTP", "tests\service\data\TestTP\TestTP.fsproj", "{FF76BD3C-5E0A-4752-B6C3-044F6E15719B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceFile", "vsintegration\ItemTemplates\ResourceFile\ResourceFile.csproj", "{0385564F-07B4-4264-AB8A-17C393E9140C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResourceFile", "vsintegration\ItemTemplates\ResourceFile\ResourceFile.csproj", "{0385564F-07B4-4264-AB8A-17C393E9140C}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Build.UnitTests", "tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj", "{400FAB03-786E-40CC-85A8-04B0C2869B14}" EndProject @@ -140,23 +142,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.SDK", "set EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{647810D0-5307-448F-99A2-E83917010DAE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler", "src\fsharp\FSharp.Compiler.nuget\Microsoft.FSharp.Compiler.csproj", "{04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Core.nuget", "src\fsharp\FSharp.Core.nuget\FSharp.Core.nuget.csproj", "{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{60BAFFA5-6631-4328-B044-2E012AB76DCA}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer.UnitTests", "tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj", "{AAF2D233-1C38-4090-8FFA-F7C545625E06}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Editor.Helpers", "vsintegration\src\FSharp.Editor.Helpers\FSharp.Editor.Helpers.csproj", "{79255A92-ED00-40BA-9D64-12FCC664A976}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting", "src\fsharp\FSharp.Compiler.Private.Scripting\FSharp.Compiler.Private.Scripting.fsproj", "{20B7BC36-CF51-4D75-9E13-66681C07977F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler", "src\fsharp\Microsoft.FSharp.Compiler\Microsoft.FSharp.Compiler.csproj", "{04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting.UnitTests", "tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj", "{09F56540-AFA5-4694-B7A6-0DBF6D4618C2}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager", "src\fsharp\FSharp.DependencyManager\FSharp.DependencyManager.fsproj", "{DFA30881-C0B1-4813-B087-C21B5AF9B77F}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager.UnitTests", "tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj", "{AF7AE565-E1C4-4A24-BD4B-D7983FC84768}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager.Nuget", "src\fsharp\FSharp.DependencyManager.Nuget\FSharp.DependencyManager.Nuget.fsproj", "{DFA30881-C0B1-4813-B087-C21B5AF9B77F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualFSharpTemplates", "vsintegration\Vsix\VisualFSharpTemplates\VisualFSharpTemplates.csproj", "{AA259A37-418F-4E18-87B2-C7D5F8C26CC4}" EndProject @@ -168,6 +158,32 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryProject", "vsintegra EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TutorialProject", "vsintegration\ProjectTemplates\TutorialProject\TutorialProject.csproj", "{2937CBEC-262D-4C94-BE1D-291FAB72E3E8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TaskPerfCSharp", "tests\benchmarks\TaskPerfCSharp\TaskPerfCSharp.csproj", "{D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TaskPerf", "tests\benchmarks\TaskPerf\TaskPerf.fsproj", "{03596D51-754D-4644-8E23-84EC9532ABDC}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.ComponentTests", "tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj", "{0610FB97-7C15-422A-86FD-32335C6DF14D}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "src\fsharp\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service.Tests", "tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj", "{14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}" + ProjectSection(ProjectDependencies) = postProject + {FF76BD3C-5E0A-4752-B6C3-044F6E15719B} = {FF76BD3C-5E0A-4752-B6C3-044F6E15719B} + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB} = {887630A3-4B1D-40EA-B8B3-2D842E9C40DB} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualFSharpDebug", "vsintegration\Vsix\VisualFSharpFull\VisualFSharpDebug.csproj", "{A422D673-8E3B-4924-821B-DD3174173426}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{DFB6ADD7-3149-43D9-AFA0-FC4A818B472B}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Benchmarks", "tests\benchmarks\CompilerServiceBenchmarks\FSharp.Compiler.Benchmarks.fsproj", "{564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroPerfCSharp", "tests\benchmarks\MicroPerf\CS\MicroPerfCSharp.csproj", "{208E36EE-665C-42D2-B767-C6DB03C4FEB2}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MicroPerf", "tests\benchmarks\MicroPerf\MicroPerf.fsproj", "{EE08E954-AE91-4EFA-8595-10931D29E628}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MicroPerf", "MicroPerf", "{47112E07-9FF1-43E7-8021-F2A21D6A19A0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -190,18 +206,6 @@ Global {991DCF75-C2EB-42B6-9A0D-AA1D2409D519}.Release|Any CPU.Build.0 = Release|Any CPU {991DCF75-C2EB-42B6-9A0D-AA1D2409D519}.Release|x86.ActiveCfg = Release|Any CPU {991DCF75-C2EB-42B6-9A0D-AA1D2409D519}.Release|x86.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|x86.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|x86.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.Build.0 = Release|Any CPU {59ADCE46-9740-4079-834D-9A03A3494EBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {59ADCE46-9740-4079-834D-9A03A3494EBC}.Debug|Any CPU.Build.0 = Debug|Any CPU {59ADCE46-9740-4079-834D-9A03A3494EBC}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -538,6 +542,18 @@ Global {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.Build.0 = Release|Any CPU {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|x86.ActiveCfg = Release|Any CPU {D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|x86.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|x86.ActiveCfg = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Debug|x86.Build.0 = Debug|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|Any CPU.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|x86.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Proto|x86.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|Any CPU.Build.0 = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|x86.ActiveCfg = Release|Any CPU + {60D275B0-B14A-41CB-A1B2-E815A7448FCB}.Release|x86.Build.0 = Release|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.Build.0 = Debug|Any CPU {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -578,10 +594,10 @@ Global {6BA13AA4-C25F-480F-856B-8E8000299A72}.Debug|Any CPU.Build.0 = Debug|Any CPU {6BA13AA4-C25F-480F-856B-8E8000299A72}.Debug|x86.ActiveCfg = Debug|Any CPU {6BA13AA4-C25F-480F-856B-8E8000299A72}.Debug|x86.Build.0 = Debug|Any CPU - {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|Any CPU.Build.0 = Proto|Any CPU - {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|x86.ActiveCfg = Proto|Any CPU - {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|x86.Build.0 = Proto|Any CPU + {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|Any CPU.Build.0 = Release|Any CPU + {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|x86.ActiveCfg = Release|Any CPU + {6BA13AA4-C25F-480F-856B-8E8000299A72}.Proto|x86.Build.0 = Release|Any CPU {6BA13AA4-C25F-480F-856B-8E8000299A72}.Release|Any CPU.ActiveCfg = Release|Any CPU {6BA13AA4-C25F-480F-856B-8E8000299A72}.Release|Any CPU.Build.0 = Release|Any CPU {6BA13AA4-C25F-480F-856B-8E8000299A72}.Release|x86.ActiveCfg = Release|Any CPU @@ -590,10 +606,10 @@ Global {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Debug|Any CPU.Build.0 = Debug|Any CPU {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Debug|x86.ActiveCfg = Debug|Any CPU {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Debug|x86.Build.0 = Debug|Any CPU - {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|Any CPU.Build.0 = Proto|Any CPU - {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|x86.ActiveCfg = Proto|Any CPU - {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|x86.Build.0 = Proto|Any CPU + {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|Any CPU.Build.0 = Release|Any CPU + {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|x86.ActiveCfg = Release|Any CPU + {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Proto|x86.Build.0 = Release|Any CPU {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Release|Any CPU.ActiveCfg = Release|Any CPU {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Release|Any CPU.Build.0 = Release|Any CPU {12AC2813-E895-4AAA-AE6C-94E21DA09F64}.Release|x86.ActiveCfg = Release|Any CPU @@ -602,10 +618,10 @@ Global {A333B85A-DC23-49B6-9797-B89A7951E92D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A333B85A-DC23-49B6-9797-B89A7951E92D}.Debug|x86.ActiveCfg = Debug|Any CPU {A333B85A-DC23-49B6-9797-B89A7951E92D}.Debug|x86.Build.0 = Debug|Any CPU - {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|Any CPU.Build.0 = Proto|Any CPU - {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|x86.ActiveCfg = Proto|Any CPU - {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|x86.Build.0 = Proto|Any CPU + {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|Any CPU.Build.0 = Release|Any CPU + {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|x86.ActiveCfg = Release|Any CPU + {A333B85A-DC23-49B6-9797-B89A7951E92D}.Proto|x86.Build.0 = Release|Any CPU {A333B85A-DC23-49B6-9797-B89A7951E92D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A333B85A-DC23-49B6-9797-B89A7951E92D}.Release|Any CPU.Build.0 = Release|Any CPU {A333B85A-DC23-49B6-9797-B89A7951E92D}.Release|x86.ActiveCfg = Release|Any CPU @@ -614,10 +630,10 @@ Global {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Debug|Any CPU.Build.0 = Debug|Any CPU {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Debug|x86.ActiveCfg = Debug|Any CPU {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Debug|x86.Build.0 = Debug|Any CPU - {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|Any CPU.Build.0 = Proto|Any CPU - {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|x86.ActiveCfg = Proto|Any CPU - {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|x86.Build.0 = Proto|Any CPU + {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|Any CPU.Build.0 = Release|Any CPU + {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|x86.ActiveCfg = Release|Any CPU + {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Proto|x86.Build.0 = Release|Any CPU {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Release|Any CPU.ActiveCfg = Release|Any CPU {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Release|Any CPU.Build.0 = Release|Any CPU {E3FDD4AC-46B6-4B9F-B672-317D1202CC50}.Release|x86.ActiveCfg = Release|Any CPU @@ -626,10 +642,10 @@ Global {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Debug|Any CPU.Build.0 = Debug|Any CPU {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Debug|x86.ActiveCfg = Debug|Any CPU {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Debug|x86.Build.0 = Debug|Any CPU - {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|Any CPU.Build.0 = Proto|Any CPU - {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|x86.ActiveCfg = Proto|Any CPU - {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|x86.Build.0 = Proto|Any CPU + {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|Any CPU.Build.0 = Release|Any CPU + {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|x86.ActiveCfg = Release|Any CPU + {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Proto|x86.Build.0 = Release|Any CPU {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Release|Any CPU.ActiveCfg = Release|Any CPU {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Release|Any CPU.Build.0 = Release|Any CPU {D11FC318-8F5D-4C8C-9287-AB40A016D13C}.Release|x86.ActiveCfg = Release|Any CPU @@ -638,10 +654,10 @@ Global {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Debug|x86.ActiveCfg = Debug|Any CPU {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Debug|x86.Build.0 = Debug|Any CPU - {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|Any CPU.Build.0 = Proto|Any CPU - {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|x86.ActiveCfg = Proto|Any CPU - {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|x86.Build.0 = Proto|Any CPU + {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|Any CPU.Build.0 = Release|Any CPU + {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|x86.ActiveCfg = Release|Any CPU + {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Proto|x86.Build.0 = Release|Any CPU {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Release|Any CPU.Build.0 = Release|Any CPU {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6}.Release|x86.ActiveCfg = Release|Any CPU @@ -670,18 +686,6 @@ Global {2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Release|Any CPU.Build.0 = Release|Any CPU {2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Release|x86.ActiveCfg = Release|Any CPU {2E60864A-E3FF-4BCC-810F-DC7C34E6B236}.Release|x86.Build.0 = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Debug|x86.ActiveCfg = Debug|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Debug|x86.Build.0 = Debug|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Proto|Any CPU.Build.0 = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Proto|x86.ActiveCfg = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Proto|x86.Build.0 = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|Any CPU.Build.0 = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|x86.ActiveCfg = Release|Any CPU - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|x86.Build.0 = Release|Any CPU {C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -722,10 +726,10 @@ Global {0385564F-07B4-4264-AB8A-17C393E9140C}.Debug|Any CPU.Build.0 = Debug|Any CPU {0385564F-07B4-4264-AB8A-17C393E9140C}.Debug|x86.ActiveCfg = Debug|Any CPU {0385564F-07B4-4264-AB8A-17C393E9140C}.Debug|x86.Build.0 = Debug|Any CPU - {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|Any CPU.ActiveCfg = Proto|Any CPU - {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|Any CPU.Build.0 = Proto|Any CPU - {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|x86.ActiveCfg = Proto|Any CPU - {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|x86.Build.0 = Proto|Any CPU + {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|Any CPU.Build.0 = Release|Any CPU + {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|x86.ActiveCfg = Release|Any CPU + {0385564F-07B4-4264-AB8A-17C393E9140C}.Proto|x86.Build.0 = Release|Any CPU {0385564F-07B4-4264-AB8A-17C393E9140C}.Release|Any CPU.ActiveCfg = Release|Any CPU {0385564F-07B4-4264-AB8A-17C393E9140C}.Release|Any CPU.Build.0 = Release|Any CPU {0385564F-07B4-4264-AB8A-17C393E9140C}.Release|x86.ActiveCfg = Release|Any CPU @@ -838,66 +842,6 @@ Global {04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8}.Release|Any CPU.Build.0 = Release|Any CPU {04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8}.Release|x86.ActiveCfg = Release|Any CPU {04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8}.Release|x86.Build.0 = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Debug|x86.ActiveCfg = Debug|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Debug|x86.Build.0 = Debug|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Proto|Any CPU.Build.0 = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Proto|x86.ActiveCfg = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Proto|x86.Build.0 = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|Any CPU.Build.0 = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|x86.ActiveCfg = Release|Any CPU - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|x86.Build.0 = Release|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|x86.ActiveCfg = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|x86.Build.0 = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|Any CPU.Build.0 = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|x86.ActiveCfg = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|x86.Build.0 = Debug|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|Any CPU.Build.0 = Release|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|x86.ActiveCfg = Release|Any CPU - {60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|x86.Build.0 = Release|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|x86.ActiveCfg = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|x86.Build.0 = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|Any CPU.Build.0 = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|x86.ActiveCfg = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|x86.Build.0 = Debug|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|Any CPU.Build.0 = Release|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|x86.ActiveCfg = Release|Any CPU - {AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|x86.Build.0 = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|x86.ActiveCfg = Debug|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|x86.Build.0 = Debug|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|Any CPU.Build.0 = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|x86.ActiveCfg = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|x86.Build.0 = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Release|Any CPU.Build.0 = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Release|x86.ActiveCfg = Release|Any CPU - {79255A92-ED00-40BA-9D64-12FCC664A976}.Release|x86.Build.0 = Release|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|x86.ActiveCfg = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|x86.Build.0 = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Proto|Any CPU.Build.0 = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Proto|x86.ActiveCfg = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Proto|x86.Build.0 = Debug|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Release|Any CPU.Build.0 = Release|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Release|x86.ActiveCfg = Release|Any CPU - {20B7BC36-CF51-4D75-9E13-66681C07977F}.Release|x86.Build.0 = Release|Any CPU {09F56540-AFA5-4694-B7A6-0DBF6D4618C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {09F56540-AFA5-4694-B7A6-0DBF6D4618C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {09F56540-AFA5-4694-B7A6-0DBF6D4618C2}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -922,18 +866,6 @@ Global {DFA30881-C0B1-4813-B087-C21B5AF9B77F}.Release|Any CPU.Build.0 = Release|Any CPU {DFA30881-C0B1-4813-B087-C21B5AF9B77F}.Release|x86.ActiveCfg = Release|Any CPU {DFA30881-C0B1-4813-B087-C21B5AF9B77F}.Release|x86.Build.0 = Release|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Debug|x86.ActiveCfg = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Debug|x86.Build.0 = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Proto|Any CPU.Build.0 = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Proto|x86.ActiveCfg = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Proto|x86.Build.0 = Debug|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Release|Any CPU.Build.0 = Release|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Release|x86.ActiveCfg = Release|Any CPU - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768}.Release|x86.Build.0 = Release|Any CPU {AA259A37-418F-4E18-87B2-C7D5F8C26CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AA259A37-418F-4E18-87B2-C7D5F8C26CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU {AA259A37-418F-4E18-87B2-C7D5F8C26CC4}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -982,6 +914,114 @@ Global {2937CBEC-262D-4C94-BE1D-291FAB72E3E8}.Release|Any CPU.Build.0 = Release|Any CPU {2937CBEC-262D-4C94-BE1D-291FAB72E3E8}.Release|x86.ActiveCfg = Release|Any CPU {2937CBEC-262D-4C94-BE1D-291FAB72E3E8}.Release|x86.Build.0 = Release|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Debug|x86.Build.0 = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Proto|Any CPU.Build.0 = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Proto|x86.ActiveCfg = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Proto|x86.Build.0 = Debug|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Release|Any CPU.Build.0 = Release|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Release|x86.ActiveCfg = Release|Any CPU + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0}.Release|x86.Build.0 = Release|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Debug|x86.ActiveCfg = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Debug|x86.Build.0 = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Proto|Any CPU.Build.0 = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Proto|x86.ActiveCfg = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Proto|x86.Build.0 = Debug|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Release|Any CPU.Build.0 = Release|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Release|x86.ActiveCfg = Release|Any CPU + {03596D51-754D-4644-8E23-84EC9532ABDC}.Release|x86.Build.0 = Release|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Debug|x86.ActiveCfg = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Debug|x86.Build.0 = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Proto|Any CPU.Build.0 = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Proto|x86.ActiveCfg = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Proto|x86.Build.0 = Debug|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Release|Any CPU.Build.0 = Release|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Release|x86.ActiveCfg = Release|Any CPU + {0610FB97-7C15-422A-86FD-32335C6DF14D}.Release|x86.Build.0 = Release|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Debug|x86.ActiveCfg = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Debug|x86.Build.0 = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Proto|Any CPU.Build.0 = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Proto|x86.ActiveCfg = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Proto|x86.Build.0 = Debug|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Release|Any CPU.Build.0 = Release|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Release|x86.ActiveCfg = Release|Any CPU + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2}.Release|x86.Build.0 = Release|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Debug|x86.ActiveCfg = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Debug|x86.Build.0 = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Proto|Any CPU.Build.0 = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Proto|x86.ActiveCfg = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Proto|x86.Build.0 = Debug|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Release|Any CPU.Build.0 = Release|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Release|x86.ActiveCfg = Release|Any CPU + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA}.Release|x86.Build.0 = Release|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Debug|x86.ActiveCfg = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Debug|x86.Build.0 = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Proto|Any CPU.Build.0 = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Proto|x86.ActiveCfg = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Proto|x86.Build.0 = Debug|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Release|Any CPU.Build.0 = Release|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Release|x86.ActiveCfg = Release|Any CPU + {A422D673-8E3B-4924-821B-DD3174173426}.Release|x86.Build.0 = Release|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Debug|Any CPU.Build.0 = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Debug|x86.ActiveCfg = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Debug|x86.Build.0 = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Proto|Any CPU.Build.0 = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Proto|x86.ActiveCfg = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Proto|x86.Build.0 = Debug|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Release|Any CPU.ActiveCfg = Release|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Release|Any CPU.Build.0 = Release|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Release|x86.ActiveCfg = Release|Any CPU + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61}.Release|x86.Build.0 = Release|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Debug|x86.ActiveCfg = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Debug|x86.Build.0 = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Proto|Any CPU.Build.0 = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Proto|x86.ActiveCfg = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Proto|x86.Build.0 = Debug|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Release|Any CPU.Build.0 = Release|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Release|x86.ActiveCfg = Release|Any CPU + {208E36EE-665C-42D2-B767-C6DB03C4FEB2}.Release|x86.Build.0 = Release|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Debug|x86.ActiveCfg = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Debug|x86.Build.0 = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Proto|Any CPU.ActiveCfg = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Proto|Any CPU.Build.0 = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Proto|x86.ActiveCfg = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Proto|x86.Build.0 = Debug|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Release|Any CPU.Build.0 = Release|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Release|x86.ActiveCfg = Release|Any CPU + {EE08E954-AE91-4EFA-8595-10931D29E628}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -990,16 +1030,14 @@ Global {3F044931-FB83-4433-B934-AE66AB27B278} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {F6DAEE9A-8BE1-4C4A-BC83-09215517C7DA} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} - {D086C8C6-D00D-4C3B-9AB2-A4286C9F5922} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {35636A82-401A-4C3A-B2AB-EB7DC5E9C268} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} {CCAB6E50-34C6-42AF-A6B0-567C29FCD91B} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {991DCF75-C2EB-42B6-9A0D-AA1D2409D519} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} {59ADCE46-9740-4079-834D-9A03A3494EBC} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06} = {B8DDA694-7939-42E3-95E5-265C2217C142} {DED3BBD7-53F4-428A-8C9F-27968E768605} = {3058BC79-8E79-4645-B05D-48CC182FA8A6} - {EE85AAB7-CDA0-4C4E-BDA0-A64CCC413E3F} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} - {1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} + {EE85AAB7-CDA0-4C4E-BDA0-A64CCC413E3F} = {CCAB6E50-34C6-42AF-A6B0-567C29FCD91B} + {1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF} = {CCAB6E50-34C6-42AF-A6B0-567C29FCD91B} {65E0E82A-EACE-4787-8994-888674C2FE87} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7} = {CCAB6E50-34C6-42AF-A6B0-567C29FCD91B} {FCFB214C-462E-42B3-91CA-FC557EFEE74F} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} @@ -1023,6 +1061,7 @@ Global {649FA588-F02E-457C-9FCF-87E46407481E} = {B8DDA694-7939-42E3-95E5-265C2217C142} {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} = {B8DDA694-7939-42E3-95E5-265C2217C142} {D0E98C0D-490B-4C61-9329-0862F6E87645} = {B8DDA694-7939-42E3-95E5-265C2217C142} + {60D275B0-B14A-41CB-A1B2-E815A7448FCB} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {C163E892-5BF7-4B59-AA99-B0E8079C67C4} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {88E2D422-6852-46E3-A740-83E391DC7973} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} @@ -1034,7 +1073,6 @@ Global {1FB1DD07-06AA-45B4-B5AC-20FF5BEE98B6} = {F6DAEE9A-8BE1-4C4A-BC83-09215517C7DA} {4239EFEA-E746-446A-BF7A-51FCBAB13946} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {2E60864A-E3FF-4BCC-810F-DC7C34E6B236} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} - {E7FA3A71-51AF-4FCA-9C2F-7C853E515903} = {D086C8C6-D00D-4C3B-9AB2-A4286C9F5922} {C4586A06-1402-48BC-8E35-A1B8642F895B} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {887630A3-4B1D-40EA-B8B3-2D842E9C40DB} = {35636A82-401A-4C3A-B2AB-EB7DC5E9C268} {FF76BD3C-5E0A-4752-B6C3-044F6E15719B} = {35636A82-401A-4C3A-B2AB-EB7DC5E9C268} @@ -1048,19 +1086,23 @@ Global {E93E7D28-1C6B-4E04-BE83-68428CF7E039} = {6235B3AF-774D-4EA1-8F37-789E767F6368} {9482211E-23D0-4BD0-9893-E4AA5559F67A} = {6235B3AF-774D-4EA1-8F37-789E767F6368} {04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8} = {647810D0-5307-448F-99A2-E83917010DAE} - {8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC} = {647810D0-5307-448F-99A2-E83917010DAE} - {60BAFFA5-6631-4328-B044-2E012AB76DCA} = {B8DDA694-7939-42E3-95E5-265C2217C142} - {AAF2D233-1C38-4090-8FFA-F7C545625E06} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} - {79255A92-ED00-40BA-9D64-12FCC664A976} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} - {20B7BC36-CF51-4D75-9E13-66681C07977F} = {B8DDA694-7939-42E3-95E5-265C2217C142} {09F56540-AFA5-4694-B7A6-0DBF6D4618C2} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {DFA30881-C0B1-4813-B087-C21B5AF9B77F} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} - {AF7AE565-E1C4-4A24-BD4B-D7983FC84768} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {AA259A37-418F-4E18-87B2-C7D5F8C26CC4} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {12EF27FD-A34B-4373-860A-F9FCE9651859} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} {44155269-9B30-43DA-B97F-4F36F887B211} = {12EF27FD-A34B-4373-860A-F9FCE9651859} {B53D9D05-8EF7-43A6-9A5B-0B113CBC54F8} = {12EF27FD-A34B-4373-860A-F9FCE9651859} {2937CBEC-262D-4C94-BE1D-291FAB72E3E8} = {12EF27FD-A34B-4373-860A-F9FCE9651859} + {D5ECF8DF-E150-4AE3-B613-AB2B0FFA93E0} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {03596D51-754D-4644-8E23-84EC9532ABDC} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {0610FB97-7C15-422A-86FD-32335C6DF14D} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {B5A9BBD9-2F45-4722-A6CA-BAE3C64CD4E2} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77} + {14F3D3D6-5C8E-43C2-98A2-17EA704D4DEA} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} + {A422D673-8E3B-4924-821B-DD3174173426} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D} + {564E7DC5-11CB-4FCF-ABDD-23AD93AF3A61} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} + {208E36EE-665C-42D2-B767-C6DB03C4FEB2} = {47112E07-9FF1-43E7-8021-F2A21D6A19A0} + {EE08E954-AE91-4EFA-8595-10931D29E628} = {47112E07-9FF1-43E7-8021-F2A21D6A19A0} + {47112E07-9FF1-43E7-8021-F2A21D6A19A0} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {48EDBBBE-C8EE-4E3C-8B19-97184A487B37} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1906529ef34..2accfcebf6b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,14 +1,49 @@ # CI and PR triggers trigger: -- master -- dev16.1 -- feature/* -- release/* + branches: + include: + - main + - dev16.1 + - feature/* + - release/* + paths: + include: + - '*' + exclude: + - .github/* + - docs/compiler-guide.md + - attributions.md + - CODE_OF_CONDUCT.md + - DEVGUIDE.md + - INTERNAL.md + - Language-Version-History.md + - License.txt + - README.md + - release-notes.md + - TESTGUIDE.md + pr: -- master -- dev16.1 -- feature/* -- release/* + branches: + include: + - main + - dev16.1 + - feature/* + - release/* + paths: + include: + - '*' + exclude: + - .github/* + - docs/compiler-guide.md + - attributions.md + - CODE_OF_CONDUCT.md + - DEVGUIDE.md + - INTERNAL.md + - Language-Version-History.md + - License.txt + - README.md + - release-notes.md + - TESTGUIDE.md variables: - name: _TeamName @@ -21,6 +56,9 @@ variables: value: .NETCore - name: VisualStudioDropName value: Products/$(System.TeamProject)/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber) + - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}: + - name: RunningAsPullRequest + value: true # Variables defined in yml cannot be overridden at queue time; instead overridable variables must be defined in the web UI. # Commenting out until something like this is supported: https://github.com/Microsoft/azure-pipelines-yaml/pull/129 @@ -37,6 +75,12 @@ stages: # Signed build # #-------------------------------------------------------------------------------------------------------------------# - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: + - template: /eng/common/templates/job/onelocbuild.yml + parameters: + MirrorRepo: fsharp + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-FSHARP' - template: /eng/common/templates/jobs/jobs.yml parameters: enableMicrobuild: true @@ -44,6 +88,7 @@ stages: enablePublishTestResults: false enablePublishBuildAssets: true enablePublishUsingPipelines: $(_PublishUsingPipelines) + enableSourceBuild: true enableTelemetry: true helixRepo: dotnet/fsharp jobs: @@ -83,6 +128,8 @@ stages: /p:OfficialBuildId=$(BUILD.BUILDNUMBER) /p:PublishToSymbolServer=true /p:VisualStudioDropName=$(VisualStudioDropName) + - script: .\tests\EndToEndBuildTests\EndToEndBuildTests.cmd -c $(_BuildConfig) + displayName: End to end build tests - task: PublishTestResults@2 displayName: Publish Test Results inputs: @@ -114,7 +161,7 @@ stages: - task: PublishBuildArtifacts@1 displayName: Publish Artifact Nightly inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpFull.vsix' + PathtoPublish: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(_BuildConfig)\VisualFSharpDebug.vsix' ArtifactName: 'Nightly' condition: succeeded() - task: PublishBuildArtifacts@1 @@ -142,6 +189,7 @@ stages: enablePublishTestResults: false enablePublishBuildAssets: true enablePublishUsingPipelines: $(_PublishUsingPipelines) + enableSourceBuild: true enableTelemetry: true helixRepo: dotnet/fsharp jobs: @@ -149,7 +197,12 @@ stages: # Windows - job: Windows pool: - vmImage: windows-2019 + # The PR build definition sets this variable: + # WindowsMachineQueueName=BuildPool.Windows.10.Amd64.VS2019.Open + # and there is an alternate build definition that sets this to a queue that is always scouting the + # next preview of Visual Studio. + name: NetCorePublic-Pool + queue: $(WindowsMachineQueueName) timeoutInMinutes: 120 strategy: maxParallel: 4 @@ -186,12 +239,33 @@ stages: ArtifactName: 'Windows $(_configuration) $(_testKind) test logs' publishLocation: Container continueOnError: true - condition: eq(variables['_testKind'], 'testFSharpQA') + condition: failed() + - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj + displayName: Dump NuGet cache contents + condition: failed() + - task: PublishBuildArtifacts@1 + displayName: Publish NuGet cache contents + inputs: + PathtoPublish: '$(Build.SourcesDirectory)\artifacts\NugetPackageRootContents' + ArtifactName: 'NuGetPackageContents Windows $(_testKind)' + publishLocation: Container + continueOnError: true + condition: failed() + + # Mock official build + - job: MockOfficial + pool: + vmImage: windows-latest + steps: + - checkout: self + clean: true + - pwsh: .\eng\MockBuild.ps1 + displayName: Build with OfficialBuildId # Linux - job: Linux pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-latest variables: - name: _SignType value: Test @@ -208,11 +282,30 @@ stages: searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' continueOnError: true condition: always() + - task: PublishBuildArtifacts@1 + displayName: Publish Test Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + ArtifactName: 'Linux $(_BuildConfig) test logs' + publishLocation: Container + continueOnError: true + condition: failed() + - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj + displayName: Dump NuGet cache contents + condition: failed() + - task: PublishBuildArtifacts@1 + displayName: Publish NuGet cache contents + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/NugetPackageRootContents' + ArtifactName: 'NuGetPackageContents Linux' + publishLocation: Container + continueOnError: true + condition: failed() # MacOS - job: MacOS pool: - vmImage: macOS-10.13 + vmImage: macOS-latest variables: - name: _SignType value: Test @@ -229,98 +322,160 @@ stages: searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' continueOnError: true condition: always() + - task: PublishBuildArtifacts@1 + displayName: Publish Test Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + ArtifactName: 'MacOS $(_BuildConfig) test logs' + publishLocation: Container + continueOnError: true + condition: failed() + - script: dotnet build $(Build.SourcesDirectory)/eng/DumpPackageRoot/DumpPackageRoot.csproj + displayName: Dump NuGet cache contents + condition: failed() + - task: PublishBuildArtifacts@1 + displayName: Publish NuGet cache contents + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/NugetPackageRootContents' + ArtifactName: 'NuGetPackageContents Mac' + publishLocation: Container + continueOnError: true + condition: failed() - # Source Build Linux - - job: SourceBuild_Linux + # End to end build + - job: EndToEndBuildTests pool: - vmImage: ubuntu-16.04 + vmImage: windows-latest steps: - checkout: self clean: true - - script: ./eng/cibuild.sh --configuration Release /p:DotNetBuildFromSource=true /p:FSharpSourceBuild=true - displayName: Build + - script: .\Build.cmd -c Release + - script: .\tests\EndToEndBuildTests\EndToEndBuildTests.cmd -c Release + displayName: End to end build tests - # Source Build Windows - - job: SourceBuild_Windows - pool: - vmImage: windows-2019 - steps: - - checkout: self - clean: true - - script: eng\CIBuild.cmd -configuration Release -noSign /p:DotNetBuildFromSource=true /p:FSharpSourceBuild=true - displayName: Build + # Up-to-date - disabled due to it being flaky + #- job: UpToDate_Windows + # pool: + # vmImage: windows-latest + # steps: + # - checkout: self + # clean: true + # - task: PowerShell@2 + # displayName: Run up-to-date build check + # inputs: + # filePath: eng\tests\UpToDate.ps1 + # arguments: -configuration $(_BuildConfig) -ci -binaryLog - # Up-to-date - - job: UpToDate_Windows + # Plain build Windows + - job: Plain_Build_Windows pool: - vmImage: windows-2019 + vmImage: windows-latest + variables: + - name: _BuildConfig + value: Debug steps: - checkout: self clean: true - - task: PowerShell@2 - displayName: Run up-to-date build check + - script: .\Build.cmd + displayName: Initial build + - script: dotnet --list-sdks + displayName: Report dotnet SDK versions + - task: UseDotNet@2 + displayName: install SDK inputs: - filePath: eng\tests\UpToDate.ps1 - arguments: -configuration $(_BuildConfig) -ci -binaryLog + packageType: sdk + useGlobalJson: true + includePreviewVersions: true + workingDirectory: $(Build.SourcesDirectory) + installationPath: $(Agent.ToolsDirectory)/dotnet + - script: dotnet build .\FSharp.sln /bl:\"artifacts/log/$(_BuildConfig)/RegularBuild.binlog\" + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.sln + - script: dotnet build .\FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" + workingDirectory: $(Build.SourcesDirectory)/service + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.Compiler.Service.sln - #-------------------------------------------------------------------------------------------------------------------# - # FCS builds # - #-------------------------------------------------------------------------------------------------------------------# - - - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - template: /eng/common/templates/jobs/jobs.yml - parameters: - enableMicrobuild: true - enablePublishTestResults: false - enablePublishBuildAssets: true - enablePublishUsingPipelines: false - enableTelemetry: true - helixRepo: dotnet/fsharp - jobs: - - - job: Windows_FCS + # Plain build Linux + - job: Plain_Build_Linux pool: - vmImage: windows-2019 + vmImage: ubuntu-latest variables: - - name: _SignType - value: Test + - name: _BuildConfig + value: Debug steps: - checkout: self clean: true - - script: fcs\build.cmd TestAndNuget - displayName: Build / Test - - task: PublishTestResults@2 - displayName: Publish Test Results + - script: ./build.sh + displayName: Initial build + - script: dotnet --list-sdks + displayName: Report dotnet SDK versions + - task: UseDotNet@2 + displayName: install SDK inputs: - testResultsFormat: 'NUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/Release' - continueOnError: true - condition: always() + packageType: sdk + useGlobalJson: true + includePreviewVersions: true + workingDirectory: $(Build.SourcesDirectory) + installationPath: $(Agent.ToolsDirectory)/dotnet + - script: dotnet build ./FSharp.sln /bl:\"artifacts/log/$(_BuildConfig)/RegularBuild.binlog\" + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.sln + - script: dotnet build ./FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" + workingDirectory: $(Build.SourcesDirectory)/service + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.Compiler.Service.sln - - job: Linux_FCS + # Plain build Mac + - job: Plain_Build_MacOS pool: - vmImage: ubuntu-16.04 + vmImage: macos-latest variables: - - name: _SignType - value: Test + - name: _BuildConfig + value: Debug steps: - checkout: self clean: true - - script: ./fcs/build.sh - displayName: Build + - script: ./build.sh + displayName: Initial build + - script: dotnet --list-sdks + displayName: Report dotnet SDK versions + - task: UseDotNet@2 + displayName: install SDK + inputs: + packageType: sdk + useGlobalJson: true + includePreviewVersions: true + workingDirectory: $(Build.SourcesDirectory) + installationPath: $(Agent.ToolsDirectory)/dotnet + - script: dotnet build ./FSharp.sln /bl:\"artifacts/log/$(_BuildConfig)/RegularBuild.binlog\" + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.sln + - script: dotnet build ./FSharp.Compiler.Service.sln /bl:\"artifacts/log/$(_BuildConfig)/ServiceRegularBuild.binlog\" + workingDirectory: $(Build.SourcesDirectory)/service + env: + DOTNET_ROLL_FORWARD_TO_PRERELEASE: 1 + displayName: Regular rebuild of FSharp.Compiler.Service.sln - # - job: MacOS_FCS - # pool: - # vmImage: macOS-10.13 - # variables: - # - name: _SignType - # value: Test - # steps: - # - checkout: self - # clean: true - # - script: ./fcs/build.sh - # displayName: Build + # Arcade-powered source build + # turned off until https://github.com/dotnet/source-build/issues/1795 is fixed + # - template: /eng/common/templates/jobs/jobs.yml + # parameters: + # enablePublishUsingPipelines: true + # enablePublishBuildArtifacts: true + # enablePublishBuildAssets: true + # artifacts: + # publish: + # artifacts: true + # manifests: true + # runSourceBuild: true + # sourceBuildParameters: + # includeDefaultManagedPlatform: true #---------------------------------------------------------------------------------------------------------------------# # Post Build # @@ -328,6 +483,7 @@ stages: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: eng/common/templates/post-build/post-build.yml parameters: + publishingInfraVersion: 3 # Symbol validation is not entirely reliable as of yet, so should be turned off until https://github.com/dotnet/arcade/issues/2871 is resolved. enableSymbolValidation: false # SourceLink improperly looks for generated files. See https://github.com/dotnet/arcade/issues/3069 @@ -339,7 +495,8 @@ stages: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: eng/release/insert-into-vs.yml parameters: - componentBranchName: refs/heads/release/dev16.5 - insertTargetBranch: master + componentBranchName: refs/heads/release/dev16.9 + insertTargetBranch: rel/d16.9 insertTeamEmail: fsharpteam@microsoft.com insertTeamName: 'F#' + completeInsertion: 'auto' diff --git a/benchmarks/Benchmarks.sln b/benchmarks/Benchmarks.sln deleted file mode 100644 index 3d490e60b8c..00000000000 --- a/benchmarks/Benchmarks.sln +++ /dev/null @@ -1,44 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28407.52 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CompilerServiceBenchmarks", "CompilerServiceBenchmarks\CompilerServiceBenchmarks.fsproj", "{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}" -EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "..\src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Proto|Any CPU = Proto|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Proto|Any CPU.ActiveCfg = Release|Any CPU - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Proto|Any CPU.Build.0 = Release|Any CPU - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.Build.0 = Release|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Proto|Any CPU.Build.0 = Debug|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {049A4D02-709F-418C-AD59-7FB0DBE956B1} - EndGlobalSection -EndGlobal diff --git a/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj b/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj deleted file mode 100644 index 2fb509e4c14..00000000000 --- a/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $(MSBuildProjectDirectory)\..\..\src - - - - Exe - net472 - true - true - $(SystemValueTupleVersion) - - - - AnyCPU - - - - - - - - - - - - - - - - - diff --git a/benchmarks/CompilerServiceBenchmarks/Program.fs b/benchmarks/CompilerServiceBenchmarks/Program.fs deleted file mode 100644 index 201856e3f98..00000000000 --- a/benchmarks/CompilerServiceBenchmarks/Program.fs +++ /dev/null @@ -1,321 +0,0 @@ -open System -open System.IO -open System.Text -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILBinaryReader -open Microsoft.CodeAnalysis.Text -open BenchmarkDotNet.Attributes -open BenchmarkDotNet.Running - -module private SourceText = - - open System.Runtime.CompilerServices - - let weakTable = ConditionalWeakTable() - - let create (sourceText: SourceText) = - - let sourceText = - { new ISourceText with - - member __.Item with get index = sourceText.[index] - - member __.GetLineString(lineIndex) = - sourceText.Lines.[lineIndex].ToString() - - member __.GetLineCount() = - sourceText.Lines.Count - - member __.GetLastCharacterPosition() = - if sourceText.Lines.Count > 0 then - (sourceText.Lines.Count, sourceText.Lines.[sourceText.Lines.Count - 1].Span.Length) - else - (0, 0) - - member __.GetSubTextString(start, length) = - sourceText.GetSubText(TextSpan(start, length)).ToString() - - member __.SubTextEquals(target, startIndex) = - if startIndex < 0 || startIndex >= sourceText.Length then - raise (ArgumentOutOfRangeException("startIndex")) - - if String.IsNullOrEmpty(target) then - raise (ArgumentException("Target is null or empty.", "target")) - - let lastIndex = startIndex + target.Length - if lastIndex <= startIndex || lastIndex >= sourceText.Length then - raise (ArgumentException("Target is too big.", "target")) - - let mutable finished = false - let mutable didEqual = true - let mutable i = 0 - while not finished && i < target.Length do - if target.[i] <> sourceText.[startIndex + i] then - didEqual <- false - finished <- true // bail out early - else - i <- i + 1 - - didEqual - - member __.ContentEquals(sourceText) = - match sourceText with - | :? SourceText as sourceText -> sourceText.ContentEquals(sourceText) - | _ -> false - - member __.Length = sourceText.Length - - member __.CopyTo(sourceIndex, destination, destinationIndex, count) = - sourceText.CopyTo(sourceIndex, destination, destinationIndex, count) - } - - sourceText - -type SourceText with - - member this.ToFSharpSourceText() = - SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create)) - -[] -module Helpers = - - let createProject name referencedProjects = - let tmpPath = Path.GetTempPath() - let file = Path.Combine(tmpPath, Path.ChangeExtension(name, ".fs")) - { - ProjectFileName = Path.Combine(tmpPath, Path.ChangeExtension(name, ".dll")) - ProjectId = None - SourceFiles = [|file|] - OtherOptions = - Array.append [|"--optimize+"; "--target:library" |] (referencedProjects |> Array.ofList |> Array.map (fun x -> "-r:" + x.ProjectFileName)) - ReferencedProjects = - referencedProjects - |> List.map (fun x -> (x.ProjectFileName, x)) - |> Array.ofList - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime() - UnresolvedReferences = None - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = Some 0L (* set the stamp to 0L on each run so we don't evaluate the whole project again *) - } - - let generateSourceCode moduleName = - sprintf """ -module Benchmark.%s - -type %s = - - val X : int - - val Y : int - - val Z : int - -let function%s (x: %s) = - let x = 1 - let y = 2 - let z = x + y - z""" moduleName moduleName moduleName moduleName - -[] -type CompilerService() = - - let mutable checkerOpt = None - - let mutable sourceOpt = None - - let parsingOptions = - { - SourceFiles = [|"TypeChecker.fs"|] - ConditionalCompilationDefines = [] - ErrorSeverityOptions = FSharpErrorSeverityOptions.Default - IsInteractive = false - LightSyntax = None - CompilingFsLib = false - IsExe = false - } - - let mutable assembliesOpt = None - - let readerOptions = - { - pdbDirPath = None - ilGlobals = mkILGlobals ILScopeRef.Local - reduceMemoryUsage = ReduceMemoryFlag.No - metadataOnly = MetadataOnlyFlag.Yes - tryGetMetadataSnapshot = fun _ -> None - } - - [] - member __.Setup() = - match checkerOpt with - | None -> checkerOpt <- Some(FSharpChecker.Create(projectCacheSize = 200)) - | _ -> () - - match sourceOpt with - | None -> - sourceOpt <- Some <| SourceText.From(File.OpenRead("""..\..\..\..\..\src\fsharp\TypeChecker.fs"""), Encoding.Default, SourceHashAlgorithm.Sha1, true) - | _ -> () - - match assembliesOpt with - | None -> - assembliesOpt <- - System.AppDomain.CurrentDomain.GetAssemblies() - |> Array.map (fun x -> (x.Location)) - |> Some - | _ -> () - - [] - member __.ParsingTypeCheckerFs() = - match checkerOpt, sourceOpt with - | None, _ -> failwith "no checker" - | _, None -> failwith "no source" - | Some(checker), Some(source) -> - let results = checker.ParseFile("TypeChecker.fs", source.ToFSharpSourceText(), parsingOptions) |> Async.RunSynchronously - if results.ParseHadErrors then failwithf "parse had errors: %A" results.Errors - - [] - member __.ParsingTypeCheckerFsSetup() = - match checkerOpt with - | None -> failwith "no checker" - | Some(checker) -> - checker.InvalidateAll() - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - checker.ParseFile("dummy.fs", SourceText.ofString "dummy", parsingOptions) |> Async.RunSynchronously |> ignore - ClearAllILModuleReaderCache() - - [] - member __.ILReading() = - match assembliesOpt with - | None -> failwith "no assemblies" - | Some(assemblies) -> - // We try to read most of everything in the assembly that matter, mainly types with their properties, methods, and fields. - // CustomAttrs and SecurityDecls are lazy until you call them, so we call them here for benchmarking. - assemblies - |> Array.iter (fun (fileName) -> - let reader = OpenILModuleReader fileName readerOptions - - let ilModuleDef = reader.ILModuleDef - - let ilAssemblyManifest = ilModuleDef.Manifest.Value - - ilAssemblyManifest.CustomAttrs |> ignore - ilAssemblyManifest.SecurityDecls |> ignore - ilAssemblyManifest.ExportedTypes.AsList - |> List.iter (fun x -> - x.CustomAttrs |> ignore - ) - - ilModuleDef.CustomAttrs |> ignore - ilModuleDef.TypeDefs.AsArray - |> Array.iter (fun ilTypeDef -> - ilTypeDef.CustomAttrs |> ignore - ilTypeDef.SecurityDecls |> ignore - - ilTypeDef.Methods.AsArray - |> Array.iter (fun ilMethodDef -> - ilMethodDef.CustomAttrs |> ignore - ilMethodDef.SecurityDecls |> ignore - ) - - ilTypeDef.Fields.AsList - |> List.iter (fun ilFieldDef -> - ilFieldDef.CustomAttrs |> ignore - ) - - ilTypeDef.Properties.AsList - |> List.iter (fun ilPropertyDef -> - ilPropertyDef.CustomAttrs |> ignore - ) - ) - ) - - [] - member __.ILReadingSetup() = - // With caching, performance increases an order of magnitude when re-reading an ILModuleReader. - // Clear it for benchmarking. - ClearAllILModuleReaderCache() - - member val TypeCheckFileWith100ReferencedProjectsOptions = - createProject "MainProject" - [ for i = 1 to 100 do - yield - createProject ("ReferencedProject" + string i) [] - ] - - member this.TypeCheckFileWith100ReferencedProjectsRun() = - let options = this.TypeCheckFileWith100ReferencedProjectsOptions - let file = options.SourceFiles.[0] - - match checkerOpt with - | None -> failwith "no checker" - | Some checker -> - let parseResult, checkResult = - checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString (File.ReadAllText(file)), options) - |> Async.RunSynchronously - - if parseResult.Errors.Length > 0 then - failwithf "%A" parseResult.Errors - - match checkResult with - | FSharpCheckFileAnswer.Aborted -> failwith "aborted" - | FSharpCheckFileAnswer.Succeeded checkFileResult -> - - if checkFileResult.Errors.Length > 0 then - failwithf "%A" checkFileResult.Errors - - [] - member this.TypeCheckFileWith100ReferencedProjectsSetup() = - this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles - |> Seq.iter (fun file -> - File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) - ) - - this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects - |> Seq.iter (fun (_, referencedProjectOptions) -> - referencedProjectOptions.SourceFiles - |> Seq.iter (fun file -> - File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) - ) - ) - - this.TypeCheckFileWith100ReferencedProjectsRun() - - [] - member this.TypeCheckFileWith100ReferencedProjects() = - // Because the checker's projectcachesize is set to 200, this should be fast. - // If set to 3, it will be almost as slow as re-evaluating all project and it's projects references on setup; this could be a bug or not what we want. - this.TypeCheckFileWith100ReferencedProjectsRun() - - [] - member this.TypeCheckFileWith100ReferencedProjectsCleanup() = - this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles - |> Seq.iter (fun file -> - try File.Delete(file) with | _ -> () - ) - - this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects - |> Seq.iter (fun (_, referencedProjectOptions) -> - referencedProjectOptions.SourceFiles - |> Seq.iter (fun file -> - try File.Delete(file) with | _ -> () - ) - ) - - match checkerOpt with - | None -> failwith "no checker" - | Some(checker) -> - checker.InvalidateAll() - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - ClearAllILModuleReaderCache() - -[] -let main argv = - let _ = BenchmarkRunner.Run() - 0 diff --git a/docs/compiler-guide.md b/docs/compiler-guide.md new file mode 100644 index 00000000000..86e23265268 --- /dev/null +++ b/docs/compiler-guide.md @@ -0,0 +1,596 @@ +# F# compiler guide + +This guide discusses the F# compiler source code and implementation from a technical point of view. + +## Overview + +There are several artifacts involved in the development of F#: + +* The [F# compiler library](https://github.com/dotnet/fsharp/tree/main/src/fsharp/FSharp.Compiler.Service), called `FSharp.Compiler.Service`. Contains all logic for F# compilation - including parsing, syntax tree processing, typechecking, constraint solving, optimizations, IL importing, IL writing, pretty printing of F# constructs, and F# metadata format processing - and the F# compiler APIs for tooling. + +* The [F# compiler executable](https://github.com/dotnet/fsharp/tree/main/src/fsharp/fsc), called `fsc`, which is called as a console app. It sets the .NET GC into batch mode and then invokes `FSharp.Compiler.Service` with command-line arguments. + +* The [F# Core Library](https://github.com/dotnet/fsharp/tree/main/src/fsharp/FSharp.Core), called `FSharp.Core`. Contains all primitive F# types and logic for how they interact, core data structures and library functions for operating on them, structured printing logic, units of measure for scientific programming, core numeric functionality, F# quotations, F# type reflection logic, and asynchronous programming types and logic. + +* The [F# Interactive tool](https://github.com/dotnet/fsharp/tree/main/src/fsharp/fsi), called `fsi`. A REPL for F# that supports execution and pretty-printing of F# code and results, loading F# script files, referencing assemblies, and referencing packages from NuGet. + +The `FSharp.Compiler.Service` is by far the largest of these components and contains nearly all logic that `fsc` and `fsi` use. It is the primary subject of this guide. + +## Resources for learning + +* Video: [Learn me some F# Compiler, an online chat with Vlad and Don](https://www.youtube.com/watch?v=-dKf15xSWPY) + +* Video: [Understanding the F# Optimizer, and online chat with Vlad and Don](https://www.youtube.com/watch?v=sfAe5lDue7k) + +## Key data formats and representations + +The following are the key data formats and internal data representations of the F# compiler code in its various configurations: + +* _Input source files_ Read as Unicode text, or binary for referenced assemblies. + +* _Input command-line arguments_ See [CompilerOptions.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CompilerOptions.fs) for the full code implementing the arguments table. Command-line arguments are also accepted by the F# Compiler Service API in project specifications, and as optional input to F# Interactive. + +* _Tokens_, see [pars.fsy](https://github.com/dotnet/fsharp/blob/main/src/fsharp/pars.fsy), [lex.fsl](https://github.com/dotnet/fsharp/blob/main/src/fsharp/lex.fsl), [lexhelp.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/lexhelp.fs) and related files. + +* _Abstract Syntax Tree (AST)_, see [SyntaxTree.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/SyntaxTree.fs), the untyped syntax tree resulting from parsing. + +* _Typed Abstract Syntax Tree (Typed Tree)_, see [TypedTree.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTree.fs), [TypedTreeBasics.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTree.fs), [TypedTreeOps.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTreeOps.fs), and related files. The typed, bound syntax tree including both type/module definitions and their backing expressions, resulting from type checking and the subject of successive phases of optimization and representation change. + +* _Type checking context/state_, see for example [`TcState` in ParseAndCheckInputs.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ParseAndCheckInputs.fsi) and its constituent parts, particularly `TcEnv` in [CheckExpressions.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CheckExpressions.fsi) and `NameResolutionEnv` in [NameResolution.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/NameResolution.fsi). A set of tables representing the available names, assemblies etc. in scope during type checking, plus associated information. + +* _Abstract IL_, the output of code generation, then used for binary generation, and the input format when reading .NET assemblies, see [`ILModuleDef` in il.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/il.fsi). + +* _The .NET Binary format_ (with added "pickled" F# Metadata resource), the final output of fsc.exe, see the ECMA 335 specification and the [ilread.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilread.fs) and [ilwrite.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilwrite.fs) binary reader/generator implementations. The added F# metadata is stored in a binary resource, see [TypedTreePickle.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTreePickle.fs). + +* _The incrementally emitted .NET reflection assembly,_ the incremental output of fsi.exe. See [ilreflect.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilreflect.fs). + +## Key constructs and APIs for F# tooling + +The following are the most relevant parts of the F# compiler tooling, making up the "engine" and API surface area of `FSharp.Compiler.Service`. + +* The incremental project build engine state in [IncrementalBuild.fsi](https://github.com/fsharp/FSharp.Compiler.Service/tree/master/src/fsharp/service/IncrementalBuild.fsi)/[IncrementalBuild.fs](https://github.com/fsharp/FSharp.Compiler.Service/tree/master/src/fsharp/service/IncrementalBuild.fs), a part of the F# Compiler Service API. + +* The corresponding APIs wrapping and accessing these structures in the public-facing [`FSharp.Compiler.Service` API](https://github.com/dotnet/fsharp/tree/main/src/fsharp/service) and [Symbol API](https://github.com/dotnet/fsharp/tree/main/src/fsharp/symbols). + +* The [F# Compiler Service Operations Queue](https://fsharp.github.io/FSharp.Compiler.Service/queue.html), the mechanism used to sequentially process requests that require semantic information. + +* The [F# Compiler Service Caches](https://fsharp.github.io/FSharp.Compiler.Service/caches.html), the various caches maintained by an instance of an `FSharpChecker`. + +## Key compiler phases + +The following is a diagram of how different phases of F# compiler work: + +![F# compiler phases](http://fsharp.github.io/img/fscomp-phases.png) + +The following are the key phases and high-level logical operations of the F# compiler code in its various configurations: + +* _Basic lexing_. Produces a token stream from input source file text. + +* _White-space sensitive lexing_. Accepts and produces a token stream, augmenting per the F# Language Specification. + +* _Parsing_. Accepts a token stream and produces an AST per the grammar in the F# Language Specification. + +* _Resolving references_. For .NET SDK generally references are resolved explicitly by external tooling. + There is a legacy aspect to this if references use old .NET Framework references including for + scripting. See [ReferenceResolver.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ReferenceResolver.fs) for the abstract definition of compiler reference resolution. See [LegacyMSBuildReferenceResolver.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/LegacyMSBuildReferenceResolver.fs) for reference resolution used by the .NET Framework F# compiler when running on .NET Framework. See [SimulatedMSBuildReferenceResolver.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/SimulatedMSBuildReferenceResolver.fs) when not using the .NET Framework F# compiler. + See [DependencyManager](https://github.com/dotnet/fsharp/tree/main/src/fsharp/DependencyManager) for reference resolution and package management used in `fsi`. + +* _Importing referenced .NET binaries_, see [import.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/import.fsi)/[import.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/import.fs). Accepts file references and produces a Typed Tree node for each referenced assembly, including information about its type definitions (and type forwarders if any). + +* _Importing referenced F# binaries and optimization information as Typed Tree data structures_, see [TypedTreePickle.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTreePickle.fs). Accepts binary data and produces Typed Tree nodes for each referenced assembly, including information about its type/module/function/member definitions. + +* _Sequentially type checking files_, see [CheckDeclarations.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CheckDeclarations.fsi)/[CheckDeclarations.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CheckDeclarations.fs). Accepts an AST plus a type checking context/state and produces new Typed Tree nodes + incorporated into an updated type checking state, plus additional Typed Tree Expression nodes used during code generation. A key part of this is + checking syntactic types and expressions, see [CheckExpressions.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CheckDeclarations.fsi)/[CheckExpressions.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CheckDeclarations.fs) including the state held across the checking of a file (see `TcFileState`) and the + environment active as we traverse declarations and expressions (see `TcEnv`). + +* _Pattern match compilation_, see [PatternMatchCompilation.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/PatternMatchCompilation.fsi)/[PatternMatchCompilation.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/PatternMatchCompilation.fs). Accepts a subset of checked Typed Tree nodes representing F# pattern matching and produces Typed Tree expressions implementing the pattern matching. Called during type checking as each construct involving pattern matching is processed. + +* _Constraint solving_, see [ConstraintSolver.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ConstraintSolver.fsi)/[ConstraintSolver.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ConstraintSolver.fs).A constraint solver state is maintained during type checking of a single file, and constraints are progressively asserted (i.e. added to this state). Fresh inference variables are generated and variables are eliminated (solved). Variables are also generalized at various language constructs, or explicitly declared, making them "rigid". Called during type checking as each construct is processed. + +* _Post-inference type checks_, see [PostInferenceChecks.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/PostInferenceChecks.fsi)/[PostInferenceChecks.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/PostInferenceChecks.fs). Called at the end of type checking/inference for each file. A range of checks that can only be enforced after type checking on a file is complete, such as analysis when using `byref<'T>` or other `IsByRefLike` structs. + +* _Quotation translation_, see [QuotationTranslator.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/QuotationTranslator.fsi)/[QuotationTranslator.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/QuotationTranslator.fs)/[QuotationPickler.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/QuotationPickler.fsi)/[QuotationPickler.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/QuotationPickler.fs). Generates the stored information for F# quotation nodes, generated from the Typed Tree expression structures of the F# compiler. Quotations are ultimately stored as binary data plus some added type references. "ReflectedDefinition" quotations are collected and stored in a single blob. + +* _Optimization phases_, primarily the "Optimize" (peephole/inlining) and "Top Level Representation" (lambda lifting) phases, see [Optimizer.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/Optimizer.fsi)/[Optimizer.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/Optimizer.fs) and [InnerLambdasToTopLevelFuncs.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/InnerLambdasToTopLevelFuncs.fsi)/[InnerLambdasToTopLevelFuncs.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/InnerLambdasToTopLevelFuncs.fs) and [LowerCallsAndSeqs.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/LowerCallsAndSeqs.fs). Each of these takes Typed Tree nodes for types and expressions and either modifies the nodes in place or produces new Typed Tree nodes. These phases are orchestrated in [CompilerOptions.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/CompilerOptions.fs) + +* _Code generation_, see [IlxGen.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/IlxGen.fsi)/[IlxGen.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/IlxGen.fs). Accepts Typed Tree nodes and produces Abstract IL nodes, sometimes applying optimizations. + +* _Abstract IL code rewriting_, see [EraseClosures.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ilx/EraseClosures.fs) and + [EraseUnions.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/ilx/EraseUnions.fs). Eliminates some constructs by rewriting Abstract IL nodes. + +* _Binary emit_, see [ilwrite.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilwrite.fsi)/[ilwrite.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilwrite.fs). + +* _Reflection-Emit_, see [ilreflect.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/absil/ilreflect.fs). + +These and transformations used to build the following: + +* _The F# Compiler Service API_, see the [Symbol API](https://github.com/dotnet/fsharp/tree/main/src/fsharp/symbols) and [Service API](https://github.com/dotnet/fsharp/tree/main/src/fsharp/service) + +* _The F# Interactive Shell_, see [fsi.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/fsi/fsi.fs). + +* _The F# Compiler Shell_, see [fsc.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/fsc.fs) and [fscmain.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/fscmain.fs). + +## Tools to help work with the compiler + +* [sharplab.io](https://sharplab.io/) can be used to decompile code. + +* [fantomas-tools](https://fsprojects.github.io/fantomas-tools/#/ast) can be used to view the Untyped & Typed Abstract Syntax Tree. + + +## Coding standards and idioms + +The compiler codebase uses various abbreviations. Here are some of the most common ones. + +| Abbreviation | Meaning | +|:------------------------------|:-----------| +| `ad` | Accessor domain, meaning the permissions the accessing code has to access other constructs | +| `amap` | Assembly map, saying how to map IL references to F# CCUs | +| `arg` | Argument (parameter) | +| `argty` | Argument (parameter) type | +| `arginfo` | Argument (parameter) metadata | +| `ccu` | Reference to an F# compilation unit = an F# DLL (possibly including the DLL being compiled) | +| `celem` | Custom attribute element | +| `cenv` | Compilation environment. Means different things in different contexts, but usually a parameter for a singlecompilation state object being passed through a set of related functions in a single phase. The compilation state is often mutable. | +| `cpath` | Compilation path, meaning A.B.C for the overall names containing a type or module definition | +| `css` | Constraint solver state. | +| `denv` | Display Environment. Parameters guiding the formatting of types | +| `einfo` | An info object for an event (whether a .NET event, an F# event or a provided event) | +| `e` | Expression | +| `env` | Environment. Means different things in different contexts, but usually immutable state being passed and adjusted through a set of related functions in a single phase. | +| `finfo` | An info object for a field (whether a .NET field or a provided field) | +| `fref` | A reference to an ILFieldRef Abstract IL node for a field reference. Would normally be modernized to `ilFieldRef` | +| `g` | The TcGlobals value | +| `id` | Identifier | +| `lid` | Long Identifier | +| `m` | A source code range marker | +| `mimpl` | IL interface method implementation | +| `minfo` | An info object for a method (whet a .NET method, an F# method or a provided method) | +| `modul` | a Typed Tree structure for a namespace or F# module | +| `pat` | Pattern, a syntactic AST node representing part of a pattern in a pattern match | +| `pinfo` | An info object for a property (whether a .NET property, an F# property or a provided property) | +| `rfref` | Record or class field reference, a reference to a Typed Tree node for a record or class field | +| `scoref` | The scope of a reference in IL metadata, either assembly, `.netmodule` or local | +| `spat` | Simple Pattern, a syntactic AST node representing part of a pattern in a pattern match | +| `tau` | A type with the "forall" nodes stripped off (i.e. the nodes which represent generic type parameters). Comes from the notation _𝛕_ used in type theory | +| `tcref` | Type constructor reference (an `EntityRef`) | +| `tinst` | Type instantiation | +| `tpenv` | Type parameter environment, tracks the type parameters in scope during type checking | +| `ty`, `typ` | Type, usually a Typed Tree type | +| `tys`, `typs` | List of types, usually Typed Tree types | +| `typar` | Type Parameter | +| `tyvar` | Type Variable, usually referring to an IL type variable, the compiled form of an F# type parameter | +| `ucref` | Union case reference, a reference to a Typed Tree node for a union case | +| `vref` | Value reference, a reference to a Typed Tree node for a value | + +| Phase Abbreviation | Meaning | +|:------------------------------|:-----------| +| `Syn` | Abstract Syntax Tree | +| `Tc` | Type-checker | +| `IL` | Abstract IL = F# representation of .NET IL | +| `Ilx` | Extended Abstract IL = .NET IL plus a coulpe of contructs that get erased | + +## Adding Error Messages + +Adding or adjusting errors emitted by the compiler is usually straightforward (though it can sometimes imply deeper compiler work). Here's the general process: + +1. Reproduce the compiler error or warning with the latest F# compiler built from the [F# compiler repository](https://github.com/dotnet/fsharp). +2. Find the error code (such as `FS0020`) in the message. +3. Use a search tool and search for a part of the message. You should find it in `FSComp.fs` with a title, such as `parsMissingTypeArgs`. +4. Use another search tool or a tool like Find All References / Find Usages to see where it's used in the compiler source code. +5. Set a breakpoint at the location in source you found. If you debug the compiler with the same steps, it should trigger the breakpoint you set. This verifies that the location you found is the one that emits the error or warning you want to improve. + +From here, you can either simply update the error test, or you can use some of the information at the point in the source code you identified to see if there is more information to include in the error message. For example, if the error message doesn't contain information about the identifier the user is using incorrectly, you may be able to include the name of the identifier based on data the compiler has available at that stage of compilation. + +If you're including data from user code in an error message, it's important to also write a test that verifies the exact error message for a given string of F# code. + +## Formatting User Text from Typed Tree items + +When formatting Typed Tree objects such as `TyconRef`s as text, you normally use either + +* The functions in the `NicePrint` module such as `NicePrint.outputTyconRef`. These take a `DisplayEnv` that records the context in which a type was referenced, for example, the open namespaces. Opened namespaces are not shown in the displayed output. + +* The `DisplayName` properties on the relevant object. This drops the `'n` text that .NET adds to the compiled name of a type, and uses the F#-facing name for a type rather than the compiled name for a type (for example, the name given in a `CompiledName` attribute). + +* The functions such as `Tastops.fullTextOfTyconRef`, used to show the full, qualified name of an item. + +When formatting "info" objects, see the functions in the `NicePrint` module. + +## Notes on displaying types + +When displaying a type, you will normally want to "prettify" the type first. This converts any remaining type inference variables to new, better user-friendly type variables with names like `'a`. Various functions prettify types prior to display, for example, `NicePrint.layoutPrettifiedTypes` and others. + +When displaying multiple types in a comparative way, for example, two types that didn't match, you will want to display the minimal amount of infomation to convey the fact that the two types are different, for example, `NicePrint.minimalStringsOfTwoTypes`. + +When displaying a type, you have the option of displaying the constraints implied by any type variables mentioned in the types, appended as `when ...`. For example, `NicePrint.layoutPrettifiedTypeAndConstraints`. + +## Processing large inputs + +The compiler accepts large inputs such as: + +* Large literals, such as `let str = "a1" + "a2" + ... + "a1000"` +* Large array expressions +* Large list expressions +* Long lists of sequential expressions +* Long lists of bindings, such as `let v1 = e1 in let v2 = e2 in ....` +* Long sequences of `if .. then ... else` expressions +* Long sequences of `match x with ... | ...` expressions +* Combinations of these + +The compiler performs constant folding for large constants so there are no costs to using them at runtime. However, this is subject to a machine's stack size when compiling, leading to `StackOverflow` exceptions if those constants are very large. The same can be observed for certain kinds of array, list, or sequence expressions. This appears to be more prominent when compiling on macOS because macOS has a smaller stack size. + +Many sources of `StackOverflow` exceptions prior to F# 4.7 when processing these kinds of constructs were resolved by processing them on the heap via continuation passing techniques. This avoids filling data on the stack and appears to have negligible effects on overall throughout or memory usage of the compiler. + +Aside from array expressions, most of the previously-listed inputs are called "linear" expressions. This means that there is a single linear hole in the shape of expressions. For example: + +* `expr :: HOLE` (list expressions or other right-linear constructions) +* `expr; HOLE` (sequential expressions) +* `let v = expr in HOLE` (let expressions) +* `if expr then expr else HOLE` (conditional expression) +* `match expr with pat[vs] -> e1[vs] | pat2 -> HOLE` (for example, `match expr with Some x -> ... | None -> ...`) + +Processing these constructs with continuation passing is more difficult than a more "natural" approach that would use the stack. + +For example, consider the following contrived example: + +```fsharp +and remapLinearExpr g compgen tmenv expr contf = + match expr with + | Expr.Let (bind, bodyExpr, m, _) -> + ... + // tailcall for the linear position + remapLinearExpr g compgen tmenvinner bodyExpr (contf << (fun bodyExpr' -> + ...)) + + | Expr.Sequential (expr1, expr2, dir, spSeq, m) -> + ... + // tailcall for the linear position + remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> + ...)) + + | LinearMatchExpr (spBind, exprm, dtree, tg1, expr2, sp2, m2, ty) -> + ... + // tailcall for the linear position + remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> ...)) + + | LinearOpExpr (op, tyargs, argsFront, argLast, m) -> + ... + // tailcall for the linear position + remapLinearExpr g compgen tmenv argLast (contf << (fun argLast' -> ...)) + + | _ -> contf (remapExpr g compgen tmenv e) + +and remapExpr (g: TcGlobals) (compgen:ValCopyFlag) (tmenv:Remap) expr = + match expr with + ... + | LinearOpExpr _ + | LinearMatchExpr _ + | Expr.Sequential _ + | Expr.Let _ -> remapLinearExpr g compgen tmenv expr (fun x -> x) +``` + +The `remapExpr` operation becomes two functions, `remapExpr` (for non-linear cases) and `remapLinearExpr` (for linear cases). `remapLinearExpr` uses tailcalls for constructs in the `HOLE` positions mentioned previously, passing the result to the continuation. + +Some common aspects of this style of programming are: + +* The tell-tale use of `contf` (continuation function) +* The processing of the body expression `e` of a let-expression is tail-recursive, if the next construct is also a let-expression. +* The processing of the `e2` expression of a sequential-expression is tail-recursive +* The processing of the second expression in a cons is tail-recursive + +The previous example is considered incomplete, because arbitrary _combinations_ of `let` and sequential expressions aren't going to be dealt with in a tail-recursive way. The compiler generally tries to do these combinations as well. + +## Code Optimizations + +Code optimizations are performed in [`Optimizer.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/Optimizer.fs), [`DetupleArgs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/DetupleArgs.fs), [`InnerLambdasToTopLevelFuncs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/InnerLambdasToTopLevelFuncs.fs) and [`LowerCallsAndSeqs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/LowerCallsAndSeqs.fs). + +Some of the optimizations performed in [`Optimizer.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/Optimizer.fs) are: + +* Propagation of known values (constants, x = y, lambdas, tuples/records/union-cases of known values) +* Inlining of known lambda values +* Eliminating unused bindings +* Eliminating sequential code when there is no side-effect +* Eliminating switches when we determine definite success or failure of pattern matching +* Eliminating getting fields from an immutable record/tuple/union-case of known value +* Expansion of tuple bindings "let v = (x1,...x3)" to avoid allocations if it's not used as a first class value +* Splitting large functions into multiple methods, especially at match cases, to avoid massive methods that take a long time to JIT +* Removing tailcalls when it is determined that no code in the transitive closure does a tailcall nor recurses + +In [`DetupleArgs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/DetupleArgs.fs), tuples at call sites are eliminated if possible. Concretely, functions that accept a tuple at all call sites are replaced by functions that accept each of the tuple's arguments individually. This may require inlining to activate. + +Considering the following example: + +```fsharp +let max3 t = + let (x, y, z) = t + max x (max y z) + +max3 (1, 2, 3) +``` + +The `max3` function gets rewritten to simply accept three arguments, and depending on how it gets called it will either get inlined at the call site or called with 3 arguments instead of a new tuple. In either case, the tuple allocation is eliminated. + +However, sometimes this optimization is not applied unless a function is marked `inline`. Consider a more complicated case: + +```fsharp +let rec runWithTuple t offset times = + let offsetValues x y z offset = + (x + offset, y + offset, z + offset) + if times <= 0 then + t + else + let (x, y, z) = t + let r = offsetValues x y z offset + runWithTuple r offset (times - 1) +``` + +The inner function `offsetValues` will allocate a new tuple when called. However, if `offsetValues` is marked as `inline` then it will no longer allocate a tuple. + +Currently, these optimizations are not applied to `struct` tuples or explicit `ValueTuple`s passed to a function. In most cases, this doesn't matter because the handling of `ValueTuple` is well-optimized and may be erased at runtime. However, in the previous `runWithTuple` function, the overhead of allocating a `ValueTuple` each call ends up being higher than the previous example with `inline` applied to `offsetValues`. This may be addressed in the future. + +In [`InnerLambdasToTopLevelFuncs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/InnerLambdasToTopLevelFuncs.fs), inner functions and lambdas are analyzed and, if possible, rewritten into separate methods that do not require an `FSharpFunc` allocation. + +Consider the following implementation of `sumBy` on an F# list: + +```fsharp +let sumBy f xs = + let rec loop xs acc = + match xs with + | [] -> acc + | x :: t -> loop t (f x + acc) + loop xs 0 +``` + +The inner `loop` function is emitted as a separate static method named `loop@2` and incurs no overhead involved with allocatin an `FSharpFunc` at runtime. + +In [`LowerCallsAndSeqs.fs`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/LowerCallsAndSeqs.fs), a few optimizations are performed: + +* Performs eta-expansion on under-applied values applied to lambda expressions and does a beta-reduction to bind any known arguments +* Analyzes a sequence expression and translates it into a state machine so that operating on sequences doesn't incur significant closure overhead + +### Potential future optimizations: Better Inlining + +Consider the following example: + +```fsharp +let inline f k = (fun x -> k (x + 1)) +let inline g k = (fun x -> k (x + 2)) + +let res = (f << g) id 1 // 4 +``` + +Intermediate values that inherit from `FSharpFunc` are allocated at the call set of `res` to support function composition, even if the functions are marked as `inline`. Currently, if this overhead needs removal, you need to rewrite the code to be more like this: + +```fsharp +let f x = x + 1 +let g x = x + 2 + +let res = id 1 |> g |> f // 4 +``` + +The downside of course being that the `id` function can't propagate to composed functions, meaning the code is now different despite yielding the same result. + +More generally, any time a first-order function is passed as an argument to a second-order function, the first-order function is not inlined even if everything is marked as `inline`. This results in a performance penalty. + +## Compiler Startup Performance + +Compiler startup performance is a key factor affecting happiness of F# users. If the compiler took 10sec to start up, then far fewer people would use F#. + +On all platforms, the following factors affect startup performance: + +* Time to load compiler binaries. This depends on the size of the generated binaries, whether they are pre-compiled (for example, using NGEN or CrossGen), and the way the .NET implementation loads them. + +* Time to open referenced assemblies (for example, `mscorlib.dll`, `FSharp.Core.dll`) and analyze them for the types and namespaces defined. This depends particularly on whether this is correctly done in an on-demand way. + +* Time to process "open" declarations are the top of each file. Processing these declarations have been observed to take time in some cases of F# compilation. + +* Factors specific to the specific files being compiled. + +On Windows, the compiler delivered with Visual Studio currently uses NGEN to pre-compile `fsc`, `fsi`, and some assemblies used in Visual Studio tooling. For .NET Core, the CrossGen tool is used to accomplish the same thing. Visual Studio will use _delayed_ NGEN, meaning that it does not run NGEN on every binary up front. This means that F# compilation through Visual Studio may be slow for a few times before it gets NGENed. + +## Compiler Memory Usage + +Overall memory usage is a primary determinant of the usability of the F# compiler and instances of the F# compiler service. Overly high memory usage results in poor throughput (particularly due to increased GC times) and low user interface responsivity in tools such as Visual Studio or other editing environments. In some extreme cases, it can lead to Visual Studio crashing or another IDE becoming unusable due to constant paging from absurdly high memory usage. Luckily, these extreme cases are very rare. + +### Why memory usage matters + +When you do a single compilation to produce a binary, memory usage typically doesn't matter much. It's often fine to allocate a lot of memory because it will just be reclaimed after compilation is over. + +However, the F# compiler is not simply a batch process that accepts source code as input and produces an assembly as output. When you consider the needs of editor and project tooling in IDEs, the F# compiler is: + +* An engine that processes syntax trees and outputs data at various stages of compilation +* A database of syntactic and semantic data about the code hosted in an IDE +* A server process that accepts requests for syntactic and semantic information +* An API layer for tools to request tooling-specific data (e.g., F# tooltip information) + +Thinking about the F# compiler in these ways makes performance far more complicated than just throughput of a batch compilation process. + +### Kinds of data processed and served in F# tooling + +The following tables are split into two categories: syntactic and semantic. They contain common kinds of information requested, the kind of data that is involved, and roughly how expensive the operation is. + +#### IDE actions based on syntax + +| Action | Data inspected | Data returned | Cost (S/M/L/XL) | +|---------|---------------|---------------|-----------------| +| Syntactic Classification | Current document's source text | Text span and classification type for each token in the document | S | +| Breakpoint Resolution | Current document's syntax tree | Text span representing where breakpoing where resolve | S | +| Debugging data tip info | Current document's source text | Text span representing the token being inspected | S | +| Brace pair matching | Current document's source text | Text spans representing brace pairs that match in the input document | S | +| "Smart" indentation | Current document's source text | Indentation location in a document | S | +| Code fixes operating only on syntax | Current document's source text | Small text change for document | S | +| XML doc template generation | Current document's syntax tree | Small (usually) text change for document | S | +| Brace pair completion | Current line in a source document | Additional brace pair inserted into source text | S | +| Souce document navigation (usually via dropdowns) | Current document's syntax tree | "Navigation Items" with optional child navigation items containing ranges in source code | S | +| Code outlining | Current document's source text | Text spans representing blocks of F# code that are collapsable as a group | S - M | +| Editor formatting | Current document's source text | New source text for the document | S - L | +| Syntax diagnostics | Current document's source text | List of diagnostic data including the span of text corresponding to the diagnostic | S | +| Global construct search and navigation | All syntax trees for all projects | All items that match a user's search pattern with spans of text that represent where a given item is located | S-L | + +You likely noticed that nearly all of the syntactical operations are marked `S`. Aside from extreme cases, like files with 50k lines or higher, syntax-only operations typically finish very quickly. In addition to being computationally inexpensive, they are also run asynchronously and free-threaded. + +Editor formatting is a bit of an exception. Most IDEs offer common commands for format an entire document, and although they also offer commands to format a given text selection, users typically choose to format the whole document. This means an entire document has to be inspected and potentially rewritten based on often complex rules. In practice this isn't bad when working with a document that has already been formatted, but it can be expensive for larger documents with strange stylistic choices. + +Most of the syntax operations require an entire document's source text or parse tree. It stands to reason that this could be improved by operating on a diff of a parse tree instead of the whole thing. This is likely a very complex thing to implement though, since none of the F# compiler infrastructure works in this way today. + +#### IDE actions based on semantics + +| Action | Data inspected | Data returned | Cost (S/M/L/XL) | +|---------|---------------|---------------|-----------------| +| Most code fixes | Current document's typecheck data | Set (1 or more) of suggested text replacements | S-M | +| Semantic classification | Current document's typecheck data | Spans of text with semantic classification type for all constructs in a document | S-L | +| Code lenses | Current document's typecheck data and top-level declarations (for showing signatures); graph of all projects that reference the current one (for showing references) | Signature data for each top-level construct; spans of text for each reference to a top-level construct with navigation information | S-XL | +| Code generation / refactorings | Current document's typecheck data and/or current resolved symbol/symbols | Text replacement(s) | S-L | +| Code completion | Current document's typecheck data and currently-resolved symbol user is typing at | List of all symbols in scope that are "completable" based on where completion is invoked | S-L | +| Editor tooltips | Current document's typecheck data and resolved symbol where user invoked a tooltip | F# tooltip data based on inspecting a type and its declarations, then pretty-printing them | S-XL | +| Diagnostics based on F# semantics | Current document's typecheck data | Diagnostic info for each symbol with diagnostics to show, including the range of text associated with the diagnostic | M-XL | +| Symbol highlighting in a document | Current document's typecheck data and currently-resolved symbol where user's caret is located | Ranges of text representing instances of that symbol in the document | S-M | +| Semantic navigation (for example, Go to Definition) | Current document's typecheck data and currently-resolved symbol where the user invoked navigation | Location of a symbol's declaration | S-M | +| Rename | Graph of all projects that use the symbol that rename is triggered on and the typecheck data for each of those projects | List of all uses of all symbols that are to be renamed | S-XL | +| Find all references | Graph of all projects that Find References is triggered on and the typecheck data for each of those projects | List of all uses of all symbols that are found | S-XL | +| Unused value/symbol analysis | Typecheck data for the current document | List of all symbols that aren't a public API and are unused | S-M | +| Unused `open` analysis | Typecheck data for the current document and all symbol data brought into scope by each `open` declaration | List of `open` declarations whose symbols it exposes aren't used in the current document | S-L | +| Missing `open` analysis | Typecheck data for the current document, resolved symbol with an error, and list of available namespaces or modules | List of candidate namespaces or modules that can be opened | S-M | +| Misspelled name suggestion analysis | Typecheck data for the current document and resolved symbol with an error | List of candidates that are in scope and best match the misspelled name based on a string distance algorithm | S-M | +| Name simplification analysis | Typecheck data for the current document and all symbol data brought into scope by each `open` declaration | List of text changes available for any fully- or partially-qualified symbol that can be simplified | S-XL | + +You likely noticed that every cost associated with an action has a range. This is based on two factors: + +1. If the semantic data being operated on is cached +2. How much semantic data must be processed for the action to be completed + +Most actions are `S` if they operate on cached data and the compiler determines that no data needs to be re-computed. The size of their range is influenced largely by the _kind_ of semantic operations each action has to do, such as: + +* Typechecking a single document and processing the resulting data +* Typechecking a document and its containing project and then processing the resulting data +* Resolving a single symbol in a document +* Resolving the definition of a single symbol in a codebase +* Inspecting all symbols brought into scope by a given `open` declaration +* Inspecting all symbols in a document +* Inspecting all symbols in all documents contained in a graph of projects + +For example, commands like Find All References and Rename can be cheap if a codebase is small, hence the lower bound being `S`. But if the symbol in question is used across many documents in a large project graph, they are very expensive because the entire graph must be crawled and all symbols contained in its documents must be inspected. + +In contrast, actions like highlighting all symbols in a document aren't terribly expensive even for very large file files. That's because the symbols to be inspected are ultimately only in a single document. + +Operations that use typecheck data execute on a single background thread (see [Reactor.fsi](https://github.com/dotnet/fsharp/blob/main/src/fsharp/service/Reactor.fsi)/[Reactor.fs](https://github.com/dotnet/fsharp/blob/main/src/fsharp/service/Reactor.fs)). Each operation is cancellable - for example, if you run an expensive Find All References but decide to do something else, the next action you take that requires semantic data will cancel the Find All References operation and start the one you requested. + +TODO for don --> why single-threaded? why no priority queue if can't be multithreaded? + +### Analyzing compiler memory usage + +In general, the F# compiler allocates a lot of memory. More than it needs to. However, most of the "easy" sources of allocations have been squashed out and what remains are many smaller sources of allocations. The remaining "big" pieces allocate as a result of their current architecture, so it isn't straightforward to address them. + +To analyze memory usage of F# tooling, you have two primary avenues: + +1. Take a process dump on your machine and analyze it with process dump analysis tools like [dotMemory](https://www.jetbrains.com/dotmemory/) +2. Use a sampling tool like [PerfView](https://github.com/Microsoft/perfview) or [dotTrace](https://www.jetbrains.com/profiler/) to collect a trace of your system while you perform various tasks in an IDE, ideally for 60 seconds or more. + +#### Analyzing a process dump file + +Process dump files are extremely information-rich data files that can be used to see the distribution of memory usage across various types. Tools like [dotMemory](https://www.jetbrains.com/dotmemory/) will show these distributions and intelligently group things to help identify the biggest areas worth improving. Additionally, they will notice things like duplicate strings and sparse arrays, which are often great ways to improve memory usage since it means more memory is being used than is necessary. + +As of F# 5, one of the most prominent sources of memory usage is `ILModuleReader`, often making up more than 20% of total memory usage for a given session. There is a considerably large "long tail" of small chunks of memory usage that in aggreate add up to a lot of resource utilization. Many can be improved. + +#### Analyzing a sample trace of IDE usage + +The other important tool to understand memory and CPU usage for a given sample of IDE usage is a trace file. These are collected and analyzed by tools like [PerfView](https://github.com/Microsoft/perfview) and [dotTrace](https://www.jetbrains.com/profiler/). + +When analyzing a trace, there are a few things to look out for: + +1. Overall GC statistics for the sample to give an overall picture of what was going on in the IDE for your sample: + a. How much CPU time was spent in the GC as a percentage of total CPU time for the IDE process? + b. What was the peak working set (total memory usage)? + c. What was the peak allocations per second? + d. How many allocations were Gen0? Gen1? Gen2? +2. Memory allocations for the sample, typically also ignoring object deaths: + a. Is `LargeObject` showing up anywhere prominently? If so, that's a problem! + b. Which objects show up highest on the list? Does their presence that high make sense? + c. For a type such as `System.String`, which caller allocates it the most? Can that be improved? +3. CPU sampling data, sorted by most CPU time + a. Are any methods showing up that correspond with high memory allocations? Something showing up prominently in both places is often a sign that it needs work! + +After analyzing a trace, you should have a good idea of places that could see improvement. Often times a tuple can be made into a struct tuple, or some convenient string processing could be adjusted to use a `ReadonlySpan<'T>` or turned into a more verbose loop that avoids allocations. + +### The cross-project references problem + +The compiler is generally built to compile one assembly: the assumption that the compiler is compiling one assembly is baked into several aspects of the design of the Typed Tree. + +In contract, FCS supports compiling a graph of projects, each for a different assembly. The Typed Tree nodes are **not** shared between different project compilations. This means that representation of project references is roughly O(n^2) in memory usage. In practice it's not strictly O(n^2), but for very large codebases the proportionality is felt. + +Some key things to understand are: + +* The `RawFSharpAssemblyData` is the data blob that would normally be stuffed in the F# resource in the generated DLL in a normal compilation. That's the "output" of checking each project. + +* This is used as "input" for the assembly reference of each consuming project (instead of an on-disk DLL) + +* Within each consuming project that blob is then resurrected to Typed Tree nodes in `TypedTreePickle.fs`. + +The biggest question is: could the compiler share this data across projects? In theory, yes. In practice, it's very tricky business. + +From a correctness point of view: the process of generating this blob (TypedTreePickle `p_XYZ`) and resurrecting it (TypedTreePickle `u_*`) does some transformations to the Typed Tree that are necessary for correctness of compilation, for example, [in `TypedTreePickle`](https://github.com/dotnet/fsharp/blob/main/src/fsharp/TypedTreePickle.fs#L738). Basically, the Typed Tree nodes from the compilation of one assembly are _not_ valid when compiling a different assembly. + +The Typed Tree nodes include `CcuData` nodes, which have access to a number of callbacks into the `TcImports` compilation context for the assembly being compiled. TypedTree nodes are effectively tied to a particular compilation of a particular assembly due to this. + +There isn't any way to share this data without losing correctness and invalidating many invariants held in the current design. + +From a lifetime point of view: the Typed Tree nodes are tied together in a graph, so sharing one or two of them might drag across the entire graph and extend lifetimes of that graph. None of these interrelated nodes were designed to be shared across assemblies. + +## `eventually` computations + +Some parts of the F# codebase (specifically, the type checker) are written using `eventually` computation expressions. These define resumption-like computations which can be time-sliced, suspended or discarded at "bind" points. + +This is done to ensure that long-running type-checking and other computations in the F# Compiler Service can be interrupted and cancelled. The documentation of the [F# Compiler Service Operations Queue](https://fsharp.github.io/FSharp.Compiler.Service/queue.html) covers some aspects of this. + +When compiling code with `fsc` or executing code with `fsi`, these computations are not time-sliced and simply run synchronously and without interruption (unless the user requests it). + +TODO for don --> is the below stuff still accurate? + +Instances of the F# compiler service use time slicing for two things: + +1. The low-priority computations of the reactor thread (i.e. the background typechecking of the incremental builder) +2. The typechecking phase of TypeCheckOneFile which are high-priority computations on the reactor thread. + +The first can be interrupted by having the incremental builder dependency graph +(see [IncrementalBuild.fsi](https://github.com/fsharp/FSharp.Compiler.Service/tree/master/src/fsharp/service/IncrementalBuild.fsi)/[IncrementalBuild.fs](https://github.com/fsharp/FSharp.Compiler.Service/tree/master/src/fsharp/service/IncrementalBuild.fs)) +decide not to bother continuing with the computation (it drops it on the floor) + +The second can be interrupted via having `isResultObsolete` to the F# Compiler Service API return true. + +### The F# Compiler Service Public Surface Area + +The "intended" FCS API is the parts under the namespaces + +* FSharp.Compiler.SourceCodeServices.* (analysis, compilation, tooling, lexing) +* FSharp.Compiler.Interactive.Shell.* (scripting support) +* FSharp.Compiler.AbstractIL.* (for ILAssemblyReader hook for Rider) +* FSharp.Compiler.Syntax.* (direct access to full untyped tree) + +These sections are generally designed with F#/.NET design conventions (e.g. types in namespaces, not modules, no nesting of modules etc.) +and we will continue to iterate to make this so. + +In contrast, the public parts of the compiler directly under `FSharp.Compiler.*` and `FSharp.AbstractIL.*` are +"incidental" and not really designed for public use apart from the hook for JetBrains Rider +(Aside: In theory all these other parts could be renamed to FSharp.Compiler though there's no need to do that right now). +These internal parts tend to be implemented with the "module containing lots of stuff in one big file" approach for layers of the compiler. + + +### The F# Compiler Service Operations Queue + +See [F# Compiler Service Queue](https://fsharp.github.io/FSharp.Compiler.Service/queue.html). + +### The F# Compiler Service Caches + +See [F# Compiler Service Caches](https://fsharp.github.io/FSharp.Compiler.Service/caches.html). + +## Bootstrapping + +The F# compiler is bootstrapped. That is, an existing F# compiler is used to build a "proto" compiler from the current source code. That "proto" compiler is then used to compile itself, producing a "final" compiler. This ensures the final compiler is compiled with all relevant optimizations and fixes. + +## FSharp.Build + +`FSharp.Build.dll` and `Microsoft.FSharp.targets` give MSBuild support for F# projects (`.fsproj`) and contain the. Although not strictly part of the F# compiler, they are essential for using F# in all contexts for .NET, aside from some more targeted scripting scenarios. The targets expose things like the `CoreCompile` and `Fsc` tasks called by MSBuild. + +### Attribution + +This document is based on an original document published in 2015 by the [F# Software Foundation](http://fsharp.org). It has since been updated substantially. diff --git a/fcs/docsrc/content/caches.fsx b/docs/fcs/caches.fsx similarity index 98% rename from fcs/docsrc/content/caches.fsx rename to docs/fcs/caches.fsx index 2f63c4b394e..442015bda58 100644 --- a/fcs/docsrc/content/caches.fsx +++ b/docs/fcs/caches.fsx @@ -1,5 +1,5 @@ (*** hide ***) -#I "../../../artifacts/bin/fcs/net461" +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" (** Compiler Services: Notes on the FSharpChecker caches ================================================= diff --git a/docs/fcs/compiler.fsx b/docs/fcs/compiler.fsx new file mode 100644 index 00000000000..e880ed57f1a --- /dev/null +++ b/docs/fcs/compiler.fsx @@ -0,0 +1,100 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Hosted Compiler +=============== + +This tutorial demonstrates how to host the F# compiler. + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published +*) + +(** +> **NOTE:** There are several options for hosting the F# compiler. The easiest one is to use the +`fsc.exe` process and pass arguments. +*) + +(** + +> **NOTE:** By default [compilations using FSharp.Compiler.Service reference FSharp.Core 4.3.0.0](https://github.com/fsharp/FSharp.Compiler.Service/issues/156) (matching F# 3.0). You can override +this choice by passing a reference to FSharp.Core for 4.3.1.0 or later explicitly in your command-line arguments. + +*) + +(** +--------------------------- + +First, we need to reference the libraries that contain F# interactive service: +*) + +#r "FSharp.Compiler.Service.dll" +open System.IO +open FSharp.Compiler.CodeAnalysis + +// Create an interactive checker instance +let checker = FSharpChecker.Create() + +(** +Now write content to a temporary file: + +*) +let fn = Path.GetTempFileName() +let fn2 = Path.ChangeExtension(fn, ".fsx") +let fn3 = Path.ChangeExtension(fn, ".dll") + +File.WriteAllText(fn2, """ +module M + +type C() = + member x.P = 1 + +let x = 3 + 4 +""") + +(** +Now invoke the compiler: +*) + +let errors1, exitCode1 = + checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) + |> Async.RunSynchronously + +(** + +If errors occur you can see this in the 'exitCode' and the returned array of errors: + +*) +File.WriteAllText(fn2, """ +module M + +let x = 1.0 + "" // a type error +""") + +let errors1b, exitCode1b = + checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) + |> Async.RunSynchronously + +(** + +Compiling to a dynamic assembly +=============================== + +You can also compile to a dynamic assembly, which uses the F# Interactive code generator. +This can be useful if you are, for example, in a situation where writing to the file system +is not really an option. + +You still have to pass the "-o" option to name the output file, but the output file is not actually written to disk. + +The 'None' option indicates that the initialization code for the assembly is not executed. +*) +let errors2, exitCode2, dynAssembly2 = + checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None) + |> Async.RunSynchronously + +(* +Passing 'Some' for the 'execute' parameter executes the initialization code for the assembly. +*) +let errors3, exitCode3, dynAssembly3 = + checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr)) + |> Async.RunSynchronously + diff --git a/docs/fcs/corelib.fsx b/docs/fcs/corelib.fsx new file mode 100644 index 00000000000..cfcdba13557 --- /dev/null +++ b/docs/fcs/corelib.fsx @@ -0,0 +1,90 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Notes on FSharp.Core.dll +================================================= + +Versions of FSharp.Core involved in the operation of FSharp.Compiler.Service +--------------------------------------------- + +There are three versions of FSharp.Core relevant to the operation of FSharp.Compiler.Service: + +1. **The FSharp.Compiler.Service.dll static reference to FSharp.Core** - The FCS DLL and nuget have a static minbound dependency on FSharp.Core. + + This is just a normal .NET dependency like any other, it expresses the minimum surface area of FSharp.Core that the implementation of FSharp.Compiler.Service (and any components that depend on it) needs. It could be a reference to a reference assembly if we supported that. In theory this could be very low and all is cool - if we could implement FCS in terms of FSharp.Core 2.0.0.0 then that could be the minbound (indeed in theory we could implement FCS pretty almost without any use of FSharp.Core functionality at all, though obviously we don't) + + In practice this is 0-2 versions behind latest FSharp.Core. + +2. **The runtime reference to FSharp.Core in a tool, application or test suite that includes FSharp.Compiler.Service** - This is the actual version of FSharp.Core used when, say, fsc.exe or devenv.exe or fsi.exe or fsdocs.exe runs. + + This must be at least as high as (1) and is usually the very latest FSharp.Core available (in or out of repo tree). This is important to the operation of the FCS-based tool because it is used for execution of scripts, and the default compilation reference for scripts. If scripts are going to use a particular language feature then this must be sufficient to support the language feature + +3. **The FSharp.Core reference in a compilation or analysis being processed by FSharp.Compiler.Service**. + + This can be anything - 2.0.0.0, 4.0.0.0 or 5.0.0 or whatever. For script compilation and execution is is the same as (2). It must be sufficient to support language features used in the compilation. + +Shipping an FSharp.Core with your application +--------------------------------------------- + +When building applications or plug-in components which use FSharp.Compiler.Service.dll, you will normally also +include a copy of FSharp.Core.dll as part of your application. + +For example, if you build a ``HostedCompiler.exe``, you will normally place an FSharp.Core.dll (say 4.3.1.0) alongside +your ``HostedCompiler.exe``. + + +Which FSharp.Core and .NET Framework gets referenced in compilation? +-------------------------------------- + +The FSharp.Compiler.Service component can be used to do more or less any sort of F# compilation. +In particular you can reference an explicit FSharp.Core and/or framework +assemblies in the command line arguments (different to the FSharp.Core and a .NET Framework being used to run your tool). + +To target a specific FSharp.Core and/or .NET Framework assemblies, use the ``--noframework`` argument +and the appropriate command-line arguments: + + [] + let fsharpCorePath = + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll" + let errors2, exitCode2 = + scs.Compile( + [| "fsc.exe"; "--noframework"; + "-r"; fsharpCorePath; + "-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"; + "-o"; fn3; + "-a"; fn2 |]) + +You will need to determine the location of these assemblies. The easiest way to locate these DLLs in a cross-platform way and +convert them to command-line arguments is to [crack an F# project file](https://fsharp.github.io/FSharp.Compiler.Service/project.html). +Alternatively you can compute SDK paths yourself, and some helpers to do this are in [the tests for FSharp.Compiler.Service.dll](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54). + + +What about if I am processing a script or using ``GetCheckOptionsFromScriptRoot`` +------------------------------------------------------------------------- + +If you do _not_ explicitly reference an FSharp.Core.dll from an SDK location, or if you are processing a script +using ``FsiEvaluationSession`` or ``GetCheckOptionsFromScriptRoot``, then an implicit reference to FSharp.Core will be made +by the following choice: + +1. The version of FSharp.Core.dll statically referenced by the host assembly returned by ``System.Reflection.Assembly.GetEntryAssembly()``. + +2. If there is no static reference to FSharp.Core in the host assembly, then + + - For FSharp.Compiler.Service 1.4.0.x above (F# 4.0 series), a reference to FSharp.Core version 4.4.0.0 is added + +Do I need to include FSharp.Core.optdata and FSharp.Core.sigdata? +-------------------------------------- + +No, unless you are doing something with very old FSharp.Core.dll. + +Summary +------- + +In this design note we have discussed three things: + +- the versions of FSharp.Core relevant to the operation of FSharp.Compiler.Service.dll +- which FSharp.Core.dll is used to run your compilation tools +- how to configure binding redirects for the FSharp.Core.dll used to run your compilation tools +- which FSharp.Core.dll and/or framework assemblies are referenced during the checking and compilations performed by your tools. + +*) diff --git a/fcs/docsrc/content/devnotes.md b/docs/fcs/devnotes.md similarity index 94% rename from fcs/docsrc/content/devnotes.md rename to docs/fcs/devnotes.md index 7f80660f364..98684f9f358 100644 --- a/fcs/docsrc/content/devnotes.md +++ b/docs/fcs/devnotes.md @@ -54,4 +54,4 @@ Release checklist to publish a new version on nuget.org 1. Update `RELEASE_NOTES.md` 2. Check the version numbers are correct across the source (some files duplicate them) 3. Commit and add the necessary tag to the repo -4. Publish the nupkgs for `FSharp.Compiler.Service` and `FSharp.Compiler.Service.ProjectCracker` once they appear in AppVeyor artifacts +4. Publish the nupkgs for `FSharp.Compiler.Service` once it appears in AppVeyor artifacts diff --git a/docs/fcs/editor.fsx b/docs/fcs/editor.fsx new file mode 100644 index 00000000000..b707663c01b --- /dev/null +++ b/docs/fcs/editor.fsx @@ -0,0 +1,251 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Editor services +================================== + +This tutorial demonstrates how to use the editor services provided by the F# compiler. +This API is used to provide auto-complete, tool-tips, parameter info help, matching of +brackets and other functions in F# editors including Visual Studio, Xamarin Studio and Emacs +(see [fsharpbindings](https://github.com/fsharp/fsharpbinding) project for more information). +Similarly to [the tutorial on using untyped AST](untypedtree.html), we start by +getting the `InteractiveChecker` object. + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published + + +Type checking sample source code +-------------------------------- + +As in the [previous tutorial (using untyped AST)](untypedtree.html), we start by referencing +`FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance +of `InteractiveChecker`: + +*) +// Reference F# compiler API +#r "FSharp.Compiler.Service.dll" + +open System +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization + +// Create an interactive checker instance +let checker = FSharpChecker.Create() + +(** + +As [previously](untypedtree.html), we use `GetProjectOptionsFromScriptRoot` to get a context +where the specified input is the only file passed to the compiler (and it is treated as a +script file or stand-alone F# source code). + +*) +// Sample input as a multi-line string +let input = + """ + open System + + let foo() = + let msg = String.Concat("Hello"," ","world") + if true then + printfn "%s" msg. + """ +// Split the input & define file name +let inputLines = input.Split('\n') +let file = "/home/user/Test.fsx" + +let projOptions, errors = + checker.GetProjectOptionsFromScript(file, SourceText.ofString input) + |> Async.RunSynchronously + +let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) + +(** +To perform type checking, we first need to parse the input using +`ParseFile`, which gives us access to the [untyped AST](untypedtree.html). However, +then we need to call `CheckFileInProject` to perform the full type checking. This function +also requires the result of `ParseFileInProject`, so the two functions are often called +together. +*) +// Perform parsing + +let parseFileResults = + checker.ParseFile(file, SourceText.ofString input, parsingOptions) + |> Async.RunSynchronously +(** +Before we look at the interesting operations provided by `TypeCheckResults`, we +need to run the type checker on a sample input. On F# code with errors, you would get some type checking +result (but it may contain incorrectly "guessed" results). +*) + +// Perform type checking +let checkFileAnswer = + checker.CheckFileInProject(parseFileResults, file, 0, SourceText.ofString input, projOptions) + |> Async.RunSynchronously + +(** +Alternatively you can use `ParseAndCheckFileInProject` to check both in one step: +*) + +let parseResults2, checkFileAnswer2 = + checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString input, projOptions) + |> Async.RunSynchronously + +(** + +The function returns both the untyped parse result (which we do not use in this +tutorial), but also a `CheckFileAnswer` value, which gives us access to all +the interesting functionality... +*) + +let checkFileResults = + match checkFileAnswer with + | FSharpCheckFileAnswer.Succeeded(res) -> res + | res -> failwithf "Parsing did not finish... (%A)" res + +(** + +Here, we type check a simple function that (conditionally) prints "Hello world". +On the last line, we leave an additional dot in `msg.` so that we can get the +completion list on the `msg` value (we expect to see various methods on the string +type there). + + +Using type checking results +--------------------------- + +Let's now look at some of the API that is exposed by the `TypeCheckResults` type. In general, +this is the type that lets you implement most of the interesting F# source code editor services. + +### Getting a tool tip + +To get a tool tip, you can use `GetToolTip` method. The method takes a line number and character +offset. Both of the numbers are zero-based. In the sample code, we want to get tooltip for the `foo` +function that is defined on line 3 (line 0 is blank) and the letter `f` starts at index 7 (the tooltip +would work anywhere inside the identifier). + +In addition, the method takes a tag of token which is typically `IDENT`, when getting tooltip for an +identifier (the other option lets you get tooltip with full assembly location when using `#r "..."`). + +*) +// Get tag of the IDENT token to be used as the last argument +let identToken = FSharpTokenTag.Identifier + +// Get tool tip at the specified location +let tip = checkFileResults.GetToolTip(4, 7, inputLines.[1], ["foo"], identToken) +printfn "%A" tip + +(** + +*) + +(** +Aside from the location and token kind, the function also requires the current contents of the line +(useful when the source code changes) and a `Names` value, which is a list of strings representing +the current long name. For example to get tooltip for the `Random` identifier in a long name +`System.Random`, you would use location somewhere in the string `Random` and you would pass +`["System"; "Random"]` as the `Names` value. + +The returned value is of type `ToolTipText` which contains a discriminated union `ToolTipElement`. +The union represents different kinds of tool tips that you can get from the compiler. + +### Getting auto-complete lists + +The next method exposed by `TypeCheckResults` lets us perform auto-complete on a given location. +This can be called on any identifier or in any scope (in which case you get a list of names visible +in the scope) or immediately after `.` to get a list of members of some object. Here, we get a +list of members of the string value `msg`. + +To do this, we call `GetDeclarationListInfo` with the location of the `.` symbol on the last line +(ending with `printfn "%s" msg.`). The offsets are one-based, so the location is `7, 23`. +We also need to specify a function that says that the text has not changed and the current identifier +where we need to perform the completion. +*) +// Get declarations (autocomplete) for a location +let decls = + checkFileResults.GetDeclarationListInfo + (Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun () -> [])) + +// Print the names of available items +for item in decls.Items do + printfn " - %s" item.Name + +(** + +> **NOTE:** `v` is an alternative name for the old `GetDeclarations`. The old `GetDeclarations` was +deprecated because it accepted zero-based line numbers. At some point it will be removed, and `GetDeclarationListInfo` will be renamed back to `GetDeclarations`. +*) + +(** +When you run the code, you should get a list containing the usual string methods such as +`Substring`, `ToUpper`, `ToLower` etc. The fourth argument of `GetDeclarations`, here `([], "msg")`, +specifies the context for the auto-completion. Here, we want a completion on a complete name +`msg`, but you could for example use `(["System"; "Collections"], "Generic")` to get a completion list +for a fully qualified namespace. + +### Getting parameter information + +The next common feature of editors is to provide information about overloads of a method. In our +sample code, we use `String.Concat` which has a number of overloads. We can get the list using +`GetMethods` operation. As previously, this takes zero-indexed offset of the location that we are +interested in (here, right at the end of the `String.Concat` identifier) and we also need to provide +the identifier again (so that the compiler can provide up-to-date information when the source code +changes): + +*) +// Get overloads of the String.Concat method +let methods = + checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) + +// Print concatenated parameter lists +for mi in methods.Methods do + [ for p in mi.Parameters do for tt in p.Display do yield tt.Text ] + |> String.concat ", " + |> printfn "%s(%s)" methods.MethodName +(** +The code uses the `Display` property to get the annotation for each parameter. This returns information +such as `arg0: obj` or `params args: obj[]` or `str0: string, str1: string`. We concatenate the parameters +and print a type annotation with the method name. +*) + +(** + +## Asynchronous and immediate operations + +You may have noticed that `CheckFileInProject` is an asynchronous operation. +This indicates that type checking of F# code can take some time. +The F# compiler performs the work in background (automatically) and when +we call `CheckFileInProject` method, it returns an asynchronous operation. + +There is also the `CheckFileInProjectIfReady` method. This returns immediately if the +type checking operation can't be started immediately, e.g. if other files in the project +are not yet type-checked. In this case, a background worker might choose to do other +work in the meantime, or give up on type checking the file until the `FileTypeCheckStateIsDirty` event +is raised. + +> The [fsharpbinding](https://github.com/fsharp/fsharpbinding) project has more advanced +example of handling the background work where all requests are sent through an F# agent. +This may be a more appropriate for implementing editor support. + +*) + + +(** +Summary +------- + +The `CheckFileAnswer` object contains other useful methods that were not covered in this tutorial. You +can use it to get location of a declaration for a given identifier, additional colorization information +(the F# 3.1 colorizes computation builder identifiers & query operators) and others. + +Using the FSharpChecker component in multi-project, incremental and interactive editing situations may involve +knowledge of the [FSharpChecker operations queue](queue.html) and the [FSharpChecker caches](caches.html). + + +Finally, if you are implementing an editor support for an editor that cannot directly call .NET API, +you can call many of the methods discussed here via a command line interface that is available in the +[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete) project. + + +*) diff --git a/docs/fcs/filesystem.fsx b/docs/fcs/filesystem.fsx new file mode 100644 index 00000000000..503a18ea9f1 --- /dev/null +++ b/docs/fcs/filesystem.fsx @@ -0,0 +1,190 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Virtualized File System +========================================== + +The `FSharp.Compiler.Service` component has a global variable +representing the file system. By setting this variable you can host the compiler in situations where a file system +is not available. + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. + + +Setting the FileSystem +---------------------- + +In the example below, we set the file system to an implementation which reads from disk +*) +#r "FSharp.Compiler.Service.dll" +open System +open System.IO +open System.Collections.Generic +open System.Text +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO +open FSharp.Compiler.Text + +let defaultFileSystem = FileSystem + +let fileName1 = @"c:\mycode\test1.fs" // note, the path doesn't exist +let fileName2 = @"c:\mycode\test2.fs" // note, the path doesn't exist + +type MyFileSystem() = + let file1 = """ +module File1 + +let A = 1""" + let file2 = """ +module File2 +let B = File1.A + File1.A""" + let files = dict [(fileName1, file1); (fileName2, file2)] + + interface IFileSystem with + // Implement the service to open files for reading and writing + member __.FileStreamReadShim(fileName) = + match files.TryGetValue fileName with + | true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream + | _ -> defaultFileSystem.FileStreamReadShim(fileName) + + member __.FileStreamCreateShim(fileName) = + defaultFileSystem.FileStreamCreateShim(fileName) + + member __.FileStreamWriteExistingShim(fileName) = + defaultFileSystem.FileStreamWriteExistingShim(fileName) + + member __.ReadAllBytesShim(fileName) = + match files.TryGetValue fileName with + | true, text -> Encoding.UTF8.GetBytes(text) + | _ -> defaultFileSystem.ReadAllBytesShim(fileName) + + // Implement the service related to temporary paths and file time stamps + member __.GetTempPathShim() = + defaultFileSystem.GetTempPathShim() + + member __.GetLastWriteTimeShim(fileName) = + defaultFileSystem.GetLastWriteTimeShim(fileName) + + member __.GetFullPathShim(fileName) = + defaultFileSystem.GetFullPathShim(fileName) + + member __.IsInvalidPathShim(fileName) = + defaultFileSystem.IsInvalidPathShim(fileName) + + member __.IsPathRootedShim(fileName) = + defaultFileSystem.IsPathRootedShim(fileName) + + member __.IsStableFileHeuristic(fileName) = + defaultFileSystem.IsStableFileHeuristic(fileName) + + // Implement the service related to file existence and deletion + member __.SafeExists(fileName) = + files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName) + + member __.FileDelete(fileName) = + defaultFileSystem.FileDelete(fileName) + + // Implement the service related to assembly loading, used to load type providers + // and for F# interactive. + member __.AssemblyLoadFrom(fileName) = + defaultFileSystem.AssemblyLoadFrom fileName + + member __.AssemblyLoad(assemblyName) = + defaultFileSystem.AssemblyLoad assemblyName + +let myFileSystem = MyFileSystem() +FileSystem <- MyFileSystem() + +(** + +Doing a compilation with the FileSystem +--------------------------------------- + +*) + +let checker = FSharpChecker.Create() + +let projectOptions = + let sysLib nm = + if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows + System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + + @"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" + nm + ".dll" + else + let sysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + let (++) a b = System.IO.Path.Combine(a,b) + sysDir ++ nm + ".dll" + + let fsCore4300() = + if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows + System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + + @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll" + else + sysLib "FSharp.Core" + + let allFlags = + [| yield "--simpleresolution"; + yield "--noframework"; + yield "--debug:full"; + yield "--define:DEBUG"; + yield "--optimize-"; + yield "--doc:test.xml"; + yield "--warn:3"; + yield "--fullpaths"; + yield "--flaterrors"; + yield "--target:library"; + let references = + [ sysLib "mscorlib" + sysLib "System" + sysLib "System.Core" + fsCore4300() ] + for r in references do + yield "-r:" + r |] + + { ProjectFileName = @"c:\mycode\compilation.fsproj" // Make a name that is unique in this directory. + ProjectId = None + SourceFiles = [| fileName1; fileName2 |] + OriginalLoadReferences = [] + Stamp = None + OtherOptions = allFlags + ReferencedProjects = [| |] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = true + LoadTime = System.DateTime.Now // Note using 'Now' forces reloading + UnresolvedReferences = None } + +let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously + +results.Diagnostics +results.AssemblySignature.Entities.Count //2 +results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1 +results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B" + +(** +Summary +------- +In this tutorial, we've seen how to globally customize the view of the file system used by the FSharp.Compiler.Service +component. + +At the time of writing, the following System.IO operations are not considered part of the virtualized file system API. +Future iterations on the compiler service implementation may add these to the API. + + - Path.Combine + - Path.DirectorySeparatorChar + - Path.GetDirectoryName + - Path.GetFileName + - Path.GetFileNameWithoutExtension + - Path.HasExtension + - Path.GetRandomFileName (used only in generation compiled win32 resources in assemblies) + +**NOTE:** Several operations in the `SourceCodeServices` API accept the contents of a file to parse +or check as a parameter, in addition to a file name. In these cases, the file name is only used for +error reporting. + +**NOTE:** Type provider components do not use the virtualized file system. + +**NOTE:** The compiler service may use MSBuild for assembly resolutions unless `--simpleresolution` is +provided. When using the `FileSystem` API you will normally want to specify `--simpleresolution` as one +of your compiler flags. Also specify `--noframework`. You will need to supply explicit resolutions of all +referenced .NET assemblies. + +*) \ No newline at end of file diff --git a/fcs/docsrc/content/index.md b/docs/fcs/index.md similarity index 100% rename from fcs/docsrc/content/index.md rename to docs/fcs/index.md diff --git a/docs/fcs/interactive.fsx b/docs/fcs/interactive.fsx new file mode 100644 index 00000000000..e455e7283c4 --- /dev/null +++ b/docs/fcs/interactive.fsx @@ -0,0 +1,278 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Interactive Service: Embedding F# Interactive +============================================= + +This tutorial demonstrates how to embed F# interactive in your application. F# interactive +is an interactive scripting environment that compiles F# code into highly efficient IL code +and executes it on the fly. The F# interactive service allows you to embed F# evaluation in +your application. + +> **NOTE:** There is a number of options for embedding F# Interactive. The easiest one is to use the +`fsi.exe` process and communicate with it using standard input and standard output. In this +tutorial, we look at calling F# Interactive directly through .NET API. However, if you have +no control over the input, it is a good idea to run F# interactive in a separate process. +One reason is that there is no way to handle `StackOverflowException` and so a poorly written +script can terminate the host process. **Remember that while calling F# Interactive through .NET API, +` --shadowcopyreferences` option will be ignored**. For detailed discussion, please take a look at +[this thread](https://github.com/fsharp/FSharp.Compiler.Service/issues/292). +> **NOTE:** If `FsiEvaluationSession.Create` fails with an error saying that `FSharp.Core.dll` cannot be found, +add the `FSharp.Core.sigdata` and `FSharp.Core.optdata` files. More info [here](https://fsharp.github.io/FSharp.Compiler.Service/corelib.html). + +However, the F# interactive service is still useful, because you might want to wrap it in your +own executable that is then executed (and communicates with the rest of your application), or +if you only need to execute limited subset of F# code (e.g. generated by your own DSL). + +Starting the F# interactive +--------------------------- + +First, we need to reference the libraries that contain F# interactive service: +*) + +#r "FSharp.Compiler.Service.dll" +open FSharp.Compiler.Interactive.Shell +open FSharp.Compiler.Tokenization + +(** +To communicate with F# interactive, we need to create streams that represent input and +output. We will use those later to read the output printed as a result of evaluating some +F# code that prints: +*) +open System +open System.IO +open System.Text + +// Initialize output and input streams +let sbOut = new StringBuilder() +let sbErr = new StringBuilder() +let inStream = new StringReader("") +let outStream = new StringWriter(sbOut) +let errStream = new StringWriter(sbErr) + +// Build command line arguments & start FSI session +let argv = [| "C:\\fsi.exe" |] +let allArgs = Array.append argv [|"--noninteractive"|] + +let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() +let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream) + + + +(** +Evaluating and executing code +----------------------------- + +The F# interactive service exposes several methods that can be used for evaluation. The first +is `EvalExpression` which evaluates an expression and returns its result. The result contains +the returned value (as `obj`) and the statically inferred type of the value: +*) +/// Evaluate expression & return the result +let evalExpression text = + match fsiSession.EvalExpression(text) with + | Some value -> printfn "%A" value.ReflectionValue + | None -> printfn "Got no result!" + +(** +This takes a string as an argument and evaluates (i.e. executes) it as F# code. +*) +evalExpression "42+1" // prints '43' + +(** +This can be used in a strongly typed way as follows: +*) + +/// Evaluate expression & return the result, strongly typed +let evalExpressionTyped<'T> (text) = + match fsiSession.EvalExpression(text) with + | Some value -> value.ReflectionValue |> unbox<'T> + | None -> failwith "Got no result!" + +evalExpressionTyped "42+1" // gives '43' + + +(** +The `EvalInteraction` method can be used to evaluate side-effectful operations +such as printing, declarations, or other interactions that are not valid F# expressions, but can be entered in +the F# Interactive console. Such commands include `#time "on"` (and other directives), `open System` +all declarations and other top-level statements. The code +does not require `;;` at the end. Just enter the code that you want to execute: +*) +fsiSession.EvalInteraction "printfn \"bye\"" + + +(** +The `EvalScript` method allows to evaluate a complete .fsx script. +*) + +File.WriteAllText("sample.fsx", "let twenty = 10 + 10") +fsiSession.EvalScript "sample.fsx" + +(** +Catching errors +------------------ + +``EvalExpression``, ``EvalInteraction`` and ``EvalScript`` are awkward if the +code has type checking warnings or errors, or if evaluation fails with an exception. +In these cases you can use ``EvalExpressionNonThrowing``, ``EvalInteractionNonThrowing`` +and ``EvalScriptNonThrowing``. These return a tuple of a result and an array of ``FSharpDiagnostic`` values. +These represent the errors and warnings. The result part is a ``Choice<_,_>`` between an actual +result and an exception. + +The result part of ``EvalExpression`` and ``EvalExpressionNonThrowing`` is an optional ``FSharpValue``. +If that value is not present then it just indicates that the expression didn't have a tangible +result that could be represented as a .NET object. This situation shouldn't actually +occur for any normal input expressions, and only for primitives used in libraries. +*) + +File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0") +let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx" + +// show the result +match result with +| Choice1Of2 () -> printfn "checked and executed ok" +| Choice2Of2 exn -> printfn "execution exception: %s" exn.Message + + +(** +Gives: + + execution exception: Operation could not be completed due to earlier error +*) + +// show the errors and warnings +for w in warnings do + printfn "Warning %s at %d,%d" w.Message w.StartLine w.StartColumn + +(** +Gives: + + Warning The type 'float' does not match the type 'char' at 1,19 + Warning The type 'float' does not match the type 'char' at 1,17 + +For expressions: +*) + + +let evalExpressionTyped2<'T> text = + let res, warnings = fsiSession.EvalExpressionNonThrowing(text) + for w in warnings do + printfn "Warning %s at %d,%d" w.Message w.StartLine w.StartColumn + match res with + | Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T> + | Choice1Of2 None -> failwith "null or no result" + | Choice2Of2 (exn:exn) -> failwith (sprintf "exception %s" exn.Message) + +evalExpressionTyped2 "42+1" // gives '43' + + +(** +Executing in parallel +------------------ + +By default the code passed to ``EvalExpression`` is executed immediately. To execute in parallel, submit a computation that starts a task: +*) + +open System.Threading.Tasks + +let sampleLongRunningExpr = + """ +async { + // The code of what you want to run + do System.Threading.Thread.Sleep 5000 + return 10 +} + |> Async.StartAsTask""" + +let task1 = evalExpressionTyped>(sampleLongRunningExpr) +let task2 = evalExpressionTyped>(sampleLongRunningExpr) + +(** +Both computations have now started. You can now fetch the results: +*) + + +task1.Result // gives the result after completion (up to 5 seconds) +task2.Result // gives the result after completion (up to 5 seconds) + +(** +Type checking in the evaluation context +------------------ + +Let's assume you have a situation where you would like to typecheck code +in the context of the F# Interactive scripting session. For example, you first +evaluation a declaration: +*) + +fsiSession.EvalInteraction "let xxx = 1 + 1" + +(** + +Now you want to typecheck the partially complete code `xxx + xx` +*) + +let parseResults, checkResults, checkProjectResults = + fsiSession.ParseAndCheckInteraction("xxx + xx") + |> Async.RunSynchronously + +(** +The `parseResults` and `checkResults` have types `ParseFileResults` and `CheckFileResults` +explained in [Editor](editor.html). You can, for example, look at the type errors in the code: +*) +checkResults.Diagnostics.Length // 1 + +(** +The code is checked with respect to the logical type context available in the F# interactive session +based on the declarations executed so far. + +You can also request declaration list information, tooltip text and symbol resolution: +*) + +// get a tooltip +checkResults.GetToolTip(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT) + +checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // symbol xxx + +(** +The 'fsi' object +------------------ + +If you want your scripting code to be able to access the 'fsi' object, you should pass in an implementation of this object explicitly. +Normally the one from FSharp.Compiler.Interactive.Settings.dll is used. +*) + +let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsiSession) + +(** +Collectible code generation +------------------ + +Evaluating code in using FsiEvaluationSession generates a .NET dynamic assembly and uses other resources. +You can make generated code collectible by passing `collectible=true`. However code will only +be collected if there are no outstanding object references involving types, for example +`FsiValue` objects returned by `EvalExpression`, and you must have disposed the `FsiEvaluationSession`. +See also [Restrictions on Collectible Assemblies](https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/dd554932(v=vs.100)#restrictions). + +The example below shows the creation of 200 evaluation sessions. Note that `collectible=true` and +`use session = ...` are both used. + +If collectible code is working correctly, +overall resource usage will not increase linearly as the evaluation progresses. +*) + +let collectionTest() = + + for i in 1 .. 200 do + let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|] + use inStream = new StringReader("") + use outStream = new StringWriter() + use errStream = new StringWriter() + + let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() + use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true) + + session.EvalInteraction (sprintf "type D = { v : int }") + let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i) + printfn "iteration %d, result = %A" i v.Value.ReflectionValue + +// collectionTest() <-- run the test like this diff --git a/docs/fcs/ja/compiler.fsx b/docs/fcs/ja/compiler.fsx new file mode 100644 index 00000000000..a795d8b2d39 --- /dev/null +++ b/docs/fcs/ja/compiler.fsx @@ -0,0 +1,89 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラの組み込み +==================== + +このチュートリアルではF#コンパイラをホストする方法を紹介します。 + +> **注意:** 以下で使用しているAPIは実験的なもので、 + 新しいnugetパッケージの公開に伴って変更される可能性があります。 + +> **注意:** F#コンパイラをホストする方法はいくつかあります。 + 一番簡単な方法は `fsc.exe` のプロセスを使って引数を渡す方法です。 + +--------------------------- + +まず、F# Interactiveサービスを含むライブラリへの参照を追加します: +*) + +#r "FSharp.Compiler.Service.dll" +open FSharp.Compiler.CodeAnalysis +open System.IO + +let scs = FSharpChecker.Create() + +(** +次に、一時ファイルへコンテンツを書き込みます: + +*) +let fn = Path.GetTempFileName() +let fn2 = Path.ChangeExtension(fn, ".fs") +let fn3 = Path.ChangeExtension(fn, ".dll") + +File.WriteAllText(fn2, """ +module M + +type C() = + member x.P = 1 + +let x = 3 + 4 +""") + +(** +そしてコンパイラを呼び出します: +*) + +let errors1, exitCode1 = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously + +(** + +エラーが発生した場合は「終了コード」とエラーの配列から原因を特定できます: + +*) +File.WriteAllText(fn2, """ +module M + +let x = 1.0 + "" // a type error +""") + +let errors1b, exitCode1b = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously + +if exitCode1b <> 0 then + errors1b + |> Array.iter (printfn "%A") + +(** + +動的アセンブリへのコンパイル +============================ + +コードを動的アセンブリとしてコンパイルすることもできます。 +動的アセンブリはF# Interactiveコードジェネレータでも使用されています。 + +この機能はたとえばファイルシステムが必ずしも利用できないような状況で役に立ちます。 + +出力ファイルの名前を指定する "-o" オプションを指定することは可能ですが、 +実際には出力ファイルがディスク上に書き込まれることはありません。 + +'execute' 引数に 'None' を指定するとアセンブリ用の初期化コードが実行されません。 +*) +let errors2, exitCode2, dynAssembly2 = + scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None) |> Async.RunSynchronously + +(** +'Some' を指定するとアセンブリ用の初期化コードが実行されます。 +*) +let errors3, exitCode3, dynAssembly3 = + scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr)) |> Async.RunSynchronously + diff --git a/docs/fcs/ja/corelib.fsx b/docs/fcs/ja/corelib.fsx new file mode 100644 index 00000000000..f5a7bbd2890 --- /dev/null +++ b/docs/fcs/ja/corelib.fsx @@ -0,0 +1,72 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス: FSharp.Core.dll についてのメモ +================================================== + +あなたのアプリケーションとともに FSharp.Core を配布する +------------------------------------------------------- + +FSharp.Compiler.Service.dll を利用するアプリケーションまたはプラグイン・コンポーネントをビルドする際、普通はアプリの一部として FSharp.Core.dll のコピーも含めることになるでしょう。 + +例えば、 ``HostedCompiler.exe`` をビルドする場合、普通はあなたの ``HostedCompiler.exe`` と同じフォルダに FSharp.Core.dll (例えば 4.3.1.0)を配置します。 + +動的コンパイルや動的実行を行う場合、FSharp.Core.optdata と FSharp.Core.sigdata も含める必要があるかもしれませんが、これらについては下記の指針をご覧ください。 + +どの FSharp.Core と .NET フレームワークがコンパイル時に参照される? +-------------------------------------- + +FSharp.Combiler.Service コンポーネントは多かれ少なかれ、F#コードを コンパイルするために使われるに過ぎません。特に、コマンドライン引数(あなたのツールを実行するために使われる FSharp.Core や .NET フレームワークとは違います)に明示的に FSharp.Core および/またはフレームワークのアセンブリを参照することが出来ます。 + +特定の FSharp.Core および .NET フレームワーク アセンブリ、またはそのいずれかをターゲットにする場合、 ``--noframework`` 引数と適切なコマンドライン引数を使います: + + [] + let fsharpCorePath = + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll" + let errors2, exitCode2 = + scs.Compile( + [| "fsc.exe"; "--noframework"; + "-r"; fsharpCorePath; + "-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"; + "-o"; fn3; + "-a"; fn2 |]) + +これらのアセンブリが配置されている場所を指定する必要があります。クロスプラットフォームに対応した方法でDLL を配置して、それらをコマンドライン引数に変換する最も簡単な方法は、[F# プロジェクトファイルをクラックする](https://fsharp.github.io/FSharp.Compiler.Service/ja/project.html)ことです。 +自分で SDK のパスを処理する代わりに、[FSharp.Compiler.Service.dll 用のテスト](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54)で使用しているようなヘルパー関数も用意されています。 + + +スクリプトを処理しているか ``GetCheckOptionsFromScriptRoot`` を使っている場合 +------------------------------------------------------------------------- + +もし SDK 配置先にある FSharp.Core.dll を明示的に参照 *していない* 場合、または ``FsiEvaluationSession`` や ``GetCheckOptionsFromScriptRoot`` を使用してスクリプトを処理している場合、以下のいずれかの方法により、暗黙的にFSharp.Core が参照されます: + +1. ``System.Reflection.Assembly.GetEntryAssembly()`` によって返されるホストアセンブリから静的に参照されたFSharp.Core.dll のバージョン + +2. ホストアセンブリに FSharp.Core への静的な参照がない場合、 + + - FSharp.Compiler.Service 0.x シリーズでは、FSharp.Core バージョン 4.3.0.0 への参照が付与されます + + - FSharp.Compiler.Service 1.3.1.x (F# 3.1 シリーズ)では、FSharp.Core バージョン 4.3.1.0 への参照が付与されます + + - FSharp.Compiler.Service 1.4.0.x (F# 4.0 シリーズ)では、FSharp.Core バージョン 4.4.0.0 への参照が付与されます + +FSharp.Core.optdata と FSharp.Core.sigdata を含める必要はありますか? +-------------------------------------- + +もしあなたのコンパイル引数が SDK 配置先にある FSharp.Core.dll を明示的に参照している場合、FSharp.Core.sigdata と FSharp.Core.optdata はその DLL と同じフォルダになければいけません(これらのファイルがインストールされていない場合、F# SDKの インストールに問題があります)。もしコンパイル引数で常に明示的に参照していたなら、FSharp.Core.optdata と FSharp.Core.sigdata はあなたのアプリケーションの一部として含める必要は *ありません* 。 + +もしあなたが暗黙的な参照(例えば、上記のスクリプト処理など)に頼っているのなら、これはあなたのツールがアプリケーションの一部として FSharp.Core.dll を参照しているかもしれない、ということです。この場合、FSharp.Core.optdata および FSharp.Core.sigdata が FSharp.Core.dll と同じフォルダに見つからないというエラーが発生するかもしれません。 **もしあなたがアプリケーションに含めている FSharp.Core.dll を暗黙的に参照したいのであれば、FSharp.Core.sigdata と FSharp.Core.optdata もアプリケーションに追加する2つのファイルとして追加しましょう。** ``CombileToDynamicAssembly`` を使用する場合、この問題によって[アセンブリ解決中のスタックオーバーフロー](https://github.com/fsharp/FSharp.Compiler.Service/issues/258)も引き起こされるでしょう。 + +動的コンパイルと動的コード実行を行うツール(例: ``HostedExecution.exe``)はしばしば FSharp.Core.dll を暗黙的に参照するようになっています。 +これはつまり通常 FSharp.Core.optdata と FSharp.Core.sigdata を含んでいるということです。 + +要約 +------- + +このデザインノートでは3つのポイントを検討しました: + +- どの FSharp.Core.dll があなたのコンパイルツールを実行するのに使われるか +- あなたのコンパイルツールを実行するのに使われる FSharp.Core.dll へのバインド リダイレクトを設定する方法 +- あなたのツールによって実行されるチェック時およびコンパイル時にどの FSharp.Core.dll および/またはフレームワークのアセンブリが参照されるか + +*) diff --git a/fcs/docsrc/content/ja/devnotes.md b/docs/fcs/ja/devnotes.md similarity index 100% rename from fcs/docsrc/content/ja/devnotes.md rename to docs/fcs/ja/devnotes.md diff --git a/docs/fcs/ja/editor.fsx b/docs/fcs/ja/editor.fsx new file mode 100644 index 00000000000..d5543eefdee --- /dev/null +++ b/docs/fcs/ja/editor.fsx @@ -0,0 +1,268 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス: エディタサービス +==================================== + +このチュートリアルはF#コンパイラによって公開されるエディタサービスの +使用方法についてのデモです。 +このAPIにより、Visual StudioやXamarin Studio、EmacsなどのF#エディタ内において、 +自動補完機能やツールチップ表示、引数情報のヘルプ表示、括弧の補完などの機能を +実装することができます +(詳細については [fsharpbindings](https://github.com/fsharp/fsharpbinding) のプロジェクトを参照してください)。 +[型無しASTを使用するチュートリアル](untypedtree.html) と同じく、 +今回も `FSharpChecker` オブジェクトを作成するところから始めます。 + +> **注意:** 以下で使用しているAPIは試験的なもので、最新バージョンのnugetパッケージの +公開に伴って変更されることがあります。 + +サンプルソースコードの型チェック +-------------------------------- + +[前回の(型無しASTを使った)チュートリアル](untypedtree.html) と同じく、 +`FSharp.Compiler.Service.dll` への参照を追加した後に特定の名前空間をオープンし、 +`FSharpChecker` のインスタンスを作成します: + +*) +// F#コンパイラAPIを参照 +#r "FSharp.Compiler.Service.dll" + +open System +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization + +// インタラクティブチェッカーのインスタンスを作成 +let checker = FSharpChecker.Create() + +(** + +[前回](untypedtree.html) 同様、 +コンパイラに渡されるファイルとしては特定の入力値だけであるという +コンテキストを想定するため、 `GetCheckOptionsFromScriptRoot` を使います +(この入力値はコンパイラによってスクリプトファイル、 +あるいはスタンドアロンのF#ソースコードとみなされます)。 + +*) +// サンプルの入力となる複数行文字列 +let input = + """ +open System + +let foo() = +let msg = String.Concat("Hello"," ","world") +if true then +printfn "%s" msg. +""" +// 入力値の分割とファイル名の定義 +let inputLines = input.Split('\n') +let file = "/home/user/Test.fsx" + +let projOptions, _errors1 = checker.GetProjectOptionsFromScript(file, SourceText.ofString input) |> Async.RunSynchronously + +let parsingOptions, _errors2 = checker.GetParsingOptionsFromProjectOptions(projOptions) + +(** + +型チェックを実行するには、まず `ParseFile` を使って +入力値をパースする必要があります。 +このメソッドを使うと [型無しAST](untypedtree.html) にアクセスできるようになります。 +しかし今回は完全な型チェックを実行するため、続けて `CheckFileInProject` +を呼び出す必要があります。 +このメソッドは `ParseFile` の結果も必要とするため、 +たいていの場合にはこれら2つのメソッドをセットで呼び出すことになります。 + +*) +// パースを実行 +let parseFileResults = + checker.ParseFile(file, SourceText.ofString input, parsingOptions) + |> Async.RunSynchronously +(** +`TypeCheckResults` に備えられた興味深い機能の紹介に入る前に、 +サンプル入力に対して型チェッカーを実行する必要があります。 +F#コードにエラーがあった場合も何らかの型チェックの結果が返されます +(ただし間違って「推測された」結果が含まれることがあります)。 +*) + +// 型チェックを実行 +let checkFileAnswer = + checker.CheckFileInProject(parseFileResults, file, 0, SourceText.ofString input, projOptions) + |> Async.RunSynchronously + +(** +あるいは `ParseAndCheckFileInProject` を使用すれば1つの操作で両方のチェックを行うことができます: +*) + +let parseResults2, checkFileAnswer2 = + checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString input, projOptions) + |> Async.RunSynchronously + +(** +この返り値は `CheckFileAnswer` 型で、この型に機能的に興味深いものが揃えられています... +*) + +let checkFileResults = + match checkFileAnswer with + | FSharpCheckFileAnswer.Succeeded(res) -> res + | res -> failwithf "パースが完了していません... (%A)" res + +(** + +今回は単に(状況に応じて)「Hello world」と表示するだけの +単純な関数の型をチェックしています。 +最終行では値 `msg` に対する補完リストを表示することができるように、 +`msg.` というようにドットを追加している点に注意してください +(今回の場合は文字列型に対する様々なメソッドが期待されます)。 + + +型チェックの結果を使用する +-------------------------- + +では `TypeCheckResults` 型で公開されているAPIをいくつか見ていきましょう。 +一般的に、F#ソースコードエディタサービスの実装に必要な機能は +ほとんどこの型に備えられています。 + +### ツールチップの取得 + +ツールチップを取得するには `GetToolTipTextAlternate` メソッドを使用します。 +このメソッドには行数と文字オフセットを指定します。 +いずれも0から始まる数値です。 +サンプルコードでは3行目(0行目は空白行)、インデックス7にある文字 `f` から始まる関数 +`foo` のツールチップを取得しています +(ツールチップは識別子の中であれば任意の位置で機能します)。 + +またこのメソッドにはトークンタグを指定する必要もあります。 +トークンタグは一般的には `IDENT` を指定して、識別子に対する +ツールチップが取得できるようにします +(あるいは `#r "..."` を使用している場合にはアセンブリの完全パスを表示させるように +することもできるでしょう)。 + +*) +// 最後の引数に指定する、IDENTトークンのタグを取得 + +// 特定の位置におけるツールチップを取得 +let tip = checkFileResults.GetToolTip(4, 7, inputLines.[1], ["foo"], FSharpTokenTag.Identifier) +printfn "%A" tip + +(** + +この関数には位置とトークンの種類の他にも、 +(ソースコードの変更時に役立つように)特定行の現在の内容と、 +現時点における完全修飾された `名前` を表す文字列のリストを指定する必要があります。 +たとえば完全修飾名 `System.Random` という名前を持った識別子 `Random` に対する +ツールチップを取得する場合、 `Random` という文字列が現れる場所の他に、 +`["System"; "Random"]` という値を指定する必要があります。 + +返り値の型は `ToolTipText` で、この型には `ToolTipElement` という +判別共用体が含まれます。 +この共用体は、コンパイラによって返されたツールチップの種類に応じて異なります。 + +### 自動補完リストの取得 + +次に紹介する `TypeCheckResults` のメソッドを使用すると、 +特定の位置における自動補完機能を実装できます。 +この機能は任意の識別子上、 +あるいは(特定のスコープ内で利用可能な名前の一覧を取得する場合には)任意のスコープ、 +あるいは特定のオブジェクトにおけるメンバーリストを取得する場合には +`.` の直後で呼び出すことができます。 +今回は文字列の値 `msg` に対するメンバーリストを取得することにします。 + +そのためには最終行( `printfn "%s" msg.` で終わっている行)にある +シンボル `.` の位置を指定して `GetDeclarationListInfo` を呼び出します。 +オフセットは1から始まるため、位置は `7, 23` になります。 +また、テキストが変更されていないことを表す関数と、 +現時点において補完する必要がある識別子を指定する必要もあります。 +*) +// 特定の位置における宣言(自動補完)を取得する +let decls = + checkFileResults.GetDeclarationListInfo + (Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun _ -> [])) + +// 利用可能な項目を表示 +for item in decls.Items do + printfn " - %s" item.Name +(** + +> **注意:** `GetDeclarationListInfo` は古い関数 `GetDeclarations` に代わるものです。 +`GetDeclarations` は0から始まる行番号を受け取るようになっていたため、非推奨になりました。 +また、将来的には現在の `GetDeclarations` が削除され、 `GetDeclarationListInfo` が +`GetDeclarations` になる予定です。 + +コードを実行してみると、 `Substring` や `ToUpper` 、 `ToLower` といった +文字列に対するいつものメソッドのリストが取得できていることでしょう。 +`GetDeclarations` の5,6番目の引数( `[]` および `"msg"` )には +自動補完用のコンテキストを指定します。 +今回の場合は完全名 `msg` に対する補完を行いましたが、 +たとえば `["System"; "Collections"]` と `"Generic"` というように +完全修飾された名前空間を指定して補完リストを取得することもできます。 + +### 引数の情報を取得する + +次に一般的なエディタの機能としては、メソッドのオーバーロードに +関する情報を提供するというものでしょう。 +サンプルコード中では多数のオーバーロードを持った `String.Concat` を使っています。 +このオーバーロード一覧は `GetMethods` で取得できます。 +先ほどと同じく、このメソッドには対象とする項目の位置を0基準のオフセットで指定し +(今回は `String.Concat` 識別子の右側の終端)、 +識別子もやはり指定します +(これにより、コンパイラはソースコードが変更された場合でも最新の情報に追従できます): + +*) +//String.Concatメソッドのオーバーロードを取得する +let methods = + checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) + +// 連結された引数リストを表示 +for mi in methods.Methods do + [ for p in mi.Parameters do for tt in p.Display do yield tt.Text ] + |> String.concat ", " + |> printfn "%s(%s)" methods.MethodName +(** +ここでは `Display` プロパティを使用することで各引数に対する +アノテーションを取得しています。 +このプロパティは `arg0: obj` あるいは `params args: obj[]` 、 +`str0: string, str1: string` といった情報を返します。 +これらの引数を連結した後、メソッド名とメソッドの型情報とともに表示させています。 +*) + +(** + +## 非同期操作と即時操作 + +`CheckFileInProject` が非同期操作であることを気にされる人もいるかもしれません。 +これはつまり、F#コードの型チェックにはある程度時間がかかることを示唆しています。 +F#コンパイラは型チェックを(自動的に)バックグラウンドで処理を進めているため、 +`CheckFileInProject` メソッドを呼び出すと非同期操作が返されることになります。 + +また、 `CheckFileInProjectIfReady` というメソッドもあります。 +このメソッドは、型チェックの操作が即座に開始できない場合、 +つまりプロジェクト内の他のファイルがまだ型チェックされていない場合には +処理が即座に返されます。 +この場合、バックグラウンドワーカーは一定期間他の作業を進めるか、 +`FileTypeCheckStateIsDirty` イベントが発生するまでは +ファイルに対する型チェックを諦めるか、どちらか選択することになります。 + +> [fsharpbinding](https://github.com/fsharp/fsharpbinding) プロジェクトには +1つのF#エージェント経由ですべてのリクエストをバックグラウンドワークとして +処理するような、より複雑な具体例も含まれています。 +エディタの機能を実装する方法としてはこちらのほうが適切です。 + +*) + + +(** +まとめ +------ + +`CheckFileAnswer` にはチュートリアルで紹介していないような便利なメソッドが +多数揃えられています。 +これらを使用すれば特定の識別子に対する宣言の位置を取得したり、 +付加的な色情報を取得したりすることができます +(F# 3.1では式ビルダーの識別子やクエリ演算子も着色表示されます)。 + +最後に、直接.NET APIを呼び出すことができないようなエディタに対するサポート機能を +実装する場合、ここで紹介した様々な機能を +[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete) +プロジェクトのコマンドラインインターフェイス経由で呼び出すこともできます。 +*) diff --git a/docs/fcs/ja/filesystem.fsx b/docs/fcs/ja/filesystem.fsx new file mode 100644 index 00000000000..c012596a73b --- /dev/null +++ b/docs/fcs/ja/filesystem.fsx @@ -0,0 +1,173 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス: ファイルシステム仮想化 +========================================== + +`FSharp.Compiler.Service` にはファイルシステムを表すグローバル変数があります。 +この変数を設定するこにより、ファイルシステムが利用できない状況でも +コンパイラをホストすることができるようになります。 + +> **注意:** 以下で使用しているAPIは実験的なもので、 + 新しいnugetパッケージの公開に伴って変更される可能性があります。 + +FileSystemの設定 +---------------- + +以下の例ではディスクからの読み取りを行うような実装をファイルシステムに設定しています: +*) +#r "FSharp.Compiler.Service.dll" +open System.IO +open System.Text +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO + +let defaultFileSystem = FileSystem + +let fileName1 = @"c:\mycode\test1.fs" // 注意: 実際には存在しないファイルのパス +let fileName2 = @"c:\mycode\test2.fs" // 注意: 実際には存在しないファイルのパス + +type MyFileSystem() = + let file1 = """ +module File1 + +let A = 1""" + let file2 = """ +module File2 +let B = File1.A + File1.A""" + let files = dict [(fileName1, file1); (fileName2, file2)] + + interface IFileSystem with + // 読み取りおよび書き込み用にファイルをオープンする機能を実装 + member __.FileStreamReadShim(fileName) = + match files.TryGetValue fileName with + | true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream + | _ -> defaultFileSystem.FileStreamReadShim(fileName) + + member __.FileStreamCreateShim(fileName) = + defaultFileSystem.FileStreamCreateShim(fileName) + + member __.IsStableFileHeuristic(fileName) = + defaultFileSystem.IsStableFileHeuristic(fileName) + + member __.FileStreamWriteExistingShim(fileName) = + defaultFileSystem.FileStreamWriteExistingShim(fileName) + + member __.ReadAllBytesShim(fileName) = + match files.TryGetValue fileName with + | true, text -> Encoding.UTF8.GetBytes(text) + | _ -> defaultFileSystem.ReadAllBytesShim(fileName) + + // 一時パスおよびファイルのタイムスタンプに関連する機能を実装 + member __.GetTempPathShim() = + defaultFileSystem.GetTempPathShim() + + member __.GetLastWriteTimeShim(fileName) = + defaultFileSystem.GetLastWriteTimeShim(fileName) + + member __.GetFullPathShim(fileName) = + defaultFileSystem.GetFullPathShim(fileName) + + member __.IsInvalidPathShim(fileName) = + defaultFileSystem.IsInvalidPathShim(fileName) + + member __.IsPathRootedShim(fileName) = + defaultFileSystem.IsPathRootedShim(fileName) + + // ファイルの存在確認および削除に関連する機能を実装 + member __.SafeExists(fileName) = + files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName) + + member __.FileDelete(fileName) = + defaultFileSystem.FileDelete(fileName) + + // アセンブリのロードに関連する機能を実装。 + // 型プロバイダやF# Interactiveで使用される。 + member __.AssemblyLoadFrom(fileName) = + defaultFileSystem.AssemblyLoadFrom fileName + + member __.AssemblyLoad(assemblyName) = + defaultFileSystem.AssemblyLoad assemblyName + +let myFileSystem = MyFileSystem() +FileSystem <- MyFileSystem() + +(** + +FileSystemによるコンパイルの実行 +-------------------------------- + +*) +open FSharp.Compiler.CodeAnalysis + +let checker = FSharpChecker.Create() +let projectOptions = + let allFlags = + [| yield "--simpleresolution"; + yield "--noframework"; + yield "--debug:full"; + yield "--define:DEBUG"; + yield "--optimize-"; + yield "--doc:test.xml"; + yield "--warn:3"; + yield "--fullpaths"; + yield "--flaterrors"; + yield "--target:library"; + let references = + [ @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll"; + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll"; + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll"; + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"] + for r in references do + yield "-r:" + r |] + + { ProjectFileName = @"c:\mycode\compilation.fsproj" // 現在のディレクトリで一意な名前を指定 + ProjectId = None + SourceFiles = [| fileName1; fileName2 |] + OriginalLoadReferences = [] + Stamp = None + OtherOptions = allFlags + ReferencedProjects=[| |] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = true + LoadTime = System.DateTime.Now // 'Now' を指定して強制的に再読込させている点に注意 + UnresolvedReferences = None } + +let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously + +results.Diagnostics +results.AssemblySignature.Entities.Count //2 +results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1 +results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B" + +(** +まとめ +------ +このチュートリアルでは FSharp.Compiler.Service コンポーネントで使用される +ファイルシステムに注目して、グローバルな設定を変更する方法について紹介しました。 + +このチュートリアルの執筆時点では、以下に列挙したSystem.IOの操作に対しては +仮想化されたファイルシステムAPIが用意されない予定になっています。 +将来のバージョンのコンパイラサービスではこれらのAPIが追加されるかもしれません。 + + - Path.Combine + - Path.DirectorySeparatorChar + - Path.GetDirectoryName + - Path.GetFileName + - Path.GetFileNameWithoutExtension + - Path.HasExtension + - Path.GetRandomFileName (アセンブリ内にコンパイル済みwin32リソースを生成する場合にのみ使用される) + +**注意:** `SourceCodeServices` API内の一部の操作では、 +引数にファイルの内容だけでなくファイル名を指定する必要があります。 +これらのAPIにおいて、ファイル名はエラーの報告のためだけに使用されます。 + +**注意:** 型プロバイダーコンポーネントは仮想化されたファイルシステムを使用しません。 + +**注意:** コンパイラサービスは `--simpleresolution` が指定されていない場合、 +MSBuildを使ってアセンブリの解決を試みることがあります。 +`FileSystem` APIを使用する場合、通常はコンパイラへのフラグとして +`--simpleresolution` を指定することになります。 +それと同時に `--noframework` を指定します。 +.NETアセンブリに対するすべての参照を明示的に指定する必要があるでしょう。 +*) diff --git a/fcs/docsrc/content/ja/index.md b/docs/fcs/ja/index.md similarity index 100% rename from fcs/docsrc/content/ja/index.md rename to docs/fcs/ja/index.md diff --git a/docs/fcs/ja/interactive.fsx b/docs/fcs/ja/interactive.fsx new file mode 100644 index 00000000000..9f7fb2109f4 --- /dev/null +++ b/docs/fcs/ja/interactive.fsx @@ -0,0 +1,298 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +インタラクティブサービス: F# Interactiveの組み込み +================================================== + +このチュートリアルでは、独自のアプリケーションに +F# Interactiveを組み込む方法について紹介します。 +F# Interactiveは対話式のスクリプティング環境で、 +F#コードを高度に最適化されたILコードへとコンパイルしつつ、 +それを即座に実行することができます。 +F# Interactiveサービスを使用すると、独自のアプリケーションに +F#の評価機能を追加できます。 + +> **注意:** F# Interactiveは様々な方法で組み込むことができます。 + 最も簡単な方法は `fsi.exe` プロセスとの間で標準入出力経由でやりとりする方法です。 + このチュートリアルではF# Interactiveの機能を.NET APIで + 直接呼び出す方法について紹介します。 + ただし入力用のコントロールを備えていない場合、別プロセスでF# Interactiveを + 起動するのはよい方法だといえます。 + 理由の1つとしては `StackOverflowException` を処理する方法がないため、 + 出来の悪いスクリプトによってはホストプロセスが停止させられてしまう + 場合があるからです。 + **.NET APIを通じてF# Interactiveを呼び出すとしても、 `--shadowcopyreferences` + オプションは無視されることを覚えておきましょう。** + 詳細な議論については、[このスレッド](https://github.com/fsharp/FSharp.Compiler.Service/issues/292) + に目を通してみてください。 + **注意:** もし`FSharp.Core.dll` が見つからないというエラーが出て `FsiEvaluationSession.Create` + に失敗した場合、 `FSharp.Core.sigdata` と `FSharp.Core.optdata` というファイルを追加してください。 + 詳しい内容は[こちら](https://fsharp.github.io/FSharp.Compiler.Service/ja/corelib.html) + にあります。 + +しかしそれでもF# InteractiveサービスにはF# Interactiveを実行ファイルに埋め込んで +実行出来る(そしてアプリケーションの各機能とやりとり出来る)、あるいは +機能限定されたF#コード(たとえば独自のDSLによって生成されたコード)だけを +実行させることが出来るという便利さがあります。 + +F# Interactiveの開始 +-------------------- + +まずF# Interactiveサービスを含むライブラリへの参照を追加します: +*) + +#r "FSharp.Compiler.Service.dll" +open FSharp.Compiler.Tokenization +open FSharp.Compiler.Interactive.Shell + +(** +F# Interactiveとやりとりするには、入出力を表すストリームを作成する必要があります。 +これらのストリームを使用することで、 +いくつかのF#コードに対する評価結果を後から出力することができます: +*) +open System +open System.IO +open System.Text + +// 入出力のストリームを初期化 +let sbOut = StringBuilder() +let sbErr = StringBuilder() +let inStream = new StringReader("") +let outStream = new StringWriter(sbOut) +let errStream = new StringWriter(sbErr) + +// コマンドライン引数を組み立てて、FSIセッションを開始する +let argv = [| "C:\\fsi.exe" |] +let allArgs = Array.append argv [|"--noninteractive"|] + +let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() +let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream) + +(** +コードの評価および実行 +---------------------- + +F# Interactiveサービスにはコードを評価するためのメソッドがいくつか用意されています。 +最初の1つは `EvalExpression` で、式を評価してその結果を返します。 +結果には戻り値が( `obj` として)含まれる他、値に対して静的に推論された型も含まれます: +*) +/// 式を評価して結果を返す +let evalExpression text = + match fsiSession.EvalExpression(text) with + | Some value -> printfn "%A" value.ReflectionValue + | None -> printfn "結果が得られませんでした!" + +(** +これは引数に文字列を取り、それをF#コードとして評価(つまり実行)します。 +*) +evalExpression "42+1" // '43' を表示する + +(** +これは以下のように強く型付けされた方法で使うことができます: +*) + +/// 式を評価して、強く型付けされた結果を返す +let evalExpressionTyped<'T> (text) = + match fsiSession.EvalExpression(text) with + | Some value -> value.ReflectionValue |> unbox<'T> + | None -> failwith "結果が得られませんでした!" + +evalExpressionTyped "42+1" // '43' になる + + +(** +`EvalInteraction` メソッドは画面出力機能や宣言、 +F#の式としては不正なものの、F# Interactiveコンソールには入力できるようなものなど、 +副作用を伴う命令を評価する場合に使用できます。 +たとえば `#time "on"` (あるいはその他のディレクティブ)や `open System` 、 +その他の宣言やトップレベルステートメントなどが該当します。 +指定するコードの終端に `;;` を入力する必要はありません。 +実行したいコードだけを入力します: +*) +fsiSession.EvalInteraction "printfn \"bye\"" + + +(** +`EvalScript` メソッドを使用すると、完全な .fsx スクリプトを評価することができます。 +*) + +File.WriteAllText("sample.fsx", "let twenty = 10 + 10") +fsiSession.EvalScript "sample.fsx" + +(** +例外処理 +-------- + +コードに型チェックの警告やエラーがあった場合、または評価して例外で失敗した場合、 +`EvalExpression` 、 `EvalInteraction` そして `EvalScript` ではあまりうまく処理されません。 +これらのケースでは、 `EvalExpressionNonThrowing` 、 `EvalInteractionNonThrowing` +そして `EvalScriptNonThrowing` を使うことが出来ます。 +これらは結果と `FSharpDiagnostic` 値の配列の組を返します。 +これらはエラーと警告を表します。結果の部分は実際の結果と例外のいずれかを表す +`Choice<_,_>` です。 + +`EvalExpression` および `EvalExpressionNonThrowing` の結果部分は +オプションの `FSharpValue` 値です。 +その値が存在しない場合、式が .NET オブジェクトとして表現できる具体的な結果を +持っていなかったということを指し示しています。 +この状況は実際には入力されたどんな通常の式に対しても発生すべきではなく、 +ライブラリ内で使われるプリミティブ値に対してのみ発生すべきです。 +*) + +File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0") +let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx" + +// 結果を表示する +match result with +| Choice1Of2 () -> printfn "チェックと実行はOKでした" +| Choice2Of2 exn -> printfn "実行例外: %s" exn.Message + + +(** +は次のようになります: + + 実行例外: Operation could not be completed due to earlier error +*) + +// エラーと警告を表示する +for w in warnings do + printfn "警告 %s 場所 %d,%d" w.Message w.StartLine w.StartColumn + +(** +は次のようになります: + + 警告 The type 'float' does not match the type 'char' 場所 1,19 + 警告 The type 'float' does not match the type 'char' 場所 1,17 + +式に対しては: +*) + + +let evalExpressionTyped2<'T> text = + let res, warnings = fsiSession.EvalExpressionNonThrowing(text) + for w in warnings do + printfn "警告 %s 場所 %d,%d" w.Message w.StartLine w.StartColumn + match res with + | Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T> + | Choice1Of2 None -> failwith "null または結果がありません" + | Choice2Of2 (exn:exn) -> failwith (sprintf "例外 %s" exn.Message) + +evalExpressionTyped2 "42+1" // '43' になる + + +(** +並列実行 +-------- + +デフォルトでは `EvalExpression` に渡したコードは即時実行されます。 +並列に実行するために、タスクを開始する計算を投入します: +*) + +open System.Threading.Tasks + +let sampleLongRunningExpr = + """ +async { + // 実行したいコード + do System.Threading.Thread.Sleep 5000 + return 10 +} + |> Async.StartAsTask""" + +let task1 = evalExpressionTyped>(sampleLongRunningExpr) +let task2 = evalExpressionTyped>(sampleLongRunningExpr) + +(** +両方の計算がいま開始しました。結果を取得することが出来ます: +*) + + +task1.Result // 完了後に結果が出てくる (最大5秒) +task2.Result // 完了後に結果が出てくる (最大5秒) + +(** +評価コンテキスト内での型チェック +-------------------------------- + +F# Interactiveの一連のスクリプティングセッション中で +コードの型チェックを実行したいような状況を考えてみましょう。 +たとえばまず宣言を評価します: +*) + +fsiSession.EvalInteraction "let xxx = 1 + 1" + +(** + +次に部分的に完全な `xxx + xx` というコードの型チェックを実行したいとします: +*) + +let parseResults, checkResults, checkProjectResults = + fsiSession.ParseAndCheckInteraction("xxx + xx") |> Async.RunSynchronously + +(** +`parseResults` と `checkResults` はそれぞれ [エディタ](editor.html) +のページで説明している `FSharpParseFileResults` と `FSharpCheckFileResults` 型です。 +たとえば以下のようなコードでエラーを確認出来ます: +*) +checkResults.Diagnostics.Length // 1 + +(** +コードはF# Interactiveセッション内において、その時点までに実行された +有効な宣言からなる論理的な型コンテキストと結びつく形でチェックされます。 + +また、宣言リスト情報やツールチップテキスト、シンボルの解決といった処理を +要求することもできます: + +*) + +// ツールチップを取得する +checkResults.GetToolTip(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT) + +checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // シンボル xxx + +(** +'fsi'オブジェクト +----------------- + +スクリプトのコードが'fsi'オブジェクトにアクセスできるようにしたい場合、 +このオブジェクトの実装を明示的に渡さなければなりません。 +通常、FSharp.Compiler.Interactive.Settings.dll由来の1つが使われます。 +*) + +let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsi) + +(** +収集可能なコード生成 +-------------------- + +FsiEvaluationSessionを使用してコードを評価すると、 +.NET の動的アセンブリを生成し、他のリソースを使用します。 +`collectible=true` を渡すことで、生成されたコードを収集可能に出来ます。 +しかしながら、例えば `EvalExpression` から返される `FsiValue` のような型を必要とする未解放のオブジェクト参照が無く、 +かつ `FsiEvaluationSession` を破棄したに違いない場合に限ってコードが収集されます。 +[収集可能なアセンブリに対する制限](https://msdn.microsoft.com/ja-jp/library/dd554932%28v=vs.110%29.aspx#Anchor_1) +も参照してください。 + +以下の例は200個の評価セッションを生成しています。 `collectible=true` と `use session = ...` +の両方を使っていることに気をつけてください。 + +収集可能なコードが正しく動いた場合、全体としてのリソース使用量は +評価が進んでも線形には増加しないでしょう。 +*) + +let collectionTest() = + + for i in 1 .. 200 do + let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|] + use inStream = new StringReader("") + use outStream = new StringWriter() + use errStream = new StringWriter() + + let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() + use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true) + + session.EvalInteraction (sprintf "type D = { v : int }") + let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i) + printfn "その %d, 結果 = %A" i v.Value.ReflectionValue + +// collectionTest() <-- このようにテストを実行する \ No newline at end of file diff --git a/docs/fcs/ja/project.fsx b/docs/fcs/ja/project.fsx new file mode 100644 index 00000000000..bdb658a0452 --- /dev/null +++ b/docs/fcs/ja/project.fsx @@ -0,0 +1,281 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス: プロジェクトの分析 +====================================== + +このチュートリアルではF#コンパイラによって提供されるサービスを使用して +プロジェクト全体を分析する方法について紹介します。 + +> **注意:** 以下で使用しているAPIは試験的なもので、 + 最新のnugetパッケージの公開に伴って変更されることがあります。 + + +プロジェクト全体の結果を取得する +-------------------------------- + +[以前の(型無しASTを使った)チュートリアル](untypedtree.html) と同じく、 +まずは `FSharp.Compiler.Service.dll` への参照追加と、適切な名前空間のオープン、 +`FSharpChecker` インスタンスの作成を行います: + +*) +// F#コンパイラAPIへの参照 +#r "FSharp.Compiler.Service.dll" + +open System.Collections.Generic +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text + +// インタラクティブチェッカーのインスタンスを作成 +let checker = FSharpChecker.Create() + +(** +今回のサンプル入力は以下の通りです: +*) + +module Inputs = + open System.IO + + let base1 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(base1, ".fs") + let base2 = Path.GetTempFileName() + let fileName2 = Path.ChangeExtension(base2, ".fs") + let dllName = Path.ChangeExtension(base2, ".dll") + let projFileName = Path.ChangeExtension(base2, ".fsproj") + let fileSource1 = """ +module M + +type C() = + member x.P = 1 + +let xxx = 3 + 4 +let fff () = xxx + xxx + """ + File.WriteAllText(fileName1, fileSource1) + + let fileSource2 = """ +module N + +open M + +type D1() = + member x.SomeProperty = M.xxx + +type D2() = + member x.SomeProperty = M.fff() + +// 警告を発生させる +let y2 = match 1 with 1 -> M.xxx + """ + File.WriteAllText(fileName2, fileSource2) + + +(** +`GetProjectOptionsFromCommandLineArgs` を使用して、 +2つのファイルを1つのプロジェクトとして扱えるようにします: +*) + +let projectOptions = + checker.GetProjectOptionsFromCommandLineArgs + (Inputs.projFileName, + [| yield "--simpleresolution" + yield "--noframework" + yield "--debug:full" + yield "--define:DEBUG" + yield "--optimize-" + yield "--out:" + Inputs.dllName + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + yield Inputs.fileName1 + yield Inputs.fileName2 + let references = + [ @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"] + for r in references do + yield "-r:" + r |]) + +(** +そして(ディスク上に保存されたファイルを使用して) +プロジェクト全体をチェックします: +*) + +let wholeProjectResults = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously + +(** +発生したエラーと警告は以下のようにしてチェックできます: +*) +wholeProjectResults.Diagnostics.Length // 1 +wholeProjectResults.Diagnostics.[0].Message.Contains("Incomplete pattern matches on this expression") // true + +wholeProjectResults.Diagnostics.[0].StartLine // 13 +wholeProjectResults.Diagnostics.[0].EndLine // 13 +wholeProjectResults.Diagnostics.[0].StartColumn // 15 +wholeProjectResults.Diagnostics.[0].EndColumn // 16 + +(** +推測されたプロジェクトのシグネチャをチェックします: +*) +[ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] // ["N"; "M"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] // ["D1"; "D2"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[1].NestedEntities -> x.DisplayName ] // ["C"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] // ["y2"] + +(** +プロジェクト内の全シンボルを取得することもできます: +*) +let rec allSymbolsInEntities (entities: IList) = + [ for e in entities do + yield (e :> FSharpSymbol) + for x in e.MembersFunctionsAndValues do + yield (x :> FSharpSymbol) + for x in e.UnionCases do + yield (x :> FSharpSymbol) + for x in e.FSharpFields do + yield (x :> FSharpSymbol) + yield! allSymbolsInEntities e.NestedEntities ] + +let allSymbols = allSymbolsInEntities wholeProjectResults.AssemblySignature.Entities +(** +プロジェクト全体のチェックが完了した後は、 +プロジェクト内の各ファイルに対する個別の結果を取得することもできます。 +この処理は即座に完了し、改めてチェックが実行されることもありません。 +*) + +let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Inputs.fileName1, projectOptions) + |> Async.RunSynchronously + + +(** +そしてそれぞれのファイル内にあるシンボルを解決できます: +*) + +let xSymbol = + backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) + +(** +それぞれのシンボルに対して、シンボルへの参照を検索することもできます: +*) +let usesOfXSymbol = wholeProjectResults.GetUsesOfSymbol(xSymbol.Value.Symbol) + +(** +推測されたシグネチャ内にあるすべての定義済みシンボルに対して、 +それらがどこで使用されているのかを探し出すこともできます: +*) +let allUsesOfAllSignatureSymbols = + [ for s in allSymbols do + yield s.ToString(), wholeProjectResults.GetUsesOfSymbol(s) ] + +(** +(ローカルスコープで使用されているものも含めて) +プロジェクト全体で使用されているすべてのシンボルを確認することもできます: +*) +let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() + +(** +また、プロジェクト内のファイルに対して、更新後のバージョンに対して +チェックを実行するようにリクエストすることもできます +(なお [FileSystem API](filesystem.html) を使用していない場合には、 +プロジェクト内のその他のファイルがまだディスクから +読み取り中であることに注意してください): + +*) +let parseResults1, checkAnswer1 = + checker.ParseAndCheckFileInProject(Inputs.fileName1, 0, SourceText.ofString Inputs.fileSource1, projectOptions) + |> Async.RunSynchronously + +let checkResults1 = + match checkAnswer1 with + | FSharpCheckFileAnswer.Succeeded x -> x + | _ -> failwith "想定外の終了状態です" + +let parseResults2, checkAnswer2 = + checker.ParseAndCheckFileInProject(Inputs.fileName2, 0, SourceText.ofString Inputs.fileSource2, projectOptions) + |> Async.RunSynchronously + +let checkResults2 = + match checkAnswer2 with + | FSharpCheckFileAnswer.Succeeded x -> x + | _ -> failwith "想定外の終了状態です" + +(** +そして再びシンボルを解決したり、参照を検索したりすることができます: +*) + +let xSymbol2 = + checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) + +let usesOfXSymbol2 = wholeProjectResults.GetUsesOfSymbol(xSymbol2.Value.Symbol) + +(** +あるいは(ローカルスコープで使用されているシンボルも含めて) +ファイル中で使用されているすべてのシンボルを検索することもできます: +*) +let allUsesOfAllSymbolsInFile1 = checkResults1.GetAllUsesOfAllSymbolsInFile() + +(** +あるいは特定のファイル中で使用されているシンボルを検索することもできます: +*) +let allUsesOfXSymbolInFile1 = checkResults1.GetUsesOfSymbolInFile(xSymbol2.Value.Symbol) + +let allUsesOfXSymbolInFile2 = checkResults2.GetUsesOfSymbolInFile(xSymbol2.Value.Symbol) + +(** + +複数プロジェクトの分析 +---------------------- + +複数のプロジェクトにまたがった参照があるような、 +複数のF# プロジェクトを分析したい場合、 +それらのプロジェクトを一旦ビルドして、 +ProjectOptionsで `-r:プロジェクト-出力-までの-パス.dll` 引数を指定して +プロジェクトの相互参照を設定すると一番簡単です。 +しかしこの場合、それぞれのプロジェクトが正しくビルド出来、 +DLLファイルが参照可能なディスク上に生成されなければいけません。 + +たとえばIDEを操作している場合など、状況によっては +DLLのコンパイルが通るようになる前に +プロジェクトを参照したいことがあるでしょう。 +この場合はProjectOptionsのReferencedProjectsを設定します。 +この値には依存するプロジェクトのオプションを再帰的に指定します。 +それぞれのプロジェクト参照にはやはり、 +ReferencedProjectsのエントリそれぞれに対応する +`-r:プロジェクト-出力-までの-パス.dll` というコマンドライン引数を +ProjectOptionsに設定する必要があります。 + +プロジェクト参照が設定されると、ソースファイルからのF#プロジェクト分析処理が +インクリメンタル分析の結果を使用して行われるようになります。 +その際にはソースファイルファイルをDLLへとコンパイルする必要はありません。 + +相互参照を含むようなF#プロジェクトを効率よく分析するには、 +ReferencedProjectsを正しく設定した後、 +それぞれのプロジェクトを順番通りに分析していくとよいでしょう。 + +> **注意:** プロジェクトの参照機能は試作段階です。 + プロジェクトの参照を使用すると、依存先のプロジェクトがまだ分析中で、 + 要求したサービスがまだ利用できないことがあるため、 + コンパイラサービスの性能が低下することがあります。 + +> **注意:** アセンブリが型プロバイダーのコンポーネントを含む場合、 + プロジェクト参照機能は利用できません。 + プロジェクトの分析処理を強制しない限りはプロジェクト参照を設定しても + 効果がありません。 + また、分析を強制する場合にはディスク上にDLLが存在しなければいけません。 + +*) + +(** +まとめ +------ + +これまで説明してきた通り、 `ParseAndCheckProject` を使用すると +シンボルの参照などのようなプロジェクト全体の解析結果にアクセスできるようになります。 +シンボルに対する処理の詳細については [シンボル](symbols.html) のページを参照してください。 + +*) diff --git a/docs/fcs/ja/symbols.fsx b/docs/fcs/ja/symbols.fsx new file mode 100644 index 00000000000..02e2ee48602 --- /dev/null +++ b/docs/fcs/ja/symbols.fsx @@ -0,0 +1,236 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス: シンボルの処理 +================================== + +このチュートリアルでは、F#コンパイラによって提供される +シンボルの扱い方についてのデモを紹介します。 +シンボルの参照に関する情報については [プロジェクト全体の分析](project.html) +も参考にしてください。 + +> **注意:** 以下で使用しているAPIは試験的なもので、 + 最新のnugetパッケージの公開に伴って変更されることがあります。 + +これまでと同じく、 `FSharp.Compiler.Service.dll` への参照を追加した後、 +適切な名前空間をオープンし、 `FSharpChecker` のインスタンスを作成します: + +*) +// F#コンパイラAPIへの参照 +#r "FSharp.Compiler.Service.dll" + +open System.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text + +// インタラクティブチェッカーのインスタンスを作成 +let checker = FSharpChecker.Create() + +(** + +そして特定の入力値に対して型チェックを行います: + +*) + +let parseAndTypeCheckSingleFile (file, input) = + // スタンドアロンの(スクリプト)ファイルを表すコンテキストを取得 + let projOptions, _errors = + checker.GetProjectOptionsFromScript(file, input) + |> Async.RunSynchronously + + let parseFileResults, checkFileResults = + checker.ParseAndCheckFileInProject(file, 0, input, projOptions) + |> Async.RunSynchronously + + // 型チェックが成功(あるいは100%に到達)するまで待機 + match checkFileResults with + | FSharpCheckFileAnswer.Succeeded(res) -> parseFileResults, res + | res -> failwithf "Parsing did not finish... (%A)" res + +let file = "/home/user/Test.fsx" + +(** +## ファイルに対する解決済みのシグネチャ情報を取得する + +ファイルに対する型チェックが完了すると、 +`TypeCheckResults` の `PartialAssemblySignature` プロパティを参照することにより、 +チェック中の特定のファイルを含む、推論されたプロジェクトのシグネチャに +アクセスすることができます。 + +モジュールや型、属性、メンバ、値、関数、共用体、レコード型、測定単位、 +およびその他のF#言語要素に対する完全なシグネチャ情報が参照できます。 + +ただし型付き式ツリーに対する情報は(今のところ)この方法では利用できません。 + +*) + +let input2 = + """ +[] +let foo(x, y) = + let msg = String.Concat("Hello"," ","world") + if true then + printfn "x = %d, y = %d" x y + printfn "%s" msg + +type C() = + member x.P = 1 + """ +let parseFileResults, checkFileResults = + parseAndTypeCheckSingleFile(file, SourceText.ofString input2) + +(** +これでコードに対する部分的なアセンブリのシグネチャが取得できるようになります: +*) +let partialAssemblySignature = checkFileResults.PartialAssemblySignature + +partialAssemblySignature.Entities.Count = 1 // エンティティは1つ + +(** +そしてコードを含むモジュールに関連したエンティティを取得します: +*) +let moduleEntity = partialAssemblySignature.Entities.[0] + +moduleEntity.DisplayName = "Test" + +(** +そしてコード内の型定義に関連したエンティティを取得します: +*) +let classEntity = moduleEntity.NestedEntities.[0] + +(** +そしてコード内で定義された関数に関連した値を取得します: +*) +let fnVal = moduleEntity.MembersFunctionsAndValues.[0] + +(** +関数値に関するプロパティの値を確認してみましょう。 +*) +fnVal.Attributes.Count // 1 +fnVal.CurriedParameterGroups.Count // 1 +fnVal.CurriedParameterGroups.[0].Count // 2 +fnVal.CurriedParameterGroups.[0].[0].Name // "x" +fnVal.CurriedParameterGroups.[0].[1].Name // "y" +fnVal.DeclarationLocation.StartLine // 3 +fnVal.DisplayName // "foo" +fnVal.DeclaringEntity.Value.DisplayName // "Test" +fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1 +fnVal.GenericParameters.Count // 0 +fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline +fnVal.IsActivePattern // false +fnVal.IsCompilerGenerated // false +fnVal.IsDispatchSlot // false +fnVal.IsExtensionMember // false +fnVal.IsPropertyGetterMethod // false +fnVal.IsImplicitConstructor // false +fnVal.IsInstanceMember // false +fnVal.IsMember // false +fnVal.IsModuleValueOrMember // true +fnVal.IsMutable // false +fnVal.IsPropertySetterMethod // false +fnVal.IsTypeFunction // false + +(** +次に、この関数の型がファーストクラスの値として使用されているかどうかチェックします。 +(ちなみに `CurriedParameterGroups` プロパティには引数の名前など、 +より多くの情報も含まれています) +*) +fnVal.FullType // int * int -> unit +fnVal.FullType.IsFunctionType // true +fnVal.FullType.GenericArguments.[0] // int * int +fnVal.FullType.GenericArguments.[0].IsTupleType // true +let argTy1 = fnVal.FullType.GenericArguments.[0].GenericArguments.[0] + +argTy1.TypeDefinition.DisplayName // int + +(** +というわけで `int * int -> unit` という型を表現するオブジェクトが取得できて、 +その1つめの 'int' を確認できたわけです。 +また、以下のようにすると 'int' 型についてのより詳細な情報が取得でき、 +それが名前付きの型であり、F#の型省略形 `type int = int32` であることがわかります: +*) + +argTy1.HasTypeDefinition // true +argTy1.TypeDefinition.IsFSharpAbbreviation // true + +(** +型省略形の右辺、つまり `int32` についてもチェックしてみましょう: +*) + +let argTy1b = argTy1.TypeDefinition.AbbreviatedType +argTy1b.TypeDefinition.Namespace // Some "Microsoft.FSharp.Core" +argTy1b.TypeDefinition.CompiledName // "int32" + +(** +そして再び型省略形 `type int32 = System.Int32` から型に関する完全な情報が取得できます: +*) +let argTy1c = argTy1b.TypeDefinition.AbbreviatedType +argTy1c.TypeDefinition.Namespace // Some "System" +argTy1c.TypeDefinition.CompiledName // "Int32" + +(** +ファイルに対する型チェックの結果には、 +コンパイル時に使用されたプロジェクト(あるいはスクリプト)のオプションに関する +`ProjectContext` と呼ばれる情報も含まれています: +*) +let projectContext = checkFileResults.ProjectContext + +for assembly in projectContext.GetReferencedAssemblies() do + match assembly.FileName with + | None -> printfn "コンパイル時にファイルの存在しないアセンブリを参照しました" + | Some s -> printfn "コンパイル時にアセンブリ '%s' を参照しました" s + +(** +**注意:** + + - 不完全なコードが存在する場合、一部あるいはすべての属性が意図したとおりには + 並ばないことがあります。 + - (実際には非常によくあることですが)一部のアセンブリが見つからない場合、 + 外部アセンブリに関連する値やメンバ、エンティティにおける 'IsUnresolved' が + trueになることがあります。 + IsUnresolvedによる例外に対処できるよう、堅牢なコードにしておくべきです。 + +*) + +(** + +## プロジェクト全体に対するシンボル情報を取得する + +プロジェクト全体をチェックする場合、チェッカーを作成した後に `parseAndCheckScript` +を呼び出します。 +今回の場合は単に1つのスクリプトだけが含まれたプロジェクトをチェックします。 +異なる "projOptions" を指定すると、巨大なプロジェクトに対する設定を +構成することもできます。 +*) +let parseAndCheckScript (file, input) = + let projOptions, errors = + checker.GetProjectOptionsFromScript(file, SourceText.ofString input) + |> Async.RunSynchronously + + let projResults = + checker.ParseAndCheckProject(projOptions) + |> Async.RunSynchronously + + projResults + +(** +そして特定の入力に対してこの関数を呼び出します: +*) + +let tmpFile = Path.ChangeExtension(System.IO.Path.GetTempFileName() , "fs") +File.WriteAllText(tmpFile, input2) + +let projectResults = parseAndCheckScript(tmpFile, input2) + + +(** +結果は以下の通りです: +*) + +let assemblySig = projectResults.AssemblySignature + +assemblySig.Entities.Count = 1 // エンティティは1つ +assemblySig.Entities.[0].Namespace // null +assemblySig.Entities.[0].DisplayName // "Tmp28D0" +assemblySig.Entities.[0].MembersFunctionsAndValues.Count // 1 +assemblySig.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "foo" diff --git a/docs/fcs/ja/tokenizer.fsx b/docs/fcs/ja/tokenizer.fsx new file mode 100644 index 00000000000..46548bbd74e --- /dev/null +++ b/docs/fcs/ja/tokenizer.fsx @@ -0,0 +1,145 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス:F#トークナイザを使用する +============================================ + +このチュートリアルではF#言語トークナイザの呼び出し方を紹介します。 +F#のソースコードに対して、トークナイザは +コードの各行にあるトークンに関する情報を含んだソースコード行のリストを生成します。 +各トークンに対してはトークンの種類や位置を取得したり、 +トークンの種類(キーワード、識別子、数値、演算子など)に応じた +色を取得したりすることができます。 + +> **注意:** 以下で使用しているAPIは実験的なもので、 + 新しいnugetパッケージの公開に伴って変更される可能性があります。 + +トークナイザの作成 +------------------ + +トークナイザを使用するには、 `FSharp.Compiler.Service.dll` への参照を追加した後に +`Tokenization` 名前空間をオープンします: +*) +#r "FSharp.Compiler.Service.dll" +open FSharp.Compiler.Tokenization +(** +すると `FSharpSourceTokenizer` のインスタンスを作成できるようになります。 +このクラスには2つの引数を指定します。 +最初の引数には定義済みのシンボルのリスト、 +2番目の引数にはソースコードのファイル名を指定します。 +定義済みのシンボルのリストを指定するのは、 +トークナイザが `#if` ディレクティブを処理する必要があるからです。 +ファイル名はソースコードの位置を特定する場合にのみ指定する必要があります +(存在しないファイル名でも指定できます): +*) +let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") +(** +`sourceTok` オブジェクトを使用することでF#ソースコードの各行を +(繰り返し)トークン化することができます。 + +F#コードのトークン化 +-------------------- + +トークナイザはソースファイル全体ではなく、行単位で処理を行います。 +トークンを取得した後、トークナイザは新しいステートを( `int64` 値として)返します。 +この値を使うとF#コードをより効率的にトークン化できます。 +つまり、ソースコードが変更された場合もファイル全体を +再度トークン化する必要はありません。 +変更された部分だけをトークン化すればよいのです。 + +### 1行をトークン化する + +1行をトークン化するには、先ほど作成した `FSharpSourceTokenizer` オブジェクトに対して +`CreateLineTokenizer` を呼び、 `FSharpLineTokenizer` を作成します: +*) +let tokenizer = sourceTok.CreateLineTokenizer("let answer=42") +(** +そして `tokenizer` の `ScanToken` を繰り返し `None` を返すまで +(つまり最終行に到達するまで)繰り返し呼び出すような単純な再帰関数を用意します。 +この関数が成功すると、必要な詳細情報をすべて含んだ `FSharpTokenInfo` オブジェクトが +返されます: +*) +/// F#コード1行をトークン化します +let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = + match tokenizer.ScanToken(state) with + | Some tok, state -> + // トークン名を表示 + printf "%s " tok.TokenName + // 新しい状態で残りをトークン化 + tokenizeLine tokenizer state + | None, state -> state +(** +この関数は、複数行コードや複数行コメント内の前方の行をトークン化する場合に +必要となるような新しい状態を返します。 +初期値としては `0L` を指定します: +*) +tokenizeLine tokenizer FSharpTokenizerLexState.Initial +(** +この結果は LET WHITESPACE IDENT EQUALS INT32 という +トークン名のシーケンスになります。 +`FSharpTokenInfo` にはたとえば以下のような興味深いプロパティが多数あります: + + - `CharClass` および `ColorClass` はF#コードを色づけする場合に使用できるような、 + トークンのカテゴリに関する情報を返します。 + - `LeftColumn` および `RightColumn` は行内におけるトークンの位置を返します。 + - `TokenName` は(F# レキサ内で定義された)トークンの名前を返します。 + +なおトークナイザはステートフルであることに注意してください。 +つまり、1行を複数回トークン化したい場合にはその都度 `CreateLineTokenizer` を +呼び出す必要があります。 + +### サンプルコードのトークン化 + +トークナイザをもっと長いサンプルコードやファイル全体に対して実行する場合、 +サンプル入力を `string` のコレクションとして読み取る必要があります: +*) +let lines = """ + // Hello world + let hello() = + printfn "Hello world!" """.Split('\r','\n') +(** +複数行の入力値をトークン化する場合も、現在の状態を保持するような +再帰関数が必要になります。 +以下の関数はソースコード行を文字列のリストとして受け取ります +(また、行番号および現在の状態も受け取ります)。 +各行に対して新しいトークナイザを作成して、 +直前の行における **最後** の状態を使って `tokenizeLine` を呼び出します: +*) +/// 複数行のコードに対してトークンの名前を表示します +let rec tokenizeLines state count lines = + match lines with + | line::lines -> + // トークナイザを作成して1行をトークン化 + printfn "\nLine %d" count + let tokenizer = sourceTok.CreateLineTokenizer(line) + let state = tokenizeLine tokenizer state + // 新しい状態を使って残りをトークン化 + tokenizeLines state (count+1) lines + | [] -> () +(** +ここでは単に(先ほど定義した) `tokenizeLine` を呼び出して、 +各行にあるすべてのトークンの名前を表示しています。 +この関数は先と同じく、初期状態の値 `0L` と、1行目を表す `1` を +指定して呼び出すことができます: +*) +lines +|> List.ofSeq +|> tokenizeLines FSharpTokenizerLexState.Initial 1 +(** +重要ではない部分(各行の先頭にある空白文字や、1行目のように空白文字しかない行) +を除けば、このコードを実行すると以下のような出力になります: + + [lang=text] + Line 1 + LINE_COMMENT LINE_COMMENT (...) LINE_COMMENT + Line 2 + LET WHITESPACE IDENT LPAREN RPAREN WHITESPACE EQUALS + Line 3 + IDENT WHITESPACE STRING_TEXT (...) STRING_TEXT STRING + +注目すべきは、単一行コメントや文字列に対して、 +トークナイザが複数回(大まかにいって単語単位で) `LINE_COMMENT` や +`STRING_TEXT` を返しているところです。 +したがって、コメントや文字列全体をテキストとして取得したい場合には +それぞれのトークンを連結する必要があります。 +*) \ No newline at end of file diff --git a/docs/fcs/ja/untypedtree.fsx b/docs/fcs/ja/untypedtree.fsx new file mode 100644 index 00000000000..6504431959f --- /dev/null +++ b/docs/fcs/ja/untypedtree.fsx @@ -0,0 +1,277 @@ +(*** hide ***) +#I "../../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +コンパイラサービス:型無し構文木の処理 +====================================== + +このチュートリアルではF#コードに対する型無し抽象構文木 +(untyped abstract syntax tree: untyped AST) +を取得する方法、および木全体を走査する方法を紹介します。 +この処理を行うことによって、コードフォーマットツールや +基本的なリファクタリングツール、コードナビゲーションツールなどを作成できます。 +型無し構文木にはコードの構造に関する情報が含まれていますが、 +型情報が含まれていないだけでなく、後で型チェッカーを通すまでは +解決されないような曖昧さも残されています。 +また、 [エディタサービス](editor.html) として提供されているAPIと +型無しASTの情報を組み合わせることもできます。 + +> **注釈:** 以下で使用しているAPIは試験的なもので、将来的に変更される場合があります。 + つまりFSharp.Compiler.Service.dll には既存のものと重複する機能が多数あるため、 + 将来的にはもっときちんとした形に変更されます。 + そのため、これらのサービスを使用するAPIには破壊的変更が加えられる可能性があります。 + + +型無しASTの取得 +--------------- + + +型無しASTにアクセスするには、 `FSharpChecker` のインスタンスを作成します。 +これは型チェックおよびパース用のコンテキストを表す型で、、 +スタンドアロンのF#スクリプトファイル(たとえばVisual Studioで開いたファイル)、 +あるいは複数ファイルで構成されたロード済みのプロジェクトファイルの +いずれかと結びつきます。 +このインスタンスを作成すると、型チェックの最初のステップである +「型無しパース」を実行できます。 +次のフェーズは「型有りパース」で、これは [エディタサービス](editor.html) で +使用されるものです。 + +インタラクティブチェッカーを使用するには、 +`FSharp.Compiler.Service.dll` への参照を追加した後、 +`CodeAnalysis` 名前空間をオープンします: +*) +#r "FSharp.Compiler.Service.dll" +open System +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text +(** + +### 型無しパースの実行 + +型無しパース処理は(それなりの時間がかかる型チェック処理と比較すると) +かなり高速なため、同期的に実行できます。 +まず `FSharpChecker` を作成します。 + +*) +// インタラクティブチェッカーのインスタンスを作成 +let checker = FSharpChecker.Create() +(** + +ASTを取得するために、ファイル名とソースコードを受け取る関数を用意します +(ファイル名は位置情報のためだけに使用されるもので、存在しなくても構いません)。 +まず、コンテキストを表す「インタラクティブチェッカーオプション」を +用意する必要があります。 +単純な処理に対しては、 `GetCheckOptionsFromScriptRoot` を使えば +スクリプトファイルのコンテキストを推測させることができます。 +そして `UntypedParse` メソッドを呼び出した後、 +`ParseTree` プロパティの値を返します: + +*) +/// 特定の入力に対する型無し構文木を取得する +let getUntypedTree (file, input) = + // 1つのスクリプトファイルから推測される「プロジェクト」用の + // コンパイラオプションを取得する + let projOptions, errors = + checker.GetProjectOptionsFromScript(file, SourceText.ofString input) + |> Async.RunSynchronously + + let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) + + // コンパイラの第1フェーズを実行する + let untypedRes = + checker.ParseFile(file, SourceText.ofString input, parsingOptions) + |> Async.RunSynchronously + + match untypedRes.ParseTree with + | Some tree -> tree + | None -> failwith "パース中に何らかの問題が発生しました!" + +(** +`FSharpChecker` の詳細については +[ APIドキュメント](../reference/microsoft-fsharp-compiler-sourcecodeservices-FSharpChecker.html) +の他に、F# ソースコードのインラインコメントも参考になるでしょう +( [`service.fsi` のソースコードを参照](https://github.com/fsharp/fsharp/blob/fsharp_31/src/fsharp/service/service.fsi) )。 + +ASTの走査 +--------- + +抽象構文木は(式やパターン、宣言など)それぞれ異なる文法的要素を表現する、 +多数の判別共用体として定義されています。 +ASTを理解するには +[`ast.fs`内にあるソースコード](https://github.com/fsharp/fsharp/blob/master/src/fsharp/ast.fs#L464) +の定義を確認する方法が一番よいでしょう。 + +ASTに関連する要素は以下の名前空間に含まれています: +*) +open FSharp.Compiler.Syntax +(** + +ASTを処理する場合、異なる文法的要素に対するパターンマッチを行うような +相互再帰関数を多数用意することになります。 +サポートすべき要素は非常に多種多様です。 +たとえばトップレベル要素としてはモジュールや名前空間の宣言、 +モジュール内における(letバインディングや型などの)宣言などがあります。 +モジュール内のlet宣言には式が含まれ、さらにこの式に +パターンが含まれていることもあります。 + +### パターンと式を走査する + +まずは式とパターンを走査する関数から始めます。 +この関数は要素を走査しつつ、要素に関する情報を画面に表示します。 +パターンの場合、入力は `SynPat` 型であり、この型には `Wild` ( `_` パターンを表す)や +`Named` ( ` という名前` のパターン)、 +`LongIdent` ( `Foo.Bar` 形式の名前)など、多数のケースがあります。 +なお、基本的にパース後のパターンは元のソースコードの見た目よりも複雑になります +(具体的には `Named` がかなり多数現れます): +*) +/// パターンの走査 +/// これは let = あるいは 'match' 式に対する例です +let rec visitPattern = function + | SynPat.Wild(_) -> + printfn " .. アンダースコアパターン" + | SynPat.Named(pat, name, _, _, _) -> + visitPattern pat + printfn " .. 名前 '%s' のパターン" name.idText + | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> + let names = String.concat "." [ for i in ident -> i.idText ] + printfn " .. 識別子: %s" names + | pat -> printfn " .. その他のパターン: %A" pat +(** +この関数は (`bar という名前の (foo, _)` のような、 +ネストされたパターンに対応するために) 再帰関数になっていますが、 +以降で定義するいずれの関数も呼び出しません +(パターンはその他の文法的な要素を含むことができないからです)。 + +次の関数は式全体を走査するものです。 +これは処理の大部分が行われる関数で、 +20以上のケースをカバーすることになるでしょう +( `SynExpr` と入力するとその他のオプションが確認できます)。 +以下のコードでは `if .. then ..` と `let .. = ...` という式を +処理する方法だけを紹介しています: +*) +/// 式を走査する。 +/// 式に2つあるいは3つの部分式が含まれていた場合('else'の分岐がない場合は2つ)、 +/// let式にはパターンおよび2つの部分式が含まれる +let rec visitExpression = function + | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> + // すべての部分式を走査 + printfn "条件部:" + visitExpression cond + visitExpression trueBranch + falseBranchOpt |> Option.iter visitExpression + + | SynExpr.LetOrUse(_, _, bindings, body, _) -> + // バインディングを走査 + // ('let .. = .. and .. = .. in ...' に対しては複数回走査されることがある) + printfn "以下のバインディングを含むLetOrUse:" + for binding in bindings do + let (SynBinding(access, kind, inlin, mutabl, attrs, xmlDoc, + data, pat, retInfo, init, m, sp)) = binding + visitPattern pat + visitExpression init + // 本体の式を走査 + printfn "本体は以下:" + visitExpression body + | expr -> printfn " - サポート対象外の式: %A" expr +(** +`visitExpression` 関数はモジュール内のすべてのトップレベル宣言を走査するような +関数から呼ばれることになります。 +今回のチュートリアルでは型やメンバーを無視していますが、 +これらを走査する場合も `visitExpression` を呼び出すことになるでしょう。 + +### 宣言を走査する + +既に説明したように、1つのファイルに対するASTには多数のモジュールや +名前空間の宣言が(トップレベルノードとして)含まれ、 +モジュール内にも(letバインディングや型の)宣言が、 +名前空間にも(こちらは単に型だけの)宣言が含まれます。 +以下の関数はそれぞれの宣言を走査します。 +ただし今回は型やネストされたモジュール、その他の要素については無視して、 +トップレベルの(値および関数に対する) `let` バインディングだけを対象にしています: +*) +/// モジュール内の宣言リストを走査する。 +/// モジュール内のトップレベルに記述できるすべての要素 +/// (letバインディングやネストされたモジュール、型の宣言など)が対象になる。 +let visitDeclarations decls = + for declaration in decls do + match declaration with + | SynModuleDecl.Let(isRec, bindings, range) -> + // 宣言としてのletバインディングは + // (visitExpressionで処理したような)式としてのletバインディングと + // 似ているが、本体を持たない + for binding in bindings do + let (SynBinding(access, kind, inlin, mutabl, attrs, xmlDoc, + data, pat, retInfo, body, m, sp)) = binding + visitPattern pat + visitExpression body + | _ -> printfn " - サポート対象外の宣言: %A" declaration +(** +`visitDeclarations` 関数はモジュールや名前空間の宣言のシーケンスを走査する +関数から呼ばれることになります。 +このシーケンスはたとえば複数の `namespace Foo` 宣言を含むようなファイルに対応します: +*) +/// すべてのモジュールや名前空間の宣言を走査する +/// (基本的には 'module Foo =' または 'namespace Foo.Bar' というコード) +/// なおファイル中で明示的に定義されていない場合であっても +/// 暗黙的にモジュールまたは名前空間の宣言が存在することに注意。 +let visitModulesAndNamespaces modulesOrNss = + for moduleOrNs in modulesOrNss do + let (SynModuleOrNamespace(lid, isRec, isMod, decls, xml, attrs, _, m)) = moduleOrNs + printfn "名前空間またはモジュール: %A" lid + visitDeclarations decls +(** +以上でASTの要素を(宣言から始まって式やパターンに至るまで)走査するための +関数がそろったので、サンプル入力からASTを取得した後、 +上記の関数を実行することができるようになりました。 + +すべてを組み合わせる +-------------------- + +既に説明したように、 `getUntypedTree` 関数では `FSharpChecker` を使って +ASTに対する第1フェーズ(パース)を行ってツリーを返しています。 +この関数にはF#のソースコードとともに、ファイルのパスを指定する必要があります。 +(単に位置情報として利用されるだけなので) +指定先のパスにファイルが存在している必要はなく、 +UnixとWindowsどちらの形式でも指定できます: +*) +// コンパイラサービスへのサンプル入力 +let input = """ + let foo() = + let msg = "Hello world" + if true then + printfn "%s" msg """ +// Unix形式のファイル名 +let file = "/home/user/Test.fsx" + +// サンプルF#コードに対するASTを取得 +let tree = getUntypedTree(file, input) +(** +このコードをF# Interactiveで実行した場合、コンソールに `tree;;` と入力すると、 +データ構造に対する文字列表現が表示されることが確認できます。 +ツリーには大量の情報が含まれているため、あまり読みやすいものではありませんが、 +木が動作する様子を想像することはできるでしょう。 + +`tree` の返値はやはり判別共用体で、2つのケースに分かれます。 +1つはF#のシグネチャファイル( `*.fsi` )を表す `ParsedInput.SigFile` で、 +もう1つは通常のソースコード( `*.fsx` または `*.fs` )を表す +`ParsedInput.ImplFile` です。 +上記の手順で作成した関数に渡すことができるモジュールや名前空間のシーケンスは +実装ファイルに含まれています: +*) +// 実装ファイルの詳細をチェックする +match tree with +| ParsedInput.ImplFile(implFile) -> + // 宣言を展開してそれぞれを走査する + let (ParsedImplFileInput(fn, script, name, _, _, modules, _)) = implFile + visitModulesAndNamespaces modules +| _ -> failwith "F# インターフェイスファイル (*.fsi) は未サポートです。" +(** +まとめ +------ +このチュートリアルでは型無し抽象構文木に対する基本的な走査方法を紹介しました。 +このトピックは包括的なものであるため、1つの記事ですべてを説明することは不可能です。 +さらに深く理解するためには、型無しASTを活用するツールのよい例として +[Fantomas project](https://github.com/dungpa/fantomas) を参考にするとよいでしょう。 +実際には今回参照したような情報と、次のチュートリアルで説明する +[エディタサービス](editor.html) から得られる情報とを +組み合わせて利用することになるでしょう。 +*) diff --git a/docs/fcs/project.fsx b/docs/fcs/project.fsx new file mode 100644 index 00000000000..2c01f7f3379 --- /dev/null +++ b/docs/fcs/project.fsx @@ -0,0 +1,310 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Project Analysis +================================== + +This tutorial demonstrates how to can analyze a whole project using services provided by the F# compiler. + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. + +*) + + +(** + +Getting whole-project results +----------------------------- + +As in the [previous tutorial (using untyped AST)](untypedtree.html), we start by referencing +`FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance +of `InteractiveChecker`: + +*) +// Reference F# compiler API +#r "FSharp.Compiler.Service.dll" + +open System +open System.Collections.Generic +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text + +// Create an interactive checker instance +let checker = FSharpChecker.Create() + +(** +Here are our sample inputs: +*) + +module Inputs = + open System.IO + + let base1 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(base1, ".fs") + let base2 = Path.GetTempFileName() + let fileName2 = Path.ChangeExtension(base2, ".fs") + let dllName = Path.ChangeExtension(base2, ".dll") + let projFileName = Path.ChangeExtension(base2, ".fsproj") + let fileSource1 = """ +module M + +type C() = + member x.P = 1 + +let xxx = 3 + 4 +let fff () = xxx + xxx + """ + File.WriteAllText(fileName1, fileSource1) + + let fileSource2 = """ +module N + +open M + +type D1() = + member x.SomeProperty = M.xxx + +type D2() = + member x.SomeProperty = M.fff() + D1().P + +// Generate a warning +let y2 = match 1 with 1 -> M.xxx + """ + File.WriteAllText(fileName2, fileSource2) + + +(** +We use `GetProjectOptionsFromCommandLineArgs` to treat two files as a project: +*) + +let projectOptions = + let sysLib nm = + if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then + // file references only valid on Windows + System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + + @"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" + nm + ".dll" + else + let sysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + let (++) a b = System.IO.Path.Combine(a,b) + sysDir ++ nm + ".dll" + + let fsCore4300() = + if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then + // file references only valid on Windows + System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + + @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll" + else + sysLib "FSharp.Core" + + checker.GetProjectOptionsFromCommandLineArgs + (Inputs.projFileName, + [| yield "--simpleresolution" + yield "--noframework" + yield "--debug:full" + yield "--define:DEBUG" + yield "--optimize-" + yield "--out:" + Inputs.dllName + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + yield Inputs.fileName1 + yield Inputs.fileName2 + let references = + [ sysLib "mscorlib" + sysLib "System" + sysLib "System.Core" + fsCore4300() ] + for r in references do + yield "-r:" + r |]) + +(** +Now check the entire project (using the files saved on disk): +*) + +let wholeProjectResults = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously + +(** +Now look at the errors and warnings: +*) +wholeProjectResults.Diagnostics.Length // 1 +wholeProjectResults.Diagnostics.[0].Message.Contains("Incomplete pattern matches on this expression") // yes it does + +wholeProjectResults.Diagnostics.[0].StartLine // 13 +wholeProjectResults.Diagnostics.[0].EndLine // 13 +wholeProjectResults.Diagnostics.[0].StartColumn // 15 +wholeProjectResults.Diagnostics.[0].EndColumn // 16 + +(** +Now look at the inferred signature for the project: +*) +[ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] // ["N"; "M"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] // ["D1"; "D2"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[1].NestedEntities -> x.DisplayName ] // ["C"] +[ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] // ["y"; "y2"] + +(** +You can also get all symbols in the project: +*) +let rec allSymbolsInEntities (entities: IList) = + [ for e in entities do + yield (e :> FSharpSymbol) + for x in e.MembersFunctionsAndValues do + yield (x :> FSharpSymbol) + for x in e.UnionCases do + yield (x :> FSharpSymbol) + for x in e.FSharpFields do + yield (x :> FSharpSymbol) + yield! allSymbolsInEntities e.NestedEntities ] + +let allSymbols = allSymbolsInEntities wholeProjectResults.AssemblySignature.Entities +(** +After checking the whole project, you can access the background results for individual files +in the project. This will be fast and will not involve any additional checking. +*) + +let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Inputs.fileName1, projectOptions) + |> Async.RunSynchronously + + +(** +You can now resolve symbols in each file: +*) + +let xSymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) + +let xSymbolUse = xSymbolUseOpt.Value + +let xSymbol = xSymbolUse.Symbol + +(** +You can find out more about a symbol by doing type checks on various symbol kinds: +*) + +let xSymbolAsValue = + match xSymbol with + | :? FSharpMemberOrFunctionOrValue as xSymbolAsVal -> xSymbolAsVal + | _ -> failwith "we expected this to be a member, function or value" + + +(** +For each symbol, you can look up the references to that symbol: +*) +let usesOfXSymbol = + wholeProjectResults.GetUsesOfSymbol(xSymbol) + +(** +You can iterate all the defined symbols in the inferred signature and find where they are used: +*) +let allUsesOfAllSignatureSymbols = + [ for s in allSymbols do + let uses = wholeProjectResults.GetUsesOfSymbol(s) + yield s.ToString(), uses ] + +(** +You can also look at all the symbols uses in the whole project (including uses of symbols with local scope) +*) +let allUsesOfAllSymbols = + wholeProjectResults.GetAllUsesOfAllSymbols() + +(** +You can also request checks of updated versions of files within the project (note that the other files +in the project are still read from disk, unless you are using the [FileSystem API](filesystem.html)): + +*) + +let parseResults1, checkAnswer1 = + checker.ParseAndCheckFileInProject(Inputs.fileName1, 0, SourceText.ofString Inputs.fileSource1, projectOptions) + |> Async.RunSynchronously + +let checkResults1 = + match checkAnswer1 with + | FSharpCheckFileAnswer.Succeeded x -> x + | _ -> failwith "unexpected aborted" + +let parseResults2, checkAnswer2 = + checker.ParseAndCheckFileInProject(Inputs.fileName2, 0, SourceText.ofString Inputs.fileSource2, projectOptions) + |> Async.RunSynchronously + +let checkResults2 = + match checkAnswer2 with + | FSharpCheckFileAnswer.Succeeded x -> x + | _ -> failwith "unexpected aborted" + +(** +Again, you can resolve symbols and ask for references: +*) + +let xSymbolUse2Opt = + checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) + +let xSymbolUse2 = xSymbolUse2Opt.Value + +let xSymbol2 = xSymbolUse2.Symbol + +let usesOfXSymbol2 = + wholeProjectResults.GetUsesOfSymbol(xSymbol2) + +(** +Or ask for all the symbols uses in the file (including uses of symbols with local scope) +*) +let allUsesOfAllSymbolsInFile1 = + checkResults1.GetAllUsesOfAllSymbolsInFile() + +(** +Or ask for all the uses of one symbol in one file: +*) +let allUsesOfXSymbolInFile1 = + checkResults1.GetUsesOfSymbolInFile(xSymbol2) + +let allUsesOfXSymbolInFile2 = + checkResults2.GetUsesOfSymbolInFile(xSymbol2) + +(** + +Analyzing multiple projects +----------------------------- + +If you have multiple F# projects to analyze which include references from some projects to others, +then the simplest way to do this is to build the projects and specify the cross-project references using +a `-r:path-to-output-of-project.dll` argument in the ProjectOptions. However, this requires the build +of each project to succeed, producing the DLL file on disk which can be referred to. + +In some situations, e.g. in an IDE, you may wish to allow references to other F# projects prior to successful compilation to +a DLL. To do this, fill in the ProjectReferences entry in ProjectOptions, which recursively specifies the project +options for dependent projects. Each project reference still needs a corresponding `-r:path-to-output-of-project.dll` +command line argument in ProjectOptions, along with an entry in ProjectReferences. +The first element of each tuple in the ProjectReferences entry should be the DLL name, i.e. `path-to-output-of-project.dll`. +This should be the same as the text used in the `-r` project reference. + +When a project reference is used, the analysis will make use of the results of incremental +analysis of the referenced F# project from source files, without requiring the compilation of these files to DLLs. + +To efficiently analyze a set of F# projects which include cross-references, you should populate the ProjectReferences +correctly and then analyze each project in turn. + +*) + +(** + +> **NOTE:** Project references are disabled if the assembly being referred to contains type provider components - + specifying the project reference will have no effect beyond forcing the analysis of the project, and the DLL will + still be required on disk. + +*) + +(** +Summary +------- + +As you have seen, the `ParseAndCheckProject` lets you access results of project-wide analysis +such as symbol references. To learn more about working with symbols, see [Symbols](symbols.html). + +Using the FSharpChecker component in multi-project, incremental and interactive editing situations may involve +knowledge of the [FSharpChecker operations queue](queue.html) and the [FSharpChecker caches](caches.html). + +*) diff --git a/docs/fcs/queue.fsx b/docs/fcs/queue.fsx new file mode 100644 index 00000000000..bc9e8595b5d --- /dev/null +++ b/docs/fcs/queue.fsx @@ -0,0 +1,79 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Notes on the FSharpChecker operations queue +================================================= + +This is a design note on the FSharpChecker component and its operations queue. See also the notes on the [FSharpChecker caches](caches.html) + +FSharpChecker maintains an operations queue. Items from the FSharpChecker operations queue are processed +sequentially and in order. + +This means the FCS API has three kinds of operations: + +* "Runs on caller thread (runs on caller thread)" - Some requests from FSharp.Editor are + serviced concurrently without using the queue at all. Everything without an Async return type + is in this category. + +* "Queued-at-high-priority (runs on reactor thread)" - These are requests made via the FCS API + (e.g. from FSharp.Editor) and anything with "Async" return type is in this category. The + originating calls are not typically on the UI thread and are associated with active actions + by the user (editing a file etc.). + + These correspond to the calls to EnqueueAndAwaitOpAsync in [service.fs](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/service/service.fs). + For example, calling `ParseAndCheckProject` enqueues a `ParseAndCheckProjectImpl` operation. The time taken for the + operation will depend on how much work is required to bring the project analysis up-to-date. + The length of the operation will vary - many will be very fast - but they won't + be processed until other operations already in the queue are complete. + +* "Queued and interleaved at lower priority (runs on reactor thread)" - This is reserved + for a "background" job (CheckProjectInBackground) used for to prepare the project builder + state of the current project being worked on. The "background" work is intended to be + divided into little chunks so it can always be interrupted in order to service the higher-priority work. + + This operation runs when the queue is empty. When the operations queue has been empty for 1 second, + this work is run in small incremental fragments. The overall work may get cancelled if replaced + by an alternative project build. This work is cooperatively + time-sliced to be approximately <50ms, (see `maxTimeShareMilliseconds` in + IncrementalBuild.fs). The project to be checked in the background is set implicitly + by calls to ``CheckFileInProject`` and ``ParseAndCheckFileInProject``. + To disable implicit background checking completely, set ``checker.ImplicitlyStartBackgroundWork`` to false. + To change the time before background work starts, set ``checker.PauseBeforeBackgroundWork`` to the required + number of milliseconds. + +Some tools throw a lot of "Queued-at-high-priority" work at the FSharpChecker operations queue. +If you are writing such a component, consider running your project against a debug build +of FSharp.Compiler.Service.dll to see the Trace.WriteInformation messages indicating the length of the +operations queue and the time to process requests. + +For those writing interactive editors which use FCS, you +should be cautious about long running "Queued-at-high-priority" operations - these +will run in preference to other similar operations and must be both asynchronous +and cancelled if the results will no longer be needed. +For example, be careful about requesting the check of an entire project +on operations like "Highlight Symbol" or "Find Unused Declarations" +(which run automatically when the user opens a file or moves the cursor). +as opposed to operations like "Find All References" (which a user explicitly triggers). +Project checking can cause long and contention on the FSharpChecker operations queue. You *must* +cancel such operations if the results will be out-of-date, in order for your editing tools to be performant. + +Requests can be cancelled via the cancellation token of the async operation. (Some requests also +include additional callbacks which can be used to indicate a cancellation condition). +If the operation has not yet started it will remain in the queue and be discarded when it reaches the front. + +The long term intent of FCS is to eventually remove the reactor thread and the operations queue. However the queue +has several operational impacts we need to be mindful of + +1. It acts as a brake on the overall resource usage (if 1000 requests get made from FSharp.Editor they are serviced one at a time, and the work is not generally repeated as it get cached). + +2. It potentially acts as a data-lock on the project builder compilation state. + +3. It runs the low-priority project build. + +Summary +------- + +In this design note, you learned that the FSharpChecker component keeps an operations queue. When using FSharpChecker +in highly interactive situations, you should carefully consider the characteristics of the operations you are +enqueueing. +*) diff --git a/fcs/docsrc/content/react.fsx b/docs/fcs/react.fsx similarity index 98% rename from fcs/docsrc/content/react.fsx rename to docs/fcs/react.fsx index be108b92adb..07c9195e0b5 100644 --- a/fcs/docsrc/content/react.fsx +++ b/docs/fcs/react.fsx @@ -1,5 +1,5 @@ (*** hide ***) -#I "../../../artifacts/bin/fcs/net461" +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" (** Compiler Services: Reacting to Changes ============================================ diff --git a/docs/fcs/symbols.fsx b/docs/fcs/symbols.fsx new file mode 100644 index 00000000000..c38e23b9943 --- /dev/null +++ b/docs/fcs/symbols.fsx @@ -0,0 +1,225 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Working with symbols +============================================ + +This tutorial demonstrates how to work with symbols provided by the F# compiler. See also [project wide analysis](project.html) +for information on symbol references. + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. + +As usual we start by referencing `FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance +of `FSharpChecker`: + +*) +// Reference F# compiler API +#r "FSharp.Compiler.Service.dll" + +open System +open System.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text + +// Create an interactive checker instance +let checker = FSharpChecker.Create() + +(** + +We now perform type checking on the specified input: + +*) + +let parseAndTypeCheckSingleFile (file, input) = + // Get context representing a stand-alone (script) file + let projOptions, errors = + checker.GetProjectOptionsFromScript(file, input) + |> Async.RunSynchronously + + let parseFileResults, checkFileResults = + checker.ParseAndCheckFileInProject(file, 0, input, projOptions) + |> Async.RunSynchronously + + // Wait until type checking succeeds (or 100 attempts) + match checkFileResults with + | FSharpCheckFileAnswer.Succeeded(res) -> parseFileResults, res + | res -> failwithf "Parsing did not finish... (%A)" res + +let file = "/home/user/Test.fsx" + +(** +## Getting resolved signature information about the file + +After type checking a file, you can access the inferred signature of a project up to and including the +checking of the given file through the `PartialAssemblySignature` property of the `TypeCheckResults`. + +The full signature information is available for modules, types, attributes, members, values, functions, +union cases, record types, units of measure and other F# language constructs. + +The typed expression trees are also available, see [typed tree tutorial](typedtree.html). + +*) + +let input2 = + """ +[] +let foo(x, y) = + let msg = String.Concat("Hello"," ","world") + if true then + printfn "x = %d, y = %d" x y + printfn "%s" msg + +type C() = + member x.P = 1 + """ +let parseFileResults, checkFileResults = + parseAndTypeCheckSingleFile(file, SourceText.ofString input2) + +(** +Now get the partial assembly signature for the code: +*) +let partialAssemblySignature = checkFileResults.PartialAssemblySignature + +partialAssemblySignature.Entities.Count = 1 // one entity + + +(** +Now get the entity that corresponds to the module containing the code: +*) +let moduleEntity = partialAssemblySignature.Entities.[0] + +moduleEntity.DisplayName = "Test" + +(** +Now get the entity that corresponds to the type definition in the code: +*) +let classEntity = moduleEntity.NestedEntities.[0] + +(** +Now get the value that corresponds to the function defined in the code: +*) +let fnVal = moduleEntity.MembersFunctionsAndValues.[0] + +(** +Now look around at the properties describing the function value. All of the following evaluate to `true`: +*) +fnVal.Attributes.Count = 1 +fnVal.CurriedParameterGroups.Count // 1 +fnVal.CurriedParameterGroups.[0].Count // 2 +fnVal.CurriedParameterGroups.[0].[0].Name // "x" +fnVal.CurriedParameterGroups.[0].[1].Name // "y" +fnVal.DeclarationLocation.StartLine // 3 +fnVal.DisplayName // "foo" +fnVal.DeclaringEntity.Value.DisplayName // "Test" +fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1 +fnVal.GenericParameters.Count // 0 +fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline +fnVal.IsActivePattern // false +fnVal.IsCompilerGenerated // false +fnVal.IsDispatchSlot // false +fnVal.IsExtensionMember // false +fnVal.IsPropertyGetterMethod // false +fnVal.IsImplicitConstructor // false +fnVal.IsInstanceMember // false +fnVal.IsMember // false +fnVal.IsModuleValueOrMember // true +fnVal.IsMutable // false +fnVal.IsPropertySetterMethod // false +fnVal.IsTypeFunction // false + +(** +Now look at the type of the function if used as a first class value. (Aside: the `CurriedParameterGroups` property contains +more information like the names of the arguments.) +*) +fnVal.FullType // int * int -> unit +fnVal.FullType.IsFunctionType // int * int -> unit +fnVal.FullType.GenericArguments.[0] // int * int +fnVal.FullType.GenericArguments.[0].IsTupleType // int * int +let argTy1 = fnVal.FullType.GenericArguments.[0].GenericArguments.[0] + +argTy1.TypeDefinition.DisplayName // int + +(** +OK, so we got an object representation of the type `int * int -> unit`, and we have seen the first 'int'. We can find out more about the +type 'int' as follows, determining that it is a named type, which is an F# type abbreviation, `type int = int32`: +*) + +argTy1.HasTypeDefinition +argTy1.TypeDefinition.IsFSharpAbbreviation // "int" + +(** +We can now look at the right-hand-side of the type abbreviation, which is the type `int32`: +*) + +let argTy1b = argTy1.TypeDefinition.AbbreviatedType +argTy1b.TypeDefinition.Namespace // Some "Microsoft.FSharp.Core" +argTy1b.TypeDefinition.CompiledName // "int32" + +(** +Again we can now look through the type abbreviation `type int32 = System.Int32` to get the +full information about the type: +*) +let argTy1c = argTy1b.TypeDefinition.AbbreviatedType +argTy1c.TypeDefinition.Namespace // Some "SystemCore" +argTy1c.TypeDefinition.CompiledName // "Int32" + +(** +The type checking results for a file also contain information extracted from the project (or script) options +used in the compilation, called the `ProjectContext`: +*) +let projectContext = checkFileResults.ProjectContext + +for assembly in projectContext.GetReferencedAssemblies() do + match assembly.FileName with + | None -> printfn "compilation referenced an assembly without a file" + | Some s -> printfn "compilation references assembly '%s'" s + + +(** +**Notes:** + + - If incomplete code is present, some or all of the attributes may not be quite as expected. + - If some assembly references are missing (which is actually very, very common), then 'IsUnresolved' may + be true on values, members and/or entities related to external assemblies. You should be sure to make your + code robust against IsUnresolved exceptions. + +*) + +(** + +## Getting symbolic information about whole projects + +To check whole projects, create a checker, then call `parseAndCheckScript`. In this case, we just check +the project for a single script. By specifying a different "projOptions" you can create +a specification of a larger project. +*) +let parseAndCheckScript (file, input) = + let projOptions, errors = + checker.GetProjectOptionsFromScript(file, input) + |> Async.RunSynchronously + + checker.ParseAndCheckProject(projOptions) |> Async.RunSynchronously + +(** +Now do it for a particular input: +*) + +let tmpFile = Path.ChangeExtension(System.IO.Path.GetTempFileName() , "fs") +File.WriteAllText(tmpFile, input2) + +let projectResults = parseAndCheckScript(tmpFile, SourceText.ofString input2) + + +(** +Now look at the results: +*) + +let assemblySig = projectResults.AssemblySignature + +assemblySig.Entities.Count = 1 // one entity +assemblySig.Entities.[0].Namespace // one entity +assemblySig.Entities.[0].DisplayName // "Tmp28D0" +assemblySig.Entities.[0].MembersFunctionsAndValues.Count // 1 +assemblySig.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "foo" + diff --git a/docs/fcs/tokenizer.fsx b/docs/fcs/tokenizer.fsx new file mode 100644 index 00000000000..ba584446170 --- /dev/null +++ b/docs/fcs/tokenizer.fsx @@ -0,0 +1,131 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Using the F# tokenizer +========================================= + +This tutorial demonstrates how to call the F# language tokenizer. Given F# +source code, the tokenizer generates a list of source code lines that contain +information about tokens on each line. For each token, you can get the type +of the token, exact location as well as color kind of the token (keyword, +identifier, number, operator, etc.). + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published + + +Creating the tokenizer +--------------------- + +To use the tokenizer, reference `FSharp.Compiler.Service.dll` and open the +`FSharp.Compiler.Tokenization` namespace: +*) +#r "FSharp.Compiler.Service.dll" +open FSharp.Compiler.Tokenization +(** +Now you can create an instance of `FSharpSourceTokenizer`. The class takes two +arguments - the first is the list of defined symbols and the second is the +file name of the source code. The defined symbols are required because the +tokenizer handles `#if` directives. The file name is required only to specify +locations of the source code (and it does not have to exist): +*) +let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") +(** +Using the `sourceTok` object, we can now (repeatedly) tokenize lines of +F# source code. + +Tokenizing F# code +------------------ + +The tokenizer operates on individual lines rather than on the entire source +file. After getting a token, the tokenizer also returns new state (as `int64` value). +This can be used to tokenize F# code more efficiently. When source code changes, +you do not need to re-tokenize the entire file - only the parts that have changed. + +### Tokenizing single line + +To tokenize a single line, we create a `FSharpLineTokenizer` by calling `CreateLineTokenizer` +on the `FSharpSourceTokenizer` object that we created earlier: +*) +let tokenizer = sourceTok.CreateLineTokenizer("let answer=42") +(** +Now, we can write a simple recursive function that calls `ScanToken` on the `tokenizer` +until it returns `None` (indicating the end of line). When the function succeeds, it +returns `FSharpTokenInfo` object with all the interesting details: +*) +/// Tokenize a single line of F# code +let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = + match tokenizer.ScanToken(state) with + | Some tok, state -> + // Print token name + printf "%s " tok.TokenName + // Tokenize the rest, in the new state + tokenizeLine tokenizer state + | None, state -> state +(** +The function returns the new state, which is needed if you need to tokenize multiple lines +and an earlier line ends with a multi-line comment. As an initial state, we can use `0L`: +*) +tokenizeLine tokenizer FSharpTokenizerLexState.Initial +(** +The result is a sequence of tokens with names LET, WHITESPACE, IDENT, EQUALS and INT32. +There is a number of interesting properties on `FSharpTokenInfo` including: + + - `CharClass` and `ColorClass` return information about the token category that + can be used for colorizing F# code. + - `LeftColumn` and `RightColumn` return the location of the token inside the line. + - `TokenName` is the name of the token (as defined in the F# lexer) + +Note that the tokenizer is stateful - if you want to tokenize single line multiple times, +you need to call `CreateLineTokenizer` again. + +### Tokenizing sample code + +To run the tokenizer on a longer sample code or an entire file, you need to read the +sample input as a collection of `string` values: +*) +let lines = """ + // Hello world + let hello() = + printfn "Hello world!" """.Split('\r','\n') +(** +To tokenize multi-line input, we again need a recursive function that keeps the current +state. The following function takes the lines as a list of strings (together with line number +and the current state). We create a new tokenizer for each line and call `tokenizeLine` +using the state from the *end* of the previous line: +*) +/// Print token names for multiple lines of code +let rec tokenizeLines state count lines = + match lines with + | line::lines -> + // Create tokenizer & tokenize single line + printfn "\nLine %d" count + let tokenizer = sourceTok.CreateLineTokenizer(line) + let state = tokenizeLine tokenizer state + // Tokenize the rest using new state + tokenizeLines state (count+1) lines + | [] -> () +(** +The function simply calls `tokenizeLine` (defined earlier) to print the names of all +the tokens on each line. We can call it on the previous input with `0L` as the initial +state and `1` as the number of the first line: +*) +lines +|> List.ofSeq +|> tokenizeLines FSharpTokenizerLexState.Initial 1 +(** +Ignoring some unimportant details (like whitespace at the beginning of each line and +the first line which is just whitespace), the code generates the following output: + + [lang=text] + Line 1 + LINE_COMMENT LINE_COMMENT (...) LINE_COMMENT + Line 2 + LET WHITESPACE IDENT LPAREN RPAREN WHITESPACE EQUALS + Line 3 + IDENT WHITESPACE STRING_TEXT (...) STRING_TEXT STRING + +It is worth noting that the tokenizer yields multiple `LINE_COMMENT` tokens and multiple +`STRING_TEXT` tokens for each single comment or string (roughly, one for each word), so +if you want to get the entire text of a comment/string, you need to concatenate the +tokens. +*) \ No newline at end of file diff --git a/docs/fcs/typedtree.fsx b/docs/fcs/typedtree.fsx new file mode 100644 index 00000000000..ad392d38776 --- /dev/null +++ b/docs/fcs/typedtree.fsx @@ -0,0 +1,307 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Processing typed expression tree +================================================= + +This tutorial demonstrates how to get the checked, typed expressions tree (TAST) +for F# code and how to walk over the tree. + +This can be used for creating tools such as source code analyzers and refactoring tools. +You can also combine the information with the API available +from [symbols](symbols.html). + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published + + +Getting checked expressions +----------------------- + +To access the type-checked, resolved expressions, you need to create an instance of `InteractiveChecker`. + +To use the interactive checker, reference `FSharp.Compiler.Service.dll` and open the +relevant namespaces: +*) +#r "FSharp.Compiler.Service.dll" +open System +open System.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text +(** + +### Checking code + +We first parse and check some code as in the [symbols](symbols.html) tutorial. +One difference is that we set keepAssemblyContents to true. + +*) +// Create an interactive checker instance +let checker = FSharpChecker.Create(keepAssemblyContents=true) + +let parseAndCheckSingleFile (input) = + let file = Path.ChangeExtension(System.IO.Path.GetTempFileName(), "fsx") + File.WriteAllText(file, input) + // Get context representing a stand-alone (script) file + let projOptions, _errors = + checker.GetProjectOptionsFromScript(file, SourceText.ofString input) + |> Async.RunSynchronously + + checker.ParseAndCheckProject(projOptions) + |> Async.RunSynchronously + +(** +## Getting the expressions + +After type checking a file, you can access the declarations and contents of the assembly, including expressions: + +*) + +let input2 = + """ +module MyLibrary + +open System + +let foo(x, y) = + let msg = String.Concat("Hello", " ", "world") + if msg.Length > 10 then + 10 + else + 20 + +type MyClass() = + member x.MyMethod() = 1 + """ +let checkProjectResults = + parseAndCheckSingleFile(input2) + +checkProjectResults.Diagnostics // should be empty + +(** + +Checked assemblies are made up of a series of checked implementation files. The "file" granularity +matters in F# because initialization actions are triggered at the granularity of files. +In this case there is only one implementation file in the project: + +*) + +let checkedFile = checkProjectResults.AssemblyContents.ImplementationFiles.[0] + +(** + +Checked assemblies are made up of a series of checked implementation files. The "file" granularity +matters in F# because initialization actions are triggered at the granularity of files. +In this case there is only one implementation file in the project: + +*) + +let rec printDecl prefix d = + match d with + | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> + printfn "%sEntity %s was declared and contains %d sub-declarations" prefix e.CompiledName subDecls.Length + for subDecl in subDecls do + printDecl (prefix+" ") subDecl + | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> + printfn "%sMember or value %s was declared" prefix v.CompiledName + | FSharpImplementationFileDeclaration.InitAction(e) -> + printfn "%sA top-level expression was declared" prefix + + +for d in checkedFile.Declarations do + printDecl "" d + +// Entity MyLibrary was declared and contains 4 sub-declarations +// Member or value foo was declared +// Entity MyClass was declared and contains 0 sub-declarations +// Member or value .ctor was declared +// Member or value MyMethod was declared + +(** + +As can be seen, the only declaration in the implementation file is that of the module MyLibrary, which +contains fours sub-declarations. + +> As an aside, one peculiarity here is that the member declarations (e.g. the "MyMethod" member) are returned as part of the containing module entity, not as part of their class. + +> Note that the class constructor is returned as a separate declaration. The class type definition has been "split" into a constructor and the other declarations. + +*) + +let myLibraryEntity, myLibraryDecls = + match checkedFile.Declarations.[0] with + | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> (e, subDecls) + | _ -> failwith "unexpected" + + +(** + +What about the expressions, for example the body of function "foo"? Let's find it: +*) + +let (fooSymbol, fooArgs, fooExpression) = + match myLibraryDecls.[0] with + | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> (v, vs, e) + | _ -> failwith "unexpected" + + +(** Here 'fooSymbol' is a symbol associated with the declaration of 'foo', +'fooArgs' represents the formal arguments to the 'foo' function, and 'fooExpression' +is an expression for the implementation of the 'foo' function. + +Once you have an expression, you can work with it much like an F# quotation. For example, +you can find its declaration range and its type: + +*) + +fooExpression.Type // shows that the return type of the body expression is 'int' +fooExpression.Range // shows the declaration range of the expression implementing 'foo' + +(** + +### Walking over expressions + + +Expressions are analyzed using active patterns, much like F# quotations. +Here is a generic expression visitor: + +*) + +let rec visitExpr f (e:FSharpExpr) = + f e + match e with + | FSharpExprPatterns.AddressOf(lvalueExpr) -> + visitExpr f lvalueExpr + | FSharpExprPatterns.AddressSet(lvalueExpr, rvalueExpr) -> + visitExpr f lvalueExpr; visitExpr f rvalueExpr + | FSharpExprPatterns.Application(funcExpr, typeArgs, argExprs) -> + visitExpr f funcExpr; visitExprs f argExprs + | FSharpExprPatterns.Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) -> + visitObjArg f objExprOpt; visitExprs f argExprs + | FSharpExprPatterns.Coerce(targetType, inpExpr) -> + visitExpr f inpExpr + | FSharpExprPatterns.FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp) -> + visitExpr f startExpr; visitExpr f limitExpr; visitExpr f consumeExpr + | FSharpExprPatterns.ILAsm(asmCode, typeArgs, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.ILFieldGet (objExprOpt, fieldType, fieldName) -> + visitObjArg f objExprOpt + | FSharpExprPatterns.ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) -> + visitObjArg f objExprOpt + | FSharpExprPatterns.IfThenElse (guardExpr, thenExpr, elseExpr) -> + visitExpr f guardExpr; visitExpr f thenExpr; visitExpr f elseExpr + | FSharpExprPatterns.Lambda(lambdaVar, bodyExpr) -> + visitExpr f bodyExpr + | FSharpExprPatterns.Let((bindingVar, bindingExpr), bodyExpr) -> + visitExpr f bindingExpr; visitExpr f bodyExpr + | FSharpExprPatterns.LetRec(recursiveBindings, bodyExpr) -> + List.iter (snd >> visitExpr f) recursiveBindings; visitExpr f bodyExpr + | FSharpExprPatterns.NewArray(arrayType, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.NewDelegate(delegateType, delegateBodyExpr) -> + visitExpr f delegateBodyExpr + | FSharpExprPatterns.NewObject(objType, typeArgs, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.NewRecord(recordType, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.NewAnonRecord(recordType, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.NewTuple(tupleType, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.NewUnionCase(unionType, unionCase, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.Quote(quotedExpr) -> + visitExpr f quotedExpr + | FSharpExprPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> + visitObjArg f objExprOpt + | FSharpExprPatterns.AnonRecordGet(objExpr, recordOrClassType, fieldInfo) -> + visitExpr f objExpr + | FSharpExprPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) -> + visitObjArg f objExprOpt; visitExpr f argExpr + | FSharpExprPatterns.Sequential(firstExpr, secondExpr) -> + visitExpr f firstExpr; visitExpr f secondExpr + | FSharpExprPatterns.TryFinally(bodyExpr, finalizeExpr) -> + visitExpr f bodyExpr; visitExpr f finalizeExpr + | FSharpExprPatterns.TryWith(bodyExpr, _, _, catchVar, catchExpr) -> + visitExpr f bodyExpr; visitExpr f catchExpr + | FSharpExprPatterns.TupleGet(tupleType, tupleElemIndex, tupleExpr) -> + visitExpr f tupleExpr + | FSharpExprPatterns.DecisionTree(decisionExpr, decisionTargets) -> + visitExpr f decisionExpr; List.iter (snd >> visitExpr f) decisionTargets + | FSharpExprPatterns.DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) -> + visitExprs f decisionTargetExprs + | FSharpExprPatterns.TypeLambda(genericParam, bodyExpr) -> + visitExpr f bodyExpr + | FSharpExprPatterns.TypeTest(ty, inpExpr) -> + visitExpr f inpExpr + | FSharpExprPatterns.UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) -> + visitExpr f unionExpr; visitExpr f valueExpr + | FSharpExprPatterns.UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> + visitExpr f unionExpr + | FSharpExprPatterns.UnionCaseTest(unionExpr, unionType, unionCase) -> + visitExpr f unionExpr + | FSharpExprPatterns.UnionCaseTag(unionExpr, unionType) -> + visitExpr f unionExpr + | FSharpExprPatterns.ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) -> + visitExpr f baseCallExpr + List.iter (visitObjMember f) overrides + List.iter (snd >> List.iter (visitObjMember f)) interfaceImplementations + | FSharpExprPatterns.TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) -> + visitExprs f argExprs + | FSharpExprPatterns.ValueSet(valToSet, valueExpr) -> + visitExpr f valueExpr + | FSharpExprPatterns.WhileLoop(guardExpr, bodyExpr) -> + visitExpr f guardExpr; visitExpr f bodyExpr + | FSharpExprPatterns.BaseValue baseType -> () + | FSharpExprPatterns.DefaultValue defaultType -> () + | FSharpExprPatterns.ThisValue thisType -> () + | FSharpExprPatterns.Const(constValueObj, constType) -> () + | FSharpExprPatterns.Value(valueToGet) -> () + | _ -> failwith (sprintf "unrecognized %+A" e) + +and visitExprs f exprs = + List.iter (visitExpr f) exprs + +and visitObjArg f objOpt = + Option.iter (visitExpr f) objOpt + +and visitObjMember f memb = + visitExpr f memb.Body + +(** +Let's use this expresssion walker: + +*) +fooExpression |> visitExpr (fun e -> printfn "Visiting %A" e) + +// Prints: +// +// Visiting Let... +// Visiting Call... +// Visiting Const ("Hello", ...) +// Visiting Const (" ", ...) +// Visiting Const ("world", ...) +// Visiting IfThenElse... +// Visiting Call... +// Visiting Call... +// Visiting Value ... +// Visiting Const ... +// Visiting Const ... +// Visiting Const ... + +(** +Note that + +* The visitExpr function is recursive (for nested expressions). + +* Pattern matching is removed from the tree, into a form called 'decision trees'. + +Summary +------- +In this tutorial, we looked at basic of working with checked declarations and expressions. + +In practice, it is also useful to combine the information here +with some information you can obtain from the [symbols](symbols.html) +tutorial. +*) diff --git a/docs/fcs/untypedtree.fsx b/docs/fcs/untypedtree.fsx new file mode 100644 index 00000000000..4dd5c369a57 --- /dev/null +++ b/docs/fcs/untypedtree.fsx @@ -0,0 +1,246 @@ +(*** hide ***) +#I "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0" +(** +Compiler Services: Processing untyped syntax tree +================================================= + +This tutorial demonstrates how to get the untyped abstract syntax tree (AST) +for F# code and how to walk over the tree. This can be used for creating tools +such as code formatter, basic refactoring or code navigation tools. The untyped +syntax tree contains information about the code structure, but does not contain +types and there are some ambiguities that are resolved only later by the type +checker. You can also combine the untyped AST information with the API available +from [editor services](editor.html). + +> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published + + +Getting the untyped AST +----------------------- + +To access the untyped AST, you need to create an instance of `FSharpChecker`. +This type represents a context for type checking and parsing and corresponds either +to a stand-alone F# script file (e.g. opened in Visual Studio) or to a loaded project +file with multiple files. Once you have an instance of `FSharpChecker`, you can +use it to perform "untyped parse" which is the first step of type-checking. The +second phase is "typed parse" and is used by [editor services](editor.html). + +To use the interactive checker, reference `FSharp.Compiler.Service.dll` and open the +`SourceCodeServices` namespace: +*) +#r "FSharp.Compiler.Service.dll" +open System +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text +(** + +### Performing untyped parse + +The untyped parse operation is very fast (compared to type checking, which can +take notable amount of time) and so we can perform it synchronously. First, we +need to create `FSharpChecker` - the constructor takes an argument that +can be used to notify the checker about file changes (which we ignore). + +*) +// Create an interactive checker instance +let checker = FSharpChecker.Create() +(** + +To get the AST, we define a function that takes file name and the source code +(the file is only used for location information and does not have to exist). +We first need to get "interactive checker options" which represents the context. +For simple tasks, you can use `GetProjectOptionsFromScriptRoot` which infers +the context for a script file. Then we use the `ParseFile` method and +return the `ParseTree` property: + +*) +/// Get untyped tree for a specified input +let getUntypedTree (file, input) = + // Get compiler options for the 'project' implied by a single script file + let projOptions, errors = + checker.GetProjectOptionsFromScript(file, input) + |> Async.RunSynchronously + + let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) + + // Run the first phase (untyped parsing) of the compiler + let parseFileResults = + checker.ParseFile(file, input, parsingOptions) + |> Async.RunSynchronously + + match parseFileResults.ParseTree with + | Some tree -> tree + | None -> failwith "Something went wrong during parsing!" + +(** + +Walking over the AST +-------------------- + +The abstract syntax tree is defined as a number of discriminated unions that represent +different syntactical elements (such as expressions, patterns, declarations etc.). The best +way to understand the AST is to look at the definitions in [`ast.fs` in the source +code](https://github.com/fsharp/fsharp/blob/master/src/fsharp/ast.fs#L464). + +The relevant parts are in the following namespace: +*) +open FSharp.Compiler.Syntax +(** + +When processing the AST, you will typically write a number of mutually recursive functions +that pattern match on the different syntactical elements. There is a number of elements +that need to be supported - the top-level element is module or namespace declaration, +containing declarations inside a module (let bindings, types etc.). A let declaration inside +a module then contains expression, which can contain patterns. + +### Walking over patterns and expressions + +We start by looking at functions that walk over expressions and patterns - as we walk, +we print information about the visited elements. For patterns, the input is of type +`SynPat` and has a number of cases including `Wild` (for `_` pattern), `Named` (for +` as name`) and `LongIdent` (for a `Foo.Bar` name). Note that the parsed pattern +is occasionally more complex than what is in the source code (in particular, `Named` is +used more often): +*) +/// Walk over a pattern - this is for example used in +/// let = or in the 'match' expression +let rec visitPattern = function + | SynPat.Wild(_) -> + printfn " .. underscore pattern" + | SynPat.Named(pat, name, _, _, _) -> + visitPattern pat + printfn " .. named as '%s'" name.idText + | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> + let names = String.concat "." [ for i in ident -> i.idText ] + printfn " .. identifier: %s" names + | pat -> printfn " .. other pattern: %A" pat +(** +The function is recursive (for nested patterns such as `(foo, _) as bar`), but it does not +call any of the functions defined later (because patterns cannot contain other syntactical +elements). + +The next function iterates over expressions - this is where most of the work would be and +there are around 20 cases to cover (type `SynExpr.` and you'll get completion with other +options). In the following, we only show how to handle `if .. then ..` and `let .. = ...`: +*) +/// Walk over an expression - if expression contains two or three +/// sub-expressions (two if the 'else' branch is missing), let expression +/// contains pattern and two sub-expressions +let rec visitExpression e = + match e with + | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> + // Visit all sub-expressions + printfn "Conditional:" + visitExpression cond + visitExpression trueBranch + falseBranchOpt |> Option.iter visitExpression + + | SynExpr.LetOrUse(_, _, bindings, body, _) -> + // Visit bindings (there may be multiple + // for 'let .. = .. and .. = .. in ...' + printfn "LetOrUse with the following bindings:" + for binding in bindings do + let (SynBinding(access, kind, inlin, mutabl, attrs, xmlDoc, + data, pat, retInfo, init, m, sp)) = binding + visitPattern pat + visitExpression init + // Visit the body expression + printfn "And the following body:" + visitExpression body + | expr -> printfn " - not supported expression: %A" expr +(** +The `visitExpression` function will be called from a function that visits all top-level +declarations inside a module. In this tutorial, we ignore types and members, but that would +be another source of calls to `visitExpression`. + +### Walking over declarations + +As mentioned earlier, the AST of a file contains a number of module or namespace declarations +(top-level node) that contain declarations inside a module (let bindings or types) or inside +a namespace (just types). The following functions walks over declarations - we ignore types, +nested modules and all other elements and look only at top-level `let` bindings (values and +functions): +*) +/// Walk over a list of declarations in a module. This is anything +/// that you can write as a top-level inside module (let bindings, +/// nested modules, type declarations etc.) +let visitDeclarations decls = + for declaration in decls do + match declaration with + | SynModuleDecl.Let(isRec, bindings, range) -> + // Let binding as a declaration is similar to let binding + // as an expression (in visitExpression), but has no body + for binding in bindings do + let (SynBinding(access, kind, inlin, mutabl, attrs, xmlDoc, + data, pat, retInfo, body, m, sp)) = binding + visitPattern pat + visitExpression body + | _ -> printfn " - not supported declaration: %A" declaration +(** +The `visitDeclarations` function will be called from a function that walks over a +sequence of module or namespace declarations. This corresponds, for example, to a file +with multiple `namespace Foo` declarations: +*) +/// Walk over all module or namespace declarations +/// (basically 'module Foo =' or 'namespace Foo.Bar') +/// Note that there is one implicitly, even if the file +/// does not explicitly define it.. +let visitModulesAndNamespaces modulesOrNss = + for moduleOrNs in modulesOrNss do + let (SynModuleOrNamespace(lid, isRec, isMod, decls, xml, attrs, _, m)) = moduleOrNs + printfn "Namespace or module: %A" lid + visitDeclarations decls +(** +Now that we have functions that walk over the elements of the AST (starting from declaration, +down to expressions and patterns), we can get AST of a sample input and run the above function. + +Putting things together +----------------------- + +As already discussed, the `getUntypedTree` function uses `FSharpChecker` to run the first +phase (parsing) on the AST and get back the tree. The function requires F# source code together +with location of the file. The location does not have to exist (it is used only for location +information) and it can be in both Unix and Windows formats: +*) +// Sample input for the compiler service +let input = + """ + let foo() = + let msg = "Hello world" + if true then + printfn "%s" msg + """ + +// File name in Unix format +let file = "/home/user/Test.fsx" + +// Get the AST of sample F# code +let tree = getUntypedTree(file, SourceText.ofString input) +(** +When you run the code in F# interactive, you can enter `tree;;` in the interactive console and +see pretty printed representation of the data structure - the tree contains a lot of information, +so this is not particularly readable, but it gives you good idea about how the tree looks. + +The returned `tree` value is again a discriminated union that can be two different cases - one case +is `ParsedInput.SigFile` which represents F# signature file (`*.fsi`) and the other one is +`ParsedInput.ImplFile` representing regular source code (`*.fsx` or `*.fs`). The implementation +file contains a sequence of modules or namespaces that we can pass to the function implemented +in the previous step: +*) +// Extract implementation file details +match tree with +| ParsedInput.ImplFile(implFile) -> + // Extract declarations and walk over them + let (ParsedImplFileInput(fn, script, name, _, _, modules, _)) = implFile + visitModulesAndNamespaces modules +| _ -> failwith "F# Interface file (*.fsi) not supported." +(** +Summary +------- +In this tutorial, we looked at basic of working with the untyped abstract syntax tree. This is a +comprehensive topic, so it is not possible to explain everything in a single article. The +[Fantomas project](https://github.com/dungpa/fantomas) is a good example of tool based on the untyped +AST that can help you understand more. In practice, it is also useful to combine the information here +with some information you can obtain from the [editor services](editor.html) discussed in the next +tutorial. +*) diff --git a/fcs/docsrc/files/content/fcs.css b/docs/files/content/fcs.css similarity index 100% rename from fcs/docsrc/files/content/fcs.css rename to docs/files/content/fcs.css diff --git a/fcs/docsrc/files/content/style.ja.css b/docs/files/content/style.ja.css similarity index 100% rename from fcs/docsrc/files/content/style.ja.css rename to docs/files/content/style.ja.css diff --git a/fcs/docsrc/files/images/en.png b/docs/files/images/en.png similarity index 100% rename from fcs/docsrc/files/images/en.png rename to docs/files/images/en.png diff --git a/fcs/docsrc/files/images/ja.png b/docs/files/images/ja.png similarity index 100% rename from fcs/docsrc/files/images/ja.png rename to docs/files/images/ja.png diff --git a/fcs/docsrc/files/images/logo.png b/docs/files/images/logo.png similarity index 100% rename from fcs/docsrc/files/images/logo.png rename to docs/files/images/logo.png diff --git a/docs/fsharp-core-notes.md b/docs/fsharp-core-notes.md new file mode 100644 index 00000000000..1b0b1f1c5ee --- /dev/null +++ b/docs/fsharp-core-notes.md @@ -0,0 +1,130 @@ +# Notes and Guidance on FSharp.Core + +This technical guide discusses the FSharp.Core library. + +Reference documentation for FSharp.Core can be found here: https://fsharp.github.io/fsharp-core-docs/ + +Much of the guidance below applies to any .NET library respecting binary compatibility. + +## FSharp.Core is binary compatible + +FSharp.Core is binary compatible across versions of the F# language. For example, this means you can create a newer project with a newer FSharp.Core in an older codebase and things should generally "just work". + +**Binary compatibility means that a component built for X can bind to Y at runtime. It doesn't mean that Y behaves 100% the same as X, though.** For example, an older compiler that doesn't know how to understand `inref<'T>` referencing a newer FSharp.Core that has `inref<'T>` defined may not behave correctly if `inref<'T>` is used in source. + +## FSharp.Core and F# scripts + +F# scripts, executed by F# interactive, execute against the FSharp.Core deployed with the .NET SDK you are using. If you're expecting to use a more modern library feature and find that it's missing, it's likely because you have an older .NET SDK and thus an older F# Interactive. Upgrade your .NET SDK. + +## Guidance for package authors + +If you are authoring a NuGet package for consumption in the F# and .NET ecosystem, you already have to make a decision about functionality vs. reach by deciding what target framework(s) you support. + +As an F# package author, you also need to make this decision with respect to FSharp.Core: + +* Targeting an earlier version of FSharp.Core increases your reach because older codebases can use it without issue +* Targeting a newer version of FSharp.Core lets you use and extend newer features + +This decision is critical, because it can have a network effect. If you choose a higher FSharp.Core version, then that also becomes a dependency for any other package that may depend on your package. + +### Package authors should pin their FSharp.Core reference + +The default templates for F# projects carry an implicit reference to FSharp.Core. This is ideal for application developers, since applications almost always want to be referencing the highest FSharp.Core available to them. As you upgrade your .NET SDK, the FSharp.Core package referenced implicitly will also be upgraded over time, since FSharp.Core is also distributed with the .NET SDK. + +However, as a package author this means that unless you reference FSharp.Core explicitly, you will default to the latest possible version and thus eliminate any hope of reaching older projects in older environments. + +### How to explicitly reference FSharp.Core + +It's a simple gesture in your project file that pins to FSharp.Core 4.7.2: + +```xml + + + +``` + +Or if you're using Paket: + +``` +nuget FSharp.Core >= 4.7.2 +``` + +And that's it! + +### Compatibility table + +The following table can help you decide the minimum language/package version you want to support: + +|Minimum F# language version|Minimum FSharp.Core package version| +|------------------------------|------------------------------| +|F# 4.1|4.3.4| +|F# 4.5|4.5.2| +|F# 4.6|4.6.2| +|F# 4.7|4.7.2| +|F# 5.0|5.0.0| + +If you want to be compatible with much older projects using an F# 4.0 compiler or earlier, you can still do that but it's not recommended. People using those codebases should upgrade instead. + +### Do *not* bundle FSharp.Core directly with a library + +Do _not_ include a copy of FSharp.Core with your library or package, such in the `lib` folder of a package. If you do this, you will create havoc for users of your library. + +The decision about which `FSharp.Core` a library binds to is up to the application hosting of the library. + +## Guidance for everyone else + +If you're not authoring packages for distribution, you have a lot less to worry about. + +If you are distributing library code across a private organization as if it were a NuGet package, please see the above guidance, as it likely still applies. Otherwise, the below guidance applies. + +### Application authors don't have to explicitly reference FSharp.Core + +In general, applications can always just use the latest FSharp.Core bundled in the SDK they are built with. + +### C# projects referencing F# projects may need to pin FSharp.Core + +You can reference an F# project just fine without needing to be explicit about an FSharp.Core reference when using C# projects based on the .NET SDK. References flow transitively for SDK-style projects, so even if you need to use types directly from FSharp.Core (which you probably shouldn't do anyways) it will pick up the right types from the right assembly. + +If you do have an explicit FSharp.Core reference in your C# project that you **need**, you should pin your FSharp.Core reference across your entire codebase. Being in a mixed pinned/non-pinned world is difficult to keep straight over a long period of time. + +## Guidance for older projects, compilers, and tools + +Modern .NET development, including F#, uses SDK-style projects. You can read about that here: https://docs.microsoft.com/dotnet/core/project-sdk/overview + +If you are not using SDK-style projects F# projects and/or have an older toolset, the following guidance applies. + +### Consider upgrading + +Yes, really. The old project system that manages legacy projects is not that good, the compiler is older and unoptimized for supporting larger codebases, tooling is not as responsive, etc. You will really have a much better life if you upgrade. Try out the `try-convert` tool to do that: https://github.com/dotnet/try-convert + +If you cannot upgrade for some reason, the rest of the guidance applies. + +### Always deploy FSharp.Core as part of a compiled application + +For applications, FSharp.Core is normally part of the application itself (so-called "xcopy deploy" of FSharp.Core). + +For older project files, you may need to use ``true`` in your project file. In Visual Studio this is equivalent to setting the `CopyLocal` property to `true` properties for the `FSharp.Core` reference. + +FSharp.Core.dll will normally appear in the `bin` output folder for your application. For example: + +``` + Directory of ...\ConsoleApplication3\bin\Debug\net5.0 + + 18/04/2020 13:20 5,632 ConsoleApplication3.exe + 14/10/2020 12:12 1,400,472 FSharp.Core.dll +``` + +### FSharp.Core and static linking + +The ILMerge tool and the F# compiler both allow static linking of assemblies including static linking of FSharp.Core. +This can be useful to build a single standalone file for a tool. + +However, these options must be used with caution. + +* Only use this option for applications, not libraries. If it's not a .EXE (or a library that is effectively an application) then don't even try using this option. + +Searching on stackoverflow reveals further guidance on this topic. + +## Reference: FSharp.Core version and NuGet package numbers + +See [the F# version information RFC](https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1004-versioning-plan.md). diff --git a/fcs/docsrc/tools/generate.fsx b/docs/tools/generate.fsx similarity index 100% rename from fcs/docsrc/tools/generate.fsx rename to docs/tools/generate.fsx diff --git a/fcs/docsrc/tools/generate.ja.fsx b/docs/tools/generate.ja.fsx similarity index 100% rename from fcs/docsrc/tools/generate.ja.fsx rename to docs/tools/generate.ja.fsx diff --git a/fcs/docsrc/tools/templates/ja/template.cshtml b/docs/tools/templates/ja/template.cshtml similarity index 100% rename from fcs/docsrc/tools/templates/ja/template.cshtml rename to docs/tools/templates/ja/template.cshtml diff --git a/fcs/docsrc/tools/templates/template.cshtml b/docs/tools/templates/template.cshtml similarity index 100% rename from fcs/docsrc/tools/templates/template.cshtml rename to docs/tools/templates/template.cshtml diff --git a/eng/Build.ps1 b/eng/Build.ps1 index b1bac650541..b085a9163f9 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -14,7 +14,7 @@ # it's fine to call `build.ps1 -build -testDesktop` followed by repeated calls to # `.\build.ps1 -testDesktop`. -[CmdletBinding(PositionalBinding=$false)] +[CmdletBinding(PositionalBinding = $false)] param ( [string][Alias('c')]$configuration = "Debug", [string][Alias('v')]$verbosity = "m", @@ -36,7 +36,9 @@ param ( [switch][Alias('proto')]$bootstrap, [string]$bootstrapConfiguration = "Proto", [string]$bootstrapTfm = "net472", - [switch][Alias('bl')]$binaryLog, + [switch][Alias('bl')]$binaryLog = $true, + [switch][Alias('nobl')]$excludeCIBinaryLog = $false, + [switch][Alias('nolog')]$noBinaryLog = $false, [switch]$ci, [switch]$official, [switch]$procdump, @@ -48,19 +50,23 @@ param ( [switch]$testCoreClr, [switch]$testCambridge, [switch]$testCompiler, - [switch]$testDependencyManager, + [switch]$testCompilerService, [switch]$testFSharpCore, [switch]$testFSharpQA, [switch]$testScripting, [switch]$testVs, [switch]$testAll, + [switch]$testpack, [string]$officialSkipTests = "false", [switch]$noVisualStudio, + [switch]$sourceBuild, - [parameter(ValueFromRemainingArguments=$true)][string[]]$properties) + [parameter(ValueFromRemainingArguments = $true)][string[]]$properties) Set-StrictMode -version 2.0 $ErrorActionPreference = "Stop" +$BuildCategory = "" +$BuildMessage = "" function Print-Usage() { Write-Host "Common settings:" @@ -68,6 +74,8 @@ function Print-Usage() { Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]" Write-Host " -deployExtensions Deploy built vsixes" Write-Host " -binaryLog Create MSBuild binary log (short: -bl)" + Write-Host " -noLog Turn off logging (short: -nolog)" + Write-Host " -excludeCIBinaryLog When running on CI, allow no binary log (short: -nobl)" Write-Host "" Write-Host "Actions:" Write-Host " -restore Restore packages (short: -r)" @@ -84,13 +92,14 @@ function Print-Usage() { Write-Host " -testAll Run all tests" Write-Host " -testCambridge Run Cambridge tests" Write-Host " -testCompiler Run FSharpCompiler unit tests" - Write-Host " -testDependencyManager Run FSharp.DependencyManager.UnitTests" + Write-Host " -testCompilerService Run FSharpCompilerService unit tests" Write-Host " -testDesktop Run tests against full .NET Framework" Write-Host " -testCoreClr Run tests against CoreCLR" Write-Host " -testFSharpCore Run FSharpCore unit tests" Write-Host " -testFSharpQA Run F# Cambridge tests" Write-Host " -testScripting Run Scripting tests" Write-Host " -testVs Run F# editor unit tests" + Write-Host " -testpack Verify built packages" Write-Host " -officialSkipTests Set to 'true' to skip running tests" Write-Host "" Write-Host "Advanced settings:" @@ -102,6 +111,7 @@ function Print-Usage() { Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -useGlobalNuGetCache Use global NuGet cache." Write-Host " -noVisualStudio Only build fsc and fsi as .NET Core applications. No Visual Studio required. '-configuration', '-verbosity', '-norestore', '-rebuild' are supported." + Write-Host " -sourceBuild Simulate building for source-build." Write-Host "" Write-Host "Command line arguments starting with '/p:' are passed through to MSBuild." } @@ -110,9 +120,10 @@ function Print-Usage() { # specified. function Process-Arguments() { if ($help -or (($properties -ne $null) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { - Print-Usage - exit 0 + Print-Usage + exit 0 } + $script:nodeReuse = $False; if ($testAll) { @@ -126,12 +137,13 @@ function Process-Arguments() { $script:testAll = $False $script:testCambridge = $False $script:testCompiler = $False - $script:testDependencyManager = $False + $script:testCompilerService = $False $script:testDesktop = $False $script:testCoreClr = $False $script:testFSharpCore = $False $script:testFSharpQA = $False $script:testVs = $False + $script:testpack = $False } if ($noRestore) { @@ -142,6 +154,18 @@ function Process-Arguments() { $script:sign = $False; } + if ($testpack) { + $script:pack = $True; + } + + if ($sourceBuild) { + $script:testpack = $False; + } + + if ($noBinaryLog) { + $script:binaryLog = $False; + } + foreach ($property in $properties) { if (!$property.StartsWith("/p:", "InvariantCultureIgnoreCase")) { Write-Host "Invalid argument: $property" @@ -153,33 +177,32 @@ function Process-Arguments() { function Update-Arguments() { if ($script:noVisualStudio) { - $script:bootstrapTfm = "netcoreapp3.0" + $script:bootstrapTfm = "net5.0" $script:msbuildEngine = "dotnet" } - if ($bootstrapTfm -eq "netcoreapp3.0") { + if ($bootstrapTfm -eq "net5.0") { if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc\fsc.runtimeconfig.json")) { $script:bootstrap = $True } - } else { + } + else { if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc\fsc.exe") -or (Test-Path "$ArtifactsDir\Bootstrap\fsc\fsc.runtimeconfig.json")) { $script:bootstrap = $True } } } -function BuildSolution() { - # VisualFSharp.sln can't be built with dotnet due to WPF, WinForms and VSIX build task dependencies - $solution = "VisualFSharp.sln" - - Write-Host "$($solution):" +function BuildSolution([string] $solutionName) { + Write-Host "${solutionName}:" $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "Build.binlog") } else { "" } - $projects = Join-Path $RepoRoot $solution + + $projects = Join-Path $RepoRoot $solutionName $officialBuildId = if ($official) { $env:BUILD_BUILDNUMBER } else { "" } $toolsetBuildProj = InitializeToolset $quietRestore = !$ci - $testTargetFrameworks = if ($testCoreClr) { "netcoreapp3.0" } else { "" } + $testTargetFrameworks = if ($testCoreClr) { "net5.0" } else { "" } # Do not set the property to true explicitly, since that would override value projects might set. $suppressExtensionDeployment = if (!$deployExtensions) { "/p:DeployExtension=false" } else { "" } @@ -200,6 +223,7 @@ function BuildSolution() { /p:QuietRestore=$quietRestore ` /p:QuietRestoreBinaryLog=$binaryLog ` /p:TestTargetFrameworks=$testTargetFrameworks ` + /p:DotNetBuildFromSource=$sourceBuild ` /v:$verbosity ` $suppressExtensionDeployment ` @properties @@ -241,13 +265,14 @@ function VerifyAssemblyVersionsAndSymbols() { } } -function TestUsingNUnit([string] $testProject, [string] $targetFramework) { +function TestUsingMSBuild([string] $testProject, [string] $targetFramework, [string]$testadapterpath, [boolean] $noTestFilter = $false) { $dotnetPath = InitializeDotNetCli $dotnetExe = Join-Path $dotnetPath "dotnet.exe" $projectName = [System.IO.Path]::GetFileNameWithoutExtension($testProject) $testLogPath = "$ArtifactsDir\TestResults\$configuration\${projectName}_$targetFramework.xml" $testBinLogPath = "$LogDir\${projectName}_$targetFramework.binlog" - $args = "test $testProject -c $configuration -f $targetFramework -v n --test-adapter-path . --logger ""nunit;LogFilePath=$testLogPath"" /bl:$testBinLogPath" + $args = "test $testProject -c $configuration -f $targetFramework -v n --test-adapter-path $testadapterpath --logger ""nunit;LogFilePath=$testLogPath"" /bl:$testBinLogPath" + $args += " --blame --results-directory $ArtifactsDir\TestResults\$configuration" if (-not $noVisualStudio -or $norestore) { $args += " --no-restore" @@ -257,25 +282,20 @@ function TestUsingNUnit([string] $testProject, [string] $targetFramework) { $args += " --no-build" } + if ($env:RunningAsPullRequest -ne "true" -and $noTestFilter -eq $false) { + $args += " --filter TestCategory!=PullRequest" + } + + Write-Host("$args") Exec-Console $dotnetExe $args } -function BuildCompiler() { - if ($bootstrapTfm -eq "netcoreapp3.0") { - $dotnetPath = InitializeDotNetCli - $dotnetExe = Join-Path $dotnetPath "dotnet.exe" - $fscProject = "$RepoRoot\src\fsharp\fsc\fsc.fsproj" - $fsiProject = "$RepoRoot\src\fsharp\fsi\fsi.fsproj" - - $argNoRestore = if ($norestore) { " --no-restore" } else { "" } - $argNoIncremental = if ($rebuild) { " --no-incremental" } else { "" } - - $args = "build $fscProject -c $configuration -v $verbosity -f netcoreapp3.0" + $argNoRestore + $argNoIncremental - Exec-Console $dotnetExe $args +function TestUsingXUnit([string] $testProject, [string] $targetFramework, [string]$testadapterpath) { + TestUsingMsBuild -testProject $testProject -targetFramework $targetFramework -testadapterpath $testadapterpath -noTestFilter $true +} - $args = "build $fsiProject -c $configuration -v $verbosity -f netcoreapp3.0" + $argNoRestore + $argNoIncremental - Exec-Console $dotnetExe $args - } +function TestUsingNUnit([string] $testProject, [string] $targetFramework, [string]$testadapterpath) { + TestUsingMsBuild -testProject $testProject -targetFramework $targetFramework -testadapterpath $testadapterpath -noTestFilter $false } function Prepare-TempDir() { @@ -283,26 +303,124 @@ function Prepare-TempDir() { Copy-Item (Join-Path $RepoRoot "tests\Resources\Directory.Build.targets") $TempDir } +function DownloadDotnetFrameworkSdk() { + $dlTempPath = [System.IO.Path]::GetTempPath() + $dlRandomFile = [System.IO.Path]::GetRandomFileName() + $net48Dir = Join-Path $dlTempPath $dlRandomFile + Create-Directory $net48Dir + + $net48Exe = Join-Path $net48Dir "ndp48-devpack-enu.exe" + $dlLogFilePath = Join-Path $LogDir "dotnet48.install.log" + Invoke-WebRequest "https://go.microsoft.com/fwlink/?linkid=2088517" -OutFile $net48Exe + + Write-Host "Exec-Console $net48Exe /install /quiet /norestart /log $dlLogFilePath" + Exec-Console $net48Exe "/install /quiet /norestart /log $dlLogFilePath" +} + +function Test-IsAdmin { + ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") +} + +function TryDownloadDotnetFrameworkSdk() { + # If we are not running as admin user, don't bother grabbing ndp sdk -- since we don't need sn.exe + $isAdmin = Test-IsAdmin + Write-Host "TryDownloadDotnetFrameworkSdk -- Test-IsAdmin = '$isAdmin'" + if ($isAdmin -eq $true) { + # Get program files(x86) location + if (${env:ProgramFiles(x86)} -eq $null) { + $programFiles = $env:ProgramFiles + } + else { + $programFiles = ${env:ProgramFiles(x86)} + } + + # Get windowsSDK location for x86 + $windowsSDK_ExecutablePath_x86 = $env:WindowsSDK_ExecutablePath_x86 + $newWindowsSDK_ExecutablePath_x86 = Join-Path "$programFiles" "Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" + + if ($windowsSDK_ExecutablePath_x86 -eq $null) { + $snPathX86 = Join-Path $newWindowsSDK_ExecutablePath_x86 "sn.exe" + } + else { + $snPathX86 = Join-Path $windowsSDK_ExecutablePath_x86 "sn.exe" + $snPathX86Exists = Test-Path $snPathX86 -PathType Leaf + if ($snPathX86Exists -ne $true) { + $windowsSDK_ExecutablePath_x86 = null + $snPathX86 = Join-Path $newWindowsSDK_ExecutablePath_x86 "sn.exe" + } + } + + $windowsSDK_ExecutablePath_x64 = $env:WindowsSDK_ExecutablePath_x64 + $newWindowsSDK_ExecutablePath_x64 = Join-Path "$programFiles" "Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64" + + if ($windowsSDK_ExecutablePath_x64 -eq $null) { + $snPathX64 = Join-Path $newWindowsSDK_ExecutablePath_x64 "sn.exe" + } + else { + $snPathX64 = Join-Path $windowsSDK_ExecutablePath_x64 "sn.exe" + $snPathX64Exists = Test-Path $snPathX64 -PathType Leaf + if ($snPathX64Exists -ne $true) { + $windowsSDK_ExecutablePath_x86 = null + $snPathX64 = Join-Path $newWindowsSDK_ExecutablePath_x64 "sn.exe" + } + } + + $snPathX86Exists = Test-Path $snPathX86 -PathType Leaf + Write-Host "pre-dl snPathX86Exists : $snPathX86Exists - '$snPathX86'" + if ($snPathX86Exists -ne $true) { + DownloadDotnetFrameworkSdk + } + + $snPathX86Exists = Test-Path $snPathX86 -PathType Leaf + if ($snPathX86Exists -eq $true) { + if ($windowsSDK_ExecutablePath_x86 -ne $newWindowsSDK_ExecutablePath_x86) { + $windowsSDK_ExecutablePath_x86 = $newWindowsSDK_ExecutablePath_x86 + # x86 environment variable + Write-Host "set WindowsSDK_ExecutablePath_x86=$WindowsSDK_ExecutablePath_x86" + [System.Environment]::SetEnvironmentVariable("WindowsSDK_ExecutablePath_x86", "$newWindowsSDK_ExecutablePath_x86", [System.EnvironmentVariableTarget]::Machine) + $env:WindowsSDK_ExecutablePath_x86 = $newWindowsSDK_ExecutablePath_x86 + } + } + + # Also update environment variable for x64 + $snPathX64Exists = Test-Path $snPathX64 -PathType Leaf + if ($snPathX64Exists -eq $true) { + if ($windowsSDK_ExecutablePath_x64 -ne $newWindowsSDK_ExecutablePath_x64) { + $windowsSDK_ExecutablePath_x64 = $newWindowsSDK_ExecutablePath_x64 + # x64 environment variable + Write-Host "set WindowsSDK_ExecutablePath_x64=$WindowsSDK_ExecutablePath_x64" + [System.Environment]::SetEnvironmentVariable("WindowsSDK_ExecutablePath_x64", "$newWindowsSDK_ExecutablePath_x64", [System.EnvironmentVariableTarget]::Machine) + $env:WindowsSDK_ExecutablePath_x64 = $newWindowsSDK_ExecutablePath_x64 + } + } + } +} + function EnablePreviewSdks() { - if (Test-Path variable:global:_MSBuildExe) { - return - } - $vsInfo = LocateVisualStudio - if ($vsInfo -eq $null) { - # Preview SDKs are allowed when no Visual Studio instance is installed - return - } - - $vsId = $vsInfo.instanceId - $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] - - $instanceDir = Join-Path ${env:USERPROFILE} "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsId" - Create-Directory $instanceDir - $sdkFile = Join-Path $instanceDir "sdk.txt" - 'UsePreviews=True' | Set-Content $sdkFile + if (Test-Path variable:global:_MSBuildExe) { + return + } + $vsInfo = LocateVisualStudio + if ($vsInfo -eq $null) { + # Preview SDKs are allowed when no Visual Studio instance is installed + return + } + + $vsId = $vsInfo.instanceId + $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] + + $instanceDir = Join-Path ${env:USERPROFILE} "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsId" + Create-Directory $instanceDir + $sdkFile = Join-Path $instanceDir "sdk.txt" + 'UsePreviews=True' | Set-Content $sdkFile } try { + $script:BuildCategory = "Build" + $script:BuildMessage = "Failure preparing build" + + [System.Environment]::SetEnvironmentVariable('DOTNET_ROLL_FORWARD_TO_PRERELEASE', '1', [System.EnvironmentVariableTarget]::User) + Process-Arguments . (Join-Path $PSScriptRoot "build-utils.ps1") @@ -311,20 +429,34 @@ try { Push-Location $RepoRoot + Get-ChildItem ENV: | Sort-Object Name + Write-Host "" + if ($ci) { Prepare-TempDir EnablePreviewSdks } + $buildTool = InitializeBuildTool + $toolsetBuildProj = InitializeToolset + TryDownloadDotnetFrameworkSdk + + $dotnetPath = InitializeDotNetCli + $env:DOTNET_ROOT = "$dotnetPath" + Get-Item -Path Env: + if ($bootstrap) { + $script:BuildMessage = "Failure building bootstrap compiler" $bootstrapDir = Make-BootstrapBuild } + $script:BuildMessage = "Failure building product" if ($restore -or $build -or $rebuild -or $pack -or $sign -or $publish) { if ($noVisualStudio) { - BuildCompiler - } else { - BuildSolution + BuildSolution "FSharp.sln" + } + else { + BuildSolution "VisualFSharp.sln" } } @@ -332,41 +464,44 @@ try { VerifyAssemblyVersionsAndSymbols } + $script:BuildCategory = "Test" + $script:BuildMessage = "Failure running tests" $desktopTargetFramework = "net472" - $coreclrTargetFramework = "netcoreapp3.0" - - if ($testDesktop -and -not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework + $coreclrTargetFramework = "net5.0" + + if ($testDesktop) { + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" -noTestFilter $true + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Build.UnitTests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } if ($testCoreClr) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Build.UnitTests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } - if ($testFSharpQA -and -not $noVisualStudio) { + if ($testFSharpQA) { Push-Location "$RepoRoot\tests\fsharpqa\source" + $nugetPackages = Get-PackagesDir $resultsRoot = "$ArtifactsDir\TestResults\$configuration" $resultsLog = "test-net40-fsharpqa-results.log" $errorLog = "test-net40-fsharpqa-errors.log" $failLog = "test-net40-fsharpqa-errors" - $perlPackageRoot = "$env:USERPROFILE\.nuget\packages\StrawberryPerl\5.28.0.1"; + $perlPackageRoot = "$nugetPackages\StrawberryPerl\5.28.0.1"; $perlExe = "$perlPackageRoot\bin\perl.exe" Create-Directory $resultsRoot UpdatePath $env:HOSTED_COMPILER = 1 - $env:CSC_PIPE = "$env:USERPROFILE\.nuget\packages\Microsoft.Net.Compilers\2.7.0\tools\csc.exe" + $env:CSC_PIPE = "$nugetPackages\Microsoft.Net.Compilers\2.7.0\tools\csc.exe" $env:FSCOREDLLPATH = "$ArtifactsDir\bin\fsc\$configuration\net472\FSharp.Core.dll" $env:LINK_EXE = "$RepoRoot\tests\fsharpqa\testenv\bin\link\link.exe" $env:OSARCH = $env:PROCESSOR_ARCHITECTURE @@ -376,43 +511,61 @@ try { } if ($testFSharpCore) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Core.UnitTests\" } if ($testCompiler) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" -noTestFilter $true + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.ComponentTests\FSharp.Compiler.ComponentTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.ComponentTests\" -noTestFilter $true + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.UnitTests\" } - if ($testDependencyManager) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.DependencyManager.UnitTests\FSharp.DependencyManager.UnitTests.fsproj" -targetFramework $coreclrTargetFramework + if ($testCompilerService) { + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" + TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Service.Tests\" } if ($testCambridge) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" + TestUsingNUnit -testProject "$RepoRoot\tests\fsharp\FSharpSuite.Tests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharpSuite.Tests\" } - - if ($testScripting) { - if (-not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework - } - TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework +` + if ($testScripting) { + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" + TestUsingXUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework -testadapterpath "$ArtifactsDir\bin\FSharp.Compiler.Private.Scripting.UnitTests\" } if ($testVs -and -not $noVisualStudio) { - TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\GetTypesVS.UnitTests\GetTypesVS.UnitTests.fsproj" -targetFramework $desktopTargetFramework - TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\UnitTests\VisualFSharp.UnitTests.fsproj" -targetFramework $desktopTargetFramework + TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\GetTypesVS.UnitTests\GetTypesVS.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\GetTypesVS.UnitTests" + TestUsingNUnit -testProject "$RepoRoot\vsintegration\tests\UnitTests\VisualFSharp.UnitTests.fsproj" -targetFramework $desktopTargetFramework -testadapterpath "$ArtifactsDir\bin\VisualFSharp.UnitTests" + } + + # verify nupkgs have access to the source code + $nupkgtestFailed = $false + if ($testpack) { + # Fetch soucelink test + $dotnetPath = InitializeDotNetCli + $dotnetExe = Join-Path $dotnetPath "dotnet.exe" + $dotnettoolsPath = Join-Path $RepoRoot "\.tools\" + $sourcelink = Join-Path $dotnettoolsPath "sourcelink.exe" + try { + $out = New-Item -Path $dotnettoolsPath -ItemType Directory -Force + Exec-Console $dotnetExe "tool install sourcelink --tool-path $dotnettoolsPath" + } + catch { + Write-Host "Already installed is not a problem" + } + + $nupkgs = @(Get-ChildItem "$artifactsDir\packages\$configuration\Shipping\*.nupkg" -recurse) + $nupkgs | Foreach { + Exec-Console """$sourcelink"" test ""$_""" + if (-not $?) { $nupkgtestFailed = $true } + } + } + if ($nupkgtestFailed) { + throw "Error Verifying nupkgs have access to the source code" } ExitWithExitCode 0 @@ -421,6 +574,7 @@ catch { Write-Host $_ Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category $script:BuildCategory -Message $script:BuildMessage ExitWithExitCode 1 } finally { diff --git a/eng/DumpPackageRoot/DumpPackageRoot.csproj b/eng/DumpPackageRoot/DumpPackageRoot.csproj new file mode 100644 index 00000000000..0c94f0a999c --- /dev/null +++ b/eng/DumpPackageRoot/DumpPackageRoot.csproj @@ -0,0 +1,22 @@ + + + + + + net5.0 + + + + + + + + + $(ArtifactsDir)NugetPackageRootContents + $(PackageRootArtifactDirectory)/package_contents.txt + + + + + diff --git a/eng/MockBuild.ps1 b/eng/MockBuild.ps1 new file mode 100644 index 00000000000..e8000edb45f --- /dev/null +++ b/eng/MockBuild.ps1 @@ -0,0 +1,15 @@ +Set-StrictMode -version 2.0 +$ErrorActionPreference = "Stop" + +try { + $fakeBuildId = (Get-Date -Format "yyyyMMdd") + ".0" + $visualStudioDropName = "Products/mock/dotnet-fsharp/branch/$fakeBuildId" + & "$PSScriptRoot\Build.ps1" -build -restore -ci -bootstrap -binaryLog -pack -configuration Release /p:OfficialBuildId=$fakeBuildId /p:VisualStudioDropName=$visualStudioDropName +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + Write-Host "##[error](NETCORE_ENGINEERING_TELEMETRY=Build) Error doing mock official build." + exit 1 +} diff --git a/eng/Publishing.props b/eng/Publishing.props new file mode 100644 index 00000000000..18483e92a08 --- /dev/null +++ b/eng/Publishing.props @@ -0,0 +1,5 @@ + + + 3 + + diff --git a/eng/Signing.props b/eng/Signing.props index da17d32fa4d..222ad3dc47a 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -5,4 +5,7 @@ + + true + diff --git a/eng/SourceBuild.props b/eng/SourceBuild.props new file mode 100644 index 00000000000..22c929f286c --- /dev/null +++ b/eng/SourceBuild.props @@ -0,0 +1,47 @@ + + + + fsharp + true + + + + + + + + + + + + + + $(InnerBuildArgs) /p:Projects="$(InnerSourceBuildRepoRoot)\FSharp.sln" + + + + + + + + + + diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml new file mode 100644 index 00000000000..c1b6dfbf053 --- /dev/null +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c98fbfbee49..f8884b8b7a0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,11 +1,17 @@ + + https://github.com/dotnet/xliff-tasks + 7e80445ee82adbf9a8e6ae601ac5e239d982afaa + + - + https://github.com/dotnet/arcade - d0833c8e5e58cfc507ce3c8da364e55931190263 + 4b7c80f398fd3dcea03fdc4e454789b61181d300 + diff --git a/eng/Versions.props b/eng/Versions.props index f7611980e00..ff88c64babf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -12,61 +12,71 @@ beta - 4.7 - $(FSLanguageVersion) - $(FSCoreMajorVersion).1 - $(FSCoreMajorVersion).0 - $(FSCoreVersionPrefix).0 + + 5 + 0 + 3 + 0 + + $(FSMajorVersion).$(FSMinorVersion) + $(FSMajorVersion)-$(FSMinorVersion) + + $(FSMajorVersion).$(FSMinorVersion) + $(FSMajorVersion).$(FSMinorVersion).$(FSBuildVersion) + $(FSMajorVersion)-$(FSMinorVersion)-$(FSBuildVersion) + $(FSMajorVersion).$(FSMinorVersion).$(FSBuildVersion) + $(FSMajorVersion).$(FSMinorVersion).0.0 + + 40 + 0 + 1 + $(FSRevisionVersion) + $(FCSMajorVersion).$(FCSMinorVersion).$(FCSBuildVersion) + $(FCSMajorVersion).$(FCSMinorVersion).$(FCSBuildVersion).$(FCSRevisionVersion) + $(FCSMajorVersion)$(FCSMinorVersion)$(FCSBuildVersion) - 4.7.0 + 5.0.2 $(FSCorePackageVersion)-$(PreReleaseVersionLabel).* - - - 10.7 - $(FSPackageMajorVersion).1 - $(FSPackageVersion) - $(FSPackageVersion).0 + 11 + 3 + $(FSBuildVersion) + $(FSRevisionVersion) + $(FSToolsMajorVersion).$(FSToolsMinorVersion).$(FSToolsBuildVersion) + $(FSToolsMajorVersion)-$(FSToolsMinorVersion)-$(FSToolsBuildVersion) + $(FSToolsMajorVersion).$(FSToolsMinorVersion).$(FSToolsBuildVersion).$(FSToolsRevisionVersion) 16 - 4 + 10 $(VSMajorVersion).0 $(VSMajorVersion).$(VSMinorVersion).0 $(VSAssemblyVersionPrefix).0 - + + $(FSCoreVersionPrefix) + $(FSCoreVersion) + + $(FSCoreVersionPrefix) - $(FSCorePackageVersion) $(FSProductVersionPrefix) $(VSAssemblyVersionPrefix) - $(VersionPrefix).0 + $(FSharpCompilerServicePackageVersion) + $(VersionPrefix).0 $(RestoreSources); - https://www.myget.org/F/fsharp-daily/api/v3/index.json; - https://dotnet.myget.org/F/roslyn-master-nightly/api/v3/index.json; - https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; - https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json; - https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json; - https://api.nuget.org/v3/index.json; - https://dotnet.myget.org/F/roslyn/api/v3/index.json; - https://dotnet.myget.org/F/symreader-converter/api/v3/index.json; - https://dotnet.myget.org/F/interactive-window/api/v3/index.json; - https://myget.org/F/vs-devcore/api/v3/index.json; - https://myget.org/F/vs-editor/api/v3/index.json; + https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json; https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json; https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-impl/nuget/v3/index.json; - https://myget.org/F/roslyn_concord/api/v3/index.json; - - $([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\RoslynPackageVersion.txt').Trim()) - 1.5.0 + 4.5.1 + 5.0.0 4.3.0 4.3.0 4.0.0 @@ -75,90 +85,95 @@ 4.3.0 4.3.0 4.3.0 - 4.5.3 + 4.5.4 4.3.0 - 4.3.0 + 4.3.1 4.3.0 - 1.6.0 + 5.0.0 4.3.0 1.5.0 4.3.0 4.3.0 4.3.0 - 4.3.0 4.3.0 4.3.0 4.3.0 - 4.6.0 4.3.0 - 4.11.0 + 4.11.1 4.3.0 4.3.0 - 4.5.0 + 4.7.1 + 3.8.0-5.20570.14 $(RoslynVersion) $(RoslynVersion) $(RoslynVersion) $(RoslynVersion) $(RoslynVersion) $(RoslynVersion) - 2.0.17 + 2.0.28 $(RoslynVersion) - 16.4 + 16.9 $(MicrosoftBuildOverallPackagesVersion) $(MicrosoftBuildOverallPackagesVersion) $(MicrosoftBuildOverallPackagesVersion) $(MicrosoftBuildOverallPackagesVersion) - - 8.0.1 + + 16.8.39 + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + $(VisualStudioEditorPackagesVersion) + + 16.7.30329.88 + $(VisualStudioLanguageAndShellVersion) + $(VisualStudioLanguageAndShellVersion) + $(VisualStudioLanguageAndShellVersion) + $(VisualStudioLanguageAndShellVersion) + + 16.7.30328.74 + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + $(VisualStudioLanguageAndShellInteropVersion) + + 16.8.30 + 16.6.255 14.0.25420 - 16.1.89 - 16.1.89 1.1.4322 - 16.1.89 - 16.1.89 16.0.28226-alpha - 16.1.28916.169 - 16.1.28917.181 - 16.1.3121 - 16.1.89 - 16.1.89 - 16.1.89 + 16.7.30329.63 8.0.50728 - 7.10.6071 - 16.1.28917.181 - 16.1.89 8.0.50728 16.0.201-pre-g7d366164d0 2.3.6152103 14.3.25407 - 16.1.28917.181 - 16.1.28917.181 - 16.1.28917.181 10.0.30319 11.0.50727 15.0.25123-Dev15Preview - 7.10.6072 - 8.0.50728 - 9.0.30730 - 10.0.30320 - 11.0.61031 - 12.0.30111 - 16.0.0 - 16.1.89 - 16.1.89 - 7.10.6071 - 8.0.50728 - 10.0.30320 - 12.0.30112 - 16.1.89 - 16.1.89 - 16.0.102 - 16.1.28917.181 - 15.3.58 + 16.0.1 + 16.0.28924.11111 + 16.8.55 + 16.7.30329.38 + 16.8.33 9.0.30729 - 16.3.2099 + 16.5.2044 12.0.4 7.0.4 8.0.4 @@ -172,20 +187,22 @@ 3.0.0-alpha4 4.3.0.0 1.0.30 - 8.0.0-alpha + 8.0.0 2.7.0 - 3.0.0-preview-27318-01 - 3.0.0-preview-27318-01 - 15.8.0 - 1.0.0 + 3.1.0 + 5.0.0-preview.7.20364.11 + 5.0.0-preview.7.20364.11 + 16.6.1 4.3.0 - 9.0.1 + 12.0.2 3.11.0 3.11.2 3.11.0 - 2.1.36 + 2.1.41 1.0.0-beta2-dev3 5.28.0.1 - 2.0.187 + 2.6.113 + 2.4.1 + 5.10.3 diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1 index 316a36062ce..ffc4498fb85 100644 --- a/eng/build-utils.ps1 +++ b/eng/build-utils.ps1 @@ -237,16 +237,38 @@ function Make-BootstrapBuild() { Create-Directory $dir # prepare FsLex and Fsyacc and AssemblyCheck - Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Publish /p:PublishWindowsPdb=false" -logFileName "BuildTools" -configuration $bootstrapConfiguration - Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp3.0\publish" -Destination "$dir\fslex" -Force -Recurse - Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp3.0\publish" -Destination "$dir\fsyacc" -Force -Recurse - Copy-Item "$ArtifactsDir\bin\AssemblyCheck\$bootstrapConfiguration\netcoreapp3.0\publish" -Destination "$dir\AssemblyCheck" -Force -Recurse + $dotnetPath = InitializeDotNetCli + $dotnetExe = Join-Path $dotnetPath "dotnet.exe" + $buildToolsProject = "`"$RepoRoot\src\buildtools\buildtools.proj`"" + + $argNoRestore = if ($norestore) { " --no-restore" } else { "" } + $argNoIncremental = if ($rebuild) { " --no-incremental" } else { "" } + + $args = "build $buildToolsProject -c $bootstrapConfiguration -v $verbosity" + $argNoRestore + $argNoIncremental + if ($binaryLog) { + $logFilePath = Join-Path $LogDir "toolsBootstrapLog.binlog" + $args += " /bl:$logFilePath" + } + Exec-Console $dotnetExe $args + + Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\net5.0" -Destination "$dir\fslex" -Force -Recurse + Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\net5.0" -Destination "$dir\fsyacc" -Force -Recurse + Copy-Item "$ArtifactsDir\bin\AssemblyCheck\$bootstrapConfiguration\net5.0" -Destination "$dir\AssemblyCheck" -Force -Recurse # prepare compiler - $projectPath = "$RepoRoot\proto.proj" - Run-MSBuild $projectPath "/restore /t:Publish /p:TargetFramework=$bootstrapTfm;ProtoTargetFramework=$bootstrapTfm /p:PublishWindowsPdb=false" -logFileName "Bootstrap" -configuration $bootstrapConfiguration - Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsc" -Force -Recurse - Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsi" -Force -Recurse + $protoProject = "`"$RepoRoot\proto.proj`"" + $args = "build $protoProject -c $bootstrapConfiguration -v $verbosity -f $bootstrapTfm" + $argNoRestore + $argNoIncremental + if ($binaryLog) { + $logFilePath = Join-Path $LogDir "protoBootstrapLog.binlog" + $args += " /bl:$logFilePath" + } + Exec-Console $dotnetExe $args + + Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm" -Destination "$dir\fsc" -Force -Recurse + Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm" -Destination "$dir\fsi" -Force -Recurse return $dir } + + + diff --git a/eng/build.sh b/eng/build.sh index a53fce79146..9a2aa0083f3 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -29,7 +29,9 @@ usage() echo " --ci Building in CI" echo " --docker Run in a docker container if applicable" echo " --skipAnalyzers Do not run analyzers during build operations" + echo " --skipBuild Do not run the build" echo " --prepareMachine Prepare machine for CI run, clean up processes after build" + echo " --sourceBuild Simulate building for source-build" echo "" echo "Command line arguments starting with '/p:' are passed through to MSBuild." } @@ -59,6 +61,7 @@ binary_log=false force_bootstrap=false ci=false skip_analyzers=false +skip_build=false prepare_machine=false source_build=false properties="" @@ -66,6 +69,9 @@ properties="" docker=false args="" +BuildCategory="" +BuildMessage="" + if [[ $# = 0 ]] then usage @@ -122,19 +128,20 @@ while [[ $# > 0 ]]; do --skipanalyzers) skip_analyzers=true ;; + --skipbuild) + skip_build=true + ;; --preparemachine) prepare_machine=true ;; --docker) docker=true - shift - continue + ;; + --sourcebuild) + source_build=true ;; /p:*) properties="$properties $1" - if [[ "$1" == "/p:dotnetbuildfromsource=true" ]]; then - source_build=true - fi ;; *) echo "Invalid argument: $1" @@ -150,8 +157,11 @@ done . "$scriptroot/common/tools.sh" function TestUsingNUnit() { + BuildCategory="Test" + BuildMessage="Error running tests" testproject="" targetframework="" + notestfilter=0 while [[ $# > 0 ]]; do opt="$(echo "$1" | awk '{print tolower($0)}')" case "$opt" in @@ -163,6 +173,10 @@ function TestUsingNUnit() { targetframework=$2 shift ;; + --notestfilter) + notestfilter=1 + shift + ;; *) echo "Invalid argument: $1" exit 1 @@ -176,31 +190,34 @@ function TestUsingNUnit() { exit 1 fi + filterArgs="" + if [[ "${RunningAsPullRequest:-}" != "true" && $notestfilter == 0 ]]; then + filterArgs=" --filter TestCategory!=PullRequest" + fi + projectname=$(basename -- "$testproject") projectname="${projectname%.*}" testlogpath="$artifacts_dir/TestResults/$configuration/${projectname}_$targetframework.xml" - args="test \"$testproject\" --no-restore --no-build -c $configuration -f $targetframework --test-adapter-path . --logger \"nunit;LogFilePath=$testlogpath\"" - "$DOTNET_INSTALL_DIR/dotnet" $args || { - local exit_code=$? - Write-PipelineTelemetryError -category 'Test' "dotnet test failed for $testproject:$targetframework (exit code $exit_code)." - ExitWithExitCode $exit_code - } + args="test \"$testproject\" --no-restore --no-build -c $configuration -f $targetframework --test-adapter-path . --logger \"nunit;LogFilePath=$testlogpath\"$filterArgs --blame --results-directory $artifacts_dir/TestResults/$configuration" + "$DOTNET_INSTALL_DIR/dotnet" $args || exit $? } function BuildSolution { + BuildCategory="Build" + BuildMessage="Error preparing build" local solution="FSharp.sln" echo "$solution:" InitializeToolset local toolset_build_proj=$_InitializeToolset - + local bl="" if [[ "$binary_log" = true ]]; then bl="/bl:\"$log_dir/Build.binlog\"" fi - - local projects="$repo_root/$solution" - + + local projects="$repo_root/$solution" + # https://github.com/dotnet/roslyn/issues/23736 local enable_analyzers=!$skip_analyzers UNAME="$(uname)" @@ -229,68 +246,71 @@ function BuildSolution { rm -fr $bootstrap_dir fi if [ ! -f "$bootstrap_dir/fslex.dll" ]; then + BuildMessage="Error building tools" MSBuild "$repo_root/src/buildtools/buildtools.proj" \ /restore \ - /p:Configuration=$bootstrap_config \ - /t:Publish || { - local exit_code=$? - Write-PipelineTelemetryError -category 'Build' "Error building buildtools (exit code '$exit_code')." - ExitWithExitCode $exit_code - } + /p:Configuration=$bootstrap_config mkdir -p "$bootstrap_dir" - cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fslex - cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fsyacc + cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/net5.0 $bootstrap_dir/fslex + cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/net5.0 $bootstrap_dir/fsyacc fi if [ ! -f "$bootstrap_dir/fsc.exe" ]; then + BuildMessage="Error building bootstrap" MSBuild "$repo_root/proto.proj" \ /restore \ /p:Configuration=$bootstrap_config \ - /t:Publish || { - local exit_code=$? - Write-PipelineTelemetryError -category 'Build' "Error building bootstrap compiler (exit code '$exit_code')." - ExitWithExitCode $exit_code - } - cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/netcoreapp3.0/publish $bootstrap_dir/fsc + + cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/net5.0 $bootstrap_dir/fsc + fi + + if [[ "$skip_build" != true ]]; then + # do real build + BuildMessage="Error building solution" + MSBuild $toolset_build_proj \ + $bl \ + /v:$verbosity \ + /p:Configuration=$configuration \ + /p:Projects="$projects" \ + /p:RepoRoot="$repo_root" \ + /p:Restore=$restore \ + /p:Build=$build \ + /p:Rebuild=$rebuild \ + /p:Pack=$pack \ + /p:Publish=$publish \ + /p:UseRoslynAnalyzers=$enable_analyzers \ + /p:ContinuousIntegrationBuild=$ci \ + /p:QuietRestore=$quiet_restore \ + /p:QuietRestoreBinaryLog="$binary_log" \ + /p:ArcadeBuildFromSource=$source_build \ + $properties fi +} - # do real build - MSBuild $toolset_build_proj \ - $bl \ - /v:$verbosity \ - /p:Configuration=$configuration \ - /p:Projects="$projects" \ - /p:RepoRoot="$repo_root" \ - /p:Restore=$restore \ - /p:Build=$build \ - /p:Rebuild=$rebuild \ - /p:Pack=$pack \ - /p:Publish=$publish \ - /p:UseRoslynAnalyzers=$enable_analyzers \ - /p:ContinuousIntegrationBuild=$ci \ - /p:QuietRestore=$quiet_restore \ - /p:QuietRestoreBinaryLog="$binary_log" \ - $properties || { - local exit_code=$? - Write-PipelineTelemetryError -category 'Build' "Error building solution (exit code '$exit_code')." - ExitWithExitCode $exit_code - } +function TrapAndReportError { + local exit_code=$? + if [[ ! $exit_code == 0 ]]; then + Write-PipelineTelemetryError -category $BuildCategory "$BuildMessage (exit code '$exit_code')." + ExitWithExitCode $exit_code + fi } +# allow early termination to report the appropriate build failure reason +trap TrapAndReportError EXIT + InitializeDotNetCli $restore BuildSolution if [[ "$test_core_clr" == true ]]; then - coreclrtestframework=netcoreapp3.0 + coreclrtestframework=net5.0 + TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj" --targetframework $coreclrtestframework --notestfilter + TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj" --targetframework $coreclrtestframework --notestfilter TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj" --targetframework $coreclrtestframework - TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj" --targetframework $coreclrtestframework TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj" --targetframework $coreclrtestframework - TestUsingNUnit --testproject "$repo_root/tests/FSharp.DependencyManager.UnitTests/FSharp.DependencyManager.UnitTests.fsproj" --targetframework $coreclrtestframework TestUsingNUnit --testproject "$repo_root/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj" --targetframework $coreclrtestframework TestUsingNUnit --testproject "$repo_root/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj" --targetframework $coreclrtestframework fi ExitWithExitCode 0 - diff --git a/eng/common/CheckSymbols.ps1 b/eng/common/CheckSymbols.ps1 deleted file mode 100644 index b8d84607b89..00000000000 --- a/eng/common/CheckSymbols.ps1 +++ /dev/null @@ -1,158 +0,0 @@ -param( - [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where NuGet packages to be checked are stored - [Parameter(Mandatory=$true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation - [Parameter(Mandatory=$true)][string] $SymbolToolPath # Full path to directory where dotnet symbol-tool was installed -) - -Add-Type -AssemblyName System.IO.Compression.FileSystem - -function FirstMatchingSymbolDescriptionOrDefault { - param( - [string] $FullPath, # Full path to the module that has to be checked - [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols - [string] $SymbolsPath - ) - - $FileName = [System.IO.Path]::GetFileName($FullPath) - $Extension = [System.IO.Path]::GetExtension($FullPath) - - # Those below are potential symbol files that the `dotnet symbol` might - # return. Which one will be returned depend on the type of file we are - # checking and which type of file was uploaded. - - # The file itself is returned - $SymbolPath = $SymbolsPath + "\" + $FileName - - # PDB file for the module - $PdbPath = $SymbolPath.Replace($Extension, ".pdb") - - # PDB file for R2R module (created by crossgen) - $NGenPdb = $SymbolPath.Replace($Extension, ".ni.pdb") - - # DBG file for a .so library - $SODbg = $SymbolPath.Replace($Extension, ".so.dbg") - - # DWARF file for a .dylib - $DylibDwarf = $SymbolPath.Replace($Extension, ".dylib.dwarf") - - .\dotnet-symbol.exe --symbols --modules --windows-pdbs $TargetServerParam $FullPath -o $SymbolsPath | Out-Null - - if (Test-Path $PdbPath) { - return "PDB" - } - elseif (Test-Path $NGenPdb) { - return "NGen PDB" - } - elseif (Test-Path $SODbg) { - return "DBG for SO" - } - elseif (Test-Path $DylibDwarf) { - return "Dwarf for Dylib" - } - elseif (Test-Path $SymbolPath) { - return "Module" - } - else { - return $null - } -} - -function CountMissingSymbols { - param( - [string] $PackagePath # Path to a NuGet package - ) - - # Ensure input file exist - if (!(Test-Path $PackagePath)) { - throw "Input file does not exist: $PackagePath" - } - - # Extensions for which we'll look for symbols - $RelevantExtensions = @(".dll", ".exe", ".so", ".dylib") - - # How many files are missing symbol information - $MissingSymbols = 0 - - $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) - $PackageGuid = New-Guid - $ExtractPath = Join-Path -Path $ExtractPath -ChildPath $PackageGuid - $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath "Symbols" - - [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) - - # Makes easier to reference `symbol tool` - Push-Location $SymbolToolPath - - Get-ChildItem -Recurse $ExtractPath | - Where-Object {$RelevantExtensions -contains $_.Extension} | - ForEach-Object { - if ($_.FullName -Match "\\ref\\") { - Write-Host "`t Ignoring reference assembly file" $_.FullName - return - } - - $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--microsoft-symbol-server" $SymbolsPath - $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--internal-server" $SymbolsPath - - Write-Host -NoNewLine "`t Checking file" $_.FullName "... " - - if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) { - Write-Host "Symbols found on MSDL (" $SymbolsOnMSDL ") and SymWeb (" $SymbolsOnSymWeb ")" - } - else { - $MissingSymbols++ - - if ($SymbolsOnMSDL -eq $null -and $SymbolsOnSymWeb -eq $null) { - Write-Host "No symbols found on MSDL or SymWeb!" - } - else { - if ($SymbolsOnMSDL -eq $null) { - Write-Host "No symbols found on MSDL!" - } - else { - Write-Host "No symbols found on SymWeb!" - } - } - } - } - - Pop-Location - - return $MissingSymbols -} - -function CheckSymbolsAvailable { - if (Test-Path $ExtractPath) { - Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue - } - - Get-ChildItem "$InputPath\*.nupkg" | - ForEach-Object { - $FileName = $_.Name - - # These packages from Arcade-Services include some native libraries that - # our current symbol uploader can't handle. Below is a workaround until - # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted. - if ($FileName -Match "Microsoft\.DotNet\.Darc\.") { - Write-Host "Ignoring Arcade-services file: $FileName" - Write-Host - return - } - elseif ($FileName -Match "Microsoft\.DotNet\.Maestro\.Tasks\.") { - Write-Host "Ignoring Arcade-services file: $FileName" - Write-Host - return - } - - Write-Host "Validating $FileName " - $Status = CountMissingSymbols "$InputPath\$FileName" - - if ($Status -ne 0) { - Write-Error "Missing symbols for $Status modules in the package $FileName" - } - - Write-Host - } -} - -CheckSymbolsAvailable diff --git a/eng/common/PublishToPackageFeed.proj b/eng/common/PublishToPackageFeed.proj deleted file mode 100644 index a1b1333723e..00000000000 --- a/eng/common/PublishToPackageFeed.proj +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - netcoreapp2.1 - - - - - - - - - - - - - - - - - - - - - - - - - https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json - https://dotnetfeed.blob.core.windows.net/arcade-validation/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore-tooling/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json - https://dotnetfeed.blob.core.windows.net/dotnet-coreclr/index.json - https://dotnetfeed.blob.core.windows.net/dotnet-sdk/index.json - https://dotnetfeed.blob.core.windows.net/dotnet-tools-internal/index.json - https://dotnetfeed.blob.core.windows.net/dotnet-toolset/index.json - https://dotnetfeed.blob.core.windows.net/dotnet-windowsdesktop/index.json - https://dotnetfeed.blob.core.windows.net/nuget-nugetclient/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-entityframework6/index.json - https://dotnetfeed.blob.core.windows.net/aspnet-blazor/index.json - - - - - - - - - - - - diff --git a/eng/common/PublishToSymbolServers.proj b/eng/common/PublishToSymbolServers.proj deleted file mode 100644 index 5d55e312b01..00000000000 --- a/eng/common/PublishToSymbolServers.proj +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - netcoreapp2.1 - - - - - - - - - - - - - - - - 3650 - true - false - - - - - - - - - - - - - - - - - diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index a8b5280d9dd..18823840b11 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -11,6 +11,8 @@ # See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` # from the AzureDevOps-Artifact-Feeds-Pats variable group. # +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing +# # - task: PowerShell@2 # displayName: Setup Private Feeds Credentials # condition: eq(variables['Agent.OS'], 'Windows_NT') @@ -94,6 +96,15 @@ function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Passw } } +function EnablePrivatePackageSources($DisabledPackageSources) { + $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]") + ForEach ($DisabledPackageSource in $maestroPrivateSources) { + Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource" + # Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries + $DisabledPackageSources.RemoveChild($DisabledPackageSource) + } +} + if (!(Test-Path $ConfigFile -PathType Leaf)) { Write-PipelineTelemetryError -Category 'Build' -Message "Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile" ExitWithExitCode 1 @@ -123,21 +134,34 @@ if ($creds -eq $null) { $doc.DocumentElement.AppendChild($creds) | Out-Null } +# Check for disabledPackageSources; we'll enable any darc-int ones we find there +$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources") +if ($disabledSources -ne $null) { + Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node" + EnablePrivatePackageSources -DisabledPackageSources $disabledSources +} + $userName = "dn-bot" # Insert credential nodes for Maestro's private feeds InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -Password $Password -$dotnet3Source = $sources.SelectSingleNode("add[@key='dotnet3']") -if ($dotnet3Source -ne $null) { - AddPackageSource -Sources $sources -SourceName "dotnet3-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "dotnet3-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password -} - $dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") if ($dotnet31Source -ne $null) { AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password } -$doc.Save($filename) \ No newline at end of file +$dotnet5Source = $sources.SelectSingleNode("add[@key='dotnet5']") +if ($dotnet5Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet5-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet5-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet5-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet5-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password +} + +$dotnet6Source = $sources.SelectSingleNode("add[@key='dotnet6']") +if ($dotnet6Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet6-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet6-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password +} + +$doc.Save($filename) diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index 4ebb1e5a440..ad3fb74fd2c 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -13,6 +13,8 @@ # See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` # from the AzureDevOps-Artifact-Feeds-Pats variable group. # +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing. +# # - task: Bash@3 # displayName: Setup Private Feeds Credentials # inputs: @@ -63,7 +65,7 @@ if [ "$?" != "0" ]; then ConfigNodeHeader="" PackageSourcesTemplate="${TB}${NL}${TB}" - sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" NuGet.config + sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile fi # Ensure there is a ... section. @@ -74,58 +76,81 @@ if [ "$?" != "0" ]; then PackageSourcesNodeFooter="" PackageSourceCredentialsTemplate="${TB}${NL}${TB}" - sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" NuGet.config + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile fi PackageSources=() -# Ensure dotnet3-internal and dotnet3-internal-transport are in the packageSources if the public dotnet3 feeds are present -grep -i "" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet3.1-internal') + + grep -i "" $ConfigFile + if [ "$?" != "0" ]; then + echo "Adding dotnet3.1-internal-transport to the packageSources." + PackageSourcesNodeFooter="" + PackageSourceTemplate="${TB}" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet3.1-internal-transport') +fi +# Ensure dotnet5-internal and dotnet5-internal-transport are in the packageSources if the public dotnet5 feeds are present +grep -i "" $ConfigFile + grep -i "" + PackageSourceTemplate="${TB}" sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile fi - PackageSources+=('dotnet3-internal') + PackageSources+=('dotnet5-internal') - grep -i "" $ConfigFile if [ "$?" != "0" ]; then - echo "Adding dotnet3-internal-transport to the packageSources." + echo "Adding dotnet5-internal-transport to the packageSources." PackageSourcesNodeFooter="" - PackageSourceTemplate="${TB}" + PackageSourceTemplate="${TB}" sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile fi - PackageSources+=('dotnet3-internal-transport') + PackageSources+=('dotnet5-internal-transport') fi -# Ensure dotnet3.1-internal and dotnet3.1-internal-transport are in the packageSources if the public dotnet3.1 feeds are present -grep -i "" + PackageSourceTemplate="${TB}" sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile fi - PackageSources+=('dotnet3.1-internal') + PackageSources+=('dotnet6-internal') - grep -i "" $ConfigFile + grep -i "" $ConfigFile if [ "$?" != "0" ]; then - echo "Adding dotnet3.1-internal-transport to the packageSources." + echo "Adding dotnet6-internal-transport to the packageSources." PackageSourcesNodeFooter="" - PackageSourceTemplate="${TB}" + PackageSourceTemplate="${TB}" sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile fi - PackageSources+=('dotnet3.1-internal-transport') + PackageSources+=('dotnet6-internal-transport') fi # I want things split line by line @@ -146,4 +171,21 @@ for FeedName in ${PackageSources[@]} ; do sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile fi -done \ No newline at end of file +done + +# Re-enable any entries in disabledPackageSources where the feed name contains darc-int +grep -i "" $ConfigFile +if [ "$?" == "0" ]; then + DisabledDarcIntSources=() + echo "Re-enabling any disabled \"darc-int\" package sources in $ConfigFile" + DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' $ConfigFile | tr -d '"') + for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do + if [[ $DisabledSourceName == darc-int* ]] + then + OldDisableValue="" + NewDisableValue="" + sed -i.bak "s|$OldDisableValue|$NewDisableValue|" $ConfigFile + echo "Neutralized disablePackageSources entry for '$DisabledSourceName'" + fi + done +fi diff --git a/eng/common/SigningValidation.proj b/eng/common/SigningValidation.proj deleted file mode 100644 index 3d0ac80af3f..00000000000 --- a/eng/common/SigningValidation.proj +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - netcoreapp2.1 - - - - - - - - $(NuGetPackageRoot)Microsoft.DotNet.SignCheck\$(SignCheckVersion)\tools\Microsoft.DotNet.SignCheck.exe - - $(PackageBasePath) - signcheck.log - signcheck.errors.log - signcheck.exclusions.txt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eng/common/SourceLinkValidation.ps1 b/eng/common/SourceLinkValidation.ps1 deleted file mode 100644 index cb2d28cb99e..00000000000 --- a/eng/common/SourceLinkValidation.ps1 +++ /dev/null @@ -1,184 +0,0 @@ -param( - [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where Symbols.NuGet packages to be checked are stored - [Parameter(Mandatory=$true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation - [Parameter(Mandatory=$true)][string] $SourceLinkToolPath, # Full path to directory where dotnet SourceLink CLI was installed - [Parameter(Mandatory=$true)][string] $GHRepoName, # GitHub name of the repo including the Org. E.g., dotnet/arcade - [Parameter(Mandatory=$true)][string] $GHCommit # GitHub commit SHA used to build the packages -) - -# Cache/HashMap (File -> Exist flag) used to consult whether a file exist -# in the repository at a specific commit point. This is populated by inserting -# all files present in the repo at a specific commit point. -$global:RepoFiles = @{} - -$ValidatePackage = { - param( - [string] $PackagePath # Full path to a Symbols.NuGet package - ) - - # Ensure input file exist - if (!(Test-Path $PackagePath)) { - throw "Input file does not exist: $PackagePath" - } - - # Extensions for which we'll look for SourceLink information - # For now we'll only care about Portable & Embedded PDBs - $RelevantExtensions = @(".dll", ".exe", ".pdb") - - Write-Host -NoNewLine "Validating" ([System.IO.Path]::GetFileName($PackagePath)) "... " - - $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) - $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId - $FailedFiles = 0 - - Add-Type -AssemblyName System.IO.Compression.FileSystem - - [System.IO.Directory]::CreateDirectory($ExtractPath); - - $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath) - - $zip.Entries | - Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} | - ForEach-Object { - $FileName = $_.FullName - $Extension = [System.IO.Path]::GetExtension($_.Name) - $FakeName = -Join((New-Guid), $Extension) - $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName - - # We ignore resource DLLs - if ($FileName.EndsWith(".resources.dll")) { - return - } - - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true) - - $ValidateFile = { - param( - [string] $FullPath, # Full path to the module that has to be checked - [string] $RealPath, - [ref] $FailedFiles - ) - - # Makes easier to reference `sourcelink cli` - Push-Location $using:SourceLinkToolPath - - $SourceLinkInfos = .\sourcelink.exe print-urls $FullPath | Out-String - - if ($LASTEXITCODE -eq 0 -and -not ([string]::IsNullOrEmpty($SourceLinkInfos))) { - $NumFailedLinks = 0 - - # We only care about Http addresses - $Matches = (Select-String '(http[s]?)(:\/\/)([^\s,]+)' -Input $SourceLinkInfos -AllMatches).Matches - - if ($Matches.Count -ne 0) { - $Matches.Value | - ForEach-Object { - $Link = $_ - $CommitUrl = -Join("https://raw.githubusercontent.com/", $using:GHRepoName, "/", $using:GHCommit, "/") - $FilePath = $Link.Replace($CommitUrl, "") - $Status = 200 - $Cache = $using:RepoFiles - - if ( !($Cache.ContainsKey($FilePath)) ) { - try { - $Uri = $Link -as [System.URI] - - # Only GitHub links are valid - if ($Uri.AbsoluteURI -ne $null -and $Uri.Host -match "github") { - $Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode - } - else { - $Status = 0 - } - } - catch { - $Status = 0 - } - } - - if ($Status -ne 200) { - if ($NumFailedLinks -eq 0) { - if ($FailedFiles.Value -eq 0) { - Write-Host - } - - Write-Host "`tFile $RealPath has broken links:" - } - - Write-Host "`t`tFailed to retrieve $Link" - - $NumFailedLinks++ - } - } - } - - if ($NumFailedLinks -ne 0) { - $FailedFiles.value++ - $global:LASTEXITCODE = 1 - } - } - - Pop-Location - } - - &$ValidateFile $TargetFile $FileName ([ref]$FailedFiles) - } - - $zip.Dispose() - - if ($FailedFiles -eq 0) { - Write-Host "Passed." - } -} - -function ValidateSourceLinkLinks { - if (!($GHRepoName -Match "^[^\s\/]+/[^\s\/]+$")) { - Write-Host "GHRepoName should be in the format /" - $global:LASTEXITCODE = 1 - return - } - - if (!($GHCommit -Match "^[0-9a-fA-F]{40}$")) { - Write-Host "GHCommit should be a 40 chars hexadecimal string" - $global:LASTEXITCODE = 1 - return - } - - $RepoTreeURL = -Join("https://api.github.com/repos/", $GHRepoName, "/git/trees/", $GHCommit, "?recursive=1") - $CodeExtensions = @(".cs", ".vb", ".fs", ".fsi", ".fsx", ".fsscript") - - try { - # Retrieve the list of files in the repo at that particular commit point and store them in the RepoFiles hash - $Data = Invoke-WebRequest $RepoTreeURL | ConvertFrom-Json | Select-Object -ExpandProperty tree - - foreach ($file in $Data) { - $Extension = [System.IO.Path]::GetExtension($file.path) - - if ($CodeExtensions.Contains($Extension)) { - $RepoFiles[$file.path] = 1 - } - } - } - catch { - Write-Host "Problems downloading the list of files from the repo. Url used: $RepoTreeURL" - $global:LASTEXITCODE = 1 - return - } - - if (Test-Path $ExtractPath) { - Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue - } - - # Process each NuGet package in parallel - $Jobs = @() - Get-ChildItem "$InputPath\*.symbols.nupkg" | - ForEach-Object { - $Jobs += Start-Job -ScriptBlock $ValidatePackage -ArgumentList $_.FullName - } - - foreach ($Job in $Jobs) { - Wait-Job -Id $Job.Id | Receive-Job - } -} - -Measure-Command { ValidateSourceLinkLinks } diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 index e001ccb481c..8943da242f6 100644 --- a/eng/common/build.ps1 +++ b/eng/common/build.ps1 @@ -18,56 +18,69 @@ Param( [switch] $sign, [switch] $pack, [switch] $publish, + [switch] $clean, [switch][Alias('bl')]$binaryLog, + [switch][Alias('nobl')]$excludeCIBinarylog, [switch] $ci, [switch] $prepareMachine, + [string] $runtimeSourceFeed = '', + [string] $runtimeSourceFeedKey = '', + [switch] $excludePrereleaseVS, [switch] $help, [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties ) -. $PSScriptRoot\tools.ps1 - +# Unset 'Platform' environment variable to avoid unwanted collision in InstallDotNetCore.targets file +# some computer has this env var defined (e.g. Some HP) +if($env:Platform) { + $env:Platform="" +} function Print-Usage() { - Write-Host "Common settings:" - Write-Host " -configuration Build configuration: 'Debug' or 'Release' (short: -c)" - Write-Host " -platform Platform configuration: 'x86', 'x64' or any valid Platform value to pass to msbuild" - Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" - Write-Host " -binaryLog Output binary log (short: -bl)" - Write-Host " -help Print help and exit" - Write-Host "" - - Write-Host "Actions:" - Write-Host " -restore Restore dependencies (short: -r)" - Write-Host " -build Build solution (short: -b)" - Write-Host " -rebuild Rebuild solution" - Write-Host " -deploy Deploy built VSIXes" - Write-Host " -deployDeps Deploy dependencies (e.g. VSIXes for integration tests)" - Write-Host " -test Run all unit tests in the solution (short: -t)" - Write-Host " -integrationTest Run all integration tests in the solution" - Write-Host " -performanceTest Run all performance tests in the solution" - Write-Host " -pack Package build outputs into NuGet packages and Willow components" - Write-Host " -sign Sign build outputs" - Write-Host " -publish Publish artifacts (e.g. symbols)" - Write-Host "" - - Write-Host "Advanced settings:" - Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" - Write-Host " -ci Set when running on CI server" - Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" - Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" - Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." - Write-Host "" - - Write-Host "Command line arguments not listed above are passed thru to msbuild." - Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." + Write-Host "Common settings:" + Write-Host " -configuration Build configuration: 'Debug' or 'Release' (short: -c)" + Write-Host " -platform Platform configuration: 'x86', 'x64' or any valid Platform value to pass to msbuild" + Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" + Write-Host " -binaryLog Output binary log (short: -bl)" + Write-Host " -help Print help and exit" + Write-Host "" + + Write-Host "Actions:" + Write-Host " -restore Restore dependencies (short: -r)" + Write-Host " -build Build solution (short: -b)" + Write-Host " -rebuild Rebuild solution" + Write-Host " -deploy Deploy built VSIXes" + Write-Host " -deployDeps Deploy dependencies (e.g. VSIXes for integration tests)" + Write-Host " -test Run all unit tests in the solution (short: -t)" + Write-Host " -integrationTest Run all integration tests in the solution" + Write-Host " -performanceTest Run all performance tests in the solution" + Write-Host " -pack Package build outputs into NuGet packages and Willow components" + Write-Host " -sign Sign build outputs" + Write-Host " -publish Publish artifacts (e.g. symbols)" + Write-Host " -clean Clean the solution" + Write-Host "" + + Write-Host "Advanced settings:" + Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" + Write-Host " -ci Set when running on CI server" + Write-Host " -excludeCIBinarylog Don't output binary log (short: -nobl)" + Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" + Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio" + Write-Host "" + + Write-Host "Command line arguments not listed above are passed thru to msbuild." + Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." } +. $PSScriptRoot\tools.ps1 + function InitializeCustomToolset { if (-not $restore) { return } - $script = Join-Path $EngRoot "restore-toolset.ps1" + $script = Join-Path $EngRoot 'restore-toolset.ps1' if (Test-Path $script) { . $script @@ -78,8 +91,8 @@ function Build { $toolsetBuildProj = InitializeToolset InitializeCustomToolset - $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "Build.binlog") } else { "" } - $platformArg = if ($platform) { "/p:Platform=$platform" } else { "" } + $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'Build.binlog') } else { '' } + $platformArg = if ($platform) { "/p:Platform=$platform" } else { '' } if ($projects) { # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons. @@ -113,24 +126,27 @@ function Build { } try { - if ($help -or (($null -ne $properties) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { + if ($clean) { + if (Test-Path $ArtifactsDir) { + Remove-Item -Recurse -Force $ArtifactsDir + Write-Host 'Artifacts directory deleted.' + } + exit 0 + } + + if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $properties.Contains('/?')))) { Print-Usage exit 0 } if ($ci) { - $binaryLog = $true + if (-not $excludeCIBinarylog) { + $binaryLog = $true + } $nodeReuse = $false } - # Import custom tools configuration, if present in the repo. - # Note: Import in global scope so that the script set top-level variables without qualification. - $configureToolsetScript = Join-Path $EngRoot "configure-toolset.ps1" - if (Test-Path $configureToolsetScript) { - . $configureToolsetScript - } - - if (($restore) -and ($null -eq $env:DisableNativeToolsetInstalls)) { + if ($restore) { InitializeNativeTools } @@ -138,7 +154,7 @@ try { } catch { Write-Host $_.ScriptStackTrace - Write-PipelineTelemetryError -Category "InitializeToolset" -Message $_ + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/build.sh b/eng/common/build.sh index 6236fc4d38c..bc07a1c6848 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -26,11 +26,13 @@ usage() echo " --pack Package build outputs into NuGet packages and Willow components" echo " --sign Sign build outputs" echo " --publish Publish artifacts (e.g. symbols)" + echo " --clean Clean the solution" echo "" echo "Advanced settings:" echo " --projects Project or solution file(s) to build" echo " --ci Set when running on CI server" + echo " --excludeCIBinarylog Don't output binary log (short: -nobl)" echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" @@ -62,26 +64,32 @@ publish=false sign=false public=false ci=false +clean=false warn_as_error=true node_reuse=true binary_log=false +exclude_ci_binary_log=false pipelines_log=false projects='' configuration='Debug' prepare_machine=false verbosity='minimal' +runtime_source_feed='' +runtime_source_feed_key='' properties='' - while [[ $# > 0 ]]; do - opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -help|-h) usage exit 0 ;; + -clean) + clean=true + ;; -configuration|-c) configuration=$2 shift @@ -93,6 +101,9 @@ while [[ $# > 0 ]]; do -binarylog|-bl) binary_log=true ;; + -excludeCIBinarylog|-nobl) + exclude_ci_binary_log=true + ;; -pipelineslog|-pl) pipelines_log=true ;; @@ -141,6 +152,14 @@ while [[ $# > 0 ]]; do node_reuse=$2 shift ;; + -runtimesourcefeed) + runtime_source_feed=$2 + shift + ;; + -runtimesourcefeedkey) + runtime_source_feed_key=$2 + shift + ;; *) properties="$properties $1" ;; @@ -151,8 +170,10 @@ done if [[ "$ci" == true ]]; then pipelines_log=true - binary_log=true node_reuse=false + if [[ "$exclude_ci_binary_log" == false ]]; then + binary_log=true + fi fi . "$scriptroot/tools.sh" @@ -166,6 +187,10 @@ function InitializeCustomToolset { } function Build { + + if [[ "$ci" == true ]]; then + TryLogClientIpAddress + fi InitializeToolset InitializeCustomToolset @@ -196,20 +221,15 @@ function Build { ExitWithExitCode 0 } -# Import custom tools configuration, if present in the repo. -configure_toolset_script="$eng_root/configure-toolset.sh" -if [[ -a "$configure_toolset_script" ]]; then - . "$configure_toolset_script" -fi - -# TODO: https://github.com/dotnet/arcade/issues/1468 -# Temporary workaround to avoid breaking change. -# Remove once repos are updated. -if [[ -n "${useInstalledDotNetCli:-}" ]]; then - use_installed_dotnet_cli="$useInstalledDotNetCli" +if [[ "$clean" == true ]]; then + if [ -d "$artifacts_dir" ]; then + rm -rf $artifacts_dir + echo "Artifacts directory deleted." + fi + exit 0 fi -if [[ "$restore" == true && -z ${DisableNativeToolsetInstalls:-} ]]; then +if [[ "$restore" == true ]]; then InitializeNativeTools fi diff --git a/eng/common/cross/android/arm/toolchain.cmake b/eng/common/cross/android/arm/toolchain.cmake deleted file mode 100644 index a7e1c73501b..00000000000 --- a/eng/common/cross/android/arm/toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -set(CROSS_NDK_TOOLCHAIN $ENV{ROOTFS_DIR}/../) -set(CROSS_ROOTFS ${CROSS_NDK_TOOLCHAIN}/sysroot) -set(CLR_CMAKE_PLATFORM_ANDROID "Android") - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_SYSTEM_PROCESSOR arm) - -## Specify the toolchain -set(TOOLCHAIN "arm-linux-androideabi") -set(CMAKE_PREFIX_PATH ${CROSS_NDK_TOOLCHAIN}) -set(TOOLCHAIN_PREFIX ${TOOLCHAIN}-) - -find_program(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}clang) -find_program(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}clang++) -find_program(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}clang) -find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) -find_program(CMAKE_LD ${TOOLCHAIN_PREFIX}ar) -find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) -find_program(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) - -add_compile_options(--sysroot=${CROSS_ROOTFS}) -add_compile_options(-fPIE) -add_compile_options(-mfloat-abi=soft) -include_directories(SYSTEM ${CROSS_NDK_TOOLCHAIN}/include/c++/4.9.x/) -include_directories(SYSTEM ${CROSS_NDK_TOOLCHAIN}/include/c++/4.9.x/arm-linux-androideabi/) - -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -B ${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -L${CROSS_ROOTFS}/lib/${TOOLCHAIN}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} --sysroot=${CROSS_ROOTFS}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -fPIE -pie") - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) -set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) - -set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/android/arm64/toolchain.cmake b/eng/common/cross/android/arm64/toolchain.cmake deleted file mode 100644 index 29415899c1c..00000000000 --- a/eng/common/cross/android/arm64/toolchain.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(CROSS_NDK_TOOLCHAIN $ENV{ROOTFS_DIR}/../) -set(CROSS_ROOTFS ${CROSS_NDK_TOOLCHAIN}/sysroot) -set(CLR_CMAKE_PLATFORM_ANDROID "Android") - -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_SYSTEM_PROCESSOR aarch64) - -## Specify the toolchain -set(TOOLCHAIN "aarch64-linux-android") -set(CMAKE_PREFIX_PATH ${CROSS_NDK_TOOLCHAIN}) -set(TOOLCHAIN_PREFIX ${TOOLCHAIN}-) - -find_program(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}clang) -find_program(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}clang++) -find_program(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}clang) -find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) -find_program(CMAKE_LD ${TOOLCHAIN_PREFIX}ar) -find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) -find_program(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) - -add_compile_options(--sysroot=${CROSS_ROOTFS}) -add_compile_options(-fPIE) - -## Needed for Android or bionic specific conditionals -add_compile_options(-D__ANDROID__) -add_compile_options(-D__BIONIC__) - -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -B ${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -L${CROSS_ROOTFS}/lib/${TOOLCHAIN}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} --sysroot=${CROSS_ROOTFS}") -set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -fPIE -pie") - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) -set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) - -set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/arm/sources.list.trusty b/eng/common/cross/arm/sources.list.trusty deleted file mode 100644 index 07d8f88d82e..00000000000 --- a/eng/common/cross/arm/sources.list.trusty +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/trusty-lttng-2.4.patch b/eng/common/cross/arm/trusty-lttng-2.4.patch deleted file mode 100644 index 8e4dd7ae719..00000000000 --- a/eng/common/cross/arm/trusty-lttng-2.4.patch +++ /dev/null @@ -1,71 +0,0 @@ -From e72c9d7ead60e3317bd6d1fade995c07021c947b Mon Sep 17 00:00:00 2001 -From: Mathieu Desnoyers -Date: Thu, 7 May 2015 13:25:04 -0400 -Subject: [PATCH] Fix: building probe providers with C++ compiler - -Robert Daniels wrote: -> > I'm attempting to use lttng userspace tracing with a C++ application -> > on an ARM platform. I'm using GCC 4.8.4 on Linux 3.14 with the 2.6 -> > release of lttng. I've compiled lttng-modules, lttng-ust, and -> > lttng-tools and have been able to get a simple test working with C -> > code. When I attempt to run the hello.cxx test on my target it will -> > segfault. -> -> -> I spent a little time digging into this issue and finally discovered the -> cause of my segfault with ARM C++ tracepoints. -> -> There is a struct called 'lttng_event' in ust-events.h which contains an -> empty union 'u'. This was the cause of my issue. Under C, this empty union -> compiles to a zero byte member while under C++ it compiles to a one byte -> member, and in my case was four-byte aligned which caused my C++ code to -> have the 'cds_list_head node' offset incorrectly by four bytes. This lead -> to an incorrect linked list structure which caused my issue. -> -> Since this union is empty, I simply removed it from the struct and everything -> worked correctly. -> -> I don't know the history or purpose behind this empty union so I'd like to -> know if this is a safe fix. If it is I can submit a patch with the union -> removed. - -That's a very nice catch! - -We do not support building tracepoint probe provider with -g++ yet, as stated in lttng-ust(3): - -"- Note for C++ support: although an application instrumented with - tracepoints can be compiled with g++, tracepoint probes should be - compiled with gcc (only tested with gcc so far)." - -However, if it works fine with this fix, then I'm tempted to take it, -especially because removing the empty union does not appear to affect -the layout of struct lttng_event as seen from liblttng-ust, which must -be compiled with a C compiler, and from probe providers compiled with -a C compiler. So all we are changing is the layout of a probe provider -compiled with a C++ compiler, which is anyway buggy at the moment, -because it is not compatible with the layout expected by liblttng-ust -compiled with a C compiler. - -Reported-by: Robert Daniels -Signed-off-by: Mathieu Desnoyers ---- - include/lttng/ust-events.h | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/usr/include/lttng/ust-events.h b/usr/include/lttng/ust-events.h -index 328a875..3d7a274 100644 ---- a/usr/include/lttng/ust-events.h -+++ b/usr/include/lttng/ust-events.h -@@ -407,8 +407,6 @@ struct lttng_event { - void *_deprecated1; - struct lttng_ctx *ctx; - enum lttng_ust_instrumentation instrumentation; -- union { -- } u; - struct cds_list_head node; /* Event list in session */ - struct cds_list_head _deprecated2; - void *_deprecated3; --- -2.7.4 - diff --git a/eng/common/cross/arm/trusty.patch b/eng/common/cross/arm/trusty.patch deleted file mode 100644 index 2f2972f8eb5..00000000000 --- a/eng/common/cross/arm/trusty.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h ---- a/usr/include/urcu/uatomic/generic.h 2014-03-28 06:04:42.000000000 +0900 -+++ b/usr/include/urcu/uatomic/generic.h 2017-02-13 10:35:21.189927116 +0900 -@@ -65,17 +65,17 @@ - switch (len) { - #ifdef UATOMIC_HAS_ATOMIC_BYTE - case 1: -- return __sync_val_compare_and_swap_1(addr, old, _new); -+ return __sync_val_compare_and_swap_1((uint8_t *) addr, old, _new); - #endif - #ifdef UATOMIC_HAS_ATOMIC_SHORT - case 2: -- return __sync_val_compare_and_swap_2(addr, old, _new); -+ return __sync_val_compare_and_swap_2((uint16_t *) addr, old, _new); - #endif - case 4: -- return __sync_val_compare_and_swap_4(addr, old, _new); -+ return __sync_val_compare_and_swap_4((uint32_t *) addr, old, _new); - #if (CAA_BITS_PER_LONG == 64) - case 8: -- return __sync_val_compare_and_swap_8(addr, old, _new); -+ return __sync_val_compare_and_swap_8((uint64_t *) addr, old, _new); - #endif - } - _uatomic_link_error(); -@@ -100,20 +100,20 @@ - switch (len) { - #ifdef UATOMIC_HAS_ATOMIC_BYTE - case 1: -- __sync_and_and_fetch_1(addr, val); -+ __sync_and_and_fetch_1((uint8_t *) addr, val); - return; - #endif - #ifdef UATOMIC_HAS_ATOMIC_SHORT - case 2: -- __sync_and_and_fetch_2(addr, val); -+ __sync_and_and_fetch_2((uint16_t *) addr, val); - return; - #endif - case 4: -- __sync_and_and_fetch_4(addr, val); -+ __sync_and_and_fetch_4((uint32_t *) addr, val); - return; - #if (CAA_BITS_PER_LONG == 64) - case 8: -- __sync_and_and_fetch_8(addr, val); -+ __sync_and_and_fetch_8((uint64_t *) addr, val); - return; - #endif - } -@@ -139,20 +139,20 @@ - switch (len) { - #ifdef UATOMIC_HAS_ATOMIC_BYTE - case 1: -- __sync_or_and_fetch_1(addr, val); -+ __sync_or_and_fetch_1((uint8_t *) addr, val); - return; - #endif - #ifdef UATOMIC_HAS_ATOMIC_SHORT - case 2: -- __sync_or_and_fetch_2(addr, val); -+ __sync_or_and_fetch_2((uint16_t *) addr, val); - return; - #endif - case 4: -- __sync_or_and_fetch_4(addr, val); -+ __sync_or_and_fetch_4((uint32_t *) addr, val); - return; - #if (CAA_BITS_PER_LONG == 64) - case 8: -- __sync_or_and_fetch_8(addr, val); -+ __sync_or_and_fetch_8((uint64_t *) addr, val); - return; - #endif - } -@@ -180,17 +180,17 @@ - switch (len) { - #ifdef UATOMIC_HAS_ATOMIC_BYTE - case 1: -- return __sync_add_and_fetch_1(addr, val); -+ return __sync_add_and_fetch_1((uint8_t *) addr, val); - #endif - #ifdef UATOMIC_HAS_ATOMIC_SHORT - case 2: -- return __sync_add_and_fetch_2(addr, val); -+ return __sync_add_and_fetch_2((uint16_t *) addr, val); - #endif - case 4: -- return __sync_add_and_fetch_4(addr, val); -+ return __sync_add_and_fetch_4((uint32_t *) addr, val); - #if (CAA_BITS_PER_LONG == 64) - case 8: -- return __sync_add_and_fetch_8(addr, val); -+ return __sync_add_and_fetch_8((uint64_t *) addr, val); - #endif - } - _uatomic_link_error(); diff --git a/eng/common/cross/arm64/sources.list.trusty b/eng/common/cross/arm64/sources.list.trusty deleted file mode 100644 index 07d8f88d82e..00000000000 --- a/eng/common/cross/arm64/sources.list.trusty +++ /dev/null @@ -1,11 +0,0 @@ -deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted - -deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/tizen-build-rootfs.sh b/eng/common/cross/arm64/tizen-build-rootfs.sh new file mode 100644 index 00000000000..13bfddb5e2a --- /dev/null +++ b/eng/common/cross/arm64/tizen-build-rootfs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -e + +__CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__TIZEN_CROSSDIR="$__CrossDir/tizen" + +if [[ -z "$ROOTFS_DIR" ]]; then + echo "ROOTFS_DIR is not defined." + exit 1; +fi + +TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp +mkdir -p $TIZEN_TMP_DIR + +# Download files +echo ">>Start downloading files" +VERBOSE=1 $__CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR +echo "<>Start constructing Tizen rootfs" +TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` +cd $ROOTFS_DIR +for f in $TIZEN_RPM_FILES; do + rpm2cpio $f | cpio -idm --quiet +done +echo "<>Start configuring Tizen rootfs" +ln -sfn asm-arm64 ./usr/include/asm +patch -p1 < $__TIZEN_CROSSDIR/tizen.patch +echo "</dev/null; then + VERBOSE=0 +fi + +Log() +{ + if [ $VERBOSE -ge $1 ]; then + echo ${@:2} + fi +} + +Inform() +{ + Log 1 -e "\x1B[0;34m$@\x1B[m" +} + +Debug() +{ + Log 2 -e "\x1B[0;32m$@\x1B[m" +} + +Error() +{ + >&2 Log 0 -e "\x1B[0;31m$@\x1B[m" +} + +Fetch() +{ + URL=$1 + FILE=$2 + PROGRESS=$3 + if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then + CURL_OPT="--progress-bar" + else + CURL_OPT="--silent" + fi + curl $CURL_OPT $URL > $FILE +} + +hash curl 2> /dev/null || { Error "Require 'curl' Aborting."; exit 1; } +hash xmllint 2> /dev/null || { Error "Require 'xmllint' Aborting."; exit 1; } +hash sha256sum 2> /dev/null || { Error "Require 'sha256sum' Aborting."; exit 1; } + +TMPDIR=$1 +if [ ! -d $TMPDIR ]; then + TMPDIR=./tizen_tmp + Debug "Create temporary directory : $TMPDIR" + mkdir -p $TMPDIR +fi + +TIZEN_URL=http://download.tizen.org/snapshots/tizen/ +BUILD_XML=build.xml +REPOMD_XML=repomd.xml +PRIMARY_XML=primary.xml +TARGET_URL="http://__not_initialized" + +Xpath_get() +{ + XPATH_RESULT='' + XPATH=$1 + XML_FILE=$2 + RESULT=$(xmllint --xpath $XPATH $XML_FILE) + if [[ -z ${RESULT// } ]]; then + Error "Can not find target from $XML_FILE" + Debug "Xpath = $XPATH" + exit 1 + fi + XPATH_RESULT=$RESULT +} + +fetch_tizen_pkgs_init() +{ + TARGET=$1 + PROFILE=$2 + Debug "Initialize TARGET=$TARGET, PROFILE=$PROFILE" + + TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs + if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi + mkdir -p $TMP_PKG_DIR + + PKG_URL=$TIZEN_URL/$PROFILE/latest + + BUILD_XML_URL=$PKG_URL/$BUILD_XML + TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML + TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML + TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML + TMP_PRIMARYGZ=${TMP_PRIMARY}.gz + + Fetch $BUILD_XML_URL $TMP_BUILD + + Debug "fetch $BUILD_XML_URL to $TMP_BUILD" + + TARGET_XPATH="//build/buildtargets/buildtarget[@name=\"$TARGET\"]/repo[@type=\"binary\"]/text()" + Xpath_get $TARGET_XPATH $TMP_BUILD + TARGET_PATH=$XPATH_RESULT + TARGET_URL=$PKG_URL/$TARGET_PATH + + REPOMD_URL=$TARGET_URL/repodata/repomd.xml + PRIMARY_XPATH='string(//*[local-name()="data"][@type="primary"]/*[local-name()="location"]/@href)' + + Fetch $REPOMD_URL $TMP_REPOMD + + Debug "fetch $REPOMD_URL to $TMP_REPOMD" + + Xpath_get $PRIMARY_XPATH $TMP_REPOMD + PRIMARY_XML_PATH=$XPATH_RESULT + PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH + + Fetch $PRIMARY_URL $TMP_PRIMARYGZ + + Debug "fetch $PRIMARY_URL to $TMP_PRIMARYGZ" + + gunzip $TMP_PRIMARYGZ + + Debug "unzip $TMP_PRIMARYGZ to $TMP_PRIMARY" +} + +fetch_tizen_pkgs() +{ + ARCH=$1 + PACKAGE_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="location"]/@href)' + + PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="checksum"]/text())' + + for pkg in ${@:2} + do + Inform "Fetching... $pkg" + XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + PKG_PATH=$XPATH_RESULT + + XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + CHECKSUM=$XPATH_RESULT + + PKG_URL=$TARGET_URL/$PKG_PATH + PKG_FILE=$(basename $PKG_PATH) + PKG_PATH=$TMPDIR/$PKG_FILE + + Debug "Download $PKG_URL to $PKG_PATH" + Fetch $PKG_URL $PKG_PATH true + + echo "$CHECKSUM $PKG_PATH" | sha256sum -c - > /dev/null + if [ $? -ne 0 ]; then + Error "Fail to fetch $PKG_URL to $PKG_PATH" + Debug "Checksum = $CHECKSUM" + exit 1 + fi + done +} + +Inform "Initialize arm base" +fetch_tizen_pkgs_init standard base +Inform "fetch common packages" +fetch_tizen_pkgs aarch64 gcc glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel keyutils keyutils-devel libkeyutils +Inform "fetch coreclr packages" +fetch_tizen_pkgs aarch64 lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu +Inform "fetch corefx packages" +fetch_tizen_pkgs aarch64 libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel + +Inform "Initialize standard unified" +fetch_tizen_pkgs_init standard unified +Inform "fetch corefx packages" +fetch_tizen_pkgs aarch64 gssdp gssdp-devel tizen-release + diff --git a/eng/common/cross/arm64/tizen/tizen.patch b/eng/common/cross/arm64/tizen/tizen.patch new file mode 100644 index 00000000000..af7c8be0590 --- /dev/null +++ b/eng/common/cross/arm64/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf64-littleaarch64) +-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) ) diff --git a/eng/common/cross/armel/armel.jessie.patch b/eng/common/cross/armel/armel.jessie.patch new file mode 100644 index 00000000000..2d261561935 --- /dev/null +++ b/eng/common/cross/armel/armel.jessie.patch @@ -0,0 +1,43 @@ +diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h +--- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700 ++++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700 +@@ -69,10 +69,10 @@ + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- return __sync_val_compare_and_swap_2(addr, old, _new); ++ return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new); + #endif + case 4: +- return __sync_val_compare_and_swap_4(addr, old, _new); ++ return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new); + #if (CAA_BITS_PER_LONG == 64) + case 8: + return __sync_val_compare_and_swap_8(addr, old, _new); +@@ -109,7 +109,7 @@ + return; + #endif + case 4: +- __sync_and_and_fetch_4(addr, val); ++ __sync_and_and_fetch_4((uint32_t*) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +@@ -148,7 +148,7 @@ + return; + #endif + case 4: +- __sync_or_and_fetch_4(addr, val); ++ __sync_or_and_fetch_4((uint32_t*) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +@@ -187,7 +187,7 @@ + return __sync_add_and_fetch_2(addr, val); + #endif + case 4: +- return __sync_add_and_fetch_4(addr, val); ++ return __sync_add_and_fetch_4((uint32_t*) addr, val); + #if (CAA_BITS_PER_LONG == 64) + case 8: + return __sync_add_and_fetch_8(addr, val); diff --git a/eng/common/cross/armel/tizen-build-rootfs.sh b/eng/common/cross/armel/tizen-build-rootfs.sh index 87c48e78fbb..9a4438af61c 100755 --- a/eng/common/cross/armel/tizen-build-rootfs.sh +++ b/eng/common/cross/armel/tizen-build-rootfs.sh @@ -9,13 +9,6 @@ if [[ -z "$ROOTFS_DIR" ]]; then exit 1; fi -# Clean-up (TODO-Cleanup: We may already delete $ROOTFS_DIR at ./cross/build-rootfs.sh.) -# hk0110 -if [ -d "$ROOTFS_DIR" ]; then - umount $ROOTFS_DIR/* - rm -rf $ROOTFS_DIR -fi - TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp mkdir -p $TIZEN_TMP_DIR @@ -37,8 +30,6 @@ rm -rf $TIZEN_TMP_DIR # Configure Tizen rootfs echo ">>Start configuring Tizen rootfs" -rm ./usr/lib/libunwind.so -ln -s libunwind.so.8 ./usr/lib/libunwind.so ln -sfn asm-arm ./usr/include/asm patch -p1 < $__TIZEN_CROSSDIR/tizen.patch echo "< $__ToolchainDir/sysroot/android_platform -echo Now run: -echo CONFIG_DIR=\`realpath cross/android/$__BuildArch\` ROOTFS_DIR=\`realpath $__ToolchainDir/sysroot\` ./build.sh cross $__BuildArch skipgenerateversion skipnuget cmakeargs -DENABLE_LLDBPLUGIN=0 +for path in $(wget -qO- http://termux.net/dists/stable/main/binary-$__AndroidArch/Packages |\ + grep -A15 "Package: \(${__AndroidPackages// /\\|}\)" | grep -v "static\|tool" | grep Filename); do + if [[ "$path" != "Filename:" ]]; then + echo "Working on: $path" + wget -qO- http://termux.net/$path | dpkg -x - "$__TmpDir" + fi +done + +cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/sysroot/usr/" + +# Generate platform file for build.sh script to assign to __DistroRid +echo "Generating platform file..." +echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/sysroot/android_platform + +echo "Now to build coreclr, libraries and installers; run:" +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory coreclr +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory libraries +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory installer diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index d7d5d7d5f44..6fa2c8aa551 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -1,19 +1,26 @@ #!/usr/bin/env bash +set -e + usage() { - echo "Usage: $0 [BuildArch] [LinuxCodeName] [lldbx.y] [--skipunmount] --rootfsdir ]" + echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [--skipunmount] --rootfsdir ]" echo "BuildArch can be: arm(default), armel, arm64, x86" - echo "LinuxCodeName - optional, Code name for Linux, can be: trusty, xenial(default), zesty, bionic, alpine. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." - echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine" + echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine, alpine3.13 or alpine3.14. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." + echo " for FreeBSD can be: freebsd11, freebsd12, freebsd13" + echo " for illumos can be: illumos." + echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD" echo "--skipunmount - optional, will skip the unmount of rootfs folder." + echo "--use-mirror - optional, use mirror URL to fetch resources, when available." exit 1 } -__LinuxCodeName=xenial +__CodeName=xenial __CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) __InitialDir=$PWD __BuildArch=arm +__AlpineArch=armv7 +__QEMUArch=arm __UbuntuArch=armhf __UbuntuRepo="http://ports.ubuntu.com/" __LLDB_Package="liblldb-3.9-dev" @@ -26,7 +33,8 @@ __AlpinePackages="alpine-base" __AlpinePackages+=" build-base" __AlpinePackages+=" linux-headers" __AlpinePackages+=" lldb-dev" -__AlpinePackages+=" llvm-dev" +__AlpinePackages+=" python3" +__AlpinePackages+=" libedit" # symlinks fixer __UbuntuPackages+=" symlinks" @@ -52,13 +60,34 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" +__FreeBSDBase="12.2-RELEASE" +__FreeBSDPkg="1.12.0" +__FreeBSDABI="12" +__FreeBSDPackages="libunwind" +__FreeBSDPackages+=" icu" +__FreeBSDPackages+=" libinotify" +__FreeBSDPackages+=" lttng-ust" +__FreeBSDPackages+=" krb5" +__FreeBSDPackages+=" terminfo-db" + +__IllumosPackages="icu-64.2nb2" +__IllumosPackages+=" mit-krb5-1.16.2nb4" +__IllumosPackages+=" openssl-1.1.1e" +__IllumosPackages+=" zlib-1.2.11" + +# ML.NET dependencies +__UbuntuPackages+=" libomp5" +__UbuntuPackages+=" libomp-dev" + +__UseMirror=0 + __UnprocessedBuildArgs= while :; do if [ $# -le 0 ]; then break fi - lowerI="$(echo $1 | awk '{print tolower($0)}')" + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" case $lowerI in -?|-h|--help) usage @@ -67,7 +96,7 @@ while :; do arm) __BuildArch=arm __UbuntuArch=armhf - __AlpineArch=armhf + __AlpineArch=armv7 __QEMUArch=arm ;; arm64) @@ -80,7 +109,16 @@ while :; do __BuildArch=armel __UbuntuArch=armel __UbuntuRepo="http://ftp.debian.org/debian/" - __LinuxCodeName=jessie + __CodeName=jessie + ;; + s390x) + __BuildArch=s390x + __UbuntuArch=s390x + __UbuntuRepo="http://ports.ubuntu.com/ubuntu-ports/" + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libunwind8-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp5//') + unset __LLDB_Package ;; x86) __BuildArch=x86 @@ -108,53 +146,77 @@ while :; do no-lldb) unset __LLDB_Package ;; - trusty) # Ubuntu 14.04 - if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=trusty - fi - ;; xenial) # Ubuntu 16.04 - if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=xenial + if [ "$__CodeName" != "jessie" ]; then + __CodeName=xenial fi ;; zesty) # Ubuntu 17.04 - if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=zesty + if [ "$__CodeName" != "jessie" ]; then + __CodeName=zesty fi ;; bionic) # Ubuntu 18.04 - if [ "$__LinuxCodeName" != "jessie" ]; then - __LinuxCodeName=bionic + if [ "$__CodeName" != "jessie" ]; then + __CodeName=bionic fi ;; jessie) # Debian 8 - __LinuxCodeName=jessie + __CodeName=jessie __UbuntuRepo="http://ftp.debian.org/debian/" ;; stretch) # Debian 9 - __LinuxCodeName=stretch + __CodeName=stretch __UbuntuRepo="http://ftp.debian.org/debian/" __LLDB_Package="liblldb-6.0-dev" ;; buster) # Debian 10 - __LinuxCodeName=buster + __CodeName=buster __UbuntuRepo="http://ftp.debian.org/debian/" __LLDB_Package="liblldb-6.0-dev" ;; tizen) - if [ "$__BuildArch" != "armel" ]; then - echo "Tizen is available only for armel." + if [ "$__BuildArch" != "armel" ] && [ "$__BuildArch" != "arm64" ]; then + echo "Tizen is available only for armel and arm64." usage; exit 1; fi - __LinuxCodeName= + __CodeName= __UbuntuRepo= __Tizen=tizen ;; - alpine) - __LinuxCodeName=alpine + alpine|alpine3.13) + __CodeName=alpine + __UbuntuRepo= + __AlpineVersion=3.13 + __AlpinePackages+=" llvm10-libs" + ;; + alpine3.14) + __CodeName=alpine __UbuntuRepo= + __AlpineVersion=3.14 + __AlpinePackages+=" llvm11-libs" + ;; + freebsd11) + __FreeBSDBase="11.3-RELEASE" + __FreeBSDABI="11" + ;& + freebsd12) + __CodeName=freebsd + __BuildArch=x64 + __SkipUnmount=1 + ;; + freebsd13) + __CodeName=freebsd + __FreeBSDBase="13.0-RELEASE" + __FreeBSDABI="13" + __BuildArch=x64 + __SkipUnmount=1 + ;; + illumos) + __CodeName=illumos + __BuildArch=x64 + __SkipUnmount=1 ;; --skipunmount) __SkipUnmount=1 @@ -163,6 +225,9 @@ while :; do shift __RootfsDir=$1 ;; + --use-mirror) + __UseMirror=1 + ;; *) __UnprocessedBuildArgs="$__UnprocessedBuildArgs $1" ;; @@ -186,46 +251,110 @@ fi if [ -d "$__RootfsDir" ]; then if [ $__SkipUnmount == 0 ]; then - umount $__RootfsDir/* + umount $__RootfsDir/* || true fi rm -rf $__RootfsDir fi -if [[ "$__LinuxCodeName" == "alpine" ]]; then +mkdir -p $__RootfsDir +__RootfsDir="$( cd "$__RootfsDir" && pwd )" + +if [[ "$__CodeName" == "alpine" ]]; then __ApkToolsVersion=2.9.1 - __AlpineVersion=3.7 __ApkToolsDir=$(mktemp -d) wget https://github.com/alpinelinux/apk-tools/releases/download/v$__ApkToolsVersion/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -P $__ApkToolsDir tar -xf $__ApkToolsDir/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -C $__ApkToolsDir mkdir -p $__RootfsDir/usr/bin cp -v /usr/bin/qemu-$__QEMUArch-static $__RootfsDir/usr/bin + $__ApkToolsDir/apk-tools-$__ApkToolsVersion/apk \ -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/main \ -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/community \ - -X http://dl-cdn.alpinelinux.org/alpine/edge/testing \ - -X http://dl-cdn.alpinelinux.org/alpine/edge/main \ -U --allow-untrusted --root $__RootfsDir --arch $__AlpineArch --initdb \ add $__AlpinePackages + rm -r $__ApkToolsDir -elif [[ -n $__LinuxCodeName ]]; then - qemu-debootstrap --arch $__UbuntuArch $__LinuxCodeName $__RootfsDir $__UbuntuRepo - cp $__CrossDir/$__BuildArch/sources.list.$__LinuxCodeName $__RootfsDir/etc/apt/sources.list +elif [[ "$__CodeName" == "freebsd" ]]; then + mkdir -p $__RootfsDir/usr/local/etc + JOBS="$(getconf _NPROCESSORS_ONLN)" + wget -O - https://download.freebsd.org/ftp/releases/amd64/${__FreeBSDBase}/base.txz | tar -C $__RootfsDir -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version + echo "ABI = \"FreeBSD:${__FreeBSDABI}:amd64\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > ${__RootfsDir}/usr/local/etc/pkg.conf + echo "FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > ${__RootfsDir}/etc/pkg/FreeBSD.conf + mkdir -p $__RootfsDir/tmp + # get and build package manager + wget -O - https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz | tar -C $__RootfsDir/tmp -zxf - + cd $__RootfsDir/tmp/pkg-${__FreeBSDPkg} + # needed for install to succeed + mkdir -p $__RootfsDir/host/etc + ./autogen.sh && ./configure --prefix=$__RootfsDir/host && make -j "$JOBS" && make install + rm -rf $__RootfsDir/tmp/pkg-${__FreeBSDPkg} + # install packages we need. + INSTALL_AS_USER=$(whoami) $__RootfsDir/host/sbin/pkg -r $__RootfsDir -C $__RootfsDir/usr/local/etc/pkg.conf update + INSTALL_AS_USER=$(whoami) $__RootfsDir/host/sbin/pkg -r $__RootfsDir -C $__RootfsDir/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages +elif [[ "$__CodeName" == "illumos" ]]; then + mkdir "$__RootfsDir/tmp" + pushd "$__RootfsDir/tmp" + JOBS="$(getconf _NPROCESSORS_ONLN)" + echo "Downloading sysroot." + wget -O - https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C "$__RootfsDir" -xzf - + echo "Building binutils. Please wait.." + wget -O - https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2 | tar -xjf - + mkdir build-binutils && cd build-binutils + ../binutils-2.33.1/configure --prefix="$__RootfsDir" --target="x86_64-sun-solaris2.10" --program-prefix="x86_64-illumos-" --with-sysroot="$__RootfsDir" + make -j "$JOBS" && make install && cd .. + echo "Building gcc. Please wait.." + wget -O - https://ftp.gnu.org/gnu/gcc/gcc-8.4.0/gcc-8.4.0.tar.xz | tar -xJf - + CFLAGS="-fPIC" + CXXFLAGS="-fPIC" + CXXFLAGS_FOR_TARGET="-fPIC" + CFLAGS_FOR_TARGET="-fPIC" + export CFLAGS CXXFLAGS CXXFLAGS_FOR_TARGET CFLAGS_FOR_TARGET + mkdir build-gcc && cd build-gcc + ../gcc-8.4.0/configure --prefix="$__RootfsDir" --target="x86_64-sun-solaris2.10" --program-prefix="x86_64-illumos-" --with-sysroot="$__RootfsDir" --with-gnu-as \ + --with-gnu-ld --disable-nls --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libcilkrts --disable-libada --disable-libsanitizer \ + --disable-libquadmath-support --disable-shared --enable-tls + make -j "$JOBS" && make install && cd .. + BaseUrl=https://pkgsrc.joyent.com + if [[ "$__UseMirror" == 1 ]]; then + BaseUrl=http://pkgsrc.smartos.skylime.net + fi + BaseUrl="$BaseUrl"/packages/SmartOS/2020Q1/x86_64/All + echo "Downloading dependencies." + read -ra array <<<"$__IllumosPackages" + for package in "${array[@]}"; do + echo "Installing $package..." + wget "$BaseUrl"/"$package".tgz + ar -x "$package".tgz + tar --skip-old-files -xzf "$package".tmp.tgz -C "$__RootfsDir" 2>/dev/null + done + echo "Cleaning up temporary files." + popd + rm -rf "$__RootfsDir"/{tmp,+*} + mkdir -p "$__RootfsDir"/usr/include/net + mkdir -p "$__RootfsDir"/usr/include/netpacket + wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h + wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h + wget -P "$__RootfsDir"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h + wget -P "$__RootfsDir"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h +elif [[ -n $__CodeName ]]; then + qemu-debootstrap --arch $__UbuntuArch $__CodeName $__RootfsDir $__UbuntuRepo + cp $__CrossDir/$__BuildArch/sources.list.$__CodeName $__RootfsDir/etc/apt/sources.list chroot $__RootfsDir apt-get update chroot $__RootfsDir apt-get -f -y install chroot $__RootfsDir apt-get -y install $__UbuntuPackages chroot $__RootfsDir symlinks -cr /usr + chroot $__RootfsDir apt-get clean if [ $__SkipUnmount == 0 ]; then - umount $__RootfsDir/* + umount $__RootfsDir/* || true fi - if [[ "$__BuildArch" == "arm" && "$__LinuxCodeName" == "trusty" ]]; then + if [[ "$__BuildArch" == "armel" && "$__CodeName" == "jessie" ]]; then pushd $__RootfsDir - patch -p1 < $__CrossDir/$__BuildArch/trusty.patch - patch -p1 < $__CrossDir/$__BuildArch/trusty-lttng-2.4.patch + patch -p1 < $__CrossDir/$__BuildArch/armel.jessie.patch popd fi -elif [ "$__Tizen" == "tizen" ]; then +elif [[ "$__Tizen" == "tizen" ]]; then ROOTFS_DIR=$__RootfsDir $__CrossDir/$__BuildArch/tizen-build-rootfs.sh else echo "Unsupported target platform." diff --git a/eng/common/cross/s390x/sources.list.bionic b/eng/common/cross/s390x/sources.list.bionic new file mode 100644 index 00000000000..21095574095 --- /dev/null +++ b/eng/common/cross/s390x/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 071d4112419..6501c3a955f 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -1,18 +1,27 @@ set(CROSS_ROOTFS $ENV{ROOTFS_DIR}) set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH}) -set(CMAKE_SYSTEM_NAME Linux) +if(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version) + set(CMAKE_SYSTEM_NAME FreeBSD) +elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc) + set(CMAKE_SYSTEM_NAME SunOS) + set(ILLUMOS 1) +else() + set(CMAKE_SYSTEM_NAME Linux) +endif() set(CMAKE_SYSTEM_VERSION 1) if(TARGET_ARCH_NAME STREQUAL "armel") set(CMAKE_SYSTEM_PROCESSOR armv7l) set(TOOLCHAIN "arm-linux-gnueabi") if("$ENV{__DistroRid}" MATCHES "tizen.*") - set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/6.2.1") + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0") endif() elseif(TARGET_ARCH_NAME STREQUAL "arm") set(CMAKE_SYSTEM_PROCESSOR armv7l) - if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf) + set(TOOLCHAIN "armv7-alpine-linux-musleabihf") + elseif(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf) set(TOOLCHAIN "armv6-alpine-linux-musleabihf") else() set(TOOLCHAIN "arm-linux-gnueabihf") @@ -24,65 +33,151 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64") else() set(TOOLCHAIN "aarch64-linux-gnu") endif() + if("$ENV{__DistroRid}" MATCHES "tizen.*") + set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu/9.2.0") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "s390x") + set(CMAKE_SYSTEM_PROCESSOR s390x) + set(TOOLCHAIN "s390x-linux-gnu") elseif(TARGET_ARCH_NAME STREQUAL "x86") set(CMAKE_SYSTEM_PROCESSOR i686) set(TOOLCHAIN "i686-linux-gnu") +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + set(triple "x86_64-unknown-freebsd12") +elseif (ILLUMOS) + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + set(TOOLCHAIN "x86_64-illumos") else() - message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64 and x86 are supported!") + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64, s390x and x86 are supported!") +endif() + +if(DEFINED ENV{TOOLCHAIN}) + set(TOOLCHAIN $ENV{TOOLCHAIN}) endif() # Specify include paths -if(TARGET_ARCH_NAME STREQUAL "armel") - if(DEFINED TIZEN_TOOLCHAIN) +if(DEFINED TIZEN_TOOLCHAIN) + if(TARGET_ARCH_NAME STREQUAL "armel") include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi) endif() + if(TARGET_ARCH_NAME STREQUAL "arm64") + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/aarch64-tizen-linux-gnu) + endif() endif() -# add_compile_param - adds only new options without duplicates. -# arg0 - list with result options, arg1 - list with new options. -# arg2 - optional argument, quick summary string for optional using CACHE FORCE mode. -macro(add_compile_param) - if(NOT ${ARGC} MATCHES "^(2|3)$") - message(FATAL_ERROR "Wrong using add_compile_param! Two or three parameters must be given! See add_compile_param description.") - endif() - foreach(OPTION ${ARGV1}) - if(NOT ${ARGV0} MATCHES "${OPTION}($| )") - set(${ARGV0} "${${ARGV0}} ${OPTION}") - if(${ARGC} EQUAL "3") # CACHE FORCE mode - set(${ARGV0} "${${ARGV0}}" CACHE STRING "${ARGV2}" FORCE) - endif() +if("$ENV{__DistroRid}" MATCHES "android.*") + if(TARGET_ARCH_NAME STREQUAL "arm") + set(ANDROID_ABI armeabi-v7a) + elseif(TARGET_ARCH_NAME STREQUAL "arm64") + set(ANDROID_ABI arm64-v8a) endif() - endforeach() -endmacro() + + # extract platform number required by the NDK's toolchain + string(REGEX REPLACE ".*\\.([0-9]+)-.*" "\\1" ANDROID_PLATFORM "$ENV{__DistroRid}") + + set(ANDROID_TOOLCHAIN clang) + set(FEATURE_EVENT_TRACE 0) # disable event trace as there is no lttng-ust package in termux repository + set(CMAKE_SYSTEM_LIBRARY_PATH "${CROSS_ROOTFS}/usr/lib") + set(CMAKE_SYSTEM_INCLUDE_PATH "${CROSS_ROOTFS}/usr/include") + + # include official NDK toolchain script + include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake) +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + # we cross-compile by instructing clang + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + set(CMAKE_ASM_COMPILER_TARGET ${triple}) + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=lld") +elseif(ILLUMOS) + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + + include_directories(SYSTEM ${CROSS_ROOTFS}/include) + + set(TOOLSET_PREFIX ${TOOLCHAIN}-) + function(locate_toolchain_exec exec var) + string(TOUPPER ${exec} EXEC_UPPERCASE) + if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "") + set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE) + return() + endif() + + find_program(EXEC_LOCATION_${exec} + NAMES + "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" + "${TOOLSET_PREFIX}${exec}") + + if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND") + message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.") + endif() + set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE) + endfunction() + + set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}") + + locate_toolchain_exec(gcc CMAKE_C_COMPILER) + locate_toolchain_exec(g++ CMAKE_CXX_COMPILER) + + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") +else() + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + + set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") + set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") + set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") +endif() # Specify link flags -add_compile_param(CROSS_LINK_FLAGS "--sysroot=${CROSS_ROOTFS}") -add_compile_param(CROSS_LINK_FLAGS "--gcc-toolchain=${CROSS_ROOTFS}/usr") -add_compile_param(CROSS_LINK_FLAGS "--target=${TOOLCHAIN}") -add_compile_param(CROSS_LINK_FLAGS "-fuse-ld=gold") + +function(add_toolchain_linker_flag Flag) + set(Config "${ARGV1}") + set(CONFIG_SUFFIX "") + if (NOT Config STREQUAL "") + set(CONFIG_SUFFIX "_${Config}") + endif() + set("CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT" "${CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}" PARENT_SCOPE) + set("CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT" "${CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}" PARENT_SCOPE) +endfunction() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib/${TOOLCHAIN}") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}") +endif() if(TARGET_ARCH_NAME STREQUAL "armel") if(DEFINED TIZEN_TOOLCHAIN) # For Tizen only - add_compile_param(CROSS_LINK_FLAGS "-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") - add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/lib") - add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/usr/lib") - add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm64") + if(DEFINED TIZEN_TOOLCHAIN) # For Tizen only + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") - add_compile_param(CROSS_LINK_FLAGS "-m32") + add_toolchain_linker_flag(-m32) +elseif(ILLUMOS) + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/amd64/lib") endif() -add_compile_param(CMAKE_EXE_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") -add_compile_param(CMAKE_SHARED_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") -add_compile_param(CMAKE_MODULE_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") - # Specify compile options -add_compile_options("--sysroot=${CROSS_ROOTFS}") -add_compile_options("--target=${TOOLCHAIN}") -add_compile_options("--gcc-toolchain=${CROSS_ROOTFS}/usr") -if(TARGET_ARCH_NAME MATCHES "^(arm|armel|arm64)$") +if((TARGET_ARCH_NAME MATCHES "^(arm|armel|arm64|s390x)$" AND NOT "$ENV{__DistroRid}" MATCHES "android.*") OR ILLUMOS) set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) @@ -90,20 +185,33 @@ endif() if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") add_compile_options(-mthumb) - add_compile_options(-mfpu=vfpv3) + if (NOT DEFINED CLR_ARM_FPU_TYPE) + set (CLR_ARM_FPU_TYPE vfpv3) + endif (NOT DEFINED CLR_ARM_FPU_TYPE) + + add_compile_options (-mfpu=${CLR_ARM_FPU_TYPE}) + if (NOT DEFINED CLR_ARM_FPU_CAPABILITY) + set (CLR_ARM_FPU_CAPABILITY 0x7) + endif (NOT DEFINED CLR_ARM_FPU_CAPABILITY) + + add_definitions (-DCLR_ARM_FPU_CAPABILITY=${CLR_ARM_FPU_CAPABILITY}) + if(TARGET_ARCH_NAME STREQUAL "armel") add_compile_options(-mfloat-abi=softfp) - if(DEFINED TIZEN_TOOLCHAIN) - add_compile_options(-Wno-deprecated-declarations) # compile-time option - add_compile_options(-D__extern_always_inline=inline) # compile-time option - endif() endif() elseif(TARGET_ARCH_NAME STREQUAL "x86") add_compile_options(-m32) add_compile_options(-Wno-error=unused-command-line-argument) endif() -# Set LLDB include and library paths +if(DEFINED TIZEN_TOOLCHAIN) + if(TARGET_ARCH_NAME MATCHES "^(armel|arm64)$") + add_compile_options(-Wno-deprecated-declarations) # compile-time option + add_compile_options(-D__extern_always_inline=inline) # compile-time option + endif() +endif() + +# Set LLDB include and library paths for builds that need lldb. if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") if(TARGET_ARCH_NAME STREQUAL "x86") set(LLVM_CROSS_DIR "$ENV{LLVM_CROSS_HOME}") @@ -131,7 +239,6 @@ if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") endif() endif() -set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/eng/common/cross/x86/sources.list.trusty b/eng/common/cross/x86/sources.list.trusty deleted file mode 100644 index 9b3085436e9..00000000000 --- a/eng/common/cross/x86/sources.list.trusty +++ /dev/null @@ -1,11 +0,0 @@ -deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe -deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe - -deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted -deb-src http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted - -deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse -deb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 index 46d175fdfdc..435e7641341 100644 --- a/eng/common/darc-init.ps1 +++ b/eng/common/darc-init.ps1 @@ -1,13 +1,14 @@ param ( $darcVersion = $null, - $versionEndpoint = "https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16", - $verbosity = "m" + $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16', + $verbosity = 'minimal', + $toolpath = $null ) . $PSScriptRoot\tools.ps1 -function InstallDarcCli ($darcVersion) { - $darcCliPackageName = "microsoft.dotnet.darc" +function InstallDarcCli ($darcVersion, $toolpath) { + $darcCliPackageName = 'microsoft.dotnet.darc' $dotnetRoot = InitializeDotNetCli -install:$true $dotnet = "$dotnetRoot\dotnet.exe" @@ -23,11 +24,24 @@ function InstallDarcCli ($darcVersion) { $darcVersion = $(Invoke-WebRequest -Uri $versionEndpoint -UseBasicParsing).Content } - $arcadeServicesSource = 'https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json' + $arcadeServicesSource = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' Write-Host "Installing Darc CLI version $darcVersion..." - Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." - & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g + Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.' + if (-not $toolpath) { + Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity -g" + & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g + }else { + Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity --tool-path '$toolpath'" + & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath" + } } -InstallDarcCli $darcVersion +try { + InstallDarcCli $darcVersion $toolpath +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Darc' -Message $_ + ExitWithExitCode 1 +} \ No newline at end of file diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index 242429bca65..39abdbecdcf 100755 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -2,11 +2,11 @@ source="${BASH_SOURCE[0]}" darcVersion='' -versionEndpoint="https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16" -verbosity=m +versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16' +verbosity='minimal' while [[ $# > 0 ]]; do - opt="$(echo "$1" | awk '{print tolower($0)}')" + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in --darcversion) darcVersion=$2 @@ -20,6 +20,10 @@ while [[ $# > 0 ]]; do verbosity=$2 shift ;; + --toolpath) + toolpath=$2 + shift + ;; *) echo "Invalid argument: $1" usage @@ -52,17 +56,27 @@ function InstallDarcCli { InitializeDotNetCli local dotnet_root=$_InitializeDotNetCli - local uninstall_command=`$dotnet_root/dotnet tool uninstall $darc_cli_package_name -g` - local tool_list=$($dotnet_root/dotnet tool list -g) - if [[ $tool_list = *$darc_cli_package_name* ]]; then - echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g) + if [ -z "$toolpath" ]; then + local tool_list=$($dotnet_root/dotnet tool list -g) + if [[ $tool_list = *$darc_cli_package_name* ]]; then + echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g) + fi + else + local tool_list=$($dotnet_root/dotnet tool list --tool-path "$toolpath") + if [[ $tool_list = *$darc_cli_package_name* ]]; then + echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name --tool-path "$toolpath") + fi fi - local arcadeServicesSource="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" + local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" echo "Installing Darc CLI version $darcVersion..." echo "You may need to restart your command shell if this is the first dotnet tool you have installed." - echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g) + if [ -z "$toolpath" ]; then + echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g) + else + echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath") + fi } InstallDarcCli diff --git a/eng/common/dotnet-install.ps1 b/eng/common/dotnet-install.ps1 index ec3e739fe83..811f0f717f7 100644 --- a/eng/common/dotnet-install.ps1 +++ b/eng/common/dotnet-install.ps1 @@ -1,28 +1,27 @@ [CmdletBinding(PositionalBinding=$false)] Param( - [string] $verbosity = "minimal", - [string] $architecture = "", - [string] $version = "Latest", - [string] $runtime = "dotnet", - [string] $RuntimeSourceFeed = "", - [string] $RuntimeSourceFeedKey = "" + [string] $verbosity = 'minimal', + [string] $architecture = '', + [string] $version = 'Latest', + [string] $runtime = 'dotnet', + [string] $RuntimeSourceFeed = '', + [string] $RuntimeSourceFeedKey = '' ) . $PSScriptRoot\tools.ps1 -$dotnetRoot = Join-Path $RepoRoot ".dotnet" +$dotnetRoot = Join-Path $RepoRoot '.dotnet' $installdir = $dotnetRoot try { - if ($architecture -and $architecture.Trim() -eq "x86") { - $installdir = Join-Path $installdir "x86" + if ($architecture -and $architecture.Trim() -eq 'x86') { + $installdir = Join-Path $installdir 'x86' } - InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey -} + InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey +} catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh index d259a274c78..fdfeea66e7d 100755 --- a/eng/common/dotnet-install.sh +++ b/eng/common/dotnet-install.sh @@ -11,13 +11,15 @@ while [[ -h "$source" ]]; do done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" +. "$scriptroot/tools.sh" + version='Latest' architecture='' runtime='dotnet' runtimeSourceFeed='' runtimeSourceFeedKey='' while [[ $# > 0 ]]; do - opt="$(echo "$1" | awk '{print tolower($0)}')" + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in -version|-v) shift @@ -40,18 +42,42 @@ while [[ $# > 0 ]]; do runtimeSourceFeedKey="$1" ;; *) - echo "Invalid argument: $1" + Write-PipelineTelemetryError -Category 'Build' -Message "Invalid argument: $1" exit 1 ;; esac shift done -. "$scriptroot/tools.sh" -dotnetRoot="$repo_root/.dotnet" +# Use uname to determine what the CPU is, see https://en.wikipedia.org/wiki/Uname#Examples +cpuname=$(uname -m) +case $cpuname in + aarch64) + buildarch=arm64 + ;; + amd64|x86_64) + buildarch=x64 + ;; + armv*l) + buildarch=arm + ;; + i686) + buildarch=x86 + ;; + *) + echo "Unknown CPU $cpuname detected, treating it as x64" + buildarch=x64 + ;; +esac + +dotnetRoot="${repo_root}.dotnet" +if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then + dotnetRoot="$dotnetRoot/$architecture" +fi + InstallDotNet $dotnetRoot $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || { local exit_code=$? - echo "dotnet-install.sh failed (exit code '$exit_code')." >&2 + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2 ExitWithExitCode $exit_code } diff --git a/eng/common/enable-cross-org-publishing.ps1 b/eng/common/enable-cross-org-publishing.ps1 index eccbf9f1b16..da09da4f1fc 100644 --- a/eng/common/enable-cross-org-publishing.ps1 +++ b/eng/common/enable-cross-org-publishing.ps1 @@ -2,5 +2,12 @@ param( [string] $token ) -Write-Host "##vso[task.setvariable variable=VSS_NUGET_ACCESSTOKEN]$token" -Write-Host "##vso[task.setvariable variable=VSS_NUGET_URI_PREFIXES]https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/" + +. $PSScriptRoot\pipeline-logging-functions.ps1 + +# Write-PipelineSetVariable will no-op if a variable named $ci is not defined +# Since this script is only ever called in AzDO builds, just universally set it +$ci = $true + +Write-PipelineSetVariable -Name 'VSS_NUGET_ACCESSTOKEN' -Value $token -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'VSS_NUGET_URI_PREFIXES' -Value 'https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/' -IsMultiJobVariable $false diff --git a/eng/common/generate-graph-files.ps1 b/eng/common/generate-graph-files.ps1 index b056e4c1ac2..0728b1a8b57 100644 --- a/eng/common/generate-graph-files.ps1 +++ b/eng/common/generate-graph-files.ps1 @@ -3,39 +3,39 @@ Param( [Parameter(Mandatory=$true)][string] $gitHubPat, # GitHub personal access token from https://github.com/settings/tokens (no auth scopes needed) [Parameter(Mandatory=$true)][string] $azdoPat, # Azure Dev Ops tokens from https://dev.azure.com/dnceng/_details/security/tokens (code read scope needed) [Parameter(Mandatory=$true)][string] $outputFolder, # Where the graphviz.txt file will be created - [string] $darcVersion = '1.1.0-beta.19175.6', # darc's version + [string] $darcVersion, # darc's version [string] $graphvizVersion = '2.38', # GraphViz version [switch] $includeToolset # Whether the graph should include toolset dependencies or not. i.e. arcade, optimization. For more about # toolset dependencies see https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md#toolset-vs-product-dependencies ) -$ErrorActionPreference = "Stop" -. $PSScriptRoot\tools.ps1 - -Import-Module -Name (Join-Path $PSScriptRoot "native\CommonLibrary.psm1") - function CheckExitCode ([string]$stage) { $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { - Write-Host "Something failed in stage: '$stage'. Check for errors above. Exiting now..." + Write-PipelineTelemetryError -Category 'Arcade' -Message "Something failed in stage: '$stage'. Check for errors above. Exiting now..." ExitWithExitCode $exitCode } } try { + $ErrorActionPreference = 'Stop' + . $PSScriptRoot\tools.ps1 + + Import-Module -Name (Join-Path $PSScriptRoot 'native\CommonLibrary.psm1') + Push-Location $PSScriptRoot - Write-Host "Installing darc..." + Write-Host 'Installing darc...' . .\darc-init.ps1 -darcVersion $darcVersion - CheckExitCode "Running darc-init" + CheckExitCode 'Running darc-init' - $engCommonBaseDir = Join-Path $PSScriptRoot "native\" + $engCommonBaseDir = Join-Path $PSScriptRoot 'native\' $graphvizInstallDir = CommonLibrary\Get-NativeInstallDirectory - $nativeToolBaseUri = "https://netcorenativeassets.blob.core.windows.net/resource-packages/external" - $installBin = Join-Path $graphvizInstallDir "bin" + $nativeToolBaseUri = 'https://netcorenativeassets.blob.core.windows.net/resource-packages/external' + $installBin = Join-Path $graphvizInstallDir 'bin' - Write-Host "Installing dot..." + Write-Host 'Installing dot...' .\native\install-tool.ps1 -ToolName graphviz -InstallPath $installBin -BaseUri $nativeToolBaseUri -CommonLibraryDirectory $engCommonBaseDir -Version $graphvizVersion -Verbose $darcExe = "$env:USERPROFILE\.dotnet\tools" @@ -51,37 +51,36 @@ try { $graphVizImageFilePath = "$outputFolder\graph.png" $normalGraphFilePath = "$outputFolder\graph-full.txt" $flatGraphFilePath = "$outputFolder\graph-flat.txt" - $baseOptions = @( "--github-pat", "$gitHubPat", "--azdev-pat", "$azdoPat", "--password", "$barToken" ) + $baseOptions = @( '--github-pat', "$gitHubPat", '--azdev-pat', "$azdoPat", '--password', "$barToken" ) if ($includeToolset) { - Write-Host "Toolsets will be included in the graph..." - $baseOptions += @( "--include-toolset" ) + Write-Host 'Toolsets will be included in the graph...' + $baseOptions += @( '--include-toolset' ) } - Write-Host "Generating standard dependency graph..." + Write-Host 'Generating standard dependency graph...' & "$darcExe" get-dependency-graph @baseOptions --output-file $normalGraphFilePath - CheckExitCode "Generating normal dependency graph" + CheckExitCode 'Generating normal dependency graph' - Write-Host "Generating flat dependency graph and graphviz file..." + Write-Host 'Generating flat dependency graph and graphviz file...' & "$darcExe" get-dependency-graph @baseOptions --flat --coherency --graphviz $graphVizFilePath --output-file $flatGraphFilePath - CheckExitCode "Generating flat and graphviz dependency graph" + CheckExitCode 'Generating flat and graphviz dependency graph' Write-Host "Generating graph image $graphVizFilePath" $dotFilePath = Join-Path $installBin "graphviz\$graphvizVersion\release\bin\dot.exe" & "$dotFilePath" -Tpng -o"$graphVizImageFilePath" "$graphVizFilePath" - CheckExitCode "Generating graphviz image" + CheckExitCode 'Generating graphviz image' Write-Host "'$graphVizFilePath', '$flatGraphFilePath', '$normalGraphFilePath' and '$graphVizImageFilePath' created!" } catch { if (!$includeToolset) { - Write-Host "This might be a toolset repo which includes only toolset dependencies. " -NoNewline -ForegroundColor Yellow - Write-Host "Since -includeToolset is not set there is no graph to create. Include -includeToolset and try again..." -ForegroundColor Yellow + Write-Host 'This might be a toolset repo which includes only toolset dependencies. ' -NoNewline -ForegroundColor Yellow + Write-Host 'Since -includeToolset is not set there is no graph to create. Include -includeToolset and try again...' -ForegroundColor Yellow } - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Arcade' -Message $_ ExitWithExitCode 1 } finally { - Pop-Location + Pop-Location } \ No newline at end of file diff --git a/eng/common/generate-locproject.ps1 b/eng/common/generate-locproject.ps1 new file mode 100644 index 00000000000..25e97ac0077 --- /dev/null +++ b/eng/common/generate-locproject.ps1 @@ -0,0 +1,117 @@ +Param( + [Parameter(Mandatory=$true)][string] $SourcesDirectory, # Directory where source files live; if using a Localize directory it should live in here + [string] $LanguageSet = 'VS_Main_Languages', # Language set to be used in the LocProject.json + [switch] $UseCheckedInLocProjectJson, # When set, generates a LocProject.json and compares it to one that already exists in the repo; otherwise just generates one + [switch] $CreateNeutralXlfs # Creates neutral xlf files. Only set to false when running locally +) + +# Generates LocProject.json files for the OneLocBuild task. OneLocBuildTask is described here: +# https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop" +. $PSScriptRoot\tools.ps1 + +Import-Module -Name (Join-Path $PSScriptRoot 'native\CommonLibrary.psm1') + +$exclusionsFilePath = "$SourcesDirectory\eng\Localize\LocExclusions.json" +$exclusions = @{ Exclusions = @() } +if (Test-Path -Path $exclusionsFilePath) +{ + $exclusions = Get-Content "$exclusionsFilePath" | ConvertFrom-Json +} + +Push-Location "$SourcesDirectory" # push location for Resolve-Path -Relative to work + +# Template files +$jsonFiles = @() +$jsonTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\.template\.config\\localize\\.+\.en\.json" } # .NET templating pattern +$jsonTemplateFiles | ForEach-Object { + $null = $_.Name -Match "(.+)\.[\w-]+\.json" # matches '[filename].[langcode].json + + $destinationFile = "$($_.Directory.FullName)\$($Matches.1).json" + $jsonFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru +} + +$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern + +$xlfFiles = @() + +$allXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.xlf" +$langXlfFiles = @() +if ($allXlfFiles) { + $null = $allXlfFiles[0].FullName -Match "\.([\w-]+)\.xlf" # matches '[langcode].xlf' + $firstLangCode = $Matches.1 + $langXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.$firstLangCode.xlf" +} +$langXlfFiles | ForEach-Object { + $null = $_.Name -Match "(.+)\.[\w-]+\.xlf" # matches '[filename].[langcode].xlf + + $destinationFile = "$($_.Directory.FullName)\$($Matches.1).xlf" + $xlfFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru +} + +$locFiles = $jsonFiles + $jsonWinformsTemplateFiles + $xlfFiles + +$locJson = @{ + Projects = @( + @{ + LanguageSet = $LanguageSet + LocItems = @( + $locFiles | ForEach-Object { + $outputPath = "$(($_.DirectoryName | Resolve-Path -Relative) + "\")" + $continue = $true + foreach ($exclusion in $exclusions.Exclusions) { + if ($outputPath.Contains($exclusion)) + { + $continue = $false + } + } + $sourceFile = ($_.FullName | Resolve-Path -Relative) + if (!$CreateNeutralXlfs -and $_.Extension -eq '.xlf') { + Remove-Item -Path $sourceFile + } + if ($continue) + { + if ($_.Directory.Name -eq 'en' -and $_.Extension -eq '.json') { + return @{ + SourceFile = $sourceFile + CopyOption = "LangIDOnPath" + OutputPath = "$($_.Directory.Parent.FullName | Resolve-Path -Relative)\" + } + } + else { + return @{ + SourceFile = $sourceFile + CopyOption = "LangIDOnName" + OutputPath = $outputPath + } + } + } + } + ) + } + ) +} + +$json = ConvertTo-Json $locJson -Depth 5 +Write-Host "LocProject.json generated:`n`n$json`n`n" +Pop-Location + +if (!$UseCheckedInLocProjectJson) { + New-Item "$SourcesDirectory\eng\Localize\LocProject.json" -Force # Need this to make sure the Localize directory is created + Set-Content "$SourcesDirectory\eng\Localize\LocProject.json" $json +} +else { + New-Item "$SourcesDirectory\eng\Localize\LocProject-generated.json" -Force # Need this to make sure the Localize directory is created + Set-Content "$SourcesDirectory\eng\Localize\LocProject-generated.json" $json + + if ((Get-FileHash "$SourcesDirectory\eng\Localize\LocProject-generated.json").Hash -ne (Get-FileHash "$SourcesDirectory\eng\Localize\LocProject.json").Hash) { + Write-PipelineTelemetryError -Category "OneLocBuild" -Message "Existing LocProject.json differs from generated LocProject.json. Download LocProject-generated.json and compare them." + + exit 1 + } + else { + Write-Host "Generated LocProject.json and current LocProject.json are identical." + } +} \ No newline at end of file diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1 index 8cf18bcfeba..db830c00a6f 100644 --- a/eng/common/init-tools-native.ps1 +++ b/eng/common/init-tools-native.ps1 @@ -35,7 +35,7 @@ File path to global.json file #> [CmdletBinding(PositionalBinding=$false)] Param ( - [string] $BaseUri = "https://netcorenativeassets.blob.core.windows.net/resource-packages/external", + [string] $BaseUri = 'https://netcorenativeassets.blob.core.windows.net/resource-packages/external', [string] $InstallDirectory, [switch] $Clean = $False, [switch] $Force = $False, @@ -45,26 +45,27 @@ Param ( ) if (!$GlobalJsonFile) { - $GlobalJsonFile = Join-Path (Get-Item $PSScriptRoot).Parent.Parent.FullName "global.json" + $GlobalJsonFile = Join-Path (Get-Item $PSScriptRoot).Parent.Parent.FullName 'global.json' } Set-StrictMode -version 2.0 -$ErrorActionPreference="Stop" +$ErrorActionPreference='Stop' -Import-Module -Name (Join-Path $PSScriptRoot "native\CommonLibrary.psm1") +. $PSScriptRoot\pipeline-logging-functions.ps1 +Import-Module -Name (Join-Path $PSScriptRoot 'native\CommonLibrary.psm1') try { # Define verbose switch if undefined - $Verbose = $VerbosePreference -Eq "Continue" + $Verbose = $VerbosePreference -Eq 'Continue' - $EngCommonBaseDir = Join-Path $PSScriptRoot "native\" + $EngCommonBaseDir = Join-Path $PSScriptRoot 'native\' $NativeBaseDir = $InstallDirectory if (!$NativeBaseDir) { $NativeBaseDir = CommonLibrary\Get-NativeInstallDirectory } $Env:CommonLibrary_NativeInstallDir = $NativeBaseDir - $InstallBin = Join-Path $NativeBaseDir "bin" - $InstallerPath = Join-Path $EngCommonBaseDir "install-tool.ps1" + $InstallBin = Join-Path $NativeBaseDir 'bin' + $InstallerPath = Join-Path $EngCommonBaseDir 'install-tool.ps1' # Process tools list Write-Host "Processing $GlobalJsonFile" @@ -74,7 +75,7 @@ try { } $NativeTools = Get-Content($GlobalJsonFile) -Raw | ConvertFrom-Json | - Select-Object -Expand "native-tools" -ErrorAction SilentlyContinue + Select-Object -Expand 'native-tools' -ErrorAction SilentlyContinue if ($NativeTools) { $NativeTools.PSObject.Properties | ForEach-Object { $ToolName = $_.Name @@ -112,18 +113,21 @@ try { } $toolInstallationFailure = $true } else { - Write-Error $errMsg + # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482 + Write-Host $errMsg exit 1 } } } if ((Get-Variable 'toolInstallationFailure' -ErrorAction 'SilentlyContinue') -and $toolInstallationFailure) { + # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482 + Write-Host 'Native tools bootstrap failed' exit 1 } } else { - Write-Host "No native tools defined in global.json" + Write-Host 'No native tools defined in global.json' exit 0 } @@ -131,17 +135,18 @@ try { exit 0 } if (Test-Path $InstallBin) { - Write-Host "Native tools are available from" (Convert-Path -Path $InstallBin) + Write-Host 'Native tools are available from ' (Convert-Path -Path $InstallBin) Write-Host "##vso[task.prependpath]$(Convert-Path -Path $InstallBin)" + return $InstallBin } else { - Write-Error "Native tools install directory does not exist, installation failed" + Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message 'Native tools install directory does not exist, installation failed' exit 1 } exit 0 } catch { - Write-Host $_ - Write-Host $_.Exception - exit 1 + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message $_ + ExitWithExitCode 1 } diff --git a/eng/common/init-tools-native.sh b/eng/common/init-tools-native.sh index 4dafaaca130..3e6a8d6acf2 100755 --- a/eng/common/init-tools-native.sh +++ b/eng/common/init-tools-native.sh @@ -10,12 +10,13 @@ force=false download_retries=5 retry_wait_time_seconds=30 global_json_file="$(dirname "$(dirname "${scriptroot}")")/global.json" -declare -A native_assets +declare -a native_assets +. $scriptroot/pipeline-logging-functions.sh . $scriptroot/native/common-library.sh while (($# > 0)); do - lowerI="$(echo $1 | awk '{print tolower($0)}')" + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" case $lowerI in --baseuri) base_uri=$2 @@ -33,6 +34,14 @@ while (($# > 0)); do force=true shift 1 ;; + --donotabortonfailure) + donotabortonfailure=true + shift 1 + ;; + --donotdisplaywarnings) + donotdisplaywarnings=true + shift 1 + ;; --downloadretries) download_retries=$2 shift 2 @@ -51,6 +60,8 @@ while (($# > 0)); do echo " - (default) %USERPROFILE%/.netcoreeng/native" echo "" echo " --clean Switch specifying not to install anything, but cleanup native asset folders" + echo " --donotabortonfailure Switch specifiying whether to abort native tools installation on failure" + echo " --donotdisplaywarnings Switch specifiying whether to display warnings during native tools installation on failure" echo " --force Clean and then install tools" echo " --help Print help and exit" echo "" @@ -65,24 +76,89 @@ while (($# > 0)); do done function ReadGlobalJsonNativeTools { - # Get the native-tools section from the global.json. - local native_tools_section=$(cat $global_json_file | awk '/"native-tools"/,/}/') - # Only extract the contents of the object. - local native_tools_list=$(echo $native_tools_section | awk -F"[{}]" '{print $2}') - native_tools_list=${native_tools_list//[\" ]/} - native_tools_list=$( echo "$native_tools_list" | sed 's/\s//g' | sed 's/,/\n/g' ) - - local old_IFS=$IFS - while read -r line; do - # Lines are of the form: 'tool:version' - IFS=: - while read -r key value; do - native_assets[$key]=$value - done <<< "$line" - done <<< "$native_tools_list" - IFS=$old_IFS - - return 0; + # happy path: we have a proper JSON parsing tool `jq(1)` in PATH! + if command -v jq &> /dev/null; then + + # jq: read each key/value pair under "native-tools" entry and emit: + # KEY="" VALUE="" + # followed by a null byte. + # + # bash: read line with null byte delimeter and push to array (for later `eval`uation). + + while IFS= read -rd '' line; do + native_assets+=("$line") + done < <(jq -r '. | + select(has("native-tools")) | + ."native-tools" | + keys[] as $k | + @sh "KEY=\($k) VALUE=\(.[$k])\u0000"' "$global_json_file") + + return + fi + + # Warning: falling back to manually parsing JSON, which is not recommended. + + # Following routine matches the output and escaping logic of jq(1)'s @sh formatter used above. + # It has been tested with several weird strings with escaped characters in entries (key and value) + # and results were compared with the output of jq(1) in binary representation using xxd(1); + # just before the assignment to 'native_assets' array (above and below). + + # try to capture the section under "native-tools". + if [[ ! "$(cat "$global_json_file")" =~ \"native-tools\"[[:space:]\:\{]*([^\}]+) ]]; then + return + fi + + section="${BASH_REMATCH[1]}" + + parseStarted=0 + possibleEnd=0 + escaping=0 + escaped=0 + isKey=1 + + for (( i=0; i<${#section}; i++ )); do + char="${section:$i:1}" + if ! ((parseStarted)) && [[ "$char" =~ [[:space:],:] ]]; then continue; fi + + if ! ((escaping)) && [[ "$char" == "\\" ]]; then + escaping=1 + elif ((escaping)) && ! ((escaped)); then + escaped=1 + fi + + if ! ((parseStarted)) && [[ "$char" == "\"" ]]; then + parseStarted=1 + possibleEnd=0 + elif [[ "$char" == "'" ]]; then + token="$token'\\\''" + possibleEnd=0 + elif ((escaping)) || [[ "$char" != "\"" ]]; then + token="$token$char" + possibleEnd=1 + fi + + if ((possibleEnd)) && ! ((escaping)) && [[ "$char" == "\"" ]]; then + # Use printf to unescape token to match jq(1)'s @sh formatting rules. + # do not use 'token="$(printf "$token")"' syntax, as $() eats the trailing linefeed. + printf -v token "'$token'" + + if ((isKey)); then + KEY="$token" + isKey=0 + else + line="KEY=$KEY VALUE=$token" + native_assets+=("$line") + isKey=1 + fi + + # reset for next token + parseStarted=0 + token= + elif ((escaping)) && ((escaped)); then + escaping=0 + escaped=0 + fi + done } native_base_dir=$install_directory @@ -91,6 +167,7 @@ if [[ -z $install_directory ]]; then fi install_bin="${native_base_dir}/bin" +installed_any=false ReadGlobalJsonNativeTools @@ -99,14 +176,14 @@ if [[ ${#native_assets[@]} -eq 0 ]]; then exit 0; else native_installer_dir="$scriptroot/native" - for tool in "${!native_assets[@]}" - do - tool_version=${native_assets[$tool]} - installer_name="install-$tool.sh" - installer_command="$native_installer_dir/$installer_name" + for index in "${!native_assets[@]}"; do + eval "${native_assets["$index"]}" + + installer_path="$native_installer_dir/install-$KEY.sh" + installer_command="$installer_path" installer_command+=" --baseuri $base_uri" installer_command+=" --installpath $install_bin" - installer_command+=" --version $tool_version" + installer_command+=" --version $VALUE" echo $installer_command if [[ $force = true ]]; then @@ -117,11 +194,29 @@ else installer_command+=" --clean" fi - $installer_command - - if [[ $? != 0 ]]; then - echo "Execution Failed" >&2 - exit 1 + if [[ -a $installer_path ]]; then + $installer_command + if [[ $? != 0 ]]; then + if [[ $donotabortonfailure = true ]]; then + if [[ $donotdisplaywarnings != true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed" + fi + else + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed" + exit 1 + fi + else + $installed_any = true + fi + else + if [[ $donotabortonfailure == true ]]; then + if [[ $donotdisplaywarnings != true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed: no install script" + fi + else + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed: no install script" + exit 1 + fi fi done fi @@ -134,8 +229,10 @@ if [[ -d $install_bin ]]; then echo "Native tools are available from $install_bin" echo "##vso[task.prependpath]$install_bin" else - echo "Native tools install directory does not exist, installation failed" >&2 - exit 1 + if [[ $installed_any = true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Native tools install directory does not exist, installation failed" + exit 1 + fi fi exit 0 diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1 index 8b8bafd6a89..92b77347d99 100644 --- a/eng/common/internal-feed-operations.ps1 +++ b/eng/common/internal-feed-operations.ps1 @@ -6,9 +6,8 @@ param( [switch] $IsFeedPrivate ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 - . $PSScriptRoot\tools.ps1 # Sets VSS_NUGET_EXTERNAL_FEED_ENDPOINTS based on the "darc-int-*" feeds defined in NuGet.config. This is needed @@ -21,7 +20,7 @@ function SetupCredProvider { ) # Install the Cred Provider NuGet plugin - Write-Host "Setting up Cred Provider NuGet plugin in the agent..." + Write-Host 'Setting up Cred Provider NuGet plugin in the agent...' Write-Host "Getting 'installcredprovider.ps1' from 'https://github.com/microsoft/artifacts-credprovider'..." $url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1' @@ -29,28 +28,28 @@ function SetupCredProvider { Write-Host "Writing the contents of 'installcredprovider.ps1' locally..." Invoke-WebRequest $url -OutFile installcredprovider.ps1 - Write-Host "Installing plugin..." + Write-Host 'Installing plugin...' .\installcredprovider.ps1 -Force Write-Host "Deleting local copy of 'installcredprovider.ps1'..." Remove-Item .\installcredprovider.ps1 if (-Not("$env:USERPROFILE\.nuget\plugins\netcore")) { - Write-Host "CredProvider plugin was not installed correctly!" + Write-PipelineTelemetryError -Category 'Arcade' -Message 'CredProvider plugin was not installed correctly!' ExitWithExitCode 1 } else { - Write-Host "CredProvider plugin was installed correctly!" + Write-Host 'CredProvider plugin was installed correctly!' } # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable # feeds successfully - $nugetConfigPath = "$RepoRoot\NuGet.config" + $nugetConfigPath = Join-Path $RepoRoot "NuGet.config" if (-Not (Test-Path -Path $nugetConfigPath)) { - Write-Host "NuGet.config file not found in repo's root!" - ExitWithExitCode 1 + Write-PipelineTelemetryError -Category 'Build' -Message 'NuGet.config file not found in repo root!' + ExitWithExitCode 1 } $endpoints = New-Object System.Collections.ArrayList @@ -64,7 +63,6 @@ function SetupCredProvider { } if (($endpoints | Measure-Object).Count -gt 0) { - # Create the JSON object. It should look like '{"endpointCredentials": [{"endpoint":"http://example.index.json", "username":"optional", "password":"accesstoken"}]}' $endpointCredentials = @{endpointCredentials=$endpoints} | ConvertTo-Json -Compress # Create the environment variables the AzDo way @@ -81,13 +79,13 @@ function SetupCredProvider { } else { - Write-Host "No internal endpoints found in NuGet.config" + Write-Host 'No internal endpoints found in NuGet.config' } } #Workaround for https://github.com/microsoft/msbuild/issues/4430 function InstallDotNetSdkAndRestoreArcade { - $dotnetTempDir = "$RepoRoot\dotnet" + $dotnetTempDir = Join-Path $RepoRoot "dotnet" $dotnetSdkVersion="2.1.507" # After experimentation we know this version works when restoring the SDK (compared to 3.0.*) $dotnet = "$dotnetTempDir\dotnet.exe" $restoreProjPath = "$PSScriptRoot\restore.proj" @@ -99,7 +97,7 @@ function InstallDotNetSdkAndRestoreArcade { & $dotnet restore $restoreProjPath - Write-Host "Arcade SDK restored!" + Write-Host 'Arcade SDK restored!' if (Test-Path -Path $restoreProjPath) { Remove-Item $restoreProjPath @@ -113,23 +111,22 @@ function InstallDotNetSdkAndRestoreArcade { try { Push-Location $PSScriptRoot - if ($Operation -like "setup") { + if ($Operation -like 'setup') { SetupCredProvider $AuthToken } - elseif ($Operation -like "install-restore") { + elseif ($Operation -like 'install-restore') { InstallDotNetSdkAndRestoreArcade } else { - Write-Host "Unknown operation '$Operation'!" + Write-PipelineTelemetryError -Category 'Arcade' -Message "Unknown operation '$Operation'!" ExitWithExitCode 1 } } catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Arcade' -Message $_ ExitWithExitCode 1 } finally { - Pop-Location + Pop-Location } diff --git a/eng/common/internal-feed-operations.sh b/eng/common/internal-feed-operations.sh index 1ff654d2ffc..9378223ba09 100755 --- a/eng/common/internal-feed-operations.sh +++ b/eng/common/internal-feed-operations.sh @@ -30,7 +30,7 @@ function SetupCredProvider { rm installcredprovider.sh if [ ! -d "$HOME/.nuget/plugins" ]; then - echo "CredProvider plugin was not installed correctly!" + Write-PipelineTelemetryError -category 'Build' 'CredProvider plugin was not installed correctly!' ExitWithExitCode 1 else echo "CredProvider plugin was installed correctly!" @@ -39,10 +39,10 @@ function SetupCredProvider { # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable # feeds successfully - local nugetConfigPath="$repo_root/NuGet.config" + local nugetConfigPath="{$repo_root}NuGet.config" if [ ! "$nugetConfigPath" ]; then - echo "NuGet.config file not found in repo's root!" + Write-PipelineTelemetryError -category 'Build' "NuGet.config file not found in repo's root!" ExitWithExitCode 1 fi @@ -62,7 +62,6 @@ function SetupCredProvider { endpoints+=']' if [ ${#endpoints} -gt 2 ]; then - # Create the JSON object. It should look like '{"endpointCredentials": [{"endpoint":"http://example.index.json", "username":"optional", "password":"accesstoken"}]}' local endpointCredentials="{\"endpointCredentials\": "$endpoints"}" echo "##vso[task.setvariable variable=VSS_NUGET_EXTERNAL_FEED_ENDPOINTS]$endpointCredentials" @@ -102,7 +101,7 @@ authToken='' repoName='' while [[ $# > 0 ]]; do - opt="$(echo "$1" | awk '{print tolower($0)}')" + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in --operation) operation=$2 diff --git a/eng/common/internal/Directory.Build.props b/eng/common/internal/Directory.Build.props index e33179ef373..dbf99d82a5c 100644 --- a/eng/common/internal/Directory.Build.props +++ b/eng/common/internal/Directory.Build.props @@ -1,4 +1,4 @@ - + diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj index 1a39a7ef3f6..beb9c4648ea 100644 --- a/eng/common/internal/Tools.csproj +++ b/eng/common/internal/Tools.csproj @@ -1,9 +1,9 @@ - - + net472 false + false diff --git a/eng/common/msbuild.ps1 b/eng/common/msbuild.ps1 index b37fd3d5e97..eea19cd8452 100644 --- a/eng/common/msbuild.ps1 +++ b/eng/common/msbuild.ps1 @@ -1,10 +1,11 @@ [CmdletBinding(PositionalBinding=$false)] Param( - [string] $verbosity = "minimal", + [string] $verbosity = 'minimal', [bool] $warnAsError = $true, [bool] $nodeReuse = $true, [switch] $ci, [switch] $prepareMachine, + [switch] $excludePrereleaseVS, [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs ) @@ -18,9 +19,8 @@ try { MSBuild @extraArgs } catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Build' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/msbuild.sh b/eng/common/msbuild.sh index 8160cd5a59d..20d3dad5435 100755 --- a/eng/common/msbuild.sh +++ b/eng/common/msbuild.sh @@ -19,7 +19,7 @@ prepare_machine=false extra_args='' while (($# > 0)); do - lowerI="$(echo $1 | awk '{print tolower($0)}')" + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" case $lowerI in --verbosity) verbosity=$2 diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1 index 41416862d91..adf707c8fe7 100644 --- a/eng/common/native/CommonLibrary.psm1 +++ b/eng/common/native/CommonLibrary.psm1 @@ -48,7 +48,7 @@ function DownloadAndExtract { -Verbose:$Verbose if ($DownloadStatus -Eq $False) { - Write-Error "Download failed" + Write-Error "Download failed from $Uri" return $False } @@ -145,9 +145,12 @@ function Get-File { New-Item -path $DownloadDirectory -force -itemType "Directory" | Out-Null } + $TempPath = "$Path.tmp" if (Test-Path -IsValid -Path $Uri) { - Write-Verbose "'$Uri' is a file path, copying file to '$Path'" - Copy-Item -Path $Uri -Destination $Path + Write-Verbose "'$Uri' is a file path, copying temporarily to '$TempPath'" + Copy-Item -Path $Uri -Destination $TempPath + Write-Verbose "Moving temporary file to '$Path'" + Move-Item -Path $TempPath -Destination $Path return $? } else { @@ -157,8 +160,10 @@ function Get-File { while($Attempt -Lt $DownloadRetries) { try { - Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $Path - Write-Verbose "Downloaded to '$Path'" + Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $TempPath + Write-Verbose "Downloaded to temporary location '$TempPath'" + Move-Item -Path $TempPath -Destination $Path + Write-Verbose "Moved temporary file to '$Path'" return $True } catch { @@ -359,16 +364,21 @@ function Expand-Zip { return $False } } - if (-Not (Test-Path $OutputDirectory)) { - New-Item -path $OutputDirectory -Force -itemType "Directory" | Out-Null + + $TempOutputDirectory = Join-Path "$(Split-Path -Parent $OutputDirectory)" "$(Split-Path -Leaf $OutputDirectory).tmp" + if (Test-Path $TempOutputDirectory) { + Remove-Item $TempOutputDirectory -Force -Recurse } + New-Item -Path $TempOutputDirectory -Force -ItemType "Directory" | Out-Null Add-Type -assembly "system.io.compression.filesystem" - [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$OutputDirectory") + [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$TempOutputDirectory") if ($? -Eq $False) { Write-Error "Unable to extract '$ZipPath'" return $False } + + Move-Item -Path $TempOutputDirectory -Destination $OutputDirectory } catch { Write-Host $_ diff --git a/eng/common/native/common-library.sh b/eng/common/native/common-library.sh index 271bddfac5a..080c2c283ae 100755 --- a/eng/common/native/common-library.sh +++ b/eng/common/native/common-library.sh @@ -34,7 +34,7 @@ function ExpandZip { echo "'Force flag enabled, but '$output_directory' exists. Removing directory" rm -rf $output_directory if [[ $? != 0 ]]; then - echo Unable to remove '$output_directory'>&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Unable to remove '$output_directory'" return 1 fi fi @@ -45,7 +45,7 @@ function ExpandZip { echo "Extracting archive" tar -xf $zip_path -C $output_directory if [[ $? != 0 ]]; then - echo "Unable to extract '$zip_path'" >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Unable to extract '$zip_path'" return 1 fi @@ -117,7 +117,7 @@ function DownloadAndExtract { # Download file GetFile "$uri" "$temp_tool_path" $force $download_retries $retry_wait_time_seconds if [[ $? != 0 ]]; then - echo "Failed to download '$uri' to '$temp_tool_path'." >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Failed to download '$uri' to '$temp_tool_path'." return 1 fi @@ -125,7 +125,7 @@ function DownloadAndExtract { echo "extracting from $temp_tool_path to $installDir" ExpandZip "$temp_tool_path" "$installDir" $force $download_retries $retry_wait_time_seconds if [[ $? != 0 ]]; then - echo "Failed to extract '$temp_tool_path' to '$installDir'." >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Failed to extract '$temp_tool_path' to '$installDir'." return 1 fi @@ -148,8 +148,12 @@ function NewScriptShim { fi if [[ ! -f $tool_file_path ]]; then - echo "Specified tool file path:'$tool_file_path' does not exist" >&2 - return 1 + # try to see if the path is lower cased + tool_file_path="$(echo $tool_file_path | tr "[:upper:]" "[:lower:]")" + if [[ ! -f $tool_file_path ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Specified tool file path:'$tool_file_path' does not exist" + return 1 + fi fi local shim_contents=$'#!/usr/bin/env bash\n' diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh new file mode 100644 index 00000000000..1daadf32a52 --- /dev/null +++ b/eng/common/native/init-compiler.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +# +# This file detects the C/C++ compiler and exports it to the CC/CXX environment variables +# + +if [[ "$#" -lt 2 ]]; then + echo "Usage..." + echo "init-compiler.sh " + echo "Specify the target architecture." + echo "Specify the name of compiler (clang or gcc)." + echo "Specify the major version of compiler." + echo "Specify the minor version of compiler." + exit 1 +fi + +. "$( cd -P "$( dirname "$0" )" && pwd )"/../pipeline-logging-functions.sh + +build_arch="$1" +compiler="$2" +cxxCompiler="$compiler++" +majorVersion="$3" +minorVersion="$4" + +# clear the existing CC and CXX from environment +CC= +CXX= +LDFLAGS= + +if [[ "$compiler" == "gcc" ]]; then cxxCompiler="g++"; fi + +check_version_exists() { + desired_version=-1 + + # Set up the environment to be used for building with the desired compiler. + if command -v "$compiler-$1.$2" > /dev/null; then + desired_version="-$1.$2" + elif command -v "$compiler$1$2" > /dev/null; then + desired_version="$1$2" + elif command -v "$compiler-$1$2" > /dev/null; then + desired_version="-$1$2" + fi + + echo "$desired_version" +} + +if [[ -z "$CLR_CC" ]]; then + + # Set default versions + if [[ -z "$majorVersion" ]]; then + # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. + if [[ "$compiler" == "clang" ]]; then versions=( 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5 ) + elif [[ "$compiler" == "gcc" ]]; then versions=( 11 10 9 8 7 6 5 4.9 ); fi + + for version in "${versions[@]}"; do + parts=(${version//./ }) + desired_version="$(check_version_exists "${parts[0]}" "${parts[1]}")" + if [[ "$desired_version" != "-1" ]]; then majorVersion="${parts[0]}"; break; fi + done + + if [[ -z "$majorVersion" ]]; then + if command -v "$compiler" > /dev/null; then + if [[ "$(uname)" != "Darwin" ]]; then + Write-PipelineTelemetryError -category "Build" -type "warning" "Specific version of $compiler not found, falling back to use the one in PATH." + fi + CC="$(command -v "$compiler")" + CXX="$(command -v "$cxxCompiler")" + else + Write-PipelineTelemetryError -category "Build" "No usable version of $compiler found." + exit 1 + fi + else + if [[ "$compiler" == "clang" && "$majorVersion" -lt 5 ]]; then + if [[ "$build_arch" == "arm" || "$build_arch" == "armel" ]]; then + if command -v "$compiler" > /dev/null; then + Write-PipelineTelemetryError -category "Build" -type "warning" "Found clang version $majorVersion which is not supported on arm/armel architectures, falling back to use clang from PATH." + CC="$(command -v "$compiler")" + CXX="$(command -v "$cxxCompiler")" + else + Write-PipelineTelemetryError -category "Build" "Found clang version $majorVersion which is not supported on arm/armel architectures, and there is no clang in PATH." + exit 1 + fi + fi + fi + fi + else + desired_version="$(check_version_exists "$majorVersion" "$minorVersion")" + if [[ "$desired_version" == "-1" ]]; then + Write-PipelineTelemetryError -category "Build" "Could not find specific version of $compiler: $majorVersion $minorVersion." + exit 1 + fi + fi + + if [[ -z "$CC" ]]; then + CC="$(command -v "$compiler$desired_version")" + CXX="$(command -v "$cxxCompiler$desired_version")" + if [[ -z "$CXX" ]]; then CXX="$(command -v "$cxxCompiler")"; fi + fi +else + if [[ ! -f "$CLR_CC" ]]; then + Write-PipelineTelemetryError -category "Build" "CLR_CC is set but path '$CLR_CC' does not exist" + exit 1 + fi + CC="$CLR_CC" + CXX="$CLR_CXX" +fi + +if [[ -z "$CC" ]]; then + Write-PipelineTelemetryError -category "Build" "Unable to find $compiler." + exit 1 +fi + +if [[ "$compiler" == "clang" ]]; then + if command -v "lld$desired_version" > /dev/null; then + # Only lld version >= 9 can be considered stable + if [[ "$majorVersion" -ge 9 ]]; then + LDFLAGS="-fuse-ld=lld" + fi + fi +fi + +SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version")" + +export CC CXX LDFLAGS SCAN_BUILD_COMMAND diff --git a/eng/common/native/install-cmake-test.sh b/eng/common/native/install-cmake-test.sh index 53ddf4e6860..8a5e7cf0db5 100755 --- a/eng/common/native/install-cmake-test.sh +++ b/eng/common/native/install-cmake-test.sh @@ -14,7 +14,7 @@ download_retries=5 retry_wait_time_seconds=30 while (($# > 0)); do - lowerI="$(echo $1 | awk '{print tolower($0)}')" + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" case $lowerI in --baseuri) base_uri=$2 @@ -63,7 +63,7 @@ done tool_name="cmake-test" tool_os=$(GetCurrentOS) -tool_folder=$(echo $tool_os | awk '{print tolower($0)}') +tool_folder="$(echo $tool_os | tr "[:upper:]" "[:lower:]")" tool_arch="x86_64" tool_name_moniker="$tool_name-$version-$tool_os-$tool_arch" tool_install_directory="$install_path/$tool_name/$version" @@ -101,7 +101,7 @@ fi DownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds if [[ $? != 0 ]]; then - echo "Installation failed" >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed' exit 1 fi @@ -110,8 +110,8 @@ fi NewScriptShim $shim_path $tool_file_path true if [[ $? != 0 ]]; then - echo "Shim generation failed" >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed' exit 1 fi -exit 0 \ No newline at end of file +exit 0 diff --git a/eng/common/native/install-cmake.sh b/eng/common/native/install-cmake.sh index 5f1a182fa9f..de496beebc5 100755 --- a/eng/common/native/install-cmake.sh +++ b/eng/common/native/install-cmake.sh @@ -14,7 +14,7 @@ download_retries=5 retry_wait_time_seconds=30 while (($# > 0)); do - lowerI="$(echo $1 | awk '{print tolower($0)}')" + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" case $lowerI in --baseuri) base_uri=$2 @@ -63,7 +63,7 @@ done tool_name="cmake" tool_os=$(GetCurrentOS) -tool_folder=$(echo $tool_os | awk '{print tolower($0)}') +tool_folder="$(echo $tool_os | tr "[:upper:]" "[:lower:]")" tool_arch="x86_64" tool_name_moniker="$tool_name-$version-$tool_os-$tool_arch" tool_install_directory="$install_path/$tool_name/$version" @@ -101,7 +101,7 @@ fi DownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds if [[ $? != 0 ]]; then - echo "Installation failed" >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed' exit 1 fi @@ -110,8 +110,8 @@ fi NewScriptShim $shim_path $tool_file_path true if [[ $? != 0 ]]; then - echo "Shim generation failed" >&2 + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed' exit 1 fi -exit 0 \ No newline at end of file +exit 0 diff --git a/eng/common/native/install-tool.ps1 b/eng/common/native/install-tool.ps1 index 635ab3fd414..78f2d84a4e4 100644 --- a/eng/common/native/install-tool.ps1 +++ b/eng/common/native/install-tool.ps1 @@ -46,6 +46,8 @@ Param ( [int] $RetryWaitTimeInSeconds = 30 ) +. $PSScriptRoot\..\pipeline-logging-functions.ps1 + # Import common library modules Import-Module -Name (Join-Path $CommonLibraryDirectory "CommonLibrary.psm1") @@ -93,7 +95,7 @@ try { -Verbose:$Verbose if ($InstallStatus -Eq $False) { - Write-Error "Installation failed" + Write-PipelineTelemetryError "Installation failed" -Category "NativeToolsetBootstrapping" exit 1 } } @@ -103,7 +105,7 @@ try { Write-Error "There are multiple copies of $ToolName in $($ToolInstallDirectory): `n$(@($ToolFilePath | out-string))" exit 1 } elseif (@($ToolFilePath).Length -Lt 1) { - Write-Error "$ToolName was not found in $ToolFilePath." + Write-Host "$ToolName was not found in $ToolInstallDirectory." exit 1 } @@ -117,14 +119,14 @@ try { -Verbose:$Verbose if ($GenerateShimStatus -Eq $False) { - Write-Error "Generate shim failed" + Write-PipelineTelemetryError "Generate shim failed" -Category "NativeToolsetBootstrapping" return 1 } exit 0 } catch { - Write-Host $_ - Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category "NativeToolsetBootstrapping" -Message $_ exit 1 } diff --git a/eng/common/performance/perfhelixpublish.proj b/eng/common/performance/perfhelixpublish.proj deleted file mode 100644 index e5826b53237..00000000000 --- a/eng/common/performance/perfhelixpublish.proj +++ /dev/null @@ -1,102 +0,0 @@ - - - - %HELIX_CORRELATION_PAYLOAD%\performance\scripts\benchmarks_ci.py --csproj %HELIX_CORRELATION_PAYLOAD%\performance\$(TargetCsproj) - --dotnet-versions %DOTNET_VERSION% --cli-source-info args --cli-branch %PERFLAB_BRANCH% --cli-commit-sha %PERFLAB_HASH% --cli-repository https://github.com/%PERFLAB_REPO% --cli-source-timestamp %PERFLAB_BUILDTIMESTAMP% - py -3 - %HELIX_CORRELATION_PAYLOAD%\Core_Root\CoreRun.exe - %HELIX_CORRELATION_PAYLOAD%\Baseline_Core_Root\CoreRun.exe - $(HelixPreCommands);call %HELIX_CORRELATION_PAYLOAD%\performance\tools\machine-setup.cmd - %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts - %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts_Baseline - %HELIX_CORRELATION_PAYLOAD%\performance\src\tools\ResultsComparer\ResultsComparer.csproj - %HELIX_CORRELATION_PAYLOAD%\performance\tools\dotnet\$(Architecture)\dotnet.exe - %25%25 - %HELIX_WORKITEM_ROOT%\testResults.xml - - - - $HELIX_CORRELATION_PAYLOAD - $(BaseDirectory)/performance - - - - $HELIX_WORKITEM_PAYLOAD - $(BaseDirectory) - - - - $(PerformanceDirectory)/scripts/benchmarks_ci.py --csproj $(PerformanceDirectory)/$(TargetCsproj) - --dotnet-versions $DOTNET_VERSION --cli-source-info args --cli-branch $PERFLAB_BRANCH --cli-commit-sha $PERFLAB_HASH --cli-repository https://github.com/$PERFLAB_REPO --cli-source-timestamp $PERFLAB_BUILDTIMESTAMP - python3 - $(BaseDirectory)/Core_Root/corerun - $(BaseDirectory)/Baseline_Core_Root/corerun - $(HelixPreCommands);chmod +x $(PerformanceDirectory)/tools/machine-setup.sh;. $(PerformanceDirectory)/tools/machine-setup.sh - $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts - $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts_Baseline - $(PerformanceDirectory)/src/tools/ResultsComparer/ResultsComparer.csproj - $(PerformanceDirectory)/tools/dotnet/$(Architecture)/dotnet - %25 - $HELIX_WORKITEM_ROOT/testResults.xml - - - - --corerun $(CoreRun) - - - - --corerun $(BaselineCoreRun) - - - - $(Python) $(WorkItemCommand) --incremental no --architecture $(Architecture) -f $(_Framework) $(PerfLabArguments) - - - - $(WorkItemCommand) $(CliArguments) - - - - - %(Identity) - - - - - 5 - - - - - - - - - - - false - - - - - - $(WorkItemDirectory) - $(WorkItemCommand) --bdn-artifacts $(BaselineArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)" - $(WorkItemCommand) --bdn-artifacts $(ArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)" - $(DotnetExe) run -f $(_Framework) -p $(ResultsComparer) --base $(BaselineArtifactsDirectory) --diff $(ArtifactsDirectory) --threshold 2$(Percent) --xml $(XMLResults);$(FinalCommand) - 4:00 - - - - - - $(WorkItemDirectory) - $(WorkItemCommand) --bdn-artifacts $(BaselineArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(BaselineCoreRunArgument)" - $(WorkItemCommand) --bdn-artifacts $(ArtifactsDirectory) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument)" - $(DotnetExe) run -f $(_Framework) -p $(ResultsComparer) --base $(BaselineArtifactsDirectory) --diff $(ArtifactsDirectory) --threshold 2$(Percent) --xml $(XMLResults) - 4:00 - - - \ No newline at end of file diff --git a/eng/common/performance/performance-setup.ps1 b/eng/common/performance/performance-setup.ps1 deleted file mode 100644 index ec41965fc89..00000000000 --- a/eng/common/performance/performance-setup.ps1 +++ /dev/null @@ -1,106 +0,0 @@ -Param( - [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY, - [string] $CoreRootDirectory, - [string] $BaselineCoreRootDirectory, - [string] $Architecture="x64", - [string] $Framework="netcoreapp5.0", - [string] $CompilationMode="Tiered", - [string] $Repository=$env:BUILD_REPOSITORY_NAME, - [string] $Branch=$env:BUILD_SOURCEBRANCH, - [string] $CommitSha=$env:BUILD_SOURCEVERSION, - [string] $BuildNumber=$env:BUILD_BUILDNUMBER, - [string] $RunCategories="coreclr corefx", - [string] $Csproj="src\benchmarks\micro\MicroBenchmarks.csproj", - [string] $Kind="micro", - [switch] $Internal, - [switch] $Compare, - [string] $Configurations="CompilationMode=$CompilationMode" -) - -$RunFromPerformanceRepo = ($Repository -eq "dotnet/performance") -or ($Repository -eq "dotnet-performance") -$UseCoreRun = ($CoreRootDirectory -ne [string]::Empty) -$UseBaselineCoreRun = ($BaselineCoreRootDirectory -ne [string]::Empty) - -$PayloadDirectory = (Join-Path $SourceDirectory "Payload") -$PerformanceDirectory = (Join-Path $PayloadDirectory "performance") -$WorkItemDirectory = (Join-Path $SourceDirectory "workitem") -$ExtraBenchmarkDotNetArguments = "--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true" -$Creator = $env:BUILD_DEFINITIONNAME -$PerfLabArguments = "" -$HelixSourcePrefix = "pr" - -$Queue = "Windows.10.Amd64.ClientRS4.DevEx.15.8.Open" - -if ($Framework.StartsWith("netcoreapp")) { - $Queue = "Windows.10.Amd64.ClientRS5.Open" -} - -if ($Compare) { - $Queue = "Windows.10.Amd64.19H1.Tiger.Perf.Open" - $PerfLabArguments = "" - $ExtraBenchmarkDotNetArguments = "" -} - -if ($Internal) { - $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" - $PerfLabArguments = "--upload-to-perflab-container" - $ExtraBenchmarkDotNetArguments = "" - $Creator = "" - $HelixSourcePrefix = "official" -} - -$CommonSetupArguments="--frameworks $Framework --queue $Queue --build-number $BuildNumber --build-configs $Configurations" -$SetupArguments = "--repository https://github.com/$Repository --branch $Branch --get-perf-hash --commit-sha $CommitSha $CommonSetupArguments" - -if ($RunFromPerformanceRepo) { - $SetupArguments = "--perf-hash $CommitSha $CommonSetupArguments" - - robocopy $SourceDirectory $PerformanceDirectory /E /XD $PayloadDirectory $SourceDirectory\artifacts $SourceDirectory\.git -} -else { - git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $PerformanceDirectory -} - -if ($UseCoreRun) { - $NewCoreRoot = (Join-Path $PayloadDirectory "Core_Root") - Move-Item -Path $CoreRootDirectory -Destination $NewCoreRoot -} -if ($UseBaselineCoreRun) { - $NewBaselineCoreRoot = (Join-Path $PayloadDirectory "Baseline_Core_Root") - Move-Item -Path $BaselineCoreRootDirectory -Destination $NewBaselineCoreRoot -} - -$DocsDir = (Join-Path $PerformanceDirectory "docs") -robocopy $DocsDir $WorkItemDirectory - -# Set variables that we will need to have in future steps -$ci = $true - -. "$PSScriptRoot\..\pipeline-logging-functions.ps1" - -# Directories -Write-PipelineSetVariable -Name 'PayloadDirectory' -Value "$PayloadDirectory" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'PerformanceDirectory' -Value "$PerformanceDirectory" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'WorkItemDirectory' -Value "$WorkItemDirectory" -IsMultiJobVariable $false - -# Script Arguments -Write-PipelineSetVariable -Name 'Python' -Value "py -3" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'ExtraBenchmarkDotNetArguments' -Value "$ExtraBenchmarkDotNetArguments" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'SetupArguments' -Value "$SetupArguments" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'PerfLabArguments' -Value "$PerfLabArguments" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'BDNCategories' -Value "$RunCategories" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'TargetCsproj' -Value "$Csproj" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'Kind' -Value "$Kind" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'Architecture' -Value "$Architecture" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'UseCoreRun' -Value "$UseCoreRun" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'UseBaselineCoreRun' -Value "$UseBaselineCoreRun" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'RunFromPerfRepo' -Value "$RunFromPerformanceRepo" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'Compare' -Value "$Compare" -IsMultiJobVariable $false - -# Helix Arguments -Write-PipelineSetVariable -Name 'Creator' -Value "$Creator" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'Queue' -Value "$Queue" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name 'HelixSourcePrefix' -Value "$HelixSourcePrefix" -IsMultiJobVariable $false -Write-PipelineSetVariable -Name '_BuildConfig' -Value "$Architecture.$Kind.$Framework" -IsMultiJobVariable $false - -exit 0 \ No newline at end of file diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh deleted file mode 100755 index 2f2092166e4..00000000000 --- a/eng/common/performance/performance-setup.sh +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env bash - -source_directory=$BUILD_SOURCESDIRECTORY -core_root_directory= -baseline_core_root_directory= -architecture=x64 -framework=netcoreapp5.0 -compilation_mode=tiered -repository=$BUILD_REPOSITORY_NAME -branch=$BUILD_SOURCEBRANCH -commit_sha=$BUILD_SOURCEVERSION -build_number=$BUILD_BUILDNUMBER -internal=false -compare=false -kind="micro" -run_categories="coreclr corefx" -csproj="src\benchmarks\micro\MicroBenchmarks.csproj" -configurations= -run_from_perf_repo=false -use_core_run=true -use_baseline_core_run=true - -while (($# > 0)); do - lowerI="$(echo $1 | awk '{print tolower($0)}')" - case $lowerI in - --sourcedirectory) - source_directory=$2 - shift 2 - ;; - --corerootdirectory) - core_root_directory=$2 - shift 2 - ;; - --baselinecorerootdirectory) - baseline_core_root_directory=$2 - shift 2 - ;; - --architecture) - architecture=$2 - shift 2 - ;; - --framework) - framework=$2 - shift 2 - ;; - --compilationmode) - compilation_mode=$2 - shift 2 - ;; - --repository) - repository=$2 - shift 2 - ;; - --branch) - branch=$2 - shift 2 - ;; - --commitsha) - commit_sha=$2 - shift 2 - ;; - --buildnumber) - build_number=$2 - shift 2 - ;; - --kind) - kind=$2 - shift 2 - ;; - --runcategories) - run_categories=$2 - shift 2 - ;; - --csproj) - csproj=$2 - shift 2 - ;; - --internal) - internal=true - shift 1 - ;; - --compare) - compare=true - shift 1 - ;; - --configurations) - configurations=$2 - shift 2 - ;; - --help) - echo "Common settings:" - echo " --corerootdirectory Directory where Core_Root exists, if running perf testing with --corerun" - echo " --architecture Architecture of the testing being run" - echo " --configurations List of key=value pairs that will be passed to perf testing infrastructure." - echo " ex: --configurations \"CompilationMode=Tiered OptimzationLevel=PGO\"" - echo " --help Print help and exit" - echo "" - echo "Advanced settings:" - echo " --framework The framework to run, if not running in master" - echo " --compliationmode The compilation mode if not passing --configurations" - echo " --sourcedirectory The directory of the sources. Defaults to env:BUILD_SOURCESDIRECTORY" - echo " --repository The name of the repository in the / format. Defaults to env:BUILD_REPOSITORY_NAME" - echo " --branch The name of the branch. Defaults to env:BUILD_SOURCEBRANCH" - echo " --commitsha The commit sha1 to run against. Defaults to env:BUILD_SOURCEVERSION" - echo " --buildnumber The build number currently running. Defaults to env:BUILD_BUILDNUMBER" - echo " --csproj The relative path to the benchmark csproj whose tests should be run. Defaults to src\benchmarks\micro\MicroBenchmarks.csproj" - echo " --kind Related to csproj. The kind of benchmarks that should be run. Defaults to micro" - echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\"" - echo " --internal If the benchmarks are running as an official job." - echo "" - exit 0 - ;; - esac -done - -if [ "$repository" == "dotnet/performance" ] || [ "$repository" == "dotnet-performance" ]; then - run_from_perf_repo=true -fi - -if [ -z "$configurations" ]; then - configurations="CompliationMode=$compilation_mode" -fi - -if [ -z "$core_root_directory" ]; then - use_core_run=false -fi - -if [ -z "$baseline_core_root_directory" ]; then - use_baseline_core_run=false -fi - -payload_directory=$source_directory/Payload -performance_directory=$payload_directory/performance -workitem_directory=$source_directory/workitem -extra_benchmark_dotnet_arguments="--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true" -perflab_arguments= -queue=Ubuntu.1804.Amd64.Open -creator=$BUILD_DEFINITIONNAME -helix_source_prefix="pr" - -if [[ "$compare" == true ]]; then - extra_benchmark_dotnet_arguments= - perflab_arguments= - - # No open queues for arm64 - if [[ "$architecture" = "arm64" ]]; then - echo "Compare not available for arm64" - exit 1 - fi - - queue=Ubuntu.1804.Amd64.Tiger.Perf.Open -fi - -if [[ "$internal" == true ]]; then - perflab_arguments="--upload-to-perflab-container" - helix_source_prefix="official" - creator= - extra_benchmark_dotnet_arguments= - - if [[ "$architecture" = "arm64" ]]; then - queue=Ubuntu.1804.Arm64.Perf - else - queue=Ubuntu.1804.Amd64.Tiger.Perf - fi -fi - -common_setup_arguments="--frameworks $framework --queue $queue --build-number $build_number --build-configs $configurations" -setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments" - -if [[ "$run_from_perf_repo" = true ]]; then - payload_directory= - workitem_directory=$source_directory - performance_directory=$workitem_directory - setup_arguments="--perf-hash $commit_sha $common_setup_arguments" -else - git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $performance_directory - - docs_directory=$performance_directory/docs - mv $docs_directory $workitem_directory -fi - -if [[ "$use_core_run" = true ]]; then - new_core_root=$payload_directory/Core_Root - mv $core_root_directory $new_core_root -fi - -if [[ "$use_baseline_core_run" = true ]]; then - new_baseline_core_root=$payload_directory/Baseline_Core_Root - mv $baseline_core_root_directory $new_baseline_core_root -fi - -ci=true - -_script_dir=$(pwd)/eng/common -. "$_script_dir/pipeline-logging-functions.sh" - -# Make sure all of our variables are available for future steps -Write-PipelineSetVariable -name "UseCoreRun" -value "$use_core_run" -is_multi_job_variable false -Write-PipelineSetVariable -name "UseBaselineCoreRun" -value "$use_baseline_core_run" -is_multi_job_variable false -Write-PipelineSetVariable -name "Architecture" -value "$architecture" -is_multi_job_variable false -Write-PipelineSetVariable -name "PayloadDirectory" -value "$payload_directory" -is_multi_job_variable false -Write-PipelineSetVariable -name "PerformanceDirectory" -value "$performance_directory" -is_multi_job_variable false -Write-PipelineSetVariable -name "WorkItemDirectory" -value "$workitem_directory" -is_multi_job_variable false -Write-PipelineSetVariable -name "Queue" -value "$queue" -is_multi_job_variable false -Write-PipelineSetVariable -name "SetupArguments" -value "$setup_arguments" -is_multi_job_variable false -Write-PipelineSetVariable -name "Python" -value "$python3" -is_multi_job_variable false -Write-PipelineSetVariable -name "PerfLabArguments" -value "$perflab_arguments" -is_multi_job_variable false -Write-PipelineSetVariable -name "ExtraBenchmarkDotNetArguments" -value "$extra_benchmark_dotnet_arguments" -is_multi_job_variable false -Write-PipelineSetVariable -name "BDNCategories" -value "$run_categories" -is_multi_job_variable false -Write-PipelineSetVariable -name "TargetCsproj" -value "$csproj" -is_multi_job_variable false -Write-PipelineSetVariable -name "RunFromPerfRepo" -value "$run_from_perf_repo" -is_multi_job_variable false -Write-PipelineSetVariable -name "Creator" -value "$creator" -is_multi_job_variable false -Write-PipelineSetVariable -name "HelixSourcePrefix" -value "$helix_source_prefix" -is_multi_job_variable false -Write-PipelineSetVariable -name "Kind" -value "$kind" -is_multi_job_variable false -Write-PipelineSetVariable -name "_BuildConfig" -value "$architecture.$kind.$framework" -is_multi_job_variable false -Write-PipelineSetVariable -name "Compare" -value "$compare" -is_multi_job_variable false diff --git a/eng/common/pipeline-logging-functions.ps1 b/eng/common/pipeline-logging-functions.ps1 index af5f48aaceb..8e422c561e4 100644 --- a/eng/common/pipeline-logging-functions.ps1 +++ b/eng/common/pipeline-logging-functions.ps1 @@ -12,6 +12,7 @@ $script:loggingCommandEscapeMappings = @( # TODO: WHAT ABOUT "="? WHAT ABOUT "%" # TODO: BUG: Escape % ??? # TODO: Add test to verify don't need to escape "=". +# Specify "-Force" to force pipeline formatted output even if "$ci" is false or not set function Write-PipelineTelemetryError { [CmdletBinding()] param( @@ -25,80 +26,101 @@ function Write-PipelineTelemetryError { [string]$SourcePath, [string]$LineNumber, [string]$ColumnNumber, - [switch]$AsOutput) + [switch]$AsOutput, + [switch]$Force) - $PSBoundParameters.Remove("Category") | Out-Null + $PSBoundParameters.Remove('Category') | Out-Null + if ($Force -Or ((Test-Path variable:ci) -And $ci)) { $Message = "(NETCORE_ENGINEERING_TELEMETRY=$Category) $Message" - $PSBoundParameters.Remove("Message") | Out-Null - $PSBoundParameters.Add("Message", $Message) - - Write-PipelineTaskError @PSBoundParameters + } + $PSBoundParameters.Remove('Message') | Out-Null + $PSBoundParameters.Add('Message', $Message) + Write-PipelineTaskError @PSBoundParameters } +# Specify "-Force" to force pipeline formatted output even if "$ci" is false or not set function Write-PipelineTaskError { [CmdletBinding()] param( - [Parameter(Mandatory = $true)] - [string]$Message, - [Parameter(Mandatory = $false)] - [string]$Type = 'error', - [string]$ErrCode, - [string]$SourcePath, - [string]$LineNumber, - [string]$ColumnNumber, - [switch]$AsOutput) - - if(!$ci) { - if($Type -eq 'error') { - Write-Host $Message -ForegroundColor Red - return + [Parameter(Mandatory = $true)] + [string]$Message, + [Parameter(Mandatory = $false)] + [string]$Type = 'error', + [string]$ErrCode, + [string]$SourcePath, + [string]$LineNumber, + [string]$ColumnNumber, + [switch]$AsOutput, + [switch]$Force + ) + + if (!$Force -And (-Not (Test-Path variable:ci) -Or !$ci)) { + if ($Type -eq 'error') { + Write-Host $Message -ForegroundColor Red + return } elseif ($Type -eq 'warning') { - Write-Host $Message -ForegroundColor Yellow - return + Write-Host $Message -ForegroundColor Yellow + return } - } - - if(($Type -ne 'error') -and ($Type -ne 'warning')) { + } + + if (($Type -ne 'error') -and ($Type -ne 'warning')) { Write-Host $Message return - } - if(-not $PSBoundParameters.ContainsKey('Type')) { + } + $PSBoundParameters.Remove('Force') | Out-Null + if (-not $PSBoundParameters.ContainsKey('Type')) { $PSBoundParameters.Add('Type', 'error') - } - Write-LogIssue @PSBoundParameters - } + } + Write-LogIssue @PSBoundParameters +} - function Write-PipelineSetVariable { +function Write-PipelineSetVariable { [CmdletBinding()] param( - [Parameter(Mandatory = $true)] - [string]$Name, - [string]$Value, - [switch]$Secret, - [switch]$AsOutput, - [bool]$IsMultiJobVariable=$true) - - if($ci) { + [Parameter(Mandatory = $true)] + [string]$Name, + [string]$Value, + [switch]$Secret, + [switch]$AsOutput, + [bool]$IsMultiJobVariable = $true) + + if ((Test-Path variable:ci) -And $ci) { Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{ - 'variable' = $Name - 'isSecret' = $Secret - 'isOutput' = $IsMultiJobVariable + 'variable' = $Name + 'isSecret' = $Secret + 'isOutput' = $IsMultiJobVariable } -AsOutput:$AsOutput - } - } + } +} - function Write-PipelinePrependPath { +function Write-PipelinePrependPath { [CmdletBinding()] param( - [Parameter(Mandatory=$true)] - [string]$Path, - [switch]$AsOutput) - if($ci) { + [Parameter(Mandatory = $true)] + [string]$Path, + [switch]$AsOutput) + + if ((Test-Path variable:ci) -And $ci) { Write-LoggingCommand -Area 'task' -Event 'prependpath' -Data $Path -AsOutput:$AsOutput - } - } + } +} + +function Write-PipelineSetResult { + [CmdletBinding()] + param( + [ValidateSet("Succeeded", "SucceededWithIssues", "Failed", "Cancelled", "Skipped")] + [Parameter(Mandatory = $true)] + [string]$Result, + [string]$Message) + if ((Test-Path variable:ci) -And $ci) { + Write-LoggingCommand -Area 'task' -Event 'complete' -Data $Message -Properties @{ + 'result' = $Result + } + } +} <######################################## # Private functions. @@ -115,7 +137,8 @@ function Format-LoggingCommandData { foreach ($mapping in $script:loggingCommandEscapeMappings) { $Value = $Value.Replace($mapping.Token, $mapping.Replacement) } - } else { + } + else { for ($i = $script:loggingCommandEscapeMappings.Length - 1 ; $i -ge 0 ; $i--) { $mapping = $script:loggingCommandEscapeMappings[$i] $Value = $Value.Replace($mapping.Replacement, $mapping.Token) @@ -148,7 +171,8 @@ function Format-LoggingCommand { if ($first) { $null = $sb.Append(' ') $first = $false - } else { + } + else { $null = $sb.Append(';') } @@ -185,7 +209,8 @@ function Write-LoggingCommand { $command = Format-LoggingCommand -Area $Area -Event $Event -Data $Data -Properties $Properties if ($AsOutput) { $command - } else { + } + else { Write-Host $command } } @@ -204,12 +229,12 @@ function Write-LogIssue { [switch]$AsOutput) $command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties @{ - 'type' = $Type - 'code' = $ErrCode - 'sourcepath' = $SourcePath - 'linenumber' = $LineNumber - 'columnnumber' = $ColumnNumber - } + 'type' = $Type + 'code' = $ErrCode + 'sourcepath' = $SourcePath + 'linenumber' = $LineNumber + 'columnnumber' = $ColumnNumber + } if ($AsOutput) { return $command } @@ -221,7 +246,8 @@ function Write-LogIssue { $foregroundColor = [System.ConsoleColor]::Red $backgroundColor = [System.ConsoleColor]::Black } - } else { + } + else { $foregroundColor = $host.PrivateData.WarningForegroundColor $backgroundColor = $host.PrivateData.WarningBackgroundColor if ($foregroundColor -isnot [System.ConsoleColor] -or $backgroundColor -isnot [System.ConsoleColor]) { @@ -231,4 +257,4 @@ function Write-LogIssue { } Write-Host $command -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor -} \ No newline at end of file +} diff --git a/eng/common/pipeline-logging-functions.sh b/eng/common/pipeline-logging-functions.sh index 1c560a50613..6a0b2255e91 100755 --- a/eng/common/pipeline-logging-functions.sh +++ b/eng/common/pipeline-logging-functions.sh @@ -2,15 +2,19 @@ function Write-PipelineTelemetryError { local telemetry_category='' + local force=false local function_args=() local message='' while [[ $# -gt 0 ]]; do - opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -category|-c) telemetry_category=$2 shift ;; + -force|-f) + force=true + ;; -*) function_args+=("$1 $2") shift @@ -22,31 +26,29 @@ function Write-PipelineTelemetryError { shift done - if [[ "$ci" != true ]]; then + if [[ $force != true ]] && [[ "$ci" != true ]]; then echo "$message" >&2 return fi + if [[ $force == true ]]; then + function_args+=("-force") + fi message="(NETCORE_ENGINEERING_TELEMETRY=$telemetry_category) $message" function_args+=("$message") - - Write-PipelineTaskError $function_args + Write-PipelineTaskError ${function_args[@]} } function Write-PipelineTaskError { - if [[ "$ci" != true ]]; then - echo "$@" >&2 - return - fi - local message_type="error" local sourcepath='' local linenumber='' local columnnumber='' local error_code='' + local force=false while [[ $# -gt 0 ]]; do - opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -type|-t) message_type=$2 @@ -68,6 +70,9 @@ function Write-PipelineTaskError { error_code=$2 shift ;; + -force|-f) + force=true + ;; *) break ;; @@ -76,6 +81,11 @@ function Write-PipelineTaskError { shift done + if [[ $force != true ]] && [[ "$ci" != true ]]; then + echo "$@" >&2 + return + fi + local message="##vso[task.logissue" message="$message type=$message_type" @@ -112,7 +122,7 @@ function Write-PipelineSetVariable { local is_multi_job_variable=true while [[ $# -gt 0 ]]; do - opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -name|-n) name=$2 @@ -154,7 +164,7 @@ function Write-PipelinePrependPath { local prepend_path='' while [[ $# -gt 0 ]]; do - opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -path|-p) prepend_path=$2 @@ -169,4 +179,28 @@ function Write-PipelinePrependPath { if [[ "$ci" == true ]]; then echo "##vso[task.prependpath]$prepend_path" fi -} \ No newline at end of file +} + +function Write-PipelineSetResult { + local result='' + local message='' + + while [[ $# -gt 0 ]]; do + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + -result|-r) + result=$2 + shift + ;; + -message|-m) + message=$2 + shift + ;; + esac + shift + done + + if [[ "$ci" == true ]]; then + echo "##vso[task.complete result=$result;]$message" + fi +} diff --git a/eng/common/post-build/add-build-to-channel.ps1 b/eng/common/post-build/add-build-to-channel.ps1 new file mode 100644 index 00000000000..de2d957922a --- /dev/null +++ b/eng/common/post-build/add-build-to-channel.ps1 @@ -0,0 +1,48 @@ +param( + [Parameter(Mandatory=$true)][int] $BuildId, + [Parameter(Mandatory=$true)][int] $ChannelId, + [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' +) + +try { + . $PSScriptRoot\post-build-utils.ps1 + + # Check that the channel we are going to promote the build to exist + $channelInfo = Get-MaestroChannel -ChannelId $ChannelId + + if (!$channelInfo) { + Write-PipelineTelemetryCategory -Category 'PromoteBuild' -Message "Channel with BAR ID $ChannelId was not found in BAR!" + ExitWithExitCode 1 + } + + # Get info about which channel(s) the build has already been promoted to + $buildInfo = Get-MaestroBuild -BuildId $BuildId + + if (!$buildInfo) { + Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "Build with BAR ID $BuildId was not found in BAR!" + ExitWithExitCode 1 + } + + # Find whether the build is already assigned to the channel or not + if ($buildInfo.channels) { + foreach ($channel in $buildInfo.channels) { + if ($channel.Id -eq $ChannelId) { + Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!" + ExitWithExitCode 0 + } + } + } + + Write-Host "Promoting build '$BuildId' to channel '$ChannelId'." + + Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId + + Write-Host 'done.' +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'" + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/check-channel-consistency.ps1 b/eng/common/post-build/check-channel-consistency.ps1 new file mode 100644 index 00000000000..63f3464c986 --- /dev/null +++ b/eng/common/post-build/check-channel-consistency.ps1 @@ -0,0 +1,40 @@ +param( + [Parameter(Mandatory=$true)][string] $PromoteToChannels, # List of channels that the build should be promoted to + [Parameter(Mandatory=$true)][array] $AvailableChannelIds # List of channel IDs available in the YAML implementation +) + +try { + . $PSScriptRoot\post-build-utils.ps1 + + if ($PromoteToChannels -eq "") { + Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info." + ExitWithExitCode 0 + } + + # Check that every channel that Maestro told to promote the build to + # is available in YAML + $PromoteToChannelsIds = $PromoteToChannels -split "\D" | Where-Object { $_ } + + $hasErrors = $false + + foreach ($id in $PromoteToChannelsIds) { + if (($id -ne 0) -and ($id -notin $AvailableChannelIds)) { + Write-PipelineTaskError -Message "Channel $id is not present in the post-build YAML configuration! This is an error scenario. Please contact @dnceng." + $hasErrors = $true + } + } + + # The `Write-PipelineTaskError` doesn't error the script and we might report several errors + # in the previous lines. The check below makes sure that we return an error state from the + # script if we reported any validation error + if ($hasErrors) { + ExitWithExitCode 1 + } + + Write-Host 'done.' +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Category 'CheckChannelConsistency' -Message "There was an error while trying to check consistency of Maestro default channels for the build and post-build YAML configuration." + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/darc-gather-drop.ps1 b/eng/common/post-build/darc-gather-drop.ps1 deleted file mode 100644 index 89854d3c1c2..00000000000 --- a/eng/common/post-build/darc-gather-drop.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -param( - [Parameter(Mandatory=$true)][int] $BarBuildId, # ID of the build which assets should be downloaded - [Parameter(Mandatory=$true)][string] $DropLocation, # Where the assets should be downloaded to - [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, # Token used to access Maestro API - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", # Maestro API URL - [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" # Version of Maestro API to use -) - -. $PSScriptRoot\post-build-utils.ps1 - -try { - Write-Host "Installing DARC ..." - - . $PSScriptRoot\..\darc-init.ps1 - $exitCode = $LASTEXITCODE - - if ($exitCode -ne 0) { - Write-PipelineTaskError "Something failed while running 'darc-init.ps1'. Check for errors above. Exiting now..." - ExitWithExitCode $exitCode - } - - # For now, only use a dry run. - # Ideally we would change darc to enable a quick request that - # would check whether the file exists that you can download it, - # and that it won't conflict with other files. - # https://github.com/dotnet/arcade/issues/3674 - # Right now we can't remove continue-on-error because we ocassionally will have - # dependencies that have no associated builds (e.g. an old dependency). - # We need to add an option to baseline specific dependencies away, or add them manually - # to the BAR. - darc gather-drop --non-shipping ` - --dry-run ` - --continue-on-error ` - --id $BarBuildId ` - --output-dir $DropLocation ` - --bar-uri $MaestroApiEndpoint ` - --password $MaestroApiAccessToken ` - --latest-location -} -catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - ExitWithExitCode 1 -} diff --git a/eng/common/post-build/nuget-validation.ps1 b/eng/common/post-build/nuget-validation.ps1 index 78ed0d540f5..dab3534ab53 100644 --- a/eng/common/post-build/nuget-validation.ps1 +++ b/eng/common/post-build/nuget-validation.ps1 @@ -6,20 +6,19 @@ param( [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to ) -. $PSScriptRoot\post-build-utils.ps1 - try { - $url = "https://raw.githubusercontent.com/NuGet/NuGetGallery/jver-verify/src/VerifyMicrosoftPackage/verify.ps1" + . $PSScriptRoot\post-build-utils.ps1 + + $url = 'https://raw.githubusercontent.com/NuGet/NuGetGallery/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1' - New-Item -ItemType "directory" -Path ${ToolDestinationPath} -Force + New-Item -ItemType 'directory' -Path ${ToolDestinationPath} -Force Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1 & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg } catch { - Write-PipelineTaskError "NuGet package validation failed. Please check error logs." - Write-Host $_ Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'NuGetValidation' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1 index 551ae113f89..534f6988d5b 100644 --- a/eng/common/post-build/post-build-utils.ps1 +++ b/eng/common/post-build/post-build-utils.ps1 @@ -1,16 +1,17 @@ # Most of the functions in this file require the variables `MaestroApiEndPoint`, # `MaestroApiVersion` and `MaestroApiAccessToken` to be globally available. -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 # `tools.ps1` checks $ci to perform some actions. Since the post-build # scripts don't necessarily execute in the same agent that run the # build.ps1/sh script this variable isn't automatically set. $ci = $true +$disableConfigureToolsetImport = $true . $PSScriptRoot\..\tools.ps1 -function Create-MaestroApiRequestHeaders([string]$ContentType = "application/json") { +function Create-MaestroApiRequestHeaders([string]$ContentType = 'application/json') { Validate-MaestroVars $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' @@ -50,40 +51,40 @@ function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) { return $result } -function Trigger-Subscription([string]$SubscriptionId) { +function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) { Validate-MaestroVars $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion" - Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null + $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion" + Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null } -function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) { +function Trigger-Subscription([string]$SubscriptionId) { Validate-MaestroVars $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken - $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion" - Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null + $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion" + Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null } function Validate-MaestroVars { try { - Get-Variable MaestroApiEndPoint -Scope Global | Out-Null - Get-Variable MaestroApiVersion -Scope Global | Out-Null - Get-Variable MaestroApiAccessToken -Scope Global | Out-Null + Get-Variable MaestroApiEndPoint | Out-Null + Get-Variable MaestroApiVersion | Out-Null + Get-Variable MaestroApiAccessToken | Out-Null - if (!($MaestroApiEndPoint -Match "^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$")) { - Write-PipelineTaskError "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'" + if (!($MaestroApiEndPoint -Match '^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$')) { + Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'" ExitWithExitCode 1 } - if (!($MaestroApiVersion -Match "^[0-9]{4}-[0-9]{2}-[0-9]{2}$")) { - Write-PipelineTaskError "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'" + if (!($MaestroApiVersion -Match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$')) { + Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'" ExitWithExitCode 1 } } catch { - Write-PipelineTaskError "Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script." + Write-PipelineTelemetryError -Category 'MaestroVars' -Message 'Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script.' Write-Host $_ ExitWithExitCode 1 } diff --git a/eng/common/post-build/promote-build.ps1 b/eng/common/post-build/promote-build.ps1 deleted file mode 100644 index e5ae85f2517..00000000000 --- a/eng/common/post-build/promote-build.ps1 +++ /dev/null @@ -1,48 +0,0 @@ -param( - [Parameter(Mandatory=$true)][int] $BuildId, - [Parameter(Mandatory=$true)][int] $ChannelId, - [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", - [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" -) - -. $PSScriptRoot\post-build-utils.ps1 - -try { - # Check that the channel we are going to promote the build to exist - $channelInfo = Get-MaestroChannel -ChannelId $ChannelId - - if (!$channelInfo) { - Write-Host "Channel with BAR ID $ChannelId was not found in BAR!" - ExitWithExitCode 1 - } - - # Get info about which channels the build has already been promoted to - $buildInfo = Get-MaestroBuild -BuildId $BuildId - - if (!$buildInfo) { - Write-Host "Build with BAR ID $BuildId was not found in BAR!" - ExitWithExitCode 1 - } - - # Find whether the build is already assigned to the channel or not - if ($buildInfo.channels) { - foreach ($channel in $buildInfo.channels) { - if ($channel.Id -eq $ChannelId) { - Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!" - ExitWithExitCode 0 - } - } - } - - Write-Host "Promoting build '$BuildId' to channel '$ChannelId'." - - Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId - - Write-Host "done." -} -catch { - Write-Host "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'" - Write-Host $_ - Write-Host $_.ScriptStackTrace -} diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 new file mode 100644 index 00000000000..2427ca6b6ae --- /dev/null +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -0,0 +1,80 @@ +param( + [Parameter(Mandatory=$true)][int] $BuildId, + [Parameter(Mandatory=$true)][int] $PublishingInfraVersion, + [Parameter(Mandatory=$true)][string] $AzdoToken, + [Parameter(Mandatory=$true)][string] $MaestroToken, + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, + [Parameter(Mandatory=$false)][string] $EnableSourceLinkValidation, + [Parameter(Mandatory=$false)][string] $EnableSigningValidation, + [Parameter(Mandatory=$false)][string] $EnableNugetValidation, + [Parameter(Mandatory=$false)][string] $PublishInstallersAndChecksums, + [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, + [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters, + [Parameter(Mandatory=$false)][string] $SigningValidationAdditionalParameters +) + +try { + . $PSScriptRoot\post-build-utils.ps1 + + $darc = Get-Darc + + $optionalParams = [System.Collections.ArrayList]::new() + + if ("" -ne $ArtifactsPublishingAdditionalParameters) { + $optionalParams.Add("--artifact-publishing-parameters") | Out-Null + $optionalParams.Add($ArtifactsPublishingAdditionalParameters) | Out-Null + } + + if ("" -ne $SymbolPublishingAdditionalParameters) { + $optionalParams.Add("--symbol-publishing-parameters") | Out-Null + $optionalParams.Add($SymbolPublishingAdditionalParameters) | Out-Null + } + + if ("false" -eq $WaitPublishingFinish) { + $optionalParams.Add("--no-wait") | Out-Null + } + + if ("false" -ne $PublishInstallersAndChecksums) { + $optionalParams.Add("--publish-installers-and-checksums") | Out-Null + } + + if ("true" -eq $EnableNugetValidation) { + $optionalParams.Add("--validate-nuget") | Out-Null + } + + if ("true" -eq $EnableSourceLinkValidation) { + $optionalParams.Add("--validate-sourcelinkchecksums") | Out-Null + } + + if ("true" -eq $EnableSigningValidation) { + $optionalParams.Add("--validate-signingchecksums") | Out-Null + + if ("" -ne $SigningValidationAdditionalParameters) { + $optionalParams.Add("--signing-validation-parameters") | Out-Null + $optionalParams.Add($SigningValidationAdditionalParameters) | Out-Null + } + } + + & $darc add-build-to-channel ` + --id $buildId ` + --publishing-infra-version $PublishingInfraVersion ` + --default-channels ` + --source-branch main ` + --azdev-pat $AzdoToken ` + --bar-uri $MaestroApiEndPoint ` + --password $MaestroToken ` + @optionalParams + + if ($LastExitCode -ne 0) { + Write-Host "Problems using Darc to promote build ${buildId} to default channels. Stopping execution..." + exit 1 + } + + Write-Host 'done.' +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to publish build '$BuildId' to default channels." + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/setup-maestro-vars.ps1 b/eng/common/post-build/setup-maestro-vars.ps1 deleted file mode 100644 index d7f64dc63cb..00000000000 --- a/eng/common/post-build/setup-maestro-vars.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -param( - [Parameter(Mandatory=$true)][string] $ReleaseConfigsPath # Full path to ReleaseConfigs.txt asset -) - -. $PSScriptRoot\post-build-utils.ps1 - -try { - $Content = Get-Content $ReleaseConfigsPath - - $BarId = $Content | Select -Index 0 - - $Channels = "" - $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," } - - $IsStableBuild = $Content | Select -Index 2 - - Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId - Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels" - Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild -} -catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - ExitWithExitCode 1 -} diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1 index bbfdacca130..e8ab29afeb3 100644 --- a/eng/common/post-build/sourcelink-validation.ps1 +++ b/eng/common/post-build/sourcelink-validation.ps1 @@ -14,7 +14,10 @@ param( $global:RepoFiles = @{} # Maximum number of jobs to run in parallel -$MaxParallelJobs = 6 +$MaxParallelJobs = 16 + +$MaxRetries = 5 +$RetryWaitTimeInSeconds = 30 # Wait time between check for system load $SecondsBetweenLoadChecks = 10 @@ -29,14 +32,17 @@ $ValidatePackage = { # Ensure input file exist if (!(Test-Path $PackagePath)) { Write-Host "Input file does not exist: $PackagePath" - return 1 + return [pscustomobject]@{ + result = 1 + packagePath = $PackagePath + } } # Extensions for which we'll look for SourceLink information # For now we'll only care about Portable & Embedded PDBs - $RelevantExtensions = @(".dll", ".exe", ".pdb") + $RelevantExtensions = @('.dll', '.exe', '.pdb') - Write-Host -NoNewLine "Validating" ([System.IO.Path]::GetFileName($PackagePath)) "... " + Write-Host -NoNewLine 'Validating ' ([System.IO.Path]::GetFileName($PackagePath)) '...' $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId @@ -58,8 +64,11 @@ $ValidatePackage = { $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName # We ignore resource DLLs - if ($FileName.EndsWith(".resources.dll")) { - return + if ($FileName.EndsWith('.resources.dll')) { + return [pscustomobject]@{ + result = 0 + packagePath = $PackagePath + } } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true) @@ -91,36 +100,59 @@ $ValidatePackage = { $Status = 200 $Cache = $using:RepoFiles - if ( !($Cache.ContainsKey($FilePath)) ) { - try { - $Uri = $Link -as [System.URI] - - # Only GitHub links are valid - if ($Uri.AbsoluteURI -ne $null -and ($Uri.Host -match "github" -or $Uri.Host -match "githubusercontent")) { - $Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode + $attempts = 0 + + while ($attempts -lt $using:MaxRetries) { + if ( !($Cache.ContainsKey($FilePath)) ) { + try { + $Uri = $Link -as [System.URI] + + if ($Link -match "submodules") { + # Skip submodule links until sourcelink properly handles submodules + $Status = 200 + } + elseif ($Uri.AbsoluteURI -ne $null -and ($Uri.Host -match 'github' -or $Uri.Host -match 'githubusercontent')) { + # Only GitHub links are valid + $Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode + } + else { + # If it's not a github link, we want to break out of the loop and not retry. + $Status = 0 + $attempts = $using:MaxRetries + } } - else { + catch { + Write-Host $_ $Status = 0 } } - catch { - write-host $_ - $Status = 0 - } - } - if ($Status -ne 200) { - if ($NumFailedLinks -eq 0) { - if ($FailedFiles.Value -eq 0) { - Write-Host + if ($Status -ne 200) { + $attempts++ + + if ($attempts -lt $using:MaxRetries) + { + $attemptsLeft = $using:MaxRetries - $attempts + Write-Warning "Download failed, $attemptsLeft attempts remaining, will retry in $using:RetryWaitTimeInSeconds seconds" + Start-Sleep -Seconds $using:RetryWaitTimeInSeconds + } + else { + if ($NumFailedLinks -eq 0) { + if ($FailedFiles.Value -eq 0) { + Write-Host + } + + Write-Host "`tFile $RealPath has broken links:" + } + + Write-Host "`t`tFailed to retrieve $Link" + + $NumFailedLinks++ } - - Write-Host "`tFile $RealPath has broken links:" } - - Write-Host "`t`tFailed to retrieve $Link" - - $NumFailedLinks++ + else { + break + } } } } @@ -136,26 +168,45 @@ $ValidatePackage = { } } catch { - + Write-Host $_ } finally { $zip.Dispose() } if ($FailedFiles -eq 0) { - Write-Host "Passed." - return 0 + Write-Host 'Passed.' + return [pscustomobject]@{ + result = 0 + packagePath = $PackagePath + } } else { - Write-Host "$PackagePath has broken SourceLink links." - return 1 + Write-PipelineTelemetryError -Category 'SourceLink' -Message "$PackagePath has broken SourceLink links." + return [pscustomobject]@{ + result = 1 + packagePath = $PackagePath + } + } +} + +function CheckJobResult( + $result, + $packagePath, + [ref]$ValidationFailures, + [switch]$logErrors) { + if ($result -ne '0') { + if ($logErrors) { + Write-PipelineTelemetryError -Category 'SourceLink' -Message "$packagePath has broken SourceLink links." + } + $ValidationFailures.Value++ } } function ValidateSourceLinkLinks { - if ($GHRepoName -ne "" -and !($GHRepoName -Match "^[^\s\/]+/[^\s\/]+$")) { - if (!($GHRepoName -Match "^[^\s-]+-[^\s]+$")) { - Write-PipelineTaskError "GHRepoName should be in the format / or -. '$GHRepoName'" + if ($GHRepoName -ne '' -and !($GHRepoName -Match '^[^\s\/]+/[^\s\/]+$')) { + if (!($GHRepoName -Match '^[^\s-]+-[^\s]+$')) { + Write-PipelineTelemetryError -Category 'SourceLink' -Message "GHRepoName should be in the format / or -. '$GHRepoName'" ExitWithExitCode 1 } else { @@ -163,14 +214,14 @@ function ValidateSourceLinkLinks { } } - if ($GHCommit -ne "" -and !($GHCommit -Match "^[0-9a-fA-F]{40}$")) { - Write-PipelineTaskError "GHCommit should be a 40 chars hexadecimal string. '$GHCommit'" + if ($GHCommit -ne '' -and !($GHCommit -Match '^[0-9a-fA-F]{40}$')) { + Write-PipelineTelemetryError -Category 'SourceLink' -Message "GHCommit should be a 40 chars hexadecimal string. '$GHCommit'" ExitWithExitCode 1 } - if ($GHRepoName -ne "" -and $GHCommit -ne "") { - $RepoTreeURL = -Join("http://api.github.com/repos/", $GHRepoName, "/git/trees/", $GHCommit, "?recursive=1") - $CodeExtensions = @(".cs", ".vb", ".fs", ".fsi", ".fsx", ".fsscript") + if ($GHRepoName -ne '' -and $GHCommit -ne '') { + $RepoTreeURL = -Join('http://api.github.com/repos/', $GHRepoName, '/git/trees/', $GHCommit, '?recursive=1') + $CodeExtensions = @('.cs', '.vb', '.fs', '.fsi', '.fsx', '.fsscript') try { # Retrieve the list of files in the repo at that particular commit point and store them in the RepoFiles hash @@ -188,17 +239,20 @@ function ValidateSourceLinkLinks { Write-Host "Problems downloading the list of files from the repo. Url used: $RepoTreeURL . Execution will proceed without caching." } } - elseif ($GHRepoName -ne "" -or $GHCommit -ne "") { - Write-Host "For using the http caching mechanism both GHRepoName and GHCommit should be informed." + elseif ($GHRepoName -ne '' -or $GHCommit -ne '') { + Write-Host 'For using the http caching mechanism both GHRepoName and GHCommit should be informed.' } if (Test-Path $ExtractPath) { Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue } + $ValidationFailures = 0 + # Process each NuGet package in parallel Get-ChildItem "$InputPath\*.symbols.nupkg" | ForEach-Object { + Write-Host "Starting $($_.FullName)" Start-Job -ScriptBlock $ValidatePackage -ArgumentList $_.FullName | Out-Null $NumJobs = @(Get-Job -State 'Running').Count @@ -209,26 +263,25 @@ function ValidateSourceLinkLinks { } foreach ($Job in @(Get-Job -State 'Completed')) { - Receive-Job -Id $Job.Id + $jobResult = Wait-Job -Id $Job.Id | Receive-Job + CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures) -LogErrors Remove-Job -Id $Job.Id } } - $ValidationFailures = 0 foreach ($Job in @(Get-Job)) { $jobResult = Wait-Job -Id $Job.Id | Receive-Job - if ($jobResult -ne "0") { - $ValidationFailures++ - } + CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures) + Remove-Job -Id $Job.Id } if ($ValidationFailures -gt 0) { - Write-PipelineTaskError " $ValidationFailures package(s) failed validation." + Write-PipelineTelemetryError -Category 'SourceLink' -Message "$ValidationFailures package(s) failed validation." ExitWithExitCode 1 } } function InstallSourcelinkCli { - $sourcelinkCliPackageName = "sourcelink" + $sourcelinkCliPackageName = 'sourcelink' $dotnetRoot = InitializeDotNetCli -install:$true $dotnet = "$dotnetRoot\dotnet.exe" @@ -239,7 +292,7 @@ function InstallSourcelinkCli { } else { Write-Host "Installing SourceLink CLI version $sourcelinkCliVersion..." - Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." + Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.' & "$dotnet" tool install $sourcelinkCliPackageName --version $sourcelinkCliVersion --verbosity "minimal" --global } } @@ -247,11 +300,15 @@ function InstallSourcelinkCli { try { InstallSourcelinkCli + foreach ($Job in @(Get-Job)) { + Remove-Job -Id $Job.Id + } + ValidateSourceLinkLinks } catch { - Write-Host $_ Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'SourceLink' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1 index 096ac321d12..a5af041ba77 100644 --- a/eng/common/post-build/symbols-validation.ps1 +++ b/eng/common/post-build/symbols-validation.ps1 @@ -1,127 +1,215 @@ param( - [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where NuGet packages to be checked are stored - [Parameter(Mandatory=$true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation - [Parameter(Mandatory=$true)][string] $DotnetSymbolVersion # Version of dotnet symbol to use + [Parameter(Mandatory = $true)][string] $InputPath, # Full path to directory where NuGet packages to be checked are stored + [Parameter(Mandatory = $true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation + [Parameter(Mandatory = $true)][string] $DotnetSymbolVersion, # Version of dotnet symbol to use + [Parameter(Mandatory = $false)][switch] $CheckForWindowsPdbs, # If we should check for the existence of windows pdbs in addition to portable PDBs + [Parameter(Mandatory = $false)][switch] $ContinueOnError, # If we should keep checking symbols after an error + [Parameter(Mandatory = $false)][switch] $Clean # Clean extracted symbols directory after checking symbols ) -. $PSScriptRoot\post-build-utils.ps1 +# Maximum number of jobs to run in parallel +$MaxParallelJobs = 16 -Add-Type -AssemblyName System.IO.Compression.FileSystem +# Max number of retries +$MaxRetry = 5 -function FirstMatchingSymbolDescriptionOrDefault { - param( - [string] $FullPath, # Full path to the module that has to be checked - [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols - [string] $SymbolsPath - ) - - $FileName = [System.IO.Path]::GetFileName($FullPath) - $Extension = [System.IO.Path]::GetExtension($FullPath) - - # Those below are potential symbol files that the `dotnet symbol` might - # return. Which one will be returned depend on the type of file we are - # checking and which type of file was uploaded. - - # The file itself is returned - $SymbolPath = $SymbolsPath + "\" + $FileName +# Wait time between check for system load +$SecondsBetweenLoadChecks = 10 - # PDB file for the module - $PdbPath = $SymbolPath.Replace($Extension, ".pdb") +# Set error codes +Set-Variable -Name "ERROR_BADEXTRACT" -Option Constant -Value -1 +Set-Variable -Name "ERROR_FILEDOESNOTEXIST" -Option Constant -Value -2 - # PDB file for R2R module (created by crossgen) - $NGenPdb = $SymbolPath.Replace($Extension, ".ni.pdb") - - # DBG file for a .so library - $SODbg = $SymbolPath.Replace($Extension, ".so.dbg") - - # DWARF file for a .dylib - $DylibDwarf = $SymbolPath.Replace($Extension, ".dylib.dwarf") - - $dotnetSymbolExe = "$env:USERPROFILE\.dotnet\tools" - $dotnetSymbolExe = Resolve-Path "$dotnetSymbolExe\dotnet-symbol.exe" - - & $dotnetSymbolExe --symbols --modules --windows-pdbs $TargetServerParam $FullPath -o $SymbolsPath | Out-Null - - if (Test-Path $PdbPath) { - return "PDB" - } - elseif (Test-Path $NGenPdb) { - return "NGen PDB" - } - elseif (Test-Path $SODbg) { - return "DBG for SO" - } - elseif (Test-Path $DylibDwarf) { - return "Dwarf for Dylib" - } - elseif (Test-Path $SymbolPath) { - return "Module" - } - else { - return $null - } +$WindowsPdbVerificationParam = "" +if ($CheckForWindowsPdbs) { + $WindowsPdbVerificationParam = "--windows-pdbs" } -function CountMissingSymbols { +$CountMissingSymbols = { param( - [string] $PackagePath # Path to a NuGet package + [string] $PackagePath, # Path to a NuGet package + [string] $WindowsPdbVerificationParam # If we should check for the existence of windows pdbs in addition to portable PDBs ) + . $using:PSScriptRoot\..\tools.ps1 + + Add-Type -AssemblyName System.IO.Compression.FileSystem + + Write-Host "Validating $PackagePath " + # Ensure input file exist if (!(Test-Path $PackagePath)) { Write-PipelineTaskError "Input file does not exist: $PackagePath" - ExitWithExitCode 1 + return [pscustomobject]@{ + result = $using:ERROR_FILEDOESNOTEXIST + packagePath = $PackagePath + } } # Extensions for which we'll look for symbols - $RelevantExtensions = @(".dll", ".exe", ".so", ".dylib") + $RelevantExtensions = @('.dll', '.exe', '.so', '.dylib') # How many files are missing symbol information $MissingSymbols = 0 $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) $PackageGuid = New-Guid - $ExtractPath = Join-Path -Path $ExtractPath -ChildPath $PackageGuid - $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath "Symbols" + $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageGuid + $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath 'Symbols' - [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) + try { + [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) + } + catch { + Write-Host "Something went wrong extracting $PackagePath" + Write-Host $_ + return [pscustomobject]@{ + result = $using:ERROR_BADEXTRACT + packagePath = $PackagePath + } + } Get-ChildItem -Recurse $ExtractPath | - Where-Object {$RelevantExtensions -contains $_.Extension} | - ForEach-Object { - if ($_.FullName -Match "\\ref\\") { - Write-Host "`t Ignoring reference assembly file" $_.FullName - return + Where-Object { $RelevantExtensions -contains $_.Extension } | + ForEach-Object { + $FileName = $_.FullName + if ($FileName -Match '\\ref\\') { + Write-Host "`t Ignoring reference assembly file " $FileName + return + } + + $FirstMatchingSymbolDescriptionOrDefault = { + param( + [string] $FullPath, # Full path to the module that has to be checked + [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols + [string] $WindowsPdbVerificationParam, # Parameter to pass to potential check for windows-pdbs. + [string] $SymbolsPath + ) + + $FileName = [System.IO.Path]::GetFileName($FullPath) + $Extension = [System.IO.Path]::GetExtension($FullPath) + + # Those below are potential symbol files that the `dotnet symbol` might + # return. Which one will be returned depend on the type of file we are + # checking and which type of file was uploaded. + + # The file itself is returned + $SymbolPath = $SymbolsPath + '\' + $FileName + + # PDB file for the module + $PdbPath = $SymbolPath.Replace($Extension, '.pdb') + + # PDB file for R2R module (created by crossgen) + $NGenPdb = $SymbolPath.Replace($Extension, '.ni.pdb') + + # DBG file for a .so library + $SODbg = $SymbolPath.Replace($Extension, '.so.dbg') + + # DWARF file for a .dylib + $DylibDwarf = $SymbolPath.Replace($Extension, '.dylib.dwarf') + + $dotnetSymbolExe = "$env:USERPROFILE\.dotnet\tools" + $dotnetSymbolExe = Resolve-Path "$dotnetSymbolExe\dotnet-symbol.exe" + + $totalRetries = 0 + + while ($totalRetries -lt $using:MaxRetry) { + + # Save the output and get diagnostic output + $output = & $dotnetSymbolExe --symbols --modules $WindowsPdbVerificationParam $TargetServerParam $FullPath -o $SymbolsPath --diagnostics | Out-String + + if (Test-Path $PdbPath) { + return 'PDB' + } + elseif (Test-Path $NGenPdb) { + return 'NGen PDB' + } + elseif (Test-Path $SODbg) { + return 'DBG for SO' + } + elseif (Test-Path $DylibDwarf) { + return 'Dwarf for Dylib' + } + elseif (Test-Path $SymbolPath) { + return 'Module' + } + else + { + $totalRetries++ + } } + + return $null + } + + $FileGuid = New-Guid + $ExpandedSymbolsPath = Join-Path -Path $SymbolsPath -ChildPath $FileGuid - $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--microsoft-symbol-server" $SymbolsPath - $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--internal-server" $SymbolsPath + $SymbolsOnMSDL = & $FirstMatchingSymbolDescriptionOrDefault ` + -FullPath $FileName ` + -TargetServerParam '--microsoft-symbol-server' ` + -SymbolsPath "$ExpandedSymbolsPath-msdl" ` + -WindowsPdbVerificationParam $WindowsPdbVerificationParam + $SymbolsOnSymWeb = & $FirstMatchingSymbolDescriptionOrDefault ` + -FullPath $FileName ` + -TargetServerParam '--internal-server' ` + -SymbolsPath "$ExpandedSymbolsPath-symweb" ` + -WindowsPdbVerificationParam $WindowsPdbVerificationParam - Write-Host -NoNewLine "`t Checking file" $_.FullName "... " + Write-Host -NoNewLine "`t Checking file " $FileName "... " - if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) { - Write-Host "Symbols found on MSDL (" $SymbolsOnMSDL ") and SymWeb (" $SymbolsOnSymWeb ")" + if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) { + Write-Host "Symbols found on MSDL ($SymbolsOnMSDL) and SymWeb ($SymbolsOnSymWeb)" + } + else { + $MissingSymbols++ + + if ($SymbolsOnMSDL -eq $null -and $SymbolsOnSymWeb -eq $null) { + Write-Host 'No symbols found on MSDL or SymWeb!' } else { - $MissingSymbols++ - - if ($SymbolsOnMSDL -eq $null -and $SymbolsOnSymWeb -eq $null) { - Write-Host "No symbols found on MSDL or SymWeb!" + if ($SymbolsOnMSDL -eq $null) { + Write-Host 'No symbols found on MSDL!' } else { - if ($SymbolsOnMSDL -eq $null) { - Write-Host "No symbols found on MSDL!" - } - else { - Write-Host "No symbols found on SymWeb!" - } + Write-Host 'No symbols found on SymWeb!' } } } + } + + if ($using:Clean) { + Remove-Item $ExtractPath -Recurse -Force + } Pop-Location - return $MissingSymbols + return [pscustomobject]@{ + result = $MissingSymbols + packagePath = $PackagePath + } +} + +function CheckJobResult( + $result, + $packagePath, + [ref]$DupedSymbols, + [ref]$TotalFailures) { + if ($result -eq $ERROR_BADEXTRACT) { + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "$packagePath has duplicated symbol files" + $DupedSymbols.Value++ + } + elseif ($result -eq $ERROR_FILEDOESNOTEXIST) { + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "$packagePath does not exist" + $TotalFailures.Value++ + } + elseif ($result -gt '0') { + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "Missing symbols for $result modules in the package $packagePath" + $TotalFailures.Value++ + } + else { + Write-Host "All symbols verified for package $packagePath" + } } function CheckSymbolsAvailable { @@ -129,38 +217,72 @@ function CheckSymbolsAvailable { Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue } + $TotalPackages = 0 + $TotalFailures = 0 + $DupedSymbols = 0 + Get-ChildItem "$InputPath\*.nupkg" | ForEach-Object { $FileName = $_.Name - + $FullName = $_.FullName + # These packages from Arcade-Services include some native libraries that # our current symbol uploader can't handle. Below is a workaround until # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted. - if ($FileName -Match "Microsoft\.DotNet\.Darc\.") { + if ($FileName -Match 'Microsoft\.DotNet\.Darc\.') { Write-Host "Ignoring Arcade-services file: $FileName" Write-Host return } - elseif ($FileName -Match "Microsoft\.DotNet\.Maestro\.Tasks\.") { + elseif ($FileName -Match 'Microsoft\.DotNet\.Maestro\.Tasks\.') { Write-Host "Ignoring Arcade-services file: $FileName" Write-Host return } - - Write-Host "Validating $FileName " - $Status = CountMissingSymbols "$InputPath\$FileName" - - if ($Status -ne 0) { - Write-PipelineTaskError "Missing symbols for $Status modules in the package $FileName" - ExitWithExitCode $exitCode + + $TotalPackages++ + + Start-Job -ScriptBlock $CountMissingSymbols -ArgumentList @($FullName,$WindowsPdbVerificationParam) | Out-Null + + $NumJobs = @(Get-Job -State 'Running').Count + + while ($NumJobs -ge $MaxParallelJobs) { + Write-Host "There are $NumJobs validation jobs running right now. Waiting $SecondsBetweenLoadChecks seconds to check again." + sleep $SecondsBetweenLoadChecks + $NumJobs = @(Get-Job -State 'Running').Count } + foreach ($Job in @(Get-Job -State 'Completed')) { + $jobResult = Wait-Job -Id $Job.Id | Receive-Job + CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$DupedSymbols) ([ref]$TotalFailures) + Remove-Job -Id $Job.Id + } Write-Host } + + foreach ($Job in @(Get-Job)) { + $jobResult = Wait-Job -Id $Job.Id | Receive-Job + CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$DupedSymbols) ([ref]$TotalFailures) + } + + if ($TotalFailures -gt 0 -or $DupedSymbols -gt 0) { + if ($TotalFailures -gt 0) { + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "Symbols missing for $TotalFailures/$TotalPackages packages" + } + + if ($DupedSymbols -gt 0) { + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "$DupedSymbols/$TotalPackages packages had duplicated symbol files and could not be extracted" + } + + ExitWithExitCode 1 + } + else { + Write-Host "All symbols validated!" + } } function InstallDotnetSymbol { - $dotnetSymbolPackageName = "dotnet-symbol" + $dotnetSymbolPackageName = 'dotnet-symbol' $dotnetRoot = InitializeDotNetCli -install:$true $dotnet = "$dotnetRoot\dotnet.exe" @@ -171,19 +293,24 @@ function InstallDotnetSymbol { } else { Write-Host "Installing dotnet-symbol version $dotnetSymbolVersion..." - Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." + Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.' & "$dotnet" tool install $dotnetSymbolPackageName --version $dotnetSymbolVersion --verbosity "minimal" --global } } try { + . $PSScriptRoot\post-build-utils.ps1 + InstallDotnetSymbol + foreach ($Job in @(Get-Job)) { + Remove-Job -Id $Job.Id + } + CheckSymbolsAvailable } catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 index 926d5b45513..55dea518ac5 100644 --- a/eng/common/post-build/trigger-subscriptions.ps1 +++ b/eng/common/post-build/trigger-subscriptions.ps1 @@ -2,56 +2,63 @@ param( [Parameter(Mandatory=$true)][string] $SourceRepo, [Parameter(Mandatory=$true)][int] $ChannelId, [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, - [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", - [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com', + [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' ) -. $PSScriptRoot\post-build-utils.ps1 +try { + . $PSScriptRoot\post-build-utils.ps1 -# Get all the $SourceRepo subscriptions -$normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '') -$subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId + # Get all the $SourceRepo subscriptions + $normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '') + $subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId -if (!$subscriptions) { - Write-Host "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'" - ExitWithExitCode 0 -} + if (!$subscriptions) { + Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'" + ExitWithExitCode 0 + } -$subscriptionsToTrigger = New-Object System.Collections.Generic.List[string] -$failedTriggeredSubscription = $false + $subscriptionsToTrigger = New-Object System.Collections.Generic.List[string] + $failedTriggeredSubscription = $false -# Get all enabled subscriptions that need dependency flow on 'everyBuild' -foreach ($subscription in $subscriptions) { - if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) { - Write-Host "Should trigger this subscription: $subscription.id" - [void]$subscriptionsToTrigger.Add($subscription.id) + # Get all enabled subscriptions that need dependency flow on 'everyBuild' + foreach ($subscription in $subscriptions) { + if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) { + Write-Host "Should trigger this subscription: ${$subscription.id}" + [void]$subscriptionsToTrigger.Add($subscription.id) + } } -} -foreach ($subscriptionToTrigger in $subscriptionsToTrigger) { - try { - Write-Host "Triggering subscription '$subscriptionToTrigger'." - - Trigger-Subscription -SubscriptionId $subscriptionToTrigger - - Write-Host "done." - } - catch - { - Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'" - Write-Host $_ - Write-Host $_.ScriptStackTrace - $failedTriggeredSubscription = $true + foreach ($subscriptionToTrigger in $subscriptionsToTrigger) { + try { + Write-Host "Triggering subscription '$subscriptionToTrigger'." + + Trigger-Subscription -SubscriptionId $subscriptionToTrigger + + Write-Host 'done.' + } + catch + { + Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'" + Write-Host $_ + Write-Host $_.ScriptStackTrace + $failedTriggeredSubscription = $true + } } -} -if ($subscriptionsToTrigger.Count -eq 0) { - Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'." + if ($subscriptionsToTrigger.Count -eq 0) { + Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'." + } + elseif ($failedTriggeredSubscription) { + Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message 'At least one subscription failed to be triggered...' + ExitWithExitCode 1 + } + else { + Write-Host 'All subscriptions were triggered successfully!' + } } -elseif ($failedTriggeredSubscription) { - Write-Host "At least one subscription failed to be triggered..." +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message $_ ExitWithExitCode 1 } -else { - Write-Host "All subscriptions were triggered successfully!" -} diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index d0eec5163ef..7ab9baac5c8 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -1,8 +1,8 @@ [CmdletBinding(PositionalBinding=$false)] Param( - [string] $configuration = "Debug", + [string] $configuration = 'Debug', [string] $task, - [string] $verbosity = "minimal", + [string] $verbosity = 'minimal', [string] $msbuildEngine = $null, [switch] $restore, [switch] $prepareMachine, @@ -32,9 +32,9 @@ function Print-Usage() { } function Build([string]$target) { - $logSuffix = if ($target -eq "Execute") { "" } else { ".$target" } + $logSuffix = if ($target -eq 'Execute') { '' } else { ".$target" } $log = Join-Path $LogDir "$task$logSuffix.binlog" - $outputPath = Join-Path $ToolsetDir "$task\\" + $outputPath = Join-Path $ToolsetDir "$task\" MSBuild $taskProject ` /bl:$log ` @@ -42,37 +42,58 @@ function Build([string]$target) { /p:Configuration=$configuration ` /p:RepoRoot=$RepoRoot ` /p:BaseIntermediateOutputPath=$outputPath ` + /v:$verbosity ` @properties } try { - if ($help -or (($null -ne $properties) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { + if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $properties.Contains('/?')))) { Print-Usage exit 0 } if ($task -eq "") { - Write-Host "Missing required parameter '-task '" -ForegroundColor Red + Write-PipelineTelemetryError -Category 'Build' -Message "Missing required parameter '-task '" Print-Usage ExitWithExitCode 1 } + if( $msbuildEngine -eq "vs") { + # Ensure desktop MSBuild is available for sdk tasks. + if( -not ($GlobalJson.tools.PSObject.Properties.Name -contains "vs" )) { + $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty + } + if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "16.10.0-preview2" -MemberType NoteProperty + } + if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { + $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true + } + if ($xcopyMSBuildToolsFolder -eq $null) { + throw 'Unable to get xcopy downloadable version of msbuild' + } + + $global:_MSBuildExe = "$($xcopyMSBuildToolsFolder)\MSBuild\Current\Bin\MSBuild.exe" + } + $taskProject = GetSdkTaskProject $task if (!(Test-Path $taskProject)) { - Write-Host "Unknown task: $task" -ForegroundColor Red + Write-PipelineTelemetryError -Category 'Build' -Message "Unknown task: $task" ExitWithExitCode 1 } if ($restore) { - Build "Restore" + if ($ci) { + Try-LogClientIpAddress + } + Build 'Restore' } - Build "Execute" + Build 'Execute' } catch { - Write-Host $_ - Write-Host $_.Exception Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Build' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/sdl/configure-sdl-tool.ps1 b/eng/common/sdl/configure-sdl-tool.ps1 new file mode 100644 index 00000000000..4999c307088 --- /dev/null +++ b/eng/common/sdl/configure-sdl-tool.ps1 @@ -0,0 +1,109 @@ +Param( + [string] $GuardianCliLocation, + [string] $WorkingDirectory, + [string] $TargetDirectory, + [string] $GdnFolder, + # The list of Guardian tools to configure. For each object in the array: + # - If the item is a [hashtable], it must contain these entries: + # - Name = The tool name as Guardian knows it. + # - Scenario = (Optional) Scenario-specific name for this configuration entry. It must be unique + # among all tool entries with the same Name. + # - Args = (Optional) Array of Guardian tool configuration args, like '@("Target > C:\temp")' + # - If the item is a [string] $v, it is treated as '@{ Name="$v" }' + [object[]] $ToolsList, + [string] $GuardianLoggerLevel='Standard', + # Optional: Additional params to add to any tool using CredScan. + [string[]] $CrScanAdditionalRunConfigParams, + # Optional: Additional params to add to any tool using PoliCheck. + [string[]] $PoliCheckAdditionalRunConfigParams +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2.0 +$disableConfigureToolsetImport = $true +$global:LASTEXITCODE = 0 + +try { + # `tools.ps1` checks $ci to perform some actions. Since the SDL + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + . $PSScriptRoot\..\tools.ps1 + + # Normalize tools list: all in [hashtable] form with defined values for each key. + $ToolsList = $ToolsList | + ForEach-Object { + if ($_ -is [string]) { + $_ = @{ Name = $_ } + } + + if (-not ($_['Scenario'])) { $_.Scenario = "" } + if (-not ($_['Args'])) { $_.Args = @() } + $_ + } + + Write-Host "List of tools to configure:" + $ToolsList | ForEach-Object { $_ | Out-String | Write-Host } + + # We store config files in the r directory of .gdn + $gdnConfigPath = Join-Path $GdnFolder 'r' + $ValidPath = Test-Path $GuardianCliLocation + + if ($ValidPath -eq $False) + { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Invalid Guardian CLI Location." + ExitWithExitCode 1 + } + + foreach ($tool in $ToolsList) { + # Put together the name and scenario to make a unique key. + $toolConfigName = $tool.Name + if ($tool.Scenario) { + $toolConfigName += "_" + $tool.Scenario + } + + Write-Host "=== Configuring $toolConfigName..." + + $gdnConfigFile = Join-Path $gdnConfigPath "$toolConfigName-configure.gdnconfig" + + # For some tools, add default and automatic args. + if ($tool.Name -eq 'credscan') { + if ($targetDirectory) { + $tool.Args += "TargetDirectory < $TargetDirectory" + } + $tool.Args += "OutputType < pre" + $tool.Args += $CrScanAdditionalRunConfigParams + } elseif ($tool.Name -eq 'policheck') { + if ($targetDirectory) { + $tool.Args += "Target < $TargetDirectory" + } + $tool.Args += $PoliCheckAdditionalRunConfigParams + } + + # Create variable pointing to the args array directly so we can use splat syntax later. + $toolArgs = $tool.Args + + # Configure the tool. If args array is provided or the current tool has some default arguments + # defined, add "--args" and splat each element on the end. Arg format is "{Arg id} < {Value}", + # one per parameter. Doc page for "guardian configure": + # https://dev.azure.com/securitytools/SecurityIntegration/_wiki/wikis/Guardian/1395/configure + Exec-BlockVerbosely { + & $GuardianCliLocation configure ` + --working-directory $WorkingDirectory ` + --tool $tool.Name ` + --output-path $gdnConfigFile ` + --logger-level $GuardianLoggerLevel ` + --noninteractive ` + --force ` + $(if ($toolArgs) { "--args" }) @toolArgs + Exit-IfNZEC "Sdl" + } + + Write-Host "Created '$toolConfigName' configuration file: $gdnConfigFile" + } +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} diff --git a/eng/common/sdl/execute-all-sdl-tools.ps1 b/eng/common/sdl/execute-all-sdl-tools.ps1 index 01799d63ff3..1157151f486 100644 --- a/eng/common/sdl/execute-all-sdl-tools.ps1 +++ b/eng/common/sdl/execute-all-sdl-tools.ps1 @@ -1,100 +1,163 @@ Param( - [string] $GuardianPackageName, # Required: the name of guardian CLI package (not needed if GuardianCliLocation is specified) - [string] $NugetPackageDirectory, # Required: directory where NuGet packages are installed (not needed if GuardianCliLocation is specified) - [string] $GuardianCliLocation, # Optional: Direct location of Guardian CLI executable if GuardianPackageName & NugetPackageDirectory are not specified - [string] $Repository=$env:BUILD_REPOSITORY_NAME, # Required: the name of the repository (e.g. dotnet/arcade) - [string] $BranchName=$env:BUILD_SOURCEBRANCH, # Optional: name of branch or version of gdn settings; defaults to master - [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY, # Required: the directory where source files are located - [string] $ArtifactsDirectory = (Join-Path $env:BUILD_SOURCESDIRECTORY ("artifacts")), # Required: the directory where build artifacts are located - [string] $AzureDevOpsAccessToken, # Required: access token for dnceng; should be provided via KeyVault - [string[]] $SourceToolsList, # Optional: list of SDL tools to run on source code - [string[]] $ArtifactToolsList, # Optional: list of SDL tools to run on built artifacts - [bool] $TsaPublish=$False, # Optional: true will publish results to TSA; only set to true after onboarding to TSA; TSA is the automated framework used to upload test results as bugs. - [string] $TsaBranchName=$env:BUILD_SOURCEBRANCH, # Optional: required for TSA publish; defaults to $(Build.SourceBranchName); TSA is the automated framework used to upload test results as bugs. - [string] $TsaRepositoryName=$env:BUILD_REPOSITORY_NAME, # Optional: TSA repository name; will be generated automatically if not submitted; TSA is the automated framework used to upload test results as bugs. - [string] $BuildNumber=$env:BUILD_BUILDNUMBER, # Optional: required for TSA publish; defaults to $(Build.BuildNumber) - [bool] $UpdateBaseline=$False, # Optional: if true, will update the baseline in the repository; should only be run after fixing any issues which need to be fixed - [bool] $TsaOnboard=$False, # Optional: if true, will onboard the repository to TSA; should only be run once; TSA is the automated framework used to upload test results as bugs. - [string] $TsaInstanceUrl, # Optional: only needed if TsaOnboard or TsaPublish is true; the instance-url registered with TSA; TSA is the automated framework used to upload test results as bugs. - [string] $TsaCodebaseName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the codebase registered with TSA; TSA is the automated framework used to upload test results as bugs. - [string] $TsaProjectName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the project registered with TSA; TSA is the automated framework used to upload test results as bugs. - [string] $TsaNotificationEmail, # Optional: only needed if TsaOnboard is true; the email(s) which will receive notifications of TSA bug filings (e.g. alias@microsoft.com); TSA is the automated framework used to upload test results as bugs. - [string] $TsaCodebaseAdmin, # Optional: only needed if TsaOnboard is true; the aliases which are admins of the TSA codebase (e.g. DOMAIN\alias); TSA is the automated framework used to upload test results as bugs. - [string] $TsaBugAreaPath, # Optional: only needed if TsaOnboard is true; the area path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. - [string] $TsaIterationPath, # Optional: only needed if TsaOnboard is true; the iteration path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. - [string] $GuardianLoggerLevel="Standard", # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error - [string[]] $CrScanAdditionalRunConfigParams, # Optional: Additional Params to custom build a CredScan run config in the format @("xyz:abc","sdf:1") - [string[]] $PoliCheckAdditionalRunConfigParams # Optional: Additional Params to custom build a Policheck run config in the format @("xyz:abc","sdf:1") + [string] $GuardianPackageName, # Required: the name of guardian CLI package (not needed if GuardianCliLocation is specified) + [string] $NugetPackageDirectory, # Required: directory where NuGet packages are installed (not needed if GuardianCliLocation is specified) + [string] $GuardianCliLocation, # Optional: Direct location of Guardian CLI executable if GuardianPackageName & NugetPackageDirectory are not specified + [string] $Repository=$env:BUILD_REPOSITORY_NAME, # Required: the name of the repository (e.g. dotnet/arcade) + [string] $BranchName=$env:BUILD_SOURCEBRANCH, # Optional: name of branch or version of gdn settings; defaults to master + [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY, # Required: the directory where source files are located + [string] $ArtifactsDirectory = (Join-Path $env:BUILD_ARTIFACTSTAGINGDIRECTORY ('artifacts')), # Required: the directory where build artifacts are located + [string] $AzureDevOpsAccessToken, # Required: access token for dnceng; should be provided via KeyVault + + # Optional: list of SDL tools to run on source code. See 'configure-sdl-tool.ps1' for tools list + # format. + [object[]] $SourceToolsList, + # Optional: list of SDL tools to run on built artifacts. See 'configure-sdl-tool.ps1' for tools + # list format. + [object[]] $ArtifactToolsList, + # Optional: list of SDL tools to run without automatically specifying a target directory. See + # 'configure-sdl-tool.ps1' for tools list format. + [object[]] $CustomToolsList, + + [bool] $TsaPublish=$False, # Optional: true will publish results to TSA; only set to true after onboarding to TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaBranchName=$env:BUILD_SOURCEBRANCH, # Optional: required for TSA publish; defaults to $(Build.SourceBranchName); TSA is the automated framework used to upload test results as bugs. + [string] $TsaRepositoryName=$env:BUILD_REPOSITORY_NAME, # Optional: TSA repository name; will be generated automatically if not submitted; TSA is the automated framework used to upload test results as bugs. + [string] $BuildNumber=$env:BUILD_BUILDNUMBER, # Optional: required for TSA publish; defaults to $(Build.BuildNumber) + [bool] $UpdateBaseline=$False, # Optional: if true, will update the baseline in the repository; should only be run after fixing any issues which need to be fixed + [bool] $TsaOnboard=$False, # Optional: if true, will onboard the repository to TSA; should only be run once; TSA is the automated framework used to upload test results as bugs. + [string] $TsaInstanceUrl, # Optional: only needed if TsaOnboard or TsaPublish is true; the instance-url registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaCodebaseName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the codebase registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaProjectName, # Optional: only needed if TsaOnboard or TsaPublish is true; the name of the project registered with TSA; TSA is the automated framework used to upload test results as bugs. + [string] $TsaNotificationEmail, # Optional: only needed if TsaOnboard is true; the email(s) which will receive notifications of TSA bug filings (e.g. alias@microsoft.com); TSA is the automated framework used to upload test results as bugs. + [string] $TsaCodebaseAdmin, # Optional: only needed if TsaOnboard is true; the aliases which are admins of the TSA codebase (e.g. DOMAIN\alias); TSA is the automated framework used to upload test results as bugs. + [string] $TsaBugAreaPath, # Optional: only needed if TsaOnboard is true; the area path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. + [string] $TsaIterationPath, # Optional: only needed if TsaOnboard is true; the iteration path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. + [string] $GuardianLoggerLevel='Standard', # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error + [string[]] $CrScanAdditionalRunConfigParams, # Optional: Additional Params to custom build a CredScan run config in the format @("xyz:abc","sdf:1") + [string[]] $PoliCheckAdditionalRunConfigParams, # Optional: Additional Params to custom build a Policheck run config in the format @("xyz:abc","sdf:1") + [bool] $BreakOnFailure=$False # Optional: Fail the build if there were errors during the run ) -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 -$LASTEXITCODE = 0 +try { + $ErrorActionPreference = 'Stop' + Set-StrictMode -Version 2.0 + $disableConfigureToolsetImport = $true + $global:LASTEXITCODE = 0 -#Replace repo names to the format of org/repo -if (!($Repository.contains('/'))) { - $RepoName = $Repository -replace '(.*?)-(.*)', '$1/$2'; -} -else{ - $RepoName = $Repository; -} + # `tools.ps1` checks $ci to perform some actions. Since the SDL + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + . $PSScriptRoot\..\tools.ps1 -if ($GuardianPackageName) { - $guardianCliLocation = Join-Path $NugetPackageDirectory (Join-Path $GuardianPackageName (Join-Path "tools" "guardian.cmd")) -} else { - $guardianCliLocation = $GuardianCliLocation -} + #Replace repo names to the format of org/repo + if (!($Repository.contains('/'))) { + $RepoName = $Repository -replace '(.*?)-(.*)', '$1/$2'; + } + else{ + $RepoName = $Repository; + } -$workingDirectory = (Split-Path $SourceDirectory -Parent) -$ValidPath = Test-Path $guardianCliLocation + if ($GuardianPackageName) { + $guardianCliLocation = Join-Path $NugetPackageDirectory (Join-Path $GuardianPackageName (Join-Path 'tools' 'guardian.cmd')) + } else { + $guardianCliLocation = $GuardianCliLocation + } -if ($ValidPath -eq $False) -{ - Write-Host "Invalid Guardian CLI Location." - exit 1 -} + $workingDirectory = (Split-Path $SourceDirectory -Parent) + $ValidPath = Test-Path $guardianCliLocation -& $(Join-Path $PSScriptRoot "init-sdl.ps1") -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel -$gdnFolder = Join-Path $workingDirectory ".gdn" + if ($ValidPath -eq $False) + { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Invalid Guardian CLI Location.' + ExitWithExitCode 1 + } + + Exec-BlockVerbosely { + & $(Join-Path $PSScriptRoot 'init-sdl.ps1') -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel + } + $gdnFolder = Join-Path $workingDirectory '.gdn' -if ($TsaOnboard) { - if ($TsaCodebaseName -and $TsaNotificationEmail -and $TsaCodebaseAdmin -and $TsaBugAreaPath) { - Write-Host "$guardianCliLocation tsa-onboard --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel" - & $guardianCliLocation tsa-onboard --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian tsa-onboard failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE + if ($TsaOnboard) { + if ($TsaCodebaseName -and $TsaNotificationEmail -and $TsaCodebaseAdmin -and $TsaBugAreaPath) { + Exec-BlockVerbosely { + & $guardianCliLocation tsa-onboard --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel + } + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Guardian tsa-onboard failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + } else { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Could not onboard to TSA -- not all required values ($TsaCodebaseName, $TsaNotificationEmail, $TsaCodebaseAdmin, $TsaBugAreaPath) were specified.' + ExitWithExitCode 1 } - } else { - Write-Host "Could not onboard to TSA -- not all required values ($$TsaCodebaseName, $$TsaNotificationEmail, $$TsaCodebaseAdmin, $$TsaBugAreaPath) were specified." - exit 1 } -} -if ($ArtifactToolsList -and $ArtifactToolsList.Count -gt 0) { - & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $workingDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams -} -if ($SourceToolsList -and $SourceToolsList.Count -gt 0) { - & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $workingDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams -} + # Configure a list of tools with a default target directory. Populates the ".gdn/r" directory. + function Configure-ToolsList([object[]] $tools, [string] $targetDirectory) { + if ($tools -and $tools.Count -gt 0) { + Exec-BlockVerbosely { + & $(Join-Path $PSScriptRoot 'configure-sdl-tool.ps1') ` + -GuardianCliLocation $guardianCliLocation ` + -WorkingDirectory $workingDirectory ` + -TargetDirectory $targetDirectory ` + -GdnFolder $gdnFolder ` + -ToolsList $tools ` + -AzureDevOpsAccessToken $AzureDevOpsAccessToken ` + -GuardianLoggerLevel $GuardianLoggerLevel ` + -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams ` + -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams + if ($BreakOnFailure) { + Exit-IfNZEC "Sdl" + } + } + } + } -if ($UpdateBaseline) { - & (Join-Path $PSScriptRoot "push-gdn.ps1") -Repository $RepoName -BranchName $BranchName -GdnFolder $GdnFolder -AzureDevOpsAccessToken $AzureDevOpsAccessToken -PushReason "Update baseline" -} + # Configure Artifact and Source tools with default Target directories. + Configure-ToolsList $ArtifactToolsList $ArtifactsDirectory + Configure-ToolsList $SourceToolsList $SourceDirectory + # Configure custom tools with no default Target directory. + Configure-ToolsList $CustomToolsList $null -if ($TsaPublish) { - if ($TsaBranchName -and $BuildNumber) { - if (-not $TsaRepositoryName) { - $TsaRepositoryName = "$($Repository)-$($BranchName)" + # At this point, all tools are configured in the ".gdn" directory. Run them all in a single call. + # (If we used "run" multiple times, each run would overwrite data from earlier runs.) + Exec-BlockVerbosely { + & $(Join-Path $PSScriptRoot 'run-sdl.ps1') ` + -GuardianCliLocation $guardianCliLocation ` + -WorkingDirectory $workingDirectory ` + -UpdateBaseline $UpdateBaseline ` + -GdnFolder $gdnFolder + } + + if ($TsaPublish) { + if ($TsaBranchName -and $BuildNumber) { + if (-not $TsaRepositoryName) { + $TsaRepositoryName = "$($Repository)-$($BranchName)" + } + Exec-BlockVerbosely { + & $guardianCliLocation tsa-publish --all-tools --repository-name "$TsaRepositoryName" --branch-name "$TsaBranchName" --build-number "$BuildNumber" --onboard $True --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel + } + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Guardian tsa-publish failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + } else { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message 'Could not publish to TSA -- not all required values ($TsaBranchName, $BuildNumber) were specified.' + ExitWithExitCode 1 } - Write-Host "$guardianCliLocation tsa-publish --all-tools --repository-name `"$TsaRepositoryName`" --branch-name `"$TsaBranchName`" --build-number `"$BuildNumber`" --codebase-name `"$TsaCodebaseName`" --notification-alias `"$TsaNotificationEmail`" --codebase-admin `"$TsaCodebaseAdmin`" --instance-url `"$TsaInstanceUrl`" --project-name `"$TsaProjectName`" --area-path `"$TsaBugAreaPath`" --iteration-path `"$TsaIterationPath`" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel" - & $guardianCliLocation tsa-publish --all-tools --repository-name "$TsaRepositoryName" --branch-name "$TsaBranchName" --build-number "$BuildNumber" --onboard $True --codebase-name "$TsaCodebaseName" --notification-alias "$TsaNotificationEmail" --codebase-admin "$TsaCodebaseAdmin" --instance-url "$TsaInstanceUrl" --project-name "$TsaProjectName" --area-path "$TsaBugAreaPath" --iteration-path "$TsaIterationPath" --working-directory $workingDirectory --logger-level $GuardianLoggerLevel - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian tsa-publish failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE + } + + if ($BreakOnFailure) { + Write-Host "Failing the build in case of breaking results..." + Exec-BlockVerbosely { + & $guardianCliLocation break --working-directory $workingDirectory --logger-level $GuardianLoggerLevel } } else { - Write-Host "Could not publish to TSA -- not all required values ($$TsaBranchName, $$BuildNumber) were specified." - exit 1 + Write-Host "Letting the build pass even if there were breaking results..." } } +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + exit 1 +} diff --git a/eng/common/sdl/extract-artifact-archives.ps1 b/eng/common/sdl/extract-artifact-archives.ps1 new file mode 100644 index 00000000000..68da4fbf257 --- /dev/null +++ b/eng/common/sdl/extract-artifact-archives.ps1 @@ -0,0 +1,63 @@ +# This script looks for each archive file in a directory and extracts it into the target directory. +# For example, the file "$InputPath/bin.tar.gz" extracts to "$ExtractPath/bin.tar.gz.extracted/**". +# Uses the "tar" utility added to Windows 10 / Windows 2019 that supports tar.gz and zip. +param( + # Full path to directory where archives are stored. + [Parameter(Mandatory=$true)][string] $InputPath, + # Full path to directory to extract archives into. May be the same as $InputPath. + [Parameter(Mandatory=$true)][string] $ExtractPath +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2.0 + +$disableConfigureToolsetImport = $true + +try { + # `tools.ps1` checks $ci to perform some actions. Since the SDL + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + . $PSScriptRoot\..\tools.ps1 + + Measure-Command { + $jobs = @() + + # Find archive files for non-Windows and Windows builds. + $archiveFiles = @( + Get-ChildItem (Join-Path $InputPath "*.tar.gz") + Get-ChildItem (Join-Path $InputPath "*.zip") + ) + + foreach ($targzFile in $archiveFiles) { + $jobs += Start-Job -ScriptBlock { + $file = $using:targzFile + $fileName = [System.IO.Path]::GetFileName($file) + $extractDir = Join-Path $using:ExtractPath "$fileName.extracted" + + New-Item $extractDir -ItemType Directory -Force | Out-Null + + Write-Host "Extracting '$file' to '$extractDir'..." + + # Pipe errors to stdout to prevent PowerShell detecting them and quitting the job early. + # This type of quit skips the catch, so we wouldn't be able to tell which file triggered the + # error. Save output so it can be stored in the exception string along with context. + $output = tar -xf $file -C $extractDir 2>&1 + # Handle NZEC manually rather than using Exit-IfNZEC: we are in a background job, so we + # don't have access to the outer scope. + if ($LASTEXITCODE -ne 0) { + throw "Error extracting '$file': non-zero exit code ($LASTEXITCODE). Output: '$output'" + } + + Write-Host "Extracted to $extractDir" + } + } + + Receive-Job $jobs -Wait + } +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} diff --git a/eng/common/sdl/extract-artifact-packages.ps1 b/eng/common/sdl/extract-artifact-packages.ps1 index 6e6825013bf..7f28d9c59ec 100644 --- a/eng/common/sdl/extract-artifact-packages.ps1 +++ b/eng/common/sdl/extract-artifact-packages.ps1 @@ -3,54 +3,12 @@ param( [Parameter(Mandatory=$true)][string] $ExtractPath # Full path to directory where the packages will be extracted ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 -# `tools.ps1` checks $ci to perform some actions. Since the post-build -# scripts don't necessarily execute in the same agent that run the -# build.ps1/sh script this variable isn't automatically set. -$ci = $true -. $PSScriptRoot\..\tools.ps1 +$disableConfigureToolsetImport = $true -$ExtractPackage = { - param( - [string] $PackagePath # Full path to a NuGet package - ) - - if (!(Test-Path $PackagePath)) { - Write-PipelineTaskError "Input file does not exist: $PackagePath" - ExitWithExitCode 1 - } - - $RelevantExtensions = @(".dll", ".exe", ".pdb") - Write-Host -NoNewLine "Extracting" ([System.IO.Path]::GetFileName($PackagePath)) "... " - - $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) - $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId - - Add-Type -AssemblyName System.IO.Compression.FileSystem - - [System.IO.Directory]::CreateDirectory($ExtractPath); - - try { - $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath) - - $zip.Entries | - Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} | - ForEach-Object { - $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.Name - - [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true) - } - } - catch { - - } - finally { - $zip.Dispose() - } - } - function ExtractArtifacts { +function ExtractArtifacts { if (!(Test-Path $InputPath)) { Write-Host "Input Path does not exist: $InputPath" ExitWithExitCode 0 @@ -67,11 +25,56 @@ $ExtractPackage = { } try { + # `tools.ps1` checks $ci to perform some actions. Since the SDL + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + . $PSScriptRoot\..\tools.ps1 + + $ExtractPackage = { + param( + [string] $PackagePath # Full path to a NuGet package + ) + + if (!(Test-Path $PackagePath)) { + Write-PipelineTelemetryError -Category 'Build' -Message "Input file does not exist: $PackagePath" + ExitWithExitCode 1 + } + + $RelevantExtensions = @('.dll', '.exe', '.pdb') + Write-Host -NoNewLine 'Extracting ' ([System.IO.Path]::GetFileName($PackagePath)) '...' + + $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) + $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId + + Add-Type -AssemblyName System.IO.Compression.FileSystem + + [System.IO.Directory]::CreateDirectory($ExtractPath); + + try { + $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath) + + $zip.Entries | + Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} | + ForEach-Object { + $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.Name + + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true) + } + } + catch { + Write-Host $_ + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 + } + finally { + $zip.Dispose() + } + } Measure-Command { ExtractArtifacts } } catch { Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ ExitWithExitCode 1 } diff --git a/eng/common/sdl/init-sdl.ps1 b/eng/common/sdl/init-sdl.ps1 index c737eb0e71c..3ac1d92b370 100644 --- a/eng/common/sdl/init-sdl.ps1 +++ b/eng/common/sdl/init-sdl.ps1 @@ -1,15 +1,22 @@ Param( [string] $GuardianCliLocation, [string] $Repository, - [string] $BranchName="master", + [string] $BranchName='master', [string] $WorkingDirectory, [string] $AzureDevOpsAccessToken, - [string] $GuardianLoggerLevel="Standard" + [string] $GuardianLoggerLevel='Standard' ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 -$LASTEXITCODE = 0 +$disableConfigureToolsetImport = $true +$global:LASTEXITCODE = 0 + +# `tools.ps1` checks $ci to perform some actions. Since the SDL +# scripts don't necessarily execute in the same agent that run the +# build.ps1/sh script this variable isn't automatically set. +$ci = $true +. $PSScriptRoot\..\tools.ps1 # Don't display the console progress UI - it's a huge perf hit $ProgressPreference = 'SilentlyContinue' @@ -17,35 +24,32 @@ $ProgressPreference = 'SilentlyContinue' # Construct basic auth from AzDO access token; construct URI to the repository's gdn folder stored in that repository; construct location of zip file $encodedPat = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$AzureDevOpsAccessToken")) $escapedRepository = [Uri]::EscapeDataString("/$Repository/$BranchName/.gdn") -$uri = "https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0-preview.1" +$uri = "https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0" $zipFile = "$WorkingDirectory/gdn.zip" Add-Type -AssemblyName System.IO.Compression.FileSystem -$gdnFolder = (Join-Path $WorkingDirectory ".gdn") -Try -{ - # We try to download the zip; if the request fails (e.g. the file doesn't exist), we catch it and init guardian instead - Write-Host "Downloading gdn folder from internal config repostiory..." - Invoke-WebRequest -Headers @{ "Accept"="application/zip"; "Authorization"="Basic $encodedPat" } -Uri $uri -OutFile $zipFile - if (Test-Path $gdnFolder) { - # Remove the gdn folder if it exists (it shouldn't unless there's too much caching; this is just in case) - Remove-Item -Force -Recurse $gdnFolder - } - [System.IO.Compression.ZipFile]::ExtractToDirectory($zipFile, $WorkingDirectory) - Write-Host $gdnFolder -} Catch [System.Net.WebException] { +$gdnFolder = (Join-Path $WorkingDirectory '.gdn') + +try { # if the folder does not exist, we'll do a guardian init and push it to the remote repository - Write-Host "Initializing Guardian..." + Write-Host 'Initializing Guardian...' Write-Host "$GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel" & $GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel if ($LASTEXITCODE -ne 0) { - Write-Error "Guardian init failed with exit code $LASTEXITCODE." + Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian init failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE } # We create the mainbaseline so it can be edited later Write-Host "$GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline" & $GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline if ($LASTEXITCODE -ne 0) { - Write-Error "Guardian baseline failed with exit code $LASTEXITCODE." + Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian baseline failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE } - & $(Join-Path $PSScriptRoot "push-gdn.ps1") -Repository $Repository -BranchName $BranchName -GdnFolder $gdnFolder -AzureDevOpsAccessToken $AzureDevOpsAccessToken -PushReason "Initialize gdn folder" -} \ No newline at end of file + ExitWithExitCode 0 +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config index 256ffbfb93a..3bd8b29ebd7 100644 --- a/eng/common/sdl/packages.config +++ b/eng/common/sdl/packages.config @@ -1,4 +1,4 @@ - + diff --git a/eng/common/sdl/push-gdn.ps1 b/eng/common/sdl/push-gdn.ps1 deleted file mode 100644 index 79c707d6d8a..00000000000 --- a/eng/common/sdl/push-gdn.ps1 +++ /dev/null @@ -1,51 +0,0 @@ -Param( - [string] $Repository, - [string] $BranchName="master", - [string] $GdnFolder, - [string] $AzureDevOpsAccessToken, - [string] $PushReason -) - -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 -$LASTEXITCODE = 0 - -# We create the temp directory where we'll store the sdl-config repository -$sdlDir = Join-Path $env:TEMP "sdl" -if (Test-Path $sdlDir) { - Remove-Item -Force -Recurse $sdlDir -} - -Write-Host "git clone https://dnceng:`$AzureDevOpsAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir" -git clone https://dnceng:$AzureDevOpsAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir -if ($LASTEXITCODE -ne 0) { - Write-Error "Git clone failed with exit code $LASTEXITCODE." -} -# We copy the .gdn folder from our local run into the git repository so it can be committed -$sdlRepositoryFolder = Join-Path (Join-Path (Join-Path $sdlDir $Repository) $BranchName) ".gdn" -if (Get-Command Robocopy) { - Robocopy /S $GdnFolder $sdlRepositoryFolder -} else { - rsync -r $GdnFolder $sdlRepositoryFolder -} -# cd to the sdl-config directory so we can run git there -Push-Location $sdlDir -# git add . --> git commit --> git push -Write-Host "git add ." -git add . -if ($LASTEXITCODE -ne 0) { - Write-Error "Git add failed with exit code $LASTEXITCODE." -} -Write-Host "git -c user.email=`"dn-bot@microsoft.com`" -c user.name=`"Dotnet Bot`" commit -m `"$PushReason for $Repository/$BranchName`"" -git -c user.email="dn-bot@microsoft.com" -c user.name="Dotnet Bot" commit -m "$PushReason for $Repository/$BranchName" -if ($LASTEXITCODE -ne 0) { - Write-Error "Git commit failed with exit code $LASTEXITCODE." -} -Write-Host "git push" -git push -if ($LASTEXITCODE -ne 0) { - Write-Error "Git push failed with exit code $LASTEXITCODE." -} - -# Return to the original directory -Pop-Location \ No newline at end of file diff --git a/eng/common/sdl/run-sdl.ps1 b/eng/common/sdl/run-sdl.ps1 index 9bc25314ae2..2eac8c78f10 100644 --- a/eng/common/sdl/run-sdl.ps1 +++ b/eng/common/sdl/run-sdl.ps1 @@ -1,59 +1,49 @@ Param( [string] $GuardianCliLocation, [string] $WorkingDirectory, - [string] $TargetDirectory, [string] $GdnFolder, - [string[]] $ToolsList, [string] $UpdateBaseline, - [string] $GuardianLoggerLevel="Standard", - [string[]] $CrScanAdditionalRunConfigParams, - [string[]] $PoliCheckAdditionalRunConfigParams + [string] $GuardianLoggerLevel='Standard' ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 -$LASTEXITCODE = 0 +$disableConfigureToolsetImport = $true +$global:LASTEXITCODE = 0 -# We store config files in the r directory of .gdn -Write-Host $ToolsList -$gdnConfigPath = Join-Path $GdnFolder "r" -$ValidPath = Test-Path $GuardianCliLocation +try { + # `tools.ps1` checks $ci to perform some actions. Since the SDL + # scripts don't necessarily execute in the same agent that run the + # build.ps1/sh script this variable isn't automatically set. + $ci = $true + . $PSScriptRoot\..\tools.ps1 -if ($ValidPath -eq $False) -{ - Write-Host "Invalid Guardian CLI Location." - exit 1 -} - -$configParam = @("--config") + # We store config files in the r directory of .gdn + $gdnConfigPath = Join-Path $GdnFolder 'r' + $ValidPath = Test-Path $GuardianCliLocation -foreach ($tool in $ToolsList) { - $gdnConfigFile = Join-Path $gdnConfigPath "$tool-configure.gdnconfig" - Write-Host $tool - # We have to manually configure tools that run on source to look at the source directory only - if ($tool -eq "credscan") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory < $TargetDirectory `" `" OutputType < pre `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory < $TargetDirectory " "OutputType < pre" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams}) - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE - } - } - if ($tool -eq "policheck") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target < $TargetDirectory `" $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target < $TargetDirectory " $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams}) - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE - } + if ($ValidPath -eq $False) + { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Invalid Guardian CLI Location." + ExitWithExitCode 1 } - $configParam+=$gdnConfigFile -} + $gdnConfigFiles = Get-ChildItem $gdnConfigPath -Recurse -Include '*.gdnconfig' + Write-Host "Discovered Guardian config files:" + $gdnConfigFiles | Out-String | Write-Host -Write-Host "$GuardianCliLocation run --working-directory $WorkingDirectory --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam" -& $GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam -if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian run for $ToolsList using $configParam failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE + Exec-BlockVerbosely { + & $GuardianCliLocation run ` + --working-directory $WorkingDirectory ` + --baseline mainbaseline ` + --update-baseline $UpdateBaseline ` + --logger-level $GuardianLoggerLevel ` + --config @gdnConfigFiles + Exit-IfNZEC "Sdl" + } +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ + ExitWithExitCode 1 } diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index 52e2ff021d7..69eb67849d7 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -1,54 +1,146 @@ parameters: + enable: 'false' # Whether the SDL validation job should execute or not overrideParameters: '' # Optional: to override values for parameters. additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth + # diagnosis of problems with specific tool configurations. + publishGuardianDirectoryToPipeline: false + # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL + # parameters rather than relying on YAML. It may be better to use a local script, because you can + # reproduce results locally without piecing together a command based on the YAML. + executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named # 'continueOnError', the parameter value is not correctly picked up. # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter sdlContinueOnError: false # optional: determines whether to continue the build if the step errors; + # optional: determines if build artifacts should be downloaded. + downloadArtifacts: true + # optional: determines if this job should search the directory of downloaded artifacts for + # 'tar.gz' and 'zip' archive files and extract them before running SDL validation tasks. + extractArchiveArtifacts: false dependsOn: '' # Optional: dependencies of the job artifactNames: '' # Optional: patterns supplied to DownloadBuildArtifacts # Usage: # artifactNames: # - 'BlobArtifacts' # - 'Artifacts_Windows_NT_Release' + # Optional: download a list of pipeline artifacts. 'downloadArtifacts' controls build artifacts, + # not pipeline artifacts, so doesn't affect the use of this parameter. + pipelineArtifactNames: [] + # Optional: location and ID of the AzDO build that the build/pipeline artifacts should be + # downloaded from. By default, uses runtime expressions to decide based on the variables set by + # the 'setupMaestroVars' dependency. Overriding this parameter is necessary if SDL tasks are + # running without Maestro++/BAR involved, or to download artifacts from a specific existing build + # to iterate quickly on SDL changes. + AzDOProjectName: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + AzDOPipelineId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + AzDOBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] jobs: - job: Run_SDL dependsOn: ${{ parameters.dependsOn }} displayName: Run SDL tool + condition: eq( ${{ parameters.enable }}, 'true') variables: - group: DotNet-VSTS-Bot + - name: AzDOProjectName + value: ${{ parameters.AzDOProjectName }} + - name: AzDOPipelineId + value: ${{ parameters.AzDOPipelineId }} + - name: AzDOBuildId + value: ${{ parameters.AzDOBuildId }} + # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in + # sync with the packages.config file. + - name: DefaultGuardianVersion + value: 0.53.3 + - name: GuardianVersion + value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} + - name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config pool: - name: Hosted VS2017 + # To extract archives (.tar.gz, .zip), we need access to "tar", added in Windows 10/2019. + ${{ if eq(parameters.extractArchiveArtifacts, 'false') }}: + name: Hosted VS2017 + ${{ if ne(parameters.extractArchiveArtifacts, 'false') }}: + vmImage: windows-2019 steps: - checkout: self clean: true - - ${{ if ne(parameters.artifactNames, '') }}: - - ${{ each artifactName in parameters.artifactNames }}: + + - ${{ if ne(parameters.downloadArtifacts, 'false')}}: + - ${{ if ne(parameters.artifactNames, '') }}: + - ${{ each artifactName in parameters.artifactNames }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Build Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: ${{ artifactName }} + downloadPath: $(Build.ArtifactStagingDirectory)\artifacts + checkDownloadedFiles: true + - ${{ if eq(parameters.artifactNames, '') }}: - task: DownloadBuildArtifacts@0 displayName: Download Build Artifacts inputs: - buildType: current - artifactName: ${{ artifactName }} + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + downloadType: specific files + itemPattern: "**" downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - - ${{ if eq(parameters.artifactNames, '') }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Build Artifacts + checkDownloadedFiles: true + + - ${{ each artifactName in parameters.pipelineArtifactNames }}: + - task: DownloadPipelineArtifact@2 + displayName: Download Pipeline Artifacts inputs: - buildType: current - downloadType: specific files - itemPattern: "**" + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: ${{ artifactName }} downloadPath: $(Build.ArtifactStagingDirectory)\artifacts + checkDownloadedFiles: true + - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts - -ExtractPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts + -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts + -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts displayName: Extract Blob Artifacts continueOnError: ${{ parameters.sdlContinueOnError }} + - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts - -ExtractPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts + -InputPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts + -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts displayName: Extract Package Artifacts continueOnError: ${{ parameters.sdlContinueOnError }} + + - ${{ if ne(parameters.extractArchiveArtifacts, 'false') }}: + - powershell: eng/common/sdl/extract-artifact-archives.ps1 + -InputPath $(Build.ArtifactStagingDirectory)\artifacts + -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts + displayName: Extract Archive Artifacts + continueOnError: ${{ parameters.sdlContinueOnError }} + + - ${{ if ne(parameters.overrideGuardianVersion, '') }}: + - powershell: | + $content = Get-Content $(GuardianPackagesConfigFile) + + Write-Host "packages.config content was:`n$content" + + $content = $content.Replace('$(DefaultGuardianVersion)', '$(GuardianVersion)') + $content | Set-Content $(GuardianPackagesConfigFile) + + Write-Host "packages.config content updated to:`n$content" + displayName: Use overridden Guardian version ${{ parameters.overrideGuardianVersion }} + - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' - task: NuGetCommand@2 @@ -59,15 +151,35 @@ jobs: nugetConfigPath: $(Build.SourcesDirectory)\eng\common\sdl\NuGet.config externalFeedCredentials: GuardianConnect restoreDirectory: $(Build.SourcesDirectory)\.packages + - ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: eng/common/sdl/execute-all-sdl-tools.ps1 ${{ parameters.overrideParameters }} + - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} displayName: Execute SDL continueOnError: ${{ parameters.sdlContinueOnError }} - ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: eng/common/sdl/execute-all-sdl-tools.ps1 - -GuardianPackageName Microsoft.Guardian.Cli.0.7.2 + - powershell: ${{ parameters.executeAllSdlToolsScript }} + -GuardianPackageName Microsoft.Guardian.Cli.$(GuardianVersion) -NugetPackageDirectory $(Build.SourcesDirectory)\.packages -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) ${{ parameters.additionalParameters }} displayName: Execute SDL continueOnError: ${{ parameters.sdlContinueOnError }} + + - ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: + # We want to publish the Guardian results and configuration for easy diagnosis. However, the + # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default + # tooling files. Some of these files are large and aren't useful during an investigation, so + # exclude them by simply deleting them before publishing. (As of writing, there is no documented + # way to selectively exclude a dir from the pipeline artifact publish task.) + - task: DeleteFiles@1 + displayName: Delete Guardian dependencies to avoid uploading + inputs: + SourceFolder: $(Agent.BuildDirectory)/.gdn + Contents: | + c + i + condition: succeededOrFailed() + - publish: $(Agent.BuildDirectory)/.gdn + artifact: GuardianConfiguration + displayName: Publish GuardianConfiguration + condition: succeededOrFailed() diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index ffda80a197b..37dceb1bab0 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -1,67 +1,36 @@ +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + parameters: # Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job cancelTimeoutInMinutes: '' - condition: '' - - continueOnError: false - container: '' - + continueOnError: false dependsOn: '' - displayName: '' - - steps: [] - pool: '' - + steps: [] strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - # Job base template specific parameters - # Optional: Enable installing Microbuild plugin - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _TeamName - the name of your team - # _SignType - 'test' or 'real' +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + artifacts: '' enableMicrobuild: false - - # Optional: Include PublishBuildArtifacts task enablePublishBuildArtifacts: false - - # Optional: Enable publishing to the build asset registry enablePublishBuildAssets: false - - # Optional: Prevent gather/push manifest from executing when using publishing pipelines - enablePublishUsingPipelines: false - - # Optional: Include PublishTestResults task enablePublishTestResults: false - - # Optional: enable sending telemetry - enableTelemetry: false - - # Optional: define the helix repo for telemetry (example: 'dotnet/arcade') - helixRepo: '' - - # Optional: define the helix type for telemetry (example: 'build/product/') - helixType: '' - - # Required: name of the job + enablePublishUsingPipelines: false + mergeTestResults: false + testRunTitle: '' + testResultsFormat: '' name: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + preSteps: [] runAsPublic: false -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: - job: ${{ parameters.name }} @@ -93,9 +62,12 @@ jobs: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} variables: - - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE value: '$(Build.Repository.Uri)' + - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: + - name: EnableRichCodeNavigation + value: 'true' - ${{ each variable in parameters.variables }}: # handle name-value variable syntax # example: @@ -125,22 +97,13 @@ jobs: workspace: ${{ parameters.workspace }} steps: - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - # Telemetry tasks are built from https://github.com/dotnet/arcade-extensions - - task: sendStartTelemetry@0 - displayName: 'Send Helix Start Telemetry' - inputs: - helixRepo: ${{ parameters.helixRepo }} - ${{ if ne(parameters.helixType, '') }}: - helixType: ${{ parameters.helixType }} - buildConfig: $(_BuildConfig) - runAsPublic: ${{ parameters.runAsPublic }} - continueOnError: ${{ parameters.continueOnError }} - condition: always() + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildSigningPlugin@2 + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildSigningPlugin@3 displayName: Install MicroBuild plugin inputs: signType: $(_SignType) @@ -151,12 +114,28 @@ jobs: continueOnError: ${{ parameters.continueOnError }} condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: NuGetAuthenticate@0 + - ${{ if or(eq(parameters.artifacts.download, 'true'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + - ${{ each step in parameters.steps }}: - ${{ step }} + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + continueOnError: true + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: MicroBuildCleanup@1 @@ -166,30 +145,83 @@ jobs: env: TeamName: $(_TeamName) - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - # Telemetry tasks are built from https://github.com/dotnet/arcade-extensions - - task: sendEndTelemetry@0 - displayName: 'Send Helix End Telemetry' - continueOnError: ${{ parameters.continueOnError }} - condition: always() - - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if or(eq(parameters.artifacts.publish.artifacts, 'true'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if or(eq(parameters.artifacts.publish.logs, 'true'), ne(parameters.artifacts.publish.logs, '')) }}: + - publish: artifacts/log + artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: Publish logs + continueOnError: true + condition: always() + - ${{ if or(eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - ${{ if and(ne(parameters.enablePublishUsingPipelines, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: CopyFiles@2 + displayName: Gather Asset Manifests + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/AssetManifest' + TargetFolder: '$(Build.ArtifactStagingDirectory)/AssetManifests' + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) + + - task: PublishBuildArtifacts@1 + displayName: Push Asset Manifests + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/AssetManifests' + PublishLocation: Container + ArtifactName: AssetManifests + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - task: PublishBuildArtifacts@1 displayName: Publish Logs inputs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' PublishLocation: Container - ArtifactName: $(Agent.Os)_$(Agent.JobName) + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} continueOnError: true condition: always() - - ${{ if eq(parameters.enablePublishTestResults, 'true') }}: + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: - task: PublishTestResults@2 - displayName: Publish Test Results + displayName: Publish XUnit Test Results inputs: testResultsFormat: 'xUnit' testResultsFiles: '*.xml' searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} continueOnError: true condition: always() diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml new file mode 100644 index 00000000000..e8bc77d2ebb --- /dev/null +++ b/eng/common/templates/job/onelocbuild.yml @@ -0,0 +1,93 @@ +parameters: + # Optional: dependencies of the job + dependsOn: '' + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: + vmImage: vs2017-win2016 + + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex + GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + + SourcesDirectory: $(Build.SourcesDirectory) + CreatePr: true + AutoCompletePr: false + UseLfLineEndings: true + UseCheckedInLocProjectJson: false + LanguageSet: VS_Main_Languages + LclSource: lclFilesInRepo + LclPackageId: '' + RepoType: gitHub + GitHubOrg: dotnet + MirrorRepo: '' + MirrorBranch: main + condition: '' + +jobs: +- job: OneLocBuild + + dependsOn: ${{ parameters.dependsOn }} + + displayName: OneLocBuild + + pool: ${{ parameters.pool }} + + variables: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + - name: _GenerateLocProjectArguments + value: -SourcesDirectory ${{ parameters.SourcesDirectory }} + -LanguageSet "${{ parameters.LanguageSet }}" + -CreateNeutralXlfs + - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: + - name: _GenerateLocProjectArguments + value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson + + + steps: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + arguments: $(_GenerateLocProjectArguments) + displayName: Generate LocProject.json + condition: ${{ parameters.condition }} + + - task: OneLocBuild@2 + displayName: OneLocBuild + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + locProj: eng/Localize/LocProject.json + outDir: $(Build.ArtifactStagingDirectory) + lclSource: ${{ parameters.LclSource }} + lclPackageId: ${{ parameters.LclPackageId }} + isCreatePrSelected: ${{ parameters.CreatePr }} + ${{ if eq(parameters.CreatePr, true) }}: + isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} + isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + packageSourceAuth: patAuth + patVariable: ${{ parameters.CeapexPat }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + repoType: ${{ parameters.RepoType }} + gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if ne(parameters.MirrorRepo, '') }}: + isMirrorRepoSelected: true + gitHubOrganization: ${{ parameters.GitHubOrg }} + mirrorRepo: ${{ parameters.MirrorRepo }} + mirrorBranch: ${{ parameters.MirrorBranch }} + condition: ${{ parameters.condition }} + + - task: PublishBuildArtifacts@1 + displayName: Publish Localization Files + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} + + - task: PublishBuildArtifacts@1 + displayName: Publish LocProject.json + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates/job/performance.yml b/eng/common/templates/job/performance.yml deleted file mode 100644 index f877fd7a898..00000000000 --- a/eng/common/templates/job/performance.yml +++ /dev/null @@ -1,95 +0,0 @@ -parameters: - steps: [] # optional -- any additional steps that need to happen before pulling down the performance repo and sending the performance benchmarks to helix (ie building your repo) - variables: [] # optional -- list of additional variables to send to the template - jobName: '' # required -- job name - displayName: '' # optional -- display name for the job. Will use jobName if not passed - pool: '' # required -- name of the Build pool - container: '' # required -- name of the container - osGroup: '' # required -- operating system for the job - extraSetupParameters: '' # optional -- extra arguments to pass to the setup script - frameworks: ['netcoreapp3.0'] # optional -- list of frameworks to run against - continueOnError: 'false' # optional -- determines whether to continue the build if the step errors - dependsOn: '' # optional -- dependencies of the job - timeoutInMinutes: 320 # optional -- timeout for the job - enableTelemetry: false # optional -- enable for telemetry - -jobs: -- template: ../jobs/jobs.yml - parameters: - dependsOn: ${{ parameters.dependsOn }} - enableTelemetry: ${{ parameters.enableTelemetry }} - enablePublishBuildArtifacts: true - continueOnError: ${{ parameters.continueOnError }} - - jobs: - - job: '${{ parameters.jobName }}' - - ${{ if ne(parameters.displayName, '') }}: - displayName: '${{ parameters.displayName }}' - ${{ if eq(parameters.displayName, '') }}: - displayName: '${{ parameters.jobName }}' - - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - variables: - - - ${{ each variable in parameters.variables }}: - - ${{ if ne(variable.name, '') }}: - - name: ${{ variable.name }} - value: ${{ variable.value }} - - ${{ if ne(variable.group, '') }}: - - group: ${{ variable.group }} - - - IsInternal: '' - - HelixApiAccessToken: '' - - HelixPreCommand: '' - - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq( parameters.osGroup, 'Windows_NT') }}: - - HelixPreCommand: 'set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - - IsInternal: -Internal - - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - - HelixPreCommand: 'export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - - IsInternal: --internal - - - group: DotNet-HelixApi-Access - - group: dotnet-benchview - - workspace: - clean: all - pool: - ${{ parameters.pool }} - container: ${{ parameters.container }} - strategy: - matrix: - ${{ each framework in parameters.frameworks }}: - ${{ framework }}: - _Framework: ${{ framework }} - steps: - - checkout: self - clean: true - # Run all of the steps to setup repo - - ${{ each step in parameters.steps }}: - - ${{ step }} - - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal) -Framework $(_Framework) ${{ parameters.extraSetupParameters }} - displayName: Performance Setup (Windows) - condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal) --framework $(_Framework) ${{ parameters.extraSetupParameters }} - displayName: Performance Setup (Unix) - condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $(Python) $(PerformanceDirectory)/scripts/ci_setup.py $(SetupArguments) - displayName: Run ci setup script - # Run perf testing in helix - - template: /eng/common/templates/steps/perf-send-to-helix.yml - parameters: - HelixSource: '$(HelixSourcePrefix)/$(Build.Repository.Name)/$(Build.SourceBranch)' # sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'test/performance/$(Kind)/$(_Framework)/$(Architecture)' - HelixAccessToken: $(HelixApiAccessToken) - HelixTargetQueues: $(Queue) - HelixPreCommands: $(HelixPreCommand) - Creator: $(Creator) - WorkItemTimeout: 4:00 # 4 hours - WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy - CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions \ No newline at end of file diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index b722975f9c2..fe9dfdf720c 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -37,6 +37,13 @@ jobs: - name: _BuildConfig value: ${{ parameters.configuration }} - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + # Skip component governance and codesign validation for SDL. These jobs + # create no content. + - name: skipComponentGovernanceDetection + value: true + - name: runCodesignValidationInjection + value: false steps: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: @@ -45,12 +52,19 @@ jobs: inputs: artifactName: AssetManifests downloadPath: '$(Build.StagingDirectory)/Download' + checkDownloadedFiles: true condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: NuGetAuthenticate@0 + - task: PowerShell@2 + displayName: Enable cross-org NuGet feed authentication + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-all-orgs-artifact-feeds-rw) + - task: PowerShell@2 displayName: Publish Build Assets inputs: @@ -61,6 +75,7 @@ jobs: /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:Configuration=$(_BuildConfig) + /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} @@ -79,13 +94,32 @@ jobs: PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' PublishLocation: Container ArtifactName: ReleaseConfigs - + + - task: powershell@2 + displayName: Check if SymbolPublishingExclusionsFile.txt exists + inputs: + targetType: inline + script: | + $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + if(Test-Path -Path $symbolExclusionfile) + { + Write-Host "SymbolExclusionFile exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" + } + else{ + Write-Host "Symbols Exclusion file does not exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" + } + + - task: PublishBuildArtifacts@1 + displayName: Publish SymbolPublishingExclusionsFile Artifact + condition: eq(variables['SymbolExclusionFile'], 'true') + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + PublishLocation: Container + ArtifactName: ReleaseConfigs + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - task: PublishBuildArtifacts@1 - displayName: Publish Logs to VSTS - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: $(Agent.Os)_PublishBuildAssets - continueOnError: true - condition: always() + - template: /eng/common/templates/steps/publish-logs.yml + parameters: + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates/job/source-build.yml b/eng/common/templates/job/source-build.yml new file mode 100644 index 00000000000..5023d36dcb3 --- /dev/null +++ b/eng/common/templates/job/source-build.yml @@ -0,0 +1,60 @@ +parameters: + # This template adds arcade-powered source-build to CI. The template produces a server job with a + # default ID 'Source_Build_Complete' to put in a dependency list if necessary. + + # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. + jobNamePrefix: 'Source_Build' + + # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for + # managed-only repositories. This is an object with these properties: + # + # name: '' + # The name of the job. This is included in the job ID. + # targetRID: '' + # The name of the target RID to use, instead of the one auto-detected by Arcade. + # nonPortable: false + # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than + # linux-x64), and compiling against distro-provided packages rather than portable ones. + # skipPublishValidation: false + # Disables publishing validation. By default, a check is performed to ensure no packages are + # published by source-build. + # container: '' + # A container to use. Runs in docker. + # pool: {} + # A pool to use. Runs directly on an agent. + # buildScript: '' + # Specifies the build script to invoke to perform the build in the repo. The default + # './build.sh' should work for typical Arcade repositories, but this is customizable for + # difficult situations. + # jobProperties: {} + # A list of job properties to inject at the top level, for potential extensibility beyond + # container and pool. + platform: {} + + # The default VM host AzDO pool. This should be capable of running Docker containers: almost all + # source-build builds run in Docker, including the default managed platform. + defaultContainerHostPool: + vmImage: ubuntu-20.04 + +jobs: +- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} + displayName: Source-Build (${{ parameters.platform.name }}) + + ${{ each property in parameters.platform.jobProperties }}: + ${{ property.key }}: ${{ property.value }} + + ${{ if ne(parameters.platform.container, '') }}: + container: ${{ parameters.platform.container }} + + ${{ if eq(parameters.platform.pool, '') }}: + pool: ${{ parameters.defaultContainerHostPool }} + ${{ if ne(parameters.platform.pool, '') }}: + pool: ${{ parameters.platform.pool }} + + workspace: + clean: all + + steps: + - template: /eng/common/templates/steps/source-build.yml + parameters: + platform: ${{ parameters.platform }} diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml new file mode 100644 index 00000000000..1cc0c29e4fd --- /dev/null +++ b/eng/common/templates/job/source-index-stage1.yml @@ -0,0 +1,57 @@ +parameters: + runAsPublic: false + sourceIndexPackageVersion: 1.0.1-20210614.1 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" + preSteps: [] + binlogPath: artifacts/log/Debug/Build.binlog + pool: + vmImage: vs2017-win2016 + condition: '' + dependsOn: '' + +jobs: +- job: SourceIndexStage1 + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + variables: + - name: SourceIndexPackageVersion + value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexPackageSource + value: ${{ parameters.sourceIndexPackageSource }} + - name: BinlogPath + value: ${{ parameters.binlogPath }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: source-dot-net stage1 variables + + pool: ${{ parameters.pool }} + steps: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - task: UseDotNet@2 + displayName: Use .NET Core sdk 3.1 + inputs: + packageType: sdk + version: 3.1.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + + - script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: Download Tools + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + + - script: ${{ parameters.sourceIndexBuildCommand }} + displayName: Build Repository + + - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: Process Binlog into indexable sln + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) + displayName: Upload stage1 artifacts to source index + env: + BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml index 6a2f98c036f..a1f8fce96ca 100644 --- a/eng/common/templates/jobs/jobs.yml +++ b/eng/common/templates/jobs/jobs.yml @@ -1,41 +1,29 @@ parameters: - # Optional: 'true' if failures in job.yml job should not fail the job + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md continueOnError: false - # Optional: Enable installing Microbuild plugin - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _TeamName - the name of your team - # _SignType - 'test' or 'real' - enableMicrobuild: false - # Optional: Include PublishBuildArtifacts task enablePublishBuildArtifacts: false - # Optional: Enable publishing to the build asset registry - enablePublishBuildAssets: false - # Optional: Enable publishing using release pipelines enablePublishUsingPipelines: false - + + # Optional: Enable running the source-build jobs to build repo from source + enableSourceBuild: false + + # Optional: Parameters for source-build template. + # See /eng/common/templates/jobs/source-build.yml for options + sourceBuildParameters: [] + graphFileGeneration: # Optional: Enable generating the graph files at the end of the build enabled: false # Optional: Include toolset dependencies in the generated graph files includeToolset: false - # Optional: Include PublishTestResults task - enablePublishTestResults: false - - # Optional: enable sending telemetry - # if enabled then the 'helixRepo' parameter should also be specified - enableTelemetry: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job jobs: [] - # Optional: define the helix repo for telemetry (example: 'dotnet/arcade') - helixRepo: '' - # Optional: Override automatically derived dependsOn value for "publish build assets" job publishBuildAssetsDependsOn: '' @@ -43,6 +31,9 @@ parameters: # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. runAsPublic: false + enableSourceIndex: false + sourceIndexParams: {} + # Internal resources (telemetry, microbuild) can only be accessed from non-public projects, # and some (Microbuild) should only be applied to non-PR cases for internal builds. @@ -62,29 +53,47 @@ jobs: name: ${{ job.job }} -- ${{ if and(eq(parameters.enablePublishBuildAssets, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: ../job/publish-build-assets.yml +- ${{ if eq(parameters.enableSourceBuild, true) }}: + - template: /eng/common/templates/jobs/source-build.yml parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - pool: - vmImage: vs2017-win2016 - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - -- ${{ if and(eq(parameters.graphFileGeneration.enabled, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: ../job/generate-graph-files.yml + allCompletedJobId: Source_Build_Complete + ${{ each parameter in parameters.sourceBuildParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if eq(parameters.enableSourceIndex, 'true') }}: + - template: ../job/source-index-stage1.yml parameters: - continueOnError: ${{ parameters.continueOnError }} - includeToolset: ${{ parameters.graphFileGeneration.includeToolset }} - dependsOn: - - Asset_Registry_Publish - pool: - vmImage: vs2017-win2016 + runAsPublic: ${{ parameters.runAsPublic }} + ${{ each parameter in parameters.sourceIndexParams }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + - ${{ if eq(parameters.enableSourceBuild, true) }}: + - Source_Build_Complete + pool: + vmImage: vs2017-win2016 + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + + - ${{ if eq(parameters.graphFileGeneration.enabled, true) }}: + - template: ../job/generate-graph-files.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + includeToolset: ${{ parameters.graphFileGeneration.includeToolset }} + dependsOn: + - Asset_Registry_Publish + pool: + vmImage: vs2017-win2016 diff --git a/eng/common/templates/jobs/source-build.yml b/eng/common/templates/jobs/source-build.yml new file mode 100644 index 00000000000..00aa98eb3bf --- /dev/null +++ b/eng/common/templates/jobs/source-build.yml @@ -0,0 +1,46 @@ +parameters: + # This template adds arcade-powered source-build to CI. A job is created for each platform, as + # well as an optional server job that completes when all platform jobs complete. + + # The name of the "join" job for all source-build platforms. If set to empty string, the job is + # not included. Existing repo pipelines can use this job depend on all source-build jobs + # completing without maintaining a separate list of every single job ID: just depend on this one + # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. + allCompletedJobId: '' + + # See /eng/common/templates/job/source-build.yml + jobNamePrefix: 'Source_Build' + + # This is the default platform provided by Arcade, intended for use by a managed-only repo. + defaultManagedPlatform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-3e800f1-20190501005343' + + # Defines the platforms on which to run build jobs. One job is created for each platform, and the + # object in this array is sent to the job template as 'platform'. If no platforms are specified, + # one job runs on 'defaultManagedPlatform'. + platforms: [] + +jobs: + +- ${{ if ne(parameters.allCompletedJobId, '') }}: + - job: ${{ parameters.allCompletedJobId }} + displayName: Source-Build Complete + pool: server + dependsOn: + - ${{ each platform in parameters.platforms }}: + - ${{ parameters.jobNamePrefix }}_${{ platform.name }} + - ${{ if eq(length(parameters.platforms), 0) }}: + - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} + +- ${{ each platform in parameters.platforms }}: + - template: /eng/common/templates/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ platform }} + +- ${{ if eq(length(parameters.platforms), 0) }}: + - template: /eng/common/templates/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ parameters.defaultManagedPlatform }} diff --git a/eng/common/templates/phases/base.yml b/eng/common/templates/phases/base.yml deleted file mode 100644 index 0123cf43b16..00000000000 --- a/eng/common/templates/phases/base.yml +++ /dev/null @@ -1,130 +0,0 @@ -parameters: - # Optional: Clean sources before building - clean: true - - # Optional: Git fetch depth - fetchDepth: '' - - # Optional: name of the phase (not specifying phase name may cause name collisions) - name: '' - # Optional: display name of the phase - displayName: '' - - # Optional: condition for the job to run - condition: '' - - # Optional: dependencies of the phase - dependsOn: '' - - # Required: A defined YAML queue - queue: {} - - # Required: build steps - steps: [] - - # Optional: variables - variables: {} - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - ## Telemetry variables - - # Optional: enable sending telemetry - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _HelixBuildConfig - differentiate between Debug, Release, other - # _HelixSource - Example: build/product - # _HelixType - Example: official/dotnet/arcade/$(Build.SourceBranch) - enableTelemetry: false - - # Optional: Enable installing Microbuild plugin - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _TeamName - the name of your team - # _SignType - 'test' or 'real' - enableMicrobuild: false - -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - -phases: -- phase: ${{ parameters.name }} - - ${{ if ne(parameters.displayName, '') }}: - displayName: ${{ parameters.displayName }} - - ${{ if ne(parameters.condition, '') }}: - condition: ${{ parameters.condition }} - - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }} - - queue: ${{ parameters.queue }} - - ${{ if ne(parameters.variables, '') }}: - variables: - ${{ insert }}: ${{ parameters.variables }} - - steps: - - checkout: self - clean: ${{ parameters.clean }} - ${{ if ne(parameters.fetchDepth, '') }}: - fetchDepth: ${{ parameters.fetchDepth }} - - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - - template: /eng/common/templates/steps/telemetry-start.yml - parameters: - buildConfig: $(_HelixBuildConfig) - helixSource: $(_HelixSource) - helixType: $(_HelixType) - runAsPublic: ${{ parameters.runAsPublic }} - - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - # Internal only resource, and Microbuild signing shouldn't be applied to PRs. - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildSigningPlugin@2 - displayName: Install MicroBuild plugin - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - - env: - TeamName: $(_TeamName) - continueOnError: false - condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - - # Run provided build steps - - ${{ parameters.steps }} - - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - # Internal only resources - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildCleanup@1 - displayName: Execute Microbuild cleanup tasks - condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - env: - TeamName: $(_TeamName) - - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - - template: /eng/common/templates/steps/telemetry-end.yml - parameters: - helixSource: $(_HelixSource) - helixType: $(_HelixType) - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: CopyFiles@2 - displayName: Gather Asset Manifests - inputs: - SourceFolder: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/AssetManifest' - TargetFolder: '$(Build.StagingDirectory)/AssetManifests' - continueOnError: false - condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) - - task: PublishBuildArtifacts@1 - displayName: Push Asset Manifests - inputs: - PathtoPublish: '$(Build.StagingDirectory)/AssetManifests' - PublishLocation: Container - ArtifactName: AssetManifests - continueOnError: false - condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) diff --git a/eng/common/templates/phases/publish-build-assets.yml b/eng/common/templates/phases/publish-build-assets.yml deleted file mode 100644 index a0a8074282a..00000000000 --- a/eng/common/templates/phases/publish-build-assets.yml +++ /dev/null @@ -1,51 +0,0 @@ -parameters: - dependsOn: '' - queue: {} - configuration: 'Debug' - condition: succeeded() - continueOnError: false - runAsPublic: false - publishUsingPipelines: false -phases: - - phase: Asset_Registry_Publish - displayName: Publish to Build Asset Registry - dependsOn: ${{ parameters.dependsOn }} - queue: ${{ parameters.queue }} - variables: - _BuildConfig: ${{ parameters.configuration }} - steps: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - task: AzureKeyVault@1 - inputs: - azureSubscription: 'DotNet-Engineering-Services_KeyVault' - KeyVaultName: EngKeyVault - SecretsFilter: 'MaestroAccessToken' - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - task: PowerShell@2 - displayName: Publish Build Assets - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} - /p:Configuration=$(_BuildConfig) - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - task: PublishBuildArtifacts@1 - displayName: Publish Logs to VSTS - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: $(Agent.Os)_Asset_Registry_Publish - continueOnError: true - condition: always() diff --git a/eng/common/templates/post-build/channels/generic-internal-channel.yml b/eng/common/templates/post-build/channels/generic-internal-channel.yml index ad9375f5e5c..8990dfc8c87 100644 --- a/eng/common/templates/post-build/channels/generic-internal-channel.yml +++ b/eng/common/templates/post-build/channels/generic-internal-channel.yml @@ -1,5 +1,10 @@ parameters: - publishInstallersAndChecksums: false + BARBuildId: '' + PromoteToChannelIds: '' + artifactsPublishingAdditionalParameters: '' + dependsOn: + - Validate + publishInstallersAndChecksums: true symbolPublishingAdditionalParameters: '' stageName: '' channelName: '' @@ -10,37 +15,65 @@ parameters: stages: - stage: ${{ parameters.stageName }} - dependsOn: validate + dependsOn: ${{ parameters.dependsOn }} variables: - template: ../common-variables.yml displayName: ${{ parameters.channelName }} Publishing jobs: - template: ../setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - job: + - job: publish_symbols displayName: Symbol Publishing dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }} )) + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} )) variables: - group: DotNet-Symbol-Server-Pats + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] pool: vmImage: 'windows-2019' steps: + - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions." + displayName: Warn about v2 Arcade Publishing Usage + # This is necessary whenever we want to publish/restore to an AzDO private feed - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - artifactName: 'BlobArtifacts' + displayName: Download Build Assets continueOnError: true + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + downloadType: 'specific' + itemPattern: | + PdbArtifacts/** + BlobArtifacts/** + downloadPath: '$(Build.ArtifactStagingDirectory)' + checkDownloadedFiles: true - - task: DownloadBuildArtifacts@0 - displayName: Download PDB Artifacts + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@0 + displayName: 'Authenticate to AzDO Feeds' + + - task: PowerShell@2 + displayName: Enable cross-org publishing inputs: - artifactName: 'PDBArtifacts' - continueOnError: true + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) - task: PowerShell@2 displayName: Publish @@ -53,39 +86,52 @@ stages: /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' /p:Configuration=Release + /p:PublishToMSDL=false ${{ parameters.symbolPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'SymbolPublishing' + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars + timeoutInMinutes: 120 variables: - - group: DotNet-Blob-Feed - - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: IsStableBuild value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }})) + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} )) pool: vmImage: 'windows-2019' steps: - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: current - artifactName: PackageArtifacts + - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions." + displayName: Warn about v2 Arcade Publishing Usage - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: current - artifactName: BlobArtifacts - - - task: DownloadBuildArtifacts@0 - displayName: Download Asset Manifests + displayName: Download Build Assets + continueOnError: true inputs: - buildType: current - artifactName: AssetManifests + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + downloadType: 'specific' + itemPattern: | + PackageArtifacts/** + BlobArtifacts/** + AssetManifests/** + downloadPath: '$(Build.ArtifactStagingDirectory)' + checkDownloadedFiles: true - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' @@ -105,6 +151,7 @@ stages: inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet + /p:PublishingInfraVersion=2 /p:IsStableBuild=$(IsStableBuild) /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) @@ -119,12 +166,11 @@ stages: /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' /p:Configuration=Release - /p:PublishInstallersAndChecksums=true + /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }} /p:ChecksumsTargetStaticFeed=$(InternalChecksumsBlobFeedUrl) /p:ChecksumsAzureAccountKey=$(InternalChecksumsBlobFeedKey) /p:InstallersTargetStaticFeed=$(InternalInstallersBlobFeedUrl) /p:InstallersAzureAccountKey=$(InternalInstallersBlobFeedKey) - /p:PublishToAzureDevOpsNuGetFeeds=true /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}' @@ -134,6 +180,11 @@ stages: /p:PublishToMSDL=false ${{ parameters.artifactsPublishingAdditionalParameters }} - - template: ../../steps/promote-build.yml + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'AssetsPublishing' + + - template: ../../steps/add-build-to-channel.yml parameters: ChannelId: ${{ parameters.channelId }} diff --git a/eng/common/templates/post-build/channels/generic-public-channel.yml b/eng/common/templates/post-build/channels/generic-public-channel.yml index c4bc1897d81..3220c6a4f92 100644 --- a/eng/common/templates/post-build/channels/generic-public-channel.yml +++ b/eng/common/templates/post-build/channels/generic-public-channel.yml @@ -1,6 +1,10 @@ parameters: + BARBuildId: '' + PromoteToChannelIds: '' artifactsPublishingAdditionalParameters: '' - publishInstallersAndChecksums: false + dependsOn: + - Validate + publishInstallersAndChecksums: true symbolPublishingAdditionalParameters: '' stageName: '' channelName: '' @@ -8,36 +12,54 @@ parameters: transportFeed: '' shippingFeed: '' symbolsFeed: '' + # If the channel name is empty, no links will be generated + akaMSChannelName: '' stages: - stage: ${{ parameters.stageName }} - dependsOn: validate + dependsOn: ${{ parameters.dependsOn }} variables: - template: ../common-variables.yml displayName: ${{ parameters.channelName }} Publishing jobs: - template: ../setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - job: + - job: publish_symbols displayName: Symbol Publishing dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }} )) + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} )) variables: - group: DotNet-Symbol-Server-Pats + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] pool: vmImage: 'windows-2019' steps: - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - artifactName: 'BlobArtifacts' - continueOnError: true + - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions." + displayName: Warn about v2 Arcade Publishing Usage - task: DownloadBuildArtifacts@0 - displayName: Download PDB Artifacts - inputs: - artifactName: 'PDBArtifacts' + displayName: Download Build Assets continueOnError: true + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + downloadType: 'specific' + itemPattern: | + PdbArtifacts/** + BlobArtifacts/** + downloadPath: '$(Build.ArtifactStagingDirectory)' + checkDownloadedFiles: true # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here @@ -64,37 +86,51 @@ stages: /p:Configuration=Release ${{ parameters.symbolPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'SymbolPublishing' + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars + timeoutInMinutes: 120 variables: - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: IsStableBuild value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }})) + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] + - name: ArtifactsCategory + value: ${{ coalesce(variables._DotNetArtifactsCategory, '.NETCore') }} + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} )) pool: vmImage: 'windows-2019' steps: - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: current - artifactName: PackageArtifacts - continueOnError: true + - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions." + displayName: Warn about v2 Arcade Publishing Usage - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: current - artifactName: BlobArtifacts + displayName: Download Build Assets continueOnError: true - - - task: DownloadBuildArtifacts@0 - displayName: Download Asset Manifests inputs: - buildType: current - artifactName: AssetManifests + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + downloadType: 'specific' + itemPattern: | + PackageArtifacts/** + BlobArtifacts/** + AssetManifests/** + downloadPath: '$(Build.ArtifactStagingDirectory)' + checkDownloadedFiles: true - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' @@ -114,7 +150,8 @@ stages: inputs: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet - /p:ArtifactsCategory=$(_DotNetArtifactsCategory) + /p:PublishingInfraVersion=2 + /p:ArtifactsCategory=$(ArtifactsCategory) /p:IsStableBuild=$(IsStableBuild) /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) @@ -134,15 +171,22 @@ stages: /p:InstallersAzureAccountKey=$(dotnetcli-storage-key) /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl) /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key) - /p:PublishToAzureDevOpsNuGetFeeds=true /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}' /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' /p:AzureDevOpsStaticSymbolsFeed='${{ parameters.symbolsFeed }}' /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' + /p:LatestLinkShortUrlPrefix=dotnet/'${{ parameters.akaMSChannelName }}' + /p:AkaMSClientId=$(akams-client-id) + /p:AkaMSClientSecret=$(akams-client-secret) ${{ parameters.artifactsPublishingAdditionalParameters }} - - template: ../../steps/promote-build.yml + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'AssetsPublishing' + + - template: ../../steps/add-build-to-channel.yml parameters: ChannelId: ${{ parameters.channelId }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index 216d043e4e3..c99fd750376 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -4,13 +4,13 @@ variables: - group: DotNet-DotNetCli-Storage - group: DotNet-MSRC-Storage - group: Publish-Build-Assets - + # .NET Core 3.1 Dev - name: PublicDevRelease_31_Channel_Id value: 128 - # .NET Core 5 Dev - - name: NetCore_5_Dev_Channel_Id + # .NET 5 Dev + - name: Net_5_Dev_Channel_Id value: 131 # .NET Eng - Validation @@ -49,6 +49,10 @@ variables: - name: NetCore_31_Blazor_Features_Channel_Id value: 531 + # .NET Core Experimental + - name: NetCore_Experimental_Channel_Id + value: 562 + # Whether the build is internal or not - name: IsInternalBuild value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} @@ -59,7 +63,7 @@ variables: - name: MaestroApiAccessToken value: $(MaestroAccessToken) - name: MaestroApiVersion - value: "2019-01-16" + value: "2020-02-20" - name: SourceLinkCLIVersion value: 3.0.0 @@ -86,3 +90,10 @@ variables: value: https://dotnetclimsrc.blob.core.windows.net/dotnet/index.json - name: InternalInstallersBlobFeedKey value: $(dotnetclimsrc-access-key) + + # Skip component governance and codesign validation for SDL. These jobs + # create no content. + - name: skipComponentGovernanceDetection + value: true + - name: runCodesignValidationInjection + value: false diff --git a/eng/common/templates/post-build/darc-gather-drop.yml b/eng/common/templates/post-build/darc-gather-drop.yml deleted file mode 100644 index 3268ccaa551..00000000000 --- a/eng/common/templates/post-build/darc-gather-drop.yml +++ /dev/null @@ -1,23 +0,0 @@ -parameters: - ChannelId: 0 - -jobs: -- job: gatherDrop - displayName: Gather Drop - dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.ChannelId }})) - variables: - - name: BARBuildId - value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Darc gather-drop - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/darc-gather-drop.ps1 - arguments: -BarBuildId $(BARBuildId) - -DropLocation $(Agent.BuildDirectory)/Temp/Drop/ - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index b121d77e07d..4f79cf0f337 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -1,14 +1,31 @@ parameters: + # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. + # Publishing V2 accepts optionally outlining the publishing stages - default is inline. + # Publishing V3 DOES NOT accept inlining the publishing stages. + publishingInfraVersion: 2 + # When set to true the publishing templates from the repo will be used + # otherwise Darc add-build-to-channel will be used to trigger the promotion pipeline + inline: true + + # Only used if inline==false. When set to true will stall the current build until + # the Promotion Pipeline build finishes. Otherwise, the current build will continue + # execution concurrently with the promotion build. + waitPublishingFinish: true + + BARBuildId: '' + PromoteToChannelIds: '' + enableSourceLinkValidation: false enableSigningValidation: true enableSymbolValidation: false enableNugetValidation: true - publishInstallersAndChecksums: false + publishInstallersAndChecksums: true SDLValidationParameters: enable: false continueOnError: false params: '' artifactNames: '' + downloadArtifacts: true # These parameters let the user customize the call to sdk-task.ps1 for publishing # symbols & general artifacts as well as for signing validation @@ -17,24 +34,90 @@ parameters: signingValidationAdditionalParameters: '' # Which stages should finish execution before post-build stages start - dependsOn: [build] + validateDependsOn: + - build + publishDependsOn: + - Validate + + # Channel ID's instantiated in this file. + # When adding a new channel implementation the call to `check-channel-consistency.ps1` + # needs to be updated with the new channel ID + NetEngLatestChannelId: 2 + NetEngValidationChannelId: 9 + NetDev5ChannelId: 131 + NetDev6ChannelId: 1296 + GeneralTestingChannelId: 529 + NETCoreToolingDevChannelId: 548 + NETCoreToolingReleaseChannelId: 549 + NETInternalToolingChannelId: 551 + NETCoreExperimentalChannelId: 562 + NetEngServicesIntChannelId: 678 + NetEngServicesProdChannelId: 679 + NetCoreSDK313xxChannelId: 759 + NetCoreSDK313xxInternalChannelId: 760 + NetCoreSDK314xxChannelId: 921 + NetCoreSDK314xxInternalChannelId: 922 + VS166ChannelId: 1010 + VS167ChannelId: 1011 + VS168ChannelId: 1154 + VSMasterChannelId: 1012 + VS169ChannelId: 1473 + VS1610ChannelId: 1692 stages: -- stage: validate - dependsOn: ${{ parameters.dependsOn }} - displayName: Validate - jobs: - - ${{ if eq(parameters.enableNugetValidation, 'true') }}: +- ${{ if or(and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')), eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + - stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Validate Build Assets + variables: + - template: common-variables.yml + jobs: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - ${{ if and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')) }}: + - job: + displayName: Post-build Checks + dependsOn: setupMaestroVars + variables: + - name: TargetChannels + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'] ] + pool: + vmImage: 'windows-2019' + steps: + - task: PowerShell@2 + displayName: Maestro Channels Consistency + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/check-channel-consistency.ps1 + arguments: -PromoteToChannels "$(TargetChannels)" + -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}},${{parameters.VS169ChannelId}},${{parameters.VS1610ChannelId}} + - job: displayName: NuGet Validation + dependsOn: setupMaestroVars + condition: eq( ${{ parameters.enableNugetValidation }}, 'true') pool: vmImage: 'windows-2019' + variables: + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] steps: - task: DownloadBuildArtifacts@0 displayName: Download Package Artifacts inputs: - buildType: current + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) artifactName: PackageArtifacts + checkDownloadedFiles: true - task: PowerShell@2 displayName: Validate @@ -43,47 +126,88 @@ stages: arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - - ${{ if eq(parameters.enableSigningValidation, 'true') }}: - job: displayName: Signing Validation + dependsOn: setupMaestroVars + condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) + variables: + - template: common-variables.yml + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] pool: vmImage: 'windows-2019' steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + itemPattern: | + ** + !**/Microsoft.SourceBuild.Intermediate.*.nupkg + # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here # otherwise it'll complain about accessing a private feed. - task: NuGetAuthenticate@0 displayName: 'Authenticate to AzDO Feeds' - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts + - task: PowerShell@2 + displayName: Enable cross-org publishing inputs: - buildType: current - artifactName: PackageArtifacts + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. - task: PowerShell@2 displayName: Validate inputs: filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine dotnet + arguments: -task SigningValidation -restore -msbuildEngine vs /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - /p:Configuration=Release ${{ parameters.signingValidationAdditionalParameters }} - - ${{ if eq(parameters.enableSourceLinkValidation, 'true') }}: + - template: ../steps/publish-logs.yml + parameters: + StageLabel: 'Validation' + JobLabel: 'Signing' + - job: displayName: SourceLink Validation + dependsOn: setupMaestroVars + condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') variables: - template: common-variables.yml + - name: AzDOProjectName + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ] + - name: AzDOPipelineId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ] + - name: AzDOBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ] pool: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 displayName: Download Blob Artifacts inputs: - buildType: current + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) artifactName: BlobArtifacts + checkDownloadedFiles: true - task: PowerShell@2 displayName: Validate @@ -96,249 +220,370 @@ stages: -SourcelinkCliVersion $(SourceLinkCLIVersion) continueOnError: true - - ${{ if eq(parameters.SDLValidationParameters.enable, 'true') }}: - template: /eng/common/templates/job/execute-sdl.yml parameters: + enable: ${{ parameters.SDLValidationParameters.enable }} + dependsOn: setupMaestroVars additionalParameters: ${{ parameters.SDLValidationParameters.params }} continueOnError: ${{ parameters.SDLValidationParameters.continueOnError }} artifactNames: ${{ parameters.SDLValidationParameters.artifactNames }} + downloadArtifacts: ${{ parameters.SDLValidationParameters.downloadArtifacts }} + +- ${{ if or(ge(parameters.publishingInfraVersion, 3), eq(parameters.inline, 'false')) }}: + - stage: publish_using_darc + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.publishDependsOn }} + ${{ if and(ne(parameters.enableNugetValidation, 'true'), ne(parameters.enableSigningValidation, 'true'), ne(parameters.enableSourceLinkValidation, 'true'), ne(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Publish using Darc + variables: + - template: common-variables.yml + jobs: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - job: + displayName: Publish Using Darc + dependsOn: setupMaestroVars + timeoutInMinutes: 120 + variables: + - name: BARBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + pool: + vmImage: 'windows-2019' + steps: + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion ${{ parameters.PublishingInfraVersion }} + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish ${{ parameters.waitPublishingFinish }} + -PublishInstallersAndChecksums ${{ parameters.publishInstallersAndChecksums }} + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + +- ${{ if and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')) }}: + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NetCore_Dev5_Publish' + channelName: '.NET 5 Dev' + akaMSChannelName: 'net5/dev' + channelId: ${{ parameters.NetDev5ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NetCore_Dev6_Publish' + channelName: '.NET 6 Dev' + akaMSChannelName: 'net6/dev' + channelId: ${{ parameters.NetDev6ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'Net_Eng_Latest_Publish' + channelName: '.NET Eng - Latest' + akaMSChannelName: 'eng/daily' + channelId: ${{ parameters.NetEngLatestChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'Net_Eng_Validation_Publish' + channelName: '.NET Eng - Validation' + akaMSChannelName: 'eng/validation' + channelId: ${{ parameters.NetEngValidationChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'General_Testing_Publish' + channelName: 'General Testing' + akaMSChannelName: 'generaltesting' + channelId: ${{ parameters.GeneralTestingChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_Tooling_Dev_Publishing' + channelName: '.NET Core Tooling Dev' + channelId: ${{ parameters.NETCoreToolingDevChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_Tooling_Release_Publishing' + channelName: '.NET Core Tooling Release' + channelId: ${{ parameters.NETCoreToolingReleaseChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NET_Internal_Tooling_Publishing' + channelName: '.NET Internal Tooling' + channelId: ${{ parameters.NETInternalToolingChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_Experimental_Publishing' + channelName: '.NET Core Experimental' + channelId: ${{ parameters.NETCoreExperimentalChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'Net_Eng_Services_Int_Publish' + channelName: '.NET Eng Services - Int' + channelId: ${{ parameters.NetEngServicesIntChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'Net_Eng_Services_Prod_Publish' + channelName: '.NET Eng Services - Prod' + channelId: ${{ parameters.NetEngServicesProdChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_314xx_Publishing' + channelName: '.NET Core SDK 3.1.4xx' + channelId: ${{ parameters.NetCoreSDK314xxChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_314xx_Internal_Publishing' + channelName: '.NET Core SDK 3.1.4xx Internal' + channelId: ${{ parameters.NetCoreSDK314xxInternalChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_313xx_Publishing' + channelName: '.NET Core SDK 3.1.3xx' + channelId: ${{ parameters.NetCoreSDK313xxChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_313xx_Internal_Publishing' + channelName: '.NET Core SDK 3.1.3xx Internal' + channelId: ${{ parameters.NetCoreSDK313xxInternalChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS16_6_Publishing' + channelName: 'VS 16.6' + channelId: ${{ parameters.VS166ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS16_7_Publishing' + channelName: 'VS 16.7' + channelId: ${{ parameters.VS167ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS16_8_Publishing' + channelName: 'VS 16.8' + channelId: ${{ parameters.VS168ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS_Master_Publishing' + channelName: 'VS Master' + channelId: ${{ parameters.VSMasterChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' + + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS_16_9_Publishing' + channelName: 'VS 16.9' + channelId: ${{ parameters.VS169ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Dev5_Publish' - channelName: '.NET Core 5 Dev' - channelId: 131 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Dev31_Publish' - channelName: '.NET Core 3.1 Dev' - channelId: 128 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'Net_Eng_Latest_Publish' - channelName: '.NET Eng - Latest' - channelId: 2 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'Net_Eng_Validation_Publish' - channelName: '.NET Eng - Validation' - channelId: 9 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_3_Tools_Validation_Publish' - channelName: '.NET 3 Tools - Validation' - channelId: 390 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_3_Tools_Publish' - channelName: '.NET 3 Tools' - channelId: 344 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Release30_Publish' - channelName: '.NET Core 3.0 Release' - channelId: 19 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Release31_Publish' - channelName: '.NET Core 3.1 Release' - channelId: 129 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Blazor31_Features_Publish' - channelName: '.NET Core 3.1 Blazor Features' - channelId: 531 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_30_Internal_Servicing_Publishing' - channelName: '.NET Core 3.0 Internal Servicing' - channelId: 184 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_31_Internal_Servicing_Publishing' - channelName: '.NET Core 3.1 Internal Servicing' - channelId: 550 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'General_Testing_Publish' - channelName: 'General Testing' - channelId: 529 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_Tooling_Dev_Publishing' - channelName: '.NET Core Tooling Dev' - channelId: 548 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_Tooling_Release_Publishing' - channelName: '.NET Core Tooling Release' - channelId: 549 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_301xx_Publishing' - channelName: '.NET Core SDK 3.0.1xx' - channelId: 556 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_301xx_Internal_Publishing' - channelName: '.NET Core SDK 3.0.1xx Internal' - channelId: 555 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_311xx_Publishing' - channelName: '.NET Core SDK 3.1.1xx' - channelId: 560 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_311xx_Internal_Publishing' - channelName: '.NET Core SDK 3.1.1xx Internal' - channelId: 559 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_312xx_Publishing' - channelName: '.NET Core SDK 3.1.2xx' - channelId: 558 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_312xx_Internal_Publishing' - channelName: '.NET Core SDK 3.1.2xx Internal' - channelId: 557 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' \ No newline at end of file + - template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'VS_16_10_Publishing' + channelName: 'VS 16.10' + channelId: ${{ parameters.VS1610ChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' diff --git a/eng/common/templates/post-build/promote-build.yml b/eng/common/templates/post-build/promote-build.yml deleted file mode 100644 index 6b479c3b82a..00000000000 --- a/eng/common/templates/post-build/promote-build.yml +++ /dev/null @@ -1,25 +0,0 @@ -parameters: - ChannelId: 0 - -jobs: -- job: - displayName: Promote Build - dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.ChannelId }})) - variables: - - name: BARBuildId - value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - - name: ChannelId - value: ${{ parameters.ChannelId }} - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId $(ChannelId) - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index 56242b068e1..4a22b2e6f6d 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -1,18 +1,78 @@ +parameters: + BARBuildId: '' + PromoteToChannelIds: '' + jobs: - job: setupMaestroVars displayName: Setup Maestro Vars + variables: + - template: common-variables.yml pool: vmImage: 'windows-2019' steps: - - task: DownloadBuildArtifacts@0 - displayName: Download Release Configs - inputs: - buildType: current - artifactName: ReleaseConfigs + - checkout: none + + - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Release Configs + inputs: + buildType: current + artifactName: ReleaseConfigs + checkDownloadedFiles: true - task: PowerShell@2 name: setReleaseVars displayName: Set Release Configs Vars inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/setup-maestro-vars.ps1 - arguments: -ReleaseConfigsPath '$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt' + targetType: inline + script: | + try { + if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + $Channels = $Content | Select -Index 1 + $IsStableBuild = $Content | Select -Index 2 + + $AzureDevOpsProject = $Env:System_TeamProject + $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId + $AzureDevOpsBuildId = $Env:Build_BuildId + } + else { + $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + + $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $apiHeaders.Add('Accept', 'application/json') + $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") + + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + + $BarId = $Env:BARBuildId + $Channels = $Env:PromoteToMaestroChannels -split "," + $Channels = $Channels -join "][" + $Channels = "[$Channels]" + + $IsStableBuild = $buildInfo.stable + $AzureDevOpsProject = $buildInfo.azureDevOpsProject + $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId + $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId + } + + Write-Host "##vso[task.setvariable variable=BARBuildId;isOutput=true]$BarId" + Write-Host "##vso[task.setvariable variable=TargetChannels;isOutput=true]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild;isOutput=true]$IsStableBuild" + + Write-Host "##vso[task.setvariable variable=AzDOProjectName;isOutput=true]$AzureDevOpsProject" + Write-Host "##vso[task.setvariable variable=AzDOPipelineId;isOutput=true]$AzureDevOpsBuildDefinitionId" + Write-Host "##vso[task.setvariable variable=AzDOBuildId;isOutput=true]$AzureDevOpsBuildId" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } + env: + MAESTRO_API_TOKEN: $(MaestroApiAccessToken) + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/templates/steps/add-build-to-channel.yml b/eng/common/templates/steps/add-build-to-channel.yml new file mode 100644 index 00000000000..f67a210d62f --- /dev/null +++ b/eng/common/templates/steps/add-build-to-channel.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Add Build to Channel + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml deleted file mode 100644 index b3ea9acf1f1..00000000000 --- a/eng/common/templates/steps/perf-send-to-helix.yml +++ /dev/null @@ -1,66 +0,0 @@ -# Please remember to update the documentation if you make changes to these parameters! -parameters: - HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' - HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group - HelixPreCommands: '' # optional -- commands to run before Helix work item execution - HelixPostCommands: '' # optional -- commands to run after Helix work item execution - WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects - CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload - IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk' or 'runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json - EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control - WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." - Creator: '' # optional -- if the build is external, use this to specify who is sending the job - DisplayNamePrefix: 'Send job to Helix' # optional -- rename the beginning of the displayName of the steps in AzDO - condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() - continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false - -steps: - - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\perfhelixpublish.proj /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/perfhelixpublish.proj /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates/steps/promote-build.yml b/eng/common/templates/steps/promote-build.yml deleted file mode 100644 index b90404435dd..00000000000 --- a/eng/common/templates/steps/promote-build.yml +++ /dev/null @@ -1,13 +0,0 @@ -parameters: - ChannelId: 0 - -steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml new file mode 100644 index 00000000000..88f238f36bf --- /dev/null +++ b/eng/common/templates/steps/publish-logs.yml @@ -0,0 +1,23 @@ +parameters: + StageLabel: '' + JobLabel: '' + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' + PublishLocation: Container + ArtifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml index 05df886f55f..cd02ae1607f 100644 --- a/eng/common/templates/steps/send-to-helix.yml +++ b/eng/common/templates/steps/send-to-helix.yml @@ -10,7 +10,7 @@ parameters: HelixPostCommands: '' # optional -- commands to run after Helix work item execution WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects - WorkItemTimeout: '' # optional -- a timeout in seconds for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload XUnitProjects: '' # optional -- semicolon delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects @@ -18,11 +18,12 @@ parameters: XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk' or 'runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json + DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting int) Creator: '' # optional -- if the build is external, use this to specify who is sending the job DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() @@ -55,6 +56,7 @@ steps: DotNetCliVersion: ${{ parameters.DotNetCliVersion }} EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} Creator: ${{ parameters.Creator }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) @@ -85,6 +87,7 @@ steps: DotNetCliVersion: ${{ parameters.DotNetCliVersion }} EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} Creator: ${{ parameters.Creator }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml new file mode 100644 index 00000000000..ba40dc82f14 --- /dev/null +++ b/eng/common/templates/steps/source-build.yml @@ -0,0 +1,102 @@ +parameters: + # This template adds arcade-powered source-build to CI. + + # This is a 'steps' template, and is intended for advanced scenarios where the existing build + # infra has a careful build methodology that must be followed. For example, a repo + # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline + # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to + # GitHub. Using this steps template leaves room for that infra to be included. + + # Defines the platform on which to run the steps. See 'eng/common/templates/job/source-build.yml' + # for details. The entire object is described in the 'job' template for simplicity, even though + # the usage of the properties on this object is split between the 'job' and 'steps' templates. + platform: {} + +steps: +# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) +- script: | + set -x + df -h + + # If building on the internal project, the artifact feeds variable may be available (usually only if needed) + # In that case, call the feed setup script to add internal feeds corresponding to public ones. + # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. + # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those + # changes. + $internalRestoreArgs= + if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then + # Temporarily work around https://github.com/dotnet/arcade/issues/7709 + chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) + internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' + + # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. + # This only works if there is a username/email configured, which won't be the case in most CI runs. + git config --get user.email + if [ $? -ne 0 ]; then + git config user.email dn-bot@microsoft.com + git config user.name dn-bot + fi + fi + + # If building on the internal project, the internal storage variable may be available (usually only if needed) + # In that case, add variables to allow the download of internal runtimes if the specified versions are not found + # in the default public locations. + internalRuntimeDownloadArgs= + if [ '$(dotnetclimsrc-read-sas-token-base64)' != '$''(dotnetclimsrc-read-sas-token-base64)' ]; then + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetclimsrc.blob.core.windows.net/dotnet /p:DotNetRuntimeSourceFeedKey=$(dotnetclimsrc-read-sas-token-base64) --runtimesourcefeed https://dotnetclimsrc.blob.core.windows.net/dotnet --runtimesourcefeedkey $(dotnetclimsrc-read-sas-token-base64)' + fi + + buildConfig=Release + # Check if AzDO substitutes in a build config from a variable, and use it if so. + if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then + buildConfig='$(_BuildConfig)' + fi + + officialBuildArgs= + if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then + officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' + fi + + targetRidArgs= + if [ '${{ parameters.platform.targetRID }}' != '' ]; then + targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' + fi + + publishArgs= + if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then + publishArgs='--publish' + fi + + ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ + --configuration $buildConfig \ + --restore --build --pack $publishArgs -bl \ + $officialBuildArgs \ + $internalRuntimeDownloadArgs \ + $internalRestoreArgs \ + $targetRidArgs \ + /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ + /p:ArcadeBuildFromSource=true + displayName: Build + +# Upload build logs for diagnosis. +- task: CopyFiles@2 + displayName: Prepare BuildLogs staging directory + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + artifacts/source-build/self/prebuilt-report/** + TargetFolder: '$(Build.StagingDirectory)/BuildLogs' + CleanTargetFolder: true + continueOnError: true + condition: succeededOrFailed() + +- task: PublishPipelineArtifact@1 + displayName: Publish BuildLogs + inputs: + targetPath: '$(Build.StagingDirectory)/BuildLogs' + artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) + continueOnError: true + condition: succeededOrFailed() diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 92a053bd16b..02347914f5d 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -5,11 +5,13 @@ [bool]$ci = if (Test-Path variable:ci) { $ci } else { $false } # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. -[string]$configuration = if (Test-Path variable:configuration) { $configuration } else { "Debug" } +[string]$configuration = if (Test-Path variable:configuration) { $configuration } else { 'Debug' } + +# Set to true to opt out of outputting binary log while running in CI +[bool]$excludeCIBinarylog = if (Test-Path variable:excludeCIBinarylog) { $excludeCIBinarylog } else { $false } # Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. -# Binary log must be enabled on CI. -[bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci } +[bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci -and !$excludeCIBinarylog } # Set to true to use the pipelines logger which will enable Azure logging output. # https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md @@ -24,7 +26,7 @@ [bool]$restore = if (Test-Path variable:restore) { $restore } else { $true } # Adjusts msbuild verbosity level. -[string]$verbosity = if (Test-Path variable:verbosity) { $verbosity } else { "minimal" } +[string]$verbosity = if (Test-Path variable:verbosity) { $verbosity } else { 'minimal' } # Set to true to reuse msbuild nodes. Recommended to not reuse on CI. [bool]$nodeReuse = if (Test-Path variable:nodeReuse) { $nodeReuse } else { !$ci } @@ -40,23 +42,31 @@ [bool]$useInstalledDotNetCli = if (Test-Path variable:useInstalledDotNetCli) { $useInstalledDotNetCli } else { $true } # Enable repos to use a particular version of the on-line dotnet-install scripts. -# default URL: https://dot.net/v1/dotnet-install.ps1 -[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { "v1" } +# default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1 +[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { 'v1' } # True to use global NuGet cache instead of restoring packages to repository-local directory. [bool]$useGlobalNuGetCache = if (Test-Path variable:useGlobalNuGetCache) { $useGlobalNuGetCache } else { !$ci } +# True to exclude prerelease versions Visual Studio during build +[bool]$excludePrereleaseVS = if (Test-Path variable:excludePrereleaseVS) { $excludePrereleaseVS } else { $false } + # An array of names of processes to stop on script exit if prepareMachine is true. -$processesToStopOnExit = if (Test-Path variable:processesToStopOnExit) { $processesToStopOnExit } else { @("msbuild", "dotnet", "vbcscompiler") } +$processesToStopOnExit = if (Test-Path variable:processesToStopOnExit) { $processesToStopOnExit } else { @('msbuild', 'dotnet', 'vbcscompiler') } + +$disableConfigureToolsetImport = if (Test-Path variable:disableConfigureToolsetImport) { $disableConfigureToolsetImport } else { $null } set-strictmode -version 2.0 -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -function Create-Directory([string[]] $path) { - if (!(Test-Path $path)) { - New-Item -path $path -force -itemType "Directory" | Out-Null - } +# If specifies, provides an alternate path for getting .NET Core SDKs and Runtimes. This script will still try public sources first. +[string]$runtimeSourceFeed = if (Test-Path variable:runtimeSourceFeed) { $runtimeSourceFeed } else { $null } +# Base-64 encoded SAS token that has permission to storage container described by $runtimeSourceFeed +[string]$runtimeSourceFeedKey = if (Test-Path variable:runtimeSourceFeedKey) { $runtimeSourceFeedKey } else { $null } + +function Create-Directory ([string[]] $path) { + New-Item -Path $path -Force -ItemType 'Directory' | Out-Null } function Unzip([string]$zipfile, [string]$outpath) { @@ -96,7 +106,50 @@ function Exec-Process([string]$command, [string]$commandArgs) { } } -function InitializeDotNetCli([bool]$install) { +# Take the given block, print it, print what the block probably references from the current set of +# variables using low-effort string matching, then run the block. +# +# This is intended to replace the pattern of manually copy-pasting a command, wrapping it in quotes, +# and printing it using "Write-Host". The copy-paste method is more readable in build logs, but less +# maintainable and less reliable. It is easy to make a mistake and modify the command without +# properly updating the "Write-Host" line, resulting in misleading build logs. The probability of +# this mistake makes the pattern hard to trust when it shows up in build logs. Finding the bug in +# existing source code can also be difficult, because the strings are not aligned to each other and +# the line may be 300+ columns long. +# +# By removing the need to maintain two copies of the command, Exec-BlockVerbosely avoids the issues. +# +# In Bash (or any posix-like shell), "set -x" prints usable verbose output automatically. +# "Set-PSDebug" appears to be similar at first glance, but unfortunately, it isn't very useful: it +# doesn't print any info about the variables being used by the command, which is normally the +# interesting part to diagnose. +function Exec-BlockVerbosely([scriptblock] $block) { + Write-Host "--- Running script block:" + $blockString = $block.ToString().Trim() + Write-Host $blockString + + Write-Host "--- List of variables that might be used:" + # For each variable x in the environment, check the block for a reference to x via simple "$x" or + # "@x" syntax. This doesn't detect other ways to reference variables ("${x}" nor "$variable:x", + # among others). It only catches what this function was originally written for: simple + # command-line commands. + $variableTable = Get-Variable | + Where-Object { + $blockString.Contains("`$$($_.Name)") -or $blockString.Contains("@$($_.Name)") + } | + Format-Table -AutoSize -HideTableHeaders -Wrap | + Out-String + Write-Host $variableTable.Trim() + + Write-Host "--- Executing:" + & $block + Write-Host "--- Done running script block!" +} + +# createSdkLocationFile parameter enables a file being generated under the toolset directory +# which writes the sdk's location into. This is only necessary for cmd --> powershell invocations +# as dot sourcing isn't possible. +function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { if (Test-Path variable:global:_DotNetInstallDir) { return $global:_DotNetInstallDir } @@ -110,6 +163,9 @@ function InitializeDotNetCli([bool]$install) { # Disable telemetry on CI. if ($ci) { $env:DOTNET_CLI_TELEMETRY_OPTOUT=1 + + # In case of network error, try to log the current IP for reference + Try-LogClientIpAddress } # Source Build uses DotNetCoreSdkDir variable @@ -119,7 +175,9 @@ function InitializeDotNetCli([bool]$install) { # Find the first path on %PATH% that contains the dotnet.exe if ($useInstalledDotNetCli -and (-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -eq $null)) { - $dotnetCmd = Get-Command "dotnet.exe" -ErrorAction SilentlyContinue + $dotnetExecutable = GetExecutableFileName 'dotnet' + $dotnetCmd = Get-Command $dotnetExecutable -ErrorAction SilentlyContinue + if ($dotnetCmd -ne $null) { $env:DOTNET_INSTALL_DIR = Split-Path $dotnetCmd.Path -Parent } @@ -129,16 +187,16 @@ function InitializeDotNetCli([bool]$install) { # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. - if ((-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -ne $null) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) { + if ((-not $globalJsonHasRuntimes) -and (-not [string]::IsNullOrEmpty($env:DOTNET_INSTALL_DIR)) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) { $dotnetRoot = $env:DOTNET_INSTALL_DIR } else { - $dotnetRoot = Join-Path $RepoRoot ".dotnet" + $dotnetRoot = Join-Path $RepoRoot '.dotnet' if (-not (Test-Path(Join-Path $dotnetRoot "sdk\$dotnetSdkVersion"))) { if ($install) { InstallDotNetSdk $dotnetRoot $dotnetSdkVersion } else { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Unable to find dotnet with SDK version '$dotnetSdkVersion'" + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unable to find dotnet with SDK version '$dotnetSdkVersion'" ExitWithExitCode 1 } } @@ -146,6 +204,24 @@ function InitializeDotNetCli([bool]$install) { $env:DOTNET_INSTALL_DIR = $dotnetRoot } + # Creates a temporary file under the toolset dir. + # The following code block is protecting against concurrent access so that this function can + # be called in parallel. + if ($createSdkLocationFile) { + do { + $sdkCacheFileTemp = Join-Path $ToolsetDir $([System.IO.Path]::GetRandomFileName()) + } + until (!(Test-Path $sdkCacheFileTemp)) + Set-Content -Path $sdkCacheFileTemp -Value $dotnetRoot + + try { + Move-Item -Force $sdkCacheFileTemp (Join-Path $ToolsetDir 'sdk.txt') + } catch { + # Somebody beat us + Remove-Item -Path $sdkCacheFileTemp + } + } + # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom # build steps from using anything other than what we've downloaded. # It also ensures that VS msbuild will use the downloaded sdk targets. @@ -154,43 +230,65 @@ function InitializeDotNetCli([bool]$install) { # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build Write-PipelinePrependPath -Path $dotnetRoot - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 - if ($ci) { - $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 - $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 - Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' - Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20' - } - Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1' return $global:_DotNetInstallDir = $dotnetRoot } +function Retry($downloadBlock, $maxRetries = 5) { + $retries = 1 + + while($true) { + try { + & $downloadBlock + break + } + catch { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ + } + + if (++$retries -le $maxRetries) { + $delayInSeconds = [math]::Pow(2, $retries) - 1 # Exponential backoff + Write-Host "Retrying. Waiting for $delayInSeconds seconds before next attempt ($retries of $maxRetries)." + Start-Sleep -Seconds $delayInSeconds + } + else { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unable to download file in $maxRetries attempts." + break + } + + } +} + function GetDotNetInstallScript([string] $dotnetRoot) { - $installScript = Join-Path $dotnetRoot "dotnet-install.ps1" + $installScript = Join-Path $dotnetRoot 'dotnet-install.ps1' if (!(Test-Path $installScript)) { Create-Directory $dotnetRoot $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit - Invoke-WebRequest "https://dot.net/$dotnetInstallScriptVersion/dotnet-install.ps1" -OutFile $installScript + $uri = "https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.ps1" + + Retry({ + Write-Host "GET $uri" + Invoke-WebRequest $uri -OutFile $installScript + }) } return $installScript } -function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = "") { - InstallDotNet $dotnetRoot $version $architecture +function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = '', [switch] $noPath) { + InstallDotNet $dotnetRoot $version $architecture '' $false $runtimeSourceFeed $runtimeSourceFeedKey -noPath:$noPath } -function InstallDotNet([string] $dotnetRoot, - [string] $version, - [string] $architecture = "", - [string] $runtime = "", - [bool] $skipNonVersionedFiles = $false, - [string] $runtimeSourceFeed = "", - [string] $runtimeSourceFeedKey = "") { +function InstallDotNet([string] $dotnetRoot, + [string] $version, + [string] $architecture = '', + [string] $runtime = '', + [bool] $skipNonVersionedFiles = $false, + [string] $runtimeSourceFeed = '', + [string] $runtimeSourceFeedKey = '', + [switch] $noPath) { $installScript = GetDotNetInstallScript $dotnetRoot $installParameters = @{ @@ -201,15 +299,14 @@ function InstallDotNet([string] $dotnetRoot, if ($architecture) { $installParameters.Architecture = $architecture } if ($runtime) { $installParameters.Runtime = $runtime } if ($skipNonVersionedFiles) { $installParameters.SkipNonVersionedFiles = $skipNonVersionedFiles } + if ($noPath) { $installParameters.NoPath = $True } try { & $installScript @installParameters } catch { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Failed to install dotnet runtime '$runtime' from public location." - - # Only the runtime can be installed from a custom [private] location. - if ($runtime -and ($runtimeSourceFeed -or $runtimeSourceFeedKey)) { + if ($runtimeSourceFeed -or $runtimeSourceFeedKey) { + Write-Host "Failed to install dotnet from public location. Trying from '$runtimeSourceFeed'" if ($runtimeSourceFeed) { $installParameters.AzureFeed = $runtimeSourceFeed } if ($runtimeSourceFeedKey) { @@ -222,10 +319,11 @@ function InstallDotNet([string] $dotnetRoot, & $installScript @installParameters } catch { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Failed to install dotnet runtime '$runtime' from custom location '$runtimeSourceFeed'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from custom location '$runtimeSourceFeed'." ExitWithExitCode 1 } } else { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from public location." ExitWithExitCode 1 } } @@ -243,21 +341,34 @@ function InstallDotNet([string] $dotnetRoot, # Throws on failure. # function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = $null) { + if (-not (IsWindowsPlatform)) { + throw "Cannot initialize Visual Studio on non-Windows" + } + if (Test-Path variable:global:_MSBuildExe) { return $global:_MSBuildExe } + # Minimum VS version to require. + $vsMinVersionReqdStr = '16.8' + $vsMinVersionReqd = [Version]::new($vsMinVersionReqdStr) + + # If the version of msbuild is going to be xcopied, + # use this version. Version matches a package here: + # https://dev.azure.com/dnceng/public/_packaging?_a=package&feed=dotnet-eng&package=RoslynTools.MSBuild&protocolType=NuGet&version=16.10.0-preview2&view=overview + $defaultXCopyMSBuildVersion = '16.10.0-preview2' + if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } - $vsMinVersionStr = if ($vsRequirements.version) { $vsRequirements.version } else { "15.9" } + $vsMinVersionStr = if ($vsRequirements.version) { $vsRequirements.version } else { $vsMinVersionReqdStr } $vsMinVersion = [Version]::new($vsMinVersionStr) # Try msbuild command available in the environment. if ($env:VSINSTALLDIR -ne $null) { - $msbuildCmd = Get-Command "msbuild.exe" -ErrorAction SilentlyContinue + $msbuildCmd = Get-Command 'msbuild.exe' -ErrorAction SilentlyContinue if ($msbuildCmd -ne $null) { # Workaround for https://github.com/dotnet/roslyn/issues/35793 # Due to this issue $msbuildCmd.Version returns 0.0.0.0 for msbuild.exe 16.2+ - $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split(@('-', '+'))[0]) + $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split([char[]]@('-', '+'))[0]) if ($msbuildVersion -ge $vsMinVersion) { return $global:_MSBuildExe = $msbuildCmd.Path @@ -277,22 +388,49 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = InitializeVisualStudioEnvironmentVariables $vsInstallDir $vsMajorVersion } else { - if (Get-Member -InputObject $GlobalJson.tools -Name "xcopy-msbuild") { + if (Get-Member -InputObject $GlobalJson.tools -Name 'xcopy-msbuild') { $xcopyMSBuildVersion = $GlobalJson.tools.'xcopy-msbuild' $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0] } else { - $vsMajorVersion = $vsMinVersion.Major - $xcopyMSBuildVersion = "$vsMajorVersion.$($vsMinVersion.Minor).0-alpha" + #if vs version provided in global.json is incompatible (too low) then use the default version for xcopy msbuild download + if($vsMinVersion -lt $vsMinVersionReqd){ + Write-Host "Using xcopy-msbuild version of $defaultXCopyMSBuildVersion since VS version $vsMinVersionStr provided in global.json is not compatible" + $xcopyMSBuildVersion = $defaultXCopyMSBuildVersion + } + else{ + # If the VS version IS compatible, look for an xcopy msbuild package + # with a version matching VS. + # Note: If this version does not exist, then an explicit version of xcopy msbuild + # can be specified in global.json. This will be required for pre-release versions of msbuild. + $vsMajorVersion = $vsMinVersion.Major + $vsMinorVersion = $vsMinVersion.Minor + $xcopyMSBuildVersion = "$vsMajorVersion.$vsMinorVersion.0" + } } - $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install + $vsInstallDir = $null + if ($xcopyMSBuildVersion.Trim() -ine "none") { + $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install + if ($vsInstallDir -eq $null) { + throw "Could not xcopy msbuild. Please check that package 'RoslynTools.MSBuild @ $xcopyMSBuildVersion' exists on feed 'dotnet-eng'." + } + } if ($vsInstallDir -eq $null) { - throw "Unable to find Visual Studio that has required version and components installed" + throw 'Unable to find Visual Studio that has required version and components installed' } } $msbuildVersionDir = if ([int]$vsMajorVersion -lt 16) { "$vsMajorVersion.0" } else { "Current" } - return $global:_MSBuildExe = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin\msbuild.exe" + + $local:BinFolder = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin" + $local:Prefer64bit = if (Get-Member -InputObject $vsRequirements -Name 'Prefer64bit') { $vsRequirements.Prefer64bit } else { $false } + if ($local:Prefer64bit -and (Test-Path(Join-Path $local:BinFolder "amd64"))) { + $global:_MSBuildExe = Join-Path $local:BinFolder "amd64\msbuild.exe" + } else { + $global:_MSBuildExe = Join-Path $local:BinFolder "msbuild.exe" + } + + return $global:_MSBuildExe } function InitializeVisualStudioEnvironmentVariables([string] $vsInstallDir, [string] $vsMajorVersion) { @@ -311,7 +449,7 @@ function InstallXCopyMSBuild([string]$packageVersion) { } function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { - $packageName = "RoslynTools.MSBuild" + $packageName = 'RoslynTools.MSBuild' $packageDir = Join-Path $ToolsDir "msbuild\$packageVersion" $packagePath = Join-Path $packageDir "$packageName.$packageVersion.nupkg" @@ -321,13 +459,17 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { } Create-Directory $packageDir + Write-Host "Downloading $packageName $packageVersion" $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit - Invoke-WebRequest "https://dotnet.myget.org/F/roslyn-tools/api/v2/package/$packageName/$packageVersion/" -OutFile $packagePath + Retry({ + Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath + }) + Unzip $packagePath $packageDir } - return Join-Path $packageDir "tools" + return Join-Path $packageDir 'tools' } # @@ -344,32 +486,42 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { # or $null if no instance meeting the requirements is found on the machine. # function LocateVisualStudio([object]$vsRequirements = $null){ - if (Get-Member -InputObject $GlobalJson.tools -Name "vswhere") { + if (-not (IsWindowsPlatform)) { + throw "Cannot run vswhere on non-Windows platforms." + } + + if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') { $vswhereVersion = $GlobalJson.tools.vswhere } else { - $vswhereVersion = "2.5.2" + $vswhereVersion = '2.5.2' } $vsWhereDir = Join-Path $ToolsDir "vswhere\$vswhereVersion" - $vsWhereExe = Join-Path $vsWhereDir "vswhere.exe" + $vsWhereExe = Join-Path $vsWhereDir 'vswhere.exe' if (!(Test-Path $vsWhereExe)) { Create-Directory $vsWhereDir - Write-Host "Downloading vswhere" - Invoke-WebRequest "https://github.com/Microsoft/vswhere/releases/download/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe + Write-Host 'Downloading vswhere' + Retry({ + Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe + }) } if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } - $args = @("-latest", "-prerelease", "-format", "json", "-requires", "Microsoft.Component.MSBuild", "-products", "*") + $args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*') - if (Get-Member -InputObject $vsRequirements -Name "version") { - $args += "-version" + if (!$excludePrereleaseVS) { + $args += '-prerelease' + } + + if (Get-Member -InputObject $vsRequirements -Name 'version') { + $args += '-version' $args += $vsRequirements.version } - if (Get-Member -InputObject $vsRequirements -Name "components") { + if (Get-Member -InputObject $vsRequirements -Name 'components') { foreach ($component in $vsRequirements.components) { - $args += "-requires" + $args += '-requires' $args += $component } } @@ -386,7 +538,13 @@ function LocateVisualStudio([object]$vsRequirements = $null){ function InitializeBuildTool() { if (Test-Path variable:global:_BuildTool) { - return $global:_BuildTool + # If the requested msbuild parameters do not match, clear the cached variables. + if($global:_BuildTool.Contains('ExcludePrereleaseVS') -and $global:_BuildTool.ExcludePrereleaseVS -ne $excludePrereleaseVS) { + Remove-Item variable:global:_BuildTool + Remove-Item variable:global:_MSBuildExe + } else { + return $global:_BuildTool + } } if (-not $msbuildEngine) { @@ -395,27 +553,28 @@ function InitializeBuildTool() { # Initialize dotnet cli if listed in 'tools' $dotnetRoot = $null - if (Get-Member -InputObject $GlobalJson.tools -Name "dotnet") { + if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') { $dotnetRoot = InitializeDotNetCli -install:$restore } - if ($msbuildEngine -eq "dotnet") { + if ($msbuildEngine -eq 'dotnet') { if (!$dotnetRoot) { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "/global.json must specify 'tools.dotnet'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "/global.json must specify 'tools.dotnet'." ExitWithExitCode 1 } - $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild"; Tool = "dotnet"; Framework = "netcoreapp2.1" } + $dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet') + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'netcoreapp3.1' } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore } catch { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message $_ + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ ExitWithExitCode 1 } - $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472" } + $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472"; ExcludePrereleaseVS = $excludePrereleaseVS } } else { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'." ExitWithExitCode 1 } @@ -424,26 +583,29 @@ function InitializeBuildTool() { function GetDefaultMSBuildEngine() { # Presence of tools.vs indicates the repo needs to build using VS msbuild on Windows. - if (Get-Member -InputObject $GlobalJson.tools -Name "vs") { - return "vs" + if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { + return 'vs' } - if (Get-Member -InputObject $GlobalJson.tools -Name "dotnet") { - return "dotnet" + if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') { + return 'dotnet' } - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." ExitWithExitCode 1 } function GetNuGetPackageCachePath() { if ($env:NUGET_PACKAGES -eq $null) { - # Use local cache on CI to ensure deterministic build, + # Use local cache on CI to ensure deterministic build. + # Avoid using the http cache as workaround for https://github.com/NuGet/Home/issues/3116 # use global cache in dev builds to avoid cost of downloading packages. + # For directory normalization, see also: https://github.com/NuGet/Home/issues/7968 if ($useGlobalNuGetCache) { - $env:NUGET_PACKAGES = Join-Path $env:UserProfile ".nuget\packages" + $env:NUGET_PACKAGES = Join-Path $env:UserProfile '.nuget\packages\' } else { - $env:NUGET_PACKAGES = Join-Path $RepoRoot ".packages" + $env:NUGET_PACKAGES = Join-Path $RepoRoot '.packages\' + $env:RESTORENOCACHE = $true } } @@ -456,7 +618,7 @@ function GetSdkTaskProject([string]$taskName) { } function InitializeNativeTools() { - if (Get-Member -InputObject $GlobalJson -Name "native-tools") { + if (-Not (Test-Path variable:DisableNativeToolsetInstalls) -And (Get-Member -InputObject $GlobalJson -Name "native-tools")) { $nativeArgs= @{} if ($ci) { $nativeArgs = @{ @@ -485,20 +647,20 @@ function InitializeToolset() { } if (-not $restore) { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Toolset version $toolsetVersion has not been restored." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Toolset version $toolsetVersion has not been restored." ExitWithExitCode 1 } $buildTool = InitializeBuildTool - $proj = Join-Path $ToolsetDir "restore.proj" - $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "ToolsetRestore.binlog") } else { "" } + $proj = Join-Path $ToolsetDir 'restore.proj' + $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'ToolsetRestore.binlog') } else { '' } '' | Set-Content $proj MSBuild-Core $proj $bl /t:__WriteToolsetLocation /clp:ErrorsOnly`;NoSummary /p:__ToolsetLocationOutputFile=$toolsetLocationFile - $path = Get-Content $toolsetLocationFile -TotalCount 1 + $path = Get-Content $toolsetLocationFile -Encoding UTF8 -TotalCount 1 if (!(Test-Path $path)) { throw "Invalid toolset path: $path" } @@ -513,8 +675,19 @@ function ExitWithExitCode([int] $exitCode) { exit $exitCode } +# Check if $LASTEXITCODE is a nonzero exit code (NZEC). If so, print a Azure Pipeline error for +# diagnostics, then exit the script with the $LASTEXITCODE. +function Exit-IfNZEC([string] $category = "General") { + Write-Host "Exit code $LASTEXITCODE" + if ($LASTEXITCODE -ne 0) { + $message = "Last command failed with exit code $LASTEXITCODE." + Write-PipelineTelemetryError -Force -Category $category -Message $message + ExitWithExitCode $LASTEXITCODE + } +} + function Stop-Processes() { - Write-Host "Killing running build processes..." + Write-Host 'Killing running build processes...' foreach ($processName in $processesToStopOnExit) { Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process } @@ -529,16 +702,45 @@ function MSBuild() { if ($pipelinesLog) { $buildTool = InitializeBuildTool - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 - if ($ci -and $buildTool.Tool -eq "dotnet") { - dotnet nuget locals http-cache -c + if ($ci -and $buildTool.Tool -eq 'dotnet') { + $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 + $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20' + } + + if ($ci) { + $env:NUGET_ENABLE_EXPERIMENTAL_HTTP_RETRY = 'true' + $env:NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT = 6 + $env:NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS = 1000 + Write-PipelineSetVariable -Name 'NUGET_ENABLE_EXPERIMENTAL_HTTP_RETRY' -Value 'true' + Write-PipelineSetVariable -Name 'NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT' -Value '6' + Write-PipelineSetVariable -Name 'NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS' -Value '1000' } $toolsetBuildProject = InitializeToolset - $path = Split-Path -parent $toolsetBuildProject - $path = Join-Path $path (Join-Path $buildTool.Framework "Microsoft.DotNet.Arcade.Sdk.dll") - $args += "/logger:$path" + $basePath = Split-Path -parent $toolsetBuildProject + $possiblePaths = @( + # new scripts need to work with old packages, so we need to look for the old names/versions + (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.ArcadeLogging.dll')), + (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.Arcade.Sdk.dll')), + (Join-Path $basePath (Join-Path netcoreapp2.1 'Microsoft.DotNet.ArcadeLogging.dll')), + (Join-Path $basePath (Join-Path netcoreapp2.1 'Microsoft.DotNet.Arcade.Sdk.dll')) + (Join-Path $basePath (Join-Path netcoreapp3.1 'Microsoft.DotNet.ArcadeLogging.dll')), + (Join-Path $basePath (Join-Path netcoreapp3.1 'Microsoft.DotNet.Arcade.Sdk.dll')) + ) + $selectedPath = $null + foreach ($path in $possiblePaths) { + if (Test-Path $path -PathType Leaf) { + $selectedPath = $path + break + } + } + if (-not $selectedPath) { + Write-PipelineTelemetryError -Category 'Build' -Message 'Unable to find arcade sdk logger assembly.' + ExitWithExitCode 1 + } + $args += "/logger:$selectedPath" } MSBuild-Core @args @@ -551,13 +753,13 @@ function MSBuild() { # function MSBuild-Core() { if ($ci) { - if (!$binaryLog) { - Write-PipelineTaskError -Message "Binary log must be enabled in CI build." + if (!$binaryLog -and !$excludeCIBinarylog) { + Write-PipelineTelemetryError -Category 'Build' -Message 'Binary log must be enabled in CI build, or explicitly opted-out from with the -excludeCIBinarylog switch.' ExitWithExitCode 1 } if ($nodeReuse) { - Write-PipelineTaskError -Message "Node reuse must be disabled in CI build." + Write-PipelineTelemetryError -Category 'Build' -Message 'Node reuse must be disabled in CI build.' ExitWithExitCode 1 } } @@ -567,29 +769,43 @@ function MSBuild-Core() { $cmdArgs = "$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse /p:ContinuousIntegrationBuild=$ci" if ($warnAsError) { - $cmdArgs += " /warnaserror /p:TreatWarningsAsErrors=true" + $cmdArgs += ' /warnaserror /p:TreatWarningsAsErrors=true' } else { - $cmdArgs += " /p:TreatWarningsAsErrors=false" + $cmdArgs += ' /p:TreatWarningsAsErrors=false' } foreach ($arg in $args) { - if ($arg -ne $null -and $arg.Trim() -ne "") { + if ($null -ne $arg -and $arg.Trim() -ne "") { + if ($arg.EndsWith('\')) { + $arg = $arg + "\" + } $cmdArgs += " `"$arg`"" } } + $env:ARCADE_BUILD_TOOL_COMMAND = "$($buildTool.Path) $cmdArgs" + $exitCode = Exec-Process $buildTool.Path $cmdArgs if ($exitCode -ne 0) { - Write-PipelineTaskError -Message "Build failed." + # We should not Write-PipelineTaskError here because that message shows up in the build summary + # The build already logged an error, that's the reason it failed. Producing an error here only adds noise. + Write-Host "Build failed with exit code $exitCode. Check errors above." -ForegroundColor Red $buildLog = GetMSBuildBinaryLogCommandLineArgument $args - if ($buildLog -ne $null) { + if ($null -ne $buildLog) { Write-Host "See log: $buildLog" -ForegroundColor DarkGray } - ExitWithExitCode $exitCode + if ($ci) { + Write-PipelineSetResult -Result "Failed" -Message "msbuild execution failed." + # Exiting with an exit code causes the azure pipelines task to log yet another "noise" error + # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error + ExitWithExitCode 0 + } else { + ExitWithExitCode $exitCode + } } } @@ -597,12 +813,12 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) { foreach ($argument in $arguments) { if ($argument -ne $null) { $arg = $argument.Trim() - if ($arg.StartsWith("/bl:", "OrdinalIgnoreCase")) { - return $arg.Substring("/bl:".Length) + if ($arg.StartsWith('/bl:', "OrdinalIgnoreCase")) { + return $arg.Substring('/bl:'.Length) } - if ($arg.StartsWith("/binaryLogger:", "OrdinalIgnoreCase")) { - return $arg.Substring("/binaryLogger:".Length) + if ($arg.StartsWith('/binaryLogger:', 'OrdinalIgnoreCase')) { + return $arg.Substring('/binaryLogger:'.Length) } } } @@ -610,16 +826,39 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) { return $null } +function GetExecutableFileName($baseName) { + if (IsWindowsPlatform) { + return "$baseName.exe" + } + else { + return $baseName + } +} + +function IsWindowsPlatform() { + return [environment]::OSVersion.Platform -eq [PlatformID]::Win32NT +} + +function Get-Darc($version) { + $darcPath = "$TempDir\darc\$(New-Guid)" + if ($version -ne $null) { + & $PSScriptRoot\darc-init.ps1 -toolpath $darcPath -darcVersion $version | Out-Host + } else { + & $PSScriptRoot\darc-init.ps1 -toolpath $darcPath | Out-Host + } + return "$darcPath\darc.exe" +} + . $PSScriptRoot\pipeline-logging-functions.ps1 -$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") -$EngRoot = Resolve-Path (Join-Path $PSScriptRoot "..") -$ArtifactsDir = Join-Path $RepoRoot "artifacts" -$ToolsetDir = Join-Path $ArtifactsDir "toolset" -$ToolsDir = Join-Path $RepoRoot ".tools" -$LogDir = Join-Path (Join-Path $ArtifactsDir "log") $configuration -$TempDir = Join-Path (Join-Path $ArtifactsDir "tmp") $configuration -$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot "global.json") | ConvertFrom-Json +$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..\..\') +$EngRoot = Resolve-Path (Join-Path $PSScriptRoot '..') +$ArtifactsDir = Join-Path $RepoRoot 'artifacts' +$ToolsetDir = Join-Path $ArtifactsDir 'toolset' +$ToolsDir = Join-Path $RepoRoot '.tools' +$LogDir = Join-Path (Join-Path $ArtifactsDir 'log') $configuration +$TempDir = Join-Path (Join-Path $ArtifactsDir 'tmp') $configuration +$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json # true if global.json contains a "runtimes" section $globalJsonHasRuntimes = if ($GlobalJson.tools.PSObject.Properties.Name -Match 'runtimes') { $true } else { $false } @@ -632,3 +871,36 @@ Write-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir Write-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir Write-PipelineSetVariable -Name 'TEMP' -Value $TempDir Write-PipelineSetVariable -Name 'TMP' -Value $TempDir + +# Import custom tools configuration, if present in the repo. +# Note: Import in global scope so that the script set top-level variables without qualification. +if (!$disableConfigureToolsetImport) { + $configureToolsetScript = Join-Path $EngRoot 'configure-toolset.ps1' + if (Test-Path $configureToolsetScript) { + . $configureToolsetScript + if ((Test-Path variable:failOnConfigureToolsetError) -And $failOnConfigureToolsetError) { + if ((Test-Path variable:LastExitCode) -And ($LastExitCode -ne 0)) { + Write-PipelineTelemetryError -Category 'Build' -Message 'configure-toolset.ps1 returned a non-zero exit code' + ExitWithExitCode $LastExitCode + } + } + } +} + +function Try-LogClientIpAddress() +{ + Write-Host "Attempting to log this client's IP for Azure Package feed telemetry purposes" + try + { + $result = Invoke-WebRequest -Uri "http://co1.msedge.net/fdv2/diagnostics.aspx" -UseBasicParsing + $lines = $result.Content.Split([Environment]::NewLine) + $socketIp = $lines | Select-String -Pattern "^Socket IP:.*" + Write-Host $socketIp + $clientIp = $lines | Select-String -Pattern "^Client IP:.*" + Write-Host $clientIp + } + catch + { + Write-Host "Unable to get this machine's effective IP address for logging: $_" + } +} diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 94965a8fd2a..6a4871ef72b 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -18,9 +18,17 @@ fi # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. configuration=${configuration:-'Debug'} +# Set to true to opt out of outputting binary log while running in CI +exclude_ci_binary_log=${exclude_ci_binary_log:-false} + +if [[ "$ci" == true && "$exclude_ci_binary_log" == false ]]; then + binary_log_default=true +else + binary_log_default=false +fi + # Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. -# Binary log must be enabled on CI. -binary_log=${binary_log:-$ci} +binary_log=${binary_log:-$binary_log_default} # Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes). prepare_machine=${prepare_machine:-false} @@ -41,12 +49,12 @@ fi # Configures warning treatment in msbuild. warn_as_error=${warn_as_error:-true} -# True to attempt using .NET Core already that meets requirements specified in global.json +# True to attempt using .NET Core already that meets requirements specified in global.json # installed on the machine instead of downloading one. use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} # Enable repos to use a particular version of the on-line dotnet-install scripts. -# default URL: https://dot.net/v1/dotnet-install.sh +# default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh dotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'} # True to use global NuGet cache instead of restoring packages to repository-local directory. @@ -56,6 +64,10 @@ else use_global_nuget_cache=${use_global_nuget_cache:-true} fi +# Used when restoring .NET SDK from alternative feeds +runtime_source_feed=${runtime_source_feed:-''} +runtime_source_feed_key=${runtime_source_feed_key:-''} + # Resolve any symlinks in the given path. function ResolvePath { local path=$1 @@ -77,16 +89,16 @@ function ResolvePath { function ReadGlobalVersion { local key=$1 - local line=`grep -m 1 "$key" "$global_json_file"` - local pattern="\"$key\" *: *\"(.*)\"" + if command -v jq &> /dev/null; then + _ReadGlobalVersion="$(jq -r ".[] | select(has(\"$key\")) | .\"$key\"" "$global_json_file")" + elif [[ "$(cat "$global_json_file")" =~ \"$key\"[[:space:]\:]*\"([^\"]+) ]]; then + _ReadGlobalVersion=${BASH_REMATCH[1]} + fi - if [[ ! $line =~ $pattern ]]; then - Write-PipelineTelemetryError -category 'InitializeToolset' "Error: Cannot find \"$key\" in $global_json_file" + if [[ -z "$_ReadGlobalVersion" ]]; then + Write-PipelineTelemetryError -category 'Build' "Error: Cannot find \"$key\" in $global_json_file" ExitWithExitCode 1 fi - - # return value - _ReadGlobalVersion=${BASH_REMATCH[1]} } function InitializeDotNetCli { @@ -152,15 +164,6 @@ function InitializeDotNetCli { # build steps from using anything other than what we've downloaded. Write-PipelinePrependPath -path "$dotnet_root" - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 - if [[ "$ci" == true ]]; then - export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 - export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 - Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" - Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20" - fi - Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0" Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1" @@ -171,66 +174,95 @@ function InitializeDotNetCli { function InstallDotNetSdk { local root=$1 local version=$2 - local architecture="" - if [[ $# == 3 ]]; then + local architecture="unset" + if [[ $# -ge 3 ]]; then architecture=$3 fi - InstallDotNet "$root" "$version" $architecture + InstallDotNet "$root" "$version" $architecture 'sdk' 'false' $runtime_source_feed $runtime_source_feed_key } function InstallDotNet { local root=$1 local version=$2 - + GetDotNetInstallScript "$root" local install_script=$_GetDotNetInstallScript local archArg='' - if [[ -n "${3:-}" ]]; then + if [[ -n "${3:-}" ]] && [ "$3" != 'unset' ]; then archArg="--architecture $3" fi local runtimeArg='' - if [[ -n "${4:-}" ]]; then + if [[ -n "${4:-}" ]] && [ "$4" != 'sdk' ]; then runtimeArg="--runtime $4" fi - local skipNonVersionedFilesArg="" - if [[ "$#" -ge "5" ]]; then + if [[ "$#" -ge "5" ]] && [[ "$5" != 'false' ]]; then skipNonVersionedFilesArg="--skip-non-versioned-files" fi bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg || { local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." + echo "Failed to install dotnet SDK from public location (exit code '$exit_code')." - if [[ -n "$runtimeArg" ]]; then - local runtimeSourceFeed='' - if [[ -n "${6:-}" ]]; then - runtimeSourceFeed="--azure-feed $6" - fi + local runtimeSourceFeed='' + if [[ -n "${6:-}" ]]; then + runtimeSourceFeed="--azure-feed $6" + fi - local runtimeSourceFeedKey='' - if [[ -n "${7:-}" ]]; then - decodedFeedKey=`echo $7 | base64 --decode` - runtimeSourceFeedKey="--feed-credential $decodedFeedKey" + local runtimeSourceFeedKey='' + if [[ -n "${7:-}" ]]; then + # The 'base64' binary on alpine uses '-d' and doesn't support '--decode' + # '-d'. To work around this, do a simple detection and switch the parameter + # accordingly. + decodeArg="--decode" + if base64 --help 2>&1 | grep -q "BusyBox"; then + decodeArg="-d" fi + decodedFeedKey=`echo $7 | base64 $decodeArg` + runtimeSourceFeedKey="--feed-credential $decodedFeedKey" + fi - if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then - bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." - ExitWithExitCode $exit_code - } - else + if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then + bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." ExitWithExitCode $exit_code + } + else + if [[ $exit_code != 0 ]]; then + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." fi + ExitWithExitCode $exit_code fi } } +function with_retries { + local maxRetries=5 + local retries=1 + echo "Trying to run '$@' for maximum of $maxRetries attempts." + while [[ $((retries++)) -le $maxRetries ]]; do + "$@" + + if [[ $? == 0 ]]; then + echo "Ran '$@' successfully." + return 0 + fi + + timeout=$((3**$retries-1)) + echo "Failed to execute '$@'. Waiting $timeout seconds before next attempt ($retries out of $maxRetries)." 1>&2 + sleep $timeout + done + + echo "Failed to execute '$@' for $maxRetries times." 1>&2 + + return 1 +} + function GetDotNetInstallScript { local root=$1 local install_script="$root/dotnet-install.sh" - local install_script_url="https://dot.net/$dotnetInstallScriptVersion/dotnet-install.sh" + local install_script_url="https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.sh" if [[ ! -a "$install_script" ]]; then mkdir -p "$root" @@ -239,13 +271,21 @@ function GetDotNetInstallScript { # Use curl if available, otherwise use wget if command -v curl > /dev/null; then + # first, try directly, if this fails we will retry with verbose logging curl "$install_script_url" -sSL --retry 10 --create-dirs -o "$install_script" || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." - ExitWithExitCode $exit_code + if command -v openssl &> /dev/null; then + echo "Curl failed; dumping some information about dotnet.microsoft.com for later investigation" + echo | openssl s_client -showcerts -servername dotnet.microsoft.com -connect dotnet.microsoft.com:443 + fi + echo "Will now retry the same URL with verbose logging." + with_retries curl "$install_script_url" -sSL --verbose --retry 10 --create-dirs -o "$install_script" || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." + ExitWithExitCode $exit_code + } } - else - wget -q -O "$install_script" "$install_script_url" || { + else + with_retries wget -v -O "$install_script" "$install_script_url" || { local exit_code=$? Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to acquire dotnet install script (exit code '$exit_code')." ExitWithExitCode $exit_code @@ -260,21 +300,23 @@ function InitializeBuildTool { if [[ -n "${_InitializeBuildTool:-}" ]]; then return fi - + InitializeDotNetCli $restore # return values - _InitializeBuildTool="$_InitializeDotNetCli/dotnet" + _InitializeBuildTool="$_InitializeDotNetCli/dotnet" _InitializeBuildToolCommand="msbuild" - _InitializeBuildToolFramework="netcoreapp2.1" + _InitializeBuildToolFramework="netcoreapp3.1" } +# Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116 function GetNuGetPackageCachePath { if [[ -z ${NUGET_PACKAGES:-} ]]; then if [[ "$use_global_nuget_cache" == true ]]; then export NUGET_PACKAGES="$HOME/.nuget/packages" else export NUGET_PACKAGES="$repo_root/.packages" + export RESTORENOCACHE=true fi fi @@ -283,6 +325,9 @@ function GetNuGetPackageCachePath { } function InitializeNativeTools() { + if [[ -n "${DisableNativeToolsetInstalls:-}" ]]; then + return + fi if grep -Fq "native-tools" $global_json_file then local nativeArgs="" @@ -325,14 +370,14 @@ function InitializeToolset { if [[ "$binary_log" == true ]]; then bl="/bl:$log_dir/ToolsetRestore.binlog" fi - + echo '' > "$proj" MSBuild-Core "$proj" $bl /t:__WriteToolsetLocation /clp:ErrorsOnly\;NoSummary /p:__ToolsetLocationOutputFile="$toolset_location_file" local toolset_build_proj=`cat "$toolset_location_file"` if [[ ! -a "$toolset_build_proj" ]]; then - Write-PipelineTelemetryError -category 'InitializeToolset' "Invalid toolset path: $toolset_build_proj" + Write-PipelineTelemetryError -category 'Build' "Invalid toolset path: $toolset_build_proj" ExitWithExitCode 3 fi @@ -354,21 +399,54 @@ function StopProcesses { return 0 } +function TryLogClientIpAddress () { + echo 'Attempting to log this client''s IP for Azure Package feed telemetry purposes' + if command -v curl > /dev/null; then + curl -s 'http://co1.msedge.net/fdv2/diagnostics.aspx' | grep ' IP: ' || true + fi +} + function MSBuild { local args=$@ if [[ "$pipelines_log" == true ]]; then InitializeBuildTool InitializeToolset - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 if [[ "$ci" == true ]]; then - dotnet nuget locals http-cache -c + export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 + export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 + Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" + Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20" + + export NUGET_ENABLE_EXPERIMENTAL_HTTP_RETRY=true + export NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT=6 + export NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 + Write-PipelineSetVariable -name "NUGET_ENABLE_EXPERIMENTAL_HTTP_RETRY" -value "true" + Write-PipelineSetVariable -name "NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT" -value "6" + Write-PipelineSetVariable -name "NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS" -value "1000" fi local toolset_dir="${_InitializeToolset%/*}" - local logger_path="$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" - args=( "${args[@]}" "-logger:$logger_path" ) + # new scripts need to work with old packages, so we need to look for the old names/versions + local selectedPath= + local possiblePaths=() + possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.ArcadeLogging.dll" ) + possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" ) + possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.ArcadeLogging.dll" ) + possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.Arcade.Sdk.dll" ) + possiblePaths+=( "$toolset_dir/netcoreapp3.1/Microsoft.DotNet.ArcadeLogging.dll" ) + possiblePaths+=( "$toolset_dir/netcoreapp3.1/Microsoft.DotNet.Arcade.Sdk.dll" ) + for path in "${possiblePaths[@]}"; do + if [[ -f $path ]]; then + selectedPath=$path + break + fi + done + if [[ -z "$selectedPath" ]]; then + Write-PipelineTelemetryError -category 'Build' "Unable to find arcade sdk logger assembly." + ExitWithExitCode 1 + fi + args+=( "-logger:$selectedPath" ) fi MSBuild-Core ${args[@]} @@ -376,13 +454,13 @@ function MSBuild { function MSBuild-Core { if [[ "$ci" == true ]]; then - if [[ "$binary_log" != true ]]; then - Write-PipelineTaskError "Binary log must be enabled in CI build." + if [[ "$binary_log" != true && "$exclude_ci_binary_log" != true ]]; then + Write-PipelineTelemetryError -category 'Build' "Binary log must be enabled in CI build, or explicitly opted-out from with the -noBinaryLog switch." ExitWithExitCode 1 fi if [[ "$node_reuse" == true ]]; then - Write-PipelineTaskError "Node reuse must be disabled in CI build." + Write-PipelineTelemetryError -category 'Build' "Node reuse must be disabled in CI build." ExitWithExitCode 1 fi fi @@ -394,11 +472,26 @@ function MSBuild-Core { warnaserror_switch="/warnaserror" fi - "$_InitializeBuildTool" "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" || { - local exit_code=$? - Write-PipelineTaskError "Build failed (exit code '$exit_code')." - ExitWithExitCode $exit_code + function RunBuildTool { + export ARCADE_BUILD_TOOL_COMMAND="$_InitializeBuildTool $@" + + "$_InitializeBuildTool" "$@" || { + local exit_code=$? + # We should not Write-PipelineTaskError here because that message shows up in the build summary + # The build already logged an error, that's the reason it failed. Producing an error here only adds noise. + echo "Build failed with exit code $exit_code. Check errors above." + if [[ "$ci" == "true" ]]; then + Write-PipelineSetResult -result "Failed" -message "msbuild execution failed." + # Exiting with an exit code causes the azure pipelines task to log yet another "noise" error + # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error + ExitWithExitCode 0 + else + ExitWithExitCode $exit_code + fi + } } + + RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" } ResolvePath "${BASH_SOURCE[0]}" @@ -408,23 +501,27 @@ _script_dir=`dirname "$_ResolvePath"` eng_root=`cd -P "$_script_dir/.." && pwd` repo_root=`cd -P "$_script_dir/../.." && pwd` -artifacts_dir="$repo_root/artifacts" +repo_root="${repo_root}/" +artifacts_dir="${repo_root}artifacts" toolset_dir="$artifacts_dir/toolset" -tools_dir="$repo_root/.tools" +tools_dir="${repo_root}.tools" log_dir="$artifacts_dir/log/$configuration" temp_dir="$artifacts_dir/tmp/$configuration" -global_json_file="$repo_root/global.json" +global_json_file="${repo_root}global.json" # determine if global.json contains a "runtimes" entry global_json_has_runtimes=false -dotnetlocal_key=`grep -m 1 "runtimes" "$global_json_file"` || true -if [[ -n "$dotnetlocal_key" ]]; then +if command -v jq &> /dev/null; then + if jq -er '. | select(has("runtimes"))' "$global_json_file" &> /dev/null; then + global_json_has_runtimes=true + fi +elif [[ "$(cat "$global_json_file")" =~ \"runtimes\"[[:space:]\:]*\{ ]]; then global_json_has_runtimes=true fi # HOME may not be defined in some scenarios, but it is required by NuGet if [[ -z $HOME ]]; then - export HOME="$repo_root/artifacts/.home/" + export HOME="${repo_root}artifacts/.home/" mkdir -p "$HOME" fi @@ -437,3 +534,18 @@ Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir" Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir" Write-PipelineSetVariable -name "Temp" -value "$temp_dir" Write-PipelineSetVariable -name "TMP" -value "$temp_dir" + +# Import custom tools configuration, if present in the repo. +if [ -z "${disable_configure_toolset_import:-}" ]; then + configure_toolset_script="$eng_root/configure-toolset.sh" + if [[ -a "$configure_toolset_script" ]]; then + . "$configure_toolset_script" + fi +fi + +# TODO: https://github.com/dotnet/arcade/issues/1468 +# Temporary workaround to avoid breaking change. +# Remove once repos are updated. +if [[ -n "${useInstalledDotNetCli:-}" ]]; then + use_installed_dotnet_cli="$useInstalledDotNetCli" +fi diff --git a/eng/release/insert-into-vs.yml b/eng/release/insert-into-vs.yml index 98c3ee790de..b1048ad2e04 100644 --- a/eng/release/insert-into-vs.yml +++ b/eng/release/insert-into-vs.yml @@ -1,9 +1,10 @@ parameters: componentBranchName: '' - insertBuildPolicy: 'CloudBuild - Request RPS' + insertBuildPolicy: 'Request Perf DDRITs' insertTargetBranch: '' insertTeamEmail: '' insertTeamName: '' + completeInsertion: 'false' # 'true', 'false', 'auto' dependsOn: [build] stages: @@ -27,7 +28,7 @@ stages: - name: InsertTeamName value: ${{ parameters.insertTeamName }} - name: InsertPayloadName - value: 'F# $(Build.SourceBranchName) $(Build.BuildNumber)' + value: '${{ parameters.insertTeamName }} $(Build.SourceBranchName) $(Build.BuildNumber)' steps: - task: DownloadBuildArtifacts@0 displayName: Download Insertion Artifacts @@ -49,8 +50,23 @@ stages: inputs: filePath: $(Build.SourcesDirectory)/eng/release/scripts/GetAssemblyVersions.ps1 arguments: -assemblyVersionsPath $(Build.ArtifactStagingDirectory)\VSSetup\DevDivPackages\DependentAssemblyVersions.csv + - task: PowerShell@2 + displayName: Calculate autocompletion state + inputs: + targetType: 'inline' + pwsh: true + script: | + # mark the insertion for auto-completion if: + # `parameters.completeInsertion` == `true` + # OR + # `parameters.completeInsertion` == `auto` AND `parameters.insertTargetBranch` does not contain 'rel/' + $completeInsertion = '${{ parameters.completeInsertion }}' + $autoComplete = ($completeInsertion -Eq 'true') -Or (($completeInsertion -Eq 'auto') -And (-Not ($env:INSERTTARGETBRANCH.Contains('rel/')))) + $autoCompleteStr = if ($autoComplete) { 'true' } else { 'false' } + Write-Host "Setting InsertAutoComplete to '$autoCompleteStr'" + Write-Host "##vso[task.setvariable variable=InsertAutoComplete]$autoCompleteStr" - task: ms-vseng.MicroBuildShipTasks.55100717-a81d-45ea-a363-b8fe3ec375ad.MicroBuildInsertVsPayload@3 displayName: 'Insert VS Payload' inputs: LinkWorkItemsToPR: false - condition: and(succeeded(), eq(variables['Build.SourceBranch'], '${{ parameters.componentBranchName }}')) + condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], '${{ parameters.componentBranchName }}'), eq(variables['Build.SourceBranch'], 'refs/heads/${{ parameters.componentBranchName }}'))) diff --git a/eng/release/scripts/GetPublishUrls.ps1 b/eng/release/scripts/GetPublishUrls.ps1 index 758c20ea515..897ef398f52 100644 --- a/eng/release/scripts/GetPublishUrls.ps1 +++ b/eng/release/scripts/GetPublishUrls.ps1 @@ -8,31 +8,37 @@ param ( Set-StrictMode -version 2.0 $ErrorActionPreference = "Stop" -try { - # build map of all *.vsman files to their `info.buildVersion` values - $manifestVersionMap = @{} - Get-ChildItem -Path "$insertionDir\*" -Filter "*.vsman" | ForEach-Object { - $manifestName = Split-Path $_ -Leaf - $vsmanContents = Get-Content $_ | ConvertFrom-Json - $buildVersion = $vsmanContents.info.buildVersion - $manifestVersionMap.Add($manifestName, $buildVersion) - } +$dropUrlRegex = "(https://vsdrop\.corp\.microsoft\.com/[^\r\n;]+);([^\r\n]+)\r?\n" - # find all publish URLs - $manifests = @() - $seenManifests = @{} - $url = "https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId/logs?api-version=5.1" +function Invoke-WebRequestWithAccessToken([string] $uri, [string] $accessToken, [int] $retryCount = 5) { + Write-Host "Fetching content from $uri" $base64 = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$accessToken")) $headers = @{ Authorization = "Basic $base64" } - Write-Host "Fetching log from $url" - $json = Invoke-WebRequest -Method Get -Uri $url -Headers $headers -UseBasicParsing | ConvertFrom-Json + + for ($i = 0; $i -lt $retryCount; $i++) { + try { + return Invoke-WebRequest -Method Get -Uri $uri -Headers $headers -UseBasicParsing + } + catch { + Write-Host "Invoke-WebRequest failed: $_" + Start-Sleep -Seconds 1 + } + } + + throw "Unable to fetch $uri after $retryCount tries." +} + +# this function has to download ~500 individual logs and check each one; prone to timeouts +function Get-ManifestsViaIndividualLogs([PSObject] $manifestVersionMap, [string] $buildId, [string] $accessToken) { + $manifests = @() + $seenManifests = @{} + $json = Invoke-WebRequestWithAccessToken -uri "https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId/logs?api-version=5.1" -accessToken $accessToken | ConvertFrom-Json foreach ($l in $json.value) { $logUrl = $l.url - Write-Host "Fetching log from $logUrl" - $log = (Invoke-WebRequest -Method Get -Uri $logUrl -Headers $headers -UseBasicParsing).Content - If ($log -Match "(https://vsdrop\.corp\.microsoft\.com/[^\r\n;]+);([^\r\n]+)\r?\n") { + $log = (Invoke-WebRequestWithAccessToken -uri $logUrl -accessToken $accessToken).Content + If ($log -Match $dropUrlRegex) { $manifestShortUrl = $Matches[1] $manifestName = $Matches[2] $manifestUrl = "$manifestShortUrl;$manifestName" @@ -45,6 +51,66 @@ try { } } + return $manifests +} + +# this function only has to download 1 file and look at a very specific file +function Get-ManifestsViaZipLog([PSObject] $manifestVersionMap, [string] $buildId, [string] $accessToken) { + # create temporary location + $guid = [System.Guid]::NewGuid().ToString() + $tempDir = Join-Path ([System.IO.Path]::GetTempPath()) $guid + New-Item -ItemType Directory -Path $tempDir | Out-Null + + # download the logs + $base64 = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$accessToken")) + $headers = @{ + Authorization = "Basic $base64" + } + $uri = "https://dev.azure.com/dnceng/internal/_apis/build/builds/$buildId/logs?`$format=zip" + Invoke-WebRequest -Uri $uri -Method Get -Headers $headers -UseBasicParsing -OutFile "$tempDir/logs.zip" + + # expand the logs + New-Item -ItemType Directory -Path "$tempDir/logs" | Out-Null + Expand-Archive -Path "$tempDir/logs.zip" -DestinationPath "$tempDir/logs" + + # parse specific logs + $logDir = "$tempDir/logs" + $manifests = @() + $seenManifests = @{} + Get-ChildItem $logDir -r -inc "*Upload VSTS Drop*" | ForEach-Object { + $result = Select-String -Path $_ -Pattern "(https://vsdrop\.corp\.microsoft\.com[^;]+);(.*)" -AllMatches + $result.Matches | ForEach-Object { + $manifestShortUrl = $_.Groups[1].Value + $manifestName = $_.Groups[2].Value + $manifestUrl = "$manifestShortUrl;$manifestName" + If (-Not $seenManifests.Contains($manifestUrl)) { + $seenManifests.Add($manifestUrl, $true) + $buildVersion = $manifestVersionMap[$manifestName] + $manifestEntry = "$manifestName{$buildVersion}=$manifestUrl" + $manifests += $manifestEntry + } + } + } + + Remove-Item -Path $tempDir -Recurse + + return $manifests +} + +try { + # build map of all *.vsman files to their `info.buildVersion` values + $manifestVersionMap = @{} + Get-ChildItem -Path "$insertionDir\*" -Filter "*.vsman" | ForEach-Object { + $manifestName = Split-Path $_ -Leaf + $vsmanContents = Get-Content $_ | ConvertFrom-Json + $buildVersion = $vsmanContents.info.buildVersion + $manifestVersionMap.Add($manifestName, $buildVersion) + } + + # find all publish URLs + #$manifests = Get-ManifestsViaIndividualLogs -manifestVersionMap $manifestVersionMap -buildId $buildId -accessToken $accessToken + $manifests = Get-ManifestsViaZipLog -manifestVersionMap $manifestVersionMap -buildId $buildId -accessToken $accessToken + $final = $manifests -Join "," Write-Host "Setting InsertJsonValues to $final" Write-Host "##vso[task.setvariable variable=InsertJsonValues]$final" diff --git a/eng/targets/NGenBinaries.targets b/eng/targets/NGenBinaries.targets index 6e4ad9799f6..c084206d0a6 100644 --- a/eng/targets/NGenBinaries.targets +++ b/eng/targets/NGenBinaries.targets @@ -1,33 +1,70 @@ - - - true - true - false - + + + + + + false + true + + + + + + + true + false + + + AfterTargets="Build" + Condition="'$(OS)' != 'Unix' AND $(TargetFramework.StartsWith('net4')) AND '$(NGenBinary)' == 'true' AND '$(IsAdministrator)' == 'true' AND Exists('$(TargetPath)') "> + - $(windir)\Microsoft.NET\Framework64\v4.0.30319\ngen.exe $(windir)\Microsoft.NET\Framework\v4.0.30319\ngen.exe - $(WindowsSDK_ExecutablePath_x86)sn.exe + $(windir)\Microsoft.NET\Framework64\v4.0.30319\ngen.exe - - + + + + + + + - - - - - \ No newline at end of file + + + + + $(WindowsSDK_ExecutablePath_x86)\sn.exe + $(WindowsSDK_ExecutablePath_x64)\sn.exe + + + + + + + diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index 474e5d22a86..77f7a0c7048 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -11,9 +11,4 @@ false - - - false - - diff --git a/eng/tests/UpToDate.ps1 b/eng/tests/UpToDate.ps1 index a7e50a26d60..0a730ac48f3 100644 --- a/eng/tests/UpToDate.ps1 +++ b/eng/tests/UpToDate.ps1 @@ -16,17 +16,25 @@ try { # do first build & $BuildScript -configuration $configuration @properties if ($LASTEXITCODE -ne 0) { - Write-Host "Error running first build." + Write-Host "##[error](NETCORE_ENGINEERING_TELEMETRY=Build) Error running first build." exit 1 } # gather assembly timestamps $ArtifactsBinDir = Join-Path $RepoRoot "artifacts" | Join-Path -ChildPath "bin" -Resolve $FSharpAssemblyDirs = Get-ChildItem -Path $ArtifactsBinDir -Filter "FSharp.*" - $FSharpAssemblyPaths = $FSharpAssemblyDirs | ForEach-Object { Get-ChildItem -Path (Join-Path $ArtifactsBinDir $_) -Recurse -Filter "$_.dll" } | ForEach-Object { $_.FullName } + $FscAssemblyDir = Get-ChildItem -Path $ArtifactsBinDir -Filter "fsc" + $FsiAssemblyDir = Get-ChildItem -Path $ArtifactsBinDir -Filter "fsi" + $FsiAnyCpuAssemblyDir = Get-ChildItem -Path $ArtifactsBinDir -Filter "fsiAnyCpu" + $ProjectSystemAssemblyDirs = Get-ChildItem -Path $ArtifactsBinDir -Filter "ProjectSystem*" + $FSharpDirs = @($FSharpAssemblyDirs) + @($FscAssemblyDir) + @($FsiAssemblyDir) + @($FsiAnyCpuAssemblyDir) + @($ProjectSystemAssemblyDirs) + $FSharpDllPaths = $FSharpDirs | ForEach-Object { Get-ChildItem -Path (Join-Path $ArtifactsBinDir $_) -Recurse -Filter "*.dll" } | ForEach-Object { $_.FullName } + $FSharpExePaths = $FSharpDirs | ForEach-Object { Get-ChildItem -Path (Join-Path $ArtifactsBinDir $_) -Recurse -Filter "*.exe" } | ForEach-Object { $_.FullName } + $FSharpAssemblyPaths = @($FSharpDllPaths) + @($FSharpExePaths) $InitialAssembliesAndTimes = @{} foreach ($asm in $FSharpAssemblyPaths) { + Write-Host "Assembly : $asm" $LastWriteTime = (Get-Item $asm).LastWriteTimeUtc $InitialAssembliesAndTimes.Add($asm, $LastWriteTime) } @@ -36,7 +44,7 @@ try { # build again & $BuildScript -configuration $configuration @properties if ($LASTEXITCODE -ne 0) { - Write-Host "Error running second build." + Write-Host "##[error](NETCORE_ENGINEERING_TELEMETRY=Build) Error running second build." exit 1 } @@ -53,14 +61,20 @@ try { $InitialTime = $InitialAssembliesAndTimes[$asm] $FinalTime = $FinalAssembliesAndTimes[$asm] if ($InitialTime -ne $FinalTime) { + Write-Host "Rebuilt assembly: $asm" $RecompiledFiles += $asm } } $RecompiledCount = $RecompiledFiles.Length - Write-Host "$RecompiledCount of $InitialCompiledCount assemblies were re-compiled" - $RecompiledFiles | ForEach-Object { Write-Host " $_" } - exit $RecompiledCount + if ($RecompiledCount -ge 0) { + Write-Host "##[error](NETCORE_ENGINEERING_TELEMETRY=Test) $RecompiledCount of $InitialCompiledCount assemblies were re-compiled." + $RecompiledFiles | ForEach-Object { Write-Host " $_" } + exit $RecompiledCount + } else { + Write-Host "No assemblies rebuilt." + exit 0 + } } catch { Write-Host $_ diff --git a/fcs/samples/EditorService/App.config b/fcs-samples/EditorService/App.config similarity index 100% rename from fcs/samples/EditorService/App.config rename to fcs-samples/EditorService/App.config diff --git a/fcs/samples/EditorService/EditorService.fsproj b/fcs-samples/EditorService/EditorService.fsproj similarity index 91% rename from fcs/samples/EditorService/EditorService.fsproj rename to fcs-samples/EditorService/EditorService.fsproj index 2fdc22b6c89..27bdbef249c 100644 --- a/fcs/samples/EditorService/EditorService.fsproj +++ b/fcs-samples/EditorService/EditorService.fsproj @@ -1,7 +1,7 @@  - $(FcsTargetNetFxFramework);netcoreapp3.0 + $(FcsTargetNetFxFramework);net5.0 true Exe false diff --git a/fcs/samples/EditorService/Program.fs b/fcs-samples/EditorService/Program.fs similarity index 100% rename from fcs/samples/EditorService/Program.fs rename to fcs-samples/EditorService/Program.fs diff --git a/fcs/samples/FscExe/App.config b/fcs-samples/FscExe/App.config similarity index 100% rename from fcs/samples/FscExe/App.config rename to fcs-samples/FscExe/App.config diff --git a/fcs/samples/FscExe/FscExe.fsproj b/fcs-samples/FscExe/FscExe.fsproj similarity index 100% rename from fcs/samples/FscExe/FscExe.fsproj rename to fcs-samples/FscExe/FscExe.fsproj diff --git a/fcs/samples/FscExe/FscMain.fs b/fcs-samples/FscExe/FscMain.fs similarity index 99% rename from fcs/samples/FscExe/FscMain.fs rename to fcs-samples/FscExe/FscMain.fs index b2d5d6a8993..4b465cb2ab5 100644 --- a/fcs/samples/FscExe/FscMain.fs +++ b/fcs-samples/FscExe/FscMain.fs @@ -8,8 +8,8 @@ open System.IO open System.Reflection open System.Runtime.CompilerServices open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.AbstractIL.IL // runningOnMono -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.AbstractIL.Utils // runningOnMono +open FSharp.Compiler.AbstractIL.Library open FSharp.Compiler.ErrorLogger #if RESIDENT_COMPILER diff --git a/fcs/samples/FsiExe/App.config b/fcs-samples/FsiExe/App.config similarity index 100% rename from fcs/samples/FsiExe/App.config rename to fcs-samples/FsiExe/App.config diff --git a/fcs/samples/FsiExe/FsiExe.fsproj b/fcs-samples/FsiExe/FsiExe.fsproj similarity index 100% rename from fcs/samples/FsiExe/FsiExe.fsproj rename to fcs-samples/FsiExe/FsiExe.fsproj diff --git a/fcs/samples/FsiExe/console.fs b/fcs-samples/FsiExe/console.fs similarity index 100% rename from fcs/samples/FsiExe/console.fs rename to fcs-samples/FsiExe/console.fs diff --git a/fcs/samples/FsiExe/fsimain.fs b/fcs-samples/FsiExe/fsimain.fs similarity index 100% rename from fcs/samples/FsiExe/fsimain.fs rename to fcs-samples/FsiExe/fsimain.fs diff --git a/fcs/samples/FsiExe/fsiserver.fs b/fcs-samples/FsiExe/fsiserver.fs similarity index 91% rename from fcs/samples/FsiExe/fsiserver.fs rename to fcs-samples/FsiExe/fsiserver.fs index 838c2593046..6fafe5d1bcb 100644 --- a/fcs/samples/FsiExe/fsiserver.fs +++ b/fcs-samples/FsiExe/fsiserver.fs @@ -33,10 +33,6 @@ open System.Runtime.Remoting.Lifetime type internal FSharpInteractiveServer() = inherit System.MarshalByRefObject() abstract Interrupt : unit -> unit -#if FSI_SERVER_INTELLISENSE - abstract Completions : prefix:string -> string array - abstract GetDeclarations : text:string * names:string array -> (string * string * string * int) array -#endif default x.Interrupt() = () [] diff --git a/fcs/samples/InteractiveService/App.config b/fcs-samples/InteractiveService/App.config similarity index 100% rename from fcs/samples/InteractiveService/App.config rename to fcs-samples/InteractiveService/App.config diff --git a/fcs/samples/InteractiveService/InteractiveService.fsproj b/fcs-samples/InteractiveService/InteractiveService.fsproj similarity index 100% rename from fcs/samples/InteractiveService/InteractiveService.fsproj rename to fcs-samples/InteractiveService/InteractiveService.fsproj diff --git a/fcs/samples/InteractiveService/Program.fs b/fcs-samples/InteractiveService/Program.fs similarity index 100% rename from fcs/samples/InteractiveService/Program.fs rename to fcs-samples/InteractiveService/Program.fs diff --git a/fcs/samples/Tokenizer/App.config b/fcs-samples/Tokenizer/App.config similarity index 100% rename from fcs/samples/Tokenizer/App.config rename to fcs-samples/Tokenizer/App.config diff --git a/fcs/samples/Tokenizer/Program.fs b/fcs-samples/Tokenizer/Program.fs similarity index 100% rename from fcs/samples/Tokenizer/Program.fs rename to fcs-samples/Tokenizer/Program.fs diff --git a/fcs/samples/Tokenizer/Tokenizer.fsproj b/fcs-samples/Tokenizer/Tokenizer.fsproj similarity index 100% rename from fcs/samples/Tokenizer/Tokenizer.fsproj rename to fcs-samples/Tokenizer/Tokenizer.fsproj diff --git a/fcs/samples/UntypedTree/App.config b/fcs-samples/UntypedTree/App.config similarity index 100% rename from fcs/samples/UntypedTree/App.config rename to fcs-samples/UntypedTree/App.config diff --git a/fcs-samples/UntypedTree/Program.fs b/fcs-samples/UntypedTree/Program.fs new file mode 100644 index 00000000000..7203195a173 --- /dev/null +++ b/fcs-samples/UntypedTree/Program.fs @@ -0,0 +1,91 @@ +// Open the namespace with InteractiveChecker type +open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Syntax + +// Create a checker instance (ignore notifications) +let checker = FSharpChecker.Create() + +// ------------------------------------------------------------------ + +// Get untyped tree for a specified input +let getUntypedTree (file, input) = + let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| file |] } + let untypedRes = checker.ParseFile(file, FSharp.Compiler.Text.SourceText.ofString input, parsingOptions) |> Async.RunSynchronously + match untypedRes.ParseTree with + | Some tree -> tree + | None -> failwith "Something went wrong during parsing!" + +// ------------------------------------------------------------------ + +/// Walk over all module or namespace declarations +/// (basically 'module Foo =' or 'namespace Foo.Bar') +/// Note that there is one implicitly, even if the file +/// does not explicitly define it.. +let rec visitModulesAndNamespaces modulesOrNss = + for moduleOrNs in modulesOrNss do + let (SynModuleOrNamespace(lid, isRec, isModule, decls, xmlDoc, attribs, synAccess, m)) = moduleOrNs + printfn "Namespace or module: %A" lid + visitDeclarations decls + +/// Walk over a pattern - this is for example used in +/// let = or in the 'match' expression +and visitPattern = function + | SynPat.Wild(_) -> + printfn " .. underscore pattern" + | SynPat.Named(pat, name, _, _, _) -> + visitPattern pat + printfn " .. named as '%s'" name.idText + | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> + printfn " identifier: %s" (String.concat "." [ for i in ident -> i.idText ]) + | pat -> printfn " - not supported pattern: %A" pat + +/// Walk over an expression - the most interesting part :-) +and visitExpression = function + | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> + printfn "Conditional:" + visitExpression cond + visitExpression trueBranch + falseBranchOpt |> Option.iter visitExpression + + | SynExpr.LetOrUse(_, _, bindings, body, _) -> + printfn "LetOrUse with the following bindings:" + for binding in bindings do + let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, data, pat, retInfo, body, m, sp)) = binding + visitPattern pat + printfn "And the following body:" + visitExpression body + | expr -> printfn " - not supported expression: %A" expr + +/// Walk over a list of declarations in a module. This is anything +/// that you can write as a top-level inside module (let bindings, +/// nested modules, type declarations etc.) +and visitDeclarations decls = + for declaration in decls do + match declaration with + | SynModuleDecl.Let(isRec, bindings, range) -> + for binding in bindings do + let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, data, pat, retInfo, body, m, sp)) = binding + visitPattern pat + visitExpression body + | _ -> printfn " - not supported declaration: %A" declaration + + +// ------------------------------------------------------------------ + +// Sample input for the compiler service +let input = """ + let foo() = + let msg = "Hello world" + if true then + printfn "%s" msg """ +let file = "/home/user/Test.fsx" + +let tree = getUntypedTree(file, input) + +// Testing: Print the AST to see what it looks like +// tree |> printfn "%A" + +match tree with +| ParsedInput.ImplFile(ParsedImplFileInput(file, isScript, qualName, pragmas, hashDirectives, modules, b)) -> + visitModulesAndNamespaces modules +| _ -> failwith "F# Interface file (*.fsi) not supported." \ No newline at end of file diff --git a/fcs/samples/UntypedTree/UntypedTree.fsproj b/fcs-samples/UntypedTree/UntypedTree.fsproj similarity index 100% rename from fcs/samples/UntypedTree/UntypedTree.fsproj rename to fcs-samples/UntypedTree/UntypedTree.fsproj diff --git a/fcs/.config/dotnet-tools.json b/fcs/.config/dotnet-tools.json deleted file mode 100644 index c3e6f5e472f..00000000000 --- a/fcs/.config/dotnet-tools.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "fake-cli": { - "version": "5.18.3", - "commands": [ - "fake" - ] - }, - "paket": { - "version": "5.236.0", - "commands": [ - "paket" - ] - } - } -} \ No newline at end of file diff --git a/fcs/.gitignore b/fcs/.gitignore deleted file mode 100644 index ba316d8d5ae..00000000000 --- a/fcs/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -.paket/ -build.fsx.lock -FSharp.Compiler.Service.Tests/TestResults/* -FSharp.Compiler.Service.netstandard/illex.fs -FSharp.Compiler.Service.netstandard/ilpars.fs -FSharp.Compiler.Service.netstandard/ilpars.fsi -FSharp.Compiler.Service.netstandard/lex.fs -FSharp.Compiler.Service.netstandard/pars.fs -FSharp.Compiler.Service.netstandard/pars.fsi -FSharp.Compiler.Service.netstandard/pplex.fs -FSharp.Compiler.Service.netstandard/pppars.fs -FSharp.Compiler.Service.netstandard/pppars.fsi - diff --git a/fcs/Directory.Build.props b/fcs/Directory.Build.props deleted file mode 100644 index 2841a5fb34f..00000000000 --- a/fcs/Directory.Build.props +++ /dev/null @@ -1,37 +0,0 @@ - - - - - $(RestoreSources); - https://api.nuget.org/v3/index.json; - https://dotnet.myget.org/F/fsharp/api/v3/index.json; - - - - - $(UserProfile)\.nuget\packages\ - $(HOME)/.nuget/packages/ - $(NuGetPackageRoot)\ - $(NuGetPackageRoot)/ - $(MSBuildThisFileDirectory)..\artifacts - $(ArtifactsDir)\bin - $(ArtifactsDir)\obj - $(ArtifactsBinDir)\fcs\$(Configuration) - $(ArtifactsObjDir)\fcs\$(Configuration) - true - - - - - $(MSBuildThisFileDirectory)..\src - 22.0.3 - --version:$(VersionPrefix) - false - - - $(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools - fsi.exe - 4.6.2 - net461 - - diff --git a/fcs/Directory.Build.targets b/fcs/Directory.Build.targets deleted file mode 100644 index 00f6e63aa81..00000000000 --- a/fcs/Directory.Build.targets +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - <__TargetFilePath>@(NoneSubstituteText->'$(IntermediateOutputPath)%(Filename)%(Extension)') - <__TargetFileName>@(NoneSubstituteText->'%(Filename)%(Extension)') - - <_ReplacementText>$([System.IO.File]::ReadAllText('%(NoneSubstituteText.FullPath)')) - <_ReplacementText Condition="'%(NoneSubstituteText.Pattern1)' != ''">$(_ReplacementText.Replace('%(NoneSubstituteText.Pattern1)', '%(NoneSubstituteText.Replacement1)')) - <_ReplacementText Condition="'%(NoneSubstituteText.Pattern2)' != ''">$(_ReplacementText.Replace('%(NoneSubstituteText.Pattern2)', '%(NoneSubstituteText.Replacement2)')) - - <_CopyToOutputDirectory Condition="'%(NoneSubstituteText.CopyToOutputDirectory)' != ''">%(NoneSubstituteText.CopyToOutputDirectory) - <_CopyToOutputDirectory Condition="'%(NoneSubstituteText.CopyToOutputDirectory)' == ''">Never - - - - - - - - - - - - - - - - <_BuildPropertyLines Remove="@(_BuildPropertyLines)" /> - <_BuildPropertyLines Include="// <auto-generated >" /> - <_BuildPropertyLines Include="// <Generated by the FSharp WriteCodeFragment class./>" /> - <_BuildPropertyLines Include="// </auto-generated/>" /> - <_BuildPropertyLines Include="//" /> - <_BuildPropertyLines Include="module internal FSharp.BuildProperties" /> - <_BuildPropertyLines Include="let fsProductVersion = "$(FSPRODUCTVERSION)"" /> - <_BuildPropertyLines Include="let fsLanguageVersion = "$(FSLANGUAGEVERSION)"" /> - - - - - - - - - - - - diff --git a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj deleted file mode 100644 index ad6a9d7cd62..00000000000 --- a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - $(FcsTargetNetFxFramework) - true - $(DefineConstants);CROSS_PLATFORM_COMPILER - $(DefineConstants);ENABLE_MONO_SUPPORT - - - Additional DLL for legacy compat for the F# compiler service. - Additional DLL for legacy compat for the F# compiler service. - false - Microsoft Corporation; F# community contributors - https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE - https://github.com/fsharp/FSharp.Compiler.Service - logo.png - F#, compiler, msbuild - - - - - Service/MSBuildReferenceResolver.fs - - - - - - - - - - - - - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj b/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj deleted file mode 100644 index b12fa10ee5b..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $(FcsTargetNetFxFramework) - true - - - Legacy project file cracker for the F# compiler service. - Legacy project file cracker for the F# compiler service. - false - Microsoft Corporation; F# community contributors - https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE - https://github.com/fsharp/FSharp.Compiler.Service - logo.png - F#, compiler, msbuild - - - - - ProjectCrackerOptions.fs - - - - - - - - - - - - - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs b/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs deleted file mode 100644 index 3a096cb5660..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCracker/ProjectCracker.fs +++ /dev/null @@ -1,127 +0,0 @@ -namespace FSharp.Compiler.SourceCodeServices - -#if !NETSTANDARD -open System.Runtime.Serialization.Json -#endif -open System.Text -open System.IO -open System - -module Utils = - - let Convert loadedTimeStamp (originalOpts: ProjectCrackerTool.ProjectOptions) = - let logMap = ref Map.empty - - let rec convertProject (opts: ProjectCrackerTool.ProjectOptions) = - if not (isNull opts.Error) then failwith opts.Error - - let referencedProjects() = Array.map (fun (a, b) -> a,convertProject b) opts.ReferencedProjectOptions - - let sourceFiles, otherOptions = - opts.Options - |> Array.partition (fun x -> - let extension = Path.GetExtension(x).ToLower() - x.IndexOfAny(Path.GetInvalidPathChars()) = -1 - && (extension = ".fs" || extension = ".fsi")) - - let sepChar = Path.DirectorySeparatorChar - - let sourceFiles = sourceFiles |> Array.map (fun x -> - match sepChar with - | '\\' -> x.Replace('/', '\\') - | '/' -> x.Replace('\\', '/') - | _ -> x - ) - - logMap := Map.add opts.ProjectFile opts.LogOutput !logMap - { ProjectFileName = opts.ProjectFile - ProjectId = None - SourceFiles = sourceFiles - OtherOptions = otherOptions - ReferencedProjects = referencedProjects() - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = loadedTimeStamp - UnresolvedReferences = None - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = None } - - convertProject originalOpts, !logMap - -type ProjectCracker = - - static member GetProjectOptionsFromProjectFileLogged(projectFileName : string, ?properties : (string * string) list, ?loadedTimeStamp, ?enableLogging) = - let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading - let properties = defaultArg properties [] - let enableLogging = defaultArg enableLogging true - - -#if NETSTANDARD - let arguments = [| - yield projectFileName - yield enableLogging.ToString() - for k, v in properties do - yield k - yield v - |] - - let ret, opts = FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.crackOpen arguments - ignore ret -#else - let arguments = new StringBuilder() - arguments.Append('"').Append(projectFileName).Append('"') |> ignore - arguments.Append(' ').Append(enableLogging.ToString()) |> ignore - for k, v in properties do - arguments.Append(' ').Append(k).Append(' ').Append(v) |> ignore - let codebase = Path.GetDirectoryName(Uri(typeof.Assembly.CodeBase).LocalPath) - - let crackerFilename = Path.Combine(codebase,"FSharp.Compiler.Service.ProjectCrackerTool.exe") - if not (File.Exists crackerFilename) then - failwithf "ProjectCracker exe not found at: %s it must be next to the ProjectCracker dll." crackerFilename - - let p = new System.Diagnostics.Process() - - p.StartInfo.FileName <- crackerFilename - p.StartInfo.Arguments <- arguments.ToString() - p.StartInfo.UseShellExecute <- false - p.StartInfo.CreateNoWindow <- true - p.StartInfo.RedirectStandardOutput <- true - p.StartInfo.RedirectStandardError <- true - - let sbOut = StringBuilder() - let sbErr = StringBuilder() - - p.ErrorDataReceived.AddHandler(fun _ a -> sbErr.AppendLine a.Data |> ignore) - p.OutputDataReceived.AddHandler(fun _ a -> sbOut.AppendLine a.Data |> ignore) - - ignore <| p.Start() - - p.EnableRaisingEvents <- true - p.BeginOutputReadLine() - p.BeginErrorReadLine() - - p.WaitForExit() - - let crackerOut = sbOut.ToString() - let crackerErr = sbErr.ToString() - - let opts = - try - let ser = new DataContractJsonSerializer(typeof) - let stringBytes = Encoding.Unicode.GetBytes crackerOut - use ms = new MemoryStream(stringBytes) - ser.ReadObject(ms) :?> ProjectCrackerTool.ProjectOptions - with - exn -> - raise (Exception(sprintf "error parsing ProjectCrackerTool output, stdoutput was:\n%s\n\nstderr was:\n%s" crackerOut crackerErr, exn)) -#endif - - Utils.Convert loadedTimeStamp opts - - static member GetProjectOptionsFromProjectFile(projectFileName : string, ?properties : (string * string) list, ?loadedTimeStamp) = - fst (ProjectCracker.GetProjectOptionsFromProjectFileLogged( - projectFileName, - ?properties=properties, - ?loadedTimeStamp=loadedTimeStamp, - enableLogging=false)) diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/App.config b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/App.config deleted file mode 100644 index fdab151af22..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets deleted file mode 100644 index ed01293adaf..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCracker.targets +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj deleted file mode 100644 index 19789a96299..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - Exe - $(FcsTargetNetFxFramework) - true - $(DefineConstants);CROSS_PLATFORM_COMPILER - $(DefineConstants);ENABLE_MONO_SUPPORT - $(OtherFlags) --staticlink:FSharp.Core - true - false - - - - - - - - - - - - - - diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs deleted file mode 100644 index 5cc3fc8b1eb..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/Program.fs +++ /dev/null @@ -1,46 +0,0 @@ -namespace FSharp.Compiler.SourceCodeServices.ProjectCrackerTool - -open System -open System.Reflection -open System.Runtime.Serialization.Json - -module Program = - -#if !NETCOREAPP - let addMSBuildv14BackupResolution () = - let onResolveEvent = new ResolveEventHandler(fun sender evArgs -> - let requestedAssembly = AssemblyName(evArgs.Name) - if requestedAssembly.Name.StartsWith("Microsoft.Build", StringComparison.Ordinal) && - not (requestedAssembly.Name.EndsWith(".resources", StringComparison.Ordinal)) && - not (requestedAssembly.Version.ToString().Contains("12.0.0.0")) - then - // If the version of MSBuild that we're using wasn't present on the machine, then - // just revert back to 12.0.0.0 since that's normally installed as part of the .NET - // Framework. - requestedAssembly.Version <- Version("12.0.0.0") - Assembly.Load requestedAssembly - else - null) - AppDomain.CurrentDomain.add_AssemblyResolve(onResolveEvent) -#endif - - let crackAndSendOutput asText argv = - let ret, opts = ProjectCrackerTool.crackOpen argv - - if asText then - printfn "%A" opts - else - let ser = new DataContractJsonSerializer(typeof) - ser.WriteObject(Console.OpenStandardOutput(), opts) - ret - - - [][] - let main argv = - let asText = Array.exists (fun (s: string) -> s = "--text") argv - let argv = Array.filter (fun (s: string) -> s <> "--text") argv - -#if !NETCOREAPP - addMSBuildv14BackupResolution () -#endif - crackAndSendOutput asText argv diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerOptions.fs b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerOptions.fs deleted file mode 100644 index a48bdc25aa7..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerOptions.fs +++ /dev/null @@ -1,11 +0,0 @@ -namespace FSharp.Compiler.SourceCodeServices.ProjectCrackerTool - -[] -type ProjectOptions = - { - ProjectFile: string - Options: string[] - ReferencedProjectOptions: (string * ProjectOptions)[] - LogOutput: string - Error: string - } diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs deleted file mode 100644 index 0f2d4ad056e..00000000000 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs +++ /dev/null @@ -1,471 +0,0 @@ -namespace FSharp.Compiler.SourceCodeServices.ProjectCrackerTool - -open System -open System.IO -open System.Text -open Microsoft.Build.Framework -open Microsoft.Build.Utilities - -module internal ProjectCrackerTool = - open System.Collections.Generic - - let runningOnMono = -#if NETCOREAPP - false -#else - try match System.Type.GetType("Mono.Runtime") with null -> false | _ -> true - with e -> false -#endif - - type internal BasicStringLogger() = - inherit Logger() - - let sb = new StringBuilder() - - let log (e: BuildEventArgs) = - sb.Append(e.Message) |> ignore - sb.AppendLine() |> ignore - - override x.Initialize(eventSource:IEventSource) = - sb.Clear() |> ignore - eventSource.AnyEventRaised.Add(log) - - member x.Log = sb.ToString() - - type internal HostCompile() = - member th.Compile(_:obj, _:obj, _:obj) = 0 - interface ITaskHost - - let vs = - let programFiles = - let getEnv v = - let result = System.Environment.GetEnvironmentVariable(v) - match result with - | null -> None - | _ -> Some result - - match List.tryPick getEnv [ "ProgramFiles(x86)"; "ProgramFiles" ] with - | Some r -> r - | None -> "C:\\Program Files (x86)" - - let vsVersions = ["14.0"; "12.0"] - let msbuildBin v = IO.Path.Combine(programFiles, "MSBuild", v, "Bin", "MSBuild.exe") - List.tryFind (fun v -> IO.File.Exists(msbuildBin v)) vsVersions - - let mkAbsolute dir v = - if Path.IsPathRooted v then v - else Path.Combine(dir, v) - - let mkAbsoluteOpt dir v = Option.map (mkAbsolute dir) v - - let CrackProjectUsingNewBuildAPI fsprojFile properties logOpt = - let fsprojFullPath = try Path.GetFullPath(fsprojFile) with _ -> fsprojFile - let fsprojAbsDirectory = Path.GetDirectoryName fsprojFullPath - - use _pwd = - let dir = Directory.GetCurrentDirectory() - Directory.SetCurrentDirectory(fsprojAbsDirectory) - { new System.IDisposable with - member x.Dispose() = Directory.SetCurrentDirectory(dir) } - use engine = new Microsoft.Build.Evaluation.ProjectCollection() - let host = new HostCompile() - - engine.HostServices.RegisterHostObject(fsprojFullPath, "CoreCompile", "Fsc", host) - - let projectInstanceFromFullPath (fsprojFullPath: string) = - use file = new FileStream(fsprojFullPath, FileMode.Open, FileAccess.Read, FileShare.Read) - use stream = new StreamReader(file) - use xmlReader = System.Xml.XmlReader.Create(stream) - - let project = - try - engine.LoadProject(xmlReader, FullPath=fsprojFullPath) - with - | exn -> - let tools = engine.Toolsets |> Seq.map (fun x -> x.ToolsPath) |> Seq.toList - raise (new Exception(sprintf "Could not load project %s in ProjectCollection. Available tools: %A. Message: %s" fsprojFullPath tools exn.Message)) - - project.SetGlobalProperty("BuildingInsideVisualStudio", "true") |> ignore - if not (List.exists (fun (p,_) -> p = "VisualStudioVersion") properties) then - match vs with - | Some version -> project.SetGlobalProperty("VisualStudioVersion", version) |> ignore - | None -> () - project.SetGlobalProperty("ShouldUnsetParentConfigurationAndPlatform", "false") |> ignore - for (prop, value) in properties do - project.SetGlobalProperty(prop, value) |> ignore - - project.CreateProjectInstance() - - let project = projectInstanceFromFullPath fsprojFullPath - let directory = project.Directory - - let getprop (p: Microsoft.Build.Execution.ProjectInstance) s = - let v = p.GetPropertyValue s - if String.IsNullOrWhiteSpace v then None - else Some v - - let outFileOpt = getprop project "TargetPath" - - let log = match logOpt with - | None -> [] - | Some l -> [l :> ILogger] - - project.Build([| "Build" |], log) |> ignore - - let getItems s = [ for f in project.GetItems(s) -> mkAbsolute directory f.EvaluatedInclude ] - - let projectReferences = - [ for cp in project.GetItems("ProjectReference") do - yield cp.GetMetadataValue("FullPath") - ] - - let references = - [ for i in project.GetItems("ReferencePath") do - yield i.EvaluatedInclude - for i in project.GetItems("ChildProjectReferences") do - yield i.EvaluatedInclude ] - - outFileOpt, directory, getItems, references, projectReferences, getprop project, project.FullPath - -#if !NETCOREAPP - let CrackProjectUsingOldBuildAPI (fsprojFile:string) properties logOpt = - let engine = new Microsoft.Build.BuildEngine.Engine() - Option.iter (fun l -> engine.RegisterLogger(l)) logOpt - - let bpg = Microsoft.Build.BuildEngine.BuildPropertyGroup() - - bpg.SetProperty("BuildingInsideVisualStudio", "true") - for (prop, value) in properties do - bpg.SetProperty(prop, value) - - engine.GlobalProperties <- bpg - - let projectFromFile (fsprojFile:string) = - // We seem to need to pass 12.0/4.0 in here for some unknown reason - let project = new Microsoft.Build.BuildEngine.Project(engine, engine.DefaultToolsVersion) - do project.Load(fsprojFile) - project - - let project = projectFromFile fsprojFile - project.Build([| "ResolveReferences" |]) |> ignore - let directory = Path.GetDirectoryName project.FullFileName - - let getProp (p: Microsoft.Build.BuildEngine.Project) s = - let v = p.GetEvaluatedProperty s - if String.IsNullOrWhiteSpace v then None - else Some v - - let outFileOpt = - match mkAbsoluteOpt directory (getProp project "OutDir") with - | None -> None - | Some d -> mkAbsoluteOpt d (getProp project "TargetFileName") - - let getItems s = - let fs = project.GetEvaluatedItemsByName(s) - [ for f in fs -> mkAbsolute directory f.FinalItemSpec ] - - let projectReferences = - [ for i in project.GetEvaluatedItemsByName("ProjectReference") do - yield mkAbsolute directory i.FinalItemSpec - ] - - let references = - [ for i in project.GetEvaluatedItemsByName("ReferencePath") do - yield i.FinalItemSpec - for i in project.GetEvaluatedItemsByName("ChildProjectReferences") do - yield i.FinalItemSpec ] - // Duplicate slashes sometimes appear in the output here, which prevents - // them from matching keys used in FSharpProjectOptions.ReferencedProjects - |> List.map (fun (s: string) -> s.Replace("//","/")) - - outFileOpt, directory, getItems, references, projectReferences, getProp project, project.FullFileName - -#endif - - //---------------------------------------------------------------------------- - // FSharpProjectFileInfo - // - [] - type FSharpProjectFileInfo (fsprojFileName:string, ?properties, ?enableLogging) = - let properties = defaultArg properties [] - let enableLogging = defaultArg enableLogging false - - let logOpt = - if enableLogging then - let log = new BasicStringLogger() - do log.Verbosity <- Microsoft.Build.Framework.LoggerVerbosity.Diagnostic - Some log - else - None - - let outFileOpt, directory, getItems, references, projectReferences, getProp, fsprojFullPath = - try -#if NETCOREAPP - CrackProjectUsingNewBuildAPI fsprojFileName properties logOpt - with -#else - if runningOnMono then - CrackProjectUsingOldBuildAPI fsprojFileName properties logOpt - else - CrackProjectUsingNewBuildAPI fsprojFileName properties logOpt - with - | :? Microsoft.Build.BuildEngine.InvalidProjectFileException as e -> - raise (Microsoft.Build.Exceptions.InvalidProjectFileException( - e.ProjectFile, - e.LineNumber, - e.ColumnNumber, - e.EndLineNumber, - e.EndColumnNumber, - e.Message, - e.ErrorSubcategory, - e.ErrorCode, - e.HelpKeyword)) -#endif - | :? ArgumentException as e -> raise (IO.FileNotFoundException(e.Message)) - - let logOutput = match logOpt with None -> "" | Some l -> l.Log - let pages = getItems "Page" - let embeddedResources = getItems "EmbeddedResource" - let files = getItems "Compile" - let resources = getItems "Resource" - let noaction = getItems "None" - let content = getItems "Content" - - let split (s : string option) (cs : char []) = - match s with - | None -> [||] - | Some s -> - if String.IsNullOrWhiteSpace s then [||] - else s.Split(cs, StringSplitOptions.RemoveEmptyEntries) - - let getbool (s : string option) = - match s with - | None -> false - | Some s -> - match (Boolean.TryParse s) with - | (true, result) -> result - | (false, _) -> false - - let fxVer = getProp "TargetFrameworkVersion" - let optimize = getProp "Optimize" |> getbool - let assemblyNameOpt = getProp "AssemblyName" - let tailcalls = getProp "Tailcalls" |> getbool - let outputPathOpt = getProp "OutputPath" - let docFileOpt = getProp "DocumentationFile" - let outputTypeOpt = getProp "OutputType" - let debugTypeOpt = getProp "DebugType" - let baseAddressOpt = getProp "BaseAddress" - let sigFileOpt = getProp "GenerateSignatureFile" - let keyFileOpt = getProp "KeyFile" - let pdbFileOpt = getProp "PdbFile" - let platformOpt = getProp "Platform" - let targetTypeOpt = getProp "TargetType" - let versionFileOpt = getProp "VersionFile" - let targetProfileOpt = getProp "TargetProfile" - let warnLevelOpt = getProp "Warn" - let subsystemVersionOpt = getProp "SubsystemVersion" - let win32ResOpt = getProp "Win32ResourceFile" - let heOpt = getProp "HighEntropyVA" |> getbool - let win32ManifestOpt = getProp "Win32ManifestFile" - let debugSymbols = getProp "DebugSymbols" |> getbool - let prefer32bit = getProp "Prefer32Bit" |> getbool - let warnAsError = getProp "TreatWarningsAsErrors" |> getbool - let defines = split (getProp "DefineConstants") [| ';'; ','; ' ' |] - let nowarn = split (getProp "NoWarn") [| ';'; ','; ' ' |] - let warningsAsError = split (getProp "WarningsAsErrors") [| ';'; ','; ' ' |] - let libPaths = split (getProp "ReferencePath") [| ';'; ',' |] - let otherFlags = split (getProp "OtherFlags") [| ' ' |] - let isLib = (outputTypeOpt = Some "Library") - - let docFileOpt = - match docFileOpt with - | None -> None - | Some docFile -> Some(mkAbsolute directory docFile) - - - let options = - [ yield "--simpleresolution" - yield "--noframework" - match outFileOpt with - | None -> () - | Some outFile -> yield "--out:" + outFile - match docFileOpt with - | None -> () - | Some docFile -> yield "--doc:" + docFile - match baseAddressOpt with - | None -> () - | Some baseAddress -> yield "--baseaddress:" + baseAddress - match keyFileOpt with - | None -> () - | Some keyFile -> yield "--keyfile:" + keyFile - match sigFileOpt with - | None -> () - | Some sigFile -> yield "--sig:" + sigFile - match pdbFileOpt with - | None -> () - | Some pdbFile -> yield "--pdb:" + pdbFile - match versionFileOpt with - | None -> () - | Some versionFile -> yield "--versionfile:" + versionFile - match warnLevelOpt with - | None -> () - | Some warnLevel -> yield "--warn:" + warnLevel - match subsystemVersionOpt with - | None -> () - | Some s -> yield "--subsystemversion:" + s - if heOpt then yield "--highentropyva+" - match win32ResOpt with - | None -> () - | Some win32Res -> yield "--win32res:" + win32Res - match win32ManifestOpt with - | None -> () - | Some win32Manifest -> yield "--win32manifest:" + win32Manifest - match targetProfileOpt with - | None -> () - | Some targetProfile -> yield "--targetprofile:" + targetProfile - yield "--fullpaths" - yield "--flaterrors" - if warnAsError then yield "--warnaserror" - yield - if isLib then "--target:library" - else "--target:exe" - for symbol in defines do - if not (String.IsNullOrWhiteSpace symbol) then yield "--define:" + symbol - for nw in nowarn do - if not (String.IsNullOrWhiteSpace nw) then yield "--nowarn:" + nw - for nw in warningsAsError do - if not (String.IsNullOrWhiteSpace nw) then yield "--warnaserror:" + nw - yield if debugSymbols then "--debug+" - else "--debug-" - yield if optimize then "--optimize+" - else "--optimize-" - yield if tailcalls then "--tailcalls+" - else "--tailcalls-" - match debugTypeOpt with - | None -> () - | Some debugType -> - match debugType.ToUpperInvariant() with - | "NONE" -> () - | "PDBONLY" -> yield "--debug:pdbonly" - | "FULL" -> yield "--debug:full" - | _ -> () - match platformOpt |> Option.map (fun o -> o.ToUpperInvariant()), prefer32bit, - targetTypeOpt |> Option.map (fun o -> o.ToUpperInvariant()) with - | Some "ANYCPU", true, Some "EXE" | Some "ANYCPU", true, Some "WINEXE" -> yield "--platform:anycpu32bitpreferred" - | Some "ANYCPU", _, _ -> yield "--platform:anycpu" - | Some "X86", _, _ -> yield "--platform:x86" - | Some "X64", _, _ -> yield "--platform:x64" - | Some "ITANIUM", _, _ -> yield "--platform:Itanium" - | _ -> () - match targetTypeOpt |> Option.map (fun o -> o.ToUpperInvariant()) with - | Some "LIBRARY" -> yield "--target:library" - | Some "EXE" -> yield "--target:exe" - | Some "WINEXE" -> yield "--target:winexe" - | Some "MODULE" -> yield "--target:module" - | _ -> () - yield! otherFlags - for f in resources do - yield "--resource:" + f - for i in libPaths do - yield "--lib:" + mkAbsolute directory i - for r in references do - yield "-r:" + r - yield! files ] - - member x.Options = options - member x.FrameworkVersion = fxVer - member x.ProjectReferences = projectReferences - member x.References = references - member x.CompileFiles = files - member x.ResourceFiles = resources - member x.EmbeddedResourceFiles = embeddedResources - member x.ContentFiles = content - member x.OtherFiles = noaction - member x.PageFiles = pages - member x.OutputFile = outFileOpt - member x.Directory = directory - member x.AssemblyName = assemblyNameOpt - member x.OutputPath = outputPathOpt - member x.FullPath = fsprojFullPath - member x.LogOutput = logOutput - static member Parse(fsprojFileName:string, ?properties, ?enableLogging) = new FSharpProjectFileInfo(fsprojFileName, ?properties=properties, ?enableLogging=enableLogging) - - let getOptions file enableLogging properties = - let cache = new Dictionary<_,_>() - let rec getOptions file : Option * ProjectOptions = - match cache.TryGetValue file with - | true, option -> option - | _ -> - let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=enableLogging) - - let referencedProjectOptions = - [| for file in parsedProject.ProjectReferences do - if Path.GetExtension(file) = ".fsproj" then - match getOptions file with - | Some outFile, opts -> yield outFile, opts - | None, _ -> () |] - - // Workaround for Mono 4.2, which doesn't populate the subproject - // details anymore outside of a solution context. See https://github.com/mono/mono/commit/76c6a08e730393927b6851709cdae1d397cbcc3a#diff-59afd196a55d61d5d1eaaef7bd49d1e5 - // and some explanation from the author at https://github.com/fsharp/FSharp.Compiler.Service/pull/455#issuecomment-154103963 - // - // In particular we want the output path, which we can get from - // fully parsing that project itself. We also have to specially parse - // C# referenced projects, as we don't look at them otherwise. - let referencedProjectOutputs = - if runningOnMono then - [ yield! Array.map (fun (s,_) -> "-r:" + s) referencedProjectOptions - for file in parsedProject.ProjectReferences do - let ext = Path.GetExtension(file) - if ext = ".csproj" || ext = ".vbproj" then - let parsedProject = FSharpProjectFileInfo.Parse(file, properties=properties, enableLogging=false) - match parsedProject.OutputFile with - | None -> () - | Some f -> yield "-r:" + f ] - else - [] - - // On some versions of Mono the referenced projects are already - // correctly included, so we make sure not to introduce duplicates - |> List.filter (fun r -> not (Set.contains r (set parsedProject.Options))) - - let options = { ProjectFile = file - Options = Array.ofSeq (parsedProject.Options @ referencedProjectOutputs) - ReferencedProjectOptions = referencedProjectOptions - LogOutput = parsedProject.LogOutput - Error = null } - - let result = parsedProject.OutputFile, options - cache.Add(file,result) - result - - snd (getOptions file) - - - let rec pairs l = - match l with - | [] | [_] -> [] - | x::y::rest -> (x,y) :: pairs rest - - let crackOpen (argv: string[])= - if argv.Length >= 2 then - let projectFile = argv.[0] - let enableLogging = match Boolean.TryParse(argv.[1]) with - | true, true -> true - | _ -> false - try - let props = pairs (List.ofArray argv.[2..]) - let opts = getOptions argv.[0] enableLogging props - 0, opts - with e -> - 2, { ProjectFile = projectFile; - Options = [||]; - ReferencedProjectOptions = [||]; - LogOutput = e.ToString() + " StackTrace: " + e.StackTrace - Error = e.Message + " StackTrace: " + e.StackTrace } - else - 1, { ProjectFile = ""; - Options = [||]; - ReferencedProjectOptions = [||]; - LogOutput = "At least two arguments required." - Error = null } diff --git a/fcs/FSharp.Compiler.Service.Tests/App.config b/fcs/FSharp.Compiler.Service.Tests/App.config deleted file mode 100644 index fb0bc6286b1..00000000000 --- a/fcs/FSharp.Compiler.Service.Tests/App.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj b/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj deleted file mode 100644 index 534a1435415..00000000000 --- a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - $(FcsTargetNetFxFramework);netstandard2.0 - false - $(NoWarn);0067;1591 - - - - - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj deleted file mode 100644 index 0c32c068af2..00000000000 --- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - $(FcsTargetNetFxFramework);netcoreapp3.0 - true - 4.1.19 - $(NoWarn);44;75; - true - true - false - true - true - - - $(DefineConstants);NO_PROJECTCRACKER - - - - FsUnit.fs - - - Common.fs - - - AssemblyReaderShim.fs - - - EditorTests.fs - - - Symbols.fs - - - FileSystemTests.fs - - - ProjectAnalysisTests.fs - - - MultiProjectAnalysisTests.fs - - - PerfTests.fs - - - InteractiveCheckerTests.fs - - - ExprTests.fs - - - CSharpProjectAnalysis.fs - - - ProjectOptionsTests.fs - - - StructureTests.fs - - - TokenizerTests.fs - - - ServiceUntypedParseTests.fs - - - TreeVisitorTests.fs - - - Program.fs - - - {{FSCoreVersion}} - $(FSCoreVersion) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.sln b/fcs/FSharp.Compiler.Service.sln deleted file mode 100644 index 192f8bd6242..00000000000 --- a/fcs/FSharp.Compiler.Service.sln +++ /dev/null @@ -1,153 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.16 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{B6B68AE6-E7A4-4D43-9B34-FFA74BFE192B}" - ProjectSection(SolutionItems) = preProject - build.cmd = build.cmd - build.fsx = build.fsx - build.sh = build.sh - nuget\FSharp.Compiler.Service.MSBuild.v12.nuspec = nuget\FSharp.Compiler.Service.MSBuild.v12.nuspec - nuget\FSharp.Compiler.Service.nuspec = nuget\FSharp.Compiler.Service.nuspec - nuget\FSharp.Compiler.Service.ProjectCracker.nuspec = nuget\FSharp.Compiler.Service.ProjectCracker.nuspec - paket.dependencies = paket.dependencies - README.md = README.md - RELEASE_NOTES.md = RELEASE_NOTES.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docsrc", "docsrc", "{83FEE492-6701-4E59-9184-16B1D30E91F8}" - ProjectSection(SolutionItems) = preProject - docsrc\content\caches.fsx = docsrc\content\caches.fsx - docsrc\content\corelib.fsx = docsrc\content\corelib.fsx - docsrc\content\devnotes.md = docsrc\content\devnotes.md - docsrc\content\editor.fsx = docsrc\content\editor.fsx - docsrc\content\filesystem.fsx = docsrc\content\filesystem.fsx - docsrc\content\fsharp-readme.md = docsrc\content\fsharp-readme.md - docsrc\content\index.md = docsrc\content\index.md - docsrc\content\interactive.fsx = docsrc\content\interactive.fsx - docsrc\content\project.fsx = docsrc\content\project.fsx - docsrc\content\queue.fsx = docsrc\content\queue.fsx - docsrc\content\symbols.fsx = docsrc\content\symbols.fsx - docsrc\content\tokenizer.fsx = docsrc\content\tokenizer.fsx - docsrc\content\typedtree.fsx = docsrc\content\typedtree.fsx - docsrc\content\untypedtree.fsx = docsrc\content\untypedtree.fsx - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0554567F-1DCB-46A5-9EF2-E1938A3D4F14}" - ProjectSection(SolutionItems) = preProject - docsrc\tools\generate.fsx = docsrc\tools\generate.fsx - docsrc\tools\templates\template.cshtml = docsrc\tools\templates\template.cshtml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E396742E-B4E5-4584-A9E4-CC1A491F5BC1}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "EditorService", "samples\EditorService\EditorService.fsproj", "{A40507D6-FA48-43D3-B18A-AE3DAACE4020}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "InteractiveService", "samples\InteractiveService\InteractiveService.fsproj", "{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tokenizer", "samples\Tokenizer\Tokenizer.fsproj", "{92793069-816F-4F69-84AC-0966F8275E65}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UntypedTree", "samples\UntypedTree\UntypedTree.fsproj", "{C816728D-BBEA-472D-9F6C-E8913957A673}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FscExe", "samples\FscExe\FscExe.fsproj", "{C94C257C-3C0A-4858-B5D8-D746498D1F08}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharp_Analysis", "FSharp.Compiler.Service.Tests\CSharp_Analysis\CSharp_Analysis.csproj", "{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsiExe", "samples\FsiExe\FsiExe.fsproj", "{F9540CA8-1CE0-4546-A23A-A461E416E95B}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.ProjectCrackerTool", "FSharp.Compiler.Service.ProjectCrackerTool\FSharp.Compiler.Service.ProjectCrackerTool.fsproj", "{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.ProjectCracker", "FSharp.Compiler.Service.ProjectCracker\FSharp.Compiler.Service.ProjectCracker.fsproj", "{893C3CD9-5AF8-4027-A667-21E62FC2C703}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{098D1C35-D0FB-4720-83DD-8002293EA237}" - ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - .travis.yml = .travis.yml - appveyor.yml = appveyor.yml - NuGet.Config = NuGet.Config - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "package", "package", "{9020E136-794A-473F-9B1B-9623C97B7161}" - ProjectSection(SolutionItems) = preProject - nuget\FSharp.Compiler.Service.template = nuget\FSharp.Compiler.Service.template - nuget\projectcracker.template = nuget\projectcracker.template - EndProjectSection -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.MSBuild.v12", "FSharp.Compiler.Service.MSBuild.v12\FSharp.Compiler.Service.MSBuild.v12.fsproj", "{8157B50E-397D-4232-A4E0-1977AFC7076D}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service", "FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.Tests", "FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj", "{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Release|Any CPU.Build.0 = Release|Any CPU - {067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Debug|Any CPU.Build.0 = Debug|Any CPU - {067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Release|Any CPU.ActiveCfg = Release|Any CPU - {067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Release|Any CPU.Build.0 = Release|Any CPU - {92793069-816F-4F69-84AC-0966F8275E65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92793069-816F-4F69-84AC-0966F8275E65}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92793069-816F-4F69-84AC-0966F8275E65}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92793069-816F-4F69-84AC-0966F8275E65}.Release|Any CPU.Build.0 = Release|Any CPU - {C816728D-BBEA-472D-9F6C-E8913957A673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C816728D-BBEA-472D-9F6C-E8913957A673}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C816728D-BBEA-472D-9F6C-E8913957A673}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C816728D-BBEA-472D-9F6C-E8913957A673}.Release|Any CPU.Build.0 = Release|Any CPU - {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.Build.0 = Release|Any CPU - {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.Build.0 = Release|Any CPU - {F9540CA8-1CE0-4546-A23A-A461E416E95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F9540CA8-1CE0-4546-A23A-A461E416E95B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F9540CA8-1CE0-4546-A23A-A461E416E95B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F9540CA8-1CE0-4546-A23A-A461E416E95B}.Release|Any CPU.Build.0 = Release|Any CPU - {B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Release|Any CPU.Build.0 = Release|Any CPU - {893C3CD9-5AF8-4027-A667-21E62FC2C703}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {893C3CD9-5AF8-4027-A667-21E62FC2C703}.Debug|Any CPU.Build.0 = Debug|Any CPU - {893C3CD9-5AF8-4027-A667-21E62FC2C703}.Release|Any CPU.ActiveCfg = Release|Any CPU - {893C3CD9-5AF8-4027-A667-21E62FC2C703}.Release|Any CPU.Build.0 = Release|Any CPU - {8157B50E-397D-4232-A4E0-1977AFC7076D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8157B50E-397D-4232-A4E0-1977AFC7076D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8157B50E-397D-4232-A4E0-1977AFC7076D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8157B50E-397D-4232-A4E0-1977AFC7076D}.Release|Any CPU.Build.0 = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU - {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {0554567F-1DCB-46A5-9EF2-E1938A3D4F14} = {83FEE492-6701-4E59-9184-16B1D30E91F8} - {A40507D6-FA48-43D3-B18A-AE3DAACE4020} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - {067E95E5-E3DC-4CA7-813A-4D1E277D2D52} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - {92793069-816F-4F69-84AC-0966F8275E65} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - {C816728D-BBEA-472D-9F6C-E8913957A673} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - {C94C257C-3C0A-4858-B5D8-D746498D1F08} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - {F9540CA8-1CE0-4546-A23A-A461E416E95B} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9E9BAC7B-3834-497C-B7AC-6B7988778D1A} - EndGlobalSection -EndGlobal diff --git a/fcs/FSharp.Compiler.Service/.gitignore b/fcs/FSharp.Compiler.Service/.gitignore deleted file mode 100644 index 722f2e9b839..00000000000 --- a/fcs/FSharp.Compiler.Service/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -net4*/ -netstandard*/ diff --git a/fcs/FSharp.Compiler.Service/AssemblyInfo.fs b/fcs/FSharp.Compiler.Service/AssemblyInfo.fs deleted file mode 100644 index 90521fefd5a..00000000000 --- a/fcs/FSharp.Compiler.Service/AssemblyInfo.fs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Microsoft.FSharp -open System.Reflection -open System.Runtime.InteropServices - -[] -[] -[] -[] -[] -[] - -#if NO_STRONG_NAMES -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] - -// Note: internals visible to unit test DLLs in Retail (and all) builds. -[] -[] -[] -[] -[] -#endif - -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] -[] - -// Until dotnet sdk can version assemblies, use this -#if BUILD_FROM_SOURCE -[] -[] -[] -#endif - -do() \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj deleted file mode 100644 index f99d7aac7af..00000000000 --- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ /dev/null @@ -1,701 +0,0 @@ - - - - - - $(FcsTargetNetFxFramework);netstandard2.0 - true - $(DefineConstants);COMPILER_SERVICE_AS_DLL - $(DefineConstants);COMPILER - $(DefineConstants);ENABLE_MONO_SUPPORT - $(DefineConstants);NO_STRONG_NAMES - $(DefineConstants);LOCALIZATION_FSCOMP - $(TargetFramework)\ - $(TargetFramework)\ - $(OtherFlags) /warnon:1182 - $(OtherFlags) --times - $(NoWarn);44;62;69;65;54;61;75;62;9;2003;NU5125 - true - true - true - - - The F# compiler as library. For editors, for tools, for scripting. For you. - The F# compiler services package contains a custom build of the F# compiler that exposes additional functionality for implementing F# language bindings, additional tools based on the compiler or refactoring tools. The package also includes F# interactive service that can be used for embedding F# scripting into your applications. - false - Microsoft Corporation; F# community contributors - https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE - https://github.com/fsharp/FSharp.Compiler.Service - logo.png - F#, fsharp, interactive, compiler, editor - - - $(DefineConstants);FX_NO_PDB_READER - $(DefineConstants);FX_NO_PDB_WRITER - $(DefineConstants);FX_NO_SYMBOLSTORE - $(DefineConstants);FX_NO_APP_DOMAINS - $(DefineConstants);FX_NO_WIN_REGISTRY - $(DefineConstants);FX_NO_SYSTEM_CONFIGURATION - $(DefineConstants);FX_RESHAPED_REFEMIT - - - - - AssemblyInfo/AssemblyInfo.fs - - - FSComp.txt - - - FSIstrings.txt - - - FSStrings.resx - FSStrings.resources - - - --module FSharp.Compiler.AbstractIL.Internal.AsciiParser --open FSharp.Compiler.AbstractIL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - ilpars.fsy - - - --module FSharp.Compiler.Parser --open FSharp.Compiler --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - pars.fsy - - - Logger.fsi - - - Logger.fs - - - ErrorText/sformat.fsi - - - ErrorText/sformat.fs - - - ErrorText/sr.fsi - - - ErrorText/sr.fs - - - Driver\LanguageFeatures.fsi - - - Driver\LanguageFeatures.fs - - - LexYaccRuntime/prim-lexing.fsi - - - LexYaccRuntime/prim-lexing.fs - - - LexYaccRuntime/prim-parsing.fsi - - - LexYaccRuntime/prim-parsing.fs - - - Utilities/PathMap.fsi - - - Utilities/PathMap.fs - - - Utilities/ResizeArray.fsi - - - Utilities/ResizeArray.fs - - - Utilities/HashMultiMap.fsi - - - Utilities/HashMultiMap.fs - - - Utilities/EditDistance.fs - - - Utilities/TaggedCollections.fsi - - - Utilities/TaggedCollections.fs - - - Utilities/QueueList.fs - - - Utilities/ildiag.fsi - - - Utilities/ildiag.fs - - - Utilities/illib.fs - - - Utilities/filename.fsi - - - Utilities/filename.fs - - - Utilities/zmap.fsi - - - Utilities/zmap.fs - - - Utilities/zset.fsi - - - Utilities/zset.fs - - - Utilities/bytes.fsi - - - Utilities/bytes.fs - - - Utilities\XmlAdapters.fs - - - Utilities/lib.fs - - - Utilities/InternalCollections.fsi - - - Utilities/InternalCollections.fs - - - Utilities/rational.fsi - - - Utilities/rational.fs - - - ErrorLogging/range.fsi - - - ErrorLogging/range.fs - - - ErrorLogging/ErrorLogger.fs - - - ErrorLogging/ErrorResolutionHints.fs - - - --unicode --lexlib Internal.Utilities.Text.Lexing - AbsIL/illex.fsl - - - AbsIL/il.fsi - - - AbsIL/il.fs - - - AbsIL/ilx.fsi - - - AbsIL/ilx.fs - - - AbsIL/ilascii.fsi - - - AbsIL/ilascii.fs - - - AbsIL/ilprint.fsi - - - AbsIL/ilprint.fs - - - AbsIL/ilmorph.fsi - - - AbsIL/ilmorph.fs - - - - - AbsIL/ilsign.fs - - - - - AbsIL/ilnativeres.fsi - - - AbsIL/ilnativeres.fs - - - AbsIL/ilsupp.fsi - - - AbsIL/ilsupp.fs - - - AbsIL/ilpars.fs - - - AbsIL/illex.fs - - - AbsIL/ilbinary.fsi - - - AbsIL/ilbinary.fs - - - AbsIL/ilread.fsi - - - AbsIL/ilread.fs - - - AbsIL/ilwritepdb.fsi - - - AbsIL/ilwritepdb.fs - - - AbsIL/ilwrite.fsi - - - AbsIL/ilwrite.fs - - - AbsIL/ilreflect.fs - - - ReferenceResolution/reshapedmsbuild.fs - - - ReferenceResolution/ReferenceResolver.fs - - - ReferenceResolution/SimulatedMSBuildReferenceResolver.fs - - - CompilerLocation/CompilerLocationUtils.fs - - - PrettyNaming/PrettyNaming.fs - - - ILXErase/ilxsettings.fs - - - ILXErase/EraseClosures.fsi - - - ILXErase/EraseClosures.fs - - - ILXErase/EraseUnions.fsi - - - ILXErase/EraseUnions.fs - - - --unicode --lexlib Internal.Utilities.Text.Lexing - ParserAndUntypedAST/lex.fsl - - - --unicode --lexlib Internal.Utilities.Text.Lexing - ParserAndUntypedAST/pplex.fsl - - - --module FSharp.Compiler.PPParser --open FSharp.Compiler --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - ParserAndUntypedAST/pppars.fsy - - - ParserAndUntypedAST/UnicodeLexing.fsi - - - ParserAndUntypedAST/UnicodeLexing.fs - - - ParserAndUntypedAST/layout.fsi - - - ParserAndUntypedAST/layout.fs - - - ParserAndUntypedAST/ast.fs - - - ParserAndUntypedAST/pppars.fs - - - ParserAndUntypedAST/pars.fs - - - ParserAndUntypedAST/lexhelp.fsi - - - ParserAndUntypedAST/lexhelp.fs - - - ParserAndUntypedAST/pplex.fs - - - ParserAndUntypedAST/lex.fs - - - ParserAndUntypedAST/LexFilter.fs - - - TypedAST/tainted.fsi - - - TypedAST/tainted.fs - - - TypedAST/ExtensionTyping.fsi - - - TypedAST/ExtensionTyping.fs - - - TypedAST/QuotationPickler.fsi - - - TypedAST/QuotationPickler.fs - - - TypedAST/CompilerGlobalState.fs - - - TypedAST/tast.fs - - - TypedAST/TcGlobals.fs - - - TypedAST/TastOps.fsi - - - TypedAST/TastOps.fs - - - TypedAST/TastPickle.fsi - - - TypedAST/TastPickle.fs - - - Logic/import.fsi - - - Logic/import.fs - - - Logic/infos.fs - - - Logic/AccessibilityLogic.fs - - - Logic/AttributeChecking.fs - - - Logic/InfoReader.fs - - - Logic/NicePrint.fs - - - Logic/AugmentWithHashCompare.fsi - - - Logic/AugmentWithHashCompare.fs - - - Logic/NameResolution.fsi - - - Logic/NameResolution.fs - - - Logic/TypeRelations.fs - - - Logic/SignatureConformance.fs - - - Logic/MethodOverrides.fs - - - Logic/MethodCalls.fs - - - Logic/PatternMatchCompilation.fsi - - - Logic/PatternMatchCompilation.fs - - - Logic/ConstraintSolver.fsi - - - Logic/ConstraintSolver.fs - - - Logic/CheckFormatStrings.fsi - - - Logic/CheckFormatStrings.fs - - - Logic/FindUnsolved.fsi - - - Logic/FindUnsolved.fs - - - Logic/QuotationTranslator.fsi - - - Logic/QuotationTranslator.fs - - - Logic/PostInferenceChecks.fsi - - - Logic/PostInferenceChecks.fs - - - Logic/TypeChecker.fsi - - - Logic/TypeChecker.fs - - - Optimize/Optimizer.fsi - - - Optimize/Optimizer.fs - - - Optimize/DetupleArgs.fsi - - - Optimize/DetupleArgs.fs - - - Optimize/InnerLambdasToTopLevelFuncs.fsi - - - Optimize/InnerLambdasToTopLevelFuncs.fs - - - Optimize/LowerCallsAndSeqs.fsi - - - Optimize/LowerCallsAndSeqs.fs - - - Optimize/autobox.fsi - - - Optimize/autobox.fs - - - CodeGen/IlxGen.fsi - - - CodeGen/IlxGen.fs - - - Driver\DotNetFrameworkDependencies.fs - - - Driver/DependencyManager.Integration.fsi - - - Driver/DependencyManager.Integration.fs - - - Driver/CompileOps.fsi - - - Driver/CompileOps.fs - - - Driver/CompileOptions.fsi - - - Driver/CompileOptions.fs - - - Driver/fsc.fsi - - - Driver/fsc.fs - - - Symbols/SymbolHelpers.fsi - - - Symbols/SymbolHelpers.fs - - - Symbols/Symbols.fsi - - - Symbols/Symbols.fs - - - Symbols/Exprs.fsi - - - Symbols/Exprs.fs - - - Symbols/SymbolPatterns.fsi - - - Symbols/SymbolPatterns.fs - - - Service/Reactor.fsi - - - Service/Reactor.fs - - - Service/IncrementalBuild.fsi - - - Service/IncrementalBuild.fs - - - Service/ServiceConstants.fs - - - Service/ServiceLexing.fsi - - - Service/ServiceLexing.fs - - - Service/ServiceParseTreeWalk.fs - - - Service/ServiceNavigation.fsi - - - Service/ServiceNavigation.fs - - - Service/ServiceParamInfoLocations.fsi - - - Service/ServiceParamInfoLocations.fs - - - Service/ServiceUntypedParse.fsi - - - Service/ServiceUntypedParse.fs - - - Service/ServiceDeclarationLists.fsi - - - Service/ServiceDeclarationLists.fs - - - Service/ServiceAssemblyContent.fsi - - - Service/ServiceAssemblyContent.fs - - - Service/ServiceXmlDocParser.fsi - - - Service/ServiceXmlDocParser.fs - - - Service/ExternalSymbol.fsi - - - Service/ExternalSymbol.fs - - - Service/QuickParse.fsi - - - Service/QuickParse.fs - - - Service/FSharpCheckerResults.fsi - - - Service/FSharpCheckerResults.fs - - - Service/service.fsi - - - Service/service.fs - - - Service/ServiceInterfaceStubGenerator.fsi - - - Service/ServiceInterfaceStubGenerator.fs - - - Service/ServiceStructure.fsi - - - Service/ServiceStructure.fs - - - Service/ServiceAnalysis.fsi - - - Service/ServiceAnalysis.fs - - - Service/fsi.fsi - - - Service/fsi.fs - - - - - - - - - - - - - - - - - - - - - $(FSharpSourcesRoot)\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - - \ No newline at end of file diff --git a/fcs/README.md b/fcs/README.md deleted file mode 100644 index 8a518f62198..00000000000 --- a/fcs/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# The FSharp.Compiler.Service components and NuGet package - -This directory contains the build, packaging, test and documentation-generation logic for the NuGet package ``FSharp.Compiler.Service``. The source for this NuGet -package is in ``..\src``. - -Basically we are packaging up the compiler as a DLL and publishing it as a NuGet package. - -## FSharp.Compiler.Service v. FSharp.Compiler.Private - -There are subtle differences between FSharp.Compiler.Service and FSharp.Compiler.Private (shipped with the Visual F# Tools) - -- FCS has a public API - -- FCS is built against **.NET 4.6.1** and **FSharp.Core NuGet 4.6.2** to give broader reach - -- FCS has a NuGet package - -- FCS has a .NET Standard 2.0 version in the nuget package - -- FCS testing also tests the "Project Cracker" (see below) - -- FCS doesn't add the System.ValueTuple.dll reference by default, see ``#if COMPILER_SERVICE_AS_DLL`` in compiler codebase - -## Version Numbers - -FCS uses its own version number sequence for assemblies and packages, approximately following SemVer rules. -To update the version number a global replace through fcs\... is currently needed, e.g. - - Directory.Build.props - nuget/FSharp.Compiler.Service.nuspec - nuget/FSharp.Compiler.Service.MSBuild.v12.nuspec - nuget/FSharp.Compiler.Service.ProjectCracker.nuspec - RELEASE_NOTES.md - -## Building, Testing, Packaging, Releases - -To build the package use any of: - - fcs\build Build.NetFx - fcs\build Test.NetFx - fcs\build NuGet.NetFx - - fcs\build Build.NetStd - fcs\build Test.NetStd - fcs\build NuGet.NetStd - - fcs\build Build - fcs\build Test - fcs\build NuGet - fcs\build Release - -which does things like: - - cd fcs - .paket\paket.bootstrapper.exe - .paket\paket.exe restore - dotnet restore tools.proj - packages\FAKE\tools\FAKE.exe build.fsx WhateverTarget - -### Manual push of packages - -You can push the packages if you have permissions, either automatically using ``build Release`` or manually - - set APIKEY=... - ..\fsharp\.nuget\nuget.exe push %HOMEDRIVE%%HOMEPATH%\Downloads\FSharp.Compiler.Service.22.0.3.nupkg %APIKEY% -Source https://nuget.org - ..\fsharp\.nuget\nuget.exe push %HOMEDRIVE%%HOMEPATH%\Downloads\FSharp.Compiler.Service.MSBuild.v12.22.0.3.nupkg %APIKEY% -Source https://nuget.org - ..\fsharp\.nuget\nuget.exe push %HOMEDRIVE%%HOMEPATH%\Downloads\FSharp.Compiler.Service.ProjectCracker.22.0.3.nupkg %APIKEY% -Source https://nuget.org - -### Use of Paket and FAKE - -Paket is only used to get FAKE and FSharp.Formatting tools. Eventually we will likely remove this once we update the project files to .NET SDK 2.0. - -FAKE is only used to run build.fsx. Eventually we will likely remove this once we update the project files to .NET SDK 2.0. - -### Testing - -Testing reuses the test files from ..\tests\service which were are also FCS tests. - -### Documentation Generation - - fcs\build GenerateDocs - -Output is in ``docs``. In the ``FSharp.Compiler.Service`` repo this is checked in and hosted as . - -## The two other NuGet packages - -It also contains both the source, build, packaging and test logic for - -- ``FSharp.Compiler.Service.MSBuild.v12`` adds legacy MSBuild v12 support to an instance of FSharp.Compiler.Service, if exact compatibility for scripting references such as ``#r "Foo, Version=1.3.4"`` is required. - -- ``FSharp.Compiler.Service.ProjectCracker`` is part of ``FsAutoComplete`` and Ionide and is used to crack old-style project formats using MSBuild. It used to be part of the FCS API. - -Both of these components are gradually becoming obsolete - -## Engineering road map - -FSharp.Compiler.Service is a somewhat awkward component. There are some things we can do to simplify things: - -1. Remove the use of Paket and FAKE -1. Move all projects under fcs\... to new .NET SDK project file format -1. Drop the use of ``dotnet mergenupkg`` since we should be able to use cross targeting -1. Make FCS a DLL similar to the rest of the build and make this an official component from Microsoft (signed etc.) -1. Replace FSharp.Compiler.Private by FSharp.Compiler.Service diff --git a/fcs/RELEASE_NOTES.md b/fcs/RELEASE_NOTES.md deleted file mode 100644 index e1cb2f3ecb6..00000000000 --- a/fcs/RELEASE_NOTES.md +++ /dev/null @@ -1,629 +0,0 @@ -#### 23.0.1 - * FSharp.Compiler.Service nuget now uses net461, netstandard2.0 and FSharp.Core 4.6.2 - -#### 22.0.3 - * [Add entity.DeclaringEntity](https://github.com/Microsoft/visualfsharp/pull/4633), [FCS feature request](https://github.com/fsharp/FSharp.Compiler.Service/issues/830) - -#### 22.0.2 - * Use correct version number in DLLs (needed until https://github.com/Microsoft/visualfsharp/issues/3113 is fixed) - -#### 22.0.1 - * Integrate visualfsharp master - * Includes recent memory usage reduction work for ByteFile and ILAttributes - -#### 21.0.1 - * Use new .NET SDK project files - * FSharp.Compiler.Service nuget now uses net461 and netstandard2.0 - * FSharp.Compiler.Service netstandard2.0 now supports type providers - -#### 19.0.1 - * Rename ``LogicalEnclosingEntity`` to ``ApparentEnclosingEntity`` for consistency int he F# codebase terminology. - * Rename ``EnclosingEntity`` to ``DeclaringEntity``. In the case of extension properties, ``EnclosingEntity`` was incorrectly returning the logical enclosing entity (i.e. the type the property appears to extend), and in this case ``ApparentEnclosingEntity`` should be used instead. - -#### 18.0.1 - * Integrate visualfsharp master - -#### 17.0.2 - * Integrate visualfsharp master - -#### 16.0.3 - * [File name deduplication not working with ParseAndCheckFileInProject](https://github.com/fsharp/FSharp.Compiler.Service/issues/819) - -#### 16.0.2 - * [ProjectCracker returns *.fsi files in FSharpProjectOptions.SourceFiles array](https://github.com/fsharp/FSharp.Compiler.Service/pull/812) - - * [Fix line endings in the Nuget packages descriptions](https://github.com/fsharp/FSharp.Compiler.Service/pull/811) - -#### 16.0.1 - * FSharpChecker provides non-reactor ParseFile instead of ParseFileInProject - * Add FSharpParsingOptions, GetParsingOptionsFromProjectOptions, GetParsingOptionsFromCommandLine - -#### 15.0.1 - * Integrate latest changes from visualfsharp - * Add implementation file contents to CheckFileResults - * Fix non-public API in .NET Standard 1.6 version - -#### 14.0.1 - * Integrate latest changes from visualfsharp - * Trial release for new build in fcs\... - -#### 13.0.1 - * Move docs --> docssrc - -#### 13.0.0 - * Move FSharp.Compiler.Service.MSBuild.v12.dll to a separate nuget package - -#### 12.0.8 - * Set bit on output executables correctly - -#### 12.0.7 - * Integrate visualfsharp master - -#### 12.0.6 - * [758: Fix project cracker when invalid path given](https://github.com/fsharp/FSharp.Compiler.Service/pull/758) - -#### 12.0.5 - * Remove dependency on System.ValueTuple - -#### 12.0.3 - * [De-duplicate module names again](https://github.com/fsharp/FSharp.Compiler.Service/pull/749) - -#### 12.0.2 - * De-duplicate module names - -#### 12.0.1 - * [Integrate visualfsharp and fsharp](https://github.com/fsharp/fsharp/pull/696) - -#### 11.0.10 - * [Fix F# Interactive on Mono 4.0.9+](https://github.com/fsharp/fsharp/pull/696) - -#### 11.0.9 - * [Make incremental builder counter atomic](https://github.com/fsharp/FSharp.Compiler.Service/pull/724) - * [Add IsValCompiledAsMethod to FSharpMemberOrFunctionOrValue](https://github.com/fsharp/FSharp.Compiler.Service/pull/727) - * [Check before ILTypeInfo.FromType](https://github.com/fsharp/FSharp.Compiler.Service/issues/734) - * [Transition over to dotnet cli Fsproj](https://github.com/fsharp/FSharp.Compiler.Service/issues/700) - -#### 11.0.8 - * Depend on FSharp.Core package - -#### 11.0.6 - * Fix [stack overflow exception](https://github.com/fsharp/FSharp.Compiler.Service/issues/672) - -#### 11.0.4 - * Fix [out of range exception](https://github.com/fsharp/FSharp.Compiler.Service/issues/709) - -#### 11.0.2 - * Integrate fsharp\fsharp and Microsoft\visualfsharp to 262deb017cfcd0f0d4138779ff42ede7dbf44c46 - -#### 11.0.1 - * Integrate fsharp\fsharp and Microsoft\visualfsharp to d0cc249b951374257d5a806939e42714d8a2f4c6 - -#### 10.0.3 - * [Expose assumeDotNetFramework in FSharpChecker.GetProjectOptionsFromScript](https://github.com/fsharp/FSharp.Compiler.Service/pull/699) - * [SemanticClassificationType should not be internal](https://github.com/fsharp/FSharp.Compiler.Service/pull/696) - -#### 10.0.1 - * [Adds FormatValue to FsiEvaluationSession, using the fsi object values for formatting](https://github.com/fsharp/FSharp.Compiler.Service/pull/686) - -#### 10.0.0 - * Integrate fsharp\fsharp and Microsoft\visualfsharp to c3e55bf0b10bf08790235dc585b8cdc75f71618e - * Integrate fsharp\fsharp and Microsoft\visualfsharp to 11c0a085c96a91102cc881145ce281271ac159fe - * Some API changes for structured text provision for tagged structured text - -#### 9.0.0 - * Update names of union fields in AST API - * Fix load closure for ParseAndCheckInteraction - * [Fix #631 compiler dependency on MSBuild](https://github.com/fsharp/FSharp.Compiler.Service/pull/657) - * Fixed netcore codegen on Linux - * Explicit error when cracker exe is missing - -#### 8.0.0 - * Integrate fsharp\fsharp and Microsoft\visualfsharp to c494a9cab525dbd89585f7b733ea5310471a8001 - * Then integrate to 2002675f8aba5b3576a924a2e1e47b18e4e9a83d - * [Add module values to navigable items](https://github.com/fsharp/FSharp.Compiler.Service/pull/650) - * Optionally remove dependency on MSBuild reference resolution https://github.com/fsharp/FSharp.Compiler.Service/pull/649 - * [Compiler api harmonise](https://github.com/fsharp/FSharp.Compiler.Service/pull/639) - * Various bits of work on .NET Core version (buildable from source but not in nuget package) - -#### 7.0.0 - * Integrate fsharp\fsharp and Microsoft\visualfsharp to 835b79c041f9032fceeceb39f680e0662cba92ec - -#### 6.0.2 - * [Fix #568: recognize provided expressions](https://github.com/fsharp/FSharp.Compiler.Service/pull/568) - -#### 6.0.1 - * [Fix ProjectFileNames order when getting project options from script](https://github.com/fsharp/FSharp.Compiler.Service/pull/594) - -#### 6.0.0 - * Switch to new major version on assumption integrated F# compiler changes induce API change - -#### 5.0.2 - * Integrate Microsoft\visualfsharp to 688c26bdbbfc766326fc45e4d918f87fcba1e7ba. F# 4.1 work - -#### 5.0.1 -* [Fixed dependencies in nuget package](https://github.com/fsharp/FSharp.Compiler.Service/pull/608) - -#### 5.0.0 -* Fixed empty symbol declared pdb #564 from kekyo/fix-empty-pdb -* .NET Core ProjectCracker - updated version and dependencies -* Properly embed 'FSIstrings' resource, fixes #591 -* make build.sh work on windows (git bash). -* Added default script references for .NET Core -* Store useMonoResolution flag -* Updated MSBuild version -* Assume FSharp.Core 4.4.0.0 - -#### 4.0.1 -* Integrate Microsoft\visualfsharp and fsharp\fsharp to master (including portable PDB) -* Remove .NET Framework 4.0 support (now needs .NET Framework 4.5) - -#### 4.0.0 -* Integrate Microsoft\visualfsharp and fsharp\fsharp to master - -#### 3.0.0.0 -* #538 - BackgroundCompiler takes a very long time on a big solution with a very connected project dependency graph -* #544 - Losing operator call when one of operands is application of a partially applied function -* #534 - Function valued property erasing calls -* #495 - Detupling missing when calling a module function value -* #543 - Tuple not being destructured in AST -* #541 - Results of multiple calls to active pattern are always bound to variable with same name -* #539 - BasicPatterns.NewDelegate shows same value for different arguments - -#### 2.0.0.6 -* #530 - Adjust ProjectCracker NuGet for VS/NuGet - -#### 2.0.0.5 -* #527 - Provide API that includes printf specifier arities along with ranges - -#### 2.0.0.4 -* #519 - Change nuget layout for ProjectCracker package -* #523 - Project cracking: spaces in file paths - -#### 2.0.0.3 -* #508 - Integrate visualfsharp/master removal of Silverlight #if -* #513 - Make CrackerTool `internal` to prevent accidental usage -* #515 - Add simple Visual Studio version detection for project cracker - -#### 2.0.0.2 -* Integrate visualfsharp/master and fsharp/master --> master -* Expose QualifiedName and FileName of FSharpImplementationFileContents -* Add FSharpErrorInfo.ErrorNumber - -#### 2.0.0.1-beta -* Fix 452 - FSharpField.IsMutable = true for BCL enum cases -* Fix 414 - Add IsInstanceMemberInCompiledCode - -#### 2.0.0.0-beta -* Feature #470, #478, #479 - Move ProjectCracker to separate nuget package and DLL, used ProjectCrackerTool.exe to run -* Feature #463 - Expose slot signatures of members in object expressions -* Feature #469, #475 - Add EvalExpressionNonThrowing, EvalInteractionNonThrowing, EvalScriptNonThrowing -* Fix #456 - FCS makes calls to kernel32.dll when running on OSX -* Fix #473 - stack overflow in resolution logic -* Fix #460 - Failure getting expression for a provided method call - -#### 1.4.2.3 - -* Fix bug in loop optimization, apply https://github.com/Microsoft/visualfsharp/pull/756/ - -#### 1.4.2.2 - -* #488 - Performance problems with project references - -#### 1.4.2.1 - -* #450 - Correct generation of ReferencedProjects - -#### 1.4.2.0 - -* Fix bug in double lookup of cache, see https://github.com/fsharp/FSharp.Compiler.Service/pull/447 - -#### 1.4.1 - -* Add pause before backgrounnd work starts. The FCS request queue must be empty for 1 second before work will start -* Write trace information about the reactor queue to the event log -* Rewrite reactor to consistently prioritize queued work -* Implement cancellation for queued work if it is cancelled prior to being executed -* Adjust caching to check cache correctly if there is a gap before the request is executed - -#### 1.4.0.9 - -* FSharpType.Format fix -* Disable maximum-memory trigger by default until use case ironed out - -#### 1.4.0.8 - -* FSharpType.Format now prettifies type variables. If necessary, FSharpType.Prettify can also be called -* Add maximum-memory trigger to downsize FCS caches. Defaults to 1.7GB of allocaed memory in the system - process for a 32-bit process, and 2x this for a 64-bit process - -#### 1.4.0.7 - -* fix 427 - Make event information available for properties which represent first-class uses of F#-declared events -* fix 410 - Symbols for C# fields (and especially enum fields) -* Expose implemented abstract slots -* Fix problem with obscure filenames caught by Microsoft\visualfsharp tests -* Integrate with visualfsharp master - -#### 1.4.0.6 - -* fix 423 - Symbols for non-standard C# events -* fix 235 - XmlDocSigs for references assemblies -* fix 177 - GetAllUsesOfAllSymbolsInFile returns nothing for C# nested enum -* make Internal.Utilities.Text.Lexing.Position a struct -* Exposing assembly attributes on FSharpAssemblySignature -* clean up IncrementalFSharpBuild.frameworkTcImportsCache - -#### 1.4.0.5 - -* add more entries to FSharpTokenTag - -#### 1.4.0.4 - -* add more entries to FSharpTokenTag -* add PrettyNaming.QuoteIdentifierIfNeeded and PrettyNaming.KeywordNames - -#### 1.4.0.3 - -* integrate Microsoft/visualfsharp OOB cleanup via fsharp/fsharp -* Make Parser and Lexer private - -#### 1.4.0.2 - -* #387 - types and arrays in F# attribute contructor arguments - -#### 1.4.0.1 - F# 4.0 support -* Use FSharp.Core 4.4.0.0 by default for scripting scenarios if not FSharp.Core referenced by host process - -#### 1.4.0.0-beta - F# 4.0 support -* Integrate F# 4.0 support into FSharp.Compiler.Service - -#### 1.3.1.0 - -* simplified source indexing with new SourceLink -* Add noframework option in AST compiler methods - -#### 0.0.90 - -* Add fix for #343 Use ResolveReferences task -* Expose BinFolderOfDefaultFSharpCompiler to editors -* Fix the registry checking on mono to avoid unnecessary exceptions being thrown - -#### 0.0.89 - -* Fix output location of referenced projects - -#### 0.0.88 - -* Added Fix to allow implicit PCL references to be retrieved - -#### 0.0.87 - -* Don't report fake symbols in indexing #325 -* Add EnclosingEntity for an active pattern group #327 -* Add ImmediateSubExpressions #284 -* integrate fsharp/fsharp master into master - -#### 0.0.85 - -* Fix for FSharpSymbolUse for single case union type #301 -* Added supprt for ReturnParameter in nested functions - -#### 0.0.84 - -* Added curried parameter groups for nested functions - -#### 0.0.83 - -* Add Overloads to the symbols signature so it is publicly visible -* Update OnEvaluation event to have FSharpSymbolUse information available - -#### 0.0.82 - -* Better support for Metadata of C# (and other) Assemblies. -* Expose the DefaultFileSystem as a type instead of anonymous - -#### 0.0.81 - -* Update GetDeclarationListSymbols to expose FSharpSymbolUse -* Improve reporting of format specifiers - -#### 0.0.80 - -* Update to latest F# 3.1.3 (inclunding updated FsLex/FsYacc used in build of FCS) -* Report printf specifiers from Service API -* Improve Accessibility of non-F# symbols - -#### 0.0.79 - -* Do not use memory mapped files when cracking a DLL to get an assembly reference -* Fix for multilanguage projects in project cracker - -#### 0.0.78 - -* Reduce background checker memory usage -* add docs on FSharp.Core -* docs on caches and queues - -#### 0.0.77 - -* Update to github.com/fsharp/fsharp 05f426cee85609f2fe51b71473b07d7928bb01c8 - -#### 0.0.76 - -* Fix #249 - Fix TryFullName when used on namespaces of provided erased type definitions -* Add OnEvaluation event to FCS to allow detailed information to be exposed - -#### 0.0.75 - -* Do not use shared cursor for IL binaries (https://github.com/fsprojects/VisualFSharpPowerTools/issues/822) - -#### 0.0.74 - -* Extension members are returned as members of current modules -* Fix exceptions while cross-reference a type provider project - -#### 0.0.73 - -* Add AssemblyContents and FSharpExpr to allow access to resolved, checked expression trees -* Populate ReferencedProjects using ProjectFileInfo -* Fix finding symbols declared in signature files -* Add logging to project cracking facility - -#### 0.0.72 - -* Allow project parser to be used on project file with relative paths -* Expose attributes for non-F# symbols - -#### 0.0.71 - -* More renamings in SourceCodeServices API for more consistent use of 'FSharp' prefix - -#### 0.0.70 - -* Make FSharpProjectFileParser public -* Fixes to project parser for Mono (.NET 4.0 component) -* Renamings in SourceCodeServices API for more consistent use of 'FSharp' prefix - -#### 0.0.67 - -* Fixes to project parser for Mono - -#### 0.0.66 - -* Fixes to project parser for Mono -* Use MSBuild v12.0 for reference resolution on .NET 4.5+ - -#### 0.0.65 - -* Fixes to project parser - -#### 0.0.64 - -* Add project parser, particularly GetProjectOptionsFromProjectFile - -#### 0.0.63 - -* #221 - Normalize return types of .NET events - -#### 0.0.62 - -* Integrate to latest https://github.com/fsharp/fsharp (#80f9221f811217bd890b3a670d717ebc510aeeaf) - -#### 0.0.61 - -* #216 - Return associated getters/setters from F# properties -* #214 - Added missing XmlDocSig for FSharpMemberOrFunctionOrValue's Events, Methods and Properties -* #213 - Retrieve information for all active pattern cases -* #188 - Fix leak in file handles when using multiple instances of FsiEvaluationSession, and add optionally collectible assemblies - -#### 0.0.60 - -* #207 - Add IsLiteral/LiteralValue to FSharpField -* #205 - Add IsOptionalArg and related properties to FSharpParameter -* #210 - Check default/override members via 'IsOverrideOrExplicitMember' -* #209 - Add TryFullName to FSharpEntity - -#### 0.0.59 - -* Fix for #184 - Fix EvalScript by using verbatim string for #Load -* Fix for #183 - The line no. reporting is still using 0-based indexes in errors. This is confusing. - -#### 0.0.58 - -* Fix for #156 - The FSharp.Core should be retrieved from the hosting environment - -#### 0.0.57 - -* Second fix for #160 - Nuget package now contains .NET 4.0 and 4.5 - -#### 0.0.56 - -* Fix for #160 - Nuget package contains .NET 4.0 and 4.5 - -#### 0.0.55 - -* Integrate changes for F# 3.1.x, Fix #166 - -#### 0.0.54 - -* Fix for #159 - Unsubscribe from TP Invalidate events when disposing builders - -#### 0.0.53 - -* Add queue length to InteractiveChecker - -#### 0.0.52 - -* Fix caches keeping hold of stale entries - -#### 0.0.51 - -* Add IsAccessible to FSharpSymbol, and ProjectContext.AccessibilityRights to give the context of an access - -#### 0.0.50 - -* Fix #79 - FindUsesOfSymbol returns None at definition of properties with explicit getters and setters - -#### 0.0.49 - -* Fix #138 - Fix symbol equality for provided type members -* Fix #150 - Return IsGetterMethod = true for declarations of F# properties (no separate 'property' symbol is yet returned, see #79) -* Fix #132 - Add IsStaticInstantiation on FSharpEntity to allow clients to detect fake symbols arising from application of static parameters -* Fix #154 - Add IsArrayType on FSharpEntity to allow clients to detect the symbols for array types -* Fix #96 - Return resolutions of 'Module' and 'Type' in "Module.field" and "Type.field" - -#### 0.0.48 - -* Allow own fsi object without referencing FSharp.Compiler.Interactive.Settings.dll (#127) - -#### 0.0.47 - -* Adjust fix for #143 for F# types with abstract+default events - -#### 0.0.46 - -* Fix multi-project analysis when referenced projects have changed (#141) -* Fix process exit on bad arguments to FsiEvaluationSession (#126) -* Deprecate FsiEvaluationSession constructor and add FsiEvaluationSession.Create static method to allow for future API that can return errors -* Return additional 'property' and 'event' methods for F#-defined types to regularize symbols (#108, #143) -* Add IsPropertySetterMethod and IsPropertyGetterMethod which only return true for getter/setter methods, not properties. Deprecate IsSetterMethod and IsGetterMethod in favour of these. -* Add IsEventAddMethod and IsEventRemoveMethod which return true for add/remove methods with an associated event -* Change IsProperty and IsEvent to only return true for the symbols for properties and events, rather than the methods associated with these -* Fix value of Assembly for some symbols (e.g. property symbols) - -#### 0.0.45 - -* Add optional project cache size parameter to InteractiveChecker -* Switch to openBinariesInMemory for SimpleSourceCodeServices -* Cleanup SimpleSourceCodeServices to avoid code duplication - -#### 0.0.44 - -* Integrate latest changes from visualfsharp.codeplex.com via github.com/fsharp/fsharp -* Fix problem with task that generates description text of declaration -* Add AllInterfaceTypes to FSharpEntity and FSharpType -* Add BaseType to FSharpType to propagate instantiation -* Add Instantiate to FSharpType - -#### 0.0.43 - -* Fix #109 - Duplicates in GetUsesOfSymbolInFile - -#### 0.0.42 - -* Fix #105 - Register enum symbols in patterns -* Fix #107 - Return correct results for inheritance chain of .NET types -* Fix #101 - Add DeclaringEntity property - -#### 0.0.41 - -* Fixed #104 - Make all operations that may utilize the FCS reactor async -* Add FSharpDisplayContext and FSharpType.Format -* Replace GetSymbolAtLocationAlternate by GetSymbolUseAtLocation - -#### 0.0.40 - -* Fixed #86 - Expose Microsoft.FSharp.Compiler.Interactive.Shell.Settings.fsi -* Fixed #99 - Add IsNamespace property to FSharpEntity - -#### 0.0.39 - -* Fixed #79 - Usage points for symbols in union patterns - -#### 0.0.38 - -* Fixed #94 and #89 by addition of new properties to the FSharpSymbolUse type -* Fixed #93 by addition of IsOpaque to FSharpEntity type -* Fixed #92 - Issue with nested classes -* Fixed #87 - Allow analysis of members from external assemblies - -#### 0.0.37 - -* Obsolete HasDefaultValue - see https://github.com/fsharp/FSharp.Compiler.Service/issues/77 - -#### 0.0.36 - -* Fix #71 - Expose static parameters and xml docs of type providers -* Fix #63 - SourceCodeServices: #r ignores include paths passed as command-line flags - -#### 0.0.35 - -* Fix #38 - FSharp.Compiler.Services should tolerate an FSharp.Core without siginfo/optdata in the search path - - -#### 0.0.34 - -* Add StaticParameters property to entities, plus FSharpStaticParameter symbol -* Fix #65 - -#### 0.0.33 - -* Add FullName and Assembly properties for symbols -* Fix #76 -* Add Japanese documentation - -#### 0.0.32 - -* Make ParseFileInProject asynchronous -* Add ParseAndCheckFileInProject -* Use cached results in ParseAndCheckFileInProject if available - -#### 0.0.31 - -* Fix performance problem with CheckFileInProject - -#### 0.0.30 - -* Add initial prototype version of multi-project support, through optional ProjectReferences in ProjectOptions. Leave this empty - to use DLL/file-based references to results from other projects. - -#### 0.0.29 - -* Fix symbols for named union fields in patterns - -#### 0.0.28 - -* Fix symbols for named union fields -* Add FSharpActivePatternCase to refine FSharpSymbol - -#### 0.0.27 - -* Fix exception tag symbol reporting - -#### 0.0.26 - -* Fix off-by-one in reporting of range for active pattern name - -#### 0.0.25 - -* Add optional source argument to TryGetRecentTypeCheckResultsForFile to specify that source must match exactly - -#### 0.0.24 - -* Update version number as nuget package may not have published properly - -#### 0.0.23 - -* Move to one-based line numbering everywhere -* Provide better symbol information for active patterns - -#### 0.0.22 - -* Provide symbol location for type parameters - -#### 0.0.21 - -* Add GetUsesOfSymbolInFile -* Better symbol resolution results for type parameter symbols - -#### 0.0.20 - -* Update version number as nuget package may not have published properly - -#### 0.0.19 - -* Change return type of GetAllUsesOfSymbol, GetAllUsesOfAllSymbols and GetAllUsesOfAllSymbolsInFile to FSharpSymbolUse -* Add symbol uses when an abstract member is implemented. - -#### 0.0.18 - -* Add GetAllUsesOfAllSymbols and GetAllUsesOfAllSymbolsInFile - -#### 0.0.17 - -* Improvements to symbol accuracy w.r.t. type abbreviations - -#### 0.0.16 - -* Make FSharpEntity.BaseType return an option -* FsiSesion got a new "EvalScript" method which allows to evaluate .fsx files - -#### 0.0.15 - -* Update version number as nuget package may not have published properly - -#### 0.0.14 - -* Update version number as nuget package may not have published properly - -#### 0.0.13-alpha - -* Fix #39 - Constructor parameters are mistaken for record fields in classes - -#### 0.0.12-alpha - -* Make the parts of the lexer/parser used by 'XmlDoc' tools in F# VS Power tools public - -#### 0.0.11-alpha - -* Add 'IsUnresolved' - -#### 0.0.10-alpha - -* Fix bug where 'multiple references to FSharp.Core' was given as error for scripts - -#### 0.0.9-alpha - -* Fix fsc corrupting assemblies when generating pdb files (really) -* Give better error messages for missing assemblies -* Report more information about symbols returned by GetSymbolAtLocation (through subtypes) -* Fix typos in docs -* Return full project results from ParseAndCheckInteraction -* Be more robust to missing assembly references by default. - -#### 0.0.8-alpha - -* Fix fsc corrupting assemblies when generating pdb files - -#### 0.0.7-alpha - -* Fix docs -* Make symbols more robust to missing assemblies -* Be robust to failures on IncrementalBuilder creation -* Allow use of MSBuild resolution by IncrementalBuilder - -#### 0.0.6-alpha - -* Fix version number - -#### 0.0.5-alpha - -* Added GetUsesOfSymbol(), FSharpSymbol type, GetSymbolAtLocation(...) - -#### 0.0.4-alpha - -* Added documentation of file system API -* Reporte errors correctly from ParseAndCheckProject - - -#### 0.0.3-alpha - -* Integrate FSharp.PowerPack.Metadata as the FSharp* symbol API -* Renamed Param --> MethodGroupItemParameter and hid record from view, made into an object -* Renamed Method --> MethodGroupItem and hid record from view, made into an object -* Renamed Methods --> MethodGroup and hid record from view, made into an object -* Renamed MethodGroup.Name --> MethodGroup.MethodName -* Renamed DataTip --> ToolTip consistently across all text -* Renamed CheckOptions --> ProjectOptions -* Renamed TypeCheckAnswer --> CheckFileAnswer -* Renamed UntypedParseInfo --> ParseFileResults -* Removed GetCheckOptionsFromScriptRoot member overload in favour of optional argument -* Renamed GetCheckOptionsFromScriptRoot --> GetProjectOptionsFromScript -* Renamed UntypedParse --> ParseFileInProject -* Renamed TypeCheckSource --> CheckFileInProjectIfReady -* Added numerous methods to API including CheckFileInProject -* Added experimental GetBackgroundCheckResultsForFileInProject, GetBackgroundParseResultsForFileInProject -* Added PartialAssemblySignature to TypeCheckResults/CheckFileResults -* Added CurrentPartialAssemblySignature to FsiEvaluationSession -* Added ParseAndCheckInteraction to FsiEvaluationSession to support intellisense implementation against a script fragment -* Added initial testing in tests/service -* Added ParseAndCheckProject to SourceCodeServices API. This will eventually return "whole project" information such as symbol tables. -* Added GetDefaultConfiguration to simplify process of configuring FsiEvaluationSession -* Added PartialAssemblySignatureUpdated event to FsiEvaluationSession -* Added travis build - -#### 0.0.2-alpha - -* Integrate hosted FSI configuration, SimpleSourceCodeServices, cleanup to SourceCodeServices API - - diff --git a/fcs/build.cmd b/fcs/build.cmd deleted file mode 100644 index dc47a88f8cf..00000000000 --- a/fcs/build.cmd +++ /dev/null @@ -1,29 +0,0 @@ -@echo off - -setlocal -pushd %~dp0% - -dotnet tool restore - -if errorlevel 1 ( - endlocal - exit /b %errorlevel% -) - -dotnet paket restore -if errorlevel 1 ( - endlocal - exit /b %errorlevel% -) - -:: don't care if this fails -dotnet build-server shutdown >NUL 2>&1 - -dotnet fake build -t %* - -if errorlevel 1 ( - endlocal - exit /b %errorlevel% -) -endlocal -exit /b 0 diff --git a/fcs/build.fsx b/fcs/build.fsx deleted file mode 100644 index 00dc80cf6f3..00000000000 --- a/fcs/build.fsx +++ /dev/null @@ -1,150 +0,0 @@ -// -------------------------------------------------------------------------------------- -// FAKE build script -// -------------------------------------------------------------------------------------- -#r "paket: groupref Main //" -#load "./.fake/build.fsx/intellisense.fsx" - -open System -open System.IO -open Fake.BuildServer -open Fake.Core -open Fake.DotNet -open Fake.IO - -BuildServer.install [ AppVeyor.Installer ] -// -------------------------------------------------------------------------------------- -// Utilities -// -------------------------------------------------------------------------------------- - -let withDotnetExe = - // Build.cmd normally downloads a dotnet cli to: \artifacts\toolset\dotnet - // check if there is one there to avoid downloading an additional one here - let pathToCli = Path.Combine(__SOURCE_DIRECTORY__, @"..\artifacts\toolset\dotnet\dotnet.exe") - if File.Exists(pathToCli) then - (fun opts -> { opts with DotNet.Options.DotNetCliPath = pathToCli }) - else - DotNet.install (fun cliOpts -> { cliOpts with Version = DotNet.CliVersion.GlobalJson }) - -let runDotnet workingDir command args = - let result = DotNet.exec (DotNet.Options.withWorkingDirectory workingDir >> withDotnetExe) command args - - if result.ExitCode <> 0 then failwithf "dotnet %s failed with errors: %s" args (result.Errors |> String.concat "\n") - -// -------------------------------------------------------------------------------------- -// The rest of the code is standard F# build script -// -------------------------------------------------------------------------------------- - -let releaseDir = Path.Combine(__SOURCE_DIRECTORY__, "../artifacts/bin/fcs/Release") - -// Read release notes & version info from RELEASE_NOTES.md -let release = ReleaseNotes.load (__SOURCE_DIRECTORY__ + "/RELEASE_NOTES.md") -let isAppVeyorBuild = AppVeyor.detect() -let isVersionTag (tag: string) = Version.TryParse tag |> fst -let hasRepoVersionTag = isAppVeyorBuild && AppVeyor.Environment.RepoTag && isVersionTag AppVeyor.Environment.RepoTagName -let assemblyVersion = if hasRepoVersionTag then AppVeyor.Environment.RepoTagName else release.NugetVersion - -let buildVersion = - if hasRepoVersionTag then assemblyVersion - else if isAppVeyorBuild then sprintf "%s-b%s" assemblyVersion AppVeyor.Environment.BuildNumber - else assemblyVersion - -Target.create "Clean" (fun _ -> - Shell.cleanDir releaseDir -) - -Target.create "Restore" (fun _ -> - // We assume a paket restore has already been run - runDotnet __SOURCE_DIRECTORY__ "restore" "../src/buildtools/buildtools.proj -v n" - runDotnet __SOURCE_DIRECTORY__ "restore" "FSharp.Compiler.Service.sln -v n" -) - -Target.create "BuildVersion" (fun _ -> - Shell.Exec("appveyor", sprintf "UpdateBuild -Version \"%s\"" buildVersion) |> ignore -) - -Target.create "Build" (fun _ -> - runDotnet __SOURCE_DIRECTORY__ "build" "../src/buildtools/buildtools.proj -v n -c Proto" - let fslexPath = __SOURCE_DIRECTORY__ + "/../artifacts/bin/fslex/Proto/netcoreapp3.0/fslex.dll" - let fsyaccPath = __SOURCE_DIRECTORY__ + "/../artifacts/bin/fsyacc/Proto/netcoreapp3.0/fsyacc.dll" - runDotnet __SOURCE_DIRECTORY__ "build" (sprintf "FSharp.Compiler.Service.sln -nodereuse:false -v n -c Release /p:DisableCompilerRedirection=true /p:FsLexPath=%s /p:FsYaccPath=%s" fslexPath fsyaccPath) -) - -Target.create "Test" (fun _ -> - // This project file is used for the netcoreapp2.0 tests to work out reference sets - runDotnet __SOURCE_DIRECTORY__ "build" "../tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj -nodereuse:false -v n /restore /p:DisableCompilerRedirection=true" - - // Now run the tests - let logFilePath = Path.Combine(__SOURCE_DIRECTORY__, "..", "artifacts", "TestResults", "Release", "FSharp.Compiler.Service.Test.xml") - runDotnet __SOURCE_DIRECTORY__ "test" (sprintf "FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj --no-restore --no-build -nodereuse:false -v n -c Release --test-adapter-path . --logger \"nunit;LogFilePath=%s\"" logFilePath) -) - -Target.create "NuGet" (fun _ -> - DotNet.pack (fun packOpts -> - { packOpts with - Configuration = DotNet.BuildConfiguration.Release - Common = packOpts.Common |> withDotnetExe |> DotNet.Options.withVerbosity (Some DotNet.Verbosity.Normal) - MSBuildParams = { packOpts.MSBuildParams with - Properties = packOpts.MSBuildParams.Properties @ [ "Version", assemblyVersion ] } - }) "FSharp.Compiler.Service.sln" -) - -Target.create "GenerateDocsEn" (fun _ -> - runDotnet "docsrc/tools" "fake" "run generate.fsx" -) - -Target.create "GenerateDocsJa" (fun _ -> - runDotnet "docsrc/tools" "fake" "run generate.ja.fsx" -) - -Target.create "PublishNuGet" (fun _ -> - let apikey = Environment.environVarOrDefault "nuget-apikey" (UserInput.getUserPassword "Nuget API Key: ") - Paket.push (fun p -> - { p with - ApiKey = apikey - WorkingDir = releaseDir }) -) - -// -------------------------------------------------------------------------------------- -// Run all targets by default. Invoke 'build ' to override - -Target.create "Start" ignore -Target.create "Release" ignore -Target.create "GenerateDocs" ignore -Target.create "TestAndNuGet" ignore - -open Fake.Core.TargetOperators - -"Start" - =?> ("BuildVersion", isAppVeyorBuild) - ==> "Restore" - ==> "Build" - -"Build" - ==> "Test" - -"Build" - ==> "NuGet" - -"Test" - ==> "TestAndNuGet" - -"NuGet" - ==> "TestAndNuGet" - -"Build" - ==> "NuGet" - ==> "PublishNuGet" - ==> "Release" - -"Build" - // ==> "GenerateDocsEn" - ==> "GenerateDocs" - -"Build" - // ==> "GenerateDocsJa" - ==> "GenerateDocs" - -"GenerateDocs" - ==> "Release" - -Target.runOrDefaultWithArguments "Build" diff --git a/fcs/build.sh b/fcs/build.sh deleted file mode 100755 index 4c4819aca7c..00000000000 --- a/fcs/build.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# bail out as soon as any single command errors -set -e - -start_pwd=$PWD - -# dotnet tools look in certain paths by default that Just Work when we're in the fcs dir, -# so let's force that here: -cd $(dirname ${BASH_SOURCE[0]}) - -dotnet tool restore -dotnet paket restore -dotnet fake build -t $@ - -# but we'll be nice and go back to the start dir at the end -cd $start_pwd \ No newline at end of file diff --git a/fcs/dependencies/MSBuild.v12.0/.gitignore b/fcs/dependencies/MSBuild.v12.0/.gitignore deleted file mode 100644 index 6a7461313bb..00000000000 --- a/fcs/dependencies/MSBuild.v12.0/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.dll diff --git a/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.csproj b/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.csproj deleted file mode 100644 index b59e15cd058..00000000000 --- a/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - net45 - MSBuild.v12.0.nuspec - - - - - diff --git a/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.nuspec b/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.nuspec deleted file mode 100644 index e3047f0a962..00000000000 --- a/fcs/dependencies/MSBuild.v12.0/MSBuild.v12.0.nuspec +++ /dev/null @@ -1,20 +0,0 @@ - - - - FSharp.Compiler.Service.MSBuild.v12.0 - 1.0 - Microsoft and F# Software Foundation - MSBuild.v12.0 dependencies for fcs. - - - - - - - - - - - - - diff --git a/fcs/dependencies/MSBuild.v12.0/README.md b/fcs/dependencies/MSBuild.v12.0/README.md deleted file mode 100644 index 6fe2cf4f3b1..00000000000 --- a/fcs/dependencies/MSBuild.v12.0/README.md +++ /dev/null @@ -1,9 +0,0 @@ -The MSBuild.12.0 dependencies have been converted to a NuGet package. - -To create an updated version of the package: - -1. Copy the appropriate `Microsoft.Build.*.dll` files to this directory. -2. Update the `` element of `MSBuild.v12.0.nuspec`. -3. Run `msbuild MSBuild.v12.0.csproj /t:Pack` -4. Upload `\artifacts\bin\fcs\FSharp.Compiler.Service.MSBuild.v12.0.*.nupkg` to the MyGet feed at - `https://dotnet.myget.org/F/fsharp/api/v3/index.json` diff --git a/fcs/docsrc/content/compiler.fsx b/fcs/docsrc/content/compiler.fsx deleted file mode 100644 index a7e5303a06b..00000000000 --- a/fcs/docsrc/content/compiler.fsx +++ /dev/null @@ -1,100 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Hosted Compiler -=============== - -This tutorial demonstrates how to host the F# compiler. - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published -*) - -(** -> **NOTE:** There are several options for hosting the F# compiler. The easiest one is to use the -`fsc.exe` process and pass arguments. -*) - -(** - -> **NOTE:** By default [compilations using FSharp.Compiler.Service reference FSharp.Core 4.3.0.0](https://github.com/fsharp/FSharp.Compiler.Service/issues/156) (matching F# 3.0). You can override -this choice by passing a reference to FSharp.Core for 4.3.1.0 or later explicitly in your command-line arguments. - -*) - -(** ---------------------------- - -First, we need to reference the libraries that contain F# interactive service: -*) - -#r "FSharp.Compiler.Service.dll" -open System.IO -open FSharp.Compiler.SourceCodeServices - -// Create an interactive checker instance -let checker = FSharpChecker.Create() - -(** -Now write content to a temporary file: - -*) -let fn = Path.GetTempFileName() -let fn2 = Path.ChangeExtension(fn, ".fsx") -let fn3 = Path.ChangeExtension(fn, ".dll") - -File.WriteAllText(fn2, """ -module M - -type C() = - member x.P = 1 - -let x = 3 + 4 -""") - -(** -Now invoke the compiler: -*) - -let errors1, exitCode1 = - checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) - |> Async.RunSynchronously - -(** - -If errors occur you can see this in the 'exitCode' and the returned array of errors: - -*) -File.WriteAllText(fn2, """ -module M - -let x = 1.0 + "" // a type error -""") - -let errors1b, exitCode1b = - checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) - |> Async.RunSynchronously - -(** - -Compiling to a dynamic assembly -=============================== - -You can also compile to a dynamic assembly, which uses the F# Interactive code generator. -This can be useful if you are, for example, in a situation where writing to the file system -is not really an option. - -You still have to pass the "-o" option to name the output file, but the output file is not actually written to disk. - -The 'None' option indicates that the initialization code for the assembly is not executed. -*) -let errors2, exitCode2, dynAssembly2 = - checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None) - |> Async.RunSynchronously - -(* -Passing 'Some' for the 'execute' parameter executes the initialization code for the assembly. -*) -let errors3, exitCode3, dynAssembly3 = - checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr)) - |> Async.RunSynchronously - diff --git a/fcs/docsrc/content/corelib.fsx b/fcs/docsrc/content/corelib.fsx deleted file mode 100644 index a0c1e85f029..00000000000 --- a/fcs/docsrc/content/corelib.fsx +++ /dev/null @@ -1,96 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Notes on FSharp.Core.dll -================================================= - -Shipping an FSharp.Core with your application ---------------------------------------------- - -When building applications or plug-in components which use FSharp.Compiler.Service.dll, you will normally also -include a copy of FSharp.Core.dll as part of your application. - -For example, if you build a ``HostedCompiler.exe``, you will normally place an FSharp.Core.dll (say 4.3.1.0) alongside -your ``HostedCompiler.exe``. - -Binding redirects for your application --------------------------------------- - -The FSharp.Compiler.Service.dll component depends on FSharp.Core 4.4.0.0. Normally your application will target -a later version of FSharp.Core, and you may need a [binding redirect](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions) to ensure -that other versions of FSharp.Core forward to the final version of FSharp.Core.dll your application uses. -Binding redirect files are normally generated automatically by build tools. If not, you can use one like this -(if your tool is called ``HostedCompiler.exe``, the binding redirect file is called ``HostedCompiler.exe.config``) - -Some other dependencies may also need to be reconciled and forwarded. - - - - - - - - - - - - - - - - - -Which FSharp.Core and .NET Framework gets referenced in compilation? --------------------------------------- - -The FSharp.Compiler.Service component can be used to do more or less any sort of F# compilation. -In particular you can reference an explicit FSharp.Core and/or framework -assemblies in the command line arguments (different to the FSharp.Core and a .NET Framework being used to run your tool). - -To target a specific FSharp.Core and/or .NET Framework assemblies, use the ``--noframework`` argument -and the appropriate command-line arguments: - - [] - let fsharpCorePath = - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll" - let errors2, exitCode2 = - scs.Compile( - [| "fsc.exe"; "--noframework"; - "-r"; fsharpCorePath; - "-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"; - "-o"; fn3; - "-a"; fn2 |]) - -You will need to determine the location of these assemblies. The easiest way to locate these DLLs in a cross-platform way and -convert them to command-line arguments is to [crack an F# project file](https://fsharp.github.io/FSharp.Compiler.Service/project.html). -Alternatively you can compute SDK paths yourself, and some helpers to do this are in [the tests for FSharp.Compiler.Service.dll](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54). - - -What about if I am processing a script or using ``GetCheckOptionsFromScriptRoot`` -------------------------------------------------------------------------- - -If you do _not_ explicitly reference an FSharp.Core.dll from an SDK location, or if you are processing a script -using ``FsiEvaluationSession`` or ``GetCheckOptionsFromScriptRoot``, then an implicit reference to FSharp.Core will be made -by the following choice: - -1. The version of FSharp.Core.dll statically referenced by the host assembly returned by ``System.Reflection.Assembly.GetEntryAssembly()``. - -2. If there is no static reference to FSharp.Core in the host assembly, then - - - For FSharp.Compiler.Service 1.4.0.x above (F# 4.0 series), a reference to FSharp.Core version 4.4.0.0 is added - -Do I need to include FSharp.Core.optdata and FSharp.Core.sigdata? --------------------------------------- - -No, unless you are doing something with very old FSharp.Core.dll. - -Summary -------- - -In this design note we have discussed three things: - -- which FSharp.Core.dll is used to run your compilation tools -- how to configure binding redirects for the FSharp.Core.dll used to run your compilation tools -- which FSharp.Core.dll and/or framework assemblies are referenced during the checking and compilations performed by your tools. - -*) diff --git a/fcs/docsrc/content/editor.fsx b/fcs/docsrc/content/editor.fsx deleted file mode 100644 index 46ddd882e58..00000000000 --- a/fcs/docsrc/content/editor.fsx +++ /dev/null @@ -1,254 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Editor services -================================== - -This tutorial demonstrates how to use the editor services provided by the F# compiler. -This API is used to provide auto-complete, tool-tips, parameter info help, matching of -brackets and other functions in F# editors including Visual Studio, Xamarin Studio and Emacs -(see [fsharpbindings](https://github.com/fsharp/fsharpbinding) project for more information). -Similarly to [the tutorial on using untyped AST](untypedtree.html), we start by -getting the `InteractiveChecker` object. - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published - - -Type checking sample source code --------------------------------- - -As in the [previous tutorial (using untyped AST)](untypedtree.html), we start by referencing -`FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance -of `InteractiveChecker`: - -*) -// Reference F# compiler API -#r "FSharp.Compiler.Service.dll" - -open System -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text - -// Create an interactive checker instance -let checker = FSharpChecker.Create() - -(** - -As [previously](untypedtree.html), we use `GetProjectOptionsFromScriptRoot` to get a context -where the specified input is the only file passed to the compiler (and it is treated as a -script file or stand-alone F# source code). - -*) -// Sample input as a multi-line string -let input = - """ - open System - - let foo() = - let msg = String.Concat("Hello"," ","world") - if true then - printfn "%s" msg. - """ -// Split the input & define file name -let inputLines = input.Split('\n') -let file = "/home/user/Test.fsx" - -let projOptions, errors = - checker.GetProjectOptionsFromScript(file, SourceText.ofString input) - |> Async.RunSynchronously - -let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) - -(** -To perform type checking, we first need to parse the input using -`ParseFile`, which gives us access to the [untyped AST](untypedtree.html). However, -then we need to call `CheckFileInProject` to perform the full type checking. This function -also requires the result of `ParseFileInProject`, so the two functions are often called -together. -*) -// Perform parsing - -let parseFileResults = - checker.ParseFile(file, SourceText.ofString input, parsingOptions) - |> Async.RunSynchronously -(** -Before we look at the interesting operations provided by `TypeCheckResults`, we -need to run the type checker on a sample input. On F# code with errors, you would get some type checking -result (but it may contain incorrectly "guessed" results). -*) - -// Perform type checking -let checkFileAnswer = - checker.CheckFileInProject(parseFileResults, file, 0, SourceText.ofString input, projOptions) - |> Async.RunSynchronously - -(** -Alternatively you can use `ParseAndCheckFileInProject` to check both in one step: -*) - -let parseResults2, checkFileAnswer2 = - checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString input, projOptions) - |> Async.RunSynchronously - -(** - -The function returns both the untyped parse result (which we do not use in this -tutorial), but also a `CheckFileAnswer` value, which gives us access to all -the interesting functionality... -*) - -let checkFileResults = - match checkFileAnswer with - | FSharpCheckFileAnswer.Succeeded(res) -> res - | res -> failwithf "Parsing did not finish... (%A)" res - -(** - -Here, we type check a simple function that (conditionally) prints "Hello world". -On the last line, we leave an additional dot in `msg.` so that we can get the -completion list on the `msg` value (we expect to see various methods on the string -type there). - - -Using type checking results ---------------------------- - -Let's now look at some of the API that is exposed by the `TypeCheckResults` type. In general, -this is the type that lets you implement most of the interesting F# source code editor services. - -### Getting a tool tip - -To get a tool tip, you can use `GetToolTipTextAlternate` method. The method takes a line number and character -offset. Both of the numbers are zero-based. In the sample code, we want to get tooltip for the `foo` -function that is defined on line 3 (line 0 is blank) and the letter `f` starts at index 7 (the tooltip -would work anywhere inside the identifier). - -In addition, the method takes a tag of token which is typically `IDENT`, when getting tooltip for an -identifier (the other option lets you get tooltip with full assembly location when using `#r "..."`). - -*) -// Get tag of the IDENT token to be used as the last argument -open FSharp.Compiler -let identToken = FSharpTokenTag.Identifier - -// Get tool tip at the specified location -let tip = checkFileResults.GetToolTipText(4, 7, inputLines.[1], ["foo"], identToken) -printfn "%A" tip - -(** - -> **NOTE:** `GetToolTipTextAlternate` is an alternative name for the old `GetToolTipText`. The old `GetToolTipText` was -deprecated because it accepted zero-based line numbers. At some point it will be removed, and `GetToolTipTextAlternate` will be renamed back to `GetToolTipText`. -*) - -(** -Aside from the location and token kind, the function also requires the current contents of the line -(useful when the source code changes) and a `Names` value, which is a list of strings representing -the current long name. For example to get tooltip for the `Random` identifier in a long name -`System.Random`, you would use location somewhere in the string `Random` and you would pass -`["System"; "Random"]` as the `Names` value. - -The returned value is of type `ToolTipText` which contains a discriminated union `ToolTipElement`. -The union represents different kinds of tool tips that you can get from the compiler. - -### Getting auto-complete lists - -The next method exposed by `TypeCheckResults` lets us perform auto-complete on a given location. -This can be called on any identifier or in any scope (in which case you get a list of names visible -in the scope) or immediately after `.` to get a list of members of some object. Here, we get a -list of members of the string value `msg`. - -To do this, we call `GetDeclarationListInfo` with the location of the `.` symbol on the last line -(ending with `printfn "%s" msg.`). The offsets are one-based, so the location is `7, 23`. -We also need to specify a function that says that the text has not changed and the current identifier -where we need to perform the completion. -*) -// Get declarations (autocomplete) for a location -let decls = - checkFileResults.GetDeclarationListInfo - (Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun () -> []), fun _ -> false) - |> Async.RunSynchronously - -// Print the names of available items -for item in decls.Items do - printfn " - %s" item.Name - -(** - -> **NOTE:** `v` is an alternative name for the old `GetDeclarations`. The old `GetDeclarations` was -deprecated because it accepted zero-based line numbers. At some point it will be removed, and `GetDeclarationListInfo` will be renamed back to `GetDeclarations`. -*) - -(** -When you run the code, you should get a list containing the usual string methods such as -`Substring`, `ToUpper`, `ToLower` etc. The fourth argument of `GetDeclarations`, here `([], "msg")`, -specifies the context for the auto-completion. Here, we want a completion on a complete name -`msg`, but you could for example use `(["System"; "Collections"], "Generic")` to get a completion list -for a fully qualified namespace. - -### Getting parameter information - -The next common feature of editors is to provide information about overloads of a method. In our -sample code, we use `String.Concat` which has a number of overloads. We can get the list using -`GetMethods` operation. As previously, this takes zero-indexed offset of the location that we are -interested in (here, right at the end of the `String.Concat` identifier) and we also need to provide -the identifier again (so that the compiler can provide up-to-date information when the source code -changes): - -*) -// Get overloads of the String.Concat method -let methods = - checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) - |> Async.RunSynchronously - -// Print concatenated parameter lists -for mi in methods.Methods do - [ for p in mi.Parameters -> p.Display ] - |> String.concat ", " - |> printfn "%s(%s)" methods.MethodName -(** -The code uses the `Display` property to get the annotation for each parameter. This returns information -such as `arg0: obj` or `params args: obj[]` or `str0: string, str1: string`. We concatenate the parameters -and print a type annotation with the method name. -*) - -(** - -## Asynchronous and immediate operations - -You may have noticed that `CheckFileInProject` is an asynchronous operation. -This indicates that type checking of F# code can take some time. -The F# compiler performs the work in background (automatically) and when -we call `CheckFileInProject` method, it returns an asynchronous operation. - -There is also the `CheckFileInProjectIfReady` method. This returns immediately if the -type checking operation can't be started immediately, e.g. if other files in the project -are not yet type-checked. In this case, a background worker might choose to do other -work in the meantime, or give up on type checking the file until the `FileTypeCheckStateIsDirty` event -is raised. - -> The [fsharpbinding](https://github.com/fsharp/fsharpbinding) project has more advanced -example of handling the background work where all requests are sent through an F# agent. -This may be a more appropriate for implementing editor support. - -*) - - -(** -Summary -------- - -The `CheckFileAnswer` object contains other useful methods that were not covered in this tutorial. You -can use it to get location of a declaration for a given identifier, additional colorization information -(the F# 3.1 colorizes computation builder identifiers & query operators) and others. - -Using the FSharpChecker component in multi-project, incremental and interactive editing situations may involve -knowledge of the [FSharpChecker operations queue](queue.html) and the [FSharpChecker caches](caches.html). - - -Finally, if you are implementing an editor support for an editor that cannot directly call .NET API, -you can call many of the methods discussed here via a command line interface that is available in the -[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete) project. - - -*) diff --git a/fcs/docsrc/content/filesystem.fsx b/fcs/docsrc/content/filesystem.fsx deleted file mode 100644 index ad0a57712b9..00000000000 --- a/fcs/docsrc/content/filesystem.fsx +++ /dev/null @@ -1,190 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Virtualized File System -========================================== - -The `FSharp.Compiler.Service` component has a global variable -representing the file system. By setting this variable you can host the compiler in situations where a file system -is not available. - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. - - -Setting the FileSystem ----------------------- - -In the example below, we set the file system to an implementation which reads from disk -*) -#r "FSharp.Compiler.Service.dll" -open System -open System.IO -open System.Collections.Generic -open System.Text -open FSharp.Compiler.AbstractIL.Internal.Library - -let defaultFileSystem = Shim.FileSystem - -let fileName1 = @"c:\mycode\test1.fs" // note, the path doesn't exist -let fileName2 = @"c:\mycode\test2.fs" // note, the path doesn't exist - -type MyFileSystem() = - let file1 = """ -module File1 - -let A = 1""" - let file2 = """ -module File2 -let B = File1.A + File1.A""" - let files = dict [(fileName1, file1); (fileName2, file2)] - - interface IFileSystem with - // Implement the service to open files for reading and writing - member __.FileStreamReadShim(fileName) = - match files.TryGetValue fileName with - | true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream - | _ -> defaultFileSystem.FileStreamReadShim(fileName) - - member __.FileStreamCreateShim(fileName) = - defaultFileSystem.FileStreamCreateShim(fileName) - - member __.FileStreamWriteExistingShim(fileName) = - defaultFileSystem.FileStreamWriteExistingShim(fileName) - - member __.ReadAllBytesShim(fileName) = - match files.TryGetValue fileName with - | true, text -> Encoding.UTF8.GetBytes(text) - | _ -> defaultFileSystem.ReadAllBytesShim(fileName) - - // Implement the service related to temporary paths and file time stamps - member __.GetTempPathShim() = - defaultFileSystem.GetTempPathShim() - - member __.GetLastWriteTimeShim(fileName) = - defaultFileSystem.GetLastWriteTimeShim(fileName) - - member __.GetFullPathShim(fileName) = - defaultFileSystem.GetFullPathShim(fileName) - - member __.IsInvalidPathShim(fileName) = - defaultFileSystem.IsInvalidPathShim(fileName) - - member __.IsPathRootedShim(fileName) = - defaultFileSystem.IsPathRootedShim(fileName) - - member __.IsStableFileHeuristic(fileName) = - defaultFileSystem.IsStableFileHeuristic(fileName) - - // Implement the service related to file existence and deletion - member __.SafeExists(fileName) = - files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName) - - member __.FileDelete(fileName) = - defaultFileSystem.FileDelete(fileName) - - // Implement the service related to assembly loading, used to load type providers - // and for F# interactive. - member __.AssemblyLoadFrom(fileName) = - defaultFileSystem.AssemblyLoadFrom fileName - - member __.AssemblyLoad(assemblyName) = - defaultFileSystem.AssemblyLoad assemblyName - -let myFileSystem = MyFileSystem() -Shim.FileSystem <- MyFileSystem() - -(** - -Doing a compilation with the FileSystem ---------------------------------------- - -*) -open FSharp.Compiler.SourceCodeServices - -let checker = FSharpChecker.Create() - -let projectOptions = - let sysLib nm = - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows - System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + - @"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" + nm + ".dll" - else - let sysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() - let (++) a b = System.IO.Path.Combine(a,b) - sysDir ++ nm + ".dll" - - let fsCore4300() = - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows - System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + - @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll" - else - sysLib "FSharp.Core" - - let allFlags = - [| yield "--simpleresolution"; - yield "--noframework"; - yield "--debug:full"; - yield "--define:DEBUG"; - yield "--optimize-"; - yield "--doc:test.xml"; - yield "--warn:3"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:library"; - let references = - [ sysLib "mscorlib" - sysLib "System" - sysLib "System.Core" - fsCore4300() ] - for r in references do - yield "-r:" + r |] - - { ProjectFileName = @"c:\mycode\compilation.fsproj" // Make a name that is unique in this directory. - ProjectId = None - SourceFiles = [| fileName1; fileName2 |] - OriginalLoadReferences = [] - ExtraProjectInfo=None - Stamp = None - OtherOptions = allFlags - ReferencedProjects = [| |] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = true - LoadTime = System.DateTime.Now // Note using 'Now' forces reloading - UnresolvedReferences = None } - -let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously - -results.Errors -results.AssemblySignature.Entities.Count //2 -results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1 -results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B" - -(** -Summary -------- -In this tutorial, we've seen how to globally customize the view of the file system used by the FSharp.Compiler.Service -component. - -At the time of writing, the following System.IO operations are not considered part of the virtualized file system API. -Future iterations on the compiler service implementation may add these to the API. - - - Path.Combine - - Path.DirectorySeparatorChar - - Path.GetDirectoryName - - Path.GetFileName - - Path.GetFileNameWithoutExtension - - Path.HasExtension - - Path.GetRandomFileName (used only in generation compiled win32 resources in assemblies) - -**NOTE:** Several operations in the `SourceCodeServices` API accept the contents of a file to parse -or check as a parameter, in addition to a file name. In these cases, the file name is only used for -error reporting. - -**NOTE:** Type provider components do not use the virtualized file system. - -**NOTE:** The compiler service may use MSBuild for assembly resolutions unless `--simpleresolution` is -provided. When using the `FileSystem` API you will normally want to specify `--simpleresolution` as one -of your compiler flags. Also specify `--noframework`. You will need to supply explicit resolutions of all -referenced .NET assemblies. - -*) \ No newline at end of file diff --git a/fcs/docsrc/content/interactive.fsx b/fcs/docsrc/content/interactive.fsx deleted file mode 100644 index 6226bcbee16..00000000000 --- a/fcs/docsrc/content/interactive.fsx +++ /dev/null @@ -1,279 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Interactive Service: Embedding F# Interactive -============================================= - -This tutorial demonstrates how to embed F# interactive in your application. F# interactive -is an interactive scripting environment that compiles F# code into highly efficient IL code -and executes it on the fly. The F# interactive service allows you to embed F# evaluation in -your application. - -> **NOTE:** There is a number of options for embedding F# Interactive. The easiest one is to use the -`fsi.exe` process and communicate with it using standard input and standard output. In this -tutorial, we look at calling F# Interactive directly through .NET API. However, if you have -no control over the input, it is a good idea to run F# interactive in a separate process. -One reason is that there is no way to handle `StackOverflowException` and so a poorly written -script can terminate the host process. **Remember that while calling F# Interactive through .NET API, -` --shadowcopyreferences` option will be ignored**. For detailed discussion, please take a look at -[this thread](https://github.com/fsharp/FSharp.Compiler.Service/issues/292). -> **NOTE:** If `FsiEvaluationSession.Create` fails with an error saying that `FSharp.Core.dll` cannot be found, -add the `FSharp.Core.sigdata` and `FSharp.Core.optdata` files. More info [here](https://fsharp.github.io/FSharp.Compiler.Service/corelib.html). - -However, the F# interactive service is still useful, because you might want to wrap it in your -own executable that is then executed (and communicates with the rest of your application), or -if you only need to execute limited subset of F# code (e.g. generated by your own DSL). - -Starting the F# interactive ---------------------------- - -First, we need to reference the libraries that contain F# interactive service: -*) - -#r "FSharp.Compiler.Service.dll" -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Interactive.Shell - -(** -To communicate with F# interactive, we need to create streams that represent input and -output. We will use those later to read the output printed as a result of evaluating some -F# code that prints: -*) -open System -open System.IO -open System.Text - -// Initialize output and input streams -let sbOut = new StringBuilder() -let sbErr = new StringBuilder() -let inStream = new StringReader("") -let outStream = new StringWriter(sbOut) -let errStream = new StringWriter(sbErr) - -// Build command line arguments & start FSI session -let argv = [| "C:\\fsi.exe" |] -let allArgs = Array.append argv [|"--noninteractive"|] - -let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() -let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream) - - - -(** -Evaluating and executing code ------------------------------ - -The F# interactive service exposes several methods that can be used for evaluation. The first -is `EvalExpression` which evaluates an expression and returns its result. The result contains -the returned value (as `obj`) and the statically inferred type of the value: -*) -/// Evaluate expression & return the result -let evalExpression text = - match fsiSession.EvalExpression(text) with - | Some value -> printfn "%A" value.ReflectionValue - | None -> printfn "Got no result!" - -(** -This takes a string as an argument and evaluates (i.e. executes) it as F# code. -*) -evalExpression "42+1" // prints '43' - -(** -This can be used in a strongly typed way as follows: -*) - -/// Evaluate expression & return the result, strongly typed -let evalExpressionTyped<'T> (text) = - match fsiSession.EvalExpression(text) with - | Some value -> value.ReflectionValue |> unbox<'T> - | None -> failwith "Got no result!" - -evalExpressionTyped "42+1" // gives '43' - - -(** -The `EvalInteraction` method can be used to evaluate side-effectful operations -such as printing, declarations, or other interactions that are not valid F# expressions, but can be entered in -the F# Interactive console. Such commands include `#time "on"` (and other directives), `open System` -all declarations and other top-level statements. The code -does not require `;;` at the end. Just enter the code that you want to execute: -*) -fsiSession.EvalInteraction "printfn \"bye\"" - - -(** -The `EvalScript` method allows to evaluate a complete .fsx script. -*) - -File.WriteAllText("sample.fsx", "let twenty = 10 + 10") -fsiSession.EvalScript "sample.fsx" - -(** -Catching errors ------------------- - -``EvalExpression``, ``EvalInteraction`` and ``EvalScript`` are awkward if the -code has type checking warnings or errors, or if evaluation fails with an exception. -In these cases you can use ``EvalExpressionNonThrowing``, ``EvalInteractionNonThrowing`` -and ``EvalScriptNonThrowing``. These return a tuple of a result and an array of ``FSharpErrorInfo`` values. -These represent the errors and warnings. The result part is a ``Choice<_,_>`` between an actual -result and an exception. - -The result part of ``EvalExpression`` and ``EvalExpressionNonThrowing`` is an optional ``FSharpValue``. -If that value is not present then it just indicates that the expression didn't have a tangible -result that could be represented as a .NET object. This situation shouldn't actually -occur for any normal input expressions, and only for primitives used in libraries. -*) - -File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0") -let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx" - -// show the result -match result with -| Choice1Of2 () -> printfn "checked and executed ok" -| Choice2Of2 exn -> printfn "execution exception: %s" exn.Message - - -(** -Gives: - - execution exception: Operation could not be completed due to earlier error -*) - -// show the errors and warnings -for w in warnings do - printfn "Warning %s at %d,%d" w.Message w.StartLineAlternate w.StartColumn - -(** -Gives: - - Warning The type 'float' does not match the type 'char' at 1,19 - Warning The type 'float' does not match the type 'char' at 1,17 - -For expressions: -*) - - -let evalExpressionTyped2<'T> text = - let res, warnings = fsiSession.EvalExpressionNonThrowing(text) - for w in warnings do - printfn "Warning %s at %d,%d" w.Message w.StartLineAlternate w.StartColumn - match res with - | Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T> - | Choice1Of2 None -> failwith "null or no result" - | Choice2Of2 (exn:exn) -> failwith (sprintf "exception %s" exn.Message) - -evalExpressionTyped2 "42+1" // gives '43' - - -(** -Executing in parallel ------------------- - -By default the code passed to ``EvalExpression`` is executed immediately. To execute in parallel, submit a computation that starts a task: -*) - -open System.Threading.Tasks - -let sampleLongRunningExpr = - """ -async { - // The code of what you want to run - do System.Threading.Thread.Sleep 5000 - return 10 -} - |> Async.StartAsTask""" - -let task1 = evalExpressionTyped>(sampleLongRunningExpr) -let task2 = evalExpressionTyped>(sampleLongRunningExpr) - -(** -Both computations have now started. You can now fetch the results: -*) - - -task1.Result // gives the result after completion (up to 5 seconds) -task2.Result // gives the result after completion (up to 5 seconds) - -(** -Type checking in the evaluation context ------------------- - -Let's assume you have a situation where you would like to typecheck code -in the context of the F# Interactive scripting session. For example, you first -evaluation a declaration: -*) - -fsiSession.EvalInteraction "let xxx = 1 + 1" - -(** - -Now you want to typecheck the partially complete code `xxx + xx` -*) - -let parseResults, checkResults, checkProjectResults = - fsiSession.ParseAndCheckInteraction("xxx + xx") - |> Async.RunSynchronously - -(** -The `parseResults` and `checkResults` have types `ParseFileResults` and `CheckFileResults` -explained in [Editor](editor.html). You can, for example, look at the type errors in the code: -*) -checkResults.Errors.Length // 1 - -(** -The code is checked with respect to the logical type context available in the F# interactive session -based on the declarations executed so far. - -You can also request declaration list information, tooltip text and symbol resolution: -*) -open FSharp.Compiler - -// get a tooltip -checkResults.GetToolTipText(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT) - -checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // symbol xxx - -(** -The 'fsi' object ------------------- - -If you want your scripting code to be able to access the 'fsi' object, you should pass in an implementation of this object explicitly. -Normally the one from FSharp.Compiler.Interactive.Settings.dll is used. -*) - -let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsiSession) - -(** -Collectible code generation ------------------- - -Evaluating code in using FsiEvaluationSession generates a .NET dynamic assembly and uses other resources. -You can make generated code collectible by passing `collectible=true`. However code will only -be collected if there are no outstanding object references involving types, for example -`FsiValue` objects returned by `EvalExpression`, and you must have disposed the `FsiEvaluationSession`. -See also [Restrictions on Collectible Assemblies](https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/dd554932(v=vs.100)#restrictions). - -The example below shows the creation of 200 evaluation sessions. Note that `collectible=true` and -`use session = ...` are both used. - -If collectible code is working correctly, -overall resource usage will not increase linearly as the evaluation progresses. -*) - -let collectionTest() = - - for i in 1 .. 200 do - let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|] - use inStream = new StringReader("") - use outStream = new StringWriter() - use errStream = new StringWriter() - - let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() - use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true) - - session.EvalInteraction (sprintf "type D = { v : int }") - let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i) - printfn "iteration %d, result = %A" i v.Value.ReflectionValue - -// collectionTest() <-- run the test like this diff --git a/fcs/docsrc/content/ja/compiler.fsx b/fcs/docsrc/content/ja/compiler.fsx deleted file mode 100644 index 788c715294f..00000000000 --- a/fcs/docsrc/content/ja/compiler.fsx +++ /dev/null @@ -1,89 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラの組み込み -==================== - -このチュートリアルではF#コンパイラをホストする方法を紹介します。 - -> **注意:** 以下で使用しているAPIは実験的なもので、 - 新しいnugetパッケージの公開に伴って変更される可能性があります。 - -> **注意:** F#コンパイラをホストする方法はいくつかあります。 - 一番簡単な方法は `fsc.exe` のプロセスを使って引数を渡す方法です。 - ---------------------------- - -まず、F# Interactiveサービスを含むライブラリへの参照を追加します: -*) - -#r "FSharp.Compiler.Service.dll" -open FSharp.Compiler.SourceCodeServices -open System.IO - -let scs = FSharpChecker.Create() - -(** -次に、一時ファイルへコンテンツを書き込みます: - -*) -let fn = Path.GetTempFileName() -let fn2 = Path.ChangeExtension(fn, ".fs") -let fn3 = Path.ChangeExtension(fn, ".dll") - -File.WriteAllText(fn2, """ -module M - -type C() = - member x.P = 1 - -let x = 3 + 4 -""") - -(** -そしてコンパイラを呼び出します: -*) - -let errors1, exitCode1 = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously - -(** - -エラーが発生した場合は「終了コード」とエラーの配列から原因を特定できます: - -*) -File.WriteAllText(fn2, """ -module M - -let x = 1.0 + "" // a type error -""") - -let errors1b, exitCode1b = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously - -if exitCode1b <> 0 then - errors1b - |> Array.iter (printfn "%A") - -(** - -動的アセンブリへのコンパイル -============================ - -コードを動的アセンブリとしてコンパイルすることもできます。 -動的アセンブリはF# Interactiveコードジェネレータでも使用されています。 - -この機能はたとえばファイルシステムが必ずしも利用できないような状況で役に立ちます。 - -出力ファイルの名前を指定する "-o" オプションを指定することは可能ですが、 -実際には出力ファイルがディスク上に書き込まれることはありません。 - -'execute' 引数に 'None' を指定するとアセンブリ用の初期化コードが実行されません。 -*) -let errors2, exitCode2, dynAssembly2 = - scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None) |> Async.RunSynchronously - -(** -'Some' を指定するとアセンブリ用の初期化コードが実行されます。 -*) -let errors3, exitCode3, dynAssembly3 = - scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr)) |> Async.RunSynchronously - diff --git a/fcs/docsrc/content/ja/corelib.fsx b/fcs/docsrc/content/ja/corelib.fsx deleted file mode 100644 index ea9ee87f8fb..00000000000 --- a/fcs/docsrc/content/ja/corelib.fsx +++ /dev/null @@ -1,93 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス: FSharp.Core.dll についてのメモ -================================================== - -あなたのアプリケーションとともに FSharp.Core を配布する -------------------------------------------------------- - -FSharp.Compiler.Service.dll を利用するアプリケーションまたはプラグイン・コンポーネントをビルドする際、普通はアプリの一部として FSharp.Core.dll のコピーも含めることになるでしょう。 - -例えば、 ``HostedCompiler.exe`` をビルドする場合、普通はあなたの ``HostedCompiler.exe`` と同じフォルダに FSharp.Core.dll (例えば 4.3.1.0)を配置します。 - -動的コンパイルや動的実行を行う場合、FSharp.Core.optdata と FSharp.Core.sigdata も含める必要があるかもしれませんが、これらについては下記の指針をご覧ください。 - -あなたのアプリケーションにリダイレクトをバインドする ----------------------------------------------------- - -FSharp.Compiler.Service.dll コンポーネントは FSharp.Core 4.3.0.0 に依存しています。通例、あなたのアプリケーションはこれより後のバージョンの FSharp.Core をターゲットにしており、FSharp.Core 4.3.0.0 をあなたのアプリケーションで用いる FSharp.Core.dll の最終バージョンにちゃんと転送させるように[バインド リダイレクト](https://msdn.microsoft.com/ja-jp/library/7wd6ex19(v=vs.110).aspx)が必要になるでしょう。バインド リダイレクト ファイルは通常ビルドツールによって自動的に生成されます。そうでない場合、下記のようなファイル(あなたのツールが ``HostedCompiler.exe`` という名前で、バインド リダイレクト ファイルが ``HostedCompiler.exe.config`` という名前の場合)を使うことが出来ます。 - - - - - - - - - - - - - - - - - -どの FSharp.Core と .NET フレームワークがコンパイル時に参照される? --------------------------------------- - -FSharp.Combiler.Service コンポーネントは多かれ少なかれ、F#コードを コンパイルするために使われるに過ぎません。特に、コマンドライン引数(あなたのツールを実行するために使われる FSharp.Core や .NET フレームワークとは違います)に明示的に FSharp.Core および/またはフレームワークのアセンブリを参照することが出来ます。 - -特定の FSharp.Core および .NET フレームワーク アセンブリ、またはそのいずれかをターゲットにする場合、 ``--noframework`` 引数と適切なコマンドライン引数を使います: - - [] - let fsharpCorePath = - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll" - let errors2, exitCode2 = - scs.Compile( - [| "fsc.exe"; "--noframework"; - "-r"; fsharpCorePath; - "-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"; - "-o"; fn3; - "-a"; fn2 |]) - -これらのアセンブリが配置されている場所を指定する必要があります。クロスプラットフォームに対応した方法でDLL を配置して、それらをコマンドライン引数に変換する最も簡単な方法は、[F# プロジェクトファイルをクラックする](https://fsharp.github.io/FSharp.Compiler.Service/ja/project.html)ことです。 -自分で SDK のパスを処理する代わりに、[FSharp.Compiler.Service.dll 用のテスト](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54)で使用しているようなヘルパー関数も用意されています。 - - -スクリプトを処理しているか ``GetCheckOptionsFromScriptRoot`` を使っている場合 -------------------------------------------------------------------------- - -もし SDK 配置先にある FSharp.Core.dll を明示的に参照 *していない* 場合、または ``FsiEvaluationSession`` や ``GetCheckOptionsFromScriptRoot`` を使用してスクリプトを処理している場合、以下のいずれかの方法により、暗黙的にFSharp.Core が参照されます: - -1. ``System.Reflection.Assembly.GetEntryAssembly()`` によって返されるホストアセンブリから静的に参照されたFSharp.Core.dll のバージョン - -2. ホストアセンブリに FSharp.Core への静的な参照がない場合、 - - - FSharp.Compiler.Service 0.x シリーズでは、FSharp.Core バージョン 4.3.0.0 への参照が付与されます - - - FSharp.Compiler.Service 1.3.1.x (F# 3.1 シリーズ)では、FSharp.Core バージョン 4.3.1.0 への参照が付与されます - - - FSharp.Compiler.Service 1.4.0.x (F# 4.0 シリーズ)では、FSharp.Core バージョン 4.4.0.0 への参照が付与されます - -FSharp.Core.optdata と FSharp.Core.sigdata を含める必要はありますか? --------------------------------------- - -もしあなたのコンパイル引数が SDK 配置先にある FSharp.Core.dll を明示的に参照している場合、FSharp.Core.sigdata と FSharp.Core.optdata はその DLL と同じフォルダになければいけません(これらのファイルがインストールされていない場合、F# SDKの インストールに問題があります)。もしコンパイル引数で常に明示的に参照していたなら、FSharp.Core.optdata と FSharp.Core.sigdata はあなたのアプリケーションの一部として含める必要は *ありません* 。 - -もしあなたが暗黙的な参照(例えば、上記のスクリプト処理など)に頼っているのなら、これはあなたのツールがアプリケーションの一部として FSharp.Core.dll を参照しているかもしれない、ということです。この場合、FSharp.Core.optdata および FSharp.Core.sigdata が FSharp.Core.dll と同じフォルダに見つからないというエラーが発生するかもしれません。 **もしあなたがアプリケーションに含めている FSharp.Core.dll を暗黙的に参照したいのであれば、FSharp.Core.sigdata と FSharp.Core.optdata もアプリケーションに追加する2つのファイルとして追加しましょう。** ``CombileToDynamicAssembly`` を使用する場合、この問題によって[アセンブリ解決中のスタックオーバーフロー](https://github.com/fsharp/FSharp.Compiler.Service/issues/258)も引き起こされるでしょう。 - -動的コンパイルと動的コード実行を行うツール(例: ``HostedExecution.exe``)はしばしば FSharp.Core.dll を暗黙的に参照するようになっています。 -これはつまり通常 FSharp.Core.optdata と FSharp.Core.sigdata を含んでいるということです。 - -要約 -------- - -このデザインノートでは3つのポイントを検討しました: - -- どの FSharp.Core.dll があなたのコンパイルツールを実行するのに使われるか -- あなたのコンパイルツールを実行するのに使われる FSharp.Core.dll へのバインド リダイレクトを設定する方法 -- あなたのツールによって実行されるチェック時およびコンパイル時にどの FSharp.Core.dll および/またはフレームワークのアセンブリが参照されるか - -*) diff --git a/fcs/docsrc/content/ja/editor.fsx b/fcs/docsrc/content/ja/editor.fsx deleted file mode 100644 index f8a33e9a75a..00000000000 --- a/fcs/docsrc/content/ja/editor.fsx +++ /dev/null @@ -1,270 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス: エディタサービス -==================================== - -このチュートリアルはF#コンパイラによって公開されるエディタサービスの -使用方法についてのデモです。 -このAPIにより、Visual StudioやXamarin Studio、EmacsなどのF#エディタ内において、 -自動補完機能やツールチップ表示、引数情報のヘルプ表示、括弧の補完などの機能を -実装することができます -(詳細については [fsharpbindings](https://github.com/fsharp/fsharpbinding) のプロジェクトを参照してください)。 -[型無しASTを使用するチュートリアル](untypedtree.html) と同じく、 -今回も `FSharpChecker` オブジェクトを作成するところから始めます。 - -> **注意:** 以下で使用しているAPIは試験的なもので、最新バージョンのnugetパッケージの -公開に伴って変更されることがあります。 - -サンプルソースコードの型チェック --------------------------------- - -[前回の(型無しASTを使った)チュートリアル](untypedtree.html) と同じく、 -`FSharp.Compiler.Service.dll` への参照を追加した後に特定の名前空間をオープンし、 -`FSharpChecker` のインスタンスを作成します: - -*) -// F#コンパイラAPIを参照 -#r "FSharp.Compiler.Service.dll" - -open System -open FSharp.Compiler.SourceCodeServices - -// インタラクティブチェッカーのインスタンスを作成 -let checker = FSharpChecker.Create() - -(** - -[前回](untypedtree.html) 同様、 -コンパイラに渡されるファイルとしては特定の入力値だけであるという -コンテキストを想定するため、 `GetCheckOptionsFromScriptRoot` を使います -(この入力値はコンパイラによってスクリプトファイル、 -あるいはスタンドアロンのF#ソースコードとみなされます)。 - -*) -// サンプルの入力となる複数行文字列 -let input = - """ -open System - -let foo() = -let msg = String.Concat("Hello"," ","world") -if true then -printfn "%s" msg. -""" -// 入力値の分割とファイル名の定義 -let inputLines = input.Split('\n') -let file = "/home/user/Test.fsx" - -let projOptions, _errors1 = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously - -let parsingOptions, _errors2 = checker.GetParsingOptionsFromProjectOptions(projOptions) - -(** - -型チェックを実行するには、まず `ParseFile` を使って -入力値をパースする必要があります。 -このメソッドを使うと [型無しAST](untypedtree.html) にアクセスできるようになります。 -しかし今回は完全な型チェックを実行するため、続けて `CheckFileInProject` -を呼び出す必要があります。 -このメソッドは `ParseFile` の結果も必要とするため、 -たいていの場合にはこれら2つのメソッドをセットで呼び出すことになります。 - -*) -// パースを実行 -let parseFileResults = - checker.ParseFile(file, input, parsingOptions) - |> Async.RunSynchronously -(** -`TypeCheckResults` に備えられた興味深い機能の紹介に入る前に、 -サンプル入力に対して型チェッカーを実行する必要があります。 -F#コードにエラーがあった場合も何らかの型チェックの結果が返されます -(ただし間違って「推測された」結果が含まれることがあります)。 -*) - -// 型チェックを実行 -let checkFileAnswer = - checker.CheckFileInProject(parseFileResults, file, 0, input, projOptions) - |> Async.RunSynchronously - -(** -あるいは `ParseAndCheckFileInProject` を使用すれば1つの操作で両方のチェックを行うことができます: -*) - -let parseResults2, checkFileAnswer2 = - checker.ParseAndCheckFileInProject(file, 0, input, projOptions) - |> Async.RunSynchronously - -(** -この返り値は `CheckFileAnswer` 型で、この型に機能的に興味深いものが揃えられています... -*) - -let checkFileResults = - match checkFileAnswer with - | FSharpCheckFileAnswer.Succeeded(res) -> res - | res -> failwithf "パースが完了していません... (%A)" res - -(** - -今回は単に(状況に応じて)「Hello world」と表示するだけの -単純な関数の型をチェックしています。 -最終行では値 `msg` に対する補完リストを表示することができるように、 -`msg.` というようにドットを追加している点に注意してください -(今回の場合は文字列型に対する様々なメソッドが期待されます)。 - - -型チェックの結果を使用する --------------------------- - -では `TypeCheckResults` 型で公開されているAPIをいくつか見ていきましょう。 -一般的に、F#ソースコードエディタサービスの実装に必要な機能は -ほとんどこの型に備えられています。 - -### ツールチップの取得 - -ツールチップを取得するには `GetToolTipTextAlternate` メソッドを使用します。 -このメソッドには行数と文字オフセットを指定します。 -いずれも0から始まる数値です。 -サンプルコードでは3行目(0行目は空白行)、インデックス7にある文字 `f` から始まる関数 -`foo` のツールチップを取得しています -(ツールチップは識別子の中であれば任意の位置で機能します)。 - -またこのメソッドにはトークンタグを指定する必要もあります。 -トークンタグは一般的には `IDENT` を指定して、識別子に対する -ツールチップが取得できるようにします -(あるいは `#r "..."` を使用している場合にはアセンブリの完全パスを表示させるように -することもできるでしょう)。 - -*) -// 最後の引数に指定する、IDENTトークンのタグを取得 -open FSharp.Compiler - -// 特定の位置におけるツールチップを取得 -let tip = checkFileResults.GetToolTipText(4, 7, inputLines.[1], ["foo"], FSharpTokenTag.Identifier) -printfn "%A" tip - -(** - -> **注意:** `GetToolTipTextAlternate` は古い関数 `GetToolTipText` に代わるものです。 -`GetToolTipText` は0から始まる行番号を受け取るようになっていたため、非推奨になりました。 - -この関数には位置とトークンの種類の他にも、 -(ソースコードの変更時に役立つように)特定行の現在の内容と、 -現時点における完全修飾された `名前` を表す文字列のリストを指定する必要があります。 -たとえば完全修飾名 `System.Random` という名前を持った識別子 `Random` に対する -ツールチップを取得する場合、 `Random` という文字列が現れる場所の他に、 -`["System"; "Random"]` という値を指定する必要があります。 - -返り値の型は `ToolTipText` で、この型には `ToolTipElement` という -判別共用体が含まれます。 -この共用体は、コンパイラによって返されたツールチップの種類に応じて異なります。 - -### 自動補完リストの取得 - -次に紹介する `TypeCheckResults` のメソッドを使用すると、 -特定の位置における自動補完機能を実装できます。 -この機能は任意の識別子上、 -あるいは(特定のスコープ内で利用可能な名前の一覧を取得する場合には)任意のスコープ、 -あるいは特定のオブジェクトにおけるメンバーリストを取得する場合には -`.` の直後で呼び出すことができます。 -今回は文字列の値 `msg` に対するメンバーリストを取得することにします。 - -そのためには最終行( `printfn "%s" msg.` で終わっている行)にある -シンボル `.` の位置を指定して `GetDeclarationListInfo` を呼び出します。 -オフセットは1から始まるため、位置は `7, 23` になります。 -また、テキストが変更されていないことを表す関数と、 -現時点において補完する必要がある識別子を指定する必要もあります。 -*) -// 特定の位置における宣言(自動補完)を取得する -let decls = - checkFileResults.GetDeclarationListInfo - (Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun _ -> []), fun _ -> false) - |> Async.RunSynchronously - -// 利用可能な項目を表示 -for item in decls.Items do - printfn " - %s" item.Name -(** - -> **注意:** `GetDeclarationListInfo` は古い関数 `GetDeclarations` に代わるものです。 -`GetDeclarations` は0から始まる行番号を受け取るようになっていたため、非推奨になりました。 -また、将来的には現在の `GetDeclarations` が削除され、 `GetDeclarationListInfo` が -`GetDeclarations` になる予定です。 - -コードを実行してみると、 `Substring` や `ToUpper` 、 `ToLower` といった -文字列に対するいつものメソッドのリストが取得できていることでしょう。 -`GetDeclarations` の5,6番目の引数( `[]` および `"msg"` )には -自動補完用のコンテキストを指定します。 -今回の場合は完全名 `msg` に対する補完を行いましたが、 -たとえば `["System"; "Collections"]` と `"Generic"` というように -完全修飾された名前空間を指定して補完リストを取得することもできます。 - -### 引数の情報を取得する - -次に一般的なエディタの機能としては、メソッドのオーバーロードに -関する情報を提供するというものでしょう。 -サンプルコード中では多数のオーバーロードを持った `String.Concat` を使っています。 -このオーバーロード一覧は `GetMethods` で取得できます。 -先ほどと同じく、このメソッドには対象とする項目の位置を0基準のオフセットで指定し -(今回は `String.Concat` 識別子の右側の終端)、 -識別子もやはり指定します -(これにより、コンパイラはソースコードが変更された場合でも最新の情報に追従できます): - -*) -//String.Concatメソッドのオーバーロードを取得する -let methods = - checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) |> Async.RunSynchronously - -// 連結された引数リストを表示 -for mi in methods.Methods do - [ for p in mi.Parameters -> p.Display ] - |> String.concat ", " - |> printfn "%s(%s)" methods.MethodName -(** -ここでは `Display` プロパティを使用することで各引数に対する -アノテーションを取得しています。 -このプロパティは `arg0: obj` あるいは `params args: obj[]` 、 -`str0: string, str1: string` といった情報を返します。 -これらの引数を連結した後、メソッド名とメソッドの型情報とともに表示させています。 -*) - -(** - -## 非同期操作と即時操作 - -`CheckFileInProject` が非同期操作であることを気にされる人もいるかもしれません。 -これはつまり、F#コードの型チェックにはある程度時間がかかることを示唆しています。 -F#コンパイラは型チェックを(自動的に)バックグラウンドで処理を進めているため、 -`CheckFileInProject` メソッドを呼び出すと非同期操作が返されることになります。 - -また、 `CheckFileInProjectIfReady` というメソッドもあります。 -このメソッドは、型チェックの操作が即座に開始できない場合、 -つまりプロジェクト内の他のファイルがまだ型チェックされていない場合には -処理が即座に返されます。 -この場合、バックグラウンドワーカーは一定期間他の作業を進めるか、 -`FileTypeCheckStateIsDirty` イベントが発生するまでは -ファイルに対する型チェックを諦めるか、どちらか選択することになります。 - -> [fsharpbinding](https://github.com/fsharp/fsharpbinding) プロジェクトには -1つのF#エージェント経由ですべてのリクエストをバックグラウンドワークとして -処理するような、より複雑な具体例も含まれています。 -エディタの機能を実装する方法としてはこちらのほうが適切です。 - -*) - - -(** -まとめ ------- - -`CheckFileAnswer` にはチュートリアルで紹介していないような便利なメソッドが -多数揃えられています。 -これらを使用すれば特定の識別子に対する宣言の位置を取得したり、 -付加的な色情報を取得したりすることができます -(F# 3.1では式ビルダーの識別子やクエリ演算子も着色表示されます)。 - -最後に、直接.NET APIを呼び出すことができないようなエディタに対するサポート機能を -実装する場合、ここで紹介した様々な機能を -[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete) -プロジェクトのコマンドラインインターフェイス経由で呼び出すこともできます。 -*) diff --git a/fcs/docsrc/content/ja/filesystem.fsx b/fcs/docsrc/content/ja/filesystem.fsx deleted file mode 100644 index 0680f34122f..00000000000 --- a/fcs/docsrc/content/ja/filesystem.fsx +++ /dev/null @@ -1,175 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス: ファイルシステム仮想化 -========================================== - -`FSharp.Compiler.Service` にはファイルシステムを表すグローバル変数があります。 -この変数を設定するこにより、ファイルシステムが利用できない状況でも -コンパイラをホストすることができるようになります。 - -> **注意:** 以下で使用しているAPIは実験的なもので、 - 新しいnugetパッケージの公開に伴って変更される可能性があります。 - -FileSystemの設定 ----------------- - -以下の例ではディスクからの読み取りを行うような実装をファイルシステムに設定しています: -*) -#r "FSharp.Compiler.Service.dll" -open System -open System.IO -open System.Collections.Generic -open System.Text -open FSharp.Compiler.AbstractIL.Internal.Library - -let defaultFileSystem = Shim.FileSystem - -let fileName1 = @"c:\mycode\test1.fs" // 注意: 実際には存在しないファイルのパス -let fileName2 = @"c:\mycode\test2.fs" // 注意: 実際には存在しないファイルのパス - -type MyFileSystem() = - let file1 = """ -module File1 - -let A = 1""" - let file2 = """ -module File2 -let B = File1.A + File1.A""" - let files = dict [(fileName1, file1); (fileName2, file2)] - - interface IFileSystem with - // 読み取りおよび書き込み用にファイルをオープンする機能を実装 - member __.FileStreamReadShim(fileName) = - match files.TryGetValue fileName with - | true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream - | _ -> defaultFileSystem.FileStreamReadShim(fileName) - - member __.FileStreamCreateShim(fileName) = - defaultFileSystem.FileStreamCreateShim(fileName) - - member __.IsStableFileHeuristic(fileName) = - defaultFileSystem.IsStableFileHeuristic(fileName) - - member __.FileStreamWriteExistingShim(fileName) = - defaultFileSystem.FileStreamWriteExistingShim(fileName) - - member __.ReadAllBytesShim(fileName) = - match files.TryGetValue fileName with - | true, text -> Encoding.UTF8.GetBytes(text) - | _ -> defaultFileSystem.ReadAllBytesShim(fileName) - - // 一時パスおよびファイルのタイムスタンプに関連する機能を実装 - member __.GetTempPathShim() = - defaultFileSystem.GetTempPathShim() - - member __.GetLastWriteTimeShim(fileName) = - defaultFileSystem.GetLastWriteTimeShim(fileName) - - member __.GetFullPathShim(fileName) = - defaultFileSystem.GetFullPathShim(fileName) - - member __.IsInvalidPathShim(fileName) = - defaultFileSystem.IsInvalidPathShim(fileName) - - member __.IsPathRootedShim(fileName) = - defaultFileSystem.IsPathRootedShim(fileName) - - // ファイルの存在確認および削除に関連する機能を実装 - member __.SafeExists(fileName) = - files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName) - - member __.FileDelete(fileName) = - defaultFileSystem.FileDelete(fileName) - - // アセンブリのロードに関連する機能を実装。 - // 型プロバイダやF# Interactiveで使用される。 - member __.AssemblyLoadFrom(fileName) = - defaultFileSystem.AssemblyLoadFrom fileName - - member __.AssemblyLoad(assemblyName) = - defaultFileSystem.AssemblyLoad assemblyName - -let myFileSystem = MyFileSystem() -Shim.FileSystem <- MyFileSystem() - -(** - -FileSystemによるコンパイルの実行 --------------------------------- - -*) -open FSharp.Compiler.SourceCodeServices - -let checker = FSharpChecker.Create() -let projectOptions = - let allFlags = - [| yield "--simpleresolution"; - yield "--noframework"; - yield "--debug:full"; - yield "--define:DEBUG"; - yield "--optimize-"; - yield "--doc:test.xml"; - yield "--warn:3"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:library"; - let references = - [ @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll"; - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll"; - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll"; - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"] - for r in references do - yield "-r:" + r |] - - { ProjectFileName = @"c:\mycode\compilation.fsproj" // 現在のディレクトリで一意な名前を指定 - ProjectId = None - SourceFiles = [| fileName1; fileName2 |] - OriginalLoadReferences = [] - ExtraProjectInfo=None - Stamp = None - OtherOptions = allFlags - ReferencedProjects=[| |] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = true - LoadTime = System.DateTime.Now // 'Now' を指定して強制的に再読込させている点に注意 - UnresolvedReferences = None } - -let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously - -results.Errors -results.AssemblySignature.Entities.Count //2 -results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1 -results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B" - -(** -まとめ ------- -このチュートリアルでは FSharp.Compiler.Service コンポーネントで使用される -ファイルシステムに注目して、グローバルな設定を変更する方法について紹介しました。 - -このチュートリアルの執筆時点では、以下に列挙したSystem.IOの操作に対しては -仮想化されたファイルシステムAPIが用意されない予定になっています。 -将来のバージョンのコンパイラサービスではこれらのAPIが追加されるかもしれません。 - - - Path.Combine - - Path.DirectorySeparatorChar - - Path.GetDirectoryName - - Path.GetFileName - - Path.GetFileNameWithoutExtension - - Path.HasExtension - - Path.GetRandomFileName (アセンブリ内にコンパイル済みwin32リソースを生成する場合にのみ使用される) - -**注意:** `SourceCodeServices` API内の一部の操作では、 -引数にファイルの内容だけでなくファイル名を指定する必要があります。 -これらのAPIにおいて、ファイル名はエラーの報告のためだけに使用されます。 - -**注意:** 型プロバイダーコンポーネントは仮想化されたファイルシステムを使用しません。 - -**注意:** コンパイラサービスは `--simpleresolution` が指定されていない場合、 -MSBuildを使ってアセンブリの解決を試みることがあります。 -`FileSystem` APIを使用する場合、通常はコンパイラへのフラグとして -`--simpleresolution` を指定することになります。 -それと同時に `--noframework` を指定します。 -.NETアセンブリに対するすべての参照を明示的に指定する必要があるでしょう。 -*) diff --git a/fcs/docsrc/content/ja/interactive.fsx b/fcs/docsrc/content/ja/interactive.fsx deleted file mode 100644 index 59bae44f01b..00000000000 --- a/fcs/docsrc/content/ja/interactive.fsx +++ /dev/null @@ -1,299 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -インタラクティブサービス: F# Interactiveの組み込み -================================================== - -このチュートリアルでは、独自のアプリケーションに -F# Interactiveを組み込む方法について紹介します。 -F# Interactiveは対話式のスクリプティング環境で、 -F#コードを高度に最適化されたILコードへとコンパイルしつつ、 -それを即座に実行することができます。 -F# Interactiveサービスを使用すると、独自のアプリケーションに -F#の評価機能を追加できます。 - -> **注意:** F# Interactiveは様々な方法で組み込むことができます。 - 最も簡単な方法は `fsi.exe` プロセスとの間で標準入出力経由でやりとりする方法です。 - このチュートリアルではF# Interactiveの機能を.NET APIで - 直接呼び出す方法について紹介します。 - ただし入力用のコントロールを備えていない場合、別プロセスでF# Interactiveを - 起動するのはよい方法だといえます。 - 理由の1つとしては `StackOverflowException` を処理する方法がないため、 - 出来の悪いスクリプトによってはホストプロセスが停止させられてしまう - 場合があるからです。 - **.NET APIを通じてF# Interactiveを呼び出すとしても、 `--shadowcopyreferences` - オプションは無視されることを覚えておきましょう。** - 詳細な議論については、[このスレッド](https://github.com/fsharp/FSharp.Compiler.Service/issues/292) - に目を通してみてください。 - **注意:** もし`FSharp.Core.dll` が見つからないというエラーが出て `FsiEvaluationSession.Create` - に失敗した場合、 `FSharp.Core.sigdata` と `FSharp.Core.optdata` というファイルを追加してください。 - 詳しい内容は[こちら](https://fsharp.github.io/FSharp.Compiler.Service/ja/corelib.html) - にあります。 - -しかしそれでもF# InteractiveサービスにはF# Interactiveを実行ファイルに埋め込んで -実行出来る(そしてアプリケーションの各機能とやりとり出来る)、あるいは -機能限定されたF#コード(たとえば独自のDSLによって生成されたコード)だけを -実行させることが出来るという便利さがあります。 - -F# Interactiveの開始 --------------------- - -まずF# Interactiveサービスを含むライブラリへの参照を追加します: -*) - -#r "FSharp.Compiler.Service.dll" -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Interactive.Shell - -(** -F# Interactiveとやりとりするには、入出力を表すストリームを作成する必要があります。 -これらのストリームを使用することで、 -いくつかのF#コードに対する評価結果を後から出力することができます: -*) -open System -open System.IO -open System.Text - -// 入出力のストリームを初期化 -let sbOut = new StringBuilder() -let sbErr = new StringBuilder() -let inStream = new StringReader("") -let outStream = new StringWriter(sbOut) -let errStream = new StringWriter(sbErr) - -// コマンドライン引数を組み立てて、FSIセッションを開始する -let argv = [| "C:\\fsi.exe" |] -let allArgs = Array.append argv [|"--noninteractive"|] - -let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() -let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream) - -(** -コードの評価および実行 ----------------------- - -F# Interactiveサービスにはコードを評価するためのメソッドがいくつか用意されています。 -最初の1つは `EvalExpression` で、式を評価してその結果を返します。 -結果には戻り値が( `obj` として)含まれる他、値に対して静的に推論された型も含まれます: -*) -/// 式を評価して結果を返す -let evalExpression text = - match fsiSession.EvalExpression(text) with - | Some value -> printfn "%A" value.ReflectionValue - | None -> printfn "結果が得られませんでした!" - -(** -これは引数に文字列を取り、それをF#コードとして評価(つまり実行)します。 -*) -evalExpression "42+1" // '43' を表示する - -(** -これは以下のように強く型付けされた方法で使うことができます: -*) - -/// 式を評価して、強く型付けされた結果を返す -let evalExpressionTyped<'T> (text) = - match fsiSession.EvalExpression(text) with - | Some value -> value.ReflectionValue |> unbox<'T> - | None -> failwith "結果が得られませんでした!" - -evalExpressionTyped "42+1" // '43' になる - - -(** -`EvalInteraction` メソッドは画面出力機能や宣言、 -F#の式としては不正なものの、F# Interactiveコンソールには入力できるようなものなど、 -副作用を伴う命令を評価する場合に使用できます。 -たとえば `#time "on"` (あるいはその他のディレクティブ)や `open System` 、 -その他の宣言やトップレベルステートメントなどが該当します。 -指定するコードの終端に `;;` を入力する必要はありません。 -実行したいコードだけを入力します: -*) -fsiSession.EvalInteraction "printfn \"bye\"" - - -(** -`EvalScript` メソッドを使用すると、完全な .fsx スクリプトを評価することができます。 -*) - -File.WriteAllText("sample.fsx", "let twenty = 10 + 10") -fsiSession.EvalScript "sample.fsx" - -(** -例外処理 --------- - -コードに型チェックの警告やエラーがあった場合、または評価して例外で失敗した場合、 -`EvalExpression` 、 `EvalInteraction` そして `EvalScript` ではあまりうまく処理されません。 -これらのケースでは、 `EvalExpressionNonThrowing` 、 `EvalInteractionNonThrowing` -そして `EvalScriptNonThrowing` を使うことが出来ます。 -これらは結果と `FSharpErrorInfo` 値の配列の組を返します。 -これらはエラーと警告を表します。結果の部分は実際の結果と例外のいずれかを表す -`Choice<_,_>` です。 - -`EvalExpression` および `EvalExpressionNonThrowing` の結果部分は -オプションの `FSharpValue` 値です。 -その値が存在しない場合、式が .NET オブジェクトとして表現できる具体的な結果を -持っていなかったということを指し示しています。 -この状況は実際には入力されたどんな通常の式に対しても発生すべきではなく、 -ライブラリ内で使われるプリミティブ値に対してのみ発生すべきです。 -*) - -File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0") -let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx" - -// 結果を表示する -match result with -| Choice1Of2 () -> printfn "チェックと実行はOKでした" -| Choice2Of2 exn -> printfn "実行例外: %s" exn.Message - - -(** -は次のようになります: - - 実行例外: Operation could not be completed due to earlier error -*) - -// エラーと警告を表示する -for w in warnings do - printfn "警告 %s 場所 %d,%d" w.Message w.StartLineAlternate w.StartColumn - -(** -は次のようになります: - - 警告 The type 'float' does not match the type 'char' 場所 1,19 - 警告 The type 'float' does not match the type 'char' 場所 1,17 - -式に対しては: -*) - - -let evalExpressionTyped2<'T> text = - let res, warnings = fsiSession.EvalExpressionNonThrowing(text) - for w in warnings do - printfn "警告 %s 場所 %d,%d" w.Message w.StartLineAlternate w.StartColumn - match res with - | Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T> - | Choice1Of2 None -> failwith "null または結果がありません" - | Choice2Of2 (exn:exn) -> failwith (sprintf "例外 %s" exn.Message) - -evalExpressionTyped2 "42+1" // '43' になる - - -(** -並列実行 --------- - -デフォルトでは `EvalExpression` に渡したコードは即時実行されます。 -並列に実行するために、タスクを開始する計算を投入します: -*) - -open System.Threading.Tasks - -let sampleLongRunningExpr = - """ -async { - // 実行したいコード - do System.Threading.Thread.Sleep 5000 - return 10 -} - |> Async.StartAsTask""" - -let task1 = evalExpressionTyped>(sampleLongRunningExpr) -let task2 = evalExpressionTyped>(sampleLongRunningExpr) - -(** -両方の計算がいま開始しました。結果を取得することが出来ます: -*) - - -task1.Result // 完了後に結果が出てくる (最大5秒) -task2.Result // 完了後に結果が出てくる (最大5秒) - -(** -評価コンテキスト内での型チェック --------------------------------- - -F# Interactiveの一連のスクリプティングセッション中で -コードの型チェックを実行したいような状況を考えてみましょう。 -たとえばまず宣言を評価します: -*) - -fsiSession.EvalInteraction "let xxx = 1 + 1" - -(** - -次に部分的に完全な `xxx + xx` というコードの型チェックを実行したいとします: -*) - -let parseResults, checkResults, checkProjectResults = - fsiSession.ParseAndCheckInteraction("xxx + xx") |> Async.RunSynchronously - -(** -`parseResults` と `checkResults` はそれぞれ [エディタ](editor.html) -のページで説明している `ParseFileResults` と `CheckFileResults` 型です。 -たとえば以下のようなコードでエラーを確認出来ます: -*) -checkResults.Errors.Length // 1 - -(** -コードはF# Interactiveセッション内において、その時点までに実行された -有効な宣言からなる論理的な型コンテキストと結びつく形でチェックされます。 - -また、宣言リスト情報やツールチップテキスト、シンボルの解決といった処理を -要求することもできます: - -*) -open FSharp.Compiler - -// ツールチップを取得する -checkResults.GetToolTipText(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT) - -checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // シンボル xxx - -(** -'fsi'オブジェクト ------------------ - -スクリプトのコードが'fsi'オブジェクトにアクセスできるようにしたい場合、 -このオブジェクトの実装を明示的に渡さなければなりません。 -通常、FSharp.Compiler.Interactive.Settings.dll由来の1つが使われます。 -*) - -let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsi) - -(** -収集可能なコード生成 --------------------- - -FsiEvaluationSessionを使用してコードを評価すると、 -.NET の動的アセンブリを生成し、他のリソースを使用します。 -`collectible=true` を渡すことで、生成されたコードを収集可能に出来ます。 -しかしながら、例えば `EvalExpression` から返される `FsiValue` のような型を必要とする未解放のオブジェクト参照が無く、 -かつ `FsiEvaluationSession` を破棄したに違いない場合に限ってコードが収集されます。 -[収集可能なアセンブリに対する制限](https://msdn.microsoft.com/ja-jp/library/dd554932%28v=vs.110%29.aspx#Anchor_1) -も参照してください。 - -以下の例は200個の評価セッションを生成しています。 `collectible=true` と `use session = ...` -の両方を使っていることに気をつけてください。 - -収集可能なコードが正しく動いた場合、全体としてのリソース使用量は -評価が進んでも線形には増加しないでしょう。 -*) - -let collectionTest() = - - for i in 1 .. 200 do - let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|] - use inStream = new StringReader("") - use outStream = new StringWriter() - use errStream = new StringWriter() - - let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() - use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true) - - session.EvalInteraction (sprintf "type D = { v : int }") - let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i) - printfn "その %d, 結果 = %A" i v.Value.ReflectionValue - -// collectionTest() <-- このようにテストを実行する \ No newline at end of file diff --git a/fcs/docsrc/content/ja/project.fsx b/fcs/docsrc/content/ja/project.fsx deleted file mode 100644 index 8b70e3df5f7..00000000000 --- a/fcs/docsrc/content/ja/project.fsx +++ /dev/null @@ -1,282 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス: プロジェクトの分析 -====================================== - -このチュートリアルではF#コンパイラによって提供されるサービスを使用して -プロジェクト全体を分析する方法について紹介します。 - -> **注意:** 以下で使用しているAPIは試験的なもので、 - 最新のnugetパッケージの公開に伴って変更されることがあります。 - - -プロジェクト全体の結果を取得する --------------------------------- - -[以前の(型無しASTを使った)チュートリアル](untypedtree.html) と同じく、 -まずは `FSharp.Compiler.Service.dll` への参照追加と、適切な名前空間のオープン、 -`FSharpChecker` インスタンスの作成を行います: - -*) -// F#コンパイラAPIへの参照 -#r "FSharp.Compiler.Service.dll" - -open System -open System.Collections.Generic -open FSharp.Compiler.SourceCodeServices - -// インタラクティブチェッカーのインスタンスを作成 -let checker = FSharpChecker.Create() - -(** -今回のサンプル入力は以下の通りです: -*) - -module Inputs = - open System.IO - - let base1 = Path.GetTempFileName() - let fileName1 = Path.ChangeExtension(base1, ".fs") - let base2 = Path.GetTempFileName() - let fileName2 = Path.ChangeExtension(base2, ".fs") - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") - let fileSource1 = """ -module M - -type C() = - member x.P = 1 - -let xxx = 3 + 4 -let fff () = xxx + xxx - """ - File.WriteAllText(fileName1, fileSource1) - - let fileSource2 = """ -module N - -open M - -type D1() = - member x.SomeProperty = M.xxx - -type D2() = - member x.SomeProperty = M.fff() - -// 警告を発生させる -let y2 = match 1 with 1 -> M.xxx - """ - File.WriteAllText(fileName2, fileSource2) - - -(** -`GetProjectOptionsFromCommandLineArgs` を使用して、 -2つのファイルを1つのプロジェクトとして扱えるようにします: -*) - -let projectOptions = - checker.GetProjectOptionsFromCommandLineArgs - (Inputs.projFileName, - [| yield "--simpleresolution" - yield "--noframework" - yield "--debug:full" - yield "--define:DEBUG" - yield "--optimize-" - yield "--out:" + Inputs.dllName - yield "--doc:test.xml" - yield "--warn:3" - yield "--fullpaths" - yield "--flaterrors" - yield "--target:library" - yield Inputs.fileName1 - yield Inputs.fileName2 - let references = - [ @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"] - for r in references do - yield "-r:" + r |]) - -(** -そして(ディスク上に保存されたファイルを使用して) -プロジェクト全体をチェックします: -*) - -let wholeProjectResults = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously - -(** -発生したエラーと警告は以下のようにしてチェックできます: -*) -wholeProjectResults.Errors.Length // 1 -wholeProjectResults.Errors.[0].Message.Contains("Incomplete pattern matches on this expression") // true - -wholeProjectResults.Errors.[0].StartLineAlternate // 13 -wholeProjectResults.Errors.[0].EndLineAlternate // 13 -wholeProjectResults.Errors.[0].StartColumn // 15 -wholeProjectResults.Errors.[0].EndColumn // 16 - -(** -推測されたプロジェクトのシグネチャをチェックします: -*) -[ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] // ["N"; "M"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] // ["D1"; "D2"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[1].NestedEntities -> x.DisplayName ] // ["C"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] // ["y2"] - -(** -プロジェクト内の全シンボルを取得することもできます: -*) -let rec allSymbolsInEntities (entities: IList) = - [ for e in entities do - yield (e :> FSharpSymbol) - for x in e.MembersFunctionsAndValues do - yield (x :> FSharpSymbol) - for x in e.UnionCases do - yield (x :> FSharpSymbol) - for x in e.FSharpFields do - yield (x :> FSharpSymbol) - yield! allSymbolsInEntities e.NestedEntities ] - -let allSymbols = allSymbolsInEntities wholeProjectResults.AssemblySignature.Entities -(** -プロジェクト全体のチェックが完了した後は、 -プロジェクト内の各ファイルに対する個別の結果を取得することもできます。 -この処理は即座に完了し、改めてチェックが実行されることもありません。 -*) - -let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Inputs.fileName1, projectOptions) - |> Async.RunSynchronously - - -(** -そしてそれぞれのファイル内にあるシンボルを解決できます: -*) - -let xSymbol = - backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) - |> Async.RunSynchronously - -(** -それぞれのシンボルに対して、シンボルへの参照を検索することもできます: -*) -let usesOfXSymbol = wholeProjectResults.GetUsesOfSymbol(xSymbol.Value.Symbol) - -(** -推測されたシグネチャ内にあるすべての定義済みシンボルに対して、 -それらがどこで使用されているのかを探し出すこともできます: -*) -let allUsesOfAllSignatureSymbols = - [ for s in allSymbols do - yield s.ToString(), wholeProjectResults.GetUsesOfSymbol(s) ] - -(** -(ローカルスコープで使用されているものも含めて) -プロジェクト全体で使用されているすべてのシンボルを確認することもできます: -*) -let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - -(** -また、プロジェクト内のファイルに対して、更新後のバージョンに対して -チェックを実行するようにリクエストすることもできます -(なお [FileSystem API](filesystem.html) を使用していない場合には、 -プロジェクト内のその他のファイルがまだディスクから -読み取り中であることに注意してください): - -*) -let parseResults1, checkAnswer1 = - checker.ParseAndCheckFileInProject(Inputs.fileName1, 0, Inputs.fileSource1, projectOptions) - |> Async.RunSynchronously - -let checkResults1 = - match checkAnswer1 with - | FSharpCheckFileAnswer.Succeeded x -> x - | _ -> failwith "想定外の終了状態です" - -let parseResults2, checkAnswer2 = - checker.ParseAndCheckFileInProject(Inputs.fileName2, 0, Inputs.fileSource2, projectOptions) - |> Async.RunSynchronously - -let checkResults2 = - match checkAnswer2 with - | FSharpCheckFileAnswer.Succeeded x -> x - | _ -> failwith "想定外の終了状態です" - -(** -そして再びシンボルを解決したり、参照を検索したりすることができます: -*) - -let xSymbol2 = - checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) - |> Async.RunSynchronously - -let usesOfXSymbol2 = wholeProjectResults.GetUsesOfSymbol(xSymbol2.Value.Symbol) - -(** -あるいは(ローカルスコープで使用されているシンボルも含めて) -ファイル中で使用されているすべてのシンボルを検索することもできます: -*) -let allUsesOfAllSymbolsInFile1 = checkResults1.GetAllUsesOfAllSymbolsInFile() - -(** -あるいは特定のファイル中で使用されているシンボルを検索することもできます: -*) -let allUsesOfXSymbolInFile1 = checkResults1.GetUsesOfSymbolInFile(xSymbol2.Value.Symbol) - -let allUsesOfXSymbolInFile2 = checkResults2.GetUsesOfSymbolInFile(xSymbol2.Value.Symbol) - -(** - -複数プロジェクトの分析 ----------------------- - -複数のプロジェクトにまたがった参照があるような、 -複数のF# プロジェクトを分析したい場合、 -それらのプロジェクトを一旦ビルドして、 -ProjectOptionsで `-r:プロジェクト-出力-までの-パス.dll` 引数を指定して -プロジェクトの相互参照を設定すると一番簡単です。 -しかしこの場合、それぞれのプロジェクトが正しくビルド出来、 -DLLファイルが参照可能なディスク上に生成されなければいけません。 - -たとえばIDEを操作している場合など、状況によっては -DLLのコンパイルが通るようになる前に -プロジェクトを参照したいことがあるでしょう。 -この場合はProjectOptionsのReferencedProjectsを設定します。 -この値には依存するプロジェクトのオプションを再帰的に指定します。 -それぞれのプロジェクト参照にはやはり、 -ReferencedProjectsのエントリそれぞれに対応する -`-r:プロジェクト-出力-までの-パス.dll` というコマンドライン引数を -ProjectOptionsに設定する必要があります。 - -プロジェクト参照が設定されると、ソースファイルからのF#プロジェクト分析処理が -インクリメンタル分析の結果を使用して行われるようになります。 -その際にはソースファイルファイルをDLLへとコンパイルする必要はありません。 - -相互参照を含むようなF#プロジェクトを効率よく分析するには、 -ReferencedProjectsを正しく設定した後、 -それぞれのプロジェクトを順番通りに分析していくとよいでしょう。 - -> **注意:** プロジェクトの参照機能は試作段階です。 - プロジェクトの参照を使用すると、依存先のプロジェクトがまだ分析中で、 - 要求したサービスがまだ利用できないことがあるため、 - コンパイラサービスの性能が低下することがあります。 - -> **注意:** アセンブリが型プロバイダーのコンポーネントを含む場合、 - プロジェクト参照機能は利用できません。 - プロジェクトの分析処理を強制しない限りはプロジェクト参照を設定しても - 効果がありません。 - また、分析を強制する場合にはディスク上にDLLが存在しなければいけません。 - -*) - -(** -まとめ ------- - -これまで説明してきた通り、 `ParseAndCheckProject` を使用すると -シンボルの参照などのようなプロジェクト全体の解析結果にアクセスできるようになります。 -シンボルに対する処理の詳細については [シンボル](symbols.html) のページを参照してください。 - -*) diff --git a/fcs/docsrc/content/ja/symbols.fsx b/fcs/docsrc/content/ja/symbols.fsx deleted file mode 100644 index ff62b0de6b2..00000000000 --- a/fcs/docsrc/content/ja/symbols.fsx +++ /dev/null @@ -1,236 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス: シンボルの処理 -================================== - -このチュートリアルでは、F#コンパイラによって提供される -シンボルの扱い方についてのデモを紹介します。 -シンボルの参照に関する情報については [プロジェクト全体の分析](project.html) -も参考にしてください。 - -> **注意:** 以下で使用しているAPIは試験的なもので、 - 最新のnugetパッケージの公開に伴って変更されることがあります。 - -これまでと同じく、 `FSharp.Compiler.Service.dll` への参照を追加した後、 -適切な名前空間をオープンし、 `FSharpChecker` のインスタンスを作成します: - -*) -// F#コンパイラAPIへの参照 -#r "FSharp.Compiler.Service.dll" - -open System -open System.IO -open FSharp.Compiler.SourceCodeServices - -// インタラクティブチェッカーのインスタンスを作成 -let checker = FSharpChecker.Create() - -(** - -そして特定の入力値に対して型チェックを行います: - -*) - -let parseAndTypeCheckSingleFile (file, input) = - // スタンドアロンの(スクリプト)ファイルを表すコンテキストを取得 - let projOptions, _errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - let parseFileResults, checkFileResults = - checker.ParseAndCheckFileInProject(file, 0, input, projOptions) - |> Async.RunSynchronously - - // 型チェックが成功(あるいは100%に到達)するまで待機 - match checkFileResults with - | FSharpCheckFileAnswer.Succeeded(res) -> parseFileResults, res - | res -> failwithf "Parsing did not finish... (%A)" res - -let file = "/home/user/Test.fsx" - -(** -## ファイルに対する解決済みのシグネチャ情報を取得する - -ファイルに対する型チェックが完了すると、 -`TypeCheckResults` の `PartialAssemblySignature` プロパティを参照することにより、 -チェック中の特定のファイルを含む、推論されたプロジェクトのシグネチャに -アクセスすることができます。 - -モジュールや型、属性、メンバ、値、関数、共用体、レコード型、測定単位、 -およびその他のF#言語要素に対する完全なシグネチャ情報が参照できます。 - -ただし型付き式ツリーに対する情報は(今のところ)この方法では利用できません。 - -*) - -let input2 = - """ -[] -let foo(x, y) = - let msg = String.Concat("Hello"," ","world") - if true then - printfn "x = %d, y = %d" x y - printfn "%s" msg - -type C() = - member x.P = 1 - """ -let parseFileResults, checkFileResults = - parseAndTypeCheckSingleFile(file, input2) - -(** -これでコードに対する部分的なアセンブリのシグネチャが取得できるようになります: -*) -let partialAssemblySignature = checkFileResults.PartialAssemblySignature - -partialAssemblySignature.Entities.Count = 1 // エンティティは1つ - -(** -そしてコードを含むモジュールに関連したエンティティを取得します: -*) -let moduleEntity = partialAssemblySignature.Entities.[0] - -moduleEntity.DisplayName = "Test" - -(** -そしてコード内の型定義に関連したエンティティを取得します: -*) -let classEntity = moduleEntity.NestedEntities.[0] - -(** -そしてコード内で定義された関数に関連した値を取得します: -*) -let fnVal = moduleEntity.MembersFunctionsAndValues.[0] - -(** -関数値に関するプロパティの値を確認してみましょう。 -*) -fnVal.Attributes.Count // 1 -fnVal.CurriedParameterGroups.Count // 1 -fnVal.CurriedParameterGroups.[0].Count // 2 -fnVal.CurriedParameterGroups.[0].[0].Name // "x" -fnVal.CurriedParameterGroups.[0].[1].Name // "y" -fnVal.DeclarationLocation.StartLine // 3 -fnVal.DisplayName // "foo" -fnVal.DeclaringEntity.Value.DisplayName // "Test" -fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1 -fnVal.GenericParameters.Count // 0 -fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline -fnVal.IsActivePattern // false -fnVal.IsCompilerGenerated // false -fnVal.IsDispatchSlot // false -fnVal.IsExtensionMember // false -fnVal.IsPropertyGetterMethod // false -fnVal.IsImplicitConstructor // false -fnVal.IsInstanceMember // false -fnVal.IsMember // false -fnVal.IsModuleValueOrMember // true -fnVal.IsMutable // false -fnVal.IsPropertySetterMethod // false -fnVal.IsTypeFunction // false - -(** -次に、この関数の型がファーストクラスの値として使用されているかどうかチェックします。 -(ちなみに `CurriedParameterGroups` プロパティには引数の名前など、 -より多くの情報も含まれています) -*) -fnVal.FullType // int * int -> unit -fnVal.FullType.IsFunctionType // true -fnVal.FullType.GenericArguments.[0] // int * int -fnVal.FullType.GenericArguments.[0].IsTupleType // true -let argTy1 = fnVal.FullType.GenericArguments.[0].GenericArguments.[0] - -argTy1.TypeDefinition.DisplayName // int - -(** -というわけで `int * int -> unit` という型を表現するオブジェクトが取得できて、 -その1つめの 'int' を確認できたわけです。 -また、以下のようにすると 'int' 型についてのより詳細な情報が取得でき、 -それが名前付きの型であり、F#の型省略形 `type int = int32` であることがわかります: -*) - -argTy1.HasTypeDefinition // true -argTy1.TypeDefinition.IsFSharpAbbreviation // true - -(** -型省略形の右辺、つまり `int32` についてもチェックしてみましょう: -*) - -let argTy1b = argTy1.TypeDefinition.AbbreviatedType -argTy1b.TypeDefinition.Namespace // Some "Microsoft.FSharp.Core" -argTy1b.TypeDefinition.CompiledName // "int32" - -(** -そして再び型省略形 `type int32 = System.Int32` から型に関する完全な情報が取得できます: -*) -let argTy1c = argTy1b.TypeDefinition.AbbreviatedType -argTy1c.TypeDefinition.Namespace // Some "System" -argTy1c.TypeDefinition.CompiledName // "Int32" - -(** -ファイルに対する型チェックの結果には、 -コンパイル時に使用されたプロジェクト(あるいはスクリプト)のオプションに関する -`ProjectContext` と呼ばれる情報も含まれています: -*) -let projectContext = checkFileResults.ProjectContext - -for assembly in projectContext.GetReferencedAssemblies() do - match assembly.FileName with - | None -> printfn "コンパイル時にファイルの存在しないアセンブリを参照しました" - | Some s -> printfn "コンパイル時にアセンブリ '%s' を参照しました" s - -(** -**注意:** - - - 不完全なコードが存在する場合、一部あるいはすべての属性が意図したとおりには - 並ばないことがあります。 - - (実際には非常によくあることですが)一部のアセンブリが見つからない場合、 - 外部アセンブリに関連する値やメンバ、エンティティにおける 'IsUnresolved' が - trueになることがあります。 - IsUnresolvedによる例外に対処できるよう、堅牢なコードにしておくべきです。 - -*) - -(** - -## プロジェクト全体に対するシンボル情報を取得する - -プロジェクト全体をチェックする場合、チェッカーを作成した後に `parseAndCheckScript` -を呼び出します。 -今回の場合は単に1つのスクリプトだけが含まれたプロジェクトをチェックします。 -異なる "projOptions" を指定すると、巨大なプロジェクトに対する設定を -構成することもできます。 -*) -let parseAndCheckScript (file, input) = - let projOptions, errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - let projResults = - checker.ParseAndCheckProject(projOptions) - |> Async.RunSynchronously - - projResults - -(** -そして特定の入力に対してこの関数を呼び出します: -*) - -let tmpFile = Path.ChangeExtension(System.IO.Path.GetTempFileName() , "fs") -File.WriteAllText(tmpFile, input2) - -let projectResults = parseAndCheckScript(tmpFile, input2) - - -(** -結果は以下の通りです: -*) - -let assemblySig = projectResults.AssemblySignature - -assemblySig.Entities.Count = 1 // エンティティは1つ -assemblySig.Entities.[0].Namespace // null -assemblySig.Entities.[0].DisplayName // "Tmp28D0" -assemblySig.Entities.[0].MembersFunctionsAndValues.Count // 1 -assemblySig.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "foo" diff --git a/fcs/docsrc/content/ja/tokenizer.fsx b/fcs/docsrc/content/ja/tokenizer.fsx deleted file mode 100644 index 4daf29b7ead..00000000000 --- a/fcs/docsrc/content/ja/tokenizer.fsx +++ /dev/null @@ -1,145 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス:F#トークナイザを使用する -============================================ - -このチュートリアルではF#言語トークナイザの呼び出し方を紹介します。 -F#のソースコードに対して、トークナイザは -コードの各行にあるトークンに関する情報を含んだソースコード行のリストを生成します。 -各トークンに対してはトークンの種類や位置を取得したり、 -トークンの種類(キーワード、識別子、数値、演算子など)に応じた -色を取得したりすることができます。 - -> **注意:** 以下で使用しているAPIは実験的なもので、 - 新しいnugetパッケージの公開に伴って変更される可能性があります。 - -トークナイザの作成 ------------------- - -トークナイザを使用するには、 `FSharp.Compiler.Service.dll` への参照を追加した後に -`SourceCodeServices` 名前空間をオープンします: -*) -#r "FSharp.Compiler.Service.dll" -open FSharp.Compiler.SourceCodeServices -(** -すると `FSharpSourceTokenizer` のインスタンスを作成できるようになります。 -このクラスには2つの引数を指定します。 -最初の引数には定義済みのシンボルのリスト、 -2番目の引数にはソースコードのファイル名を指定します。 -定義済みのシンボルのリストを指定するのは、 -トークナイザが `#if` ディレクティブを処理する必要があるからです。 -ファイル名はソースコードの位置を特定する場合にのみ指定する必要があります -(存在しないファイル名でも指定できます): -*) -let sourceTok = FSharpSourceTokenizer([], "C:\\test.fsx") -(** -`sourceTok` オブジェクトを使用することでF#ソースコードの各行を -(繰り返し)トークン化することができます。 - -F#コードのトークン化 --------------------- - -トークナイザはソースファイル全体ではなく、行単位で処理を行います。 -トークンを取得した後、トークナイザは新しいステートを( `int64` 値として)返します。 -この値を使うとF#コードをより効率的にトークン化できます。 -つまり、ソースコードが変更された場合もファイル全体を -再度トークン化する必要はありません。 -変更された部分だけをトークン化すればよいのです。 - -### 1行をトークン化する - -1行をトークン化するには、先ほど作成した `FSharpSourceTokenizer` オブジェクトに対して -`CreateLineTokenizer` を呼び、 `FSharpLineTokenizer` を作成します: -*) -let tokenizer = sourceTok.CreateLineTokenizer("let answer=42") -(** -そして `tokenizer` の `ScanToken` を繰り返し `None` を返すまで -(つまり最終行に到達するまで)繰り返し呼び出すような単純な再帰関数を用意します。 -この関数が成功すると、必要な詳細情報をすべて含んだ `FSharpTokenInfo` オブジェクトが -返されます: -*) -/// F#コード1行をトークン化します -let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = - match tokenizer.ScanToken(state) with - | Some tok, state -> - // トークン名を表示 - printf "%s " tok.TokenName - // 新しい状態で残りをトークン化 - tokenizeLine tokenizer state - | None, state -> state -(** -この関数は、複数行コードや複数行コメント内の前方の行をトークン化する場合に -必要となるような新しい状態を返します。 -初期値としては `0L` を指定します: -*) -tokenizeLine tokenizer FSharpTokenizerLexState.Initial -(** -この結果は LET WHITESPACE IDENT EQUALS INT32 という -トークン名のシーケンスになります。 -`FSharpTokenInfo` にはたとえば以下のような興味深いプロパティが多数あります: - - - `CharClass` および `ColorClass` はF#コードを色づけする場合に使用できるような、 - トークンのカテゴリに関する情報を返します。 - - `LeftColumn` および `RightColumn` は行内におけるトークンの位置を返します。 - - `TokenName` は(F# レキサ内で定義された)トークンの名前を返します。 - -なおトークナイザはステートフルであることに注意してください。 -つまり、1行を複数回トークン化したい場合にはその都度 `CreateLineTokenizer` を -呼び出す必要があります。 - -### サンプルコードのトークン化 - -トークナイザをもっと長いサンプルコードやファイル全体に対して実行する場合、 -サンプル入力を `string` のコレクションとして読み取る必要があります: -*) -let lines = """ - // Hello world - let hello() = - printfn "Hello world!" """.Split('\r','\n') -(** -複数行の入力値をトークン化する場合も、現在の状態を保持するような -再帰関数が必要になります。 -以下の関数はソースコード行を文字列のリストとして受け取ります -(また、行番号および現在の状態も受け取ります)。 -各行に対して新しいトークナイザを作成して、 -直前の行における **最後** の状態を使って `tokenizeLine` を呼び出します: -*) -/// 複数行のコードに対してトークンの名前を表示します -let rec tokenizeLines state count lines = - match lines with - | line::lines -> - // トークナイザを作成して1行をトークン化 - printfn "\nLine %d" count - let tokenizer = sourceTok.CreateLineTokenizer(line) - let state = tokenizeLine tokenizer state - // 新しい状態を使って残りをトークン化 - tokenizeLines state (count+1) lines - | [] -> () -(** -ここでは単に(先ほど定義した) `tokenizeLine` を呼び出して、 -各行にあるすべてのトークンの名前を表示しています。 -この関数は先と同じく、初期状態の値 `0L` と、1行目を表す `1` を -指定して呼び出すことができます: -*) -lines -|> List.ofSeq -|> tokenizeLines FSharpTokenizerLexState.Initial 1 -(** -重要ではない部分(各行の先頭にある空白文字や、1行目のように空白文字しかない行) -を除けば、このコードを実行すると以下のような出力になります: - - [lang=text] - Line 1 - LINE_COMMENT LINE_COMMENT (...) LINE_COMMENT - Line 2 - LET WHITESPACE IDENT LPAREN RPAREN WHITESPACE EQUALS - Line 3 - IDENT WHITESPACE STRING_TEXT (...) STRING_TEXT STRING - -注目すべきは、単一行コメントや文字列に対して、 -トークナイザが複数回(大まかにいって単語単位で) `LINE_COMMENT` や -`STRING_TEXT` を返しているところです。 -したがって、コメントや文字列全体をテキストとして取得したい場合には -それぞれのトークンを連結する必要があります。 -*) \ No newline at end of file diff --git a/fcs/docsrc/content/ja/untypedtree.fsx b/fcs/docsrc/content/ja/untypedtree.fsx deleted file mode 100644 index 447e3742fff..00000000000 --- a/fcs/docsrc/content/ja/untypedtree.fsx +++ /dev/null @@ -1,276 +0,0 @@ -(*** hide ***) -#I "../../../../artifacts/bin/fcs/net461" -(** -コンパイラサービス:型無し構文木の処理 -====================================== - -このチュートリアルではF#コードに対する型無し抽象構文木 -(untyped abstract syntax tree: untyped AST) -を取得する方法、および木全体を走査する方法を紹介します。 -この処理を行うことによって、コードフォーマットツールや -基本的なリファクタリングツール、コードナビゲーションツールなどを作成できます。 -型無し構文木にはコードの構造に関する情報が含まれていますが、 -型情報が含まれていないだけでなく、後で型チェッカーを通すまでは -解決されないような曖昧さも残されています。 -また、 [エディタサービス](editor.html) として提供されているAPIと -型無しASTの情報を組み合わせることもできます。 - -> **注釈:** 以下で使用しているAPIは試験的なもので、将来的に変更される場合があります。 - つまりFSharp.Compiler.Service.dll には既存のものと重複する機能が多数あるため、 - 将来的にはもっときちんとした形に変更されます。 - そのため、これらのサービスを使用するAPIには破壊的変更が加えられる可能性があります。 - - -型無しASTの取得 ---------------- - - -型無しASTにアクセスするには、 `FSharpChecker` のインスタンスを作成します。 -これは型チェックおよびパース用のコンテキストを表す型で、、 -スタンドアロンのF#スクリプトファイル(たとえばVisual Studioで開いたファイル)、 -あるいは複数ファイルで構成されたロード済みのプロジェクトファイルの -いずれかと結びつきます。 -このインスタンスを作成すると、型チェックの最初のステップである -「型無しパース」を実行できます。 -次のフェーズは「型有りパース」で、これは [エディタサービス](editor.html) で -使用されるものです。 - -インタラクティブチェッカーを使用するには、 -`FSharp.Compiler.Service.dll` への参照を追加した後、 -`SourceCodeServices` 名前空間をオープンします: -*) -#r "FSharp.Compiler.Service.dll" -open System -open FSharp.Compiler.SourceCodeServices -(** - -### 型無しパースの実行 - -型無しパース処理は(それなりの時間がかかる型チェック処理と比較すると) -かなり高速なため、同期的に実行できます。 -まず `FSharpChecker` を作成します。 - -*) -// インタラクティブチェッカーのインスタンスを作成 -let checker = FSharpChecker.Create() -(** - -ASTを取得するために、ファイル名とソースコードを受け取る関数を用意します -(ファイル名は位置情報のためだけに使用されるもので、存在しなくても構いません)。 -まず、コンテキストを表す「インタラクティブチェッカーオプション」を -用意する必要があります。 -単純な処理に対しては、 `GetCheckOptionsFromScriptRoot` を使えば -スクリプトファイルのコンテキストを推測させることができます。 -そして `UntypedParse` メソッドを呼び出した後、 -`ParseTree` プロパティの値を返します: - -*) -/// 特定の入力に対する型無し構文木を取得する -let getUntypedTree (file, input) = - // 1つのスクリプトファイルから推測される「プロジェクト」用の - // コンパイラオプションを取得する - let projOptions, errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) - - // コンパイラの第1フェーズを実行する - let untypedRes = - checker.ParseFile(file, input, parsingOptions) - |> Async.RunSynchronously - - match untypedRes.ParseTree with - | Some tree -> tree - | None -> failwith "パース中に何らかの問題が発生しました!" - -(** -`FSharpChecker` の詳細については -[ APIドキュメント](../reference/microsoft-fsharp-compiler-sourcecodeservices-FSharpChecker.html) -の他に、F# ソースコードのインラインコメントも参考になるでしょう -( [`service.fsi` のソースコードを参照](https://github.com/fsharp/fsharp/blob/fsharp_31/src/fsharp/service/service.fsi) )。 - -ASTの走査 ---------- - -抽象構文木は(式やパターン、宣言など)それぞれ異なる文法的要素を表現する、 -多数の判別共用体として定義されています。 -ASTを理解するには -[`ast.fs`内にあるソースコード](https://github.com/fsharp/fsharp/blob/master/src/fsharp/ast.fs#L464) -の定義を確認する方法が一番よいでしょう。 - -ASTに関連する要素は以下の名前空間に含まれています: -*) -open FSharp.Compiler.Ast -(** - -ASTを処理する場合、異なる文法的要素に対するパターンマッチを行うような -相互再帰関数を多数用意することになります。 -サポートすべき要素は非常に多種多様です。 -たとえばトップレベル要素としてはモジュールや名前空間の宣言、 -モジュール内における(letバインディングや型などの)宣言などがあります。 -モジュール内のlet宣言には式が含まれ、さらにこの式に -パターンが含まれていることもあります。 - -### パターンと式を走査する - -まずは式とパターンを走査する関数から始めます。 -この関数は要素を走査しつつ、要素に関する情報を画面に表示します。 -パターンの場合、入力は `SynPat` 型であり、この型には `Wild` ( `_` パターンを表す)や -`Named` ( ` という名前` のパターン)、 -`LongIdent` ( `Foo.Bar` 形式の名前)など、多数のケースがあります。 -なお、基本的にパース後のパターンは元のソースコードの見た目よりも複雑になります -(具体的には `Named` がかなり多数現れます): -*) -/// パターンの走査 -/// これは let = あるいは 'match' 式に対する例です -let rec visitPattern = function - | SynPat.Wild(_) -> - printfn " .. アンダースコアパターン" - | SynPat.Named(pat, name, _, _, _) -> - visitPattern pat - printfn " .. 名前 '%s' のパターン" name.idText - | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> - let names = String.concat "." [ for i in ident -> i.idText ] - printfn " .. 識別子: %s" names - | pat -> printfn " .. その他のパターン: %A" pat -(** -この関数は (`bar という名前の (foo, _)` のような、 -ネストされたパターンに対応するために) 再帰関数になっていますが、 -以降で定義するいずれの関数も呼び出しません -(パターンはその他の文法的な要素を含むことができないからです)。 - -次の関数は式全体を走査するものです。 -これは処理の大部分が行われる関数で、 -20以上のケースをカバーすることになるでしょう -( `SynExpr` と入力するとその他のオプションが確認できます)。 -以下のコードでは `if .. then ..` と `let .. = ...` という式を -処理する方法だけを紹介しています: -*) -/// 式を走査する。 -/// 式に2つあるいは3つの部分式が含まれていた場合('else'の分岐がない場合は2つ)、 -/// let式にはパターンおよび2つの部分式が含まれる -let rec visitExpression = function - | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> - // すべての部分式を走査 - printfn "条件部:" - visitExpression cond - visitExpression trueBranch - falseBranchOpt |> Option.iter visitExpression - - | SynExpr.LetOrUse(_, _, bindings, body, _) -> - // バインディングを走査 - // ('let .. = .. and .. = .. in ...' に対しては複数回走査されることがある) - printfn "以下のバインディングを含むLetOrUse:" - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, - data, pat, retInfo, init, m, sp)) = binding - visitPattern pat - visitExpression init - // 本体の式を走査 - printfn "本体は以下:" - visitExpression body - | expr -> printfn " - サポート対象外の式: %A" expr -(** -`visitExpression` 関数はモジュール内のすべてのトップレベル宣言を走査するような -関数から呼ばれることになります。 -今回のチュートリアルでは型やメンバーを無視していますが、 -これらを走査する場合も `visitExpression` を呼び出すことになるでしょう。 - -### 宣言を走査する - -既に説明したように、1つのファイルに対するASTには多数のモジュールや -名前空間の宣言が(トップレベルノードとして)含まれ、 -モジュール内にも(letバインディングや型の)宣言が、 -名前空間にも(こちらは単に型だけの)宣言が含まれます。 -以下の関数はそれぞれの宣言を走査します。 -ただし今回は型やネストされたモジュール、その他の要素については無視して、 -トップレベルの(値および関数に対する) `let` バインディングだけを対象にしています: -*) -/// モジュール内の宣言リストを走査する。 -/// モジュール内のトップレベルに記述できるすべての要素 -/// (letバインディングやネストされたモジュール、型の宣言など)が対象になる。 -let visitDeclarations decls = - for declaration in decls do - match declaration with - | SynModuleDecl.Let(isRec, bindings, range) -> - // 宣言としてのletバインディングは - // (visitExpressionで処理したような)式としてのletバインディングと - // 似ているが、本体を持たない - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, - data, pat, retInfo, body, m, sp)) = binding - visitPattern pat - visitExpression body - | _ -> printfn " - サポート対象外の宣言: %A" declaration -(** -`visitDeclarations` 関数はモジュールや名前空間の宣言のシーケンスを走査する -関数から呼ばれることになります。 -このシーケンスはたとえば複数の `namespace Foo` 宣言を含むようなファイルに対応します: -*) -/// すべてのモジュールや名前空間の宣言を走査する -/// (基本的には 'module Foo =' または 'namespace Foo.Bar' というコード) -/// なおファイル中で明示的に定義されていない場合であっても -/// 暗黙的にモジュールまたは名前空間の宣言が存在することに注意。 -let visitModulesAndNamespaces modulesOrNss = - for moduleOrNs in modulesOrNss do - let (SynModuleOrNamespace(lid, isRec, isMod, decls, xml, attrs, _, m)) = moduleOrNs - printfn "名前空間またはモジュール: %A" lid - visitDeclarations decls -(** -以上でASTの要素を(宣言から始まって式やパターンに至るまで)走査するための -関数がそろったので、サンプル入力からASTを取得した後、 -上記の関数を実行することができるようになりました。 - -すべてを組み合わせる --------------------- - -既に説明したように、 `getUntypedTree` 関数では `FSharpChecker` を使って -ASTに対する第1フェーズ(パース)を行ってツリーを返しています。 -この関数にはF#のソースコードとともに、ファイルのパスを指定する必要があります。 -(単に位置情報として利用されるだけなので) -指定先のパスにファイルが存在している必要はなく、 -UnixとWindowsどちらの形式でも指定できます: -*) -// コンパイラサービスへのサンプル入力 -let input = """ - let foo() = - let msg = "Hello world" - if true then - printfn "%s" msg """ -// Unix形式のファイル名 -let file = "/home/user/Test.fsx" - -// サンプルF#コードに対するASTを取得 -let tree = getUntypedTree(file, input) -(** -このコードをF# Interactiveで実行した場合、コンソールに `tree;;` と入力すると、 -データ構造に対する文字列表現が表示されることが確認できます。 -ツリーには大量の情報が含まれているため、あまり読みやすいものではありませんが、 -木が動作する様子を想像することはできるでしょう。 - -`tree` の返値はやはり判別共用体で、2つのケースに分かれます。 -1つはF#のシグネチャファイル( `*.fsi` )を表す `ParsedInput.SigFile` で、 -もう1つは通常のソースコード( `*.fsx` または `*.fs` )を表す -`ParsedInput.ImplFile` です。 -上記の手順で作成した関数に渡すことができるモジュールや名前空間のシーケンスは -実装ファイルに含まれています: -*) -// 実装ファイルの詳細をチェックする -match tree with -| ParsedInput.ImplFile(implFile) -> - // 宣言を展開してそれぞれを走査する - let (ParsedImplFileInput(fn, script, name, _, _, modules, _)) = implFile - visitModulesAndNamespaces modules -| _ -> failwith "F# インターフェイスファイル (*.fsi) は未サポートです。" -(** -まとめ ------- -このチュートリアルでは型無し抽象構文木に対する基本的な走査方法を紹介しました。 -このトピックは包括的なものであるため、1つの記事ですべてを説明することは不可能です。 -さらに深く理解するためには、型無しASTを活用するツールのよい例として -[Fantomas project](https://github.com/dungpa/fantomas) を参考にするとよいでしょう。 -実際には今回参照したような情報と、次のチュートリアルで説明する -[エディタサービス](editor.html) から得られる情報とを -組み合わせて利用することになるでしょう。 -*) diff --git a/fcs/docsrc/content/project.fsx b/fcs/docsrc/content/project.fsx deleted file mode 100644 index a537000435e..00000000000 --- a/fcs/docsrc/content/project.fsx +++ /dev/null @@ -1,374 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Project Analysis -================================== - -This tutorial demonstrates how to can analyze a whole project using services provided by the F# compiler. - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. - -*) - - -(** - -Getting whole-project results ------------------------------ - -As in the [previous tutorial (using untyped AST)](untypedtree.html), we start by referencing -`FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance -of `InteractiveChecker`: - -*) -// Reference F# compiler API -#r "FSharp.Compiler.Service.dll" -#r "FSharp.Compiler.Service.ProjectCracker.dll" - -open System -open System.Collections.Generic -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text - -// Create an interactive checker instance -let checker = FSharpChecker.Create() - -(** -Here are our sample inputs: -*) - -module Inputs = - open System.IO - - let base1 = Path.GetTempFileName() - let fileName1 = Path.ChangeExtension(base1, ".fs") - let base2 = Path.GetTempFileName() - let fileName2 = Path.ChangeExtension(base2, ".fs") - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") - let fileSource1 = """ -module M - -type C() = - member x.P = 1 - -let xxx = 3 + 4 -let fff () = xxx + xxx - """ - File.WriteAllText(fileName1, fileSource1) - - let fileSource2 = """ -module N - -open M - -type D1() = - member x.SomeProperty = M.xxx - -type D2() = - member x.SomeProperty = M.fff() + D1().P - -// Generate a warning -let y2 = match 1 with 1 -> M.xxx - """ - File.WriteAllText(fileName2, fileSource2) - - -(** -We use `GetProjectOptionsFromCommandLineArgs` to treat two files as a project: -*) - -let projectOptions = - let sysLib nm = - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then - // file references only valid on Windows - System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + - @"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" + nm + ".dll" - else - let sysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() - let (++) a b = System.IO.Path.Combine(a,b) - sysDir ++ nm + ".dll" - - let fsCore4300() = - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then - // file references only valid on Windows - System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) + - @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll" - else - sysLib "FSharp.Core" - - checker.GetProjectOptionsFromCommandLineArgs - (Inputs.projFileName, - [| yield "--simpleresolution" - yield "--noframework" - yield "--debug:full" - yield "--define:DEBUG" - yield "--optimize-" - yield "--out:" + Inputs.dllName - yield "--doc:test.xml" - yield "--warn:3" - yield "--fullpaths" - yield "--flaterrors" - yield "--target:library" - yield Inputs.fileName1 - yield Inputs.fileName2 - let references = - [ sysLib "mscorlib" - sysLib "System" - sysLib "System.Core" - fsCore4300() ] - for r in references do - yield "-r:" + r |]) - -(** -Now check the entire project (using the files saved on disk): -*) - -let wholeProjectResults = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously - -(** -Now look at the errors and warnings: -*) -wholeProjectResults .Errors.Length // 1 -wholeProjectResults.Errors.[0].Message.Contains("Incomplete pattern matches on this expression") // yes it does - -wholeProjectResults.Errors.[0].StartLineAlternate // 13 -wholeProjectResults.Errors.[0].EndLineAlternate // 13 -wholeProjectResults.Errors.[0].StartColumn // 15 -wholeProjectResults.Errors.[0].EndColumn // 16 - -(** -Now look at the inferred signature for the project: -*) -[ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] // ["N"; "M"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] // ["D1"; "D2"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[1].NestedEntities -> x.DisplayName ] // ["C"] -[ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] // ["y"; "y2"] - -(** -You can also get all symbols in the project: -*) -let rec allSymbolsInEntities (entities: IList) = - [ for e in entities do - yield (e :> FSharpSymbol) - for x in e.MembersFunctionsAndValues do - yield (x :> FSharpSymbol) - for x in e.UnionCases do - yield (x :> FSharpSymbol) - for x in e.FSharpFields do - yield (x :> FSharpSymbol) - yield! allSymbolsInEntities e.NestedEntities ] - -let allSymbols = allSymbolsInEntities wholeProjectResults.AssemblySignature.Entities -(** -After checking the whole project, you can access the background results for individual files -in the project. This will be fast and will not involve any additional checking. -*) - -let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Inputs.fileName1, projectOptions) - |> Async.RunSynchronously - - -(** -You can now resolve symbols in each file: -*) - -let xSymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) - |> Async.RunSynchronously - -let xSymbolUse = xSymbolUseOpt.Value - -let xSymbol = xSymbolUse.Symbol - -(** -You can find out more about a symbol by doing type checks on various symbol kinds: -*) - -let xSymbolAsValue = - match xSymbol with - | :? FSharpMemberOrFunctionOrValue as xSymbolAsVal -> xSymbolAsVal - | _ -> failwith "we expected this to be a member, function or value" - - -(** -For each symbol, you can look up the references to that symbol: -*) -let usesOfXSymbol = - wholeProjectResults.GetUsesOfSymbol(xSymbol) - |> Async.RunSynchronously - -(** -You can iterate all the defined symbols in the inferred signature and find where they are used: -*) -let allUsesOfAllSignatureSymbols = - [ for s in allSymbols do - let uses = wholeProjectResults.GetUsesOfSymbol(s) |> Async.RunSynchronously - yield s.ToString(), uses ] - -(** -You can also look at all the symbols uses in the whole project (including uses of symbols with local scope) -*) -let allUsesOfAllSymbols = - wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - -(** -You can also request checks of updated versions of files within the project (note that the other files -in the project are still read from disk, unless you are using the [FileSystem API](filesystem.html)): - -*) - -let parseResults1, checkAnswer1 = - checker.ParseAndCheckFileInProject(Inputs.fileName1, 0, SourceText.ofString Inputs.fileSource1, projectOptions) - |> Async.RunSynchronously - -let checkResults1 = - match checkAnswer1 with - | FSharpCheckFileAnswer.Succeeded x -> x - | _ -> failwith "unexpected aborted" - -let parseResults2, checkAnswer2 = - checker.ParseAndCheckFileInProject(Inputs.fileName2, 0, SourceText.ofString Inputs.fileSource2, projectOptions) - |> Async.RunSynchronously - -let checkResults2 = - match checkAnswer2 with - | FSharpCheckFileAnswer.Succeeded x -> x - | _ -> failwith "unexpected aborted" - -(** -Again, you can resolve symbols and ask for references: -*) - -let xSymbolUse2Opt = - checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) - |> Async.RunSynchronously - -let xSymbolUse2 = xSymbolUse2Opt.Value - -let xSymbol2 = xSymbolUse2.Symbol - -let usesOfXSymbol2 = - wholeProjectResults.GetUsesOfSymbol(xSymbol2) - |> Async.RunSynchronously - - -(** -Or ask for all the symbols uses in the file (including uses of symbols with local scope) -*) -let allUsesOfAllSymbolsInFile1 = - checkResults1.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - -(** -Or ask for all the uses of one symbol in one file: -*) -let allUsesOfXSymbolInFile1 = - checkResults1.GetUsesOfSymbolInFile(xSymbol2) - |> Async.RunSynchronously - -let allUsesOfXSymbolInFile2 = - checkResults2.GetUsesOfSymbolInFile(xSymbol2) - |> Async.RunSynchronously - -(** - -Analyzing multiple projects ------------------------------ - -If you have multiple F# projects to analyze which include references from some projects to others, -then the simplest way to do this is to build the projects and specify the cross-project references using -a `-r:path-to-output-of-project.dll` argument in the ProjectOptions. However, this requires the build -of each project to succeed, producing the DLL file on disk which can be referred to. - -In some situations, e.g. in an IDE, you may wish to allow references to other F# projects prior to successful compilation to -a DLL. To do this, fill in the ProjectReferences entry in ProjectOptions, which recursively specifies the project -options for dependent projects. Each project reference still needs a corresponding `-r:path-to-output-of-project.dll` -command line argument in ProjectOptions, along with an entry in ProjectReferences. -The first element of each tuple in the ProjectReferences entry should be the DLL name, i.e. `path-to-output-of-project.dll`. -This should be the same as the text used in the `-r` project reference. - -When a project reference is used, the analysis will make use of the results of incremental -analysis of the referenced F# project from source files, without requiring the compilation of these files to DLLs. - -To efficiently analyze a set of F# projects which include cross-references, you should populate the ProjectReferences -correctly and then analyze each project in turn. - -*) - -(** - -> **NOTE:** Project references are disabled if the assembly being referred to contains type provider components - - specifying the project reference will have no effect beyond forcing the analysis of the project, and the DLL will - still be required on disk. - -*) - -(** -Cracking a legacy project file ------------------------------ - -F# projects normally use the '.fsproj' project file format. -A project cracking facility for legacy old-style .fsproj is provided as a separate NuGet package: -FSharp.Compiler.Service.ProjectCracker. - -Project cracking for modern project files should be done using a library such as DotNetProjInfo. -See FsAutoComplete for example code. - -The legacy NuGet package `FSharp.Compiler.Service.ProjectCracker` contains a -library `FSharp.Compiler.Service.ProjectCracker.dll`, which should be -referenced by your application directly, and an executable -`FSharp.Compiler.Service.ProjectCrackerTool.exe`, which should be copied -into the output folder of your application by the build process. If -you install using Paket or NuGet, then this will be configured for you -automatically. If not, you should reference the provided `.targets` -file manually in your application. This can be found in the NuGet -package at `build/net461/FSharp.Compiler.Service.ProjectCrackerTool.targets`. - -The reason for this split was so the analysis of an F# project -file is performed out of process, in order that the necessary assembly -binding redirects can be applied without requiring the caller to -arrange this. In this way MSBuild versions from 4 up to 14 can be -accommodated transparently. - -In this example we get the project options for one of the -project files in the F# Compiler Service project itself - you should also be able to use this technique -for any project that builds cleanly using the command line tools 'xbuild' or 'msbuild'. - - -*) - -let projectFile = __SOURCE_DIRECTORY__ + @"/../../src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj" - -ProjectCracker.GetProjectOptionsFromProjectFile(projectFile) - - -(** - -You can also request RELEASE mode and set other build configuration parameters: - -*) - -ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Release")]) - -(** - -For debugging purposes it is also possible to obtain a detailed log from the assembly resolution process. - -*) - -let options, logs = ProjectCracker.GetProjectOptionsFromProjectFileLogged(projectFile, [("Configuration", "Release")]) - -(** -Summary -------- - -As you have seen, the `ParseAndCheckProject` lets you access results of project-wide analysis -such as symbol references. To learn more about working with symbols, see [Symbols](symbols.html). - -Using the FSharpChecker component in multi-project, incremental and interactive editing situations may involve -knowledge of the [FSharpChecker operations queue](queue.html) and the [FSharpChecker caches](caches.html). - -*) diff --git a/fcs/docsrc/content/queue.fsx b/fcs/docsrc/content/queue.fsx deleted file mode 100644 index 7cf14a7b709..00000000000 --- a/fcs/docsrc/content/queue.fsx +++ /dev/null @@ -1,60 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Notes on the FSharpChecker operations queue -================================================= - -This is a design note on the FSharpChecker component and its operations queue. See also the notes on the [FSharpChecker caches](caches.html) - -FSharpChecker maintains an operations queue. Items from the FSharpChecker operations queue are processed -sequentially and in order. - -The thread processing these requests can also run a low-priority, interleaved background operation when the -queue is empty. This can be used to implicitly bring the background check of a project "up-to-date". -When the operations queue has been empty for 1 second, -this background work is run in small incremental fragments. This work is cooperatively time-sliced to be approximately <50ms, (see `maxTimeShareMilliseconds` in -IncrementalBuild.fs). The project to be checked in the background is set implicitly -by calls to ``CheckFileInProject`` and ``ParseAndCheckFileInProject``. -To disable implicit background checking completely, set ``checker.ImplicitlyStartBackgroundWork`` to false. -To change the time before background work starts, set ``checker.PauseBeforeBackgroundWork`` to the required number of milliseconds. - -Most calls to the FSharpChecker API enqueue an operation in the FSharpChecker compiler queue. These correspond to the -calls to EnqueueAndAwaitOpAsync in [service.fs](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/service/service.fs). - -* For example, calling `ParseAndCheckProject` enqueues a `ParseAndCheckProjectImpl` operation. The time taken for the - operation will depend on how much work is required to bring the project analysis up-to-date. - -* Likewise, calling any of `GetUsesOfSymbol`, `GetAllUsesOfAllSymbols`, `ParseFileInProject`, - `GetBackgroundParseResultsForFileInProject`, `MatchBraces`, `CheckFileInProjectIfReady`, `ParseAndCheckFileInProject`, `GetBackgroundCheckResultsForFileInProject`, - `ParseAndCheckProject`, `GetProjectOptionsFromScript`, `InvalidateConfiguration`, `InvaidateAll` and operations - on FSharpCheckResults will cause an operation to be enqueued. The length of the operation will - vary - many will be very fast - but they won't be processed until other operations already in the queue are complete. - -Some operations do not enqueue anything on the FSharpChecker operations queue - notably any accesses to the Symbol APIs. -These use cross-threaded access to the TAST data produced by other FSharpChecker operations. - -Some tools throw a lot of interactive work at the FSharpChecker operations queue. -If you are writing such a component, consider running your project against a debug build -of FSharp.Compiler.Service.dll to see the Trace.WriteInformation messages indicating the length of the -operations queue and the time to process requests. - -For those writing interactive editors which use FCS, you -should be cautious about operations that request a check of the entire project. -For example, be careful about requesting the check of an entire project -on operations like "Highlight Symbol" or "Find Unused Declarations" -(which run automatically when the user opens a file or moves the cursor). -as opposed to operations like "Find All References" (which a user explicitly triggers). -Project checking can cause long and contention on the FSharpChecker operations queue. - -Requests to FCS can be cancelled by cancelling the async operation. (Some requests also -include additional callbacks which can be used to indicate a cancellation condition). -This cancellation will be effective if the cancellation is performed before the operation -is executed in the operations queue. - -Summary -------- - -In this design note, you learned that the FSharpChecker component keeps an operations queue. When using FSharpChecker -in highly interactive situations, you should carefully consider the characteristics of the operations you are -enqueueing. -*) diff --git a/fcs/docsrc/content/symbols.fsx b/fcs/docsrc/content/symbols.fsx deleted file mode 100644 index ab6b4657dcf..00000000000 --- a/fcs/docsrc/content/symbols.fsx +++ /dev/null @@ -1,224 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Working with symbols -============================================ - -This tutorial demonstrates how to work with symbols provided by the F# compiler. See also [project wide analysis](project.html) -for information on symbol references. - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published. - -As usual we start by referencing `FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance -of `FSharpChecker`: - -*) -// Reference F# compiler API -#r "FSharp.Compiler.Service.dll" - -open System -open System.IO -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text - -// Create an interactive checker instance -let checker = FSharpChecker.Create() - -(** - -We now perform type checking on the specified input: - -*) - -let parseAndTypeCheckSingleFile (file, input) = - // Get context representing a stand-alone (script) file - let projOptions, errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - let parseFileResults, checkFileResults = - checker.ParseAndCheckFileInProject(file, 0, input, projOptions) - |> Async.RunSynchronously - - // Wait until type checking succeeds (or 100 attempts) - match checkFileResults with - | FSharpCheckFileAnswer.Succeeded(res) -> parseFileResults, res - | res -> failwithf "Parsing did not finish... (%A)" res - -let file = "/home/user/Test.fsx" - -(** -## Getting resolved signature information about the file - -After type checking a file, you can access the inferred signature of a project up to and including the -checking of the given file through the `PartialAssemblySignature` property of the `TypeCheckResults`. - -The full signature information is available for modules, types, attributes, members, values, functions, -union cases, record types, units of measure and other F# language constructs. - -The typed expression trees are also available, see [typed tree tutorial](typedtree.html). - -*) - -let input2 = - """ -[] -let foo(x, y) = - let msg = String.Concat("Hello"," ","world") - if true then - printfn "x = %d, y = %d" x y - printfn "%s" msg - -type C() = - member x.P = 1 - """ -let parseFileResults, checkFileResults = - parseAndTypeCheckSingleFile(file, SourceText.ofString input2) - -(** -Now get the partial assembly signature for the code: -*) -let partialAssemblySignature = checkFileResults.PartialAssemblySignature - -partialAssemblySignature.Entities.Count = 1 // one entity - - -(** -Now get the entity that corresponds to the module containing the code: -*) -let moduleEntity = partialAssemblySignature.Entities.[0] - -moduleEntity.DisplayName = "Test" - -(** -Now get the entity that corresponds to the type definition in the code: -*) -let classEntity = moduleEntity.NestedEntities.[0] - -(** -Now get the value that corresponds to the function defined in the code: -*) -let fnVal = moduleEntity.MembersFunctionsAndValues.[0] - -(** -Now look around at the properties describing the function value. All of the following evaluate to `true`: -*) -fnVal.Attributes.Count = 1 -fnVal.CurriedParameterGroups.Count // 1 -fnVal.CurriedParameterGroups.[0].Count // 2 -fnVal.CurriedParameterGroups.[0].[0].Name // "x" -fnVal.CurriedParameterGroups.[0].[1].Name // "y" -fnVal.DeclarationLocation.StartLine // 3 -fnVal.DisplayName // "foo" -fnVal.DeclaringEntity.Value.DisplayName // "Test" -fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1 -fnVal.GenericParameters.Count // 0 -fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline -fnVal.IsActivePattern // false -fnVal.IsCompilerGenerated // false -fnVal.IsDispatchSlot // false -fnVal.IsExtensionMember // false -fnVal.IsPropertyGetterMethod // false -fnVal.IsImplicitConstructor // false -fnVal.IsInstanceMember // false -fnVal.IsMember // false -fnVal.IsModuleValueOrMember // true -fnVal.IsMutable // false -fnVal.IsPropertySetterMethod // false -fnVal.IsTypeFunction // false - -(** -Now look at the type of the function if used as a first class value. (Aside: the `CurriedParameterGroups` property contains -more information like the names of the arguments.) -*) -fnVal.FullType // int * int -> unit -fnVal.FullType.IsFunctionType // int * int -> unit -fnVal.FullType.GenericArguments.[0] // int * int -fnVal.FullType.GenericArguments.[0].IsTupleType // int * int -let argTy1 = fnVal.FullType.GenericArguments.[0].GenericArguments.[0] - -argTy1.TypeDefinition.DisplayName // int - -(** -OK, so we got an object representation of the type `int * int -> unit`, and we have seen the first 'int'. We can find out more about the -type 'int' as follows, determining that it is a named type, which is an F# type abbreviation, `type int = int32`: -*) - -argTy1.HasTypeDefinition -argTy1.TypeDefinition.IsFSharpAbbreviation // "int" - -(** -We can now look at the right-hand-side of the type abbreviation, which is the type `int32`: -*) - -let argTy1b = argTy1.TypeDefinition.AbbreviatedType -argTy1b.TypeDefinition.Namespace // Some "Microsoft.FSharp.Core" -argTy1b.TypeDefinition.CompiledName // "int32" - -(** -Again we can now look through the type abbreviation `type int32 = System.Int32` to get the -full information about the type: -*) -let argTy1c = argTy1b.TypeDefinition.AbbreviatedType -argTy1c.TypeDefinition.Namespace // Some "SystemCore" -argTy1c.TypeDefinition.CompiledName // "Int32" - -(** -The type checking results for a file also contain information extracted from the project (or script) options -used in the compilation, called the `ProjectContext`: -*) -let projectContext = checkFileResults.ProjectContext - -for assembly in projectContext.GetReferencedAssemblies() do - match assembly.FileName with - | None -> printfn "compilation referenced an assembly without a file" - | Some s -> printfn "compilation references assembly '%s'" s - - -(** -**Notes:** - - - If incomplete code is present, some or all of the attributes may not be quite as expected. - - If some assembly references are missing (which is actually very, very common), then 'IsUnresolved' may - be true on values, members and/or entities related to external assemblies. You should be sure to make your - code robust against IsUnresolved exceptions. - -*) - -(** - -## Getting symbolic information about whole projects - -To check whole projects, create a checker, then call `parseAndCheckScript`. In this case, we just check -the project for a single script. By specifying a different "projOptions" you can create -a specification of a larger project. -*) -let parseAndCheckScript (file, input) = - let projOptions, errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - checker.ParseAndCheckProject(projOptions) |> Async.RunSynchronously - -(** -Now do it for a particular input: -*) - -let tmpFile = Path.ChangeExtension(System.IO.Path.GetTempFileName() , "fs") -File.WriteAllText(tmpFile, input2) - -let projectResults = parseAndCheckScript(tmpFile, input2) - - -(** -Now look at the results: -*) - -let assemblySig = projectResults.AssemblySignature - -assemblySig.Entities.Count = 1 // one entity -assemblySig.Entities.[0].Namespace // one entity -assemblySig.Entities.[0].DisplayName // "Tmp28D0" -assemblySig.Entities.[0].MembersFunctionsAndValues.Count // 1 -assemblySig.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "foo" - diff --git a/fcs/docsrc/content/tokenizer.fsx b/fcs/docsrc/content/tokenizer.fsx deleted file mode 100644 index 93a1dd3bf16..00000000000 --- a/fcs/docsrc/content/tokenizer.fsx +++ /dev/null @@ -1,131 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Using the F# tokenizer -========================================= - -This tutorial demonstrates how to call the F# language tokenizer. Given F# -source code, the tokenizer generates a list of source code lines that contain -information about tokens on each line. For each token, you can get the type -of the token, exact location as well as color kind of the token (keyword, -identifier, number, operator, etc.). - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published - - -Creating the tokenizer ---------------------- - -To use the tokenizer, reference `FSharp.Compiler.Service.dll` and open the -`SourceCodeServices` namespace: -*) -#r "FSharp.Compiler.Service.dll" -open FSharp.Compiler.SourceCodeServices -(** -Now you can create an instance of `FSharpSourceTokenizer`. The class takes two -arguments - the first is the list of defined symbols and the second is the -file name of the source code. The defined symbols are required because the -tokenizer handles `#if` directives. The file name is required only to specify -locations of the source code (and it does not have to exist): -*) -let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") -(** -Using the `sourceTok` object, we can now (repeatedly) tokenize lines of -F# source code. - -Tokenizing F# code ------------------- - -The tokenizer operates on individual lines rather than on the entire source -file. After getting a token, the tokenizer also returns new state (as `int64` value). -This can be used to tokenize F# code more efficiently. When source code changes, -you do not need to re-tokenize the entire file - only the parts that have changed. - -### Tokenizing single line - -To tokenize a single line, we create a `FSharpLineTokenizer` by calling `CreateLineTokenizer` -on the `FSharpSourceTokenizer` object that we created earlier: -*) -let tokenizer = sourceTok.CreateLineTokenizer("let answer=42") -(** -Now, we can write a simple recursive function that calls `ScanToken` on the `tokenizer` -until it returns `None` (indicating the end of line). When the function succeeds, it -returns `FSharpTokenInfo` object with all the interesting details: -*) -/// Tokenize a single line of F# code -let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = - match tokenizer.ScanToken(state) with - | Some tok, state -> - // Print token name - printf "%s " tok.TokenName - // Tokenize the rest, in the new state - tokenizeLine tokenizer state - | None, state -> state -(** -The function returns the new state, which is needed if you need to tokenize multiple lines -and an earlier line ends with a multi-line comment. As an initial state, we can use `0L`: -*) -tokenizeLine tokenizer FSharpTokenizerLexState.Initial -(** -The result is a sequence of tokens with names LET, WHITESPACE, IDENT, EQUALS and INT32. -There is a number of interesting properties on `FSharpTokenInfo` including: - - - `CharClass` and `ColorClass` return information about the token category that - can be used for colorizing F# code. - - `LeftColumn` and `RightColumn` return the location of the token inside the line. - - `TokenName` is the name of the token (as defined in the F# lexer) - -Note that the tokenizer is stateful - if you want to tokenize single line multiple times, -you need to call `CreateLineTokenizer` again. - -### Tokenizing sample code - -To run the tokenizer on a longer sample code or an entire file, you need to read the -sample input as a collection of `string` values: -*) -let lines = """ - // Hello world - let hello() = - printfn "Hello world!" """.Split('\r','\n') -(** -To tokenize multi-line input, we again need a recursive function that keeps the current -state. The following function takes the lines as a list of strings (together with line number -and the current state). We create a new tokenizer for each line and call `tokenizeLine` -using the state from the *end* of the previous line: -*) -/// Print token names for multiple lines of code -let rec tokenizeLines state count lines = - match lines with - | line::lines -> - // Create tokenizer & tokenize single line - printfn "\nLine %d" count - let tokenizer = sourceTok.CreateLineTokenizer(line) - let state = tokenizeLine tokenizer state - // Tokenize the rest using new state - tokenizeLines state (count+1) lines - | [] -> () -(** -The function simply calls `tokenizeLine` (defined earlier) to print the names of all -the tokens on each line. We can call it on the previous input with `0L` as the initial -state and `1` as the number of the first line: -*) -lines -|> List.ofSeq -|> tokenizeLines FSharpTokenizerLexState.Initial 1 -(** -Ignoring some unimportant details (like whitespace at the beginning of each line and -the first line which is just whitespace), the code generates the following output: - - [lang=text] - Line 1 - LINE_COMMENT LINE_COMMENT (...) LINE_COMMENT - Line 2 - LET WHITESPACE IDENT LPAREN RPAREN WHITESPACE EQUALS - Line 3 - IDENT WHITESPACE STRING_TEXT (...) STRING_TEXT STRING - -It is worth noting that the tokenizer yields multiple `LINE_COMMENT` tokens and multiple -`STRING_TEXT` tokens for each single comment or string (roughly, one for each word), so -if you want to get the entire text of a comment/string, you need to concatenate the -tokens. -*) \ No newline at end of file diff --git a/fcs/docsrc/content/typedtree.fsx b/fcs/docsrc/content/typedtree.fsx deleted file mode 100644 index 385822335e9..00000000000 --- a/fcs/docsrc/content/typedtree.fsx +++ /dev/null @@ -1,306 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Processing typed expression tree -================================================= - -This tutorial demonstrates how to get the checked, typed expressions tree (TAST) -for F# code and how to walk over the tree. - -This can be used for creating tools such as source code analyzers and refactoring tools. -You can also combine the information with the API available -from [symbols](symbols.html). - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published - - -Getting checked expressions ------------------------ - -To access the type-checked, resolved expressions, you need to create an instance of `InteractiveChecker`. - -To use the interactive checker, reference `FSharp.Compiler.Service.dll` and open the -`SourceCodeServices` namespace: -*) -#r "FSharp.Compiler.Service.dll" -open System -open System.IO -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text -(** - -### Checking code - -We first parse and check some code as in the [symbols](symbols.html) tutorial. -One difference is that we set keepAssemblyContents to true. - -*) -// Create an interactive checker instance -let checker = FSharpChecker.Create(keepAssemblyContents=true) - -let parseAndCheckSingleFile (input) = - let file = Path.ChangeExtension(System.IO.Path.GetTempFileName(), "fsx") - File.WriteAllText(file, input) - // Get context representing a stand-alone (script) file - let projOptions, _errors = - checker.GetProjectOptionsFromScript(file, SourceText.ofString input) - |> Async.RunSynchronously - - checker.ParseAndCheckProject(projOptions) - |> Async.RunSynchronously - -(** -## Getting the expressions - -After type checking a file, you can access the declarations and contents of the assembly, including expressions: - -*) - -let input2 = - """ -module MyLibrary - -open System - -let foo(x, y) = - let msg = String.Concat("Hello", " ", "world") - if msg.Length > 10 then - 10 - else - 20 - -type MyClass() = - member x.MyMethod() = 1 - """ -let checkProjectResults = - parseAndCheckSingleFile(input2) - -checkProjectResults.Errors // should be empty - - -(** - -Checked assemblies are made up of a series of checked implementation files. The "file" granularity -matters in F# because initialization actions are triggered at the granularity of files. -In this case there is only one implementation file in the project: - -*) - -let checkedFile = checkProjectResults.AssemblyContents.ImplementationFiles.[0] - -(** - -Checked assemblies are made up of a series of checked implementation files. The "file" granularity -matters in F# because initialization actions are triggered at the granularity of files. -In this case there is only one implementation file in the project: - -*) - -let rec printDecl prefix d = - match d with - | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> - printfn "%sEntity %s was declared and contains %d sub-declarations" prefix e.CompiledName subDecls.Length - for subDecl in subDecls do - printDecl (prefix+" ") subDecl - | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> - printfn "%sMember or value %s was declared" prefix v.CompiledName - | FSharpImplementationFileDeclaration.InitAction(e) -> - printfn "%sA top-level expression was declared" prefix - - -for d in checkedFile.Declarations do - printDecl "" d - -// Entity MyLibrary was declared and contains 4 sub-declarations -// Member or value foo was declared -// Entity MyClass was declared and contains 0 sub-declarations -// Member or value .ctor was declared -// Member or value MyMethod was declared - -(** - -As can be seen, the only declaration in the implementation file is that of the module MyLibrary, which -contains fours sub-declarations. - -> As an aside, one peculiarity here is that the member declarations (e.g. the "MyMethod" member) are returned as part of the containing module entity, not as part of their class. - -> Note that the class constructor is returned as a separate declaration. The class type definition has been "split" into a constructor and the other declarations. - -*) - -let myLibraryEntity, myLibraryDecls = - match checkedFile.Declarations.[0] with - | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> (e, subDecls) - | _ -> failwith "unexpected" - - -(** - -What about the expressions, for example the body of function "foo"? Let's find it: -*) - -let (fooSymbol, fooArgs, fooExpression) = - match myLibraryDecls.[0] with - | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> (v, vs, e) - | _ -> failwith "unexpected" - - -(** Here 'fooSymbol' is a symbol associated with the declaration of 'foo', -'fooArgs' represents the formal arguments to the 'foo' function, and 'fooExpression' -is an expression for the implementation of the 'foo' function. - -Once you have an expression, you can work with it much like an F# quotation. For example, -you can find its declaration range and its type: - -*) - -fooExpression.Type // shows that the return type of the body expression is 'int' -fooExpression.Range // shows the declaration range of the expression implementing 'foo' - -(** - -### Walking over expressions - - -Expressions are analyzed using active patterns, much like F# quotations. -Here is a generic expression visitor: - -*) - -let rec visitExpr f (e:FSharpExpr) = - f e - match e with - | BasicPatterns.AddressOf(lvalueExpr) -> - visitExpr f lvalueExpr - | BasicPatterns.AddressSet(lvalueExpr, rvalueExpr) -> - visitExpr f lvalueExpr; visitExpr f rvalueExpr - | BasicPatterns.Application(funcExpr, typeArgs, argExprs) -> - visitExpr f funcExpr; visitExprs f argExprs - | BasicPatterns.Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) -> - visitObjArg f objExprOpt; visitExprs f argExprs - | BasicPatterns.Coerce(targetType, inpExpr) -> - visitExpr f inpExpr - | BasicPatterns.FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp) -> - visitExpr f startExpr; visitExpr f limitExpr; visitExpr f consumeExpr - | BasicPatterns.ILAsm(asmCode, typeArgs, argExprs) -> - visitExprs f argExprs - | BasicPatterns.ILFieldGet (objExprOpt, fieldType, fieldName) -> - visitObjArg f objExprOpt - | BasicPatterns.ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) -> - visitObjArg f objExprOpt - | BasicPatterns.IfThenElse (guardExpr, thenExpr, elseExpr) -> - visitExpr f guardExpr; visitExpr f thenExpr; visitExpr f elseExpr - | BasicPatterns.Lambda(lambdaVar, bodyExpr) -> - visitExpr f bodyExpr - | BasicPatterns.Let((bindingVar, bindingExpr), bodyExpr) -> - visitExpr f bindingExpr; visitExpr f bodyExpr - | BasicPatterns.LetRec(recursiveBindings, bodyExpr) -> - List.iter (snd >> visitExpr f) recursiveBindings; visitExpr f bodyExpr - | BasicPatterns.NewArray(arrayType, argExprs) -> - visitExprs f argExprs - | BasicPatterns.NewDelegate(delegateType, delegateBodyExpr) -> - visitExpr f delegateBodyExpr - | BasicPatterns.NewObject(objType, typeArgs, argExprs) -> - visitExprs f argExprs - | BasicPatterns.NewRecord(recordType, argExprs) -> - visitExprs f argExprs - | BasicPatterns.NewAnonRecord(recordType, argExprs) -> - visitExprs f argExprs - | BasicPatterns.NewTuple(tupleType, argExprs) -> - visitExprs f argExprs - | BasicPatterns.NewUnionCase(unionType, unionCase, argExprs) -> - visitExprs f argExprs - | BasicPatterns.Quote(quotedExpr) -> - visitExpr f quotedExpr - | BasicPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> - visitObjArg f objExprOpt - | BasicPatterns.AnonRecordGet(objExpr, recordOrClassType, fieldInfo) -> - visitExpr f objExpr - | BasicPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) -> - visitObjArg f objExprOpt; visitExpr f argExpr - | BasicPatterns.Sequential(firstExpr, secondExpr) -> - visitExpr f firstExpr; visitExpr f secondExpr - | BasicPatterns.TryFinally(bodyExpr, finalizeExpr) -> - visitExpr f bodyExpr; visitExpr f finalizeExpr - | BasicPatterns.TryWith(bodyExpr, _, _, catchVar, catchExpr) -> - visitExpr f bodyExpr; visitExpr f catchExpr - | BasicPatterns.TupleGet(tupleType, tupleElemIndex, tupleExpr) -> - visitExpr f tupleExpr - | BasicPatterns.DecisionTree(decisionExpr, decisionTargets) -> - visitExpr f decisionExpr; List.iter (snd >> visitExpr f) decisionTargets - | BasicPatterns.DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) -> - visitExprs f decisionTargetExprs - | BasicPatterns.TypeLambda(genericParam, bodyExpr) -> - visitExpr f bodyExpr - | BasicPatterns.TypeTest(ty, inpExpr) -> - visitExpr f inpExpr - | BasicPatterns.UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) -> - visitExpr f unionExpr; visitExpr f valueExpr - | BasicPatterns.UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> - visitExpr f unionExpr - | BasicPatterns.UnionCaseTest(unionExpr, unionType, unionCase) -> - visitExpr f unionExpr - | BasicPatterns.UnionCaseTag(unionExpr, unionType) -> - visitExpr f unionExpr - | BasicPatterns.ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) -> - visitExpr f baseCallExpr - List.iter (visitObjMember f) overrides - List.iter (snd >> List.iter (visitObjMember f)) interfaceImplementations - | BasicPatterns.TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) -> - visitExprs f argExprs - | BasicPatterns.ValueSet(valToSet, valueExpr) -> - visitExpr f valueExpr - | BasicPatterns.WhileLoop(guardExpr, bodyExpr) -> - visitExpr f guardExpr; visitExpr f bodyExpr - | BasicPatterns.BaseValue baseType -> () - | BasicPatterns.DefaultValue defaultType -> () - | BasicPatterns.ThisValue thisType -> () - | BasicPatterns.Const(constValueObj, constType) -> () - | BasicPatterns.Value(valueToGet) -> () - | _ -> failwith (sprintf "unrecognized %+A" e) - -and visitExprs f exprs = - List.iter (visitExpr f) exprs - -and visitObjArg f objOpt = - Option.iter (visitExpr f) objOpt - -and visitObjMember f memb = - visitExpr f memb.Body - -(** -Let's use this expresssion walker: - -*) -fooExpression |> visitExpr (fun e -> printfn "Visiting %A" e) - -// Prints: -// -// Visiting Let... -// Visiting Call... -// Visiting Const ("Hello", ...) -// Visiting Const (" ", ...) -// Visiting Const ("world", ...) -// Visiting IfThenElse... -// Visiting Call... -// Visiting Call... -// Visiting Value ... -// Visiting Const ... -// Visiting Const ... -// Visiting Const ... - -(** -Note that - -* The visitExpr function is recursive (for nested expressions). - -* Pattern matching is removed from the tree, into a form called 'decision trees'. - -Summary -------- -In this tutorial, we looked at basic of working with checked declarations and expressions. - -In practice, it is also useful to combine the information here -with some information you can obtain from the [symbols](symbols.html) -tutorial. -*) diff --git a/fcs/docsrc/content/untypedtree.fsx b/fcs/docsrc/content/untypedtree.fsx deleted file mode 100644 index 162fedfa196..00000000000 --- a/fcs/docsrc/content/untypedtree.fsx +++ /dev/null @@ -1,245 +0,0 @@ -(*** hide ***) -#I "../../../artifacts/bin/fcs/net461" -(** -Compiler Services: Processing untyped syntax tree -================================================= - -This tutorial demonstrates how to get the untyped abstract syntax tree (AST) -for F# code and how to walk over the tree. This can be used for creating tools -such as code formatter, basic refactoring or code navigation tools. The untyped -syntax tree contains information about the code structure, but does not contain -types and there are some ambiguities that are resolved only later by the type -checker. You can also combine the untyped AST information with the API available -from [editor services](editor.html). - -> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published - - -Getting the untyped AST ------------------------ - -To access the untyped AST, you need to create an instance of `FSharpChecker`. -This type represents a context for type checking and parsing and corresponds either -to a stand-alone F# script file (e.g. opened in Visual Studio) or to a loaded project -file with multiple files. Once you have an instance of `FSharpChecker`, you can -use it to perform "untyped parse" which is the first step of type-checking. The -second phase is "typed parse" and is used by [editor services](editor.html). - -To use the interactive checker, reference `FSharp.Compiler.Service.dll` and open the -`SourceCodeServices` namespace: -*) -#r "FSharp.Compiler.Service.dll" -open System -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Text -(** - -### Performing untyped parse - -The untyped parse operation is very fast (compared to type checking, which can -take notable amount of time) and so we can perform it synchronously. First, we -need to create `FSharpChecker` - the constructor takes an argument that -can be used to notify the checker about file changes (which we ignore). - -*) -// Create an interactive checker instance -let checker = FSharpChecker.Create() -(** - -To get the AST, we define a function that takes file name and the source code -(the file is only used for location information and does not have to exist). -We first need to get "interactive checker options" which represents the context. -For simple tasks, you can use `GetProjectOptionsFromScriptRoot` which infers -the context for a script file. Then we use the `ParseFile` method and -return the `ParseTree` property: - -*) -/// Get untyped tree for a specified input -let getUntypedTree (file, input) = - // Get compiler options for the 'project' implied by a single script file - let projOptions, errors = - checker.GetProjectOptionsFromScript(file, input) - |> Async.RunSynchronously - - let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions) - - // Run the first phase (untyped parsing) of the compiler - let parseFileResults = - checker.ParseFile(file, input, parsingOptions) - |> Async.RunSynchronously - - match parseFileResults.ParseTree with - | Some tree -> tree - | None -> failwith "Something went wrong during parsing!" - -(** - -Walking over the AST --------------------- - -The abstract syntax tree is defined as a number of discriminated unions that represent -different syntactical elements (such as expressions, patterns, declarations etc.). The best -way to understand the AST is to look at the definitions in [`ast.fs` in the source -code](https://github.com/fsharp/fsharp/blob/master/src/fsharp/ast.fs#L464). - -The relevant parts are in the following namespace: -*) -open FSharp.Compiler.Ast -(** - -When processing the AST, you will typically write a number of mutually recursive functions -that pattern match on the different syntactical elements. There is a number of elements -that need to be supported - the top-level element is module or namespace declaration, -containing declarations inside a module (let bindings, types etc.). A let declaration inside -a module then contains expression, which can contain patterns. - -### Walking over patterns and expressions - -We start by looking at functions that walk over expressions and patterns - as we walk, -we print information about the visited elements. For patterns, the input is of type -`SynPat` and has a number of cases including `Wild` (for `_` pattern), `Named` (for -` as name`) and `LongIdent` (for a `Foo.Bar` name). Note that the parsed pattern -is occasionally more complex than what is in the source code (in particular, `Named` is -used more often): -*) -/// Walk over a pattern - this is for example used in -/// let = or in the 'match' expression -let rec visitPattern = function - | SynPat.Wild(_) -> - printfn " .. underscore pattern" - | SynPat.Named(pat, name, _, _, _) -> - visitPattern pat - printfn " .. named as '%s'" name.idText - | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> - let names = String.concat "." [ for i in ident -> i.idText ] - printfn " .. identifier: %s" names - | pat -> printfn " .. other pattern: %A" pat -(** -The function is recursive (for nested patterns such as `(foo, _) as bar`), but it does not -call any of the functions defined later (because patterns cannot contain other syntactical -elements). - -The next function iterates over expressions - this is where most of the work would be and -there are around 20 cases to cover (type `SynExpr.` and you'll get completion with other -options). In the following, we only show how to handle `if .. then ..` and `let .. = ...`: -*) -/// Walk over an expression - if expression contains two or three -/// sub-expressions (two if the 'else' branch is missing), let expression -/// contains pattern and two sub-expressions -let rec visitExpression = function - | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> - // Visit all sub-expressions - printfn "Conditional:" - visitExpression cond - visitExpression trueBranch - falseBranchOpt |> Option.iter visitExpression - - | SynExpr.LetOrUse(_, _, bindings, body, _) -> - // Visit bindings (there may be multiple - // for 'let .. = .. and .. = .. in ...' - printfn "LetOrUse with the following bindings:" - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, - data, pat, retInfo, init, m, sp)) = binding - visitPattern pat - visitExpression init - // Visit the body expression - printfn "And the following body:" - visitExpression body - | expr -> printfn " - not supported expression: %A" expr -(** -The `visitExpression` function will be called from a function that visits all top-level -declarations inside a module. In this tutorial, we ignore types and members, but that would -be another source of calls to `visitExpression`. - -### Walking over declarations - -As mentioned earlier, the AST of a file contains a number of module or namespace declarations -(top-level node) that contain declarations inside a module (let bindings or types) or inside -a namespace (just types). The following functions walks over declarations - we ignore types, -nested modules and all other elements and look only at top-level `let` bindings (values and -functions): -*) -/// Walk over a list of declarations in a module. This is anything -/// that you can write as a top-level inside module (let bindings, -/// nested modules, type declarations etc.) -let visitDeclarations decls = - for declaration in decls do - match declaration with - | SynModuleDecl.Let(isRec, bindings, range) -> - // Let binding as a declaration is similar to let binding - // as an expression (in visitExpression), but has no body - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, - data, pat, retInfo, body, m, sp)) = binding - visitPattern pat - visitExpression body - | _ -> printfn " - not supported declaration: %A" declaration -(** -The `visitDeclarations` function will be called from a function that walks over a -sequence of module or namespace declarations. This corresponds, for example, to a file -with multiple `namespace Foo` declarations: -*) -/// Walk over all module or namespace declarations -/// (basically 'module Foo =' or 'namespace Foo.Bar') -/// Note that there is one implicitly, even if the file -/// does not explicitly define it.. -let visitModulesAndNamespaces modulesOrNss = - for moduleOrNs in modulesOrNss do - let (SynModuleOrNamespace(lid, isRec, isMod, decls, xml, attrs, _, m)) = moduleOrNs - printfn "Namespace or module: %A" lid - visitDeclarations decls -(** -Now that we have functions that walk over the elements of the AST (starting from declaration, -down to expressions and patterns), we can get AST of a sample input and run the above function. - -Putting things together ------------------------ - -As already discussed, the `getUntypedTree` function uses `FSharpChecker` to run the first -phase (parsing) on the AST and get back the tree. The function requires F# source code together -with location of the file. The location does not have to exist (it is used only for location -information) and it can be in both Unix and Windows formats: -*) -// Sample input for the compiler service -let input = - """ - let foo() = - let msg = "Hello world" - if true then - printfn "%s" msg - """ - -// File name in Unix format -let file = "/home/user/Test.fsx" - -// Get the AST of sample F# code -let tree = getUntypedTree(file, SourceText.ofString input) -(** -When you run the code in F# interactive, you can enter `tree;;` in the interactive console and -see pretty printed representation of the data structure - the tree contains a lot of information, -so this is not particularly readable, but it gives you good idea about how the tree looks. - -The returned `tree` value is again a discriminated union that can be two different cases - one case -is `ParsedInput.SigFile` which represents F# signature file (`*.fsi`) and the other one is -`ParsedInput.ImplFile` representing regular source code (`*.fsx` or `*.fs`). The implementation -file contains a sequence of modules or namespaces that we can pass to the function implemented -in the previous step: -*) -// Extract implementation file details -match tree with -| ParsedInput.ImplFile(implFile) -> - // Extract declarations and walk over them - let (ParsedImplFileInput(fn, script, name, _, _, modules, _)) = implFile - visitModulesAndNamespaces modules -| _ -> failwith "F# Interface file (*.fsi) not supported." -(** -Summary -------- -In this tutorial, we looked at basic of working with the untyped abstract syntax tree. This is a -comprehensive topic, so it is not possible to explain everything in a single article. The -[Fantomas project](https://github.com/dungpa/fantomas) is a good example of tool based on the untyped -AST that can help you understand more. In practice, it is also useful to combine the information here -with some information you can obtain from the [editor services](editor.html) discussed in the next -tutorial. -*) diff --git a/fcs/global.json b/fcs/global.json deleted file mode 100644 index 2223a05e312..00000000000 --- a/fcs/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "3.0.100" - } -} \ No newline at end of file diff --git a/fcs/misc/logo.pdn b/fcs/misc/logo.pdn deleted file mode 100644 index bc47490f6e9..00000000000 Binary files a/fcs/misc/logo.pdn and /dev/null differ diff --git a/fcs/netfx.props b/fcs/netfx.props deleted file mode 100644 index 064f29b1809..00000000000 --- a/fcs/netfx.props +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - true - - - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono - /usr/lib/mono - /usr/local/lib/mono - - - $(BaseFrameworkPathOverrideForMono)/4.5-api - $(BaseFrameworkPathOverrideForMono)/4.5.1-api - $(BaseFrameworkPathOverrideForMono)/4.5.2-api - $(BaseFrameworkPathOverrideForMono)/4.6-api - $(BaseFrameworkPathOverrideForMono)/4.6.1-api - $(BaseFrameworkPathOverrideForMono)/4.6.2-api - $(BaseFrameworkPathOverrideForMono)/4.7-api - $(BaseFrameworkPathOverrideForMono)/4.7.1-api - true - - - $(FrameworkPathOverride)/Facades;$(AssemblySearchPaths) - - \ No newline at end of file diff --git a/fcs/paket.dependencies b/fcs/paket.dependencies deleted file mode 100644 index c3d2f47304e..00000000000 --- a/fcs/paket.dependencies +++ /dev/null @@ -1,29 +0,0 @@ -source https://api.nuget.org/v3/index.json - -storage: none -framework: netstandard2.0 - -nuget FSharp.Core ~> 4.7 -nuget Fake.BuildServer.AppVeyor -nuget Fake.Core -nuget Fake.Core.Environment -nuget Fake.Core.Process -nuget Fake.Core.ReleaseNotes -nuget Fake.Core.Target -nuget Fake.Core.UserInput -nuget Fake.DotNet.Cli -nuget Fake.DotNet.Fsi -nuget Fake.DotNet.Paket - -group generate - -source https://api.nuget.org/v3/index.json - -storage: none -framework: netstandard2.0 - -nuget FSharp.Core -nuget Fake.Core -nuget Fake.IO.FileSystem -nuget Fake.Core.Trace -nuget FSharp.Literate diff --git a/fcs/paket.lock b/fcs/paket.lock deleted file mode 100644 index 13fe5c84cc2..00000000000 --- a/fcs/paket.lock +++ /dev/null @@ -1,1089 +0,0 @@ -STORAGE: NONE -RESTRICTION: == netstandard2.0 -NUGET - remote: https://api.nuget.org/v3/index.json - BlackFox.VsWhere (1.0) - FSharp.Core (>= 4.2.3) - Fake.BuildServer.AppVeyor (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - Fake.Net.Http (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Diagnostics.FileVersionInfo (>= 4.3) - System.Diagnostics.Process (>= 4.3) - System.IO.FileSystem.Watcher (>= 4.3) - System.Net.Http (>= 4.3.4) - System.Xml.ReaderWriter (>= 4.3.1) - System.Xml.XDocument (>= 4.3) - System.Xml.XmlDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - System.Xml.XPath.XDocument (>= 4.3) - System.Xml.XPath.XmlDocument (>= 4.3) - Fake.Core (5.16) - Fake.Core.CommandLineParsing (5.18.3) - FParsec (>= 1.0.3) - FSharp.Core (>= 4.7) - Fake.Core.Context (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Environment (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.FakeVar (5.18.3) - Fake.Core.Context (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Process (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.FakeVar (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Diagnostics.Process (>= 4.3) - Fake.Core.ReleaseNotes (5.18.3) - Fake.Core.SemVer (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.SemVer (5.18.3) - FSharp.Core (>= 4.7) - System.Runtime.Numerics (>= 4.3) - Fake.Core.String (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Target (5.18.3) - Fake.Core.CommandLineParsing (>= 5.18.3) - Fake.Core.Context (>= 5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.FakeVar (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - FSharp.Control.Reactive (>= 4.2) - FSharp.Core (>= 4.7) - System.Reactive.Compatibility (>= 4.2) - Fake.Core.Tasks (5.18.3) - Fake.Core.Trace (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Trace (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.FakeVar (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.UserInput (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Xml (5.18.3) - Fake.Core.String (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Xml.ReaderWriter (>= 4.3.1) - System.Xml.XDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - System.Xml.XPath.XDocument (>= 4.3) - System.Xml.XPath.XmlDocument (>= 4.3) - Fake.DotNet.Cli (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.DotNet.MSBuild (>= 5.18.3) - Fake.DotNet.NuGet (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - FSharp.Core (>= 4.7) - Mono.Posix.NETStandard (>= 1.0) - Newtonsoft.Json (>= 12.0.2) - Fake.DotNet.Fsi (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.DotNet.MSBuild (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - Fake.Tools.Git (>= 5.18.3) - FSharp.Compiler.Service (>= 32.0) - FSharp.Core (>= 4.7) - Fake.DotNet.MSBuild (5.18.3) - BlackFox.VsWhere (>= 1.0) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - FSharp.Core (>= 4.7) - MSBuild.StructuredLogger (>= 2.0.110) - Fake.DotNet.NuGet (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.SemVer (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Tasks (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.Core.Xml (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - Fake.Net.Http (>= 5.18.3) - FSharp.Core (>= 4.7) - Newtonsoft.Json (>= 12.0.2) - NuGet.Protocol (>= 4.9.4) - System.Net.Http (>= 4.3.4) - Fake.DotNet.Paket (5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.DotNet.Cli (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.IO.FileSystem (5.18.3) - Fake.Core.String (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Diagnostics.FileVersionInfo (>= 4.3) - System.IO.FileSystem.Watcher (>= 4.3) - Fake.Net.Http (5.18.3) - Fake.Core.Trace (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Net.Http (>= 4.3.4) - Fake.Tools.Git (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.Process (>= 5.18.3) - Fake.Core.SemVer (>= 5.18.3) - Fake.Core.String (>= 5.18.3) - Fake.Core.Trace (>= 5.18.3) - Fake.IO.FileSystem (>= 5.18.3) - FSharp.Core (>= 4.7) - FParsec (1.0.3) - FSharp.Core (>= 4.2.3) - NETStandard.Library (>= 1.6.1) - FSharp.Compiler.Service (33.0) - FSharp.Core (>= 4.6.2) - System.Collections.Immutable (>= 1.5) - System.Diagnostics.Process (>= 4.1) - System.Diagnostics.TraceSource (>= 4.0) - System.Reflection.Emit (>= 4.3) - System.Reflection.Metadata (>= 1.6) - System.Reflection.TypeExtensions (>= 4.3) - System.Runtime.Loader (>= 4.0) - System.Security.Cryptography.Algorithms (>= 4.3) - FSharp.Control.Reactive (4.2) - FSharp.Core (>= 4.2.3) - System.Reactive (>= 4.0) - FSharp.Core (4.7) - Microsoft.Build (16.3) - Microsoft.Build.Framework (16.3) - System.Runtime.Serialization.Primitives (>= 4.1.1) - System.Threading.Thread (>= 4.0) - Microsoft.Build.Tasks.Core (16.3) - Microsoft.Build.Framework (>= 16.3) - Microsoft.Build.Utilities.Core (>= 16.3) - Microsoft.Win32.Registry (>= 4.3) - System.CodeDom (>= 4.4) - System.Collections.Immutable (>= 1.5) - System.Linq.Parallel (>= 4.0.1) - System.Net.Http (>= 4.3.4) - System.Reflection.Metadata (>= 1.6) - System.Reflection.TypeExtensions (>= 4.1) - System.Resources.Extensions (>= 4.6) - System.Resources.Writer (>= 4.0) - System.Threading.Tasks.Dataflow (>= 4.9) - Microsoft.Build.Utilities.Core (16.3) - Microsoft.Build.Framework (>= 16.3) - Microsoft.Win32.Registry (>= 4.3) - System.Collections.Immutable (>= 1.5) - System.Text.Encoding.CodePages (>= 4.0.1) - Microsoft.NETCore.Platforms (3.0) - Microsoft.NETCore.Targets (3.0) - Microsoft.Win32.Primitives (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - Microsoft.Win32.Registry (4.6) - System.Buffers (>= 4.5) - System.Memory (>= 4.5.3) - System.Security.AccessControl (>= 4.6) - System.Security.Principal.Windows (>= 4.6) - Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.0.152) - Microsoft.Build (>= 15.8.166) - Microsoft.Build.Framework (>= 15.8.166) - Microsoft.Build.Tasks.Core (>= 15.8.166) - Microsoft.Build.Utilities.Core (>= 15.8.166) - NETStandard.Library (2.0.3) - Microsoft.NETCore.Platforms (>= 1.1) - Newtonsoft.Json (12.0.3) - NuGet.Common (5.3.1) - NuGet.Frameworks (>= 5.3.1) - System.Diagnostics.Process (>= 4.3) - System.Threading.Thread (>= 4.3) - NuGet.Configuration (5.3.1) - NuGet.Common (>= 5.3.1) - System.Security.Cryptography.ProtectedData (>= 4.3) - NuGet.Frameworks (5.3.1) - NuGet.Packaging (5.3.1) - Newtonsoft.Json (>= 9.0.1) - NuGet.Configuration (>= 5.3.1) - NuGet.Versioning (>= 5.3.1) - System.Dynamic.Runtime (>= 4.3) - NuGet.Protocol (5.3.1) - NuGet.Packaging (>= 5.3.1) - System.Dynamic.Runtime (>= 4.3) - NuGet.Versioning (5.3.1) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.native.System (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - runtime.native.System.Net.Http (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - System.Buffers (4.5) - System.CodeDom (4.6) - System.Collections (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Collections.Concurrent (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Globalization (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Collections.Immutable (1.6) - System.Memory (>= 4.5.3) - System.Diagnostics.Debug (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Diagnostics.DiagnosticSource (4.6) - System.Memory (>= 4.5.3) - System.Diagnostics.FileVersionInfo (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Reflection.Metadata (>= 1.4.1) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Diagnostics.Process (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.Win32.Primitives (>= 4.3) - Microsoft.Win32.Registry (>= 4.3) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Text.Encoding.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Thread (>= 4.3) - System.Threading.ThreadPool (>= 4.3) - System.Diagnostics.Tools (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Diagnostics.TraceSource (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Diagnostics.Tracing (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Dynamic.Runtime (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Linq (>= 4.3) - System.Linq.Expressions (>= 4.3) - System.ObjectModel (>= 4.3) - System.Reflection (>= 4.3) - System.Reflection.Emit (>= 4.3) - System.Reflection.Emit.ILGeneration (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Reflection.TypeExtensions (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Globalization (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Globalization.Calendars (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Globalization (>= 4.3) - System.Runtime (>= 4.3) - System.Globalization.Extensions (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.IO (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.IO.FileSystem (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.IO (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.IO.FileSystem.Primitives (4.3) - System.Runtime (>= 4.3) - System.IO.FileSystem.Watcher (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.Win32.Primitives (>= 4.3) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Overlapped (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Thread (>= 4.3) - System.Linq (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Linq.Expressions (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Linq (>= 4.3) - System.ObjectModel (>= 4.3) - System.Reflection (>= 4.3) - System.Reflection.Emit (>= 4.3) - System.Reflection.Emit.ILGeneration (>= 4.3) - System.Reflection.Emit.Lightweight (>= 4.3) - System.Reflection.Extensions (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Reflection.TypeExtensions (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Linq.Parallel (4.3) - System.Collections (>= 4.3) - System.Collections.Concurrent (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Memory (4.5.3) - System.Buffers (>= 4.4) - System.Numerics.Vectors (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.2) - System.Net.Http (4.3.4) - Microsoft.NETCore.Platforms (>= 1.1.1) - runtime.native.System (>= 4.3) - runtime.native.System.Net.Http (>= 4.3) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.DiagnosticSource (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Globalization (>= 4.3) - System.Globalization.Extensions (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.Net.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Security.Cryptography.X509Certificates (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Net.Primitives (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime (>= 4.3.1) - System.Runtime.Handles (>= 4.3) - System.Numerics.Vectors (4.5) - System.ObjectModel (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Threading (>= 4.3) - System.Reactive (4.2) - System.Runtime.InteropServices.WindowsRuntime (>= 4.3) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Compatibility (4.2) - System.Reactive.Core (>= 4.2) - System.Reactive.Interfaces (>= 4.2) - System.Reactive.Linq (>= 4.2) - System.Reactive.PlatformServices (>= 4.2) - System.Reactive.Providers (>= 4.2) - System.Reactive.Core (4.2) - System.Reactive (>= 4.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Interfaces (4.2) - System.Reactive (>= 4.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Linq (4.2) - System.Reactive (>= 4.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.PlatformServices (4.2) - System.Reactive (>= 4.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Providers (4.2) - System.Reactive (>= 4.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reflection (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.IO (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Reflection.Emit (4.6) - System.Reflection.Emit.ILGeneration (>= 4.6) - System.Reflection.Emit.ILGeneration (4.6) - System.Reflection.Emit.Lightweight (4.6) - System.Reflection.Emit.ILGeneration (>= 4.6) - System.Reflection.Extensions (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Reflection (>= 4.3) - System.Runtime (>= 4.3) - System.Reflection.Metadata (1.7) - System.Collections.Immutable (>= 1.6) - System.Reflection.Primitives (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Reflection.TypeExtensions (4.6) - System.Resources.Extensions (4.6) - System.Memory (>= 4.5.3) - System.Resources.ResourceManager (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Globalization (>= 4.3) - System.Reflection (>= 4.3) - System.Runtime (>= 4.3) - System.Resources.Writer (4.3) - System.Collections (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Runtime (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (4.6) - System.Runtime.Extensions (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime (>= 4.3.1) - System.Runtime.Handles (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Runtime.InteropServices (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Reflection (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices.WindowsRuntime (4.3) - System.Runtime (>= 4.3) - System.Runtime.Loader (4.3) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Numerics (4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Serialization.Primitives (4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Security.AccessControl (4.6) - System.Security.Principal.Windows (>= 4.6) - System.Security.Cryptography.Algorithms (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Runtime.Numerics (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.Cng (4.6) - System.Security.Cryptography.Csp (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Security.Cryptography.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3) - System.Collections (>= 4.3) - System.Collections.Concurrent (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (4.6) - System.Security.Cryptography.Primitives (4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Security.Cryptography.ProtectedData (4.6) - System.Memory (>= 4.5.3) - System.Security.Cryptography.X509Certificates (4.3.2) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System (>= 4.3) - runtime.native.System.Net.Http (>= 4.3) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.Globalization.Calendars (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Runtime.Numerics (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Cng (>= 4.3) - System.Security.Cryptography.Csp (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Security.Principal.Windows (4.6) - System.Text.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding.CodePages (4.6) - System.Runtime.CompilerServices.Unsafe (>= 4.6) - System.Text.Encoding.Extensions (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Text.RegularExpressions (4.3.1) - System.Collections (>= 4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3.1) - System.Runtime.Extensions (>= 4.3.1) - System.Threading (>= 4.3) - System.Threading (4.3) - System.Runtime (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Overlapped (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Threading.Tasks (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Threading.Tasks.Dataflow (4.10) - System.Threading.Tasks.Extensions (4.5.3) - System.Runtime.CompilerServices.Unsafe (>= 4.5.2) - System.Threading.Thread (4.3) - System.Runtime (>= 4.3) - System.Threading.ThreadPool (4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Xml.ReaderWriter (4.3.1) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Text.Encoding.Extensions (>= 4.3) - System.Text.RegularExpressions (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Tasks.Extensions (>= 4.3) - System.Xml.XDocument (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tools (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XmlDocument (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XPath (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XPath.XDocument (4.3) - System.Diagnostics.Debug (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - System.Xml.XPath.XmlDocument (4.3) - System.Collections (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XmlDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - -GROUP generate -STORAGE: NONE -RESTRICTION: == netstandard2.0 -NUGET - remote: https://api.nuget.org/v3/index.json - Fake.Core (5.16) - Fake.Core.Context (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Environment (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.FakeVar (5.18.3) - Fake.Core.Context (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.String (5.18.3) - FSharp.Core (>= 4.7) - Fake.Core.Trace (5.18.3) - Fake.Core.Environment (>= 5.18.3) - Fake.Core.FakeVar (>= 5.18.3) - FSharp.Core (>= 4.7) - Fake.IO.FileSystem (5.18.3) - Fake.Core.String (>= 5.18.3) - FSharp.Core (>= 4.7) - System.Diagnostics.FileVersionInfo (>= 4.3) - System.IO.FileSystem.Watcher (>= 4.3) - FSharp.Compiler.Service (27.0.1) - FSharp.Core (>= 4.5.2) - System.Collections.Immutable (>= 1.5) - System.Diagnostics.Process (>= 4.1) - System.Diagnostics.TraceSource (>= 4.0) - System.Reflection.Emit (>= 4.3) - System.Reflection.Metadata (>= 1.6) - System.Reflection.TypeExtensions (>= 4.3) - System.Runtime.Loader (>= 4.0) - System.Security.Cryptography.Algorithms (>= 4.3) - FSharp.Core (4.7) - FSharp.Literate (3.1) - FSharp.Compiler.Service (>= 27.0.1 < 28.0) - System.ValueTuple (>= 4.5 < 5.0) - Microsoft.NETCore.Platforms (3.0) - Microsoft.NETCore.Targets (3.0) - Microsoft.Win32.Primitives (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - Microsoft.Win32.Registry (4.6) - System.Buffers (>= 4.5) - System.Memory (>= 4.5.3) - System.Security.AccessControl (>= 4.6) - System.Security.Principal.Windows (>= 4.6) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.native.System (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - System.Buffers (4.5) - System.Collections (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Collections.Concurrent (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Globalization (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Collections.Immutable (1.6) - System.Memory (>= 4.5.3) - System.Diagnostics.Debug (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Diagnostics.FileVersionInfo (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Reflection.Metadata (>= 1.4.1) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Diagnostics.Process (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.Win32.Primitives (>= 4.3) - Microsoft.Win32.Registry (>= 4.3) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Text.Encoding.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Thread (>= 4.3) - System.Threading.ThreadPool (>= 4.3) - System.Diagnostics.TraceSource (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Diagnostics.Tracing (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Globalization (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.IO (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.IO.FileSystem (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.IO (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.IO.FileSystem.Primitives (4.3) - System.Runtime (>= 4.3) - System.IO.FileSystem.Watcher (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.Win32.Primitives (>= 4.3) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Overlapped (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Thread (>= 4.3) - System.Linq (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Memory (4.5.3) - System.Buffers (>= 4.4) - System.Numerics.Vectors (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.2) - System.Numerics.Vectors (4.5) - System.Reflection (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.IO (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Reflection.Emit (4.6) - System.Reflection.Emit.ILGeneration (>= 4.6) - System.Reflection.Emit.ILGeneration (4.6) - System.Reflection.Metadata (1.7) - System.Collections.Immutable (>= 1.6) - System.Reflection.Primitives (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Reflection.TypeExtensions (4.6) - System.Resources.ResourceManager (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Globalization (>= 4.3) - System.Reflection (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (4.6) - System.Runtime.Extensions (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime (>= 4.3.1) - System.Runtime.Handles (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Runtime.InteropServices (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Reflection (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.Loader (4.3) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Numerics (4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Security.AccessControl (4.6) - System.Security.Principal.Windows (>= 4.6) - System.Security.Cryptography.Algorithms (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Runtime.Numerics (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3) - System.Collections (>= 4.3) - System.Collections.Concurrent (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Security.Principal.Windows (4.6) - System.Text.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding.Extensions (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (4.3) - System.Runtime (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Overlapped (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Threading.Tasks (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Threading.Thread (4.3) - System.Runtime (>= 4.3) - System.Threading.ThreadPool (4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.ValueTuple (4.5) diff --git a/fcs/samples/UntypedTree/Program.fs b/fcs/samples/UntypedTree/Program.fs deleted file mode 100644 index 9d99b8199f8..00000000000 --- a/fcs/samples/UntypedTree/Program.fs +++ /dev/null @@ -1,93 +0,0 @@ -// Open the namespace with InteractiveChecker type -open FSharp.Compiler.SourceCodeServices - - -// Create a checker instance (ignore notifications) -let checker = FSharpChecker.Create() - -// ------------------------------------------------------------------ - -// Get untyped tree for a specified input -let getUntypedTree (file, input) = - let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| file |] } - let untypedRes = checker.ParseFile(file, FSharp.Compiler.Text.SourceText.ofString input, parsingOptions) |> Async.RunSynchronously - match untypedRes.ParseTree with - | Some tree -> tree - | None -> failwith "Something went wrong during parsing!" - -// ------------------------------------------------------------------ - -open FSharp.Compiler.Ast - -/// Walk over all module or namespace declarations -/// (basically 'module Foo =' or 'namespace Foo.Bar') -/// Note that there is one implicitly, even if the file -/// does not explicitly define it.. -let rec visitModulesAndNamespaces modulesOrNss = - for moduleOrNs in modulesOrNss do - let (SynModuleOrNamespace(lid, isRec, isModule, decls, xmlDoc, attribs, synAccess, m)) = moduleOrNs - printfn "Namespace or module: %A" lid - visitDeclarations decls - -/// Walk over a pattern - this is for example used in -/// let = or in the 'match' expression -and visitPattern = function - | SynPat.Wild(_) -> - printfn " .. underscore pattern" - | SynPat.Named(pat, name, _, _, _) -> - visitPattern pat - printfn " .. named as '%s'" name.idText - | SynPat.LongIdent(LongIdentWithDots(ident, _), _, _, _, _, _) -> - printfn " identifier: %s" (String.concat "." [ for i in ident -> i.idText ]) - | pat -> printfn " - not supported pattern: %A" pat - -/// Walk over an expression - the most interesting part :-) -and visitExpression = function - | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> - printfn "Conditional:" - visitExpression cond - visitExpression trueBranch - falseBranchOpt |> Option.iter visitExpression - - | SynExpr.LetOrUse(_, _, bindings, body, _) -> - printfn "LetOrUse with the following bindings:" - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, data, pat, retInfo, body, m, sp)) = binding - visitPattern pat - printfn "And the following body:" - visitExpression body - | expr -> printfn " - not supported expression: %A" expr - -/// Walk over a list of declarations in a module. This is anything -/// that you can write as a top-level inside module (let bindings, -/// nested modules, type declarations etc.) -and visitDeclarations decls = - for declaration in decls do - match declaration with - | SynModuleDecl.Let(isRec, bindings, range) -> - for binding in bindings do - let (Binding(access, kind, inlin, mutabl, attrs, xmlDoc, data, pat, retInfo, body, m, sp)) = binding - visitPattern pat - visitExpression body - | _ -> printfn " - not supported declaration: %A" declaration - - -// ------------------------------------------------------------------ - -// Sample input for the compiler service -let input = """ - let foo() = - let msg = "Hello world" - if true then - printfn "%s" msg """ -let file = "/home/user/Test.fsx" - -let tree = getUntypedTree(file, input) - -// Testing: Print the AST to see what it looks like -// tree |> printfn "%A" - -match tree with -| ParsedInput.ImplFile(ParsedImplFileInput(file, isScript, qualName, pragmas, hashDirectives, modules, b)) -> - visitModulesAndNamespaces modules -| _ -> failwith "F# Interface file (*.fsi) not supported." \ No newline at end of file diff --git a/global.json b/global.json index f12de763877..50311b694fb 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,20 @@ { + "sdk": { + "version": "6.0.100-preview.7.21379.14", + "allowPrerelease": true, + "rollForward": "minor" + }, "tools": { - "dotnet": "3.1.100", + "dotnet": "6.0.100-preview.7.21379.14", "vs": { - "version": "16.3", + "version": "16.8", "components": [ - "Microsoft.Net.Core.Component.SDK.2.1", "Microsoft.VisualStudio.Component.FSharp" ] } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19616.5", + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.21463.4", "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2" } } diff --git a/mono/FSharp.Build/Makefile b/mono/FSharp.Build/Makefile deleted file mode 100644 index 4fef5306a1f..00000000000 --- a/mono/FSharp.Build/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -NAME=FSharp.Build -ASSEMBLY = $(NAME).dll -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-sdk-lib - diff --git a/mono/FSharp.Compiler.Interactive.Settings/Makefile b/mono/FSharp.Compiler.Interactive.Settings/Makefile deleted file mode 100644 index bb894b51662..00000000000 --- a/mono/FSharp.Compiler.Interactive.Settings/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -NAME=FSharp.Compiler.Interactive.Settings -ASSEMBLY = $(NAME).dll -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-sdk-lib - - - - diff --git a/mono/FSharp.Compiler.Private/Makefile b/mono/FSharp.Compiler.Private/Makefile deleted file mode 100644 index 88a3d797b06..00000000000 --- a/mono/FSharp.Compiler.Private/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -NAME=FSharp.Compiler.Private -ASSEMBLY = $(NAME).dll -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-sdk-lib - - - diff --git a/mono/FSharp.Compiler.Server.Shared/Makefile b/mono/FSharp.Compiler.Server.Shared/Makefile deleted file mode 100644 index 213bc156d3f..00000000000 --- a/mono/FSharp.Compiler.Server.Shared/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -NAME=FSharp.Compiler.Server.Shared -ASSEMBLY = $(NAME).dll -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-sdk-lib - - - - diff --git a/mono/FSharp.Core/Makefile b/mono/FSharp.Core/Makefile deleted file mode 100644 index 13667a91613..00000000000 --- a/mono/FSharp.Core/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -NAME=FSharp.Core -ASSEMBLY = $(NAME).dll -DELAY_SIGN=1 -TOKEN=$(FSCORE_DELAY_SIGN_TOKEN) - -include ../config.make - -install: install-sdk-lib - - diff --git a/mono/Fsc/Makefile b/mono/Fsc/Makefile deleted file mode 100644 index 1d55380927a..00000000000 --- a/mono/Fsc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -NAME=fsc -ASSEMBLY = $(NAME).exe -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-bin - - - diff --git a/mono/appveyor.ps1 b/mono/appveyor.ps1 deleted file mode 100644 index 30445b98db0..00000000000 --- a/mono/appveyor.ps1 +++ /dev/null @@ -1,30 +0,0 @@ - -# the version under development, update after a release -$version = '4.1.31' - -function isVersionTag($tag){ - $v = New-Object Version - [Version]::TryParse(($tag).Replace('-alpha','').Replace('-beta',''), [ref]$v) -} - -# append the AppVeyor build number as the pre-release version -if ($env:appveyor){ - $version = $version + '-b' + [int]::Parse($env:appveyor_build_number).ToString('000') - if ($env:appveyor_repo_tag -eq 'true' -and (isVersionTag($env:appveyor_repo_tag_name))){ - $version = $env:appveyor_repo_tag_name - } - Update-AppveyorBuild -Version $version -} else { - $version = $version + '-b001' -} - -$nuget = (gi .\.nuget\NuGet.exe).FullName - -$packagesOutDir = Join-Path $PSScriptRoot "..\release\" - -function pack($nuspec){ - $dir = [IO.Path]::GetDirectoryName($nuspec) - & $nuget pack $nuspec -BasePath "$dir" -Version $version -OutputDirectory "$packagesOutDir" -NoDefaultExcludes -Verbosity d -} - -pack(gi .\FSharp.Compiler.Tools.Nuget\FSharp.Compiler.Tools.nuspec) diff --git a/mono/build-mono.sh b/mono/build-mono.sh deleted file mode 100755 index 12e49fae468..00000000000 --- a/mono/build-mono.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Bootstrap the compiler -# Install the compiler -./mono/prepare-mono.sh && \ -make && \ -sudo make install - diff --git a/mono/cibuild.sh b/mono/cibuild.sh deleted file mode 100755 index 9a5ea5af571..00000000000 --- a/mono/cibuild.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# note: expects to run from top directory -#./mono/latest-mono-stable.sh -make Configuration=$@ -#sudo make install Configuration=$@ -#./mono/test-mono.sh \ No newline at end of file diff --git a/mono/config.make b/mono/config.make deleted file mode 100644 index 91351b8ef85..00000000000 --- a/mono/config.make +++ /dev/null @@ -1,281 +0,0 @@ -DEFAULT: all - -.PHONY: install-sdk-lib - -monocmd = $(shell which mono) -monocmddir = $(dir $(monocmd)) -prefix = $(shell (cd $(monocmddir)/..; pwd)) -thisdir = $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -topdir = $(thisdir)../ -builddir = $(topdir) -libdir = $(prefix)/lib/ -bindir = $(prefix)/bin/ -monobindir = $(bindir) -monolibdir = $(libdir) -monodir = $(monolibdir)mono - -debugvars: - @echo prefix=$(prefix) - @echo topdir=$(topdir) - @echo monodir=$(monodir) - @echo monolibdir=$(monolibdir) - @echo monobindir=$(monobindir) - -TargetDotnetProfile = net40 -Configuration = Release -DISTVERSION = 201011 - -# Version number mappings for various versions of FSharp.Core - - -ifeq (x-$(TargetDotnetProfile)-,x-net40-) - -ifeq (x-$(FSharpCoreBackVersion)-,x--) -VERSION = 4.4.1.0 -PKGINSTALL = yes -REFASSEMPATH = .NETFramework/v4.0 -outsuffix = $(TargetDotnetProfile) -endif - -ifeq (x-$(FSharpCoreBackVersion)-,x-3.0-) -VERSION = 4.3.0.0 -REFASSEMPATH = .NETFramework/v4.0 -outsuffix = fsharp30/$(TargetDotnetProfile) -endif - -ifeq (x-$(FSharpCoreBackVersion)-,x-3.1-) -VERSION = 4.3.1.0 -REFASSEMPATH = .NETFramework/v4.0 -outsuffix = fsharp31/$(TargetDotnetProfile) -endif - -ifeq (x-$(FSharpCoreBackVersion)-,x-4.0-) -VERSION = 4.4.0.0 -REFASSEMPATH = .NETFramework/v4.0 -outsuffix = fsharp40/$(TargetDotnetProfile) -endif - -endif - -ifeq (x-$(TargetDotnetProfile)-,x-monoandroid10+monotouch10+xamarinios10-) -VERSION = 3.98.41.0 -outsuffix = $(TargetDotnetProfile) -endif - - -ifeq (x-$(TargetDotnetProfile)-,x-xamarinmacmobile-) -VERSION = 3.99.41.0 -outsuffix = $(TargetDotnetProfile) -endif - -ifeq (x-$(TargetDotnetProfile)-,x-portable47-) -VERSION = 3.47.41.0 -PCLPATH = .NETPortable -outsuffix = $(TargetDotnetProfile) -endif - -ifeq (x-$(TargetDotnetProfile)-,x-portable7-) -VERSION = 3.7.41.0 -PCLPATH = .NETCore -outsuffix = $(TargetDotnetProfile) -endif - -ifeq (x-$(TargetDotnetProfile)-,x-portable78-) -VERSION = 3.78.41.0 -PCLPATH = .NETCore -outsuffix = $(TargetDotnetProfile) -endif - -ifeq (x-$(TargetDotnetProfile)-,x-portable259-) -VERSION = 3.259.41.0 -PCLPATH = .NETCore -outsuffix = $(TargetDotnetProfile) -endif - - -FSCORE_DELAY_SIGN_TOKEN = b03f5f7f11d50a3a -SIGN_TOKEN = f536804aa0eb945b - -tmpdir = .libs/$(Configuration)/ -outdir = $(builddir)$(Configuration)/$(outsuffix)/bin/ - -INSTALL = $(SHELL) $(topdir)/mono/install-sh -INSTALL_BIN = $(INSTALL) -c -m 755 -INSTALL_LIB = $(INSTALL_BIN) - -MSBUILD = msbuild - -EXTRA_DIST = configure -NO_DIST = .gitignore lib/debug lib/proto lib/release - - -# Install .optdata/.sigdata if they exist (they go alongside FSharp.Core) -# Install the .Targets file. The XBuild targets file gets installed into the place(s) expected for standard F# project -# files. For F# 2.0 project files this is -# /usr/lib/mono/Microsoft F#/v4.0/Microsoft.FSharp.Targets -# For F# 3.0 project files this is -# /usr/lib/mono/Microsoft SDKs/F#/3.0/Framework/v4.0/Microsoft.FSharp.Targets -# For F# 3.1 project files this is -# /usr/lib/mono/xbuild/Microsoft/VisualStudio/v12.0/FSharp/Microsoft.FSharp.Targets -# For F# 4.0 project files this is -# /usr/lib/mono/xbuild/Microsoft/VisualStudio/v14.0/FSharp/Microsoft.FSharp.Targets -# For F# 4.1 project files this is -# /usr/lib/mono/xbuild/Microsoft/VisualStudio/v15.0/FSharp/Microsoft.FSharp.Targets -# -# Here 12.0/14.0/15.0 is 'VisualStudioVersion'. xbuild should set this to 11.0/12.0/14.0/15.0, copying MSBuild. -# -# We put the F# targets and link the SDK DLLs for all these locations -# -# We put a forwarding targets file into all three locations. We also put one in -# .../lib/mono/xbuild/Microsoft/VisualStudio/v/FSharp/Microsoft.FSharp.Targets -# since this is the location if 'xbuild' fails to set VisualStudioVersion. -# -install-sdk-lib: - @echo "Installing $(ASSEMBLY)" - @mkdir -p $(DESTDIR)$(monodir)/fsharp - @if test "x$(DELAY_SIGN)" = "x1"; then \ - echo "Signing $(outdir)$(ASSEMBLY) with Mono key"; \ - $(monobindir)sn -q -R $(outdir)$(ASSEMBLY) $(topdir)mono/mono.snk; \ - fi - @if test x-$(NAME) = x-FSharp.Compiler.Private; then \ - echo "Installing extra dependency System.Collections.Immutable.dll to $(DESTDIR)$(monodir)/fsharp/"; \ - $(INSTALL_LIB) $(outdir)System.Collections.Immutable.dll $(DESTDIR)$(monodir)/fsharp/; \ - echo "Installing extra dependency System.Reflection.Metadata.dll to $(DESTDIR)$(monodir)/fsharp/"; \ - $(INSTALL_LIB) $(outdir)System.Reflection.Metadata.dll $(DESTDIR)$(monodir)/fsharp/; \ - fi - @if test x-$(NAME) = x-FSharp.Build; then \ - echo "Installing Microsoft.FSharp.Targets and Microsoft.Portable.FSharp.Targets into install locations matching Visual Studio"; \ - echo " --> $(DESTDIR)$(monodir)/fsharp/"; \ - echo " --> $(DESTDIR)$(monodir)/Microsoft\ F#/v4.0/"; \ - echo " --> $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.0/Framework/v4.0/"; \ - echo " --> $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.1/Framework/v4.0/"; \ - echo " --> $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.0/Framework/v4.0/"; \ - echo " --> $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.1/Framework/v4.0/"; \ - echo " --> $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/"; \ - echo " --> $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/"; \ - echo " --> $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/"; \ - echo " --> $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/"; \ - echo " --> $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/"; \ - \ - mkdir -p $(tmpdir); \ - mkdir -p $(DESTDIR)$(monodir)/Microsoft\ F#/v4.0/; \ - mkdir -p $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.0/Framework/v4.0/; \ - mkdir -p $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.1/Framework/v4.0/; \ - mkdir -p $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.0/Framework/v4.0/; \ - mkdir -p $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.1/Framework/v4.0/; \ - mkdir -p $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - mkdir -p $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - mkdir -p $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - mkdir -p $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - mkdir -p $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/fsharp/; \ - \ - echo '' > $(tmpdir)Microsoft.FSharp.Targets; \ - echo ' ' >> $(tmpdir)Microsoft.FSharp.Targets; \ - echo '' >> $(tmpdir)Microsoft.FSharp.Targets; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ F#/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.0/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.1/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.0/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.1/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - \ - echo '' > $(tmpdir)Microsoft.Portable.FSharp.Targets; \ - echo ' ' >> $(tmpdir)Microsoft.Portable.FSharp.Targets; \ - echo '' >> $(tmpdir)Microsoft.Portable.FSharp.Targets; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ F#/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.0/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/3.1/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.0/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/Microsoft\ SDKs/F#/4.1/Framework/v4.0/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - $(INSTALL_LIB) $(tmpdir)Microsoft.Portable.FSharp.Targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.props $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.props $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.props $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.props $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.props $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Overrides.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Overrides.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v11.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Overrides.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v12.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Overrides.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v14.0/FSharp/; \ - $(INSTALL_LIB) $(outdir)Microsoft.FSharp.Overrides.NetSdk.targets $(DESTDIR)$(monodir)/xbuild/Microsoft/VisualStudio/v15.0/FSharp/; \ - fi - @if test x-$(outsuffix) = x-net40; then \ - if test -e $(outdir)$(NAME).dll; then \ - echo "Installing $(outdir)$(NAME).dll to $(DESTDIR)$(monodir)/fsharp/"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)$(NAME).dll $(DESTDIR)$(monodir)/fsharp/; \ - fi; \ - if test -e $(outdir)$(NAME).dll.config; then \ - echo "Installing $(outdir)$(NAME).dll to $(DESTDIR)$(monodir)/fsharp/"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)$(NAME).dll.config $(DESTDIR)$(monodir)/fsharp/; \ - fi; \ - if test -e $(outdir)$(NAME).xml; then \ - echo "Installing $(outdir)$(NAME).xml into $(DESTDIR)$(monodir)/fsharp/"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)$(NAME).xml $(DESTDIR)$(monodir)/fsharp/; \ - fi; \ - if test -e $(outdir)$(NAME).sigdata; then \ - echo "Installing $(outdir)$(NAME).sigdata into $(DESTDIR)$(monodir)/fsharp/"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)$(NAME).sigdata $(DESTDIR)$(monodir)/fsharp/; \ - fi; \ - if test -e $(outdir)$(NAME).optdata; then \ - echo "Installing $(outdir)$(NAME).optdata into $(DESTDIR)$(monodir)/fsharp/"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/; \ - $(INSTALL_LIB) $(outdir)$(NAME).optdata $(DESTDIR)$(monodir)/fsharp/; \ - fi; \ - fi - @if test x-$(NAME) = x-FSharp.Core && test x-$(REFASSEMPATH) != x-; then \ - echo "Installing FSharp.Core $(VERSION) reference assembly into api location"; \ - echo " --> $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION)"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION); \ - $(INSTALL_LIB) $(outdir)$(NAME).xml $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).sigdata $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).optdata $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).dll $(DESTDIR)$(monodir)/fsharp/api/$(REFASSEMPATH)/$(VERSION)/; \ - fi - @if test x-$(NAME) = x-FSharp.Core && test x-$(PCLPATH) != x-; then \ - echo "Installing FSharp.Core $(VERSION) reference assembly into api location"; \ - echo " --> $(DESTDIR)$(monodir)/fsharp/$(PCLPATH)/$(VERSION)"; \ - mkdir -p $(DESTDIR)$(monodir)/fsharp/api/$(PCLPATH)/$(VERSION); \ - $(INSTALL_LIB) $(outdir)$(NAME).xml $(DESTDIR)$(monodir)/fsharp/api/$(PCLPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).sigdata $(DESTDIR)$(monodir)/fsharp/api/$(PCLPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).optdata $(DESTDIR)$(monodir)/fsharp/api/$(PCLPATH)/$(VERSION)/; \ - $(INSTALL_LIB) $(outdir)$(NAME).dll $(DESTDIR)$(monodir)/fsharp/api/$(PCLPATH)/$(VERSION)/; \ - fi - - - -# The binaries fsc.exe and fsi.exe only get installed for Mono 4.5 profile -# This also installs 'fsharpc' and 'fsharpi' and 'fsharpiAnyCpu' -install-bin: - chmod +x $(outdir)$(ASSEMBLY) - sed -e 's,[@]DIR[@],$(monodir)/fsharp,g' -e 's,[@]TOOL[@],$(ASSEMBLY),g' -e 's,[@]MONOBINDIR[@],$(monobindir),g' < $(topdir)mono/launcher > $(outdir)$(subst fs,fsharp,$(NAME)) - chmod +x $(outdir)$(subst fs,fsharp,$(NAME)) - @mkdir -p $(DESTDIR)$(monodir)/fsharp - @mkdir -p $(DESTDIR)$(bindir) - $(INSTALL_BIN) $(outdir)$(ASSEMBLY) $(DESTDIR)$(monodir)/fsharp - $(INSTALL_BIN) $(outdir)$(ASSEMBLY).config $(DESTDIR)$(monodir)/fsharp - $(INSTALL_BIN) $(outdir)$(subst fs,fsharp,$(NAME)) $(DESTDIR)$(bindir) - - diff --git a/mono/dependencies/2.1/MonoAndroid/System.Core.dll b/mono/dependencies/2.1/MonoAndroid/System.Core.dll deleted file mode 100644 index 3ddcf7dbb05..00000000000 Binary files a/mono/dependencies/2.1/MonoAndroid/System.Core.dll and /dev/null differ diff --git a/mono/dependencies/2.1/MonoAndroid/System.Numerics.dll b/mono/dependencies/2.1/MonoAndroid/System.Numerics.dll deleted file mode 100644 index 4674335b695..00000000000 Binary files a/mono/dependencies/2.1/MonoAndroid/System.Numerics.dll and /dev/null differ diff --git a/mono/dependencies/2.1/MonoAndroid/System.dll b/mono/dependencies/2.1/MonoAndroid/System.dll deleted file mode 100644 index 481cce72ccd..00000000000 Binary files a/mono/dependencies/2.1/MonoAndroid/System.dll and /dev/null differ diff --git a/mono/dependencies/2.1/MonoAndroid/mscorlib.dll b/mono/dependencies/2.1/MonoAndroid/mscorlib.dll deleted file mode 100644 index f1b625ddfbf..00000000000 Binary files a/mono/dependencies/2.1/MonoAndroid/mscorlib.dll and /dev/null differ diff --git a/mono/dependencies/2.1/MonoDroid.FSharp.targets b/mono/dependencies/2.1/MonoDroid.FSharp.targets deleted file mode 100644 index 540e71418ab..00000000000 --- a/mono/dependencies/2.1/MonoDroid.FSharp.targets +++ /dev/null @@ -1,11 +0,0 @@ - - - MonoAndroid - v1.0 - v2.2 - SdkOnly - - - - - \ No newline at end of file diff --git a/mono/dependencies/2.1/XamarinMac/System.Core.dll b/mono/dependencies/2.1/XamarinMac/System.Core.dll deleted file mode 100644 index 6e391ff4713..00000000000 Binary files a/mono/dependencies/2.1/XamarinMac/System.Core.dll and /dev/null differ diff --git a/mono/dependencies/2.1/XamarinMac/System.Numerics.dll b/mono/dependencies/2.1/XamarinMac/System.Numerics.dll deleted file mode 100644 index 122c785ce2b..00000000000 Binary files a/mono/dependencies/2.1/XamarinMac/System.Numerics.dll and /dev/null differ diff --git a/mono/dependencies/2.1/XamarinMac/System.dll b/mono/dependencies/2.1/XamarinMac/System.dll deleted file mode 100644 index 18065042a50..00000000000 Binary files a/mono/dependencies/2.1/XamarinMac/System.dll and /dev/null differ diff --git a/mono/dependencies/2.1/XamarinMac/mscorlib.dll b/mono/dependencies/2.1/XamarinMac/mscorlib.dll deleted file mode 100644 index f1a475fffee..00000000000 Binary files a/mono/dependencies/2.1/XamarinMac/mscorlib.dll and /dev/null differ diff --git a/mono/fsi/Makefile b/mono/fsi/Makefile deleted file mode 100644 index f188ef02184..00000000000 --- a/mono/fsi/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -NAME=fsi -ASSEMBLY = $(NAME).exe -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-bin - - - diff --git a/mono/fsiAnyCpu/Makefile b/mono/fsiAnyCpu/Makefile deleted file mode 100644 index 11b66f9d477..00000000000 --- a/mono/fsiAnyCpu/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -NAME=fsiAnyCpu -ASSEMBLY = $(NAME).exe -TOKEN=$(SIGN_TOKEN) - -include ../config.make - -install: install-bin - - - diff --git a/mono/install-sh b/mono/install-sh deleted file mode 100755 index 6781b987bdb..00000000000 --- a/mono/install-sh +++ /dev/null @@ -1,520 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2009-04-28.21; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/mono/latest-mono-stable.sh b/mono/latest-mono-stable.sh deleted file mode 100755 index 045b80f8377..00000000000 --- a/mono/latest-mono-stable.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# suitable for Ubuntu 16.04 - get latest Mono stable -mono --version -sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -echo "deb http://download.mono-project.com/repo/ubuntu stable-xenial main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list -sudo apt-get update -ps -A | grep apt -#sudo rm /var/lib/dpkg/lock -#sudo dpkg --configure -a -sudo apt-get -my install mono-devel -mono --version diff --git a/mono/launcher b/mono/launcher deleted file mode 100644 index e61b7bba19d..00000000000 --- a/mono/launcher +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -EXEC="exec " - -if test x"$1" = x--debug; then - DEBUG=--debug - shift -fi - -if test x"$1" = x--gdb; then - shift - EXEC="gdb --eval-command=run --args " -fi - -if test x"$1" = x--valgrind; then - shift - EXEC="valgrind $VALGRIND_OPTIONS" -fi - -$EXEC @MONOBINDIR@/mono $DEBUG $MONO_OPTIONS @DIR@/@TOOL@ --exename:$(basename "$0") "$@" diff --git a/mono/mono.snk b/mono/mono.snk deleted file mode 100644 index 380116c18fc..00000000000 Binary files a/mono/mono.snk and /dev/null differ diff --git a/mono/msfinal.pub b/mono/msfinal.pub deleted file mode 100644 index 110b59c7b0d..00000000000 Binary files a/mono/msfinal.pub and /dev/null differ diff --git a/mono/prepare-mono.sh b/mono/prepare-mono.sh deleted file mode 100755 index 229a7eb8492..00000000000 --- a/mono/prepare-mono.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env sh - -# OS detection - -OSName=$(uname -s) -case $OSName in - Darwin) - OS=OSX - ;; - - Linux) - OS=Linux - ;; - - *) - echo "Unsupported OS '$OSName' detected. Cannot continue with build, the scripts must be updated to support this OS." - exit 1 - ;; -esac - -# On Linux (or at least, Ubuntu), when building with Mono, need to install the mono-devel package first. -if [ $OS = 'Linux' ]; then - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF - echo "deb http://download.mono-project.com/repo/ubuntu trusty main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list - sudo apt-get update - sudo apt-get -y install mono-devel msbuild -fi - -# The FSharp.Compiler.Tools package doesn't work correctly unless a proper install of F# has been done on the machine. -# OSX can skip this because the OSX Mono installer includes F#. -if [ $OS != 'OSX' ]; then - sudo apt-get -y install fsharp -fi - -# "access to the path /etc/mono/registry/last-time is denied" -# On non-OSX systems, may need to create Mono's registry folder to avoid exceptions during builds. -# This doesn't seem to be necessary on OSX, as the folder is created by the installer. -if [ $OS != 'OSX' ]; then - # This registry folder path is correct for Linux; - # on OSX the folder is /Library/Frameworks/Mono.framework/Versions/Current/etc/mono/registry - # and may be different for *BSD systems. - __MonoRegistryDir="/etc/mono/registry" - if [ ! -d "$__MonoRegistryDir" ]; then - echo "Mono registry directory does not exist (it may not have been created yet)." - echo "The directory needs to be created now; superuser permissions are required for this." - { sudo -- sh -c "mkdir -p $__MonoRegistryDir && chmod uog+rw $__MonoRegistryDir"; } || { echo "Unable to create/chmod Mono registry directory '$__MonoRegistryDir'." >&2; } - fi -fi diff --git a/mono/test-mono.sh b/mono/test-mono.sh deleted file mode 100755 index bbcc8b8705e..00000000000 --- a/mono/test-mono.sh +++ /dev/null @@ -1,10 +0,0 @@ -# Run some project building tests -# Run some a variation of the tests/fsharp suite -# Run the FSharp.Core.UnitTests suite - -# note: expects to run from top directory -(cd tests/projects; ./build.sh) && -(cd tests/fsharp/core; ./run-opt.sh) -# This currently takes too long in travis -#&& mono packages/NUnit.Console.3.0.0/tools/nunit3-console.exe --agents=1 Release/net40/bin/FSharp.Core.UnitTests.dll - diff --git a/proto.proj b/proto.proj index 3a9793b4be3..bb077834555 100644 --- a/proto.proj +++ b/proto.proj @@ -7,13 +7,13 @@ - TargetFramework=netcoreapp3.0 + TargetFramework=netstandard2.0 - TargetFramework=netcoreapp3.0 + TargetFramework=net5.0 - TargetFramework=netcoreapp3.0 + TargetFramework=net5.0 diff --git a/release-notes.md b/release-notes.md index 88c4c4a3e94..a69910a8f87 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,218 +1,1990 @@ - Copyright (c) Microsoft Corporation. All Rights Reserved. - See License.txt in the project root for license information. +Copyright (c) Microsoft Corporation. All Rights Reserved. +See License.txt in the project root for license information. ## About the release notes -We deliver F# and F# tools for Visual Studio and .NET Core releases. These can include bug fixes, new tooling features, new compiler features, performance improvements, infrastructure improvements, and new language versions. The most recent release of F# or any F# component will be at the top of this document. +This document contains current and historical release notes information. They are preserved in their original form. -## Visual Studio 15.9 +* [Current Release notes](#Current-release-notes) +* [Visual Studio 2017-2019 release notes](#visual-studio-2017-2019-update-167-release-notes) +* [FSharp.Compiler.Service release notes (version 37 and lower)](#FSharp-Compiler-Service-Versions-Release-notes) +* [Older release notes (pre-F# 4.0)](#older-visual-f-releases) + +## Current release notes + +These release notes track our current efforts to document changes to the F# project over time. They are split into the language, core library, compiler/tools, and compiler service. + +### F# 5 / Visual Studio 16.9 + +### FSharp.Core 5.0.2 + +* [Fix #11143 - FSharp.Core 5.0.1 should not have FSharp.Core.xml in contentFiles #11160](https://github.com/dotnet/fsharp/pull/11160) + +### FSharp.Core 5.0.1 + +* [Performance improvement](https://github.com/dotnet/fsharp/pull/10188) to core collections Map by [Victor Baybekov](https://github.com/buybackoff) + +### FSharp tools 11.0.1 + +* Significant improvements to the performance of code making heavy use of closures at runtime +* Warnings for mismatched parameter names between signature and implementation files +* Warnings for incorrect XML documentation files are turned on by default +* Big performance gains in tools for codebases with F# signature files +* Improved responsiveness for most IDE features +* Signature Help for F# function calls +* .NET 5 scripting for Visual Studio +* Add ConvertToAnonymousRecord quick fix [#10493](https://github.com/dotnet/fsharp/pull/10493) +* Add UseMutationWhenValueIsMutable code fix [#10488](https://github.com/dotnet/fsharp/pull/10488) +* Add MakeDeclarationMutable code fix [#10480](https://github.com/dotnet/fsharp/pull/10480) +* Add ChangeToUpcast code fix [#10463](https://github.com/dotnet/fsharp/pull/10463) +* Add AddMissingEqualsToTypeDefinition code fixer [#10470](https://github.com/dotnet/fsharp/pull/10470) +* Tag items in tooltips consistenly with respect to document classification. [#9563](https://github.com/dotnet/fsharp/pull/9563) +* Add ConvertToSingleEqualsEqualityExpression code fix [#10462](https://github.com/dotnet/fsharp/pull/10462) +* Turn XML doc and Sig<->Impl mismatch warnings on by default [#10457](https://github.com/dotnet/fsharp/pull/10457) +* Add ChangeRefCellDerefToNotExpression code fixer [#10469](https://github.com/dotnet/fsharp/pull/10469) +* Add WrapExpressionInParentheses code fix [#10460](https://github.com/dotnet/fsharp/pull/10460) +* Add ChangePrefixNegationToInfixSubtraction code fixeroo [#10471](https://github.com/dotnet/fsharp/pull/10471) +* Fix generic overloads with nullable [#10582](https://github.com/dotnet/fsharp/pull/10582) +* Resolve issue with implicit yields requiring Zero [#10556](https://github.com/dotnet/fsharp/pull/10556), by [Ryan Coy](https://github.com/laenas) +* Fix issue10550 FSI accessing System.Configuration. [#10572](https://github.com/dotnet/fsharp/pull/10572) +* Add field names to ILNativeType.Custom. [#10567](https://github.com/dotnet/fsharp/pull/10567), by [Scott Hutchinson](https://github.com/ScottHutchinson) +* Add field names to the ILExceptionClause.FilterCatch constructor. [#10559](https://github.com/dotnet/fsharp/pull/10559), by [Scott Hutchinson](https://github.com/ScottHutchinson) +* Fix completion with backticks, underscores, numbers [#10500](https://github.com/dotnet/fsharp/pull/10500), by [zanaptak](https://github.com/zanaptak) +* Emitting IsReadOnly/In attributes on abstract properties [#10542](https://github.com/dotnet/fsharp/pull/10542) +* Disable partial type checking when getting full results for a file [#10448](https://github.com/dotnet/fsharp/pull/10448) +* Fix unused open type declaration detection [#10510](https://github.com/dotnet/fsharp/pull/10510), by [André Slupik](https://github.com/asik) + +### FSharp Compiler Service 40.0.0 + +This is a second big update to FCS. There are significant trimmings and renamings of the API and gets +it close to a more permanent form: + +The primary namespaces are now: + +``` +FSharp.Compiler.IO // FileSystem +FSharp.Compiler.CodeAnalysis // FSharpChecker, FSharpCheckFileResults, FSharpChecProjectResults and friends +FSharp.Compiler.Diagnostics // FSharpDiagnostic and friends +FSharp.Compiler.EditorServices // Misc functionality for editors, e.g. interface stub generation +FSharp.Compiler.Interactive.Shell // F# Interactive +FSharp.Compiler.Symbols // FSharpEntity etc +FSharp.Compiler.Syntax // SyntaxTree, XmlDoc, PrettyNaming +FSharp.Compiler.Text // ISourceFile, Range, TaggedText and other things +FSharp.Compiler.Tokenization // FSharpLineTokenizer etc. +``` + +##### Changes in `FSharp.Compiler.Diagnostics` + +* `ErrorHelpers` --> `DiagnosticHelpers` + +* `ErrorResolutionHints.getSuggestedNames` --> `ErrorResolutionHints.GetSuggestedNames` + +##### Changes in `FSharp.Compiler.SourceCodeServices` + +* Everything is moved to one of the other namespaces + +* The `FSharp` prefix is used for things in `FSharp.Compiler.Symbols` but not `FSharp.Compiler.EditorServices` + +* `AssemblyContentProvider` --> `AssemblyContent` in EditorServices + +* `AstVisitorBase` --> moved to `SyntaxVisitorBase` in FSharp.Compiler.Syntax + +* `AstVisitorBase.*` --> `SyntaxVisitorBase.*` and methods now all take `path` parameters consistently + +* `AstTraversal.Traverse` --> `SyntaxTraversal.Traverse` + +* `BasicPatterns` --> `FSharpExprPatterns` in FSharp.Compiler.Symbols + +* `DebuggerEnvironment.*` merged into `CompilerEnvironment` in FSharp.Compiler + +* `ExternalType` --> `FindDeclExternalType` in EditorServices + +* `FSharpChecker.ParseFileNoCache` --> removed in favour of optional `cache=false` argument on `FSharpChecker.ParseFile` + +* `FSharpChecker.BeforeBackgroundFileCheck` event now takes FSharpProjectOptions arg + +* `FSharpChecker.FileChecked` event now takes FSharpProjectOptions arg + +* `FSharpChecker.FileParsed` event now takes FSharpProjectOptions arg + +* `FSharpChecker.ProjectChecked` event now takes FSharpProjectOptions arg + +* `FSharpCheckFileResults.Errors` --> `FSharpCheckFileResults.Diagnostics` + +* `FSharpCheckProjectResults.Errors` --> `FSharpCheckProjectResults.Diagnostics` + +* `FSharpDeclarationListInfo` --> `DeclarationListInfo` in EditorServices + +* `FSharpEnclosingEntityKind` --> `NavigationEntityKind` in EditorServices + +* `FSharpExternalSymbol` --> `FindDeclExternalSymbol` in EditorServices + +* `FSharpFileUtilities.*` merged into `CompilerEnvironment` in FSharp.Compiler + +* `FSharpFindDeclResult` --> `FindDeclResult` in EditorServices + +* `FSharpLexer.Lex` --> `FSharpLexer.Tokenize` in FSharp.Compiler.Tokenization + +* `FSharpMethodGroup` --> `MethodGroup` in EditorServices + +* `FSharpMethodGroupItem` --> `MethodGroupItem` in EditorServices + +* `FSharpMethodGroupItemParameter` --> `MethodGroupItemParameter` in EditorServices + +* `FSharpMethodGroupItemParameter.StructuredDisplay` ---> `MethodGroupItemParameter.Display` + +* `FSharpMethodGroupItemParameter.StructuredReturnTypeText` ---> `MethodGroupItemParameter.ReturnTypeText` + +* `FSharpNavigationDeclarationItem` --> `NavigationItem` in EditorServices + +* `FSharpNavigationTopLevelDeclaration` --> `NavigationTopLevelDeclaration` in EditorServices + +* `FSharpNavigationItems` --> `NavigationItems` in EditorServices + +* `FSharpNavigation` --> `Navigation` in EditorServices + +* `FSharpNavigationDeclarationItemKind` --> `NavigationItemKind` in EditorServices + +* `FSharpNoteworthyParamInfoLocations` --> `ParameterLocations` + +* `FSharpProjectOptions.ExtraProjectInfo` is removed + +* `FSharpSemanticClassificationItem` --> `SemanticClassificationItem` in EditorServices + +* `FSharpSemanticClassificationView ` --> `SemanticClassificationView` in EditorServices + +* `FSharpStructuredToolTipText` --> `ToolTipText` in EditorServices + +* `FSharpStructuredToolTipElementData` --> `ToolTipElementData` in EditorServices + +* `FSharpStructuredToolTipElement` --> `ToolTipElement` in EditorServices + +* `FSharpSymbol.Accessibility` is now non-optional. Will return "public" in cases it previously returned "None" + +* `FSharpSymbol.XmlDoc` now returns `FSharpXmlDoc` with cases for internal and external XML doc. Use `match symbol.XmlDoc with FSharpXmlDoc.FromText doc -> doc.UnprocessedLines` to get unprocessed XML lines + +* `FSharpSymbol.ElaboratedXmlDoc` now removed. Use `match symbol.XmlDoc with FSharpXmlDoc.FromText doc -> doc.GetElaboratedLine()` + +* `FSharpToolTipText` --> `ToolTipText` in EditorServices + +* `FSharpToolTipElementData` --> `ToolTipElementData` in EditorServices + +* `FSharpToolTipElement` --> `ToolTipElement` in EditorServices + +* `FSharpType.FormatLayout` now returns `TaggedText[]` + +* `FSharpType.FormatLayout` now returns `TaggedText[]` + +* `FSharpUnresolvedSymbol` --> `UnresolvedSymbol` in EditorServices + +* `InterfaceStubGenerator.*` are all capitalized + +* `Idents` --> `ShortIdents` in EditorServices + +* `LongIdent` abbreviation removed and replaced by `string` + +* `NavigateTo.NavigableItemKind ` --> now directly in EditorServices + +* `NavigateTo.ContainerType` --> `NavigableContainerType` now directly in EditorServices + +* `NavigateTo.NavigableItem` --> `NavigableItem` now directly in EditorServices + +* `NavigateTo.getNavigableItems` --> NavigateTo.GetNavigableItems in EditorServices + +* `ParamTypeSymbol` --> `FindDeclExternalParam in EditorServices` + +* `ParsedInput.tryFindInsertionContext` --> `ParsedInput.TryFindInsertionContext` + +* `ParsedInput.findNearestPointToInsertOpenDeclaration ` --> `ParsedInput.FindNearestPointToInsertOpenDeclaration ` + +* `ParsedInput.getLongIdentAt` --> `ParsedInput.GetLongIdentAt` + +* `ParsedInput.adjustInsertionPoint` --> `ParsedInput.AdjustInsertionPoint` + +* `Symbol` --> `FSharpSymbolPatterns` in FSharp.Compiler.Symbols and marked experimental + +* `Symbol.isAttribute` --> now `attrib.IsAttribute<'T>()` + +* `Symbol.getAbbreviatedType` --> now `symbol.StripAbbreviations()` + +* `Symbol.hasAttribute` --> now `symbol.HasAttribute<'T>()` + +* `Symbol.tryGetAttribute` --> now `symbol.TryGetAttribute<'T>()` + +* `TraverseStep` --> `SyntaxNode` in FSharp.Compiler.Syntax + +* ToolTips now only return the structured (TaggedText) tooltips. You can iterate to get the text tooltips + +##### Changes in `FSharp.Compiler.Text` + +* `Pos` --> `Position` + +##### Changes in `FSharp.Compiler.TextLayout` + +* Everything moves to `FSharp.Compiler.Text` + +* `LayoutTag` --> `TextTag` + +* `Layout` is now internal and replaced by `TaggedText[]` + +* `LayoutOps` is now internal + +##### Changes in `FSharp.Compiler.SyntaxTree` + +* Everything moves to namespace `FSharp.Compiler.Syntax` + +* `DebugPointAtBinding` is now RequireQualifiedAccess + +* `NoDebugPointAtStickyBinding` --> `DebugPointAtBinding.NoneAtSticky` + +* `Clause` --> `SynMatchClause` + +* `NormalBinding` -> `SynBindingKind.Normal` + +* `Binding` --> `SynBinding` + +* `Field` --> `SynField` + +* `UnionCase` --> `SynUnionCase` + +* `UnionCaseFullType` --> `SynUnionCaseKind.FullType` + +* `UnionCaseFields` --> `SynUnionCaseKind.Fields` + +* `MemberKind` --> `SynMemberKind` + +* `MemberFlags` --> `SynMemberFlags` + +* `TyconUnspecified` --> `SynTypeDefnKind.Unspecified` + +* `TyconClass` --> `SynTypeDefnKind.Class` + +* `TyconInterface` --> `SynTypeDefnKind.Interface` + +* `TyconStruct` --> `SynTypeDefnKind.Struct` + +* `TyconHiddenRepr` --> `SynTypeDefnKind.Opaque` + +* `TyconUnion` --> `SynTypeDefnKind.Union` + +* `TyconDelegate ` --> `SynTypeDefnKind.Delegate` + +* `ComponentInfo` --> `SynComponentInfo` + +* `TyconAugmentation` --> `SynTypeDefnKind.Augmentation` + +* `TypeDefnSig` --> `SynTypeDefnSig` + +* `HeadTypeStaticReq` --> `TyparStaticReq.HeadType` + +* `NoStaticReq` --> `TyparStaticReq.None` + +* `SynTypeConstraint` is now RequiresQualifiedAccess + +* `ValSpfn` --> `SynValSpfn` + +* `TyparDecl` --> `SynTyparDecl` + +* `Typar` --> `SynTypar` + +* `SynSimplePatAlternativeIdInfo` is now RequiresQualifiedAccess + +* `InterfaceImpl` --> `SynInterfaceImpl` + +* `SynBindingKind` is now RequiresQualifiedAccess + +* `DoBinding` --> `SynBindingKind.Do` + +* `StandaloneExpression` --> `SynBindingKind.StandaloneExpression` + +* `SynModuleOrNamespaceKind` is now RequiresQualifiedAccess + +* `IDefns` --> `ParsedScriptInteraction.Definitions` + +* `IHash ` --> `ParsedScriptInteraction.HashDirective` + +##### Other changes + +* `LegacyReferenceResolver` now marked obsolete + +### FSharp Compiler Service 39.0.0 + +This is a big update to FCS. There are significant trimmings and renamings of the API as a first step towards getting it under control with aims to eventually have a stable, sane public API surface area. + +Renamings: + +```diff +-type FSharp.Compiler.AbstractIL.Internal.Library.IFileSystem ++type FSharp.Compiler.SourceCodeServices.IFileSystem + +-module FSharp.Compiler.AbstractIL.Internal.Library.Shim ++FSharp.Compiler.SourceCodeServices.FileSystemAutoOpens + +-type FSharp.Compiler.AbstractIL.Layout ++type FSharp.Compiler.TextLayout.Layout + +-type FSharp.Compiler.AbstractIL.Internal.TaggedText ++type FSharp.Compiler.TextLayout.TaggedText + +-type FSharp.Compiler.Layout.layout ++type FSharp.Compiler.TextLayout.layout + +-type FSharp.Compiler.Layout.Layout ++FSharp.Compiler.TextLayout.Layout + +-module FSharp.Compiler.Layout ++module FSharp.Compiler.TextLayout.LayoutRender + +-module FSharp.Compiler.LayoutOps ++module FSharp.Compiler.TextLayout.Layout + +-module FSharp.Compiler.Layout.TaggedText ++module FSharp.Compiler.TextLayout.TaggedText + +-module FSharp.Compiler.Layout.TaggedTextOps ++FSharp.Compiler.TextLayout.TaggedText + +-module FSharp.Compiler.Layout.TaggedTextOps.Literals ++FSharp.Compiler.TextLayout.TaggedText + +-type FSharp.Compiler.Range.range ++FSharp.Compiler.Text.Range + +-type FSharp.Compiler.Range.pos ++FSharp.Compiler.Text.Pos + +-module FSharp.Compiler.Range.Range ++module FSharp.Compiler.Text.Pos ++module FSharp.Compiler.Text.Range + +-module FSharp.Compiler.QuickParse ++module FSharp.Compiler.SourceCodeServices.QuickParse + +-module FSharp.Compiler.PrettyNaming ++FSharp.Compiler.SourceCodeServices.PrettyNaming + +-val FSharpKeywords.PrettyNaming.KeywordNames ++FSharp.Compiler.SourceCodeServices.FSharpKeywords.KeywordNames + +-val FSharpKeywords.PrettyNaming.QuoteIdentifierIfNeeded ++FSharp.Compiler.SourceCodeServices.FSharpKeywords.QuoteIdentifierIfNeeded + +-val FSharpKeywords.PrettyNaming.FormatAndOtherOverloadsString ++FSharp.Compiler.SourceCodeServices.FSharpKeywords.FormatAndOtherOverloadsString +``` + +Renamings in `FSharp.Compiler.SourceCodeServices`: + +```diff +-Lexer.* ++FSharp.Compiler.SourceCodeServices.* + +-FSharpSyntaxToken* ++FSharpToken* + +-FSharpErrorInfo ++FSharpDiagnostic + +-FSharpErrorSeverity ++FSharpDiagnosticSeverity + +-ExternalSymbol ++FSharpExternalSymbol + +-UnresolvedSymbol ++FSharpUnresolvedSymbol + +-CompletionKind ++FSharpCompletionKind + +-module Keywords ++module FSharpKeywords + +``` + +* Extension methods in `ServiceAssemblyContent.fsi` are now now intrinsic methods on the symbol types themselves. +* `SemanticClassificationType` is now an enum instead of a discriminated union. +* `GetBackgroundSemanticClassificationForFile` now returns `Async` instead of `Async`. The `SemanticClassificationView` provides a read-only view over the semantic classification contents via the `ForEach (FSharpSemanticClassificationItem -> unit) -> unit` function. + +The following namespaces have been made internal + +* `FSharp.Compiler.AbstractIL.*`, aside from a small hook for JetBrains Rider +* `FSharp.Compiler.ErrorLogger.*` + +New functions in the `SourceCodeServices` API: + +* `FSharpDiagnostic.NewlineifyErrorString` +* `FSharpDiagnostic.NormalizeErrorString` + +### F# 5 / Visual Studio 16.8 / .NET 5 + +This release covers three important milestones: F# 5, Visual Studio 16.8, and .NET 5. + +### FSharpLanguage 5.0.0 + +* Package references in scripts via `#r "nuget:..."` +* String interpolation +* Support for `nameof` and the `nameof` pattern by Microsoft and [Loïc Denuzière](https://github.com/Tarmil) +* `open type` declarations +* Applicative computation expressions via `let! ... and!` +* Overloads for custom operations in computation expressions (in preview), by [Ryan Riley](https://github.com/panesofglass) and [Diego Esmerio](https://github.com/Nhowka) +* Interfaces can now be implemented at different generic instantiations +* Default interface member consumption +* Better interop with nullable value types + +### FSharp Core 5.0.0 + + +* Consistent behavior for empty/non-existent slices for lists, strings, arrays, 2D arrays, 3D arrays, and 4D arrays +* Support for fixed-index slices in 3D and 4D arrays +* Support for negative indexes (in preview) +* Reverted a change where the %A and %O and `ToString`/`string` result of a union with `RequireQualifiedAccess` gave the fully-qualified union case name in response to user feedback +* Significantly improved XML documentation for all APIs +* Optimized reflection for F# types by [kerams](https://github.com/kerams) + +### FSharp Tools 11.0.0 + +* Improved batch compilation performance (up to 30% faster depending on the project type) +* Support for editing `#r "nuget:..."` scripts in Visual Studio +* Various fixes for F# script editing performance, especially for scripts with significant dependencies getting loaded +* Support for compiling against .NET Core on Windows when no STAThread is availble +* Support for validating signatures against XML doc comments when compiling via `/warnon:3390` +* Fixed a bug where FSharp.Core XML doc contents were not displayed in F# scripts in Visual Studio +* Support for strong name signing against F# projects when compiling using the .NET SDK +* Fixed a bug where manually referencing `Akkling.Cluster.Sharding.0.9.3` in FSI would not work +* Bring back the custom colorization options that were missed in the 16.7 update +* Support coloring disposable values independently from disposable types +* Fix a bug where emitting an `inref<_>` could cause a value to no longer be consumable by C# +* Support displaying `Some x` when debugging F# options in Visual Studio, by [Friedrich von Never](https://github.com/ForNeVeR) +* Fix a bug where compiling large anonymous records could fail in release mode +* Support for considering struct tuples and struct anonymous records as subtypes of `System.ValueTuple` +* Fix several internal errors in the compiler when compiling various niche scenarios +* Various performance enhancements when editing large files by Microsoft and [Daniel Svensson](https://github.com/Daniel-Svensson) +* Optimized output for the `string` function, by [Abel Braaksma](https://github.com/abelbraaksma) +* Various fixes for some display regressions for Find all References in Visual Studio +* Fix duplicate symbol output when renaming constructs in a project with multiple TFMs +* Support for `Int64.MinValue` as a `nativeint` literal, by [Abel Braaksma](https://github.com/abelbraaksma) +* Prevent assignment to `const` fields, by [Chet Husk](https://github.com/baronfel) +* Compiler message improvements (especially for overload resolution) by [Gauthier Segay](https://github.com/smoothdeveloper), [Vladimir Shchur](https://github.com/Lanayx), and Microsoft + +### FSharp Compiler Service 38.0.2 + +* Add FSharp.DependencyManager.Nuget as a project reference and ensure it is in the package, allowing other editors to consume `#r "nuget:..."` references at design-time [#10784](https://github.com/dotnet/fsharp/pull/10784) + +### FSharp Compiler Service 38.0.1 +* Add check for system assemblies completion [#10575](https://github.com/dotnet/fsharp/pull/10575) +* Fix net sdk references discovery [#10569](https://github.com/dotnet/fsharp/pull/10569) +* Fix FSC nuget package dependencies [#10588](https://github.com/dotnet/fsharp/pull/10588) + +### FSharp Compiler Service 38.0.0 + +The most notable change for FSharp.Compiler.Service is that it is now built and deployed as a part of the dotnet/fsharp codebase. Builds are produced nightly, matching exactly the nightly builds of the F# compiler, FSharp.Core, and F# tools. + +* Support for Witness information [#9510](https://github.com/dotnet/fsharp/pull/95100) in `FSharpExpr` and `FSharpMemberOrFunctionOrValue` +* Support for Jupyter Notebooks and VSCode notebooks via `FSharp.Compiler.Private.Scripting` and .NET Interactive +* Improvements to the F# syntax tree represtation by [Eugene Auduchinok](https://github.com/auduchinok) +* Support for `const` in keyword completion info by [Alex Berezhnykh](https://github.com/DedSec256) +* Support for passing in a `PrimaryAssembly` for AST compilation routines by [Eirik Tsarpalis](https://github.com/eiriktsarpalis) +* Support for `ToString` in `FSharp.Compiler.SourceCodeServices.StringText` by [Asti](https://github.com/deviousasti) +* Fix an issue with equality comparisons for `StringText` by [Asti](https://github.com/deviousasti) + +Significant changes for consumers: + +* Several APIs no longer require the Reactor thread +* `GetAllUsesOfAllSymbolsInFile` now returns `seq` instead of `FSharpSymbol[]` +* All four `Get*UsesOfAllSymbolsIn*` APIs are no longer asynchronous +* `StructuredDescriptionTextAsync` and `DescriptionTextAsync` are now deprecated, please use `StructuredDescriptionText` and `DescriptionText` instead +* The `hasTextChangedSinceLastTypecheck` optional argument has been removed (it has been unused in Visual Studio since VS 2017) +* The `textSnapshotInfo` optional argument is removed as it only made sense in tandem with `hasTextChangedSinceLastTypecheck` +* `userOpName` is removed from all APIs that are no longer asynchronous + +## Visual Studio 2017-2019 Update 16.7 release notes + +These release notes contain release notes for all F# product release delivered alongside Visual Studio since Visual Studio 2017 and up until Visual Studio 2019 update 16.7. + +### Visual Studio 16.7 + +This release is focused on closing out F# 5 feature development and making Visual Studio tooling improvements. + +#### F# language + +The following features were added to F# 5 preview: + +* String interpolation +* Complete `nameof` design implementation +* `nameof` support for patterns +* `open type` declarations +* Overloads of custom keywords in computation expressions +* Interfaces can be implemented at different generic instantiation + +#### F# compiler and tools + +* Various bug fixes +* Updated semantic classification to better distinguish various F# constructs from one another +* Improvements to performance of various array-based operations in FSharp.Core by [Abel Braaksma](https://github.com/abelbraaksma) +* Various improvements to the F# compiler service by [Eugene Auduchinok](https://github.com/auduchinok) +* Improvements to SourceLink support by [Chet Husk](https://github.com/baronfel) +* Support for `Map.change` by [Fraser Waters](https://github.com/Frassle) + +### Visual Studio 16.6 + +This release is focused on more F# 5 preview features and Visual Studio tooling improvements. + +#### F# language + +The following features were added to F# 5 preview: + +* Support for interop with Default Interface Methods +* Improvements for `#r "nuget"` - allow packages with native dependencies +* Improvements for `#r "nuget"` - allow packages like FParsec that require `.dll`s to be referenced in a particular order +* Improved interop with Nullable Value Types + +#### F# compiler and tools + +* Various bug fixes +* Significant improvements to memory usage for symbol-based operations such as Find All References and Rename, especially for large codebases +* 15% or higher reduction in compile times (as measured by compiling [`FSharpPlus.dll`](https://github.com/fsprojects/FSharpPlus/)) +* Performance improvements for design-time builds by [Saul Rennison](https://github.com/saul) +* Improved stack traces in F# async and other computations, thanks to [Nino Floris](https://github.com/NinoFloris) +* All new F# project types now use the .NET SDK +* Descriptions in completion lists for tooltips +* Improved UI for completion for unimported types +* Bug fix for adding a needed `open` declaration when at the top of a file (such as a script) +* Various improvements to error recovery and data shown in tooltips have been contributed by [Eugene Auduchinok](https://github.com/auduchinok) and [Matt Constable](https://github.com/mcon). +* Various compiler performance improvements by [Steffen Forkmann](https://github.com/forki/) +* Improvements to F# CodeLenses by [Victor Peter Rouven Muller](https://github.com/realvictorprm) +* Better emitted IL for `uint64` literals by [Teo Tsirpanis](https://github.com/teo-tsirpanis) + +### Visual Studio 16.5 + +The primary focus of this release has been improving the [performance and scalability of large F# codebases in Visual Studio](https://github.com/dotnet/fsharp/issues/8255). This work was influenced by working directly with customers who have very large codebases. The performance work is [still ongoing](https://github.com/dotnet/fsharp/issues/6866), but if you have a medium-to-large sized codebase, you should see reduced memory usage. + +Beyond performance enhancements, this release includes a variety of other fixes, many of which were contributed by our wonderful F# OSS community. + +#### F# language + +Several F# preview language features have been merged. You can try them out by setting your `LangVersion` to `preview` in your project file. + +* [F# RFC FS-1076 - From the end slicing and indexing for collections](https://github.com/fsharp/fslang-design/blob/master/preview/FS-1076-from-the-end-slicing.md) has been completed for F# preview +* [F# RFC FS-1077 - Tolerant Slicing](https://github.com/fsharp/fslang-design/blob/master/preview/FS-1077-tolerant-slicing.md) has been completed for F# preview +* [F# RFC FS-1077 - Slicing for 3D/4D arrays with fixed index](https://github.com/fsharp/fslang-design/blob/master/preview/FS-1077-3d-4d-fixed-index-slicing.md) has been completed for F# preview +* [F# RFC FS-1080 - Float32 without dot](https://github.com/fsharp/fslang-design/blob/master/preview/FS-1080-float32-without-dot.md) has been completed for F# preview, contributed by [Grzegorz Dziadkiewicz](https://github.com/gdziadkiewicz) + +#### F# compiler + +* [Support for `--standalone`](https://github.com/dotnet/fsharp/issues/3924) has been added for .NET Core +* Various improvements to error recovery have been contributed by [Eugene Auduchinok](https://github.com/auduchinok) +* [Support for generating an AssemblyInfo from a project file](https://github.com/dotnet/fsharp/issues/3113) has been added +* [Better error reporting for mismatched Anonymous Records](https://github.com/dotnet/fsharp/issues/8091) was contributed by [Isaac Abraham](https://github.com/isaacabraham) +* A bug where [use of type abbreviations could bypass `byref` analysis](https://github.com/dotnet/fsharp/issues/7934) in the compiler has been resolved +* It is now possible to [specify the `[]` attribute](https://github.com/dotnet/fsharp/issues/7897) in F# signature files +* A bug where the [`LangVersion` flag was culture-dependent](https://github.com/dotnet/fsharp/issues/7757) has been resolved +* A bug where [large types and expressions defined in source would lead to a stack overflow](https://github.com/dotnet/fsharp/issues/7673) has been resolved +* A bug where [arbitrary, nonsense attributes could be defined on F# type extesions](https://github.com/dotnet/fsharp/issues/7394) was resolved +* A bug where [exhaustive matches on SByte and Byte literal values emitted a warning](https://github.com/dotnet/fsharp/issues/6928) was resolved +* A bug where [invalid type abbreviations with `byref`s and `byref`-like values](https://github.com/dotnet/fsharp/issues/6133) could be defined was resolved +* A bug where [invalid binary and octal literals would be accepted by the compiler](https://github.com/dotnet/fsharp/issues/5729) was resolved, contributed by [Grzegorz Dziadkiewicz](https://github.com/gdziadkiewicz) +* A bug where [`P/Invoke to "kernel32.dll"` was getting called in a FreeBSD source build of .NET Core](https://github.com/dotnet/fsharp/pull/7858) has been resolved by [Adeel Mujahid](https://github.com/am11) +* Various smaller performance improvements have been added by [Eugene Auduchinok](https://github.com/auduchinok) and [Steffen Formann](https://github.com/forki/) + +#### F# core library + +* A bug where [calling `string` or `.ToString` on `ValueNone` would throw an exception](https://github.com/dotnet/fsharp/issues/7693) has been resolved +* A bug where calling `Async.Sleep` within a sequentially processed set of async expressions wouldn't process sequentially has been resolved, contributed by [Fraser Waters](https://github.com/Frassle) +* An issue in [`Async.Choice` that could lead to memory leaks](https://github.com/dotnet/fsharp/pull/7892) has been resolved, contributed by [Fraser Waters](https://github.com/Frassle) + +#### F# tools for Visual Studio + +* A bug where the Product Version in the About Visual Studio window [mistakenly displayed F# 4.6](https://github.com/dotnet/fsharp/issues/8018) has been resolved +* A bug where the `fsi` type in F# scripts was [incorrectly treated as not defined](https://github.com/dotnet/fsharp/issues/7950) has been resolved + +#### F# open source development experience + +* The FSharp.Compiler.Service build in the F# repository has been moved to use the .NET SDK, contributed by [Chet Husk](https://github.com/baronfel) + +### Visual Studio 16.3 + +This release includes support for F# 4.7, the newest version of the F# language! + +Much of F# 4.7 was dedicated to underlying infrastructural changes that allow us to deliver preview of F# language functionality more effectively. That said, there are still some nice new features delivered as well. + +#### F# language and core library + +We added support for F# 4.7, a minor language release that comes with compiler infrastructure to enable preview features so that we can get feedback on feature designs earlier in the development process. + +The full F# 4.7 feature set is: + +* Support for the `LangVersion` flag, which allows for configuring the F# language version used by the compiler to be F# 4.6 or higher +* Support for [implicit yields](https://github.com/fsharp/fslang-design/blob/master/FSharp-4.7/FS-1069-implicit-yields.md) in array, list, and sequence expressions +* [Indentation requirement relaxations](https://github.com/fsharp/fslang-design/blob/master/FSharp-4.7/FS-1070-offside-relaxations.md) for static members and constructors +* [Relaxing the need for a double-underscore (`__`)](https://github.com/fsharp/fslang-design/blob/master/FSharp-4.7/FS-1046-wildcard-self-identifiers.md) in [member declarations](https://github.com/dotnet/fsharp/pull/6829) and [`for` loops](https://github.com/dotnet/fsharp/pull/6867), contributed by [Gustavo Leon](https://github.com/gusty) +* FSharp.Core now targets `netstandard2.0` instead of `netstandard1.6`, following the deprecation of support for .NET Core 1.x +* FSharp.Core on .NET Core now supports `FSharpFunc.FromConverter`, `FSharpFunc.ToConverter`, and `FuncConvert.ToFSharpFunc` +* FSharp.Core now supports [`Async.Sequential` and an optional `maxDegreeOfParallelism` parameter for `Async.Parallel`](https://github.com/fsharp/fslang-design/blob/master/FSharp.Core-4.7.0/FS-1067-Async-Sequential.md), contributed by [Fraser Waters](https://github.com/Frassle) + +In addition to the F# 4.7 feature set, this release includes support for the following preview F# language features: + +* Support for [`nameof` expressions](https://github.com/fsharp/fslang-design/blob/master/preview/FS-1003-nameof-operator.md) +* Support for opening of static classes + +You can enable this by seeting `preview` in your project file. + +This release also contains the following bug fixes and improvements to the F# compiler: + +* A longstanding issue where the F# compiler could stack overflow with massive records, structs, or other types has been resolved ([#7070](https://github.com/dotnet/fsharp/issues/7070)) +* An issue where specifying invalid inline IL could crash Visual Studio has been resolved ([#7164](https://github.com/dotnet/fsharp/issues/7164) +* Resolution of an issue where copying of a struct would not occur if it was defined in C# and mutated in a member call ([#7406](https://github.com/dotnet/fsharp/issues/7406)) +* A crypto hash of the portable PDB content created by the compiler is not included in the PE debug directory, with a configurable hash set to SHA-256 by default ([#4259](https://github.com/dotnet/fsharp/issues/4259), [#1223](https://github.com/dotnet/fsharp/issues/1223)) +* A bug where `LeafExpressionConverter` ignored `ValueType` and assumed `System.Tuple` has been fixed ([#6515](https://github.com/dotnet/fsharp/issues/6515)) by [Kevin Malenfant](https://github.com/kevmal) +* A bug where `List.transpose` discaded data instead of throwing an exception has been resolved ([#6908](https://github.com/dotnet/fsharp/issues/6908)) by [Patrick McDonald](https://github.com/PatrickMcDonald) +* A bug where `List.map3` gave a misleading error when used on lists of different lengths has been resolved ([#6897](https://github.com/dotnet/fsharp/issues/6897)) by [reacheight](https://github.com/reacheight) + +#### F# tools + +This release also includes a few improvements to the F# tools for Visual Studio: + +* Records are formatted more to look more like canonical declarations and values in tooltips and F# interactive ([#7163](https://github.com/dotnet/fsharp/issues/7163)) +* Properties in tooltips now specify whether or not that are `get`-only, `set`-only, or `get` and `set` ([#7007](https://github.com/dotnet/fsharp/issues/7007)) +* An issue where Go to Definition and other features could not always work across projects when files use forward slashes ([#4446](https://github.com/dotnet/fsharp/issues/4446), [#5521](https://github.com/dotnet/fsharp/issues/5521), [#4016](https://github.com/dotnet/fsharp/issues/4016)) has been fixed, with help from [chadunit](https://github.com/chadunit) +* Issues with anonymous records and debugging have been resolved ([#6728](https://github.com/dotnet/fsharp/issues/6728), [#6512](https://github.com/dotnet/fsharp/issues/6512)) +* A bug where empty hash directives in source could make source text coloring seem random has been resolved ([#6400](https://github.com/dotnet/fsharp/issues/6400), [#7000](https://github.com/dotnet/fsharp/issues/7000)) + +### Visual Studio 16.1 + +This is a relatively minor release for the F# language and tools, but it's not without some goodies! As with the VS 16.0 update, this release also focused on performance of editor tooling. + +#### F# compiler and F# interactive + +* Added `P/Invoke` support to F# interactive on .NET Core ([#6544](https://github.com/Microsoft/visualfsharp/issues/6544)) +* Added a compiler optimization for `Span<'T>` when used in a `for` loop ([#6195](https://github.com/Microsoft/visualfsharp/issues/6195)) +* Added an optimization to avoid an extraneous `Some` allocations for F# options in various scenarios ([#6532](https://github.com/Microsoft/visualfsharp/issues/6532)) +* Changed the execution order of expressions used in the instantiation of Anonymous Records to be top-to-bottom, rather than alphabetical, to match the current experience with normal Records ([#6487](https://github.com/Microsoft/visualfsharp/issues/6487)) +* A bug where very large literal expressions or very large struct declarations could cause the compiler to stack overflow on build has been resolved ([#6258](https://github.com/Microsoft/visualfsharp/issues/6258)) +* A bug where breakpoints would no longer trigger when debugging a function with an Anonymous Records has been fixed ([#6512](https://github.com/Microsoft/visualfsharp/issues/6512)) +* A bug where Anonymous Records passed to constructs expecting an `obj` parameter caused a compiler crash has been fixed ([#6434](https://github.com/Microsoft/visualfsharp/issues/6434)) +* A bug where `for var expr1 to expr2 do ...` loops could result in bizarrely valid (and discarded) syntax has been fixed ([#6586](https://github.com/Microsoft/visualfsharp/issues/6586)) +* A bug where Anonymous Records could not be used properly with events has been fixed ([#6572](https://github.com/Microsoft/visualfsharp/issues/6572)) +* A longstanding bug where extremely large generated parsers in FsLexYacc (over 100 million lines) has been resolved ([#5967](https://github.com/Microsoft/visualfsharp/issues/5976]) +* A longstanding issue in the Type Provider plugin component of the compiler that could leave the door open for a memory leak caused by a type provider has been resolved ([#6409](https://github.com/Microsoft/visualfsharp/issues/6409)) +* Support for `--pathmap` was added to the F# compiler by [Saul Rennison](https://github.com/saul), which resolves an issue where the resulting executable from a compilation would include absolute paths to source files in the embedded F# signature file resource ([#5213](https://github.com/Microsoft/visualfsharp/issues/5213)) +* An optimization to the F# AST that improves its consumption via other tools and enviroments (e.g., [Fable](https://fable.io/)) has been added by [ncave](https://github.com/ncave) ([#6333](https://github.com/Microsoft/visualfsharp/pull/6333)) +* An optimization around traversing information when resolving members has been added by [Steffen Forkmann](https://github.com/forki) ([#4457](https://github.com/Microsoft/visualfsharp/pull/4457)) +* An improvement to error messages such that when a type implementation is missing necessary overrides a list of those missing overrides is reported has been added by [Gauthier Segay](https://github.com/smoothdeveloper) ([#4982](https://github.com/Microsoft/visualfsharp/issues/4982)) + +#### F# tools + +* The Target Framework dropdown for F# projects in the .NET SDK will now include values for all available .NET Core, .NET Standard, and .NET Framework values to ease migrating to .NET Core from .NET Framework on the .NET SDK +* A bug where renaming generic type parameters produces double backtick-escaped names has been fixed ([#5389](https://github.com/Microsoft/visualfsharp/issues/5389)) +* A longstanding problem where Type Providers were redundantly reinstantiated, causing massive allocations over time, has been resolved ([#5929](https://github.com/Microsoft/visualfsharp/issues/5929)) +* A longstanding issue where reading IL needlessly allocated 20MB over a short period of time was been resolved ([#6403](https://github.com/Microsoft/visualfsharp/issues/6403)) +* A bug where the method `GetToolTipText` in the F# compiler service could show the same XML signature for several member overloads has been resolved by [Vasily Kirichenko](https://github.com/vasily-kirichenko) ([#6244](https://github.com/Microsoft/visualfsharp/issues/6244)) + +#### F# open source infrastructure + +Finally, we improved the contribution experience by doing the following: + +* Completed our build from source process so that the F# compiler and core library can be built with the .NET Core source build repository +* Removed our dependency on `netstandard1.6` so that the entire codebase uniformly targets `netstandard2.0` and `net472` +* Added a `.vsconfig` file to the root of the repository so that contributors using Visual Studio don't have to know everything that needs installing up front +* Rewrote our project's [README](https://github.com/microsoft/visualfsharp) to remove potentially confusing information, include a quickstart for getting started with contributing, and attempting to be more inclusive in our messaging about the kinds of changes we'd love to take + +### Visual Studio 16.0 + +F# improvements in Visual Studio 2019 are in three major areas: + +* F# 4.6 +* Major performance improvements for medium and larger solutions +* Lots of open source work by our excellent open source community + +#### F# 4.6 + +This release contains the F# 4.6 language: + +* [Anonymous Record types](https://github.com/fsharp/fslang-design/blob/master/FSharp-4.6/FS-1030-anonymous-records.md) have been added to the language, including full tooling support and the ability to emit them types into JavaScript objects via the [Fable](https://fable.io/) compiler. +* [ValueOption type and ValueOption module function parity with Option type](https://github.com/fsharp/fslang-design/blob/master/FSharp.Core-4.6.0/FS-1065-valueoption-parity.md). +* [tryExactlyOne function for arrays, lists, and sequences](https://github.com/fsharp/fslang-design/blob/master/FSharp.Core-4.6.0/FS-1065-valueoption-parity.md), contributed by [Grzegorz Dziadkiewicz](https://github.com/gdziadkiewicz). + +#### F# compiler and FSharp.Core improvements + +The F# and compiler and FSharp.Core have seen numerous improvements, especially from open source contributors: + +* **fsi.exe** and **fsc.exe** now defaults to .NET Framework 4.7.2, allowing the loading of components targeting this framework or lower ([#4946](https://github.com/Microsoft/visualfsharp/issues/4946)). +* We optimized methods on structs and struct records to perform as well as methods on classes and class-based records (#3057). +* We optimized the emitted IL for combined Boolean logic in F# code (#635). +* We've optimized the use of `+` with strings in F# to call the minimal amount of `String.Concat` calls as possible ([#5560](https://github.com/Microsoft/visualfsharp/issues/5560)). +* We fixed an issue in the FSharp.Core package where some extra directories with test assets were included. FSharp.Core 4.5.5 and 4.6.1 should have the fix ([#5814](https://github.com/Microsoft/visualfsharp/issues/5814)). +* When a user-defined attribute does not inherit from the `Attribute` class, you will now receive a warning, by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* The `AssemblyInformationVersionAttribute` value in a project file now supports arbitrary values to support scenarios such as SourceLink (#4822). +* A bug where illegal syntax with Active Patterns would cause an internal compiler error has been fixed by Steffen Forkmann (#5745). +* A bug where the `Module` suffix was erroneously added to a module in a recursive module to match a type where the only difference is a generic parameter was fixed by BooksBaum (#5794). +* An improvement to the error message when type parameters are not adjacent to a type name has been improved by Alan Ball (#4183). +* The `uint16` literal suffix is listed correctly in the error messages for invalid numeric literals, by Teo Tsirpanis (#5712). +* Error messages for computation expressions no longer state `async` in the message and instead refer to "computation expression(s)", by John Wostenberg (#5343). +* An error message when incorrectly referencing `.dll`s in F# interactive was fixed by Bartoz Sypytkowski (#5416). +* A bug where Statically Resolved Type Parameters couldn't handle calling a member that hides an inherited member was fixed by [Victor Peter Rouven Müller](https://github.com/realvictorprm) ([#5531](https://github.com/Microsoft/visualfsharp/issues/5531)). +* Various smaller performance improvements to the compiler have been added by Steffen Forkmann and Robert Jeppesen. + +#### F# performance improvements + +Another big focus area for F# in Visual Studio 2019 has been performance for medium and large solutions. We addressed some very long-standing issues, some of which dating back to the very first edition of F# tools for Visual Studio. We also got some help from the excellent F# open source community. + +* We've revamped how the F# language service is initialized by Roslyn. Type colorization for larger solutions should generally appear sooner. +* We changed our representation of source text to avoid large allocations over time, especially with bigger files ([#5935](https://github.com/Microsoft/visualfsharp/issues/5935), [#5936](https://github.com/Microsoft/visualfsharp/issues/5936), [#5937](https://github.com/Microsoft/visualfsharp/issues/5937), [#4881](https://github.com/Microsoft/visualfsharp/issues/4881)). +* We changed our build caches for small edits to files to use significantly less memory ([#6028](https://github.com/Microsoft/visualfsharp/issues/6028)). +* We modified a compiler feature that suggests names when unrecognized tokens are typed to only compute these suggestions on-demand, resulting in significant CPU and memory reductions when typing slowly in larger solutions ([#6044](https://github.com/Microsoft/visualfsharp/issues/6044)). +* We changed IntelliSense so that it will no longer show symbols from unopened namespaces by default. This notably improves performance for IntelliSense in projects with many references. This feature can be turned back on in the settings via **Tools > Options > Text Editor > F# > IntelliSense**. +* We improved memory usage when using Type Providers to generate very large amounts of provided types in a completion list (#5599). +* A reduction to CPU and memory usage to an internal string comparison algorithm for suggesting unrecognized names has been fixed by [Avi Avni](https://github.com/aviavni) ([#6050](https://github.com/Microsoft/visualfsharp/pull/6050)). +* A notable source of large string allocations, particularly for IDE tooling, was fixed by [Avi Avni](https://github.com/aviavni) ([#5922](https://github.com/Microsoft/visualfsharp/issues/5922)). +* A notable source of Large Object Heap allocations coming from computing IntelliSense has been fixed by [Chet Husk](https://github.com/baronfel) ([#6084](https://github.com/Microsoft/visualfsharp/issues/6084)) + +#### F# tooling improvements + +In addition to performance improvements, various other improvements to F# tooling for Visual Studio 2019 have been made: + +* The Add `open` statement code fix will now default to adding the `open` statement at the top of the file. +* We fixed a bug where `match!` in user code invalidated structure guidelines and code outlining nodes for subsequent scopes (#5456). +* The editor will now correctly color `byref`, `outref`, and `ref` values as record fields with the mutable value colorization (#5579). +* We fixed a bug where the rename refactoring did not recognize the `'` character in symbol names (#5604). +* We've fixed a longstanding bug where renaming F# script files resulted in a loss of colorization data ([#1944](https://github.com/Microsoft/visualfsharp/issues/1944)). +* We cleaned up IntelliSense so that it doesn't show unrelated items in the list when pressing backspace. +* With "Smart" indentation on, pasting F# code into the editor will now format it to match an appropriate scope based on the current cursor position, implemented by Saul Rennison (#4702). +* An issue where F# editor options weren't syncing has been fixed by [Jakob Majocha](https://github.com/majocha) ([#5997](https://github.com/Microsoft/visualfsharp/issues/5997), [#5998](https://github.com/Microsoft/visualfsharp/issues/5998)). +* A bug where IntelliSense in a constructor within an `inherit` clause wouldn't show the primary constructor has been fixed by [Eugene Auduchinok](https://github.com/auduchinok) ([#3699](https://github.com/Microsoft/visualfsharp/issues/3699)) +* Various smaller improvements to the F# language service have been made by [Eugene Auduchinok](https://github.com/auduchinok) + +##### F# open source infrastructure + +We've fully migrated the F# and F# tools codebase to use the .NET SDK. This dramatically simplifies the contribution process for developers, especially if they are not using Windows. Additionally, [Jakob Majocha](https://github.com/majocha) has helped in cleaning up documents for new contributors in light of the changes to the codebase. + +### Visual Studio 15.9 You can find all tracked VS 15.9 items in the [15.9 milestone](https://github.com/Microsoft/visualfsharp/milestone/24). -### F# Compiler +#### F# Compiler + +* Fix (#4637) - Can't debug FCS when compiled with portable pdb debug symbols, by [Jason Imison](https://github.com/nosami). +* Fix (#5355) - We fixed a bug where extension methods that take `byref` values could mutate an immutable value. +* Fix (#5446) - We improved the compile error information for overloads on `byref`/`inref`/`outref`, rather than displaying the previously obscure error. +* Fix (#5354) - Optional Type Extensions on `byref`s are now disallowed entirely. They could be declared previously, but were unusable, resulting in a confusing user experience. +* Fix (#5294) - We fixed a bug where `CompareTo` on a struct tuple and causing a type equivalence with an aliased struct tuple would result in a runtime exception. +* Fix (#5621) - We fixed a bug where use of `System.Void` in the context of authoring a Type Provider for .NET Standard could fail to find the `System.Void` type at design-time. +* Fix (#5468) - We fixed a bug where an internal error could occur when a partially applied Discriminated Union constructor is mismatched with an annotated or inferred type for the Discriminated Union. +* Fix (#5540) - We modified the compiler error message when attempting to take an address of an expression (such as accessing a property) to make it more clear that it violates scoping rules for `byref` types. +* Fix (#5536) - We fixed a bug where your program could crash at runtime when partially applying a `byref` type to a method or function. An error message will now display. +* Fix (#5459) - We fixed an issue where an invalid combination of a `byref` and a reference type (such as `byref option`) would fail at runtime and not emit an error message. We now emit an error message. + +#### F# Tools for Visual Studio + +* Fix (#5657) - We resolved an issue where metadata for F# assemblies built with the .NET Core SDK was not shown in file properties on Windows. You can now see this metadata by right-clicking an assembly on Windows and selecting **Properties**. +* Fix (#5615) - We fixed a bug where use of `module global` in F# source could cause Visual Studio to become unresponsive. +* Fix (#5515) - We fixed a bug where extension methods using `inref<'T>` would not show in completion lists. +* Fix (#5514) - We fixed a bug where the TargetFramework dropdown in Project Properties for .NET Framework F# projects was empty. +* Fix (#5507) - We fixed a bug where File | New Project on a .NET Framework 4.0 project would fail. + +#### F# OSS Build + +* Feature (#5027) - Set VisualFSharpFull as the default startup project, by [Robert Jeppesen](https://github.com/rojepp). + +### Visual Studio 15.8.5 + +* Fix (#5504) - Internal MSBuild Error when building non-.NET SDK projects with MSBuild parallelism +* Fix (#5518) - Visual Studio-deployed components are not NGEN'd +* Fix ([Devcom 322883](https://developercommunity.visualstudio.com/content/problem/322883/all-net-framework-f-projects-build-to-4500-regardl.html)) - FSharp.Core 4.5.0.0 binary is deployed to FSharp.Core 4.4.3.0 location + +All other closed issues for the VS 15.8 release can be found [here](https://github.com/Microsoft/visualfsharp/milestone/14). + +### F# 4.5 + +We introduced the F# language version 4.5 with this release. This also corresponds with the new 4.5.x family of FSharp.Core (the F# core library). You can read the specs for each of these changes in the [F# RFC repository](https://github.com/fsharp/fslang-design). There are also many improvements to F# tools for Visual Studio with this release. + +#### Releases + +* Visual Studio 2017 update 15.8 +* .NET Core SDK version 2.1.400 or higher + +#### Language features + +* Support for `voidptr` +* `NativePtr.ofVoidPtr` and `NativePtr.toVoidPtr` support +* New types: `inref<'T>`, `outref<'T>` to represent read-only and write-only `byref`s +* Support for `IsByRefLike` structs +* Support for `IsReadOnly` structs +* Full support for production and consumption of `byref` returns +* Support for extension methods for `byref`/`inref`/`outref` +* Support for `match!` in computation expressions +* Relaxed upcast requirements for `yield` in sequence, list, and array expressions +* Relaxed indentation requirements for list and array expressions +* Enumeration cases emitted as public +* Various bug fixes with `byref` programming + +#### FSharp.Core features + +* Version aligned to 4.5.x for the NuGet package and 4.5.0.0 for the binary +* Improved strack traces for `async { }` so that user code can now be seen +* Support for `ValueOption<'T>` +* Support for `TryGetValue` on Map + +#### Compiler improvements + +Improvements to the F# compiler in addition to the previously-mentioned language features are in F# 4.5. These include: + +* Restored ability to inherit from `FSharpFunc` +* Removed ~2.2% of all allocations in the F# compiler +* F# reference normalization support for user control of transitive assembly references written to an output file +* Respecting `WarningsNotAsErrors` +* Error message improvement when branches of a pattern match do not return the same type +* Respecting `#nowarn "2003"` +* Other smaller performance improvements and many bug fixes + +#### Tooling improvements + +Significant improvements in the F# tools, such as performance enhancements and some new editor features are included this release. As always, with a large number of contributions from the F# open source community. Here are the highlights: + +* We improved IntelliSense performance for .NET SDK-style projects of all forms, including those that use multi-targeting. +* A community-driven effort to analyze and improve IntelliSense performance for very large files was contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko),[ Steffen Forkmann](https://github.com/forki), and [Gauthier Segay](https://github.com/smoothdeveloper). IntelliSense in very large files (10k+ lines of code) is roughly twice as fast now. +* The warning for an outdated FSharp.Core (despite the package being installed) is no longer present in .NET SDK-style projects. +* The description tooltip that displays XML documentation for a member after . in IntelliSense no longer times out after 10 seconds. +* A bug where you could not set breakpoints in object constructor arguments has been fixed. +* A bug where a renamed symbol would be duplicated when it is a generic parameter has been fixed. +* Templates for .NET Framework (classic F# templates) now consume FSharp.Core from a NuGet package, to align with .NET SDK F# templates. +* Automatic, transactional brace completion is now available for `()`, `[]`, `{}`, `[||]`, and `[<>]` brace pairs. We did this work in collaboration with [Gibran Rosa](https://github.com/gibranrosa). +* You can now go to definition with **Ctrl + Click** on an F# symbol. The settings for this gesture are also respected in the **Tools > Options** window. +* The IntelliSense performance UI has been modified to allow configuration of stale typecheck information for various IDE features. Explanations for each option are now present in tooltips for the settings. +* Brace match highlighting now correctly highlights braces, completed in collaboration with [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* Go to definition now navigates correctly when a type is defined recursively, contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* A bug where an auto-imported namespace wasn't opened when the top of a file was empty has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* A bug where `printf` specifiers that contained dots were miscolored has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* A bug where all opens were considered unused inside of a recursive module has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* Autocompletion for attributes now only suggests options that are actually attributes, contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* Signature Help tooltips are now generated for Type Provider static parameters at the constructor call site, contributed by[Vasily Kirichenko](https://github.com/vasily-kirichenko). +* A bug where value types used as units of measure were colored as reference types has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +* A bug where semantic colorization could disappear for some files while scrolling has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). +There is now an experimental CodeLens implementation, contributed by [Victor Peter Rouven Müller](https://github.com/realvictorprm). You can turn it on in **Options > Text Editor > F# > Code Lens**. +* A bug where the F# compiler service would incorrectly elide the module names in XML documentation has been fixed by [Sebastian Urban](https://github.com/surban). +* Code that uses `Dictionary` with `ContainsKey` and subsequent `Item` calls has been changed to use `TryGetValue`, by [Eugene Auduchinok](https://github.com/auduchinok). +* [Jakob Majoka](https://github.com/majocha) also contributed in the process of consuming a different API for FSharpToolTip. + +#### Infrastructure, Packaging, and Open Source Improvements + +We made the following enhancements to infrastructure, packaging, and our open source contribution experience: + +* The F# compiler distributed with Visual Studio no longer installs as a singleton in the F# Compiler SDK location. It is now fully side-by-side with Visual Studio, meaning that side-by-side installations of Visual Studio wil finally have truly side-by-side F# tooling and language experiences. +* The FSharp.Core NuGet package is now signed. +* ETW logging has been added to the F# tools and compiler. +* The very large `control.fs`/`control.fsi` files in FSharp.Core have been split into `async.fs`/`async.fsi`, `event.fs`/`event.fsi`, `eventmodule.fs`/`eventmodule.fsi`, `mailbox.fs`/`mailbox.fsi`, and `observable.fs`/`observable.fsi`. +* We added .NET SDK-style versions of our project performance stress test artifacts. +* We removed Newtonsoft.json from our codebase, and you now have one less package downloaded for OSS contributors. +* We now use the latest versions of System.Collections.Immutable and System.Reflection.Metadata. + +### F# 4.1 + +#### Releases + +* Visual Studio 2017 updates 15.0 to 15.8 (exclusive) +* .NET Core SDK versions 1.0 to 2.1.400 (exclusive) + +#### Language and Core Library features + +* Struct tuples +* Initial support for consuming C#-style `ref` returns +* Struct record support with the `[]` attribute +* Struct Discriminated Union support with the `[]` attribute +* `Result<'TSuccess, 'TFailure>` type, with supporting functions in FSharp.Core +* Support for the `fixed` keyword to pin a pointer-tyle local to the stack +* Underscores in numeric literals +* Caller Info Attribute Argument support +* `namespace rec` and `module rec` to support mutually referential types and functions within the same file +* Implicit "Module" suffix added to modules that share the same name as a type +* Tuple equality for F# tuples and `System.Tuple` + +#### Compiler improvements + +* Support for generating Portable PDBs +* Significant improvements to error messages, particularly to aid with suggestions +* Performance improvements +* Interoperability improvements +* Support for geenerating F# AssymblyInfo from properties for .NET SDK projects +* `--debug:full` support for F# on .NET Core on Windows +* `MakeTuple` support for struct tuples +* Warnings are forwarded when searching for method overloads +* Support for emitting an enum-specific warning when pattern matching over one +* Many smaller bug fixes + +#### FSharp.Core features + +* Support for `NativePtr.ByRef` +* Support for `Async.StartImmediateAsTask` +* Support for `Seq.transpose`/`Array.transpose`/`List.transpose` +* `IsSerializable` support for `Option` and `Async<'T>` +* Many smaller bug fixes + +#### IDE features for F# tools in Visual Studio + +Most items here contributed by community members. + +* Default installation of F# wherever .NET Core is installed +* Significant memory reductions in F# tooling +* IntelliSense Filters and Glyphs +* Support for Go to All +* Find all Reference support +* In-memory cross-project references support +* QuickInfo supports type colorization +* QuickInfo supports navigable links that will invoke Go to Definition +* Inline Rename support +* Go to Definition from F# to C# support +* Semantic document highlighting for selected symbols +* Support for Structured Guidelines and code outlining, which is toggleable +* Support for `EditorBrowsable(EditorBrowsableState.Never)` +* Code fix for making Record and Discriminated Union case lables upper-case +* Code fix to make suggestions for an unkown identifier +* Code fix for prefixing or replacing an unused value with an underscore +* Code fix to add the `new` keyword to a disposable type +* Code fix to add an `open` statement at the top for a symbol coming from an unopened namespace or module +* Code fix to simplify a name by removing unnecessary namespace qualifiers +* Graying out unused values in the editor +* Colorized `fsi.exe` when ran as a standalone console application +* Autocompletion support, including symbols from unopened namespaces +* Colorization for mutable values to distinguish them from immutable values +* Support for move up/down on solution folder nodes +* Support for Blue (High Contrast) theming +* Full support for .NET Core and .NET Standard projects, with the ability to create new ASP.NET Core projects in F# +* Full support for ASP.NET Web SDK tooling, such as Azure publish UI, for F# projects +* Property page auto-sizing support for different monitors +* Smart indentation support which auto-indents based on scope and auto-deindents for bracket-like characters +* XML documentation comment width scaling to prevent it running horizontally off the screen +* Multiple settings pages to modify tooling settings +* Support for Drag and Drop across folders +* Support for nightly builds of the tools +* Expanded debugger view for lists from 50 items to 5000 items +* Support for Optimization APIs in the compiler service +* Support for `IsNameGenerated` in the F# symbols API + +## FSharp Compiler Service Versions Release notes + +## 37.0.0 + +This release bring a number of new changes, including a massive enhancement to SemanticClassification types thanks to @cartermp. + +From dotnet/fsharp:333eb82c8..d9e070a9d: + +* now allows for multiple implementations of generic interfaces (preview feature) (thanks @0x53A!) +* the default assembly set for script resolution now includes System.Numerics (thanks @KevinRansom) +* #r nuget package resolution is now committed eagerly, instead of delayed (thanks @KevinRansom) +* reduced allocations for some strings in the compiler (thanks @kerams) +* better printing for SRTP constraints (thanks @abelbraaksma/@realvictorprm) +* more expressive DUs for semantic classification (thanks @cartermp) +* remove legacymsbuildreferenceresolver (thanks @KevinRandom) +* supply witnesses for op_UnaryPlus (thanks @TIHan) +* clean up CE classifications (thanks @cartermp) +* Fixed tostring/equality for StringText (thanks @deviousasti) +* Fixed error text for FS0874 +* Disallow assignment to C# Const/Readonly properties (thanks @baronfel) +* Allow Int64.MinValue as a valid nativeint literal (thanks @abelbraaksma) +* Enhancements to the nameof feature (preview feature) +* String interpolation (preview feature) + +### 36.0.3 + +This is a small bugfix release that fixes a nuspec package dependency issue with Sourcelink + +### 36.0.2 + +This is a small bugfix release that I'm making primarily to publish a version +of FCS with sourcelink enabled, so that tooling users can make use of that information. + +From dotnet/fsharp:079276b4b..37d0cccec: + +* Fixes for `do!` handling in computation expressions (thanks @baronfel) +* Add missing versions in FCS' Interactive header (thanks @nightroman) +* Support `Source`-translation in `match!` expressions (thanks @baronfel) +* Ensure stack traces from uncaught exceptions in CEs are maintained (thanks @NinoFloris) +* Better handling of `inline` in witness-passing codepaths (thanks @dsyme) +* Enable publishing of FCS with sourcelink (thanks @baronfel) +* Extend `nameof` to support naming generic parameters (`nameof<'t>`) and instance members (`nameof(Unchecked.defaultof.Property)`) (thanks @dsyme) + +### 36.0.1 + +From dotnet/fsharp:522dd906c..16bca5aef: + +* Fixes to attribute range parsing (thanks @auduchinok) +* Added nested exception details to Type Provider load errors (thanks @dsyme) +* Improved error messages around unknown identifiers in patterns (thanks @jbeeko) +* Better dependency probing behavior with Facade assemblies (thanks @KevinRansom) +* APIs for programmatically adding and retrieving bindings in an FSI session (thanks @TIHan) +* Optional parameter on `FSharpChecker.FindBackgroundReferencesInFile` API to allow for stale results (thanks @TIHan) +* Better tooltips for function arguments (thanks @mcon) +* Many performance tweaks to various compiler function implementations (thanks @forki) +* Typo fixes in the AST (thanks @auduchinok) +* Better IL emitted for usages of static members as System.Action (thanks @MoFtZ) +* Allow for indexers to specify a type annotation (thanks @TIHan) +* Allow languages/scripts that have no notion of upper-case to use their characters for DU identifiers (thanks @KevinRansom) +* more optimized comparison/equality for DateTime (thanks @cartermp) +* add support for `char` for the `GenericZero/GenericOne` mechanisms (thanks @Happypig375) +* enhancements for the dependencymanager's resolution for native scripts (thanks @KevinRansom) +* more consistent support for type-directed nullable parameters (thanks @dsyme) +* fix FSI's ordering of out-of-order dlls in nuget packages (thanks @KevinRansom) +* New SyntaxTree.Paren syntax node (thanks @auduchinok) +* add SRTP witness solutions (via the new `CallWithWitnesses` pattern) (thanks @dsyme) + +### 35.0.0 + +This version bumps the major due to API surface area changes in the AST and TAST. In addition, there's a new package for the +built-in Nuget dependency manager for FSI: FSharp.DependencyManager.Nuget + +Members are now in SyntaxTree/SyntaxTreeOps and TypedTree/TypedTreeBasics/TypedTreeOps/TypedTreePickle. + +From dotnet/fsharp:d1a3d0705..522dd906c: + +* Improved error recovery from patterns (thanks @auduchinok) +* Smaller IL Emit for unsigned 64-bit constants (thanks @teo-tsirpanis) +* Improved ProvidedTypes Type generation (thanks @DedSec256) +* Improved CodeLenses provided (thanks @realvictorprm) +* Optimize internal member calculations in PrettyNaming and items lookup (thanks @auduchinok) +* More fixes to compiler internals, ranges, etc (thanks @auduchinok) +* Support for consumption of C# Default Interfaces +* Better encapsulation of ProvidedExpr members (thanks @DedSec256) + +### 34.1.1 + +From dotnet/fsharp:3777cd4d8..836da28c0: + +* Slight tweaks to error messages around numeric literals (Thanks @Happypig375) +* Deny taking native address of an immutable local value (Thanks @TIHan) +* Fixes to reported ranges for wildcard self-identifiers, module abbreviations, nested modules, attributes, nested types, and fields (Thanks @auduchinok) +* Better compiler error recovery for errors in constructor expressions (Thanks @auduchinok) +* Fix handling of F# Options in C# members with regards to nullable type interop (Thanks @TIHan) +* Move dependency handling of native dlls to the DependencyManager (Thanks @KevinRansom) + +### 34.1.0 + +From dotnet/fsharp:3af8959b6..9d69b49b7: + +* set default script TFM to netcoreapp3.1 if none found +* improve C#-nullable and optional interop (RFC FS-1075) +* Add type name to `undefined name error` if known +* improve printing via %A/fsi +* misc. improvements to DependencyManager +* improve type provider support for .netcoreapp3.1 target frameworks. +* New, optimized find-all-references API with reduced memory usage. +* better error messages for failed overload resolution + +### 34.0.1 + +Contains commits from 32b124966 to d7018737c from dotnet/fsharp. Notable changes include: + +* lowered allocations for large strings and char arrays (notably source file texts) +* improved support for byref-like rules with regards to type abbreviations +* better support for scopes in recursive modules +* better location of .net core reference assemblies +* lowered allocations for several internal compiler structures +* better error messages for anonymous record mismatches +* FSharpChecker learned how to keep background symbol uses +* Project cracker/project cracker tool were removed +* Better support for consuming C# in-ref parameters +* new services around simplifying names and finding unused declarations +* package management in scripts (in preview) +* and-bang syntax support (in preview) + +### 33.0.1 + +Integrate dotnet/fsharp from 4f5f08320 to 7b25d7f82. Notable changes include: + +* Addition of the FsharpUnionCase.HasFields property +* FCS builds entirely on .Net Core now +* Better debug information for ranges +* Support for Literal values in signature files +* Using memory-mapped files cross-platform to read IL. + +### 33.0.0 + +Integrate dotnet/fsharp from 48f932cf8 to 085985140. Notable changes include: + + allowing '_' as a self-identifier + events for FSI evaluation lifecycle events + enhancements to FSI return-values + fixed parsing for langversion CLI arguments + allow cancellation of FSI interactions + ToString fixes for value options + Fixes for code generation in autogenerated members for very large records + make ranges of member declarations capture the entire member + improve error recovery in the parser + improve logic for auto-detecting framework assemblies for FSI + +### 32.0.0 + +* integrate dotnet/fsharp from e1b8537ee to 48f932cf8 +* notable changes include: +* (preview) nameof +* (preview) open static classes +* Fixed 64-bit integer literal parsing +* Better exhaustiveness checking for byte and sbyte pattern matches +* Better native resource handling +* Script-host assembly load events + +### 31.0.0 + +* Integrate dotnet/fsharp from 5a8f454a1 to 05c558a61 +* Notable changes include: + * Removal of the `Microsoft.FSharp.Compiler.SourceCodeServices` namespace + * A new API for determining if an identifier needs to be quoted is available: `FSharp.Compiler.LexHelp.FSharpKeywords.DoesIdentifierNeedQuotation` + * Enhancements to the correctness of PDBs + * Better string formatting of records and values + * More stack overflow fixes in the compiler + * Inline IL parsing error handling + * `LeafExpressionConverter` handles struct tuples + * `FSharpChecker` now can parse a file without caching: `ParseFileNoCache` + +### 30.0.0 + +* Integrate dotnet/fsharp from 25560f477 to 5a8f454a1 +* Notable improvements include: + * performance improvements + * FCS APIs for FSComp and Implement Interface + * line directive handling + * improved performance when computing quick fix suggestions + +### 29.0.1 + +* Fix versioning of the assembly + +### 29.0.0 + +* Integrate visualfsharp master from 165b736b9 (2019-03-29) to 25560f477 (2019-05-24) +* Notable improvements include: + * Improved Portable PDB debugging + * Misc IL generation fixes + * Representing inlined mutable variables in the AST + * Moving on from net46 targeting + * Fixes for anonymous record generation + * Dependency updates + * Checking for constructors in FSharpMemberOrFunctionOrValue + * Fix unused opens false positive for record fields + +### 28.0.0 + +* Integrate visualfsharp master from efb57cf56 to 8dfc02feb +* Notable improvements include: + * XmlDoc fixes for overloads + * Fixes for deterministic compilation + * Improved tail-recursion when processing large expressions + * Better tooltip detection for operators with constraints + * FSharp.Compiler.Service nuget now uses net461, netstandard2.0 and FSharp.Core 4.6.2 + * updated lexer and parser implementations to reduce stackoverflow likelihood on .net core + +### 27.0.1 + +* Integrate visualfsharp master from 5a5ca976ec296d02551e79c3eb8e8db809e4304d to 2c8497bb097d5c5d3ef12f355594873838a48494 +* Notable improvements include: + * Anonymous Record support for expressions + * Union Case Naming fixes + * Trimming of the nuget package dependencies from 26.0.1 + +### 26.0.1 + +* Integrate visualfsharp master to 99e307f3a3ef2109ba6542ffc58affe76fc0e2a0 + +### 25.0.1 + +* Integrate visualfsharp master to 15d9391e78c554f91824d2be2e69938cd811df68 + +### 24.0.1 + +* Integrate visualfsharp master to 59156db2d0a744233d1baffee7088ca2d9f959c7 + +### 23.0.3 + +* Clarify package authors + +### 23.0.1 + +* Integrate visualfsharp master to ee938a7a5cfdf4849b091087efbf64605110541f + +### 22.0.3 + +* [Add entity.DeclaringEntity](https://github.com/Microsoft/visualfsharp/pull/4633), [FCS feature request](https://github.com/fsharp/FSharp.Compiler.Service/issues/830) + +### 22.0.2 + +* Use correct version number in DLLs (needed until https://github.com/Microsoft/visualfsharp/issues/3113 is fixed) + +### 22.0.1 + +* Integrate visualfsharp master +* Includes recent memory usage reduction work for ByteFile and ILAttributes + +### 21.0.1 + +* Use new .NET SDK project files +* FSharp.Compiler.Service nuget now uses net461 and netstandard2.0 +* FSharp.Compiler.Service netstandard2.0 now supports type providers + +### 20.0.1 + +* Integrate visualfsharp master + +### 19.0.1 + +* Rename ``LogicalEnclosingEntity`` to ``ApparentEnclosingEntity`` for consistency int he F# codebase terminology. +* Rename ``EnclosingEntity`` to ``DeclaringEntity``. In the case of extension properties, ``EnclosingEntity`` was incorrectly returning the logical enclosing entity (i.e. the type the property appears to extend), and in this case ``ApparentEnclosingEntity`` should be used instead. + +### 18.0.1 + +* Integrate visualfsharp master + +### 17.0.2 + +* Integrate visualfsharp master + +### 16.0.3 + +* [File name deduplication not working with ParseAndCheckFileInProject](https://github.com/fsharp/FSharp.Compiler.Service/issues/819) + +### 16.0.2 + +* [ProjectCracker returns *.fsi files in FSharpProjectOptions.SourceFiles array](https://github.com/fsharp/FSharp.Compiler.Service/pull/812) +* [Fix line endings in the Nuget packages descriptions](https://github.com/fsharp/FSharp.Compiler.Service/pull/811) + +### 16.0.1 + +* FSharpChecker provides non-reactor ParseFile instead of ParseFileInProject +* Add FSharpParsingOptions, GetParsingOptionsFromProjectOptions, GetParsingOptionsFromCommandLine + +### 15.0.1 + +* Integrate latest changes from visualfsharp +* Add implementation file contents to CheckFileResults +* Fix non-public API in .NET Standard 1.6 version + +### 14.0.1 + +* Integrate latest changes from visualfsharp +* Trial release for new build in fcs\... + +### 13.0.1 + +* Move docs --> docssrc + +### 13.0.0 + +* Move FSharp.Compiler.Service.MSBuild.v12.dll to a separate nuget package + +### 12.0.8 + +* Set bit on output executables correctly + +### 12.0.7 + +* Integrate visualfsharp master + +### 12.0.6 + +* [758: Fix project cracker when invalid path given](https://github.com/fsharp/FSharp.Compiler.Service/pull/758) + +### 12.0.5 + +* Remove dependency on System.ValueTuple + +### 12.0.3 + +* [De-duplicate module names again](https://github.com/fsharp/FSharp.Compiler.Service/pull/749) + +### 12.0.2 + +* De-duplicate module names + +### 12.0.1 + +* [Integrate visualfsharp and fsharp](https://github.com/fsharp/fsharp/pull/696) + +### 11.0.10 + +* [Fix F# Interactive on Mono 4.0.9+](https://github.com/fsharp/fsharp/pull/696) + +### 11.0.9 + +* [Make incremental builder counter atomic](https://github.com/fsharp/FSharp.Compiler.Service/pull/724) +* [Add IsValCompiledAsMethod to FSharpMemberOrFunctionOrValue](https://github.com/fsharp/FSharp.Compiler.Service/pull/727) +* [Check before ILTypeInfo.FromType](https://github.com/fsharp/FSharp.Compiler.Service/issues/734) +* [Transition over to dotnet cli Fsproj](https://github.com/fsharp/FSharp.Compiler.Service/issues/700) + +### 11.0.8 + +* Depend on FSharp.Core package + +### 11.0.6 + +* Fix [stack overflow exception](https://github.com/fsharp/FSharp.Compiler.Service/issues/672) + +### 11.0.4 + +* Fix [out of range exception](https://github.com/fsharp/FSharp.Compiler.Service/issues/709) + +### 11.0.2 + +* Integrate fsharp\fsharp and Microsoft\visualfsharp to 262deb017cfcd0f0d4138779ff42ede7dbf44c46 + +### 11.0.1 + +* Integrate fsharp\fsharp and Microsoft\visualfsharp to d0cc249b951374257d5a806939e42714d8a2f4c6 + +### 10.0.3 + +* [Expose assumeDotNetFramework in FSharpChecker.GetProjectOptionsFromScript](https://github.com/fsharp/FSharp.Compiler.Service/pull/699) +* [SemanticClassificationType should not be internal](https://github.com/fsharp/FSharp.Compiler.Service/pull/696) + +### 10.0.1 + +* [Adds FormatValue to FsiEvaluationSession, using the fsi object values for formatting](https://github.com/fsharp/FSharp.Compiler.Service/pull/686) + +### 10.0.0 + +* Integrate fsharp\fsharp and Microsoft\visualfsharp to c3e55bf0b10bf08790235dc585b8cdc75f71618e +* Integrate fsharp\fsharp and Microsoft\visualfsharp to 11c0a085c96a91102cc881145ce281271ac159fe +* Some API changes for structured text provision for tagged structured text + +### 9.0.0 + +* Update names of union fields in AST API +* Fix load closure for ParseAndCheckInteraction +* [Fix #631 compiler dependency on MSBuild](https://github.com/fsharp/FSharp.Compiler.Service/pull/657) +* Fixed netcore codegen on Linux +* Explicit error when cracker exe is missing + +### 8.0.0 + +* Integrate fsharp\fsharp and Microsoft\visualfsharp to c494a9cab525dbd89585f7b733ea5310471a8001 +* Then integrate to 2002675f8aba5b3576a924a2e1e47b18e4e9a83d +* [Add module values to navigable items](https://github.com/fsharp/FSharp.Compiler.Service/pull/650) +* Optionally remove dependency on MSBuild reference resolution https://github.com/fsharp/FSharp.Compiler.Service/pull/649 +* [Compiler api harmonise](https://github.com/fsharp/FSharp.Compiler.Service/pull/639) +* Various bits of work on .NET Core version (buildable from source but not in nuget package) + +### 7.0.0 + +* Integrate fsharp\fsharp and Microsoft\visualfsharp to 835b79c041f9032fceeceb39f680e0662cba92ec + +### 6.0.2 + +* [Fix #568: recognize provided expressions](https://github.com/fsharp/FSharp.Compiler.Service/pull/568) + +### 6.0.1 + +* [Fix ProjectFileNames order when getting project options from script](https://github.com/fsharp/FSharp.Compiler.Service/pull/594) + +### 6.0.0 + +* Switch to new major version on assumption integrated F# compiler changes induce API change + +### 5.0.2 + +* Integrate Microsoft\visualfsharp to 688c26bdbbfc766326fc45e4d918f87fcba1e7ba. F# 4.1 work + +### 5.0.1 + +* [Fixed dependencies in nuget package](https://github.com/fsharp/FSharp.Compiler.Service/pull/608) + +### 5.0.0 + +* Fixed empty symbol declared pdb #564 from kekyo/fix-empty-pdb +* .NET Core ProjectCracker - updated version and dependencies +* Properly embed 'FSIstrings' resource, fixes #591 +* make build.sh work on windows (git bash). +* Added default script references for .NET Core +* Store useMonoResolution flag +* Updated MSBuild version +* Assume FSharp.Core 4.4.0.0 + +### 4.0.1 + +* Integrate Microsoft\visualfsharp and fsharp\fsharp to master (including portable PDB) +* Remove .NET Framework 4.0 support (now needs .NET Framework 4.5) + +### 4.0.0 + +* Integrate Microsoft\visualfsharp and fsharp\fsharp to master + +### 3.0.0.0 + +* #538 - BackgroundCompiler takes a very long time on a big solution with a very connected project dependency graph +* #544 - Losing operator call when one of operands is application of a partially applied function +* #534 - Function valued property erasing calls +* #495 - Detupling missing when calling a module function value +* #543 - Tuple not being destructured in AST +* #541 - Results of multiple calls to active pattern are always bound to variable with same name +* #539 - BasicPatterns.NewDelegate shows same value for different arguments + +### 2.0.0.6 + +* #530 - Adjust ProjectCracker NuGet for VS/NuGet + +### 2.0.0.5 + +* #527 - Provide API that includes printf specifier arities along with ranges + +### 2.0.0.4 + +* #519 - Change nuget layout for ProjectCracker package +* #523 - Project cracking: spaces in file paths + +### 2.0.0.3 + +* #508 - Integrate visualfsharp/master removal of Silverlight #if +* #513 - Make CrackerTool `internal` to prevent accidental usage +* #515 - Add simple Visual Studio version detection for project cracker + +### 2.0.0.2 + +* Integrate visualfsharp/master and fsharp/master --> master +* Expose QualifiedName and FileName of FSharpImplementationFileContents +* Add FSharpDiagnostic.ErrorNumber + +### 2.0.0.1-beta + +* Fix 452 - FSharpField.IsMutable = true for BCL enum cases +* Fix 414 - Add IsInstanceMemberInCompiledCode + +### 2.0.0.0-beta + +* Feature #470, #478, #479 - Move ProjectCracker to separate nuget package and DLL, used ProjectCrackerTool.exe to run +* Feature #463 - Expose slot signatures of members in object expressions +* Feature #469, #475 - Add EvalExpressionNonThrowing, EvalInteractionNonThrowing, EvalScriptNonThrowing +* Fix #456 - FCS makes calls to kernel32.dll when running on OSX +* Fix #473 - stack overflow in resolution logic +* Fix #460 - Failure getting expression for a provided method call + +### 1.4.2.3 - + +* Fix bug in loop optimization, apply https://github.com/Microsoft/visualfsharp/pull/756/ + +### 1.4.2.2 - + +* #488 - Performance problems with project references + +### 1.4.2.1 - + +* #450 - Correct generation of ReferencedProjects + +### 1.4.2.0 - + +* Fix bug in double lookup of cache, see https://github.com/fsharp/FSharp.Compiler.Service/pull/447 + +### 1.4.1 - + +* Add pause before backgrounnd work starts. The FCS request queue must be empty for 1 second before work will start +* Write trace information about the reactor queue to the event log +* Rewrite reactor to consistently prioritize queued work +* Implement cancellation for queued work if it is cancelled prior to being executed +* Adjust caching to check cache correctly if there is a gap before the request is executed + +### 1.4.0.9 - + +* FSharpType.Format fix +* Disable maximum-memory trigger by default until use case ironed out + +### 1.4.0.8 - + +* FSharpType.Format now prettifies type variables. If necessary, FSharpType.Prettify can also be called +* Add maximum-memory trigger to downsize FCS caches. Defaults to 1.7GB of allocaed memory in the system + process for a 32-bit process, and 2x this for a 64-bit process + +### 1.4.0.7 - + +* fix 427 - Make event information available for properties which represent first-class uses of F#-declared events +* fix 410 - Symbols for C# fields (and especially enum fields) +* Expose implemented abstract slots +* Fix problem with obscure filenames caught by Microsoft\visualfsharp tests +* Integrate with visualfsharp master + +### 1.4.0.6 - + +* fix 423 - Symbols for non-standard C# events +* fix 235 - XmlDocSigs for references assemblies +* fix 177 - GetAllUsesOfAllSymbolsInFile returns nothing for C# nested enum +* make Internal.Utilities.Text.Lexing.Position a struct +* Exposing assembly attributes on FSharpAssemblySignature +* clean up IncrementalFSharpBuild.frameworkTcImportsCache + +### 1.4.0.5 - + +* add more entries to FSharpTokenTag + +### 1.4.0.4 - + +* add more entries to FSharpTokenTag +* add PrettyNaming.QuoteIdentifierIfNeeded and PrettyNaming.KeywordNames + +### 1.4.0.3 - + +* integrate Microsoft/visualfsharp OOB cleanup via fsharp/fsharp +* Make Parser and Lexer private + +### 1.4.0.2 - + +* #387 - types and arrays in F# attribute contructor arguments + +### 1.4.0.1 - F# 4.0 support + +* Use FSharp.Core 4.4.0.0 by default for scripting scenarios if not FSharp.Core referenced by host process + +### 1.4.0.0-beta - F# 4.0 support + +* Integrate F# 4.0 support into FSharp.Compiler.Service + +### 1.3.1.0 - + +* simplified source indexing with new SourceLink +* Add noframework option in AST compiler methods + +### 0.0.90 - + +* Add fix for #343 Use ResolveReferences task +* Expose BinFolderOfDefaultFSharpCompiler to editors +* Fix the registry checking on mono to avoid unnecessary exceptions being thrown + +### 0.0.89 - + +* Fix output location of referenced projects + +### 0.0.88 - +* Added Fix to al +* low implicit PCL references to be retrieved + +### 0.0.87 - + +* Don't report fake symbols in indexing #325 +* Add EnclosingEntity for an active pattern group #327 +* Add ImmediateSubExpressions #284 +* integrate fsharp/fsharp master into master + +### 0.0.85 - + +* Fix for FSharpSymbolUse for single case union type #301 +* Added supprt for ReturnParameter in nested functions + +### 0.0.84 - + +* Added curried parameter groups for nested functions + +### 0.0.83 - + +* Add Overloads to the symbols signature so it is publicly visible +* Update OnEvaluation event to have FSharpSymbolUse information available + +### 0.0.82 - + +* Better support for Metadata of C# (and other) Assemblies. +* Expose the DefaultFileSystem as a type instead of anonymous + +### 0.0.81 - + +* Update GetDeclarationListSymbols to expose FSharpSymbolUse +* Improve reporting of format specifiers + +### 0.0.80 - + +* Update to latest F# 3.1.3 (inclunding updated FsLex/FsYacc used in build of FCS) +* Report printf specifiers from Service API +* Improve Accessibility of non-F# symbols + +### 0.0.79 - + +* Do not use memory mapped files when cracking a DLL to get an assembly reference +* Fix for multilanguage projects in project cracker + +### 0.0.78 - + +* Reduce background checker memory usage +* add docs on FSharp.Core +* docs on caches and queues + +### 0.0.77 - + +* Update to github.com/fsharp/fsharp 05f426cee85609f2fe51b71473b07d7928bb01c8 + +### 0.0.76 - -* Fix (#4637) - Can't debug FCS when compiled with portable pdb debug symbols, by [Jason Imison](https://github.com/nosami). -* Fix (#5355) - We fixed a bug where extension methods that take `byref` values could mutate an immutable value. -* Fix (#5446) - We improved the compile error information for overloads on `byref`/`inref`/`outref`, rather than displaying the previously obscure error. -* Fix (#5354) - Optional Type Extensions on `byref`s are now disallowed entirely. They could be declared previously, but were unusable, resulting in a confusing user experience. -* Fix (#5294) - We fixed a bug where `CompareTo` on a struct tuple and causing a type equivalence with an aliased struct tuple would result in a runtime exception. -* Fix (#5621) - We fixed a bug where use of `System.Void` in the context of authoring a Type Provider for .NET Standard could fail to find the `System.Void` type at design-time. -* Fix (#5468) - We fixed a bug where an internal error could occur when a partially applied Discriminated Union constructor is mismatched with an annotated or inferred type for the Discriminated Union. -* Fix (#5540) - We modified the compiler error message when attempting to take an address of an expression (such as accessing a property) to make it more clear that it violates scoping rules for `byref` types. -* Fix (#5536) - We fixed a bug where your program could crash at runtime when partially applying a `byref` type to a method or function. An error message will now display. -* Fix (#5459) - We fixed an issue where an invalid combination of a `byref` and a reference type (such as `byref option`) would fail at runtime and not emit an error message. We now emit an error message. +* Fix #249 - Fix TryFullName when used on namespaces of provided erased type definitions +* Add OnEvaluation event to FCS to allow detailed information to be exposed -### F# Tools for Visual Studio +### 0.0.75 - -* Fix (#5657) - We resolved an issue where metadata for F# assemblies built with the .NET Core SDK was not shown in file properties on Windows. You can now see this metadata by right-clicking an assembly on Windows and selecting **Properties**. -* Fix (#5615) - We fixed a bug where use of `module global` in F# source could cause Visual Studio to become unresponsive. -* Fix (#5515) - We fixed a bug where extension methods using `inref<'T>` would not show in completion lists. -* Fix (#5514) - We fixed a bug where the TargetFramework dropdown in Project Properties for .NET Framework F# projects was empty. -* Fix (#5507) - We fixed a bug where File | New Project on a .NET Framework 4.0 project would fail. +* Do not use shared cursor for IL binaries (https://github.com/fsprojects/VisualFSharpPowerTools/issues/822) -### F# OSS Build +### 0.0.74 - -* Feature (#5027) - Set VisualFSharpFull as the default startup project, by [Robert Jeppesen](https://github.com/rojepp). +* Extension members are returned as members of current modules +* Fix exceptions while cross-reference a type provider project -## Visual Studio 15.8.5 +### 0.0.73 - -* Fix (#5504) - Internal MSBuild Error when building non-.NET SDK projects with MSBuild parallelism -* Fix (#5518) - Visual Studio-deployed components are not NGEN'd -* Fix ([Devcom 322883](https://developercommunity.visualstudio.com/content/problem/322883/all-net-framework-f-projects-build-to-4500-regardl.html)) - FSharp.Core 4.5.0.0 binary is deployed to FSharp.Core 4.4.3.0 location +* Add AssemblyContents and FSharpExpr to allow access to resolved, checked expression trees +* Populate ReferencedProjects using ProjectFileInfo +* Fix finding symbols declared in signature files +* Add logging to project cracking facility -All other closed issues for the VS 15.8 release can be found [here](https://github.com/Microsoft/visualfsharp/milestone/14). +### 0.0.72 - -## F# 4.5 +* Allow project parser to be used on project file with relative paths +* Expose attributes for non-F# symbols -We introduced the F# language version 4.5 with this release. This also corresponds with the new 4.5.x family of FSharp.Core (the F# core library). You can read the specs for each of these changes in the [F# RFC repository](https://github.com/fsharp/fslang-design). There are also many improvements to F# tools for Visual Studio with this release. +### 0.0.71 - -### Releases +* More renamings in SourceCodeServices API for more consistent use of 'FSharp' prefix -* Visual Studio 2017 update 15.8 -* .NET Core SDK version 2.1.400 or higher +### 0.0.70 - -### Language features +* Make FSharpProjectFileParser public +* Fixes to project parser for Mono (.NET 4.0 component) +* Renamings in SourceCodeServices API for more consistent use of 'FSharp' prefix -* Support for `voidptr` -* `NativePtr.ofVoidPtr` and `NativePtr.toVoidPtr` support -* New types: `inref<'T>`, `outref<'T>` to represent read-only and write-only `byref`s -* Support for `IsByRefLike` structs -* Support for `IsReadOnly` structs -* Full support for production and consumption of `byref` returns -* Support for extension methods for `byref`/`inref`/`outref` -* Support for `match!` in computation expressions -* Relaxed upcast requirements for `yield` in sequence, list, and array expressions -* Relaxed indentation requirements for list and array expressions -* Enumeration cases emitted as public -* Various bug fixes with `byref` programming +### 0.0.67 - -### FSharp.Core features +* Fixes to project parser for Mono -* Version aligned to 4.5.x for the NuGet package and 4.5.0.0 for the binary -* Improved strack traces for `async { }` so that user code can now be seen -* Support for `ValueOption<'T>` -* Support for `TryGetValue` on Map +### 0.0.66 - -### Compiler improvements +* Fixes to project parser for Mono +* Use MSBuild v12.0 for reference resolution on .NET 4.5+ -Improvements to the F# compiler in addition to the previously-mentioned language features are in F# 4.5. These include: +### 0.0.65 - -* Restored ability to inherit from `FSharpFunc` -* Removed ~2.2% of all allocations in the F# compiler -* F# reference normalization support for user control of transitive assembly references written to an output file -* Respecting `WarningsNotAsErrors` -* Error message improvement when branches of a pattern match do not return the same type -* Respecting `#nowarn "2003"` -* Other smaller performance improvements and many bug fixes +* Fixes to project parser -### Tooling improvements +### 0.0.64 - -Significant improvements in the F# tools, such as performance enhancements and some new editor features are included this release. As always, with a large number of contributions from the F# open source community. Here are the highlights: +* Add project parser, particularly GetProjectOptionsFromProjectFile -* We improved IntelliSense performance for .NET SDK-style projects of all forms, including those that use multi-targeting. -* A community-driven effort to analyze and improve IntelliSense performance for very large files was contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko),[ Steffen Forkmann](https://github.com/forki), and [Gauthier Segay](https://github.com/smoothdeveloper). IntelliSense in very large files (10k+ lines of code) is roughly twice as fast now. -* The warning for an outdated FSharp.Core (despite the package being installed) is no longer present in .NET SDK-style projects. -* The description tooltip that displays XML documentation for a member after . in IntelliSense no longer times out after 10 seconds. -* A bug where you could not set breakpoints in object constructor arguments has been fixed. -* A bug where a renamed symbol would be duplicated when it is a generic parameter has been fixed. -* Templates for .NET Framework (classic F# templates) now consume FSharp.Core from a NuGet package, to align with .NET SDK F# templates. -* Automatic, transactional brace completion is now available for `()`, `[]`, `{}`, `[||]`, and `[<>]` brace pairs. We did this work in collaboration with [Gibran Rosa](https://github.com/gibranrosa). -* You can now go to definition with **Ctrl + Click** on an F# symbol. The settings for this gesture are also respected in the **Tools > Options** window. -* The IntelliSense performance UI has been modified to allow configuration of stale typecheck information for various IDE features. Explanations for each option are now present in tooltips for the settings. -* Brace match highlighting now correctly highlights braces, completed in collaboration with [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* Go to definition now navigates correctly when a type is defined recursively, contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* A bug where an auto-imported namespace wasn't opened when the top of a file was empty has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* A bug where `printf` specifiers that contained dots were miscolored has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* A bug where all opens were considered unused inside of a recursive module has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* Autocompletion for attributes now only suggests options that are actually attributes, contributed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* Signature Help tooltips are now generated for Type Provider static parameters at the constructor call site, contributed by[Vasily Kirichenko](https://github.com/vasily-kirichenko). -* A bug where value types used as units of measure were colored as reference types has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -* A bug where semantic colorization could disappear for some files while scrolling has been fixed by [Vasily Kirichenko](https://github.com/vasily-kirichenko). -There is now an experimental CodeLens implementation, contributed by [Victor Peter Rouven Müller](https://github.com/realvictorprm). You can turn it on in **Options > Text Editor > F# > Code Lens**. -* A bug where the F# compiler service would incorrectly elide the module names in XML documentation has been fixed by [Sebastian Urban](https://github.com/surban). -* Code that uses `Dictionary` with `ContainsKey` and subsequent `Item` calls has been changed to use `TryGetValue`, by [Eugene Auduchinok](https://github.com/auduchinok). -* [Jakob Majoka](https://github.com/majocha) also contributed in the process of consuming a different API for Tooltips. +### 0.0.63 - -### Infrastructure, Packaging, and Open Source Improvements +* #221 - Normalize return types of .NET events -We made the following enhancements to infrastructure, packaging, and our open source contribution experience: +### 0.0.62 - -* The F# compiler distributed with Visual Studio no longer installs as a singleton in the F# Compiler SDK location. It is now fully side-by-side with Visual Studio, meaning that side-by-side installations of Visual Studio wil finally have truly side-by-side F# tooling and language experiences. -* The FSharp.Core NuGet package is now signed. -* ETW logging has been added to the F# tools and compiler. -* The very large `control.fs`/`control.fsi` files in FSharp.Core have been split into `async.fs`/`async.fsi`, `event.fs`/`event.fsi`, `eventmodule.fs`/`eventmodule.fsi`, `mailbox.fs`/`mailbox.fsi`, and `observable.fs`/`observable.fsi`. -* We added .NET SDK-style versions of our project performance stress test artifacts. -* We removed Newtonsoft.json from our codebase, and you now have one less package downloaded for OSS contributors. -* We now use the latest versions of System.Collections.Immutable and System.Reflection.Metadata. +* Integrate to latest https://github.com/fsharp/fsharp (#80f9221f811217bd890b3a670d717ebc510aeeaf) -## F# 4.1 +### 0.0.61 - -### Releases +* #216 - Return associated getters/setters from F# properties +* #214 - Added missing XmlDocSig for FSharpMemberOrFunctionOrValue's Events, Methods and Properties +* #213 - Retrieve information for all active pattern cases +* #188 - Fix leak in file handles when using multiple instances of FsiEvaluationSession, and add optionally collectible assemblies -* Visual Studio 2017 updates 15.0 to 15.8 (exclusive) -* .NET Core SDK versions 1.0 to 2.1.400 (exclusive) +### 0.0.60 - -### Language and Core Library features +* #207 - Add IsLiteral/LiteralValue to FSharpField +* #205 - Add IsOptionalArg and related properties to FSharpParameter +* #210 - Check default/override members via 'IsOverrideOrExplicitMember' +* #209 - Add TryFullName to FSharpEntity -* Struct tuples -* Initial support for consuming C#-style `ref` returns -* Struct record support with the `[]` attribute -* Struct Discriminated Union support with the `[]` attribute -* `Result<'TSuccess, 'TFailure>` type, with supporting functions in FSharp.Core -* Support for the `fixed` keyword to pin a pointer-tyle local to the stack -* Underscores in numeric literals -* Caller Info Attribute Argument support -* `namespace rec` and `module rec` to support mutually referential types and functions within the same file -* Implicit "Module" suffix added to modules that share the same name as a type -* Tuple equality for F# tuples and `System.Tuple` +### 0.0.59 - -### Compiler improvements +* Fix for #184 - Fix EvalScript by using verbatim string for #Load +* Fix for #183 - The line no. reporting is still using 0-based indexes in errors. This is confusing. -* Support for generating Portable PDBs -* Significant improvements to error messages, particularly to aid with suggestions -* Performance improvements -* Interoperability improvements -* Support for geenerating F# AssymblyInfo from properties for .NET SDK projects -* `--debug:full` support for F# on .NET Core on Windows -* `MakeTuple` support for struct tuples -* Warnings are forwarded when searching for method overloads -* Support for emitting an enum-specific warning when pattern matching over one -* Many smaller bug fixes +### 0.0.58 - -### FSharp.Core features +* Fix for #156 - The FSharp.Core should be retrieved from the hosting environment -* Support for `NativePtr.ByRef` -* Support for `Async.StartImmediateAsTask` -* Support for `Seq.transpose`/`Array.transpose`/`List.transpose` -* `IsSerializable` support for `Option` and `Async<'T>` -* Many smaller bug fixes +### 0.0.57 - -### IDE features for F# tools in Visual Studio +* Second fix for #160 - Nuget package now contains .NET 4.0 and 4.5 -Most items here contributed by community members. +### 0.0.56 - -* Default installation of F# wherever .NET Core is installed -* Significant memory reductions in F# tooling -* IntelliSense Filters and Glyphs -* Support for Go to All -* Find all Reference support -* In-memory cross-project references support -* QuickInfo supports type colorization -* QuickInfo supports navigable links that will invoke Go to Definition -* Inline Rename support -* Go to Definition from F# to C# support -* Semantic document highlighting for selected symbols -* Support for Structured Guidelines and code outlining, which is toggleable -* Support for `EditorBrowsable(EditorBrowsableState.Never)` -* Code fix for making Record and Discriminated Union case lables upper-case -* Code fix to make suggestions for an unkown identifier -* Code fix for prefixing or replacing an unused value with an underscore -* Code fix to add the `new` keyword to a disposable type -* Code fix to add an `open` statement at the top for a symbol coming from an unopened namespace or module -* Code fix to simplify a name by removing unnecessary namespace qualifiers -* Graying out unused values in the editor -* Colorized `fsi.exe` when ran as a standalone console application -* Autocompletion support, including symbols from unopened namespaces -* Colorization for mutable values to distinguish them from immutable values -* Support for move up/down on solution folder nodes -* Support for Blue (High Contrast) theming -* Full support for .NET Core and .NET Standard projects, with the ability to create new ASP.NET Core projects in F# -* Full support for ASP.NET Web SDK tooling, such as Azure publish UI, for F# projects -* Property page auto-sizing support for different monitors -* Smart indentation support which auto-indents based on scope and auto-deindents for bracket-like characters -* XML documentation comment width scaling to prevent it running horizontally off the screen -* Multiple settings pages to modify tooling settings -* Support for Drag and Drop across folders -* Support for nightly builds of the tools -* Expanded debugger view for lists from 50 items to 5000 items -* Support for Optimization APIs in the compiler service -* Support for `IsNameGenerated` in the F# symbols API +* Fix for #160 - Nuget package contains .NET 4.0 and 4.5 + +### 0.0.55 - + +* Integrate changes for F# 3.1.x, Fix #166 + +### 0.0.54 - + +* Fix for #159 - Unsubscribe from TP Invalidate events when disposing builders + +### 0.0.53 - + +* Add queue length to InteractiveChecker + +### 0.0.52 - + +* Fix caches keeping hold of stale entries + +### 0.0.51 - + +* Add IsAccessible to FSharpSymbol, and ProjectContext.AccessibilityRights to give the context of an access + +### 0.0.50 - + +* Fix #79 - FindUsesOfSymbol returns None at definition of properties with explicit getters and setters + +### 0.0.49 - + +* Fix #138 - Fix symbol equality for provided type members +* Fix #150 - Return IsGetterMethod = true for declarations of F# properties (no separate 'property' symbol is yet returned, see #79) +* Fix #132 - Add IsStaticInstantiation on FSharpEntity to allow clients to detect fake symbols arising from application of static parameters +* Fix #154 - Add IsArrayType on FSharpEntity to allow clients to detect the symbols for array types +* Fix #96 - Return resolutions of 'Module' and 'Type' in "Module.field" and "Type.field" + +### 0.0.48 - + +* Allow own fsi object without referencing FSharp.Compiler.Interactive.Settings.dll (#127) + +### 0.0.47 - + +* Adjust fix for #143 for F# types with abstract+default events + +### 0.0.46 - + +* Fix multi-project analysis when referenced projects have changed (#141) +* Fix process exit on bad arguments to FsiEvaluationSession (#126) +* Deprecate FsiEvaluationSession constructor and add FsiEvaluationSession.Create static method to allow for future API that can return errors +* Return additional 'property' and 'event' methods for F#-defined types to regularize symbols (#108, #143) +* Add IsPropertySetterMethod and IsPropertyGetterMethod which only return true for getter/setter methods, not properties. Deprecate IsSetterMethod and IsGetterMethod in favour of these. +* Add IsEventAddMethod and IsEventRemoveMethod which return true for add/remove methods with an associated event +* Change IsProperty and IsEvent to only return true for the symbols for properties and events, rather than the methods associated with these +* Fix value of Assembly for some symbols (e.g. property symbols) + +### 0.0.45 - + +* Add optional project cache size parameter to InteractiveChecker +* Switch to openBinariesInMemory for SimpleSourceCodeServices +* Cleanup SimpleSourceCodeServices to avoid code duplication + +### 0.0.44 - + +* Integrate latest changes from visualfsharp.codeplex.com via github.com/fsharp/fsharp +* Fix problem with task that generates description text of declaration +* Add AllInterfaceTypes to FSharpEntity and FSharpType +* Add BaseType to FSharpType to propagate instantiation +* Add Instantiate to FSharpType + +### 0.0.43 - + +* Fix #109 - Duplicates in GetUsesOfSymbolInFile + +### 0.0.42 - + +* Fix #105 - Register enum symbols in patterns +* Fix #107 - Return correct results for inheritance chain of .NET types +* Fix #101 - Add DeclaringEntity property + +### 0.0.41 - + +* Fixed #104 - Make all operations that may utilize the FCS reactor async +* Add FSharpDisplayContext and FSharpType.Format +* Replace GetSymbolAtLocationAlternate by GetSymbolUseAtLocation + +### 0.0.40 - + +* Fixed #86 - Expose Microsoft.FSharp.Compiler.Interactive.Shell.Settings.fsi +* Fixed #99 - Add IsNamespace property to FSharpEntity + +### 0.0.39 - + +* Fixed #79 - Usage points for symbols in union patterns + +### 0.0.38 - + +* Fixed #94 and #89 by addition of new properties to the FSharpSymbolUse type +* Fixed #93 by addition of IsOpaque to FSharpEntity type +* Fixed #92 - Issue with nested classes +* Fixed #87 - Allow analysis of members from external assemblies + +### 0.0.37 - + +* Obsolete HasDefaultValue - see https://github.com/fsharp/FSharp.Compiler.Service/issues/77 + +### 0.0.36 - + +* Fix #71 - Expose static parameters and xml docs of type providers +* Fix #63 - SourceCodeServices: #r ignores include paths passed as command-line flags + +### 0.0.35 - + +* Fix #38 - FSharp.Compiler.Services should tolerate an FSharp.Core without siginfo/optdata in the search path + + +### 0.0.34 - + +* Add StaticParameters property to entities, plus FSharpStaticParameter symbol +* Fix #65 + +### 0.0.33 - + +* Add FullName and Assembly properties for symbols +* Fix #76 +* Add Japanese documentation + +### 0.0.32 - + +* Make ParseFileInProject asynchronous +* Add ParseAndCheckFileInProject +* Use cached results in ParseAndCheckFileInProject if available -## Older F# releases +### 0.0.31 - + +* Fix performance problem with CheckFileInProject + +### 0.0.30 - + +* Add initial prototype version of multi-project support, through optional ProjectReferences in ProjectOptions. Leave this empty + to use DLL/file-based references to results from other projects. + +### 0.0.29 - + +* Fix symbols for named union fields in patterns + +### 0.0.28 - + +* Fix symbols for named union fields +* Add FSharpActivePatternCase to refine FSharpSymbol + +### 0.0.27 - + +* Fix exception tag symbol reporting + +### 0.0.26 - + +* Fix off-by-one in reporting of range for active pattern name + +### 0.0.25 - + +* Add optional source argument to TryGetRecentTypeCheckResultsForFile to specify that source must match exactly + +### 0.0.24 - + +* Update version number as nuget package may not have published properly + +### 0.0.23 - + +* Move to one-based line numbering everywhere +* Provide better symbol information for active patterns + +### 0.0.22 - + +* Provide symbol location for type parameters + +### 0.0.21 - + +* Add GetUsesOfSymbolInFile +* Better symbol resolution results for type parameter symbols + +### 0.0.20 - + +* Update version number as nuget package may not have published properly + +### 0.0.19 - + +* Change return type of GetAllUsesOfSymbol, GetAllUsesOfAllSymbols and GetAllUsesOfAllSymbolsInFile to FSharpSymbolUse +* Add symbol uses when an abstract member is implemented. + +### 0.0.18 - + +* Add GetAllUsesOfAllSymbols and GetAllUsesOfAllSymbolsInFile + +### 0.0.17 - + +* Improvements to symbol accuracy w.r.t. type abbreviations + +### 0.0.16 - + +* Make FSharpEntity.BaseType return an option +* FsiSesion got a new "EvalScript" method which allows to evaluate .fsx files + +### 0.0.15 - + +* Update version number as nuget package may not have published properly + +### 0.0.14 - + +* Update version number as nuget package may not have published properly + +### 0.0.13-alpha - + +* Fix #39 - Constructor parameters are mistaken for record fields in classes + +### 0.0.12-alpha - + +* Make the parts of the lexer/parser used by 'XmlDoc' tools in F# VS Power tools public + +### 0.0.11-alpha - + +* Add 'IsUnresolved' + +### 0.0.10-alpha - + +* Fix bug where 'multiple references to FSharp.Core' was given as error for scripts + +### 0.0.9-alpha - + +* Fix fsc corrupting assemblies when generating pdb files (really) +* Give better error messages for missing assemblies +* Report more information about symbols returned by GetSymbolAtLocation (through subtypes) +* Fix typos in docs +* Return full project results from ParseAndCheckInteraction +* Be more robust to missing assembly references by default. + +### 0.0.8-alpha - + +* Fix fsc corrupting assemblies when generating pdb files + +### 0.0.7-alpha - + +* Fix docs +* Make symbols more robust to missing assemblies +* Be robust to failures on IncrementalBuilder creation +* Allow use of MSBuild resolution by IncrementalBuilder + +### 0.0.6-alpha - + +* Fix version number + +### 0.0.5-alpha - + +* Added GetUsesOfSymbol(), FSharpSymbol type, GetSymbolAtLocation(...) + +### 0.0.4-alpha - + +* Added documentation of file system API +* Reporte errors correctly from ParseAndCheckProject + +### 0.0.3-alpha - + +* Integrate FSharp.PowerPack.Metadata as the FSharp* symbol API +* Renamed Param --> MethodGroupItemParameter and hid record from view, made into an object +* Renamed Method --> MethodGroupItem and hid record from view, made into an object +* Renamed Methods --> MethodGroup and hid record from view, made into an object +* Renamed MethodGroup.Name --> MethodGroup.MethodName +* Renamed DataTip --> ToolTip consistently across all text +* Renamed CheckOptions --> ProjectOptions +* Renamed TypeCheckAnswer --> CheckFileAnswer +* Renamed UntypedParseInfo --> ParseFileResults +* Removed GetCheckOptionsFromScriptRoot member overload in favour of optional argument +* Renamed GetCheckOptionsFromScriptRoot --> GetProjectOptionsFromScript +* Renamed UntypedParse --> ParseFileInProject +* Renamed TypeCheckSource --> CheckFileInProjectIfReady +* Added numerous methods to API including CheckFileInProject +* Added experimental GetBackgroundCheckResultsForFileInProject, GetBackgroundParseResultsForFileInProject +* Added PartialAssemblySignature to TypeCheckResults/CheckFileResults +* Added CurrentPartialAssemblySignature to FsiEvaluationSession +* Added ParseAndCheckInteraction to FsiEvaluationSession to support intellisense implementation against a script fragment +* Added initial testing in tests/service +* Added ParseAndCheckProject to SourceCodeServices API. This will eventually return "whole project" information such as symbol tables. +* Added GetDefaultConfiguration to simplify process of configuring FsiEvaluationSession +* Added PartialAssemblySignatureUpdated event to FsiEvaluationSession +* Added travis build + +### 0.0.2-alpha - + +* Integrate hosted FSI configuration, SimpleSourceCodeServices, cleanup to SourceCodeServices API + +## Older Visual F# releases ### [4.0.0] - Visual Studio 2015 Update 1 - 30 November 2015 #### Enhancements + * Perf: `for i in expr do body` optimization [#219](https://github.com/Microsoft/visualfsharp/pull/219) * Remove type provider security dialog and use custom icon for type provider assembly reference [#448](https://github.com/Microsoft/visualfsharp/pull/448) * Perf: Enable parallel build inside Visual Studio [#487](https://github.com/Microsoft/visualfsharp/pull/487) @@ -221,6 +1993,7 @@ Most items here contributed by community members. * Add a compiler warning for lower case literals in patterns [#666](https://github.com/Microsoft/visualfsharp/pull/666) #### Bug fixes + * Fix scope of types for named values in attributes improperly set [#437](https://github.com/Microsoft/visualfsharp/pull/437) * Add general check for escaping typars to check phase [#442](https://github.com/Microsoft/visualfsharp/pull/442) * Fix AccessViolationException on obfuscated assemblies [#519](https://github.com/Microsoft/visualfsharp/pull/519) @@ -239,15 +2012,15 @@ Includes commits up to `dd8252eb8d20aaedf7b1c7576cd2a8a82d24f587` #### Language, compiler, runtime, interactive * Normalization and expansion of `Array`, `List`, and `Seq` modules - * New APIs for 4.0: `chunkBySize`, `contains`, `except`, `findBack`, `findInstanceBack`, `indexed`, `item`, `mapFold`, `mapFoldBack`, `sortByDescending`, `sortDescending`, `splitInto`, `tryFindBack`, `tryFindIndexBack`, `tryHead`, `tryItem`, `tryLast` +* New APIs for 4.0: `chunkBySize`, `contains`, `except`, `findBack`, `findInstanceBack`, `indexed`, `item`, `mapFold`, `mapFoldBack`, `sortByDescending`, `sortDescending`, `splitInto`, `tryFindBack`, `tryFindIndexBack`, `tryHead`, `tryItem`, `tryLast` ![Collection API additions](http://i.imgur.com/SdJ7Doh.png) * Other new APIs - * `Option.filter`, `Option.toObj`, `Option.ofObj`, `Option.toNullable`, `Option.ofNullable` - * `String.filter` - * `Checked.int8`, `Checked.uint8` - * `Async.AwaitTask` (non-generic) - * `WebClient.AsyncDownloadFile`, `WebClient.AsyncDownloadData` - * `tryUnbox`, `isNull` +* `Option.filter`, `Option.toObj`, `Option.ofObj`, `Option.toNullable`, `Option.ofNullable` +* `String.filter` +* `Checked.int8`, `Checked.uint8` +* `Async.AwaitTask` (non-generic) +* `WebClient.AsyncDownloadFile`, `WebClient.AsyncDownloadData` +* `tryUnbox`, `isNull` * New active pattern to match constant `Decimal` in quotations * Slicing support for lists * Support for consuming high-rank (> 4) arrays @@ -409,7 +2182,6 @@ Includes commits up to `3385e58aabc91368c8e1f551650ba48705aaa285` * Bugfix: Typos in tutorial project script * Bugfix: Required C# event members do not appear in intellisense when signature is (object, byref) - ### [3.1.1] - 24 January 2014 #### Language, compiler, runtime, interactive @@ -431,3 +2203,111 @@ Includes commits up to `3385e58aabc91368c8e1f551650ba48705aaa285` [3.1.2]: http://blogs.msdn.com/b/fsharpteam/archive/2014/08/20/announcing-the-release-of-visual-f-tools-3-1-2.aspx [3.1.1]: http://blogs.msdn.com/b/fsharpteam/archive/2014/01/22/announcing-visual-f-3-1-1-and-support-for-desktop-express.aspx + +Features Added in F# Language Versions +====================================== + +# [F# 4.7](https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-47) + +- Compiler support for `LangVersion` +- Implicit `yield`s +- No more required double underscore (wildcard identifier) +- Indentation relaxations for parameters passed to constructors and static methods + +# [F# 4.6](https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-46) + +- Anonymous records +- `ValueOption` module functions + +# [F# 4.5](https://docs.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-45) + +- Versioning alignment of binary, package, and language +- Support for `Span<'T>` and related types +- Ability to produce `byref` returns +- The `voidptr` type +- The `inref<'T>` and `outref<'T>` types to represent readonly and write-only `byref`s +- `IsByRefLike` structs +- `IsReadOnly` structs +- Extension method support for `byref<'T>`/`inref<'T>`/`outref<'T>` +- `match!` keyword in computation expressions +- Relaxed upcast with `yield` in F# sequence/list/array expressions +- Relaxed indentation with list and array expressions +- Enumeration cases emitted as public + +# [F# 4.1](https://fsharp.org/specs/language-spec/4.1/FSharpSpec-4.1-latest.pdf) + +- Struct tuples which inter-operate with C# tuples +- Struct annotations for Records +- Struct annotations for Single-case Discriminated Unions +- Underscores in numeric literals +- Caller info argument attributes +- Result type and some basic Result functions +- Mutually referential types and modules within the same file +- Implicit `Module` syntax on modules with shared name as type +- Byref returns, supporting consuming C# `ref`-returning methods +- Error message improvements +- Support for `fixed` + +# [F# 4.0](https://fsharp.org/specs/language-spec/4.0/FSharpSpec-4.0-final.pdf) + +- `printf` on unitized values +- Extension property initializers +- Non-null provided types +- Primary constructors as functions +- Static parameters for provided methods +- `printf` interpolation +- Extended `#if` grammar +- Multiple interface instantiations +- Optional type args +- Params dictionaries + +# [F# 3.1](https://fsharp.org/specs/language-spec/3.1/FSharpSpec-3.1-final.pdf) + +- Named union type fields +- Extensions to array slicing +- Type inference enhancements + +# [F# 3.0](https://fsharp.org/specs/language-spec/3.0/FSharpSpec-3.0-final.pdf) + +- Type providers +- LINQ query expressions +- CLIMutable attribute +- Triple-quoted strings +- Auto-properties +- Provided units-of-measure + +# [F# 2.0](https://fsharp.org/specs/language-spec/2.0/FSharpSpec-2.0-April-2012.pdf) + +- Active patterns +- Units of measure +- Sequence expressions +- Asynchronous programming +- Agent programming +- Extension members +- Named arguments +- Optional arguments +- Array slicing +- Quotations +- Native interoperability +- Computation expressions + +# [F# 1.1](https://docs.microsoft.com/en-us/archive/blogs/dsyme/a-taste-of-whats-new-in-f-1-1) + +- Interactive environment +- Object programming +- Encapsulation Extensions + +# [F# 1.0](https://docs.microsoft.com/en-us/archive/blogs/dsyme/welcome-to-dons-f-blog) + +- Discriminated unions +- Records +- Tuples +- Pattern matching +- Type abbreviations +- Object expressions +- Structs +- Signature files +- Imperative programming +- Modules (no functors) +- Nested modules +- .NET Interoperability diff --git a/scripts/init-tools.sh b/scripts/init-tools.sh index 67067dd4867..178d1bca003 100644 --- a/scripts/init-tools.sh +++ b/scripts/init-tools.sh @@ -9,7 +9,7 @@ __DOTNET_PATH=$__TOOLRUNTIME_DIR/dotnetcli __DOTNET_CMD=$__DOTNET_PATH/dotnet __DOTNET_VERSION=$(cat $__scriptpath/../DotnetCLIVersion.txt) -if [ -z "$__BUILDTOOLS_SOURCE" ]; then __BUILDTOOLS_SOURCE=https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json; fi +if [ -z "$__BUILDTOOLS_SOURCE" ]; then __BUILDTOOLS_SOURCE=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json; fi __BUILD_TOOLS_PACKAGE_VERSION=$(cat $__scriptpath/../BuildToolsVersion.txt) diff --git a/service/FSharp.Compiler.Service.sln b/service/FSharp.Compiler.Service.sln new file mode 100644 index 00000000000..a764ba014a1 --- /dev/null +++ b/service/FSharp.Compiler.Service.sln @@ -0,0 +1,55 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30503.244 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "..\src\fsharp\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{A59DB8AE-8044-41A5-848A-800A7FF31C93}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service.Tests", "..\tests\FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj", "{8D9C9683-5041-48AB-8FA9-0939D2D27D33}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager.Nuget", "..\src\fsharp\FSharp.DependencyManager.Nuget\FSharp.DependencyManager.Nuget.fsproj", "{98E7659D-8E0C-489F-B4F5-E12AFC0D1BFA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FSharp.Compiler.Service.Tests support", "FSharp.Compiler.Service.Tests support", "{875D91AC-BA4C-4191-AB11-AE461DB9B8DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharp_Analysis", "..\tests\service\data\CSharp_Analysis\CSharp_Analysis.csproj", "{BFE6E6F1-1B73-404F-A3A5-30B57E5E0731}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TestTP", "..\tests\service\data\TestTP\TestTP.fsproj", "{2EF674B9-8B56-4796-9933-42B2629E52C3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A59DB8AE-8044-41A5-848A-800A7FF31C93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A59DB8AE-8044-41A5-848A-800A7FF31C93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A59DB8AE-8044-41A5-848A-800A7FF31C93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A59DB8AE-8044-41A5-848A-800A7FF31C93}.Release|Any CPU.Build.0 = Release|Any CPU + {8D9C9683-5041-48AB-8FA9-0939D2D27D33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D9C9683-5041-48AB-8FA9-0939D2D27D33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D9C9683-5041-48AB-8FA9-0939D2D27D33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D9C9683-5041-48AB-8FA9-0939D2D27D33}.Release|Any CPU.Build.0 = Release|Any CPU + {98E7659D-8E0C-489F-B4F5-E12AFC0D1BFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98E7659D-8E0C-489F-B4F5-E12AFC0D1BFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98E7659D-8E0C-489F-B4F5-E12AFC0D1BFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98E7659D-8E0C-489F-B4F5-E12AFC0D1BFA}.Release|Any CPU.Build.0 = Release|Any CPU + {BFE6E6F1-1B73-404F-A3A5-30B57E5E0731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFE6E6F1-1B73-404F-A3A5-30B57E5E0731}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFE6E6F1-1B73-404F-A3A5-30B57E5E0731}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFE6E6F1-1B73-404F-A3A5-30B57E5E0731}.Release|Any CPU.Build.0 = Release|Any CPU + {2EF674B9-8B56-4796-9933-42B2629E52C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EF674B9-8B56-4796-9933-42B2629E52C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EF674B9-8B56-4796-9933-42B2629E52C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EF674B9-8B56-4796-9933-42B2629E52C3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {BFE6E6F1-1B73-404F-A3A5-30B57E5E0731} = {875D91AC-BA4C-4191-AB11-AE461DB9B8DB} + {2EF674B9-8B56-4796-9933-42B2629E52C3} = {875D91AC-BA4C-4191-AB11-AE461DB9B8DB} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F9A60F3B-D894-4C8E-BA0F-C51115B25A5A} + EndGlobalSection +EndGlobal diff --git a/fcs/FSharp.Compiler.Service.sln.DotSettings b/service/FSharp.Compiler.Service.sln.DotSettings similarity index 100% rename from fcs/FSharp.Compiler.Service.sln.DotSettings rename to service/FSharp.Compiler.Service.sln.DotSettings diff --git a/service/global.json b/service/global.json new file mode 100644 index 00000000000..1950f1c063f --- /dev/null +++ b/service/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "5.0.300", + "allowPrerelease": true, + "rollForward": "minor" + } +} diff --git a/setup/Swix/Directory.Build.targets b/setup/Swix/Directory.Build.targets index 7e50ced3f2b..5e826e8da63 100644 --- a/setup/Swix/Directory.Build.targets +++ b/setup/Swix/Directory.Build.targets @@ -15,7 +15,7 @@ + Condition="'$(DotNetBuildFromSource)' != 'true' AND '$(ArcadeBuildFromSource)' != 'true'"> diff --git a/setup/Swix/Microsoft.FSharp.Compiler.MSBuild/Microsoft.FSharp.Compiler.MSBuild.csproj b/setup/Swix/Microsoft.FSharp.Compiler.MSBuild/Microsoft.FSharp.Compiler.MSBuild.csproj index cc9d75a2887..5ebc1fe5ea4 100644 --- a/setup/Swix/Microsoft.FSharp.Compiler.MSBuild/Microsoft.FSharp.Compiler.MSBuild.csproj +++ b/setup/Swix/Microsoft.FSharp.Compiler.MSBuild/Microsoft.FSharp.Compiler.MSBuild.csproj @@ -8,15 +8,12 @@ + - + - - - - - + - + <_Line> @@ -67,11 +62,7 @@ folder "InstallDir:Common7\IDE\CommonExtensions\Microsoft\FSharp\%(_XlfLanguages - + <_Lines> @@ -85,32 +76,40 @@ vs.dependencies version=$(VsixVersion) type=Required -folder "InstallDir:Common7\IDE\CommonExtensions\Microsoft\FSharp" - file source="$(BinariesFolder)\fsc\$(Configuration)\$(TargetFramework)\fsc.exe" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsc.exe" - file source="$(BinariesFolder)\fsc\$(Configuration)\$(TargetFramework)\fsc.exe.config" - file source="$(BinariesFolder)\fsi\$(Configuration)\$(TargetFramework)\fsi.exe" vs.file.ngen=yes vs.file.ngenArchitecture=X86 vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsi.exe" - file source="$(BinariesFolder)\fsi\$(Configuration)\$(TargetFramework)\fsi.exe.config" - file source="$(BinariesFolder)\fsiAnyCpu\$(Configuration)\$(TargetFramework)\fsiAnyCpu.exe" vs.file.ngen=yes vs.file.ngenArchitecture=X64 vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsiAnyCpu.exe" - file source="$(BinariesFolder)\fsiAnyCpu\$(Configuration)\$(TargetFramework)\fsiAnyCpu.exe.config" - file source="$(BinariesFolder)\FSharp.Compiler.Interactive.Settings\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Interactive.Settings.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 - file source="$(BinariesFolder)\FSharp.Compiler.Private\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Private.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 - file source="$(BinariesFolder)\FSharp.Compiler.Server.Shared\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Server.Shared.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 - file source="$(BinariesFolder)\FSharp.Core\$(Configuration)\net45\FSharp.Core.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 - file source="$(BinariesFolder)\FSharp.Core\$(Configuration)\net45\FSharp.Core.optdata" - file source="$(BinariesFolder)\FSharp.Core\$(Configuration)\net45\FSharp.Core.sigdata" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\FSharp.Build.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 - file source="$(NuGetPackageRoot)\Microsoft.VisualFSharp.Type.Providers.Redist\$(MicrosoftVisualFSharpTypeProvidersRedistVersion)\content\$(FSharpDataTypeProvidersVersion)\FSharp.Data.TypeProviders.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.Build.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.Build.Framework.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.Build.Tasks.Core.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.Build.Utilities.Core.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.Portable.FSharp.Targets" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\System.Collections.Immutable.dll" - file source="$(BinariesFolder)\FSharp.Compiler.Private\$(Configuration)\$(TargetFramework)\System.Reflection.Metadata.dll" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.FSharp.NetSdk.props" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.FSharp.NetSdk.targets" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.FSharp.Overrides.NetSdk.targets" - file source="$(BinariesFolder)\FSharp.Build\$(Configuration)\$(TargetFramework)\Microsoft.FSharp.Targets" +folder "InstallDir:Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\fsc.exe" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools\fsc.exe" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\fsc.exe.config" + file source="$(BinariesFolder)fsi\$(Configuration)\$(TargetFramework)\fsi.exe" vs.file.ngen=yes vs.file.ngenArchitecture=X86 vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools\fsi.exe" + file source="$(BinariesFolder)fsi\$(Configuration)\$(TargetFramework)\fsi.exe.config" + file source="$(BinariesFolder)fsiAnyCpu\$(Configuration)\$(TargetFramework)\fsiAnyCpu.exe" vs.file.ngen=yes vs.file.ngenArchitecture=X64 vs.file.ngenPriority=2 vs.file.ngenApplication="[installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools\fsiAnyCpu.exe" + file source="$(BinariesFolder)fsiAnyCpu\$(Configuration)\$(TargetFramework)\fsiAnyCpu.exe.config" + file source="$(BinariesFolder)FSharp.Compiler.Interactive.Settings\$(Configuration)\netstandard2.0\FSharp.Compiler.Interactive.Settings.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)FSharp.Compiler.Interactive.Settings\$(Configuration)\netstandard2.0\FSharp.Compiler.Interactive.Settings.xml" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Service.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Service.xml" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Buffers.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Collections.Immutable.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Memory.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Numerics.Vectors.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Reflection.Metadata.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Resources.Extensions.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Runtime.CompilerServices.Unsafe.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\System.Threading.Tasks.Dataflow.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\Microsoft.Build.Framework.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\Microsoft.Build.Tasks.Core.dll" + file source="$(BinariesFolder)fsc\$(Configuration)\$(TargetFramework)\Microsoft.Build.Utilities.Core.dll" + file source="$(BinariesFolder)FSharp.Compiler.Server.Shared\$(Configuration)\$(TargetFramework)\FSharp.Compiler.Server.Shared.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)FSharp.Core\$(Configuration)\netstandard2.0\FSharp.Core.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)FSharp.Core\$(Configuration)\netstandard2.0\FSharp.Core.xml" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\FSharp.Build.dll" vs.file.ngen=no vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\FSharp.Build.xml" + file source="$(BinariesFolder)FSharp.DependencyManager.Nuget\$(Configuration)\netstandard2.0\FSharp.DependencyManager.Nuget.dll" vs.file.ngen=yes vs.file.ngenArchitecture=All vs.file.ngenPriority=2 + file source="$(BinariesFolder)FSharp.DependencyManager.Nuget\$(Configuration)\netstandard2.0\FSharp.DependencyManager.Nuget.xml" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\Microsoft.Portable.FSharp.Targets" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\Microsoft.FSharp.NetSdk.props" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\Microsoft.FSharp.NetSdk.targets" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\Microsoft.FSharp.Overrides.NetSdk.targets" + file source="$(BinariesFolder)FSharp.Build\$(Configuration)\netstandard2.0\Microsoft.FSharp.Targets" @(_BuiltSwrLines) ]]> diff --git a/setup/Swix/Microsoft.FSharp.Dependencies/fsharp.bat b/setup/Swix/Microsoft.FSharp.Dependencies/fsharp.bat index adbadf3f819..0090e8ce5fc 100644 --- a/setup/Swix/Microsoft.FSharp.Dependencies/fsharp.bat +++ b/setup/Swix/Microsoft.FSharp.Dependencies/fsharp.bat @@ -1,7 +1,7 @@ if "%VSCMD_TEST%" NEQ "" goto :test if "%VSCMD_ARG_CLEAN_ENV%" NEQ "" goto :clean_env -set FSHARPINSTALLDIR=%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\FSharp\ +set FSHARPINSTALLDIR=%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools set "PATH=%FSHARPINSTALLDIR%;%PATH%" goto :end diff --git a/setup/Swix/Microsoft.FSharp.IDE/Microsoft.FSharp.IDE.csproj b/setup/Swix/Microsoft.FSharp.IDE/Microsoft.FSharp.IDE.csproj index 03d9cf42ba6..834d95d3bf1 100644 --- a/setup/Swix/Microsoft.FSharp.IDE/Microsoft.FSharp.IDE.csproj +++ b/setup/Swix/Microsoft.FSharp.IDE/Microsoft.FSharp.IDE.csproj @@ -16,10 +16,10 @@ <_Dependency Include="FSharp.Build" Version="$(FSProductVersion)" /> <_Dependency Include="FSharp.Compiler.Interactive.Settings" Version="$(FSProductVersion)" /> - <_Dependency Include="FSharp.Compiler.Private" Version="$(FSProductVersion)" /> + <_Dependency Include="FSharp.Compiler.Service" Version="$(FSharpCompilerServiceVersion)" /> + <_Dependency Include="FSharp.DependencyManager.Nuget" Version="$(FSProductVersion)" /> <_Dependency Include="FSharp.Compiler.Server.Shared" Version="$(FSProductVersion)" /> <_Dependency Include="FSharp.Core" Version="$(FSCoreVersion)" /> - <_Dependency Include="FSharp.Data.TypeProviders" Version="$(FSharpDataTypeProvidersVersion)" /> <_Dependency Include="FSharp.Editor" Version="$(VSAssemblyVersion)" /> <_Dependency Include="FSharp.LanguageService.Base" Version="$(VSAssemblyVersion)" /> <_Dependency Include="FSharp.LanguageService" Version="$(VSAssemblyVersion)" /> @@ -31,8 +31,7 @@ <_Dependency Include="FSharp.VS.FSI" Version="$(VSAssemblyVersion)" /> - + $(InsertionDir)\DevDivPackages $(DevDivPackagesDir)\DependentAssemblyVersions.csv @@ -46,4 +45,4 @@ - + \ No newline at end of file diff --git a/setup/Swix/Microsoft.FSharp.IDE/Package.swr b/setup/Swix/Microsoft.FSharp.IDE/Package.swr index 8184815f837..ea75aebf1da 100644 --- a/setup/Swix/Microsoft.FSharp.IDE/Package.swr +++ b/setup/Swix/Microsoft.FSharp.IDE/Package.swr @@ -8,6 +8,10 @@ vs.dependencies version=$(VsixVersion) type=Required + vs.dependency id=Microsoft.FSharp.Compiler + version=$(VsixVersion) + type=Required + vs.dependency id=Microsoft.FSharp.VSIX.Full.Core version=$(VsixVersion) type=Required @@ -20,4 +24,4 @@ folder "InstallDir:Common7\IDE\NewScriptItems" folder "InstallDir:Common7\IDE\NewFileItems" file source="$(SetupResourcesDir)\NewFileDialog\General\NewFSharpFileItems.vsdir" file source="$(SetupResourcesDir)\NewFileDialog\General\File.fs" - file source="$(SetupResourcesDir)\NewFileDialog\General\Script.fsx" + file source="$(SetupResourcesDir)\NewFileDialog\General\Script.fsx" \ No newline at end of file diff --git a/setup/shims/Microsoft.FSharp.NetSdk.Shim.props b/setup/shims/Microsoft.FSharp.NetSdk.Shim.props index 203b37e5734..28907c3c23c 100644 --- a/setup/shims/Microsoft.FSharp.NetSdk.Shim.props +++ b/setup/shims/Microsoft.FSharp.NetSdk.Shim.props @@ -1,6 +1,6 @@ - + diff --git a/setup/shims/Microsoft.FSharp.NetSdk.Shim.targets b/setup/shims/Microsoft.FSharp.NetSdk.Shim.targets index f5212ec914a..b9e0ea907e3 100644 --- a/setup/shims/Microsoft.FSharp.NetSdk.Shim.targets +++ b/setup/shims/Microsoft.FSharp.NetSdk.Shim.targets @@ -1,6 +1,6 @@ - + diff --git a/setup/shims/Microsoft.FSharp.Overrides.NetSdk.Shim.targets b/setup/shims/Microsoft.FSharp.Overrides.NetSdk.Shim.targets index c7c7b8a477b..cfd530eefd4 100644 --- a/setup/shims/Microsoft.FSharp.Overrides.NetSdk.Shim.targets +++ b/setup/shims/Microsoft.FSharp.Overrides.NetSdk.Shim.targets @@ -1,6 +1,6 @@ - + diff --git a/setup/shims/Microsoft.FSharp.Shim.targets b/setup/shims/Microsoft.FSharp.Shim.targets index 62b798f5e78..53acced723e 100644 --- a/setup/shims/Microsoft.FSharp.Shim.targets +++ b/setup/shims/Microsoft.FSharp.Shim.targets @@ -1,6 +1,6 @@ - + diff --git a/setup/shims/Microsoft.Portable.FSharp.Shim.targets b/setup/shims/Microsoft.Portable.FSharp.Shim.targets index 5aecfd384fa..f24c26561d8 100644 --- a/setup/shims/Microsoft.Portable.FSharp.Shim.targets +++ b/setup/shims/Microsoft.Portable.FSharp.Shim.targets @@ -1,6 +1,6 @@ - + diff --git a/src/absil/bytes.fs b/src/absil/bytes.fs deleted file mode 100644 index 9ec17577937..00000000000 --- a/src/absil/bytes.fs +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Byte arrays -namespace FSharp.Compiler.AbstractIL.Internal - -open System -open System.IO -open System.IO.MemoryMappedFiles -open System.Runtime.InteropServices -open System.Runtime.CompilerServices -open FSharp.NativeInterop - -#nowarn "9" - -module internal Bytes = - let b0 n = (n &&& 0xFF) - let b1 n = ((n >>> 8) &&& 0xFF) - let b2 n = ((n >>> 16) &&& 0xFF) - let b3 n = ((n >>> 24) &&& 0xFF) - - let dWw1 n = int32 ((n >>> 32) &&& 0xFFFFFFFFL) - let dWw0 n = int32 (n &&& 0xFFFFFFFFL) - - let get (b:byte[]) n = int32 (Array.get b n) - let zeroCreate n : byte[] = Array.zeroCreate n - - let sub ( b:byte[]) s l = Array.sub b s l - let blit (a:byte[]) b c d e = Array.blit a b c d e - - let ofInt32Array (arr:int[]) = Array.init arr.Length (fun i -> byte arr.[i]) - - let stringAsUtf8NullTerminated (s:string) = - Array.append (System.Text.Encoding.UTF8.GetBytes s) (ofInt32Array [| 0x0 |]) - - let stringAsUnicodeNullTerminated (s:string) = - Array.append (System.Text.Encoding.Unicode.GetBytes s) (ofInt32Array [| 0x0;0x0 |]) - -[] -type ByteMemory () = - - abstract Item: int -> byte with get, set - - abstract Length: int - - abstract ReadBytes: pos: int * count: int -> byte[] - - abstract ReadInt32: pos: int -> int - - abstract ReadUInt16: pos: int -> uint16 - - abstract ReadUtf8String: pos: int * count: int -> string - - abstract Slice: pos: int * count: int -> ByteMemory - - abstract CopyTo: Stream -> unit - - abstract Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit - - abstract ToArray: unit -> byte[] - - abstract AsStream: unit -> Stream - - abstract AsReadOnlyStream: unit -> Stream - -[] -type ByteArrayMemory(bytes: byte[], offset, length) = - inherit ByteMemory() - - do - if length <= 0 || length > bytes.Length then - raise (ArgumentOutOfRangeException("length")) - - if offset < 0 || (offset + length) > bytes.Length then - raise (ArgumentOutOfRangeException("offset")) - - override _.Item - with get i = bytes.[offset + i] - and set i v = bytes.[offset + i] <- v - - override _.Length = length - - override _.ReadBytes(pos, count) = - Array.sub bytes (offset + pos) count - - override _.ReadInt32 pos = - let finalOffset = offset + pos - (uint32 bytes.[finalOffset]) ||| - ((uint32 bytes.[finalOffset + 1]) <<< 8) ||| - ((uint32 bytes.[finalOffset + 2]) <<< 16) ||| - ((uint32 bytes.[finalOffset + 3]) <<< 24) - |> int - - override _.ReadUInt16 pos = - let finalOffset = offset + pos - (uint16 bytes.[finalOffset]) ||| - ((uint16 bytes.[finalOffset + 1]) <<< 8) - - override _.ReadUtf8String(pos, count) = - System.Text.Encoding.UTF8.GetString(bytes, offset + pos, count) - - override _.Slice(pos, count) = - ByteArrayMemory(bytes, offset + pos, count) :> ByteMemory - - override _.CopyTo stream = - stream.Write(bytes, offset, length) - - override _.Copy(srcOffset, dest, destOffset, count) = - Array.blit bytes (offset + srcOffset) dest destOffset count - - override _.ToArray() = - Array.sub bytes offset length - - override _.AsStream() = - new MemoryStream(bytes, offset, length) :> Stream - - override _.AsReadOnlyStream() = - new MemoryStream(bytes, offset, length, false) :> Stream - -[] -type SafeUnmanagedMemoryStream = - inherit UnmanagedMemoryStream - - val mutable private hold: obj - val mutable private isDisposed: bool - - new (addr, length, hold) = - { - inherit UnmanagedMemoryStream(addr, length) - hold = hold - isDisposed = false - } - - new (addr: nativeptr, length: int64, capacity: int64, access: FileAccess, hold) = - { - inherit UnmanagedMemoryStream(addr, length, capacity, access) - hold = hold - isDisposed = false - } - - override x.Finalize() = - x.Dispose false - - override x.Dispose disposing = - base.Dispose disposing - if not x.isDisposed then - x.hold <- null // Null out so it can be collected. - x.isDisposed <- true - -[] -type RawByteMemory(addr: nativeptr, length: int, hold: obj) = - inherit ByteMemory () - - let check i = - if i < 0 || i >= length then - raise (ArgumentOutOfRangeException("i")) - - do - if length <= 0 then - raise (ArgumentOutOfRangeException("length")) - - override _.Item - with get i = - check i - NativePtr.add addr i - |> NativePtr.read - and set i v = - check i - NativePtr.set addr i v - - override _.Length = length - - override _.ReadUtf8String(pos, count) = - check pos - check (pos + count - 1) - System.Text.Encoding.UTF8.GetString(NativePtr.add addr pos, count) - - override _.ReadBytes(pos, count) = - check pos - check (pos + count - 1) - let res = Bytes.zeroCreate count - Marshal.Copy(NativePtr.toNativeInt addr + nativeint pos, res, 0, count) - res - - override _.ReadInt32 pos = - check pos - check (pos + 3) - Marshal.ReadInt32(NativePtr.toNativeInt addr + nativeint pos) - - override _.ReadUInt16 pos = - check pos - check (pos + 1) - uint16(Marshal.ReadInt16(NativePtr.toNativeInt addr + nativeint pos)) - - override _.Slice(pos, count) = - check pos - check (pos + count - 1) - RawByteMemory(NativePtr.add addr pos, count, hold) :> ByteMemory - - override x.CopyTo stream = - use stream2 = x.AsStream() - stream2.CopyTo stream - - override _.Copy(srcOffset, dest, destOffset, count) = - check srcOffset - Marshal.Copy(NativePtr.toNativeInt addr + nativeint srcOffset, dest, destOffset, count) - - override _.ToArray() = - let res = Array.zeroCreate length - Marshal.Copy(NativePtr.toNativeInt addr, res, 0, res.Length) - res - - override _.AsStream() = - new SafeUnmanagedMemoryStream(addr, int64 length, hold) :> Stream - - override _.AsReadOnlyStream() = - new SafeUnmanagedMemoryStream(addr, int64 length, int64 length, FileAccess.Read, hold) :> Stream - -[] -type ReadOnlyByteMemory(bytes: ByteMemory) = - - member _.Item with get i = bytes.[i] - - member _.Length with get () = bytes.Length - - member _.ReadBytes(pos, count) = bytes.ReadBytes(pos, count) - - member _.ReadInt32 pos = bytes.ReadInt32 pos - - member _.ReadUInt16 pos = bytes.ReadUInt16 pos - - member _.ReadUtf8String(pos, count) = bytes.ReadUtf8String(pos, count) - - member _.Slice(pos, count) = bytes.Slice(pos, count) |> ReadOnlyByteMemory - - member _.CopyTo stream = bytes.CopyTo stream - - member _.Copy(srcOffset, dest, destOffset, count) = bytes.Copy(srcOffset, dest, destOffset, count) - - member _.ToArray() = bytes.ToArray() - - member _.AsStream() = bytes.AsReadOnlyStream() - -type ByteMemory with - - member x.AsReadOnly() = ReadOnlyByteMemory x - - static member CreateMemoryMappedFile(bytes: ReadOnlyByteMemory) = - let length = int64 bytes.Length - let mmf = - let mmf = - MemoryMappedFile.CreateNew( - null, - length, - MemoryMappedFileAccess.ReadWrite, - MemoryMappedFileOptions.None, - HandleInheritability.None) - use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite) - bytes.CopyTo stream - mmf - - let accessor = mmf.CreateViewAccessor(0L, length, MemoryMappedFileAccess.ReadWrite) - - let safeHolder = - { new obj() with - override x.Finalize() = - (x :?> IDisposable).Dispose() - interface IDisposable with - member x.Dispose() = - GC.SuppressFinalize x - accessor.Dispose() - mmf.Dispose() } - RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, safeHolder) - - static member FromFile(path, access, ?canShadowCopy: bool) = - let canShadowCopy = defaultArg canShadowCopy false - - let memoryMappedFileAccess = - match access with - | FileAccess.Read -> MemoryMappedFileAccess.Read - | FileAccess.Write -> MemoryMappedFileAccess.Write - | _ -> MemoryMappedFileAccess.ReadWrite - - let mmf, accessor, length = - let fileStream = File.Open(path, FileMode.Open, access, FileShare.Read) - let length = fileStream.Length - let mmf = - if canShadowCopy then - let mmf = - MemoryMappedFile.CreateNew( - null, - length, - MemoryMappedFileAccess.ReadWrite, - MemoryMappedFileOptions.None, - HandleInheritability.None) - use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite) - fileStream.CopyTo(stream) - fileStream.Dispose() - mmf - else - MemoryMappedFile.CreateFromFile( - fileStream, - null, - length, - memoryMappedFileAccess, - HandleInheritability.None, - leaveOpen=false) - mmf, mmf.CreateViewAccessor(0L, length, memoryMappedFileAccess), length - - match access with - | FileAccess.Read when not accessor.CanRead -> failwith "Cannot read file" - | FileAccess.Write when not accessor.CanWrite -> failwith "Cannot write file" - | _ when not accessor.CanRead || not accessor.CanWrite -> failwith "Cannot read or write file" - | _ -> () - - let safeHolder = - { new obj() with - override x.Finalize() = - (x :?> IDisposable).Dispose() - interface IDisposable with - member x.Dispose() = - GC.SuppressFinalize x - accessor.Dispose() - mmf.Dispose() } - RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, safeHolder) - - static member FromUnsafePointer(addr, length, hold: obj) = - RawByteMemory(NativePtr.ofNativeInt addr, length, hold) :> ByteMemory - - static member FromArray(bytes, offset, length) = - ByteArrayMemory(bytes, offset, length) :> ByteMemory - - static member FromArray bytes = - ByteArrayMemory.FromArray(bytes, 0, bytes.Length) - -type internal ByteStream = - { bytes: ReadOnlyByteMemory - mutable pos: int - max: int } - member b.ReadByte() = - if b.pos >= b.max then failwith "end of stream" - let res = b.bytes.[b.pos] - b.pos <- b.pos + 1 - res - member b.ReadUtf8String n = - let res = b.bytes.ReadUtf8String(b.pos,n) - b.pos <- b.pos + n; res - - static member FromBytes (b: ReadOnlyByteMemory,n,len) = - if n < 0 || (n+len) > b.Length then failwith "FromBytes" - { bytes = b; pos = n; max = n+len } - - member b.ReadBytes n = - if b.pos + n > b.max then failwith "ReadBytes: end of stream" - let res = b.bytes.Slice(b.pos, n) - b.pos <- b.pos + n - res - - member b.Position = b.pos -#if LAZY_UNPICKLE - member b.CloneAndSeek = { bytes=b.bytes; pos=pos; max=b.max } - member b.Skip = b.pos <- b.pos + n -#endif - - -type internal ByteBuffer = - { mutable bbArray: byte[] - mutable bbCurrent: int } - - member buf.Ensure newSize = - let oldBufSize = buf.bbArray.Length - if newSize > oldBufSize then - let old = buf.bbArray - buf.bbArray <- Bytes.zeroCreate (max newSize (oldBufSize * 2)) - Bytes.blit old 0 buf.bbArray 0 buf.bbCurrent - - member buf.Close () = Bytes.sub buf.bbArray 0 buf.bbCurrent - - member buf.EmitIntAsByte (i:int) = - let newSize = buf.bbCurrent + 1 - buf.Ensure newSize - buf.bbArray.[buf.bbCurrent] <- byte i - buf.bbCurrent <- newSize - - member buf.EmitByte (b:byte) = buf.EmitIntAsByte (int b) - - member buf.EmitIntsAsBytes (arr:int[]) = - let n = arr.Length - let newSize = buf.bbCurrent + n - buf.Ensure newSize - let bbArr = buf.bbArray - let bbBase = buf.bbCurrent - for i = 0 to n - 1 do - bbArr.[bbBase + i] <- byte arr.[i] - buf.bbCurrent <- newSize - - member bb.FixupInt32 pos n = - bb.bbArray.[pos] <- (Bytes.b0 n |> byte) - bb.bbArray.[pos + 1] <- (Bytes.b1 n |> byte) - bb.bbArray.[pos + 2] <- (Bytes.b2 n |> byte) - bb.bbArray.[pos + 3] <- (Bytes.b3 n |> byte) - - member buf.EmitInt32 n = - let newSize = buf.bbCurrent + 4 - buf.Ensure newSize - buf.FixupInt32 buf.bbCurrent n - buf.bbCurrent <- newSize - - member buf.EmitBytes (i:byte[]) = - let n = i.Length - let newSize = buf.bbCurrent + n - buf.Ensure newSize - Bytes.blit i 0 buf.bbArray buf.bbCurrent n - buf.bbCurrent <- newSize - - member buf.EmitByteMemory (i:ReadOnlyByteMemory) = - let n = i.Length - let newSize = buf.bbCurrent + n - buf.Ensure newSize - i.Copy(0, buf.bbArray, buf.bbCurrent, n) - buf.bbCurrent <- newSize - - member buf.EmitInt32AsUInt16 n = - let newSize = buf.bbCurrent + 2 - buf.Ensure newSize - buf.bbArray.[buf.bbCurrent] <- (Bytes.b0 n |> byte) - buf.bbArray.[buf.bbCurrent + 1] <- (Bytes.b1 n |> byte) - buf.bbCurrent <- newSize - - member buf.EmitBoolAsByte (b:bool) = buf.EmitIntAsByte (if b then 1 else 0) - - member buf.EmitUInt16 (x:uint16) = buf.EmitInt32AsUInt16 (int32 x) - - member buf.EmitInt64 x = - buf.EmitInt32 (Bytes.dWw0 x) - buf.EmitInt32 (Bytes.dWw1 x) - - member buf.Position = buf.bbCurrent - - static member Create sz = - { bbArray=Bytes.zeroCreate sz - bbCurrent = 0 } - - diff --git a/src/absil/bytes.fsi b/src/absil/bytes.fsi deleted file mode 100644 index 11e7c9f58cc..00000000000 --- a/src/absil/bytes.fsi +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Blobs of bytes, cross-compiling -namespace FSharp.Compiler.AbstractIL.Internal - -open System.IO -open Internal.Utilities - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal - - -module internal Bytes = - /// returned int will be 0 <= x <= 255 - val get: byte[] -> int -> int - val zeroCreate: int -> byte[] - /// each int must be 0 <= x <= 255 - val ofInt32Array: int[] -> byte[] - /// each int will be 0 <= x <= 255 - - val blit: byte[] -> int -> byte[] -> int -> int -> unit - - val stringAsUnicodeNullTerminated: string -> byte[] - val stringAsUtf8NullTerminated: string -> byte[] - -/// May be backed by managed or unmanaged memory, or memory mapped file. -[] -type internal ByteMemory = - - abstract Item: int -> byte with get - - abstract Length: int - - abstract ReadBytes: pos: int * count: int -> byte[] - - abstract ReadInt32: pos: int -> int - - abstract ReadUInt16: pos: int -> uint16 - - abstract ReadUtf8String: pos: int * count: int -> string - - abstract Slice: pos: int * count: int -> ByteMemory - - abstract CopyTo: Stream -> unit - - abstract Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit - - abstract ToArray: unit -> byte[] - - /// Get a stream representation of the backing memory. - /// Disposing this will not free up any of the backing memory. - abstract AsStream: unit -> Stream - - /// Get a stream representation of the backing memory. - /// Disposing this will not free up any of the backing memory. - /// Stream cannot be written to. - abstract AsReadOnlyStream: unit -> Stream - -[] -type internal ReadOnlyByteMemory = - - new: ByteMemory -> ReadOnlyByteMemory - - member Item: int -> byte with get - - member Length: int - - member ReadBytes: pos: int * count: int -> byte[] - - member ReadInt32: pos: int -> int - - member ReadUInt16: pos: int -> uint16 - - member ReadUtf8String: pos: int * count: int -> string - - member Slice: pos: int * count: int -> ReadOnlyByteMemory - - member CopyTo: Stream -> unit - - member Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit - - member ToArray: unit -> byte[] - - member AsStream: unit -> Stream - -type ByteMemory with - - member AsReadOnly: unit -> ReadOnlyByteMemory - - /// Create another ByteMemory object that has a backing memory mapped file based on another ByteMemory's contents. - static member CreateMemoryMappedFile: ReadOnlyByteMemory -> ByteMemory - - /// Creates a ByteMemory object that has a backing memory mapped file from a file on-disk. - static member FromFile: path: string * FileAccess * ?canShadowCopy: bool -> ByteMemory - - /// Creates a ByteMemory object that is backed by a raw pointer. - /// Use with care. - static member FromUnsafePointer: addr: nativeint * length: int * hold: obj -> ByteMemory - - /// Creates a ByteMemory object that is backed by a byte array with the specified offset and length. - static member FromArray: bytes: byte[] * offset: int * length: int -> ByteMemory - - /// Creates a ByteMemory object that is backed by a byte array. - static member FromArray: bytes: byte[] -> ByteMemory - -/// Imperative buffers and streams of byte[] -[] -type internal ByteBuffer = - member Close : unit -> byte[] - member EmitIntAsByte : int -> unit - member EmitIntsAsBytes : int[] -> unit - member EmitByte : byte -> unit - member EmitBytes : byte[] -> unit - member EmitByteMemory : ReadOnlyByteMemory -> unit - member EmitInt32 : int32 -> unit - member EmitInt64 : int64 -> unit - member FixupInt32 : pos: int -> value: int32 -> unit - member EmitInt32AsUInt16 : int32 -> unit - member EmitBoolAsByte : bool -> unit - member EmitUInt16 : uint16 -> unit - member Position : int - static member Create : int -> ByteBuffer - - -[] -type internal ByteStream = - member ReadByte : unit -> byte - member ReadBytes : int -> ReadOnlyByteMemory - member ReadUtf8String : int -> string - member Position : int - static member FromBytes : ReadOnlyByteMemory * start:int * length:int -> ByteStream - -#if LAZY_UNPICKLE - member CloneAndSeek : int -> ByteStream - member Skip : int -> unit -#endif diff --git a/src/absil/il.fsi b/src/absil/il.fsi deleted file mode 100644 index 506878e1d6e..00000000000 --- a/src/absil/il.fsi +++ /dev/null @@ -1,2024 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// The "unlinked" view of .NET metadata and code. Central to the Abstract IL library -module public FSharp.Compiler.AbstractIL.IL - -open FSharp.Compiler.AbstractIL.Internal -open System.Collections.Generic -open System.Reflection - -[] -type PrimaryAssembly = - | Mscorlib - | System_Runtime - | NetStandard - - member Name: string - -/// Represents guids -type ILGuid = byte[] - -[] -type ILPlatform = - | X86 - | AMD64 - | IA64 - -/// Debug info. Values of type "source" can be attached at sequence -/// points and some other locations. -[] -type ILSourceDocument = - static member Create: language: ILGuid option * vendor: ILGuid option * documentType: ILGuid option * file: string -> ILSourceDocument - member Language: ILGuid option - member Vendor: ILGuid option - member DocumentType: ILGuid option - member File: string - - -[] -type ILSourceMarker = - static member Create: document: ILSourceDocument * line: int * column: int * endLine:int * endColumn: int-> ILSourceMarker - member Document: ILSourceDocument - member Line: int - member Column: int - member EndLine: int - member EndColumn: int - -[] -type PublicKey = - | PublicKey of byte[] - | PublicKeyToken of byte[] - member IsKey: bool - member IsKeyToken: bool - member Key: byte[] - member KeyToken: byte[] - static member KeyAsToken: byte[] -> PublicKey - -[] -type ILVersionInfo = - - val Major: uint16 - val Minor: uint16 - val Build: uint16 - val Revision: uint16 - - new : major: uint16 * minor: uint16 * build: uint16 * revision: uint16 -> ILVersionInfo - -[] -type ILAssemblyRef = - static member Create: name: string * hash: byte[] option * publicKey: PublicKey option * retargetable: bool * version: ILVersionInfo option * locale: string option -> ILAssemblyRef - static member FromAssemblyName: System.Reflection.AssemblyName -> ILAssemblyRef - member Name: string - - /// The fully qualified name of the assembly reference, e.g. mscorlib, Version=1.0.3705 etc. - member QualifiedName: string - member Hash: byte[] option - member PublicKey: PublicKey option - - /// CLI says this indicates if the assembly can be retargeted (at runtime) to be from a different publisher. - member Retargetable: bool - member Version: ILVersionInfo option - member Locale: string option - - member EqualsIgnoringVersion: ILAssemblyRef -> bool - - interface System.IComparable - -[] -type ILModuleRef = - static member Create: name: string * hasMetadata: bool * hash: byte[] option -> ILModuleRef - member Name: string - member HasMetadata: bool - member Hash: byte[] option - interface System.IComparable - -// Scope references -[] -type ILScopeRef = - /// A reference to the type in the current module - | Local - /// A reference to a type in a module in the same assembly - | Module of ILModuleRef - /// A reference to a type in another assembly - | Assembly of ILAssemblyRef - /// A reference to a type in the primary assembly - | PrimaryAssembly - member IsLocalRef: bool - member QualifiedName: string - -// Calling conventions. -// -// For nearly all purposes you simply want to use ILArgConvention.Default combined -// with ILThisConvention.Instance or ILThisConvention.Static, i.e. -// ILCallingConv.Instance == Callconv(ILThisConvention.Instance, ILArgConvention.Default): for an instance method -// ILCallingConv.Static == Callconv(ILThisConvention.Static, ILArgConvention.Default): for a static method -// -// ILThisConvention.InstanceExplicit is only used by Managed C++, and indicates -// that the 'this' pointer is actually explicit in the signature. -[] -type ILArgConvention = - | Default - | CDecl - | StdCall - | ThisCall - | FastCall - | VarArg - -[] -type ILThisConvention = - /// accepts an implicit 'this' pointer - | Instance - /// accepts an explicit 'this' pointer - | InstanceExplicit - /// no 'this' pointer is passed - | Static - -[] -type ILCallingConv = - | Callconv of ILThisConvention * ILArgConvention - - member IsInstance: bool - member IsInstanceExplicit: bool - member IsStatic: bool - member ThisConv: ILThisConvention - member BasicConv: ILArgConvention - - static member Instance: ILCallingConv - static member Static : ILCallingConv - -/// Array shapes. For most purposes the rank is the only thing that matters. -type ILArrayBound = int32 option - -/// Lower-bound/size pairs -type ILArrayBounds = ILArrayBound * ILArrayBound - -type ILArrayShape = - | ILArrayShape of ILArrayBounds list - - member Rank: int - - /// Bounds for a single dimensional, zero based array - static member SingleDimensional: ILArrayShape - static member FromRank: int -> ILArrayShape - -type ILBoxity = - | AsObject - | AsValue - -type ILGenericVariance = - | NonVariant - | CoVariant - | ContraVariant - -/// Type refs, i.e. references to types in some .NET assembly -[] -type ILTypeRef = - - /// Create a ILTypeRef. - static member Create: scope: ILScopeRef * enclosing: string list * name: string -> ILTypeRef - - /// Where is the type, i.e. is it in this module, in another module in this assembly or in another assembly? - member Scope: ILScopeRef - - /// The list of enclosing type names for a nested type. If non-nil then the first of these also contains the namespace. - member Enclosing: string list - - /// The name of the type. This also contains the namespace if Enclosing is empty. - member Name: string - - /// The name of the type in the assembly using the '.' notation for nested types. - member FullName: string - - /// The name of the type in the assembly using the '+' notation for nested types. - member BasicQualifiedName: string - - member QualifiedName: string - - interface System.IComparable - -/// Type specs and types. -[] -type ILTypeSpec = - /// Create an ILTypeSpec. - static member Create: typeRef:ILTypeRef * instantiation:ILGenericArgs -> ILTypeSpec - - /// Which type is being referred to? - member TypeRef: ILTypeRef - - /// The type instantiation if the type is generic, otherwise empty - member GenericArgs: ILGenericArgs - - /// Where is the type, i.e. is it in this module, in another module in this assembly or in another assembly? - member Scope: ILScopeRef - - /// The list of enclosing type names for a nested type. If non-nil then the first of these also contains the namespace. - member Enclosing: string list - - /// The name of the type. This also contains the namespace if Enclosing is empty. - member Name: string - - /// The name of the type in the assembly using the '.' notation for nested types. - member FullName: string - - interface System.IComparable - -and - [] - ILType = - - /// Used only in return and pointer types. - | Void - - /// Array types - | Array of ILArrayShape * ILType - - /// Unboxed types, including builtin types. - | Value of ILTypeSpec - - /// Reference types. Also may be used for parents of members even if for members in value types. - | Boxed of ILTypeSpec - - /// Unmanaged pointers. Nb. the type is used by tools and for binding only, not by the verifier. - | Ptr of ILType - - /// Managed pointers. - | Byref of ILType - - /// ILCode pointers. - | FunctionPointer of ILCallingSignature - - /// Reference a generic arg. - | TypeVar of uint16 - - /// Custom modifiers. - | Modified of - /// True if modifier is "required". - bool * - /// The class of the custom modifier. - ILTypeRef * - /// The type being modified. - ILType - - member TypeSpec: ILTypeSpec - - member Boxity: ILBoxity - - member TypeRef: ILTypeRef - - member IsNominal: bool - - member GenericArgs: ILGenericArgs - - member IsTyvar: bool - - member BasicQualifiedName: string - - member QualifiedName: string - -and [] - ILCallingSignature = - { CallingConv: ILCallingConv - ArgTypes: ILTypes - ReturnType: ILType } - -/// Actual generic parameters are always types. -and ILGenericArgs = ILType list - -and ILTypes = ILType list - -/// Formal identities of methods. -[] -type ILMethodRef = - - /// Functional creation - static member Create: enclosingTypeRef: ILTypeRef * callingConv: ILCallingConv * name: string * genericArity: int * argTypes: ILTypes * returnType: ILType -> ILMethodRef - - member DeclaringTypeRef: ILTypeRef - - member CallingConv: ILCallingConv - - member Name: string - - member GenericArity: int - - member ArgCount: int - - member ArgTypes: ILTypes - - member ReturnType: ILType - - member CallingSignature: ILCallingSignature - - interface System.IComparable - -/// Formal identities of fields. -[] -type ILFieldRef = - { DeclaringTypeRef: ILTypeRef - Name: string - Type: ILType } - -/// The information at the callsite of a method -[] -type ILMethodSpec = - - /// Functional creation - static member Create: ILType * ILMethodRef * ILGenericArgs -> ILMethodSpec - - member MethodRef: ILMethodRef - - member DeclaringType: ILType - - member GenericArgs: ILGenericArgs - - member CallingConv: ILCallingConv - - member GenericArity: int - - member Name: string - - member FormalArgTypes: ILTypes - - member FormalReturnType: ILType - - interface System.IComparable - -/// Field specs. The data given for a ldfld, stfld etc. instruction. -[] -type ILFieldSpec = - { FieldRef: ILFieldRef - DeclaringType: ILType } - - member DeclaringTypeRef: ILTypeRef - - member Name: string - - member FormalType: ILType - - member ActualType: ILType - -/// ILCode labels. In structured code each code label refers to a basic block somewhere in the code of the method. -type ILCodeLabel = int - -[] -type ILBasicType = - | DT_R - | DT_I1 - | DT_U1 - | DT_I2 - | DT_U2 - | DT_I4 - | DT_U4 - | DT_I8 - | DT_U8 - | DT_R4 - | DT_R8 - | DT_I - | DT_U - | DT_REF - -[] -type ILToken = - | ILType of ILType - | ILMethod of ILMethodSpec - | ILField of ILFieldSpec - -[] -type ILConst = - | I4 of int32 - | I8 of int64 - | R4 of single - | R8 of double - -type ILTailcall = - | Tailcall - | Normalcall - -type ILAlignment = - | Aligned - | Unaligned1 - | Unaligned2 - | Unaligned4 - -type ILVolatility = - | Volatile - | Nonvolatile - -type ILReadonly = - | ReadonlyAddress - | NormalAddress - -type ILVarArgs = ILTypes option - -[] -type ILComparisonInstr = - | BI_beq - | BI_bge - | BI_bge_un - | BI_bgt - | BI_bgt_un - | BI_ble - | BI_ble_un - | BI_blt - | BI_blt_un - | BI_bne_un - | BI_brfalse - | BI_brtrue - -/// The instruction set. -[] -type ILInstr = - | AI_add - | AI_add_ovf - | AI_add_ovf_un - | AI_and - | AI_div - | AI_div_un - | AI_ceq - | AI_cgt - | AI_cgt_un - | AI_clt - | AI_clt_un - | AI_conv of ILBasicType - | AI_conv_ovf of ILBasicType - | AI_conv_ovf_un of ILBasicType - | AI_mul - | AI_mul_ovf - | AI_mul_ovf_un - | AI_rem - | AI_rem_un - | AI_shl - | AI_shr - | AI_shr_un - | AI_sub - | AI_sub_ovf - | AI_sub_ovf_un - | AI_xor - | AI_or - | AI_neg - | AI_not - | AI_ldnull - | AI_dup - | AI_pop - | AI_ckfinite - | AI_nop - | AI_ldc of ILBasicType * ILConst - | I_ldarg of uint16 - | I_ldarga of uint16 - | I_ldind of ILAlignment * ILVolatility * ILBasicType - | I_ldloc of uint16 - | I_ldloca of uint16 - | I_starg of uint16 - | I_stind of ILAlignment * ILVolatility * ILBasicType - | I_stloc of uint16 - - // Control transfer - | I_br of ILCodeLabel - | I_jmp of ILMethodSpec - | I_brcmp of ILComparisonInstr * ILCodeLabel - | I_switch of ILCodeLabel list - | I_ret - - // Method call - | I_call of ILTailcall * ILMethodSpec * ILVarArgs - | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs - | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs - | I_calli of ILTailcall * ILCallingSignature * ILVarArgs - | I_ldftn of ILMethodSpec - | I_newobj of ILMethodSpec * ILVarArgs - - // Exceptions - | I_throw - | I_endfinally - | I_endfilter - | I_leave of ILCodeLabel - | I_rethrow - - // Object instructions - | I_ldsfld of ILVolatility * ILFieldSpec - | I_ldfld of ILAlignment * ILVolatility * ILFieldSpec - | I_ldsflda of ILFieldSpec - | I_ldflda of ILFieldSpec - | I_stsfld of ILVolatility * ILFieldSpec - | I_stfld of ILAlignment * ILVolatility * ILFieldSpec - | I_ldstr of string - | I_isinst of ILType - | I_castclass of ILType - | I_ldtoken of ILToken - | I_ldvirtftn of ILMethodSpec - - // Value type instructions - | I_cpobj of ILType - | I_initobj of ILType - | I_ldobj of ILAlignment * ILVolatility * ILType - | I_stobj of ILAlignment * ILVolatility * ILType - | I_box of ILType - | I_unbox of ILType - | I_unbox_any of ILType - | I_sizeof of ILType - - // Generalized array instructions. In AbsIL these instructions include - // both the single-dimensional variants (with ILArrayShape == ILArrayShape.SingleDimensional) - // and calls to the "special" multi-dimensional "methods" such as: - // newobj void string[,]::.ctor(int32, int32) - // call string string[,]::Get(int32, int32) - // call string& string[,]::Address(int32, int32) - // call void string[,]::Set(int32, int32,string) - // - // The IL reader transforms calls of this form to the corresponding - // generalized instruction with the corresponding ILArrayShape - // argument. This is done to simplify the IL and make it more uniform. - // The IL writer then reverses this when emitting the binary. - | I_ldelem of ILBasicType - | I_stelem of ILBasicType - | I_ldelema of ILReadonly * bool * ILArrayShape * ILType (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *) - | I_ldelem_any of ILArrayShape * ILType (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *) - | I_stelem_any of ILArrayShape * ILType (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *) - | I_newarr of ILArrayShape * ILType (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *) - | I_ldlen - - // "System.TypedReference" related instructions: almost - // no languages produce these, though they do occur in mscorlib.dll - // System.TypedReference represents a pair of a type and a byref-pointer - // to a value of that type. - | I_mkrefany of ILType - | I_refanytype - | I_refanyval of ILType - - // Debug-specific - // I_seqpoint is a fake instruction to represent a sequence point: - // the next instruction starts the execution of the - // statement covered by the given range - this is a - // dummy instruction and is not emitted - | I_break - | I_seqpoint of ILSourceMarker - - // Varargs - C++ only - | I_arglist - - // Local aggregates, i.e. stack allocated data (alloca): C++ only - | I_localloc - | I_cpblk of ILAlignment * ILVolatility - | I_initblk of ILAlignment * ILVolatility - - // EXTENSIONS - | EI_ilzero of ILType - | EI_ldlen_multi of int32 * int32 - -[] -type ILExceptionClause = - | Finally of (ILCodeLabel * ILCodeLabel) - | Fault of (ILCodeLabel * ILCodeLabel) - | FilterCatch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel) - | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel) - -[] -type ILExceptionSpec = - { Range: (ILCodeLabel * ILCodeLabel) - Clause: ILExceptionClause } - -/// Indicates that a particular local variable has a particular source -/// language name within a given set of ranges. This does not effect local -/// variable numbering, which is global over the whole method. -[] -type ILLocalDebugMapping = - { LocalIndex: int - LocalName: string } - -[] -type ILLocalDebugInfo = - { Range: (ILCodeLabel * ILCodeLabel); - DebugMappings: ILLocalDebugMapping list } - -[] -type ILCode = - { Labels: Dictionary - Instrs:ILInstr[] - Exceptions: ILExceptionSpec list - Locals: ILLocalDebugInfo list } - -/// Field Init -[] -type ILFieldInit = - | String of string - | Bool of bool - | Char of uint16 - | Int8 of sbyte - | Int16 of int16 - | Int32 of int32 - | Int64 of int64 - | UInt8 of byte - | UInt16 of uint16 - | UInt32 of uint32 - | UInt64 of uint64 - | Single of single - | Double of double - | Null - -[] -type ILNativeVariant = - | Empty - | Null - | Variant - | Currency - | Decimal - | Date - | BSTR - | LPSTR - | LPWSTR - | IUnknown - | IDispatch - | SafeArray - | Error - | HRESULT - | CArray - | UserDefined - | Record - | FileTime - | Blob - | Stream - | Storage - | StreamedObject - | StoredObject - | BlobObject - | CF - | CLSID - | Void - | Bool - | Int8 - | Int16 - | Int32 - | Int64 - | Single - | Double - | UInt8 - | UInt16 - | UInt32 - | UInt64 - | PTR - | Array of ILNativeVariant - | Vector of ILNativeVariant - | Byref of ILNativeVariant - | Int - | UInt - -/// Native Types, for marshalling to the native C interface. -/// These are taken directly from the ILASM syntax, see ECMA Spec (Partition II, 7.4). -[] -type ILNativeType = - | Empty - | Custom of ILGuid * string * string * byte[] (* guid,nativeTypeName,custMarshallerName,cookieString *) - | FixedSysString of int32 - | FixedArray of int32 - | Currency - | LPSTR - | LPWSTR - | LPTSTR - | LPUTF8STR - | ByValStr - | TBSTR - | LPSTRUCT - | Struct - | Void - | Bool - | Int8 - | Int16 - | Int32 - | Int64 - | Single - | Double - | Byte - | UInt16 - | UInt32 - | UInt64 - /// optional idx of parameter giving size plus optional additive i.e. num elems - | Array of ILNativeType option * (int32 * int32 option) option - | Int - | UInt - | Method - | AsAny - | BSTR - | IUnknown - | IDispatch - | Interface - | Error - | SafeArray of ILNativeVariant * string option - | ANSIBSTR - | VariantBool - -/// Local variables -[] -type ILLocal = - { Type: ILType - IsPinned: bool - DebugInfo: (string * int * int) option } - -type ILLocals = list - -/// IL method bodies -[] -type ILMethodBody = - { IsZeroInit: bool - MaxStack: int32 - NoInlining: bool - AggressiveInlining: bool - Locals: ILLocals - Code: ILCode - SourceMarker: ILSourceMarker option } - -/// Member Access -[] -type ILMemberAccess = - | Assembly - | CompilerControlled - | FamilyAndAssembly - | FamilyOrAssembly - | Family - | Private - | Public - -[] -type ILAttribElem = - /// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special - /// way as indicated by Ecma-335 Partition II. - | String of string option - | Bool of bool - | Char of char - | SByte of sbyte - | Int16 of int16 - | Int32 of int32 - | Int64 of int64 - | Byte of byte - | UInt16 of uint16 - | UInt32 of uint32 - | UInt64 of uint64 - | Single of single - | Double of double - | Null - | Type of ILType option - | TypeRef of ILTypeRef option - | Array of ILType * ILAttribElem list - -/// Named args: values and flags indicating if they are fields or properties. -type ILAttributeNamedArg = string * ILType * bool * ILAttribElem - -/// Custom attribute. -type ILAttribute = - /// Attribute with args encoded to a binary blob according to ECMA-335 II.21 and II.23.3. - /// 'decodeILAttribData' is used to parse the byte[] blob to ILAttribElem's as best as possible. - | Encoded of method: ILMethodSpec * data: byte[] * elements: ILAttribElem list - - /// Attribute with args in decoded form. - | Decoded of method: ILMethodSpec * fixedArgs: ILAttribElem list * namedArgs: ILAttributeNamedArg list - - /// Attribute instance constructor. - member Method: ILMethodSpec - - /// Decoded arguments. May be empty in encoded attribute form. - member Elements: ILAttribElem list - - member WithMethod: method: ILMethodSpec -> ILAttribute - -[] -type ILAttributes = - member AsArray: ILAttribute [] - member AsList: ILAttribute list - -/// Represents the efficiency-oriented storage of ILAttributes in another item. -[] -type ILAttributesStored - -/// Method parameters and return values. -[] -type ILParameter = - { Name: string option - Type: ILType - Default: ILFieldInit option - /// Marshalling map for parameters. COM Interop only. - Marshal: ILNativeType option - IsIn: bool - IsOut: bool - IsOptional: bool - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - member CustomAttrs: ILAttributes - -type ILParameters = list - -val typesOfILParams: ILParameters -> ILType list - -/// Method return values. -[] -type ILReturn = - { Marshal: ILNativeType option - Type: ILType - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - - member CustomAttrs: ILAttributes - - member WithCustomAttrs: customAttrs: ILAttributes -> ILReturn - -[] -type ILSecurityAction = - | Request - | Demand - | Assert - | Deny - | PermitOnly - | LinkCheck - | InheritCheck - | ReqMin - | ReqOpt - | ReqRefuse - | PreJitGrant - | PreJitDeny - | NonCasDemand - | NonCasLinkDemand - | NonCasInheritance - | LinkDemandChoice - | InheritanceDemandChoice - | DemandChoice - -type ILSecurityDecl = - | ILSecurityDecl of ILSecurityAction * byte[] - -/// Abstract type equivalent to ILSecurityDecl list - use helpers -/// below to construct/destruct these. -[] -type ILSecurityDecls = - member AsList: ILSecurityDecl list - -/// Represents the efficiency-oriented storage of ILSecurityDecls in another item. -[] -type ILSecurityDeclsStored - -/// PInvoke attributes. -[] -type PInvokeCallingConvention = - | None - | Cdecl - | Stdcall - | Thiscall - | Fastcall - | WinApi - -[] -type PInvokeCharEncoding = - | None - | Ansi - | Unicode - | Auto - -[] -type PInvokeCharBestFit = - | UseAssembly - | Enabled - | Disabled - -[] -type PInvokeThrowOnUnmappableChar = - | UseAssembly - | Enabled - | Disabled - -[] -type PInvokeMethod = - { Where: ILModuleRef - Name: string - CallingConv: PInvokeCallingConvention - CharEncoding: PInvokeCharEncoding - NoMangle: bool - LastError: bool - ThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar - CharBestFit: PInvokeCharBestFit } - - -/// [OverridesSpec] - refer to a method declaration in a superclass or interface. -type ILOverridesSpec = - | OverridesSpec of ILMethodRef * ILType - member MethodRef: ILMethodRef - member DeclaringType: ILType - -type ILMethodVirtualInfo = - { IsFinal: bool - IsNewSlot: bool - IsCheckAccessOnOverride: bool - IsAbstract: bool } - -[] -type MethodKind = - | Static - | Cctor - | Ctor - | NonVirtual - | Virtual of ILMethodVirtualInfo - -[] -type MethodBody = - | IL of ILMethodBody - | PInvoke of PInvokeMethod - | Abstract - | Native - | NotAvailable - -[] -type MethodCodeKind = - | IL - | Native - | Runtime - -/// Generic parameters. Formal generic parameter declarations may include the bounds, if any, on the generic parameter. -type ILGenericParameterDef = - { Name: string - - /// At most one is the parent type, the others are interface types. - Constraints: ILTypes - - /// Variance of type parameters, only applicable to generic parameters for generic interfaces and delegates. - Variance: ILGenericVariance - - /// Indicates the type argument must be a reference type. - HasReferenceTypeConstraint: bool - - /// Indicates the type argument must be a value type, but not Nullable. - HasNotNullableValueTypeConstraint: bool - - /// Indicates the type argument must have a public nullary constructor. - HasDefaultConstructorConstraint: bool - - /// Do not use this - CustomAttrsStored: ILAttributesStored - - /// Do not use this - MetadataIndex: int32 } - - member CustomAttrs: ILAttributes - -type ILGenericParameterDefs = ILGenericParameterDef list - -[] -type ILLazyMethodBody = - member Contents: MethodBody - -/// IL Method definitions. -[] -type ILMethodDef = - - /// Functional creation of a value, with delayed reading of some elements via a metadata index - new: name: string * attributes: MethodAttributes * implAttributes: MethodImplAttributes * callingConv: ILCallingConv * - parameters: ILParameters * ret: ILReturn * body: ILLazyMethodBody * isEntryPoint:bool * genericParams: ILGenericParameterDefs * - securityDeclsStored: ILSecurityDeclsStored * customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILMethodDef - - /// Functional creation of a value, immediate - new: name: string * attributes: MethodAttributes * implAttributes: MethodImplAttributes * callingConv: ILCallingConv * - parameters: ILParameters * ret: ILReturn * body: ILLazyMethodBody * isEntryPoint:bool * genericParams: ILGenericParameterDefs * - securityDecls: ILSecurityDecls * customAttrs: ILAttributes -> ILMethodDef - - member Name: string - member Attributes: MethodAttributes - member ImplAttributes: MethodImplAttributes - member CallingConv: ILCallingConv - member Parameters: ILParameters - member Return: ILReturn - member Body: ILLazyMethodBody - member SecurityDecls: ILSecurityDecls - member IsEntryPoint:bool - member GenericParams: ILGenericParameterDefs - member CustomAttrs: ILAttributes - member ParameterTypes: ILTypes - member IsIL: bool - member Code: ILCode option - member Locals: ILLocals - member MaxStack: int32 - member IsZeroInit: bool - - /// Indicates a .cctor method. - member IsClassInitializer: bool - - /// Indicates a .ctor method. - member IsConstructor: bool - - /// Indicates a static method. - member IsStatic: bool - - /// Indicates this is an instance methods that is not virtual. - member IsNonVirtualInstance: bool - - /// Indicates an instance methods that is virtual or abstract or implements an interface slot. - member IsVirtual: bool - - member IsFinal: bool - member IsNewSlot: bool - member IsCheckAccessOnOverride: bool - member IsAbstract: bool - member MethodBody: ILMethodBody - member CallingSignature: ILCallingSignature - member Access: ILMemberAccess - member IsHideBySig: bool - member IsSpecialName: bool - - /// The method is exported to unmanaged code using COM interop. - member IsUnmanagedExport: bool - member IsReqSecObj: bool - - /// Some methods are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute - member HasSecurity: bool - member IsManaged: bool - member IsForwardRef: bool - member IsInternalCall: bool - member IsPreserveSig: bool - member IsSynchronized: bool - member IsNoInline: bool - member IsAggressiveInline: bool - - /// SafeHandle finalizer must be run. - member IsMustRun: bool - - /// Functional update of the value - member With: ?name: string * ?attributes: MethodAttributes * ?implAttributes: MethodImplAttributes * ?callingConv: ILCallingConv * - ?parameters: ILParameters * ?ret: ILReturn * ?body: ILLazyMethodBody * ?securityDecls: ILSecurityDecls * ?isEntryPoint:bool * - ?genericParams: ILGenericParameterDefs * ?customAttrs: ILAttributes -> ILMethodDef - member WithSpecialName: ILMethodDef - member WithHideBySig: unit -> ILMethodDef - member WithHideBySig: bool -> ILMethodDef - member WithFinal: bool -> ILMethodDef - member WithAbstract: bool -> ILMethodDef - member WithAccess: ILMemberAccess -> ILMethodDef - member WithNewSlot: ILMethodDef - member WithSecurity: bool -> ILMethodDef - member WithPInvoke: bool -> ILMethodDef - member WithPreserveSig: bool -> ILMethodDef - member WithSynchronized: bool -> ILMethodDef - member WithNoInlining: bool -> ILMethodDef - member WithAggressiveInlining: bool -> ILMethodDef - member WithRuntime: bool -> ILMethodDef - -/// Tables of methods. Logically equivalent to a list of methods but -/// the table is kept in a form optimized for looking up methods by -/// name and arity. -[] -type ILMethodDefs = - interface IEnumerable - member AsArray: ILMethodDef[] - member AsList: ILMethodDef list - member FindByName: string -> ILMethodDef list - -/// Field definitions. -[] -type ILFieldDef = - - /// Functional creation of a value using delayed reading via a metadata index - new: name: string * fieldType: ILType * attributes: FieldAttributes * data: byte[] option * - literalValue: ILFieldInit option * offset: int32 option * marshal: ILNativeType option * - customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILFieldDef - - /// Functional creation of a value, immediate - new: name: string * fieldType: ILType * attributes: FieldAttributes * data: byte[] option * - literalValue: ILFieldInit option * offset: int32 option * marshal: ILNativeType option * - customAttrs: ILAttributes -> ILFieldDef - - member Name: string - member FieldType: ILType - member Attributes: FieldAttributes - member Data: byte[] option - member LiteralValue: ILFieldInit option - - /// The explicit offset in bytes when explicit layout is used. - member Offset: int32 option - member Marshal: ILNativeType option - member CustomAttrs: ILAttributes - member IsStatic: bool - member IsSpecialName: bool - member IsLiteral: bool - member NotSerialized: bool - member IsInitOnly: bool - member Access: ILMemberAccess - - /// Functional update of the value - member With: ?name: string * ?fieldType: ILType * ?attributes: FieldAttributes * ?data: byte[] option * ?literalValue: ILFieldInit option * - ?offset: int32 option * ?marshal: ILNativeType option * ?customAttrs: ILAttributes -> ILFieldDef - member WithAccess: ILMemberAccess -> ILFieldDef - member WithInitOnly: bool -> ILFieldDef - member WithStatic: bool -> ILFieldDef - member WithSpecialName: bool -> ILFieldDef - member WithNotSerialized: bool -> ILFieldDef - member WithLiteralDefaultValue: ILFieldInit option -> ILFieldDef - member WithFieldMarshal: ILNativeType option -> ILFieldDef - -/// Tables of fields. Logically equivalent to a list of fields but the table is kept in -/// a form to allow efficient looking up fields by name. -[] -type ILFieldDefs = - member AsList: ILFieldDef list - member LookupByName: string -> ILFieldDef list - -/// Event definitions. -[] -type ILEventDef = - - /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs - new: eventType: ILType option * name: string * attributes: EventAttributes * addMethod: ILMethodRef * - removeMethod: ILMethodRef * fireMethod: ILMethodRef option * otherMethods: ILMethodRef list * - customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILEventDef - - /// Functional creation of a value, immediate - new: eventType: ILType option * name: string * attributes: EventAttributes * addMethod: ILMethodRef * - removeMethod: ILMethodRef * fireMethod: ILMethodRef option * otherMethods: ILMethodRef list * - customAttrs: ILAttributes -> ILEventDef - - member EventType: ILType option - member Name: string - member Attributes: EventAttributes - member AddMethod: ILMethodRef - member RemoveMethod: ILMethodRef - member FireMethod: ILMethodRef option - member OtherMethods: ILMethodRef list - member CustomAttrs: ILAttributes - member IsSpecialName: bool - member IsRTSpecialName: bool - - /// Functional update of the value - member With: ?eventType: ILType option * ?name: string * ?attributes: EventAttributes * ?addMethod: ILMethodRef * - ?removeMethod: ILMethodRef * ?fireMethod: ILMethodRef option * ?otherMethods: ILMethodRef list * - ?customAttrs: ILAttributes -> ILEventDef - -/// Table of those events in a type definition. -[] -type ILEventDefs = - member AsList: ILEventDef list - member LookupByName: string -> ILEventDef list - -/// Property definitions -[] -type ILPropertyDef = - - /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs - new: name: string * attributes: PropertyAttributes * setMethod: ILMethodRef option * getMethod: ILMethodRef option * - callingConv: ILThisConvention * propertyType: ILType * init: ILFieldInit option * args: ILTypes * - customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILPropertyDef - - /// Functional creation of a value, immediate - new: name: string * attributes: PropertyAttributes * setMethod: ILMethodRef option * getMethod: ILMethodRef option * - callingConv: ILThisConvention * propertyType: ILType * init: ILFieldInit option * args: ILTypes * - customAttrs: ILAttributes -> ILPropertyDef - - member Name: string - member Attributes: PropertyAttributes - member SetMethod: ILMethodRef option - member GetMethod: ILMethodRef option - member CallingConv: ILThisConvention - member PropertyType: ILType - member Init: ILFieldInit option - member Args: ILTypes - member CustomAttrs: ILAttributes - member IsSpecialName: bool - member IsRTSpecialName: bool - - /// Functional update of the value - member With: ?name: string * ?attributes: PropertyAttributes * ?setMethod: ILMethodRef option * ?getMethod: ILMethodRef option * - ?callingConv: ILThisConvention * ?propertyType: ILType * ?init: ILFieldInit option * ?args: ILTypes * - ?customAttrs: ILAttributes -> ILPropertyDef - -/// Table of properties in an IL type definition. -[] -[] -type ILPropertyDefs = - member AsList: ILPropertyDef list - member LookupByName: string -> ILPropertyDef list - -/// Method Impls -type ILMethodImplDef = - { Overrides: ILOverridesSpec - OverrideBy: ILMethodSpec } - -[] -type ILMethodImplDefs = - member AsList: ILMethodImplDef list - -/// Type Layout information. -[] -type ILTypeDefLayout = - | Auto - | Sequential of ILTypeDefLayoutInfo - | Explicit of ILTypeDefLayoutInfo - -and ILTypeDefLayoutInfo = - { Size: int32 option - Pack: uint16 option } - -/// Indicate the initialization semantics of a type. -[] -type ILTypeInit = - | BeforeField - | OnAny - -/// Default Unicode encoding for P/Invoke within a type. -[] -type ILDefaultPInvokeEncoding = - | Ansi - | Auto - | Unicode - -/// Type Access. -[] -type ILTypeDefAccess = - | Public - | Private - | Nested of ILMemberAccess - -/// A categorization of type definitions into "kinds" -[] -type ILTypeDefKind = - | Class - | ValueType - | Interface - | Enum - | Delegate - -/// Tables of named type definitions. -[] -type ILTypeDefs = - interface IEnumerable - - member AsArray: ILTypeDef[] - - member AsList: ILTypeDef list - - /// Get some information about the type defs, but do not force the read of the type defs themselves. - member AsArrayOfPreTypeDefs: ILPreTypeDef[] - - /// Calls to FindByName will result in any laziness in the overall - /// set of ILTypeDefs being read in in addition - /// to the details for the type found, but the remaining individual - /// type definitions will not be read. - member FindByName: string -> ILTypeDef - -/// Represents IL Type Definitions. -and [] - ILTypeDef = - - /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs - new: name: string * attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * genericParams: ILGenericParameterDefs * - extends: ILType option * methods: ILMethodDefs * nestedTypes: ILTypeDefs * fields: ILFieldDefs * methodImpls: ILMethodImplDefs * - events: ILEventDefs * properties: ILPropertyDefs * securityDeclsStored: ILSecurityDeclsStored * customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILTypeDef - - /// Functional creation of a value, immediate - new: name: string * attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * genericParams: ILGenericParameterDefs * - extends: ILType option * methods: ILMethodDefs * nestedTypes: ILTypeDefs * fields: ILFieldDefs * methodImpls: ILMethodImplDefs * - events: ILEventDefs * properties: ILPropertyDefs * securityDecls: ILSecurityDecls * customAttrs: ILAttributes -> ILTypeDef - - member Name: string - member Attributes: TypeAttributes - member GenericParams: ILGenericParameterDefs - member Layout: ILTypeDefLayout - member NestedTypes: ILTypeDefs - member Implements: ILTypes - member Extends: ILType option - member Methods: ILMethodDefs - member SecurityDecls: ILSecurityDecls - member Fields: ILFieldDefs - member MethodImpls: ILMethodImplDefs - member Events: ILEventDefs - member Properties: ILPropertyDefs - member CustomAttrs: ILAttributes - member IsClass: bool - member IsStruct: bool - member IsInterface: bool - member IsEnum: bool - member IsDelegate: bool - member IsStructOrEnum: bool - member Access: ILTypeDefAccess - member IsAbstract: bool - member IsSealed: bool - member IsSerializable: bool - /// Class or interface generated for COM interop. - member IsComInterop: bool - member IsSpecialName: bool - /// Some classes are marked "HasSecurity" even if there are no permissions attached, - /// e.g. if they use SuppressUnmanagedCodeSecurityAttribute - member HasSecurity: bool - member Encoding: ILDefaultPInvokeEncoding - - member WithAccess: ILTypeDefAccess -> ILTypeDef - member WithNestedAccess: ILMemberAccess -> ILTypeDef - member WithSealed: bool -> ILTypeDef - member WithSerializable: bool -> ILTypeDef - member WithAbstract: bool -> ILTypeDef - member WithImport: bool -> ILTypeDef - member WithHasSecurity: bool -> ILTypeDef - member WithLayout: ILTypeDefLayout -> ILTypeDef - member WithKind: ILTypeDefKind -> ILTypeDef - member WithEncoding: ILDefaultPInvokeEncoding -> ILTypeDef - member WithSpecialName: bool -> ILTypeDef - member WithInitSemantics: ILTypeInit -> ILTypeDef - - /// Functional update - member With: ?name: string * ?attributes: TypeAttributes * ?layout: ILTypeDefLayout * ?implements: ILTypes * - ?genericParams:ILGenericParameterDefs * ?extends:ILType option * ?methods:ILMethodDefs * - ?nestedTypes:ILTypeDefs * ?fields: ILFieldDefs * ?methodImpls:ILMethodImplDefs * ?events:ILEventDefs * - ?properties:ILPropertyDefs * ?customAttrs:ILAttributes * ?securityDecls: ILSecurityDecls -> ILTypeDef - -/// Represents a prefix of information for ILTypeDef. -/// -/// The information is enough to perform name resolution for the F# compiler, probe attributes -/// for ExtensionAttribute etc. This is key to the on-demand exploration of .NET metadata. -/// This information has to be "Goldilocks" - not too much, not too little, just right. -and [] ILPreTypeDef = - abstract Namespace: string list - abstract Name: string - /// Realise the actual full typedef - abstract GetTypeDef : unit -> ILTypeDef - - -and [] ILPreTypeDefImpl = - interface ILPreTypeDef - - -and [] ILTypeDefStored - -val mkILPreTypeDef : ILTypeDef -> ILPreTypeDef -val mkILPreTypeDefComputed : string list * string * (unit -> ILTypeDef) -> ILPreTypeDef -val mkILPreTypeDefRead : string list * string * int32 * ILTypeDefStored -> ILPreTypeDef -val mkILTypeDefReader: (int32 -> ILTypeDef) -> ILTypeDefStored - -[] -type ILNestedExportedTypes = - member AsList: ILNestedExportedType list - -/// "Classes Elsewhere" - classes in auxiliary modules. -/// -/// Manifests include declarations for all the classes in an -/// assembly, regardless of which module they are in. -/// -/// The ".class extern" construct describes so-called exported types -- -/// these are public classes defined in the auxiliary modules of this assembly, -/// i.e. modules other than the manifest-carrying module. -/// -/// For example, if you have a two-module -/// assembly (A.DLL and B.DLL), and the manifest resides in the A.DLL, -/// then in the manifest all the public classes declared in B.DLL should -/// be defined as exported types, i.e., as ".class extern". The public classes -/// defined in A.DLL should not be defined as ".class extern" -- they are -/// already available in the manifest-carrying module. The union of all -/// public classes defined in the manifest-carrying module and all -/// exported types defined there is the set of all classes exposed by -/// this assembly. Thus, by analysing the metadata of the manifest-carrying -/// module of an assembly, you can identify all the classes exposed by -/// this assembly, and where to find them. -/// -/// Nested classes found in external modules should also be located in -/// this table, suitably nested inside another "ILExportedTypeOrForwarder" -/// definition. - -/// these are only found in the "Nested" field of ILExportedTypeOrForwarder objects -// REVIEW: fold this into ILExportedTypeOrForwarder. There's not much value in keeping these distinct -and ILNestedExportedType = - { Name: string - Access: ILMemberAccess - Nested: ILNestedExportedTypes - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - member CustomAttrs: ILAttributes - -/// these are only found in the ILExportedTypesAndForwarders table in the manifest -[] -type ILExportedTypeOrForwarder = - { ScopeRef: ILScopeRef - /// [Namespace.]Name - Name: string - Attributes: TypeAttributes - Nested: ILNestedExportedTypes - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - member Access: ILTypeDefAccess - member IsForwarder: bool - member CustomAttrs: ILAttributes - -[] -[] -type ILExportedTypesAndForwarders = - member AsList: ILExportedTypeOrForwarder list - member TryFindByName: string -> ILExportedTypeOrForwarder option - -[] -type ILResourceAccess = - | Public - | Private - -[] -type ILResourceLocation = - internal - /// Represents a manifest resource that can be read or written to a PE file - | Local of ReadOnlyByteMemory - - /// Represents a manifest resource in an associated file - | File of ILModuleRef * int32 - - /// Represents a manifest resource in a different assembly - | Assembly of ILAssemblyRef - -/// "Manifest ILResources" are chunks of resource data, being one of: -/// - the data section of the current module (byte[] of resource given directly). -/// - in an external file in this assembly (offset given in the ILResourceLocation field). -/// - as a resources in another assembly of the same name. -type ILResource = - { Name: string - Location: ILResourceLocation - Access: ILResourceAccess - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - - /// Read the bytes from a resource local to an assembly. Will fail for non-local resources. - member internal GetBytes : unit -> ReadOnlyByteMemory - - member CustomAttrs: ILAttributes - -/// Table of resources in a module. -[] -[] -type ILResources = - member AsList: ILResource list - - -[] -type ILAssemblyLongevity = - | Unspecified - | Library - | PlatformAppDomain - | PlatformProcess - | PlatformSystem - -/// The main module of an assembly is a module plus some manifest information. -type ILAssemblyManifest = - { Name: string - /// This is the ID of the algorithm used for the hashes of auxiliary - /// files in the assembly. These hashes are stored in the - /// ILModuleRef.Hash fields of this assembly. These are not - /// cryptographic hashes: they are simple file hashes. The algorithm - /// is normally 0x00008004 indicating the SHA1 hash algorithm. - AuxModuleHashAlgorithm: int32 - SecurityDeclsStored: ILSecurityDeclsStored - /// This is the public key used to sign this - /// assembly (the signature itself is stored elsewhere: see the - /// binary format, and may not have been written if delay signing - /// is used). (member Name, member PublicKey) forms the full - /// public name of the assembly. - PublicKey: byte[] option - Version: ILVersionInfo option - Locale: string option - CustomAttrsStored: ILAttributesStored - AssemblyLongevity: ILAssemblyLongevity - DisableJitOptimizations: bool - JitTracking: bool - IgnoreSymbolStoreSequencePoints: bool - Retargetable: bool - /// Records the types implemented by this assembly in auxiliary - /// modules. - ExportedTypes: ILExportedTypesAndForwarders - /// Records whether the entrypoint resides in another module. - EntrypointElsewhere: ILModuleRef option - MetadataIndex: int32 - } - member CustomAttrs: ILAttributes - member SecurityDecls: ILSecurityDecls - - -[] -type ILNativeResource = - /// Represents a native resource to be read from the PE file - | In of fileName: string * linkedResourceBase: int * linkedResourceStart: int * linkedResourceLength: int - - /// Represents a native resource to be written in an output file - | Out of unlinkedResource: byte[] - -/// One module in the "current" assembly, either a main-module or -/// an auxiliary module. The main module will have a manifest. -/// -/// An assembly is built by joining together a "main" module plus -/// several auxiliary modules. -type ILModuleDef = - { Manifest: ILAssemblyManifest option - Name: string - TypeDefs: ILTypeDefs - SubsystemVersion: int * int - UseHighEntropyVA: bool - SubSystemFlags: int32 - IsDLL: bool - IsILOnly: bool - Platform: ILPlatform option - StackReserveSize: int32 option - Is32Bit: bool - Is32BitPreferred: bool - Is64Bit: bool - VirtualAlignment: int32 - PhysicalAlignment: int32 - ImageBase: int32 - MetadataVersion: string - Resources: ILResources - /// e.g. win86 resources, as the exact contents of a .res or .obj file. Must be unlinked manually. - NativeResources: ILNativeResource list - CustomAttrsStored: ILAttributesStored - MetadataIndex: int32 } - member ManifestOfAssembly: ILAssemblyManifest - member HasManifest: bool - member CustomAttrs: ILAttributes - -/// Find the method definition corresponding to the given property or -/// event operation. These are always in the same class as the property -/// or event. This is useful especially if your code is not using the Ilbind -/// API to bind references. -val resolveILMethodRef: ILTypeDef -> ILMethodRef -> ILMethodDef -val resolveILMethodRefWithRescope: (ILType -> ILType) -> ILTypeDef -> ILMethodRef -> ILMethodDef - -// ------------------------------------------------------------------ -// Type Names -// -// The name of a type stored in the Name field is as follows: -// - For outer types it is, for example, System.String, i.e. -// the namespace followed by the type name. -// - For nested types, it is simply the type name. The namespace -// must be gleaned from the context in which the nested type -// lies. -// ------------------------------------------------------------------ - -val splitNamespace: string -> string list - -val splitNamespaceToArray: string -> string[] - -/// The splitILTypeName utility helps you split a string representing -/// a type name into the leading namespace elements (if any), the -/// names of any nested types and the type name itself. This function -/// memoizes and interns the splitting of the namespace portion of -/// the type name. -val splitILTypeName: string -> string list * string - -val splitILTypeNameWithPossibleStaticArguments: string -> string[] * string - -/// splitTypeNameRight is like splitILTypeName except the -/// namespace is kept as a whole string, rather than split at dots. -val splitTypeNameRight: string -> string option * string - -val typeNameForGlobalFunctions: string - -val isTypeNameForGlobalFunctions: string -> bool - -// ==================================================================== -// PART 2 -// -// Making metadata. Where no explicit constructor -// is given, you should create the concrete datatype directly, -// e.g. by filling in all appropriate record fields. -// ==================================================================== *) - -/// A table of common references to items in primary assembly (System.Runtime or mscorlib). -/// If a particular version of System.Runtime.dll has been loaded then you should -/// reference items from it via an ILGlobals for that specific version built using mkILGlobals. -[] -type ILGlobals = - member primaryAssemblyScopeRef: ILScopeRef - member primaryAssemblyRef: ILAssemblyRef - member primaryAssemblyName: string - member typ_Object: ILType - member typ_String: ILType - member typ_Type: ILType - member typ_Array: ILType - member typ_IntPtr: ILType - member typ_UIntPtr: ILType - member typ_Byte: ILType - member typ_Int16: ILType - member typ_Int32: ILType - member typ_Int64: ILType - member typ_SByte: ILType - member typ_UInt16: ILType - member typ_UInt32: ILType - member typ_UInt64: ILType - member typ_Single: ILType - member typ_Double: ILType - member typ_Bool: ILType - member typ_Char: ILType - member typ_TypedReference: ILType - - /// Is the given assembly possibly a primary assembly? - /// In practice, a primary assembly is an assembly that contains the System.Object type definition - /// and has no referenced assemblies. - /// However, we must consider assemblies that forward the System.Object type definition - /// to be possible primary assemblies. - /// Therefore, this will return true if the given assembly is the real primary assembly or an assembly that forwards - /// the System.Object type definition. - /// Assembly equivalency ignores the version here. - member IsPossiblePrimaryAssemblyRef: ILAssemblyRef -> bool - -/// Build the table of commonly used references given functions to find types in system assemblies -val mkILGlobals: primaryScopeRef: ILScopeRef * assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list -> ILGlobals - -val EcmaMscorlibILGlobals: ILGlobals - -/// When writing a binary the fake "toplevel" type definition (called ) -/// must come first. This function puts it first, and creates it in the returned -/// list as an empty typedef if it doesn't already exist. -val destTypeDefsWithGlobalFunctionsFirst: ILGlobals -> ILTypeDefs -> ILTypeDef list - -/// Not all custom attribute data can be decoded without binding types. In particular -/// enums must be bound in order to discover the size of the underlying integer. -/// The following assumes enums have size int32. -val decodeILAttribData: - ILGlobals -> - ILAttribute -> - ILAttribElem list * (* fixed args *) - ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) - -/// Generate simple references to assemblies and modules. -val mkSimpleAssemblyRef: string -> ILAssemblyRef - -val mkSimpleModRef: string -> ILModuleRef - -val mkILTyvarTy: uint16 -> ILType - -/// Make type refs. -val mkILNestedTyRef: ILScopeRef * string list * string -> ILTypeRef -val mkILTyRef: ILScopeRef * string -> ILTypeRef -val mkILTyRefInTyRef: ILTypeRef * string -> ILTypeRef - -type ILGenericArgsList = ILType list - -/// Make type specs. -val mkILNonGenericTySpec: ILTypeRef -> ILTypeSpec -val mkILTySpec: ILTypeRef * ILGenericArgsList -> ILTypeSpec - -/// Make types. -val mkILTy: ILBoxity -> ILTypeSpec -> ILType -val mkILNamedTy: ILBoxity -> ILTypeRef -> ILGenericArgsList -> ILType -val mkILBoxedTy: ILTypeRef -> ILGenericArgsList -> ILType -val mkILValueTy: ILTypeRef -> ILGenericArgsList -> ILType -val mkILNonGenericBoxedTy: ILTypeRef -> ILType -val mkILNonGenericValueTy: ILTypeRef -> ILType -val mkILArrTy: ILType * ILArrayShape -> ILType -val mkILArr1DTy: ILType -> ILType -val isILArrTy: ILType -> bool -val destILArrTy: ILType -> ILArrayShape * ILType -val mkILBoxedType: ILTypeSpec -> ILType - -/// Make method references and specs. -val mkILMethRef: ILTypeRef * ILCallingConv * string * int * ILType list * ILType -> ILMethodRef -val mkILMethSpec: ILMethodRef * ILBoxity * ILGenericArgsList * ILGenericArgsList -> ILMethodSpec -val mkILMethSpecForMethRefInTy: ILMethodRef * ILType * ILGenericArgsList -> ILMethodSpec -val mkILMethSpecInTy: ILType * ILCallingConv * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec - -/// Construct references to methods on a given type . -val mkILNonGenericMethSpecInTy: ILType * ILCallingConv * string * ILType list * ILType -> ILMethodSpec - -/// Construct references to instance methods. -val mkILInstanceMethSpecInTy: ILType * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec - -/// Construct references to instance methods. -val mkILNonGenericInstanceMethSpecInTy: ILType * string * ILType list * ILType -> ILMethodSpec - -/// Construct references to static methods. -val mkILStaticMethSpecInTy: ILType * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec - -/// Construct references to static, non-generic methods. -val mkILNonGenericStaticMethSpecInTy: ILType * string * ILType list * ILType -> ILMethodSpec - -/// Construct references to constructors. -val mkILCtorMethSpecForTy: ILType * ILType list -> ILMethodSpec - -/// Construct references to fields. -val mkILFieldRef: ILTypeRef * string * ILType -> ILFieldRef -val mkILFieldSpec: ILFieldRef * ILType -> ILFieldSpec -val mkILFieldSpecInTy: ILType * string * ILType -> ILFieldSpec - -val mkILCallSig: ILCallingConv * ILType list * ILType -> ILCallingSignature - -/// Make generalized versions of possibly-generic types, e.g. Given the ILTypeDef for List, return the type "List". -val mkILFormalBoxedTy: ILTypeRef -> ILGenericParameterDef list -> ILType -val mkILFormalNamedTy: ILBoxity -> ILTypeRef -> ILGenericParameterDef list -> ILType - -val mkILFormalTypars: ILType list -> ILGenericParameterDefs -val mkILFormalGenericArgs: int -> ILGenericParameterDefs -> ILGenericArgsList -val mkILSimpleTypar: string -> ILGenericParameterDef - -/// Make custom attributes. -val mkILCustomAttribMethRef: - ILGlobals - -> ILMethodSpec - * ILAttribElem list (* fixed args: values and implicit types *) - * ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) - -> ILAttribute - -val mkILCustomAttribute: - ILGlobals - -> ILTypeRef * ILType list * - ILAttribElem list (* fixed args: values and implicit types *) * - ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) - -> ILAttribute - -val getCustomAttrData: ILGlobals -> ILAttribute -> byte[] - -val mkPermissionSet: ILGlobals -> ILSecurityAction * (ILTypeRef * (string * ILType * ILAttribElem) list) list -> ILSecurityDecl - -/// Making code. -val generateCodeLabel: unit -> ILCodeLabel -val formatCodeLabel: ILCodeLabel -> string - -/// Make some code that is a straight line sequence of instructions. -/// The function will add a "return" if the last instruction is not an exiting instruction. -val nonBranchingInstrsToCode: ILInstr list -> ILCode - -/// Helpers for codegen: scopes for allocating new temporary variables. -type ILLocalsAllocator = - new: preAlloc: int -> ILLocalsAllocator - member AllocLocal: ILLocal -> uint16 - member Close: unit -> ILLocal list - -/// Derived functions for making some common patterns of instructions. -val mkNormalCall: ILMethodSpec -> ILInstr -val mkNormalCallvirt: ILMethodSpec -> ILInstr -val mkNormalCallconstraint: ILType * ILMethodSpec -> ILInstr -val mkNormalNewobj: ILMethodSpec -> ILInstr -val mkCallBaseConstructor: ILType * ILType list -> ILInstr list -val mkNormalStfld: ILFieldSpec -> ILInstr -val mkNormalStsfld: ILFieldSpec -> ILInstr -val mkNormalLdsfld: ILFieldSpec -> ILInstr -val mkNormalLdfld: ILFieldSpec -> ILInstr -val mkNormalLdflda: ILFieldSpec -> ILInstr -val mkNormalLdobj: ILType -> ILInstr -val mkNormalStobj: ILType -> ILInstr -val mkLdcInt32: int32 -> ILInstr -val mkLdarg0: ILInstr -val mkLdloc: uint16 -> ILInstr -val mkStloc: uint16 -> ILInstr -val mkLdarg: uint16 -> ILInstr - -val andTailness: ILTailcall -> bool -> ILTailcall - -/// Derived functions for making return, parameter and local variable -/// objects for use in method definitions. -val mkILParam: string option * ILType -> ILParameter -val mkILParamAnon: ILType -> ILParameter -val mkILParamNamed: string * ILType -> ILParameter -val mkILReturn: ILType -> ILReturn -val mkILLocal: ILType -> (string * int * int) option -> ILLocal - -/// Make a formal generic parameters. -val mkILEmptyGenericParams: ILGenericParameterDefs - -/// Make method definitions. -val mkILMethodBody: initlocals:bool * ILLocals * int * ILCode * ILSourceMarker option -> ILMethodBody -val mkMethodBody: bool * ILLocals * int * ILCode * ILSourceMarker option -> MethodBody -val methBodyNotAvailable: ILLazyMethodBody -val methBodyAbstract: ILLazyMethodBody -val methBodyNative: ILLazyMethodBody - -val mkILCtor: ILMemberAccess * ILParameter list * MethodBody -> ILMethodDef -val mkILClassCtor: MethodBody -> ILMethodDef -val mkILNonGenericEmptyCtor: ILSourceMarker option -> ILType -> ILMethodDef -val mkILStaticMethod: ILGenericParameterDefs * string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef -val mkILNonGenericStaticMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef -val mkILGenericVirtualMethod: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturn * MethodBody -> ILMethodDef -val mkILGenericNonVirtualMethod: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturn * MethodBody -> ILMethodDef -val mkILNonGenericVirtualMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef -val mkILNonGenericInstanceMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef - - -/// Make field definitions. -val mkILInstanceField: string * ILType * ILFieldInit option * ILMemberAccess -> ILFieldDef -val mkILStaticField: string * ILType * ILFieldInit option * byte[] option * ILMemberAccess -> ILFieldDef -val mkILLiteralField: string * ILType * ILFieldInit * byte[] option * ILMemberAccess -> ILFieldDef - -/// Make a type definition. -val mkILGenericClass: string * ILTypeDefAccess * ILGenericParameterDefs * ILType * ILType list * ILMethodDefs * ILFieldDefs * ILTypeDefs * ILPropertyDefs * ILEventDefs * ILAttributes * ILTypeInit -> ILTypeDef -val mkILSimpleClass: ILGlobals -> string * ILTypeDefAccess * ILMethodDefs * ILFieldDefs * ILTypeDefs * ILPropertyDefs * ILEventDefs * ILAttributes * ILTypeInit -> ILTypeDef -val mkILTypeDefForGlobalFunctions: ILGlobals -> ILMethodDefs * ILFieldDefs -> ILTypeDef - -/// Make a type definition for a value type used to point to raw data. -/// These are useful when generating array initialization code -/// according to the -/// ldtoken field valuetype ''/'$$struct0x6000127-1' ''::'$$method0x6000127-1' -/// call void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class System.Array,valuetype System.RuntimeFieldHandle) -/// idiom. -val mkRawDataValueTypeDef: ILType -> string * size:int32 * pack:uint16 -> ILTypeDef - -/// Injecting code into existing code blocks. A branch will -/// be added from the given instructions to the (unique) entry of -/// the code, and the first instruction will be the new entry -/// of the method. The instructions should be non-branching. - -val prependInstrsToCode: ILInstr list -> ILCode -> ILCode -val prependInstrsToMethod: ILInstr list -> ILMethodDef -> ILMethodDef - -/// Injecting initialization code into a class. -/// Add some code to the end of the .cctor for a type. Create a .cctor -/// if one doesn't exist already. -val prependInstrsToClassCtor: ILInstr list -> ILSourceMarker option -> ILTypeDef -> ILTypeDef - -/// Derived functions for making some simple constructors -val mkILStorageCtor: ILSourceMarker option * ILInstr list * ILType * (string * ILType) list * ILMemberAccess -> ILMethodDef -val mkILSimpleStorageCtor: ILSourceMarker option * ILTypeSpec option * ILType * ILParameter list * (string * ILType) list * ILMemberAccess -> ILMethodDef -val mkILSimpleStorageCtorWithParamNames: ILSourceMarker option * ILTypeSpec option * ILType * ILParameter list * (string * string * ILType) list * ILMemberAccess -> ILMethodDef - -val mkILDelegateMethods: ILMemberAccess -> ILGlobals -> ILType * ILType -> ILParameter list * ILReturn -> ILMethodDef list - -/// Given a delegate type definition which lies in a particular scope, -/// make a reference to its constructor. -val mkCtorMethSpecForDelegate: ILGlobals -> ILType * bool -> ILMethodSpec - -/// The toplevel "class" for a module or assembly. -val mkILTypeForGlobalFunctions: ILScopeRef -> ILType - -/// Making tables of custom attributes, etc. -val mkILCustomAttrs: ILAttribute list -> ILAttributes -val mkILCustomAttrsFromArray: ILAttribute[] -> ILAttributes -val storeILCustomAttrs: ILAttributes -> ILAttributesStored -val mkILCustomAttrsReader: (int32 -> ILAttribute[]) -> ILAttributesStored -val emptyILCustomAttrs: ILAttributes - -val mkILSecurityDecls: ILSecurityDecl list -> ILSecurityDecls -val emptyILSecurityDecls: ILSecurityDecls -val storeILSecurityDecls: ILSecurityDecls -> ILSecurityDeclsStored -val mkILSecurityDeclsReader: (int32 -> ILSecurityDecl[]) -> ILSecurityDeclsStored - -val mkMethBodyAux: MethodBody -> ILLazyMethodBody -val mkMethBodyLazyAux: Lazy -> ILLazyMethodBody - -val mkILEvents: ILEventDef list -> ILEventDefs -val mkILEventsLazy: Lazy -> ILEventDefs -val emptyILEvents: ILEventDefs - -val mkILProperties: ILPropertyDef list -> ILPropertyDefs -val mkILPropertiesLazy: Lazy -> ILPropertyDefs -val emptyILProperties: ILPropertyDefs - -val mkILMethods: ILMethodDef list -> ILMethodDefs -val mkILMethodsFromArray: ILMethodDef[] -> ILMethodDefs -val mkILMethodsComputed: (unit -> ILMethodDef[]) -> ILMethodDefs -val emptyILMethods: ILMethodDefs - -val mkILFields: ILFieldDef list -> ILFieldDefs -val mkILFieldsLazy: Lazy -> ILFieldDefs -val emptyILFields: ILFieldDefs - -val mkILMethodImpls: ILMethodImplDef list -> ILMethodImplDefs -val mkILMethodImplsLazy: Lazy -> ILMethodImplDefs -val emptyILMethodImpls: ILMethodImplDefs - -val mkILTypeDefs: ILTypeDef list -> ILTypeDefs -val mkILTypeDefsFromArray: ILTypeDef[] -> ILTypeDefs -val emptyILTypeDefs: ILTypeDefs - -/// Create table of types which is loaded/computed on-demand, and whose individual -/// elements are also loaded/computed on-demand. Any call to tdefs.AsList will -/// result in the laziness being forced. Operations can examine the -/// custom attributes and name of each type in order to decide whether -/// to proceed with examining the other details of the type. -/// -/// Note that individual type definitions may contain further delays -/// in their method, field and other tables. -val mkILTypeDefsComputed: (unit -> ILPreTypeDef[]) -> ILTypeDefs -val addILTypeDef: ILTypeDef -> ILTypeDefs -> ILTypeDefs - -val mkTypeForwarder: ILScopeRef -> string -> ILNestedExportedTypes -> ILAttributes -> ILTypeDefAccess -> ILExportedTypeOrForwarder -val mkILNestedExportedTypes: ILNestedExportedType list -> ILNestedExportedTypes -val mkILNestedExportedTypesLazy: Lazy -> ILNestedExportedTypes - -val mkILExportedTypes: ILExportedTypeOrForwarder list -> ILExportedTypesAndForwarders -val mkILExportedTypesLazy: Lazy -> ILExportedTypesAndForwarders - -val mkILResources: ILResource list -> ILResources - -/// Making modules. -val mkILSimpleModule: assemblyName:string -> moduleName:string -> dll:bool -> subsystemVersion: (int * int) -> useHighEntropyVA: bool -> ILTypeDefs -> int32 option -> string option -> int -> ILExportedTypesAndForwarders -> string -> ILModuleDef - -/// Generate references to existing type definitions, method definitions -/// etc. Useful for generating references, e.g. to a class we're processing -/// Also used to reference type definitions that we've generated. [ILScopeRef] -/// is normally ILScopeRef.Local, unless we've generated the ILTypeDef in -/// an auxiliary module or are generating multiple assemblies at -/// once. - -val mkRefForNestedILTypeDef: ILScopeRef -> ILTypeDef list * ILTypeDef -> ILTypeRef -val mkRefForILMethod : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILMethodDef -> ILMethodRef -val mkRefForILField : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILFieldDef -> ILFieldRef - -val mkRefToILMethod: ILTypeRef * ILMethodDef -> ILMethodRef -val mkRefToILField: ILTypeRef * ILFieldDef -> ILFieldRef - -val mkRefToILAssembly: ILAssemblyManifest -> ILAssemblyRef -val mkRefToILModule: ILModuleDef -> ILModuleRef - -val NoMetadataIdx: int32 - -// -------------------------------------------------------------------- -// Rescoping. -// -// Given an object O1 referenced from where1 (e.g. O1 binds to some -// result R when referenced from where1), and given that SR2 resolves to where1 from where2, -// produce a new O2 for use from where2 (e.g. O2 binds to R from where2) -// -// So, ILScopeRef tells you how to reference the original scope from -// the new scope. e.g. if ILScopeRef is: -// [ILScopeRef.Local] then the object is returned unchanged -// [ILScopeRef.Module m] then an object is returned -// where all ILScopeRef.Local references -// become ILScopeRef.Module m -// [ILScopeRef.Assembly m] then an object is returned -// where all ILScopeRef.Local and ILScopeRef.Module references -// become ILScopeRef.Assembly m -// -------------------------------------------------------------------- - -/// Rescoping. The first argument tells the function how to reference the original scope from -/// the new scope. -val rescopeILScopeRef: ILScopeRef -> ILScopeRef -> ILScopeRef - -/// Rescoping. The first argument tells the function how to reference the original scope from -/// the new scope. -val rescopeILTypeSpec: ILScopeRef -> ILTypeSpec -> ILTypeSpec - -/// Rescoping. The first argument tells the function how to reference the original scope from -/// the new scope. -val rescopeILType: ILScopeRef -> ILType -> ILType - -/// Rescoping. The first argument tells the function how to reference the original scope from -/// the new scope. -val rescopeILMethodRef: ILScopeRef -> ILMethodRef -> ILMethodRef - -/// Rescoping. The first argument tells the function how to reference the original scope from -/// the new scope. -val rescopeILFieldRef: ILScopeRef -> ILFieldRef -> ILFieldRef - -/// Unscoping. Clears every scope information, use for looking up IL method references only. -val unscopeILType: ILType -> ILType - -val buildILCode: string -> lab2pc: Dictionary -> instrs:ILInstr[] -> ILExceptionSpec list -> ILLocalDebugInfo list -> ILCode - -/// Instantiate type variables that occur within types and other items. -val instILTypeAux: int -> ILGenericArgs -> ILType -> ILType - -/// Instantiate type variables that occur within types and other items. -val instILType: ILGenericArgs -> ILType -> ILType - -/// This is a 'vendor neutral' way of referencing mscorlib. -val ecmaPublicKey: PublicKey - -/// Discriminating different important built-in types. -val isILObjectTy: ILGlobals -> ILType -> bool -val isILStringTy: ILGlobals -> ILType -> bool -val isILSByteTy: ILGlobals -> ILType -> bool -val isILByteTy: ILGlobals -> ILType -> bool -val isILInt16Ty: ILGlobals -> ILType -> bool -val isILUInt16Ty: ILGlobals -> ILType -> bool -val isILInt32Ty: ILGlobals -> ILType -> bool -val isILUInt32Ty: ILGlobals -> ILType -> bool -val isILInt64Ty: ILGlobals -> ILType -> bool -val isILUInt64Ty: ILGlobals -> ILType -> bool -val isILIntPtrTy: ILGlobals -> ILType -> bool -val isILUIntPtrTy: ILGlobals -> ILType -> bool -val isILBoolTy: ILGlobals -> ILType -> bool -val isILCharTy: ILGlobals -> ILType -> bool -val isILTypedReferenceTy: ILGlobals -> ILType -> bool -val isILDoubleTy: ILGlobals -> ILType -> bool -val isILSingleTy: ILGlobals -> ILType -> bool - -val sha1HashInt64 : byte[] -> int64 -/// Get a public key token from a public key. -val sha1HashBytes: byte[] -> byte[] (* SHA1 hash *) - -/// Get a version number from a CLR version string, e.g. 1.0.3705.0 -val parseILVersion: string -> ILVersionInfo -val formatILVersion: ILVersionInfo -> string -val compareILVersions: ILVersionInfo -> ILVersionInfo -> int - -/// Decompose a type definition according to its kind. -type ILEnumInfo = - { enumValues: (string * ILFieldInit) list - enumType: ILType } - -val getTyOfILEnumInfo: ILEnumInfo -> ILType - -val computeILEnumInfo: string * ILFieldDefs -> ILEnumInfo - -/// A utility type provided for completeness -[] -type ILEventRef = - static member Create: ILTypeRef * string -> ILEventRef - member DeclaringTypeRef: ILTypeRef - member Name: string - -/// A utility type provided for completeness -[] -type ILPropertyRef = - static member Create: ILTypeRef * string -> ILPropertyRef - member DeclaringTypeRef: ILTypeRef - member Name: string - interface System.IComparable - -val runningOnMono: bool - -type ILReferences = - { AssemblyReferences: ILAssemblyRef list - ModuleReferences: ILModuleRef list } - -/// Find the full set of assemblies referenced by a module. -val computeILRefs: ILGlobals -> ILModuleDef -> ILReferences -val emptyILRefs: ILReferences - diff --git a/src/absil/illib.fs b/src/absil/illib.fs deleted file mode 100644 index 33e0566a6c2..00000000000 --- a/src/absil/illib.fs +++ /dev/null @@ -1,1417 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module public FSharp.Compiler.AbstractIL.Internal.Library -#nowarn "1178" // The struct, record or union type 'internal_instr_extension' is not structurally comparable because the type - - -open System -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.Reflection -open System.Threading -open System.Runtime.CompilerServices - -// Logical shift right treating int32 as unsigned integer. -// Code that uses this should probably be adjusted to use unsigned integer types. -let (>>>&) (x: int32) (n: int32) = int32 (uint32 x >>> n) - -let notlazy v = Lazy<_>.CreateFromValue v - -let inline isNil l = List.isEmpty l - -/// Returns true if the list has less than 2 elements. Otherwise false. -let inline isNilOrSingleton l = - match l with - | [] - | [_] -> true - | _ -> false - -/// Returns true if the list contains exactly 1 element. Otherwise false. -let inline isSingleton l = - match l with - | [_] -> true - | _ -> false - -let inline isNonNull x = not (isNull x) - -let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x - -let inline (===) x y = LanguagePrimitives.PhysicalEquality x y - -/// Per the docs the threshold for the Large Object Heap is 85000 bytes: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap#how-an-object-ends-up-on-the-large-object-heap-and-how-gc-handles-them -/// We set the limit to be 80k to account for larger pointer sizes for when F# is running 64-bit. -let LOH_SIZE_THRESHOLD_BYTES = 80_000 - -//--------------------------------------------------------------------- -// Library: ReportTime -//--------------------------------------------------------------------- -let reportTime = - let mutable tFirst =None - let mutable tPrev = None - fun showTimes descr -> - if showTimes then - let t = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds - let prev = match tPrev with None -> 0.0 | Some t -> t - let first = match tFirst with None -> (tFirst <- Some t; t) | Some t -> t - printf "ilwrite: TIME %10.3f (total) %10.3f (delta) - %s\n" (t - first) (t - prev) descr - tPrev <- Some t - -//------------------------------------------------------------------------- -// Library: projections -//------------------------------------------------------------------------ - -[] -/// An efficient lazy for inline storage in a class type. Results in fewer thunks. -type InlineDelayInit<'T when 'T : not struct> = - new (f: unit -> 'T) = {store = Unchecked.defaultof<'T>; func = Func<_>(f) } - val mutable store : 'T - val mutable func : Func<'T> - - member x.Value = - match x.func with - | null -> x.store - | _ -> - let res = LazyInitializer.EnsureInitialized(&x.store, x.func) - x.func <- Unchecked.defaultof<_> - res - -//------------------------------------------------------------------------- -// Library: projections -//------------------------------------------------------------------------ - -let foldOn p f z x = f z (p x) - -let notFound() = raise (KeyNotFoundException()) - -module Order = - let orderBy (p : 'T -> 'U) = - { new IComparer<'T> with member __.Compare(x, xx) = compare (p x) (p xx) } - - let orderOn p (pxOrder: IComparer<'U>) = - { new IComparer<'T> with member __.Compare(x, xx) = pxOrder.Compare (p x, p xx) } - - let toFunction (pxOrder: IComparer<'U>) x y = pxOrder.Compare(x, y) - -//------------------------------------------------------------------------- -// Library: arrays, lists, options, resizearrays -//------------------------------------------------------------------------- - -module Array = - - let mapq f inp = - match inp with - | [| |] -> inp - | _ -> - let res = Array.map f inp - let len = inp.Length - let mutable eq = true - let mutable i = 0 - while eq && i < len do - if not (inp.[i] === res.[i]) then eq <- false - i <- i + 1 - if eq then inp else res - - let lengthsEqAndForall2 p l1 l2 = - Array.length l1 = Array.length l2 && - Array.forall2 p l1 l2 - - let order (eltOrder: IComparer<'T>) = - { new IComparer> with - member __.Compare(xs, ys) = - let c = compare xs.Length ys.Length - if c <> 0 then c else - let rec loop i = - if i >= xs.Length then 0 else - let c = eltOrder.Compare(xs.[i], ys.[i]) - if c <> 0 then c else - loop (i+1) - loop 0 } - - let existsOne p l = - let rec forallFrom p l n = - (n >= Array.length l) || (p l.[n] && forallFrom p l (n+1)) - - let rec loop p l n = - (n < Array.length l) && - (if p l.[n] then forallFrom (fun x -> not (p x)) l (n+1) else loop p l (n+1)) - - loop p l 0 - - let existsTrue (arr: bool[]) = - let rec loop n = (n < arr.Length) && (arr.[n] || loop (n+1)) - loop 0 - - let findFirstIndexWhereTrue (arr: _[]) p = - let rec look lo hi = - assert ((lo >= 0) && (hi >= 0)) - assert ((lo <= arr.Length) && (hi <= arr.Length)) - if lo = hi then lo - else - let i = (lo+hi)/2 - if p arr.[i] then - if i = 0 then i - else - if p arr.[i-1] then - look lo i - else - i - else - // not true here, look after - look (i+1) hi - look 0 arr.Length - - /// pass an array byref to reverse it in place - let revInPlace (array: 'T []) = - if Array.isEmpty array then () else - let arrLen, revLen = array.Length-1, array.Length/2 - 1 - for idx in 0 .. revLen do - let t1 = array.[idx] - let t2 = array.[arrLen-idx] - array.[idx] <- t2 - array.[arrLen-idx] <- t1 - - /// Async implementation of Array.map. - let mapAsync (mapping : 'T -> Async<'U>) (array : 'T[]) : Async<'U[]> = - let len = Array.length array - let result = Array.zeroCreate len - - async { // Apply the mapping function to each array element. - for i in 0 .. len - 1 do - let! mappedValue = mapping array.[i] - result.[i] <- mappedValue - - // Return the completed results. - return result - } - - /// Returns a new array with an element replaced with a given value. - let replace index value (array: _ []) = - if index >= array.Length then raise (IndexOutOfRangeException "index") - let res = Array.copy array - res.[index] <- value - res - - /// Optimized arrays equality. ~100x faster than `array1 = array2` on strings. - /// ~2x faster for floats - /// ~0.8x slower for ints - let inline areEqual (xs: 'T []) (ys: 'T []) = - match xs, ys with - | null, null -> true - | [||], [||] -> true - | null, _ | _, null -> false - | _ when xs.Length <> ys.Length -> false - | _ -> - let mutable break' = false - let mutable i = 0 - let mutable result = true - while i < xs.Length && not break' do - if xs.[i] <> ys.[i] then - break' <- true - result <- false - i <- i + 1 - result - - /// Returns all heads of a given array. - /// For [|1;2;3|] it returns [|[|1; 2; 3|]; [|1; 2|]; [|1|]|] - let heads (array: 'T []) = - let res = Array.zeroCreate<'T[]> array.Length - for i = array.Length - 1 downto 0 do - res.[i] <- array.[0..i] - res - - /// check if subArray is found in the wholeArray starting - /// at the provided index - let inline isSubArray (subArray: 'T []) (wholeArray:'T []) index = - if isNull subArray || isNull wholeArray then false - elif subArray.Length = 0 then true - elif subArray.Length > wholeArray.Length then false - elif subArray.Length = wholeArray.Length then areEqual subArray wholeArray else - let rec loop subidx idx = - if subidx = subArray.Length then true - elif subArray.[subidx] = wholeArray.[idx] then loop (subidx+1) (idx+1) - else false - loop 0 index - - /// Returns true if one array has another as its subset from index 0. - let startsWith (prefix: _ []) (whole: _ []) = - isSubArray prefix whole 0 - - /// Returns true if one array has trailing elements equal to another's. - let endsWith (suffix: _ []) (whole: _ []) = - isSubArray suffix whole (whole.Length-suffix.Length) - -module Option = - - let mapFold f s opt = - match opt with - | None -> None, s - | Some x -> - let x2, s2 = f s x - Some x2, s2 - - let attempt (f: unit -> 'T) = try Some (f()) with _ -> None - -module List = - - let sortWithOrder (c: IComparer<'T>) elements = List.sortWith (Order.toFunction c) elements - - let splitAfter n l = - let rec split_after_acc n l1 l2 = if n <= 0 then List.rev l1, l2 else split_after_acc (n-1) ((List.head l2) :: l1) (List.tail l2) - split_after_acc n [] l - - let existsi f xs = - let rec loop i xs = match xs with [] -> false | h :: t -> f i h || loop (i+1) t - loop 0 xs - - let existsTrue (xs: bool list) = - let rec loop i xs = match xs with [] -> false | h :: t -> h || loop (i+1) t - loop 0 xs - - let lengthsEqAndForall2 p l1 l2 = - List.length l1 = List.length l2 && - List.forall2 p l1 l2 - - let rec findi n f l = - match l with - | [] -> None - | h :: t -> if f h then Some (h, n) else findi (n+1) f t - - let rec drop n l = - match l with - | [] -> [] - | _ :: xs -> if n=0 then l else drop (n-1) xs - - let splitChoose select l = - let rec ch acc1 acc2 l = - match l with - | [] -> List.rev acc1, List.rev acc2 - | x :: xs -> - match select x with - | Choice1Of2 sx -> ch (sx :: acc1) acc2 xs - | Choice2Of2 sx -> ch acc1 (sx :: acc2) xs - - ch [] [] l - - let rec checkq l1 l2 = - match l1, l2 with - | h1 :: t1, h2 :: t2 -> h1 === h2 && checkq t1 t2 - | _ -> true - - let mapq (f: 'T -> 'T) inp = - assert not (typeof<'T>.IsValueType) - match inp with - | [] -> inp - | [h1a] -> - let h2a = f h1a - if h1a === h2a then inp else [h2a] - | [h1a; h1b] -> - let h2a = f h1a - let h2b = f h1b - if h1a === h2a && h1b === h2b then inp else [h2a; h2b] - | [h1a; h1b; h1c] -> - let h2a = f h1a - let h2b = f h1b - let h2c = f h1c - if h1a === h2a && h1b === h2b && h1c === h2c then inp else [h2a; h2b; h2c] - | _ -> - let res = List.map f inp - if checkq inp res then inp else res - - let frontAndBack l = - let rec loop acc l = - match l with - | [] -> - Debug.Assert(false, "empty list") - invalidArg "l" "empty list" - | [h] -> List.rev acc, h - | h :: t -> loop (h :: acc) t - loop [] l - - let tryRemove f inp = - let rec loop acc l = - match l with - | [] -> None - | h :: t -> if f h then Some (h, List.rev acc @ t) else loop (h :: acc) t - loop [] inp - - let headAndTail l = - match l with - | [] -> - Debug.Assert(false, "empty list") - failwith "List.headAndTail" - | h :: t -> h, t - - let zip4 l1 l2 l3 l4 = - List.zip l1 (List.zip3 l2 l3 l4) |> List.map (fun (x1, (x2, x3, x4)) -> (x1, x2, x3, x4)) - - let unzip4 l = - let a, b, cd = List.unzip3 (List.map (fun (x, y, z, w) -> (x, y, (z, w))) l) - let c, d = List.unzip cd - a, b, c, d - - let rec iter3 f l1 l2 l3 = - match l1, l2, l3 with - | h1 :: t1, h2 :: t2, h3 :: t3 -> f h1 h2 h3; iter3 f t1 t2 t3 - | [], [], [] -> () - | _ -> failwith "iter3" - - let takeUntil p l = - let rec loop acc l = - match l with - | [] -> List.rev acc, [] - | x :: xs -> if p x then List.rev acc, l else loop (x :: acc) xs - loop [] l - - let order (eltOrder: IComparer<'T>) = - { new IComparer> with - member __.Compare(xs, ys) = - let rec loop xs ys = - match xs, ys with - | [], [] -> 0 - | [], _ -> -1 - | _, [] -> 1 - | x :: xs, y :: ys -> - let cxy = eltOrder.Compare(x, y) - if cxy=0 then loop xs ys else cxy - loop xs ys } - - module FrontAndBack = - let (|NonEmpty|Empty|) l = match l with [] -> Empty | _ -> NonEmpty(frontAndBack l) - - let range n m = [ n .. m ] - - let indexNotFound() = raise (new KeyNotFoundException("An index satisfying the predicate was not found in the collection")) - - let rec assoc x l = - match l with - | [] -> indexNotFound() - | ((h, r) :: t) -> if x = h then r else assoc x t - - let rec memAssoc x l = - match l with - | [] -> false - | ((h, _) :: t) -> x = h || memAssoc x t - - let rec memq x l = - match l with - | [] -> false - | h :: t -> LanguagePrimitives.PhysicalEquality x h || memq x t - - let mapNth n f xs = - let rec mn i = function - | [] -> [] - | x :: xs -> if i=n then f x :: xs else x :: mn (i+1) xs - - mn 0 xs - let count pred xs = List.fold (fun n x -> if pred x then n+1 else n) 0 xs - - // WARNING: not tail-recursive - let mapHeadTail fhead ftail = function - | [] -> [] - | [x] -> [fhead x] - | x :: xs -> fhead x :: List.map ftail xs - - let collectFold f s l = - let l, s = List.mapFold f s l - List.concat l, s - - let collect2 f xs ys = List.concat (List.map2 f xs ys) - - let toArraySquared xss = xss |> List.map List.toArray |> List.toArray - - let iterSquared f xss = xss |> List.iter (List.iter f) - - let collectSquared f xss = xss |> List.collect (List.collect f) - - let mapSquared f xss = xss |> List.map (List.map f) - - let mapFoldSquared f z xss = List.mapFold (List.mapFold f) z xss - - let forallSquared f xss = xss |> List.forall (List.forall f) - - let mapiSquared f xss = xss |> List.mapi (fun i xs -> xs |> List.mapi (fun j x -> f i j x)) - - let existsSquared f xss = xss |> List.exists (fun xs -> xs |> List.exists (fun x -> f x)) - - let mapiFoldSquared f z xss = mapFoldSquared f z (xss |> mapiSquared (fun i j x -> (i, j, x))) - -module ResizeArray = - - /// Split a ResizeArray into an array of smaller chunks. - /// This requires `items/chunkSize` Array copies of length `chunkSize` if `items/chunkSize % 0 = 0`, - /// otherwise `items/chunkSize + 1` Array copies. - let chunkBySize chunkSize f (items: ResizeArray<'t>) = - // we could use Seq.chunkBySize here, but that would involve many enumerator.MoveNext() calls that we can sidestep with a bit of math - let itemCount = items.Count - if itemCount = 0 - then [||] - else - let chunksCount = - match itemCount / chunkSize with - | n when itemCount % chunkSize = 0 -> n - | n -> n + 1 // any remainder means we need an additional chunk to store it - - [| for index in 0..chunksCount-1 do - let startIndex = index * chunkSize - let takeCount = min (itemCount - startIndex) chunkSize - - let holder = Array.zeroCreate takeCount - // we take a bounds-check hit here on each access. - // other alternatives here include - // * iterating across an IEnumerator (incurs MoveNext penalty) - // * doing a block copy using `List.CopyTo(index, array, index, count)` (requires more copies to do the mapping) - // none are significantly better. - for i in 0 .. takeCount - 1 do - holder.[i] <- f items.[i] - yield holder |] - - /// Split a large ResizeArray into a series of array chunks that are each under the Large Object Heap limit. - /// This is done to help prevent a stop-the-world collection of the single large array, instead allowing for a greater - /// probability of smaller collections. Stop-the-world is still possible, just less likely. - let mapToSmallArrayChunks f (inp: ResizeArray<'t>) = - let itemSizeBytes = sizeof<'t> - // rounding down here is good because it ensures we don't go over - let maxArrayItemCount = LOH_SIZE_THRESHOLD_BYTES / itemSizeBytes - - /// chunk the provided input into arrays that are smaller than the LOH limit - /// in order to prevent long-term storage of those values - chunkBySize maxArrayItemCount f inp - -module ValueOptionInternal = - - let inline ofOption x = match x with Some x -> ValueSome x | None -> ValueNone - - let inline bind f x = match x with ValueSome x -> f x | ValueNone -> ValueNone - -type String with - member inline x.StartsWithOrdinal value = - x.StartsWith(value, StringComparison.Ordinal) - - member inline x.EndsWithOrdinal value = - x.EndsWith(value, StringComparison.Ordinal) - -module String = - let make (n: int) (c: char) : string = new String(c, n) - - let get (str: string) i = str.[i] - - let sub (s: string) (start: int) (len: int) = s.Substring(start, len) - - let contains (s: string) (c: char) = s.IndexOf c <> -1 - - let order = LanguagePrimitives.FastGenericComparer - - let lowercase (s: string) = - s.ToLowerInvariant() - - let uppercase (s: string) = - s.ToUpperInvariant() - - let isUpper (s: string) = - s.Length >= 1 && Char.IsUpper s.[0] && not (Char.IsLower s.[0]) - - let capitalize (s: string) = - if s.Length = 0 then s - else uppercase s.[0..0] + s.[ 1.. s.Length - 1 ] - - let uncapitalize (s: string) = - if s.Length = 0 then s - else lowercase s.[0..0] + s.[ 1.. s.Length - 1 ] - - let dropPrefix (s: string) (t: string) = s.[t.Length..s.Length - 1] - - let dropSuffix (s: string) (t: string) = s.[0..s.Length - t.Length - 1] - - let inline toCharArray (str: string) = str.ToCharArray() - - let lowerCaseFirstChar (str: string) = - if String.IsNullOrEmpty str - || Char.IsLower(str, 0) then str else - let strArr = toCharArray str - match Array.tryHead strArr with - | None -> str - | Some c -> - strArr.[0] <- Char.ToLower c - String strArr - - let extractTrailingIndex (str: string) = - match str with - | null -> null, None - | _ -> - let charr = str.ToCharArray() - Array.revInPlace charr - let digits = Array.takeWhile Char.IsDigit charr - Array.revInPlace digits - String digits - |> function - | "" -> str, None - | index -> str.Substring (0, str.Length - index.Length), Some (int index) - - /// Remove all trailing and leading whitespace from the string - /// return null if the string is null - let trim (value: string) = if isNull value then null else value.Trim() - - /// Splits a string into substrings based on the strings in the array separators - let split options (separator: string []) (value: string) = - if isNull value then null else value.Split(separator, options) - - let (|StartsWith|_|) pattern value = - if String.IsNullOrWhiteSpace value then - None - elif value.StartsWithOrdinal pattern then - Some() - else None - - let (|Contains|_|) pattern value = - if String.IsNullOrWhiteSpace value then - None - elif value.Contains pattern then - Some() - else None - - let getLines (str: string) = - use reader = new StringReader(str) - [| - let mutable line = reader.ReadLine() - while not (isNull line) do - yield line - line <- reader.ReadLine() - if str.EndsWithOrdinal("\n") then - // last trailing space not returned - // http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak - yield String.Empty - |] - -module Dictionary = - let inline newWithSize (size: int) = Dictionary<_, _>(size, HashIdentity.Structural) - -[] -type DictionaryExtensions() = - - [] - static member inline BagAdd(dic: Dictionary<'key, 'value list>, key: 'key, value: 'value) = - match dic.TryGetValue key with - | true, values -> dic.[key] <- value :: values - | _ -> dic.[key] <- [value] - - [] - static member inline BagExistsValueForKey(dic: Dictionary<'key, 'value list>, key: 'key, f: 'value -> bool) = - match dic.TryGetValue key with - | true, values -> values |> List.exists f - | _ -> false - -module Lazy = - let force (x: Lazy<'T>) = x.Force() - -//---------------------------------------------------------------------------- -// Single threaded execution and mutual exclusion - -/// Represents a permission active at this point in execution -type ExecutionToken = interface end - -/// Represents a token that indicates execution on the compilation thread, i.e. -/// - we have full access to the (partially mutable) TAST and TcImports data structures -/// - compiler execution may result in type provider invocations when resolving types and members -/// - we can access various caches in the SourceCodeServices -/// -/// Like other execution tokens this should be passed via argument passing and not captured/stored beyond -/// the lifetime of stack-based calls. This is not checked, it is a discipline within the compiler code. -type CompilationThreadToken() = interface ExecutionToken - -/// Represents a place where we are stating that execution on the compilation thread is required. The -/// reason why will be documented in a comment in the code at the callsite. -let RequireCompilationThread (_ctok: CompilationThreadToken) = () - -/// Represents a place in the compiler codebase where we are passed a CompilationThreadToken unnecessarily. -/// This represents code that may potentially not need to be executed on the compilation thread. -let DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent (_ctok: CompilationThreadToken) = () - -/// Represents a place in the compiler codebase where we assume we are executing on a compilation thread -let AssumeCompilationThreadWithoutEvidence () = Unchecked.defaultof - -/// Represents a token that indicates execution on a any of several potential user threads calling the F# compiler services. -type AnyCallerThreadToken() = interface ExecutionToken -let AssumeAnyCallerThreadWithoutEvidence () = Unchecked.defaultof - -/// A base type for various types of tokens that must be passed when a lock is taken. -/// Each different static lock should declare a new subtype of this type. -type LockToken = inherit ExecutionToken -let AssumeLockWithoutEvidence<'LockTokenType when 'LockTokenType :> LockToken> () = Unchecked.defaultof<'LockTokenType> - -/// Encapsulates a lock associated with a particular token-type representing the acquisition of that lock. -type Lock<'LockTokenType when 'LockTokenType :> LockToken>() = - let lockObj = obj() - member __.AcquireLock f = lock lockObj (fun () -> f (AssumeLockWithoutEvidence<'LockTokenType>())) - -//--------------------------------------------------- -// Misc - -/// Get an initialization hole -let getHole r = match !r with None -> failwith "getHole" | Some x -> x - -module Map = - let tryFindMulti k map = match Map.tryFind k map with Some res -> res | None -> [] - -type ResultOrException<'TResult> = - | Result of 'TResult - | Exception of Exception - -[] -module ResultOrException = - - let success a = Result a - - let raze (b: exn) = Exception b - - // map - let (|?>) res f = - match res with - | Result x -> Result(f x ) - | Exception err -> Exception err - - let ForceRaise res = - match res with - | Result x -> x - | Exception err -> raise err - - let otherwise f x = - match x with - | Result x -> success x - | Exception _err -> f() - -[] -type ValueOrCancelled<'TResult> = - | Value of 'TResult - | Cancelled of OperationCanceledException - -/// Represents a cancellable computation with explicit representation of a cancelled result. -/// -/// A cancellable computation is passed may be cancelled via a CancellationToken, which is propagated implicitly. -/// If cancellation occurs, it is propagated as data rather than by raising an OperationCanceledException. -type Cancellable<'TResult> = Cancellable of (CancellationToken -> ValueOrCancelled<'TResult>) - -[] -module Cancellable = - - /// Run a cancellable computation using the given cancellation token - let run (ct: CancellationToken) (Cancellable oper) = - if ct.IsCancellationRequested then - ValueOrCancelled.Cancelled (OperationCanceledException ct) - else - oper ct - - /// Bind the result of a cancellable computation - let bind f comp1 = - Cancellable (fun ct -> - match run ct comp1 with - | ValueOrCancelled.Value v1 -> run ct (f v1) - | ValueOrCancelled.Cancelled err1 -> ValueOrCancelled.Cancelled err1) - - /// Map the result of a cancellable computation - let map f oper = - Cancellable (fun ct -> - match run ct oper with - | ValueOrCancelled.Value res -> ValueOrCancelled.Value (f res) - | ValueOrCancelled.Cancelled err -> ValueOrCancelled.Cancelled err) - - /// Return a simple value as the result of a cancellable computation - let ret x = Cancellable (fun _ -> ValueOrCancelled.Value x) - - /// Fold a cancellable computation along a sequence of inputs - let fold f acc seq = - Cancellable (fun ct -> - (ValueOrCancelled.Value acc, seq) - ||> Seq.fold (fun acc x -> - match acc with - | ValueOrCancelled.Value accv -> run ct (f accv x) - | res -> res)) - - /// Iterate a cancellable computation over a collection - let each f seq = - Cancellable (fun ct -> - (ValueOrCancelled.Value [], seq) - ||> Seq.fold (fun acc x -> - match acc with - | ValueOrCancelled.Value acc -> - match run ct (f x) with - | ValueOrCancelled.Value x2 -> ValueOrCancelled.Value (x2 :: acc) - | ValueOrCancelled.Cancelled err1 -> ValueOrCancelled.Cancelled err1 - | canc -> canc) - |> function - | ValueOrCancelled.Value acc -> ValueOrCancelled.Value (List.rev acc) - | canc -> canc) - - /// Delay a cancellable computation - let delay (f: unit -> Cancellable<'T>) = Cancellable (fun ct -> let (Cancellable g) = f() in g ct) - - /// Run the computation in a mode where it may not be cancelled. The computation never results in a - /// ValueOrCancelled.Cancelled. - let runWithoutCancellation comp = - let res = run CancellationToken.None comp - match res with - | ValueOrCancelled.Cancelled _ -> failwith "unexpected cancellation" - | ValueOrCancelled.Value r -> r - - /// Bind the cancellation token associated with the computation - let token () = Cancellable (fun ct -> ValueOrCancelled.Value ct) - - /// Represents a canceled computation - let canceled() = Cancellable (fun ct -> ValueOrCancelled.Cancelled (OperationCanceledException ct)) - - /// Catch exceptions in a computation - let private catch (Cancellable e) = - Cancellable (fun ct -> - try - match e ct with - | ValueOrCancelled.Value r -> ValueOrCancelled.Value (Choice1Of2 r) - | ValueOrCancelled.Cancelled e -> ValueOrCancelled.Cancelled e - with err -> - ValueOrCancelled.Value (Choice2Of2 err)) - - /// Implement try/finally for a cancellable computation - let tryFinally e compensation = - catch e |> bind (fun res -> - compensation() - match res with Choice1Of2 r -> ret r | Choice2Of2 err -> raise err) - - /// Implement try/with for a cancellable computation - let tryWith e handler = - catch e |> bind (fun res -> - match res with Choice1Of2 r -> ret r | Choice2Of2 err -> handler err) - - // Run the cancellable computation within an Async computation. This isn't actually used in the codebase, but left - // here in case we need it in the future - // - // let toAsync e = - // async { - // let! ct = Async.CancellationToken - // return! - // Async.FromContinuations(fun (cont, econt, ccont) -> - // // Run the computation synchronously using the given cancellation token - // let res = try Choice1Of2 (run ct e) with err -> Choice2Of2 err - // match res with - // | Choice1Of2 (ValueOrCancelled.Value v) -> cont v - // | Choice1Of2 (ValueOrCancelled.Cancelled err) -> ccont err - // | Choice2Of2 err -> econt err) - // } - -type CancellableBuilder() = - - member x.Bind(e, k) = Cancellable.bind k e - - member x.Return v = Cancellable.ret v - - member x.ReturnFrom v = v - - member x.Combine(e1, e2) = e1 |> Cancellable.bind (fun () -> e2) - - member x.TryWith(e, handler) = Cancellable.tryWith e handler - - member x.Using(resource, e) = Cancellable.tryFinally (e resource) (fun () -> (resource :> IDisposable).Dispose()) - - member x.TryFinally(e, compensation) = Cancellable.tryFinally e compensation - - member x.Delay f = Cancellable.delay f - - member x.Zero() = Cancellable.ret () - -let cancellable = CancellableBuilder() - -/// Computations that can cooperatively yield by returning a continuation -/// -/// - Any yield of a NotYetDone should typically be "abandonable" without adverse consequences. No resource release -/// will be called when the computation is abandoned. -/// -/// - Computations suspend via a NotYetDone may use local state (mutables), where these are -/// captured by the NotYetDone closure. Computations do not need to be restartable. -/// -/// - The key thing is that you can take an Eventually value and run it with -/// Eventually.repeatedlyProgressUntilDoneOrTimeShareOverOrCanceled -/// -/// - Cancellation results in a suspended computation rather than complete abandonment -type Eventually<'T> = - | Done of 'T - | NotYetDone of (CompilationThreadToken -> Eventually<'T>) - -[] -module Eventually = - - let rec box e = - match e with - | Done x -> Done (Operators.box x) - | NotYetDone work -> NotYetDone (fun ctok -> box (work ctok)) - - let rec forceWhile ctok check e = - match e with - | Done x -> Some x - | NotYetDone work -> - if not(check()) - then None - else forceWhile ctok check (work ctok) - - let force ctok e = Option.get (forceWhile ctok (fun () -> true) e) - - /// Keep running the computation bit by bit until a time limit is reached. - /// The runner gets called each time the computation is restarted - /// - /// If cancellation happens, the operation is left half-complete, ready to resume. - let repeatedlyProgressUntilDoneOrTimeShareOverOrCanceled timeShareInMilliseconds (ct: CancellationToken) runner e = - let sw = new Stopwatch() - let rec runTimeShare ctok e = - runner ctok (fun ctok -> - sw.Reset() - sw.Start() - let rec loop ctok ev2 = - match ev2 with - | Done _ -> ev2 - | NotYetDone work -> - if ct.IsCancellationRequested || sw.ElapsedMilliseconds > timeShareInMilliseconds then - sw.Stop() - NotYetDone(fun ctok -> runTimeShare ctok ev2) - else - loop ctok (work ctok) - loop ctok e) - NotYetDone (fun ctok -> runTimeShare ctok e) - - /// Keep running the asynchronous computation bit by bit. The runner gets called each time the computation is restarted. - /// Can be cancelled as an Async in the normal way. - let forceAsync (runner: (CompilationThreadToken -> Eventually<'T>) -> Async>) (e: Eventually<'T>) : Async<'T option> = - let rec loop (e: Eventually<'T>) = - async { - match e with - | Done x -> return Some x - | NotYetDone work -> - let! r = runner work - return! loop r - } - loop e - - let rec bind k e = - match e with - | Done x -> k x - | NotYetDone work -> NotYetDone (fun ctok -> bind k (work ctok)) - - let fold f acc seq = - (Done acc, seq) ||> Seq.fold (fun acc x -> acc |> bind (fun acc -> f acc x)) - - let rec catch e = - match e with - | Done x -> Done(Result x) - | NotYetDone work -> - NotYetDone (fun ctok -> - let res = try Result(work ctok) with | e -> Exception e - match res with - | Result cont -> catch cont - | Exception e -> Done(Exception e)) - - let delay (f: unit -> Eventually<'T>) = NotYetDone (fun _ctok -> f()) - - let tryFinally e compensation = - catch e - |> bind (fun res -> - compensation() - match res with - | Result v -> Eventually.Done v - | Exception e -> raise e) - - let tryWith e handler = - catch e - |> bind (function Result v -> Done v | Exception e -> handler e) - - // All eventually computations carry a CompilationThreadToken - let token = - NotYetDone (fun ctok -> Done ctok) - -type EventuallyBuilder() = - - member x.Bind(e, k) = Eventually.bind k e - - member x.Return v = Eventually.Done v - - member x.ReturnFrom v = v - - member x.Combine(e1, e2) = e1 |> Eventually.bind (fun () -> e2) - - member x.TryWith(e, handler) = Eventually.tryWith e handler - - member x.TryFinally(e, compensation) = Eventually.tryFinally e compensation - - member x.Delay f = Eventually.delay f - - member x.Zero() = Eventually.Done () - -let eventually = new EventuallyBuilder() - -(* -let _ = eventually { return 1 } -let _ = eventually { let x = 1 in return 1 } -let _ = eventually { let! x = eventually { return 1 } in return 1 } -let _ = eventually { try return (failwith "") with _ -> return 1 } -let _ = eventually { use x = null in return 1 } -*) - -/// Generates unique stamps -type UniqueStampGenerator<'T when 'T : equality>() = - let encodeTab = new Dictionary<'T, int>(HashIdentity.Structural) - let mutable nItems = 0 - let encode str = - match encodeTab.TryGetValue str with - | true, idx -> idx - | _ -> - let idx = nItems - encodeTab.[str] <- idx - nItems <- nItems + 1 - idx - - member this.Encode str = encode str - - member this.Table = encodeTab.Keys - -/// memoize tables (all entries cached, never collected) -type MemoizationTable<'T, 'U>(compute: 'T -> 'U, keyComparer: IEqualityComparer<'T>, ?canMemoize) = - - let table = new Dictionary<'T, 'U>(keyComparer) - - member t.Apply x = - if (match canMemoize with None -> true | Some f -> f x) then - match table.TryGetValue x with - | true, res -> res - | _ -> - lock table (fun () -> - match table.TryGetValue x with - | true, res -> res - | _ -> - let res = compute x - table.[x] <- res - res) - else compute x - - -exception UndefinedException - -type LazyWithContextFailure(exn: exn) = - - static let undefined = new LazyWithContextFailure(UndefinedException) - - member x.Exception = exn - - static member Undefined = undefined - -/// Just like "Lazy" but EVERY forcer must provide an instance of "ctxt", e.g. to help track errors -/// on forcing back to at least one sensible user location -[] -[] -type LazyWithContext<'T, 'ctxt> = - { /// This field holds the result of a successful computation. It's initial value is Unchecked.defaultof - mutable value : 'T - - /// This field holds either the function to run or a LazyWithContextFailure object recording the exception raised - /// from running the function. It is null if the thunk has been evaluated successfully. - mutable funcOrException: obj - - /// A helper to ensure we rethrow the "original" exception - findOriginalException : exn -> exn } - - static member Create(f: ('ctxt->'T), findOriginalException) : LazyWithContext<'T, 'ctxt> = - { value = Unchecked.defaultof<'T> - funcOrException = box f - findOriginalException = findOriginalException } - - static member NotLazy(x:'T) : LazyWithContext<'T, 'ctxt> = - { value = x - funcOrException = null - findOriginalException = id } - - member x.IsDelayed = (match x.funcOrException with null -> false | :? LazyWithContextFailure -> false | _ -> true) - - member x.IsForced = (match x.funcOrException with null -> true | _ -> false) - - member x.Force(ctxt:'ctxt) = - match x.funcOrException with - | null -> x.value - | _ -> - // Enter the lock in case another thread is in the process of evaluating the result - Monitor.Enter x; - try - x.UnsynchronizedForce ctxt - finally - Monitor.Exit x - - member x.UnsynchronizedForce ctxt = - match x.funcOrException with - | null -> x.value - | :? LazyWithContextFailure as res -> - // Re-raise the original exception - raise (x.findOriginalException res.Exception) - | :? ('ctxt -> 'T) as f -> - x.funcOrException <- box(LazyWithContextFailure.Undefined) - try - let res = f ctxt - x.value <- res - x.funcOrException <- null - res - with e -> - x.funcOrException <- box(new LazyWithContextFailure(e)) - reraise() - | _ -> - failwith "unreachable" - -/// Intern tables to save space. -module Tables = - let memoize f = - let t = new Dictionary<_, _>(1000, HashIdentity.Structural) - fun x -> - match t.TryGetValue x with - | true, res -> res - | _ -> - let res = f x - t.[x] <- res - res - -/// Interface that defines methods for comparing objects using partial equality relation -type IPartialEqualityComparer<'T> = - inherit IEqualityComparer<'T> - /// Can the specified object be tested for equality? - abstract InEqualityRelation : 'T -> bool - -module IPartialEqualityComparer = - - let On f (c: IPartialEqualityComparer<_>) = - { new IPartialEqualityComparer<_> with - member __.InEqualityRelation x = c.InEqualityRelation (f x) - member __.Equals(x, y) = c.Equals(f x, f y) - member __.GetHashCode x = c.GetHashCode(f x) } - - // Wrapper type for use by the 'partialDistinctBy' function - [] - type private WrapType<'T> = Wrap of 'T - - // Like Seq.distinctBy but only filters out duplicates for some of the elements - let partialDistinctBy (per: IPartialEqualityComparer<'T>) seq = - let wper = - { new IPartialEqualityComparer> with - member __.InEqualityRelation (Wrap x) = per.InEqualityRelation x - member __.Equals(Wrap x, Wrap y) = per.Equals(x, y) - member __.GetHashCode (Wrap x) = per.GetHashCode x } - // Wrap a Wrap _ around all keys in case the key type is itself a type using null as a representation - let dict = Dictionary, obj>(wper) - seq |> List.filter (fun v -> - let key = Wrap v - if (per.InEqualityRelation v) then - if dict.ContainsKey key then false else (dict.[key] <- null; true) - else true) - -//------------------------------------------------------------------------- -// Library: Name maps -//------------------------------------------------------------------------ - -type NameMap<'T> = Map - -type NameMultiMap<'T> = NameMap<'T list> - -type MultiMap<'T, 'U when 'T : comparison> = Map<'T, 'U list> - -[] -module NameMap = - - let empty = Map.empty - - let range m = List.rev (Map.foldBack (fun _ x sofar -> x :: sofar) m []) - - let foldBack f (m: NameMap<'T>) z = Map.foldBack f m z - - let forall f m = Map.foldBack (fun x y sofar -> sofar && f x y) m true - - let exists f m = Map.foldBack (fun x y sofar -> sofar || f x y) m false - - let ofKeyedList f l = List.foldBack (fun x acc -> Map.add (f x) x acc) l Map.empty - - let ofList l : NameMap<'T> = Map.ofList l - - let ofSeq l : NameMap<'T> = Map.ofSeq l - - let toList (l: NameMap<'T>) = Map.toList l - - let layer (m1 : NameMap<'T>) m2 = Map.foldBack Map.add m1 m2 - - /// Not a very useful function - only called in one place - should be changed - let layerAdditive addf m1 m2 = - Map.foldBack (fun x y sofar -> Map.add x (addf (Map.tryFindMulti x sofar) y) sofar) m1 m2 - - /// Union entries by identical key, using the provided function to union sets of values - let union unionf (ms: NameMap<_> seq) = - seq { for m in ms do yield! m } - |> Seq.groupBy (fun (KeyValue(k, _v)) -> k) - |> Seq.map (fun (k, es) -> (k, unionf (Seq.map (fun (KeyValue(_k, v)) -> v) es))) - |> Map.ofSeq - - /// For every entry in m2 find an entry in m1 and fold - let subfold2 errf f m1 m2 acc = - Map.foldBack (fun n x2 acc -> try f n (Map.find n m1) x2 acc with :? KeyNotFoundException -> errf n x2) m2 acc - - let suball2 errf p m1 m2 = subfold2 errf (fun _ x1 x2 acc -> p x1 x2 && acc) m1 m2 true - - let mapFold f s (l: NameMap<'T>) = - Map.foldBack (fun x y (l2, sx) -> let y2, sy = f sx x y in Map.add x y2 l2, sy) l (Map.empty, s) - - let foldBackRange f (l: NameMap<'T>) acc = Map.foldBack (fun _ y acc -> f y acc) l acc - - let filterRange f (l: NameMap<'T>) = Map.foldBack (fun x y acc -> if f y then Map.add x y acc else acc) l Map.empty - - let mapFilter f (l: NameMap<'T>) = Map.foldBack (fun x y acc -> match f y with None -> acc | Some y' -> Map.add x y' acc) l Map.empty - - let map f (l : NameMap<'T>) = Map.map (fun _ x -> f x) l - - let iter f (l : NameMap<'T>) = Map.iter (fun _k v -> f v) l - - let partition f (l : NameMap<'T>) = Map.filter (fun _ x-> f x) l, Map.filter (fun _ x -> not (f x)) l - - let mem v (m: NameMap<'T>) = Map.containsKey v m - - let find v (m: NameMap<'T>) = Map.find v m - - let tryFind v (m: NameMap<'T>) = Map.tryFind v m - - let add v x (m: NameMap<'T>) = Map.add v x m - - let isEmpty (m: NameMap<'T>) = (Map.isEmpty m) - - let existsInRange p m = Map.foldBack (fun _ y acc -> acc || p y) m false - - let tryFindInRange p m = - Map.foldBack (fun _ y acc -> - match acc with - | None -> if p y then Some y else None - | _ -> acc) m None - -[] -module NameMultiMap = - - let existsInRange f (m: NameMultiMap<'T>) = NameMap.exists (fun _ l -> List.exists f l) m - - let find v (m: NameMultiMap<'T>) = match m.TryGetValue v with true, r -> r | _ -> [] - - let add v x (m: NameMultiMap<'T>) = NameMap.add v (x :: find v m) m - - let range (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] - - let rangeReversingEachBucket (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.rev x @ sofar) m [] - - let chooseRange f (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.choose f x @ sofar) m [] - - let map f (m: NameMultiMap<'T>) = NameMap.map (List.map f) m - - let empty : NameMultiMap<'T> = Map.empty - - let initBy f xs : NameMultiMap<'T> = xs |> Seq.groupBy f |> Seq.map (fun (k, v) -> (k, List.ofSeq v)) |> Map.ofSeq - - let ofList (xs: (string * 'T) list) : NameMultiMap<'T> = xs |> Seq.groupBy fst |> Seq.map (fun (k, v) -> (k, List.ofSeq (Seq.map snd v))) |> Map.ofSeq - -[] -module MultiMap = - - let existsInRange f (m: MultiMap<_, _>) = Map.exists (fun _ l -> List.exists f l) m - - let find v (m: MultiMap<_, _>) = match m.TryGetValue v with true, r -> r | _ -> [] - - let add v x (m: MultiMap<_, _>) = Map.add v (x :: find v m) m - - let range (m: MultiMap<_, _>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] - - let empty : MultiMap<_, _> = Map.empty - - let initBy f xs : MultiMap<_, _> = xs |> Seq.groupBy f |> Seq.map (fun (k, v) -> (k, List.ofSeq v)) |> Map.ofSeq - -type LayeredMap<'Key, 'Value when 'Key : comparison> = Map<'Key, 'Value> - -type Map<'Key, 'Value when 'Key : comparison> with - - static member Empty : Map<'Key, 'Value> = Map.empty - - member x.Values = [ for (KeyValue(_, v)) in x -> v ] - - member x.AddAndMarkAsCollapsible (kvs: _[]) = (x, kvs) ||> Array.fold (fun x (KeyValue(k, v)) -> x.Add(k, v)) - - member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) = x.Add (key, f (x.TryFind key)) - - member x.MarkAsCollapsible () = x - -/// Immutable map collection, with explicit flattening to a backing dictionary -[] -type LayeredMultiMap<'Key, 'Value when 'Key : equality and 'Key : comparison>(contents : LayeredMap<'Key, 'Value list>) = - - member x.Add (k, v) = LayeredMultiMap(contents.Add(k, v :: x.[k])) - - member x.Item with get k = match contents.TryGetValue k with true, l -> l | _ -> [] - - member x.AddAndMarkAsCollapsible (kvs: _[]) = - let x = (x, kvs) ||> Array.fold (fun x (KeyValue(k, v)) -> x.Add(k, v)) - x.MarkAsCollapsible() - - member x.MarkAsCollapsible() = LayeredMultiMap(contents.MarkAsCollapsible()) - - member x.TryFind k = contents.TryFind k - - member x.TryGetValue k = contents.TryGetValue k - - member x.Values = contents.Values |> List.concat - - static member Empty : LayeredMultiMap<'Key, 'Value> = LayeredMultiMap LayeredMap.Empty - -[] -module Shim = - - type IFileSystem = - - /// A shim over File.ReadAllBytes - abstract ReadAllBytesShim: fileName: string -> byte[] - - /// A shim over FileStream with FileMode.Open, FileAccess.Read, FileShare.ReadWrite - abstract FileStreamReadShim: fileName: string -> Stream - - /// A shim over FileStream with FileMode.Create, FileAccess.Write, FileShare.Read - abstract FileStreamCreateShim: fileName: string -> Stream - - /// A shim over FileStream with FileMode.Open, FileAccess.Write, FileShare.Read - abstract FileStreamWriteExistingShim: fileName: string -> Stream - - /// Take in a filename with an absolute path, and return the same filename - /// but canonicalized with respect to extra path separators (e.g. C:\\\\foo.txt) - /// and '..' portions - abstract GetFullPathShim: fileName: string -> string - - /// A shim over Path.IsPathRooted - abstract IsPathRootedShim: path: string -> bool - - /// A shim over Path.IsInvalidPath - abstract IsInvalidPathShim: filename: string -> bool - - /// A shim over Path.GetTempPath - abstract GetTempPathShim : unit -> string - - /// Utc time of the last modification - abstract GetLastWriteTimeShim: fileName: string -> DateTime - - /// A shim over File.Exists - abstract SafeExists: fileName: string -> bool - - /// A shim over File.Delete - abstract FileDelete: fileName: string -> unit - - /// Used to load type providers and located assemblies in F# Interactive - abstract AssemblyLoadFrom: fileName: string -> Assembly - - /// Used to load a dependency for F# Interactive and in an unused corner-case of type provider loading - abstract AssemblyLoad: assemblyName: AssemblyName -> Assembly - - /// Used to determine if a file will not be subject to deletion during the lifetime of a typical client process. - abstract IsStableFileHeuristic: fileName: string -> bool - - - type DefaultFileSystem() = - interface IFileSystem with - - member __.AssemblyLoadFrom(fileName: string) = - Assembly.UnsafeLoadFrom fileName - - member __.AssemblyLoad(assemblyName: AssemblyName) = - Assembly.Load assemblyName - - member __.ReadAllBytesShim (fileName: string) = File.ReadAllBytes fileName - - member __.FileStreamReadShim (fileName: string) = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) :> Stream - - member __.FileStreamCreateShim (fileName: string) = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false) :> Stream - - member __.FileStreamWriteExistingShim (fileName: string) = new FileStream(fileName, FileMode.Open, FileAccess.Write, FileShare.Read, 0x1000, false) :> Stream - - member __.GetFullPathShim (fileName: string) = System.IO.Path.GetFullPath fileName - - member __.IsPathRootedShim (path: string) = Path.IsPathRooted path - - member __.IsInvalidPathShim(path: string) = - let isInvalidPath(p: string) = - String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidPathChars()) <> -1 - - let isInvalidFilename(p: string) = - String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidFileNameChars()) <> -1 - - let isInvalidDirectory(d: string) = - d=null || d.IndexOfAny(Path.GetInvalidPathChars()) <> -1 - - isInvalidPath path || - let directory = Path.GetDirectoryName path - let filename = Path.GetFileName path - isInvalidDirectory directory || isInvalidFilename filename - - member __.GetTempPathShim() = Path.GetTempPath() - - member __.GetLastWriteTimeShim (fileName: string) = File.GetLastWriteTimeUtc fileName - - member __.SafeExists (fileName: string) = File.Exists fileName - - member __.FileDelete (fileName: string) = File.Delete fileName - - member __.IsStableFileHeuristic (fileName: string) = - let directory = Path.GetDirectoryName fileName - directory.Contains("Reference Assemblies/") || - directory.Contains("Reference Assemblies\\") || - directory.Contains("packages/") || - directory.Contains("packages\\") || - directory.Contains("lib/mono/") - - let mutable FileSystem = DefaultFileSystem() :> IFileSystem - - // The choice of 60 retries times 50 ms is not arbitrary. The NTFS FILETIME structure - // uses 2 second resolution for LastWriteTime. We retry long enough to surpass this threshold - // plus 1 second. Once past the threshold the incremental builder will be able to retry asynchronously based - // on plain old timestamp checking. - // - // The sleep time of 50ms is chosen so that we can respond to the user more quickly for Intellisense operations. - // - // This is not run on the UI thread for VS but it is on a thread that must be stopped before Intellisense - // can return any result except for pending. - let private retryDelayMilliseconds = 50 - let private numRetries = 60 - - let private getReader (filename, codePage: int option, retryLocked: bool) = - // Retry multiple times since other processes may be writing to this file. - let rec getSource retryNumber = - try - // Use the .NET functionality to auto-detect the unicode encoding - let stream = FileSystem.FileStreamReadShim(filename) - match codePage with - | None -> new StreamReader(stream,true) - | Some n -> new StreamReader(stream,System.Text.Encoding.GetEncoding(n)) - with - // We can get here if the file is locked--like when VS is saving a file--we don't have direct - // access to the HRESULT to see that this is EONOACCESS. - | :? System.IO.IOException as err when retryLocked && err.GetType() = typeof -> - // This second check is to make sure the exception is exactly IOException and none of these for example: - // DirectoryNotFoundException - // EndOfStreamException - // FileNotFoundException - // FileLoadException - // PathTooLongException - if retryNumber < numRetries then - System.Threading.Thread.Sleep (retryDelayMilliseconds) - getSource (retryNumber + 1) - else - reraise() - getSource 0 - - type File with - - static member ReadBinaryChunk (fileName, start, len) = - use stream = FileSystem.FileStreamReadShim fileName - stream.Seek(int64 start, SeekOrigin.Begin) |> ignore - let buffer = Array.zeroCreate len - let mutable n = 0 - while n < len do - n <- n + stream.Read(buffer, n, len-n) - buffer - - static member OpenReaderAndRetry (filename, codepage, retryLocked) = - getReader (filename, codepage, retryLocked) - diff --git a/src/absil/ilmorph.fs b/src/absil/ilmorph.fs deleted file mode 100644 index b6fb7ce69b6..00000000000 --- a/src/absil/ilmorph.fs +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.AbstractIL.Morphs - -open System.Collections.Generic -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.IL - -let mutable morphCustomAttributeData = false - -let enableMorphCustomAttributeData() = - morphCustomAttributeData <- true - -let disableMorphCustomAttributeData() = - morphCustomAttributeData <- false - -let code_instr2instr f (code: ILCode) = {code with Instrs= Array.map f code.Instrs} - -let code_instr2instrs f (code: ILCode) = - let instrs = code.Instrs - let codebuf = ResizeArray() - let adjust = Dictionary() - let mutable old = 0 - let mutable nw = 0 - for instr in instrs do - adjust.[old] <- nw - let instrs : list<_> = f instr - for instr2 in instrs do - codebuf.Add instr2 - nw <- nw + 1 - old <- old + 1 - adjust.[old] <- nw - let labels = - let dict = Dictionary.newWithSize code.Labels.Count - for kvp in code.Labels do dict.Add(kvp.Key, adjust.[kvp.Value]) - dict - { code with - Instrs = codebuf.ToArray() - Labels = labels } - - - -let code_instr2instr_ty2ty (finstr,fty) (c:ILCode) = - let c = code_instr2instr finstr c - { c with - Exceptions = c.Exceptions |> List.map (fun e -> { e with Clause = e.Clause |> (function ILExceptionClause.TypeCatch (ilty, b) -> ILExceptionClause.TypeCatch (fty ilty, b) | cl -> cl) }) } - -// -------------------------------------------------------------------- -// Standard morphisms - mapping types etc. -// -------------------------------------------------------------------- - -let rec ty_tref2tref f x = - match x with - | ILType.Ptr t -> ILType.Ptr (ty_tref2tref f t) - | ILType.FunctionPointer x -> - ILType.FunctionPointer - { x with - ArgTypes=List.map (ty_tref2tref f) x.ArgTypes - ReturnType=ty_tref2tref f x.ReturnType} - | ILType.Byref t -> ILType.Byref (ty_tref2tref f t) - | ILType.Boxed cr -> mkILBoxedType (tspec_tref2tref f cr) - | ILType.Value ir -> ILType.Value (tspec_tref2tref f ir) - | ILType.Array (s,ty) -> ILType.Array (s,ty_tref2tref f ty) - | ILType.TypeVar v -> ILType.TypeVar v - | ILType.Modified (req,tref,ty) -> ILType.Modified (req, f tref, ty_tref2tref f ty) - | ILType.Void -> ILType.Void -and tspec_tref2tref f (x:ILTypeSpec) = - mkILTySpec(f x.TypeRef, List.map (ty_tref2tref f) x.GenericArgs) - -let rec ty_scoref2scoref_tyvar2ty ((_fscope,ftyvar) as fs)x = - match x with - | ILType.Ptr t -> ILType.Ptr (ty_scoref2scoref_tyvar2ty fs t) - | ILType.FunctionPointer t -> ILType.FunctionPointer (callsig_scoref2scoref_tyvar2ty fs t) - | ILType.Byref t -> ILType.Byref (ty_scoref2scoref_tyvar2ty fs t) - | ILType.Boxed cr -> mkILBoxedType (tspec_scoref2scoref_tyvar2ty fs cr) - | ILType.Value ir -> ILType.Value (tspec_scoref2scoref_tyvar2ty fs ir) - | ILType.Array (s,ty) -> ILType.Array (s,ty_scoref2scoref_tyvar2ty fs ty) - | ILType.TypeVar v -> ftyvar v - | x -> x -and tspec_scoref2scoref_tyvar2ty fs (x:ILTypeSpec) = - ILTypeSpec.Create(morphILScopeRefsInILTypeRef (fst fs) x.TypeRef,tys_scoref2scoref_tyvar2ty fs x.GenericArgs) -and callsig_scoref2scoref_tyvar2ty f x = - { x with - ArgTypes=List.map (ty_scoref2scoref_tyvar2ty f) x.ArgTypes - ReturnType=ty_scoref2scoref_tyvar2ty f x.ReturnType} -and tys_scoref2scoref_tyvar2ty f i = List.map (ty_scoref2scoref_tyvar2ty f) i -and gparams_scoref2scoref_tyvar2ty f i = List.map (gparam_scoref2scoref_tyvar2ty f) i -and gparam_scoref2scoref_tyvar2ty _f i = i -and morphILScopeRefsInILTypeRef fscope (x:ILTypeRef) = - ILTypeRef.Create(scope=fscope x.Scope, enclosing=x.Enclosing, name = x.Name) - - -let callsig_ty2ty f (x: ILCallingSignature) = - { CallingConv=x.CallingConv - ArgTypes=List.map f x.ArgTypes - ReturnType=f x.ReturnType} - -let gparam_ty2ty f gf = {gf with Constraints = List.map f gf.Constraints} -let gparams_ty2ty f gfs = List.map (gparam_ty2ty f) gfs -let tys_ty2ty (f: ILType -> ILType) x = List.map f x -let mref_ty2ty (f: ILType -> ILType) (x:ILMethodRef) = - ILMethodRef.Create(enclosingTypeRef= (f (mkILBoxedType (mkILNonGenericTySpec x.DeclaringTypeRef))).TypeRef, - callingConv=x.CallingConv, - name=x.Name, - genericArity=x.GenericArity, - argTypes= List.map f x.ArgTypes, - returnType= f x.ReturnType) - - -type formal_scopeCtxt = Choice - -let mspec_ty2ty (((factualty : ILType -> ILType), (fformalty: formal_scopeCtxt -> ILType -> ILType))) (x: ILMethodSpec) = - mkILMethSpecForMethRefInTy(mref_ty2ty (fformalty (Choice1Of2 x)) x.MethodRef, - factualty x.DeclaringType, - tys_ty2ty factualty x.GenericArgs) - -let fref_ty2ty (f: ILType -> ILType) x = - { x with DeclaringTypeRef = (f (mkILBoxedType (mkILNonGenericTySpec x.DeclaringTypeRef))).TypeRef - Type= f x.Type } - -let fspec_ty2ty ((factualty,(fformalty : formal_scopeCtxt -> ILType -> ILType))) x = - { FieldRef=fref_ty2ty (fformalty (Choice2Of2 x)) x.FieldRef - DeclaringType= factualty x.DeclaringType } - -let rec celem_ty2ty f celem = - match celem with - | ILAttribElem.Type (Some ty) -> ILAttribElem.Type (Some (f ty)) - | ILAttribElem.TypeRef (Some tref) -> ILAttribElem.TypeRef (Some (f (mkILBoxedType (mkILNonGenericTySpec tref))).TypeRef) - | ILAttribElem.Array (elemTy,elems) -> ILAttribElem.Array (f elemTy, List.map (celem_ty2ty f) elems) - | _ -> celem - -let cnamedarg_ty2ty f ((nm, ty, isProp, elem) : ILAttributeNamedArg) = - (nm, f ty, isProp, celem_ty2ty f elem) - -let cattr_ty2ty ilg f (c: ILAttribute) = - let meth = mspec_ty2ty (f, (fun _ -> f)) c.Method - // dev11 M3 defensive coding: if anything goes wrong with attribute decoding or encoding, then back out. - if morphCustomAttributeData then - try - let elems,namedArgs = IL.decodeILAttribData ilg c - let elems = elems |> List.map (celem_ty2ty f) - let namedArgs = namedArgs |> List.map (cnamedarg_ty2ty f) - mkILCustomAttribMethRef ilg (meth, elems, namedArgs) - with _ -> - c.WithMethod(meth) - else - c.WithMethod(meth) - - -let cattrs_ty2ty ilg f (cs: ILAttributes) = - mkILCustomAttrs (List.map (cattr_ty2ty ilg f) cs.AsList) - -let fdef_ty2ty ilg ftye (fd: ILFieldDef) = - fd.With(fieldType=ftye fd.FieldType, - customAttrs=cattrs_ty2ty ilg ftye fd.CustomAttrs) - -let local_ty2ty f (l: ILLocal) = {l with Type = f l.Type} -let varargs_ty2ty f (varargs: ILVarArgs) = Option.map (List.map f) varargs -(* REVIEW: convert varargs *) -let morphILTypesInILInstr ((factualty,fformalty)) i = - let factualty = factualty (Some i) - let conv_fspec fr = fspec_ty2ty (factualty,fformalty (Some i)) fr - let conv_mspec mr = mspec_ty2ty (factualty,fformalty (Some i)) mr - match i with - | I_calli (a,mref,varargs) -> I_calli (a,callsig_ty2ty (factualty) mref,varargs_ty2ty factualty varargs) - | I_call (a,mr,varargs) -> I_call (a,conv_mspec mr,varargs_ty2ty factualty varargs) - | I_callvirt (a,mr,varargs) -> I_callvirt (a,conv_mspec mr,varargs_ty2ty factualty varargs) - | I_callconstraint (a,ty,mr,varargs) -> I_callconstraint (a,factualty ty,conv_mspec mr,varargs_ty2ty factualty varargs) - | I_newobj (mr,varargs) -> I_newobj (conv_mspec mr,varargs_ty2ty factualty varargs) - | I_ldftn mr -> I_ldftn (conv_mspec mr) - | I_ldvirtftn mr -> I_ldvirtftn (conv_mspec mr) - | I_ldfld (a,b,fr) -> I_ldfld (a,b,conv_fspec fr) - | I_ldsfld (a,fr) -> I_ldsfld (a,conv_fspec fr) - | I_ldsflda (fr) -> I_ldsflda (conv_fspec fr) - | I_ldflda fr -> I_ldflda (conv_fspec fr) - | I_stfld (a,b,fr) -> I_stfld (a,b,conv_fspec fr) - | I_stsfld (a,fr) -> I_stsfld (a,conv_fspec fr) - | I_castclass ty -> I_castclass (factualty ty) - | I_isinst ty -> I_isinst (factualty ty) - | I_initobj ty -> I_initobj (factualty ty) - | I_cpobj ty -> I_cpobj (factualty ty) - | I_stobj (al,vol,ty) -> I_stobj (al,vol,factualty ty) - | I_ldobj (al,vol,ty) -> I_ldobj (al,vol,factualty ty) - | I_box ty -> I_box (factualty ty) - | I_unbox ty -> I_unbox (factualty ty) - | I_unbox_any ty -> I_unbox_any (factualty ty) - | I_ldelem_any (shape,ty) -> I_ldelem_any (shape,factualty ty) - | I_stelem_any (shape,ty) -> I_stelem_any (shape,factualty ty) - | I_newarr (shape,ty) -> I_newarr (shape,factualty ty) - | I_ldelema (ro,isNativePtr,shape,ty) -> I_ldelema (ro,isNativePtr,shape,factualty ty) - | I_sizeof ty -> I_sizeof (factualty ty) - | I_ldtoken tok -> - match tok with - | ILToken.ILType ty -> I_ldtoken (ILToken.ILType (factualty ty)) - | ILToken.ILMethod mr -> I_ldtoken (ILToken.ILMethod (conv_mspec mr)) - | ILToken.ILField fr -> I_ldtoken (ILToken.ILField (conv_fspec fr)) - | x -> x - -let return_ty2ty ilg f (r:ILReturn) = {r with Type=f r.Type; CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty ilg f r.CustomAttrs)} -let param_ty2ty ilg f (p: ILParameter) = {p with Type=f p.Type; CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty ilg f p.CustomAttrs)} - -let morphILMethodDefs f (m:ILMethodDefs) = mkILMethods (List.map f m.AsList) -let fdefs_fdef2fdef f (m:ILFieldDefs) = mkILFields (List.map f m.AsList) - -(* use this when the conversion produces just one tye... *) -let morphILTypeDefs f (m: ILTypeDefs) = mkILTypeDefsFromArray (Array.map f m.AsArray) - -let locals_ty2ty f ls = List.map (local_ty2ty f) ls - -let ilmbody_instr2instr_ty2ty fs (il: ILMethodBody) = - let (finstr,ftye) = fs - {il with Code=code_instr2instr_ty2ty (finstr,ftye) il.Code - Locals = locals_ty2ty ftye il.Locals } - -let morphILMethodBody (filmbody) (x: ILLazyMethodBody) = - let c = - match x.Contents with - | MethodBody.IL il -> MethodBody.IL (filmbody il) - | x -> x - mkMethBodyAux c - -let ospec_ty2ty f (OverridesSpec(mref,ty)) = OverridesSpec(mref_ty2ty f mref, f ty) - -let mdef_ty2ty_ilmbody2ilmbody ilg fs (md: ILMethodDef) = - let (ftye,filmbody) = fs - let ftye' = ftye (Some md) - let body' = morphILMethodBody (filmbody (Some md)) md.Body - md.With(genericParams=gparams_ty2ty ftye' md.GenericParams, - body= body', - parameters = List.map (param_ty2ty ilg ftye') md.Parameters, - ret = return_ty2ty ilg ftye' md.Return, - customAttrs=cattrs_ty2ty ilg ftye' md.CustomAttrs) - -let fdefs_ty2ty ilg f x = fdefs_fdef2fdef (fdef_ty2ty ilg f) x - -let mdefs_ty2ty_ilmbody2ilmbody ilg fs x = morphILMethodDefs (mdef_ty2ty_ilmbody2ilmbody ilg fs) x - -let mimpl_ty2ty f e = - { Overrides = ospec_ty2ty f e.Overrides - OverrideBy = mspec_ty2ty (f,(fun _ -> f)) e.OverrideBy; } - -let edef_ty2ty ilg f (e: ILEventDef) = - e.With(eventType = Option.map f e.EventType, - addMethod = mref_ty2ty f e.AddMethod, - removeMethod = mref_ty2ty f e.RemoveMethod, - fireMethod = Option.map (mref_ty2ty f) e.FireMethod, - otherMethods = List.map (mref_ty2ty f) e.OtherMethods, - customAttrs = cattrs_ty2ty ilg f e.CustomAttrs) - -let pdef_ty2ty ilg f (p: ILPropertyDef) = - p.With(setMethod = Option.map (mref_ty2ty f) p.SetMethod, - getMethod = Option.map (mref_ty2ty f) p.GetMethod, - propertyType = f p.PropertyType, - args = List.map f p.Args, - customAttrs = cattrs_ty2ty ilg f p.CustomAttrs) - -let pdefs_ty2ty ilg f (pdefs: ILPropertyDefs) = mkILProperties (List.map (pdef_ty2ty ilg f) pdefs.AsList) -let edefs_ty2ty ilg f (edefs: ILEventDefs) = mkILEvents (List.map (edef_ty2ty ilg f) edefs.AsList) - -let mimpls_ty2ty f (mimpls : ILMethodImplDefs) = mkILMethodImpls (List.map (mimpl_ty2ty f) mimpls.AsList) - -let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs ilg enc fs (td: ILTypeDef) = - let (ftye,fmdefs) = fs - let ftye' = ftye (Some (enc,td)) None - let mdefs' = fmdefs (enc,td) td.Methods - let fdefs' = fdefs_ty2ty ilg ftye' td.Fields - td.With(implements= List.map ftye' td.Implements, - genericParams= gparams_ty2ty ftye' td.GenericParams, - extends = Option.map ftye' td.Extends, - methods=mdefs', - nestedTypes=tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs ilg (enc@[td]) fs td.NestedTypes, - fields=fdefs', - methodImpls = mimpls_ty2ty ftye' td.MethodImpls, - events = edefs_ty2ty ilg ftye' td.Events, - properties = pdefs_ty2ty ilg ftye' td.Properties, - customAttrs = cattrs_ty2ty ilg ftye' td.CustomAttrs) - -and tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs ilg enc fs tdefs = - morphILTypeDefs (tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs ilg enc fs) tdefs - -// -------------------------------------------------------------------- -// Derived versions of the above, e.g. with defaults added -// -------------------------------------------------------------------- - -let manifest_ty2ty ilg f (m : ILAssemblyManifest) = - { m with CustomAttrsStored = storeILCustomAttrs (cattrs_ty2ty ilg f m.CustomAttrs) } - -let morphILTypeInILModule_ilmbody2ilmbody_mdefs2mdefs ilg ((ftye: ILModuleDef -> (ILTypeDef list * ILTypeDef) option -> ILMethodDef option -> ILType -> ILType),fmdefs) m = - - let ftdefs = tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs ilg [] (ftye m,fmdefs m) - - { m with TypeDefs=ftdefs m.TypeDefs - CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty ilg (ftye m None None) m.CustomAttrs) - Manifest=Option.map (manifest_ty2ty ilg (ftye m None None)) m.Manifest } - -let module_instr2instr_ty2ty ilg fs x = - let (fcode,ftye) = fs - let filmbody modCtxt tdefCtxt mdefCtxt = ilmbody_instr2instr_ty2ty (fcode modCtxt tdefCtxt mdefCtxt, ftye modCtxt (Some tdefCtxt) mdefCtxt) - let fmdefs modCtxt tdefCtxt = mdefs_ty2ty_ilmbody2ilmbody ilg (ftye modCtxt (Some tdefCtxt), filmbody modCtxt tdefCtxt) - morphILTypeInILModule_ilmbody2ilmbody_mdefs2mdefs ilg (ftye, fmdefs) x - -let morphILInstrsAndILTypesInILModule ilg (f1,f2) x = - module_instr2instr_ty2ty ilg (f1, f2) x - -let morphILInstrsInILCode f x = code_instr2instrs f x - -let morphILTypeInILModule ilg ftye y = - let finstr modCtxt tdefCtxt mdefCtxt = - let fty = ftye modCtxt (Some tdefCtxt) mdefCtxt - morphILTypesInILInstr ((fun _instrCtxt -> fty), (fun _instrCtxt _formalCtxt -> fty)) - morphILInstrsAndILTypesInILModule ilg (finstr,ftye) y - -let morphILTypeRefsInILModuleMemoized ilg f modul = - let fty = Tables.memoize (ty_tref2tref f) - morphILTypeInILModule ilg (fun _ _ _ ty -> fty ty) modul - -let morphILScopeRefsInILModuleMemoized ilg f modul = - morphILTypeRefsInILModuleMemoized ilg (morphILScopeRefsInILTypeRef f) modul diff --git a/src/absil/ilnativeres.fsi b/src/absil/ilnativeres.fsi deleted file mode 100644 index c9582400851..00000000000 --- a/src/absil/ilnativeres.fsi +++ /dev/null @@ -1,62 +0,0 @@ - -module internal FSharp.Compiler.AbstractIL.Internal.NativeRes - -open System -open System.Collections.Generic -open System.Linq -open System.Diagnostics -open System.IO -open System.Reflection.Metadata - -type BYTE = System.Byte -type DWORD = System.UInt32 -type WCHAR = System.Char -type WORD = System.UInt16 - -[] -type RESOURCE_STRING = - member Ordinal: WORD with get, set - member theString : string with get, set - -[] -type RESOURCE = - member pstringType : RESOURCE_STRING with get, set - member pstringName : RESOURCE_STRING with get, set - member DataSize : DWORD with get, set - member HeaderSize : DWORD with get, set - member DataVersion : DWORD with get, set - member MemoryFlags : WORD with get, set - member LanguageId : WORD with get, set - member Version : DWORD with get, set - member Characteristics : DWORD with get, set - member data : byte[] with get, set - -type Win32Resource = - new : data:byte [] * codePage: DWORD * languageId: DWORD * id: int * - name: string * typeId:int * typeName : string -> Win32Resource - member CodePage: DWORD - member Data: byte [] - member Id: int - member LanguageId : DWORD - member Name: string - member TypeId: int - member TypeName: string - -[] -type CvtResFile = - static member ReadResFile : stream:Stream -> System.Collections.Generic.List - -[] -type Win32ResourceConversions = - static member AppendIconToResourceStream : resStream:Stream * iconStream:Stream -> unit - static member AppendVersionToResourceStream : resStream:Stream * isDll:System.Boolean * fileVersion:string * originalFileName:string * internalName:string * productVersion:string * assemblyVersion:Version * ?fileDescription:string * ?legalCopyright:string * ?legalTrademarks:string * ?productName:string * ?comments:string * ?companyName:string -> unit - static member AppendManifestToResourceStream : resStream:Stream * manifestStream:Stream * isDll:System.Boolean -> unit - -// Write native resources -[] -type NativeResourceWriter = - static member SortResources: resources: IEnumerable -> IEnumerable - static member SerializeWin32Resources: builder:BlobBuilder * theResources: IEnumerable * resourcesRva: int -> unit - (* - static member SerializeWin32Resources (builder : BlobBuilder, resourceSections : ResourceSection, resourcesRva : int) -> unit - ()*) \ No newline at end of file diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs deleted file mode 100644 index aa4438cedfa..00000000000 --- a/src/absil/ilread.fs +++ /dev/null @@ -1,3938 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -//--------------------------------------------------------------------- -// The big binary reader -// -//--------------------------------------------------------------------- - -module FSharp.Compiler.AbstractIL.ILBinaryReader - -#nowarn "42" // This construct is deprecated: it is only for use in the F# library - -open System -open System.Collections.Concurrent -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.IO.MemoryMappedFiles -open System.Runtime.InteropServices -open System.Text -open Internal.Utilities -open Internal.Utilities.Collections -open FSharp.NativeInterop -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Support -open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.AbstractIL.Internal.BinaryConstants -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range -open System.Reflection - -#nowarn "9" - -let primaryAssemblyILGlobals = mkILGlobals (ILScopeRef.PrimaryAssembly, []) - -let checking = false -let logging = false -let _ = if checking then dprintn "warning: ILBinaryReader.checking is on" -let noStableFileHeuristic = try (System.Environment.GetEnvironmentVariable("FSharp_NoStableFileHeuristic") <> null) with _ -> false -let alwaysMemoryMapFSC = try (System.Environment.GetEnvironmentVariable("FSharp_AlwaysMemoryMapCommandLineCompiler") <> null) with _ -> false -let stronglyHeldReaderCacheSizeDefault = 30 -let stronglyHeldReaderCacheSize = try (match System.Environment.GetEnvironmentVariable("FSharp_StronglyHeldBinaryReaderCacheSize") with null -> stronglyHeldReaderCacheSizeDefault | s -> int32 s) with _ -> stronglyHeldReaderCacheSizeDefault - -let singleOfBits (x: int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes x, 0) -let doubleOfBits (x: int64) = System.BitConverter.Int64BitsToDouble x - -//--------------------------------------------------------------------- -// Utilities. -//--------------------------------------------------------------------- - -let align alignment n = ((n + alignment - 0x1) / alignment) * alignment - -let uncodedToken (tab: TableName) idx = ((tab.Index <<< 24) ||| idx) - -let i32ToUncodedToken tok = - let idx = tok &&& 0xffffff - let tab = tok >>>& 24 - (TableName.FromIndex tab, idx) - - -[] -type TaggedIndex<'T> = - val tag: 'T - val index: int32 - new(tag, index) = { tag=tag; index=index } - -let uncodedTokenToTypeDefOrRefOrSpec (tab, tok) = - let tag = - if tab = TableNames.TypeDef then tdor_TypeDef - elif tab = TableNames.TypeRef then tdor_TypeRef - elif tab = TableNames.TypeSpec then tdor_TypeSpec - else failwith "bad table in uncodedTokenToTypeDefOrRefOrSpec" - TaggedIndex(tag, tok) - -let uncodedTokenToMethodDefOrRef (tab, tok) = - let tag = - if tab = TableNames.Method then mdor_MethodDef - elif tab = TableNames.MemberRef then mdor_MemberRef - else failwith "bad table in uncodedTokenToMethodDefOrRef" - TaggedIndex(tag, tok) - -let (|TaggedIndex|) (x: TaggedIndex<'T>) = x.tag, x.index -let tokToTaggedIdx f nbits tok = - let tagmask = - if nbits = 1 then 1 - elif nbits = 2 then 3 - elif nbits = 3 then 7 - elif nbits = 4 then 15 - elif nbits = 5 then 31 - else failwith "too many nbits" - let tag = tok &&& tagmask - let idx = tok >>>& nbits - TaggedIndex(f tag, idx) - -type Statistics = - { mutable rawMemoryFileCount: int - mutable memoryMapFileOpenedCount: int - mutable memoryMapFileClosedCount: int - mutable weakByteFileCount: int - mutable byteFileCount: int } - -let stats = - { rawMemoryFileCount = 0 - memoryMapFileOpenedCount = 0 - memoryMapFileClosedCount = 0 - weakByteFileCount = 0 - byteFileCount = 0 } - -let GetStatistics() = stats - -type private BinaryView = ReadOnlyByteMemory - -/// An abstraction over how we access the contents of .NET binaries. -type BinaryFile = - abstract GetView: unit -> BinaryView - -/// Gives views over a raw chunk of memory, for example those returned to us by the memory manager in Roslyn's -/// Visual Studio integration. 'obj' must keep the memory alive. The object will capture it and thus also keep the memory alive for -/// the lifetime of this object. -type RawMemoryFile(fileName: string, obj: obj, addr: nativeint, length: int) = - do stats.rawMemoryFileCount <- stats.rawMemoryFileCount + 1 - let view = ByteMemory.FromUnsafePointer(addr, length, obj).AsReadOnly() - member __.HoldObj() = obj // make sure we capture 'obj' - member __.FileName = fileName - interface BinaryFile with - override __.GetView() = view - -/// A BinaryFile backed by an array of bytes held strongly as managed memory -[] -type ByteFile(fileName: string, bytes: byte[]) = - let view = ByteMemory.FromArray(bytes).AsReadOnly() - do stats.byteFileCount <- stats.byteFileCount + 1 - member __.FileName = fileName - interface BinaryFile with - override bf.GetView() = view - -/// Same as ByteFile but holds the bytes weakly. The bytes will be re-read from the backing file when a view is requested. -/// This is the default implementation used by F# Compiler Services when accessing "stable" binaries. It is not used -/// by Visual Studio, where tryGetMetadataSnapshot provides a RawMemoryFile backed by Roslyn data. -[] -type WeakByteFile(fileName: string, chunk: (int * int) option) = - - do stats.weakByteFileCount <- stats.weakByteFileCount + 1 - - /// Used to check that the file hasn't changed - let fileStamp = FileSystem.GetLastWriteTimeShim fileName - - /// The weak handle to the bytes for the file - let weakBytes = new WeakReference (null) - - member __.FileName = fileName - - /// Get the bytes for the file - interface BinaryFile with - - override this.GetView() = - let strongBytes = - let mutable tg = null - if not (weakBytes.TryGetTarget(&tg)) then - if FileSystem.GetLastWriteTimeShim fileName <> fileStamp then - error (Error (FSComp.SR.ilreadFileChanged fileName, range0)) - - let bytes = - match chunk with - | None -> FileSystem.ReadAllBytesShim fileName - | Some(start, length) -> File.ReadBinaryChunk (fileName, start, length) - - tg <- bytes - - weakBytes.SetTarget bytes - - tg - - ByteMemory.FromArray(strongBytes).AsReadOnly() - - -let seekReadByte (mdv: BinaryView) addr = mdv.[addr] -let seekReadBytes (mdv: BinaryView) addr len = mdv.ReadBytes(addr, len) -let seekReadInt32 (mdv: BinaryView) addr = mdv.ReadInt32 addr -let seekReadUInt16 (mdv: BinaryView) addr = mdv.ReadUInt16 addr - -let seekReadByteAsInt32 mdv addr = int32 (seekReadByte mdv addr) - -let seekReadInt64 mdv addr = - let b0 = seekReadByte mdv addr - let b1 = seekReadByte mdv (addr+1) - let b2 = seekReadByte mdv (addr+2) - let b3 = seekReadByte mdv (addr+3) - let b4 = seekReadByte mdv (addr+4) - let b5 = seekReadByte mdv (addr+5) - let b6 = seekReadByte mdv (addr+6) - let b7 = seekReadByte mdv (addr+7) - int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| - (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56) - -let seekReadUInt16AsInt32 mdv addr = int32 (seekReadUInt16 mdv addr) - -let seekReadCompressedUInt32 mdv addr = - let b0 = seekReadByte mdv addr - if b0 <= 0x7Fuy then int b0, addr+1 - elif b0 <= 0xBFuy then - let b0 = b0 &&& 0x7Fuy - let b1 = seekReadByteAsInt32 mdv (addr+1) - (int b0 <<< 8) ||| int b1, addr+2 - else - let b0 = b0 &&& 0x3Fuy - let b1 = seekReadByteAsInt32 mdv (addr+1) - let b2 = seekReadByteAsInt32 mdv (addr+2) - let b3 = seekReadByteAsInt32 mdv (addr+3) - (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, addr+4 - -let seekReadSByte mdv addr = sbyte (seekReadByte mdv addr) -let seekReadSingle mdv addr = singleOfBits (seekReadInt32 mdv addr) -let seekReadDouble mdv addr = doubleOfBits (seekReadInt64 mdv addr) - -let rec seekCountUtf8String mdv addr n = - let c = seekReadByteAsInt32 mdv addr - if c = 0 then n - else seekCountUtf8String mdv (addr+1) (n+1) - -let seekReadUTF8String mdv addr = - let n = seekCountUtf8String mdv addr 0 - let bytes = seekReadBytes mdv addr n - System.Text.Encoding.UTF8.GetString (bytes, 0, bytes.Length) - -let seekReadBlob mdv addr = - let len, addr = seekReadCompressedUInt32 mdv addr - seekReadBytes mdv addr len - -let seekReadUserString mdv addr = - let len, addr = seekReadCompressedUInt32 mdv addr - let bytes = seekReadBytes mdv addr (len - 1) - Encoding.Unicode.GetString(bytes, 0, bytes.Length) - -let seekReadGuid mdv addr = seekReadBytes mdv addr 0x10 - -let seekReadUncodedToken mdv addr = - i32ToUncodedToken (seekReadInt32 mdv addr) - - -//--------------------------------------------------------------------- -// Primitives to help read signatures. These do not use the file cursor -//--------------------------------------------------------------------- - -let sigptrCheck (bytes: byte[]) sigptr = - if checking && sigptr >= bytes.Length then failwith "read past end of sig. " - -// All this code should be moved to use a mutable index into the signature -// -//type SigPtr(bytes: byte[], sigptr: int) = -// let mutable curr = sigptr -// member x.GetByte() = let res = bytes.[curr] in curr <- curr + 1; res - -let sigptrGetByte (bytes: byte[]) sigptr = - sigptrCheck bytes sigptr - bytes.[sigptr], sigptr + 1 - -let sigptrGetBool bytes sigptr = - let b0, sigptr = sigptrGetByte bytes sigptr - (b0 = 0x01uy), sigptr - -let sigptrGetSByte bytes sigptr = - let i, sigptr = sigptrGetByte bytes sigptr - sbyte i, sigptr - -let sigptrGetUInt16 bytes sigptr = - let b0, sigptr = sigptrGetByte bytes sigptr - let b1, sigptr = sigptrGetByte bytes sigptr - uint16 (int b0 ||| (int b1 <<< 8)), sigptr - -let sigptrGetInt16 bytes sigptr = - let u, sigptr = sigptrGetUInt16 bytes sigptr - int16 u, sigptr - -let sigptrGetInt32 bytes sigptr = - sigptrCheck bytes sigptr - let b0 = bytes.[sigptr] - let b1 = bytes.[sigptr+1] - let b2 = bytes.[sigptr+2] - let b3 = bytes.[sigptr+3] - let res = int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) - res, sigptr + 4 - -let sigptrGetUInt32 bytes sigptr = - let u, sigptr = sigptrGetInt32 bytes sigptr - uint32 u, sigptr - -let sigptrGetUInt64 bytes sigptr = - let u0, sigptr = sigptrGetUInt32 bytes sigptr - let u1, sigptr = sigptrGetUInt32 bytes sigptr - (uint64 u0 ||| (uint64 u1 <<< 32)), sigptr - -let sigptrGetInt64 bytes sigptr = - let u, sigptr = sigptrGetUInt64 bytes sigptr - int64 u, sigptr - -let sigptrGetSingle bytes sigptr = - let u, sigptr = sigptrGetInt32 bytes sigptr - singleOfBits u, sigptr - -let sigptrGetDouble bytes sigptr = - let u, sigptr = sigptrGetInt64 bytes sigptr - doubleOfBits u, sigptr - -let sigptrGetZInt32 bytes sigptr = - let b0, sigptr = sigptrGetByte bytes sigptr - if b0 <= 0x7Fuy then int b0, sigptr - elif b0 <= 0xBFuy then - let b0 = b0 &&& 0x7Fuy - let b1, sigptr = sigptrGetByte bytes sigptr - (int b0 <<< 8) ||| int b1, sigptr - else - let b0 = b0 &&& 0x3Fuy - let b1, sigptr = sigptrGetByte bytes sigptr - let b2, sigptr = sigptrGetByte bytes sigptr - let b3, sigptr = sigptrGetByte bytes sigptr - (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, sigptr - -let rec sigptrFoldAcc f n (bytes: byte[]) (sigptr: int) i acc = - if i < n then - let x, sp = f bytes sigptr - sigptrFoldAcc f n bytes sp (i+1) (x :: acc) - else - List.rev acc, sigptr - -let sigptrFold f n (bytes: byte[]) (sigptr: int) = - sigptrFoldAcc f n bytes sigptr 0 [] - - -let sigptrGetBytes n (bytes: byte[]) sigptr = - if checking && sigptr + n >= bytes.Length then - dprintn "read past end of sig. in sigptrGetString" - Bytes.zeroCreate 0, sigptr - else - let res = Bytes.zeroCreate n - for i = 0 to (n - 1) do - res.[i] <- bytes.[sigptr + i] - res, sigptr + n - -let sigptrGetString n bytes sigptr = - let bytearray, sigptr = sigptrGetBytes n bytes sigptr - (System.Text.Encoding.UTF8.GetString(bytearray, 0, bytearray.Length)), sigptr - - -// -------------------------------------------------------------------- -// Now the tables of instructions -// -------------------------------------------------------------------- - -[] -type ILInstrPrefixesRegister = - { mutable al: ILAlignment - mutable tl: ILTailcall - mutable vol: ILVolatility - mutable ro: ILReadonly - mutable constrained: ILType option} - -let noPrefixes mk prefixes = - if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" - if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" - if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" - if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" - if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" - mk - -let volatileOrUnalignedPrefix mk prefixes = - if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" - if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" - if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" - mk (prefixes.al, prefixes.vol) - -let volatilePrefix mk prefixes = - if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" - if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" - if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" - if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" - mk prefixes.vol - -let tailPrefix mk prefixes = - if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" - if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" - if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" - if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" - mk prefixes.tl - -let constraintOrTailPrefix mk prefixes = - if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" - if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" - if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" - mk (prefixes.constrained, prefixes.tl ) - -let readonlyPrefix mk prefixes = - if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" - if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" - if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" - if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" - mk prefixes.ro - - -[] -type ILInstrDecoder = - | I_u16_u8_instr of (ILInstrPrefixesRegister -> uint16 -> ILInstr) - | I_u16_u16_instr of (ILInstrPrefixesRegister -> uint16 -> ILInstr) - | I_none_instr of (ILInstrPrefixesRegister -> ILInstr) - | I_i64_instr of (ILInstrPrefixesRegister -> int64 -> ILInstr) - | I_i32_i32_instr of (ILInstrPrefixesRegister -> int32 -> ILInstr) - | I_i32_i8_instr of (ILInstrPrefixesRegister -> int32 -> ILInstr) - | I_r4_instr of (ILInstrPrefixesRegister -> single -> ILInstr) - | I_r8_instr of (ILInstrPrefixesRegister -> double -> ILInstr) - | I_field_instr of (ILInstrPrefixesRegister -> ILFieldSpec -> ILInstr) - | I_method_instr of (ILInstrPrefixesRegister -> ILMethodSpec * ILVarArgs -> ILInstr) - | I_unconditional_i32_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) - | I_unconditional_i8_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) - | I_conditional_i32_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) - | I_conditional_i8_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) - | I_string_instr of (ILInstrPrefixesRegister -> string -> ILInstr) - | I_switch_instr of (ILInstrPrefixesRegister -> ILCodeLabel list -> ILInstr) - | I_tok_instr of (ILInstrPrefixesRegister -> ILToken -> ILInstr) - | I_sig_instr of (ILInstrPrefixesRegister -> ILCallingSignature * ILVarArgs -> ILInstr) - | I_type_instr of (ILInstrPrefixesRegister -> ILType -> ILInstr) - | I_invalid_instr - -let mkStind dt = volatileOrUnalignedPrefix (fun (x, y) -> I_stind(x, y, dt)) -let mkLdind dt = volatileOrUnalignedPrefix (fun (x, y) -> I_ldind(x, y, dt)) - -let instrs () = - [ i_ldarg_s, I_u16_u8_instr (noPrefixes mkLdarg) - i_starg_s, I_u16_u8_instr (noPrefixes I_starg) - i_ldarga_s, I_u16_u8_instr (noPrefixes I_ldarga) - i_stloc_s, I_u16_u8_instr (noPrefixes mkStloc) - i_ldloc_s, I_u16_u8_instr (noPrefixes mkLdloc) - i_ldloca_s, I_u16_u8_instr (noPrefixes I_ldloca) - i_ldarg, I_u16_u16_instr (noPrefixes mkLdarg) - i_starg, I_u16_u16_instr (noPrefixes I_starg) - i_ldarga, I_u16_u16_instr (noPrefixes I_ldarga) - i_stloc, I_u16_u16_instr (noPrefixes mkStloc) - i_ldloc, I_u16_u16_instr (noPrefixes mkLdloc) - i_ldloca, I_u16_u16_instr (noPrefixes I_ldloca) - i_stind_i, I_none_instr (mkStind DT_I) - i_stind_i1, I_none_instr (mkStind DT_I1) - i_stind_i2, I_none_instr (mkStind DT_I2) - i_stind_i4, I_none_instr (mkStind DT_I4) - i_stind_i8, I_none_instr (mkStind DT_I8) - i_stind_r4, I_none_instr (mkStind DT_R4) - i_stind_r8, I_none_instr (mkStind DT_R8) - i_stind_ref, I_none_instr (mkStind DT_REF) - i_ldind_i, I_none_instr (mkLdind DT_I) - i_ldind_i1, I_none_instr (mkLdind DT_I1) - i_ldind_i2, I_none_instr (mkLdind DT_I2) - i_ldind_i4, I_none_instr (mkLdind DT_I4) - i_ldind_i8, I_none_instr (mkLdind DT_I8) - i_ldind_u1, I_none_instr (mkLdind DT_U1) - i_ldind_u2, I_none_instr (mkLdind DT_U2) - i_ldind_u4, I_none_instr (mkLdind DT_U4) - i_ldind_r4, I_none_instr (mkLdind DT_R4) - i_ldind_r8, I_none_instr (mkLdind DT_R8) - i_ldind_ref, I_none_instr (mkLdind DT_REF) - i_cpblk, I_none_instr (volatileOrUnalignedPrefix I_cpblk) - i_initblk, I_none_instr (volatileOrUnalignedPrefix I_initblk) - i_ldc_i8, I_i64_instr (noPrefixes (fun x ->(AI_ldc (DT_I8, ILConst.I8 x)))) - i_ldc_i4, I_i32_i32_instr (noPrefixes mkLdcInt32) - i_ldc_i4_s, I_i32_i8_instr (noPrefixes mkLdcInt32) - i_ldc_r4, I_r4_instr (noPrefixes (fun x -> (AI_ldc (DT_R4, ILConst.R4 x)))) - i_ldc_r8, I_r8_instr (noPrefixes (fun x -> (AI_ldc (DT_R8, ILConst.R8 x)))) - i_ldfld, I_field_instr (volatileOrUnalignedPrefix(fun (x, y) fspec -> I_ldfld (x, y, fspec))) - i_stfld, I_field_instr (volatileOrUnalignedPrefix(fun (x, y) fspec -> I_stfld (x, y, fspec))) - i_ldsfld, I_field_instr (volatilePrefix (fun x fspec -> I_ldsfld (x, fspec))) - i_stsfld, I_field_instr (volatilePrefix (fun x fspec -> I_stsfld (x, fspec))) - i_ldflda, I_field_instr (noPrefixes I_ldflda) - i_ldsflda, I_field_instr (noPrefixes I_ldsflda) - i_call, I_method_instr (tailPrefix (fun tl (mspec, y) -> I_call (tl, mspec, y))) - i_ldftn, I_method_instr (noPrefixes (fun (mspec, _y) -> I_ldftn mspec)) - i_ldvirtftn, I_method_instr (noPrefixes (fun (mspec, _y) -> I_ldvirtftn mspec)) - i_newobj, I_method_instr (noPrefixes I_newobj) - i_callvirt, I_method_instr (constraintOrTailPrefix (fun (c, tl) (mspec, y) -> match c with Some ty -> I_callconstraint(tl, ty, mspec, y) | None -> I_callvirt (tl, mspec, y))) - i_leave_s, I_unconditional_i8_instr (noPrefixes (fun x -> I_leave x)) - i_br_s, I_unconditional_i8_instr (noPrefixes I_br) - i_leave, I_unconditional_i32_instr (noPrefixes (fun x -> I_leave x)) - i_br, I_unconditional_i32_instr (noPrefixes I_br) - i_brtrue_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_brtrue, x))) - i_brfalse_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_brfalse, x))) - i_beq_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_beq, x))) - i_blt_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_blt, x))) - i_blt_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_blt_un, x))) - i_ble_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_ble, x))) - i_ble_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_ble_un, x))) - i_bgt_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bgt, x))) - i_bgt_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bgt_un, x))) - i_bge_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bge, x))) - i_bge_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bge_un, x))) - i_bne_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bne_un, x))) - i_brtrue, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_brtrue, x))) - i_brfalse, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_brfalse, x))) - i_beq, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_beq, x))) - i_blt, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_blt, x))) - i_blt_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_blt_un, x))) - i_ble, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_ble, x))) - i_ble_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_ble_un, x))) - i_bgt, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bgt, x))) - i_bgt_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bgt_un, x))) - i_bge, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bge, x))) - i_bge_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bge_un, x))) - i_bne_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bne_un, x))) - i_ldstr, I_string_instr (noPrefixes I_ldstr) - i_switch, I_switch_instr (noPrefixes I_switch) - i_ldtoken, I_tok_instr (noPrefixes I_ldtoken) - i_calli, I_sig_instr (tailPrefix (fun tl (x, y) -> I_calli (tl, x, y))) - i_mkrefany, I_type_instr (noPrefixes I_mkrefany) - i_refanyval, I_type_instr (noPrefixes I_refanyval) - i_ldelema, I_type_instr (readonlyPrefix (fun ro x -> I_ldelema (ro, false, ILArrayShape.SingleDimensional, x))) - i_ldelem_any, I_type_instr (noPrefixes (fun x -> I_ldelem_any (ILArrayShape.SingleDimensional, x))) - i_stelem_any, I_type_instr (noPrefixes (fun x -> I_stelem_any (ILArrayShape.SingleDimensional, x))) - i_newarr, I_type_instr (noPrefixes (fun x -> I_newarr (ILArrayShape.SingleDimensional, x))) - i_castclass, I_type_instr (noPrefixes I_castclass) - i_isinst, I_type_instr (noPrefixes I_isinst) - i_unbox_any, I_type_instr (noPrefixes I_unbox_any) - i_cpobj, I_type_instr (noPrefixes I_cpobj) - i_initobj, I_type_instr (noPrefixes I_initobj) - i_ldobj, I_type_instr (volatileOrUnalignedPrefix (fun (x, y) z -> I_ldobj (x, y, z))) - i_stobj, I_type_instr (volatileOrUnalignedPrefix (fun (x, y) z -> I_stobj (x, y, z))) - i_sizeof, I_type_instr (noPrefixes I_sizeof) - i_box, I_type_instr (noPrefixes I_box) - i_unbox, I_type_instr (noPrefixes I_unbox) ] - -// The tables are delayed to avoid building them unnecessarily at startup -// Many applications of AbsIL (e.g. a compiler) don't need to read instructions. -let oneByteInstrs = ref None -let twoByteInstrs = ref None -let fillInstrs () = - let oneByteInstrTable = Array.create 256 I_invalid_instr - let twoByteInstrTable = Array.create 256 I_invalid_instr - let addInstr (i, f) = - if i > 0xff then - assert (i >>>& 8 = 0xfe) - let i = (i &&& 0xff) - match twoByteInstrTable.[i] with - | I_invalid_instr -> () - | _ -> dprintn ("warning: duplicate decode entries for "+string i) - twoByteInstrTable.[i] <- f - else - match oneByteInstrTable.[i] with - | I_invalid_instr -> () - | _ -> dprintn ("warning: duplicate decode entries for "+string i) - oneByteInstrTable.[i] <- f - List.iter addInstr (instrs()) - List.iter (fun (x, mk) -> addInstr (x, I_none_instr (noPrefixes mk))) (noArgInstrs.Force()) - oneByteInstrs := Some oneByteInstrTable - twoByteInstrs := Some twoByteInstrTable - -let rec getOneByteInstr i = - match !oneByteInstrs with - | None -> fillInstrs(); getOneByteInstr i - | Some t -> t.[i] - -let rec getTwoByteInstr i = - match !twoByteInstrs with - | None -> fillInstrs(); getTwoByteInstr i - | Some t -> t.[i] - -//--------------------------------------------------------------------- -// -//--------------------------------------------------------------------- - -type ImageChunk = { size: int32; addr: int32 } - -let chunk sz next = ({addr=next; size=sz}, next + sz) -let nochunk next = ({addr= 0x0;size= 0x0; }, next) - -type RowElementKind = - | UShort - | ULong - | Byte - | Data - | GGuid - | Blob - | SString - | SimpleIndex of TableName - | TypeDefOrRefOrSpec - | TypeOrMethodDef - | HasConstant - | HasCustomAttribute - | HasFieldMarshal - | HasDeclSecurity - | MemberRefParent - | HasSemantics - | MethodDefOrRef - | MemberForwarded - | Implementation - | CustomAttributeType - | ResolutionScope - -type RowKind = RowKind of RowElementKind list - -let kindAssemblyRef = RowKind [ UShort; UShort; UShort; UShort; ULong; Blob; SString; SString; Blob; ] -let kindModuleRef = RowKind [ SString ] -let kindFileRef = RowKind [ ULong; SString; Blob ] -let kindTypeRef = RowKind [ ResolutionScope; SString; SString ] -let kindTypeSpec = RowKind [ Blob ] -let kindTypeDef = RowKind [ ULong; SString; SString; TypeDefOrRefOrSpec; SimpleIndex TableNames.Field; SimpleIndex TableNames.Method ] -let kindPropertyMap = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.Property ] -let kindEventMap = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.Event ] -let kindInterfaceImpl = RowKind [ SimpleIndex TableNames.TypeDef; TypeDefOrRefOrSpec ] -let kindNested = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.TypeDef ] -let kindCustomAttribute = RowKind [ HasCustomAttribute; CustomAttributeType; Blob ] -let kindDeclSecurity = RowKind [ UShort; HasDeclSecurity; Blob ] -let kindMemberRef = RowKind [ MemberRefParent; SString; Blob ] -let kindStandAloneSig = RowKind [ Blob ] -let kindFieldDef = RowKind [ UShort; SString; Blob ] -let kindFieldRVA = RowKind [ Data; SimpleIndex TableNames.Field ] -let kindFieldMarshal = RowKind [ HasFieldMarshal; Blob ] -let kindConstant = RowKind [ UShort;HasConstant; Blob ] -let kindFieldLayout = RowKind [ ULong; SimpleIndex TableNames.Field ] -let kindParam = RowKind [ UShort; UShort; SString ] -let kindMethodDef = RowKind [ ULong; UShort; UShort; SString; Blob; SimpleIndex TableNames.Param ] -let kindMethodImpl = RowKind [ SimpleIndex TableNames.TypeDef; MethodDefOrRef; MethodDefOrRef ] -let kindImplMap = RowKind [ UShort; MemberForwarded; SString; SimpleIndex TableNames.ModuleRef ] -let kindMethodSemantics = RowKind [ UShort; SimpleIndex TableNames.Method; HasSemantics ] -let kindProperty = RowKind [ UShort; SString; Blob ] -let kindEvent = RowKind [ UShort; SString; TypeDefOrRefOrSpec ] -let kindManifestResource = RowKind [ ULong; ULong; SString; Implementation ] -let kindClassLayout = RowKind [ UShort; ULong; SimpleIndex TableNames.TypeDef ] -let kindExportedType = RowKind [ ULong; ULong; SString; SString; Implementation ] -let kindAssembly = RowKind [ ULong; UShort; UShort; UShort; UShort; ULong; Blob; SString; SString ] -let kindGenericParam_v1_1 = RowKind [ UShort; UShort; TypeOrMethodDef; SString; TypeDefOrRefOrSpec ] -let kindGenericParam_v2_0 = RowKind [ UShort; UShort; TypeOrMethodDef; SString ] -let kindMethodSpec = RowKind [ MethodDefOrRef; Blob ] -let kindGenericParamConstraint = RowKind [ SimpleIndex TableNames.GenericParam; TypeDefOrRefOrSpec ] -let kindModule = RowKind [ UShort; SString; GGuid; GGuid; GGuid ] -let kindIllegal = RowKind [ ] - -//--------------------------------------------------------------------- -// Used for binary searches of sorted tables. Each function that reads -// a table row returns a tuple that contains the elements of the row. -// One of these elements may be a key for a sorted table. These -// keys can be compared using the functions below depending on the -// kind of element in that column. -//--------------------------------------------------------------------- - -let hcCompare (TaggedIndex((t1: HasConstantTag), (idx1: int))) (TaggedIndex((t2: HasConstantTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let hsCompare (TaggedIndex((t1: HasSemanticsTag), (idx1: int))) (TaggedIndex((t2: HasSemanticsTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let hcaCompare (TaggedIndex((t1: HasCustomAttributeTag), (idx1: int))) (TaggedIndex((t2: HasCustomAttributeTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let mfCompare (TaggedIndex((t1: MemberForwardedTag), (idx1: int))) (TaggedIndex((t2: MemberForwardedTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let hdsCompare (TaggedIndex((t1: HasDeclSecurityTag), (idx1: int))) (TaggedIndex((t2: HasDeclSecurityTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let hfmCompare (TaggedIndex((t1: HasFieldMarshalTag), idx1)) (TaggedIndex((t2: HasFieldMarshalTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let tomdCompare (TaggedIndex((t1: TypeOrMethodDefTag), idx1)) (TaggedIndex((t2: TypeOrMethodDefTag), idx2)) = - if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag - -let simpleIndexCompare (idx1: int) (idx2: int) = - compare idx1 idx2 - -//--------------------------------------------------------------------- -// The various keys for the various caches. -//--------------------------------------------------------------------- - -type TypeDefAsTypIdx = TypeDefAsTypIdx of ILBoxity * ILGenericArgs * int -type TypeRefAsTypIdx = TypeRefAsTypIdx of ILBoxity * ILGenericArgs * int -type BlobAsMethodSigIdx = BlobAsMethodSigIdx of int * int32 -type BlobAsFieldSigIdx = BlobAsFieldSigIdx of int * int32 -type BlobAsPropSigIdx = BlobAsPropSigIdx of int * int32 -type BlobAsLocalSigIdx = BlobAsLocalSigIdx of int * int32 -type MemberRefAsMspecIdx = MemberRefAsMspecIdx of int * int -type MethodSpecAsMspecIdx = MethodSpecAsMspecIdx of int * int -type MemberRefAsFspecIdx = MemberRefAsFspecIdx of int * int -type CustomAttrIdx = CustomAttrIdx of CustomAttributeTypeTag * int * int32 -type GenericParamsIdx = GenericParamsIdx of int * TypeOrMethodDefTag * int - -//--------------------------------------------------------------------- -// Polymorphic caches for row and heap readers -//--------------------------------------------------------------------- - -let mkCacheInt32 lowMem _inbase _nm _sz = - if lowMem then (fun f x -> f x) else - let cache = ref null - let count = ref 0 -#if STATISTICS - addReport (fun oc -> if !count <> 0 then oc.WriteLine ((_inbase + string !count + " "+ _nm + " cache hits"): string)) -#endif - fun f (idx: int32) -> - let cache = - match !cache with - | null -> cache := new Dictionary(11) - | _ -> () - !cache - match cache.TryGetValue idx with - | true, res -> - incr count - res - | _ -> - let res = f idx - cache.[idx] <- res - res - -let mkCacheGeneric lowMem _inbase _nm _sz = - if lowMem then (fun f x -> f x) else - let cache = ref null - let count = ref 0 -#if STATISTICS - addReport (fun oc -> if !count <> 0 then oc.WriteLine ((_inbase + string !count + " " + _nm + " cache hits"): string)) -#endif - fun f (idx :'T) -> - let cache = - match !cache with - | null -> cache := new Dictionary<_, _>(11 (* sz: int *) ) - | _ -> () - !cache - match cache.TryGetValue idx with - | true, v -> - incr count - v - | _ -> - let res = f idx - cache.[idx] <- res - res - -//----------------------------------------------------------------------- -// Polymorphic general helpers for searching for particular rows. -// ---------------------------------------------------------------------- - -let seekFindRow numRows rowChooser = - let mutable i = 1 - while (i <= numRows && not (rowChooser i)) do - i <- i + 1 - if i > numRows then dprintn "warning: seekFindRow: row not found" - i - -// search for rows satisfying predicate -let seekReadIndexedRows (numRows, rowReader, keyFunc, keyComparer, binaryChop, rowConverter) = - if binaryChop then - let mutable low = 0 - let mutable high = numRows + 1 - begin - let mutable fin = false - while not fin do - if high - low <= 1 then - fin <- true - else - let mid = (low + high) / 2 - let midrow = rowReader mid - let c = keyComparer (keyFunc midrow) - if c > 0 then - low <- mid - elif c < 0 then - high <- mid - else - fin <- true - end - let mutable res = [] - if high - low > 1 then - // now read off rows, forward and backwards - let mid = (low + high) / 2 - // read forward - begin - let mutable fin = false - let mutable curr = mid - while not fin do - if curr > numRows then - fin <- true - else - let currrow = rowReader curr - if keyComparer (keyFunc currrow) = 0 then - res <- rowConverter currrow :: res - else - fin <- true - curr <- curr + 1 - done - end - res <- List.rev res - // read backwards - begin - let mutable fin = false - let mutable curr = mid - 1 - while not fin do - if curr = 0 then - fin <- true - else - let currrow = rowReader curr - if keyComparer (keyFunc currrow) = 0 then - res <- rowConverter currrow :: res - else - fin <- true - curr <- curr - 1 - end - // sanity check -#if CHECKING - if checking then - let res2 = - [ for i = 1 to numRows do - let rowinfo = rowReader i - if keyComparer (keyFunc rowinfo) = 0 then - yield rowConverter rowinfo ] - if (res2 <> res) then - failwith ("results of binary search did not match results of linear search: linear search produced "+string res2.Length+", binary search produced "+string res.Length) -#endif - - res - else - let res = ref [] - for i = 1 to numRows do - let rowinfo = rowReader i - if keyComparer (keyFunc rowinfo) = 0 then - res := rowConverter rowinfo :: !res - List.rev !res - - -let seekReadOptionalIndexedRow info = - match seekReadIndexedRows info with - | [k] -> Some k - | [] -> None - | h :: _ -> - dprintn ("multiple rows found when indexing table") - Some h - -let seekReadIndexedRow info = - match seekReadOptionalIndexedRow info with - | Some row -> row - | None -> failwith ("no row found for key when indexing table") - -//--------------------------------------------------------------------- -// The big fat reader. -//--------------------------------------------------------------------- - -type MethodData = MethodData of ILType * ILCallingConv * string * ILTypes * ILType * ILTypes -type VarArgMethodData = VarArgMethodData of ILType * ILCallingConv * string * ILTypes * ILVarArgs * ILType * ILTypes - -[] -type PEReader = - { fileName: string -#if FX_NO_PDB_READER - pdb: obj option -#else - pdb: (PdbReader * (string -> ILSourceDocument)) option -#endif - entryPointToken: TableName * int - pefile: BinaryFile - textSegmentPhysicalLoc: int32 - textSegmentPhysicalSize: int32 - dataSegmentPhysicalLoc: int32 - dataSegmentPhysicalSize: int32 - anyV2P: (string * int32) -> int32 - metadataAddr: int32 - sectionHeaders: (int32 * int32 * int32) list - nativeResourcesAddr: int32 - nativeResourcesSize: int32 - resourcesAddr: int32 - strongnameAddr: int32 - vtableFixupsAddr: int32 - noFileOnDisk: bool -} - -[] -type ILMetadataReader = - { sorted: int64 - mdfile: BinaryFile - pectxtCaptured: PEReader option // only set when reading full PE including code etc. for static linking - entryPointToken: TableName * int - dataEndPoints: Lazy - fileName: string - getNumRows: TableName -> int - userStringsStreamPhysicalLoc: int32 - stringsStreamPhysicalLoc: int32 - blobsStreamPhysicalLoc: int32 - blobsStreamSize: int32 - readUserStringHeap: (int32 -> string) - memoizeString: string -> string - readStringHeap: (int32 -> string) - readBlobHeap: (int32 -> byte[]) - guidsStreamPhysicalLoc: int32 - rowAddr: (TableName -> int -> int32) - tableBigness: bool [] - rsBigness: bool - tdorBigness: bool - tomdBigness: bool - hcBigness: bool - hcaBigness: bool - hfmBigness: bool - hdsBigness: bool - mrpBigness: bool - hsBigness: bool - mdorBigness: bool - mfBigness: bool - iBigness: bool - catBigness: bool - stringsBigness: bool - guidsBigness: bool - blobsBigness: bool - seekReadNestedRow: int -> int * int - seekReadConstantRow: int -> uint16 * TaggedIndex * int32 - seekReadMethodSemanticsRow: int -> int32 * int * TaggedIndex - seekReadTypeDefRow: int -> int32 * int32 * int32 * TaggedIndex * int * int - seekReadAssemblyRef: int -> ILAssemblyRef - seekReadMethodSpecAsMethodData: MethodSpecAsMspecIdx -> VarArgMethodData - seekReadMemberRefAsMethodData: MemberRefAsMspecIdx -> VarArgMethodData - seekReadMemberRefAsFieldSpec: MemberRefAsFspecIdx -> ILFieldSpec - seekReadCustomAttr: CustomAttrIdx -> ILAttribute - seekReadTypeRef: int ->ILTypeRef - seekReadTypeRefAsType: TypeRefAsTypIdx -> ILType - readBlobHeapAsPropertySig: BlobAsPropSigIdx -> ILThisConvention * ILType * ILTypes - readBlobHeapAsFieldSig: BlobAsFieldSigIdx -> ILType - readBlobHeapAsMethodSig: BlobAsMethodSigIdx -> bool * int32 * ILCallingConv * ILType * ILTypes * ILVarArgs - readBlobHeapAsLocalsSig: BlobAsLocalSigIdx -> ILLocal list - seekReadTypeDefAsType: TypeDefAsTypIdx -> ILType - seekReadMethodDefAsMethodData: int -> MethodData - seekReadGenericParams: GenericParamsIdx -> ILGenericParameterDef list - seekReadFieldDefAsFieldSpec: int -> ILFieldSpec - customAttrsReader_Module: ILAttributesStored - customAttrsReader_Assembly: ILAttributesStored - customAttrsReader_TypeDef: ILAttributesStored - customAttrsReader_GenericParam: ILAttributesStored - customAttrsReader_FieldDef: ILAttributesStored - customAttrsReader_MethodDef: ILAttributesStored - customAttrsReader_ParamDef: ILAttributesStored - customAttrsReader_Event: ILAttributesStored - customAttrsReader_Property: ILAttributesStored - customAttrsReader_ManifestResource: ILAttributesStored - customAttrsReader_ExportedType: ILAttributesStored - securityDeclsReader_TypeDef: ILSecurityDeclsStored - securityDeclsReader_MethodDef: ILSecurityDeclsStored - securityDeclsReader_Assembly: ILSecurityDeclsStored - typeDefReader: ILTypeDefStored } - - -let seekReadUInt16Adv mdv (addr: byref) = - let res = seekReadUInt16 mdv addr - addr <- addr + 2 - res - -let seekReadInt32Adv mdv (addr: byref) = - let res = seekReadInt32 mdv addr - addr <- addr+4 - res - -let seekReadUInt16AsInt32Adv mdv (addr: byref) = - let res = seekReadUInt16AsInt32 mdv addr - addr <- addr+2 - res - -let seekReadTaggedIdx f nbits big mdv (addr: byref) = - let tok = if big then seekReadInt32Adv mdv &addr else seekReadUInt16AsInt32Adv mdv &addr - tokToTaggedIdx f nbits tok - - -let seekReadIdx big mdv (addr: byref) = - if big then seekReadInt32Adv mdv &addr else seekReadUInt16AsInt32Adv mdv &addr - -let seekReadUntaggedIdx (tab: TableName) (ctxt: ILMetadataReader) mdv (addr: byref) = - seekReadIdx ctxt.tableBigness.[tab.Index] mdv &addr - - -let seekReadResolutionScopeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkResolutionScopeTag 2 ctxt.rsBigness mdv &addr -let seekReadTypeDefOrRefOrSpecIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkTypeDefOrRefOrSpecTag 2 ctxt.tdorBigness mdv &addr -let seekReadTypeOrMethodDefIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkTypeOrMethodDefTag 1 ctxt.tomdBigness mdv &addr -let seekReadHasConstantIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasConstantTag 2 ctxt.hcBigness mdv &addr -let seekReadHasCustomAttributeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasCustomAttributeTag 5 ctxt.hcaBigness mdv &addr -let seekReadHasFieldMarshalIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasFieldMarshalTag 1 ctxt.hfmBigness mdv &addr -let seekReadHasDeclSecurityIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasDeclSecurityTag 2 ctxt.hdsBigness mdv &addr -let seekReadMemberRefParentIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMemberRefParentTag 3 ctxt.mrpBigness mdv &addr -let seekReadHasSemanticsIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasSemanticsTag 1 ctxt.hsBigness mdv &addr -let seekReadMethodDefOrRefIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMethodDefOrRefTag 1 ctxt.mdorBigness mdv &addr -let seekReadMemberForwardedIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMemberForwardedTag 1 ctxt.mfBigness mdv &addr -let seekReadImplementationIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkImplementationTag 2 ctxt.iBigness mdv &addr -let seekReadCustomAttributeTypeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkILCustomAttributeTypeTag 3 ctxt.catBigness mdv &addr -let seekReadStringIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.stringsBigness mdv &addr -let seekReadGuidIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.guidsBigness mdv &addr -let seekReadBlobIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.blobsBigness mdv &addr - -let seekReadModuleRow (ctxt: ILMetadataReader) mdv idx = - if idx = 0 then failwith "cannot read Module table row 0" - let mutable addr = ctxt.rowAddr TableNames.Module idx - let generation = seekReadUInt16Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let mvidIdx = seekReadGuidIdx ctxt mdv &addr - let encidIdx = seekReadGuidIdx ctxt mdv &addr - let encbaseidIdx = seekReadGuidIdx ctxt mdv &addr - (generation, nameIdx, mvidIdx, encidIdx, encbaseidIdx) - -/// Read Table ILTypeRef. -let seekReadTypeRefRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.TypeRef idx - let scopeIdx = seekReadResolutionScopeIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let namespaceIdx = seekReadStringIdx ctxt mdv &addr - (scopeIdx, nameIdx, namespaceIdx) - -/// Read Table ILTypeDef. -let seekReadTypeDefRow (ctxt: ILMetadataReader) idx = ctxt.seekReadTypeDefRow idx -let seekReadTypeDefRowUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let mutable addr = ctxt.rowAddr TableNames.TypeDef idx - let flags = seekReadInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let namespaceIdx = seekReadStringIdx ctxt mdv &addr - let extendsIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr - let fieldsIdx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr - let methodsIdx = seekReadUntaggedIdx TableNames.Method ctxt mdv &addr - (flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) - -/// Read Table Field. -let seekReadFieldRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Field idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let typeIdx = seekReadBlobIdx ctxt mdv &addr - (flags, nameIdx, typeIdx) - -/// Read Table Method. -let seekReadMethodRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Method idx - let codeRVA = seekReadInt32Adv mdv &addr - let implflags = seekReadUInt16AsInt32Adv mdv &addr - let flags = seekReadUInt16AsInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let typeIdx = seekReadBlobIdx ctxt mdv &addr - let paramIdx = seekReadUntaggedIdx TableNames.Param ctxt mdv &addr - (codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) - -/// Read Table Param. -let seekReadParamRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Param idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let seq = seekReadUInt16AsInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - (flags, seq, nameIdx) - -/// Read Table InterfaceImpl. -let seekReadInterfaceImplRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.InterfaceImpl idx - let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - let intfIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr - (tidx, intfIdx) - -/// Read Table MemberRef. -let seekReadMemberRefRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.MemberRef idx - let mrpIdx = seekReadMemberRefParentIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let typeIdx = seekReadBlobIdx ctxt mdv &addr - (mrpIdx, nameIdx, typeIdx) - -/// Read Table Constant. -let seekReadConstantRow (ctxt: ILMetadataReader) idx = ctxt.seekReadConstantRow idx -let seekReadConstantRowUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let mutable addr = ctxt.rowAddr TableNames.Constant idx - let kind = seekReadUInt16Adv mdv &addr - let parentIdx = seekReadHasConstantIdx ctxt mdv &addr - let valIdx = seekReadBlobIdx ctxt mdv &addr - (kind, parentIdx, valIdx) - -/// Read Table CustomAttribute. -let seekReadCustomAttributeRow (ctxt: ILMetadataReader) idx = - let mdv = ctxt.mdfile.GetView() - let mutable addr = ctxt.rowAddr TableNames.CustomAttribute idx - let parentIdx = seekReadHasCustomAttributeIdx ctxt mdv &addr - let typeIdx = seekReadCustomAttributeTypeIdx ctxt mdv &addr - let valIdx = seekReadBlobIdx ctxt mdv &addr - (parentIdx, typeIdx, valIdx) - -/// Read Table FieldMarshal. -let seekReadFieldMarshalRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.FieldMarshal idx - let parentIdx = seekReadHasFieldMarshalIdx ctxt mdv &addr - let typeIdx = seekReadBlobIdx ctxt mdv &addr - (parentIdx, typeIdx) - -/// Read Table Permission. -let seekReadPermissionRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Permission idx - let action = seekReadUInt16Adv mdv &addr - let parentIdx = seekReadHasDeclSecurityIdx ctxt mdv &addr - let typeIdx = seekReadBlobIdx ctxt mdv &addr - (action, parentIdx, typeIdx) - -/// Read Table ClassLayout. -let seekReadClassLayoutRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.ClassLayout idx - let pack = seekReadUInt16Adv mdv &addr - let size = seekReadInt32Adv mdv &addr - let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - (pack, size, tidx) - -/// Read Table FieldLayout. -let seekReadFieldLayoutRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.FieldLayout idx - let offset = seekReadInt32Adv mdv &addr - let fidx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr - (offset, fidx) - -//// Read Table StandAloneSig. -let seekReadStandAloneSigRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.StandAloneSig idx - let sigIdx = seekReadBlobIdx ctxt mdv &addr - sigIdx - -/// Read Table EventMap. -let seekReadEventMapRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.EventMap idx - let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - let eventsIdx = seekReadUntaggedIdx TableNames.Event ctxt mdv &addr - (tidx, eventsIdx) - -/// Read Table Event. -let seekReadEventRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Event idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let typIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr - (flags, nameIdx, typIdx) - -/// Read Table PropertyMap. -let seekReadPropertyMapRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.PropertyMap idx - let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - let propsIdx = seekReadUntaggedIdx TableNames.Property ctxt mdv &addr - (tidx, propsIdx) - -/// Read Table Property. -let seekReadPropertyRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Property idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let typIdx = seekReadBlobIdx ctxt mdv &addr - (flags, nameIdx, typIdx) - -/// Read Table MethodSemantics. -let seekReadMethodSemanticsRow (ctxt: ILMetadataReader) idx = ctxt.seekReadMethodSemanticsRow idx -let seekReadMethodSemanticsRowUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let mutable addr = ctxt.rowAddr TableNames.MethodSemantics idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let midx = seekReadUntaggedIdx TableNames.Method ctxt mdv &addr - let assocIdx = seekReadHasSemanticsIdx ctxt mdv &addr - (flags, midx, assocIdx) - -/// Read Table MethodImpl. -let seekReadMethodImplRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.MethodImpl idx - let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - let mbodyIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr - let mdeclIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr - (tidx, mbodyIdx, mdeclIdx) - -/// Read Table ILModuleRef. -let seekReadModuleRefRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.ModuleRef idx - let nameIdx = seekReadStringIdx ctxt mdv &addr - nameIdx - -/// Read Table ILTypeSpec. -let seekReadTypeSpecRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.TypeSpec idx - let blobIdx = seekReadBlobIdx ctxt mdv &addr - blobIdx - -/// Read Table ImplMap. -let seekReadImplMapRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.ImplMap idx - let flags = seekReadUInt16AsInt32Adv mdv &addr - let forwrdedIdx = seekReadMemberForwardedIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let scopeIdx = seekReadUntaggedIdx TableNames.ModuleRef ctxt mdv &addr - (flags, forwrdedIdx, nameIdx, scopeIdx) - -/// Read Table FieldRVA. -let seekReadFieldRVARow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.FieldRVA idx - let rva = seekReadInt32Adv mdv &addr - let fidx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr - (rva, fidx) - -/// Read Table Assembly. -let seekReadAssemblyRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.Assembly idx - let hash = seekReadInt32Adv mdv &addr - let v1 = seekReadUInt16Adv mdv &addr - let v2 = seekReadUInt16Adv mdv &addr - let v3 = seekReadUInt16Adv mdv &addr - let v4 = seekReadUInt16Adv mdv &addr - let flags = seekReadInt32Adv mdv &addr - let publicKeyIdx = seekReadBlobIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let localeIdx = seekReadStringIdx ctxt mdv &addr - (hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx) - -/// Read Table ILAssemblyRef. -let seekReadAssemblyRefRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.AssemblyRef idx - let v1 = seekReadUInt16Adv mdv &addr - let v2 = seekReadUInt16Adv mdv &addr - let v3 = seekReadUInt16Adv mdv &addr - let v4 = seekReadUInt16Adv mdv &addr - let flags = seekReadInt32Adv mdv &addr - let publicKeyOrTokenIdx = seekReadBlobIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let localeIdx = seekReadStringIdx ctxt mdv &addr - let hashValueIdx = seekReadBlobIdx ctxt mdv &addr - (v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx) - -/// Read Table File. -let seekReadFileRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.File idx - let flags = seekReadInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let hashValueIdx = seekReadBlobIdx ctxt mdv &addr - (flags, nameIdx, hashValueIdx) - -/// Read Table ILExportedTypeOrForwarder. -let seekReadExportedTypeRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.ExportedType idx - let flags = seekReadInt32Adv mdv &addr - let tok = seekReadInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let namespaceIdx = seekReadStringIdx ctxt mdv &addr - let implIdx = seekReadImplementationIdx ctxt mdv &addr - (flags, tok, nameIdx, namespaceIdx, implIdx) - -/// Read Table ManifestResource. -let seekReadManifestResourceRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.ManifestResource idx - let offset = seekReadInt32Adv mdv &addr - let flags = seekReadInt32Adv mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - let implIdx = seekReadImplementationIdx ctxt mdv &addr - (offset, flags, nameIdx, implIdx) - -/// Read Table Nested. -let seekReadNestedRow (ctxt: ILMetadataReader) idx = ctxt.seekReadNestedRow idx -let seekReadNestedRowUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let mutable addr = ctxt.rowAddr TableNames.Nested idx - let nestedIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - let enclIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr - (nestedIdx, enclIdx) - -/// Read Table GenericParam. -let seekReadGenericParamRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.GenericParam idx - let seq = seekReadUInt16Adv mdv &addr - let flags = seekReadUInt16Adv mdv &addr - let ownerIdx = seekReadTypeOrMethodDefIdx ctxt mdv &addr - let nameIdx = seekReadStringIdx ctxt mdv &addr - (idx, seq, flags, ownerIdx, nameIdx) - -// Read Table GenericParamConstraint. -let seekReadGenericParamConstraintRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.GenericParamConstraint idx - let pidx = seekReadUntaggedIdx TableNames.GenericParam ctxt mdv &addr - let constraintIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr - (pidx, constraintIdx) - -/// Read Table ILMethodSpec. -let seekReadMethodSpecRow (ctxt: ILMetadataReader) mdv idx = - let mutable addr = ctxt.rowAddr TableNames.MethodSpec idx - let mdorIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr - let instIdx = seekReadBlobIdx ctxt mdv &addr - (mdorIdx, instIdx) - - -let readUserStringHeapUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - seekReadUserString mdv (ctxt.userStringsStreamPhysicalLoc + idx) - -let readUserStringHeap (ctxt: ILMetadataReader) idx = ctxt.readUserStringHeap idx - -let readStringHeapUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - seekReadUTF8String mdv (ctxt.stringsStreamPhysicalLoc + idx) - -let readStringHeap (ctxt: ILMetadataReader) idx = ctxt.readStringHeap idx - -let readStringHeapOption (ctxt: ILMetadataReader) idx = if idx = 0 then None else Some (readStringHeap ctxt idx) - -let emptyByteArray: byte[] = [||] - -let readBlobHeapUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - // valid index lies in range [1..streamSize) - // NOTE: idx cannot be 0 - Blob\String heap has first empty element that mdv one byte 0 - if idx <= 0 || idx >= ctxt.blobsStreamSize then emptyByteArray - else seekReadBlob mdv (ctxt.blobsStreamPhysicalLoc + idx) - -let readBlobHeap (ctxt: ILMetadataReader) idx = ctxt.readBlobHeap idx - -let readBlobHeapOption ctxt idx = if idx = 0 then None else Some (readBlobHeap ctxt idx) - -//let readGuidHeap ctxt idx = seekReadGuid ctxt.mdv (ctxt.guidsStreamPhysicalLoc + idx) - -// read a single value out of a blob heap using the given function -let readBlobHeapAsBool ctxt vidx = fst (sigptrGetBool (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsSByte ctxt vidx = fst (sigptrGetSByte (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsInt16 ctxt vidx = fst (sigptrGetInt16 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsInt32 ctxt vidx = fst (sigptrGetInt32 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsInt64 ctxt vidx = fst (sigptrGetInt64 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsByte ctxt vidx = fst (sigptrGetByte (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsUInt16 ctxt vidx = fst (sigptrGetUInt16 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsUInt32 ctxt vidx = fst (sigptrGetUInt32 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsUInt64 ctxt vidx = fst (sigptrGetUInt64 (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsSingle ctxt vidx = fst (sigptrGetSingle (readBlobHeap ctxt vidx) 0) -let readBlobHeapAsDouble ctxt vidx = fst (sigptrGetDouble (readBlobHeap ctxt vidx) 0) - -//----------------------------------------------------------------------- -// Some binaries have raw data embedded their text sections, e.g. mscorlib, for -// field inits. And there is no information that definitively tells us the extent of -// the text section that may be interesting data. But we certainly don't want to duplicate -// the entire text section as data! -// -// So, we assume: -// 1. no part of the metadata is double-used for raw data -// 2. the data bits are all the bits of the text section -// that stretch from a Field or Resource RVA to one of -// (a) the next Field or resource RVA -// (b) a MethodRVA -// (c) the start of the metadata -// (d) the end of a section -// (e) the start of the native resources attached to the binary if any -// ----------------------------------------------------------------------*) - -// noFileOnDisk indicates that the PE file was read from Memory using OpenILModuleReaderFromBytes -// For example the assembly came from a type provider -// In this case we eagerly read the native resources into memory -let readNativeResources (pectxt: PEReader) = - [ if pectxt.nativeResourcesSize <> 0x0 && pectxt.nativeResourcesAddr <> 0x0 then - let start = pectxt.anyV2P (pectxt.fileName + ": native resources", pectxt.nativeResourcesAddr) - if pectxt.noFileOnDisk then - let unlinkedResource = - let linkedResource = seekReadBytes (pectxt.pefile.GetView()) start pectxt.nativeResourcesSize - unlinkResource pectxt.nativeResourcesAddr linkedResource - yield ILNativeResource.Out unlinkedResource - else - yield ILNativeResource.In (pectxt.fileName, pectxt.nativeResourcesAddr, start, pectxt.nativeResourcesSize ) ] - - -let getDataEndPointsDelayed (pectxt: PEReader) ctxtH = - lazy - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let dataStartPoints = - let res = ref [] - for i = 1 to ctxt.getNumRows TableNames.FieldRVA do - let rva, _fidx = seekReadFieldRVARow ctxt mdv i - res := ("field", rva) :: !res - for i = 1 to ctxt.getNumRows TableNames.ManifestResource do - let (offset, _, _, TaggedIndex(_tag, idx)) = seekReadManifestResourceRow ctxt mdv i - if idx = 0 then - let rva = pectxt.resourcesAddr + offset - res := ("manifest resource", rva) :: !res - !res - if isNil dataStartPoints then [] - else - let methodRVAs = - let res = ref [] - for i = 1 to ctxt.getNumRows TableNames.Method do - let (rva, _, _, nameIdx, _, _) = seekReadMethodRow ctxt mdv i - if rva <> 0 then - let nm = readStringHeap ctxt nameIdx - res := (nm, rva) :: !res - !res - ([ pectxt.textSegmentPhysicalLoc + pectxt.textSegmentPhysicalSize - pectxt.dataSegmentPhysicalLoc + pectxt.dataSegmentPhysicalSize ] - @ - (List.map pectxt.anyV2P - (dataStartPoints - @ [for (virtAddr, _virtSize, _physLoc) in pectxt.sectionHeaders do yield ("section start", virtAddr) done] - @ [("md", pectxt.metadataAddr)] - @ (if pectxt.nativeResourcesAddr = 0x0 then [] else [("native resources", pectxt.nativeResourcesAddr) ]) - @ (if pectxt.resourcesAddr = 0x0 then [] else [("managed resources", pectxt.resourcesAddr) ]) - @ (if pectxt.strongnameAddr = 0x0 then [] else [("managed strongname", pectxt.strongnameAddr) ]) - @ (if pectxt.vtableFixupsAddr = 0x0 then [] else [("managed vtable_fixups", pectxt.vtableFixupsAddr) ]) - @ methodRVAs))) - |> List.distinct - |> List.sort - - -let rvaToData (ctxt: ILMetadataReader) (pectxt: PEReader) nm rva = - if rva = 0x0 then failwith "rva is zero" - let start = pectxt.anyV2P (nm, rva) - let endPoints = (Lazy.force ctxt.dataEndPoints) - let rec look l = - match l with - | [] -> - failwithf "find_text_data_extent: none found for fileName=%s, name=%s, rva=0x%08x, start=0x%08x" ctxt.fileName nm rva start - | e :: t -> - if start < e then - let pev = pectxt.pefile.GetView() - seekReadBytes pev start (e - start) - else look t - look endPoints - - -//----------------------------------------------------------------------- -// Read the AbsIL structure (lazily) by reading off the relevant rows. -// ---------------------------------------------------------------------- - -let isSorted (ctxt: ILMetadataReader) (tab: TableName) = ((ctxt.sorted &&& (int64 1 <<< tab.Index)) <> int64 0x0) - -// Note, pectxtEager and pevEager must not be captured by the results of this function -let rec seekReadModule (ctxt: ILMetadataReader) canReduceMemory (pectxtEager: PEReader) pevEager peinfo ilMetadataVersion idx = - let (subsys, subsysversion, useHighEntropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal) = peinfo - let mdv = ctxt.mdfile.GetView() - let (_generation, nameIdx, _mvidIdx, _encidIdx, _encbaseidIdx) = seekReadModuleRow ctxt mdv idx - let ilModuleName = readStringHeap ctxt nameIdx - let nativeResources = readNativeResources pectxtEager - - { Manifest = - if ctxt.getNumRows TableNames.Assembly > 0 then Some (seekReadAssemblyManifest ctxt pectxtEager 1) - else None - CustomAttrsStored = ctxt.customAttrsReader_Module - MetadataIndex = idx - Name = ilModuleName - NativeResources=nativeResources - TypeDefs = mkILTypeDefsComputed (fun () -> seekReadTopTypeDefs ctxt) - SubSystemFlags = int32 subsys - IsILOnly = ilOnly - SubsystemVersion = subsysversion - UseHighEntropyVA = useHighEntropyVA - Platform = platform - StackReserveSize = None // TODO - Is32Bit = only32 - Is32BitPreferred = is32bitpreferred - Is64Bit = only64 - IsDLL=isDll - VirtualAlignment = alignVirt - PhysicalAlignment = alignPhys - ImageBase = imageBaseReal - MetadataVersion = ilMetadataVersion - Resources = seekReadManifestResources ctxt canReduceMemory mdv pectxtEager pevEager } - -and seekReadAssemblyManifest (ctxt: ILMetadataReader) pectxt idx = - let mdview = ctxt.mdfile.GetView() - let (hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx) = seekReadAssemblyRow ctxt mdview idx - let name = readStringHeap ctxt nameIdx - let pubkey = readBlobHeapOption ctxt publicKeyIdx - { Name= name - AuxModuleHashAlgorithm=hash - SecurityDeclsStored= ctxt.securityDeclsReader_Assembly - PublicKey= pubkey - Version= Some (ILVersionInfo (v1, v2, v3, v4)) - Locale= readStringHeapOption ctxt localeIdx - CustomAttrsStored = ctxt.customAttrsReader_Assembly - MetadataIndex = idx - AssemblyLongevity = - let masked = flags &&& 0x000e - if masked = 0x0000 then ILAssemblyLongevity.Unspecified - elif masked = 0x0002 then ILAssemblyLongevity.Library - elif masked = 0x0004 then ILAssemblyLongevity.PlatformAppDomain - elif masked = 0x0006 then ILAssemblyLongevity.PlatformProcess - elif masked = 0x0008 then ILAssemblyLongevity.PlatformSystem - else ILAssemblyLongevity.Unspecified - ExportedTypes= seekReadTopExportedTypes ctxt - EntrypointElsewhere= - let (tab, tok) = pectxt.entryPointToken - if tab = TableNames.File then Some (seekReadFile ctxt mdview tok) else None - Retargetable = 0 <> (flags &&& 0x100) - DisableJitOptimizations = 0 <> (flags &&& 0x4000) - JitTracking = 0 <> (flags &&& 0x8000) - IgnoreSymbolStoreSequencePoints = 0 <> (flags &&& 0x2000) } - -and seekReadAssemblyRef (ctxt: ILMetadataReader) idx = ctxt.seekReadAssemblyRef idx -and seekReadAssemblyRefUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let (v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx) = seekReadAssemblyRefRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - let publicKey = - match readBlobHeapOption ctxt publicKeyOrTokenIdx with - | None -> None - | Some blob -> Some (if (flags &&& 0x0001) <> 0x0 then PublicKey blob else PublicKeyToken blob) - - ILAssemblyRef.Create - (name = nm, - hash = readBlobHeapOption ctxt hashValueIdx, - publicKey = publicKey, - retargetable = ((flags &&& 0x0100) <> 0x0), - version = Some (ILVersionInfo (v1, v2, v3, v4)), - locale = readStringHeapOption ctxt localeIdx) - -and seekReadModuleRef (ctxt: ILMetadataReader) mdv idx = - let nameIdx = seekReadModuleRefRow ctxt mdv idx - ILModuleRef.Create(name = readStringHeap ctxt nameIdx, hasMetadata=true, hash=None) - -and seekReadFile (ctxt: ILMetadataReader) mdv idx = - let (flags, nameIdx, hashValueIdx) = seekReadFileRow ctxt mdv idx - ILModuleRef.Create(name = readStringHeap ctxt nameIdx, hasMetadata= ((flags &&& 0x0001) = 0x0), hash= readBlobHeapOption ctxt hashValueIdx) - -and seekReadClassLayout (ctxt: ILMetadataReader) mdv idx = - match seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.ClassLayout, seekReadClassLayoutRow ctxt mdv, (fun (_, _, tidx) -> tidx), simpleIndexCompare idx, isSorted ctxt TableNames.ClassLayout, (fun (pack, size, _) -> pack, size)) with - | None -> { Size = None; Pack = None } - | Some (pack, size) -> { Size = Some size; Pack = Some pack } - -and typeAccessOfFlags flags = - let f = (flags &&& 0x00000007) - if f = 0x00000001 then ILTypeDefAccess.Public - elif f = 0x00000002 then ILTypeDefAccess.Nested ILMemberAccess.Public - elif f = 0x00000003 then ILTypeDefAccess.Nested ILMemberAccess.Private - elif f = 0x00000004 then ILTypeDefAccess.Nested ILMemberAccess.Family - elif f = 0x00000006 then ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly - elif f = 0x00000007 then ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly - elif f = 0x00000005 then ILTypeDefAccess.Nested ILMemberAccess.Assembly - else ILTypeDefAccess.Private - -and typeLayoutOfFlags (ctxt: ILMetadataReader) mdv flags tidx = - let f = (flags &&& 0x00000018) - if f = 0x00000008 then ILTypeDefLayout.Sequential (seekReadClassLayout ctxt mdv tidx) - elif f = 0x00000010 then ILTypeDefLayout.Explicit (seekReadClassLayout ctxt mdv tidx) - else ILTypeDefLayout.Auto - -and isTopTypeDef flags = - (typeAccessOfFlags flags = ILTypeDefAccess.Private) || - typeAccessOfFlags flags = ILTypeDefAccess.Public - -and seekIsTopTypeDefOfIdx ctxt idx = - let (flags, _, _, _, _, _) = seekReadTypeDefRow ctxt idx - isTopTypeDef flags - -and readBlobHeapAsSplitTypeName ctxt (nameIdx, namespaceIdx) = - let name = readStringHeap ctxt nameIdx - let nspace = readStringHeapOption ctxt namespaceIdx - match nspace with - | Some nspace -> splitNamespace nspace, name - | None -> [], name - -and readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) = - let name = readStringHeap ctxt nameIdx - let nspace = readStringHeapOption ctxt namespaceIdx - match nspace with - | None -> name - | Some ns -> ctxt.memoizeString (ns+"."+name) - -and seekReadTypeDefRowExtents (ctxt: ILMetadataReader) _info (idx: int) = - if idx >= ctxt.getNumRows TableNames.TypeDef then - ctxt.getNumRows TableNames.Field + 1, - ctxt.getNumRows TableNames.Method + 1 - else - let (_, _, _, _, fieldsIdx, methodsIdx) = seekReadTypeDefRow ctxt (idx + 1) - fieldsIdx, methodsIdx - -and seekReadTypeDefRowWithExtents ctxt (idx: int) = - let info= seekReadTypeDefRow ctxt idx - info, seekReadTypeDefRowExtents ctxt info idx - -and seekReadPreTypeDef ctxt toponly (idx: int) = - let (flags, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow ctxt idx - if toponly && not (isTopTypeDef flags) then None - else - let ns, n = readBlobHeapAsSplitTypeName ctxt (nameIdx, namespaceIdx) - // Return the ILPreTypeDef - Some (mkILPreTypeDefRead (ns, n, idx, ctxt.typeDefReader)) - -and typeDefReader ctxtH: ILTypeDefStored = - mkILTypeDefReader - (fun idx -> - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - // Re-read so as not to save all these in the lazy closure - this suspension ctxt.is the largest - // heavily allocated one in all of AbsIL - - let ((flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) as info) = seekReadTypeDefRow ctxt idx - let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) - let (endFieldsIdx, endMethodsIdx) = seekReadTypeDefRowExtents ctxt info idx - let typars = seekReadGenericParams ctxt 0 (tomd_TypeDef, idx) - let numtypars = typars.Length - let super = seekReadOptionalTypeDefOrRef ctxt numtypars AsObject extendsIdx - let layout = typeLayoutOfFlags ctxt mdv flags idx - let hasLayout = (match layout with ILTypeDefLayout.Explicit _ -> true | _ -> false) - let mdefs = seekReadMethods ctxt numtypars methodsIdx endMethodsIdx - let fdefs = seekReadFields ctxt (numtypars, hasLayout) fieldsIdx endFieldsIdx - let nested = seekReadNestedTypeDefs ctxt idx - let impls = seekReadInterfaceImpls ctxt mdv numtypars idx - let mimpls = seekReadMethodImpls ctxt numtypars idx - let props = seekReadProperties ctxt numtypars idx - let events = seekReadEvents ctxt numtypars idx - ILTypeDef(name=nm, - genericParams=typars, - attributes= enum(flags), - layout = layout, - nestedTypes= nested, - implements = impls, - extends = super, - methods = mdefs, - securityDeclsStored = ctxt.securityDeclsReader_TypeDef, - fields=fdefs, - methodImpls=mimpls, - events= events, - properties=props, - customAttrsStored=ctxt.customAttrsReader_TypeDef, - metadataIndex=idx) - ) - -and seekReadTopTypeDefs (ctxt: ILMetadataReader) = - [| for i = 1 to ctxt.getNumRows TableNames.TypeDef do - match seekReadPreTypeDef ctxt true i with - | None -> () - | Some td -> yield td |] - -and seekReadNestedTypeDefs (ctxt: ILMetadataReader) tidx = - mkILTypeDefsComputed (fun () -> - let nestedIdxs = seekReadIndexedRows (ctxt.getNumRows TableNames.Nested, seekReadNestedRow ctxt, snd, simpleIndexCompare tidx, false, fst) - [| for i in nestedIdxs do - match seekReadPreTypeDef ctxt false i with - | None -> () - | Some td -> yield td |]) - -and seekReadInterfaceImpls (ctxt: ILMetadataReader) mdv numtypars tidx = - seekReadIndexedRows (ctxt.getNumRows TableNames.InterfaceImpl, - seekReadInterfaceImplRow ctxt mdv, - fst, - simpleIndexCompare tidx, - isSorted ctxt TableNames.InterfaceImpl, - (snd >> seekReadTypeDefOrRef ctxt numtypars AsObject (*ok*) List.empty)) - -and seekReadGenericParams ctxt numtypars (a, b): ILGenericParameterDefs = - ctxt.seekReadGenericParams (GenericParamsIdx(numtypars, a, b)) - -and seekReadGenericParamsUncached ctxtH (GenericParamsIdx(numtypars, a, b)) = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let pars = - seekReadIndexedRows - (ctxt.getNumRows TableNames.GenericParam, seekReadGenericParamRow ctxt mdv, - (fun (_, _, _, tomd, _) -> tomd), - tomdCompare (TaggedIndex(a, b)), - isSorted ctxt TableNames.GenericParam, - (fun (gpidx, seq, flags, _, nameIdx) -> - let flags = int32 flags - let variance_flags = flags &&& 0x0003 - let variance = - if variance_flags = 0x0000 then NonVariant - elif variance_flags = 0x0001 then CoVariant - elif variance_flags = 0x0002 then ContraVariant - else NonVariant - let constraints = seekReadGenericParamConstraints ctxt mdv numtypars gpidx - seq, {Name=readStringHeap ctxt nameIdx - Constraints = constraints - Variance=variance - CustomAttrsStored = ctxt.customAttrsReader_GenericParam - MetadataIndex=gpidx - HasReferenceTypeConstraint= (flags &&& 0x0004) <> 0 - HasNotNullableValueTypeConstraint= (flags &&& 0x0008) <> 0 - HasDefaultConstructorConstraint=(flags &&& 0x0010) <> 0 })) - pars |> List.sortBy fst |> List.map snd - -and seekReadGenericParamConstraints (ctxt: ILMetadataReader) mdv numtypars gpidx = - seekReadIndexedRows - (ctxt.getNumRows TableNames.GenericParamConstraint, - seekReadGenericParamConstraintRow ctxt mdv, - fst, - simpleIndexCompare gpidx, - isSorted ctxt TableNames.GenericParamConstraint, - (snd >> seekReadTypeDefOrRef ctxt numtypars AsObject (*ok*) List.empty)) - -and seekReadTypeDefAsType (ctxt: ILMetadataReader) boxity (ginst: ILTypes) idx = - ctxt.seekReadTypeDefAsType (TypeDefAsTypIdx (boxity, ginst, idx)) - -and seekReadTypeDefAsTypeUncached ctxtH (TypeDefAsTypIdx (boxity, ginst, idx)) = - let ctxt = getHole ctxtH - mkILTy boxity (ILTypeSpec.Create(seekReadTypeDefAsTypeRef ctxt idx, ginst)) - -and seekReadTypeDefAsTypeRef (ctxt: ILMetadataReader) idx = - let enc = - if seekIsTopTypeDefOfIdx ctxt idx then [] - else - let enclIdx = seekReadIndexedRow (ctxt.getNumRows TableNames.Nested, seekReadNestedRow ctxt, fst, simpleIndexCompare idx, isSorted ctxt TableNames.Nested, snd) - let tref = seekReadTypeDefAsTypeRef ctxt enclIdx - tref.Enclosing@[tref.Name] - let (_, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow ctxt idx - let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) - ILTypeRef.Create(scope=ILScopeRef.Local, enclosing=enc, name = nm ) - -and seekReadTypeRef (ctxt: ILMetadataReader) idx = ctxt.seekReadTypeRef idx -and seekReadTypeRefUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let scopeIdx, nameIdx, namespaceIdx = seekReadTypeRefRow ctxt mdv idx - let scope, enc = seekReadTypeRefScope ctxt mdv scopeIdx - let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) - ILTypeRef.Create(scope=scope, enclosing=enc, name = nm) - -and seekReadTypeRefAsType (ctxt: ILMetadataReader) boxity ginst idx = ctxt.seekReadTypeRefAsType (TypeRefAsTypIdx (boxity, ginst, idx)) -and seekReadTypeRefAsTypeUncached ctxtH (TypeRefAsTypIdx (boxity, ginst, idx)) = - let ctxt = getHole ctxtH - mkILTy boxity (ILTypeSpec.Create(seekReadTypeRef ctxt idx, ginst)) - -and seekReadTypeDefOrRef (ctxt: ILMetadataReader) numtypars boxity (ginst: ILTypes) (TaggedIndex(tag, idx) ) = - let mdv = ctxt.mdfile.GetView() - match tag with - | tag when tag = tdor_TypeDef -> seekReadTypeDefAsType ctxt boxity ginst idx - | tag when tag = tdor_TypeRef -> seekReadTypeRefAsType ctxt boxity ginst idx - | tag when tag = tdor_TypeSpec -> - if not (List.isEmpty ginst) then dprintn ("type spec used as type constructor for a generic instantiation: ignoring instantiation") - readBlobHeapAsType ctxt numtypars (seekReadTypeSpecRow ctxt mdv idx) - | _ -> failwith "seekReadTypeDefOrRef ctxt" - -and seekReadTypeDefOrRefAsTypeRef (ctxt: ILMetadataReader) (TaggedIndex(tag, idx) ) = - match tag with - | tag when tag = tdor_TypeDef -> seekReadTypeDefAsTypeRef ctxt idx - | tag when tag = tdor_TypeRef -> seekReadTypeRef ctxt idx - | tag when tag = tdor_TypeSpec -> - dprintn ("type spec used where a type ref or def is required") - primaryAssemblyILGlobals.typ_Object.TypeRef - | _ -> failwith "seekReadTypeDefOrRefAsTypeRef_readTypeDefOrRefOrSpec" - -and seekReadMethodRefParent (ctxt: ILMetadataReader) mdv numtypars (TaggedIndex(tag, idx)) = - match tag with - | tag when tag = mrp_TypeRef -> seekReadTypeRefAsType ctxt AsObject (* not ok - no way to tell if a member ref parent is a value type or not *) List.empty idx - | tag when tag = mrp_ModuleRef -> mkILTypeForGlobalFunctions (ILScopeRef.Module (seekReadModuleRef ctxt mdv idx)) - | tag when tag = mrp_MethodDef -> - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx - let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - mspec.DeclaringType - | tag when tag = mrp_TypeSpec -> readBlobHeapAsType ctxt numtypars (seekReadTypeSpecRow ctxt mdv idx) - | _ -> failwith "seekReadMethodRefParent" - -and seekReadMethodDefOrRef (ctxt: ILMetadataReader) numtypars (TaggedIndex(tag, idx)) = - match tag with - | tag when tag = mdor_MethodDef -> - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx - VarArgMethodData(enclTy, cc, nm, argtys, None, retty, minst) - | tag when tag = mdor_MemberRef -> - seekReadMemberRefAsMethodData ctxt numtypars idx - | _ -> failwith "seekReadMethodDefOrRef" - -and seekReadMethodDefOrRefNoVarargs (ctxt: ILMetadataReader) numtypars x = - let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = seekReadMethodDefOrRef ctxt numtypars x - if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" - MethodData(enclTy, cc, nm, argtys, retty, minst) - -and seekReadCustomAttrType (ctxt: ILMetadataReader) (TaggedIndex(tag, idx) ) = - match tag with - | tag when tag = cat_MethodDef -> - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx - mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - | tag when tag = cat_MemberRef -> - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMemberRefAsMethDataNoVarArgs ctxt 0 idx - mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - | _ -> failwith "seekReadCustomAttrType ctxt" - -and seekReadImplAsScopeRef (ctxt: ILMetadataReader) mdv (TaggedIndex(tag, idx) ) = - if idx = 0 then ILScopeRef.Local - else - match tag with - | tag when tag = i_File -> ILScopeRef.Module (seekReadFile ctxt mdv idx) - | tag when tag = i_AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef ctxt idx) - | tag when tag = i_ExportedType -> failwith "seekReadImplAsScopeRef" - | _ -> failwith "seekReadImplAsScopeRef" - -and seekReadTypeRefScope (ctxt: ILMetadataReader) mdv (TaggedIndex(tag, idx) ) = - match tag with - | tag when tag = rs_Module -> ILScopeRef.Local, [] - | tag when tag = rs_ModuleRef -> ILScopeRef.Module (seekReadModuleRef ctxt mdv idx), [] - | tag when tag = rs_AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef ctxt idx), [] - | tag when tag = rs_TypeRef -> - let tref = seekReadTypeRef ctxt idx - tref.Scope, (tref.Enclosing@[tref.Name]) - | _ -> failwith "seekReadTypeRefScope" - -and seekReadOptionalTypeDefOrRef (ctxt: ILMetadataReader) numtypars boxity idx = - if idx = TaggedIndex(tdor_TypeDef, 0) then None - else Some (seekReadTypeDefOrRef ctxt numtypars boxity List.empty idx) - -and seekReadField ctxt mdv (numtypars, hasLayout) (idx: int) = - let (flags, nameIdx, typeIdx) = seekReadFieldRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - let isStatic = (flags &&& 0x0010) <> 0 - ILFieldDef(name = nm, - fieldType= readBlobHeapAsFieldSig ctxt numtypars typeIdx, - attributes = enum(flags), - literalValue = (if (flags &&& 0x8000) = 0 then None else Some (seekReadConstant ctxt (TaggedIndex(hc_FieldDef, idx)))), - marshal = - (if (flags &&& 0x1000) = 0 then - None - else - Some (seekReadIndexedRow (ctxt.getNumRows TableNames.FieldMarshal, seekReadFieldMarshalRow ctxt mdv, - fst, hfmCompare (TaggedIndex(hfm_FieldDef, idx)), - isSorted ctxt TableNames.FieldMarshal, - (snd >> readBlobHeapAsNativeType ctxt)))), - data = - (if (flags &&& 0x0100) = 0 then - None - else - match ctxt.pectxtCaptured with - | None -> None // indicates metadata only, where Data is not available - | Some pectxt -> - let rva = seekReadIndexedRow (ctxt.getNumRows TableNames.FieldRVA, seekReadFieldRVARow ctxt mdv, - snd, simpleIndexCompare idx, isSorted ctxt TableNames.FieldRVA, fst) - Some (rvaToData ctxt pectxt "field" rva)), - offset = - (if hasLayout && not isStatic then - Some (seekReadIndexedRow (ctxt.getNumRows TableNames.FieldLayout, seekReadFieldLayoutRow ctxt mdv, - snd, simpleIndexCompare idx, isSorted ctxt TableNames.FieldLayout, fst)) else None), - customAttrsStored=ctxt.customAttrsReader_FieldDef, - metadataIndex = idx) - -and seekReadFields (ctxt: ILMetadataReader) (numtypars, hasLayout) fidx1 fidx2 = - mkILFieldsLazy - (lazy - let mdv = ctxt.mdfile.GetView() - [ if fidx1 > 0 then - for i = fidx1 to fidx2 - 1 do - yield seekReadField ctxt mdv (numtypars, hasLayout) i ]) - -and seekReadMethods (ctxt: ILMetadataReader) numtypars midx1 midx2 = - mkILMethodsComputed (fun () -> - let mdv = ctxt.mdfile.GetView() - [| if midx1 > 0 then - for i = midx1 to midx2 - 1 do - yield seekReadMethod ctxt mdv numtypars i |]) - -and sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr = - let n, sigptr = sigptrGetZInt32 bytes sigptr - if (n &&& 0x01) = 0x0 then (* Type Def *) - TaggedIndex(tdor_TypeDef, (n >>>& 2)), sigptr - else (* Type Ref *) - TaggedIndex(tdor_TypeRef, (n >>>& 2)), sigptr - -and sigptrGetTy (ctxt: ILMetadataReader) numtypars bytes sigptr = - let b0, sigptr = sigptrGetByte bytes sigptr - if b0 = et_OBJECT then primaryAssemblyILGlobals.typ_Object, sigptr - elif b0 = et_STRING then primaryAssemblyILGlobals.typ_String, sigptr - elif b0 = et_I1 then primaryAssemblyILGlobals.typ_SByte, sigptr - elif b0 = et_I2 then primaryAssemblyILGlobals.typ_Int16, sigptr - elif b0 = et_I4 then primaryAssemblyILGlobals.typ_Int32, sigptr - elif b0 = et_I8 then primaryAssemblyILGlobals.typ_Int64, sigptr - elif b0 = et_I then primaryAssemblyILGlobals.typ_IntPtr, sigptr - elif b0 = et_U1 then primaryAssemblyILGlobals.typ_Byte, sigptr - elif b0 = et_U2 then primaryAssemblyILGlobals.typ_UInt16, sigptr - elif b0 = et_U4 then primaryAssemblyILGlobals.typ_UInt32, sigptr - elif b0 = et_U8 then primaryAssemblyILGlobals.typ_UInt64, sigptr - elif b0 = et_U then primaryAssemblyILGlobals.typ_UIntPtr, sigptr - elif b0 = et_R4 then primaryAssemblyILGlobals.typ_Single, sigptr - elif b0 = et_R8 then primaryAssemblyILGlobals.typ_Double, sigptr - elif b0 = et_CHAR then primaryAssemblyILGlobals.typ_Char, sigptr - elif b0 = et_BOOLEAN then primaryAssemblyILGlobals.typ_Bool, sigptr - elif b0 = et_WITH then - let b0, sigptr = sigptrGetByte bytes sigptr - let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr - let n, sigptr = sigptrGetZInt32 bytes sigptr - let argtys, sigptr = sigptrFold (sigptrGetTy ctxt numtypars) n bytes sigptr - seekReadTypeDefOrRef ctxt numtypars (if b0 = et_CLASS then AsObject else AsValue) argtys tdorIdx, - sigptr - - elif b0 = et_CLASS then - let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr - seekReadTypeDefOrRef ctxt numtypars AsObject List.empty tdorIdx, sigptr - elif b0 = et_VALUETYPE then - let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr - seekReadTypeDefOrRef ctxt numtypars AsValue List.empty tdorIdx, sigptr - elif b0 = et_VAR then - let n, sigptr = sigptrGetZInt32 bytes sigptr - ILType.TypeVar (uint16 n), sigptr - elif b0 = et_MVAR then - let n, sigptr = sigptrGetZInt32 bytes sigptr - ILType.TypeVar (uint16 (n + numtypars)), sigptr - elif b0 = et_BYREF then - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - ILType.Byref ty, sigptr - elif b0 = et_PTR then - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - ILType.Ptr ty, sigptr - elif b0 = et_SZARRAY then - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - mkILArr1DTy ty, sigptr - elif b0 = et_ARRAY then - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - let rank, sigptr = sigptrGetZInt32 bytes sigptr - let numSized, sigptr = sigptrGetZInt32 bytes sigptr - let sizes, sigptr = sigptrFold sigptrGetZInt32 numSized bytes sigptr - let numLoBounded, sigptr = sigptrGetZInt32 bytes sigptr - let lobounds, sigptr = sigptrFold sigptrGetZInt32 numLoBounded bytes sigptr - let shape = - let dim i = - (if i < numLoBounded then Some (List.item i lobounds) else None), - (if i < numSized then Some (List.item i sizes) else None) - ILArrayShape (List.init rank dim) - mkILArrTy (ty, shape), sigptr - - elif b0 = et_VOID then ILType.Void, sigptr - elif b0 = et_TYPEDBYREF then - primaryAssemblyILGlobals.typ_TypedReference, sigptr - elif b0 = et_CMOD_REQD || b0 = et_CMOD_OPT then - let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - ILType.Modified((b0 = et_CMOD_REQD), seekReadTypeDefOrRefAsTypeRef ctxt tdorIdx, ty), sigptr - elif b0 = et_FNPTR then - let ccByte, sigptr = sigptrGetByte bytes sigptr - let generic, cc = byteAsCallConv ccByte - if generic then failwith "fptr sig may not be generic" - let numparams, sigptr = sigptrGetZInt32 bytes sigptr - let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - let argtys, sigptr = sigptrFold (sigptrGetTy ctxt numtypars) ( numparams) bytes sigptr - let typ = - ILType.FunctionPointer - { CallingConv=cc - ArgTypes = argtys - ReturnType=retty } - typ, sigptr - elif b0 = et_SENTINEL then failwith "varargs NYI" - else ILType.Void, sigptr - -and sigptrGetVarArgTys (ctxt: ILMetadataReader) n numtypars bytes sigptr = - sigptrFold (sigptrGetTy ctxt numtypars) n bytes sigptr - -and sigptrGetArgTys (ctxt: ILMetadataReader) n numtypars bytes sigptr acc = - if n <= 0 then (List.rev acc, None), sigptr - else - let b0, sigptr2 = sigptrGetByte bytes sigptr - if b0 = et_SENTINEL then - let varargs, sigptr = sigptrGetVarArgTys ctxt n numtypars bytes sigptr2 - (List.rev acc, Some varargs), sigptr - else - let x, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - sigptrGetArgTys ctxt (n-1) numtypars bytes sigptr (x :: acc) - -and sigptrGetLocal (ctxt: ILMetadataReader) numtypars bytes sigptr = - let pinned, sigptr = - let b0, sigptr' = sigptrGetByte bytes sigptr - if b0 = et_PINNED then - true, sigptr' - else - false, sigptr - let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - let loc: ILLocal = { IsPinned = pinned; Type = ty; DebugInfo = None } - loc, sigptr - -and readBlobHeapAsMethodSig (ctxt: ILMetadataReader) numtypars blobIdx = - ctxt.readBlobHeapAsMethodSig (BlobAsMethodSigIdx (numtypars, blobIdx)) - -and readBlobHeapAsMethodSigUncached ctxtH (BlobAsMethodSigIdx (numtypars, blobIdx)) = - let (ctxt: ILMetadataReader) = getHole ctxtH - let bytes = readBlobHeap ctxt blobIdx - let sigptr = 0 - let ccByte, sigptr = sigptrGetByte bytes sigptr - let generic, cc = byteAsCallConv ccByte - let genarity, sigptr = if generic then sigptrGetZInt32 bytes sigptr else 0x0, sigptr - let numparams, sigptr = sigptrGetZInt32 bytes sigptr - let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - let (argtys, varargs), _sigptr = sigptrGetArgTys ctxt numparams numtypars bytes sigptr [] - generic, genarity, cc, retty, argtys, varargs - -and readBlobHeapAsType ctxt numtypars blobIdx = - let bytes = readBlobHeap ctxt blobIdx - let ty, _sigptr = sigptrGetTy ctxt numtypars bytes 0 - ty - -and readBlobHeapAsFieldSig ctxt numtypars blobIdx = - ctxt.readBlobHeapAsFieldSig (BlobAsFieldSigIdx (numtypars, blobIdx)) - -and readBlobHeapAsFieldSigUncached ctxtH (BlobAsFieldSigIdx (numtypars, blobIdx)) = - let ctxt = getHole ctxtH - let bytes = readBlobHeap ctxt blobIdx - let sigptr = 0 - let ccByte, sigptr = sigptrGetByte bytes sigptr - if ccByte <> e_IMAGE_CEE_CS_CALLCONV_FIELD then dprintn "warning: field sig was not CC_FIELD" - let retty, _sigptr = sigptrGetTy ctxt numtypars bytes sigptr - retty - - -and readBlobHeapAsPropertySig (ctxt: ILMetadataReader) numtypars blobIdx = - ctxt.readBlobHeapAsPropertySig (BlobAsPropSigIdx (numtypars, blobIdx)) - -and readBlobHeapAsPropertySigUncached ctxtH (BlobAsPropSigIdx (numtypars, blobIdx)) = - let ctxt = getHole ctxtH - let bytes = readBlobHeap ctxt blobIdx - let sigptr = 0 - let ccByte, sigptr = sigptrGetByte bytes sigptr - let hasthis = byteAsHasThis ccByte - let ccMaxked = (ccByte &&& 0x0Fuy) - if ccMaxked <> e_IMAGE_CEE_CS_CALLCONV_PROPERTY then dprintn ("warning: property sig was "+string ccMaxked+" instead of CC_PROPERTY") - let numparams, sigptr = sigptrGetZInt32 bytes sigptr - let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr - let argtys, _sigptr = sigptrFold (sigptrGetTy ctxt numtypars) ( numparams) bytes sigptr - hasthis, retty, argtys - -and readBlobHeapAsLocalsSig (ctxt: ILMetadataReader) numtypars blobIdx = - ctxt.readBlobHeapAsLocalsSig (BlobAsLocalSigIdx (numtypars, blobIdx)) - -and readBlobHeapAsLocalsSigUncached ctxtH (BlobAsLocalSigIdx (numtypars, blobIdx)) = - let ctxt = getHole ctxtH - let bytes = readBlobHeap ctxt blobIdx - let sigptr = 0 - let ccByte, sigptr = sigptrGetByte bytes sigptr - if ccByte <> e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG then dprintn "warning: local sig was not CC_LOCAL" - let numlocals, sigptr = sigptrGetZInt32 bytes sigptr - let localtys, _sigptr = sigptrFold (sigptrGetLocal ctxt numtypars) ( numlocals) bytes sigptr - localtys - -and byteAsHasThis b = - let hasthis_masked = b &&& 0x60uy - if hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE then ILThisConvention.Instance - elif hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT then ILThisConvention.InstanceExplicit - else ILThisConvention.Static - -and byteAsCallConv b = - let cc = - let ccMaxked = b &&& 0x0Fuy - if ccMaxked = e_IMAGE_CEE_CS_CALLCONV_FASTCALL then ILArgConvention.FastCall - elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_STDCALL then ILArgConvention.StdCall - elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_THISCALL then ILArgConvention.ThisCall - elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_CDECL then ILArgConvention.CDecl - elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_VARARG then ILArgConvention.VarArg - else ILArgConvention.Default - let generic = (b &&& e_IMAGE_CEE_CS_CALLCONV_GENERIC) <> 0x0uy - generic, Callconv (byteAsHasThis b, cc) - -and seekReadMemberRefAsMethodData ctxt numtypars idx: VarArgMethodData = - ctxt.seekReadMemberRefAsMethodData (MemberRefAsMspecIdx (numtypars, idx)) - -and seekReadMemberRefAsMethodDataUncached ctxtH (MemberRefAsMspecIdx (numtypars, idx)) = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let (mrpIdx, nameIdx, typeIdx) = seekReadMemberRefRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - let enclTy = seekReadMethodRefParent ctxt mdv numtypars mrpIdx - let _generic, genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt enclTy.GenericArgs.Length typeIdx - let minst = List.init genarity (fun n -> mkILTyvarTy (uint16 (numtypars+n))) - (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) - -and seekReadMemberRefAsMethDataNoVarArgs ctxt numtypars idx: MethodData = - let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = seekReadMemberRefAsMethodData ctxt numtypars idx - if Option.isSome varargs then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" - (MethodData(enclTy, cc, nm, argtys, retty, minst)) - -and seekReadMethodSpecAsMethodData (ctxt: ILMetadataReader) numtypars idx = - ctxt.seekReadMethodSpecAsMethodData (MethodSpecAsMspecIdx (numtypars, idx)) - -and seekReadMethodSpecAsMethodDataUncached ctxtH (MethodSpecAsMspecIdx (numtypars, idx)) = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let (mdorIdx, instIdx) = seekReadMethodSpecRow ctxt mdv idx - let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, _)) = seekReadMethodDefOrRef ctxt numtypars mdorIdx - let minst = - let bytes = readBlobHeap ctxt instIdx - let sigptr = 0 - let ccByte, sigptr = sigptrGetByte bytes sigptr - if ccByte <> e_IMAGE_CEE_CS_CALLCONV_GENERICINST then dprintn ("warning: method inst ILCallingConv was "+string ccByte+" instead of CC_GENERICINST") - let numgpars, sigptr = sigptrGetZInt32 bytes sigptr - let argtys, _sigptr = sigptrFold (sigptrGetTy ctxt numtypars) numgpars bytes sigptr - argtys - VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst) - -and seekReadMemberRefAsFieldSpec (ctxt: ILMetadataReader) numtypars idx = - ctxt.seekReadMemberRefAsFieldSpec (MemberRefAsFspecIdx (numtypars, idx)) - -and seekReadMemberRefAsFieldSpecUncached ctxtH (MemberRefAsFspecIdx (numtypars, idx)) = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let (mrpIdx, nameIdx, typeIdx) = seekReadMemberRefRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - let enclTy = seekReadMethodRefParent ctxt mdv numtypars mrpIdx - let retty = readBlobHeapAsFieldSig ctxt numtypars typeIdx - mkILFieldSpecInTy(enclTy, nm, retty) - -// One extremely annoying aspect of the MD format is that given a -// ILMethodDef token it is non-trivial to find which ILTypeDef it belongs -// to. So we do a binary chop through the ILTypeDef table -// looking for which ILTypeDef has the ILMethodDef within its range. -// Although the ILTypeDef table is not "sorted", it is effectively sorted by -// method-range and field-range start/finish indexes -and seekReadMethodDefAsMethodData ctxt idx = - ctxt.seekReadMethodDefAsMethodData idx - -and seekReadMethodDefAsMethodDataUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - // Look for the method def parent. - let tidx = - seekReadIndexedRow (ctxt.getNumRows TableNames.TypeDef, - (fun i -> i, seekReadTypeDefRowWithExtents ctxt i), - (fun r -> r), - (fun (_, ((_, _, _, _, _, methodsIdx), - (_, endMethodsIdx))) -> - if endMethodsIdx <= idx then 1 - elif methodsIdx <= idx && idx < endMethodsIdx then 0 - else -1), - true, fst) - // Create a formal instantiation if needed - let typeGenericArgs = seekReadGenericParams ctxt 0 (tomd_TypeDef, tidx) - let typeGenericArgsCount = typeGenericArgs.Length - - let methodGenericArgs = seekReadGenericParams ctxt typeGenericArgsCount (tomd_MethodDef, idx) - - let finst = mkILFormalGenericArgs 0 typeGenericArgs - let minst = mkILFormalGenericArgs typeGenericArgsCount methodGenericArgs - - // Read the method def parent. - let enclTy = seekReadTypeDefAsType ctxt AsObject (* not ok: see note *) finst tidx - - // Return the constituent parts: put it together at the place where this is called. - let (_code_rva, _implflags, _flags, nameIdx, typeIdx, _paramIdx) = seekReadMethodRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - - // Read the method def signature. - let _generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt typeGenericArgsCount typeIdx - if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" - - MethodData(enclTy, cc, nm, argtys, retty, minst) - - -and seekReadFieldDefAsFieldSpec (ctxt: ILMetadataReader) idx = - ctxt.seekReadFieldDefAsFieldSpec idx - -and seekReadFieldDefAsFieldSpecUncached ctxtH idx = - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - let (_flags, nameIdx, typeIdx) = seekReadFieldRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - (* Look for the field def parent. *) - let tidx = - seekReadIndexedRow (ctxt.getNumRows TableNames.TypeDef, - (fun i -> i, seekReadTypeDefRowWithExtents ctxt i), - (fun r -> r), - (fun (_, ((_, _, _, _, fieldsIdx, _), (endFieldsIdx, _))) -> - if endFieldsIdx <= idx then 1 - elif fieldsIdx <= idx && idx < endFieldsIdx then 0 - else -1), - true, fst) - // Read the field signature. - let retty = readBlobHeapAsFieldSig ctxt 0 typeIdx - - // Create a formal instantiation if needed - let finst = mkILFormalGenericArgs 0 (seekReadGenericParams ctxt 0 (tomd_TypeDef, tidx)) - - // Read the field def parent. - let enclTy = seekReadTypeDefAsType ctxt AsObject (* not ok: see note *) finst tidx - - // Put it together. - mkILFieldSpecInTy(enclTy, nm, retty) - -and seekReadMethod (ctxt: ILMetadataReader) mdv numtypars (idx: int) = - let (codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) = seekReadMethodRow ctxt mdv idx - let nm = readStringHeap ctxt nameIdx - let abstr = (flags &&& 0x0400) <> 0x0 - let pinvoke = (flags &&& 0x2000) <> 0x0 - let codetype = implflags &&& 0x0003 - let unmanaged = (implflags &&& 0x0004) <> 0x0 - let internalcall = (implflags &&& 0x1000) <> 0x0 - let noinline = (implflags &&& 0x0008) <> 0x0 - let aggressiveinline = (implflags &&& 0x0100) <> 0x0 - let _generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt numtypars typeIdx - if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef signature" - - let endParamIdx = - if idx >= ctxt.getNumRows TableNames.Method then - ctxt.getNumRows TableNames.Param + 1 - else - let (_, _, _, _, _, paramIdx) = seekReadMethodRow ctxt mdv (idx + 1) - paramIdx - - let ret, ilParams = seekReadParams ctxt mdv (retty, argtys) paramIdx endParamIdx - - let isEntryPoint = - let (tab, tok) = ctxt.entryPointToken - (tab = TableNames.Method && tok = idx) - - let body = - if (codetype = 0x01) && pinvoke then - methBodyNative - elif pinvoke then - seekReadImplMap ctxt nm idx - elif internalcall || abstr || unmanaged || (codetype <> 0x00) then - methBodyAbstract - else - match ctxt.pectxtCaptured with - | None -> methBodyNotAvailable - | Some pectxt -> seekReadMethodRVA pectxt ctxt (idx, nm, internalcall, noinline, aggressiveinline, numtypars) codeRVA - - ILMethodDef(name=nm, - attributes = enum(flags), - implAttributes= enum(implflags), - securityDeclsStored=ctxt.securityDeclsReader_MethodDef, - isEntryPoint=isEntryPoint, - genericParams=seekReadGenericParams ctxt numtypars (tomd_MethodDef, idx), - parameters= ilParams, - callingConv=cc, - ret=ret, - body=body, - customAttrsStored=ctxt.customAttrsReader_MethodDef, - metadataIndex=idx) - - -and seekReadParams (ctxt: ILMetadataReader) mdv (retty, argtys) pidx1 pidx2 = - let retRes = ref (mkILReturn retty) - let paramsRes = argtys |> List.toArray |> Array.map mkILParamAnon - for i = pidx1 to pidx2 - 1 do - seekReadParamExtras ctxt mdv (retRes, paramsRes) i - !retRes, List.ofArray paramsRes - -and seekReadParamExtras (ctxt: ILMetadataReader) mdv (retRes, paramsRes) (idx: int) = - let (flags, seq, nameIdx) = seekReadParamRow ctxt mdv idx - let inOutMasked = (flags &&& 0x00FF) - let hasMarshal = (flags &&& 0x2000) <> 0x0 - let hasDefault = (flags &&& 0x1000) <> 0x0 - let fmReader idx = seekReadIndexedRow (ctxt.getNumRows TableNames.FieldMarshal, seekReadFieldMarshalRow ctxt mdv, fst, hfmCompare idx, isSorted ctxt TableNames.FieldMarshal, (snd >> readBlobHeapAsNativeType ctxt)) - if seq = 0 then - retRes := { !retRes with - Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None) - CustomAttrsStored = ctxt.customAttrsReader_ParamDef - MetadataIndex = idx} - elif seq > Array.length paramsRes then dprintn "bad seq num. for param" - else - paramsRes.[seq - 1] <- - { paramsRes.[seq - 1] with - Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None) - Default = (if hasDefault then Some (seekReadConstant ctxt (TaggedIndex(hc_ParamDef, idx))) else None) - Name = readStringHeapOption ctxt nameIdx - IsIn = ((inOutMasked &&& 0x0001) <> 0x0) - IsOut = ((inOutMasked &&& 0x0002) <> 0x0) - IsOptional = ((inOutMasked &&& 0x0010) <> 0x0) - CustomAttrsStored = ctxt.customAttrsReader_ParamDef - MetadataIndex = idx } - -and seekReadMethodImpls (ctxt: ILMetadataReader) numtypars tidx = - mkILMethodImplsLazy - (lazy - let mdv = ctxt.mdfile.GetView() - let mimpls = seekReadIndexedRows (ctxt.getNumRows TableNames.MethodImpl, seekReadMethodImplRow ctxt mdv, (fun (a, _, _) -> a), simpleIndexCompare tidx, isSorted ctxt TableNames.MethodImpl, (fun (_, b, c) -> b, c)) - mimpls |> List.map (fun (b, c) -> - { OverrideBy= - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars b - mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - Overrides= - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars c - let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - OverridesSpec(mspec.MethodRef, mspec.DeclaringType) })) - -and seekReadMultipleMethodSemantics (ctxt: ILMetadataReader) (flags, id) = - seekReadIndexedRows - (ctxt.getNumRows TableNames.MethodSemantics, - seekReadMethodSemanticsRow ctxt, - (fun (_flags, _, c) -> c), - hsCompare id, - isSorted ctxt TableNames.MethodSemantics, - (fun (a, b, _c) -> - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt b - a, (mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst)).MethodRef)) - |> List.filter (fun (flags2, _) -> flags = flags2) - |> List.map snd - - -and seekReadoptional_MethodSemantics ctxt id = - match seekReadMultipleMethodSemantics ctxt id with - | [] -> None - | [h] -> Some h - | h :: _ -> dprintn "multiple method semantics found"; Some h - -and seekReadMethodSemantics ctxt id = - match seekReadoptional_MethodSemantics ctxt id with - | None -> failwith "seekReadMethodSemantics ctxt: no method found" - | Some x -> x - -and seekReadEvent ctxt mdv numtypars idx = - let (flags, nameIdx, typIdx) = seekReadEventRow ctxt mdv idx - ILEventDef(eventType = seekReadOptionalTypeDefOrRef ctxt numtypars AsObject typIdx, - name = readStringHeap ctxt nameIdx, - attributes = enum(flags), - addMethod= seekReadMethodSemantics ctxt (0x0008, TaggedIndex(hs_Event, idx)), - removeMethod=seekReadMethodSemantics ctxt (0x0010, TaggedIndex(hs_Event, idx)), - fireMethod=seekReadoptional_MethodSemantics ctxt (0x0020, TaggedIndex(hs_Event, idx)), - otherMethods = seekReadMultipleMethodSemantics ctxt (0x0004, TaggedIndex(hs_Event, idx)), - customAttrsStored=ctxt.customAttrsReader_Event, - metadataIndex = idx ) - - (* REVIEW: can substantially reduce numbers of EventMap and PropertyMap reads by first checking if the whole table mdv sorted according to ILTypeDef tokens and then doing a binary chop *) -and seekReadEvents (ctxt: ILMetadataReader) numtypars tidx = - mkILEventsLazy - (lazy - let mdv = ctxt.mdfile.GetView() - match seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.EventMap, (fun i -> i, seekReadEventMapRow ctxt mdv i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with - | None -> [] - | Some (rowNum, beginEventIdx) -> - let endEventIdx = - if rowNum >= ctxt.getNumRows TableNames.EventMap then - ctxt.getNumRows TableNames.Event + 1 - else - let (_, endEventIdx) = seekReadEventMapRow ctxt mdv (rowNum + 1) - endEventIdx - - [ if beginEventIdx > 0 then - for i in beginEventIdx .. endEventIdx - 1 do - yield seekReadEvent ctxt mdv numtypars i ]) - -and seekReadProperty ctxt mdv numtypars idx = - let (flags, nameIdx, typIdx) = seekReadPropertyRow ctxt mdv idx - let cc, retty, argtys = readBlobHeapAsPropertySig ctxt numtypars typIdx - let setter= seekReadoptional_MethodSemantics ctxt (0x0001, TaggedIndex(hs_Property, idx)) - let getter = seekReadoptional_MethodSemantics ctxt (0x0002, TaggedIndex(hs_Property, idx)) -(* NOTE: the "ThisConv" value on the property is not reliable: better to look on the getter/setter *) -(* NOTE: e.g. tlbimp on Office msword.olb seems to set this incorrectly *) - let cc2 = - match getter with - | Some mref -> mref.CallingConv.ThisConv - | None -> - match setter with - | Some mref -> mref.CallingConv .ThisConv - | None -> cc - - ILPropertyDef(name=readStringHeap ctxt nameIdx, - callingConv = cc2, - attributes = enum(flags), - setMethod=setter, - getMethod=getter, - propertyType=retty, - init= (if (flags &&& 0x1000) = 0 then None else Some (seekReadConstant ctxt (TaggedIndex(hc_Property, idx)))), - args=argtys, - customAttrsStored=ctxt.customAttrsReader_Property, - metadataIndex = idx ) - -and seekReadProperties (ctxt: ILMetadataReader) numtypars tidx = - mkILPropertiesLazy - (lazy - let mdv = ctxt.mdfile.GetView() - match seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.PropertyMap, (fun i -> i, seekReadPropertyMapRow ctxt mdv i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with - | None -> [] - | Some (rowNum, beginPropIdx) -> - let endPropIdx = - if rowNum >= ctxt.getNumRows TableNames.PropertyMap then - ctxt.getNumRows TableNames.Property + 1 - else - let (_, endPropIdx) = seekReadPropertyMapRow ctxt mdv (rowNum + 1) - endPropIdx - [ if beginPropIdx > 0 then - for i in beginPropIdx .. endPropIdx - 1 do - yield seekReadProperty ctxt mdv numtypars i ]) - - -and customAttrsReader ctxtH tag: ILAttributesStored = - mkILCustomAttrsReader - (fun idx -> - let (ctxt: ILMetadataReader) = getHole ctxtH - seekReadIndexedRows (ctxt.getNumRows TableNames.CustomAttribute, - seekReadCustomAttributeRow ctxt, (fun (a, _, _) -> a), - hcaCompare (TaggedIndex(tag,idx)), - isSorted ctxt TableNames.CustomAttribute, - (fun (_, b, c) -> seekReadCustomAttr ctxt (b, c))) - |> List.toArray) - -and seekReadCustomAttr ctxt (TaggedIndex(cat, idx), b) = - ctxt.seekReadCustomAttr (CustomAttrIdx (cat, idx, b)) - -and seekReadCustomAttrUncached ctxtH (CustomAttrIdx (cat, idx, valIdx)) = - let ctxt = getHole ctxtH - let method = seekReadCustomAttrType ctxt (TaggedIndex(cat, idx)) - let data = - match readBlobHeapOption ctxt valIdx with - | Some bytes -> bytes - | None -> Bytes.ofInt32Array [| |] - let elements = [] - ILAttribute.Encoded (method, data, elements) - -and securityDeclsReader ctxtH tag = - mkILSecurityDeclsReader - (fun idx -> - let (ctxt: ILMetadataReader) = getHole ctxtH - let mdv = ctxt.mdfile.GetView() - seekReadIndexedRows (ctxt.getNumRows TableNames.Permission, - seekReadPermissionRow ctxt mdv, - (fun (_, par, _) -> par), - hdsCompare (TaggedIndex(tag,idx)), - isSorted ctxt TableNames.Permission, - (fun (act, _, ty) -> seekReadSecurityDecl ctxt (act, ty))) - |> List.toArray) - -and seekReadSecurityDecl ctxt (act, ty) = - ILSecurityDecl ((if List.memAssoc (int act) (Lazy.force ILSecurityActionRevMap) then List.assoc (int act) (Lazy.force ILSecurityActionRevMap) else failwith "unknown security action"), - readBlobHeap ctxt ty) - -and seekReadConstant (ctxt: ILMetadataReader) idx = - let kind, vidx = seekReadIndexedRow (ctxt.getNumRows TableNames.Constant, - seekReadConstantRow ctxt, - (fun (_, key, _) -> key), - hcCompare idx, isSorted ctxt TableNames.Constant, (fun (kind, _, v) -> kind, v)) - match kind with - | x when x = uint16 et_STRING -> - let blobHeap = readBlobHeap ctxt vidx - let s = System.Text.Encoding.Unicode.GetString(blobHeap, 0, blobHeap.Length) - ILFieldInit.String s - | x when x = uint16 et_BOOLEAN -> ILFieldInit.Bool (readBlobHeapAsBool ctxt vidx) - | x when x = uint16 et_CHAR -> ILFieldInit.Char (readBlobHeapAsUInt16 ctxt vidx) - | x when x = uint16 et_I1 -> ILFieldInit.Int8 (readBlobHeapAsSByte ctxt vidx) - | x when x = uint16 et_I2 -> ILFieldInit.Int16 (readBlobHeapAsInt16 ctxt vidx) - | x when x = uint16 et_I4 -> ILFieldInit.Int32 (readBlobHeapAsInt32 ctxt vidx) - | x when x = uint16 et_I8 -> ILFieldInit.Int64 (readBlobHeapAsInt64 ctxt vidx) - | x when x = uint16 et_U1 -> ILFieldInit.UInt8 (readBlobHeapAsByte ctxt vidx) - | x when x = uint16 et_U2 -> ILFieldInit.UInt16 (readBlobHeapAsUInt16 ctxt vidx) - | x when x = uint16 et_U4 -> ILFieldInit.UInt32 (readBlobHeapAsUInt32 ctxt vidx) - | x when x = uint16 et_U8 -> ILFieldInit.UInt64 (readBlobHeapAsUInt64 ctxt vidx) - | x when x = uint16 et_R4 -> ILFieldInit.Single (readBlobHeapAsSingle ctxt vidx) - | x when x = uint16 et_R8 -> ILFieldInit.Double (readBlobHeapAsDouble ctxt vidx) - | x when x = uint16 et_CLASS || x = uint16 et_OBJECT -> ILFieldInit.Null - | _ -> ILFieldInit.Null - -and seekReadImplMap (ctxt: ILMetadataReader) nm midx = - mkMethBodyLazyAux - (lazy - let mdv = ctxt.mdfile.GetView() - let (flags, nameIdx, scopeIdx) = seekReadIndexedRow (ctxt.getNumRows TableNames.ImplMap, - seekReadImplMapRow ctxt mdv, - (fun (_, m, _, _) -> m), - mfCompare (TaggedIndex(mf_MethodDef, midx)), - isSorted ctxt TableNames.ImplMap, - (fun (a, _, c, d) -> a, c, d)) - let cc = - let masked = flags &&& 0x0700 - if masked = 0x0000 then PInvokeCallingConvention.None - elif masked = 0x0200 then PInvokeCallingConvention.Cdecl - elif masked = 0x0300 then PInvokeCallingConvention.Stdcall - elif masked = 0x0400 then PInvokeCallingConvention.Thiscall - elif masked = 0x0500 then PInvokeCallingConvention.Fastcall - elif masked = 0x0100 then PInvokeCallingConvention.WinApi - else (dprintn "strange CallingConv"; PInvokeCallingConvention.None) - - let enc = - let masked = flags &&& 0x0006 - if masked = 0x0000 then PInvokeCharEncoding.None - elif masked = 0x0002 then PInvokeCharEncoding.Ansi - elif masked = 0x0004 then PInvokeCharEncoding.Unicode - elif masked = 0x0006 then PInvokeCharEncoding.Auto - else (dprintn "strange CharEncoding"; PInvokeCharEncoding.None) - - let bestfit = - let masked = flags &&& 0x0030 - if masked = 0x0000 then PInvokeCharBestFit.UseAssembly - elif masked = 0x0010 then PInvokeCharBestFit.Enabled - elif masked = 0x0020 then PInvokeCharBestFit.Disabled - else (dprintn "strange CharBestFit"; PInvokeCharBestFit.UseAssembly) - - let unmap = - let masked = flags &&& 0x3000 - if masked = 0x0000 then PInvokeThrowOnUnmappableChar.UseAssembly - elif masked = 0x1000 then PInvokeThrowOnUnmappableChar.Enabled - elif masked = 0x2000 then PInvokeThrowOnUnmappableChar.Disabled - else (dprintn "strange ThrowOnUnmappableChar"; PInvokeThrowOnUnmappableChar.UseAssembly) - - MethodBody.PInvoke { CallingConv = cc - CharEncoding = enc - CharBestFit=bestfit - ThrowOnUnmappableChar=unmap - NoMangle = (flags &&& 0x0001) <> 0x0 - LastError = (flags &&& 0x0040) <> 0x0 - Name = - (match readStringHeapOption ctxt nameIdx with - | None -> nm - | Some nm2 -> nm2) - Where = seekReadModuleRef ctxt mdv scopeIdx }) - -and seekReadTopCode (ctxt: ILMetadataReader) pev mdv numtypars (sz: int) start seqpoints = - let labelsOfRawOffsets = new Dictionary<_, _>(sz/2) - let ilOffsetsOfLabels = new Dictionary<_, _>(sz/2) - let tryRawToLabel rawOffset = - match labelsOfRawOffsets.TryGetValue rawOffset with - | true, v -> Some v - | _ -> None - - let rawToLabel rawOffset = - match tryRawToLabel rawOffset with - | Some l -> l - | None -> - let lab = generateCodeLabel() - labelsOfRawOffsets.[rawOffset] <- lab - lab - - let markAsInstructionStart rawOffset ilOffset = - let lab = rawToLabel rawOffset - ilOffsetsOfLabels.[lab] <- ilOffset - - let ibuf = new ResizeArray<_>(sz/2) - let curr = ref 0 - let prefixes = { al=Aligned; tl= Normalcall; vol= Nonvolatile;ro=NormalAddress;constrained=None } - let lastb = ref 0x0 - let lastb2 = ref 0x0 - let b = ref 0x0 - let get () = - lastb := seekReadByteAsInt32 pev (start + (!curr)) - incr curr - b := - if !lastb = 0xfe && !curr < sz then - lastb2 := seekReadByteAsInt32 pev (start + (!curr)) - incr curr - !lastb2 - else - !lastb - - let seqPointsRemaining = ref seqpoints - - while !curr < sz do - // registering "+string !curr+" as start of an instruction") - markAsInstructionStart !curr ibuf.Count - - // Insert any sequence points into the instruction sequence - while - (match !seqPointsRemaining with - | (i, _tag) :: _rest when i <= !curr -> true - | _ -> false) - do - // Emitting one sequence point - let (_, tag) = List.head !seqPointsRemaining - seqPointsRemaining := List.tail !seqPointsRemaining - ibuf.Add (I_seqpoint tag) - - // Read the prefixes. Leave lastb and lastb2 holding the instruction byte(s) - begin - prefixes.al <- Aligned - prefixes.tl <- Normalcall - prefixes.vol <- Nonvolatile - prefixes.ro<-NormalAddress - prefixes.constrained<-None - get () - while !curr < sz && - !lastb = 0xfe && - (!b = (i_constrained &&& 0xff) || - !b = (i_readonly &&& 0xff) || - !b = (i_unaligned &&& 0xff) || - !b = (i_volatile &&& 0xff) || - !b = (i_tail &&& 0xff)) do - begin - if !b = (i_unaligned &&& 0xff) then - let unal = seekReadByteAsInt32 pev (start + (!curr)) - incr curr - prefixes.al <- - if unal = 0x1 then Unaligned1 - elif unal = 0x2 then Unaligned2 - elif unal = 0x4 then Unaligned4 - else (dprintn "bad alignment for unaligned"; Aligned) - elif !b = (i_volatile &&& 0xff) then prefixes.vol <- Volatile - elif !b = (i_readonly &&& 0xff) then prefixes.ro <- ReadonlyAddress - elif !b = (i_constrained &&& 0xff) then - let uncoded = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - let ty = seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec uncoded) - prefixes.constrained <- Some ty - else prefixes.tl <- Tailcall - end - get () - end - - // data for instruction begins at "+string !curr - // Read and decode the instruction - if (!curr <= sz) then - let idecoder = - if !lastb = 0xfe then getTwoByteInstr ( !lastb2) - else getOneByteInstr ( !lastb) - let instr = - match idecoder with - | I_u16_u8_instr f -> - let x = seekReadByte pev (start + (!curr)) |> uint16 - curr := !curr + 1 - f prefixes x - | I_u16_u16_instr f -> - let x = seekReadUInt16 pev (start + (!curr)) - curr := !curr + 2 - f prefixes x - | I_none_instr f -> - f prefixes - | I_i64_instr f -> - let x = seekReadInt64 pev (start + (!curr)) - curr := !curr + 8 - f prefixes x - | I_i32_i8_instr f -> - let x = seekReadSByte pev (start + (!curr)) |> int32 - curr := !curr + 1 - f prefixes x - | I_i32_i32_instr f -> - let x = seekReadInt32 pev (start + (!curr)) - curr := !curr + 4 - f prefixes x - | I_r4_instr f -> - let x = seekReadSingle pev (start + (!curr)) - curr := !curr + 4 - f prefixes x - | I_r8_instr f -> - let x = seekReadDouble pev (start + (!curr)) - curr := !curr + 8 - f prefixes x - | I_field_instr f -> - let (tab, tok) = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - let fspec = - if tab = TableNames.Field then - seekReadFieldDefAsFieldSpec ctxt tok - elif tab = TableNames.MemberRef then - seekReadMemberRefAsFieldSpec ctxt numtypars tok - else failwith "bad table in FieldDefOrRef" - f prefixes fspec - | I_method_instr f -> - // method instruction, curr = "+string !curr - - let (tab, idx) = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = - if tab = TableNames.Method then - seekReadMethodDefOrRef ctxt numtypars (TaggedIndex(mdor_MethodDef, idx)) - elif tab = TableNames.MemberRef then - seekReadMethodDefOrRef ctxt numtypars (TaggedIndex(mdor_MemberRef, idx)) - elif tab = TableNames.MethodSpec then - seekReadMethodSpecAsMethodData ctxt numtypars idx - else failwith "bad table in MethodDefOrRefOrSpec" - match enclTy with - | ILType.Array (shape, ty) -> - match nm with - | "Get" -> I_ldelem_any(shape, ty) - | "Set" -> I_stelem_any(shape, ty) - | "Address" -> I_ldelema(prefixes.ro, false, shape, ty) - | ".ctor" -> I_newarr(shape, ty) - | _ -> failwith "bad method on array type" - | _ -> - let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) - f prefixes (mspec, varargs) - | I_type_instr f -> - let uncoded = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - let ty = seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec uncoded) - f prefixes ty - | I_string_instr f -> - let (tab, idx) = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - if tab <> TableNames.UserStrings then dprintn "warning: bad table in user string for ldstr" - f prefixes (readUserStringHeap ctxt idx) - - | I_conditional_i32_instr f -> - let offsDest = (seekReadInt32 pev (start + (!curr))) - curr := !curr + 4 - let dest = !curr + offsDest - f prefixes (rawToLabel dest) - | I_conditional_i8_instr f -> - let offsDest = int (seekReadSByte pev (start + (!curr))) - curr := !curr + 1 - let dest = !curr + offsDest - f prefixes (rawToLabel dest) - | I_unconditional_i32_instr f -> - let offsDest = (seekReadInt32 pev (start + (!curr))) - curr := !curr + 4 - let dest = !curr + offsDest - f prefixes (rawToLabel dest) - | I_unconditional_i8_instr f -> - let offsDest = int (seekReadSByte pev (start + (!curr))) - curr := !curr + 1 - let dest = !curr + offsDest - f prefixes (rawToLabel dest) - | I_invalid_instr -> - dprintn ("invalid instruction: "+string !lastb+ (if !lastb = 0xfe then ", "+string !lastb2 else "")) - I_ret - | I_tok_instr f -> - let (tab, idx) = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - (* REVIEW: this incorrectly labels all MemberRef tokens as ILMethod's: we should go look at the MemberRef sig to determine if it is a field or method *) - let token_info = - if tab = TableNames.Method || tab = TableNames.MemberRef (* REVIEW: generics or tab = TableNames.MethodSpec *) then - let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars (uncodedTokenToMethodDefOrRef (tab, idx)) - ILToken.ILMethod (mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst)) - elif tab = TableNames.Field then - ILToken.ILField (seekReadFieldDefAsFieldSpec ctxt idx) - elif tab = TableNames.TypeDef || tab = TableNames.TypeRef || tab = TableNames.TypeSpec then - ILToken.ILType (seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec (tab, idx))) - else failwith "bad token for ldtoken" - f prefixes token_info - | I_sig_instr f -> - let (tab, idx) = seekReadUncodedToken pev (start + (!curr)) - curr := !curr + 4 - if tab <> TableNames.StandAloneSig then dprintn "strange table for callsig token" - let generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt numtypars (seekReadStandAloneSigRow ctxt mdv idx) - if generic then failwith "bad image: a generic method signature is begin used at a calli instruction" - f prefixes (mkILCallSig (cc, argtys, retty), varargs) - | I_switch_instr f -> - let n = (seekReadInt32 pev (start + (!curr))) - curr := !curr + 4 - let offsets = - List.init n (fun _ -> - let i = (seekReadInt32 pev (start + (!curr))) - curr := !curr + 4 - i) - let dests = List.map (fun offs -> rawToLabel (!curr + offs)) offsets - f prefixes dests - ibuf.Add instr - done - // Finished reading instructions - mark the end of the instruction stream in case the PDB information refers to it. - markAsInstructionStart !curr ibuf.Count - // Build the function that maps from raw labels (offsets into the bytecode stream) to indexes in the AbsIL instruction stream - let lab2pc = ilOffsetsOfLabels - - // Some offsets used in debug info refer to the end of an instruction, rather than the - // start of the subsequent instruction. But all labels refer to instruction starts, - // apart from a final label which refers to the end of the method. This function finds - // the start of the next instruction referred to by the raw offset. - let raw2nextLab rawOffset = - let isInstrStart x = - match tryRawToLabel x with - | None -> false - | Some lab -> ilOffsetsOfLabels.ContainsKey lab - if isInstrStart rawOffset then rawToLabel rawOffset - elif isInstrStart (rawOffset+1) then rawToLabel (rawOffset+1) - else failwith ("the bytecode raw offset "+string rawOffset+" did not refer either to the start or end of an instruction") - let instrs = ibuf.ToArray() - instrs, rawToLabel, lab2pc, raw2nextLab - -#if FX_NO_PDB_READER -and seekReadMethodRVA (pectxt: PEReader) (ctxt: ILMetadataReader) (_idx, nm, _internalcall, noinline, aggressiveinline, numtypars) rva = -#else -and seekReadMethodRVA (pectxt: PEReader) (ctxt: ILMetadataReader) (idx, nm, _internalcall, noinline, aggressiveinline, numtypars) rva = -#endif - mkMethBodyLazyAux - (lazy - let pev = pectxt.pefile.GetView() - let mdv = ctxt.mdfile.GetView() - - // Read any debug information for this method into temporary data structures - // -- a list of locals, marked with the raw offsets (actually closures which accept the resolution function that maps raw offsets to labels) - // -- an overall range for the method - // -- the sequence points for the method - let localPdbInfos, methRangePdbInfo, seqpoints = -#if FX_NO_PDB_READER - [], None, [] -#else - match pectxt.pdb with - | None -> - [], None, [] - | Some (pdbr, get_doc) -> - try - - let pdbm = pdbReaderGetMethod pdbr (uncodedToken TableNames.Method idx) - let sps = pdbMethodGetSequencePoints pdbm - (*dprintf "#sps for 0x%x = %d\n" (uncodedToken TableNames.Method idx) (Array.length sps) *) - (* let roota, rootb = pdbScopeGetOffsets rootScope in *) - let seqpoints = - let arr = - sps |> Array.map (fun sp -> - (* It is VERY annoying to have to call GetURL for the document for each sequence point. This appears to be a short coming of the PDB reader API. They should return an index into the array of documents for the reader *) - let sourcedoc = get_doc (pdbDocumentGetURL sp.pdbSeqPointDocument) - let source = - ILSourceMarker.Create(document = sourcedoc, - line = sp.pdbSeqPointLine, - column = sp.pdbSeqPointColumn, - endLine = sp.pdbSeqPointEndLine, - endColumn = sp.pdbSeqPointEndColumn) - (sp.pdbSeqPointOffset, source)) - - Array.sortInPlaceBy fst arr - - Array.toList arr - let rec scopes scp = - let a, b = pdbScopeGetOffsets scp - let lvs = pdbScopeGetLocals scp - let ilvs = - lvs - |> Array.toList - |> List.filter (fun l -> - let k, _idx = pdbVariableGetAddressAttributes l - k = 1 (* ADDR_IL_OFFSET *)) - let ilinfos: ILLocalDebugMapping list = - ilvs |> List.map (fun ilv -> - let _k, idx = pdbVariableGetAddressAttributes ilv - let n = pdbVariableGetName ilv - { LocalIndex= idx - LocalName=n}) - - let thisOne = - (fun raw2nextLab -> - { Range= (raw2nextLab a, raw2nextLab b) - DebugMappings = ilinfos }: ILLocalDebugInfo ) - let others = List.foldBack (scopes >> (@)) (Array.toList (pdbScopeGetChildren scp)) [] - thisOne :: others - let localPdbInfos = [] (* scopes fail for mscorlib scopes rootScope *) - // REVIEW: look through sps to get ranges? Use GetRanges?? Change AbsIL?? - (localPdbInfos, None, seqpoints) - with e -> - // "* Warning: PDB info for method "+nm+" could not be read and will be ignored: "+e.Message - [], None, [] -#endif - - let baseRVA = pectxt.anyV2P("method rva", rva) - // ": reading body of method "+nm+" at rva "+string rva+", phys "+string baseRVA - let b = seekReadByte pev baseRVA - if (b &&& e_CorILMethod_FormatMask) = e_CorILMethod_TinyFormat then - let codeBase = baseRVA + 1 - let codeSize = (int32 b >>>& 2) - // tiny format for "+nm+", code size = " + string codeSize) - let instrs, _, lab2pc, raw2nextLab = seekReadTopCode ctxt pev mdv numtypars codeSize codeBase seqpoints - (* Convert the linear code format to the nested code format *) - let localPdbInfos2 = List.map (fun f -> f raw2nextLab) localPdbInfos - let code = buildILCode nm lab2pc instrs [] localPdbInfos2 - MethodBody.IL - { IsZeroInit=false - MaxStack= 8 - NoInlining=noinline - AggressiveInlining=aggressiveinline - Locals=List.empty - SourceMarker=methRangePdbInfo - Code=code } - - elif (b &&& e_CorILMethod_FormatMask) = e_CorILMethod_FatFormat then - let hasMoreSections = (b &&& e_CorILMethod_MoreSects) <> 0x0uy - let initlocals = (b &&& e_CorILMethod_InitLocals) <> 0x0uy - let maxstack = seekReadUInt16AsInt32 pev (baseRVA + 2) - let codeSize = seekReadInt32 pev (baseRVA + 4) - let localsTab, localToken = seekReadUncodedToken pev (baseRVA + 8) - let codeBase = baseRVA + 12 - let locals = - if localToken = 0x0 then [] - else - if localsTab <> TableNames.StandAloneSig then dprintn "strange table for locals token" - readBlobHeapAsLocalsSig ctxt numtypars (seekReadStandAloneSigRow ctxt pev localToken) - - // fat format for "+nm+", code size = " + string codeSize+", hasMoreSections = "+(if hasMoreSections then "true" else "false")+", b = "+string b) - - // Read the method body - let instrs, rawToLabel, lab2pc, raw2nextLab = seekReadTopCode ctxt pev mdv numtypars ( codeSize) codeBase seqpoints - - // Read all the sections that follow the method body. - // These contain the exception clauses. - let nextSectionBase = ref (align 4 (codeBase + codeSize)) - let moreSections = ref hasMoreSections - let seh = ref [] - while !moreSections do - let sectionBase = !nextSectionBase - let sectionFlag = seekReadByte pev sectionBase - // fat format for "+nm+", sectionFlag = " + string sectionFlag) - let sectionSize, clauses = - if (sectionFlag &&& e_CorILMethod_Sect_FatFormat) <> 0x0uy then - let bigSize = (seekReadInt32 pev sectionBase) >>>& 8 - // bigSize = "+string bigSize) - let clauses = - if (sectionFlag &&& e_CorILMethod_Sect_EHTable) <> 0x0uy then - // WORKAROUND: The ECMA spec says this should be - // let numClauses = ((bigSize - 4) / 24) in - // but the CCI IL generator generates multiples of 24 - let numClauses = (bigSize / 24) - - List.init numClauses (fun i -> - let clauseBase = sectionBase + 4 + (i * 24) - let kind = seekReadInt32 pev (clauseBase + 0) - let st1 = seekReadInt32 pev (clauseBase + 4) - let sz1 = seekReadInt32 pev (clauseBase + 8) - let st2 = seekReadInt32 pev (clauseBase + 12) - let sz2 = seekReadInt32 pev (clauseBase + 16) - let extra = seekReadInt32 pev (clauseBase + 20) - (kind, st1, sz1, st2, sz2, extra)) - else [] - bigSize, clauses - else - let smallSize = seekReadByteAsInt32 pev (sectionBase + 0x01) - let clauses = - if (sectionFlag &&& e_CorILMethod_Sect_EHTable) <> 0x0uy then - // WORKAROUND: The ECMA spec says this should be - // let numClauses = ((smallSize - 4) / 12) in - // but the C# compiler (or some IL generator) generates multiples of 12 - let numClauses = (smallSize / 12) - // dprintn (nm+" has " + string numClauses + " tiny seh clauses") - List.init numClauses (fun i -> - let clauseBase = sectionBase + 4 + (i * 12) - let kind = seekReadUInt16AsInt32 pev (clauseBase + 0) - if logging then dprintn ("One tiny SEH clause, kind = "+string kind) - let st1 = seekReadUInt16AsInt32 pev (clauseBase + 2) - let sz1 = seekReadByteAsInt32 pev (clauseBase + 4) - let st2 = seekReadUInt16AsInt32 pev (clauseBase + 5) - let sz2 = seekReadByteAsInt32 pev (clauseBase + 7) - let extra = seekReadInt32 pev (clauseBase + 8) - (kind, st1, sz1, st2, sz2, extra)) - else - [] - smallSize, clauses - - // Morph together clauses that cover the same range - let sehClauses = - let sehMap = Dictionary<_, _>(clauses.Length, HashIdentity.Structural) - - List.iter - (fun (kind, st1, sz1, st2, sz2, extra) -> - let tryStart = rawToLabel st1 - let tryFinish = rawToLabel (st1 + sz1) - let handlerStart = rawToLabel st2 - let handlerFinish = rawToLabel (st2 + sz2) - let clause = - if kind = e_COR_ILEXCEPTION_CLAUSE_EXCEPTION then - ILExceptionClause.TypeCatch(seekReadTypeDefOrRef ctxt numtypars AsObject List.empty (uncodedTokenToTypeDefOrRefOrSpec (i32ToUncodedToken extra)), (handlerStart, handlerFinish) ) - elif kind = e_COR_ILEXCEPTION_CLAUSE_FILTER then - let filterStart = rawToLabel extra - let filterFinish = handlerStart - ILExceptionClause.FilterCatch((filterStart, filterFinish), (handlerStart, handlerFinish)) - elif kind = e_COR_ILEXCEPTION_CLAUSE_FINALLY then - ILExceptionClause.Finally(handlerStart, handlerFinish) - elif kind = e_COR_ILEXCEPTION_CLAUSE_FAULT then - ILExceptionClause.Fault(handlerStart, handlerFinish) - else begin - dprintn (ctxt.fileName + ": unknown exception handler kind: "+string kind) - ILExceptionClause.Finally(handlerStart, handlerFinish) - end - - let key = (tryStart, tryFinish) - match sehMap.TryGetValue key with - | true, prev -> sehMap.[key] <- prev @ [clause] - | _ -> sehMap.[key] <- [clause]) - clauses - ([], sehMap) ||> Seq.fold (fun acc (KeyValue(key, bs)) -> [ for b in bs -> {Range=key; Clause=b}: ILExceptionSpec ] @ acc) - seh := sehClauses - moreSections := (sectionFlag &&& e_CorILMethod_Sect_MoreSects) <> 0x0uy - nextSectionBase := sectionBase + sectionSize - done (* while *) - - (* Convert the linear code format to the nested code format *) - if logging then dprintn ("doing localPdbInfos2") - let localPdbInfos2 = List.map (fun f -> f raw2nextLab) localPdbInfos - if logging then dprintn ("done localPdbInfos2, checking code...") - let code = buildILCode nm lab2pc instrs !seh localPdbInfos2 - if logging then dprintn ("done checking code.") - MethodBody.IL - { IsZeroInit=initlocals - MaxStack= maxstack - NoInlining=noinline - AggressiveInlining=aggressiveinline - Locals = locals - Code=code - SourceMarker=methRangePdbInfo} - else - if logging then failwith "unknown format" - MethodBody.Abstract) - -and int32AsILVariantType (ctxt: ILMetadataReader) (n: int32) = - if List.memAssoc n (Lazy.force ILVariantTypeRevMap) then - List.assoc n (Lazy.force ILVariantTypeRevMap) - elif (n &&& vt_ARRAY) <> 0x0 then ILNativeVariant.Array (int32AsILVariantType ctxt (n &&& (~~~ vt_ARRAY))) - elif (n &&& vt_VECTOR) <> 0x0 then ILNativeVariant.Vector (int32AsILVariantType ctxt (n &&& (~~~ vt_VECTOR))) - elif (n &&& vt_BYREF) <> 0x0 then ILNativeVariant.Byref (int32AsILVariantType ctxt (n &&& (~~~ vt_BYREF))) - else (dprintn (ctxt.fileName + ": int32AsILVariantType ctxt: unexpected variant type, n = "+string n) ; ILNativeVariant.Empty) - -and readBlobHeapAsNativeType ctxt blobIdx = - // reading native type blob "+string blobIdx) - let bytes = readBlobHeap ctxt blobIdx - let res, _ = sigptrGetILNativeType ctxt bytes 0 - res - -and sigptrGetILNativeType ctxt bytes sigptr = - // reading native type blob, sigptr= "+string sigptr) - let ntbyte, sigptr = sigptrGetByte bytes sigptr - if List.memAssoc ntbyte (Lazy.force ILNativeTypeMap) then - List.assoc ntbyte (Lazy.force ILNativeTypeMap), sigptr - elif ntbyte = 0x0uy then ILNativeType.Empty, sigptr - elif ntbyte = nt_CUSTOMMARSHALER then - // reading native type blob CM1, sigptr= "+string sigptr+ ", bytes.Length = "+string bytes.Length) - let guidLen, sigptr = sigptrGetZInt32 bytes sigptr - // reading native type blob CM2, sigptr= "+string sigptr+", guidLen = "+string ( guidLen)) - let guid, sigptr = sigptrGetBytes ( guidLen) bytes sigptr - // reading native type blob CM3, sigptr= "+string sigptr) - let nativeTypeNameLen, sigptr = sigptrGetZInt32 bytes sigptr - // reading native type blob CM4, sigptr= "+string sigptr+", nativeTypeNameLen = "+string ( nativeTypeNameLen)) - let nativeTypeName, sigptr = sigptrGetString ( nativeTypeNameLen) bytes sigptr - // reading native type blob CM4, sigptr= "+string sigptr+", nativeTypeName = "+nativeTypeName) - // reading native type blob CM5, sigptr= "+string sigptr) - let custMarshallerNameLen, sigptr = sigptrGetZInt32 bytes sigptr - // reading native type blob CM6, sigptr= "+string sigptr+", custMarshallerNameLen = "+string ( custMarshallerNameLen)) - let custMarshallerName, sigptr = sigptrGetString ( custMarshallerNameLen) bytes sigptr - // reading native type blob CM7, sigptr= "+string sigptr+", custMarshallerName = "+custMarshallerName) - let cookieStringLen, sigptr = sigptrGetZInt32 bytes sigptr - // reading native type blob CM8, sigptr= "+string sigptr+", cookieStringLen = "+string ( cookieStringLen)) - let cookieString, sigptr = sigptrGetBytes ( cookieStringLen) bytes sigptr - // reading native type blob CM9, sigptr= "+string sigptr) - ILNativeType.Custom (guid, nativeTypeName, custMarshallerName, cookieString), sigptr - elif ntbyte = nt_FIXEDSYSSTRING then - let i, sigptr = sigptrGetZInt32 bytes sigptr - ILNativeType.FixedSysString i, sigptr - elif ntbyte = nt_FIXEDARRAY then - let i, sigptr = sigptrGetZInt32 bytes sigptr - ILNativeType.FixedArray i, sigptr - elif ntbyte = nt_SAFEARRAY then - (if sigptr >= bytes.Length then - ILNativeType.SafeArray(ILNativeVariant.Empty, None), sigptr - else - let i, sigptr = sigptrGetZInt32 bytes sigptr - if sigptr >= bytes.Length then - ILNativeType.SafeArray (int32AsILVariantType ctxt i, None), sigptr - else - let len, sigptr = sigptrGetZInt32 bytes sigptr - let s, sigptr = sigptrGetString ( len) bytes sigptr - ILNativeType.SafeArray (int32AsILVariantType ctxt i, Some s), sigptr) - elif ntbyte = nt_ARRAY then - if sigptr >= bytes.Length then - ILNativeType.Array(None, None), sigptr - else - let nt, sigptr = - let u, sigptr' = sigptrGetZInt32 bytes sigptr - if (u = int nt_MAX) then - ILNativeType.Empty, sigptr' - else - // NOTE: go back to start and read native type - sigptrGetILNativeType ctxt bytes sigptr - if sigptr >= bytes.Length then - ILNativeType.Array (Some nt, None), sigptr - else - let pnum, sigptr = sigptrGetZInt32 bytes sigptr - if sigptr >= bytes.Length then - ILNativeType.Array (Some nt, Some(pnum, None)), sigptr - else - let additive, sigptr = - if sigptr >= bytes.Length then 0, sigptr - else sigptrGetZInt32 bytes sigptr - ILNativeType.Array (Some nt, Some(pnum, Some additive)), sigptr - else (ILNativeType.Empty, sigptr) - -// Note, pectxtEager and pevEager must not be captured by the results of this function -// As a result, reading the resource offsets in the physical file is done eagerly to avoid holding on to any resources -and seekReadManifestResources (ctxt: ILMetadataReader) canReduceMemory (mdv: BinaryView) (pectxtEager: PEReader) (pevEager: BinaryView) = - mkILResources - [ for i = 1 to ctxt.getNumRows TableNames.ManifestResource do - let (offset, flags, nameIdx, implIdx) = seekReadManifestResourceRow ctxt mdv i - - let scoref = seekReadImplAsScopeRef ctxt mdv implIdx - - let location = - match scoref with - | ILScopeRef.Local -> - let start = pectxtEager.anyV2P ("resource", offset + pectxtEager.resourcesAddr) - let resourceLength = seekReadInt32 pevEager start - let offsetOfBytesFromStartOfPhysicalPEFile = start + 4 - let bytes = - let bytes = pevEager.Slice(offsetOfBytesFromStartOfPhysicalPEFile, resourceLength) - // If we are trying to reduce memory, create a memory mapped file based on the contents. - if canReduceMemory then - ByteMemory.CreateMemoryMappedFile bytes - else - ByteMemory.FromArray(bytes.ToArray()) - ILResourceLocation.Local(bytes.AsReadOnly()) - - | ILScopeRef.Module mref -> ILResourceLocation.File (mref, offset) - | ILScopeRef.Assembly aref -> ILResourceLocation.Assembly aref - | _ -> failwith "seekReadManifestResources: Invalid ILScopeRef" - - let r = - { Name= readStringHeap ctxt nameIdx - Location = location - Access = (if (flags &&& 0x01) <> 0x0 then ILResourceAccess.Public else ILResourceAccess.Private) - CustomAttrsStored = ctxt.customAttrsReader_ManifestResource - MetadataIndex = i } - yield r ] - -and seekReadNestedExportedTypes ctxt (exported: _ []) (nested: Lazy<_ []>) parentIdx = - mkILNestedExportedTypesLazy - (lazy - nested.Force().[parentIdx-1] - |> List.map (fun i -> - let (flags, _tok, nameIdx, namespaceIdx, _implIdx) = exported.[i-1] - { Name = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) - Access = (match typeAccessOfFlags flags with - | ILTypeDefAccess.Nested n -> n - | _ -> failwith "non-nested access for a nested type described as being in an auxiliary module") - Nested = seekReadNestedExportedTypes ctxt exported nested i - CustomAttrsStored = ctxt.customAttrsReader_ExportedType - MetadataIndex = i } - )) - -and seekReadTopExportedTypes (ctxt: ILMetadataReader) = - mkILExportedTypesLazy - (lazy - let mdv = ctxt.mdfile.GetView() - let numRows = ctxt.getNumRows TableNames.ExportedType - let exported = [| for i in 1..numRows -> seekReadExportedTypeRow ctxt mdv i |] - - // add each nested type id to their parent's children list - let nested = lazy ( - let nested = [| for _i in 1..numRows -> [] |] - for i = 1 to numRows do - let (flags,_,_,_,TaggedIndex(tag, idx)) = exported.[i-1] - if not (isTopTypeDef flags) && (tag = i_ExportedType) then - nested.[idx-1] <- i :: nested.[idx-1] - nested) - - // return top exported types - [ for i = 1 to numRows do - let (flags, _tok, nameIdx, namespaceIdx, implIdx) = exported.[i-1] - let (TaggedIndex(tag, _idx)) = implIdx - - // if not a nested type - if (isTopTypeDef flags) && (tag <> i_ExportedType) then - yield - { ScopeRef = seekReadImplAsScopeRef ctxt mdv implIdx - Name = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) - Attributes = enum(flags) - Nested = seekReadNestedExportedTypes ctxt exported nested i - CustomAttrsStored = ctxt.customAttrsReader_ExportedType - MetadataIndex = i } - ]) - -#if !FX_NO_PDB_READER -let getPdbReader pdbDirPath fileName = - match pdbDirPath with - | None -> None - | Some pdbpath -> - try - let pdbr = pdbReadOpen fileName pdbpath - let pdbdocs = pdbReaderGetDocuments pdbr - - let tab = new Dictionary<_, _>(Array.length pdbdocs) - pdbdocs |> Array.iter (fun pdbdoc -> - let url = pdbDocumentGetURL pdbdoc - tab.[url] <- - ILSourceDocument.Create(language=Some (pdbDocumentGetLanguage pdbdoc), - vendor = Some (pdbDocumentGetLanguageVendor pdbdoc), - documentType = Some (pdbDocumentGetType pdbdoc), - file = url)) - - let docfun url = - match tab.TryGetValue url with - | true, doc -> doc - | _ -> failwith ("Document with URL " + url + " not found in list of documents in the PDB file") - Some (pdbr, docfun) - with e -> dprintn ("* Warning: PDB file could not be read and will be ignored: "+e.Message); None -#endif - -// Note, pectxtEager and pevEager must not be captured by the results of this function -let openMetadataReader (fileName, mdfile: BinaryFile, metadataPhysLoc, peinfo, pectxtEager: PEReader, pevEager, pectxtCaptured, reduceMemoryUsage) = - let mdv = mdfile.GetView() - let magic = seekReadUInt16AsInt32 mdv metadataPhysLoc - if magic <> 0x5342 then failwith (fileName + ": bad metadata magic number: " + string magic) - let magic2 = seekReadUInt16AsInt32 mdv (metadataPhysLoc + 2) - if magic2 <> 0x424a then failwith "bad metadata magic number" - let _majorMetadataVersion = seekReadUInt16 mdv (metadataPhysLoc + 4) - let _minorMetadataVersion = seekReadUInt16 mdv (metadataPhysLoc + 6) - - let versionLength = seekReadInt32 mdv (metadataPhysLoc + 12) - let ilMetadataVersion = seekReadBytes mdv (metadataPhysLoc + 16) versionLength |> Array.filter (fun b -> b <> 0uy) - let x = align 0x04 (16 + versionLength) - let numStreams = seekReadUInt16AsInt32 mdv (metadataPhysLoc + x + 2) - let streamHeadersStart = (metadataPhysLoc + x + 4) - - let tryFindStream name = - let rec look i pos = - if i >= numStreams then None - else - let offset = seekReadInt32 mdv (pos + 0) - let length = seekReadInt32 mdv (pos + 4) - let res = ref true - let fin = ref false - let n = ref 0 - // read and compare the stream name byte by byte - while (not !fin) do - let c= seekReadByteAsInt32 mdv (pos + 8 + (!n)) - if c = 0 then - fin := true - elif !n >= Array.length name || c <> name.[!n] then - res := false - incr n - if !res then Some(offset + metadataPhysLoc, length) - else look (i+1) (align 0x04 (pos + 8 + (!n))) - look 0 streamHeadersStart - - let findStream name = - match tryFindStream name with - | None -> (0x0, 0x0) - | Some positions -> positions - - let (tablesStreamPhysLoc, _tablesStreamSize) = - match tryFindStream [| 0x23; 0x7e |] (* #~ *) with - | Some res -> res - | None -> - match tryFindStream [| 0x23; 0x2d |] (* #-: at least one DLL I've seen uses this! *) with - | Some res -> res - | None -> - let firstStreamOffset = seekReadInt32 mdv (streamHeadersStart + 0) - let firstStreamLength = seekReadInt32 mdv (streamHeadersStart + 4) - firstStreamOffset, firstStreamLength - - let (stringsStreamPhysicalLoc, stringsStreamSize) = findStream [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; |] (* #Strings *) - let (userStringsStreamPhysicalLoc, userStringsStreamSize) = findStream [| 0x23; 0x55; 0x53; |] (* #US *) - let (guidsStreamPhysicalLoc, _guidsStreamSize) = findStream [| 0x23; 0x47; 0x55; 0x49; 0x44; |] (* #GUID *) - let (blobsStreamPhysicalLoc, blobsStreamSize) = findStream [| 0x23; 0x42; 0x6c; 0x6f; 0x62; |] (* #Blob *) - - let tableKinds = - [|kindModule (* Table 0 *) - kindTypeRef (* Table 1 *) - kindTypeDef (* Table 2 *) - kindIllegal (* kindFieldPtr *) (* Table 3 *) - kindFieldDef (* Table 4 *) - kindIllegal (* kindMethodPtr *) (* Table 5 *) - kindMethodDef (* Table 6 *) - kindIllegal (* kindParamPtr *) (* Table 7 *) - kindParam (* Table 8 *) - kindInterfaceImpl (* Table 9 *) - kindMemberRef (* Table 10 *) - kindConstant (* Table 11 *) - kindCustomAttribute (* Table 12 *) - kindFieldMarshal (* Table 13 *) - kindDeclSecurity (* Table 14 *) - kindClassLayout (* Table 15 *) - kindFieldLayout (* Table 16 *) - kindStandAloneSig (* Table 17 *) - kindEventMap (* Table 18 *) - kindIllegal (* kindEventPtr *) (* Table 19 *) - kindEvent (* Table 20 *) - kindPropertyMap (* Table 21 *) - kindIllegal (* kindPropertyPtr *) (* Table 22 *) - kindProperty (* Table 23 *) - kindMethodSemantics (* Table 24 *) - kindMethodImpl (* Table 25 *) - kindModuleRef (* Table 26 *) - kindTypeSpec (* Table 27 *) - kindImplMap (* Table 28 *) - kindFieldRVA (* Table 29 *) - kindIllegal (* kindENCLog *) (* Table 30 *) - kindIllegal (* kindENCMap *) (* Table 31 *) - kindAssembly (* Table 32 *) - kindIllegal (* kindAssemblyProcessor *) (* Table 33 *) - kindIllegal (* kindAssemblyOS *) (* Table 34 *) - kindAssemblyRef (* Table 35 *) - kindIllegal (* kindAssemblyRefProcessor *) (* Table 36 *) - kindIllegal (* kindAssemblyRefOS *) (* Table 37 *) - kindFileRef (* Table 38 *) - kindExportedType (* Table 39 *) - kindManifestResource (* Table 40 *) - kindNested (* Table 41 *) - kindGenericParam_v2_0 (* Table 42 *) - kindMethodSpec (* Table 43 *) - kindGenericParamConstraint (* Table 44 *) - kindIllegal (* Table 45 *) - kindIllegal (* Table 46 *) - kindIllegal (* Table 47 *) - kindIllegal (* Table 48 *) - kindIllegal (* Table 49 *) - kindIllegal (* Table 50 *) - kindIllegal (* Table 51 *) - kindIllegal (* Table 52 *) - kindIllegal (* Table 53 *) - kindIllegal (* Table 54 *) - kindIllegal (* Table 55 *) - kindIllegal (* Table 56 *) - kindIllegal (* Table 57 *) - kindIllegal (* Table 58 *) - kindIllegal (* Table 59 *) - kindIllegal (* Table 60 *) - kindIllegal (* Table 61 *) - kindIllegal (* Table 62 *) - kindIllegal (* Table 63 *) - |] - - let heapSizes = seekReadByteAsInt32 mdv (tablesStreamPhysLoc + 6) - let valid = seekReadInt64 mdv (tablesStreamPhysLoc + 8) - let sorted = seekReadInt64 mdv (tablesStreamPhysLoc + 16) - let tablesPresent, tableRowCount, startOfTables = - let present = ref [] - let numRows = Array.create 64 0 - let prevNumRowIdx = ref (tablesStreamPhysLoc + 24) - for i = 0 to 63 do - if (valid &&& (int64 1 <<< i)) <> int64 0 then - present := i :: !present - numRows.[i] <- (seekReadInt32 mdv !prevNumRowIdx) - prevNumRowIdx := !prevNumRowIdx + 4 - List.rev !present, numRows, !prevNumRowIdx - - let getNumRows (tab: TableName) = tableRowCount.[tab.Index] - let numTables = tablesPresent.Length - let stringsBigness = (heapSizes &&& 1) <> 0 - let guidsBigness = (heapSizes &&& 2) <> 0 - let blobsBigness = (heapSizes &&& 4) <> 0 - - if logging then dprintn (fileName + ": numTables = "+string numTables) - if logging && stringsBigness then dprintn (fileName + ": strings are big") - if logging && blobsBigness then dprintn (fileName + ": blobs are big") - - let tableBigness = Array.map (fun n -> n >= 0x10000) tableRowCount - - let codedBigness nbits tab = - let rows = getNumRows tab - rows >= (0x10000 >>>& nbits) - - let tdorBigness = - codedBigness 2 TableNames.TypeDef || - codedBigness 2 TableNames.TypeRef || - codedBigness 2 TableNames.TypeSpec - - let tomdBigness = - codedBigness 1 TableNames.TypeDef || - codedBigness 1 TableNames.Method - - let hcBigness = - codedBigness 2 TableNames.Field || - codedBigness 2 TableNames.Param || - codedBigness 2 TableNames.Property - - let hcaBigness = - codedBigness 5 TableNames.Method || - codedBigness 5 TableNames.Field || - codedBigness 5 TableNames.TypeRef || - codedBigness 5 TableNames.TypeDef || - codedBigness 5 TableNames.Param || - codedBigness 5 TableNames.InterfaceImpl || - codedBigness 5 TableNames.MemberRef || - codedBigness 5 TableNames.Module || - codedBigness 5 TableNames.Permission || - codedBigness 5 TableNames.Property || - codedBigness 5 TableNames.Event || - codedBigness 5 TableNames.StandAloneSig || - codedBigness 5 TableNames.ModuleRef || - codedBigness 5 TableNames.TypeSpec || - codedBigness 5 TableNames.Assembly || - codedBigness 5 TableNames.AssemblyRef || - codedBigness 5 TableNames.File || - codedBigness 5 TableNames.ExportedType || - codedBigness 5 TableNames.ManifestResource || - codedBigness 5 TableNames.GenericParam || - codedBigness 5 TableNames.GenericParamConstraint || - codedBigness 5 TableNames.MethodSpec - - - let hfmBigness = - codedBigness 1 TableNames.Field || - codedBigness 1 TableNames.Param - - let hdsBigness = - codedBigness 2 TableNames.TypeDef || - codedBigness 2 TableNames.Method || - codedBigness 2 TableNames.Assembly - - let mrpBigness = - codedBigness 3 TableNames.TypeRef || - codedBigness 3 TableNames.ModuleRef || - codedBigness 3 TableNames.Method || - codedBigness 3 TableNames.TypeSpec - - let hsBigness = - codedBigness 1 TableNames.Event || - codedBigness 1 TableNames.Property - - let mdorBigness = - codedBigness 1 TableNames.Method || - codedBigness 1 TableNames.MemberRef - - let mfBigness = - codedBigness 1 TableNames.Field || - codedBigness 1 TableNames.Method - - let iBigness = - codedBigness 2 TableNames.File || - codedBigness 2 TableNames.AssemblyRef || - codedBigness 2 TableNames.ExportedType - - let catBigness = - codedBigness 3 TableNames.Method || - codedBigness 3 TableNames.MemberRef - - let rsBigness = - codedBigness 2 TableNames.Module || - codedBigness 2 TableNames.ModuleRef || - codedBigness 2 TableNames.AssemblyRef || - codedBigness 2 TableNames.TypeRef - - let rowKindSize (RowKind kinds) = - kinds |> List.sumBy (fun x -> - match x with - | UShort -> 2 - | ULong -> 4 - | Byte -> 1 - | Data -> 4 - | GGuid -> (if guidsBigness then 4 else 2) - | Blob -> (if blobsBigness then 4 else 2) - | SString -> (if stringsBigness then 4 else 2) - | SimpleIndex tab -> (if tableBigness.[tab.Index] then 4 else 2) - | TypeDefOrRefOrSpec -> (if tdorBigness then 4 else 2) - | TypeOrMethodDef -> (if tomdBigness then 4 else 2) - | HasConstant -> (if hcBigness then 4 else 2) - | HasCustomAttribute -> (if hcaBigness then 4 else 2) - | HasFieldMarshal -> (if hfmBigness then 4 else 2) - | HasDeclSecurity -> (if hdsBigness then 4 else 2) - | MemberRefParent -> (if mrpBigness then 4 else 2) - | HasSemantics -> (if hsBigness then 4 else 2) - | MethodDefOrRef -> (if mdorBigness then 4 else 2) - | MemberForwarded -> (if mfBigness then 4 else 2) - | Implementation -> (if iBigness then 4 else 2) - | CustomAttributeType -> (if catBigness then 4 else 2) - | ResolutionScope -> (if rsBigness then 4 else 2)) - - let tableRowSizes = tableKinds |> Array.map rowKindSize - - let tablePhysLocations = - let res = Array.create 64 0x0 - let mutable prevTablePhysLoc = startOfTables - for i = 0 to 63 do - res.[i] <- prevTablePhysLoc - prevTablePhysLoc <- prevTablePhysLoc + (tableRowCount.[i] * tableRowSizes.[i]) - res - - let inbase = Filename.fileNameOfPath fileName + ": " - - // All the caches. The sizes are guesstimates for the rough sharing-density of the assembly - let cacheAssemblyRef = mkCacheInt32 false inbase "ILAssemblyRef" (getNumRows TableNames.AssemblyRef) - let cacheMethodSpecAsMethodData = mkCacheGeneric reduceMemoryUsage inbase "MethodSpecAsMethodData" (getNumRows TableNames.MethodSpec / 20 + 1) - let cacheMemberRefAsMemberData = mkCacheGeneric reduceMemoryUsage inbase "MemberRefAsMemberData" (getNumRows TableNames.MemberRef / 20 + 1) - let cacheCustomAttr = mkCacheGeneric reduceMemoryUsage inbase "CustomAttr" (getNumRows TableNames.CustomAttribute / 50 + 1) - let cacheTypeRef = mkCacheInt32 false inbase "ILTypeRef" (getNumRows TableNames.TypeRef / 20 + 1) - let cacheTypeRefAsType = mkCacheGeneric reduceMemoryUsage inbase "TypeRefAsType" (getNumRows TableNames.TypeRef / 20 + 1) - let cacheBlobHeapAsPropertySig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsPropertySig" (getNumRows TableNames.Property / 20 + 1) - let cacheBlobHeapAsFieldSig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsFieldSig" (getNumRows TableNames.Field / 20 + 1) - let cacheBlobHeapAsMethodSig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsMethodSig" (getNumRows TableNames.Method / 20 + 1) - let cacheTypeDefAsType = mkCacheGeneric reduceMemoryUsage inbase "TypeDefAsType" (getNumRows TableNames.TypeDef / 20 + 1) - let cacheMethodDefAsMethodData = mkCacheInt32 reduceMemoryUsage inbase "MethodDefAsMethodData" (getNumRows TableNames.Method / 20 + 1) - let cacheGenericParams = mkCacheGeneric reduceMemoryUsage inbase "GenericParams" (getNumRows TableNames.GenericParam / 20 + 1) - let cacheFieldDefAsFieldSpec = mkCacheInt32 reduceMemoryUsage inbase "FieldDefAsFieldSpec" (getNumRows TableNames.Field / 20 + 1) - let cacheUserStringHeap = mkCacheInt32 reduceMemoryUsage inbase "UserStringHeap" ( userStringsStreamSize / 20 + 1) - // nb. Lots and lots of cache hits on this cache, hence never optimize cache away - let cacheStringHeap = mkCacheInt32 false inbase "string heap" ( stringsStreamSize / 50 + 1) - let cacheBlobHeap = mkCacheInt32 reduceMemoryUsage inbase "blob heap" ( blobsStreamSize / 50 + 1) - - // These tables are not required to enforce sharing fo the final data - // structure, but are very useful as searching these tables gives rise to many reads - // in standard applications. - - let cacheNestedRow = mkCacheInt32 reduceMemoryUsage inbase "Nested Table Rows" (getNumRows TableNames.Nested / 20 + 1) - let cacheConstantRow = mkCacheInt32 reduceMemoryUsage inbase "Constant Rows" (getNumRows TableNames.Constant / 20 + 1) - let cacheMethodSemanticsRow = mkCacheInt32 reduceMemoryUsage inbase "MethodSemantics Rows" (getNumRows TableNames.MethodSemantics / 20 + 1) - let cacheTypeDefRow = mkCacheInt32 reduceMemoryUsage inbase "ILTypeDef Rows" (getNumRows TableNames.TypeDef / 20 + 1) - - let rowAddr (tab: TableName) idx = tablePhysLocations.[tab.Index] + (idx - 1) * tableRowSizes.[tab.Index] - - // Build the reader context - // Use an initialization hole - let ctxtH = ref None - let ctxt: ILMetadataReader = - { sorted=sorted - getNumRows=getNumRows - mdfile=mdfile - dataEndPoints = match pectxtCaptured with None -> notlazy [] | Some pectxt -> getDataEndPointsDelayed pectxt ctxtH - pectxtCaptured=pectxtCaptured - entryPointToken=pectxtEager.entryPointToken - fileName=fileName - userStringsStreamPhysicalLoc = userStringsStreamPhysicalLoc - stringsStreamPhysicalLoc = stringsStreamPhysicalLoc - blobsStreamPhysicalLoc = blobsStreamPhysicalLoc - blobsStreamSize = blobsStreamSize - memoizeString = Tables.memoize id - readUserStringHeap = cacheUserStringHeap (readUserStringHeapUncached ctxtH) - readStringHeap = cacheStringHeap (readStringHeapUncached ctxtH) - readBlobHeap = cacheBlobHeap (readBlobHeapUncached ctxtH) - seekReadNestedRow = cacheNestedRow (seekReadNestedRowUncached ctxtH) - seekReadConstantRow = cacheConstantRow (seekReadConstantRowUncached ctxtH) - seekReadMethodSemanticsRow = cacheMethodSemanticsRow (seekReadMethodSemanticsRowUncached ctxtH) - seekReadTypeDefRow = cacheTypeDefRow (seekReadTypeDefRowUncached ctxtH) - seekReadAssemblyRef = cacheAssemblyRef (seekReadAssemblyRefUncached ctxtH) - seekReadMethodSpecAsMethodData = cacheMethodSpecAsMethodData (seekReadMethodSpecAsMethodDataUncached ctxtH) - seekReadMemberRefAsMethodData = cacheMemberRefAsMemberData (seekReadMemberRefAsMethodDataUncached ctxtH) - seekReadMemberRefAsFieldSpec = seekReadMemberRefAsFieldSpecUncached ctxtH - seekReadCustomAttr = cacheCustomAttr (seekReadCustomAttrUncached ctxtH) - seekReadTypeRef = cacheTypeRef (seekReadTypeRefUncached ctxtH) - readBlobHeapAsPropertySig = cacheBlobHeapAsPropertySig (readBlobHeapAsPropertySigUncached ctxtH) - readBlobHeapAsFieldSig = cacheBlobHeapAsFieldSig (readBlobHeapAsFieldSigUncached ctxtH) - readBlobHeapAsMethodSig = cacheBlobHeapAsMethodSig (readBlobHeapAsMethodSigUncached ctxtH) - readBlobHeapAsLocalsSig = readBlobHeapAsLocalsSigUncached ctxtH - seekReadTypeDefAsType = cacheTypeDefAsType (seekReadTypeDefAsTypeUncached ctxtH) - seekReadTypeRefAsType = cacheTypeRefAsType (seekReadTypeRefAsTypeUncached ctxtH) - seekReadMethodDefAsMethodData = cacheMethodDefAsMethodData (seekReadMethodDefAsMethodDataUncached ctxtH) - seekReadGenericParams = cacheGenericParams (seekReadGenericParamsUncached ctxtH) - seekReadFieldDefAsFieldSpec = cacheFieldDefAsFieldSpec (seekReadFieldDefAsFieldSpecUncached ctxtH) - customAttrsReader_Module = customAttrsReader ctxtH hca_Module - customAttrsReader_Assembly = customAttrsReader ctxtH hca_Assembly - customAttrsReader_TypeDef = customAttrsReader ctxtH hca_TypeDef - customAttrsReader_GenericParam= customAttrsReader ctxtH hca_GenericParam - customAttrsReader_FieldDef= customAttrsReader ctxtH hca_FieldDef - customAttrsReader_MethodDef= customAttrsReader ctxtH hca_MethodDef - customAttrsReader_ParamDef= customAttrsReader ctxtH hca_ParamDef - customAttrsReader_Event= customAttrsReader ctxtH hca_Event - customAttrsReader_Property= customAttrsReader ctxtH hca_Property - customAttrsReader_ManifestResource= customAttrsReader ctxtH hca_ManifestResource - customAttrsReader_ExportedType= customAttrsReader ctxtH hca_ExportedType - securityDeclsReader_TypeDef = securityDeclsReader ctxtH hds_TypeDef - securityDeclsReader_MethodDef = securityDeclsReader ctxtH hds_MethodDef - securityDeclsReader_Assembly = securityDeclsReader ctxtH hds_Assembly - typeDefReader = typeDefReader ctxtH - guidsStreamPhysicalLoc = guidsStreamPhysicalLoc - rowAddr=rowAddr - rsBigness=rsBigness - tdorBigness=tdorBigness - tomdBigness=tomdBigness - hcBigness=hcBigness - hcaBigness=hcaBigness - hfmBigness=hfmBigness - hdsBigness=hdsBigness - mrpBigness=mrpBigness - hsBigness=hsBigness - mdorBigness=mdorBigness - mfBigness=mfBigness - iBigness=iBigness - catBigness=catBigness - stringsBigness=stringsBigness - guidsBigness=guidsBigness - blobsBigness=blobsBigness - tableBigness=tableBigness } - ctxtH := Some ctxt - - let ilModule = seekReadModule ctxt reduceMemoryUsage pectxtEager pevEager peinfo (System.Text.Encoding.UTF8.GetString (ilMetadataVersion, 0, ilMetadataVersion.Length)) 1 - let ilAssemblyRefs = lazy [ for i in 1 .. getNumRows TableNames.AssemblyRef do yield seekReadAssemblyRef ctxt i ] - - ilModule, ilAssemblyRefs - -//----------------------------------------------------------------------- -// Crack the binary headers, build a reader context and return the lazy -// read of the AbsIL module. -// ---------------------------------------------------------------------- - -let openPEFileReader (fileName, pefile: BinaryFile, pdbDirPath, noFileOnDisk) = - let pev = pefile.GetView() - (* MSDOS HEADER *) - let peSignaturePhysLoc = seekReadInt32 pev 0x3c - - (* PE HEADER *) - let peFileHeaderPhysLoc = peSignaturePhysLoc + 0x04 - let peOptionalHeaderPhysLoc = peFileHeaderPhysLoc + 0x14 - let peSignature = seekReadInt32 pev (peSignaturePhysLoc + 0) - if peSignature <> 0x4550 then failwithf "not a PE file - bad magic PE number 0x%08x, is = %A" peSignature pev - - - (* PE SIGNATURE *) - let machine = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 0) - let numSections = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 2) - let optHeaderSize = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 16) - if optHeaderSize <> 0xe0 && - optHeaderSize <> 0xf0 then failwith "not a PE file - bad optional header size" - let x64adjust = optHeaderSize - 0xe0 - let only64 = (optHeaderSize = 0xf0) (* May want to read in the optional header Magic number and check that as well... *) - let platform = match machine with | 0x8664 -> Some AMD64 | 0x200 -> Some IA64 | _ -> Some X86 - let sectionHeadersStartPhysLoc = peOptionalHeaderPhysLoc + optHeaderSize - - let flags = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 18) - let isDll = (flags &&& 0x2000) <> 0x0 - - (* OPTIONAL PE HEADER *) - let _textPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 4) (* Size of the code (text) section, or the sum of all code sections if there are multiple sections. *) - (* x86: 000000a0 *) - let _initdataPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 8) (* Size of the initialized data section, or the sum of all such sections if there are multiple data sections. *) - let _uninitdataPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 12) (* Size of the uninitialized data section, or the sum of all such sections if there are multiple data sections. *) - let _entrypointAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 16) (* RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 in a section marked execute/read for EXEs or 0 for DLLs e.g. 0x0000b57e *) - let _textAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 20) (* e.g. 0x0002000 *) - (* x86: 000000b0 *) - let dataSegmentAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 24) (* e.g. 0x0000c000 *) - (* REVIEW: For now, we'll use the DWORD at offset 24 for x64. This currently ok since fsc doesn't support true 64-bit image bases, - but we'll have to fix this up when such support is added. *) - let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 pev (peOptionalHeaderPhysLoc + 28) // Image Base Always 0x400000 (see Section 23.1). - let alignVirt = seekReadInt32 pev (peOptionalHeaderPhysLoc + 32) // Section Alignment Always 0x2000 (see Section 23.1). - let alignPhys = seekReadInt32 pev (peOptionalHeaderPhysLoc + 36) // File Alignment Either 0x200 or 0x1000. - (* x86: 000000c0 *) - let _osMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 40) // OS Major Always 4 (see Section 23.1). - let _osMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 42) // OS Minor Always 0 (see Section 23.1). - let _userMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 44) // User Major Always 0 (see Section 23.1). - let _userMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 46) // User Minor Always 0 (see Section 23.1). - let subsysMajor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 48) // SubSys Major Always 4 (see Section 23.1). - let subsysMinor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 50) // SubSys Minor Always 0 (see Section 23.1). - (* x86: 000000d0 *) - let _imageEndAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 56) // Image Size: Size, in bytes, of image, including all headers and padding - let _headerPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 60) // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding - let subsys = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 68) // SubSystem Subsystem required to run this image. - let useHighEnthropyVA = - let n = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 70) - let highEnthropyVA = 0x20us - (n &&& highEnthropyVA) = highEnthropyVA - - (* x86: 000000e0 *) - - (* WARNING: THESE ARE 64 bit ON x64/ia64 *) - (* REVIEW: If we ever decide that we need these values for x64, we'll have to read them in as 64bit and fix up the rest of the offsets. - Then again, it should suffice to just use the defaults, and still not bother... *) - (* let stackReserve = seekReadInt32 is (peOptionalHeaderPhysLoc + 72) in *) (* Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). *) - (* let stackCommit = seekReadInt32 is (peOptionalHeaderPhysLoc + 76) in *) (* Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). *) - (* let heapReserve = seekReadInt32 is (peOptionalHeaderPhysLoc + 80) in *) (* Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). *) - (* let heapCommit = seekReadInt32 is (peOptionalHeaderPhysLoc + 84) in *) (* Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). *) - - (* x86: 000000f0, x64: 00000100 *) - let _numDataDirectories = seekReadInt32 pev (peOptionalHeaderPhysLoc + 92 + x64adjust) (* Number of Data Directories: Always 0x10 (see Section 23.1). *) - (* 00000100 - these addresses are for x86 - for the x64 location, add x64adjust (0x10) *) - let _importTableAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 104 + x64adjust) (* Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 *) - let _importTableSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 108 + x64adjust) (* Size of Import Table, (see clause 24.3.1). *) - let nativeResourcesAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 112 + x64adjust) - let nativeResourcesSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 116 + x64adjust) - (* 00000110 *) - (* 00000120 *) - (* let base_relocTableNames.addr = seekReadInt32 is (peOptionalHeaderPhysLoc + 136) - let base_relocTableNames.size = seekReadInt32 is (peOptionalHeaderPhysLoc + 140) in *) - (* 00000130 *) - (* 00000140 *) - (* 00000150 *) - let _importAddrTableAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 192 + x64adjust) (* RVA of Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 *) - let _importAddrTableSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 196 + x64adjust) (* Size of Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 *) - (* 00000160 *) - let cliHeaderAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 208 + x64adjust) - let _cliHeaderSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 212 + x64adjust) - (* 00000170 *) - - - (* Crack section headers *) - - let sectionHeaders = - [ for i in 0 .. numSections-1 do - let pos = sectionHeadersStartPhysLoc + i * 0x28 - let virtSize = seekReadInt32 pev (pos + 8) - let virtAddr = seekReadInt32 pev (pos + 12) - let physLoc = seekReadInt32 pev (pos + 20) - yield (virtAddr, virtSize, physLoc) ] - - let findSectionHeader addr = - let rec look i pos = - if i >= numSections then 0x0 - else - let virtSize = seekReadInt32 pev (pos + 8) - let virtAddr = seekReadInt32 pev (pos + 12) - if (addr >= virtAddr && addr < virtAddr + virtSize) then pos - else look (i+1) (pos + 0x28) - look 0 sectionHeadersStartPhysLoc - - let textHeaderStart = findSectionHeader cliHeaderAddr - let dataHeaderStart = findSectionHeader dataSegmentAddr - (* let relocHeaderStart = findSectionHeader base_relocTableNames.addr in *) - - let _textSize = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 8) - let _textAddr = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 12) - let textSegmentPhysicalSize = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 16) - let textSegmentPhysicalLoc = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 20) - - //let dataSegmentSize = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 8) - //let dataSegmentAddr = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 12) - let dataSegmentPhysicalSize = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 16) - let dataSegmentPhysicalLoc = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 20) - - let anyV2P (n, v) = - let pev = pefile.GetView() - let rec look i pos = - if i >= numSections then (failwith (fileName + ": bad "+n+", rva "+string v); 0x0) - else - let virtSize = seekReadInt32 pev (pos + 8) - let virtAddr = seekReadInt32 pev (pos + 12) - let physLoc = seekReadInt32 pev (pos + 20) - if (v >= virtAddr && (v < virtAddr + virtSize)) then (v - virtAddr) + physLoc - else look (i+1) (pos + 0x28) - look 0 sectionHeadersStartPhysLoc - - let cliHeaderPhysLoc = anyV2P ("cli header", cliHeaderAddr) - - let _majorRuntimeVersion = seekReadUInt16 pev (cliHeaderPhysLoc + 4) - let _minorRuntimeVersion = seekReadUInt16 pev (cliHeaderPhysLoc + 6) - let metadataAddr = seekReadInt32 pev (cliHeaderPhysLoc + 8) - let metadataSize = seekReadInt32 pev (cliHeaderPhysLoc + 12) - let cliFlags = seekReadInt32 pev (cliHeaderPhysLoc + 16) - - let ilOnly = (cliFlags &&& 0x01) <> 0x00 - let only32 = (cliFlags &&& 0x02) <> 0x00 - let is32bitpreferred = (cliFlags &&& 0x00020003) <> 0x00 - let _strongnameSigned = (cliFlags &&& 0x08) <> 0x00 - let _trackdebugdata = (cliFlags &&& 0x010000) <> 0x00 - - let entryPointToken = seekReadUncodedToken pev (cliHeaderPhysLoc + 20) - let resourcesAddr = seekReadInt32 pev (cliHeaderPhysLoc + 24) - let resourcesSize = seekReadInt32 pev (cliHeaderPhysLoc + 28) - let strongnameAddr = seekReadInt32 pev (cliHeaderPhysLoc + 32) - let _strongnameSize = seekReadInt32 pev (cliHeaderPhysLoc + 36) - let vtableFixupsAddr = seekReadInt32 pev (cliHeaderPhysLoc + 40) - let _vtableFixupsSize = seekReadInt32 pev (cliHeaderPhysLoc + 44) - - if logging then dprintn (fileName + ": metadataAddr = "+string metadataAddr) - if logging then dprintn (fileName + ": resourcesAddr = "+string resourcesAddr) - if logging then dprintn (fileName + ": resourcesSize = "+string resourcesSize) - if logging then dprintn (fileName + ": nativeResourcesAddr = "+string nativeResourcesAddr) - if logging then dprintn (fileName + ": nativeResourcesSize = "+string nativeResourcesSize) - - let metadataPhysLoc = anyV2P ("metadata", metadataAddr) - //----------------------------------------------------------------------- - // Set up the PDB reader so we can read debug info for methods. - // ---------------------------------------------------------------------- -#if FX_NO_PDB_READER - let pdb = ignore pdbDirPath; None -#else - let pdb = - if runningOnMono then - None - else - getPdbReader pdbDirPath fileName -#endif - - let pectxt: PEReader = - { pdb=pdb - textSegmentPhysicalLoc=textSegmentPhysicalLoc - textSegmentPhysicalSize=textSegmentPhysicalSize - dataSegmentPhysicalLoc=dataSegmentPhysicalLoc - dataSegmentPhysicalSize=dataSegmentPhysicalSize - anyV2P=anyV2P - metadataAddr=metadataAddr - sectionHeaders=sectionHeaders - nativeResourcesAddr=nativeResourcesAddr - nativeResourcesSize=nativeResourcesSize - resourcesAddr=resourcesAddr - strongnameAddr=strongnameAddr - vtableFixupsAddr=vtableFixupsAddr - pefile=pefile - fileName=fileName - entryPointToken=entryPointToken - noFileOnDisk=noFileOnDisk - } - let peinfo = (subsys, (subsysMajor, subsysMinor), useHighEnthropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal) - (metadataPhysLoc, metadataSize, peinfo, pectxt, pev, pdb) - -let openPE (fileName, pefile, pdbDirPath, reduceMemoryUsage, noFileOnDisk) = - let (metadataPhysLoc, _metadataSize, peinfo, pectxt, pev, pdb) = openPEFileReader (fileName, pefile, pdbDirPath, noFileOnDisk) - let ilModule, ilAssemblyRefs = openMetadataReader (fileName, pefile, metadataPhysLoc, peinfo, pectxt, pev, Some pectxt, reduceMemoryUsage) - ilModule, ilAssemblyRefs, pdb - -let openPEMetadataOnly (fileName, peinfo, pectxtEager, pevEager, mdfile: BinaryFile, reduceMemoryUsage) = - openMetadataReader (fileName, mdfile, 0, peinfo, pectxtEager, pevEager, None, reduceMemoryUsage) - -let ClosePdbReader pdb = -#if FX_NO_PDB_READER - ignore pdb - () -#else - match pdb with - | Some (pdbr, _) -> pdbReadClose pdbr - | None -> () -#endif - -type ILReaderMetadataSnapshot = (obj * nativeint * int) -type ILReaderTryGetMetadataSnapshot = (* path: *) string * (* snapshotTimeStamp: *) System.DateTime -> ILReaderMetadataSnapshot option - -[] -type MetadataOnlyFlag = Yes | No - -[] -type ReduceMemoryFlag = Yes | No - -type ILReaderOptions = - { pdbDirPath: string option - reduceMemoryUsage: ReduceMemoryFlag - metadataOnly: MetadataOnlyFlag - tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot } - - -type ILModuleReader = - abstract ILModuleDef: ILModuleDef - abstract ILAssemblyRefs: ILAssemblyRef list - - /// ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false - inherit System.IDisposable - - -[] -type ILModuleReaderImpl(ilModule: ILModuleDef, ilAssemblyRefs: Lazy, dispose: unit -> unit) = - interface ILModuleReader with - member x.ILModuleDef = ilModule - member x.ILAssemblyRefs = ilAssemblyRefs.Force() - member x.Dispose() = dispose() - -// ++GLOBAL MUTABLE STATE (concurrency safe via locking) -type ILModuleReaderCacheKey = ILModuleReaderCacheKey of string * DateTime * bool * ReduceMemoryFlag * MetadataOnlyFlag - -// Cache to extend the lifetime of a limited number of readers that are otherwise eligible for GC -type ILModuleReaderCache1LockToken() = interface LockToken -let ilModuleReaderCache1 = - new AgedLookup - (stronglyHeldReaderCacheSize, - keepMax=stronglyHeldReaderCacheSize, // only strong entries - areSimilar=(fun (x, y) -> x = y)) -let ilModuleReaderCache1Lock = Lock() - -// // Cache to reuse readers that have already been created and are not yet GC'd -let ilModuleReaderCache2 = new ConcurrentDictionary>(HashIdentity.Structural) - -let stableFileHeuristicApplies fileName = - not noStableFileHeuristic && try FileSystem.IsStableFileHeuristic fileName with _ -> false - -let createByteFileChunk opts fileName chunk = - // If we're trying to reduce memory usage then we are willing to go back and re-read the binary, so we can use - // a weakly-held handle to an array of bytes. - if opts.reduceMemoryUsage = ReduceMemoryFlag.Yes && stableFileHeuristicApplies fileName then - WeakByteFile(fileName, chunk) :> BinaryFile - else - let bytes = - match chunk with - | None -> FileSystem.ReadAllBytesShim fileName - | Some (start, length) -> File.ReadBinaryChunk(fileName, start, length) - ByteFile(fileName, bytes) :> BinaryFile - -let createMemoryMapFile fileName = - let mmf, accessor, length = - let fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read) - let length = fileStream.Length - let mmf = MemoryMappedFile.CreateFromFile(fileStream, null, length, MemoryMappedFileAccess.Read, HandleInheritability.None, leaveOpen=false) - mmf, mmf.CreateViewAccessor(0L, fileStream.Length, MemoryMappedFileAccess.Read), length - let safeHolder = - { new obj() with - override x.Finalize() = - (x :?> IDisposable).Dispose() - interface IDisposable with - member x.Dispose() = - GC.SuppressFinalize x - accessor.Dispose() - mmf.Dispose() - stats.memoryMapFileClosedCount <- stats.memoryMapFileClosedCount + 1 } - stats.memoryMapFileOpenedCount <- stats.memoryMapFileOpenedCount + 1 - safeHolder, RawMemoryFile(fileName, safeHolder, accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length) :> BinaryFile - -let OpenILModuleReaderFromBytes fileName bytes opts = - let pefile = ByteFile(fileName, bytes) :> BinaryFile - let ilModule, ilAssemblyRefs, pdb = openPE (fileName, pefile, opts.pdbDirPath, (opts.reduceMemoryUsage = ReduceMemoryFlag.Yes), true) - new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) :> ILModuleReader - -let ClearAllILModuleReaderCache() = - ilModuleReaderCache1.Clear(ILModuleReaderCache1LockToken()) - ilModuleReaderCache2.Clear() - -let OpenILModuleReader fileName opts = - // Pseudo-normalize the paths. - let (ILModuleReaderCacheKey (fullPath,writeStamp,_,_,_) as key), keyOk = - try - let fullPath = FileSystem.GetFullPathShim fileName - let writeTime = FileSystem.GetLastWriteTimeShim fileName - let key = ILModuleReaderCacheKey (fullPath, writeTime, opts.pdbDirPath.IsSome, opts.reduceMemoryUsage, opts.metadataOnly) - key, true - with exn -> - System.Diagnostics.Debug.Assert(false, sprintf "Failed to compute key in OpenILModuleReader cache for '%s'. Falling back to uncached. Error = %s" fileName (exn.ToString())) - let fakeKey = ILModuleReaderCacheKey(fileName, System.DateTime.UtcNow, false, ReduceMemoryFlag.Yes, MetadataOnlyFlag.Yes) - fakeKey, false - - let cacheResult1 = - // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable - if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.TryGet(ltok, key)) - else - None - - match cacheResult1 with - | Some ilModuleReader -> ilModuleReader - | None -> - - let cacheResult2 = - // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable - if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache2.TryGetValue key - else - false, Unchecked.defaultof<_> - - let mutable res = Unchecked.defaultof<_> - match cacheResult2 with - | true, weak when weak.TryGetTarget(&res) -> res - | _ -> - - let reduceMemoryUsage = (opts.reduceMemoryUsage = ReduceMemoryFlag.Yes) - let metadataOnly = (opts.metadataOnly = MetadataOnlyFlag.Yes) - - if reduceMemoryUsage && opts.pdbDirPath.IsNone then - - // This case is used in FCS applications, devenv.exe and fsi.exe - // - let ilModuleReader = - // Check if we are doing metadataOnly reading (the most common case in both the compiler and IDE) - if metadataOnly then - - // See if tryGetMetadata gives us a BinaryFile for the metadata section alone. - let mdfileOpt = - match opts.tryGetMetadataSnapshot (fullPath, writeStamp) with - | Some (obj, start, len) -> Some (RawMemoryFile(fullPath, obj, start, len) :> BinaryFile) - | None -> None - - // For metadata-only, always use a temporary, short-lived PE file reader, preferably over a memory mapped file. - // Then use the metadata blob as the long-lived memory resource. - let disposer, pefileEager = createMemoryMapFile fullPath - use _disposer = disposer - let (metadataPhysLoc, metadataSize, peinfo, pectxtEager, pevEager, _pdb) = openPEFileReader (fullPath, pefileEager, None, false) - let mdfile = - match mdfileOpt with - | Some mdfile -> mdfile - | None -> - // If tryGetMetadata doesn't give anything, then just read the metadata chunk out of the binary - createByteFileChunk opts fullPath (Some (metadataPhysLoc, metadataSize)) - - let ilModule, ilAssemblyRefs = openPEMetadataOnly (fullPath, peinfo, pectxtEager, pevEager, mdfile, reduceMemoryUsage) - new ILModuleReaderImpl(ilModule, ilAssemblyRefs, ignore) - else - // If we are not doing metadata-only, then just go ahead and read all the bytes and hold them either strongly or weakly - // depending on the heuristic - let pefile = createByteFileChunk opts fullPath None - let ilModule, ilAssemblyRefs, _pdb = openPE (fullPath, pefile, None, reduceMemoryUsage, false) - new ILModuleReaderImpl(ilModule, ilAssemblyRefs, ignore) - - let ilModuleReader = ilModuleReader :> ILModuleReader - if keyOk then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) - ilModuleReaderCache2.[key] <- System.WeakReference<_>(ilModuleReader) - ilModuleReader - - - else - // This case is primarily used in fsc.exe. - // - // In fsc.exe, we're not trying to reduce memory usage, nor do we really care if we leak memory. - // - // Note we ignore the "metadata only" flag as it's generally OK to read in the - // whole binary for the command-line compiler: address space is rarely an issue. - // - // We do however care about avoiding locks on files that prevent their deletion during a - // multi-proc build. So use memory mapping, but only for stable files. Other files - // still use an in-memory ByteFile - let pefile = - if alwaysMemoryMapFSC || stableFileHeuristicApplies fullPath then - let _, pefile = createMemoryMapFile fullPath - pefile - else - createByteFileChunk opts fullPath None - - let ilModule, ilAssemblyRefs, pdb = openPE (fullPath, pefile, opts.pdbDirPath, reduceMemoryUsage, false) - let ilModuleReader = new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) - - let ilModuleReader = ilModuleReader :> ILModuleReader - - // Readers with PDB reader disposal logic don't go in the cache. Note the PDB reader is only used in static linking. - if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) - ilModuleReaderCache2.[key] <- WeakReference<_>(ilModuleReader) - - ilModuleReader - -[] -module Shim = - - type IAssemblyReader = - abstract GetILModuleReader: filename: string * readerOptions: ILReaderOptions -> ILModuleReader - - [] - type DefaultAssemblyReader() = - interface IAssemblyReader with - member __.GetILModuleReader(filename, readerOptions) = - OpenILModuleReader filename readerOptions - - let mutable AssemblyReader = DefaultAssemblyReader() :> IAssemblyReader diff --git a/src/absil/ilsign.fs b/src/absil/ilsign.fs deleted file mode 100644 index 6fbc1ca4525..00000000000 --- a/src/absil/ilsign.fs +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.AbstractIL.Internal.StrongNameSign - -#nowarn "9" - -open System -open System.IO -open System.Collections.Immutable -open System.Reflection.PortableExecutable -open System.Security.Cryptography -open System.Runtime.InteropServices - - type KeyType = - | Public - | KeyPair - - let ALG_TYPE_RSA = int (2 <<< 9) - let ALG_CLASS_KEY_EXCHANGE = int (5 <<< 13) - let ALG_CLASS_SIGNATURE = int (1 <<< 13) - let CALG_RSA_KEYX = int (ALG_CLASS_KEY_EXCHANGE ||| ALG_TYPE_RSA) - let CALG_RSA_SIGN = int (ALG_CLASS_SIGNATURE ||| ALG_TYPE_RSA) - - let ALG_CLASS_HASH = int (4 <<< 13) - let ALG_TYPE_ANY = int 0 - let CALG_SHA1 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 4) - let CALG_SHA_256 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 12) - let CALG_SHA_384 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 13) - let CALG_SHA_512 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 14) - - let PUBLICKEYBLOB = int 0x6 - let PRIVATEKEYBLOB = int 0x7 - let BLOBHEADER_CURRENT_BVERSION = int 0x2 - let BLOBHEADER_LENGTH = int 20 - let RSA_PUB_MAGIC = int 0x31415352 - let RSA_PRIV_MAGIC = int 0x32415352 - - let getResourceString (_, str) = str - - [] - type ByteArrayUnion = - [] - val UnderlyingArray: byte[] - - [] - val ImmutableArray: ImmutableArray - - new (immutableArray: ImmutableArray) = { UnderlyingArray = Array.empty; ImmutableArray = immutableArray} - - let getUnderlyingArray (array: ImmutableArray) =ByteArrayUnion(array).UnderlyingArray - - // Compute a hash over the elements of an assembly manifest file that should - // remain static (skip checksum, Authenticode signatures and strong name signature blob) - let hashAssembly (peReader:PEReader) (hashAlgorithm:IncrementalHash ) = - // Hash content of all headers - let peHeaders = peReader.PEHeaders - let peHeaderOffset = peHeaders.PEHeaderStartOffset - - // Even though some data in OptionalHeader is different for 32 and 64, this field is the same - let checkSumOffset = peHeaderOffset + 0x40; // offsetof(IMAGE_OPTIONAL_HEADER, CheckSum) - let securityDirectoryEntryOffset, peHeaderSize = - match peHeaders.PEHeader.Magic with - | PEMagic.PE32 -> peHeaderOffset + 0x80, 0xE0 // offsetof(IMAGE_OPTIONAL_HEADER32, DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]), sizeof(IMAGE_OPTIONAL_HEADER32) - | PEMagic.PE32Plus -> peHeaderOffset + 0x90,0xF0 // offsetof(IMAGE_OPTIONAL_HEADER64, DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]), sizeof(IMAGE_OPTIONAL_HEADER64) - | _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignInvalidMagicValue()))) - - let allHeadersSize = peHeaderOffset + peHeaderSize + int (peHeaders.CoffHeader.NumberOfSections) * 0x28; // sizeof(IMAGE_SECTION_HEADER) - let allHeaders = - let array:byte[] = Array.zeroCreate allHeadersSize - peReader.GetEntireImage().GetContent().CopyTo(0, array, 0, allHeadersSize) - array - - // Clear checksum and security data directory - for i in 0 .. 3 do allHeaders.[checkSumOffset + i] <- 0uy - for i in 0 .. 7 do allHeaders.[securityDirectoryEntryOffset + i] <- 0uy - hashAlgorithm.AppendData(allHeaders, 0, allHeadersSize) - - // Hash content of all sections - let signatureDirectory = peHeaders.CorHeader.StrongNameSignatureDirectory - let signatureStart = - match peHeaders.TryGetDirectoryOffset signatureDirectory with - | true, value -> value - | _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignBadImageFormat()))) - let signatureEnd = signatureStart + signatureDirectory.Size - let buffer = getUnderlyingArray (peReader.GetEntireImage().GetContent()) - let sectionHeaders = peHeaders.SectionHeaders - - for i in 0 .. (sectionHeaders.Length - 1) do - let section = sectionHeaders.[i] - let mutable st = section.PointerToRawData - let en = st + section.SizeOfRawData - - if st <= signatureStart && signatureStart < en then do - // The signature should better end within this section as well - if not ( (st < signatureEnd) && (signatureEnd <= en)) then raise (BadImageFormatException()) - - // Signature starts within this section - hash everything up to the signature start - hashAlgorithm.AppendData(buffer, st, signatureStart - st) - - // Trim what we have written - st <- signatureEnd - - hashAlgorithm.AppendData(buffer, st, en - st) - () - hashAlgorithm.GetHashAndReset() - - type BlobReader = - val mutable _blob:byte[] - val mutable _offset:int - new (blob:byte[]) = { _blob = blob; _offset = 0; } - - member x.ReadInt32:int = - let offset = x._offset - x._offset <- offset + 4 - int (x._blob.[offset]) ||| (int (x._blob.[offset + 1]) <<< 8) ||| (int (x._blob.[offset + 2]) <<< 16) ||| (int (x._blob.[offset + 3]) <<< 24) - - member x.ReadBigInteger (length:int):byte[] = - let arr:byte[] = Array.zeroCreate length - Array.Copy(x._blob, x._offset, arr, 0, length) |> ignore - x._offset <- x._offset + length - arr |> Array.rev - - let RSAParamatersFromBlob (blob:byte[]) keyType = - let mutable reader = BlobReader blob - if reader.ReadInt32 <> 0x00000207 && keyType = KeyType.KeyPair then raise (CryptographicException(getResourceString(FSComp.SR.ilSignPrivateKeyExpected()))) - reader.ReadInt32 |>ignore // ALG_ID - if reader.ReadInt32 <> RSA_PRIV_MAGIC then raise (CryptographicException(getResourceString(FSComp.SR.ilSignRsaKeyExpected()))) // 'RSA2' - let byteLen, halfLen = - let bitLen = reader.ReadInt32 - match bitLen % 16 with - | 0 -> (bitLen / 8, bitLen / 16) - | _ -> raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidBitLen()))) - let mutable key = RSAParameters() - key.Exponent <- reader.ReadBigInteger 4 - key.Modulus <- reader.ReadBigInteger byteLen - key.P <- reader.ReadBigInteger halfLen - key.Q <- reader.ReadBigInteger halfLen - key.DP <- reader.ReadBigInteger halfLen - key.DQ <- reader.ReadBigInteger halfLen - key.InverseQ <- reader.ReadBigInteger halfLen - key.D <- reader.ReadBigInteger byteLen - key - - let toCLRKeyBlob (rsaParameters:RSAParameters) (algId:int) : byte[] = - let validateRSAField (field:byte[]) expected (name:string) = - if field <> null && field.Length <> expected then - raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), name))) - - // The original FCall this helper emulates supports other algId's - however, the only algid we need to support is CALG_RSA_KEYX. We will not port the codepaths dealing with other algid's. - if algId <> CALG_RSA_KEYX then raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidAlgId()))) - - // Validate the RSA structure first. - if rsaParameters.Modulus = null then raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), "Modulus"))) - if rsaParameters.Exponent = null || rsaParameters.Exponent.Length > 4 then raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), "Exponent"))) - - let modulusLength = rsaParameters.Modulus.Length - let halfModulusLength = (modulusLength + 1) / 2 - - // We assume that if P != null, then so are Q, DP, DQ, InverseQ and D and indicate KeyPair RSA Parameters - let isPrivate = - if rsaParameters.P <> null then - validateRSAField rsaParameters.P halfModulusLength "P" - validateRSAField rsaParameters.Q halfModulusLength "Q" - validateRSAField rsaParameters.DP halfModulusLength "DP" - validateRSAField rsaParameters.InverseQ halfModulusLength "InverseQ" - validateRSAField rsaParameters.D halfModulusLength "D" - true - else false - - let key = - use ms = new MemoryStream() - use bw = new BinaryWriter(ms) - - bw.Write(int CALG_RSA_SIGN) // CLRHeader.aiKeyAlg - bw.Write(int CALG_SHA1) // CLRHeader.aiHashAlg - bw.Write(int (modulusLength + BLOBHEADER_LENGTH)) // CLRHeader.KeyLength - - // Write out the BLOBHEADER - bw.Write(byte (if isPrivate = true then PRIVATEKEYBLOB else PUBLICKEYBLOB)) // BLOBHEADER.bType - bw.Write(byte BLOBHEADER_CURRENT_BVERSION) // BLOBHEADER.bVersion - bw.Write(int16 0) // BLOBHEADER.wReserved - bw.Write(int CALG_RSA_SIGN) // BLOBHEADER.aiKeyAlg - - // Write the RSAPubKey header - bw.Write(int (if isPrivate then RSA_PRIV_MAGIC else RSA_PUB_MAGIC)) // RSAPubKey.magic - bw.Write(int (modulusLength * 8)) // RSAPubKey.bitLen - - let expAsDword = - let mutable buffer = int 0 - for i in 0 .. rsaParameters.Exponent.Length - 1 do - buffer <- (buffer <<< 8) ||| int (rsaParameters.Exponent.[i]) - buffer - - bw.Write expAsDword // RSAPubKey.pubExp - bw.Write(rsaParameters.Modulus |> Array.rev) // Copy over the modulus for both public and private - if isPrivate = true then do - bw.Write(rsaParameters.P |> Array.rev) - bw.Write(rsaParameters.Q |> Array.rev) - bw.Write(rsaParameters.DP |> Array.rev) - bw.Write(rsaParameters.DQ |> Array.rev) - bw.Write(rsaParameters.InverseQ |> Array.rev) - bw.Write(rsaParameters.D |> Array.rev) - - bw.Flush() - ms.ToArray() - key - - let createSignature (hash:byte[]) (keyBlob:byte[]) keyType = - use rsa = RSA.Create() - rsa.ImportParameters(RSAParamatersFromBlob keyBlob keyType) - let signature = rsa.SignHash(hash, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1) - signature |>Array.rev - - let patchSignature (stream:Stream) (peReader:PEReader) (signature:byte[]) = - let peHeaders = peReader.PEHeaders - let signatureDirectory = peHeaders.CorHeader.StrongNameSignatureDirectory - let signatureOffset = - if signatureDirectory.Size > signature.Length then raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignInvalidSignatureSize()))) - match peHeaders.TryGetDirectoryOffset signatureDirectory with - | false, _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignNoSignatureDirectory()))) - | true, signatureOffset -> int64 signatureOffset - stream.Seek(signatureOffset, SeekOrigin.Begin) |>ignore - stream.Write(signature, 0, signature.Length) - - let corHeaderFlagsOffset = int64(peHeaders.CorHeaderStartOffset + 16) // offsetof(IMAGE_COR20_HEADER, Flags) - stream.Seek(corHeaderFlagsOffset, SeekOrigin.Begin) |>ignore - stream.WriteByte (byte (peHeaders.CorHeader.Flags ||| CorFlags.StrongNameSigned)) - () - - let signStream stream keyBlob = - use peReader = new PEReader(stream, PEStreamOptions.PrefetchEntireImage ||| PEStreamOptions.LeaveOpen) - let hash = - use hashAlgorithm = IncrementalHash.CreateHash(HashAlgorithmName.SHA1) - hashAssembly peReader hashAlgorithm - let signature = createSignature hash keyBlob KeyType.KeyPair - patchSignature stream peReader signature - - let signFile filename keyBlob = - use fs = File.Open(filename, FileMode.Open, FileAccess.ReadWrite) - signStream fs keyBlob - - let signatureSize (pk:byte[]) = - if pk.Length < 25 then raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidPKBlob()))) - let mutable reader = BlobReader pk - reader.ReadBigInteger 12 |> ignore // Skip CLRHeader - reader.ReadBigInteger 8 |> ignore // Skip BlobHeader - let magic = reader.ReadInt32 // Read magic - if not (magic = RSA_PRIV_MAGIC || magic = RSA_PUB_MAGIC) then // RSAPubKey.magic - raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidPKBlob()))) - let x = reader.ReadInt32 / 8 - x - - // Returns a CLR Format Blob public key - let getPublicKeyForKeyPair keyBlob = - use rsa = RSA.Create() - rsa.ImportParameters(RSAParamatersFromBlob keyBlob KeyType.KeyPair) - let rsaParameters = rsa.ExportParameters false - toCLRKeyBlob rsaParameters CALG_RSA_KEYX diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs deleted file mode 100644 index 1464e299239..00000000000 --- a/src/absil/ilwrite.fs +++ /dev/null @@ -1,4302 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.AbstractIL.ILBinaryWriter - -open System.Collections.Generic -open System.IO - -open Internal.Utilities -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.BinaryConstants -open FSharp.Compiler.AbstractIL.Internal.Support -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.ILPdbWriter -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range -#if FX_NO_CORHOST_SIGNER -open FSharp.Compiler.AbstractIL.Internal.StrongNameSign -#endif - - -#if DEBUG -let showEntryLookups = false -#endif - -//--------------------------------------------------------------------- -// Byte, byte array fragments and other concrete representations -// manipulations. -//--------------------------------------------------------------------- - -// Little-endian encoding of int32 -let b0 n = byte (n &&& 0xFF) -let b1 n = byte ((n >>> 8) &&& 0xFF) -let b2 n = byte ((n >>> 16) &&& 0xFF) -let b3 n = byte ((n >>> 24) &&& 0xFF) - -// Little-endian encoding of int64 -let dw7 n = byte ((n >>> 56) &&& 0xFFL) -let dw6 n = byte ((n >>> 48) &&& 0xFFL) -let dw5 n = byte ((n >>> 40) &&& 0xFFL) -let dw4 n = byte ((n >>> 32) &&& 0xFFL) -let dw3 n = byte ((n >>> 24) &&& 0xFFL) -let dw2 n = byte ((n >>> 16) &&& 0xFFL) -let dw1 n = byte ((n >>> 8) &&& 0xFFL) -let dw0 n = byte (n &&& 0xFFL) - -let bitsOfSingle (x: float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes x, 0) -let bitsOfDouble (x: float) = System.BitConverter.DoubleToInt64Bits x - -let emitBytesViaBuffer f = let bb = ByteBuffer.Create 10 in f bb; bb.Close() - -/// Alignment and padding -let align alignment n = ((n + alignment - 1) / alignment) * alignment - -//--------------------------------------------------------------------- -// Concrete token representations etc. used in PE files -//--------------------------------------------------------------------- - -type ByteBuffer with - - /// Z32 = compressed unsigned integer - static member Z32Size n = - if n <= 0x7F then 1 - elif n <= 0x3FFF then 2 - else 4 - - /// Emit int32 as compressed unsigned integer - member buf.EmitZ32 n = - if n >= 0 && n <= 0x7F then - buf.EmitIntAsByte n - elif n >= 0x80 && n <= 0x3FFF then - buf.EmitIntAsByte (0x80 ||| (n >>> 8)) - buf.EmitIntAsByte (n &&& 0xFF) - else - buf.EmitIntAsByte (0xC0 ||| ((n >>> 24) &&& 0xFF)) - buf.EmitIntAsByte ((n >>> 16) &&& 0xFF) - buf.EmitIntAsByte ((n >>> 8) &&& 0xFF) - buf.EmitIntAsByte (n &&& 0xFF) - - member buf.EmitPadding n = - for i = 0 to n-1 do - buf.EmitByte 0x0uy - - // Emit compressed untagged integer - member buf.EmitZUntaggedIndex big idx = - if big then buf.EmitInt32 idx - else - // Note, we can have idx=0x10000 generated for method table idx + 1 for just beyond last index of method table. - // This indicates that a MethodList, FieldList, PropertyList or EventList has zero entries - // For this case, the EmitInt32AsUInt16 writes a 0 (null) into the field. Binary readers respect this as an empty - // list of methods/fields/properties/events. - if idx > 0x10000 then - System.Diagnostics.Debug.Assert (false, "EmitZUntaggedIndex: too big for small address or simple index") - buf.EmitInt32AsUInt16 idx - - // Emit compressed tagged integer - member buf.EmitZTaggedIndex tag nbits big idx = - let idx2 = (idx <<< nbits) ||| tag - if big then buf.EmitInt32 idx2 - else buf.EmitInt32AsUInt16 idx2 - -let getUncodedToken (tab: TableName) idx = ((tab.Index <<< 24) ||| idx) - -// From ECMA for UserStrings: -// This final byte holds the value 1 if and only if any UTF16 character within the string has any bit set in its top byte, or its low byte is any of the following: -// 0x01-0x08, 0x0E-0x1F, 0x27, 0x2D, -// 0x7F. Otherwise, it holds 0. The 1 signifies Unicode characters that require handling beyond that normally provided for 8-bit encoding sets. - -// HOWEVER, there is a discrepancy here between the ECMA spec and the Microsoft C# implementation. -// The code below follows the latter. We've raised the issue with both teams. See Dev10 bug 850073 for details. - -let markerForUnicodeBytes (b: byte[]) = - let len = b.Length - let rec scan i = - i < len/2 && - (let b1 = Bytes.get b (i*2) - let b2 = Bytes.get b (i*2+1) - (b2 <> 0) - || (b1 >= 0x01 && b1 <= 0x08) // as per ECMA and C# - || (b1 >= 0xE && b1 <= 0x1F) // as per ECMA and C# - || (b1 = 0x27) // as per ECMA and C# - || (b1 = 0x2D) // as per ECMA and C# - || (b1 > 0x7F) // as per C# (but ECMA omits this) - || scan (i+1)) - let marker = if scan 0 then 0x01 else 0x00 - marker - - -// -------------------------------------------------------------------- -// Fixups -// -------------------------------------------------------------------- - -/// Check that the data held at a fixup is some special magic value, as a sanity check -/// to ensure the fixup is being placed at a ood location. -let checkFixup32 (data: byte[]) offset exp = - if data.[offset + 3] <> b3 exp then failwith "fixup sanity check failed" - if data.[offset + 2] <> b2 exp then failwith "fixup sanity check failed" - if data.[offset + 1] <> b1 exp then failwith "fixup sanity check failed" - if data.[offset] <> b0 exp then failwith "fixup sanity check failed" - -let applyFixup32 (data: byte[]) offset v = - data.[offset] <- b0 v - data.[offset+1] <- b1 v - data.[offset+2] <- b2 v - data.[offset+3] <- b3 v - -//--------------------------------------------------------------------- -// Strong name signing -//--------------------------------------------------------------------- - -type ILStrongNameSigner = - | PublicKeySigner of Support.pubkey - | PublicKeyOptionsSigner of Support.pubkeyOptions - | KeyPair of Support.keyPair - | KeyContainer of Support.keyContainerName - - static member OpenPublicKeyOptions s p = PublicKeyOptionsSigner((Support.signerOpenPublicKeyFile s), p) - - static member OpenPublicKey pubkey = PublicKeySigner pubkey - - static member OpenKeyPairFile s = KeyPair(Support.signerOpenKeyPairFile s) - - static member OpenKeyContainer s = KeyContainer s - - member s.Close() = - match s with - | PublicKeySigner _ - | PublicKeyOptionsSigner _ - | KeyPair _ -> () - | KeyContainer containerName -> Support.signerCloseKeyContainer containerName - - member s.IsFullySigned = - match s with - | PublicKeySigner _ -> false - | PublicKeyOptionsSigner pko -> let _, usePublicSign = pko - usePublicSign - | KeyPair _ | KeyContainer _ -> true - - member s.PublicKey = - match s with - | PublicKeySigner pk -> pk - | PublicKeyOptionsSigner pko -> let pk, _ = pko - pk - | KeyPair kp -> Support.signerGetPublicKeyForKeyPair kp - | KeyContainer kn -> Support.signerGetPublicKeyForKeyContainer kn - - member s.SignatureSize = - let pkSignatureSize pk = - try Support.signerSignatureSize pk - with e -> - failwith ("A call to StrongNameSignatureSize failed ("+e.Message+")") - 0x80 - match s with - | PublicKeySigner pk -> pkSignatureSize pk - | PublicKeyOptionsSigner pko -> let pk, _ = pko - pkSignatureSize pk - | KeyPair kp -> pkSignatureSize (Support.signerGetPublicKeyForKeyPair kp) - | KeyContainer kn -> pkSignatureSize (Support.signerGetPublicKeyForKeyContainer kn) - - member s.SignFile file = - match s with - | PublicKeySigner _ -> () - | PublicKeyOptionsSigner _ -> () - | KeyPair kp -> Support.signerSignFileWithKeyPair file kp - | KeyContainer kn -> Support.signerSignFileWithKeyContainer file kn - -//--------------------------------------------------------------------- -// TYPES FOR TABLES -//--------------------------------------------------------------------- - -module RowElementTags = - let [] UShort = 0 - let [] ULong = 1 - let [] Data = 2 - let [] DataResources = 3 - let [] Guid = 4 - let [] Blob = 5 - let [] String = 6 - let [] SimpleIndexMin = 7 - let SimpleIndex (t : TableName) = assert (t.Index <= 112); SimpleIndexMin + t.Index - let [] SimpleIndexMax = 119 - - let [] TypeDefOrRefOrSpecMin = 120 - let TypeDefOrRefOrSpec (t: TypeDefOrRefTag) = assert (t.Tag <= 2); TypeDefOrRefOrSpecMin + t.Tag (* + 111 + 1 = 0x70 + 1 = max TableName.Tndex + 1 *) - let [] TypeDefOrRefOrSpecMax = 122 - - let [] TypeOrMethodDefMin = 123 - let TypeOrMethodDef (t: TypeOrMethodDefTag) = assert (t.Tag <= 1); TypeOrMethodDefMin + t.Tag (* + 2 + 1 = max TypeDefOrRefOrSpec.Tag + 1 *) - let [] TypeOrMethodDefMax = 124 - - let [] HasConstantMin = 125 - let HasConstant (t: HasConstantTag) = assert (t.Tag <= 2); HasConstantMin + t.Tag (* + 1 + 1 = max TypeOrMethodDef.Tag + 1 *) - let [] HasConstantMax = 127 - - let [] HasCustomAttributeMin = 128 - let HasCustomAttribute (t: HasCustomAttributeTag) = assert (t.Tag <= 21); HasCustomAttributeMin + t.Tag (* + 2 + 1 = max HasConstant.Tag + 1 *) - let [] HasCustomAttributeMax = 149 - - let [] HasFieldMarshalMin = 150 - let HasFieldMarshal (t: HasFieldMarshalTag) = assert (t.Tag <= 1); HasFieldMarshalMin + t.Tag (* + 21 + 1 = max HasCustomAttribute.Tag + 1 *) - let [] HasFieldMarshalMax = 151 - - let [] HasDeclSecurityMin = 152 - let HasDeclSecurity (t: HasDeclSecurityTag) = assert (t.Tag <= 2); HasDeclSecurityMin + t.Tag (* + 1 + 1 = max HasFieldMarshal.Tag + 1 *) - let [] HasDeclSecurityMax = 154 - - let [] MemberRefParentMin = 155 - let MemberRefParent (t: MemberRefParentTag) = assert (t.Tag <= 4); MemberRefParentMin + t.Tag (* + 2 + 1 = max HasDeclSecurity.Tag + 1 *) - let [] MemberRefParentMax = 159 - - let [] HasSemanticsMin = 160 - let HasSemantics (t: HasSemanticsTag) = assert (t.Tag <= 1); HasSemanticsMin + t.Tag (* + 4 + 1 = max MemberRefParent.Tag + 1 *) - let [] HasSemanticsMax = 161 - - let [] MethodDefOrRefMin = 162 - let MethodDefOrRef (t: MethodDefOrRefTag) = assert (t.Tag <= 2); MethodDefOrRefMin + t.Tag (* + 1 + 1 = max HasSemantics.Tag + 1 *) - let [] MethodDefOrRefMax = 164 - - let [] MemberForwardedMin = 165 - let MemberForwarded (t: MemberForwardedTag) = assert (t.Tag <= 1); MemberForwardedMin + t.Tag (* + 2 + 1 = max MethodDefOrRef.Tag + 1 *) - let [] MemberForwardedMax = 166 - - let [] ImplementationMin = 167 - let Implementation (t: ImplementationTag) = assert (t.Tag <= 2); ImplementationMin + t.Tag (* + 1 + 1 = max MemberForwarded.Tag + 1 *) - let [] ImplementationMax = 169 - - let [] CustomAttributeTypeMin = 170 - let CustomAttributeType (t: CustomAttributeTypeTag) = assert (t.Tag <= 3); CustomAttributeTypeMin + t.Tag (* + 2 + 1 = max Implementation.Tag + 1 *) - let [] CustomAttributeTypeMax = 173 - - let [] ResolutionScopeMin = 174 - let ResolutionScope (t: ResolutionScopeTag) = assert (t.Tag <= 4); ResolutionScopeMin + t.Tag (* + 3 + 1 = max CustomAttributeType.Tag + 1 *) - let [] ResolutionScopeMax = 178 - -[] -type RowElement(tag: int32, idx: int32) = - - member x.Tag = tag - member x.Val = idx - -// These create RowElements -let UShort (x: uint16) = RowElement(RowElementTags.UShort, int32 x) -let ULong (x: int32) = RowElement(RowElementTags.ULong, x) -/// Index into cenv.data or cenv.resources. Gets fixed up later once we known an overall -/// location for the data section. flag indicates if offset is relative to cenv.resources. -let Data (x: int, k: bool) = RowElement((if k then RowElementTags.DataResources else RowElementTags.Data ), x) -/// pos. in guid array -let Guid (x: int) = RowElement(RowElementTags.Guid, x) -/// pos. in blob array -let Blob (x: int) = RowElement(RowElementTags.Blob, x) -/// pos. in string array -let StringE (x: int) = RowElement(RowElementTags.String, x) -/// pos. in some table -let SimpleIndex (t, x: int) = RowElement(RowElementTags.SimpleIndex t, x) -let TypeDefOrRefOrSpec (t, x: int) = RowElement(RowElementTags.TypeDefOrRefOrSpec t, x) -let TypeOrMethodDef (t, x: int) = RowElement(RowElementTags.TypeOrMethodDef t, x) -let HasConstant (t, x: int) = RowElement(RowElementTags.HasConstant t, x) -let HasCustomAttribute (t, x: int) = RowElement(RowElementTags.HasCustomAttribute t, x) -let HasFieldMarshal (t, x: int) = RowElement(RowElementTags.HasFieldMarshal t, x) -let HasDeclSecurity (t, x: int) = RowElement(RowElementTags.HasDeclSecurity t, x) -let MemberRefParent (t, x: int) = RowElement(RowElementTags.MemberRefParent t, x) -let HasSemantics (t, x: int) = RowElement(RowElementTags.HasSemantics t, x) -let MethodDefOrRef (t, x: int) = RowElement(RowElementTags.MethodDefOrRef t, x) -let MemberForwarded (t, x: int) = RowElement(RowElementTags.MemberForwarded t, x) -let Implementation (t, x: int) = RowElement(RowElementTags.Implementation t, x) -let CustomAttributeType (t, x: int) = RowElement(RowElementTags.CustomAttributeType t, x) -let ResolutionScope (t, x: int) = RowElement(RowElementTags.ResolutionScope t, x) -(* -type RowElement = - | UShort of uint16 - | ULong of int32 - | Data of int * bool // Index into cenv.data or cenv.resources. Will be adjusted later in writing once we fix an overall location for the data section. flag indicates if offset is relative to cenv.resources. - | Guid of int // pos. in guid array - | Blob of int // pos. in blob array - | String of int // pos. in string array - | SimpleIndex of TableName * int // pos. in some table - | TypeDefOrRefOrSpec of TypeDefOrRefTag * int - | TypeOrMethodDef of TypeOrMethodDefTag * int - | HasConstant of HasConstantTag * int - | HasCustomAttribute of HasCustomAttributeTag * int - | HasFieldMarshal of HasFieldMarshalTag * int - | HasDeclSecurity of HasDeclSecurityTag * int - | MemberRefParent of MemberRefParentTag * int - | HasSemantics of HasSemanticsTag * int - | MethodDefOrRef of MethodDefOrRefTag * int - | MemberForwarded of MemberForwardedTag * int - | Implementation of ImplementationTag * int - | CustomAttributeType of CustomAttributeTypeTag * int - | ResolutionScope of ResolutionScopeTag * int -*) - -type BlobIndex = int -type StringIndex = int - -let BlobIndex (x: BlobIndex) : int = x -let StringIndex (x: StringIndex) : int = x - -let inline combineHash x2 acc = 37 * acc + x2 // (acc <<< 6 + acc >>> 2 + x2 + 0x9e3779b9) - -let hashRow (elems: RowElement[]) = - let mutable acc = 0 - for i in 0 .. elems.Length - 1 do - acc <- (acc <<< 1) + elems.[i].Tag + elems.[i].Val + 631 - acc - -let equalRows (elems: RowElement[]) (elems2: RowElement[]) = - if elems.Length <> elems2.Length then false else - let mutable ok = true - let n = elems.Length - let mutable i = 0 - while ok && i < n do - if elems.[i].Tag <> elems2.[i].Tag || elems.[i].Val <> elems2.[i].Val then ok <- false - i <- i + 1 - ok - - -type GenericRow = RowElement[] - -/// This is the representation of shared rows is used for most shared row types. -/// Rows ILAssemblyRef and ILMethodRef are very common and are given their own -/// representations. -[] -type SharedRow(elems: RowElement[], hashCode: int) = - member x.GenericRow = elems - override x.GetHashCode() = hashCode - override x.Equals(obj: obj) = - match obj with - | :? SharedRow as y -> equalRows elems y.GenericRow - | _ -> false - -let SharedRow(elems: RowElement[]) = new SharedRow(elems, hashRow elems) - -/// Special representation : Note, only hashing by name -let AssemblyRefRow(s1, s2, s3, s4, l1, b1, nameIdx, str2, b2) = - let hashCode = hash nameIdx - let genericRow = [| UShort s1; UShort s2; UShort s3; UShort s4; ULong l1; Blob b1; StringE nameIdx; StringE str2; Blob b2 |] - new SharedRow(genericRow, hashCode) - -/// Special representation the computes the hash more efficiently -let MemberRefRow(mrp: RowElement, nmIdx: StringIndex, blobIdx: BlobIndex) = - let hashCode = combineHash (hash blobIdx) (combineHash (hash nmIdx) (hash mrp)) - let genericRow = [| mrp; StringE nmIdx; Blob blobIdx |] - new SharedRow(genericRow, hashCode) - -/// Unshared rows are used for definitional tables where elements do not need to be made unique -/// e.g. ILMethodDef and ILTypeDef. Most tables are like this. We don't precompute a -/// hash code for these rows, and indeed the GetHashCode and Equals should not be needed. -[] -type UnsharedRow(elems: RowElement[]) = - member x.GenericRow = elems - override x.GetHashCode() = hashRow elems - override x.Equals(obj: obj) = - match obj with - | :? UnsharedRow as y -> equalRows elems y.GenericRow - | _ -> false - - -//===================================================================== -//===================================================================== -// IL --> TABLES+CODE -//===================================================================== -//===================================================================== - -// This environment keeps track of how many generic parameters are in scope. -// This lets us translate AbsIL type variable number to IL type variable numbering -type ILTypeWriterEnv = { EnclosingTyparCount: int } -let envForTypeDef (td: ILTypeDef) = { EnclosingTyparCount=td.GenericParams.Length } -let envForMethodRef env (ty: ILType) = { EnclosingTyparCount=(match ty with ILType.Array _ -> env.EnclosingTyparCount | _ -> ty.GenericArgs.Length) } -let envForNonGenericMethodRef _mref = { EnclosingTyparCount=System.Int32.MaxValue } -let envForFieldSpec (fspec: ILFieldSpec) = { EnclosingTyparCount=fspec.DeclaringType.GenericArgs.Length } -let envForOverrideSpec (ospec: ILOverridesSpec) = { EnclosingTyparCount=ospec.DeclaringType.GenericArgs.Length } - -//--------------------------------------------------------------------- -// TABLES -//--------------------------------------------------------------------- - -[] -type MetadataTable<'T> = - { name: string - dict: Dictionary<'T, int> // given a row, find its entry number -#if DEBUG - mutable lookups: int -#endif - mutable rows: ResizeArray<'T> } - member x.Count = x.rows.Count - - static member New(nm, hashEq) = - { name=nm -#if DEBUG - lookups=0 -#endif - dict = new Dictionary<_, _>(100, hashEq) - rows= new ResizeArray<_>() } - - member tbl.EntriesAsArray = -#if DEBUG - if showEntryLookups then dprintf "--> table %s had %d entries and %d lookups\n" tbl.name tbl.Count tbl.lookups -#endif - tbl.rows |> ResizeArray.toArray - - member tbl.Entries = -#if DEBUG - if showEntryLookups then dprintf "--> table %s had %d entries and %d lookups\n" tbl.name tbl.Count tbl.lookups -#endif - tbl.rows |> ResizeArray.toList - - member tbl.AddSharedEntry x = - let n = tbl.rows.Count + 1 - tbl.dict.[x] <- n - tbl.rows.Add x - n - - member tbl.AddUnsharedEntry x = - let n = tbl.rows.Count + 1 - tbl.rows.Add x - n - - member tbl.FindOrAddSharedEntry x = -#if DEBUG - tbl.lookups <- tbl.lookups + 1 -#endif - match tbl.dict.TryGetValue x with - | true, res -> res - | _ -> tbl.AddSharedEntry x - - - /// This is only used in one special place - see further below. - member tbl.SetRowsOfTable t = - tbl.rows <- ResizeArray.ofArray t - let h = tbl.dict - h.Clear() - t |> Array.iteri (fun i x -> h.[x] <- (i+1)) - - member tbl.AddUniqueEntry nm getter x = - if tbl.dict.ContainsKey x then failwith ("duplicate entry '"+getter x+"' in "+nm+" table") - else tbl.AddSharedEntry x - - member tbl.GetTableEntry x = tbl.dict.[x] - -//--------------------------------------------------------------------- -// Keys into some of the tables -//--------------------------------------------------------------------- - -/// We use this key type to help find ILMethodDefs for MethodRefs -type MethodDefKey(tidx: int, garity: int, nm: string, rty: ILType, argtys: ILTypes, isStatic: bool) = - // Precompute the hash. The hash doesn't include the return type or - // argument types (only argument type count). This is very important, since - // hashing these is way too expensive - let hashCode = - hash tidx - |> combineHash (hash garity) - |> combineHash (hash nm) - |> combineHash (hash argtys.Length) - |> combineHash (hash isStatic) - member key.TypeIdx = tidx - member key.GenericArity = garity - member key.Name = nm - member key.ReturnType = rty - member key.ArgTypes = argtys - member key.IsStatic = isStatic - override x.GetHashCode() = hashCode - override x.Equals(obj: obj) = - match obj with - | :? MethodDefKey as y -> - tidx = y.TypeIdx && - garity = y.GenericArity && - nm = y.Name && - // note: these next two use structural equality on AbstractIL ILType values - rty = y.ReturnType && - List.lengthsEqAndForall2 (fun a b -> a = b) argtys y.ArgTypes && - isStatic = y.IsStatic - | _ -> false - -/// We use this key type to help find ILFieldDefs for FieldRefs -type FieldDefKey(tidx: int, nm: string, ty: ILType) = - // precompute the hash. hash doesn't include the type - let hashCode = hash tidx |> combineHash (hash nm) - member key.TypeIdx = tidx - member key.Name = nm - member key.Type = ty - override x.GetHashCode() = hashCode - override x.Equals(obj: obj) = - match obj with - | :? FieldDefKey as y -> - tidx = y.TypeIdx && - nm = y.Name && - ty = y.Type - | _ -> false - -type PropertyTableKey = PropKey of int (* type. def. idx. *) * string * ILType * ILTypes -type EventTableKey = EventKey of int (* type. def. idx. *) * string -type TypeDefTableKey = TdKey of string list (* enclosing *) * string (* type name *) - -//--------------------------------------------------------------------- -// The Writer Context -//--------------------------------------------------------------------- - -[] -type MetadataTable = - | Shared of MetadataTable - | Unshared of MetadataTable - member t.FindOrAddSharedEntry x = match t with Shared u -> u.FindOrAddSharedEntry x | Unshared u -> failwithf "FindOrAddSharedEntry: incorrect table kind, u.name = %s" u.name - member t.AddSharedEntry x = match t with | Shared u -> u.AddSharedEntry x | Unshared u -> failwithf "AddSharedEntry: incorrect table kind, u.name = %s" u.name - member t.AddUnsharedEntry x = match t with Unshared u -> u.AddUnsharedEntry x | Shared u -> failwithf "AddUnsharedEntry: incorrect table kind, u.name = %s" u.name - member t.GenericRowsOfTable = match t with Unshared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) | Shared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) - member t.SetRowsOfSharedTable rows = match t with Shared u -> u.SetRowsOfTable (Array.map SharedRow rows) | Unshared u -> failwithf "SetRowsOfSharedTable: incorrect table kind, u.name = %s" u.name - member t.Count = match t with Unshared u -> u.Count | Shared u -> u.Count - - -[] -type cenv = - { ilg: ILGlobals - emitTailcalls: bool - deterministic: bool - showTimes: bool - desiredMetadataVersion: ILVersionInfo - requiredDataFixups: (int32 * (int * bool)) list ref - /// References to strings in codestreams: offset of code and a (fixup-location, string token) list) - mutable requiredStringFixups: (int32 * (int * int) list) list - codeChunks: ByteBuffer - mutable nextCodeAddr: int32 - - // Collected debug information - mutable moduleGuid: byte[] - generatePdb: bool - pdbinfo: ResizeArray - documents: MetadataTable - /// Raw data, to go into the data section - data: ByteBuffer - /// Raw resource data, to go into the data section - resources: ByteBuffer - mutable entrypoint: (bool * int) option - - /// Caches - trefCache: Dictionary - - /// The following are all used to generate unique items in the output - tables: MetadataTable[] - AssemblyRefs: MetadataTable - fieldDefs: MetadataTable - methodDefIdxsByKey: MetadataTable - methodDefIdxs: Dictionary - propertyDefs: MetadataTable - eventDefs: MetadataTable - typeDefs: MetadataTable - guids: MetadataTable - blobs: MetadataTable - strings: MetadataTable - userStrings: MetadataTable - normalizeAssemblyRefs: ILAssemblyRef -> ILAssemblyRef - } - member cenv.GetTable (tab: TableName) = cenv.tables.[tab.Index] - - - member cenv.AddCode ((reqdStringFixupsOffset, requiredStringFixups), code) = - if align 4 cenv.nextCodeAddr <> cenv.nextCodeAddr then dprintn "warning: code not 4-byte aligned" - cenv.requiredStringFixups <- (cenv.nextCodeAddr + reqdStringFixupsOffset, requiredStringFixups) :: cenv.requiredStringFixups - cenv.codeChunks.EmitBytes code - cenv.nextCodeAddr <- cenv.nextCodeAddr + code.Length - - member cenv.GetCode() = cenv.codeChunks.Close() - - override x.ToString() = "" - -let FindOrAddSharedRow (cenv: cenv) tbl x = cenv.GetTable(tbl).FindOrAddSharedEntry x - -// Shared rows must be hash-cons'd to be made unique (no duplicates according to contents) -let AddSharedRow (cenv: cenv) tbl x = cenv.GetTable(tbl).AddSharedEntry x - -// Unshared rows correspond to definition elements (e.g. a ILTypeDef or a ILMethodDef) -let AddUnsharedRow (cenv: cenv) tbl (x: UnsharedRow) = cenv.GetTable(tbl).AddUnsharedEntry x - -let metadataSchemaVersionSupportedByCLRVersion v = - // Whidbey Beta 1 version numbers are between 2.0.40520.0 and 2.0.40607.0 - // Later Whidbey versions are post 2.0.40607.0.. However we assume - // internal builds such as 2.0.x86chk are Whidbey Beta 2 or later - if compareILVersions v (parseILVersion ("2.0.40520.0")) >= 0 && - compareILVersions v (parseILVersion ("2.0.40608.0")) < 0 then 1, 1 - elif compareILVersions v (parseILVersion ("2.0.0.0")) >= 0 then 2, 0 - else 1, 0 - -let headerVersionSupportedByCLRVersion v = - // The COM20HEADER version number - // Whidbey version numbers are 2.5 - // Earlier are 2.0 - // From an email from jeffschw: "Be built with a compiler that marks the COM20HEADER with Major >=2 and Minor >= 5. The V2.0 compilers produce images with 2.5, V1.x produces images with 2.0." - if compareILVersions v (parseILVersion ("2.0.0.0")) >= 0 then 2, 5 - else 2, 0 - -let peOptionalHeaderByteByCLRVersion v = - // A flag in the PE file optional header seems to depend on CLI version - // Whidbey version numbers are 8 - // Earlier are 6 - // Tools are meant to ignore this, but the VS Profiler wants it to have the right value - if compareILVersions v (parseILVersion ("2.0.0.0")) >= 0 then 8 - else 6 - -// returned by writeBinaryAndReportMappings -[] -type ILTokenMappings = - { TypeDefTokenMap: ILTypeDef list * ILTypeDef -> int32 - FieldDefTokenMap: ILTypeDef list * ILTypeDef -> ILFieldDef -> int32 - MethodDefTokenMap: ILTypeDef list * ILTypeDef -> ILMethodDef -> int32 - PropertyTokenMap: ILTypeDef list * ILTypeDef -> ILPropertyDef -> int32 - EventTokenMap: ILTypeDef list * ILTypeDef -> ILEventDef -> int32 } - -let recordRequiredDataFixup requiredDataFixups (buf: ByteBuffer) pos lab = - requiredDataFixups := (pos, lab) :: !requiredDataFixups - // Write a special value in that we check later when applying the fixup - buf.EmitInt32 0xdeaddddd - -//--------------------------------------------------------------------- -// The UserString, BlobHeap, GuidHeap tables -//--------------------------------------------------------------------- - -let GetUserStringHeapIdx cenv s = - cenv.userStrings.FindOrAddSharedEntry s - -let GetBytesAsBlobIdx cenv (bytes: byte[]) = - if bytes.Length = 0 then 0 - else cenv.blobs.FindOrAddSharedEntry bytes - -let GetStringHeapIdx cenv s = - if s = "" then 0 - else cenv.strings.FindOrAddSharedEntry s - -let GetGuidIdx cenv info = cenv.guids.FindOrAddSharedEntry info - -let GetStringHeapIdxOption cenv sopt = - match sopt with - | Some ns -> GetStringHeapIdx cenv ns - | None -> 0 - -let GetTypeNameAsElemPair cenv n = - let (n1, n2) = splitTypeNameRight n - StringE (GetStringHeapIdxOption cenv n1), - StringE (GetStringHeapIdx cenv n2) - -//===================================================================== -// Pass 1 - allocate indexes for types -//===================================================================== - -let rec GenTypeDefPass1 enc cenv (td: ILTypeDef) = - ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, td.Name))) - GenTypeDefsPass1 (enc@[td.Name]) cenv td.NestedTypes.AsList - -and GenTypeDefsPass1 enc cenv tds = List.iter (GenTypeDefPass1 enc cenv) tds - -//===================================================================== -// Pass 2 - allocate indexes for methods and fields and write rows for types -//===================================================================== - -let rec GetIdxForTypeDef cenv key = - try cenv.typeDefs.GetTableEntry key - with - :? KeyNotFoundException -> - let (TdKey (enc, n) ) = key - errorR(InternalError("One of your modules expects the type '"+String.concat "." (enc@[n])+"' to be defined within the module being emitted. You may be missing an input file", range0)) - 0 - -// -------------------------------------------------------------------- -// Assembly and module references -// -------------------------------------------------------------------- - -let rec GetAssemblyRefAsRow cenv (aref: ILAssemblyRef) = - AssemblyRefRow - ((match aref.Version with None -> 0us | Some version -> version.Major), - (match aref.Version with None -> 0us | Some version -> version.Minor), - (match aref.Version with None -> 0us | Some version -> version.Build), - (match aref.Version with None -> 0us | Some version -> version.Revision), - ((match aref.PublicKey with Some (PublicKey _) -> 0x0001 | _ -> 0x0000) - ||| (if aref.Retargetable then 0x0100 else 0x0000)), - BlobIndex (match aref.PublicKey with - | None -> 0 - | Some (PublicKey b | PublicKeyToken b) -> GetBytesAsBlobIdx cenv b), - StringIndex (GetStringHeapIdx cenv aref.Name), - StringIndex (match aref.Locale with None -> 0 | Some s -> GetStringHeapIdx cenv s), - BlobIndex (match aref.Hash with None -> 0 | Some s -> GetBytesAsBlobIdx cenv s)) - -and GetAssemblyRefAsIdx cenv aref = - FindOrAddSharedRow cenv TableNames.AssemblyRef (GetAssemblyRefAsRow cenv (cenv.normalizeAssemblyRefs aref)) - -and GetModuleRefAsRow cenv (mref: ILModuleRef) = - SharedRow - [| StringE (GetStringHeapIdx cenv mref.Name) |] - -and GetModuleRefAsFileRow cenv (mref: ILModuleRef) = - SharedRow - [| ULong (if mref.HasMetadata then 0x0000 else 0x0001) - StringE (GetStringHeapIdx cenv mref.Name) - (match mref.Hash with None -> Blob 0 | Some s -> Blob (GetBytesAsBlobIdx cenv s)) |] - -and GetModuleRefAsIdx cenv mref = - FindOrAddSharedRow cenv TableNames.ModuleRef (GetModuleRefAsRow cenv mref) - -and GetModuleRefAsFileIdx cenv mref = - FindOrAddSharedRow cenv TableNames.File (GetModuleRefAsFileRow cenv mref) - -// -------------------------------------------------------------------- -// Does a ILScopeRef point to this module? -// -------------------------------------------------------------------- - -let isScopeRefLocal scoref = (scoref = ILScopeRef.Local) -let isTypeRefLocal (tref: ILTypeRef) = isScopeRefLocal tref.Scope -let isTypeLocal (ty: ILType) = ty.IsNominal && isNil ty.GenericArgs && isTypeRefLocal ty.TypeRef - -// -------------------------------------------------------------------- -// Scopes to Implementation elements. -// -------------------------------------------------------------------- - -let GetScopeRefAsImplementationElem cenv scoref = - match scoref with - | ILScopeRef.Local -> (i_AssemblyRef, 0) - | ILScopeRef.Assembly aref -> (i_AssemblyRef, GetAssemblyRefAsIdx cenv aref) - | ILScopeRef.Module mref -> (i_File, GetModuleRefAsFileIdx cenv mref) - | ILScopeRef.PrimaryAssembly -> (i_AssemblyRef, GetAssemblyRefAsIdx cenv cenv.ilg.primaryAssemblyRef) - -// -------------------------------------------------------------------- -// Type references, types etc. -// -------------------------------------------------------------------- - -let rec GetTypeRefAsTypeRefRow cenv (tref: ILTypeRef) = - let nselem, nelem = GetTypeNameAsElemPair cenv tref.Name - let rs1, rs2 = GetResolutionScopeAsElem cenv (tref.Scope, tref.Enclosing) - SharedRow [| ResolutionScope (rs1, rs2); nelem; nselem |] - -and GetTypeRefAsTypeRefIdx cenv tref = - match cenv.trefCache.TryGetValue tref with - | true, res -> res - | _ -> - let res = FindOrAddSharedRow cenv TableNames.TypeRef (GetTypeRefAsTypeRefRow cenv tref) - cenv.trefCache.[tref] <- res - res - -and GetTypeDescAsTypeRefIdx cenv (scoref, enc, n) = - GetTypeRefAsTypeRefIdx cenv (mkILNestedTyRef (scoref, enc, n)) - -and GetResolutionScopeAsElem cenv (scoref, enc) = - if isNil enc then - match scoref with - | ILScopeRef.Local -> (rs_Module, 1) - | ILScopeRef.Assembly aref -> (rs_AssemblyRef, GetAssemblyRefAsIdx cenv aref) - | ILScopeRef.Module mref -> (rs_ModuleRef, GetModuleRefAsIdx cenv mref) - | ILScopeRef.PrimaryAssembly -> (rs_AssemblyRef, GetAssemblyRefAsIdx cenv cenv.ilg.primaryAssemblyRef) - else - let enc2, n2 = List.frontAndBack enc - (rs_TypeRef, GetTypeDescAsTypeRefIdx cenv (scoref, enc2, n2)) - - -let emitTypeInfoAsTypeDefOrRefEncoded cenv (bb: ByteBuffer) (scoref, enc, nm) = - if isScopeRefLocal scoref then - let idx = GetIdxForTypeDef cenv (TdKey(enc, nm)) - bb.EmitZ32 (idx <<< 2) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeDef - else - let idx = GetTypeDescAsTypeRefIdx cenv (scoref, enc, nm) - bb.EmitZ32 ((idx <<< 2) ||| 0x01) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeRef - -let getTypeDefOrRefAsUncodedToken (tag, idx) = - let tab = - if tag = tdor_TypeDef then TableNames.TypeDef - elif tag = tdor_TypeRef then TableNames.TypeRef - elif tag = tdor_TypeSpec then TableNames.TypeSpec - else failwith "getTypeDefOrRefAsUncodedToken" - getUncodedToken tab idx - -// REVIEW: write into an accumulating buffer -let EmitArrayShape (bb: ByteBuffer) (ILArrayShape shape) = - let sized = List.filter (function (_, Some _) -> true | _ -> false) shape - let lobounded = List.filter (function (Some _, _) -> true | _ -> false) shape - bb.EmitZ32 shape.Length - bb.EmitZ32 sized.Length - sized |> List.iter (function (_, Some sz) -> bb.EmitZ32 sz | _ -> failwith "?") - bb.EmitZ32 lobounded.Length - lobounded |> List.iter (function (Some low, _) -> bb.EmitZ32 low | _ -> failwith "?") - -let hasthisToByte hasthis = - match hasthis with - | ILThisConvention.Instance -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE - | ILThisConvention.InstanceExplicit -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT - | ILThisConvention.Static -> 0x00uy - -let callconvToByte ntypars (Callconv (hasthis, bcc)) = - hasthisToByte hasthis ||| - (if ntypars > 0 then e_IMAGE_CEE_CS_CALLCONV_GENERIC else 0x00uy) ||| - (match bcc with - | ILArgConvention.FastCall -> e_IMAGE_CEE_CS_CALLCONV_FASTCALL - | ILArgConvention.StdCall -> e_IMAGE_CEE_CS_CALLCONV_STDCALL - | ILArgConvention.ThisCall -> e_IMAGE_CEE_CS_CALLCONV_THISCALL - | ILArgConvention.CDecl -> e_IMAGE_CEE_CS_CALLCONV_CDECL - | ILArgConvention.Default -> 0x00uy - | ILArgConvention.VarArg -> e_IMAGE_CEE_CS_CALLCONV_VARARG) - - -// REVIEW: write into an accumulating buffer -let rec EmitTypeSpec cenv env (bb: ByteBuffer) (et, tspec: ILTypeSpec) = - if isNil tspec.GenericArgs then - bb.EmitByte et - emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Enclosing, tspec.Name) - else - bb.EmitByte et_WITH - bb.EmitByte et - emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Enclosing, tspec.Name) - bb.EmitZ32 tspec.GenericArgs.Length - EmitTypes cenv env bb tspec.GenericArgs - -and GetTypeAsTypeDefOrRef cenv env (ty: ILType) = - if isTypeLocal ty then - let tref = ty.TypeRef - (tdor_TypeDef, GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name))) - elif ty.IsNominal && isNil ty.GenericArgs then - (tdor_TypeRef, GetTypeRefAsTypeRefIdx cenv ty.TypeRef) - else - (tdor_TypeSpec, GetTypeAsTypeSpecIdx cenv env ty) - -and GetTypeAsBytes cenv env ty = emitBytesViaBuffer (fun bb -> EmitType cenv env bb ty) - -and GetTypeOfLocalAsBytes cenv env (l: ILLocal) = - emitBytesViaBuffer (fun bb -> EmitLocalInfo cenv env bb l) - -and GetTypeAsBlobIdx cenv env (ty: ILType) = - GetBytesAsBlobIdx cenv (GetTypeAsBytes cenv env ty) - -and GetTypeAsTypeSpecRow cenv env (ty: ILType) = - SharedRow [| Blob (GetTypeAsBlobIdx cenv env ty) |] - -and GetTypeAsTypeSpecIdx cenv env ty = - FindOrAddSharedRow cenv TableNames.TypeSpec (GetTypeAsTypeSpecRow cenv env ty) - -and EmitType cenv env bb ty = - let ilg = cenv.ilg - match ty with - | ty when isILSByteTy ilg ty -> bb.EmitByte et_I1 - | ty when isILInt16Ty ilg ty -> bb.EmitByte et_I2 - | ty when isILInt32Ty ilg ty -> bb.EmitByte et_I4 - | ty when isILInt64Ty ilg ty -> bb.EmitByte et_I8 - | ty when isILByteTy ilg ty -> bb.EmitByte et_U1 - | ty when isILUInt16Ty ilg ty -> bb.EmitByte et_U2 - | ty when isILUInt32Ty ilg ty -> bb.EmitByte et_U4 - | ty when isILUInt64Ty ilg ty -> bb.EmitByte et_U8 - | ty when isILDoubleTy ilg ty -> bb.EmitByte et_R8 - | ty when isILSingleTy ilg ty -> bb.EmitByte et_R4 - | ty when isILBoolTy ilg ty -> bb.EmitByte et_BOOLEAN - | ty when isILCharTy ilg ty -> bb.EmitByte et_CHAR - | ty when isILStringTy ilg ty -> bb.EmitByte et_STRING - | ty when isILObjectTy ilg ty -> bb.EmitByte et_OBJECT - | ty when isILIntPtrTy ilg ty -> bb.EmitByte et_I - | ty when isILUIntPtrTy ilg ty -> bb.EmitByte et_U - | ty when isILTypedReferenceTy ilg ty -> bb.EmitByte et_TYPEDBYREF - - | ILType.Boxed tspec -> EmitTypeSpec cenv env bb (et_CLASS, tspec) - | ILType.Value tspec -> EmitTypeSpec cenv env bb (et_VALUETYPE, tspec) - | ILType.Array (shape, ty) -> - if shape = ILArrayShape.SingleDimensional then (bb.EmitByte et_SZARRAY ; EmitType cenv env bb ty) - else (bb.EmitByte et_ARRAY; EmitType cenv env bb ty; EmitArrayShape bb shape) - | ILType.TypeVar tv -> - let cgparams = env.EnclosingTyparCount - if int32 tv < cgparams then - bb.EmitByte et_VAR - bb.EmitZ32 (int32 tv) - else - bb.EmitByte et_MVAR - bb.EmitZ32 (int32 tv - cgparams) - - | ILType.Byref ty -> - bb.EmitByte et_BYREF - EmitType cenv env bb ty - | ILType.Ptr ty -> - bb.EmitByte et_PTR - EmitType cenv env bb ty - | ILType.Void -> - bb.EmitByte et_VOID - | ILType.FunctionPointer x -> - bb.EmitByte et_FNPTR - EmitCallsig cenv env bb (x.CallingConv, x.ArgTypes, x.ReturnType, None, 0) - | ILType.Modified (req, tref, ty) -> - bb.EmitByte (if req then et_CMOD_REQD else et_CMOD_OPT) - emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tref.Scope, tref.Enclosing, tref.Name) - EmitType cenv env bb ty - | _ -> failwith "EmitType" - -and EmitLocalInfo cenv env (bb: ByteBuffer) (l: ILLocal) = - if l.IsPinned then - bb.EmitByte et_PINNED - EmitType cenv env bb l.Type - -and EmitCallsig cenv env bb (callconv, args: ILTypes, ret, varargs: ILVarArgs, genarity) = - bb.EmitByte (callconvToByte genarity callconv) - if genarity > 0 then bb.EmitZ32 genarity - bb.EmitZ32 ((args.Length + (match varargs with None -> 0 | Some l -> l.Length))) - EmitType cenv env bb ret - args |> List.iter (EmitType cenv env bb) - match varargs with - | None -> ()// no extra arg = no sentinel - | Some tys -> - if isNil tys then () // no extra arg = no sentinel - else - bb.EmitByte et_SENTINEL - List.iter (EmitType cenv env bb) tys - -and GetCallsigAsBytes cenv env x = emitBytesViaBuffer (fun bb -> EmitCallsig cenv env bb x) - -// REVIEW: write into an accumulating buffer -and EmitTypes cenv env bb (inst: ILTypes) = - inst |> List.iter (EmitType cenv env bb) - -let GetTypeAsMemberRefParent cenv env ty = - match GetTypeAsTypeDefOrRef cenv env ty with - | (tag, _) when tag = tdor_TypeDef -> dprintn "GetTypeAsMemberRefParent: mspec should have been encoded as mdtMethodDef?"; MemberRefParent (mrp_TypeRef, 1) - | (tag, tok) when tag = tdor_TypeRef -> MemberRefParent (mrp_TypeRef, tok) - | (tag, tok) when tag = tdor_TypeSpec -> MemberRefParent (mrp_TypeSpec, tok) - | _ -> failwith "GetTypeAsMemberRefParent" - - -// -------------------------------------------------------------------- -// Native types -// -------------------------------------------------------------------- - -let rec GetVariantTypeAsInt32 ty = - if List.memAssoc ty (Lazy.force ILVariantTypeMap) then - (List.assoc ty (Lazy.force ILVariantTypeMap )) - else - match ty with - | ILNativeVariant.Array vt -> vt_ARRAY ||| GetVariantTypeAsInt32 vt - | ILNativeVariant.Vector vt -> vt_VECTOR ||| GetVariantTypeAsInt32 vt - | ILNativeVariant.Byref vt -> vt_BYREF ||| GetVariantTypeAsInt32 vt - | _ -> failwith "Unexpected variant type" - -// based on information in ECMA and asmparse.y in the CLR codebase -let rec GetNativeTypeAsBlobIdx cenv (ty: ILNativeType) = - GetBytesAsBlobIdx cenv (GetNativeTypeAsBytes ty) - -and GetNativeTypeAsBytes ty = emitBytesViaBuffer (fun bb -> EmitNativeType bb ty) - -// REVIEW: write into an accumulating buffer -and EmitNativeType bb ty = - if List.memAssoc ty (Lazy.force ILNativeTypeRevMap) then - bb.EmitByte (List.assoc ty (Lazy.force ILNativeTypeRevMap)) - else - match ty with - | ILNativeType.Empty -> () - | ILNativeType.Custom (guid, nativeTypeName, custMarshallerName, cookieString) -> - let u1 = System.Text.Encoding.UTF8.GetBytes nativeTypeName - let u2 = System.Text.Encoding.UTF8.GetBytes custMarshallerName - let u3 = cookieString - bb.EmitByte nt_CUSTOMMARSHALER - bb.EmitZ32 guid.Length - bb.EmitBytes guid - bb.EmitZ32 u1.Length; bb.EmitBytes u1 - bb.EmitZ32 u2.Length; bb.EmitBytes u2 - bb.EmitZ32 u3.Length; bb.EmitBytes u3 - | ILNativeType.FixedSysString i -> - bb.EmitByte nt_FIXEDSYSSTRING - bb.EmitZ32 i - - | ILNativeType.FixedArray i -> - bb.EmitByte nt_FIXEDARRAY - bb.EmitZ32 i - | (* COM interop *) ILNativeType.SafeArray (vt, name) -> - bb.EmitByte nt_SAFEARRAY - bb.EmitZ32 (GetVariantTypeAsInt32 vt) - match name with - | None -> () - | Some n -> - let u1 = Bytes.stringAsUtf8NullTerminated n - bb.EmitZ32 (Array.length u1) ; bb.EmitBytes u1 - | ILNativeType.Array (nt, sizeinfo) -> (* REVIEW: check if this corresponds to the ECMA spec *) - bb.EmitByte nt_ARRAY - match nt with - | None -> bb.EmitZ32 (int nt_MAX) - | Some ntt -> - (if ntt = ILNativeType.Empty then - bb.EmitZ32 (int nt_MAX) - else - EmitNativeType bb ntt) - match sizeinfo with - | None -> () // chunk out with zeroes because some tools (e.g. asmmeta) read these poorly and expect further elements. - | Some (pnum, additive) -> - // ParamNum - bb.EmitZ32 pnum - (* ElemMul *) (* z_u32 0x1l *) - match additive with - | None -> () - | Some n -> (* NumElem *) bb.EmitZ32 n - | _ -> failwith "Unexpected native type" - -// -------------------------------------------------------------------- -// Native types -// -------------------------------------------------------------------- - -let rec GetFieldInitAsBlobIdx cenv (x: ILFieldInit) = - GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> GetFieldInit bb x)) - -// REVIEW: write into an accumulating buffer -and GetFieldInit (bb: ByteBuffer) x = - match x with - | ILFieldInit.String b -> bb.EmitBytes (System.Text.Encoding.Unicode.GetBytes b) - | ILFieldInit.Bool b -> bb.EmitByte (if b then 0x01uy else 0x00uy) - | ILFieldInit.Char x -> bb.EmitUInt16 x - | ILFieldInit.Int8 x -> bb.EmitByte (byte x) - | ILFieldInit.Int16 x -> bb.EmitUInt16 (uint16 x) - | ILFieldInit.Int32 x -> bb.EmitInt32 x - | ILFieldInit.Int64 x -> bb.EmitInt64 x - | ILFieldInit.UInt8 x -> bb.EmitByte x - | ILFieldInit.UInt16 x -> bb.EmitUInt16 x - | ILFieldInit.UInt32 x -> bb.EmitInt32 (int32 x) - | ILFieldInit.UInt64 x -> bb.EmitInt64 (int64 x) - | ILFieldInit.Single x -> bb.EmitInt32 (bitsOfSingle x) - | ILFieldInit.Double x -> bb.EmitInt64 (bitsOfDouble x) - | ILFieldInit.Null -> bb.EmitInt32 0 - -and GetFieldInitFlags i = - UShort - (uint16 - (match i with - | ILFieldInit.String _ -> et_STRING - | ILFieldInit.Bool _ -> et_BOOLEAN - | ILFieldInit.Char _ -> et_CHAR - | ILFieldInit.Int8 _ -> et_I1 - | ILFieldInit.Int16 _ -> et_I2 - | ILFieldInit.Int32 _ -> et_I4 - | ILFieldInit.Int64 _ -> et_I8 - | ILFieldInit.UInt8 _ -> et_U1 - | ILFieldInit.UInt16 _ -> et_U2 - | ILFieldInit.UInt32 _ -> et_U4 - | ILFieldInit.UInt64 _ -> et_U8 - | ILFieldInit.Single _ -> et_R4 - | ILFieldInit.Double _ -> et_R8 - | ILFieldInit.Null -> et_CLASS)) - -// -------------------------------------------------------------------- -// Type definitions -// -------------------------------------------------------------------- - -let GetMemberAccessFlags access = - match access with - | ILMemberAccess.Public -> 0x00000006 - | ILMemberAccess.Private -> 0x00000001 - | ILMemberAccess.Family -> 0x00000004 - | ILMemberAccess.CompilerControlled -> 0x00000000 - | ILMemberAccess.FamilyAndAssembly -> 0x00000002 - | ILMemberAccess.FamilyOrAssembly -> 0x00000005 - | ILMemberAccess.Assembly -> 0x00000003 - -let GetTypeAccessFlags access = - match access with - | ILTypeDefAccess.Public -> 0x00000001 - | ILTypeDefAccess.Private -> 0x00000000 - | ILTypeDefAccess.Nested ILMemberAccess.Public -> 0x00000002 - | ILTypeDefAccess.Nested ILMemberAccess.Private -> 0x00000003 - | ILTypeDefAccess.Nested ILMemberAccess.Family -> 0x00000004 - | ILTypeDefAccess.Nested ILMemberAccess.CompilerControlled -> failwith "bad type access" - | ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly -> 0x00000006 - | ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> 0x00000007 - | ILTypeDefAccess.Nested ILMemberAccess.Assembly -> 0x00000005 - -let rec GetTypeDefAsRow cenv env _enc (td: ILTypeDef) = - let nselem, nelem = GetTypeNameAsElemPair cenv td.Name - let flags = - if (isTypeNameForGlobalFunctions td.Name) then 0x00000000 - else - int td.Attributes - - let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env td.Extends - UnsharedRow - [| ULong flags - nelem - nselem - TypeDefOrRefOrSpec (tdorTag, tdorRow) - SimpleIndex (TableNames.Field, cenv.fieldDefs.Count + 1) - SimpleIndex (TableNames.Method, cenv.methodDefIdxsByKey.Count + 1) |] - -and GetTypeOptionAsTypeDefOrRef cenv env tyOpt = - match tyOpt with - | None -> (tdor_TypeDef, 0) - | Some ty -> (GetTypeAsTypeDefOrRef cenv env ty) - -and GetTypeDefAsPropertyMapRow cenv tidx = - UnsharedRow - [| SimpleIndex (TableNames.TypeDef, tidx) - SimpleIndex (TableNames.Property, cenv.propertyDefs.Count + 1) |] - -and GetTypeDefAsEventMapRow cenv tidx = - UnsharedRow - [| SimpleIndex (TableNames.TypeDef, tidx) - SimpleIndex (TableNames.Event, cenv.eventDefs.Count + 1) |] - -and GetKeyForFieldDef tidx (fd: ILFieldDef) = - FieldDefKey (tidx, fd.Name, fd.FieldType) - -and GenFieldDefPass2 cenv tidx fd = - ignore (cenv.fieldDefs.AddUniqueEntry "field" (fun (fdkey: FieldDefKey) -> fdkey.Name) (GetKeyForFieldDef tidx fd)) - -and GetKeyForMethodDef tidx (md: ILMethodDef) = - MethodDefKey (tidx, md.GenericParams.Length, md.Name, md.Return.Type, md.ParameterTypes, md.CallingConv.IsStatic) - -and GenMethodDefPass2 cenv tidx md = - let idx = - cenv.methodDefIdxsByKey.AddUniqueEntry - "method" - (fun (key: MethodDefKey) -> - dprintn "Duplicate in method table is:" - dprintn (" Type index: "+string key.TypeIdx) - dprintn (" Method name: "+key.Name) - dprintn (" Method arity (num generic params): "+string key.GenericArity) - key.Name - ) - (GetKeyForMethodDef tidx md) - - cenv.methodDefIdxs.[md] <- idx - -and GetKeyForPropertyDef tidx (x: ILPropertyDef) = - PropKey (tidx, x.Name, x.PropertyType, x.Args) - -and GenPropertyDefPass2 cenv tidx x = - ignore (cenv.propertyDefs.AddUniqueEntry "property" (fun (PropKey (_, n, _, _)) -> n) (GetKeyForPropertyDef tidx x)) - -and GetTypeAsImplementsRow cenv env tidx ty = - let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty - UnsharedRow - [| SimpleIndex (TableNames.TypeDef, tidx) - TypeDefOrRefOrSpec (tdorTag, tdorRow) |] - -and GenImplementsPass2 cenv env tidx ty = - AddUnsharedRow cenv TableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) |> ignore - -and GetKeyForEvent tidx (x: ILEventDef) = - EventKey (tidx, x.Name) - -and GenEventDefPass2 cenv tidx x = - ignore (cenv.eventDefs.AddUniqueEntry "event" (fun (EventKey(_, b)) -> b) (GetKeyForEvent tidx x)) - -and GenTypeDefPass2 pidx enc cenv (td: ILTypeDef) = - try - let env = envForTypeDef td - let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) - let tidx2 = AddUnsharedRow cenv TableNames.TypeDef (GetTypeDefAsRow cenv env enc td) - if tidx <> tidx2 then failwith "index of typedef on second pass does not match index on first pass" - - // Add entries to auxiliary mapping tables, e.g. Nested, PropertyMap etc. - // Note Nested is organised differently to the others... - if not (isNil enc) then - AddUnsharedRow cenv TableNames.Nested - (UnsharedRow - [| SimpleIndex (TableNames.TypeDef, tidx) - SimpleIndex (TableNames.TypeDef, pidx) |]) |> ignore - let props = td.Properties.AsList - if not (isNil props) then - AddUnsharedRow cenv TableNames.PropertyMap (GetTypeDefAsPropertyMapRow cenv tidx) |> ignore - let events = td.Events.AsList - if not (isNil events) then - AddUnsharedRow cenv TableNames.EventMap (GetTypeDefAsEventMapRow cenv tidx) |> ignore - - // Now generate or assign index numbers for tables referenced by the maps. - // Don't yet generate contents of these tables - leave that to pass3, as - // code may need to embed these entries. - td.Implements |> List.iter (GenImplementsPass2 cenv env tidx) - props |> List.iter (GenPropertyDefPass2 cenv tidx) - events |> List.iter (GenEventDefPass2 cenv tidx) - td.Fields.AsList |> List.iter (GenFieldDefPass2 cenv tidx) - td.Methods |> Seq.iter (GenMethodDefPass2 cenv tidx) - td.NestedTypes.AsList |> GenTypeDefsPass2 tidx (enc@[td.Name]) cenv - with e -> - failwith ("Error in pass2 for type "+td.Name+", error: "+e.Message) - -and GenTypeDefsPass2 pidx enc cenv tds = - List.iter (GenTypeDefPass2 pidx enc cenv) tds - -//===================================================================== -// Pass 3 - write details of methods, fields, IL code, custom attrs etc. -//===================================================================== - -exception MethodDefNotFound -let FindMethodDefIdx cenv mdkey = - try cenv.methodDefIdxsByKey.GetTableEntry mdkey - with :? KeyNotFoundException -> - let typeNameOfIdx i = - match - (cenv.typeDefs.dict - |> Seq.fold (fun sofar kvp -> - let tkey2 = kvp.Key - let tidx2 = kvp.Value - if i = tidx2 then - if sofar = None then - Some tkey2 - else failwith "multiple type names map to index" - else sofar) None) with - | Some x -> x - | None -> raise MethodDefNotFound - let (TdKey (tenc, tname)) = typeNameOfIdx mdkey.TypeIdx - dprintn ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") - dprintn ("generic arity: "+string mdkey.GenericArity) - cenv.methodDefIdxsByKey.dict |> Seq.iter (fun (KeyValue(mdkey2, _)) -> - if mdkey2.TypeIdx = mdkey.TypeIdx && mdkey.Name = mdkey2.Name then - let (TdKey (tenc2, tname2)) = typeNameOfIdx mdkey2.TypeIdx - dprintn ("A method in '"+(String.concat "." (tenc2@[tname2]))+"' had the right name but the wrong signature:") - dprintn ("generic arity: "+string mdkey2.GenericArity) - dprintn (sprintf "mdkey2: %+A" mdkey2)) - raise MethodDefNotFound - - -let rec GetMethodDefIdx cenv md = - cenv.methodDefIdxs.[md] - -and FindFieldDefIdx cenv fdkey = - try cenv.fieldDefs.GetTableEntry fdkey - with :? KeyNotFoundException -> - errorR(InternalError("The local field "+fdkey.Name+" was referenced but not declared", range0)) - 1 - -and GetFieldDefAsFieldDefIdx cenv tidx fd = - FindFieldDefIdx cenv (GetKeyForFieldDef tidx fd) - -// -------------------------------------------------------------------- -// ILMethodRef --> ILMethodDef. -// -// Only successfully converts ILMethodRef's referring to -// methods in the module being emitted. -// -------------------------------------------------------------------- - -let GetMethodRefAsMethodDefIdx cenv (mref: ILMethodRef) = - let tref = mref.DeclaringTypeRef - try - if not (isTypeRefLocal tref) then - failwithf "method referred to by method impl, event or property is not in a type defined in this module, method ref is %A" mref - let tidx = GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name)) - let mdkey = MethodDefKey (tidx, mref.GenericArity, mref.Name, mref.ReturnType, mref.ArgTypes, mref.CallingConv.IsStatic) - FindMethodDefIdx cenv mdkey - with e -> - failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" (mref.Name, tref.Name) e.Message - -let rec MethodRefInfoAsMemberRefRow cenv env fenv (nm, ty, callconv, args, ret, varargs, genarity) = - MemberRefRow(GetTypeAsMemberRefParent cenv env ty, - GetStringHeapIdx cenv nm, - GetMethodRefInfoAsBlobIdx cenv fenv (callconv, args, ret, varargs, genarity)) - -and GetMethodRefInfoAsBlobIdx cenv env info = - GetBytesAsBlobIdx cenv (GetCallsigAsBytes cenv env info) - -let GetMethodRefInfoAsMemberRefIdx cenv env ((_, ty, _, _, _, _, _) as minfo) = - let fenv = envForMethodRef env ty - FindOrAddSharedRow cenv TableNames.MemberRef (MethodRefInfoAsMemberRefRow cenv env fenv minfo) - -let GetMethodRefInfoAsMethodRefOrDef isAlwaysMethodDef cenv env ((nm, ty: ILType, cc, args, ret, varargs, genarity) as minfo) = - if Option.isNone varargs && (isAlwaysMethodDef || isTypeLocal ty) then - if not ty.IsNominal then failwith "GetMethodRefInfoAsMethodRefOrDef: unexpected local tref-ty" - try (mdor_MethodDef, GetMethodRefAsMethodDefIdx cenv (mkILMethRef (ty.TypeRef, cc, nm, genarity, args, ret))) - with MethodDefNotFound -> (mdor_MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) - else (mdor_MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) - - -// -------------------------------------------------------------------- -// ILMethodSpec --> ILMethodRef/ILMethodDef/ILMethodSpec -// -------------------------------------------------------------------- - -let rec GetMethodSpecInfoAsMethodSpecIdx cenv env (nm, ty, cc, args, ret, varargs, minst: ILGenericArgs) = - let mdorTag, mdorRow = GetMethodRefInfoAsMethodRefOrDef false cenv env (nm, ty, cc, args, ret, varargs, minst.Length) - let blob = - emitBytesViaBuffer (fun bb -> - bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_GENERICINST - bb.EmitZ32 minst.Length - minst |> List.iter (EmitType cenv env bb)) - FindOrAddSharedRow cenv TableNames.MethodSpec - (SharedRow - [| MethodDefOrRef (mdorTag, mdorRow) - Blob (GetBytesAsBlobIdx cenv blob) |]) - -and GetMethodDefOrRefAsUncodedToken (tag, idx) = - let tab = - if tag = mdor_MethodDef then TableNames.Method - elif tag = mdor_MemberRef then TableNames.MemberRef - else failwith "GetMethodDefOrRefAsUncodedToken" - getUncodedToken tab idx - -and GetMethodSpecInfoAsUncodedToken cenv env ((_, _, _, _, _, _, minst: ILGenericArgs) as minfo) = - if List.isEmpty minst then - GetMethodDefOrRefAsUncodedToken (GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo minfo)) - else - getUncodedToken TableNames.MethodSpec (GetMethodSpecInfoAsMethodSpecIdx cenv env minfo) - -and GetMethodSpecAsUncodedToken cenv env mspec = - GetMethodSpecInfoAsUncodedToken cenv env (InfoOfMethodSpec mspec) - -and GetMethodRefInfoOfMethodSpecInfo (nm, ty, cc, args, ret, varargs, minst: ILGenericArgs) = - (nm, ty, cc, args, ret, varargs, minst.Length) - -and GetMethodSpecAsMethodDefOrRef cenv env (mspec, varargs) = - GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) - -and GetMethodSpecAsMethodDef cenv env (mspec, varargs) = - GetMethodRefInfoAsMethodRefOrDef true cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) - -and InfoOfMethodSpec (mspec: ILMethodSpec, varargs) = - (mspec.Name, - mspec.DeclaringType, - mspec.CallingConv, - mspec.FormalArgTypes, - mspec.FormalReturnType, - varargs, - mspec.GenericArgs) - -// -------------------------------------------------------------------- -// method_in_parent --> ILMethodRef/ILMethodDef -// -// Used for MethodImpls. -// -------------------------------------------------------------------- - -let rec GetOverridesSpecAsMemberRefIdx cenv env ospec = - let fenv = envForOverrideSpec ospec - let row = MethodRefInfoAsMemberRefRow cenv env fenv (ospec.MethodRef.Name, ospec.DeclaringType, ospec.MethodRef.CallingConv, ospec.MethodRef.ArgTypes, ospec.MethodRef.ReturnType, None, ospec.MethodRef.GenericArity) - FindOrAddSharedRow cenv TableNames.MemberRef row - -and GetOverridesSpecAsMethodDefOrRef cenv env (ospec: ILOverridesSpec) = - let ty = ospec.DeclaringType - if isTypeLocal ty then - if not ty.IsNominal then failwith "GetOverridesSpecAsMethodDefOrRef: unexpected local tref-ty" - try (mdor_MethodDef, GetMethodRefAsMethodDefIdx cenv ospec.MethodRef) - with MethodDefNotFound -> (mdor_MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) - else - (mdor_MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) - -// -------------------------------------------------------------------- -// ILMethodRef --> ILMethodRef/ILMethodDef -// -// Used for Custom Attrs. -// -------------------------------------------------------------------- - -let rec GetMethodRefAsMemberRefIdx cenv env fenv (mref: ILMethodRef) = - let row = MethodRefInfoAsMemberRefRow cenv env fenv (mref.Name, mkILNonGenericBoxedTy mref.DeclaringTypeRef, mref.CallingConv, mref.ArgTypes, mref.ReturnType, None, mref.GenericArity) - FindOrAddSharedRow cenv TableNames.MemberRef row - -and GetMethodRefAsCustomAttribType cenv (mref: ILMethodRef) = - let fenv = envForNonGenericMethodRef mref - let tref = mref.DeclaringTypeRef - if isTypeRefLocal tref then - try (cat_MethodDef, GetMethodRefAsMethodDefIdx cenv mref) - with MethodDefNotFound -> (cat_MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) - else - (cat_MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) - -// -------------------------------------------------------------------- -// ILAttributes --> CustomAttribute rows -// -------------------------------------------------------------------- - -let rec GetCustomAttrDataAsBlobIdx cenv (data: byte[]) = - if data.Length = 0 then 0 else GetBytesAsBlobIdx cenv data - -and GetCustomAttrRow cenv hca (attr: ILAttribute) = - let cat = GetMethodRefAsCustomAttribType cenv attr.Method.MethodRef - let data = getCustomAttrData cenv.ilg attr - for element in attr.Elements do - match element with - | ILAttribElem.Type (Some ty) when ty.IsNominal -> GetTypeRefAsTypeRefIdx cenv ty.TypeRef |> ignore - | ILAttribElem.TypeRef (Some tref) -> GetTypeRefAsTypeRefIdx cenv tref |> ignore - | _ -> () - - UnsharedRow - [| HasCustomAttribute (fst hca, snd hca) - CustomAttributeType (fst cat, snd cat) - Blob (GetCustomAttrDataAsBlobIdx cenv data) - |] - -and GenCustomAttrPass3Or4 cenv hca attr = - AddUnsharedRow cenv TableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore - -and GenCustomAttrsPass3Or4 cenv hca (attrs: ILAttributes) = - attrs.AsArray |> Array.iter (GenCustomAttrPass3Or4 cenv hca) - -// -------------------------------------------------------------------- -// ILSecurityDecl --> DeclSecurity rows -// -------------------------------------------------------------------- *) - -let rec GetSecurityDeclRow cenv hds (ILSecurityDecl (action, s)) = - UnsharedRow - [| UShort (uint16 (List.assoc action (Lazy.force ILSecurityActionMap))) - HasDeclSecurity (fst hds, snd hds) - Blob (GetBytesAsBlobIdx cenv s) |] - -and GenSecurityDeclPass3 cenv hds attr = - AddUnsharedRow cenv TableNames.Permission (GetSecurityDeclRow cenv hds attr) |> ignore - -and GenSecurityDeclsPass3 cenv hds attrs = - List.iter (GenSecurityDeclPass3 cenv hds) attrs - -// -------------------------------------------------------------------- -// ILFieldSpec --> FieldRef or ILFieldDef row -// -------------------------------------------------------------------- - -let rec GetFieldSpecAsMemberRefRow cenv env fenv (fspec: ILFieldSpec) = - MemberRefRow (GetTypeAsMemberRefParent cenv env fspec.DeclaringType, - GetStringHeapIdx cenv fspec.Name, - GetFieldSpecSigAsBlobIdx cenv fenv fspec) - -and GetFieldSpecAsMemberRefIdx cenv env fspec = - let fenv = envForFieldSpec fspec - FindOrAddSharedRow cenv TableNames.MemberRef (GetFieldSpecAsMemberRefRow cenv env fenv fspec) - -// REVIEW: write into an accumulating buffer -and EmitFieldSpecSig cenv env (bb: ByteBuffer) (fspec: ILFieldSpec) = - bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD - EmitType cenv env bb fspec.FormalType - -and GetFieldSpecSigAsBytes cenv env x = - emitBytesViaBuffer (fun bb -> EmitFieldSpecSig cenv env bb x) - -and GetFieldSpecSigAsBlobIdx cenv env x = - GetBytesAsBlobIdx cenv (GetFieldSpecSigAsBytes cenv env x) - -and GetFieldSpecAsFieldDefOrRef cenv env (fspec: ILFieldSpec) = - let ty = fspec.DeclaringType - if isTypeLocal ty then - if not ty.IsNominal then failwith "GetFieldSpecAsFieldDefOrRef: unexpected local tref-ty" - let tref = ty.TypeRef - let tidx = GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name)) - let fdkey = FieldDefKey (tidx, fspec.Name, fspec.FormalType) - (true, FindFieldDefIdx cenv fdkey) - else - (false, GetFieldSpecAsMemberRefIdx cenv env fspec) - -and GetFieldDefOrRefAsUncodedToken (tag, idx) = - let tab = if tag then TableNames.Field else TableNames.MemberRef - getUncodedToken tab idx - -// -------------------------------------------------------------------- -// callsig --> StandAloneSig -// -------------------------------------------------------------------- - -let GetCallsigAsBlobIdx cenv env (callsig: ILCallingSignature, varargs) = - GetBytesAsBlobIdx cenv - (GetCallsigAsBytes cenv env (callsig.CallingConv, - callsig.ArgTypes, - callsig.ReturnType, varargs, 0)) - -let GetCallsigAsStandAloneSigRow cenv env x = - SharedRow [| Blob (GetCallsigAsBlobIdx cenv env x) |] - -let GetCallsigAsStandAloneSigIdx cenv env info = - FindOrAddSharedRow cenv TableNames.StandAloneSig (GetCallsigAsStandAloneSigRow cenv env info) - -// -------------------------------------------------------------------- -// local signatures --> BlobHeap idx -// -------------------------------------------------------------------- - -let EmitLocalSig cenv env (bb: ByteBuffer) (locals: ILLocals) = - bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG - bb.EmitZ32 locals.Length - locals |> List.iter (EmitLocalInfo cenv env bb) - -let GetLocalSigAsBlobHeapIdx cenv env locals = - GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> EmitLocalSig cenv env bb locals)) - -let GetLocalSigAsStandAloneSigIdx cenv env locals = - SharedRow [| Blob (GetLocalSigAsBlobHeapIdx cenv env locals) |] - - - -type ExceptionClauseKind = - | FinallyClause - | FaultClause - | TypeFilterClause of int32 - | FilterClause of int - -type ExceptionClauseSpec = (int * int * int * int * ExceptionClauseKind) - -type CodeBuffer = - - // -------------------------------------------------------------------- - // Buffer to write results of emitting code into. Also record: - // - branch sources (where fixups will occur) - // - possible branch destinations - // - locations of embedded handles into the string table - // - the exception table - // -------------------------------------------------------------------- - { code: ByteBuffer - /// (instruction; optional short form); start of instr in code buffer; code loc for the end of the instruction the fixup resides in ; where is the destination of the fixup - mutable reqdBrFixups: ((int * int option) * int * ILCodeLabel list) list - availBrFixups: Dictionary - /// code loc to fixup in code buffer - mutable reqdStringFixupsInMethod: (int * int) list - /// data for exception handling clauses - mutable seh: ExceptionClauseSpec list - seqpoints: ResizeArray } - - static member Create _nm = - { seh = [] - code= ByteBuffer.Create 200 - reqdBrFixups=[] - reqdStringFixupsInMethod=[] - availBrFixups = Dictionary<_, _>(10, HashIdentity.Structural) - seqpoints = new ResizeArray<_>(10) - } - - member codebuf.EmitExceptionClause seh = codebuf.seh <- seh :: codebuf.seh - - member codebuf.EmitSeqPoint cenv (m: ILSourceMarker) = - if cenv.generatePdb then - // table indexes are 1-based, document array indexes are 0-based - let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 - codebuf.seqpoints.Add - { Document=doc - Offset= codebuf.code.Position - Line=m.Line - Column=m.Column - EndLine=m.EndLine - EndColumn=m.EndColumn } - - member codebuf.EmitByte x = codebuf.code.EmitIntAsByte x - member codebuf.EmitUInt16 x = codebuf.code.EmitUInt16 x - member codebuf.EmitInt32 x = codebuf.code.EmitInt32 x - member codebuf.EmitInt64 x = codebuf.code.EmitInt64 x - - member codebuf.EmitUncodedToken u = codebuf.EmitInt32 u - - member codebuf.RecordReqdStringFixup stringIdx = - codebuf.reqdStringFixupsInMethod <- (codebuf.code.Position, stringIdx) :: codebuf.reqdStringFixupsInMethod - // Write a special value in that we check later when applying the fixup - codebuf.EmitInt32 0xdeadbeef - - member codebuf.RecordReqdBrFixups i tgs = - codebuf.reqdBrFixups <- (i, codebuf.code.Position, tgs) :: codebuf.reqdBrFixups - // Write a special value in that we check later when applying the fixup - // Value is 0x11 {deadbbbb}* where 11 is for the instruction and deadbbbb is for each target - codebuf.EmitByte 0x11 // for the instruction - (if fst i = i_switch then - codebuf.EmitInt32 tgs.Length) - List.iter (fun _ -> codebuf.EmitInt32 0xdeadbbbb) tgs - - member codebuf.RecordReqdBrFixup i tg = codebuf.RecordReqdBrFixups i [tg] - member codebuf.RecordAvailBrFixup tg = - codebuf.availBrFixups.[tg] <- codebuf.code.Position - -module Codebuf = - // -------------------------------------------------------------------- - // Applying branch fixups. Use short versions of instructions - // wherever possible. Sadly we can only determine if we can use a short - // version after we've layed out the code for all other instructions. - // This in turn means that using a short version may change - // the various offsets into the code. - // -------------------------------------------------------------------- - - let binaryChop p (arr: 'T[]) = - let rec go n m = - if n > m then raise (KeyNotFoundException("binary chop did not find element")) - else - let i = (n+m)/2 - let c = p arr.[i] - if c = 0 then i elif c < 0 then go n (i-1) else go (i+1) m - go 0 (Array.length arr) - - let applyBrFixups (origCode : byte[]) origExnClauses origReqdStringFixups (origAvailBrFixups: Dictionary) origReqdBrFixups origSeqPoints origScopes = - let orderedOrigReqdBrFixups = origReqdBrFixups |> List.sortBy (fun (_, fixupLoc, _) -> fixupLoc) - - let newCode = ByteBuffer.Create origCode.Length - - // Copy over all the code, working out whether the branches will be short - // or long and adjusting the branch destinations. Record an adjust function to adjust all the other - // gumpf that refers to fixed offsets in the code stream. - let newCode, newReqdBrFixups, adjuster = - let remainingReqdFixups = ref orderedOrigReqdBrFixups - let origWhere = ref 0 - let newWhere = ref 0 - let doneLast = ref false - let newReqdBrFixups = ref [] - - let adjustments = ref [] - - while (!remainingReqdFixups <> [] || not !doneLast) do - let doingLast = isNil !remainingReqdFixups - let origStartOfNoBranchBlock = !origWhere - let newStartOfNoBranchBlock = !newWhere - - let origEndOfNoBranchBlock = - if doingLast then origCode.Length - else - let (_, origStartOfInstr, _) = List.head !remainingReqdFixups - origStartOfInstr - - // Copy over a chunk of non-branching code - let nobranch_len = origEndOfNoBranchBlock - origStartOfNoBranchBlock - newCode.EmitBytes origCode.[origStartOfNoBranchBlock..origStartOfNoBranchBlock+nobranch_len-1] - - // Record how to adjust addresses in this range, including the branch instruction - // we write below, or the end of the method if we're doing the last bblock - adjustments := (origStartOfNoBranchBlock, origEndOfNoBranchBlock, newStartOfNoBranchBlock) :: !adjustments - - // Increment locations to the branch instruction we're really interested in - origWhere := origEndOfNoBranchBlock - newWhere := !newWhere + nobranch_len - - // Now do the branch instruction. Decide whether the fixup will be short or long in the new code - if doingLast then - doneLast := true - else - let (i, origStartOfInstr, tgs: ILCodeLabel list) = List.head !remainingReqdFixups - remainingReqdFixups := List.tail !remainingReqdFixups - if origCode.[origStartOfInstr] <> 0x11uy then failwith "br fixup sanity check failed (1)" - let i_length = if fst i = i_switch then 5 else 1 - origWhere := !origWhere + i_length - - let origEndOfInstr = origStartOfInstr + i_length + 4 * tgs.Length - let newEndOfInstrIfSmall = !newWhere + i_length + 1 - let newEndOfInstrIfBig = !newWhere + i_length + 4 * tgs.Length - - let short = - match i, tgs with - | (_, Some i_short), [tg] - when - // Use the original offsets to compute if the branch is small or large. This is - // a safe approximation because code only gets smaller. - (let origDest = - match origAvailBrFixups.TryGetValue tg with - | true, fixup -> fixup - | _ -> - dprintn ("branch target " + formatCodeLabel tg + " not found in code") - 666666 - let origRelOffset = origDest - origEndOfInstr - -128 <= origRelOffset && origRelOffset <= 127) - -> - newCode.EmitIntAsByte i_short - true - | (i_long, _), _ -> - newCode.EmitIntAsByte i_long - (if i_long = i_switch then - newCode.EmitInt32 tgs.Length) - false - - newWhere := !newWhere + i_length - if !newWhere <> newCode.Position then dprintn "mismatch between newWhere and newCode" - - tgs |> List.iter (fun tg -> - let origFixupLoc = !origWhere - checkFixup32 origCode origFixupLoc 0xdeadbbbb - - if short then - newReqdBrFixups := (!newWhere, newEndOfInstrIfSmall, tg, true) :: !newReqdBrFixups - newCode.EmitIntAsByte 0x98 (* sanity check *) - newWhere := !newWhere + 1 - else - newReqdBrFixups := (!newWhere, newEndOfInstrIfBig, tg, false) :: !newReqdBrFixups - newCode.EmitInt32 0xf00dd00f (* sanity check *) - newWhere := !newWhere + 4 - if !newWhere <> newCode.Position then dprintn "mismatch between newWhere and newCode" - origWhere := !origWhere + 4) - - if !origWhere <> origEndOfInstr then dprintn "mismatch between origWhere and origEndOfInstr" - - let adjuster = - let arr = Array.ofList (List.rev !adjustments) - fun addr -> - let i = - try binaryChop (fun (a1, a2, _) -> if addr < a1 then -1 elif addr > a2 then 1 else 0) arr - with - :? KeyNotFoundException -> - failwith ("adjuster: address "+string addr+" is out of range") - let (origStartOfNoBranchBlock, _, newStartOfNoBranchBlock) = arr.[i] - addr - (origStartOfNoBranchBlock - newStartOfNoBranchBlock) - - newCode.Close(), - !newReqdBrFixups, - adjuster - - // Now adjust everything - let newAvailBrFixups = - let tab = Dictionary<_, _>(10, HashIdentity.Structural) - for (KeyValue(tglab, origBrDest)) in origAvailBrFixups do - tab.[tglab] <- adjuster origBrDest - tab - let newReqdStringFixups = List.map (fun (origFixupLoc, stok) -> adjuster origFixupLoc, stok) origReqdStringFixups - let newSeqPoints = Array.map (fun (sp: PdbSequencePoint) -> {sp with Offset=adjuster sp.Offset}) origSeqPoints - let newExnClauses = - origExnClauses |> List.map (fun (st1, sz1, st2, sz2, kind) -> - (adjuster st1, (adjuster (st1 + sz1) - adjuster st1), - adjuster st2, (adjuster (st2 + sz2) - adjuster st2), - (match kind with - | FinallyClause | FaultClause | TypeFilterClause _ -> kind - | FilterClause n -> FilterClause (adjuster n)))) - - let newScopes = - let rec remap scope = - {scope with StartOffset = adjuster scope.StartOffset - EndOffset = adjuster scope.EndOffset - Children = Array.map remap scope.Children } - List.map remap origScopes - - // Now apply the adjusted fixups in the new code - newReqdBrFixups |> List.iter (fun (newFixupLoc, endOfInstr, tg, small) -> - match newAvailBrFixups.TryGetValue tg with - | true, n -> - let relOffset = n - endOfInstr - if small then - if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixup sanity check failed" - newCode.[newFixupLoc] <- b0 relOffset - else - checkFixup32 newCode newFixupLoc 0xf00dd00fl - applyFixup32 newCode newFixupLoc relOffset - | _ -> failwith ("target " + formatCodeLabel tg + " not found in new fixups")) - - newCode, newReqdStringFixups, newExnClauses, newSeqPoints, newScopes - - - // -------------------------------------------------------------------- - // Structured residue of emitting instructions: SEH exception handling - // and scopes for local variables. - // -------------------------------------------------------------------- - - // Emitting instructions generates a tree of seh specifications - // We then emit the exception handling specs separately. - // nb. ECMA spec says the SEH blocks must be returned inside-out - type SEHTree = - | Node of ExceptionClauseSpec option * SEHTree list - - - // -------------------------------------------------------------------- - // Table of encodings for instructions without arguments, also indexes - // for all instructions. - // -------------------------------------------------------------------- - - let encodingsForNoArgInstrs = Dictionary<_, _>(300, HashIdentity.Structural) - let _ = - List.iter - (fun (x, mk) -> encodingsForNoArgInstrs.[mk] <- x) - (noArgInstrs.Force()) - let encodingsOfNoArgInstr si = encodingsForNoArgInstrs.[si] - - // -------------------------------------------------------------------- - // Emit instructions - // -------------------------------------------------------------------- - - /// Emit the code for an instruction - let emitInstrCode (codebuf: CodeBuffer) i = - if i > 0xFF then - assert (i >>> 8 = 0xFE) - codebuf.EmitByte ((i >>> 8) &&& 0xFF) - codebuf.EmitByte (i &&& 0xFF) - else - codebuf.EmitByte i - - let emitTypeInstr cenv codebuf env i ty = - emitInstrCode codebuf i - codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) - - let emitMethodSpecInfoInstr cenv codebuf env i mspecinfo = - emitInstrCode codebuf i - codebuf.EmitUncodedToken (GetMethodSpecInfoAsUncodedToken cenv env mspecinfo) - - let emitMethodSpecInstr cenv codebuf env i mspec = - emitInstrCode codebuf i - codebuf.EmitUncodedToken (GetMethodSpecAsUncodedToken cenv env mspec) - - let emitFieldSpecInstr cenv codebuf env i fspec = - emitInstrCode codebuf i - codebuf.EmitUncodedToken (GetFieldDefOrRefAsUncodedToken (GetFieldSpecAsFieldDefOrRef cenv env fspec)) - - let emitShortUInt16Instr codebuf (i_short, i) x = - let n = int32 x - if n <= 255 then - emitInstrCode codebuf i_short - codebuf.EmitByte n - else - emitInstrCode codebuf i - codebuf.EmitUInt16 x - - let emitShortInt32Instr codebuf (i_short, i) x = - if x >= (-128) && x <= 127 then - emitInstrCode codebuf i_short - codebuf.EmitByte (if x < 0x0 then x + 256 else x) - else - emitInstrCode codebuf i - codebuf.EmitInt32 x - - let emitTailness (cenv: cenv) codebuf tl = - if tl = Tailcall && cenv.emitTailcalls then emitInstrCode codebuf i_tail - - //let emitAfterTailcall codebuf tl = - // if tl = Tailcall then emitInstrCode codebuf i_ret - - let emitVolatility codebuf tl = - if tl = Volatile then emitInstrCode codebuf i_volatile - - let emitConstrained cenv codebuf env ty = - emitInstrCode codebuf i_constrained - codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) - - let emitAlignment codebuf tl = - match tl with - | Aligned -> () - | Unaligned1 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x1 - | Unaligned2 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x2 - | Unaligned4 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x4 - - let rec emitInstr cenv codebuf env instr = - match instr with - | si when isNoArgInstr si -> - emitInstrCode codebuf (encodingsOfNoArgInstr si) - | I_brcmp (cmp, tg1) -> - codebuf.RecordReqdBrFixup ((Lazy.force ILCmpInstrMap).[cmp], Some (Lazy.force ILCmpInstrRevMap).[cmp]) tg1 - | I_br tg -> codebuf.RecordReqdBrFixup (i_br, Some i_br_s) tg - | I_seqpoint s -> codebuf.EmitSeqPoint cenv s - | I_leave tg -> codebuf.RecordReqdBrFixup (i_leave, Some i_leave_s) tg - | I_call (tl, mspec, varargs) -> - emitTailness cenv codebuf tl - emitMethodSpecInstr cenv codebuf env i_call (mspec, varargs) - //emitAfterTailcall codebuf tl - | I_callvirt (tl, mspec, varargs) -> - emitTailness cenv codebuf tl - emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) - //emitAfterTailcall codebuf tl - | I_callconstraint (tl, ty, mspec, varargs) -> - emitTailness cenv codebuf tl - emitConstrained cenv codebuf env ty - emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) - //emitAfterTailcall codebuf tl - | I_newobj (mspec, varargs) -> - emitMethodSpecInstr cenv codebuf env i_newobj (mspec, varargs) - | I_ldftn mspec -> - emitMethodSpecInstr cenv codebuf env i_ldftn (mspec, None) - | I_ldvirtftn mspec -> - emitMethodSpecInstr cenv codebuf env i_ldvirtftn (mspec, None) - - | I_calli (tl, callsig, varargs) -> - emitTailness cenv codebuf tl - emitInstrCode codebuf i_calli - codebuf.EmitUncodedToken (getUncodedToken TableNames.StandAloneSig (GetCallsigAsStandAloneSigIdx cenv env (callsig, varargs))) - //emitAfterTailcall codebuf tl - - | I_ldarg u16 -> emitShortUInt16Instr codebuf (i_ldarg_s, i_ldarg) u16 - | I_starg u16 -> emitShortUInt16Instr codebuf (i_starg_s, i_starg) u16 - | I_ldarga u16 -> emitShortUInt16Instr codebuf (i_ldarga_s, i_ldarga) u16 - | I_ldloc u16 -> emitShortUInt16Instr codebuf (i_ldloc_s, i_ldloc) u16 - | I_stloc u16 -> emitShortUInt16Instr codebuf (i_stloc_s, i_stloc) u16 - | I_ldloca u16 -> emitShortUInt16Instr codebuf (i_ldloca_s, i_ldloca) u16 - - | I_cpblk (al, vol) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitInstrCode codebuf i_cpblk - | I_initblk (al, vol) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitInstrCode codebuf i_initblk - - | (AI_ldc (DT_I4, ILConst.I4 x)) -> - emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) x - | (AI_ldc (DT_I8, ILConst.I8 x)) -> - emitInstrCode codebuf i_ldc_i8 - codebuf.EmitInt64 x - | (AI_ldc (_, ILConst.R4 x)) -> - emitInstrCode codebuf i_ldc_r4 - codebuf.EmitInt32 (bitsOfSingle x) - | (AI_ldc (_, ILConst.R8 x)) -> - emitInstrCode codebuf i_ldc_r8 - codebuf.EmitInt64 (bitsOfDouble x) - - | I_ldind (al, vol, dt) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitInstrCode codebuf - (match dt with - | DT_I -> i_ldind_i - | DT_I1 -> i_ldind_i1 - | DT_I2 -> i_ldind_i2 - | DT_I4 -> i_ldind_i4 - | DT_U1 -> i_ldind_u1 - | DT_U2 -> i_ldind_u2 - | DT_U4 -> i_ldind_u4 - | DT_I8 -> i_ldind_i8 - | DT_R4 -> i_ldind_r4 - | DT_R8 -> i_ldind_r8 - | DT_REF -> i_ldind_ref - | _ -> failwith "ldind") - - | I_stelem dt -> - emitInstrCode codebuf - (match dt with - | DT_I | DT_U -> i_stelem_i - | DT_U1 | DT_I1 -> i_stelem_i1 - | DT_I2 | DT_U2 -> i_stelem_i2 - | DT_I4 | DT_U4 -> i_stelem_i4 - | DT_I8 | DT_U8 -> i_stelem_i8 - | DT_R4 -> i_stelem_r4 - | DT_R8 -> i_stelem_r8 - | DT_REF -> i_stelem_ref - | _ -> failwith "stelem") - - | I_ldelem dt -> - emitInstrCode codebuf - (match dt with - | DT_I -> i_ldelem_i - | DT_I1 -> i_ldelem_i1 - | DT_I2 -> i_ldelem_i2 - | DT_I4 -> i_ldelem_i4 - | DT_I8 -> i_ldelem_i8 - | DT_U1 -> i_ldelem_u1 - | DT_U2 -> i_ldelem_u2 - | DT_U4 -> i_ldelem_u4 - | DT_R4 -> i_ldelem_r4 - | DT_R8 -> i_ldelem_r8 - | DT_REF -> i_ldelem_ref - | _ -> failwith "ldelem") - - | I_stind (al, vol, dt) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitInstrCode codebuf - (match dt with - | DT_U | DT_I -> i_stind_i - | DT_U1 | DT_I1 -> i_stind_i1 - | DT_U2 | DT_I2 -> i_stind_i2 - | DT_U4 | DT_I4 -> i_stind_i4 - | DT_U8 | DT_I8 -> i_stind_i8 - | DT_R4 -> i_stind_r4 - | DT_R8 -> i_stind_r8 - | DT_REF -> i_stind_ref - | _ -> failwith "stelem") - - | I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs - - | I_ldfld (al, vol, fspec) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitFieldSpecInstr cenv codebuf env i_ldfld fspec - | I_ldflda fspec -> - emitFieldSpecInstr cenv codebuf env i_ldflda fspec - | I_ldsfld (vol, fspec) -> - emitVolatility codebuf vol - emitFieldSpecInstr cenv codebuf env i_ldsfld fspec - | I_ldsflda fspec -> - emitFieldSpecInstr cenv codebuf env i_ldsflda fspec - | I_stfld (al, vol, fspec) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitFieldSpecInstr cenv codebuf env i_stfld fspec - | I_stsfld (vol, fspec) -> - emitVolatility codebuf vol - emitFieldSpecInstr cenv codebuf env i_stsfld fspec - - | I_ldtoken tok -> - emitInstrCode codebuf i_ldtoken - codebuf.EmitUncodedToken - (match tok with - | ILToken.ILType ty -> - match GetTypeAsTypeDefOrRef cenv env ty with - | (tag, idx) when tag = tdor_TypeDef -> getUncodedToken TableNames.TypeDef idx - | (tag, idx) when tag = tdor_TypeRef -> getUncodedToken TableNames.TypeRef idx - | (tag, idx) when tag = tdor_TypeSpec -> getUncodedToken TableNames.TypeSpec idx - | _ -> failwith "?" - | ILToken.ILMethod mspec -> - match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with - | (tag, idx) when tag = mdor_MethodDef -> getUncodedToken TableNames.Method idx - | (tag, idx) when tag = mdor_MemberRef -> getUncodedToken TableNames.MemberRef idx - | _ -> failwith "?" - - | ILToken.ILField fspec -> - match GetFieldSpecAsFieldDefOrRef cenv env fspec with - | (true, idx) -> getUncodedToken TableNames.Field idx - | (false, idx) -> getUncodedToken TableNames.MemberRef idx) - | I_ldstr s -> - emitInstrCode codebuf i_ldstr - codebuf.RecordReqdStringFixup (GetUserStringHeapIdx cenv s) - - | I_box ty -> emitTypeInstr cenv codebuf env i_box ty - | I_unbox ty -> emitTypeInstr cenv codebuf env i_unbox ty - | I_unbox_any ty -> emitTypeInstr cenv codebuf env i_unbox_any ty - - | I_newarr (shape, ty) -> - if (shape = ILArrayShape.SingleDimensional) then - emitTypeInstr cenv codebuf env i_newarr ty - else - let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) - emitMethodSpecInfoInstr cenv codebuf env i_newobj (".ctor", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, []) - - | I_stelem_any (shape, ty) -> - if (shape = ILArrayShape.SingleDimensional) then - emitTypeInstr cenv codebuf env i_stelem_any ty - else - let args = List.init (shape.Rank+1) (fun i -> if i < shape.Rank then cenv.ilg.typ_Int32 else ty) - emitMethodSpecInfoInstr cenv codebuf env i_call ("Set", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, []) - - | I_ldelem_any (shape, ty) -> - if (shape = ILArrayShape.SingleDimensional) then - emitTypeInstr cenv codebuf env i_ldelem_any ty - else - let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) - emitMethodSpecInfoInstr cenv codebuf env i_call ("Get", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ty, None, []) - - | I_ldelema (ro, _isNativePtr, shape, ty) -> - if (ro = ReadonlyAddress) then - emitInstrCode codebuf i_readonly - if (shape = ILArrayShape.SingleDimensional) then - emitTypeInstr cenv codebuf env i_ldelema ty - else - let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) - emitMethodSpecInfoInstr cenv codebuf env i_call ("Address", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Byref ty, None, []) - - | I_castclass ty -> emitTypeInstr cenv codebuf env i_castclass ty - | I_isinst ty -> emitTypeInstr cenv codebuf env i_isinst ty - | I_refanyval ty -> emitTypeInstr cenv codebuf env i_refanyval ty - | I_mkrefany ty -> emitTypeInstr cenv codebuf env i_mkrefany ty - | I_initobj ty -> emitTypeInstr cenv codebuf env i_initobj ty - | I_ldobj (al, vol, ty) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitTypeInstr cenv codebuf env i_ldobj ty - | I_stobj (al, vol, ty) -> - emitAlignment codebuf al - emitVolatility codebuf vol - emitTypeInstr cenv codebuf env i_stobj ty - | I_cpobj ty -> emitTypeInstr cenv codebuf env i_cpobj ty - | I_sizeof ty -> emitTypeInstr cenv codebuf env i_sizeof ty - | EI_ldlen_multi (_, m) -> - emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) m - emitInstr cenv codebuf env (mkNormalCall(mkILNonGenericMethSpecInTy(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [(cenv.ilg.typ_Int32)], (cenv.ilg.typ_Int32)))) - - | _ -> failwith "an IL instruction cannot be emitted" - - - let mkScopeNode cenv (localSigs: _[]) (startOffset, endOffset, ls: ILLocalDebugMapping list, childScopes) = - if isNil ls || not cenv.generatePdb then childScopes - else - [ { Children= Array.ofList childScopes - StartOffset=startOffset - EndOffset=endOffset - Locals= - ls |> List.filter (fun v -> v.LocalName <> "") - |> List.map (fun x -> - { Name=x.LocalName - Signature= (try localSigs.[x.LocalIndex] with _ -> failwith ("local variable index "+string x.LocalIndex+"in debug info does not reference a valid local")) - Index= x.LocalIndex } ) - |> Array.ofList } ] - - - // Used to put local debug scopes and exception handlers into a tree form - let rangeInsideRange (start_pc1, end_pc1) (start_pc2, end_pc2) = - (start_pc1: int) >= start_pc2 && start_pc1 < end_pc2 && - (end_pc1: int) > start_pc2 && end_pc1 <= end_pc2 - - let lranges_of_clause cl = - match cl with - | ILExceptionClause.Finally r1 -> [r1] - | ILExceptionClause.Fault r1 -> [r1] - | ILExceptionClause.FilterCatch (r1, r2) -> [r1;r2] - | ILExceptionClause.TypeCatch (_ty, r1) -> [r1] - - - let labelsToRange (lab2pc : Dictionary) p = let (l1, l2) = p in lab2pc.[l1], lab2pc.[l2] - - let labelRangeInsideLabelRange lab2pc ls1 ls2 = - rangeInsideRange (labelsToRange lab2pc ls1) (labelsToRange lab2pc ls2) - - let findRoots contains vs = - // For each item, either make it a root or make it a child of an existing root - let addToRoot roots x = - // Look to see if 'x' is inside one of the roots - let roots, found = - (false, roots) ||> List.mapFold (fun found (r, children) -> - if found then ((r, children), true) - elif contains x r then ((r, x :: children), true) - else ((r, children), false)) - - if found then roots - else - // Find the ones that 'x' encompasses and collapse them - let yes, others = roots |> List.partition (fun (r, _) -> contains r x) - (x, yes |> List.collect (fun (r, ch) -> r :: ch)) :: others - - ([], vs) ||> List.fold addToRoot - - let rec makeSEHTree cenv env (pc2pos: int[]) (lab2pc : Dictionary) (exs : ILExceptionSpec list) = - - let clause_inside_lrange cl lr = - List.forall (fun lr1 -> labelRangeInsideLabelRange lab2pc lr1 lr) (lranges_of_clause cl) - - let tryspec_inside_lrange (tryspec1: ILExceptionSpec) lr = - (labelRangeInsideLabelRange lab2pc tryspec1.Range lr && clause_inside_lrange tryspec1.Clause lr) - - let tryspec_inside_clause tryspec1 cl = - List.exists (fun lr -> tryspec_inside_lrange tryspec1 lr) (lranges_of_clause cl) - - let tryspec_inside_tryspec tryspec1 (tryspec2: ILExceptionSpec) = - tryspec_inside_lrange tryspec1 tryspec2.Range || - tryspec_inside_clause tryspec1 tryspec2.Clause - - let roots = findRoots tryspec_inside_tryspec exs - let trees = - roots |> List.map (fun (cl, ch) -> - let r1 = labelsToRange lab2pc cl.Range - let conv ((s1, e1), (s2, e2)) x = pc2pos.[s1], pc2pos.[e1] - pc2pos.[s1], pc2pos.[s2], pc2pos.[e2] - pc2pos.[s2], x - let children = makeSEHTree cenv env pc2pos lab2pc ch - let n = - match cl.Clause with - | ILExceptionClause.Finally r2 -> - conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FinallyClause - | ILExceptionClause.Fault r2 -> - conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FaultClause - | ILExceptionClause.FilterCatch ((filterStart, _), r3) -> - conv (r1, labelsToRange lab2pc r3) (ExceptionClauseKind.FilterClause (pc2pos.[lab2pc.[filterStart]])) - | ILExceptionClause.TypeCatch (ty, r2) -> - conv (r1, labelsToRange lab2pc r2) (TypeFilterClause (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty))) - SEHTree.Node (Some n, children) ) - - trees - - let rec makeLocalsTree cenv localSigs (pc2pos: int[]) (lab2pc : Dictionary) (exs : ILLocalDebugInfo list) = - let localInsideLocal (locspec1: ILLocalDebugInfo) (locspec2: ILLocalDebugInfo) = - labelRangeInsideLabelRange lab2pc locspec1.Range locspec2.Range - - let roots = findRoots localInsideLocal exs - - let trees = - roots |> List.collect (fun (cl, ch) -> - let (s1, e1) = labelsToRange lab2pc cl.Range - let (s1, e1) = pc2pos.[s1], pc2pos.[e1] - let children = makeLocalsTree cenv localSigs pc2pos lab2pc ch - mkScopeNode cenv localSigs (s1, e1, cl.DebugMappings, children)) - trees - - - // Emit the SEH tree - let rec emitExceptionHandlerTree (codebuf: CodeBuffer) (Node (x, childSEH)) = - List.iter (emitExceptionHandlerTree codebuf) childSEH // internal first - x |> Option.iter codebuf.EmitExceptionClause - - let emitCode cenv localSigs (codebuf: CodeBuffer) env (code: ILCode) = - let instrs = code.Instrs - - // Build a table mapping Abstract IL pcs to positions in the generated code buffer - let pc2pos = Array.zeroCreate (instrs.Length+1) - let pc2labs = Dictionary() - for KeyValue (lab, pc) in code.Labels do - match pc2labs.TryGetValue pc with - | true, labels -> - pc2labs.[pc] <- lab :: labels - | _ -> pc2labs.[pc] <- [lab] - - // Emit the instructions - for pc = 0 to instrs.Length do - match pc2labs.TryGetValue pc with - | true, labels -> - for lab in labels do - codebuf.RecordAvailBrFixup lab - | _ -> () - pc2pos.[pc] <- codebuf.code.Position - if pc < instrs.Length then - match instrs.[pc] with - | I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction - | i -> emitInstr cenv codebuf env i - - // Build the exceptions and locals information, ready to emit - let SEHTree = makeSEHTree cenv env pc2pos code.Labels code.Exceptions - List.iter (emitExceptionHandlerTree codebuf) SEHTree - - // Build the locals information, ready to emit - let localsTree = makeLocalsTree cenv localSigs pc2pos code.Labels code.Locals - localsTree - - let EmitTopCode cenv localSigs env nm code = - let codebuf = CodeBuffer.Create nm - let origScopes = emitCode cenv localSigs codebuf env code - let origCode = codebuf.code.Close() - let origExnClauses = List.rev codebuf.seh - let origReqdStringFixups = codebuf.reqdStringFixupsInMethod - let origAvailBrFixups = codebuf.availBrFixups - let origReqdBrFixups = codebuf.reqdBrFixups - let origSeqPoints = codebuf.seqpoints.ToArray() - - let newCode, newReqdStringFixups, newExnClauses, newSeqPoints, newScopes = - applyBrFixups origCode origExnClauses origReqdStringFixups origAvailBrFixups origReqdBrFixups origSeqPoints origScopes - - let rootScope = - { Children= Array.ofList newScopes - StartOffset=0 - EndOffset=newCode.Length - Locals=[| |] } - - (newReqdStringFixups, newExnClauses, newCode, newSeqPoints, rootScope) - -// -------------------------------------------------------------------- -// ILMethodBody --> bytes -// -------------------------------------------------------------------- -let GetFieldDefTypeAsBlobIdx cenv env ty = - let bytes = emitBytesViaBuffer (fun bb -> bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD - EmitType cenv env bb ty) - GetBytesAsBlobIdx cenv bytes - -let GenILMethodBody mname cenv env (il: ILMethodBody) = - let localSigs = - if cenv.generatePdb then - il.Locals |> List.toArray |> Array.map (fun l -> - // Write a fake entry for the local signature headed by e_IMAGE_CEE_CS_CALLCONV_FIELD. This is referenced by the PDB file - ignore (FindOrAddSharedRow cenv TableNames.StandAloneSig (SharedRow [| Blob (GetFieldDefTypeAsBlobIdx cenv env l.Type) |])) - // Now write the type - GetTypeOfLocalAsBytes cenv env l) - else - [| |] - - let requiredStringFixups, seh, code, seqpoints, scopes = Codebuf.EmitTopCode cenv localSigs env mname il.Code - let codeSize = code.Length - let methbuf = ByteBuffer.Create (codeSize * 3) - // Do we use the tiny format? - if isNil il.Locals && il.MaxStack <= 8 && isNil seh && codeSize < 64 then - // Use Tiny format - let alignedCodeSize = align 4 (codeSize + 1) - let codePadding = (alignedCodeSize - (codeSize + 1)) - let requiredStringFixups' = (1, requiredStringFixups) - methbuf.EmitByte (byte codeSize <<< 2 ||| e_CorILMethod_TinyFormat) - methbuf.EmitBytes code - methbuf.EmitPadding codePadding - 0x0, (requiredStringFixups', methbuf.Close()), seqpoints, scopes - else - // Use Fat format - let flags = - e_CorILMethod_FatFormat ||| - (if seh <> [] then e_CorILMethod_MoreSects else 0x0uy) ||| - (if il.IsZeroInit then e_CorILMethod_InitLocals else 0x0uy) - - let localToken = - if isNil il.Locals then 0x0 else - getUncodedToken TableNames.StandAloneSig - (FindOrAddSharedRow cenv TableNames.StandAloneSig (GetLocalSigAsStandAloneSigIdx cenv env il.Locals)) - - let alignedCodeSize = align 0x4 codeSize - let codePadding = (alignedCodeSize - codeSize) - - methbuf.EmitByte flags - methbuf.EmitByte 0x30uy // last four bits record size of fat header in 4 byte chunks - this is always 12 bytes = 3 four word chunks - methbuf.EmitUInt16 (uint16 il.MaxStack) - methbuf.EmitInt32 codeSize - methbuf.EmitInt32 localToken - methbuf.EmitBytes code - methbuf.EmitPadding codePadding - - if not (isNil seh) then - // Can we use the small exception handling table format? - let smallSize = (seh.Length * 12 + 4) - let canUseSmall = - smallSize <= 0xFF && - seh |> List.forall (fun (st1, sz1, st2, sz2, _) -> - st1 <= 0xFFFF && st2 <= 0xFFFF && sz1 <= 0xFF && sz2 <= 0xFF) - - let kindAsInt32 k = - match k with - | FinallyClause -> e_COR_ILEXCEPTION_CLAUSE_FINALLY - | FaultClause -> e_COR_ILEXCEPTION_CLAUSE_FAULT - | FilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_FILTER - | TypeFilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_EXCEPTION - let kindAsExtraInt32 k = - match k with - | FinallyClause | FaultClause -> 0x0 - | FilterClause i -> i - | TypeFilterClause uncoded -> uncoded - - if canUseSmall then - methbuf.EmitByte e_CorILMethod_Sect_EHTable - methbuf.EmitByte (b0 smallSize) - methbuf.EmitByte 0x00uy - methbuf.EmitByte 0x00uy - seh |> List.iter (fun (st1, sz1, st2, sz2, kind) -> - let k32 = kindAsInt32 kind - methbuf.EmitInt32AsUInt16 k32 - methbuf.EmitInt32AsUInt16 st1 - methbuf.EmitByte (b0 sz1) - methbuf.EmitInt32AsUInt16 st2 - methbuf.EmitByte (b0 sz2) - methbuf.EmitInt32 (kindAsExtraInt32 kind)) - else - let bigSize = (seh.Length * 24 + 4) - methbuf.EmitByte (e_CorILMethod_Sect_EHTable ||| e_CorILMethod_Sect_FatFormat) - methbuf.EmitByte (b0 bigSize) - methbuf.EmitByte (b1 bigSize) - methbuf.EmitByte (b2 bigSize) - seh |> List.iter (fun (st1, sz1, st2, sz2, kind) -> - let k32 = kindAsInt32 kind - methbuf.EmitInt32 k32 - methbuf.EmitInt32 st1 - methbuf.EmitInt32 sz1 - methbuf.EmitInt32 st2 - methbuf.EmitInt32 sz2 - methbuf.EmitInt32 (kindAsExtraInt32 kind)) - - let requiredStringFixups' = (12, requiredStringFixups) - - localToken, (requiredStringFixups', methbuf.Close()), seqpoints, scopes - -// -------------------------------------------------------------------- -// ILFieldDef --> FieldDef Row -// -------------------------------------------------------------------- - -let rec GetFieldDefAsFieldDefRow cenv env (fd: ILFieldDef) = - let flags = int fd.Attributes - UnsharedRow - [| UShort (uint16 flags) - StringE (GetStringHeapIdx cenv fd.Name) - Blob (GetFieldDefSigAsBlobIdx cenv env fd ) |] - -and GetFieldDefSigAsBlobIdx cenv env fd = GetFieldDefTypeAsBlobIdx cenv env fd.FieldType - -and GenFieldDefPass3 cenv env fd = - let fidx = AddUnsharedRow cenv TableNames.Field (GetFieldDefAsFieldDefRow cenv env fd) - GenCustomAttrsPass3Or4 cenv (hca_FieldDef, fidx) fd.CustomAttrs - // Write FieldRVA table - fixups into data section done later - match fd.Data with - | None -> () - | Some b -> - let offs = cenv.data.Position - cenv.data.EmitBytes b - AddUnsharedRow cenv TableNames.FieldRVA - (UnsharedRow [| Data (offs, false); SimpleIndex (TableNames.Field, fidx) |]) |> ignore - // Write FieldMarshal table - match fd.Marshal with - | None -> () - | Some ntyp -> - AddUnsharedRow cenv TableNames.FieldMarshal - (UnsharedRow [| HasFieldMarshal (hfm_FieldDef, fidx) - Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore - // Write Content table - match fd.LiteralValue with - | None -> () - | Some i -> - AddUnsharedRow cenv TableNames.Constant - (UnsharedRow - [| GetFieldInitFlags i - HasConstant (hc_FieldDef, fidx) - Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore - // Write FieldLayout table - match fd.Offset with - | None -> () - | Some offset -> - AddUnsharedRow cenv TableNames.FieldLayout - (UnsharedRow [| ULong offset; SimpleIndex (TableNames.Field, fidx) |]) |> ignore - - -// -------------------------------------------------------------------- -// ILGenericParameterDef --> GenericParam Row -// -------------------------------------------------------------------- - -let rec GetGenericParamAsGenericParamRow cenv _env idx owner gp = - let flags = - (match gp.Variance with - | NonVariant -> 0x0000 - | CoVariant -> 0x0001 - | ContraVariant -> 0x0002) ||| - (if gp.HasReferenceTypeConstraint then 0x0004 else 0x0000) ||| - (if gp.HasNotNullableValueTypeConstraint then 0x0008 else 0x0000) ||| - (if gp.HasDefaultConstructorConstraint then 0x0010 else 0x0000) - - let mdVersionMajor, _ = metadataSchemaVersionSupportedByCLRVersion cenv.desiredMetadataVersion - if (mdVersionMajor = 1) then - SharedRow - [| UShort (uint16 idx) - UShort (uint16 flags) - TypeOrMethodDef (fst owner, snd owner) - StringE (GetStringHeapIdx cenv gp.Name) - TypeDefOrRefOrSpec (tdor_TypeDef, 0) (* empty kind field in deprecated metadata *) |] - else - SharedRow - [| UShort (uint16 idx) - UShort (uint16 flags) - TypeOrMethodDef (fst owner, snd owner) - StringE (GetStringHeapIdx cenv gp.Name) |] - -and GenTypeAsGenericParamConstraintRow cenv env gpidx ty = - let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty - UnsharedRow - [| SimpleIndex (TableNames.GenericParam, gpidx) - TypeDefOrRefOrSpec (tdorTag, tdorRow) |] - -and GenGenericParamConstraintPass4 cenv env gpidx ty = - AddUnsharedRow cenv TableNames.GenericParamConstraint (GenTypeAsGenericParamConstraintRow cenv env gpidx ty) |> ignore - -and GenGenericParamPass3 cenv env idx owner gp = - // here we just collect generic params, its constraints\custom attributes will be processed on pass4 - // shared since we look it up again below in GenGenericParamPass4 - AddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) - |> ignore - - -and GenGenericParamPass4 cenv env idx owner gp = - let gpidx = FindOrAddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) - GenCustomAttrsPass3Or4 cenv (hca_GenericParam, gpidx) gp.CustomAttrs - gp.Constraints |> List.iter (GenGenericParamConstraintPass4 cenv env gpidx) - -// -------------------------------------------------------------------- -// param and return --> Param Row -// -------------------------------------------------------------------- - -let rec GetParamAsParamRow cenv _env seq (param: ILParameter) = - let flags = - (if param.IsIn then 0x0001 else 0x0000) ||| - (if param.IsOut then 0x0002 else 0x0000) ||| - (if param.IsOptional then 0x0010 else 0x0000) ||| - (if param.Default <> None then 0x1000 else 0x0000) ||| - (if param.Marshal <> None then 0x2000 else 0x0000) - - UnsharedRow - [| UShort (uint16 flags) - UShort (uint16 seq) - StringE (GetStringHeapIdxOption cenv param.Name) |] - -and GenParamPass3 cenv env seq (param: ILParameter) = - if not param.IsIn && not param.IsOut && not param.IsOptional && Option.isNone param.Default && Option.isNone param.Name && Option.isNone param.Marshal - then () - else - let pidx = AddUnsharedRow cenv TableNames.Param (GetParamAsParamRow cenv env seq param) - GenCustomAttrsPass3Or4 cenv (hca_ParamDef, pidx) param.CustomAttrs - // Write FieldRVA table - fixups into data section done later - match param.Marshal with - | None -> () - | Some ntyp -> - AddUnsharedRow cenv TableNames.FieldMarshal - (UnsharedRow [| HasFieldMarshal (hfm_ParamDef, pidx); Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore - // Write Content table for DefaultParameterValue attr - match param.Default with - | None -> () - | Some i -> - AddUnsharedRow cenv TableNames.Constant - (UnsharedRow - [| GetFieldInitFlags i - HasConstant (hc_ParamDef, pidx) - Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore - -let GenReturnAsParamRow (returnv : ILReturn) = - let flags = (if returnv.Marshal <> None then 0x2000 else 0x0000) - UnsharedRow - [| UShort (uint16 flags) - UShort 0us (* sequence num. *) - StringE 0 |] - -let GenReturnPass3 cenv (returnv: ILReturn) = - if Option.isSome returnv.Marshal || not (Array.isEmpty returnv.CustomAttrs.AsArray) then - let pidx = AddUnsharedRow cenv TableNames.Param (GenReturnAsParamRow returnv) - GenCustomAttrsPass3Or4 cenv (hca_ParamDef, pidx) returnv.CustomAttrs - match returnv.Marshal with - | None -> () - | Some ntyp -> - AddUnsharedRow cenv TableNames.FieldMarshal - (UnsharedRow - [| HasFieldMarshal (hfm_ParamDef, pidx) - Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore - -// -------------------------------------------------------------------- -// ILMethodDef --> ILMethodDef Row -// -------------------------------------------------------------------- - -let GetMethodDefSigAsBytes cenv env (mdef: ILMethodDef) = - emitBytesViaBuffer (fun bb -> - bb.EmitByte (callconvToByte mdef.GenericParams.Length mdef.CallingConv) - if not (List.isEmpty mdef.GenericParams) then bb.EmitZ32 mdef.GenericParams.Length - bb.EmitZ32 mdef.Parameters.Length - EmitType cenv env bb mdef.Return.Type - mdef.ParameterTypes |> List.iter (EmitType cenv env bb)) - -let GenMethodDefSigAsBlobIdx cenv env mdef = - GetBytesAsBlobIdx cenv (GetMethodDefSigAsBytes cenv env mdef) - -let GenMethodDefAsRow cenv env midx (md: ILMethodDef) = - let flags = md.Attributes - - let implflags = md.ImplAttributes - - if md.IsEntryPoint then - if cenv.entrypoint <> None then failwith "duplicate entrypoint" - else cenv.entrypoint <- Some (true, midx) - let codeAddr = - (match md.Body.Contents with - | MethodBody.IL ilmbody -> - let addr = cenv.nextCodeAddr - let (localToken, code, seqpoints, rootScope) = GenILMethodBody md.Name cenv env ilmbody - - // Now record the PDB record for this method - we write this out later. - if cenv.generatePdb then - cenv.pdbinfo.Add - { MethToken=getUncodedToken TableNames.Method midx - MethName=md.Name - LocalSignatureToken=localToken - Params= [| |] (* REVIEW *) - RootScope = Some rootScope - Range= - match ilmbody.SourceMarker with - | Some m when cenv.generatePdb -> - // table indexes are 1-based, document array indexes are 0-based - let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 - - Some ({ Document=doc - Line=m.Line - Column=m.Column }, - { Document=doc - Line=m.EndLine - Column=m.EndColumn }) - | _ -> None - SequencePoints=seqpoints } - cenv.AddCode code - addr - | MethodBody.Abstract - | MethodBody.PInvoke _ -> - // Now record the PDB record for this method - we write this out later. - if cenv.generatePdb then - cenv.pdbinfo.Add - { MethToken = getUncodedToken TableNames.Method midx - MethName = md.Name - LocalSignatureToken = 0x0 // No locals it's abstract - Params = [| |] - RootScope = None - Range = None - SequencePoints = [| |] } - 0x0000 - | MethodBody.Native -> - failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries" - | _ -> 0x0000) - - UnsharedRow - [| ULong codeAddr - UShort (uint16 implflags) - UShort (uint16 flags) - StringE (GetStringHeapIdx cenv md.Name) - Blob (GenMethodDefSigAsBlobIdx cenv env md) - SimpleIndex(TableNames.Param, cenv.GetTable(TableNames.Param).Count + 1) |] - -let GenMethodImplPass3 cenv env _tgparams tidx mimpl = - let midxTag, midxRow = GetMethodSpecAsMethodDef cenv env (mimpl.OverrideBy, None) - let midx2Tag, midx2Row = GetOverridesSpecAsMethodDefOrRef cenv env mimpl.Overrides - AddUnsharedRow cenv TableNames.MethodImpl - (UnsharedRow - [| SimpleIndex (TableNames.TypeDef, tidx) - MethodDefOrRef (midxTag, midxRow) - MethodDefOrRef (midx2Tag, midx2Row) |]) |> ignore - -let GenMethodDefPass3 cenv env (md: ILMethodDef) = - let midx = GetMethodDefIdx cenv md - let idx2 = AddUnsharedRow cenv TableNames.Method (GenMethodDefAsRow cenv env midx md) - if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2" - GenReturnPass3 cenv md.Return - md.Parameters |> List.iteri (fun n param -> GenParamPass3 cenv env (n+1) param) - md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_MethodDef, midx) - md.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx) - md.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_MethodDef, midx) gp) - match md.Body.Contents with - | MethodBody.PInvoke attr -> - let flags = - begin match attr.CallingConv with - | PInvokeCallingConvention.None -> 0x0000 - | PInvokeCallingConvention.Cdecl -> 0x0200 - | PInvokeCallingConvention.Stdcall -> 0x0300 - | PInvokeCallingConvention.Thiscall -> 0x0400 - | PInvokeCallingConvention.Fastcall -> 0x0500 - | PInvokeCallingConvention.WinApi -> 0x0100 - end ||| - begin match attr.CharEncoding with - | PInvokeCharEncoding.None -> 0x0000 - | PInvokeCharEncoding.Ansi -> 0x0002 - | PInvokeCharEncoding.Unicode -> 0x0004 - | PInvokeCharEncoding.Auto -> 0x0006 - end ||| - begin match attr.CharBestFit with - | PInvokeCharBestFit.UseAssembly -> 0x0000 - | PInvokeCharBestFit.Enabled -> 0x0010 - | PInvokeCharBestFit.Disabled -> 0x0020 - end ||| - begin match attr.ThrowOnUnmappableChar with - | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000 - | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000 - | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000 - end ||| - (if attr.NoMangle then 0x0001 else 0x0000) ||| - (if attr.LastError then 0x0040 else 0x0000) - AddUnsharedRow cenv TableNames.ImplMap - (UnsharedRow - [| UShort (uint16 flags) - MemberForwarded (mf_MethodDef, midx) - StringE (GetStringHeapIdx cenv attr.Name) - SimpleIndex (TableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore - | _ -> () - -let GenMethodDefPass4 cenv env md = - let midx = GetMethodDefIdx cenv md - List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_MethodDef, midx) gp) md.GenericParams - -let GenPropertyMethodSemanticsPass3 cenv pidx kind mref = - // REVIEW: why are we catching exceptions here? - let midx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 - AddUnsharedRow cenv TableNames.MethodSemantics - (UnsharedRow - [| UShort (uint16 kind) - SimpleIndex (TableNames.Method, midx) - HasSemantics (hs_Property, pidx) |]) |> ignore - -let rec GetPropertySigAsBlobIdx cenv env prop = - GetBytesAsBlobIdx cenv (GetPropertySigAsBytes cenv env prop) - -and GetPropertySigAsBytes cenv env (prop: ILPropertyDef) = - emitBytesViaBuffer (fun bb -> - let b = ((hasthisToByte prop.CallingConv) ||| e_IMAGE_CEE_CS_CALLCONV_PROPERTY) - bb.EmitByte b - bb.EmitZ32 prop.Args.Length - EmitType cenv env bb prop.PropertyType - prop.Args |> List.iter (EmitType cenv env bb)) - -and GetPropertyAsPropertyRow cenv env (prop: ILPropertyDef) = - let flags = prop.Attributes - UnsharedRow - [| UShort (uint16 flags) - StringE (GetStringHeapIdx cenv prop.Name) - Blob (GetPropertySigAsBlobIdx cenv env prop) |] - -/// ILPropertyDef --> Property Row + MethodSemantics entries -and GenPropertyPass3 cenv env prop = - let pidx = AddUnsharedRow cenv TableNames.Property (GetPropertyAsPropertyRow cenv env prop) - prop.SetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0001) - prop.GetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0002) - // Write Constant table - match prop.Init with - | None -> () - | Some i -> - AddUnsharedRow cenv TableNames.Constant - (UnsharedRow - [| GetFieldInitFlags i - HasConstant (hc_Property, pidx) - Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore - GenCustomAttrsPass3Or4 cenv (hca_Property, pidx) prop.CustomAttrs - -let rec GenEventMethodSemanticsPass3 cenv eidx kind mref = - let addIdx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 - AddUnsharedRow cenv TableNames.MethodSemantics - (UnsharedRow - [| UShort (uint16 kind) - SimpleIndex (TableNames.Method, addIdx) - HasSemantics (hs_Event, eidx) |]) |> ignore - -/// ILEventDef --> Event Row + MethodSemantics entries -and GenEventAsEventRow cenv env (md: ILEventDef) = - let flags = md.Attributes - let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env md.EventType - UnsharedRow - [| UShort (uint16 flags) - StringE (GetStringHeapIdx cenv md.Name) - TypeDefOrRefOrSpec (tdorTag, tdorRow) |] - -and GenEventPass3 cenv env (md: ILEventDef) = - let eidx = AddUnsharedRow cenv TableNames.Event (GenEventAsEventRow cenv env md) - md.AddMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0008 - md.RemoveMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0010 - Option.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0020) md.FireMethod - List.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0004) md.OtherMethods - GenCustomAttrsPass3Or4 cenv (hca_Event, eidx) md.CustomAttrs - - -// -------------------------------------------------------------------- -// resource --> generate ... -// -------------------------------------------------------------------- - -let rec GetResourceAsManifestResourceRow cenv r = - let data, impl = - let embedManagedResources (bytes: ReadOnlyByteMemory) = - // Embedded managed resources must be word-aligned. However resource format is - // not specified in ECMA. Some mscorlib resources appear to be non-aligned - it seems it doesn't matter.. - let offset = cenv.resources.Position - let alignedOffset = (align 0x8 offset) - let pad = alignedOffset - offset - let resourceSize = bytes.Length - cenv.resources.EmitPadding pad - cenv.resources.EmitInt32 resourceSize - cenv.resources.EmitByteMemory bytes - Data (alignedOffset, true), (i_File, 0) - - match r.Location with - | ILResourceLocation.Local bytes -> embedManagedResources bytes - | ILResourceLocation.File (mref, offset) -> ULong offset, (i_File, GetModuleRefAsFileIdx cenv mref) - | ILResourceLocation.Assembly aref -> ULong 0x0, (i_AssemblyRef, GetAssemblyRefAsIdx cenv aref) - - UnsharedRow - [| data - ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02) - StringE (GetStringHeapIdx cenv r.Name) - Implementation (fst impl, snd impl) |] - -and GenResourcePass3 cenv r = - let idx = AddUnsharedRow cenv TableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r) - GenCustomAttrsPass3Or4 cenv (hca_ManifestResource, idx) r.CustomAttrs - -// -------------------------------------------------------------------- -// ILTypeDef --> generate ILFieldDef, ILMethodDef, ILPropertyDef etc. rows -// -------------------------------------------------------------------- - -let rec GenTypeDefPass3 enc cenv (td: ILTypeDef) = - try - let env = envForTypeDef td - let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) - td.Properties.AsList |> List.iter (GenPropertyPass3 cenv env) - td.Events.AsList |> List.iter (GenEventPass3 cenv env) - td.Fields.AsList |> List.iter (GenFieldDefPass3 cenv env) - td.Methods |> Seq.iter (GenMethodDefPass3 cenv env) - td.MethodImpls.AsList |> List.iter (GenMethodImplPass3 cenv env td.GenericParams.Length tidx) - // ClassLayout entry if needed - match td.Layout with - | ILTypeDefLayout.Auto -> () - | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> - if Option.isSome layout.Pack || Option.isSome layout.Size then - AddUnsharedRow cenv TableNames.ClassLayout - (UnsharedRow - [| UShort (defaultArg layout.Pack (uint16 0x0)) - ULong (defaultArg layout.Size 0x0) - SimpleIndex (TableNames.TypeDef, tidx) |]) |> ignore - - td.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_TypeDef, tidx) - td.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_TypeDef, tidx) - td.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_TypeDef, tidx) gp) - td.NestedTypes.AsList |> GenTypeDefsPass3 (enc@[td.Name]) cenv - with e -> - failwith ("Error in pass3 for type "+td.Name+", error: "+e.Message) - reraise() - raise e - -and GenTypeDefsPass3 enc cenv tds = - List.iter (GenTypeDefPass3 enc cenv) tds - -/// ILTypeDef --> generate generic params on ILMethodDef: ensures -/// GenericParam table is built sorted by owner. - -let rec GenTypeDefPass4 enc cenv (td: ILTypeDef) = - try - let env = envForTypeDef td - let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) - td.Methods |> Seq.iter (GenMethodDefPass4 cenv env) - List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_TypeDef, tidx) gp) td.GenericParams - GenTypeDefsPass4 (enc@[td.Name]) cenv td.NestedTypes.AsList - with e -> - failwith ("Error in pass4 for type "+td.Name+", error: "+e.Message) - reraise() - raise e - -and GenTypeDefsPass4 enc cenv tds = - List.iter (GenTypeDefPass4 enc cenv) tds - - -let timestamp = absilWriteGetTimeStamp () - -// -------------------------------------------------------------------- -// ILExportedTypesAndForwarders --> ILExportedTypeOrForwarder table -// -------------------------------------------------------------------- - -let rec GenNestedExportedTypePass3 cenv cidx (ce: ILNestedExportedType) = - let flags = GetMemberAccessFlags ce.Access - let nidx = - AddUnsharedRow cenv TableNames.ExportedType - (UnsharedRow - [| ULong flags - ULong 0x0 - StringE (GetStringHeapIdx cenv ce.Name) - StringE 0 - Implementation (i_ExportedType, cidx) |]) - GenCustomAttrsPass3Or4 cenv (hca_ExportedType, nidx) ce.CustomAttrs - GenNestedExportedTypesPass3 cenv nidx ce.Nested - -and GenNestedExportedTypesPass3 cenv nidx (nce: ILNestedExportedTypes) = - nce.AsList |> List.iter (GenNestedExportedTypePass3 cenv nidx) - -and GenExportedTypePass3 cenv (ce: ILExportedTypeOrForwarder) = - let nselem, nelem = GetTypeNameAsElemPair cenv ce.Name - let flags = int32 ce.Attributes - let impl = GetScopeRefAsImplementationElem cenv ce.ScopeRef - let cidx = - AddUnsharedRow cenv TableNames.ExportedType - (UnsharedRow - [| ULong flags - ULong 0x0 - nelem - nselem - Implementation (fst impl, snd impl) |]) - GenCustomAttrsPass3Or4 cenv (hca_ExportedType, cidx) ce.CustomAttrs - GenNestedExportedTypesPass3 cenv cidx ce.Nested - -and GenExportedTypesPass3 cenv (ce: ILExportedTypesAndForwarders) = - List.iter (GenExportedTypePass3 cenv) ce.AsList - -// -------------------------------------------------------------------- -// manifest --> generate Assembly row -// -------------------------------------------------------------------- - -and GetManifestAsAssemblyRow cenv m = - UnsharedRow - [|ULong m.AuxModuleHashAlgorithm - UShort (match m.Version with None -> 0us | Some version -> version.Major) - UShort (match m.Version with None -> 0us | Some version -> version.Minor) - UShort (match m.Version with None -> 0us | Some version -> version.Build) - UShort (match m.Version with None -> 0us | Some version -> version.Revision) - ULong - ( (match m.AssemblyLongevity with - | ILAssemblyLongevity.Unspecified -> 0x0000 - | ILAssemblyLongevity.Library -> 0x0002 - | ILAssemblyLongevity.PlatformAppDomain -> 0x0004 - | ILAssemblyLongevity.PlatformProcess -> 0x0006 - | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| - (if m.Retargetable then 0x100 else 0x0) ||| - // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. - // Any debugging customAttributes will automatically propagate - // REVIEW: No longer appears to be the case - (if m.JitTracking then 0x8000 else 0x0) ||| - (match m.PublicKey with None -> 0x0000 | Some _ -> 0x0001) ||| 0x0000) - (match m.PublicKey with None -> Blob 0 | Some x -> Blob (GetBytesAsBlobIdx cenv x)) - StringE (GetStringHeapIdx cenv m.Name) - (match m.Locale with None -> StringE 0 | Some x -> StringE (GetStringHeapIdx cenv x)) |] - -and GenManifestPass3 cenv m = - let aidx = AddUnsharedRow cenv TableNames.Assembly (GetManifestAsAssemblyRow cenv m) - GenSecurityDeclsPass3 cenv (hds_Assembly, aidx) m.SecurityDecls.AsList - GenCustomAttrsPass3Or4 cenv (hca_Assembly, aidx) m.CustomAttrs - GenExportedTypesPass3 cenv m.ExportedTypes - // Record the entrypoint decl if needed. - match m.EntrypointElsewhere with - | Some mref -> - if cenv.entrypoint <> None then failwith "duplicate entrypoint" - else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) - | None -> () - -and newGuid (modul: ILModuleDef) = - let n = timestamp - let m = hash n - let m2 = hash modul.Name - [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] - -and deterministicGuid (modul: ILModuleDef) = - let n = 16909060 - let m2 = Seq.sum (Seq.mapi (fun i x -> i + int x) modul.Name) // use a stable hash - [| b0 n; b1 n; b2 n; b3 n; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] - -and GetModuleAsRow (cenv: cenv) (modul: ILModuleDef) = - // Store the generated MVID in the environment (needed for generating debug information) - let modulGuid = if cenv.deterministic then deterministicGuid modul else newGuid modul - cenv.moduleGuid <- modulGuid - UnsharedRow - [| UShort (uint16 0x0) - StringE (GetStringHeapIdx cenv modul.Name) - Guid (GetGuidIdx cenv modulGuid) - Guid 0 - Guid 0 |] - - -let rowElemCompare (e1: RowElement) (e2: RowElement) = - let c = compare e1.Val e2.Val - if c <> 0 then c else - compare e1.Tag e2.Tag - -let TableRequiresSorting tab = - List.memAssoc tab sortedTableInfo - -let SortTableRows tab (rows: GenericRow[]) = - assert (TableRequiresSorting tab) - let col = List.assoc tab sortedTableInfo - rows - // This needs to be a stable sort, so we use List.sortWith - |> Array.toList - |> List.sortWith (fun r1 r2 -> rowElemCompare r1.[col] r2.[col]) - |> Array.ofList - //|> Array.map SharedRow - -let GenModule (cenv : cenv) (modul: ILModuleDef) = - let midx = AddUnsharedRow cenv TableNames.Module (GetModuleAsRow cenv modul) - List.iter (GenResourcePass3 cenv) modul.Resources.AsList - let tds = destTypeDefsWithGlobalFunctionsFirst cenv.ilg modul.TypeDefs - reportTime cenv.showTimes "Module Generation Preparation" - GenTypeDefsPass1 [] cenv tds - reportTime cenv.showTimes "Module Generation Pass 1" - GenTypeDefsPass2 0 [] cenv tds - reportTime cenv.showTimes "Module Generation Pass 2" - (match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m) - GenTypeDefsPass3 [] cenv tds - reportTime cenv.showTimes "Module Generation Pass 3" - GenCustomAttrsPass3Or4 cenv (hca_Module, midx) modul.CustomAttrs - // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes). - // Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params. - // Note this mutates the rows in a table. 'SetRowsOfTable' clears - // the key --> index map since it is no longer valid - cenv.GetTable(TableNames.GenericParam).SetRowsOfSharedTable (SortTableRows TableNames.GenericParam (cenv.GetTable(TableNames.GenericParam).GenericRowsOfTable)) - GenTypeDefsPass4 [] cenv tds - reportTime cenv.showTimes "Module Generation Pass 4" - -let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : ILGlobals, emitTailcalls, deterministic, showTimes) (m : ILModuleDef) cilStartAddress normalizeAssemblyRefs = - let isDll = m.IsDLL - - let cenv = - { emitTailcalls=emitTailcalls - deterministic = deterministic - showTimes=showTimes - ilg = ilg - desiredMetadataVersion=desiredMetadataVersion - requiredDataFixups= requiredDataFixups - requiredStringFixups = [] - codeChunks=ByteBuffer.Create 40000 - nextCodeAddr = cilStartAddress - data = ByteBuffer.Create 200 - resources = ByteBuffer.Create 200 - tables= - Array.init 64 (fun i -> - if (i = TableNames.AssemblyRef.Index || - i = TableNames.MemberRef.Index || - i = TableNames.ModuleRef.Index || - i = TableNames.File.Index || - i = TableNames.TypeRef.Index || - i = TableNames.TypeSpec.Index || - i = TableNames.MethodSpec.Index || - i = TableNames.StandAloneSig.Index || - i = TableNames.GenericParam.Index) then - MetadataTable.Shared (MetadataTable.New ("row table "+string i, EqualityComparer.Default)) - else - MetadataTable.Unshared (MetadataTable.New ("row table "+string i, EqualityComparer.Default))) - - AssemblyRefs = MetadataTable<_>.New("ILAssemblyRef", EqualityComparer.Default) - documents=MetadataTable<_>.New("pdbdocs", EqualityComparer.Default) - trefCache=new Dictionary<_, _>(100) - pdbinfo= new ResizeArray<_>(200) - moduleGuid= Array.zeroCreate 16 - fieldDefs= MetadataTable<_>.New("field defs", EqualityComparer.Default) - methodDefIdxsByKey = MetadataTable<_>.New("method defs", EqualityComparer.Default) - // This uses reference identity on ILMethodDef objects - methodDefIdxs = new Dictionary<_, _>(100, HashIdentity.Reference) - propertyDefs = MetadataTable<_>.New("property defs", EqualityComparer.Default) - eventDefs = MetadataTable<_>.New("event defs", EqualityComparer.Default) - typeDefs = MetadataTable<_>.New("type defs", EqualityComparer.Default) - entrypoint=None - generatePdb=generatePdb - // These must use structural comparison since they are keyed by arrays - guids=MetadataTable<_>.New("guids", HashIdentity.Structural) - blobs= MetadataTable<_>.New("blobs", HashIdentity.Structural) - strings= MetadataTable<_>.New("strings", EqualityComparer.Default) - userStrings= MetadataTable<_>.New("user strings", EqualityComparer.Default) - normalizeAssemblyRefs = normalizeAssemblyRefs } - - // Now the main compilation step - GenModule cenv m - - // .exe files have a .entrypoint instruction. Do not write it to the entrypoint when writing dll. - let entryPointToken = - match cenv.entrypoint with - | Some (epHere, tok) -> - if isDll then 0x0 - else getUncodedToken (if epHere then TableNames.Method else TableNames.File) tok - | None -> - if not isDll then dprintn "warning: no entrypoint specified in executable binary" - 0x0 - - let pdbData = - { EntryPoint= (if isDll then None else Some entryPointToken) - Timestamp = timestamp - ModuleID = cenv.moduleGuid - Documents = cenv.documents.EntriesAsArray - Methods = cenv.pdbinfo.ToArray() - TableRowCounts = cenv.tables |> Seq.map(fun t -> t.Count) |> Seq.toArray } - - let idxForNextedTypeDef (tds: ILTypeDef list, td: ILTypeDef) = - let enc = tds |> List.map (fun td -> td.Name) - GetIdxForTypeDef cenv (TdKey(enc, td.Name)) - - let strings = Array.map Bytes.stringAsUtf8NullTerminated cenv.strings.EntriesAsArray - let userStrings = cenv.userStrings.EntriesAsArray |> Array.map System.Text.Encoding.Unicode.GetBytes - let blobs = cenv.blobs.EntriesAsArray - let guids = cenv.guids.EntriesAsArray - let tables = cenv.tables - let code = cenv.GetCode() - // turn idx tbls into token maps - let mappings = - { TypeDefTokenMap = (fun t -> - getUncodedToken TableNames.TypeDef (idxForNextedTypeDef t)) - FieldDefTokenMap = (fun t fd -> - let tidx = idxForNextedTypeDef t - getUncodedToken TableNames.Field (GetFieldDefAsFieldDefIdx cenv tidx fd)) - MethodDefTokenMap = (fun t md -> - let tidx = idxForNextedTypeDef t - getUncodedToken TableNames.Method (FindMethodDefIdx cenv (GetKeyForMethodDef tidx md))) - PropertyTokenMap = (fun t pd -> - let tidx = idxForNextedTypeDef t - getUncodedToken TableNames.Property (cenv.propertyDefs.GetTableEntry (GetKeyForPropertyDef tidx pd))) - EventTokenMap = (fun t ed -> - let tidx = idxForNextedTypeDef t - getUncodedToken TableNames.Event (cenv.eventDefs.GetTableEntry (EventKey (tidx, ed.Name)))) } - reportTime cenv.showTimes "Finalize Module Generation Results" - // New return the results - let data = cenv.data.Close() - let resources = cenv.resources.Close() - (strings, userStrings, blobs, guids, tables, entryPointToken, code, cenv.requiredStringFixups, data, resources, pdbData, mappings) - - -//===================================================================== -// TABLES+BLOBS --> PHYSICAL METADATA+BLOBS -//===================================================================== -let chunk sz next = ({addr=next; size=sz}, next + sz) -let emptychunk next = ({addr=next; size=0}, next) -let nochunk next = ({addr= 0x0;size= 0x0; }, next) - -let count f arr = - Array.fold (fun x y -> x + f y) 0x0 arr - -module FileSystemUtilities = - open System - open System.Reflection - open System.Globalization - let progress = try System.Environment.GetEnvironmentVariable("FSharp_DebugSetFilePermissions") <> null with _ -> false - let setExecutablePermission (filename: string) = - -#if ENABLE_MONO_SUPPORT - if runningOnMono then - try - let monoPosix = Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756") - if progress then eprintf "loading type Mono.Unix.UnixFileInfo...\n" - let monoUnixFileInfo = monoPosix.GetType("Mono.Unix.UnixFileSystemInfo") - let fileEntry = monoUnixFileInfo.InvokeMember("GetFileSystemEntry", (BindingFlags.InvokeMethod ||| BindingFlags.Static ||| BindingFlags.Public), null, null, [| box filename |], CultureInfo.InvariantCulture) - let prevPermissions = monoUnixFileInfo.InvokeMember("get_FileAccessPermissions", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, fileEntry, [| |], CultureInfo.InvariantCulture) - let prevPermissionsValue = prevPermissions |> unbox - let newPermissionsValue = prevPermissionsValue ||| 0x000001ED - let newPermissions = Enum.ToObject(prevPermissions.GetType(), newPermissionsValue) - // Add 0x000001ED (UserReadWriteExecute, GroupReadExecute, OtherReadExecute) to the access permissions on Unix - monoUnixFileInfo.InvokeMember("set_FileAccessPermissions", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, fileEntry, [| newPermissions |], CultureInfo.InvariantCulture) |> ignore - with e -> - if progress then eprintf "failure: %s...\n" (e.ToString()) - // Fail silently - else -#else - ignore filename -#endif - () - -let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs = - - // When we know the real RVAs of the data section we fixup the references for the FieldRVA table. - // These references are stored as offsets into the metadata we return from this function - let requiredDataFixups = ref [] - - let next = cilStartAddress - - let strings, userStrings, blobs, guids, tables, entryPointToken, code, requiredStringFixups, data, resources, pdbData, mappings = - generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs - - reportTime showTimes "Generated Tables and Code" - let tableSize (tab: TableName) = tables.[tab.Index].Count - - // Now place the code - let codeSize = code.Length - let alignedCodeSize = align 0x4 codeSize - let codep, next = chunk codeSize next - let codePadding = Array.create (alignedCodeSize - codeSize) 0x0uy - let _codePaddingChunk, next = chunk codePadding.Length next - - // Now layout the chunks of metadata and IL - let metadataHeaderStartChunk, _next = chunk 0x10 next - - let numStreams = 0x05 - - let (mdtableVersionMajor, mdtableVersionMinor) = metadataSchemaVersionSupportedByCLRVersion desiredMetadataVersion - - let version = - System.Text.Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" desiredMetadataVersion.Major desiredMetadataVersion.Minor desiredMetadataVersion.Build) - - - let paddedVersionLength = align 0x4 (Array.length version) - - // Most addresses after this point are measured from the MD root - // Switch to md-rooted addresses - let next = metadataHeaderStartChunk.size - let _metadataHeaderVersionChunk, next = chunk paddedVersionLength next - let _metadataHeaderEndChunk, next = chunk 0x04 next - let _tablesStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#~".Length + 0x01))) next - let _stringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Strings".Length + 0x01))) next - let _userStringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#US".Length + 0x01))) next - let _guidsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#GUID".Length + 0x01))) next - let _blobsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Blob".Length + 0x01))) next - - let tablesStreamStart = next - - let stringsStreamUnpaddedSize = count (fun (s: byte[]) -> s.Length) strings + 1 - let stringsStreamPaddedSize = align 4 stringsStreamUnpaddedSize - - let userStringsStreamUnpaddedSize = count (fun (s: byte[]) -> let n = s.Length + 1 in n + ByteBuffer.Z32Size n) userStrings + 1 - let userStringsStreamPaddedSize = align 4 userStringsStreamUnpaddedSize - - let guidsStreamUnpaddedSize = (Array.length guids) * 0x10 - let guidsStreamPaddedSize = align 4 guidsStreamUnpaddedSize - - let blobsStreamUnpaddedSize = count (fun (blob: byte[]) -> let n = blob.Length in n + ByteBuffer.Z32Size n) blobs + 1 - let blobsStreamPaddedSize = align 4 blobsStreamUnpaddedSize - - let guidsBig = guidsStreamPaddedSize >= 0x10000 - let stringsBig = stringsStreamPaddedSize >= 0x10000 - let blobsBig = blobsStreamPaddedSize >= 0x10000 - - // 64bit bitvector indicating which tables are in the metadata. - let (valid1, valid2), _ = - (((0, 0), 0), tables) ||> Array.fold (fun ((valid1, valid2) as valid, n) rows -> - let valid = - if rows.Count = 0 then valid else - ( (if n < 32 then valid1 ||| (1 <<< n ) else valid1), - (if n >= 32 then valid2 ||| (1 <<< (n-32)) else valid2) ) - (valid, n+1)) - - // 64bit bitvector indicating which tables are sorted. - // Constant - REVIEW: make symbolic! compute from sorted table info! - let sorted1 = 0x3301fa00 - let sorted2 = - // If there are any generic parameters in the binary we're emitting then mark that - // table as sorted, otherwise don't. This maximizes the number of assemblies we emit - // which have an ECMA-v.1. compliant set of sorted tables. - (if tableSize TableNames.GenericParam > 0 then 0x00000400 else 0x00000000) ||| - (if tableSize TableNames.GenericParamConstraint > 0 then 0x00001000 else 0x00000000) ||| - 0x00000200 - - reportTime showTimes "Layout Header of Tables" - - let guidAddress n = (if n = 0 then 0 else (n - 1) * 0x10 + 0x01) - - let stringAddressTable = - let tab = Array.create (strings.Length + 1) 0 - let pos = ref 1 - for i = 1 to strings.Length do - tab.[i] <- !pos - let s = strings.[i - 1] - pos := !pos + s.Length - tab - - let stringAddress n = - if n >= Array.length stringAddressTable then failwith ("string index "+string n+" out of range") - stringAddressTable.[n] - - let userStringAddressTable = - let tab = Array.create (Array.length userStrings + 1) 0 - let pos = ref 1 - for i = 1 to Array.length userStrings do - tab.[i] <- !pos - let s = userStrings.[i - 1] - let n = s.Length + 1 - pos := !pos + n + ByteBuffer.Z32Size n - tab - - let userStringAddress n = - if n >= Array.length userStringAddressTable then failwith "userString index out of range" - userStringAddressTable.[n] - - let blobAddressTable = - let tab = Array.create (blobs.Length + 1) 0 - let pos = ref 1 - for i = 1 to blobs.Length do - tab.[i] <- !pos - let blob = blobs.[i - 1] - pos := !pos + blob.Length + ByteBuffer.Z32Size blob.Length - tab - - let blobAddress n = - if n >= blobAddressTable.Length then failwith "blob index out of range" - blobAddressTable.[n] - - reportTime showTimes "Build String/Blob Address Tables" - - let sortedTables = - Array.init 64 (fun i -> - let tab = tables.[i] - let tabName = TableName.FromIndex i - let rows = tab.GenericRowsOfTable - if TableRequiresSorting tabName then SortTableRows tabName rows else rows) - - reportTime showTimes "Sort Tables" - - let codedTables = - - let bignessTable = Array.map (fun rows -> Array.length rows >= 0x10000) sortedTables - let bigness (tab: int32) = bignessTable.[tab] - - let codedBigness nbits tab = - (tableSize tab) >= (0x10000 >>> nbits) - - let tdorBigness = - codedBigness 2 TableNames.TypeDef || - codedBigness 2 TableNames.TypeRef || - codedBigness 2 TableNames.TypeSpec - - let tomdBigness = - codedBigness 1 TableNames.TypeDef || - codedBigness 1 TableNames.Method - - let hcBigness = - codedBigness 2 TableNames.Field || - codedBigness 2 TableNames.Param || - codedBigness 2 TableNames.Property - - let hcaBigness = - codedBigness 5 TableNames.Method || - codedBigness 5 TableNames.Field || - codedBigness 5 TableNames.TypeRef || - codedBigness 5 TableNames.TypeDef || - codedBigness 5 TableNames.Param || - codedBigness 5 TableNames.InterfaceImpl || - codedBigness 5 TableNames.MemberRef || - codedBigness 5 TableNames.Module || - codedBigness 5 TableNames.Permission || - codedBigness 5 TableNames.Property || - codedBigness 5 TableNames.Event || - codedBigness 5 TableNames.StandAloneSig || - codedBigness 5 TableNames.ModuleRef || - codedBigness 5 TableNames.TypeSpec || - codedBigness 5 TableNames.Assembly || - codedBigness 5 TableNames.AssemblyRef || - codedBigness 5 TableNames.File || - codedBigness 5 TableNames.ExportedType || - codedBigness 5 TableNames.ManifestResource || - codedBigness 5 TableNames.GenericParam || - codedBigness 5 TableNames.GenericParamConstraint || - codedBigness 5 TableNames.MethodSpec - - - let hfmBigness = - codedBigness 1 TableNames.Field || - codedBigness 1 TableNames.Param - - let hdsBigness = - codedBigness 2 TableNames.TypeDef || - codedBigness 2 TableNames.Method || - codedBigness 2 TableNames.Assembly - - let mrpBigness = - codedBigness 3 TableNames.TypeRef || - codedBigness 3 TableNames.ModuleRef || - codedBigness 3 TableNames.Method || - codedBigness 3 TableNames.TypeSpec - - let hsBigness = - codedBigness 1 TableNames.Event || - codedBigness 1 TableNames.Property - - let mdorBigness = - codedBigness 1 TableNames.Method || - codedBigness 1 TableNames.MemberRef - - let mfBigness = - codedBigness 1 TableNames.Field || - codedBigness 1 TableNames.Method - - let iBigness = - codedBigness 2 TableNames.File || - codedBigness 2 TableNames.AssemblyRef || - codedBigness 2 TableNames.ExportedType - - let catBigness = - codedBigness 3 TableNames.Method || - codedBigness 3 TableNames.MemberRef - - let rsBigness = - codedBigness 2 TableNames.Module || - codedBigness 2 TableNames.ModuleRef || - codedBigness 2 TableNames.AssemblyRef || - codedBigness 2 TableNames.TypeRef - - let tablesBuf = ByteBuffer.Create 20000 - - // Now the coded tables themselves - first the schemata header - tablesBuf.EmitIntsAsBytes - [| 0x00; 0x00; 0x00; 0x00 - mdtableVersionMajor // major version of table schemata - mdtableVersionMinor // minor version of table schemata - - ((if stringsBig then 0x01 else 0x00) ||| // bit vector for heap size - (if guidsBig then 0x02 else 0x00) ||| - (if blobsBig then 0x04 else 0x00)) - 0x01 (* reserved, always 1 *) |] - - tablesBuf.EmitInt32 valid1 - tablesBuf.EmitInt32 valid2 - tablesBuf.EmitInt32 sorted1 - tablesBuf.EmitInt32 sorted2 - - // Numbers of rows in various tables - for rows in sortedTables do - if rows.Length <> 0 then - tablesBuf.EmitInt32 rows.Length - - - reportTime showTimes "Write Header of tablebuf" - - // The tables themselves - for rows in sortedTables do - for row in rows do - for x in row do - // Emit the coded token for the array element - let t = x.Tag - let n = x.Val - match t with - | _ when t = RowElementTags.UShort -> tablesBuf.EmitUInt16 (uint16 n) - | _ when t = RowElementTags.ULong -> tablesBuf.EmitInt32 n - | _ when t = RowElementTags.Data -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, false) - | _ when t = RowElementTags.DataResources -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, true) - | _ when t = RowElementTags.Guid -> tablesBuf.EmitZUntaggedIndex guidsBig (guidAddress n) - | _ when t = RowElementTags.Blob -> tablesBuf.EmitZUntaggedIndex blobsBig (blobAddress n) - | _ when t = RowElementTags.String -> tablesBuf.EmitZUntaggedIndex stringsBig (stringAddress n) - | _ when t <= RowElementTags.SimpleIndexMax -> tablesBuf.EmitZUntaggedIndex (bigness (t - RowElementTags.SimpleIndexMin)) n - | _ when t <= RowElementTags.TypeDefOrRefOrSpecMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeDefOrRefOrSpecMin) 2 tdorBigness n - | _ when t <= RowElementTags.TypeOrMethodDefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeOrMethodDefMin) 1 tomdBigness n - | _ when t <= RowElementTags.HasConstantMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasConstantMin) 2 hcBigness n - | _ when t <= RowElementTags.HasCustomAttributeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasCustomAttributeMin) 5 hcaBigness n - | _ when t <= RowElementTags.HasFieldMarshalMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasFieldMarshalMin) 1 hfmBigness n - | _ when t <= RowElementTags.HasDeclSecurityMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasDeclSecurityMin) 2 hdsBigness n - | _ when t <= RowElementTags.MemberRefParentMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberRefParentMin) 3 mrpBigness n - | _ when t <= RowElementTags.HasSemanticsMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasSemanticsMin) 1 hsBigness n - | _ when t <= RowElementTags.MethodDefOrRefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MethodDefOrRefMin) 1 mdorBigness n - | _ when t <= RowElementTags.MemberForwardedMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberForwardedMin) 1 mfBigness n - | _ when t <= RowElementTags.ImplementationMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ImplementationMin) 2 iBigness n - | _ when t <= RowElementTags.CustomAttributeTypeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.CustomAttributeTypeMin) 3 catBigness n - | _ when t <= RowElementTags.ResolutionScopeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ResolutionScopeMin) 2 rsBigness n - | _ -> failwith "invalid tag in row element" - - tablesBuf.Close() - - reportTime showTimes "Write Tables to tablebuf" - - let tablesStreamUnpaddedSize = codedTables.Length - // QUERY: extra 4 empty bytes in array.exe - why? Include some extra padding after - // the tables just in case there is a mistake in the ECMA spec. - let tablesStreamPaddedSize = align 4 (tablesStreamUnpaddedSize + 4) - let tablesChunk, next = chunk tablesStreamPaddedSize next - let tablesStreamPadding = tablesChunk.size - tablesStreamUnpaddedSize - - let stringsChunk, next = chunk stringsStreamPaddedSize next - let stringsStreamPadding = stringsChunk.size - stringsStreamUnpaddedSize - let userStringsChunk, next = chunk userStringsStreamPaddedSize next - let userStringsStreamPadding = userStringsChunk.size - userStringsStreamUnpaddedSize - let guidsChunk, next = chunk (0x10 * guids.Length) next - let blobsChunk, _next = chunk blobsStreamPaddedSize next - let blobsStreamPadding = blobsChunk.size - blobsStreamUnpaddedSize - - reportTime showTimes "Layout Metadata" - - let metadata, guidStart = - let mdbuf = ByteBuffer.Create 500000 - mdbuf.EmitIntsAsBytes - [| 0x42; 0x53; 0x4a; 0x42 // Magic signature - 0x01; 0x00 // Major version - 0x01; 0x00 // Minor version - |] - mdbuf.EmitInt32 0x0 // Reserved - - mdbuf.EmitInt32 paddedVersionLength - mdbuf.EmitBytes version - for i = 1 to (paddedVersionLength - Array.length version) do - mdbuf.EmitIntAsByte 0x00 - - mdbuf.EmitBytes - [| 0x00uy; 0x00uy // flags, reserved - b0 numStreams; b1 numStreams; |] - mdbuf.EmitInt32 tablesChunk.addr - mdbuf.EmitInt32 tablesChunk.size - mdbuf.EmitIntsAsBytes [| 0x23; 0x7e; 0x00; 0x00; (* #~00 *)|] - mdbuf.EmitInt32 stringsChunk.addr - mdbuf.EmitInt32 stringsChunk.size - mdbuf.EmitIntsAsBytes [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; 0x00; 0x00; 0x00; 0x00 (* "#Strings0000" *)|] - mdbuf.EmitInt32 userStringsChunk.addr - mdbuf.EmitInt32 userStringsChunk.size - mdbuf.EmitIntsAsBytes [| 0x23; 0x55; 0x53; 0x00; (* #US0*) |] - mdbuf.EmitInt32 guidsChunk.addr - mdbuf.EmitInt32 guidsChunk.size - mdbuf.EmitIntsAsBytes [| 0x23; 0x47; 0x55; 0x49; 0x44; 0x00; 0x00; 0x00; (* #GUID000 *)|] - mdbuf.EmitInt32 blobsChunk.addr - mdbuf.EmitInt32 blobsChunk.size - mdbuf.EmitIntsAsBytes [| 0x23; 0x42; 0x6c; 0x6f; 0x62; 0x00; 0x00; 0x00; (* #Blob000 *)|] - - reportTime showTimes "Write Metadata Header" - // Now the coded tables themselves - mdbuf.EmitBytes codedTables - for i = 1 to tablesStreamPadding do - mdbuf.EmitIntAsByte 0x00 - reportTime showTimes "Write Metadata Tables" - - // The string stream - mdbuf.EmitByte 0x00uy - for s in strings do - mdbuf.EmitBytes s - for i = 1 to stringsStreamPadding do - mdbuf.EmitIntAsByte 0x00 - reportTime showTimes "Write Metadata Strings" - // The user string stream - mdbuf.EmitByte 0x00uy - for s in userStrings do - mdbuf.EmitZ32 (s.Length + 1) - mdbuf.EmitBytes s - mdbuf.EmitIntAsByte (markerForUnicodeBytes s) - for i = 1 to userStringsStreamPadding do - mdbuf.EmitIntAsByte 0x00 - - reportTime showTimes "Write Metadata User Strings" - // The GUID stream - let guidStart = mdbuf.Position - Array.iter mdbuf.EmitBytes guids - - // The blob stream - mdbuf.EmitByte 0x00uy - for s in blobs do - mdbuf.EmitZ32 s.Length - mdbuf.EmitBytes s - for i = 1 to blobsStreamPadding do - mdbuf.EmitIntAsByte 0x00 - reportTime showTimes "Write Blob Stream" - // Done - close the buffer and return the result. - mdbuf.Close(), guidStart - - - // Now we know the user string tables etc. we can fixup the - // uses of strings in the code - for (codeStartAddr, l) in requiredStringFixups do - for (codeOffset, userStringIndex) in l do - if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then - failwith "strings-in-code fixup: a group of fixups is located outside the code array" - let locInCode = ((codeStartAddr + codeOffset) - codep.addr) - checkFixup32 code locInCode 0xdeadbeef - let token = getUncodedToken TableNames.UserStrings (userStringAddress userStringIndex) - if (Bytes.get code (locInCode-1) <> i_ldstr) then failwith "strings-in-code fixup: not at ldstr instruction!" - applyFixup32 code locInCode token - reportTime showTimes "Fixup Metadata" - - entryPointToken, code, codePadding, metadata, data, resources, !requiredDataFixups, pdbData, mappings, guidStart - -//--------------------------------------------------------------------- -// PHYSICAL METADATA+BLOBS --> PHYSICAL PE FORMAT -//--------------------------------------------------------------------- - -// THIS LAYS OUT A 2-SECTION .NET PE BINARY -// SECTIONS -// TEXT: physical 0x0200 --> RVA 0x00020000 -// e.g. raw size 0x9600, -// e.g. virt size 0x9584 -// RELOC: physical 0x9800 --> RVA 0x0000c000 -// i.e. physbase --> rvabase -// where physbase = textbase + text raw size -// phsrva = roundup(0x2000, 0x0002000 + text virt size) - -let msdosHeader : byte[] = - [| 0x4duy; 0x5auy; 0x90uy; 0x00uy; 0x03uy; 0x00uy; 0x00uy; 0x00uy - 0x04uy; 0x00uy; 0x00uy; 0x00uy; 0xFFuy; 0xFFuy; 0x00uy; 0x00uy - 0xb8uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy - 0x40uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy - 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy - 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy - 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy - 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy - 0x0euy; 0x1fuy; 0xbauy; 0x0euy; 0x00uy; 0xb4uy; 0x09uy; 0xcduy - 0x21uy; 0xb8uy; 0x01uy; 0x4cuy; 0xcduy; 0x21uy; 0x54uy; 0x68uy - 0x69uy; 0x73uy; 0x20uy; 0x70uy; 0x72uy; 0x6fuy; 0x67uy; 0x72uy - 0x61uy; 0x6duy; 0x20uy; 0x63uy; 0x61uy; 0x6euy; 0x6euy; 0x6fuy - 0x74uy; 0x20uy; 0x62uy; 0x65uy; 0x20uy; 0x72uy; 0x75uy; 0x6euy - 0x20uy; 0x69uy; 0x6euy; 0x20uy; 0x44uy; 0x4fuy; 0x53uy; 0x20uy - 0x6duy; 0x6fuy; 0x64uy; 0x65uy; 0x2euy; 0x0duy; 0x0duy; 0x0auy - 0x24uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] - -let writeInt64 (os: BinaryWriter) x = - os.Write (dw0 x) - os.Write (dw1 x) - os.Write (dw2 x) - os.Write (dw3 x) - os.Write (dw4 x) - os.Write (dw5 x) - os.Write (dw6 x) - os.Write (dw7 x) - -let writeInt32 (os: BinaryWriter) x = - os.Write (byte (b0 x)) - os.Write (byte (b1 x)) - os.Write (byte (b2 x)) - os.Write (byte (b3 x)) - -let writeInt32AsUInt16 (os: BinaryWriter) x = - os.Write (byte (b0 x)) - os.Write (byte (b1 x)) - -let writeDirectory os dict = - writeInt32 os (if dict.size = 0x0 then 0x0 else dict.addr) - writeInt32 os dict.size - -let writeBytes (os: BinaryWriter) (chunk: byte[]) = os.Write(chunk, 0, chunk.Length) - -let writeBinaryAndReportMappings (outfile, - ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, - embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, dumpDebugInfo, pathMap) - modul normalizeAssemblyRefs = - // Store the public key from the signer into the manifest. This means it will be written - // to the binary and also acts as an indicator to leave space for delay sign - - reportTime showTimes "Write Started" - let isDll = modul.IsDLL - - let signer = - match signer, modul.Manifest with - | Some _, _ -> signer - | _, None -> signer - | None, Some {PublicKey=Some pubkey} -> - (dprintn "Note: The output assembly will be delay-signed using the original public" - dprintn "Note: key. In order to load it you will need to either sign it with" - dprintn "Note: the original private key or to turn off strong-name verification" - dprintn "Note: (use sn.exe from the .NET Framework SDK to do this, e.g. 'sn -Vr *')." - dprintn "Note: Alternatively if this tool supports it you can provide the original" - dprintn "Note: private key when converting the assembly, assuming you have access to" - dprintn "Note: it." - Some (ILStrongNameSigner.OpenPublicKey pubkey)) - | _ -> signer - - let modul = - let pubkey = - match signer with - | None -> None - | Some s -> - try Some s.PublicKey - with e -> - failwith ("A call to StrongNameGetPublicKey failed ("+e.Message+")") - None - begin match modul.Manifest with - | None -> () - | Some m -> - if m.PublicKey <> None && m.PublicKey <> pubkey then - dprintn "Warning: The output assembly is being signed or delay-signed with a strong name that is different to the original." - end - { modul with Manifest = match modul.Manifest with None -> None | Some m -> Some {m with PublicKey = pubkey} } - - let os = - try - // Ensure the output directory exists otherwise it will fail - let dir = Path.GetDirectoryName outfile - if not (Directory.Exists dir) then Directory.CreateDirectory dir |>ignore - new BinaryWriter(FileSystem.FileStreamCreateShim outfile) - with e -> - failwith ("Could not open file for writing (binary mode): " + outfile) - - let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings = - try - - let imageBaseReal = modul.ImageBase // FIXED CHOICE - let alignVirt = modul.VirtualAlignment // FIXED CHOICE - let alignPhys = modul.PhysicalAlignment // FIXED CHOICE - - let isItanium = modul.Platform = Some IA64 - - let numSections = 3 // .text, .sdata, .reloc - - - // HEADERS - let next = 0x0 - let headerSectionPhysLoc = 0x0 - let headerAddr = next - let next = headerAddr - - let msdosHeaderSize = 0x80 - let msdosHeaderChunk, next = chunk msdosHeaderSize next - - let peSignatureSize = 0x04 - let peSignatureChunk, next = chunk peSignatureSize next - - let peFileHeaderSize = 0x14 - let peFileHeaderChunk, next = chunk peFileHeaderSize next - - let peOptionalHeaderSize = if modul.Is64Bit then 0xf0 else 0xe0 - let peOptionalHeaderChunk, next = chunk peOptionalHeaderSize next - - let textSectionHeaderSize = 0x28 - let textSectionHeaderChunk, next = chunk textSectionHeaderSize next - - let dataSectionHeaderSize = 0x28 - let dataSectionHeaderChunk, next = chunk dataSectionHeaderSize next - - let relocSectionHeaderSize = 0x28 - let relocSectionHeaderChunk, next = chunk relocSectionHeaderSize next - - let headerSize = next - headerAddr - let nextPhys = align alignPhys (headerSectionPhysLoc + headerSize) - let headerSectionPhysSize = nextPhys - headerSectionPhysLoc - let next = align alignVirt (headerAddr + headerSize) - - // TEXT SECTION: 8 bytes IAT table 72 bytes CLI header - - let textSectionPhysLoc = nextPhys - let textSectionAddr = next - let next = textSectionAddr - - let importAddrTableChunk, next = chunk 0x08 next - let cliHeaderPadding = (if isItanium then (align 16 next) else next) - next - let next = next + cliHeaderPadding - let cliHeaderChunk, next = chunk 0x48 next - - let desiredMetadataVersion = - if modul.MetadataVersion <> "" then - parseILVersion modul.MetadataVersion - else - match ilg.primaryAssemblyScopeRef with - | ILScopeRef.Local -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Local" - | ILScopeRef.Module(_) -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module" - | ILScopeRef.PrimaryAssembly -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.PrimaryAssembly" - | ILScopeRef.Assembly aref -> - match aref.Version with - | Some version when version.Major = 2us -> parseILVersion "2.0.50727.0" - | Some v -> v - | None -> failwith "Expected mscorlib to have a version number" - - let entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups, pdbData, mappings, guidStart = - writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul next normalizeAssemblyRefs - - reportTime showTimes "Generated IL and metadata" - let _codeChunk, next = chunk code.Length next - let _codePaddingChunk, next = chunk codePadding.Length next - - let metadataChunk, next = chunk metadata.Length next - - let strongnameChunk, next = - match signer with - | None -> nochunk next - | Some s -> chunk s.SignatureSize next - - let resourcesChunk, next = chunk resources.Length next - - let rawdataChunk, next = chunk data.Length next - - let vtfixupsChunk, next = nochunk next // Note: only needed for mixed mode assemblies - let importTableChunkPrePadding = (if isItanium then (align 16 next) else next) - next - let next = next + importTableChunkPrePadding - let importTableChunk, next = chunk 0x28 next - let importLookupTableChunk, next = chunk 0x14 next - let importNameHintTableChunk, next = chunk 0x0e next - let mscoreeStringChunk, next = chunk 0x0c next - - let next = align 0x10 (next + 0x05) - 0x05 - let importTableChunk = { addr=importTableChunk.addr; size = next - importTableChunk.addr} - let importTableChunkPadding = importTableChunk.size - (0x28 + 0x14 + 0x0e + 0x0c) - - let next = next + 0x03 - let entrypointCodeChunk, next = chunk 0x06 next - let globalpointerCodeChunk, next = chunk (if isItanium then 0x8 else 0x0) next - - let pdbOpt = - match portablePDB with - | true -> - let (uncompressedLength, contentId, stream, algorithmName, checkSum) as pdbStream = - generatePortablePdb embedAllSource embedSourceList sourceLink checksumAlgorithm showTimes pdbData pathMap - - if embeddedPDB then - let uncompressedLength, contentId, stream = compressPortablePdbStream uncompressedLength contentId stream - Some (uncompressedLength, contentId, stream, algorithmName, checkSum) - else Some pdbStream - - | _ -> None - - let debugDirectoryChunk, next = - chunk (if pdbfile = None then - 0x0 - else - sizeof_IMAGE_DEBUG_DIRECTORY * 2 + - (if embeddedPDB then sizeof_IMAGE_DEBUG_DIRECTORY else 0) + - (if deterministic then sizeof_IMAGE_DEBUG_DIRECTORY else 0) - ) next - - // The debug data is given to us by the PDB writer and appears to - // typically be the type of the data plus the PDB file name. We fill - // this in after we've written the binary. We approximate the size according - // to what PDB writers seem to require and leave extra space just in case... - let debugDataJustInCase = 40 - let debugDataChunk, next = - chunk (align 0x4 (match pdbfile with - | None -> 0 - | Some f -> (24 - + System.Text.Encoding.Unicode.GetByteCount f // See bug 748444 - + debugDataJustInCase))) next - - let debugChecksumPdbChunk, next = - chunk (align 0x4 (match pdbOpt with - | Some (_, _, _, algorithmName, checkSum) -> - let alg = System.Text.Encoding.UTF8.GetBytes(algorithmName) - let size = alg.Length + 1 + checkSum.Length - size - | None -> 0)) next - - let debugEmbeddedPdbChunk, next = - if embeddedPDB then - let streamLength = - match pdbOpt with - | Some (_, _, stream, _, _) -> int stream.Length - | None -> 0 - chunk (align 0x4 (match embeddedPDB with - | true -> 8 + streamLength - | _ -> 0 )) next - else - nochunk next - - let debugDeterministicPdbChunk, next = - if deterministic then emptychunk next - else nochunk next - - - let textSectionSize = next - textSectionAddr - let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) - let textSectionPhysSize = nextPhys - textSectionPhysLoc - let next = align alignVirt (textSectionAddr + textSectionSize) - - // .RSRC SECTION (DATA) - let dataSectionPhysLoc = nextPhys - let dataSectionAddr = next - let dataSectionVirtToPhys v = v - dataSectionAddr + dataSectionPhysLoc - let nativeResources = - match modul.NativeResources with - | [] -> [||] - | resources -> - let unlinkedResources = - resources |> List.map (function - | ILNativeResource.Out bytes -> bytes - | ILNativeResource.In (fileName, linkedResourceBase, start, len) -> - let linkedResource = File.ReadBinaryChunk (fileName, start, len) - unlinkResource linkedResourceBase linkedResource) - - begin - try linkNativeResources unlinkedResources next - with e -> failwith ("Linking a native resource failed: "+e.Message+"") - end - - let nativeResourcesSize = nativeResources.Length - - let nativeResourcesChunk, next = chunk nativeResourcesSize next - - let dummydatap, next = chunk (if next = dataSectionAddr then 0x01 else 0x0) next - - let dataSectionSize = next - dataSectionAddr - let nextPhys = align alignPhys (dataSectionPhysLoc + dataSectionSize) - let dataSectionPhysSize = nextPhys - dataSectionPhysLoc - let next = align alignVirt (dataSectionAddr + dataSectionSize) - - // .RELOC SECTION base reloc table: 0x0c size - let relocSectionPhysLoc = nextPhys - let relocSectionAddr = next - let baseRelocTableChunk, next = chunk 0x0c next - - let relocSectionSize = next - relocSectionAddr - let nextPhys = align alignPhys (relocSectionPhysLoc + relocSectionSize) - let relocSectionPhysSize = nextPhys - relocSectionPhysLoc - let next = align alignVirt (relocSectionAddr + relocSectionSize) - - // Now we know where the data section lies we can fix up the - // references into the data section from the metadata tables. - begin - requiredDataFixups |> List.iter - (fun (metadataOffset32, (dataOffset, kind)) -> - let metadataOffset = metadataOffset32 - if metadataOffset < 0 || metadataOffset >= metadata.Length - 4 then failwith "data RVA fixup: fixup located outside metadata" - checkFixup32 metadata metadataOffset 0xdeaddddd - let dataRva = - if kind then - let res = dataOffset - if res >= resourcesChunk.size then dprintn ("resource offset bigger than resource data section") - res - else - let res = rawdataChunk.addr + dataOffset - if res < rawdataChunk.addr then dprintn ("data rva before data section") - if res >= rawdataChunk.addr + rawdataChunk.size then - dprintn ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr - + ", rawdataChunk.size = "+string rawdataChunk.size) - res - applyFixup32 metadata metadataOffset dataRva) - end - - // IMAGE TOTAL SIZE - let imageEndSectionPhysLoc = nextPhys - let imageEndAddr = next - - reportTime showTimes "Layout image" - - let write p (os: BinaryWriter) chunkName chunk = - match p with - | None -> () - | Some pExpected -> - os.Flush() - let pCurrent = int32 os.BaseStream.Position - if pCurrent <> pExpected then - failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected) - writeBytes os chunk - - let writePadding (os: BinaryWriter) _comment sz = - if sz < 0 then failwith "writePadding: size < 0" - for i = 0 to sz - 1 do - os.Write 0uy - - // Now we've computed all the offsets, write the image - - write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader - - write (Some peSignatureChunk.addr) os "pe signature" [| |] - - writeInt32 os 0x4550 - - write (Some peFileHeaderChunk.addr) os "pe file header" [| |] - - if (modul.Platform = Some AMD64) then - writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64 - elif isItanium then - writeInt32AsUInt16 os 0x200 - else - writeInt32AsUInt16 os 0x014c // Machine - IMAGE_FILE_MACHINE_I386 - - writeInt32AsUInt16 os numSections - - let pdbData = - // Hash code, data and metadata - if deterministic then - use sha = - match checksumAlgorithm with - | HashAlgorithm.Sha1 -> System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm - | HashAlgorithm.Sha256 -> System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm - - let hCode = sha.ComputeHash code - let hData = sha.ComputeHash data - let hMeta = sha.ComputeHash metadata - let final = [| hCode; hData; hMeta |] |> Array.collect id |> sha.ComputeHash - - // Confirm we have found the correct data and aren't corrupting the metadata - if metadata.[ guidStart..guidStart+3] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" - if metadata.[ guidStart+12..guidStart+15] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" - - // Update MVID guid in metadata - Array.blit final 0 metadata guidStart 16 - - // Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused - let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24) - writeInt32 os timestamp - - // Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID - // Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-deterministic Windows native code - { pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp } - else - writeInt32 os timestamp // date since 1970 - pdbData - - writeInt32 os 0x00 // Pointer to Symbol Table Always 0 - // 00000090 - writeInt32 os 0x00 // Number of Symbols Always 0 - writeInt32AsUInt16 os peOptionalHeaderSize // Size of the optional header, the format is described below. - - // 64bit: IMAGE_FILE_32BIT_MACHINE ||| IMAGE_FILE_LARGE_ADDRESS_AWARE - // 32bit: IMAGE_FILE_32BIT_MACHINE - // Yes, 32BIT_MACHINE is set for AMD64... - let iMachineCharacteristic = match modul.Platform with | Some IA64 -> 0x20 | Some AMD64 -> 0x0120 | _ -> 0x0100 - - writeInt32AsUInt16 os ((if isDll then 0x2000 else 0x0000) ||| 0x0002 ||| 0x0004 ||| 0x0008 ||| iMachineCharacteristic) - - // Now comes optional header - - let peOptionalHeaderByte = peOptionalHeaderByteByCLRVersion desiredMetadataVersion - - write (Some peOptionalHeaderChunk.addr) os "pe optional header" [| |] - if modul.Is64Bit then - writeInt32AsUInt16 os 0x020B // Magic number is 0x020B for 64-bit - else - writeInt32AsUInt16 os 0x010b // Always 0x10B (see Section 23.1). - writeInt32AsUInt16 os peOptionalHeaderByte // ECMA spec says 6, some binaries, e.g. fscmanaged.exe say 7, Whidbey binaries say 8 - writeInt32 os textSectionPhysSize // Size of the code (text) section, or the sum of all code sections if there are multiple sections. - // 000000a0 - writeInt32 os dataSectionPhysSize // Size of the initialized data section - writeInt32 os 0x00 // Size of the uninitialized data section - writeInt32 os entrypointCodeChunk.addr // RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 - writeInt32 os textSectionAddr // e.g. 0x0002000 - // 000000b0 - if modul.Is64Bit then - writeInt64 os ((int64)imageBaseReal) // REVIEW: For 64-bit, we should use a 64-bit image base - else - writeInt32 os dataSectionAddr // e.g. 0x0000c000 - writeInt32 os imageBaseReal // Image Base Always 0x400000 (see Section 23.1). - QUERY : no it's not always 0x400000, e.g. 0x034f0000 - - writeInt32 os alignVirt // Section Alignment Always 0x2000 (see Section 23.1). - writeInt32 os alignPhys // File Alignment Either 0x200 or 0x1000. - // 000000c0 - writeInt32AsUInt16 os 0x04 // OS Major Always 4 (see Section 23.1). - writeInt32AsUInt16 os 0x00 // OS Minor Always 0 (see Section 23.1). - writeInt32AsUInt16 os 0x00 // User Major Always 0 (see Section 23.1). - writeInt32AsUInt16 os 0x00 // User Minor Always 0 (see Section 23.1). - do - let (major, minor) = modul.SubsystemVersion - writeInt32AsUInt16 os major - writeInt32AsUInt16 os minor - writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). - // 000000d0 - writeInt32 os imageEndAddr // Image Size: Size, in bytes, of image, including all headers and padding - writeInt32 os headerSectionPhysSize // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding - writeInt32 os 0x00 // File Checksum Always 0 (see Section 23.1). QUERY: NOT ALWAYS ZERO - writeInt32AsUInt16 os modul.SubSystemFlags // SubSystem Subsystem required to run this image. - // DLL Flags Always 0x400 (no unmanaged windows exception handling - see Section 23.1). - // Itanium: see notes at end of file - // IMAGE_DLLCHARACTERISTICS_NX_COMPAT: See FSharp 1.0 bug 5019 and http://blogs.msdn.com/ed_maurer/archive/2007/12/14/nxcompat-and-the-c-compiler.aspx - // Itanium : IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE | IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT - // x86 : IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT - // x64 : IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT - let dllCharacteristics = - let flags = - if modul.Is64Bit then (if isItanium then 0x8540 else 0x540) - else 0x540 - if modul.UseHighEntropyVA then flags ||| 0x20 // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA - else flags - writeInt32AsUInt16 os dllCharacteristics - // 000000e0 - // Note that the defaults differ between x86 and x64 - if modul.Is64Bit then - let size = defaultArg modul.StackReserveSize 0x400000 |> int64 - writeInt64 os size // Stack Reserve Size Always 0x400000 (4Mb) (see Section 23.1). - writeInt64 os 0x4000L // Stack Commit Size Always 0x4000 (16Kb) (see Section 23.1). - writeInt64 os 0x100000L // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). - writeInt64 os 0x2000L // Heap Commit Size Always 0x800 (8Kb) (see Section 23.1). - else - let size = defaultArg modul.StackReserveSize 0x100000 - writeInt32 os size // Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). - writeInt32 os 0x1000 // Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). - writeInt32 os 0x100000 // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). - writeInt32 os 0x1000 // Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). - // 000000f0 - x86 location, moving on, for x64, add 0x10 - writeInt32 os 0x00 // Loader Flags Always 0 (see Section 23.1) - writeInt32 os 0x10 // Number of Data Directories: Always 0x10 (see Section 23.1). - writeInt32 os 0x00 - writeInt32 os 0x00 // Export Table Always 0 (see Section 23.1). - // 00000100 - writeDirectory os importTableChunk // Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 - // Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not. - writeDirectory os nativeResourcesChunk - - // 00000110 - writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). - // 00000120 - writeDirectory os baseRelocTableChunk - writeDirectory os debugDirectoryChunk // Debug Directory - // 00000130 - writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). - writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). - writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). - writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). - // 00000140 - writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). - writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). - // 00000150 - writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). - writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). - writeDirectory os importAddrTableChunk // Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 - // 00000160 - writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). - writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). - writeDirectory os cliHeaderChunk - // 00000170 - writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). - writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). - - write (Some textSectionHeaderChunk.addr) os "text section header" [| |] - - // 00000178 - writeBytes os [| 0x2euy; 0x74uy; 0x65uy; 0x78uy; 0x74uy; 0x00uy; 0x00uy; 0x00uy; |] // ".text\000\000\000" - // 00000180 - writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. - writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section - writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes - writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file. - // 00000190 - writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. - writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). - // 00000198 - writeInt32AsUInt16 os 0x00// NumberOfRelocations Number of relocations, set to 0 if unused. - writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). - writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ - - write (Some dataSectionHeaderChunk.addr) os "data section header" [| |] - - // 000001a0 - writeBytes os [| 0x2euy; 0x72uy; 0x73uy; 0x72uy; 0x63uy; 0x00uy; 0x00uy; 0x00uy; |] // ".rsrc\000\000\000" - // writeBytes os [| 0x2e; 0x73; 0x64; 0x61; 0x74; 0x61; 0x00; 0x00; |] // ".sdata\000\000" - writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. - writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section. - // 000001b0 - writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, - writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. - // 000001b8 - writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. - writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). - // 000001c0 - writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. - writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). - writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x40uy |] // Characteristics Flags: IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA - - write (Some relocSectionHeaderChunk.addr) os "reloc section header" [| |] - // 000001a0 - writeBytes os [| 0x2euy; 0x72uy; 0x65uy; 0x6cuy; 0x6fuy; 0x63uy; 0x00uy; 0x00uy; |] // ".reloc\000\000" - writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. - writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section. - // 000001b0 - writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes - writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. - // 000001b8 - writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. - writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). - // 000001c0 - writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. - writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). - writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x42uy |] // Characteristics Flags: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | - - writePadding os "pad to text begin" (textSectionPhysLoc - headerSize) - - // TEXT SECTION: e.g. 0x200 - - let textV2P v = v - textSectionAddr + textSectionPhysLoc - - // e.g. 0x0200 - write (Some (textV2P importAddrTableChunk.addr)) os "import addr table" [| |] - writeInt32 os importNameHintTableChunk.addr - writeInt32 os 0x00 // QUERY 4 bytes of zeros not 2 like ECMA 24.3.1 says - - // e.g. 0x0208 - - let flags = - (if modul.IsILOnly then 0x01 else 0x00) ||| - (if modul.Is32Bit then 0x02 else 0x00) ||| - (if modul.Is32BitPreferred then 0x00020003 else 0x00) ||| - (if (match signer with None -> false | Some s -> s.IsFullySigned) then 0x08 else 0x00) - - let headerVersionMajor, headerVersionMinor = headerVersionSupportedByCLRVersion desiredMetadataVersion - - writePadding os "pad to cli header" cliHeaderPadding - write (Some (textV2P cliHeaderChunk.addr)) os "cli header" [| |] - writeInt32 os 0x48 // size of header - writeInt32AsUInt16 os headerVersionMajor // Major part of minimum version of CLR reqd. - writeInt32AsUInt16 os headerVersionMinor // Minor part of minimum version of CLR reqd. ... - // e.g. 0x0210 - writeDirectory os metadataChunk - writeInt32 os flags - - writeInt32 os entryPointToken - write None os "rest of cli header" [| |] - - // e.g. 0x0220 - writeDirectory os resourcesChunk - writeDirectory os strongnameChunk - // e.g. 0x0230 - writeInt32 os 0x00 // code manager table, always 0 - writeInt32 os 0x00 // code manager table, always 0 - writeDirectory os vtfixupsChunk - // e.g. 0x0240 - writeInt32 os 0x00 // export addr table jumps, always 0 - writeInt32 os 0x00 // export addr table jumps, always 0 - writeInt32 os 0x00 // managed native header, always 0 - writeInt32 os 0x00 // managed native header, always 0 - - writeBytes os code - write None os "code padding" codePadding - - writeBytes os metadata - - // write 0x80 bytes of empty space for encrypted SHA1 hash, written by SN.EXE or call to signing API - if signer <> None then - write (Some (textV2P strongnameChunk.addr)) os "strongname" (Array.create strongnameChunk.size 0x0uy) - - write (Some (textV2P resourcesChunk.addr)) os "raw resources" [| |] - writeBytes os resources - write (Some (textV2P rawdataChunk.addr)) os "raw data" [| |] - writeBytes os data - - writePadding os "start of import table" importTableChunkPrePadding - - // vtfixups would go here - write (Some (textV2P importTableChunk.addr)) os "import table" [| |] - - writeInt32 os importLookupTableChunk.addr - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os mscoreeStringChunk.addr - writeInt32 os importAddrTableChunk.addr - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os 0x00 - - write (Some (textV2P importLookupTableChunk.addr)) os "import lookup table" [| |] - writeInt32 os importNameHintTableChunk.addr - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os 0x00 - writeInt32 os 0x00 - - - write (Some (textV2P importNameHintTableChunk.addr)) os "import name hint table" [| |] - // Two zero bytes of hint, then Case sensitive, null-terminated ASCII string containing name to import. - // Shall _CorExeMain a .exe file _CorDllMain for a .dll file. - if isDll then - writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy ; 0x6fuy; 0x72uy; 0x44uy; 0x6cuy; 0x6cuy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] - else - writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy; 0x6fuy; 0x72uy; 0x45uy; 0x78uy; 0x65uy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] - - write (Some (textV2P mscoreeStringChunk.addr)) os "mscoree string" - [| 0x6duy; 0x73uy; 0x63uy; 0x6fuy ; 0x72uy; 0x65uy ; 0x65uy; 0x2euy ; 0x64uy; 0x6cuy ; 0x6cuy; 0x00uy ; |] - - writePadding os "end of import tab" importTableChunkPadding - - writePadding os "head of entrypoint" 0x03 - let ep = (imageBaseReal + textSectionAddr) - write (Some (textV2P entrypointCodeChunk.addr)) os " entrypoint code" - [| 0xFFuy; 0x25uy; (* x86 Instructions for entry *) b0 ep; b1 ep; b2 ep; b3 ep |] - if isItanium then - write (Some (textV2P globalpointerCodeChunk.addr)) os " itanium global pointer" - [| 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy |] - - if pdbfile.IsSome then - write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy) - write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy) - write (Some (textV2P debugChecksumPdbChunk.addr)) os "debug checksum" (Array.create debugChecksumPdbChunk.size 0x0uy) - - if embeddedPDB then - write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy) - - if deterministic then - write (Some (textV2P debugDeterministicPdbChunk.addr)) os "debug deterministic" Array.empty - - writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize) - - // DATA SECTION - match nativeResources with - | [||] -> () - | resources -> - write (Some (dataSectionVirtToPhys nativeResourcesChunk.addr)) os "raw native resources" [| |] - writeBytes os resources - - if dummydatap.size <> 0x0 then - write (Some (dataSectionVirtToPhys dummydatap.addr)) os "dummy data" [| 0x0uy |] - - writePadding os "end of .rsrc" (relocSectionPhysLoc - dataSectionPhysLoc - dataSectionSize) - - // RELOC SECTION - - // See ECMA 24.3.2 - let relocV2P v = v - relocSectionAddr + relocSectionPhysLoc - - let entrypointFixupAddr = entrypointCodeChunk.addr + 0x02 - let entrypointFixupBlock = (entrypointFixupAddr / 4096) * 4096 - let entrypointFixupOffset = entrypointFixupAddr - entrypointFixupBlock - let reloc = (if modul.Is64Bit then 0xA000 (* IMAGE_REL_BASED_DIR64 *) else 0x3000 (* IMAGE_REL_BASED_HIGHLOW *)) ||| entrypointFixupOffset - // For the itanium, you need to set a relocation entry for the global pointer - let reloc2 = - if not isItanium then - 0x0 - else - 0xA000 ||| (globalpointerCodeChunk.addr - ((globalpointerCodeChunk.addr / 4096) * 4096)) - - write (Some (relocV2P baseRelocTableChunk.addr)) os "base reloc table" - [| b0 entrypointFixupBlock; b1 entrypointFixupBlock; b2 entrypointFixupBlock; b3 entrypointFixupBlock - 0x0cuy; 0x00uy; 0x00uy; 0x00uy - b0 reloc; b1 reloc - b0 reloc2; b1 reloc2; |] - writePadding os "end of .reloc" (imageEndSectionPhysLoc - relocSectionPhysLoc - relocSectionSize) - - os.Dispose() - - try - FileSystemUtilities.setExecutablePermission outfile - with _ -> - () - pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings - - // Looks like a finally - with e -> - (try - os.Dispose() - FileSystem.FileDelete outfile - with _ -> ()) - reraise() - - reportTime showTimes "Writing Image" - - if dumpDebugInfo then logDebugInfo outfile pdbData - - // Now we've done the bulk of the binary, do the PDB file and fixup the binary. - begin match pdbfile with - | None -> () -#if ENABLE_MONO_SUPPORT - | Some fmdb when runningOnMono && not portablePDB -> - writeMdbInfo fmdb outfile pdbData -#endif - | Some fpdb -> - try - let idd = - match pdbOpt with - | Some (originalLength, contentId, stream, algorithmName, checkSum) -> - if embeddedPDB then - embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic - else - writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic - | None -> -#if FX_NO_PDB_WRITER - Array.empty -#else - writePdbInfo showTimes outfile fpdb pdbData debugDataChunk -#endif - reportTime showTimes "Generate PDB Info" - - // Now we have the debug data we can go back and fill in the debug directory in the image - let fs2 = FileSystem.FileStreamWriteExistingShim outfile - let os2 = new BinaryWriter(fs2) - try - // write the IMAGE_DEBUG_DIRECTORY - os2.BaseStream.Seek (int64 (textV2P debugDirectoryChunk.addr), SeekOrigin.Begin) |> ignore - for i in idd do - writeInt32 os2 i.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics - writeInt32 os2 i.iddTimestamp - writeInt32AsUInt16 os2 i.iddMajorVersion - writeInt32AsUInt16 os2 i.iddMinorVersion - writeInt32 os2 i.iddType - writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData - writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData - writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData - - // Write the Debug Data - for i in idd do - if i.iddChunk.size <> 0 then - // write the debug raw data as given us by the PDB writer - os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore - if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable" - writeBytes os2 i.iddData - os2.Dispose() - with e -> - failwith ("Error while writing debug directory entry: "+e.Message) - (try os2.Dispose(); FileSystem.FileDelete outfile with _ -> ()) - reraise() - with e -> - reraise() - - end - reportTime showTimes "Finalize PDB" - - /// Sign the binary. No further changes to binary allowed past this point! - match signer with - | None -> () - | Some s -> - try - s.SignFile outfile - s.Close() - with e -> - failwith ("Warning: A call to SignFile failed ("+e.Message+")") - (try s.Close() with _ -> ()) - (try FileSystem.FileDelete outfile with _ -> ()) - () - - reportTime showTimes "Signing Image" - //Finished writing and signing the binary and debug info... - mappings - -type options = - { ilg: ILGlobals - pdbfile: string option - portablePDB: bool - embeddedPDB: bool - embedAllSource: bool - embedSourceList: string list - sourceLink: string - checksumAlgorithm: HashAlgorithm - signer: ILStrongNameSigner option - emitTailcalls: bool - deterministic: bool - showTimes: bool - dumpDebugInfo: bool - pathMap: PathMap } - -let WriteILBinary (outfile, (args: options), modul, normalizeAssemblyRefs) = - writeBinaryAndReportMappings (outfile, - args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, args.embedAllSource, - args.embedSourceList, args.sourceLink, args.checksumAlgorithm, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo, args.pathMap) modul normalizeAssemblyRefs - |> ignore diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi deleted file mode 100644 index 9dba89c9b6c..00000000000 --- a/src/absil/ilwrite.fsi +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// The IL Binary writer. -module internal FSharp.Compiler.AbstractIL.ILBinaryWriter - -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILPdbWriter - -[] -type ILStrongNameSigner = - member PublicKey: byte[] - static member OpenPublicKeyOptions: string -> bool -> ILStrongNameSigner - static member OpenPublicKey: byte[] -> ILStrongNameSigner - static member OpenKeyPairFile: string -> ILStrongNameSigner - static member OpenKeyContainer: string -> ILStrongNameSigner - -type options = - { ilg: ILGlobals - pdbfile: string option - portablePDB: bool - embeddedPDB: bool - embedAllSource: bool - embedSourceList: string list - sourceLink: string - checksumAlgorithm: HashAlgorithm - signer : ILStrongNameSigner option - emitTailcalls: bool - deterministic: bool - showTimes : bool - dumpDebugInfo : bool - pathMap : PathMap } - -/// Write a binary to the file system. Extra configuration parameters can also be specified. -val WriteILBinary: filename: string * options: options * input: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs deleted file mode 100644 index 682b20a6888..00000000000 --- a/src/absil/ilwritepdb.fs +++ /dev/null @@ -1,819 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.AbstractIL.ILPdbWriter - -open System -open System.Collections.Generic -open System.Collections.Immutable -open System.IO -open System.IO.Compression -open System.Reflection -open System.Reflection.Metadata -open System.Reflection.Metadata.Ecma335 -open System.Text -open Internal.Utilities -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Support -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range - - -type BlobBuildingStream () = - inherit Stream() - - static let chunkSize = 32 * 1024 - let builder = new BlobBuilder(chunkSize) - - override this.CanWrite = true - override this.CanRead = false - override this.CanSeek = false - override this.Length = int64 (builder.Count) - - override this.Write(buffer: byte array, offset: int, count: int) = builder.WriteBytes(buffer, offset, count) - override this.WriteByte(value: byte) = builder.WriteByte value - member this.WriteInt32(value: int) = builder.WriteInt32 value - member this.ToImmutableArray() = builder.ToImmutableArray() - member this.TryWriteBytes(stream: Stream, length: int) = builder.TryWriteBytes(stream, length) - - override this.Flush() = () - override this.Dispose(_disposing: bool) = () - override this.Seek(_offset: int64, _origin: SeekOrigin) = raise (new NotSupportedException()) - override this.Read(_buffer: byte array, _offset: int, _count: int) = raise (new NotSupportedException()) - override this.SetLength(_value: int64) = raise (new NotSupportedException()) - override val Position = 0L with get, set - -// -------------------------------------------------------------------- -// PDB types -// -------------------------------------------------------------------- -type PdbDocumentData = ILSourceDocument - -type PdbLocalVar = - { Name: string - Signature: byte[] - /// the local index the name corresponds to - Index: int32 } - -type PdbMethodScope = - { Children: PdbMethodScope array - StartOffset: int - EndOffset: int - Locals: PdbLocalVar array - (* REVIEW open_namespaces: pdb_namespace array *) } - -type PdbSourceLoc = - { Document: int - Line: int - Column: int } - -type PdbSequencePoint = - { Document: int - Offset: int - Line: int - Column: int - EndLine: int - EndColumn: int } - override x.ToString() = sprintf "(%d,%d)-(%d,%d)" x.Line x.Column x.EndLine x.EndColumn - -type PdbMethodData = - { MethToken: int32 - MethName: string - LocalSignatureToken: int32 - Params: PdbLocalVar array - RootScope: PdbMethodScope option - Range: (PdbSourceLoc * PdbSourceLoc) option - SequencePoints: PdbSequencePoint array } - -module SequencePoint = - let orderBySource sp1 sp2 = - let c1 = compare sp1.Document sp2.Document - if c1 <> 0 then - c1 - else - let c1 = compare sp1.Line sp2.Line - if c1 <> 0 then - c1 - else - compare sp1.Column sp2.Column - - let orderByOffset sp1 sp2 = - compare sp1.Offset sp2.Offset - -/// 28 is the size of the IMAGE_DEBUG_DIRECTORY in ntimage.h -let sizeof_IMAGE_DEBUG_DIRECTORY = 28 - -[] -type PdbData = - { EntryPoint: int32 option - Timestamp: int32 - ModuleID: byte[] - Documents: PdbDocumentData[] - Methods: PdbMethodData[] - TableRowCounts: int[] } - -type BinaryChunk = - { size: int32 - addr: int32 } - -type idd = - { iddCharacteristics: int32 - iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) - iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) - iddType: int32 - iddTimestamp: int32 - iddData: byte[] - iddChunk: BinaryChunk } - -/// The specified Hash algorithm to use on portable pdb files. -type HashAlgorithm = - | Sha1 - | Sha256 - -// Document checksum algorithms -let guidSha1 = Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460") -let guidSha2 = Guid("8829d00f-11b8-4213-878b-770e8597ac16") - -let checkSum (url: string) (checksumAlgorithm: HashAlgorithm) = - try - use file = FileSystem.FileStreamReadShim url - let guid, alg = - match checksumAlgorithm with - | HashAlgorithm.Sha1 -> guidSha1, System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm - | HashAlgorithm.Sha256 -> guidSha2, System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm - - let checkSum = alg.ComputeHash file - Some (guid, checkSum) - with _ -> None - -//--------------------------------------------------------------------- -// Portable PDB Writer -//--------------------------------------------------------------------- -let cvMagicNumber = 0x53445352L -let pdbGetCvDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvChunk: BinaryChunk) = - let iddCvBuffer = - // Debug directory entry - let path = (System.Text.Encoding.UTF8.GetBytes filepath) - let buffer = Array.zeroCreate (sizeof + mvid.Length + sizeof + path.Length + 1) - let (offset, size) = (0, sizeof) // Magic Number RSDS dword: 0x53445352L - Buffer.BlockCopy(BitConverter.GetBytes cvMagicNumber, 0, buffer, offset, size) - let (offset, size) = (offset + size, mvid.Length) // mvid Guid - Buffer.BlockCopy(mvid, 0, buffer, offset, size) - let (offset, size) = (offset + size, sizeof) // # of pdb files generated (1) - Buffer.BlockCopy(BitConverter.GetBytes 1, 0, buffer, offset, size) - let (offset, size) = (offset + size, path.Length) // Path to pdb string - Buffer.BlockCopy(path, 0, buffer, offset, size) - buffer - { iddCharacteristics = 0 // Reserved - iddMajorVersion = 0x0100 // VersionMajor should be 0x0100 - iddMinorVersion = 0x504d // VersionMinor should be 0x504d - iddType = 2 // IMAGE_DEBUG_TYPE_CODEVIEW - iddTimestamp = timestamp - iddData = iddCvBuffer // Path name to the pdb file when built - iddChunk = cvChunk - } - -let pdbMagicNumber= 0x4244504dL -let pdbGetEmbeddedPdbDebugInfo (embeddedPdbChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) = - let iddPdbBuffer = - let buffer = Array.zeroCreate (sizeof + sizeof + int(stream.Length)) - let (offset, size) = (0, sizeof) // Magic Number dword: 0x4244504dL - Buffer.BlockCopy(BitConverter.GetBytes pdbMagicNumber, 0, buffer, offset, size) - let (offset, size) = (offset + size, sizeof) // Uncompressed size - Buffer.BlockCopy(BitConverter.GetBytes((int uncompressedLength)), 0, buffer, offset, size) - let (offset, size) = (offset + size, int(stream.Length)) // Uncompressed size - Buffer.BlockCopy(stream.ToArray(), 0, buffer, offset, size) - buffer - { iddCharacteristics = 0 // Reserved - iddMajorVersion = 0x0100 // VersionMajor should be 0x0100 - iddMinorVersion = 0x0100 // VersionMinor should be 0x0100 - iddType = 17 // IMAGE_DEBUG_TYPE_EMBEDDEDPDB - iddTimestamp = 0 - iddData = iddPdbBuffer // Path name to the pdb file when built - iddChunk = embeddedPdbChunk - } - -let pdbChecksumDebugInfo timestamp (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte[]) = - let iddBuffer = - let alg = Encoding.UTF8.GetBytes(algorithmName) - let buffer = Array.zeroCreate (alg.Length + 1 + checksum.Length) - Buffer.BlockCopy(alg, 0, buffer, 0, alg.Length) - Buffer.BlockCopy(checksum, 0, buffer, alg.Length + 1, checksum.Length) - buffer - { iddCharacteristics = 0 // Reserved - iddMajorVersion = 1 // VersionMajor should be 1 - iddMinorVersion = 0 // VersionMinor should be 0 - iddType = 19 // IMAGE_DEBUG_TYPE_CHECKSUMPDB - iddTimestamp = timestamp - iddData = iddBuffer // Path name to the pdb file when built - iddChunk = checksumPdbChunk - } - -let pdbGetPdbDebugDeterministicInfo (deterministicPdbChunk: BinaryChunk) = - { iddCharacteristics = 0 // Reserved - iddMajorVersion = 0 // VersionMajor should be 0 - iddMinorVersion = 0 // VersionMinor should be 00 - iddType = 16 // IMAGE_DEBUG_TYPE_DETERMINISTIC - iddTimestamp = 0 - iddData = Array.empty // No DATA - iddChunk = deterministicPdbChunk - } - -let pdbGetDebugInfo (contentId: byte[]) (timestamp: int32) (filepath: string) - (cvChunk: BinaryChunk) - (embeddedPdbChunk: BinaryChunk option) - (deterministicPdbChunk: BinaryChunk) - (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte []) - (uncompressedLength: int64) (stream: MemoryStream option) - (embeddedPdb: bool) (deterministic: bool) = - [| yield pdbGetCvDebugInfo contentId timestamp filepath cvChunk - yield pdbChecksumDebugInfo timestamp checksumPdbChunk algorithmName checksum - if embeddedPdb then - match stream, embeddedPdbChunk with - | None, _ | _, None -> () - | Some s, Some chunk -> - yield pdbGetEmbeddedPdbDebugInfo chunk uncompressedLength s - if deterministic then - yield pdbGetPdbDebugDeterministicInfo deterministicPdbChunk - |] - -//------------------------------------------------------------------------------ -// PDB Writer. The function [WritePdbInfo] abstracts the -// imperative calls to the Symbol Writer API. -//------------------------------------------------------------------------------ - -// This function takes output file name and returns debug file name. -let getDebugFileName outfile (portablePDB: bool) = -#if ENABLE_MONO_SUPPORT - if IL.runningOnMono && not portablePDB then - outfile + ".mdb" - else -#else - ignore portablePDB -#endif - (Filename.chopExtension outfile) + ".pdb" - -let sortMethods showTimes info = - reportTime showTimes (sprintf "PDB: Defined %d documents" info.Documents.Length) - Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods - reportTime showTimes (sprintf "PDB: Sorted %d methods" info.Methods.Length) - () - -let getRowCounts tableRowCounts = - let builder = ImmutableArray.CreateBuilder(tableRowCounts |> Array.length) - tableRowCounts |> Seq.iter(fun x -> builder.Add x) - builder.MoveToImmutable() - -let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) checksumAlgorithm showTimes (info: PdbData) (pathMap: PathMap) = - sortMethods showTimes info - let externalRowCounts = getRowCounts info.TableRowCounts - let docs = - match info.Documents with - | null -> Array.empty - | _ -> info.Documents - - let metadata = MetadataBuilder() - let serializeDocumentName (name: string) = - let name = PathMap.apply pathMap name - let count s c = s |> Seq.filter(fun ch -> if c = ch then true else false) |> Seq.length - - let s1, s2 = '/', '\\' - let separator = if (count name s1) >= (count name s2) then s1 else s2 - - let writer = new BlobBuilder() - writer.WriteByte(byte separator) - - for part in name.Split( [| separator |] ) do - let partIndex = MetadataTokens.GetHeapOffset(BlobHandle.op_Implicit(metadata.GetOrAddBlobUTF8 part)) - writer.WriteCompressedInteger(int partIndex) - - metadata.GetOrAddBlob writer - - let corSymLanguageTypeId = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) - let embeddedSourceId = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) - let sourceLinkId = System.Guid(0xcc110556u, 0xa091us, 0x4d38us, 0x9fuy, 0xecuy, 0x25uy, 0xabuy, 0x9auy, 0x35uy, 0x1auy, 0x6auy) - - /// - /// The maximum number of bytes in to write out uncompressed. - /// - /// This prevents wasting resources on compressing tiny files with little to negative gain - /// in PDB file size. - /// - /// Chosen as the point at which we start to see > 10% blob size reduction using all - /// current source files in corefx and roslyn as sample data. - /// - let sourceCompressionThreshold = 200 - - let documentIndex = - let includeSource file = - let isInList = embedSourceList |> List.exists (fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) - - if not embedAllSource && not isInList || not (File.Exists file) then - None - else - let stream = File.OpenRead file - let length64 = stream.Length - if length64 > int64 (Int32.MaxValue) then raise (new IOException("File is too long")) - - let builder = new BlobBuildingStream() - let length = int length64 - if length < sourceCompressionThreshold then - builder.WriteInt32 0 - builder.TryWriteBytes(stream, length) |> ignore - else - builder.WriteInt32 length |>ignore - use deflater = new DeflateStream(builder, CompressionMode.Compress, true) - stream.CopyTo deflater |> ignore - Some (builder.ToImmutableArray()) - - let mutable index = new Dictionary(docs.Length) - let docLength = docs.Length + if String.IsNullOrEmpty sourceLink then 1 else 0 - metadata.SetCapacity(TableIndex.Document, docLength) - for doc in docs do - let handle = - match checkSum doc.File checksumAlgorithm with - | Some (hashAlg, checkSum) -> - let dbgInfo = - (serializeDocumentName doc.File, - metadata.GetOrAddGuid hashAlg, - metadata.GetOrAddBlob(checkSum.ToImmutableArray()), - metadata.GetOrAddGuid corSymLanguageTypeId) |> metadata.AddDocument - match includeSource doc.File with - | None -> () - | Some blob -> - metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit dbgInfo, - metadata.GetOrAddGuid embeddedSourceId, - metadata.GetOrAddBlob blob) |> ignore - dbgInfo - | None -> - let dbgInfo = - (serializeDocumentName doc.File, - metadata.GetOrAddGuid(System.Guid.Empty), - metadata.GetOrAddBlob(ImmutableArray.Empty), - metadata.GetOrAddGuid corSymLanguageTypeId) |> metadata.AddDocument - dbgInfo - index.Add(doc.File, handle) - - if not (String.IsNullOrEmpty sourceLink) then - let fs = File.OpenRead sourceLink - let ms = new MemoryStream() - fs.CopyTo ms - metadata.AddCustomDebugInformation( - ModuleDefinitionHandle.op_Implicit(EntityHandle.ModuleDefinition), - metadata.GetOrAddGuid sourceLinkId, - metadata.GetOrAddBlob(ms.ToArray())) |> ignore - index - - let mutable lastLocalVariableHandle = Unchecked.defaultof - metadata.SetCapacity(TableIndex.MethodDebugInformation, info.Methods.Length) - info.Methods |> Array.iter (fun minfo -> - let docHandle, sequencePointBlob = - let sps = - match minfo.SequencePoints with - | null -> Array.empty - | _ -> - match minfo.Range with - | None -> Array.empty - | Some (_,_) -> minfo.SequencePoints - - let builder = new BlobBuilder() - builder.WriteCompressedInteger(minfo.LocalSignatureToken) - - if sps.Length = 0 then - builder.WriteCompressedInteger( 0 ) - builder.WriteCompressedInteger( 0 ) - Unchecked.defaultof, Unchecked.defaultof - else - let getDocumentHandle d = - if docs.Length = 0 || d < 0 || d > docs.Length then - Unchecked.defaultof - else - match documentIndex.TryGetValue(docs.[d].File) with - | false, _ -> Unchecked.defaultof - | true, h -> h - - // Return a document that the entire method body is declared within. - // If part of the method body is in another document returns nil handle. - let tryGetSingleDocumentIndex = - let mutable singleDocumentIndex = sps.[0].Document - for i in 1 .. sps.Length - 1 do - if sps.[i].Document <> singleDocumentIndex then - singleDocumentIndex <- -1 - singleDocumentIndex - - // Initial document: When sp's spread over more than one document we put the initial document here. - let singleDocumentIndex = tryGetSingleDocumentIndex - if singleDocumentIndex = -1 then - builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle (sps.[0].Document))) ) - - let mutable previousNonHiddenStartLine = -1 - let mutable previousNonHiddenStartColumn = 0 - - for i in 0 .. (sps.Length - 1) do - - if singleDocumentIndex <> -1 && sps.[i].Document <> singleDocumentIndex then - builder.WriteCompressedInteger( 0 ) - builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle (sps.[i].Document))) ) - else - //============================================================================================================================================= - // Sequence-point-record - // Validate these with magic numbers according to the portable pdb spec Sequence point dexcription: - // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#methoddebuginformation-table-0x31 - // - // So the spec is actually bit iffy!!!!! (More like guidelines really. ) - // It uses code similar to this to validate the values - // if (result < 0 || result >= ushort.MaxValue) // be errorfull - // Spec Says 0x10000 and value max = 0xFFFF but it can't even be = to maxvalue, and so the range is 0 .. 0xfffe inclusive - //============================================================================================================================================= - - let capValue v maxValue = - if v < 0 then 0 - elif v > maxValue then maxValue - else v - - let capOffset v = capValue v 0xfffe - let capLine v = capValue v 0x1ffffffe - let capColumn v = capValue v 0xfffe - - let offset = capOffset sps.[i].Offset - let startLine = capLine sps.[i].Line - let endLine = capLine sps.[i].EndLine - let startColumn = capColumn sps.[i].Column - let endColumn = capColumn sps.[i].EndColumn - - let offsetDelta = // delta from previous offset - if i > 0 then offset - capOffset sps.[i - 1].Offset - else offset - - if i < 1 || offsetDelta > 0 then - builder.WriteCompressedInteger offsetDelta - - // Check for hidden-sequence-point-record - if startLine = 0xfeefee || - endLine = 0xfeefee || - (startColumn = 0 && endColumn = 0) || - ((endLine - startLine) = 0 && (endColumn - startColumn) = 0) - then - // Hidden-sequence-point-record - builder.WriteCompressedInteger 0 - builder.WriteCompressedInteger 0 - else - // Non-hidden-sequence-point-record - let deltaLines = endLine - startLine // lines - builder.WriteCompressedInteger deltaLines - - let deltaColumns = endColumn - startColumn // Columns - if deltaLines = 0 then - builder.WriteCompressedInteger deltaColumns - else - builder.WriteCompressedSignedInteger deltaColumns - - if previousNonHiddenStartLine < 0 then // delta Start Line & Column: - builder.WriteCompressedInteger startLine - builder.WriteCompressedInteger startColumn - else - builder.WriteCompressedSignedInteger(startLine - previousNonHiddenStartLine) - builder.WriteCompressedSignedInteger(startColumn - previousNonHiddenStartColumn) - - previousNonHiddenStartLine <- startLine - previousNonHiddenStartColumn <- startColumn - - getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob builder - - metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore - - // Write the scopes - let nextHandle handle = MetadataTokens.LocalVariableHandle(MetadataTokens.GetRowNumber(LocalVariableHandle.op_Implicit handle) + 1) - let writeMethodScope scope = - let scopeSorter (scope1: PdbMethodScope) (scope2: PdbMethodScope) = - if scope1.StartOffset > scope2.StartOffset then 1 - elif scope1.StartOffset < scope2.StartOffset then -1 - elif (scope1.EndOffset - scope1.StartOffset) > (scope2.EndOffset - scope2.StartOffset) then -1 - elif (scope1.EndOffset - scope1.StartOffset) < (scope2.EndOffset - scope2.StartOffset) then 1 - else 0 - - let collectScopes scope = - let list = new List() - let rec toList scope parent = - let nested = - match parent with - | Some p -> scope.StartOffset <> p.StartOffset || scope.EndOffset <> p.EndOffset - | None -> true - - if nested then list.Add scope - scope.Children |> Seq.iter(fun s -> toList s (if nested then Some scope else parent)) - - toList scope None - list.ToArray() |> Array.sortWith scopeSorter - - collectScopes scope |> Seq.iter(fun s -> - metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - nextHandle lastLocalVariableHandle, - Unchecked.defaultof, - s.StartOffset, s.EndOffset - s.StartOffset ) |>ignore - - for localVariable in s.Locals do - lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) - ) - - match minfo.RootScope with - | None -> () - | Some scope -> writeMethodScope scope ) - - let entryPoint = - match info.EntryPoint with - | None -> MetadataTokens.MethodDefinitionHandle 0 - | Some x -> MetadataTokens.MethodDefinitionHandle x - - // Compute the contentId for the pdb. Always do it deterministically, since we have to compute the anyway. - // The contentId is the hash of the ID using whichever algorithm has been specified to the compiler - let mutable contentHash = Array.empty - - let algorithmName, hashAlgorithm = - match checksumAlgorithm with - | HashAlgorithm.Sha1 -> "SHA1", System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm - | HashAlgorithm.Sha256 -> "SHA256", System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm - let idProvider: System.Func, BlobContentId> = - let convert (content: IEnumerable) = - let contentBytes = content |> Seq.collect (fun c -> c.GetBytes()) |> Array.ofSeq - contentHash <- contentBytes |> hashAlgorithm.ComputeHash - BlobContentId.FromHash contentHash - System.Func, BlobContentId>(convert) - - let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, idProvider) - let blobBuilder = new BlobBuilder() - let contentId= serializer.Serialize blobBuilder - let portablePdbStream = new MemoryStream() - blobBuilder.WriteContentTo portablePdbStream - reportTime showTimes "PDB: Created" - (portablePdbStream.Length, contentId, portablePdbStream, algorithmName, contentHash) - -let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) = - let compressedStream = new MemoryStream() - use compressionStream = new DeflateStream(compressedStream, CompressionMode.Compress,true) - stream.WriteTo compressionStream - (uncompressedLength, contentId, compressedStream) - -let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb = - try FileSystem.FileDelete fpdb with _ -> () - use pdbFile = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite) - stream.WriteTo pdbFile - reportTime showTimes "PDB: Closed" - pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) (PathMap.apply pathMap fpdb) cvChunk None deterministicPdbChunk checksumPdbChunk algName checksum 0L None embeddedPdb deterministicPdb - -let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk deterministicPdbChunk checksumPdbChunk algName checksum embeddedPdb deterministicPdb = - reportTime showTimes "PDB: Closed" - let fn = Path.GetFileName fpdb - pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) deterministicPdbChunk checksumPdbChunk algName checksum uncompressedLength (Some stream) embeddedPdb deterministicPdb - -#if !FX_NO_PDB_WRITER -//--------------------------------------------------------------------- -// PDB Writer. The function [WritePdbInfo] abstracts the -// imperative calls to the Symbol Writer API. -//--------------------------------------------------------------------- -let writePdbInfo showTimes f fpdb info cvChunk = - - try FileSystem.FileDelete fpdb with _ -> () - - let pdbw = ref Unchecked.defaultof - - try - pdbw := pdbInitialize f fpdb - with _ -> error(Error(FSComp.SR.ilwriteErrorCreatingPdb fpdb, rangeCmdArgs)) - - match info.EntryPoint with - | None -> () - | Some x -> pdbSetUserEntryPoint !pdbw x - - let docs = info.Documents |> Array.map (fun doc -> pdbDefineDocument !pdbw doc.File) - let getDocument i = - if i < 0 || i > docs.Length then failwith "getDocument: bad doc number" - docs.[i] - reportTime showTimes (sprintf "PDB: Defined %d documents" info.Documents.Length) - Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods - reportTime showTimes (sprintf "PDB: Sorted %d methods" info.Methods.Length) - - let spCounts = info.Methods |> Array.map (fun x -> x.SequencePoints.Length) - let allSps = Array.collect (fun x -> x.SequencePoints) info.Methods |> Array.indexed - - let spOffset = ref 0 - info.Methods |> Array.iteri (fun i minfo -> - - let sps = Array.sub allSps !spOffset spCounts.[i] - spOffset := !spOffset + spCounts.[i] - begin match minfo.Range with - | None -> () - | Some (a,b) -> - pdbOpenMethod !pdbw minfo.MethToken - - pdbSetMethodRange !pdbw - (getDocument a.Document) a.Line a.Column - (getDocument b.Document) b.Line b.Column - - // Partition the sequence points by document - let spsets = - let res = Dictionary() - for (_,sp) in sps do - let k = sp.Document - let mutable xsR = Unchecked.defaultof<_> - if res.TryGetValue(k,&xsR) then - xsR := sp :: !xsR - else - res.[k] <- ref [sp] - - res - - spsets - |> Seq.iter (fun kv -> - let spset = !kv.Value - if not spset.IsEmpty then - let spset = Array.ofList spset - Array.sortInPlaceWith SequencePoint.orderByOffset spset - let sps = - spset |> Array.map (fun sp -> - // Ildiag.dprintf "token 0x%08lx has an sp at offset 0x%08x\n" minfo.MethToken sp.Offset - (sp.Offset, sp.Line, sp.Column,sp.EndLine, sp.EndColumn)) - // Use of alloca in implementation of pdbDefineSequencePoints can give stack overflow here - if sps.Length < 5000 then - pdbDefineSequencePoints !pdbw (getDocument spset.[0].Document) sps) - - // Write the scopes - let rec writePdbScope parent sco = - if parent = None || sco.Locals.Length <> 0 || sco.Children.Length <> 0 then - // Only nest scopes if the child scope is a different size from - let nested = - match parent with - | Some p -> sco.StartOffset <> p.StartOffset || sco.EndOffset <> p.EndOffset - | None -> true - if nested then pdbOpenScope !pdbw sco.StartOffset - sco.Locals |> Array.iter (fun v -> pdbDefineLocalVariable !pdbw v.Name v.Signature v.Index) - sco.Children |> Array.iter (writePdbScope (if nested then Some sco else parent)) - if nested then pdbCloseScope !pdbw sco.EndOffset - - match minfo.RootScope with - | None -> () - | Some rootscope -> writePdbScope None rootscope - pdbCloseMethod !pdbw - end) - reportTime showTimes "PDB: Wrote methods" - - let res = pdbWriteDebugInfo !pdbw - for pdbDoc in docs do pdbCloseDocument pdbDoc - pdbClose !pdbw f fpdb - - reportTime showTimes "PDB: Closed" - [| { iddCharacteristics = res.iddCharacteristics - iddMajorVersion = res.iddMajorVersion - iddMinorVersion = res.iddMinorVersion - iddType = res.iddType - iddTimestamp = info.Timestamp - iddData = res.iddData - iddChunk = cvChunk } |] -#endif - -#if ENABLE_MONO_SUPPORT -//--------------------------------------------------------------------- -// Support functions for calling 'Mono.CompilerServices.SymbolWriter' -// assembly dynamically if it is available to the compiler -//--------------------------------------------------------------------- -open Microsoft.FSharp.Reflection - -// Dynamic invoke operator. Implements simple overload resolution based -// on the name and number of parameters only. -// Supports the following cases: -// obj?Foo() // call with no arguments -// obj?Foo(1, "a") // call with two arguments (extracted from tuple) -// NOTE: This doesn't actually handle all overloads. It just picks first entry with right -// number of arguments. -let (?) this memb (args:'Args) : 'R = - // Get array of 'obj' arguments for the reflection call - let args = - if typeof<'Args> = typeof then [| |] - elif FSharpType.IsTuple typeof<'Args> then Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields args - else [| box args |] - - // Get methods and perform overload resolution - let methods = this.GetType().GetMethods() - let bestMatch = methods |> Array.tryFind (fun mi -> mi.Name = memb && mi.GetParameters().Length = args.Length) - match bestMatch with - | Some mi -> unbox(mi.Invoke(this, args)) - | None -> error(Error(FSComp.SR.ilwriteMDBMemberMissing memb, rangeCmdArgs)) - -// Creating instances of needed classes from 'Mono.CompilerServices.SymbolWriter' assembly - -let monoCompilerSvc = new AssemblyName("Mono.CompilerServices.SymbolWriter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756") -let ctor (asmName: AssemblyName) clsName (args: obj[]) = - let asm = Assembly.Load asmName - let ty = asm.GetType clsName - System.Activator.CreateInstance(ty, args) - -let createSourceMethodImpl (name: string) (token: int) (namespaceID: int) = - ctor monoCompilerSvc "Mono.CompilerServices.SymbolWriter.SourceMethodImpl" [| box name; box token; box namespaceID |] - -let createWriter (f: string) = - ctor monoCompilerSvc "Mono.CompilerServices.SymbolWriter.MonoSymbolWriter" [| box f |] - -//--------------------------------------------------------------------- -// MDB Writer. Generate debug symbols using the MDB format -//--------------------------------------------------------------------- -let writeMdbInfo fmdb f info = - // Note, if we can't delete it code will fail later - try FileSystem.FileDelete fmdb with _ -> () - - // Try loading the MDB symbol writer from an assembly available on Mono dynamically - // Report an error if the assembly is not available. - let wr = - try createWriter f - with e -> error(Error(FSComp.SR.ilwriteErrorCreatingMdb(), rangeCmdArgs)) - - // NOTE: MonoSymbolWriter doesn't need information about entrypoints, so 'info.EntryPoint' is unused here. - // Write information about Documents. Returns '(SourceFileEntry*CompileUnitEntry)[]' - let docs = - [| for doc in info.Documents do - let doc = wr?DefineDocument(doc.File) - let unit = wr?DefineCompilationUnit doc - yield doc, unit |] - - let getDocument i = - if i < 0 || i >= Array.length docs then failwith "getDocument: bad doc number" else docs.[i] - - // Sort methods and write them to the MDB file - Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods - for meth in info.Methods do - // Creates an instance of 'SourceMethodImpl' which is a private class that implements 'IMethodDef' interface - // We need this as an argument to 'OpenMethod' below. Using private class is ugly, but since we don't reference - // the assembly, the only way to implement 'IMethodDef' interface would be dynamically using Reflection.Emit... - let sm = createSourceMethodImpl meth.MethName meth.MethToken 0 - match meth.Range with - | Some(mstart, _) -> - // NOTE: 'meth.Params' is not needed, Mono debugger apparently reads this from meta-data - let _, cue = getDocument mstart.Document - wr?OpenMethod(cue, 0, sm) |> ignore - - // Write sequence points - for sp in meth.SequencePoints do - wr?MarkSequencePoint(sp.Offset, cue?get_SourceFile(), sp.Line, sp.Column, false) - - // Walk through the tree of scopes and write all variables - let rec writeScope (scope: PdbMethodScope) = - wr?OpenScope(scope.StartOffset) |> ignore - for local in scope.Locals do - wr?DefineLocalVariable(local.Index, local.Name) - for child in scope.Children do - writeScope child - wr?CloseScope(scope.EndOffset) - match meth.RootScope with - | None -> () - | Some rootscope -> writeScope rootscope - - - // Finished generating debug information for the curretn method - wr?CloseMethod() - | _ -> () - - // Finalize - MDB requires the MVID of the generated .NET module - let moduleGuid = new System.Guid(info.ModuleID |> Array.map byte) - wr?WriteSymbolFile moduleGuid -#endif - -//--------------------------------------------------------------------- -// Dumps debug info into a text file for testing purposes -//--------------------------------------------------------------------- -open Printf - -let logDebugInfo (outfile: string) (info: PdbData) = - use sw = new StreamWriter(new FileStream(outfile + ".debuginfo", FileMode.Create)) - - fprintfn sw "ENTRYPOINT\r\n %b\r\n" info.EntryPoint.IsSome - fprintfn sw "DOCUMENTS" - for i, doc in Seq.zip [0 .. info.Documents.Length-1] info.Documents do - fprintfn sw " [%d] %s" i doc.File - fprintfn sw " Type: %A" doc.DocumentType - fprintfn sw " Language: %A" doc.Language - fprintfn sw " Vendor: %A" doc.Vendor - - // Sort methods (because they are sorted in PDBs/MDBs too) - fprintfn sw "\r\nMETHODS" - Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods - for meth in info.Methods do - fprintfn sw " %s" meth.MethName - fprintfn sw " Params: %A" [ for p in meth.Params -> sprintf "%d: %s" p.Index p.Name ] - fprintfn sw " Range: %A" (meth.Range |> Option.map (fun (f, t) -> - sprintf "[%d,%d:%d] - [%d,%d:%d]" f.Document f.Line f.Column t.Document t.Line t.Column)) - fprintfn sw " Points:" - - for sp in meth.SequencePoints do - fprintfn sw " - Doc: %d Offset:%d [%d:%d]-[%d-%d]" sp.Document sp.Offset sp.Line sp.Column sp.EndLine sp.EndColumn - - // Walk through the tree of scopes and write all variables - fprintfn sw " Scopes:" - let rec writeScope offs (scope: PdbMethodScope) = - fprintfn sw " %s- [%d-%d]" offs scope.StartOffset scope.EndOffset - if scope.Locals.Length > 0 then - fprintfn sw " %s Locals: %A" offs [ for p in scope.Locals -> sprintf "%d: %s" p.Index p.Name ] - for child in scope.Children do writeScope (offs + " ") child - - match meth.RootScope with - | None -> () - | Some rootscope -> writeScope "" rootscope - fprintfn sw "" diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi deleted file mode 100644 index 748e178a461..00000000000 --- a/src/absil/ilwritepdb.fsi +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// The ILPdbWriter -module internal FSharp.Compiler.AbstractIL.ILPdbWriter - -open Internal.Utilities -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range -open System.Collections.Generic -open System.IO -open System.Reflection.Metadata - -type PdbDocumentData = ILSourceDocument - -type PdbLocalVar = - { Name: string - Signature: byte[] - /// the local index the name corresponds to - Index: int32 } - -type PdbMethodScope = - { Children: PdbMethodScope array - StartOffset: int - EndOffset: int - Locals: PdbLocalVar array - (* REVIEW open_namespaces: pdb_namespace array *) } - -type PdbSourceLoc = - { Document: int - Line: int - Column: int } - -type PdbSequencePoint = - { Document: int - Offset: int - Line: int - Column: int - EndLine: int - EndColumn: int } - override ToString: unit -> string - -type PdbMethodData = - { MethToken: int32 - MethName:string - LocalSignatureToken: int32 - Params: PdbLocalVar array - RootScope: PdbMethodScope option - Range: (PdbSourceLoc * PdbSourceLoc) option - SequencePoints: PdbSequencePoint array } - -[] -type PdbData = - { EntryPoint: int32 option - Timestamp: int32 - ModuleID: byte[] // MVID of the generated .NET module (used by MDB files to identify debug info) - Documents: PdbDocumentData[] - Methods: PdbMethodData[] - TableRowCounts: int[] } - - -/// Takes the output file name and returns debug file name. -val getDebugFileName: string -> bool -> string - -/// 28 is the size of the IMAGE_DEBUG_DIRECTORY in ntimage.h -val sizeof_IMAGE_DEBUG_DIRECTORY : System.Int32 -val logDebugInfo : string -> PdbData -> unit - -#if ENABLE_MONO_SUPPORT -val writeMdbInfo<'a> : string -> string -> PdbData -> 'a -#endif - -type BinaryChunk = - { size: int32 - addr: int32 } - -type idd = - { iddCharacteristics: int32; - iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) - iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) - iddType: int32; - iddTimestamp: int32; - iddData: byte[]; - iddChunk: BinaryChunk } - -type HashAlgorithm = - | Sha1 - | Sha256 - -val generatePortablePdb : embedAllSource: bool -> embedSourceList: string list -> sourceLink: string -> checksumAlgorithm: HashAlgorithm -> showTimes: bool -> info: PdbData -> pathMap:PathMap -> (int64 * BlobContentId * MemoryStream * string * byte[]) -val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> (int64 * BlobContentId * MemoryStream) -val embedPortablePdbInfo: uncompressedLength: int64 -> contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> cvChunk: BinaryChunk -> pdbChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[] -val writePortablePdbInfo: contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> pathMap: PathMap -> cvChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPDB: bool -> deterministic: bool -> idd[] - -#if !FX_NO_PDB_WRITER -val writePdbInfo : showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> cvChunk:BinaryChunk -> idd[] -#endif diff --git a/src/absil/ilx.fs b/src/absil/ilx.fs deleted file mode 100644 index 2b364186c98..00000000000 --- a/src/absil/ilx.fs +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Defines an extension of the IL algebra -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.Types - -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library - -// -------------------------------------------------------------------- -// Define an extension of the IL instruction algebra -// -------------------------------------------------------------------- - -let mkLowerName (nm: string) = - // Use the lower case name of a field or constructor as the field/parameter name if it differs from the uppercase name - let lowerName = String.uncapitalize nm - if lowerName = nm then "_" + nm else lowerName - -[] -type IlxUnionField(fd: ILFieldDef) = - let lowerName = mkLowerName fd.Name - member x.ILField = fd - member x.Type = x.ILField.FieldType - member x.Name = x.ILField.Name - member x.LowerName = lowerName - - -type IlxUnionAlternative = - { altName: string - altFields: IlxUnionField[] - altCustomAttrs: ILAttributes } - - member x.FieldDefs = x.altFields - member x.FieldDef n = x.altFields.[n] - member x.Name = x.altName - member x.IsNullary = (x.FieldDefs.Length = 0) - member x.FieldTypes = x.FieldDefs |> Array.map (fun fd -> fd.Type) - -type IlxUnionHasHelpers = - | NoHelpers - | AllHelpers - | SpecialFSharpListHelpers - | SpecialFSharpOptionHelpers - -type IlxUnionRef = - | IlxUnionRef of boxity: ILBoxity * ILTypeRef * IlxUnionAlternative[] * bool * (* hasHelpers: *) IlxUnionHasHelpers - -type IlxUnionSpec = - | IlxUnionSpec of IlxUnionRef * ILGenericArgs - member x.DeclaringType = let (IlxUnionSpec(IlxUnionRef(bx, tref, _, _, _), inst)) = x in mkILNamedTy bx tref inst - member x.Boxity = let (IlxUnionSpec(IlxUnionRef(bx, _, _, _, _), _)) = x in bx - member x.TypeRef = let (IlxUnionSpec(IlxUnionRef(_, tref, _, _, _), _)) = x in tref - member x.GenericArgs = let (IlxUnionSpec(_, inst)) = x in inst - member x.AlternativesArray = let (IlxUnionSpec(IlxUnionRef(_, _, alts, _, _), _)) = x in alts - member x.IsNullPermitted = let (IlxUnionSpec(IlxUnionRef(_, _, _, np, _), _)) = x in np - member x.HasHelpers = let (IlxUnionSpec(IlxUnionRef(_, _, _, _, b), _)) = x in b - member x.Alternatives = Array.toList x.AlternativesArray - member x.Alternative idx = x.AlternativesArray.[idx] - member x.FieldDef idx fidx = x.Alternative(idx).FieldDef(fidx) - - -type IlxClosureLambdas = - | Lambdas_forall of ILGenericParameterDef * IlxClosureLambdas - | Lambdas_lambda of ILParameter * IlxClosureLambdas - | Lambdas_return of ILType - -type IlxClosureApps = - | Apps_tyapp of ILType * IlxClosureApps - | Apps_app of ILType * IlxClosureApps - | Apps_done of ILType - -let rec instAppsAux n inst = function - Apps_tyapp (ty, rty) -> Apps_tyapp(instILTypeAux n inst ty, instAppsAux n inst rty) - | Apps_app (dty, rty) -> Apps_app(instILTypeAux n inst dty, instAppsAux n inst rty) - | Apps_done rty -> Apps_done(instILTypeAux n inst rty) - -let rec instLambdasAux n inst = function - | Lambdas_forall (b, rty) -> - Lambdas_forall(b, instLambdasAux n inst rty) - | Lambdas_lambda (p, rty) -> - Lambdas_lambda({ p with Type=instILTypeAux n inst p.Type}, instLambdasAux n inst rty) - | Lambdas_return rty -> Lambdas_return(instILTypeAux n inst rty) - -let instLambdas i t = instLambdasAux 0 i t - -type IlxClosureFreeVar = - { fvName: string - fvCompilerGenerated:bool - fvType: ILType } - -let mkILFreeVar (name, compgen, ty) = - { fvName=name - fvCompilerGenerated=compgen - fvType=ty } - - -type IlxClosureRef = - | IlxClosureRef of ILTypeRef * IlxClosureLambdas * IlxClosureFreeVar[] - -type IlxClosureSpec = - | IlxClosureSpec of IlxClosureRef * ILGenericArgs * ILType - member x.TypeRef = let (IlxClosureRef(tref, _, _)) = x.ClosureRef in tref - member x.ILType = let (IlxClosureSpec(_, _, ty)) = x in ty - member x.ClosureRef = let (IlxClosureSpec(cloref, _, _)) = x in cloref - member x.FormalFreeVars = let (IlxClosureRef(_, _, fvs)) = x.ClosureRef in fvs - member x.FormalLambdas = let (IlxClosureRef(_, lambdas, _)) = x.ClosureRef in lambdas - member x.GenericArgs = let (IlxClosureSpec(_, inst, _)) = x in inst - static member Create (cloref, inst) = - let (IlxClosureRef(tref, _, _)) = cloref - IlxClosureSpec(cloref, inst, mkILBoxedType (mkILTySpec (tref, inst))) - member clospec.Constructor = - let cloTy = clospec.ILType - let fields = clospec.FormalFreeVars - mkILCtorMethSpecForTy (cloTy, fields |> Array.map (fun fv -> fv.fvType) |> Array.toList) - - -// Define an extension of the IL algebra of type definitions -type IlxClosureInfo = - { cloStructure: IlxClosureLambdas - cloFreeVars: IlxClosureFreeVar[] - cloCode: Lazy } - -type IlxUnionInfo = - { /// is the representation public? - cudReprAccess: ILMemberAccess - /// are the representation public? - cudHelpersAccess: ILMemberAccess - /// generate the helpers? - cudHasHelpers: IlxUnionHasHelpers - /// generate the helpers? - cudDebugProxies: bool - cudDebugDisplayAttributes: ILAttribute list - cudAlternatives: IlxUnionAlternative[] - cudNullPermitted: bool - /// debug info for generated code for classunions - cudWhere: ILSourceMarker option } - -// -------------------------------------------------------------------- -// Define these as extensions of the IL types -// -------------------------------------------------------------------- - -let destTyFuncApp = function Apps_tyapp (b, c) -> b, c | _ -> failwith "destTyFuncApp" - -let mkILFormalCloRef gparams csig = IlxClosureSpec.Create(csig, mkILFormalGenericArgs 0 gparams) - -let actualTypOfIlxUnionField (cuspec : IlxUnionSpec) idx fidx = - instILType cuspec.GenericArgs (cuspec.FieldDef idx fidx).Type - diff --git a/src/absil/ilx.fsi b/src/absil/ilx.fsi deleted file mode 100644 index 657e8353f62..00000000000 --- a/src/absil/ilx.fsi +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// ILX extensions to Abstract IL types and instructions F# -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.Types - -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.IL - -// -------------------------------------------------------------------- -// Union references -// -------------------------------------------------------------------- - -[] -type IlxUnionField = - new : ILFieldDef -> IlxUnionField - member Type : ILType - member Name : string - /// The name used for the field in parameter or IL field position. - member LowerName : string - member ILField : ILFieldDef - -type IlxUnionAlternative = - { altName: string - altFields: IlxUnionField[] - altCustomAttrs: ILAttributes } - - member FieldDefs : IlxUnionField[] - member FieldDef : int -> IlxUnionField - member Name : string - member IsNullary : bool - member FieldTypes : ILType[] - - -type IlxUnionHasHelpers = - | NoHelpers - | AllHelpers - | SpecialFSharpListHelpers - | SpecialFSharpOptionHelpers - -type IlxUnionRef = - | IlxUnionRef of boxity: ILBoxity * ILTypeRef * IlxUnionAlternative[] * bool (* cudNullPermitted *) * IlxUnionHasHelpers (* cudHasHelpers *) - -type IlxUnionSpec = - | IlxUnionSpec of IlxUnionRef * ILGenericArgs - member DeclaringType : ILType - member GenericArgs : ILGenericArgs - member Alternatives : IlxUnionAlternative list - member AlternativesArray : IlxUnionAlternative[] - member Boxity : ILBoxity - member TypeRef : ILTypeRef - member IsNullPermitted : bool - member HasHelpers : IlxUnionHasHelpers - member Alternative : int -> IlxUnionAlternative - member FieldDef : int -> int -> IlxUnionField - -// -------------------------------------------------------------------- -// Closure references -// -------------------------------------------------------------------- - -type IlxClosureLambdas = - | Lambdas_forall of ILGenericParameterDef * IlxClosureLambdas - | Lambdas_lambda of ILParameter * IlxClosureLambdas - | Lambdas_return of ILType - -type IlxClosureFreeVar = - { fvName: string - fvCompilerGenerated:bool - fvType: ILType } - -type IlxClosureRef = - | IlxClosureRef of ILTypeRef * IlxClosureLambdas * IlxClosureFreeVar[] - -type IlxClosureSpec = - | IlxClosureSpec of IlxClosureRef * ILGenericArgs * ILType - - member TypeRef : ILTypeRef - member ILType : ILType - member ClosureRef : IlxClosureRef - member FormalLambdas : IlxClosureLambdas - member GenericArgs : ILGenericArgs - static member Create : IlxClosureRef * ILGenericArgs -> IlxClosureSpec - member Constructor : ILMethodSpec - - -/// IlxClosureApps - i.e. types being applied at a callsite. -type IlxClosureApps = - | Apps_tyapp of ILType * IlxClosureApps - | Apps_app of ILType * IlxClosureApps - | Apps_done of ILType - -// -------------------------------------------------------------------- -// ILX extensions to the kinds of type definitions available -// -------------------------------------------------------------------- - -type IlxClosureInfo = - { cloStructure: IlxClosureLambdas - cloFreeVars: IlxClosureFreeVar[] - cloCode: Lazy } - -type IlxUnionInfo = - { /// Is the representation public? - cudReprAccess: ILMemberAccess - /// Are the representation helpers public? - cudHelpersAccess: ILMemberAccess - /// Generate the helpers? - cudHasHelpers: IlxUnionHasHelpers - cudDebugProxies: bool - cudDebugDisplayAttributes: ILAttribute list - cudAlternatives: IlxUnionAlternative[] - cudNullPermitted: bool - /// Debug info for generated code for classunions. - cudWhere: ILSourceMarker option - } - -// -------------------------------------------------------------------- -// MS-ILX constructs: Closures, thunks, classunions -// -------------------------------------------------------------------- - -val instAppsAux: int -> ILGenericArgs -> IlxClosureApps -> IlxClosureApps -val destTyFuncApp: IlxClosureApps -> ILType * IlxClosureApps - -val mkILFormalCloRef: ILGenericParameterDefs -> IlxClosureRef -> IlxClosureSpec - - -// -------------------------------------------------------------------- -// MS-ILX: Unions -// -------------------------------------------------------------------- - - -val actualTypOfIlxUnionField: IlxUnionSpec -> int -> int -> ILType - -val mkILFreeVar: string * bool * ILType -> IlxClosureFreeVar diff --git a/src/buildtools/AssemblyCheck/AssemblyCheck.fs b/src/buildtools/AssemblyCheck/AssemblyCheck.fs index c6bd035a673..a4f916e2f49 100644 --- a/src/buildtools/AssemblyCheck/AssemblyCheck.fs +++ b/src/buildtools/AssemblyCheck/AssemblyCheck.fs @@ -15,35 +15,51 @@ module AssemblyCheck = let private devVersionPattern = new Regex(@"-(ci|dev)", RegexOptions.Compiled) let verifyEmbeddedPdb (filename:string) = - use fileStream = File.OpenRead(filename) - let reader = new PEReader(fileStream) - let mutable hasEmbeddedPdb = false - - try - for entry in reader.ReadDebugDirectory() do - match entry.Type with - | DebugDirectoryEntryType.CodeView -> - let _ = reader.ReadCodeViewDebugDirectoryData(entry) - () - - | DebugDirectoryEntryType.EmbeddedPortablePdb -> - let _ = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry) - hasEmbeddedPdb <- true - () - - | DebugDirectoryEntryType.PdbChecksum -> - let _ = reader.ReadPdbChecksumDebugDirectoryData(entry) - () - - | _ -> () - with | e -> printfn "Error validating assembly %s\nMessage: %s" filename (e.ToString()) - hasEmbeddedPdb + let isManagedDll = + try + // Is il assembly? throws if not + let _ = AssemblyName.GetAssemblyName(filename).Version + true + with + | :? System.BadImageFormatException -> false // uninterested in embedded pdbs for native dlls + + if isManagedDll then + use fileStream = File.OpenRead(filename) + let reader = new PEReader(fileStream) + let mutable hasEmbeddedPdb = false + + try + for entry in reader.ReadDebugDirectory() do + match entry.Type with + | DebugDirectoryEntryType.CodeView -> + let _ = reader.ReadCodeViewDebugDirectoryData(entry) + () + + | DebugDirectoryEntryType.EmbeddedPortablePdb -> + let _ = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry) + hasEmbeddedPdb <- true + () + + | DebugDirectoryEntryType.PdbChecksum -> + let _ = reader.ReadPdbChecksumDebugDirectoryData(entry) + () + + | _ -> () + with + | e -> printfn "Error validating assembly %s\nMessage: %s" filename (e.ToString()) + + hasEmbeddedPdb + else + true let verifyAssemblies (binariesPath:string) = let excludedAssemblies = - [ "FSharp.Data.TypeProviders.dll" ] - |> Set.ofList + [ ] |> Set.ofList + + let maybeNativeExe = + [ "fsi.exe" + "fsc.exe" ] |> Set.ofList let fsharpAssemblies = [ "FSharp*.dll" @@ -64,8 +80,12 @@ module AssemblyCheck = let failedVersionCheck = fsharpAssemblies |> List.filter (fun a -> - let assemblyVersion = AssemblyName.GetAssemblyName(a).Version - assemblyVersion = versionZero || assemblyVersion = versionOne) + try + let assemblyVersion = AssemblyName.GetAssemblyName(a).Version + assemblyVersion = versionZero || assemblyVersion = versionOne + with | :? System.BadImageFormatException -> + // fsc.exe and fsi.exe are il on the desktop and native on the coreclr + Set.contains (Path.GetFileName(a)) maybeNativeExe |> not) if failedVersionCheck.Length > 0 then printfn "The following assemblies had a version of %A or %A" versionZero versionOne diff --git a/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj b/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj index cde9cb37a7e..464b6ef78c8 100644 --- a/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj +++ b/src/buildtools/AssemblyCheck/AssemblyCheck.fsproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.0 + net5.0 true diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets index 185fd4d0599..86346fc2a15 100644 --- a/src/buildtools/buildtools.targets +++ b/src/buildtools/buildtools.targets @@ -31,6 +31,7 @@ + @@ -54,6 +55,7 @@ + diff --git a/src/buildtools/fslex/Arg.fs b/src/buildtools/fslex/Arg.fs index a1f63bd9638..b1131625cf3 100644 --- a/src/buildtools/fslex/Arg.fs +++ b/src/buildtools/fslex/Arg.fs @@ -52,13 +52,13 @@ type ArgParser() = sbuf.ToString() - static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) = - let other = defaultArg other (fun _ -> ()) + static member ParsePartial(cursor,argv,arguments:seq,?otherArgs,?usageText) = + let otherArgs = defaultArg otherArgs (fun _ -> ()) let usageText = defaultArg usageText "" let nargs = Array.length argv incr cursor; - let argSpecs = argSpecs |> Seq.toList - let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType) + let arguments = arguments |> Seq.toList + let specs = arguments |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType) while !cursor < nargs do let arg = argv.[!cursor] let rec findMatchingArg args = @@ -66,7 +66,7 @@ type ArgParser() = | ((s, action) :: _) when s = arg -> let getSecondArg () = if !cursor + 1 >= nargs then - raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText)); + raise(Bad("option "+s+" needs an argument.\n"+getUsage arguments usageText)); argv.[!cursor+1] match action with @@ -85,12 +85,12 @@ type ArgParser() = cursor := !cursor + 2 | IntArg f -> let arg2 = getSecondArg () - let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage arguments usageText)) in f arg2; cursor := !cursor + 2; | FloatArg f -> let arg2 = getSecondArg() - let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + let arg2 = try float arg2 with _ -> raise(Bad(getUsage arguments usageText)) in f arg2; cursor := !cursor + 2; | RestArg f -> @@ -102,26 +102,26 @@ type ArgParser() = | (_ :: more) -> findMatchingArg more | [] -> if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then - raise (HelpText (getUsage argSpecs usageText)) + raise (HelpText (getUsage arguments usageText)) // Note: for '/abc/def' does not count as an argument // Note: '/abc' does elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then - raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText)) + raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage arguments usageText)) else - other arg; + otherArgs arg; incr cursor findMatchingArg specs - static member Usage (specs,?usage) = + static member Usage (arguments,?usage) = let usage = defaultArg usage "" - System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage) + System.Console.Error.WriteLine (getUsage (Seq.toList arguments) usage) #if FX_NO_COMMAND_LINE_ARGS #else - static member Parse (specs,?other,?usageText) = + static member Parse (arguments,?otherArgs,?usageText) = let current = ref 0 let argv = System.Environment.GetCommandLineArgs() - try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText) + try ArgParser.ParsePartial (current, argv, arguments, ?otherArgs=otherArgs, ?usageText=usageText) with | Bad h | HelpText h -> diff --git a/src/buildtools/fslex/Parsing.fsi b/src/buildtools/fslex/Parsing.fsi index 2fef45975a8..f4d12606462 100644 --- a/src/buildtools/fslex/Parsing.fsi +++ b/src/buildtools/fslex/Parsing.fsi @@ -100,7 +100,7 @@ type Tables<'tok> = /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state. /// Returns an object indicating the final synthesized value for the parse. - member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj + member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * initialState:int -> obj #if INTERNALIZED_FSLEXYACC_RUNTIME exception internal Accept of obj diff --git a/src/buildtools/fslex/fslex.fsproj b/src/buildtools/fslex/fslex.fsproj index e9c7bb0c55d..1959ce59c00 100644 --- a/src/buildtools/fslex/fslex.fsproj +++ b/src/buildtools/fslex/fslex.fsproj @@ -2,8 +2,8 @@ Exe - netcoreapp3.0 - INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstant) + net5.0 + INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstants) true diff --git a/src/buildtools/fsyacc/Arg.fs b/src/buildtools/fsyacc/Arg.fs index a1f63bd9638..b1131625cf3 100644 --- a/src/buildtools/fsyacc/Arg.fs +++ b/src/buildtools/fsyacc/Arg.fs @@ -52,13 +52,13 @@ type ArgParser() = sbuf.ToString() - static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) = - let other = defaultArg other (fun _ -> ()) + static member ParsePartial(cursor,argv,arguments:seq,?otherArgs,?usageText) = + let otherArgs = defaultArg otherArgs (fun _ -> ()) let usageText = defaultArg usageText "" let nargs = Array.length argv incr cursor; - let argSpecs = argSpecs |> Seq.toList - let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType) + let arguments = arguments |> Seq.toList + let specs = arguments |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType) while !cursor < nargs do let arg = argv.[!cursor] let rec findMatchingArg args = @@ -66,7 +66,7 @@ type ArgParser() = | ((s, action) :: _) when s = arg -> let getSecondArg () = if !cursor + 1 >= nargs then - raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText)); + raise(Bad("option "+s+" needs an argument.\n"+getUsage arguments usageText)); argv.[!cursor+1] match action with @@ -85,12 +85,12 @@ type ArgParser() = cursor := !cursor + 2 | IntArg f -> let arg2 = getSecondArg () - let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage arguments usageText)) in f arg2; cursor := !cursor + 2; | FloatArg f -> let arg2 = getSecondArg() - let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + let arg2 = try float arg2 with _ -> raise(Bad(getUsage arguments usageText)) in f arg2; cursor := !cursor + 2; | RestArg f -> @@ -102,26 +102,26 @@ type ArgParser() = | (_ :: more) -> findMatchingArg more | [] -> if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then - raise (HelpText (getUsage argSpecs usageText)) + raise (HelpText (getUsage arguments usageText)) // Note: for '/abc/def' does not count as an argument // Note: '/abc' does elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then - raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText)) + raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage arguments usageText)) else - other arg; + otherArgs arg; incr cursor findMatchingArg specs - static member Usage (specs,?usage) = + static member Usage (arguments,?usage) = let usage = defaultArg usage "" - System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage) + System.Console.Error.WriteLine (getUsage (Seq.toList arguments) usage) #if FX_NO_COMMAND_LINE_ARGS #else - static member Parse (specs,?other,?usageText) = + static member Parse (arguments,?otherArgs,?usageText) = let current = ref 0 let argv = System.Environment.GetCommandLineArgs() - try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText) + try ArgParser.ParsePartial (current, argv, arguments, ?otherArgs=otherArgs, ?usageText=usageText) with | Bad h | HelpText h -> diff --git a/src/buildtools/fsyacc/Parsing.fsi b/src/buildtools/fsyacc/Parsing.fsi index 2fef45975a8..f4d12606462 100644 --- a/src/buildtools/fsyacc/Parsing.fsi +++ b/src/buildtools/fsyacc/Parsing.fsi @@ -100,7 +100,7 @@ type Tables<'tok> = /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state. /// Returns an object indicating the final synthesized value for the parse. - member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj + member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * initialState:int -> obj #if INTERNALIZED_FSLEXYACC_RUNTIME exception internal Accept of obj diff --git a/src/buildtools/fsyacc/fsyacc.fsproj b/src/buildtools/fsyacc/fsyacc.fsproj index fad9941bdc1..5d1b7141f47 100644 --- a/src/buildtools/fsyacc/fsyacc.fsproj +++ b/src/buildtools/fsyacc/fsyacc.fsproj @@ -2,8 +2,8 @@ Exe - netcoreapp3.0 - INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstant) + net5.0 + INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstants) true diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 4070ea9b402..5737933732c 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -7,9 +7,10 @@ open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Infos -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping @@ -18,11 +19,9 @@ open FSharp.Compiler.ExtensionTyping /// Represents the 'keys' a particular piece of code can use to access other constructs?. [] type AccessorDomain = - /// AccessibleFrom(cpaths, tyconRefOpt) - /// /// cpaths: indicates we have the keys to access any members private to the given paths /// tyconRefOpt: indicates we have the keys to access any protected members of the super types of 'TyconRef' - | AccessibleFrom of CompilationPath list * TyconRef option + | AccessibleFrom of cpaths: CompilationPath list * tyconRefOpt: TyconRef option /// An AccessorDomain which returns public items | AccessibleFromEverywhere @@ -45,6 +44,7 @@ type AccessorDomain = | AccessibleFromEverywhere -> 2 | AccessibleFromSomeFSharpCode -> 3 | AccessibleFromSomewhere -> 4 + static member CustomEquals(g:TcGlobals, ad1:AccessorDomain, ad2:AccessorDomain) = match ad1, ad2 with | AccessibleFrom(cs1, tc1), AccessibleFrom(cs2, tc2) -> (cs1 = cs2) && (match tc1, tc2 with None, None -> true | Some tc1, Some tc2 -> tyconRefEq g tc1 tc2 | _ -> false) @@ -145,7 +145,7 @@ let private IsILTypeInfoAccessible amap m ad (tcrefOfViewedItem : TyconRef) = let parentTycon = Import.ImportILTypeRef amap m parentILTyRef check (Some (parentTycon, [x])) xs ) - | (Some (parentTycon, parentPath)) -> + | Some (parentTycon, parentPath) -> match path with | [] -> true // end of path is reached - success | x :: xs -> @@ -207,12 +207,13 @@ and IsTypeInstAccessible g amap m ad tinst = /// Indicate if a provided member is accessible let IsProvidedMemberAccessible (amap:Import.ImportMap) m ad ty access = let g = amap.g - let isTyAccessible = IsTypeAccessible g amap m ad ty - if not isTyAccessible then false + if IsTypeAccessible g amap m ad ty then + match tryTcrefOfAppTy g ty with + | ValueNone -> true + | ValueSome tcrefOfViewedItem -> + IsILMemberAccessible g amap m tcrefOfViewedItem ad access else - not (isAppTy g ty) || - let tcrefOfViewedItem = tcrefOfAppTy g ty - IsILMemberAccessible g amap m tcrefOfViewedItem ad access + false /// Compute the accessibility of a provided member let ComputeILAccess isPublic isFamily isFamilyOrAssembly isFamilyAndAssembly = @@ -222,7 +223,6 @@ let ComputeILAccess isPublic isFamily isFamilyOrAssembly isFamilyAndAssembly = elif isFamilyAndAssembly then ILMemberAccess.FamilyAndAssembly else ILMemberAccess.Private -/// IndiCompute the accessibility of a provided member let IsILFieldInfoAccessible g amap m ad x = match x with | ILFieldInfo (tinfo, fd) -> IsILTypeAndMemberAccessible g amap m ad ad tinfo fd.Access @@ -247,12 +247,53 @@ let private IsILMethInfoAccessible g amap m adType ad ilminfo = let GetILAccessOfILPropInfo (ILPropInfo(tinfo, pdef)) = let tdef = tinfo.RawMetadata let ilAccess = - match pdef.GetMethod with - | Some mref -> (resolveILMethodRef tdef mref).Access - | None -> - match pdef.SetMethod with - | None -> ILMemberAccess.Public - | Some mref -> (resolveILMethodRef tdef mref).Access + match pdef.GetMethod, pdef.SetMethod with + | Some mref, None + | None, Some mref -> (resolveILMethodRef tdef mref).Access + + | Some mrefGet, Some mrefSet -> + // + // Dotnet properties have a getter and a setter method, each of which can have a separate visibility public, protected, private etc ... + // This code computes the visibility for the property by choosing the most visible method. This approximation is usefull for cases + // where the compiler needs to know the visibility of the property. + // The specific ordering for choosing the most visible is: + // ILMemberAccess.Public, + // ILMemberAccess.FamilyOrAssembly + // ILMemberAccess.Assembly + // ILMemberAccess.Family + // ILMemberAccess.FamilyAndAssembly + // ILMemberAccess.Private + // ILMemberAccess.CompilerControlled + // + let getA = (resolveILMethodRef tdef mrefGet).Access + let setA = (resolveILMethodRef tdef mrefSet).Access + + // Use the accessors to determine the visibility of the property. + // N.B. It is critical to keep the ordering in decreasing visibility order in the following match expression + match getA, setA with + | ILMemberAccess.Public, _ + | _, ILMemberAccess.Public -> ILMemberAccess.Public + + | ILMemberAccess.FamilyOrAssembly, _ + | _, ILMemberAccess.FamilyOrAssembly -> ILMemberAccess.FamilyOrAssembly + + | ILMemberAccess.Assembly, _ + | _, ILMemberAccess.Assembly -> ILMemberAccess.Assembly + + | ILMemberAccess.Family, _ + | _, ILMemberAccess.Family -> ILMemberAccess.Family + + | ILMemberAccess.FamilyAndAssembly, _ + | _, ILMemberAccess.FamilyAndAssembly -> ILMemberAccess.FamilyAndAssembly + + | ILMemberAccess.Private, _ + | _, ILMemberAccess.Private -> ILMemberAccess.Private + + | ILMemberAccess.CompilerControlled, _ + | _, ILMemberAccess.CompilerControlled -> ILMemberAccess.CompilerControlled + + | None, None -> ILMemberAccess.Public + ilAccess let IsILPropInfoAccessible g amap m ad pinfo = @@ -321,8 +362,11 @@ let IsMethInfoAccessible amap m ad minfo = IsTypeAndMethInfoAccessible amap m ad let IsPropInfoAccessible g amap m ad = function | ILProp ilpinfo -> IsILPropInfoAccessible g amap m ad ilpinfo - | FSProp (_, _, Some vref, _) - | FSProp (_, _, _, Some vref) -> IsValAccessible ad vref + | FSProp (_, _, Some vref, None) + | FSProp (_, _, None, Some vref) -> IsValAccessible ad vref + | FSProp (_, _, Some vrefGet, Some vrefSet) -> + // pick most accessible + IsValAccessible ad vrefGet || IsValAccessible ad vrefSet #if !NO_EXTENSIONTYPING | ProvidedProp (amap, tppi, m) as pp-> let access = @@ -341,4 +385,3 @@ let IsPropInfoAccessible g amap m ad = function let IsFieldInfoAccessible ad (rfref:RecdFieldInfo) = IsAccessible ad rfref.RecdField.Accessibility - diff --git a/src/fsharp/AccessibilityLogic.fsi b/src/fsharp/AccessibilityLogic.fsi new file mode 100644 index 00000000000..9a9511c2d4e --- /dev/null +++ b/src/fsharp/AccessibilityLogic.fsi @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The basic logic of private/internal/protected/InternalsVisibleTo/public accessibility +module internal FSharp.Compiler.AccessibilityLogic + +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler +open FSharp.Compiler.Import +open FSharp.Compiler.Infos +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +/// Represents the 'keys' a particular piece of code can use to access other constructs?. +[] +type AccessorDomain = + /// cpaths: indicates we have the keys to access any members private to the given paths + /// tyconRefOpt: indicates we have the keys to access any protected members of the super types of 'TyconRef' + | AccessibleFrom of cpaths: CompilationPath list * tyconRefOpt: TyconRef option + + /// An AccessorDomain which returns public items + | AccessibleFromEverywhere + + /// An AccessorDomain which returns everything but .NET private/internal items. + /// This is used + /// - when solving member trait constraints, which are solved independently of accessibility + /// - for failure paths in error reporting, e.g. to produce an error that an F# item is not accessible + /// - an adhoc use in service.fs to look up a delegate signature + | AccessibleFromSomeFSharpCode + + /// An AccessorDomain which returns all items + | AccessibleFromSomewhere + + // Hashing and comparison is used for the memoization tables keyed by an accessor domain. + // It is dependent on a TcGlobals because of the TyconRef in the data structure + static member CustomEquals: g:TcGlobals * ad1:AccessorDomain * ad2:AccessorDomain -> bool + + // Hashing and comparison is used for the memoization tables keyed by an accessor domain. + // It is dependent on a TcGlobals because of the TyconRef in the data structure + static member CustomGetHashCode: ad:AccessorDomain -> int + +/// Indicates if an F# item is accessible +val IsAccessible: ad:AccessorDomain -> taccess:Accessibility -> bool + +/// Indicates if an entity is accessible +val IsEntityAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TyconRef -> bool + +/// Check that an entity is accessible +val CheckTyconAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TyconRef -> bool + +/// Indicates if a type definition and its representation contents are accessible +val IsTyconReprAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TyconRef -> bool + +/// Check that a type definition and its representation contents are accessible +val CheckTyconReprAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TyconRef -> bool + +/// Indicates if a type is accessible (both definition and instantiation) +val IsTypeAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> ty:TType -> bool + +val IsTypeInstAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> tinst:TypeInst -> bool + +/// Indicate if a provided member is accessible +val IsProvidedMemberAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ty:TType -> access:ILMemberAccess -> bool + +/// Compute the accessibility of a provided member +val ComputeILAccess: isPublic:bool -> isFamily:bool -> isFamilyOrAssembly:bool -> isFamilyAndAssembly:bool -> ILMemberAccess + +val IsILFieldInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> x:ILFieldInfo -> bool + +val GetILAccessOfILEventInfo: ILEventInfo -> ILMemberAccess + +val IsILEventInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> einfo:ILEventInfo -> bool + +val GetILAccessOfILPropInfo: ILPropInfo -> ILMemberAccess + +val IsILPropInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> pinfo:ILPropInfo -> bool + +val IsValAccessible: ad:AccessorDomain -> vref:ValRef -> bool + +val CheckValAccessible: m:range -> ad:AccessorDomain -> vref:ValRef -> unit + +val IsUnionCaseAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ucref:TypedTree.UnionCaseRef -> bool + +val CheckUnionCaseAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ucref:TypedTree.UnionCaseRef -> bool + +val IsRecdFieldAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfref:TypedTree.RecdFieldRef -> bool + +val CheckRecdFieldAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfref:TypedTree.RecdFieldRef -> bool + +val CheckRecdFieldInfoAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfinfo:RecdFieldInfo -> unit + +val CheckILFieldInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> finfo:ILFieldInfo -> unit + +val IsTypeAndMethInfoAccessible: amap:ImportMap -> m:range -> accessDomainTy:AccessorDomain -> ad:AccessorDomain -> _arg1:MethInfo -> bool + +val IsMethInfoAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> minfo:MethInfo -> bool + +val IsPropInfoAccessible: g:TcGlobals ->amap:ImportMap -> m:range -> ad:AccessorDomain -> _arg1:PropInfo -> bool + +val IsFieldInfoAccessible: ad:AccessorDomain -> rfref:RecdFieldInfo -> bool diff --git a/src/fsharp/AttributeChecking.fs b/src/fsharp/AttributeChecking.fs index fb19937c53e..71b0fcb8d8a 100644 --- a/src/fsharp/AttributeChecking.fs +++ b/src/fsharp/AttributeChecking.fs @@ -6,20 +6,19 @@ module internal FSharp.Compiler.AttributeChecking open System open System.Collections.Generic +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler -open FSharp.Compiler.Range open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Infos -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping -open Microsoft.FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices #endif exception ObsoleteWarning of string * range @@ -79,6 +78,11 @@ type AttribInfo = | FSAttribInfo of TcGlobals * Attrib | ILAttribInfo of TcGlobals * Import.ImportMap * ILScopeRef * ILAttribute * range + member x.Range = + match x with + | FSAttribInfo(_, attrib) -> attrib.Range + | ILAttribInfo (_, _, _, _, m) -> m + member x.TyconRef = match x with | FSAttribInfo(_g, Attrib(tcref, _, _, _, _, _, _)) -> tcref @@ -94,9 +98,9 @@ type AttribInfo = let ty = tyOfExpr g origExpr let obj = evalFSharpAttribArg g evaluatedExpr ty, obj) - | ILAttribInfo (g, amap, scoref, cattr, m) -> - let parms, _args = decodeILAttribData g.ilg cattr - [ for (argty, argval) in Seq.zip cattr.Method.FormalArgTypes parms -> + | ILAttribInfo (_g, amap, scoref, cattr, m) -> + let parms, _args = decodeILAttribData cattr + [ for argty, argval in Seq.zip cattr.Method.FormalArgTypes parms -> let ty = ImportILType scoref amap m [] argty let obj = evalILAttribElem argval ty, obj ] @@ -109,9 +113,9 @@ type AttribInfo = let ty = tyOfExpr g origExpr let obj = evalFSharpAttribArg g evaluatedExpr ty, nm, isField, obj) - | ILAttribInfo (g, amap, scoref, cattr, m) -> - let _parms, namedArgs = decodeILAttribData g.ilg cattr - [ for (nm, argty, isProp, argval) in namedArgs -> + | ILAttribInfo (_g, amap, scoref, cattr, m) -> + let _parms, namedArgs = decodeILAttribData cattr + [ for nm, argty, isProp, argval in namedArgs -> let ty = ImportILType scoref amap m [] argty let obj = evalILAttribElem argval let isField = not isProp @@ -174,29 +178,6 @@ let GetAttribInfosOfEvent amap m einfo = | ProvidedEvent _ -> [] #endif -/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and -/// provided attributes. -// -// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types) -let TryBindTyconRefAttribute g m (AttribInfo (atref, _) as args) (tcref:TyconRef) f1 f2 f3 = - ignore m; ignore f3 - match metadataOfTycon tcref.Deref with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> - let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)), m) - match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), atref.FullName)), m) with - | Some args -> f3 args - | None -> None -#endif - | ILTypeMetadata (TILObjectReprData(_, _, tdef)) -> - match TryDecodeILAttribute g atref tdef.CustomAttrs with - | Some attr -> f1 attr - | _ -> None - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - match TryFindFSharpAttribute g args tcref.Attribs with - | Some attr -> f2 attr - | _ -> None - /// Analyze three cases for attributes declared on methods: IL-declared attributes, F#-declared attributes and /// provided attributes. let BindMethInfoAttributes m minfo f1 f2 f3 = @@ -211,14 +192,13 @@ let BindMethInfoAttributes m minfo f1 f2 f3 = /// Analyze three cases for attributes declared on methods: IL-declared attributes, F#-declared attributes and /// provided attributes. -let TryBindMethInfoAttribute g m (AttribInfo(atref, _) as attribSpec) minfo f1 f2 f3 = -#if !NO_EXTENSIONTYPING -#else +let TryBindMethInfoAttribute g (m: range) (AttribInfo(atref, _) as attribSpec) minfo f1 f2 f3 = +#if NO_EXTENSIONTYPING // to prevent unused parameter warning ignore f3 #endif BindMethInfoAttributes m minfo - (fun ilAttribs -> TryDecodeILAttribute g atref ilAttribs |> Option.bind f1) + (fun ilAttribs -> TryDecodeILAttribute atref ilAttribs |> Option.bind f1) (fun fsAttribs -> TryFindFSharpAttribute g attribSpec fsAttribs |> Option.bind f2) #if !NO_EXTENSIONTYPING (fun provAttribs -> @@ -232,11 +212,11 @@ let TryBindMethInfoAttribute g m (AttribInfo(atref, _) as attribSpec) minfo f1 f /// Try to find a specific attribute on a method, where the attribute accepts a string argument. /// /// This is just used for the 'ConditionalAttribute' attribute -let TryFindMethInfoStringAttribute g m attribSpec minfo = +let TryFindMethInfoStringAttribute g (m: range) attribSpec minfo = TryBindMethInfoAttribute g m attribSpec minfo - (function ([ILAttribElem.String (Some msg) ], _) -> Some msg | _ -> None) - (function (Attrib(_, _, [ AttribStringArg msg ], _, _, _, _)) -> Some msg | _ -> None) - (function ([ Some ((:? string as msg) : obj) ], _) -> Some msg | _ -> None) + (function [ILAttribElem.String (Some msg) ], _ -> Some msg | _ -> None) + (function Attrib(_, _, [ AttribStringArg msg ], _, _, _, _) -> Some msg | _ -> None) + (function [ Some (:? string as msg : obj) ], _ -> Some msg | _ -> None) /// Check if a method has a specific attribute. let MethInfoHasAttribute g m attribSpec minfo = @@ -250,7 +230,7 @@ let MethInfoHasAttribute g m attribSpec minfo = /// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m = let (AttribInfo(tref,_)) = g.attrib_SystemObsolete - match TryDecodeILAttribute g tref cattrs with + match TryDecodeILAttribute tref cattrs with | Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef -> WarnD(ObsoleteWarning(msg, m)) | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) when not isByrefLikeTyconRef -> @@ -265,9 +245,10 @@ let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m = | _ -> CompleteD +let langVersionPrefix = "--langversion:preview" + /// Check F# attributes for 'ObsoleteAttribute', 'CompilerMessageAttribute' and 'ExperimentalAttribute', /// returning errors and warnings as data -let langVersionPrefix = "--langversion:preview" let CheckFSharpAttributes (g:TcGlobals) attribs m = let isExperimentalAttributeDisabled (s:string) = if g.compilingFslib then @@ -298,7 +279,11 @@ let CheckFSharpAttributes (g:TcGlobals) attribs m = match namedArgs with | ExtractAttribNamedArg "IsError" (AttribBoolArg v) -> v | _ -> false - if isError && (not g.compilingFslib || n <> 1204) then ErrorD msg else WarnD msg + // If we are using a compiler that supports nameof then error 3501 is always suppressed. + // See attribute on FSharp.Core 'nameof' + if n = 3501 then CompleteD + elif isError && (not g.compilingFslib || n <> 1204) then ErrorD msg + else WarnD msg | _ -> CompleteD ) ++ (fun () -> @@ -344,7 +329,7 @@ let private CheckProvidedAttributes (g: TcGlobals) m (provAttribs: Tainted) m = - provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), typeof.FullName).IsSome), m) + provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), typeof.FullName).IsSome), m) #endif /// Check the attributes associated with a property, returning warnings and errors as data. @@ -428,7 +413,7 @@ let CheckMethInfoAttributes g m tyargsOpt minfo = /// Indicate if a method has 'Obsolete', 'CompilerMessageAttribute' or 'TypeProviderEditorHideMethodsAttribute'. /// Used to suppress the item in intellisense. -let MethInfoIsUnseen g m ty minfo = +let MethInfoIsUnseen g (m: range) (ty: TType) minfo = let isUnseenByObsoleteAttrib () = match BindMethInfoAttributes m minfo (fun ilAttribs -> Some(CheckILAttributesForUnseen g ilAttribs m)) @@ -449,7 +434,7 @@ let MethInfoIsUnseen g m ty minfo = isObjTy g minfo.ApparentEnclosingType && let tcref = tcrefOfAppTy g ty match tcref.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> + | TProvidedTypeRepr info -> info.ProvidedType.PUntaint((fun st -> (st :> IProvidedCustomAttributeProvider).GetHasTypeProviderEditorHideMethodsAttribute(info.ProvidedType.TypeProvider.PUntaintNoFailure(id))), m) | _ -> // This attribute check is done by name to ensure compilation doesn't take a dependency diff --git a/src/fsharp/AttributeChecking.fsi b/src/fsharp/AttributeChecking.fsi new file mode 100644 index 00000000000..1c8bb25e22a --- /dev/null +++ b/src/fsharp/AttributeChecking.fsi @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Logic associated with checking "ObsoleteAttribute" and other attributes +/// on items from name resolution +module internal FSharp.Compiler.AttributeChecking + +open System.Collections.Generic +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Infos +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +exception ObsoleteWarning of string * range + +exception ObsoleteError of string * range + +type AttribInfo = + | FSAttribInfo of TcGlobals * Attrib + | ILAttribInfo of TcGlobals * Import.ImportMap * ILScopeRef * ILAttribute * range + member ConstructorArguments: (TType * obj) list + member NamedArguments: (TType * string * bool * obj) list + member Range: range + member TyconRef: TyconRef + +val AttribInfosOfIL: g:TcGlobals -> amap:Import.ImportMap -> scoref:ILScopeRef -> m:range -> attribs:ILAttributes -> AttribInfo list + +val GetAttribInfosOfEntity: g:TcGlobals -> amap:Import.ImportMap -> m:range -> tcref:TyconRef -> AttribInfo list + +val GetAttribInfosOfMethod: amap:Import.ImportMap -> m:range -> minfo:MethInfo -> AttribInfo list + +val GetAttribInfosOfProp: amap:Import.ImportMap -> m:range -> pinfo:PropInfo -> AttribInfo list + +val GetAttribInfosOfEvent: amap:Import.ImportMap -> m:range -> einfo:EventInfo -> AttribInfo list + +#if NO_EXTENSIONTYPING +val TryBindMethInfoAttribute: g:TcGlobals -> m:range -> BuiltinAttribInfo -> minfo:MethInfo -> f1:(ILAttribElem list * ILAttributeNamedArg list -> 'a option) -> f2:(Attrib -> 'a option) -> f3: _ -> 'a option +#else +val TryBindMethInfoAttribute: g:TcGlobals -> m:range -> BuiltinAttribInfo -> minfo:MethInfo -> f1:(ILAttribElem list * ILAttributeNamedArg list -> 'a option) -> f2:(Attrib -> 'a option) -> f3:(obj option list * (string * obj option) list -> 'a option) -> 'a option +#endif + +val TryFindMethInfoStringAttribute: g:TcGlobals -> m:range -> attribSpec:BuiltinAttribInfo -> minfo:MethInfo -> string option + +val MethInfoHasAttribute: g:TcGlobals -> m:range -> attribSpec:BuiltinAttribInfo -> minfo:MethInfo -> bool + +val CheckFSharpAttributes: g:TcGlobals -> attribs:Attrib list -> m:range -> OperationResult + +val CheckILAttributesForUnseen: g:TcGlobals -> cattrs:ILAttributes -> _m:'a -> bool + +val CheckFSharpAttributesForHidden: g:TcGlobals -> attribs:Attrib list -> bool + +val CheckFSharpAttributesForObsolete: g:TcGlobals -> attribs:Attrib list -> bool + +val CheckFSharpAttributesForUnseen: g:TcGlobals -> attribs:Attrib list -> _m:'a -> bool + +val CheckPropInfoAttributes: pinfo:PropInfo -> m:range -> OperationResult + +val CheckILFieldAttributes: g:TcGlobals -> finfo:ILFieldInfo -> m:range -> unit + +val CheckMethInfoAttributes: g:TcGlobals -> m:range -> tyargsOpt:'a option -> minfo:MethInfo -> OperationResult + +val MethInfoIsUnseen: g:TcGlobals -> m:range -> ty:TType -> minfo:MethInfo -> bool + +val PropInfoIsUnseen: m:'a -> pinfo:PropInfo -> bool + +val CheckEntityAttributes: g:TcGlobals -> x:TyconRef -> m:range -> OperationResult + +val CheckUnionCaseAttributes: g:TcGlobals -> x:UnionCaseRef -> m:range -> OperationResult + +val CheckRecdFieldAttributes: g:TcGlobals -> x:RecdFieldRef -> m:range -> OperationResult + +val CheckValAttributes: g:TcGlobals -> x:ValRef -> m:range -> OperationResult + +val CheckRecdFieldInfoAttributes: g:TcGlobals -> x:RecdFieldInfo -> m:range -> OperationResult + +val IsSecurityAttribute: g:TcGlobals -> amap:Import.ImportMap -> casmap:Dictionary -> Attrib -> m:range -> bool + +val IsSecurityCriticalAttribute: g:TcGlobals -> Attrib -> bool + diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs index ce562dedaa4..aa69ea08050 100644 --- a/src/fsharp/AugmentWithHashCompare.fs +++ b/src/fsharp/AugmentWithHashCompare.fs @@ -3,15 +3,16 @@ /// Generate the hash/compare functions we add to user-defined types by default. module internal FSharp.Compiler.AugmentWithHashCompare -open FSharp.Compiler.AbstractIL +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.TcGlobals open FSharp.Compiler.Infos +open FSharp.Compiler.Syntax +open FSharp.Compiler.Xml +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps let mkIComparableCompareToSlotSig (g: TcGlobals) = TSlotSig("CompareTo", g.mk_IComparable_ty, [], [], [[TSlotParam(Some("obj"), g.obj_ty, false, false, false, [])]], Some g.int_ty) @@ -65,9 +66,9 @@ let mkHashWithComparerTy g ty = (mkThisTy g ty) --> (g.IEqualityComparer_ty --> let mkRelBinOp (g: TcGlobals) op m e1 e2 = mkAsmExpr ([ op ], [], [e1; e2], [g.bool_ty], m) -let mkClt g m e1 e2 = mkRelBinOp g IL.AI_clt m e1 e2 +let mkClt g m e1 e2 = mkRelBinOp g AI_clt m e1 e2 -let mkCgt g m e1 e2 = mkRelBinOp g IL.AI_cgt m e1 e2 +let mkCgt g m e1 e2 = mkRelBinOp g AI_cgt m e1 e2 //------------------------------------------------------------------------- // REVIEW: make this a .constrained call, not a virtual call. @@ -81,20 +82,20 @@ let mkILLangPrimTy (g: TcGlobals) = mkILNonGenericBoxedTy g.tcref_LanguagePrimit let mkILCallGetComparer (g: TcGlobals) m = let ty = mkILNonGenericBoxedTy g.tcref_System_Collections_IComparer.CompiledRepresentationForNamedType let mspec = mkILNonGenericStaticMethSpecInTy (mkILLangPrimTy g, "get_GenericComparer", [], ty) - mkAsmExpr ([IL.mkNormalCall mspec], [], [], [g.IComparer_ty], m) + mkAsmExpr ([mkNormalCall mspec], [], [], [g.IComparer_ty], m) let mkILCallGetEqualityComparer (g: TcGlobals) m = let ty = mkILNonGenericBoxedTy g.tcref_System_Collections_IEqualityComparer.CompiledRepresentationForNamedType let mspec = mkILNonGenericStaticMethSpecInTy (mkILLangPrimTy g, "get_GenericEqualityComparer", [], ty) - mkAsmExpr ([IL.mkNormalCall mspec], [], [], [g.IEqualityComparer_ty], m) + mkAsmExpr ([mkNormalCall mspec], [], [], [g.IEqualityComparer_ty], m) let mkThisVar g m ty = mkCompGenLocal m "this" (mkThisTy g ty) -let mkShl g m acce n = mkAsmExpr ([ IL.AI_shl ], [], [acce; mkInt g m n], [g.int_ty], m) +let mkShl g m acce n = mkAsmExpr ([ AI_shl ], [], [acce; mkInt g m n], [g.int_ty], m) -let mkShr g m acce n = mkAsmExpr ([ IL.AI_shr ], [], [acce; mkInt g m n], [g.int_ty], m) +let mkShr g m acce n = mkAsmExpr ([ AI_shr ], [], [acce; mkInt g m n], [g.int_ty], m) -let mkAdd (g: TcGlobals) m e1 e2 = mkAsmExpr ([ IL.AI_add ], [], [e1;e2], [g.int_ty], m) +let mkAdd (g: TcGlobals) m e1 e2 = mkAsmExpr ([ AI_add ], [], [e1;e2], [g.int_ty], m) let mkAddToHashAcc g m e accv acce = mkValSet m accv (mkAdd g m (mkInt g m 0x9e3779b9) @@ -156,10 +157,10 @@ let mkCompareTestConjuncts g m exprs = (a, b) ||> List.foldBack (fun e acc -> let nv, ne = mkCompGenLocal m "n" g.int_ty mkCompGenLet m nv e - (mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.int_ty + (mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.int_ty (mkClt g m ne (mkZero g m)) ne - (mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.int_ty + (mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.int_ty (mkCgt g m ne (mkZero g m)) ne acc))) @@ -170,7 +171,7 @@ let mkEqualsTestConjuncts g m exprs = | [h] -> h | l -> let a, b = List.frontAndBack l - List.foldBack (fun e acc -> mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.bool_ty e acc (mkFalse g m)) a b + List.foldBack (fun e acc -> mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.bool_ty e acc (mkFalse g m)) a b let mkMinimalTy (g: TcGlobals) (tcref: TyconRef) = if tcref.Deref.IsExceptionDecl then [], g.exn_ty @@ -217,7 +218,6 @@ let mkRecdCompare g tcref (tycon: Tycon) = let thatv, expr = mkThatVarBind g m ty thataddrv expr thisv, thatv, expr - /// Build the comparison implementation for a record type when parameterized by a comparer let mkRecdCompareWithComparer g tcref (tycon: Tycon) (_thisv, thise) (_, thate) compe = let m = tycon.Range @@ -243,7 +243,6 @@ let mkRecdCompareWithComparer g tcref (tycon: Tycon) (_thisv, thise) (_, thate) let expr = mkCompGenLet m tcv thate expr expr - /// Build the .Equals(that) equality implementation wrapper for a record type let mkRecdEquality g tcref (tycon: Tycon) = let m = tycon.Range @@ -301,18 +300,17 @@ let mkExnEquality (g: TcGlobals) exnref (exnc: Tycon) = (mkExnCaseFieldGet(thate, exnref, i, m)) let expr = mkEqualsTestConjuncts g m (List.mapi mkTest exnc.AllInstanceFieldsAsList) let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let cases = [ mkCase(DecisionTreeTest.IsInst(g.exn_ty, mkAppTy exnref []), - mbuilder.AddResultTarget(expr, SuppressSequencePointAtTarget)) ] - let dflt = Some(mbuilder.AddResultTarget(mkFalse g m, SuppressSequencePointAtTarget)) - let dtree = TDSwitch(thate, cases, dflt, m) + mbuilder.AddResultTarget(expr, DebugPointAtTarget.No)) ] + let dflt = Some(mbuilder.AddResultTarget(mkFalse g m, DebugPointAtTarget.No)) + let dtree = TDSwitch(DebugPointAtSwitch.No, thate, cases, dflt, m) mbuilder.Close(dtree, m, g.bool_ty) let expr = mkBindThatNullEquals g m thise thate expr thisv, thatv, expr - /// Build the equality implementation for an exception definition when parameterized by a comparer let mkExnEqualityWithComparer g exnref (exnc: Tycon) (_thisv, thise) thatobje (thatv, thate) compe = let m = exnc.Range @@ -325,12 +323,12 @@ let mkExnEqualityWithComparer g exnref (exnc: Tycon) (_thisv, thise) thatobje (t (mkExnCaseFieldGet(thataddre, exnref, i, m)) let expr = mkEqualsTestConjuncts g m (List.mapi mkTest exnc.AllInstanceFieldsAsList) let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let cases = [ mkCase(DecisionTreeTest.IsInst(g.exn_ty, mkAppTy exnref []), - mbuilder.AddResultTarget(expr, SuppressSequencePointAtTarget)) ] - let dflt = mbuilder.AddResultTarget(mkFalse g m, SuppressSequencePointAtTarget) - let dtree = TDSwitch(thate, cases, Some dflt, m) + mbuilder.AddResultTarget(expr, DebugPointAtTarget.No)) ] + let dflt = mbuilder.AddResultTarget(mkFalse g m, DebugPointAtTarget.No) + let dtree = TDSwitch(DebugPointAtSwitch.No, thate, cases, Some dflt, m) mbuilder.Close(dtree, m, g.bool_ty) let expr = mkBindThatAddr g m g.exn_ty thataddrv thatv thate expr let expr = mkIsInstConditional g m g.exn_ty thatobje thatv expr (mkFalse g m) @@ -348,7 +346,7 @@ let mkUnionCompare g tcref (tycon: Tycon) = let compe = mkILCallGetComparer g m let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let mkCase ucase = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range @@ -368,22 +366,22 @@ let mkUnionCompare g tcref (tycon: Tycon) = mkCompGenLet m thisucv (mkUnionCaseProof (thise, cref, tinst, m)) (mkCompGenLet m thatucv (mkUnionCaseProof (thataddre, cref, tinst, m)) (mkCompareTestConjuncts g m (List.mapi (mkTest thisucve thatucve) rfields))) - Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, SuppressSequencePointAtTarget))) + Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, DebugPointAtTarget.No))) let nullary, nonNullary = List.partition Option.isNone (List.map mkCase ucases) if isNil nonNullary then mkZero g m else - let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionCompare") - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m, SuppressSequencePointAtTarget)) - let dtree = TDSwitch(thise, cases, dflt, m) + let cases = nonNullary |> List.map (function Some c -> c | None -> failwith "mkUnionCompare") + let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m, DebugPointAtTarget.No)) + let dtree = TDSwitch(DebugPointAtSwitch.No, thise, cases, dflt, m) mbuilder.Close(dtree, m, g.int_ty) let expr = if ucases.Length = 1 then expr else let tagsEqTested = - mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.int_ty + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.int_ty (mkILAsmCeq g m thistage thattage) expr - (mkAsmExpr ([ IL.AI_sub ], [], [thistage; thattage], [g.int_ty], m))in + (mkAsmExpr ([ AI_sub ], [], [thistage; thattage], [g.int_ty], m))in mkCompGenLet m thistagv (mkUnionCaseTagGetViaExprAddr (thise, tcref, tinst, m)) (mkCompGenLet m thattagv @@ -406,7 +404,7 @@ let mkUnionCompareWithComparer g tcref (tycon: Tycon) (_thisv, thise) (_thatobjv let thattagv, thattage = mkCompGenLocal m "thatTag" g.int_ty let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let mkCase ucase = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range @@ -429,22 +427,22 @@ let mkUnionCompareWithComparer g tcref (tycon: Tycon) (_thisv, thise) (_thatobjv (mkCompGenLet m thatucv (mkUnionCaseProof (thataddre, cref, tinst, m)) (mkCompareTestConjuncts g m (List.mapi (mkTest thisucve thatucve) rfields))) - Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, SuppressSequencePointAtTarget))) + Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, DebugPointAtTarget.No))) let nullary, nonNullary = List.partition Option.isNone (List.map mkCase ucases) if isNil nonNullary then mkZero g m else - let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionCompare") - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m, SuppressSequencePointAtTarget)) - let dtree = TDSwitch(thise, cases, dflt, m) + let cases = nonNullary |> List.map (function Some c -> c | None -> failwith "mkUnionCompare") + let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m, DebugPointAtTarget.No)) + let dtree = TDSwitch(DebugPointAtSwitch.No, thise, cases, dflt, m) mbuilder.Close(dtree, m, g.int_ty) let expr = if ucases.Length = 1 then expr else let tagsEqTested = - mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.int_ty + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.int_ty (mkILAsmCeq g m thistage thattage) expr - (mkAsmExpr ([ IL.AI_sub ], [], [thistage; thattage], [g.int_ty], m)) + (mkAsmExpr ([ AI_sub ], [], [thistage; thattage], [g.int_ty], m)) mkCompGenLet m thistagv (mkUnionCaseTagGetViaExprAddr (thise, tcref, tinst, m)) (mkCompGenLet m thattagv @@ -467,7 +465,7 @@ let mkUnionEquality g tcref (tycon: Tycon) = let thattagv, thattage = mkCompGenLocal m "thatTag" g.int_ty let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let mkCase ucase = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range @@ -489,19 +487,19 @@ let mkUnionEquality g tcref (tycon: Tycon) = (mkCompGenLet m thatucv (mkUnionCaseProof (thataddre, cref, tinst, m)) (mkEqualsTestConjuncts g m (List.mapi (mkTest thisucve thatucve) rfields))) - Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, SuppressSequencePointAtTarget))) + Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget(test, DebugPointAtTarget.No))) let nullary, nonNullary = List.partition Option.isNone (List.map mkCase ucases) if isNil nonNullary then mkTrue g m else - let cases = List.map (function (Some c) -> c | None -> failwith "mkUnionEquality") nonNullary - let dflt = (if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m, SuppressSequencePointAtTarget))) - let dtree = TDSwitch(thise, cases, dflt, m) + let cases = List.map (function Some c -> c | None -> failwith "mkUnionEquality") nonNullary + let dflt = (if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m, DebugPointAtTarget.No))) + let dtree = TDSwitch(DebugPointAtSwitch.No, thise, cases, dflt, m) mbuilder.Close(dtree, m, g.bool_ty) let expr = if ucases.Length = 1 then expr else let tagsEqTested = - mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.bool_ty + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.bool_ty (mkILAsmCeq g m thistage thattage) expr (mkFalse g m) @@ -526,7 +524,7 @@ let mkUnionEqualityWithComparer g tcref (tycon: Tycon) (_thisv, thise) thatobje let thataddrv, thataddre = mkThatAddrLocal g m ty let expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let mkCase ucase = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range @@ -551,19 +549,19 @@ let mkUnionEqualityWithComparer g tcref (tycon: Tycon) (_thisv, thise) thatobje (mkCompGenLet m thatucv (mkUnionCaseProof (thataddre, cref, tinst, m)) (mkEqualsTestConjuncts g m (List.mapi (mkTest thisucve thatucve) rfields))) - Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget (test, SuppressSequencePointAtTarget))) + Some (mkCase(DecisionTreeTest.UnionCase(cref, tinst), mbuilder.AddResultTarget (test, DebugPointAtTarget.No))) let nullary, nonNullary = List.partition Option.isNone (List.map mkCase ucases) if isNil nonNullary then mkTrue g m else - let cases = List.map (function (Some c) -> c | None -> failwith "mkUnionEquality") nonNullary - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m, SuppressSequencePointAtTarget)) - let dtree = TDSwitch(thise, cases, dflt, m) + let cases = List.map (function Some c -> c | None -> failwith "mkUnionEquality") nonNullary + let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m, DebugPointAtTarget.No)) + let dtree = TDSwitch(DebugPointAtSwitch.No, thise, cases, dflt, m) mbuilder.Close(dtree, m, g.bool_ty) let expr = if ucases.Length = 1 then expr else let tagsEqTested = - mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.bool_ty + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.bool_ty (mkILAsmCeq g m thistage thattage) expr (mkFalse g m) @@ -626,7 +624,7 @@ let mkUnionHashWithComparer g tcref (tycon: Tycon) compe = let ucases = tycon.UnionCasesAsList let tinst, ty = mkMinimalTy g tcref let thisv, thise = mkThisVar g m ty - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) let accv, acce = mkMutableCompGenLocal m "i" g.int_ty let mkCase i ucase1 = let c1ref = tcref.MakeNestedUnionCaseRef ucase1 @@ -650,17 +648,17 @@ let mkUnionHashWithComparer g tcref (tycon: Tycon) compe = (mkCompGenSequential m (mkValSet m (mkLocalValRef accv) (mkInt g m i)) (mkCombineHashGenerators g m (List.mapi (mkHash ucve) ucase1.RecdFields) (mkLocalValRef accv) acce)) - Some(mkCase(DecisionTreeTest.UnionCase(c1ref, tinst), mbuilder.AddResultTarget(test, SuppressSequencePointAtTarget))) + Some(mkCase(DecisionTreeTest.UnionCase(c1ref, tinst), mbuilder.AddResultTarget(test, DebugPointAtTarget.No))) let nullary, nonNullary = ucases |> List.mapi mkCase |> List.partition (fun i -> i.IsNone) - let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionHash") + let cases = nonNullary |> List.map (function Some c -> c | None -> failwith "mkUnionHash") let dflt = if isNil nullary then None else let tag = mkUnionCaseTagGetViaExprAddr (thise, tcref, tinst, m) - Some(mbuilder.AddResultTarget(tag, SuppressSequencePointAtTarget)) - let dtree = TDSwitch(thise, cases, dflt, m) + Some(mbuilder.AddResultTarget(tag, DebugPointAtTarget.No)) + let dtree = TDSwitch(DebugPointAtSwitch.No, thise, cases, dflt, m) let stmt = mbuilder.Close(dtree, m, g.int_ty) let expr = mkCompGenLet m accv (mkZero g m) stmt let expr = if tycon.IsStructOrEnumTycon then expr else mkBindNullHash g m thise expr @@ -744,10 +742,9 @@ let CheckAugmentationAttribs isImplementation g amap (tycon: Tycon) = // [] on anything | _, _, Some true, None, None, None, Some true, None, None -> - () - (* THESE ARE THE ERROR CASES *) + // THESE ARE THE ERROR CASES // [] | _, _, Some true, _, _, _, None, _, _ -> @@ -866,7 +863,7 @@ let slotImplMethod (final, c, slotsig) : ValMemberInfo = IsDispatchSlot=false IsFinal=final IsOverrideOrExplicitImpl=true - MemberKind=MemberKind.Member} + MemberKind=SynMemberKind.Member} IsImplemented=false ApparentEnclosingEntity=c} @@ -876,22 +873,26 @@ let nonVirtualMethod c : ValMemberInfo = IsDispatchSlot=false IsFinal=false IsOverrideOrExplicitImpl=false - MemberKind=MemberKind.Member} + MemberKind=SynMemberKind.Member} IsImplemented=false ApparentEnclosingEntity=c} let unitArg = ValReprInfo.unitArgData let unaryArg = [ ValReprInfo.unnamedTopArg ] let tupArg = [ [ ValReprInfo.unnamedTopArg1; ValReprInfo.unnamedTopArg1 ] ] -let mkValSpec g (tcref: TyconRef) tmty vis slotsig methn ty argData = +let mkValSpec g (tcref: TyconRef) tmty vis slotsig methn ty argData = let m = tcref.Range let tps = tcref.Typars m - let final = isUnionTy g tmty || isRecdTy g tmty || isStructTy g tmty - let membInfo = match slotsig with None -> nonVirtualMethod tcref | Some slotsig -> slotImplMethod(final, tcref, slotsig) + let membInfo = + match slotsig with + | None -> nonVirtualMethod tcref + | Some slotsig -> + let final = isUnionTy g tmty || isRecdTy g tmty || isStructTy g tmty + slotImplMethod(final, tcref, slotsig) let inl = ValInline.Optional let args = ValReprInfo.unnamedTopArg :: argData let topValInfo = Some (ValReprInfo (ValReprInfo.InferTyparInfo tps, args, ValReprInfo.unnamedRetVal)) - NewVal (methn, m, None, ty, Immutable, true, topValInfo, vis, ValNotInRecScope, Some membInfo, NormalVal, [], inl, XmlDoc.Empty, true, false, false, false, false, false, None, Parent tcref) + Construct.NewVal (methn, m, None, ty, Immutable, true, topValInfo, vis, ValNotInRecScope, Some membInfo, NormalVal, [], inl, XmlDoc.Empty, true, false, false, false, false, false, None, Parent tcref) let MakeValsForCompareAugmentation g (tcref: TyconRef) = let m = tcref.Range @@ -899,8 +900,8 @@ let MakeValsForCompareAugmentation g (tcref: TyconRef) = let tps = tcref.Typars m let vis = tcref.TypeReprAccessibility - mkValSpec g tcref tmty vis (Some(mkIComparableCompareToSlotSig g)) "CompareTo" (tps +-> (mkCompareObjTy g tmty)) unaryArg, - mkValSpec g tcref tmty vis (Some(mkGenericIComparableCompareToSlotSig g tmty)) "CompareTo" (tps +-> (mkCompareTy g tmty)) unaryArg + mkValSpec g tcref tmty vis (Some(mkIComparableCompareToSlotSig g)) "CompareTo" (tps +-> (mkCompareObjTy g tmty)) unaryArg, + mkValSpec g tcref tmty vis (Some(mkGenericIComparableCompareToSlotSig g tmty)) "CompareTo" (tps +-> (mkCompareTy g tmty)) unaryArg let MakeValsForCompareWithComparerAugmentation g (tcref: TyconRef) = let m = tcref.Range @@ -915,15 +916,15 @@ let MakeValsForEqualsAugmentation g (tcref: TyconRef) = let vis = tcref.TypeReprAccessibility let tps = tcref.Typars m - let objEqualsVal = mkValSpec g tcref tmty vis (Some(mkEqualsSlotSig g)) "Equals" (tps +-> (mkEqualsObjTy g tmty)) unaryArg - let nocEqualsVal = mkValSpec g tcref tmty vis (if tcref.Deref.IsExceptionDecl then None else Some(mkGenericIEquatableEqualsSlotSig g tmty)) "Equals" (tps +-> (mkEqualsTy g tmty)) unaryArg + let objEqualsVal = mkValSpec g tcref tmty vis (Some(mkEqualsSlotSig g)) "Equals" (tps +-> (mkEqualsObjTy g tmty)) unaryArg + let nocEqualsVal = mkValSpec g tcref tmty vis (if tcref.Deref.IsExceptionDecl then None else Some(mkGenericIEquatableEqualsSlotSig g tmty)) "Equals" (tps +-> (mkEqualsTy g tmty)) unaryArg objEqualsVal, nocEqualsVal let MakeValsForEqualityWithComparerAugmentation g (tcref: TyconRef) = let _, tmty = mkMinimalTy g tcref let vis = tcref.TypeReprAccessibility let tps = tcref.Typars tcref.Range - let objGetHashCodeVal = mkValSpec g tcref tmty vis (Some(mkGetHashCodeSlotSig g)) "GetHashCode" (tps +-> (mkHashTy g tmty)) unitArg + let objGetHashCodeVal = mkValSpec g tcref tmty vis (Some(mkGetHashCodeSlotSig g)) "GetHashCode" (tps +-> (mkHashTy g tmty)) unitArg let withcGetHashCodeVal = mkValSpec g tcref tmty vis (Some(mkIStructuralEquatableGetHashCodeSlotSig g)) "GetHashCode" (tps +-> (mkHashWithComparerTy g tmty)) unaryArg let withcEqualsVal = mkValSpec g tcref tmty vis (Some(mkIStructuralEquatableEqualsSlotSig g)) "Equals" (tps +-> (mkEqualsWithComparerTy g tmty)) tupArg objGetHashCodeVal, withcGetHashCodeVal, withcEqualsVal @@ -1071,23 +1072,28 @@ let MakeBindingsForEqualsAugmentation (g: TcGlobals) (tycon: Tycon) = elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then mkEquals mkRecdEquality else [] -let rec TypeDefinitelyHasEquality g ty = - if isAppTy g ty && HasFSharpAttribute g g.attrib_NoEqualityAttribute (tcrefOfAppTy g ty).Attribs then +let rec TypeDefinitelyHasEquality g ty = + let appTy = tryAppTy g ty + match appTy with + | ValueSome(tcref,_) when HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs -> false - elif isTyparTy g ty && - (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then - true - else - match ty with - | SpecialEquatableHeadType g tinst -> - tinst |> List.forall (TypeDefinitelyHasEquality g) - | SpecialNotEquatableHeadType g _ -> - false - | _ -> - // The type is equatable because it has Object.Equals(...) - isAppTy g ty && - let tcref, tinst = destAppTy g ty - // Give a good error for structural types excluded from the equality relation because of their fields - not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) && - // Check the (possibly inferred) structural dependencies - (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> not tp.EqualityConditionalOn || TypeDefinitelyHasEquality g ty) + | _ -> + if isTyparTy g ty && + (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then + true + else + match ty with + | SpecialEquatableHeadType g tinst -> + tinst |> List.forall (TypeDefinitelyHasEquality g) + | SpecialNotEquatableHeadType g _ -> + false + | _ -> + // The type is equatable because it has Object.Equals(...) + match appTy with + | ValueSome(tcref,tinst) -> + // Give a good error for structural types excluded from the equality relation because of their fields + not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) && + // Check the (possibly inferred) structural dependencies + (tinst, tcref.TyparsNoRange) + ||> List.lengthsEqAndForall2 (fun ty tp -> not tp.EqualityConditionalOn || TypeDefinitelyHasEquality g ty) + | _ -> false diff --git a/src/fsharp/AugmentWithHashCompare.fsi b/src/fsharp/AugmentWithHashCompare.fsi index 13d3f18f0e9..4e3acc47ab7 100644 --- a/src/fsharp/AugmentWithHashCompare.fsi +++ b/src/fsharp/AugmentWithHashCompare.fsi @@ -4,25 +4,34 @@ module internal FSharp.Compiler.AugmentWithHashCompare open FSharp.Compiler -open FSharp.Compiler.Tast +open FSharp.Compiler.TypedTree open FSharp.Compiler.TcGlobals -val CheckAugmentationAttribs : bool -> TcGlobals -> Import.ImportMap -> Tycon -> unit -val TyconIsCandidateForAugmentationWithCompare : TcGlobals -> Tycon -> bool -val TyconIsCandidateForAugmentationWithEquals : TcGlobals -> Tycon -> bool -val TyconIsCandidateForAugmentationWithHash : TcGlobals -> Tycon -> bool +val CheckAugmentationAttribs: bool -> TcGlobals -> Import.ImportMap -> Tycon -> unit -val MakeValsForCompareAugmentation : TcGlobals -> TyconRef -> Val * Val -val MakeValsForCompareWithComparerAugmentation : TcGlobals -> TyconRef -> Val -val MakeValsForEqualsAugmentation : TcGlobals -> TyconRef -> Val * Val -val MakeValsForEqualityWithComparerAugmentation : TcGlobals -> TyconRef -> Val * Val * Val +val TyconIsCandidateForAugmentationWithCompare: TcGlobals -> Tycon -> bool -val MakeBindingsForCompareAugmentation : TcGlobals -> Tycon -> Binding list -val MakeBindingsForCompareWithComparerAugmentation : TcGlobals -> Tycon -> Binding list -val MakeBindingsForEqualsAugmentation : TcGlobals -> Tycon -> Binding list -val MakeBindingsForEqualityWithComparerAugmentation : TcGlobals -> Tycon -> Binding list +val TyconIsCandidateForAugmentationWithEquals: TcGlobals -> Tycon -> bool + +val TyconIsCandidateForAugmentationWithHash: TcGlobals -> Tycon -> bool + +val MakeValsForCompareAugmentation: TcGlobals -> TyconRef -> Val * Val + +val MakeValsForCompareWithComparerAugmentation: TcGlobals -> TyconRef -> Val + +val MakeValsForEqualsAugmentation: TcGlobals -> TyconRef -> Val * Val + +val MakeValsForEqualityWithComparerAugmentation: TcGlobals -> TyconRef -> Val * Val * Val + +val MakeBindingsForCompareAugmentation: TcGlobals -> Tycon -> Binding list + +val MakeBindingsForCompareWithComparerAugmentation: TcGlobals -> Tycon -> Binding list + +val MakeBindingsForEqualsAugmentation: TcGlobals -> Tycon -> Binding list + +val MakeBindingsForEqualityWithComparerAugmentation: TcGlobals -> Tycon -> Binding list /// This predicate can be used once type inference is complete, before then it is an approximation /// that doesn't assert any new constraints -val TypeDefinitelyHasEquality : TcGlobals -> TType -> bool +val TypeDefinitelyHasEquality: TcGlobals -> TType -> bool diff --git a/src/fsharp/BinaryResourceFormats.fs b/src/fsharp/BinaryResourceFormats.fs new file mode 100644 index 00000000000..24ea75803d9 --- /dev/null +++ b/src/fsharp/BinaryResourceFormats.fs @@ -0,0 +1,231 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.BinaryResourceFormats + +open FSharp.Compiler.IO +open FSharp.Compiler.AbstractIL.IL + +// Helpers for generating binary blobs +module BinaryGenerationUtilities = + // Little-endian encoding of int32 + let b0 n = byte (n &&& 0xFF) + let b1 n = byte ((n >>> 8) &&& 0xFF) + let b2 n = byte ((n >>> 16) &&& 0xFF) + let b3 n = byte ((n >>> 24) &&& 0xFF) + + let i16 (i: int32) = [| b0 i; b1 i |] + let i32 (i: int32) = [| b0 i; b1 i; b2 i; b3 i |] + + // Emit the bytes and pad to a 32-bit alignment + let Padded initialAlignment (v: byte[]) = + [| yield! v + for _ in 1..(4 - (initialAlignment + v.Length) % 4) % 4 do + yield 0x0uy |] + +// Generate nodes in a .res file format. These are then linked by Abstract IL using linkNativeResources +module ResFileFormat = + open BinaryGenerationUtilities + + let ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, data: byte[]) = + [| yield! i32 data.Length // DWORD ResHdr.dwDataSize + yield! i32 0x00000020 // dwHeaderSize + yield! i32 ((dwTypeID <<< 16) ||| 0x0000FFFF) // dwTypeID, sizeof(DWORD) + yield! i32 ((dwNameID <<< 16) ||| 0x0000FFFF) // dwNameID, sizeof(DWORD) + yield! i32 0x00000000 // DWORD dwDataVersion + yield! i16 wMemFlags // WORD wMemFlags + yield! i16 wLangID // WORD wLangID + yield! i32 0x00000000 // DWORD dwVersion + yield! i32 0x00000000 // DWORD dwCharacteristics + yield! Padded 0 data |] + + let ResFileHeader() = ResFileNode(0x0, 0x0, 0x0, 0x0, [| |]) + +// Generate the VS_VERSION_INFO structure held in a Win32 Version Resource in a PE file +// +// Web reference: http://www.piclist.com/tecHREF/os/win/api/win32/struc/src/str24_5.htm +module VersionResourceFormat = + open BinaryGenerationUtilities + + let VersionInfoNode(data: byte[]) = + [| yield! i16 (data.Length + 2) // wLength : int16 // Specifies the length, in bytes, of the VS_VERSION_INFO structure. + yield! data |] + + let VersionInfoElement(wType, szKey, valueOpt: byte[] option, children: byte[][], isString) = + // for String structs, wValueLength represents the word count, not the byte count + let wValueLength = (match valueOpt with None -> 0 | Some value -> (if isString then value.Length / 2 else value.Length)) + VersionInfoNode + [| yield! i16 wValueLength // wValueLength: int16. Specifies the length, in words, of the Value member. + yield! i16 wType // wType : int16 Specifies the type of data in the version resource. + yield! Padded 2 szKey + match valueOpt with + | None -> yield! [] + | Some value -> yield! Padded 0 value + for child in children do + yield! child |] + + let Version(version: ILVersionInfo) = + [| // DWORD dwFileVersionMS + // Specifies the most significant 32 bits of the file's binary + // version number. This member is used with dwFileVersionLS to form a 64-bit value used + // for numeric comparisons. + yield! i32 (int32 version.Major <<< 16 ||| int32 version.Minor) + + // DWORD dwFileVersionLS + // Specifies the least significant 32 bits of the file's binary + // version number. This member is used with dwFileVersionMS to form a 64-bit value used + // for numeric comparisons. + yield! i32 (int32 version.Build <<< 16 ||| int32 version.Revision) + |] + + let String(string, value) = + let wType = 0x1 // Specifies the type of data in the version resource. + let szKey = Bytes.stringAsUnicodeNullTerminated string + VersionInfoElement(wType, szKey, Some (Bytes.stringAsUnicodeNullTerminated value), [| |], true) + + let StringTable(language, strings) = + let wType = 0x1 // Specifies the type of data in the version resource. + let szKey = Bytes.stringAsUnicodeNullTerminated language + // Specifies an 8-digit hexadecimal number stored as a Unicode string. + + let children = + [| for string in strings do + yield String string |] + VersionInfoElement(wType, szKey, None, children, false) + + let StringFileInfo(stringTables: #seq >) = + let wType = 0x1 // Specifies the type of data in the version resource. + let szKey = Bytes.stringAsUnicodeNullTerminated "StringFileInfo" // Contains the Unicode string StringFileInfo + // Contains an array of one or more StringTable structures. + let children = + [| for stringTable in stringTables do + yield StringTable stringTable |] + VersionInfoElement(wType, szKey, None, children, false) + + let VarFileInfo(vars: #seq) = + let wType = 0x1 // Specifies the type of data in the version resource. + let szKey = Bytes.stringAsUnicodeNullTerminated "VarFileInfo" // Contains the Unicode string StringFileInfo + // Contains an array of one or more StringTable structures. + let children = + [| for lang, codePage in vars do + let szKey = Bytes.stringAsUnicodeNullTerminated "Translation" + yield VersionInfoElement(0x0, szKey, Some([| yield! i16 lang + yield! i16 codePage |]), [| |], false) |] + VersionInfoElement(wType, szKey, None, children, false) + + let VS_FIXEDFILEINFO(fileVersion: ILVersionInfo, + productVersion: ILVersionInfo, + dwFileFlagsMask, + dwFileFlags, dwFileOS, + dwFileType, dwFileSubtype, + lwFileDate: int64) = + let dwStrucVersion = 0x00010000 + [| // DWORD dwSignature // Contains the value 0xFEEFO4BD. + yield! i32 0xFEEF04BD + + // DWORD dwStrucVersion // Specifies the binary version number of this structure. + yield! i32 dwStrucVersion + + // DWORD dwFileVersionMS, dwFileVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. + yield! Version fileVersion + + // DWORD dwProductVersionMS, dwProductVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. + yield! Version productVersion + + // DWORD dwFileFlagsMask // Contains a bitmask that specifies the valid bits in dwFileFlags. + yield! i32 dwFileFlagsMask + + // DWORD dwFileFlags // Contains a bitmask that specifies the Boolean attributes of the file. + yield! i32 dwFileFlags + // VS_FF_DEBUG 0x1L The file contains debugging information or is compiled with debugging features enabled. + // VS_FF_INFOINFERRED The file's version structure was created dynamically; therefore, some of the members + // in this structure may be empty or incorrect. This flag should never be set in a file's + // VS_VERSION_INFO data. + // VS_FF_PATCHED The file has been modified and is not identical to the original shipping file of + // the same version number. + // VS_FF_PRERELEASE The file is a development version, not a commercially released product. + // VS_FF_PRIVATEBUILD The file was not built using standard release procedures. If this flag is + // set, the StringFileInfo structure should contain a PrivateBuild entry. + // VS_FF_SPECIALBUILD The file was built by the original company using standard release procedures + // but is a variation of the normal file of the same version number. If this + // flag is set, the StringFileInfo structure should contain a SpecialBuild entry. + + //Specifies the operating system for which this file was designed. This member can be one of the following values: Flag + yield! i32 dwFileOS + //VOS_DOS 0x0001L The file was designed for MS-DOS. + //VOS_NT 0x0004L The file was designed for Windows NT. + //VOS__WINDOWS16 The file was designed for 16-bit Windows. + //VOS__WINDOWS32 The file was designed for the Win32 API. + //VOS_OS216 0x00020000L The file was designed for 16-bit OS/2. + //VOS_OS232 0x00030000L The file was designed for 32-bit OS/2. + //VOS__PM16 The file was designed for 16-bit Presentation Manager. + //VOS__PM32 The file was designed for 32-bit Presentation Manager. + //VOS_UNKNOWN The operating system for which the file was designed is unknown to Windows. + + // Specifies the general type of file. This member can be one of the following values: + yield! i32 dwFileType + + //VFT_UNKNOWN The file type is unknown to Windows. + //VFT_APP The file contains an application. + //VFT_DLL The file contains a dynamic-link library (DLL). + //VFT_DRV The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver. + //VFT_FONT The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file. + //VFT_VXD The file contains a virtual device. + //VFT_STATIC_LIB The file contains a static-link library. + + // Specifies the function of the file. The possible values depend on the value of + // dwFileType. For all values of dwFileType not described in the following list, + // dwFileSubtype is zero. If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values: + yield! i32 dwFileSubtype + //VFT2_UNKNOWN The driver type is unknown by Windows. + //VFT2_DRV_COMM The file contains a communications driver. + //VFT2_DRV_PRINTER The file contains a printer driver. + //VFT2_DRV_KEYBOARD The file contains a keyboard driver. + //VFT2_DRV_LANGUAGE The file contains a language driver. + //VFT2_DRV_DISPLAY The file contains a display driver. + //VFT2_DRV_MOUSE The file contains a mouse driver. + //VFT2_DRV_NETWORK The file contains a network driver. + //VFT2_DRV_SYSTEM The file contains a system driver. + //VFT2_DRV_INSTALLABLE The file contains an installable driver. + //VFT2_DRV_SOUND The file contains a sound driver. + // + //If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values: + // + //VFT2_UNKNOWN The font type is unknown by Windows. + //VFT2_FONT_RASTER The file contains a raster font. + //VFT2_FONT_VECTOR The file contains a vector font. + //VFT2_FONT_TRUETYPE The file contains a TrueType font. + // + //If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block. + + // Specifies the most significant 32 bits of the file's 64-bit binary creation date and time stamp. + yield! i32 (int32 (lwFileDate >>> 32)) + + //Specifies the least significant 32 bits of the file's 64-bit binary creation date and time stamp. + yield! i32 (int32 lwFileDate) + |] + + let VS_VERSION_INFO(fixedFileInfo, stringFileInfo, varFileInfo) = + let wType = 0x0 + let szKey = Bytes.stringAsUnicodeNullTerminated "VS_VERSION_INFO" // Contains the Unicode string VS_VERSION_INFO + let value = VS_FIXEDFILEINFO fixedFileInfo + let children = + [| yield StringFileInfo stringFileInfo + yield VarFileInfo varFileInfo + |] + VersionInfoElement(wType, szKey, Some value, children, false) + + let VS_VERSION_INFO_RESOURCE data = + let dwTypeID = 0x0010 + let dwNameID = 0x0001 + let wMemFlags = 0x0030 // REVIEW: HARDWIRED TO ENGLISH + let wLangID = 0x0 + ResFileFormat.ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, VS_VERSION_INFO data) + +module ManifestResourceFormat = + + let VS_MANIFEST_RESOURCE(data, isLibrary) = + let dwTypeID = 0x0018 + let dwNameID = if isLibrary then 0x2 else 0x1 + let wMemFlags = 0x0 + let wLangID = 0x0 + ResFileFormat.ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, data) diff --git a/src/fsharp/BinaryResourceFormats.fsi b/src/fsharp/BinaryResourceFormats.fsi new file mode 100644 index 00000000000..2efe5ff8221 --- /dev/null +++ b/src/fsharp/BinaryResourceFormats.fsi @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.BinaryResourceFormats + +open FSharp.Compiler.AbstractIL.IL + +module VersionResourceFormat = + + val VS_VERSION_INFO_RESOURCE: + (ILVersionInfo * ILVersionInfo * int32 * int32 * int32 * int32 * int32 * int64) * + seq> * + seq + -> byte[] + +module ManifestResourceFormat = + + val VS_MANIFEST_RESOURCE : data: byte[] * isLibrary: bool -> byte[] + +module ResFileFormat = + + val ResFileHeader: unit -> byte[] diff --git a/src/fsharp/BuildGraph.fs b/src/fsharp/BuildGraph.fs new file mode 100644 index 00000000000..df797d0a3b3 --- /dev/null +++ b/src/fsharp/BuildGraph.fs @@ -0,0 +1,393 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +module FSharp.Compiler.BuildGraph + +open System +open System.Threading +open System.Threading.Tasks +open System.Diagnostics +open System.Globalization +open FSharp.Compiler.ErrorLogger +open Internal.Utilities.Library + +/// This represents the thread-local state established as each task function runs as part of the build. +/// +/// Use to reset error and warning handlers. +type CompilationGlobalsScope(errorLogger: ErrorLogger, phase: BuildPhase) = + let unwindEL = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) + let unwindBP = PushThreadBuildPhaseUntilUnwind phase + + member _.ErrorLogger = errorLogger + member _.Phase = phase + + // Return the disposable object that cleans up + interface IDisposable with + member d.Dispose() = + unwindBP.Dispose() + unwindEL.Dispose() + +[] +type NodeCode<'T> = Node of Async<'T> + +let wrapThreadStaticInfo computation = + async { + let errorLogger = CompileThreadStatic.ErrorLogger + let phase = CompileThreadStatic.BuildPhase + try + return! computation + finally + CompileThreadStatic.ErrorLogger <- errorLogger + CompileThreadStatic.BuildPhase <- phase + } + +type Async<'T> with + + static member AwaitNodeCode(node: NodeCode<'T>) = + match node with + | Node(computation) -> wrapThreadStaticInfo computation + +[] +type NodeCodeBuilder() = + + static let zero = Node(async.Zero()) + + [] + member _.Zero () : NodeCode = zero + + [] + member _.Delay (f: unit -> NodeCode<'T>) = + Node(async.Delay(fun () -> match f() with Node(p) -> p)) + + [] + member _.Return value = Node(async.Return(value)) + + [] + member _.ReturnFrom (computation: NodeCode<_>) = computation + + [] + member _.Bind (Node(p): NodeCode<'a>, binder: 'a -> NodeCode<'b>) : NodeCode<'b> = + Node(async.Bind(p, fun x -> match binder x with Node p -> p)) + + [] + member _.TryWith(Node(p): NodeCode<'T>, binder: exn -> NodeCode<'T>) : NodeCode<'T> = + Node(async.TryWith(p, fun ex -> match binder ex with Node p -> p)) + + [] + member _.TryFinally(Node(p): NodeCode<'T>, binder: unit -> unit) : NodeCode<'T> = + Node(async.TryFinally(p, binder)) + + [] + member _.For(xs: 'T seq, binder: 'T -> NodeCode) : NodeCode = + Node(async.For(xs, fun x -> match binder x with Node p -> p)) + + [] + member _.Combine(Node(p1): NodeCode, Node(p2): NodeCode<'T>) : NodeCode<'T> = + Node(async.Combine(p1, p2)) + + [] + member _.Using(value: CompilationGlobalsScope, binder: CompilationGlobalsScope -> NodeCode<'U>) = + Node( + async { + CompileThreadStatic.ErrorLogger <- value.ErrorLogger + CompileThreadStatic.BuildPhase <- value.Phase + try + return! binder value |> Async.AwaitNodeCode + finally + (value :> IDisposable).Dispose() + } + ) + +let node = NodeCodeBuilder() + +[] +type NodeCode private () = + + static let cancellationToken = + Node(wrapThreadStaticInfo Async.CancellationToken) + + static member RunImmediate (computation: NodeCode<'T>, ct: CancellationToken) = + let errorLogger = CompileThreadStatic.ErrorLogger + let phase = CompileThreadStatic.BuildPhase + try + try + let work = + async { + CompileThreadStatic.ErrorLogger <- errorLogger + CompileThreadStatic.BuildPhase <- phase + return! computation |> Async.AwaitNodeCode + } + Async.StartImmediateAsTask(work, cancellationToken=ct).Result + finally + CompileThreadStatic.ErrorLogger <- errorLogger + CompileThreadStatic.BuildPhase <- phase + with + | :? AggregateException as ex when ex.InnerExceptions.Count = 1 -> + raise(ex.InnerExceptions.[0]) + + static member RunImmediateWithoutCancellation (computation: NodeCode<'T>) = + NodeCode.RunImmediate(computation, CancellationToken.None) + + static member StartAsTask_ForTesting (computation: NodeCode<'T>, ?ct: CancellationToken) = + let errorLogger = CompileThreadStatic.ErrorLogger + let phase = CompileThreadStatic.BuildPhase + try + let work = + async { + CompileThreadStatic.ErrorLogger <- errorLogger + CompileThreadStatic.BuildPhase <- phase + return! computation |> Async.AwaitNodeCode + } + Async.StartAsTask(work, cancellationToken=defaultArg ct CancellationToken.None) + finally + CompileThreadStatic.ErrorLogger <- errorLogger + CompileThreadStatic.BuildPhase <- phase + + static member CancellationToken = cancellationToken + + static member FromCancellable(computation: Cancellable<'T>) = + Node(wrapThreadStaticInfo (Cancellable.toAsync computation)) + + static member AwaitAsync(computation: Async<'T>) = + Node(wrapThreadStaticInfo computation) + + static member AwaitTask(task: Task<'T>) = + Node(wrapThreadStaticInfo(Async.AwaitTask task)) + + static member AwaitTask(task: Task) = + Node(wrapThreadStaticInfo(Async.AwaitTask task)) + + static member AwaitWaitHandle_ForTesting(waitHandle: WaitHandle) = + Node(wrapThreadStaticInfo (Async.AwaitWaitHandle(waitHandle))) + + static member Sleep(ms: int) = + Node(wrapThreadStaticInfo (Async.Sleep(ms))) + + static member Sequential(computations: NodeCode<'T> seq) = + node { + let results = ResizeArray() + for computation in computations do + let! res = computation + results.Add(res) + return results.ToArray() + } + +type private AgentMessage<'T> = + | GetValue of AsyncReplyChannel> * callerCancellationToken: CancellationToken + +type private Agent<'T> = MailboxProcessor> * CancellationTokenSource + +[] +type private GraphNodeAction<'T> = + | GetValueByAgent + | GetValue + | CachedValue of 'T + +[] +module GraphNode = + + // We need to store the culture for the VS thread that is executing now, + // so that when the agent in the async lazy object picks up thread from the thread pool we can set the culture + let mutable culture = CultureInfo(CultureInfo.CurrentUICulture.Name) + + let SetPreferredUILang (preferredUiLang: string option) = + match preferredUiLang with + | Some s -> + culture <- CultureInfo s +#if FX_RESHAPED_GLOBALIZATION + CultureInfo.CurrentUICulture <- culture +#else + Thread.CurrentThread.CurrentUICulture <- culture +#endif + | None -> () + +[] +type GraphNode<'T> (retryCompute: bool, computation: NodeCode<'T>) = + + let gate = obj () + let mutable computation = computation + let mutable requestCount = 0 + let mutable cachedResult: Task<'T> = Unchecked.defaultof<_> + let mutable cachedResultNode: NodeCode<'T> = Unchecked.defaultof<_> + + let isCachedResultNodeNotNull() = + not (obj.ReferenceEquals(cachedResultNode, null)) + + let isCachedResultNotNull() = + cachedResult <> null + + // retryCompute indicates that we abandon computations when the originator is + // cancelled. + // + // If retryCompute is 'true', the computation is run directly in the originating requestor's + // thread. If cancelled, other awaiting computations must restart the computation from scratch. + // + // If retryCompute is 'false', a MailboxProcessor is used to allow the cancelled originator + // to detach from the computation, while other awaiting computations continue to wait on the result. + // + // Currently, 'retryCompute' = true for all graph nodes. However, the code for we include the + // code to allow 'retryCompute' = false in case it's needed in the future, and ensure it is under independent + // unit test. + let loop (agent: MailboxProcessor>) = + async { + assert (not retryCompute) + try + while true do + match! agent.Receive() with + | GetValue (replyChannel, callerCancellationToken) -> + + Thread.CurrentThread.CurrentUICulture <- GraphNode.culture + try + use _reg = + // When a cancellation has occured, notify the reply channel to let the requester stop waiting for a response. + callerCancellationToken.Register (fun () -> + let ex = OperationCanceledException() :> exn + replyChannel.Reply (Result.Error ex) + ) + + callerCancellationToken.ThrowIfCancellationRequested () + + if isCachedResultNotNull() then + replyChannel.Reply(Ok cachedResult.Result) + else + // This computation can only be canceled if the requestCount reaches zero. + let! result = computation |> Async.AwaitNodeCode + cachedResult <- Task.FromResult(result) + cachedResultNode <- node { return result } + computation <- Unchecked.defaultof<_> + if not callerCancellationToken.IsCancellationRequested then + replyChannel.Reply(Ok result) + with + | ex -> + if not callerCancellationToken.IsCancellationRequested then + replyChannel.Reply(Result.Error ex) + with + | _ -> + () + } + + let mutable agent: Agent<'T> = Unchecked.defaultof<_> + + let semaphore: SemaphoreSlim = + if retryCompute then + new SemaphoreSlim(1, 1) + else + Unchecked.defaultof<_> + + member _.GetOrComputeValue() = + // fast path + if isCachedResultNodeNotNull() then + cachedResultNode + else + node { + if isCachedResultNodeNotNull() then + return! cachedResult |> NodeCode.AwaitTask + else + let action = + lock gate <| fun () -> + // We try to get the cached result after the lock so we don't spin up a new mailbox processor. + if isCachedResultNodeNotNull() then + GraphNodeAction<'T>.CachedValue cachedResult.Result + else + requestCount <- requestCount + 1 + if retryCompute then + GraphNodeAction<'T>.GetValue + else + match box agent with + | null -> + try + let cts = new CancellationTokenSource() + let mbp = new MailboxProcessor<_>(loop, cancellationToken = cts.Token) + let newAgent = (mbp, cts) + agent <- newAgent + mbp.Start() + GraphNodeAction<'T>.GetValueByAgent + with + | ex -> + agent <- Unchecked.defaultof<_> + raise ex + | _ -> + GraphNodeAction<'T>.GetValueByAgent + + match action with + | GraphNodeAction.CachedValue result -> return result + | GraphNodeAction.GetValue -> + try + let! ct = NodeCode.CancellationToken + + // We must set 'taken' before any implicit cancellation checks + // occur, making sure we are under the protection of the 'try'. + // For example, NodeCode's 'try/finally' (TryFinally) uses async.TryFinally which does + // implicit cancellation checks even before the try is entered, as do the + // de-sugaring of 'do!' and other CodeCode constructs. + let mutable taken = false + try + do! + semaphore.WaitAsync(ct) + .ContinueWith( + (fun _ -> taken <- true), + (TaskContinuationOptions.NotOnCanceled ||| TaskContinuationOptions.NotOnFaulted ||| TaskContinuationOptions.ExecuteSynchronously) + ) + |> NodeCode.AwaitTask + + if isCachedResultNotNull() then + return cachedResult.Result + else + let tcs = TaskCompletionSource<'T>() + let (Node(p)) = computation + Async.StartWithContinuations( + async { + Thread.CurrentThread.CurrentUICulture <- GraphNode.culture + return! p + }, + (fun res -> + cachedResult <- Task.FromResult(res) + cachedResultNode <- node { return res } + computation <- Unchecked.defaultof<_> + tcs.SetResult(res) + ), + (fun ex -> + tcs.SetException(ex) + ), + (fun _ -> + tcs.SetCanceled() + ), + ct + ) + return! tcs.Task |> NodeCode.AwaitTask + finally + if taken then + semaphore.Release() |> ignore + finally + lock gate <| fun () -> + requestCount <- requestCount - 1 + + | GraphNodeAction.GetValueByAgent -> + assert (not retryCompute) + let mbp, cts = agent + try + let! ct = NodeCode.CancellationToken + let! res = mbp.PostAndAsyncReply(fun replyChannel -> GetValue(replyChannel, ct)) |> NodeCode.AwaitAsync + match res with + | Ok result -> return result + | Result.Error ex -> return raise ex + finally + lock gate <| fun () -> + requestCount <- requestCount - 1 + if requestCount = 0 then + cts.Cancel() // cancel computation when all requests are cancelled + try (mbp :> IDisposable).Dispose () with | _ -> () + cts.Dispose() + agent <- Unchecked.defaultof<_> + } + + member _.TryPeekValue() = + match cachedResult with + | null -> ValueNone + | _ -> ValueSome cachedResult.Result + + member _.HasValue = cachedResult <> null + + member _.IsComputing = requestCount > 0 + + new(computation) = + GraphNode(retryCompute=true, computation=computation) \ No newline at end of file diff --git a/src/fsharp/BuildGraph.fsi b/src/fsharp/BuildGraph.fsi new file mode 100644 index 00000000000..cf1d750c3e0 --- /dev/null +++ b/src/fsharp/BuildGraph.fsi @@ -0,0 +1,120 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +module internal FSharp.Compiler.BuildGraph + +open System +open System.Threading +open System.Threading.Tasks +open FSharp.Compiler.ErrorLogger +open Internal.Utilities.Library + +/// This represents the global state established as each task function runs as part of the build. +/// +/// Use to reset error and warning handlers. +type CompilationGlobalsScope = + new : ErrorLogger * BuildPhase -> CompilationGlobalsScope + interface IDisposable + +/// Represents code that can be run as part of the build graph. +/// +/// This is essentially cancellable async code where the only asynchronous waits are on nodes. +/// When a node is evaluated the evaluation is run synchronously on the thread of the +/// first requestor. +[] +type NodeCode<'T> + +type Async<'T> with + + /// Asynchronously await code in the build graph + static member AwaitNodeCode: node: NodeCode<'T> -> Async<'T> + +/// A standard builder for node code. +[] +type NodeCodeBuilder = + + member Bind : NodeCode<'T> * ('T -> NodeCode<'U>) -> NodeCode<'U> + + member Zero : unit -> NodeCode + + member Delay : (unit -> NodeCode<'T>) -> NodeCode<'T> + + member Return : 'T -> NodeCode<'T> + + member ReturnFrom : NodeCode<'T> -> NodeCode<'T> + + member TryWith : NodeCode<'T> * (exn -> NodeCode<'T>) -> NodeCode<'T> + + member TryFinally : NodeCode<'T> * (unit -> unit) -> NodeCode<'T> + + member For : xs: 'T seq * binder: ('T -> NodeCode) -> NodeCode + + member Combine : x1: NodeCode * x2: NodeCode<'T> -> NodeCode<'T> + + /// A limited form 'use' for establishing the compilation globals. (Note + /// that a proper generic 'use' could be implemented but has not currently been necessary) + member Using : CompilationGlobalsScope * (CompilationGlobalsScope -> NodeCode<'T>) -> NodeCode<'T> + +/// Specifies code that can be run as part of the build graph. +val node : NodeCodeBuilder + +/// Contains helpers to specify code that can be run as part of the build graph. +[] +type NodeCode = + + /// Only used for testing, do not use + static member RunImmediate: computation: NodeCode<'T> * ct: CancellationToken -> 'T + + /// Used in places where we don't care about cancellation, e.g. the command line compiler + /// and F# Interactive + static member RunImmediateWithoutCancellation: computation: NodeCode<'T> -> 'T + + static member CancellationToken: NodeCode + + static member Sequential: computations: NodeCode<'T> seq -> NodeCode<'T []> + + /// Execute the cancellable computation synchronously using the ambient cancellation token of + /// the NodeCode. + static member FromCancellable: computation: Cancellable<'T> -> NodeCode<'T> + + /// Only used for testing, do not use + static member StartAsTask_ForTesting: computation: NodeCode<'T> * ?ct: CancellationToken -> Task<'T> + + /// Only used for testing, do not use + static member AwaitWaitHandle_ForTesting: waitHandle: WaitHandle -> NodeCode + +/// Contains helpers related to the build graph +[] +module internal GraphNode = + + /// Allows to specify the language for error messages + val SetPreferredUILang: preferredUiLang: string option -> unit + +/// Evaluate the computation, allowing asynchronous waits on existing ongoing evaluations of the +/// same node, and strongly cache the result. +/// +/// Once the result has been cached, the computation function will also be removed, or 'null'ed out, +/// as to prevent any references captured by the computation from being strongly held. +[] +type internal GraphNode<'T> = + + /// - retryCompute - When set to 'true', subsequent requesters will retry the computation if the first-in request cancels. Retrying computations will have better callstacks. + /// - computation - The computation code to run. + new: retryCompute: bool * computation: NodeCode<'T> -> GraphNode<'T> + + /// By default, 'retryCompute' is 'true'. + new : computation: NodeCode<'T> -> GraphNode<'T> + + /// Return NodeCode which, when executed, will get the value of the computation if already computed, or + /// await an existing in-progress computation for the node if one exists, or else will synchronously + /// start the computation on the current thread. + member GetOrComputeValue: unit -> NodeCode<'T> + + /// Return 'Some' if the computation has already been computed, else None if + /// the computation is in-progress or has not yet been started. + member TryPeekValue: unit -> 'T voption + + /// Return 'true' if the computation has already been computed. + member HasValue: bool + + /// Return 'true' if the computation is in-progress. + member IsComputing: bool \ No newline at end of file diff --git a/src/fsharp/CheckComputationExpressions.fs b/src/fsharp/CheckComputationExpressions.fs new file mode 100644 index 00000000000..1c9aecdc594 --- /dev/null +++ b/src/fsharp/CheckComputationExpressions.fs @@ -0,0 +1,2058 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The typechecker. Left-to-right constrained type checking +/// with generalization at appropriate points. +module internal FSharp.Compiler.CheckComputationExpressions + +open Internal.Utilities.Library +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.Infos +open FSharp.Compiler.InfoReader +open FSharp.Compiler.NameResolution +open FSharp.Compiler.PatternMatchCompilation +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +type cenv = TcFileState + +/// Used to flag if this is the first or a sebsequent translation pass through a computation expression +type CompExprTranslationPass = Initial | Subsequent + +/// Used to flag if computation expression custom operations are allowed in a given context +type CustomOperationsMode = Allowed | Denied + +let TryFindIntrinsicOrExtensionMethInfo collectionSettings (cenv: cenv) (env: TcEnv) m ad nm ty = + AllMethInfosOfTypeInScope collectionSettings cenv.infoReader env.NameEnv (Some nm) ad IgnoreOverrides m ty + +/// Ignores an attribute +let IgnoreAttribute _ = None + +let (|ExprAsPat|_|) (f: SynExpr) = + match f with + | SingleIdent v1 | SynExprParen(SingleIdent v1, _, _, _) -> Some (mkSynPatVar None v1) + | SynExprParen(SynExpr.Tuple (false, elems, _, _), _, _, _) -> + let elems = elems |> List.map (|SingleIdent|_|) + if elems |> List.forall (fun x -> x.IsSome) then + Some (SynPat.Tuple(false, (elems |> List.map (fun x -> mkSynPatVar None x.Value)), f.Range)) + else + None + | _ -> None + +// For join clauses that join on nullable, we syntactically insert the creation of nullable values on the appropriate side of the condition, +// then pull the syntax apart again +let (|JoinRelation|_|) cenv env (e: SynExpr) = + let m = e.Range + let ad = env.eAccessRights + + let isOpName opName vref s = + (s = opName) && + match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.eNameResEnv TypeNameResolutionInfo.Default [ident(opName, m)] with + | Result (_, Item.Value vref2, []) -> valRefEq cenv.g vref vref2 + | _ -> false + + match e with + | BinOpExpr(opId, a, b) when isOpName opNameEquals cenv.g.equals_operator_vref opId.idText -> Some (a, b) + + | BinOpExpr(opId, a, b) when isOpName opNameEqualsNullable cenv.g.equals_nullable_operator_vref opId.idText -> + + let a = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet a.Range [MangledGlobalName;"System"] "Nullable", a, a.Range) + Some (a, b) + + | BinOpExpr(opId, a, b) when isOpName opNameNullableEquals cenv.g.nullable_equals_operator_vref opId.idText -> + + let b = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet b.Range [MangledGlobalName;"System"] "Nullable", b, b.Range) + Some (a, b) + + | BinOpExpr(opId, a, b) when isOpName opNameNullableEqualsNullable cenv.g.nullable_equals_nullable_operator_vref opId.idText -> + + Some (a, b) + + | _ -> None + +let elimFastIntegerForLoop (spBind, id, start, dir, finish, innerExpr, m) = + let pseudoEnumExpr = + if dir then mkSynInfix m start ".." finish + else mkSynTrifix m ".. .." start (SynExpr.Const (SynConst.Int32 -1, start.Range)) finish + SynExpr.ForEach (spBind, SeqExprOnly false, true, mkSynPatVar None id, pseudoEnumExpr, innerExpr, m) + +/// Check if a computation or sequence expression is syntactically free of 'yield' (though not yield!) +let YieldFree (cenv: cenv) expr = + if cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield then + + // Implement yield free logic for F# Language including the LanguageFeature.ImplicitYield + let rec YieldFree expr = + match expr with + | SynExpr.Sequential (_, _, e1, e2, _) -> + YieldFree e1 && YieldFree e2 + + | SynExpr.IfThenElse (_, _, _, _, e2, _, e3opt, _, _, _, _) -> + YieldFree e2 && Option.forall YieldFree e3opt + + | SynExpr.TryWith (e1, _, clauses, _, _, _, _) -> + YieldFree e1 && clauses |> List.forall (fun (SynMatchClause(resultExpr = e)) -> YieldFree e) + + | SynExpr.Match (_, _, clauses, _) | SynExpr.MatchBang (_, _, clauses, _) -> + clauses |> List.forall (fun (SynMatchClause(resultExpr = e)) -> YieldFree e) + + | SynExpr.For (_, _, _, _, _, body, _) + | SynExpr.TryFinally (body, _, _, _, _) + | SynExpr.LetOrUse (_, _, _, body, _) + | SynExpr.While (_, _, body, _) + | SynExpr.ForEach (_, _, _, _, _, body, _) -> + YieldFree body + + | SynExpr.LetOrUseBang(_, _, _, _, _, _, body, _) -> + YieldFree body + + | SynExpr.YieldOrReturn((true, _), _, _) -> false + + | _ -> true + + YieldFree expr + else + // Implement yield free logic for F# Language without the LanguageFeature.ImplicitYield + let rec YieldFree expr = + match expr with + | SynExpr.Sequential (_, _, e1, e2, _) -> + YieldFree e1 && YieldFree e2 + + | SynExpr.IfThenElse (_, _, _, _, e2, _, e3opt, _, _, _, _) -> + YieldFree e2 && Option.forall YieldFree e3opt + + | SynExpr.TryWith (e1, _, clauses, _, _, _, _) -> + YieldFree e1 && clauses |> List.forall (fun (SynMatchClause(resultExpr = e)) -> YieldFree e) + + | SynExpr.Match (_, _, clauses, _) | SynExpr.MatchBang (_, _, clauses, _) -> + clauses |> List.forall (fun (SynMatchClause(resultExpr = e)) -> YieldFree e) + + | SynExpr.For (_, _, _, _, _, body, _) + | SynExpr.TryFinally (body, _, _, _, _) + | SynExpr.LetOrUse (_, _, _, body, _) + | SynExpr.While (_, _, body, _) + | SynExpr.ForEach (_, _, _, _, _, body, _) -> + YieldFree body + + | SynExpr.LetOrUseBang _ + | SynExpr.YieldOrReturnFrom _ + | SynExpr.YieldOrReturn _ + | SynExpr.ImplicitZero _ + | SynExpr.Do _ -> false + + | _ -> true + + YieldFree expr + + +/// Determine if a syntactic expression inside 'seq { ... }' or '[...]' counts as a "simple sequence +/// of semicolon separated values". For example [1;2;3]. +/// 'acceptDeprecated' is true for the '[ ... ]' case, where we allow the syntax '[ if g then t else e ]' but ask it to be parenthesized +/// +let (|SimpleSemicolonSequence|_|) cenv acceptDeprecated cexpr = + + let IsSimpleSemicolonSequenceElement expr = + match expr with + | SynExpr.IfThenElse _ when acceptDeprecated && YieldFree cenv expr -> true + | SynExpr.IfThenElse _ + | SynExpr.TryWith _ + | SynExpr.Match _ + | SynExpr.For _ + | SynExpr.ForEach _ + | SynExpr.TryFinally _ + | SynExpr.YieldOrReturnFrom _ + | SynExpr.YieldOrReturn _ + | SynExpr.LetOrUse _ + | SynExpr.Do _ + | SynExpr.MatchBang _ + | SynExpr.LetOrUseBang _ + | SynExpr.While _ -> false + | _ -> true + + let rec TryGetSimpleSemicolonSequenceOfComprehension expr acc = + match expr with + | SynExpr.Sequential (_, true, e1, e2, _) -> + if IsSimpleSemicolonSequenceElement e1 then + TryGetSimpleSemicolonSequenceOfComprehension e2 (e1 :: acc) + else + None + | e -> + if IsSimpleSemicolonSequenceElement e then + Some(List.rev (e :: acc)) + else + None + + TryGetSimpleSemicolonSequenceOfComprehension cexpr [] + +let RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv expr = + // This function is motivated by cases like + // query { for ... join(for x in f(). } + // where there is incomplete code in a query, and we are current just dropping a piece of the AST on the floor (above, the bit inside the 'join'). + // + // The problem with dropping the AST on the floor is that we get no captured resolutions, which means no Intellisense/QuickInfo/ParamHelp. + // + // The idea behind the fix is to semi-typecheck this AST-fragment, just to get resolutions captured. + // + // The tricky bit is to not also have any other effects from typechecking, namely producing error diagnostics (which may be spurious) or having + // side-effects on the typecheck environment. + // + // REVIEW: We are yet to deal with the tricky bit. As it stands, we turn off error logging, but still have typechecking environment effects. As a result, + // at the very least, you cannot call this function unless you're already reported a typechecking error (the 'worst' possible outcome would be + // to incorrectly solve typecheck constraints as a result of effects in this function, and then have the code compile successfully and behave + // in some weird way; so ensure the code can't possibly compile before calling this function as an expedient way to get better IntelliSense). + suppressErrorReporting (fun () -> + try ignore(TcExprOfUnknownType cenv env tpenv expr) + with e -> ()) + +/// Used for all computation expressions except sequence expressions +let TcComputationExpression cenv env (overallTy: OverallTy) tpenv (mWhole, interpExpr: Expr, builderTy, comp: SynExpr) = + let overallTy = overallTy.Commit + + //dprintfn "TcComputationExpression, comp = \n%A\n-------------------\n" comp + let ad = env.eAccessRights + + let mkSynDelay2 (e: SynExpr) = mkSynDelay (e.Range.MakeSynthetic()) e + + let builderValName = CompilerGeneratedName "builder" + let mBuilderVal = interpExpr.Range + + // Give bespoke error messages for the FSharp.Core "query" builder + let isQuery = + match interpExpr with + | Expr.Val (vf, _, m) -> + let item = Item.CustomBuilder (vf.DisplayName, vf) + CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + valRefEq cenv.g vf cenv.g.query_value_vref + | _ -> false + + /// Make a builder.Method(...) call + let mkSynCall nm (m: range) args = + let m = m.MakeSynthetic() // Mark as synthetic so the language service won't pick it up. + let args = + match args with + | [] -> SynExpr.Const (SynConst.Unit, m) + | [arg] -> SynExpr.Paren (SynExpr.Paren (arg, range0, None, m), range0, None, m) + | args -> SynExpr.Paren (SynExpr.Tuple (false, args, [], m), range0, None, m) + + let builderVal = mkSynIdGet m builderValName + mkSynApp1 (SynExpr.DotGet (builderVal, range0, LongIdentWithDots([mkSynId m nm], []), m)) args m + + let hasMethInfo nm = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad nm builderTy |> isNil |> not + + let sourceMethInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Source" builderTy + + // Optionally wrap sources of "let!", "yield!", "use!" in "query.Source" + let mkSourceExpr callExpr = + match sourceMethInfo with + | [] -> callExpr + | _ -> mkSynCall "Source" callExpr.Range [callExpr] + + let mkSourceExprConditional isFromSource callExpr = + if isFromSource then mkSourceExpr callExpr else callExpr + + /// Decide if the builder is an auto-quote builder + let isAutoQuote = hasMethInfo "Quote" + + let customOperationMethods = + AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults cenv.infoReader env.NameEnv None ad IgnoreOverrides mBuilderVal builderTy + |> List.choose (fun methInfo -> + if not (IsMethInfoAccessible cenv.amap mBuilderVal ad methInfo) then None else + let nameSearch = + TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo + IgnoreAttribute // We do not respect this attribute for IL methods + (function Attrib(_, _, [ AttribStringArg msg ], _, _, _, _) -> Some msg | _ -> None) + IgnoreAttribute // We do not respect this attribute for provided methods + + match nameSearch with + | None -> None + | Some nm -> + let joinConditionWord = + TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo + IgnoreAttribute // We do not respect this attribute for IL methods + (function Attrib(_, _, _, ExtractAttribNamedArg "JoinConditionWord" (AttribStringArg s), _, _, _) -> Some s | _ -> None) + IgnoreAttribute // We do not respect this attribute for provided methods + + let flagSearch (propName: string) = + TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo + IgnoreAttribute // We do not respect this attribute for IL methods + (function Attrib(_, _, _, ExtractAttribNamedArg propName (AttribBoolArg b), _, _, _) -> Some b | _ -> None) + IgnoreAttribute // We do not respect this attribute for provided methods + + let maintainsVarSpaceUsingBind = defaultArg (flagSearch "MaintainsVariableSpaceUsingBind") false + let maintainsVarSpace = defaultArg (flagSearch "MaintainsVariableSpace") false + let allowInto = defaultArg (flagSearch "AllowIntoPattern") false + let isLikeZip = defaultArg (flagSearch "IsLikeZip") false + let isLikeJoin = defaultArg (flagSearch "IsLikeJoin") false + let isLikeGroupJoin = defaultArg (flagSearch "IsLikeGroupJoin") false + + Some (nm, maintainsVarSpaceUsingBind, maintainsVarSpace, allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, joinConditionWord, methInfo)) + + let customOperationMethodsIndexedByKeyword = + if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then + customOperationMethods + |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) + |> Seq.map (fun (nm, group) -> + (nm, + group + |> Seq.toList)) + else + customOperationMethods + |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) + |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) + |> dict + + // Check for duplicates by method name (keywords and method names must be 1:1) + let customOperationMethodsIndexedByMethodName = + if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then + customOperationMethods + |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.map (fun (nm, group) -> + (nm, + group + |> Seq.toList)) + else + customOperationMethods + |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) + |> dict + + /// Decide if the identifier represents a use of a custom query operator + let tryGetDataForCustomOperation (nm: Ident) = + match customOperationMethodsIndexedByKeyword.TryGetValue nm.idText with + | true, opDatas when (opDatas.Length = 1 || (opDatas.Length > 0 && cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations)) -> + for opData in opDatas do + let opName, maintainsVarSpaceUsingBind, maintainsVarSpace, _allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, _joinConditionWord, methInfo = opData + if (maintainsVarSpaceUsingBind && maintainsVarSpace) || (isLikeZip && isLikeJoin) || (isLikeZip && isLikeGroupJoin) || (isLikeJoin && isLikeGroupJoin) then + errorR(Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) + if not (cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations) then + match customOperationMethodsIndexedByMethodName.TryGetValue methInfo.LogicalName with + | true, [_] -> () + | _ -> errorR(Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) + Some opDatas + | true, opData :: _ -> errorR(Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)); Some [opData] + | _ -> None + + /// Decide if the identifier represents a use of a custom query operator + let hasCustomOperations () = if isNil customOperationMethods then CustomOperationsMode.Denied else CustomOperationsMode.Allowed + + let isCustomOperation nm = tryGetDataForCustomOperation nm |> Option.isSome + + let customOperationCheckValidity m f opDatas = + let vs = opDatas |> List.map f + let v0 = vs.[0] + let opName, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo = opDatas.[0] + if not (List.allEqual vs) then + errorR(Error(FSComp.SR.tcCustomOperationInvalid opName, m)) + v0 + + // Check for the MaintainsVariableSpace on custom operation + let customOperationMaintainsVarSpace (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> maintainsVarSpace) + + let customOperationMaintainsVarSpaceUsingBind (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> maintainsVarSpaceUsingBind) + + let customOperationIsLikeZip (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeZip) + + let customOperationIsLikeJoin (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeJoin) + + let customOperationIsLikeGroupJoin (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeGroupJoin) + + let customOperationJoinConditionWord (nm: Ident) = + match tryGetDataForCustomOperation nm with + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, joinConditionWord, _methInfo) -> joinConditionWord) + |> function None -> "on" | Some v -> v + | _ -> "on" + + let customOperationAllowsInto (nm: Ident) = + match tryGetDataForCustomOperation nm with + | None -> false + | Some opDatas -> + opDatas |> customOperationCheckValidity nm.idRange (fun (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> allowInto) + + let customOpUsageText nm = + match tryGetDataForCustomOperation nm with + | Some ((_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, _joinConditionWord, _methInfo) :: _) -> + if isLikeGroupJoin then + Some (FSComp.SR.customOperationTextLikeGroupJoin(nm.idText, customOperationJoinConditionWord nm, customOperationJoinConditionWord nm)) + elif isLikeJoin then + Some (FSComp.SR.customOperationTextLikeJoin(nm.idText, customOperationJoinConditionWord nm, customOperationJoinConditionWord nm)) + elif isLikeZip then + Some (FSComp.SR.customOperationTextLikeZip(nm.idText)) + else + None + | _ -> None + + /// Inside the 'query { ... }' use a modified name environment that contains fake 'CustomOperation' entries + /// for all custom operations. This adds them to the completion lists and prevents them being used as values inside + /// the query. + let env = + if List.isEmpty customOperationMethods then env else + { env with + eNameResEnv = + (env.eNameResEnv, customOperationMethods) + ||> Seq.fold (fun nenv (nm, _, _, _, _, _, _, _, methInfo) -> + AddFakeNameToNameEnv nm nenv (Item.CustomOperation (nm, (fun () -> customOpUsageText (ident (nm, mBuilderVal))), Some methInfo))) } + + // Environment is needed for completions + CallEnvSink cenv.tcSink (comp.Range, env.NameEnv, ad) + + let tryGetArgAttribsForCustomOperator (nm: Ident) = + match tryGetDataForCustomOperation nm with + | Some argInfos -> + argInfos + |> List.map (fun (_nm, __maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, methInfo) -> + match methInfo.GetParamAttribs(cenv.amap, mWhole) with + | [curriedArgInfo] -> Some curriedArgInfo // one for the actual argument group + | _ -> None) + |> Some + | _ -> None + + let tryGetArgInfosForCustomOperator (nm: Ident) = + match tryGetDataForCustomOperation nm with + | Some argInfos -> + argInfos + |> List.map (fun (_nm, __maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, methInfo) -> + match methInfo with + | FSMeth(_, _, vref, _) -> + match ArgInfosOfMember cenv.g vref with + | [curriedArgInfo] -> Some curriedArgInfo + | _ -> None + | _ -> None) + |> Some + | _ -> None + + let tryExpectedArgCountForCustomOperator (nm: Ident) = + match tryGetArgAttribsForCustomOperator nm with + | None -> None + | Some argInfosForOverloads -> + let nums = argInfosForOverloads |> List.map (function None -> -1 | Some argInfos -> List.length argInfos) + + // Prior to 'OverloadsForCustomOperations' we count exact arguments. + // + // With 'OverloadsForCustomOperations' we don't compute an exact expected argument count + // if any arguments are optional, out or ParamArray. + let isSpecial = + if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then + argInfosForOverloads |> List.exists (fun info -> + match info with + | None -> false + | Some args -> + args |> List.exists (fun (isParamArrayArg, _isInArg, isOutArg, optArgInfo, _callerInfo, _reflArgInfo) -> isParamArrayArg || isOutArg || optArgInfo.IsOptional)) + else + false + + if not isSpecial && nums |> List.forall (fun v -> v >= 0 && v = nums.[0]) then + Some (max (nums.[0] - 1) 0) // drop the computation context argument + else + None + + // Check for the [] attribute on an argument position + let isCustomOperationProjectionParameter i (nm: Ident) = + match tryGetArgInfosForCustomOperator nm with + | None -> false + | Some argInfosForOverloads -> + let vs = + argInfosForOverloads |> List.map (function + | None -> false + | Some argInfos -> + i < argInfos.Length && + let _, argInfo = List.item i argInfos + HasFSharpAttribute cenv.g cenv.g.attrib_ProjectionParameterAttribute argInfo.Attribs) + if List.allEqual vs then vs.[0] + else + let opDatas = (tryGetDataForCustomOperation nm).Value + let opName, _, _, _, _, _, _, _j, _ = opDatas.[0] + errorR(Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) + false + + let (|ForEachThen|_|) e = + match e with + | SynExpr.ForEach (_spBind, SeqExprOnly false, isFromSource, pat1, expr1, SynExpr.Sequential (_, true, clause, rest, _), _) -> Some (isFromSource, pat1, expr1, clause, rest) + | _ -> None + + let (|CustomOpId|_|) predicate e = + match e with + | SingleIdent nm when isCustomOperation nm && predicate nm -> Some nm + | _ -> None + + // e1 in e2 ('in' is parsed as 'JOIN_IN') + let (|InExpr|_|) (e: SynExpr) = + match e with + | SynExpr.JoinIn (e1, _, e2, mApp) -> Some (e1, e2, mApp) + | _ -> None + + // e1 on e2 (note: 'on' is the 'JoinConditionWord') + let (|OnExpr|_|) nm (e: SynExpr) = + match tryGetDataForCustomOperation nm with + | None -> None + | Some _ -> + match e with + | SynExpr.App (_, _, SynExpr.App (_, _, e1, SingleIdent opName, _), e2, _) when opName.idText = customOperationJoinConditionWord nm -> + let item = Item.CustomOperation (opName.idText, (fun () -> None), None) + CallNameResolutionSink cenv.tcSink (opName.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) + Some (e1, e2) + | _ -> None + + // e1 into e2 + let (|IntoSuffix|_|) (e: SynExpr) = + match e with + | SynExpr.App (_, _, SynExpr.App (_, _, x, SingleIdent nm2, _), ExprAsPat intoPat, _) when nm2.idText = CustomOperations.Into -> + Some (x, nm2.idRange, intoPat) + | _ -> + None + + let arbPat (m: range) = mkSynPatVar None (mkSynId (m.MakeSynthetic()) "_missingVar") + + let MatchIntoSuffixOrRecover alreadyGivenError (nm: Ident) (e: SynExpr) = + match e with + | IntoSuffix (x, intoWordRange, intoPat) -> + // record the "into" as a custom operation for colorization + let item = Item.CustomOperation ("into", (fun () -> None), None) + CallNameResolutionSink cenv.tcSink (intoWordRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + (x, intoPat, alreadyGivenError) + | _ -> + if not alreadyGivenError then + errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + (e, arbPat e.Range, true) + + let MatchOnExprOrRecover alreadyGivenError nm (onExpr: SynExpr) = + match onExpr with + | OnExpr nm (innerSource, SynExprParen(keySelectors, _, _, _)) -> + (innerSource, keySelectors) + | _ -> + if not alreadyGivenError then + suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv onExpr) |> ignore + errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + (arbExpr("_innerSource", onExpr.Range), mkSynBifix onExpr.Range "=" (arbExpr("_keySelectors", onExpr.Range)) (arbExpr("_keySelector2", onExpr.Range))) + + let JoinOrGroupJoinOp detector e = + match e with + | SynExpr.App (_, _, CustomOpId detector nm, ExprAsPat innerSourcePat, mJoinCore) -> + Some(nm, innerSourcePat, mJoinCore, false) + // join with bad pattern (gives error on "join" and continues) + | SynExpr.App (_, _, CustomOpId detector nm, _innerSourcePatExpr, mJoinCore) -> + errorR(Error(FSComp.SR.tcBinaryOperatorRequiresVariable(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some(nm, arbPat mJoinCore, mJoinCore, true) + // join (without anything after - gives error on "join" and continues) + | CustomOpId detector nm -> + errorR(Error(FSComp.SR.tcBinaryOperatorRequiresVariable(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some(nm, arbPat e.Range, e.Range, true) + | _ -> + None + // JoinOrGroupJoinOp customOperationIsLikeJoin + + let (|JoinOp|_|) (e: SynExpr) = JoinOrGroupJoinOp customOperationIsLikeJoin e + let (|GroupJoinOp|_|) (e: SynExpr) = JoinOrGroupJoinOp customOperationIsLikeGroupJoin e + + let arbKeySelectors m = mkSynBifix m "=" (arbExpr("_keySelectors", m)) (arbExpr("_keySelector2", m)) + + let (|JoinExpr|_|) (e: SynExpr) = + match e with + | InExpr (JoinOp(nm, innerSourcePat, _, alreadyGivenError), onExpr, mJoinCore) -> + let innerSource, keySelectors = MatchOnExprOrRecover alreadyGivenError nm onExpr + Some(nm, innerSourcePat, innerSource, keySelectors, mJoinCore) + | JoinOp (nm, innerSourcePat, mJoinCore, alreadyGivenError) -> + if alreadyGivenError then + errorR(Error(FSComp.SR.tcOperatorRequiresIn(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some (nm, innerSourcePat, arbExpr("_innerSource", e.Range), arbKeySelectors e.Range, mJoinCore) + | _ -> None + + let (|GroupJoinExpr|_|) (e: SynExpr) = + match e with + | InExpr (GroupJoinOp (nm, innerSourcePat, _, alreadyGivenError), intoExpr, mGroupJoinCore) -> + let onExpr, intoPat, alreadyGivenError = MatchIntoSuffixOrRecover alreadyGivenError nm intoExpr + let innerSource, keySelectors = MatchOnExprOrRecover alreadyGivenError nm onExpr + Some (nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) + | GroupJoinOp (nm, innerSourcePat, mGroupJoinCore, alreadyGivenError) -> + if alreadyGivenError then + errorR(Error(FSComp.SR.tcOperatorRequiresIn(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some (nm, innerSourcePat, arbExpr("_innerSource", e.Range), arbKeySelectors e.Range, arbPat e.Range, mGroupJoinCore) + | _ -> + None + + + let (|JoinOrGroupJoinOrZipClause|_|) (e: SynExpr) = + match e with + + // join innerSourcePat in innerSource on (keySelector1 = keySelector2) + | JoinExpr (nm, innerSourcePat, innerSource, keySelectors, mJoinCore) -> + Some(nm, innerSourcePat, innerSource, Some keySelectors, None, mJoinCore) + + // groupJoin innerSourcePat in innerSource on (keySelector1 = keySelector2) into intoPat + | GroupJoinExpr (nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) -> + Some(nm, innerSourcePat, innerSource, Some keySelectors, Some intoPat, mGroupJoinCore) + + // zip intoPat in secondSource + | InExpr (SynExpr.App (_, _, CustomOpId customOperationIsLikeZip nm, ExprAsPat secondSourcePat, _), secondSource, mZipCore) -> + Some(nm, secondSourcePat, secondSource, None, None, mZipCore) + + // zip (without secondSource or in - gives error) + | CustomOpId customOperationIsLikeZip nm -> + errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some(nm, arbPat e.Range, arbExpr("_secondSource", e.Range), None, None, e.Range) + + // zip secondSource (without in - gives error) + | SynExpr.App (_, _, CustomOpId customOperationIsLikeZip nm, ExprAsPat secondSourcePat, mZipCore) -> + errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), mZipCore)) + Some(nm, secondSourcePat, arbExpr("_innerSource", e.Range), None, None, mZipCore) + + | _ -> + None + + let (|ForEachThenJoinOrGroupJoinOrZipClause|_|) strict e = + match e with + | ForEachThen (isFromSource, firstSourcePat, firstSource, JoinOrGroupJoinOrZipClause(nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), innerComp) + when + (let _firstSourceSimplePats, later1 = + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat + Option.isNone later1) + + -> Some (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore, innerComp) + + | JoinOrGroupJoinOrZipClause(nm, pat2, expr2, expr3, pat3opt, mOpCore) when strict -> + errorR(Error(FSComp.SR.tcBinaryOperatorRequiresBody(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + Some (true, arbPat e.Range, arbExpr("_outerSource", e.Range), nm, pat2, expr2, expr3, pat3opt, mOpCore, arbExpr("_innerComp", e.Range)) + + | _ -> + None + + let (|StripApps|) e = + let rec strip e = + match e with + | SynExpr.FromParseError (SynExpr.App (_, _, f, arg, _), _) + | SynExpr.App (_, _, f, arg, _) -> + let g, acc = strip f + g, (arg :: acc) + | _ -> e, [] + let g, acc = strip e + g, List.rev acc + + let (|OptionalIntoSuffix|) e = + match e with + | IntoSuffix (body, intoWordRange, optInfo) -> (body, Some (intoWordRange, optInfo)) + | body -> (body, None) + + let (|CustomOperationClause|_|) e = + match e with + | OptionalIntoSuffix(StripApps(SingleIdent nm, _) as core, optInto) when isCustomOperation nm -> + // Now we know we have a custom operation, commit the name resolution + let optIntoInfo = + match optInto with + | Some (intoWordRange, optInfo) -> + let item = Item.CustomOperation ("into", (fun () -> None), None) + CallNameResolutionSink cenv.tcSink (intoWordRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + Some optInfo + | None -> None + + Some (nm, Option.get (tryGetDataForCustomOperation nm), core, core.Range, optIntoInfo) + | _ -> None + + let mkSynLambda p e m = SynExpr.Lambda (false, false, p, None, e, None, m) + + let mkExprForVarSpace m (patvs: Val list) = + match patvs with + | [] -> SynExpr.Const (SynConst.Unit, m) + | [v] -> SynExpr.Ident v.Id + | vs -> SynExpr.Tuple (false, (vs |> List.map (fun v -> SynExpr.Ident v.Id)), [], m) + + let mkSimplePatForVarSpace m (patvs: Val list) = + let spats = + match patvs with + | [] -> [] + | [v] -> [mkSynSimplePatVar false v.Id] + | vs -> vs |> List.map (fun v -> mkSynSimplePatVar false v.Id) + SynSimplePats.SimplePats (spats, m) + + let mkPatForVarSpace m (patvs: Val list) = + match patvs with + | [] -> SynPat.Const (SynConst.Unit, m) + | [v] -> mkSynPatVar None v.Id + | vs -> SynPat.Tuple(false, (vs |> List.map (fun x -> mkSynPatVar None x.Id)), m) + + let (|OptionalSequential|) e = + match e with + | SynExpr.Sequential (_sp, true, dataComp1, dataComp2, _) -> (dataComp1, Some dataComp2) + | _ -> (e, None) + + // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) + // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay + // NOTE: we should probably suppress these sequence points altogether + let rangeForCombine innerComp1 = + match innerComp1 with + | SynExpr.IfThenElse (_, _, _, _, _, _, _, _, _, mIfToThen, _m) -> mIfToThen + | SynExpr.Match (DebugPointAtBinding.Yes mMatch, _, _, _) -> mMatch + | SynExpr.TryWith (_, _, _, _, _, DebugPointAtTry.Yes mTry, _) -> mTry + | SynExpr.TryFinally (_, _, _, DebugPointAtTry.Yes mTry, _) -> mTry + | SynExpr.For (DebugPointAtFor.Yes mBind, _, _, _, _, _, _) -> mBind + | SynExpr.ForEach (DebugPointAtFor.Yes mBind, _, _, _, _, _, _) -> mBind + | SynExpr.While (DebugPointAtWhile.Yes mWhile, _, _, _) -> mWhile + | _ -> innerComp1.Range + + // Check for 'where x > y', 'select x, y' and other mis-applications of infix operators, give a good error message, and return a flag + let checkForBinaryApp comp = + match comp with + | StripApps(SingleIdent nm, [StripApps(SingleIdent nm2, args); arg2]) when + IsInfixOperator nm.idText && + (match tryExpectedArgCountForCustomOperator nm2 with Some n -> n > 0 | _ -> false) && + not (List.isEmpty args) -> + let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range arg2.Range + errorR(Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator(), estimatedRangeOfIntendedLeftAndRightArguments)) + true + | SynExpr.Tuple (false, StripApps(SingleIdent nm2, args) :: _, _, m) when + (match tryExpectedArgCountForCustomOperator nm2 with Some n -> n > 0 | _ -> false) && + not (List.isEmpty args) -> + let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range m.EndRange + errorR(Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator(), estimatedRangeOfIntendedLeftAndRightArguments)) + true + | _ -> + false + + let addVarsToVarSpace (varSpace: LazyWithContext) f = + LazyWithContext.Create + ((fun m -> + let (patvs: Val list, env) = varSpace.Force m + let vs, envinner = f m env + let patvs = List.append patvs (vs |> List.filter (fun v -> not (patvs |> List.exists (fun v2 -> v.LogicalName = v2.LogicalName)))) + patvs, envinner), + id) + + let emptyVarSpace = LazyWithContext.NotLazy ([], env) + + // If there are no 'yield' in the computation expression, and the builder supports 'Yield', + // then allow the type-directed rule interpreting non-unit-typed expressions in statement + // positions as 'yield'. 'yield!' may be present in the computation expression. + let enableImplicitYield = + cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield + && (hasMethInfo "Yield" && hasMethInfo "Combine" && hasMethInfo "Delay" && YieldFree cenv comp) + + // q - a flag indicating if custom operators are allowed. They are not allowed inside try/with, try/finally, if/then/else etc. + // varSpace - a lazy data structure indicating the variables bound so far in the overall computation + // comp - the computation expression being analyzed + // translatedCtxt - represents the translation of the context in which the computation expression 'comp' occurs, up to a + // hole to be filled by (part of) the results of translating 'comp'. + let rec tryTrans firstTry q varSpace comp translatedCtxt = + + match comp with + + // for firstSourcePat in firstSource do + // join secondSourcePat in expr2 on (expr3 = expr4) + // ... + // --> + // join expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat secondSourcePat -> ...) + + // for firstSourcePat in firstSource do + // groupJoin secondSourcePat in expr2 on (expr3 = expr4) into groupPat + // ... + // --> + // groupJoin expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat groupPat -> ...) + + // for firstSourcePat in firstSource do + // zip secondSource into secondSourcePat + // ... + // --> + // zip expr1 expr2 (fun pat1 pat3 -> ...) + | ForEachThenJoinOrGroupJoinOrZipClause true (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, secondResultPatOpt, mOpCore, innerComp) -> + + if q = CustomOperationsMode.Denied then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), nm.idRange)) + let firstSource = mkSourceExprConditional isFromSource firstSource + let secondSource = mkSourceExpr secondSource + + // Add the variables to the variable space, on demand + let varSpaceWithFirstVars = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (firstSourcePat, None) + vspecs, envinner) + + let varSpaceWithSecondVars = + addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (secondSourcePat, None) + vspecs, envinner) + + let varSpaceWithGroupJoinVars = + match secondResultPatOpt with + | Some pat3 -> + addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat3, None) + vspecs, envinner) + | None -> varSpace + + let firstSourceSimplePats, later1 = SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat + let secondSourceSimplePats, later2 = SimplePatsOfPat cenv.synArgNameGenerator secondSourcePat + + if Option.isSome later1 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), firstSourcePat.Range)) + if Option.isSome later2 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondSourcePat.Range)) + + // check 'join' or 'groupJoin' or 'zip' is permitted for this builder + match tryGetDataForCustomOperation nm with + | None -> error(Error(FSComp.SR.tcMissingCustomOperation(nm.idText), nm.idRange)) + | Some opDatas -> + let opName, _, _, _, _, _, _, _, methInfo = opDatas.[0] + + // Record the resolution of the custom operation for posterity + let item = Item.CustomOperation (opName, (fun () -> customOpUsageText nm), Some methInfo) + + // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE. + CallNameResolutionSink cenv.tcSink (nm.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + + let mkJoinExpr keySelector1 keySelector2 innerPat e = + let mSynthetic = mOpCore.MakeSynthetic() + mkSynCall methInfo.DisplayName mOpCore + [ firstSource + secondSource + (mkSynLambda firstSourceSimplePats keySelector1 mSynthetic) + (mkSynLambda secondSourceSimplePats keySelector2 mSynthetic) + (mkSynLambda firstSourceSimplePats (mkSynLambda innerPat e mSynthetic) mSynthetic) ] + + let mkZipExpr e = + let mSynthetic = mOpCore.MakeSynthetic() + mkSynCall methInfo.DisplayName mOpCore + [ firstSource + secondSource + (mkSynLambda firstSourceSimplePats (mkSynLambda secondSourceSimplePats e mSynthetic) mSynthetic) ] + + // wraps given expression into sequence with result produced by arbExpr so result will look like: + // l; SynExpr.ArbitraryAfterError (...) + // this allows to handle cases like 'on (a > b)' // '>' is not permitted as correct join relation + // after wrapping a and b can still be typechecked (so we'll have correct completion inside 'on' part) + // but presence of SynExpr.ArbitraryAfterError allows to avoid errors about incompatible types in cases like + // query { + // for a in [1] do + // join b in [""] on (a > b) + // } + // if we typecheck raw 'a' and 'b' then we'll end up with 2 errors: + // 1. incorrect join relation + // 2. incompatible types: int and string + // with SynExpr.ArbitraryAfterError we have only first one + let wrapInArbErrSequence l caption = + SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, true, l, (arbExpr(caption, l.Range.EndRange)), l.Range) + + let mkOverallExprGivenVarSpaceExpr, varSpaceInner = + let isNullableOp opId = + match DecompileOpName opId with "?=" | "=?" | "?=?" -> true | _ -> false + match secondResultPatOpt, keySelectorsOpt with + // groupJoin + | Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin nm -> + let secondResultSimplePats, later3 = SimplePatsOfPat cenv.synArgNameGenerator secondResultPat + if Option.isSome later3 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondResultPat.Range)) + match relExpr with + | JoinRelation cenv env (keySelector1, keySelector2) -> + mkJoinExpr keySelector1 keySelector2 secondResultSimplePats, varSpaceWithGroupJoinVars + | BinOpExpr (opId, l, r) -> + if isNullableOp opId.idText then + // When we cannot resolve NullableOps, recommend the relevant namespace to be added + errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range)) + else + errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) + let l = wrapInArbErrSequence l "_keySelector1" + let r = wrapInArbErrSequence r "_keySelector2" + // this is not correct JoinRelation but it is still binary operation + // we've already reported error now we can use operands of binary operation as join components + mkJoinExpr l r secondResultSimplePats, varSpaceWithGroupJoinVars + | _ -> + errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) + // since the shape of relExpr doesn't match our expectations (JoinRelation) + // then we assume that this is l.h.s. of the join relation + // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in GroupJoin method + mkJoinExpr relExpr (arbExpr("_keySelector2", relExpr.Range)) secondResultSimplePats, varSpaceWithGroupJoinVars + + | None, Some relExpr when customOperationIsLikeJoin nm -> + match relExpr with + | JoinRelation cenv env (keySelector1, keySelector2) -> + mkJoinExpr keySelector1 keySelector2 secondSourceSimplePats, varSpaceWithSecondVars + | BinOpExpr (opId, l, r) -> + if isNullableOp opId.idText then + // When we cannot resolve NullableOps, recommend the relevant namespace to be added + errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range)) + else + errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) + // this is not correct JoinRelation but it is still binary operation + // we've already reported error now we can use operands of binary operation as join components + let l = wrapInArbErrSequence l "_keySelector1" + let r = wrapInArbErrSequence r "_keySelector2" + mkJoinExpr l r secondSourceSimplePats, varSpaceWithGroupJoinVars + | _ -> + errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) + // since the shape of relExpr doesn't match our expectations (JoinRelation) + // then we assume that this is l.h.s. of the join relation + // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in Join method + mkJoinExpr relExpr (arbExpr("_keySelector2", relExpr.Range)) secondSourceSimplePats, varSpaceWithGroupJoinVars + + | None, None when customOperationIsLikeZip nm -> + mkZipExpr, varSpaceWithSecondVars + + | _ -> + assert false + failwith "unreachable" + + + // Case from C# spec: A query expression with a join clause with an into followed by something other than a select clause + // Case from C# spec: A query expression with a join clause without an into followed by something other than a select clause + let valsInner, _env = varSpaceInner.Force mOpCore + let varSpaceExpr = mkExprForVarSpace mOpCore valsInner + let varSpacePat = mkPatForVarSpace mOpCore valsInner + let joinExpr = mkOverallExprGivenVarSpaceExpr varSpaceExpr + Some (trans CompExprTranslationPass.Initial q varSpaceInner (SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, joinExpr, innerComp, mOpCore)) translatedCtxt) + + + | SynExpr.ForEach (spForLoop, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _) -> + let sourceExpr = + match RewriteRangeExpr sourceExpr with + | Some e -> e + | None -> sourceExpr + let wrappedSourceExpr = mkSourceExprConditional isFromSource sourceExpr + let mFor = match spForLoop with DebugPointAtFor.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.For) | _ -> pat.Range + let mPat = pat.Range + let spBind = match spForLoop with DebugPointAtFor.Yes m -> DebugPointAtBinding.Yes m | DebugPointAtFor.No -> DebugPointAtBinding.NoneAtSticky + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mFor ad "For" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("For"), mFor)) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) + vspecs, envinner) + + Some (trans CompExprTranslationPass.Initial q varSpace innerComp + (fun holeFill -> + translatedCtxt (mkSynCall "For" mFor [wrappedSourceExpr; SynExpr.MatchLambda (false, sourceExpr.Range, [SynMatchClause(pat, None, None, holeFill, mPat, DebugPointAtTarget.Yes)], spBind, mFor) ])) ) + + | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> + let mFor = match spBind with DebugPointAtFor.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.For) | _ -> m + if isQuery then errorR(Error(FSComp.SR.tcNoIntegerForLoopInQuery(), mFor)) + Some (trans CompExprTranslationPass.Initial q varSpace (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m)) translatedCtxt ) + + | SynExpr.While (spWhile, guardExpr, innerComp, _) -> + let mGuard = guardExpr.Range + let mWhile = match spWhile with DebugPointAtWhile.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.While) | _ -> mGuard + if isQuery then error(Error(FSComp.SR.tcNoWhileInQuery(), mWhile)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "While" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("While"), mWhile)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "Delay" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mWhile)) + Some(trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "While" mWhile [mkSynDelay2 guardExpr; mkSynCall "Delay" mWhile [mkSynDelay innerComp.Range holeFill]])) ) + + | SynExpr.TryFinally (innerComp, unwindExpr, mTryToLast, spTry, _spFinally) -> + + let mTry = match spTry with DebugPointAtTry.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.Try) | _ -> mTryToLast + if isQuery then error(Error(FSComp.SR.tcNoTryFinallyInQuery(), mTry)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryFinally" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("TryFinally"), mTry)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mTry)) + Some (translatedCtxt (mkSynCall "TryFinally" mTry [mkSynCall "Delay" mTry [mkSynDelay innerComp.Range (transNoQueryOps innerComp)]; mkSynDelay2 unwindExpr])) + + | SynExpr.Paren (_, _, _, m) -> + error(Error(FSComp.SR.tcConstructIsAmbiguousInComputationExpression(), m)) + + // In some cases the node produced by `mkSynCall "Zero" m []` may be discarded in the case + // of implicit yields - for example "list { 1; 2 }" when each expression checks as an implicit yield. + // If it is not discarded, the syntax node will later be checked and the existence/non-existence of the Zero method + // will be checked/reported appropriately (though the error message won't mention computation expressions + // like our other error messages for missing methods). + | SynExpr.ImplicitZero m -> + if (not enableImplicitYield) && + isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"), m)) + Some (translatedCtxt (mkSynCall "Zero" m [])) + + | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _) + when firstTry = CompExprTranslationPass.Initial -> + + // 'join' clauses preceded by 'let' and other constructs get processed by repackaging with a 'for' loop. + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs + let varSpacePat = mkPatForVarSpace mClause patvs + + let dataCompPrior = + translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn ((true, false), varSpaceExpr, mClause))) + + // Rebind using for ... + let rebind = + SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, dataCompPrior, comp, comp.Range) + + // Retry with the 'for' loop packaging. Set firstTry=false just in case 'join' processing fails + tryTrans CompExprTranslationPass.Subsequent q varSpace rebind id + + + | OptionalSequential (CustomOperationClause (nm, _, opExpr, mClause, _), _) -> + + if q = CustomOperationsMode.Denied then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), opExpr.Range)) + + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs + + let dataCompPriorToOp = + let isYield = not (customOperationMaintainsVarSpaceUsingBind nm) + translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn ((isYield, false), varSpaceExpr, mClause))) + + + // Now run the consumeCustomOpClauses + Some (consumeCustomOpClauses q varSpace dataCompPriorToOp comp false mClause) + + | SynExpr.Sequential (sp, true, innerComp1, innerComp2, m) -> + + // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1 + if isQuery && checkForBinaryApp innerComp1 then + Some (trans CompExprTranslationPass.Initial q varSpace innerComp2 translatedCtxt) + + else + + if isQuery && not(innerComp1.IsArbExprAndThusAlreadyReportedError) then + match innerComp1 with + | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential + | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), innerComp1.RangeOfFirstPortion)) + + match tryTrans CompExprTranslationPass.Initial CustomOperationsMode.Denied varSpace innerComp1 id with + | Some c -> + // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) + // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay + // NOTE: we should probably suppress these sequence points altogether + let m1 = rangeForCombine innerComp1 + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Combine" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Combine"), m)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Delay" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), m)) + Some (translatedCtxt (mkSynCall "Combine" m1 [c; mkSynCall "Delay" m1 [mkSynDelay innerComp2.Range (transNoQueryOps innerComp2)]])) + | None -> + // "do! expr; cexpr" is treated as { let! () = expr in cexpr } + match innerComp1 with + | SynExpr.DoBang (rhsExpr, m) -> + let sp = + match sp with + | DebugPointAtSequential.SuppressExpr -> DebugPointAtBinding.NoneAtDo + | DebugPointAtSequential.SuppressBoth -> DebugPointAtBinding.NoneAtDo + | DebugPointAtSequential.SuppressStmt -> DebugPointAtBinding.Yes m + | DebugPointAtSequential.SuppressNeither -> DebugPointAtBinding.Yes m + Some(trans CompExprTranslationPass.Initial q varSpace (SynExpr.LetOrUseBang (sp, false, true, SynPat.Const(SynConst.Unit, rhsExpr.Range), rhsExpr, [], innerComp2, m)) translatedCtxt) + + // "expr; cexpr" is treated as sequential execution + | _ -> + Some (trans CompExprTranslationPass.Initial q varSpace innerComp2 (fun holeFill -> + let fillExpr = + if enableImplicitYield then + // When implicit yields are enabled, then if the 'innerComp1' checks as type + // 'unit' we interpret the expression as a sequential, and when it doesn't + // have type 'unit' we interpret it as a 'Yield + Combine'. + let combineExpr = + let m1 = rangeForCombine innerComp1 + let implicitYieldExpr = mkSynCall "Yield" comp.Range [innerComp1] + mkSynCall "Combine" m1 [implicitYieldExpr; mkSynCall "Delay" m1 [mkSynDelay holeFill.Range holeFill]] + SynExpr.SequentialOrImplicitYield(sp, innerComp1, holeFill, combineExpr, m) + else + SynExpr.Sequential(sp, true, innerComp1, holeFill, m) + translatedCtxt fillExpr)) + + | SynExpr.IfThenElse (ifKw, isElif, guardExpr, thenKw, thenComp, elseKw, elseCompOpt, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch) -> + match elseCompOpt with + | Some elseComp -> + if isQuery then error(Error(FSComp.SR.tcIfThenElseMayNotBeUsedWithinQueries(), mIfToThen)) + Some (translatedCtxt (SynExpr.IfThenElse (ifKw, isElif, guardExpr, thenKw, transNoQueryOps thenComp, elseKw, Some(transNoQueryOps elseComp), spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch))) + | None -> + let elseComp = + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mIfToThen ad "Zero" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"), mIfToThen)) + mkSynCall "Zero" mIfToThen [] + Some (trans CompExprTranslationPass.Initial q varSpace thenComp (fun holeFill -> translatedCtxt (SynExpr.IfThenElse (ifKw, isElif, guardExpr, thenKw, holeFill, None, Some elseComp, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch)))) + + // 'let binds in expr' + | SynExpr.LetOrUse (isRec, false, binds, innerComp, m) -> + + // For 'query' check immediately + if isQuery then + match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with + | [NormalizedBinding(_, SynBindingKind.Normal, (*inline*)false, (*mutable*)false, _, _, _, _, _, _, _, _)] when not isRec -> + () + | normalizedBindings -> + let failAt m = error(Error(FSComp.SR.tcNonSimpleLetBindingInQuery(), m)) + match normalizedBindings with + | NormalizedBinding(_, _, _, _, _, _, _, _, _, _, mBinding, _) :: _ -> failAt mBinding + | _ -> failAt m + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun mQueryOp env -> + // Normalize the bindings before detecting the bound variables + match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with + | [NormalizedBinding(_vis, SynBindingKind.Normal, false, false, _, _, _, _, pat, _, _, _)] -> + // successful case + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) + vspecs, envinner + | _ -> + // error case + error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings(), mQueryOp))) + + Some (trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt (SynExpr.LetOrUse (isRec, false, binds, holeFill, m)))) + + // 'use x = expr in expr' + | SynExpr.LetOrUse (_, true, [SynBinding (_, SynBindingKind.Normal, _, _, _, _, _, pat, _, rhsExpr, _, spBind)], innerComp, _) -> + let bindRange = match spBind with DebugPointAtBinding.Yes m -> m | _ -> rhsExpr.Range + if isQuery then error(Error(FSComp.SR.tcUseMayNotBeUsedInQueries(), bindRange)) + let innerCompRange = innerComp.Range + let consumeExpr = SynExpr.MatchLambda(false, innerCompRange, [SynMatchClause(pat, None, None, transNoQueryOps innerComp, innerCompRange, DebugPointAtTarget.Yes)], spBind, innerCompRange) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Using" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Using"), bindRange)) + Some (translatedCtxt (mkSynCall "Using" bindRange [rhsExpr; consumeExpr ])) + + // 'let! pat = expr in expr' + // --> build.Bind(e1, (fun _argN -> match _argN with pat -> expr)) + // or + // --> build.BindReturn(e1, (fun _argN -> match _argN with pat -> expr-without-return)) + | SynExpr.LetOrUseBang (spBind, false, isFromSource, pat, rhsExpr, [], innerComp, _) -> + + let bindRange = match spBind with DebugPointAtBinding.Yes m -> m | _ -> rhsExpr.Range + if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), bindRange)) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) + vspecs, envinner) + + let rhsExpr = mkSourceExprConditional isFromSource rhsExpr + Some (transBind q varSpace bindRange "Bind" [rhsExpr] pat spBind innerComp translatedCtxt) + + // 'use! pat = e1 in e2' --> build.Bind(e1, (function _argN -> match _argN with pat -> build.Using(x, (fun _argN -> match _argN with pat -> e2)))) + | SynExpr.LetOrUseBang (spBind, true, isFromSource, (SynPat.Named (id, false, _, _) as pat) , rhsExpr, [], innerComp, _) + | SynExpr.LetOrUseBang (spBind, true, isFromSource, (SynPat.LongIdent (longDotId=LongIdentWithDots([id], _)) as pat), rhsExpr, [], innerComp, _) -> + + let bindRange = match spBind with DebugPointAtBinding.Yes m -> m | _ -> rhsExpr.Range + if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), bindRange)) + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Using" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Using"), bindRange)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Bind" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), bindRange)) + + let consumeExpr = SynExpr.MatchLambda(false, bindRange, [SynMatchClause(pat, None, None, transNoQueryOps innerComp, innerComp.Range, DebugPointAtTarget.Yes)], spBind, bindRange) + let consumeExpr = mkSynCall "Using" bindRange [SynExpr.Ident(id); consumeExpr ] + let consumeExpr = SynExpr.MatchLambda(false, bindRange, [SynMatchClause(pat, None, None, consumeExpr, id.idRange, DebugPointAtTarget.Yes)], spBind, bindRange) + let rhsExpr = mkSourceExprConditional isFromSource rhsExpr + // TODO: consider allowing translation to BindReturn + Some(translatedCtxt (mkSynCall "Bind" bindRange [rhsExpr; consumeExpr])) + + // 'use! pat = e1 ... in e2' where 'pat' is not a simple name --> error + | SynExpr.LetOrUseBang (_spBind, true, _isFromSource, pat, _rhsExpr, andBangs, _innerComp, _) -> + if isNil andBangs then + error(Error(FSComp.SR.tcInvalidUseBangBinding(), pat.Range)) + else + error(Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs(), comp.Range)) + + // 'let! pat1 = expr1 and! pat2 = expr2 in ...' --> + // build.BindN(expr1, expr2, ...) + // or + // build.BindNReturn(expr1, expr2, ...) + // or + // build.Bind(build.MergeSources(expr1, expr2), ...) + | SynExpr.LetOrUseBang(letSpBind, false, isFromSource, letPat, letRhsExpr, andBangBindings, innerComp, letBindRange) -> + if not (cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang) then + error(Error(FSComp.SR.tcAndBangNotSupported(), comp.Range)) + + if isQuery then + error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), letBindRange)) + + let bindRange = match letSpBind with DebugPointAtBinding.Yes m -> m | _ -> letRhsExpr.Range + let sources = (letRhsExpr :: [for _, _, _, _, andExpr, _ in andBangBindings -> andExpr ]) |> List.map (mkSourceExprConditional isFromSource) + let pats = letPat :: [for _, _, _, andPat, _, _ in andBangBindings -> andPat ] + let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges + + let numSources = sources.Length + let bindReturnNName = "Bind"+string numSources+"Return" + let bindNName = "Bind"+string numSources + + // Check if this is a Bind2Return etc. + let hasBindReturnN = not (isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindReturnNName builderTy)) + if hasBindReturnN && Option.isSome (convertSimpleReturnToExpr varSpace innerComp) then + let consumePat = SynPat.Tuple(false, pats, letPat.Range) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (consumePat, None) + vspecs, envinner) + + Some (transBind q varSpace bindRange bindNName sources consumePat letSpBind innerComp translatedCtxt) + + else + + // Check if this is a Bind2 etc. + let hasBindN = not (isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindNName builderTy)) + if hasBindN then + let consumePat = SynPat.Tuple(false, pats, letPat.Range) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (consumePat, None) + vspecs, envinner) + + Some (transBind q varSpace bindRange bindNName sources consumePat letSpBind innerComp translatedCtxt) + else + + // Look for the maximum supported MergeSources, MergeSources3, ... + let mkMergeSourcesName n = if n = 2 then "MergeSources" else "MergeSources"+(string n) + + let maxMergeSources = + let rec loop (n: int) = + let mergeSourcesName = mkMergeSourcesName n + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad mergeSourcesName builderTy) then + (n-1) + else + loop (n+1) + loop 2 + + if maxMergeSources = 1 then error(Error(FSComp.SR.tcRequireMergeSourcesOrBindN(bindNName), bindRange)) + + let rec mergeSources (sourcesAndPats: (SynExpr * SynPat) list) = + let numSourcesAndPats = sourcesAndPats.Length + assert (numSourcesAndPats <> 0) + if numSourcesAndPats = 1 then + sourcesAndPats.[0] + + elif numSourcesAndPats <= maxMergeSources then + + // Call MergeSources2(e1, e2), MergeSources3(e1, e2, e3) etc + let mergeSourcesName = mkMergeSourcesName numSourcesAndPats + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad mergeSourcesName builderTy) then + error(Error(FSComp.SR.tcRequireMergeSourcesOrBindN(bindNName), bindRange)) + + let source = mkSynCall mergeSourcesName sourcesRange (List.map fst sourcesAndPats) + let pat = SynPat.Tuple(false, List.map snd sourcesAndPats, letPat.Range) + source, pat + + else + + // Call MergeSourcesMax(e1, e2, e3, e4, (...)) + let nowSourcesAndPats, laterSourcesAndPats = List.splitAt (maxMergeSources - 1) sourcesAndPats + let mergeSourcesName = mkMergeSourcesName maxMergeSources + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad mergeSourcesName builderTy) then + error(Error(FSComp.SR.tcRequireMergeSourcesOrBindN(bindNName), bindRange)) + + let laterSource, laterPat = mergeSources laterSourcesAndPats + let source = mkSynCall mergeSourcesName sourcesRange (List.map fst nowSourcesAndPats @ [laterSource]) + let pat = SynPat.Tuple(false, List.map snd nowSourcesAndPats @ [laterPat], letPat.Range) + source, pat + + let mergedSources, consumePat = mergeSources (List.zip sources pats) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (consumePat, None) + vspecs, envinner) + + // Build the 'Bind' call + Some (transBind q varSpace bindRange "Bind" [mergedSources] consumePat letSpBind innerComp translatedCtxt) + + | SynExpr.Match (spMatch, expr, clauses, m) -> + let mMatch = match spMatch with DebugPointAtBinding.Yes mMatch -> mMatch | _ -> m + if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) + let clauses = clauses |> List.map (fun (SynMatchClause(pat, cond, arrow, innerComp, patm, sp)) -> SynMatchClause(pat, cond, arrow, transNoQueryOps innerComp, patm, sp)) + Some(translatedCtxt (SynExpr.Match (spMatch, expr, clauses, m))) + + // 'match! expr with pats ...' --> build.Bind(e1, (function pats ...)) + | SynExpr.MatchBang (spMatch, expr, clauses, m) -> + let matchExpr = mkSourceExpr expr + let mMatch = match spMatch with DebugPointAtBinding.Yes mMatch -> mMatch | _ -> m + if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mMatch ad "Bind" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), mMatch)) + + let clauses = clauses |> List.map (fun (SynMatchClause(pat, cond, arrow, innerComp, patm, sp)) -> SynMatchClause(pat, cond, arrow, transNoQueryOps innerComp, patm, sp)) + let consumeExpr = SynExpr.MatchLambda (false, mMatch, clauses, spMatch, mMatch) + + // TODO: consider allowing translation to BindReturn + Some(translatedCtxt (mkSynCall "Bind" mMatch [matchExpr; consumeExpr])) + + | SynExpr.TryWith (innerComp, _mTryToWith, clauses, _mWithToLast, mTryToLast, spTry, _spWith) -> + let mTry = match spTry with DebugPointAtTry.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.Try) | _ -> mTryToLast + + if isQuery then error(Error(FSComp.SR.tcTryWithMayNotBeUsedInQueries(), mTry)) + + let clauses = clauses |> List.map (fun (SynMatchClause(pat, cond, arrow, clauseComp, patm, sp)) -> SynMatchClause(pat, cond, arrow, transNoQueryOps clauseComp, patm, sp)) + let consumeExpr = SynExpr.MatchLambda(true, mTryToLast, clauses, DebugPointAtBinding.NoneAtSticky, mTryToLast) + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryWith" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("TryWith"), mTry)) + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mTry)) + + Some(translatedCtxt (mkSynCall "TryWith" mTry [mkSynCall "Delay" mTry [mkSynDelay2 (transNoQueryOps innerComp)]; consumeExpr])) + + | SynExpr.YieldOrReturnFrom ((true, _), yieldExpr, m) -> + let yieldFromExpr = mkSourceExpr yieldExpr + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "YieldFrom" builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod("YieldFrom"), m)) + Some (translatedCtxt (mkSynCall "YieldFrom" m [yieldFromExpr])) + + | SynExpr.YieldOrReturnFrom ((false, _), returnedExpr, m) -> + let returnFromExpr = mkSourceExpr returnedExpr + if isQuery then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(), m)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "ReturnFrom" builderTy) then + errorR(Error(FSComp.SR.tcRequireBuilderMethod("ReturnFrom"), m)) + Some (translatedCtxt returnFromExpr) + else + Some (translatedCtxt (mkSynCall "ReturnFrom" m [returnFromExpr])) + + | SynExpr.YieldOrReturn ((isYield, _), yieldExpr, m) -> + let methName = (if isYield then "Yield" else "Return") + if isQuery && not isYield then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(), m)) + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad methName builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod(methName), m)) + Some(translatedCtxt (mkSynCall methName m [yieldExpr])) + + | _ -> None + + and consumeCustomOpClauses q (varSpace: LazyWithContext<_, _>) dataCompPrior compClausesExpr lastUsesBind mClause = + + // Substitute 'yield ' into the context + + let patvs, _env = varSpace.Force comp.Range + let varSpaceSimplePat = mkSimplePatForVarSpace mClause patvs + let varSpacePat = mkPatForVarSpace mClause patvs + + match compClausesExpr with + + // Detect one custom operation... This clause will always match at least once... + | OptionalSequential (CustomOperationClause (nm, opDatas, opExpr, mClause, optionalIntoPat), optionalCont) -> + + let opName, _, _, _, _, _, _, _, methInfo = opDatas.[0] + let isLikeZip = customOperationIsLikeZip nm + let isLikeJoin = customOperationIsLikeJoin nm + let isLikeGroupJoin = customOperationIsLikeZip nm + + // Record the resolution of the custom operation for posterity + let item = Item.CustomOperation (opName, (fun () -> customOpUsageText nm), Some methInfo) + + // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE. + CallNameResolutionSink cenv.tcSink (nm.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + + if isLikeZip || isLikeJoin || isLikeGroupJoin then + errorR(Error(FSComp.SR.tcBinaryOperatorRequiresBody(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + match optionalCont with + | None -> + // we are about to drop the 'opExpr' AST on the floor. we've already reported an error. attempt to get name resolutions before dropping it + RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv opExpr + dataCompPrior + | Some contExpr -> consumeCustomOpClauses q varSpace dataCompPrior contExpr lastUsesBind mClause + else + + let maintainsVarSpace = customOperationMaintainsVarSpace nm + let maintainsVarSpaceUsingBind = customOperationMaintainsVarSpaceUsingBind nm + + let expectedArgCount = tryExpectedArgCountForCustomOperator nm + + let dataCompAfterOp = + match opExpr with + | StripApps(SingleIdent nm, args) -> + let argCountsMatch = + match expectedArgCount with + | Some n -> n = args.Length + | None -> cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations + if argCountsMatch then + // Check for the [] attribute on each argument position + let args = args |> List.mapi (fun i arg -> + if isCustomOperationProjectionParameter (i+1) nm then + SynExpr.Lambda (false, false, varSpaceSimplePat, None, arg, None, arg.Range.MakeSynthetic()) + else arg) + mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) + else + let expectedArgCount = defaultArg expectedArgCount 0 + errorR(Error(FSComp.SR.tcCustomOperationHasIncorrectArgCount(nm.idText, expectedArgCount, args.Length), nm.idRange)) + mkSynCall methInfo.DisplayName mClause ([ dataCompPrior ] @ List.init expectedArgCount (fun i -> arbExpr("_arg" + string i, mClause))) + | _ -> failwith "unreachable" + + match optionalCont with + | None -> + match optionalIntoPat with + | Some intoPat -> errorR(Error(FSComp.SR.tcIntoNeedsRestOfQuery(), intoPat.Range)) + | None -> () + dataCompAfterOp + + | Some contExpr -> + + // select a.Name into name; ... + // distinct into d; ... + // + // Rebind the into pattern and process the rest of the clauses + match optionalIntoPat with + | Some intoPat -> + if not (customOperationAllowsInto nm) then + error(Error(FSComp.SR.tcOperatorDoesntAcceptInto(nm.idText), intoPat.Range)) + + // Rebind using either for ... or let!.... + let rebind = + if maintainsVarSpaceUsingBind then + SynExpr.LetOrUseBang (DebugPointAtBinding.NoneAtLet, false, false, intoPat, dataCompAfterOp, [], contExpr, intoPat.Range) + else + SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, intoPat, dataCompAfterOp, contExpr, intoPat.Range) + + trans CompExprTranslationPass.Initial q emptyVarSpace rebind id + + // select a.Name; ... + // distinct; ... + // + // Process the rest of the clauses + | None -> + if maintainsVarSpace || maintainsVarSpaceUsingBind then + consumeCustomOpClauses q varSpace dataCompAfterOp contExpr maintainsVarSpaceUsingBind mClause + else + consumeCustomOpClauses q emptyVarSpace dataCompAfterOp contExpr false mClause + + // No more custom operator clauses in compClausesExpr, but there may be clauses like join, yield etc. + // Bind/iterate the dataCompPrior and use compClausesExpr as the body. + | _ -> + // Rebind using either for ... or let!.... + let rebind = + if lastUsesBind then + SynExpr.LetOrUseBang (DebugPointAtBinding.NoneAtLet, false, false, varSpacePat, dataCompPrior, [], compClausesExpr, compClausesExpr.Range) + else + SynExpr.ForEach (DebugPointAtFor.No, SeqExprOnly false, false, varSpacePat, dataCompPrior, compClausesExpr, compClausesExpr.Range) + + trans CompExprTranslationPass.Initial q varSpace rebind id + + and transNoQueryOps comp = + trans CompExprTranslationPass.Initial CustomOperationsMode.Denied emptyVarSpace comp id + + and trans firstTry q varSpace comp translatedCtxt = + match tryTrans firstTry q varSpace comp translatedCtxt with + | Some e -> e + | None -> + // This only occurs in final position in a sequence + match comp with + // "do! expr;" in final position is treated as { let! () = expr in return () } when Return is provided (and no Zero with Default attribute is available) or as { let! () = expr in zero } otherwise + | SynExpr.DoBang (rhsExpr, m) -> + let mUnit = rhsExpr.Range + let rhsExpr = mkSourceExpr rhsExpr + if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), m)) + let bodyExpr = + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Return" builderTy) then + SynExpr.ImplicitZero m + else + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Zero" builderTy with + | minfo :: _ when MethInfoHasAttribute cenv.g m cenv.g.attrib_DefaultValueAttribute minfo -> SynExpr.ImplicitZero m + | _ -> SynExpr.YieldOrReturn ((false, true), SynExpr.Const (SynConst.Unit, m), m) + trans CompExprTranslationPass.Initial q varSpace (SynExpr.LetOrUseBang (DebugPointAtBinding.NoneAtDo, false, false, SynPat.Const(SynConst.Unit, mUnit), rhsExpr, [], bodyExpr, m)) translatedCtxt + + // "expr;" in final position is treated as { expr; zero } + // Suppress the sequence point on the "zero" + | _ -> + // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore comp + if isQuery && checkForBinaryApp comp then + trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) translatedCtxt + else + if isQuery && not comp.IsArbExprAndThusAlreadyReportedError then + match comp with + | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential + | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), comp.RangeOfFirstPortion)) + trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) (fun holeFill -> + let fillExpr = + if enableImplicitYield then + let implicitYieldExpr = mkSynCall "Yield" comp.Range [comp] + SynExpr.SequentialOrImplicitYield(DebugPointAtSequential.SuppressExpr, comp, holeFill, implicitYieldExpr, comp.Range) + else + SynExpr.Sequential(DebugPointAtSequential.SuppressExpr, true, comp, holeFill, comp.Range) + translatedCtxt fillExpr) + + and transBind q varSpace bindRange bindName bindArgs (consumePat: SynPat) spBind (innerComp: SynExpr) translatedCtxt = + + let innerRange = innerComp.Range + + let innerCompReturn = + if cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang then + convertSimpleReturnToExpr varSpace innerComp + else None + + match innerCompReturn with + | Some (innerExpr, customOpInfo) when + (let bindName = bindName + "Return" + not (isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindName builderTy))) -> + + let bindName = bindName + "Return" + + // Build the `BindReturn` call + let dataCompPriorToOp = + let consumeExpr = SynExpr.MatchLambda(false, consumePat.Range, [SynMatchClause(consumePat, None, None, innerExpr, innerRange, DebugPointAtTarget.Yes)], spBind, innerRange) + translatedCtxt (mkSynCall bindName bindRange (bindArgs @ [consumeExpr])) + + match customOpInfo with + | None -> dataCompPriorToOp + | Some (innerComp, mClause) -> + // If the `BindReturn` was forced by a custom operation, continue to process the clauses of the CustomOp + consumeCustomOpClauses q varSpace dataCompPriorToOp innerComp false mClause + + | _ -> + + if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindName builderTy) then + error(Error(FSComp.SR.tcRequireBuilderMethod(bindName), bindRange)) + + // Build the `Bind` call + trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> + let consumeExpr = SynExpr.MatchLambda(false, consumePat.Range, [SynMatchClause(consumePat, None, None, holeFill, innerRange, DebugPointAtTarget.Yes)], spBind, innerRange) + translatedCtxt (mkSynCall bindName bindRange (bindArgs @ [consumeExpr]))) + + and convertSimpleReturnToExpr varSpace innerComp = + match innerComp with + | SynExpr.YieldOrReturn ((false, _), returnExpr, _) -> Some (returnExpr, None) + | SynExpr.Match (spMatch, expr, clauses, m) -> + let clauses = + clauses |> List.map (fun (SynMatchClause(pat, cond, arrow, innerComp2, patm, sp)) -> + match convertSimpleReturnToExpr varSpace innerComp2 with + | None -> None // failure + | Some (_, Some _) -> None // custom op on branch = failure + | Some (innerExpr2, None) -> Some (SynMatchClause(pat, cond, arrow, innerExpr2, patm, sp))) + if clauses |> List.forall Option.isSome then + Some (SynExpr.Match (spMatch, expr, (clauses |> List.map Option.get), m), None) + else + None + + | SynExpr.IfThenElse (ifKw, isElif, guardExpr, thenKw, thenComp, elseKw, elseCompOpt, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch) -> + match convertSimpleReturnToExpr varSpace thenComp with + | None -> None + | Some (_, Some _) -> None + | Some (thenExpr, None) -> + let elseExprOptOpt = + match elseCompOpt with + | None -> Some None + | Some elseComp -> + match convertSimpleReturnToExpr varSpace elseComp with + | None -> None // failure + | Some (_, Some _) -> None // custom op on branch = failure + | Some (elseExpr, None) -> Some (Some elseExpr) + match elseExprOptOpt with + | None -> None + | Some elseExprOpt -> Some (SynExpr.IfThenElse (ifKw, isElif, guardExpr, thenKw, thenExpr, elseKw, elseExprOpt, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch), None) + + | SynExpr.LetOrUse (isRec, false, binds, innerComp, m) -> + match convertSimpleReturnToExpr varSpace innerComp with + | None -> None + | Some (_, Some _) -> None + | Some (innerExpr, None) -> Some (SynExpr.LetOrUse (isRec, false, binds, innerExpr, m), None) + + | OptionalSequential (CustomOperationClause (nm, _, _, mClause, _), _) when customOperationMaintainsVarSpaceUsingBind nm -> + + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs + + Some (varSpaceExpr, Some (innerComp, mClause)) + + | SynExpr.Sequential (sp, true, innerComp1, innerComp2, m) -> + + // Check the first part isn't a computation expression construct + if isSimpleExpr innerComp1 then + // Check the second part is a simple return + match convertSimpleReturnToExpr varSpace innerComp2 with + | None -> None + | Some (innerExpr2, optionalCont) -> Some (SynExpr.Sequential (sp, true, innerComp1, innerExpr2, m), optionalCont) + else + None + + | _ -> None + + /// Check is an expression has no computation expression constructs + and isSimpleExpr comp = + + match comp with + | ForEachThenJoinOrGroupJoinOrZipClause false _ -> false + | SynExpr.ForEach _ -> false + | SynExpr.For _ -> false + | SynExpr.While _ -> false + | SynExpr.TryFinally _ -> false + | SynExpr.ImplicitZero _ -> false + | OptionalSequential (JoinOrGroupJoinOrZipClause _, _) -> false + | OptionalSequential (CustomOperationClause _, _) -> false + | SynExpr.Sequential (_, _, innerComp1, innerComp2, _) -> isSimpleExpr innerComp1 && isSimpleExpr innerComp2 + | SynExpr.IfThenElse (_, _, _, _, thenComp, _, elseCompOpt, _, _, _, _) -> + isSimpleExpr thenComp && (match elseCompOpt with None -> true | Some c -> isSimpleExpr c) + | SynExpr.LetOrUse (_, _, _, innerComp, _) -> isSimpleExpr innerComp + | SynExpr.LetOrUseBang _ -> false + | SynExpr.Match (_, _, clauses, _) -> + clauses |> List.forall (fun (SynMatchClause(resultExpr = innerComp)) -> isSimpleExpr innerComp) + | SynExpr.MatchBang _ -> false + | SynExpr.TryWith (innerComp, _, clauses, _, _, _, _) -> + isSimpleExpr innerComp && + clauses |> List.forall (fun (SynMatchClause(resultExpr = clauseComp)) -> isSimpleExpr clauseComp) + | SynExpr.YieldOrReturnFrom _ -> false + | SynExpr.YieldOrReturn _ -> false + | SynExpr.DoBang _ -> false + | _ -> true + + let basicSynExpr = + trans CompExprTranslationPass.Initial (hasCustomOperations ()) (LazyWithContext.NotLazy ([], env)) comp id + + let delayedExpr = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Delay" builderTy with + | [] -> basicSynExpr + | _ -> mkSynCall "Delay" mBuilderVal [(mkSynDelay2 basicSynExpr)] + + let quotedSynExpr = + if isAutoQuote then + SynExpr.Quote (mkSynIdGet (mBuilderVal.MakeSynthetic()) (CompileOpName "<@ @>"), (*isRaw=*)false, delayedExpr, (*isFromQueryExpression=*)true, mWhole) + else delayedExpr + + let runExpr = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Run" builderTy with + | [] -> quotedSynExpr + | _ -> mkSynCall "Run" mBuilderVal [quotedSynExpr] + + let lambdaExpr = + let mBuilderVal = mBuilderVal.MakeSynthetic() + SynExpr.Lambda (false, false, SynSimplePats.SimplePats ([mkSynSimplePatVar false (mkSynId mBuilderVal builderValName)], mBuilderVal), None, runExpr, None, mBuilderVal) + + let env = + match comp with + | SynExpr.YieldOrReturn ((true, _), _, _) -> { env with eContextInfo = ContextInfo.YieldInComputationExpression } + | SynExpr.YieldOrReturn ((_, true), _, _) -> { env with eContextInfo = ContextInfo.ReturnInComputationExpression } + | _ -> env + + let lambdaExpr, tpenv= TcExpr cenv (MustEqual (builderTy --> overallTy)) env tpenv lambdaExpr + // beta-var-reduce to bind the builder using a 'let' binding + let coreExpr = mkApps cenv.g ((lambdaExpr, tyOfExpr cenv.g lambdaExpr), [], [interpExpr], mBuilderVal) + + coreExpr, tpenv + +let mkSeqEmpty (cenv: cenv) env m genTy = + // We must discover the 'zero' of the monadic algebra being generated in order to compile failing matches. + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + mkCallSeqEmpty cenv.g m genResultTy + +let mkSeqCollect (cenv: cenv) env m enumElemTy genTy lam enumExpr = + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr + mkCallSeqCollect cenv.g m enumElemTy genResultTy lam enumExpr + +let mkSeqUsing (cenv: cenv) (env: TcEnv) m resourceTy genTy resourceExpr lam = + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace cenv.g.system_IDisposable_ty resourceTy + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + mkCallSeqUsing cenv.g m resourceTy genResultTy resourceExpr lam + +let mkSeqDelay (cenv: cenv) env m genTy lam = + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + mkCallSeqDelay cenv.g m genResultTy (mkUnitDelayLambda cenv.g m lam) + +let mkSeqAppend (cenv: cenv) env m genTy e1 e2 = + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + let e1 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e1) e1 + let e2 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e2) e2 + mkCallSeqAppend cenv.g m genResultTy e1 e2 + +let mkSeqFromFunctions (cenv: cenv) env m genTy e1 e2 = + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + let e2 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e2) e2 + mkCallSeqGenerated cenv.g m genResultTy e1 e2 + +let mkSeqFinally (cenv: cenv) env m genTy e1 e2 = + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) + let e1 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e1) e1 + mkCallSeqFinally cenv.g m genResultTy e1 e2 + +let mkSeqExprMatchClauses (pat', vspecs) innerExpr = + [TClause(pat', None, TTarget(vspecs, innerExpr, DebugPointAtTarget.Yes, None), pat'.Range) ] + +let compileSeqExprMatchClauses (cenv: cenv) env inputExprMark (pat: Pattern, vspecs) innerExpr inputExprOpt bindPatTy genInnerTy = + let patMark = pat.Range + let tclauses = mkSeqExprMatchClauses (pat, vspecs) innerExpr + CompilePatternForMatchClauses cenv env inputExprMark patMark false ThrowIncompleteMatchException inputExprOpt bindPatTy genInnerTy tclauses + +/// This case is used for computation expressions which are sequence expressions. Technically the code path is different because it +/// typechecks rather than doing a shallow syntactic translation, and generates calls into the Seq.* library +/// and helpers rather than to the builder methods (there is actually no builder for 'seq' in the library). +/// These are later detected by state machine compilation. +/// +/// Also "ienumerable extraction" is performed on arguments to "for". +let TcSequenceExpression (cenv: cenv) env tpenv comp (overallTy: OverallTy) m = + + let genEnumElemTy = NewInferenceType () + UnifyTypes cenv env m overallTy.Commit (mkSeqTy cenv.g genEnumElemTy) + + // Allow subsumption at 'yield' if the element type is nominal prior to the analysis of the body of the sequence expression + let flex = not (isTyparTy cenv.g genEnumElemTy) + + // If there are no 'yield' in the computation expression then allow the type-directed rule + // interpreting non-unit-typed expressions in statement positions as 'yield'. 'yield!' may be + // present in the computation expression. + let enableImplicitYield = + cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield + && (YieldFree cenv comp) + + let mkDelayedExpr m (coreExpr: Expr) = + let overallTy = tyOfExpr cenv.g coreExpr + mkSeqDelay cenv env m overallTy coreExpr + + let rec tryTcSequenceExprBody env genOuterTy tpenv comp = + match comp with + | SynExpr.ForEach (spFor, SeqExprOnly _seqExprOnly, _isFromSource, pat, pseudoEnumExpr, innerComp, m) -> + let pseudoEnumExpr = + match RewriteRangeExpr pseudoEnumExpr with + | Some e -> e + | None -> pseudoEnumExpr + // This expression is not checked with the knowledge it is an IEnumerable, since we permit other enumerable types with GetEnumerator/MoveNext methods, as does C# + let pseudoEnumExpr, arbitraryTy, tpenv = TcExprOfUnknownType cenv env tpenv pseudoEnumExpr + let enumExpr, enumElemTy = ConvertArbitraryExprToEnumerable cenv arbitraryTy env pseudoEnumExpr + let pat', _, (vspecs: Val list), envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + + let enumExprMark = enumExpr.Range + // We attach the debug point to the lambda expression so we can fetch it out again in LowerComputedListOrArraySeqExpr + let mFor = + match spFor with + | DebugPointAtFor.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.For) + | _ -> enumExprMark + + match pat', vspecs, innerExpr with + // peephole optimization: "for x in e1 -> e2" == "e1 |> List.map (fun x -> e2)" *) + | (TPat_as (TPat_wild _, PBind (v, _), _), + vs, + Expr.App (Expr.Val (vf, _, _), _, [genEnumElemTy], [yexpr], _)) + when vs.Length = 1 && valRefEq cenv.g vf cenv.g.seq_singleton_vref -> + + let lam = mkLambda mFor v (yexpr, genEnumElemTy) + + // SEQUENCE POINTS: need to build a let here consuming spBind + let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr + Some(mkCallSeqMap cenv.g m enumElemTy genEnumElemTy lam enumExpr, tpenv) + + | _ -> + let enumExprMark = enumExpr.Range + + // SEQUENCE POINTS: need to build a let here consuming spBind + + let matchv, matchExpr = compileSeqExprMatchClauses cenv env enumExprMark (pat', vspecs) innerExpr None enumElemTy genOuterTy + let lam = mkLambda mFor matchv (matchExpr, tyOfExpr cenv.g matchExpr) + Some(mkSeqCollect cenv env m enumElemTy genOuterTy lam enumExpr, tpenv) + + | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> + Some(tcSequenceExprBody env genOuterTy tpenv (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m))) + + | SynExpr.While (spWhile, guardExpr, innerComp, _m) -> + let guardExpr, tpenv = TcExpr cenv (MustEqual cenv.g.bool_ty) env tpenv guardExpr + let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp + + let guardExprMark = guardExpr.Range + let guardExpr = mkUnitDelayLambda cenv.g guardExprMark guardExpr + + // We attach the debug point to the lambda expression so we can fetch it out again in LowerComputedListOrArraySeqExpr + let mWhile = + match spWhile with + | DebugPointAtWhile.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.While) + | _ -> guardExprMark + + let innerExpr = mkDelayedExpr mWhile innerExpr + Some(mkSeqFromFunctions cenv env guardExprMark genOuterTy guardExpr innerExpr, tpenv) + + | SynExpr.TryFinally (innerComp, unwindExpr, mTryToLast, spTry, spFinally) -> + let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp + let unwindExpr, tpenv = TcExpr cenv (MustEqual cenv.g.unit_ty) env tpenv unwindExpr + + // We attach the debug points to the lambda expressions so we can fetch it out again in LowerComputedListOrArraySeqExpr + let mTry = + match spTry with + | DebugPointAtTry.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.Try) + | _ -> unwindExpr.Range + + let mFinally = + match spFinally with + | DebugPointAtFinally.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.Finally) + | _ -> unwindExpr.Range + + let innerExpr = mkDelayedExpr mTry innerExpr + let unwindExpr = mkUnitDelayLambda cenv.g mFinally unwindExpr + + Some(mkSeqFinally cenv env mTryToLast genOuterTy innerExpr unwindExpr, tpenv) + + | SynExpr.Paren (_, _, _, m) when not (cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield)-> + error(Error(FSComp.SR.tcConstructIsAmbiguousInSequenceExpression(), m)) + + | SynExpr.ImplicitZero m -> + Some(mkSeqEmpty cenv env m genOuterTy, tpenv ) + + | SynExpr.DoBang (_rhsExpr, m) -> + error(Error(FSComp.SR.tcDoBangIllegalInSequenceExpression(), m)) + + | SynExpr.Sequential (sp, true, innerComp1, innerComp2, m) -> + // "expr; cexpr" is treated as sequential execution + // "cexpr; cexpr" is treated as append + let res, tpenv = tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv innerComp1 + match res with + | Choice1Of2 innerExpr1 -> + let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 + let innerExpr2 = mkDelayedExpr innerExpr2.Range innerExpr2 + Some(mkSeqAppend cenv env innerComp1.Range genOuterTy innerExpr1 innerExpr2, tpenv) + | Choice2Of2 stmt1 -> + let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 + Some(Expr.Sequential(stmt1, innerExpr2, NormalSeq, sp, m), tpenv) + + | SynExpr.IfThenElse (_, _, guardExpr, _, thenComp, _, elseCompOpt, spIfToThen, _isRecovery, mIfToThen, mIfToEndOfElseBranch) -> + let guardExpr', tpenv = TcExpr cenv (MustEqual cenv.g.bool_ty) env tpenv guardExpr + let thenExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv thenComp + let elseComp = (match elseCompOpt with Some c -> c | None -> SynExpr.ImplicitZero mIfToThen) + let elseExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv elseComp + Some(mkCond spIfToThen DebugPointAtTarget.Yes mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv) + + // 'let x = expr in expr' + | SynExpr.LetOrUse (_, false (* not a 'use' binding *), _, _, _) -> + TcLinearExprs + (fun overallTy envinner tpenv e -> tcSequenceExprBody envinner overallTy.Commit tpenv e) + cenv env overallTy + tpenv + true + comp + id |> Some + + // 'use x = expr in expr' + | SynExpr.LetOrUse (_isRec, true, [SynBinding (_vis, SynBindingKind.Normal, _, _, _, _, _, pat, _, rhsExpr, _, spBind)], innerComp, wholeExprMark) -> + + let bindPatTy = NewInferenceType () + let inputExprTy = NewInferenceType () + let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv bindPatTy env tpenv (pat, None) + UnifyTypes cenv env m inputExprTy bindPatTy + let inputExpr, tpenv = TcExpr cenv (MustEqual inputExprTy) env tpenv rhsExpr + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + let mBind = + match spBind with + | DebugPointAtBinding.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.Binding) + | _ -> inputExpr.Range + let inputExprMark = inputExpr.Range + let matchv, matchExpr = compileSeqExprMatchClauses cenv env inputExprMark (pat', vspecs) innerExpr (Some inputExpr) bindPatTy genOuterTy + let consumeExpr = mkLambda mBind matchv (matchExpr, genOuterTy) + //SEQPOINT NEEDED - we must consume spBind on this path + Some(mkSeqUsing cenv env wholeExprMark bindPatTy genOuterTy inputExpr consumeExpr, tpenv) + + | SynExpr.LetOrUseBang (range=m) -> + error(Error(FSComp.SR.tcUseForInSequenceExpression(), m)) + + | SynExpr.Match (spMatch, expr, clauses, _) -> + let inputExpr, matchty, tpenv = TcExprOfUnknownType cenv env tpenv expr + let tclauses, tpenv = + (tpenv, clauses) ||> List.mapFold (fun tpenv (SynMatchClause(pat, cond, _, innerComp, _, sp)) -> + let pat', cond', vspecs, envinner, tpenv = TcMatchPattern cenv matchty env tpenv (pat, cond) + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + TClause(pat', cond', TTarget(vspecs, innerExpr, sp, None), pat'.Range), tpenv) + let inputExprTy = tyOfExpr cenv.g inputExpr + let inputExprMark = inputExpr.Range + let matchv, matchExpr = CompilePatternForMatchClauses cenv env inputExprMark inputExprMark true ThrowIncompleteMatchException (Some inputExpr) inputExprTy genOuterTy tclauses + Some(mkLet spMatch inputExprMark matchv inputExpr matchExpr, tpenv) + + | SynExpr.TryWith (tryRange=mTryToWith) -> + error(Error(FSComp.SR.tcTryIllegalInSequenceExpression(), mTryToWith)) + + | SynExpr.YieldOrReturnFrom ((isYield, _), yieldExpr, m) -> + let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv yieldExpr + + if not isYield then errorR(Error(FSComp.SR.tcUseYieldBangForMultipleResults(), m)) + + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy + Some(mkCoerceExpr(resultExpr, genOuterTy, m, genExprTy), tpenv) + + | SynExpr.YieldOrReturn ((isYield, _), yieldExpr, m) -> + let genResultTy = NewInferenceType () + if not isYield then errorR(Error(FSComp.SR.tcSeqResultsUseYield(), m)) + UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) + + let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv yieldExpr + Some(mkCallSeqSingleton cenv.g m genResultTy resultExpr, tpenv ) + + | _ -> None + + and tcSequenceExprBody env (genOuterTy: TType) tpenv comp = + let res, tpenv = tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv comp + match res with + | Choice1Of2 expr -> + expr, tpenv + | Choice2Of2 stmt -> + let m = comp.Range + let resExpr = Expr.Sequential(stmt, mkSeqEmpty cenv env m genOuterTy, NormalSeq, DebugPointAtSequential.SuppressExpr, m) + resExpr, tpenv + + and tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv comp = + match tryTcSequenceExprBody env genOuterTy tpenv comp with + | Some (expr, tpenv) -> Choice1Of2 expr, tpenv + | None -> + let env = { env with eContextInfo = ContextInfo.SequenceExpression genOuterTy } + if enableImplicitYield then + let hasTypeUnit, expr, tpenv = TryTcStmt cenv env tpenv comp + if hasTypeUnit then + Choice2Of2 expr, tpenv + else + let genResultTy = NewInferenceType () + UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) + let exprTy = tyOfExpr cenv.g expr + AddCxTypeMustSubsumeType env.eContextInfo env.DisplayEnv cenv.css m NoTrace genResultTy exprTy + let resExpr = mkCallSeqSingleton cenv.g m genResultTy (mkCoerceExpr(expr, genResultTy, m, exprTy)) + Choice1Of2 resExpr, tpenv + else + let stmt, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv comp + Choice2Of2 stmt, tpenv + + let coreExpr, tpenv = tcSequenceExprBody env overallTy.Commit tpenv comp + let delayedExpr = mkDelayedExpr coreExpr.Range coreExpr + delayedExpr, tpenv + +let TcSequenceExpressionEntry (cenv: cenv) env (overallTy: OverallTy) tpenv (hasBuilder, comp) m = + match RewriteRangeExpr comp with + | Some replacementExpr -> + TcExpr cenv overallTy env tpenv replacementExpr + | None -> + + let implicitYieldEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield + let validateObjectSequenceOrRecordExpression = not implicitYieldEnabled + match comp with + | SynExpr.New _ -> + errorR(Error(FSComp.SR.tcInvalidObjectExpressionSyntaxForm(), m)) + | SimpleSemicolonSequence cenv false _ when validateObjectSequenceOrRecordExpression -> + errorR(Error(FSComp.SR.tcInvalidObjectSequenceOrRecordExpression(), m)) + | _ -> + () + + if not hasBuilder && not cenv.g.compilingFslib then + error(Error(FSComp.SR.tcInvalidSequenceExpressionSyntaxForm(), m)) + + TcSequenceExpression cenv env tpenv comp overallTy m + +let TcArrayOrListComputedExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (isArray, comp) m = + // The syntax '[ n .. m ]' and '[ n .. step .. m ]' is not really part of array or list syntax. + // It could be in the future, e.g. '[ 1; 2..30; 400 ]' + // + // The elaborated form of '[ n .. m ]' is 'List.ofSeq (seq (op_Range n m))' and this shouldn't change + match RewriteRangeExpr comp with + | Some replacementExpr -> + let genCollElemTy = NewInferenceType () + + let genCollTy = (if isArray then mkArrayType else mkListTy) cenv.g genCollElemTy + + UnifyTypes cenv env m overallTy.Commit genCollTy + + let exprTy = mkSeqTy cenv.g genCollElemTy + + let expr, tpenv = TcExpr cenv (MustEqual exprTy) env tpenv replacementExpr + let expr = + if cenv.g.compilingFslib then + //warning(Error(FSComp.SR.fslibUsingComputedListOrArray(), expr.Range)) + expr + else + // We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the + // comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined. + mkCallSeq cenv.g m genCollElemTy expr + + let expr = mkCoerceExpr(expr, exprTy, expr.Range, overallTy.Commit) + + let expr = + if isArray then + mkCallSeqToArray cenv.g m genCollElemTy expr + else + mkCallSeqToList cenv.g m genCollElemTy expr + expr, tpenv + + | None -> + + // LanguageFeatures.ImplicitYield do not require this validation + let implicitYieldEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield + let validateExpressionWithIfRequiresParenthesis = not implicitYieldEnabled + let acceptDeprecatedIfThenExpression = not implicitYieldEnabled + + match comp with + | SimpleSemicolonSequence cenv acceptDeprecatedIfThenExpression elems -> + match comp with + | SimpleSemicolonSequence cenv false _ -> () + | _ when validateExpressionWithIfRequiresParenthesis -> errorR(Deprecated(FSComp.SR.tcExpressionWithIfRequiresParenthesis(), m)) + | _ -> () + + let replacementExpr = + if isArray then + // This are to improve parsing/processing speed for parser tables by converting to an array blob ASAP + let nelems = elems.Length + if nelems > 0 && List.forall (function SynExpr.Const (SynConst.UInt16 _, _) -> true | _ -> false) elems + then SynExpr.Const (SynConst.UInt16s (Array.ofList (List.map (function SynExpr.Const (SynConst.UInt16 x, _) -> x | _ -> failwith "unreachable") elems)), m) + elif nelems > 0 && List.forall (function SynExpr.Const (SynConst.Byte _, _) -> true | _ -> false) elems + then SynExpr.Const (SynConst.Bytes (Array.ofList (List.map (function SynExpr.Const (SynConst.Byte x, _) -> x | _ -> failwith "unreachable") elems), SynByteStringKind.Regular, m), m) + else SynExpr.ArrayOrList (isArray, elems, m) + else + if elems.Length > 500 then + error(Error(FSComp.SR.tcListLiteralMaxSize(), m)) + SynExpr.ArrayOrList (isArray, elems, m) + + TcExprUndelayed cenv overallTy env tpenv replacementExpr + | _ -> + + let genCollElemTy = NewInferenceType () + + let genCollTy = (if isArray then mkArrayType else mkListTy) cenv.g genCollElemTy + + // Propagating type directed conversion, e.g. for + // let x : seq = [ yield 1; if true then yield 2 ] + TcPropagatingExprLeafThenConvert cenv overallTy genCollTy env (* canAdhoc *) m (fun () -> + + let exprTy = mkSeqTy cenv.g genCollElemTy + + // Check the comprehension + let expr, tpenv = TcSequenceExpression cenv env tpenv comp (MustEqual exprTy) m + + let expr = mkCoerceIfNeeded cenv.g exprTy (tyOfExpr cenv.g expr) expr + + let expr = + if cenv.g.compilingFslib then + //warning(Error(FSComp.SR.fslibUsingComputedListOrArray(), expr.Range)) + expr + else + // We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the + // comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined. + mkCallSeq cenv.g m genCollElemTy expr + + let expr = mkCoerceExpr(expr, exprTy, expr.Range, overallTy.Commit) + + let expr = + if isArray then + mkCallSeqToArray cenv.g m genCollElemTy expr + else + mkCallSeqToList cenv.g m genCollElemTy expr + + expr, tpenv) diff --git a/src/fsharp/CheckComputationExpressions.fsi b/src/fsharp/CheckComputationExpressions.fsi new file mode 100644 index 00000000000..451b5b4bfc2 --- /dev/null +++ b/src/fsharp/CheckComputationExpressions.fsi @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CheckComputationExpressions + +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +val TcSequenceExpressionEntry: cenv:TcFileState -> env:TcEnv -> overallTy:OverallTy -> tpenv:UnscopedTyparEnv -> hasBuilder:bool * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv + +val TcArrayOrListComputedExpression: cenv:TcFileState -> env:TcEnv -> overallTy:OverallTy -> tpenv:UnscopedTyparEnv -> isArray:bool * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv + +val TcComputationExpression: cenv:TcFileState -> env:TcEnv -> overallTy:OverallTy -> tpenv:UnscopedTyparEnv -> mWhole:range * interpExpr:Expr * builderTy:TType * comp:SynExpr -> Expr * UnscopedTyparEnv + diff --git a/src/fsharp/CheckDeclarations.fs b/src/fsharp/CheckDeclarations.fs new file mode 100644 index 00000000000..28ca2c85c0c --- /dev/null +++ b/src/fsharp/CheckDeclarations.fs @@ -0,0 +1,5960 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CheckDeclarations + +open System +open System.Collections.Generic + +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Library.ResultOrException +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckComputationExpressions +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.Infos +open FSharp.Compiler.InfoReader +open FSharp.Compiler.MethodOverrides +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypeRelations + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +type cenv = TcFileState + +//------------------------------------------------------------------------- +// Mutually recursive shapes +//------------------------------------------------------------------------- + +type MutRecDataForOpen = MutRecDataForOpen of SynOpenDeclTarget * range * appliedScope: range * OpenDeclaration list ref +type MutRecDataForModuleAbbrev = MutRecDataForModuleAbbrev of Ident * LongIdent * range + +/// Represents the shape of a mutually recursive group of declarations including nested modules +[] +type MutRecShape<'TypeData, 'LetsData, 'ModuleData> = + | Tycon of 'TypeData + | Lets of 'LetsData + | Module of 'ModuleData * MutRecShapes<'TypeData, 'LetsData, 'ModuleData> + | ModuleAbbrev of MutRecDataForModuleAbbrev + | Open of MutRecDataForOpen + +and MutRecShapes<'TypeData, 'LetsData, 'ModuleData> = MutRecShape<'TypeData, 'LetsData, 'ModuleData> list + +//------------------------------------------------------------------------- +// Mutually recursive shapes +//------------------------------------------------------------------------- + +module MutRecShapes = + let rec map f1 f2 f3 x = + x |> List.map (function + | MutRecShape.Open a -> MutRecShape.Open a + | MutRecShape.ModuleAbbrev b -> MutRecShape.ModuleAbbrev b + | MutRecShape.Tycon a -> MutRecShape.Tycon (f1 a) + | MutRecShape.Lets b -> MutRecShape.Lets (f2 b) + | MutRecShape.Module (c, d) -> MutRecShape.Module (f3 c, map f1 f2 f3 d)) + + let mapTycons f1 xs = map f1 id id xs + let mapTyconsAndLets f1 f2 xs = map f1 f2 id xs + let mapLets f2 xs = map id f2 id xs + let mapModules f1 xs = map id id f1 xs + + let rec mapWithEnv fTycon fLets (env: 'Env) x = + x |> List.map (function + | MutRecShape.Open a -> MutRecShape.Open a + | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a + | MutRecShape.Tycon a -> MutRecShape.Tycon (fTycon env a) + | MutRecShape.Lets b -> MutRecShape.Lets (fLets env b) + | MutRecShape.Module ((c, env2), d) -> MutRecShape.Module ((c, env2), mapWithEnv fTycon fLets env2 d)) + + let mapTyconsWithEnv f1 env xs = mapWithEnv f1 (fun _env x -> x) env xs + + let rec mapWithParent parent f1 f2 f3 xs = + xs |> List.map (function + | MutRecShape.Open a -> MutRecShape.Open a + | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a + | MutRecShape.Tycon a -> MutRecShape.Tycon (f2 parent a) + | MutRecShape.Lets b -> MutRecShape.Lets (f3 parent b) + | MutRecShape.Module (c, d) -> + let c2, parent2 = f1 parent c d + MutRecShape.Module (c2, mapWithParent parent2 f1 f2 f3 d)) + + let rec computeEnvs f1 f2 (env: 'Env) xs = + let env = f2 env xs + env, + xs |> List.map (function + | MutRecShape.Open a -> MutRecShape.Open a + | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a + | MutRecShape.Tycon a -> MutRecShape.Tycon a + | MutRecShape.Lets b -> MutRecShape.Lets b + | MutRecShape.Module (c, ds) -> + let env2 = f1 env c + let env3, ds2 = computeEnvs f1 f2 env2 ds + MutRecShape.Module ((c, env3), ds2)) + + let rec extendEnvs f1 (env: 'Env) xs = + let env = f1 env xs + env, + xs |> List.map (function + | MutRecShape.Module ((c, env), ds) -> + let env2, ds2 = extendEnvs f1 env ds + MutRecShape.Module ((c, env2), ds2) + | x -> x) + + let dropEnvs xs = xs |> mapModules fst + + let rec expandTyconsWithEnv f1 env xs = + let preBinds, postBinds = + xs |> List.map (fun elem -> + match elem with + | MutRecShape.Tycon a -> f1 env a + | _ -> [], []) + |> List.unzip + [MutRecShape.Lets (List.concat preBinds)] @ + (xs |> List.map (fun elem -> + match elem with + | MutRecShape.Module ((c, env2), d) -> MutRecShape.Module ((c, env2), expandTyconsWithEnv f1 env2 d) + | _ -> elem)) @ + [MutRecShape.Lets (List.concat postBinds)] + + let rec mapFoldWithEnv f1 z env xs = + (z, xs) ||> List.mapFold (fun z x -> + match x with + | MutRecShape.Module ((c, env2), ds) -> let ds2, z = mapFoldWithEnv f1 z env2 ds in MutRecShape.Module ((c, env2), ds2), z + | _ -> let x2, z = f1 z env x in x2, z) + + + let rec collectTycons x = + x |> List.collect (function + | MutRecShape.Tycon a -> [a] + | MutRecShape.Module (_, d) -> collectTycons d + | _ -> []) + + let topTycons x = + x |> List.choose (function MutRecShape.Tycon a -> Some a | _ -> None) + + let rec iter f1 f2 f3 f4 f5 x = + x |> List.iter (function + | MutRecShape.Tycon a -> f1 a + | MutRecShape.Lets b -> f2 b + | MutRecShape.Module (c, d) -> f3 c; iter f1 f2 f3 f4 f5 d + | MutRecShape.Open a -> f4 a + | MutRecShape.ModuleAbbrev a -> f5 a) + + let iterTycons f1 x = iter f1 ignore ignore ignore ignore x + let iterTyconsAndLets f1 f2 x = iter f1 f2 ignore ignore ignore x + let iterModules f1 x = iter ignore ignore f1 ignore ignore x + + let rec iterWithEnv f1 f2 f3 f4 env x = + x |> List.iter (function + | MutRecShape.Tycon a -> f1 env a + | MutRecShape.Lets b -> f2 env b + | MutRecShape.Module ((_, env), d) -> iterWithEnv f1 f2 f3 f4 env d + | MutRecShape.Open a -> f3 env a + | MutRecShape.ModuleAbbrev a -> f4 env a) + + let iterTyconsWithEnv f1 env xs = iterWithEnv f1 (fun _env _x -> ()) (fun _env _x -> ()) (fun _env _x -> ()) env xs + + +/// Indicates a declaration is contained in the given module +let ModuleOrNamespaceContainerInfo modref = ContainerInfo(Parent modref, Some(MemberOrValContainerInfo(modref, None, None, NoSafeInitInfo, []))) + +/// Indicates a declaration is contained in the given type definition in the given module +let TyconContainerInfo (parent, tcref, declaredTyconTypars, safeInitInfo) = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, None, None, safeInitInfo, declaredTyconTypars))) + +type TyconBindingDefn = TyconBindingDefn of ContainerInfo * NewSlotsOK * DeclKind * SynMemberDefn * range + +type MutRecSigsInitialData = MutRecShape list +type MutRecDefnsInitialData = MutRecShape list + +type MutRecDefnsPhase1DataForTycon = MutRecDefnsPhase1DataForTycon of SynComponentInfo * SynTypeDefnSimpleRepr * (SynType * range) list * preEstablishedHasDefaultCtor: bool * hasSelfReferentialCtor: bool * isAtOriginalTyconDefn: bool +type MutRecDefnsPhase1Data = MutRecShape list + +type MutRecDefnsPhase2DataForTycon = MutRecDefnsPhase2DataForTycon of Tycon option * ParentRef * DeclKind * TyconRef * Val option * SafeInitData * Typars * SynMemberDefn list * range * NewSlotsOK * fixupFinalAttribs: (unit -> unit) +type MutRecDefnsPhase2DataForModule = MutRecDefnsPhase2DataForModule of ModuleOrNamespaceType ref * ModuleOrNamespace +type MutRecDefnsPhase2Data = MutRecShape list + +type MutRecDefnsPhase2InfoForTycon = MutRecDefnsPhase2InfoForTycon of Tycon option * TyconRef * Typars * DeclKind * TyconBindingDefn list * fixupFinalAttrs: (unit -> unit) +type MutRecDefnsPhase2Info = MutRecShape list + +//------------------------------------------------------------------------- +// Helpers for TcEnv +//------------------------------------------------------------------------- + +/// Add an exception definition to TcEnv and report it to the sink +let AddLocalExnDefnAndReport tcSink scopem env (exnc: Tycon) = + let env = { env with eNameResEnv = AddExceptionDeclsToNameEnv BulkAdd.No env.eNameResEnv (mkLocalEntityRef exnc) } + // Also make VisualStudio think there is an identifier in scope at the range of the identifier text of its binding location + CallEnvSink tcSink (exnc.Range, env.NameEnv, env.AccessRights) + CallEnvSink tcSink (scopem, env.NameEnv, env.AccessRights) + env + +/// Add a list of type definitions to TcEnv +let AddLocalTyconRefs ownDefinition g amap m tcrefs env = + if isNil tcrefs then env else + { env with eNameResEnv = AddTyconRefsToNameEnv BulkAdd.No ownDefinition g amap env.eAccessRights m false env.eNameResEnv tcrefs } + +/// Add a list of type definitions to TcEnv +let AddLocalTycons g amap m (tycons: Tycon list) env = + if isNil tycons then env else + env |> AddLocalTyconRefs false g amap m (List.map mkLocalTyconRef tycons) + +/// Add a list of type definitions to TcEnv and report them to the sink +let AddLocalTyconsAndReport tcSink scopem g amap m tycons env = + let env = AddLocalTycons g amap m tycons env + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + env + +/// Add a "module X = ..." definition to the TcEnv +let AddLocalSubModule g amap m env (modul: ModuleOrNamespace) = + let env = { env with + eNameResEnv = AddModuleOrNamespaceRefToNameEnv g amap m false env.eAccessRights env.eNameResEnv (mkLocalModRef modul) + eUngeneralizableItems = addFreeItemOfModuleTy modul.ModuleOrNamespaceType env.eUngeneralizableItems } + env + +/// Add a "module X = ..." definition to the TcEnv and report it to the sink +let AddLocalSubModuleAndReport tcSink scopem g amap m env (modul: ModuleOrNamespace) = + let env = AddLocalSubModule g amap m env modul + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + env + +/// Given an inferred module type, place that inside a namespace path implied by a "namespace X.Y.Z" definition +let BuildRootModuleType enclosingNamespacePath (cpath: CompilationPath) mtyp = + (enclosingNamespacePath, (cpath, (mtyp, []))) + ||> List.foldBack (fun id (cpath, (mtyp, mspecs)) -> + let a, b = wrapModuleOrNamespaceTypeInNamespace id cpath.ParentCompPath mtyp + cpath.ParentCompPath, (a, b :: mspecs)) + |> fun (_, (mtyp, mspecs)) -> mtyp, List.rev mspecs + +/// Given a resulting module expression, place that inside a namespace path implied by a "namespace X.Y.Z" definition +let BuildRootModuleExpr enclosingNamespacePath (cpath: CompilationPath) mexpr = + (enclosingNamespacePath, (cpath, mexpr)) + ||> List.foldBack (fun id (cpath, mexpr) -> (cpath.ParentCompPath, wrapModuleOrNamespaceExprInNamespace id cpath.ParentCompPath mexpr)) + |> snd + +/// Try to take the "FSINNN" prefix off a namespace path +let TryStripPrefixPath (g: TcGlobals) (enclosingNamespacePath: Ident list) = + match enclosingNamespacePath with + | p :: rest when + g.isInteractive && + not (isNil rest) && + p.idText.StartsWithOrdinal FsiDynamicModulePrefix && + p.idText.[FsiDynamicModulePrefix.Length..] |> String.forall Char.IsDigit + -> Some(p, rest) + | _ -> None + +/// Add a "module X = Y" local module abbreviation to the TcEnv +let AddModuleAbbreviationAndReport tcSink scopem id modrefs env = + let env = + if isNil modrefs then env else + { env with eNameResEnv = AddModuleAbbrevToNameEnv id env.eNameResEnv modrefs } + + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + let item = Item.ModuleOrNamespaces modrefs + CallNameResolutionSink tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) + env + +/// Adjust the TcEnv to account for opening the set of modules or namespaces implied by an `open` declaration +let OpenModuleOrNamespaceRefs tcSink g amap scopem root env mvvs openDeclaration = + let env = + if isNil mvvs then env else + { env with eNameResEnv = AddModuleOrNamespaceRefsContentsToNameEnv g amap env.eAccessRights scopem root env.eNameResEnv mvvs } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + CallOpenDeclarationSink tcSink openDeclaration + env + +/// Adjust the TcEnv to account for opening a type implied by an `open type` declaration +let OpenTypeContent tcSink g amap scopem env (typ: TType) openDeclaration = + let env = + { env with eNameResEnv = AddTypeContentsToNameEnv g amap env.eAccessRights scopem env.eNameResEnv typ } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + CallOpenDeclarationSink tcSink openDeclaration + env + +/// Adjust the TcEnv to account for a new root Ccu being available, e.g. a referenced assembly +let AddRootModuleOrNamespaceRefs g amap m env modrefs = + if isNil modrefs then env else + { env with eNameResEnv = AddModuleOrNamespaceRefsToNameEnv g amap m true env.eAccessRights env.eNameResEnv modrefs } + +/// Adjust the TcEnv to make more things 'InternalsVisibleTo' +let addInternalsAccessibility env (ccu: CcuThunk) = + let compPath = CompPath (ccu.ILScopeRef, []) + let eInternalsVisibleCompPaths = compPath :: env.eInternalsVisibleCompPaths + { env with + eAccessRights = ComputeAccessRights env.eAccessPath eInternalsVisibleCompPaths env.eFamilyType // update this computed field + eInternalsVisibleCompPaths = compPath :: env.eInternalsVisibleCompPaths } + +/// Adjust the TcEnv to account for a new referenced assembly +let AddNonLocalCcu g amap scopem env assemblyName (ccu: CcuThunk, internalsVisibleToAttributes) = + + let internalsVisible = + internalsVisibleToAttributes + |> List.exists (fun visibleTo -> + try + System.Reflection.AssemblyName(visibleTo).Name = assemblyName + with e -> + warning(InvalidInternalsVisibleToAssemblyName(visibleTo, ccu.FileName)) + false) + + let env = if internalsVisible then addInternalsAccessibility env ccu else env + + // Compute the top-rooted module or namespace references + let modrefs = ccu.RootModulesAndNamespaces |> List.map (mkNonLocalCcuRootEntityRef ccu) + + // Compute the top-rooted type definitions + let tcrefs = ccu.RootTypeAndExceptionDefinitions |> List.map (mkNonLocalCcuRootEntityRef ccu) + let env = AddRootModuleOrNamespaceRefs g amap scopem env modrefs + let env = + if isNil tcrefs then env else + { env with eNameResEnv = AddTyconRefsToNameEnv BulkAdd.Yes false g amap env.eAccessRights scopem true env.eNameResEnv tcrefs } + env + +/// Adjust the TcEnv to account for a fully processed "namespace" declaration in this file +let AddLocalRootModuleOrNamespace tcSink g amap scopem env (mtyp: ModuleOrNamespaceType) = + // Compute the top-rooted module or namespace references + let modrefs = mtyp.ModuleAndNamespaceDefinitions |> List.map mkLocalModRef + // Compute the top-rooted type definitions + let tcrefs = mtyp.TypeAndExceptionDefinitions |> List.map mkLocalTyconRef + let env = AddRootModuleOrNamespaceRefs g amap scopem env modrefs + let env = { env with + eNameResEnv = if isNil tcrefs then env.eNameResEnv else AddTyconRefsToNameEnv BulkAdd.No false g amap env.eAccessRights scopem true env.eNameResEnv tcrefs + eUngeneralizableItems = addFreeItemOfModuleTy mtyp env.eUngeneralizableItems } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + env + +/// Inside "namespace X.Y.Z" there is an implicit open of "X.Y.Z" +let ImplicitlyOpenOwnNamespace tcSink g amap scopem enclosingNamespacePath (env: TcEnv) = + if isNil enclosingNamespacePath then + env + else + // For F# interactive, skip "FSI_0002" prefixes when determining the path to open implicitly + let enclosingNamespacePathToOpen = + match TryStripPrefixPath g enclosingNamespacePath with + | Some(_, rest) -> rest + | None -> enclosingNamespacePath + + match enclosingNamespacePathToOpen with + | id :: rest -> + let ad = env.AccessRights + match ResolveLongIdentAsModuleOrNamespace tcSink ResultCollectionSettings.AllResults amap scopem true OpenQualified env.eNameResEnv ad id rest true with + | Result modrefs -> + let modrefs = List.map p23 modrefs + let openTarget = SynOpenDeclTarget.ModuleOrNamespace(enclosingNamespacePathToOpen, scopem) + let openDecl = OpenDeclaration.Create (openTarget, modrefs, [], scopem, true) + OpenModuleOrNamespaceRefs tcSink g amap scopem false env modrefs openDecl + | Exception _ -> env + | _ -> env + +//------------------------------------------------------------------------- +// Bind elements of data definitions for exceptions and types (fields, etc.) +//------------------------------------------------------------------------- + +exception NotUpperCaseConstructor of range + +let CheckNamespaceModuleOrTypeName (g: TcGlobals) (id: Ident) = + // type names '[]' etc. are used in fslib + if not g.compilingFslib && id.idText.IndexOfAny IllegalCharactersInTypeAndNamespaceNames <> -1 then + errorR(Error(FSComp.SR.tcInvalidNamespaceModuleTypeUnionName(), id.idRange)) + +let CheckDuplicates (idf: _ -> Ident) k elems = + elems |> List.iteri (fun i uc1 -> + elems |> List.iteri (fun j uc2 -> + let id1 = (idf uc1) + let id2 = (idf uc2) + if j > i && id1.idText = id2.idText then + errorR (Duplicate(k, id1.idText, id1.idRange)))) + elems + + +module TcRecdUnionAndEnumDeclarations = + + let CombineReprAccess parent vis = + match parent with + | ParentNone -> vis + | Parent tcref -> combineAccess vis tcref.TypeReprAccessibility + + let MakeRecdFieldSpec _cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, vol, xmldoc, vis, m) = + let vis, _ = ComputeAccessAndCompPath env None m vis None parent + let vis = CombineReprAccess parent vis + Construct.NewRecdField isStatic konst id nameGenerated ty' isMutable vol attrsForProperty attrsForField xmldoc vis false + + let TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, synAttrs, id, nameGenerated, ty, isMutable, xmldoc, vis, m) = + let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDecl synAttrs + let attrsForProperty, attrsForField = attrs |> List.partition (fun (attrTargets, _) -> (attrTargets &&& AttributeTargets.Property) <> enum 0) + let attrsForProperty = (List.map snd attrsForProperty) + let attrsForField = (List.map snd attrsForField) + let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType env tpenv ty + let zeroInit = HasFSharpAttribute cenv.g cenv.g.attrib_DefaultValueAttribute attrsForField + let isVolatile = HasFSharpAttribute cenv.g cenv.g.attrib_VolatileFieldAttribute attrsForField + + let isThreadStatic = isThreadOrContextStatic cenv.g attrsForField + if isThreadStatic && (not zeroInit || not isStatic) then + error(Error(FSComp.SR.tcThreadStaticAndContextStaticMustBeStatic(), m)) + + if isVolatile then + error(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), m)) + + if isIncrClass && (not zeroInit || not isMutable) then errorR(Error(FSComp.SR.tcUninitializedValFieldsMustBeMutable(), m)) + if isStatic && (not zeroInit || not isMutable || vis <> Some SynAccess.Private ) then errorR(Error(FSComp.SR.tcStaticValFieldsMustBeMutableAndPrivate(), m)) + let konst = if zeroInit then Some Const.Zero else None + let rfspec = MakeRecdFieldSpec cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, isVolatile, xmldoc, vis, m) + match parent with + | Parent tcref when useGenuineField tcref.Deref rfspec -> + // Recheck the attributes for errors if the definition only generates a field + TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore + | _ -> () + rfspec + + let TcAnonFieldDecl cenv env parent tpenv nm (SynField(Attributes attribs, isStatic, idOpt, ty, isMutable, xmldoc, vis, m)) = + let id = (match idOpt with None -> mkSynId m nm | Some id -> id) + let doc = xmldoc.ToXmlDoc(true, Some []) + TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, idOpt.IsNone, ty, isMutable, doc, vis, m) + + let TcNamedFieldDecl cenv env parent isIncrClass tpenv (SynField(Attributes attribs, isStatic, id, ty, isMutable, xmldoc, vis, m)) = + match id with + | None -> error (Error(FSComp.SR.tcFieldRequiresName(), m)) + | Some id -> + let doc = xmldoc.ToXmlDoc(true, Some []) + TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, false, ty, isMutable, doc, vis, m) + + let TcNamedFieldDecls cenv env parent isIncrClass tpenv fields = + fields |> List.map (TcNamedFieldDecl cenv env parent isIncrClass tpenv) + + //------------------------------------------------------------------------- + // Bind other elements of type definitions (constructors etc.) + //------------------------------------------------------------------------- + + let CheckUnionCaseName (cenv: cenv) (id: Ident) = + let name = id.idText + if name = "Tags" then + errorR(Error(FSComp.SR.tcUnionCaseNameConflictsWithGeneratedType(name, "Tags"), id.idRange)) + + CheckNamespaceModuleOrTypeName cenv.g id + if not (String.isLeadingIdentifierCharacterUpperCase name) && name <> opNameCons && name <> opNameNil then + errorR(NotUpperCaseConstructor(id.idRange)) + + let ValidateFieldNames (synFields: SynField list, tastFields: RecdField list) = + let seen = Dictionary() + (synFields, tastFields) ||> List.iter2 (fun sf f -> + match seen.TryGetValue f.LogicalName with + | true, synField -> + match sf, synField with + | SynField(_, _, Some id, _, _, _, _, _), SynField(_, _, Some _, _, _, _, _, _) -> + error(Error(FSComp.SR.tcFieldNameIsUsedModeThanOnce(id.idText), id.idRange)) + | SynField(_, _, Some id, _, _, _, _, _), SynField(_, _, None, _, _, _, _, _) + | SynField(_, _, None, _, _, _, _, _), SynField(_, _, Some id, _, _, _, _, _) -> + error(Error(FSComp.SR.tcFieldNameConflictsWithGeneratedNameForAnonymousField(id.idText), id.idRange)) + | _ -> assert false + | _ -> + seen.Add(f.LogicalName, sf)) + + let TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv (SynUnionCase(Attributes synAttrs, id, args, xmldoc, vis, m)) = + let attrs = TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs // the attributes of a union case decl get attached to the generated "static factory" method + let vis, _ = ComputeAccessAndCompPath env None m vis None parent + let vis = CombineReprAccess parent vis + + CheckUnionCaseName cenv id + + let rfields, recordTy = + match args with + | SynUnionCaseKind.Fields flds -> + let nFields = flds.Length + let rfields = flds |> List.mapi (fun i (SynField (idOpt = idOpt) as fld) -> + match idOpt, parent with + | Some fieldId, Parent tcref -> + let item = Item.UnionCaseField (UnionCaseInfo (thisTyInst, UnionCaseRef (tcref, id.idText)), i) + CallNameResolutionSink cenv.tcSink (fieldId.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + | _ -> () + + TcAnonFieldDecl cenv env parent tpenv (mkUnionCaseFieldName nFields i) fld) + ValidateFieldNames(flds, rfields) + + rfields, thisTy + | SynUnionCaseKind.FullType (ty, arity) -> + let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType env tpenv ty + let curriedArgTys, recordTy = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m + if curriedArgTys.Length > 1 then + errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) + let argTys = curriedArgTys |> List.concat + let nFields = argTys.Length + let rfields = + argTys |> List.mapi (fun i (argty, argInfo) -> + let id = (match argInfo.Name with Some id -> id | None -> mkSynId m (mkUnionCaseFieldName nFields i)) + MakeRecdFieldSpec cenv env parent (false, None, argty, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m)) + if not (typeEquiv cenv.g recordTy thisTy) then + error(Error(FSComp.SR.tcReturnTypesForUnionMustBeSameAsType(), m)) + rfields, recordTy + let names = rfields |> List.map (fun f -> f.DisplayNameCore) + let doc = xmldoc.ToXmlDoc(true, Some names) + Construct.NewUnionCase id rfields recordTy attrs doc vis + + let TcUnionCaseDecls cenv env parent (thisTy: TType) thisTyInst tpenv unionCases = + let unionCases' = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv) + unionCases' |> CheckDuplicates (fun uc -> uc.Id) "union case" + + let TcEnumDecl cenv env parent thisTy fieldTy (SynEnumCase(Attributes synAttrs, id, v, _, xmldoc, m)) = + let attrs = TcAttributes cenv env AttributeTargets.Field synAttrs + match v with + | SynConst.Bytes _ + | SynConst.UInt16s _ + | SynConst.UserNum _ -> error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), m)) + | _ -> + let v = TcConst cenv fieldTy m env v + let vis, _ = ComputeAccessAndCompPath env None m None None parent + let vis = CombineReprAccess parent vis + if id.idText = "value__" then errorR(Error(FSComp.SR.tcNotValidEnumCaseName(), id.idRange)) + let doc = xmldoc.ToXmlDoc(true, Some []) + Construct.NewRecdField true (Some v) id false thisTy false false [] attrs doc vis false + + let TcEnumDecls cenv env parent thisTy enumCases = + let fieldTy = NewInferenceType () + let enumCases' = enumCases |> List.map (TcEnumDecl cenv env parent thisTy fieldTy) |> CheckDuplicates (fun f -> f.Id) "enum element" + fieldTy, enumCases' + +//------------------------------------------------------------------------- +// Bind elements of classes +//------------------------------------------------------------------------- + +let PublishInterface (cenv: cenv) denv (tcref: TyconRef) m compgen ty' = + if not (isInterfaceTy cenv.g ty') then errorR(Error(FSComp.SR.tcTypeIsNotInterfaceType1(NicePrint.minimalStringOfType denv ty'), m)) + let tcaug = tcref.TypeContents + if tcref.HasInterface cenv.g ty' then + errorR(Error(FSComp.SR.tcDuplicateSpecOfInterface(), m)) + tcaug.tcaug_interfaces <- (ty', compgen, m) :: tcaug.tcaug_interfaces + +let TcAndPublishMemberSpec cenv env containerInfo declKind tpenv memb = + match memb with + | SynMemberSig.ValField(_, m) -> error(Error(FSComp.SR.tcFieldValIllegalHere(), m)) + | SynMemberSig.Inherit(_, m) -> error(Error(FSComp.SR.tcInheritIllegalHere(), m)) + | SynMemberSig.NestedType(_, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)) + | SynMemberSig.Member(valSpfn, memberFlags, _) -> + TcAndPublishValSpec (cenv, env, containerInfo, declKind, Some memberFlags, tpenv, valSpfn) + | SynMemberSig.Interface _ -> + // These are done in TcMutRecDefns_Phase1 + [], tpenv + + +let TcTyconMemberSpecs cenv env containerInfo declKind tpenv augSpfn = + let members, tpenv = List.mapFold (TcAndPublishMemberSpec cenv env containerInfo declKind) tpenv augSpfn + List.concat members, tpenv + + +//------------------------------------------------------------------------- +// Bind 'open' declarations +//------------------------------------------------------------------------- + +let TcOpenLidAndPermitAutoResolve tcSink (env: TcEnv) amap (longId : Ident list) = + let ad = env.AccessRights + match longId with + | [] -> [] + | id :: rest -> + let m = longId |> List.map (fun id -> id.idRange) |> List.reduce unionRanges + match ResolveLongIdentAsModuleOrNamespace tcSink ResultCollectionSettings.AllResults amap m true OpenQualified env.NameEnv ad id rest true with + | Result res -> res + | Exception err -> + errorR(err); [] + +let TcOpenModuleOrNamespaceDecl tcSink g amap scopem env (longId, m) = + match TcOpenLidAndPermitAutoResolve tcSink env amap longId with + | [] -> env, [] + | modrefs -> + + // validate opened namespace names + for id in longId do + if id.idText <> MangledGlobalName then + CheckNamespaceModuleOrTypeName g id + + let IsPartiallyQualifiedNamespace (modref: ModuleOrNamespaceRef) = + let (CompPath(_, p)) = modref.CompilationPath + // Bug FSharp 1.0 3274: FSI paths don't count when determining this warning + let p = + match p with + | [] -> [] + | (h, _) :: t -> if h.StartsWithOrdinal FsiDynamicModulePrefix then t else p + + // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f + let isFSharpCoreSpecialCase = + match ccuOfTyconRef modref with + | None -> false + | Some ccu -> + ccuEq ccu g.fslibCcu && + // Check if we're using a reference one string shorter than what we expect. + // + // "p" is the fully qualified path _containing_ the thing we're opening, e.g. "Microsoft.FSharp" when opening "Microsoft.FSharp.Data" + // "longId" is the text being used, e.g. "FSharp.Data" + // Length of thing being opened = p.Length + 1 + // Length of reference = longId.Length + // So the reference is a "shortened" reference if (p.Length + 1) - 1 = longId.Length + (p.Length + 1) - 1 = longId.Length && + fst p.[0] = "Microsoft" + + modref.IsNamespace && + p.Length >= longId.Length && + not isFSharpCoreSpecialCase + // Allow "open Foo" for "Microsoft.Foo" from FSharp.Core + + modrefs |> List.iter (fun (_, modref, _) -> + if modref.IsModule && HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs then + errorR(Error(FSComp.SR.tcModuleRequiresQualifiedAccess(fullDisplayTextOfModRef modref), m))) + + // Bug FSharp 1.0 3133: 'open Lexing'. Skip this warning if we successfully resolved to at least a module name + if not (modrefs |> List.exists (fun (_, modref, _) -> modref.IsModule && not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs))) then + modrefs |> List.iter (fun (_, modref, _) -> + if IsPartiallyQualifiedNamespace modref then + errorR(Error(FSComp.SR.tcOpenUsedWithPartiallyQualifiedPath(fullDisplayTextOfModRef modref), m))) + + let modrefs = List.map p23 modrefs + modrefs |> List.iter (fun modref -> CheckEntityAttributes g modref m |> CommitOperationResult) + + let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.ModuleOrNamespace (longId, m), modrefs, [], scopem, false) + let env = OpenModuleOrNamespaceRefs tcSink g amap scopem false env modrefs openDecl + env, [openDecl] + +let TcOpenTypeDecl (cenv: cenv) mOpenDecl scopem env (synType: SynType, m) = + let g = cenv.g + + checkLanguageFeatureError g.langVersion LanguageFeature.OpenTypeDeclaration mOpenDecl + + let typ, _tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.Open env emptyUnscopedTyparEnv synType + + if not (isAppTy g typ) then + error(Error(FSComp.SR.tcNamedTypeRequired("open type"), m)) + + if isByrefTy g typ then + error(Error(FSComp.SR.tcIllegalByrefsInOpenTypeDeclaration(), m)) + + let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.Type (synType, m), [], [typ], scopem, false) + let env = OpenTypeContent cenv.tcSink g cenv.amap scopem env typ openDecl + env, [openDecl] + +let TcOpenDecl cenv mOpenDecl scopem env target = + match target with + | SynOpenDeclTarget.ModuleOrNamespace (longId, m) -> TcOpenModuleOrNamespaceDecl cenv.tcSink cenv.g cenv.amap scopem env (longId, m) + | SynOpenDeclTarget.Type (synType, m) -> TcOpenTypeDecl cenv mOpenDecl scopem env (synType, m) + +exception ParameterlessStructCtor of range + +let MakeSafeInitField (g: TcGlobals) env m isStatic = + let id = + // Ensure that we have an g.CompilerGlobalState + assert(g.CompilerGlobalState |> Option.isSome) + ident(g.CompilerGlobalState.Value.NiceNameGenerator.FreshCompilerGeneratedName("init", m), m) + let taccess = TAccess [env.eAccessPath] + Construct.NewRecdField isStatic None id false g.int_ty true true [] [] XmlDoc.Empty taccess true + +/// Incremental class definitions +module IncrClassChecking = + + /// Represents a single group of bindings in a class with an implicit constructor + type IncrClassBindingGroup = + | IncrClassBindingGroup of Binding list * (*isStatic:*) bool* (*recursive:*) bool + | IncrClassDo of Expr * (*isStatic:*) bool + + /// Typechecked info for implicit constructor and it's arguments + type IncrClassCtorLhs = + { + /// The TyconRef for the type being defined + TyconRef: TyconRef + + /// The type parameters allocated for the implicit instance constructor. + /// These may be equated with other (WillBeRigid) type parameters through equi-recursive inference, and so + /// should always be renormalized/canonicalized when used. + InstanceCtorDeclaredTypars: Typars + + /// The value representing the static implicit constructor. + /// Lazy to ensure the static ctor value is only published if needed. + StaticCtorValInfo: Lazy + + /// The value representing the implicit constructor. + InstanceCtorVal: Val + + /// The type of the implicit constructor, representing as a ValScheme. + InstanceCtorValScheme: ValScheme + + /// The values representing the arguments to the implicit constructor. + InstanceCtorArgs: Val list + + /// The reference cell holding the 'this' parameter within the implicit constructor so it can be referenced in the + /// arguments passed to the base constructor + InstanceCtorSafeThisValOpt: Val option + + /// Data indicating if safe-initialization checks need to be inserted for this type. + InstanceCtorSafeInitInfo: SafeInitData + + /// The value representing the 'base' variable within the implicit instance constructor. + InstanceCtorBaseValOpt: Val option + + /// The value representing the 'this' variable within the implicit instance constructor. + InstanceCtorThisVal: Val + + /// The name generator used to generate the names of fields etc. within the type. + NameGenerator: NiceNameGenerator + } + + /// Get the type parameters of the implicit constructor, after taking equi-recursive inference into account. + member ctorInfo.GetNormalizedInstanceCtorDeclaredTypars (cenv: cenv) denv m = + let ctorDeclaredTypars = ctorInfo.InstanceCtorDeclaredTypars + let ctorDeclaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g denv ctorDeclaredTypars m + ctorDeclaredTypars + + /// Check and elaborate the "left hand side" of the implicit class construction + /// syntax. + let TcImplicitCtorLhs_Phase2A(cenv: cenv, env, tpenv, tcref: TyconRef, vis, attrs, spats, thisIdOpt, baseValOpt: Val option, safeInitInfo, m, copyOfTyconTypars, objTy, thisTy, doc: PreXmlDoc) = + + let baseValOpt = + match GetSuperTypeOfType cenv.g cenv.amap m objTy with + | Some superTy -> MakeAndPublishBaseVal cenv env (match baseValOpt with None -> None | Some v -> Some v.Id) superTy + | None -> None + + // Add class typars to env + let env = AddDeclaredTypars CheckForDuplicateTypars copyOfTyconTypars env + + // Type check arguments by processing them as 'simple' patterns + // NOTE: if we allow richer patterns here this is where we'd process those patterns + let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true CheckCxs env tpenv (SynSimplePats.SimplePats (spats, m)) + + // Create the values with the given names + let _, vspecs = MakeAndPublishSimpleVals cenv env names + + if tcref.IsStructOrEnumTycon && isNil spats then + errorR (ParameterlessStructCtor(tcref.Range)) + + // Put them in order + let ctorArgs = List.map (fun v -> NameMap.find v vspecs) ctorArgNames + let safeThisValOpt = MakeAndPublishSafeThisVal cenv env thisIdOpt thisTy + + // NOTE: the type scheme here is not complete!!! The ctorTy is more or less + // just a type variable. The type and typars get fixed-up after inference + let ctorValScheme, ctorVal = + let argty = mkRefTupledTy cenv.g (typesOfVals ctorArgs) + // Initial type has known information + let ctorTy = mkFunTy argty objTy + // REVIEW: no attributes can currently be specified for the implicit constructor + let attribs = TcAttributes cenv env (AttributeTargets.Constructor ||| AttributeTargets.Method) attrs + let memberFlags = CtorMemberFlags + + let synArgInfos = List.map (SynInfo.InferSynArgInfoFromSimplePat []) spats + let valSynData = SynValInfo([synArgInfos], SynInfo.unnamedRetVal) + let id = ident ("new", m) + + CheckForNonAbstractInterface ModuleOrMemberBinding tcref memberFlags id.idRange + let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, false, attribs, [], memberFlags, valSynData, id, false) + let partialValReprInfo = TranslateTopValSynInfo m (TcAttributes cenv env) valSynData + let prelimTyschemeG = TypeScheme(copyOfTyconTypars, ctorTy) + let isComplete = ComputeIsComplete copyOfTyconTypars [] ctorTy + let topValInfo = InferGenericArityFromTyScheme prelimTyschemeG partialValReprInfo + let ctorValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, vis, false, true, false, false) + let paramNames = topValInfo.ArgNames + let doc = doc.ToXmlDoc(true, paramNames) + let ctorVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValInRecScope isComplete, ctorValScheme, attribs, doc, None, false) + ctorValScheme, ctorVal + + // We only generate the cctor on demand, because we don't need it if there are no cctor actions. + // The code below has a side-effect (MakeAndPublishVal), so we only want to run it once if at all. + // The .cctor is never referenced by any other code. + let cctorValInfo = + lazy + (let cctorArgs = [ fst(mkCompGenLocal m "unitVar" cenv.g.unit_ty) ] + + let cctorTy = mkFunTy cenv.g.unit_ty cenv.g.unit_ty + let valSynData = SynValInfo([[]], SynInfo.unnamedRetVal) + let id = ident ("cctor", m) + CheckForNonAbstractInterface ModuleOrMemberBinding tcref ClassCtorMemberFlags id.idRange + let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, false, [(*no attributes*)], [], ClassCtorMemberFlags, valSynData, id, false) + let partialValReprInfo = TranslateTopValSynInfo m (TcAttributes cenv env) valSynData + let prelimTyschemeG = TypeScheme(copyOfTyconTypars, cctorTy) + let topValInfo = InferGenericArityFromTyScheme prelimTyschemeG partialValReprInfo + let cctorValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, Some SynAccess.Private, false, true, false, false) + + let cctorVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValNotInRecScope, cctorValScheme, [(* no attributes*)], XmlDoc.Empty, None, false) + cctorArgs, cctorVal, cctorValScheme) + + let thisVal = + // --- Create this for use inside constructor + let thisId = ident ("this", m) + let thisValScheme = ValScheme(thisId, NonGenericTypeScheme thisTy, None, None, false, ValInline.Never, CtorThisVal, None, true, false, false, false) + let thisVal = MakeAndPublishVal cenv env (ParentNone, false, ClassLetBinding false, ValNotInRecScope, thisValScheme, [], XmlDoc.Empty, None, false) + thisVal + + {TyconRef = tcref + InstanceCtorDeclaredTypars = copyOfTyconTypars + StaticCtorValInfo = cctorValInfo + InstanceCtorArgs = ctorArgs + InstanceCtorVal = ctorVal + InstanceCtorValScheme = ctorValScheme + InstanceCtorBaseValOpt = baseValOpt + InstanceCtorSafeThisValOpt = safeThisValOpt + InstanceCtorSafeInitInfo = safeInitInfo + InstanceCtorThisVal = thisVal + // For generating names of local fields + NameGenerator = NiceNameGenerator() + + } + + + // Partial class defns - local val mapping to fields + + /// Create the field for a "let" binding in a type definition. + /// + /// The "v" is the local typed w.r.t. tyvars of the implicit ctor. + /// The formalTyparInst does the formal-typars/implicit-ctor-typars subst. + /// Field specifications added to a tcref must be in terms of the tcrefs formal typars. + let private MakeIncrClassField(g, cpath, formalTyparInst: TyparInst, v: Val, isStatic, rfref: RecdFieldRef) = + let name = rfref.FieldName + let id = ident (name, v.Range) + let ty = v.Type |> instType formalTyparInst + let taccess = TAccess [cpath] + let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute v.Attribs + + Construct.NewRecdField isStatic None id false ty v.IsMutable isVolatile [] v.Attribs v.XmlDoc taccess true + + /// Indicates how is a 'let' bound value in a class with implicit construction is represented in + /// the TAST ultimately produced by type checking. + type IncrClassValRepr = + + // e.g representation for 'let v = 3' if it is not used in anything given a method representation + | InVar of (* isArg: *) bool + + // e.g representation for 'let v = 3' + | InField of (*isStatic:*)bool * (*staticCountForSafeInit:*) int * RecdFieldRef + + // e.g representation for 'let f x = 3' + | InMethod of (*isStatic:*)bool * Val * ValReprInfo + + /// IncrClassReprInfo represents the decisions we make about the representation of 'let' and 'do' bindings in a + /// type defined with implicit class construction. + type IncrClassReprInfo = + { + /// Indicates the set of field names taken within one incremental class + TakenFieldNames: Set + + RepInfoTcGlobals: TcGlobals + + /// vals mapped to representations + ValReprs: Zmap + + /// vals represented as fields or members from this point on + ValsWithRepresentation: Zset + } + + static member Empty(g, names) = + { TakenFieldNames=Set.ofList names + RepInfoTcGlobals=g + ValReprs = Zmap.empty valOrder + ValsWithRepresentation = Zset.empty valOrder } + + /// Find the representation of a value + member localRep.LookupRepr (v: Val) = + match Zmap.tryFind v localRep.ValReprs with + | None -> error(InternalError("LookupRepr: failed to find representation for value", v.Range)) + | Some res -> res + + static member IsMethodRepr (cenv: cenv) (bind: Binding) = + let v = bind.Var + // unit fields are not stored, just run rhs for effects + if isUnitTy cenv.g v.Type then + false + else + let arity = InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes v bind.Expr + not arity.HasNoArgs && not v.IsMutable + + + /// Choose how a binding is represented + member localRep.ChooseRepresentation (cenv: cenv, env: TcEnv, isStatic, isCtorArg, + ctorInfo: IncrClassCtorLhs, + /// The vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings + staticForcedFieldVars: FreeLocals, + /// The vars forced to be fields due to instance member bindings + instanceForcedFieldVars: FreeLocals, + takenFieldNames: Set, + bind: Binding) = + let g = cenv.g + let v = bind.Var + let relevantForcedFieldVars = (if isStatic then staticForcedFieldVars else instanceForcedFieldVars) + + let tcref = ctorInfo.TyconRef + let name, takenFieldNames = + + let isNameTaken = + // Check if a implicit field already exists with this name + takenFieldNames.Contains(v.LogicalName) || + // Check if a user-defined field already exists with this name. Struct fields have already been created - see bug FSharp 1.0 5304 + (tcref.GetFieldByName(v.LogicalName).IsSome && (isStatic || not tcref.IsFSharpStructOrEnumTycon)) + + let nm = + if isNameTaken then + ctorInfo.NameGenerator.FreshCompilerGeneratedName (v.LogicalName, v.Range) + else + v.LogicalName + nm, takenFieldNames.Add nm + + let reportIfUnused() = + if not v.HasBeenReferenced && not v.IsCompiledAsTopLevel && not (v.DisplayName.StartsWithOrdinal("_")) && not v.IsCompilerGenerated then + warning (Error(FSComp.SR.chkUnusedValue(v.DisplayName), v.Range)) + + let repr = + match InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v bind.Expr with + | arity when arity.HasNoArgs || v.IsMutable -> + // all mutable variables are forced into fields, since they may escape into closures within the implicit constructor + // e.g. + // type C() = + // let mutable m = 1 + // let n = ... (fun () -> m) .... + // + // All struct variables are forced into fields. Structs may not contain "let" bindings, so no new variables can be + // introduced. + + if v.IsMutable || relevantForcedFieldVars.Contains v || tcref.IsStructOrEnumTycon then + //dprintfn "Representing %s as a field %s" v.LogicalName name + let rfref = RecdFieldRef(tcref, name) + reportIfUnused() + InField (isStatic, localRep.ValReprs.Count, rfref) + else + //if not v.Attribs.IsEmpty then + // warning(Error(FSComp.SR.tcAttributesIgnoredOnLetBinding(), v.Range)) + //dprintfn + // "Representing %s as a local variable %s, staticForcedFieldVars = %s, instanceForcedFieldVars = %s" + // v.LogicalName name + // (staticForcedFieldVars |> Seq.map (fun v -> v.LogicalName) |> String.concat ",") + // (instanceForcedFieldVars |> Seq.map (fun v -> v.LogicalName) |> String.concat ",") + InVar isCtorArg + | topValInfo -> + //dprintfn "Representing %s as a method %s" v.LogicalName name + let tps, _, argInfos, _, _ = GetTopValTypeInCompiledForm g topValInfo 0 v.Type v.Range + + let valSynInfo = SynValInfo(argInfos |> List.mapSquared (fun (_, argInfo) -> SynArgInfo([], false, argInfo.Name)), SynInfo.unnamedRetVal) + let memberFlags = (if isStatic then StaticMemberFlags else NonVirtualMemberFlags) SynMemberKind.Member + let id = mkSynId v.Range name + let memberInfo = MakeMemberDataAndMangledNameForMemberVal(g, tcref, false, [], [], memberFlags, valSynInfo, mkSynId v.Range name, true) + + let copyOfTyconTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv env.DisplayEnv ctorInfo.TyconRef.Range + // Add the 'this' pointer on to the function + let memberTauTy, topValInfo = + let tauTy = v.TauType + if isStatic then + tauTy, topValInfo + else + let tauTy = ctorInfo.InstanceCtorThisVal.Type --> v.TauType + let (ValReprInfo(tpNames, args, ret)) = topValInfo + let topValInfo = ValReprInfo(tpNames, ValReprInfo.selfMetadata :: args, ret) + tauTy, topValInfo + + // Add the enclosing type parameters on to the function + let topValInfo = + let (ValReprInfo(tpNames, args, ret)) = topValInfo + ValReprInfo(tpNames@ValReprInfo.InferTyparInfo copyOfTyconTypars, args, ret) + + let prelimTyschemeG = TypeScheme(copyOfTyconTypars@tps, memberTauTy) + let memberValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, None, true (* isCompilerGenerated *), true (* isIncrClass *), false, false) + let methodVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValNotInRecScope, memberValScheme, v.Attribs, XmlDoc.Empty, None, false) + reportIfUnused() + InMethod(isStatic, methodVal, topValInfo) + + repr, takenFieldNames + + /// Extend the known local representations by choosing a representation for a binding + member localRep.ChooseAndAddRepresentation(cenv: cenv, env: TcEnv, isStatic, isCtorArg, ctorInfo: IncrClassCtorLhs, staticForcedFieldVars: FreeLocals, instanceForcedFieldVars: FreeLocals, bind: Binding) = + let v = bind.Var + let repr, takenFieldNames = localRep.ChooseRepresentation (cenv, env, isStatic, isCtorArg, ctorInfo, staticForcedFieldVars, instanceForcedFieldVars, localRep.TakenFieldNames, bind ) + // OK, representation chosen, now add it + {localRep with + TakenFieldNames=takenFieldNames + ValReprs = Zmap.add v repr localRep.ValReprs} + + member localRep.ValNowWithRepresentation (v: Val) = + {localRep with ValsWithRepresentation = Zset.add v localRep.ValsWithRepresentation} + + member localRep.IsValWithRepresentation (v: Val) = + localRep.ValsWithRepresentation.Contains v + + member localRep.IsValRepresentedAsLocalVar (v: Val) = + match localRep.LookupRepr v with + | InVar false -> true + | _ -> false + + member localRep.IsValRepresentedAsMethod (v: Val) = + localRep.IsValWithRepresentation v && + match localRep.LookupRepr v with + | InMethod _ -> true + | _ -> false + + /// Make the elaborated expression that represents a use of a + /// a "let v = ..." class binding + member localRep.MakeValueLookup thisValOpt tinst safeStaticInitInfo v tyargs m = + let g = localRep.RepInfoTcGlobals + match localRep.LookupRepr v, thisValOpt with + | InVar _, _ -> + exprForVal m v + | InField(false, _idx, rfref), Some thisVal -> + let thise = exprForVal m thisVal + mkRecdFieldGetViaExprAddr (thise, rfref, tinst, m) + | InField(false, _idx, _rfref), None -> + error(InternalError("Unexpected missing 'this' variable in MakeValueLookup", m)) + | InField(true, idx, rfref), _ -> + let expr = mkStaticRecdFieldGet (rfref, tinst, m) + MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr + + | InMethod(isStatic, methodVal, topValInfo), _ -> + //dprintfn "Rewriting application of %s to be call to method %s" v.LogicalName methodVal.LogicalName + let expr, exprty = AdjustValForExpectedArity g m (mkLocalValRef methodVal) NormalValUse topValInfo + // Prepend the the type arguments for the class + let tyargs = tinst @ tyargs + let thisArgs = + if isStatic then [] + else Option.toList (Option.map (exprForVal m) thisValOpt) + + MakeApplicationAndBetaReduce g (expr, exprty, [tyargs], thisArgs, m) + + /// Make the elaborated expression that represents an assignment + /// to a "let mutable v = ..." class binding + member localRep.MakeValueAssign thisValOpt tinst safeStaticInitInfo v expr m = + let g = localRep.RepInfoTcGlobals + match localRep.LookupRepr v, thisValOpt with + | InField(false, _, rfref), Some thisVal -> + let thise = exprForVal m thisVal + mkRecdFieldSetViaExprAddr(thise, rfref, tinst, expr, m) + | InField(false, _, _rfref), None -> + error(InternalError("Unexpected missing 'this' variable in MakeValueAssign", m)) + | InVar _, _ -> + mkValSet m (mkLocalValRef v) expr + | InField (true, idx, rfref), _ -> + let expr = mkStaticRecdFieldSet(rfref, tinst, expr, m) + MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr + | InMethod _, _ -> + error(InternalError("Local was given method storage, yet later it's been assigned to", m)) + + member localRep.MakeValueGetAddress readonly thisValOpt tinst safeStaticInitInfo v m = + let g = localRep.RepInfoTcGlobals + match localRep.LookupRepr v, thisValOpt with + | InField(false, _, rfref), Some thisVal -> + let thise = exprForVal m thisVal + mkRecdFieldGetAddrViaExprAddr(readonly, thise, rfref, tinst, m) + | InField(false, _, _rfref), None -> + error(InternalError("Unexpected missing 'this' variable in MakeValueGetAddress", m)) + | InField(true, idx, rfref), _ -> + let expr = mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m) + MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr + | InVar _, _ -> + mkValAddr m readonly (mkLocalValRef v) + | InMethod _, _ -> + error(InternalError("Local was given method storage, yet later it's address was required", m)) + + /// Mutate a type definition by adding fields + /// Used as part of processing "let" bindings in a type definition. + member localRep.PublishIncrClassFields (cenv, denv, cpath, ctorInfo: IncrClassCtorLhs, safeStaticInitInfo) = + let tcref = ctorInfo.TyconRef + let rfspecs = + [ for KeyValue(v, repr) in localRep.ValReprs do + match repr with + | InField(isStatic, _, rfref) -> + // Instance fields for structs are published earlier because the full set of fields is determined syntactically from the implicit + // constructor arguments. This is important for the "default value" and "does it have an implicit default constructor" + // semantic conditions for structs - see bug FSharp 1.0 5304. + if isStatic || not tcref.IsFSharpStructOrEnumTycon then + let ctorDeclaredTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv denv ctorInfo.TyconRef.Range + + // Note: tcrefObjTy contains the original "formal" typars, thisTy is the "fresh" one... f<>fresh. + let revTypeInst = List.zip ctorDeclaredTypars (tcref.TyparsNoRange |> List.map mkTyparTy) + + yield MakeIncrClassField(localRep.RepInfoTcGlobals, cpath, revTypeInst, v, isStatic, rfref) + | _ -> + () + match safeStaticInitInfo with + | SafeInitField (_, fld) -> yield fld + | NoSafeInitInfo -> () ] + + let recdFields = Construct.MakeRecdFieldsTable (rfspecs @ tcref.AllFieldsAsList) + + // Mutate the entity_tycon_repr to publish the fields + tcref.Deref.entity_tycon_repr <- TFSharpObjectRepr { tcref.FSharpObjectModelTypeInfo with fsobjmodel_rfields = recdFields} + + + /// Given localRep saying how locals have been represented, e.g. as fields. + /// Given an expr under a given thisVal context. + // + /// Fix up the references to the locals, e.g. + /// v -> this.fieldv + /// f x -> this.method x + member localRep.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo (thisTyInst: TypeInst) expr = + // fixup: intercept and expr rewrite + let FixupExprNode rw e = + //dprintfn "Fixup %s" (showL (exprL e)) + let g = localRep.RepInfoTcGlobals + let e = NormalizeAndAdjustPossibleSubsumptionExprs g e + match e with + // Rewrite references to applied let-bound-functions-compiled-as-methods + // Rewrite references to applied recursive let-bound-functions-compiled-as-methods + // Rewrite references to applied recursive generic let-bound-functions-compiled-as-methods + | Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, args, m) + | Expr.App (Expr.Link {contents = Expr.Val (ValDeref v, _, _) }, _, tyargs, args, m) + | Expr.App (Expr.Link {contents = Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, [], _) }, _, [], args, m) + when localRep.IsValRepresentedAsMethod v && not (cenv.recUses.ContainsKey v) -> + + let expr = localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v tyargs m + let args = args |> List.map rw + Some (MakeApplicationAndBetaReduce g (expr, (tyOfExpr g expr), [], args, m)) + + // Rewrite references to values stored as fields and first class uses of method values + | Expr.Val (ValDeref v, _, m) + when localRep.IsValWithRepresentation v -> + + //dprintfn "Found use of %s" v.LogicalName + Some (localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v [] m) + + // Rewrite assignments to mutable values stored as fields + | Expr.Op (TOp.LValueOp (LSet, ValDeref v), [], [arg], m) + when localRep.IsValWithRepresentation v -> + let arg = rw arg + Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m) + + // Rewrite taking the address of mutable values stored as fields + | Expr.Op (TOp.LValueOp (LAddrOf readonly, ValDeref v), [], [], m) + when localRep.IsValWithRepresentation v -> + Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m) + + | _ -> None + RewriteExpr { PreIntercept = Some FixupExprNode + PostTransform = (fun _ -> None) + PreInterceptBinding = None + IsUnderQuotations=true } expr + + + type IncrClassConstructionBindingsPhase2C = + | Phase2CBindings of IncrClassBindingGroup list + | Phase2CCtorJustAfterSuperInit + | Phase2CCtorJustAfterLastLet + + /// Given a set of 'let' bindings (static or not, recursive or not) that make up a class, + /// generate their initialization expression(s). + let MakeCtorForIncrClassConstructionPhase2C + (cenv: cenv, + env: TcEnv, + /// The lhs information about the implicit constructor + ctorInfo: IncrClassCtorLhs, + /// The call to the super class constructor + inheritsExpr, + /// Should we place a sequence point at the 'inheritedTys call? + inheritsIsVisible, + /// The declarations + decs: IncrClassConstructionBindingsPhase2C list, + memberBinds: Binding list, + /// Record any unconstrained type parameters generalized for the outer members as "free choices" in the let bindings + generalizedTyparsForRecursiveBlock, + safeStaticInitInfo: SafeInitData) = + + + let denv = env.DisplayEnv + let g = cenv.g + let thisVal = ctorInfo.InstanceCtorThisVal + + let m = thisVal.Range + let ctorDeclaredTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv denv m + + ctorDeclaredTypars |> List.iter (SetTyparRigid env.DisplayEnv m) + + // Reconstitute the type with the correct quantified type variables. + ctorInfo.InstanceCtorVal.SetType (mkForallTyIfNeeded ctorDeclaredTypars ctorInfo.InstanceCtorVal.TauType) + + let freeChoiceTypars = ListSet.subtract typarEq generalizedTyparsForRecursiveBlock ctorDeclaredTypars + + let thisTyInst = List.map mkTyparTy ctorDeclaredTypars + + let accFreeInExpr acc expr = + unionFreeVars acc (freeInExpr CollectLocalsNoCaching expr) + + let accFreeInBinding acc (bind: Binding) = + accFreeInExpr acc bind.Expr + + let accFreeInBindings acc (binds: Binding list) = + (acc, binds) ||> List.fold accFreeInBinding + + // Find all the variables used in any method. These become fields. + // staticForcedFieldVars: FreeLocals: the vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings + // instanceForcedFieldVars: FreeLocals: the vars forced to be fields due to instance member bindings + + let staticForcedFieldVars, instanceForcedFieldVars = + let staticForcedFieldVars, instanceForcedFieldVars = + ((emptyFreeVars, emptyFreeVars), decs) ||> List.fold (fun (staticForcedFieldVars, instanceForcedFieldVars) dec -> + match dec with + | Phase2CCtorJustAfterLastLet + | Phase2CCtorJustAfterSuperInit -> + (staticForcedFieldVars, instanceForcedFieldVars) + | Phase2CBindings decs -> + ((staticForcedFieldVars, instanceForcedFieldVars), decs) ||> List.fold (fun (staticForcedFieldVars, instanceForcedFieldVars) dec -> + match dec with + | IncrClassBindingGroup(binds, isStatic, _) -> + let methodBinds = binds |> List.filter (IncrClassReprInfo.IsMethodRepr cenv) + let staticForcedFieldVars = + if isStatic then + // Any references to static variables in any static method force the variable to be represented as a field + (staticForcedFieldVars, methodBinds) ||> accFreeInBindings + else + // Any references to static variables in any instance bindings force the variable to be represented as a field + (staticForcedFieldVars, binds) ||> accFreeInBindings + + let instanceForcedFieldVars = + // Any references to instance variables in any methods force the variable to be represented as a field + (instanceForcedFieldVars, methodBinds) ||> accFreeInBindings + + (staticForcedFieldVars, instanceForcedFieldVars) + | IncrClassDo (e, isStatic) -> + let staticForcedFieldVars = + if isStatic then + staticForcedFieldVars + else + unionFreeVars staticForcedFieldVars (freeInExpr CollectLocalsNoCaching e) + (staticForcedFieldVars, instanceForcedFieldVars))) + let staticForcedFieldVars = (staticForcedFieldVars, memberBinds) ||> accFreeInBindings + let instanceForcedFieldVars = (instanceForcedFieldVars, memberBinds) ||> accFreeInBindings + + // Any references to static variables in the 'inherits' expression force those static variables to be represented as fields + let staticForcedFieldVars = (staticForcedFieldVars, inheritsExpr) ||> accFreeInExpr + + (staticForcedFieldVars.FreeLocals, instanceForcedFieldVars.FreeLocals) + + + // Compute the implicit construction side effects of single + // 'let' or 'let rec' binding in the implicit class construction sequence + let TransBind (reps: IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) = + if v.MustInline then + error(Error(FSComp.SR.tcLocalClassBindingsCannotBeInline(), v.Range)) + let rhsExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst rhsExpr + + // The initialization of the 'ref cell' variable for 'this' is the only binding which comes prior to the super init + let isPriorToSuperInit = + match ctorInfo.InstanceCtorSafeThisValOpt with + | None -> false + | Some v2 -> valEq v v2 + + match reps.LookupRepr v with + | InMethod(isStatic, methodVal, _) -> + let _, chooseTps, tauExpr, tauTy, m = + match rhsExpr with + | Expr.TyChoose (chooseTps, b, _) -> [], chooseTps, b, (tyOfExpr g b), m + | Expr.TyLambda (_, tps, Expr.TyChoose (chooseTps, b, _), m, returnTy) -> tps, chooseTps, b, returnTy, m + | Expr.TyLambda (_, tps, b, m, returnTy) -> tps, [], b, returnTy, m + | e -> [], [], e, (tyOfExpr g e), e.Range + + let chooseTps = chooseTps @ (ListSet.subtract typarEq freeChoiceTypars methodVal.Typars) + + // Add the 'this' variable as an argument + let tauExpr, tauTy = + if isStatic then + tauExpr, tauTy + else + let e = mkLambda m thisVal (tauExpr, tauTy) + e, tyOfExpr g e + + // Replace the type parameters that used to be on the rhs with + // the full set of type parameters including the type parameters of the enclosing class + let rhsExpr = mkTypeLambda m methodVal.Typars (mkTypeChoose m chooseTps tauExpr, tauTy) + (isPriorToSuperInit, id), [TBind (methodVal, rhsExpr, spBind)] + + // If it's represented as a non-escaping local variable then just bind it to its value + // If it's represented as a non-escaping local arg then no binding necessary (ctor args are already bound) + + | InVar isArg -> + (isPriorToSuperInit, (fun e -> if isArg then e else mkLetBind m (TBind(v, rhsExpr, spBind)) e)), [] + + | InField (isStatic, idx, _) -> + // Use spBind if it available as the span for the assignment into the field + let m = + match spBind, rhsExpr with + // Don't generate big sequence points for functions in classes + | _, (Expr.Lambda _ | Expr.TyLambda _) -> v.Range + | DebugPointAtBinding.Yes m, _ -> m + | _ -> v.Range + let assignExpr = reps.MakeValueAssign (Some thisVal) thisTyInst NoSafeInitInfo v rhsExpr m + let adjustSafeInitFieldExprOpt = + if isStatic then + match safeStaticInitInfo with + | SafeInitField (rfref, _) -> + let setExpr = mkStaticRecdFieldSet (rfref, thisTyInst, mkInt g m idx, m) + let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) NoSafeInitInfo thisTyInst setExpr + Some setExpr + | NoSafeInitInfo -> + None + else + None + + (isPriorToSuperInit, (fun e -> + let e = match adjustSafeInitFieldExprOpt with None -> e | Some ae -> mkCompGenSequential m ae e + mkSequential DebugPointAtSequential.SuppressNeither m assignExpr e)), [] + + /// Work out the implicit construction side effects of a 'let', 'let rec' or 'do' + /// binding in the implicit class construction sequence + let TransTrueDec isCtorArg (reps: IncrClassReprInfo) dec = + match dec with + | IncrClassBindingGroup(binds, isStatic, isRec) -> + let actions, reps, methodBinds = + let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, ctorInfo, staticForcedFieldVars, instanceForcedFieldVars, bind)) // extend + if isRec then + // Note: the recursive calls are made via members on the object + // or via access to fields. This means the recursive loop is "broken", + // and we can collapse to sequential bindings + let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ValNowWithRepresentation bind.Var) // in scope before + let actions, methodBinds = binds |> List.map (TransBind reps) |> List.unzip // since can occur in RHS of own defns + actions, reps, methodBinds + else + let actions, methodBinds = binds |> List.map (TransBind reps) |> List.unzip + let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ValNowWithRepresentation bind.Var) // in scope after + actions, reps, methodBinds + let methodBinds = List.concat methodBinds + if isStatic then + (actions, [], methodBinds), reps + else + ([], actions, methodBinds), reps + + | IncrClassDo (doExpr, isStatic) -> + let doExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst doExpr + let binder = (fun e -> mkSequential DebugPointAtSequential.SuppressNeither doExpr.Range doExpr e) + let isPriorToSuperInit = false + if isStatic then + ([(isPriorToSuperInit, binder)], [], []), reps + else + ([], [(isPriorToSuperInit, binder)], []), reps + + + /// Work out the implicit construction side effects of each declaration + /// in the implicit class construction sequence + let TransDec (reps: IncrClassReprInfo) dec = + match dec with + // The call to the base class constructor is done so we can set the ref cell + | Phase2CCtorJustAfterSuperInit -> + let binders = + [ match ctorInfo.InstanceCtorSafeThisValOpt with + | None -> () + | Some v -> + let setExpr = mkRefCellSet g m ctorInfo.InstanceCtorThisVal.Type (exprForVal m v) (exprForVal m ctorInfo.InstanceCtorThisVal) + let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst setExpr + let binder = (fun e -> mkSequential DebugPointAtSequential.SuppressNeither setExpr.Range setExpr e) + let isPriorToSuperInit = false + yield (isPriorToSuperInit, binder) ] + + ([], binders, []), reps + + // The last 'let' binding is done so we can set the initialization condition for the collection of object fields + // which now allows members to be called. + | Phase2CCtorJustAfterLastLet -> + let binders = + [ match ctorInfo.InstanceCtorSafeInitInfo with + | SafeInitField (rfref, _) -> + let setExpr = mkRecdFieldSetViaExprAddr (exprForVal m thisVal, rfref, thisTyInst, mkOne g m, m) + let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst setExpr + let binder = (fun e -> mkSequential DebugPointAtSequential.SuppressNeither setExpr.Range setExpr e) + let isPriorToSuperInit = false + yield (isPriorToSuperInit, binder) + | NoSafeInitInfo -> + () ] + + ([], binders, []), reps + + | Phase2CBindings decs -> + let initActions, reps = List.mapFold (TransTrueDec false) reps decs + let cctorInitActions, ctorInitActions, methodBinds = List.unzip3 initActions + (List.concat cctorInitActions, List.concat ctorInitActions, List.concat methodBinds), reps + + + + let takenFieldNames = + [ for b in memberBinds do + yield b.Var.CompiledName cenv.g.CompilerGlobalState + yield b.Var.DisplayName + yield b.Var.DisplayNameCoreMangled + yield b.Var.LogicalName ] + let reps = IncrClassReprInfo.Empty(g, takenFieldNames) + + // Bind the IsArg(true) representations of the object constructor arguments and assign them to fields + // if they escape to the members. We do this by running the instance bindings 'let x = x' through TransTrueDec + // for each constructor argument 'x', but with the special flag 'isCtorArg', which helps TransBind know that + // the value is already available as an argument, and that nothing special needs to be done unless the + // value is being stored into a field. + let (cctorInitActions1, ctorInitActions1, methodBinds1), reps = + let binds = ctorInfo.InstanceCtorArgs |> List.map (fun v -> mkInvisibleBind v (exprForVal v.Range v)) + TransTrueDec true reps (IncrClassBindingGroup(binds, false, false)) + + // We expect that only ctorInitActions1 will be non-empty here, and even then only if some elements are stored in the field + assert (isNil cctorInitActions1) + assert (isNil methodBinds1) + + // Now deal with all the 'let' and 'member' declarations + let initActions, reps = List.mapFold TransDec reps decs + let cctorInitActions2, ctorInitActions2, methodBinds2 = List.unzip3 initActions + let cctorInitActions = cctorInitActions1 @ List.concat cctorInitActions2 + let ctorInitActions = ctorInitActions1 @ List.concat ctorInitActions2 + let methodBinds = methodBinds1 @ List.concat methodBinds2 + + let ctorBody = + // Build the elements of the implicit constructor body, starting from the bottom + // + // + // + // return () + let ctorInitActionsPre, ctorInitActionsPost = ctorInitActions |> List.partition fst + + // This is the return result + let ctorBody = mkUnit g m + + // Add . + // That is, add any that come prior to the super init constructor call, + // This is only ever at most the init of the InstanceCtorSafeThisValOpt and InstanceCtorSafeInitInfo var/field + let ctorBody = List.foldBack (fun (_, binder) acc -> binder acc) ctorInitActionsPost ctorBody + + // Add the + let ctorBody = + // The inheritsExpr may refer to the this variable or to incoming arguments, e.g. in closure fields. + // References to the this variable go via the ref cell that gets created to help ensure coherent initialization. + // This ref cell itself may be stored in a field of the object and accessed via arg0. + // Likewise the incoming arguments will eventually be stored in fields and accessed via arg0. + // + // As a result, the most natural way to implement this would be to simply capture arg0 if needed + // and access all variables via that. This would be done by rewriting the inheritsExpr as follows: + // let inheritsExpr = reps.FixupIncrClassExprPhase2C (Some thisVal) thisTyInst inheritsExpr + // However, the rules of IL mean we are not actually allowed to capture arg0 + // and store it as a closure field before the base class constructor is called. + // + // As a result we do not rewrite the inheritsExpr and instead + // (a) wrap a let binding for the ref cell around the inheritsExpr if needed + // (b) rely on the fact that the input arguments are in scope and can be accessed from as argument variables + // (c) rely on the fact that there are no 'let' bindings prior to the inherits expr. + let inheritsExpr = + match ctorInfo.InstanceCtorSafeThisValOpt with + | Some v when not (reps.IsValRepresentedAsLocalVar v) -> + // Rewrite the expression to convert it to a load of a field if needed. + // We are allowed to load fields from our own object even though we haven't called + // the super class constructor yet. + let ldexpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst (exprForVal m v) + mkInvisibleLet m v ldexpr inheritsExpr + | _ -> + inheritsExpr + + let spAtSuperInit = (if inheritsIsVisible then DebugPointAtSequential.SuppressNeither else DebugPointAtSequential.SuppressStmt) + mkSequential spAtSuperInit m inheritsExpr ctorBody + + // Add the normal + let ctorBody = List.foldBack (fun (_, binder) acc -> binder acc) ctorInitActionsPre ctorBody + + // Add the final wrapping to make this into a method + let ctorBody = mkMemberLambdas m [] (Some thisVal) ctorInfo.InstanceCtorBaseValOpt [ctorInfo.InstanceCtorArgs] (ctorBody, g.unit_ty) + + ctorBody + + let cctorBodyOpt = + /// Omit the .cctor if it's empty + match cctorInitActions with + | [] -> None + | _ -> + let cctorInitAction = List.foldBack (fun (_, binder) acc -> binder acc) cctorInitActions (mkUnit g m) + let m = thisVal.Range + let cctorArgs, cctorVal, _ = ctorInfo.StaticCtorValInfo.Force() + // Reconstitute the type of the implicit class constructor with the correct quantified type variables. + cctorVal.SetType (mkForallTyIfNeeded ctorDeclaredTypars cctorVal.TauType) + let cctorBody = mkMemberLambdas m [] None None [cctorArgs] (cctorInitAction, g.unit_ty) + Some cctorBody + + ctorBody, cctorBodyOpt, methodBinds, reps + +// Checking of mutually recursive types, members and 'let' bindings in classes +// +// Technique: multiple passes. +// Phase1: create and establish type definitions and core representation information +// Phase2A: create Vals for recursive items given names and args +// Phase2B-D: type check AST to TAST collecting (sufficient) type constraints, +// generalize definitions, fix up recursive instances, build ctor binding +module MutRecBindingChecking = + + open IncrClassChecking + + /// Represents one element in a type definition, after the first phase + type TyconBindingPhase2A = + /// An entry corresponding to the definition of the implicit constructor for a class + | Phase2AIncrClassCtor of IncrClassCtorLhs + /// An 'inherit' declaration in an incremental class + /// + /// Phase2AInherit (ty, arg, baseValOpt, m) + | Phase2AInherit of SynType * SynExpr * Val option * range + /// A set of value or function definitions in an incremental class + /// + /// Phase2AIncrClassBindings (tcref, letBinds, isStatic, isRec, m) + | Phase2AIncrClassBindings of TyconRef * SynBinding list * bool * bool * range + /// A 'member' definition in a class + | Phase2AMember of PreCheckingRecursiveBinding +#if OPEN_IN_TYPE_DECLARATIONS + /// A dummy declaration, should we ever support 'open' in type definitions + | Phase2AOpen of SynOpenDeclTarget * range +#endif + /// Indicates the super init has just been called, 'this' may now be published + | Phase2AIncrClassCtorJustAfterSuperInit + /// Indicates the last 'field' has been initialized, only 'do' comes after + | Phase2AIncrClassCtorJustAfterLastLet + + /// The collected syntactic input definitions for a single type or type-extension definition + type TyconBindingsPhase2A = + | TyconBindingsPhase2A of Tycon option * DeclKind * Val list * TyconRef * Typar list * TType * TyconBindingPhase2A list + + /// The collected syntactic input definitions for a recursive group of type or type-extension definitions + type MutRecDefnsPhase2AData = MutRecShape list + + /// Represents one element in a type definition, after the second phase + type TyconBindingPhase2B = + | Phase2BIncrClassCtor of IncrClassCtorLhs * Binding option + | Phase2BInherit of Expr * Val option + /// A set of value of function definitions in a class definition with an implicit constructor. + | Phase2BIncrClassBindings of IncrClassBindingGroup list + | Phase2BMember of int + /// An intermediate definition that represent the point in an implicit class definition where + /// the super type has been initialized. + | Phase2BIncrClassCtorJustAfterSuperInit + /// An intermediate definition that represent the point in an implicit class definition where + /// the last 'field' has been initialized, i.e. only 'do' and 'member' definitions come after + /// this point. + | Phase2BIncrClassCtorJustAfterLastLet + + type TyconBindingsPhase2B = TyconBindingsPhase2B of Tycon option * TyconRef * TyconBindingPhase2B list + + type MutRecDefnsPhase2BData = MutRecShape list + + /// Represents one element in a type definition, after the third phase + type TyconBindingPhase2C = + | Phase2CIncrClassCtor of IncrClassCtorLhs * Binding option + | Phase2CInherit of Expr * Val option + | Phase2CIncrClassBindings of IncrClassBindingGroup list + | Phase2CMember of PreInitializationGraphEliminationBinding + // Indicates the last 'field' has been initialized, only 'do' comes after + | Phase2CIncrClassCtorJustAfterSuperInit + | Phase2CIncrClassCtorJustAfterLastLet + + type TyconBindingsPhase2C = TyconBindingsPhase2C of Tycon option * TyconRef * TyconBindingPhase2C list + + type MutRecDefnsPhase2CData = MutRecShape list + + // Phase2A: create member prelimRecValues for "recursive" items, i.e. ctor val and member vals + // Phase2A: also processes their arg patterns - collecting type assertions + let TcMutRecBindings_Phase2A_CreateRecursiveValuesAndCheckArgumentPatterns (cenv: cenv) tpenv (envMutRec, mutRecDefns: MutRecDefnsPhase2Info) = + let g = cenv.g + + // The basic iteration over the declarations in a single type definition + // State: + // tpenv: floating type parameter environment + // recBindIdx: index of the recursive binding + // prelimRecValuesRev: accumulation of prelim value entries + // uncheckedBindsRev: accumulation of unchecked bindings + let (defnsAs: MutRecDefnsPhase2AData), (tpenv, _, uncheckedBindsRev) = + let initialOuterState = (tpenv, 0, ([]: PreCheckingRecursiveBinding list)) + (initialOuterState, envMutRec, mutRecDefns) |||> MutRecShapes.mapFoldWithEnv (fun outerState envForDecls defn -> + let tpenv, recBindIdx, uncheckedBindsRev = outerState + match defn with + | MutRecShape.Module _ -> failwith "unreachable" + | MutRecShape.Open x -> MutRecShape.Open x, outerState + | MutRecShape.ModuleAbbrev x -> MutRecShape.ModuleAbbrev x, outerState + | MutRecShape.Lets recBinds -> + let normRecDefns = + [ for RecDefnBindingInfo(a, b, c, bind) in recBinds do + yield NormalizedRecBindingDefn(a, b, c, BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForDecls bind) ] + let bindsAndValues, (tpenv, recBindIdx) = ((tpenv, recBindIdx), normRecDefns) ||> List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue ErrorOnOverrides false cenv envForDecls) + let binds = bindsAndValues |> List.collect fst + + let defnAs = MutRecShape.Lets binds + defnAs, (tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev) + + | MutRecShape.Tycon (MutRecDefnsPhase2InfoForTycon(tyconOpt, tcref, declaredTyconTypars, declKind, binds, _)) -> + + // Class members can access protected members of the implemented type + // Class members can access private members in the ty + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let initialEnvForTycon = MakeInnerEnvForTyconRef envForDecls tcref isExtrinsic + + // Re-add the type constructor to make it take precedence for record label field resolutions + // This does not apply to extension members: in those cases the relationship between the record labels + // and the type is too extruded + let envForTycon = + if isExtrinsic then + initialEnvForTycon + else + AddLocalTyconRefs true g cenv.amap tcref.Range [tcref] initialEnvForTycon + + // Make fresh version of the class type for type checking the members and lets * + let _, copyOfTyconTypars, _, objTy, thisTy = FreshenObjectArgType cenv tcref.Range TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars + + + // The basic iteration over the declarations in a single type definition + let initialInnerState = (None, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) + let defnAs, (_, _envForTycon, tpenv, recBindIdx, uncheckedBindsRev) = + + (initialInnerState, binds) ||> List.collectFold (fun innerState defn -> + + let (TyconBindingDefn(containerInfo, newslotsOK, declKind, classMemberDef, m)) = defn + let incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev = innerState + + if tcref.IsTypeAbbrev then + // ideally we'd have the 'm' of the type declaration stored here, to avoid needing to trim to line to approx + error(Error(FSComp.SR.tcTypeAbbreviationsMayNotHaveMembers(), (trimRangeToLine m))) + + if tcref.IsEnumTycon && (declKind <> ExtrinsicExtensionBinding) then + // ideally we'd have the 'm' of the type declaration stored here, to avoid needing to trim to line to approx + error(Error(FSComp.SR.tcEnumerationsMayNotHaveMembers(), (trimRangeToLine m))) + + match classMemberDef, containerInfo with + | SynMemberDefn.ImplicitCtor (vis, Attributes attrs, SynSimplePats.SimplePats(spats, _), thisIdOpt, doc, m), ContainerInfo(_, Some(MemberOrValContainerInfo(tcref, _, baseValOpt, safeInitInfo, _))) -> + if tcref.TypeOrMeasureKind = TyparKind.Measure then + error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) + + // Phase2A: make incrClassCtorLhs - ctorv, thisVal etc, type depends on argty(s) + let incrClassCtorLhs = TcImplicitCtorLhs_Phase2A(cenv, envForTycon, tpenv, tcref, vis, attrs, spats, thisIdOpt, baseValOpt, safeInitInfo, m, copyOfTyconTypars, objTy, thisTy, doc) + // Phase2A: Add copyOfTyconTypars from incrClassCtorLhs - or from tcref + let envForTycon = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envForTycon + let innerState = (Some incrClassCtorLhs, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) + + [Phase2AIncrClassCtor incrClassCtorLhs], innerState + + | SynMemberDefn.ImplicitInherit (ty, arg, _baseIdOpt, m), _ -> + if tcref.TypeOrMeasureKind = TyparKind.Measure then + error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) + + // Phase2A: inherit ty(arg) as base - pass through + // Phase2A: pick up baseValOpt! + let baseValOpt = incrClassCtorLhsOpt |> Option.bind (fun x -> x.InstanceCtorBaseValOpt) + let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) + [Phase2AInherit (ty, arg, baseValOpt, m); Phase2AIncrClassCtorJustAfterSuperInit], innerState + + | SynMemberDefn.LetBindings (letBinds, isStatic, isRec, m), _ -> + match tcref.TypeOrMeasureKind, isStatic with + | TyparKind.Measure, false -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) + | _ -> () + + if not isStatic && tcref.IsStructOrEnumTycon then + let allDo = letBinds |> List.forall (function SynBinding(_, SynBindingKind.Do, _, _, _, _, _, _, _, _, _, _) -> true | _ -> false) + // Code for potential future design change to allow functions-compiled-as-members in structs + if allDo then + errorR(Deprecated(FSComp.SR.tcStructsMayNotContainDoBindings(), (trimRangeToLine m))) + else + // Code for potential future design change to allow functions-compiled-as-members in structs + errorR(Error(FSComp.SR.tcStructsMayNotContainLetBindings(), (trimRangeToLine m))) + + if isStatic && Option.isNone incrClassCtorLhsOpt then + errorR(Error(FSComp.SR.tcStaticLetBindingsRequireClassesWithImplicitConstructors(), m)) + + // Phase2A: let-bindings - pass through + let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) + [Phase2AIncrClassBindings (tcref, letBinds, isStatic, isRec, m)], innerState + + | SynMemberDefn.Member (bind, m), _ -> + // Phase2A: member binding - create prelim valspec (for recursive reference) and RecursiveBindingInfo + let NormalizedBinding(_, _, _, _, _, _, _, valSynData, _, _, _, _) as bind = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForTycon bind + let (SynValData(memberFlagsOpt, _, _)) = valSynData + match tcref.TypeOrMeasureKind with + | TyparKind.Type -> () + | TyparKind.Measure -> + match memberFlagsOpt with + | None -> () + | Some memberFlags -> + if memberFlags.IsInstance then error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) + match memberFlags.MemberKind with + | SynMemberKind.Constructor -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembersNotConstructors(), m)) + | _ -> () + let rbind = NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, bind) + let overridesOK = DeclKind.CanOverrideOrImplement declKind + let (binds, _values), (tpenv, recBindIdx) = AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv envForTycon (tpenv, recBindIdx) rbind + let cbinds = [ for rbind in binds -> Phase2AMember rbind ] + + let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev) + cbinds, innerState + +#if OPEN_IN_TYPE_DECLARATIONS + | SynMemberDefn.Open (target, m), _ -> + let innerState = (incrClassCtorLhsOpt, env, tpenv, recBindIdx, prelimRecValuesRev, uncheckedBindsRev) + [ Phase2AOpen (target, m) ], innerState +#endif + + | definition -> + error(InternalError(sprintf "Unexpected definition %A" definition, m))) + + // If no constructor call, insert Phase2AIncrClassCtorJustAfterSuperInit at start + let defnAs = + match defnAs with + | Phase2AIncrClassCtor _ as b1 :: rest -> + let rest = + if rest |> List.exists (function Phase2AIncrClassCtorJustAfterSuperInit -> true | _ -> false) then + rest + else + Phase2AIncrClassCtorJustAfterSuperInit :: rest + // Insert Phase2AIncrClassCtorJustAfterLastLet at the point where local construction is known to have been finished + let rest = + let isAfter b = + match b with +#if OPEN_IN_TYPE_DECLARATIONS + | Phase2AOpen _ +#endif + | Phase2AIncrClassCtor _ | Phase2AInherit _ | Phase2AIncrClassCtorJustAfterSuperInit -> false + | Phase2AIncrClassBindings (_, binds, _, _, _) -> binds |> List.exists (function SynBinding (_, SynBindingKind.Do, _, _, _, _, _, _, _, _, _, _) -> true | _ -> false) + | Phase2AIncrClassCtorJustAfterLastLet + | Phase2AMember _ -> true + let restRev = List.rev rest + let afterRev = restRev |> List.takeWhile isAfter + let beforeRev = restRev |> List.skipWhile isAfter + + [ yield! List.rev beforeRev + yield Phase2AIncrClassCtorJustAfterLastLet + yield! List.rev afterRev ] + b1 :: rest + + // Cover the case where this is not a type with an implicit constructor. + | rest -> rest + + let prelimRecValues = [ for x in defnAs do match x with Phase2AMember bind -> yield bind.RecBindingInfo.Val | _ -> () ] + let defnAs = MutRecShape.Tycon(TyconBindingsPhase2A(tyconOpt, declKind, prelimRecValues, tcref, copyOfTyconTypars, thisTy, defnAs)) + defnAs, (tpenv, recBindIdx, uncheckedBindsRev)) + + let uncheckedRecBinds = List.rev uncheckedBindsRev + + (defnsAs, uncheckedRecBinds, tpenv) + + /// Phase2B: check each of the bindings, convert from ast to tast and collects type assertions. + /// Also generalize incrementally. + let TcMutRecBindings_Phase2B_TypeCheckAndIncrementalGeneralization (cenv: cenv) tpenv envInitial (envMutRec, defnsAs: MutRecDefnsPhase2AData, uncheckedRecBinds: PreCheckingRecursiveBinding list, scopem) : MutRecDefnsPhase2BData * _ * _ = + let g = cenv.g + + let (defnsBs: MutRecDefnsPhase2BData), (tpenv, generalizedRecBinds, preGeneralizationRecBinds, _, _) = + + let uncheckedRecBindsTable = uncheckedRecBinds |> List.map (fun rbind -> rbind.RecBindingInfo.Val.Stamp, rbind) |> Map.ofList + + // Loop through the types being defined... + // + // The envNonRec is the environment used to limit generalization to prevent leakage of type + // variables into the types of 'let' bindings. It gets accumulated across type definitions, e.g. + // consider + // + // type A<'T>() = + // let someFuncValue: 'A = A<'T>.Meth2() + // static member Meth2() = A<'T>.Meth2() + // and B<'T>() = + // static member Meth1() = A<'T>.Meth2() + // + // Here 'A can't be generalized, even at 'Meth1'. + // + // The envForTycon is the environment used for name resolution within the let and member bindings + // of the type definition. This becomes 'envStatic' and 'envInstance' for the two + + let initialOuterState = (tpenv, ([]: PostGeneralizationRecursiveBinding list), ([]: PreGeneralizationRecursiveBinding list), uncheckedRecBindsTable, envInitial) + + (initialOuterState, envMutRec, defnsAs) |||> MutRecShapes.mapFoldWithEnv (fun outerState envForDecls defnsA -> + + let tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec = outerState + + match defnsA with + | MutRecShape.Module _ -> failwith "unreachable" + | MutRecShape.Open x -> MutRecShape.Open x, outerState + | MutRecShape.ModuleAbbrev x -> MutRecShape.ModuleAbbrev x, outerState + | MutRecShape.Lets binds -> + + let defnBs, (tpenv, _, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = + + let initialInnerState = (tpenv, envForDecls, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + (initialInnerState, binds) ||> List.mapFold (fun innerState rbind -> + + let tpenv, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable = innerState + + let envNonRec, generalizedRecBinds, preGeneralizationRecBinds, _, uncheckedRecBindsTable = + TcLetrecBinding (cenv, envStatic, scopem, [], None) (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) rbind + + let innerState = (tpenv, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + rbind.RecBindingInfo.Index, innerState) + + let outerState = (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec) + MutRecShape.Lets defnBs, outerState + + | MutRecShape.Tycon (TyconBindingsPhase2A(tyconOpt, declKind, _, tcref, copyOfTyconTypars, thisTy, defnAs)) -> + + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let envForTycon = MakeInnerEnvForTyconRef envForDecls tcref isExtrinsic + let envForTycon = if isExtrinsic then envForTycon else AddLocalTyconRefs true g cenv.amap tcref.Range [tcref] envForTycon + // Set up the environment so use-before-definition warnings are given, at least + // until we reach a Phase2AIncrClassCtorJustAfterSuperInit. + let envForTycon = { envForTycon with eCtorInfo = Some (InitialImplicitCtorInfo()) } + + let reqdThisValTyOpt = Some thisTy + + // Loop through the definition elements in a type... + // State: + // envInstance: the environment in scope in instance members + // envStatic: the environment in scope in static members + // envNonRec: the environment relevant to generalization + // generalizedRecBinds: part of the incremental generalization state + // preGeneralizationRecBinds: part of the incremental generalization state + // uncheckedRecBindsTable: part of the incremental generalization state + let defnBs, (tpenv, _, _, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = + + let initialInnerState = (tpenv, envForTycon, envForTycon, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + (initialInnerState, defnAs) ||> List.mapFold (fun innerState defnA -> + + let tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable = innerState + + match defnA with + // Phase2B for the definition of an implicit constructor. Enrich the instance environments + // with the implicit ctor args. + | Phase2AIncrClassCtor incrClassCtorLhs -> + + let envInstance = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envInstance + let envStatic = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envStatic + let envInstance = match incrClassCtorLhs.InstanceCtorSafeThisValOpt with Some v -> AddLocalVal g cenv.tcSink scopem v envInstance | None -> envInstance + let envInstance = List.foldBack (AddLocalValPrimitive cenv.g) incrClassCtorLhs.InstanceCtorArgs envInstance + let envNonRec = match incrClassCtorLhs.InstanceCtorSafeThisValOpt with Some v -> AddLocalVal g cenv.tcSink scopem v envNonRec | None -> envNonRec + let envNonRec = List.foldBack (AddLocalValPrimitive cenv.g) incrClassCtorLhs.InstanceCtorArgs envNonRec + let safeThisValBindOpt = TcLetrecComputeCtorSafeThisValBind cenv incrClassCtorLhs.InstanceCtorSafeThisValOpt + + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt), innerState + + // Phase2B: typecheck the argument to an 'inherits' call and build the new object expr for the inherit-call + | Phase2AInherit (synBaseTy, arg, baseValOpt, m) -> + let baseTy, tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.Use envInstance tpenv synBaseTy + let baseTy = baseTy |> convertToTypeWithMetadataIfPossible g + let inheritsExpr, tpenv = + try + TcNewExpr cenv envInstance tpenv baseTy (Some synBaseTy.Range) true arg m + with e -> + errorRecovery e m + mkUnit g m, tpenv + let envInstance = match baseValOpt with Some baseVal -> AddLocalVal g cenv.tcSink scopem baseVal envInstance | None -> envInstance + let envNonRec = match baseValOpt with Some baseVal -> AddLocalVal g cenv.tcSink scopem baseVal envNonRec | None -> envNonRec + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BInherit (inheritsExpr, baseValOpt), innerState + + // Phase2B: let and let rec value and function definitions + | Phase2AIncrClassBindings (tcref, binds, isStatic, isRec, bindsm) -> + let envForBinding = if isStatic then envStatic else envInstance + let binds, bindRs, env, tpenv = + if isRec then + + // Type check local recursive binding + let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(ExprContainerInfo, NoNewSlots, ClassLetBinding isStatic, bind)) + let binds, env, tpenv = TcLetrec ErrorOnOverrides cenv envForBinding tpenv (binds, scopem(*bindsm*), scopem) + let bindRs = [IncrClassBindingGroup(binds, isStatic, true)] + binds, bindRs, env, tpenv + else + + // Type check local binding + let binds, env, tpenv = TcLetBindings cenv envForBinding ExprContainerInfo (ClassLetBinding isStatic) tpenv (binds, bindsm, scopem) + let binds, bindRs = + binds + |> List.map (function + | TMDefLet(bind, _) -> [bind], IncrClassBindingGroup([bind], isStatic, false) + | TMDefDo(e, _) -> [], IncrClassDo(e, isStatic) + | _ -> error(InternalError("unexpected definition kind", tcref.Range))) + |> List.unzip + List.concat binds, bindRs, env, tpenv + + let envNonRec = (envNonRec, binds) ||> List.fold (fun acc bind -> AddLocalValPrimitive g bind.Var acc) + + // Check to see that local bindings and members don't have the same name and check some other adhoc conditions + for bind in binds do + if not isStatic && HasFSharpAttributeOpt g g.attrib_DllImportAttribute bind.Var.Attribs then + errorR(Error(FSComp.SR.tcDllImportNotAllowed(), bind.Var.Range)) + + let nm = bind.Var.DisplayName + let ty = generalizedTyconRef tcref + let ad = envNonRec.AccessRights + match TryFindIntrinsicMethInfo cenv.infoReader bind.Var.Range ad nm ty, + TryFindIntrinsicPropInfo cenv.infoReader bind.Var.Range ad nm ty with + | [], [] -> () + | _ -> errorR (Error(FSComp.SR.tcMemberAndLocalClassBindingHaveSameName nm, bind.Var.Range)) + + // Also add static entries to the envInstance if necessary + let envInstance = (if isStatic then (binds, envInstance) ||> List.foldBack (fun b e -> AddLocalVal cenv.g cenv.tcSink scopem b.Var e) else env) + let envStatic = (if isStatic then env else envStatic) + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BIncrClassBindings bindRs, innerState + + | Phase2AIncrClassCtorJustAfterSuperInit -> + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BIncrClassCtorJustAfterSuperInit, innerState + + | Phase2AIncrClassCtorJustAfterLastLet -> + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BIncrClassCtorJustAfterLastLet, innerState + + +#if OPEN_IN_TYPE_DECLARATIONS + | Phase2AOpen(target, m) -> + let envInstance = TcOpenDecl cenv m scopem envInstance target + let envStatic = TcOpenDecl cenv m scopem envStatic target + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BOpen, innerState +#endif + + + // Note: this path doesn't add anything the environment, because the member is already available off via its type + + | Phase2AMember rbind -> + + // Phase2B: Typecheck member binding, generalize them later, when all type constraints are known + // static members are checked under envStatic. + // envStatic contains class typars and the (ungeneralized) members on the class(es). + // envStatic has no instance-variables (local let-bindings or ctor args). + + let v = rbind.RecBindingInfo .Val + let envForBinding = if v.IsInstanceMember then envInstance else envStatic + + // Type variables derived from the type definition (or implicit constructor) are always generalizable (we check their generalizability later). + // Note they may be solved to be equi-recursive. + let extraGeneralizableTypars = copyOfTyconTypars + + // Inside the incremental class syntax we assert the type of the 'this' variable to be precisely the same type as the + // this variable for the implicit class constructor. For static members, we assert the type variables associated + // for the class to be identical to those used for the implicit class constructor and the static class constructor. + // + // See TcLetrecBinding where this information is consumed. + + // Type check the member and apply early generalization. + // We ignore the tpenv returned by checking each member. Each member gets checked in a fresh, clean tpenv + let envNonRec, generalizedRecBinds, preGeneralizationRecBinds, _, uncheckedRecBindsTable = + TcLetrecBinding (cenv, envForBinding, scopem, extraGeneralizableTypars, reqdThisValTyOpt) (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) rbind + + let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) + Phase2BMember rbind.RecBindingInfo.Index, innerState) + + let defnBs = MutRecShape.Tycon (TyconBindingsPhase2B(tyconOpt, tcref, defnBs)) + let outerState = (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec) + defnBs, outerState) + + // There should be no bindings that have not been generalized since checking the vary last binding always + // results in the generalization of all remaining ungeneralized bindings, since there are no remaining unchecked bindings + // to prevent the generalization + assert preGeneralizationRecBinds.IsEmpty + + defnsBs, generalizedRecBinds, tpenv + + + // Choose type scheme implicit constructors and adjust their recursive types. + // Fixup recursive references to members. + let TcMutRecBindings_Phase2C_FixupRecursiveReferences (cenv: cenv) (denv, defnsBs: MutRecDefnsPhase2BData, generalizedTyparsForRecursiveBlock: Typar list, generalizedRecBinds: PostGeneralizationRecursiveBinding list, scopem) = + let g = cenv.g + + // Build an index ---> binding map + let generalizedBindingsMap = generalizedRecBinds |> List.map (fun pgrbind -> (pgrbind.RecBindingInfo.Index, pgrbind)) |> Map.ofList + + defnsBs |> MutRecShapes.mapTyconsAndLets + + // Phase2C: Fixup member bindings + (fun (TyconBindingsPhase2B(tyconOpt, tcref, defnBs)) -> + + let defnCs = + defnBs |> List.map (fun defnB -> + + // Phase2C: Generalise implicit ctor val + match defnB with + | Phase2BIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) -> + let valscheme = incrClassCtorLhs.InstanceCtorValScheme + let valscheme = ChooseCanonicalValSchemeAfterInference g denv valscheme scopem + AdjustRecType incrClassCtorLhs.InstanceCtorVal valscheme + Phase2CIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) + + | Phase2BInherit (inheritsExpr, basevOpt) -> + Phase2CInherit (inheritsExpr, basevOpt) + + | Phase2BIncrClassBindings bindRs -> + Phase2CIncrClassBindings bindRs + + | Phase2BIncrClassCtorJustAfterSuperInit -> + Phase2CIncrClassCtorJustAfterSuperInit + + | Phase2BIncrClassCtorJustAfterLastLet -> + Phase2CIncrClassCtorJustAfterLastLet + + | Phase2BMember idx -> + // Phase2C: Fixup member bindings + let generalizedBinding = generalizedBindingsMap.[idx] + let vxbind = TcLetrecAdjustMemberForSpecialVals cenv generalizedBinding + let pgbrind = FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock vxbind + Phase2CMember pgbrind) + TyconBindingsPhase2C(tyconOpt, tcref, defnCs)) + + // Phase2C: Fixup let bindings + (fun bindIdxs -> + [ for idx in bindIdxs do + let generalizedBinding = generalizedBindingsMap.[idx] + let vxbind = TcLetrecAdjustMemberForSpecialVals cenv generalizedBinding + yield FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock vxbind ]) + + + // --- Extract field bindings from let-bindings + // --- Extract method bindings from let-bindings + // --- Extract bindings for implicit constructors + let TcMutRecBindings_Phase2D_ExtractImplicitFieldAndMethodBindings (cenv: cenv) envMutRec tpenv (denv, generalizedTyparsForRecursiveBlock, defnsCs: MutRecDefnsPhase2CData) = + let g = cenv.g + + // let (fixupValueExprBinds, methodBinds) = + (envMutRec, defnsCs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (TyconBindingsPhase2C(tyconOpt, tcref, defnCs)) -> + match defnCs with + | Phase2CIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) :: defnCs -> + + // Determine is static fields in this type need to be "protected" against invalid recursive initialization + let safeStaticInitInfo = + // Safe static init checks are not added to FSharp.Core. The FailInit helper is not defined in some places, and + // there are some minor concerns about performance w.r.t. these static bindings: + // + // set.fs (also map.fs) + // static let empty: Set<'T> = + // let comparer = LanguagePrimitives.FastGenericComparer<'T> + // new Set<'T>(comparer, SetEmpty) + // + // prim-types.fs: + // type TypeInfo<'T>() = + // static let info = + // let ty = typeof<'T> + // ... + // and some others in prim-types.fs + // + // REVIEW: consider allowing an optimization switch to turn off these checks + + let needsSafeStaticInit = not g.compilingFslib + + // We only need safe static init checks if there are some static field bindings (actually, we look for non-method bindings) + let hasStaticBindings = + defnCs |> List.exists (function + | Phase2CIncrClassBindings groups -> + groups |> List.exists (function + | IncrClassBindingGroup(binds, isStatic, _) -> + isStatic && (binds |> List.exists (IncrClassReprInfo.IsMethodRepr cenv >> not)) + | _ -> false) + | _ -> false) + + if needsSafeStaticInit && hasStaticBindings then + let rfield = MakeSafeInitField g envForDecls tcref.Range true + SafeInitField(mkRecdFieldRef tcref rfield.LogicalName, rfield) + else + NoSafeInitInfo + + + // This is the type definition we're processing + let tcref = incrClassCtorLhs.TyconRef + + // Assumes inherit call immediately follows implicit ctor. Checked by CheckMembersForm + let inheritsExpr, inheritsIsVisible, _, defnCs = + match defnCs |> List.partition (function Phase2CInherit _ -> true | _ -> false) with + | [Phase2CInherit (inheritsExpr, baseValOpt)], defnCs -> + inheritsExpr, true, baseValOpt, defnCs + + | _ -> + if tcref.IsStructOrEnumTycon then + mkUnit g tcref.Range, false, None, defnCs + else + let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range + inheritsExpr, false, None, defnCs + + let envForTycon = MakeInnerEnvForTyconRef envForDecls tcref false + + // Compute the cpath used when creating the hidden fields + let cpath = envForTycon.eAccessPath + + let localDecs = + defnCs |> List.filter (function + | Phase2CIncrClassBindings _ + | Phase2CIncrClassCtorJustAfterSuperInit + | Phase2CIncrClassCtorJustAfterLastLet -> true + | _ -> false) + let memberBindsWithFixups = defnCs |> List.choose (function Phase2CMember pgrbind -> Some pgrbind | _ -> None) + + // Extend localDecs with "let safeThisVal = ref null" if there is a safeThisVal + let localDecs = + match safeThisValBindOpt with + | None -> localDecs + | Some bind -> Phase2CIncrClassBindings [IncrClassBindingGroup([bind], false, false)] :: localDecs + + // Carve out the initialization sequence and decide on the localRep + let ctorBodyLambdaExpr, cctorBodyLambdaExprOpt, methodBinds, localReps = + + let localDecs = + [ for localDec in localDecs do + match localDec with + | Phase2CIncrClassBindings binds -> yield Phase2CBindings binds + | Phase2CIncrClassCtorJustAfterSuperInit -> yield Phase2CCtorJustAfterSuperInit + | Phase2CIncrClassCtorJustAfterLastLet -> yield Phase2CCtorJustAfterLastLet + | _ -> () ] + let memberBinds = memberBindsWithFixups |> List.map (fun x -> x.Binding) + MakeCtorForIncrClassConstructionPhase2C(cenv, envForTycon, incrClassCtorLhs, inheritsExpr, inheritsIsVisible, localDecs, memberBinds, generalizedTyparsForRecursiveBlock, safeStaticInitInfo) + + // Generate the (value, expr) pairs for the implicit + // object constructor and implicit static initializer + let ctorValueExprBindings = + [ (let ctorValueExprBinding = TBind(incrClassCtorLhs.InstanceCtorVal, ctorBodyLambdaExpr, DebugPointAtBinding.NoneAtSticky) + let rbind = { ValScheme = incrClassCtorLhs.InstanceCtorValScheme ; Binding = ctorValueExprBinding } + FixupLetrecBind cenv envForDecls.DisplayEnv generalizedTyparsForRecursiveBlock rbind) ] + @ + ( match cctorBodyLambdaExprOpt with + | None -> [] + | Some cctorBodyLambdaExpr -> + [ (let _, cctorVal, cctorValScheme = incrClassCtorLhs.StaticCtorValInfo.Force() + let cctorValueExprBinding = TBind(cctorVal, cctorBodyLambdaExpr, DebugPointAtBinding.NoneAtSticky) + let rbind = { ValScheme = cctorValScheme; Binding = cctorValueExprBinding } + FixupLetrecBind cenv envForDecls.DisplayEnv generalizedTyparsForRecursiveBlock rbind) ] ) + + // Publish the fields of the representation to the type + localReps.PublishIncrClassFields (cenv, denv, cpath, incrClassCtorLhs, safeStaticInitInfo) (* mutation *) + + // Fixup members + let memberBindsWithFixups = + memberBindsWithFixups |> List.map (fun pgrbind -> + let (TBind(v, x, spBind)) = pgrbind.Binding + + // Work out the 'this' variable and type instantiation for field fixups. + // We use the instantiation from the instance member if any. Note: It is likely this is not strictly needed + // since we unify the types of the 'this' variables with those of the ctor declared typars. + let thisValOpt = GetInstanceMemberThisVariable (v, x) + + // Members have at least as many type parameters as the enclosing class. Just grab the type variables for the type. + let thisTyInst = List.map mkTyparTy (List.truncate (tcref.Typars(v.Range).Length) v.Typars) + + let x = localReps.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo thisTyInst x + + { pgrbind with Binding = TBind(v, x, spBind) } ) + + tyconOpt, ctorValueExprBindings @ memberBindsWithFixups, methodBinds + + // Cover the case where this is not a class with an implicit constructor + | defnCs -> + let memberBindsWithFixups = defnCs |> List.choose (function Phase2CMember pgrbind -> Some pgrbind | _ -> None) + tyconOpt, memberBindsWithFixups, []) + + /// Check a "module X = A.B.C" module abbreviation declaration + let TcModuleAbbrevDecl (cenv: cenv) scopem (env: TcEnv) (id, p, m) = + let ad = env.AccessRights + let resolved = + match p with + | [] -> Result [] + | id :: rest -> ResolveLongIdentAsModuleOrNamespace cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m true OpenQualified env.NameEnv ad id rest false + let mvvs = ForceRaise resolved + if isNil mvvs then env else + let modrefs = mvvs |> List.map p23 + if not (isNil modrefs) && modrefs |> List.forall (fun modref -> modref.IsNamespace) then + errorR(Error(FSComp.SR.tcModuleAbbreviationForNamespace(fullDisplayTextOfModRef (List.head modrefs)), m)) + let modrefs = modrefs |> List.filter (fun mvv -> not mvv.IsNamespace) + if isNil modrefs then env else + modrefs |> List.iter (fun modref -> CheckEntityAttributes cenv.g modref m |> CommitOperationResult) + let env = AddModuleAbbreviationAndReport cenv.tcSink scopem id modrefs env + env + + /// Update the contents accessible via the recursive namespace declaration, if any + let TcMutRecDefns_UpdateNSContents mutRecNSInfo = + match mutRecNSInfo with + | Some (Some (mspecNS: ModuleOrNamespace), mtypeAcc: _ ref) -> + mspecNS.entity_modul_contents <- MaybeLazy.Strict mtypeAcc.Value + | _ -> () + + /// Updates the types of the modules to contain the contents so far + let TcMutRecDefns_UpdateModuleContents mutRecNSInfo defns = + defns |> MutRecShapes.iterModules (fun (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), _) -> + mspec.entity_modul_contents <- MaybeLazy.Strict mtypeAcc.Value) + + TcMutRecDefns_UpdateNSContents mutRecNSInfo + + /// Compute the active environments within each nested module. + let TcMutRecDefns_ComputeEnvs getTyconOpt getVals (cenv: cenv) report scopem m envInitial mutRecShape = + (envInitial, mutRecShape) ||> MutRecShapes.computeEnvs + (fun envAbove (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec)) -> MakeInnerEnvWithAcc true envAbove mspec.Id mtypeAcc mspec.ModuleOrNamespaceType.ModuleOrNamespaceKind) + (fun envAbove decls -> + + // Collect the type definitions, exception definitions, modules and "open" declarations + let tycons = decls |> List.choose (function MutRecShape.Tycon d -> getTyconOpt d | _ -> None) + let mspecs = decls |> List.choose (function MutRecShape.Module (MutRecDefnsPhase2DataForModule (_, mspec), _) -> Some mspec | _ -> None) + let moduleAbbrevs = decls |> List.choose (function MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev (id, mp, m)) -> Some (id, mp, m) | _ -> None) + let opens = decls |> List.choose (function MutRecShape.Open (MutRecDataForOpen (target, m, moduleRange, openDeclsRef)) -> Some (target, m, moduleRange, openDeclsRef) | _ -> None) + let lets = decls |> List.collect (function MutRecShape.Lets binds -> getVals binds | _ -> []) + let exns = tycons |> List.filter (fun (tycon: Tycon) -> tycon.IsExceptionDecl) + + // Add the type definitions, exceptions, modules and "open" declarations. + // The order here is sensitive. The things added first will be resolved in an environment + // where not everything has been added. The things added last will be preferred in name + // resolution. + // + // 'open' declarations ('open M') may refer to modules being defined ('M') and so must be + // processed in an environment where 'M' is present. However, in later processing the names of + // modules being defined ('M') take precedence over those coming from 'open' declarations. + // So add the names of the modules being defined to the environment twice - once to allow + // the processing of 'open M', and once to allow the correct name resolution of 'M'. + // + // Module abbreviations being defined ('module M = A.B.C') are not available for use in 'open' + // declarations. So + // namespace rec N = + // open M + // module M = FSharp.Core.Operators + // is not allowed. + + let envForDecls = envAbove + // Add the modules being defined + let envForDecls = (envForDecls, mspecs) ||> List.fold ((if report then AddLocalSubModuleAndReport cenv.tcSink scopem else AddLocalSubModule) cenv.g cenv.amap m) + // Process the 'open' declarations + let envForDecls = + (envForDecls, opens) ||> List.fold (fun env (target, m, moduleRange, openDeclsRef) -> + let env, openDecls = TcOpenDecl cenv m moduleRange env target + openDeclsRef.Value <- openDecls + env) + // Add the type definitions being defined + let envForDecls = (if report then AddLocalTyconsAndReport cenv.tcSink scopem else AddLocalTycons) cenv.g cenv.amap m tycons envForDecls + // Add the exception definitions being defined + let envForDecls = (envForDecls, exns) ||> List.fold (AddLocalExnDefnAndReport cenv.tcSink scopem) + // Add the modules again (but don't report them a second time) + let envForDecls = (envForDecls, mspecs) ||> List.fold (AddLocalSubModule cenv.g cenv.amap m) + // Add the module abbreviations + let envForDecls = (envForDecls, moduleAbbrevs) ||> List.fold (TcModuleAbbrevDecl cenv scopem) + // Add the values and members + let envForDecls = AddLocalVals cenv.g cenv.tcSink scopem lets envForDecls + envForDecls) + + /// Phase 2: Check the members and 'let' definitions in a mutually recursive group of definitions. + let TcMutRecDefns_Phase2_Bindings (cenv: cenv) envInitial tpenv bindsm scopem mutRecNSInfo (envMutRecPrelimWithReprs: TcEnv) (mutRecDefns: MutRecDefnsPhase2Info) = + let g = cenv.g + let denv = envMutRecPrelimWithReprs.DisplayEnv + + // Phase2A: create member prelimRecValues for "recursive" items, i.e. ctor val and member vals + // Phase2A: also processes their arg patterns - collecting type assertions + let defnsAs, uncheckedRecBinds, tpenv = TcMutRecBindings_Phase2A_CreateRecursiveValuesAndCheckArgumentPatterns cenv tpenv (envMutRecPrelimWithReprs, mutRecDefns) + + // Now basic member values are created we can compute the final attributes (i.e. in the case where attributes refer to constructors being defined) + mutRecDefns |> MutRecShapes.iterTycons (fun (MutRecDefnsPhase2InfoForTycon(_, _, _, _, _, fixupFinalAttrs)) -> + fixupFinalAttrs()) + + // Updates the types of the modules to contain the contents so far, which now includes values and members + TcMutRecDefns_UpdateModuleContents mutRecNSInfo defnsAs + + // Updates the environments to include the values + // We must open all modules from scratch again because there may be extension methods and/or AutoOpen + let envMutRec, defnsAs = + (envInitial, MutRecShapes.dropEnvs defnsAs) + ||> TcMutRecDefns_ComputeEnvs + (fun (TyconBindingsPhase2A(tyconOpt, _, _, _, _, _, _)) -> tyconOpt) + (fun binds -> [ for bind in binds -> bind.RecBindingInfo.Val ]) + cenv false scopem scopem + ||> MutRecShapes.extendEnvs (fun envForDecls decls -> + + let prelimRecValues = + decls |> List.collect (function + | MutRecShape.Tycon (TyconBindingsPhase2A(_, _, prelimRecValues, _, _, _, _)) -> prelimRecValues + | MutRecShape.Lets binds -> [ for bind in binds -> bind.RecBindingInfo.Val ] + | _ -> []) + + let ctorVals = + decls |> MutRecShapes.topTycons |> List.collect (fun (TyconBindingsPhase2A(_, _, _, _, _, _, defnAs)) -> + [ for defnB in defnAs do + match defnB with + | Phase2AIncrClassCtor incrClassCtorLhs -> yield incrClassCtorLhs.InstanceCtorVal + | _ -> () ]) + + let envForDeclsUpdated = + envForDecls + |> AddLocalVals cenv.g cenv.tcSink scopem prelimRecValues + |> AddLocalVals cenv.g cenv.tcSink scopem ctorVals + + envForDeclsUpdated) + + // Phase2B: type check pass, convert from ast to tast and collects type assertions, and generalize + let defnsBs, generalizedRecBinds, tpenv = TcMutRecBindings_Phase2B_TypeCheckAndIncrementalGeneralization cenv tpenv envInitial (envMutRec, defnsAs, uncheckedRecBinds, scopem) + + let generalizedTyparsForRecursiveBlock = + generalizedRecBinds + |> List.map (fun pgrbind -> pgrbind.GeneralizedTypars) + |> unionGeneralizedTypars + + // Check the escape condition for all extraGeneralizableTypars. + // First collect up all the extraGeneralizableTypars. + let allExtraGeneralizableTypars = + defnsAs |> MutRecShapes.collectTycons |> List.collect (fun (TyconBindingsPhase2A(_, _, _, _, copyOfTyconTypars, _, defnAs)) -> + [ yield! copyOfTyconTypars + for defnA in defnAs do + match defnA with + | Phase2AMember rbind -> yield! rbind.RecBindingInfo.EnclosingDeclaredTypars + | _ -> () ]) + + // Now check they don't escape the overall scope of the recursive set of types + if not (isNil allExtraGeneralizableTypars) then + let freeInInitialEnv = GeneralizationHelpers.ComputeUngeneralizableTypars envInitial + for extraTypar in allExtraGeneralizableTypars do + if Zset.memberOf freeInInitialEnv extraTypar then + let ty = mkTyparTy extraTypar + error(Error(FSComp.SR.tcNotSufficientlyGenericBecauseOfScope(NicePrint.prettyStringOfTy denv ty), extraTypar.Range)) + + // Solve any type variables in any part of the overall type signature of the class whose + // constraints involve generalized type variables. + // + // This includes property, member and constructor argument types that couldn't be fully generalized because they + // involve generalized copies of class type variables. + let unsolvedTyparsForRecursiveBlockInvolvingGeneralizedVariables = + let genSet = (freeInTypes CollectAllNoCaching [ for tp in generalizedTyparsForRecursiveBlock -> mkTyparTy tp ]).FreeTypars + //printfn "genSet.Count = %d" genSet.Count + let allTypes = + [ for pgrbind in generalizedRecBinds do + yield pgrbind.RecBindingInfo.Val.Type + for TyconBindingsPhase2B(_tyconOpt, _tcref, defnBs) in MutRecShapes.collectTycons defnsBs do + for defnB in defnBs do + match defnB with + | Phase2BIncrClassCtor (incrClassCtorLhs, _) -> + yield incrClassCtorLhs.InstanceCtorVal.Type + | _ -> + () + ] + //printfn "allTypes.Length = %d" allTypes.Length + let unsolvedTypars = freeInTypesLeftToRight g true allTypes + //printfn "unsolvedTypars.Length = %d" unsolvedTypars.Length + //for x in unsolvedTypars do + // printfn "unsolvedTypar: %s #%d" x.DisplayName x.Stamp + let unsolvedTyparsInvolvingGeneralizedVariables = + unsolvedTypars |> List.filter (fun tp -> + let freeInTypar = (freeInType CollectAllNoCaching (mkTyparTy tp)).FreeTypars + // Check it is not one of the generalized variables... + not (genSet.Contains tp) && + // Check it involves a generalized variable in one of its constraints... + freeInTypar.Exists(fun otherTypar -> genSet.Contains otherTypar)) + //printfn "unsolvedTyparsInvolvingGeneralizedVariables.Length = %d" unsolvedTyparsInvolvingGeneralizedVariables.Length + //for x in unsolvedTypars do + // printfn "unsolvedTyparsInvolvingGeneralizedVariable: %s #%d" x.DisplayName x.Stamp + unsolvedTyparsInvolvingGeneralizedVariables + + for tp in unsolvedTyparsForRecursiveBlockInvolvingGeneralizedVariables do + //printfn "solving unsolvedTyparsInvolvingGeneralizedVariable: %s #%d" tp.DisplayName tp.Stamp + if (tp.Rigidity <> TyparRigidity.Rigid) && not tp.IsSolved then + ChooseTyparSolutionAndSolve cenv.css denv tp + + // Now that we know what we've generalized we can adjust the recursive references + let defnsCs = TcMutRecBindings_Phase2C_FixupRecursiveReferences cenv (denv, defnsBs, generalizedTyparsForRecursiveBlock, generalizedRecBinds, scopem) + + // --- Extract field bindings from let-bindings + // --- Extract method bindings from let-bindings + // --- Extract bindings for implicit constructors + let defnsDs = TcMutRecBindings_Phase2D_ExtractImplicitFieldAndMethodBindings cenv envMutRec tpenv (denv, generalizedTyparsForRecursiveBlock, defnsCs) + + // Phase2E - rewrite values to initialization graphs + let defnsEs = + EliminateInitializationGraphs + //(fun morpher (tyconOpt, fixupValueExprBinds, methodBinds) -> (tyconOpt, morpher fixupValueExprBinds @ methodBinds)) + g true denv defnsDs + (fun morpher shape -> shape |> MutRecShapes.iterTyconsAndLets (p23 >> morpher) morpher) + MutRecShape.Lets + (fun morpher shape -> shape |> MutRecShapes.mapTyconsAndLets (fun (tyconOpt, fixupValueExprBinds, methodBinds) -> tyconOpt, (morpher fixupValueExprBinds @ methodBinds)) morpher) + bindsm + + defnsEs, envMutRec + +/// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions. +let TcMutRecDefns_Phase2 (cenv: cenv) envInitial bindsm scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) = + let g = cenv.g + let interfacesFromTypeDefn envForTycon tyconMembersData = + let (MutRecDefnsPhase2DataForTycon(_, _, declKind, tcref, _, _, declaredTyconTypars, members, _, _, _)) = tyconMembersData + let overridesOK = DeclKind.CanOverrideOrImplement declKind + members |> List.collect (function + | SynMemberDefn.Interface(ity, defnOpt, _) -> + let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref + let m = ity.Range + if tcref.IsTypeAbbrev then error(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveInterfaceDeclaration(), m)) + if tcref.IsEnumTycon then error(Error(FSComp.SR.tcEnumerationsCannotHaveInterfaceDeclaration(), m)) + + let ity' = + let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTyconTypars envForTycon + TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner emptyUnscopedTyparEnv ity |> fst + + if not (tcref.HasInterface g ity') then + error(Error(FSComp.SR.tcAllImplementedInterfacesShouldBeDeclared(), ity.Range)) + + let generatedCompareToValues = tcref.GeneratedCompareToValues.IsSome + let generatedHashAndEqualsWithComparerValues = tcref.GeneratedHashAndEqualsWithComparerValues.IsSome + let generatedCompareToWithComparerValues = tcref.GeneratedCompareToWithComparerValues.IsSome + + if (generatedCompareToValues && typeEquiv g ity' g.mk_IComparable_ty) || + (generatedCompareToWithComparerValues && typeEquiv g ity' g.mk_IStructuralComparable_ty) || + (generatedCompareToValues && typeEquiv g ity' (mkAppTy g.system_GenericIComparable_tcref [ty])) || + (generatedHashAndEqualsWithComparerValues && typeEquiv g ity' (mkAppTy g.system_GenericIEquatable_tcref [ty])) || + (generatedHashAndEqualsWithComparerValues && typeEquiv g ity' g.mk_IStructuralEquatable_ty) then + errorR(Error(FSComp.SR.tcDefaultImplementationForInterfaceHasAlreadyBeenAdded(), ity.Range)) + + if overridesOK = WarnOnOverrides then + warning(IntfImplInIntrinsicAugmentation(ity.Range)) + if overridesOK = ErrorOnOverrides then + errorR(IntfImplInExtrinsicAugmentation(ity.Range)) + match defnOpt with + | Some defn -> [ (ity', defn, m) ] + | _-> [] + + | _ -> []) + + let interfaceMembersFromTypeDefn tyconMembersData (ity', defn, _) implTySet = + let (MutRecDefnsPhase2DataForTycon(_, parent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, _, _, newslotsOK, _)) = tyconMembersData + let containerInfo = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, Some(ity', implTySet), baseValOpt, safeInitInfo, declaredTyconTypars))) + defn |> List.choose (fun mem -> + match mem with + | SynMemberDefn.Member(_, m) -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, mem, m)) + | SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, _, _, m) -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, mem, m)) + | _ -> errorR(Error(FSComp.SR.tcMemberNotPermittedInInterfaceImplementation(), mem.Range)); None) + + let tyconBindingsOfTypeDefn (MutRecDefnsPhase2DataForTycon(_, parent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, _, newslotsOK, _)) = + let containerInfo = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, None, baseValOpt, safeInitInfo, declaredTyconTypars))) + members + |> List.choose (fun memb -> + match memb with + | SynMemberDefn.ImplicitCtor _ + | SynMemberDefn.ImplicitInherit _ + | SynMemberDefn.LetBindings _ + | SynMemberDefn.AutoProperty _ + | SynMemberDefn.Member _ + | SynMemberDefn.Open _ + -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, memb, memb.Range)) + + // Interfaces exist in the member list - handled above in interfaceMembersFromTypeDefn + | SynMemberDefn.Interface _ -> None + + // The following should have been List.unzip out already in SplitTyconDefn + | SynMemberDefn.AbstractSlot _ + | SynMemberDefn.ValField _ + | SynMemberDefn.Inherit _ -> error(InternalError("Unexpected declaration element", memb.Range)) + | SynMemberDefn.NestedType _ -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), memb.Range))) + + let tpenv = emptyUnscopedTyparEnv + + try + // Some preliminary checks + mutRecDefns |> MutRecShapes.iterTycons (fun tyconData -> + let (MutRecDefnsPhase2DataForTycon(_, _, declKind, tcref, _, _, _, members, m, newslotsOK, _)) = tyconData + let tcaug = tcref.TypeContents + if tcaug.tcaug_closed && declKind <> ExtrinsicExtensionBinding then + error(InternalError("Intrinsic augmentations of types are only permitted in the same file as the definition of the type", m)) + members |> List.iter (fun mem -> + match mem with + | SynMemberDefn.Member _ -> () + | SynMemberDefn.Interface _ -> () + | SynMemberDefn.Open _ + | SynMemberDefn.AutoProperty _ + | SynMemberDefn.LetBindings _ // accept local definitions + | SynMemberDefn.ImplicitCtor _ // accept implicit ctor pattern, should be first! + | SynMemberDefn.ImplicitInherit _ when newslotsOK = NewSlotsOK -> () // accept implicit ctor pattern, should be first! + // The rest should have been removed by splitting, they belong to "core" (they are "shape" of type, not implementation) + | _ -> error(Error(FSComp.SR.tcDeclarationElementNotPermittedInAugmentation(), mem.Range)))) + + + let binds: MutRecDefnsPhase2Info = + (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls tyconData -> + let (MutRecDefnsPhase2DataForTycon(tyconOpt, _, declKind, tcref, _, _, declaredTyconTypars, _, _, _, fixupFinalAttrs)) = tyconData + let envForDecls = + // This allows to implement protected interface methods if it's a DIM. + // Does not need to be hidden behind a lang version as it needs to be possible to + // implement protected interface methods in lower F# versions regardless if it's a DIM or not. + match tyconOpt with + | Some _ when declKind = DeclKind.ModuleOrMemberBinding -> + MakeInnerEnvForTyconRef envForDecls tcref false + | _ -> + envForDecls + let obinds = tyconBindingsOfTypeDefn tyconData + let ibinds = + let intfTypes = interfacesFromTypeDefn envForDecls tyconData + let slotImplSets = DispatchSlotChecking.GetSlotImplSets cenv.infoReader envForDecls.DisplayEnv envForDecls.AccessRights false (List.map (fun (ity, _, m) -> (ity, m)) intfTypes) + (intfTypes, slotImplSets) ||> List.map2 (interfaceMembersFromTypeDefn tyconData) |> List.concat + MutRecDefnsPhase2InfoForTycon(tyconOpt, tcref, declaredTyconTypars, declKind, obinds @ ibinds, fixupFinalAttrs)) + + MutRecBindingChecking.TcMutRecDefns_Phase2_Bindings cenv envInitial tpenv bindsm scopem mutRecNSInfo envMutRec binds + + with e -> errorRecovery e scopem; [], envMutRec + +//------------------------------------------------------------------------- +// Build augmentation declarations +//------------------------------------------------------------------------- + +module AddAugmentationDeclarations = + let tcaugHasNominalInterface g (tcaug: TyconAugmentation) tcref = + tcaug.tcaug_interfaces |> List.exists (fun (x, _, _) -> + match tryTcrefOfAppTy g x with + | ValueSome tcref2 when tyconRefEq g tcref2 tcref -> true + | _ -> false) + + let AddGenericCompareDeclarations (cenv: cenv) (env: TcEnv) (scSet: Set) (tycon: Tycon) = + let g = cenv.g + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare g tycon && scSet.Contains tycon.Stamp then + let tcref = mkLocalTyconRef tycon + let tcaug = tycon.TypeContents + let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref + let m = tycon.Range + let genericIComparableTy = mkAppTy g.system_GenericIComparable_tcref [ty] + + + let hasExplicitIComparable = tycon.HasInterface g g.mk_IComparable_ty + let hasExplicitGenericIComparable = tcaugHasNominalInterface g tcaug g.system_GenericIComparable_tcref + let hasExplicitIStructuralComparable = tycon.HasInterface g g.mk_IStructuralComparable_ty + + if hasExplicitIComparable then + errorR(Error(FSComp.SR.tcImplementsIComparableExplicitly(tycon.DisplayName), m)) + + elif hasExplicitGenericIComparable then + errorR(Error(FSComp.SR.tcImplementsGenericIComparableExplicitly(tycon.DisplayName), m)) + elif hasExplicitIStructuralComparable then + errorR(Error(FSComp.SR.tcImplementsIStructuralComparableExplicitly(tycon.DisplayName), m)) + else + let hasExplicitGenericIComparable = tycon.HasInterface g genericIComparableTy + let cvspec1, cvspec2 = AugmentWithHashCompare.MakeValsForCompareAugmentation g tcref + let cvspec3 = AugmentWithHashCompare.MakeValsForCompareWithComparerAugmentation g tcref + + PublishInterface cenv env.DisplayEnv tcref m true g.mk_IStructuralComparable_ty + PublishInterface cenv env.DisplayEnv tcref m true g.mk_IComparable_ty + if not tycon.IsExceptionDecl && not hasExplicitGenericIComparable then + PublishInterface cenv env.DisplayEnv tcref m true genericIComparableTy + tcaug.SetCompare (mkLocalValRef cvspec1, mkLocalValRef cvspec2) + tcaug.SetCompareWith (mkLocalValRef cvspec3) + PublishValueDefn cenv env ModuleOrMemberBinding cvspec1 + PublishValueDefn cenv env ModuleOrMemberBinding cvspec2 + PublishValueDefn cenv env ModuleOrMemberBinding cvspec3 + + let AddGenericEqualityWithComparerDeclarations (cenv: cenv) (env: TcEnv) (seSet: Set) (tycon: Tycon) = + let g = cenv.g + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tycon && seSet.Contains tycon.Stamp then + let tcref = mkLocalTyconRef tycon + let tcaug = tycon.TypeContents + let m = tycon.Range + + let hasExplicitIStructuralEquatable = tycon.HasInterface g g.mk_IStructuralEquatable_ty + + if hasExplicitIStructuralEquatable then + errorR(Error(FSComp.SR.tcImplementsIStructuralEquatableExplicitly(tycon.DisplayName), m)) + else + let evspec1, evspec2, evspec3 = AugmentWithHashCompare.MakeValsForEqualityWithComparerAugmentation g tcref + PublishInterface cenv env.DisplayEnv tcref m true g.mk_IStructuralEquatable_ty + tcaug.SetHashAndEqualsWith (mkLocalValRef evspec1, mkLocalValRef evspec2, mkLocalValRef evspec3) + PublishValueDefn cenv env ModuleOrMemberBinding evspec1 + PublishValueDefn cenv env ModuleOrMemberBinding evspec2 + PublishValueDefn cenv env ModuleOrMemberBinding evspec3 + + let AddGenericCompareBindings (cenv: cenv) (tycon: Tycon) = + if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToValues then + AugmentWithHashCompare.MakeBindingsForCompareAugmentation cenv.g tycon + else + [] + + let AddGenericCompareWithComparerBindings (cenv: cenv) (tycon: Tycon) = + if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToWithComparerValues then + (AugmentWithHashCompare.MakeBindingsForCompareWithComparerAugmentation cenv.g tycon) + else + [] + + let AddGenericEqualityWithComparerBindings (cenv: cenv) (tycon: Tycon) = + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then + (AugmentWithHashCompare.MakeBindingsForEqualityWithComparerAugmentation cenv.g tycon) + else + [] + + let AddGenericHashAndComparisonDeclarations (cenv: cenv) (env: TcEnv) scSet seSet tycon = + AddGenericCompareDeclarations cenv env scSet tycon + AddGenericEqualityWithComparerDeclarations cenv env seSet tycon + + let AddGenericHashAndComparisonBindings cenv tycon = + AddGenericCompareBindings cenv tycon @ AddGenericCompareWithComparerBindings cenv tycon @ AddGenericEqualityWithComparerBindings cenv tycon + + // We can only add the Equals override after we've done the augmentation because we have to wait until + // tycon.HasOverride can give correct results + let AddGenericEqualityBindings (cenv: cenv) (env: TcEnv) tycon = + let g = cenv.g + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tycon then + let tcref = mkLocalTyconRef tycon + let tcaug = tycon.TypeContents + let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref + let m = tycon.Range + + // Note: tycon.HasOverride only gives correct results after we've done the type augmentation + let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty] + let hasExplicitGenericIEquatable = tcaugHasNominalInterface g tcaug g.system_GenericIEquatable_tcref + + if hasExplicitGenericIEquatable then + errorR(Error(FSComp.SR.tcImplementsIEquatableExplicitly(tycon.DisplayName), m)) + + // Note: only provide the equals method if Equals is not implemented explicitly, and + // we're actually generating Hash/Equals for this type + if not hasExplicitObjectEqualsOverride && + Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then + + let vspec1, vspec2 = AugmentWithHashCompare.MakeValsForEqualsAugmentation g tcref + tcaug.SetEquals (mkLocalValRef vspec1, mkLocalValRef vspec2) + if not tycon.IsExceptionDecl then + PublishInterface cenv env.DisplayEnv tcref m true (mkAppTy g.system_GenericIEquatable_tcref [ty]) + PublishValueDefn cenv env ModuleOrMemberBinding vspec1 + PublishValueDefn cenv env ModuleOrMemberBinding vspec2 + AugmentWithHashCompare.MakeBindingsForEqualsAugmentation g tycon + else [] + else [] + + + +/// Infer 'comparison' and 'equality' constraints from type definitions +module TyconConstraintInference = + + /// Infer 'comparison' constraints from type definitions + let InferSetOfTyconsSupportingComparable (cenv: cenv) (denv: DisplayEnv) tyconsWithStructuralTypes = + + let g = cenv.g + let tab = tyconsWithStructuralTypes |> List.map (fun (tycon: Tycon, structuralTypes) -> tycon.Stamp, (tycon, structuralTypes)) |> Map.ofList + + // Initially, assume the equality relation is available for all structural type definitions + let initialAssumedTycons = + set [ for tycon, _ in tyconsWithStructuralTypes do + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon then + yield tycon.Stamp ] + + // Initially, don't assume that the equality relation is dependent on any type variables + let initialAssumedTypars = Set.empty + + // Repeatedly eliminate structural type definitions whose structural component types no longer support + // comparison. On the way record type variables which are support the comparison relation. + let rec loop (assumedTycons: Set) (assumedTypars: Set) = + let mutable assumedTyparsAcc = assumedTypars + + // Checks if a field type supports the 'comparison' constraint based on the assumptions about the type constructors + // and type parameters. + let rec checkIfFieldTypeSupportsComparison (tycon: Tycon) (ty: TType) = + + // Is the field type a type parameter? + match tryDestTyparTy cenv.g ty with + | ValueSome tp -> + // Look for an explicit 'comparison' constraint + if tp.Constraints |> List.exists (function TyparConstraint.SupportsComparison _ -> true | _ -> false) then + true + + // Within structural types, type parameters can be optimistically assumed to have comparison + // We record the ones for which we have made this assumption. + elif tycon.TyparsNoRange |> List.exists (fun tp2 -> typarRefEq tp tp2) then + assumedTyparsAcc <- assumedTyparsAcc.Add(tp.Stamp) + true + + else + false + | _ -> + match ty with + // Look for array, UIntPtr and IntPtr types + | SpecialComparableHeadType g tinst -> + tinst |> List.forall (checkIfFieldTypeSupportsComparison tycon) + + // Otherwise it's a nominal type + | _ -> + + match ty with + | AppTy g (tcref, tinst) -> + // Check the basic requirement - IComparable/IStructuralComparable or assumed-comparable + (if initialAssumedTycons.Contains tcref.Stamp then + assumedTycons.Contains tcref.Stamp + else + ExistsSameHeadTypeInHierarchy g cenv.amap range0 ty g.mk_IComparable_ty || + ExistsSameHeadTypeInHierarchy g cenv.amap range0 ty g.mk_IStructuralComparable_ty) + && + // Check it isn't ruled out by the user + not (HasFSharpAttribute g g.attrib_NoComparisonAttribute tcref.Attribs) + && + // Check the structural dependencies + (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> + if tp.ComparisonConditionalOn || assumedTypars.Contains tp.Stamp then + checkIfFieldTypeSupportsComparison tycon ty + else + true) + | _ -> + false + + let newSet = + assumedTycons |> Set.filter (fun tyconStamp -> + let tycon, structuralTypes = tab.[tyconStamp] + + if cenv.g.compilingFslib && + AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && + not (HasFSharpAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs) && + not (HasFSharpAttribute g g.attrib_NoComparisonAttribute tycon.Attribs) then + errorR(Error(FSComp.SR.tcFSharpCoreRequiresExplicit(), tycon.Range)) + + let res = (structuralTypes |> List.forall (fst >> checkIfFieldTypeSupportsComparison tycon)) + + // If the type was excluded, say why + if not res then + match TryFindFSharpBoolAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs with + | Some true -> + match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with + | None -> + assert false + failwith "unreachable" + | Some (ty, _) -> + if isTyparTy g ty then + errorR(Error(FSComp.SR.tcStructuralComparisonNotSatisfied1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) + else + errorR(Error(FSComp.SR.tcStructuralComparisonNotSatisfied2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) + | Some false -> + () + + | None -> + match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with + | None -> + assert false + failwith "unreachable" + | Some (ty, _) -> + // NOTE: these warnings are off by default - they are level 4 informational warnings + // PERF: this call to prettyStringOfTy is always being executed, even when the warning + // is not being reported (the normal case). + if isTyparTy g ty then + warning(Error(FSComp.SR.tcNoComparisonNeeded1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) + else + warning(Error(FSComp.SR.tcNoComparisonNeeded2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) + + + res) + + if newSet = assumedTycons && assumedTypars = assumedTyparsAcc then + newSet, assumedTyparsAcc + else + loop newSet assumedTyparsAcc + + let uneliminatedTycons, assumedTyparsActual = loop initialAssumedTycons initialAssumedTypars + + // OK, we're done, Record the results for the type variable which provide the support + for tyconStamp in uneliminatedTycons do + let tycon, _ = tab.[tyconStamp] + for tp in tycon.Typars(tycon.Range) do + if assumedTyparsActual.Contains(tp.Stamp) then + tp.SetComparisonDependsOn true + + // Return the set of structural type definitions which support the relation + uneliminatedTycons + + /// Infer 'equality' constraints from type definitions + let InferSetOfTyconsSupportingEquatable (cenv: cenv) (denv: DisplayEnv) (tyconsWithStructuralTypes:(Tycon * _) list) = + + let g = cenv.g + let tab = tyconsWithStructuralTypes |> List.map (fun (tycon, c) -> tycon.Stamp, (tycon, c)) |> Map.ofList + + // Initially, assume the equality relation is available for all structural type definitions + let initialAssumedTycons = + set [ for tycon, _ in tyconsWithStructuralTypes do + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then + yield tycon.Stamp ] + + // Initially, don't assume that the equality relation is dependent on any type variables + let initialAssumedTypars = Set.empty + + // Repeatedly eliminate structural type definitions whose structural component types no longer support + // equality. On the way add type variables which are support the equality relation + let rec loop (assumedTycons: Set) (assumedTypars: Set) = + let mutable assumedTyparsAcc = assumedTypars + + // Checks if a field type supports the 'equality' constraint based on the assumptions about the type constructors + // and type parameters. + let rec checkIfFieldTypeSupportsEquality (tycon: Tycon) (ty: TType) = + match tryDestTyparTy cenv.g ty with + | ValueSome tp -> + // Look for an explicit 'equality' constraint + if tp.Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then + true + + // Within structural types, type parameters can be optimistically assumed to have equality + // We record the ones for which we have made this assumption. + elif tycon.Typars(tycon.Range) |> List.exists (fun tp2 -> typarRefEq tp tp2) then + assumedTyparsAcc <- assumedTyparsAcc.Add(tp.Stamp) + true + else + false + | _ -> + match ty with + | SpecialEquatableHeadType g tinst -> + tinst |> List.forall (checkIfFieldTypeSupportsEquality tycon) + | SpecialNotEquatableHeadType g -> + false + | _ -> + // Check the basic requirement - any types except those eliminated + match ty with + | AppTy g (tcref, tinst) -> + (if initialAssumedTycons.Contains tcref.Stamp then + assumedTycons.Contains tcref.Stamp + elif AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tcref.Deref then + Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues + else + true) + && + // Check it isn't ruled out by the user + not (HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs) + && + // Check the structural dependencies + (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> + if tp.EqualityConditionalOn || assumedTypars.Contains tp.Stamp then + checkIfFieldTypeSupportsEquality tycon ty + else + true) + | _ -> + false + + let newSet = + assumedTycons |> Set.filter (fun tyconStamp -> + + let tycon, structuralTypes = tab.[tyconStamp] + + if cenv.g.compilingFslib && + AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && + not (HasFSharpAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs) && + not (HasFSharpAttribute g g.attrib_NoEqualityAttribute tycon.Attribs) then + errorR(Error(FSComp.SR.tcFSharpCoreRequiresExplicit(), tycon.Range)) + + // Remove structural types with incomparable elements from the assumedTycons + let res = (structuralTypes |> List.forall (fst >> checkIfFieldTypeSupportsEquality tycon)) + + // If the type was excluded, say why + if not res then + match TryFindFSharpBoolAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs with + | Some true -> + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then + match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with + | None -> + assert false + failwith "unreachable" + | Some (ty, _) -> + if isTyparTy g ty then + errorR(Error(FSComp.SR.tcStructuralEqualityNotSatisfied1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) + else + errorR(Error(FSComp.SR.tcStructuralEqualityNotSatisfied2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) + else + () + | Some false -> + () + | None -> + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then + match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with + | None -> + assert false + failwith "unreachable" + | Some (ty, _) -> + if isTyparTy g ty then + warning(Error(FSComp.SR.tcNoEqualityNeeded1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) + else + warning(Error(FSComp.SR.tcNoEqualityNeeded2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) + + + res) + + if newSet = assumedTycons && assumedTypars = assumedTyparsAcc then + newSet, assumedTyparsAcc + else + loop newSet assumedTyparsAcc + + let uneliminatedTycons, assumedTyparsActual = loop initialAssumedTycons initialAssumedTypars + + // OK, we're done, Record the results for the type variable which provide the support + for tyconStamp in uneliminatedTycons do + let tycon, _ = tab.[tyconStamp] + for tp in tycon.Typars(tycon.Range) do + if assumedTyparsActual.Contains(tp.Stamp) then + tp.SetEqualityDependsOn true + + // Return the set of structural type definitions which support the relation + uneliminatedTycons + + +//------------------------------------------------------------------------- +// Helpers for modules, types and exception declarations +//------------------------------------------------------------------------- + +let ComputeModuleName (longPath: Ident list) = + if longPath.Length <> 1 then error(Error(FSComp.SR.tcInvalidModuleName(), (List.head longPath).idRange)) + longPath.Head + +let CheckForDuplicateConcreteType env nm m = + let curr = GetCurrAccumulatedModuleOrNamespaceType env + if Map.containsKey nm curr.AllEntitiesByCompiledAndLogicalMangledNames then + // Use 'error' instead of 'errorR' here to avoid cascading errors - see bug 1177 in FSharp 1.0 + error (Duplicate(FSComp.SR.tcTypeExceptionOrModule(), nm, m)) + +let CheckForDuplicateModule env nm m = + let curr = GetCurrAccumulatedModuleOrNamespaceType env + if curr.ModulesAndNamespacesByDemangledName.ContainsKey nm then + errorR (Duplicate(FSComp.SR.tcTypeOrModule(), nm, m)) + + +//------------------------------------------------------------------------- +// Bind exception definitions +//------------------------------------------------------------------------- + +/// Check 'exception' declarations in implementations and signatures +module TcExceptionDeclarations = + + let TcExnDefnCore_Phase1A cenv env parent (SynExceptionDefnRepr(Attributes synAttrs, SynUnionCase(_, id, _, _, _, _), _, doc, vis, m)) = + let attrs = TcAttributes cenv env AttributeTargets.ExnDecl synAttrs + if not (String.isLeadingIdentifierCharacterUpperCase id.idText) then errorR(NotUpperCaseConstructor m) + let vis, cpath = ComputeAccessAndCompPath env None m vis None parent + let vis = TcRecdUnionAndEnumDeclarations.CombineReprAccess parent vis + CheckForDuplicateConcreteType env (id.idText + "Exception") id.idRange + CheckForDuplicateConcreteType env id.idText id.idRange + let repr = TExnFresh (Construct.MakeRecdFieldsTable []) + let doc = doc.ToXmlDoc(true, Some []) + Construct.NewExn cpath id vis repr attrs doc + + let TcExnDefnCore_Phase1G_EstablishRepresentation (cenv: cenv) (env: TcEnv) parent (exnc: Entity) (SynExceptionDefnRepr(_, SynUnionCase(_, _, args, _, _, _), reprIdOpt, _, _, m)) = + let g = cenv.g + let args = match args with SynUnionCaseKind.Fields args -> args | _ -> error(Error(FSComp.SR.tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors(), m)) + let ad = env.AccessRights + let id = exnc.Id + + let args' = + args |> List.mapi (fun i (SynField (idOpt = idOpt) as fdef) -> + match idOpt with + | Some fieldId -> + let tcref = mkLocalTyconRef exnc + let thisTypInst, _ = generalizeTyconRef tcref + let item = Item.RecdField (RecdFieldInfo (thisTypInst, RecdFieldRef (tcref, fieldId.idText))) + CallNameResolutionSink cenv.tcSink (fieldId.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + | _ -> () + + TcRecdUnionAndEnumDeclarations.TcAnonFieldDecl cenv env parent emptyUnscopedTyparEnv (mkExceptionFieldName i) fdef) + TcRecdUnionAndEnumDeclarations.ValidateFieldNames(args, args') + let repr = + match reprIdOpt with + | Some longId -> + let resolution = + ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default longId + |> ForceRaise + match resolution with + | _, Item.ExnCase exnc, [] -> + CheckTyconAccessible cenv.amap m env.AccessRights exnc |> ignore + if not (isNil args') then + errorR (Error(FSComp.SR.tcExceptionAbbreviationsShouldNotHaveArgumentList(), m)) + TExnAbbrevRepr exnc + | _, Item.CtorGroup(_, meths), [] -> + // REVIEW: check this really is an exception type + match args' with + | [] -> () + | _ -> error (Error(FSComp.SR.tcAbbreviationsFordotNetExceptionsCannotTakeArguments(), m)) + let candidates = + meths |> List.filter (fun minfo -> + minfo.NumArgs = [args'.Length] && + minfo.GenericArity = 0) + match candidates with + | [minfo] -> + match minfo.ApparentEnclosingType with + | AppTy g (tcref, _) as ety when (TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m g.exn_ty ety) -> + let tref = tcref.CompiledRepresentationForNamedType + TExnAsmRepr tref + | _ -> + error(Error(FSComp.SR.tcExceptionAbbreviationsMustReferToValidExceptions(), m)) + | _ -> + error (Error(FSComp.SR.tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor(), m)) + | _ -> + error (Error(FSComp.SR.tcNotAnException(), m)) + | None -> + TExnFresh (Construct.MakeRecdFieldsTable args') + + exnc.SetExceptionInfo repr + + let item = Item.ExnCase(mkLocalTyconRef exnc) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + args' + + let private TcExnDefnCore cenv env parent synExnDefnRepr = + let exnc = TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr + let args' = TcExnDefnCore_Phase1G_EstablishRepresentation cenv env parent exnc synExnDefnRepr + exnc.TypeContents.tcaug_super <- Some cenv.g.exn_ty + + PublishTypeDefn cenv env exnc + + let structuralTypes = args' |> List.map (fun rf -> (rf.FormalType, rf.Range)) + let scSet = TyconConstraintInference.InferSetOfTyconsSupportingComparable cenv env.DisplayEnv [(exnc, structuralTypes)] + let seSet = TyconConstraintInference.InferSetOfTyconsSupportingEquatable cenv env.DisplayEnv [(exnc, structuralTypes)] + + // Augment the exception constructor with comparison and hash methods if needed + let binds = + match exnc.ExceptionInfo with + | TExnAbbrevRepr _ | TExnNone | TExnAsmRepr _ -> [] + | TExnFresh _ -> + AddAugmentationDeclarations.AddGenericHashAndComparisonDeclarations cenv env scSet seSet exnc + AddAugmentationDeclarations.AddGenericHashAndComparisonBindings cenv exnc + + binds, exnc + + + let TcExnDefn cenv envInitial parent (SynExceptionDefn(core, aug, m), scopem) = + let binds1, exnc = TcExnDefnCore cenv envInitial parent core + let envMutRec = AddLocalExnDefnAndReport cenv.tcSink scopem (AddLocalTycons cenv.g cenv.amap scopem [exnc] envInitial) exnc + + let defns = [MutRecShape.Tycon(MutRecDefnsPhase2DataForTycon(Some exnc, parent, ModuleOrMemberBinding, mkLocalEntityRef exnc, None, NoSafeInitInfo, [], aug, m, NoNewSlots, (fun () -> ())))] + let binds2, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem None envMutRec defns + let binds2flat = binds2 |> MutRecShapes.collectTycons |> List.collect snd + // Augment types with references to values that implement the pre-baked semantics of the type + let binds3 = AddAugmentationDeclarations.AddGenericEqualityBindings cenv envFinal exnc + binds1 @ binds2flat @ binds3, exnc, envFinal + + let TcExnSignature cenv envInitial parent tpenv (SynExceptionSig(core, aug, _), scopem) = + let binds, exnc = TcExnDefnCore cenv envInitial parent core + let envMutRec = AddLocalExnDefnAndReport cenv.tcSink scopem (AddLocalTycons cenv.g cenv.amap scopem [exnc] envInitial) exnc + let ecref = mkLocalEntityRef exnc + let vals, _ = TcTyconMemberSpecs cenv envMutRec (ContainerInfo(parent, Some(MemberOrValContainerInfo(ecref, None, None, NoSafeInitInfo, [])))) ModuleOrMemberBinding tpenv aug + binds, vals, ecref, envMutRec + + + +/// Bind type definitions +/// +/// We first establish the cores of a set of type definitions (i.e. everything +/// about the type definitions that doesn't involve values or expressions) +/// +/// This is a non-trivial multi-phase algorithm. The technique used +/// is to gradually "fill in" the fields of the type constructors. +/// +/// This use of mutation is very problematic. This has many dangers, +/// since the process of filling in the fields +/// involves creating, traversing and analyzing types that may recursively +/// refer to the types being defined. However a functional version of this +/// would need to re-implement certain type relations to work over a +/// partial representation of types. +module EstablishTypeDefinitionCores = + + type TypeRealizationPass = + | FirstPass + | SecondPass + + /// Compute the mangled name of a type definition. 'doErase' is true for all type definitions except type abbreviations. + let private ComputeTyconName (longPath: Ident list, doErase: bool, typars: Typars) = + if longPath.Length <> 1 then error(Error(FSComp.SR.tcInvalidTypeExtension(), longPath.Head.idRange)) + let id = longPath.Head + let erasedArity = + if doErase then typars |> Seq.sumBy (fun tp -> if tp.IsErased then 0 else 1) + else typars.Length + mkSynId id.idRange (if erasedArity = 0 then id.idText else id.idText + "`" + string erasedArity) + + let private GetTyconAttribs g attrs = + let hasClassAttr = HasFSharpAttribute g g.attrib_ClassAttribute attrs + let hasAbstractClassAttr = HasFSharpAttribute g g.attrib_AbstractClassAttribute attrs + let hasInterfaceAttr = HasFSharpAttribute g g.attrib_InterfaceAttribute attrs + let hasStructAttr = HasFSharpAttribute g g.attrib_StructAttribute attrs + let hasMeasureAttr = HasFSharpAttribute g g.attrib_MeasureAttribute attrs + (hasClassAttr, hasAbstractClassAttr, hasInterfaceAttr, hasStructAttr, hasMeasureAttr) + + //------------------------------------------------------------------------- + // Type kind inference + //------------------------------------------------------------------------- + + let private InferTyconKind g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) = + let hasClassAttr, hasAbstractClassAttr, hasInterfaceAttr, hasStructAttr, hasMeasureAttr = GetTyconAttribs g attrs + let bi b = (if b then 1 else 0) + if (bi hasClassAttr + bi hasInterfaceAttr + bi hasStructAttr + bi hasMeasureAttr) > 1 || + (bi hasAbstractClassAttr + bi hasInterfaceAttr + bi hasStructAttr + bi hasMeasureAttr) > 1 then + error(Error(FSComp.SR.tcAttributesOfTypeSpecifyMultipleKindsForType(), m)) + + match kind with + | SynTypeDefnKind.Unspecified -> + if hasClassAttr || hasAbstractClassAttr || hasMeasureAttr then SynTypeDefnKind.Class + elif hasInterfaceAttr then SynTypeDefnKind.Interface + elif hasStructAttr then SynTypeDefnKind.Struct + elif isConcrete || not (isNil fields) then SynTypeDefnKind.Class + elif isNil slotsigs && inSig then SynTypeDefnKind.Opaque + else SynTypeDefnKind.Interface + | k -> + if hasClassAttr && not (match k with SynTypeDefnKind.Class -> true | _ -> false) || + hasMeasureAttr && not (match k with SynTypeDefnKind.Class | SynTypeDefnKind.Abbrev | SynTypeDefnKind.Opaque -> true | _ -> false) || + hasInterfaceAttr && not (match k with SynTypeDefnKind.Interface -> true | _ -> false) || + hasStructAttr && not (match k with SynTypeDefnKind.Struct | SynTypeDefnKind.Record | SynTypeDefnKind.Union -> true | _ -> false) then + error(Error(FSComp.SR.tcKindOfTypeSpecifiedDoesNotMatchDefinition(), m)) + k + + let private (|TyconCoreAbbrevThatIsReallyAUnion|_|) (hasMeasureAttr, envinner: TcEnv, id: Ident) synTyconRepr = + match synTyconRepr with + | SynTypeDefnSimpleRepr.TypeAbbrev(_, StripParenTypes (SynType.LongIdent(LongIdentWithDots([unionCaseName], _))), m) + when + (not hasMeasureAttr && + (isNil (LookupTypeNameInEnvNoArity OpenQualified unionCaseName.idText envinner.NameEnv) || + id.idText = unionCaseName.idText)) -> + Some(unionCaseName, m) + | _ -> + None + + /// Get the component types that make a record, union or struct type. + /// + /// Used when determining if a structural type supports structural comparison. + let private GetStructuralElementsOfTyconDefn cenv env tpenv (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) tycon = + let thisTyconRef = mkLocalTyconRef tycon + let m = tycon.Range + let env = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) env + let env = MakeInnerEnvForTyconRef env thisTyconRef false + [ match synTyconRepr with + | SynTypeDefnSimpleRepr.None _ -> () + | SynTypeDefnSimpleRepr.Union (_, unionCases, _) -> + + for SynUnionCase (_, _, args, _, _, m) in unionCases do + match args with + | SynUnionCaseKind.Fields flds -> + for SynField(_, _, _, ty, _, _, _, m) in flds do + let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty + yield (ty', m) + | SynUnionCaseKind.FullType (ty, arity) -> + let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty + let curriedArgTys, _ = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m + if curriedArgTys.Length > 1 then + errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) + for argTys in curriedArgTys do + for argty, _ in argTys do + yield (argty, m) + + | SynTypeDefnSimpleRepr.General (_, _, _, fields, _, _, implicitCtorSynPats, _) when tycon.IsFSharpStructOrEnumTycon -> // for structs + for SynField(_, isStatic, _, ty, _, _, _, m) in fields do + if not isStatic then + let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty + yield (ty', m) + + match implicitCtorSynPats with + | None -> () + | Some spats -> + let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true NoCheckCxs env tpenv spats + for arg in ctorArgNames do + let ty = names.[arg].Type + let m = names.[arg].Ident.idRange + if not (isNil (ListSet.subtract typarEq (freeInTypeLeftToRight cenv.g false ty) tycon.TyparsNoRange)) then + errorR(Error(FSComp.SR.tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly(), m)) + yield (ty, m) + + | SynTypeDefnSimpleRepr.Record (_, fields, _) -> + for SynField(_, _, _, ty, _, _, _, m) in fields do + let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty + yield (ty', m) + + | _ -> + () ] + + let ComputeModuleOrNamespaceKind g isModule typeNames attribs nm = + if not isModule then Namespace + elif ModuleNameIsMangled g attribs || Set.contains nm typeNames then FSharpModuleWithSuffix + else ModuleOrType + + let AdjustModuleName modKind nm = (match modKind with FSharpModuleWithSuffix -> nm+FSharpModuleSuffix | _ -> nm) + + let InstanceMembersNeedSafeInitCheck (cenv: cenv) m thisTy = + ExistsInEntireHierarchyOfType + (fun ty -> not (isStructTy cenv.g ty) && (match tryTcrefOfAppTy cenv.g ty with ValueSome tcref when tcref.HasSelfReferentialConstructor -> true | _ -> false)) + cenv.g + cenv.amap + m + AllowMultiIntfInstantiations.Yes + thisTy + + // Make the "delayed reference" boolean value recording the safe initialization of a type in a hierarchy where there is a HasSelfReferentialConstructor + let ComputeInstanceSafeInitInfo (cenv: cenv) env m thisTy = + if InstanceMembersNeedSafeInitCheck cenv m thisTy then + let rfield = MakeSafeInitField cenv.g env m false + let tcref = tcrefOfAppTy cenv.g thisTy + SafeInitField (mkRecdFieldRef tcref rfield.LogicalName, rfield) + else + NoSafeInitInfo + + + let TypeNamesInMutRecDecls cenv env (compDecls: MutRecShapes) = + [ for d in compDecls do + match d with + | MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(SynComponentInfo(_, TyparDecls typars, _, ids, _, _, _, _), _, _, _, _, isAtOriginalTyconDefn), _) -> + if isAtOriginalTyconDefn && (TcTyparDecls cenv env typars |> List.forall (fun p -> p.Kind = TyparKind.Measure)) then + yield (List.last ids).idText + | _ -> () ] + |> set + + let TypeNamesInNonMutRecDecls defs = + [ for def in defs do + match def with + | SynModuleDecl.Types (typeSpecs, _) -> + for SynTypeDefn(SynComponentInfo(_, TyparDecls typars, _, ids, _, _, _, _), trepr, _, _, _) in typeSpecs do + if isNil typars then + match trepr with + | SynTypeDefnRepr.ObjectModel(SynTypeDefnKind.Augmentation, _, _) -> () + | _ -> yield (List.last ids).idText + | _ -> () ] + |> set + + // Collect the type names so we can implicitly add the compilation suffix to module names + let TypeNamesInNonMutRecSigDecls defs = + [ for def in defs do + match def with + | SynModuleSigDecl.Types (typeSpecs, _) -> + for SynTypeDefnSig(SynComponentInfo(_, TyparDecls typars, _, ids, _, _, _, _), trepr, extraMembers, _) in typeSpecs do + if isNil typars then + match trepr with + | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.None _, _) when not (isNil extraMembers) -> () + | _ -> yield (List.last ids).idText + | _ -> () ] + |> set + + let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo decls = + let (SynComponentInfo(Attributes attribs, _, _, longPath, xml, _, vis, im)) = compInfo + let id = ComputeModuleName longPath + let modAttrs = TcAttributes cenv envInitial AttributeTargets.ModuleDecl attribs + let modKind = ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText + let modName = AdjustModuleName modKind id.idText + + let vis, _ = ComputeAccessAndCompPath envInitial None id.idRange vis None parent + + CheckForDuplicateModule envInitial id.idText id.idRange + let id = ident (modName, id.idRange) + CheckForDuplicateConcreteType envInitial id.idText im + CheckNamespaceModuleOrTypeName cenv.g id + + let envForDecls, mtypeAcc = MakeInnerEnv true envInitial id modKind + let mty = Construct.NewEmptyModuleOrNamespaceType modKind + let doc = xml.ToXmlDoc(true, Some []) + let mspec = Construct.NewModuleOrNamespace (Some envInitial.eCompPath) vis id doc modAttrs (MaybeLazy.Strict mty) + let innerParent = Parent (mkLocalModRef mspec) + let innerTypeNames = TypeNamesInMutRecDecls cenv envForDecls decls + MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, innerTypeNames, envForDecls) + + /// Establish 'type C < T1... TN > = ...' including + /// - computing the mangled name for C + /// but + /// - we don't yet 'properly' establish constraints on type parameters + let private TcTyconDefnCore_Phase1A_BuildInitialTycon (cenv: cenv) env parent (MutRecDefnsPhase1DataForTycon(synTyconInfo, synTyconRepr, _, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, _)) = + let (SynComponentInfo (_, TyparDecls synTypars, _, id, doc, preferPostfix, synVis, _)) = synTyconInfo + let checkedTypars = TcTyparDecls cenv env synTypars + id |> List.iter (CheckNamespaceModuleOrTypeName cenv.g) + match synTyconRepr with + | SynTypeDefnSimpleRepr.Exception synExnDefnRepr -> + TcExceptionDeclarations.TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr + | _ -> + let id = ComputeTyconName (id, (match synTyconRepr with SynTypeDefnSimpleRepr.TypeAbbrev _ -> false | _ -> true), checkedTypars) + + // Augmentations of type definitions are allowed within the same file as long as no new type representation or abbreviation is given + CheckForDuplicateConcreteType env id.idText id.idRange + let vis, cpath = ComputeAccessAndCompPath env None id.idRange synVis None parent + + // Establish the visibility of the representation, e.g. + // type R = + // private { f: int } + // member x.P = x.f + x.f + let synVisOfRepr = + match synTyconRepr with + | SynTypeDefnSimpleRepr.None _ -> None + | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None + | SynTypeDefnSimpleRepr.Union (vis, _, _) -> vis + | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None + | SynTypeDefnSimpleRepr.Record (vis, _, _) -> vis + | SynTypeDefnSimpleRepr.General _ -> None + | SynTypeDefnSimpleRepr.Enum _ -> None + | SynTypeDefnSimpleRepr.Exception _ -> None + + let visOfRepr, _ = ComputeAccessAndCompPath env None id.idRange synVisOfRepr None parent + let visOfRepr = combineAccess vis visOfRepr + // If we supported nested types and modules then additions would be needed here + let lmtyp = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType) + + // '' documentation is allowed for delegates + let paramNames = + match synTyconRepr with + | SynTypeDefnSimpleRepr.General (SynTypeDefnKind.Delegate (_ty, arity), _, _, _, _, _, _, _) -> arity.ArgNames + | SynTypeDefnSimpleRepr.General (SynTypeDefnKind.Unspecified, _, _, _, _, _, Some synPats, _) -> + let rec patName (p: SynSimplePat) = + match p with + | SynSimplePat.Id (id, _, _, _, _, _) -> id.idText + | SynSimplePat.Typed(pat, _, _) -> patName pat + | SynSimplePat.Attrib(pat, _, _) -> patName pat + + let rec pats (p: SynSimplePats) = + match p with + | SynSimplePats.SimplePats (ps, _) -> ps + | SynSimplePats.Typed (ps, _, _) -> pats ps + + let patNames = + pats synPats + |> List.map patName + + patNames + | _ -> [] + let doc = doc.ToXmlDoc(true, Some paramNames ) + Construct.NewTycon + (cpath, id.idText, id.idRange, vis, visOfRepr, TyparKind.Type, LazyWithContext.NotLazy checkedTypars, + doc, preferPostfix, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, lmtyp) + + //------------------------------------------------------------------------- + /// Establishing type definitions: early phase: work out the basic kind of the type definition + /// + /// On entry: the Tycon for the type definition has been created but many of its fields are not + /// yet filled in. + /// On exit: the entity_tycon_repr field of the tycon has been filled in with a dummy value that + /// indicates the kind of the type constructor + /// Also, some adhoc checks are made. + /// + /// synTyconInfo: Syntactic AST for the name, attributes etc. of the type constructor + /// synTyconRepr: Syntactic AST for the RHS of the type definition + let private TcTyconDefnCore_Phase1B_EstablishBasicKind (cenv: cenv) inSig envinner (MutRecDefnsPhase1DataForTycon(synTyconInfo, synTyconRepr, _, _, _, _)) (tycon: Tycon) = + let (SynComponentInfo(Attributes synAttrs, TyparDecls typars, _, _, _, _, _, _)) = synTyconInfo + let m = tycon.Range + let id = tycon.Id + + // 'Check' the attributes. We return the results to avoid having to re-check them in all other phases. + // Allow failure of constructor resolution because Vals for members in the same recursive group are not yet available + let attrs, getFinalAttrs = TcAttributesCanFail cenv envinner AttributeTargets.TyconDecl synAttrs + let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs + + let isStructRecordOrUnionType = + match synTyconRepr with + | SynTypeDefnSimpleRepr.Record _ + | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) _ + | SynTypeDefnSimpleRepr.Union _ -> + HasFSharpAttribute cenv.g cenv.g.attrib_StructAttribute attrs + | _ -> + false + + tycon.SetIsStructRecordOrUnion isStructRecordOrUnionType + + // Set the compiled name, if any + tycon.SetCompiledName (TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs) + + if hasMeasureAttr then + tycon.SetTypeOrMeasureKind TyparKind.Measure + if not (isNil typars) then error(Error(FSComp.SR.tcMeasureDefinitionsCannotHaveTypeParameters(), m)) + + let repr = + match synTyconRepr with + | SynTypeDefnSimpleRepr.Exception _ -> TNoRepr + | SynTypeDefnSimpleRepr.None m -> + // Run InferTyconKind to raise errors on inconsistent attribute sets + InferTyconKind cenv.g (SynTypeDefnKind.Opaque, attrs, [], [], inSig, true, m) |> ignore + if not inSig && not hasMeasureAttr then + errorR(Error(FSComp.SR.tcTypeRequiresDefinition(), m)) + if hasMeasureAttr then + TFSharpObjectRepr { fsobjmodel_kind = TFSharpClass + fsobjmodel_vslots = [] + fsobjmodel_rfields = Construct.MakeRecdFieldsTable [] } + else + TNoRepr + + | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (_, m) + | SynTypeDefnSimpleRepr.Union (_, _, m) -> + + // Run InferTyconKind to raise errors on inconsistent attribute sets + InferTyconKind cenv.g (SynTypeDefnKind.Union, attrs, [], [], inSig, true, m) |> ignore + + // Note: the table of union cases is initially empty + Construct.MakeUnionRepr [] + + | SynTypeDefnSimpleRepr.TypeAbbrev _ -> + // Run InferTyconKind to raise errors on inconsistent attribute sets + InferTyconKind cenv.g (SynTypeDefnKind.Abbrev, attrs, [], [], inSig, true, m) |> ignore + TNoRepr + + | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (s, m) -> + let s = (s :?> ILType) + // Run InferTyconKind to raise errors on inconsistent attribute sets + InferTyconKind cenv.g (SynTypeDefnKind.IL, attrs, [], [], inSig, true, m) |> ignore + TAsmRepr s + + | SynTypeDefnSimpleRepr.Record (_, _, m) -> + + // Run InferTyconKind to raise errors on inconsistent attribute sets + InferTyconKind cenv.g (SynTypeDefnKind.Record, attrs, [], [], inSig, true, m) |> ignore + + // Note: the table of record fields is initially empty + TFSharpRecdRepr (Construct.MakeRecdFieldsTable []) + + | SynTypeDefnSimpleRepr.General (kind, _, slotsigs, fields, isConcrete, _, _, _) -> + let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) + match kind with + | SynTypeDefnKind.Opaque -> + TNoRepr + | _ -> + let kind = + match kind with + | SynTypeDefnKind.Class -> TFSharpClass + | SynTypeDefnKind.Interface -> TFSharpInterface + | SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", cenv.g.unit_ty, [], [], [], None)) + | SynTypeDefnKind.Struct -> TFSharpStruct + | _ -> error(InternalError("should have inferred tycon kind", m)) + + let repr = + { fsobjmodel_kind = kind + fsobjmodel_vslots = [] + fsobjmodel_rfields = Construct.MakeRecdFieldsTable [] } + + TFSharpObjectRepr repr + + | SynTypeDefnSimpleRepr.Enum _ -> + let kind = TFSharpEnum + let repr = + { fsobjmodel_kind = kind + fsobjmodel_vslots = [] + fsobjmodel_rfields = Construct.MakeRecdFieldsTable [] } + + TFSharpObjectRepr repr + + // OK, now fill in the (partially computed) type representation + tycon.entity_tycon_repr <- repr + attrs, getFinalAttrs + +#if !NO_EXTENSIONTYPING + /// Get the items on the r.h.s. of a 'type X = ABC<...>' definition + let private TcTyconDefnCore_GetGenerateDeclaration_Rhs (StripParenTypes rhsType) = + match rhsType with + | SynType.App (StripParenTypes (SynType.LongIdent(LongIdentWithDots(tc, _))), _, args, _commas, _, _postfix, m) -> Some(tc, args, m) + | SynType.LongIdent (LongIdentWithDots(tc, _) as lidwd) -> Some(tc, [], lidwd.Range) + | SynType.LongIdentApp (StripParenTypes (SynType.LongIdent (LongIdentWithDots(tc, _))), LongIdentWithDots(longId, _), _, args, _commas, _, m) -> Some(tc@longId, args, m) + | _ -> None + + /// Check whether 'type X = ABC<...>' is a generative provided type definition + let private TcTyconDefnCore_TryAsGenerateDeclaration (cenv: cenv) (envinner: TcEnv) tpenv (tycon: Tycon, rhsType) = + + let tcref = mkLocalTyconRef tycon + match TcTyconDefnCore_GetGenerateDeclaration_Rhs rhsType with + | None -> None + | Some (tc, args, m) -> + let ad = envinner.AccessRights + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInType OpenQualified envinner.NameEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.Yes with + | Result (_, tcrefBeforeStaticArguments) when + tcrefBeforeStaticArguments.IsProvided && + not tcrefBeforeStaticArguments.IsErased -> + + let typeBeforeArguments = + match tcrefBeforeStaticArguments.TypeReprInfo with + | TProvidedTypeRepr info -> info.ProvidedType + | _ -> failwith "unreachable" + + if IsGeneratedTypeDirectReference (typeBeforeArguments, m) then + let optGeneratedTypePath = Some (tcref.CompilationPath.MangledPath @ [ tcref.LogicalName ]) + let _hasNoArgs, providedTypeAfterStaticArguments, checkTypeName = TcProvidedTypeAppToStaticConstantArgs cenv envinner optGeneratedTypePath tpenv tcrefBeforeStaticArguments args m + let isGenerated = providedTypeAfterStaticArguments.PUntaint((fun st -> not st.IsErased), m) + if isGenerated then + Some (tcrefBeforeStaticArguments, providedTypeAfterStaticArguments, checkTypeName, args, m) + else + None // The provided type (after ApplyStaticArguments) must also be marked 'IsErased=false' + else + // This must be a direct reference to a generated type, otherwise it is a type abbreviation + None + | _ -> + None + + + /// Check and establish a 'type X = ABC<...>' provided type definition + let private TcTyconDefnCore_Phase1C_EstablishDeclarationForGeneratedSetOfTypes (cenv: cenv) inSig (tycon: Tycon, rhsType: SynType, tcrefForContainer: TyconRef, theRootType: Tainted, checkTypeName, args, m) = + // Explanation: We are definitely on the compilation thread here, we just have not propagated the token this far. + let ctok = AssumeCompilationThreadWithoutEvidence() + + let tcref = mkLocalTyconRef tycon + try + let resolutionEnvironment = + if not (isNil args) then + checkTypeName() + let resolutionEnvironment = + match tcrefForContainer.TypeReprInfo with + | TProvidedTypeRepr info -> info.ResolutionEnvironment + | _ -> failwith "unreachable" + resolutionEnvironment + + // Build up a mapping from System.Type --> TyconRef/ILTypeRef, to allow reverse-mapping + // of types + + let previousContext = (theRootType.PApply ((fun x -> x.Context), m)).PUntaint (id, m) + let lookupILTypeRef, lookupTyconRef = previousContext.GetDictionaries() + + let ctxt = ProvidedTypeContext.Create(lookupILTypeRef, lookupTyconRef) + + // Create a new provided type which captures the reverse-remapping tables. + let theRootTypeWithRemapping = theRootType.PApply ((fun x -> ProvidedType.ApplyContext(x, ctxt)), m) + + let isRootGenerated, rootProvAssemStaticLinkInfoOpt = + let stRootAssembly = theRootTypeWithRemapping.PApply((fun st -> st.Assembly), m) + + cenv.amap.assemblyLoader.GetProvidedAssemblyInfo (ctok, m, stRootAssembly) + + let isRootGenerated = isRootGenerated || theRootTypeWithRemapping.PUntaint((fun st -> not st.IsErased), m) + + if not isRootGenerated then + let desig = theRootTypeWithRemapping.TypeProviderDesignation + let nm = theRootTypeWithRemapping.PUntaint((fun st -> st.FullName), m) + error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) + + cenv.createsGeneratedProvidedTypes <- true + + // In compiled code, all types in the set of generated types end up being both generated and relocated, unless relocation is suppressed + let isForcedSuppressRelocate = theRootTypeWithRemapping.PUntaint((fun st -> st.IsSuppressRelocate), m) + if isForcedSuppressRelocate && canAccessFromEverywhere tycon.Accessibility && not cenv.isScript then + errorR(Error(FSComp.SR.tcGeneratedTypesShouldBeInternalOrPrivate(), tcref.Range)) + + let isSuppressRelocate = cenv.g.isInteractive || isForcedSuppressRelocate + + // Adjust the representation of the container type + let repr = + Construct.NewProvidedTyconRepr(resolutionEnvironment, theRootTypeWithRemapping, + Import.ImportProvidedType cenv.amap m, + isSuppressRelocate, m) + tycon.entity_tycon_repr <- repr + // Record the details so we can map System.Type --> TyconRef + let ilOrigRootTypeRef = GetOriginalILTypeRefOfProvidedType (theRootTypeWithRemapping, m) + theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, tcref))), m) + + // Record the details so we can map System.Type --> ILTypeRef, including the relocation if any + if not isSuppressRelocate then + let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType + theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtRootTyRef))), m) + + // Iterate all nested types and force their embedding, to populate the mapping from System.Type --> TyconRef/ILTypeRef. + // This is only needed for generated types, because for other types the System.Type objects self-describe + // their corresponding F# type. + let rec doNestedType (eref: EntityRef) (st: Tainted) = + + // Check the type is a generated type + let isGenerated, provAssemStaticLinkInfoOpt = + let stAssembly = st.PApply((fun st -> st.Assembly), m) + cenv.amap.assemblyLoader.GetProvidedAssemblyInfo (ctok, m, stAssembly) + + let isGenerated = isGenerated || st.PUntaint((fun st -> not st.IsErased), m) + + if not isGenerated then + let desig = st.TypeProviderDesignation + let nm = st.PUntaint((fun st -> st.FullName), m) + error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) + + // Embed the type into the module we're compiling + let cpath = eref.CompilationPath.NestedCompPath eref.LogicalName ModuleOrNamespaceKind.ModuleOrType + let access = combineAccess tycon.Accessibility (if st.PUntaint((fun st -> st.IsPublic || st.IsNestedPublic), m) then taccessPublic else taccessPrivate cpath) + + let nestedTycon = Construct.NewProvidedTycon(resolutionEnvironment, st, + Import.ImportProvidedType cenv.amap m, + isSuppressRelocate, + m=m, cpath=cpath, access=access) + eref.ModuleOrNamespaceType.AddProvidedTypeEntity nestedTycon + + let nestedTyRef = eref.NestedTyconRef nestedTycon + let ilOrigTypeRef = GetOriginalILTypeRefOfProvidedType (st, m) + + // Record the details so we can map System.Type --> TyconRef + st.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, nestedTyRef))), m) + + if isGenerated then + let ilTgtTyRef = nestedTycon.CompiledRepresentationForNamedType + // Record the details so we can map System.Type --> ILTypeRef + st.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtTyRef))), m) + + // Record the details so we can build correct ILTypeDefs during static linking rewriting + if not isSuppressRelocate then + match provAssemStaticLinkInfoOpt with + | Some provAssemStaticLinkInfo -> provAssemStaticLinkInfo.ILTypeMap.[ilOrigTypeRef] <- ilTgtTyRef + | None -> () + + ProviderGeneratedType(ilOrigTypeRef, ilTgtTyRef, doNestedTypes nestedTyRef st) + else + ProviderGeneratedType(ilOrigTypeRef, ilOrigTypeRef, doNestedTypes nestedTyRef st) + + + //System.Diagnostics.Debug.Assert eref.TryDeref.IsSome + + and doNestedTypes (eref: EntityRef) (st: Tainted) = + st.PApplyArray((fun st -> st.GetAllNestedTypes()), "GetAllNestedTypes", m) + |> Array.map (doNestedType eref) + |> Array.toList + + let nested = doNestedTypes tcref theRootTypeWithRemapping + if not isSuppressRelocate then + + let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType + match rootProvAssemStaticLinkInfoOpt with + | Some provAssemStaticLinkInfo -> provAssemStaticLinkInfo.ILTypeMap.[ilOrigRootTypeRef] <- ilTgtRootTyRef + | None -> () + + if not inSig then + cenv.amap.assemblyLoader.RecordGeneratedTypeRoot (ProviderGeneratedType(ilOrigRootTypeRef, ilTgtRootTyRef, nested)) + + with e -> + errorRecovery e rhsType.Range +#endif + + /// Establish any type abbreviations + /// + /// e.g. for + /// type B<'a when 'a: C> = DDD of C + /// and C = B + /// + /// we establish + /// + /// Entity('B) + /// TypeAbbrev = TType_app(Entity('int'), []) + /// + /// and for + /// + /// type C = B + /// + /// we establish + /// TypeAbbrev = TType_app(Entity('B'), []) + /// + /// Note that for + /// type PairOfInts = int * int + /// then after running this phase and checking for cycles, operations + // such as 'isRefTupleTy' will return reliable results, e.g. isRefTupleTy on the + /// TAST type for 'PairOfInts' will report 'true' + // + let private TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations (cenv: cenv) envinner inSig tpenv pass (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) (tycon: Tycon) (attrs: Attribs) = + let m = tycon.Range + let checkCxs = if (pass = SecondPass) then CheckCxs else NoCheckCxs + let firstPass = (pass = FirstPass) + try + let id = tycon.Id + let thisTyconRef = mkLocalTyconRef tycon + + let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs + let hasMeasureableAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureableAttribute attrs + let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner + let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false + + match synTyconRepr with + + // This unfortunate case deals with "type x = A" + // In F# this only defines a new type if A is not in scope + // as a type constructor, or if the form type A = A is used. + // "type x = | A" can always be used instead. + | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) _ -> () + + | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, m) -> + +#if !NO_EXTENSIONTYPING + // Check we have not already decided that this is a generative provided type definition. If we have already done this (i.e. this is the second pass + // for a generative provided type definition, then there is no more work to do). + if (match tycon.entity_tycon_repr with TNoRepr -> true | _ -> false) then + + // Determine if this is a generative type definition. + match TcTyconDefnCore_TryAsGenerateDeclaration cenv envinner tpenv (tycon, rhsType) with + | Some (tcrefForContainer, providedTypeAfterStaticArguments, checkTypeName, args, m) -> + // If this is a generative provided type definition then establish the provided type and all its nested types. Only do this on the first pass. + if firstPass then + TcTyconDefnCore_Phase1C_EstablishDeclarationForGeneratedSetOfTypes cenv inSig (tycon, rhsType, tcrefForContainer, providedTypeAfterStaticArguments, checkTypeName, args, m) + | None -> +#else + ignore inSig +#endif + + // This case deals with ordinary type and measure abbreviations + if not hasMeasureableAttr then + let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type + let ty, _ = TcTypeOrMeasureAndRecover (Some kind) cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner tpenv rhsType + + if not firstPass then + let ftyvs = freeInTypeLeftToRight cenv.g false ty + let typars = tycon.Typars m + if ftyvs.Length <> typars.Length then + errorR(Deprecated(FSComp.SR.tcTypeAbbreviationHasTypeParametersMissingOnType(), tycon.Range)) + + if firstPass then + tycon.SetTypeAbbrev (Some ty) + + | _ -> () + + with e -> + errorRecovery e m + + // Third phase: check and publish the super types. Run twice, once before constraints are established + // and once after + let private TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig pass (envMutRec, mutRecDefns: MutRecShape<_ * (Tycon * (Attribs * _)) option, _, _> list) = + let checkCxs = if (pass = SecondPass) then CheckCxs else NoCheckCxs + let firstPass = (pass = FirstPass) + + // Publish the immediately declared interfaces. + let tyconWithImplementsL = + (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envinner (origInfo, tyconAndAttrsOpt) -> + match origInfo, tyconAndAttrsOpt with + | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> + let (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, explicitImplements, _, _, _)) = typeDefCore + let m = tycon.Range + let tcref = mkLocalTyconRef tycon + let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner + let envinner = MakeInnerEnvForTyconRef envinner tcref false + + let implementedTys, _ = List.mapFold (mapFoldFst (TcTypeAndRecover cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner)) tpenv explicitImplements + + if firstPass then + tycon.entity_attribs <- attrs + + let implementedTys, inheritedTys = + match synTyconRepr with + | SynTypeDefnSimpleRepr.Exception _ -> [], [] + | SynTypeDefnSimpleRepr.General (kind, inherits, slotsigs, fields, isConcrete, _, _, m) -> + let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) + + let inherits = inherits |> List.map (fun (ty, m, _) -> (ty, m)) + let inheritedTys = fst (List.mapFold (mapFoldFst (TcTypeAndRecover cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner)) tpenv inherits) + let implementedTys, inheritedTys = + match kind with + | SynTypeDefnKind.Interface -> + explicitImplements |> List.iter (fun (_, m) -> errorR(Error(FSComp.SR.tcInterfacesShouldUseInheritNotInterface(), m))) + (implementedTys @ inheritedTys), [] + | _ -> implementedTys, inheritedTys + implementedTys, inheritedTys + | SynTypeDefnSimpleRepr.Enum _ | SynTypeDefnSimpleRepr.None _ | SynTypeDefnSimpleRepr.TypeAbbrev _ + + | SynTypeDefnSimpleRepr.Union _ | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ | SynTypeDefnSimpleRepr.Record _ -> + // REVIEW: we could do the IComparable/IStructuralHash interface analysis here. + // This would let the type satisfy more recursive IComparable/IStructuralHash constraints + implementedTys, [] + + for implementedTy, m in implementedTys do + if firstPass && isErasedType cenv.g implementedTy then + errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) + + // Publish interfaces, but only on the first pass, to avoid a duplicate interface check + if firstPass then + implementedTys |> List.iter (fun (ty, m) -> PublishInterface cenv envinner.DisplayEnv tcref m false ty) + + Some (attrs, inheritedTys, synTyconRepr, tycon) + | _ -> None) + + // Publish the attributes and supertype + tyconWithImplementsL |> MutRecShapes.iterTycons (Option.iter (fun (attrs, inheritedTys, synTyconRepr, tycon) -> + let m = tycon.Range + try + let super = + match synTyconRepr with + | SynTypeDefnSimpleRepr.Exception _ -> Some cenv.g.exn_ty + | SynTypeDefnSimpleRepr.None _ -> None + | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None + | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None + | SynTypeDefnSimpleRepr.Union _ + | SynTypeDefnSimpleRepr.Record _ -> + if tycon.IsStructRecordOrUnionTycon then Some(cenv.g.system_Value_ty) + else None + | SynTypeDefnSimpleRepr.General (kind, _, slotsigs, fields, isConcrete, _, _, _) -> + let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) + + match inheritedTys with + | [] -> + match kind with + | SynTypeDefnKind.Struct -> Some(cenv.g.system_Value_ty) + | SynTypeDefnKind.Delegate _ -> Some(cenv.g.system_MulticastDelegate_ty ) + | SynTypeDefnKind.Opaque | SynTypeDefnKind.Class | SynTypeDefnKind.Interface -> None + | _ -> error(InternalError("should have inferred tycon kind", m)) + + | [(ty, m)] -> + if not firstPass && not (match kind with SynTypeDefnKind.Class -> true | _ -> false) then + errorR (Error(FSComp.SR.tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes(), m)) + CheckSuperType cenv ty m + if isTyparTy cenv.g ty then + if firstPass then + errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), m)) + Some cenv.g.obj_ty // a "super" that is a variable type causes grief later + else + Some ty + | _ -> + error(Error(FSComp.SR.tcTypesCannotInheritFromMultipleConcreteTypes(), m)) + + | SynTypeDefnSimpleRepr.Enum _ -> + Some(cenv.g.system_Enum_ty) + + // Allow super type to be a function type but convert back to FSharpFunc to make sure it has metadata + // (We don't apply the same rule to tuple types, i.e. no F#-declared inheritors of those are permitted) + let super = + super |> Option.map (fun ty -> + if isFunTy cenv.g ty then + let a,b = destFunTy cenv.g ty + mkAppTy cenv.g.fastFunc_tcr [a; b] + else ty) + + // Publish the super type + tycon.TypeContents.tcaug_super <- super + + with e -> errorRecovery e m)) + + /// Establish the fields, dispatch slots and union cases of a type + let private TcTyconDefnCore_Phase1G_EstablishRepresentation (cenv: cenv) envinner tpenv inSig (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) (tycon: Tycon) (attrs: Attribs) = + let g = cenv.g + let m = tycon.Range + try + let id = tycon.Id + let thisTyconRef = mkLocalTyconRef tycon + let innerParent = Parent thisTyconRef + let thisTyInst, thisTy = generalizeTyconRef thisTyconRef + + let hasAbstractAttr = HasFSharpAttribute g g.attrib_AbstractClassAttribute attrs + let hasSealedAttr = + // The special case is needed for 'unit' because the 'Sealed' attribute is not yet available when this type is defined. + if g.compilingFslib && id.idText = "Unit" then + Some true + else + TryFindFSharpBoolAttribute g g.attrib_SealedAttribute attrs + let hasMeasureAttr = HasFSharpAttribute g g.attrib_MeasureAttribute attrs + + // REVIEW: for hasMeasureableAttr we need to be stricter about checking these + // are only used on exactly the right kinds of type definitions and not in conjunction with other attributes. + let hasMeasureableAttr = HasFSharpAttribute g g.attrib_MeasureableAttribute attrs + let hasCLIMutable = HasFSharpAttribute g g.attrib_CLIMutableAttribute attrs + + let structLayoutAttr = TryFindFSharpInt32Attribute g g.attrib_StructLayoutAttribute attrs + let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute g g.attrib_AllowNullLiteralAttribute attrs = Some true + + if hasAbstractAttr then + tycon.TypeContents.tcaug_abstract <- true + + tycon.entity_attribs <- attrs + let noAbstractClassAttributeCheck() = + if hasAbstractAttr then errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) + + let noAllowNullLiteralAttributeCheck() = + if hasAllowNullLiteralAttr then errorR (Error(FSComp.SR.tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute(), m)) + + + let allowNullLiteralAttributeCheck() = + if hasAllowNullLiteralAttr then + tycon.TypeContents.tcaug_super |> Option.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) + tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) + + + let structLayoutAttributeCheck allowed = + let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit + match structLayoutAttr with + | Some kind -> + if allowed then + if kind = explicitKind then + warning(PossibleUnverifiableCode m) + elif List.isEmpty (thisTyconRef.Typars m) then + errorR (Error(FSComp.SR.tcOnlyStructsCanHaveStructLayout(), m)) + else + errorR (Error(FSComp.SR.tcGenericTypesCannotHaveStructLayout(), m)) + | None -> () + + let hiddenReprChecks hasRepr = + structLayoutAttributeCheck false + if hasSealedAttr = Some false || (hasRepr && hasSealedAttr <> Some true && not (id.idText = "Unit" && g.compilingFslib) ) then + errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) + if hasAbstractAttr then + errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) + + let noMeasureAttributeCheck() = + if hasMeasureAttr then errorR (Error(FSComp.SR.tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure(), m)) + + let noCLIMutableAttributeCheck() = + if hasCLIMutable then errorR (Error(FSComp.SR.tcThisTypeMayNotHaveACLIMutableAttribute(), m)) + + let noSealedAttributeCheck k = + if hasSealedAttr = Some true then errorR (Error(k(), m)) + + let noFieldsCheck(fields': RecdField list) = + match fields' with + | rf :: _ -> errorR (Error(FSComp.SR.tcInterfaceTypesAndDelegatesCannotContainFields(), rf.Range)) + | _ -> () + + + let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner + let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false + + + // Notify the Language Service about field names in record/class declaration + let ad = envinner.AccessRights + let writeFakeRecordFieldsToSink (fields: RecdField list) = + let nenv = envinner.NameEnv + // Record fields should be visible from IntelliSense, so add fake names for them (similarly to "let a = ..") + for fspec in fields do + if not fspec.IsCompilerGenerated then + let info = RecdFieldInfo(thisTyInst, thisTyconRef.MakeNestedRecdFieldRef fspec) + let nenv' = AddFakeNameToNameEnv fspec.LogicalName nenv (Item.RecdField info) + // Name resolution gives better info for tooltips + let item = Item.RecdField(FreshenRecdFieldRef cenv.nameResolver m (thisTyconRef.MakeNestedRecdFieldRef fspec)) + CallNameResolutionSink cenv.tcSink (fspec.Range, nenv, item, emptyTyparInst, ItemOccurence.Binding, ad) + // Environment is needed for completions + CallEnvSink cenv.tcSink (fspec.Range, nenv', ad) + + // Notify the Language Service about constructors in discriminated union declaration + let writeFakeUnionCtorsToSink (unionCases: UnionCase list) = + let nenv = envinner.NameEnv + // Constructors should be visible from IntelliSense, so add fake names for them + for unionCase in unionCases do + let info = UnionCaseInfo(thisTyInst, mkUnionCaseRef thisTyconRef unionCase.Id.idText) + let nenv' = AddFakeNameToNameEnv unionCase.Id.idText nenv (Item.UnionCase(info, false)) + // Report to both - as in previous function + let item = Item.UnionCase(info, false) + CallNameResolutionSink cenv.tcSink (unionCase.Range, nenv, item, emptyTyparInst, ItemOccurence.Binding, ad) + CallEnvSink cenv.tcSink (unionCase.Id.idRange, nenv', ad) + + let typeRepr, baseValOpt, safeInitInfo = + match synTyconRepr with + + | SynTypeDefnSimpleRepr.Exception synExnDefnRepr -> + let parent = Parent (mkLocalTyconRef tycon) + TcExceptionDeclarations.TcExnDefnCore_Phase1G_EstablishRepresentation cenv envinner parent tycon synExnDefnRepr |> ignore + TNoRepr, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.None _ -> + hiddenReprChecks false + noAllowNullLiteralAttributeCheck() + if hasMeasureAttr then + let repr = TFSharpObjectRepr { fsobjmodel_kind=TFSharpClass + fsobjmodel_vslots=[] + fsobjmodel_rfields= Construct.MakeRecdFieldsTable [] } + repr, None, NoSafeInitInfo + else + TNoRepr, None, NoSafeInitInfo + + // This unfortunate case deals with "type x = A" + // In F# this only defines a new type if A is not in scope + // as a type constructor, or if the form type A = A is used. + // "type x = | A" can always be used instead. + | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (unionCaseName, _) -> + + structLayoutAttributeCheck false + noAllowNullLiteralAttributeCheck() + TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName + let unionCase = Construct.NewUnionCase unionCaseName [] thisTy [] XmlDoc.Empty tycon.Accessibility + writeFakeUnionCtorsToSink [ unionCase ] + Construct.MakeUnionRepr [ unionCase ], None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ErrorRecovery, _rhsType, _) -> + TNoRepr, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, _) -> + if hasSealedAttr = Some true then + errorR (Error(FSComp.SR.tcAbbreviatedTypesCannotBeSealed(), m)) + noAbstractClassAttributeCheck() + noAllowNullLiteralAttributeCheck() + if hasMeasureableAttr then + let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type + let theTypeAbbrev, _ = TcTypeOrMeasureAndRecover (Some kind) cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv rhsType + + TMeasureableRepr theTypeAbbrev, None, NoSafeInitInfo + // If we already computed a representation, e.g. for a generative type definition, then don't change it here. + elif (match tycon.TypeReprInfo with TNoRepr -> false | _ -> true) then + tycon.TypeReprInfo, None, NoSafeInitInfo + else + TNoRepr, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.Union (_, unionCases, _) -> + noCLIMutableAttributeCheck() + noMeasureAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedDU + noAbstractClassAttributeCheck() + noAllowNullLiteralAttributeCheck() + structLayoutAttributeCheck false + let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst tpenv unionCases + + if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then + let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft.LogicalName ] + if fieldNames |> List.distinct |> List.length <> fieldNames.Length then + errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) + + writeFakeUnionCtorsToSink unionCases + let repr = Construct.MakeUnionRepr unionCases + repr, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.Record (_, fields, _) -> + noMeasureAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedRecord + noAbstractClassAttributeCheck() + noAllowNullLiteralAttributeCheck() + structLayoutAttributeCheck true // these are allowed for records + let recdFields = TcRecdUnionAndEnumDeclarations.TcNamedFieldDecls cenv envinner innerParent false tpenv fields + recdFields |> CheckDuplicates (fun f -> f.Id) "field" |> ignore + writeFakeRecordFieldsToSink recdFields + let repr = TFSharpRecdRepr (Construct.MakeRecdFieldsTable recdFields) + repr, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (s, _) -> + let s = (s :?> ILType) + noCLIMutableAttributeCheck() + noMeasureAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedAssemblyCode + noAllowNullLiteralAttributeCheck() + structLayoutAttributeCheck false + noAbstractClassAttributeCheck() + TAsmRepr s, None, NoSafeInitInfo + + | SynTypeDefnSimpleRepr.General (kind, inherits, slotsigs, fields, isConcrete, isIncrClass, implicitCtorSynPats, _) -> + let userFields = TcRecdUnionAndEnumDeclarations.TcNamedFieldDecls cenv envinner innerParent isIncrClass tpenv fields + let implicitStructFields = + [ // For structs with an implicit ctor, determine the fields immediately based on the arguments + match implicitCtorSynPats with + | None -> + () + | Some spats -> + if tycon.IsFSharpStructOrEnumTycon then + let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true CheckCxs envinner tpenv spats + for arg in ctorArgNames do + let ty = names.[arg].Type + let id = names.[arg].Ident + let taccess = TAccess [envinner.eAccessPath] + yield Construct.NewRecdField false None id false ty false false [] [] XmlDoc.Empty taccess true ] + + (userFields @ implicitStructFields) |> CheckDuplicates (fun f -> f.Id) "field" |> ignore + writeFakeRecordFieldsToSink userFields + + let superTy = tycon.TypeContents.tcaug_super + let containerInfo = TyconContainerInfo(innerParent, thisTyconRef, thisTyconRef.Typars m, NoSafeInitInfo) + let kind = InferTyconKind g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) + match kind with + | SynTypeDefnKind.Opaque -> + hiddenReprChecks true + noAllowNullLiteralAttributeCheck() + TNoRepr, None, NoSafeInitInfo + | _ -> + + // Note: for a mutually recursive set we can't check this condition + // until "isSealedTy" and "isClassTy" give reliable results. + superTy |> Option.iter (fun ty -> + let m = match inherits with | [] -> m | (_, m, _) :: _ -> m + if isSealedTy g ty then + errorR(Error(FSComp.SR.tcCannotInheritFromSealedType(), m)) + elif not (isClassTy g ty) then + errorR(Error(FSComp.SR.tcCannotInheritFromInterfaceType(), m))) + + let kind = + match kind with + | SynTypeDefnKind.Struct -> + noCLIMutableAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedStruct + noAbstractClassAttributeCheck() + noAllowNullLiteralAttributeCheck() + if not (isNil slotsigs) then + errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(), m)) + structLayoutAttributeCheck true + + TFSharpStruct + | SynTypeDefnKind.Interface -> + if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) + noCLIMutableAttributeCheck() + structLayoutAttributeCheck false + noAbstractClassAttributeCheck() + allowNullLiteralAttributeCheck() + noFieldsCheck userFields + TFSharpInterface + | SynTypeDefnKind.Class -> + noCLIMutableAttributeCheck() + structLayoutAttributeCheck(not isIncrClass) + allowNullLiteralAttributeCheck() + TFSharpClass + | SynTypeDefnKind.Delegate (ty, arity) -> + noCLIMutableAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedDelegate + structLayoutAttributeCheck false + noAllowNullLiteralAttributeCheck() + noAbstractClassAttributeCheck() + noFieldsCheck userFields + let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv ty + let _, _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv envinner) |> TranslatePartialArity []) 0 ty' m + if curriedArgInfos.Length < 1 then error(Error(FSComp.SR.tcInvalidDelegateSpecification(), m)) + if curriedArgInfos.Length > 1 then error(Error(FSComp.SR.tcDelegatesCannotBeCurried(), m)) + let ttps = thisTyconRef.Typars m + let fparams = curriedArgInfos.Head |> List.map MakeSlotParam + TFSharpDelegate (MakeSlotSig("Invoke", thisTy, ttps, [], [fparams], returnTy)) + | _ -> + error(InternalError("should have inferred tycon kind", m)) + + let baseIdOpt = + match synTyconRepr with + | SynTypeDefnSimpleRepr.None _ -> None + | SynTypeDefnSimpleRepr.Exception _ -> None + | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None + | SynTypeDefnSimpleRepr.Union _ -> None + | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None + | SynTypeDefnSimpleRepr.Record _ -> None + | SynTypeDefnSimpleRepr.Enum _ -> None + | SynTypeDefnSimpleRepr.General (_, inherits, _, _, _, _, _, _) -> + match inherits with + | [] -> None + | (_, m, baseIdOpt) :: _ -> + match baseIdOpt with + | None -> Some(ident("base", m)) + | Some id -> Some id + + let abstractSlots = + [ for valSpfn, memberFlags in slotsigs do + + let (SynValSig(_, _, _, _, _valSynData, _, _, _, _, _, m)) = valSpfn + + CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m + + let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, valSpfn)) + // Multiple slots may be returned, e.g. for + // abstract P: int with get, set + + for slot in slots do + yield mkLocalValRef slot ] + + let baseValOpt = MakeAndPublishBaseVal cenv envinner baseIdOpt (superOfTycon g tycon) + let safeInitInfo = ComputeInstanceSafeInitInfo cenv envinner thisTyconRef.Range thisTy + let safeInitFields = match safeInitInfo with SafeInitField (_, fld) -> [fld] | NoSafeInitInfo -> [] + + let repr = + TFSharpObjectRepr + { fsobjmodel_kind = kind + fsobjmodel_vslots = abstractSlots + fsobjmodel_rfields = Construct.MakeRecdFieldsTable (userFields @ implicitStructFields @ safeInitFields) } + repr, baseValOpt, safeInitInfo + + | SynTypeDefnSimpleRepr.Enum (decls, m) -> + let fieldTy, fields' = TcRecdUnionAndEnumDeclarations.TcEnumDecls cenv envinner innerParent thisTy decls + let kind = TFSharpEnum + structLayoutAttributeCheck false + noCLIMutableAttributeCheck() + noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedEnum + noAllowNullLiteralAttributeCheck() + let vid = ident("value__", m) + let vfld = Construct.NewRecdField false None vid false fieldTy false false [] [] XmlDoc.Empty taccessPublic true + + let legitEnumTypes = [ g.int32_ty; g.int16_ty; g.sbyte_ty; g.int64_ty; g.char_ty; g.bool_ty; g.uint32_ty; g.uint16_ty; g.byte_ty; g.uint64_ty ] + if not (ListSet.contains (typeEquiv g) fieldTy legitEnumTypes) then + errorR(Error(FSComp.SR.tcInvalidTypeForLiteralEnumeration(), m)) + + writeFakeRecordFieldsToSink fields' + let repr = + TFSharpObjectRepr + { fsobjmodel_kind=kind + fsobjmodel_vslots=[] + fsobjmodel_rfields= Construct.MakeRecdFieldsTable (vfld :: fields') } + repr, None, NoSafeInitInfo + + tycon.entity_tycon_repr <- typeRepr + // We check this just after establishing the representation + if TyconHasUseNullAsTrueValueAttribute g tycon && not (CanHaveUseNullAsTrueValueAttribute g tycon) then + errorR(Error(FSComp.SR.tcInvalidUseNullAsTrueValue(), m)) + + // validate ConditionalAttribute, should it be applied (it's only valid on a type if the type is an attribute type) + match attrs |> List.tryFind (IsMatchingFSharpAttribute g g.attrib_ConditionalAttribute) with + | Some _ -> + if not(ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy g.tcref_System_Attribute [])) g cenv.amap m AllowMultiIntfInstantiations.Yes thisTy) then + errorR(Error(FSComp.SR.tcConditionalAttributeUsage(), m)) + | _ -> () + + (baseValOpt, safeInitInfo) + with e -> + errorRecovery e m + None, NoSafeInitInfo + + /// Check that a set of type definitions is free of cycles in abbreviations + let private TcTyconDefnCore_CheckForCyclicAbbreviations tycons = + + let edgesFrom (tycon: Tycon) = + + let rec accInAbbrevType ty acc = + match stripTyparEqns ty with + | TType_anon (_,l) + | TType_tuple (_, l) -> accInAbbrevTypes l acc + | TType_ucase (UnionCaseRef(tc, _), tinst) + | TType_app (tc, tinst) -> + let tycon2 = tc.Deref + let acc = accInAbbrevTypes tinst acc + // Record immediate recursive references + if ListSet.contains (===) tycon2 tycons then + (tycon, tycon2) :: acc + // Expand the representation of abbreviations + elif tc.IsTypeAbbrev then + accInAbbrevType (reduceTyconRefAbbrev tc tinst) acc + // Otherwise H - explore the instantiation. + else + acc + + | TType_fun (d, r) -> + accInAbbrevType d (accInAbbrevType r acc) + + | TType_var _ -> acc + + | TType_forall (_, r) -> accInAbbrevType r acc + + | TType_measure ms -> accInMeasure ms acc + + and accInMeasure ms acc = + match stripUnitEqns ms with + | Measure.Con tc when ListSet.contains (===) tc.Deref tycons -> + (tycon, tc.Deref) :: acc + | Measure.Con tc when tc.IsTypeAbbrev -> + accInMeasure (reduceTyconRefAbbrevMeasureable tc) acc + | Measure.Prod (ms1, ms2) -> accInMeasure ms1 (accInMeasure ms2 acc) + | Measure.Inv ms -> accInMeasure ms acc + | _ -> acc + + and accInAbbrevTypes tys acc = + List.foldBack accInAbbrevType tys acc + + match tycon.TypeAbbrev with + | None -> [] + | Some ty -> accInAbbrevType ty [] + + let edges = List.collect edgesFrom tycons + let graph = Graph ((fun tc -> tc.Stamp), tycons, edges) + graph.IterateCycles (fun path -> + let tycon = path.Head + // The thing is cyclic. Set the abbreviation and representation to be "None" to stop later VS crashes + tycon.SetTypeAbbrev None + tycon.entity_tycon_repr <- TNoRepr + errorR(Error(FSComp.SR.tcTypeDefinitionIsCyclic(), tycon.Range))) + + + /// Check that a set of type definitions is free of inheritance cycles + let TcTyconDefnCore_CheckForCyclicStructsAndInheritance (cenv: cenv) tycons = + let g = cenv.g + // Overview: + // Given several tycons now being defined (the "initial" tycons). + // Look for cycles in inheritance and struct-field-containment. + // + // The graph is on the (initial) type constructors (not types (e.g. tycon instantiations)). + // Closing under edges: + // 1. (tycon, superTycon) -- tycon (initial) to the tycon of its super type. + // 2. (tycon, interfaceTycon) -- tycon (initial) to the tycon of an interface it implements. + // 3. (tycon, T) -- tycon (initial) is a struct with a field (static or instance) that would store a T<_> + // where storing T<_> means is T<_> + // or is a struct with an instance field that stores T<_>. + // The implementation only stores edges between (initial) tycons. + // + // The special case "S<'a> static field on S<'a>" is allowed, so no #3 edge is collected for this. + // Only static fields for current tycons need to be followed. Previous tycons are assumed (previously checked) OK. + // + // BEGIN: EARLIER COMMENT + // Of course structs are not allowed to contain instance fields of their own type: + // type S = struct { field x: S } + // + // In addition, see bug 3429. In the .NET IL structs are allowed to contain + // static fields of their exact generic type, e.g. + // type S = struct { static field x: S } + // type S = struct { static field x: S } + // but not + // type S = struct { static field x: S } + // type S = struct { static field x: S } + // etc. + // + // Ideally structs would allow static fields of any type. However + // this is a restriction and exemption that originally stems from + // the way the Microsoft desktop CLR class loader works. + // END: EARLIER COMMENT + + // edgesFrom tycon collects (tycon, tycon2) edges, for edges as described above. + let edgesFrom (tycon: Tycon) = + // Record edge (tycon, tycon2), only when tycon2 is an "initial" tycon. + let insertEdgeToTycon tycon2 acc = + if ListSet.contains (===) tycon2 tycons && // note: only add if tycon2 is initial + not (List.exists (fun (tc, tc2) -> tc === tycon && tc2 === tycon2) acc) // note: only add if (tycon, tycon2) not already an edge + then + (tycon, tycon2) :: acc + else acc // note: all edges added are (tycon, _) + let insertEdgeToType ty acc = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + insertEdgeToTycon tcref.Deref acc + | _ -> + acc + + // collect edges from an a struct field (which is struct-contained in tycon) + let rec accStructField (structTycon: Tycon) structTyInst (fspec: RecdField) (doneTypes, acc) = + let fieldTy = actualTyOfRecdFieldForTycon structTycon structTyInst fspec + accStructFieldType structTycon structTyInst fspec fieldTy (doneTypes, acc) + + // collect edges from an a struct field (given the field type, which may be expanded if it is a type abbreviation) + and accStructFieldType structTycon structTyInst fspec fieldTy (doneTypes, acc) = + let fieldTy = stripTyparEqns fieldTy + match fieldTy with + | TType_tuple (_isStruct , tinst2) when isStructTupleTy cenv.g fieldTy -> + // The field is a struct tuple. Check each element of the tuple. + // This case was added to resolve issues/3916 + ((doneTypes, acc), tinst2) + ||> List.fold (fun acc' x -> accStructFieldType structTycon structTyInst fspec x acc') + | TType_app (tcref2 , tinst2) when tcref2.IsStructOrEnumTycon -> + // The field is a struct. + // An edge (tycon, tycon2) should be recorded, unless it is the "static self-typed field" case. + let tycon2 = tcref2.Deref + let specialCaseStaticField = + // The special case of "static field S<'a> in struct S<'a>" is permitted. (so no (S, S) edge to be collected). + fspec.IsStatic && + (structTycon === tycon2) && + (structTyInst, tinst2) ||> List.lengthsEqAndForall2 (fun ty1 ty2 -> + match tryDestTyparTy g ty1 with + | ValueSome destTypar1 -> + match tryDestTyparTy g ty2 with + | ValueSome destTypar2 -> typarEq destTypar1 destTypar2 + | _ -> false + | _ -> false) + if specialCaseStaticField then + doneTypes, acc // no edge collected, no recursion. + else + let acc = insertEdgeToTycon tycon2 acc // collect edge (tycon, tycon2), if tycon2 is initial. + accStructInstanceFields fieldTy tycon2 tinst2 (doneTypes, acc) // recurse through struct field looking for more edges + | TType_app (tcref2, tinst2) when tcref2.IsTypeAbbrev -> + // The field is a type abbreviation. Expand and repeat. + accStructFieldType structTycon structTyInst fspec (reduceTyconRefAbbrev tcref2 tinst2) (doneTypes, acc) + | _ -> + doneTypes, acc + + // collect edges from the fields of a given struct type. + and accStructFields includeStaticFields ty (structTycon: Tycon) tinst (doneTypes, acc) = + if List.exists (typeEquiv g ty) doneTypes then + // This type (type instance) has been seen before, so no need to collect the same edges again (and avoid loops!) + doneTypes, acc + else + // Only collect once from each type instance. + let doneTypes = ty :: doneTypes + let fspecs = + if structTycon.IsUnionTycon then + [ for uc in structTycon.UnionCasesArray do + for c in uc.FieldTable.FieldsByIndex do + yield c] + else + structTycon.AllFieldsAsList + let fspecs = fspecs |> List.filter (fun fspec -> includeStaticFields || not fspec.IsStatic) + let doneTypes, acc = List.foldBack (accStructField structTycon tinst) fspecs (doneTypes, acc) + doneTypes, acc + and accStructInstanceFields ty structTycon tinst (doneTypes, acc) = accStructFields false ty structTycon tinst (doneTypes, acc) + and accStructAllFields ty (structTycon: Tycon) tinst (doneTypes, acc) = accStructFields true ty structTycon tinst (doneTypes, acc) + + let acc = [] + let acc = + if tycon.IsStructOrEnumTycon then + let tinst, ty = generalizeTyconRef (mkLocalTyconRef tycon) + let _, acc = accStructAllFields ty tycon tinst ([], acc) + acc + else + acc + + let acc = + // Note: only the nominal type counts + let super = superOfTycon g tycon + insertEdgeToType super acc + let acc = + // Note: only the nominal type counts + List.foldBack insertEdgeToType tycon.ImmediateInterfaceTypesOfFSharpTycon acc + acc + let edges = (List.collect edgesFrom tycons) + let graph = Graph ((fun tc -> tc.Stamp), tycons, edges) + graph.IterateCycles (fun path -> + let tycon = path.Head + // The thing is cyclic. Set the abbreviation and representation to be "None" to stop later VS crashes + tycon.SetTypeAbbrev None + tycon.entity_tycon_repr <- TNoRepr + errorR(Error(FSComp.SR.tcTypeDefinitionIsCyclicThroughInheritance(), tycon.Range))) + + + // Interlude between Phase1D and Phase1E - Check and publish the explicit constraints. + let TcMutRecDefns_CheckExplicitConstraints cenv tpenv m checkCxs envMutRecPrelim withEnvs = + (envMutRecPrelim, withEnvs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> + match origInfo, tyconOpt with + | (typeDefCore, _, _), Some (tycon: Tycon) -> + let (MutRecDefnsPhase1DataForTycon(synTyconInfo, _, _, _, _, _)) = typeDefCore + let (SynComponentInfo(_, TyparsAndConstraints (_, cs1), cs2, _, _, _, _, _)) = synTyconInfo + let synTyconConstraints = cs1 @ cs2 + let envForTycon = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envForDecls + let thisTyconRef = mkLocalTyconRef tycon + let envForTycon = MakeInnerEnvForTyconRef envForTycon thisTyconRef false + try TcTyparConstraints cenv NoNewTypars checkCxs ItemOccurence.UseInType envForTycon tpenv synTyconConstraints |> ignore + with e -> errorRecovery e m + | _ -> ()) + + + let TcMutRecDefns_Phase1 mkLetInfo (cenv: cenv) envInitial parent typeNames inSig tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecShapes) = + // Phase1A - build Entity for type definitions, exception definitions and module definitions. + // Also for abbreviations of any of these. Augmentations are skipped in this phase. + let withEntities = + mutRecDefns + |> MutRecShapes.mapWithParent + (parent, typeNames, envInitial) + // Build the initial entity for each module definition + (fun (innerParent, typeNames, envForDecls) compInfo decls -> + TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent typeNames compInfo decls) + + // Build the initial Tycon for each type definition + (fun (innerParent, _, envForDecls) (typeDefCore, tyconMemberInfo) -> + let (MutRecDefnsPhase1DataForTycon(_, _, _, _, _, isAtOriginalTyconDefn)) = typeDefCore + let tyconOpt = + if isAtOriginalTyconDefn then + Some (TcTyconDefnCore_Phase1A_BuildInitialTycon cenv envForDecls innerParent typeDefCore) + else + None + (typeDefCore, tyconMemberInfo, innerParent), tyconOpt) + + // Bundle up the data for each 'val', 'member' or 'let' definition (just package up the data, no processing yet) + (fun (innerParent, _, _) synBinds -> + let containerInfo = ModuleOrNamespaceContainerInfo(match innerParent with Parent p -> p | _ -> failwith "unreachable") + mkLetInfo containerInfo synBinds) + + // Phase1AB - Publish modules + let envTmp, withEnvs = + (envInitial, withEntities) ||> MutRecShapes.computeEnvs + (fun envAbove (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec)) -> + PublishModuleDefn cenv envAbove mspec + MakeInnerEnvWithAcc true envAbove mspec.Id mtypeAcc mspec.ModuleOrNamespaceType.ModuleOrNamespaceKind) + (fun envAbove _ -> envAbove) + + // Updates the types of the modules to contain the contents so far, which now includes the nested modules and types + MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo withEnvs + + // Publish tycons + (envTmp, withEnvs) ||> MutRecShapes.iterTyconsWithEnv + (fun envAbove (_, tyconOpt) -> + tyconOpt |> Option.iter (fun tycon -> + // recheck these in case type is a duplicate in a mutually recursive set + CheckForDuplicateConcreteType envAbove tycon.LogicalName tycon.Range + PublishTypeDefn cenv envAbove tycon)) + + // Updates the types of the modules to contain the contents so far + MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo withEnvs + + // Phase1AB - Compute the active environments within each nested module. + // + // Add the types to the environment. This does not add the fields and union cases (because we haven't established them yet). + // We re-add them to the original environment later on. We don't report them to the Language Service yet as we don't know if + // they are well-formed (e.g. free of abbreviation cycles) + let envMutRecPrelim, withEnvs = (envInitial, withEntities) ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs snd (fun _ -> []) cenv false scopem m + + // Phase 1B. Establish the kind of each type constructor + // Here we run InferTyconKind and record partial information about the kind of the type constructor. + // This means TyconFSharpObjModelKind is set, which means isSealedTy, isInterfaceTy etc. give accurate results. + let withAttrs = + (envMutRecPrelim, withEnvs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> + let res = + match origInfo, tyconOpt with + | (typeDefCore, _, _), Some tycon -> Some (tycon, TcTyconDefnCore_Phase1B_EstablishBasicKind cenv inSig envForDecls typeDefCore tycon) + | _ -> None + origInfo, res) + + // Phase 1C. Establish the abbreviations (no constraint checking, because constraints not yet established) + (envMutRecPrelim, withAttrs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> + match origInfo, tyconAndAttrsOpt with + | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations cenv envForDecls inSig tpenv FirstPass typeDefCore tycon attrs + | _ -> ()) + + // Check for cyclic abbreviations. If this succeeds we can start reducing abbreviations safely. + let tycons = withEntities |> MutRecShapes.collectTycons |> List.choose snd + + TcTyconDefnCore_CheckForCyclicAbbreviations tycons + + // Phase 1D. Establish the super type and interfaces (no constraint checking, because constraints not yet established) + (envMutRecPrelim, withAttrs) |> TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig FirstPass + + // Interlude between Phase1D and Phase1E - Add the interface and member declarations for + // hash/compare. Because this adds interfaces, this may let constraints + // be satisfied, so we have to do this prior to checking any constraints. + // + // First find all the field types in all the structural types + let tyconsWithStructuralTypes = + (envMutRecPrelim, withEnvs) + ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> + match origInfo, tyconOpt with + | (typeDefCore, _, _), Some tycon -> Some (tycon, GetStructuralElementsOfTyconDefn cenv envForDecls tpenv typeDefCore tycon) + | _ -> None) + |> MutRecShapes.collectTycons + |> List.choose id + + let scSet = TyconConstraintInference.InferSetOfTyconsSupportingComparable cenv envMutRecPrelim.DisplayEnv tyconsWithStructuralTypes + let seSet = TyconConstraintInference.InferSetOfTyconsSupportingEquatable cenv envMutRecPrelim.DisplayEnv tyconsWithStructuralTypes + + (envMutRecPrelim, withEnvs) + ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (_, tyconOpt) -> + tyconOpt |> Option.iter (AddAugmentationDeclarations.AddGenericHashAndComparisonDeclarations cenv envForDecls scSet seSet)) + + TcMutRecDefns_CheckExplicitConstraints cenv tpenv m NoCheckCxs envMutRecPrelim withEnvs + + // No inferred constraints allowed on declared typars + (envMutRecPrelim, withEnvs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (_, tyconOpt) -> + tyconOpt |> Option.iter (fun tycon -> tycon.Typars m |> List.iter (SetTyparRigid envForDecls.DisplayEnv m))) + + // Phase1E. OK, now recheck the abbreviations, super/interface and explicit constraints types (this time checking constraints) + (envMutRecPrelim, withAttrs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> + match origInfo, tyconAndAttrsOpt with + | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations cenv envForDecls inSig tpenv SecondPass typeDefCore tycon attrs + | _ -> ()) + + // Phase1F. Establish inheritance hierarchy + (envMutRecPrelim, withAttrs) |> TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig SecondPass + + TcMutRecDefns_CheckExplicitConstraints cenv tpenv m CheckCxs envMutRecPrelim withEnvs + + // Add exception definitions to the environments, which are used for checking exception abbreviations in representations + let envMutRecPrelim, withAttrs = + (envMutRecPrelim, withAttrs) + ||> MutRecShapes.extendEnvs (fun envForDecls decls -> + let tycons = decls |> List.choose (function MutRecShape.Tycon (_, Some (tycon, _)) -> Some tycon | _ -> None) + let exns = tycons |> List.filter (fun tycon -> tycon.IsExceptionDecl) + let envForDecls = (envForDecls, exns) ||> List.fold (AddLocalExnDefnAndReport cenv.tcSink scopem) + envForDecls) + + // Phase1G. Establish inheritance hierarchy + // Now all the type parameters, abbreviations, constraints and kind information is established. + // Now do the representations. Each baseValOpt is a residue from the representation which is potentially available when + // checking the members. + let withBaseValsAndSafeInitInfos = + (envMutRecPrelim, withAttrs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> + let info = + match origInfo, tyconAndAttrsOpt with + | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1G_EstablishRepresentation cenv envForDecls tpenv inSig typeDefCore tycon attrs + | _ -> None, NoSafeInitInfo + let tyconOpt, fixupFinalAttrs = + match tyconAndAttrsOpt with + | None -> None, (fun () -> ()) + | Some (tycon, (_prelimAttrs, getFinalAttrs)) -> Some tycon, (fun () -> tycon.entity_attribs <- getFinalAttrs()) + + (origInfo, tyconOpt, fixupFinalAttrs, info)) + + // Now check for cyclic structs and inheritance. It's possible these should be checked as separate conditions. + // REVIEW: checking for cyclic inheritance is happening too late. See note above. + TcTyconDefnCore_CheckForCyclicStructsAndInheritance cenv tycons + + + (tycons, envMutRecPrelim, withBaseValsAndSafeInitInfos) + + +/// Bind declarations in implementation and signature files +module TcDeclarations = + + /// Given a type definition, compute whether its members form an extension of an existing type, and if so if it is an + /// intrinsic or extrinsic extension + let private ComputeTyconDeclKind (cenv: cenv) (envForDecls: TcEnv) tyconOpt isAtOriginalTyconDefn inSig m (synTypars: SynTyparDecl list) synTyparCxs longPath = + let g = cenv.g + let ad = envForDecls.AccessRights + + let tcref = + match tyconOpt with + | Some tycon when isAtOriginalTyconDefn -> + + // This records a name resolution of the type at the location + let resInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs synTypars.Length + ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Binding OpenQualified envForDecls.NameEnv ad longPath resInfo PermitDirectReferenceToGeneratedType.No + |> ignore + + mkLocalTyconRef tycon + + | _ -> + let resInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs synTypars.Length + let _, tcref = + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Binding OpenQualified envForDecls.NameEnv ad longPath resInfo PermitDirectReferenceToGeneratedType.No with + | Result res -> res + | res when inSig && longPath.Length = 1 -> + errorR(Deprecated(FSComp.SR.tcReservedSyntaxForAugmentation(), m)) + ForceRaise res + | res -> ForceRaise res + tcref + + let isInterfaceOrDelegateOrEnum = + tcref.Deref.IsFSharpInterfaceTycon || + tcref.Deref.IsFSharpDelegateTycon || + tcref.Deref.IsFSharpEnumTycon + + let reqTypars = tcref.Typars m + + // Member definitions are intrinsic (added directly to the type) if: + // a) For interfaces, only if it is in the original defn. + // Augmentations to interfaces via partial type defns will always be extensions, e.g. extension members on interfaces. + // b) For other types, if the type is isInSameModuleOrNamespace + let declKind, typars = + if isAtOriginalTyconDefn then + ModuleOrMemberBinding, reqTypars + + else + let isInSameModuleOrNamespace = + match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryGetValue tcref.LogicalName with + | true, tycon -> tyconOrder.Compare(tcref.Deref, tycon) = 0 + | _ -> + //false + // There is a special case we allow when compiling FSharp.Core.dll which permits interface implementations across namespace fragments + g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`") + + let nReqTypars = reqTypars.Length + + let declaredTypars = TcTyparDecls cenv envForDecls synTypars + let envForTycon = AddDeclaredTypars CheckForDuplicateTypars declaredTypars envForDecls + let _tpenv = TcTyparConstraints cenv NoNewTypars CheckCxs ItemOccurence.UseInType envForTycon emptyUnscopedTyparEnv synTyparCxs + declaredTypars |> List.iter (SetTyparRigid envForDecls.DisplayEnv m) + + if isInSameModuleOrNamespace && not isInterfaceOrDelegateOrEnum then + // For historical reasons we only give a warning for incorrect type parameters on intrinsic extensions + if nReqTypars <> synTypars.Length then + warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) + if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then + warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) + // Note we return 'reqTypars' for intrinsic extensions since we may only have given warnings + IntrinsicExtensionBinding, reqTypars + else + if isInSameModuleOrNamespace && isInterfaceOrDelegateOrEnum then + errorR(Error(FSComp.SR.tcMembersThatExtendInterfaceMustBePlacedInSeparateModule(), tcref.Range)) + if nReqTypars <> synTypars.Length then + error(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) + if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then + errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) + ExtrinsicExtensionBinding, declaredTypars + + + declKind, tcref, typars + + + let private isAugmentationTyconDefnRepr = function SynTypeDefnSimpleRepr.General(SynTypeDefnKind.Augmentation, _, _, _, _, _, _, _) -> true | _ -> false + let private isAutoProperty = function SynMemberDefn.AutoProperty _ -> true | _ -> false + let private isMember = function SynMemberDefn.Member _ -> true | _ -> false + let private isImplicitCtor = function SynMemberDefn.ImplicitCtor _ -> true | _ -> false + let private isImplicitInherit = function SynMemberDefn.ImplicitInherit _ -> true | _ -> false + let private isAbstractSlot = function SynMemberDefn.AbstractSlot _ -> true | _ -> false + let private isInterface = function SynMemberDefn.Interface _ -> true | _ -> false + let private isInherit = function SynMemberDefn.Inherit _ -> true | _ -> false + let private isField = function SynMemberDefn.ValField _ -> true | _ -> false + let private isTycon = function SynMemberDefn.NestedType _ -> true | _ -> false + + let private allFalse ps x = List.forall (fun p -> not (p x)) ps + + /// Check the ordering on the bindings and members in a class construction + // Accepted forms: + // + // Implicit Construction: + // implicit_ctor + // optional implicit_inherit + // multiple bindings + // multiple member-binding(includes-overrides) or abstract-slot-declaration or interface-bindings + // + // Classic construction: + // multiple (binding or slotsig or field or interface or inherit). + // i.e. not local-bindings, implicit ctor or implicit inherit (or tycon?). + // atMostOne inherit. + let private CheckMembersForm ds = + match ds with + | d :: ds when isImplicitCtor d -> + // Implicit construction + let ds = + match ds with + | d :: ds when isImplicitInherit d -> ds // skip inherit call if it comes next + | _ -> ds + + // Skip over 'let' and 'do' bindings + let _, ds = ds |> List.takeUntil (function SynMemberDefn.LetBindings _ -> false | _ -> true) + + // Skip over 'let' and 'do' bindings + let _, ds = ds |> List.takeUntil (allFalse [isMember;isAbstractSlot;isInterface;isAutoProperty]) + + match ds with + | SynMemberDefn.Member (_, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have binding", m)) + | SynMemberDefn.AbstractSlot (_, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have slotsig", m)) + | SynMemberDefn.Interface (_, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have interface", m)) + | SynMemberDefn.ImplicitCtor (_, _, _, _, _, m) :: _ -> errorR(InternalError("implicit class construction with two implicit constructions", m)) + | SynMemberDefn.AutoProperty (_, _, _, _, _, _, _, _, _, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have auto property", m)) + | SynMemberDefn.ImplicitInherit (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit(), m)) + | SynMemberDefn.LetBindings (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers(), m)) + | SynMemberDefn.Inherit (_, _, m) :: _ -> errorR(Error(FSComp.SR.tcInheritDeclarationMissingArguments(), m)) + | SynMemberDefn.NestedType (_, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)) + | _ -> () + | ds -> + // Classic class construction + let _, ds = List.takeUntil (allFalse [isMember;isAbstractSlot;isInterface;isInherit;isField;isTycon]) ds + match ds with + | SynMemberDefn.Member (_, m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m)) + | SynMemberDefn.ImplicitCtor (_, _, _, _, _, m) :: _ -> errorR(InternalError("CheckMembersForm: implicit ctor line should be first", m)) + | SynMemberDefn.ImplicitInherit (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcInheritConstructionCallNotPartOfImplicitSequence(), m)) + | SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcAutoPropertyRequiresImplicitConstructionSequence(), m)) + | SynMemberDefn.LetBindings (_, false, _, m) :: _ -> errorR(Error(FSComp.SR.tcLetAndDoRequiresImplicitConstructionSequence(), m)) + | SynMemberDefn.AbstractSlot (_, _, m) :: _ + | SynMemberDefn.Interface (_, _, m) :: _ + | SynMemberDefn.Inherit (_, _, m) :: _ + | SynMemberDefn.ValField (_, m) :: _ + | SynMemberDefn.NestedType (_, _, m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m)) + | _ -> () + + + /// Separates the definition into core (shape) and body. + /// + /// core = synTyconInfo, simpleRepr, interfaceTypes + /// where simpleRepr can contain inherit type, declared fields and virtual slots. + /// body = members + /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. + let rec private SplitTyconDefn (SynTypeDefn(synTyconInfo, trepr, extraMembers, _, _)) = + let implements1 = List.choose (function SynMemberDefn.Interface (ty, _, _) -> Some(ty, ty.Range) | _ -> None) extraMembers + match trepr with + | SynTypeDefnRepr.ObjectModel(kind, cspec, m) -> + CheckMembersForm cspec + let fields = cspec |> List.choose (function SynMemberDefn.ValField (f, _) -> Some f | _ -> None) + let implements2 = cspec |> List.choose (function SynMemberDefn.Interface (ty, _, _) -> Some(ty, ty.Range) | _ -> None) + let inherits = + cspec |> List.choose (function + | SynMemberDefn.Inherit (ty, idOpt, m) -> Some(ty, m, idOpt) + | SynMemberDefn.ImplicitInherit (ty, _, idOpt, m) -> Some(ty, m, idOpt) + | _ -> None) + //let nestedTycons = cspec |> List.choose (function SynMemberDefn.NestedType (x, _, _) -> Some x | _ -> None) + let slotsigs = cspec |> List.choose (function SynMemberDefn.AbstractSlot (x, y, _) -> Some(x, y) | _ -> None) + + let members = + let membersIncludingAutoProps = + cspec |> List.filter (fun memb -> + match memb with + | SynMemberDefn.Interface _ + | SynMemberDefn.Member _ + | SynMemberDefn.LetBindings _ + | SynMemberDefn.ImplicitCtor _ + | SynMemberDefn.AutoProperty _ + | SynMemberDefn.Open _ + | SynMemberDefn.ImplicitInherit _ -> true + | SynMemberDefn.NestedType (_, _, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)); false + // covered above + | SynMemberDefn.ValField _ + | SynMemberDefn.Inherit _ + | SynMemberDefn.AbstractSlot _ -> false) + + // Convert auto properties to let bindings in the pre-list + let rec preAutoProps memb = + match memb with + | SynMemberDefn.AutoProperty(Attributes attribs, isStatic, id, tyOpt, propKind, _, xmlDoc, _access, synExpr, _mGetSet, mWholeAutoProp) -> + // Only the keep the field-targeted attributes + let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> true | _ -> false) + let mLetPortion = synExpr.Range + let fldId = ident (CompilerGeneratedName id.idText, mLetPortion) + let headPat = SynPat.LongIdent (LongIdentWithDots([fldId], []), None, Some noInferredTypars, SynArgPats.Pats [], None, mLetPortion) + let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) + let isMutable = + match propKind with + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGetSet -> true + | _ -> false + let attribs = mkAttributeList attribs mWholeAutoProp + let binding = mkSynBinding (xmlDoc, headPat) (None, false, isMutable, mLetPortion, DebugPointAtBinding.NoneAtInvisible, retInfo, synExpr, synExpr.Range, [], attribs, None) + + [(SynMemberDefn.LetBindings ([binding], isStatic, false, mWholeAutoProp))] + + | SynMemberDefn.Interface (_, Some membs, _) -> membs |> List.collect preAutoProps + | SynMemberDefn.LetBindings _ + | SynMemberDefn.ImplicitCtor _ + | SynMemberDefn.Open _ + | SynMemberDefn.ImplicitInherit _ -> [memb] + | _ -> [] + + // Convert auto properties to member bindings in the post-list + let rec postAutoProps memb = + match memb with + | SynMemberDefn.AutoProperty(Attributes attribs, isStatic, id, tyOpt, propKind, memberFlags, xmlDoc, access, _synExpr, mGetSetOpt, _mWholeAutoProp) -> + let mMemberPortion = id.idRange + // Only the keep the non-field-targeted attributes + let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> false | _ -> true) + let fldId = ident (CompilerGeneratedName id.idText, mMemberPortion) + let headPatIds = if isStatic then [id] else [ident ("__", mMemberPortion);id] + let headPat = SynPat.LongIdent (LongIdentWithDots(headPatIds, []), None, Some noInferredTypars, SynArgPats.Pats [], None, mMemberPortion) + + match propKind, mGetSetOpt with + | SynMemberKind.PropertySet, Some m -> errorR(Error(FSComp.SR.parsMutableOnAutoPropertyShouldBeGetSetNotJustSet(), m)) + | _ -> () + + [ + match propKind with + | SynMemberKind.Member + | SynMemberKind.PropertyGet + | SynMemberKind.PropertyGetSet -> + let getter = + let rhsExpr = SynExpr.Ident fldId + let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) + let attribs = mkAttributeList attribs mMemberPortion + let binding = mkSynBinding (xmlDoc, headPat) (access, false, false, mMemberPortion, DebugPointAtBinding.NoneAtInvisible, retInfo, rhsExpr, rhsExpr.Range, [], attribs, Some (memberFlags SynMemberKind.Member)) + SynMemberDefn.Member (binding, mMemberPortion) + yield getter + | _ -> () + + match propKind with + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGetSet -> + let setter = + let vId = ident("v", mMemberPortion) + let headPat = SynPat.LongIdent (LongIdentWithDots(headPatIds, []), None, Some noInferredTypars, SynArgPats.Pats [mkSynPatVar None vId], None, mMemberPortion) + let rhsExpr = mkSynAssign (SynExpr.Ident fldId) (SynExpr.Ident vId) + //let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) + let binding = mkSynBinding (xmlDoc, headPat) (access, false, false, mMemberPortion, DebugPointAtBinding.NoneAtInvisible, None, rhsExpr, rhsExpr.Range, [], [], Some (memberFlags SynMemberKind.PropertySet)) + SynMemberDefn.Member (binding, mMemberPortion) + yield setter + | _ -> ()] + | SynMemberDefn.Interface (ty, Some membs, m) -> + let membs' = membs |> List.collect postAutoProps + [SynMemberDefn.Interface (ty, Some membs', m)] + | SynMemberDefn.LetBindings _ + | SynMemberDefn.ImplicitCtor _ + | SynMemberDefn.Open _ + | SynMemberDefn.ImplicitInherit _ -> [] + | _ -> [memb] + + let preMembers = membersIncludingAutoProps |> List.collect preAutoProps + let postMembers = membersIncludingAutoProps |> List.collect postAutoProps + + preMembers @ postMembers + + let isConcrete = + members |> List.exists (function + | SynMemberDefn.Member(SynBinding(_, _, _, _, _, _, SynValData(Some memberFlags, _, _), _, _, _, _, _), _) -> not memberFlags.IsDispatchSlot + | SynMemberDefn.Interface (_, defOpt, _) -> Option.isSome defOpt + | SynMemberDefn.LetBindings _ -> true + | SynMemberDefn.ImplicitCtor _ -> true + | SynMemberDefn.ImplicitInherit _ -> true + | _ -> false) + + let isIncrClass = + members |> List.exists (function + | SynMemberDefn.ImplicitCtor _ -> true + | _ -> false) + + let hasSelfReferentialCtor = + members |> List.exists (function + | SynMemberDefn.ImplicitCtor (_, _, _, thisIdOpt, _, _) + | SynMemberDefn.Member(SynBinding(_, _, _, _, _, _, SynValData(_, _, thisIdOpt), _, _, _, _, _), _) -> thisIdOpt.IsSome + | _ -> false) + + let implicitCtorSynPats = + members |> List.tryPick (function + | SynMemberDefn.ImplicitCtor (_, _, (SynSimplePats.SimplePats _ as spats), _, _, _) -> Some spats + | _ -> None) + + // An ugly bit of code to pre-determine if a type has a nullary constructor, prior to establishing the + // members of the type + let preEstablishedHasDefaultCtor = + members |> List.exists (function + | SynMemberDefn.Member(SynBinding(_, _, _, _, _, _, SynValData(Some memberFlags, _, _), SynPatForConstructorDecl SynPatForNullaryArgs, _, _, _, _), _) -> + memberFlags.MemberKind=SynMemberKind.Constructor + | SynMemberDefn.ImplicitCtor (_, _, SynSimplePats.SimplePats(spats, _), _, _, _) -> isNil spats + | _ -> false) + let repr = SynTypeDefnSimpleRepr.General(kind, inherits, slotsigs, fields, isConcrete, isIncrClass, implicitCtorSynPats, m) + let isAtOriginalTyconDefn = not (isAugmentationTyconDefnRepr repr) + let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements2@implements1, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isAtOriginalTyconDefn) + + core, members @ extraMembers + + | SynTypeDefnRepr.Simple(repr, _) -> + let members = [] + let isAtOriginalTyconDefn = true + let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements1, false, false, isAtOriginalTyconDefn) + core, members @ extraMembers + + | SynTypeDefnRepr.Exception r -> + let isAtOriginalTyconDefn = true + let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) + core, extraMembers + + //------------------------------------------------------------------------- + + /// Bind a collection of mutually recursive definitions in an implementation file + let TcMutRecDefinitions (cenv: cenv) envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) = + + // Split the definitions into "core representations" and "members". The code to process core representations + // is shared between processing of signature files and implementation files. + let mutRecDefnsAfterSplit = mutRecDefns |> MutRecShapes.mapTycons SplitTyconDefn + + // Create the entities for each module and type definition, and process the core representation of each type definition. + let tycons, envMutRecPrelim, mutRecDefnsAfterCore = + EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 + (fun containerInfo synBinds -> [ for synBind in synBinds -> RecDefnBindingInfo(containerInfo, NoNewSlots, ModuleOrMemberBinding, synBind) ]) + cenv envInitial parent typeNames false tpenv m scopem mutRecNSInfo mutRecDefnsAfterSplit + + // Package up the phase two information for processing members. + let mutRecDefnsAfterPrep = + (envMutRecPrelim, mutRecDefnsAfterCore) + ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls ((typeDefnCore, members, innerParent), tyconOpt, fixupFinalAttrs, (baseValOpt, safeInitInfo)) -> + let (MutRecDefnsPhase1DataForTycon(synTyconInfo, _, _, _, _, isAtOriginalTyconDefn)) = typeDefnCore + let tyDeclRange = synTyconInfo.Range + let (SynComponentInfo(_, TyparsAndConstraints (typars, cs1), cs2, longPath, _, _, _, _)) = synTyconInfo + let cs = cs1 @ cs2 + let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind cenv envForDecls tyconOpt isAtOriginalTyconDefn false tyDeclRange typars cs longPath + let newslotsOK = (if isAtOriginalTyconDefn && tcref.IsFSharpObjectModelTycon then NewSlotsOK else NoNewSlots) + + if (declKind = ExtrinsicExtensionBinding) && isByrefTyconRef cenv.g tcref then + error(Error(FSComp.SR.tcByrefsMayNotHaveTypeExtensions(), tyDeclRange)) + + if not (isNil members) && tcref.IsTypeAbbrev then + errorR(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveAugmentations(), tyDeclRange)) + + let (SynComponentInfo (attributes, _, _, _, _, _, _, _)) = synTyconInfo + if not (List.isEmpty attributes) && (declKind = ExtrinsicExtensionBinding || declKind = IntrinsicExtensionBinding) then + let attributeRange = (List.head attributes).Range + error(Error(FSComp.SR.tcAugmentationsCannotHaveAttributes(), attributeRange)) + + MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) + + // By now we've established the full contents of type definitions apart from their + // members and any fields determined by implicit construction. We know the kinds and + // representations of types and have established them as valid. + // + // We now reconstruct the active environments all over again - this will add the union cases and fields. + // + // Note: This environment reconstruction doesn't seem necessary. We're about to create Val's for all members, + // which does require type checking, but no more information than is already available. + let envMutRecPrelimWithReprs, withEnvs = + (envInitial, MutRecShapes.dropEnvs mutRecDefnsAfterPrep) + ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs + (fun (MutRecDefnsPhase2DataForTycon(tyconOpt, _, _, _, _, _, _, _, _, _, _)) -> tyconOpt) + (fun _binds -> [ (* no values are available yet *) ]) + cenv true scopem m + + // Check the members and decide on representations for types with implicit constructors. + let withBindings, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem mutRecNSInfo envMutRecPrelimWithReprs withEnvs + + // Generate the hash/compare/equality bindings for all tycons. + // + // Note: generating these bindings must come after generating the members, since some in the case of structs some fields + // may be added by generating the implicit construction syntax + let withExtraBindings = + (envFinal, withBindings) ||> MutRecShapes.expandTyconsWithEnv (fun envForDecls (tyconOpt, _) -> + match tyconOpt with + | None -> [], [] + | Some tycon -> + // We put the hash/compare bindings before the type definitions and the + // equality bindings after because tha is the order they've always been generated + // in, and there are code generation tests to check that. + let binds = AddAugmentationDeclarations.AddGenericHashAndComparisonBindings cenv tycon + let binds3 = AddAugmentationDeclarations.AddGenericEqualityBindings cenv envForDecls tycon + binds, binds3) + + // Check for cyclic structs and inheritance all over again, since we may have added some fields to the struct when generating the implicit construction syntax + EstablishTypeDefinitionCores.TcTyconDefnCore_CheckForCyclicStructsAndInheritance cenv tycons + + withExtraBindings, envFinal + + + //------------------------------------------------------------------------- + + /// Separates the signature declaration into core (shape) and body. + let rec private SplitTyconSignature (SynTypeDefnSig(synTyconInfo, trepr, extraMembers, _)) = + + let implements1 = + extraMembers |> List.choose (function SynMemberSig.Interface (f, m) -> Some(f, m) | _ -> None) + + match trepr with + | SynTypeDefnSigRepr.ObjectModel(kind, cspec, m) -> + let fields = cspec |> List.choose (function SynMemberSig.ValField (f, _) -> Some f | _ -> None) + let implements2 = cspec |> List.choose (function SynMemberSig.Interface (ty, m) -> Some(ty, m) | _ -> None) + let inherits = cspec |> List.choose (function SynMemberSig.Inherit (ty, _) -> Some(ty, m, None) | _ -> None) + //let nestedTycons = cspec |> List.choose (function SynMemberSig.NestedType (x, _) -> Some x | _ -> None) + let slotsigs = cspec |> List.choose (function SynMemberSig.Member (v, fl, _) when fl.IsDispatchSlot -> Some(v, fl) | _ -> None) + let members = cspec |> List.filter (function + | SynMemberSig.Interface _ -> true + | SynMemberSig.Member (_, memberFlags, _) when not memberFlags.IsDispatchSlot -> true + | SynMemberSig.NestedType (_, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)); false + | _ -> false) + let isConcrete = + members |> List.exists (function + | SynMemberSig.Member (_, memberFlags, _) -> memberFlags.MemberKind=SynMemberKind.Constructor + | _ -> false) + + // An ugly bit of code to pre-determine if a type has a nullary constructor, prior to establishing the + // members of the type + let preEstablishedHasDefaultCtor = + members |> List.exists (function + | SynMemberSig.Member (valSpfn, memberFlags, _) -> + memberFlags.MemberKind=SynMemberKind.Constructor && + // REVIEW: This is a syntactic approximation + (match valSpfn.SynType, valSpfn.SynInfo.CurriedArgInfos with + | StripParenTypes (SynType.Fun (StripParenTypes (SynType.LongIdent (LongIdentWithDots([id], _))), _, _)), [[_]] when id.idText = "unit" -> true + | _ -> false) + | _ -> false) + + let hasSelfReferentialCtor = false + + let repr = SynTypeDefnSimpleRepr.General(kind, inherits, slotsigs, fields, isConcrete, false, None, m) + let isAtOriginalTyconDefn = true + let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, repr, implements2@implements1, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isAtOriginalTyconDefn) + + tyconCore, (synTyconInfo, members@extraMembers) + + // 'type X with ...' in a signature is always interpreted as an extrinsic extension. + // Representation-hidden types with members and interfaces are written 'type X = ...' + | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.None _ as r, _) when not (isNil extraMembers) -> + let isAtOriginalTyconDefn = false + let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, r, implements1, false, false, isAtOriginalTyconDefn) + tyconCore, (synTyconInfo, extraMembers) + + | SynTypeDefnSigRepr.Exception r -> + let isAtOriginalTyconDefn = true + let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) + core, (synTyconInfo, extraMembers) + + | SynTypeDefnSigRepr.Simple(r, _) -> + let isAtOriginalTyconDefn = true + let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, r, implements1, false, false, isAtOriginalTyconDefn) + tyconCore, (synTyconInfo, extraMembers) + + + let private TcMutRecSignatureDecls_Phase2 (cenv: cenv) scopem envMutRec mutRecDefns = + (envMutRec, mutRecDefns) ||> MutRecShapes.mapWithEnv + // Do this for the members in each 'type' declaration + (fun envForDecls ((tyconCore, (synTyconInfo, members), innerParent), tyconOpt, _fixupFinalAttrs, _) -> + let tpenv = emptyUnscopedTyparEnv + let (MutRecDefnsPhase1DataForTycon (_, _, _, _, _, isAtOriginalTyconDefn)) = tyconCore + let (SynComponentInfo(_, TyparsAndConstraints (typars, cs1), cs2, longPath, _, _, _, m)) = synTyconInfo + let cs = cs1 @ cs2 + let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind cenv envForDecls tyconOpt isAtOriginalTyconDefn true m typars cs longPath + + let envForTycon = AddDeclaredTypars CheckForDuplicateTypars declaredTyconTypars envForDecls + let envForTycon = MakeInnerEnvForTyconRef envForTycon tcref (declKind = ExtrinsicExtensionBinding) + + TcTyconMemberSpecs cenv envForTycon (TyconContainerInfo(innerParent, tcref, declaredTyconTypars, NoSafeInitInfo)) declKind tpenv members) + + // Do this for each 'val' declaration in a module + (fun envForDecls (containerInfo, valSpec) -> + let tpenv = emptyUnscopedTyparEnv + let idvs, _ = TcAndPublishValSpec (cenv, envForDecls, containerInfo, ModuleOrMemberBinding, None, tpenv, valSpec) + let env = List.foldBack (AddLocalVal cenv.g cenv.tcSink scopem) idvs envForDecls + env) + + + /// Bind a collection of mutually recursive declarations in a signature file + let TcMutRecSignatureDecls (cenv: cenv) envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecSigs: MutRecSigsInitialData) = + let mutRecSigsAfterSplit = mutRecSigs |> MutRecShapes.mapTycons SplitTyconSignature + let _tycons, envMutRec, mutRecDefnsAfterCore = + EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 + (fun containerInfo valDecl -> (containerInfo, valDecl)) + cenv envInitial parent typeNames true tpenv m scopem mutRecNSInfo mutRecSigsAfterSplit + + // Updates the types of the modules to contain the contents so far, which now includes values and members + MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterCore + + // By now we've established the full contents of type definitions apart from their + // members and any fields determined by implicit construction. We know the kinds and + // representations of types and have established them as valid. + // + // We now reconstruct the active environments all over again - this will add the union cases and fields. + // + // Note: This environment reconstruction doesn't seem necessary. We're about to create Val's for all members, + // which does require type checking, but no more information than is already available. + let envMutRecPrelimWithReprs, withEnvs = + (envInitial, MutRecShapes.dropEnvs mutRecDefnsAfterCore) + ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs + (fun (_, tyconOpt, _, _) -> tyconOpt) + (fun _binds -> [ (* no values are available yet *) ]) + cenv true scopem m + + let mutRecDefnsAfterVals = TcMutRecSignatureDecls_Phase2 cenv scopem envMutRecPrelimWithReprs withEnvs + + // Updates the types of the modules to contain the contents so far, which now includes values and members + MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterVals + + envMutRec + +//------------------------------------------------------------------------- +// Bind module types +//------------------------------------------------------------------------- + +let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synSigDecl: Cancellable = + cancellable { + try + match synSigDecl with + | SynModuleSigDecl.Exception (edef, m) -> + let scopem = unionRanges m.EndRange endm + let _, _, _, env = TcExceptionDeclarations.TcExnSignature cenv env parent emptyUnscopedTyparEnv (edef, scopem) + return env + + | SynModuleSigDecl.Types (typeSpecs, m) -> + let scopem = unionRanges m endm + let mutRecDefns = typeSpecs |> List.map MutRecShape.Tycon + let env = TcDeclarations.TcMutRecSignatureDecls cenv env parent typeNames emptyUnscopedTyparEnv m scopem None mutRecDefns + return env + + | SynModuleSigDecl.Open (target, m) -> + let scopem = unionRanges m.EndRange endm + let env, _openDecl = TcOpenDecl cenv m scopem env target + return env + + | SynModuleSigDecl.Val (vspec, m) -> + let parentModule = + match parent with + | ParentNone -> error(Error(FSComp.SR.tcNamespaceCannotContainValues(), vspec.RangeOfId)) + | Parent p -> p + let containerInfo = ModuleOrNamespaceContainerInfo parentModule + let idvs, _ = TcAndPublishValSpec (cenv, env, containerInfo, ModuleOrMemberBinding, None, emptyUnscopedTyparEnv, vspec) + let scopem = unionRanges m endm + let env = List.foldBack (AddLocalVal cenv.g cenv.tcSink scopem) idvs env + return env + + | SynModuleSigDecl.NestedModule(SynComponentInfo(Attributes attribs, _, _, longPath, xml, _, vis, im) as compInfo, isRec, mdefs, m) -> + if isRec then + // Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...' + let modDecl = SynModuleSigDecl.NestedModule(compInfo, false, mdefs, m) + + return! TcSignatureElementsMutRec cenv parent typeNames endm None env [modDecl] + else + let id = ComputeModuleName longPath + let vis, _ = ComputeAccessAndCompPath env None im vis None parent + let attribs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs + CheckNamespaceModuleOrTypeName cenv.g id + let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames attribs id.idText + let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText + CheckForDuplicateConcreteType env modName id.idRange + + // Now typecheck the signature, accumulating and then recording the submodule description. + let id = ident (modName, id.idRange) + + let mty = Construct.NewEmptyModuleOrNamespaceType modKind + let doc = xml.ToXmlDoc(true, Some []) + let mspec = Construct.NewModuleOrNamespace (Some env.eCompPath) vis id doc attribs (MaybeLazy.Strict mty) + + let! mtyp, _ = TcModuleOrNamespaceSignatureElementsNonMutRec cenv (Parent (mkLocalModRef mspec)) env (id, modKind, mdefs, m, xml) + + mspec.entity_modul_contents <- MaybeLazy.Strict mtyp + let scopem = unionRanges m endm + PublishModuleDefn cenv env mspec + let env = AddLocalSubModuleAndReport cenv.tcSink scopem cenv.g cenv.amap m env mspec + return env + + | SynModuleSigDecl.ModuleAbbrev (id, p, m) -> + let ad = env.AccessRights + let resolved = + match p with + | [] -> Result [] + | id :: rest -> ResolveLongIdentAsModuleOrNamespace cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m true OpenQualified env.NameEnv ad id rest false + let mvvs = ForceRaise resolved + let scopem = unionRanges m endm + let unfilteredModrefs = mvvs |> List.map p23 + + let modrefs = unfilteredModrefs |> List.filter (fun modref -> not modref.IsNamespace) + + if not (List.isEmpty unfilteredModrefs) && List.isEmpty modrefs then + errorR(Error(FSComp.SR.tcModuleAbbreviationForNamespace(fullDisplayTextOfModRef (List.head unfilteredModrefs)), m)) + + if List.isEmpty modrefs then return env else + modrefs |> List.iter (fun modref -> CheckEntityAttributes cenv.g modref m |> CommitOperationResult) + + let env = AddModuleAbbreviationAndReport cenv.tcSink scopem id modrefs env + return env + + | SynModuleSigDecl.HashDirective _ -> + return env + + + | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig(longId, isRec, kind, defs, xml, attribs, vis, m)) -> + + do for id in longId do + CheckNamespaceModuleOrTypeName cenv.g id + + // Logically speaking, this changes + // module [rec] A.B.M + // ... + // to + // namespace [rec] A.B + // module M = ... + let enclosingNamespacePath, defs = + if kind.IsModule then + let nsp, modName = List.frontAndBack longId + let modDecl = [SynModuleSigDecl.NestedModule(SynComponentInfo(attribs, None, [], [modName], xml, false, vis, m), false, defs, m)] + nsp, modDecl + else + longId, defs + + let envNS = LocateEnv cenv.topCcu env enclosingNamespacePath + let envNS = ImplicitlyOpenOwnNamespace cenv.tcSink cenv.g cenv.amap m enclosingNamespacePath envNS + + // For 'namespace rec' and 'module rec' we add the thing being defined + let mtypNS = envNS.eModuleOrNamespaceTypeAccumulator.Value + let mtypRoot, mspecNSs = BuildRootModuleType enclosingNamespacePath envNS.eCompPath mtypNS + let mspecNSOpt = List.tryHead mspecNSs + + mspecNSs |> List.iter (fun mspec -> + let modref = mkLocalModRef mspec + let item = Item.ModuleOrNamespaces [modref] + CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights)) + + // For 'namespace rec' and 'module rec' we add the thing being defined + let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m envNS mtypRoot else envNS + let nsInfo = Some (mspecNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) + let mutRecNSInfo = if isRec then nsInfo else None + + let! envAtEnd = TcSignatureElements cenv ParentNone m.EndRange envNS xml mutRecNSInfo defs + + MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo + + let env = + if isNil enclosingNamespacePath then + envAtEnd + else + let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot + + // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment. + let env, _openDecls = + match TryStripPrefixPath cenv.g enclosingNamespacePath with + | Some(p, _) -> TcOpenModuleOrNamespaceDecl cenv.tcSink cenv.g cenv.amap m.EndRange env ([p], m.EndRange) + | None -> env, [] + + // Publish the combined module type + env.eModuleOrNamespaceTypeAccumulator.Value <- + CombineCcuContentFragments m [env.eModuleOrNamespaceTypeAccumulator.Value; mtypRoot] + env + + return env + + with e -> + errorRecovery e endm + return env + } + + +and TcSignatureElements cenv parent endm env xml mutRecNSInfo defs = + cancellable { + // Ensure the .Deref call in UpdateAccModuleOrNamespaceType succeeds + if cenv.compilingCanonicalFslibModuleType then + let doc = xml.ToXmlDoc(true, Some []) + ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath doc + + let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecSigDecls defs + match mutRecNSInfo with + | Some _ -> + return! TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo env defs + | None -> + return! TcSignatureElementsNonMutRec cenv parent typeNames endm env defs + } + +and TcSignatureElementsNonMutRec cenv parent typeNames endm env defs = + Cancellable.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs + +and TcSignatureElementsMutRec cenv parent typeNames m mutRecNSInfo envInitial (defs: SynModuleSigDecl list) = + cancellable { + let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges + let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m) + + let mutRecDefns = + let rec loop isNamespace moduleRange defs: MutRecSigsInitialData = + ((true, true), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk) def -> + match def with + | SynModuleSigDecl.Types (typeSpecs, _) -> + let decls = typeSpecs |> List.map MutRecShape.Tycon + decls, (false, false) + + | SynModuleSigDecl.Open (target, m) -> + if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m)) + let decls = [ MutRecShape.Open (MutRecDataForOpen(target, m, moduleRange, ref [])) ] + decls, (openOk, moduleAbbrevOk) + + | SynModuleSigDecl.Exception (SynExceptionSig(exnRepr, members, _), _) -> + let ( SynExceptionDefnRepr(synAttrs, SynUnionCase(_, id, _args, _, _, _), _, doc, vis, m)) = exnRepr + let compInfo = SynComponentInfo(synAttrs, None, [], [id], doc, false, vis, id.idRange) + let decls = [ MutRecShape.Tycon(SynTypeDefnSig.SynTypeDefnSig(compInfo, SynTypeDefnSigRepr.Exception exnRepr, members, m)) ] + decls, (false, false) + + | SynModuleSigDecl.Val (vspec, _) -> + if isNamespace then error(Error(FSComp.SR.tcNamespaceCannotContainValues(), vspec.RangeOfId)) + let decls = [ MutRecShape.Lets vspec ] + decls, (false, false) + + | SynModuleSigDecl.NestedModule(compInfo, isRec, synDefs, moduleRange) -> + if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range)) + let mutRecDefs = loop false moduleRange synDefs + let decls = [MutRecShape.Module (compInfo, mutRecDefs)] + decls, (false, false) + + | SynModuleSigDecl.HashDirective _ -> + [], (openOk, moduleAbbrevOk) + + | SynModuleSigDecl.ModuleAbbrev (id, p, m) -> + if not moduleAbbrevOk then errorR(Error(FSComp.SR.tcModuleAbbrevFirstInMutRec(), m)) + let decls = [ MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev(id, p, m)) ] + decls, (false, moduleAbbrevOk) + + | SynModuleSigDecl.NamespaceFragment _ -> + error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), def.Range))) + + |> fst + loop (match parent with ParentNone -> true | Parent _ -> false) m defs + return TcDeclarations.TcMutRecSignatureDecls cenv envInitial parent typeNames emptyUnscopedTyparEnv m scopem mutRecNSInfo mutRecDefns + } + + + +and TcModuleOrNamespaceSignatureElementsNonMutRec cenv parent env (id, modKind, defs, m: range, xml) = + + cancellable { + let endm = m.EndRange // use end of range for errors + + // Create the module type that will hold the results of type checking.... + let envForModule, mtypeAcc = MakeInnerEnv true env id modKind + + // Now typecheck the signature, using mutation to fill in the submodule description. + let! envAtEnd = TcSignatureElements cenv parent endm envForModule xml None defs + + // mtypeAcc has now accumulated the module type + return mtypeAcc.Value, envAtEnd + } + +//------------------------------------------------------------------------- +// Bind definitions within modules +//------------------------------------------------------------------------- + + +let ElimModuleDoBinding bind = + match bind with + | SynModuleDecl.DoExpr (spExpr, expr, m) -> + let bind2 = SynBinding (None, SynBindingKind.StandaloneExpression, false, false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, SynPat.Wild m, None, expr, m, spExpr) + SynModuleDecl.Let(false, [bind2], m) + | _ -> bind + +let TcMutRecDefnsEscapeCheck (binds: MutRecShapes<_, _, _>) env = + let freeInEnv = GeneralizationHelpers.ComputeUnabstractableTycons env + let checkTycon (tycon: Tycon) = + if not tycon.IsTypeAbbrev && Zset.contains tycon freeInEnv then + let nm = tycon.DisplayName + errorR(Error(FSComp.SR.tcTypeUsedInInvalidWay(nm, nm, nm), tycon.Range)) + + binds |> MutRecShapes.iterTycons (fst >> Option.iter checkTycon) + + let freeInEnv = GeneralizationHelpers.ComputeUnabstractableTraitSolutions env + let checkBinds (binds: Binding list) = + for bind in binds do + if Zset.contains bind.Var freeInEnv then + let nm = bind.Var.DisplayName + errorR(Error(FSComp.SR.tcMemberUsedInInvalidWay(nm, nm, nm), bind.Var.Range)) + + binds |> MutRecShapes.iterTyconsAndLets (snd >> checkBinds) checkBinds + +// ignore solitary '()' expressions and 'do ()' bindings, since these are allowed in namespaces +// for the purposes of attaching attributes to an assembly, e.g. +// namespace A.B.C +// [] +// do() + +let CheckLetOrDoInNamespace binds m = + match binds with + | [ SynBinding (None, (SynBindingKind.StandaloneExpression | SynBindingKind.Do), false, false, [], _, _, _, None, (SynExpr.Do (SynExpr.Const (SynConst.Unit, _), _) | SynExpr.Const (SynConst.Unit, _)), _, _) ] -> + () + | [] -> + error(Error(FSComp.SR.tcNamespaceCannotContainValues(), m)) + | _ -> + error(Error(FSComp.SR.tcNamespaceCannotContainValues(), binds.Head.RangeOfHeadPattern)) + +/// The non-mutually recursive case for a declaration +let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem env synDecl = + cancellable { + cenv.synArgNameGenerator.Reset() + let tpenv = emptyUnscopedTyparEnv + + //printfn "----------\nCHECKING, e = %+A\n------------------\n" e + try + match ElimModuleDoBinding synDecl with + + | SynModuleDecl.ModuleAbbrev (id, p, m) -> + let env = MutRecBindingChecking.TcModuleAbbrevDecl cenv scopem env (id, p, m) + return (Operators.id, []), env, env + + | SynModuleDecl.Exception (edef, m) -> + let binds, decl, env = TcExceptionDeclarations.TcExnDefn cenv env parent (edef, scopem) + return ((fun e -> TMDefRec(true, [], [decl], binds |> List.map ModuleOrNamespaceBinding.Binding, m) :: e), []), env, env + + | SynModuleDecl.Types (typeDefs, m) -> + let scopem = unionRanges m scopem + let mutRecDefns = typeDefs |> List.map MutRecShape.Tycon + let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent typeNames tpenv m scopem None mutRecDefns + // Check the non-escaping condition as we build the expression on the way back up + let exprfWithEscapeCheck e = + TcMutRecDefnsEscapeCheck mutRecDefnsChecked env + TcMutRecDefsFinish cenv mutRecDefnsChecked m :: e + + return (exprfWithEscapeCheck, []), envAfter, envAfter + + | SynModuleDecl.Open (target, m) -> + let scopem = unionRanges m.EndRange scopem + let env, openDecls = TcOpenDecl cenv m scopem env target + return ((fun decls -> (match openDecls with [] -> decls | _ -> TMDefOpens openDecls :: decls)), []), env, env + + | SynModuleDecl.Let (letrec, binds, m) -> + + match parent with + | ParentNone -> + CheckLetOrDoInNamespace binds m + return (id, []), env, env + + | Parent parentModule -> + let containerInfo = ModuleOrNamespaceContainerInfo parentModule + if letrec then + let scopem = unionRanges m scopem + let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(containerInfo, NoNewSlots, ModuleOrMemberBinding, bind)) + let binds, env, _ = TcLetrec WarnOnOverrides cenv env tpenv (binds, m, scopem) + return ((fun e -> TMDefRec(true, [], [], binds |> List.map ModuleOrNamespaceBinding.Binding, m) :: e), []), env, env + else + let binds, env, _ = TcLetBindings cenv env containerInfo ModuleOrMemberBinding tpenv (binds, m, scopem) + return ((fun e -> binds@e), []), env, env + + | SynModuleDecl.DoExpr _ -> return! failwith "unreachable" + + | SynModuleDecl.Attributes (Attributes synAttrs, _) -> + let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.Top synAttrs + return (id, attrs), env, env + + | SynModuleDecl.HashDirective _ -> + return (id, []), env, env + + | SynModuleDecl.NestedModule(compInfo, isRec, mdefs, isContinuingModule, m) -> + + // Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...' + if isRec then + assert (not isContinuingModule) + let modDecl = SynModuleDecl.NestedModule(compInfo, false, mdefs, isContinuingModule, m) + return! TcModuleOrNamespaceElementsMutRec cenv parent typeNames m env None [modDecl] + else + let (SynComponentInfo(Attributes attribs, _, _, longPath, xml, _, vis, im)) = compInfo + let id = ComputeModuleName longPath + + let modAttrs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs + let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText + let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText + CheckForDuplicateConcreteType env modName im + CheckForDuplicateModule env id.idText id.idRange + let vis, _ = ComputeAccessAndCompPath env None id.idRange vis None parent + + let endm = m.EndRange + let id = ident (modName, id.idRange) + + CheckNamespaceModuleOrTypeName cenv.g id + + let envForModule, mtypeAcc = MakeInnerEnv true env id modKind + + // Create the new module specification to hold the accumulated results of the type of the module + // Also record this in the environment as the accumulator + let mty = Construct.NewEmptyModuleOrNamespaceType modKind + let doc = xml.ToXmlDoc(true, Some []) + let mspec = Construct.NewModuleOrNamespace (Some env.eCompPath) vis id doc modAttrs (MaybeLazy.Strict mty) + + // Now typecheck. + let! mexpr, topAttrsNew, envAtEnd = TcModuleOrNamespaceElements cenv (Parent (mkLocalModRef mspec)) endm envForModule xml None [] mdefs + + // Get the inferred type of the decls and record it in the mspec. + mspec.entity_modul_contents <- MaybeLazy.Strict mtypeAcc.Value + let modDefn = TMDefRec(false, [], [], [ModuleOrNamespaceBinding.Module(mspec, mexpr)], m) + PublishModuleDefn cenv env mspec + let env = AddLocalSubModuleAndReport cenv.tcSink scopem cenv.g cenv.amap m env mspec + + // isContinuingModule is true for all of the following + // - the implicit module of a script + // - the major 'module' declaration for a file stating with 'module X.Y' + // - an interactive entry for F# Interactive + // + // In this case the envAtEnd is the environment at the end of this module, which doesn't contain the module definition itself + // but does contain the results of all the 'open' declarations and so on. + let envAtEnd = (if isContinuingModule then envAtEnd else env) + + return ((fun modDefs -> modDefn :: modDefs), topAttrsNew), env, envAtEnd + + + | SynModuleDecl.NamespaceFragment(SynModuleOrNamespace(longId, isRec, kind, defs, xml, attribs, vis, m)) -> + + if progress then dprintn ("Typecheck implementation " + textOfLid longId) + let endm = m.EndRange + + do for id in longId do + CheckNamespaceModuleOrTypeName cenv.g id + + // Logically speaking, this changes + // module [rec] A.B.M + // ... + // to + // namespace [rec] A.B + // module M = ... + let enclosingNamespacePath, defs = + if kind.IsModule then + let nsp, modName = List.frontAndBack longId + let modDecl = [SynModuleDecl.NestedModule(SynComponentInfo(attribs, None, [], [modName], xml, false, vis, m), false, defs, true, m)] + nsp, modDecl + else + longId, defs + + let envNS = LocateEnv cenv.topCcu env enclosingNamespacePath + let envNS = ImplicitlyOpenOwnNamespace cenv.tcSink cenv.g cenv.amap m enclosingNamespacePath envNS + + let mtypNS = envNS.eModuleOrNamespaceTypeAccumulator.Value + let mtypRoot, mspecNSs = BuildRootModuleType enclosingNamespacePath envNS.eCompPath mtypNS + let mspecNSOpt = List.tryHead mspecNSs + + mspecNSs |> List.iter (fun mspec -> + let modref = mkLocalModRef mspec + let item = Item.ModuleOrNamespaces [modref] + CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights)) + + // For 'namespace rec' and 'module rec' we add the thing being defined + let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m envNS mtypRoot else envNS + let nsInfo = Some (mspecNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) + let mutRecNSInfo = if isRec then nsInfo else None + + let! modExpr, topAttrs, envAtEnd = TcModuleOrNamespaceElements cenv parent endm envNS xml mutRecNSInfo [] defs + + MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo + + let env, openDecls = + if isNil enclosingNamespacePath then + envAtEnd, [] + else + let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot + + // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment + let env, openDecls = + match TryStripPrefixPath cenv.g enclosingNamespacePath with + | Some(p, _) -> TcOpenModuleOrNamespaceDecl cenv.tcSink cenv.g cenv.amap m.EndRange env ([p], m.EndRange) + | None -> env, [] + + // Publish the combined module type + env.eModuleOrNamespaceTypeAccumulator.Value <- + CombineCcuContentFragments m [env.eModuleOrNamespaceTypeAccumulator.Value; mtypRoot] + env, openDecls + + let modExprRoot = BuildRootModuleExpr enclosingNamespacePath envNS.eCompPath modExpr + + return + ((fun modExprs -> + match openDecls with + | [] -> modExprRoot :: modExprs + | _ -> TMDefOpens openDecls :: modExprRoot :: modExprs), topAttrs), env, envAtEnd + + with exn -> + errorRecovery exn synDecl.Range + return (id, []), env, env + } + +/// The non-mutually recursive case for a sequence of declarations +and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) = + cancellable { + match moreDefs with + | firstDef :: otherDefs -> + // Lookahead one to find out the scope of the next declaration. + let scopem = + if isNil otherDefs then unionRanges firstDef.Range endm + else unionRanges (List.head otherDefs).Range endm + + // Possibly better: + //let scopem = unionRanges h1.Range.EndRange endm + + let! firstDef', env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef + // tail recursive + return! TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs + | [] -> + return List.rev defsSoFar, envAtEnd + } + +/// The mutually recursive case for a sequence of declarations (and nested modules) +and TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial mutRecNSInfo (defs: SynModuleDecl list) = + cancellable { + + let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges + let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m) + + let mutRecDefns, (_, _, Attributes synAttrs) = + let rec loop isNamespace moduleRange attrs defs: MutRecDefnsInitialData * _ = + ((true, true, attrs), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk, attrs) def -> + match ElimModuleDoBinding def with + + | SynModuleDecl.Types (typeDefs, _) -> + let decls = typeDefs |> List.map MutRecShape.Tycon + decls, (false, false, attrs) + + | SynModuleDecl.Let (letrec, binds, m) -> + let binds = + if isNamespace then + CheckLetOrDoInNamespace binds m; [] + else + if letrec then [MutRecShape.Lets binds] + else List.map (List.singleton >> MutRecShape.Lets) binds + binds, (false, false, attrs) + + | SynModuleDecl.NestedModule(compInfo, isRec, synDefs, _isContinuingModule, moduleRange) -> + if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range)) + let mutRecDefs, (_, _, attrs) = loop false moduleRange attrs synDefs + let decls = [MutRecShape.Module (compInfo, mutRecDefs)] + decls, (false, false, attrs) + + | SynModuleDecl.Open (target, m) -> + if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m)) + let decls = [ MutRecShape.Open (MutRecDataForOpen(target, m, moduleRange, ref [])) ] + decls, (openOk, moduleAbbrevOk, attrs) + + | SynModuleDecl.Exception (SynExceptionDefn(repr, members, _), _m) -> + let (SynExceptionDefnRepr(synAttrs, SynUnionCase(_, id, _args, _, _, _), _repr, doc, vis, m)) = repr + let compInfo = SynComponentInfo(synAttrs, None, [], [id], doc, false, vis, id.idRange) + let decls = [ MutRecShape.Tycon(SynTypeDefn(compInfo, SynTypeDefnRepr.Exception repr, members, None, m)) ] + decls, (false, false, attrs) + + | SynModuleDecl.HashDirective _ -> + [ ], (openOk, moduleAbbrevOk, attrs) + + | SynModuleDecl.Attributes (synAttrs, _) -> + [ ], (false, false, synAttrs) + + | SynModuleDecl.ModuleAbbrev (id, p, m) -> + if not moduleAbbrevOk then errorR(Error(FSComp.SR.tcModuleAbbrevFirstInMutRec(), m)) + let decls = [ MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev(id, p, m)) ] + decls, (false, moduleAbbrevOk, attrs) + + | SynModuleDecl.DoExpr _ -> failwith "unreachable: SynModuleDecl.DoExpr - ElimModuleDoBinding" + + | SynModuleDecl.NamespaceFragment _ as d -> error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), d.Range))) + + loop (match parent with ParentNone -> true | Parent _ -> false) m [] defs + + let tpenv = emptyUnscopedTyparEnv + let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns + + // Check the assembly attributes + let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs + + // Check the non-escaping condition as we build the list of module expressions on the way back up + let exprfWithEscapeCheck modExprs = + TcMutRecDefnsEscapeCheck mutRecDefnsChecked envInitial + let modExpr = TcMutRecDefsFinish cenv mutRecDefnsChecked m + modExpr :: modExprs + + return (exprfWithEscapeCheck, attrs), envAfter, envAfter + + } + +and TcMutRecDefsFinish cenv defs m = + let opens = + [ for def in defs do + match def with + | MutRecShape.Open (MutRecDataForOpen (_target, _m, _moduleRange, openDeclsRef)) -> + yield! openDeclsRef.Value + | _ -> () ] + + let tycons = defs |> List.choose (function MutRecShape.Tycon (Some tycon, _) -> Some tycon | _ -> None) + + let binds = + defs |> List.collect (function + | MutRecShape.Open _ -> [] + | MutRecShape.ModuleAbbrev _ -> [] + | MutRecShape.Tycon (_, binds) + | MutRecShape.Lets binds -> + binds |> List.map ModuleOrNamespaceBinding.Binding + | MutRecShape.Module ((MutRecDefnsPhase2DataForModule(mtypeAcc, mspec), _), mdefs) -> + let mexpr = TcMutRecDefsFinish cenv mdefs m + mspec.entity_modul_contents <- MaybeLazy.Strict mtypeAcc.Value + [ ModuleOrNamespaceBinding.Module(mspec, mexpr) ]) + + TMDefRec(true, opens, tycons, binds, m) + +and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo openDecls0 defs = + cancellable { + // Ensure the deref_nlpath call in UpdateAccModuleOrNamespaceType succeeds + if cenv.compilingCanonicalFslibModuleType then + let doc = xml.ToXmlDoc(true, Some []) + ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath doc + + // Collect the type names so we can implicitly add the compilation suffix to module names + let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecDecls defs + + match mutRecNSInfo with + | Some _ -> + let! (exprf, topAttrsNew), _, envAtEnd = TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm env mutRecNSInfo defs + // Apply the functions for each declaration to build the overall expression-builder + let mexpr = TMDefs(exprf []) + return (mexpr, topAttrsNew, envAtEnd) + + | None -> + + let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) defs + + // Apply the functions for each declaration to build the overall expression-builder + let mdefs = List.foldBack (fun (f, _) x -> f x) compiledDefs [] + let mdefs = match openDecls0 with [] -> mdefs | _ -> TMDefOpens openDecls0 :: mdefs + let mexpr = TMDefs mdefs + + // Collect up the attributes that are global to the file + let topAttrsNew = compiledDefs |> List.map snd |> List.concat + return (mexpr, topAttrsNew, envAtEnd) + } + + +//-------------------------------------------------------------------------- +// TypeCheckOneImplFile - Typecheck all the namespace fragments in a file. +//-------------------------------------------------------------------------- + + +let ApplyAssemblyLevelAutoOpenAttributeToTcEnv g amap (ccu: CcuThunk) scopem env (p, root) = + let warn() = + warning(Error(FSComp.SR.tcAttributeAutoOpenWasIgnored(p, ccu.AssemblyName), scopem)) + [], env + let p = splitNamespace p + if isNil p then warn() else + let h, t = List.frontAndBack p + let modref = mkNonLocalTyconRef (mkNonLocalEntityRef ccu (Array.ofList h)) t + match modref.TryDeref with + | ValueNone -> warn() + | ValueSome _ -> + let openTarget = SynOpenDeclTarget.ModuleOrNamespace([], scopem) + let openDecl = OpenDeclaration.Create (openTarget, [modref], [], scopem, false) + let envinner = OpenModuleOrNamespaceRefs TcResultsSink.NoSink g amap scopem root env [modref] openDecl + [openDecl], envinner + +// Add the CCU and apply the "AutoOpen" attributes +let AddCcuToTcEnv (g, amap, scopem, env, assemblyName, ccu, autoOpens, internalsVisibleToAttributes) = + let env = AddNonLocalCcu g amap scopem env assemblyName (ccu, internalsVisibleToAttributes) + + // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f + // "Microsoft" is opened by default in FSharp.Core + let autoOpens = + let autoOpens = autoOpens |> List.map (fun p -> (p, false)) + if ccuEq ccu g.fslibCcu then + // Auto open 'Microsoft' in FSharp.Core.dll. Even when using old versions of FSharp.Core.dll that do + // not have this attribute. The 'true' means 'treat all namespaces so revealed as "roots" accessible via + // global, e.g. global.FSharp.Collections' + ("Microsoft", true) :: autoOpens + else + autoOpens + + (env, autoOpens) ||> List.collectFold (ApplyAssemblyLevelAutoOpenAttributeToTcEnv g amap ccu scopem) + +let emptyTcEnv g = + let cpath = compPathInternal // allow internal access initially + { eNameResEnv = NameResolutionEnv.Empty g + eUngeneralizableItems = [] + ePath = [] + eCompPath = cpath // dummy + eAccessPath = cpath // dummy + eAccessRights = ComputeAccessRights cpath [] None // compute this field + eInternalsVisibleCompPaths = [] + eContextInfo = ContextInfo.NoContext + eModuleOrNamespaceTypeAccumulator = ref (Construct.NewEmptyModuleOrNamespaceType Namespace) + eFamilyType = None + eCtorInfo = None + eCallerMemberName = None + eLambdaArgInfos = [] } + +let CreateInitialTcEnv(g, amap, scopem, assemblyName, ccus) = + (emptyTcEnv g, ccus) ||> List.collectFold (fun env (ccu, autoOpens, internalsVisible) -> + try + AddCcuToTcEnv(g, amap, scopem, env, assemblyName, ccu, autoOpens, internalsVisible) + with e -> + errorRecovery e scopem + [], env) + +type ConditionalDefines = + string list + + +/// The attributes that don't get attached to any declaration +type TopAttribs = + { mainMethodAttrs: Attribs + netModuleAttrs: Attribs + assemblyAttrs: Attribs } + +let EmptyTopAttrs = + { mainMethodAttrs=[] + netModuleAttrs=[] + assemblyAttrs =[] } + +let CombineTopAttrs topAttrs1 topAttrs2 = + { mainMethodAttrs = topAttrs1.mainMethodAttrs @ topAttrs2.mainMethodAttrs + netModuleAttrs = topAttrs1.netModuleAttrs @ topAttrs2.netModuleAttrs + assemblyAttrs = topAttrs1.assemblyAttrs @ topAttrs2.assemblyAttrs } + +let rec IterTyconsOfModuleOrNamespaceType f (mty: ModuleOrNamespaceType) = + mty.AllEntities |> QueueList.iter (fun tycon -> f tycon) + mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> + IterTyconsOfModuleOrNamespaceType f v.ModuleOrNamespaceType) + + +// Defaults get applied before the module signature is checked and before the implementation conditions on virtuals/overrides. +// Defaults get applied in priority order. Defaults listed last get priority 0 (lowest), 2nd last priority 1 etc. +let ApplyDefaults (cenv: cenv) g denvAtEnd m mexpr extraAttribs = + try + let unsolved = FindUnsolved.UnsolvedTyparsOfModuleDef g cenv.amap denvAtEnd (mexpr, extraAttribs) + + CanonicalizePartialInferenceProblem cenv.css denvAtEnd m unsolved + + // The priority order comes from the order of declaration of the defaults in FSharp.Core. + for priority = 10 downto 0 do + unsolved |> List.iter (fun tp -> + if not tp.IsSolved then + // Apply the first default. If we're defaulting one type variable to another then + // the defaults will be propagated to the new type variable. + ApplyTyparDefaultAtPriority denvAtEnd cenv.css priority tp) + + // OK, now apply defaults for any unsolved TyparStaticReq.HeadType + unsolved |> List.iter (fun tp -> + if not tp.IsSolved then + if (tp.StaticReq <> TyparStaticReq.None) then + ChooseTyparSolutionAndSolve cenv.css denvAtEnd tp) + with e -> errorRecovery e m + +let CheckValueRestriction denvAtEnd infoReader rootSigOpt implFileTypePriorToSig m = + if Option.isNone rootSigOpt then + let rec check (mty: ModuleOrNamespaceType) = + for v in mty.AllValsAndMembers do + let ftyvs = (freeInVal CollectTyparsNoCaching v).FreeTypars |> Zset.elements + if (not v.IsCompilerGenerated && + not (ftyvs |> List.exists (fun tp -> tp.IsFromError)) && + // Do not apply the value restriction to methods and functions + // Note, normally these completely generalize their argument types anyway. However, + // some methods (property getters/setters, constructors) can't be as generic + // as they might naturally be, and these can leave type variables unsolved. See + // for example FSharp 1.0 3661. + (match v.ValReprInfo with None -> true | Some tvi -> tvi.HasNoArgs)) then + match ftyvs with + | tp :: _ -> errorR (ValueRestriction(denvAtEnd, infoReader, false, v, tp, v.Range)) + | _ -> () + mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> check v.ModuleOrNamespaceType) + try check implFileTypePriorToSig with e -> errorRecovery e m + + +let SolveInternalUnknowns g (cenv: cenv) denvAtEnd mexpr extraAttribs = + let unsolved = FindUnsolved.UnsolvedTyparsOfModuleDef g cenv.amap denvAtEnd (mexpr, extraAttribs) + + unsolved |> List.iter (fun tp -> + if (tp.Rigidity <> TyparRigidity.Rigid) && not tp.IsSolved then + ChooseTyparSolutionAndSolve cenv.css denvAtEnd tp) + +let CheckModuleSignature g (cenv: cenv) m denvAtEnd rootSigOpt implFileTypePriorToSig implFileSpecPriorToSig mexpr = + match rootSigOpt with + | None -> + // Deep copy the inferred type of the module + let implFileTypePriorToSigCopied = copyModuleOrNamespaceType g CloneAll implFileTypePriorToSig + + ModuleOrNamespaceExprWithSig(implFileTypePriorToSigCopied, mexpr, m) + + | Some sigFileType -> + + // We want to show imperative type variables in any types in error messages at this late point + let denv = { denvAtEnd with showImperativeTyparAnnotations=true } + begin + try + + // As typechecked the signature and implementation use different tycons etc. + // Here we (a) check there are enough names, (b) match them up to build a renaming and + // (c) check signature conformance up to this renaming. + if not (SignatureConformance.CheckNamesOfModuleOrNamespace denv cenv.infoReader (mkLocalTyconRef implFileSpecPriorToSig) sigFileType) then + raise (ReportedError None) + + // Compute the remapping from implementation to signature + let remapInfo, _ = ComputeRemappingFromInferredSignatureToExplicitSignature cenv.g implFileTypePriorToSig sigFileType + + let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } + + if not (SignatureConformance.Checker(cenv.g, cenv.amap, denv, remapInfo, true).CheckSignature aenv cenv.infoReader (mkLocalModRef implFileSpecPriorToSig) sigFileType) then ( + // We can just raise 'ReportedError' since CheckModuleOrNamespace raises its own error + raise (ReportedError None) + ) + with e -> errorRecovery e m + end + + ModuleOrNamespaceExprWithSig(sigFileType, mexpr, m) + + +/// Make the initial type checking environment for a single file with an empty accumulator for the overall contents for the file +let MakeInitialEnv env = + // Note: here we allocate a new module type accumulator + let mtypeAcc = ref (Construct.NewEmptyModuleOrNamespaceType Namespace) + { env with eModuleOrNamespaceTypeAccumulator = mtypeAcc }, mtypeAcc + +/// Check an entire implementation file +/// Typecheck, then close the inference scope and then check the file meets its signature (if any) +let TypeCheckOneImplFile + // checkForErrors: A function to help us stop reporting cascading errors + (g, niceNameGen, amap, + topCcu, + openDecls0, + checkForErrors, + conditionalDefines, + tcSink, + isInternalTestSpanStackReferring, + env, + rootSigOpt: ModuleOrNamespaceType option, + synImplFile) = + + let (ParsedImplFileInput (_, isScript, qualNameOfFile, scopedPragmas, _, implFileFrags, isLastCompiland)) = synImplFile + let infoReader = InfoReader(g, amap) + + cancellable { + let cenv = + cenv.Create (g, isScript, niceNameGen, amap, topCcu, false, Option.isSome rootSigOpt, + conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring, + tcSequenceExpressionEntry=TcSequenceExpressionEntry, + tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression, + tcComputationExpression=TcComputationExpression) + + let envinner, mtypeAcc = MakeInitialEnv env + + let defs = [ for x in implFileFrags -> SynModuleDecl.NamespaceFragment x ] + let! mexpr, topAttrs, envAtEnd = TcModuleOrNamespaceElements cenv ParentNone qualNameOfFile.Range envinner PreXmlDoc.Empty None openDecls0 defs + + let implFileTypePriorToSig = mtypeAcc.Value + + let topAttrs = + let mainMethodAttrs, others = topAttrs |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Method <> enum 0) + let assemblyAttrs, others = others |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Assembly <> enum 0) + // REVIEW: consider checking if '_others' is empty + let netModuleAttrs, _others = others |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Module <> enum 0) + { mainMethodAttrs = List.map snd mainMethodAttrs + netModuleAttrs = List.map snd netModuleAttrs + assemblyAttrs = List.map snd assemblyAttrs} + let denvAtEnd = envAtEnd.DisplayEnv + let m = qualNameOfFile.Range + + // This is a fake module spec + let implFileSpecPriorToSig = wrapModuleOrNamespaceType qualNameOfFile.Id (compPathOfCcu topCcu) implFileTypePriorToSig + + let extraAttribs = topAttrs.mainMethodAttrs@topAttrs.netModuleAttrs@topAttrs.assemblyAttrs + + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + ApplyDefaults cenv g denvAtEnd m mexpr extraAttribs) + + // Check completion of all classes defined across this file. + // NOTE: this is not a great technique if inner signatures are permitted to hide + // virtual dispatch slots. + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + try implFileTypePriorToSig |> IterTyconsOfModuleOrNamespaceType (FinalTypeDefinitionChecksAtEndOfInferenceScope (cenv.infoReader, envAtEnd.NameEnv, cenv.tcSink, true, denvAtEnd)) + with e -> errorRecovery e m) + + // Check the value restriction. Only checked if there is no signature. + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + CheckValueRestriction denvAtEnd infoReader rootSigOpt implFileTypePriorToSig m) + + // Solve unsolved internal type variables + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + SolveInternalUnknowns g cenv denvAtEnd mexpr extraAttribs) + + // Check the module matches the signature + let implFileExprAfterSig = + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + CheckModuleSignature g cenv m denvAtEnd rootSigOpt implFileTypePriorToSig implFileSpecPriorToSig mexpr) + + // Run any additional checks registered for post-type-inference + do + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + for check in cenv.postInferenceChecks do + try + check() + with e -> + errorRecovery e m) + + // We ALWAYS run the PostTypeCheckSemanticChecks phase, though we if we have already encountered some + // errors we turn off error reporting. This is because it performs various fixups over the TAST, e.g. + // assigning nice names for inference variables. + let hasExplicitEntryPoint, anonRecdTypes = + + conditionallySuppressErrorReporting (checkForErrors()) (fun () -> + + try + let reportErrors = not (checkForErrors()) + let tcVal = LightweightTcValForUsingInBuildMethodCall g + PostTypeCheckSemanticChecks.CheckTopImpl + (g, cenv.amap, reportErrors, cenv.infoReader, + env.eInternalsVisibleCompPaths, cenv.topCcu, tcVal, envAtEnd.DisplayEnv, + implFileExprAfterSig, extraAttribs, isLastCompiland, + isInternalTestSpanStackReferring) + + with e -> + errorRecovery e m + false, StampMap.Empty) + + // Warn on version attributes. + topAttrs.assemblyAttrs |> List.iter (function + | Attrib(tref, _, [ AttribExpr(Expr.Const (Const.String version, range, _), _) ], _, _, _, _) -> + let attrName = tref.CompiledRepresentationForNamedType.FullName + let isValid() = + try parseILVersion version |> ignore; true + with _ -> false + match attrName with + | "System.Reflection.AssemblyFileVersionAttribute" //TODO compile error like c# compiler? + | "System.Reflection.AssemblyVersionAttribute" when not (isValid()) -> + warning(Error(FSComp.SR.fscBadAssemblyVersion(attrName, version), range)) + | _ -> () + | _ -> ()) + + let implFile = TImplFile (qualNameOfFile, scopedPragmas, implFileExprAfterSig, hasExplicitEntryPoint, isScript, anonRecdTypes) + + return (topAttrs, implFile, implFileTypePriorToSig, envAtEnd, cenv.createsGeneratedProvidedTypes) + } + + + +/// Check an entire signature file +let TypeCheckOneSigFile (g, niceNameGen, amap, topCcu, checkForErrors, conditionalDefines, tcSink, isInternalTestSpanStackReferring) tcEnv (ParsedSigFileInput (_, qualNameOfFile, _, _, sigFileFrags)) = + cancellable { + let cenv = + cenv.Create + (g, false, niceNameGen, amap, topCcu, true, false, conditionalDefines, tcSink, + (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring, + tcSequenceExpressionEntry=TcSequenceExpressionEntry, + tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression, + tcComputationExpression=TcComputationExpression) + + let envinner, mtypeAcc = MakeInitialEnv tcEnv + + let specs = [ for x in sigFileFrags -> SynModuleSigDecl.NamespaceFragment x ] + let! tcEnv = TcSignatureElements cenv ParentNone qualNameOfFile.Range envinner PreXmlDoc.Empty None specs + + let sigFileType = mtypeAcc.Value + + if not (checkForErrors()) then + try sigFileType |> IterTyconsOfModuleOrNamespaceType (FinalTypeDefinitionChecksAtEndOfInferenceScope(cenv.infoReader, tcEnv.NameEnv, cenv.tcSink, false, tcEnv.DisplayEnv)) + with e -> errorRecovery e qualNameOfFile.Range + + return (tcEnv, sigFileType, cenv.createsGeneratedProvidedTypes) + } diff --git a/src/fsharp/CheckDeclarations.fsi b/src/fsharp/CheckDeclarations.fsi new file mode 100644 index 00000000000..2878efca08b --- /dev/null +++ b/src/fsharp/CheckDeclarations.fsi @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CheckDeclarations + +open Internal.Utilities.Library +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Import +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +val AddLocalRootModuleOrNamespace : TcResultsSink -> TcGlobals -> ImportMap -> range -> TcEnv -> ModuleOrNamespaceType -> TcEnv + +val CreateInitialTcEnv: + TcGlobals * + ImportMap * + range * + assemblyName: string * + (CcuThunk * string list * string list) list + -> OpenDeclaration list * TcEnv + +val AddCcuToTcEnv: + TcGlobals * + ImportMap * + range * + TcEnv * + assemblyName: string * + ccu: CcuThunk * + autoOpens: string list * + internalsVisibleToAttributes: string list + -> OpenDeclaration list * TcEnv + +type TopAttribs = + { mainMethodAttrs: Attribs + netModuleAttrs: Attribs + assemblyAttrs: Attribs } + +type ConditionalDefines = string list + +val EmptyTopAttrs : TopAttribs + +val CombineTopAttrs : TopAttribs -> TopAttribs -> TopAttribs + +val TcOpenModuleOrNamespaceDecl: TcResultsSink -> TcGlobals -> ImportMap -> range -> TcEnv -> LongIdent * range -> TcEnv * OpenDeclaration list + +val AddLocalSubModule: g: TcGlobals -> amap: ImportMap -> m: range -> env: TcEnv -> modul: ModuleOrNamespace -> TcEnv + +val TypeCheckOneImplFile: + TcGlobals * + NiceNameGenerator * + ImportMap * + CcuThunk * + OpenDeclaration list * + (unit -> bool) * + ConditionalDefines option * + TcResultsSink * + bool * + TcEnv * + ModuleOrNamespaceType option * + ParsedImplFileInput + -> Cancellable + +val TypeCheckOneSigFile : + TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines option * TcResultsSink * bool + -> TcEnv + -> ParsedSigFileInput + -> Cancellable + +exception ParameterlessStructCtor of range + +exception NotUpperCaseConstructor of range diff --git a/src/fsharp/CheckExpressions.fs b/src/fsharp/CheckExpressions.fs new file mode 100644 index 00000000000..d4b8e08d9d6 --- /dev/null +++ b/src/fsharp/CheckExpressions.fs @@ -0,0 +1,11467 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The typechecker. Left-to-right constrained type checking +/// with generalization at appropriate points. +module internal FSharp.Compiler.CheckExpressions + +open System +open System.Collections.Generic + +open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Library.ResultOrException +open Internal.Utilities.Rational +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.Infos +open FSharp.Compiler.InfoReader +open FSharp.Compiler.MethodCalls +open FSharp.Compiler.MethodOverrides +open FSharp.Compiler.NameResolution +open FSharp.Compiler.PatternMatchCompilation +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypeRelations + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +//------------------------------------------------------------------------- +// Helpers that should be elsewhere +//------------------------------------------------------------------------- + +let mkNilListPat (g: TcGlobals) m ty = TPat_unioncase(g.nil_ucref, [ty], [], m) + +let mkConsListPat (g: TcGlobals) ty ph pt = TPat_unioncase(g.cons_ucref, [ty], [ph;pt], unionRanges ph.Range pt.Range) + +//------------------------------------------------------------------------- +// Errors. +//------------------------------------------------------------------------- + +exception BakedInMemberConstraintName of string * range +exception FunctionExpected of DisplayEnv * TType * range +exception NotAFunction of DisplayEnv * TType * range * range +exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range * bool +exception Recursion of DisplayEnv * Ident * TType * TType * range +exception RecursiveUseCheckedAtRuntime of DisplayEnv * ValRef * range +exception LetRecEvaluatedOutOfOrder of DisplayEnv * ValRef * ValRef * range +exception LetRecCheckedAtRuntime of range +exception LetRecUnsound of DisplayEnv * ValRef list * range +exception TyconBadArgs of DisplayEnv * TyconRef * int * range +exception UnionCaseWrongArguments of DisplayEnv * int * int * range +exception UnionCaseWrongNumberOfArgs of DisplayEnv * int * int * range +exception FieldsFromDifferentTypes of DisplayEnv * RecdFieldRef * RecdFieldRef * range +exception FieldGivenTwice of DisplayEnv * RecdFieldRef * range +exception MissingFields of string list * range +exception FunctionValueUnexpected of DisplayEnv * TType * range +exception UnitTypeExpected of DisplayEnv * TType * range +exception UnitTypeExpectedWithEquality of DisplayEnv * TType * range +exception UnitTypeExpectedWithPossibleAssignment of DisplayEnv * TType * bool * string * range +exception UnitTypeExpectedWithPossiblePropertySetter of DisplayEnv * TType * string * string * range +exception UnionPatternsBindDifferentNames of range +exception VarBoundTwice of Ident +exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range +exception ValNotMutable of DisplayEnv * ValRef * range +exception ValNotLocal of DisplayEnv * ValRef * range +exception InvalidRuntimeCoercion of DisplayEnv * TType * TType * range +exception IndeterminateRuntimeCoercion of DisplayEnv * TType * TType * range +exception IndeterminateStaticCoercion of DisplayEnv * TType * TType * range +exception RuntimeCoercionSourceSealed of DisplayEnv * TType * range +exception CoercionTargetSealed of DisplayEnv * TType * range +exception UpcastUnnecessary of range +exception TypeTestUnnecessary of range +exception StaticCoercionShouldUseBox of DisplayEnv * TType * TType * range +exception SelfRefObjCtor of bool * range +exception VirtualAugmentationOnNullValuedType of range +exception NonVirtualAugmentationOnNullValuedType of range +exception UseOfAddressOfOperator of range +exception DeprecatedThreadStaticBindingWarning of range +exception IntfImplInIntrinsicAugmentation of range +exception IntfImplInExtrinsicAugmentation of range +exception OverrideInIntrinsicAugmentation of range +exception OverrideInExtrinsicAugmentation of range +exception NonUniqueInferredAbstractSlot of TcGlobals * DisplayEnv * string * MethInfo * MethInfo * range +exception StandardOperatorRedefinitionWarning of string * range +exception InvalidInternalsVisibleToAssemblyName of (*badName*)string * (*fileName option*) string option + +/// Represents information about the initialization field used to check that object constructors +/// have completed before fields are accessed. +type SafeInitData = + | SafeInitField of RecdFieldRef * RecdField + | NoSafeInitInfo + +/// Represents information about object constructors +type CtorInfo = + { /// Object model constructors have a very specific form to satisfy .NET limitations. + /// For "new = \arg. { new C with ... }" + /// ctor = 3 indicates about to type check "\arg. (body)", + /// ctor = 2 indicates about to type check "body" + /// ctor = 1 indicates actually type checking the body expression + /// 0 indicates everywhere else, including auxiliary expressions such e1 in "let x = e1 in { new ... }" + /// REVIEW: clean up this rather odd approach ... + ctorShapeCounter: int + + /// A handle to the ref cell to hold results of 'this' for 'type X() as x = ...' and 'new() as x = ...' constructs + /// in case 'x' is used in the arguments to the 'inherits' call. + safeThisValOpt: Val option + + /// A handle to the boolean ref cell to hold success of initialized 'this' for 'type X() as x = ...' constructs + safeInitInfo: SafeInitData + + /// Is the an implicit constructor or an explicit one? + ctorIsImplicit: bool + } + +/// Represents an item in the environment that may restrict the automatic generalization of later +/// declarations because it refers to type inference variables. As type inference progresses +/// these type inference variables may get solved. +[] +type UngeneralizableItem(computeFreeTyvars: unit -> FreeTyvars) = + + // Flag is for: have we determined that this item definitely has + // no free type inference variables? This implies that + // (a) it will _never_ have any free type inference variables as further constraints are added to the system. + // (b) its set of FreeTycons will not change as further constraints are added to the system + let mutable willNeverHaveFreeTypars = false + + // If WillNeverHaveFreeTypars then we can cache the computation of FreeTycons, since they are invariant. + let mutable cachedFreeLocalTycons = emptyFreeTycons + + // If WillNeverHaveFreeTypars then we can cache the computation of FreeTraitSolutions, since they are invariant. + let mutable cachedFreeTraitSolutions = emptyFreeLocals + + member item.GetFreeTyvars() = + let fvs = computeFreeTyvars() + if fvs.FreeTypars.IsEmpty then + willNeverHaveFreeTypars <- true + cachedFreeLocalTycons <- fvs.FreeTycons + cachedFreeTraitSolutions <- fvs.FreeTraitSolutions + fvs + + member item.WillNeverHaveFreeTypars = willNeverHaveFreeTypars + + member item.CachedFreeLocalTycons = cachedFreeLocalTycons + + member item.CachedFreeTraitSolutions = cachedFreeTraitSolutions + +/// Represents the type environment at a particular scope. Includes the name +/// resolution environment, the ungeneralizable items from earlier in the scope +/// and other information about the scope. +[] +type TcEnv = + { /// Name resolution information + eNameResEnv: NameResolutionEnv + + /// The list of items in the environment that may contain free inference + /// variables (which may not be generalized). The relevant types may + /// change as a result of inference equations being asserted, hence may need to + /// be recomputed. + eUngeneralizableItems: UngeneralizableItem list + + // Two (!) versions of the current module path + // These are used to: + // - Look up the appropriate point in the corresponding signature + // see if an item is public or not + // - Change fslib canonical module type to allow compiler references to these items + // - Record the cpath for concrete modul_specs, tycon_specs and excon_specs so they can cache their generated IL representation where necessary + // - Record the pubpath of public, concrete {val, tycon, modul, excon}_specs. + // This information is used mainly when building non-local references + // to public items. + // + // Of the two, 'ePath' is the one that's barely used. It's only + // used by UpdateAccModuleOrNamespaceType to modify the CCU while compiling FSharp.Core + ePath: Ident list + + eCompPath: CompilationPath + + eAccessPath: CompilationPath + + /// This field is computed from other fields, but we amortize the cost of computing it. + eAccessRights: AccessorDomain + + /// Internals under these should be accessible + eInternalsVisibleCompPaths: CompilationPath list + + /// Mutable accumulator for the current module type + eModuleOrNamespaceTypeAccumulator: ModuleOrNamespaceType ref + + /// Context information for type checker + eContextInfo: ContextInfo + + /// Here Some tcref indicates we can access protected members in all super types + eFamilyType: TyconRef option + + // Information to enforce special restrictions on valid expressions + // for .NET constructors. + eCtorInfo: CtorInfo option + + eCallerMemberName: string option + + // Active arg infos in iterated lambdas , allowing us to determine the attributes of arguments + eLambdaArgInfos: ArgReprInfo list list + } + + member tenv.DisplayEnv = tenv.eNameResEnv.DisplayEnv + + member tenv.NameEnv = tenv.eNameResEnv + + member tenv.AccessRights = tenv.eAccessRights + + override tenv.ToString() = "TcEnv(...)" + +/// Compute the available access rights from a particular location in code +let ComputeAccessRights eAccessPath eInternalsVisibleCompPaths eFamilyType = + AccessibleFrom (eAccessPath :: eInternalsVisibleCompPaths, eFamilyType) + +//------------------------------------------------------------------------- +// Helpers related to determining if we're in a constructor and/or a class +// that may be able to access "protected" members. +//------------------------------------------------------------------------- + +let InitialExplicitCtorInfo (safeThisValOpt, safeInitInfo) = + { ctorShapeCounter = 3 + safeThisValOpt = safeThisValOpt + safeInitInfo = safeInitInfo + ctorIsImplicit = false} + +let InitialImplicitCtorInfo () = + { ctorShapeCounter = 0 + safeThisValOpt = None + safeInitInfo = NoSafeInitInfo + ctorIsImplicit = true } + +let EnterFamilyRegion tcref env = + let eFamilyType = Some tcref + { env with + eAccessRights = ComputeAccessRights env.eAccessPath env.eInternalsVisibleCompPaths eFamilyType // update this computed field + eFamilyType = eFamilyType } + +let ExitFamilyRegion env = + let eFamilyType = None + match env.eFamilyType with + | None -> env // optimization to avoid reallocation + | _ -> + { env with + eAccessRights = ComputeAccessRights env.eAccessPath env.eInternalsVisibleCompPaths eFamilyType // update this computed field + eFamilyType = eFamilyType } + +let AreWithinCtorShape env = match env.eCtorInfo with None -> false | Some ctorInfo -> ctorInfo.ctorShapeCounter > 0 +let AreWithinImplicitCtor env = match env.eCtorInfo with None -> false | Some ctorInfo -> ctorInfo.ctorIsImplicit +let GetCtorShapeCounter env = match env.eCtorInfo with None -> 0 | Some ctorInfo -> ctorInfo.ctorShapeCounter +let GetRecdInfo env = match env.eCtorInfo with None -> RecdExpr | Some ctorInfo -> if ctorInfo.ctorShapeCounter = 1 then RecdExprIsObjInit else RecdExpr + +let AdjustCtorShapeCounter f env = {env with eCtorInfo = Option.map (fun ctorInfo -> { ctorInfo with ctorShapeCounter = f ctorInfo.ctorShapeCounter }) env.eCtorInfo } +let ExitCtorShapeRegion env = AdjustCtorShapeCounter (fun _ -> 0) env + +/// Add a type to the TcEnv, i.e. register it as ungeneralizable. +let addFreeItemOfTy ty eUngeneralizableItems = + let fvs = freeInType CollectAllNoCaching ty + if isEmptyFreeTyvars fvs then eUngeneralizableItems + else UngeneralizableItem(fun () -> freeInType CollectAllNoCaching ty) :: eUngeneralizableItems + +/// Add the contents of a module type to the TcEnv, i.e. register the contents as ungeneralizable. +/// Add a module type to the TcEnv, i.e. register it as ungeneralizable. +let addFreeItemOfModuleTy mtyp eUngeneralizableItems = + let fvs = freeInModuleTy mtyp + if isEmptyFreeTyvars fvs then eUngeneralizableItems + else UngeneralizableItem(fun () -> freeInModuleTy mtyp) :: eUngeneralizableItems + +/// Add a table of values to the name resolution environment. +let AddValMapToNameEnv g vs nenv = + NameMap.foldBackRange (fun v nenv -> AddValRefToNameEnv g nenv (mkLocalValRef v)) vs nenv + +/// Add a list of values to the name resolution environment. +let AddValListToNameEnv g vs nenv = + List.foldBack (fun v nenv -> AddValRefToNameEnv g nenv (mkLocalValRef v)) vs nenv + +/// Add a local value to TcEnv +let AddLocalValPrimitive g (v: Val) env = + { env with + eNameResEnv = AddValRefToNameEnv g env.eNameResEnv (mkLocalValRef v) + eUngeneralizableItems = addFreeItemOfTy v.Type env.eUngeneralizableItems } + +/// Add a table of local values to TcEnv +let AddLocalValMap g tcSink scopem (vals: Val NameMap) env = + let env = + if vals.IsEmpty then + env + else + { env with + eNameResEnv = AddValMapToNameEnv g vals env.eNameResEnv + eUngeneralizableItems = NameMap.foldBackRange (typeOfVal >> addFreeItemOfTy) vals env.eUngeneralizableItems } + CallEnvSink tcSink (scopem, env.NameEnv, env.AccessRights) + env + +/// Add a list of local values to TcEnv and report them to the sink +let AddLocalVals g tcSink scopem (vals: Val list) env = + let env = + if isNil vals then + env + else + { env with + eNameResEnv = AddValListToNameEnv g vals env.eNameResEnv + eUngeneralizableItems = List.foldBack (typeOfVal >> addFreeItemOfTy) vals env.eUngeneralizableItems } + CallEnvSink tcSink (scopem, env.NameEnv, env.AccessRights) + env + +/// Add a local value to TcEnv and report it to the sink +let AddLocalVal g tcSink scopem v env = + let env = { env with + eNameResEnv = AddValRefToNameEnv g env.eNameResEnv (mkLocalValRef v) + eUngeneralizableItems = addFreeItemOfTy v.Type env.eUngeneralizableItems } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + env + +/// Add a set of explicitly declared type parameters as being available in the TcEnv +let AddDeclaredTypars check typars env = + if isNil typars then env else + let env = { env with eNameResEnv = AddDeclaredTyparsToNameEnv check env.eNameResEnv typars } + { env with eUngeneralizableItems = List.foldBack (mkTyparTy >> addFreeItemOfTy) typars env.eUngeneralizableItems } + +/// Environment of implicitly scoped type parameters, e.g. 'a in "(x: 'a)" + +type UnscopedTyparEnv = UnscopedTyparEnv of NameMap + +let emptyUnscopedTyparEnv: UnscopedTyparEnv = UnscopedTyparEnv Map.empty + +let AddUnscopedTypar n p (UnscopedTyparEnv tab) = UnscopedTyparEnv (Map.add n p tab) + +let TryFindUnscopedTypar n (UnscopedTyparEnv tab) = Map.tryFind n tab + +let HideUnscopedTypars typars (UnscopedTyparEnv tab) = + UnscopedTyparEnv (List.fold (fun acc (tp: Typar) -> Map.remove tp.Name acc) tab typars) + +/// Represents the compilation environment for typechecking a single file in an assembly. +[] +type TcFileState = + { g: TcGlobals + + /// Push an entry every time a recursive value binding is used, + /// in order to be able to fix up recursive type applications as + /// we infer type parameters + mutable recUses: ValMultiMap + + /// Checks to run after all inference is complete. + mutable postInferenceChecks: ResizeArray unit> + + /// Set to true if this file causes the creation of generated provided types. + mutable createsGeneratedProvidedTypes: bool + + /// Are we in a script? if so relax the reporting of discarded-expression warnings at the top level + isScript: bool + + /// Environment needed to convert IL types to F# types in the importer. + amap: Import.ImportMap + + /// Used to generate new syntactic argument names in post-parse syntactic processing + synArgNameGenerator: SynArgNameGenerator + + tcSink: TcResultsSink + + /// Holds a reference to the component being compiled. + /// This field is very rarely used (mainly when fixing up forward references to fslib. + topCcu: CcuThunk + + /// Holds the current inference constraints + css: ConstraintSolverState + + /// Are we compiling the signature of a module from fslib? + compilingCanonicalFslibModuleType: bool + + /// Is this a .fsi file? + isSig: bool + + /// Does this .fs file have a .fsi file? + haveSig: bool + + /// Used to generate names + niceNameGen: NiceNameGenerator + + /// Used to read and cache information about types and members + infoReader: InfoReader + + /// Used to resolve names + nameResolver: NameResolver + + /// The set of active conditional defines. The value is None when conditional erasure is disabled in tooling. + conditionalDefines: string list option + + isInternalTestSpanStackReferring: bool + // forward call + TcSequenceExpressionEntry: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv + + // forward call + TcArrayOrListComputedExpression: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv + + // forward call + TcComputationExpression: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> range * Expr * TType * SynExpr -> Expr * UnscopedTyparEnv + } + + /// Create a new compilation environment + static member Create + (g, isScript, niceNameGen, amap, topCcu, isSig, haveSig, conditionalDefines, tcSink, tcVal, isInternalTestSpanStackReferring, + tcSequenceExpressionEntry, tcArrayOrListSequenceExpression, tcComputationExpression) = + let infoReader = InfoReader(g, amap) + let instantiationGenerator m tpsorig = FreshenTypars m tpsorig + let nameResolver = NameResolver(g, amap, infoReader, instantiationGenerator) + { g = g + amap = amap + recUses = ValMultiMap<_>.Empty + postInferenceChecks = ResizeArray() + createsGeneratedProvidedTypes = false + topCcu = topCcu + isScript = isScript + css = ConstraintSolverState.New(g, amap, infoReader, tcVal) + infoReader = infoReader + tcSink = tcSink + nameResolver = nameResolver + niceNameGen = niceNameGen + synArgNameGenerator = SynArgNameGenerator() + isSig = isSig + haveSig = haveSig + compilingCanonicalFslibModuleType = (isSig || not haveSig) && g.compilingFslib + conditionalDefines = conditionalDefines + isInternalTestSpanStackReferring = isInternalTestSpanStackReferring + TcSequenceExpressionEntry = tcSequenceExpressionEntry + TcArrayOrListComputedExpression = tcArrayOrListSequenceExpression + TcComputationExpression = tcComputationExpression + } + + override _.ToString() = "" + +type cenv = TcFileState + +let CopyAndFixupTypars m rigid tpsorig = + FreshenAndFixupTypars m rigid [] [] tpsorig + +let UnifyTypes cenv (env: TcEnv) m actualTy expectedTy = + AddCxTypeEqualsType env.eContextInfo env.DisplayEnv cenv.css m (tryNormalizeMeasureInType cenv.g actualTy) (tryNormalizeMeasureInType cenv.g expectedTy) + +// If the overall type admits subsumption or type directed conversion, and the original unify would have failed, +// then allow subsumption or type directed conversion. +// +// Any call to UnifyOverallType MUST have a matching call to TcAdjustExprForTypeDirectedConversions +// to actually build the expression for any conversion applied. +let UnifyOverallType cenv (env: TcEnv) m overallTy actualTy = + match overallTy with + | MustConvertTo(isMethodArg, reqdTy) when cenv.g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> + let actualTy = tryNormalizeMeasureInType cenv.g actualTy + let reqdTy = tryNormalizeMeasureInType cenv.g reqdTy + if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m reqdTy actualTy then + () + else + // try adhoc type-directed conversions + let reqdTy2, usesTDC, eqn = AdjustRequiredTypeForTypeDirectedConversions cenv.infoReader env.eAccessRights isMethodArg false reqdTy actualTy m + match eqn with + | Some (ty1, ty2, msg) -> + UnifyTypes cenv env m ty1 ty2 + msg env.DisplayEnv + | None -> () + match usesTDC with + | TypeDirectedConversionUsed.Yes warn -> warning(warn env.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + if AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m reqdTy2 actualTy then + let reqdTyText, actualTyText, _cxs = NicePrint.minimalStringsOfTwoTypes env.DisplayEnv reqdTy actualTy + warning (Error(FSComp.SR.tcSubsumptionImplicitConversionUsed(actualTyText, reqdTyText), m)) + else + // report the error + UnifyTypes cenv env m reqdTy actualTy + | _ -> + UnifyTypes cenv env m overallTy.Commit actualTy + +let UnifyOverallTypeAndRecover cenv env m overallTy actualTy = + try + UnifyOverallType cenv env m overallTy actualTy + with e -> + errorRecovery e m + +// Calls UnifyTypes, but upon error only does the minimal error recovery +// so that IntelliSense information can continue to be collected. +let UnifyTypesAndRecover cenv env m expectedTy actualTy = + try + UnifyTypes cenv env m expectedTy actualTy + with e -> + errorRecovery e m + +/// Make an environment suitable for a module or namespace. Does not create a new accumulator but uses one we already have/ +let MakeInnerEnvWithAcc addOpenToNameEnv env nm mtypeAcc modKind = + let path = env.ePath @ [nm] + let cpath = env.eCompPath.NestedCompPath nm.idText modKind + { env with + ePath = path + eCompPath = cpath + eAccessPath = cpath + eAccessRights = ComputeAccessRights cpath env.eInternalsVisibleCompPaths env.eFamilyType // update this computed field + eNameResEnv = + if addOpenToNameEnv then + { env.NameEnv with eDisplayEnv = env.DisplayEnv.AddOpenPath (pathOfLid path) } + else + env.NameEnv + eModuleOrNamespaceTypeAccumulator = mtypeAcc } + +/// Make an environment suitable for a module or namespace, creating a new accumulator. +let MakeInnerEnv addOpenToNameEnv env nm modKind = + // Note: here we allocate a new module type accumulator + let mtypeAcc = ref (Construct.NewEmptyModuleOrNamespaceType modKind) + MakeInnerEnvWithAcc addOpenToNameEnv env nm mtypeAcc modKind, mtypeAcc + +/// Make an environment suitable for processing inside a type definition +let MakeInnerEnvForTyconRef env tcref isExtrinsicExtension = + if isExtrinsicExtension then + // Extension members don't get access to protected stuff + env + else + // Regular members get access to protected stuff + let env = EnterFamilyRegion tcref env + // Note: assumes no nesting + let eAccessPath = env.eCompPath.NestedCompPath tcref.LogicalName ModuleOrType + { env with + eAccessRights = ComputeAccessRights eAccessPath env.eInternalsVisibleCompPaths env.eFamilyType // update this computed field + eAccessPath = eAccessPath } + +/// Make an environment suitable for processing inside a member definition +let MakeInnerEnvForMember env (v: Val) = + match v.MemberInfo with + | None -> env + | Some _ -> MakeInnerEnvForTyconRef env v.MemberApparentEntity v.IsExtensionMember + +/// Get the current accumulator for the namespace/module we're in +let GetCurrAccumulatedModuleOrNamespaceType env = + env.eModuleOrNamespaceTypeAccumulator.Value + +/// Set the current accumulator for the namespace/module we're in, updating the inferred contents +let SetCurrAccumulatedModuleOrNamespaceType env x = + env.eModuleOrNamespaceTypeAccumulator.Value <- x + +/// Set up the initial environment accounting for the enclosing "namespace X.Y.Z" definition +let LocateEnv ccu env enclosingNamespacePath = + let cpath = compPathOfCcu ccu + let env = + {env with + ePath = [] + eCompPath = cpath + eAccessPath = cpath + // update this computed field + eAccessRights = ComputeAccessRights cpath env.eInternalsVisibleCompPaths env.eFamilyType } + let env = List.fold (fun env id -> MakeInnerEnv false env id Namespace |> fst) env enclosingNamespacePath + let env = { env with eNameResEnv = { env.NameEnv with eDisplayEnv = env.DisplayEnv.AddOpenPath (pathOfLid env.ePath) } } + env + +//------------------------------------------------------------------------- +// Helpers for unification +//------------------------------------------------------------------------- + +/// When the context is matching the oldRange then this function shrinks it to newRange. +/// This can be used to change context over no-op expressions like parens. +let ShrinkContext env oldRange newRange = + match env.eContextInfo with + | ContextInfo.NoContext + | ContextInfo.RecordFields + | ContextInfo.TupleInRecordFields + | ContextInfo.ReturnInComputationExpression + | ContextInfo.YieldInComputationExpression + | ContextInfo.RuntimeTypeTest _ + | ContextInfo.DowncastUsedInsteadOfUpcast _ + | ContextInfo.SequenceExpression _ -> + env + | ContextInfo.CollectionElement (b,m) -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.CollectionElement(b,newRange) } + | ContextInfo.FollowingPatternMatchClause m -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.FollowingPatternMatchClause newRange } + | ContextInfo.PatternMatchGuard m -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.PatternMatchGuard newRange } + | ContextInfo.IfExpression m -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.IfExpression newRange } + | ContextInfo.OmittedElseBranch m -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.OmittedElseBranch newRange } + | ContextInfo.ElseBranchResult m -> + if not (equals m oldRange) then env else + { env with eContextInfo = ContextInfo.ElseBranchResult newRange } + +/// Optimized unification routine that avoids creating new inference +/// variables unnecessarily +let UnifyRefTupleType contextInfo cenv denv m ty ps = + let ptys = + if isRefTupleTy cenv.g ty then + let ptys = destRefTupleTy cenv.g ty + if List.length ps = List.length ptys then ptys + else NewInferenceTypes ps + else NewInferenceTypes ps + + let contextInfo = + match contextInfo with + | ContextInfo.RecordFields -> ContextInfo.TupleInRecordFields + | _ -> contextInfo + + AddCxTypeEqualsType contextInfo denv cenv.css m ty (TType_tuple (tupInfoRef, ptys)) + ptys + +/// Allow the inference of structness from the known type, e.g. +/// let (x: struct (int * int)) = (3,4) +let UnifyTupleTypeAndInferCharacteristics contextInfo cenv denv m knownTy isExplicitStruct ps = + let tupInfo, ptys = + if isAnyTupleTy cenv.g knownTy then + let tupInfo, ptys = destAnyTupleTy cenv.g knownTy + let tupInfo = (if isExplicitStruct then tupInfoStruct else tupInfo) + let ptys = + if List.length ps = List.length ptys then ptys + else NewInferenceTypes ps + tupInfo, ptys + else + mkTupInfo isExplicitStruct, NewInferenceTypes ps + + let contextInfo = + match contextInfo with + | ContextInfo.RecordFields -> ContextInfo.TupleInRecordFields + | _ -> contextInfo + + let ty2 = TType_tuple (tupInfo, ptys) + AddCxTypeEqualsType contextInfo denv cenv.css m knownTy ty2 + tupInfo, ptys + +// Allow inference of assembly-affinity and structness from the known type - even from another assembly. This is a rule of +// the language design and allows effective cross-assembly use of anonymous types in some limited circumstances. +let UnifyAnonRecdTypeAndInferCharacteristics contextInfo cenv denv m ty isExplicitStruct unsortedNames = + let anonInfo, ptys = + match tryDestAnonRecdTy cenv.g ty with + | ValueSome (anonInfo, ptys) -> + // Note: use the assembly of the known type, not the current assembly + // Note: use the structness of the known type, unless explicit + // Note: use the names of our type, since they are always explicit + let tupInfo = (if isExplicitStruct then tupInfoStruct else anonInfo.TupInfo) + let anonInfo = AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo, unsortedNames) + let ptys = + if List.length ptys = Array.length unsortedNames then ptys + else NewInferenceTypes (Array.toList anonInfo.SortedNames) + anonInfo, ptys + | ValueNone -> + // Note: no known anonymous record type - use our assembly + let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, mkTupInfo isExplicitStruct, unsortedNames) + anonInfo, NewInferenceTypes (Array.toList anonInfo.SortedNames) + let ty2 = TType_anon (anonInfo, ptys) + AddCxTypeEqualsType contextInfo denv cenv.css m ty ty2 + anonInfo, ptys + + +/// Optimized unification routine that avoids creating new inference +/// variables unnecessarily +let UnifyFunctionTypeUndoIfFailed cenv denv m ty = + match tryDestFunTy cenv.g ty with + | ValueNone -> + let domainTy = NewInferenceType () + let resultTy = NewInferenceType () + if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty (domainTy --> resultTy) then + ValueSome(domainTy, resultTy) + else + ValueNone + | r -> r + +/// Optimized unification routine that avoids creating new inference +/// variables unnecessarily +let UnifyFunctionType extraInfo cenv denv mFunExpr ty = + match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr ty with + | ValueSome res -> res + | ValueNone -> + match extraInfo with + | Some argm -> error (NotAFunction(denv, ty, mFunExpr, argm)) + | None -> error (FunctionExpected(denv, ty, mFunExpr)) + +let ReportImplicitlyIgnoredBoolExpression denv m ty expr = + let checkExpr m expr = + match expr with + | Expr.App (Expr.Val (vf, _, _), _, _, exprs, _) when vf.LogicalName = opNameEquals -> + match exprs with + | Expr.App (Expr.Val (propRef, _, _), _, _, Expr.Val (vf, _, _) :: _, _) :: _ -> + if propRef.IsPropertyGetterMethod then + let propertyName = propRef.PropertyName + let hasCorrespondingSetter = + match propRef.DeclaringEntity with + | Parent entityRef -> + entityRef.MembersOfFSharpTyconSorted + |> List.exists (fun valRef -> valRef.IsPropertySetterMethod && valRef.PropertyName = propertyName) + | _ -> false + + if hasCorrespondingSetter then + UnitTypeExpectedWithPossiblePropertySetter (denv, ty, vf.DisplayName, propertyName, m) + else + UnitTypeExpectedWithEquality (denv, ty, m) + else + UnitTypeExpectedWithEquality (denv, ty, m) + | Expr.Op (TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, _, _, _), _, Expr.Val (vf, _, _) :: _, _) :: _ when ilMethRef.Name.StartsWithOrdinal("get_") -> + UnitTypeExpectedWithPossiblePropertySetter (denv, ty, vf.DisplayName, ChopPropertyName(ilMethRef.Name), m) + | Expr.Val (vf, _, _) :: _ -> + UnitTypeExpectedWithPossibleAssignment (denv, ty, vf.IsMutable, vf.DisplayName, m) + | _ -> UnitTypeExpectedWithEquality (denv, ty, m) + | _ -> UnitTypeExpected (denv, ty, m) + + match expr with + | Expr.Let (_, Expr.Sequential (_, inner, _, _, _), _, _) + | Expr.Sequential (_, inner, _, _, _) -> + let rec extractNext expr = + match expr with + | Expr.Sequential (_, inner, _, _, _) -> extractNext inner + | _ -> checkExpr expr.Range expr + extractNext inner + | expr -> checkExpr m expr + +let UnifyUnitType cenv (env: TcEnv) m ty expr = + let denv = env.DisplayEnv + if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty cenv.g.unit_ty then + true + else + let domainTy = NewInferenceType () + let resultTy = NewInferenceType () + if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty (domainTy --> resultTy) then + warning (FunctionValueUnexpected(denv, ty, m)) + else + let reportImplicitlyDiscardError() = + if typeEquiv cenv.g cenv.g.bool_ty ty then + warning (ReportImplicitlyIgnoredBoolExpression denv m ty expr) + else + warning (UnitTypeExpected (denv, ty, m)) + + match env.eContextInfo with + | ContextInfo.SequenceExpression seqTy -> + let lifted = mkSeqTy cenv.g ty + if typeEquiv cenv.g seqTy lifted then + warning (Error (FSComp.SR.implicitlyDiscardedInSequenceExpression(NicePrint.prettyStringOfTy denv ty), m)) + else + if isListTy cenv.g ty || isArrayTy cenv.g ty || typeEquiv cenv.g seqTy ty then + warning (Error (FSComp.SR.implicitlyDiscardedSequenceInSequenceExpression(NicePrint.prettyStringOfTy denv ty), m)) + else + reportImplicitlyDiscardError() + | _ -> + reportImplicitlyDiscardError() + + false + +let TryUnifyUnitTypeWithoutWarning cenv (env:TcEnv) m ty = + let denv = env.DisplayEnv + AddCxTypeEqualsTypeUndoIfFailedOrWarnings denv cenv.css m ty cenv.g.unit_ty + +// Logically extends System.AttributeTargets +module AttributeTargets = + let FieldDecl = AttributeTargets.Field ||| AttributeTargets.Property + let FieldDeclRestricted = AttributeTargets.Field + let UnionCaseDecl = AttributeTargets.Method ||| AttributeTargets.Property + let TyconDecl = AttributeTargets.Class ||| AttributeTargets.Interface ||| AttributeTargets.Delegate ||| AttributeTargets.Struct ||| AttributeTargets.Enum + let ExnDecl = AttributeTargets.Class + let ModuleDecl = AttributeTargets.Class + let Top = AttributeTargets.Assembly ||| AttributeTargets.Module ||| AttributeTargets.Method + +let ForNewConstructors tcSink (env: TcEnv) mObjTy methodName meths = + let origItem = Item.CtorGroup(methodName, meths) + let callSink (item, minst) = CallMethodGroupNameResolutionSink tcSink (mObjTy, env.NameEnv, item, origItem, minst, ItemOccurence.Use, env.AccessRights) + let sendToSink minst refinedMeths = callSink (Item.CtorGroup(methodName, refinedMeths), minst) + match meths with + | [] -> + AfterResolution.DoNothing + | [_] -> + sendToSink emptyTyparInst meths + AfterResolution.DoNothing + | _ -> + AfterResolution.RecordResolution (None, (fun tpinst -> callSink (origItem, tpinst)), (fun (minfo, _, minst) -> sendToSink minst [minfo]), (fun () -> callSink (origItem, emptyTyparInst))) + + +/// Typecheck rational constant terms in units-of-measure exponents +let rec TcSynRationalConst c = + match c with + | SynRationalConst.Integer i -> intToRational i + | SynRationalConst.Negate c' -> NegRational (TcSynRationalConst c') + | SynRationalConst.Rational(p, q, _) -> DivRational (intToRational p) (intToRational q) + +/// Typecheck constant terms in expressions and patterns +let TcConst cenv (overallTy: TType) m env c = + let rec tcMeasure ms = + match ms with + | SynMeasure.One -> Measure.One + | SynMeasure.Named(tc, m) -> + let ad = env.eAccessRights + let _, tcref = ForceRaise(ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Use OpenQualified env.eNameResEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No) + match tcref.TypeOrMeasureKind with + | TyparKind.Type -> error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) + | TyparKind.Measure -> Measure.Con tcref + + | SynMeasure.Power(ms, exponent, _) -> Measure.RationalPower (tcMeasure ms, TcSynRationalConst exponent) + | SynMeasure.Product(ms1, ms2, _) -> Measure.Prod(tcMeasure ms1, tcMeasure ms2) + | SynMeasure.Divide(ms1, (SynMeasure.Seq (_ :: _ :: _, _) as ms2), m) -> + warning(Error(FSComp.SR.tcImplicitMeasureFollowingSlash(), m)) + Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2)) + | SynMeasure.Divide(ms1, ms2, _) -> + Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2)) + | SynMeasure.Seq(mss, _) -> ProdMeasures (List.map tcMeasure mss) + | SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), m)) + | SynMeasure.Var(_, m) -> error(Error(FSComp.SR.tcNonZeroConstantCannotHaveGenericUnit(), m)) + + let unif expected = UnifyTypes cenv env m overallTy expected + + let unifyMeasureArg iszero tcr c = + let measureTy = + match c with + | SynConst.Measure(_, _, SynMeasure.Anon _) -> + (mkAppTy tcr [TType_measure (Measure.Var (NewAnonTypar (TyparKind.Measure, m, TyparRigidity.Anon, (if iszero then TyparStaticReq.None else TyparStaticReq.HeadType), TyparDynamicReq.No)))]) + + | SynConst.Measure(_, _, ms) -> mkAppTy tcr [TType_measure (tcMeasure ms)] + | _ -> mkAppTy tcr [TType_measure Measure.One] + unif measureTy + + let expandedMeasurablesEnabled = + cenv.g.langVersion.SupportsFeature LanguageFeature.ExpandedMeasurables + + match c with + | SynConst.Unit -> unif cenv.g.unit_ty; Const.Unit + | SynConst.Bool i -> unif cenv.g.bool_ty; Const.Bool i + | SynConst.Single f -> unif cenv.g.float32_ty; Const.Single f + | SynConst.Double f -> unif cenv.g.float_ty; Const.Double f + | SynConst.Decimal f -> unif (mkAppTy cenv.g.decimal_tcr []); Const.Decimal f + | SynConst.SByte i -> unif cenv.g.sbyte_ty; Const.SByte i + | SynConst.Int16 i -> unif cenv.g.int16_ty; Const.Int16 i + | SynConst.Int32 i -> unif cenv.g.int_ty; Const.Int32 i + | SynConst.Int64 i -> unif cenv.g.int64_ty; Const.Int64 i + | SynConst.IntPtr i -> unif cenv.g.nativeint_ty; Const.IntPtr i + | SynConst.Byte i -> unif cenv.g.byte_ty; Const.Byte i + | SynConst.UInt16 i -> unif cenv.g.uint16_ty; Const.UInt16 i + | SynConst.UInt32 i -> unif cenv.g.uint32_ty; Const.UInt32 i + | SynConst.UInt64 i -> unif cenv.g.uint64_ty; Const.UInt64 i + | SynConst.UIntPtr i -> unif cenv.g.unativeint_ty; Const.UIntPtr i + | SynConst.Measure(SynConst.Single f, _, _) -> unifyMeasureArg (f=0.0f) cenv.g.pfloat32_tcr c; Const.Single f + | SynConst.Measure(SynConst.Double f, _, _) -> unifyMeasureArg (f=0.0) cenv.g.pfloat_tcr c; Const.Double f + | SynConst.Measure(SynConst.Decimal f, _, _) -> unifyMeasureArg false cenv.g.pdecimal_tcr c; Const.Decimal f + | SynConst.Measure(SynConst.SByte i, _, _) -> unifyMeasureArg (i=0y) cenv.g.pint8_tcr c; Const.SByte i + | SynConst.Measure(SynConst.Int16 i, _, _) -> unifyMeasureArg (i=0s) cenv.g.pint16_tcr c; Const.Int16 i + | SynConst.Measure(SynConst.Int32 i, _, _) -> unifyMeasureArg (i=0) cenv.g.pint_tcr c; Const.Int32 i + | SynConst.Measure(SynConst.Int64 i, _, _) -> unifyMeasureArg (i=0L) cenv.g.pint64_tcr c; Const.Int64 i + | SynConst.Measure(SynConst.IntPtr i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0L) cenv.g.pnativeint_tcr c; Const.IntPtr i + | SynConst.Measure(SynConst.Byte i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0uy) cenv.g.puint8_tcr c; Const.Byte i + | SynConst.Measure(SynConst.UInt16 i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0us) cenv.g.puint16_tcr c; Const.UInt16 i + | SynConst.Measure(SynConst.UInt32 i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0u) cenv.g.puint_tcr c; Const.UInt32 i + | SynConst.Measure(SynConst.UInt64 i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0UL) cenv.g.puint64_tcr c; Const.UInt64 i + | SynConst.Measure(SynConst.UIntPtr i, _, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0UL) cenv.g.punativeint_tcr c; Const.UIntPtr i + | SynConst.Char c -> unif cenv.g.char_ty; Const.Char c + | SynConst.String (s, _, _) + | SynConst.SourceIdentifier (_, s, _) -> unif cenv.g.string_ty; Const.String s + | SynConst.UserNum _ -> error (InternalError(FSComp.SR.tcUnexpectedBigRationalConstant(), m)) + | SynConst.Measure _ -> error (Error(FSComp.SR.tcInvalidTypeForUnitsOfMeasure(), m)) + | SynConst.UInt16s _ -> error (InternalError(FSComp.SR.tcUnexpectedConstUint16Array(), m)) + | SynConst.Bytes _ -> error (InternalError(FSComp.SR.tcUnexpectedConstByteArray(), m)) + +/// Convert an Abstract IL ILFieldInit value read from .NET metadata to a TAST constant +let TcFieldInit (_m: range) lit = ilFieldToTastConst lit + +//------------------------------------------------------------------------- +// Arities. These serve two roles in the system: +// 1. syntactic arities come from the syntactic forms found +// signature files and the syntactic forms of function and member definitions. +// 2. compiled arities representing representation choices w.r.t. internal representations of +// functions and members. +//------------------------------------------------------------------------- + +// Adjust the arities that came from the parsing of the toptyp (arities) to be a valSynData. +// This means replacing the "[unitArg]" arising from a "unit -> ty" with a "[]". +let AdjustValSynInfoInSignature g ty (SynValInfo(argsData, retData) as sigMD) = + if argsData.Length = 1 && argsData.Head.Length = 1 && isFunTy g ty && typeEquiv g g.unit_ty (domainOfFunTy g ty) then + SynValInfo(argsData.Head.Tail :: argsData.Tail, retData) + else + sigMD + +/// The ValReprInfo for a value, except the number of typars is not yet inferred +type PartialValReprInfo = + | PartialValReprInfo of + curriedArgInfos: ArgReprInfo list list * + returnInfo: ArgReprInfo + +let TranslateTopArgSynInfo isArg m tcAttributes (SynArgInfo(Attributes attrs, isOpt, nm)) = + // Synthesize an artificial "OptionalArgument" attribute for the parameter + let optAttrs = + if isOpt then + [ ( { TypeName=LongIdentWithDots(pathToSynLid m ["Microsoft";"FSharp";"Core";"OptionalArgument"], []) + ArgExpr=mkSynUnit m + Target=None + AppliesToGetterAndSetter=false + Range=m} : SynAttribute) ] + else + [] + + if isArg && not (isNil attrs) && Option.isNone nm then + errorR(Error(FSComp.SR.tcParameterRequiresName(), m)) + + if not isArg && Option.isSome nm then + errorR(Error(FSComp.SR.tcReturnValuesCannotHaveNames(), m)) + + // Call the attribute checking function + let attribs = tcAttributes (optAttrs@attrs) + ({ Attribs = attribs; Name = nm } : ArgReprInfo) + +/// Members have an arity inferred from their syntax. This "valSynData" is not quite the same as the arities +/// used in the middle and backends of the compiler ("topValInfo"). +/// "0" in a valSynData (see arity_of_pat) means a "unit" arg in a topValInfo +/// Hence remove all "zeros" from arity and replace them with 1 here. +/// Note we currently use the compiled form for choosing unique names, to distinguish overloads because this must match up +/// between signature and implementation, and the signature just has "unit". +let TranslateTopValSynInfo m tcAttributes (SynValInfo(argsData, retData)) = + PartialValReprInfo (argsData |> List.mapSquared (TranslateTopArgSynInfo true m (tcAttributes AttributeTargets.Parameter)), + retData |> TranslateTopArgSynInfo false m (tcAttributes AttributeTargets.ReturnValue)) + +let TranslatePartialArity tps (PartialValReprInfo (argsData, retData)) = + ValReprInfo(ValReprInfo.InferTyparInfo tps, argsData, retData) + +//------------------------------------------------------------------------- +// Members +//------------------------------------------------------------------------- + +let ComputeLogicalName (id: Ident) (memberFlags: SynMemberFlags) = + match memberFlags.MemberKind with + | SynMemberKind.ClassConstructor -> ".cctor" + | SynMemberKind.Constructor -> ".ctor" + | SynMemberKind.Member -> + match id.idText with + | ".ctor" | ".cctor" as r -> errorR(Error(FSComp.SR.tcInvalidMemberNameCtor(), id.idRange)); r + | r -> r + | SynMemberKind.PropertyGetSet -> error(InternalError(FSComp.SR.tcMemberKindPropertyGetSetNotExpected(), id.idRange)) + | SynMemberKind.PropertyGet -> "get_" + id.idText + | SynMemberKind.PropertySet -> "set_" + id.idText + +type PreValMemberInfo = + | PreValMemberInfo of + memberInfo: ValMemberInfo * + logicalName: string * + compiledName: string + +/// Make the unique "name" for a member. +// +// optImplSlotTy = None (for classes) or Some ty (when implementing interface type ty) +let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, optImplSlotTys, memberFlags, valSynData, id, isCompGen) = + let logicalName = ComputeLogicalName id memberFlags + let optIntfSlotTys = if optImplSlotTys |> List.forall (isInterfaceTy g) then optImplSlotTys else [] + let memberInfo: ValMemberInfo = + { ApparentEnclosingEntity=tcref + MemberFlags=memberFlags + IsImplemented=false + // NOTE: This value is initially only set for interface implementations and those overrides + // where we manage to pre-infer which abstract is overridden by the method. It is filled in + // properly when we check the allImplemented implementation checks at the end of the inference scope. + ImplementedSlotSigs=optImplSlotTys |> List.map (fun ity -> TSlotSig(logicalName, ity, [], [], [], None)) } + let isInstance = MemberIsCompiledAsInstance g tcref isExtrinsic memberInfo attrs + if (memberFlags.IsDispatchSlot || not (isNil optIntfSlotTys)) then + if not isInstance then + errorR(VirtualAugmentationOnNullValuedType(id.idRange)) + elif not memberFlags.IsOverrideOrExplicitImpl && memberFlags.IsInstance then + if not isExtrinsic && not isInstance then + warning(NonVirtualAugmentationOnNullValuedType(id.idRange)) + + let compiledName = + if isExtrinsic then + let tname = tcref.LogicalName + let text = tname + "." + logicalName + let text = if memberFlags.MemberKind <> SynMemberKind.Constructor && memberFlags.MemberKind <> SynMemberKind.ClassConstructor && not memberFlags.IsInstance then text + ".Static" else text + let text = if memberFlags.IsOverrideOrExplicitImpl then text + ".Override" else text + text + else if not optIntfSlotTys.IsEmpty then + // interface implementation + if optIntfSlotTys.Length > 1 then + failwithf "unexpected: optIntfSlotTys.Length > 1 (== %i) in MakeMemberDataAndMangledNameForMemberVal for '%s'" optIntfSlotTys.Length logicalName + qualifiedInterfaceImplementationName g optIntfSlotTys.Head logicalName + else + List.foldBack (fun x -> qualifiedMangledNameOfTyconRef (tcrefOfAppTy g x)) optIntfSlotTys logicalName + + if not isCompGen && IsMangledOpName id.idText && IsInfixOperator id.idText then + let m = id.idRange + let name = DecompileOpName id.idText + // Check symbolic members. Expect valSynData implied arity to be [[2]]. + match SynInfo.AritiesOfArgs valSynData with + | [] | [0] -> warning(Error(FSComp.SR.memberOperatorDefinitionWithNoArguments name, m)) + | n :: otherArgs -> + let opTakesThreeArgs = IsTernaryOperator name + if n<>2 && not opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonPairArgument(name, n), m)) + if n<>3 && opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonTripleArgument(name, n), m)) + if not (isNil otherArgs) then warning(Error(FSComp.SR.memberOperatorDefinitionWithCurriedArguments name, m)) + + if isExtrinsic && IsMangledOpName id.idText then + warning(Error(FSComp.SR.tcMemberOperatorDefinitionInExtrinsic(), id.idRange)) + + PreValMemberInfo(memberInfo, logicalName, compiledName) + +type OverridesOK = + | OverridesOK + | WarnOnOverrides + | ErrorOnOverrides + +/// A type to represent information associated with values to indicate what explicit (declared) type parameters +/// are given and what additional type parameters can be inferred, if any. +/// +/// The declared type parameters, e.g. let f<'a> (x:'a) = x, plus an indication +/// of whether additional polymorphism may be inferred, e.g. let f<'a, ..> (x:'a) y = x +type ExplicitTyparInfo = + | ExplicitTyparInfo of + rigidCopyOfDeclaredTypars: Typars * + declaredTypars: Typars * + infer: bool + +let permitInferTypars = ExplicitTyparInfo ([], [], true) +let dontInferTypars = ExplicitTyparInfo ([], [], false) + +type ArgAndRetAttribs = ArgAndRetAttribs of Attribs list list * Attribs +let noArgOrRetAttribs = ArgAndRetAttribs ([], []) + +/// A flag to represent the sort of bindings are we processing. +/// Processing "declaration" and "class" bindings that make up a module (such as "let x = 1 let y = 2") +/// shares the same code paths (e.g. TcLetBinding and TcLetrec) as processing expression bindings (such as "let x = 1 in ...") +/// Member bindings also use this path. +// +/// However there are differences in how different bindings get processed, +/// i.e. module bindings get published to the implicitly accumulated module type, but expression 'let' bindings don't. +type DeclKind = + | ModuleOrMemberBinding + + /// Extensions to a type within the same assembly + | IntrinsicExtensionBinding + + /// Extensions to a type in a different assembly + | ExtrinsicExtensionBinding + + | ClassLetBinding of isStatic: bool + + | ObjectExpressionOverrideBinding + + | ExpressionBinding + + static member IsModuleOrMemberOrExtensionBinding x = + match x with + | ModuleOrMemberBinding -> true + | IntrinsicExtensionBinding -> true + | ExtrinsicExtensionBinding -> true + | ClassLetBinding _ -> false + | ObjectExpressionOverrideBinding -> false + | ExpressionBinding -> false + + static member MustHaveArity x = DeclKind.IsModuleOrMemberOrExtensionBinding x + + member x.CanBeDllImport = + match x with + | ModuleOrMemberBinding -> true + | IntrinsicExtensionBinding -> true + | ExtrinsicExtensionBinding -> true + | ClassLetBinding _ -> true + | ObjectExpressionOverrideBinding -> false + | ExpressionBinding -> false + + static member IsAccessModifierPermitted x = DeclKind.IsModuleOrMemberOrExtensionBinding x + + static member ImplicitlyStatic x = DeclKind.IsModuleOrMemberOrExtensionBinding x + + static member AllowedAttribTargets (memberFlagsOpt: SynMemberFlags option) x = + match x with + | ModuleOrMemberBinding | ObjectExpressionOverrideBinding -> + match memberFlagsOpt with + | Some flags when flags.MemberKind = SynMemberKind.Constructor -> AttributeTargets.Constructor + | Some flags when flags.MemberKind = SynMemberKind.PropertyGetSet -> AttributeTargets.Event ||| AttributeTargets.Property + | Some flags when flags.MemberKind = SynMemberKind.PropertyGet -> AttributeTargets.Event ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | Some flags when flags.MemberKind = SynMemberKind.PropertySet -> AttributeTargets.Property + | Some _ -> AttributeTargets.Method ||| AttributeTargets.ReturnValue + | None -> AttributeTargets.Field ||| AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | IntrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | ExtrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.ReturnValue + | ClassLetBinding _ -> AttributeTargets.Field ||| AttributeTargets.Method ||| AttributeTargets.ReturnValue + | ExpressionBinding -> enum 0 // indicates attributes not allowed on expression 'let' bindings + + // Note: now always true + static member CanGeneralizeConstrainedTypars x = + match x with + | ModuleOrMemberBinding -> true + | IntrinsicExtensionBinding -> true + | ExtrinsicExtensionBinding -> true + | ClassLetBinding _ -> true + | ObjectExpressionOverrideBinding -> true + | ExpressionBinding -> true + + static member ConvertToLinearBindings x = + match x with + | ModuleOrMemberBinding -> true + | IntrinsicExtensionBinding -> true + | ExtrinsicExtensionBinding -> true + | ClassLetBinding _ -> true + | ObjectExpressionOverrideBinding -> true + | ExpressionBinding -> false + + static member CanOverrideOrImplement x = + match x with + | ModuleOrMemberBinding -> OverridesOK + | IntrinsicExtensionBinding -> WarnOnOverrides + | ExtrinsicExtensionBinding -> ErrorOnOverrides + | ClassLetBinding _ -> ErrorOnOverrides + | ObjectExpressionOverrideBinding -> OverridesOK + | ExpressionBinding -> ErrorOnOverrides + +//------------------------------------------------------------------------- +// Data structures that track the gradual accumulation of information +// about values and members during inference. +//------------------------------------------------------------------------- + +/// The results of preliminary pass over patterns to extract variables being declared. +// We should make this a record for cleaner code +type PrelimValScheme1 = + | PrelimValScheme1 of + id: Ident * + explicitTyparInfo: ExplicitTyparInfo * + TType * + PartialValReprInfo option * + PreValMemberInfo option * + bool * + ValInline * + ValBaseOrThisInfo * + ArgAndRetAttribs * + SynAccess option * + bool + + member x.Type = let (PrelimValScheme1(_, _, ty, _, _, _, _, _, _, _, _)) = x in ty + + member x.Ident = let (PrelimValScheme1(id, _, _, _, _, _, _, _, _, _, _)) = x in id + +/// The results of applying let-style generalization after type checking. +// We should make this a record for cleaner code +type PrelimValScheme2 = + PrelimValScheme2 of + Ident * + TypeScheme * + PartialValReprInfo option * + PreValMemberInfo option * + bool * + ValInline * + ValBaseOrThisInfo * + ArgAndRetAttribs * + SynAccess option * + bool * + bool (* hasDeclaredTypars *) + + +/// The results of applying arity inference to PrelimValScheme2 +type ValScheme = + | ValScheme of + id: Ident * + typeScheme: TypeScheme * + topValInfo: ValReprInfo option * + memberInfo: PreValMemberInfo option * + isMutable: bool * + inlineInfo: ValInline * + baseOrThisInfo: ValBaseOrThisInfo * + visibility: SynAccess option * + compgen: bool * + isIncrClass: bool * + isTyFunc: bool * + hasDeclaredTypars: bool + + member x.GeneralizedTypars = let (ValScheme(_, TypeScheme(gtps, _), _, _, _, _, _, _, _, _, _, _)) = x in gtps + + member x.TypeScheme = let (ValScheme(_, ts, _, _, _, _, _, _, _, _, _, _)) = x in ts + + member x.ValReprInfo = let (ValScheme(_, _, topValInfo, _, _, _, _, _, _, _, _, _)) = x in topValInfo + +/// Translation of patterns is split into three phases. The first collects names. +/// The second is run after val_specs have been created for those names and inference +/// has been resolved. The second phase is run by applying a function returned by the +/// first phase. The input to the second phase is a List.map that gives the Val and type scheme +/// for each value bound by the pattern. +type TcPatPhase2Input = + | TcPatPhase2Input of (Val * TypeScheme) NameMap * bool + // Get an input indicating we are no longer on the left-most path through a disjunctive "or" pattern + member x.RightPath = (let (TcPatPhase2Input(a, _)) = x in TcPatPhase2Input(a, false)) + +/// The first phase of checking and elaborating a binding leaves a goop of information. +/// This is a bit of a mess: much of this information is also carried on a per-value basis by the +/// "NameMap". +type CheckedBindingInfo = + | CheckedBindingInfo of + inlineFlag: ValInline * + valAttribs: Attribs * + xmlDoc: XmlDoc * + tcPatPhase2: (TcPatPhase2Input -> Pattern) * + exlicitTyparInfo: ExplicitTyparInfo * + nameToPrelimValSchemeMap: NameMap * + rhsExprChecked: Expr * + argAndRetAttribs: ArgAndRetAttribs * + overallPatTy: TType * + mBinding: range * + spBind: DebugPointAtBinding * + isCompilerGenerated: bool * + literalValue: Const option * + isFixed: bool + member x.Expr = let (CheckedBindingInfo(_, _, _, _, _, _, expr, _, _, _, _, _, _, _)) = x in expr + member x.SeqPoint = let (CheckedBindingInfo(_, _, _, _, _, _, _, _, _, _, spBind, _, _, _)) = x in spBind + +/// Return the generalized type for a type scheme +let GeneralizedTypeForTypeScheme typeScheme = + let (TypeScheme(generalizedTypars, tau)) = typeScheme + mkForallTyIfNeeded generalizedTypars tau + +/// Create a type scheme for something that is not generic +let NonGenericTypeScheme ty = TypeScheme([], ty) + +//------------------------------------------------------------------------- +// Helpers related to publishing values, types and members into the +// elaborated representation. +//------------------------------------------------------------------------- + +let UpdateAccModuleOrNamespaceType cenv env f = + // When compiling FSharp.Core, modify the fslib CCU to ensure forward stable references used by + // the compiler can be resolved ASAP. Not at all pretty but it's hard to + // find good ways to do references from the compiler into a term graph. + if cenv.compilingCanonicalFslibModuleType then + let nleref = mkNonLocalEntityRef cenv.topCcu (arrPathOfLid env.ePath) + let modul = nleref.Deref + modul.entity_modul_contents <- MaybeLazy.Strict (f true modul.ModuleOrNamespaceType) + SetCurrAccumulatedModuleOrNamespaceType env (f false (GetCurrAccumulatedModuleOrNamespaceType env)) + +let PublishModuleDefn cenv env mspec = + UpdateAccModuleOrNamespaceType cenv env (fun intoFslibCcu mty -> + if intoFslibCcu then mty + else mty.AddEntity mspec) + let item = Item.ModuleOrNamespaces([mkLocalModRef mspec]) + CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + +let PublishTypeDefn cenv env mspec = + UpdateAccModuleOrNamespaceType cenv env (fun _ mty -> + mty.AddEntity mspec) + +let PublishValueDefnPrim cenv env (vspec: Val) = + UpdateAccModuleOrNamespaceType cenv env (fun _ mty -> + mty.AddVal vspec) + +let PublishValueDefn cenv env declKind (vspec: Val) = + if (declKind = ModuleOrMemberBinding) && + ((GetCurrAccumulatedModuleOrNamespaceType env).ModuleOrNamespaceKind = Namespace) && + (Option.isNone vspec.MemberInfo) then + errorR(Error(FSComp.SR.tcNamespaceCannotContainValues(), vspec.Range)) + + if (declKind = ExtrinsicExtensionBinding) && + ((GetCurrAccumulatedModuleOrNamespaceType env).ModuleOrNamespaceKind = Namespace) then + errorR(Error(FSComp.SR.tcNamespaceCannotContainExtensionMembers(), vspec.Range)) + + // Publish the value to the module type being generated. + match declKind with + | ModuleOrMemberBinding + | ExtrinsicExtensionBinding + | IntrinsicExtensionBinding -> PublishValueDefnPrim cenv env vspec + | _ -> () + + match vspec.MemberInfo with + | Some _ when + (not vspec.IsCompilerGenerated && + // Extrinsic extensions don't get added to the tcaug + not (declKind = ExtrinsicExtensionBinding)) -> + // // Static initializers don't get published to the tcaug + // not (memberInfo.MemberFlags.MemberKind = SynMemberKind.ClassConstructor)) -> + + let tcaug = vspec.MemberApparentEntity.TypeContents + let vref = mkLocalValRef vspec + tcaug.tcaug_adhoc <- NameMultiMap.add vspec.LogicalName vref tcaug.tcaug_adhoc + tcaug.tcaug_adhoc_list.Add (ValRefIsExplicitImpl cenv.g vref, vref) + | _ -> () + +let CombineVisibilityAttribs vis1 vis2 m = + match vis1 with + | Some _ -> + if Option.isSome vis2 then + errorR(Error(FSComp.SR.tcMultipleVisibilityAttributes(), m)) + vis1 + | _ -> vis2 + +let ComputeAccessAndCompPath env declKindOpt m vis overrideVis actualParent = + let accessPath = env.eAccessPath + let accessModPermitted = + match declKindOpt with + | None -> true + | Some declKind -> DeclKind.IsAccessModifierPermitted declKind + + if Option.isSome vis && not accessModPermitted then + errorR(Error(FSComp.SR.tcMultipleVisibilityAttributesWithLet(), m)) + + let vis = + match overrideVis, vis with + | Some v, _ -> v + | _, None -> taccessPublic (* a module or member binding defaults to "public" *) + | _, Some SynAccess.Public -> taccessPublic + | _, Some SynAccess.Private -> taccessPrivate accessPath + | _, Some SynAccess.Internal -> taccessInternal + + let vis = + match actualParent with + | ParentNone -> vis + | Parent tcref -> combineAccess vis tcref.Accessibility + + let cpath = if accessModPermitted then Some env.eCompPath else None + vis, cpath + +let CheckForAbnormalOperatorNames cenv (idRange: range) coreDisplayName (memberInfoOpt: ValMemberInfo option) = + if (idRange.EndColumn - idRange.StartColumn <= 5) && + not cenv.g.compilingFslib + then + let opName = DecompileOpName coreDisplayName + let isMember = memberInfoOpt.IsSome + match opName with + | Relational -> + if isMember then + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMethodNameForRelationalOperator(opName, coreDisplayName), idRange)) + else + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinitionRelational opName, idRange)) + | Equality -> + if isMember then + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMethodNameForEquality(opName, coreDisplayName), idRange)) + else + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinitionEquality opName, idRange)) + | Control -> + if isMember then + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMemberName(opName, coreDisplayName), idRange)) + else + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinition opName, idRange)) + | Indexer -> + if not isMember then + error(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidIndexOperatorDefinition opName, idRange)) + | FixedTypes -> + if isMember then + warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMemberNameFixedTypes opName, idRange)) + | Other -> () + +let MakeAndPublishVal cenv env (altActualParent, inSig, declKind, vrec, vscheme, attrs, doc, konst, isGeneratedEventVal) = + + let (ValScheme(id, typeScheme, topValData, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars)) = vscheme + + let ty = GeneralizedTypeForTypeScheme typeScheme + + let m = id.idRange + + let isTopBinding = + match declKind with + | ModuleOrMemberBinding -> true + | ExtrinsicExtensionBinding -> true + | IntrinsicExtensionBinding -> true + | _ -> false + + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + + let actualParent, overrideVis = + // Use the parent of the member if it's available + // If it's an extrinsic extension member or not a member then use the containing module. + match memberInfoOpt with + | Some (PreValMemberInfo(memberInfo, _, _)) when not isExtrinsic -> + if memberInfo.ApparentEnclosingEntity.IsModuleOrNamespace then + errorR(InternalError(FSComp.SR.tcExpectModuleOrNamespaceParent(id.idText), m)) + + // Members of interface implementations have the accessibility of the interface + // they are implementing. + let vis = + if MemberIsExplicitImpl cenv.g memberInfo then + let slotSig = List.head memberInfo.ImplementedSlotSigs + match slotSig.ImplementedType with + | TType_app (tyconref, _) -> Some tyconref.Accessibility + | _ -> None + else + None + Parent(memberInfo.ApparentEnclosingEntity), vis + | _ -> altActualParent, None + + let vis, _ = ComputeAccessAndCompPath env (Some declKind) id.idRange vis overrideVis actualParent + + let inlineFlag = + if HasFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute attrs then + if inlineFlag = ValInline.Always then + errorR(Error(FSComp.SR.tcDllImportStubsCannotBeInlined(), m)) + ValInline.Never + else + let implflags = + match TryFindFSharpAttribute cenv.g cenv.g.attrib_MethodImplAttribute attrs with + | Some (Attrib(_, _, [ AttribInt32Arg flags ], _, _, _, _)) -> flags + | _ -> 0x0 + // MethodImplOptions.NoInlining = 0x8 + let NO_INLINING = 0x8 + if (implflags &&& NO_INLINING) <> 0x0 then + ValInline.Never + else + inlineFlag + + // CompiledName not allowed on virtual/abstract/override members + let compiledNameAttrib = TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs + if Option.isSome compiledNameAttrib then + match memberInfoOpt with + | Some (PreValMemberInfo(memberInfo, _, _)) -> + if memberInfo.MemberFlags.IsDispatchSlot || memberInfo.MemberFlags.IsOverrideOrExplicitImpl then + errorR(Error(FSComp.SR.tcCompiledNameAttributeMisused(), m)) + | None -> + match altActualParent with + | ParentNone -> errorR(Error(FSComp.SR.tcCompiledNameAttributeMisused(), m)) + | _ -> () + + let compiledNameIsOnProp = + match memberInfoOpt with + | Some (PreValMemberInfo(memberInfo, _, _)) -> + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet + | _ -> false + + let compiledName = + match compiledNameAttrib with + // We fix up CompiledName on properties during codegen + | Some _ when not compiledNameIsOnProp -> compiledNameAttrib + | _ -> + match memberInfoOpt with + | Some (PreValMemberInfo(_, _, compiledName)) -> + Some compiledName + | None -> + None + + let logicalName = + match memberInfoOpt with + | Some (PreValMemberInfo(_, logicalName, _)) -> + logicalName + | None -> + id.idText + + let memberInfoOpt = + match memberInfoOpt with + | Some (PreValMemberInfo(memberInfo, _, _)) -> + Some memberInfo + | None -> + None + + let mut = if isMutable then Mutable else Immutable + let vspec = + Construct.NewVal + (logicalName, id.idRange, compiledName, ty, mut, + compgen, topValData, vis, vrec, memberInfoOpt, baseOrThis, attrs, inlineFlag, + doc, isTopBinding, isExtrinsic, isIncrClass, isTyFunc, + (hasDeclaredTypars || inSig), isGeneratedEventVal, konst, actualParent) + + + CheckForAbnormalOperatorNames cenv id.idRange vspec.DisplayNameCoreMangled memberInfoOpt + + PublishValueDefn cenv env declKind vspec + + let shouldNotifySink (vspec: Val) = + match vspec.MemberInfo with + // `this` reference named `__`. It's either: + // * generated by compiler for auto properties or + // * provided by source code (i.e. `member _.Method = ...`) + // We don't notify sink about it to prevent generating `FSharpSymbol` for it and appearing in completion list. + | None when + vspec.IsBaseVal || + vspec.IsMemberThisVal && vspec.LogicalName = "__" -> false + | _ -> true + + match cenv.tcSink.CurrentSink with + | Some _ when not vspec.IsCompilerGenerated && shouldNotifySink vspec -> + let nenv = AddFakeNamedValRefToNameEnv vspec.DisplayName env.NameEnv (mkLocalValRef vspec) + CallEnvSink cenv.tcSink (vspec.Range, nenv, env.eAccessRights) + let item = Item.Value(mkLocalValRef vspec) + CallNameResolutionSink cenv.tcSink (vspec.Range, nenv, item, emptyTyparInst, ItemOccurence.Binding, env.eAccessRights) + | _ -> () + + vspec + +let MakeAndPublishVals cenv env (altActualParent, inSig, declKind, vrec, valSchemes, attrs, doc, literalValue) = + Map.foldBack + (fun name (valscheme: ValScheme) values -> + Map.add name (MakeAndPublishVal cenv env (altActualParent, inSig, declKind, vrec, valscheme, attrs, doc, literalValue, false), valscheme.TypeScheme) values) + valSchemes + Map.empty + +let MakeAndPublishBaseVal cenv env baseIdOpt ty = + baseIdOpt + |> Option.map (fun (id: Ident) -> + let valscheme = ValScheme(id, NonGenericTypeScheme ty, None, None, false, ValInline.Never, BaseVal, None, false, false, false, false) + MakeAndPublishVal cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valscheme, [], XmlDoc.Empty, None, false)) + +// Make the "delayed reference" value where the this pointer will reside after calling the base class constructor +// Make the value for the 'this' pointer for use within a constructor +let MakeAndPublishSafeThisVal cenv env (thisIdOpt: Ident option) thisTy = + match thisIdOpt with + | Some thisId -> + // for structs, thisTy is a byref + if not (isFSharpObjModelTy cenv.g thisTy) then + errorR(Error(FSComp.SR.tcStructsCanOnlyBindThisAtMemberDeclaration(), thisId.idRange)) + + let valScheme = ValScheme(thisId, NonGenericTypeScheme(mkRefCellTy cenv.g thisTy), None, None, false, ValInline.Never, CtorThisVal, None, false, false, false, false) + Some(MakeAndPublishVal cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valScheme, [], XmlDoc.Empty, None, false)) + + | None -> + None + + +//------------------------------------------------------------------------- +// Helpers for type inference for recursive bindings +//------------------------------------------------------------------------- + +/// Fixup the type instantiation at recursive references. Used after the bindings have been +/// checked. The fixups are applied by using mutation. +let AdjustAndForgetUsesOfRecValue cenv (vrefTgt: ValRef) (valScheme: ValScheme) = + let (TypeScheme(generalizedTypars, _)) = valScheme.TypeScheme + let fty = GeneralizedTypeForTypeScheme valScheme.TypeScheme + let lvrefTgt = vrefTgt.Deref + if not (isNil generalizedTypars) then + // Find all the uses of this recursive binding and use mutation to adjust the expressions + // at those points in order to record the inferred type parameters. + let recUses = cenv.recUses.Find lvrefTgt + recUses + |> List.iter (fun (fixupPoint, m, isComplete) -> + if not isComplete then + // Keep any values for explicit type arguments + let fixedUpExpr = + let vrefFlags, tyargs0 = + match fixupPoint.Value with + | Expr.App (Expr.Val (_, vrefFlags, _), _, tyargs0, [], _) -> vrefFlags, tyargs0 + | Expr.Val (_, vrefFlags, _) -> vrefFlags, [] + | _ -> + errorR(Error(FSComp.SR.tcUnexpectedExprAtRecInfPoint(), m)) + NormalValUse, [] + + let ityargs = generalizeTypars (List.skip (List.length tyargs0) generalizedTypars) + primMkApp (Expr.Val (vrefTgt, vrefFlags, m), fty) (tyargs0 @ ityargs) [] m + fixupPoint.Value <- fixedUpExpr) + + vrefTgt.Deref.SetValRec ValNotInRecScope + cenv.recUses <- cenv.recUses.Remove vrefTgt.Deref + + +/// Set the properties of recursive values that are only fully known after inference is complete +let AdjustRecType (vspec: Val) (ValScheme(_, typeScheme, topValData, _, _, _, _, _, _, _, _, _)) = + let fty = GeneralizedTypeForTypeScheme typeScheme + vspec.SetType fty + vspec.SetValReprInfo topValData + vspec.SetValRec (ValInRecScope true) + +/// Record the generated value expression as a place where we will have to +/// adjust using AdjustAndForgetUsesOfRecValue at a letrec point. Every use of a value +/// under a letrec gets used at the _same_ type instantiation. +let RecordUseOfRecValue cenv vrec (vrefTgt: ValRef) vexp m = + match vrec with + | ValInRecScope isComplete -> + let fixupPoint = ref vexp + cenv.recUses <- cenv.recUses.Add (vrefTgt.Deref, (fixupPoint, m, isComplete)) + Expr.Link fixupPoint + | ValNotInRecScope -> + vexp + +type RecursiveUseFixupPoints = RecursiveUseFixupPoints of (Expr ref * range) list + +/// Get all recursive references, for fixing up delayed recursion using laziness +let GetAllUsesOfRecValue cenv vrefTgt = + RecursiveUseFixupPoints (cenv.recUses.Find vrefTgt |> List.map (fun (fixupPoint, m, _) -> (fixupPoint, m))) + + +//------------------------------------------------------------------------- +// Helpers for Generalization +//------------------------------------------------------------------------- + +let ChooseCanonicalDeclaredTyparsAfterInference g denv declaredTypars m = + declaredTypars |> List.iter (fun tp -> + let ty = mkTyparTy tp + if not (isAnyParTy g ty) then + error(Error(FSComp.SR.tcLessGenericBecauseOfAnnotation(tp.Name, NicePrint.prettyStringOfTy denv ty), tp.Range))) + + let declaredTypars = NormalizeDeclaredTyparsForEquiRecursiveInference g declaredTypars + + if ListSet.hasDuplicates typarEq declaredTypars then + errorR(Error(FSComp.SR.tcConstrainedTypeVariableCannotBeGeneralized(), m)) + + declaredTypars + +let ChooseCanonicalValSchemeAfterInference g denv vscheme m = + let (ValScheme(id, typeScheme, arityInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars)) = vscheme + let (TypeScheme(generalizedTypars, ty)) = typeScheme + let generalizedTypars = ChooseCanonicalDeclaredTyparsAfterInference g denv generalizedTypars m + let typeScheme = TypeScheme(generalizedTypars, ty) + let valscheme = ValScheme(id, typeScheme, arityInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars) + valscheme + +let PlaceTyparsInDeclarationOrder declaredTypars generalizedTypars = + declaredTypars @ (generalizedTypars |> List.filter (fun tp -> not (ListSet.contains typarEq tp declaredTypars))) + +let SetTyparRigid denv m (tp: Typar) = + match tp.Solution with + | None -> () + | Some ty -> + if tp.IsCompilerGenerated then + errorR(Error(FSComp.SR.tcGenericParameterHasBeenConstrained(NicePrint.prettyStringOfTy denv ty), m)) + else + errorR(Error(FSComp.SR.tcTypeParameterHasBeenConstrained(NicePrint.prettyStringOfTy denv ty), tp.Range)) + tp.SetRigidity TyparRigidity.Rigid + +let GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTyparsForThisBinding + (PrelimValScheme1(id, explicitTyparInfo, ty, partialValReprInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) = + + let (ExplicitTyparInfo(_rigidCopyOfDeclaredTypars, declaredTypars, _)) = explicitTyparInfo + + let m = id.idRange + + let allDeclaredTypars = enclosingDeclaredTypars@declaredTypars + let allDeclaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g denv allDeclaredTypars m + + // Trim out anything not in type of the value (as opposed to the type of the r.h.s) + // This is important when a single declaration binds + // multiple generic items, where each item does not use all the polymorphism + // of the r.h.s., e.g. let x, y = None, [] + let computeRelevantTypars thruFlag = + let ftps = freeInTypeLeftToRight cenv.g thruFlag ty + let generalizedTypars = generalizedTyparsForThisBinding |> List.filter (fun tp -> ListSet.contains typarEq tp ftps) + // Put declared typars first + let generalizedTypars = PlaceTyparsInDeclarationOrder allDeclaredTypars generalizedTypars + generalizedTypars + + let generalizedTypars = computeRelevantTypars false + + // Check stability of existence and ordering of type parameters under erasure of type abbreviations + let generalizedTyparsLookingThroughTypeAbbreviations = computeRelevantTypars true + if not (generalizedTypars.Length = generalizedTyparsLookingThroughTypeAbbreviations.Length && + List.forall2 typarEq generalizedTypars generalizedTyparsLookingThroughTypeAbbreviations) + then + warning(Error(FSComp.SR.tcTypeParametersInferredAreNotStable(), m)) + + let hasDeclaredTypars = not (isNil declaredTypars) + // This is just about the only place we form a TypeScheme + let tyScheme = TypeScheme(generalizedTypars, ty) + PrelimValScheme2(id, tyScheme, partialValReprInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen, hasDeclaredTypars) + +let GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars types = + NameMap.map (GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars) types + +let DontGeneralizeVals types = + let dontGeneralizeVal (PrelimValScheme1(id, _, ty, partialValReprInfoOpt, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) = + PrelimValScheme2(id, NonGenericTypeScheme ty, partialValReprInfoOpt, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen, false) + NameMap.map dontGeneralizeVal types + +let InferGenericArityFromTyScheme (TypeScheme(generalizedTypars, _)) partialValReprInfo = + TranslatePartialArity generalizedTypars partialValReprInfo + +let ComputeIsTyFunc(id: Ident, hasDeclaredTypars, arityInfo: ValReprInfo option) = + hasDeclaredTypars && + (match arityInfo with + | None -> error(Error(FSComp.SR.tcExplicitTypeParameterInvalid(), id.idRange)) + | Some info -> info.NumCurriedArgs = 0) + +let UseSyntacticArity declKind typeScheme partialValReprInfo = + if DeclKind.MustHaveArity declKind then + Some(InferGenericArityFromTyScheme typeScheme partialValReprInfo) + else + None + +/// Combine the results of InferSynValData and InferArityOfExpr. +// +// The F# spec says that we infer arities from declaration forms and types. +// +// For example +// let f (a, b) c = 1 // gets arity [2;1] +// let f (a: int*int) = 1 // gets arity [2], based on type +// let f () = 1 // gets arity [0] +// let f = (fun (x: int) (y: int) -> 1) // gets arity [1;1] +// let f = (fun (x: int*int) y -> 1) // gets arity [2;1] +// +// Some of this arity inference is purely syntax directed and done in InferSynValData in ast.fs +// Some is done by InferArityOfExpr. +// +// However, there are some corner cases in this specification. In particular, consider +// let f () () = 1 // [0;1] or [0;0]? Answer: [0;1] +// let f (a: unit) = 1 // [0] or [1]? Answer: [1] +// let f = (fun () -> 1) // [0] or [1]? Answer: [0] +// let f = (fun (a: unit) -> 1) // [0] or [1]? Answer: [1] +// +// The particular choice of [1] for +// let f (a: unit) = 1 +// is intended to give a disambiguating form for members that override methods taking a single argument +// instantiated to type "unit", e.g. +// type Base<'a> = +// abstract M: 'a -> unit +// +// { new Base with +// member x.M(v: int) = () } +// +// { new Base with +// member x.M(v: unit) = () } +// +let CombineSyntacticAndInferredArities g declKind rhsExpr prelimScheme = + let (PrelimValScheme2(_, typeScheme, partialValReprInfoOpt, memberInfoOpt, isMutable, _, _, ArgAndRetAttribs(argAttribs, retAttribs), _, _, _)) = prelimScheme + match partialValReprInfoOpt, DeclKind.MustHaveArity declKind with + | _, false -> None + | None, true -> Some(PartialValReprInfo([], ValReprInfo.unnamedRetVal)) + // Don't use any expression information for members, where syntax dictates the arity completely + | _ when memberInfoOpt.IsSome -> + partialValReprInfoOpt + // Don't use any expression information for 'let' bindings where return attributes are present + | _ when retAttribs.Length > 0 -> + partialValReprInfoOpt + | Some partialValReprInfoFromSyntax, true -> + let (PartialValReprInfo(curriedArgInfosFromSyntax, retInfoFromSyntax)) = partialValReprInfoFromSyntax + let partialArityInfo = + if isMutable then + PartialValReprInfo ([], retInfoFromSyntax) + else + + let (ValReprInfo (_, curriedArgInfosFromExpression, _)) = + InferArityOfExpr g AllowTypeDirectedDetupling.Yes (GeneralizedTypeForTypeScheme typeScheme) argAttribs retAttribs rhsExpr + + // Choose between the syntactic arity and the expression-inferred arity + // If the syntax specifies an eliminated unit arg, then use that + let choose ai1 ai2 = + match ai1, ai2 with + | [], _ -> [] + // Dont infer eliminated unit args from the expression if they don't occur syntactically. + | ai, [] -> ai + // If we infer a tupled argument from the expression and/or type then use that + | _ when ai1.Length < ai2.Length -> ai2 + | _ -> ai1 + let rec loop ais1 ais2 = + match ais1, ais2 with + // If the expression infers additional arguments then use those (this shouldn't happen, since the + // arity inference done on the syntactic form should give identical results) + | [], ais | ais, [] -> ais + | h1 :: t1, h2 :: t2 -> choose h1 h2 :: loop t1 t2 + let curriedArgInfos = loop curriedArgInfosFromSyntax curriedArgInfosFromExpression + PartialValReprInfo (curriedArgInfos, retInfoFromSyntax) + + Some partialArityInfo + +let BuildValScheme declKind partialArityInfoOpt prelimScheme = + let (PrelimValScheme2(id, typeScheme, _, memberInfoOpt, isMutable, inlineFlag, baseOrThis, _, vis, compgen, hasDeclaredTypars)) = prelimScheme + let topValInfo = + if DeclKind.MustHaveArity declKind then + Option.map (InferGenericArityFromTyScheme typeScheme) partialArityInfoOpt + else + None + let isTyFunc = ComputeIsTyFunc(id, hasDeclaredTypars, topValInfo) + ValScheme(id, typeScheme, topValInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, false, isTyFunc, hasDeclaredTypars) + +let UseCombinedArity g declKind rhsExpr prelimScheme = + let partialArityInfoOpt = CombineSyntacticAndInferredArities g declKind rhsExpr prelimScheme + BuildValScheme declKind partialArityInfoOpt prelimScheme + +let UseNoArity prelimScheme = + BuildValScheme ExpressionBinding None prelimScheme + +/// Make and publish the Val nodes for a collection of simple (non-generic) value specifications +let MakeAndPublishSimpleVals cenv env names = + let tyschemes = DontGeneralizeVals names + let valSchemes = NameMap.map UseNoArity tyschemes + let values = MakeAndPublishVals cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valSchemes, [], XmlDoc.Empty, None) + let vspecMap = NameMap.map fst values + values, vspecMap + +/// Make and publish the Val nodes for a collection of value specifications at Lambda and Match positions +/// +/// We merge the additions to the name resolution environment into one using a merged range so all values are brought +/// into scope simultaneously. The technique used to do this is a disturbing and unfortunate hack that +/// intercepts `NotifyNameResolution` calls being emitted by `MakeAndPublishSimpleVals` + +let MakeAndPublishSimpleValsForMergedScope cenv env m (names: NameMap<_>) = + let values, vspecMap = + if names.Count <= 1 then + MakeAndPublishSimpleVals cenv env names + else + let nameResolutions = ResizeArray() + + let notifyNameResolution (pos, item, itemGroup, itemTyparInst, occurence, nenv, ad, m: range, replacing) = + if not m.IsSynthetic then + nameResolutions.Add(pos, item, itemGroup, itemTyparInst, occurence, nenv, ad, m, replacing) + + let values, vspecMap = + let sink = + { new ITypecheckResultsSink with + member this.NotifyEnvWithScope(_, _, _) = () // ignore EnvWithScope reports + + member this.NotifyNameResolution(pos, item, itemTyparInst, occurence, nenv, ad, m, replacing) = + notifyNameResolution (pos, item, item, itemTyparInst, occurence, nenv, ad, m, replacing) + + member this.NotifyMethodGroupNameResolution(pos, item, itemGroup, itemTyparInst, occurence, nenv, ad, m, replacing) = + notifyNameResolution (pos, item, itemGroup, itemTyparInst, occurence, nenv, ad, m, replacing) + + member this.NotifyExprHasType(_, _, _, _) = assert false // no expr typings in MakeAndPublishSimpleVals + member this.NotifyFormatSpecifierLocation(_, _) = () + member this.NotifyOpenDeclaration _ = () + member this.CurrentSourceText = None + member this.FormatStringCheckContext = None } + + use _h = WithNewTypecheckResultsSink(sink, cenv.tcSink) + MakeAndPublishSimpleVals cenv env names + + if nameResolutions.Count <> 0 then + let _, _, _, _, _, _, ad, m1, _replacing = nameResolutions.[0] + // mergedNameEnv - name resolution env that contains all names + // mergedRange - union of ranges of names + let mergedNameEnv, mergedRange = + ((env.NameEnv, m1), nameResolutions) ||> Seq.fold (fun (nenv, merged) (_, item, _, _, _, _, _, m, _) -> + // MakeAndPublishVal creates only Item.Value + let item = match item with Item.Value item -> item | _ -> failwith "impossible" + (AddFakeNamedValRefToNameEnv item.DisplayName nenv item), (unionRanges m merged) + ) + // send notification about mergedNameEnv + CallEnvSink cenv.tcSink (mergedRange, mergedNameEnv, ad) + // call CallNameResolutionSink for all captured name resolutions using mergedNameEnv + for _, item, itemGroup, itemTyparInst, occurence, _nenv, ad, m, _replacing in nameResolutions do + CallMethodGroupNameResolutionSink cenv.tcSink (m, mergedNameEnv, item, itemGroup, itemTyparInst, occurence, ad) + + values, vspecMap + + let envinner = AddLocalValMap cenv.g cenv.tcSink m vspecMap env + envinner, values, vspecMap + +//------------------------------------------------------------------------- +// Helpers to freshen existing types and values, i.e. when a reference +// to C<_> occurs then generate C for a fresh type inference variable ?ty. +//------------------------------------------------------------------------- + +let FreshenTyconRef m rigid (tcref: TyconRef) declaredTyconTypars = + let tpsorig = declaredTyconTypars + let tps = copyTypars tpsorig + if rigid <> TyparRigidity.Rigid then + tps |> List.iter (fun tp -> tp.SetRigidity rigid) + + let renaming, tinst = FixupNewTypars m [] [] tpsorig tps + (TType_app(tcref, List.map mkTyparTy tpsorig), tps, renaming, TType_app(tcref, tinst)) + +let FreshenPossibleForallTy g m rigid ty = + let tpsorig, tau = tryDestForallTy g ty + if isNil tpsorig then + [], [], [], tau + else + // tps may be have been equated to other tps in equi-recursive type inference and units-of-measure type inference. Normalize them here + let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference g tpsorig + let tps, renaming, tinst = CopyAndFixupTypars m rigid tpsorig + tpsorig, tps, tinst, instType renaming tau + +let FreshenTyconRef2 m (tcref: TyconRef) = + let tps, renaming, tinst = FreshenTypeInst m (tcref.Typars m) + tps, renaming, tinst, TType_app (tcref, tinst) + + +/// Given a abstract method, which may be a generic method, freshen the type in preparation +/// to apply it as a constraint to the method that implements the abstract slot +let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = + + // Work out if an explicit instantiation has been given. If so then the explicit type + // parameters will be made rigid and checked for generalization. If not then auto-generalize + // by making the copy of the type parameters on the virtual being overridden rigid. + + let typarsFromAbsSlotAreRigid = + + match synTyparDecls with + | ValTyparDecls(synTypars, _, infer) -> + if infer && not (isNil synTypars) then + errorR(Error(FSComp.SR.tcOverridingMethodRequiresAllOrNoTypeParameters(), m)) + + isNil synTypars + + let (CompiledSig (argTys, retTy, fmtps, _)) = CompiledSigOfMeth g amap m absMethInfo + + // If the virtual method is a generic method then copy its type parameters + let typarsFromAbsSlot, typarInstFromAbsSlot, _ = + let ttps = absMethInfo.GetFormalTyparsOfDeclaringType m + let ttinst = argsOfAppTy g absMethInfo.ApparentEnclosingType + let rigid = if typarsFromAbsSlotAreRigid then TyparRigidity.Rigid else TyparRigidity.Flexible + FreshenAndFixupTypars m rigid ttps ttinst fmtps + + // Work out the required type of the member + let argTysFromAbsSlot = argTys |> List.mapSquared (instType typarInstFromAbsSlot) + let retTyFromAbsSlot = retTy |> GetFSharpViewOfReturnType g |> instType typarInstFromAbsSlot + typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot + + +//------------------------------------------------------------------------- +// Helpers to typecheck expressions and patterns +//------------------------------------------------------------------------- + +let BuildFieldMap cenv env isPartial ty flds m = + let ad = env.eAccessRights + if isNil flds then invalidArg "flds" "BuildFieldMap" + let fldCount = flds.Length + + let frefSets = + let allFields = flds |> List.map (fun ((_, ident), _) -> ident) + flds + |> List.map (fun (fld, fldExpr) -> + let frefSet = ResolveField cenv.tcSink cenv.nameResolver env.eNameResEnv ad ty fld allFields + fld, frefSet, fldExpr) + + let relevantTypeSets = + frefSets |> List.map (fun (_, frefSet, _) -> frefSet |> List.map (fun (FieldResolution(rfinfo, _)) -> rfinfo.TypeInst, rfinfo.TyconRef)) + + let tinst, tcref = + match List.fold (ListSet.intersect (fun (_, tcref1) (_, tcref2) -> tyconRefEq cenv.g tcref1 tcref2)) (List.head relevantTypeSets) (List.tail relevantTypeSets) with + | [tinst, tcref] -> tinst, tcref + | tcrefs -> + if isPartial then + warning (Error(FSComp.SR.tcFieldsDoNotDetermineUniqueRecordType(), m)) + + // try finding a record type with the same number of fields as the ones that are given. + match tcrefs |> List.tryFind (fun (_, tc) -> tc.TrueFieldsAsList.Length = fldCount) with + | Some (tinst, tcref) -> tinst, tcref + | _ -> + // OK, there isn't a unique, good type dictated by the intersection for the field refs. + // We're going to get an error of some kind below. + // Just choose one field ref and let the error come later + let _, frefSet1, _ = List.head frefSets + let (FieldResolution(rfinfo1, _)) = List.head frefSet1 + rfinfo1.TypeInst, rfinfo1.TyconRef + + let fldsmap, rfldsList = + ((Map.empty, []), frefSets) ||> List.fold (fun (fs, rfldsList) (fld, frefs, fldExpr) -> + match frefs |> List.filter (fun (FieldResolution(rfinfo2, _)) -> tyconRefEq cenv.g tcref rfinfo2.TyconRef) with + | [FieldResolution(rfinfo2, showDeprecated)] -> + + // Record the precise resolution of the field for intellisense + let item = Item.RecdField(rfinfo2) + CallNameResolutionSink cenv.tcSink ((snd fld).idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad) + + let fref2 = rfinfo2.RecdFieldRef + CheckRecdFieldAccessible cenv.amap m env.eAccessRights fref2 |> ignore + CheckFSharpAttributes cenv.g fref2.PropertyAttribs m |> CommitOperationResult + if Map.containsKey fref2.FieldName fs then + errorR (Error(FSComp.SR.tcFieldAppearsTwiceInRecord(fref2.FieldName), m)) + if showDeprecated then + warning(Deprecated(FSComp.SR.nrRecordTypeNeedsQualifiedAccess(fref2.FieldName, fref2.Tycon.DisplayName) |> snd, m)) + + if not (tyconRefEq cenv.g tcref fref2.TyconRef) then + let _, frefSet1, _ = List.head frefSets + let (FieldResolution(rfinfo1, _)) = List.head frefSet1 + errorR (FieldsFromDifferentTypes(env.DisplayEnv, rfinfo1.RecdFieldRef, fref2, m)) + fs, rfldsList + else + Map.add fref2.FieldName fldExpr fs, (fref2.FieldName, fldExpr) :: rfldsList + + | _ -> error(Error(FSComp.SR.tcRecordFieldInconsistentTypes(), m))) + tinst, tcref, fldsmap, List.rev rfldsList + +let rec ApplyUnionCaseOrExn (makerForUnionCase, makerForExnTag) m cenv env overallTy item = + let ad = env.eAccessRights + match item with + | Item.ExnCase ecref -> + CheckEntityAttributes cenv.g ecref m |> CommitOperationResult + UnifyTypes cenv env m overallTy cenv.g.exn_ty + CheckTyconAccessible cenv.amap m ad ecref |> ignore + let mkf = makerForExnTag ecref + mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f.Id ] + + | Item.UnionCase(ucinfo, showDeprecated) -> + if showDeprecated then + warning(Deprecated(FSComp.SR.nrUnionTypeNeedsQualifiedAccess(ucinfo.DisplayName, ucinfo.Tycon.DisplayName) |> snd, m)) + + let ucref = ucinfo.UnionCaseRef + CheckUnionCaseAttributes cenv.g ucref m |> CommitOperationResult + CheckUnionCaseAccessible cenv.amap m ad ucref |> ignore + let gtyp2 = actualResultTyOfUnionCase ucinfo.TypeInst ucref + let inst = mkTyparInst ucref.TyconRef.TyparsNoRange ucinfo.TypeInst + UnifyTypes cenv env m overallTy gtyp2 + let mkf = makerForUnionCase(ucref, ucinfo.TypeInst) + mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f.Id ] + | _ -> invalidArg "item" "not a union case or exception reference" + +let ApplyUnionCaseOrExnTypes m cenv env overallTy c = + ApplyUnionCaseOrExn ((fun (a, b) mArgs args -> mkUnionCaseExpr(a, b, args, unionRanges m mArgs)), + (fun a mArgs args -> mkExnExpr (a, args, unionRanges m mArgs))) m cenv env overallTy c + +let ApplyUnionCaseOrExnTypesForPat m cenv env overallTy c = + ApplyUnionCaseOrExn ((fun (a, b) mArgs args -> TPat_unioncase(a, b, args, unionRanges m mArgs)), + (fun a mArgs args -> TPat_exnconstr(a, args, unionRanges m mArgs))) m cenv env overallTy c + +let UnionCaseOrExnCheck (env: TcEnv) numArgTys numArgs m = + if numArgs <> numArgTys then error (UnionCaseWrongArguments(env.DisplayEnv, numArgTys, numArgs, m)) + +let TcUnionCaseOrExnField cenv (env: TcEnv) ty1 m c n funcs = + let ad = env.eAccessRights + let mkf, argTys, _argNames = + match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false m ad env.eNameResEnv TypeNameResolutionInfo.Default c with + | Item.UnionCase _ | Item.ExnCase _ as item -> + ApplyUnionCaseOrExn funcs m cenv env ty1 item + | _ -> error(Error(FSComp.SR.tcUnknownUnion(), m)) + let argstysLength = List.length argTys + if n >= argstysLength then + error (UnionCaseWrongNumberOfArgs(env.DisplayEnv, argstysLength, n, m)) + let ty2 = List.item n argTys + mkf, ty2 + +//------------------------------------------------------------------------- +// Helpers for generalizing type variables +//------------------------------------------------------------------------- + +type GeneralizeConstrainedTyparOptions = + | CanGeneralizeConstrainedTypars + | DoNotGeneralizeConstrainedTypars + + +module GeneralizationHelpers = + let ComputeUngeneralizableTypars env = + + let acc = List() + for item in env.eUngeneralizableItems do + if not item.WillNeverHaveFreeTypars then + let ftps = item.GetFreeTyvars().FreeTypars + if not ftps.IsEmpty then + for ftp in ftps do + acc.Add ftp + + Zset.Create(typarOrder, acc) + + + let ComputeUnabstractableTycons env = + let accInFreeItem acc (item: UngeneralizableItem) = + let ftycs = + if item.WillNeverHaveFreeTypars then item.CachedFreeLocalTycons else + let ftyvs = item.GetFreeTyvars() + ftyvs.FreeTycons + if ftycs.IsEmpty then acc else unionFreeTycons ftycs acc + + List.fold accInFreeItem emptyFreeTycons env.eUngeneralizableItems + + let ComputeUnabstractableTraitSolutions env = + let accInFreeItem acc (item: UngeneralizableItem) = + let ftycs = + if item.WillNeverHaveFreeTypars then item.CachedFreeTraitSolutions else + let ftyvs = item.GetFreeTyvars() + ftyvs.FreeTraitSolutions + if ftycs.IsEmpty then acc else unionFreeLocals ftycs acc + + List.fold accInFreeItem emptyFreeLocals env.eUngeneralizableItems + + let rec IsGeneralizableValue g t = + match t with + | Expr.Lambda _ | Expr.TyLambda _ | Expr.Const _ -> true + + // let f(x: byref) = let v = &x in ... shouldn't generalize "v" + | Expr.Val (vref, _, m) -> not (isByrefLikeTy g m vref.Type) + + // Look through coercion nodes corresponding to introduction of subsumption + | Expr.Op (TOp.Coerce, [inputTy;actualTy], [e1], _) when isFunTy g actualTy && isFunTy g inputTy -> + IsGeneralizableValue g e1 + + | Expr.Op (op, _, args, _) -> + + let canGeneralizeOp = + match op with + | TOp.Tuple _ -> true + | TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc) + | TOp.Recd (ctorInfo, tcref) -> + match ctorInfo with + | RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) + | RecdExprIsObjInit -> false + | TOp.Array -> isNil args + | TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec) + | TOp.ILAsm ([], _) -> true + | _ -> false + + canGeneralizeOp && List.forall (IsGeneralizableValue g) args + + | Expr.LetRec (binds, body, _, _) -> + binds |> List.forall (fun b -> not b.Var.IsMutable) && + binds |> List.forall (fun b -> IsGeneralizableValue g b.Expr) && + IsGeneralizableValue g body + + | Expr.Let (bind, body, _, _) -> + not bind.Var.IsMutable && + IsGeneralizableValue g bind.Expr && + IsGeneralizableValue g body + + // Applications of type functions are _not_ normally generalizable unless explicitly marked so + | Expr.App (Expr.Val (vref, _, _), _, _, [], _) when vref.IsTypeFunction -> + HasFSharpAttribute g g.attrib_GeneralizableValueAttribute vref.Attribs + + | Expr.App (e1, _, _, [], _) -> IsGeneralizableValue g e1 + | Expr.TyChoose (_, b, _) -> IsGeneralizableValue g b + | Expr.Obj (_, ty, _, _, _, _, _) -> isInterfaceTy g ty || isDelegateTy g ty + | Expr.Link eref -> IsGeneralizableValue g eref.Value + + | _ -> false + + let CanGeneralizeConstrainedTyparsForDecl declKind = + if DeclKind.CanGeneralizeConstrainedTypars declKind + then CanGeneralizeConstrainedTypars + else DoNotGeneralizeConstrainedTypars + + /// Recursively knock out typars we can't generalize. + /// For non-generalized type variables be careful to iteratively knock out + /// both the typars and any typars free in the constraints of the typars + /// into the set that are considered free in the environment. + let rec TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag (generalizedTypars: Typar list) freeInEnv = + // Do not generalize type variables with a static requirement unless function is marked 'inline' + let generalizedTypars, ungeneralizableTypars1 = + if inlineFlag = ValInline.Always then generalizedTypars, [] + else generalizedTypars |> List.partition (fun tp -> tp.StaticReq = TyparStaticReq.None) + + // Do not generalize type variables which would escape their scope + // because they are free in the environment + let generalizedTypars, ungeneralizableTypars2 = + List.partition (fun x -> not (Zset.contains x freeInEnv)) generalizedTypars + + // Some situations, e.g. implicit class constructions that represent functions as fields, + // do not allow generalisation over constrained typars. (since they can not be represented as fields) + // + // Don't generalize IsCompatFlex type parameters to avoid changing inferred types. + let generalizedTypars, ungeneralizableTypars3 = + generalizedTypars + |> List.partition (fun tp -> + (genConstrainedTyparFlag = CanGeneralizeConstrainedTypars || tp.Constraints.IsEmpty) && + not tp.IsCompatFlex) + + if isNil ungeneralizableTypars1 && isNil ungeneralizableTypars2 && isNil ungeneralizableTypars3 then + generalizedTypars, freeInEnv + else + let freeInEnv = + unionFreeTypars + (accFreeInTypars CollectAllNoCaching ungeneralizableTypars1 + (accFreeInTypars CollectAllNoCaching ungeneralizableTypars2 + (accFreeInTypars CollectAllNoCaching ungeneralizableTypars3 emptyFreeTyvars))).FreeTypars + freeInEnv + TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag generalizedTypars freeInEnv + + /// Condense type variables in positive position + let CondenseTypars (cenv, denv: DisplayEnv, generalizedTypars: Typars, tauTy, m) = + + // The type of the value is ty11 * ... * ty1N -> ... -> tyM1 * ... * tyMM -> retTy + // This is computed REGARDLESS of the arity of the expression. + let curriedArgTys, retTy = stripFunTy cenv.g tauTy + let allUntupledArgTys = curriedArgTys |> List.collect (tryDestRefTupleTy cenv.g) + + // Compute the type variables in 'retTy' + let returnTypeFreeTypars = freeInTypeLeftToRight cenv.g false retTy + let allUntupledArgTysWithFreeVars = allUntupledArgTys |> List.map (fun ty -> (ty, freeInTypeLeftToRight cenv.g false ty)) + + let relevantUniqueSubtypeConstraint (tp: Typar) = + // Find a single subtype constraint + match tp.Constraints |> List.partition (function TyparConstraint.CoercesTo _ -> true | _ -> false) with + | [TyparConstraint.CoercesTo(cxty, _)], others -> + // Throw away null constraints if they are implied + if others |> List.exists (function TyparConstraint.SupportsNull _ -> not (TypeSatisfiesNullConstraint cenv.g m cxty) | _ -> true) + then None + else Some cxty + | _ -> None + + + // Condensation typars can't be used in the constraints of any candidate condensation typars. So compute all the + // typars free in the constraints of tyIJ + + let lhsConstraintTypars = + allUntupledArgTys |> List.collect (fun ty -> + match tryDestTyparTy cenv.g ty with + | ValueSome tp -> + match relevantUniqueSubtypeConstraint tp with + | Some cxty -> freeInTypeLeftToRight cenv.g false cxty + | None -> [] + | _ -> []) + + let IsCondensationTypar (tp: Typar) = + // A condensation typar may not a user-generated type variable nor has it been unified with any user type variable + (tp.DynamicReq = TyparDynamicReq.No) && + // A condensation typar must have a single constraint "'a :> A" + (Option.isSome (relevantUniqueSubtypeConstraint tp)) && + // This is type variable is not used on the r.h.s. of the type + not (ListSet.contains typarEq tp returnTypeFreeTypars) && + // A condensation typar can't be used in the constraints of any candidate condensation typars + not (ListSet.contains typarEq tp lhsConstraintTypars) && + // A condensation typar must occur precisely once in tyIJ, and must not occur free in any other tyIJ + (match allUntupledArgTysWithFreeVars |> List.partition (fun (ty, _) -> match tryDestTyparTy cenv.g ty with ValueSome destTypar -> typarEq destTypar tp | _ -> false) with + | [_], rest -> not (rest |> List.exists (fun (_, fvs) -> ListSet.contains typarEq tp fvs)) + | _ -> false) + + let condensationTypars, generalizedTypars = generalizedTypars |> List.partition IsCondensationTypar + + // Condensation solves type variables eagerly and removes them from the generalization set + condensationTypars |> List.iter (fun tp -> + ChooseTyparSolutionAndSolve cenv.css denv tp) + generalizedTypars + + let ComputeAndGeneralizeGenericTypars (cenv, + denv: DisplayEnv, + m, + freeInEnv: FreeTypars, + canInferTypars, + genConstrainedTyparFlag, + inlineFlag, + exprOpt, + allDeclaredTypars: Typars, + maxInferredTypars: Typars, + tauTy, + resultFirst) = + + let allDeclaredTypars = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g allDeclaredTypars + let typarsToAttemptToGeneralize = + if (match exprOpt with None -> true | Some e -> IsGeneralizableValue cenv.g e) + then (ListSet.unionFavourLeft typarEq allDeclaredTypars maxInferredTypars) + else allDeclaredTypars + + let generalizedTypars, freeInEnv = + TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag typarsToAttemptToGeneralize freeInEnv + + allDeclaredTypars + |> List.iter (fun tp -> + if Zset.memberOf freeInEnv tp then + let ty = mkTyparTy tp + error(Error(FSComp.SR.tcNotSufficientlyGenericBecauseOfScope(NicePrint.prettyStringOfTy denv ty), m))) + + let generalizedTypars = CondenseTypars(cenv, denv, generalizedTypars, tauTy, m) + + let generalizedTypars = + if canInferTypars then generalizedTypars + else generalizedTypars |> List.filter (fun tp -> ListSet.contains typarEq tp allDeclaredTypars) + + let allConstraints = List.collect (fun (tp: Typar) -> tp.Constraints) generalizedTypars + let generalizedTypars = SimplifyMeasuresInTypeScheme cenv.g resultFirst generalizedTypars tauTy allConstraints + + // Generalization turns inference type variables into rigid, quantified type variables, + // (they may be rigid already) + generalizedTypars |> List.iter (SetTyparRigid denv m) + + // Generalization removes constraints related to generalized type variables + EliminateConstraintsForGeneralizedTypars denv cenv.css m NoTrace generalizedTypars + + generalizedTypars + + //------------------------------------------------------------------------- + // Helpers to freshen existing types and values, i.e. when a reference + // to C<_> occurs then generate C for a fresh type inference variable ?ty. + //------------------------------------------------------------------------- + + let CheckDeclaredTyparsPermitted (memFlagsOpt: SynMemberFlags option, declaredTypars, m) = + match memFlagsOpt with + | None -> () + | Some memberFlags -> + match memberFlags.MemberKind with + // can't infer extra polymorphism for properties + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet -> + if not (isNil declaredTypars) then + errorR(Error(FSComp.SR.tcPropertyRequiresExplicitTypeParameters(), m)) + | SynMemberKind.Constructor -> + if not (isNil declaredTypars) then + errorR(Error(FSComp.SR.tcConstructorCannotHaveTypeParameters(), m)) + | _ -> () + + /// Properties and Constructors may only generalize the variables associated with the containing class (retrieved from the 'this' pointer) + /// Also check they don't declare explicit typars. + let ComputeCanInferExtraGeneralizableTypars (parentRef, canInferTypars, memFlagsOpt: SynMemberFlags option) = + canInferTypars && + (match memFlagsOpt with + | None -> true + | Some memberFlags -> + match memberFlags.MemberKind with + // can't infer extra polymorphism for properties + | SynMemberKind.PropertyGet | SynMemberKind.PropertySet -> false + // can't infer extra polymorphism for class constructors + | SynMemberKind.ClassConstructor -> false + // can't infer extra polymorphism for constructors + | SynMemberKind.Constructor -> false + // feasible to infer extra polymorphism + | _ -> true) && + (match parentRef with + | Parent tcref -> not tcref.IsFSharpDelegateTycon + | _ -> true) // no generic parameters inferred for 'Invoke' method + + + +//------------------------------------------------------------------------- +// ComputeInlineFlag +//------------------------------------------------------------------------- + +let ComputeInlineFlag (memFlagsOption: SynMemberFlags option) isInline isMutable m = + let inlineFlag = + // Mutable values may never be inlined + // Constructors may never be inlined + // Calls to virtual/abstract slots may never be inlined + if isMutable || + (match memFlagsOption with + | None -> false + | Some x -> (x.MemberKind = SynMemberKind.Constructor) || x.IsDispatchSlot || x.IsOverrideOrExplicitImpl) + then ValInline.Never + elif isInline then ValInline.Always + else ValInline.Optional + if isInline && (inlineFlag <> ValInline.Always) then + errorR(Error(FSComp.SR.tcThisValueMayNotBeInlined(), m)) + inlineFlag + + +//------------------------------------------------------------------------- +// Binding normalization. +// +// Determine what sort of value is being bound (normal value, instance +// member, normal function, static member etc.) and make some +// name-resolution-sensitive adjustments to the syntax tree. +// +// One part of this "normalization" ensures: +// "let SynPat.LongIdent(f) = e" when f not a datatype constructor --> let Pat_var(f) = e" +// "let SynPat.LongIdent(f) pat = e" when f not a datatype constructor --> let Pat_var(f) = \pat. e" +// "let (SynPat.LongIdent(f) : ty) = e" when f not a datatype constructor --> let (Pat_var(f) : ty) = e" +// "let (SynPat.LongIdent(f) : ty) pat = e" when f not a datatype constructor --> let (Pat_var(f) : ty) = \pat. e" +// +// This is because the first lambda in a function definition "let F x = e" +// now looks like a constructor application, i.e. let (F x) = e ... +// also let A.F x = e ... +// also let f x = e ... +// +// The other parts turn property definitions into method definitions. +//------------------------------------------------------------------------- + + +// NormalizedBindingRhs records the r.h.s. of a binding after some munging just before type checking. +// NOTE: This is a bit of a mess. In the early implementation of F# we decided +// to have the parser convert "let f x = e" into +// "let f = fun x -> e". This is called "pushing" a pattern across to the right hand side. Complex +// patterns (e.g. non-tuple patterns) result in a computation on the right. +// However, this approach really isn't that great - especially since +// the language is now considerably more complex, e.g. we use +// type information from the first (but not the second) form in +// type inference for recursive bindings, and the first form +// may specify .NET attributes for arguments. There are still many +// relics of this approach around, e.g. the expression in BindingRhs +// below is of the second form. However, to extract relevant information +// we keep a record of the pats and optional explicit return type already pushed +// into expression so we can use any user-given type information from these +type NormalizedBindingRhs = + | NormalizedBindingRhs of + simplePats: SynSimplePats list * + returnTyOpt: SynBindingReturnInfo option * + rhsExpr: SynExpr + +let PushOnePatternToRhs (cenv: cenv) isMember p (NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr)) = + let spats, rhsExpr = PushPatternToExpr cenv.synArgNameGenerator isMember p rhsExpr + NormalizedBindingRhs(spats :: spatsL, rtyOpt, rhsExpr) + +type NormalizedBindingPatternInfo = + NormalizedBindingPat of SynPat * NormalizedBindingRhs * SynValData * SynValTyparDecls + +/// Represents a syntactic, unchecked binding after the resolution of the name resolution status of pattern +/// constructors and after "pushing" all complex patterns to the right hand side. +type NormalizedBinding = + | NormalizedBinding of + visibility: SynAccess option * + kind: SynBindingKind * + mustInline: bool * + isMutable: bool * + attribs: SynAttribute list * + xmlDoc: XmlDoc * + typars: SynValTyparDecls * + valSynData: SynValData * + pat: SynPat * + rhsExpr: NormalizedBindingRhs * + mBinding: range * + spBinding: DebugPointAtBinding + +type IsObjExprBinding = + | ObjExprBinding + | ValOrMemberBinding + +module BindingNormalization = + /// Push a bunch of pats at once. They may contain patterns, e.g. let f (A x) (B y) = ... + /// In this case the semantics is let f a b = let A x = a in let B y = b + let private PushMultiplePatternsToRhs (cenv: cenv) isMember pats (NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr)) = + let spatsL2, rhsExpr = PushCurriedPatternsToExpr cenv.synArgNameGenerator rhsExpr.Range isMember pats None rhsExpr + NormalizedBindingRhs(spatsL2@spatsL, rtyOpt, rhsExpr) + + + let private MakeNormalizedStaticOrValBinding cenv isObjExprBinding id vis typars args rhsExpr valSynData = + let (SynValData(memberFlagsOpt, _, _)) = valSynData + NormalizedBindingPat(mkSynPatVar vis id, PushMultiplePatternsToRhs cenv ((isObjExprBinding = ObjExprBinding) || Option.isSome memberFlagsOpt) args rhsExpr, valSynData, typars) + + let private MakeNormalizedInstanceMemberBinding cenv thisId memberId toolId vis m typars args rhsExpr valSynData = + NormalizedBindingPat(SynPat.InstanceMember(thisId, memberId, toolId, vis, m), PushMultiplePatternsToRhs cenv true args rhsExpr, valSynData, typars) + + let private NormalizeStaticMemberBinding cenv (memberFlags: SynMemberFlags) valSynData id vis typars args m rhsExpr = + let (SynValData(_, valSynInfo, thisIdOpt)) = valSynData + if memberFlags.IsInstance then + // instance method without adhoc "this" argument + error(Error(FSComp.SR.tcInstanceMemberRequiresTarget(), m)) + match args, memberFlags.MemberKind with + | _, SynMemberKind.PropertyGetSet -> error(Error(FSComp.SR.tcUnexpectedPropertyInSyntaxTree(), m)) + | [], SynMemberKind.ClassConstructor -> error(Error(FSComp.SR.tcStaticInitializerRequiresArgument(), m)) + | [], SynMemberKind.Constructor -> error(Error(FSComp.SR.tcObjectConstructorRequiresArgument(), m)) + | [_], SynMemberKind.ClassConstructor + | [_], SynMemberKind.Constructor -> MakeNormalizedStaticOrValBinding cenv ValOrMemberBinding id vis typars args rhsExpr valSynData + // Static property declared using 'static member P = expr': transformed to a method taking a "unit" argument + // static property: these transformed into methods taking one "unit" argument + | [], SynMemberKind.Member -> + let memberFlags = {memberFlags with MemberKind = SynMemberKind.PropertyGet} + let valSynData = SynValData(Some memberFlags, valSynInfo, thisIdOpt) + NormalizedBindingPat(mkSynPatVar vis id, + PushOnePatternToRhs cenv true (SynPat.Const(SynConst.Unit, m)) rhsExpr, + valSynData, + typars) + | _ -> MakeNormalizedStaticOrValBinding cenv ValOrMemberBinding id vis typars args rhsExpr valSynData + + let private NormalizeInstanceMemberBinding cenv (memberFlags: SynMemberFlags) valSynData thisId memberId (toolId: Ident option) vis typars args m rhsExpr = + let (SynValData(_, valSynInfo, thisIdOpt)) = valSynData + if not memberFlags.IsInstance then + // static method with adhoc "this" argument + error(Error(FSComp.SR.tcStaticMemberShouldNotHaveThis(), m)) + match args, memberFlags.MemberKind with + | _, SynMemberKind.ClassConstructor -> error(Error(FSComp.SR.tcExplicitStaticInitializerSyntax(), m)) + | _, SynMemberKind.Constructor -> error(Error(FSComp.SR.tcExplicitObjectConstructorSyntax(), m)) + | _, SynMemberKind.PropertyGetSet -> error(Error(FSComp.SR.tcUnexpectedPropertySpec(), m)) + // Instance property declared using 'x.Member': transformed to methods taking a "this" and a "unit" argument + // We push across the 'this' arg in mk_rec_binds + | [], SynMemberKind.Member -> + let memberFlags = {memberFlags with MemberKind = SynMemberKind.PropertyGet} + NormalizedBindingPat + (SynPat.InstanceMember(thisId, memberId, toolId, vis, m), + PushOnePatternToRhs cenv true (SynPat.Const(SynConst.Unit, m)) rhsExpr, + // Update the member info to record that this is a SynMemberKind.PropertyGet + SynValData(Some memberFlags, valSynInfo, thisIdOpt), + typars) + + | _ -> MakeNormalizedInstanceMemberBinding cenv thisId memberId toolId vis m typars args rhsExpr valSynData + + let private NormalizeBindingPattern cenv nameResolver isObjExprBinding (env: TcEnv) valSynData pat rhsExpr = + let ad = env.AccessRights + let (SynValData(memberFlagsOpt, _, _)) = valSynData + let rec normPattern pat = + // One major problem with versions of F# prior to 1.9.x was that data constructors easily 'pollute' the namespace + // of available items, to the point that you can't even define a function with the same name as an existing union case. + match pat with + | SynPat.FromParseError(p, _) -> normPattern p + | SynPat.LongIdent (LongIdentWithDots(longId, _), toolId, tyargs, SynArgPats.Pats args, vis, m) -> + let typars = match tyargs with None -> inferredTyparDecls | Some typars -> typars + match memberFlagsOpt with + | None -> + match ResolvePatternLongIdent cenv.tcSink nameResolver AllIdsOK true m ad env.NameEnv TypeNameResolutionInfo.Default longId with + | Item.NewDef id -> + if id.idText = opNameCons then + NormalizedBindingPat(pat, rhsExpr, valSynData, typars) + else + if isObjExprBinding = ObjExprBinding then + errorR(Deprecated(FSComp.SR.tcObjectExpressionFormDeprecated(), m)) + MakeNormalizedStaticOrValBinding cenv isObjExprBinding id vis typars args rhsExpr valSynData + | _ -> + error(Error(FSComp.SR.tcInvalidDeclaration(), m)) + + | Some memberFlags -> + match longId with + // x.Member in member binding patterns. + | [thisId;memberId] -> NormalizeInstanceMemberBinding cenv memberFlags valSynData thisId memberId toolId vis typars args m rhsExpr + | [memberId] -> + if memberFlags.IsInstance then + // instance method without adhoc "this" argument + errorR(Error(FSComp.SR.tcInstanceMemberRequiresTarget(), memberId.idRange)) + let thisId = ident ("_", m) + NormalizeInstanceMemberBinding cenv memberFlags valSynData thisId memberId toolId vis typars args m rhsExpr + else + NormalizeStaticMemberBinding cenv memberFlags valSynData memberId vis typars args m rhsExpr + | _ -> NormalizedBindingPat(pat, rhsExpr, valSynData, typars) + + // Object constructors are normalized in TcLetrec + // Here we are normalizing member definitions with simple (not long) ids, + // e.g. "static member x = 3" and "member x = 3" (instance with missing "this." comes through here. It is trapped and generates a warning) + | SynPat.Named(id, false, vis, m) + when + (match memberFlagsOpt with + | None -> false + | Some memberFlags -> + memberFlags.MemberKind <> SynMemberKind.Constructor && + memberFlags.MemberKind <> SynMemberKind.ClassConstructor) -> + NormalizeStaticMemberBinding cenv (Option.get memberFlagsOpt) valSynData id vis inferredTyparDecls [] m rhsExpr + + | SynPat.Typed(pat', x, y) -> + let (NormalizedBindingPat(pat'', e'', valSynData, typars)) = normPattern pat' + NormalizedBindingPat(SynPat.Typed(pat'', x, y), e'', valSynData, typars) + + | SynPat.Attrib(_, _, m) -> + error(Error(FSComp.SR.tcAttributesInvalidInPatterns(), m)) + + | _ -> + NormalizedBindingPat(pat, rhsExpr, valSynData, inferredTyparDecls) + normPattern pat + + let NormalizeBinding isObjExprBinding cenv (env: TcEnv) binding = + match binding with + | SynBinding (vis, bkind, isInline, isMutable, Attributes attrs, doc, valSynData, p, retInfo, rhsExpr, mBinding, spBind) -> + let (NormalizedBindingPat(pat, rhsExpr, valSynData, typars)) = + NormalizeBindingPattern cenv cenv.nameResolver isObjExprBinding env valSynData p (NormalizedBindingRhs ([], retInfo, rhsExpr)) + let paramNames = Some valSynData.SynValInfo.ArgNames + let doc = doc.ToXmlDoc(true, paramNames) + NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc, typars, valSynData, pat, rhsExpr, mBinding, spBind) + +//------------------------------------------------------------------------- +// input is: +// [] +// member x.P with get = fun () -> e +// --> +// member x.add_P< >(argName) = (e).AddHandler(argName) +// member x.remove_P< >(argName) = (e).RemoveHandler(argName) + +module EventDeclarationNormalization = + let ConvertSynInfo m (SynValInfo(argInfos, retInfo)) = + // reconstitute valSynInfo by adding the argument + let argInfos = + match argInfos with + | [[thisArgInfo];[]] -> [[thisArgInfo];SynInfo.unnamedTopArg] // instance property getter + | [[]] -> [SynInfo.unnamedTopArg] // static property getter + | _ -> error(BadEventTransformation m) + + // reconstitute valSynInfo + SynValInfo(argInfos, retInfo) + + // The property x.P becomes methods x.add_P and x.remove_P + let ConvertMemberFlags (memberFlags: SynMemberFlags) = { memberFlags with MemberKind = SynMemberKind.Member } + + let private ConvertMemberFlagsOpt m memberFlagsOpt = + match memberFlagsOpt with + | Some memberFlags -> Some (ConvertMemberFlags memberFlags) + | _ -> error(BadEventTransformation m) + + let private ConvertSynData m valSynData = + let (SynValData(memberFlagsOpt, valSynInfo, thisIdOpt)) = valSynData + let memberFlagsOpt = ConvertMemberFlagsOpt m memberFlagsOpt + let valSynInfo = ConvertSynInfo m valSynInfo + SynValData(memberFlagsOpt, valSynInfo, thisIdOpt) + + let rec private RenameBindingPattern f declPattern = + match declPattern with + | SynPat.FromParseError(p, _) -> RenameBindingPattern f p + | SynPat.Typed(pat', _, _) -> RenameBindingPattern f pat' + | SynPat.Named (id, x2, vis2, m) -> SynPat.Named (ident(f id.idText, id.idRange), x2, vis2, m) + | SynPat.InstanceMember(thisId, id, toolId, vis2, m) -> SynPat.InstanceMember(thisId, ident(f id.idText, id.idRange), toolId, vis2, m) + | _ -> error(Error(FSComp.SR.tcOnlySimplePatternsInLetRec(), declPattern.Range)) + + /// Some F# bindings syntactically imply additional bindings, notably properties + /// annotated with [] + let GenerateExtraBindings cenv (bindingAttribs, binding) = + let (NormalizedBinding(vis1, bindingKind, isInline, isMutable, _, bindingXmlDoc, _synTyparDecls, valSynData, declPattern, bindingRhs, mBinding, spBind)) = binding + if CompileAsEvent cenv.g bindingAttribs then + + let MakeOne (prefix, target) = + let declPattern = RenameBindingPattern (fun s -> prefix + s) declPattern + let argName = "handler" + // modify the rhs and argument data + let bindingRhs, valSynData = + let (NormalizedBindingRhs(_, _, rhsExpr)) = bindingRhs + let m = rhsExpr.Range + // reconstitute valSynInfo by adding the argument + let valSynData = ConvertSynData m valSynData + + match rhsExpr with + // Detect 'fun () -> e' which results from the compilation of a property getter + | SynExpr.Lambda (_, _, SynSimplePats.SimplePats([], _), _, trueRhsExpr, _, m) -> + let rhsExpr = mkSynApp1 (SynExpr.DotGet (SynExpr.Paren (trueRhsExpr, range0, None, m), range0, LongIdentWithDots([ident(target, m)], []), m)) (SynExpr.Ident (ident(argName, m))) m + + // reconstitute rhsExpr + let bindingRhs = NormalizedBindingRhs([], None, rhsExpr) + + // add the argument to the expression + let bindingRhs = PushOnePatternToRhs cenv true (mkSynPatVar None (ident (argName, mBinding))) bindingRhs + + bindingRhs, valSynData + | _ -> + error(BadEventTransformation m) + + // reconstitute the binding + NormalizedBinding(vis1, bindingKind, isInline, isMutable, [], bindingXmlDoc, noInferredTypars, valSynData, declPattern, bindingRhs, mBinding, spBind) + + [ MakeOne ("add_", "AddHandler"); MakeOne ("remove_", "RemoveHandler") ] + else + [] + + + +/// Make a copy of the "this" type for a generic object type, e.g. List<'T> --> List<'?> for a fresh inference variable. +/// Also adjust the "this" type to take into account whether the type is a struct. +let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars = +#if EXTENDED_EXTENSION_MEMBERS // indicates if extension members can add additional constraints to type parameters + let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy = FreshenTyconRef m (if isExtrinsic then TyparRigidity.Flexible else rigid) tcref declaredTyconTypars +#else + let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy = FreshenTyconRef m rigid tcref declaredTyconTypars +#endif + // Struct members have a byref 'this' type (unless they are extrinsic extension members) + let thisTy = + if not isExtrinsic && tcref.IsStructOrEnumTycon then + if isRecdOrStructTyReadOnly cenv.g m objTy then + mkInByrefTy cenv.g objTy + else + mkByrefTy cenv.g objTy + else + objTy + tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy + + +// The early generalization rule of F# 2.0 can be unsound for members in generic types (Bug DevDiv2 10649). +// It gives rise to types like "Forall T. ?X -> ?Y" where ?X and ?Y are later discovered to involve T. +// +// For example: +// type C<'T>() = +// let mutable x = Unchecked.defaultof<_> // unknown inference variable ?X +// static member A() = x +// // At this point A is generalized early to "Forall T. unit -> ?X" +// static member B1() = C.A() +// // At this point during type inference, the return type of C.A() is '?X' +// // After type inference, the return type of C.A() is 'string' +// static member B2() = C.A() +// // At this point during type inference, the return type of C.A() is '?X' +// // After type inference, the return type of C.A() is 'int' +// member this.C() = (x: 'T) +// // At this point during type inference the type of 'x' is inferred to be 'T' +// +// Here "A" is generalized too early. +// +// Ideally we would simply generalize "A" later, when it is known to be +// sound. However, that can lead to other problems (e.g. some programs that typecheck today would no longer +// be accepted). As a result, we deal with this unsoundness by an adhoc post-type-checking +// consistency check for recursive uses of "A" with explicit instantiations within the recursive +// scope of "A". +let TcValEarlyGeneralizationConsistencyCheck cenv (env: TcEnv) (v: Val, vrec, tinst, vty, tau, m) = + match vrec with + | ValInRecScope isComplete when isComplete && not (isNil tinst) -> + //printfn "pushing post-inference check for '%s', vty = '%s'" v.DisplayName (DebugPrint.showType vty) + cenv.postInferenceChecks.Add (fun () -> + //printfn "running post-inference check for '%s'" v.DisplayName + //printfn "tau = '%s'" (DebugPrint.showType tau) + //printfn "vty = '%s'" (DebugPrint.showType vty) + let tpsorig, tau2 = tryDestForallTy cenv.g vty + //printfn "tau2 = '%s'" (DebugPrint.showType tau2) + if not (isNil tpsorig) then + let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g tpsorig + let tau3 = instType (mkTyparInst tpsorig tinst) tau2 + //printfn "tau3 = '%s'" (DebugPrint.showType tau3) + if not (AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m tau tau3) then + let txt = bufs (fun buf -> NicePrint.outputQualifiedValSpec env.DisplayEnv cenv.infoReader buf (mkLocalValRef v)) + error(Error(FSComp.SR.tcInferredGenericTypeGivesRiseToInconsistency(v.DisplayName, txt), m))) + | _ -> () + + +/// TcVal. "Use" a value, normally at a fresh type instance (unless optInst is +/// given). optInst is set when an explicit type instantiation is given, e.g. +/// Seq.empty +/// In this case the vrefFlags inside optInst are just NormalValUse. +/// +/// optInst is is also set when building the final call for a reference to an +/// F# object model member, in which case the optInst is the type instantiation +/// inferred by member overload resolution, and vrefFlags indicate if the +/// member is being used in a special way, i.e. may be one of: +/// | CtorValUsedAsSuperInit "inherit Panel()" +/// | CtorValUsedAsSelfInit "new() = new OwnType(3)" +/// | VSlotDirectCall "base.OnClick(eventArgs)" +let TcVal checkAttributes cenv env tpenv (vref: ValRef) optInst optAfterResolution m = + let tpsorig, _, _, _, tinst, _ as res = + let v = vref.Deref + let vrec = v.RecursiveValInfo + v.SetHasBeenReferenced() + CheckValAccessible m env.eAccessRights vref + if checkAttributes then + CheckValAttributes cenv.g vref m |> CommitOperationResult + let vty = vref.Type + // byref-typed values get dereferenced + if isByrefTy cenv.g vty then + let isSpecial = true + [], mkAddrGet m vref, isSpecial, destByrefTy cenv.g vty, [], tpenv + else + match v.LiteralValue with + | Some c -> + // Literal values go to constants + let isSpecial = true + // The value may still be generic, e.g. + // [] + // let Null = null + let tpsorig, _, tinst, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty + tpsorig, Expr.Const (c, m, tau), isSpecial, tau, tinst, tpenv + + | None -> + // References to 'this' in classes get dereferenced from their implicit reference cell and poked + if v.IsCtorThisVal && isRefCellTy cenv.g vty then + let exprForVal = exprForValRef m vref + //if AreWithinCtorPreConstruct env then + // warning(SelfRefObjCtor(AreWithinImplicitCtor env, m)) + + let ty = destRefCellTy cenv.g vty + let isSpecial = true + [], mkCallCheckThis cenv.g m ty (mkRefCellGet cenv.g m ty exprForVal), isSpecial, ty, [], tpenv + else + // Instantiate the value + let tpsorig, vrefFlags, tinst, tau, tpenv = + // Have we got an explicit instantiation? + match optInst with + // No explicit instantiation (the normal case) + | None -> + if HasFSharpAttribute cenv.g cenv.g.attrib_RequiresExplicitTypeArgumentsAttribute v.Attribs then + errorR(Error(FSComp.SR.tcFunctionRequiresExplicitTypeArguments(v.DisplayName), m)) + + match vrec with + | ValInRecScope false -> + let tpsorig, tau = vref.TypeScheme + let tinst = tpsorig |> List.map mkTyparTy + tpsorig, NormalValUse, tinst, tau, tpenv + | ValInRecScope true + | ValNotInRecScope -> + let tpsorig, _, tinst, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty + tpsorig, NormalValUse, tinst, tau, tpenv + + // If we have got an explicit instantiation then use that + | Some(vrefFlags, checkTys) -> + let checkInst (tinst: TypeInst) = + if not v.IsMember && not v.PermitsExplicitTypeInstantiation && not (List.isEmpty tinst) && not (List.isEmpty v.Typars) then + warning(Error(FSComp.SR.tcDoesNotAllowExplicitTypeArguments(v.DisplayName), m)) + match vrec with + | ValInRecScope false -> + let tpsorig, tau = vref.TypeScheme + let (tinst: TypeInst), tpenv = checkTys tpenv (tpsorig |> List.map (fun tp -> tp.Kind)) + checkInst tinst + if tpsorig.Length <> tinst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tpsorig.Length, tinst.Length), m)) + let tau2 = instType (mkTyparInst tpsorig tinst) tau + (tpsorig, tinst) ||> List.iter2 (fun tp ty -> + try UnifyTypes cenv env m (mkTyparTy tp) ty + with _ -> error (Recursion(env.DisplayEnv, v.Id, tau2, tau, m))) + tpsorig, vrefFlags, tinst, tau2, tpenv + | ValInRecScope true + | ValNotInRecScope -> + let tpsorig, tps, tptys, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty + //dprintfn "After Freshen: tau = %s" (LayoutRender.showL (typeL tau)) + let (tinst: TypeInst), tpenv = checkTys tpenv (tps |> List.map (fun tp -> tp.Kind)) + checkInst tinst + //dprintfn "After Check: tau = %s" (LayoutRender.showL (typeL tau)) + if tptys.Length <> tinst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tps.Length, tinst.Length), m)) + List.iter2 (UnifyTypes cenv env m) tptys tinst + TcValEarlyGeneralizationConsistencyCheck cenv env (v, vrec, tinst, vty, tau, m) + + //dprintfn "After Unify: tau = %s" (LayoutRender.showL (typeL tau)) + tpsorig, vrefFlags, tinst, tau, tpenv + + let exprForVal = Expr.Val (vref, vrefFlags, m) + let exprForVal = mkTyAppExpr m (exprForVal, vty) tinst + let isSpecial = + (match vrefFlags with NormalValUse | PossibleConstrainedCall _ -> false | _ -> true) || + valRefEq cenv.g vref cenv.g.splice_expr_vref || + valRefEq cenv.g vref cenv.g.splice_raw_expr_vref + + let exprForVal = RecordUseOfRecValue cenv vrec vref exprForVal m + + tpsorig, exprForVal, isSpecial, tau, tinst, tpenv + + match optAfterResolution with + | Some (AfterResolution.RecordResolution(_, callSink, _, _)) -> callSink (mkTyparInst tpsorig tinst) + | Some AfterResolution.DoNothing | None -> () + res + +/// simplified version of TcVal used in calls to BuildMethodCall (typrelns.fs) +/// this function is used on typechecking step for making calls to provided methods and on optimization step (for the same purpose). +let LightweightTcValForUsingInBuildMethodCall g (vref: ValRef) vrefFlags (vrefTypeInst: TTypes) m = + let v = vref.Deref + let vty = vref.Type + // byref-typed values get dereferenced + if isByrefTy g vty then + mkAddrGet m vref, destByrefTy g vty + else + match v.LiteralValue with + | Some c -> + let _, _, _, tau = FreshenPossibleForallTy g m TyparRigidity.Flexible vty + Expr.Const (c, m, tau), tau + | None -> + // Instantiate the value + let tau = + // If we have got an explicit instantiation then use that + let _, tps, tptys, tau = FreshenPossibleForallTy g m TyparRigidity.Flexible vty + if tptys.Length <> vrefTypeInst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tps.Length, vrefTypeInst.Length), m)) + instType (mkTyparInst tps vrefTypeInst) tau + + let exprForVal = Expr.Val (vref, vrefFlags, m) + let exprForVal = mkTyAppExpr m (exprForVal, vty) vrefTypeInst + exprForVal, tau + +/// Mark points where we decide whether an expression will support automatic +/// decondensation or not. This is somewhat a relic of a previous implementation of decondensation and could +/// be removed + +type ApplicableExpr = + | ApplicableExpr of + // context + cenv * + // the function-valued expression + Expr * + // is this the first in an application series + bool + + member x.Range = + match x with + | ApplicableExpr (_, e, _) -> e.Range + + member x.Type = + match x with + | ApplicableExpr (cenv, e, _) -> tyOfExpr cenv.g e + + member x.SupplyArgument(e2, m) = + let (ApplicableExpr (cenv, fe, first)) = x + let combinedExpr = + match fe with + | Expr.App (e1, e1ty, tyargs1, args1, e1m) when + (not first || isNil args1) && + (not (isForallTy cenv.g e1ty) || isFunTy cenv.g (applyTys cenv.g e1ty (tyargs1, args1))) -> + Expr.App (e1, e1ty, tyargs1, args1@[e2], unionRanges e1m m) + | _ -> + Expr.App (fe, tyOfExpr cenv.g fe, [], [e2], m) + ApplicableExpr(cenv, combinedExpr, false) + + member x.Expr = + match x with + | ApplicableExpr(_, e, _) -> e + +let MakeApplicableExprNoFlex cenv expr = + ApplicableExpr (cenv, expr, true) + +/// This function reverses the effect of condensation for a named function value (indeed it can +/// work for any expression, though we only invoke it immediately after a call to TcVal). +/// +/// De-condensation is determined BEFORE any arguments are checked. Thus +/// let f (x:'a) (y:'a) = () +/// +/// f (new obj()) "string" +/// +/// does not type check (the argument instantiates 'a to "obj" but there is no flexibility on the +/// second argument position. +/// +/// De-condensation is applied AFTER taking into account an explicit type instantiation. This +/// let f<'a> (x:'a) = () +/// +/// f("string)" +/// +/// will type check but +/// +/// Sealed types and 'obj' do not introduce generic flexibility when functions are used as first class +/// values. +/// +/// For 'obj' this is because introducing this flexibility would NOT be the reverse of condensation, +/// since we don't condense +/// f: 'a -> unit +/// to +/// f: obj -> unit +/// +/// We represent the flexibility in the TAST by leaving a function-to-function coercion node in the tree +/// This "special" node is immediately eliminated by the use of IteratedFlexibleAdjustArityOfLambdaBody as soon as we +/// first transform the tree (currently in optimization) + +let MakeApplicableExprWithFlex cenv (env: TcEnv) expr = + let g = cenv.g + let exprTy = tyOfExpr g expr + let m = expr.Range + + let isNonFlexibleType ty = isSealedTy g ty + + let argTys, retTy = stripFunTy g exprTy + let curriedActualTypes = argTys |> List.map (tryDestRefTupleTy g) + if (curriedActualTypes.IsEmpty || + curriedActualTypes |> List.exists (List.exists (isByrefTy g)) || + curriedActualTypes |> List.forall (List.forall isNonFlexibleType)) then + + ApplicableExpr (cenv, expr, true) + else + let curriedFlexibleTypes = + curriedActualTypes |> List.mapSquared (fun actualType -> + if isNonFlexibleType actualType + then actualType + else + let flexibleType = NewInferenceType () + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace actualType flexibleType + flexibleType) + + // Create a coercion to represent the expansion of the application + let expr = mkCoerceExpr (expr, mkIteratedFunTy (List.map (mkRefTupledTy g) curriedFlexibleTypes) retTy, m, exprTy) + ApplicableExpr (cenv, expr, true) + + +/// Checks, warnings and constraint assertions for downcasts +let TcRuntimeTypeTest isCast isOperator cenv denv m tgtTy srcTy = + let g = cenv.g + if TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgtTy srcTy then + warning(TypeTestUnnecessary m) + + if isTyparTy g srcTy && not (destTyparTy g srcTy).IsCompatFlex then + error(IndeterminateRuntimeCoercion(denv, srcTy, tgtTy, m)) + + if isSealedTy g srcTy then + error(RuntimeCoercionSourceSealed(denv, srcTy, m)) + + if isSealedTy g tgtTy || isTyparTy g tgtTy || not (isInterfaceTy g srcTy) then + if isCast then + AddCxTypeMustSubsumeType (ContextInfo.RuntimeTypeTest isOperator) denv cenv.css m NoTrace srcTy tgtTy + else + AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace srcTy tgtTy + + if isErasedType g tgtTy then + if isCast then + warning(Error(FSComp.SR.tcTypeCastErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g tgtTy)), m)) + else + error(Error(FSComp.SR.tcTypeTestErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g tgtTy)), m)) + else + getErasedTypes g tgtTy |> + List.iter (fun ety -> if isMeasureTy g ety + then warning(Error(FSComp.SR.tcTypeTestLosesMeasures(NicePrint.minimalStringOfType denv ety), m)) + else warning(Error(FSComp.SR.tcTypeTestLossy(NicePrint.minimalStringOfType denv ety, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g ety)), m))) + +/// Checks, warnings and constraint assertions for upcasts +let TcStaticUpcast cenv denv m tgtTy srcTy = + if isTyparTy cenv.g tgtTy then + if not (destTyparTy cenv.g tgtTy).IsCompatFlex then + error(IndeterminateStaticCoercion(denv, srcTy, tgtTy, m)) + //else warning(UpcastUnnecessary m) + + if isSealedTy cenv.g tgtTy && not (isTyparTy cenv.g tgtTy) then + warning(CoercionTargetSealed(denv, tgtTy, m)) + + if typeEquiv cenv.g srcTy tgtTy then + warning(UpcastUnnecessary m) + + AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace tgtTy srcTy + +let BuildPossiblyConditionalMethodCall cenv env isMutable m isProp minfo valUseFlags minst objArgs args = + + let conditionalCallDefineOpt = TryFindMethInfoStringAttribute cenv.g m cenv.g.attrib_ConditionalAttribute minfo + + match conditionalCallDefineOpt, cenv.conditionalDefines with + | Some d, Some defines when not (List.contains d defines) -> + + // Methods marked with 'Conditional' must return 'unit' + UnifyTypes cenv env m cenv.g.unit_ty (minfo.GetFSharpReturnTy(cenv.amap, m, minst)) + mkUnit cenv.g m, cenv.g.unit_ty + + | _ -> +#if !NO_EXTENSIONTYPING + match minfo with + | ProvidedMeth(_, mi, _, _) -> + // BuildInvokerExpressionForProvidedMethodCall converts references to F# intrinsics back to values + // and uses TcVal to do this. However we don't want to check attributes again for provided references to values, + // so we pass 'false' for 'checkAttributes'. + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + let _, retExpt, retTy = ProvidedMethodCalls.BuildInvokerExpressionForProvidedMethodCall tcVal (cenv.g, cenv.amap, mi, objArgs, isMutable, isProp, valUseFlags, args, m) + retExpt, retTy + + | _ -> +#endif + let tcVal valref valUse ttypes m = + let _, a, _, b, _, _ = TcVal true cenv env emptyUnscopedTyparEnv valref (Some (valUse, (fun x _ -> ttypes, x))) None m + a, b + BuildMethodCall tcVal cenv.g cenv.amap isMutable m isProp minfo valUseFlags minst objArgs args + + +let TryFindIntrinsicOrExtensionMethInfo collectionSettings (cenv: cenv) (env: TcEnv) m ad nm ty = + AllMethInfosOfTypeInScope collectionSettings cenv.infoReader env.NameEnv (Some nm) ad IgnoreOverrides m ty + +let TryFindFSharpSignatureInstanceGetterProperty (cenv: cenv) (env: TcEnv) m nm ty (sigTys: TType list) = + TryFindIntrinsicPropInfo cenv.infoReader m env.AccessRights nm ty + |> List.tryFind (fun propInfo -> + not propInfo.IsStatic && propInfo.HasGetter && + ( + match propInfo.GetterMethod.GetParamTypes(cenv.amap, m, []) with + | [] -> false + | argTysList -> + + let argTys = (argTysList |> List.reduce (@)) @ [ propInfo.GetterMethod.GetFSharpReturnTy(cenv.amap, m, []) ] in + if argTys.Length <> sigTys.Length then + false + else + (argTys, sigTys) + ||> List.forall2 (typeEquiv cenv.g) + ) + ) + +/// Build the 'test and dispose' part of a 'use' statement +let BuildDisposableCleanup cenv env m (v: Val) = + v.SetHasBeenReferenced() + let ad = env.eAccessRights + let disposeMethod = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Dispose" cenv.g.system_IDisposable_ty with + | [x] -> x + | _ -> error(InternalError(FSComp.SR.tcCouldNotFindIDisposable(), m)) + + + // For struct types the test is simpler: we can determine if IDisposable is supported, and even when it is, we can avoid doing the type test + // Note this affects the elaborated form seen by quotations etc. + if isStructTy cenv.g v.Type then + if TypeFeasiblySubsumesType 0 cenv.g cenv.amap m cenv.g.system_IDisposable_ty CanCoerce v.Type then + // We can use NeverMutates here because the variable is going out of scope, there is no need to take a defensive + // copy of it. + let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false disposeMethod NormalValUse [] [exprForVal v.Range v] [] + disposeExpr + else + mkUnit cenv.g m + else + let disposeObjVar, disposeObjExpr = mkCompGenLocal m "objectToDispose" cenv.g.system_IDisposable_ty + let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] + let inpe = mkCoerceExpr(exprForVal v.Range v, cenv.g.obj_ty, m, v.Type) + mkIsInstConditional cenv.g m cenv.g.system_IDisposable_ty inpe disposeObjVar disposeExpr (mkUnit cenv.g m) + +/// Build call to get_OffsetToStringData as part of 'fixed' +let BuildOffsetToStringData cenv env m = + let ad = env.eAccessRights + let offsetToStringDataMethod = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_OffsetToStringData" cenv.g.system_RuntimeHelpers_ty with + | [x] -> x + | _ -> error(Error(FSComp.SR.tcCouldNotFindOffsetToStringData(), m)) + + let offsetExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false offsetToStringDataMethod NormalValUse [] [] [] + offsetExpr + +let BuildILFieldGet g amap m objExpr (finfo: ILFieldInfo) = + let fref = finfo.ILFieldRef + let isValueType = finfo.IsValueType + let valu = if isValueType then AsValue else AsObject + let tinst = finfo.TypeInst + let fieldType = finfo.FieldType (amap, m) +#if !NO_EXTENSIONTYPING + let ty = tyOfExpr g objExpr + match finfo with + | ProvidedField _ when (isErasedType g ty) -> + // we know it's accessible, and there are no attributes to check for now... + match finfo.LiteralValue with + | None -> + error (Error(FSComp.SR.tcTPFieldMustBeLiteral(), m)) + | Some lit -> + Expr.Const (TcFieldInit m lit, m, fieldType) + | _ -> +#endif + let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g isValueType false NeverMutates objExpr None m + // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm + // This ensures we always get the type instantiation right when doing this from + // polymorphic code, after inlining etc. * + let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) + // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. + wrap (mkAsmExpr (([ mkNormalLdfld fspec ] @ (if finfo.IsInitOnly then [ AI_nop ] else [])), tinst, [objExpr], [fieldType], m)) + +/// Checks that setting a field value does not set a literal or initonly field +let private CheckFieldLiteralArg (finfo: ILFieldInfo) argExpr m = + finfo.LiteralValue |> Option.iter (fun _ -> + match argExpr with + | Expr.Const (v, _, _) -> + let literalValue = string v + error (Error(FSComp.SR.tcLiteralFieldAssignmentWithArg literalValue, m)) + | _ -> + error (Error(FSComp.SR.tcLiteralFieldAssignmentNoArg(), m)) + ) + if finfo.IsInitOnly then error (Error (FSComp.SR.tcFieldIsReadonly(), m)) + +let BuildILFieldSet g m objExpr (finfo: ILFieldInfo) argExpr = + let fref = finfo.ILFieldRef + let isValueType = finfo.IsValueType + let valu = if isValueType then AsValue else AsObject + let tinst = finfo.TypeInst + // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm + // This ensures we always get the type instantiation right when doing this from + // polymorphic code, after inlining etc. * + let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) + CheckFieldLiteralArg finfo argExpr m + let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g isValueType false DefinitelyMutates objExpr None m + wrap (mkAsmExpr ([ mkNormalStfld fspec ], tinst, [objExpr; argExpr], [], m)) + +let BuildILStaticFieldSet m (finfo: ILFieldInfo) argExpr = + let fref = finfo.ILFieldRef + let isValueType = finfo.IsValueType + let valu = if isValueType then AsValue else AsObject + let tinst = finfo.TypeInst + // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm + // This ensures we always get the type instantiation right when doing this from + // polymorphic code, after inlining etc. + let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) + CheckFieldLiteralArg finfo argExpr m + mkAsmExpr ([ mkNormalStsfld fspec ], tinst, [argExpr], [], m) + +let BuildRecdFieldSet g m objExpr (rfinfo: RecdFieldInfo) argExpr = + let tgtTy = rfinfo.DeclaringType + let valu = isStructTy g tgtTy + let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, m, tyOfExpr g objExpr) + let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m + wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) ) + +//------------------------------------------------------------------------- +// Helpers dealing with named and optional args at callsites +//------------------------------------------------------------------------- + +let (|BinOpExpr|_|) e = + match e with + | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent opId, a, _), b, _) -> Some (opId, a, b) + | _ -> None + +let (|SimpleEqualsExpr|_|) e = + match e with + | BinOpExpr(opId, a, b) when opId.idText = opNameEquals -> Some (a, b) + | _ -> None + +/// Detect a named argument at a callsite +let TryGetNamedArg e = + match e with + | SimpleEqualsExpr(LongOrSingleIdent(isOpt, LongIdentWithDots([a], _), None, _), b) -> Some(isOpt, a, b) + | _ -> None + +let inline IsNamedArg e = + match e with + | SimpleEqualsExpr(LongOrSingleIdent(_, LongIdentWithDots([_], _), None, _), _) -> true + | _ -> false + +/// Get the method arguments at a callsite, taking into account named and optional arguments +let GetMethodArgs arg = + let args = + match arg with + | SynExpr.Const (SynConst.Unit, _) -> [] + | SynExprParen(SynExpr.Tuple (false, args, _, _), _, _, _) | SynExpr.Tuple (false, args, _, _) -> args + | SynExprParen(arg, _, _, _) | arg -> [arg] + let unnamedCallerArgs, namedCallerArgs = + args |> List.takeUntil IsNamedArg + let namedCallerArgs = + namedCallerArgs + |> List.choose (fun e -> + match TryGetNamedArg e with + | None -> + // ignore errors to avoid confusing error messages in cases like foo(a = 1, ) + // do not abort overload resolution in case if named arguments are mixed with errors + match e with + | SynExpr.ArbitraryAfterError _ -> None + | _ -> error(Error(FSComp.SR.tcNameArgumentsMustAppearLast(), e.Range)) + | namedArg -> namedArg) + unnamedCallerArgs, namedCallerArgs + + +//------------------------------------------------------------------------- +// Helpers dealing with pattern match compilation +//------------------------------------------------------------------------- + +let CompilePatternForMatch cenv (env: TcEnv) mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy = + let dtree, targets = CompilePattern cenv.g env.DisplayEnv cenv.amap (LightweightTcValForUsingInBuildMethodCall cenv.g) cenv.infoReader mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy + mkAndSimplifyMatch DebugPointAtBinding.NoneAtInvisible mExpr matchm resultTy dtree targets + +/// Compile a pattern +let CompilePatternForMatchClauses cenv env mExpr matchm warnOnUnused actionOnFailure inputExprOpt inputTy resultTy tclauses = + // Avoid creating a dummy in the common cases where we are about to bind a name for the expression + // CLEANUP: avoid code duplication with code further below, i.e.all callers should call CompilePatternForMatch + match tclauses with + | [TClause(TPat_as (pat1, PBind (asVal, TypeScheme(generalizedTypars, _)), _), None, TTarget(vs, e, spTarget, _), m2)] -> + let vs2 = ListSet.remove valEq asVal vs + let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (asVal, generalizedTypars, None) [TClause(pat1, None, TTarget(vs2, e, spTarget, None), m2)] inputTy resultTy + asVal, expr + | _ -> + let matchValueTmp, _ = mkCompGenLocal mExpr "matchValue" inputTy + let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (matchValueTmp, [], inputExprOpt) tclauses inputTy resultTy + matchValueTmp, expr + +//------------------------------------------------------------------------- +// Helpers dealing with sequence expressions +//------------------------------------------------------------------------- + +/// Get the fragmentary expressions resulting from turning +/// an expression into an enumerable value, e.g. at 'for' loops + +// localAlloc is relevant if the enumerator is a mutable struct and indicates +// if the enumerator can be allocated as a mutable local variable +let AnalyzeArbitraryExprAsEnumerable cenv (env: TcEnv) localAlloc m exprty expr = + let ad = env.AccessRights + + let err k ty = + let txt = NicePrint.minimalStringOfType env.DisplayEnv ty + let msg = if k then FSComp.SR.tcTypeCannotBeEnumerated txt else FSComp.SR.tcEnumTypeCannotBeEnumerated txt + Exception(Error(msg, m)) + + let findMethInfo k m nm ty = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad nm ty with + | [] -> err k ty + | res :: _ -> Result res + + // Ensure there are no curried arguments, and indeed no arguments at all + let hasArgs (minfo: MethInfo) minst = + match minfo.GetParamTypes(cenv.amap, m, minst) with + | [[]] -> false + | _ -> true + + let tryType (exprToSearchForGetEnumeratorAndItem, tyToSearchForGetEnumeratorAndItem) = + match findMethInfo true m "GetEnumerator" tyToSearchForGetEnumeratorAndItem with + | Exception e -> Exception e + | Result getEnumerator_minfo -> + + let getEnumerator_minst = FreshenMethInfo m getEnumerator_minfo + let retTypeOfGetEnumerator = getEnumerator_minfo.GetFSharpReturnTy(cenv.amap, m, getEnumerator_minst) + if hasArgs getEnumerator_minfo getEnumerator_minst then err true tyToSearchForGetEnumeratorAndItem else + + match findMethInfo false m "MoveNext" retTypeOfGetEnumerator with + | Exception e -> Exception e + | Result moveNext_minfo -> + + let moveNext_minst = FreshenMethInfo m moveNext_minfo + let retTypeOfMoveNext = moveNext_minfo.GetFSharpReturnTy(cenv.amap, m, moveNext_minst) + if not (typeEquiv cenv.g cenv.g.bool_ty retTypeOfMoveNext) then err false retTypeOfGetEnumerator else + if hasArgs moveNext_minfo moveNext_minst then err false retTypeOfGetEnumerator else + + match findMethInfo false m "get_Current" retTypeOfGetEnumerator with + | Exception e -> Exception e + | Result get_Current_minfo -> + + let get_Current_minst = FreshenMethInfo m get_Current_minfo + if hasArgs get_Current_minfo get_Current_minst then err false retTypeOfGetEnumerator else + let enumElemTy = get_Current_minfo.GetFSharpReturnTy(cenv.amap, m, get_Current_minst) + + // Compute the element type of the strongly typed enumerator + // + // Like C#, we detect the 'GetEnumerator' pattern for .NET version 1.x abstractions that don't + // support the correct generic interface. However unlike C# we also go looking for a 'get_Item' or 'Item' method + // with a single integer indexer argument to try to get a strong type for the enumeration should the Enumerator + // not provide anything useful. To enable interop with some legacy COM APIs, + // the single integer indexer argument is allowed to have type 'object'. + + let enumElemTy = + + if isObjTy cenv.g enumElemTy then + // Look for an 'Item' property, or a set of these with consistent return types + let allEquivReturnTypes (minfo: MethInfo) (others: MethInfo list) = + let returnTy = minfo.GetFSharpReturnTy(cenv.amap, m, []) + others |> List.forall (fun other -> typeEquiv cenv.g (other.GetFSharpReturnTy(cenv.amap, m, [])) returnTy) + + let isInt32OrObjectIndexer (minfo: MethInfo) = + match minfo.GetParamTypes(cenv.amap, m, []) with + | [[ty]] -> + // e.g. MatchCollection + typeEquiv cenv.g cenv.g.int32_ty ty || + // e.g. EnvDTE.Documents.Item + typeEquiv cenv.g cenv.g.obj_ty ty + | _ -> false + + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_Item" tyToSearchForGetEnumeratorAndItem with + | minfo :: others when (allEquivReturnTypes minfo others && + List.exists isInt32OrObjectIndexer (minfo :: others)) -> + minfo.GetFSharpReturnTy(cenv.amap, m, []) + + | _ -> + + // Some types such as XmlNodeList have only an Item method + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Item" tyToSearchForGetEnumeratorAndItem with + | minfo :: others when (allEquivReturnTypes minfo others && + List.exists isInt32OrObjectIndexer (minfo :: others)) -> + minfo.GetFSharpReturnTy(cenv.amap, m, []) + + | _ -> enumElemTy + else + enumElemTy + + let isEnumeratorTypeStruct = isStructTy cenv.g retTypeOfGetEnumerator + let originalRetTypeOfGetEnumerator = retTypeOfGetEnumerator + + let (enumeratorVar, enumeratorExpr), retTypeOfGetEnumerator = + if isEnumeratorTypeStruct then + if localAlloc then + mkMutableCompGenLocal m "enumerator" retTypeOfGetEnumerator, retTypeOfGetEnumerator + else + let refCellTyForRetTypeOfGetEnumerator = mkRefCellTy cenv.g retTypeOfGetEnumerator + let v, e = mkMutableCompGenLocal m "enumerator" refCellTyForRetTypeOfGetEnumerator + (v, mkRefCellGet cenv.g m retTypeOfGetEnumerator e), refCellTyForRetTypeOfGetEnumerator + + else + mkCompGenLocal m "enumerator" retTypeOfGetEnumerator, retTypeOfGetEnumerator + + let getEnumExpr, getEnumTy = + let getEnumExpr, getEnumTy as res = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false getEnumerator_minfo NormalValUse getEnumerator_minst [exprToSearchForGetEnumeratorAndItem] [] + if not isEnumeratorTypeStruct || localAlloc then res + else + // wrap enumerators that are represented as mutable structs into ref cells + let getEnumExpr = mkRefCell cenv.g m originalRetTypeOfGetEnumerator getEnumExpr + let getEnumTy = mkRefCellTy cenv.g getEnumTy + getEnumExpr, getEnumTy + + let guardExpr, guardTy = BuildPossiblyConditionalMethodCall cenv env DefinitelyMutates m false moveNext_minfo NormalValUse moveNext_minst [enumeratorExpr] [] + let currentExpr, currentTy = BuildPossiblyConditionalMethodCall cenv env DefinitelyMutates m true get_Current_minfo NormalValUse get_Current_minst [enumeratorExpr] [] + let currentExpr = mkCoerceExpr(currentExpr, enumElemTy, currentExpr.Range, currentTy) + let currentExpr, enumElemTy = + // Implicitly dereference byref for expr 'for x in ...' + if isByrefTy cenv.g enumElemTy then + let expr = mkDerefAddrExpr m currentExpr currentExpr.Range enumElemTy + expr, destByrefTy cenv.g enumElemTy + else + currentExpr, enumElemTy + + Result(enumeratorVar, enumeratorExpr, retTypeOfGetEnumerator, enumElemTy, getEnumExpr, getEnumTy, guardExpr, guardTy, currentExpr) + + // First try the original known static type + match (if isArray1DTy cenv.g exprty then Exception (Failure "") else tryType (expr, exprty)) with + | Result res -> res + | Exception e -> + + let probe ty = + if (AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m ty exprty) then + match tryType (mkCoerceExpr(expr, ty, expr.Range, exprty), ty) with + | Result res -> Some res + | Exception e -> + PreserveStackTrace e + raise e + else None + + // Next try to typecheck the thing as a sequence + let enumElemTy = NewInferenceType () + let exprTyAsSeq = mkSeqTy cenv.g enumElemTy + + match probe exprTyAsSeq with + | Some res -> res + | None -> + let ienumerable = mkAppTy cenv.g.tcref_System_Collections_IEnumerable [] + match probe ienumerable with + | Some res -> res + | None -> + PreserveStackTrace e + raise e + +// Used inside sequence expressions +let ConvertArbitraryExprToEnumerable (cenv: cenv) ty (env: TcEnv) (expr: Expr) = + let m = expr.Range + let enumElemTy = NewInferenceType () + if AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m ( mkSeqTy cenv.g enumElemTy) ty then + expr, enumElemTy + else + let enumerableVar, enumerableExpr = mkCompGenLocal m "inputSequence" ty + let enumeratorVar, _, retTypeOfGetEnumerator, enumElemTy, getEnumExpr, _, guardExpr, guardTy, betterCurrentExpr = + AnalyzeArbitraryExprAsEnumerable cenv env false m ty enumerableExpr + + let expr = + mkCompGenLet m enumerableVar expr + (mkCallSeqOfFunctions cenv.g m retTypeOfGetEnumerator enumElemTy + (mkUnitDelayLambda cenv.g m getEnumExpr) + (mkLambda m enumeratorVar (guardExpr, guardTy)) + (mkLambda m enumeratorVar (betterCurrentExpr, enumElemTy))) + expr, enumElemTy + +//------------------------------------------------------------------------- +// Post-transform initialization graphs using the 'lazy' interpretation. +// See ML workshop paper. +//------------------------------------------------------------------------- + +type InitializationGraphAnalysisState = + | Top + | InnerTop + | DefinitelyStrict + | MaybeLazy + | DefinitelyLazy + +type PreInitializationGraphEliminationBinding = + { FixupPoints: RecursiveUseFixupPoints + Binding: Binding } + +/// Check for safety and determine if we need to insert lazy thunks +let EliminateInitializationGraphs + g + mustHaveArity + denv + (bindings: 'Bindings list) + (iterBindings: (PreInitializationGraphEliminationBinding list -> unit) -> 'Bindings list -> unit) + (buildLets: Binding list -> 'Result) + (mapBindings: (PreInitializationGraphEliminationBinding list -> Binding list) -> 'Bindings list -> 'Result list) + bindsm = + + let recursiveVals = + let hash = ValHash.Create() + let add (pgrbind: PreInitializationGraphEliminationBinding) = let c = pgrbind.Binding.Var in hash.Add(c, c) + bindings |> iterBindings (List.iter add) + hash + + // The output of the analysis + let mutable outOfOrder = false + let mutable runtimeChecks = false + let mutable directRecursiveData = false + let mutable reportedEager = false + let mutable definiteDependencies = [] + + let rec stripChooseAndExpr e = + match stripExpr e with + | Expr.TyChoose (_, b, _) -> stripChooseAndExpr b + | e -> e + + let availIfInOrder = ValHash<_>.Create() + let check boundv expr = + let strict = function + | MaybeLazy -> MaybeLazy + | DefinitelyLazy -> DefinitelyLazy + | Top | DefinitelyStrict | InnerTop -> DefinitelyStrict + let lzy = function + | Top | InnerTop | DefinitelyLazy -> DefinitelyLazy + | MaybeLazy | DefinitelyStrict -> MaybeLazy + let fixable = function + | Top | InnerTop -> InnerTop + | DefinitelyStrict -> DefinitelyStrict + | MaybeLazy -> MaybeLazy + | DefinitelyLazy -> DefinitelyLazy + + let rec CheckExpr st e = + match stripChooseAndExpr e with + // Expressions with some lazy parts + | Expr.Lambda (_, _, _, _, b, _, _) -> checkDelayed st b + + // Type-lambdas are analyzed as if they are strict. + // + // This is a design decision (See bug 6496), so that generalized recursive bindings such as + // let rec x = x + // are analyzed. Although we give type "x: 'T" to these, from the users point of view + // any use of "x" will result in an infinite recursion. Type instantiation is implicit in F# + // because of type inference, which makes it reasonable to check generic bindings strictly. + | Expr.TyLambda (_, _, b, _, _) -> CheckExpr st b + + | Expr.Obj (_, ty, _, e, overrides, extraImpls, _) -> + // NOTE: we can't fixup recursive references inside delegates since the closure delegee of a delegate is not accessible + // from outside. Object expressions implementing interfaces can, on the other hand, be fixed up. See FSharp 1.0 bug 1469 + if isInterfaceTy g ty then + List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> checkDelayed st e) overrides + List.iter (snd >> List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> checkDelayed st e)) extraImpls + else + CheckExpr (strict st) e + List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> CheckExpr (lzy (strict st)) e) overrides + List.iter (snd >> List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> CheckExpr (lzy (strict st)) e)) extraImpls + + // Expressions where fixups may be needed + | Expr.Val (v, _, m) -> CheckValRef st v m + + // Expressions where subparts may be fixable + | Expr.Op ((TOp.Tuple _ | TOp.UnionCase _ | TOp.Recd _), _, args, _) -> + List.iter (CheckExpr (fixable st)) args + + // Composite expressions + | Expr.Const _ -> () + | Expr.LetRec (binds, e, _, _) -> + binds |> List.iter (CheckBinding (strict st)) + CheckExpr (strict st) e + | Expr.Let (bind, e, _, _) -> + CheckBinding (strict st) bind + CheckExpr (strict st) e + | Expr.Match (_, _, pt, targets, _, _) -> + CheckDecisionTree (strict st) pt + Array.iter (CheckDecisionTreeTarget (strict st)) targets + | Expr.App (e1, _, _, args, _) -> + CheckExpr (strict st) e1 + List.iter (CheckExpr (strict st)) args + // Binary expressions + | Expr.Sequential (e1, e2, _, _, _) + | Expr.StaticOptimization (_, e1, e2, _) -> + CheckExpr (strict st) e1; CheckExpr (strict st) e2 + // n-ary expressions + | Expr.Op (op, _, args, m) -> CheckExprOp st op m; List.iter (CheckExpr (strict st)) args + // misc + | Expr.Link eref -> CheckExpr st eref.Value + | Expr.TyChoose (_, b, _) -> CheckExpr st b + | Expr.Quote _ -> () + | Expr.WitnessArg (_witnessInfo, _m) -> () + + and CheckBinding st (TBind(_, e, _)) = CheckExpr st e + + and CheckDecisionTree st = function + | TDSwitch(_, e1, csl, dflt, _) -> CheckExpr st e1; List.iter (fun (TCase(_, d)) -> CheckDecisionTree st d) csl; Option.iter (CheckDecisionTree st) dflt + | TDSuccess (es, _) -> es |> List.iter (CheckExpr st) + | TDBind(bind, e) -> CheckBinding st bind; CheckDecisionTree st e + + and CheckDecisionTreeTarget st (TTarget(_, e, _, _)) = CheckExpr st e + + and CheckExprOp st op m = + match op with + | TOp.LValueOp (_, lvr) -> CheckValRef (strict st) lvr m + | _ -> () + + and CheckValRef st (v: ValRef) m = + match st with + | MaybeLazy -> + if recursiveVals.TryFind v.Deref |> Option.isSome then + warning (RecursiveUseCheckedAtRuntime (denv, v, m)) + if not reportedEager then + (warning (LetRecCheckedAtRuntime m); reportedEager <- true) + runtimeChecks <- true + + | Top | DefinitelyStrict -> + if recursiveVals.TryFind v.Deref |> Option.isSome then + if availIfInOrder.TryFind v.Deref |> Option.isNone then + warning (LetRecEvaluatedOutOfOrder (denv, boundv, v, m)) + outOfOrder <- true + if not reportedEager then + (warning (LetRecCheckedAtRuntime m); reportedEager <- true) + definiteDependencies <- (boundv, v) :: definiteDependencies + | InnerTop -> + if recursiveVals.TryFind v.Deref |> Option.isSome then + directRecursiveData <- true + | DefinitelyLazy -> () + and checkDelayed st b = + match st with + | MaybeLazy | DefinitelyStrict -> CheckExpr MaybeLazy b + | DefinitelyLazy | Top | InnerTop -> () + + + CheckExpr Top expr + + + // Check the bindings one by one, each w.r.t. the previously available set of binding + begin + let checkBind (pgrbind: PreInitializationGraphEliminationBinding) = + let (TBind(v, e, _)) = pgrbind.Binding + check (mkLocalValRef v) e + availIfInOrder.Add(v, 1) + bindings |> iterBindings (List.iter checkBind) + end + + // ddg = definiteDependencyGraph + let ddgNodes = recursiveVals.Values |> Seq.toList |> List.map mkLocalValRef + let ddg = Graph((fun v -> v.Stamp), ddgNodes, definiteDependencies ) + ddg.IterateCycles (fun path -> error (LetRecUnsound (denv, path, path.Head.Range))) + + let requiresLazyBindings = runtimeChecks || outOfOrder + if directRecursiveData && requiresLazyBindings then + error(Error(FSComp.SR.tcInvalidMixtureOfRecursiveForms(), bindsm)) + + if requiresLazyBindings then + let morphBinding (pgrbind: PreInitializationGraphEliminationBinding) = + let (RecursiveUseFixupPoints fixupPoints) = pgrbind.FixupPoints + let (TBind(v, e, seqPtOpt)) = pgrbind.Binding + match stripChooseAndExpr e with + | Expr.Lambda _ | Expr.TyLambda _ -> + [], [mkInvisibleBind v e] + | _ -> + let ty = v.Type + let m = v.Range + let vty = (mkLazyTy g ty) + + let fty = (g.unit_ty --> ty) + let flazy, felazy = mkCompGenLocal m v.LogicalName fty + let frhs = mkUnitDelayLambda g m e + if mustHaveArity then flazy.SetValReprInfo (Some(InferArityOfExpr g AllowTypeDirectedDetupling.Yes fty [] [] frhs)) + + let vlazy, velazy = mkCompGenLocal m v.LogicalName vty + let vrhs = (mkLazyDelayed g m ty felazy) + + if mustHaveArity then vlazy.SetValReprInfo (Some(InferArityOfExpr g AllowTypeDirectedDetupling.Yes vty [] [] vrhs)) + for (fixupPoint, _) in fixupPoints do + fixupPoint.Value <- mkLazyForce g fixupPoint.Value.Range ty velazy + + [mkInvisibleBind flazy frhs; mkInvisibleBind vlazy vrhs], + [mkBind seqPtOpt v (mkLazyForce g m ty velazy)] + + let newTopBinds = ResizeArray<_>() + let morphBindings pgrbinds = pgrbinds |> List.map morphBinding |> List.unzip |> (fun (a, b) -> newTopBinds.Add (List.concat a); List.concat b) + + let res = bindings |> mapBindings morphBindings + if newTopBinds.Count = 0 then res + else buildLets (List.concat newTopBinds) :: res + else + let noMorph (pgrbinds: PreInitializationGraphEliminationBinding list) = pgrbinds |> List.map (fun pgrbind -> pgrbind.Binding) + bindings |> mapBindings noMorph + +//------------------------------------------------------------------------- +// Check the shape of an object constructor and rewrite calls +//------------------------------------------------------------------------- + +let CheckAndRewriteObjectCtor g env (ctorLambdaExpr: Expr) = + + let m = ctorLambdaExpr.Range + let tps, vsl, body, returnTy = stripTopLambda (ctorLambdaExpr, tyOfExpr g ctorLambdaExpr) + + // Rewrite legitimate self-construction calls to CtorValUsedAsSelfInit + let error (expr: Expr) = + errorR(Error(FSComp.SR.tcInvalidObjectConstructionExpression(), expr.Range)) + expr + + // Build an assignment into the safeThisValOpt mutable reference cell that holds recursive references to 'this' + // Build an assignment into the safeInitInfo mutable field that indicates that partial initialization is successful + let rewriteConstruction recdExpr = + match env.eCtorInfo with + | None -> recdExpr + | Some ctorInfo -> + let recdExpr = + match ctorInfo.safeThisValOpt with + | None -> recdExpr + | Some safeInitVal -> + let ty = tyOfExpr g recdExpr + let thisExpr = mkGetArg0 m ty + let setExpr = mkRefCellSet g m ty (exprForValRef m (mkLocalValRef safeInitVal)) thisExpr + Expr.Sequential (recdExpr, setExpr, ThenDoSeq, DebugPointAtSequential.SuppressStmt, m) + let recdExpr = + match ctorInfo.safeInitInfo with + | NoSafeInitInfo -> recdExpr + | SafeInitField (rfref, _) -> + let thisTy = tyOfExpr g recdExpr + let thisExpr = mkGetArg0 m thisTy + let thisTyInst = argsOfAppTy g thisTy + let setExpr = mkRecdFieldSetViaExprAddr (thisExpr, rfref, thisTyInst, mkOne g m, m) + Expr.Sequential (recdExpr, setExpr, ThenDoSeq, DebugPointAtSequential.SuppressStmt, m) + recdExpr + + + let rec checkAndRewrite (expr: Expr) = + match expr with + // = { fields } + // The constructor ends in an object initialization expression - good + | Expr.Op (TOp.Recd (RecdExprIsObjInit, _), _, _, _) -> rewriteConstruction expr + + // = "a; " + | Expr.Sequential (a, body, NormalSeq, spSeq, b) -> Expr.Sequential (a, checkAndRewrite body, NormalSeq, spSeq, b) + + // = " then " + | Expr.Sequential (body, a, ThenDoSeq, spSeq, b) -> Expr.Sequential (checkAndRewrite body, a, ThenDoSeq, spSeq, b) + + // = "let pat = expr in " + | Expr.Let (bind, body, m, _) -> mkLetBind m bind (checkAndRewrite body) + + // The constructor is a sequence "let pat = expr in " + | Expr.Match (spBind, a, b, targets, c, d) -> + let targets = targets |> Array.map (fun (TTarget(vs, body, spTarget, flags)) -> TTarget(vs, checkAndRewrite body, spTarget, flags)) + Expr.Match (spBind, a, b, targets, c, d) + + // = "let rec binds in " + | Expr.LetRec (a, body, _, _) -> Expr.LetRec (a, checkAndRewrite body, m, Construct.NewFreeVarsCache()) + + // = "new C(...)" + | Expr.App (f, b, c, d, m) -> + // The application had better be an application of a ctor + let f = checkAndRewriteCtorUsage f + let expr = Expr.App (f, b, c, d, m) + rewriteConstruction expr + + | _ -> + error expr + + and checkAndRewriteCtorUsage expr = + match expr with + | Expr.Link eref -> + let e = checkAndRewriteCtorUsage eref.Value + eref.Value <- e + expr + + // Type applications are ok, e.g. + // type C<'a>(x: int) = + // new() = C<'a>(3) + | Expr.App (f, fty, tyargs, [], m) -> + let f = checkAndRewriteCtorUsage f + Expr.App (f, fty, tyargs, [], m) + + // Self-calls are OK and get rewritten. + | Expr.Val (vref, NormalValUse, a) -> + let isCtor = + match vref.MemberInfo with + | None -> false + | Some memberInfo -> memberInfo.MemberFlags.MemberKind = SynMemberKind.Constructor + + if not isCtor then + error expr + else + Expr.Val (vref, CtorValUsedAsSelfInit, a) + | _ -> + error expr + + let body = checkAndRewrite body + mkMultiLambdas m tps vsl (body, returnTy) + + + +/// Post-typechecking normalizations to enforce semantic constraints +/// lazy and, lazy or, rethrow, address-of +let buildApp cenv expr resultTy arg m = + let g = cenv.g + match expr, arg with + + // Special rule for building applications of the 'x && y' operator + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [x0], _), _), _ + when valRefEq g vf g.and_vref + || valRefEq g vf g.and2_vref -> + MakeApplicableExprNoFlex cenv (mkLazyAnd g m x0 arg), resultTy + + // Special rule for building applications of the 'x || y' operator + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [x0], _), _), _ + when valRefEq g vf g.or_vref + || valRefEq g vf g.or2_vref -> + MakeApplicableExprNoFlex cenv (mkLazyOr g m x0 arg ), resultTy + + // Special rule for building applications of the 'reraise' operator + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ + when valRefEq g vf g.reraise_vref -> + + // exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type. + MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy + + // Special rules for NativePtr.ofByRef to generalize result. + // See RFC FS-1053.md + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ + when (valRefEq g vf g.nativeptr_tobyref_vref) -> + + let argty = NewInferenceType() + let resultTy = mkByrefTyWithInference g argty (NewByRefKindInferenceType g m) + expr.SupplyArgument (arg, m), resultTy + + // Special rules for building applications of the '&expr' operator, which gets the + // address of an expression. + // + // See also RFC FS-1053.md + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ + when valRefEq g vf g.addrof_vref -> + + let wrap, e1a', readonly, _writeonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some vf) m + // Assert the result type to be readonly if we couldn't take the address + let resultTy = + let argTy = tyOfExpr g arg + if readonly then + mkInByrefTy g argTy + + // "`outref<'T>` types are never introduced implicitly by F#.", see rationale in RFC FS-1053 + // + // We do _not_ introduce outref here, e.g. '&x' where 'x' is outref<_> is _not_ outref. + // This effectively makes 'outref<_>' documentation-only. There is frequently a need to pass outref + // pointers to .NET library functions whose signatures are not tagged with [] + //elif writeonly then + // mkOutByrefTy g argTy + + else + mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) + + MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy + + // Special rules for building applications of the &&expr' operators, which gets the + // address of an expression. + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ + when valRefEq g vf g.addrof2_vref -> + + warning(UseOfAddressOfOperator m) + let wrap, e1a', _readonly, _writeonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some vf) m + MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy + + | _ when isByrefTy g resultTy -> + // Handle byref returns, byref-typed returns get implicitly dereferenced + let expr = expr.SupplyArgument (arg, m) + let expr = mkDerefAddrExpr m expr.Expr m resultTy + let resultTy = destByrefTy g resultTy + MakeApplicableExprNoFlex cenv expr, resultTy + + | _ -> + expr.SupplyArgument (arg, m), resultTy + +//------------------------------------------------------------------------- +// Additional data structures used by type checking +//------------------------------------------------------------------------- + +type DelayedItem = + /// Represents the in "item" + | DelayedTypeApp of + typeArgs: SynType list * + mTypeArgs: range * + mExprAndTypeArgs: range + + /// Represents the args in "item args", or "item.Property(args)". + | DelayedApp of + isAtomic: ExprAtomicFlag * + isSugar: bool * + synLeftExprOpt: SynExpr option * + argExpr: SynExpr * + mFuncAndArg: range + + /// Represents the long identifiers in "item.Ident1", or "item.Ident1.Ident2" etc. + | DelayedDotLookup of + idents: Ident list * + range + + /// Represents an incomplete "item." + | DelayedDot + + /// Represents the valueExpr in "item <- valueExpr", also "item.[indexerArgs] <- valueExpr" etc. + | DelayedSet of SynExpr * range + +let MakeDelayedSet(e: SynExpr, m) = + // We have longId <- e. Wrap 'e' in another pair of parentheses to ensure it's never interpreted as + // a named argument, e.g. for "el.Checked <- (el = el2)" + DelayedSet (SynExpr.Paren (e, range0, None, e.Range), m) + +/// Indicates if member declarations are allowed to be abstract members. +type NewSlotsOK = + | NewSlotsOK + | NoNewSlots + +/// Indicates whether a syntactic type is allowed to include new type variables +/// not declared anywhere, e.g. `let f (x: 'T option) = x.Value` +type ImplicitlyBoundTyparsAllowed = + | NewTyparsOKButWarnIfNotRigid + | NewTyparsOK + | NoNewTypars + +/// Indicates whether constraints should be checked when checking syntactic types +type CheckConstraints = + | CheckCxs + | NoCheckCxs + +/// Represents information about the module or type in which a member or value is declared. +type MemberOrValContainerInfo = + | MemberOrValContainerInfo of + tcref: TyconRef * + optIntfSlotTy: (TType * SlotImplSet) option * + baseValOpt: Val option * + safeInitInfo: SafeInitData * + declaredTyconTypars: Typars + +/// Provides information about the context for a value or member definition +type ContainerInfo = + | ContainerInfo of + // The nearest containing module. Used as the 'actual' parent for extension members and values + ParentRef * + // For members: + MemberOrValContainerInfo option + member x.ParentRef = + let (ContainerInfo(v, _)) = x + v + +/// Indicates a declaration is contained in an expression +let ExprContainerInfo = ContainerInfo(ParentNone, None) + +type NormalizedRecBindingDefn = + | NormalizedRecBindingDefn of + containerInfo: ContainerInfo * + newslotsOk: NewSlotsOK * + declKind: DeclKind * + binding: NormalizedBinding + +type ValSpecResult = + | ValSpecResult of + altActualParent: ParentRef * + memberInfoOpt: PreValMemberInfo option * + id: Ident * + enclosingDeclaredTypars: Typars * + declaredTypars: Typars * + ty: TType * + partialValReprInfo: PartialValReprInfo * + declKind: DeclKind + +type DecodedIndexArg = + | IndexArgRange of (SynExpr * bool) option * (SynExpr * bool) option * range * range + | IndexArgItem of SynExpr * bool * range +//------------------------------------------------------------------------- +// Additional data structures used by checking recursive bindings +//------------------------------------------------------------------------- + +type RecDefnBindingInfo = + | RecDefnBindingInfo of + containerInfo: ContainerInfo * + newslotsOk: NewSlotsOK * + declKind: DeclKind * + synBinding: SynBinding + +/// RecursiveBindingInfo - flows through initial steps of TcLetrec +type RecursiveBindingInfo = + | RecursiveBindingInfo of + recBindIndex: int * // index of the binding in the recursive group + containerInfo: ContainerInfo * + enclosingDeclaredTypars: Typars * + inlineFlag: ValInline * + vspec: Val * + explicitTyparInfo: ExplicitTyparInfo * + partialValReprInfo: PartialValReprInfo * + memberInfoOpt: PreValMemberInfo option * + baseValOpt: Val option * + safeThisValOpt: Val option * + safeInitInfo: SafeInitData * + visibility: SynAccess option * + ty: TType * + declKind: DeclKind + + member x.EnclosingDeclaredTypars = let (RecursiveBindingInfo(_, _, enclosingDeclaredTypars, _, _, _, _, _, _, _, _, _, _, _)) = x in enclosingDeclaredTypars + member x.Val = let (RecursiveBindingInfo(_, _, _, _, vspec, _, _, _, _, _, _, _, _, _)) = x in vspec + member x.ExplicitTyparInfo = let (RecursiveBindingInfo(_, _, _, _, _, explicitTyparInfo, _, _, _, _, _, _, _, _)) = x in explicitTyparInfo + member x.DeclaredTypars = let (ExplicitTyparInfo(_, declaredTypars, _)) = x.ExplicitTyparInfo in declaredTypars + member x.Index = let (RecursiveBindingInfo(i, _, _, _, _, _, _, _, _, _, _, _, _, _)) = x in i + member x.ContainerInfo = let (RecursiveBindingInfo(_, c, _, _, _, _, _, _, _, _, _, _, _, _)) = x in c + member x.DeclKind = let (RecursiveBindingInfo(_, _, _, _, _, _, _, _, _, _, _, _, _, declKind)) = x in declKind + +type PreCheckingRecursiveBinding = + { SyntacticBinding: NormalizedBinding + RecBindingInfo: RecursiveBindingInfo } + +type PreGeneralizationRecursiveBinding = + { ExtraGeneralizableTypars: Typars + CheckedBinding: CheckedBindingInfo + RecBindingInfo: RecursiveBindingInfo } + +type PostGeneralizationRecursiveBinding = + { ValScheme: ValScheme + CheckedBinding: CheckedBindingInfo + RecBindingInfo: RecursiveBindingInfo } + member x.GeneralizedTypars = x.ValScheme.GeneralizedTypars + +type PostSpecialValsRecursiveBinding = + { ValScheme: ValScheme + Binding: Binding } + +let CanInferExtraGeneralizedTyparsForRecBinding (pgrbind: PreGeneralizationRecursiveBinding) = + let explicitTyparInfo = pgrbind.RecBindingInfo.ExplicitTyparInfo + let (ExplicitTyparInfo(_, _, canInferTypars)) = explicitTyparInfo + let memFlagsOpt = pgrbind.RecBindingInfo.Val.MemberInfo |> Option.map (fun memInfo -> memInfo.MemberFlags) + let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (pgrbind.RecBindingInfo.ContainerInfo.ParentRef, canInferTypars, memFlagsOpt) + canInferTypars + +/// Get the "this" variable from an instance member binding +let GetInstanceMemberThisVariable (vspec: Val, expr) = + // Skip over LAM tps. Choose 'a. + if vspec.IsInstanceMember then + let rec firstArg e = + match e with + | Expr.TyLambda (_, _, b, _, _) -> firstArg b + | Expr.TyChoose (_, b, _) -> firstArg b + | Expr.Lambda (_, _, _, [v], _, _, _) -> Some v + | _ -> failwith "GetInstanceMemberThisVariable: instance member did not have expected internal form" + + firstArg expr + else + None + +//------------------------------------------------------------------------- +// Checking types and type constraints +//------------------------------------------------------------------------- +/// Check specifications of constraints on type parameters +let rec TcTyparConstraint ridx cenv newOk checkCxs occ (env: TcEnv) tpenv c = + let checkSimpleConstraint tp m constraintAdder = + let tp', tpenv = TcTypar cenv env newOk tpenv tp + constraintAdder env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') + tpenv + + match c with + | SynTypeConstraint.WhereTyparDefaultsToType(tp, ty, m) -> + let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty + let tp', tpenv = TcTypar cenv env newOk tpenv tp + AddCxTyparDefaultsTo env.DisplayEnv cenv.css m env.eContextInfo tp' ridx ty' + tpenv + + | SynTypeConstraint.WhereTyparSubtypeOfType(tp, ty, m) -> + let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType env tpenv ty + let tp', tpenv = TcTypar cenv env newOk tpenv tp + if newOk = NoNewTypars && isSealedTy cenv.g ty' then + errorR(Error(FSComp.SR.tcInvalidConstraintTypeSealed(), m)) + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty' (mkTyparTy tp') + tpenv + + | SynTypeConstraint.WhereTyparSupportsNull(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportNull + + | SynTypeConstraint.WhereTyparIsComparable(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportComparison + + | SynTypeConstraint.WhereTyparIsEquatable(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportEquality + + | SynTypeConstraint.WhereTyparIsReferenceType(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsReferenceType + + | SynTypeConstraint.WhereTyparIsValueType(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsValueType + + | SynTypeConstraint.WhereTyparIsUnmanaged(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsUnmanaged + + | SynTypeConstraint.WhereTyparIsEnum(tp, tyargs, m) -> + let tp', tpenv = TcTypar cenv env newOk tpenv tp + let tpenv = + match tyargs with + | [underlying] -> + let underlying', tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType env tpenv underlying + AddCxTypeIsEnum env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') underlying' + tpenv + | _ -> + errorR(Error(FSComp.SR.tcInvalidEnumConstraint(), m)) + tpenv + tpenv + + | SynTypeConstraint.WhereTyparIsDelegate(tp, tyargs, m) -> + let tp', tpenv = TcTypar cenv env newOk tpenv tp + match tyargs with + | [a;b] -> + let a', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv a + let b', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv b + AddCxTypeIsDelegate env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') a' b' + tpenv + | _ -> + errorR(Error(FSComp.SR.tcInvalidEnumConstraint(), m)) + tpenv + + | SynTypeConstraint.WhereTyparSupportsMember(tps, memSpfn, m) -> + let traitInfo, tpenv = TcPseudoMemberSpec cenv newOk env tps tpenv memSpfn m + match traitInfo with + | TTrait(objtys, ".ctor", memberFlags, argTys, returnTy, _) when memberFlags.MemberKind = SynMemberKind.Constructor -> + match objtys, argTys with + | [ty], [] when typeEquiv cenv.g ty (GetFSharpViewOfReturnType cenv.g returnTy) -> + AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css m NoTrace ty + tpenv + | _ -> + errorR(Error(FSComp.SR.tcInvalidNewConstraint(), m)) + tpenv + | _ -> + AddCxMethodConstraint env.DisplayEnv cenv.css m NoTrace traitInfo + tpenv + +and TcPseudoMemberSpec cenv newOk env synTypes tpenv memSpfn m = +#if ALLOW_MEMBER_CONSTRAINTS_ON_MEASURES + let tps, tpenv = List.mapFold (TcTyparOrMeasurePar None cenv env newOk) tpenv synTypars +#else + let tys, tpenv = List.mapFold (TcTypeAndRecover cenv newOk CheckCxs ItemOccurence.UseInType env) tpenv synTypes +#endif + match memSpfn with + | SynMemberSig.Member (valSpfn, memberFlags, m) -> + // REVIEW: Test pseudo constraints cannot refer to polymorphic methods. + // REVIEW: Test pseudo constraints cannot be curried. + let members, tpenv = TcValSpec cenv env ModuleOrMemberBinding newOk ExprContainerInfo (Some memberFlags) (Some (List.head tys)) tpenv valSpfn [] + match members with + | [ValSpecResult(_, _, id, _, _, memberConstraintTy, partialValReprInfo, _)] -> + let memberConstraintTypars, _ = tryDestForallTy cenv.g memberConstraintTy + let topValInfo = TranslatePartialArity memberConstraintTypars partialValReprInfo + let _, _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm cenv.g topValInfo 0 memberConstraintTy m + //if curriedArgInfos.Length > 1 then error(Error(FSComp.SR.tcInvalidConstraint(), m)) + let argTys = List.concat curriedArgInfos + let argTys = List.map fst argTys + let logicalCompiledName = ComputeLogicalName id memberFlags + + let item = Item.ArgName (id, memberConstraintTy, None) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) + + TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv + | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) + | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) + + +/// Check a value specification, e.g. in a signature, interface declaration or a constraint +and TcValSpec cenv env declKind newOk containerInfo memFlagsOpt thisTyOpt tpenv valSpfn attrs = + let (SynValSig(_, id, ValTyparDecls (synTypars, synTyparConstraints, _), ty, valSynInfo, _, _, _, _, _, m)) = valSpfn + let declaredTypars = TcTyparDecls cenv env synTypars + let (ContainerInfo(altActualParent, tcrefContainerInfo)) = containerInfo + let enclosingDeclaredTypars, memberContainerInfo, thisTyOpt, declKind = + match tcrefContainerInfo with + | Some(MemberOrValContainerInfo(tcref, _, _, _, declaredTyconTypars)) -> + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let _, enclosingDeclaredTypars, _, _, thisTy = FreshenObjectArgType cenv m TyparRigidity.Rigid tcref isExtrinsic declaredTyconTypars + // An implemented interface type is in terms of the type's type parameters. + // We need a signature in terms of the values' type parameters. + // let optIntfSlotTy = Option.map (instType renaming) optIntfSlotTy in + enclosingDeclaredTypars, Some tcref, Some thisTy, declKind + | None -> + [], None, thisTyOpt, ModuleOrMemberBinding + let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars + let envinner = AddDeclaredTypars NoCheckForDuplicateTypars allDeclaredTypars env + let checkCxs = CheckCxs + let tpenv = TcTyparConstraints cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv synTyparConstraints + + // Treat constraints at the "end" of the type as if they are declared. + // This is by far the most convenient place to locate the constraints. + // e.g. + // val FastGenericComparer<'T>: IComparer<'T> when 'T: comparison + let tpenv = + match ty with + | SynType.WithGlobalConstraints(_, wcs, _) -> + TcTyparConstraints cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv wcs + | _ -> + tpenv + + // Enforce "no undeclared constraints allowed on declared typars" + allDeclaredTypars |> List.iter (SetTyparRigid env.DisplayEnv m) + // Process the type, including any constraints + let declaredTy, tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv ty + + match memFlagsOpt, thisTyOpt with + | Some memberFlags, Some thisTy -> + let generateOneMember (memberFlags: SynMemberFlags) = + + // Decode members in the signature + let ty', valSynInfo = + match memberFlags.MemberKind with + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.Member -> + declaredTy, valSynInfo + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet -> + let fakeArgReprInfos = [ for n in SynInfo.AritiesOfArgs valSynInfo do yield [ for _ in 1 .. n do yield ValReprInfo.unnamedTopArg1 ] ] + let arginfos, returnTy = GetTopTauTypeInFSharpForm cenv.g fakeArgReprInfos declaredTy m + if arginfos.Length > 1 then error(Error(FSComp.SR.tcInvalidPropertyType(), m)) + match memberFlags.MemberKind with + | SynMemberKind.PropertyGet -> + if SynInfo.HasNoArgs valSynInfo then + (cenv.g.unit_ty --> declaredTy), (SynInfo.IncorporateEmptyTupledArgForPropertyGetter valSynInfo) + else + declaredTy, valSynInfo + | _ -> + let setterTy = (mkRefTupledTy cenv.g (List.map fst (List.concat arginfos) @ [returnTy]) --> cenv.g.unit_ty) + let synInfo = SynInfo.IncorporateSetterArg valSynInfo + setterTy, synInfo + | SynMemberKind.PropertyGetSet -> + error(InternalError("Unexpected SynMemberKind.PropertyGetSet from signature parsing", m)) + + // Take "unit" into account in the signature + let valSynInfo = AdjustValSynInfoInSignature cenv.g ty' valSynInfo + + let ty', valSynInfo = + if memberFlags.IsInstance then + (thisTy --> ty'), (SynInfo.IncorporateSelfArg valSynInfo) + else + ty', valSynInfo + + let reallyGenerateOneMember(id: Ident, valSynInfo, ty', memberFlags) = + let PartialValReprInfo(argsData, _) as partialValReprInfo = + TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynInfo + + + // Fold in the optional argument information + // Resort to using the syntactic argument information since that is what tells us + // what is optional and what is not. + let ty' = + + if SynInfo.HasOptionalArgs valSynInfo then + let curriedArgTys, returnTy = GetTopTauTypeInFSharpForm cenv.g argsData ty' m + let curriedArgTys = + ((List.mapSquared fst curriedArgTys), valSynInfo.CurriedArgInfos) + ||> List.map2 (fun argTys argInfos -> + (argTys, argInfos) + ||> List.map2 (fun argty argInfo -> + if SynInfo.IsOptionalArg argInfo then mkOptionTy cenv.g argty + else argty)) + mkIteratedFunTy (List.map (mkRefTupledTy cenv.g) curriedArgTys) returnTy + else ty' + + let memberInfoOpt = + match memberContainerInfo with + | Some tcref -> + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let memberInfoTransient = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, attrs, [], memberFlags, valSynInfo, id, false) + Some memberInfoTransient + | None -> + None + + ValSpecResult(altActualParent, memberInfoOpt, id, enclosingDeclaredTypars, declaredTypars, ty', partialValReprInfo, declKind) + + [ yield reallyGenerateOneMember(id, valSynInfo, ty', memberFlags) + if CompileAsEvent cenv.g attrs then + let valSynInfo = EventDeclarationNormalization.ConvertSynInfo id.idRange valSynInfo + let memberFlags = EventDeclarationNormalization.ConvertMemberFlags memberFlags + let delTy = FindDelegateTypeOfPropertyEvent cenv.g cenv.amap id.idText id.idRange declaredTy + let ty = + if memberFlags.IsInstance then + thisTy --> (delTy --> cenv.g.unit_ty) + else + (delTy --> cenv.g.unit_ty) + yield reallyGenerateOneMember(ident("add_" + id.idText, id.idRange), valSynInfo, ty, memberFlags) + yield reallyGenerateOneMember(ident("remove_" + id.idText, id.idRange), valSynInfo, ty, memberFlags) ] + + + + match memberFlags.MemberKind with + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.Member + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet -> + generateOneMember memberFlags, tpenv + | SynMemberKind.PropertyGetSet -> + [ yield! generateOneMember({memberFlags with MemberKind=SynMemberKind.PropertyGet}) + yield! generateOneMember({memberFlags with MemberKind=SynMemberKind.PropertySet}) ], tpenv + | _ -> + let valSynInfo = AdjustValSynInfoInSignature cenv.g declaredTy valSynInfo + let partialValReprInfo = TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynInfo + [ ValSpecResult(altActualParent, None, id, enclosingDeclaredTypars, declaredTypars, declaredTy, partialValReprInfo, declKind) ], tpenv + +//------------------------------------------------------------------------- +// Bind types +//------------------------------------------------------------------------- + +/// Check and elaborate a type or measure parameter occurrence +/// If optKind=Some kind, then this is the kind we're expecting (we're in *analysis* mode) +/// If optKind=None, we need to determine the kind (we're in *synthesis* mode) +/// +and TcTyparOrMeasurePar optKind cenv (env: TcEnv) newOk tpenv (SynTypar(id, _, _) as tp) = + let checkRes (res: Typar) = + match optKind, res.Kind with + | Some TyparKind.Measure, TyparKind.Type -> error (Error(FSComp.SR.tcExpectedUnitOfMeasureMarkWithAttribute(), id.idRange)); res, tpenv + | Some TyparKind.Type, TyparKind.Measure -> error (Error(FSComp.SR.tcExpectedTypeParameter(), id.idRange)); res, tpenv + | _, _ -> + let item = Item.TypeVar(id.idText, res) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.UseInType, env.AccessRights) + res, tpenv + let key = id.idText + match env.eNameResEnv.eTypars.TryGetValue key with + | true, res -> checkRes res + | _ -> + match TryFindUnscopedTypar key tpenv with + | Some res -> checkRes res + | None -> + if newOk = NoNewTypars then + let suggestTypeParameters (addToBuffer: string -> unit) = + for p in env.eNameResEnv.eTypars do + addToBuffer ("'" + p.Key) + + match tpenv with + | UnscopedTyparEnv elements -> + for p in elements do + addToBuffer ("'" + p.Key) + + let reportedId = Ident("'" + id.idText, id.idRange) + error (UndefinedName(0, FSComp.SR.undefinedNameTypeParameter, reportedId, suggestTypeParameters)) + + // OK, this is an implicit declaration of a type parameter + // The kind defaults to Type + let kind = match optKind with None -> TyparKind.Type | Some kind -> kind + let tp' = Construct.NewTypar (kind, TyparRigidity.WarnIfNotRigid, tp, false, TyparDynamicReq.Yes, [], false, false) + let item = Item.TypeVar(id.idText, tp') + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.UseInType, env.AccessRights) + tp', AddUnscopedTypar key tp' tpenv + +and TcTypar cenv env newOk tpenv tp = + TcTyparOrMeasurePar (Some TyparKind.Type) cenv env newOk tpenv tp + +and TcTyparDecl cenv env (SynTyparDecl(Attributes synAttrs, (SynTypar(id, _, _) as stp))) = + let attrs = TcAttributes cenv env AttributeTargets.GenericParameter synAttrs + let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs + let hasEqDepAttr = HasFSharpAttribute cenv.g cenv.g.attrib_EqualityConditionalOnAttribute attrs + let hasCompDepAttr = HasFSharpAttribute cenv.g cenv.g.attrib_ComparisonConditionalOnAttribute attrs + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute >> not) + let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type + let tp = Construct.NewTypar (kind, TyparRigidity.WarnIfNotRigid, stp, false, TyparDynamicReq.Yes, attrs, hasEqDepAttr, hasCompDepAttr) + match TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs with + | Some compiledName -> + tp.SetILName (Some compiledName) + | None -> + () + let item = Item.TypeVar(id.idText, tp) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.UseInType, env.eAccessRights) + tp + + +and TcTyparDecls cenv env synTypars = List.map (TcTyparDecl cenv env) synTypars + +/// Check and elaborate a syntactic type or measure +/// If optKind=Some kind, then this is the kind we're expecting (we're in *analysis* mode) +/// If optKind=None, we need to determine the kind (we're in *synthesis* mode) +/// +and TcTypeOrMeasure optKind cenv newOk checkCxs occ env (tpenv: UnscopedTyparEnv) ty = + let g = cenv.g + + match ty with + | SynType.LongIdent(LongIdentWithDots([], _)) -> + // special case when type name is absent - i.e. empty inherit part in type declaration + g.obj_ty, tpenv + + | SynType.LongIdent(LongIdentWithDots(tc, _) as lidwd) -> + let m = lidwd.Range + let ad = env.eAccessRights + let tinstEnclosing, tcref = ForceRaise(ResolveTypeLongIdent cenv.tcSink cenv.nameResolver occ OpenQualified env.NameEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No) + match optKind, tcref.TypeOrMeasureKind with + | Some TyparKind.Type, TyparKind.Measure -> + error(Error(FSComp.SR.tcExpectedTypeNotUnitOfMeasure(), m)) + NewErrorType (), tpenv + | Some TyparKind.Measure, TyparKind.Type -> + error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) + TType_measure (NewErrorMeasure ()), tpenv + | _, TyparKind.Measure -> + TType_measure (Measure.Con tcref), tpenv + | _, TyparKind.Type -> + TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinstEnclosing [] + + | SynType.App (StripParenTypes (SynType.LongIdent(LongIdentWithDots(tc, _))), _, args, _commas, _, postfix, m) -> + let ad = env.eAccessRights + + let tinstEnclosing, tcref = + let tyResInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs args.Length + ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInType OpenQualified env.eNameResEnv ad tc tyResInfo PermitDirectReferenceToGeneratedType.No + |> ForceRaise + + match optKind, tcref.TypeOrMeasureKind with + | Some TyparKind.Type, TyparKind.Measure -> + error(Error(FSComp.SR.tcExpectedTypeNotUnitOfMeasure(), m)) + NewErrorType (), tpenv + + | Some TyparKind.Measure, TyparKind.Type -> + error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) + TType_measure (NewErrorMeasure ()), tpenv + + | _, TyparKind.Type -> + if postfix && tcref.Typars m |> List.exists (fun tp -> match tp.Kind with TyparKind.Measure -> true | _ -> false) + then error(Error(FSComp.SR.tcInvalidUnitsOfMeasurePrefix(), m)) + TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinstEnclosing args + | _, TyparKind.Measure -> + match args, postfix with + | [arg], true -> + let ms, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg m + TType_measure (Measure.Prod(Measure.Con tcref, ms)), tpenv + + | _, _ -> + errorR(Error(FSComp.SR.tcUnitsOfMeasureInvalidInTypeConstructor(), m)) + NewErrorType (), tpenv + + | SynType.LongIdentApp (ltyp, LongIdentWithDots(longId, _), _, args, _commas, _, m) -> + let ad = env.eAccessRights + let ltyp, tpenv = TcType cenv newOk checkCxs occ env tpenv ltyp + match ltyp with + | AppTy g (tcref, tinst) -> + let tcref = ResolveTypeLongIdentInTyconRef cenv.tcSink cenv.nameResolver env.eNameResEnv (TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.FromTyArgs args.Length)) ad m tcref longId + TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinst args + | _ -> error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), m)) + + | SynType.Tuple(isStruct, args, m) -> + let tupInfo = mkTupInfo isStruct + if isStruct then + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m + TType_tuple(tupInfo,args'),tpenv + else + let isMeasure = match optKind with Some TyparKind.Measure -> true | None -> List.exists (fun (isquot,_) -> isquot) args | _ -> false + if isMeasure then + let ms,tpenv = TcMeasuresAsTuple cenv newOk checkCxs occ env tpenv args m + TType_measure ms,tpenv + else + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m + TType_tuple(tupInfo,args'),tpenv + + | SynType.AnonRecd(_, [],m) -> + error(Error((FSComp.SR.tcAnonymousTypeInvalidInDeclaration()), m)) + + | SynType.AnonRecd(isStruct, args,m) -> + let tupInfo = mkTupInfo isStruct + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv (args |> List.map snd |> List.map (fun x -> (false,x))) m + let unsortedFieldIds = args |> List.map fst |> List.toArray + let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, tupInfo, unsortedFieldIds) + // Sort into canonical order + let sortedFieldTys, sortedCheckedArgTys = List.zip args args' |> List.indexed |> List.sortBy (fun (i,_) -> unsortedFieldIds.[i].idText) |> List.map snd |> List.unzip + sortedFieldTys |> List.iteri (fun i (x,_) -> + let item = Item.AnonRecdField(anonInfo, sortedCheckedArgTys, i, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange,env.NameEnv,item,emptyTyparInst,ItemOccurence.UseInType,env.eAccessRights)) + TType_anon(anonInfo, sortedCheckedArgTys),tpenv + + | SynType.Fun(domainTy, resultTy, _) -> + let domainTy', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv domainTy + let resultTy', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv resultTy + (domainTy' --> resultTy'), tpenv + + | SynType.Array (n, elemTy, m) -> + let elemTy, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv elemTy + mkArrayTy g n elemTy m, tpenv + + | SynType.Var (tp, _) -> + let tp', tpenv = TcTyparOrMeasurePar optKind cenv env newOk tpenv tp + match tp'.Kind with + | TyparKind.Measure -> TType_measure (Measure.Var tp'), tpenv + | TyparKind.Type -> mkTyparTy tp', tpenv + + // _ types + | SynType.Anon m -> + let tp: Typar = TcAnonTypeOrMeasure optKind cenv TyparRigidity.Anon TyparDynamicReq.No newOk m + match tp.Kind with + | TyparKind.Measure -> TType_measure (Measure.Var tp), tpenv + | TyparKind.Type -> mkTyparTy tp, tpenv + + | SynType.WithGlobalConstraints(ty, wcs, _) -> + let cty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty + let tpenv = TcTyparConstraints cenv newOk checkCxs occ env tpenv wcs + cty, tpenv + + // #typ + | SynType.HashConstraint(ty, m) -> + let tp = TcAnonTypeOrMeasure (Some TyparKind.Type) cenv TyparRigidity.WarnIfNotRigid TyparDynamicReq.Yes newOk m + let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty' (mkTyparTy tp) + tp.AsType, tpenv + + | SynType.StaticConstant (c, m) -> + match c, optKind with + | _, Some TyparKind.Type -> + errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) + NewErrorType (), tpenv + | SynConst.Int32 1, _ -> + TType_measure Measure.One, tpenv + | _ -> + errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) + NewErrorType (), tpenv + + | SynType.StaticConstantNamed (_, _, m) + + | SynType.StaticConstantExpr (_, m) -> + errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) + NewErrorType (), tpenv + + | SynType.MeasurePower(ty, exponent, m) -> + match optKind with + | Some TyparKind.Type -> + errorR(Error(FSComp.SR.tcUnexpectedSymbolInTypeExpression("^"), m)) + NewErrorType (), tpenv + | _ -> + let ms, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv ty m + TType_measure (Measure.RationalPower (ms, TcSynRationalConst exponent)), tpenv + + | SynType.MeasureDivide(typ1, typ2, m) -> + match optKind with + | Some TyparKind.Type -> + errorR(Error(FSComp.SR.tcUnexpectedSymbolInTypeExpression("/"), m)) + NewErrorType (), tpenv + | _ -> + let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv typ1 m + let ms2, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv typ2 m + TType_measure (Measure.Prod(ms1, Measure.Inv ms2)), tpenv + + | SynType.App(StripParenTypes (SynType.Var(_, m1) | SynType.MeasurePower(_, _, m1)) as arg1, _, args, _commas, _, postfix, m) -> + match optKind, args, postfix with + | (None | Some TyparKind.Measure), [arg2], true -> + let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg1 m1 + let ms2, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg2 m + TType_measure (Measure.Prod(ms1, ms2)), tpenv + + | _ -> + errorR(Error(FSComp.SR.tcTypeParameterInvalidAsTypeConstructor(), m)) + NewErrorType (), tpenv + + | SynType.App(_, _, _, _, _, _, m) -> + errorR(Error(FSComp.SR.tcIllegalSyntaxInTypeExpression(), m)) + NewErrorType (), tpenv + + | SynType.Paren(innerType, _) -> + TcTypeOrMeasure optKind cenv newOk checkCxs occ env (tpenv: UnscopedTyparEnv) innerType + +and TcType cenv newOk checkCxs occ env (tpenv: UnscopedTyparEnv) ty = + TcTypeOrMeasure (Some TyparKind.Type) cenv newOk checkCxs occ env tpenv ty + +and TcMeasure cenv newOk checkCxs occ env (tpenv: UnscopedTyparEnv) (StripParenTypes ty) m = + match ty with + | SynType.Anon m -> + error(Error(FSComp.SR.tcAnonymousUnitsOfMeasureCannotBeNested(), m)) + NewErrorMeasure (), tpenv + | _ -> + match TcTypeOrMeasure (Some TyparKind.Measure) cenv newOk checkCxs occ env tpenv ty with + | TType_measure ms, tpenv -> ms, tpenv + | _ -> + error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) + NewErrorMeasure (), tpenv + +and TcAnonTypeOrMeasure optKind _cenv rigid dyn newOk m = + if newOk = NoNewTypars then errorR (Error(FSComp.SR.tcAnonymousTypeInvalidInDeclaration(), m)) + let rigid = (if rigid = TyparRigidity.Anon && newOk = NewTyparsOKButWarnIfNotRigid then TyparRigidity.WarnIfNotRigid else rigid) + let kind = match optKind with Some TyparKind.Measure -> TyparKind.Measure | _ -> TyparKind.Type + NewAnonTypar (kind, m, rigid, TyparStaticReq.None, dyn) + +and TcTypes cenv newOk checkCxs occ env tpenv args = + List.mapFold (TcTypeAndRecover cenv newOk checkCxs occ env) tpenv args + +and TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m = + match args with + | [] -> error(InternalError("empty tuple type", m)) + | [(_, ty)] -> let ty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty in [ty], tpenv + | (isquot, ty) :: args -> + let ty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty + let tys, tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m + if isquot then errorR(Error(FSComp.SR.tcUnexpectedSlashInType(), m)) + ty :: tys, tpenv + +// Type-check a list of measures separated by juxtaposition, * or / +and TcMeasuresAsTuple cenv newOk checkCxs occ env (tpenv: UnscopedTyparEnv) args m = + let rec gather args tpenv isquot acc = + match args with + | [] -> acc, tpenv + | (nextisquot, ty) :: args -> + let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv ty m + gather args tpenv nextisquot (if isquot then Measure.Prod(acc, Measure.Inv ms1) else Measure.Prod(acc, ms1)) + gather args tpenv false Measure.One + +and TcTypesOrMeasures optKinds cenv newOk checkCxs occ env tpenv args m = + match optKinds with + | None -> + List.mapFold (TcTypeOrMeasure None cenv newOk checkCxs occ env) tpenv args + | Some kinds -> + if List.length kinds = List.length args then + List.mapFold (fun tpenv (arg, kind) -> TcTypeOrMeasure (Some kind) cenv newOk checkCxs occ env tpenv arg) tpenv (List.zip args kinds) + elif isNil kinds then error(Error(FSComp.SR.tcUnexpectedTypeArguments(), m)) + else error(Error(FSComp.SR.tcTypeParameterArityMismatch((List.length kinds), (List.length args)), m)) + +and TcTyparConstraints cenv newOk checkCxs occ env tpenv synConstraints = + // Mark up default constraints with a priority in reverse order: last gets 0, second + // last gets 1 etc. See comment on TyparConstraint.DefaultsTo + let _, tpenv = List.fold (fun (ridx, tpenv) tc -> ridx - 1, TcTyparConstraint ridx cenv newOk checkCxs occ env tpenv tc) (List.length synConstraints - 1, tpenv) synConstraints + tpenv + +#if !NO_EXTENSIONTYPING +and TcStaticConstantParameter cenv (env: TcEnv) tpenv kind (StripParenTypes v) idOpt container = + let g = cenv.g + let fail() = error(Error(FSComp.SR.etInvalidStaticArgument(NicePrint.minimalStringOfType env.DisplayEnv kind), v.Range)) + let record ttype = + match idOpt with + | Some id -> + let item = Item.ArgName (id, ttype, Some container) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) + | _ -> () + + match v with + | SynType.StaticConstant(sc, _) -> + let v = + match sc with + | SynConst.Byte n when typeEquiv g g.byte_ty kind -> record(g.byte_ty); box (n: byte) + | SynConst.Int16 n when typeEquiv g g.int16_ty kind -> record(g.int16_ty); box (n: int16) + | SynConst.Int32 n when typeEquiv g g.int32_ty kind -> record(g.int32_ty); box (n: int) + | SynConst.Int64 n when typeEquiv g g.int64_ty kind -> record(g.int64_ty); box (n: int64) + | SynConst.SByte n when typeEquiv g g.sbyte_ty kind -> record(g.sbyte_ty); box (n: sbyte) + | SynConst.UInt16 n when typeEquiv g g.uint16_ty kind -> record(g.uint16_ty); box (n: uint16) + | SynConst.UInt32 n when typeEquiv g g.uint32_ty kind -> record(g.uint32_ty); box (n: uint32) + | SynConst.UInt64 n when typeEquiv g g.uint64_ty kind -> record(g.uint64_ty); box (n: uint64) + | SynConst.Decimal n when typeEquiv g g.decimal_ty kind -> record(g.decimal_ty); box (n: decimal) + | SynConst.Single n when typeEquiv g g.float32_ty kind -> record(g.float32_ty); box (n: single) + | SynConst.Double n when typeEquiv g g.float_ty kind -> record(g.float_ty); box (n: double) + | SynConst.Char n when typeEquiv g g.char_ty kind -> record(g.char_ty); box (n: char) + | SynConst.String (s, _, _) + | SynConst.SourceIdentifier (_, s, _) when s <> null && typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string) + | SynConst.Bool b when typeEquiv g g.bool_ty kind -> record(g.bool_ty); box (b: bool) + | _ -> fail() + v, tpenv + | SynType.StaticConstantExpr(e, _ ) -> + + // If an error occurs, don't try to recover, since the constant expression will be nothing like what we need + let te, tpenv' = TcExprNoRecover cenv (MustEqual kind) env tpenv e + + // Evaluate the constant expression using static attribute argument rules + let te = EvalLiteralExprOrAttribArg g te + let v = + match stripExpr te with + // Check we have a residue constant. We know the type was correct because we checked the expression with this type. + | Expr.Const (c, _, _) -> + match c with + | Const.Byte n -> record(g.byte_ty); box (n: byte) + | Const.Int16 n -> record(g.int16_ty); box (n: int16) + | Const.Int32 n -> record(g.int32_ty); box (n: int) + | Const.Int64 n -> record(g.int64_ty); box (n: int64) + | Const.SByte n -> record(g.sbyte_ty); box (n: sbyte) + | Const.UInt16 n -> record(g.uint16_ty); box (n: uint16) + | Const.UInt32 n -> record(g.uint32_ty); box (n: uint32) + | Const.UInt64 n -> record(g.uint64_ty); box (n: uint64) + | Const.Decimal n -> record(g.decimal_ty); box (n: decimal) + | Const.Single n -> record(g.float32_ty); box (n: single) + | Const.Double n -> record(g.float_ty); box (n: double) + | Const.Char n -> record(g.char_ty); box (n: char) + | Const.String null -> fail() + | Const.String s -> record(g.string_ty); box (s: string) + | Const.Bool b -> record(g.bool_ty); box (b: bool) + | _ -> fail() + | _ -> error(Error(FSComp.SR.tcInvalidConstantExpression(), v.Range)) + v, tpenv' + | SynType.LongIdent lidwd -> + let m = lidwd.Range + TcStaticConstantParameter cenv env tpenv kind (SynType.StaticConstantExpr(SynExpr.LongIdent (false, lidwd, None, m), m)) idOpt container + | _ -> + fail() + +and CrackStaticConstantArgs cenv env tpenv (staticParameters: Tainted[], args: SynType list, container, containerName, m) = + let args = + args |> List.map (function + | StripParenTypes (SynType.StaticConstantNamed(StripParenTypes (SynType.LongIdent(LongIdentWithDots([id], _))), v, _)) -> Some id, v + | v -> None, v) + + let unnamedArgs = args |> Seq.takeWhile (fst >> Option.isNone) |> Seq.toArray |> Array.map snd + let otherArgs = args |> List.skipWhile (fst >> Option.isNone) + let namedArgs = otherArgs |> List.takeWhile (fst >> Option.isSome) |> List.map (map1Of2 Option.get) + let otherArgs = otherArgs |> List.skipWhile (fst >> Option.isSome) + if not otherArgs.IsEmpty then + error (Error(FSComp.SR.etBadUnnamedStaticArgs(), m)) + + let indexedStaticParameters = staticParameters |> Array.toList |> List.indexed + for n, _ in namedArgs do + match indexedStaticParameters |> List.filter (fun (j, sp) -> j >= unnamedArgs.Length && n.idText = sp.PUntaint((fun sp -> sp.Name), m)) with + | [] -> + if staticParameters |> Array.exists (fun sp -> n.idText = sp.PUntaint((fun sp -> sp.Name), n.idRange)) then + error (Error(FSComp.SR.etStaticParameterAlreadyHasValue n.idText, n.idRange)) + else + error (Error(FSComp.SR.etNoStaticParameterWithName n.idText, n.idRange)) + | [_] -> () + | _ -> error (Error(FSComp.SR.etMultipleStaticParameterWithName n.idText, n.idRange)) + + if staticParameters.Length < namedArgs.Length + unnamedArgs.Length then + error (Error(FSComp.SR.etTooManyStaticParameters(staticParameters.Length, unnamedArgs.Length, namedArgs.Length), m)) + + let argsInStaticParameterOrderIncludingDefaults = + staticParameters |> Array.mapi (fun i sp -> + let spKind = Import.ImportProvidedType cenv.amap m (sp.PApply((fun x -> x.ParameterType), m)) + let spName = sp.PUntaint((fun sp -> sp.Name), m) + if i < unnamedArgs.Length then + let v = unnamedArgs.[i] + let v, _tpenv = TcStaticConstantParameter cenv env tpenv spKind v None container + v + else + match namedArgs |> List.filter (fun (n, _) -> n.idText = spName) with + | [(n, v)] -> + let v, _tpenv = TcStaticConstantParameter cenv env tpenv spKind v (Some n) container + v + | [] -> + if sp.PUntaint((fun sp -> sp.IsOptional), m) then + match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with + | null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, containerName, containerName, spName), m)) + | v -> v + else + error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, containerName, containerName, spName), m)) + | ps -> + error (Error(FSComp.SR.etMultipleStaticParameterWithName spName, (fst (List.last ps)).idRange))) + + argsInStaticParameterOrderIncludingDefaults + +and TcProvidedTypeAppToStaticConstantArgs cenv env optGeneratedTypePath tpenv (tcref: TyconRef) (args: SynType list) m = + let typeBeforeArguments = + match tcref.TypeReprInfo with + | TProvidedTypeRepr info -> info.ProvidedType + | _ -> failwith "unreachable" + + let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.GetStaticParameters provider), range=m) + let staticParameters = staticParameters.PApplyArray(id, "GetStaticParameters", m) + + let argsInStaticParameterOrderIncludingDefaults = CrackStaticConstantArgs cenv env tpenv (staticParameters, args, ArgumentContainer.Type tcref, tcref.DisplayName, m) + + // Take the static arguments (as SynType's) and convert them to objects of the appropriate type, based on the expected kind. + let providedTypeAfterStaticArguments, checkTypeName = + match TryApplyProvidedType(typeBeforeArguments, optGeneratedTypePath, argsInStaticParameterOrderIncludingDefaults, m) with + | None -> error(Error(FSComp.SR.etErrorApplyingStaticArgumentsToType(), m)) + | Some (ty, checkTypeName) -> (ty, checkTypeName) + + let hasNoArgs = (argsInStaticParameterOrderIncludingDefaults.Length = 0) + hasNoArgs, providedTypeAfterStaticArguments, checkTypeName + +and TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos: MethInfo list, argsOpt, mExprAndArg, mItem) = + match minfos, argsOpt with + | [minfo], Some (args, _) -> + match minfo.ProvidedStaticParameterInfo with + | Some (methBeforeArguments, staticParams) -> + let providedMethAfterStaticArguments = TcProvidedMethodAppToStaticConstantArgs cenv env tpenv (minfo, methBeforeArguments, staticParams, args, mExprAndArg) + let minfoAfterStaticArguments = ProvidedMeth(cenv.amap, providedMethAfterStaticArguments, minfo.ExtensionMemberPriorityOption, mItem) + Some minfoAfterStaticArguments + | _ -> None + | _ -> None + +and TcProvidedMethodAppToStaticConstantArgs cenv env tpenv (minfo, methBeforeArguments, staticParams, args, m) = + + let argsInStaticParameterOrderIncludingDefaults = CrackStaticConstantArgs cenv env tpenv (staticParams, args, ArgumentContainer.Method minfo, minfo.DisplayName, m) + + let providedMethAfterStaticArguments = + match TryApplyProvidedMethod(methBeforeArguments, argsInStaticParameterOrderIncludingDefaults, m) with + | None -> error(Error(FSComp.SR.etErrorApplyingStaticArgumentsToMethod(), m)) + | Some meth -> meth + + providedMethAfterStaticArguments + +and TcProvidedTypeApp cenv env tpenv tcref args m = + let hasNoArgs, providedTypeAfterStaticArguments, checkTypeName = TcProvidedTypeAppToStaticConstantArgs cenv env None tpenv tcref args m + + let isGenerated = providedTypeAfterStaticArguments.PUntaint((fun st -> not st.IsErased), m) + + //printfn "adding entity for provided type '%s', isDirectReferenceToGenerated = %b, isGenerated = %b" (st.PUntaint((fun st -> st.Name), m)) isDirectReferenceToGenerated isGenerated + let isDirectReferenceToGenerated = isGenerated && IsGeneratedTypeDirectReference (providedTypeAfterStaticArguments, m) + if isDirectReferenceToGenerated then + error(Error(FSComp.SR.etDirectReferenceToGeneratedTypeNotAllowed(tcref.DisplayName), m)) + + // We put the type name check after the 'isDirectReferenceToGenerated' check because we need the 'isDirectReferenceToGenerated' error to be shown for generated types + checkTypeName() + if hasNoArgs then + mkAppTy tcref [], tpenv + else + let ty = Import.ImportProvidedType cenv.amap m providedTypeAfterStaticArguments + ty, tpenv +#endif + +/// Typecheck an application of a generic type to type arguments. +/// +/// Note that the generic type may be a nested generic type List.ListEnumerator. +/// In this case, 'args' is only the instantiation of the suffix type arguments, and pathTypeArgs gives +/// the prefix of type arguments. +and TcTypeApp cenv newOk checkCxs occ env tpenv m tcref pathTypeArgs (synArgTys: SynType list) = + let g = cenv.g + CheckTyconAccessible cenv.amap m env.AccessRights tcref |> ignore + CheckEntityAttributes g tcref m |> CommitOperationResult + +#if !NO_EXTENSIONTYPING + // Provided types are (currently) always non-generic. Their names may include mangled + // static parameters, which are passed by the provider. + if tcref.Deref.IsProvided then TcProvidedTypeApp cenv env tpenv tcref synArgTys m else +#endif + + let tps, _, tinst, _ = FreshenTyconRef2 m tcref + + // If we're not checking constraints, i.e. when we first assert the super/interfaces of a type definition, then just + // clear the constraint lists of the freshly generated type variables. A little ugly but fairly localized. + if checkCxs = NoCheckCxs then tps |> List.iter (fun tp -> tp.SetConstraints []) + let synArgTysLength = synArgTys.Length + let pathTypeArgsLength = pathTypeArgs.Length + if tinst.Length <> pathTypeArgsLength + synArgTysLength then + error (TyconBadArgs(env.DisplayEnv, tcref, pathTypeArgsLength + synArgTysLength, m)) + + let argTys, tpenv = + // Get the suffix of typars + let tpsForArgs = List.skip (tps.Length - synArgTysLength) tps + let kindsForArgs = tpsForArgs |> List.map (fun tp -> tp.Kind) + TcTypesOrMeasures (Some kindsForArgs) cenv newOk checkCxs occ env tpenv synArgTys m + + // Add the types of the enclosing class for a nested type + let actualArgTys = pathTypeArgs @ argTys + + if checkCxs = CheckCxs then + List.iter2 (UnifyTypes cenv env m) tinst actualArgTys + + // Try to decode System.Tuple --> F~ tuple types etc. + let ty = g.decompileType tcref actualArgTys + + ty, tpenv + +and TcTypeOrMeasureAndRecover optKind cenv newOk checkCxs occ env tpenv ty = + try TcTypeOrMeasure optKind cenv newOk checkCxs occ env tpenv ty + with e -> + errorRecovery e ty.Range + let rty = + match optKind, newOk with + | Some TyparKind.Measure, NoNewTypars -> TType_measure Measure.One + | Some TyparKind.Measure, _ -> TType_measure (NewErrorMeasure ()) + | _, NoNewTypars -> cenv.g.obj_ty + | _ -> NewErrorType () + rty, tpenv + + +and TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty = + TcTypeOrMeasureAndRecover (Some TyparKind.Type) cenv newOk checkCxs occ env tpenv ty + +and TcNestedTypeApplication cenv newOk checkCxs occ env tpenv mWholeTypeApp ty pathTypeArgs tyargs = + let ty = convertToTypeWithMetadataIfPossible cenv.g ty + if not (isAppTy cenv.g ty) then error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), mWholeTypeApp)) + match ty with + | TType_app(tcref, _) -> + TcTypeApp cenv newOk checkCxs occ env tpenv mWholeTypeApp tcref pathTypeArgs tyargs + | _ -> error(InternalError("TcNestedTypeApplication: expected type application", mWholeTypeApp)) + + +and TryAdjustHiddenVarNameToCompGenName cenv env (id: Ident) altNameRefCellOpt = + match altNameRefCellOpt with + | Some ({contents = SynSimplePatAlternativeIdInfo.Undecided altId } as altNameRefCell) -> + match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false id.idRange env.eAccessRights env.eNameResEnv TypeNameResolutionInfo.Default [id] with + | Item.NewDef _ -> + // The name is not in scope as a pattern identifier (e.g. union case), so do not use the alternate ID + None + | _ -> + // The name is in scope as a pattern identifier, so use the alternate ID + altNameRefCell.Value <- SynSimplePatAlternativeIdInfo.Decided altId + Some altId + | Some {contents = SynSimplePatAlternativeIdInfo.Decided altId } -> Some altId + | None -> None + +/// Bind the patterns used in a lambda. Not clear why we don't use TcPat. +and TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p = + match p with + | SynSimplePat.Id (id, altNameRefCellOpt, compgen, isMemberThis, isOpt, m) -> + // Check to see if pattern translation decides to use an alternative identifier. + match TryAdjustHiddenVarNameToCompGenName cenv env id altNameRefCellOpt with + | Some altId -> TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) (SynSimplePat.Id (altId, None, compgen, isMemberThis, isOpt, m) ) + | None -> + if isOpt then + if not optArgsOK then + errorR(Error(FSComp.SR.tcOptionalArgsOnlyOnMembers(), m)) + + let tyarg = NewInferenceType () + UnifyTypes cenv env m ty (mkOptionTy cenv.g tyarg) + + let _, names, takenNames = TcPatBindingName cenv env id ty isMemberThis None None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, compgen) (names, takenNames) + id.idText, + (tpenv, names, takenNames) + + | SynSimplePat.Typed (p, cty, m) -> + let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK checkCxs ItemOccurence.UseInType env tpenv cty + match p with + // Optional arguments on members + | SynSimplePat.Id(_, _, _, _, true, _) -> UnifyTypes cenv env m ty (mkOptionTy cenv.g cty') + | _ -> UnifyTypes cenv env m ty cty' + + TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p + + | SynSimplePat.Attrib (p, _, _) -> + TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p + +// raise an error if any optional args precede any non-optional args +and ValidateOptArgOrder (spats: SynSimplePats) = + + let rec getPats spats = + match spats with + | SynSimplePats.SimplePats(p, m) -> p, m + | SynSimplePats.Typed(p, _, _) -> getPats p + + let rec isOptArg pat = + match pat with + | SynSimplePat.Id (_, _, _, _, isOpt, _) -> isOpt + | SynSimplePat.Typed (p, _, _) -> isOptArg p + | SynSimplePat.Attrib (p, _, _) -> isOptArg p + + let pats, m = getPats spats + + let mutable hitOptArg = false + + List.iter (fun pat -> if isOptArg pat then hitOptArg <- true elif hitOptArg then error(Error(FSComp.SR.tcOptionalArgsMustComeAfterNonOptionalArgs(), m))) pats + + +/// Bind the patterns used in argument position for a function, method or lambda. +and TcSimplePats cenv optArgsOK checkCxs ty env (tpenv, names, takenNames: Set<_>) p = + + // validate optional argument declaration + ValidateOptArgOrder p + + match p with + | SynSimplePats.SimplePats ([], m) -> + // Unit "()" patterns in argument position become SynSimplePats.SimplePats([], _) in the + // syntactic translation when building bindings. This is done because the + // use of "()" has special significance for arity analysis and argument counting. + // + // Here we give a name to the single argument implied by those patterns. + // This is a little awkward since it would be nice if this was + // uniform with the process where we give names to other (more complex) + // patterns used in argument position, e.g. "let f (D(x)) = ..." + let id = ident("unitVar" + string takenNames.Count, m) + UnifyTypes cenv env m ty cenv.g.unit_ty + let _, names, takenNames = TcPatBindingName cenv env id ty false None None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, true) (names, takenNames) + [id.idText], (tpenv, names, takenNames) + + | SynSimplePats.SimplePats ([p], _) -> + let v, (tpenv, names, takenNames) = TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p + [v], (tpenv, names, takenNames) + + | SynSimplePats.SimplePats (ps, m) -> + let ptys = UnifyRefTupleType env.eContextInfo cenv env.DisplayEnv m ty ps + let ps', (tpenv, names, takenNames) = List.mapFold (fun tpenv (ty, e) -> TcSimplePat optArgsOK checkCxs cenv ty env tpenv e) (tpenv, names, takenNames) (List.zip ptys ps) + ps', (tpenv, names, takenNames) + + | SynSimplePats.Typed (p, cty, m) -> + let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty + + match p with + // Solitary optional arguments on members + | SynSimplePats.SimplePats([SynSimplePat.Id(_, _, _, _, true, _)], _) -> UnifyTypes cenv env m ty (mkOptionTy cenv.g cty') + | _ -> UnifyTypes cenv env m ty cty' + + TcSimplePats cenv optArgsOK checkCxs ty env (tpenv, names, takenNames) p + +and TcSimplePatsOfUnknownType cenv optArgsOK checkCxs env tpenv spats = + let argty = NewInferenceType () + TcSimplePats cenv optArgsOK checkCxs argty env (tpenv, NameMap.empty, Set.empty) spats + +and TcPatBindingName cenv env id ty isMemberThis vis1 topValData (inlineFlag, declaredTypars, argAttribs, isMutable, vis2, compgen) (names, takenNames: Set) = + let vis = if Option.isSome vis1 then vis1 else vis2 + if takenNames.Contains id.idText then errorR (VarBoundTwice id) + let compgen = compgen || IsCompilerGeneratedName id.idText + let baseOrThis = if isMemberThis then MemberThisVal else NormalVal + let names = Map.add id.idText (PrelimValScheme1(id, declaredTypars, ty, topValData, None, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) names + let takenNames = Set.add id.idText takenNames + (fun (TcPatPhase2Input (values, isLeftMost)) -> + let vspec, typeScheme = + let name = id.idText + match values.TryGetValue name with + | true, value -> + if not (String.IsNullOrEmpty name) && not (String.isLeadingIdentifierCharacterUpperCase name) then + match env.eNameResEnv.ePatItems.TryGetValue name with + | true, Item.Value vref when vref.LiteralValue.IsSome -> + warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern name, id.idRange)) + | _ -> () + value + | _ -> error(Error(FSComp.SR.tcNameNotBoundInPattern name, id.idRange)) + + // isLeftMost indicates we are processing the left-most path through a disjunctive or pattern. + // For those binding locations, CallNameResolutionSink is called in MakeAndPublishValue, like all other bindings + // For non-left-most paths, we register the name resolutions here + if not isLeftMost && not vspec.IsCompilerGenerated && not (vspec.LogicalName.StartsWithOrdinal("_")) then + let item = Item.Value(mkLocalValRef vspec) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + + PBind(vspec, typeScheme)), + names, takenNames + +and TcPatAndRecover warnOnUpper cenv (env: TcEnv) topValInfo vFlags (tpenv, names, takenNames) ty (pat: SynPat) = + try + TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty pat + with e -> + // Error recovery - return some rubbish expression, but replace/annotate + // the type of the current expression with a type variable that indicates an error + let m = pat.Range + errorRecovery e m + //solveTypAsError cenv env.DisplayEnv m ty + (fun _ -> TPat_error m), (tpenv, names, takenNames) + +/// Typecheck a pattern. Patterns are type-checked in three phases: +/// 1. TcPat builds a List.map from simple variable names to inferred types for +/// those variables. It also returns a function to perform the second phase. +/// 2. The second phase assumes the caller has built the actual value_spec's +/// for the values being defined, and has decided if the types of these +/// variables are to be generalized. The caller hands this information to +/// the second-phase function in terms of a List.map from names to actual +/// value specifications. +and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty pat = + let ad = env.AccessRights + match pat with + | SynPat.As(_, SynPat.Named _, _) -> () + | SynPat.As (_, _, m) -> checkLanguageFeatureError cenv.g.langVersion LanguageFeature.NonVariablePatternsToRightOfAsPatterns m + | _ -> () + match pat with + | SynPat.Const (c, m) -> + match c with + | SynConst.Bytes (bytes, _, m) -> + UnifyTypes cenv env m ty (mkByteArrayTy cenv.g) + TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty (SynPat.ArrayOrList (true, [ for b in bytes -> SynPat.Const(SynConst.Byte b, m) ], m)) + + | SynConst.UserNum _ -> + errorR (Error (FSComp.SR.tcInvalidNonPrimitiveLiteralInPatternMatch (), m)) + (fun _ -> TPat_error m), (tpenv, names, takenNames) + + | _ -> + try + let c' = TcConst cenv ty m env c + (fun _ -> TPat_const (c', m)), (tpenv, names, takenNames) + with e -> + errorRecovery e m + (fun _ -> TPat_error m), (tpenv, names, takenNames) + + | SynPat.Wild m -> + (fun _ -> TPat_wild m), (tpenv, names, takenNames) + + | SynPat.IsInst(cty, m) + | SynPat.As (SynPat.IsInst(cty, m), _, _) -> + let srcTy = ty + let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOKButWarnIfNotRigid CheckCxs ItemOccurence.UseInType env tpenv cty + TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy + match pat with + | SynPat.IsInst(_, m) -> + (fun _ -> TPat_isinst (srcTy, tgtTy, None, m)), (tpenv, names, takenNames) + | SynPat.As (SynPat.IsInst _, p, m) -> + let pat, acc = TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) tgtTy p + (fun values -> TPat_isinst (srcTy, tgtTy, Some (pat values), m)), acc + | _ -> failwith "TcPat" + + | SynPat.As (p, SynPat.Named (id, isMemberThis, vis, m), _) + | SynPat.As (SynPat.Named (id, isMemberThis, vis, m), p, _) -> + let bindf, names, takenNames = TcPatBindingName cenv env id ty isMemberThis vis topValInfo vFlags (names, takenNames) + let pat', acc = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p + (fun values -> TPat_as (pat' values, bindf values, m)), + acc + + | SynPat.As (pat1, pat2, m) -> + let pats = [pat1; pat2] + let pats', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (List.map (fun _ -> ty) pats) pats + (fun values -> TPat_conjs(List.map (fun f -> f values) pats', m)), acc + + | SynPat.Named (id, isMemberThis, vis, m) -> + let bindf, names, takenNames = TcPatBindingName cenv env id ty isMemberThis vis topValInfo vFlags (names, takenNames) + let pat', acc = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty (SynPat.Wild m) + (fun values -> TPat_as (pat' values, bindf values, m)), + acc + + | SynPat.OptionalVal (id, m) -> + errorR (Error (FSComp.SR.tcOptionalArgsOnlyOnMembers (), m)) + let bindf, names, takenNames = TcPatBindingName cenv env id ty false None topValInfo vFlags (names, takenNames) + (fun values -> TPat_as (TPat_wild m, bindf values, m)), (tpenv, names, takenNames) + + | SynPat.Typed (p, cty, m) -> + let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty + UnifyTypes cenv env m ty cty' + TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p + + | SynPat.Attrib (p, attrs, _) -> + errorR (Error (FSComp.SR.tcAttributesInvalidInPatterns (), rangeOfNonNilAttrs attrs)) + for attrList in attrs do + TcAttributes cenv env Unchecked.defaultof<_> attrList.Attributes |> ignore + TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p + + | SynPat.Or (pat1, pat2, m) -> + let pat1', (tpenv, names1, takenNames1) = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty pat1 + let pat2', (tpenv, names2, takenNames2) = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty pat2 + if not (takenNames1 = takenNames2) then + errorR (UnionPatternsBindDifferentNames m) + + names1 |> Map.iter (fun _ (PrelimValScheme1 (id1, _, ty1, _, _, _, _, _, _, _, _)) -> + match names2.TryGetValue id1.idText with + | true, PrelimValScheme1 (id2, _, ty2, _, _, _, _, _, _, _, _) -> + try UnifyTypes cenv env id2.idRange ty1 ty2 + with e -> errorRecovery e m + | _ -> ()) + + let names = NameMap.layer names1 names2 + let takenNames = Set.union takenNames1 takenNames2 + (fun values -> TPat_disjs ([pat1' values; pat2' values.RightPath], m)), (tpenv, names, takenNames) + + | SynPat.Ands (pats, m) -> + let pats', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (List.map (fun _ -> ty) pats) pats + (fun values -> TPat_conjs(List.map (fun f -> f values) pats', m)), acc + + | SynPat.LongIdent (LongIdentWithDots(longId, _), _, tyargs, args, vis, m) -> + if Option.isSome tyargs then errorR(Error(FSComp.SR.tcInvalidTypeArgumentUsage(), m)) + let warnOnUpperForId = + match args with + | SynArgPats.Pats [] -> warnOnUpper + | _ -> AllIdsOK + + let lidRange = rangeOfLid longId + + let checkNoArgsForLiteral () = + match args with + | SynArgPats.Pats [] + | SynArgPats.NamePatPairs ([], _) -> () + | _ -> errorR (Error (FSComp.SR.tcLiteralDoesNotTakeArguments (), m)) + + let getArgPatterns () = + match args with + | SynArgPats.Pats args -> args + | SynArgPats.NamePatPairs (pairs, _) -> List.map snd pairs + + let tcArgPatterns () = + let args = getArgPatterns () + TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (NewInferenceTypes args) args + + // Note we parse arguments to parameterized pattern labels as patterns, not expressions. + // This means the range of syntactic expression forms that can be used here is limited. + let rec convSynPatToSynExpr x = + match x with + | SynPat.FromParseError(p, _) -> convSynPatToSynExpr p + | SynPat.Const (c, m) -> SynExpr.Const (c, m) + | SynPat.Named (id, _, None, _) -> SynExpr.Ident id + | SynPat.Typed (p, cty, m) -> SynExpr.Typed (convSynPatToSynExpr p, cty, m) + | SynPat.LongIdent (LongIdentWithDots(longId, dotms) as lidwd, _, _tyargs, args, None, m) -> + let args = match args with SynArgPats.Pats args -> args | _ -> failwith "impossible: active patterns can be used only with SynConstructorArgs.Pats" + let e = + if dotms.Length = longId.Length then + let e = SynExpr.LongIdent (false, LongIdentWithDots(longId, List.truncate (dotms.Length - 1) dotms), None, m) + SynExpr.DiscardAfterMissingQualificationAfterDot (e, unionRanges e.Range (List.last dotms)) + else SynExpr.LongIdent (false, lidwd, None, m) + List.fold (fun f x -> mkSynApp1 f (convSynPatToSynExpr x) m) e args + | SynPat.Tuple (isStruct, args, m) -> SynExpr.Tuple (isStruct, List.map convSynPatToSynExpr args, [], m) + | SynPat.Paren (p, _) -> convSynPatToSynExpr p + | SynPat.ArrayOrList (isArray, args, m) -> SynExpr.ArrayOrList (isArray,List.map convSynPatToSynExpr args, m) + | SynPat.QuoteExpr (e,_) -> e + | SynPat.Null m -> SynExpr.Null m + | _ -> error(Error(FSComp.SR.tcInvalidArgForParameterizedPattern(), x.Range)) + + let isNameof (id: Ident) = + id.idText = "nameof" && + try + match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.NameEnv TypeNameResolutionInfo.Default [id] with + | Result (_, Item.Value vref, _) -> valRefEq cenv.g vref cenv.g.nameof_vref + | _ -> false + with _ -> false + + match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver warnOnUpperForId false m ad env.NameEnv TypeNameResolutionInfo.Default longId with + | Item.NewDef id -> + match getArgPatterns () with + | [] -> + TcPat warnOnUpperForId cenv env topValInfo vFlags (tpenv, names, takenNames) ty (mkSynPatVar vis id) + + | [arg] + when cenv.g.langVersion.SupportsFeature LanguageFeature.NameOf && isNameof id -> + match TcNameOfExpr cenv env tpenv (convSynPatToSynExpr arg) with + | Expr.Const(c, m, _) -> (fun _ -> TPat_const (c, m)), (tpenv, names, takenNames) + | _ -> failwith "Impossible: TcNameOfExpr must return an Expr.Const" + | _ -> + let _, acc = tcArgPatterns () + errorR (UndefinedName (0, FSComp.SR.undefinedNamePatternDiscriminator, id, NoSuggestions)) + (fun _ -> TPat_error m), acc + + | Item.ActivePatternCase (APElemRef (apinfo, vref, idx, isStructRetTy)) as item -> + // Report information about the 'active recognizer' occurrence to IDE + CallNameResolutionSink cenv.tcSink (rangeOfLid longId, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.eAccessRights) + + match args with + | SynArgPats.Pats _ -> () + | _ -> errorR (Error (FSComp.SR.tcNamedActivePattern apinfo.ActiveTags.[idx], m)) + + let args = getArgPatterns () + + // TOTAL/PARTIAL ACTIVE PATTERNS + let _, vexp, _, _, tinst, _ = TcVal true cenv env tpenv vref None None m + let vexp = MakeApplicableExprWithFlex cenv env vexp + let vexpty = vexp.Type + + let activePatArgsAsSynPats, patarg = + match args with + | [] -> [], SynPat.Const(SynConst.Unit, m) + | _ -> + // This bit of type-directed analysis ensures that parameterized partial active patterns returning unit do not need to take an argument + // See FSharp 1.0 3502 + let dtys, rty = stripFunTy cenv.g vexpty + + if dtys.Length = args.Length + 1 && isOptionTy cenv.g rty && isUnitTy cenv.g (destOptionTy cenv.g rty) then + args, SynPat.Const(SynConst.Unit, m) + else + List.frontAndBack args + + if not (isNil activePatArgsAsSynPats) && apinfo.ActiveTags.Length <> 1 then + errorR (Error (FSComp.SR.tcRequireActivePatternWithOneResult (), m)) + + let activePatArgsAsSynExprs = List.map convSynPatToSynExpr activePatArgsAsSynPats + + let activePatResTys = NewInferenceTypes apinfo.Names + let activePatType = apinfo.OverallType cenv.g m ty activePatResTys isStructRetTy + + let delayed = activePatArgsAsSynExprs |> List.map (fun arg -> DelayedApp(ExprAtomicFlag.NonAtomic, false, None, arg, unionRanges (rangeOfLid longId) arg.Range)) + let activePatExpr, tpenv = PropagateThenTcDelayed cenv (MustEqual activePatType) env tpenv m vexp vexpty ExprAtomicFlag.NonAtomic delayed + + if idx >= activePatResTys.Length then error(Error(FSComp.SR.tcInvalidIndexIntoActivePatternArray(), m)) + let argty = List.item idx activePatResTys + + let arg', acc = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) argty patarg + + // The identity of an active pattern consists of its value and the types it is applied to. + // If there are any expression args then we've lost identity. + let activePatIdentity = if isNil activePatArgsAsSynExprs then Some (vref, tinst) else None + (fun values -> + TPat_query((activePatExpr, activePatResTys, isStructRetTy, activePatIdentity, idx, apinfo), arg' values, m)), acc + + | Item.UnionCase _ | Item.ExnCase _ as item -> + // Report information about the case occurrence to IDE + CallNameResolutionSink cenv.tcSink (lidRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.eAccessRights) + + let mkf, argTys, argNames = ApplyUnionCaseOrExnTypesForPat m cenv env ty item + let numArgTys = argTys.Length + + let args, extraPatternsFromNames = + match args with + | SynArgPats.Pats args -> args, [] + | SynArgPats.NamePatPairs (pairs, m) -> + // rewrite patterns from the form (name-N = pat-N; ...) to (..._, pat-N, _...) + // so type T = Case of name: int * value: int + // | Case(value = v) + // will become + // | Case(_, v) + let result = Array.zeroCreate numArgTys + let extraPatterns = List () + + for id, pat in pairs do + match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with + | None -> + extraPatterns.Add pat + match item with + | Item.UnionCase(uci, _) -> + errorR (Error (FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName (uci.DisplayName, id.idText), id.idRange)) + | Item.ExnCase tcref -> + errorR (Error (FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName (tcref.DisplayName, id.idText), id.idRange)) + | _ -> + errorR (Error (FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName id.idText, id.idRange)) + + | Some idx -> + let argItem = + match item with + | Item.UnionCase (uci, _) -> Item.UnionCaseField (uci, idx) + | Item.ExnCase tref -> Item.RecdField (RecdFieldInfo ([], RecdFieldRef (tref, id.idText))) + | _ -> failwithf "Expecting union case or exception item, got: %O" item + + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, emptyTyparInst, ItemOccurence.Pattern, ad) + + match box result.[idx] with + | null -> result.[idx] <- pat + | _ -> + extraPatterns.Add pat + errorR (Error (FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce id.idText, id.idRange)) + + for i = 0 to numArgTys - 1 do + if isNull (box result.[i]) then + result.[i] <- SynPat.Wild (m.MakeSynthetic()) + + let extraPatterns = + if isNull extraPatterns then [] else List.ofSeq extraPatterns + + let args = List.ofArray result + if result.Length = 1 then args, extraPatterns + else [ SynPat.Tuple(false, args, m) ], extraPatterns + + let args, extraPatterns = + match args with + | [] -> [], [] + + // note: the next will always be parenthesized + | [SynPatErrorSkip(SynPat.Tuple (false, args, _)) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Tuple (false, args, _)), _))] when numArgTys > 1 -> args, [] + + // note: we allow both 'C _' and 'C (_)' regardless of number of argument of the pattern + | [SynPatErrorSkip(SynPat.Wild _ as e) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Wild _ as e), _))] -> List.replicate numArgTys e, [] + + + | args when numArgTys = 0 -> + errorR (Error (FSComp.SR.tcUnionCaseDoesNotTakeArguments (), m)) + [], args + + | arg :: rest when numArgTys = 1 -> + if numArgTys = 1 && not (List.isEmpty rest) then + errorR (Error (FSComp.SR.tcUnionCaseRequiresOneArgument (), m)) + [arg], rest + + | [arg] -> [arg], [] + + | args -> + [], args + + let args, extraPatterns = + let numArgs = args.Length + if numArgs = numArgTys then + args, extraPatterns + elif numArgs < numArgTys then + if numArgTys > 1 then + // Expects tuple without enough args + errorR (Error (FSComp.SR.tcUnionCaseExpectsTupledArguments numArgTys, m)) + else + errorR (UnionCaseWrongArguments (env.DisplayEnv, numArgTys, numArgs, m)) + args @ (List.init (numArgTys - numArgs) (fun _ -> SynPat.Wild (m.MakeSynthetic()))), extraPatterns + else + let args, remaining = args |> List.splitAt numArgTys + for remainingArg in remaining do + errorR (UnionCaseWrongArguments (env.DisplayEnv, numArgTys, numArgs, remainingArg.Range)) + args, extraPatterns @ remaining + + let extraPatterns = extraPatterns @ extraPatternsFromNames + let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args + let _, acc = TcPatterns warnOnUpper cenv env vFlags acc (NewInferenceTypes extraPatterns) extraPatterns + (fun values -> mkf m (List.map (fun f -> f values) args')), acc + + | Item.ILField finfo -> + CheckILFieldInfoAccessible cenv.g cenv.amap lidRange env.AccessRights finfo + if not finfo.IsStatic then + errorR (Error (FSComp.SR.tcFieldIsNotStatic finfo.FieldName, lidRange)) + CheckILFieldAttributes cenv.g finfo m + match finfo.LiteralValue with + | None -> error (Error (FSComp.SR.tcFieldNotLiteralCannotBeUsedInPattern (), lidRange)) + | Some lit -> + checkNoArgsForLiteral () + let _, acc = tcArgPatterns () + + UnifyTypes cenv env m ty (finfo.FieldType (cenv.amap, m)) + let c' = TcFieldInit lidRange lit + let item = Item.ILField finfo + CallNameResolutionSink cenv.tcSink (lidRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.AccessRights) + (fun _ -> TPat_const (c', m)), acc + + | Item.RecdField rfinfo -> + CheckRecdFieldInfoAccessible cenv.amap lidRange env.AccessRights rfinfo + if not rfinfo.IsStatic then errorR (Error (FSComp.SR.tcFieldIsNotStatic(rfinfo.DisplayName), lidRange)) + CheckRecdFieldInfoAttributes cenv.g rfinfo lidRange |> CommitOperationResult + match rfinfo.LiteralValue with + | None -> error (Error(FSComp.SR.tcFieldNotLiteralCannotBeUsedInPattern(), lidRange)) + | Some lit -> + checkNoArgsForLiteral() + let _, acc = tcArgPatterns () + + UnifyTypes cenv env m ty rfinfo.FieldType + let item = Item.RecdField rfinfo + // FUTURE: can we do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE. + CallNameResolutionSink cenv.tcSink (lidRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.AccessRights) + (fun _ -> TPat_const (lit, m)), acc + + | Item.Value vref -> + match vref.LiteralValue with + | None -> error (Error(FSComp.SR.tcNonLiteralCannotBeUsedInPattern(), m)) + | Some lit -> + let _, _, _, vexpty, _, _ = TcVal true cenv env tpenv vref None None lidRange + CheckValAccessible lidRange env.AccessRights vref + CheckFSharpAttributes cenv.g vref.Attribs lidRange |> CommitOperationResult + checkNoArgsForLiteral() + let _, acc = tcArgPatterns () + + UnifyTypes cenv env m ty vexpty + let item = Item.Value vref + CallNameResolutionSink cenv.tcSink (lidRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Pattern, env.AccessRights) + (fun _ -> TPat_const (lit, m)), acc + + | _ -> error (Error(FSComp.SR.tcRequireVarConstRecogOrLiteral(), m)) + + | SynPat.QuoteExpr(_, m) -> + errorR (Error(FSComp.SR.tcInvalidPattern(), m)) + (fun _ -> TPat_error m), (tpenv, names, takenNames) + + | SynPat.Tuple (isExplicitStruct, args, m) -> + try + let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m ty isExplicitStruct args + let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args + (fun values -> TPat_tuple(tupInfo, List.map (fun f -> f values) args', argTys, m)), acc + with e -> + errorRecovery e m + let _, acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (NewInferenceTypes args) args + (fun _ -> TPat_error m), acc + + | SynPat.Paren (p, _) -> + TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p + + | SynPat.ArrayOrList (isArray, args, m) -> + let argty = NewInferenceType () + UnifyTypes cenv env m ty (if isArray then mkArrayType cenv.g argty else mkListTy cenv.g argty) + let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (List.map (fun _ -> argty) args) args + (fun values -> + let args' = List.map (fun f -> f values) args' + if isArray then TPat_array(args', argty, m) + else List.foldBack (mkConsListPat cenv.g argty) args' (mkNilListPat cenv.g m argty)), acc + + | SynPat.Record (flds, m) -> + let tinst, tcref, fldsmap, _fldsList = BuildFieldMap cenv env true ty flds m + // REVIEW: use _fldsList to type check pattern in code order not field defn order + let gtyp = mkAppTy tcref tinst + let inst = List.zip (tcref.Typars m) tinst + UnifyTypes cenv env m ty gtyp + let fields = tcref.TrueInstanceFieldsAsList + let ftys = fields |> List.map (fun fsp -> actualTyOfRecdField inst fsp, fsp) + let fldsmap', acc = + ((tpenv, names, takenNames), ftys) ||> List.mapFold (fun s (ty, fsp) -> + match fldsmap.TryGetValue fsp.rfield_id.idText with + | true, v -> TcPat warnOnUpper cenv env None vFlags s ty v + | _ -> (fun _ -> TPat_wild m), s) + (fun values -> TPat_recd (tcref, tinst, List.map (fun f -> f values) fldsmap', m)), + acc + + | SynPat.DeprecatedCharRange (c1, c2, m) -> + errorR(Deprecated(FSComp.SR.tcUseWhenPatternGuard(), m)) + UnifyTypes cenv env m ty cenv.g.char_ty + (fun _ -> TPat_range(c1, c2, m)), (tpenv, names, takenNames) + + | SynPat.Null m -> + try AddCxTypeMustSupportNull env.DisplayEnv cenv.css m NoTrace ty + with e -> errorRecovery e m + (fun _ -> TPat_null m), (tpenv, names, takenNames) + + | SynPat.InstanceMember (_, _, _, _, m) -> + errorR(Error(FSComp.SR.tcIllegalPattern(), pat.Range)) + (fun _ -> TPat_wild m), (tpenv, names, takenNames) + + | SynPat.FromParseError (pat, _) -> + suppressErrorReporting (fun () -> TcPatAndRecover warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) (NewErrorType()) pat) + +and TcPatterns warnOnUpper cenv env vFlags s argTys args = + assert (List.length args = List.length argTys) + List.mapFold (fun s (ty, pat) -> TcPat warnOnUpper cenv env None vFlags s ty pat) s (List.zip argTys args) + +and solveTypAsError cenv denv m ty = SolveTypeAsError denv cenv.css m ty + +and RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv expr = + // This function is motivated by cases like + // query { for ... join(for x in f(). } + // where there is incomplete code in a query, and we are current just dropping a piece of the AST on the floor (above, the bit inside the 'join'). + // + // The problem with dropping the AST on the floor is that we get no captured resolutions, which means no Intellisense/QuickInfo/ParamHelp. + // + // The idea behind the fix is to semi-typecheck this AST-fragment, just to get resolutions captured. + // + // The tricky bit is to not also have any other effects from typechecking, namely producing error diagnostics (which may be spurious) or having + // side-effects on the typecheck environment. + // + // REVIEW: We are yet to deal with the tricky bit. As it stands, we turn off error logging, but still have typechecking environment effects. As a result, + // at the very least, you cannot call this function unless you're already reported a typechecking error (the 'worst' possible outcome would be + // to incorrectly solve typecheck constraints as a result of effects in this function, and then have the code compile successfully and behave + // in some weird way; so ensure the code can't possibly compile before calling this function as an expedient way to get better IntelliSense). + suppressErrorReporting (fun () -> + try ignore(TcExprOfUnknownType cenv env tpenv expr) + with e -> ()) + +and RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed = + + let rec dummyCheckedDelayed delayed = + match delayed with + | DelayedApp (_hpa, _, _, arg, _mExprAndArg) :: otherDelayed -> + RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv arg + dummyCheckedDelayed otherDelayed + | _ -> () + dummyCheckedDelayed delayed + +and TcExprOfUnknownType cenv env tpenv expr = + let exprty = NewInferenceType () + let expr', tpenv = TcExpr cenv (MustEqual exprty) env tpenv expr + expr', exprty, tpenv + +and TcExprFlex cenv flex compat (desiredTy: TType) (env: TcEnv) tpenv (synExpr: SynExpr) = + // This is the old way of introducing flexibility via subtype constraints, still active + // for compat reasons. + if flex then + let argty = NewInferenceType () + if compat then + (destTyparTy cenv.g argty).SetIsCompatFlex(true) + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css synExpr.Range NoTrace desiredTy argty + let expr2, tpenv = TcExprFlex2 cenv argty env false tpenv synExpr + let expr3 = mkCoerceIfNeeded cenv.g desiredTy argty expr2 + expr3, tpenv + else + TcExprFlex2 cenv desiredTy env false tpenv synExpr + +and TcExprFlex2 cenv desiredTy env isMethodArg tpenv synExpr = + TcExpr cenv (MustConvertTo (isMethodArg, desiredTy)) env tpenv synExpr + +and TcExpr cenv ty (env: TcEnv) tpenv (expr: SynExpr) = + // Start an error recovery handler + // Note the try/with can lead to tail-recursion problems for iterated constructs, e.g. let... in... + // So be careful! + try + TcExprNoRecover cenv ty env tpenv expr + with e -> + let m = expr.Range + // Error recovery - return some rubbish expression, but replace/annotate + // the type of the current expression with a type variable that indicates an error + errorRecovery e m + solveTypAsError cenv env.DisplayEnv m ty.Commit + mkThrow m ty.Commit (mkOne cenv.g m), tpenv + +and TcExprNoRecover cenv (ty: OverallTy) (env: TcEnv) tpenv (expr: SynExpr) = + + // Count our way through the expression shape that makes up an object constructor + // See notes at definition of "ctor" re. object model constructors. + let env = + if GetCtorShapeCounter env > 0 then AdjustCtorShapeCounter (fun x -> x - 1) env + else env + + TcExprThen cenv ty env tpenv false expr [] + +// This recursive entry is only used from one callsite (DiscardAfterMissingQualificationAfterDot) +// and has been added relatively late in F# 4.0 to preserve the structure of previous code. It pushes a 'delayed' parameter +// through TcExprOfUnknownType, TcExpr and TcExprNoRecover +and TcExprOfUnknownTypeThen cenv env tpenv expr delayed = + let exprty = NewInferenceType () + let expr', tpenv = + try + TcExprThen cenv (MustEqual exprty) env tpenv false expr delayed + with e -> + let m = expr.Range + errorRecovery e m + solveTypAsError cenv env.DisplayEnv m exprty + mkThrow m exprty (mkOne cenv.g m), tpenv + expr', exprty, tpenv + +/// This is used to typecheck legitimate 'main body of constructor' expressions +and TcExprThatIsCtorBody safeInitInfo cenv overallTy env tpenv expr = + let env = {env with eCtorInfo = Some (InitialExplicitCtorInfo safeInitInfo) } + let expr, tpenv = TcExpr cenv overallTy env tpenv expr + let expr = CheckAndRewriteObjectCtor cenv.g env expr + expr, tpenv + +/// This is used to typecheck all ordinary expressions including constituent +/// parts of ctor. +and TcExprThatCanBeCtorBody cenv overallTy env tpenv expr = + let env = if AreWithinCtorShape env then AdjustCtorShapeCounter (fun x -> x + 1) env else env + TcExpr cenv overallTy env tpenv expr + +/// This is used to typecheck legitimate 'non-main body of object constructor' expressions +and TcExprThatCantBeCtorBody cenv overallTy env tpenv expr = + let env = if AreWithinCtorShape env then ExitCtorShapeRegion env else env + TcExpr cenv overallTy env tpenv expr + +/// This is used to typecheck legitimate 'non-main body of object constructor' expressions +and TcStmtThatCantBeCtorBody cenv env tpenv expr = + let env = if AreWithinCtorShape env then ExitCtorShapeRegion env else env + TcStmt cenv env tpenv expr + +and TcStmt cenv env tpenv synExpr = + let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr + let m = synExpr.Range + let wasUnit = UnifyUnitType cenv env m ty expr + if wasUnit then + expr, tpenv + else + mkCompGenSequential m expr (mkUnit cenv.g m), tpenv + +and TryTcStmt cenv env tpenv synExpr = + let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr + let m = synExpr.Range + let hasTypeUnit = TryUnifyUnitTypeWithoutWarning cenv env m ty + hasTypeUnit, expr, tpenv + +/// During checking of expressions of the form (x(y)).z(w1, w2) +/// keep a stack of things on the right. This lets us recognize +/// method applications and other item-based syntax. +and TcExprThen cenv (overallTy: OverallTy) env tpenv isArg synExpr delayed = + match synExpr with + + | LongOrSingleIdent (isOpt, longId, altNameRefCellOpt, mLongId) -> + if isOpt then errorR(Error(FSComp.SR.tcSyntaxErrorUnexpectedQMark(), mLongId)) + // Check to see if pattern translation decided to use an alternative identifier. + match altNameRefCellOpt with + | Some {contents = SynSimplePatAlternativeIdInfo.Decided altId} -> + TcExprThen cenv overallTy env tpenv isArg (SynExpr.LongIdent (isOpt, LongIdentWithDots([altId], []), None, mLongId)) delayed + | _ -> TcLongIdentThen cenv overallTy env tpenv longId delayed + + // f x + // f(x) // hpa=true + // f[x] // hpa=true + | SynExpr.App (hpa, isInfix, func, arg, mFuncAndArg) -> + + // func (arg)[arg2] gives warning that .[ must be used. + match delayed with + | DelayedApp (hpa2, isSugar2, _, arg2, _) :: _ when not isInfix && (hpa = ExprAtomicFlag.NonAtomic) && isAdjacentListExpr isSugar2 hpa2 (Some synExpr) arg2 -> + let mWarning = unionRanges arg.Range arg2.Range + match arg with + | SynExpr.Paren _ -> + if cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + warning(Error(FSComp.SR.tcParenThenAdjacentListArgumentNeedsAdjustment(), mWarning)) + elif not (cenv.g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then + informationalWarning(Error(FSComp.SR.tcParenThenAdjacentListArgumentReserved(), mWarning)) + | SynExpr.ArrayOrListComputed _ + | SynExpr.ArrayOrList _ -> + if cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + warning(Error(FSComp.SR.tcListThenAdjacentListArgumentNeedsAdjustment(), mWarning)) + elif not (cenv.g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then + informationalWarning(Error(FSComp.SR.tcListThenAdjacentListArgumentReserved(), mWarning)) + | _ -> + if cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + warning(Error(FSComp.SR.tcOtherThenAdjacentListArgumentNeedsAdjustment(), mWarning)) + elif not (cenv.g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then + informationalWarning(Error(FSComp.SR.tcOtherThenAdjacentListArgumentReserved(), mWarning)) + + | _ -> () + + TcExprThen cenv overallTy env tpenv false func ((DelayedApp (hpa, isInfix, Some func, arg, mFuncAndArg)) :: delayed) + + // e + | SynExpr.TypeApp (func, _, typeArgs, _, _, mTypeArgs, mFuncAndTypeArgs) -> + TcExprThen cenv overallTy env tpenv false func ((DelayedTypeApp (typeArgs, mTypeArgs, mFuncAndTypeArgs)) :: delayed) + + // e1.id1 + // e1.id1.id2 + // etc. + | SynExpr.DotGet (e1, _, LongIdentWithDots(longId, _), _) -> + TcExprThen cenv overallTy env tpenv false e1 ((DelayedDotLookup (longId, synExpr.RangeWithoutAnyExtraDot)) :: delayed) + + // e1.[e2] + // e1.[e21, ..., e2n] + // etc. + | SynExpr.DotIndexedGet (e1, IndexerArgs indexArgs, mDot, mWholeExpr) -> + if not isArg && cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + informationalWarning(Error(FSComp.SR.tcIndexNotationDeprecated(), mDot)) + TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv None e1 indexArgs delayed + + // e1.[e2] <- e3 + // e1.[e21, ..., e2n] <- e3 + // etc. + | SynExpr.DotIndexedSet (e1, IndexerArgs indexArgs, e3, mOfLeftOfSet, mDot, mWholeExpr) -> + if cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + warning(Error(FSComp.SR.tcIndexNotationDeprecated(), mDot)) + TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv (Some (e3, mOfLeftOfSet)) e1 indexArgs delayed + + | _ -> + match delayed with + | [] -> TcExprUndelayed cenv overallTy env tpenv synExpr + | _ -> + let expr, exprty, tpenv = TcExprUndelayedNoType cenv env tpenv synExpr + PropagateThenTcDelayed cenv overallTy env tpenv synExpr.Range (MakeApplicableExprNoFlex cenv expr) exprty ExprAtomicFlag.NonAtomic delayed + +and TcExprsWithFlexes cenv env m tpenv flexes argTys args = + if List.length args <> List.length argTys then error(Error(FSComp.SR.tcExpressionCountMisMatch((List.length argTys), (List.length args)), m)) + (tpenv, List.zip3 flexes argTys args) ||> List.mapFold (fun tpenv (flex, ty, e) -> + TcExprFlex cenv flex false ty env tpenv e) + +and CheckSuperInit cenv objTy m = + // Check the type is not abstract + match tryTcrefOfAppTy cenv.g objTy with + | ValueSome tcref when isAbstractTycon tcref.Deref -> + errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(), m)) + | _ -> () + +//------------------------------------------------------------------------- +// TcExprUndelayed +//------------------------------------------------------------------------- + +and TcExprUndelayedNoType cenv env tpenv synExpr: Expr * TType * _ = + let overallTy = NewInferenceType () + let expr, tpenv = TcExprUndelayed cenv (MustEqual overallTy) env tpenv synExpr + expr, overallTy, tpenv + +/// Process a leaf construct where the actual type (or an approximation of it such as 'list<_>' +/// or 'array<_>') is already sufficiently pre-known, and the information in the overall type +/// can be eagerly propagated into the actual type (UnifyOverallType), including pre-calculating +/// any type-directed conversion. This must mean that types extracted when processing the expression are not +/// considered in determining any type-directed conversion. +/// +/// Used for: +/// - Array or List expressions (both computed and fixed-size), to propagate from the overall type into the array/list type +/// e.g. to infer element types, which may be relevant to processing each individual expression and the 'yield' +/// returns. +/// +/// - 'new ABC<_>(args)' expressions, to propagate from the overall type into the 'ABC<_>' type, e.g. to infer type parameters, +/// which may be relevant to checking the arguments. +/// +/// - object expressions '{ new ABC<_>(args) with ... }', to propagate from the overall type into the +/// object type, e.g. to infer type parameters, which may be relevant to checking the arguments and +/// methods of the object expression. +/// +/// - string literal expressions (though the propagation is not essential in this case) +/// +and TcPropagatingExprLeafThenConvert cenv overallTy actualTy (env: TcEnv) (* canAdhoc *) m (f: unit -> Expr * UnscopedTyparEnv) = + match overallTy with + | MustConvertTo _ when cenv.g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> + assert (cenv.g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions) + + // Compute the conversion _before_ processing the construct. We know enough to process this conversion eagerly. + UnifyOverallType cenv env m overallTy actualTy + + // Process the construct + let expr, tpenv = f () + + // Build the conversion + let expr2 = TcAdjustExprForTypeDirectedConversions cenv overallTy actualTy env (* canAdhoc *) m expr + expr2, tpenv + | _ -> + UnifyTypes cenv env m overallTy.Commit actualTy + f () + +/// Process a leaf construct, for cases where we propogate the overall type eagerly in +/// some cases. Then apply additional type-directed conversions. +/// +/// However in some cases favour propagating characteristics of the overall type. +/// +/// 'isPropagating' indicates if propagation occurs +/// 'processExpr' does the actual processing of the construct. +/// +/// Used for +/// - tuple (except if overallTy is a tuple type or a variable type that can become one) +/// - anon record (except if overallTy is an anon record type or a variable type that can become one) +/// - record (except if overallTy is requiresCtor || haveCtor or a record type or a variable type that can become one)) +and TcPossiblyPropogatingExprLeafThenConvert isPropagating cenv (overallTy: OverallTy) (env: TcEnv) m processExpr = + match overallTy with + | MustConvertTo(_, reqdTy) when cenv.g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && not (isPropagating reqdTy) -> + TcNonPropagatingExprLeafThenConvert cenv overallTy env m (fun () -> + let exprTy = NewInferenceType() + + // Here 'processExpr' will eventually do the unification with exprTy. + let expr, tpenv = processExpr exprTy + expr, exprTy, tpenv) + | _ -> + // Here 'processExpr' will do the unification with the overall type. + processExpr overallTy.Commit + +/// Process a leaf construct where the processing of the construct is initially independent +/// of the overall type. Determine and apply additional type-directed conversions after the processing +/// is complete, as the inferred type of the expression may enable a type-directed conversion. +/// +/// Used for: +/// - trait call +/// - LibraryOnlyUnionCaseFieldGet +/// - constants +and TcNonPropagatingExprLeafThenConvert cenv (overallTy: OverallTy) (env: TcEnv) m processExpr = + // Process the construct + let expr, exprTy, tpenv = processExpr () + + // Now compute the conversion, based on the post-processing type + UnifyOverallType cenv env m overallTy exprTy + + let expr2 = TcAdjustExprForTypeDirectedConversions cenv overallTy exprTy env (* true *) m expr + expr2, tpenv + +and TcAdjustExprForTypeDirectedConversions cenv (overallTy: OverallTy) actualTy (env: TcEnv) (* canAdhoc *) m expr = + match overallTy with + | MustConvertTo (_, reqdTy) when cenv.g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + AdjustExprForTypeDirectedConversions tcVal cenv.g cenv.amap cenv.infoReader env.AccessRights reqdTy actualTy m expr + | _ -> + expr + +and TcExprUndelayed cenv (overallTy: OverallTy) env tpenv (synExpr: SynExpr) = + + match synExpr with + // ( * ) + | SynExpr.Paren(SynExpr.IndexRange (None, opm, None, _m1, _m2, _), _, _, _) -> + let replacementExpr = SynExpr.Ident(ident(CompileOpName "*", opm)) + TcExpr cenv overallTy env tpenv replacementExpr + + | SynExpr.Paren (expr2, _, _, mWholeExprIncludingParentheses) -> + // We invoke CallExprHasTypeSink for every construct which is atomic in the syntax, i.e. where a '.' immediately following the + // construct is a dot-lookup for the result of the construct. + CallExprHasTypeSink cenv.tcSink (mWholeExprIncludingParentheses, env.NameEnv, overallTy.Commit, env.AccessRights) + let env = ShrinkContext env mWholeExprIncludingParentheses expr2.Range + TcExpr cenv overallTy env tpenv expr2 + + | SynExpr.DotIndexedGet _ | SynExpr.DotIndexedSet _ + | SynExpr.TypeApp _ | SynExpr.Ident _ | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) + + | SynExpr.Const (SynConst.String (s, _, m), _) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) + TcConstStringExpr cenv overallTy env m tpenv s + + | SynExpr.InterpolatedString (parts, _, m) -> + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.StringInterpolation m + + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) + + TcInterpolatedStringExpr cenv overallTy env m tpenv parts + + | SynExpr.Const (synConst, m) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) + TcConstExpr cenv overallTy env m tpenv synConst + + | SynExpr.Lambda _ -> + TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr + + | SynExpr.Match (spMatch, synInputExpr, synClauses, _m) -> + + let inputExpr, inputTy, tpenv = TcExprOfUnknownType cenv env tpenv synInputExpr + let mInputExpr = inputExpr.Range + let matchVal, matchExpr, tpenv = TcAndPatternCompileMatchClauses mInputExpr mInputExpr ThrowIncompleteMatchException cenv (Some inputExpr) inputTy overallTy env tpenv synClauses + let overallExpr = mkLet spMatch mInputExpr matchVal inputExpr matchExpr + overallExpr, tpenv + + // (function[spMatch] pat1 -> expr1 ... | patN -> exprN) + // + // --> + // (fun anonArg -> let[spMatch] anonVal = anonArg in pat1 -> expr1 ... | patN -> exprN) + // + // Note the presence of the "let" is visible in quotations regardless of the presence of sequence points, so + // <@ function x -> (x: int) @> + // is + // Lambda (_arg2, Let (x, _arg2, x)) + + | SynExpr.MatchLambda (isExnMatch, mArg, clauses, spMatch, m) -> + + let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy.Commit + let idv1, idve1 = mkCompGenLocal mArg (cenv.synArgNameGenerator.New()) domainTy + let envinner = ExitFamilyRegion env + let idv2, matchExpr, tpenv = TcAndPatternCompileMatchClauses m mArg (if isExnMatch then Throw else ThrowIncompleteMatchException) cenv None domainTy (MustConvertTo (false, resultTy)) envinner tpenv clauses + let overallExpr = mkMultiLambda m [idv1] ((mkLet spMatch m idv2 idve1 matchExpr), resultTy) + overallExpr, tpenv + + | SynExpr.Assert (x, m) -> + TcAssertExpr cenv overallTy env m tpenv x + + | SynExpr.Fixed (_, m) -> + error(Error(FSComp.SR.tcFixedNotAllowed(), m)) + + // e: ty + | SynExpr.Typed (synBodyExpr, synType, m) -> + let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType + UnifyOverallType cenv env m overallTy tgtTy + let bodyExpr, tpenv = TcExpr cenv (MustConvertTo (false, tgtTy)) env tpenv synBodyExpr + let bodyExpr2 = TcAdjustExprForTypeDirectedConversions cenv overallTy tgtTy env (* true *) m bodyExpr + bodyExpr2, tpenv + + // e :? ty + | SynExpr.TypeTest (synInnerExpr, tgtTy, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr + UnifyTypes cenv env m overallTy.Commit cenv.g.bool_ty + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy + let expr = mkCallTypeTest cenv.g m tgtTy innerExpr + expr, tpenv + + // SynExpr.AddressOf is noted in the syntax ast in order to recognize it as concrete type information + // during type checking, in particular prior to resolving overloads. This helps distinguish + // its use at method calls from the use of the conflicting 'ref' mechanism for passing byref parameters + | SynExpr.AddressOf (byref, synInnerExpr, opm, m) -> + TcExpr cenv overallTy env tpenv (mkSynPrefixPrim opm m (if byref then "~&" else "~&&") synInnerExpr) + + | SynExpr.Upcast (synInnerExpr, _, m) | SynExpr.InferredUpcast (synInnerExpr, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr + let tgtTy, tpenv = + match synExpr with + | SynExpr.Upcast (_, tgtTy, m) -> + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + UnifyTypes cenv env m tgtTy overallTy.Commit + tgtTy, tpenv + | SynExpr.InferredUpcast _ -> + overallTy.Commit, tpenv + | _ -> failwith "upcast" + TcStaticUpcast cenv env.DisplayEnv m tgtTy srcTy + let expr = mkCoerceExpr(innerExpr, tgtTy, m, srcTy) + expr, tpenv + + | SynExpr.Downcast (synInnerExpr, _, m) | SynExpr.InferredDowncast (synInnerExpr, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr + let tgtTy, tpenv, isOperator = + match synExpr with + | SynExpr.Downcast (_, tgtTy, m) -> + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + UnifyTypes cenv env m tgtTy overallTy.Commit + tgtTy, tpenv, true + | SynExpr.InferredDowncast _ -> overallTy.Commit, tpenv, false + | _ -> failwith "downcast" + TcRuntimeTypeTest (*isCast*)true isOperator cenv env.DisplayEnv m tgtTy srcTy + + // TcRuntimeTypeTest ensures tgtTy is a nominal type. Hence we can insert a check here + // based on the nullness semantics of the nominal type. + let expr = mkCallUnbox cenv.g m tgtTy innerExpr + expr, tpenv + + | SynExpr.Null m -> + AddCxTypeMustSupportNull env.DisplayEnv cenv.css m NoTrace overallTy.Commit + mkNull m overallTy.Commit, tpenv + + | SynExpr.Lazy (synInnerExpr, m) -> + let innerTy = NewInferenceType () + UnifyTypes cenv env m overallTy.Commit (mkLazyTy cenv.g innerTy) + let innerExpr, tpenv = TcExpr cenv (MustEqual innerTy) env tpenv synInnerExpr + let expr = mkLazyDelayed cenv.g m innerTy (mkUnitDelayLambda cenv.g m innerExpr) + expr, tpenv + + | SynExpr.Tuple (isExplicitStruct, args, _, m) -> + TcPossiblyPropogatingExprLeafThenConvert (fun ty -> isAnyTupleTy cenv.g ty || isTyparTy cenv.g ty) cenv overallTy env m (fun overallTy -> + let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m overallTy isExplicitStruct args + + let flexes = argTys |> List.map (fun _ -> false) + let args', tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys args + let expr = mkAnyTupled cenv.g m tupInfo args' argTys + expr, tpenv + ) + + | SynExpr.AnonRecd (isStruct, optOrigExpr, unsortedFieldExprs, mWholeExpr) -> + TcPossiblyPropogatingExprLeafThenConvert (fun ty -> isAnonRecdTy cenv.g ty || isTyparTy cenv.g ty) cenv overallTy env mWholeExpr (fun overallTy -> + TcAnonRecdExpr cenv overallTy env tpenv (isStruct, optOrigExpr, unsortedFieldExprs, mWholeExpr) + ) + + | SynExpr.ArrayOrList (isArray, args, m) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) + let argty = NewInferenceType () + let actualTy = if isArray then mkArrayType cenv.g argty else mkListTy cenv.g argty + + // Propagating type directed conversion, e.g. for + // let x : seq = [ 1; 2 ] + // Consider also the case where there is no relation but an op_Implicit is enabled from List<_> to C + // let x : C = [ B(); B() ] + + TcPropagatingExprLeafThenConvert cenv overallTy actualTy env (* canAdhoc *) m (fun () -> + + // Always allow subsumption if a nominal type is known prior to type checking any arguments + let flex = not (isTyparTy cenv.g argty) + let mutable first = true + let getInitEnv m = + if first then + first <- false + env + else + { env with eContextInfo = ContextInfo.CollectionElement (isArray, m) } + + let args', tpenv = List.mapFold (fun tpenv (x: SynExpr) -> TcExprFlex cenv flex false argty (getInitEnv x.Range) tpenv x) tpenv args + + let expr = + if isArray then Expr.Op (TOp.Array, [argty], args', m) + else List.foldBack (mkCons cenv.g argty) args' (mkNil cenv.g m argty) + expr, tpenv + ) + + | SynExpr.New (superInit, synObjTy, arg, mNewExpr) -> + let objTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.Use env tpenv synObjTy + + TcPropagatingExprLeafThenConvert cenv overallTy objTy env (* true *) mNewExpr (fun () -> + TcNewExpr cenv env tpenv objTy (Some synObjTy.Range) superInit arg mNewExpr + ) + + | SynExpr.ObjExpr (synObjTy, argopt, binds, extraImpls, mNewExpr, m) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.eAccessRights) + + // Note, allowing canAdhoc = true would disable subtype-based propagation from overallTy into checking of structure + // + // For example + // let x : A seq = { new Collection<_> with ... the element type should be known in here! } + // + // So op_Implicit is effectively disabled for direct uses of object expressions + //let canAdhoc = false + + let mObjTy = synObjTy.Range + + let objTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synObjTy + + // Work out the type of any interfaces to implement + let extraImpls, tpenv = + (tpenv, extraImpls) ||> List.mapFold (fun tpenv (SynInterfaceImpl(synIntfTy, overrides, m)) -> + let intfTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synIntfTy + if not (isInterfaceTy cenv.g intfTy) then + error(Error(FSComp.SR.tcExpectedInterfaceType(), m)) + if isErasedType cenv.g intfTy then + errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) + (m, intfTy, overrides), tpenv) + + let realObjTy = if isObjTy cenv.g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy + + TcPropagatingExprLeafThenConvert cenv overallTy realObjTy env (* canAdhoc *) m (fun () -> + TcObjectExpr cenv env tpenv (objTy, realObjTy, argopt, binds, extraImpls, mObjTy, mNewExpr, m) + ) + + | SynExpr.Record (inherits, optOrigExpr, flds, mWholeExpr) -> + + CallExprHasTypeSink cenv.tcSink (mWholeExpr, env.NameEnv, overallTy.Commit, env.AccessRights) + let requiresCtor = (GetCtorShapeCounter env = 1) // Get special expression forms for constructors + let haveCtor = Option.isSome inherits + TcPossiblyPropogatingExprLeafThenConvert (fun ty -> requiresCtor || haveCtor || isRecdTy cenv.g ty || isTyparTy cenv.g ty) cenv overallTy env mWholeExpr (fun overallTy -> + TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) + ) + + | SynExpr.While (spWhile, synGuardExpr, synBodyExpr, m) -> + UnifyTypes cenv env m overallTy.Commit cenv.g.unit_ty + let guardExpr, tpenv = TcExpr cenv (MustEqual cenv.g.bool_ty) env tpenv synGuardExpr + let bodyExpr, tpenv = TcStmt cenv env tpenv synBodyExpr + mkWhile cenv.g (spWhile, NoSpecialWhileLoopMarker, guardExpr, bodyExpr, m), tpenv + + | SynExpr.For (spBind, id, start, dir, finish, body, m) -> + UnifyTypes cenv env m overallTy.Commit cenv.g.unit_ty + let startExpr, tpenv = TcExpr cenv (MustEqual cenv.g.int_ty) env tpenv start + let finishExpr, tpenv = TcExpr cenv (MustEqual cenv.g.int_ty) env tpenv finish + let idv, _ = mkLocal id.idRange id.idText cenv.g.int_ty + let envinner = AddLocalVal cenv.g cenv.tcSink m idv env + + // notify name resolution sink about loop variable + let item = Item.Value(mkLocalValRef idv) + CallNameResolutionSink cenv.tcSink (idv.Range, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights) + + let bodyExpr, tpenv = TcStmt cenv envinner tpenv body + mkFastForLoop cenv.g (spBind, m, idv, startExpr, dir, finishExpr, bodyExpr), tpenv + + | SynExpr.ForEach (spForLoop, SeqExprOnly seqExprOnly, isFromSource, pat, enumSynExpr, bodySynExpr, m) -> + assert isFromSource + if seqExprOnly then warning (Error(FSComp.SR.tcExpressionRequiresSequence(), m)) + let enumSynExpr = + match RewriteRangeExpr enumSynExpr with + | Some e -> e + | None -> enumSynExpr + TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, m, spForLoop) + + | SynExpr.ComputationExpr (hasSeqBuilder, comp, m) -> + let env = ExitFamilyRegion env + cenv.TcSequenceExpressionEntry cenv env overallTy tpenv (hasSeqBuilder, comp) m + + | SynExpr.ArrayOrListComputed (isArray, comp, m) -> + let env = ExitFamilyRegion env + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.eAccessRights) + cenv.TcArrayOrListComputedExpression cenv env overallTy tpenv (isArray, comp) m + + | SynExpr.LetOrUse _ -> + TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) + + | SynExpr.TryWith (synBodyExpr, _mTryToWith, synWithClauses, mWithToLast, mTryToLast, spTry, spWith) -> + let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr + // Compile the pattern twice, once as a List.filter with all succeeding targets returning "1", and once as a proper catch block. + let filterClauses = + synWithClauses |> List.map (fun clause -> + let (SynMatchClause(pat, optWhenExpr, arrow, _, m, _)) = clause + let oneExpr = SynExpr.Const (SynConst.Int32 1, m) + SynMatchClause(pat, optWhenExpr, arrow, oneExpr, m, DebugPointAtTarget.No)) + let checkedFilterClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty (MustEqual cenv.g.int_ty) env tpenv filterClauses + let checkedHandlerClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty overallTy env tpenv synWithClauses + let v1, filterExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true FailFilter None cenv.g.exn_ty cenv.g.int_ty checkedFilterClauses + let v2, handlerExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true Rethrow None cenv.g.exn_ty overallTy.Commit checkedHandlerClauses + mkTryWith cenv.g (bodyExpr, v1, filterExpr, v2, handlerExpr, mTryToLast, overallTy.Commit, spTry, spWith), tpenv + + | SynExpr.TryFinally (synBodyExpr, synFinallyExpr, mTryToLast, spTry, spFinally) -> + let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr + let finallyExpr, tpenv = TcStmt cenv env tpenv synFinallyExpr + mkTryFinally cenv.g (bodyExpr, finallyExpr, mTryToLast, overallTy.Commit, spTry, spFinally), tpenv + + | SynExpr.JoinIn (e1, mInToken, e2, mAll) -> + errorR(Error(FSComp.SR.parsUnfinishedExpression("in"), mInToken)) + let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv e1) + let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv e2) + mkDefault(mAll, overallTy.Commit), tpenv + + | SynExpr.ArbitraryAfterError (_debugStr, m) -> + //solveTypAsError cenv env.DisplayEnv m overallTy + mkDefault(m, overallTy.Commit), tpenv + + | SynExpr.DiscardAfterMissingQualificationAfterDot (e1, m) -> + let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownTypeThen cenv env tpenv e1 [DelayedDot]) + mkDefault(m, overallTy.Commit), tpenv + + | SynExpr.FromParseError (e1, m) -> + //solveTypAsError cenv env.DisplayEnv m overallTy + let _, tpenv = suppressErrorReporting (fun () -> TcExpr cenv overallTy env tpenv e1) + mkDefault(m, overallTy.Commit), tpenv + + | SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m) -> + if dir then + TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) + else + // Constructors using "new (...) = then " + let expr1, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synExpr1 + if (GetCtorShapeCounter env) <> 1 then + errorR(Error(FSComp.SR.tcExpressionFormRequiresObjectConstructor(), m)) + let expr2, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv synExpr2 + Expr.Sequential (expr1, expr2, ThenDoSeq, sp, m), tpenv + + // Used to implement the type-directed 'implicit yield' rule for computation expressions + | SynExpr.SequentialOrImplicitYield (sp, synExpr1, synExpr2, otherExpr, m) -> + let isStmt, expr1, tpenv = TryTcStmt cenv env tpenv synExpr1 + if isStmt then + let env = ShrinkContext env m synExpr2.Range + let expr2, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synExpr2 + Expr.Sequential(expr1, expr2, NormalSeq, sp, m), tpenv + else + // The first expression wasn't unit-typed, so proceed to the alternative interpretation + // Note a copy of the first expression is embedded in 'otherExpr' and thus + // this will type-check the first expression over again. + TcExpr cenv overallTy env tpenv otherExpr + + | SynExpr.Do (synInnerExpr, m) -> + UnifyTypes cenv env m overallTy.Commit cenv.g.unit_ty + TcStmtThatCantBeCtorBody cenv env tpenv synInnerExpr + + | SynExpr.IfThenElse _ -> + TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) + + // This is for internal use in the libraries only + | SynExpr.LibraryOnlyStaticOptimization (constraints, e2, e3, m) -> + let constraints', tpenv = List.mapFold (TcStaticOptimizationConstraint cenv env) tpenv constraints + // Do not force the types of the two expressions to be equal + // This means uses of this construct have to be very carefully written + let e2', _, tpenv = TcExprOfUnknownType cenv env tpenv e2 + let e3', tpenv = TcExpr cenv overallTy env tpenv e3 + Expr.StaticOptimization (constraints', e2', e3', m), tpenv + + /// e1.longId <- e2 + | SynExpr.DotSet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, mStmt) -> + if lidwd.ThereIsAnExtraDotAtTheEnd then + // just drop rhs on the floor + let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) + TcExprThen cenv overallTy env tpenv false e1 [DelayedDotLookup(longId, mExprAndDotLookup)] + else + let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) + TcExprThen cenv overallTy env tpenv false e1 [DelayedDotLookup(longId, mExprAndDotLookup); MakeDelayedSet(e2, mStmt)] + + /// e1 <- e2 + | SynExpr.Set (e1, e2, mStmt) -> + TcExprThen cenv overallTy env tpenv false e1 [MakeDelayedSet(e2, mStmt)] + + /// e1.longId(e2) <- e3, very rarely used named property setters + | SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) -> + if lidwd.ThereIsAnExtraDotAtTheEnd then + // just drop rhs on the floor + let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) + TcExprThen cenv overallTy env tpenv false e1 [DelayedDotLookup(longId, mExprAndDotLookup)] + else + let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) + TcExprThen cenv overallTy env tpenv false e1 + [ DelayedDotLookup(longId, mExprAndDotLookup); + DelayedApp(ExprAtomicFlag.Atomic, false, None, e2, mStmt) + MakeDelayedSet(e3, mStmt)] + + | SynExpr.LongIdentSet (lidwd, e2, m) -> + if lidwd.ThereIsAnExtraDotAtTheEnd then + // just drop rhs on the floor + TcLongIdentThen cenv overallTy env tpenv lidwd [ ] + else + TcLongIdentThen cenv overallTy env tpenv lidwd [ MakeDelayedSet(e2, m) ] + + // Type.Items(e1) <- e2 + | SynExpr.NamedIndexedPropertySet (lidwd, e1, e2, mStmt) -> + if lidwd.ThereIsAnExtraDotAtTheEnd then + // just drop rhs on the floor + TcLongIdentThen cenv overallTy env tpenv lidwd [ ] + else + TcLongIdentThen cenv overallTy env tpenv lidwd + [ DelayedApp(ExprAtomicFlag.Atomic, false, None, e1, mStmt) + MakeDelayedSet(e2, mStmt) ] + + | SynExpr.TraitCall (tps, memSpfn, arg, m) -> + TcNonPropagatingExprLeafThenConvert cenv overallTy env m (fun () -> + let synTypes = tps |> List.map (fun tp -> SynType.Var(tp, m)) + let traitInfo, tpenv = TcPseudoMemberSpec cenv NewTyparsOK env synTypes tpenv memSpfn m + if BakedInTraitConstraintNames.Contains traitInfo.MemberName then + warning(BakedInMemberConstraintName(traitInfo.MemberName, m)) + + let argTys = traitInfo.ArgumentTypes + let returnTy = GetFSharpViewOfReturnType cenv.g traitInfo.ReturnType + let args, namedCallerArgs = GetMethodArgs arg + if not (isNil namedCallerArgs) then errorR(Error(FSComp.SR.tcNamedArgumentsCannotBeUsedInMemberTraits(), m)) + // Subsumption at trait calls if arguments have nominal type prior to unification of any arguments or return type + let flexes = argTys |> List.map (isTyparTy cenv.g >> not) + let args', tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys args + AddCxMethodConstraint env.DisplayEnv cenv.css m NoTrace traitInfo + Expr.Op (TOp.TraitCall traitInfo, [], args', m), returnTy, tpenv + ) + + | SynExpr.LibraryOnlyUnionCaseFieldGet (e1, c, n, m) -> + TcNonPropagatingExprLeafThenConvert cenv overallTy env m (fun () -> + let e1', ty1, tpenv = TcExprOfUnknownType cenv env tpenv e1 + let mkf, ty2 = TcUnionCaseOrExnField cenv env ty1 m c n + ((fun (a, b) n -> mkUnionCaseFieldGetUnproven cenv.g (e1', a, b, n, m)), + (fun a n -> mkExnCaseFieldGet(e1', a, n, m))) + mkf n, ty2, tpenv + ) + + | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, c, n, e2, m) -> + UnifyTypes cenv env m overallTy.Commit cenv.g.unit_ty + let e1', ty1, tpenv = TcExprOfUnknownType cenv env tpenv e1 + let mkf, ty2 = TcUnionCaseOrExnField cenv env ty1 m c n + ((fun (a, b) n e2' -> + if not (isUnionCaseFieldMutable cenv.g a n) then errorR(Error(FSComp.SR.tcFieldIsNotMutable(), m)) + mkUnionCaseFieldSet(e1', a, b, n, e2', m)), + (fun a n e2' -> + if not (isExnFieldMutable a n) then errorR(Error(FSComp.SR.tcFieldIsNotMutable(), m)) + mkExnCaseFieldSet(e1', a, n, e2', m))) + let e2', tpenv = TcExpr cenv (MustEqual ty2) env tpenv e2 + mkf n e2', tpenv + + | SynExpr.LibraryOnlyILAssembly (s, tyargs, args, rtys, m) -> + let s = (s :?> ILInstr[]) + let argTys = NewInferenceTypes args + let tyargs', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tyargs + // No subsumption at uses of IL assembly code + let flexes = argTys |> List.map (fun _ -> false) + let args', tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys args + let rtys', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv rtys + let returnTy = + match rtys' with + | [] -> cenv.g.unit_ty + | [ returnTy ] -> returnTy + | _ -> error(InternalError("Only zero or one pushed items are permitted in IL assembly code", m)) + UnifyTypes cenv env m overallTy.Commit returnTy + mkAsmExpr (Array.toList s, tyargs', args', rtys', m), tpenv + + | SynExpr.Quote (oper, raw, ast, isFromQueryExpression, m) -> + CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) + TcQuotationExpr cenv overallTy env tpenv (oper, raw, ast, isFromQueryExpression, m) + + | SynExpr.YieldOrReturn ((isTrueYield, _), _, m) + | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, m) when isTrueYield -> + error(Error(FSComp.SR.tcConstructRequiresListArrayOrSequence(), m)) + + | SynExpr.YieldOrReturn ((_, isTrueReturn), _, m) + | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, m) when isTrueReturn -> + error(Error(FSComp.SR.tcConstructRequiresComputationExpressions(), m)) + + | SynExpr.YieldOrReturn (_, _, m) + | SynExpr.YieldOrReturnFrom (_, _, m) + | SynExpr.ImplicitZero m -> + error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m)) + + | SynExpr.DoBang (_, m) + | SynExpr.LetOrUseBang (range=m) -> + error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) + + | SynExpr.MatchBang (_, _, _, m) -> + error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) + + | SynExpr.IndexFromEnd (range=m) + | SynExpr.IndexRange (range=m) -> + error(Error(FSComp.SR.tcInvalidIndexerExpression(), m)) + +// Converts 'a..b' to a call to the '(..)' operator in FSharp.Core +// Converts 'a..b..c' to a call to the '(.. ..)' operator in FSharp.Core +// +// NOTE: we could eliminate these more efficiently in LowerCallsAndSeqs.fs, since +// [| 1..4 |] +// becomes [| for i in (..) 1 4 do yield i |] +// instead of generating the array directly from the ranges +and RewriteRangeExpr expr = + match expr with + // a..b..c (parsed as (a..b)..c ) + | SynExpr.IndexRange(Some (SynExpr.IndexRange(Some expr1, _, Some synStepExpr, _, _, _)), _, Some expr2, _m1, _m2, wholem) -> + Some (mkSynTrifix wholem ".. .." expr1 synStepExpr expr2) + // a..b + | SynExpr.IndexRange (Some expr1, opm, Some expr2, _m1, _m2, wholem) -> + let otherExpr = + match mkSynInfix opm expr1 ".." expr2 with + | SynExpr.App (a, b, c, d, _) -> SynExpr.App (a, b, c, d, wholem) + | _ -> failwith "impossible" + Some otherExpr + | _ -> None + +/// Check lambdas as a group, to catch duplicate names in patterns +and TcIteratedLambdas cenv isFirst (env: TcEnv) overallTy takenNames tpenv e = + match e with + | SynExpr.Lambda (isMember, isSubsequent, spats, _, bodyExpr, _, m) when isMember || isFirst || isSubsequent -> + let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy.Commit + let vs, (tpenv, names, takenNames) = TcSimplePats cenv isMember CheckCxs domainTy env (tpenv, Map.empty, takenNames) spats + let envinner, _, vspecMap = MakeAndPublishSimpleValsForMergedScope cenv env m names + let byrefs = vspecMap |> Map.map (fun _ v -> isByrefTy cenv.g v.Type, v) + let envinner = if isMember then envinner else ExitFamilyRegion envinner + let vspecs = vs |> List.map (fun nm -> NameMap.find nm vspecMap) + + // Match up the arginfos with the generated arguments and apply any information extracted from the attributes + let envinner = + match envinner.eLambdaArgInfos with + | infos :: rest -> + if infos.Length = vspecs.Length then + (vspecs, infos) ||> List.iter2 (fun v argInfo -> + let inlineIfLambda = HasFSharpAttribute cenv.g cenv.g.attrib_InlineIfLambdaAttribute argInfo.Attribs + if inlineIfLambda then + v.SetInlineIfLambda()) + { envinner with eLambdaArgInfos = rest } + | [] -> envinner + + let bodyExpr, tpenv = TcIteratedLambdas cenv false envinner (MustConvertTo (false, resultTy)) takenNames tpenv bodyExpr + // See bug 5758: Non-monotonicity in inference: need to ensure that parameters are never inferred to have byref type, instead it is always declared + byrefs |> Map.iter (fun _ (orig, v) -> + if not orig && isByrefTy cenv.g v.Type then errorR(Error(FSComp.SR.tcParameterInferredByref v.DisplayName, v.Range))) + + mkMultiLambda m vspecs (bodyExpr, resultTy), tpenv + + | e -> + // Dive into the expression to check for syntax errors and suppress them if they show. + conditionallySuppressErrorReporting (not isFirst && synExprContainsError e) (fun () -> + TcExpr cenv overallTy env tpenv e) + +and (|IndexArgOptionalFromEnd|) indexArg = + match indexArg with + | SynExpr.IndexFromEnd (a, m) -> (a, true, m) + | expr -> (expr, false, expr.Range) + +and DecodeIndexArg indexArg = + match indexArg with + | SynExpr.IndexRange (info1, _opm, info2, m1, m2, _) -> + let info1 = + match info1 with + | Some (IndexArgOptionalFromEnd (expr1, isFromEnd1, _)) -> Some (expr1, isFromEnd1) + | None -> None + let info2 = + match info2 with + | Some (IndexArgOptionalFromEnd (expr2, isFromEnd2, _)) -> Some (expr2, isFromEnd2) + | None -> None + IndexArgRange (info1, info2, m1, m2) + | IndexArgOptionalFromEnd (expr, isFromEnd, m) -> + IndexArgItem(expr, isFromEnd, m) + +and (|IndexerArgs|) e = + match e with + | SynExpr.IndexRange _ -> [e] + | SynExpr.IndexFromEnd _ -> [e] + | SynExpr.Tuple (false, args, _, _) -> args + | e -> [e] + +and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv (setInfo: _ option) synLeftExpr indexArgs delayed = + let leftExpr, e1ty, tpenv = TcExprOfUnknownType cenv env tpenv synLeftExpr + let expandedIndexArgs = ExpandIndexArgs (Some synLeftExpr) indexArgs + TcIndexingThen cenv env overallTy mWholeExpr mDot tpenv setInfo (Some synLeftExpr) leftExpr e1ty expandedIndexArgs indexArgs delayed + +// Eliminate GetReverseIndex from index args +and ExpandIndexArgs (synLeftExprOpt: SynExpr option) indexArgs = + + // xs.GetReverseIndex rank offset - 1 + let rewriteReverseExpr (rank: int) (offset: SynExpr) (range: range) = + let rankExpr = SynExpr.Const(SynConst.Int32(rank), range) + let sliceArgs = SynExpr.Paren(SynExpr.Tuple(false, [rankExpr; offset], [], range), range, Some range, range) + match synLeftExprOpt with + | None -> error(Error(FSComp.SR.tcInvalidUseOfReverseIndex(), range)) + | Some xsId -> + mkSynApp1 + (mkSynDot range range xsId (mkSynId (range.MakeSynthetic()) "GetReverseIndex")) + sliceArgs + range + + let mkSynSomeExpr (m: range) x = + let m = m.MakeSynthetic() + SynExpr.App (ExprAtomicFlag.NonAtomic, false, mkSynLidGet m FSharpLib.CorePath "Some", x, m) + + let mkSynNoneExpr (m: range) = + let m = m.MakeSynthetic() + mkSynLidGet m FSharpLib.CorePath "None" + + let expandedIndexArgs = + indexArgs + |> List.mapi ( fun pos indexerArg -> + match DecodeIndexArg indexerArg with + | IndexArgItem(expr, fromEnd, range) -> + [ if fromEnd then rewriteReverseExpr pos expr range else expr ] + | IndexArgRange(info1, info2, range1, range2) -> + [ + match info1 with + | Some (a1, isFromEnd1) -> + yield mkSynSomeExpr range1 (if isFromEnd1 then rewriteReverseExpr pos a1 range1 else a1) + | None -> + yield mkSynNoneExpr range1 + match info2 with + | Some (a2, isFromEnd2) -> + yield mkSynSomeExpr range2 (if isFromEnd2 then rewriteReverseExpr pos a2 range2 else a2) + | None -> + yield mkSynNoneExpr range1 + ] + ) + |> List.collect id + + expandedIndexArgs + +// Check expr.[idx] +// This is a little over complicated for my liking. Basically we want to interpret e1.[idx] as e1.Item(idx). +// However it's not so simple as all that. First "Item" can have a different name according to an attribute in +// .NET metadata. This means we manually typecheck 'expr and look to see if it has a nominal type. We then +// do the right thing in each case. +and TcIndexingThen cenv env overallTy mWholeExpr mDot tpenv setInfo synLeftExprOpt expr e1ty expandedIndexArgs indexArgs delayed = + let ad = env.AccessRights + // Find the first type in the effective hierarchy that either has a DefaultMember attribute OR + // has a member called 'Item' + let isIndex = indexArgs |> List.forall (fun indexArg -> match DecodeIndexArg indexArg with IndexArgItem _ -> true | _ -> false) + let propName = + if isIndex then + FoldPrimaryHierarchyOfType (fun ty acc -> + match acc with + | None -> + match tryTcrefOfAppTy cenv.g ty with + | ValueSome tcref -> + TryFindTyconRefStringAttribute cenv.g mWholeExpr cenv.g.attrib_DefaultMemberAttribute tcref + | _ -> + let item = Some "Item" + match AllPropInfosOfTypeInScope ResultCollectionSettings.AtMostOneResult cenv.infoReader env.NameEnv item ad IgnoreOverrides mWholeExpr ty with + | [] -> None + | _ -> item + | _ -> acc) + cenv.g + cenv.amap + mWholeExpr + AllowMultiIntfInstantiations.Yes + e1ty + None + else Some "GetSlice" + + let isNominal = isAppTy cenv.g e1ty + + let isArray = isArrayTy cenv.g e1ty + let isString = typeEquiv cenv.g cenv.g.string_ty e1ty + + let idxRange = indexArgs |> List.map (fun e -> e.Range) |> List.reduce unionRanges + + let MakeIndexParam setSliceArrayOption = + match List.map DecodeIndexArg indexArgs with + | [] -> failwith "unexpected empty index list" + | [IndexArgItem _] -> SynExpr.Paren (expandedIndexArgs.Head, range0, None, idxRange) + | _ -> SynExpr.Paren (SynExpr.Tuple (false, expandedIndexArgs @ Option.toList setSliceArrayOption, [], idxRange), range0, None, idxRange) + + let attemptArrayString = + let indexOpPath = ["Microsoft";"FSharp";"Core";"LanguagePrimitives";"IntrinsicFunctions"] + let sliceOpPath = ["Microsoft";"FSharp";"Core";"Operators";"OperatorIntrinsics"] + + let info = + if isArray then + let fixedIndex3d4dEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.FixedIndexSlice3d4d + let indexArgs = List.map DecodeIndexArg indexArgs + match indexArgs, setInfo with + | [IndexArgItem _; IndexArgItem _], None -> Some (indexOpPath, "GetArray2D", expandedIndexArgs) + | [IndexArgItem _; IndexArgItem _; IndexArgItem _;], None -> Some (indexOpPath, "GetArray3D", expandedIndexArgs) + | [IndexArgItem _; IndexArgItem _; IndexArgItem _; IndexArgItem _], None -> Some (indexOpPath, "GetArray4D", expandedIndexArgs) + | [IndexArgItem _], None -> Some (indexOpPath, "GetArray", expandedIndexArgs) + | [IndexArgItem _; IndexArgItem _], Some (e3, _) -> Some (indexOpPath, "SetArray2D", (expandedIndexArgs @ [e3])) + | [IndexArgItem _; IndexArgItem _; IndexArgItem _;], Some (e3, _) -> Some (indexOpPath, "SetArray3D", (expandedIndexArgs @ [e3])) + | [IndexArgItem _; IndexArgItem _; IndexArgItem _; IndexArgItem _], Some (e3, _) -> Some (indexOpPath, "SetArray4D", (expandedIndexArgs @ [e3])) + | [IndexArgItem _], Some (e3, _) -> Some (indexOpPath, "SetArray", (expandedIndexArgs @ [e3])) + | [IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice2DFixed1", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice2DFixed2", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice2D", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice3D", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4D", expandedIndexArgs) + | [IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice2D", (expandedIndexArgs @ [e3])) + | [IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice2DFixed1", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice2DFixed2", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3D", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4D", (expandedIndexArgs @ [e3])) + | _ when fixedIndex3d4dEnabled -> + match indexArgs, setInfo with + | [IndexArgItem _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice3DFixedSingle1", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice3DFixedSingle2", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice3DFixedSingle3", expandedIndexArgs) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice3DFixedDouble1", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice3DFixedDouble2", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice3DFixedDouble3", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedSingle1", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedSingle2", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedSingle3", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedSingle4", expandedIndexArgs) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble1", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble2", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble3", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble4", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble5", expandedIndexArgs) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedDouble6", expandedIndexArgs) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedTriple1", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedTriple2", expandedIndexArgs) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _;IndexArgItem _], None -> Some (sliceOpPath, "GetArraySlice4DFixedTriple3", expandedIndexArgs) + | [IndexArgItem _;IndexArgItem _;IndexArgItem _;IndexArgRange _], None -> Some (sliceOpPath, "GetArraySlice4DFixedTriple4", expandedIndexArgs) + | [IndexArgItem _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle1", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle2", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle3", (expandedIndexArgs @ [e3])) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble1", (expandedIndexArgs @ [e3])) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble2", (expandedIndexArgs @ [e3])) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble3", (expandedIndexArgs @ [e3])) + | [IndexArgItem _;IndexArgRange _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle1", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle2", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle3", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgRange _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle4", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble1", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble2", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgRange _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble3", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble4", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgItem _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble5", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgRange _;IndexArgItem _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble6", expandedIndexArgs @ [e3]) + | [IndexArgRange _;IndexArgItem _;IndexArgItem _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple1", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgRange _;IndexArgItem _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple2", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgItem _;IndexArgRange _;IndexArgItem _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple3", expandedIndexArgs @ [e3]) + | [IndexArgItem _;IndexArgItem _;IndexArgItem _;IndexArgRange _], Some (e3, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple4", expandedIndexArgs @ [e3]) + | _ -> None + | _ -> None + + elif isString then + match List.map DecodeIndexArg indexArgs, setInfo with + | [IndexArgRange _], None -> Some (sliceOpPath, "GetStringSlice", expandedIndexArgs) + | [IndexArgItem _], None -> Some (indexOpPath, "GetString", expandedIndexArgs) + | _ -> None + + else None + + match info with + | None -> None + | Some (path, functionName, indexArgs) -> + let operPath = mkSynLidGet (mDot.MakeSynthetic()) path functionName + let f, fty, tpenv = TcExprOfUnknownType cenv env tpenv operPath + let domainTy, resultTy = UnifyFunctionType (Some mWholeExpr) cenv env.DisplayEnv mWholeExpr fty + UnifyTypes cenv env mWholeExpr domainTy e1ty + let f', resultTy = buildApp cenv (MakeApplicableExprNoFlex cenv f) resultTy expr mWholeExpr + let delayed = List.foldBack (fun idx acc -> DelayedApp(ExprAtomicFlag.Atomic, true, None, idx, mWholeExpr) :: acc) indexArgs delayed // atomic, otherwise no ar.[1] <- xyz + Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed ) + + match attemptArrayString with + | Some res -> res + | None when isNominal || Option.isSome propName -> + let nm = + match propName with + | None -> "Item" + | Some nm -> nm + let delayed = + match setInfo with + // e1.[e2] + | None -> + [ DelayedDotLookup([ ident(nm, mWholeExpr)], mWholeExpr) + DelayedApp(ExprAtomicFlag.Atomic, true, synLeftExprOpt, MakeIndexParam None, mWholeExpr) + yield! delayed ] + // e1.[e2] <- e3 --> e1.Item(e2) <- e3 + | Some (e3, mOfLeftOfSet) -> + if isIndex then + [ DelayedDotLookup([ident(nm, mOfLeftOfSet)], mOfLeftOfSet) + DelayedApp(ExprAtomicFlag.Atomic, true, synLeftExprOpt, MakeIndexParam None, mOfLeftOfSet) + MakeDelayedSet(e3, mWholeExpr) + yield! delayed ] + else + [ DelayedDotLookup([ident("SetSlice", mOfLeftOfSet)], mOfLeftOfSet) + DelayedApp(ExprAtomicFlag.Atomic, true, synLeftExprOpt, MakeIndexParam (Some e3), mWholeExpr) + yield! delayed ] + + PropagateThenTcDelayed cenv overallTy env tpenv mDot (MakeApplicableExprNoFlex cenv expr) e1ty ExprAtomicFlag.Atomic delayed + + | _ -> + // deprecated constrained lookup + error(Error(FSComp.SR.tcObjectOfIndeterminateTypeUsedRequireTypeConstraint(), mWholeExpr)) + + +/// Check a 'new Type(args)' expression, also an 'inheritedTys declaration in an implicit or explicit class +/// For 'new Type(args)', mWholeExprOrObjTy is the whole expression +/// For 'inherit Type(args)', mWholeExprOrObjTy is the whole expression +/// For an implicit inherit from System.Object or a default constructor, mWholeExprOrObjTy is the type name of the type being defined +and TcNewExpr cenv env tpenv objTy mObjTyOpt superInit arg mWholeExprOrObjTy = + let ad = env.AccessRights + // Handle the case 'new 'a()' + if (isTyparTy cenv.g objTy) then + if superInit then error(Error(FSComp.SR.tcCannotInheritFromVariableType(), mWholeExprOrObjTy)) + AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css mWholeExprOrObjTy NoTrace objTy + + match arg with + | SynExpr.Const (SynConst.Unit, _) -> () + | _ -> errorR(Error(FSComp.SR.tcObjectConstructorsOnTypeParametersCannotTakeArguments(), mWholeExprOrObjTy)) + + mkCallCreateInstance cenv.g mWholeExprOrObjTy objTy, tpenv + else + if not (isAppTy cenv.g objTy) && not (isAnyTupleTy cenv.g objTy) then error(Error(FSComp.SR.tcNamedTypeRequired(if superInit then "inherit" else "new"), mWholeExprOrObjTy)) + let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mWholeExprOrObjTy ad objTy) + + TcCtorCall false cenv env tpenv (MustEqual objTy) objTy mObjTyOpt item superInit [arg] mWholeExprOrObjTy [] None + +/// Check an 'inheritedTys declaration in an implicit or explicit class +and TcCtorCall isNaked cenv env tpenv (overallTy: OverallTy) objTy mObjTyOpt item superInit args mWholeCall delayed afterTcOverloadResolutionOpt = + let ad = env.AccessRights + let isSuperInit = (if superInit then CtorValUsedAsSuperInit else NormalValUse) + let mItem = match mObjTyOpt with Some m -> m | None -> mWholeCall + + if isInterfaceTy cenv.g objTy then + error(Error((if superInit then FSComp.SR.tcInheritCannotBeUsedOnInterfaceType() else FSComp.SR.tcNewCannotBeUsedOnInterfaceType()), mWholeCall)) + + match item, args with + | Item.CtorGroup(methodName, minfos), _ -> + let meths = List.map (fun minfo -> minfo, None) minfos + if isNaked && TypeFeasiblySubsumesType 0 cenv.g cenv.amap mWholeCall cenv.g.system_IDisposable_ty NoCoerce objTy then + warning(Error(FSComp.SR.tcIDisposableTypeShouldUseNew(), mWholeCall)) + + // Check the type is not abstract + // skip this check if this ctor call is either 'inherit(...)' or call is located within constructor shape + if not (superInit || AreWithinCtorShape env) + then CheckSuperInit cenv objTy mWholeCall + + let afterResolution = + match mObjTyOpt, afterTcOverloadResolutionOpt with + | _, Some action -> action + | Some mObjTy, None -> ForNewConstructors cenv.tcSink env mObjTy methodName minfos + | None, _ -> AfterResolution.DoNothing + + TcMethodApplicationThen cenv env overallTy (Some objTy) tpenv None [] mWholeCall mItem methodName ad PossiblyMutates false meths afterResolution isSuperInit args ExprAtomicFlag.NonAtomic delayed + + | Item.DelegateCtor ty, [arg] -> + // Re-record the name resolution since we now know it's a constructor call + match mObjTyOpt with + | Some mObjTy -> CallNameResolutionSink cenv.tcSink (mObjTy, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) + | None -> () + TcNewDelegateThen cenv (MustEqual objTy) env tpenv mItem mWholeCall ty arg ExprAtomicFlag.NonAtomic delayed + + | _ -> + error(Error(FSComp.SR.tcSyntaxCanOnlyBeUsedToCreateObjectTypes(if superInit then "inherit" else "new"), mWholeCall)) + +// Check a record construction expression +and TcRecordConstruction cenv (overallTy: TType) env tpenv optOrigExprInfo objTy fldsList m = + let tcref, tinst = destAppTy cenv.g objTy + let tycon = tcref.Deref + UnifyTypes cenv env m overallTy objTy + + // Types with implicit constructors can't use record or object syntax: all constructions must go through the implicit constructor + if tycon.MembersOfFSharpTyconByName |> NameMultiMap.existsInRange (fun v -> v.IsIncrClassConstructor) then + errorR(Error(FSComp.SR.tcConstructorRequiresCall(tycon.DisplayName), m)) + + let fspecs = tycon.TrueInstanceFieldsAsList + // Freshen types and work out their subtype flexibility + let fldsList = + [ for fname, fexpr in fldsList do + let fspec = + try + fspecs |> List.find (fun fspec -> fspec.LogicalName = fname) + with :? KeyNotFoundException -> + error (Error(FSComp.SR.tcUndefinedField(fname, NicePrint.minimalStringOfType env.DisplayEnv objTy), m)) + let fty = actualTyOfRecdFieldForTycon tycon tinst fspec + let flex = not (isTyparTy cenv.g fty) + yield (fname, fexpr, fty, flex) ] + + // Type check and generalize the supplied bindings + let fldsList, tpenv = + let env = { env with eContextInfo = ContextInfo.RecordFields } + (tpenv, fldsList) ||> List.mapFold (fun tpenv (fname, fexpr, fty, flex) -> + let fieldExpr, tpenv = TcExprFlex cenv flex false fty env tpenv fexpr + (fname, fieldExpr), tpenv) + + // Add rebindings for unbound field when an "old value" is available + // Effect order: mutable fields may get modified by other bindings... + let oldFldsList = + match optOrigExprInfo with + | None -> [] + | Some (_, _, oldvaddre) -> + let fieldNameUnbound nom = List.forall (fun (name, _) -> name <> nom) fldsList + let flds = + fspecs |> List.choose (fun rfld -> + if fieldNameUnbound rfld.LogicalName && not rfld.IsZeroInit + then Some(rfld.LogicalName, mkRecdFieldGetViaExprAddr (oldvaddre, tcref.MakeNestedRecdFieldRef rfld, tinst, m)) + else None) + flds + + let fldsList = fldsList @ oldFldsList + + // From now on only interested in fspecs that truly need values. + let fspecs = fspecs |> List.filter (fun f -> not f.IsZeroInit) + + // Check all fields are bound + fspecs |> List.iter (fun fspec -> + if not (fldsList |> List.exists (fun (fname, _) -> fname = fspec.LogicalName)) then + error(Error(FSComp.SR.tcFieldRequiresAssignment(fspec.rfield_id.idText, fullDisplayTextOfTyconRef tcref), m))) + + // Other checks (overlap with above check now clear) + let ns1 = NameSet.ofList (List.map fst fldsList) + let ns2 = NameSet.ofList (List.map (fun x -> x.rfield_id.idText) fspecs) + + if optOrigExprInfo.IsNone && not (Zset.subset ns2 ns1) then + error (MissingFields(Zset.elements (Zset.diff ns2 ns1), m)) + + if not (Zset.subset ns1 ns2) then + error (Error(FSComp.SR.tcExtraneousFieldsGivenValues(), m)) + + // Build record + let rfrefs = List.map (fst >> mkRecdFieldRef tcref) fldsList + + // Check accessibility: this is also done in BuildFieldMap, but also need to check + // for fields in { new R with a=1 and b=2 } constructions and { r with a=1 } copy-and-update expressions + rfrefs |> List.iter (fun rfref -> + CheckRecdFieldAccessible cenv.amap m env.eAccessRights rfref |> ignore + CheckFSharpAttributes cenv.g rfref.PropertyAttribs m |> CommitOperationResult) + + let args = List.map snd fldsList + + let expr = mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m) + + let expr = + match optOrigExprInfo with + | None -> + // '{ recd fields }'. // + expr + + | Some (old, oldvaddr, _) -> + // '{ recd with fields }'. + // Assign the first object to a tmp and then construct + let wrap, oldaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates old None m + wrap (mkCompGenLet m oldvaddr oldaddr expr) + + expr, tpenv + +//------------------------------------------------------------------------- +// TcObjectExpr +//------------------------------------------------------------------------- + +and GetNameAndArityOfObjExprBinding _cenv _env b = + let (NormalizedBinding (_, _, _, _, _, _, _, valSynData, pat, rhsExpr, mBinding, _)) = b + let (SynValData(memberFlagsOpt, valSynInfo, _)) = valSynData + match pat, memberFlagsOpt with + + // This is the normal case for F# 'with member x.M(...) = ...' + | SynPat.InstanceMember(_thisId, memberId, _, None, _), Some memberFlags -> + let logicalMethId = ident (ComputeLogicalName memberId memberFlags, memberId.idRange) + logicalMethId.idText, valSynInfo + + | _ -> + // This is for the deprecated form 'with M(...) = ...' + let rec lookPat pat = + match pat with + | SynPat.Typed(pat, _, _) -> lookPat pat + | SynPat.FromParseError(pat, _) -> lookPat pat + | SynPat.Named (id, _, None, _) -> + let (NormalizedBindingRhs(pushedPats, _, _)) = rhsExpr + let infosForExplicitArgs = pushedPats |> List.map SynInfo.InferSynArgInfoFromSimplePats + let infosForExplicitArgs = SynInfo.AdjustMemberArgs SynMemberKind.Member infosForExplicitArgs + let infosForExplicitArgs = SynInfo.AdjustArgsForUnitElimination infosForExplicitArgs + let argInfos = [SynInfo.selfMetadata] @ infosForExplicitArgs + let retInfo = SynInfo.unnamedRetVal //SynInfo.InferSynReturnData pushedRetInfoOpt + let valSynData = SynValInfo(argInfos, retInfo) + (id.idText, valSynData) + | _ -> error(Error(FSComp.SR.tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual(), mBinding)) + + lookPat pat + + +and FreshenObjExprAbstractSlot cenv (env: TcEnv) (implty: TType) virtNameAndArityPairs (bind, bindAttribs, bindName, absSlots:(_ * MethInfo) list) = + let (NormalizedBinding (_, _, _, _, _, _, synTyparDecls, _, _, _, mBinding, _)) = bind + match absSlots with + | [] when not (CompileAsEvent cenv.g bindAttribs) -> + let absSlotsByName = List.filter (fst >> fst >> (=) bindName) virtNameAndArityPairs + let getSignature absSlot = (NicePrint.stringOfMethInfo cenv.infoReader mBinding env.DisplayEnv absSlot).Replace("abstract ", "") + let getDetails (absSlot: MethInfo) = + if absSlot.GetParamTypes(cenv.amap, mBinding, []) |> List.existsSquared (isAnyTupleTy cenv.g) then + FSComp.SR.tupleRequiredInAbstractMethod() + else "" + + // Compute the argument counts of the member arguments + let _, synValInfo = GetNameAndArityOfObjExprBinding cenv env bind + let arity = + match SynInfo.AritiesOfArgs synValInfo with + | _ :: x :: _ -> x + | _ -> 0 + + match absSlotsByName with + | [] -> + let tcref = tcrefOfAppTy cenv.g implty + let containsNonAbstractMemberWithSameName = + tcref.MembersOfFSharpTyconByName + |> Seq.exists (fun kv -> kv.Value |> List.exists (fun valRef -> valRef.DisplayName = bindName)) + + let suggestVirtualMembers (addToBuffer: string -> unit) = + for (x,_),_ in virtNameAndArityPairs do + addToBuffer x + + if containsNonAbstractMemberWithSameName then + errorR(ErrorWithSuggestions(FSComp.SR.tcMemberFoundIsNotAbstractOrVirtual(tcref.DisplayName, bindName), mBinding, bindName, suggestVirtualMembers)) + else + errorR(ErrorWithSuggestions(FSComp.SR.tcNoAbstractOrVirtualMemberFound bindName, mBinding, bindName, suggestVirtualMembers)) + | [(_, absSlot: MethInfo)] -> + errorR(Error(FSComp.SR.tcArgumentArityMismatch(bindName, List.sum absSlot.NumArgs, arity, getSignature absSlot, getDetails absSlot), mBinding)) + | (_, absSlot: MethInfo) :: _ -> + errorR(Error(FSComp.SR.tcArgumentArityMismatchOneOverload(bindName, List.sum absSlot.NumArgs, arity, getSignature absSlot, getDetails absSlot), mBinding)) + + None + + | [(_, absSlot)] -> + + let typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot + = FreshenAbstractSlot cenv.g cenv.amap mBinding synTyparDecls absSlot + + // Work out the required type of the member + let bindingTy = implty --> (mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot) + + Some(typarsFromAbsSlotAreRigid, typarsFromAbsSlot, bindingTy) + + | _ -> + None + + +and TcObjectExprBinding cenv (env: TcEnv) implty tpenv (absSlotInfo, bind) = + // 4a1. normalize the binding (note: needlessly repeating what we've done above) + let (NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc, synTyparDecls, valSynData, p, bindingRhs, mBinding, spBind)) = bind + let (SynValData(memberFlagsOpt, _, _)) = valSynData + // 4a2. adjust the binding, especially in the "member" case, a subset of the logic of AnalyzeAndMakeAndPublishRecursiveValue + let bindingRhs, logicalMethId, memberFlags = + let rec lookPat p = + match p, memberFlagsOpt with + | SynPat.FromParseError(pat, _), _ -> lookPat pat + | SynPat.Named (id, _, _, _), None -> + let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar (ident (CompilerGeneratedName "this", id.idRange))) bindingRhs + let logicalMethId = id + let memberFlags = OverrideMemberFlags SynMemberKind.Member + bindingRhs, logicalMethId, memberFlags + + | SynPat.InstanceMember(thisId, memberId, _, _, _), Some memberFlags -> + CheckMemberFlags None NewSlotsOK OverridesOK memberFlags mBinding + let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar thisId) bindingRhs + let logicalMethId = ident (ComputeLogicalName memberId memberFlags, memberId.idRange) + bindingRhs, logicalMethId, memberFlags + | _ -> + error(InternalError("unexpected member binding", mBinding)) + lookPat p + let bind = NormalizedBinding (vis, bkind, isInline, isMutable, attrs, doc, synTyparDecls, valSynData, mkSynPatVar vis logicalMethId, bindingRhs, mBinding, spBind) + + // 4b. typecheck the binding + let bindingTy = + match absSlotInfo with + | Some(_, _, memberTyFromAbsSlot) -> + memberTyFromAbsSlot + | _ -> + implty --> NewInferenceType () + + let CheckedBindingInfo(inlineFlag, bindingAttribs, _, _, ExplicitTyparInfo(_, declaredTypars, _), nameToPrelimValSchemeMap, rhsExpr, _, _, m, _, _, _, _), tpenv = + let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv bind + TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], explicitTyparInfo) bind + + // 4c. generalize the binding - only relevant when implementing a generic virtual method + + match NameMap.range nameToPrelimValSchemeMap with + | [PrelimValScheme1(id, _, _, _, _, _, _, _, _, _, _)] -> + let denv = env.DisplayEnv + + let declaredTypars = + match absSlotInfo with + | Some(typarsFromAbsSlotAreRigid, typarsFromAbsSlot, _) -> + if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars + | _ -> + declaredTypars + // Canonicalize constraints prior to generalization + CanonicalizePartialInferenceProblem cenv.css denv m declaredTypars + + let freeInEnv = GeneralizationHelpers.ComputeUngeneralizableTypars env + + let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv, denv, m, freeInEnv, false, CanGeneralizeConstrainedTypars, inlineFlag, Some rhsExpr, declaredTypars, [], bindingTy, false) + let declaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g env.DisplayEnv declaredTypars m + + let generalizedTypars = PlaceTyparsInDeclarationOrder declaredTypars generalizedTypars + + (id, memberFlags, (generalizedTypars +-> bindingTy), bindingAttribs, rhsExpr), tpenv + | _ -> + error(Error(FSComp.SR.tcSimpleMethodNameRequired(), m)) + +and ComputeObjectExprOverrides cenv (env: TcEnv) tpenv impls = + + // Compute the method sets each implemented type needs to implement + let slotImplSets = DispatchSlotChecking.GetSlotImplSets cenv.infoReader env.DisplayEnv env.AccessRights true (impls |> List.map (fun (m, ty, _) -> ty, m)) + + let allImpls = + (impls, slotImplSets) ||> List.map2 (fun (m, ty, binds) implTySet -> + let binds = binds |> List.map (BindingNormalization.NormalizeBinding ObjExprBinding cenv env) + m, ty, binds, implTySet) + + let overridesAndVirts, tpenv = + (tpenv, allImpls) ||> List.mapFold (fun tpenv (m, implty, binds, SlotImplSet(reqdSlots, dispatchSlotsKeyed, availPriorOverrides, _) ) -> + + // Generate extra bindings fo object expressions with bindings using the CLIEvent attribute + let binds, bindsAttributes = + [ for binding in binds do + let (NormalizedBinding(_, _, _, _, bindingSynAttribs, _, _, valSynData, _, _, _, _)) = binding + let (SynValData(memberFlagsOpt, _, _)) = valSynData + let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt ObjectExpressionOverrideBinding + let bindingAttribs = TcAttributes cenv env attrTgt bindingSynAttribs + yield binding, bindingAttribs + for extraBinding in EventDeclarationNormalization.GenerateExtraBindings cenv (bindingAttribs, binding) do + yield extraBinding, [] ] + |> List.unzip + + // 2. collect all name/arity of all overrides + let dispatchSlots = reqdSlots |> List.map (fun reqdSlot -> reqdSlot.MethodInfo) + let virtNameAndArityPairs = dispatchSlots |> List.map (fun virt -> + let vkey = (virt.LogicalName, virt.NumArgs) + //dprintfn "vkey = %A" vkey + (vkey, virt)) + let bindNameAndSynInfoPairs = binds |> List.map (GetNameAndArityOfObjExprBinding cenv env) + let bindNames = bindNameAndSynInfoPairs |> List.map fst + let bindKeys = + bindNameAndSynInfoPairs |> List.map (fun (name, valSynData) -> + // Compute the argument counts of the member arguments + let argCounts = (SynInfo.AritiesOfArgs valSynData).Tail + //dprintfn "name = %A, argCounts = %A" name argCounts + (name, argCounts)) + + // 3. infer must-have types by name/arity + let preAssignedVirtsPerBinding = + bindKeys |> List.map (fun bkey -> List.filter (fst >> (=) bkey) virtNameAndArityPairs) + + let absSlotInfo = + (List.zip4 binds bindsAttributes bindNames preAssignedVirtsPerBinding) + |> List.map (FreshenObjExprAbstractSlot cenv env implty virtNameAndArityPairs) + + // 4. typecheck/typeinfer/generalizer overrides using this information + let overrides, tpenv = (tpenv, List.zip absSlotInfo binds) ||> List.mapFold (TcObjectExprBinding cenv env implty) + + // Convert the syntactic info to actual info + let overrides = + (overrides, bindNameAndSynInfoPairs) ||> List.map2 (fun (id: Ident, memberFlags, ty, bindingAttribs, bindingBody) (_, valSynData) -> + let partialValInfo = TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynData + let tps, _ = tryDestForallTy cenv.g ty + let valInfo = TranslatePartialArity tps partialValInfo + DispatchSlotChecking.GetObjectExprOverrideInfo cenv.g cenv.amap (implty, id, memberFlags, ty, valInfo, bindingAttribs, bindingBody)) + + (m, implty, reqdSlots, dispatchSlotsKeyed, availPriorOverrides, overrides), tpenv) + + overridesAndVirts, tpenv + +and CheckSuperType cenv ty m = + if typeEquiv cenv.g ty cenv.g.system_Value_ty || + typeEquiv cenv.g ty cenv.g.system_Enum_ty || + typeEquiv cenv.g ty cenv.g.system_Array_ty || + typeEquiv cenv.g ty cenv.g.system_MulticastDelegate_ty || + typeEquiv cenv.g ty cenv.g.system_Delegate_ty then + error(Error(FSComp.SR.tcPredefinedTypeCannotBeUsedAsSuperType(), m)) + if isErasedType cenv.g ty then + errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) + + +and TcObjectExpr cenv env tpenv (objTy, realObjTy, argopt, binds, extraImpls, mObjTy, mNewExpr, mWholeExpr) = + + match tryTcrefOfAppTy cenv.g objTy with + | ValueNone -> error(Error(FSComp.SR.tcNewMustBeUsedWithNamedType(), mNewExpr)) + | ValueSome tcref -> + let isRecordTy = tcref.IsRecordTycon + if not isRecordTy && not (isInterfaceTy cenv.g objTy) && isSealedTy cenv.g objTy then errorR(Error(FSComp.SR.tcCannotCreateExtensionOfSealedType(), mNewExpr)) + + CheckSuperType cenv objTy mObjTy + + // Add the object type to the ungeneralizable items + let env = {env with eUngeneralizableItems = addFreeItemOfTy objTy env.eUngeneralizableItems } + + // Object expression members can access protected members of the implemented type + let env = EnterFamilyRegion tcref env + let ad = env.AccessRights + + if // record construction ? + isRecordTy || + // object construction? + (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && argopt.IsNone) then + + if argopt.IsSome then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(), mWholeExpr)) + if not (isNil extraImpls) then error(Error(FSComp.SR.tcNoInterfaceImplementationForConstructionExpression(), mNewExpr)) + if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env <> 1 then + error(Error(FSComp.SR.tcObjectConstructionCanOnlyBeUsedInClassTypes(), mNewExpr)) + let fldsList = + binds |> List.map (fun b -> + match BindingNormalization.NormalizeBinding ObjExprBinding cenv env b with + | NormalizedBinding (_, _, _, _, [], _, _, _, SynPat.Named(id, _, _, _), NormalizedBindingRhs(_, _, rhsExpr), _, _) -> id.idText, rhsExpr + | _ -> error(Error(FSComp.SR.tcOnlySimpleBindingsCanBeUsedInConstructionExpressions(), b.RangeOfBindingWithoutRhs))) + + TcRecordConstruction cenv objTy env tpenv None objTy fldsList mWholeExpr + else + let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy) + + if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env = 1 then + error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr)) + + let ctorCall, baseIdOpt, tpenv = + match item, argopt with + | Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) -> + let meths = minfos |> List.map (fun minfo -> minfo, None) + let afterResolution = ForNewConstructors cenv.tcSink env mObjTy methodName minfos + let ad = env.AccessRights + + let expr, tpenv = TcMethodApplicationThen cenv env (MustEqual objTy) None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic [] + // The 'base' value is always bound + let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id) + expr, baseIdOpt, tpenv + | Item.FakeInterfaceCtor intfTy, None -> + UnifyTypes cenv env mWholeExpr objTy intfTy + let expr = BuildObjCtorCall cenv.g mWholeExpr + expr, None, tpenv + | Item.FakeInterfaceCtor _, Some _ -> + error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr)) + | Item.CtorGroup _, None -> + error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr)) + | _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr)) + + let baseValOpt = MakeAndPublishBaseVal cenv env baseIdOpt objTy + let env = Option.foldBack (AddLocalVal cenv.g cenv.tcSink mNewExpr) baseValOpt env + let impls = (mWholeExpr, objTy, binds) :: extraImpls + + // 1. collect all the relevant abstract slots for each type we have to implement + + let overridesAndVirts, tpenv = ComputeObjectExprOverrides cenv env tpenv impls + + // 2. check usage conditions + overridesAndVirts |> List.iter (fun (m, implty, dispatchSlots, dispatchSlotsKeyed, availPriorOverrides, overrides) -> + let overrideSpecs = overrides |> List.map fst + + DispatchSlotChecking.CheckOverridesAreAllUsedOnce (env.DisplayEnv, cenv.g, cenv.infoReader, true, implty, dispatchSlotsKeyed, availPriorOverrides, overrideSpecs) + + DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.infoReader, m, env.NameEnv, cenv.tcSink, false, implty, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) + + // 3. create the specs of overrides + let allTypeImpls = + overridesAndVirts |> List.map (fun (m, implty, _, dispatchSlotsKeyed, _, overrides) -> + let overrides' = + [ for overrideMeth in overrides do + let Override(_, _, id, (mtps, _), _, _, isFakeEventProperty, _) as ovinfo, (_, thisVal, methodVars, bindingAttribs, bindingBody) = overrideMeth + if not isFakeEventProperty then + let searchForOverride = + dispatchSlotsKeyed + |> NameMultiMap.find id.idText + |> List.tryPick (fun reqdSlot -> + let virt = reqdSlot.MethodInfo + if DispatchSlotChecking.IsExactMatch cenv.g cenv.amap m virt ovinfo then + Some virt + else + None) + + let overridden = + match searchForOverride with + | Some x -> x + | None -> error(Error(FSComp.SR.tcAtLeastOneOverrideIsInvalid(), mObjTy)) + + yield TObjExprMethod(overridden.GetSlotSig(cenv.amap, m), bindingAttribs, mtps, [thisVal] :: methodVars, bindingBody, id.idRange) ] + (implty, overrides')) + + let objTy', overrides' = allTypeImpls.Head + assert (typeEquiv cenv.g objTy objTy') + let extraImpls = allTypeImpls.Tail + + // 7. Build the implementation + let expr = mkObjExpr(objTy', baseValOpt, ctorCall, overrides', extraImpls, mWholeExpr) + let expr = mkCoerceIfNeeded cenv.g realObjTy objTy' expr + expr, tpenv + +//------------------------------------------------------------------------- +// TcConstStringExpr +//------------------------------------------------------------------------- + +/// Check a constant string expression. It might be a 'printf' format string +and TcConstStringExpr cenv (overallTy: OverallTy) env m tpenv s = + + if (AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit cenv.g.string_ty) then + mkString cenv.g m s, tpenv + else + TcFormatStringExpr cenv overallTy env m tpenv s + +and TcFormatStringExpr cenv (overallTy: OverallTy) env m tpenv (fmtString: string) = + let g = cenv.g + let aty = NewInferenceType () + let bty = NewInferenceType () + let cty = NewInferenceType () + let dty = NewInferenceType () + let ety = NewInferenceType () + let formatTy = mkPrintfFormatTy g aty bty cty dty ety + + // This might qualify as a format string - check via a type directed rule + let ok = not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy + + if ok then + // Parse the format string to work out the phantom types + let formatStringCheckContext = match cenv.tcSink.CurrentSink with None -> None | Some sink -> sink.FormatStringCheckContext + let normalizedString = (fmtString.Replace("\r\n", "\n").Replace("\r", "\n")) + + let _argTys, atyRequired, etyRequired, _percentATys, specifierLocations, _dotnetFormatString = + try CheckFormatStrings.ParseFormatString m [m] g false false formatStringCheckContext normalizedString bty cty dty + with Failure errString -> error (Error(FSComp.SR.tcUnableToParseFormatString errString, m)) + + match cenv.tcSink.CurrentSink with + | None -> () + | Some sink -> + for specifierLocation, numArgs in specifierLocations do + sink.NotifyFormatSpecifierLocation(specifierLocation, numArgs) + + UnifyTypes cenv env m aty atyRequired + UnifyTypes cenv env m ety etyRequired + let fmtExpr = mkCallNewFormat g m aty bty cty dty ety (mkString g m fmtString) + fmtExpr, tpenv + + else + TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env (* true *) m (fun () -> + mkString g m fmtString, tpenv + ) + +/// Check an interpolated string expression +and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: SynInterpolatedStringPart list) = + let g = cenv.g + + let synFillExprs = + parts + |> List.choose (function + | SynInterpolatedStringPart.String _ -> None + | SynInterpolatedStringPart.FillExpr (fillExpr, _) -> + match fillExpr with + // Detect "x" part of "...{x,3}..." + | SynExpr.Tuple (false, [e; SynExpr.Const (SynConst.Int32 _align, _)], _, _) -> Some e + | e -> Some e) + + let stringFragmentRanges = + parts + |> List.choose (function + | SynInterpolatedStringPart.String (_,m) -> Some m + | SynInterpolatedStringPart.FillExpr _ -> None) + + let printerTy = NewInferenceType () + let printerArgTy = NewInferenceType () + let printerResidueTy = NewInferenceType () + let printerResultTy = NewInferenceType () + let printerTupleTy = NewInferenceType () + let formatTy = mkPrintfFormatTy g printerTy printerArgTy printerResidueTy printerResultTy printerTupleTy + + // Check the library support is available in the referenced FSharp.Core + let newFormatMethod = + match GetIntrinsicConstructorInfosOfType cenv.infoReader m formatTy |> List.filter (fun minfo -> minfo.NumArgs = [3]) with + | [ctorInfo] -> ctorInfo + | _ -> languageFeatureNotSupportedInLibraryError cenv.g.langVersion LanguageFeature.StringInterpolation m + + let stringKind = + // If this is an interpolated string then try to force the result to be a string + if (AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.string_ty) then + + // And if that succeeds, the result of printing is a string + UnifyTypes cenv env m printerArgTy g.unit_ty + UnifyTypes cenv env m printerResidueTy g.string_ty + UnifyTypes cenv env m printerResultTy overallTy.Commit + + // And if that succeeds, the printerTy and printerResultTy must be the same (there are no curried arguments) + UnifyTypes cenv env m printerTy printerResultTy + + Choice1Of2 (true, newFormatMethod) + + // ... or if that fails then may be a FormattableString by a type-directed rule.... + elif (not (isObjTy g overallTy.Commit) && + ((g.system_FormattableString_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_FormattableString_ty) + || (g.system_IFormattable_tcref.CanDeref && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit g.system_IFormattable_ty))) then + + // And if that succeeds, the result of printing is a string + UnifyTypes cenv env m printerArgTy g.unit_ty + UnifyTypes cenv env m printerResidueTy g.string_ty + UnifyTypes cenv env m printerResultTy overallTy.Commit + + // Find the FormattableStringFactor.Create method in the .NET libraries + let ad = env.eAccessRights + let createMethodOpt = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Create" g.system_FormattableStringFactory_ty with + | [x] -> Some x + | _ -> None + + match createMethodOpt with + | Some createMethod -> Choice2Of2 createMethod + | None -> languageFeatureNotSupportedInLibraryError cenv.g.langVersion LanguageFeature.StringInterpolation m + + // ... or if that fails then may be a PrintfFormat by a type-directed rule.... + elif not (isObjTy g overallTy.Commit) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy.Commit formatTy then + + // And if that succeeds, the printerTy and printerResultTy must be the same (there are no curried arguments) + UnifyTypes cenv env m printerTy printerResultTy + Choice1Of2 (false, newFormatMethod) + + else + Choice1Of2 (true, newFormatMethod) + + let isFormattableString = (match stringKind with Choice2Of2 _ -> true | _ -> false) + + // The format string used for checking in CheckFormatStrings. This replaces interpolation holes with %P + let printfFormatString = + parts + |> List.map (function + | SynInterpolatedStringPart.String (s, _) -> s + | SynInterpolatedStringPart.FillExpr (fillExpr, format) -> + let alignText = + match fillExpr with + // Validate and detect ",3" part of "...{x,3}..." + | SynExpr.Tuple (false, args, _, _) -> + match args with + | [_; SynExpr.Const (SynConst.Int32 align, _)] -> string align + | _ -> errorR(Error(FSComp.SR.tcInvalidAlignmentInInterpolatedString(), m)); "" + | _ -> "" + let formatText = match format with None -> "()" | Some n -> "(" + n.idText + ")" + "%" + alignText + "P" + formatText ) + |> String.concat "" + + // Parse the format string to work out the phantom types and check for absence of '%' specifiers in FormattableString + // + // If FormatStringCheckContext is set (i.e. we are doing foreground checking in the IDE) + // then we check the string twice, once to collect % positions and once to get errors. + // The process of getting % positions doesn't process the string in a semantically accurate way + // (but is enough to report % locations correctly), as it fetched the pieces from the + // original source and this may include some additional characters, + // and also doesn't raise all necessary errors + match cenv.tcSink.CurrentSink with + | Some sink when sink.FormatStringCheckContext.IsSome -> + try + let _argTys, _printerTy, _printerTupleTyRequired, _percentATys, specifierLocations, _dotnetFormatString = + CheckFormatStrings.ParseFormatString m stringFragmentRanges g true isFormattableString sink.FormatStringCheckContext printfFormatString printerArgTy printerResidueTy printerResultTy + for specifierLocation, numArgs in specifierLocations do + sink.NotifyFormatSpecifierLocation(specifierLocation, numArgs) + with _err-> + () + | _ -> () + + let argTys, _printerTy, printerTupleTyRequired, percentATys, _specifierLocations, dotnetFormatString = + try + CheckFormatStrings.ParseFormatString m stringFragmentRanges g true isFormattableString None printfFormatString printerArgTy printerResidueTy printerResultTy + with Failure errString -> + error (Error(FSComp.SR.tcUnableToParseInterpolatedString errString, m)) + + // Check the expressions filling the holes + if argTys.Length <> synFillExprs.Length then + error (Error(FSComp.SR.tcInterpolationMixedWithPercent(), m)) + + match stringKind with + + // The case for $"..." used as type string and $"...%d{x}..." used as type PrintfFormat - create a PrintfFormat that captures + // is arguments + | Choice1Of2 (isString, newFormatMethod) -> + + UnifyTypes cenv env m printerTupleTy printerTupleTyRequired + + // Type check the expressions filling the holes + + if List.isEmpty synFillExprs then + let str = mkString g m printfFormatString + + if isString then + str, tpenv + else + mkCallNewFormat cenv.g m printerTy printerArgTy printerResidueTy printerResultTy printerTupleTy str, tpenv + else + // Type check the expressions filling the holes + let flexes = argTys |> List.map (fun _ -> false) + let fillExprs, tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys synFillExprs + + let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m) + + let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m) + let percentATysExpr = + if percentATys.Length = 0 then + mkNull m (mkArrayType g g.system_Type_ty) + else + let tyExprs = percentATys |> Array.map (mkCallTypeOf g m) |> Array.toList + mkArray (g.system_Type_ty, tyExprs, m) + + let fmtExpr = MakeMethInfoCall cenv.amap m newFormatMethod [] [mkString g m printfFormatString; argsExpr; percentATysExpr] + + if isString then + TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env (* true *) m (fun () -> + // Make the call to sprintf + mkCall_sprintf g m printerTy fmtExpr [], tpenv + ) + else + fmtExpr, tpenv + + // The case for $"..." used as type FormattableString or IFormattable + | Choice2Of2 createFormattableStringMethod -> + + // Type check the expressions filling the holes + let flexes = argTys |> List.map (fun _ -> false) + let fillExprs, tpenv = TcExprsWithFlexes cenv env m tpenv flexes argTys synFillExprs + + let fillExprsBoxed = (argTys, fillExprs) ||> List.map2 (mkCallBox g m) + + let dotnetFormatStringExpr = mkString g m dotnetFormatString + let argsExpr = mkArray (g.obj_ty, fillExprsBoxed, m) + + // FormattableString are *always* turned into FormattableStringFactory.Create calls, boxing each argument + let createExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false createFormattableStringMethod NormalValUse [] [dotnetFormatStringExpr; argsExpr] [] + + let resultExpr = + if typeEquiv g overallTy.Commit g.system_IFormattable_ty then + mkCoerceIfNeeded g g.system_IFormattable_ty g.system_FormattableString_ty createExpr + else + createExpr + resultExpr, tpenv + +//------------------------------------------------------------------------- +// TcConstExpr +//------------------------------------------------------------------------- + +/// Check a constant expression. +and TcConstExpr cenv (overallTy: OverallTy) env m tpenv c = + match c with + + | SynConst.Bytes (bytes, _, m) -> + let actualTy = mkByteArrayTy cenv.g + TcPropagatingExprLeafThenConvert cenv overallTy actualTy env (* true *) m <| fun ()-> + Expr.Op (TOp.Bytes bytes, [], [], m), tpenv + + | SynConst.UInt16s arr -> + let actualTy = mkArrayType cenv.g cenv.g.uint16_ty + TcPropagatingExprLeafThenConvert cenv overallTy actualTy env (* true *) m <| fun () -> + Expr.Op (TOp.UInt16s arr, [], [], m), tpenv + + | SynConst.UserNum (s, suffix) -> + let expr = + let modName = "NumericLiteral" + suffix + let ad = env.eAccessRights + match ResolveLongIdentAsModuleOrNamespace cenv.tcSink ResultCollectionSettings.AtMostOneResult cenv.amap m true OpenQualified env.eNameResEnv ad (ident (modName, m)) [] false with + | Result [] + | Exception _ -> error(Error(FSComp.SR.tcNumericLiteralRequiresModule modName, m)) + | Result ((_, mref, _) :: _) -> + let expr = + try + match int32 s with + | 0 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromZero", SynExpr.Const (SynConst.Unit, m), m) + | 1 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromOne", SynExpr.Const (SynConst.Unit, m), m) + | i32 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromInt32", SynExpr.Const (SynConst.Int32 i32, m), m) + with _ -> + try + let i64 = int64 s + SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromInt64", SynExpr.Const (SynConst.Int64 i64, m), m) + with _ -> + SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromString", SynExpr.Const (SynConst.String (s, SynStringKind.Regular, m), m), m) + + if suffix <> "I" then + expr + else + match ccuOfTyconRef mref with + | Some ccu when ccuEq ccu cenv.g.fslibCcu -> + SynExpr.Typed (expr, SynType.LongIdent(LongIdentWithDots(pathToSynLid m ["System";"Numerics";"BigInteger"], [])), m) + | _ -> + expr + + TcExpr cenv overallTy env tpenv expr + + | _ -> + TcNonPropagatingExprLeafThenConvert cenv overallTy env m (fun () -> + let cTy = NewInferenceType() + let c' = TcConst cenv cTy m env c + Expr.Const (c', m, cTy), cTy, tpenv) + +//------------------------------------------------------------------------- +// TcAssertExpr +//------------------------------------------------------------------------- + +// Check an 'assert x' expression. +and TcAssertExpr cenv overallTy env (m: range) tpenv x = + let synm = m.MakeSynthetic() // Mark as synthetic so the language service won't pick it up. + let callDiagnosticsExpr = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet synm ["System";"Diagnostics";"Debug"] "Assert", + // wrap an extra parentheses so 'assert(x=1) isn't considered a named argument to a method call + SynExpr.Paren (x, range0, None, synm), synm) + + TcExpr cenv overallTy env tpenv callDiagnosticsExpr + +and TcRecdExpr cenv (overallTy: TType) env tpenv (inherits, optOrigExpr, flds, mWholeExpr) = + + let requiresCtor = (GetCtorShapeCounter env = 1) // Get special expression forms for constructors + let haveCtor = Option.isSome inherits + + let optOrigExpr, tpenv = + match optOrigExpr with + | None -> None, tpenv + | Some (origExpr, _) -> + match inherits with + | Some (_, _, mInherits, _, _) -> error(Error(FSComp.SR.tcInvalidRecordConstruction(), mInherits)) + | None -> + let olde, tpenv = TcExpr cenv (MustEqual overallTy) env tpenv origExpr + Some olde, tpenv + + let hasOrigExpr = optOrigExpr.IsSome + + let fldsList = + let flds = + [ + // if we met at least one field that is not syntactically correct - raise ReportedError to transfer control to the recovery routine + for (lidwd, isOk), v, _ in flds do + if not isOk then + // raising ReportedError None transfers control to the closest errorRecovery point but do not make any records into log + // we assume that parse errors were already reported + raise (ReportedError None) + + yield (List.frontAndBack lidwd.Lid, v) + ] + + match flds with + | [] -> [] + | _ -> + let tinst, tcref, _, fldsList = BuildFieldMap cenv env hasOrigExpr overallTy flds mWholeExpr + let gtyp = mkAppTy tcref tinst + UnifyTypes cenv env mWholeExpr overallTy gtyp + + [ for n, v in fldsList do + match v with + | Some v -> yield n, v + | None -> () ] + + let optOrigExprInfo = + match optOrigExpr with + | None -> None + | Some(olde) -> + let oldvaddr, oldvaddre = mkCompGenLocal mWholeExpr "inputRecord" (if isStructTy cenv.g overallTy then mkByrefTy cenv.g overallTy else overallTy) + Some(olde, oldvaddr, oldvaddre) + + if hasOrigExpr && not (isRecdTy cenv.g overallTy) then + errorR(Error(FSComp.SR.tcExpressionFormRequiresRecordTypes(), mWholeExpr)) + + if requiresCtor || haveCtor then + if not (isFSharpObjModelTy cenv.g overallTy) then + // Deliberate no-recovery failure here to prevent cascading internal errors + error(Error(FSComp.SR.tcInheritedTypeIsNotObjectModelType(), mWholeExpr)) + if not requiresCtor then + errorR(Error(FSComp.SR.tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes(), mWholeExpr)) + else + if isNil flds then + let errorInfo = if hasOrigExpr then FSComp.SR.tcEmptyCopyAndUpdateRecordInvalid() else FSComp.SR.tcEmptyRecordInvalid() + error(Error(errorInfo, mWholeExpr)) + + if isFSharpObjModelTy cenv.g overallTy then errorR(Error(FSComp.SR.tcTypeIsNotARecordTypeNeedConstructor(), mWholeExpr)) + elif not (isRecdTy cenv.g overallTy) then errorR(Error(FSComp.SR.tcTypeIsNotARecordType(), mWholeExpr)) + + let superInitExprOpt , tpenv = + match inherits, GetSuperTypeOfType cenv.g cenv.amap mWholeExpr overallTy with + | Some (superTy, arg, m, _, _), Some realSuperTy -> + // Constructor expression, with an explicit 'inheritedTys clause. Check the inherits clause. + let e, tpenv = TcExpr cenv (MustEqual realSuperTy) env tpenv (SynExpr.New (true, superTy, arg, m)) + Some e, tpenv + | None, Some realSuperTy when requiresCtor -> + // Constructor expression, No 'inherited' clause, hence look for a default constructor + let e, tpenv = TcNewExpr cenv env tpenv realSuperTy None true (SynExpr.Const (SynConst.Unit, mWholeExpr)) mWholeExpr + Some e, tpenv + | None, _ -> + None, tpenv + | _, None -> + errorR(InternalError("Unexpected failure in getting super type", mWholeExpr)) + None, tpenv + + let expr, tpenv = TcRecordConstruction cenv overallTy env tpenv optOrigExprInfo overallTy fldsList mWholeExpr + + let expr = + match superInitExprOpt with + | _ when isStructTy cenv.g overallTy -> expr + | Some superInitExpr -> mkCompGenSequential mWholeExpr superInitExpr expr + | None -> expr + expr, tpenv + + +// Check '{| .... |}' +and TcAnonRecdExpr cenv (overallTy: TType) env tpenv (isStruct, optOrigSynExpr, unsortedFieldIdsAndSynExprsGiven, mWholeExpr) = + let unsortedFieldSynExprsGiven = List.map snd unsortedFieldIdsAndSynExprsGiven + + match optOrigSynExpr with + | None -> + let unsortedFieldIds = unsortedFieldIdsAndSynExprsGiven |> List.map fst |> List.toArray + let anonInfo, sortedFieldTys = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedFieldIds + + // Sort into canonical order + let sortedIndexedArgs = + unsortedFieldIdsAndSynExprsGiven + |> List.indexed + |> List.sortBy (fun (i,_) -> unsortedFieldIds.[i].idText) + + // Map from sorted indexes to unsorted indexes + let sigma = List.map fst sortedIndexedArgs |> List.toArray + let sortedFieldExprs = List.map snd sortedIndexedArgs + + sortedFieldExprs |> List.iteri (fun j (x, _) -> + let item = Item.AnonRecdField(anonInfo, sortedFieldTys, j, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights)) + + let unsortedFieldTys = + sortedFieldTys + |> List.indexed + |> List.sortBy (fun (sortedIdx, _) -> sigma.[sortedIdx]) + |> List.map snd + + let flexes = unsortedFieldTys |> List.map (fun _ -> true) + + let unsortedCheckedArgs, tpenv = TcExprsWithFlexes cenv env mWholeExpr tpenv flexes unsortedFieldTys unsortedFieldSynExprsGiven + + mkAnonRecd cenv.g mWholeExpr anonInfo unsortedFieldIds unsortedCheckedArgs unsortedFieldTys, tpenv + + | Some (origExpr, _) -> + // The fairly complex case '{| origExpr with X = 1; Y = 2 |}' + // The origExpr may be either a record or anonymous record. + // The origExpr may be either a struct or not. + // All the properties of origExpr are copied across except where they are overridden. + // The result is a field-sorted anonymous record. + // + // Unlike in the case of record type copy-and-update we do _not_ assume that the origExpr has the same type as the overall expression. + // Unlike in the case of record type copy-and-update {| a with X = 1 |} does not force a.X to exist or have had type 'int' + + let origExprTy = NewInferenceType() + let origExprChecked, tpenv = TcExpr cenv (MustEqual origExprTy) env tpenv origExpr + let oldv, oldve = mkCompGenLocal mWholeExpr "inputRecord" origExprTy + let mOrigExpr = origExpr.Range + + if not (isAppTy cenv.g origExprTy || isAnonRecdTy cenv.g origExprTy) then + error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) + + let origExprIsStruct = + match tryDestAnonRecdTy cenv.g origExprTy with + | ValueSome (anonInfo, _) -> evalTupInfoIsStruct anonInfo.TupInfo + | ValueNone -> + let tcref, _ = destAppTy cenv.g origExprTy + tcref.IsStructOrEnumTycon + + let wrap, oldveaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g origExprIsStruct false NeverMutates oldve None mOrigExpr + + // Put all the expressions in unsorted order. The new bindings come first. The origin of each is tracked using + /// - Choice1Of2 for a new binding + /// - Choice2Of2 for a binding coming from the original expression + let unsortedIdAndExprsAll = + [| for id, e in unsortedFieldIdsAndSynExprsGiven do + yield (id, Choice1Of2 e) + match tryDestAnonRecdTy cenv.g origExprTy with + | ValueSome (anonInfo, tinst) -> + for i, id in Array.indexed anonInfo.SortedIds do + yield id, Choice2Of2 (mkAnonRecdFieldGetViaExprAddr (anonInfo, oldveaddr, tinst, i, mOrigExpr)) + | ValueNone -> + match tryAppTy cenv.g origExprTy with + | ValueSome(tcref, tinst) when tcref.IsRecordTycon -> + let fspecs = tcref.Deref.TrueInstanceFieldsAsList + for fspec in fspecs do + yield fspec.Id, Choice2Of2 (mkRecdFieldGetViaExprAddr (oldveaddr, tcref.MakeNestedRecdFieldRef fspec, tinst, mOrigExpr)) + | _ -> + error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) |] + |> Array.distinctBy (fst >> textOfId) + + let unsortedFieldIdsAll = Array.map fst unsortedIdAndExprsAll + + let anonInfo, sortedFieldTysAll = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedFieldIdsAll + + let sortedIndexedFieldsAll = unsortedIdAndExprsAll |> Array.indexed |> Array.sortBy (snd >> fst >> textOfId) + + // map from sorted indexes to unsorted indexes + let sigma = Array.map fst sortedIndexedFieldsAll + + let sortedFieldsAll = Array.map snd sortedIndexedFieldsAll + + // Report _all_ identifiers to name resolution. We should likely just report the ones + // that are explicit in source code. + sortedFieldsAll |> Array.iteri (fun j (x, expr) -> + match expr with + | Choice1Of2 _ -> + let item = Item.AnonRecdField(anonInfo, sortedFieldTysAll, j, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + | Choice2Of2 _ -> ()) + + let unsortedFieldTysAll = + sortedFieldTysAll + |> List.indexed + |> List.sortBy (fun (sortedIdx, _) -> sigma.[sortedIdx]) + |> List.map snd + + let unsortedFieldTysGiven = + unsortedFieldTysAll + |> List.take unsortedFieldIdsAndSynExprsGiven.Length + + let flexes = unsortedFieldTysGiven |> List.map (fun _ -> true) + + // Check the expressions in unsorted order + let unsortedFieldExprsGiven, tpenv = + TcExprsWithFlexes cenv env mWholeExpr tpenv flexes unsortedFieldTysGiven unsortedFieldSynExprsGiven + + let unsortedFieldExprsGiven = unsortedFieldExprsGiven |> List.toArray + + let unsortedFieldIds = + unsortedIdAndExprsAll + |> Array.map fst + + let unsortedFieldExprs = + unsortedIdAndExprsAll + |> Array.mapi (fun unsortedIdx (_, expr) -> + match expr with + | Choice1Of2 _ -> unsortedFieldExprsGiven.[unsortedIdx] + | Choice2Of2 subExpr -> UnifyTypes cenv env mOrigExpr (tyOfExpr cenv.g subExpr) unsortedFieldTysAll.[unsortedIdx]; subExpr) + |> List.ofArray + + // Permute the expressions to sorted order in the TAST + let expr = mkAnonRecd cenv.g mWholeExpr anonInfo unsortedFieldIds unsortedFieldExprs unsortedFieldTysAll + let expr = wrap expr + + // Bind the original expression + let expr = mkCompGenLet mOrigExpr oldv origExprChecked expr + expr, tpenv + +and TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, mWholeExpr, spForLoop) = + let tryGetOptimizeSpanMethodsAux g m ty isReadOnlySpan = + match (if isReadOnlySpan then tryDestReadOnlySpanTy g m ty else tryDestSpanTy g m ty) with + | ValueSome(struct(_, destTy)) -> + match TryFindFSharpSignatureInstanceGetterProperty cenv env m "Item" ty [ g.int32_ty; (if isReadOnlySpan then mkInByrefTy g destTy else mkByrefTy g destTy) ], + TryFindFSharpSignatureInstanceGetterProperty cenv env m "Length" ty [ g.int32_ty ] with + | Some(itemPropInfo), Some(lengthPropInfo) -> + ValueSome(struct(itemPropInfo.GetterMethod, lengthPropInfo.GetterMethod, isReadOnlySpan)) + | _ -> + ValueNone + | _ -> + ValueNone + + let tryGetOptimizeSpanMethods g m ty = + let result = tryGetOptimizeSpanMethodsAux g m ty false + if result.IsSome then + result + else + tryGetOptimizeSpanMethodsAux g m ty true + + UnifyTypes cenv env mWholeExpr overallTy.Commit cenv.g.unit_ty + + let mPat = pat.Range + //let mBodyExpr = bodySynExpr.Range + let mEnumExpr = enumSynExpr.Range + let mForLoopStart = match spForLoop with DebugPointAtFor.Yes mStart -> mStart | DebugPointAtFor.No -> mEnumExpr + + // Check the expression being enumerated + let enumExpr, enumExprTy, tpenv = TcExprOfUnknownType cenv env tpenv enumSynExpr + + // Depending on its type we compile it in different ways + let enumElemTy, bodyExprFixup, overallExprFixup, iterationTechnique = + match enumExpr with + + // optimize 'for i in n .. m do' + | Expr.App (Expr.Val (vf, _, _), _, [tyarg], [startExpr;finishExpr], _) + when valRefEq cenv.g vf cenv.g.range_op_vref && typeEquiv cenv.g tyarg cenv.g.int_ty -> + (cenv.g.int32_ty, (fun _ x -> x), id, Choice1Of3 (startExpr, finishExpr)) + + // optimize 'for i in arr do' + | _ when isArray1DTy cenv.g enumExprTy -> + let arrVar, arrExpr = mkCompGenLocal mEnumExpr "arr" enumExprTy + let idxVar, idxExpr = mkCompGenLocal mPat "idx" cenv.g.int32_ty + let elemTy = destArrayTy cenv.g enumExprTy + + // Evaluate the array index lookup + let bodyExprFixup elemVar bodyExpr = mkCompGenLet mForLoopStart elemVar (mkLdelem cenv.g mForLoopStart elemTy arrExpr idxExpr) bodyExpr + + // Evaluate the array expression once and put it in arrVar + let overallExprFixup overallExpr = mkCompGenLet mForLoopStart arrVar enumExpr overallExpr + + // Ask for a loop over integers for the given range + (elemTy, bodyExprFixup, overallExprFixup, Choice2Of3 (idxVar, mkZero cenv.g mForLoopStart, mkDecr cenv.g mForLoopStart (mkLdlen cenv.g mForLoopStart arrExpr))) + + | _ -> + // try optimize 'for i in span do' for span or readonlyspan + match tryGetOptimizeSpanMethods cenv.g mWholeExpr enumExprTy with + | ValueSome(struct(getItemMethInfo, getLengthMethInfo, isReadOnlySpan)) -> + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + let spanVar, spanExpr = mkCompGenLocal mEnumExpr "span" enumExprTy + let idxVar, idxExpr = mkCompGenLocal mPat "idx" cenv.g.int32_ty + let struct(_, elemTy) = if isReadOnlySpan then destReadOnlySpanTy cenv.g mWholeExpr enumExprTy else destSpanTy cenv.g mWholeExpr enumExprTy + let elemAddrTy = if isReadOnlySpan then mkInByrefTy cenv.g elemTy else mkByrefTy cenv.g elemTy + + // Evaluate the span index lookup + let bodyExprFixup elemVar bodyExpr = + let elemAddrVar, _ = mkCompGenLocal mForLoopStart "addr" elemAddrTy + let e = mkCompGenLet mForLoopStart elemVar (mkAddrGet mForLoopStart (mkLocalValRef elemAddrVar)) bodyExpr + let getItemCallExpr, _ = BuildMethodCall tcVal cenv.g cenv.amap PossiblyMutates mWholeExpr true getItemMethInfo ValUseFlag.NormalValUse [] [ spanExpr ] [ idxExpr ] + mkCompGenLet mForLoopStart elemAddrVar getItemCallExpr e + + // Evaluate the span expression once and put it in spanVar + let overallExprFixup overallExpr = mkCompGenLet mForLoopStart spanVar enumExpr overallExpr + + let getLengthCallExpr, _ = BuildMethodCall tcVal cenv.g cenv.amap PossiblyMutates mWholeExpr true getLengthMethInfo ValUseFlag.NormalValUse [] [ spanExpr ] [] + + // Ask for a loop over integers for the given range + (elemTy, bodyExprFixup, overallExprFixup, Choice2Of3 (idxVar, mkZero cenv.g mForLoopStart, mkDecr cenv.g mForLoopStart getLengthCallExpr)) + + | _ -> + let enumerableVar, enumerableExprInVar = mkCompGenLocal mEnumExpr "inputSequence" enumExprTy + let enumeratorVar, enumeratorExpr, _, enumElemTy, getEnumExpr, getEnumTy, guardExpr, _, currentExpr = + AnalyzeArbitraryExprAsEnumerable cenv env true mEnumExpr enumExprTy enumerableExprInVar + (enumElemTy, (fun _ x -> x), id, Choice3Of3(enumerableVar, enumeratorVar, enumeratorExpr, getEnumExpr, getEnumTy, guardExpr, currentExpr)) + + let pat, _, vspecs, envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) + let elemVar, pat = + // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to + match pat with + | TPat_as (pat1, PBind(v, TypeScheme([], _)), _) -> + v, pat1 + | _ -> + let tmp, _ = mkCompGenLocal pat.Range "forLoopVar" enumElemTy + tmp, pat + + // Check the body of the loop + let bodyExpr, tpenv = TcStmt cenv envinner tpenv bodySynExpr + + // Add the pattern match compilation + let bodyExpr = + let valsDefinedByMatching = ListSet.remove valEq elemVar vspecs + CompilePatternForMatch + cenv env enumSynExpr.Range pat.Range false IgnoreWithWarning (elemVar, [], None) + [TClause(pat, None, TTarget(valsDefinedByMatching, bodyExpr, DebugPointAtTarget.Yes, None), mForLoopStart)] + enumElemTy + overallTy.Commit + + // Apply the fixup to bind the elemVar if needed + let bodyExpr = bodyExprFixup elemVar bodyExpr + + // Build the overall loop + let overallExpr = + + match iterationTechnique with + + // Build iteration as a for loop + | Choice1Of3(startExpr, finishExpr) -> + mkFastForLoop cenv.g (spForLoop, mWholeExpr, elemVar, startExpr, true, finishExpr, bodyExpr) + + // Build iteration as a for loop with a specific index variable that is not the same as the elemVar + | Choice2Of3(idxVar, startExpr, finishExpr) -> + mkFastForLoop cenv.g (spForLoop, mWholeExpr, idxVar, startExpr, true, finishExpr, bodyExpr) + + // Build iteration as a while loop with a try/finally disposal + | Choice3Of3(enumerableVar, enumeratorVar, _, getEnumExpr, _, guardExpr, currentExpr) -> + + // This compiled for must be matched EXACTLY by CompiledForEachExpr in opt.fs and creflect.fs + mkCompGenLet mForLoopStart enumerableVar enumExpr + (let cleanupE = BuildDisposableCleanup cenv env mWholeExpr enumeratorVar + let spBind = match spForLoop with DebugPointAtFor.Yes spStart -> DebugPointAtBinding.Yes spStart | DebugPointAtFor.No -> DebugPointAtBinding.NoneAtSticky + (mkLet spBind mForLoopStart enumeratorVar getEnumExpr + (mkTryFinally cenv.g + (mkWhile cenv.g + (DebugPointAtWhile.No, + WhileLoopForCompiledForEachExprMarker, guardExpr, + mkCompGenLet mForLoopStart elemVar currentExpr bodyExpr, + mForLoopStart), + cleanupE, mForLoopStart, cenv.g.unit_ty, DebugPointAtTry.No, DebugPointAtFinally.No)))) + + let overallExpr = overallExprFixup overallExpr + overallExpr, tpenv + +//------------------------------------------------------------------------- +// TcQuotationExpr +//------------------------------------------------------------------------- + +and TcQuotationExpr cenv overallTy env tpenv (_oper, raw, ast, isFromQueryExpression, m) = + let astTy = NewInferenceType () + + // Assert the overall type for the domain of the quotation template + UnifyTypes cenv env m overallTy.Commit (if raw then mkRawQuotedExprTy cenv.g else mkQuotedExprTy cenv.g astTy) + + // Check the expression + let expr, tpenv = TcExpr cenv (MustEqual astTy) env tpenv ast + + // Wrap the expression + let expr = Expr.Quote (expr, ref None, isFromQueryExpression, m, overallTy.Commit) + + // Coerce it if needed + let expr = if raw then mkCoerceExpr(expr, (mkRawQuotedExprTy cenv.g), m, (tyOfExpr cenv.g expr)) else expr + + // We serialize the quoted expression to bytes in IlxGen after type inference etc. is complete. + expr, tpenv + +/// When checking sequence of function applications, +/// type applications and dot-notation projections, first extract known +/// type information from the applications. +/// +/// 'overallTy' is the type expected for the entire chain of expr + lookups. +/// 'exprty' is the type of the expression on the left of the lookup chain. +/// +/// We propagate information from the expected overall type 'overallTy'. The use +/// of function application syntax unambiguously implies that 'overallTy' is a function type. +and Propagate cenv (overallTy: OverallTy) (env: TcEnv) tpenv (expr: ApplicableExpr) exprty delayed = + + let rec propagate isAddrOf delayedList mExpr exprty = + match delayedList with + | [] -> + + if not (isNil delayed) then + + // We generate a tag inference parameter to the return type for "&x" and 'NativePtr.toByRef' + // See RFC FS-1053.md + let exprty = + if isAddrOf && isByrefTy cenv.g exprty then + mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewByRefKindInferenceType cenv.g mExpr) + elif isByrefTy cenv.g exprty then + // Implicit dereference on byref on return + if isByrefTy cenv.g overallTy.Commit then + errorR(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), mExpr)) + destByrefTy cenv.g exprty + else + exprty + + // at the end of the application chain allow coercion introduction + UnifyOverallTypeAndRecover cenv env mExpr overallTy exprty + + | DelayedDot :: _ + | DelayedSet _ :: _ + | DelayedDotLookup _ :: _ -> () + | DelayedTypeApp (_, _mTypeArgs, mExprAndTypeArgs) :: delayedList' -> + // Note this case should not occur: would eventually give an "Unexpected type application" error in TcDelayed + propagate isAddrOf delayedList' mExprAndTypeArgs exprty + + | DelayedApp (atomicFlag, isSugar, synLeftExprOpt, synArg, mExprAndArg) :: delayedList' -> + let denv = env.DisplayEnv + match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with + | ValueSome (_, resultTy) -> + + // We add tag parameter to the return type for "&x" and 'NativePtr.toByRef' + // See RFC FS-1053.md + let isAddrOf = + match expr with + | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _) + when (valRefEq cenv.g vf cenv.g.addrof_vref || + valRefEq cenv.g vf cenv.g.nativeptr_tobyref_vref) -> true + | _ -> false + + propagate isAddrOf delayedList' mExprAndArg resultTy + + | _ -> + let mArg = synArg.Range + match synArg with + // async { ... } + // seq { ... } + | SynExpr.ComputationExpr _ -> () + + // expr[idx] + // expr[idx1, idx2] + // expr[idx1..] + // expr[..idx1] + // expr[idx1..idx2] + | SynExpr.ArrayOrListComputed(false, _, _) -> + let isAdjacent = isAdjacentListExpr isSugar atomicFlag synLeftExprOpt synArg + if isAdjacent && cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + // This is the non-error path + () + else + // This is the error path. The error we give depends on what's enabled. + // + // First, 'delayed' is about to be dropped on the floor, do rudimentary checking to get name resolutions in its body + RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed + let vName = + match expr.Expr with + | Expr.Val (d, _, _) -> Some d.DisplayName + | _ -> None + if isAdjacent then + if IsIndexerType cenv.g cenv.amap expr.Type then + if cenv.g.langVersion.IsExplicitlySpecifiedAs50OrBefore() then + error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg, false)) + match vName with + | Some nm -> + error(Error(FSComp.SR.tcNotAFunctionButIndexerNamedIndexingNotYetEnabled(nm, nm), mExprAndArg)) + | _ -> + error(Error(FSComp.SR.tcNotAFunctionButIndexerIndexingNotYetEnabled(), mExprAndArg)) + else + match vName with + | Some nm -> + error(Error(FSComp.SR.tcNotAnIndexerNamedIndexingNotYetEnabled(nm), mExprAndArg)) + | _ -> + error(Error(FSComp.SR.tcNotAnIndexerIndexingNotYetEnabled(), mExprAndArg)) + else + if IsIndexerType cenv.g cenv.amap expr.Type then + let old = not (cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot) + error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg, old)) + else + error (NotAFunction(denv, overallTy.Commit, mExpr, mArg)) + + // f x (where 'f' is not a function) + | _ -> + // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body + RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed + error (NotAFunction(denv, overallTy.Commit, mExpr, mArg)) + + propagate false delayed expr.Range exprty + +and PropagateThenTcDelayed cenv (overallTy: OverallTy) env tpenv mExpr expr exprty (atomicFlag: ExprAtomicFlag) delayed = + Propagate cenv overallTy env tpenv expr exprty delayed + TcDelayed cenv overallTy env tpenv mExpr expr exprty atomicFlag delayed + +/// Typecheck "expr ... " constructs where "..." is a sequence of applications, +/// type applications and dot-notation projections. +and TcDelayed cenv (overallTy: OverallTy) env tpenv mExpr expr exprty (atomicFlag: ExprAtomicFlag) delayed = + + // OK, we've typechecked the thing on the left of the delayed lookup chain. + // We can now record for posterity the type of this expression and the location of the expression. + if (atomicFlag = ExprAtomicFlag.Atomic) then + CallExprHasTypeSink cenv.tcSink (mExpr, env.NameEnv, exprty, env.eAccessRights) + + match delayed with + | [] + | DelayedDot :: _ -> + // at the end of the application chain allow coercion introduction + UnifyOverallType cenv env mExpr overallTy exprty + let expr2 = TcAdjustExprForTypeDirectedConversions cenv overallTy exprty env (* true *) mExpr expr.Expr + expr2, tpenv + + // Expr.M (args) where x.M is a .NET method or index property + // expr.M(args) where x.M is a .NET method or index property + // expr.M where x.M is a .NET method or index property + | DelayedDotLookup (longId, mDotLookup) :: otherDelayed -> + TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup + + // f x + | DelayedApp (atomicFlag, isSugar, synLeftExpr, synArg, mExprAndArg) :: otherDelayed -> + TcApplicationThen cenv overallTy env tpenv mExprAndArg synLeftExpr expr exprty synArg atomicFlag isSugar otherDelayed + + // f + | DelayedTypeApp (_, mTypeArgs, _mExprAndTypeArgs) :: _ -> + error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs)) + + | DelayedSet (synExpr2, mStmt) :: otherDelayed -> + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mExpr)) + UnifyTypes cenv env mExpr overallTy.Commit cenv.g.unit_ty + let expr = expr.Expr + let _wrap, exprAddress, _readonly, _writeonly = mkExprAddrOfExpr cenv.g true false DefinitelyMutates expr None mExpr + let vty = tyOfExpr cenv.g expr + // Always allow subsumption on assignment to fields + let expr2, tpenv = TcExprFlex cenv true false vty env tpenv synExpr2 + let v, _ve = mkCompGenLocal mExpr "addr" (mkByrefTy cenv.g vty) + mkCompGenLet mStmt v exprAddress (mkAddrSet mStmt (mkLocalValRef v) expr2), tpenv + +/// Convert the delayed identifiers to a dot-lookup. +/// +/// TcItemThen: For StaticItem [.Lookup], mPrior is the range of StaticItem +/// TcLookupThen: For expr.InstanceItem [.Lookup], mPrior is the range of expr.InstanceItem +and delayRest rest mPrior delayed = + match rest with + | [] -> delayed + | longId -> + let mPriorAndLongId = unionRanges mPrior (rangeOfLid longId) + DelayedDotLookup (rest, mPriorAndLongId) :: delayed + +/// Typecheck "nameof" expressions +and TcNameOfExpr cenv env tpenv (synArg: SynExpr) = + + let rec stripParens expr = + match expr with + | SynExpr.Paren(expr, _, _, _) -> stripParens expr + | _ -> expr + + let cleanSynArg = stripParens synArg + let m = cleanSynArg.Range + let rec check overallTyOpt resultOpt expr (delayed: DelayedItem list) = + match expr with + | LongOrSingleIdent (false, LongIdentWithDots(longId, _), _, _) -> + + let ad = env.eAccessRights + let result = defaultArg resultOpt (List.last longId) + + // Demangle back to source operator name if the lengths in the ranges indicate the + // original source range matches exactly + let result = + if IsMangledOpName result.idText then + let demangled = DecompileOpName result.idText + if demangled.Length = result.idRange.EndColumn - result.idRange.StartColumn then + ident(demangled, result.idRange) + else result + else result + + // Nameof resolution resolves to a symbol and in general we make that the same symbol as + // would resolve if the long ident was used as an expression at the given location. + // + // So we first check if the first identifier resolves as an expression, if so commit and and resolve. + // + // However we don't commit for a type names - nameof allows 'naked' type names and thus all type name + // resolutions are checked separately in the next step. + let typeNameResInfo = GetLongIdentTypeNameInfo delayed + let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId + let resolvesAsExpr = + match nameResolutionResult with + | Result (_, item, _, _, _ as res) + when + (match item with + | Item.Types _ + | Item.DelegateCtor _ + | Item.CtorGroup _ + | Item.FakeInterfaceCtor _ -> false + | _ -> true) -> + let overallTy = match overallTyOpt with None -> MustEqual (NewInferenceType()) | Some t -> t + let _, _ = TcItemThen cenv overallTy env tpenv res delayed + true + | _ -> + false + if resolvesAsExpr then result else + + // If it's not an expression then try to resolve it as a type name + let resolvedToTypeName = + if (match delayed with [DelayedTypeApp _] | [] -> true | _ -> false) then + let (TypeNameResolutionInfo(_, staticArgsInfo)) = GetLongIdentTypeNameInfo delayed + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad longId staticArgsInfo PermitDirectReferenceToGeneratedType.No with + | Result (tinstEnclosing, tcref) when IsEntityAccessible cenv.amap m ad tcref -> + match delayed with + | [DelayedTypeApp (tyargs, _, mExprAndTypeArgs)] -> + TcTypeApp cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs tcref tinstEnclosing tyargs |> ignore + | _ -> () + true // resolved to a type name, done with checks + | _ -> + false + else + false + if resolvedToTypeName then result else + + // If it's not an expression or type name then resolve it as a module + let resolvedToModuleOrNamespaceName = + if delayed.IsEmpty then + let id,rest = List.headAndTail longId + match ResolveLongIdentAsModuleOrNamespace cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m true OpenQualified env.eNameResEnv ad id rest true with + | Result modref when delayed.IsEmpty && modref |> List.exists (p23 >> IsEntityAccessible cenv.amap m ad) -> + true // resolved to a module or namespace, done with checks + | _ -> + false + else + false + if resolvedToModuleOrNamespaceName then result else + + ForceRaise nameResolutionResult |> ignore + // If that didn't give aan exception then raise a generic error + error (Error(FSComp.SR.expressionHasNoName(), m)) + + // expr allowed, even with qualifications + | SynExpr.TypeApp (hd, _, types, _, _, _, m) -> + check overallTyOpt resultOpt hd (DelayedTypeApp(types, m, m) :: delayed) + + // expr.ID allowed + | SynExpr.DotGet (hd, _, LongIdentWithDots(longId, _), _) -> + let result = defaultArg resultOpt (List.last longId) + check overallTyOpt (Some result) hd ((DelayedDotLookup (longId, expr.RangeWithoutAnyExtraDot)) :: delayed) + + // "(expr)" allowed with no subsequent qualifications + | SynExpr.Paren(expr, _, _, _) when delayed.IsEmpty && overallTyOpt.IsNone -> + check overallTyOpt resultOpt expr delayed + + // expr : type" allowed with no subsequent qualifications + | SynExpr.Typed (synBodyExpr, synType, _) when delayed.IsEmpty && overallTyOpt.IsNone -> + let tgtTy, _tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType + check (Some (MustEqual tgtTy)) resultOpt synBodyExpr delayed + + | _ -> + error (Error(FSComp.SR.expressionHasNoName(), m)) + + let lastIdent = check None None cleanSynArg [] + TcNameOfExprResult cenv lastIdent m + +and TcNameOfExprResult cenv (lastIdent: Ident) m = + let constRange = mkRange m.FileName m.Start (mkPos m.StartLine (m.StartColumn + lastIdent.idText.Length + 2)) // `2` are for quotes + Expr.Const(Const.String(lastIdent.idText), constRange, cenv.g.string_ty) + +//------------------------------------------------------------------------- +// TcApplicationThen: Typecheck "expr x" + projections +//------------------------------------------------------------------------- + +// leftExpr[idx] gives a warning +and isAdjacentListExpr isSugar atomicFlag (synLeftExprOpt: SynExpr option) (synArg: SynExpr) = + not isSugar && + if atomicFlag = ExprAtomicFlag.Atomic then + match synArg with + | SynExpr.ArrayOrList (false, _, _) + | SynExpr.ArrayOrListComputed (false, _, _) -> true + | _ -> false + else + match synLeftExprOpt with + | Some synLeftExpr -> + match synArg with + | SynExpr.ArrayOrList (false, _, _) + | SynExpr.ArrayOrListComputed (false, _, _) -> + synLeftExpr.Range.IsAdjacentTo synArg.Range + | _ -> false + | _ -> false + +// Check f x +// Check f[x] +// Check seq { expr } +// Check async { expr } +and TcApplicationThen cenv (overallTy: OverallTy) env tpenv mExprAndArg synLeftExprOpt leftExpr exprty (synArg: SynExpr) atomicFlag isSugar delayed = + let denv = env.DisplayEnv + let mArg = synArg.Range + let mLeftExpr = leftExpr.Range + + // If the type of 'synArg' unifies as a function type, then this is a function application, otherwise + // it is an error or a computation expression or indexer or delegate invoke + match UnifyFunctionTypeUndoIfFailed cenv denv mLeftExpr exprty with + | ValueSome (domainTy, resultTy) -> + + // atomicLeftExpr[idx] unifying as application gives a warning + if not isSugar then + match synArg, atomicFlag with + | (SynExpr.ArrayOrList (false, _, _) | SynExpr.ArrayOrListComputed (false, _, _)), ExprAtomicFlag.Atomic -> + if cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), mExprAndArg)) + elif not (cenv.g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then + informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), mExprAndArg)) + | _ -> () + + match leftExpr with + | ApplicableExpr(_, NameOfExpr cenv.g _, _) when cenv.g.langVersion.SupportsFeature LanguageFeature.NameOf -> + let replacementExpr = TcNameOfExpr cenv env tpenv synArg + TcDelayed cenv overallTy env tpenv mExprAndArg (ApplicableExpr(cenv, replacementExpr, true)) cenv.g.string_ty ExprAtomicFlag.Atomic delayed + | _ -> + // Notice the special case 'seq { ... }'. In this case 'seq' is actually a function in the F# library. + // Set a flag in the syntax tree to say we noticed a leading 'seq' + // + // Note that 'seq' predated computation expressions and is not actually a computation expression builder + // though users don't realise that. + let synArg = + match synArg with + | SynExpr.ComputationExpr (false, comp, m) when + (match leftExpr with + | ApplicableExpr(_, Expr.Op(TOp.Coerce, _, [SeqExpr cenv.g], _), _) -> true + | _ -> false) -> + SynExpr.ComputationExpr (true, comp, m) + | _ -> synArg + + let arg, tpenv = TcExprFlex2 cenv domainTy env false tpenv synArg + let exprAndArg, resultTy = buildApp cenv leftExpr resultTy arg mExprAndArg + TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed + + | ValueNone -> + // Type-directed invokables + + match synArg with + // leftExpr[idx] + // leftExpr[idx] <- expr2 + | SynExpr.ArrayOrListComputed(false, IndexerArgs indexArgs, m) + when + isAdjacentListExpr isSugar atomicFlag synLeftExprOpt synArg && + cenv.g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot -> + + let expandedIndexArgs = ExpandIndexArgs synLeftExprOpt indexArgs + let setInfo, delayed = + match delayed with + | DelayedSet(e3, _) :: rest -> Some (e3, unionRanges leftExpr.Range synArg.Range), rest + | _ -> None, delayed + TcIndexingThen cenv env overallTy mExprAndArg m tpenv setInfo synLeftExprOpt leftExpr.Expr exprty expandedIndexArgs indexArgs delayed + + // Perhaps 'leftExpr' is a computation expression builder, and 'arg' is '{ ... }' + | SynExpr.ComputationExpr (false, comp, _m) -> + let bodyOfCompExpr, tpenv = cenv.TcComputationExpression cenv env overallTy tpenv (mLeftExpr, leftExpr.Expr, exprty, comp) + TcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv bodyOfCompExpr) (tyOfExpr cenv.g bodyOfCompExpr) ExprAtomicFlag.NonAtomic delayed + + | _ -> + error (NotAFunction(denv, overallTy.Commit, mLeftExpr, mArg)) + +//------------------------------------------------------------------------- +// TcLongIdentThen: Typecheck "A.B.C.E.F ... " constructs +//------------------------------------------------------------------------- + +and GetLongIdentTypeNameInfo delayed = + // Given 'MyOverloadedType.MySubType...' use the number of given type arguments to help + // resolve type name lookup of 'MyOverloadedType' + // Also determine if type names should resolve to Item.Types or Item.CtorGroup + match delayed with + | DelayedTypeApp (tyargs, _, _) :: (DelayedDot | DelayedDotLookup _) :: _ -> + // cases like 'MyType.Sth' + TypeNameResolutionInfo(ResolveTypeNamesToTypeRefs, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) + + | DelayedTypeApp (tyargs, _, _) :: _ -> + // Note, this also covers the case 'MyType.' (without LValue_get), which is needed for VS (when typing) + TypeNameResolutionInfo(ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) + + | _ -> + TypeNameResolutionInfo.Default + +and TcLongIdentThen cenv (overallTy: OverallTy) env tpenv (LongIdentWithDots(longId, _)) delayed = + + let ad = env.eAccessRights + let typeNameResInfo = GetLongIdentTypeNameInfo delayed + let nameResolutionResult = + ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId + |> ForceRaise + TcItemThen cenv overallTy env tpenv nameResolutionResult delayed + +//------------------------------------------------------------------------- +// Typecheck "item+projections" +//------------------------------------------------------------------------- *) +// mItem is the textual range covered by the long identifiers that make up the item +and TcItemThen cenv (overallTy: OverallTy) env tpenv (tinstEnclosing, item, mItem, rest, afterResolution) delayed = + let g = cenv.g + let delayed = delayRest rest mItem delayed + let ad = env.eAccessRights + match item with + // x where x is a union case or active pattern result tag. + | Item.UnionCase _ | Item.ExnCase _ | Item.ActivePatternResult _ as item -> + // ucaseAppTy is the type of the union constructor applied to its (optional) argument + let ucaseAppTy = NewInferenceType () + let mkConstrApp, argTys, argNames = + match item with + | Item.ActivePatternResult(apinfo, _apOverallTy, n, _) -> + let aparity = apinfo.Names.Length + match aparity with + | 0 | 1 -> + let mkConstrApp _mArgs = function [arg] -> arg | _ -> error(InternalError("ApplyUnionCaseOrExn", mItem)) + mkConstrApp, [ucaseAppTy], [ for s, m in apinfo.ActiveTagsWithRanges -> mkSynId m s ] + | _ -> + let ucref = mkChoiceCaseRef g mItem aparity n + let _, _, tinst, _ = FreshenTyconRef2 mItem ucref.TyconRef + let ucinfo = UnionCaseInfo (tinst, ucref) + ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy (Item.UnionCase(ucinfo, false)) + | _ -> + ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy item + let numArgTys = List.length argTys + + // Subsumption at data constructions if argument type is nominal prior to equations for any arguments or return types + let flexes = argTys |> List.map (isTyparTy g >> not) + + let (|FittedArgs|_|) arg = + match arg with + | SynExprParen(SynExpr.Tuple (false, args, _, _), _, _, _) + | SynExpr.Tuple (false, args, _, _) when numArgTys > 1 -> Some args + | SynExprParen(arg, _, _, _) + | arg when numArgTys = 1 -> Some [arg] + | _ -> None + + match delayed with + // This is where the constructor is applied to an argument + | DelayedApp (atomicFlag, _, _, (FittedArgs args as origArg), mExprAndArg) :: otherDelayed -> + // assert the overall result type if possible + if isNil otherDelayed then + UnifyOverallType cenv env mExprAndArg overallTy ucaseAppTy + + let numArgs = List.length args + UnionCaseOrExnCheck env numArgTys numArgs mExprAndArg + + // if we manage to get here - number of formal arguments = number of actual arguments + // apply named parameters + let args = + // GetMethodArgs checks that no named parameters are located before positional + let unnamedArgs, namedCallerArgs = GetMethodArgs origArg + match namedCallerArgs with + | [] -> + args + | _ -> + let fittedArgs = Array.zeroCreate numArgTys + + // first: put all positional arguments + let mutable currentIndex = 0 + for arg in unnamedArgs do + fittedArgs.[currentIndex] <- arg + currentIndex <- currentIndex + 1 + + let SEEN_NAMED_ARGUMENT = -1 + + // dealing with named arguments is a bit tricky since prior to these changes we have an ambiguous situation: + // regular notation for named parameters Some(Value = 5) can mean either 1) create option with value - result of equality operation or 2) create option using named arg syntax. + // so far we've used 1) so we cannot immediately switch to 2) since it will be a definite breaking change. + + for _, id, arg in namedCallerArgs do + match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with + | Some i -> + if isNull(box fittedArgs.[i]) then + fittedArgs.[i] <- arg + let argItem = + match item with + | Item.UnionCase (uci, _) -> Item.UnionCaseField (uci, i) + | Item.ExnCase tref -> Item.RecdField (RecdFieldInfo ([], RecdFieldRef (tref, id.idText))) + | _ -> failwithf "Expecting union case or exception item, got: %O" item + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, emptyTyparInst, ItemOccurence.Use, ad) + else error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) + currentIndex <- SEEN_NAMED_ARGUMENT + | None -> + // ambiguity may appear only when if argument is boolean\generic. + // if + // - we didn't find argument with specified name AND + // - we have not seen any named arguments so far AND + // - type of current argument is bool\generic + // then we'll favor old behavior and treat current argument as positional. + let isSpecialCaseForBackwardCompatibility = + (currentIndex <> SEEN_NAMED_ARGUMENT) && + (currentIndex < numArgTys) && + match stripTyEqns g argTys.[currentIndex] with + | TType_app(tcref, _) -> tyconRefEq g g.bool_tcr tcref || tyconRefEq g g.system_Bool_tcref tcref + | TType_var _ -> true + | _ -> false + + if isSpecialCaseForBackwardCompatibility then + assert (isNull(box fittedArgs.[currentIndex])) + fittedArgs.[currentIndex] <- List.item currentIndex args // grab original argument, not item from the list of named parameters + currentIndex <- currentIndex + 1 + else + match item with + | Item.UnionCase(uci, _) -> + error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(uci.DisplayName, id.idText), id.idRange)) + | Item.ExnCase tcref -> + error(Error(FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName(tcref.DisplayName, id.idText), id.idRange)) + | Item.ActivePatternResult _ -> + error(Error(FSComp.SR.tcActivePatternsDoNotHaveFields(), id.idRange)) + | _ -> + error(Error(FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName(id.idText), id.idRange)) + + assert (Seq.forall (box >> ((<>) null) ) fittedArgs) + List.ofArray fittedArgs + + let args', tpenv = TcExprsWithFlexes cenv env mExprAndArg tpenv flexes argTys args + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv (mkConstrApp mExprAndArg args')) ucaseAppTy atomicFlag otherDelayed + + | DelayedTypeApp (_x, mTypeArgs, _mExprAndTypeArgs) :: _delayed' -> + error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs)) + | _ -> + // Work out how many syntactic arguments we really expect. Also return a function that builds the overall + // expression, but don't apply this function until after we've checked that the number of arguments is OK + // (or else we would be building an invalid expression) + + // Unit-taking active pattern result can be applied to no args + let numArgs, mkExpr = + // This is where the constructor is an active pattern result applied to no argument + // Unit-taking active pattern result can be applied to no args + if (numArgTys = 1 && match item with Item.ActivePatternResult _ -> true | _ -> false) then + UnifyTypes cenv env mItem (List.head argTys) g.unit_ty + 1, (fun () -> mkConstrApp mItem [mkUnit g mItem]) + + // This is where the constructor expects no arguments and is applied to no argument + elif numArgTys = 0 then + 0, (fun () -> mkConstrApp mItem []) + else + // This is where the constructor expects arguments but is not applied to arguments, hence build a lambda + numArgTys, + (fun () -> + let vs, args = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip + let constrApp = mkConstrApp mItem args + let lam = mkMultiLambda mItem vs (constrApp, tyOfExpr g constrApp) + lam) + UnionCaseOrExnCheck env numArgTys numArgs mItem + let expr = mkExpr() + let exprTy = tyOfExpr g expr + PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprNoFlex cenv expr) exprTy ExprAtomicFlag.Atomic delayed + + | Item.Types(nm, ty :: _) -> + + match delayed with + | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: DelayedDotLookup (longId, mLongId) :: otherDelayed -> + // If Item.Types is returned then the ty will be of the form TType_app(tcref, genericTyargs) where tyargs + // is a fresh instantiation for tcref. TcNestedTypeApplication will chop off precisely #genericTyargs args + // and replace them by 'tyargs' + let ty, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs ty tinstEnclosing tyargs + + // Report information about the whole expression including type arguments to VS + let item = Item.Types(nm, [ty]) + CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + let typeNameResInfo = GetLongIdentTypeNameInfo otherDelayed + let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver (unionRanges mExprAndTypeArgs mLongId) ad env.eNameResEnv ty longId typeNameResInfo IgnoreOverrides true + TcItemThen cenv overallTy env tpenv ((argsOfAppTy g ty), item, mItem, rest, afterResolution) otherDelayed + + | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: _delayed' -> + // A case where we have an incomplete name e.g. 'Foo.' - we still want to report it to VS! + let ty, _ = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs ty tinstEnclosing tyargs + let item = Item.Types(nm, [ty]) + CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + + // Same error as in the following case + error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) + + | _ -> + // In this case the type is not generic, and indeed we should never have returned Item.Types. + // That's because ResolveTypeNamesToCtors should have been set at the original + // call to ResolveLongIdentAsExprAndComputeRange + error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) + + | Item.MethodGroup (methodName, minfos, _) -> + // Static method calls Type.Foo(arg1, ..., argn) + let meths = List.map (fun minfo -> minfo, None) minfos + match delayed with + | DelayedApp (atomicFlag, _, _, arg, mExprAndArg) :: otherDelayed -> + TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndArg mItem methodName ad NeverMutates false meths afterResolution NormalValUse [arg] atomicFlag otherDelayed + + | DelayedTypeApp(tys, mTypeArgs, mExprAndTypeArgs) :: otherDelayed -> + +#if !NO_EXTENSIONTYPING + match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, Some (tys, mTypeArgs), mExprAndTypeArgs, mItem) with + | Some minfoAfterStaticArguments -> + + // Replace the resolution including the static parameters, plus the extra information about the original method info + let item = Item.MethodGroup(methodName, [minfoAfterStaticArguments], Some minfos.[0]) + CallNameResolutionSinkReplacing cenv.tcSink (mItem, env.NameEnv, item, [], ItemOccurence.Use, env.eAccessRights) + + match otherDelayed with + | DelayedApp(atomicFlag, _, _, arg, mExprAndArg) :: otherDelayed -> + TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndArg mItem methodName ad NeverMutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse [arg] atomicFlag otherDelayed + | _ -> + TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndTypeArgs mItem methodName ad NeverMutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse [] ExprAtomicFlag.Atomic otherDelayed + + | None -> +#endif + + let tyargs, tpenv = TcTypesOrMeasures None cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tys mTypeArgs + + // FUTURE: can we do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE? But note we haven't yet even checked if the + // number of type arguments is correct... + CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + + match otherDelayed with + | DelayedApp(atomicFlag, _, _, arg, mExprAndArg) :: otherDelayed -> + TcMethodApplicationThen cenv env overallTy None tpenv (Some tyargs) [] mExprAndArg mItem methodName ad NeverMutates false meths afterResolution NormalValUse [arg] atomicFlag otherDelayed + | _ -> + TcMethodApplicationThen cenv env overallTy None tpenv (Some tyargs) [] mExprAndTypeArgs mItem methodName ad NeverMutates false meths afterResolution NormalValUse [] ExprAtomicFlag.Atomic otherDelayed + + | _ -> +#if !NO_EXTENSIONTYPING + if not minfos.IsEmpty && minfos.[0].ProvidedStaticParameterInfo.IsSome then + error(Error(FSComp.SR.etMissingStaticArgumentsToMethod(), mItem)) +#endif + TcMethodApplicationThen cenv env overallTy None tpenv None [] mItem mItem methodName ad NeverMutates false meths afterResolution NormalValUse [] ExprAtomicFlag.Atomic delayed + + | Item.CtorGroup(nm, minfos) -> + let objTy = + match minfos with + | minfo :: _ -> minfo.ApparentEnclosingType + | [] -> error(Error(FSComp.SR.tcTypeHasNoAccessibleConstructor(), mItem)) + match delayed with + | DelayedApp(_, _, _, arg, mExprAndArg) :: otherDelayed -> + + CallExprHasTypeSink cenv.tcSink (mExprAndArg, env.NameEnv, objTy, env.eAccessRights) + TcCtorCall true cenv env tpenv overallTy objTy (Some mItem) item false [arg] mExprAndArg otherDelayed (Some afterResolution) + + | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: DelayedApp(_, _, _, arg, mExprAndArg) :: otherDelayed -> + + let objTyAfterTyArgs, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs objTy tinstEnclosing tyargs + CallExprHasTypeSink cenv.tcSink (mExprAndArg, env.NameEnv, objTyAfterTyArgs, env.eAccessRights) + let itemAfterTyArgs, minfosAfterTyArgs = +#if !NO_EXTENSIONTYPING + // If the type is provided and took static arguments then the constructor will have changed + // to a provided constructor on the statically instantiated type. Re-resolve that constructor. + match objTyAfterTyArgs with + | AppTy g (tcref, _) when tcref.Deref.IsProvided -> + let newItem = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mExprAndArg ad objTyAfterTyArgs) + match newItem with + | Item.CtorGroup(_, newMinfos) -> newItem, newMinfos + | _ -> item, minfos + | _ -> +#endif + item, minfos + + minfosAfterTyArgs |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTyAfterTyArgs) + TcCtorCall true cenv env tpenv overallTy objTyAfterTyArgs (Some mExprAndTypeArgs) itemAfterTyArgs false [arg] mExprAndArg otherDelayed (Some afterResolution) + + | DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs) :: otherDelayed -> + + let objTy, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs objTy tinstEnclosing tyargs + + // A case where we have an incomplete name e.g. 'Foo.' - we still want to report it to VS! + let resolvedItem = Item.Types(nm, [objTy]) + CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, resolvedItem, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + + minfos |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTy) + TcCtorCall true cenv env tpenv overallTy objTy (Some mExprAndTypeArgs) item false [] mExprAndTypeArgs otherDelayed (Some afterResolution) + + | _ -> + + TcCtorCall true cenv env tpenv overallTy objTy (Some mItem) item false [] mItem delayed (Some afterResolution) + + | Item.FakeInterfaceCtor _ -> + error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem)) + + | Item.ImplicitOp(id, sln) -> + + let isPrefix = IsPrefixOperator id.idText + let isTernary = IsTernaryOperator id.idText + + let argData = + if isPrefix then + [ SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) ] + elif isTernary then + [ SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) + SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) + SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) ] + else + [ SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) + SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) ] + + let retTyData = SynTypar(mkSynId mItem (cenv.synArgNameGenerator.New()), TyparStaticReq.HeadType, true) + let argTypars = argData |> List.map (fun d -> Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, d, false, TyparDynamicReq.Yes, [], false, false)) + let retTypar = Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, retTyData, false, TyparDynamicReq.Yes, [], false, false) + let argTys = argTypars |> List.map mkTyparTy + let retTy = mkTyparTy retTypar + + let vs, ves = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip + + let memberFlags = StaticMemberFlags SynMemberKind.Member + let logicalCompiledName = ComputeLogicalName id memberFlags + let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, sln) + + let expr = Expr.Op (TOp.TraitCall traitInfo, [], ves, mItem) + let expr = mkLambdas mItem [] vs (expr, retTy) + + let rec isSimpleArgument e = + match e with + | SynExpr.New (_, _, synExpr, _) + | SynExpr.Paren (synExpr, _, _, _) + | SynExpr.Typed (synExpr, _, _) + | SynExpr.TypeApp (synExpr, _, _, _, _, _, _) + | SynExpr.TypeTest (synExpr, _, _) + | SynExpr.Upcast (synExpr, _, _) + | SynExpr.DotGet (synExpr, _, _, _) + | SynExpr.Downcast (synExpr, _, _) + | SynExpr.InferredUpcast (synExpr, _) + | SynExpr.InferredDowncast (synExpr, _) + | SynExpr.AddressOf (_, synExpr, _, _) + | SynExpr.Quote (_, _, synExpr, _, _) -> isSimpleArgument synExpr + + | SynExpr.InterpolatedString _ + | SynExpr.Null _ + | SynExpr.Ident _ + | SynExpr.Const _ + | SynExpr.LongIdent _ -> true + + | SynExpr.Tuple (_, synExprs, _, _) + | SynExpr.ArrayOrList (_, synExprs, _) -> synExprs |> List.forall isSimpleArgument + | SynExpr.Record (_, copyOpt, fields, _) -> copyOpt |> Option.forall (fst >> isSimpleArgument) && fields |> List.forall (p23 >> Option.forall isSimpleArgument) + | SynExpr.App (_, _, synExpr, synExpr2, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 + | SynExpr.IfThenElse (_, _, synExpr, _, synExpr2, _, synExprOpt, _, _, _, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 && Option.forall isSimpleArgument synExprOpt + | SynExpr.DotIndexedGet (synExpr, _, _, _) -> isSimpleArgument synExpr + | SynExpr.ObjExpr _ + | SynExpr.AnonRecd _ + | SynExpr.While _ + | SynExpr.For _ + | SynExpr.ForEach _ + | SynExpr.ArrayOrListComputed _ + | SynExpr.ComputationExpr _ + | SynExpr.Lambda _ + | SynExpr.MatchLambda _ + | SynExpr.Match _ + | SynExpr.Do _ + | SynExpr.Assert _ + | SynExpr.Fixed _ + | SynExpr.TryWith _ + | SynExpr.TryFinally _ + | SynExpr.Lazy _ + | SynExpr.Sequential _ + | SynExpr.SequentialOrImplicitYield _ + | SynExpr.LetOrUse _ + | SynExpr.DotSet _ + | SynExpr.DotIndexedSet _ + | SynExpr.LongIdentSet _ + | SynExpr.Set _ + | SynExpr.JoinIn _ + | SynExpr.NamedIndexedPropertySet _ + | SynExpr.DotNamedIndexedPropertySet _ + | SynExpr.LibraryOnlyILAssembly _ + | SynExpr.LibraryOnlyStaticOptimization _ + | SynExpr.LibraryOnlyUnionCaseFieldGet _ + | SynExpr.LibraryOnlyUnionCaseFieldSet _ + | SynExpr.ArbitraryAfterError _ + | SynExpr.FromParseError _ + | SynExpr.DiscardAfterMissingQualificationAfterDot _ + | SynExpr.ImplicitZero _ + | SynExpr.YieldOrReturn _ + | SynExpr.YieldOrReturnFrom _ + | SynExpr.MatchBang _ + | SynExpr.LetOrUseBang _ + | SynExpr.DoBang _ + | SynExpr.TraitCall _ + | SynExpr.IndexFromEnd _ + | SynExpr.IndexRange _ + -> false + + // Propagate the known application structure into function types + Propagate cenv overallTy env tpenv (MakeApplicableExprNoFlex cenv expr) (tyOfExpr g expr) delayed + + // Take all simple arguments and process them before applying the constraint. + let delayed1, delayed2 = + let pred = (function DelayedApp (_, _, _, arg, _) -> isSimpleArgument arg | _ -> false) + List.takeWhile pred delayed, List.skipWhile pred delayed + + let intermediateTy = if isNil delayed2 then overallTy.Commit else NewInferenceType () + + let resultExpr, tpenv = TcDelayed cenv (MustEqual intermediateTy) env tpenv mItem (MakeApplicableExprNoFlex cenv expr) (tyOfExpr g expr) ExprAtomicFlag.NonAtomic delayed1 + + // Add the constraint after the application arguments have been checked to allow annotations to kick in on rigid type parameters + AddCxMethodConstraint env.DisplayEnv cenv.css mItem NoTrace traitInfo + + // Process all remaining arguments after the constraint is asserted + let resultExpr2, tpenv2 = TcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprNoFlex cenv resultExpr) intermediateTy ExprAtomicFlag.NonAtomic delayed2 + resultExpr2, tpenv2 + + + | Item.DelegateCtor ty -> + match delayed with + | DelayedApp (atomicFlag, _, _, arg, mItemAndArg) :: otherDelayed -> + TcNewDelegateThen cenv overallTy env tpenv mItem mItemAndArg ty arg atomicFlag otherDelayed + | DelayedTypeApp(tyargs, _mTypeArgs, mItemAndTypeArgs) :: DelayedApp (atomicFlag, _, _, arg, mItemAndArg) :: otherDelayed -> + let ty, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mItemAndTypeArgs ty tinstEnclosing tyargs + + // Report information about the whole expression including type arguments to VS + let item = Item.DelegateCtor ty + CallNameResolutionSink cenv.tcSink (mItemAndTypeArgs, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + TcNewDelegateThen cenv overallTy env tpenv mItem mItemAndArg ty arg atomicFlag otherDelayed + | _ -> + error(Error(FSComp.SR.tcInvalidUseOfDelegate(), mItem)) + + | Item.Value vref -> + + match delayed with + // Mutable value set: 'v <- e' + | DelayedSet(e2, mStmt) :: otherDelayed -> + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + UnifyTypes cenv env mStmt overallTy.Commit g.unit_ty + vref.Deref.SetHasBeenReferenced() + CheckValAccessible mItem env.AccessRights vref + CheckValAttributes g vref mItem |> CommitOperationResult + let vty = vref.Type + let vty2 = + if isByrefTy g vty then + destByrefTy g vty + else + if not vref.IsMutable then + errorR (ValNotMutable (env.DisplayEnv, vref, mStmt)) + vty + // Always allow subsumption on assignment to fields + let e2', tpenv = TcExprFlex cenv true false vty2 env tpenv e2 + let vexp = + if isInByrefTy g vty then + errorR(Error(FSComp.SR.writeToReadOnlyByref(), mStmt)) + mkAddrSet mStmt vref e2' + elif isByrefTy g vty then + mkAddrSet mStmt vref e2' + else + mkValSet mStmt vref e2' + + PropagateThenTcDelayed cenv overallTy env tpenv mStmt (MakeApplicableExprNoFlex cenv vexp) (tyOfExpr g vexp) ExprAtomicFlag.NonAtomic otherDelayed + + // Value instantiation: v ... + | DelayedTypeApp(tys, _mTypeArgs, mExprAndTypeArgs) :: otherDelayed -> + // Note: we know this is a NormalValUse or PossibleConstrainedCall because: + // - it isn't a CtorValUsedAsSuperInit + // - it isn't a CtorValUsedAsSelfInit + // - it isn't a VSlotDirectCall (uses of base values do not take type arguments + // Allow `nameof<'T>` for a generic parameter + match vref with + | _ when isNameOfValRef cenv.g vref && cenv.g.langVersion.SupportsFeature LanguageFeature.NameOf -> + match tys with + | [SynType.Var(SynTypar(id, _, false) as tp, _m)] -> + let _tp', tpenv = TcTyparOrMeasurePar None cenv env ImplicitlyBoundTyparsAllowed.NoNewTypars tpenv tp + let vexp = TcNameOfExprResult cenv id mExprAndTypeArgs + let vexpFlex = MakeApplicableExprNoFlex cenv vexp + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndTypeArgs vexpFlex cenv.g.string_ty ExprAtomicFlag.Atomic otherDelayed + | _ -> + error (Error(FSComp.SR.expressionHasNoName(), mExprAndTypeArgs)) + | _ -> + let checkTys tpenv kinds = TcTypesOrMeasures (Some kinds) cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tys mItem + let _, vexp, isSpecial, _, _, tpenv = TcVal true cenv env tpenv vref (Some (NormalValUse, checkTys)) (Some afterResolution) mItem + + let vexpFlex = (if isSpecial then MakeApplicableExprNoFlex cenv vexp else MakeApplicableExprWithFlex cenv env vexp) + // We need to eventually record the type resolution for an expression, but this is done + // inside PropagateThenTcDelayed, so we don't have to explicitly call 'CallExprHasTypeSink' here + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndTypeArgs vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic otherDelayed + + // Value get + | _ -> + let _, vexp, isSpecial, _, _, tpenv = TcVal true cenv env tpenv vref None (Some afterResolution) mItem + let vexpFlex = (if isSpecial then MakeApplicableExprNoFlex cenv vexp else MakeApplicableExprWithFlex cenv env vexp) + PropagateThenTcDelayed cenv overallTy env tpenv mItem vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic delayed + + | Item.Property (nm, pinfos) -> + if isNil pinfos then error (InternalError ("Unexpected error: empty property list", mItem)) + // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. + // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed + let pinfo = List.head pinfos + let _, tyargsOpt, args, delayed, tpenv = + if pinfo.IsIndexer + then GetMemberApplicationArgs delayed cenv env tpenv + else ExprAtomicFlag.Atomic, None, [mkSynUnit mItem], delayed, tpenv + if not pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsNotStatic nm, mItem)) + match delayed with + | DelayedSet(e2, mStmt) :: otherDelayed -> + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + // Static Property Set (possibly indexer) + UnifyTypes cenv env mStmt overallTy.Commit g.unit_ty + let meths = pinfos |> SettersOfPropInfos + if meths.IsEmpty then + let meths = pinfos |> GettersOfPropInfos + let isByrefMethReturnSetter = meths |> List.exists (function _,Some pinfo -> isByrefTy g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false) + if not isByrefMethReturnSetter then + errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) + // x.P <- ... byref setter + if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterResolution NormalValUse args ExprAtomicFlag.Atomic delayed + else + let args = if pinfo.IsIndexer then args else [] + if isNil meths then + errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) + // Note: static calls never mutate a struct object argument + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mStmt mItem nm ad NeverMutates true meths afterResolution NormalValUse (args@[e2]) ExprAtomicFlag.NonAtomic otherDelayed + | _ -> + // Static Property Get (possibly indexer) + let meths = pinfos |> GettersOfPropInfos + if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) + // Note: static calls never mutate a struct object argument + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterResolution NormalValUse args ExprAtomicFlag.Atomic delayed + + | Item.ILField finfo -> + + ILFieldStaticChecks g cenv.amap cenv.infoReader ad mItem finfo + let fref = finfo.ILFieldRef + let exprty = finfo.FieldType(cenv.amap, mItem) + match delayed with + | DelayedSet(e2, mStmt) :: _delayed' -> + UnifyTypes cenv env mStmt overallTy.Commit g.unit_ty + // Always allow subsumption on assignment to fields + let e2', tpenv = TcExprFlex cenv true false exprty env tpenv e2 + let expr = BuildILStaticFieldSet mStmt finfo e2' + expr, tpenv + | _ -> + // Get static IL field + let expr = + match finfo.LiteralValue with + | Some lit -> + Expr.Const (TcFieldInit mItem lit, mItem, exprty) + | None -> + let isValueType = finfo.IsValueType + let valu = if isValueType then AsValue else AsObject + + // The empty instantiation on the fspec is OK, since we make the correct fspec in IlxGen.GenAsm + // This ensures we always get the type instantiation right when doing this from + // polymorphic code, after inlining etc. + let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) + + // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. + mkAsmExpr ([ mkNormalLdsfld fspec ] @ (if finfo.IsInitOnly then [ AI_nop ] else []), finfo.TypeInst, [], [exprty], mItem) + PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed + + | Item.RecdField rfinfo -> + // Get static F# field or literal + CheckRecdFieldInfoAccessible cenv.amap mItem ad rfinfo + if not rfinfo.IsStatic then error (Error (FSComp.SR.tcFieldIsNotStatic(rfinfo.DisplayName), mItem)) + CheckRecdFieldInfoAttributes g rfinfo mItem |> CommitOperationResult + let fref = rfinfo.RecdFieldRef + let fieldTy = rfinfo.FieldType + match delayed with + | DelayedSet(e2, mStmt) :: otherDelayed -> + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + + // Set static F# field + CheckRecdFieldMutation mItem env.DisplayEnv rfinfo + UnifyTypes cenv env mStmt overallTy.Commit g.unit_ty + let fieldTy = rfinfo.FieldType + // Always allow subsumption on assignment to fields + let e2', tpenv = TcExprFlex cenv true false fieldTy env tpenv e2 + let expr = mkStaticRecdFieldSet (rfinfo.RecdFieldRef, rfinfo.TypeInst, e2', mStmt) + expr, tpenv + | _ -> + let exprty = fieldTy + let expr = + match rfinfo.LiteralValue with + // Get literal F# field + | Some lit -> Expr.Const (lit, mItem, exprty) + // Get static F# field + | None -> mkStaticRecdFieldGet (fref, rfinfo.TypeInst, mItem) + PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed + + | Item.Event einfo -> + // Instance IL event (fake up event-as-value) + TcEventValueThen cenv overallTy env tpenv mItem mItem None einfo delayed + + | Item.CustomOperation (nm, usageTextOpt, _) -> + // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body + RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed + match usageTextOpt() with + | None -> error(Error(FSComp.SR.tcCustomOperationNotUsedCorrectly nm, mItem)) + | Some usageText -> error(Error(FSComp.SR.tcCustomOperationNotUsedCorrectly2(nm, usageText), mItem)) + | _ -> error(Error(FSComp.SR.tcLookupMayNotBeUsedHere(), mItem)) + + +//------------------------------------------------------------------------- +// Typecheck "expr.A.B.C ... " constructs +//------------------------------------------------------------------------- + +and GetSynMemberApplicationArgs delayed tpenv = + match delayed with + | DelayedApp (atomicFlag, _, _, arg, _) :: otherDelayed -> + atomicFlag, None, [arg], otherDelayed, tpenv + | DelayedTypeApp(tyargs, mTypeArgs, _) :: DelayedApp (atomicFlag, _, _, arg, _mExprAndArg) :: otherDelayed -> + (atomicFlag, Some (tyargs, mTypeArgs), [arg], otherDelayed, tpenv) + | DelayedTypeApp(tyargs, mTypeArgs, _) :: otherDelayed -> + (ExprAtomicFlag.Atomic, Some (tyargs, mTypeArgs), [], otherDelayed, tpenv) + | otherDelayed -> + (ExprAtomicFlag.NonAtomic, None, [], otherDelayed, tpenv) + + +and TcMemberTyArgsOpt cenv env tpenv tyargsOpt = + match tyargsOpt with + | None -> None, tpenv + | Some (tyargs, mTypeArgs) -> + let tyargsChecked, tpenv = TcTypesOrMeasures None cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tyargs mTypeArgs + Some tyargsChecked, tpenv + +and GetMemberApplicationArgs delayed cenv env tpenv = + let atomicFlag, tyargsOpt, args, delayed, tpenv = GetSynMemberApplicationArgs delayed tpenv + let tyArgsOptChecked, tpenv = TcMemberTyArgsOpt cenv env tpenv tyargsOpt + atomicFlag, tyArgsOptChecked, args, delayed, tpenv + +and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId delayed mExprAndLongId = + let objArgs = [objExpr] + let ad = env.eAccessRights + + // 'base' calls use a different resolution strategy when finding methods. + let findFlag = + let baseCall = IsBaseCall objArgs + (if baseCall then PreferOverrides else IgnoreOverrides) + + // Canonicalize inference problem prior to '.' lookup on variable types + if isTyparTy cenv.g objExprTy then + CanonicalizePartialInferenceProblem cenv.css env.DisplayEnv mExprAndLongId (freeInTypeLeftToRight cenv.g false objExprTy) + + let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver mExprAndLongId ad env.NameEnv objExprTy longId TypeNameResolutionInfo.Default findFlag false + let mExprAndItem = unionRanges mObjExpr mItem + let delayed = delayRest rest mExprAndItem delayed + + match item with + | Item.MethodGroup (methodName, minfos, _) -> + let atomicFlag, tyargsOpt, args, delayed, tpenv = GetSynMemberApplicationArgs delayed tpenv + // We pass PossiblyMutates here because these may actually mutate a value type object + // To get better warnings we special case some of the few known mutate-a-struct method names + let mutates = (if methodName = "MoveNext" || methodName = "GetNextArg" then DefinitelyMutates else PossiblyMutates) + +#if !NO_EXTENSIONTYPING + match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, tyargsOpt, mExprAndItem, mItem) with + | Some minfoAfterStaticArguments -> + // Replace the resolution including the static parameters, plus the extra information about the original method info + let item = Item.MethodGroup(methodName, [minfoAfterStaticArguments], Some minfos.[0]) + CallNameResolutionSinkReplacing cenv.tcSink (mExprAndItem, env.NameEnv, item, [], ItemOccurence.Use, env.eAccessRights) + + TcMethodApplicationThen cenv env overallTy None tpenv None objArgs mExprAndItem mItem methodName ad mutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse args atomicFlag delayed + | None -> + if not minfos.IsEmpty && minfos.[0].ProvidedStaticParameterInfo.IsSome then + error(Error(FSComp.SR.etMissingStaticArgumentsToMethod(), mItem)) +#endif + + let tyargsOpt, tpenv = TcMemberTyArgsOpt cenv env tpenv tyargsOpt + let meths = minfos |> List.map (fun minfo -> minfo, None) + + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem methodName ad mutates false meths afterResolution NormalValUse args atomicFlag delayed + + | Item.Property (nm, pinfos) -> + // Instance property + if isNil pinfos then error (InternalError ("Unexpected error: empty property list", mItem)) + // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. + // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed + let pinfo = List.head pinfos + let atomicFlag, tyargsOpt, args, delayed, tpenv = + if pinfo.IsIndexer + then GetMemberApplicationArgs delayed cenv env tpenv + else ExprAtomicFlag.Atomic, None, [mkSynUnit mItem], delayed, tpenv + if pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsStatic nm, mItem)) + + + match delayed with + | DelayedSet(e2, mStmt) :: otherDelayed -> + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + // Instance property setter + UnifyTypes cenv env mStmt overallTy.Commit cenv.g.unit_ty + let meths = SettersOfPropInfos pinfos + if meths.IsEmpty then + let meths = pinfos |> GettersOfPropInfos + let isByrefMethReturnSetter = meths |> List.exists (function _,Some pinfo -> isByrefTy cenv.g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false) + if not isByrefMethReturnSetter then + errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) + // x.P <- ... byref setter + if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed + else + let args = if pinfo.IsIndexer then args else [] + let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mStmt mItem nm ad mut true meths afterResolution NormalValUse (args @ [e2]) atomicFlag [] + | _ -> + // Instance property getter + let meths = GettersOfPropInfos pinfos + if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) + TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed + + | Item.RecdField rfinfo -> + // Get or set instance F# field or literal + RecdFieldInstanceChecks cenv.g cenv.amap ad mItem rfinfo + let tgtTy = rfinfo.DeclaringType + let valu = isStructTy cenv.g tgtTy + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgtTy objExprTy + let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, mExprAndItem, objExprTy) + let fieldTy = rfinfo.FieldType + match delayed with + | DelayedSet(e2, mStmt) :: otherDelayed -> + // Mutable value set: 'v <- e' + if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mItem)) + CheckRecdFieldMutation mItem env.DisplayEnv rfinfo + UnifyTypes cenv env mStmt overallTy.Commit cenv.g.unit_ty + // Always allow subsumption on assignment to fields + let e2', tpenv = TcExprFlex cenv true false fieldTy env tpenv e2 + BuildRecdFieldSet cenv.g mStmt objExpr rfinfo e2', tpenv + + | _ -> + + // Instance F# Record or Class field + let objExpr' = mkRecdFieldGet cenv.g (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, mExprAndItem) + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed + + | Item.AnonRecdField (anonInfo, tinst, n, _) -> + let tgty = TType_anon (anonInfo, tinst) + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgty objExprTy + let fieldTy = List.item n tinst + match delayed with + | DelayedSet _ :: _otherDelayed -> + error(Error(FSComp.SR.tcInvalidAssignment(),mItem)) + | _ -> + // Instance F# Anonymous Record + let objExpr' = mkAnonRecdFieldGet cenv.g (anonInfo,objExpr,tinst,n,mExprAndItem) + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed + + | Item.ILField finfo -> + // Get or set instance IL field + ILFieldInstanceChecks cenv.g cenv.amap ad mItem finfo + let exprty = finfo.FieldType(cenv.amap, mItem) + + match delayed with + // Set instance IL field + | DelayedSet(e2, mStmt) :: _delayed' -> + UnifyTypes cenv env mStmt overallTy.Commit cenv.g.unit_ty + // Always allow subsumption on assignment to fields + let e2', tpenv = TcExprFlex cenv true false exprty env tpenv e2 + let expr = BuildILFieldSet cenv.g mStmt objExpr finfo e2' + expr, tpenv + | _ -> + let expr = BuildILFieldGet cenv.g cenv.amap mExprAndItem objExpr finfo + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed + + | Item.Event einfo -> + // Instance IL event (fake up event-as-value) + TcEventValueThen cenv overallTy env tpenv mItem mExprAndItem (Some(objExpr, objExprTy)) einfo delayed + + | Item.FakeInterfaceCtor _ | Item.DelegateCtor _ -> error (Error (FSComp.SR.tcConstructorsCannotBeFirstClassValues(), mItem)) + | _ -> error (Error (FSComp.SR.tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields(), mItem)) + +and TcEventValueThen cenv overallTy env tpenv mItem mExprAndItem objDetails (einfo: EventInfo) delayed = + // Instance IL event (fake up event-as-value) + let nm = einfo.EventName + let ad = env.eAccessRights + match objDetails, einfo.IsStatic with + | Some _, true -> error (Error (FSComp.SR.tcEventIsStatic nm, mItem)) + | None, false -> error (Error (FSComp.SR.tcEventIsNotStatic nm, mItem)) + | _ -> () + + let delegateType = einfo.GetDelegateType(cenv.amap, mItem) + let (SigOfFunctionForDelegate(invokeMethInfo, compiledViewOfDelArgTys, _, _)) = GetSigOfFunctionForDelegate cenv.infoReader delegateType mItem ad + let objArgs = Option.toList (Option.map fst objDetails) + MethInfoChecks cenv.g cenv.amap true None objArgs env.eAccessRights mItem invokeMethInfo + + // This checks for and drops the 'object' sender + let argsTy = ArgsTypOfEventInfo cenv.infoReader mItem ad einfo + if not (slotSigHasVoidReturnTy (invokeMethInfo.GetSlotSig(cenv.amap, mItem))) then errorR (nonStandardEventError einfo.EventName mItem) + let delEventTy = mkIEventType cenv.g delegateType argsTy + + let bindObjArgs f = + match objDetails with + | None -> f [] + | Some (objExpr, objExprTy) -> mkCompGenLetIn mItem "eventTarget" objExprTy objExpr (fun (_, ve) -> f [ve]) + + // Bind the object target expression to make sure we only run its side effects once, and to make + // sure if it's a mutable reference then we dereference it - see FSharp 1.0 bug 942 + let expr = + bindObjArgs (fun objVars -> + // EventHelper ((fun d -> e.add_X(d)), (fun d -> e.remove_X(d)), (fun f -> new 'Delegate(f))) + mkCallCreateEvent cenv.g mItem delegateType argsTy + (let dv, de = mkCompGenLocal mItem "eventDelegate" delegateType + let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.AddMethod NormalValUse [] objVars [de] + mkLambda mItem dv (callExpr, cenv.g.unit_ty)) + (let dv, de = mkCompGenLocal mItem "eventDelegate" delegateType + let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.RemoveMethod NormalValUse [] objVars [de] + mkLambda mItem dv (callExpr, cenv.g.unit_ty)) + (let fvty = (cenv.g.obj_ty --> (argsTy --> cenv.g.unit_ty)) + let fv, fe = mkCompGenLocal mItem "callback" fvty + let createExpr = BuildNewDelegateExpr (Some einfo, cenv.g, cenv.amap, delegateType, invokeMethInfo, compiledViewOfDelArgTys, fe, fvty, mItem) + mkLambda mItem fv (createExpr, delegateType))) + + let exprty = delEventTy + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprNoFlex cenv expr) exprty ExprAtomicFlag.Atomic delayed + + +//------------------------------------------------------------------------- +// Method uses can calls +//------------------------------------------------------------------------- + +/// Typecheck method/member calls and uses of members as first-class values. +and TcMethodApplicationThen + cenv + env + // The type of the overall expression including "delayed". The method "application" may actually be a use of a member as + // a first-class function value, when this would be a function type. + (overallTy: OverallTy) + objTyOpt // methodType + tpenv + callerTyArgs // The return type of the overall expression including "delayed" + objArgs // The 'obj' arguments in obj.M(...) and obj.M, if any + m // The range of the object argument or whole application. We immediately union this with the range of the arguments + mItem // The range of the item that resolved to the method name + methodName // string, name of the method + ad // accessibility rights of the caller + mut // what do we know/assume about whether this method will mutate or not? + isProp // is this a property call? Used for better error messages and passed to BuildMethodCall + meths // the set of methods we may be calling + afterResolution // do we need to notify sink after overload resolution + isSuperInit // is this a special invocation, e.g. a super-class constructor call. Passed through to BuildMethodCall + args // the _syntactic_ method arguments, not yet type checked. + atomicFlag // is the expression atomic or not? + delayed // further lookups and applications that follow this + = + + // Nb. args is always of List.length <= 1 except for indexed setters, when it is 2 + let mWholeExpr = (m, args) ||> List.fold (fun m arg -> unionRanges m arg.Range) + + // Work out if we know anything about the return type of the overall expression. If there are any delayed + // lookups then we don't know anything. + let exprTy = if isNil delayed then overallTy else MustEqual (NewInferenceType ()) + + // Call the helper below to do the real checking + let (expr, attributeAssignedNamedItems, delayed), tpenv = + TcMethodApplication false cenv env tpenv callerTyArgs objArgs mWholeExpr mItem methodName objTyOpt ad mut isProp meths afterResolution isSuperInit args exprTy delayed + + // Give errors if some things couldn't be assigned + if not (isNil attributeAssignedNamedItems) then + let (CallerNamedArg(id, _)) = List.head attributeAssignedNamedItems + errorR(Error(FSComp.SR.tcNamedArgumentDidNotMatch(id.idText), id.idRange)) + + + // Resolve the "delayed" lookups + let exprty = (tyOfExpr cenv.g expr) + + PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr (MakeApplicableExprNoFlex cenv expr) exprty atomicFlag delayed + +/// Infer initial type information at the callsite from the syntax of an argument, prior to overload resolution. +and GetNewInferenceTypeForMethodArg cenv env tpenv x = + match x with + | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a + | SynExpr.AddressOf (true, a, _, m) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewByRefKindInferenceType cenv.g m) + | SynExpr.Lambda (body = a) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) + | SynExpr.Quote (_, raw, a, _, _) -> + if raw then mkRawQuotedExprTy cenv.g + else mkQuotedExprTy cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) + | _ -> NewInferenceType () + +/// Method calls, property lookups, attribute constructions etc. get checked through here +and TcMethodApplication + isCheckingAttributeCall + cenv + env + tpenv + tyargsOpt + objArgs + mMethExpr // range of the entire method expression + mItem + methodName + (objTyOpt: TType option) + ad + mut + isProp + calledMethsAndProps + afterResolution + isSuperInit + curriedCallerArgs + (exprTy: OverallTy) + delayed + = + + let denv = env.DisplayEnv + + let isSimpleFormalArg (isParamArrayArg, _isInArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfo: CallerInfo, _reflArgInfo: ReflectedArgInfo) = + not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfo = NoCallerInfo + + let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g) + + let calledMeths = calledMethsAndProps |> List.map fst + + // Uses of curried members are ALWAYS treated as if they are first class uses of members. + // Curried members may not be overloaded (checked at use-site for curried members brought into scope through extension members) + let curriedCallerArgs, exprTy, delayed = + match calledMeths with + | [calledMeth] when not isProp && calledMeth.NumArgs.Length > 1 -> + [], MustEqual (NewInferenceType ()), [ for x in curriedCallerArgs -> DelayedApp(ExprAtomicFlag.NonAtomic, false, None, x, x.Range) ] @ delayed + | _ when not isProp && calledMeths |> List.exists (fun calledMeth -> calledMeth.NumArgs.Length > 1) -> + // This condition should only apply when multiple conflicting curried extension members are brought into scope + error(Error(FSComp.SR.tcOverloadsCannotHaveCurriedArguments(), mMethExpr)) + | _ -> + curriedCallerArgs, exprTy, delayed + + let candidateMethsAndProps = + match calledMethsAndProps |> List.filter (fun (meth, _prop) -> IsMethInfoAccessible cenv.amap mItem ad meth) with + | [] -> calledMethsAndProps + | accessibleMeths -> accessibleMeths + + let candidates = candidateMethsAndProps |> List.map fst + + + // Split the syntactic arguments (if any) into named and unnamed parameters + // + // In one case (the second "single named item" rule) we delay the application of a + // argument until we've produced a lambda that detuples an input tuple + let curriedCallerArgsOpt, unnamedDelayedCallerArgExprOpt, exprTy = + match curriedCallerArgs with + | [] -> + None, None, exprTy + | _ -> + let unnamedCurriedCallerArgs, namedCurriedCallerArgs = curriedCallerArgs |> List.map GetMethodArgs |> List.unzip + + // There is an mismatch when _uses_ of indexed property setters in the tc.fs code that calls this function. + // The arguments are passed as if they are curried with arity [numberOfIndexParameters;1], however in the TAST, indexed property setters + // are uncurried and have arity [numberOfIndexParameters+1]. + // + // Here we work around this mismatch by crunching all property argument lists to uncurried form. + // Ideally the problem needs to be solved at its root cause at the callsites to this function + let unnamedCurriedCallerArgs, namedCurriedCallerArgs = + if isProp then + [List.concat unnamedCurriedCallerArgs], [List.concat namedCurriedCallerArgs] + else + unnamedCurriedCallerArgs, namedCurriedCallerArgs + + let MakeUnnamedCallerArgInfo x = (x, GetNewInferenceTypeForMethodArg cenv env tpenv x, x.Range) + + // "single named item" rule. This is where we have a single accessible method + // member x.M(arg1) + // being used with + // x.M (x, y) + // Without this rule this requires + // x.M ((x, y)) + match candidates with + | [calledMeth] + when (namedCurriedCallerArgs |> List.forall isNil && + let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) + curriedCalledArgs.Length = 1 && + curriedCalledArgs.Head.Length = 1 && + curriedCalledArgs.Head.Head |> isSimpleFormalArg) -> + let unnamedCurriedCallerArgs = curriedCallerArgs |> List.map (MakeUnnamedCallerArgInfo >> List.singleton) + let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.map (fun _ -> []) + (Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy) + + // "single named item" rule. This is where we have a single accessible method + // member x.M(arg1, arg2) + // being used with + // x.M p + // We typecheck this as if it has been written "(fun (v1, v2) -> x.M(v1, v2)) p" + // Without this rule this requires + // x.M (fst p, snd p) + | [calledMeth] + when (namedCurriedCallerArgs |> List.forall isNil && + unnamedCurriedCallerArgs.Length = 1 && + unnamedCurriedCallerArgs.Head.Length = 1 && + let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) + curriedCalledArgs.Length = 1 && + curriedCalledArgs.Head.Length > 1 && + curriedCalledArgs.Head |> List.forall isSimpleFormalArg) -> + + // The call lambda has function type + let exprTy = mkFunTy (NewInferenceType ()) exprTy.Commit + + (None, Some unnamedCurriedCallerArgs.Head.Head, MustEqual exprTy) + + | _ -> + let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared MakeUnnamedCallerArgInfo + let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (isOpt, nm, x) -> + let ty = GetNewInferenceTypeForMethodArg cenv env tpenv x + // #435263: compiler crash with .net optional parameters and F# optional syntax + // named optional arguments should always have option type + // STRUCT OPTIONS: if we allow struct options as optional arguments then we should relax this and rely + // on later inference to work out if this is a struct option or ref option + let ty = if isOpt then mkOptionTy denv.g ty else ty + nm, isOpt, x, ty, x.Range) + + (Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy) + + let CalledMethHasSingleArgumentGroupOfThisLength n (calledMeth: MethInfo) = + let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem) + curriedMethodArgAttribs.Length = 1 && + curriedMethodArgAttribs.Head.Length = n + + let GenerateMatchingSimpleArgumentTypes (calledMeth: MethInfo) = + let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem) + curriedMethodArgAttribs + |> List.map (List.filter isSimpleFormalArg >> NewInferenceTypes) + + let UnifyMatchingSimpleArgumentTypes exprTy (calledMeth: MethInfo) = + let curriedArgTys = GenerateMatchingSimpleArgumentTypes calledMeth + let returnTy = + (exprTy, curriedArgTys) ||> List.fold (fun exprTy argTys -> + let domainTy, resultTy = UnifyFunctionType None cenv denv mMethExpr exprTy + UnifyTypes cenv env mMethExpr domainTy (mkRefTupledTy cenv.g argTys) + resultTy) + curriedArgTys, returnTy + + if isProp && Option.isNone curriedCallerArgsOpt then + error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(), mItem)) + + // STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments. + // Extract what we know about the caller arguments, either type-directed if + // no arguments are given or else based on the syntax of the arguments. + let uniquelyResolved, preArgumentTypeCheckingCalledMethGroup = + let dummyExpr = mkSynUnit mItem + + // Build the CallerArg values for the caller's arguments. + // Fake up some arguments if this is the use of a method as a first class function + let unnamedCurriedCallerArgs, namedCurriedCallerArgs, returnTy = + + match curriedCallerArgsOpt, candidates with + // "single named item" rule. This is where we have a single accessible method + // member x.M(arg1, ..., argN) + // being used in a first-class way, i.e. + // x.M + // Because there is only one accessible method info available based on the name of the item + // being accessed we know the number of arguments the first class use of this + // method will take. Optional and out args are _not_ included, which means they will be resolved + // to their default values (for optionals) and be part of the return tuple (for out args). + | None, [calledMeth] -> + let curriedArgTys, returnTy = UnifyMatchingSimpleArgumentTypes exprTy.Commit calledMeth + let unnamedCurriedCallerArgs = curriedArgTys |> List.mapSquared (fun ty -> CallerArg(ty, mMethExpr, false, dummyExpr)) + let namedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.map (fun _ -> []) + unnamedCurriedCallerArgs, namedCurriedCallerArgs, MustEqual returnTy + + // "type directed" rule for first-class uses of ambiguous methods. + // By context we know a type for the input argument. If it's a tuple + // this gives us the a potential number of arguments expected. Indeed even if it's a variable + // type we assume the number of arguments is just "1". + | None, _ -> + + let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy.Commit + let argTys = if isUnitTy cenv.g domainTy then [] else tryDestRefTupleTy cenv.g domainTy + // Only apply this rule if a candidate method exists with this number of arguments + let argTys = + if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then + argTys + else + [domainTy] + let unnamedCurriedCallerArgs = [argTys |> List.map (fun ty -> CallerArg(ty, mMethExpr, false, dummyExpr)) ] + let namedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.map (fun _ -> []) + unnamedCurriedCallerArgs, namedCurriedCallerArgs, MustEqual returnTy + + | Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), _ -> + let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared (fun (argExpr, argTy, mArg) -> CallerArg(argTy, mArg, false, argExpr)) + let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (id, isOpt, argExpr, argTy, mArg) -> CallerNamedArg(id, CallerArg(argTy, mArg, isOpt, argExpr))) + unnamedCurriedCallerArgs, namedCurriedCallerArgs, exprTy + + let callerArgCounts = (List.sumBy List.length unnamedCurriedCallerArgs, List.sumBy List.length namedCurriedCallerArgs) + + let callerArgs = { Unnamed = unnamedCurriedCallerArgs; Named = namedCurriedCallerArgs } + + let makeOneCalledMeth (minfo, pinfoOpt, usesParamArrayConversion) = + let minst = FreshenMethInfo mItem minfo + let callerTyArgs = + match tyargsOpt with + | Some tyargs -> minfo.AdjustUserTypeInstForFSharpStyleIndexedExtensionMembers tyargs + | None -> minst + CalledMeth(cenv.infoReader, Some(env.NameEnv), isCheckingAttributeCall, FreshenMethInfo, mMethExpr, ad, minfo, minst, callerTyArgs, pinfoOpt, callerObjArgTys, callerArgs, usesParamArrayConversion, true, objTyOpt) + + let preArgumentTypeCheckingCalledMethGroup = + [ for minfo, pinfoOpt in candidateMethsAndProps do + let meth = makeOneCalledMeth (minfo, pinfoOpt, true) + yield meth + if meth.UsesParamArrayConversion then + yield makeOneCalledMeth (minfo, pinfoOpt, false) ] + + let uniquelyResolved = + UnifyUniqueOverloading denv cenv.css mMethExpr callerArgCounts methodName ad preArgumentTypeCheckingCalledMethGroup returnTy + + uniquelyResolved, preArgumentTypeCheckingCalledMethGroup + + // STEP 2. Type check arguments + let unnamedCurriedCallerArgs, namedCurriedCallerArgs, lambdaVars, returnTy, tpenv = + + // STEP 2a. First extract what we know about the caller arguments, either type-directed if + // no arguments are given or else based on the syntax of the arguments. + match curriedCallerArgsOpt with + | None -> + let curriedArgTys, returnTy = + match candidates with + // "single named item" rule. This is where we have a single accessible method + // member x.M(arg1, ..., argN) + // being used in a first-class way, i.e. + // x.M + // Because there is only one accessible method info available based on the name of the item + // being accessed we know the number of arguments the first class use of this + // method will take. Optional and out args are _not_ included, which means they will be resolved + // to their default values (for optionals) and be part of the return tuple (for out args). + | [calledMeth] -> + let curriedArgTys, returnTy = UnifyMatchingSimpleArgumentTypes exprTy.Commit calledMeth + curriedArgTys, MustEqual returnTy + | _ -> + let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy.Commit + let argTys = if isUnitTy cenv.g domainTy then [] else tryDestRefTupleTy cenv.g domainTy + // Only apply this rule if a candidate method exists with this number of arguments + let argTys = + if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then + argTys + else + [domainTy] + [argTys], MustEqual returnTy + + let lambdaVarsAndExprs = curriedArgTys |> List.mapiSquared (fun i j ty -> mkCompGenLocal mMethExpr ("arg"+string i+string j) ty) + let unnamedCurriedCallerArgs = lambdaVarsAndExprs |> List.mapSquared (fun (_, e) -> CallerArg(tyOfExpr cenv.g e, e.Range, false, e)) + let namedCurriedCallerArgs = lambdaVarsAndExprs |> List.map (fun _ -> []) + let lambdaVars = List.mapSquared fst lambdaVarsAndExprs + unnamedCurriedCallerArgs, namedCurriedCallerArgs, Some lambdaVars, returnTy, tpenv + + | Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs) -> + // This is the case where some explicit arguments have been given. + + let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared (fun (argExpr, argTy, mArg) -> CallerArg(argTy, mArg, false, argExpr)) + let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (id, isOpt, argExpr, argTy, mArg) -> CallerNamedArg(id, CallerArg(argTy, mArg, isOpt, argExpr))) + + // Collect the information for F# 3.1 lambda propagation rule, and apply the caller's object type to the method's object type if the rule is relevant. + let lambdaPropagationInfo = + if preArgumentTypeCheckingCalledMethGroup.Length > 1 then + [| for meth in preArgumentTypeCheckingCalledMethGroup do + match ExamineMethodForLambdaPropagation meth ad with + | Some (unnamedInfo, namedInfo) -> + let calledObjArgTys = meth.CalledObjArgTys mMethExpr + if (calledObjArgTys, callerObjArgTys) ||> Seq.forall2 (fun calledTy callerTy -> AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed denv cenv.css mMethExpr calledTy callerTy) then + yield (List.toArraySquared unnamedInfo, List.toArraySquared namedInfo) + | None -> () |] + else + [| |] + + // Now typecheck the argument expressions + let unnamedCurriedCallerArgs, (lambdaPropagationInfo, tpenv) = TcUnnamedMethodArgs cenv env lambdaPropagationInfo tpenv unnamedCurriedCallerArgs + let namedCurriedCallerArgs, (_, tpenv) = TcMethodNamedArgs cenv env lambdaPropagationInfo tpenv namedCurriedCallerArgs + unnamedCurriedCallerArgs, namedCurriedCallerArgs, None, exprTy, tpenv + + let preArgumentTypeCheckingCalledMethGroup = + preArgumentTypeCheckingCalledMethGroup |> List.map (fun cmeth -> (cmeth.Method, cmeth.CalledTyArgs, cmeth.AssociatedPropertyInfo, cmeth.UsesParamArrayConversion)) + + let uniquelyResolved = + match uniquelyResolved with + | ErrorResult _ -> + match afterResolution with + | AfterResolution.DoNothing -> () + | AfterResolution.RecordResolution(_, _, _, onFailure) -> onFailure() + | _ -> () + + uniquelyResolved |> CommitOperationResult + + // STEP 3. Resolve overloading + /// Select the called method that's the result of overload resolution + let finalCalledMeth = + + let callerArgs = { Unnamed = unnamedCurriedCallerArgs ; Named = namedCurriedCallerArgs } + + let postArgumentTypeCheckingCalledMethGroup = + preArgumentTypeCheckingCalledMethGroup |> List.map (fun (minfo: MethInfo, minst, pinfoOpt, usesParamArrayConversion) -> + let callerTyArgs = + match tyargsOpt with + | Some tyargs -> minfo.AdjustUserTypeInstForFSharpStyleIndexedExtensionMembers tyargs + | None -> minst + CalledMeth(cenv.infoReader, Some(env.NameEnv), isCheckingAttributeCall, FreshenMethInfo, mMethExpr, ad, minfo, minst, callerTyArgs, pinfoOpt, callerObjArgTys, callerArgs, usesParamArrayConversion, true, objTyOpt)) + + // Commit unassociated constraints prior to member overload resolution where there is ambiguity + // about the possible target of the call. + if not uniquelyResolved then + CanonicalizePartialInferenceProblem cenv.css denv mItem + (unnamedCurriedCallerArgs |> List.collectSquared (fun callerArg -> freeInTypeLeftToRight cenv.g false callerArg.CallerArgumentType)) + + let result, errors = ResolveOverloadingForCall denv cenv.css mMethExpr methodName 0 None callerArgs ad postArgumentTypeCheckingCalledMethGroup true (Some returnTy) + + match afterResolution, result with + | AfterResolution.DoNothing, _ -> () + + // Record the precise override resolution + | AfterResolution.RecordResolution(Some unrefinedItem, _, callSink, _), Some result + when result.Method.IsVirtual -> + + let overriding = + match unrefinedItem with + | Item.MethodGroup(_, overridenMeths, _) -> overridenMeths |> List.map (fun minfo -> minfo, None) + | Item.Property(_, pinfos) -> + if result.Method.LogicalName.StartsWithOrdinal("set_") then + SettersOfPropInfos pinfos + else + GettersOfPropInfos pinfos + | _ -> [] + + let overridingInfo = + overriding + |> List.tryFind (fun (minfo, _) -> minfo.IsVirtual && MethInfosEquivByNameAndSig EraseNone true cenv.g cenv.amap range0 result.Method minfo) + + match overridingInfo with + | Some (minfo, pinfoOpt) -> + let tps = minfo.FormalMethodTypars + let tyargs = result.CalledTyArgs + let tpinst = if tps.Length = tyargs.Length then mkTyparInst tps tyargs else [] + (minfo, pinfoOpt, tpinst) |> callSink + | None -> + (result.Method, result.AssociatedPropertyInfo, result.CalledTyparInst) |> callSink + + // Record the precise overload resolution and the type instantiation + | AfterResolution.RecordResolution(_, _, callSink, _), Some result -> + (result.Method, result.AssociatedPropertyInfo, result.CalledTyparInst) |> callSink + + | AfterResolution.RecordResolution(_, _, _, onFailure), None -> + onFailure() + + // Raise the errors from the constraint solving + RaiseOperationResult errors + match result with + | None -> error(InternalError("at least one error should be returned by failed method overloading", mItem)) + | Some res -> res + + let finalCalledMethInfo = finalCalledMeth.Method + let finalCalledMethInst = finalCalledMeth.CalledTyArgs + let finalAssignedItemSetters = finalCalledMeth.AssignedItemSetters + let finalAttributeAssignedNamedItems = finalCalledMeth.AttributeAssignedNamedArgs + + // STEP 4. Check the attributes on the method and the corresponding event/property, if any + + finalCalledMeth.AssociatedPropertyInfo |> Option.iter (fun pinfo -> CheckPropInfoAttributes pinfo mItem |> CommitOperationResult) + + let isInstance = not (isNil objArgs) + MethInfoChecks cenv.g cenv.amap isInstance tyargsOpt objArgs ad mItem finalCalledMethInfo + + // Adhoc constraints on use of .NET methods + begin + // Uses of Object.GetHashCode and Object.Equals imply an equality constraint on the object argument + // + if (isInstance && + finalCalledMethInfo.IsInstance && + typeEquiv cenv.g finalCalledMethInfo.ApparentEnclosingType cenv.g.obj_ty && + (finalCalledMethInfo.LogicalName = "GetHashCode" || finalCalledMethInfo.LogicalName = "Equals")) then + + objArgs |> List.iter (fun expr -> AddCxTypeMustSupportEquality env.DisplayEnv cenv.css mMethExpr NoTrace (tyOfExpr cenv.g expr)) + + // Uses of a Dictionary() constructor without an IEqualityComparer argument imply an equality constraint + // on the first type argument. + if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType && + finalCalledMethInfo.IsConstructor && + not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CalledTyArgs) + |> List.existsSquared (fun (ParamData(_, _, _, _, _, _, _, ty)) -> + HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_IEqualityComparer ty)) then + + match argsOfAppTy cenv.g finalCalledMethInfo.ApparentEnclosingType with + | [dty; _] -> AddCxTypeMustSupportEquality env.DisplayEnv cenv.css mMethExpr NoTrace dty + | _ -> () + end + + if not finalCalledMeth.IsIndexParamArraySetter && + (finalCalledMeth.ArgSets |> List.existsi (fun i argSet -> argSet.UnnamedCalledArgs |> List.existsi (fun j ca -> ca.Position <> (i, j)))) then + errorR(Deprecated(FSComp.SR.tcUnnamedArgumentsDoNotFormPrefix(), mMethExpr)) + + /// STEP 5. Build the argument list. Adjust for optional arguments, byref arguments and coercions. + + let objArgPreBinder, objArgs, allArgsPreBinders, allArgs, allArgsCoerced, optArgPreBinder, paramArrayPreBinders, outArgExprs, outArgTmpBinds = + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + AdjustCallerArgs tcVal TcFieldInit env.eCallerMemberName cenv.infoReader ad finalCalledMeth objArgs lambdaVars mItem mMethExpr + + // Record the resolution of the named argument for the Language Service + allArgs |> List.iter (fun assignedArg -> + match assignedArg.NamedArgIdOpt with + | None -> () + | Some id -> + let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method finalCalledMethInfo)) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad)) + + + /// STEP 6. Build the call expression, then adjust for byref-returns, out-parameters-as-tuples, post-hoc property assignments, methods-as-first-class-value, + /// + + let callExpr0, exprty = + BuildPossiblyConditionalMethodCall cenv env mut mMethExpr isProp finalCalledMethInfo isSuperInit finalCalledMethInst objArgs allArgsCoerced + + // Handle byref returns + let callExpr1, exprty = + // byref-typed returns get implicitly dereferenced + let vty = tyOfExpr cenv.g callExpr0 + if isByrefTy cenv.g vty then + mkDerefAddrExpr mMethExpr callExpr0 mMethExpr vty, destByrefTy cenv.g vty + else + callExpr0, exprty + + // Bind "out" parameters as part of the result tuple + let callExpr2, exprty = + let expr = callExpr1 + if isNil outArgTmpBinds then expr, exprty + else + let outArgTys = outArgExprs |> List.map (tyOfExpr cenv.g) + let expr = + if isUnitTy cenv.g exprty then + mkCompGenSequential mMethExpr expr (mkRefTupled cenv.g mMethExpr outArgExprs outArgTys) + else + mkRefTupled cenv.g mMethExpr (expr :: outArgExprs) (exprty :: outArgTys) + let expr = mkLetsBind mMethExpr outArgTmpBinds expr + expr, tyOfExpr cenv.g expr + + // Subsumption or conversion to return type + let callExpr2b = TcAdjustExprForTypeDirectedConversions cenv returnTy exprty env mMethExpr callExpr2 + + // Handle post-hoc property assignments + let setterExprPrebinders, callExpr3 = + let expr = callExpr2b + if isCheckingAttributeCall then + [], expr + elif isNil finalAssignedItemSetters then + [], expr + else + // This holds the result of the call + let objv, objExpr = mkMutableCompGenLocal mMethExpr "returnVal" exprty // mutable in case it's a struct + + // Build the expression that mutates the properties on the result of the call + let setterExprPrebinders, propSetExpr = + (mkUnit cenv.g mMethExpr, finalAssignedItemSetters) ||> List.mapFold (fun acc assignedItemSetter -> + let argExprPrebinder, action, m = TcSetterArgExpr cenv env denv objExpr ad assignedItemSetter + argExprPrebinder, mkCompGenSequential m acc action) + + // now put them together + let expr = mkCompGenLet mMethExpr objv expr (mkCompGenSequential mMethExpr propSetExpr objExpr) + setterExprPrebinders, expr + + // Build the lambda expression if any, if the method is used as a first-class value + let callExpr4 = + let expr = callExpr3 + match lambdaVars with + | None -> expr + | Some curriedLambdaVars -> + let mkLambda vs expr = + match vs with + | [] -> mkUnitDelayLambda cenv.g mMethExpr expr + | _ -> mkMultiLambda mMethExpr vs (expr, tyOfExpr cenv.g expr) + List.foldBack mkLambda curriedLambdaVars expr + + let callExpr5, tpenv = + let expr = callExpr4 + match unnamedDelayedCallerArgExprOpt with + | Some synArgExpr -> + match lambdaVars with + | Some [lambdaVars] -> + let argExpr, tpenv = TcExpr cenv (MustEqual (mkRefTupledVarsTy cenv.g lambdaVars)) env tpenv synArgExpr + mkApps cenv.g ((expr, tyOfExpr cenv.g expr), [], [argExpr], mMethExpr), tpenv + | _ -> + error(InternalError("unreachable - expected some lambda vars for a tuple mismatch", mItem)) + | None -> + expr, tpenv + + // Apply the PreBinders, if any + let callExpr6 = + let expr = callExpr5 + let expr = (expr, setterExprPrebinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) + let expr = (expr, paramArrayPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) + let expr = (expr, allArgsPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) + + let expr = optArgPreBinder expr + let expr = objArgPreBinder expr + expr + + (callExpr6, finalAttributeAssignedNamedItems, delayed), tpenv + +and TcSetterArgExpr cenv env denv objExpr ad (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) = + if isOptCallerArg then error(Error(FSComp.SR.tcInvalidOptionalAssignmentToPropertyOrField(), m)) + + let argExprPrebinder, action, defnItem = + match setter with + | AssignedPropSetter (pinfo, pminfo, pminst) -> + MethInfoChecks cenv.g cenv.amap true None [objExpr] ad m pminfo + let calledArgTy = List.head (List.head (pminfo.GetParamTypes(cenv.amap, m, pminst))) + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExpr tcVal cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr + let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) + let action = BuildPossiblyConditionalMethodCall cenv env mut m true pminfo NormalValUse pminst [objExpr] [argExpr] |> fst + argExprPrebinder, action, Item.Property (pinfo.PropertyName, [pinfo]) + + | AssignedILFieldSetter finfo -> + // Get or set instance IL field + ILFieldInstanceChecks cenv.g cenv.amap ad m finfo + let calledArgTy = finfo.FieldType (cenv.amap, m) + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExpr tcVal cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr + let action = BuildILFieldSet cenv.g m objExpr finfo argExpr + argExprPrebinder, action, Item.ILField finfo + + | AssignedRecdFieldSetter rfinfo -> + RecdFieldInstanceChecks cenv.g cenv.amap ad m rfinfo + let calledArgTy = rfinfo.FieldType + CheckRecdFieldMutation m denv rfinfo + let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g + let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExpr tcVal cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr + let action = BuildRecdFieldSet cenv.g m objExpr rfinfo argExpr + argExprPrebinder, action, Item.RecdField rfinfo + + // Record the resolution for the Language Service + let item = Item.SetterArg (id, defnItem) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad) + + argExprPrebinder, action, m + +and TcUnnamedMethodArgs cenv env lambdaPropagationInfo tpenv args = + List.mapiFoldSquared (TcUnnamedMethodArg cenv env) (lambdaPropagationInfo, tpenv) args + +and TcUnnamedMethodArg cenv env (lambdaPropagationInfo, tpenv) (i, j, CallerArg(argTy, mArg, isOpt, argExpr)) = + // Try to find the lambda propagation info for the corresponding unnamed argument at this position + let lambdaPropagationInfoForArg = + [| for unnamedInfo, _ in lambdaPropagationInfo -> + if i < unnamedInfo.Length && j < unnamedInfo.[i].Length then unnamedInfo.[i].[j] else NoInfo |] + TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, CallerArg(argTy, mArg, isOpt, argExpr)) + +and TcMethodNamedArgs cenv env lambdaPropagationInfo tpenv args = + List.mapFoldSquared (TcMethodNamedArg cenv env) (lambdaPropagationInfo, tpenv) args + +and TcMethodNamedArg cenv env (lambdaPropagationInfo, tpenv) (CallerNamedArg(id, arg)) = + // Try to find the lambda propagation info for the corresponding named argument + let lambdaPropagationInfoForArg = + [| for _, namedInfo in lambdaPropagationInfo -> + namedInfo |> Array.tryPick (fun namedInfoForArgSet -> + namedInfoForArgSet |> Array.tryPick (fun (nm, info) -> + if nm.idText = id.idText then Some info else None)) |] + |> Array.map (fun x -> defaultArg x NoInfo) + + let arg', (lambdaPropagationInfo, tpenv) = TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, arg) + CallerNamedArg(id, arg'), (lambdaPropagationInfo, tpenv) + +and TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, CallerArg(argTy, mArg, isOpt, argExpr)) = + + // Apply the F# 3.1 rule for extracting information for lambdas + // + // Before we check the argument, check to see if we can propagate info from a called lambda expression into the arguments of a received lambda + if lambdaPropagationInfoForArg.Length > 0 then + let allOverloadsAreNotCalledArgMatchesForThisArg = + lambdaPropagationInfoForArg + |> Array.forall (function ArgDoesNotMatch | CallerLambdaHasArgTypes _ | NoInfo -> true | CalledArgMatchesType _ -> false) + + if allOverloadsAreNotCalledArgMatchesForThisArg then + let overloadsWhichAreFuncAtThisPosition = lambdaPropagationInfoForArg |> Array.choose (function CallerLambdaHasArgTypes r -> Some (List.toArray r) | _ -> None) + if overloadsWhichAreFuncAtThisPosition.Length > 0 then + let minFuncArity = overloadsWhichAreFuncAtThisPosition |> Array.minBy Array.length |> Array.length + let prefixOfLambdaArgsForEachOverload = overloadsWhichAreFuncAtThisPosition |> Array.map (Array.take minFuncArity) + + if prefixOfLambdaArgsForEachOverload.Length > 0 then + let numLambdaVars = prefixOfLambdaArgsForEachOverload.[0].Length + // Fold across the lambda var positions checking if all method overloads imply the same argument type for a lambda variable. + // If so, force the caller to have a function type that looks like the calledLambdaArgTy. + // The loop variable callerLambdaTyOpt becomes None if something failed. + let rec loop callerLambdaTy lambdaVarNum = + if lambdaVarNum < numLambdaVars then + let calledLambdaArgTy = prefixOfLambdaArgsForEachOverload.[0].[lambdaVarNum] + let allRowsGiveSameArgumentType = + prefixOfLambdaArgsForEachOverload + |> Array.forall (fun row -> typeEquiv cenv.g calledLambdaArgTy row.[lambdaVarNum]) + + if allRowsGiveSameArgumentType then + // Force the caller to be a function type. + match UnifyFunctionTypeUndoIfFailed cenv env.DisplayEnv mArg callerLambdaTy with + | ValueSome (callerLambdaDomainTy, callerLambdaRangeTy) -> + if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css mArg calledLambdaArgTy callerLambdaDomainTy then + loop callerLambdaRangeTy (lambdaVarNum + 1) + | _ -> () + loop argTy 0 + + let e', tpenv = TcExprFlex2 cenv argTy env true tpenv argExpr + + // After we have checked, propagate the info from argument into the overloads that receive it. + // + // Filter out methods where an argument doesn't match. This just filters them from lambda propagation but not from + // later method overload resolution. + let lambdaPropagationInfo = + [| for info, argInfo in Array.zip lambdaPropagationInfo lambdaPropagationInfoForArg do + match argInfo with + | ArgDoesNotMatch _ -> () + | NoInfo | CallerLambdaHasArgTypes _ -> + yield info + | CalledArgMatchesType adjustedCalledTy -> + if AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed env.DisplayEnv cenv.css mArg adjustedCalledTy argTy then + yield info |] + + CallerArg(argTy, mArg, isOpt, e'), (lambdaPropagationInfo, tpenv) + +/// Typecheck "new Delegate(fun x y z -> ...)" constructs +and TcNewDelegateThen cenv (overallTy: OverallTy) env tpenv mDelTy mExprAndArg delegateTy arg atomicFlag delayed = + let ad = env.eAccessRights + UnifyTypes cenv env mExprAndArg overallTy.Commit delegateTy + let (SigOfFunctionForDelegate(invokeMethInfo, delArgTys, _, fty)) = GetSigOfFunctionForDelegate cenv.infoReader delegateTy mDelTy ad + // We pass isInstance = true here because we're checking the rights to access the "Invoke" method + MethInfoChecks cenv.g cenv.amap true None [] env.eAccessRights mExprAndArg invokeMethInfo + let args = GetMethodArgs arg + match args with + | [farg], [] -> + let m = arg.Range + let callerArg, (_, tpenv) = TcMethodArg cenv env (Array.empty, tpenv) (Array.empty, CallerArg(fty, m, false, farg)) + let expr = BuildNewDelegateExpr (None, cenv.g, cenv.amap, delegateTy, invokeMethInfo, delArgTys, callerArg.Expr, fty, m) + PropagateThenTcDelayed cenv overallTy env tpenv m (MakeApplicableExprNoFlex cenv expr) delegateTy atomicFlag delayed + | _ -> + error(Error(FSComp.SR.tcDelegateConstructorMustBePassed(), mExprAndArg)) + + +and bindLetRec (binds: Bindings) m e = + if isNil binds then + e + else + Expr.LetRec (binds, e, m, Construct.NewFreeVarsCache()) + +/// Check for duplicate bindings in simple recursive patterns +and CheckRecursiveBindingIds binds = + let hashOfBinds = HashSet() + + for SynBinding.SynBinding(_, _, _, _, _, _, _, b, _, _, m, _) in binds do + let nm = + match b with + | SynPat.Named(id, _, _, _) + | SynPat.As(_, SynPat.Named(id, _, _, _), _) + | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) -> id.idText + | _ -> "" + if nm <> "" && not (hashOfBinds.Add nm) then + error(Duplicate("value", nm, m)) + +/// Process a sequence of sequentials mixed with iterated lets "let ... in let ... in ..." in a tail recursive way +/// This avoids stack overflow on really large "let" and "letrec" lists +and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont = + match expr with + | SynExpr.Sequential (sp, true, e1, e2, m) when not isCompExpr -> + let e1', _ = TcStmtThatCantBeCtorBody cenv env tpenv e1 + // tailcall + let env = ShrinkContext env m e2.Range + // tailcall + TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr e2 (fun (e2', tpenv) -> + cont (Expr.Sequential (e1', e2', NormalSeq, sp, m), tpenv)) + + | SynExpr.LetOrUse (isRec, isUse, binds, body, m) when not (isUse && isCompExpr) -> + if isRec then + // TcLinearExprs processes at most one recursive binding, this is not tailcalling + CheckRecursiveBindingIds binds + let binds = List.map (fun x -> RecDefnBindingInfo(ExprContainerInfo, NoNewSlots, ExpressionBinding, x)) binds + if isUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(), m)) + let binds, envinner, tpenv = TcLetrec ErrorOnOverrides cenv env tpenv (binds, m, m) + let bodyExpr, tpenv = bodyChecker overallTy envinner tpenv body + let bodyExpr = bindLetRec binds m bodyExpr + cont (bodyExpr, tpenv) + else + // TcLinearExprs processes multiple 'let' bindings in a tail recursive way + let mkf, envinner, tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds, m, body.Range) + let envinner = ShrinkContext envinner m body.Range + // tailcall + TcLinearExprs bodyChecker cenv envinner overallTy tpenv isCompExpr body (fun (x, tpenv) -> + cont (fst (mkf (x, overallTy.Commit)), tpenv)) + + | SynExpr.IfThenElse (_, _, synBoolExpr, _, synThenExpr, _, synElseExprOpt, spIfToThen, isRecovery, mIfToThen, m) when not isCompExpr -> + let boolExpr, tpenv = TcExprThatCantBeCtorBody cenv (MustEqual cenv.g.bool_ty) env tpenv synBoolExpr + let thenExpr, tpenv = + let env = + match env.eContextInfo with + | ContextInfo.ElseBranchResult _ -> { env with eContextInfo = ContextInfo.ElseBranchResult synThenExpr.Range } + | _ -> + match synElseExprOpt with + | None -> { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range } + | _ -> { env with eContextInfo = ContextInfo.IfExpression synThenExpr.Range } + + if not isRecovery && Option.isNone synElseExprOpt then + UnifyTypes cenv env m cenv.g.unit_ty overallTy.Commit + + TcExprThatCanBeCtorBody cenv overallTy env tpenv synThenExpr + + match synElseExprOpt with + | None -> + let elseExpr = mkUnit cenv.g mIfToThen + let spElse = DebugPointAtTarget.No // the fake 'unit' value gets exactly the same range as spIfToThen + let overallExpr = primMkCond spIfToThen DebugPointAtTarget.Yes spElse m overallTy.Commit boolExpr thenExpr elseExpr + cont (overallExpr, tpenv) + + | Some synElseExpr -> + let env = { env with eContextInfo = ContextInfo.ElseBranchResult synElseExpr.Range } + // tailcall + TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synElseExpr (fun (elseExpr, tpenv) -> + let resExpr = primMkCond spIfToThen DebugPointAtTarget.Yes DebugPointAtTarget.Yes m overallTy.Commit boolExpr thenExpr elseExpr + cont (resExpr, tpenv)) + + | _ -> + cont (bodyChecker overallTy env tpenv expr) + +/// Typecheck and compile pattern-matching constructs +and TcAndPatternCompileMatchClauses mExpr matchm actionOnFailure cenv inputExprOpt inputTy resultTy env tpenv synClauses = + let clauses, tpenv = TcMatchClauses cenv inputTy resultTy env tpenv synClauses + let matchVal, expr = CompilePatternForMatchClauses cenv env mExpr matchm true actionOnFailure inputExprOpt inputTy resultTy.Commit clauses + matchVal, expr, tpenv + +and TcMatchPattern cenv inputTy env tpenv (pat: SynPat, optWhenExpr: SynExpr option) = + let m = pat.Range + let patf', (tpenv, names, _) = TcPat WarnOnUpperCase cenv env None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, false) (tpenv, Map.empty, Set.empty) inputTy pat + let envinner, values, vspecMap = MakeAndPublishSimpleValsForMergedScope cenv env m names + let optWhenExprR, tpenv = + match optWhenExpr with + | Some whenExpr -> + let guardEnv = { envinner with eContextInfo = ContextInfo.PatternMatchGuard whenExpr.Range } + let whenExprR, tpenv = TcExpr cenv (MustEqual cenv.g.bool_ty) guardEnv tpenv whenExpr + Some whenExprR, tpenv + | None -> None, tpenv + patf' (TcPatPhase2Input (values, true)), optWhenExprR, NameMap.range vspecMap, envinner, tpenv + +and TcMatchClauses cenv inputTy (resultTy: OverallTy) env tpenv clauses = + let mutable first = true + let isFirst() = if first then first <- false; true else false + List.mapFold (fun clause -> TcMatchClause cenv inputTy resultTy env (isFirst()) clause) tpenv clauses + +and TcMatchClause cenv inputTy (resultTy: OverallTy) env isFirst tpenv synMatchClause = + let (SynMatchClause(pat, optWhenExpr, _, e, patm, spTgt)) = synMatchClause + let pat', optWhenExprR, vspecs, envinner, tpenv = TcMatchPattern cenv inputTy env tpenv (pat, optWhenExpr) + let resultEnv = if isFirst then envinner else { envinner with eContextInfo = ContextInfo.FollowingPatternMatchClause e.Range } + let e', tpenv = TcExprThatCanBeCtorBody cenv resultTy resultEnv tpenv e + TClause(pat', optWhenExprR, TTarget(vspecs, e', spTgt, None), patm), tpenv + +and TcStaticOptimizationConstraint cenv env tpenv c = + match c with + | SynStaticOptimizationConstraint.WhenTyparTyconEqualsTycon(tp, ty, m) -> + if not cenv.g.compilingFslib then + errorR(Error(FSComp.SR.tcStaticOptimizationConditionalsOnlyForFSharpLibrary(), m)) + let ty', tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv ty + let tp', tpenv = TcTypar cenv env NewTyparsOK tpenv tp + TTyconEqualsTycon(mkTyparTy tp', ty'), tpenv + | SynStaticOptimizationConstraint.WhenTyparIsStruct(tp, m) -> + if not cenv.g.compilingFslib then + errorR(Error(FSComp.SR.tcStaticOptimizationConditionalsOnlyForFSharpLibrary(), m)) + let tp', tpenv = TcTypar cenv env NewTyparsOK tpenv tp + TTyconIsStruct(mkTyparTy tp'), tpenv + +/// Emit a conv.i instruction +and mkConvToNativeInt (g: TcGlobals) e m = Expr.Op (TOp.ILAsm ([ AI_conv ILBasicType.DT_I], [ g.nativeint_ty ]), [], [e], m) + +/// Fix up the r.h.s. of a 'use x = fixed expr' +and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBinding) = + warning(PossibleUnverifiableCode mBinding) + match overallExprTy with + | ty when isByrefTy cenv.g ty -> + let okByRef = + match stripExpr fixedExpr with + | Expr.Op (op, tyargs, args, _) -> + match op, tyargs, args with + | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon + | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject + | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true + | TOp.RefAddrGet _, _, _ -> true + | _ -> false + | _ -> false + if not okByRef then + error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + + let elemTy = destByrefTy cenv.g overallExprTy + UnifyTypes cenv env mBinding (mkNativePtrTy cenv.g elemTy) overallPatTy + mkCompGenLetIn mBinding "pinnedByref" ty fixedExpr (fun (v, ve) -> + v.SetIsFixed() + mkConvToNativeInt cenv.g ve mBinding) + + | ty when isStringTy cenv.g ty -> + let charPtrTy = mkNativePtrTy cenv.g cenv.g.char_ty + UnifyTypes cenv env mBinding charPtrTy overallPatTy + // + // let ptr: nativeptr = + // let pinned s = str + // (nativeptr)s + get_OffsettoStringData() + + mkCompGenLetIn mBinding "pinnedString" cenv.g.string_ty fixedExpr (fun (v, ve) -> + v.SetIsFixed() + let addrOffset = BuildOffsetToStringData cenv env mBinding + let stringAsNativeInt = mkConvToNativeInt cenv.g ve mBinding + let plusOffset = Expr.Op (TOp.ILAsm ([ AI_add ], [ cenv.g.nativeint_ty ]), [], [stringAsNativeInt; addrOffset], mBinding) + // check for non-null + mkNullTest cenv.g mBinding ve plusOffset ve) + + | ty when isArray1DTy cenv.g ty -> + let elemTy = destArrayTy cenv.g overallExprTy + let elemPtrTy = mkNativePtrTy cenv.g elemTy + UnifyTypes cenv env mBinding elemPtrTy overallPatTy + + // let ptr: nativeptr = + // let tmpArray: elem[] = arr + // if nonNull tmpArray then + // if tmpArray.Length <> 0 then + // let pinned tmpArrayByref: byref = &arr.[0] + // (nativeint) tmpArrayByref + // else + // (nativeint) 0 + // else + // (nativeint) 0 + // + mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_, ve) -> + // This is &arr.[0] + let elemZeroAddress = mkArrayElemAddress cenv.g (false, ILReadonly.NormalAddress, false, ILArrayShape.SingleDimensional, elemTy, [ve; mkInt32 cenv.g mBinding 0], mBinding) + // check for non-null and non-empty + let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding + // This is arr.Length + let arrayLengthExpr = mkCallArrayLength cenv.g mBinding elemTy ve + mkNullTest cenv.g mBinding ve + (mkNullTest cenv.g mBinding arrayLengthExpr + (mkCompGenLetIn mBinding "pinnedByref" (mkByrefTy cenv.g elemTy) elemZeroAddress (fun (v, ve) -> + v.SetIsFixed() + (mkConvToNativeInt cenv.g ve mBinding))) + zero) + zero) + + | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + + +/// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and +and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as explicitTyparInfo)) bind = + let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env + + match bind with + + | NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), mBinding, spBind) -> + let (SynValData(memberFlagsOpt, _, _)) = valSynData + + let callerName = + match declKind, bkind, pat with + | ExpressionBinding, _, _ -> envinner.eCallerMemberName + | _, _, (SynPat.Named(name, _, _, _) | SynPat.As(_, SynPat.Named(name, _, _, _), _)) -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet -> Some(name.idText.Substring 4) + | SynMemberKind.ClassConstructor -> Some(".ctor") + | SynMemberKind.Constructor -> Some(".ctor") + | _ -> Some(name.idText) + | _ -> Some(name.idText) + | ClassLetBinding false, SynBindingKind.Do, _ -> Some(".ctor") + | ClassLetBinding true, SynBindingKind.Do, _ -> Some(".cctor") + | ModuleOrMemberBinding, SynBindingKind.StandaloneExpression, _ -> Some(".cctor") + | _, _, _ -> envinner.eCallerMemberName + + let envinner = {envinner with eCallerMemberName = callerName } + + let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt declKind + + let isFixed, rhsExpr, overallPatTy, overallExprTy = + match rhsExpr with + | SynExpr.Fixed (e, _) -> true, e, NewInferenceType(), overallTy + | e -> false, e, overallTy, overallTy + + // Check the attributes of the binding, parameters or return value + let TcAttrs tgt isRet attrs = + // For all but attributes positioned at the return value, disallow implicitly + // targeting the return value. + let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue + let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs + if attrTgt = enum 0 && not (isNil attrs) then + errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), mBinding)) + attrs + + // Rotate [] from binding to return value + // Also patch the syntactic representation + let retAttribs, valAttribs, valSynData = + let attribs = TcAttrs attrTgt false attrs + let rotRetSynAttrs, rotRetAttribs, valAttribs = + // Do not rotate if some attrs fail to typecheck... + if attribs.Length <> attrs.Length then [], [], attribs + else attribs + |> List.zip attrs + |> List.partition(function | _, Attrib(_, _, _, _, _, Some ts, _) -> ts &&& AttributeTargets.ReturnValue <> enum 0 | _ -> false) + |> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v) + let retAttribs = + match rtyOpt with + | Some (SynBindingReturnInfo(_, _, Attributes retAttrs)) -> + rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs + | None -> rotRetAttribs + let valSynData = + match rotRetSynAttrs with + | [] -> valSynData + | {Range=mHead} :: _ -> + let (SynValData(valMf, SynValInfo(args, SynArgInfo(attrs, opt, retId)), valId)) = valSynData + in SynValData(valMf, SynValInfo(args, SynArgInfo({Attributes=rotRetSynAttrs; Range=mHead} :: attrs, opt, retId)), valId) + retAttribs, valAttribs, valSynData + + let isVolatile = HasFSharpAttribute cenv.g cenv.g.attrib_VolatileFieldAttribute valAttribs + + let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable mBinding + + let argAttribs = + spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter false)) + + // Assert the return type of an active pattern. A [] attribute may be used on a partial active pattern. + let isStructRetTy = HasFSharpAttribute cenv.g cenv.g.attrib_StructAttribute retAttribs + + let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) + + // See RFC FS-1087, the 'Zero' method of a builder may have 'DefaultValueAttribute' indicating it should + // always be used for empty branches of if/then/else and others + let isZeroMethod = + match declKind, pat with + | ModuleOrMemberBinding, SynPat.Named(id, _, _, _) when id.idText = "Zero" -> + match memberFlagsOpt with + | Some memberFlags -> + match memberFlags.MemberKind with + | SynMemberKind.Member -> true + | _ -> false + | _ -> false + | _ -> false + + if HasFSharpAttribute cenv.g cenv.g.attrib_DefaultValueAttribute valAttribs && not isZeroMethod then + errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) + + let isThreadStatic = isThreadOrContextStatic cenv.g valAttribs + if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) + + if isVolatile then + match declKind with + | ClassLetBinding _ -> () + | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) + + if (not isMutable || isThreadStatic) then + errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) + + if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then + errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) + + if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && + HasFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute valAttribs + then + errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) + + if Option.isNone memberFlagsOpt && HasFSharpAttribute cenv.g cenv.g.attrib_ConditionalAttribute valAttribs then + errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) + + if HasFSharpAttribute cenv.g cenv.g.attrib_EntryPointAttribute valAttribs then + if Option.isSome memberFlagsOpt then + errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) + else + UnifyTypes cenv env mBinding overallPatTy (mkArrayType cenv.g cenv.g.string_ty --> cenv.g.int_ty) + + if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) + + if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) + + let explicitTyparInfo = if isMutable then dontInferTypars else explicitTyparInfo + + if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) + + let isInline = + if isInline && isNil spatsL && isNil declaredTypars then + errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) + false + else + isInline + + let compgen = false + + // Use the syntactic arity if we're defining a function + let (SynValData(_, valSynInfo, _)) = valSynData + let partialValReprInfo = TranslateTopValSynInfo mBinding (TcAttributes cenv env) valSynInfo + + // Check the pattern of the l.h.s. of the binding + let tcPatPhase2, (tpenv, nameToPrelimValSchemeMap, _) = + TcPat AllIdsOK cenv envinner (Some partialValReprInfo) (inlineFlag, explicitTyparInfo, argAndRetAttribs, isMutable, vis, compgen) (tpenv, NameMap.empty, Set.empty) overallPatTy pat + + // Add active pattern result names to the environment + let apinfoOpt = + match NameMap.range nameToPrelimValSchemeMap with + | [PrelimValScheme1(id, _, ty, _, _, _, _, _, _, _, _) ] -> + match ActivePatternInfoOfValName id.idText id.idRange with + | Some apinfo -> Some (apinfo, ty, id.idRange) + | None -> None + | _ -> None + + // Add active pattern result names to the environment + let envinner = + match apinfoOpt with + | Some (apinfo, apOverallTy, m) -> + if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then + error(Error(FSComp.SR.tcInvalidActivePatternName(), mBinding)) + + apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> + let item = Item.ActivePatternResult(apinfo, apOverallTy, i, tagRange) + CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Binding, env.AccessRights)) + + { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv apOverallTy m } + | None -> + envinner + + // Now tc the r.h.s. + // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. + let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor | _ -> false) + + // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. + // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas + let rhsExprChecked, tpenv = + let atTopNonLambdaDefn = + DeclKind.IsModuleOrMemberOrExtensionBinding declKind && + (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && + synExprContainsError rhsExpr + + conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> + + // Save the arginfos away to match them up in the lambda + let (PartialValReprInfo(argInfos, _)) = partialValReprInfo + let envinner = { envinner with eLambdaArgInfos = argInfos } + + if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr + else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr) + + if bkind = SynBindingKind.StandaloneExpression && not cenv.isScript then + UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore + + // Fix up the r.h.s. expression for 'fixed' + let rhsExprChecked = + if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) + else rhsExprChecked + + match apinfoOpt with + | Some (apinfo, apOverallTy, _) -> + let activePatResTys = NewInferenceTypes apinfo.ActiveTags + let _, apReturnTy = stripFunTy cenv.g apOverallTy + if isStructRetTy && apinfo.IsTotal then + errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + if isStructRetTy then + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.StructActivePattern mBinding + UnifyTypes cenv env mBinding (apinfo.ResultType cenv.g rhsExpr.Range activePatResTys isStructRetTy) apReturnTy + | None -> + if isStructRetTy then + errorR(Error(FSComp.SR.tcInvalidStructReturn(), mBinding)) + + // Check other attributes + let hasLiteralAttr, literalValue = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) + + if hasLiteralAttr then + if isThreadStatic then + errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) + if isMutable then + errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) + if isInline then + errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) + if not (isNil declaredTypars) then + errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) + + CheckedBindingInfo(inlineFlag, valAttribs, doc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, spBind, compgen, literalValue, isFixed), tpenv + +and TcLiteral cenv overallTy env tpenv (attrs, synLiteralValExpr) = + let hasLiteralAttr = HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs + if hasLiteralAttr then + let literalValExpr, _ = TcExpr cenv (MustEqual overallTy) env tpenv synLiteralValExpr + match EvalLiteralExprOrAttribArg cenv.g literalValExpr with + | Expr.Const (c, _, ty) -> + if c = Const.Zero && isStructTy cenv.g ty then + warning(Error(FSComp.SR.tcIllegalStructTypeForConstantExpression(), synLiteralValExpr.Range)) + false, None + else + true, Some c + | _ -> + errorR(Error(FSComp.SR.tcInvalidConstantExpression(), synLiteralValExpr.Range)) + true, Some Const.Unit + + else hasLiteralAttr, None + +and TcBindingTyparDecls alwaysRigid cenv env tpenv (ValTyparDecls(synTypars, synTyparConstraints, infer)) = + let declaredTypars = TcTyparDecls cenv env synTypars + let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTypars env + let tpenv = TcTyparConstraints cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv synTyparConstraints + + let rigidCopyOfDeclaredTypars = + if alwaysRigid then + declaredTypars |> List.iter (fun tp -> SetTyparRigid env.DisplayEnv tp.Range tp) + declaredTypars + else + let rigidCopyOfDeclaredTypars = copyTypars declaredTypars + // The type parameters used to check rigidity after inference are marked rigid straight away + rigidCopyOfDeclaredTypars |> List.iter (fun tp -> SetTyparRigid env.DisplayEnv tp.Range tp) + // The type parameters using during inference will be marked rigid after inference + declaredTypars |> List.iter (fun tp -> tp.SetRigidity TyparRigidity.WillBeRigid) + rigidCopyOfDeclaredTypars + + ExplicitTyparInfo(rigidCopyOfDeclaredTypars, declaredTypars, infer), tpenv + +and TcNonrecBindingTyparDecls cenv env tpenv bind = + let (NormalizedBinding(_, _, _, _, _, _, synTyparDecls, _, _, _, _, _)) = bind + TcBindingTyparDecls true cenv env tpenv synTyparDecls + +and TcNonRecursiveBinding declKind cenv env tpenv ty b = + let b = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env b + let explicitTyparInfo, tpenv = TcNonrecBindingTyparDecls cenv env tpenv b + TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], explicitTyparInfo) b + +//------------------------------------------------------------------------- +// TcAttribute* +// *Ex means the function accepts attribute targets that must be explicit +//------------------------------------------------------------------------ + +and TcAttributeEx canFail cenv (env: TcEnv) attrTgt attrEx (synAttr: SynAttribute) = + let (LongIdentWithDots(tycon, _)) = synAttr.TypeName + let arg = synAttr.ArgExpr + let targetIndicator = synAttr.Target + let isAppliedToGetterOrSetter = synAttr.AppliesToGetterAndSetter + let mAttr = synAttr.Range + let typath, tyid = List.frontAndBack tycon + let tpenv = emptyUnscopedTyparEnv + + // if we're checking an attribute that was applied directly to a getter or a setter, then + // what we're really checking against is a method, not a property + let attrTgt = if isAppliedToGetterOrSetter then ((attrTgt ^^^ AttributeTargets.Property) ||| AttributeTargets.Method) else attrTgt + let ty, tpenv = + let try1 n = + let tyid = mkSynId tyid.idRange n + let tycon = (typath @ [tyid]) + let ad = env.eAccessRights + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad tycon TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No with + | Exception err -> raze err + | _ -> success(TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInAttribute env tpenv (SynType.App(SynType.LongIdent(LongIdentWithDots(tycon, [])), None, [], [], None, false, mAttr)) ) + ForceRaise ((try1 (tyid.idText + "Attribute")) |> otherwise (fun () -> (try1 tyid.idText))) + + let ad = env.eAccessRights + + if not (IsTypeAccessible cenv.g cenv.amap mAttr ad ty) then errorR(Error(FSComp.SR.tcTypeIsInaccessible(), mAttr)) + + let tcref = tcrefOfAppTy cenv.g ty + + let conditionalCallDefineOpt = TryFindTyconRefStringAttribute cenv.g mAttr cenv.g.attrib_ConditionalAttribute tcref + + match conditionalCallDefineOpt, cenv.conditionalDefines with + | Some d, Some defines when not (List.contains d defines) -> + [], false + | _ -> + // REVIEW: take notice of inherited? + let validOn, _inherited = + let validOnDefault = 0x7fff + let inheritedDefault = true + if tcref.IsILTycon then + let tdef = tcref.ILTyconRawMetadata + let tref = cenv.g.attrib_AttributeUsageAttribute.TypeRef + + match TryDecodeILAttribute tref tdef.CustomAttrs with + | Some ([ILAttribElem.Int32 validOn ], named) -> + let inherited = + match List.tryPick (function "Inherited", _, _, ILAttribElem.Bool res -> Some res | _ -> None) named with + | None -> inheritedDefault + | Some x -> x + (validOn, inherited) + | Some ([ILAttribElem.Int32 validOn; ILAttribElem.Bool _allowMultiple; ILAttribElem.Bool inherited ], _) -> + (validOn, inherited) + | _ -> + (validOnDefault, inheritedDefault) + else + match (TryFindFSharpAttribute cenv.g cenv.g.attrib_AttributeUsageAttribute tcref.Attribs) with + | Some(Attrib(_, _, [ AttribInt32Arg validOn ], _, _, _, _)) -> + (validOn, inheritedDefault) + | Some(Attrib(_, _, [ AttribInt32Arg validOn + AttribBoolArg(_allowMultiple) + AttribBoolArg inherited], _, _, _, _)) -> + (validOn, inherited) + | Some _ -> + warning(Error(FSComp.SR.tcUnexpectedConditionInImportedAssembly(), mAttr)) + (validOnDefault, inheritedDefault) + | _ -> + (validOnDefault, inheritedDefault) + let possibleTgts = enum validOn &&& attrTgt + let directedTgts = + match targetIndicator with + | Some id when id.idText = "assembly" -> AttributeTargets.Assembly + | Some id when id.idText = "module" -> AttributeTargets.Module + | Some id when id.idText = "return" -> AttributeTargets.ReturnValue + | Some id when id.idText = "field" -> AttributeTargets.Field + | Some id when id.idText = "property" -> AttributeTargets.Property + | Some id when id.idText = "method" -> AttributeTargets.Method + | Some id when id.idText = "param" -> AttributeTargets.Parameter + | Some id when id.idText = "type" -> AttributeTargets.TyconDecl + | Some id when id.idText = "constructor" -> AttributeTargets.Constructor + | Some id when id.idText = "event" -> AttributeTargets.Event + | Some id -> + errorR(Error(FSComp.SR.tcUnrecognizedAttributeTarget(), id.idRange)) + possibleTgts + // mask explicit targets + | _ -> possibleTgts &&& ~~~ attrEx + let constrainedTgts = possibleTgts &&& directedTgts + if constrainedTgts = enum 0 then + if (directedTgts = AttributeTargets.Assembly || directedTgts = AttributeTargets.Module) then + error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElementUseDo(), mAttr)) + else + error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr)) + + match ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mAttr ad ty with + | Exception _ when canFail -> [ ], true + | res -> + let item = ForceRaise res + if not (ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap mAttr ty cenv.g.tcref_System_Attribute) then warning(Error(FSComp.SR.tcTypeDoesNotInheritAttribute(), mAttr)) + let attrib = + match item with + | Item.CtorGroup(methodName, minfos) -> + let meths = minfos |> List.map (fun minfo -> minfo, None) + let afterResolution = ForNewConstructors cenv.tcSink env tyid.idRange methodName minfos + let (expr, attributeAssignedNamedItems, _), _ = + TcMethodApplication true cenv env tpenv None [] mAttr mAttr methodName None ad PossiblyMutates false meths afterResolution NormalValUse [arg] (MustEqual ty) [] + + UnifyTypes cenv env mAttr ty (tyOfExpr cenv.g expr) + + let mkAttribExpr e = + AttribExpr(e, EvalLiteralExprOrAttribArg cenv.g e) + + let namedAttribArgMap = + attributeAssignedNamedItems |> List.map (fun (CallerNamedArg(id, CallerArg(argtyv, m, isOpt, callerArgExpr))) -> + if isOpt then error(Error(FSComp.SR.tcOptionalArgumentsCannotBeUsedInCustomAttribute(), m)) + let m = callerArgExpr.Range + let setterItem, _ = ResolveLongIdentInType cenv.tcSink cenv.nameResolver env.NameEnv LookupKind.Expr m ad id IgnoreOverrides TypeNameResolutionInfo.Default ty + let nm, isProp, argty = + match setterItem with + | Item.Property (_, [pinfo]) -> + if not pinfo.HasSetter then + errorR(Error(FSComp.SR.tcPropertyCannotBeSet0(), m)) + id.idText, true, pinfo.GetPropertyType(cenv.amap, m) + | Item.ILField finfo -> + CheckILFieldInfoAccessible cenv.g cenv.amap m ad finfo + CheckILFieldAttributes cenv.g finfo m + id.idText, false, finfo.FieldType(cenv.amap, m) + | Item.RecdField rfinfo when not rfinfo.IsStatic -> + CheckRecdFieldInfoAttributes cenv.g rfinfo m |> CommitOperationResult + CheckRecdFieldInfoAccessible cenv.amap m ad rfinfo + // This uses the F# backend name mangling of fields.... + let nm = ComputeFieldName rfinfo.Tycon rfinfo.RecdField + nm, false, rfinfo.FieldType + | _ -> + errorR(Error(FSComp.SR.tcPropertyOrFieldNotFoundInAttribute(), m)) + id.idText, false, cenv.g.unit_ty + let propNameItem = Item.SetterArg(id, setterItem) + CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, propNameItem, emptyTyparInst, ItemOccurence.Use, ad) + + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace argty argtyv + + AttribNamedArg(nm, argty, isProp, mkAttribExpr callerArgExpr)) + + match expr with + | Expr.Op (TOp.ILCall (_, _, isStruct, _, _, _, _, ilMethRef, [], [], _), [], args, m) -> + if isStruct then error (Error(FSComp.SR.tcCustomAttributeMustBeReferenceType(), m)) + if args.Length <> ilMethRef.ArgTypes.Length then error (Error(FSComp.SR.tcCustomAttributeArgumentMismatch(), m)) + let args = args |> List.map mkAttribExpr + Attrib(tcref, ILAttrib ilMethRef, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, m) + + | Expr.App (InnerExprPat(ExprValWithPossibleTypeInst(vref, _, _, _)), _, _, args, _) -> + let args = args |> List.collect (function Expr.Const (Const.Unit, _, _) -> [] | expr -> tryDestRefTupleExpr expr) |> List.map mkAttribExpr + Attrib(tcref, FSAttrib vref, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, mAttr) + + | _ -> + error (Error(FSComp.SR.tcCustomAttributeMustInvokeConstructor(), mAttr)) + + | _ -> + error(Error(FSComp.SR.tcAttributeExpressionsMustBeConstructorCalls(), mAttr)) + + [ (constrainedTgts, attrib) ], false + +and TcAttributesWithPossibleTargetsEx canFail cenv env attrTgt attrEx synAttribs = + + (false, synAttribs) ||> List.collectFold (fun didFail synAttrib -> + try + let attribsAndTargets, didFail2 = TcAttributeEx canFail cenv env attrTgt attrEx synAttrib + + // This is where we place any checks that completely exclude the use of some particular + // attributes from F#. + let attribs = List.map snd attribsAndTargets + if HasFSharpAttribute cenv.g cenv.g.attrib_TypeForwardedToAttribute attribs || + HasFSharpAttribute cenv.g cenv.g.attrib_CompilationArgumentCountsAttribute attribs || + HasFSharpAttribute cenv.g cenv.g.attrib_CompilationMappingAttribute attribs then + errorR(Error(FSComp.SR.tcUnsupportedAttribute(), synAttrib.Range)) + + attribsAndTargets, didFail || didFail2 + + with e -> + errorRecovery e synAttrib.Range + [], false) + +and TcAttributesMaybeFailEx canFail cenv env attrTgt attrEx synAttribs = + let attribsAndTargets, didFail = TcAttributesWithPossibleTargetsEx canFail cenv env attrTgt attrEx synAttribs + attribsAndTargets |> List.map snd, didFail + +and TcAttributesWithPossibleTargets canFail cenv env attrTgt synAttribs = + TcAttributesWithPossibleTargetsEx canFail cenv env attrTgt (enum 0) synAttribs + +and TcAttribute canFail cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) = + TcAttributeEx canFail cenv env attrTgt (enum 0) synAttr + +and TcAttributesMaybeFail canFail cenv env attrTgt synAttribs = + TcAttributesMaybeFailEx canFail cenv env attrTgt (enum 0) synAttribs + +and TcAttributesCanFail cenv env attrTgt synAttribs = + let attrs, didFail = TcAttributesMaybeFail true cenv env attrTgt synAttribs + attrs, (fun () -> if didFail then TcAttributes cenv env attrTgt synAttribs else attrs) + +and TcAttributes cenv env attrTgt synAttribs = + TcAttributesMaybeFail false cenv env attrTgt synAttribs |> fst + +//------------------------------------------------------------------------- +// TcLetBinding +//------------------------------------------------------------------------ + +and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBindsRange, scopem) = + + // Typecheck all the bindings... + let checkedBinds, tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv (NewInferenceType ()) b) tpenv synBinds + let (ContainerInfo(altActualParent, _)) = containerInfo + + // Canonicalize constraints prior to generalization + let denv = env.DisplayEnv + CanonicalizePartialInferenceProblem cenv.css denv synBindsRange + (checkedBinds |> List.collect (fun tbinfo -> + let (CheckedBindingInfo(_, _, _, _, explicitTyparInfo, _, _, _, tauTy, _, _, _, _, _)) = tbinfo + let (ExplicitTyparInfo(_, declaredTypars, _)) = explicitTyparInfo + let maxInferredTypars = (freeInTypeLeftToRight cenv.g false tauTy) + declaredTypars @ maxInferredTypars)) + + let lazyFreeInEnv = lazy (GeneralizationHelpers.ComputeUngeneralizableTypars env) + + // Generalize the bindings... + (((fun x -> x), env, tpenv), checkedBinds) ||> List.fold (fun (buildExpr, env, tpenv) tbinfo -> + let (CheckedBindingInfo(inlineFlag, attrs, doc, tcPatPhase2, explicitTyparInfo, nameToPrelimValSchemeMap, rhsExpr, _, tauTy, m, spBind, _, literalValue, isFixed)) = tbinfo + let enclosingDeclaredTypars = [] + let (ExplicitTyparInfo(_, declaredTypars, canInferTypars)) = explicitTyparInfo + let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars + let generalizedTypars, prelimValSchemes2 = + let canInferTypars = GeneralizationHelpers. ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, canInferTypars, None) + + let maxInferredTypars = freeInTypeLeftToRight cenv.g false tauTy + + let generalizedTypars = + if isNil maxInferredTypars && isNil allDeclaredTypars then + [] + else + let freeInEnv = lazyFreeInEnv.Force() + let canConstrain = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl declKind + GeneralizationHelpers.ComputeAndGeneralizeGenericTypars + (cenv, denv, m, freeInEnv, canInferTypars, canConstrain, inlineFlag, Some rhsExpr, allDeclaredTypars, maxInferredTypars, tauTy, false) + + let prelimValSchemes2 = GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars nameToPrelimValSchemeMap + + generalizedTypars, prelimValSchemes2 + + // REVIEW: this scopes generalized type variables. Ensure this is handled properly + // on all other paths. + let tpenv = HideUnscopedTypars generalizedTypars tpenv + let valSchemes = NameMap.map (UseCombinedArity cenv.g declKind rhsExpr) prelimValSchemes2 + let values = MakeAndPublishVals cenv env (altActualParent, false, declKind, ValNotInRecScope, valSchemes, attrs, doc, literalValue) + let checkedPat = tcPatPhase2 (TcPatPhase2Input (values, true)) + let prelimRecValues = NameMap.map fst values + + // Now bind the r.h.s. to the l.h.s. + let rhsExpr = mkTypeLambda m generalizedTypars (rhsExpr, tauTy) + + match checkedPat with + // Don't introduce temporary or 'let' for 'match against wild' or 'match against unit' + + | TPat_wild _ | TPat_const (Const.Unit, _) when not isUse && not isFixed && isNil generalizedTypars -> + let mkSequentialBind (tm, tmty) = (mkSequential DebugPointAtSequential.SuppressNeither m rhsExpr tm, tmty) + (buildExpr >> mkSequentialBind, env, tpenv) + | _ -> + + // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to + let patternInputTmp, checkedPat2 = + match checkedPat with + // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to + | TPat_as (pat, PBind(v, TypeScheme(generalizedTypars', _)), _) + when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' -> + + v, pat + //Op (LValueOp (LByrefGet,x),[],[],C:\GitHub\dsyme\visualfsharp\a.fs (15,42--15,43) IsSynthetic=false) + + | _ when inlineFlag.MustInline -> + error(Error(FSComp.SR.tcInvalidInlineSpecification(), m)) + + | TPat_query _ when HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs -> + error(Error(FSComp.SR.tcLiteralAttributeCannotUseActivePattern(), m)) + + | _ -> + + let tmp, _ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy) + + if isUse then + let isDiscarded = match checkedPat with TPat_wild _ -> true | _ -> false + if not isDiscarded then + errorR(Error(FSComp.SR.tcInvalidUseBinding(), m)) + else + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.UseBindingValueDiscard checkedPat.Range + + elif isFixed then + errorR(Error(FSComp.SR.tcInvalidUseBinding(), m)) + + // If the overall declaration is declaring statics or a module value, then force the patternInputTmp to also + // have representation as module value. + if (DeclKind.MustHaveArity declKind) then + AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes tmp rhsExpr) + + tmp, checkedPat + + // Add the bind "let patternInputTmp = rhsExpr" to the bodyExpr we get from mkPatBind + let mkRhsBind (bodyExpr, bodyExprTy) = + let letExpr = mkLet spBind m patternInputTmp rhsExpr bodyExpr + letExpr, bodyExprTy + + let allValsDefinedByPattern = NameMap.range prelimRecValues + + // Add the compilation of the pattern to the bodyExpr we get from mkCleanup + let mkPatBind (bodyExpr, bodyExprTy) = + let valsDefinedByMatching = ListSet.remove valEq patternInputTmp allValsDefinedByPattern + let clauses = [TClause(checkedPat2, None, TTarget(valsDefinedByMatching, bodyExpr, DebugPointAtTarget.No, None), m)] + let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (patternInputTmp, generalizedTypars, Some rhsExpr) clauses tauTy bodyExprTy + let matchx = if (DeclKind.ConvertToLinearBindings declKind) then LinearizeTopMatch cenv.g altActualParent matchx else matchx + matchx, bodyExprTy + + // Add the dispose of any "use x = ..." to bodyExpr + let mkCleanup (bodyExpr, bodyExprTy) = + if isUse && not isFixed then + let isDiscarded = match checkedPat2 with TPat_wild _ -> true | _ -> false + let allValsDefinedByPattern = if isDiscarded then [patternInputTmp] else allValsDefinedByPattern + (allValsDefinedByPattern, (bodyExpr, bodyExprTy)) ||> List.foldBack (fun v (bodyExpr, bodyExprTy) -> + AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css v.Range NoTrace cenv.g.system_IDisposable_ty v.Type + let cleanupE = BuildDisposableCleanup cenv env m v + mkTryFinally cenv.g (bodyExpr, cleanupE, m, bodyExprTy, DebugPointAtTry.Body, DebugPointAtFinally.No), bodyExprTy) + else + (bodyExpr, bodyExprTy) + + let envInner = AddLocalValMap cenv.g cenv.tcSink scopem prelimRecValues env + + ((buildExpr >> mkCleanup >> mkPatBind >> mkRhsBind), envInner, tpenv)) + +/// Return binds corresponding to the linearised let-bindings. +/// This reveals the bound items, e.g. when the lets occur in incremental object defns. +/// RECAP: +/// The LHS of let-bindings are patterns. +/// These patterns could fail, e.g. "let Some x = ...". +/// So let bindings could contain a fork at a match construct, with one branch being the match failure. +/// If bindings are linearised, then this fork is pushed to the RHS. +/// In this case, the let bindings type check to a sequence of bindings. +and TcLetBindings cenv env containerInfo declKind tpenv (binds, bindsm, scopem) = + assert(DeclKind.ConvertToLinearBindings declKind) + let mkf, env, tpenv = TcLetBinding cenv false env containerInfo declKind tpenv (binds, bindsm, scopem) + let unite = mkUnit cenv.g bindsm + let expr, _ = mkf (unite, cenv.g.unit_ty) + let rec stripLets acc = function + | Expr.Let (bind, body, m, _) -> stripLets (TMDefLet(bind, m) :: acc) body + | Expr.Sequential (e1, e2, NormalSeq, _, m) -> stripLets (TMDefDo(e1, m) :: acc) e2 + | Expr.Const (Const.Unit, _, _) -> List.rev acc + | _ -> failwith "TcLetBindings: let sequence is non linear. Maybe a LHS pattern was not linearised?" + let binds = stripLets [] expr + binds, env, tpenv + +and CheckMemberFlags optIntfSlotTy newslotsOK overridesOK memberFlags m = + if newslotsOK = NoNewSlots && memberFlags.IsDispatchSlot then + errorR(Error(FSComp.SR.tcAbstractMembersIllegalInAugmentation(), m)) + if overridesOK = ErrorOnOverrides && memberFlags.MemberKind = SynMemberKind.Constructor then + errorR(Error(FSComp.SR.tcConstructorsIllegalInAugmentation(), m)) + if overridesOK = WarnOnOverrides && memberFlags.IsOverrideOrExplicitImpl && Option.isNone optIntfSlotTy then + warning(OverrideInIntrinsicAugmentation m) + if overridesOK = ErrorOnOverrides && memberFlags.IsOverrideOrExplicitImpl then + error(Error(FSComp.SR.tcMethodOverridesIllegalHere(), m)) + +/// Apply the pre-assumed knowledge available to type inference prior to looking at +/// the _body_ of the binding. For example, in a letrec we may assume this knowledge +/// for each binding in the letrec prior to any type inference. This might, for example, +/// tell us the type of the arguments to a recursive function. +and ApplyTypesFromArgumentPatterns (cenv, env, optArgsOK, ty, m, tpenv, NormalizedBindingRhs (pushedPats, retInfoOpt, e), memberFlagsOpt: SynMemberFlags option) = + match pushedPats with + | [] -> + match retInfoOpt with + | None -> () + | Some (SynBindingReturnInfo (retInfoTy, m, _)) -> + let retInfoTy, _ = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv retInfoTy + UnifyTypes cenv env m ty retInfoTy + // Property setters always have "unit" return type + match memberFlagsOpt with + | Some memFlags when memFlags.MemberKind = SynMemberKind.PropertySet -> + UnifyTypes cenv env m ty cenv.g.unit_ty + | _ -> () + + | pushedPat :: morePushedPats -> + let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m ty + // We apply the type information from the patterns by type checking the + // "simple" patterns against 'domainTy'. They get re-typechecked later. + ignore (TcSimplePats cenv optArgsOK CheckCxs domainTy env (tpenv, Map.empty, Set.empty) pushedPat) + ApplyTypesFromArgumentPatterns (cenv, env, optArgsOK, resultTy, m, tpenv, NormalizedBindingRhs (morePushedPats, retInfoOpt, e), memberFlagsOpt) + + +/// Check if the type annotations and inferred type information in a value give a +/// full and complete generic type for a value. If so, enable generic recursion. +and ComputeIsComplete enclosingDeclaredTypars declaredTypars ty = + Zset.isEmpty (List.fold (fun acc v -> Zset.remove v acc) + (freeInType CollectAllNoCaching ty).FreeTypars + (enclosingDeclaredTypars@declaredTypars)) + +/// Determine if a uniquely-identified-abstract-slot exists for an override member (or interface member implementation) based on the information available +/// at the syntactic definition of the member (i.e. prior to type inference). If so, we know the expected signature of the override, and the full slotsig +/// it implements. Apply the inferred slotsig. +and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (bindingTy, m, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, _objTy, optIntfSlotTy, valSynData, memberFlags: SynMemberFlags, attribs) = + + let ad = envinner.eAccessRights + let typToSearchForAbstractMembers = + match optIntfSlotTy with + | Some (ty, abstractSlots) -> + // The interface type is in terms of the type's type parameters. + // We need a signature in terms of the values' type parameters. + ty, Some abstractSlots + | None -> + tcrefObjTy, None + + // Determine if a uniquely-identified-override exists based on the information + // at the member signature. If so, we know the type of this member, and the full slotsig + // it implements. Apply the inferred slotsig. + if memberFlags.IsOverrideOrExplicitImpl then + + // for error detection, we want to compare finality when testing for equivalence + let methInfosEquivByNameAndSig meths = + match meths with + | [] -> false + | head :: tail -> + tail |> List.forall (MethInfosEquivByNameAndSig EraseNone false cenv.g cenv.amap m head) + + match memberFlags.MemberKind with + | SynMemberKind.Member -> + let dispatchSlots, dispatchSlotsArityMatch = + GetAbstractMethInfosForSynMethodDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, valSynData) + + let uniqueAbstractMethSigs = + match dispatchSlots with + | [] -> + errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) + [] + + | slots -> + match dispatchSlotsArityMatch with + | meths when methInfosEquivByNameAndSig meths -> meths + | [] -> + let details = NicePrint.multiLineStringOfMethInfos cenv.infoReader m envinner.DisplayEnv slots + errorR(Error(FSComp.SR.tcOverrideArityMismatch details, memberId.idRange)) + [] + | _ -> [] // check that method to override is sealed is located at CheckOverridesAreAllUsedOnce (typrelns.fs) + // We hit this case when it is ambiguous which abstract method is being implemented. + + + + // If we determined a unique member then utilize the type information from the slotsig + let declaredTypars = + match uniqueAbstractMethSigs with + | uniqueAbstractMeth :: _ -> + + let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming) + + let typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot = + FreshenAbstractSlot cenv.g cenv.amap m synTyparDecls uniqueAbstractMeth + + let declaredTypars = (if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars) + + let absSlotTy = mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot + + UnifyTypes cenv envinner m bindingTy absSlotTy + declaredTypars + | _ -> declaredTypars + + // Retained to ensure use of an FSComp.txt entry, can be removed at a later date: errorR(Error(FSComp.SR.tcDefaultAmbiguous(), memberId.idRange)) + + // What's the type containing the abstract slot we're implementing? Used later on in MakeMemberDataAndMangledNameForMemberVal. + // This type must be in terms of the enclosing type's formal type parameters, hence the application of revRenaming + + let optInferredImplSlotTys = + match optIntfSlotTy with + | Some (x, _) -> [x] + | None -> uniqueAbstractMethSigs |> List.map (fun x -> x.ApparentEnclosingType) + + optInferredImplSlotTys, declaredTypars + + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet as k -> + let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, k, valSynData) + + // Only consider those abstract slots where the get/set flags match the value we're defining + let dispatchSlots = + dispatchSlots + |> List.filter (fun pinfo -> + (pinfo.HasGetter && k=SynMemberKind.PropertyGet) || + (pinfo.HasSetter && k=SynMemberKind.PropertySet)) + + // Find the unique abstract slot if it exists + let uniqueAbstractPropSigs = + match dispatchSlots with + | [] when not (CompileAsEvent cenv.g attribs) -> + errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange)) + [] + | [uniqueAbstractProp] -> [uniqueAbstractProp] + | _ -> + // We hit this case when it is ambiguous which abstract property is being implemented. + [] + + // If we determined a unique member then utilize the type information from the slotsig + uniqueAbstractPropSigs |> List.iter (fun uniqueAbstractProp -> + + let kIsGet = (k = SynMemberKind.PropertyGet) + + if not (if kIsGet then uniqueAbstractProp.HasGetter else uniqueAbstractProp.HasSetter) then + error(Error(FSComp.SR.tcAbstractPropertyMissingGetOrSet(if kIsGet then "getter" else "setter"), memberId.idRange)) + + let uniqueAbstractMeth = if kIsGet then uniqueAbstractProp.GetterMethod else uniqueAbstractProp.SetterMethod + + let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming) + + let _, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot = + FreshenAbstractSlot cenv.g cenv.amap m synTyparDecls uniqueAbstractMeth + + if not (isNil typarsFromAbsSlot) then + errorR(InternalError("Unexpected generic property", memberId.idRange)) + + let absSlotTy = + if (memberFlags.MemberKind = SynMemberKind.PropertyGet) + then mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot + else + match argTysFromAbsSlot with + | [argTysFromAbsSlot] -> mkRefTupledTy cenv.g argTysFromAbsSlot --> cenv.g.unit_ty + | _ -> + error(Error(FSComp.SR.tcInvalidSignatureForSet(), memberId.idRange)) + retTyFromAbsSlot --> cenv.g.unit_ty + + UnifyTypes cenv envinner m bindingTy absSlotTy) + + // What's the type containing the abstract slot we're implementing? Used later on in MakeMemberDataAndMangledNameForMemberVal. + // This type must be in terms of the enclosing type's formal type parameters, hence the application of revRenaming. + + let optInferredImplSlotTys = + match optIntfSlotTy with + | Some (x, _) -> [ x ] + | None -> uniqueAbstractPropSigs |> List.map (fun pinfo -> pinfo.ApparentEnclosingType) + + optInferredImplSlotTys, declaredTypars + + | _ -> + match optIntfSlotTy with + | Some (x, _) -> [x], declaredTypars + | None -> [], declaredTypars + + else + + [], declaredTypars + +and CheckForNonAbstractInterface declKind tcref (memberFlags: SynMemberFlags) m = + if isInterfaceTyconRef tcref then + if memberFlags.MemberKind = SynMemberKind.ClassConstructor then + error(Error(FSComp.SR.tcStaticInitializersIllegalInInterface(), m)) + elif memberFlags.MemberKind = SynMemberKind.Constructor then + error(Error(FSComp.SR.tcObjectConstructorsIllegalInInterface(), m)) + elif memberFlags.IsOverrideOrExplicitImpl then + error(Error(FSComp.SR.tcMemberOverridesIllegalInInterface(), m)) + elif not (declKind=ExtrinsicExtensionBinding || memberFlags.IsDispatchSlot ) then + error(Error(FSComp.SR.tcConcreteMembersIllegalInInterface(), m)) + +//------------------------------------------------------------------------- +// TcLetrec - AnalyzeAndMakeAndPublishRecursiveValue s +//------------------------------------------------------------------------ + +and AnalyzeRecursiveStaticMemberOrValDecl + (cenv, + envinner: TcEnv, + tpenv, + declKind, + newslotsOK, + overridesOK, + tcrefContainerInfo, + vis1, + id: Ident, + vis2, + declaredTypars, + memberFlagsOpt, + thisIdOpt, + bindingAttribs, + valSynInfo, + ty, + bindingRhs, + mBinding, + explicitTyparInfo) = + + let vis = CombineVisibilityAttribs vis1 vis2 mBinding + + // Check if we're defining a member, in which case generate the internal unique + // name for the member and the information about which type it is augmenting + + match tcrefContainerInfo, memberFlagsOpt with + | Some(MemberOrValContainerInfo(tcref, optIntfSlotTy, baseValOpt, _safeInitInfo, declaredTyconTypars)), Some memberFlags -> + assert (Option.isNone optIntfSlotTy) + + CheckMemberFlags None newslotsOK overridesOK memberFlags id.idRange + CheckForNonAbstractInterface declKind tcref memberFlags id.idRange + + if memberFlags.MemberKind = SynMemberKind.Constructor && tcref.Deref.IsExceptionDecl then + error(Error(FSComp.SR.tcConstructorsDisallowedInExceptionAugmentation(), id.idRange)) + + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let _, enclosingDeclaredTypars, _, objTy, thisTy = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars + let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner + let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic + + let safeThisValOpt, baseValOpt = + match memberFlags.MemberKind with + + // Explicit struct or class constructor + | SynMemberKind.Constructor -> + // A fairly adhoc place to put this check + if tcref.IsStructOrEnumTycon && (match valSynInfo with SynValInfo([[]], _) -> true | _ -> false) then + errorR(Error(FSComp.SR.tcStructsCannotHaveConstructorWithNoArguments(), mBinding)) + + if not tcref.IsFSharpObjectModelTycon then + errorR(Error(FSComp.SR.tcConstructorsIllegalForThisType(), id.idRange)) + + let safeThisValOpt = MakeAndPublishSafeThisVal cenv envinner thisIdOpt thisTy + + // baseValOpt is the 'base' variable associated with the inherited portion of a class + // It is declared once on the 'inheritedTys clause, but a fresh binding is made for + // each member that may use it. + let baseValOpt = + match GetSuperTypeOfType cenv.g cenv.amap mBinding objTy with + | Some superTy -> MakeAndPublishBaseVal cenv envinner (match baseValOpt with None -> None | Some v -> Some v.Id) superTy + | None -> None + + let domainTy = NewInferenceType () + + // This is the type we pretend a constructor has, because its implementation must ultimately appear to return a value of the given type + // This is somewhat awkward later in codegen etc. + UnifyTypes cenv envinner mBinding ty (domainTy --> objTy) + + safeThisValOpt, baseValOpt + + | _ -> + None, None + + let memberInfo = + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, bindingAttribs, [], memberFlags, valSynInfo, id, false) + + envinner, tpenv, id, None, Some memberInfo, vis, vis2, safeThisValOpt, enclosingDeclaredTypars, baseValOpt, explicitTyparInfo, bindingRhs, declaredTypars + + // non-member bindings. How easy. + | _ -> + envinner, tpenv, id, None, None, vis, vis2, None, [], None, explicitTyparInfo, bindingRhs, declaredTypars + + +and AnalyzeRecursiveInstanceMemberDecl + (cenv, + envinner: TcEnv, + tpenv, + declKind, + synTyparDecls, + valSynInfo, + explicitTyparInfo: ExplicitTyparInfo, + newslotsOK, + overridesOK, + vis1, + thisId, + memberId: Ident, + toolId: Ident option, + bindingAttribs, + vis2, + tcrefContainerInfo, + memberFlagsOpt, + ty, + bindingRhs, + mBinding) = + + let vis = CombineVisibilityAttribs vis1 vis2 mBinding + let (ExplicitTyparInfo(_, declaredTypars, infer)) = explicitTyparInfo + match tcrefContainerInfo, memberFlagsOpt with + // Normal instance members. + | Some(MemberOrValContainerInfo(tcref, optIntfSlotTy, baseValOpt, _safeInitInfo, declaredTyconTypars)), Some memberFlags -> + + CheckMemberFlags optIntfSlotTy newslotsOK overridesOK memberFlags mBinding + + if Option.isSome vis && memberFlags.IsOverrideOrExplicitImpl then + errorR(Error(FSComp.SR.tcOverridesCannotHaveVisibilityDeclarations(), memberId.idRange)) + + // Syntactically push the "this" variable across to be a lambda on the right + let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar thisId) bindingRhs + + // The type being augmented tells us the type of 'this' + let isExtrinsic = (declKind = ExtrinsicExtensionBinding) + let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars + + let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner + + // If private, the member's accessibility is related to 'tcref' + let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic + + let baseValOpt = if tcref.IsFSharpObjectModelTycon then baseValOpt else None + + // Apply the known type of 'this' + let bindingTy = NewInferenceType () + UnifyTypes cenv envinner mBinding ty (thisTy --> bindingTy) + + CheckForNonAbstractInterface declKind tcref memberFlags memberId.idRange + + // Determine if a uniquely-identified-override List.exists based on the information + // at the member signature. If so, we know the type of this member, and the full slotsig + // it implements. Apply the inferred slotsig. + let optInferredImplSlotTys, declaredTypars = + ApplyAbstractSlotInference cenv envinner (bindingTy, mBinding, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, objTy, optIntfSlotTy, valSynInfo, memberFlags, bindingAttribs) + + // Update the ExplicitTyparInfo to reflect the declaredTypars inferred from the abstract slot + let explicitTyparInfo = ExplicitTyparInfo(declaredTypars, declaredTypars, infer) + + // baseValOpt is the 'base' variable associated with the inherited portion of a class + // It is declared once on the 'inheritedTys clause, but a fresh binding is made for + // each member that may use it. + let baseValOpt = + match GetSuperTypeOfType cenv.g cenv.amap mBinding objTy with + | Some superTy -> MakeAndPublishBaseVal cenv envinner (match baseValOpt with None -> None | Some v -> Some v.Id) superTy + | None -> None + + let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, bindingAttribs, optInferredImplSlotTys, memberFlags, valSynInfo, memberId, false) + // This line factored in the 'get' or 'set' as the identifier for a property declaration using "with get () = ... and set v = ..." + // It has been removed from FSharp.Compiler.Service because we want the property name to be the location of + // the definition of these symbols. + // + // See https://github.com/fsharp/FSharp.Compiler.Service/issues/79. + //let memberId = match toolId with Some tid -> ident(memberId.idText, tid.idRange) | None -> memberId + //ignore toolId + + envinner, tpenv, memberId, toolId, Some memberInfo, vis, vis2, None, enclosingDeclaredTypars, baseValOpt, explicitTyparInfo, bindingRhs, declaredTypars + | _ -> + error(Error(FSComp.SR.tcRecursiveBindingsWithMembersMustBeDirectAugmentation(), mBinding)) + +and AnalyzeRecursiveDecl + (cenv, + envinner, + tpenv, + declKind, + synTyparDecls, + declaredTypars, + thisIdOpt, + valSynInfo, + explicitTyparInfo, + newslotsOK, + overridesOK, + vis1, + declPattern, + bindingAttribs, + tcrefContainerInfo, + memberFlagsOpt, + ty, + bindingRhs, + mBinding) = + + let rec analyzeRecursiveDeclPat tpenv p = + match p with + | SynPat.FromParseError(pat', _) -> analyzeRecursiveDeclPat tpenv pat' + | SynPat.Typed(pat', cty, _) -> + let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType envinner tpenv cty + UnifyTypes cenv envinner mBinding ty cty' + analyzeRecursiveDeclPat tpenv pat' + | SynPat.Attrib(_pat', _attribs, m) -> + error(Error(FSComp.SR.tcAttributesInvalidInPatterns(), m)) + //analyzeRecursiveDeclPat pat' + + // This is for the construct 'let rec x = ... and do ... and y = ...' (DEPRECATED IN pars.mly ) + // + // Also for + // module rec M = + // printfn "hello" // side effects in recursive modules + // let x = 1 + | SynPat.Const (SynConst.Unit, m) | SynPat.Wild m -> + let id = ident (cenv.niceNameGen.FreshCompilerGeneratedName("doval", m), m) + analyzeRecursiveDeclPat tpenv (SynPat.Named (id, false, None, m)) + + | SynPat.Named (id, _, vis2, _) -> + AnalyzeRecursiveStaticMemberOrValDecl + (cenv, envinner, tpenv, declKind, + newslotsOK, overridesOK, tcrefContainerInfo, + vis1, id, vis2, declaredTypars, + memberFlagsOpt, thisIdOpt, bindingAttribs, + valSynInfo, ty, bindingRhs, mBinding, explicitTyparInfo) + + | SynPat.InstanceMember(thisId, memberId, toolId, vis2, _) -> + AnalyzeRecursiveInstanceMemberDecl + (cenv, envinner, tpenv, declKind, + synTyparDecls, valSynInfo, explicitTyparInfo, newslotsOK, + overridesOK, vis1, thisId, memberId, toolId, + bindingAttribs, vis2, tcrefContainerInfo, + memberFlagsOpt, ty, bindingRhs, mBinding) + + | _ -> error(Error(FSComp.SR.tcOnlySimplePatternsInLetRec(), mBinding)) + + analyzeRecursiveDeclPat tpenv declPattern + + +/// This is a major routine that generates the Val for a recursive binding +/// prior to the analysis of the definition of the binding. This includes +/// members of all flavours (including properties, implicit class constructors +/// and overrides). At this point we perform override inference, to infer +/// which method we are overriding, in order to add constraints to the +/// implementation of the method. +and AnalyzeAndMakeAndPublishRecursiveValue + overridesOK + isGeneratedEventVal + cenv + (env: TcEnv) + (tpenv, recBindIdx) + (NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, binding)) = + + // Pull apart the inputs + let (NormalizedBinding(vis1, bindingKind, isInline, isMutable, bindingSynAttribs, bindingXmlDoc, synTyparDecls, valSynData, declPattern, bindingRhs, mBinding, spBind)) = binding + let (NormalizedBindingRhs(_, _, bindingExpr)) = bindingRhs + let (SynValData(memberFlagsOpt, valSynInfo, thisIdOpt)) = valSynData + let (ContainerInfo(altActualParent, tcrefContainerInfo)) = containerInfo + + let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt declKind + + // Check the attributes on the declaration + let bindingAttribs = TcAttributes cenv env attrTgt bindingSynAttribs + + // Allocate the type inference variable for the inferred type + let ty = NewInferenceType () + + + let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable mBinding + if isMutable then errorR(Error(FSComp.SR.tcOnlyRecordFieldsAndSimpleLetCanBeMutable(), mBinding)) + + + // Typecheck the typar decls, if any + let explicitTyparInfo, tpenv = TcBindingTyparDecls false cenv env tpenv synTyparDecls + let (ExplicitTyparInfo(_, declaredTypars, _)) = explicitTyparInfo + let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTypars env + + // OK, analyze the declaration and return lots of information about it + let envinner, tpenv, bindingId, toolIdOpt, memberInfoOpt, vis, vis2, safeThisValOpt, enclosingDeclaredTypars, baseValOpt, explicitTyparInfo, bindingRhs, declaredTypars = + + AnalyzeRecursiveDecl (cenv, envinner, tpenv, declKind, synTyparDecls, declaredTypars, thisIdOpt, valSynInfo, explicitTyparInfo, + newslotsOK, overridesOK, vis1, declPattern, bindingAttribs, tcrefContainerInfo, + memberFlagsOpt, ty, bindingRhs, mBinding) + + let optArgsOK = Option.isSome memberFlagsOpt + + // Assert the types given in the argument patterns + ApplyTypesFromArgumentPatterns(cenv, envinner, optArgsOK, ty, mBinding, tpenv, bindingRhs, memberFlagsOpt) + + // Do the type annotations give the full and complete generic type? + // If so, generic recursion can be used when using this type. + let isComplete = ComputeIsComplete enclosingDeclaredTypars declaredTypars ty + + // NOTE: The type scheme here is normally not 'complete'!!!! The type is more or less just a type variable at this point. + // NOTE: top arity, type and typars get fixed-up after inference + let prelimTyscheme = TypeScheme(enclosingDeclaredTypars@declaredTypars, ty) + let partialValReprInfo = TranslateTopValSynInfo mBinding (TcAttributes cenv envinner) valSynInfo + let topValInfo = UseSyntacticArity declKind prelimTyscheme partialValReprInfo + let hasDeclaredTypars = not (List.isEmpty declaredTypars) + let prelimValScheme = ValScheme(bindingId, prelimTyscheme, topValInfo, memberInfoOpt, false, inlineFlag, NormalVal, vis, false, false, false, hasDeclaredTypars) + + // Check the literal r.h.s., if any + let _, literalValue = TcLiteral cenv ty envinner tpenv (bindingAttribs, bindingExpr) + + let extraBindings, extraValues, tpenv, recBindIdx = + let extraBindings = + [ for extraBinding in EventDeclarationNormalization.GenerateExtraBindings cenv (bindingAttribs, binding) do + yield (NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, extraBinding)) ] + let res, (tpenv, recBindIdx) = List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue overridesOK true cenv env) (tpenv, recBindIdx) extraBindings + let extraBindings, extraValues = List.unzip res + List.concat extraBindings, List.concat extraValues, tpenv, recBindIdx + + // Create the value + let vspec = MakeAndPublishVal cenv envinner (altActualParent, false, declKind, ValInRecScope isComplete, prelimValScheme, bindingAttribs, bindingXmlDoc, literalValue, isGeneratedEventVal) + + // Suppress hover tip for "get" and "set" at property definitions, where toolId <> bindingId + match toolIdOpt with + | Some tid when not tid.idRange.IsSynthetic && not (equals tid.idRange bindingId.idRange) -> + let item = Item.Value (mkLocalValRef vspec) + CallNameResolutionSink cenv.tcSink (tid.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.RelatedText, env.eAccessRights) + | _ -> () + + let mangledId = ident(vspec.LogicalName, vspec.Range) + // Reconstitute the binding with the unique name + let revisedBinding = NormalizedBinding (vis1, bindingKind, isInline, isMutable, bindingSynAttribs, bindingXmlDoc, synTyparDecls, valSynData, mkSynPatVar vis2 mangledId, bindingRhs, mBinding, spBind) + + // Create the RecursiveBindingInfo to use in later phases + let rbinfo = + let safeInitInfo = + match tcrefContainerInfo with + | Some(MemberOrValContainerInfo(_, _, _, safeInitInfo, _)) -> safeInitInfo + | _ -> NoSafeInitInfo + + RecursiveBindingInfo(recBindIdx, containerInfo, enclosingDeclaredTypars, inlineFlag, vspec, explicitTyparInfo, partialValReprInfo, memberInfoOpt, baseValOpt, safeThisValOpt, safeInitInfo, vis, ty, declKind) + + let recBindIdx = recBindIdx + 1 + + // Done - add the declared name to the List.map and return the bundle for use by TcLetrec + let primaryBinding: PreCheckingRecursiveBinding = + { SyntacticBinding = revisedBinding + RecBindingInfo = rbinfo } + + ((primaryBinding :: extraBindings), (vspec :: extraValues)), (tpenv, recBindIdx) + +and AnalyzeAndMakeAndPublishRecursiveValues overridesOK cenv env tpenv binds = + let recBindIdx = 0 + let res, tpenv = List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv env) (tpenv, recBindIdx) binds + let bindings, values = List.unzip res + List.concat bindings, List.concat values, tpenv + + +//------------------------------------------------------------------------- +// TcLetrecBinding +//------------------------------------------------------------------------- + +and TcLetrecBinding + (cenv, envRec: TcEnv, scopem, extraGeneralizableTypars: Typars, reqdThisValTyOpt: TType option) + + // The state of the left-to-right iteration through the bindings + (envNonRec: TcEnv, + generalizedRecBinds: PostGeneralizationRecursiveBinding list, + preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, + tpenv, + uncheckedRecBindsTable: Map) + + // This is the actual binding to check + (rbind: PreCheckingRecursiveBinding) = + + let (RecursiveBindingInfo(_, _, enclosingDeclaredTypars, _, vspec, explicitTyparInfo, _, _, baseValOpt, safeThisValOpt, safeInitInfo, _, tau, declKind)) = rbind.RecBindingInfo + + let allDeclaredTypars = enclosingDeclaredTypars @ rbind.RecBindingInfo.DeclaredTypars + + // Notes on FSharp 1.0, 3187: + // - Progressively collect the "eligible for early generalization" set of bindings -- DONE + // - After checking each binding, check this set to find generalizable bindings + // - The only reason we can't generalize is if a binding refers to type variables to which + // additional constraints may be applied as part of checking a later binding + // - Compute the set by iteratively knocking out bindings that refer to type variables free in later bindings + // - Implementation notes: + // - Generalize by remap/substitution + // - Pass in "free in later bindings" by passing in the set of inference variables for the bindings, i.e. the binding types + // - For classes the bindings will include all members in a recursive group of types + // + + // Example 1: + // let f() = g() f: unit -> ?b + // and g() = 1 f: unit -> int, can generalize (though now monomorphic) + + // Example 2: + // let f() = g() f: unit -> ?b + // and g() = [] f: unit -> ?c list, can generalize + + // Example 3: + // let f() = [] f: unit -> ?b, can generalize immediately + // and g() = [] + let envRec = Option.foldBack (AddLocalVal cenv.g cenv.tcSink scopem) baseValOpt envRec + let envRec = Option.foldBack (AddLocalVal cenv.g cenv.tcSink scopem) safeThisValOpt envRec + + // Members can access protected members of parents of the type, and private members in the type + let envRec = MakeInnerEnvForMember envRec vspec + + let checkedBind, tpenv = + TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, explicitTyparInfo) rbind.SyntacticBinding + + (try UnifyTypes cenv envRec vspec.Range (allDeclaredTypars +-> tau) vspec.Type + with e -> error (Recursion(envRec.DisplayEnv, vspec.Id, tau, vspec.Type, vspec.Range))) + + // Inside the incremental class syntax we assert the type of the 'this' variable to be precisely the same type as the + // this variable for the implicit class constructor. For static members, we assert the type variables associated + // for the class to be identical to those used for the implicit class constructor and the static class constructor. + match reqdThisValTyOpt with + | None -> () + | Some reqdThisValTy -> + let reqdThisValTy, actualThisValTy, rangeForCheck = + match GetInstanceMemberThisVariable (vspec, checkedBind.Expr) with + | None -> + let reqdThisValTy = if isByrefTy cenv.g reqdThisValTy then destByrefTy cenv.g reqdThisValTy else reqdThisValTy + let enclosingTyconRef = tcrefOfAppTy cenv.g reqdThisValTy + reqdThisValTy, (mkAppTy enclosingTyconRef (List.map mkTyparTy enclosingDeclaredTypars)), vspec.Range + | Some thisVal -> + reqdThisValTy, thisVal.Type, thisVal.Range + if not (AddCxTypeEqualsTypeUndoIfFailed envRec.DisplayEnv cenv.css rangeForCheck actualThisValTy reqdThisValTy) then + errorR (Error(FSComp.SR.tcNonUniformMemberUse vspec.DisplayName, vspec.Range)) + + let preGeneralizationRecBind = + { RecBindingInfo = rbind.RecBindingInfo + CheckedBinding= checkedBind + ExtraGeneralizableTypars= extraGeneralizableTypars } + + // Remove one binding from the unchecked list + let uncheckedRecBindsTable = + assert (uncheckedRecBindsTable.ContainsKey rbind.RecBindingInfo.Val.Stamp) + uncheckedRecBindsTable.Remove rbind.RecBindingInfo.Val.Stamp + + // Add one binding to the candidates eligible for generalization + let preGeneralizationRecBinds = (preGeneralizationRecBind :: preGeneralizationRecBinds) + + // Incrementally generalize as many bindings as we can + TcIncrementalLetRecGeneralization cenv scopem (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) + +and TcIncrementalLetRecGeneralization cenv scopem + // The state of the left-to-right iteration through the bindings + (envNonRec: TcEnv, + generalizedRecBinds: PostGeneralizationRecursiveBinding list, + preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, + tpenv, + uncheckedRecBindsTable: Map) = + + let denv = envNonRec.DisplayEnv + // recompute the free-in-environment in case any type variables have been instantiated + let freeInEnv = GeneralizationHelpers.ComputeUngeneralizableTypars envNonRec + + // Attempt to actually generalize some of the candidates eligible for generalization. + // Compute which bindings are now eligible for early generalization. + // Do this by computing a greatest fixed point by iteratively knocking out bindings that refer + // to type variables free in later bindings. Look for ones whose type doesn't involve any of the other types + let newGeneralizedRecBinds, preGeneralizationRecBinds, tpenv = + + //printfn "\n---------------------\nConsidering early generalization after type checking binding %s" vspec.DisplayName + + // Get the type variables free in bindings that have not yet been checked. + // + // The naive implementation of this is to iterate all the forward bindings, but this is quadratic. + // + // It turns out we can remove the quadratic behaviour as follows. + // - During type checking we already keep a table of recursive uses of values, indexed by target value. + // - This table is usually much smaller than the number of remaining forward declarations ? e.g. in the pathological case you mentioned below this table is size 1. + // - If a forward declaration does not have an entry in this table then its type can't involve any inference variables from the declarations we have already checked. + // - So by scanning the domain of this table we can reduce the complexity down to something like O(n * average-number-of-forward-calls). + // - For a fully connected programs or programs where every forward declaration is subject to a forward call, this would be quadratic. However we do not expect call graphs to be like this in practice + // + // Hence we use the recursive-uses table to guide the process of scraping forward references for frozen types + // If the is no entry in the recursive use table then a forward binding has never been used and + // the type of a binding will not contain any inference variables. + // + // We do this lazily in case it is "obvious" that a binding can be generalized (e.g. its type doesn't + // involve any type inference variables) + // + // The forward uses table will always be smaller than the number of potential forward bindings except in extremely + // pathological situations + let freeInUncheckedRecBinds = + lazy ((emptyFreeTyvars, cenv.recUses.Contents) ||> Map.fold (fun acc vStamp _ -> + match uncheckedRecBindsTable.TryGetValue vStamp with + | true, fwdBind -> + accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc + | _ -> + acc)) + + let rec loop (preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, + frozenBindings: PreGeneralizationRecursiveBinding list) = + + let frozenBindingTypes = frozenBindings |> List.map (fun pgrbind -> pgrbind.RecBindingInfo.Val.Type) + + let freeInFrozenAndLaterBindings = + if frozenBindingTypes.IsEmpty then + freeInUncheckedRecBinds + else + lazy (accFreeInTypes CollectAllNoCaching frozenBindingTypes (freeInUncheckedRecBinds.Force())) + + let preGeneralizationRecBinds, newFrozenBindings = + + preGeneralizationRecBinds |> List.partition (fun pgrbind -> + + //printfn "(testing binding %s)" pgrbind.RecBindingInfo.Val.DisplayName + + // Get the free type variables in the binding + // + // We use the TauType here because the binding may already have been pre-generalized because it has + // a fully type-annotated type signature. We effectively want to generalize the binding + // again here, properly - for example this means adjusting the expression for the binding to include + // a Expr_tlambda. If we use Val.Type then the type will appear closed. + let freeInBinding = (freeInType CollectAllNoCaching pgrbind.RecBindingInfo.Val.TauType).FreeTypars + + // Is the binding free of type inference variables? If so, it can be generalized immediately + if freeInBinding.IsEmpty then true else + + //printfn "(failed generalization test 1 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName + // Any declared type parameters in an type are always generalizable + let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) + + if freeInBinding.IsEmpty then true else + + //printfn "(failed generalization test 2 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName + + // Any declared method parameters can always be generalized + let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.RecBindingInfo.DeclaredTypars)) + + if freeInBinding.IsEmpty then true else + + //printfn "(failed generalization test 3 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName + + // Type variables free in the non-recursive environment do not stop us generalizing the binding, + // since they can't be generalized anyway + let freeInBinding = Zset.diff freeInBinding freeInEnv + + if freeInBinding.IsEmpty then true else + + //printfn "(failed generalization test 4 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName + + // Type variables free in unchecked bindings do stop us generalizing + let freeInBinding = Zset.inter (freeInFrozenAndLaterBindings.Force().FreeTypars) freeInBinding + + if freeInBinding.IsEmpty then true else + + //printfn "(failed generalization test 5 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName + + false) + //if canGeneralize then + // printfn "YES: binding for %s can be generalized early" pgrbind.RecBindingInfo.Val.DisplayName + //else + // printfn "NO: binding for %s can't be generalized early" pgrbind.RecBindingInfo.Val.DisplayName + + // Have we reached a fixed point? + if newFrozenBindings.IsEmpty then + preGeneralizationRecBinds, frozenBindings + else + // if not, then repeat + loop(preGeneralizationRecBinds, newFrozenBindings@frozenBindings) + + // start with no frozen bindings + let newGeneralizableBindings, preGeneralizationRecBinds = loop(preGeneralizationRecBinds, []) + + // Some of the bindings may now have been marked as 'generalizable' (which means they now transition + // from PreGeneralization --> PostGeneralization, since we won't get any more information on + // these bindings by processing later bindings). But this doesn't mean we + // actually generalize all the individual type variables occuring in these bindings - for example, some + // type variables may be free in the environment, and some definitions + // may be value definitions which can't be generalized, e.g. + // let rec f x = g x + // and g = id f + // Here the type variables in 'g' can't be generalized because it's a computation on the right. + // + // Note that in the normal case each binding passes IsGeneralizableValue. Properties and + // constructors do not pass CanInferExtraGeneralizedTyparsForRecBinding. + + let freeInEnv = + (freeInEnv, newGeneralizableBindings) ||> List.fold (fun freeInEnv pgrbind -> + if GeneralizationHelpers.IsGeneralizableValue cenv.g pgrbind.CheckedBinding.Expr then + freeInEnv + else + let freeInBinding = (freeInType CollectAllNoCaching pgrbind.RecBindingInfo.Val.TauType).FreeTypars + let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) + let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.RecBindingInfo.DeclaredTypars)) + Zset.union freeInBinding freeInEnv) + + // Process the bindings marked for transition from PreGeneralization --> PostGeneralization + let newGeneralizedRecBinds, tpenv = + if newGeneralizableBindings.IsEmpty then + [], tpenv + else + + let supportForBindings = newGeneralizableBindings |> List.collect (TcLetrecComputeSupportForBinding cenv) + CanonicalizePartialInferenceProblem cenv.css denv scopem supportForBindings + + let generalizedTyparsL = newGeneralizableBindings |> List.map (TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv) + + // Generalize the bindings. + let newGeneralizedRecBinds = (generalizedTyparsL, newGeneralizableBindings) ||> List.map2 (TcLetrecGeneralizeBinding cenv denv ) + let tpenv = HideUnscopedTypars (List.concat generalizedTyparsL) tpenv + newGeneralizedRecBinds, tpenv + + + newGeneralizedRecBinds, preGeneralizationRecBinds, tpenv + + let envNonRec = envNonRec |> AddLocalVals cenv.g cenv.tcSink scopem (newGeneralizedRecBinds |> List.map (fun b -> b.RecBindingInfo.Val)) + let generalizedRecBinds = newGeneralizedRecBinds @ generalizedRecBinds + + (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) + +//------------------------------------------------------------------------- +// TcLetrecComputeAndGeneralizeGenericTyparsForBinding +//------------------------------------------------------------------------- + +/// Compute the type variables which may be generalized and perform the generalization +and TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv (pgrbind: PreGeneralizationRecursiveBinding) = + + let freeInEnv = Zset.diff freeInEnv (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) + + let rbinfo = pgrbind.RecBindingInfo + let vspec = rbinfo.Val + let (CheckedBindingInfo(inlineFlag, _, _, _, _, _, expr, _, _, m, _, _, _, _)) = pgrbind.CheckedBinding + let (ExplicitTyparInfo(rigidCopyOfDeclaredTypars, declaredTypars, _)) = rbinfo.ExplicitTyparInfo + let allDeclaredTypars = rbinfo.EnclosingDeclaredTypars @ declaredTypars + + // The declared typars were not marked rigid to allow equi-recursive type inference to unify + // two declared type variables. So we now check that, for each binding, the declared + // type variables can be unified with a rigid version of the same and undo the results + // of this unification. + CheckDeclaredTypars denv cenv.css m rigidCopyOfDeclaredTypars declaredTypars + + let memFlagsOpt = vspec.MemberInfo |> Option.map (fun memInfo -> memInfo.MemberFlags) + let isCtor = (match memFlagsOpt with None -> false | Some memberFlags -> memberFlags.MemberKind = SynMemberKind.Constructor) + + GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, declaredTypars, m) + let canInferTypars = CanInferExtraGeneralizedTyparsForRecBinding pgrbind + + let tau = vspec.TauType + let maxInferredTypars = freeInTypeLeftToRight cenv.g false tau + + let canGeneralizeConstrained = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl rbinfo.DeclKind + let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars (cenv, denv, m, freeInEnv, canInferTypars, canGeneralizeConstrained, inlineFlag, Some expr, allDeclaredTypars, maxInferredTypars, tau, isCtor) + generalizedTypars + +/// Compute the type variables which may have member constraints that need to be canonicalized prior to generalization +and TcLetrecComputeSupportForBinding cenv (pgrbind: PreGeneralizationRecursiveBinding) = + let rbinfo = pgrbind.RecBindingInfo + let allDeclaredTypars = rbinfo.EnclosingDeclaredTypars @ rbinfo.DeclaredTypars + let maxInferredTypars = freeInTypeLeftToRight cenv.g false rbinfo.Val.TauType + allDeclaredTypars @ maxInferredTypars + +//------------------------------------------------------------------------- +// TcLetrecGeneralizeBinding +//------------------------------------------------------------------------ + +// Generalise generalizedTypars from checkedBind. +and TcLetrecGeneralizeBinding cenv denv generalizedTypars (pgrbind: PreGeneralizationRecursiveBinding) : PostGeneralizationRecursiveBinding = + + let (RecursiveBindingInfo(_, _, enclosingDeclaredTypars, _, vspec, explicitTyparInfo, partialValReprInfo, memberInfoOpt, _, _, _, vis, _, declKind)) = pgrbind.RecBindingInfo + let (CheckedBindingInfo(inlineFlag, _, _, _, _, _, expr, argAttribs, _, _, _, compgen, _, isFixed)) = pgrbind.CheckedBinding + + if isFixed then + errorR(Error(FSComp.SR.tcFixedNotAllowed(), expr.Range)) + + let _, tau = vspec.TypeScheme + + let pvalscheme1 = PrelimValScheme1(vspec.Id, explicitTyparInfo, tau, Some partialValReprInfo, memberInfoOpt, false, inlineFlag, NormalVal, argAttribs, vis, compgen) + let pvalscheme2 = GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars pvalscheme1 + + let valscheme = UseCombinedArity cenv.g declKind expr pvalscheme2 + AdjustRecType vspec valscheme + + { ValScheme = valscheme + CheckedBinding = pgrbind.CheckedBinding + RecBindingInfo = pgrbind.RecBindingInfo } + + +and TcLetrecComputeCtorSafeThisValBind cenv safeThisValOpt = + match safeThisValOpt with + | None -> None + | Some (v: Val) -> + let m = v.Range + let ty = destRefCellTy cenv.g v.Type + Some (mkCompGenBind v (mkRefCell cenv.g m ty (mkNull m ty))) + +and MakeCheckSafeInitField g tinst thisValOpt rfref reqExpr (expr: Expr) = + let m = expr.Range + let availExpr = + match thisValOpt with + | None -> mkStaticRecdFieldGet (rfref, tinst, m) + | Some thisVar -> + // This is an instance method, it must have a 'this' var + mkRecdFieldGetViaExprAddr (exprForVal m thisVar, rfref, tinst, m) + let failureExpr = match thisValOpt with None -> mkCallFailStaticInit g m | Some _ -> mkCallFailInit g m + mkCompGenSequential m (mkIfThen g m (mkILAsmClt g m availExpr reqExpr) failureExpr) expr + +and MakeCheckSafeInit g tinst safeInitInfo reqExpr expr = + match safeInitInfo with + | SafeInitField (rfref, _) -> MakeCheckSafeInitField g tinst None rfref reqExpr expr + | NoSafeInitInfo -> expr + +// Given a method binding (after generalization) +// +// method M = (fun -> ) +// +// wrap the following around it if needed +// +// method M = (fun baseVal -> +// check ctorSafeInitInfo +// let ctorSafeThisVal = ref null +// ) +// +// The "check ctorSafeInitInfo" is only added for non-constructor instance members in a class where at least one type in the +// hierarchy has HasSelfReferentialConstructor +// +// The "let ctorSafeThisVal = ref null" is only added for explicit constructors with a self-reference parameter (Note: check later code for exact conditions) +// For implicit constructors the binding is added to the bindings of the implicit constructor + +and TcLetrecAdjustMemberForSpecialVals cenv (pgrbind: PostGeneralizationRecursiveBinding) : PostSpecialValsRecursiveBinding = + + let (RecursiveBindingInfo(_, _, _, _, vspec, _, _, _, baseValOpt, safeThisValOpt, safeInitInfo, _, _, _)) = pgrbind.RecBindingInfo + let expr = pgrbind.CheckedBinding.Expr + let spBind = pgrbind.CheckedBinding.SeqPoint + + let expr = + match TcLetrecComputeCtorSafeThisValBind cenv safeThisValOpt with + | None -> expr + | Some bind -> + let m = expr.Range + let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) + mkMultiLambdas m tps vsl (mkLetBind m bind body, returnTy) + + // Add a call to CheckInit if necessary for instance members + let expr = + if vspec.IsInstanceMember && not vspec.IsExtensionMember && not vspec.IsConstructor then + match safeInitInfo with + | SafeInitField (rfref, _) -> + let m = expr.Range + let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) + // This is an instance member, it must have a 'this' + let thisVar = vsl.Head.Head + let thisTypeInst = argsOfAppTy cenv.g thisVar.Type + let newBody = MakeCheckSafeInitField cenv.g thisTypeInst (Some thisVar) rfref (mkOne cenv.g m) body + mkMultiLambdas m tps vsl (newBody, returnTy) + | NoSafeInitInfo -> + expr + + else + expr + + let expr = + match baseValOpt with + | None -> expr + | _ -> + let m = expr.Range + let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) + mkMemberLambdas m tps None baseValOpt vsl (body, returnTy) + + { ValScheme = pgrbind.ValScheme + Binding = TBind(vspec, expr, spBind) } + +and FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock (bind: PostSpecialValsRecursiveBinding) = + let (TBind(vspec, expr, spBind)) = bind.Binding + + // Check coherence of generalization of variables for memberInfo members in generic classes + match vspec.MemberInfo with +#if EXTENDED_EXTENSION_MEMBERS // indicates if extension members can add additional constraints to type parameters + | Some _ when not vspec.IsExtensionMember -> +#else + | Some _ -> +#endif + match PartitionValTyparsForApparentEnclosingType cenv.g vspec with + | Some(parentTypars, memberParentTypars, _, _, _) -> + ignore(SignatureConformance.Checker(cenv.g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.Empty memberParentTypars parentTypars) + | None -> + errorR(Error(FSComp.SR.tcMemberIsNotSufficientlyGeneric(), vspec.Range)) + | _ -> () + + // Fixup recursive references... + let fixupPoints = GetAllUsesOfRecValue cenv vspec + + AdjustAndForgetUsesOfRecValue cenv (mkLocalValRef vspec) bind.ValScheme + + let expr = mkGenericBindRhs cenv.g vspec.Range generalizedTyparsForRecursiveBlock bind.ValScheme.TypeScheme expr + + { FixupPoints = fixupPoints + Binding = TBind(vspec, expr, spBind) } + +//------------------------------------------------------------------------- +// TcLetrec - for both expressions and class-let-rec-declarations +//------------------------------------------------------------------------ + +and unionGeneralizedTypars typarSets = List.foldBack (ListSet.unionFavourRight typarEq) typarSets [] + +and TcLetrec overridesOK cenv env tpenv (binds, bindsm, scopem) = + + // Create prelimRecValues for the recursive items (includes type info from LHS of bindings) *) + let binds = binds |> List.map (fun (RecDefnBindingInfo(a, b, c, bind)) -> NormalizedRecBindingDefn(a, b, c, BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env bind)) + let uncheckedRecBinds, prelimRecValues, (tpenv, _) = AnalyzeAndMakeAndPublishRecursiveValues overridesOK cenv env tpenv binds + + let envRec = AddLocalVals cenv.g cenv.tcSink scopem prelimRecValues env + + // Typecheck bindings + let uncheckedRecBindsTable = uncheckedRecBinds |> List.map (fun rbind -> rbind.RecBindingInfo.Val.Stamp, rbind) |> Map.ofList + + let _, generalizedRecBinds, preGeneralizationRecBinds, tpenv, _ = + ((env, [], [], tpenv, uncheckedRecBindsTable), uncheckedRecBinds) ||> List.fold (TcLetrecBinding (cenv, envRec, scopem, [], None)) + + // There should be no bindings that have not been generalized since checking the vary last binding always + // results in the generalization of all remaining ungeneralized bindings, since there are no remaining unchecked bindings + // to prevent the generalization + assert preGeneralizationRecBinds.IsEmpty + + let generalizedRecBinds = generalizedRecBinds |> List.sortBy (fun pgrbind -> pgrbind.RecBindingInfo.Index) + let generalizedTyparsForRecursiveBlock = + generalizedRecBinds + |> List.map (fun pgrbind -> pgrbind.GeneralizedTypars) + |> unionGeneralizedTypars + + + let vxbinds = generalizedRecBinds |> List.map (TcLetrecAdjustMemberForSpecialVals cenv) + + // Now that we know what we've generalized we can adjust the recursive references + let vxbinds = vxbinds |> List.map (FixupLetrecBind cenv env.DisplayEnv generalizedTyparsForRecursiveBlock) + + // Now eliminate any initialization graphs + let binds = + let bindsWithoutLaziness = vxbinds + let mustHaveArity = + match uncheckedRecBinds with + | [] -> false + | rbind :: _ -> DeclKind.MustHaveArity rbind.RecBindingInfo.DeclKind + + let results = + EliminateInitializationGraphs + cenv.g mustHaveArity env.DisplayEnv + bindsWithoutLaziness + //(fun + (fun doBindings bindings -> doBindings bindings) + (fun bindings -> bindings) + (fun doBindings bindings -> [doBindings bindings]) + bindsm + List.concat results + + // Post letrec env + let envbody = AddLocalVals cenv.g cenv.tcSink scopem prelimRecValues env + binds, envbody, tpenv + +//------------------------------------------------------------------------- +// Bind specifications of values +//------------------------------------------------------------------------- + +let TcAndPublishValSpec (cenv, env, containerInfo: ContainerInfo, declKind, memFlagsOpt, tpenv, valSpfn) = + + let (SynValSig (Attributes synAttrs, _, ValTyparDecls (synTypars, _, synCanInferTypars), _, _, isInline, mutableFlag, doc, vis, literalExprOpt, m)) = valSpfn + + GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, synTypars, m) + let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, synCanInferTypars, memFlagsOpt) + + let attrTgt = DeclKind.AllowedAttribTargets memFlagsOpt declKind + + let attrs = TcAttributes cenv env attrTgt synAttrs + let newOk = if canInferTypars then NewTyparsOK else NoNewTypars + + let valinfos, tpenv = TcValSpec cenv env declKind newOk containerInfo memFlagsOpt None tpenv valSpfn attrs + let denv = env.DisplayEnv + + (tpenv, valinfos) ||> List.mapFold (fun tpenv valSpecResult -> + + let (ValSpecResult (altActualParent, memberInfoOpt, id, enclosingDeclaredTypars, declaredTypars, ty, partialValReprInfo, declKind)) = valSpecResult + + let inlineFlag = ComputeInlineFlag (memberInfoOpt |> Option.map (fun (PreValMemberInfo(memberInfo, _, _)) -> memberInfo.MemberFlags)) isInline mutableFlag m + + let freeInType = freeInTypeLeftToRight cenv.g false ty + + let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars + + let explicitTyparInfo = ExplicitTyparInfo(declaredTypars, declaredTypars, synCanInferTypars) + + let generalizedTypars = + GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv, denv, id.idRange, + emptyFreeTypars, canInferTypars, CanGeneralizeConstrainedTypars, inlineFlag, + None, allDeclaredTypars, freeInType, ty, false) + + let valscheme1 = PrelimValScheme1(id, explicitTyparInfo, ty, Some partialValReprInfo, memberInfoOpt, mutableFlag, inlineFlag, NormalVal, noArgOrRetAttribs, vis, false) + + let valscheme2 = GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars valscheme1 + + let tpenv = HideUnscopedTypars generalizedTypars tpenv + + let valscheme = BuildValScheme declKind (Some partialValReprInfo) valscheme2 + + let literalValue = + match literalExprOpt with + | None -> + let hasLiteralAttr = HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs + if hasLiteralAttr then + errorR(Error(FSComp.SR.tcLiteralAttributeRequiresConstantValue(), m)) + None + + | Some e -> + let hasLiteralAttr, literalValue = TcLiteral cenv ty env tpenv (attrs, e) + if not hasLiteralAttr then + errorR(Error(FSComp.SR.tcValueInSignatureRequiresLiteralAttribute(), e.Range)) + literalValue + + let paramNames = + match valscheme.ValReprInfo with + | None -> None + | Some topValInfo -> topValInfo.ArgNames + + let doc = doc.ToXmlDoc(true, paramNames) + let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, doc, literalValue, false) + assert(vspec.InlineInfo = inlineFlag) + + vspec, tpenv) diff --git a/src/fsharp/CheckExpressions.fsi b/src/fsharp/CheckExpressions.fsi new file mode 100644 index 00000000000..e430ce66fa0 --- /dev/null +++ b/src/fsharp/CheckExpressions.fsi @@ -0,0 +1,797 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CheckExpressions + +open System +open Internal.Utilities.Collections +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.Import +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Infos +open FSharp.Compiler.MethodOverrides +open FSharp.Compiler.NameResolution +open FSharp.Compiler.PatternMatchCompilation +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +/// Represents information about the initialization field used to check that object constructors +/// have completed before fields are accessed. +type SafeInitData = + | SafeInitField of RecdFieldRef * RecdField + | NoSafeInitInfo + +/// Represents information about object constructors +[] +type CtorInfo + +val InitialImplicitCtorInfo: unit -> CtorInfo + +/// Represents an item in the environment that may restrict the automatic generalization of later +/// declarations because it refers to type inference variables. As type inference progresses +/// these type inference variables may get solved. +[] +type UngeneralizableItem + +[] +/// Represents the type environment at a particular scope. Includes the name +/// resolution environment, the ungeneralizable items from earlier in the scope +/// and other information about the scope. +type TcEnv = + { /// Name resolution information + eNameResEnv: NameResolutionEnv + + /// The list of items in the environment that may contain free inference + /// variables (which may not be generalized). The relevant types may + /// change as a result of inference equations being asserted, hence may need to + /// be recomputed. + eUngeneralizableItems: UngeneralizableItem list + + // Two (!) versions of the current module path + // These are used to: + // - Look up the appropriate point in the corresponding signature + // see if an item is public or not + // - Change fslib canonical module type to allow compiler references to these items + // - Record the cpath for concrete modul_specs, tycon_specs and excon_specs so they can cache their generated IL representation where necessary + // - Record the pubpath of public, concrete {val, tycon, modul, excon}_specs. + // This information is used mainly when building non-local references + // to public items. + // + // Of the two, 'ePath' is the one that's barely used. It's only + // used by UpdateAccModuleOrNamespaceType to modify the CCU while compiling FSharp.Core + ePath: Ident list + + eCompPath: CompilationPath + + eAccessPath: CompilationPath + + /// This field is computed from other fields, but we amortize the cost of computing it. + eAccessRights: AccessorDomain + + /// Internals under these should be accessible + eInternalsVisibleCompPaths: CompilationPath list + + /// Mutable accumulator for the current module type + eModuleOrNamespaceTypeAccumulator: ModuleOrNamespaceType ref + + /// Context information for type checker + eContextInfo: ContextInfo + + /// Here Some tcref indicates we can access protected members in all super types + eFamilyType: TyconRef option + + // Information to enforce special restrictions on valid expressions + // for .NET constructors. + eCtorInfo: CtorInfo option + + eCallerMemberName: string option + + // Active arg infos in iterated lambdas , allowing us to determine the attributes of arguments + eLambdaArgInfos: ArgReprInfo list list + } + + member DisplayEnv : DisplayEnv + member NameEnv : NameResolutionEnv + member AccessRights : AccessorDomain + +//------------------------------------------------------------------------- +// Some of the exceptions arising from type checking. These should be moved to +// use ErrorLogger. +//------------------------------------------------------------------------- + +exception BakedInMemberConstraintName of string * range +exception FunctionExpected of DisplayEnv * TType * range +exception NotAFunction of DisplayEnv * TType * range * range +exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range * bool +exception Recursion of DisplayEnv * Ident * TType * TType * range +exception RecursiveUseCheckedAtRuntime of DisplayEnv * ValRef * range +exception LetRecEvaluatedOutOfOrder of DisplayEnv * ValRef * ValRef * range +exception LetRecCheckedAtRuntime of range +exception LetRecUnsound of DisplayEnv * ValRef list * range +exception TyconBadArgs of DisplayEnv * TyconRef * int * range +exception UnionCaseWrongArguments of DisplayEnv * int * int * range +exception UnionCaseWrongNumberOfArgs of DisplayEnv * int * int * range +exception FieldsFromDifferentTypes of DisplayEnv * RecdFieldRef * RecdFieldRef * range +exception FieldGivenTwice of DisplayEnv * RecdFieldRef * range +exception MissingFields of string list * range +exception UnitTypeExpected of DisplayEnv * TType * range +exception UnitTypeExpectedWithEquality of DisplayEnv * TType * range +exception UnitTypeExpectedWithPossiblePropertySetter of DisplayEnv * TType * string * string * range +exception UnitTypeExpectedWithPossibleAssignment of DisplayEnv * TType * bool * string * range +exception FunctionValueUnexpected of DisplayEnv * TType * range +exception UnionPatternsBindDifferentNames of range +exception VarBoundTwice of Ident +exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range +exception ValNotMutable of DisplayEnv * ValRef * range +exception ValNotLocal of DisplayEnv * ValRef * range +exception InvalidRuntimeCoercion of DisplayEnv * TType * TType * range +exception IndeterminateRuntimeCoercion of DisplayEnv * TType * TType * range +exception IndeterminateStaticCoercion of DisplayEnv * TType * TType * range +exception StaticCoercionShouldUseBox of DisplayEnv * TType * TType * range +exception RuntimeCoercionSourceSealed of DisplayEnv * TType * range +exception CoercionTargetSealed of DisplayEnv * TType * range +exception UpcastUnnecessary of range +exception TypeTestUnnecessary of range +exception SelfRefObjCtor of bool * range +exception VirtualAugmentationOnNullValuedType of range +exception NonVirtualAugmentationOnNullValuedType of range +exception UseOfAddressOfOperator of range +exception DeprecatedThreadStaticBindingWarning of range +exception IntfImplInIntrinsicAugmentation of range +exception IntfImplInExtrinsicAugmentation of range +exception OverrideInIntrinsicAugmentation of range +exception OverrideInExtrinsicAugmentation of range +exception NonUniqueInferredAbstractSlot of TcGlobals * DisplayEnv * string * MethInfo * MethInfo * range +exception StandardOperatorRedefinitionWarning of string * range +exception InvalidInternalsVisibleToAssemblyName of (*badName*)string * (*fileName option*) string option + +val TcFieldInit : range -> ILFieldInit -> Const + +val LightweightTcValForUsingInBuildMethodCall : g : TcGlobals -> vref:ValRef -> vrefFlags : ValUseFlag -> vrefTypeInst : TTypes -> m : range -> Expr * TType + +//------------------------------------------------------------------------- +// The rest are all helpers needed for declaration checking (CheckDeclarations.fs) +//------------------------------------------------------------------------- + +/// Represents the current environment of type variables that have implicit scope +/// (i.e. are without explicit declaration). +type UnscopedTyparEnv + +/// Represents the compilation environment for typechecking a single file in an assembly. +[] +type TcFileState = + { g: TcGlobals + + /// Push an entry every time a recursive value binding is used, + /// in order to be able to fix up recursive type applications as + /// we infer type parameters + mutable recUses: ValMultiMap + + /// Checks to run after all inference is complete. + mutable postInferenceChecks: ResizeArray unit> + + /// Set to true if this file causes the creation of generated provided types. + mutable createsGeneratedProvidedTypes: bool + + /// Are we in a script? if so relax the reporting of discarded-expression warnings at the top level + isScript: bool + + /// Environment needed to convert IL types to F# types in the importer. + amap: ImportMap + + /// Used to generate new syntactic argument names in post-parse syntactic processing + synArgNameGenerator: SynArgNameGenerator + + tcSink: TcResultsSink + + /// Holds a reference to the component being compiled. + /// This field is very rarely used (mainly when fixing up forward references to fslib. + topCcu: CcuThunk + + /// Holds the current inference constraints + css: ConstraintSolverState + + /// Are we compiling the signature of a module from fslib? + compilingCanonicalFslibModuleType: bool + + /// Is this a .fsi file? + isSig: bool + + /// Does this .fs file have a .fsi file? + haveSig: bool + + /// Used to generate names + niceNameGen: NiceNameGenerator + + /// Used to read and cache information about types and members + infoReader: InfoReader + + /// Used to resolve names + nameResolver: NameResolver + + /// The set of active conditional defines. The value is None when conditional erasure is disabled in tooling. + conditionalDefines: string list option + + isInternalTestSpanStackReferring: bool + // forward call + TcSequenceExpressionEntry: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv + + // forward call + TcArrayOrListComputedExpression: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv + + // forward call + TcComputationExpression: TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> range * Expr * TType * SynExpr -> Expr * UnscopedTyparEnv + } + static member Create: + g: TcGlobals * + isScript: bool * + niceNameGen: NiceNameGenerator * + amap: ImportMap * + topCcu: CcuThunk * + isSig: bool * + haveSig: bool * + conditionalDefines: string list option * + tcSink: TcResultsSink * + tcVal: TcValF * + isInternalTestSpanStackReferring: bool * + // forward call to CheckComputationExpressions.fs + tcSequenceExpressionEntry: (TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv) * + // forward call to CheckComputationExpressions.fs + tcArrayOrListSequenceExpression: (TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> bool * SynExpr -> range -> Expr * UnscopedTyparEnv) * + // forward call to CheckComputationExpressions.fs + tcComputationExpression: (TcFileState -> TcEnv -> OverallTy -> UnscopedTyparEnv -> range * Expr * TType * SynExpr -> Expr * UnscopedTyparEnv) + -> TcFileState + +/// Represents information about the module or type in which a member or value is declared. +type MemberOrValContainerInfo = + | MemberOrValContainerInfo of + tcref: TyconRef * + optIntfSlotTy: (TType * SlotImplSet) option * + baseValOpt: Val option * + safeInitInfo: SafeInitData * + declaredTyconTypars: Typars + +/// Provides information about the context for a value or member definition. +type ContainerInfo = + | ContainerInfo of + ParentRef * + MemberOrValContainerInfo option + member ParentRef : ParentRef + +val ExprContainerInfo: ContainerInfo + +/// Indicates if member declarations are allowed to be abstract members. +type NewSlotsOK = + | NewSlotsOK + | NoNewSlots + +/// Indicates if member declarations are allowed to be override members. +type OverridesOK = + | OverridesOK + | WarnOnOverrides + | ErrorOnOverrides + +/// A flag to represent the sort of bindings are we processing. +type DeclKind = + /// A binding in a module, or a member + | ModuleOrMemberBinding + + /// Extensions to a type within the same assembly + | IntrinsicExtensionBinding + + /// Extensions to a type in a different assembly + | ExtrinsicExtensionBinding + + /// A binding in a class + | ClassLetBinding of isStatic: bool + + /// A binding in an object expression + | ObjectExpressionOverrideBinding + + /// A binding in an expression + | ExpressionBinding + + static member IsModuleOrMemberOrExtensionBinding: DeclKind -> bool + + static member MustHaveArity: DeclKind -> bool + + member CanBeDllImport: bool + + static member IsAccessModifierPermitted: DeclKind -> bool + + static member ImplicitlyStatic: DeclKind -> bool + + static member AllowedAttribTargets: SynMemberFlags option -> DeclKind -> AttributeTargets + + // Note: now always true + static member CanGeneralizeConstrainedTypars: DeclKind -> bool + + static member ConvertToLinearBindings: DeclKind -> bool + + static member CanOverrideOrImplement: DeclKind -> OverridesOK + +/// Indicates whether a syntactic type is allowed to include new type variables +/// not declared anywhere, e.g. `let f (x: 'T option) = x.Value` +type ImplicitlyBoundTyparsAllowed = + | NewTyparsOKButWarnIfNotRigid + | NewTyparsOK + | NoNewTypars + +/// Indicates whether constraints should be checked when checking syntactic types +type CheckConstraints = + | CheckCxs + | NoCheckCxs + +/// Indicates if a member binding is an object expression binding +type IsObjExprBinding = + | ObjExprBinding + | ValOrMemberBinding + +/// Represents the initial information about a recursive binding +type RecDefnBindingInfo = + | RecDefnBindingInfo of + containerInfo: ContainerInfo * + newslotsOk: NewSlotsOK * + declKind: DeclKind * + synBinding: SynBinding + +/// Represents the ValReprInfo for a value, before the typars are fully inferred +type PartialValReprInfo = + | PartialValReprInfo of + curriedArgInfos: ArgReprInfo list list * + returnInfo: ArgReprInfo + +/// Holds the initial ValMemberInfo and other information before it is fully completed +type PreValMemberInfo = + | PreValMemberInfo of + memberInfo: ValMemberInfo * + logicalName: string * + compiledName: string + +/// The result of checking a value or member signature +type ValSpecResult = + | ValSpecResult of + altActualParent: ParentRef * + memberInfoOpt: PreValMemberInfo option * + id: Ident * + enclosingDeclaredTypars: Typars * + declaredTypars: Typars * + ty: TType * + partialValReprInfo: PartialValReprInfo * + declKind: DeclKind + +/// An empty environment of type variables with implicit scope +val emptyUnscopedTyparEnv: UnscopedTyparEnv + +/// A type to represent information associated with values to indicate what explicit (declared) type parameters +/// are given and what additional type parameters can be inferred, if any. +/// +/// The declared type parameters, e.g. let f<'a> (x:'a) = x, plus an indication +/// of whether additional polymorphism may be inferred, e.g. let f<'a, ..> (x:'a) y = x +type ExplicitTyparInfo = + | ExplicitTyparInfo of + rigidCopyOfDeclaredTypars: Typars * + declaredTypars: Typars * + infer: bool + +/// NormalizedBindingRhs records the r.h.s. of a binding after some munging just before type checking. +type NormalizedBindingRhs = + | NormalizedBindingRhs of + simplePats: SynSimplePats list * + returnTyOpt: SynBindingReturnInfo option * + rhsExpr: SynExpr + +/// Represents a syntactic, unchecked binding after the resolution of the name resolution status of pattern +/// constructors and after "pushing" all complex patterns to the right hand side. +type NormalizedBinding = + | NormalizedBinding of + visibility: SynAccess option * + kind: SynBindingKind * + mustInline: bool * + isMutable: bool * + attribs: SynAttribute list * + xmlDoc: XmlDoc * + typars: SynValTyparDecls * + valSynData: SynValData * + pat: SynPat * + rhsExpr: NormalizedBindingRhs * + mBinding: range * + spBinding: DebugPointAtBinding + +/// RecursiveBindingInfo - flows through initial steps of TcLetrec +type RecursiveBindingInfo = + | RecursiveBindingInfo of + recBindIndex: int * // index of the binding in the recursive group + containerInfo: ContainerInfo * + enclosingDeclaredTypars: Typars * + inlineFlag: ValInline * + vspec: Val * + explicitTyparInfo: ExplicitTyparInfo * + partialValReprInfo: PartialValReprInfo * + memberInfoOpt: PreValMemberInfo option * + baseValOpt: Val option * + safeThisValOpt: Val option * + safeInitInfo: SafeInitData * + visibility: SynAccess option * + ty: TType * + declKind: DeclKind + member Val: Val + member EnclosingDeclaredTypars: Typar list + member Index: int + +/// Represents the results of the first phase of preparing simple values from a pattern +[] +type PrelimValScheme1 = + member Ident: Ident + member Type: TType + +/// Represents the results of the first phase of preparing bindings +[] +type CheckedBindingInfo + +/// Represnts the results of the second phase of checking simple values +type ValScheme = + | ValScheme of + id: Ident * + typeScheme: TypeScheme * + topValInfo: ValReprInfo option * + memberInfo: PreValMemberInfo option * + isMutable: bool * + inlineInfo: ValInline * + baseOrThisInfo: ValBaseOrThisInfo * + visibility: SynAccess option * + compgen: bool * + isIncrClass: bool * + isTyFunc: bool * + hasDeclaredTypars: bool + +/// Represents a recursive binding after it has been normalized but before it's info has been put together +type NormalizedRecBindingDefn = + | NormalizedRecBindingDefn of + containerInfo: ContainerInfo * + newslotsOk: NewSlotsOK * + declKind: DeclKind * + binding: NormalizedBinding + +/// Represents a recursive binding after it has been normalized but before it has been checked +type PreCheckingRecursiveBinding = + { SyntacticBinding: NormalizedBinding + RecBindingInfo: RecursiveBindingInfo } + +/// Represents a recursive binding after it has been checked but prior to generalization +type PreGeneralizationRecursiveBinding = + { ExtraGeneralizableTypars: Typars + CheckedBinding: CheckedBindingInfo + RecBindingInfo: RecursiveBindingInfo } + +/// Represents the usage points of a recursive binding that need later adjustment once the +/// type of the member of value is fully inferred. +[] +type RecursiveUseFixupPoints + +/// Represents a recursive binding after it has been both checked and generalized +type PostGeneralizationRecursiveBinding = + { ValScheme: ValScheme + CheckedBinding: CheckedBindingInfo + RecBindingInfo: RecursiveBindingInfo } + member GeneralizedTypars: Typar list + +/// Represents a recursive binding after it has been both checked and generalized and after +/// the special adjustments for 'as this' class initialization checks have been inserted into members. +type PostSpecialValsRecursiveBinding = + { ValScheme: ValScheme + Binding: Binding } + +/// Represents a recursive binding after it has been both checked and generalized, but +/// before initialization recursion has been rewritten +type PreInitializationGraphEliminationBinding = + { FixupPoints: RecursiveUseFixupPoints + Binding: Binding } + +/// Record the entire contents of a module or namespace type as not-generalizable, that is +/// if any type variables occur free in the module or namespace type (because type inference +/// is not yet complete), then they can't be generalized. +val addFreeItemOfModuleTy: ModuleOrNamespaceType -> UngeneralizableItem list -> UngeneralizableItem list + +/// Merge together lists of type variables to generalize, keeping canonical order +val unionGeneralizedTypars: typarSets:Typar list list -> Typar list + +/// Add a list of explicitly declared type variables to the environment, producing a new environment +val AddDeclaredTypars: check: CheckForDuplicateTyparFlag -> typars: Typar list -> env: TcEnv -> TcEnv + +/// Add a value to the environment, producing a new environment. Report to the sink. +val AddLocalVal: g: TcGlobals -> TcResultsSink -> scopem: range -> v: Val -> TcEnv -> TcEnv + +/// Add a value to the environment, producing a new environment +val AddLocalValPrimitive: g: TcGlobals -> v: Val -> TcEnv -> TcEnv + +/// Add a list of values to the environment, producing a new environment. Report to the sink. +val AddLocalVals: g: TcGlobals -> tcSink: TcResultsSink -> scopem: range -> vals: Val list -> env: TcEnv -> TcEnv + +/// Set the type of a 'Val' after it has been fully inferred. +val AdjustRecType: vspec: Val -> vscheme: ValScheme -> unit + +/// Process a normalized recursive binding and prepare for progressive generalization +val AnalyzeAndMakeAndPublishRecursiveValue: overridesOK:OverridesOK -> isGeneratedEventVal:bool -> cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv * recBindIdx:int -> NormalizedRecBindingDefn -> (PreCheckingRecursiveBinding list * Val list) * (UnscopedTyparEnv * int) + +/// Check that a member can be included in an interface +val CheckForNonAbstractInterface: declKind:DeclKind -> tcref:TyconRef -> memberFlags:SynMemberFlags -> m:range -> unit + +/// Check the flags on a member definition for consistency +val CheckMemberFlags: optIntfSlotTy:'a option -> newslotsOK:NewSlotsOK -> overridesOK:OverridesOK -> memberFlags:SynMemberFlags -> m:range -> unit + +/// Check a super type is valid +val CheckSuperType: cenv:TcFileState -> ty:TType -> m:range -> unit + +/// After inference, view a set of declared type parameters in a canonical way. +val ChooseCanonicalDeclaredTyparsAfterInference: g: TcGlobals -> denv: DisplayEnv -> declaredTypars: Typar list -> m: range -> Typar list + +/// After inference, view a ValSchem in a canonical way. +val ChooseCanonicalValSchemeAfterInference: g: TcGlobals -> denv: DisplayEnv -> vscheme: ValScheme -> m: range -> ValScheme + +/// Check if the type annotations and inferred type information in a value give a +/// full and complete generic type for a value. If so, enable generic recursion. +val ComputeIsComplete: enclosingDeclaredTypars:Typar list -> declaredTypars:Typar list -> ty:TType -> bool + +/// Compute the available access rights from a particular location in code +val ComputeAccessRights: eAccessPath: CompilationPath -> eInternalsVisibleCompPaths: CompilationPath list -> eFamilyType: TyconRef option -> AccessorDomain + +/// Compute the available access rights and module/entity compilation path for a paricular location in code +val ComputeAccessAndCompPath: env: TcEnv -> declKindOpt:DeclKind option -> m: range -> vis: SynAccess option -> overrideVis: Accessibility option -> actualParent: ParentRef -> Accessibility * CompilationPath option + +/// Get the expression resulting from turning an expression into an enumerable value, e.g. at 'for' loops +val ConvertArbitraryExprToEnumerable: cenv:TcFileState -> ty:TType -> env:TcEnv -> expr:Expr -> Expr * TType + +/// Invoke pattern match compilation +val CompilePatternForMatchClauses: cenv:TcFileState -> env:TcEnv -> mExpr:range -> matchm:range -> warnOnUnused:bool -> actionOnFailure:ActionOnFailure -> inputExprOpt:Expr option -> inputTy:TType -> resultTy:TType -> tclauses:TypedMatchClause list -> Val * Expr + +/// Process recursive bindings so that initialization is through laziness and is checked. +/// The bindings may be either plain 'let rec' bindings or mutually recursive nestings of modules and types. +/// The functions must iterate the actual bindings and process them to the overall result. +val EliminateInitializationGraphs: + g: TcGlobals + -> mustHaveArity: bool + -> denv: DisplayEnv + -> bindings: 'Binding list + -> iterBindings:((PreInitializationGraphEliminationBinding list -> unit) -> 'Binding list -> unit) + -> buildLets: (Binding list -> 'Result) + -> mapBindings: ((PreInitializationGraphEliminationBinding list -> Binding list) -> 'Binding list -> 'Result list) + -> bindsm: range + -> 'Result list + +/// Adjust a recursive binding after generalization +val FixupLetrecBind: cenv:TcFileState -> denv:DisplayEnv -> generalizedTyparsForRecursiveBlock:Typars -> bind:PostSpecialValsRecursiveBinding -> PreInitializationGraphEliminationBinding + +/// Produce a fresh view of an object type, e.g. 'List' becomes 'List' for new +/// inference variables with the given rigidity. +val FreshenObjectArgType: cenv: TcFileState -> m: range -> rigid: TyparRigidity -> tcref: TyconRef -> isExtrinsic: bool -> declaredTyconTypars: Typar list -> TType * Typar list * TyparInst * TType * TType + +/// Get the accumulated module/namespace type for the current module/namespace being processed. +val GetCurrAccumulatedModuleOrNamespaceType: env: TcEnv -> ModuleOrNamespaceType + +/// Get the "this" variable from the lambda for an instance member binding +val GetInstanceMemberThisVariable: vspec: Val * expr: Expr -> Val option + +/// Build the full ValReprInfo one type inference is complete. +val InferGenericArityFromTyScheme: TypeScheme -> partialValReprInfo: PartialValReprInfo -> ValReprInfo + +/// Locate the environment within a particular namespace path, used to process a +/// 'namespace' declaration. +val LocateEnv: ccu: CcuThunk -> env: TcEnv -> enclosingNamespacePath: Ident list -> TcEnv + +/// Make the check for safe initialization of a member +val MakeCheckSafeInit: g: TcGlobals -> tinst: TypeInst -> safeInitInfo: SafeInitData -> reqExpr: Expr -> expr: Expr -> Expr + +/// Make an initial 'Val' and publish it to the environment and mutable module type accumulator. +val MakeAndPublishVal: cenv: TcFileState -> env: TcEnv -> altActualParent: ParentRef * inSig: bool * declKind: DeclKind * vrec: ValRecursiveScopeInfo * vscheme: ValScheme * attrs: Attribs * doc: XmlDoc * konst: Const option * isGeneratedEventVal: bool -> Val + +/// Make an initial 'base' value +val MakeAndPublishBaseVal: cenv: TcFileState -> env: TcEnv -> Ident option -> TType -> Val option + +/// Make simple values (which are not recursive nor members) +val MakeAndPublishSimpleVals: cenv: TcFileState -> env: TcEnv -> names: NameMap -> NameMap * NameMap + +/// Make an initial implicit safe initialization value +val MakeAndPublishSafeThisVal: cenv: TcFileState -> env: TcEnv -> thisIdOpt: Ident option -> thisTy: TType -> Val option + +/// Make initial information for a member value +val MakeMemberDataAndMangledNameForMemberVal: g: TcGlobals * tcref: TyconRef * isExtrinsic: bool * attrs: Attribs * optImplSlotTys: TType list * memberFlags: SynMemberFlags * valSynData: SynValInfo * id: Ident * isCompGen: bool -> PreValMemberInfo + +/// Return a new environment suitable for processing declarations in the interior of a type definition +val MakeInnerEnvForTyconRef: env: TcEnv -> tcref: TyconRef -> isExtrinsicExtension: bool -> TcEnv + +/// Return a new environment suitable for processing declarations in the interior of a module definition +/// including creating an accumulator for the module type. +val MakeInnerEnv: addOpenToNameEnv: bool -> env: TcEnv -> nm: Ident -> modKind: ModuleOrNamespaceKind -> TcEnv * ModuleOrNamespaceType ref + +/// Return a new environment suitable for processing declarations in the interior of a module definition +/// given that the accumulator for the module type already exisits. +val MakeInnerEnvWithAcc: addOpenToNameEnv: bool -> env: TcEnv -> nm: Ident -> mtypeAcc: ModuleOrNamespaceType ref -> modKind: ModuleOrNamespaceKind -> TcEnv + +/// Produce a post-generalization type scheme for a simple type where no type inference generalization +/// is appplied. +val NonGenericTypeScheme: ty: TType -> TypeScheme + +/// Publish a module definition to the module/namespace type accumulator. +val PublishModuleDefn: cenv: TcFileState -> env: TcEnv -> mspec: ModuleOrNamespace -> unit + +/// Publish a type definition to the module/namespace type accumulator. +val PublishTypeDefn: cenv: TcFileState -> env: TcEnv -> mspec: Tycon -> unit + +/// Publish a value definition to the module/namespace type accumulator. +val PublishValueDefn: cenv: TcFileState -> env: TcEnv -> declKind: DeclKind -> vspec: Val -> unit + +/// Mark a typar as no longer being an inference type variable +val SetTyparRigid: DisplayEnv -> range -> Typar -> unit + +/// Check and publish a value specification (in a signature or 'abstract' member) to the +/// module/namespace type accumulator and return the resulting Val(s). Normally only one +/// 'Val' results but CLI events may produce both and add_Event and _remove_Event Val. +val TcAndPublishValSpec: cenv: TcFileState * env: TcEnv * containerInfo: ContainerInfo * declKind: DeclKind * memFlagsOpt: SynMemberFlags option * tpenv: UnscopedTyparEnv * valSpfn: SynValSig -> Val list * UnscopedTyparEnv + +/// Check a set of attributes +val TcAttributes: cenv: TcFileState -> env: TcEnv -> attrTgt: AttributeTargets -> synAttribs: SynAttribute list -> Attrib list + +/// Check a set of attributes and allow failure because a later phase of type realization +/// may successfully check the attributes (if the attribute type or its arguments is in the +/// same recursive group) +val TcAttributesCanFail: cenv:TcFileState -> env:TcEnv -> attrTgt:AttributeTargets -> synAttribs:SynAttribute list -> Attrib list * (unit -> Attribs) + +/// Check a set of attributes which can only target specific elements +val TcAttributesWithPossibleTargets: canFail: bool -> cenv: TcFileState -> env: TcEnv -> attrTgt: AttributeTargets -> synAttribs: SynAttribute list -> (AttributeTargets * Attrib) list * bool + +/// Check a constant value, e.g. a literal +val TcConst: cenv: TcFileState -> overallTy: TType -> m: range -> env: TcEnv -> c: SynConst -> Const + +/// Check a syntactic expression and convert it to a typed tree expression +val TcExpr: cenv:TcFileState -> ty:OverallTy -> env:TcEnv -> tpenv:UnscopedTyparEnv -> expr:SynExpr -> Expr * UnscopedTyparEnv + +/// Converts 'a..b' to a call to the '(..)' operator in FSharp.Core +/// Converts 'a..b..c' to a call to the '(.. ..)' operator in FSharp.Core +val RewriteRangeExpr: expr: SynExpr -> SynExpr option + +/// Check a syntactic expression and convert it to a typed tree expression +val TcExprOfUnknownType: cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv -> expr:SynExpr -> Expr * TType * UnscopedTyparEnv + +/// Check a syntactic expression and convert it to a typed tree expression. Possibly allow for subsumption flexibility +/// and insert a coercion if necessary. +val TcExprFlex: cenv:TcFileState -> flex:bool -> compat:bool -> desiredTy:TType -> env:TcEnv -> tpenv:UnscopedTyparEnv -> synExpr:SynExpr -> Expr * UnscopedTyparEnv + +/// Process a leaf construct where the actual type of that construct is already pre-known, +/// and the overall type can be eagerly propagated into the actual type, including pre-calculating +/// any type-directed conversion. +val TcPropagatingExprLeafThenConvert: cenv:TcFileState -> overallTy: OverallTy -> actualTy: TType -> env: TcEnv -> m: range -> f: (unit -> Expr * UnscopedTyparEnv) -> Expr * UnscopedTyparEnv + +/// Check a syntactic statement and convert it to a typed tree expression. +val TcStmtThatCantBeCtorBody: cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv -> expr:SynExpr -> Expr * UnscopedTyparEnv + +/// Check a syntactic expression and convert it to a typed tree expression +val TcExprUndelayed: cenv:TcFileState -> overallTy:OverallTy -> env:TcEnv -> tpenv:UnscopedTyparEnv -> synExpr:SynExpr -> Expr * UnscopedTyparEnv + +/// Check a linear expression (e.g. a sequence of 'let') in a tail-recursive way +/// and convert it to a typed tree expression, using the bodyChecker to check the parts +/// that are not linear. +val TcLinearExprs: bodyChecker:(OverallTy -> TcEnv -> UnscopedTyparEnv -> SynExpr -> Expr * UnscopedTyparEnv) -> cenv:TcFileState -> env:TcEnv -> overallTy:OverallTy -> tpenv:UnscopedTyparEnv -> isCompExpr:bool -> expr:SynExpr -> cont:(Expr * UnscopedTyparEnv -> Expr * UnscopedTyparEnv) -> Expr * UnscopedTyparEnv + +/// Try to check a syntactic statement and indicate if it's type is not unit without emitting a warning +val TryTcStmt: cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv -> synExpr:SynExpr -> bool * Expr * UnscopedTyparEnv + +/// Check a pattern being used as a pattern match +val TcMatchPattern: cenv:TcFileState -> inputTy:TType -> env:TcEnv -> tpenv:UnscopedTyparEnv -> pat:SynPat * optWhenExpr:SynExpr option -> Pattern * Expr option * Val list * TcEnv * UnscopedTyparEnv + +val (|BinOpExpr|_|): SynExpr -> (Ident * SynExpr * SynExpr) option + +/// Check a set of let bindings +val TcLetBindings: cenv:TcFileState -> env:TcEnv -> containerInfo:ContainerInfo -> declKind:DeclKind -> tpenv:UnscopedTyparEnv -> binds:SynBinding list * bindsm:range * scopem:range -> ModuleOrNamespaceExpr list * TcEnv * UnscopedTyparEnv + +/// Check an individual `let rec` binding +val TcLetrecBinding: cenv:TcFileState * envRec:TcEnv * scopem:range * extraGeneralizableTypars:Typars * reqdThisValTyOpt:TType option -> envNonRec:TcEnv * generalizedRecBinds:PostGeneralizationRecursiveBinding list * preGeneralizationRecBinds:PreGeneralizationRecursiveBinding list * tpenv:UnscopedTyparEnv * uncheckedRecBindsTable:Map -> rbind:PreCheckingRecursiveBinding -> TcEnv * PostGeneralizationRecursiveBinding list * PreGeneralizationRecursiveBinding list * UnscopedTyparEnv * Map + +/// Get the binding for the implicit safe initialziation check value if it is being used +val TcLetrecComputeCtorSafeThisValBind: cenv:TcFileState -> safeThisValOpt:Val option -> Binding option + +/// Check a collection of `let rec` bindings +val TcLetrec: overridesOK:OverridesOK -> cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv -> binds:RecDefnBindingInfo list * bindsm:range * scopem:range -> Bindings * TcEnv * UnscopedTyparEnv + +/// Part of check a collection of recursive bindings that might include members +val TcLetrecAdjustMemberForSpecialVals: cenv: TcFileState -> pgrbind: PostGeneralizationRecursiveBinding -> PostSpecialValsRecursiveBinding + +/// Check an inheritance expression or other 'new XYZ()' expression +val TcNewExpr: cenv:TcFileState -> env:TcEnv -> tpenv:UnscopedTyparEnv -> objTy:TType -> mObjTyOpt:range option -> superInit:bool -> arg:SynExpr -> mWholeExprOrObjTy:range -> Expr * UnscopedTyparEnv + +#if !NO_EXTENSIONTYPING +/// Check the application of a provided type to static args +val TcProvidedTypeAppToStaticConstantArgs: cenv:TcFileState -> env:TcEnv -> optGeneratedTypePath:string list option -> tpenv:UnscopedTyparEnv -> tcref:TyconRef -> args:SynType list -> m:range -> bool * Tainted * (unit -> unit) +#endif + +/// Check a set of simple patterns, e.g. the declarations of parameters for an implicit constructor. +val TcSimplePatsOfUnknownType: cenv: TcFileState -> optArgsOK: bool -> checkCxs: CheckConstraints -> env: TcEnv -> tpenv: UnscopedTyparEnv -> spats: SynSimplePats -> string list * (UnscopedTyparEnv * NameMap * Set) + +/// Check a set of explicitly declared constraints on type parameters +val TcTyparConstraints: cenv: TcFileState -> newOk: ImplicitlyBoundTyparsAllowed -> checkCxs: CheckConstraints -> occ: ItemOccurence -> env: TcEnv -> tpenv: UnscopedTyparEnv -> synConstraints: SynTypeConstraint list -> UnscopedTyparEnv + +/// Check a collection of type parameters declarations +val TcTyparDecls: cenv: TcFileState -> env: TcEnv -> synTypars: SynTyparDecl list -> Typar list + +/// Check a syntactic type +val TcType: cenv: TcFileState -> newOk: ImplicitlyBoundTyparsAllowed -> checkCxs: CheckConstraints -> occ: ItemOccurence -> env: TcEnv -> tpenv: UnscopedTyparEnv -> ty: SynType -> TType * UnscopedTyparEnv + +/// Check a syntactic type or unit of measure +val TcTypeOrMeasureAndRecover: optKind: TyparKind option -> cenv: TcFileState -> newOk: ImplicitlyBoundTyparsAllowed -> checkCxs: CheckConstraints -> occ: ItemOccurence -> env: TcEnv -> tpenv: UnscopedTyparEnv -> ty: SynType -> TType * UnscopedTyparEnv + +/// Check a syntactic type (with error recovery) +val TcTypeAndRecover: cenv: TcFileState -> newOk: ImplicitlyBoundTyparsAllowed -> checkCxs: CheckConstraints -> occ: ItemOccurence -> env: TcEnv -> tpenv: UnscopedTyparEnv -> ty: SynType -> TType * UnscopedTyparEnv + +/// Check a specification of a value or member in a signature or an abstract member +val TcValSpec: cenv: TcFileState -> TcEnv -> DeclKind -> ImplicitlyBoundTyparsAllowed -> ContainerInfo -> SynMemberFlags option -> thisTyOpt: TType option -> UnscopedTyparEnv -> SynValSig -> Attrib list -> ValSpecResult list * UnscopedTyparEnv + +/// Given the declaration of a function or member, process it to produce the ValReprInfo +/// giving the names and attributes relevant to arguments and return, but before type +/// parameters have been fully inferred via generalization. +val TranslateTopValSynInfo: range -> tcAttributes: (AttributeTargets -> SynAttribute list -> Attrib list) -> synValInfo: SynValInfo -> PartialValReprInfo + +/// Given the declaration of a function or member, complete the processing of its ValReprInfo +/// once type parameters have been fully inferred via generalization. +val TranslatePartialArity: tps: Typar list -> PartialValReprInfo -> ValReprInfo + +/// Constrain two types to be equal within this type checking context +val UnifyTypes : cenv:TcFileState -> env:TcEnv -> m:range -> actualTy:TType -> expectedTy:TType -> unit + +module GeneralizationHelpers = + + /// Given an environment, compute the set of inference type variables which may not be + /// generalised, because they appear somewhere in the types of the constructs availabe + /// in the environment. + val ComputeUngeneralizableTypars: env: TcEnv -> Zset + + /// Given an environment, compute the set of trait solutions which must appear before + /// the current location, not after (to prevent use-before definitiosn and + /// forward calls via type inference filling in trait solutions). + val ComputeUnabstractableTraitSolutions: env: TcEnv -> FreeLocals + + /// Given an environment, compute the set of type definitions which must appear before + /// the current location, not after (to prevent use-before-definition of type definitions + /// via type inference). + val ComputeUnabstractableTycons: env: TcEnv -> FreeTycons + +// Logically extends System.AttributeTargets for F# constructs +module AttributeTargets = + /// The allowed attribute targets for an F# field declaration + val FieldDecl: AttributeTargets + + /// The allowed attribute targets for an F# field declaration once it's known to be targeting + /// a field not a property (see useGenuineField) + val FieldDeclRestricted: AttributeTargets + + /// The allowed attribute targets for an F# union case declaration + val UnionCaseDecl: AttributeTargets + + /// The allowed attribute targets for an F# type declaration + val TyconDecl: AttributeTargets + + /// The allowed attribute targets for an F# exception declaration + val ExnDecl: AttributeTargets + + /// The allowed attribute targets for an F# module declaration + val ModuleDecl: AttributeTargets + + /// The allowed attribute targets for an F# top level 'do' expression + val Top: AttributeTargets + +module BindingNormalization = + /// Take a syntactic binding and do the very first processing step to normalize it. + val NormalizeBinding: isObjExprBinding: IsObjExprBinding -> cenv: TcFileState -> env: TcEnv -> binding: SynBinding -> NormalizedBinding + diff --git a/src/fsharp/CheckFormatStrings.fs b/src/fsharp/CheckFormatStrings.fs index 1622a61351c..a24be5dc6ee 100644 --- a/src/fsharp/CheckFormatStrings.fs +++ b/src/fsharp/CheckFormatStrings.fs @@ -2,15 +2,17 @@ module internal FSharp.Compiler.CheckFormatStrings -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals +open System.Text +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.ConstraintSolver open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals type FormatItem = Simple of TType | FuncAndVal @@ -21,7 +23,7 @@ let copyAndFixupFormatTypar m tp = let lowestDefaultPriority = 0 (* See comment on TyparConstraint.DefaultsTo *) let mkFlexibleFormatTypar m tys dflt = - let tp = NewTypar (TyparKind.Type,TyparRigidity.Rigid,Typar(mkSynId m "fmt",HeadTypeStaticReq,true),false,TyparDynamicReq.Yes,[],false,false) + let tp = Construct.NewTypar (TyparKind.Type, TyparRigidity.Rigid, SynTypar(mkSynId m "fmt",TyparStaticReq.HeadType,true),false,TyparDynamicReq.Yes,[],false,false) tp.SetConstraints [ TyparConstraint.SimpleChoice (tys,m); TyparConstraint.DefaultsTo (lowestDefaultPriority,dflt,m)] copyAndFixupFormatTypar m tp @@ -46,31 +48,153 @@ let newInfo () = addZeros = false precision = false} -let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringCheckContext option) fmt bty cty = - // Offset is used to adjust ranges depending on whether input string is regular, verbatim or triple-quote. - // We construct a new 'fmt' string since the current 'fmt' string doesn't distinguish between "\n" and escaped "\\n". - let (offset, fmt) = +let parseFormatStringInternal (m: range) (fragRanges: range list) (g: TcGlobals) isInterpolated isFormattableString (context: FormatStringCheckContext option) fmt printerArgTy printerResidueTy = + + // As background: the F# compiler tokenizes strings on the assumption that the only thing you need from + // them is the actual corresponding text, e.g. of a string literal. This means many different textual input strings + // in the input file correspond to the 'fmt' string we have here. + // + // The problem with this is that when we go to colorize the format specifiers in string, we need to do + // that with respect to the original string source text in order to lay down accurate colorizations. + // + // One approach would be to change the F# lexer to also crack every string in a more structured way, recording + // both the original source text and the actual string literal. However this would be invasive and possibly + // too expensive since the vast majority of strings don't need this treatment. + // + // So instead, for format strings alone - and only when processing in the IDE - we crack the "original" + // source of the string by going back and getting the format string from the input source file by using the + // relevant ranges + // + // For interpolated strings this may involve many fragments, e.g. + // $"abc %d{" + // "} def %s{" + // "} xyz" + // In this case we are given the range of each fragment. One annoying thing is that we must lop off the + // quotations, $, {, } symbols off the end of each string fragment. This information should probably + // be given to us by the lexer. + // + // Note this also means that when compiling (command-line or background IncrementalBuilder in the IDE + // there are no accurate intra-string ranges available for exact error message locations within the string. + // The 'm' range passed as an input is however accurate and covers the whole string. + /// + let fmt, fragments = + + //printfn "--------------------" + //printfn "context.IsSome = %b" context.IsSome + //printfn "fmt = <<<%s>>>" fmt + //printfn "isInterpolated = %b" isInterpolated + //printfn "fragRanges = %A" fragRanges + match context with - | Some context -> + | Some context when fragRanges.Length > 0 -> let sourceText = context.SourceText + //printfn "sourceText.IsSome = %b" sourceText.IsSome let lineStartPositions = context.LineStartPositions + //printfn "lineStartPositions.Length = %d" lineStartPositions.Length let length = sourceText.Length - if m.EndLine < lineStartPositions.Length then - let startIndex = lineStartPositions.[m.StartLine-1] + m.StartColumn - let endIndex = lineStartPositions.[m.EndLine-1] + m.EndColumn - 1 - if startIndex < length-3 && sourceText.SubTextEquals("\"\"\"", startIndex) then - (3, sourceText.GetSubTextString(startIndex + 3, endIndex - startIndex)) - elif startIndex < length-2 && sourceText.SubTextEquals("@\"", startIndex) then - (2, sourceText.GetSubTextString(startIndex + 2, endIndex + 1 - startIndex)) - else (1, sourceText.GetSubTextString(startIndex + 1, endIndex - startIndex)) - else (1, fmt) - | None -> (1, fmt) - - let len = String.length fmt + let numFrags = fragRanges.Length + let fmts = + [ for i, fragRange in List.indexed fragRanges do + let m = fragRange + //printfn "m.EndLine = %d" m.EndLine + if m.StartLine - 1 < lineStartPositions.Length && m.EndLine - 1 < lineStartPositions.Length then + let startIndex = lineStartPositions.[m.StartLine-1] + m.StartColumn + let endIndex = lineStartPositions.[m.EndLine-1] + m.EndColumn + // Note, some extra """ text may be included at end of these snippets, meaning CheckFormatString in the IDE + // may be using a slightly false format string to colorize the %d markers. This doesn't matter as there + // won't be relevant %d in these sections + // + // However we make an effort to remove these to keep the calls to GetSubStringText valid. So + // we work out how much extra text there is at the end of the last line of the fragment, + // which may or may not be quote markers. If there's no flex, we don't trim the quote marks + let endNextLineIndex = if m.EndLine < lineStartPositions.Length then lineStartPositions.[m.EndLine] else endIndex + let endIndexFlex = endNextLineIndex - endIndex + let mLength = endIndex - startIndex + + //let startIndex2 = if m.StartLine < lineStartPositions.Length then lineStartPositions.[m.StartLine] else startIndex + //let sourceLineFromOffset = sourceText.GetSubTextString(startIndex, (startIndex2 - startIndex)) + //printfn "i = %d, mLength = %d, endIndexFlex = %d, sourceLineFromOffset = <<<%s>>>" i mLength endIndexFlex sourceLineFromOffset + + if isInterpolated && i=0 && startIndex < length-4 && sourceText.SubTextEquals("$\"\"\"", startIndex) then + // Take of the ending triple quote or '{' + let fragLength = mLength - 4 - min endIndexFlex (if i = numFrags-1 then 3 else 1) + (4, sourceText.GetSubTextString(startIndex + 4, fragLength), m) + elif not isInterpolated && i=0 && startIndex < length-3 && sourceText.SubTextEquals("\"\"\"", startIndex) then + // Take of the ending triple quote or '{' + let fragLength = mLength - 2 - min endIndexFlex (if i = numFrags-1 then 3 else 1) + (3, sourceText.GetSubTextString(startIndex + 3, fragLength), m) + elif isInterpolated && i=0 && startIndex < length-3 && sourceText.SubTextEquals("$@\"", startIndex) then + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 3 - min endIndexFlex 1 + (3, sourceText.GetSubTextString(startIndex + 3, fragLength), m) + elif isInterpolated && i=0 && startIndex < length-3 && sourceText.SubTextEquals("@$\"", startIndex) then + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 3 - min endIndexFlex 1 + (3, sourceText.GetSubTextString(startIndex + 3, fragLength), m) + elif not isInterpolated && i=0 && startIndex < length-2 && sourceText.SubTextEquals("@\"", startIndex) then + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 2 - min endIndexFlex 1 + (2, sourceText.GetSubTextString(startIndex + 2, fragLength), m) + elif isInterpolated && i=0 && startIndex < length-2 && sourceText.SubTextEquals("$\"", startIndex) then + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 2 - min endIndexFlex 1 + (2, sourceText.GetSubTextString(startIndex + 2, fragLength), m) + elif isInterpolated && i <> 0 && startIndex < length-1 && sourceText.SubTextEquals("}", startIndex) then + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 1 - min endIndexFlex 1 + (1, sourceText.GetSubTextString(startIndex + 1, fragLength), m) + else + // Take of the ending quote or '{', always length 1 + let fragLength = mLength - 1 - min endIndexFlex 1 + (1, sourceText.GetSubTextString(startIndex + 1, fragLength), m) + else (1, fmt, m) ] + + //printfn "fmts = %A" fmts + + // Join the fragments with holes. Note this join is only used on the IDE path, + // the CheckExpressions.fs does its own joining with the right alignments etc. substituted + // On the IDE path we don't do any checking of these in this file (some checking is + // done in CheckExpressions.fs) so it's ok to join with just '%P()'. + let fmt = fmts |> List.map p23 |> String.concat "%P()" + let fragments, _ = + (0, fmts) ||> List.mapFold (fun i (offset, fmt, fragRange) -> + (i, offset, fragRange), i + fmt.Length + 4) // the '4' is the length of '%P()' joins + + //printfn "fmt2 = <<<%s>>>" fmt + //printfn "fragments = %A" fragments + fmt, fragments + | _ -> + // Don't muck with the fmt when there is no source code context to go get the original + // source code (i.e. when compiling or background checking) + fmt, [ (0, 1, m) ] + + let len = fmt.Length let specifierLocations = ResizeArray() - let rec parseLoop acc (i, relLine, relCol) = + // For FormattableString we collect a .NET Format String with {0} etc. replacing text. '%%' are replaced + // by '%', we check there are no '%' formats, and '{{' and '}}' are *not* replaced since the subsequent + // call to String.Format etc. will process them. + let dotnetFormatString = StringBuilder() + let appendToDotnetFormatString (s: string) = dotnetFormatString.Append(s) |> ignore + let mutable dotnetFormatStringInterpolationHoleCount = 0 + let percentATys = ResizeArray<_>() + + // fragLine, fragCol - track our location w.r.t. the marker for the start of this chunk + // + let rec parseLoop acc (i, fragLine, fragCol) fragments = + + // Check if we've moved into the next fragment. Note this will always activate on + // the first step, i.e. when i=0 + let struct (fragLine, fragCol, fragments) = + match fragments with + | (idx, fragOffset, fragRange: range)::rest when i >= idx -> + //printfn "i = %d, idx = %d, moving into next fragment at %A plus fragOffset %d" i idx fragRange fragOffset + struct (fragRange.StartLine, fragRange.StartColumn + fragOffset, rest) + + | _ -> struct (fragLine, fragCol, fragments) + //printfn "parseLoop: i = %d, fragLine = %d, fragCol = %d" i fragLine fragCol + if i >= len then let argtys = if acc |> List.forall (fun (p, _) -> p = None) then // without positional specifiers @@ -79,13 +203,14 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe failwithf "%s" <| FSComp.SR.forPositionalSpecifiersNotPermitted() argtys elif System.Char.IsSurrogatePair(fmt,i) then - parseLoop acc (i+2, relLine, relCol+2) + appendToDotnetFormatString fmt.[i..i+1] + parseLoop acc (i+2, fragLine, fragCol+2) fragments else let c = fmt.[i] match c with | '%' -> - let startCol = relCol - let relCol = relCol+1 + let startFragCol = fragCol + let fragCol = fragCol+1 let i = i+1 if i >= len then failwithf "%s" <| FSComp.SR.forMissingFormatSpecifier() let info = newInfo() @@ -109,7 +234,7 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe if info.numPrefixIfPos <> None then failwithf "%s" <| FSComp.SR.forPrefixFlagSpacePlusSetTwice() info.numPrefixIfPos <- Some ' ' flags(i+1) - | '#' -> failwithf "%s" <| FSComp.SR.forHashSpecifierIsInvalid() + | '#' -> failwithf "%s" <| FSComp.SR.forHashSpecifierIsInvalid() | _ -> i let rec digitsPrecision i = @@ -131,18 +256,18 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe | '.' -> precision (i+1) | _ -> false,i - let rec digitsWidthAndPrecision i = + let rec digitsWidthAndPrecision n i = if i >= len then failwithf "%s" <| FSComp.SR.forBadPrecision() match fmt.[i] with - | c when System.Char.IsDigit c -> digitsWidthAndPrecision (i+1) - | _ -> optionalDotAndPrecision i + | c when System.Char.IsDigit c -> digitsWidthAndPrecision (n*10 + int c - int '0') (i+1) + | _ -> Some n, optionalDotAndPrecision i let widthAndPrecision i = if i >= len then failwithf "%s" <| FSComp.SR.forBadPrecision() match fmt.[i] with - | c when System.Char.IsDigit c -> false,digitsWidthAndPrecision i - | '*' -> true,optionalDotAndPrecision (i+1) - | _ -> false,optionalDotAndPrecision i + | c when System.Char.IsDigit c -> false,digitsWidthAndPrecision 0 i + | '*' -> true, (None, optionalDotAndPrecision (i+1)) + | _ -> false, (None, optionalDotAndPrecision i) let rec digitsPosition n i = if i >= len then failwithf "%s" <| FSComp.SR.forBadPrecision() @@ -160,15 +285,15 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe let oldI = i let posi, i = position i - let relCol = relCol + i - oldI + let fragCol = fragCol + i - oldI let oldI = i let i = flags i - let relCol = relCol + i - oldI + let fragCol = fragCol + i - oldI let oldI = i - let widthArg,(precisionArg,i) = widthAndPrecision i - let relCol = relCol + i - oldI + let widthArg,(widthValue, (precisionArg,i)) = widthAndPrecision i + let fragCol = fragCol + i - oldI if i >= len then failwithf "%s" <| FSComp.SR.forBadPrecision() @@ -176,127 +301,186 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe let acc = if widthArg then (Option.map ((+)1) posi, g.int_ty) :: acc else acc - let checkNoPrecision c = if info.precision then failwithf "%s" <| FSComp.SR.forFormatDoesntSupportPrecision(c.ToString()) - let checkNoZeroFlag c = if info.addZeros then failwithf "%s" <| FSComp.SR.forDoesNotSupportZeroFlag(c.ToString()) - let checkNoNumericPrefix c = if info.numPrefixIfPos <> None then - failwithf "%s" <| FSComp.SR.forDoesNotSupportPrefixFlag(c.ToString(), (Option.get info.numPrefixIfPos).ToString()) + let checkNoPrecision c = + if info.precision then failwithf "%s" <| FSComp.SR.forFormatDoesntSupportPrecision(c.ToString()) + + let checkNoZeroFlag c = + if info.addZeros then failwithf "%s" <| FSComp.SR.forDoesNotSupportZeroFlag(c.ToString()) + + let checkNoNumericPrefix c = + match info.numPrefixIfPos with + | Some n -> failwithf "%s" <| FSComp.SR.forDoesNotSupportPrefixFlag(c.ToString(), n.ToString()) + | None -> () let checkOtherFlags c = checkNoPrecision c checkNoZeroFlag c checkNoNumericPrefix c - let collectSpecifierLocation relLine relCol numStdArgs = - let numArgsForSpecifier = - numStdArgs + (if widthArg then 1 else 0) + (if precisionArg then 1 else 0) - match relLine with - | 0 -> - specifierLocations.Add( - (Range.mkFileIndexRange m.FileIndex - (Range.mkPos m.StartLine (startCol + offset)) - (Range.mkPos m.StartLine (relCol + offset + 1))), numArgsForSpecifier) - | _ -> + // Explicitly typed holes in interpolated strings "....%d{x}..." get additional '%P()' as a hole place marker + let skipPossibleInterpolationHole i = + if isInterpolated then + if i+1 < len && fmt.[i] = '%' && fmt.[i+1] = 'P' then + let i = i + 2 + if i+1 < len && fmt.[i] = '(' && fmt.[i+1] = ')' then + if isFormattableString then + failwithf "%s" <| FSComp.SR.forFormatInvalidForInterpolated4() + i + 2 + else + failwithf "%s" <| FSComp.SR.forFormatInvalidForInterpolated2() + else + failwithf "%s" <| FSComp.SR.forFormatInvalidForInterpolated() + else i + + // Implicitly typed holes in interpolated strings are translated to '... %P(...)...' in the + // type checker. They should always have '(...)' after for format string. + let requireAndSkipInterpolationHoleFormat i = + if i < len && fmt.[i] = '(' then + let i2 = fmt.IndexOf(")", i+1) + if i2 = -1 then + failwithf "%s" <| FSComp.SR.forFormatInvalidForInterpolated3() + else + let dotnetAlignment = match widthValue with None -> "" | Some w -> "," + (if info.leftJustify then "-" else "") + string w + let dotnetNumberFormat = match fmt.[i+1..i2-1] with "" -> "" | s -> ":" + s + appendToDotnetFormatString ("{" + string dotnetFormatStringInterpolationHoleCount + dotnetAlignment + dotnetNumberFormat + "}") + dotnetFormatStringInterpolationHoleCount <- dotnetFormatStringInterpolationHoleCount + 1 + i2+1 + else + failwithf "%s" <| FSComp.SR.forFormatInvalidForInterpolated3() + + let collectSpecifierLocation fragLine fragCol numStdArgs = + match context with + | Some _ -> + let numArgsForSpecifier = + numStdArgs + (if widthArg then 1 else 0) + (if precisionArg then 1 else 0) specifierLocations.Add( - (Range.mkFileIndexRange m.FileIndex - (Range.mkPos (m.StartLine + relLine) startCol) - (Range.mkPos (m.StartLine + relLine) (relCol + 1))), numArgsForSpecifier) + (Range.mkFileIndexRange m.FileIndex + (Position.mkPos fragLine startFragCol) + (Position.mkPos fragLine (fragCol + 1))), numArgsForSpecifier) + | None -> () let ch = fmt.[i] match ch with | '%' -> - collectSpecifierLocation relLine relCol 0 - parseLoop acc (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 0 + appendToDotnetFormatString "%" + parseLoop acc (i+1, fragLine, fragCol+1) fragments - | ('d' | 'i' | 'o' | 'u' | 'x' | 'X') -> + | 'd' | 'i' | 'u' | 'B' | 'o' | 'x' | 'X' -> + if ch = 'B' then ErrorLogger.checkLanguageFeatureError g.langVersion Features.LanguageFeature.PrintfBinaryFormat m if info.precision then failwithf "%s" <| FSComp.SR.forFormatDoesntSupportPrecision(ch.ToString()) - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, mkFlexibleIntFormatTypar g m) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, mkFlexibleIntFormatTypar g m) :: acc) (i, fragLine, fragCol+1) fragments - | ('l' | 'L') -> + | 'l' | 'L' -> if info.precision then failwithf "%s" <| FSComp.SR.forFormatDoesntSupportPrecision(ch.ToString()) - let relCol = relCol+1 + let fragCol = fragCol+1 let i = i+1 // "bad format specifier ... In F# code you can use %d, %x, %o or %u instead ..." if i >= len then - failwithf "%s" <| FSComp.SR.forBadFormatSpecifier() + raise (Failure (FSComp.SR.forBadFormatSpecifier())) // Always error for %l and %Lx failwithf "%s" <| FSComp.SR.forLIsUnnecessary() match fmt.[i] with - | ('d' | 'i' | 'o' | 'u' | 'x' | 'X') -> - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, mkFlexibleIntFormatTypar g m) :: acc) (i+1, relLine, relCol+1) + | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' -> + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, mkFlexibleIntFormatTypar g m) :: acc) (i, fragLine, fragCol+1) fragments | _ -> failwithf "%s" <| FSComp.SR.forBadFormatSpecifier() - | ('h' | 'H') -> + | 'h' | 'H' -> failwithf "%s" <| FSComp.SR.forHIsUnnecessary() | 'M' -> - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, mkFlexibleDecimalFormatTypar g m) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, mkFlexibleDecimalFormatTypar g m) :: acc) (i, fragLine, fragCol+1) fragments - | ('f' | 'F' | 'e' | 'E' | 'g' | 'G') -> - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, mkFlexibleFloatFormatTypar g m) :: acc) (i+1, relLine, relCol+1) + | 'f' | 'F' | 'e' | 'E' | 'g' | 'G' -> + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, mkFlexibleFloatFormatTypar g m) :: acc) (i, fragLine, fragCol+1) fragments | 'b' -> checkOtherFlags ch - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, g.bool_ty) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, g.bool_ty) :: acc) (i, fragLine, fragCol+1) fragments | 'c' -> checkOtherFlags ch - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, g.char_ty) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, g.char_ty) :: acc) (i, fragLine, fragCol+1) fragments | 's' -> checkOtherFlags ch - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, g.string_ty) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, g.string_ty) :: acc) (i, fragLine, fragCol+1) fragments | 'O' -> checkOtherFlags ch - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, NewInferenceType ()) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, NewInferenceType ()) :: acc) (i, fragLine, fragCol+1) fragments + + // residue of hole "...{n}..." in interpolated strings become %P(...) + | 'P' when isInterpolated -> + checkOtherFlags ch + let i = requireAndSkipInterpolationHoleFormat (i+1) + // Note, the fragCol doesn't advance at all as these are magically inserted. + parseLoop ((posi, NewInferenceType ()) :: acc) (i, fragLine, startFragCol) fragments | 'A' -> match info.numPrefixIfPos with | None // %A has BindingFlags=Public, %+A has BindingFlags=Public | NonPublic | Some '+' -> - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, NewInferenceType ()) :: acc) (i+1, relLine, relCol+1) - | Some _ -> failwithf "%s" <| FSComp.SR.forDoesNotSupportPrefixFlag(ch.ToString(), (Option.get info.numPrefixIfPos).ToString()) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + let xty = NewInferenceType () + percentATys.Add(xty) + parseLoop ((posi, xty) :: acc) (i, fragLine, fragCol+1) fragments + | Some n -> failwithf "%s" <| FSComp.SR.forDoesNotSupportPrefixFlag(ch.ToString(), n.ToString()) | 'a' -> checkOtherFlags ch let xty = NewInferenceType () - let fty = bty --> (xty --> cty) - collectSpecifierLocation relLine relCol 2 - parseLoop ((Option.map ((+)1) posi, xty) :: (posi, fty) :: acc) (i+1, relLine, relCol+1) + let fty = printerArgTy --> (xty --> printerResidueTy) + collectSpecifierLocation fragLine fragCol 2 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((Option.map ((+)1) posi, xty) :: (posi, fty) :: acc) (i, fragLine, fragCol+1) fragments | 't' -> checkOtherFlags ch - collectSpecifierLocation relLine relCol 1 - parseLoop ((posi, bty --> cty) :: acc) (i+1, relLine, relCol+1) + collectSpecifierLocation fragLine fragCol 1 + let i = skipPossibleInterpolationHole (i+1) + parseLoop ((posi, printerArgTy --> printerResidueTy) :: acc) (i, fragLine, fragCol+1) fragments - | c -> failwithf "%s" <| FSComp.SR.forBadFormatSpecifierGeneral(String.make 1 c) + | c -> failwithf "%s" <| FSComp.SR.forBadFormatSpecifierGeneral(String.make 1 c) - | '\n' -> parseLoop acc (i+1, relLine+1, 0) - | _ -> parseLoop acc (i+1, relLine, relCol+1) + | '\n' -> + appendToDotnetFormatString fmt.[i..i] + parseLoop acc (i+1, fragLine+1, 0) fragments + | _ -> + appendToDotnetFormatString fmt.[i..i] + parseLoop acc (i+1, fragLine, fragCol+1) fragments - let results = parseLoop [] (0, 0, m.StartColumn) - results, Seq.toList specifierLocations + let results = parseLoop [] (0, 0, m.StartColumn) fragments + results, Seq.toList specifierLocations, dotnetFormatString.ToString(), percentATys.ToArray() -let ParseFormatString m g formatStringCheckContext fmt bty cty dty = - let argtys, specifierLocations = parseFormatStringInternal m g formatStringCheckContext fmt bty cty - let aty = List.foldBack (-->) argtys dty - let ety = mkRefTupledTy g argtys - (aty, ety), specifierLocations +let ParseFormatString m fragmentRanges g isInterpolated isFormattableString formatStringCheckContext fmt printerArgTy printerResidueTy printerResultTy = + let argTys, specifierLocations, dotnetFormatString, percentATys = parseFormatStringInternal m fragmentRanges g isInterpolated isFormattableString formatStringCheckContext fmt printerArgTy printerResidueTy + let printerTy = List.foldBack (-->) argTys printerResultTy + let printerTupleTy = mkRefTupledTy g argTys + argTys, printerTy, printerTupleTy, percentATys, specifierLocations, dotnetFormatString -let TryCountFormatStringArguments m g fmt bty cty = +let TryCountFormatStringArguments m g isInterpolated fmt printerArgTy printerResidueTy = try - let argtys, _specifierLocations = parseFormatStringInternal m g None fmt bty cty - Some argtys.Length + let argTys, _specifierLocations, _dotnetFormatString, _percentATys = parseFormatStringInternal m [] g isInterpolated false None fmt printerArgTy printerResidueTy + Some argTys.Length with _ -> None diff --git a/src/fsharp/CheckFormatStrings.fsi b/src/fsharp/CheckFormatStrings.fsi index 10768a94242..83586c97e20 100644 --- a/src/fsharp/CheckFormatStrings.fsi +++ b/src/fsharp/CheckFormatStrings.fsi @@ -7,11 +7,22 @@ module internal FSharp.Compiler.CheckFormatStrings -open FSharp.Compiler open FSharp.Compiler.NameResolution -open FSharp.Compiler.Tast open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree -val ParseFormatString : Range.range -> TcGlobals -> formatStringCheckContext: FormatStringCheckContext option -> fmt: string -> bty: TType -> cty: TType -> dty: TType -> (TType * TType) * (Range.range * int) list +val ParseFormatString: + m: range + -> fragmentRanges: range list + -> g: TcGlobals + -> isInterpolated: bool + -> isFormattableString: bool + -> formatStringCheckContext: FormatStringCheckContext option + -> fmt: string + -> printerArgTy: TType + -> printerResidueTy: TType + -> printerResultTy: TType + -> TType list * TType * TType * TType[] * (range * int) list * string -val TryCountFormatStringArguments : m:Range.range -> g:TcGlobals -> fmt:string -> bty:TType -> cty:TType -> int option +val TryCountFormatStringArguments: m: range -> g: TcGlobals -> isInterpolated: bool -> fmt:string -> printerArgTy:TType -> printerResidueTy:TType -> int option diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs deleted file mode 100644 index 22171840542..00000000000 --- a/src/fsharp/CompileOps.fs +++ /dev/null @@ -1,5687 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Coordinating compiler operations - configuration, loading initial context, reporting errors etc. -module internal FSharp.Compiler.CompileOps - -open System -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.Text - -open Internal.Utilities -open Internal.Utilities.Collections -open Internal.Utilities.Filename -open Internal.Utilities.Text - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.ILPdbWriter -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Diagnostics - -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.AttributeChecking -open FSharp.Compiler.ConstraintSolver -open FSharp.Compiler.DiagnosticMessage -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Features -open FSharp.Compiler.Import -open FSharp.Compiler.Infos -open FSharp.Compiler.Lexhelp -open FSharp.Compiler.Lib -open FSharp.Compiler.MethodCalls -open FSharp.Compiler.MethodOverrides -open FSharp.Compiler.NameResolution -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range -open FSharp.Compiler.ReferenceResolver -open FSharp.Compiler.SignatureConformance -open FSharp.Compiler.TastPickle -open FSharp.Compiler.TypeChecker -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Text - -open FSharp.Compiler.DotNetFrameworkDependencies - -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -open Microsoft.FSharp.Core.CompilerServices -#endif - -#if DEBUG -[] -module internal CompilerService = - let showAssertForUnexpectedException = ref true -#endif // DEBUG - -//---------------------------------------------------------------------------- -// Some Globals -//-------------------------------------------------------------------------- - -let FSharpSigFileSuffixes = [".mli";".fsi"] -let mlCompatSuffixes = [".mli";".ml"] -let FSharpImplFileSuffixes = [".ml";".fs";".fsscript";".fsx"] -let resSuffixes = [".resx"] -let FSharpScriptFileSuffixes = [".fsscript";".fsx"] -let doNotRequireNamespaceOrModuleSuffixes = [".mli";".ml"] @ FSharpScriptFileSuffixes -let FSharpLightSyntaxFileSuffixes: string list = [ ".fs";".fsscript";".fsx";".fsi" ] - -//---------------------------------------------------------------------------- -// ERROR REPORTING -//-------------------------------------------------------------------------- - -exception HashIncludeNotAllowedInNonScript of range -exception HashReferenceNotAllowedInNonScript of range -exception HashDirectiveNotAllowedInNonScript of range -exception FileNameNotResolved of (*filename*) string * (*description of searched locations*) string * range -exception AssemblyNotResolved of (*originalName*) string * range -exception LoadedSourceNotFoundIgnoring of (*filename*) string * range -exception MSBuildReferenceResolutionWarning of (*MSBuild warning code*)string * (*Message*)string * range -exception MSBuildReferenceResolutionError of (*MSBuild warning code*)string * (*Message*)string * range -exception DeprecatedCommandLineOptionFull of string * range -exception DeprecatedCommandLineOptionForHtmlDoc of string * range -exception DeprecatedCommandLineOptionSuggestAlternative of string * string * range -exception DeprecatedCommandLineOptionNoDescription of string * range -exception InternalCommandLineOption of string * range -exception HashLoadedSourceHasIssues of (*warnings*) exn list * (*errors*) exn list * range -exception HashLoadedScriptConsideredSource of range - - -let GetRangeOfDiagnostic(err: PhasedDiagnostic) = - let rec RangeFromException = function - | ErrorFromAddingConstraint(_, err2, _) -> RangeFromException err2 -#if !NO_EXTENSIONTYPING - | ExtensionTyping.ProvidedTypeResolutionNoRange e -> RangeFromException e - | ExtensionTyping.ProvidedTypeResolution(m, _) -#endif - | ReservedKeyword(_, m) - | IndentationProblem(_, m) - | ErrorFromAddingTypeEquation(_, _, _, _, _, m) - | ErrorFromApplyingDefault(_, _, _, _, _, m) - | ErrorsFromAddingSubsumptionConstraint(_, _, _, _, _, _, m) - | FunctionExpected(_, _, m) - | BakedInMemberConstraintName(_, m) - | StandardOperatorRedefinitionWarning(_, m) - | BadEventTransformation m - | ParameterlessStructCtor m - | FieldNotMutable (_, _, m) - | Recursion (_, _, _, _, m) - | InvalidRuntimeCoercion(_, _, _, m) - | IndeterminateRuntimeCoercion(_, _, _, m) - | IndeterminateStaticCoercion (_, _, _, m) - | StaticCoercionShouldUseBox (_, _, _, m) - | CoercionTargetSealed(_, _, m) - | UpcastUnnecessary m - | QuotationTranslator.IgnoringPartOfQuotedTermWarning (_, m) - - | TypeTestUnnecessary m - | RuntimeCoercionSourceSealed(_, _, m) - | OverrideDoesntOverride(_, _, _, _, _, m) - | UnionPatternsBindDifferentNames m - | UnionCaseWrongArguments (_, _, _, m) - | TypeIsImplicitlyAbstract m - | RequiredButNotSpecified (_, _, _, _, m) - | FunctionValueUnexpected (_, _, m) - | UnitTypeExpected (_, _, m) - | UnitTypeExpectedWithEquality (_, _, m) - | UnitTypeExpectedWithPossiblePropertySetter (_, _, _, _, m) - | UnitTypeExpectedWithPossibleAssignment (_, _, _, _, m) - | UseOfAddressOfOperator m - | DeprecatedThreadStaticBindingWarning m - | NonUniqueInferredAbstractSlot (_, _, _, _, _, m) - | DefensiveCopyWarning (_, m) - | LetRecCheckedAtRuntime m - | UpperCaseIdentifierInPattern m - | NotUpperCaseConstructor m - | RecursiveUseCheckedAtRuntime (_, _, m) - | LetRecEvaluatedOutOfOrder (_, _, _, m) - | Error (_, m) - | ErrorWithSuggestions (_, m, _, _) - | NumberedError (_, m) - | SyntaxError (_, m) - | InternalError (_, m) - | FullAbstraction(_, m) - | InterfaceNotRevealed(_, _, m) - | WrappedError (_, m) - | PatternMatchCompilation.MatchIncomplete (_, _, m) - | PatternMatchCompilation.EnumMatchIncomplete (_, _, m) - | PatternMatchCompilation.RuleNeverMatched m - | ValNotMutable(_, _, m) - | ValNotLocal(_, _, m) - | MissingFields(_, m) - | OverrideInIntrinsicAugmentation m - | IntfImplInIntrinsicAugmentation m - | OverrideInExtrinsicAugmentation m - | IntfImplInExtrinsicAugmentation m - | ValueRestriction(_, _, _, _, m) - | LetRecUnsound (_, _, m) - | ObsoleteError (_, m) - | ObsoleteWarning (_, m) - | Experimental (_, m) - | PossibleUnverifiableCode m - | UserCompilerMessage (_, _, m) - | Deprecated(_, m) - | LibraryUseOnly m - | FieldsFromDifferentTypes (_, _, _, m) - | IndeterminateType m - | TyconBadArgs(_, _, _, m) -> - Some m - - | FieldNotContained(_, arf, _, _) -> Some arf.Range - | ValueNotContained(_, _, aval, _, _) -> Some aval.Range - | ConstrNotContained(_, aval, _, _) -> Some aval.Id.idRange - | ExnconstrNotContained(_, aexnc, _, _) -> Some aexnc.Range - - | VarBoundTwice id - | UndefinedName(_, _, id, _) -> - Some id.idRange - - | Duplicate(_, _, m) - | NameClash(_, _, _, m, _, _, _) - | UnresolvedOverloading(_, _, _, m) - | UnresolvedConversionOperator (_, _, _, m) - | PossibleOverload(_, _, _, m) - | VirtualAugmentationOnNullValuedType m - | NonVirtualAugmentationOnNullValuedType m - | NonRigidTypar(_, _, _, _, _, m) - | ConstraintSolverTupleDiffLengths(_, _, _, m, _) - | ConstraintSolverInfiniteTypes(_, _, _, _, m, _) - | ConstraintSolverMissingConstraint(_, _, _, m, _) - | ConstraintSolverTypesNotInEqualityRelation(_, _, _, m, _, _) - | ConstraintSolverError(_, m, _) - | ConstraintSolverTypesNotInSubsumptionRelation(_, _, _, m, _) - | ConstraintSolverRelatedInformation(_, m, _) - | SelfRefObjCtor(_, m) -> - Some m - - | NotAFunction(_, _, mfun, _) -> - Some mfun - - | NotAFunctionButIndexer(_, _, _, mfun, _) -> - Some mfun - - | IllegalFileNameChar(_) -> Some rangeCmdArgs - - | UnresolvedReferenceError(_, m) - | UnresolvedPathReference(_, _, m) - | DeprecatedCommandLineOptionFull(_, m) - | DeprecatedCommandLineOptionForHtmlDoc(_, m) - | DeprecatedCommandLineOptionSuggestAlternative(_, _, m) - | DeprecatedCommandLineOptionNoDescription(_, m) - | InternalCommandLineOption(_, m) - | HashIncludeNotAllowedInNonScript m - | HashReferenceNotAllowedInNonScript m - | HashDirectiveNotAllowedInNonScript m - | FileNameNotResolved(_, _, m) - | LoadedSourceNotFoundIgnoring(_, m) - | MSBuildReferenceResolutionWarning(_, _, m) - | MSBuildReferenceResolutionError(_, _, m) - | AssemblyNotResolved(_, m) - | HashLoadedSourceHasIssues(_, _, m) - | HashLoadedScriptConsideredSource m -> - Some m - // Strip TargetInvocationException wrappers - | :? System.Reflection.TargetInvocationException as e -> - RangeFromException e.InnerException -#if !NO_EXTENSIONTYPING - | :? TypeProviderError as e -> e.Range |> Some -#endif - - | _ -> None - - RangeFromException err.Exception - -let GetDiagnosticNumber(err: PhasedDiagnostic) = - let rec GetFromException(e: exn) = - match e with - (* DO NOT CHANGE THESE NUMBERS *) - | ErrorFromAddingTypeEquation _ -> 1 - | FunctionExpected _ -> 2 - | NotAFunctionButIndexer _ -> 3217 - | NotAFunction _ -> 3 - | FieldNotMutable _ -> 5 - | Recursion _ -> 6 - | InvalidRuntimeCoercion _ -> 7 - | IndeterminateRuntimeCoercion _ -> 8 - | PossibleUnverifiableCode _ -> 9 - | SyntaxError _ -> 10 - // 11 cannot be reused - // 12 cannot be reused - | IndeterminateStaticCoercion _ -> 13 - | StaticCoercionShouldUseBox _ -> 14 - // 15 cannot be reused - | RuntimeCoercionSourceSealed _ -> 16 - | OverrideDoesntOverride _ -> 17 - | UnionPatternsBindDifferentNames _ -> 18 - | UnionCaseWrongArguments _ -> 19 - | UnitTypeExpected _ -> 20 - | UnitTypeExpectedWithEquality _ -> 20 - | UnitTypeExpectedWithPossiblePropertySetter _ -> 20 - | UnitTypeExpectedWithPossibleAssignment _ -> 20 - | RecursiveUseCheckedAtRuntime _ -> 21 - | LetRecEvaluatedOutOfOrder _ -> 22 - | NameClash _ -> 23 - // 24 cannot be reused - | PatternMatchCompilation.MatchIncomplete _ -> 25 - | PatternMatchCompilation.RuleNeverMatched _ -> 26 - | ValNotMutable _ -> 27 - | ValNotLocal _ -> 28 - | MissingFields _ -> 29 - | ValueRestriction _ -> 30 - | LetRecUnsound _ -> 31 - | FieldsFromDifferentTypes _ -> 32 - | TyconBadArgs _ -> 33 - | ValueNotContained _ -> 34 - | Deprecated _ -> 35 - | ConstrNotContained _ -> 36 - | Duplicate _ -> 37 - | VarBoundTwice _ -> 38 - | UndefinedName _ -> 39 - | LetRecCheckedAtRuntime _ -> 40 - | UnresolvedOverloading _ -> 41 - | LibraryUseOnly _ -> 42 - | ErrorFromAddingConstraint _ -> 43 - | ObsoleteWarning _ -> 44 - | FullAbstraction _ -> 45 - | ReservedKeyword _ -> 46 - | SelfRefObjCtor _ -> 47 - | VirtualAugmentationOnNullValuedType _ -> 48 - | UpperCaseIdentifierInPattern _ -> 49 - | InterfaceNotRevealed _ -> 50 - | UseOfAddressOfOperator _ -> 51 - | DefensiveCopyWarning _ -> 52 - | NotUpperCaseConstructor _ -> 53 - | TypeIsImplicitlyAbstract _ -> 54 - // 55 cannot be reused - | DeprecatedThreadStaticBindingWarning _ -> 56 - | Experimental _ -> 57 - | IndentationProblem _ -> 58 - | CoercionTargetSealed _ -> 59 - | OverrideInIntrinsicAugmentation _ -> 60 - | NonVirtualAugmentationOnNullValuedType _ -> 61 - | UserCompilerMessage (_, n, _) -> n - | ExnconstrNotContained _ -> 63 - | NonRigidTypar _ -> 64 - // 65 cannot be reused - | UpcastUnnecessary _ -> 66 - | TypeTestUnnecessary _ -> 67 - | QuotationTranslator.IgnoringPartOfQuotedTermWarning _ -> 68 - | IntfImplInIntrinsicAugmentation _ -> 69 - | NonUniqueInferredAbstractSlot _ -> 70 - | ErrorFromApplyingDefault _ -> 71 - | IndeterminateType _ -> 72 - | InternalError _ -> 73 - | UnresolvedReferenceNoRange _ - | UnresolvedReferenceError _ - | UnresolvedPathReferenceNoRange _ - | UnresolvedPathReference _ -> 74 - | DeprecatedCommandLineOptionFull _ - | DeprecatedCommandLineOptionForHtmlDoc _ - | DeprecatedCommandLineOptionSuggestAlternative _ - | DeprecatedCommandLineOptionNoDescription _ - | InternalCommandLineOption _ -> 75 - | HashIncludeNotAllowedInNonScript _ - | HashReferenceNotAllowedInNonScript _ - | HashDirectiveNotAllowedInNonScript _ -> 76 - | BakedInMemberConstraintName _ -> 77 - | FileNameNotResolved _ -> 78 - | LoadedSourceNotFoundIgnoring _ -> 79 - // 80 cannot be reused - | ParameterlessStructCtor _ -> 81 - | MSBuildReferenceResolutionWarning _ -> 82 - | MSBuildReferenceResolutionError _ -> 83 - | AssemblyNotResolved _ -> 84 - | HashLoadedSourceHasIssues _ -> 85 - | StandardOperatorRedefinitionWarning _ -> 86 - | InvalidInternalsVisibleToAssemblyName _ -> 87 - // 88 cannot be reused - | OverrideInExtrinsicAugmentation _ -> 89 - | IntfImplInExtrinsicAugmentation _ -> 90 - | BadEventTransformation _ -> 91 - | HashLoadedScriptConsideredSource _ -> 92 - | UnresolvedConversionOperator _ -> 93 - // avoid 94-100 for safety - | ObsoleteError _ -> 101 -#if !NO_EXTENSIONTYPING - | ExtensionTyping.ProvidedTypeResolutionNoRange _ - | ExtensionTyping.ProvidedTypeResolution _ -> 103 -#endif - | PatternMatchCompilation.EnumMatchIncomplete _ -> 104 - (* DO NOT CHANGE THE NUMBERS *) - - // Strip TargetInvocationException wrappers - | :? System.Reflection.TargetInvocationException as e -> - GetFromException e.InnerException - - | WrappedError(e, _) -> GetFromException e - - | Error ((n, _), _) -> n - | ErrorWithSuggestions ((n, _), _, _, _) -> n - | Failure _ -> 192 - | NumberedError((n, _), _) -> n - | IllegalFileNameChar(fileName, invalidChar) -> fst (FSComp.SR.buildUnexpectedFileNameCharacter(fileName, string invalidChar)) -#if !NO_EXTENSIONTYPING - | :? TypeProviderError as e -> e.Number -#endif - | ErrorsFromAddingSubsumptionConstraint (_, _, _, _, _, ContextInfo.DowncastUsedInsteadOfUpcast _, _) -> fst (FSComp.SR.considerUpcast("", "")) - | _ -> 193 - GetFromException err.Exception - -let GetWarningLevel err = - match err.Exception with - // Level 5 warnings - | RecursiveUseCheckedAtRuntime _ - | LetRecEvaluatedOutOfOrder _ - | DefensiveCopyWarning _ - | FullAbstraction _ -> 5 - | NumberedError((n, _), _) - | ErrorWithSuggestions((n, _), _, _, _) - | Error((n, _), _) -> - // 1178, tcNoComparisonNeeded1, "The struct, record or union type '%s' is not structurally comparable because the type parameter %s does not satisfy the 'comparison' constraint..." - // 1178, tcNoComparisonNeeded2, "The struct, record or union type '%s' is not structurally comparable because the type '%s' does not satisfy the 'comparison' constraint...." - // 1178, tcNoEqualityNeeded1, "The struct, record or union type '%s' does not support structural equality because the type parameter %s does not satisfy the 'equality' constraint..." - // 1178, tcNoEqualityNeeded2, "The struct, record or union type '%s' does not support structural equality because the type '%s' does not satisfy the 'equality' constraint...." - if (n = 1178) then 5 else 2 - // Level 2 - | _ -> 2 - -let warningOn err level specificWarnOn = - let n = GetDiagnosticNumber err - List.contains n specificWarnOn || - // Some specific warnings are never on by default, i.e. unused variable warnings - match n with - | 1182 -> false // chkUnusedValue - off by default - | 3218 -> false // ArgumentsInSigAndImplMismatch - off by default - | 3180 -> false // abImplicitHeapAllocation - off by default - | _ -> level >= GetWarningLevel err - -let SplitRelatedDiagnostics(err: PhasedDiagnostic) = - let ToPhased e = {Exception=e; Phase = err.Phase} - let rec SplitRelatedException = function - | UnresolvedOverloading(a, overloads, b, c) -> - let related = overloads |> List.map ToPhased - UnresolvedOverloading(a, [], b, c)|>ToPhased, related - | ConstraintSolverRelatedInformation(fopt, m2, e) -> - let e, related = SplitRelatedException e - ConstraintSolverRelatedInformation(fopt, m2, e.Exception)|>ToPhased, related - | ErrorFromAddingTypeEquation(g, denv, t1, t2, e, m) -> - let e, related = SplitRelatedException e - ErrorFromAddingTypeEquation(g, denv, t1, t2, e.Exception, m)|>ToPhased, related - | ErrorFromApplyingDefault(g, denv, tp, defaultType, e, m) -> - let e, related = SplitRelatedException e - ErrorFromApplyingDefault(g, denv, tp, defaultType, e.Exception, m)|>ToPhased, related - | ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e, contextInfo, m) -> - let e, related = SplitRelatedException e - ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e.Exception, contextInfo, m)|>ToPhased, related - | ErrorFromAddingConstraint(x, e, m) -> - let e, related = SplitRelatedException e - ErrorFromAddingConstraint(x, e.Exception, m)|>ToPhased, related - | WrappedError (e, m) -> - let e, related = SplitRelatedException e - WrappedError(e.Exception, m)|>ToPhased, related - // Strip TargetInvocationException wrappers - | :? System.Reflection.TargetInvocationException as e -> - SplitRelatedException e.InnerException - | e -> - ToPhased e, [] - SplitRelatedException err.Exception - - -let DeclareMessage = FSharp.Compiler.DiagnosticMessage.DeclareResourceString - -do FSComp.SR.RunStartupValidation() -let SeeAlsoE() = DeclareResourceString("SeeAlso", "%s") -let ConstraintSolverTupleDiffLengthsE() = DeclareResourceString("ConstraintSolverTupleDiffLengths", "%d%d") -let ConstraintSolverInfiniteTypesE() = DeclareResourceString("ConstraintSolverInfiniteTypes", "%s%s") -let ConstraintSolverMissingConstraintE() = DeclareResourceString("ConstraintSolverMissingConstraint", "%s") -let ConstraintSolverTypesNotInEqualityRelation1E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation1", "%s%s") -let ConstraintSolverTypesNotInEqualityRelation2E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation2", "%s%s") -let ConstraintSolverTypesNotInSubsumptionRelationE() = DeclareResourceString("ConstraintSolverTypesNotInSubsumptionRelation", "%s%s%s") -let ErrorFromAddingTypeEquation1E() = DeclareResourceString("ErrorFromAddingTypeEquation1", "%s%s%s") -let ErrorFromAddingTypeEquation2E() = DeclareResourceString("ErrorFromAddingTypeEquation2", "%s%s%s") -let ErrorFromApplyingDefault1E() = DeclareResourceString("ErrorFromApplyingDefault1", "%s") -let ErrorFromApplyingDefault2E() = DeclareResourceString("ErrorFromApplyingDefault2", "") -let ErrorsFromAddingSubsumptionConstraintE() = DeclareResourceString("ErrorsFromAddingSubsumptionConstraint", "%s%s%s") -let UpperCaseIdentifierInPatternE() = DeclareResourceString("UpperCaseIdentifierInPattern", "") -let NotUpperCaseConstructorE() = DeclareResourceString("NotUpperCaseConstructor", "") -let PossibleOverloadE() = DeclareResourceString("PossibleOverload", "%s%s") -let FunctionExpectedE() = DeclareResourceString("FunctionExpected", "") -let BakedInMemberConstraintNameE() = DeclareResourceString("BakedInMemberConstraintName", "%s") -let BadEventTransformationE() = DeclareResourceString("BadEventTransformation", "") -let ParameterlessStructCtorE() = DeclareResourceString("ParameterlessStructCtor", "") -let InterfaceNotRevealedE() = DeclareResourceString("InterfaceNotRevealed", "%s") -let TyconBadArgsE() = DeclareResourceString("TyconBadArgs", "%s%d%d") -let IndeterminateTypeE() = DeclareResourceString("IndeterminateType", "") -let NameClash1E() = DeclareResourceString("NameClash1", "%s%s") -let NameClash2E() = DeclareResourceString("NameClash2", "%s%s%s%s%s") -let Duplicate1E() = DeclareResourceString("Duplicate1", "%s") -let Duplicate2E() = DeclareResourceString("Duplicate2", "%s%s") -let UndefinedName2E() = DeclareResourceString("UndefinedName2", "") -let FieldNotMutableE() = DeclareResourceString("FieldNotMutable", "") -let FieldsFromDifferentTypesE() = DeclareResourceString("FieldsFromDifferentTypes", "%s%s") -let VarBoundTwiceE() = DeclareResourceString("VarBoundTwice", "%s") -let RecursionE() = DeclareResourceString("Recursion", "%s%s%s%s") -let InvalidRuntimeCoercionE() = DeclareResourceString("InvalidRuntimeCoercion", "%s%s%s") -let IndeterminateRuntimeCoercionE() = DeclareResourceString("IndeterminateRuntimeCoercion", "%s%s") -let IndeterminateStaticCoercionE() = DeclareResourceString("IndeterminateStaticCoercion", "%s%s") -let StaticCoercionShouldUseBoxE() = DeclareResourceString("StaticCoercionShouldUseBox", "%s%s") -let TypeIsImplicitlyAbstractE() = DeclareResourceString("TypeIsImplicitlyAbstract", "") -let NonRigidTypar1E() = DeclareResourceString("NonRigidTypar1", "%s%s") -let NonRigidTypar2E() = DeclareResourceString("NonRigidTypar2", "%s%s") -let NonRigidTypar3E() = DeclareResourceString("NonRigidTypar3", "%s%s") -let OBlockEndSentenceE() = DeclareResourceString("BlockEndSentence", "") -let UnexpectedEndOfInputE() = DeclareResourceString("UnexpectedEndOfInput", "") -let UnexpectedE() = DeclareResourceString("Unexpected", "%s") -let NONTERM_interactionE() = DeclareResourceString("NONTERM.interaction", "") -let NONTERM_hashDirectiveE() = DeclareResourceString("NONTERM.hashDirective", "") -let NONTERM_fieldDeclE() = DeclareResourceString("NONTERM.fieldDecl", "") -let NONTERM_unionCaseReprE() = DeclareResourceString("NONTERM.unionCaseRepr", "") -let NONTERM_localBindingE() = DeclareResourceString("NONTERM.localBinding", "") -let NONTERM_hardwhiteLetBindingsE() = DeclareResourceString("NONTERM.hardwhiteLetBindings", "") -let NONTERM_classDefnMemberE() = DeclareResourceString("NONTERM.classDefnMember", "") -let NONTERM_defnBindingsE() = DeclareResourceString("NONTERM.defnBindings", "") -let NONTERM_classMemberSpfnE() = DeclareResourceString("NONTERM.classMemberSpfn", "") -let NONTERM_valSpfnE() = DeclareResourceString("NONTERM.valSpfn", "") -let NONTERM_tyconSpfnE() = DeclareResourceString("NONTERM.tyconSpfn", "") -let NONTERM_anonLambdaExprE() = DeclareResourceString("NONTERM.anonLambdaExpr", "") -let NONTERM_attrUnionCaseDeclE() = DeclareResourceString("NONTERM.attrUnionCaseDecl", "") -let NONTERM_cPrototypeE() = DeclareResourceString("NONTERM.cPrototype", "") -let NONTERM_objectImplementationMembersE() = DeclareResourceString("NONTERM.objectImplementationMembers", "") -let NONTERM_ifExprCasesE() = DeclareResourceString("NONTERM.ifExprCases", "") -let NONTERM_openDeclE() = DeclareResourceString("NONTERM.openDecl", "") -let NONTERM_fileModuleSpecE() = DeclareResourceString("NONTERM.fileModuleSpec", "") -let NONTERM_patternClausesE() = DeclareResourceString("NONTERM.patternClauses", "") -let NONTERM_beginEndExprE() = DeclareResourceString("NONTERM.beginEndExpr", "") -let NONTERM_recdExprE() = DeclareResourceString("NONTERM.recdExpr", "") -let NONTERM_tyconDefnE() = DeclareResourceString("NONTERM.tyconDefn", "") -let NONTERM_exconCoreE() = DeclareResourceString("NONTERM.exconCore", "") -let NONTERM_typeNameInfoE() = DeclareResourceString("NONTERM.typeNameInfo", "") -let NONTERM_attributeListE() = DeclareResourceString("NONTERM.attributeList", "") -let NONTERM_quoteExprE() = DeclareResourceString("NONTERM.quoteExpr", "") -let NONTERM_typeConstraintE() = DeclareResourceString("NONTERM.typeConstraint", "") -let NONTERM_Category_ImplementationFileE() = DeclareResourceString("NONTERM.Category.ImplementationFile", "") -let NONTERM_Category_DefinitionE() = DeclareResourceString("NONTERM.Category.Definition", "") -let NONTERM_Category_SignatureFileE() = DeclareResourceString("NONTERM.Category.SignatureFile", "") -let NONTERM_Category_PatternE() = DeclareResourceString("NONTERM.Category.Pattern", "") -let NONTERM_Category_ExprE() = DeclareResourceString("NONTERM.Category.Expr", "") -let NONTERM_Category_TypeE() = DeclareResourceString("NONTERM.Category.Type", "") -let NONTERM_typeArgsActualE() = DeclareResourceString("NONTERM.typeArgsActual", "") -let TokenName1E() = DeclareResourceString("TokenName1", "%s") -let TokenName1TokenName2E() = DeclareResourceString("TokenName1TokenName2", "%s%s") -let TokenName1TokenName2TokenName3E() = DeclareResourceString("TokenName1TokenName2TokenName3", "%s%s%s") -let RuntimeCoercionSourceSealed1E() = DeclareResourceString("RuntimeCoercionSourceSealed1", "%s") -let RuntimeCoercionSourceSealed2E() = DeclareResourceString("RuntimeCoercionSourceSealed2", "%s") -let CoercionTargetSealedE() = DeclareResourceString("CoercionTargetSealed", "%s") -let UpcastUnnecessaryE() = DeclareResourceString("UpcastUnnecessary", "") -let TypeTestUnnecessaryE() = DeclareResourceString("TypeTestUnnecessary", "") -let OverrideDoesntOverride1E() = DeclareResourceString("OverrideDoesntOverride1", "%s") -let OverrideDoesntOverride2E() = DeclareResourceString("OverrideDoesntOverride2", "%s") -let OverrideDoesntOverride3E() = DeclareResourceString("OverrideDoesntOverride3", "%s") -let OverrideDoesntOverride4E() = DeclareResourceString("OverrideDoesntOverride4", "%s") -let UnionCaseWrongArgumentsE() = DeclareResourceString("UnionCaseWrongArguments", "%d%d") -let UnionPatternsBindDifferentNamesE() = DeclareResourceString("UnionPatternsBindDifferentNames", "") -let RequiredButNotSpecifiedE() = DeclareResourceString("RequiredButNotSpecified", "%s%s%s") -let UseOfAddressOfOperatorE() = DeclareResourceString("UseOfAddressOfOperator", "") -let DefensiveCopyWarningE() = DeclareResourceString("DefensiveCopyWarning", "%s") -let DeprecatedThreadStaticBindingWarningE() = DeclareResourceString("DeprecatedThreadStaticBindingWarning", "") -let FunctionValueUnexpectedE() = DeclareResourceString("FunctionValueUnexpected", "%s") -let UnitTypeExpectedE() = DeclareResourceString("UnitTypeExpected", "%s") -let UnitTypeExpectedWithEqualityE() = DeclareResourceString("UnitTypeExpectedWithEquality", "%s") -let UnitTypeExpectedWithPossiblePropertySetterE() = DeclareResourceString("UnitTypeExpectedWithPossiblePropertySetter", "%s%s%s") -let UnitTypeExpectedWithPossibleAssignmentE() = DeclareResourceString("UnitTypeExpectedWithPossibleAssignment", "%s%s") -let UnitTypeExpectedWithPossibleAssignmentToMutableE() = DeclareResourceString("UnitTypeExpectedWithPossibleAssignmentToMutable", "%s%s") -let RecursiveUseCheckedAtRuntimeE() = DeclareResourceString("RecursiveUseCheckedAtRuntime", "") -let LetRecUnsound1E() = DeclareResourceString("LetRecUnsound1", "%s") -let LetRecUnsound2E() = DeclareResourceString("LetRecUnsound2", "%s%s") -let LetRecUnsoundInnerE() = DeclareResourceString("LetRecUnsoundInner", "%s") -let LetRecEvaluatedOutOfOrderE() = DeclareResourceString("LetRecEvaluatedOutOfOrder", "") -let LetRecCheckedAtRuntimeE() = DeclareResourceString("LetRecCheckedAtRuntime", "") -let SelfRefObjCtor1E() = DeclareResourceString("SelfRefObjCtor1", "") -let SelfRefObjCtor2E() = DeclareResourceString("SelfRefObjCtor2", "") -let VirtualAugmentationOnNullValuedTypeE() = DeclareResourceString("VirtualAugmentationOnNullValuedType", "") -let NonVirtualAugmentationOnNullValuedTypeE() = DeclareResourceString("NonVirtualAugmentationOnNullValuedType", "") -let NonUniqueInferredAbstractSlot1E() = DeclareResourceString("NonUniqueInferredAbstractSlot1", "%s") -let NonUniqueInferredAbstractSlot2E() = DeclareResourceString("NonUniqueInferredAbstractSlot2", "") -let NonUniqueInferredAbstractSlot3E() = DeclareResourceString("NonUniqueInferredAbstractSlot3", "%s%s") -let NonUniqueInferredAbstractSlot4E() = DeclareResourceString("NonUniqueInferredAbstractSlot4", "") -let Failure3E() = DeclareResourceString("Failure3", "%s") -let Failure4E() = DeclareResourceString("Failure4", "%s") -let FullAbstractionE() = DeclareResourceString("FullAbstraction", "%s") -let MatchIncomplete1E() = DeclareResourceString("MatchIncomplete1", "") -let MatchIncomplete2E() = DeclareResourceString("MatchIncomplete2", "%s") -let MatchIncomplete3E() = DeclareResourceString("MatchIncomplete3", "%s") -let MatchIncomplete4E() = DeclareResourceString("MatchIncomplete4", "") -let RuleNeverMatchedE() = DeclareResourceString("RuleNeverMatched", "") -let EnumMatchIncomplete1E() = DeclareResourceString("EnumMatchIncomplete1", "") -let ValNotMutableE() = DeclareResourceString("ValNotMutable", "%s") -let ValNotLocalE() = DeclareResourceString("ValNotLocal", "") -let Obsolete1E() = DeclareResourceString("Obsolete1", "") -let Obsolete2E() = DeclareResourceString("Obsolete2", "%s") -let ExperimentalE() = DeclareResourceString("Experimental", "%s") -let PossibleUnverifiableCodeE() = DeclareResourceString("PossibleUnverifiableCode", "") -let DeprecatedE() = DeclareResourceString("Deprecated", "%s") -let LibraryUseOnlyE() = DeclareResourceString("LibraryUseOnly", "") -let MissingFieldsE() = DeclareResourceString("MissingFields", "%s") -let ValueRestriction1E() = DeclareResourceString("ValueRestriction1", "%s%s%s") -let ValueRestriction2E() = DeclareResourceString("ValueRestriction2", "%s%s%s") -let ValueRestriction3E() = DeclareResourceString("ValueRestriction3", "%s") -let ValueRestriction4E() = DeclareResourceString("ValueRestriction4", "%s%s%s") -let ValueRestriction5E() = DeclareResourceString("ValueRestriction5", "%s%s%s") -let RecoverableParseErrorE() = DeclareResourceString("RecoverableParseError", "") -let ReservedKeywordE() = DeclareResourceString("ReservedKeyword", "%s") -let IndentationProblemE() = DeclareResourceString("IndentationProblem", "%s") -let OverrideInIntrinsicAugmentationE() = DeclareResourceString("OverrideInIntrinsicAugmentation", "") -let OverrideInExtrinsicAugmentationE() = DeclareResourceString("OverrideInExtrinsicAugmentation", "") -let IntfImplInIntrinsicAugmentationE() = DeclareResourceString("IntfImplInIntrinsicAugmentation", "") -let IntfImplInExtrinsicAugmentationE() = DeclareResourceString("IntfImplInExtrinsicAugmentation", "") -let UnresolvedReferenceNoRangeE() = DeclareResourceString("UnresolvedReferenceNoRange", "%s") -let UnresolvedPathReferenceNoRangeE() = DeclareResourceString("UnresolvedPathReferenceNoRange", "%s%s") -let HashIncludeNotAllowedInNonScriptE() = DeclareResourceString("HashIncludeNotAllowedInNonScript", "") -let HashReferenceNotAllowedInNonScriptE() = DeclareResourceString("HashReferenceNotAllowedInNonScript", "") -let HashDirectiveNotAllowedInNonScriptE() = DeclareResourceString("HashDirectiveNotAllowedInNonScript", "") -let FileNameNotResolvedE() = DeclareResourceString("FileNameNotResolved", "%s%s") -let AssemblyNotResolvedE() = DeclareResourceString("AssemblyNotResolved", "%s") -let HashLoadedSourceHasIssues1E() = DeclareResourceString("HashLoadedSourceHasIssues1", "") -let HashLoadedSourceHasIssues2E() = DeclareResourceString("HashLoadedSourceHasIssues2", "") -let HashLoadedScriptConsideredSourceE() = DeclareResourceString("HashLoadedScriptConsideredSource", "") -let InvalidInternalsVisibleToAssemblyName1E() = DeclareResourceString("InvalidInternalsVisibleToAssemblyName1", "%s%s") -let InvalidInternalsVisibleToAssemblyName2E() = DeclareResourceString("InvalidInternalsVisibleToAssemblyName2", "%s") -let LoadedSourceNotFoundIgnoringE() = DeclareResourceString("LoadedSourceNotFoundIgnoring", "%s") -let MSBuildReferenceResolutionErrorE() = DeclareResourceString("MSBuildReferenceResolutionError", "%s%s") -let TargetInvocationExceptionWrapperE() = DeclareResourceString("TargetInvocationExceptionWrapper", "%s") - -let getErrorString key = SR.GetString key - -let (|InvalidArgument|_|) (exn: exn) = match exn with :? ArgumentException as e -> Some e.Message | _ -> None - -let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (canSuggestNames: bool) = - - let suggestNames suggestionsF idText = - if canSuggestNames then - let buffer = ErrorResolutionHints.SuggestionBuffer idText - if not buffer.Disabled then - suggestionsF buffer.Add - if not buffer.IsEmpty then - os.Append " " |> ignore - os.Append(FSComp.SR.undefinedNameSuggestionsIntro()) |> ignore - for value in buffer do - os.AppendLine() |> ignore - os.Append " " |> ignore - os.Append(DecompileOpName value) |> ignore - - let rec OutputExceptionR (os: StringBuilder) error = - - match error with - | ConstraintSolverTupleDiffLengths(_, tl1, tl2, m, m2) -> - os.Append(ConstraintSolverTupleDiffLengthsE().Format tl1.Length tl2.Length) |> ignore - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore - - | ConstraintSolverInfiniteTypes(denv, contextInfo, t1, t2, m, m2) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - os.Append(ConstraintSolverInfiniteTypesE().Format t1 t2) |> ignore - - match contextInfo with - | ContextInfo.ReturnInComputationExpression -> - os.Append(" " + FSComp.SR.returnUsedInsteadOfReturnBang()) |> ignore - | ContextInfo.YieldInComputationExpression -> - os.Append(" " + FSComp.SR.yieldUsedInsteadOfYieldBang()) |> ignore - | _ -> () - - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore - - | ConstraintSolverMissingConstraint(denv, tpr, tpc, m, m2) -> - os.Append(ConstraintSolverMissingConstraintE().Format (NicePrint.stringOfTyparConstraint denv (tpr, tpc))) |> ignore - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore - - | ConstraintSolverTypesNotInEqualityRelation(denv, (TType_measure _ as t1), (TType_measure _ as t2), m, m2, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - - os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2 ) |> ignore - - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore - - | ConstraintSolverTypesNotInEqualityRelation(denv, t1, t2, m, m2, contextInfo) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - - match contextInfo with - | ContextInfo.IfExpression range when Range.equals range m -> os.Append(FSComp.SR.ifExpression(t1, t2)) |> ignore - | ContextInfo.CollectionElement (isArray, range) when Range.equals range m -> - if isArray then - os.Append(FSComp.SR.arrayElementHasWrongType(t1, t2)) |> ignore - else - os.Append(FSComp.SR.listElementHasWrongType(t1, t2)) |> ignore - | ContextInfo.OmittedElseBranch range when Range.equals range m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore - | ContextInfo.ElseBranchResult range when Range.equals range m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1, t2)) |> ignore - | ContextInfo.FollowingPatternMatchClause range when Range.equals range m -> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1, t2)) |> ignore - | ContextInfo.PatternMatchGuard range when Range.equals range m -> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2)) |> ignore - | _ -> os.Append(ConstraintSolverTypesNotInEqualityRelation2E().Format t1 t2) |> ignore - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore - - | ConstraintSolverTypesNotInSubsumptionRelation(denv, t1, t2, m, m2) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - os.Append(ConstraintSolverTypesNotInSubsumptionRelationE().Format t2 t1 cxs) |> ignore - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore - - | ConstraintSolverError(msg, m, m2) -> - os.Append msg |> ignore - if m.StartLine <> m2.StartLine then - os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore - - | ConstraintSolverRelatedInformation(fopt, _, e) -> - match e with - | ConstraintSolverError _ -> OutputExceptionR os e - | _ -> () - fopt |> Option.iter (Printf.bprintf os " %s") - - | ErrorFromAddingTypeEquation(g, denv, t1, t2, ConstraintSolverTypesNotInEqualityRelation(_, t1', t2', m, _, contextInfo), _) - when typeEquiv g t1 t1' - && typeEquiv g t2 t2' -> - let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - match contextInfo with - | ContextInfo.IfExpression range when Range.equals range m -> os.Append(FSComp.SR.ifExpression(t1, t2)) |> ignore - | ContextInfo.CollectionElement (isArray, range) when Range.equals range m -> - if isArray then - os.Append(FSComp.SR.arrayElementHasWrongType(t1, t2)) |> ignore - else - os.Append(FSComp.SR.listElementHasWrongType(t1, t2)) |> ignore - | ContextInfo.OmittedElseBranch range when Range.equals range m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore - | ContextInfo.ElseBranchResult range when Range.equals range m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1, t2)) |> ignore - | ContextInfo.FollowingPatternMatchClause range when Range.equals range m -> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1, t2)) |> ignore - | ContextInfo.PatternMatchGuard range when Range.equals range m -> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2)) |> ignore - | ContextInfo.TupleInRecordFields -> - os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore - os.Append(System.Environment.NewLine + FSComp.SR.commaInsteadOfSemicolonInRecord()) |> ignore - | _ when t2 = "bool" && t1.EndsWithOrdinal(" ref") -> - os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore - os.Append(System.Environment.NewLine + FSComp.SR.derefInsteadOfNot()) |> ignore - | _ -> os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore - - | ErrorFromAddingTypeEquation(_, _, _, _, ((ConstraintSolverTypesNotInEqualityRelation (_, _, _, _, _, contextInfo) ) as e), _) when (match contextInfo with ContextInfo.NoContext -> false | _ -> true) -> - OutputExceptionR os e - - | ErrorFromAddingTypeEquation(_, _, _, _, ((ConstraintSolverTypesNotInSubsumptionRelation _ | ConstraintSolverError _ ) as e), _) -> - OutputExceptionR os e - - | ErrorFromAddingTypeEquation(g, denv, t1, t2, e, _) -> - if not (typeEquiv g t1 t2) then - let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - if t1<>t2 + tpcs then os.Append(ErrorFromAddingTypeEquation2E().Format t1 t2 tpcs) |> ignore - - OutputExceptionR os e - - | ErrorFromApplyingDefault(_, denv, _, defaultType, e, _) -> - let defaultType = NicePrint.minimalStringOfType denv defaultType - os.Append(ErrorFromApplyingDefault1E().Format defaultType) |> ignore - OutputExceptionR os e - os.Append(ErrorFromApplyingDefault2E().Format) |> ignore - - | ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e, contextInfo, _) -> - match contextInfo with - | ContextInfo.DowncastUsedInsteadOfUpcast isOperator -> - let t1, t2, _ = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - if isOperator then - os.Append(FSComp.SR.considerUpcastOperator(t1, t2) |> snd) |> ignore - else - os.Append(FSComp.SR.considerUpcast(t1, t2) |> snd) |> ignore - | _ -> - if not (typeEquiv g t1 t2) then - let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 - if t1 <> (t2 + tpcs) then - os.Append(ErrorsFromAddingSubsumptionConstraintE().Format t2 t1 tpcs) |> ignore - else - OutputExceptionR os e - else - OutputExceptionR os e - - | UpperCaseIdentifierInPattern(_) -> - os.Append(UpperCaseIdentifierInPatternE().Format) |> ignore - - | NotUpperCaseConstructor(_) -> - os.Append(NotUpperCaseConstructorE().Format) |> ignore - - | ErrorFromAddingConstraint(_, e, _) -> - OutputExceptionR os e - -#if !NO_EXTENSIONTYPING - | ExtensionTyping.ProvidedTypeResolutionNoRange e - - | ExtensionTyping.ProvidedTypeResolution(_, e) -> - OutputExceptionR os e - - | :? TypeProviderError as e -> - os.Append(e.ContextualErrorMessage) |> ignore -#endif - - | UnresolvedOverloading(_, _, mtext, _) -> - os.Append mtext |> ignore - - | UnresolvedConversionOperator(denv, fromTy, toTy, _) -> - let t1, t2, _tpcs = NicePrint.minimalStringsOfTwoTypes denv fromTy toTy - os.Append(FSComp.SR.csTypeDoesNotSupportConversion(t1, t2)) |> ignore - - | PossibleOverload(_, minfo, originalError, _) -> - // print original error that describes reason why this overload was rejected - let buf = new StringBuilder() - OutputExceptionR buf originalError - - os.Append(PossibleOverloadE().Format minfo (buf.ToString())) |> ignore - - | FunctionExpected _ -> - os.Append(FunctionExpectedE().Format) |> ignore - - | BakedInMemberConstraintName(nm, _) -> - os.Append(BakedInMemberConstraintNameE().Format nm) |> ignore - - | StandardOperatorRedefinitionWarning(msg, _) -> - os.Append msg |> ignore - - | BadEventTransformation(_) -> - os.Append(BadEventTransformationE().Format) |> ignore - - | ParameterlessStructCtor(_) -> - os.Append(ParameterlessStructCtorE().Format) |> ignore - - | InterfaceNotRevealed(denv, ity, _) -> - os.Append(InterfaceNotRevealedE().Format (NicePrint.minimalStringOfType denv ity)) |> ignore - - | NotAFunctionButIndexer(_, _, name, _, _) -> - match name with - | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName name) |> ignore - | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer()) |> ignore - - | NotAFunction(_, _, _, marg) -> - if marg.StartColumn = 0 then - os.Append(FSComp.SR.notAFunctionButMaybeDeclaration()) |> ignore - else - os.Append(FSComp.SR.notAFunction()) |> ignore - - | TyconBadArgs(_, tcref, d, _) -> - let exp = tcref.TyparsNoRange.Length - if exp = 0 then - os.Append(FSComp.SR.buildUnexpectedTypeArgs(fullDisplayTextOfTyconRef tcref, d)) |> ignore - else - os.Append(TyconBadArgsE().Format (fullDisplayTextOfTyconRef tcref) exp d) |> ignore - - | IndeterminateType(_) -> - os.Append(IndeterminateTypeE().Format) |> ignore - - | NameClash(nm, k1, nm1, _, k2, nm2, _) -> - if nm = nm1 && nm1 = nm2 && k1 = k2 then - os.Append(NameClash1E().Format k1 nm1) |> ignore - else - os.Append(NameClash2E().Format k1 nm1 nm k2 nm2) |> ignore - - | Duplicate(k, s, _) -> - if k = "member" then - os.Append(Duplicate1E().Format (DecompileOpName s)) |> ignore - else - os.Append(Duplicate2E().Format k (DecompileOpName s)) |> ignore - - | UndefinedName(_, k, id, suggestionsF) -> - os.Append(k (DecompileOpName id.idText)) |> ignore - suggestNames suggestionsF id.idText - - | InternalUndefinedItemRef(f, smr, ccuName, s) -> - let _, errs = f(smr, ccuName, s) - os.Append errs |> ignore - - | FieldNotMutable _ -> - os.Append(FieldNotMutableE().Format) |> ignore - - | FieldsFromDifferentTypes (_, fref1, fref2, _) -> - os.Append(FieldsFromDifferentTypesE().Format fref1.FieldName fref2.FieldName) |> ignore - - | VarBoundTwice id -> - os.Append(VarBoundTwiceE().Format (DecompileOpName id.idText)) |> ignore - - | Recursion (denv, id, ty1, ty2, _) -> - let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(RecursionE().Format (DecompileOpName id.idText) t1 t2 tpcs) |> ignore - - | InvalidRuntimeCoercion(denv, ty1, ty2, _) -> - let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(InvalidRuntimeCoercionE().Format t1 t2 tpcs) |> ignore - - | IndeterminateRuntimeCoercion(denv, ty1, ty2, _) -> - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(IndeterminateRuntimeCoercionE().Format t1 t2) |> ignore - - | IndeterminateStaticCoercion(denv, ty1, ty2, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(IndeterminateStaticCoercionE().Format t1 t2) |> ignore - - | StaticCoercionShouldUseBox(denv, ty1, ty2, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(StaticCoercionShouldUseBoxE().Format t1 t2) |> ignore - - | TypeIsImplicitlyAbstract(_) -> - os.Append(TypeIsImplicitlyAbstractE().Format) |> ignore - - | NonRigidTypar(denv, tpnmOpt, typarRange, ty1, ty, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let (ty1, ty), _cxs = PrettyTypes.PrettifyTypePair denv.g (ty1, ty) - match tpnmOpt with - | None -> - os.Append(NonRigidTypar1E().Format (stringOfRange typarRange) (NicePrint.stringOfTy denv ty)) |> ignore - | Some tpnm -> - match ty1 with - | TType_measure _ -> - os.Append(NonRigidTypar2E().Format tpnm (NicePrint.stringOfTy denv ty)) |> ignore - | _ -> - os.Append(NonRigidTypar3E().Format tpnm (NicePrint.stringOfTy denv ty)) |> ignore - - | SyntaxError (ctxt, _) -> - let ctxt = unbox>(ctxt) - - let (|EndOfStructuredConstructToken|_|) token = - match token with - | Parser.TOKEN_ODECLEND - | Parser.TOKEN_OBLOCKSEP - | Parser.TOKEN_OEND - | Parser.TOKEN_ORIGHT_BLOCK_END - | Parser.TOKEN_OBLOCKEND | Parser.TOKEN_OBLOCKEND_COMING_SOON | Parser.TOKEN_OBLOCKEND_IS_HERE -> Some() - | _ -> None - - let tokenIdToText tid = - match tid with - | Parser.TOKEN_IDENT -> getErrorString("Parser.TOKEN.IDENT") - | Parser.TOKEN_BIGNUM - | Parser.TOKEN_INT8 - | Parser.TOKEN_UINT8 - | Parser.TOKEN_INT16 - | Parser.TOKEN_UINT16 - | Parser.TOKEN_INT32 - | Parser.TOKEN_UINT32 - | Parser.TOKEN_INT64 - | Parser.TOKEN_UINT64 - | Parser.TOKEN_UNATIVEINT - | Parser.TOKEN_NATIVEINT -> getErrorString("Parser.TOKEN.INT") - | Parser.TOKEN_IEEE32 - | Parser.TOKEN_IEEE64 -> getErrorString("Parser.TOKEN.FLOAT") - | Parser.TOKEN_DECIMAL -> getErrorString("Parser.TOKEN.DECIMAL") - | Parser.TOKEN_CHAR -> getErrorString("Parser.TOKEN.CHAR") - - | Parser.TOKEN_BASE -> getErrorString("Parser.TOKEN.BASE") - | Parser.TOKEN_LPAREN_STAR_RPAREN -> getErrorString("Parser.TOKEN.LPAREN.STAR.RPAREN") - | Parser.TOKEN_DOLLAR -> getErrorString("Parser.TOKEN.DOLLAR") - | Parser.TOKEN_INFIX_STAR_STAR_OP -> getErrorString("Parser.TOKEN.INFIX.STAR.STAR.OP") - | Parser.TOKEN_INFIX_COMPARE_OP -> getErrorString("Parser.TOKEN.INFIX.COMPARE.OP") - | Parser.TOKEN_COLON_GREATER -> getErrorString("Parser.TOKEN.COLON.GREATER") - | Parser.TOKEN_COLON_COLON ->getErrorString("Parser.TOKEN.COLON.COLON") - | Parser.TOKEN_PERCENT_OP -> getErrorString("Parser.TOKEN.PERCENT.OP") - | Parser.TOKEN_INFIX_AT_HAT_OP -> getErrorString("Parser.TOKEN.INFIX.AT.HAT.OP") - | Parser.TOKEN_INFIX_BAR_OP -> getErrorString("Parser.TOKEN.INFIX.BAR.OP") - | Parser.TOKEN_PLUS_MINUS_OP -> getErrorString("Parser.TOKEN.PLUS.MINUS.OP") - | Parser.TOKEN_PREFIX_OP -> getErrorString("Parser.TOKEN.PREFIX.OP") - | Parser.TOKEN_COLON_QMARK_GREATER -> getErrorString("Parser.TOKEN.COLON.QMARK.GREATER") - | Parser.TOKEN_INFIX_STAR_DIV_MOD_OP -> getErrorString("Parser.TOKEN.INFIX.STAR.DIV.MOD.OP") - | Parser.TOKEN_INFIX_AMP_OP -> getErrorString("Parser.TOKEN.INFIX.AMP.OP") - | Parser.TOKEN_AMP -> getErrorString("Parser.TOKEN.AMP") - | Parser.TOKEN_AMP_AMP -> getErrorString("Parser.TOKEN.AMP.AMP") - | Parser.TOKEN_BAR_BAR -> getErrorString("Parser.TOKEN.BAR.BAR") - | Parser.TOKEN_LESS -> getErrorString("Parser.TOKEN.LESS") - | Parser.TOKEN_GREATER -> getErrorString("Parser.TOKEN.GREATER") - | Parser.TOKEN_QMARK -> getErrorString("Parser.TOKEN.QMARK") - | Parser.TOKEN_QMARK_QMARK -> getErrorString("Parser.TOKEN.QMARK.QMARK") - | Parser.TOKEN_COLON_QMARK-> getErrorString("Parser.TOKEN.COLON.QMARK") - | Parser.TOKEN_INT32_DOT_DOT -> getErrorString("Parser.TOKEN.INT32.DOT.DOT") - | Parser.TOKEN_DOT_DOT -> getErrorString("Parser.TOKEN.DOT.DOT") - | Parser.TOKEN_DOT_DOT_HAT -> getErrorString("Parser.TOKEN.DOT.DOT") - | Parser.TOKEN_QUOTE -> getErrorString("Parser.TOKEN.QUOTE") - | Parser.TOKEN_STAR -> getErrorString("Parser.TOKEN.STAR") - | Parser.TOKEN_HIGH_PRECEDENCE_TYAPP -> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.TYAPP") - | Parser.TOKEN_COLON -> getErrorString("Parser.TOKEN.COLON") - | Parser.TOKEN_COLON_EQUALS -> getErrorString("Parser.TOKEN.COLON.EQUALS") - | Parser.TOKEN_LARROW -> getErrorString("Parser.TOKEN.LARROW") - | Parser.TOKEN_EQUALS -> getErrorString("Parser.TOKEN.EQUALS") - | Parser.TOKEN_GREATER_BAR_RBRACK -> getErrorString("Parser.TOKEN.GREATER.BAR.RBRACK") - | Parser.TOKEN_MINUS -> getErrorString("Parser.TOKEN.MINUS") - | Parser.TOKEN_ADJACENT_PREFIX_OP -> getErrorString("Parser.TOKEN.ADJACENT.PREFIX.OP") - | Parser.TOKEN_FUNKY_OPERATOR_NAME -> getErrorString("Parser.TOKEN.FUNKY.OPERATOR.NAME") - | Parser.TOKEN_COMMA-> getErrorString("Parser.TOKEN.COMMA") - | Parser.TOKEN_DOT -> getErrorString("Parser.TOKEN.DOT") - | Parser.TOKEN_BAR-> getErrorString("Parser.TOKEN.BAR") - | Parser.TOKEN_HASH -> getErrorString("Parser.TOKEN.HASH") - | Parser.TOKEN_UNDERSCORE -> getErrorString("Parser.TOKEN.UNDERSCORE") - | Parser.TOKEN_SEMICOLON -> getErrorString("Parser.TOKEN.SEMICOLON") - | Parser.TOKEN_SEMICOLON_SEMICOLON-> getErrorString("Parser.TOKEN.SEMICOLON.SEMICOLON") - | Parser.TOKEN_LPAREN-> getErrorString("Parser.TOKEN.LPAREN") - | Parser.TOKEN_RPAREN | Parser.TOKEN_RPAREN_COMING_SOON | Parser.TOKEN_RPAREN_IS_HERE -> getErrorString("Parser.TOKEN.RPAREN") - | Parser.TOKEN_LQUOTE -> getErrorString("Parser.TOKEN.LQUOTE") - | Parser.TOKEN_LBRACK -> getErrorString("Parser.TOKEN.LBRACK") - | Parser.TOKEN_LBRACE_BAR -> getErrorString("Parser.TOKEN.LBRACE.BAR") - | Parser.TOKEN_LBRACK_BAR -> getErrorString("Parser.TOKEN.LBRACK.BAR") - | Parser.TOKEN_LBRACK_LESS -> getErrorString("Parser.TOKEN.LBRACK.LESS") - | Parser.TOKEN_LBRACE -> getErrorString("Parser.TOKEN.LBRACE") - | Parser.TOKEN_BAR_RBRACK -> getErrorString("Parser.TOKEN.BAR.RBRACK") - | Parser.TOKEN_BAR_RBRACE -> getErrorString("Parser.TOKEN.BAR.RBRACE") - | Parser.TOKEN_GREATER_RBRACK -> getErrorString("Parser.TOKEN.GREATER.RBRACK") - | Parser.TOKEN_RQUOTE_DOT _ - | Parser.TOKEN_RQUOTE -> getErrorString("Parser.TOKEN.RQUOTE") - | Parser.TOKEN_RBRACK -> getErrorString("Parser.TOKEN.RBRACK") - | Parser.TOKEN_RBRACE | Parser.TOKEN_RBRACE_COMING_SOON | Parser.TOKEN_RBRACE_IS_HERE -> getErrorString("Parser.TOKEN.RBRACE") - | Parser.TOKEN_PUBLIC -> getErrorString("Parser.TOKEN.PUBLIC") - | Parser.TOKEN_PRIVATE -> getErrorString("Parser.TOKEN.PRIVATE") - | Parser.TOKEN_INTERNAL -> getErrorString("Parser.TOKEN.INTERNAL") - | Parser.TOKEN_CONSTRAINT -> getErrorString("Parser.TOKEN.CONSTRAINT") - | Parser.TOKEN_INSTANCE -> getErrorString("Parser.TOKEN.INSTANCE") - | Parser.TOKEN_DELEGATE -> getErrorString("Parser.TOKEN.DELEGATE") - | Parser.TOKEN_INHERIT -> getErrorString("Parser.TOKEN.INHERIT") - | Parser.TOKEN_CONSTRUCTOR-> getErrorString("Parser.TOKEN.CONSTRUCTOR") - | Parser.TOKEN_DEFAULT -> getErrorString("Parser.TOKEN.DEFAULT") - | Parser.TOKEN_OVERRIDE-> getErrorString("Parser.TOKEN.OVERRIDE") - | Parser.TOKEN_ABSTRACT-> getErrorString("Parser.TOKEN.ABSTRACT") - | Parser.TOKEN_CLASS-> getErrorString("Parser.TOKEN.CLASS") - | Parser.TOKEN_MEMBER -> getErrorString("Parser.TOKEN.MEMBER") - | Parser.TOKEN_STATIC -> getErrorString("Parser.TOKEN.STATIC") - | Parser.TOKEN_NAMESPACE-> getErrorString("Parser.TOKEN.NAMESPACE") - | Parser.TOKEN_OBLOCKBEGIN -> getErrorString("Parser.TOKEN.OBLOCKBEGIN") - | EndOfStructuredConstructToken -> getErrorString("Parser.TOKEN.OBLOCKEND") - | Parser.TOKEN_THEN - | Parser.TOKEN_OTHEN -> getErrorString("Parser.TOKEN.OTHEN") - | Parser.TOKEN_ELSE - | Parser.TOKEN_OELSE -> getErrorString("Parser.TOKEN.OELSE") - | Parser.TOKEN_LET(_) - | Parser.TOKEN_OLET(_) -> getErrorString("Parser.TOKEN.OLET") - | Parser.TOKEN_OBINDER - | Parser.TOKEN_BINDER -> getErrorString("Parser.TOKEN.BINDER") - | Parser.TOKEN_ODO -> getErrorString("Parser.TOKEN.ODO") - | Parser.TOKEN_OWITH -> getErrorString("Parser.TOKEN.OWITH") - | Parser.TOKEN_OFUNCTION -> getErrorString("Parser.TOKEN.OFUNCTION") - | Parser.TOKEN_OFUN -> getErrorString("Parser.TOKEN.OFUN") - | Parser.TOKEN_ORESET -> getErrorString("Parser.TOKEN.ORESET") - | Parser.TOKEN_ODUMMY -> getErrorString("Parser.TOKEN.ODUMMY") - | Parser.TOKEN_DO_BANG - | Parser.TOKEN_ODO_BANG -> getErrorString("Parser.TOKEN.ODO.BANG") - | Parser.TOKEN_YIELD -> getErrorString("Parser.TOKEN.YIELD") - | Parser.TOKEN_YIELD_BANG -> getErrorString("Parser.TOKEN.YIELD.BANG") - | Parser.TOKEN_OINTERFACE_MEMBER-> getErrorString("Parser.TOKEN.OINTERFACE.MEMBER") - | Parser.TOKEN_ELIF -> getErrorString("Parser.TOKEN.ELIF") - | Parser.TOKEN_RARROW -> getErrorString("Parser.TOKEN.RARROW") - | Parser.TOKEN_SIG -> getErrorString("Parser.TOKEN.SIG") - | Parser.TOKEN_STRUCT -> getErrorString("Parser.TOKEN.STRUCT") - | Parser.TOKEN_UPCAST -> getErrorString("Parser.TOKEN.UPCAST") - | Parser.TOKEN_DOWNCAST -> getErrorString("Parser.TOKEN.DOWNCAST") - | Parser.TOKEN_NULL -> getErrorString("Parser.TOKEN.NULL") - | Parser.TOKEN_RESERVED -> getErrorString("Parser.TOKEN.RESERVED") - | Parser.TOKEN_MODULE | Parser.TOKEN_MODULE_COMING_SOON | Parser.TOKEN_MODULE_IS_HERE -> getErrorString("Parser.TOKEN.MODULE") - | Parser.TOKEN_AND -> getErrorString("Parser.TOKEN.AND") - | Parser.TOKEN_AS -> getErrorString("Parser.TOKEN.AS") - | Parser.TOKEN_ASSERT -> getErrorString("Parser.TOKEN.ASSERT") - | Parser.TOKEN_OASSERT -> getErrorString("Parser.TOKEN.ASSERT") - | Parser.TOKEN_ASR-> getErrorString("Parser.TOKEN.ASR") - | Parser.TOKEN_DOWNTO -> getErrorString("Parser.TOKEN.DOWNTO") - | Parser.TOKEN_EXCEPTION -> getErrorString("Parser.TOKEN.EXCEPTION") - | Parser.TOKEN_FALSE -> getErrorString("Parser.TOKEN.FALSE") - | Parser.TOKEN_FOR -> getErrorString("Parser.TOKEN.FOR") - | Parser.TOKEN_FUN -> getErrorString("Parser.TOKEN.FUN") - | Parser.TOKEN_FUNCTION-> getErrorString("Parser.TOKEN.FUNCTION") - | Parser.TOKEN_FINALLY -> getErrorString("Parser.TOKEN.FINALLY") - | Parser.TOKEN_LAZY -> getErrorString("Parser.TOKEN.LAZY") - | Parser.TOKEN_OLAZY -> getErrorString("Parser.TOKEN.LAZY") - | Parser.TOKEN_MATCH -> getErrorString("Parser.TOKEN.MATCH") - | Parser.TOKEN_MATCH_BANG -> getErrorString("Parser.TOKEN.MATCH.BANG") - | Parser.TOKEN_MUTABLE -> getErrorString("Parser.TOKEN.MUTABLE") - | Parser.TOKEN_NEW -> getErrorString("Parser.TOKEN.NEW") - | Parser.TOKEN_OF -> getErrorString("Parser.TOKEN.OF") - | Parser.TOKEN_OPEN -> getErrorString("Parser.TOKEN.OPEN") - | Parser.TOKEN_OR -> getErrorString("Parser.TOKEN.OR") - | Parser.TOKEN_VOID -> getErrorString("Parser.TOKEN.VOID") - | Parser.TOKEN_EXTERN-> getErrorString("Parser.TOKEN.EXTERN") - | Parser.TOKEN_INTERFACE -> getErrorString("Parser.TOKEN.INTERFACE") - | Parser.TOKEN_REC -> getErrorString("Parser.TOKEN.REC") - | Parser.TOKEN_TO -> getErrorString("Parser.TOKEN.TO") - | Parser.TOKEN_TRUE -> getErrorString("Parser.TOKEN.TRUE") - | Parser.TOKEN_TRY -> getErrorString("Parser.TOKEN.TRY") - | Parser.TOKEN_TYPE | Parser.TOKEN_TYPE_COMING_SOON | Parser.TOKEN_TYPE_IS_HERE -> getErrorString("Parser.TOKEN.TYPE") - | Parser.TOKEN_VAL -> getErrorString("Parser.TOKEN.VAL") - | Parser.TOKEN_INLINE -> getErrorString("Parser.TOKEN.INLINE") - | Parser.TOKEN_WHEN -> getErrorString("Parser.TOKEN.WHEN") - | Parser.TOKEN_WHILE -> getErrorString("Parser.TOKEN.WHILE") - | Parser.TOKEN_WITH-> getErrorString("Parser.TOKEN.WITH") - | Parser.TOKEN_IF -> getErrorString("Parser.TOKEN.IF") - | Parser.TOKEN_DO -> getErrorString("Parser.TOKEN.DO") - | Parser.TOKEN_GLOBAL -> getErrorString("Parser.TOKEN.GLOBAL") - | Parser.TOKEN_DONE -> getErrorString("Parser.TOKEN.DONE") - | Parser.TOKEN_IN | Parser.TOKEN_JOIN_IN -> getErrorString("Parser.TOKEN.IN") - | Parser.TOKEN_HIGH_PRECEDENCE_PAREN_APP-> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.PAREN.APP") - | Parser.TOKEN_HIGH_PRECEDENCE_BRACK_APP-> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.BRACK.APP") - | Parser.TOKEN_BEGIN -> getErrorString("Parser.TOKEN.BEGIN") - | Parser.TOKEN_END -> getErrorString("Parser.TOKEN.END") - | Parser.TOKEN_HASH_LIGHT - | Parser.TOKEN_HASH_LINE - | Parser.TOKEN_HASH_IF - | Parser.TOKEN_HASH_ELSE - | Parser.TOKEN_HASH_ENDIF -> getErrorString("Parser.TOKEN.HASH.ENDIF") - | Parser.TOKEN_INACTIVECODE -> getErrorString("Parser.TOKEN.INACTIVECODE") - | Parser.TOKEN_LEX_FAILURE-> getErrorString("Parser.TOKEN.LEX.FAILURE") - | Parser.TOKEN_WHITESPACE -> getErrorString("Parser.TOKEN.WHITESPACE") - | Parser.TOKEN_COMMENT -> getErrorString("Parser.TOKEN.COMMENT") - | Parser.TOKEN_LINE_COMMENT -> getErrorString("Parser.TOKEN.LINE.COMMENT") - | Parser.TOKEN_STRING_TEXT -> getErrorString("Parser.TOKEN.STRING.TEXT") - | Parser.TOKEN_BYTEARRAY -> getErrorString("Parser.TOKEN.BYTEARRAY") - | Parser.TOKEN_STRING -> getErrorString("Parser.TOKEN.STRING") - | Parser.TOKEN_KEYWORD_STRING -> getErrorString("Parser.TOKEN.KEYWORD_STRING") - | Parser.TOKEN_EOF -> getErrorString("Parser.TOKEN.EOF") - | Parser.TOKEN_CONST -> getErrorString("Parser.TOKEN.CONST") - | Parser.TOKEN_FIXED -> getErrorString("Parser.TOKEN.FIXED") - | unknown -> - Debug.Assert(false, "unknown token tag") - let result = sprintf "%+A" unknown - Debug.Assert(false, result) - result - - match ctxt.CurrentToken with - | None -> os.Append(UnexpectedEndOfInputE().Format) |> ignore - | Some token -> - match (token |> Parser.tagOfToken |> Parser.tokenTagToTokenId), token with - | EndOfStructuredConstructToken, _ -> os.Append(OBlockEndSentenceE().Format) |> ignore - | Parser.TOKEN_LEX_FAILURE, Parser.LEX_FAILURE str -> Printf.bprintf os "%s" str (* Fix bug://2431 *) - | token, _ -> os.Append(UnexpectedE().Format (token |> tokenIdToText)) |> ignore - - (* Search for a state producing a single recognized non-terminal in the states on the stack *) - let foundInContext = - - (* Merge a bunch of expression non terminals *) - let (|NONTERM_Category_Expr|_|) = function - | Parser.NONTERM_argExpr|Parser.NONTERM_minusExpr|Parser.NONTERM_parenExpr|Parser.NONTERM_atomicExpr - | Parser.NONTERM_appExpr|Parser.NONTERM_tupleExpr|Parser.NONTERM_declExpr|Parser.NONTERM_braceExpr|Parser.NONTERM_braceBarExpr - | Parser.NONTERM_typedSeqExprBlock - | Parser.NONTERM_interactiveExpr -> Some() - | _ -> None - - (* Merge a bunch of pattern non terminals *) - let (|NONTERM_Category_Pattern|_|) = function - | Parser.NONTERM_constrPattern|Parser.NONTERM_parenPattern|Parser.NONTERM_atomicPattern -> Some() - | _ -> None - - (* Merge a bunch of if/then/else non terminals *) - let (|NONTERM_Category_IfThenElse|_|) = function - | Parser.NONTERM_ifExprThen|Parser.NONTERM_ifExprElifs|Parser.NONTERM_ifExprCases -> Some() - | _ -> None - - (* Merge a bunch of non terminals *) - let (|NONTERM_Category_SignatureFile|_|) = function - | Parser.NONTERM_signatureFile|Parser.NONTERM_moduleSpfn|Parser.NONTERM_moduleSpfns -> Some() - | _ -> None - let (|NONTERM_Category_ImplementationFile|_|) = function - | Parser.NONTERM_implementationFile|Parser.NONTERM_fileNamespaceImpl|Parser.NONTERM_fileNamespaceImpls -> Some() - | _ -> None - let (|NONTERM_Category_Definition|_|) = function - | Parser.NONTERM_fileModuleImpl|Parser.NONTERM_moduleDefn|Parser.NONTERM_interactiveDefns - |Parser.NONTERM_moduleDefns|Parser.NONTERM_moduleDefnsOrExpr -> Some() - | _ -> None - - let (|NONTERM_Category_Type|_|) = function - | Parser.NONTERM_typ|Parser.NONTERM_tupleType -> Some() - | _ -> None - - let (|NONTERM_Category_Interaction|_|) = function - | Parser.NONTERM_interactiveItemsTerminator|Parser.NONTERM_interaction|Parser.NONTERM__startinteraction -> Some() - | _ -> None - - - // Canonicalize the categories and check for a unique category - ctxt.ReducibleProductions |> List.exists (fun prods -> - match prods - |> List.map Parser.prodIdxToNonTerminal - |> List.map (function - | NONTERM_Category_Type -> Parser.NONTERM_typ - | NONTERM_Category_Expr -> Parser.NONTERM_declExpr - | NONTERM_Category_Pattern -> Parser.NONTERM_atomicPattern - | NONTERM_Category_IfThenElse -> Parser.NONTERM_ifExprThen - | NONTERM_Category_SignatureFile -> Parser.NONTERM_signatureFile - | NONTERM_Category_ImplementationFile -> Parser.NONTERM_implementationFile - | NONTERM_Category_Definition -> Parser.NONTERM_moduleDefn - | NONTERM_Category_Interaction -> Parser.NONTERM_interaction - | nt -> nt) - |> Set.ofList - |> Set.toList with - | [Parser.NONTERM_interaction] -> os.Append(NONTERM_interactionE().Format) |> ignore; true - | [Parser.NONTERM_hashDirective] -> os.Append(NONTERM_hashDirectiveE().Format) |> ignore; true - | [Parser.NONTERM_fieldDecl] -> os.Append(NONTERM_fieldDeclE().Format) |> ignore; true - | [Parser.NONTERM_unionCaseRepr] -> os.Append(NONTERM_unionCaseReprE().Format) |> ignore; true - | [Parser.NONTERM_localBinding] -> os.Append(NONTERM_localBindingE().Format) |> ignore; true - | [Parser.NONTERM_hardwhiteLetBindings] -> os.Append(NONTERM_hardwhiteLetBindingsE().Format) |> ignore; true - | [Parser.NONTERM_classDefnMember] -> os.Append(NONTERM_classDefnMemberE().Format) |> ignore; true - | [Parser.NONTERM_defnBindings] -> os.Append(NONTERM_defnBindingsE().Format) |> ignore; true - | [Parser.NONTERM_classMemberSpfn] -> os.Append(NONTERM_classMemberSpfnE().Format) |> ignore; true - | [Parser.NONTERM_valSpfn] -> os.Append(NONTERM_valSpfnE().Format) |> ignore; true - | [Parser.NONTERM_tyconSpfn] -> os.Append(NONTERM_tyconSpfnE().Format) |> ignore; true - | [Parser.NONTERM_anonLambdaExpr] -> os.Append(NONTERM_anonLambdaExprE().Format) |> ignore; true - | [Parser.NONTERM_attrUnionCaseDecl] -> os.Append(NONTERM_attrUnionCaseDeclE().Format) |> ignore; true - | [Parser.NONTERM_cPrototype] -> os.Append(NONTERM_cPrototypeE().Format) |> ignore; true - | [Parser.NONTERM_objExpr|Parser.NONTERM_objectImplementationMembers] -> os.Append(NONTERM_objectImplementationMembersE().Format) |> ignore; true - | [Parser.NONTERM_ifExprThen|Parser.NONTERM_ifExprElifs|Parser.NONTERM_ifExprCases] -> os.Append(NONTERM_ifExprCasesE().Format) |> ignore; true - | [Parser.NONTERM_openDecl] -> os.Append(NONTERM_openDeclE().Format) |> ignore; true - | [Parser.NONTERM_fileModuleSpec] -> os.Append(NONTERM_fileModuleSpecE().Format) |> ignore; true - | [Parser.NONTERM_patternClauses] -> os.Append(NONTERM_patternClausesE().Format) |> ignore; true - | [Parser.NONTERM_beginEndExpr] -> os.Append(NONTERM_beginEndExprE().Format) |> ignore; true - | [Parser.NONTERM_recdExpr] -> os.Append(NONTERM_recdExprE().Format) |> ignore; true - | [Parser.NONTERM_tyconDefn] -> os.Append(NONTERM_tyconDefnE().Format) |> ignore; true - | [Parser.NONTERM_exconCore] -> os.Append(NONTERM_exconCoreE().Format) |> ignore; true - | [Parser.NONTERM_typeNameInfo] -> os.Append(NONTERM_typeNameInfoE().Format) |> ignore; true - | [Parser.NONTERM_attributeList] -> os.Append(NONTERM_attributeListE().Format) |> ignore; true - | [Parser.NONTERM_quoteExpr] -> os.Append(NONTERM_quoteExprE().Format) |> ignore; true - | [Parser.NONTERM_typeConstraint] -> os.Append(NONTERM_typeConstraintE().Format) |> ignore; true - | [NONTERM_Category_ImplementationFile] -> os.Append(NONTERM_Category_ImplementationFileE().Format) |> ignore; true - | [NONTERM_Category_Definition] -> os.Append(NONTERM_Category_DefinitionE().Format) |> ignore; true - | [NONTERM_Category_SignatureFile] -> os.Append(NONTERM_Category_SignatureFileE().Format) |> ignore; true - | [NONTERM_Category_Pattern] -> os.Append(NONTERM_Category_PatternE().Format) |> ignore; true - | [NONTERM_Category_Expr] -> os.Append(NONTERM_Category_ExprE().Format) |> ignore; true - | [NONTERM_Category_Type] -> os.Append(NONTERM_Category_TypeE().Format) |> ignore; true - | [Parser.NONTERM_typeArgsActual] -> os.Append(NONTERM_typeArgsActualE().Format) |> ignore; true - | _ -> - false) - -#if DEBUG - if not foundInContext then - Printf.bprintf os ". (no 'in' context found: %+A)" (List.map (List.map Parser.prodIdxToNonTerminal) ctxt.ReducibleProductions) -#else - foundInContext |> ignore // suppress unused variable warning in RELEASE -#endif - let fix (s: string) = s.Replace(SR.GetString("FixKeyword"), "").Replace(SR.GetString("FixSymbol"), "").Replace(SR.GetString("FixReplace"), "") - match (ctxt.ShiftTokens - |> List.map Parser.tokenTagToTokenId - |> List.filter (function Parser.TOKEN_error | Parser.TOKEN_EOF -> false | _ -> true) - |> List.map tokenIdToText - |> Set.ofList - |> Set.toList) with - | [tokenName1] -> os.Append(TokenName1E().Format (fix tokenName1)) |> ignore - | [tokenName1;tokenName2] -> os.Append(TokenName1TokenName2E().Format (fix tokenName1) (fix tokenName2)) |> ignore - | [tokenName1;tokenName2;tokenName3] -> os.Append(TokenName1TokenName2TokenName3E().Format (fix tokenName1) (fix tokenName2) (fix tokenName3)) |> ignore - | _ -> () - (* - Printf.bprintf os ".\n\n state = %A\n token = %A\n expect (shift) %A\n expect (reduce) %A\n prods=%A\n non terminals: %A" - ctxt.StateStack - ctxt.CurrentToken - (List.map Parser.tokenTagToTokenId ctxt.ShiftTokens) - (List.map Parser.tokenTagToTokenId ctxt.ReduceTokens) - ctxt.ReducibleProductions - (List.mapSquared Parser.prodIdxToNonTerminal ctxt.ReducibleProductions) - *) - - | RuntimeCoercionSourceSealed(denv, ty, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - if isTyparTy denv.g ty - then os.Append(RuntimeCoercionSourceSealed1E().Format (NicePrint.stringOfTy denv ty)) |> ignore - else os.Append(RuntimeCoercionSourceSealed2E().Format (NicePrint.stringOfTy denv ty)) |> ignore - - | CoercionTargetSealed(denv, ty, _) -> - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let ty, _cxs= PrettyTypes.PrettifyType denv.g ty - os.Append(CoercionTargetSealedE().Format (NicePrint.stringOfTy denv ty)) |> ignore - - | UpcastUnnecessary(_) -> - os.Append(UpcastUnnecessaryE().Format) |> ignore - - | TypeTestUnnecessary(_) -> - os.Append(TypeTestUnnecessaryE().Format) |> ignore - - | QuotationTranslator.IgnoringPartOfQuotedTermWarning (msg, _) -> - Printf.bprintf os "%s" msg - - | OverrideDoesntOverride(denv, impl, minfoVirtOpt, g, amap, m) -> - let sig1 = DispatchSlotChecking.FormatOverride denv impl - match minfoVirtOpt with - | None -> - os.Append(OverrideDoesntOverride1E().Format sig1) |> ignore - | Some minfoVirt -> - // https://github.com/Microsoft/visualfsharp/issues/35 - // Improve error message when attempting to override generic return type with unit: - // we need to check if unit was used as a type argument - let rec hasUnitTType_app (types: TType list) = - match types with - | TType_app (maybeUnit, []) :: ts -> - match maybeUnit.TypeAbbrev with - | Some ttype when Tastops.isUnitTy g ttype -> true - | _ -> hasUnitTType_app ts - | _ :: ts -> hasUnitTType_app ts - | [] -> false - - match minfoVirt.ApparentEnclosingType with - | TType_app (t, types) when t.IsFSharpInterfaceTycon && hasUnitTType_app types -> - // match abstract member with 'unit' passed as generic argument - os.Append(OverrideDoesntOverride4E().Format sig1) |> ignore - | _ -> - os.Append(OverrideDoesntOverride2E().Format sig1) |> ignore - let sig2 = DispatchSlotChecking.FormatMethInfoSig g amap m denv minfoVirt - if sig1 <> sig2 then - os.Append(OverrideDoesntOverride3E().Format sig2) |> ignore - - | UnionCaseWrongArguments (_, n1, n2, _) -> - os.Append(UnionCaseWrongArgumentsE().Format n2 n1) |> ignore - - | UnionPatternsBindDifferentNames _ -> - os.Append(UnionPatternsBindDifferentNamesE().Format) |> ignore - - | ValueNotContained (denv, mref, implVal, sigVal, f) -> - let text1, text2 = NicePrint.minimalStringsOfTwoValues denv implVal sigVal - os.Append(f((fullDisplayTextOfModRef mref), text1, text2)) |> ignore - - | ConstrNotContained (denv, v1, v2, f) -> - os.Append(f((NicePrint.stringOfUnionCase denv v1), (NicePrint.stringOfUnionCase denv v2))) |> ignore - - | ExnconstrNotContained (denv, v1, v2, f) -> - os.Append(f((NicePrint.stringOfExnDef denv v1), (NicePrint.stringOfExnDef denv v2))) |> ignore - - | FieldNotContained (denv, v1, v2, f) -> - os.Append(f((NicePrint.stringOfRecdField denv v1), (NicePrint.stringOfRecdField denv v2))) |> ignore - - | RequiredButNotSpecified (_, mref, k, name, _) -> - let nsb = new System.Text.StringBuilder() - name nsb; - os.Append(RequiredButNotSpecifiedE().Format (fullDisplayTextOfModRef mref) k (nsb.ToString())) |> ignore - - | UseOfAddressOfOperator _ -> - os.Append(UseOfAddressOfOperatorE().Format) |> ignore - - | DefensiveCopyWarning(s, _) -> os.Append(DefensiveCopyWarningE().Format s) |> ignore - - | DeprecatedThreadStaticBindingWarning(_) -> - os.Append(DeprecatedThreadStaticBindingWarningE().Format) |> ignore - - | FunctionValueUnexpected (denv, ty, _) -> - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - let errorText = FunctionValueUnexpectedE().Format (NicePrint.stringOfTy denv ty) - os.Append errorText |> ignore - - | UnitTypeExpected (denv, ty, _) -> - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - let warningText = UnitTypeExpectedE().Format (NicePrint.stringOfTy denv ty) - os.Append warningText |> ignore - - | UnitTypeExpectedWithEquality (denv, ty, _) -> - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - let warningText = UnitTypeExpectedWithEqualityE().Format (NicePrint.stringOfTy denv ty) - os.Append warningText |> ignore - - | UnitTypeExpectedWithPossiblePropertySetter (denv, ty, bindingName, propertyName, _) -> - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - let warningText = UnitTypeExpectedWithPossiblePropertySetterE().Format (NicePrint.stringOfTy denv ty) bindingName propertyName - os.Append warningText |> ignore - - | UnitTypeExpectedWithPossibleAssignment (denv, ty, isAlreadyMutable, bindingName, _) -> - let ty, _cxs = PrettyTypes.PrettifyType denv.g ty - let warningText = - if isAlreadyMutable then - UnitTypeExpectedWithPossibleAssignmentToMutableE().Format (NicePrint.stringOfTy denv ty) bindingName - else - UnitTypeExpectedWithPossibleAssignmentE().Format (NicePrint.stringOfTy denv ty) bindingName - os.Append warningText |> ignore - - | RecursiveUseCheckedAtRuntime _ -> - os.Append(RecursiveUseCheckedAtRuntimeE().Format) |> ignore - - | LetRecUnsound (_, [v], _) -> - os.Append(LetRecUnsound1E().Format v.DisplayName) |> ignore - - | LetRecUnsound (_, path, _) -> - let bos = new System.Text.StringBuilder() - (path.Tail @ [path.Head]) |> List.iter (fun (v: ValRef) -> bos.Append(LetRecUnsoundInnerE().Format v.DisplayName) |> ignore) - os.Append(LetRecUnsound2E().Format (List.head path).DisplayName (bos.ToString())) |> ignore - - | LetRecEvaluatedOutOfOrder (_, _, _, _) -> - os.Append(LetRecEvaluatedOutOfOrderE().Format) |> ignore - - | LetRecCheckedAtRuntime _ -> - os.Append(LetRecCheckedAtRuntimeE().Format) |> ignore - - | SelfRefObjCtor(false, _) -> - os.Append(SelfRefObjCtor1E().Format) |> ignore - - | SelfRefObjCtor(true, _) -> - os.Append(SelfRefObjCtor2E().Format) |> ignore - - | VirtualAugmentationOnNullValuedType(_) -> - os.Append(VirtualAugmentationOnNullValuedTypeE().Format) |> ignore - - | NonVirtualAugmentationOnNullValuedType(_) -> - os.Append(NonVirtualAugmentationOnNullValuedTypeE().Format) |> ignore - - | NonUniqueInferredAbstractSlot(_, denv, bindnm, bvirt1, bvirt2, _) -> - os.Append(NonUniqueInferredAbstractSlot1E().Format bindnm) |> ignore - let ty1 = bvirt1.ApparentEnclosingType - let ty2 = bvirt2.ApparentEnclosingType - // REVIEW: consider if we need to show _cxs (the type parameter constraints) - let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 - os.Append(NonUniqueInferredAbstractSlot2E().Format) |> ignore - if t1 <> t2 then - os.Append(NonUniqueInferredAbstractSlot3E().Format t1 t2) |> ignore - os.Append(NonUniqueInferredAbstractSlot4E().Format) |> ignore - - | Error ((_, s), _) -> os.Append s |> ignore - - | ErrorWithSuggestions ((_, s), _, idText, suggestionF) -> - os.Append(DecompileOpName s) |> ignore - suggestNames suggestionF idText - - | NumberedError ((_, s), _) -> os.Append s |> ignore - - | InternalError (s, _) - - | InvalidArgument s - - | Failure s as exn -> - ignore exn // use the argument, even in non DEBUG - let f1 = SR.GetString("Failure1") - let f2 = SR.GetString("Failure2") - match s with - | f when f = f1 -> os.Append(Failure3E().Format s) |> ignore - | f when f = f2 -> os.Append(Failure3E().Format s) |> ignore - | _ -> os.Append(Failure4E().Format s) |> ignore -#if DEBUG - Printf.bprintf os "\nStack Trace\n%s\n" (exn.ToString()) - if !showAssertForUnexpectedException then - System.Diagnostics.Debug.Assert(false, sprintf "Unexpected exception seen in compiler: %s\n%s" s (exn.ToString())) -#endif - - | FullAbstraction(s, _) -> os.Append(FullAbstractionE().Format s) |> ignore - - | WrappedError (exn, _) -> OutputExceptionR os exn - - | PatternMatchCompilation.MatchIncomplete (isComp, cexOpt, _) -> - os.Append(MatchIncomplete1E().Format) |> ignore - match cexOpt with - | None -> () - | Some (cex, false) -> os.Append(MatchIncomplete2E().Format cex) |> ignore - | Some (cex, true) -> os.Append(MatchIncomplete3E().Format cex) |> ignore - if isComp then - os.Append(MatchIncomplete4E().Format) |> ignore - - | PatternMatchCompilation.EnumMatchIncomplete (isComp, cexOpt, _) -> - os.Append(EnumMatchIncomplete1E().Format) |> ignore - match cexOpt with - | None -> () - | Some (cex, false) -> os.Append(MatchIncomplete2E().Format cex) |> ignore - | Some (cex, true) -> os.Append(MatchIncomplete3E().Format cex) |> ignore - if isComp then - os.Append(MatchIncomplete4E().Format) |> ignore - - | PatternMatchCompilation.RuleNeverMatched _ -> os.Append(RuleNeverMatchedE().Format) |> ignore - - | ValNotMutable(_, valRef, _) -> os.Append(ValNotMutableE().Format(valRef.DisplayName)) |> ignore - - | ValNotLocal _ -> os.Append(ValNotLocalE().Format) |> ignore - - | ObsoleteError (s, _) - - | ObsoleteWarning (s, _) -> - os.Append(Obsolete1E().Format) |> ignore - if s <> "" then os.Append(Obsolete2E().Format s) |> ignore - - | Experimental (s, _) -> os.Append(ExperimentalE().Format s) |> ignore - - | PossibleUnverifiableCode _ -> os.Append(PossibleUnverifiableCodeE().Format) |> ignore - - | UserCompilerMessage (msg, _, _) -> os.Append msg |> ignore - - | Deprecated(s, _) -> os.Append(DeprecatedE().Format s) |> ignore - - | LibraryUseOnly(_) -> os.Append(LibraryUseOnlyE().Format) |> ignore - - | MissingFields(sl, _) -> os.Append(MissingFieldsE().Format (String.concat "," sl + ".")) |> ignore - - | ValueRestriction(denv, hassig, v, _, _) -> - let denv = { denv with showImperativeTyparAnnotations=true } - let tau = v.TauType - if hassig then - if isFunTy denv.g tau && (arityOfVal v).HasNoArgs then - os.Append(ValueRestriction1E().Format - v.DisplayName - (NicePrint.stringOfQualifiedValOrMember denv v) - v.DisplayName) |> ignore - else - os.Append(ValueRestriction2E().Format - v.DisplayName - (NicePrint.stringOfQualifiedValOrMember denv v) - v.DisplayName) |> ignore - else - match v.MemberInfo with - | Some membInfo when - begin match membInfo.MemberFlags.MemberKind with - | MemberKind.PropertyGet - | MemberKind.PropertySet - | MemberKind.Constructor -> true (* can't infer extra polymorphism *) - | _ -> false (* can infer extra polymorphism *) - end -> - os.Append(ValueRestriction3E().Format (NicePrint.stringOfQualifiedValOrMember denv v)) |> ignore - | _ -> - if isFunTy denv.g tau && (arityOfVal v).HasNoArgs then - os.Append(ValueRestriction4E().Format - v.DisplayName - (NicePrint.stringOfQualifiedValOrMember denv v) - v.DisplayName) |> ignore - else - os.Append(ValueRestriction5E().Format - v.DisplayName - (NicePrint.stringOfQualifiedValOrMember denv v) - v.DisplayName) |> ignore - - - | Parsing.RecoverableParseError -> os.Append(RecoverableParseErrorE().Format) |> ignore - - | ReservedKeyword (s, _) -> os.Append(ReservedKeywordE().Format s) |> ignore - - | IndentationProblem (s, _) -> os.Append(IndentationProblemE().Format s) |> ignore - - | OverrideInIntrinsicAugmentation(_) -> os.Append(OverrideInIntrinsicAugmentationE().Format) |> ignore - - | OverrideInExtrinsicAugmentation(_) -> os.Append(OverrideInExtrinsicAugmentationE().Format) |> ignore - - | IntfImplInIntrinsicAugmentation(_) -> os.Append(IntfImplInIntrinsicAugmentationE().Format) |> ignore - - | IntfImplInExtrinsicAugmentation(_) -> os.Append(IntfImplInExtrinsicAugmentationE().Format) |> ignore - - | UnresolvedReferenceError(assemblyName, _) - - | UnresolvedReferenceNoRange assemblyName -> - os.Append(UnresolvedReferenceNoRangeE().Format assemblyName) |> ignore - - | UnresolvedPathReference(assemblyName, pathname, _) - - | UnresolvedPathReferenceNoRange(assemblyName, pathname) -> - os.Append(UnresolvedPathReferenceNoRangeE().Format pathname assemblyName) |> ignore - - | DeprecatedCommandLineOptionFull(fullText, _) -> - os.Append fullText |> ignore - - | DeprecatedCommandLineOptionForHtmlDoc(optionName, _) -> - os.Append(FSComp.SR.optsDCLOHtmlDoc optionName) |> ignore - - | DeprecatedCommandLineOptionSuggestAlternative(optionName, altOption, _) -> - os.Append(FSComp.SR.optsDCLODeprecatedSuggestAlternative(optionName, altOption)) |> ignore - - | InternalCommandLineOption(optionName, _) -> - os.Append(FSComp.SR.optsInternalNoDescription optionName) |> ignore - - | DeprecatedCommandLineOptionNoDescription(optionName, _) -> - os.Append(FSComp.SR.optsDCLONoDescription optionName) |> ignore - - | HashIncludeNotAllowedInNonScript(_) -> - os.Append(HashIncludeNotAllowedInNonScriptE().Format) |> ignore - - | HashReferenceNotAllowedInNonScript(_) -> - os.Append(HashReferenceNotAllowedInNonScriptE().Format) |> ignore - - | HashDirectiveNotAllowedInNonScript(_) -> - os.Append(HashDirectiveNotAllowedInNonScriptE().Format) |> ignore - - | FileNameNotResolved(filename, locations, _) -> - os.Append(FileNameNotResolvedE().Format filename locations) |> ignore - - | AssemblyNotResolved(originalName, _) -> - os.Append(AssemblyNotResolvedE().Format originalName) |> ignore - - | IllegalFileNameChar(fileName, invalidChar) -> - os.Append(FSComp.SR.buildUnexpectedFileNameCharacter(fileName, string invalidChar)|>snd) |> ignore - - | HashLoadedSourceHasIssues(warnings, errors, _) -> - let Emit(l: exn list) = - OutputExceptionR os (List.head l) - if errors=[] then - os.Append(HashLoadedSourceHasIssues1E().Format) |> ignore - Emit warnings - else - os.Append(HashLoadedSourceHasIssues2E().Format) |> ignore - Emit errors - - | HashLoadedScriptConsideredSource(_) -> - os.Append(HashLoadedScriptConsideredSourceE().Format) |> ignore - - | InvalidInternalsVisibleToAssemblyName(badName, fileNameOption) -> - match fileNameOption with - | Some file -> os.Append(InvalidInternalsVisibleToAssemblyName1E().Format badName file) |> ignore - | None -> os.Append(InvalidInternalsVisibleToAssemblyName2E().Format badName) |> ignore - - | LoadedSourceNotFoundIgnoring(filename, _) -> - os.Append(LoadedSourceNotFoundIgnoringE().Format filename) |> ignore - - | MSBuildReferenceResolutionWarning(code, message, _) - - | MSBuildReferenceResolutionError(code, message, _) -> - os.Append(MSBuildReferenceResolutionErrorE().Format message code) |> ignore - - // Strip TargetInvocationException wrappers - | :? System.Reflection.TargetInvocationException as e -> - OutputExceptionR os e.InnerException - - | :? FileNotFoundException as e -> Printf.bprintf os "%s" e.Message - - | :? DirectoryNotFoundException as e -> Printf.bprintf os "%s" e.Message - - | :? System.ArgumentException as e -> Printf.bprintf os "%s" e.Message - - | :? System.NotSupportedException as e -> Printf.bprintf os "%s" e.Message - - | :? IOException as e -> Printf.bprintf os "%s" e.Message - - | :? System.UnauthorizedAccessException as e -> Printf.bprintf os "%s" e.Message - - | e -> - os.Append(TargetInvocationExceptionWrapperE().Format e.Message) |> ignore -#if DEBUG - Printf.bprintf os "\nStack Trace\n%s\n" (e.ToString()) - if !showAssertForUnexpectedException then - System.Diagnostics.Debug.Assert(false, sprintf "Unknown exception seen in compiler: %s" (e.ToString())) -#endif - - OutputExceptionR os err.Exception - - -// remove any newlines and tabs -let OutputPhasedDiagnostic (os: System.Text.StringBuilder) (err: PhasedDiagnostic) (flattenErrors: bool) (canSuggestNames: bool) = - let buf = new System.Text.StringBuilder() - - OutputPhasedErrorR buf err canSuggestNames - let s = if flattenErrors then ErrorLogger.NormalizeErrorString (buf.ToString()) else buf.ToString() - - os.Append s |> ignore - -let SanitizeFileName fileName implicitIncludeDir = - // The assert below is almost ok, but it fires in two cases: - // - fsi.exe sometimes passes "stdin" as a dummy filename - // - if you have a #line directive, e.g. - // # 1000 "Line01.fs" - // then it also asserts. But these are edge cases that can be fixed later, e.g. in bug 4651. - //System.Diagnostics.Debug.Assert(FileSystem.IsPathRootedShim fileName, sprintf "filename should be absolute: '%s'" fileName) - try - let fullPath = FileSystem.GetFullPathShim fileName - let currentDir = implicitIncludeDir - - // if the file name is not rooted in the current directory, return the full path - if not(fullPath.StartsWithOrdinal currentDir) then - fullPath - // if the file name is rooted in the current directory, return the relative path - else - fullPath.Replace(currentDir+"\\", "") - with _ -> - fileName - -[] -type DiagnosticLocation = - { Range: range - File: string - TextRepresentation: string - IsEmpty: bool } - -[] -type DiagnosticCanonicalInformation = - { ErrorNumber: int - Subcategory: string - TextRepresentation: string } - -[] -type DiagnosticDetailedInfo = - { Location: DiagnosticLocation option - Canonical: DiagnosticCanonicalInformation - Message: string } - -[] -type Diagnostic = - | Short of bool * string - | Long of bool * DiagnosticDetailedInfo - -/// returns sequence that contains Diagnostic for the given error + Diagnostic for all related errors -let CollectDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, isError, err: PhasedDiagnostic, canSuggestNames: bool) = - let outputWhere (showFullPaths, errorStyle) m: DiagnosticLocation = - if Range.equals m rangeStartup || Range.equals m rangeCmdArgs then - { Range = m; TextRepresentation = ""; IsEmpty = true; File = "" } - else - let file = m.FileName - let file = if showFullPaths then - Filename.fullpath implicitIncludeDir file - else - SanitizeFileName file implicitIncludeDir - let text, m, file = - match errorStyle with - | ErrorStyle.EmacsErrors -> - let file = file.Replace("\\", "/") - (sprintf "File \"%s\", line %d, characters %d-%d: " file m.StartLine m.StartColumn m.EndColumn), m, file - - // We're adjusting the columns here to be 1-based - both for parity with C# and for MSBuild, which assumes 1-based columns for error output - | ErrorStyle.DefaultErrors -> - let file = file.Replace('/', System.IO.Path.DirectorySeparatorChar) - let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) m.End - (sprintf "%s(%d,%d): " file m.StartLine m.StartColumn), m, file - - // We may also want to change TestErrors to be 1-based - | ErrorStyle.TestErrors -> - let file = file.Replace("/", "\\") - let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) - sprintf "%s(%d,%d-%d,%d): " file m.StartLine m.StartColumn m.EndLine m.EndColumn, m, file - - | ErrorStyle.GccErrors -> - let file = file.Replace('/', System.IO.Path.DirectorySeparatorChar) - let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) - sprintf "%s:%d:%d: " file m.StartLine m.StartColumn, m, file - - // Here, we want the complete range information so Project Systems can generate proper squiggles - | ErrorStyle.VSErrors -> - // Show prefix only for real files. Otherwise, we just want a truncated error like: - // parse error FS0031: blah blah - if not (Range.equals m range0) && not (Range.equals m rangeStartup) && not (Range.equals m rangeCmdArgs) then - let file = file.Replace("/", "\\") - let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) - sprintf "%s(%d,%d,%d,%d): " file m.StartLine m.StartColumn m.EndLine m.EndColumn, m, file - else - "", m, file - { Range = m; TextRepresentation = text; IsEmpty = false; File = file } - - match err.Exception with - | ReportedError _ -> - assert ("" = "Unexpected ReportedError") // this should never happen - Seq.empty - | StopProcessing -> - assert ("" = "Unexpected StopProcessing") // this should never happen - Seq.empty - | _ -> - let errors = ResizeArray() - let report err = - let OutputWhere err = - match GetRangeOfDiagnostic err with - | Some m -> Some(outputWhere (showFullPaths, errorStyle) m) - | None -> None - - let OutputCanonicalInformation(subcategory, errorNumber) : DiagnosticCanonicalInformation = - let text = - match errorStyle with - // Show the subcategory for --vserrors so that we can fish it out in Visual Studio and use it to determine error stickiness. - | ErrorStyle.VSErrors -> sprintf "%s %s FS%04d: " subcategory (if isError then "error" else "warning") errorNumber - | _ -> sprintf "%s FS%04d: " (if isError then "error" else "warning") errorNumber - { ErrorNumber = errorNumber; Subcategory = subcategory; TextRepresentation = text} - - let mainError, relatedErrors = SplitRelatedDiagnostics err - let where = OutputWhere mainError - let canonical = OutputCanonicalInformation(err.Subcategory(), GetDiagnosticNumber mainError) - let message = - let os = System.Text.StringBuilder() - OutputPhasedDiagnostic os mainError flattenErrors canSuggestNames - os.ToString() - - let entry: DiagnosticDetailedInfo = { Location = where; Canonical = canonical; Message = message } - - errors.Add ( Diagnostic.Long(isError, entry ) ) - - let OutputRelatedError(err: PhasedDiagnostic) = - match errorStyle with - // Give a canonical string when --vserror. - | ErrorStyle.VSErrors -> - let relWhere = OutputWhere mainError // mainError? - let relCanonical = OutputCanonicalInformation(err.Subcategory(), GetDiagnosticNumber mainError) // Use main error for code - let relMessage = - let os = System.Text.StringBuilder() - OutputPhasedDiagnostic os err flattenErrors canSuggestNames - os.ToString() - - let entry: DiagnosticDetailedInfo = { Location = relWhere; Canonical = relCanonical; Message = relMessage} - errors.Add( Diagnostic.Long (isError, entry) ) - - | _ -> - let os = System.Text.StringBuilder() - OutputPhasedDiagnostic os err flattenErrors canSuggestNames - errors.Add( Diagnostic.Short(isError, os.ToString()) ) - - relatedErrors |> List.iter OutputRelatedError - - match err with -#if !NO_EXTENSIONTYPING - | {Exception = (:? TypeProviderError as tpe)} -> - tpe.Iter (fun e -> - let newErr = {err with Exception = e} - report newErr - ) -#endif - | x -> report x - - errors:> seq<_> - -/// used by fsc.exe and fsi.exe, but not by VS -/// prints error and related errors to the specified StringBuilder -let rec OutputDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, isError) os (err: PhasedDiagnostic) = - - // 'true' for "canSuggestNames" is passed last here because we want to report suggestions in fsc.exe and fsi.exe, just not in regular IDE usage. - let errors = CollectDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, isError, err, true) - for e in errors do - Printf.bprintf os "\n" - match e with - | Diagnostic.Short(_, txt) -> - os.Append txt |> ignore - | Diagnostic.Long(_, details) -> - match details.Location with - | Some l when not l.IsEmpty -> os.Append l.TextRepresentation |> ignore - | _ -> () - os.Append( details.Canonical.TextRepresentation ) |> ignore - os.Append( details.Message ) |> ignore - -let OutputDiagnosticContext prefix fileLineFn os err = - match GetRangeOfDiagnostic err with - | None -> () - | Some m -> - let filename = m.FileName - let lineA = m.StartLine - let lineB = m.EndLine - let line = fileLineFn filename lineA - if line<>"" then - let iA = m.StartColumn - let iB = m.EndColumn - let iLen = if lineA = lineB then max (iB - iA) 1 else 1 - Printf.bprintf os "%s%s\n" prefix line - Printf.bprintf os "%s%s%s\n" prefix (String.make iA '-') (String.make iLen '^') - -let (++) x s = x @ [s] - -//-------------------------------------------------------------------------- -// General file name resolver -//-------------------------------------------------------------------------- - -/// Will return None if the filename is not found. -let TryResolveFileUsingPaths(paths, m, name) = - let () = - try FileSystem.IsPathRootedShim name |> ignore - with :? System.ArgumentException as e -> error(Error(FSComp.SR.buildProblemWithFilename(name, e.Message), m)) - if FileSystem.IsPathRootedShim name && FileSystem.SafeExists name - then Some name - else - let res = paths |> List.tryPick (fun path -> - let n = Path.Combine (path, name) - if FileSystem.SafeExists n then Some n - else None) - res - -/// Will raise FileNameNotResolved if the filename was not found -let ResolveFileUsingPaths(paths, m, name) = - match TryResolveFileUsingPaths(paths, m, name) with - | Some res -> res - | None -> - let searchMessage = String.concat "\n " paths - raise (FileNameNotResolved(name, searchMessage, m)) - -let GetWarningNumber(m, s: string) = - try - // Okay so ... - // #pragma strips FS of the #pragma "FS0004" and validates the warning number - // therefore if we have warning id that starts with a numeric digit we convert it to Some (int32) - // anything else is ignored None - if Char.IsDigit(s.[0]) then Some (int32 s) - elif s.StartsWithOrdinal("FS") = true then raise (new ArgumentException()) - else None - with err -> - warning(Error(FSComp.SR.buildInvalidWarningNumber s, m)) - None - -let ComputeMakePathAbsolute implicitIncludeDir (path: string) = - try - // remove any quotation marks from the path first - let path = path.Replace("\"", "") - if not (FileSystem.IsPathRootedShim path) - then Path.Combine (implicitIncludeDir, path) - else path - with - :? System.ArgumentException -> path - -//---------------------------------------------------------------------------- -// Configuration -//---------------------------------------------------------------------------- - -[] -type CompilerTarget = - | WinExe - | ConsoleExe - | Dll - | Module - member x.IsExe = (match x with ConsoleExe | WinExe -> true | _ -> false) - -[] -type ResolveAssemblyReferenceMode = Speculative | ReportErrors - -[] -type CopyFSharpCoreFlag = Yes | No - -/// Represents the file or string used for the --version flag -type VersionFlag = - | VersionString of string - | VersionFile of string - | VersionNone - member x.GetVersionInfo implicitIncludeDir = - let vstr = x.GetVersionString implicitIncludeDir - try - IL.parseILVersion vstr - with _ -> errorR(Error(FSComp.SR.buildInvalidVersionString vstr, rangeStartup)); IL.parseILVersion "0.0.0.0" - - member x.GetVersionString implicitIncludeDir = - match x with - | VersionString s -> s - | VersionFile s -> - let s = if FileSystem.IsPathRootedShim s then s else Path.Combine(implicitIncludeDir, s) - if not(FileSystem.SafeExists s) then - errorR(Error(FSComp.SR.buildInvalidVersionFile s, rangeStartup)); "0.0.0.0" - else - use is = System.IO.File.OpenText s - is.ReadLine() - | VersionNone -> "0.0.0.0" - - -/// Represents a reference to an assembly. May be backed by a real assembly on disk, or a cross-project -/// reference backed by information generated by the the compiler service. -type IRawFSharpAssemblyData = - /// The raw list AutoOpenAttribute attributes in the assembly - abstract GetAutoOpenAttributes: ILGlobals -> string list - /// The raw list InternalsVisibleToAttribute attributes in the assembly - abstract GetInternalsVisibleToAttributes: ILGlobals -> string list - /// The raw IL module definition in the assembly, if any. This is not present for cross-project references - /// in the language service - abstract TryGetILModuleDef: unit -> ILModuleDef option - /// The raw F# signature data in the assembly, if any - abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list - /// The raw F# optimization data in the assembly, if any - abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list - /// The table of type forwarders in the assembly - abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders - /// The identity of the module - abstract ILScopeRef: ILScopeRef - abstract ILAssemblyRefs: ILAssemblyRef list - abstract ShortAssemblyName: string - abstract HasAnyFSharpSignatureDataAttribute: bool - abstract HasMatchingFSharpSignatureDataAttribute: ILGlobals -> bool - -/// Cache of time stamps as we traverse a project description -type TimeStampCache(defaultTimeStamp: DateTime) = - let files = Dictionary() - let projects = Dictionary(HashIdentity.Reference) - member cache.GetFileTimeStamp fileName = - let ok, v = files.TryGetValue fileName - if ok then v else - let v = - try - FileSystem.GetLastWriteTimeShim fileName - with - | :? FileNotFoundException -> - defaultTimeStamp - files.[fileName] <- v - v - - member cache.GetProjectReferenceTimeStamp (pr: IProjectReference, ctok) = - let ok, v = projects.TryGetValue pr - if ok then v else - let v = defaultArg (pr.TryGetLogicalTimeStamp (cache, ctok)) defaultTimeStamp - projects.[pr] <- v - v - -and IProjectReference = - /// The name of the assembly file generated by the project - abstract FileName: string - - /// Evaluate raw contents of the assembly file generated by the project - abstract EvaluateRawContents: CompilationThreadToken -> Cancellable - - /// Get the logical timestamp that would be the timestamp of the assembly file generated by the project - /// - /// For project references this is maximum of the timestamps of all dependent files. - /// The project is not actually built, nor are any assemblies read, but the timestamps for each dependent file - /// are read via the FileSystem. If the files don't exist, then a default timestamp is used. - /// - /// The operation returns None only if it is not possible to create an IncrementalBuilder for the project at all, e.g. if there - /// are fatal errors in the options for the project. - abstract TryGetLogicalTimeStamp: TimeStampCache * CompilationThreadToken -> System.DateTime option - -type AssemblyReference = - | AssemblyReference of range * string * IProjectReference option - - member x.Range = (let (AssemblyReference(m, _, _)) = x in m) - - member x.Text = (let (AssemblyReference(_, text, _)) = x in text) - - member x.ProjectReference = (let (AssemblyReference(_, _, contents)) = x in contents) - - member x.SimpleAssemblyNameIs name = - (String.Compare(fileNameWithoutExtensionWithValidate false x.Text, name, StringComparison.OrdinalIgnoreCase) = 0) || - (let text = x.Text.ToLowerInvariant() - not (text.Contains "/") && not (text.Contains "\\") && not (text.Contains ".dll") && not (text.Contains ".exe") && - try let aname = System.Reflection.AssemblyName x.Text in aname.Name = name - with _ -> false) - - override x.ToString() = sprintf "AssemblyReference(%s)" x.Text - -type UnresolvedAssemblyReference = UnresolvedAssemblyReference of string * AssemblyReference list -#if !NO_EXTENSIONTYPING -type ResolvedExtensionReference = ResolvedExtensionReference of string * AssemblyReference list * Tainted list -#endif - -/// The thread in which compilation calls will be enqueued and done work on. -/// Note: This is currently only used when disposing of type providers and will be extended to all the other type provider calls when compilations can be done in parallel. -/// Right now all calls in FCS to type providers are single-threaded through use of the reactor thread. -type ICompilationThread = - - /// Enqueue work to be done on a compilation thread. - abstract EnqueueWork: (CompilationThreadToken -> unit) -> unit - -type ImportedBinary = - { FileName: string - RawMetadata: IRawFSharpAssemblyData -#if !NO_EXTENSIONTYPING - ProviderGeneratedAssembly: System.Reflection.Assembly option - IsProviderGenerated: bool - ProviderGeneratedStaticLinkMap: ProvidedAssemblyStaticLinkingMap option -#endif - ILAssemblyRefs: ILAssemblyRef list - ILScopeRef: ILScopeRef } - -type ImportedAssembly = - { ILScopeRef: ILScopeRef - FSharpViewOfMetadata: CcuThunk - AssemblyAutoOpenAttributes: string list - AssemblyInternalsVisibleToAttributes: string list -#if !NO_EXTENSIONTYPING - IsProviderGenerated: bool - mutable TypeProviders: Tainted list -#endif - FSharpOptimizationData: Microsoft.FSharp.Control.Lazy> } - -type AvailableImportedAssembly = - | ResolvedImportedAssembly of ImportedAssembly - | UnresolvedImportedAssembly of string - -type CcuLoadFailureAction = - | RaiseError - | ReturnNone - -[] -type TcConfigBuilder = - { mutable primaryAssembly: PrimaryAssembly - mutable noFeedback: bool - mutable stackReserveSize: int32 option - mutable implicitIncludeDir: string (* normally "." *) - mutable openDebugInformationForLaterStaticLinking: bool (* only for --standalone *) - defaultFSharpBinariesDir: string - mutable compilingFslib: bool - mutable useIncrementalBuilder: bool - mutable includes: string list - mutable implicitOpens: string list - mutable useFsiAuxLib: bool - mutable framework: bool - mutable resolutionEnvironment: ReferenceResolver.ResolutionEnvironment - mutable implicitlyResolveAssemblies: bool - mutable light: bool option - mutable conditionalCompilationDefines: string list - mutable loadedSources: (range * string * string) list - mutable compilerToolPaths: string list - mutable referencedDLLs: AssemblyReference list - mutable packageManagerLines: Map - mutable projectReferences: IProjectReference list - mutable knownUnresolvedReferences: UnresolvedAssemblyReference list - reduceMemoryUsage: ReduceMemoryFlag - mutable subsystemVersion: int * int - mutable useHighEntropyVA: bool - mutable inputCodePage: int option - mutable embedResources: string list - mutable errorSeverityOptions: FSharpErrorSeverityOptions - mutable mlCompatibility: bool - mutable checkOverflow: bool - mutable showReferenceResolutions: bool - mutable outputDir : string option - mutable outputFile: string option - mutable platform: ILPlatform option - mutable prefer32Bit: bool - mutable useSimpleResolution: bool - mutable target: CompilerTarget - mutable debuginfo: bool - mutable testFlagEmitFeeFeeAs100001: bool - mutable dumpDebugInfo: bool - mutable debugSymbolFile: string option - (* Backend configuration *) - mutable typeCheckOnly: bool - mutable parseOnly: bool - mutable importAllReferencesOnly: bool - mutable simulateException: string option - mutable printAst: bool - mutable tokenizeOnly: bool - mutable testInteractionParser: bool - mutable reportNumDecls: bool - mutable printSignature: bool - mutable printSignatureFile: string - mutable xmlDocOutputFile: string option - mutable stats: bool - mutable generateFilterBlocks: bool (* don't generate filter blocks due to bugs on Mono *) - - mutable signer: string option - mutable container: string option - - mutable delaysign: bool - mutable publicsign: bool - mutable version: VersionFlag - mutable metadataVersion: string option - mutable standalone: bool - mutable extraStaticLinkRoots: string list - mutable noSignatureData: bool - mutable onlyEssentialOptimizationData: bool - mutable useOptimizationDataFile: bool - mutable jitTracking: bool - mutable portablePDB: bool - mutable embeddedPDB: bool - mutable embedAllSource: bool - mutable embedSourceList: string list - mutable sourceLink: string - - mutable ignoreSymbolStoreSequencePoints: bool - mutable internConstantStrings: bool - mutable extraOptimizationIterations: int - - mutable win32res: string - mutable win32manifest: string - mutable includewin32manifest: bool - mutable linkResources: string list - mutable legacyReferenceResolver: ReferenceResolver.Resolver - - mutable showFullPaths: bool - mutable errorStyle: ErrorStyle - mutable utf8output: bool - mutable flatErrors: bool - - mutable maxErrors: int - mutable abortOnError: bool (* intended for fsi scripts that should exit on first error *) - mutable baseAddress: int32 option - mutable checksumAlgorithm: HashAlgorithm -#if DEBUG - mutable showOptimizationData: bool -#endif - mutable showTerms: bool (* show terms between passes? *) - mutable writeTermsToFiles: bool (* show terms to files? *) - mutable doDetuple: bool (* run detuple pass? *) - mutable doTLR: bool (* run TLR pass? *) - mutable doFinalSimplify: bool (* do final simplification pass *) - mutable optsOn: bool (* optimizations are turned on *) - mutable optSettings: Optimizer.OptimizationSettings - mutable emitTailcalls: bool - mutable deterministic: bool - mutable preferredUiLang: string option - mutable lcid: int option - mutable productNameForBannerText: string - /// show the MS (c) notice, e.g. with help or fsi? - mutable showBanner: bool - - /// show times between passes? - mutable showTimes: bool - mutable showLoadedAssemblies: bool - mutable continueAfterParseFailure: bool -#if !NO_EXTENSIONTYPING - /// show messages about extension type resolution? - mutable showExtensionTypeMessages: bool -#endif - mutable compilationThread: ICompilationThread - - /// pause between passes? - mutable pause: bool - /// whenever possible, emit callvirt instead of call - mutable alwaysCallVirt: bool - - /// if true, strip away data that would not be of use to end users, but is useful to us for debugging - // REVIEW: "stripDebugData"? - mutable noDebugData: bool - - /// if true, indicates all type checking and code generation is in the context of fsi.exe - isInteractive: bool - isInvalidationSupported: bool - - /// used to log sqm data - - /// if true - every expression in quotations will be augmented with full debug info (filename, location in file) - mutable emitDebugInfoInQuotations: bool - - mutable exename: string option - - // If true - the compiler will copy FSharp.Core.dll along the produced binaries - mutable copyFSharpCore: CopyFSharpCoreFlag - - /// When false FSI will lock referenced assemblies requiring process restart, false = disable Shadow Copy false (*default*) - mutable shadowCopyReferences: bool - mutable useSdkRefs: bool - - /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, - /// and from which we can read the metadata. Only used when metadataOnly=true. - mutable tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot - - mutable internalTestSpanStackReferring: bool - - mutable noConditionalErasure: bool - - mutable pathMap: PathMap - - mutable langVersion: LanguageVersion - - mutable includePathAdded: string -> unit - } - - static member Initial = - { - primaryAssembly = PrimaryAssembly.Mscorlib // default value, can be overridden using the command line switch - light = None - noFeedback = false - stackReserveSize = None - conditionalCompilationDefines = [] - implicitIncludeDir = String.Empty - openDebugInformationForLaterStaticLinking = false - defaultFSharpBinariesDir = String.Empty - compilingFslib = false - useIncrementalBuilder = false - useFsiAuxLib = false - implicitOpens = [] - includes = [] - resolutionEnvironment = ResolutionEnvironment.EditingOrCompilation false - framework = true - implicitlyResolveAssemblies = true - compilerToolPaths = [] - referencedDLLs = [] - packageManagerLines = Map.empty - projectReferences = [] - knownUnresolvedReferences = [] - loadedSources = [] - errorSeverityOptions = FSharpErrorSeverityOptions.Default - embedResources = [] - inputCodePage = None - reduceMemoryUsage = ReduceMemoryFlag.Yes // always gets set explicitly - subsystemVersion = 4, 0 // per spec for 357994 - useHighEntropyVA = false - mlCompatibility = false - checkOverflow = false - showReferenceResolutions = false - outputDir = None - outputFile = None - platform = None - prefer32Bit = false - useSimpleResolution = runningOnMono - target = CompilerTarget.ConsoleExe - debuginfo = false - testFlagEmitFeeFeeAs100001 = false - dumpDebugInfo = false - debugSymbolFile = None - - (* Backend configuration *) - typeCheckOnly = false - parseOnly = false - importAllReferencesOnly = false - simulateException = None - printAst = false - tokenizeOnly = false - testInteractionParser = false - reportNumDecls = false - printSignature = false - printSignatureFile = "" - xmlDocOutputFile = None - stats = false - generateFilterBlocks = false (* don't generate filter blocks *) - - signer = None - container = None - maxErrors = 100 - abortOnError = false - baseAddress = None - checksumAlgorithm = HashAlgorithm.Sha256 - - delaysign = false - publicsign = false - version = VersionNone - metadataVersion = None - standalone = false - extraStaticLinkRoots = [] - noSignatureData = false - onlyEssentialOptimizationData = false - useOptimizationDataFile = false - jitTracking = true - portablePDB = true - embeddedPDB = false - embedAllSource = false - embedSourceList = [] - sourceLink = "" - ignoreSymbolStoreSequencePoints = false - internConstantStrings = true - extraOptimizationIterations = 0 - - win32res = "" - win32manifest = "" - includewin32manifest = true - linkResources = [] - legacyReferenceResolver = null - showFullPaths = false - errorStyle = ErrorStyle.DefaultErrors - - utf8output = false - flatErrors = false - - #if DEBUG - showOptimizationData = false - #endif - showTerms = false - writeTermsToFiles = false - - doDetuple = false - doTLR = false - doFinalSimplify = false - optsOn = false - optSettings = Optimizer.OptimizationSettings.Defaults - emitTailcalls = true - deterministic = false - preferredUiLang = None - lcid = None - // See bug 6071 for product banner spec - productNameForBannerText = FSComp.SR.buildProductName(FSharpEnvironment.FSharpBannerVersion) - showBanner = true - showTimes = false - showLoadedAssemblies = false - continueAfterParseFailure = false -#if !NO_EXTENSIONTYPING - showExtensionTypeMessages = false -#endif - compilationThread = - let ctok = CompilationThreadToken () - { new ICompilationThread with member __.EnqueueWork work = work ctok } - pause = false - alwaysCallVirt = true - noDebugData = false - isInteractive = false - isInvalidationSupported = false - emitDebugInfoInQuotations = false - exename = None - copyFSharpCore = CopyFSharpCoreFlag.No - shadowCopyReferences = false - useSdkRefs = true - tryGetMetadataSnapshot = (fun _ -> None) - internalTestSpanStackReferring = false - noConditionalErasure = false - pathMap = PathMap.empty - langVersion = LanguageVersion("default") - includePathAdded = ignore - } - - static member CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, reduceMemoryUsage, implicitIncludeDir, - isInteractive, isInvalidationSupported, defaultCopyFSharpCore, tryGetMetadataSnapshot, ?includePathAdded: string -> unit) = - - Debug.Assert(FileSystem.IsPathRootedShim implicitIncludeDir, sprintf "implicitIncludeDir should be absolute: '%s'" implicitIncludeDir) - - if (String.IsNullOrEmpty defaultFSharpBinariesDir) then - failwith "Expected a valid defaultFSharpBinariesDir" - - let includePathAdded = defaultArg includePathAdded ignore - { TcConfigBuilder.Initial with - implicitIncludeDir = implicitIncludeDir - defaultFSharpBinariesDir = defaultFSharpBinariesDir - reduceMemoryUsage = reduceMemoryUsage - legacyReferenceResolver = legacyReferenceResolver - isInteractive = isInteractive - isInvalidationSupported = isInvalidationSupported - copyFSharpCore = defaultCopyFSharpCore - tryGetMetadataSnapshot = tryGetMetadataSnapshot - useFsiAuxLib = isInteractive - includePathAdded = includePathAdded - } - - member tcConfigB.ResolveSourceFile(m, nm, pathLoadedFrom) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - ResolveFileUsingPaths(tcConfigB.includes @ [pathLoadedFrom], m, nm) - - /// Decide names of output file, pdb and assembly - member tcConfigB.DecideNames (sourceFiles) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - if sourceFiles = [] then errorR(Error(FSComp.SR.buildNoInputsSpecified(), rangeCmdArgs)) - let ext() = match tcConfigB.target with CompilerTarget.Dll -> ".dll" | CompilerTarget.Module -> ".netmodule" | CompilerTarget.ConsoleExe | CompilerTarget.WinExe -> ".exe" - let implFiles = sourceFiles |> List.filter (fun lower -> List.exists (Filename.checkSuffix (String.lowercase lower)) FSharpImplFileSuffixes) - let outfile = - match tcConfigB.outputFile, List.rev implFiles with - | None, [] -> "out" + ext() - | None, h :: _ -> - let basic = fileNameOfPath h - let modname = try Filename.chopExtension basic with _ -> basic - modname+(ext()) - | Some f, _ -> f - let assemblyName = - let baseName = fileNameOfPath outfile - (fileNameWithoutExtension baseName) - - let pdbfile = - if tcConfigB.debuginfo then - Some (match tcConfigB.debugSymbolFile with - | None -> FSharp.Compiler.AbstractIL.ILPdbWriter.getDebugFileName outfile tcConfigB.portablePDB -#if ENABLE_MONO_SUPPORT - | Some _ when runningOnMono -> - // On Mono, the name of the debug file has to be ".mdb" so specifying it explicitly is an error - warning(Error(FSComp.SR.ilwriteMDBFileNameCannotBeChangedWarning(), rangeCmdArgs)) - FSharp.Compiler.AbstractIL.ILPdbWriter.getDebugFileName outfile tcConfigB.portablePDB -#endif - | Some f -> f) - elif (tcConfigB.debugSymbolFile <> None) && (not (tcConfigB.debuginfo)) then - error(Error(FSComp.SR.buildPdbRequiresDebug(), rangeStartup)) - else - None - tcConfigB.outputFile <- Some outfile - outfile, pdbfile, assemblyName - - member tcConfigB.TurnWarningOff(m, s: string) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - match GetWarningNumber(m, s) with - | None -> () - | Some n -> - // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus - if n = 62 then tcConfigB.mlCompatibility <- true - tcConfigB.errorSeverityOptions <- - { tcConfigB.errorSeverityOptions with WarnOff = ListSet.insert (=) n tcConfigB.errorSeverityOptions.WarnOff } - - member tcConfigB.TurnWarningOn(m, s: string) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - match GetWarningNumber(m, s) with - | None -> () - | Some n -> - // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus - if n = 62 then tcConfigB.mlCompatibility <- false - tcConfigB.errorSeverityOptions <- - { tcConfigB.errorSeverityOptions with WarnOn = ListSet.insert (=) n tcConfigB.errorSeverityOptions.WarnOn } - - member tcConfigB.AddIncludePath (m, path, pathIncludedFrom) = - let absolutePath = ComputeMakePathAbsolute pathIncludedFrom path - let ok = - let existsOpt = - try Some(Directory.Exists absolutePath) - with e -> warning(Error(FSComp.SR.buildInvalidSearchDirectory path, m)); None - match existsOpt with - | Some exists -> - if not exists then warning(Error(FSComp.SR.buildSearchDirectoryNotFound absolutePath, m)) - exists - | None -> false - if ok && not (List.contains absolutePath tcConfigB.includes) then - tcConfigB.includes <- tcConfigB.includes ++ absolutePath - tcConfigB.includePathAdded absolutePath - - member tcConfigB.AddLoadedSource(m, originalPath, pathLoadedFrom) = - if FileSystem.IsInvalidPathShim originalPath then - warning(Error(FSComp.SR.buildInvalidFilename originalPath, m)) - else - let path = - match TryResolveFileUsingPaths(tcConfigB.includes @ [pathLoadedFrom], m, originalPath) with - | Some path -> path - | None -> - // File doesn't exist in the paths. Assume it will be in the load-ed from directory. - ComputeMakePathAbsolute pathLoadedFrom originalPath - if not (List.contains path (List.map (fun (_, _, path) -> path) tcConfigB.loadedSources)) then - tcConfigB.loadedSources <- tcConfigB.loadedSources ++ (m, originalPath, path) - - - member tcConfigB.AddEmbeddedSourceFile (file) = - tcConfigB.embedSourceList <- tcConfigB.embedSourceList ++ file - - member tcConfigB.AddEmbeddedResource filename = - tcConfigB.embedResources <- tcConfigB.embedResources ++ filename - - member tcConfigB.AddCompilerToolsByPath (path) = - if not (tcConfigB.compilerToolPaths |> List.exists (fun text -> path = text)) then // NOTE: We keep same paths if range is different. - let compilerToolPath = tcConfigB.compilerToolPaths |> List.tryPick (fun text -> if text = path then Some text else None) - if compilerToolPath.IsNone then - tcConfigB.compilerToolPaths <- tcConfigB.compilerToolPaths ++ path - - member tcConfigB.AddReferencedAssemblyByPath (m, path) = - if FileSystem.IsInvalidPathShim path then - warning(Error(FSComp.SR.buildInvalidAssemblyName(path), m)) - elif not (tcConfigB.referencedDLLs |> List.exists (fun ar2 -> Range.equals m ar2.Range && path=ar2.Text)) then // NOTE: We keep same paths if range is different. - let projectReference = tcConfigB.projectReferences |> List.tryPick (fun pr -> if pr.FileName = path then Some pr else None) - tcConfigB.referencedDLLs <- tcConfigB.referencedDLLs ++ AssemblyReference(m, path, projectReference) - - member tcConfigB.AddDependencyManagerText (packageManager:DependencyManagerIntegration.IDependencyManagerProvider, m, path:string) = - let path = DependencyManagerIntegration.removeDependencyManagerKey packageManager.Key path - - match tcConfigB.packageManagerLines |> Map.tryFind packageManager.Key with - | Some lines -> tcConfigB.packageManagerLines <- Map.add packageManager.Key (lines ++ (false, path, m)) tcConfigB.packageManagerLines - | _ -> tcConfigB.packageManagerLines <- Map.add packageManager.Key [false, path, m] tcConfigB.packageManagerLines - - member tcConfigB.RemoveReferencedAssemblyByPath (m, path) = - tcConfigB.referencedDLLs <- tcConfigB.referencedDLLs |> List.filter (fun ar -> not (Range.equals ar.Range m) || ar.Text <> path) - - member tcConfigB.AddPathMapping (oldPrefix, newPrefix) = - tcConfigB.pathMap <- tcConfigB.pathMap |> PathMap.addMapping oldPrefix newPrefix - - static member SplitCommandLineResourceInfo (ri: string) = - let p = ri.IndexOf ',' - if p <> -1 then - let file = String.sub ri 0 p - let rest = String.sub ri (p+1) (String.length ri - p - 1) - let p = rest.IndexOf ',' - if p <> -1 then - let name = String.sub rest 0 p+".resources" - let pubpri = String.sub rest (p+1) (rest.Length - p - 1) - if pubpri = "public" then file, name, ILResourceAccess.Public - elif pubpri = "private" then file, name, ILResourceAccess.Private - else error(Error(FSComp.SR.buildInvalidPrivacy pubpri, rangeStartup)) - else - file, rest, ILResourceAccess.Public - else - ri, fileNameOfPath ri, ILResourceAccess.Public - - -let OpenILBinary(filename, reduceMemoryUsage, pdbDirPath, shadowCopyReferences, tryGetMetadataSnapshot) = - let opts: ILReaderOptions = - { metadataOnly = MetadataOnlyFlag.Yes - reduceMemoryUsage = reduceMemoryUsage - pdbDirPath = pdbDirPath - tryGetMetadataSnapshot = tryGetMetadataSnapshot } - - let location = -#if FX_NO_APP_DOMAINS - // In order to use memory mapped files on the shadow copied version of the Assembly, we `preload the assembly - // We swallow all exceptions so that we do not change the exception contract of this API - if shadowCopyReferences then - try - System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename).Location - with e -> filename - else -#else - ignore shadowCopyReferences -#endif - filename - AssemblyReader.GetILModuleReader(location, opts) - -#if DEBUG -[] -#endif -type AssemblyResolution = - { originalReference: AssemblyReference - resolvedPath: string - prepareToolTip: unit -> string - sysdir: bool - mutable ilAssemblyRef: ILAssemblyRef option - } - override this.ToString() = sprintf "%s%s" (if this.sysdir then "[sys]" else "") this.resolvedPath - - member this.ProjectReference = this.originalReference.ProjectReference - - /// Compute the ILAssemblyRef for a resolved assembly. This is done by reading the binary if necessary. The result - /// is cached. - /// - /// For project references in the language service, this would result in a build of the project. - /// This is because ``EvaluateRawContents ctok`` is used. However this path is only currently used - /// in fsi.fs, which does not use project references. - // - member this.GetILAssemblyRef(ctok, reduceMemoryUsage, tryGetMetadataSnapshot) = - cancellable { - match this.ilAssemblyRef with - | Some assemblyRef -> return assemblyRef - | None -> - let! assemblyRefOpt = - cancellable { - match this.ProjectReference with - | Some r -> - let! contents = r.EvaluateRawContents ctok - match contents with - | None -> return None - | Some contents -> - match contents.ILScopeRef with - | ILScopeRef.Assembly aref -> return Some aref - | _ -> return None - | None -> return None - } - let assemblyRef = - match assemblyRefOpt with - | Some aref -> aref - | None -> - let readerSettings: ILReaderOptions = - { pdbDirPath=None - reduceMemoryUsage = reduceMemoryUsage - metadataOnly = MetadataOnlyFlag.Yes - tryGetMetadataSnapshot = tryGetMetadataSnapshot } - use reader = OpenILModuleReader this.resolvedPath readerSettings - mkRefToILAssembly reader.ILModuleDef.ManifestOfAssembly - this.ilAssemblyRef <- Some assemblyRef - return assemblyRef - } - -//---------------------------------------------------------------------------- -// Names to match up refs and defs for assemblies and modules -//-------------------------------------------------------------------------- - -let GetNameOfILModule (m: ILModuleDef) = - match m.Manifest with - | Some manifest -> manifest.Name - | None -> m.Name - - -let MakeScopeRefForILModule (ilModule: ILModuleDef) = - match ilModule.Manifest with - | Some m -> ILScopeRef.Assembly (mkRefToILAssembly m) - | None -> ILScopeRef.Module (mkRefToILModule ilModule) - -let GetCustomAttributesOfILModule (ilModule: ILModuleDef) = - (match ilModule.Manifest with Some m -> m.CustomAttrs | None -> ilModule.CustomAttrs).AsList - -let GetAutoOpenAttributes ilg ilModule = - ilModule |> GetCustomAttributesOfILModule |> List.choose (TryFindAutoOpenAttr ilg) - -let GetInternalsVisibleToAttributes ilg ilModule = - ilModule |> GetCustomAttributesOfILModule |> List.choose (TryFindInternalsVisibleToAttr ilg) - -//---------------------------------------------------------------------------- -// TcConfig -//-------------------------------------------------------------------------- - -[] -/// This type is immutable and must be kept as such. Do not extract or mutate the underlying data except by cloning it. -type TcConfig private (data: TcConfigBuilder, validate: bool) = - - // Validate the inputs - this helps ensure errors in options are shown in visual studio rather than only when built - // However we only validate a minimal number of options at the moment - do if validate then try data.version.GetVersionInfo(data.implicitIncludeDir) |> ignore with e -> errorR e - - // clone the input builder to ensure nobody messes with it. - let data = { data with pause = data.pause } - - let computeKnownDllReference libraryName = - let defaultCoreLibraryReference = AssemblyReference(range0, libraryName+".dll", None) - let nameOfDll(r: AssemblyReference) = - let filename = ComputeMakePathAbsolute data.implicitIncludeDir r.Text - if FileSystem.SafeExists filename then - r, Some filename - else - // If the file doesn't exist, let reference resolution logic report the error later... - defaultCoreLibraryReference, if Range.equals r.Range rangeStartup then Some(filename) else None - match data.referencedDLLs |> List.filter (fun assemblyReference -> assemblyReference.SimpleAssemblyNameIs libraryName) with - | [] -> defaultCoreLibraryReference, None - | [r] - | r :: _ -> nameOfDll r - - // Look for an explicit reference to mscorlib/netstandard.dll or System.Runtime.dll and use that to compute clrRoot and targetFrameworkVersion - let primaryAssemblyReference, primaryAssemblyExplicitFilenameOpt = computeKnownDllReference(data.primaryAssembly.Name) - let fslibReference = - // Look for explicit FSharp.Core reference otherwise use version that was referenced by compiler - let dllReference, fileNameOpt = computeKnownDllReference getFSharpCoreLibraryName - match fileNameOpt with - | Some _ -> dllReference - | None -> AssemblyReference(range0, getDefaultFSharpCoreLocation, None) - - // clrRoot: the location of the primary assembly (mscorlib.dll or netstandard.dll or System.Runtime.dll) - // - // targetFrameworkVersionValue: Normally just HighestInstalledNetFrameworkVersion() - // - // Note, when mscorlib.dll has been given explicitly the actual value of - // targetFrameworkVersion shouldn't matter since resolution has already happened. - // In those cases where it does matter (e.g. --noframework is not being used or we are processing further - // resolutions for a script) then it is correct to just use HighestInstalledNetFrameworkVersion(). - let clrRootValue, targetFrameworkVersionValue = - match primaryAssemblyExplicitFilenameOpt with - | Some primaryAssemblyFilename -> - let filename = ComputeMakePathAbsolute data.implicitIncludeDir primaryAssemblyFilename - try - let clrRoot = Some(Path.GetDirectoryName(FileSystem.GetFullPathShim filename)) - clrRoot, data.legacyReferenceResolver.HighestInstalledNetFrameworkVersion() - with e -> - // We no longer expect the above to fail but leaving this just in case - error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), rangeStartup)) - | None -> -#if !ENABLE_MONO_SUPPORT - // TODO: we have to get msbuild out of this - if data.useSimpleResolution then - None, "" - else -#endif - None, data.legacyReferenceResolver.HighestInstalledNetFrameworkVersion() - - let systemAssemblies = systemAssemblies - - member x.primaryAssembly = data.primaryAssembly - member x.noFeedback = data.noFeedback - member x.stackReserveSize = data.stackReserveSize - member x.implicitIncludeDir = data.implicitIncludeDir - member x.openDebugInformationForLaterStaticLinking = data.openDebugInformationForLaterStaticLinking - member x.fsharpBinariesDir = data.defaultFSharpBinariesDir - member x.compilingFslib = data.compilingFslib - member x.useIncrementalBuilder = data.useIncrementalBuilder - member x.includes = data.includes - member x.implicitOpens = data.implicitOpens - member x.useFsiAuxLib = data.useFsiAuxLib - member x.framework = data.framework - member x.implicitlyResolveAssemblies = data.implicitlyResolveAssemblies - member x.resolutionEnvironment = data.resolutionEnvironment - member x.light = data.light - member x.conditionalCompilationDefines = data.conditionalCompilationDefines - member x.loadedSources = data.loadedSources - member x.compilerToolPaths = data.compilerToolPaths - member x.referencedDLLs = data.referencedDLLs - member x.knownUnresolvedReferences = data.knownUnresolvedReferences - member x.clrRoot = clrRootValue - member x.reduceMemoryUsage = data.reduceMemoryUsage - member x.subsystemVersion = data.subsystemVersion - member x.useHighEntropyVA = data.useHighEntropyVA - member x.inputCodePage = data.inputCodePage - member x.embedResources = data.embedResources - member x.errorSeverityOptions = data.errorSeverityOptions - member x.mlCompatibility = data.mlCompatibility - member x.checkOverflow = data.checkOverflow - member x.showReferenceResolutions = data.showReferenceResolutions - member x.outputDir = data.outputDir - member x.outputFile = data.outputFile - member x.platform = data.platform - member x.prefer32Bit = data.prefer32Bit - member x.useSimpleResolution = data.useSimpleResolution - member x.target = data.target - member x.debuginfo = data.debuginfo - member x.testFlagEmitFeeFeeAs100001 = data.testFlagEmitFeeFeeAs100001 - member x.dumpDebugInfo = data.dumpDebugInfo - member x.debugSymbolFile = data.debugSymbolFile - member x.typeCheckOnly = data.typeCheckOnly - member x.parseOnly = data.parseOnly - member x.importAllReferencesOnly = data.importAllReferencesOnly - member x.simulateException = data.simulateException - member x.printAst = data.printAst - member x.targetFrameworkVersion = targetFrameworkVersionValue - member x.tokenizeOnly = data.tokenizeOnly - member x.testInteractionParser = data.testInteractionParser - member x.reportNumDecls = data.reportNumDecls - member x.printSignature = data.printSignature - member x.printSignatureFile = data.printSignatureFile - member x.xmlDocOutputFile = data.xmlDocOutputFile - member x.stats = data.stats - member x.generateFilterBlocks = data.generateFilterBlocks - member x.signer = data.signer - member x.container = data.container - member x.delaysign = data.delaysign - member x.publicsign = data.publicsign - member x.version = data.version - member x.metadataVersion = data.metadataVersion - member x.standalone = data.standalone - member x.extraStaticLinkRoots = data.extraStaticLinkRoots - member x.noSignatureData = data.noSignatureData - member x.onlyEssentialOptimizationData = data.onlyEssentialOptimizationData - member x.useOptimizationDataFile = data.useOptimizationDataFile - member x.jitTracking = data.jitTracking - member x.portablePDB = data.portablePDB - member x.embeddedPDB = data.embeddedPDB - member x.embedAllSource = data.embedAllSource - member x.embedSourceList = data.embedSourceList - member x.sourceLink = data.sourceLink - member x.packageManagerLines = data.packageManagerLines - member x.ignoreSymbolStoreSequencePoints = data.ignoreSymbolStoreSequencePoints - member x.internConstantStrings = data.internConstantStrings - member x.extraOptimizationIterations = data.extraOptimizationIterations - member x.win32res = data.win32res - member x.win32manifest = data.win32manifest - member x.includewin32manifest = data.includewin32manifest - member x.linkResources = data.linkResources - member x.showFullPaths = data.showFullPaths - member x.errorStyle = data.errorStyle - member x.utf8output = data.utf8output - member x.flatErrors = data.flatErrors - member x.maxErrors = data.maxErrors - member x.baseAddress = data.baseAddress - member x.checksumAlgorithm = data.checksumAlgorithm - #if DEBUG - member x.showOptimizationData = data.showOptimizationData -#endif - member x.showTerms = data.showTerms - member x.writeTermsToFiles = data.writeTermsToFiles - member x.doDetuple = data.doDetuple - member x.doTLR = data.doTLR - member x.doFinalSimplify = data.doFinalSimplify - member x.optSettings = data.optSettings - member x.emitTailcalls = data.emitTailcalls - member x.deterministic = data.deterministic - member x.pathMap = data.pathMap - member x.langVersion = data.langVersion - member x.preferredUiLang = data.preferredUiLang - member x.lcid = data.lcid - member x.optsOn = data.optsOn - member x.productNameForBannerText = data.productNameForBannerText - member x.showBanner = data.showBanner - member x.showTimes = data.showTimes - member x.showLoadedAssemblies = data.showLoadedAssemblies - member x.continueAfterParseFailure = data.continueAfterParseFailure -#if !NO_EXTENSIONTYPING - member x.showExtensionTypeMessages = data.showExtensionTypeMessages -#endif - member x.compilationThread = data.compilationThread - member x.pause = data.pause - member x.alwaysCallVirt = data.alwaysCallVirt - member x.noDebugData = data.noDebugData - member x.isInteractive = data.isInteractive - member x.isInvalidationSupported = data.isInvalidationSupported - member x.emitDebugInfoInQuotations = data.emitDebugInfoInQuotations - member x.copyFSharpCore = data.copyFSharpCore - member x.shadowCopyReferences = data.shadowCopyReferences - member x.useSdkRefs = data.useSdkRefs - member x.tryGetMetadataSnapshot = data.tryGetMetadataSnapshot - member x.internalTestSpanStackReferring = data.internalTestSpanStackReferring - member x.noConditionalErasure = data.noConditionalErasure - - static member Create(builder, validate) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - TcConfig(builder, validate) - - member x.legacyReferenceResolver = data.legacyReferenceResolver - member tcConfig.CloneOfOriginalBuilder = - { data with conditionalCompilationDefines=data.conditionalCompilationDefines } - - member tcConfig.ComputeCanContainEntryPoint(sourceFiles: string list) = - let n = sourceFiles.Length in - (sourceFiles |> List.mapi (fun i _ -> (i = n-1)), tcConfig.target.IsExe) - - // This call can fail if no CLR is found (this is the path to mscorlib) - member tcConfig.GetTargetFrameworkDirectories() = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - try - [ - // Check if we are given an explicit framework root - if so, use that - match tcConfig.clrRoot with - | Some x -> - yield tcConfig.MakePathAbsolute x - - | None -> -// "there is no really good notion of runtime directory on .NETCore" -#if NETSTANDARD - let runtimeRoot = Path.GetDirectoryName(typeof.Assembly.Location) -#else - let runtimeRoot = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() -#endif - let runtimeRootWithoutSlash = runtimeRoot.TrimEnd('/', '\\') - let runtimeRootFacades = Path.Combine(runtimeRootWithoutSlash, "Facades") - let runtimeRootWPF = Path.Combine(runtimeRootWithoutSlash, "WPF") - - match tcConfig.resolutionEnvironment with - | ResolutionEnvironment.CompilationAndEvaluation -> - // Default compilation-and-execution-time references on .NET Framework and Mono, e.g. for F# Interactive - // - // In the current way of doing things, F# Interactive refers to implementation assemblies. - yield runtimeRoot - if Directory.Exists runtimeRootFacades then - yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades - if Directory.Exists runtimeRootWPF then - yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF - - match frameworkRefsPackDirectory with - | Some path when Directory.Exists(path) -> - yield path - | _ -> () - - | ResolutionEnvironment.EditingOrCompilation _ -> -#if ENABLE_MONO_SUPPORT - if runningOnMono then - // Default compilation-time references on Mono - // - // On Mono, the default references come from the implementation assemblies. - // This is because we have had trouble reliably using MSBuild APIs to compute DotNetFrameworkReferenceAssembliesRootDirectory on Mono. - yield runtimeRoot - if Directory.Exists runtimeRootFacades then - yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades - if Directory.Exists runtimeRootWPF then - yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF - // On Mono we also add a default reference to the 4.5-api and 4.5-api/Facades directories. - let runtimeRootApi = runtimeRootWithoutSlash + "-api" - let runtimeRootApiFacades = Path.Combine(runtimeRootApi, "Facades") - if Directory.Exists runtimeRootApi then - yield runtimeRootApi - if Directory.Exists runtimeRootApiFacades then - yield runtimeRootApiFacades - else -#endif - // Default compilation-time references on .NET Framework - // - // This is the normal case for "fsc.exe a.fs". We refer to the reference assemblies folder. - let frameworkRoot = tcConfig.legacyReferenceResolver.DotNetFrameworkReferenceAssembliesRootDirectory - let frameworkRootVersion = Path.Combine(frameworkRoot, tcConfig.targetFrameworkVersion) - yield frameworkRootVersion - let facades = Path.Combine(frameworkRootVersion, "Facades") - if Directory.Exists facades then - yield facades - match frameworkRefsPackDirectory with - | Some path when Directory.Exists(path) -> - yield path - | _ -> () - ] - with e -> - errorRecovery e range0; [] - - member tcConfig.ComputeLightSyntaxInitialStatus filename = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - let lower = String.lowercase filename - let lightOnByDefault = List.exists (Filename.checkSuffix lower) FSharpLightSyntaxFileSuffixes - if lightOnByDefault then (tcConfig.light <> Some false) else (tcConfig.light = Some true ) - - member tcConfig.GetAvailableLoadedSources() = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - let resolveLoadedSource (m, originalPath, path) = - try - if not(FileSystem.SafeExists(path)) then - let secondTrial = - tcConfig.includes - |> List.tryPick (fun root -> - let path = ComputeMakePathAbsolute root originalPath - if FileSystem.SafeExists(path) then Some path else None) - - match secondTrial with - | Some path -> Some(m,path) - | None -> - error(LoadedSourceNotFoundIgnoring(path,m)) - None - else Some(m,path) - with e -> errorRecovery e m; None - - tcConfig.loadedSources - |> List.choose resolveLoadedSource - |> List.distinct - - /// A closed set of assemblies where, for any subset S: - /// - the TcImports object built for S (and thus the F# Compiler CCUs for the assemblies in S) - /// is a resource that can be shared between any two IncrementalBuild objects that reference - /// precisely S - /// - /// Determined by looking at the set of assemblies referenced by f# . - /// - /// Returning true may mean that the file is locked and/or placed into the - /// 'framework' reference set that is potentially shared across multiple compilations. - member tcConfig.IsSystemAssembly (filename: string) = - try - FileSystem.SafeExists filename && - ((tcConfig.GetTargetFrameworkDirectories() |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) || - (systemAssemblies.Contains (fileNameWithoutExtension filename)) || - isInReferenceAssemblyPackDirectory filename) - with _ -> - false - - // This is not the complete set of search paths, it is just the set - // that is special to F# (as compared to MSBuild resolution) - member tcConfig.GetSearchPathsForLibraryFiles() = - [ yield! tcConfig.GetTargetFrameworkDirectories() - yield! List.map (tcConfig.MakePathAbsolute) tcConfig.includes - yield tcConfig.implicitIncludeDir - yield tcConfig.fsharpBinariesDir ] - - member tcConfig.MakePathAbsolute path = - let result = ComputeMakePathAbsolute tcConfig.implicitIncludeDir path - result - - member tcConfig.TryResolveLibWithDirectories (r: AssemblyReference) = - let m, nm = r.Range, r.Text - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - // Only want to resolve certain extensions (otherwise, 'System.Xml' is ambiguous). - // MSBuild resolution is limited to .exe and .dll so do the same here. - let ext = System.IO.Path.GetExtension nm - let isNetModule = String.Compare(ext, ".netmodule", StringComparison.OrdinalIgnoreCase)=0 - - // See if the language service has already produced the contents of the assembly for us, virtually - match r.ProjectReference with - | Some _ -> - let resolved = r.Text - let sysdir = tcConfig.IsSystemAssembly resolved - Some - { originalReference = r - resolvedPath = resolved - prepareToolTip = (fun () -> resolved) - sysdir = sysdir - ilAssemblyRef = None } - | None -> - - if String.Compare(ext, ".dll", StringComparison.OrdinalIgnoreCase)=0 - || String.Compare(ext, ".exe", StringComparison.OrdinalIgnoreCase)=0 - || isNetModule then - - let searchPaths = - // if this is a #r reference (not from dummy range), make sure the directory of the declaring - // file is included in the search path. This should ideally already be one of the search paths, but - // during some global checks it won't be. We append to the end of the search list so that this is the last - // place that is checked. - let isPoundRReference (r: range) = - not (Range.equals r range0) && - not (Range.equals r rangeStartup) && - not (Range.equals r rangeCmdArgs) && - FileSystem.IsPathRootedShim r.FileName - - if isPoundRReference m then - tcConfig.GetSearchPathsForLibraryFiles() @ [Path.GetDirectoryName(m.FileName)] - else - tcConfig.GetSearchPathsForLibraryFiles() - - let resolved = TryResolveFileUsingPaths(searchPaths, m, nm) - match resolved with - | Some resolved -> - let sysdir = tcConfig.IsSystemAssembly resolved - Some - { originalReference = r - resolvedPath = resolved - prepareToolTip = (fun () -> - let fusionName = System.Reflection.AssemblyName.GetAssemblyName(resolved).ToString() - let line(append: string) = append.Trim([|' '|])+"\n" - line resolved + line fusionName) - sysdir = sysdir - ilAssemblyRef = None } - | None -> None - else None - - member tcConfig.ResolveLibWithDirectories (ccuLoadFailureAction, r: AssemblyReference) = - let m, nm = r.Range, r.Text - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - // test for both libraries and executables - let ext = System.IO.Path.GetExtension nm - let isExe = (String.Compare(ext, ".exe", StringComparison.OrdinalIgnoreCase) = 0) - let isDLL = (String.Compare(ext, ".dll", StringComparison.OrdinalIgnoreCase) = 0) - let isNetModule = (String.Compare(ext, ".netmodule", StringComparison.OrdinalIgnoreCase) = 0) - - let rs = - if isExe || isDLL || isNetModule then - [r] - else - [AssemblyReference(m, nm+".dll", None);AssemblyReference(m, nm+".exe", None);AssemblyReference(m, nm+".netmodule", None)] - - match rs |> List.tryPick (fun r -> tcConfig.TryResolveLibWithDirectories r) with - | Some res -> Some res - | None -> - match ccuLoadFailureAction with - | CcuLoadFailureAction.RaiseError -> - let searchMessage = String.concat "\n " (tcConfig.GetSearchPathsForLibraryFiles()) - raise (FileNameNotResolved(nm, searchMessage, m)) - | CcuLoadFailureAction.ReturnNone -> None - - member tcConfig.ResolveSourceFile(m, nm, pathLoadedFrom) = - data.ResolveSourceFile(m, nm, pathLoadedFrom) - - // NOTE!! if mode=Speculative then this method must not report ANY warnings or errors through 'warning' or 'error'. Instead - // it must return warnings and errors as data - // - // NOTE!! if mode=ReportErrors then this method must not raise exceptions. It must just report the errors and recover - static member TryResolveLibsUsingMSBuildRules (tcConfig: TcConfig, originalReferences: AssemblyReference list, errorAndWarningRange: range, mode: ResolveAssemblyReferenceMode) : AssemblyResolution list * UnresolvedAssemblyReference list = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - if tcConfig.useSimpleResolution then - failwith "MSBuild resolution is not supported." - if originalReferences=[] then [], [] - else - // Group references by name with range values in the grouped value list. - // In the grouped reference, store the index of the last use of the reference. - let groupedReferences = - originalReferences - |> List.indexed - |> Seq.groupBy(fun (_, reference) -> reference.Text) - |> Seq.map(fun (assemblyName, assemblyAndIndexGroup)-> - let assemblyAndIndexGroup = assemblyAndIndexGroup |> List.ofSeq - let highestPosition = assemblyAndIndexGroup |> List.maxBy fst |> fst - let assemblyGroup = assemblyAndIndexGroup |> List.map snd - assemblyName, highestPosition, assemblyGroup) - |> Array.ofSeq - - let logMessage showMessages = - if showMessages && tcConfig.showReferenceResolutions then (fun (message: string)->dprintf "%s\n" message) - else ignore - - let logDiagnostic showMessages = - (fun isError code message-> - if showMessages && mode = ResolveAssemblyReferenceMode.ReportErrors then - if isError then - errorR(MSBuildReferenceResolutionError(code, message, errorAndWarningRange)) - else - match code with - // These are warnings that mean 'not resolved' for some assembly. - // Note that we don't get to know the name of the assembly that couldn't be resolved. - // Ignore these and rely on the logic below to emit an error for each unresolved reference. - | "MSB3246" // Resolved file has a bad image, no metadata, or is otherwise inaccessible. - | "MSB3106" - -> () - | _ -> - if code = "MSB3245" then - errorR(MSBuildReferenceResolutionWarning(code, message, errorAndWarningRange)) - else - warning(MSBuildReferenceResolutionWarning(code, message, errorAndWarningRange))) - - let targetProcessorArchitecture = - match tcConfig.platform with - | None -> "MSIL" - | Some X86 -> "x86" - | Some AMD64 -> "amd64" - | Some IA64 -> "ia64" - - // First, try to resolve everything as a file using simple resolution - let resolvedAsFile = - groupedReferences - |> Array.map(fun (_filename, maxIndexOfReference, references)-> - let assemblyResolution = references |> List.choose (fun r -> tcConfig.TryResolveLibWithDirectories r) - (maxIndexOfReference, assemblyResolution)) - |> Array.filter(fun (_, refs)->refs |> isNil |> not) - - - // Whatever is left, pass to MSBuild. - let Resolve(references, showMessages) = - try - tcConfig.legacyReferenceResolver.Resolve - (tcConfig.resolutionEnvironment, - references, - tcConfig.targetFrameworkVersion, - tcConfig.GetTargetFrameworkDirectories(), - targetProcessorArchitecture, - tcConfig.fsharpBinariesDir, // FSharp binaries directory - tcConfig.includes, // Explicit include directories - tcConfig.implicitIncludeDir, // Implicit include directory (likely the project directory) - logMessage showMessages, logDiagnostic showMessages) - with - ReferenceResolver.ResolutionFailure -> error(Error(FSComp.SR.buildAssemblyResolutionFailed(), errorAndWarningRange)) - - let toMsBuild = [|0..groupedReferences.Length-1|] - |> Array.map(fun i->(p13 groupedReferences.[i]), (p23 groupedReferences.[i]), i) - |> Array.filter (fun (_, i0, _)->resolvedAsFile|>Array.exists(fun (i1, _) -> i0=i1)|>not) - |> Array.map(fun (ref, _, i)->ref, string i) - - let resolutions = Resolve(toMsBuild, (*showMessages*)true) - - // Map back to original assembly resolutions. - let resolvedByMsbuild = - resolutions - |> Array.map(fun resolvedFile -> - let i = int resolvedFile.baggage - let _, maxIndexOfReference, ms = groupedReferences.[i] - let assemblyResolutions = - ms|>List.map(fun originalReference -> - System.Diagnostics.Debug.Assert(FileSystem.IsPathRootedShim(resolvedFile.itemSpec), sprintf "msbuild-resolved path is not absolute: '%s'" resolvedFile.itemSpec) - let canonicalItemSpec = FileSystem.GetFullPathShim(resolvedFile.itemSpec) - { originalReference=originalReference - resolvedPath=canonicalItemSpec - prepareToolTip = (fun () -> resolvedFile.prepareToolTip (originalReference.Text, canonicalItemSpec)) - sysdir= tcConfig.IsSystemAssembly canonicalItemSpec - ilAssemblyRef = None }) - (maxIndexOfReference, assemblyResolutions)) - - // When calculating the resulting resolutions, we're going to use the index of the reference - // in the original specification and resort it to match the ordering that we had. - let resultingResolutions = - [resolvedByMsbuild;resolvedAsFile] - |> Array.concat - |> Array.sortBy fst - |> Array.map snd - |> List.ofArray - |> List.concat - - // O(N^2) here over a small set of referenced assemblies. - let IsResolved(originalName: string) = - if resultingResolutions |> List.exists(fun resolution -> resolution.originalReference.Text = originalName) then true - else - // MSBuild resolution may have unified the result of two duplicate references. Try to re-resolve now. - // If re-resolution worked then this was a removed duplicate. - Resolve([|originalName, ""|], (*showMessages*)false).Length<>0 - - let unresolvedReferences = - groupedReferences - //|> Array.filter(p13 >> IsNotFileOrIsAssembly) - |> Array.filter(p13 >> IsResolved >> not) - |> List.ofArray - - // If mode=Speculative, then we haven't reported any errors. - // We report the error condition by returning an empty list of resolutions - if mode = ResolveAssemblyReferenceMode.Speculative && (List.length unresolvedReferences) > 0 then - [], (List.ofArray groupedReferences) |> List.map (fun (name, _, r) -> (name, r)) |> List.map UnresolvedAssemblyReference - else - resultingResolutions, unresolvedReferences |> List.map (fun (name, _, r) -> (name, r)) |> List.map UnresolvedAssemblyReference - - member tcConfig.PrimaryAssemblyDllReference() = primaryAssemblyReference - - member tcConfig.CoreLibraryDllReference() = fslibReference - - -let ReportWarning options err = - warningOn err (options.WarnLevel) (options.WarnOn) && not (List.contains (GetDiagnosticNumber err) (options.WarnOff)) - -let ReportWarningAsError options err = - warningOn err (options.WarnLevel) (options.WarnOn) && - not (List.contains (GetDiagnosticNumber err) (options.WarnAsWarn)) && - ((options.GlobalWarnAsError && not (List.contains (GetDiagnosticNumber err) options.WarnOff)) || - List.contains (GetDiagnosticNumber err) (options.WarnAsError)) - -//---------------------------------------------------------------------------- -// Scoped #nowarn pragmas - - -let GetScopedPragmasForHashDirective hd = - [ match hd with - | ParsedHashDirective("nowarn", numbers, m) -> - for s in numbers do - match GetWarningNumber(m, s) with - | None -> () - | Some n -> yield ScopedPragma.WarningOff(m, n) - | _ -> () ] - - -let GetScopedPragmasForInput input = - - match input with - | ParsedInput.SigFile (ParsedSigFileInput (scopedPragmas=pragmas)) -> pragmas - | ParsedInput.ImplFile (ParsedImplFileInput (scopedPragmas=pragmas)) -> pragmas - - - -/// Build an ErrorLogger that delegates to another ErrorLogger but filters warnings turned off by the given pragma declarations -// -// NOTE: we allow a flag to turn of strict file checking. This is because file names sometimes don't match due to use of -// #line directives, e.g. for pars.fs/pars.fsy. In this case we just test by line number - in most cases this is sufficient -// because we install a filtering error handler on a file-by-file basis for parsing and type-checking. -// However this is indicative of a more systematic problem where source-line -// sensitive operations (lexfilter and warning filtering) do not always -// interact well with #line directives. -type ErrorLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, errorLogger: ErrorLogger) = - inherit ErrorLogger("ErrorLoggerFilteringByScopedPragmas") - - override x.DiagnosticSink (phasedError, isError) = - if isError then - errorLogger.DiagnosticSink (phasedError, isError) - else - let report = - let warningNum = GetDiagnosticNumber phasedError - match GetRangeOfDiagnostic phasedError with - | Some m -> - not (scopedPragmas |> List.exists (fun pragma -> - match pragma with - | ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma) -> - warningNum = warningNumFromPragma && - (not checkFile || m.FileIndex = pragmaRange.FileIndex) && - Range.posGeq m.Start pragmaRange.Start)) - | None -> true - if report then errorLogger.DiagnosticSink(phasedError, false) - - override x.ErrorCount = errorLogger.ErrorCount - -let GetErrorLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, errorLogger) = - (ErrorLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, errorLogger) :> ErrorLogger) - - -//---------------------------------------------------------------------------- -// Parsing -//-------------------------------------------------------------------------- - - -let CanonicalizeFilename filename = - let basic = fileNameOfPath filename - String.capitalize (try Filename.chopExtension basic with _ -> basic) - -let IsScript filename = - let lower = String.lowercase filename - FSharpScriptFileSuffixes |> List.exists (Filename.checkSuffix lower) - -// Give a unique name to the different kinds of inputs. Used to correlate signature and implementation files -// QualFileNameOfModuleName - files with a single module declaration or an anonymous module -let QualFileNameOfModuleName m filename modname = QualifiedNameOfFile(mkSynId m (textOfLid modname + (if IsScript filename then "$fsx" else ""))) -let QualFileNameOfFilename m filename = QualifiedNameOfFile(mkSynId m (CanonicalizeFilename filename + (if IsScript filename then "$fsx" else ""))) - -// Interactive fragments -let ComputeQualifiedNameOfFileFromUniquePath (m, p: string list) = QualifiedNameOfFile(mkSynId m (String.concat "_" p)) - -let QualFileNameOfSpecs filename specs = - match specs with - | [SynModuleOrNamespaceSig(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname - | [SynModuleOrNamespaceSig(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename - | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename - -let QualFileNameOfImpls filename specs = - match specs with - | [SynModuleOrNamespace(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname - | [SynModuleOrNamespace(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename - | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename - -let PrependPathToQualFileName x (QualifiedNameOfFile q) = ComputeQualifiedNameOfFileFromUniquePath (q.idRange, pathOfLid x@[q.idText]) -let PrependPathToImpl x (SynModuleOrNamespace(p, b, c, d, e, f, g, h)) = SynModuleOrNamespace(x@p, b, c, d, e, f, g, h) -let PrependPathToSpec x (SynModuleOrNamespaceSig(p, b, c, d, e, f, g, h)) = SynModuleOrNamespaceSig(x@p, b, c, d, e, f, g, h) - -let PrependPathToInput x inp = - match inp with - | ParsedInput.ImplFile (ParsedImplFileInput (b, c, q, d, hd, impls, e)) -> ParsedInput.ImplFile (ParsedImplFileInput (b, c, PrependPathToQualFileName x q, d, hd, List.map (PrependPathToImpl x) impls, e)) - | ParsedInput.SigFile (ParsedSigFileInput (b, q, d, hd, specs)) -> ParsedInput.SigFile (ParsedSigFileInput (b, PrependPathToQualFileName x q, d, hd, List.map (PrependPathToSpec x) specs)) - -let ComputeAnonModuleName check defaultNamespace filename (m: range) = - let modname = CanonicalizeFilename filename - if check && not (modname |> String.forall (fun c -> System.Char.IsLetterOrDigit c || c = '_')) then - if not (filename.EndsWith("fsx", StringComparison.OrdinalIgnoreCase) || filename.EndsWith("fsscript", StringComparison.OrdinalIgnoreCase)) then - warning(Error(FSComp.SR.buildImplicitModuleIsNotLegalIdentifier(modname, (fileNameOfPath filename)), m)) - let combined = - match defaultNamespace with - | None -> modname - | Some ns -> textOfPath [ns;modname] - - let anonymousModuleNameRange = - let filename = m.FileName - mkRange filename pos0 pos0 - pathToSynLid anonymousModuleNameRange (splitNamespace combined) - -let PostParseModuleImpl (_i, defaultNamespace, isLastCompiland, filename, impl) = - match impl with - | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> - let lid = - match lid with - | [id] when kind.IsModule && id.idText = MangledGlobalName -> - error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) - | id :: rest when id.idText = MangledGlobalName -> rest - | _ -> lid - SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m) - - | ParsedImplFileFragment.AnonModule (defs, m)-> - let isLast, isExe = isLastCompiland - let lower = String.lowercase filename - if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (Filename.checkSuffix lower)) then - match defs with - | SynModuleDecl.NestedModule(_) :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), trimRangeToLine m)) - | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), trimRangeToLine m)) - - let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) - SynModuleOrNamespace(modname, false, AnonModule, defs, PreXmlDoc.Empty, [], None, m) - - | ParsedImplFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> - let lid, kind = - match lid with - | id :: rest when id.idText = MangledGlobalName -> - rest, if List.isEmpty rest then GlobalNamespace else kind - | _ -> lid, kind - SynModuleOrNamespace(lid, a, kind, c, d, e, None, m) - -let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, filename, intf) = - match intf with - | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> - let lid = - match lid with - | [id] when kind.IsModule && id.idText = MangledGlobalName -> - error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) - | id :: rest when id.idText = MangledGlobalName -> rest - | _ -> lid - SynModuleOrNamespaceSig(lid, isRec, NamedModule, decls, xmlDoc, attribs, access, m) - - | ParsedSigFileFragment.AnonModule (defs, m) -> - let isLast, isExe = isLastCompiland - let lower = String.lowercase filename - if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (Filename.checkSuffix lower)) then - match defs with - | SynModuleSigDecl.NestedModule(_) :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), m)) - | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), m)) - - let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) - SynModuleOrNamespaceSig(modname, false, AnonModule, defs, PreXmlDoc.Empty, [], None, m) - - | ParsedSigFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> - let lid, kind = - match lid with - | id :: rest when id.idText = MangledGlobalName -> - rest, if List.isEmpty rest then GlobalNamespace else kind - | _ -> lid, kind - SynModuleOrNamespaceSig(lid, a, kind, c, d, e, None, m) - - - -let PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, ParsedImplFile (hashDirectives, impls)) = - match impls |> List.rev |> List.tryPick (function ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, _, _, _, _, _, _, _)) -> Some lid | _ -> None) with - | Some lid when impls.Length > 1 -> - errorR(Error(FSComp.SR.buildMultipleToplevelModules(), rangeOfLid lid)) - | _ -> - () - let impls = impls |> List.mapi (fun i x -> PostParseModuleImpl (i, defaultNamespace, isLastCompiland, filename, x)) - let qualName = QualFileNameOfImpls filename impls - let isScript = IsScript filename - - let scopedPragmas = - [ for (SynModuleOrNamespace(_, _, _, decls, _, _, _, _)) in impls do - for d in decls do - match d with - | SynModuleDecl.HashDirective (hd, _) -> yield! GetScopedPragmasForHashDirective hd - | _ -> () - for hd in hashDirectives do - yield! GetScopedPragmasForHashDirective hd ] - ParsedInput.ImplFile (ParsedImplFileInput (filename, isScript, qualName, scopedPragmas, hashDirectives, impls, isLastCompiland)) - -let PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, ParsedSigFile (hashDirectives, specs)) = - match specs |> List.rev |> List.tryPick (function ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, _, _, _, _, _, _, _)) -> Some lid | _ -> None) with - | Some lid when specs.Length > 1 -> - errorR(Error(FSComp.SR.buildMultipleToplevelModules(), rangeOfLid lid)) - | _ -> - () - - let specs = specs |> List.mapi (fun i x -> PostParseModuleSpec(i, defaultNamespace, isLastCompiland, filename, x)) - let qualName = QualFileNameOfSpecs filename specs - let scopedPragmas = - [ for (SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _)) in specs do - for d in decls do - match d with - | SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd - | _ -> () - for hd in hashDirectives do - yield! GetScopedPragmasForHashDirective hd ] - - ParsedInput.SigFile (ParsedSigFileInput (filename, qualName, scopedPragmas, hashDirectives, specs)) - -type ModuleNamesDict = Map> - -/// Checks if a module name is already given and deduplicates the name if needed. -let DeduplicateModuleName (moduleNamesDict: ModuleNamesDict) fileName (qualNameOfFile: QualifiedNameOfFile) = - let path = Path.GetDirectoryName fileName - let path = if FileSystem.IsPathRootedShim path then try FileSystem.GetFullPathShim path with _ -> path else path - match moduleNamesDict.TryGetValue qualNameOfFile.Text with - | true, paths -> - if paths.ContainsKey path then - paths.[path], moduleNamesDict - else - let count = paths.Count + 1 - let id = qualNameOfFile.Id - let qualNameOfFileT = if count = 1 then qualNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange)) - let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, paths.Add(path, qualNameOfFileT)) - qualNameOfFileT, moduleNamesDictT - | _ -> - let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, Map.empty.Add(path, qualNameOfFile)) - qualNameOfFile, moduleNamesDictT - -/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. -let DeduplicateParsedInputModuleName (moduleNamesDict: ModuleNamesDict) input = - match input with - | ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput (fileName, isScript, qualNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) -> - let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile - let inputT = ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput (fileName, isScript, qualNameOfFileT, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) - inputT, moduleNamesDictT - | ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput (fileName, qualNameOfFile, scopedPragmas, hashDirectives, modules)) -> - let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile - let inputT = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput (fileName, qualNameOfFileT, scopedPragmas, hashDirectives, modules)) - inputT, moduleNamesDictT - -let ParseInput (lexer, errorLogger: ErrorLogger, lexbuf: UnicodeLexing.Lexbuf, defaultNamespace, filename, isLastCompiland) = - // The assert below is almost ok, but it fires in two cases: - // - fsi.exe sometimes passes "stdin" as a dummy filename - // - if you have a #line directive, e.g. - // # 1000 "Line01.fs" - // then it also asserts. But these are edge cases that can be fixed later, e.g. in bug 4651. - //System.Diagnostics.Debug.Assert(System.IO.Path.IsPathRooted filename, sprintf "should be absolute: '%s'" filename) - let lower = String.lowercase filename - // Delay sending errors and warnings until after the file is parsed. This gives us a chance to scrape the - // #nowarn declarations for the file - let delayLogger = CapturingErrorLogger("Parsing") - use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayLogger) - use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - let mutable scopedPragmas = [] - try - let input = - if mlCompatSuffixes |> List.exists (Filename.checkSuffix lower) then - mlCompatWarning (FSComp.SR.buildCompilingExtensionIsForML()) rangeStartup - - if FSharpImplFileSuffixes |> List.exists (Filename.checkSuffix lower) then - let impl = Parser.implementationFile lexer lexbuf - PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, impl) - elif FSharpSigFileSuffixes |> List.exists (Filename.checkSuffix lower) then - let intfs = Parser.signatureFile lexer lexbuf - PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, intfs) - else - delayLogger.Error(Error(FSComp.SR.buildInvalidSourceFileExtension filename, Range.rangeStartup)) - scopedPragmas <- GetScopedPragmasForInput input - input - finally - // OK, now commit the errors, since the ScopedPragmas will (hopefully) have been scraped - let filteringErrorLogger = ErrorLoggerFilteringByScopedPragmas(false, scopedPragmas, errorLogger) - delayLogger.CommitDelayedDiagnostics filteringErrorLogger - -//---------------------------------------------------------------------------- -// parsing - ParseOneInputFile -// Filename is (ml/mli/fs/fsi source). Parse it to AST. -//---------------------------------------------------------------------------- -let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) = - use unwindbuildphase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - try - let skip = true in (* don't report whitespace from lexer *) - let lightSyntaxStatus = LightSyntaxStatus (tcConfig.ComputeLightSyntaxInitialStatus filename, true) - let lexargs = mkLexargs (filename, conditionalCompilationDefines@tcConfig.conditionalCompilationDefines, lightSyntaxStatus, lexResourceManager, [], errorLogger, tcConfig.pathMap) - let shortFilename = SanitizeFileName filename tcConfig.implicitIncludeDir - let input = - Lexhelp.usingLexbufForParsing (lexbuf, filename) (fun lexbuf -> - if verbose then dprintn ("Parsing... "+shortFilename) - let tokenizer = LexFilter.LexFilter(lightSyntaxStatus, tcConfig.compilingFslib, Lexer.token lexargs skip, lexbuf) - - if tcConfig.tokenizeOnly then - while true do - printf "tokenize - getting one token from %s\n" shortFilename - let t = tokenizer.Lexer lexbuf - printf "tokenize - got %s @ %a\n" (Parser.token_to_string t) outputRange lexbuf.LexemeRange - (match t with Parser.EOF _ -> exit 0 | _ -> ()) - if lexbuf.IsPastEndOfStream then printf "!!! at end of stream\n" - - if tcConfig.testInteractionParser then - while true do - match (Parser.interaction tokenizer.Lexer lexbuf) with - | IDefns(l, m) -> dprintf "Parsed OK, got %d defs @ %a\n" l.Length outputRange m - | IHash (_, m) -> dprintf "Parsed OK, got hash @ %a\n" outputRange m - exit 0 - - let res = ParseInput(tokenizer.Lexer, errorLogger, lexbuf, None, filename, isLastCompiland) - - if tcConfig.reportNumDecls then - let rec flattenSpecs specs = - specs |> List.collect (function (SynModuleSigDecl.NestedModule (_, _, subDecls, _)) -> flattenSpecs subDecls | spec -> [spec]) - let rec flattenDefns specs = - specs |> List.collect (function (SynModuleDecl.NestedModule (_, _, subDecls, _, _)) -> flattenDefns subDecls | defn -> [defn]) - - let flattenModSpec (SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _)) = flattenSpecs decls - let flattenModImpl (SynModuleOrNamespace(_, _, _, decls, _, _, _, _)) = flattenDefns decls - match res with - | ParsedInput.SigFile (ParsedSigFileInput (_, _, _, _, specs)) -> - dprintf "parsing yielded %d specs" (List.collect flattenModSpec specs).Length - | ParsedInput.ImplFile (ParsedImplFileInput (modules = impls)) -> - dprintf "parsing yielded %d definitions" (List.collect flattenModImpl impls).Length - res - ) - if verbose then dprintn ("Parsed "+shortFilename) - Some input - with e -> (* errorR(Failure("parse failed")); *) errorRecovery e rangeStartup; None - - -let ParseOneInputFile (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) = - try - let lower = String.lowercase filename - if List.exists (Filename.checkSuffix lower) (FSharpSigFileSuffixes@FSharpImplFileSuffixes) then - if not(FileSystem.SafeExists filename) then - error(Error(FSComp.SR.buildCouldNotFindSourceFile filename, rangeStartup)) - let isFeatureSupported featureId = tcConfig.langVersion.SupportsFeature featureId - use reader = File.OpenReaderAndRetry (filename, tcConfig.inputCodePage, retryLocked) - let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(isFeatureSupported, reader) - ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) - else error(Error(FSComp.SR.buildInvalidSourceFileExtension(SanitizeFileName filename tcConfig.implicitIncludeDir), rangeStartup)) - with e -> (* errorR(Failure("parse failed")); *) errorRecovery e rangeStartup; None - - -[] -type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list, unresolved: UnresolvedAssemblyReference list) = - - let originalReferenceToResolution = results |> List.map (fun r -> r.originalReference.Text, r) |> Map.ofList - let resolvedPathToResolution = results |> List.map (fun r -> r.resolvedPath, r) |> Map.ofList - - /// Add some resolutions to the map of resolution results. - member tcResolutions.AddResolutionResults newResults = TcAssemblyResolutions(tcConfig, results @ newResults, unresolved) - - /// Add some unresolved results. - member tcResolutions.AddUnresolvedReferences newUnresolved = TcAssemblyResolutions(tcConfig, results, unresolved @ newUnresolved) - - /// Get information about referenced DLLs - member tcResolutions.GetAssemblyResolutions() = results - member tcResolutions.GetUnresolvedReferences() = unresolved - member tcResolutions.TryFindByOriginalReference(assemblyReference: AssemblyReference) = originalReferenceToResolution.TryFind assemblyReference.Text - - /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcResolution.TryFindByExactILAssemblyRef (ctok, assemblyRef) = - results |> List.tryFind (fun ar-> - let r = ar.GetILAssemblyRef(ctok, tcConfig.reduceMemoryUsage, tcConfig.tryGetMetadataSnapshot) |> Cancellable.runWithoutCancellation - r = assemblyRef) - - /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcResolution.TryFindBySimpleAssemblyName (ctok, simpleAssemName) = - results |> List.tryFind (fun ar-> - let r = ar.GetILAssemblyRef(ctok, tcConfig.reduceMemoryUsage, tcConfig.tryGetMetadataSnapshot) |> Cancellable.runWithoutCancellation - r.Name = simpleAssemName) - - member tcResolutions.TryFindByResolvedPath nm = resolvedPathToResolution.TryFind nm - member tcResolutions.TryFindByOriginalReferenceText nm = originalReferenceToResolution.TryFind nm - - static member ResolveAssemblyReferences (ctok, tcConfig: TcConfig, assemblyList: AssemblyReference list, knownUnresolved: UnresolvedAssemblyReference list) : TcAssemblyResolutions = - let resolved, unresolved = - if tcConfig.useSimpleResolution then - let resolutions = - assemblyList - |> List.map (fun assemblyReference -> - try - Choice1Of2 (tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, assemblyReference) |> Option.get) - with e -> - errorRecovery e assemblyReference.Range - Choice2Of2 assemblyReference) - let successes = resolutions |> List.choose (function Choice1Of2 x -> Some x | _ -> None) - let failures = resolutions |> List.choose (function Choice2Of2 x -> Some (UnresolvedAssemblyReference(x.Text, [x])) | _ -> None) - successes, failures - else - RequireCompilationThread ctok // we don't want to do assembly resolution concurrently, we assume MSBuild doesn't handle this - TcConfig.TryResolveLibsUsingMSBuildRules (tcConfig, assemblyList, rangeStartup, ResolveAssemblyReferenceMode.ReportErrors) - TcAssemblyResolutions(tcConfig, resolved, unresolved @ knownUnresolved) - - static member GetAllDllReferences (tcConfig: TcConfig) = [ - let primaryReference = tcConfig.PrimaryAssemblyDllReference() - //yield primaryReference - - if not tcConfig.compilingFslib then - yield tcConfig.CoreLibraryDllReference() - - let assumeDotNetFramework = primaryReference.SimpleAssemblyNameIs("mscorlib") - if tcConfig.framework then - for s in defaultReferencesForScriptsAndOutOfProjectSources tcConfig.useFsiAuxLib assumeDotNetFramework tcConfig.useSdkRefs do - yield AssemblyReference(rangeStartup, (if s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then s else s+".dll"), None) - - yield! tcConfig.referencedDLLs - ] - - static member SplitNonFoundationalResolutions (ctok, tcConfig: TcConfig) = - let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig - let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (ctok, tcConfig, assemblyList, tcConfig.knownUnresolvedReferences) - let frameworkDLLs, nonFrameworkReferences = resolutions.GetAssemblyResolutions() |> List.partition (fun r -> r.sysdir) - let unresolved = resolutions.GetUnresolvedReferences() -#if DEBUG - let mutable itFailed = false - let addedText = "\nIf you want to debug this right now, attach a debugger, and put a breakpoint in 'CompileOps.fs' near the text '!itFailed', and you can re-step through the assembly resolution logic." - unresolved - |> List.iter (fun (UnresolvedAssemblyReference(referenceText, _ranges)) -> - if referenceText.Contains("mscorlib") then - System.Diagnostics.Debug.Assert(false, sprintf "whoops, did not resolve mscorlib: '%s'%s" referenceText addedText) - itFailed <- true) - frameworkDLLs - |> List.iter (fun x -> - if not(FileSystem.IsPathRootedShim(x.resolvedPath)) then - System.Diagnostics.Debug.Assert(false, sprintf "frameworkDLL should be absolute path: '%s'%s" x.resolvedPath addedText) - itFailed <- true) - nonFrameworkReferences - |> List.iter (fun x -> - if not(FileSystem.IsPathRootedShim(x.resolvedPath)) then - System.Diagnostics.Debug.Assert(false, sprintf "nonFrameworkReference should be absolute path: '%s'%s" x.resolvedPath addedText) - itFailed <- true) - if itFailed then - // idea is, put a breakpoint here and then step through - let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig - let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (ctok, tcConfig, assemblyList, []) - let _frameworkDLLs, _nonFrameworkReferences = resolutions.GetAssemblyResolutions() |> List.partition (fun r -> r.sysdir) - () -#endif - frameworkDLLs, nonFrameworkReferences, unresolved - - static member BuildFromPriorResolutions (ctok, tcConfig: TcConfig, resolutions, knownUnresolved) = - let references = resolutions |> List.map (fun r -> r.originalReference) - TcAssemblyResolutions.ResolveAssemblyReferences (ctok, tcConfig, references, knownUnresolved) - - -//---------------------------------------------------------------------------- -// Typecheck and optimization environments on disk -//-------------------------------------------------------------------------- - -let IsSignatureDataResource (r: ILResource) = - r.Name.StartsWithOrdinal FSharpSignatureDataResourceName || - r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 - -let IsOptimizationDataResource (r: ILResource) = - r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName|| - r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 - -let GetSignatureDataResourceName (r: ILResource) = - if r.Name.StartsWithOrdinal FSharpSignatureDataResourceName then - String.dropPrefix r.Name FSharpSignatureDataResourceName - elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 then - String.dropPrefix r.Name FSharpSignatureDataResourceName2 - else failwith "GetSignatureDataResourceName" - -let GetOptimizationDataResourceName (r: ILResource) = - if r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName then - String.dropPrefix r.Name FSharpOptimizationDataResourceName - elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 then - String.dropPrefix r.Name FSharpOptimizationDataResourceName2 - else failwith "GetOptimizationDataResourceName" - -let IsReflectedDefinitionsResource (r: ILResource) = - r.Name.StartsWithOrdinal(QuotationPickler.SerializedReflectedDefinitionsResourceNameBase) - -let MakeILResource rName bytes = - { Name = rName - Location = ILResourceLocation.Local(ByteMemory.FromArray(bytes).AsReadOnly()) - Access = ILResourceAccess.Public - CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx } - -let PickleToResource inMem file (g: TcGlobals) scope rName p x = - let file = PathMap.apply g.pathMap file - - { Name = rName - Location = (let bytes = pickleObjWithDanglingCcus inMem file g scope p x in ILResourceLocation.Local(ByteMemory.FromArray(bytes).AsReadOnly())) - Access = ILResourceAccess.Public - CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx } - -let GetSignatureData (file, ilScopeRef, ilModule, byteReader) : PickledDataWithReferences = - unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo (byteReader()) - -let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, file, inMem) : ILResource = - let mspec = ccu.Contents - let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping mspec - // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers - // don't complain when they see the resource. - let rName = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName - - let includeDir = - if String.IsNullOrEmpty tcConfig.implicitIncludeDir then "" - else - tcConfig.implicitIncludeDir - |> System.IO.Path.GetFullPath - |> PathMap.applyDir tcGlobals.pathMap - - PickleToResource inMem file tcGlobals ccu (rName+ccu.AssemblyName) pickleCcuInfo - { mspec=mspec - compileTimeWorkingDir=includeDir - usesQuotations = ccu.UsesFSharp20PlusQuotations } - -let GetOptimizationData (file, ilScopeRef, ilModule, byteReader) = - unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo (byteReader()) - -let WriteOptimizationData (tcGlobals, file, inMem, ccu: CcuThunk, modulInfo) = - // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers - // don't complain when they see the resource. - let rName = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpOptimizationDataResourceName2 else FSharpOptimizationDataResourceName - PickleToResource inMem file tcGlobals ccu (rName+ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo - -//---------------------------------------------------------------------------- -// Abstraction for project reference - -type RawFSharpAssemblyDataBackedByFileOnDisk (ilModule: ILModuleDef, ilAssemblyRefs) = - let externalSigAndOptData = ["FSharp.Core"] - interface IRawFSharpAssemblyData with - member __.GetAutoOpenAttributes ilg = GetAutoOpenAttributes ilg ilModule - member __.GetInternalsVisibleToAttributes ilg = GetInternalsVisibleToAttributes ilg ilModule - member __.TryGetILModuleDef() = Some ilModule - member __.GetRawFSharpSignatureData(m, ilShortAssemName, filename) = - let resources = ilModule.Resources.AsList - let sigDataReaders = - [ for iresource in resources do - if IsSignatureDataResource iresource then - let ccuName = GetSignatureDataResourceName iresource - yield (ccuName, fun () -> iresource.GetBytes()) ] - - let sigDataReaders = - if sigDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then - let sigFileName = Path.ChangeExtension(filename, "sigdata") - if not (FileSystem.SafeExists sigFileName) then - error(Error(FSComp.SR.buildExpectedSigdataFile (FileSystem.GetFullPathShim sigFileName), m)) - [ (ilShortAssemName, fun () -> ByteMemory.FromFile(sigFileName, FileAccess.Read, canShadowCopy=true).AsReadOnly())] - else - sigDataReaders - sigDataReaders - member __.GetRawFSharpOptimizationData(m, ilShortAssemName, filename) = - let optDataReaders = - ilModule.Resources.AsList - |> List.choose (fun r -> if IsOptimizationDataResource r then Some(GetOptimizationDataResourceName r, (fun () -> r.GetBytes())) else None) - - // Look for optimization data in a file - let optDataReaders = - if optDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then - let optDataFile = Path.ChangeExtension(filename, "optdata") - if not (FileSystem.SafeExists optDataFile) then - error(Error(FSComp.SR.buildExpectedFileAlongSideFSharpCore(optDataFile, FileSystem.GetFullPathShim optDataFile), m)) - [ (ilShortAssemName, (fun () -> ByteMemory.FromFile(optDataFile, FileAccess.Read, canShadowCopy=true).AsReadOnly()))] - else - optDataReaders - optDataReaders - member __.GetRawTypeForwarders() = - match ilModule.Manifest with - | Some manifest -> manifest.ExportedTypes - | None -> mkILExportedTypes [] - member __.ShortAssemblyName = GetNameOfILModule ilModule - member __.ILScopeRef = MakeScopeRefForILModule ilModule - member __.ILAssemblyRefs = ilAssemblyRefs - member __.HasAnyFSharpSignatureDataAttribute = - let attrs = GetCustomAttributesOfILModule ilModule - List.exists IsSignatureDataVersionAttr attrs - member __.HasMatchingFSharpSignatureDataAttribute ilg = - let attrs = GetCustomAttributesOfILModule ilModule - List.exists (IsMatchingSignatureDataVersionAttr ilg (IL.parseILVersion Internal.Utilities.FSharpEnvironment.FSharpBinaryMetadataFormatRevision)) attrs - - -//---------------------------------------------------------------------------- -// Relink blobs of saved data by fixing up ccus. -//-------------------------------------------------------------------------- - -let availableToOptionalCcu = function - | ResolvedCcu ccu -> Some ccu - | UnresolvedCcu _ -> None - - -//---------------------------------------------------------------------------- -// TcConfigProvider -//-------------------------------------------------------------------------- - -/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, -/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. -type TcConfigProvider = - | TcConfigProvider of (CompilationThreadToken -> TcConfig) - member x.Get ctok = (let (TcConfigProvider f) = x in f ctok) - - /// Get a TcConfigProvider which will return only the exact TcConfig. - static member Constant tcConfig = TcConfigProvider(fun _ctok -> tcConfig) - - /// Get a TcConfigProvider which will continue to respect changes in the underlying - /// TcConfigBuilder rather than delivering snapshots. - static member BasedOnMutableBuilder tcConfigB = TcConfigProvider(fun _ctok -> TcConfig.Create(tcConfigB, validate=false)) - - -//---------------------------------------------------------------------------- -// TcImports -//-------------------------------------------------------------------------- - -#if !NO_EXTENSIONTYPING -// These are hacks in order to allow TcImports to be held as a weak reference inside a type provider. -// The reason is due to older type providers compiled using an older TypeProviderSDK, that SDK used reflection on fields and properties to determine the contract. -// The reflection code has now since been removed, see here: https://github.com/fsprojects/FSharp.TypeProviders.SDK/pull/305. But we still need to work on older type providers. -// One day we can remove these hacks when we deemed most if not all type providers were re-compiled using the newer TypeProviderSDK. -// Yuck. -type TcImportsDllInfoHack = - { - FileName: string - } - -and TcImportsWeakHack (tcImports: WeakReference) = - let mutable dllInfos: TcImportsDllInfoHack list = [] - - member __.SetDllInfos (value: ImportedBinary list) = - dllInfos <- value |> List.map (fun x -> { FileName = x.FileName }) - - member __.Base: TcImportsWeakHack option = - match tcImports.TryGetTarget() with - | true, strong -> - match strong.Base with - | Some (baseTcImports: TcImports) -> - Some baseTcImports.Weak - | _ -> - None - | _ -> - None - - member __.SystemRuntimeContainsType typeName = - match tcImports.TryGetTarget () with - | true, strong -> strong.SystemRuntimeContainsType typeName - | _ -> false -#endif -/// Represents a table of imported assemblies with their resolutions. -/// Is a disposable object, but it is recommended not to explicitly call Dispose unless you absolutely know nothing will be using its contents after the disposal. -/// Otherwise, simply allow the GC to collect this and it will properly call Dispose from the finalizer. -and [] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolutions, importsBase: TcImports option, ilGlobalsOpt, compilationThread: ICompilationThread) as this = - - let mutable resolutions = initialResolutions - let mutable importsBase: TcImports option = importsBase - let mutable dllInfos: ImportedBinary list = [] - let mutable dllTable: NameMap = NameMap.empty - let mutable ccuInfos: ImportedAssembly list = [] - let mutable ccuTable: NameMap = NameMap.empty - let mutable disposeActions = [] - let mutable disposed = false - let mutable ilGlobalsOpt = ilGlobalsOpt - let mutable tcGlobals = None -#if !NO_EXTENSIONTYPING - let mutable disposeTypeProviderActions = [] - let mutable generatedTypeRoots = new System.Collections.Generic.Dictionary() - let mutable tcImportsWeak = TcImportsWeakHack (WeakReference<_> this) -#endif - - let CheckDisposed() = - if disposed then assert false - - let dispose () = - CheckDisposed() - // disposing deliberately only closes this tcImports, not the ones up the chain - disposed <- true - if verbose then - dprintf "disposing of TcImports, %d binaries\n" disposeActions.Length -#if !NO_EXTENSIONTYPING - let actions = disposeTypeProviderActions - disposeTypeProviderActions <- [] - if actions.Length > 0 then - compilationThread.EnqueueWork (fun _ -> for action in actions do action()) -#endif - let actions = disposeActions - disposeActions <- [] - for action in actions do action() - - static let ccuHasType (ccu: CcuThunk) (nsname: string list) (tname: string) = - let matchNameSpace (entityOpt: Entity option) n = - match entityOpt with - | None -> None - | Some entity -> - entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind n - - match (Some ccu.Contents, nsname) ||> List.fold matchNameSpace with - | Some ns -> - match Map.tryFind tname ns.ModuleOrNamespaceType.TypesByMangledName with - | Some _ -> true - | None -> false - | None -> false - - member internal tcImports.Base = - CheckDisposed() - importsBase - - member tcImports.CcuTable = - CheckDisposed() - ccuTable - - member tcImports.DllTable = - CheckDisposed() - dllTable - -#if !NO_EXTENSIONTYPING - member tcImports.Weak = - CheckDisposed() - tcImportsWeak -#endif - - member tcImports.RegisterCcu ccuInfo = - CheckDisposed() - ccuInfos <- ccuInfos ++ ccuInfo - // Assembly Ref Resolution: remove this use of ccu.AssemblyName - ccuTable <- NameMap.add (ccuInfo.FSharpViewOfMetadata.AssemblyName) ccuInfo ccuTable - - member tcImports.RegisterDll dllInfo = - CheckDisposed() - dllInfos <- dllInfos ++ dllInfo -#if !NO_EXTENSIONTYPING - tcImportsWeak.SetDllInfos dllInfos -#endif - dllTable <- NameMap.add (getNameOfScopeRef dllInfo.ILScopeRef) dllInfo dllTable - - member tcImports.GetDllInfos() : ImportedBinary list = - CheckDisposed() - match importsBase with - | Some importsBase-> importsBase.GetDllInfos() @ dllInfos - | None -> dllInfos - - member tcImports.AllAssemblyResolutions() = - CheckDisposed() - let ars = resolutions.GetAssemblyResolutions() - match importsBase with - | Some importsBase-> importsBase.AllAssemblyResolutions() @ ars - | None -> ars - - member tcImports.TryFindDllInfo (ctok: CompilationThreadToken, m, assemblyName, lookupOnly) = - CheckDisposed() - let rec look (t: TcImports) = - match NameMap.tryFind assemblyName t.DllTable with - | Some res -> Some res - | None -> - match t.Base with - | Some t2 -> look t2 - | None -> None - match look tcImports with - | Some res -> Some res - | None -> - tcImports.ImplicitLoadIfAllowed(ctok, m, assemblyName, lookupOnly) - look tcImports - - - member tcImports.FindDllInfo (ctok, m, assemblyName) = - match tcImports.TryFindDllInfo (ctok, m, assemblyName, lookupOnly=false) with - | Some res -> res - | None -> error(Error(FSComp.SR.buildCouldNotResolveAssembly assemblyName, m)) - - member tcImports.GetImportedAssemblies() = - CheckDisposed() - match importsBase with - | Some importsBase-> List.append (importsBase.GetImportedAssemblies()) ccuInfos - | None -> ccuInfos - - member tcImports.GetCcusExcludingBase() = - CheckDisposed() - ccuInfos |> List.map (fun x -> x.FSharpViewOfMetadata) - - member tcImports.GetCcusInDeclOrder() = - CheckDisposed() - List.map (fun x -> x.FSharpViewOfMetadata) (tcImports.GetImportedAssemblies()) - - // This is the main "assembly reference --> assembly" resolution routine. - member tcImports.FindCcuInfo (ctok, m, assemblyName, lookupOnly) = - CheckDisposed() - let rec look (t: TcImports) = - match NameMap.tryFind assemblyName t.CcuTable with - | Some res -> Some res - | None -> - match t.Base with - | Some t2 -> look t2 - | None -> None - - match look tcImports with - | Some res -> ResolvedImportedAssembly res - | None -> - tcImports.ImplicitLoadIfAllowed(ctok, m, assemblyName, lookupOnly) - match look tcImports with - | Some res -> ResolvedImportedAssembly res - | None -> UnresolvedImportedAssembly assemblyName - - - member tcImports.FindCcu (ctok, m, assemblyName, lookupOnly) = - CheckDisposed() - match tcImports.FindCcuInfo(ctok, m, assemblyName, lookupOnly) with - | ResolvedImportedAssembly importedAssembly -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) - | UnresolvedImportedAssembly assemblyName -> UnresolvedCcu assemblyName - - member tcImports.FindCcuFromAssemblyRef(ctok, m, assemblyRef: ILAssemblyRef) = - CheckDisposed() - match tcImports.FindCcuInfo(ctok, m, assemblyRef.Name, lookupOnly=false) with - | ResolvedImportedAssembly importedAssembly -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) - | UnresolvedImportedAssembly _ -> UnresolvedCcu(assemblyRef.QualifiedName) - - -#if !NO_EXTENSIONTYPING - member tcImports.GetProvidedAssemblyInfo(ctok, m, assembly: Tainted) = - let anameOpt = assembly.PUntaint((fun assembly -> match assembly with null -> None | a -> Some (a.GetName())), m) - match anameOpt with - | None -> false, None - | Some aname -> - let ilShortAssemName = aname.Name - match tcImports.FindCcu (ctok, m, ilShortAssemName, lookupOnly=true) with - | ResolvedCcu ccu -> - if ccu.IsProviderGenerated then - let dllinfo = tcImports.FindDllInfo(ctok, m, ilShortAssemName) - true, dllinfo.ProviderGeneratedStaticLinkMap - else - false, None - - | UnresolvedCcu _ -> - let g = tcImports.GetTcGlobals() - let ilScopeRef = ILScopeRef.Assembly (ILAssemblyRef.FromAssemblyName aname) - let fileName = aname.Name + ".dll" - let bytes = assembly.PApplyWithProvider((fun (assembly, provider) -> assembly.GetManifestModuleContents provider), m).PUntaint(id, m) - let tcConfig = tcConfigP.Get ctok - let ilModule, ilAssemblyRefs = - let opts: ILReaderOptions = - { reduceMemoryUsage = tcConfig.reduceMemoryUsage - pdbDirPath = None - metadataOnly = MetadataOnlyFlag.Yes - tryGetMetadataSnapshot = tcConfig.tryGetMetadataSnapshot } - let reader = OpenILModuleReaderFromBytes fileName bytes opts - reader.ILModuleDef, reader.ILAssemblyRefs - - let theActualAssembly = assembly.PUntaint((fun x -> x.Handle), m) - let dllinfo = - { RawMetadata= RawFSharpAssemblyDataBackedByFileOnDisk (ilModule, ilAssemblyRefs) - FileName=fileName - ProviderGeneratedAssembly=Some theActualAssembly - IsProviderGenerated=true - ProviderGeneratedStaticLinkMap= if g.isInteractive then None else Some (ProvidedAssemblyStaticLinkingMap.CreateNew()) - ILScopeRef = ilScopeRef - ILAssemblyRefs = ilAssemblyRefs } - tcImports.RegisterDll dllinfo - let ccuData: CcuData = - { IsFSharp=false - UsesFSharp20PlusQuotations=false - InvalidateEvent=(new Event<_>()).Publish - IsProviderGenerated = true - QualifiedName= Some (assembly.PUntaint((fun a -> a.FullName), m)) - Contents = NewCcuContents ilScopeRef m ilShortAssemName (NewEmptyModuleOrNamespaceType Namespace) - ILScopeRef = ilScopeRef - Stamp = newStamp() - SourceCodeDirectory = "" - FileName = Some fileName - MemberSignatureEquality = (fun ty1 ty2 -> Tastops.typeEquivAux EraseAll g ty1 ty2) - ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty) - TryGetILModuleDef = (fun () -> Some ilModule) - TypeForwarders = Map.empty } - - let ccu = CcuThunk.Create(ilShortAssemName, ccuData) - let ccuinfo = - { FSharpViewOfMetadata=ccu - ILScopeRef = ilScopeRef - AssemblyAutoOpenAttributes = [] - AssemblyInternalsVisibleToAttributes = [] - IsProviderGenerated = true - TypeProviders=[] - FSharpOptimizationData = notlazy None } - tcImports.RegisterCcu ccuinfo - // Yes, it is generative - true, dllinfo.ProviderGeneratedStaticLinkMap - - member tcImports.RecordGeneratedTypeRoot root = - // checking if given ProviderGeneratedType was already recorded before (probably for another set of static parameters) - let (ProviderGeneratedType(_, ilTyRef, _)) = root - let index = - match generatedTypeRoots.TryGetValue ilTyRef with - | true, (index, _) -> index - | false, _ -> generatedTypeRoots.Count - generatedTypeRoots.[ilTyRef] <- (index, root) - - member tcImports.ProviderGeneratedTypeRoots = - generatedTypeRoots.Values - |> Seq.sortBy fst - |> Seq.map snd - |> Seq.toList -#endif - - member private tcImports.AttachDisposeAction action = - CheckDisposed() - disposeActions <- action :: disposeActions - -#if !NO_EXTENSIONTYPING - member private tcImports.AttachDisposeTypeProviderAction action = - CheckDisposed() - disposeTypeProviderActions <- action :: disposeTypeProviderActions -#endif - - // Note: the returned binary reader is associated with the tcImports, i.e. when the tcImports are closed - // then the reader is closed. - member tcImports.OpenILBinaryModule(ctok, filename, m) = - try - CheckDisposed() - let tcConfig = tcConfigP.Get ctok - let pdbDirPath = - // We open the pdb file if one exists parallel to the binary we - // are reading, so that --standalone will preserve debug information. - if tcConfig.openDebugInformationForLaterStaticLinking then - let pdbDir = try Filename.directoryName filename with _ -> "." - let pdbFile = (try Filename.chopExtension filename with _ -> filename) + ".pdb" - - if FileSystem.SafeExists pdbFile then - if verbose then dprintf "reading PDB file %s from directory %s\n" pdbFile pdbDir - Some pdbDir - else - None - else - None - - let ilILBinaryReader = - OpenILBinary (filename, tcConfig.reduceMemoryUsage, pdbDirPath, tcConfig.shadowCopyReferences, tcConfig.tryGetMetadataSnapshot) - - tcImports.AttachDisposeAction(fun _ -> (ilILBinaryReader :> IDisposable).Dispose()) - ilILBinaryReader.ILModuleDef, ilILBinaryReader.ILAssemblyRefs - with e -> - error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), m)) - - (* auxModTable is used for multi-module assemblies *) - member tcImports.MkLoaderForMultiModuleILAssemblies ctok m = - CheckDisposed() - let auxModTable = HashMultiMap(10, HashIdentity.Structural) - fun viewedScopeRef -> - - let tcConfig = tcConfigP.Get ctok - match viewedScopeRef with - | ILScopeRef.Module modref -> - let key = modref.Name - if not (auxModTable.ContainsKey key) then - let resolution = tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, AssemblyReference(m, key, None)) |> Option.get - let ilModule, _ = tcImports.OpenILBinaryModule(ctok, resolution.resolvedPath, m) - auxModTable.[key] <- ilModule - auxModTable.[key] - - | _ -> - error(InternalError("Unexpected ILScopeRef.Local or ILScopeRef.Assembly in exported type table", m)) - - member tcImports.IsAlreadyRegistered nm = - CheckDisposed() - tcImports.GetDllInfos() |> List.exists (fun dll -> - match dll.ILScopeRef with - | ILScopeRef.Assembly a -> a.Name = nm - | _ -> false) - - member tcImports.GetImportMap() = - CheckDisposed() - let loaderInterface = - { new Import.AssemblyLoader with - member x.FindCcuFromAssemblyRef (ctok, m, ilAssemblyRef) = - tcImports.FindCcuFromAssemblyRef (ctok, m, ilAssemblyRef) -#if !NO_EXTENSIONTYPING - member x.GetProvidedAssemblyInfo (ctok, m, assembly) = tcImports.GetProvidedAssemblyInfo (ctok, m, assembly) - member x.RecordGeneratedTypeRoot root = tcImports.RecordGeneratedTypeRoot root -#endif - } - new Import.ImportMap (tcImports.GetTcGlobals(), loaderInterface) - - // Note the tcGlobals are only available once mscorlib and fslib have been established. For TcImports, - // they are logically only needed when converting AbsIL data structures into F# data structures, and - // when converting AbsIL types in particular, since these types are normalized through the tables - // in the tcGlobals (E.g. normalizing 'System.Int32' to 'int'). On the whole ImportILAssembly doesn't - // actually convert AbsIL types - it only converts the outer shell of type definitions - the vast majority of - // types such as those in method signatures are currently converted on-demand. However ImportILAssembly does have to - // convert the types that are constraints in generic parameters, which was the original motivation for making sure that - // ImportILAssembly had a tcGlobals available when it really needs it. - member tcImports.GetTcGlobals() : TcGlobals = - CheckDisposed() - match tcGlobals with - | Some g -> g - | None -> - match importsBase with - | Some b -> b.GetTcGlobals() - | None -> failwith "unreachable: GetGlobals - are the references to mscorlib.dll and FSharp.Core.dll valid?" - - member private tcImports.SetILGlobals ilg = - CheckDisposed() - ilGlobalsOpt <- Some ilg - - member private tcImports.SetTcGlobals g = - CheckDisposed() - tcGlobals <- Some g - -#if !NO_EXTENSIONTYPING - member private tcImports.InjectProvidedNamespaceOrTypeIntoEntity - (typeProviderEnvironment, - tcConfig: TcConfig, - m, entity: Entity, - injectedNamespace, remainingNamespace, - provider, - st: Tainted option) = - match remainingNamespace with - | next :: rest -> - // Inject the namespace entity - match entity.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind next with - | Some childEntity -> - tcImports.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, childEntity, next :: injectedNamespace, rest, provider, st) - | None -> - // Build up the artificial namespace if there is not a real one. - let cpath = CompPath(ILScopeRef.Local, injectedNamespace |> List.rev |> List.map (fun n -> (n, ModuleOrNamespaceKind.Namespace)) ) - let newNamespace = NewModuleOrNamespace (Some cpath) taccessPublic (ident(next, rangeStartup)) XmlDoc.Empty [] (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType Namespace)) - entity.ModuleOrNamespaceType.AddModuleOrNamespaceByMutation newNamespace - tcImports.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, newNamespace, next :: injectedNamespace, rest, provider, st) - | [] -> - match st with - | Some st -> - // Inject the wrapper type into the provider assembly. - // - // Generated types get properly injected into the provided (i.e. generated) assembly CCU in tc.fs - - let importProvidedType t = Import.ImportProvidedType (tcImports.GetImportMap()) m t - let isSuppressRelocate = tcConfig.isInteractive || st.PUntaint((fun st -> st.IsSuppressRelocate), m) - let newEntity = Construct.NewProvidedTycon(typeProviderEnvironment, st, importProvidedType, isSuppressRelocate, m) - entity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity - | None -> () - - entity.entity_tycon_repr <- - match entity.TypeReprInfo with - // This is the first extension - | TNoRepr -> - TProvidedNamespaceExtensionPoint(typeProviderEnvironment, [provider]) - - // Add to the existing list of extensions - | TProvidedNamespaceExtensionPoint(resolutionFolder, prior) as repr -> - if not(prior |> List.exists(fun r->Tainted.EqTainted r provider)) then - TProvidedNamespaceExtensionPoint(resolutionFolder, provider :: prior) - else - repr - - | _ -> failwith "Unexpected representation in namespace entity referred to by a type provider" - - member tcImportsStrong.ImportTypeProviderExtensions - (ctok, tcConfig: TcConfig, - fileNameOfRuntimeAssembly, - ilScopeRefOfRuntimeAssembly, - runtimeAssemblyAttributes: ILAttribute list, - entityToInjectInto, invalidateCcu: Event<_>, m) = - - let startingErrorCount = CompileThreadStatic.ErrorLogger.ErrorCount - - // Find assembly level TypeProviderAssemblyAttributes. These will point to the assemblies that - // have class which implement ITypeProvider and which have TypeProviderAttribute on them. - let designTimeAssemblyNames = - runtimeAssemblyAttributes - |> List.choose (TryDecodeTypeProviderAssemblyAttr (defaultArg ilGlobalsOpt EcmaMscorlibILGlobals)) - // If no design-time assembly is specified, use the runtime assembly - |> List.map (function null -> fileNameOfRuntimeAssembly | s -> s) - // For each simple name of a design-time assembly, we take the first matching one in the order they are - // specified in the attributes - |> List.distinctBy (fun s -> try Path.GetFileNameWithoutExtension s with _ -> s) - - if not (List.isEmpty designTimeAssemblyNames) then - - // Find the SystemRuntimeAssemblyVersion value to report in the TypeProviderConfig. - let primaryAssemblyVersion = - let primaryAssemblyRef = tcConfig.PrimaryAssemblyDllReference() - let resolution = tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, primaryAssemblyRef) |> Option.get - // MSDN: this method causes the file to be opened and closed, but the assembly is not added to this domain - let name = System.Reflection.AssemblyName.GetAssemblyName(resolution.resolvedPath) - name.Version - - let typeProviderEnvironment = - { resolutionFolder = tcConfig.implicitIncludeDir - outputFile = tcConfig.outputFile - showResolutionMessages = tcConfig.showExtensionTypeMessages - referencedAssemblies = Array.distinct [| for r in tcImportsStrong.AllAssemblyResolutions() -> r.resolvedPath |] - temporaryFolder = FileSystem.GetTempPathShim() } - - // The type provider should not hold strong references to disposed - // TcImport objects. So the callbacks provided in the type provider config - // dispatch via a thunk which gets set to a non-resource-capturing - // failing function when the object is disposed. - let systemRuntimeContainsType = - // NOTE: do not touch this, edit: but we did, we had no choice - TPs cannot hold a strong reference on TcImports "ever". - let tcImports = tcImportsWeak - let mutable systemRuntimeContainsTypeRef = fun typeName -> tcImports.SystemRuntimeContainsType typeName - tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> systemRuntimeContainsTypeRef <- fun _ -> raise (System.ObjectDisposedException("The type provider has been disposed"))) - fun arg -> systemRuntimeContainsTypeRef arg - - let providers = [ - for designTimeAssemblyName in designTimeAssemblyNames do - yield! ExtensionTyping.GetTypeProvidersOfAssembly(fileNameOfRuntimeAssembly, - ilScopeRefOfRuntimeAssembly, - designTimeAssemblyName, - typeProviderEnvironment, - tcConfig.isInvalidationSupported, - tcConfig.isInteractive, - systemRuntimeContainsType, - primaryAssemblyVersion, - tcConfig.compilerToolPaths, - m) ] - // Note, type providers are disposable objects. The TcImports owns the provider objects - when/if it is disposed, the providers are disposed. - // We ignore all exceptions from provider disposal. - for provider in providers do - tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> - try - provider.PUntaintNoFailure(fun x -> x).Dispose() - with e -> - ()) - - // Add the invalidation signal handlers to each provider - for provider in providers do - provider.PUntaint((fun tp -> - - // Register the type provider invalidation handler. - // - // We are explicit about what the handler closure captures to help reason about the - // lifetime of captured objects, especially in case the type provider instance gets leaked - // or keeps itself alive mistakenly, e.g. via some global state in the type provider instance. - // - // The closure captures - // 1. an Event value, ultimately this is made available in all CCus as ccu.InvalidateEvent - // 2. any handlers registered to ccu.InvalidateEvent - // 3. a message string - // - // Note that the invalidation handler does not explicitly capture the TcImports. - // The only place where handlers are registered is to ccu.InvalidateEvent is in IncrementalBuilder.fs. - - let capturedInvalidateCcu = invalidateCcu - let capturedMessage = "The provider '" + fileNameOfRuntimeAssembly + "' reported a change" - let handler = tp.Invalidate.Subscribe(fun _ -> capturedInvalidateCcu.Trigger (capturedMessage)) - - // When the TcImports is disposed we detach the invalidation callback - tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> try handler.Dispose() with _ -> ())), m) - - match providers with - | [] -> - warning(Error(FSComp.SR.etHostingAssemblyFoundWithoutHosts(fileNameOfRuntimeAssembly, typeof.FullName), m)) - | _ -> - -#if DEBUG - if typeProviderEnvironment.showResolutionMessages then - dprintfn "Found extension type hosting hosting assembly '%s' with the following extensions:" fileNameOfRuntimeAssembly - providers |> List.iter(fun provider ->dprintfn " %s" (ExtensionTyping.DisplayNameOfTypeProvider(provider.TypeProvider, m))) -#endif - - for provider in providers do - try - // Inject an entity for the namespace, or if one already exists, then record this as a provider - // for that namespace. - let rec loop (providedNamespace: Tainted) = - let path = ExtensionTyping.GetProvidedNamespaceAsPath(m, provider, providedNamespace.PUntaint((fun r -> r.NamespaceName), m)) - tcImportsStrong.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, entityToInjectInto, [], path, provider, None) - - // Inject entities for the types returned by provider.GetTypes(). - // - // NOTE: The types provided by GetTypes() are available for name resolution - // when the namespace is "opened". This is part of the specification of the language - // feature. - let tys = providedNamespace.PApplyArray((fun provider -> provider.GetTypes()), "GetTypes", m) - let ptys = [| for ty in tys -> ty.PApply((fun ty -> ty |> ProvidedType.CreateNoContext), m) |] - for st in ptys do - tcImportsStrong.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, entityToInjectInto, [], path, provider, Some st) - - for providedNestedNamespace in providedNamespace.PApplyArray((fun provider -> provider.GetNestedNamespaces()), "GetNestedNamespaces", m) do - loop providedNestedNamespace - - RequireCompilationThread ctok // IProvidedType.GetNamespaces is an example of a type provider call - let providedNamespaces = provider.PApplyArray((fun r -> r.GetNamespaces()), "GetNamespaces", m) - - for providedNamespace in providedNamespaces do - loop providedNamespace - with e -> - errorRecovery e m - - if startingErrorCount Option.isSome - - // Add a referenced assembly - // - // Retargetable assembly refs are required for binaries that must run - // against DLLs supported by multiple publishers. For example - // Compact Framework binaries must use this. However it is not - // clear when else it is required, e.g. for Mono. - - member tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo: ImportedBinary) = - CheckDisposed() - let tcConfig = tcConfigP.Get ctok - assert dllinfo.RawMetadata.TryGetILModuleDef().IsSome - let ilModule = dllinfo.RawMetadata.TryGetILModuleDef().Value - let ilScopeRef = dllinfo.ILScopeRef - let aref = - match ilScopeRef with - | ILScopeRef.Assembly aref -> aref - | _ -> error(InternalError("PrepareToImportReferencedILAssembly: cannot reference .NET netmodules directly, reference the containing assembly instead", m)) - - let nm = aref.Name - if verbose then dprintn ("Converting IL assembly to F# data structures "+nm) - let auxModuleLoader = tcImports.MkLoaderForMultiModuleILAssemblies ctok m - let invalidateCcu = new Event<_>() - let ccu = Import.ImportILAssembly(tcImports.GetImportMap, m, auxModuleLoader, ilScopeRef, tcConfig.implicitIncludeDir, Some filename, ilModule, invalidateCcu.Publish) - - let ilg = defaultArg ilGlobalsOpt EcmaMscorlibILGlobals - - let ccuinfo = - { FSharpViewOfMetadata=ccu - ILScopeRef = ilScopeRef - AssemblyAutoOpenAttributes = GetAutoOpenAttributes ilg ilModule - AssemblyInternalsVisibleToAttributes = GetInternalsVisibleToAttributes ilg ilModule -#if !NO_EXTENSIONTYPING - IsProviderGenerated = false - TypeProviders = [] -#endif - FSharpOptimizationData = notlazy None } - tcImports.RegisterCcu ccuinfo - let phase2 () = -#if !NO_EXTENSIONTYPING - ccuinfo.TypeProviders <- tcImports.ImportTypeProviderExtensions (ctok, tcConfig, filename, ilScopeRef, ilModule.ManifestOfAssembly.CustomAttrs.AsList, ccu.Contents, invalidateCcu, m) -#endif - [ResolvedImportedAssembly ccuinfo] - phase2 - - member tcImports.PrepareToImportReferencedFSharpAssembly (ctok, m, filename, dllinfo: ImportedBinary) = - CheckDisposed() -#if !NO_EXTENSIONTYPING - let tcConfig = tcConfigP.Get ctok -#endif - let ilModule = dllinfo.RawMetadata - let ilScopeRef = dllinfo.ILScopeRef - let ilShortAssemName = getNameOfScopeRef ilScopeRef - if verbose then dprintn ("Converting F# assembly to F# data structures "+(getNameOfScopeRef ilScopeRef)) - if verbose then dprintn ("Relinking interface info from F# assembly "+ilShortAssemName) - let optDataReaders = ilModule.GetRawFSharpOptimizationData(m, ilShortAssemName, filename) - - let ccuRawDataAndInfos = - ilModule.GetRawFSharpSignatureData(m, ilShortAssemName, filename) - |> List.map (fun (ccuName, sigDataReader) -> - let data = GetSignatureData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader) - - let optDatas = Map.ofList optDataReaders - - let minfo: PickledCcuInfo = data.RawData - let mspec = minfo.mspec - -#if !NO_EXTENSIONTYPING - let invalidateCcu = new Event<_>() -#endif - - let codeDir = minfo.compileTimeWorkingDir - let ccuData: CcuData = - { ILScopeRef=ilScopeRef - Stamp = newStamp() - FileName = Some filename - QualifiedName= Some(ilScopeRef.QualifiedName) - SourceCodeDirectory = codeDir (* note: in some cases we fix up this information later *) - IsFSharp=true - Contents = mspec -#if !NO_EXTENSIONTYPING - InvalidateEvent=invalidateCcu.Publish - IsProviderGenerated = false - ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty) -#endif - TryGetILModuleDef = ilModule.TryGetILModuleDef - UsesFSharp20PlusQuotations = minfo.usesQuotations - MemberSignatureEquality= (fun ty1 ty2 -> Tastops.typeEquivAux EraseAll (tcImports.GetTcGlobals()) ty1 ty2) - TypeForwarders = ImportILAssemblyTypeForwarders(tcImports.GetImportMap, m, ilModule.GetRawTypeForwarders()) } - - let ccu = CcuThunk.Create(ccuName, ccuData) - - let optdata = - lazy - (match Map.tryFind ccuName optDatas with - | None -> - if verbose then dprintf "*** no optimization data for CCU %s, was DLL compiled with --no-optimization-data??\n" ccuName - None - | Some info -> - let data = GetOptimizationData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), info) - let res = data.OptionalFixup(fun nm -> availableToOptionalCcu(tcImports.FindCcu(ctok, m, nm, lookupOnly=false))) - if verbose then dprintf "found optimization data for CCU %s\n" ccuName - Some res) - let ilg = defaultArg ilGlobalsOpt EcmaMscorlibILGlobals - let ccuinfo = - { FSharpViewOfMetadata=ccu - AssemblyAutoOpenAttributes = ilModule.GetAutoOpenAttributes ilg - AssemblyInternalsVisibleToAttributes = ilModule.GetInternalsVisibleToAttributes ilg - FSharpOptimizationData=optdata -#if !NO_EXTENSIONTYPING - IsProviderGenerated = false - TypeProviders = [] -#endif - ILScopeRef = ilScopeRef } - let phase2() = -#if !NO_EXTENSIONTYPING - match ilModule.TryGetILModuleDef() with - | None -> () // no type providers can be used without a real IL Module present - | Some ilModule -> - ccuinfo.TypeProviders <- tcImports.ImportTypeProviderExtensions (ctok, tcConfig, filename, ilScopeRef, ilModule.ManifestOfAssembly.CustomAttrs.AsList, ccu.Contents, invalidateCcu, m) -#else - () -#endif - data, ccuinfo, phase2) - - // Register all before relinking to cope with mutually-referential ccus - ccuRawDataAndInfos |> List.iter (p23 >> tcImports.RegisterCcu) - let phase2 () = - (* Relink *) - (* dprintf "Phase2: %s\n" filename; REMOVE DIAGNOSTICS *) - ccuRawDataAndInfos |> List.iter (fun (data, _, _) -> data.OptionalFixup(fun nm -> availableToOptionalCcu(tcImports.FindCcu(ctok, m, nm, lookupOnly=false))) |> ignore) -#if !NO_EXTENSIONTYPING - ccuRawDataAndInfos |> List.iter (fun (_, _, phase2) -> phase2()) -#endif - ccuRawDataAndInfos |> List.map p23 |> List.map ResolvedImportedAssembly - phase2 - - - // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable. - member tcImports.RegisterAndPrepareToImportReferencedDll (ctok, r: AssemblyResolution) : Cancellable<_ * (unit -> AvailableImportedAssembly list)> = - cancellable { - CheckDisposed() - let m = r.originalReference.Range - let filename = r.resolvedPath - let! contentsOpt = - cancellable { - match r.ProjectReference with - | Some ilb -> return! ilb.EvaluateRawContents ctok - | None -> return None - } - - let assemblyData = - match contentsOpt with - | Some ilb -> ilb - | None -> - let ilModule, ilAssemblyRefs = tcImports.OpenILBinaryModule(ctok, filename, m) - RawFSharpAssemblyDataBackedByFileOnDisk (ilModule, ilAssemblyRefs) :> IRawFSharpAssemblyData - - let ilShortAssemName = assemblyData.ShortAssemblyName - let ilScopeRef = assemblyData.ILScopeRef - - if tcImports.IsAlreadyRegistered ilShortAssemName then - let dllinfo = tcImports.FindDllInfo(ctok, m, ilShortAssemName) - let phase2() = [tcImports.FindCcuInfo(ctok, m, ilShortAssemName, lookupOnly=true)] - return dllinfo, phase2 - else - let dllinfo = - { RawMetadata=assemblyData - FileName=filename -#if !NO_EXTENSIONTYPING - ProviderGeneratedAssembly=None - IsProviderGenerated=false - ProviderGeneratedStaticLinkMap = None -#endif - ILScopeRef = ilScopeRef - ILAssemblyRefs = assemblyData.ILAssemblyRefs } - tcImports.RegisterDll dllinfo - let ilg = defaultArg ilGlobalsOpt EcmaMscorlibILGlobals - let phase2 = - if assemblyData.HasAnyFSharpSignatureDataAttribute then - if not (assemblyData.HasMatchingFSharpSignatureDataAttribute ilg) then - errorR(Error(FSComp.SR.buildDifferentVersionMustRecompile filename, m)) - tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo) - else - try - tcImports.PrepareToImportReferencedFSharpAssembly (ctok, m, filename, dllinfo) - with e -> error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), m)) - else - tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo) - return dllinfo, phase2 - } - - // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable. - member tcImports.RegisterAndImportReferencedAssemblies (ctok, nms: AssemblyResolution list) = - cancellable { - CheckDisposed() - let! results = - nms |> Cancellable.each (fun nm -> - cancellable { - try - let! res = tcImports.RegisterAndPrepareToImportReferencedDll (ctok, nm) - return Some res - with e -> - errorR(Error(FSComp.SR.buildProblemReadingAssembly(nm.resolvedPath, e.Message), nm.originalReference.Range)) - return None - }) - - let dllinfos, phase2s = results |> List.choose id |> List.unzip - let ccuinfos = (List.collect (fun phase2 -> phase2()) phase2s) - return dllinfos, ccuinfos - } - - /// Note that implicit loading is not used for compilations from MSBuild, which passes ``--noframework`` - /// Implicit loading is done in non-cancellation mode. Implicit loading is never used in the language service, so - /// no cancellation is needed. - member tcImports.ImplicitLoadIfAllowed (ctok, m, assemblyName, lookupOnly) = - CheckDisposed() - // If the user is asking for the default framework then also try to resolve other implicit assemblies as they are discovered. - // Using this flag to mean 'allow implicit discover of assemblies'. - let tcConfig = tcConfigP.Get ctok - if not lookupOnly && tcConfig.implicitlyResolveAssemblies then - let tryFile speculativeFileName = - let foundFile = tcImports.TryResolveAssemblyReference (ctok, AssemblyReference (m, speculativeFileName, None), ResolveAssemblyReferenceMode.Speculative) - match foundFile with - | OkResult (warns, res) -> - ReportWarnings warns - tcImports.RegisterAndImportReferencedAssemblies(ctok, res) |> Cancellable.runWithoutCancellation |> ignore - true - | ErrorResult (_warns, _err) -> - // Throw away warnings and errors - this is speculative loading - false - - if tryFile (assemblyName + ".dll") then () - else tryFile (assemblyName + ".exe") |> ignore - -#if !NO_EXTENSIONTYPING - member tcImports.TryFindProviderGeneratedAssemblyByName(ctok, assemblyName: string) : System.Reflection.Assembly option = - // The assembly may not be in the resolutions, but may be in the load set including EST injected assemblies - match tcImports.TryFindDllInfo (ctok, range0, assemblyName, lookupOnly=true) with - | Some res -> - // Provider-generated assemblies don't necessarily have an on-disk representation we can load. - res.ProviderGeneratedAssembly - | _ -> None -#endif - - /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcImports.TryFindExistingFullyQualifiedPathBySimpleAssemblyName (ctok, simpleAssemName) : string option = - resolutions.TryFindBySimpleAssemblyName (ctok, simpleAssemName) |> Option.map (fun r -> r.resolvedPath) - - /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(ctok, assemblyRef: ILAssemblyRef) : string option = - resolutions.TryFindByExactILAssemblyRef (ctok, assemblyRef) |> Option.map (fun r -> r.resolvedPath) - - member tcImports.TryResolveAssemblyReference(ctok, assemblyReference: AssemblyReference, mode: ResolveAssemblyReferenceMode) : OperationResult = - let tcConfig = tcConfigP.Get ctok - // First try to lookup via the original reference text. - match resolutions.TryFindByOriginalReference assemblyReference with - | Some assemblyResolution -> - ResultD [assemblyResolution] - | None -> -#if NO_MSBUILD_REFERENCE_RESOLUTION - try - ResultD [tcConfig.ResolveLibWithDirectories assemblyReference] - with e -> - ErrorD e -#else - // Next try to lookup up by the exact full resolved path. - match resolutions.TryFindByResolvedPath assemblyReference.Text with - | Some assemblyResolution -> - ResultD [assemblyResolution] - | None -> - if tcConfigP.Get(ctok).useSimpleResolution then - let action = - match mode with - | ResolveAssemblyReferenceMode.ReportErrors -> CcuLoadFailureAction.RaiseError - | ResolveAssemblyReferenceMode.Speculative -> CcuLoadFailureAction.ReturnNone - match tcConfig.ResolveLibWithDirectories (action, assemblyReference) with - | Some resolved -> - resolutions <- resolutions.AddResolutionResults [resolved] - ResultD [resolved] - | None -> - ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) - else - // This is a previously unencountered assembly. Resolve it and add it to the list. - // But don't cache resolution failures because the assembly may appear on the disk later. - let resolved, unresolved = TcConfig.TryResolveLibsUsingMSBuildRules(tcConfig, [ assemblyReference ], assemblyReference.Range, mode) - match resolved, unresolved with - | (assemblyResolution :: _, _) -> - resolutions <- resolutions.AddResolutionResults resolved - ResultD [assemblyResolution] - | (_, _ :: _) -> - resolutions <- resolutions.AddUnresolvedReferences unresolved - ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) - | [], [] -> - // Note, if mode=ResolveAssemblyReferenceMode.Speculative and the resolution failed then TryResolveLibsUsingMSBuildRules returns - // the empty list and we convert the failure into an AssemblyNotResolved here. - ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) - -#endif - - - member tcImports.ResolveAssemblyReference(ctok, assemblyReference, mode) : AssemblyResolution list = - CommitOperationResult(tcImports.TryResolveAssemblyReference(ctok, assemblyReference, mode)) - - // Note: This returns a TcImports object. However, framework TcImports are not currently disposed. The only reason - // we dispose TcImports is because we need to dispose type providers, and type providers are never included in the framework DLL set. - // If a framework set ever includes type providers, you will not have to worry about explicitly calling Dispose as the Finalizer will handle it. - static member BuildFrameworkTcImports (ctok, tcConfigP: TcConfigProvider, frameworkDLLs, nonFrameworkDLLs) = - cancellable { - - let tcConfig = tcConfigP.Get ctok - let tcResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(ctok, tcConfig, frameworkDLLs, []) - let tcAltResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(ctok, tcConfig, nonFrameworkDLLs, []) - - let frameworkTcImports = new TcImports(tcConfigP, tcResolutions, None, None, tcConfig.compilationThread) - - // Fetch the primaryAssembly from the referenced assemblies otherwise - let primaryAssemblyReference = - let path = frameworkDLLs |> List.tryFind(fun dll -> String.Compare(Path.GetFileNameWithoutExtension(dll.resolvedPath), tcConfig.primaryAssembly.Name, StringComparison.OrdinalIgnoreCase) = 0) - match path with - | Some p -> AssemblyReference(range0, p.resolvedPath, None) - | None -> tcConfig.PrimaryAssemblyDllReference() - - let primaryAssemblyResolution = frameworkTcImports.ResolveAssemblyReference(ctok, primaryAssemblyReference, ResolveAssemblyReferenceMode.ReportErrors) - let! primaryAssem = frameworkTcImports.RegisterAndImportReferencedAssemblies(ctok, primaryAssemblyResolution) - let primaryScopeRef = - match primaryAssem with - | (_, [ResolvedImportedAssembly ccu]) -> ccu.FSharpViewOfMetadata.ILScopeRef - | _ -> failwith "unexpected" - - let primaryAssemblyResolvedPath = - match primaryAssemblyResolution with - | [primaryAssemblyResolution] -> primaryAssemblyResolution.resolvedPath - | _ -> failwith "unexpected" - - let resolvedAssemblies = tcResolutions.GetAssemblyResolutions() - - let readerSettings: ILReaderOptions = - { pdbDirPath=None - reduceMemoryUsage = tcConfig.reduceMemoryUsage - metadataOnly = MetadataOnlyFlag.Yes - tryGetMetadataSnapshot = tcConfig.tryGetMetadataSnapshot } - - let tryFindAssemblyByExportedType manifest (exportedType: ILExportedTypeOrForwarder) = - match exportedType.ScopeRef, primaryScopeRef with - | ILScopeRef.Assembly aref1, ILScopeRef.Assembly aref2 when aref1.EqualsIgnoringVersion aref2 -> - mkRefToILAssembly manifest - |> Some - | _ -> - None - - let tryFindAssemblyThatForwardsToPrimaryAssembly manifest = - manifest.ExportedTypes.TryFindByName "System.Object" - |> Option.bind (tryFindAssemblyByExportedType manifest) - - // Determine what other assemblies could have been the primary assembly - // by checking to see if "System.Object" is an exported type. - let assembliesThatForwardToPrimaryAssembly = - resolvedAssemblies - |> List.choose (fun resolvedAssembly -> - if primaryAssemblyResolvedPath <> resolvedAssembly.resolvedPath then - let reader = OpenILModuleReader resolvedAssembly.resolvedPath readerSettings - reader.ILModuleDef.Manifest - |> Option.bind tryFindAssemblyThatForwardsToPrimaryAssembly - else - None) - - let ilGlobals = mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly) - frameworkTcImports.SetILGlobals ilGlobals - - // Load the rest of the framework DLLs all at once (they may be mutually recursive) - let! _assemblies = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, resolvedAssemblies) - - // These are the DLLs we can search for well-known types - let sysCcus = - [| for ccu in frameworkTcImports.GetCcusInDeclOrder() do - //printfn "found sys ccu %s" ccu.AssemblyName - yield ccu |] - - //for ccu in nonFrameworkDLLs do - // printfn "found non-sys ccu %s" ccu.resolvedPath - - let tryFindSysTypeCcu path typeName = - sysCcus |> Array.tryFind (fun ccu -> ccuHasType ccu path typeName) - - let fslibCcu = - if tcConfig.compilingFslib then - // When compiling FSharp.Core.dll, the fslibCcu reference to FSharp.Core.dll is a delayed ccu thunk fixed up during type checking - CcuThunk.CreateDelayed getFSharpCoreLibraryName - else - let fslibCcuInfo = - let coreLibraryReference = tcConfig.CoreLibraryDllReference() - - let resolvedAssemblyRef = - match tcResolutions.TryFindByOriginalReference coreLibraryReference with - | Some resolution -> Some resolution - | _ -> - // Are we using a "non-canonical" FSharp.Core? - match tcAltResolutions.TryFindByOriginalReference coreLibraryReference with - | Some resolution -> Some resolution - | _ -> tcResolutions.TryFindByOriginalReferenceText (getFSharpCoreLibraryName) // was the ".dll" elided? - - match resolvedAssemblyRef with - | Some coreLibraryResolution -> - match frameworkTcImports.RegisterAndImportReferencedAssemblies(ctok, [coreLibraryResolution]) |> Cancellable.runWithoutCancellation with - | (_, [ResolvedImportedAssembly fslibCcuInfo ]) -> fslibCcuInfo - | _ -> - error(InternalError("BuildFrameworkTcImports: no successful import of "+coreLibraryResolution.resolvedPath, coreLibraryResolution.originalReference.Range)) - | None -> - error(InternalError(sprintf "BuildFrameworkTcImports: no resolution of '%s'" coreLibraryReference.Text, rangeStartup)) - IlxSettings.ilxFsharpCoreLibAssemRef <- - (let scoref = fslibCcuInfo.ILScopeRef - match scoref with - | ILScopeRef.Assembly aref -> Some aref - | ILScopeRef.Local | ILScopeRef.Module _ | ILScopeRef.PrimaryAssembly -> - error(InternalError("not ILScopeRef.Assembly", rangeStartup))) - fslibCcuInfo.FSharpViewOfMetadata - - // OK, now we have both mscorlib.dll and FSharp.Core.dll we can create TcGlobals - let tcGlobals = TcGlobals(tcConfig.compilingFslib, ilGlobals, fslibCcu, - tcConfig.implicitIncludeDir, tcConfig.mlCompatibility, - tcConfig.isInteractive, tryFindSysTypeCcu, tcConfig.emitDebugInfoInQuotations, - tcConfig.noDebugData, tcConfig.pathMap, tcConfig.langVersion) - -#if DEBUG - // the global_g reference cell is used only for debug printing - global_g <- Some tcGlobals -#endif - // do this prior to parsing, since parsing IL assembly code may refer to mscorlib -#if !NO_INLINE_IL_PARSER - FSharp.Compiler.AbstractIL.Internal.AsciiConstants.parseILGlobals <- tcGlobals.ilg -#endif - frameworkTcImports.SetTcGlobals tcGlobals - return tcGlobals, frameworkTcImports - } - - member tcImports.ReportUnresolvedAssemblyReferences knownUnresolved = - // Report that an assembly was not resolved. - let reportAssemblyNotResolved(file, originalReferences: AssemblyReference list) = - originalReferences |> List.iter(fun originalReference -> errorR(AssemblyNotResolved(file, originalReference.Range))) - knownUnresolved - |> List.map (function UnresolvedAssemblyReference(file, originalReferences) -> file, originalReferences) - |> List.iter reportAssemblyNotResolved - - override tcImports.Finalize () = - dispose () - - static member BuildNonFrameworkTcImports (ctok, tcConfigP: TcConfigProvider, tcGlobals: TcGlobals, baseTcImports, nonFrameworkReferences, knownUnresolved) = - cancellable { - let tcConfig = tcConfigP.Get ctok - let tcResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(ctok, tcConfig, nonFrameworkReferences, knownUnresolved) - let references = tcResolutions.GetAssemblyResolutions() - let tcImports = new TcImports(tcConfigP, tcResolutions, Some baseTcImports, Some tcGlobals.ilg, tcConfig.compilationThread) - let! _assemblies = tcImports.RegisterAndImportReferencedAssemblies(ctok, references) - tcImports.ReportUnresolvedAssemblyReferences knownUnresolved - return tcImports - } - - static member BuildTcImports(ctok, tcConfigP: TcConfigProvider) = - cancellable { - let tcConfig = tcConfigP.Get ctok - //let foundationalTcImports, tcGlobals = TcImports.BuildFoundationalTcImports tcConfigP - let frameworkDLLs, nonFrameworkReferences, knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) - let! tcGlobals, frameworkTcImports = TcImports.BuildFrameworkTcImports (ctok, tcConfigP, frameworkDLLs, nonFrameworkReferences) - let! tcImports = TcImports.BuildNonFrameworkTcImports(ctok, tcConfigP, tcGlobals, frameworkTcImports, nonFrameworkReferences, knownUnresolved) - return tcGlobals, tcImports - } - - interface System.IDisposable with - member tcImports.Dispose() = - dispose () - GC.SuppressFinalize tcImports - - override tcImports.ToString() = "TcImports(...)" - -/// Process #r in F# Interactive. -/// Adds the reference to the tcImports and add the ccu to the type checking environment. -let RequireDLL (ctok, tcImports: TcImports, tcEnv, thisAssemblyName, m, file, assemblyReferenceAdded: string -> unit) = - let resolutions = CommitOperationResult(tcImports.TryResolveAssemblyReference(ctok, AssemblyReference(m, file, None), ResolveAssemblyReferenceMode.ReportErrors)) - let dllinfos, ccuinfos = tcImports.RegisterAndImportReferencedAssemblies(ctok, resolutions) |> Cancellable.runWithoutCancellation - - let asms = - ccuinfos |> List.map (function - | ResolvedImportedAssembly asm -> asm - | UnresolvedImportedAssembly assemblyName -> error(Error(FSComp.SR.buildCouldNotResolveAssemblyRequiredByFile(assemblyName, file), m))) - - let g = tcImports.GetTcGlobals() - let amap = tcImports.GetImportMap() - let buildTcEnv tcEnv asm = - let tcEnv = AddCcuToTcEnv(g, amap, m, tcEnv, thisAssemblyName, asm.FSharpViewOfMetadata, asm.AssemblyAutoOpenAttributes, asm.AssemblyInternalsVisibleToAttributes) - match asm.FSharpViewOfMetadata.FileName with - | Some asmPath -> assemblyReferenceAdded asmPath - | None -> () - tcEnv - let tcEnv = (tcEnv, asms) ||> List.fold buildTcEnv - tcEnv, (dllinfos, asms) - -let ProcessMetaCommandsFromInput - (nowarnF: 'state -> range * string -> 'state, - dllRequireF: 'state -> range * string -> 'state, - packageRequireF: 'state -> DependencyManagerIntegration.IDependencyManagerProvider * range * string -> 'state, - loadSourceF: 'state -> range * string -> unit) - (tcConfig:TcConfigBuilder, inp, pathOfMetaCommandSource, state0) = - - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - - let canHaveScriptMetaCommands = - match inp with - | ParsedInput.SigFile (_) -> false - | ParsedInput.ImplFile (ParsedImplFileInput (isScript = isScript)) -> isScript - - let ProcessMetaCommand state hash = - let mutable matchedm = range0 - try - match hash with - | ParsedHashDirective("I", args, m) -> - if not canHaveScriptMetaCommands then - errorR(HashIncludeNotAllowedInNonScript m) - match args with - | [path] -> - matchedm<-m - tcConfig.AddIncludePath(m, path, pathOfMetaCommandSource) - state - | _ -> - errorR(Error(FSComp.SR.buildInvalidHashIDirective(), m)) - state - | ParsedHashDirective("nowarn",numbers,m) -> - List.fold (fun state d -> nowarnF state (m,d)) state numbers - - | ParsedHashDirective(("reference" | "r"),args,m) -> - if not canHaveScriptMetaCommands then - errorR(HashReferenceNotAllowedInNonScript m) - - match args with - | [path] -> - matchedm <- m - match DependencyManagerIntegration.tryFindDependencyManagerInPath tcConfig.compilerToolPaths tcConfig.outputDir m (path:string) with - | DependencyManagerIntegration.ReferenceType.RegisteredDependencyManager packageManager -> - if tcConfig.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then - packageRequireF state (packageManager,m,path) - else - errorR(Error(FSComp.SR.packageManagementRequiresVFive(), m)) - state - - // #r "Assembly" - | DependencyManagerIntegration.ReferenceType.Library path -> - dllRequireF state (m,path) - - | DependencyManagerIntegration.ReferenceType.UnknownType -> - state // error already reported - | _ -> - errorR(Error(FSComp.SR.buildInvalidHashrDirective(), m)) - state - - | ParsedHashDirective("load", args, m) -> - if not canHaveScriptMetaCommands then - errorR(HashDirectiveNotAllowedInNonScript m) - match args with - | _ :: _ -> - matchedm<-m - args |> List.iter (fun path -> loadSourceF state (m, path)) - | _ -> - errorR(Error(FSComp.SR.buildInvalidHashloadDirective(), m)) - state - | ParsedHashDirective("time", args, m) -> - if not canHaveScriptMetaCommands then - errorR(HashDirectiveNotAllowedInNonScript m) - match args with - | [] -> - () - | ["on" | "off"] -> - () - | _ -> - errorR(Error(FSComp.SR.buildInvalidHashtimeDirective(), m)) - state - - | _ -> - - (* warning(Error("This meta-command has been ignored", m)) *) - state - with e -> errorRecovery e matchedm; state - - let rec WarnOnIgnoredSpecDecls decls = - decls |> List.iter (fun d -> - match d with - | SynModuleSigDecl.HashDirective (_, m) -> warning(Error(FSComp.SR.buildDirectivesInModulesAreIgnored(), m)) - | SynModuleSigDecl.NestedModule (_, _, subDecls, _) -> WarnOnIgnoredSpecDecls subDecls - | _ -> ()) - - let rec WarnOnIgnoredImplDecls decls = - decls |> List.iter (fun d -> - match d with - | SynModuleDecl.HashDirective (_, m) -> warning(Error(FSComp.SR.buildDirectivesInModulesAreIgnored(), m)) - | SynModuleDecl.NestedModule (_, _, subDecls, _, _) -> WarnOnIgnoredImplDecls subDecls - | _ -> ()) - - let ProcessMetaCommandsFromModuleSpec state (SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _)) = - List.fold (fun s d -> - match d with - | SynModuleSigDecl.HashDirective (h, _) -> ProcessMetaCommand s h - | SynModuleSigDecl.NestedModule (_, _, subDecls, _) -> WarnOnIgnoredSpecDecls subDecls; s - | _ -> s) - state - decls - - let ProcessMetaCommandsFromModuleImpl state (SynModuleOrNamespace(_, _, _, decls, _, _, _, _)) = - List.fold (fun s d -> - match d with - | SynModuleDecl.HashDirective (h, _) -> ProcessMetaCommand s h - | SynModuleDecl.NestedModule (_, _, subDecls, _, _) -> WarnOnIgnoredImplDecls subDecls; s - | _ -> s) - state - decls - - match inp with - | ParsedInput.SigFile (ParsedSigFileInput (_, _, _, hashDirectives, specs)) -> - let state = List.fold ProcessMetaCommand state0 hashDirectives - let state = List.fold ProcessMetaCommandsFromModuleSpec state specs - state - | ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, hashDirectives, impls, _)) -> - let state = List.fold ProcessMetaCommand state0 hashDirectives - let state = List.fold ProcessMetaCommandsFromModuleImpl state impls - state - -let ApplyNoWarnsToTcConfig (tcConfig: TcConfig, inp: ParsedInput, pathOfMetaCommandSource) = - // Clone - let tcConfigB = tcConfig.CloneOfOriginalBuilder - let addNoWarn = fun () (m,s) -> tcConfigB.TurnWarningOff(m, s) - let addReferencedAssemblyByPath = fun () (_m,_s) -> () - let addDependencyManagerText = fun () (_prefix,_m,_s) -> () - let addLoadedSource = fun () (_m,_s) -> () - ProcessMetaCommandsFromInput (addNoWarn, addReferencedAssemblyByPath, addDependencyManagerText, addLoadedSource) (tcConfigB, inp, pathOfMetaCommandSource, ()) - TcConfig.Create(tcConfigB, validate=false) - -let ApplyMetaCommandsFromInputToTcConfig (tcConfig: TcConfig, inp: ParsedInput, pathOfMetaCommandSource) = - // Clone - let tcConfigB = tcConfig.CloneOfOriginalBuilder - let getWarningNumber = fun () _ -> () - let addReferencedAssemblyByPath = fun () (m,s) -> tcConfigB.AddReferencedAssemblyByPath(m,s) - let addDependencyManagerText = fun () (packageManager, m,s) -> tcConfigB.AddDependencyManagerText(packageManager,m,s) - let addLoadedSource = fun () (m,s) -> tcConfigB.AddLoadedSource(m,s,pathOfMetaCommandSource) - ProcessMetaCommandsFromInput (getWarningNumber, addReferencedAssemblyByPath, addDependencyManagerText, addLoadedSource) (tcConfigB, inp, pathOfMetaCommandSource, ()) - TcConfig.Create(tcConfigB, validate=false) - -//---------------------------------------------------------------------------- -// Compute the load closure of a set of script files -//-------------------------------------------------------------------------- - -let GetAssemblyResolutionInformation(ctok, tcConfig: TcConfig) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig - let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (ctok, tcConfig, assemblyList, []) - resolutions.GetAssemblyResolutions(), resolutions.GetUnresolvedReferences() - -[] -type LoadClosureInput = - { FileName: string - SyntaxTree: ParsedInput option - ParseDiagnostics: (PhasedDiagnostic * bool) list - MetaCommandDiagnostics: (PhasedDiagnostic * bool) list } - -[] -type LoadClosure = - { /// The source files along with the ranges of the #load positions in each file. - SourceFiles: (string * range list) list - /// The resolved references along with the ranges of the #r positions in each file. - References: (string * AssemblyResolution list) list - /// The list of references that were not resolved during load closure. These may still be extension references. - UnresolvedReferences: UnresolvedAssemblyReference list - /// The list of all sources in the closure with inputs when available - Inputs: LoadClosureInput list - /// The #load, including those that didn't resolve - OriginalLoadReferences: (range * string * string) list - /// The #nowarns - NoWarns: (string * range list) list - /// Diagnostics seen while processing resolutions - ResolutionDiagnostics: (PhasedDiagnostic * bool) list - /// Diagnostics seen while parsing root of closure - AllRootFileDiagnostics: (PhasedDiagnostic * bool) list - /// Diagnostics seen while processing the compiler options implied root of closure - LoadClosureRootFileDiagnostics: (PhasedDiagnostic * bool) list } - - -[] -type CodeContext = - | CompilationAndEvaluation // in fsi.exe - | Compilation // in fsc.exe - | Editing // in VS - -module ScriptPreprocessClosure = - open Internal.Utilities.Text.Lexing - - /// Represents an input to the closure finding process - type ClosureSource = ClosureSource of filename: string * referenceRange: range * sourceText: ISourceText * parseRequired: bool - - /// Represents an output of the closure finding process - type ClosureFile = ClosureFile of string * range * ParsedInput option * (PhasedDiagnostic * bool) list * (PhasedDiagnostic * bool) list * (string * range) list // filename, range, errors, warnings, nowarns - - type Observed() = - let seen = System.Collections.Generic.Dictionary<_, bool>() - member ob.SetSeen check = - if not(seen.ContainsKey check) then - seen.Add(check, true) - - member ob.HaveSeen check = - seen.ContainsKey check - - /// Parse a script from source. - let ParseScriptText - (filename: string, sourceText: ISourceText, tcConfig: TcConfig, codeContext, - lexResourceManager: Lexhelp.LexResourceManager, errorLogger: ErrorLogger) = - - // fsc.exe -- COMPILED\!INTERACTIVE - // fsi.exe -- !COMPILED\INTERACTIVE - // Language service - // .fs -- EDITING + COMPILED\!INTERACTIVE - // .fsx -- EDITING + !COMPILED\INTERACTIVE - let defines = - match codeContext with - | CodeContext.CompilationAndEvaluation -> ["INTERACTIVE"] - | CodeContext.Compilation -> ["COMPILED"] - | CodeContext.Editing -> "EDITING" :: (if IsScript filename then ["INTERACTIVE"] else ["COMPILED"]) - - let isFeatureSupported featureId = tcConfig.langVersion.SupportsFeature featureId - let lexbuf = UnicodeLexing.SourceTextAsLexbuf(isFeatureSupported, sourceText) - - let isLastCompiland = (IsScript filename), tcConfig.target.IsExe // The root compiland is last in the list of compilands. - ParseOneInputLexbuf (tcConfig, lexResourceManager, defines, lexbuf, filename, isLastCompiland, errorLogger) - - /// Create a TcConfig for load closure starting from a single .fsx file - let CreateScriptTextTcConfig - (legacyReferenceResolver, defaultFSharpBinariesDir, - filename: string, codeContext, - useSimpleResolution, useFsiAuxLib, - basicReferences, applyCommandLineArgs, - assumeDotNetFramework, useSdkRefs, - tryGetMetadataSnapshot, reduceMemoryUsage) = - - let projectDir = Path.GetDirectoryName filename - let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation) - let isInvalidationSupported = (codeContext = CodeContext.Editing) - - let tcConfigB = - TcConfigBuilder.CreateNew - (legacyReferenceResolver, defaultFSharpBinariesDir, reduceMemoryUsage, projectDir, - isInteractive, isInvalidationSupported, defaultCopyFSharpCore=CopyFSharpCoreFlag.No, - tryGetMetadataSnapshot=tryGetMetadataSnapshot) - - applyCommandLineArgs tcConfigB - - match basicReferences with - | None -> (basicReferencesForScriptLoadClosure useFsiAuxLib useSdkRefs assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references - | Some rs -> for m, r in rs do tcConfigB.AddReferencedAssemblyByPath(m, r) - - tcConfigB.resolutionEnvironment <- - match codeContext with - | CodeContext.Editing -> ResolutionEnvironment.EditingOrCompilation true - | CodeContext.Compilation -> ResolutionEnvironment.EditingOrCompilation false - | CodeContext.CompilationAndEvaluation -> ResolutionEnvironment.CompilationAndEvaluation - tcConfigB.framework <- false - tcConfigB.useSimpleResolution <- useSimpleResolution - // Indicates that there are some references not in basicReferencesForScriptLoadClosure which should - // be added conditionally once the relevant version of mscorlib.dll has been detected. - tcConfigB.implicitlyResolveAssemblies <- false - tcConfigB.useSdkRefs <- useSdkRefs - - TcConfig.Create(tcConfigB, validate=true) - - let ClosureSourceOfFilename(filename, m, inputCodePage, parseRequired) = - try - let filename = FileSystem.GetFullPathShim filename - use stream = FileSystem.FileStreamReadShim filename - use reader = - match inputCodePage with - | None -> new StreamReader(stream, true) - | Some (n: int) -> new StreamReader(stream, Encoding.GetEncoding n) - let source = reader.ReadToEnd() - [ClosureSource(filename, m, SourceText.ofString source, parseRequired)] - with e -> - errorRecovery e m - [] - - let ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn - (tcConfig: TcConfig, inp: ParsedInput, pathOfMetaCommandSource) = - - let tcConfigB = tcConfig.CloneOfOriginalBuilder - let mutable nowarns = [] - let getWarningNumber = fun () (m, s) -> nowarns <- (s, m) :: nowarns - let addReferencedAssemblyByPath = fun () (m, s) -> tcConfigB.AddReferencedAssemblyByPath(m, s) - let addDependencyManagerText = fun () (packageManagerPrefix,m,s) -> tcConfigB.AddDependencyManagerText(packageManagerPrefix,m,s) - let addLoadedSource = fun () (m, s) -> tcConfigB.AddLoadedSource(m, s, pathOfMetaCommandSource) - try - ProcessMetaCommandsFromInput (getWarningNumber, addReferencedAssemblyByPath, addDependencyManagerText, addLoadedSource) (tcConfigB, inp, pathOfMetaCommandSource, ()) - with ReportedError _ -> - // Recover by using whatever did end up in the tcConfig - () - - try - TcConfig.Create(tcConfigB, validate=false), nowarns - with ReportedError _ -> - // Recover by using a default TcConfig. - let tcConfigB = tcConfig.CloneOfOriginalBuilder - TcConfig.Create(tcConfigB, validate=false), nowarns - - let FindClosureFiles(mainFile, _m, closureSources, origTcConfig:TcConfig, codeContext, lexResourceManager: Lexhelp.LexResourceManager) = - let mutable tcConfig = origTcConfig - - let observedSources = Observed() - let loadScripts = HashSet<_>() - - // Resolve the packages - let rec resolveDependencyManagerSources scriptName = - if not (loadScripts.Contains scriptName) then - [ for kv in tcConfig.packageManagerLines do - let packageManagerKey, packageManagerLines = kv.Key, kv.Value - match packageManagerLines with - | [] -> () - | (_, _, m)::_ -> - match origTcConfig.packageManagerLines |> Map.tryFind packageManagerKey with - | Some oldDependencyManagerLines when oldDependencyManagerLines = packageManagerLines -> () - | _ -> - match DependencyManagerIntegration.tryFindDependencyManagerByKey tcConfig.compilerToolPaths tcConfig.outputDir m packageManagerKey with - | None -> - errorR(DependencyManagerIntegration.createPackageManagerUnknownError tcConfig.compilerToolPaths tcConfig.outputDir packageManagerKey m) - | Some packageManager -> - let inline snd3 (_, b, _) = b - let packageManagerTextLines = packageManagerLines |> List.map snd3 - - match DependencyManagerIntegration.resolve packageManager tcConfig.implicitIncludeDir mainFile scriptName m packageManagerTextLines with - | None -> () // error already reported - | Some (succeeded, generatedScripts, additionalIncludeFolders) -> //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // This may incrementally update tcConfig too with new #r references - // New package text is ignored on this second phase - match succeeded with - | true -> - // Resolution produced no errors - if not (isNil additionalIncludeFolders) then - let tcConfigB = tcConfig.CloneOfOriginalBuilder - for folder in additionalIncludeFolders do - tcConfigB.AddIncludePath(m, folder, "") - tcConfigB.packageManagerLines <- tcConfigB.packageManagerLines |> Map.map(fun _ l -> l |> List.map(fun (_, p, m) -> true, p, m)) - tcConfig <- TcConfig.Create(tcConfigB, validate=false) - for script in generatedScripts do - let scriptText = File.ReadAllText script - loadScripts.Add script |> ignore - let iSourceText = SourceText.ofString scriptText - yield! loop (ClosureSource(script, m, iSourceText, true)) - | false -> - // Resolution produced errors update packagerManagerLines entries to note these failure - // failed resolutions will no longer be considered - let tcConfigB = tcConfig.CloneOfOriginalBuilder - tcConfigB.packageManagerLines <- tcConfigB.packageManagerLines |> Map.map(fun _ l -> l |> List.filter(fun (tried, _, _) -> tried)) - tcConfig <- TcConfig.Create(tcConfigB, validate=false)] - else [] - - and loop (ClosureSource(filename, m, sourceText, parseRequired)) = - [ if not (observedSources.HaveSeen(filename)) then - observedSources.SetSeen(filename) - //printfn "visiting %s" filename - if IsScript filename || parseRequired then - let parseResult, parseDiagnostics = - let errorLogger = CapturingErrorLogger("FindClosureParse") - use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) - let result = ParseScriptText (filename, sourceText, tcConfig, codeContext, lexResourceManager, errorLogger) - result, errorLogger.Diagnostics - - match parseResult with - | Some parsedScriptAst -> - let errorLogger = CapturingErrorLogger("FindClosureMetaCommands") - use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) - let pathOfMetaCommandSource = Path.GetDirectoryName filename - let preSources = tcConfig.GetAvailableLoadedSources() - - let tcConfigResult, noWarns = ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn (tcConfig, parsedScriptAst, pathOfMetaCommandSource) - tcConfig <- tcConfigResult // We accumulate the tcConfig in order to collect assembly references - - yield! resolveDependencyManagerSources filename - - let postSources = tcConfig.GetAvailableLoadedSources() - let sources = if preSources.Length < postSources.Length then postSources.[preSources.Length..] else [] - - yield! resolveDependencyManagerSources filename -#if DEBUG - for (_,subFile) in sources do - printfn "visiting %s - has subsource of %s " filename subFile -#endif - for (m, subFile) in sources do - if IsScript subFile then - for subSource in ClosureSourceOfFilename(subFile, m, tcConfigResult.inputCodePage, false) do - yield! loop subSource - else - yield ClosureFile(subFile, m, None, [], [], []) - -#if DEBUG - printfn "yielding source %s" filename -#endif - yield ClosureFile(filename, m, Some parsedScriptAst, parseDiagnostics, errorLogger.Diagnostics, noWarns) - - | None -> - printfn "yielding source %s (failed parse)" filename - yield ClosureFile(filename, m, None, parseDiagnostics, [], []) - else - // Don't traverse into .fs leafs. - printfn "yielding non-script source %s" filename - yield ClosureFile(filename, m, None, [], [], []) ] - - closureSources |> List.collect loop, tcConfig - - /// Reduce the full directive closure into LoadClosure - let GetLoadClosure(ctok, rootFilename, closureFiles, tcConfig: TcConfig, codeContext) = - - // Mark the last file as isLastCompiland. - let closureFiles = - if isNil closureFiles then - closureFiles - else - match List.frontAndBack closureFiles with - | rest, ClosureFile - (filename, m, - Some(ParsedInput.ImplFile (ParsedImplFileInput (name, isScript, qualNameOfFile, scopedPragmas, hashDirectives, implFileFlags, _))), - parseDiagnostics, metaDiagnostics, nowarns) -> - - let isLastCompiland = (true, tcConfig.target.IsExe) - rest @ [ClosureFile - (filename, m, - Some(ParsedInput.ImplFile (ParsedImplFileInput (name, isScript, qualNameOfFile, scopedPragmas, hashDirectives, implFileFlags, isLastCompiland))), - parseDiagnostics, metaDiagnostics, nowarns)] - - | _ -> closureFiles - - // Get all source files. - let sourceFiles = [ for (ClosureFile(filename, m, _, _, _, _)) in closureFiles -> (filename, m) ] - - let sourceInputs = - [ for (ClosureFile(filename, _, input, parseDiagnostics, metaDiagnostics, _nowarns)) in closureFiles -> - ({ FileName=filename - SyntaxTree=input - ParseDiagnostics=parseDiagnostics - MetaCommandDiagnostics=metaDiagnostics } : LoadClosureInput) ] - - let globalNoWarns = closureFiles |> List.collect (fun (ClosureFile(_, _, _, _, _, noWarns)) -> noWarns) - - // Resolve all references. - let references, unresolvedReferences, resolutionDiagnostics = - let errorLogger = CapturingErrorLogger("GetLoadClosure") - - use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) - let references, unresolvedReferences = GetAssemblyResolutionInformation(ctok, tcConfig) - let references = references |> List.map (fun ar -> ar.resolvedPath, ar) - references, unresolvedReferences, errorLogger.Diagnostics - - // Root errors and warnings - look at the last item in the closureFiles list - let loadClosureRootDiagnostics, allRootDiagnostics = - match List.rev closureFiles with - | ClosureFile(_, _, _, parseDiagnostics, metaDiagnostics, _) :: _ -> - (metaDiagnostics @ resolutionDiagnostics), - (parseDiagnostics @ metaDiagnostics @ resolutionDiagnostics) - | _ -> [], [] // When no file existed. - - let isRootRange exn = - match GetRangeOfDiagnostic exn with - | Some m -> - // Return true if the error was *not* from a #load-ed file. - let isArgParameterWhileNotEditing = (codeContext <> CodeContext.Editing) && (Range.equals m range0 || Range.equals m rangeStartup || Range.equals m rangeCmdArgs) - let isThisFileName = (0 = String.Compare(rootFilename, m.FileName, StringComparison.OrdinalIgnoreCase)) - isArgParameterWhileNotEditing || isThisFileName - | None -> true - - // Filter out non-root errors and warnings - let allRootDiagnostics = allRootDiagnostics |> List.filter (fst >> isRootRange) - - let result: LoadClosure = - { SourceFiles = List.groupBy fst sourceFiles |> List.map (map2Of2 (List.map snd)) - References = List.groupBy fst references |> List.map (map2Of2 (List.map snd)) - UnresolvedReferences = unresolvedReferences - Inputs = sourceInputs - NoWarns = List.groupBy fst globalNoWarns |> List.map (map2Of2 (List.map snd)) - OriginalLoadReferences = tcConfig.loadedSources - ResolutionDiagnostics = resolutionDiagnostics - AllRootFileDiagnostics = allRootDiagnostics - LoadClosureRootFileDiagnostics = loadClosureRootDiagnostics } - - result - - /// Given source text, find the full load closure. Used from service.fs, when editing a script file - let GetFullClosureOfScriptText - (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, - filename, sourceText, codeContext, - useSimpleResolution, useFsiAuxLib, useSdkRefs, - lexResourceManager: Lexhelp.LexResourceManager, - applyCommandLineArgs, assumeDotNetFramework, - tryGetMetadataSnapshot, reduceMemoryUsage) = - - // Resolve the basic references such as FSharp.Core.dll first, before processing any #I directives in the script - // - // This is tries to mimic the action of running the script in F# Interactive - the initial context for scripting is created - // first, then #I and other directives are processed. - let references0 = - let tcConfig = - CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, - filename, codeContext, useSimpleResolution, - useFsiAuxLib, None, applyCommandLineArgs, assumeDotNetFramework, - useSdkRefs, tryGetMetadataSnapshot, reduceMemoryUsage) - - let resolutions0, _unresolvedReferences = GetAssemblyResolutionInformation(ctok, tcConfig) - let references0 = resolutions0 |> List.map (fun r->r.originalReference.Range, r.resolvedPath) |> Seq.distinct |> List.ofSeq - references0 - - let tcConfig = - CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename, - codeContext, useSimpleResolution, useFsiAuxLib, Some references0, - applyCommandLineArgs, assumeDotNetFramework, useSdkRefs, - tryGetMetadataSnapshot, reduceMemoryUsage) - - let closureSources = [ClosureSource(filename, range0, sourceText, true)] - let closureFiles, tcConfig = FindClosureFiles(filename, range0, closureSources, tcConfig, codeContext, lexResourceManager) - GetLoadClosure(ctok, filename, closureFiles, tcConfig, codeContext) - - /// Given source filename, find the full load closure - /// Used from fsi.fs and fsc.fs, for #load and command line - let GetFullClosureOfScriptFiles(ctok, tcConfig:TcConfig, files:(string*range) list,codeContext,lexResourceManager: Lexhelp.LexResourceManager) = - let mainFile, mainFileRange = List.last files - let closureSources = files |> List.collect (fun (filename, m) -> ClosureSourceOfFilename(filename, m,tcConfig.inputCodePage,true)) - let closureFiles,tcConfig = FindClosureFiles(mainFile, mainFileRange, closureSources, tcConfig, codeContext, lexResourceManager) - GetLoadClosure(ctok, mainFile, closureFiles, tcConfig, codeContext) - -type LoadClosure with - /// Analyze a script text and find the closure of its references. - /// Used from FCS, when editing a script file. - // - /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the - /// same arguments as the rest of the application. - static member ComputeClosureOfScriptText - (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, - filename: string, sourceText: ISourceText, codeContext, useSimpleResolution: bool, - useFsiAuxLib, useSdkRefs, lexResourceManager: Lexhelp.LexResourceManager, - applyCommandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage) = - - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - ScriptPreprocessClosure.GetFullClosureOfScriptText - (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, - codeContext, useSimpleResolution, useFsiAuxLib, useSdkRefs, lexResourceManager, - applyCommandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage) - - /// Analyze a set of script files and find the closure of their references. - static member ComputeClosureOfScriptFiles - (ctok, tcConfig: TcConfig, files:(string*range) list, codeContext, - lexResourceManager: Lexhelp.LexResourceManager) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - ScriptPreprocessClosure.GetFullClosureOfScriptFiles (ctok, tcConfig, files, codeContext, lexResourceManager) - -//---------------------------------------------------------------------------- -// Initial type checking environment -//-------------------------------------------------------------------------- - -/// Build the initial type checking environment -let GetInitialTcEnv (thisAssemblyName: string, initm: range, tcConfig: TcConfig, tcImports: TcImports, tcGlobals) = - let initm = initm.StartRange - - let ccus = - tcImports.GetImportedAssemblies() - |> List.map (fun asm -> asm.FSharpViewOfMetadata, asm.AssemblyAutoOpenAttributes, asm.AssemblyInternalsVisibleToAttributes) - - let amap = tcImports.GetImportMap() - - let tcEnv = CreateInitialTcEnv(tcGlobals, amap, initm, thisAssemblyName, ccus) - - if tcConfig.checkOverflow then - try TcOpenDecl TcResultsSink.NoSink tcGlobals amap initm initm tcEnv (pathToSynLid initm (splitNamespace FSharpLib.CoreOperatorsCheckedName)) - with e -> errorRecovery e initm; tcEnv - else - tcEnv - -//---------------------------------------------------------------------------- -// Fault injection - -/// Inject faults into checking -let CheckSimulateException(tcConfig: TcConfig) = - match tcConfig.simulateException with - | Some("tc-oom") -> raise(System.OutOfMemoryException()) - | Some("tc-an") -> raise(System.ArgumentNullException("simulated")) - | Some("tc-invop") -> raise(System.InvalidOperationException()) - | Some("tc-av") -> raise(System.AccessViolationException()) - | Some("tc-nfn") -> raise(System.NotFiniteNumberException()) - | Some("tc-aor") -> raise(System.ArgumentOutOfRangeException()) - | Some("tc-dv0") -> raise(System.DivideByZeroException()) - | Some("tc-oe") -> raise(System.OverflowException()) - | Some("tc-atmm") -> raise(System.ArrayTypeMismatchException()) - | Some("tc-bif") -> raise(System.BadImageFormatException()) - | Some("tc-knf") -> raise(System.Collections.Generic.KeyNotFoundException()) - | Some("tc-ior") -> raise(System.IndexOutOfRangeException()) - | Some("tc-ic") -> raise(System.InvalidCastException()) - | Some("tc-ip") -> raise(System.InvalidProgramException()) - | Some("tc-ma") -> raise(System.MemberAccessException()) - | Some("tc-ni") -> raise(System.NotImplementedException()) - | Some("tc-nr") -> raise(System.NullReferenceException()) - | Some("tc-oc") -> raise(System.OperationCanceledException()) - | Some("tc-fail") -> failwith "simulated" - | _ -> () - -//---------------------------------------------------------------------------- -// Type-check sets of files -//-------------------------------------------------------------------------- - -type RootSigs = Zmap -type RootImpls = Zset - -let qnameOrder = Order.orderBy (fun (q: QualifiedNameOfFile) -> q.Text) - -type TcState = - { tcsCcu: CcuThunk - tcsCcuType: ModuleOrNamespace - tcsNiceNameGen: NiceNameGenerator - tcsTcSigEnv: TcEnv - tcsTcImplEnv: TcEnv - tcsCreatesGeneratedProvidedTypes: bool - tcsRootSigs: RootSigs - tcsRootImpls: RootImpls - tcsCcuSig: ModuleOrNamespaceType } - - member x.NiceNameGenerator = x.tcsNiceNameGen - - member x.TcEnvFromSignatures = x.tcsTcSigEnv - - member x.TcEnvFromImpls = x.tcsTcImplEnv - - member x.Ccu = x.tcsCcu - - member x.CreatesGeneratedProvidedTypes = x.tcsCreatesGeneratedProvidedTypes - - // Assem(a.fsi + b.fsi + c.fsi) (after checking implementation file ) - member x.CcuType = x.tcsCcuType - - // a.fsi + b.fsi + c.fsi (after checking implementation file for c.fs) - member x.CcuSig = x.tcsCcuSig - - member x.NextStateAfterIncrementalFragment tcEnvAtEndOfLastInput = - { x with tcsTcSigEnv = tcEnvAtEndOfLastInput - tcsTcImplEnv = tcEnvAtEndOfLastInput } - - -/// Create the initial type checking state for compiling an assembly -let GetInitialTcState(m, ccuName, tcConfig: TcConfig, tcGlobals, tcImports: TcImports, niceNameGen, tcEnv0) = - ignore tcImports - - // Create a ccu to hold all the results of compilation - let ccuType = NewCcuContents ILScopeRef.Local m ccuName (NewEmptyModuleOrNamespaceType Namespace) - - let ccuData: CcuData = - { IsFSharp=true - UsesFSharp20PlusQuotations=false -#if !NO_EXTENSIONTYPING - InvalidateEvent=(new Event<_>()).Publish - IsProviderGenerated = false - ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty) -#endif - TryGetILModuleDef = (fun () -> None) - FileName=None - Stamp = newStamp() - QualifiedName= None - SourceCodeDirectory = tcConfig.implicitIncludeDir - ILScopeRef=ILScopeRef.Local - Contents=ccuType - MemberSignatureEquality= (Tastops.typeEquivAux EraseAll tcGlobals) - TypeForwarders=Map.empty } - - let ccu = CcuThunk.Create(ccuName, ccuData) - - // OK, is this is the FSharp.Core CCU then fix it up. - if tcConfig.compilingFslib then - tcGlobals.fslibCcu.Fixup ccu - - { tcsCcu= ccu - tcsCcuType=ccuType - tcsNiceNameGen=niceNameGen - tcsTcSigEnv=tcEnv0 - tcsTcImplEnv=tcEnv0 - tcsCreatesGeneratedProvidedTypes=false - tcsRootSigs = Zmap.empty qnameOrder - tcsRootImpls = Zset.empty qnameOrder - tcsCcuSig = NewEmptyModuleOrNamespaceType Namespace } - - - -/// Typecheck a single file (or interactive entry into F# Interactive) -let TypeCheckOneInputEventually (checkForErrors, tcConfig: TcConfig, tcImports: TcImports, tcGlobals, prefixPathOpt, tcSink, tcState: TcState, inp: ParsedInput) = - - eventually { - try - let! ctok = Eventually.token - RequireCompilationThread ctok // Everything here requires the compilation thread since it works on the TAST - - CheckSimulateException tcConfig - - let m = inp.Range - let amap = tcImports.GetImportMap() - match inp with - | ParsedInput.SigFile (ParsedSigFileInput (_, qualNameOfFile, _, _, _) as file) -> - - // Check if we've seen this top module signature before. - if Zmap.mem qualNameOfFile tcState.tcsRootSigs then - errorR(Error(FSComp.SR.buildSignatureAlreadySpecified(qualNameOfFile.Text), m.StartRange)) - - // Check if the implementation came first in compilation order - if Zset.contains qualNameOfFile tcState.tcsRootImpls then - errorR(Error(FSComp.SR.buildImplementationAlreadyGivenDetail(qualNameOfFile.Text), m)) - - let conditionalDefines = - if tcConfig.noConditionalErasure then None else Some (tcConfig.conditionalCompilationDefines) - - // Typecheck the signature file - let! (tcEnv, sigFileType, createsGeneratedProvidedTypes) = - TypeCheckOneSigFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcState.tcsTcSigEnv file - - let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs - - // Add the signature to the signature env (unless it had an explicit signature) - let ccuSigForFile = CombineCcuContentFragments m [sigFileType; tcState.tcsCcuSig] - - // Open the prefixPath for fsi.exe - let tcEnv = - match prefixPathOpt with - | None -> tcEnv - | Some prefixPath -> - let m = qualNameOfFile.Range - TcOpenDecl tcSink tcGlobals amap m m tcEnv prefixPath - - let tcState = - { tcState with - tcsTcSigEnv=tcEnv - tcsTcImplEnv=tcState.tcsTcImplEnv - tcsRootSigs=rootSigs - tcsCreatesGeneratedProvidedTypes=tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes} - - return (tcEnv, EmptyTopAttrs, None, ccuSigForFile), tcState - - | ParsedInput.ImplFile (ParsedImplFileInput (_, _, qualNameOfFile, _, _, _, _) as file) -> - - // Check if we've got an interface for this fragment - let rootSigOpt = tcState.tcsRootSigs.TryFind qualNameOfFile - - // Check if we've already seen an implementation for this fragment - if Zset.contains qualNameOfFile tcState.tcsRootImpls then - errorR(Error(FSComp.SR.buildImplementationAlreadyGiven(qualNameOfFile.Text), m)) - - let tcImplEnv = tcState.tcsTcImplEnv - - let conditionalDefines = - if tcConfig.noConditionalErasure then None else Some (tcConfig.conditionalCompilationDefines) - - // Typecheck the implementation file - let! topAttrs, implFile, _implFileHiddenType, tcEnvAtEnd, createsGeneratedProvidedTypes = - TypeCheckOneImplFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcImplEnv rootSigOpt file - - let hadSig = rootSigOpt.IsSome - let implFileSigType = SigTypeOfImplFile implFile - - let rootImpls = Zset.add qualNameOfFile tcState.tcsRootImpls - - // Only add it to the environment if it didn't have a signature - let m = qualNameOfFile.Range - - // Add the implementation as to the implementation env - let tcImplEnv = AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcImplEnv implFileSigType - - // Add the implementation as to the signature env (unless it had an explicit signature) - let tcSigEnv = - if hadSig then tcState.tcsTcSigEnv - else AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcState.tcsTcSigEnv implFileSigType - - // Open the prefixPath for fsi.exe (tcImplEnv) - let tcImplEnv = - match prefixPathOpt with - | Some prefixPath -> TcOpenDecl tcSink tcGlobals amap m m tcImplEnv prefixPath - | _ -> tcImplEnv - - // Open the prefixPath for fsi.exe (tcSigEnv) - let tcSigEnv = - match prefixPathOpt with - | Some prefixPath when not hadSig -> TcOpenDecl tcSink tcGlobals amap m m tcSigEnv prefixPath - | _ -> tcSigEnv - - let ccuSig = CombineCcuContentFragments m [implFileSigType; tcState.tcsCcuSig ] - - let ccuSigForFile = CombineCcuContentFragments m [implFileSigType; tcState.tcsCcuSig] - - let tcState = - { tcState with - tcsTcSigEnv=tcSigEnv - tcsTcImplEnv=tcImplEnv - tcsRootImpls=rootImpls - tcsCcuSig=ccuSig - tcsCreatesGeneratedProvidedTypes=tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes } - return (tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile), tcState - - with e -> - errorRecovery e range0 - return (tcState.TcEnvFromSignatures, EmptyTopAttrs, None, tcState.tcsCcuSig), tcState - } - -/// Typecheck a single file (or interactive entry into F# Interactive) -let TypeCheckOneInput (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt) tcState inp = - // 'use' ensures that the warning handler is restored at the end - use unwindEL = PushErrorLoggerPhaseUntilUnwind(fun oldLogger -> GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput inp, oldLogger) ) - use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck - TypeCheckOneInputEventually (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, TcResultsSink.NoSink, tcState, inp) - |> Eventually.force ctok - -/// Finish checking multiple files (or one interactive entry into F# Interactive) -let TypeCheckMultipleInputsFinish(results, tcState: TcState) = - let tcEnvsAtEndFile, topAttrs, implFiles, ccuSigsForFiles = List.unzip4 results - let topAttrs = List.foldBack CombineTopAttrs topAttrs EmptyTopAttrs - let implFiles = List.choose id implFiles - // This is the environment required by fsi.exe when incrementally adding definitions - let tcEnvAtEndOfLastFile = (match tcEnvsAtEndFile with h :: _ -> h | _ -> tcState.TcEnvFromSignatures) - (tcEnvAtEndOfLastFile, topAttrs, implFiles, ccuSigsForFiles), tcState - -let TypeCheckOneInputAndFinishEventually(checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) = - eventually { - Logger.LogBlockStart LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually - let! results, tcState = TypeCheckOneInputEventually(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) - let result = TypeCheckMultipleInputsFinish([results], tcState) - Logger.LogBlockStop LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually - return result - } - -let TypeCheckClosedInputSetFinish (declaredImpls: TypedImplFile list, tcState) = - // Publish the latest contents to the CCU - tcState.tcsCcu.Deref.Contents <- NewCcuContents ILScopeRef.Local range0 tcState.tcsCcu.AssemblyName tcState.tcsCcuSig - - // Check all interfaces have implementations - tcState.tcsRootSigs |> Zmap.iter (fun qualNameOfFile _ -> - if not (Zset.contains qualNameOfFile tcState.tcsRootImpls) then - errorR(Error(FSComp.SR.buildSignatureWithoutImplementation(qualNameOfFile.Text), qualNameOfFile.Range))) - - tcState, declaredImpls - -let TypeCheckClosedInputSet (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, inputs) = - // tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions - let results, tcState = (tcState, inputs) ||> List.mapFold (TypeCheckOneInput (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt)) - let (tcEnvAtEndOfLastFile, topAttrs, implFiles, _), tcState = TypeCheckMultipleInputsFinish(results, tcState) - let tcState, declaredImpls = TypeCheckClosedInputSetFinish (implFiles, tcState) - tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile - -// Existing public APIs delegate to newer implementations -let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName -let DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = defaultReferencesForScriptsAndOutOfProjectSources (*useFsiAuxLib*)false assumeDotNetFramework (*useSdkRefs*)false diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi deleted file mode 100644 index fd95afdd20d..00000000000 --- a/src/fsharp/CompileOps.fsi +++ /dev/null @@ -1,835 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Coordinating compiler operations - configuration, loading initial context, reporting errors etc. -module internal FSharp.Compiler.CompileOps - -open System -open System.Text -open System.Collections.Generic -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.ILPdbWriter -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler -open FSharp.Compiler.TypeChecker -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Features -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Text -open Microsoft.FSharp.Core.CompilerServices -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -#endif - - -#if DEBUG - -module internal CompilerService = - val showAssertForUnexpectedException: bool ref -#endif - -//---------------------------------------------------------------------------- -// File names and known file suffixes -//-------------------------------------------------------------------------- - -/// Signature file suffixes -val FSharpSigFileSuffixes: string list - -/// Implementation file suffixes -val FSharpImplFileSuffixes: string list - -/// Script file suffixes -val FSharpScriptFileSuffixes: string list - -val IsScript: string -> bool - -/// File suffixes where #light is the default -val FSharpLightSyntaxFileSuffixes: string list - - -/// Get the name used for FSharp.Core -val GetFSharpCoreLibraryName: unit -> string - -//---------------------------------------------------------------------------- -// Parsing inputs -//-------------------------------------------------------------------------- - -val ComputeQualifiedNameOfFileFromUniquePath: range * string list -> Ast.QualifiedNameOfFile - -val PrependPathToInput: Ast.Ident list -> Ast.ParsedInput -> Ast.ParsedInput - -/// State used to de-deduplicate module names along a list of file names -type ModuleNamesDict = Map> - -/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. -val DeduplicateParsedInputModuleName: ModuleNamesDict -> Ast.ParsedInput -> Ast.ParsedInput * ModuleNamesDict - -/// Parse a single input (A signature file or implementation file) -val ParseInput: (UnicodeLexing.Lexbuf -> Parser.token) * ErrorLogger * UnicodeLexing.Lexbuf * string option * string * isLastCompiland:(bool * bool) -> Ast.ParsedInput - -//---------------------------------------------------------------------------- -// Error and warnings -//-------------------------------------------------------------------------- - -/// Get the location associated with an error -val GetRangeOfDiagnostic: PhasedDiagnostic -> range option - -/// Get the number associated with an error -val GetDiagnosticNumber: PhasedDiagnostic -> int - -/// Split errors into a "main" error and a set of associated errors -val SplitRelatedDiagnostics: PhasedDiagnostic -> PhasedDiagnostic * PhasedDiagnostic list - -/// Output an error to a buffer -val OutputPhasedDiagnostic: StringBuilder -> PhasedDiagnostic -> flattenErrors: bool -> suggestNames: bool -> unit - -/// Output an error or warning to a buffer -val OutputDiagnostic: implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * isError:bool -> StringBuilder -> PhasedDiagnostic -> unit - -/// Output extra context information for an error or warning to a buffer -val OutputDiagnosticContext: prefix:string -> fileLineFunction:(string -> int -> string) -> StringBuilder -> PhasedDiagnostic -> unit - -/// Part of LegacyHostedCompilerForTesting -[] -type DiagnosticLocation = - { Range: range - File: string - TextRepresentation: string - IsEmpty: bool } - -/// Part of LegacyHostedCompilerForTesting -[] -type DiagnosticCanonicalInformation = - { ErrorNumber: int - Subcategory: string - TextRepresentation: string } - -/// Part of LegacyHostedCompilerForTesting -[] -type DiagnosticDetailedInfo = - { Location: DiagnosticLocation option - Canonical: DiagnosticCanonicalInformation - Message: string } - -/// Part of LegacyHostedCompilerForTesting -[] -type Diagnostic = - | Short of bool * string - | Long of bool * DiagnosticDetailedInfo - -/// Part of LegacyHostedCompilerForTesting -val CollectDiagnostic: implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * warning:bool * PhasedDiagnostic * suggestNames: bool -> seq - -//---------------------------------------------------------------------------- -// Resolve assembly references -//-------------------------------------------------------------------------- - -exception AssemblyNotResolved of (*originalName*) string * range -exception FileNameNotResolved of (*filename*) string * (*description of searched locations*) string * range -exception DeprecatedCommandLineOptionFull of string * range -exception DeprecatedCommandLineOptionForHtmlDoc of string * range -exception DeprecatedCommandLineOptionSuggestAlternative of string * string * range -exception DeprecatedCommandLineOptionNoDescription of string * range -exception InternalCommandLineOption of string * range -exception HashLoadedSourceHasIssues of (*warnings*) exn list * (*errors*) exn list * range -exception HashLoadedScriptConsideredSource of range - -//---------------------------------------------------------------------------- - -/// Represents a reference to an F# assembly. May be backed by a real assembly on disk (read by Abstract IL), or a cross-project -/// reference in FSharp.Compiler.Service. -type IRawFSharpAssemblyData = - /// The raw list AutoOpenAttribute attributes in the assembly - abstract GetAutoOpenAttributes: ILGlobals -> string list - /// The raw list InternalsVisibleToAttribute attributes in the assembly - abstract GetInternalsVisibleToAttributes: ILGlobals -> string list - /// The raw IL module definition in the assembly, if any. This is not present for cross-project references - /// in the language service - abstract TryGetILModuleDef: unit -> ILModuleDef option - abstract HasAnyFSharpSignatureDataAttribute: bool - abstract HasMatchingFSharpSignatureDataAttribute: ILGlobals -> bool - /// The raw F# signature data in the assembly, if any - abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list - /// The raw F# optimization data in the assembly, if any - abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list - /// The table of type forwarders in the assembly - abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders - /// The identity of the module - abstract ILScopeRef: ILScopeRef - abstract ILAssemblyRefs: ILAssemblyRef list - abstract ShortAssemblyName: string - -type TimeStampCache = - new: defaultTimeStamp: DateTime -> TimeStampCache - member GetFileTimeStamp: string -> DateTime - member GetProjectReferenceTimeStamp: IProjectReference * CompilationThreadToken -> DateTime - -and IProjectReference = - - /// The name of the assembly file generated by the project - abstract FileName: string - - /// Evaluate raw contents of the assembly file generated by the project - abstract EvaluateRawContents: CompilationThreadToken -> Cancellable - - /// Get the logical timestamp that would be the timestamp of the assembly file generated by the project. - /// - /// For project references this is maximum of the timestamps of all dependent files. - /// The project is not actually built, nor are any assemblies read, but the timestamps for each dependent file - /// are read via the FileSystem. If the files don't exist, then a default timestamp is used. - /// - /// The operation returns None only if it is not possible to create an IncrementalBuilder for the project at all, e.g. if there - /// are fatal errors in the options for the project. - abstract TryGetLogicalTimeStamp: TimeStampCache * CompilationThreadToken -> System.DateTime option - -type AssemblyReference = - | AssemblyReference of range * string * IProjectReference option - member Range: range - member Text: string - member ProjectReference: IProjectReference option - -type AssemblyResolution = - {/// The original reference to the assembly. - originalReference: AssemblyReference - /// Path to the resolvedFile - resolvedPath: string - /// Create the tooltip text for the assembly reference - prepareToolTip: unit -> string - /// Whether or not this is an installed system assembly (for example, System.dll) - sysdir: bool - // Lazily populated ilAssemblyRef for this reference. - mutable ilAssemblyRef: ILAssemblyRef option } - -type UnresolvedAssemblyReference = UnresolvedAssemblyReference of string * AssemblyReference list - -#if !NO_EXTENSIONTYPING -type ResolvedExtensionReference = ResolvedExtensionReference of string * AssemblyReference list * Tainted list -#endif - -/// The thread in which compilation calls will be enqueued and done work on. -/// Note: This is currently only used when disposing of type providers and will be extended to all the other type provider calls when compilations can be done in parallel. -/// Right now all calls in FCS to type providers are single-threaded through use of the reactor thread. -type ICompilationThread = - - /// Enqueue work to be done on a compilation thread. - abstract EnqueueWork: (CompilationThreadToken -> unit) -> unit - -[] -type CompilerTarget = - | WinExe - | ConsoleExe - | Dll - | Module - member IsExe: bool - -[] -type ResolveAssemblyReferenceMode = - | Speculative - | ReportErrors - -[] -type CopyFSharpCoreFlag = Yes | No - -//---------------------------------------------------------------------------- -// TcConfig -//-------------------------------------------------------------------------- - -/// Represents the file or string used for the --version flag -type VersionFlag = - | VersionString of string - | VersionFile of string - | VersionNone - member GetVersionInfo: implicitIncludeDir:string -> ILVersionInfo - member GetVersionString: implicitIncludeDir:string -> string - -[] -type TcConfigBuilder = - { mutable primaryAssembly: PrimaryAssembly - mutable noFeedback: bool - mutable stackReserveSize: int32 option - mutable implicitIncludeDir: string - mutable openDebugInformationForLaterStaticLinking: bool - defaultFSharpBinariesDir: string - mutable compilingFslib: bool - mutable useIncrementalBuilder: bool - mutable includes: string list - mutable implicitOpens: string list - mutable useFsiAuxLib: bool - mutable framework: bool - mutable resolutionEnvironment: ReferenceResolver.ResolutionEnvironment - mutable implicitlyResolveAssemblies: bool - /// Set if the user has explicitly turned indentation-aware syntax on/off - mutable light: bool option - mutable conditionalCompilationDefines: string list - /// Sources added into the build with #load - mutable loadedSources: (range * string * string) list - mutable compilerToolPaths: string list - mutable referencedDLLs: AssemblyReference list - mutable packageManagerLines: Map - - mutable projectReferences: IProjectReference list - mutable knownUnresolvedReferences: UnresolvedAssemblyReference list - reduceMemoryUsage: ReduceMemoryFlag - mutable subsystemVersion: int * int - mutable useHighEntropyVA: bool - mutable inputCodePage: int option - mutable embedResources: string list - mutable errorSeverityOptions: FSharpErrorSeverityOptions - mutable mlCompatibility:bool - mutable checkOverflow:bool - mutable showReferenceResolutions:bool - mutable outputDir: string option - mutable outputFile: string option - mutable platform: ILPlatform option - mutable prefer32Bit: bool - mutable useSimpleResolution: bool - mutable target: CompilerTarget - mutable debuginfo: bool - mutable testFlagEmitFeeFeeAs100001: bool - mutable dumpDebugInfo: bool - mutable debugSymbolFile: string option - mutable typeCheckOnly: bool - mutable parseOnly: bool - mutable importAllReferencesOnly: bool - mutable simulateException: string option - mutable printAst: bool - mutable tokenizeOnly: bool - mutable testInteractionParser: bool - mutable reportNumDecls: bool - mutable printSignature: bool - mutable printSignatureFile: string - mutable xmlDocOutputFile: string option - mutable stats: bool - mutable generateFilterBlocks: bool - mutable signer: string option - mutable container: string option - mutable delaysign: bool - mutable publicsign: bool - mutable version: VersionFlag - mutable metadataVersion: string option - mutable standalone: bool - mutable extraStaticLinkRoots: string list - mutable noSignatureData: bool - mutable onlyEssentialOptimizationData: bool - mutable useOptimizationDataFile: bool - mutable jitTracking: bool - mutable portablePDB: bool - mutable embeddedPDB: bool - mutable embedAllSource: bool - mutable embedSourceList: string list - mutable sourceLink: string - mutable ignoreSymbolStoreSequencePoints: bool - mutable internConstantStrings: bool - mutable extraOptimizationIterations: int - mutable win32res: string - mutable win32manifest: string - mutable includewin32manifest: bool - mutable linkResources: string list - mutable legacyReferenceResolver: ReferenceResolver.Resolver - mutable showFullPaths: bool - mutable errorStyle: ErrorStyle - mutable utf8output: bool - mutable flatErrors: bool - mutable maxErrors: int - mutable abortOnError: bool - mutable baseAddress: int32 option - mutable checksumAlgorithm: HashAlgorithm - #if DEBUG - mutable showOptimizationData: bool -#endif - mutable showTerms : bool - mutable writeTermsToFiles: bool - mutable doDetuple : bool - mutable doTLR : bool - mutable doFinalSimplify: bool - mutable optsOn : bool - mutable optSettings : Optimizer.OptimizationSettings - mutable emitTailcalls: bool - mutable deterministic: bool - mutable preferredUiLang: string option - mutable lcid : int option - mutable productNameForBannerText: string - mutable showBanner : bool - mutable showTimes: bool - mutable showLoadedAssemblies: bool - mutable continueAfterParseFailure: bool -#if !NO_EXTENSIONTYPING - mutable showExtensionTypeMessages: bool -#endif - mutable compilationThread: ICompilationThread - mutable pause: bool - mutable alwaysCallVirt: bool - mutable noDebugData: bool - - /// If true, indicates all type checking and code generation is in the context of fsi.exe - isInteractive: bool - isInvalidationSupported: bool - mutable emitDebugInfoInQuotations: bool - mutable exename: string option - mutable copyFSharpCore: CopyFSharpCoreFlag - mutable shadowCopyReferences: bool - mutable useSdkRefs: bool - - /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, - /// and from which we can read the metadata. Only used when metadataOnly=true. - mutable tryGetMetadataSnapshot : ILReaderTryGetMetadataSnapshot - - /// if true - 'let mutable x = Span.Empty', the value 'x' is a stack referring span. Used for internal testing purposes only until we get true stack spans. - mutable internalTestSpanStackReferring : bool - - /// Prevent erasure of conditional attributes and methods so tooling is able analyse them. - mutable noConditionalErasure: bool - - mutable pathMap : PathMap - - mutable langVersion : LanguageVersion - - mutable includePathAdded : string -> unit - } - - static member Initial: TcConfigBuilder - - static member CreateNew: - legacyReferenceResolver: ReferenceResolver.Resolver * - defaultFSharpBinariesDir: string * - reduceMemoryUsage: ReduceMemoryFlag * - implicitIncludeDir: string * - isInteractive: bool * - isInvalidationSupported: bool * - defaultCopyFSharpCore: CopyFSharpCoreFlag * - tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * - ?includePathAdded: (string -> unit) - -> TcConfigBuilder - - member DecideNames: string list -> outfile: string * pdbfile: string option * assemblyName: string - member TurnWarningOff: range * string -> unit - member TurnWarningOn: range * string -> unit - member AddIncludePath: range * string * string -> unit - member AddCompilerToolsByPath: string -> unit - member AddReferencedAssemblyByPath: range * string -> unit - member RemoveReferencedAssemblyByPath: range * string -> unit - member AddEmbeddedSourceFile: string -> unit - member AddEmbeddedResource: string -> unit - member AddPathMapping: oldPrefix: string * newPrefix: string -> unit - - static member SplitCommandLineResourceInfo: string -> string * string * ILResourceAccess - -[] -// Immutable TcConfig -type TcConfig = - member primaryAssembly: PrimaryAssembly - member noFeedback: bool - member stackReserveSize: int32 option - member implicitIncludeDir: string - member openDebugInformationForLaterStaticLinking: bool - member fsharpBinariesDir: string - member compilingFslib: bool - member useIncrementalBuilder: bool - member includes: string list - member implicitOpens: string list - member useFsiAuxLib: bool - member framework: bool - member implicitlyResolveAssemblies: bool - /// Set if the user has explicitly turned indentation-aware syntax on/off - member light: bool option - member conditionalCompilationDefines: string list - member subsystemVersion: int * int - member useHighEntropyVA: bool - member compilerToolPaths: string list - member referencedDLLs: AssemblyReference list - member reduceMemoryUsage: ReduceMemoryFlag - member inputCodePage: int option - member embedResources: string list - member errorSeverityOptions: FSharpErrorSeverityOptions - member mlCompatibility:bool - member checkOverflow:bool - member showReferenceResolutions:bool - member outputDir: string option - member outputFile: string option - member platform: ILPlatform option - member prefer32Bit: bool - member useSimpleResolution: bool - member target: CompilerTarget - member debuginfo: bool - member testFlagEmitFeeFeeAs100001: bool - member dumpDebugInfo: bool - member debugSymbolFile: string option - member typeCheckOnly: bool - member parseOnly: bool - member importAllReferencesOnly: bool - member simulateException: string option - member printAst: bool - member tokenizeOnly: bool - member testInteractionParser: bool - member reportNumDecls: bool - member printSignature: bool - member printSignatureFile: string - member xmlDocOutputFile: string option - member stats: bool - member generateFilterBlocks: bool - member signer: string option - member container: string option - member delaysign: bool - member publicsign: bool - member version: VersionFlag - member metadataVersion: string option - member standalone: bool - member extraStaticLinkRoots: string list - member noSignatureData: bool - member onlyEssentialOptimizationData: bool - member useOptimizationDataFile: bool - member jitTracking: bool - member portablePDB: bool - member embeddedPDB: bool - member embedAllSource: bool - member embedSourceList: string list - member sourceLink: string - member ignoreSymbolStoreSequencePoints: bool - member internConstantStrings: bool - member extraOptimizationIterations: int - member win32res: string - member win32manifest: string - member includewin32manifest: bool - member linkResources: string list - member showFullPaths: bool - member errorStyle: ErrorStyle - member utf8output: bool - member flatErrors: bool - - member maxErrors: int - member baseAddress: int32 option - member checksumAlgorithm: HashAlgorithm -#if DEBUG - member showOptimizationData: bool -#endif - member showTerms : bool - member writeTermsToFiles: bool - member doDetuple : bool - member doTLR : bool - member doFinalSimplify: bool - member optSettings : Optimizer.OptimizationSettings - member emitTailcalls: bool - member deterministic: bool - member pathMap: PathMap - member preferredUiLang: string option - member optsOn : bool - member productNameForBannerText: string - member showBanner : bool - member showTimes: bool - member showLoadedAssemblies: bool - member continueAfterParseFailure: bool -#if !NO_EXTENSIONTYPING - member showExtensionTypeMessages: bool -#endif - member compilationThread: ICompilationThread - member pause: bool - member alwaysCallVirt: bool - member noDebugData: bool - - /// If true, indicates all type checking and code generation is in the context of fsi.exe - member isInteractive: bool - member isInvalidationSupported: bool - - - member ComputeLightSyntaxInitialStatus: string -> bool - member GetTargetFrameworkDirectories: unit -> string list - - /// Get the loaded sources that exist and issue a warning for the ones that don't - member GetAvailableLoadedSources: unit -> (range*string) list - - member ComputeCanContainEntryPoint: sourceFiles:string list -> bool list *bool - - /// File system query based on TcConfig settings - member ResolveSourceFile: range * filename: string * pathLoadedFrom: string -> string - - /// File system query based on TcConfig settings - member MakePathAbsolute: string -> string - - member copyFSharpCore: CopyFSharpCoreFlag - member shadowCopyReferences: bool - member useSdkRefs: bool - member langVersion: LanguageVersion - - static member Create: TcConfigBuilder * validate: bool -> TcConfig - -/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, -/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. -[] -type TcConfigProvider = - - member Get: CompilationThreadToken -> TcConfig - - /// Get a TcConfigProvider which will return only the exact TcConfig. - static member Constant: TcConfig -> TcConfigProvider - - /// Get a TcConfigProvider which will continue to respect changes in the underlying - /// TcConfigBuilder rather than delivering snapshots. - static member BasedOnMutableBuilder: TcConfigBuilder -> TcConfigProvider - -//---------------------------------------------------------------------------- -// Tables of referenced DLLs -//-------------------------------------------------------------------------- - -/// Represents a resolved imported binary -[] -type ImportedBinary = - { FileName: string - RawMetadata: IRawFSharpAssemblyData -#if !NO_EXTENSIONTYPING - ProviderGeneratedAssembly: System.Reflection.Assembly option - IsProviderGenerated: bool - ProviderGeneratedStaticLinkMap: ProvidedAssemblyStaticLinkingMap option -#endif - ILAssemblyRefs: ILAssemblyRef list - ILScopeRef: ILScopeRef} - -/// Represents a resolved imported assembly -[] -type ImportedAssembly = - { ILScopeRef: ILScopeRef - FSharpViewOfMetadata: CcuThunk - AssemblyAutoOpenAttributes: string list - AssemblyInternalsVisibleToAttributes: string list -#if !NO_EXTENSIONTYPING - IsProviderGenerated: bool - mutable TypeProviders: Tainted list -#endif - FSharpOptimizationData: Lazy> } - - -[] -type TcAssemblyResolutions = - member GetAssemblyResolutions: unit -> AssemblyResolution list - static member SplitNonFoundationalResolutions : CompilationThreadToken * TcConfig -> AssemblyResolution list * AssemblyResolution list * UnresolvedAssemblyReference list - static member BuildFromPriorResolutions : CompilationThreadToken * TcConfig * AssemblyResolution list * UnresolvedAssemblyReference list -> TcAssemblyResolutions - -/// Represents a table of imported assemblies with their resolutions. -/// Is a disposable object, but it is recommended not to explicitly call Dispose unless you absolutely know nothing will be using its contents after the disposal. -/// Otherwise, simply allow the GC to collect this and it will properly call Dispose from the finalizer. -[] -type TcImports = - interface System.IDisposable - //new: TcImports option -> TcImports - member DllTable: NameMap with get - member GetImportedAssemblies: unit -> ImportedAssembly list - member GetCcusInDeclOrder: unit -> CcuThunk list - /// This excludes any framework imports (which may be shared between multiple builds) - member GetCcusExcludingBase: unit -> CcuThunk list - member FindDllInfo: CompilationThreadToken * range * string -> ImportedBinary - member TryFindDllInfo: CompilationThreadToken * range * string * lookupOnly: bool -> option - member FindCcuFromAssemblyRef: CompilationThreadToken * range * ILAssemblyRef -> CcuResolutionResult -#if !NO_EXTENSIONTYPING - member ProviderGeneratedTypeRoots: ProviderGeneratedType list -#endif - member GetImportMap: unit -> Import.ImportMap - - /// Try to resolve a referenced assembly based on TcConfig settings. - member TryResolveAssemblyReference: CompilationThreadToken * AssemblyReference * ResolveAssemblyReferenceMode -> OperationResult - - /// Resolve a referenced assembly and report an error if the resolution fails. - member ResolveAssemblyReference: CompilationThreadToken * AssemblyReference * ResolveAssemblyReferenceMode -> AssemblyResolution list - - /// Try to find the given assembly reference by simple name. Used in magic assembly resolution. Effectively does implicit - /// unification of assemblies by simple assembly name. - member TryFindExistingFullyQualifiedPathBySimpleAssemblyName: CompilationThreadToken * string -> string option - - /// Try to find the given assembly reference. - member TryFindExistingFullyQualifiedPathByExactAssemblyRef: CompilationThreadToken * ILAssemblyRef -> string option - -#if !NO_EXTENSIONTYPING - /// Try to find a provider-generated assembly - member TryFindProviderGeneratedAssemblyByName: CompilationThreadToken * assemblyName:string -> System.Reflection.Assembly option -#endif - /// Report unresolved references that also weren't consumed by any type providers. - member ReportUnresolvedAssemblyReferences: UnresolvedAssemblyReference list -> unit - member SystemRuntimeContainsType: string -> bool - - static member BuildFrameworkTcImports : CompilationThreadToken * TcConfigProvider * AssemblyResolution list * AssemblyResolution list -> Cancellable - static member BuildNonFrameworkTcImports : CompilationThreadToken * TcConfigProvider * TcGlobals * TcImports * AssemblyResolution list * UnresolvedAssemblyReference list -> Cancellable - static member BuildTcImports : CompilationThreadToken * TcConfigProvider -> Cancellable - -//---------------------------------------------------------------------------- -// Special resources in DLLs -//-------------------------------------------------------------------------- - -/// Determine if an IL resource attached to an F# assembly is an F# signature data resource -val IsSignatureDataResource: ILResource -> bool - -/// Determine if an IL resource attached to an F# assembly is an F# optimization data resource -val IsOptimizationDataResource: ILResource -> bool - -/// Determine if an IL resource attached to an F# assembly is an F# quotation data resource for reflected definitions -val IsReflectedDefinitionsResource: ILResource -> bool -val GetSignatureDataResourceName: ILResource -> string - -/// Write F# signature data as an IL resource -val WriteSignatureData: TcConfig * TcGlobals * Tastops.Remap * CcuThunk * filename: string * inMem: bool -> ILResource - -/// Write F# optimization data as an IL resource -val WriteOptimizationData: TcGlobals * filename: string * inMem: bool * CcuThunk * Optimizer.LazyModuleInfo -> ILResource - -//---------------------------------------------------------------------------- -// #r and other directives -//-------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- -// #r and other directives -//-------------------------------------------------------------------------- - -/// Process #r in F# Interactive. -/// Adds the reference to the tcImports and add the ccu to the type checking environment. -val RequireDLL: CompilationThreadToken * TcImports * TcEnv * thisAssemblyName: string * referenceRange: range * file: string * assemblyReferenceAdded: (string -> unit) -> TcEnv * (ImportedBinary list * ImportedAssembly list) - -/// Processing # commands -val ProcessMetaCommandsFromInput : - (('T -> range * string -> 'T) * ('T -> range * string -> 'T) * ('T -> DependencyManagerIntegration.IDependencyManagerProvider * range * string -> 'T) * ('T -> range * string -> unit)) - -> TcConfigBuilder * Ast.ParsedInput * string * 'T - -> 'T - -/// Process all the #r, #I etc. in an input -val ApplyMetaCommandsFromInputToTcConfig: TcConfig * Ast.ParsedInput * string -> TcConfig - -/// Process the #nowarn in an input -val ApplyNoWarnsToTcConfig: TcConfig * Ast.ParsedInput * string -> TcConfig - -//---------------------------------------------------------------------------- -// Scoped pragmas -//-------------------------------------------------------------------------- - -/// Find the scoped #nowarn pragmas with their range information -val GetScopedPragmasForInput: Ast.ParsedInput -> ScopedPragma list - -/// Get an error logger that filters the reporting of warnings based on scoped pragma information -val GetErrorLoggerFilteringByScopedPragmas: checkFile:bool * ScopedPragma list * ErrorLogger -> ErrorLogger - -/// This list is the default set of references for "non-project" files. -val DefaultReferencesForScriptsAndOutOfProjectSources: bool -> string list - -//---------------------------------------------------------------------------- -// Parsing -//-------------------------------------------------------------------------- - -/// Parse one input file -val ParseOneInputFile: TcConfig * Lexhelp.LexResourceManager * string list * string * isLastCompiland: (bool * bool) * ErrorLogger * (*retryLocked*) bool -> ParsedInput option - -//---------------------------------------------------------------------------- -// Type checking and querying the type checking state -//-------------------------------------------------------------------------- - -/// Get the initial type checking environment including the loading of mscorlib/System.Core, FSharp.Core -/// applying the InternalsVisibleTo in referenced assemblies and opening 'Checked' if requested. -val GetInitialTcEnv: assemblyName: string * range * TcConfig * TcImports * TcGlobals -> TcEnv - -[] -/// Represents the incremental type checking state for a set of inputs -type TcState = - member NiceNameGenerator: NiceNameGenerator - - /// The CcuThunk for the current assembly being checked - member Ccu: CcuThunk - - /// Get the typing environment implied by the set of signature files and/or inferred signatures of implementation files checked so far - member TcEnvFromSignatures: TcEnv - - /// Get the typing environment implied by the set of implementation files checked so far - member TcEnvFromImpls: TcEnv - - /// The inferred contents of the assembly, containing the signatures of all files. - // a.fsi + b.fsi + c.fsi (after checking implementation file for c.fs) - member CcuSig: ModuleOrNamespaceType - - member NextStateAfterIncrementalFragment: TcEnv -> TcState - - member CreatesGeneratedProvidedTypes: bool - -/// Get the initial type checking state for a set of inputs -val GetInitialTcState: - range * string * TcConfig * TcGlobals * TcImports * NiceNameGenerator * TcEnv -> TcState - -/// Check one input, returned as an Eventually computation -val TypeCheckOneInputEventually : - checkForErrors:(unit -> bool) * TcConfig * TcImports * TcGlobals * Ast.LongIdent option * NameResolution.TcResultsSink * TcState * Ast.ParsedInput - -> Eventually<(TcEnv * TopAttribs * TypedImplFile option * ModuleOrNamespaceType) * TcState> - -/// Finish the checking of multiple inputs -val TypeCheckMultipleInputsFinish: (TcEnv * TopAttribs * 'T option * 'U) list * TcState -> (TcEnv * TopAttribs * 'T list * 'U list) * TcState - -/// Finish the checking of a closed set of inputs -val TypeCheckClosedInputSetFinish: TypedImplFile list * TcState -> TcState * TypedImplFile list - -/// Check a closed set of inputs -val TypeCheckClosedInputSet: CompilationThreadToken * checkForErrors: (unit -> bool) * TcConfig * TcImports * TcGlobals * Ast.LongIdent option * TcState * Ast.ParsedInput list -> TcState * TopAttribs * TypedImplFile list * TcEnv - -/// Check a single input and finish the checking -val TypeCheckOneInputAndFinishEventually : - checkForErrors: (unit -> bool) * TcConfig * TcImports * TcGlobals * Ast.LongIdent option * NameResolution.TcResultsSink * TcState * Ast.ParsedInput - -> Eventually<(TcEnv * TopAttribs * TypedImplFile list * ModuleOrNamespaceType list) * TcState> - -/// Indicates if we should report a warning -val ReportWarning: FSharpErrorSeverityOptions -> PhasedDiagnostic -> bool - -/// Indicates if we should report a warning as an error -val ReportWarningAsError: FSharpErrorSeverityOptions -> PhasedDiagnostic -> bool - -//---------------------------------------------------------------------------- -// #load closure -//-------------------------------------------------------------------------- - -[] -type CodeContext = - | CompilationAndEvaluation - | Compilation - | Editing - -[] -type LoadClosureInput = - { FileName: string - SyntaxTree: ParsedInput option - ParseDiagnostics: (PhasedDiagnostic * bool) list - MetaCommandDiagnostics: (PhasedDiagnostic * bool) list } - -[] -type LoadClosure = - { /// The source files along with the ranges of the #load positions in each file. - SourceFiles: (string * range list) list - - /// The resolved references along with the ranges of the #r positions in each file. - References: (string * AssemblyResolution list) list - - /// The list of references that were not resolved during load closure. - UnresolvedReferences: UnresolvedAssemblyReference list - - /// The list of all sources in the closure with inputs when available, with associated parse errors and warnings - Inputs: LoadClosureInput list - - /// The original #load references, including those that didn't resolve - OriginalLoadReferences: (range * string * string) list - - /// The #nowarns - NoWarns: (string * range list) list - - /// Diagnostics seen while processing resolutions - ResolutionDiagnostics: (PhasedDiagnostic * bool) list - - /// Diagnostics to show for root of closure (used by fsc.fs) - AllRootFileDiagnostics: (PhasedDiagnostic * bool) list - - /// Diagnostics seen while processing the compiler options implied root of closure - LoadClosureRootFileDiagnostics: (PhasedDiagnostic * bool) list } - - /// Analyze a script text and find the closure of its references. - /// Used from FCS, when editing a script file. - // - /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the - /// same arguments as the rest of the application. - static member ComputeClosureOfScriptText: CompilationThreadToken * legacyReferenceResolver: ReferenceResolver.Resolver * defaultFSharpBinariesDir: string * filename: string * sourceText: ISourceText * implicitDefines:CodeContext * useSimpleResolution: bool * useFsiAuxLib: bool * useSdkRefs: bool * lexResourceManager: Lexhelp.LexResourceManager * applyCompilerOptions: (TcConfigBuilder -> unit) * assumeDotNetFramework: bool * tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * reduceMemoryUsage: ReduceMemoryFlag -> LoadClosure - - /// Analyze a set of script files and find the closure of their references. The resulting references are then added to the given TcConfig. - /// Used from fsi.fs and fsc.fs, for #load and command line. - static member ComputeClosureOfScriptFiles: CompilationThreadToken * tcConfig:TcConfig * (string * range) list * implicitDefines:CodeContext * lexResourceManager: Lexhelp.LexResourceManager -> LoadClosure diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs deleted file mode 100644 index 65107906686..00000000000 --- a/src/fsharp/CompileOptions.fs +++ /dev/null @@ -1,1883 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -// # FSComp.SR.opts - -module internal FSharp.Compiler.CompileOptions - -open Internal.Utilities -open System -open System.IO -open FSharp.Compiler -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILPdbWriter -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.CompileOps -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Features -open FSharp.Compiler.Lib -open FSharp.Compiler.Range -open FSharp.Compiler.IlxGen - -module Attributes = - open System.Runtime.CompilerServices - - //[] - [] - do() - -//---------------------------------------------------------------------------- -// Compiler option parser -// -// The argument parser is used by both the VS plug-in and the fsc.exe to -// parse the include file path and other front-end arguments. -// -// The language service uses this function too. It's important to continue -// processing flags even if an error is seen in one so that the best possible -// intellisense can be show. -//-------------------------------------------------------------------------- - -[] -type OptionSwitch = - | On - | Off - -type OptionSpec = - | OptionClear of bool ref - | OptionFloat of (float -> unit) - | OptionInt of (int -> unit) - | OptionSwitch of (OptionSwitch -> unit) - | OptionIntList of (int -> unit) - | OptionIntListSwitch of (int -> OptionSwitch -> unit) - | OptionRest of (string -> unit) - | OptionSet of bool ref - | OptionString of (string -> unit) - | OptionStringList of (string -> unit) - | OptionStringListSwitch of (string -> OptionSwitch -> unit) - | OptionUnit of (unit -> unit) - | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" - | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) - -and CompilerOption = CompilerOption of string * string * OptionSpec * Option * string option -and CompilerOptionBlock = PublicOptions of string * CompilerOption list | PrivateOptions of CompilerOption list - -let GetOptionsOfBlock block = - match block with - | PublicOptions (_, opts) -> opts - | PrivateOptions opts -> opts - -let FilterCompilerOptionBlock pred block = - match block with - | PublicOptions(heading, opts) -> PublicOptions(heading, List.filter pred opts) - | PrivateOptions opts -> PrivateOptions(List.filter pred opts) - -let compilerOptionUsage (CompilerOption(s, tag, spec, _, _)) = - let s = if s="--" then "" else s (* s="flag" for "--flag" options. s="--" for "--" option. Adjust printing here for "--" case. *) - match spec with - | (OptionUnit _ | OptionSet _ | OptionClear _ | OptionHelp _) -> sprintf "--%s" s - | OptionStringList _ -> sprintf "--%s:%s" s tag - | OptionIntList _ -> sprintf "--%s:%s" s tag - | OptionSwitch _ -> sprintf "--%s[+|-]" s - | OptionStringListSwitch _ -> sprintf "--%s[+|-]:%s" s tag - | OptionIntListSwitch _ -> sprintf "--%s[+|-]:%s" s tag - | OptionString _ -> sprintf "--%s:%s" s tag - | OptionInt _ -> sprintf "--%s:%s" s tag - | OptionFloat _ -> sprintf "--%s:%s" s tag - | OptionRest _ -> sprintf "--%s ..." s - | OptionGeneral _ -> if tag="" then sprintf "%s" s else sprintf "%s:%s" s tag (* still being decided *) - -let PrintCompilerOption (CompilerOption(_s, _tag, _spec, _, help) as compilerOption) = - let flagWidth = 42 // fixed width for printing of flags, e.g. --debug:{full|pdbonly|portable|embedded} - let defaultLineWidth = 80 // the fallback width - let lineWidth = - try - System.Console.BufferWidth - with e -> defaultLineWidth - let lineWidth = if lineWidth=0 then defaultLineWidth else lineWidth (* Have seen BufferWidth=0 on Linux/Mono *) - // Lines have this form: - // flagWidth chars - for flags description or padding on continuation lines. - // single space - space. - // description - words upto but excluding the final character of the line. - printf "%-40s" (compilerOptionUsage compilerOption) - let printWord column (word:string) = - // Have printed upto column. - // Now print the next word including any preceding whitespace. - // Returns the column printed to (suited to folding). - if column + 1 (*space*) + word.Length >= lineWidth then // NOTE: "equality" ensures final character of the line is never printed - printfn "" (* newline *) - printf "%-40s %s" ""(*<--flags*) word - flagWidth + 1 + word.Length - else - printf " %s" word - column + 1 + word.Length - let words = match help with None -> [| |] | Some s -> s.Split [| ' ' |] - let _finalColumn = Array.fold printWord flagWidth words - printfn "" (* newline *) - -let PrintPublicOptions (heading, opts) = - if not (isNil opts) then - printfn "" - printfn "" - printfn "\t\t%s" heading - List.iter PrintCompilerOption opts - -let PrintCompilerOptionBlocks blocks = - let equals x y = x=y - let publicBlocks = List.choose (function PrivateOptions _ -> None | PublicOptions (heading, opts) -> Some (heading, opts)) blocks - let consider doneHeadings (heading, _opts) = - if Set.contains heading doneHeadings then - doneHeadings - else - let headingOptions = List.filter (fst >> equals heading) publicBlocks |> List.collect snd - PrintPublicOptions (heading, headingOptions) - Set.add heading doneHeadings - List.fold consider Set.empty publicBlocks |> ignore> - -(* For QA *) -let dumpCompilerOption prefix (CompilerOption(str, _, spec, _, _)) = - printf "section='%-25s' ! option=%-30s kind=" prefix str - match spec with - | OptionUnit _ -> printf "OptionUnit" - | OptionSet _ -> printf "OptionSet" - | OptionClear _ -> printf "OptionClear" - | OptionHelp _ -> printf "OptionHelp" - | OptionStringList _ -> printf "OptionStringList" - | OptionIntList _ -> printf "OptionIntList" - | OptionSwitch _ -> printf "OptionSwitch" - | OptionStringListSwitch _ -> printf "OptionStringListSwitch" - | OptionIntListSwitch _ -> printf "OptionIntListSwitch" - | OptionString _ -> printf "OptionString" - | OptionInt _ -> printf "OptionInt" - | OptionFloat _ -> printf "OptionFloat" - | OptionRest _ -> printf "OptionRest" - | OptionGeneral _ -> printf "OptionGeneral" - printf "\n" -let dumpCompilerOptionBlock = function - | PublicOptions (heading, opts) -> List.iter (dumpCompilerOption heading) opts - | PrivateOptions opts -> List.iter (dumpCompilerOption "NoSection") opts -let DumpCompilerOptionBlocks blocks = List.iter dumpCompilerOptionBlock blocks - -let isSlashOpt (opt:string) = - opt.[0] = '/' && (opt.Length = 1 || not (opt.[1..].Contains "/")) - -module ResponseFile = - - type ResponseFileData = ResponseFileLine list - and ResponseFileLine = - | CompilerOptionSpec of string - | Comment of string - - let parseFile path: Choice = - let parseLine (l: string) = - match l with - | s when String.IsNullOrWhiteSpace s -> None - | s when l.StartsWithOrdinal("#") -> Some (ResponseFileLine.Comment (s.TrimStart('#'))) - | s -> Some (ResponseFileLine.CompilerOptionSpec (s.Trim())) - - try - use stream = FileSystem.FileStreamReadShim path - use reader = new System.IO.StreamReader(stream, true) - let data = - seq { while not reader.EndOfStream do yield reader.ReadLine () } - |> Seq.choose parseLine - |> List.ofSeq - Choice1Of2 data - with e -> - Choice2Of2 e - - -let ParseCompilerOptions (collectOtherArgument: string -> unit, blocks: CompilerOptionBlock list, args) = - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - - let specs = List.collect GetOptionsOfBlock blocks - - // returns a tuple - the option token, the option argument string - let parseOption (s: string) = - // grab the option token - let opts = s.Split([|':'|]) - let mutable opt = opts.[0] - if opt = "" then - () - // if it doesn't start with a '-' or '/', reject outright - elif opt.[0] <> '-' && opt.[0] <> '/' then - opt <- "" - elif opt <> "--" then - // is it an abbreviated or MSFT-style option? - // if so, strip the first character and move on with your life - if opt.Length = 2 || isSlashOpt opt then - opt <- opt.[1 ..] - // else, it should be a non-abbreviated option starting with "--" - elif opt.Length > 3 && opt.StartsWithOrdinal("--") then - opt <- opt.[2 ..] - else - opt <- "" - - // get the argument string - let optArgs = if opts.Length > 1 then String.Join(":", opts.[1 ..]) else "" - opt, optArgs - - let getOptionArg compilerOption (argString: string) = - if argString = "" then - errorR(Error(FSComp.SR.buildOptionRequiresParameter(compilerOptionUsage compilerOption), rangeCmdArgs)) - argString - - let getOptionArgList compilerOption (argString: string) = - if argString = "" then - errorR(Error(FSComp.SR.buildOptionRequiresParameter(compilerOptionUsage compilerOption), rangeCmdArgs)) - [] - else - argString.Split([|',';';'|]) |> List.ofArray - - let getSwitchOpt (opt: string) = - // if opt is a switch, strip the '+' or '-' - if opt <> "--" && opt.Length > 1 && (opt.EndsWithOrdinal("+") || opt.EndsWithOrdinal("-")) then - opt.[0 .. opt.Length - 2] - else - opt - - let getSwitch (s: string) = - let s = (s.Split([|':'|])).[0] - if s <> "--" && s.EndsWithOrdinal("-") then OptionSwitch.Off else OptionSwitch.On - - let rec processArg args = - match args with - | [] -> () - | ((rsp: string) :: t) when rsp.StartsWithOrdinal("@") -> - let responseFileOptions = - let fullpath = - try - Some (rsp.TrimStart('@') |> FileSystem.GetFullPathShim) - with _ -> - None - - match fullpath with - | None -> - errorR(Error(FSComp.SR.optsResponseFileNameInvalid rsp, rangeCmdArgs)) - [] - | Some path when not (FileSystem.SafeExists path) -> - errorR(Error(FSComp.SR.optsResponseFileNotFound(rsp, path), rangeCmdArgs)) - [] - | Some path -> - match ResponseFile.parseFile path with - | Choice2Of2 _ -> - errorR(Error(FSComp.SR.optsInvalidResponseFile(rsp, path), rangeCmdArgs)) - [] - | Choice1Of2 rspData -> - let onlyOptions l = - match l with - | ResponseFile.ResponseFileLine.Comment _ -> None - | ResponseFile.ResponseFileLine.CompilerOptionSpec opt -> Some opt - rspData |> List.choose onlyOptions - - processArg (responseFileOptions @ t) - - | opt :: t -> - - let optToken, argString = parseOption opt - - let reportDeprecatedOption errOpt = - match errOpt with - | Some e -> warning e - | None -> () - - let rec attempt l = - match l with - | (CompilerOption(s, _, OptionHelp f, d, _) :: _) when optToken = s && argString = "" -> - reportDeprecatedOption d - f blocks; t - | (CompilerOption(s, _, OptionUnit f, d, _) :: _) when optToken = s && argString = "" -> - reportDeprecatedOption d - f (); t - | (CompilerOption(s, _, OptionSwitch f, d, _) :: _) when getSwitchOpt optToken = s && argString = "" -> - reportDeprecatedOption d - f (getSwitch opt); t - | (CompilerOption(s, _, OptionSet f, d, _) :: _) when optToken = s && argString = "" -> - reportDeprecatedOption d - f := true; t - | (CompilerOption(s, _, OptionClear f, d, _) :: _) when optToken = s && argString = "" -> - reportDeprecatedOption d - f := false; t - | (CompilerOption(s, _, OptionString f, d, _) as compilerOption :: _) when optToken = s -> - reportDeprecatedOption d - let oa = getOptionArg compilerOption argString - if oa <> "" then - f (getOptionArg compilerOption oa) - t - | (CompilerOption(s, _, OptionInt f, d, _) as compilerOption :: _) when optToken = s -> - reportDeprecatedOption d - let oa = getOptionArg compilerOption argString - if oa <> "" then - f (try int32 oa with _ -> - errorR(Error(FSComp.SR.buildArgInvalidInt(getOptionArg compilerOption argString), rangeCmdArgs)); 0) - t - | (CompilerOption(s, _, OptionFloat f, d, _) as compilerOption :: _) when optToken = s -> - reportDeprecatedOption d - let oa = getOptionArg compilerOption argString - if oa <> "" then - f (try float oa with _ -> - errorR(Error(FSComp.SR.buildArgInvalidFloat(getOptionArg compilerOption argString), rangeCmdArgs)); 0.0) - t - | (CompilerOption(s, _, OptionRest f, d, _) :: _) when optToken = s -> - reportDeprecatedOption d - List.iter f t; [] - | (CompilerOption(s, _, OptionIntList f, d, _) as compilerOption :: _) when optToken = s -> - reportDeprecatedOption d - let al = getOptionArgList compilerOption argString - if al <> [] then - List.iter (fun i -> f (try int32 i with _ -> errorR(Error(FSComp.SR.buildArgInvalidInt i, rangeCmdArgs)); 0)) al - t - | (CompilerOption(s, _, OptionIntListSwitch f, d, _) as compilerOption :: _) when getSwitchOpt optToken = s -> - reportDeprecatedOption d - let al = getOptionArgList compilerOption argString - if al <> [] then - let switch = getSwitch opt - List.iter (fun i -> f (try int32 i with _ -> errorR(Error(FSComp.SR.buildArgInvalidInt i, rangeCmdArgs)); 0) switch) al - t - // here - | (CompilerOption(s, _, OptionStringList f, d, _) as compilerOption :: _) when optToken = s -> - reportDeprecatedOption d - let al = getOptionArgList compilerOption argString - if al <> [] then - List.iter f (getOptionArgList compilerOption argString) - t - | (CompilerOption(s, _, OptionStringListSwitch f, d, _) as compilerOption :: _) when getSwitchOpt optToken = s -> - reportDeprecatedOption d - let al = getOptionArgList compilerOption argString - if al <> [] then - let switch = getSwitch opt - List.iter (fun s -> f s switch) (getOptionArgList compilerOption argString) - t - | (CompilerOption(_, _, OptionGeneral (pred, exec), d, _) :: _) when pred args -> - reportDeprecatedOption d - let rest = exec args in rest // arguments taken, rest remaining - | (_ :: more) -> attempt more - | [] -> - if opt.Length = 0 || opt.[0] = '-' || isSlashOpt opt - then - // want the whole opt token - delimiter and all - let unrecOpt = (opt.Split([|':'|]).[0]) - errorR(Error(FSComp.SR.buildUnrecognizedOption unrecOpt, rangeCmdArgs)) - t - else - (collectOtherArgument opt; t) - let rest = attempt specs - processArg rest - - processArg args - -//---------------------------------------------------------------------------- -// Compiler options -//-------------------------------------------------------------------------- - -let lexFilterVerbose = false -let mutable enableConsoleColoring = true // global state - -let setFlag r n = - match n with - | 0 -> r false - | 1 -> r true - | _ -> raise (Failure "expected 0/1") - -let SetOptimizeOff(tcConfigB: TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false } - tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 } - tcConfigB.doDetuple <- false - tcConfigB.doTLR <- false - tcConfigB.doFinalSimplify <- false - -let SetOptimizeOn(tcConfigB: TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true } - tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 } - tcConfigB.doDetuple <- true - tcConfigB.doTLR <- true - tcConfigB.doFinalSimplify <- true - -let SetOptimizeSwitch (tcConfigB: TcConfigBuilder) switch = - if (switch = OptionSwitch.On) then SetOptimizeOn tcConfigB else SetOptimizeOff tcConfigB - -let SetTailcallSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.emitTailcalls <- (switch = OptionSwitch.On) - -let SetDeterministicSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.deterministic <- (switch = OptionSwitch.On) - -let AddPathMapping (tcConfigB: TcConfigBuilder) (pathPair: string) = - match pathPair.Split([|'='|], 2) with - | [| oldPrefix; newPrefix |] -> - tcConfigB.AddPathMapping (oldPrefix, newPrefix) - | _ -> - error(Error(FSComp.SR.optsInvalidPathMapFormat(), rangeCmdArgs)) - -let jitoptimizeSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some (switch = OptionSwitch.On) } - -let localoptimizeSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some (switch = OptionSwitch.On) } - -let crossOptimizeSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some (switch = OptionSwitch.On) } - -let splittingSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.optSettings <- { tcConfigB.optSettings with abstractBigTargets = switch = OptionSwitch.On } - -let callVirtSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.alwaysCallVirt <- switch = OptionSwitch.On - -let useHighEntropyVASwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.useHighEntropyVA <- switch = OptionSwitch.On - -let subSystemVersionSwitch (tcConfigB: TcConfigBuilder) (text: string) = - let fail() = error(Error(FSComp.SR.optsInvalidSubSystemVersion text, rangeCmdArgs)) - - // per spec for 357994: Validate input string, should be two positive integers x.y when x>=4 and y>=0 and both <= 65535 - if System.String.IsNullOrEmpty text then - fail() - else - match text.Split('.') with - | [| majorStr; minorStr|] -> - match (Int32.TryParse majorStr), (Int32.TryParse minorStr) with - | (true, major), (true, minor) - when major >= 4 && major <= 65535 - && minor >=0 && minor <= 65535 -> - tcConfigB.subsystemVersion <- (major, minor) - | _ -> fail() - | _ -> fail() - -let SetUseSdkSwitch (tcConfigB: TcConfigBuilder) switch = - tcConfigB.useSdkRefs <- (switch = OptionSwitch.On) - -let (++) x s = x @ [s] - -let SetTarget (tcConfigB: TcConfigBuilder)(s: string) = - match s.ToLowerInvariant() with - | "exe" -> tcConfigB.target <- CompilerTarget.ConsoleExe - | "winexe" -> tcConfigB.target <- CompilerTarget.WinExe - | "library" -> tcConfigB.target <- CompilerTarget.Dll - | "module" -> tcConfigB.target <- CompilerTarget.Module - | _ -> error(Error(FSComp.SR.optsUnrecognizedTarget s, rangeCmdArgs)) - -let SetDebugSwitch (tcConfigB: TcConfigBuilder) (dtype: string option) (s: OptionSwitch) = - match dtype with - | Some s -> - match s with - | "portable" -> - tcConfigB.portablePDB <- true - tcConfigB.embeddedPDB <- false - tcConfigB.jitTracking <- true - tcConfigB.ignoreSymbolStoreSequencePoints <- true - | "pdbonly" -> - tcConfigB.portablePDB <- false - tcConfigB.embeddedPDB <- false - tcConfigB.jitTracking <- false - | "embedded" -> - tcConfigB.portablePDB <- true - tcConfigB.embeddedPDB <- true - tcConfigB.jitTracking <- true - tcConfigB.ignoreSymbolStoreSequencePoints <- true -#if FX_NO_PDB_WRITER - // When building on the coreclr, full means portable - | "full" -> - tcConfigB.portablePDB <- true - tcConfigB.embeddedPDB <- false - tcConfigB.jitTracking <- true -#else - | "full" -> - tcConfigB.portablePDB <- false - tcConfigB.embeddedPDB <- false - tcConfigB.jitTracking <- true -#endif - - | _ -> error(Error(FSComp.SR.optsUnrecognizedDebugType s, rangeCmdArgs)) - | None -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On - tcConfigB.debuginfo <- s = OptionSwitch.On - -let SetEmbedAllSourceSwitch (tcConfigB: TcConfigBuilder) switch = - if (switch = OptionSwitch.On) then tcConfigB.embedAllSource <- true else tcConfigB.embedAllSource <- false - -let setOutFileName tcConfigB path = - let outputDir = Path.GetDirectoryName(path) - tcConfigB.outputDir <- Some outputDir - tcConfigB.outputFile <- Some path - -let setSignatureFile tcConfigB s = - tcConfigB.printSignature <- true - tcConfigB.printSignatureFile <- s - -// option tags -let tagString = "" -let tagExe = "exe" -let tagWinExe = "winexe" -let tagLibrary = "library" -let tagModule = "module" -let tagFile = "" -let tagFileList = "" -let tagDirList = "" -let tagPathList = "" -let tagResInfo = "" -let tagFullPDBOnlyPortable = "{full|pdbonly|portable|embedded}" -let tagWarnList = "" -let tagSymbolList = "" -let tagAddress = "
" -let tagAlgorithm = "{SHA1|SHA256}" -let tagInt = "" -let tagPathMap = "" -let tagNone = "" -let tagLangVersionValues = "{?|version|latest|preview}" - -// PrintOptionInfo -//---------------- - -/// Print internal "option state" information for diagnostics and regression tests. -let PrintOptionInfo (tcConfigB:TcConfigBuilder) = - printfn " jitOptUser . . . . . . : %+A" tcConfigB.optSettings.jitOptUser - printfn " localOptUser . . . . . : %+A" tcConfigB.optSettings.localOptUser - printfn " crossModuleOptUser . . : %+A" tcConfigB.optSettings.crossModuleOptUser - printfn " lambdaInlineThreshold : %+A" tcConfigB.optSettings.lambdaInlineThreshold - printfn " ignoreSymStoreSeqPts . : %+A" tcConfigB.ignoreSymbolStoreSequencePoints - printfn " doDetuple . . . . . . : %+A" tcConfigB.doDetuple - printfn " doTLR . . . . . . . . : %+A" tcConfigB.doTLR - printfn " doFinalSimplify. . . . : %+A" tcConfigB.doFinalSimplify - printfn " jitTracking . . . . . : %+A" tcConfigB.jitTracking - printfn " portablePDB. . . . . . : %+A" tcConfigB.portablePDB - printfn " embeddedPDB. . . . . . : %+A" tcConfigB.embeddedPDB - printfn " embedAllSource . . . . : %+A" tcConfigB.embedAllSource - printfn " embedSourceList. . . . : %+A" tcConfigB.embedSourceList - printfn " sourceLink . . . . . . : %+A" tcConfigB.sourceLink - printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo - printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment - printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText - printfn " copyFSharpCore . . . . : %+A" tcConfigB.copyFSharpCore - tcConfigB.includes |> List.sort - |> List.iter (printfn " include . . . . . . . : %A") - -// OptionBlock: Input files -//------------------------- - -let inputFileFlagsBoth (tcConfigB : TcConfigBuilder) = [ - CompilerOption("reference", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None, Some (FSComp.SR.optsReference())) - CompilerOption("compilertool", tagFile, OptionString (fun s -> tcConfigB.AddCompilerToolsByPath s), None, Some (FSComp.SR.optsCompilerTool())) - ] - -let referenceFlagAbbrev (tcConfigB : TcConfigBuilder) = - CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None, Some(FSComp.SR.optsShortFormOf("--reference"))) - -let compilerToolFlagAbbrev (tcConfigB : TcConfigBuilder) = - CompilerOption("t", tagFile, OptionString (fun s -> tcConfigB.AddCompilerToolsByPath s), None, Some(FSComp.SR.optsShortFormOf("--compilertool"))) - -let inputFileFlagsFsc tcConfigB = inputFileFlagsBoth tcConfigB - -let inputFileFlagsFsiBase (_tcConfigB: TcConfigBuilder) = -#if NETSTANDARD - [ CompilerOption("usesdkrefs", tagNone, OptionSwitch (SetUseSdkSwitch _tcConfigB), None, Some (FSComp.SR.useSdkRefs())) ] -#else - List.empty -#endif - -let inputFileFlagsFsi (tcConfigB: TcConfigBuilder) = - List.concat [ inputFileFlagsBoth tcConfigB; inputFileFlagsFsiBase tcConfigB] - -// OptionBlock: Errors and warnings -//--------------------------------- - -let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) = - let trimFS (s:string) = if s.StartsWithOrdinal("FS") = true then s.Substring 2 else s - let trimFStoInt (s:string) = - try - Some (int32 (trimFS s)) - with _ -> - errorR(Error(FSComp.SR.buildArgInvalidInt s, rangeCmdArgs)) - None - [ - CompilerOption("warnaserror", tagNone, OptionSwitch(fun switch -> - tcConfigB.errorSeverityOptions <- - { tcConfigB.errorSeverityOptions with - GlobalWarnAsError = switch <> OptionSwitch.Off }), None, Some (FSComp.SR.optsWarnaserrorPM())) - - CompilerOption("warnaserror", tagWarnList, OptionStringListSwitch (fun n switch -> - match trimFStoInt n with - | Some n -> - let options = tcConfigB.errorSeverityOptions - tcConfigB.errorSeverityOptions <- - if switch = OptionSwitch.Off then - { options with - WarnAsError = ListSet.remove (=) n options.WarnAsError - WarnAsWarn = ListSet.insert (=) n options.WarnAsWarn } - else - { options with - WarnAsError = ListSet.insert (=) n options.WarnAsError - WarnAsWarn = ListSet.remove (=) n options.WarnAsWarn } - | None -> ()), None, Some (FSComp.SR.optsWarnaserror())) - - CompilerOption("warn", tagInt, OptionInt (fun n -> - tcConfigB.errorSeverityOptions <- - { tcConfigB.errorSeverityOptions with - WarnLevel = if (n >= 0 && n <= 5) then n else error(Error (FSComp.SR.optsInvalidWarningLevel n, rangeCmdArgs)) } - ), None, Some (FSComp.SR.optsWarn())) - - CompilerOption("nowarn", tagWarnList, OptionStringList (fun n -> - tcConfigB.TurnWarningOff(rangeCmdArgs, trimFS n)), None, Some (FSComp.SR.optsNowarn())) - - CompilerOption("warnon", tagWarnList, OptionStringList (fun n -> - tcConfigB.TurnWarningOn(rangeCmdArgs, trimFS n)), None, Some (FSComp.SR.optsWarnOn())) - - CompilerOption("consolecolors", tagNone, OptionSwitch (fun switch -> - enableConsoleColoring <- switch = OptionSwitch.On), None, Some (FSComp.SR.optsConsoleColors())) - ] - - -// OptionBlock: Output files -//-------------------------- - -let outputFileFlagsFsi (_tcConfigB: TcConfigBuilder) = [] - -let outputFileFlagsFsc (tcConfigB: TcConfigBuilder) = - [ - CompilerOption - ("out", tagFile, - OptionString (setOutFileName tcConfigB), None, - Some (FSComp.SR.optsNameOfOutputFile()) ) - - CompilerOption - ("target", tagExe, - OptionString (SetTarget tcConfigB), None, - Some (FSComp.SR.optsBuildConsole())) - - CompilerOption - ("target", tagWinExe, - OptionString (SetTarget tcConfigB), None, - Some (FSComp.SR.optsBuildWindows())) - - CompilerOption - ("target", tagLibrary, - OptionString (SetTarget tcConfigB), None, - Some (FSComp.SR.optsBuildLibrary())) - - CompilerOption - ("target", tagModule, - OptionString (SetTarget tcConfigB), None, - Some (FSComp.SR.optsBuildModule())) - - CompilerOption - ("delaysign", tagNone, - OptionSwitch (fun s -> tcConfigB.delaysign <- (s = OptionSwitch.On)), None, - Some (FSComp.SR.optsDelaySign())) - - CompilerOption - ("publicsign", tagNone, - OptionSwitch (fun s -> tcConfigB.publicsign <- (s = OptionSwitch.On)), None, - Some (FSComp.SR.optsPublicSign())) - - CompilerOption - ("doc", tagFile, - OptionString (fun s -> tcConfigB.xmlDocOutputFile <- Some s), None, - Some (FSComp.SR.optsWriteXml())) - - CompilerOption - ("keyfile", tagFile, - OptionString (fun s -> tcConfigB.signer <- Some s), None, - Some (FSComp.SR.optsStrongKeyFile())) - - CompilerOption - ("keycontainer", tagString, - OptionString(fun s -> tcConfigB.container <- Some s), None, - Some(FSComp.SR.optsStrongKeyContainer())) - - CompilerOption - ("platform", tagString, - OptionString (fun s -> - tcConfigB.platform <- - match s with - | "x86" -> Some X86 - | "x64" -> Some AMD64 - | "Itanium" -> Some IA64 - | "anycpu32bitpreferred" -> - tcConfigB.prefer32Bit <- true - None - | "anycpu" -> None - | _ -> error(Error(FSComp.SR.optsUnknownPlatform s, rangeCmdArgs))), None, - Some(FSComp.SR.optsPlatform())) - - CompilerOption - ("nooptimizationdata", tagNone, - OptionUnit (fun () -> tcConfigB.onlyEssentialOptimizationData <- true), None, - Some (FSComp.SR.optsNoOpt())) - - CompilerOption - ("nointerfacedata", tagNone, - OptionUnit (fun () -> tcConfigB.noSignatureData <- true), None, - Some (FSComp.SR.optsNoInterface())) - - CompilerOption - ("sig", tagFile, - OptionString (setSignatureFile tcConfigB), None, - Some (FSComp.SR.optsSig())) - - CompilerOption - ("nocopyfsharpcore", tagNone, - OptionUnit (fun () -> tcConfigB.copyFSharpCore <- CopyFSharpCoreFlag.No), None, - Some (FSComp.SR.optsNoCopyFsharpCore())) - ] - - -// OptionBlock: Resources -//----------------------- - -let resourcesFlagsFsi (_tcConfigB: TcConfigBuilder) = [] -let resourcesFlagsFsc (tcConfigB: TcConfigBuilder) = - [ - CompilerOption - ("win32res", tagFile, - OptionString (fun s -> tcConfigB.win32res <- s), None, - Some (FSComp.SR.optsWin32res())) - - CompilerOption - ("win32manifest", tagFile, - OptionString (fun s -> tcConfigB.win32manifest <- s), None, - Some (FSComp.SR.optsWin32manifest())) - - CompilerOption - ("nowin32manifest", tagNone, - OptionUnit (fun () -> tcConfigB.includewin32manifest <- false), None, - Some (FSComp.SR.optsNowin32manifest())) - - CompilerOption - ("resource", tagResInfo, - OptionString (fun s -> tcConfigB.AddEmbeddedResource s), None, - Some (FSComp.SR.optsResource())) - - CompilerOption - ("linkresource", tagResInfo, - OptionString (fun s -> tcConfigB.linkResources <- tcConfigB.linkResources ++ s), None, - Some (FSComp.SR.optsLinkresource())) - ] - - -// OptionBlock: Code generation -//----------------------------- - -let codeGenerationFlags isFsi (tcConfigB: TcConfigBuilder) = - let debug = - [ CompilerOption - ("debug", tagNone, - OptionSwitch (SetDebugSwitch tcConfigB None), None, - Some (FSComp.SR.optsDebugPM())) - - CompilerOption - ("debug", tagFullPDBOnlyPortable, - OptionString (fun s -> SetDebugSwitch tcConfigB (Some s) OptionSwitch.On), None, - Some (FSComp.SR.optsDebug(if isFsi then "pdbonly" else "full"))) - ] - let embed = - [ CompilerOption - ("embed", tagNone, - OptionSwitch (SetEmbedAllSourceSwitch tcConfigB), None, - Some (FSComp.SR.optsEmbedAllSource())) - - CompilerOption - ("embed", tagFileList, - OptionStringList (fun f -> tcConfigB.AddEmbeddedSourceFile f), None, - Some ( FSComp.SR.optsEmbedSource())) - - CompilerOption - ("sourcelink", tagFile, - OptionString (fun f -> tcConfigB.sourceLink <- f), None, - Some ( FSComp.SR.optsSourceLink())) - ] - - let codegen = - [ CompilerOption - ("optimize", tagNone, - OptionSwitch (SetOptimizeSwitch tcConfigB), None, - Some (FSComp.SR.optsOptimize())) - - CompilerOption - ("tailcalls", tagNone, - OptionSwitch (SetTailcallSwitch tcConfigB), None, - Some (FSComp.SR.optsTailcalls())) - - CompilerOption - ("deterministic", tagNone, - OptionSwitch (SetDeterministicSwitch tcConfigB), None, - Some (FSComp.SR.optsDeterministic())) - - CompilerOption - ("pathmap", tagPathMap, - OptionStringList (AddPathMapping tcConfigB), None, - Some (FSComp.SR.optsPathMap())) - - CompilerOption - ("crossoptimize", tagNone, - OptionSwitch (crossOptimizeSwitch tcConfigB), None, - Some (FSComp.SR.optsCrossoptimize())) - ] - if isFsi then debug @ codegen - else debug @ embed @ codegen - -// OptionBlock: Language -//---------------------- - -let defineSymbol tcConfigB s = tcConfigB.conditionalCompilationDefines <- s :: tcConfigB.conditionalCompilationDefines - -let mlCompatibilityFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("mlcompatibility", tagNone, - OptionUnit (fun () -> tcConfigB.mlCompatibility<-true; tcConfigB.TurnWarningOff(rangeCmdArgs, "62")), None, - Some (FSComp.SR.optsMlcompatibility())) - -/// LanguageVersion management -let setLanguageVersion (specifiedVersion) = - - let languageVersion = new LanguageVersion(specifiedVersion) - let dumpAllowedValues () = - printfn "%s" (FSComp.SR.optsSupportedLangVersions()) - for v in languageVersion.ValidOptions do printfn "%s" v - for v in languageVersion.ValidVersions do printfn "%s" v - exit 0 - - if specifiedVersion = "?" then dumpAllowedValues () - if not (languageVersion.ContainsVersion specifiedVersion) then error(Error(FSComp.SR.optsUnrecognizedLanguageVersion specifiedVersion, rangeCmdArgs)) - languageVersion - -let languageFlags tcConfigB = - [ - // -langversion:? Display the allowed values for language version - // -langversion: Specify language version such as - // 'default' (latest major version), or - // 'latest' (latest version, including minor versions), - // 'preview' (features for preview) - // or specific versions like '4.7' - CompilerOption("langversion", tagLangVersionValues, OptionString (fun switch -> tcConfigB.langVersion <- setLanguageVersion(switch)), None, Some (FSComp.SR.optsLangVersion())) - - CompilerOption("checked", tagNone, OptionSwitch (fun switch -> tcConfigB.checkOverflow <- (switch = OptionSwitch.On)), None, Some (FSComp.SR.optsChecked())) - CompilerOption("define", tagString, OptionString (defineSymbol tcConfigB), None, Some (FSComp.SR.optsDefine())) - mlCompatibilityFlag tcConfigB - ] - -// OptionBlock: Advanced user options -//----------------------------------- - -let libFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("lib", tagDirList, - OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), None, - Some (FSComp.SR.optsLib())) - -let codePageFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("codepage", tagInt, - OptionInt (fun n -> - try - System.Text.Encoding.GetEncoding n |> ignore - with :? System.ArgumentException as err -> - error(Error(FSComp.SR.optsProblemWithCodepage(n, err.Message), rangeCmdArgs)) - - tcConfigB.inputCodePage <- Some n), None, - Some (FSComp.SR.optsCodepage())) - -let preferredUiLang (tcConfigB: TcConfigBuilder) = - CompilerOption - ("preferreduilang", tagString, - OptionString (fun s -> tcConfigB.preferredUiLang <- Some s), None, - Some(FSComp.SR.optsPreferredUiLang())) - -let utf8OutputFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("utf8output", tagNone, - OptionUnit (fun () -> tcConfigB.utf8output <- true), None, - Some (FSComp.SR.optsUtf8output())) - -let fullPathsFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("fullpaths", tagNone, - OptionUnit (fun () -> tcConfigB.showFullPaths <- true), None, - Some (FSComp.SR.optsFullpaths())) - -let cliRootFlag (_tcConfigB: TcConfigBuilder) = - CompilerOption - ("cliroot", tagString, - OptionString (fun _ -> ()), Some(DeprecatedCommandLineOptionFull(FSComp.SR.optsClirootDeprecatedMsg(), rangeCmdArgs)), - Some(FSComp.SR.optsClirootDescription())) - -let SetTargetProfile tcConfigB v = - tcConfigB.primaryAssembly <- - match v with - // Indicates we assume "mscorlib.dll", i.e .NET Framework, Mono and Profile 47 - | "mscorlib" -> PrimaryAssembly.Mscorlib - // Indicates we assume "System.Runtime.dll", i.e .NET Standard 1.x, .NET Core App 1.x and above, and Profile 7/78/259 - | "netcore" -> PrimaryAssembly.System_Runtime - // Indicates we assume "netstandard.dll", i.e .NET Standard 2.0 and above - | "netstandard" -> PrimaryAssembly.NetStandard - | _ -> error(Error(FSComp.SR.optsInvalidTargetProfile v, rangeCmdArgs)) - -let advancedFlagsBoth tcConfigB = - [ - yield codePageFlag tcConfigB - yield utf8OutputFlag tcConfigB - yield preferredUiLang tcConfigB - yield fullPathsFlag tcConfigB - yield libFlag tcConfigB - yield CompilerOption - ("simpleresolution", - tagNone, - OptionUnit (fun () -> tcConfigB.useSimpleResolution<-true), None, - Some (FSComp.SR.optsSimpleresolution())) - - yield CompilerOption - ("targetprofile", tagString, - OptionString (SetTargetProfile tcConfigB), None, - Some(FSComp.SR.optsTargetProfile())) - ] - -let noFrameworkFlag isFsc tcConfigB = - CompilerOption - ("noframework", tagNone, - OptionUnit (fun () -> - tcConfigB.framework <- false - if isFsc then - tcConfigB.implicitlyResolveAssemblies <- false), None, - Some (FSComp.SR.optsNoframework())) - -let advancedFlagsFsi tcConfigB = - advancedFlagsBoth tcConfigB @ - [ - yield noFrameworkFlag false tcConfigB - ] - -let advancedFlagsFsc tcConfigB = - advancedFlagsBoth tcConfigB @ - [ - yield CompilerOption - ("baseaddress", tagAddress, - OptionString (fun s -> tcConfigB.baseAddress <- Some(int32 s)), None, - Some (FSComp.SR.optsBaseaddress())) - - yield CompilerOption - ("checksumalgorithm", tagAlgorithm, - OptionString (fun s -> - tcConfigB.checksumAlgorithm <- - match s.ToUpperInvariant() with - | "SHA1" -> HashAlgorithm.Sha1 - | "SHA256" -> HashAlgorithm.Sha256 - | _ -> error(Error(FSComp.SR.optsUnknownChecksumAlgorithm s, rangeCmdArgs))), None, - Some (FSComp.SR.optsChecksumAlgorithm())) - - yield noFrameworkFlag true tcConfigB - - yield CompilerOption - ("standalone", tagNone, - OptionUnit (fun _ -> - tcConfigB.openDebugInformationForLaterStaticLinking <- true - tcConfigB.standalone <- true - tcConfigB.implicitlyResolveAssemblies <- true), None, - Some (FSComp.SR.optsStandalone())) - - yield CompilerOption - ("staticlink", tagFile, - OptionString (fun s -> tcConfigB.extraStaticLinkRoots <- tcConfigB.extraStaticLinkRoots @ [s]), None, - Some (FSComp.SR.optsStaticlink())) - -#if ENABLE_MONO_SUPPORT - if runningOnMono then - yield CompilerOption - ("resident", tagFile, - OptionUnit (fun () -> ()), None, - Some (FSComp.SR.optsResident())) -#endif - - yield CompilerOption - ("pdb", tagString, - OptionString (fun s -> tcConfigB.debugSymbolFile <- Some s), None, - Some (FSComp.SR.optsPdb())) - - yield CompilerOption - ("highentropyva", tagNone, - OptionSwitch (useHighEntropyVASwitch tcConfigB), None, - Some (FSComp.SR.optsUseHighEntropyVA())) - - yield CompilerOption - ("subsystemversion", tagString, - OptionString (subSystemVersionSwitch tcConfigB), None, - Some (FSComp.SR.optsSubSystemVersion())) - - yield CompilerOption - ("quotations-debug", tagNone, - OptionSwitch(fun switch -> tcConfigB.emitDebugInfoInQuotations <- switch = OptionSwitch.On), None, - Some(FSComp.SR.optsEmitDebugInfoInQuotations())) - - ] - -// OptionBlock: Internal options (test use only) -//-------------------------------------------------- - -let testFlag tcConfigB = - CompilerOption - ("test", tagString, - OptionString (fun s -> - match s with - | "StackSpan" -> tcConfigB.internalTestSpanStackReferring <- true - | "ErrorRanges" -> tcConfigB.errorStyle <- ErrorStyle.TestErrors - | "Tracking" -> Lib.tracking <- true (* general purpose on/off diagnostics flag *) - | "NoNeedToTailcall" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportNoNeedToTailcall = true } - | "FunctionSizes" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportFunctionSizes = true } - | "TotalSizes" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportTotalSizes = true } - | "HasEffect" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportHasEffect = true } - | "NoErrorText" -> FSComp.SR.SwallowResourceText <- true - | "EmitFeeFeeAs100001" -> tcConfigB.testFlagEmitFeeFeeAs100001 <- true - | "DumpDebugInfo" -> tcConfigB.dumpDebugInfo <- true - | "ShowLoadedAssemblies" -> tcConfigB.showLoadedAssemblies <- true - | "ContinueAfterParseFailure" -> tcConfigB.continueAfterParseFailure <- true - | str -> warning(Error(FSComp.SR.optsUnknownArgumentToTheTestSwitch str, rangeCmdArgs))), None, - None) - -// Not shown in fsc.exe help, no warning on use, motivation is for use from tooling. -let editorSpecificFlags (tcConfigB: TcConfigBuilder) = - [ CompilerOption("vserrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.VSErrors), None, None) - CompilerOption("validate-type-providers", tagNone, OptionUnit id, None, None) // preserved for compatibility's sake, no longer has any effect - CompilerOption("LCID", tagInt, OptionInt ignore, None, None) - CompilerOption("flaterrors", tagNone, OptionUnit (fun () -> tcConfigB.flatErrors <- true), None, None) - CompilerOption("sqmsessionguid", tagNone, OptionString ignore, None, None) - CompilerOption("gccerrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.GccErrors), None, None) - CompilerOption("exename", tagNone, OptionString (fun s -> tcConfigB.exename <- Some s), None, None) - CompilerOption("maxerrors", tagInt, OptionInt (fun n -> tcConfigB.maxErrors <- n), None, None) - CompilerOption("noconditionalerasure", tagNone, OptionUnit (fun () -> tcConfigB.noConditionalErasure <- true), None, None) ] - -let internalFlags (tcConfigB:TcConfigBuilder) = - [ - CompilerOption - ("stamps", tagNone, - OptionUnit ignore, - Some(InternalCommandLineOption("--stamps", rangeCmdArgs)), None) - - CompilerOption - ("ranges", tagNone, - OptionSet Tastops.DebugPrint.layoutRanges, - Some(InternalCommandLineOption("--ranges", rangeCmdArgs)), None) - - CompilerOption - ("terms", tagNone, - OptionUnit (fun () -> tcConfigB.showTerms <- true), - Some(InternalCommandLineOption("--terms", rangeCmdArgs)), None) - - CompilerOption - ("termsfile", tagNone, - OptionUnit (fun () -> tcConfigB.writeTermsToFiles <- true), - Some(InternalCommandLineOption("--termsfile", rangeCmdArgs)), None) - -#if DEBUG - CompilerOption - ("debug-parse", tagNone, - OptionUnit (fun () -> Internal.Utilities.Text.Parsing.Flags.debug <- true), - Some(InternalCommandLineOption("--debug-parse", rangeCmdArgs)), None) -#endif - - CompilerOption - ("pause", tagNone, - OptionUnit (fun () -> tcConfigB.pause <- true), - Some(InternalCommandLineOption("--pause", rangeCmdArgs)), None) - - CompilerOption - ("detuple", tagNone, - OptionInt (setFlag (fun v -> tcConfigB.doDetuple <- v)), - Some(InternalCommandLineOption("--detuple", rangeCmdArgs)), None) - - CompilerOption - ("simulateException", tagNone, - OptionString (fun s -> tcConfigB.simulateException <- Some s), - Some(InternalCommandLineOption("--simulateException", rangeCmdArgs)), Some "Simulate an exception from some part of the compiler") - - CompilerOption - ("stackReserveSize", tagNone, - OptionString (fun s -> tcConfigB.stackReserveSize <- Some(int32 s)), - Some(InternalCommandLineOption("--stackReserveSize", rangeCmdArgs)), Some ("for an exe, set stack reserve size")) - - CompilerOption - ("tlr", tagInt, - OptionInt (setFlag (fun v -> tcConfigB.doTLR <- v)), - Some(InternalCommandLineOption("--tlr", rangeCmdArgs)), None) - - CompilerOption - ("finalSimplify", tagInt, - OptionInt (setFlag (fun v -> tcConfigB.doFinalSimplify <- v)), - Some(InternalCommandLineOption("--finalSimplify", rangeCmdArgs)), None) - - CompilerOption - ("parseonly", tagNone, - OptionUnit (fun () -> tcConfigB.parseOnly <- true), - Some(InternalCommandLineOption("--parseonly", rangeCmdArgs)), None) - - CompilerOption - ("typecheckonly", tagNone, - OptionUnit (fun () -> tcConfigB.typeCheckOnly <- true), - Some(InternalCommandLineOption("--typecheckonly", rangeCmdArgs)), None) - - CompilerOption - ("ast", tagNone, - OptionUnit (fun () -> tcConfigB.printAst <- true), - Some(InternalCommandLineOption("--ast", rangeCmdArgs)), None) - - CompilerOption - ("tokenize", tagNone, - OptionUnit (fun () -> tcConfigB.tokenizeOnly <- true), - Some(InternalCommandLineOption("--tokenize", rangeCmdArgs)), None) - - CompilerOption - ("testInteractionParser", tagNone, - OptionUnit (fun () -> tcConfigB.testInteractionParser <- true), - Some(InternalCommandLineOption("--testInteractionParser", rangeCmdArgs)), None) - - CompilerOption - ("testparsererrorrecovery", tagNone, - OptionUnit (fun () -> tcConfigB.reportNumDecls <- true), - Some(InternalCommandLineOption("--testparsererrorrecovery", rangeCmdArgs)), None) - - CompilerOption - ("inlinethreshold", tagInt, - OptionInt (fun n -> tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = n }), - Some(InternalCommandLineOption("--inlinethreshold", rangeCmdArgs)), None) - - CompilerOption - ("extraoptimizationloops", tagNone, - OptionInt (fun n -> tcConfigB.extraOptimizationIterations <- n), - Some(InternalCommandLineOption("--extraoptimizationloops", rangeCmdArgs)), None) - - CompilerOption - ("abortonerror", tagNone, - OptionUnit (fun () -> tcConfigB.abortOnError <- true), - Some(InternalCommandLineOption("--abortonerror", rangeCmdArgs)), None) - - CompilerOption - ("implicitresolution", tagNone, - OptionUnit (fun _ -> tcConfigB.implicitlyResolveAssemblies <- true), - Some(InternalCommandLineOption("--implicitresolution", rangeCmdArgs)), None) - - // "Display assembly reference resolution information") - CompilerOption - ("resolutions", tagNone, - OptionUnit (fun () -> tcConfigB.showReferenceResolutions <- true), - Some(InternalCommandLineOption("", rangeCmdArgs)), None) - - // "The base registry key to use for assembly resolution. This part in brackets here: HKEY_LOCAL_MACHINE\[SOFTWARE\Microsoft\.NETFramework]\v2.0.50727\AssemblyFoldersEx") - CompilerOption - ("resolutionframeworkregistrybase", tagString, - OptionString (fun _ -> ()), - Some(InternalCommandLineOption("", rangeCmdArgs)), None) - - // "The base registry key to use for assembly resolution. This part in brackets here: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\[AssemblyFoldersEx]") - CompilerOption - ("resolutionassemblyfoldersuffix", tagString, - OptionString (fun _ -> ()), - Some(InternalCommandLineOption("resolutionassemblyfoldersuffix", rangeCmdArgs)), None) - - // "Additional reference resolution conditions. For example \"OSVersion=5.1.2600.0, PlatformID=id") - CompilerOption - ("resolutionassemblyfoldersconditions", tagString, - OptionString (fun _ -> ()), - Some(InternalCommandLineOption("resolutionassemblyfoldersconditions", rangeCmdArgs)), None) - - // "Resolve assembly references using MSBuild resolution rules rather than directory based (Default=true except when running fsc.exe under mono)") - CompilerOption - ("msbuildresolution", tagNone, - OptionUnit (fun () -> tcConfigB.useSimpleResolution<-false), - Some(InternalCommandLineOption("msbuildresolution", rangeCmdArgs)), None) - - CompilerOption - ("alwayscallvirt", tagNone, - OptionSwitch(callVirtSwitch tcConfigB), - Some(InternalCommandLineOption("alwayscallvirt", rangeCmdArgs)), None) - - CompilerOption - ("nodebugdata", tagNone, - OptionUnit (fun () -> tcConfigB.noDebugData<-true), - Some(InternalCommandLineOption("--nodebugdata", rangeCmdArgs)), None) - - testFlag tcConfigB ] @ - - editorSpecificFlags tcConfigB @ - [ CompilerOption - ("jit", tagNone, - OptionSwitch (jitoptimizeSwitch tcConfigB), - Some(InternalCommandLineOption("jit", rangeCmdArgs)), None) - - CompilerOption - ("localoptimize", tagNone, - OptionSwitch(localoptimizeSwitch tcConfigB), - Some(InternalCommandLineOption("localoptimize", rangeCmdArgs)), None) - - CompilerOption - ("splitting", tagNone, - OptionSwitch(splittingSwitch tcConfigB), - Some(InternalCommandLineOption("splitting", rangeCmdArgs)), None) - - CompilerOption - ("versionfile", tagString, - OptionString (fun s -> tcConfigB.version <- VersionFile s), - Some(InternalCommandLineOption("versionfile", rangeCmdArgs)), None) - - // "Display timing profiles for compilation" - CompilerOption - ("times", tagNone, - OptionUnit (fun () -> tcConfigB.showTimes <- true), - Some(InternalCommandLineOption("times", rangeCmdArgs)), None) - -#if !NO_EXTENSIONTYPING - // "Display information about extension type resolution") - CompilerOption - ("showextensionresolution", tagNone, - OptionUnit (fun () -> tcConfigB.showExtensionTypeMessages <- true), - Some(InternalCommandLineOption("showextensionresolution", rangeCmdArgs)), None) -#endif - - CompilerOption - ("metadataversion", tagString, - OptionString (fun s -> tcConfigB.metadataVersion <- Some s), - Some(InternalCommandLineOption("metadataversion", rangeCmdArgs)), None) - ] - -// OptionBlock: Deprecated flags (fsc, service only) -//-------------------------------------------------- - -let compilingFsLibFlag (tcConfigB: TcConfigBuilder) = - CompilerOption - ("compiling-fslib", tagNone, - OptionUnit (fun () -> - tcConfigB.compilingFslib <- true - tcConfigB.TurnWarningOff(rangeStartup, "42") - ErrorLogger.reportLibraryOnlyFeatures <- false - IlxSettings.ilxCompilingFSharpCoreLib <- true), - Some(InternalCommandLineOption("--compiling-fslib", rangeCmdArgs)), None) - -let compilingFsLib20Flag = - CompilerOption ("compiling-fslib-20", tagNone, OptionString (fun _ -> () ), None, None) - -let compilingFsLib40Flag = - CompilerOption ("compiling-fslib-40", tagNone, OptionUnit (fun () -> ()), None, None) - -let compilingFsLibNoBigIntFlag = - CompilerOption ("compiling-fslib-nobigint", tagNone, OptionUnit (fun () -> () ), None, None) - -let mlKeywordsFlag = - CompilerOption - ("ml-keywords", tagNone, - OptionUnit (fun () -> ()), - Some(DeprecatedCommandLineOptionNoDescription("--ml-keywords", rangeCmdArgs)), None) - -let gnuStyleErrorsFlag tcConfigB = - CompilerOption - ("gnu-style-errors", tagNone, - OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.EmacsErrors), - Some(DeprecatedCommandLineOptionNoDescription("--gnu-style-errors", rangeCmdArgs)), None) - -let deprecatedFlagsBoth tcConfigB = - [ - CompilerOption - ("light", tagNone, - OptionUnit (fun () -> tcConfigB.light <- Some true), - Some(DeprecatedCommandLineOptionNoDescription("--light", rangeCmdArgs)), None) - - CompilerOption - ("indentation-syntax", tagNone, - OptionUnit (fun () -> tcConfigB.light <- Some true), - Some(DeprecatedCommandLineOptionNoDescription("--indentation-syntax", rangeCmdArgs)), None) - - CompilerOption - ("no-indentation-syntax", tagNone, - OptionUnit (fun () -> tcConfigB.light <- Some false), - Some(DeprecatedCommandLineOptionNoDescription("--no-indentation-syntax", rangeCmdArgs)), None) - ] - -let deprecatedFlagsFsi tcConfigB = deprecatedFlagsBoth tcConfigB - -let deprecatedFlagsFsc tcConfigB = - deprecatedFlagsBoth tcConfigB @ - [ - cliRootFlag tcConfigB - CompilerOption - ("jit-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true }), - Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) - - CompilerOption - ("no-jit-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false }), - Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) - - CompilerOption - ("jit-tracking", tagNone, - OptionUnit (fun _ -> (tcConfigB.jitTracking <- true) ), - Some(DeprecatedCommandLineOptionNoDescription("--jit-tracking", rangeCmdArgs)), None) - - CompilerOption - ("no-jit-tracking", tagNone, - OptionUnit (fun _ -> (tcConfigB.jitTracking <- false) ), - Some(DeprecatedCommandLineOptionNoDescription("--no-jit-tracking", rangeCmdArgs)), None) - - CompilerOption - ("progress", tagNone, - OptionUnit (fun () -> progress <- true), - Some(DeprecatedCommandLineOptionNoDescription("--progress", rangeCmdArgs)), None) - - compilingFsLibFlag tcConfigB - compilingFsLib20Flag - compilingFsLib40Flag - compilingFsLibNoBigIntFlag - - CompilerOption - ("version", tagString, - OptionString (fun s -> tcConfigB.version <- VersionString s), - Some(DeprecatedCommandLineOptionNoDescription("--version", rangeCmdArgs)), None) - - CompilerOption - ("local-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true }), - Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) - - CompilerOption - ("no-local-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false }), - Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) - - CompilerOption - ("cross-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true }), - Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) - - CompilerOption - ("no-cross-optimize", tagNone, - OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false }), - Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) - - CompilerOption - ("no-string-interning", tagNone, - OptionUnit (fun () -> tcConfigB.internConstantStrings <- false), - Some(DeprecatedCommandLineOptionNoDescription("--no-string-interning", rangeCmdArgs)), None) - - CompilerOption - ("statistics", tagNone, - OptionUnit (fun () -> tcConfigB.stats <- true), - Some(DeprecatedCommandLineOptionNoDescription("--statistics", rangeCmdArgs)), None) - - CompilerOption - ("generate-filter-blocks", tagNone, - OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- true), - Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) - - //CompilerOption - // ("no-generate-filter-blocks", tagNone, - // OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- false), - // Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) - - CompilerOption - ("max-errors", tagInt, - OptionInt (fun n -> tcConfigB.maxErrors <- n), - Some(DeprecatedCommandLineOptionSuggestAlternative("--max-errors", "--maxerrors", rangeCmdArgs)), None) - - CompilerOption - ("debug-file", tagNone, - OptionString (fun s -> tcConfigB.debugSymbolFile <- Some s), - Some(DeprecatedCommandLineOptionSuggestAlternative("--debug-file", "--pdb", rangeCmdArgs)), None) - - CompilerOption - ("no-debug-file", tagNone, - OptionUnit (fun () -> tcConfigB.debuginfo <- false), - Some(DeprecatedCommandLineOptionSuggestAlternative("--no-debug-file", "--debug-", rangeCmdArgs)), None) - - CompilerOption - ("Ooff", tagNone, - OptionUnit (fun () -> SetOptimizeOff tcConfigB), - Some(DeprecatedCommandLineOptionSuggestAlternative("-Ooff", "--optimize-", rangeCmdArgs)), None) - - mlKeywordsFlag - gnuStyleErrorsFlag tcConfigB ] - - -// OptionBlock: Miscellaneous options -//----------------------------------- - -let DisplayBannerText tcConfigB = - if tcConfigB.showBanner then ( - printfn "%s" tcConfigB.productNameForBannerText - printfn "%s" (FSComp.SR.optsCopyright()) - ) - -/// FSC only help. (FSI has it's own help function). -let displayHelpFsc tcConfigB (blocks:CompilerOptionBlock list) = - DisplayBannerText tcConfigB - PrintCompilerOptionBlocks blocks - exit 0 - -let miscFlagsBoth tcConfigB = - [ CompilerOption("nologo", tagNone, OptionUnit (fun () -> tcConfigB.showBanner <- false), None, Some (FSComp.SR.optsNologo())) - ] - -let miscFlagsFsc tcConfigB = - miscFlagsBoth tcConfigB @ - [ CompilerOption("help", tagNone, OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, Some (FSComp.SR.optsHelp())) - CompilerOption("@", tagNone, OptionUnit ignore, None, Some (FSComp.SR.optsResponseFile())) - ] -let miscFlagsFsi tcConfigB = miscFlagsBoth tcConfigB - - -// OptionBlock: Abbreviations of existing options -//----------------------------------------------- - -let abbreviatedFlagsBoth tcConfigB = - [ - CompilerOption("d", tagString, OptionString (defineSymbol tcConfigB), None, Some(FSComp.SR.optsShortFormOf("--define"))) - CompilerOption("O", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB), None, Some(FSComp.SR.optsShortFormOf("--optimize[+|-]"))) - CompilerOption("g", tagNone, OptionSwitch (SetDebugSwitch tcConfigB None), None, Some(FSComp.SR.optsShortFormOf("--debug"))) - CompilerOption("i", tagString, OptionUnit (fun () -> tcConfigB.printSignature <- true), None, Some(FSComp.SR.optsShortFormOf("--sig"))) - CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), - None, Some(FSComp.SR.optsShortFormOf("--reference"))) - CompilerOption("I", tagDirList, OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), - None, Some (FSComp.SR.optsShortFormOf("--lib"))) - ] - -let abbreviatedFlagsFsi tcConfigB = abbreviatedFlagsBoth tcConfigB - -let abbreviatedFlagsFsc tcConfigB = - abbreviatedFlagsBoth tcConfigB @ - [ // FSC only abbreviated options - CompilerOption - ("o", tagString, - OptionString (setOutFileName tcConfigB), None, - Some(FSComp.SR.optsShortFormOf("--out"))) - - CompilerOption - ("a", tagString, - OptionUnit (fun () -> tcConfigB.target <- CompilerTarget.Dll), None, - Some(FSComp.SR.optsShortFormOf("--target library"))) - - // FSC help abbreviations. FSI has it's own help options... - CompilerOption - ("?", tagNone, - OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, - Some(FSComp.SR.optsShortFormOf("--help"))) - - CompilerOption - ("help", tagNone, - OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, - Some(FSComp.SR.optsShortFormOf("--help"))) - - CompilerOption - ("full-help", tagNone, - OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, - Some(FSComp.SR.optsShortFormOf("--help"))) - ] - -let GetAbbrevFlagSet tcConfigB isFsc = - let mutable argList: string list = [] - for c in ((if isFsc then abbreviatedFlagsFsc else abbreviatedFlagsFsi) tcConfigB) do - match c with - | CompilerOption(arg, _, OptionString _, _, _) - | CompilerOption(arg, _, OptionStringList _, _, _) -> argList <- argList @ ["-"+arg;"/"+arg] - | _ -> () - Set.ofList argList - -// check for abbreviated options that accept spaces instead of colons, and replace the spaces -// with colons when necessary -let PostProcessCompilerArgs (abbrevArgs: string Set) (args: string []) = - let mutable i = 0 - let mutable idx = 0 - let len = args.Length - let mutable arga: string[] = Array.create len "" - - while i < len do - if not(abbrevArgs.Contains(args.[i])) || i = (len - 1) then - arga.[idx] <- args.[i] - i <- i+1 - else - arga.[idx] <- args.[i] + ":" + args.[i+1] - i <- i + 2 - idx <- idx + 1 - Array.toList arga.[0 .. (idx - 1)] - -// OptionBlock: QA options -//------------------------ - -let testingAndQAFlags _tcConfigB = - [ - CompilerOption - ("dumpAllCommandLineOptions", tagNone, - OptionHelp(fun blocks -> DumpCompilerOptionBlocks blocks), - None, None) // "Command line options") - ] - - -// Core compiler options, overview -//-------------------------------- - -(* The "core" compiler options are "the ones defined here". - Currently, fsi.exe has some additional options, defined in fsi.fs. - - The compiler options are put into blocks, named as Flags. - Some block options differ between fsc and fsi, in this case they split as FlagsFsc and FlagsFsi. - - The "service.fs" (language service) flags are the same as the fsc flags (except help options are removed). - REVIEW: is this correct? what about fsx files in VS and fsi options? - - Block | notes - ---------------------------|-------------------- - outputFileFlags | - inputFileFlags | - resourcesFlags | - codeGenerationFlags | - errorsAndWarningsFlags | - languageFlags | - miscFlags | - advancedFlags | - internalFlags | - abbreviatedFlags | - deprecatedFlags | REVIEW: some of these may have been valid for fsi.exe? - fsiSpecificFlags | These are defined later, in fsi.fs - ---------------------------|-------------------- -*) - -// Core compiler options exported to fsc.fs, service.fs and fsi.fs -//---------------------------------------------------------------- - -/// The core/common options used by fsc.exe. [not currently extended by fsc.fs]. -let GetCoreFscCompilerOptions (tcConfigB: TcConfigBuilder) = - [ PublicOptions(FSComp.SR.optsHelpBannerOutputFiles(), outputFileFlagsFsc tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerInputFiles(), inputFileFlagsFsc tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerResources(), resourcesFlagsFsc tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerCodeGen(), codeGenerationFlags false tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerErrsAndWarns(), errorsAndWarningsFlags tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerLanguage(), languageFlags tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerMisc(), miscFlagsFsc tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), advancedFlagsFsc tcConfigB) - PrivateOptions(List.concat [ internalFlags tcConfigB - abbreviatedFlagsFsc tcConfigB - deprecatedFlagsFsc tcConfigB - testingAndQAFlags tcConfigB]) - ] - -/// The core/common options used by the F# VS Language Service. -/// Filter out OptionHelp which does printing then exit. This is not wanted in the context of VS!! -let GetCoreServiceCompilerOptions (tcConfigB:TcConfigBuilder) = - let isHelpOption = function CompilerOption(_, _, OptionHelp _, _, _) -> true | _ -> false - List.map (FilterCompilerOptionBlock (isHelpOption >> not)) (GetCoreFscCompilerOptions tcConfigB) - -/// The core/common options used by fsi.exe. [note, some additional options are added in fsi.fs]. -let GetCoreFsiCompilerOptions (tcConfigB: TcConfigBuilder) = - [ PublicOptions(FSComp.SR.optsHelpBannerOutputFiles(), outputFileFlagsFsi tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerInputFiles(), inputFileFlagsFsi tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerResources(), resourcesFlagsFsi tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerCodeGen(), codeGenerationFlags true tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerErrsAndWarns(), errorsAndWarningsFlags tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerLanguage(), languageFlags tcConfigB) - // Note: no HTML block for fsi.exe - PublicOptions(FSComp.SR.optsHelpBannerMisc(), miscFlagsFsi tcConfigB) - PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), advancedFlagsFsi tcConfigB) - PrivateOptions(List.concat [ internalFlags tcConfigB - abbreviatedFlagsFsi tcConfigB - deprecatedFlagsFsi tcConfigB - testingAndQAFlags tcConfigB]) - ] - -let ApplyCommandLineArgs(tcConfigB: TcConfigBuilder, sourceFiles: string list, commandLineArgs) = - try - let sourceFilesAcc = ResizeArray sourceFiles - let collect name = if not (Filename.isDll name) then sourceFilesAcc.Add name - ParseCompilerOptions(collect, GetCoreServiceCompilerOptions tcConfigB, commandLineArgs) - ResizeArray.toList sourceFilesAcc - with e -> - errorRecovery e range0 - sourceFiles - - -//---------------------------------------------------------------------------- -// PrintWholeAssemblyImplementation -//---------------------------------------------------------------------------- - -let mutable showTermFileCount = 0 -let PrintWholeAssemblyImplementation g (tcConfig:TcConfig) outfile header expr = - if tcConfig.showTerms then - if tcConfig.writeTermsToFiles then - let filename = outfile + ".terms" - use f = System.IO.File.CreateText (filename + "-" + string showTermFileCount + "-" + header) - showTermFileCount <- showTermFileCount + 1 - Layout.outL f (Layout.squashTo 192 (DebugPrint.implFilesL g expr)) - else - dprintf "\n------------------\nshowTerm: %s:\n" header - Layout.outL stderr (Layout.squashTo 192 (DebugPrint.implFilesL g expr)) - dprintf "\n------------------\n" - -//---------------------------------------------------------------------------- -// ReportTime -//---------------------------------------------------------------------------- - -let mutable tPrev = None -let mutable nPrev = None -let ReportTime (tcConfig:TcConfig) descr = - - match nPrev with - | None -> () - | Some prevDescr -> - if tcConfig.pause then - dprintf "[done '%s', entering '%s'] press to continue... " prevDescr descr - System.Console.ReadLine() |> ignore - // Intentionally putting this right after the pause so a debugger can be attached. - match tcConfig.simulateException with - | Some("fsc-oom") -> raise(System.OutOfMemoryException()) - | Some("fsc-an") -> raise(System.ArgumentNullException("simulated")) - | Some("fsc-invop") -> raise(System.InvalidOperationException()) - | Some("fsc-av") -> raise(System.AccessViolationException()) - | Some("fsc-aor") -> raise(System.ArgumentOutOfRangeException()) - | Some("fsc-dv0") -> raise(System.DivideByZeroException()) - | Some("fsc-nfn") -> raise(System.NotFiniteNumberException()) - | Some("fsc-oe") -> raise(System.OverflowException()) - | Some("fsc-atmm") -> raise(System.ArrayTypeMismatchException()) - | Some("fsc-bif") -> raise(System.BadImageFormatException()) - | Some("fsc-knf") -> raise(System.Collections.Generic.KeyNotFoundException()) - | Some("fsc-ior") -> raise(System.IndexOutOfRangeException()) - | Some("fsc-ic") -> raise(System.InvalidCastException()) - | Some("fsc-ip") -> raise(System.InvalidProgramException()) - | Some("fsc-ma") -> raise(System.MemberAccessException()) - | Some("fsc-ni") -> raise(System.NotImplementedException()) - | Some("fsc-nr") -> raise(System.NullReferenceException()) - | Some("fsc-oc") -> raise(System.OperationCanceledException()) - | Some("fsc-fail") -> failwith "simulated" - | _ -> () - - - - - if (tcConfig.showTimes || verbose) then - // Note that timing calls are relatively expensive on the startup path so we don't - // make this call unless showTimes has been turned on. - let timeNow = System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds - let maxGen = System.GC.MaxGeneration - let gcNow = [| for i in 0 .. maxGen -> System.GC.CollectionCount i |] - let ptime = System.Diagnostics.Process.GetCurrentProcess() - let wsNow = ptime.WorkingSet64/1000000L - - match tPrev, nPrev with - | Some (timePrev, gcPrev:int []), Some prevDescr -> - let spanGC = [| for i in 0 .. maxGen -> System.GC.CollectionCount i - gcPrev.[i] |] - dprintf "TIME: %4.1f Delta: %4.1f Mem: %3d" - timeNow (timeNow - timePrev) - wsNow - dprintf " G0: %3d G1: %2d G2: %2d [%s]\n" - spanGC.[Operators.min 0 maxGen] spanGC.[Operators.min 1 maxGen] spanGC.[Operators.min 2 maxGen] - prevDescr - - | _ -> () - tPrev <- Some (timeNow, gcNow) - - nPrev <- Some descr - -//---------------------------------------------------------------------------- -// OPTIMIZATION - support - addDllToOptEnv -//---------------------------------------------------------------------------- - -let AddExternalCcuToOptimizationEnv tcGlobals optEnv (ccuinfo: ImportedAssembly) = - match ccuinfo.FSharpOptimizationData.Force() with - | None -> optEnv - | Some data -> Optimizer.BindCcu ccuinfo.FSharpViewOfMetadata data optEnv tcGlobals - -//---------------------------------------------------------------------------- -// OPTIMIZATION - support - optimize -//---------------------------------------------------------------------------- - -let GetInitialOptimizationEnv (tcImports:TcImports, tcGlobals:TcGlobals) = - let ccuinfos = tcImports.GetImportedAssemblies() - let optEnv = Optimizer.IncrementalOptimizationEnv.Empty - let optEnv = List.fold (AddExternalCcuToOptimizationEnv tcGlobals) optEnv ccuinfos - optEnv - -let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importMap, isIncrementalFragment, optEnv, ccu:CcuThunk, implFiles) = - // NOTE: optEnv - threads through - // - // Always optimize once - the results of this step give the x-module optimization - // info. Subsequent optimization steps choose representations etc. which we don't - // want to save in the x-module info (i.e. x-module info is currently "high level"). - PrintWholeAssemblyImplementation tcGlobals tcConfig outfile "pass-start" implFiles -#if DEBUG - if tcConfig.showOptimizationData then - dprintf "Expression prior to optimization:\n%s\n" (Layout.showL (Layout.squashTo 192 (DebugPrint.implFilesL tcGlobals implFiles))) - - if tcConfig.showOptimizationData then - dprintf "CCU prior to optimization:\n%s\n" (Layout.showL (Layout.squashTo 192 (DebugPrint.entityL tcGlobals ccu.Contents))) -#endif - - let optEnv0 = optEnv - ReportTime tcConfig ("Optimizations") - - // Only do abstract_big_targets on the first pass! Only do it when TLR is on! - let optSettings = tcConfig.optSettings - let optSettings = { optSettings with abstractBigTargets = tcConfig.doTLR } - let optSettings = { optSettings with reportingPhase = true } - - let results, (optEnvFirstLoop, _, _, _) = - ((optEnv0, optEnv0, optEnv0, SignatureHidingInfo.Empty), implFiles) - - ||> List.mapFold (fun (optEnvFirstLoop, optEnvExtraLoop, optEnvFinalSimplify, hidden) implFile -> - - //ReportTime tcConfig ("Initial simplify") - let (optEnvFirstLoop, implFile, implFileOptData, hidden), optimizeDuringCodeGen = - Optimizer.OptimizeImplFile - (optSettings, ccu, tcGlobals, tcVal, importMap, - optEnvFirstLoop, isIncrementalFragment, - tcConfig.emitTailcalls, hidden, implFile) - - let implFile = AutoBox.TransformImplFile tcGlobals importMap implFile - - // Only do this on the first pass! - let optSettings = { optSettings with abstractBigTargets = false; reportingPhase = false } -#if DEBUG - if tcConfig.showOptimizationData then - dprintf "Optimization implFileOptData:\n%s\n" (Layout.showL (Layout.squashTo 192 (Optimizer.moduleInfoL tcGlobals implFileOptData))) -#endif - - let implFile, optEnvExtraLoop = - if tcConfig.extraOptimizationIterations > 0 then - - //ReportTime tcConfig ("Extra simplification loop") - let (optEnvExtraLoop, implFile, _, _), _ = - Optimizer.OptimizeImplFile - (optSettings, ccu, tcGlobals, tcVal, importMap, - optEnvExtraLoop, isIncrementalFragment, - tcConfig.emitTailcalls, hidden, implFile) - - //PrintWholeAssemblyImplementation tcConfig outfile (sprintf "extra-loop-%d" n) implFile - implFile, optEnvExtraLoop - else - implFile, optEnvExtraLoop - - let implFile = - if tcConfig.doDetuple then - //ReportTime tcConfig ("Detupled optimization") - let implFile = implFile |> Detuple.DetupleImplFile ccu tcGlobals - //PrintWholeAssemblyImplementation tcConfig outfile "post-detuple" implFile - implFile - else implFile - - let implFile = - if tcConfig.doTLR then - implFile |> InnerLambdasToTopLevelFuncs.MakeTLRDecisions ccu tcGlobals - else implFile - - let implFile = - LowerCallsAndSeqs.LowerImplFile tcGlobals implFile - - let implFile, optEnvFinalSimplify = - if tcConfig.doFinalSimplify then - - //ReportTime tcConfig ("Final simplify pass") - let (optEnvFinalSimplify, implFile, _, _), _ = - Optimizer.OptimizeImplFile - (optSettings, ccu, tcGlobals, tcVal, importMap, optEnvFinalSimplify, - isIncrementalFragment, tcConfig.emitTailcalls, hidden, implFile) - - //PrintWholeAssemblyImplementation tcConfig outfile "post-rec-opt" implFile - implFile, optEnvFinalSimplify - else - implFile, optEnvFinalSimplify - - ((implFile, optimizeDuringCodeGen), implFileOptData), (optEnvFirstLoop, optEnvExtraLoop, optEnvFinalSimplify, hidden)) - - let implFiles, implFileOptDatas = List.unzip results - let assemblyOptData = Optimizer.UnionOptimizationInfos implFileOptDatas - let tassembly = TypedAssemblyAfterOptimization implFiles - PrintWholeAssemblyImplementation tcGlobals tcConfig outfile "pass-end" (List.map fst implFiles) - ReportTime tcConfig ("Ending Optimizations") - tassembly, assemblyOptData, optEnvFirstLoop - -//---------------------------------------------------------------------------- -// ILX generation -//---------------------------------------------------------------------------- - -let CreateIlxAssemblyGenerator (_tcConfig:TcConfig, tcImports:TcImports, tcGlobals, tcVal, generatedCcu) = - let ilxGenerator = new IlxGen.IlxAssemblyGenerator (tcImports.GetImportMap(), tcGlobals, tcVal, generatedCcu) - let ccus = tcImports.GetCcusInDeclOrder() - ilxGenerator.AddExternalCcus ccus - ilxGenerator - -let GenerateIlxCode - (ilxBackend, isInteractiveItExpr, isInteractiveOnMono, - tcConfig:TcConfig, topAttrs: TypeChecker.TopAttribs, optimizedImpls, - fragName, ilxGenerator: IlxAssemblyGenerator) = - - let mainMethodInfo = - if (tcConfig.target = CompilerTarget.Dll) || (tcConfig.target = CompilerTarget.Module) then - None - else Some topAttrs.mainMethodAttrs - - let ilxGenOpts: IlxGenOptions = - { generateFilterBlocks = tcConfig.generateFilterBlocks - emitConstantArraysUsingStaticDataBlobs = not isInteractiveOnMono - workAroundReflectionEmitBugs=tcConfig.isInteractive // REVIEW: is this still required? - generateDebugSymbols= tcConfig.debuginfo - fragName = fragName - localOptimizationsAreOn= tcConfig.optSettings.localOpt () - testFlagEmitFeeFeeAs100001 = tcConfig.testFlagEmitFeeFeeAs100001 - mainMethodInfo= mainMethodInfo - ilxBackend = ilxBackend - isInteractive = tcConfig.isInteractive - isInteractiveItExpr = isInteractiveItExpr - alwaysCallVirt = tcConfig.alwaysCallVirt } - - ilxGenerator.GenerateCode (ilxGenOpts, optimizedImpls, topAttrs.assemblyAttrs, topAttrs.netModuleAttrs) - -//---------------------------------------------------------------------------- -// Assembly ref normalization: make sure all assemblies are referred to -// by the same references. Only used for static linking. -//---------------------------------------------------------------------------- - -let NormalizeAssemblyRefs (ctok, ilGlobals: ILGlobals, tcImports:TcImports) scoref = - let normalizeAssemblyRefByName nm = - match tcImports.TryFindDllInfo (ctok, Range.rangeStartup, nm, lookupOnly=false) with - | Some dllInfo -> dllInfo.ILScopeRef - | None -> scoref - - match scoref with - | ILScopeRef.Local - | ILScopeRef.Module _ -> scoref - | ILScopeRef.PrimaryAssembly -> normalizeAssemblyRefByName ilGlobals.primaryAssemblyName - | ILScopeRef.Assembly aref -> normalizeAssemblyRefByName aref.Name - -let GetGeneratedILModuleName (t:CompilerTarget) (s:string) = - // return the name of the file as a module name - let ext = match t with CompilerTarget.Dll -> "dll" | CompilerTarget.Module -> "netmodule" | _ -> "exe" - s + "." + ext - -let ignoreFailureOnMono1_1_16 f = try f() with _ -> () - -let foreBackColor () = - try - let c = Console.ForegroundColor // may fail, perhaps on Mac, and maybe ForegroundColor is Black - let b = Console.BackgroundColor // may fail, perhaps on Mac, and maybe BackgroundColor is White - Some (c, b) - with - e -> None - -let DoWithColor newColor f = - match enableConsoleColoring, foreBackColor() with - | false, _ - | true, None -> - // could not get console colours, so no attempt to change colours, can not set them back - f() - | true, Some (c, _) -> - try - ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- newColor) - f() - finally - ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- c) - -let DoWithErrorColor isError f = - match foreBackColor() with - | None -> f() - | Some (_, backColor) -> - let warnColor = if backColor = ConsoleColor.White then ConsoleColor.DarkBlue else ConsoleColor.Cyan - let errorColor = ConsoleColor.Red - let color = if isError then errorColor else warnColor - DoWithColor color f diff --git a/src/fsharp/CompileOptions.fsi b/src/fsharp/CompileOptions.fsi deleted file mode 100644 index da86aa42005..00000000000 --- a/src/fsharp/CompileOptions.fsi +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.CompileOptions - -open System -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.CompileOps -open FSharp.Compiler.Tast -open FSharp.Compiler.Import -open FSharp.Compiler.Optimizer -open FSharp.Compiler.TcGlobals - -//---------------------------------------------------------------------------- -// Compiler Option Parser -//---------------------------------------------------------------------------- - -// For command-line options that can be suffixed with +/- -[] -type OptionSwitch = - | On - | Off - -/// The spec value describes the action of the argument, -/// and whether it expects a following parameter. -type OptionSpec = - | OptionClear of bool ref - | OptionFloat of (float -> unit) - | OptionInt of (int -> unit) - | OptionSwitch of (OptionSwitch -> unit) - | OptionIntList of (int -> unit) - | OptionIntListSwitch of (int -> OptionSwitch -> unit) - | OptionRest of (string -> unit) - | OptionSet of bool ref - | OptionString of (string -> unit) - | OptionStringList of (string -> unit) - | OptionStringListSwitch of (string -> OptionSwitch -> unit) - | OptionUnit of (unit -> unit) - | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" - | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) - -and CompilerOption = - /// CompilerOption(name, argumentDescriptionString, actionSpec, exceptionOpt, helpTextOpt - | CompilerOption of string * string * OptionSpec * Option * string option - -and CompilerOptionBlock = - | PublicOptions of string * CompilerOption list - | PrivateOptions of CompilerOption list - -val PrintCompilerOptionBlocks : CompilerOptionBlock list -> unit // for printing usage -val DumpCompilerOptionBlocks : CompilerOptionBlock list -> unit // for QA -val FilterCompilerOptionBlock : (CompilerOption -> bool) -> CompilerOptionBlock -> CompilerOptionBlock - -/// Parse and process a set of compiler options -val ParseCompilerOptions : (string -> unit) * CompilerOptionBlock list * string list -> unit - -//---------------------------------------------------------------------------- -// Compiler Options -//-------------------------------------------------------------------------- - -val DisplayBannerText : TcConfigBuilder -> unit - -val GetCoreFscCompilerOptions : TcConfigBuilder -> CompilerOptionBlock list -val GetCoreFsiCompilerOptions : TcConfigBuilder -> CompilerOptionBlock list -val GetCoreServiceCompilerOptions : TcConfigBuilder -> CompilerOptionBlock list - -/// Apply args to TcConfigBuilder and return new list of source files -val ApplyCommandLineArgs: tcConfigB: TcConfigBuilder * sourceFiles: string list * argv: string list -> string list - -// Expose the "setters" for some user switches, to enable setting of defaults -val SetOptimizeSwitch : TcConfigBuilder -> OptionSwitch -> unit -val SetTailcallSwitch : TcConfigBuilder -> OptionSwitch -> unit -val SetDebugSwitch : TcConfigBuilder -> string option -> OptionSwitch -> unit -val PrintOptionInfo : TcConfigBuilder -> unit -val SetTargetProfile : TcConfigBuilder -> string -> unit - -val GetGeneratedILModuleName : CompilerTarget -> string -> string - -val GetInitialOptimizationEnv : TcImports * TcGlobals -> IncrementalOptimizationEnv -val AddExternalCcuToOptimizationEnv : TcGlobals -> IncrementalOptimizationEnv -> ImportedAssembly -> IncrementalOptimizationEnv -val ApplyAllOptimizations : TcConfig * TcGlobals * ConstraintSolver.TcValF * string * ImportMap * bool * IncrementalOptimizationEnv * CcuThunk * TypedImplFile list -> TypedAssemblyAfterOptimization * Optimizer.LazyModuleInfo * IncrementalOptimizationEnv - -val CreateIlxAssemblyGenerator : TcConfig * TcImports * TcGlobals * ConstraintSolver.TcValF * CcuThunk -> IlxGen.IlxAssemblyGenerator - -val GenerateIlxCode : IlxGen.IlxGenBackend * isInteractiveItExpr:bool * isInteractiveOnMono:bool * TcConfig * TypeChecker.TopAttribs * TypedAssemblyAfterOptimization * fragName:string * IlxGen.IlxAssemblyGenerator -> IlxGen.IlxGenResults - -// Used during static linking -val NormalizeAssemblyRefs : CompilationThreadToken * ILGlobals * TcImports -> (AbstractIL.IL.ILScopeRef -> AbstractIL.IL.ILScopeRef) - -// Miscellany -val ignoreFailureOnMono1_1_16 : (unit -> unit) -> unit -val mutable enableConsoleColoring : bool -val DoWithColor : ConsoleColor -> (unit -> 'a) -> 'a -val DoWithErrorColor : bool -> (unit -> 'a) -> 'a -val ReportTime : TcConfig -> string -> unit -val GetAbbrevFlagSet : TcConfigBuilder -> bool -> Set -val PostProcessCompilerArgs : string Set -> string [] -> string list diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs new file mode 100644 index 00000000000..f93653b1d8c --- /dev/null +++ b/src/fsharp/CompilerConfig.fs @@ -0,0 +1,1234 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The configuration of the compiler (TcConfig and TcConfigBuilder) +module internal FSharp.Compiler.CompilerConfig + +open System +open System.Collections.Concurrent +open System.IO +open Internal.Utilities +open Internal.Utilities.FSharpEnvironment +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.AbstractIL.ILPdbWriter +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.BuildGraph + +#if !NO_EXTENSIONTYPING +open FSharp.Core.CompilerServices +#endif + +let (++) x s = x @ [s] + +//---------------------------------------------------------------------------- +// Some Globals +//-------------------------------------------------------------------------- + +let FSharpSigFileSuffixes = [".mli";".fsi"] + +let mlCompatSuffixes = [".mli";".ml"] + +let FSharpImplFileSuffixes = [".ml";".fs";".fsscript";".fsx"] + +let FSharpScriptFileSuffixes = [".fsscript";".fsx"] + +let doNotRequireNamespaceOrModuleSuffixes = [".mli";".ml"] @ FSharpScriptFileSuffixes + +let FSharpLightSyntaxFileSuffixes: string list = [ ".fs";".fsscript";".fsx";".fsi" ] + +//-------------------------------------------------------------------------- +// General file name resolver +//-------------------------------------------------------------------------- + +exception FileNameNotResolved of (*filename*) string * (*description of searched locations*) string * range +exception LoadedSourceNotFoundIgnoring of (*filename*) string * range + +/// Will return None if the filename is not found. +let TryResolveFileUsingPaths(paths, m, name) = + let () = + try FileSystem.IsPathRootedShim name |> ignore + with :? ArgumentException as e -> error(Error(FSComp.SR.buildProblemWithFilename(name, e.Message), m)) + if FileSystem.IsPathRootedShim name && FileSystem.FileExistsShim name + then Some name + else + let res = paths |> List.tryPick (fun path -> + let n = Path.Combine (path, name) + if FileSystem.FileExistsShim n then Some n + else None) + res + +/// Will raise FileNameNotResolved if the filename was not found +let ResolveFileUsingPaths(paths, m, name) = + match TryResolveFileUsingPaths(paths, m, name) with + | Some res -> res + | None -> + let searchMessage = String.concat "\n " paths + raise (FileNameNotResolved(name, searchMessage, m)) + +let GetWarningNumber(m, warningNumber: string) = + try + // Okay so ... + // #pragma strips FS of the #pragma "FS0004" and validates the warning number + // therefore if we have warning id that starts with a numeric digit we convert it to Some (int32) + // anything else is ignored None + if Char.IsDigit(warningNumber.[0]) then Some (int32 warningNumber) + elif warningNumber.StartsWithOrdinal("FS") = true then raise (ArgumentException()) + else None + with _ -> + warning(Error(FSComp.SR.buildInvalidWarningNumber warningNumber, m)) + None + +let ComputeMakePathAbsolute implicitIncludeDir (path: string) = + try + // remove any quotation marks from the path first + let path = path.Replace("\"", "") + if not (FileSystem.IsPathRootedShim path) + then Path.Combine (implicitIncludeDir, path) + else path + with + :? ArgumentException -> path + +//---------------------------------------------------------------------------- +// Configuration +//---------------------------------------------------------------------------- + +[] +type CompilerTarget = + | WinExe + | ConsoleExe + | Dll + | Module + member x.IsExe = (match x with ConsoleExe | WinExe -> true | _ -> false) + +[] +type ResolveAssemblyReferenceMode = Speculative | ReportErrors + +[] +type CopyFSharpCoreFlag = Yes | No + +/// Represents the file or string used for the --version flag +type VersionFlag = + | VersionString of string + | VersionFile of string + | VersionNone + member x.GetVersionInfo implicitIncludeDir = + let vstr = x.GetVersionString implicitIncludeDir + try + parseILVersion vstr + with _ -> errorR(Error(FSComp.SR.buildInvalidVersionString vstr, rangeStartup)); parseILVersion "0.0.0.0" + + member x.GetVersionString implicitIncludeDir = + match x with + | VersionString s -> s + | VersionFile s -> + let s = if FileSystem.IsPathRootedShim s then s else Path.Combine(implicitIncludeDir, s) + if not(FileSystem.FileExistsShim s) then + errorR(Error(FSComp.SR.buildInvalidVersionFile s, rangeStartup)); "0.0.0.0" + else + use fs = FileSystem.OpenFileForReadShim(s) + use is = new StreamReader(fs) + is.ReadLine() + | VersionNone -> "0.0.0.0" + + +/// Represents a reference to an assembly. May be backed by a real assembly on disk, or a cross-project +/// reference backed by information generated by the the compiler service. +type IRawFSharpAssemblyData = + /// The raw list AutoOpenAttribute attributes in the assembly + abstract GetAutoOpenAttributes: unit -> string list + + /// The raw list InternalsVisibleToAttribute attributes in the assembly + abstract GetInternalsVisibleToAttributes: unit -> string list + + /// The raw IL module definition in the assembly, if any. This is not present for cross-project references + /// in the language service + abstract TryGetILModuleDef: unit -> ILModuleDef option + + /// The raw F# signature data in the assembly, if any + abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + + /// The raw F# optimization data in the assembly, if any + abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + + /// The table of type forwarders in the assembly + abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders + + /// The identity of the module + abstract ILScopeRef: ILScopeRef + + abstract ILAssemblyRefs: ILAssemblyRef list + + abstract ShortAssemblyName: string + + abstract HasAnyFSharpSignatureDataAttribute: bool + + abstract HasMatchingFSharpSignatureDataAttribute: bool + +/// Cache of time stamps as we traverse a project description +type TimeStampCache(defaultTimeStamp: DateTime) = + let files = ConcurrentDictionary() + let projects = ConcurrentDictionary(HashIdentity.Reference) + member cache.GetFileTimeStamp fileName = + let ok, v = files.TryGetValue fileName + if ok then v else + let v = + try + FileSystem.GetLastWriteTimeShim fileName + with + | :? FileNotFoundException -> + defaultTimeStamp + files.[fileName] <- v + v + + member cache.GetProjectReferenceTimeStamp (pr: IProjectReference) = + let ok, v = projects.TryGetValue pr + if ok then v else + let v = defaultArg (pr.TryGetLogicalTimeStamp cache) defaultTimeStamp + projects.[pr] <- v + v + +and [] + ProjectAssemblyDataResult = + | Available of IRawFSharpAssemblyData + | Unavailable of useOnDiskInstead: bool + +and IProjectReference = + /// The name of the assembly file generated by the project + abstract FileName: string + + /// Evaluate raw contents of the assembly file generated by the project + abstract EvaluateRawContents: unit -> NodeCode + + /// Get the logical timestamp that would be the timestamp of the assembly file generated by the project + /// + /// For project references this is maximum of the timestamps of all dependent files. + /// The project is not actually built, nor are any assemblies read, but the timestamps for each dependent file + /// are read via the FileSystem. If the files don't exist, then a default timestamp is used. + /// + /// The operation returns None only if it is not possible to create an IncrementalBuilder for the project at all, e.g. if there + /// are fatal errors in the options for the project. + abstract TryGetLogicalTimeStamp: TimeStampCache -> DateTime option + +type AssemblyReference = + | AssemblyReference of range * string * IProjectReference option + + member x.Range = (let (AssemblyReference(m, _, _)) = x in m) + + member x.Text = (let (AssemblyReference(_, text, _)) = x in text) + + member x.ProjectReference = (let (AssemblyReference(_, _, contents)) = x in contents) + + member x.SimpleAssemblyNameIs name = + (String.Compare(FileSystemUtils.fileNameWithoutExtensionWithValidate false x.Text, name, StringComparison.OrdinalIgnoreCase) = 0) || + not (x.Text.Contains "/") && + not (x.Text.Contains "\\") && + not (x.Text.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase)) && + not (x.Text.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) && + (try let aname = System.Reflection.AssemblyName x.Text in aname.Name = name + with _ -> false) + + override x.ToString() = sprintf "AssemblyReference(%s)" x.Text + +type UnresolvedAssemblyReference = UnresolvedAssemblyReference of string * AssemblyReference list +#if !NO_EXTENSIONTYPING +type ResolvedExtensionReference = ResolvedExtensionReference of string * AssemblyReference list * Tainted list +#endif + +type ImportedAssembly = + { ILScopeRef: ILScopeRef + FSharpViewOfMetadata: CcuThunk + AssemblyAutoOpenAttributes: string list + AssemblyInternalsVisibleToAttributes: string list +#if !NO_EXTENSIONTYPING + IsProviderGenerated: bool + mutable TypeProviders: Tainted list +#endif + FSharpOptimizationData: Microsoft.FSharp.Control.Lazy> } + +type AvailableImportedAssembly = + | ResolvedImportedAssembly of ImportedAssembly + | UnresolvedImportedAssembly of string + +type CcuLoadFailureAction = + | RaiseError + | ReturnNone + +type Directive = + | Resolution + | Include + +type LStatus = + | Unprocessed + | Processed + +type TokenizeOption = + | AndCompile + | Only + | Unfiltered + +type PackageManagerLine = + { Directive: Directive + LineStatus: LStatus + Line: string + Range: range } + + static member AddLineWithKey (packageKey: string) (directive:Directive) (line: string) (m: range) (packageManagerLines: Map): Map = + let path = PackageManagerLine.StripDependencyManagerKey packageKey line + let map = + let mutable found = false + let result = + packageManagerLines + |> Map.map(fun key lines -> + if key = packageKey then + found <- true + lines |> List.append [{Directive=directive; LineStatus=LStatus.Unprocessed; Line=path; Range=m}] + else + lines) + if found then + result + else + result.Add(packageKey, [{Directive=directive; LineStatus=LStatus.Unprocessed; Line=path; Range=m}]) + map + + static member RemoveUnprocessedLines (packageKey: string) (packageManagerLines: Map): Map = + let map = + packageManagerLines + |> Map.map(fun key lines -> + if key = packageKey then + lines |> List.filter(fun line -> line.LineStatus=LStatus.Processed) + else + lines) + map + + static member SetLinesAsProcessed (packageKey:string) (packageManagerLines: Map): Map = + let map = + packageManagerLines + |> Map.map(fun key lines -> + if key = packageKey then + lines |> List.map(fun line -> {line with LineStatus = LStatus.Processed;}) + else + lines) + map + + static member StripDependencyManagerKey (packageKey: string) (line: string): string = + line.Substring(packageKey.Length + 1).Trim() + +[] +type TcConfigBuilder = + { + mutable primaryAssembly: PrimaryAssembly + mutable noFeedback: bool + mutable stackReserveSize: int32 option + mutable implicitIncludeDir: string (* normally "." *) + mutable openDebugInformationForLaterStaticLinking: bool (* only for --standalone *) + defaultFSharpBinariesDir: string + mutable compilingFslib: bool + mutable useIncrementalBuilder: bool + mutable includes: string list + mutable implicitOpens: string list + mutable useFsiAuxLib: bool + mutable framework: bool + mutable resolutionEnvironment: LegacyResolutionEnvironment + mutable implicitlyResolveAssemblies: bool + mutable light: bool option + mutable conditionalCompilationDefines: string list + mutable loadedSources: (range * string * string) list + mutable compilerToolPaths: string list + mutable referencedDLLs: AssemblyReference list + mutable packageManagerLines: Map + mutable projectReferences: IProjectReference list + mutable knownUnresolvedReferences: UnresolvedAssemblyReference list + reduceMemoryUsage: ReduceMemoryFlag + mutable subsystemVersion: int * int + mutable useHighEntropyVA: bool + mutable inputCodePage: int option + mutable embedResources: string list + mutable errorSeverityOptions: FSharpDiagnosticOptions + mutable mlCompatibility: bool + mutable checkOverflow: bool + mutable showReferenceResolutions: bool + mutable outputDir : string option + mutable outputFile: string option + mutable platform: ILPlatform option + mutable prefer32Bit: bool + mutable useSimpleResolution: bool + mutable target: CompilerTarget + mutable debuginfo: bool + mutable testFlagEmitFeeFeeAs100001: bool + mutable dumpDebugInfo: bool + mutable debugSymbolFile: string option + (* Backend configuration *) + mutable typeCheckOnly: bool + mutable parseOnly: bool + mutable importAllReferencesOnly: bool + mutable simulateException: string option + mutable printAst: bool + mutable tokenize: TokenizeOption + mutable testInteractionParser: bool + mutable reportNumDecls: bool + mutable printSignature: bool + mutable printSignatureFile: string + mutable printAllSignatureFiles: bool + mutable xmlDocOutputFile: string option + mutable stats: bool + mutable generateFilterBlocks: bool (* don't generate filter blocks due to bugs on Mono *) + + mutable signer: string option + mutable container: string option + + mutable delaysign: bool + mutable publicsign: bool + mutable version: VersionFlag + mutable metadataVersion: string option + mutable standalone: bool + mutable extraStaticLinkRoots: string list + mutable noSignatureData: bool + mutable onlyEssentialOptimizationData: bool + mutable useOptimizationDataFile: bool + mutable jitTracking: bool + mutable portablePDB: bool + mutable embeddedPDB: bool + mutable embedAllSource: bool + mutable embedSourceList: string list + mutable sourceLink: string + + mutable ignoreSymbolStoreSequencePoints: bool + mutable internConstantStrings: bool + mutable extraOptimizationIterations: int + + mutable win32icon: string + mutable win32res: string + mutable win32manifest: string + mutable includewin32manifest: bool + mutable linkResources: string list + mutable legacyReferenceResolver: LegacyReferenceResolver + + mutable showFullPaths: bool + mutable errorStyle: ErrorStyle + mutable utf8output: bool + mutable flatErrors: bool + + mutable maxErrors: int + mutable abortOnError: bool (* intended for fsi scripts that should exit on first error *) + mutable baseAddress: int32 option + mutable checksumAlgorithm: HashAlgorithm +#if DEBUG + mutable showOptimizationData: bool +#endif + mutable showTerms: bool (* show terms between passes? *) + mutable writeTermsToFiles: bool (* show terms to files? *) + mutable doDetuple: bool (* run detuple pass? *) + mutable doTLR: bool (* run TLR pass? *) + mutable doFinalSimplify: bool (* do final simplification pass *) + mutable optsOn: bool (* optimizations are turned on *) + mutable optSettings: Optimizer.OptimizationSettings + mutable emitTailcalls: bool + mutable deterministic: bool + mutable concurrentBuild: bool + mutable preferredUiLang: string option + mutable lcid: int option + mutable productNameForBannerText: string + /// show the MS (c) notice, e.g. with help or fsi? + mutable showBanner: bool + + /// show times between passes? + mutable showTimes: bool + mutable showLoadedAssemblies: bool + mutable continueAfterParseFailure: bool +#if !NO_EXTENSIONTYPING + /// show messages about extension type resolution? + mutable showExtensionTypeMessages: bool +#endif + + /// pause between passes? + mutable pause: bool + /// whenever possible, emit callvirt instead of call + mutable alwaysCallVirt: bool + + /// if true, strip away data that would not be of use to end users, but is useful to us for debugging + // REVIEW: "stripDebugData"? + mutable noDebugData: bool + + /// if true, indicates all type checking and code generation is in the context of fsi.exe + isInteractive: bool + isInvalidationSupported: bool + + /// used to log sqm data + + /// if true - every expression in quotations will be augmented with full debug info (filename, location in file) + mutable emitDebugInfoInQuotations: bool + + mutable exename: string option + + // If true - the compiler will copy FSharp.Core.dll along the produced binaries + mutable copyFSharpCore: CopyFSharpCoreFlag + + /// When false FSI will lock referenced assemblies requiring process restart, false = disable Shadow Copy false (*default*) + mutable shadowCopyReferences: bool + mutable useSdkRefs: bool + mutable fxResolver: FxResolver option + + /// specify the error range for FxResolver + rangeForErrors: range + + /// Override the SDK directory used by FxResolver, used for FCS only + sdkDirOverride: string option + + /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, + /// and from which we can read the metadata. Only used when metadataOnly=true. + mutable tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot + + mutable internalTestSpanStackReferring: bool + + mutable noConditionalErasure: bool + + mutable pathMap: PathMap + + mutable langVersion: LanguageVersion + + mutable xmlDocInfoLoader: IXmlDocumentationInfoLoader option + } + + + // Directories to start probing in + // Algorithm: + // Search for native libraries using: + // 1. Include directories + // 2. compilerToolPath directories + // 3. reference dll's + // 4. The implicit include directory + // + // NOTE: it is important this is a delayed IEnumerable sequence. It is recomputed + // each time a resolution happens and additional paths may be added as a result. + member tcConfigB.GetNativeProbingRoots () = + seq { + yield! tcConfigB.includes + yield! tcConfigB.compilerToolPaths + yield! (tcConfigB.referencedDLLs |> Seq.map(fun ref -> Path.GetDirectoryName(ref.Text))) + yield tcConfigB.implicitIncludeDir + } + |> Seq.distinct + + static member CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir, + reduceMemoryUsage, + implicitIncludeDir, + isInteractive, + isInvalidationSupported, + defaultCopyFSharpCore, + tryGetMetadataSnapshot, + sdkDirOverride, + rangeForErrors) = + + if (String.IsNullOrEmpty defaultFSharpBinariesDir) then + failwith "Expected a valid defaultFSharpBinariesDir" + + // These are all default values, many can be overridden using the command line switch + { + primaryAssembly = PrimaryAssembly.Mscorlib + light = None + noFeedback = false + stackReserveSize = None + conditionalCompilationDefines = [] + openDebugInformationForLaterStaticLinking = false + compilingFslib = false + useIncrementalBuilder = false + implicitOpens = [] + includes = [] + resolutionEnvironment = LegacyResolutionEnvironment.EditingOrCompilation false + framework = true + implicitlyResolveAssemblies = true + compilerToolPaths = [] + referencedDLLs = [] + packageManagerLines = Map.empty + projectReferences = [] + knownUnresolvedReferences = [] + loadedSources = [] + errorSeverityOptions = FSharpDiagnosticOptions.Default + embedResources = [] + inputCodePage = None + subsystemVersion = 4, 0 // per spec for 357994 + useHighEntropyVA = false + mlCompatibility = false + checkOverflow = false + showReferenceResolutions = false + outputDir = None + outputFile = None + platform = None + prefer32Bit = false + useSimpleResolution = runningOnMono + target = CompilerTarget.ConsoleExe + debuginfo = false + testFlagEmitFeeFeeAs100001 = false + dumpDebugInfo = false + debugSymbolFile = None + + (* Backend configuration *) + typeCheckOnly = false + parseOnly = false + importAllReferencesOnly = false + simulateException = None + printAst = false + tokenize = TokenizeOption.AndCompile + testInteractionParser = false + reportNumDecls = false + printSignature = false + printSignatureFile = "" + printAllSignatureFiles = false + xmlDocOutputFile = None + stats = false + generateFilterBlocks = false (* don't generate filter blocks *) + + signer = None + container = None + maxErrors = 100 + abortOnError = false + baseAddress = None + checksumAlgorithm = HashAlgorithm.Sha256 + + delaysign = false + publicsign = false + version = VersionNone + metadataVersion = None + standalone = false + extraStaticLinkRoots = [] + noSignatureData = false + onlyEssentialOptimizationData = false + useOptimizationDataFile = false + jitTracking = true + portablePDB = true + embeddedPDB = false + embedAllSource = false + embedSourceList = [] + sourceLink = "" + ignoreSymbolStoreSequencePoints = false + internConstantStrings = true + extraOptimizationIterations = 0 + + win32icon = "" + win32res = "" + win32manifest = "" + includewin32manifest = true + linkResources = [] + showFullPaths = false + errorStyle = ErrorStyle.DefaultErrors + + utf8output = false + flatErrors = false + + #if DEBUG + showOptimizationData = false + #endif + showTerms = false + writeTermsToFiles = false + + doDetuple = false + doTLR = false + doFinalSimplify = false + optsOn = false + optSettings = Optimizer.OptimizationSettings.Defaults + emitTailcalls = true + deterministic = false + concurrentBuild = true + preferredUiLang = None + lcid = None + productNameForBannerText = FSharpProductName + showBanner = true + showTimes = false + showLoadedAssemblies = false + continueAfterParseFailure = false +#if !NO_EXTENSIONTYPING + showExtensionTypeMessages = false +#endif + pause = false + alwaysCallVirt = true + noDebugData = false + emitDebugInfoInQuotations = false + exename = None + shadowCopyReferences = false + useSdkRefs = true + fxResolver = None + internalTestSpanStackReferring = false + noConditionalErasure = false + pathMap = PathMap.empty + langVersion = LanguageVersion.Default + implicitIncludeDir = implicitIncludeDir + defaultFSharpBinariesDir = defaultFSharpBinariesDir + reduceMemoryUsage = reduceMemoryUsage + legacyReferenceResolver = legacyReferenceResolver + isInteractive = isInteractive + isInvalidationSupported = isInvalidationSupported + copyFSharpCore = defaultCopyFSharpCore + tryGetMetadataSnapshot = tryGetMetadataSnapshot + useFsiAuxLib = isInteractive + rangeForErrors = rangeForErrors + sdkDirOverride = sdkDirOverride + xmlDocInfoLoader = None + } + + member tcConfigB.FxResolver = + // We compute the FxResolver on-demand. It depends on some configuration parameters + // which may be later adjusted. + match tcConfigB.fxResolver with + | None -> + let useDotNetFramework = (tcConfigB.primaryAssembly = PrimaryAssembly.Mscorlib) + let fxResolver = FxResolver(useDotNetFramework, tcConfigB.implicitIncludeDir, rangeForErrors=tcConfigB.rangeForErrors, useSdkRefs=tcConfigB.useSdkRefs, isInteractive=tcConfigB.isInteractive, sdkDirOverride=tcConfigB.sdkDirOverride) + tcConfigB.fxResolver <- Some fxResolver + fxResolver + | Some fxResolver -> fxResolver + + member tcConfigB.SetPrimaryAssembly primaryAssembly = + tcConfigB.primaryAssembly <- primaryAssembly + tcConfigB.fxResolver <- None // this needs to be recreated when the primary assembly changes + + member tcConfigB.SetUseSdkRefs useSdkRefs = + tcConfigB.useSdkRefs <- useSdkRefs + tcConfigB.fxResolver <- None // this needs to be recreated when the primary assembly changes + + member tcConfigB.ResolveSourceFile(m, nm, pathLoadedFrom) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + ResolveFileUsingPaths(tcConfigB.includes @ [pathLoadedFrom], m, nm) + + /// Decide names of output file, pdb and assembly + member tcConfigB.DecideNames sourceFiles = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + if sourceFiles = [] then errorR(Error(FSComp.SR.buildNoInputsSpecified(), rangeCmdArgs)) + let ext() = match tcConfigB.target with CompilerTarget.Dll -> ".dll" | CompilerTarget.Module -> ".netmodule" | CompilerTarget.ConsoleExe | CompilerTarget.WinExe -> ".exe" + let implFiles = sourceFiles |> List.filter (fun lower -> List.exists (FileSystemUtils.checkSuffix (String.lowercase lower)) FSharpImplFileSuffixes) + let outfile = + match tcConfigB.outputFile, List.rev implFiles with + | None, [] -> "out" + ext() + | None, h :: _ -> + let basic = FileSystemUtils.fileNameOfPath h + let modname = try FileSystemUtils.chopExtension basic with _ -> basic + modname+(ext()) + | Some f, _ -> f + let assemblyName = + let baseName = FileSystemUtils.fileNameOfPath outfile + (FileSystemUtils.fileNameWithoutExtension baseName) + + let pdbfile = + if tcConfigB.debuginfo then + Some (match tcConfigB.debugSymbolFile with + | None -> getDebugFileName outfile tcConfigB.portablePDB +#if ENABLE_MONO_SUPPORT + | Some _ when runningOnMono -> + // On Mono, the name of the debug file has to be ".mdb" so specifying it explicitly is an error + warning(Error(FSComp.SR.ilwriteMDBFileNameCannotBeChangedWarning(), rangeCmdArgs)) + getDebugFileName outfile tcConfigB.portablePDB +#endif + | Some f -> f) + elif (tcConfigB.debugSymbolFile <> None) && (not tcConfigB.debuginfo) then + error(Error(FSComp.SR.buildPdbRequiresDebug(), rangeStartup)) + else + None + tcConfigB.outputFile <- Some outfile + outfile, pdbfile, assemblyName + + member tcConfigB.TurnWarningOff(m, s: string) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + match GetWarningNumber(m, s) with + | None -> () + | Some n -> + // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus + if n = 62 then tcConfigB.mlCompatibility <- true + tcConfigB.errorSeverityOptions <- + { tcConfigB.errorSeverityOptions with WarnOff = ListSet.insert (=) n tcConfigB.errorSeverityOptions.WarnOff } + + member tcConfigB.TurnWarningOn(m, s: string) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + match GetWarningNumber(m, s) with + | None -> () + | Some n -> + // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus + if n = 62 then tcConfigB.mlCompatibility <- false + tcConfigB.errorSeverityOptions <- + { tcConfigB.errorSeverityOptions with WarnOn = ListSet.insert (=) n tcConfigB.errorSeverityOptions.WarnOn } + + member tcConfigB.AddIncludePath (m, path, pathIncludedFrom) = + let absolutePath = ComputeMakePathAbsolute pathIncludedFrom path + let ok = + let existsOpt = + try Some(FileSystem.DirectoryExistsShim absolutePath) + with e -> warning(Error(FSComp.SR.buildInvalidSearchDirectory path, m)); None + match existsOpt with + | Some exists -> + if not exists then warning(Error(FSComp.SR.buildSearchDirectoryNotFound absolutePath, m)) + exists + | None -> false + if ok && not (List.contains absolutePath tcConfigB.includes) then + tcConfigB.includes <- tcConfigB.includes ++ absolutePath + + member tcConfigB.AddLoadedSource(m, originalPath, pathLoadedFrom) = + if FileSystem.IsInvalidPathShim originalPath then + warning(Error(FSComp.SR.buildInvalidFilename originalPath, m)) + else + let path = + match TryResolveFileUsingPaths(tcConfigB.includes @ [pathLoadedFrom], m, originalPath) with + | Some path -> path + | None -> + // File doesn't exist in the paths. Assume it will be in the load-ed from directory. + ComputeMakePathAbsolute pathLoadedFrom originalPath + if not (List.contains path (List.map (fun (_, _, path) -> path) tcConfigB.loadedSources)) then + tcConfigB.loadedSources <- tcConfigB.loadedSources ++ (m, originalPath, path) + + member tcConfigB.AddEmbeddedSourceFile file = + tcConfigB.embedSourceList <- tcConfigB.embedSourceList ++ file + + member tcConfigB.AddEmbeddedResource filename = + tcConfigB.embedResources <- tcConfigB.embedResources ++ filename + + member tcConfigB.AddCompilerToolsByPath path = + if not (tcConfigB.compilerToolPaths |> List.exists (fun text -> path = text)) then // NOTE: We keep same paths if range is different. + let compilerToolPath = tcConfigB.compilerToolPaths |> List.tryPick (fun text -> if text = path then Some text else None) + if compilerToolPath.IsNone then + tcConfigB.compilerToolPaths <- tcConfigB.compilerToolPaths ++ path + + member tcConfigB.AddReferencedAssemblyByPath (m, path) = + if FileSystem.IsInvalidPathShim path then + warning(Error(FSComp.SR.buildInvalidAssemblyName(path), m)) + elif not (tcConfigB.referencedDLLs |> List.exists (fun ar2 -> equals m ar2.Range && path=ar2.Text)) then // NOTE: We keep same paths if range is different. + let projectReference = tcConfigB.projectReferences |> List.tryPick (fun pr -> if pr.FileName = path then Some pr else None) + tcConfigB.referencedDLLs <- tcConfigB.referencedDLLs ++ AssemblyReference(m, path, projectReference) + + member tcConfigB.AddDependencyManagerText (packageManager: IDependencyManagerProvider, lt, m, path: string) = + tcConfigB.packageManagerLines <- PackageManagerLine.AddLineWithKey packageManager.Key lt path m tcConfigB.packageManagerLines + + member tcConfigB.AddReferenceDirective (dependencyProvider: DependencyProvider, m, path: string, directive) = + let output = tcConfigB.outputDir |> Option.defaultValue "" + + let reportError = + ResolvingErrorReport (fun errorType err msg -> + let error = err, msg + match errorType with + | ErrorReportType.Warning -> warning(Error(error, m)) + | ErrorReportType.Error -> errorR(Error(error, m))) + + let dm = dependencyProvider.TryFindDependencyManagerInPath(tcConfigB.compilerToolPaths, output , reportError, path) + + match dm with + | _, dependencyManager when not(isNull dependencyManager) -> + if tcConfigB.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then + tcConfigB.AddDependencyManagerText (dependencyManager, directive, m, path) + else + errorR(Error(FSComp.SR.packageManagementRequiresVFive(), m)) + + | _, _ when directive = Directive.Include -> + errorR(Error(FSComp.SR.poundiNotSupportedByRegisteredDependencyManagers(), m)) + + // #r "Assembly" + | path, _ -> + tcConfigB.AddReferencedAssemblyByPath (m, path) + + member tcConfigB.RemoveReferencedAssemblyByPath (m, path) = + tcConfigB.referencedDLLs <- tcConfigB.referencedDLLs |> List.filter (fun ar -> not (equals ar.Range m) || ar.Text <> path) + + member tcConfigB.AddPathMapping (oldPrefix, newPrefix) = + tcConfigB.pathMap <- tcConfigB.pathMap |> PathMap.addMapping oldPrefix newPrefix + + static member SplitCommandLineResourceInfo (ri: string) = + let p = ri.IndexOf ',' + if p <> -1 then + let file = String.sub ri 0 p + let rest = String.sub ri (p+1) (String.length ri - p - 1) + let p = rest.IndexOf ',' + if p <> -1 then + let name = String.sub rest 0 p+".resources" + let pubpri = String.sub rest (p+1) (rest.Length - p - 1) + if pubpri = "public" then file, name, ILResourceAccess.Public + elif pubpri = "private" then file, name, ILResourceAccess.Private + else error(Error(FSComp.SR.buildInvalidPrivacy pubpri, rangeStartup)) + else + file, rest, ILResourceAccess.Public + else + ri, FileSystemUtils.fileNameOfPath ri, ILResourceAccess.Public + + +//---------------------------------------------------------------------------- +// TcConfig +//-------------------------------------------------------------------------- + +[] +/// This type is immutable and must be kept as such. Do not extract or mutate the underlying data except by cloning it. +type TcConfig private (data: TcConfigBuilder, validate: bool) = + + // Validate the inputs - this helps ensure errors in options are shown in visual studio rather than only when built + // However we only validate a minimal number of options at the moment + do if validate then try data.version.GetVersionInfo(data.implicitIncludeDir) |> ignore with e -> errorR e + + // clone the input builder to ensure nobody messes with it. + let data = { data with pause = data.pause } + + let computeKnownDllReference libraryName = + let defaultCoreLibraryReference = AssemblyReference(range0, libraryName+".dll", None) + let nameOfDll(r: AssemblyReference) = + let filename = ComputeMakePathAbsolute data.implicitIncludeDir r.Text + if FileSystem.FileExistsShim filename then + r, Some filename + else + // If the file doesn't exist, let reference resolution logic report the error later... + defaultCoreLibraryReference, if equals r.Range rangeStartup then Some(filename) else None + match data.referencedDLLs |> List.filter (fun assemblyReference -> assemblyReference.SimpleAssemblyNameIs libraryName) with + | [] -> defaultCoreLibraryReference, None + | [r] + | r :: _ -> nameOfDll r + + // Look for an explicit reference to mscorlib/netstandard.dll or System.Runtime.dll and use that to compute clrRoot and targetFrameworkVersion + let primaryAssemblyReference, primaryAssemblyExplicitFilenameOpt = computeKnownDllReference(data.primaryAssembly.Name) + let fslibReference = + // Look for explicit FSharp.Core reference otherwise use version that was referenced by compiler + let dllReference, fileNameOpt = computeKnownDllReference getFSharpCoreLibraryName + match fileNameOpt with + | Some _ -> dllReference + | None -> AssemblyReference(range0, getDefaultFSharpCoreLocation(), None) + + // clrRoot: the location of the primary assembly (mscorlib.dll or netstandard.dll or System.Runtime.dll) + // + // targetFrameworkVersionValue: Normally just HighestInstalledNetFrameworkVersion() + // + // Note, when mscorlib.dll has been given explicitly the actual value of + // targetFrameworkVersion shouldn't matter since resolution has already happened. + // In those cases where it does matter (e.g. --noframework is not being used or we are processing further + // resolutions for a script) then it is correct to just use HighestInstalledNetFrameworkVersion(). + let clrRootValue, targetFrameworkVersionValue = + match primaryAssemblyExplicitFilenameOpt with + | Some primaryAssemblyFilename -> + let filename = ComputeMakePathAbsolute data.implicitIncludeDir primaryAssemblyFilename + try + let clrRoot = Some(Path.GetDirectoryName(FileSystem.GetFullPathShim filename)) + clrRoot, data.legacyReferenceResolver.Impl.HighestInstalledNetFrameworkVersion() + with e -> + // We no longer expect the above to fail but leaving this just in case + error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), rangeStartup)) + | None -> +#if !ENABLE_MONO_SUPPORT + // TODO: we have to get msbuild out of this + if data.useSimpleResolution then + None, "" + else +#endif + None, data.legacyReferenceResolver.Impl.HighestInstalledNetFrameworkVersion() + + member x.FxResolver = data.FxResolver + member x.primaryAssembly = data.primaryAssembly + member x.noFeedback = data.noFeedback + member x.stackReserveSize = data.stackReserveSize + member x.implicitIncludeDir = data.implicitIncludeDir + member x.openDebugInformationForLaterStaticLinking = data.openDebugInformationForLaterStaticLinking + member x.fsharpBinariesDir = data.defaultFSharpBinariesDir + member x.compilingFslib = data.compilingFslib + member x.useIncrementalBuilder = data.useIncrementalBuilder + member x.includes = data.includes + member x.implicitOpens = data.implicitOpens + member x.useFsiAuxLib = data.useFsiAuxLib + member x.framework = data.framework + member x.implicitlyResolveAssemblies = data.implicitlyResolveAssemblies + member x.resolutionEnvironment = data.resolutionEnvironment + member x.light = data.light + member x.conditionalCompilationDefines = data.conditionalCompilationDefines + member x.loadedSources = data.loadedSources + member x.compilerToolPaths = data.compilerToolPaths + member x.referencedDLLs = data.referencedDLLs + member x.knownUnresolvedReferences = data.knownUnresolvedReferences + member x.clrRoot = clrRootValue + member x.reduceMemoryUsage = data.reduceMemoryUsage + member x.subsystemVersion = data.subsystemVersion + member x.useHighEntropyVA = data.useHighEntropyVA + member x.inputCodePage = data.inputCodePage + member x.embedResources = data.embedResources + member x.errorSeverityOptions = data.errorSeverityOptions + member x.mlCompatibility = data.mlCompatibility + member x.checkOverflow = data.checkOverflow + member x.showReferenceResolutions = data.showReferenceResolutions + member x.outputDir = data.outputDir + member x.outputFile = data.outputFile + member x.platform = data.platform + member x.prefer32Bit = data.prefer32Bit + member x.useSimpleResolution = data.useSimpleResolution + member x.target = data.target + member x.debuginfo = data.debuginfo + member x.testFlagEmitFeeFeeAs100001 = data.testFlagEmitFeeFeeAs100001 + member x.dumpDebugInfo = data.dumpDebugInfo + member x.debugSymbolFile = data.debugSymbolFile + member x.typeCheckOnly = data.typeCheckOnly + member x.parseOnly = data.parseOnly + member x.importAllReferencesOnly = data.importAllReferencesOnly + member x.simulateException = data.simulateException + member x.printAst = data.printAst + member x.targetFrameworkVersion = targetFrameworkVersionValue + member x.tokenize = data.tokenize + member x.testInteractionParser = data.testInteractionParser + member x.reportNumDecls = data.reportNumDecls + member x.printSignature = data.printSignature + member x.printSignatureFile = data.printSignatureFile + member x.printAllSignatureFiles = data.printAllSignatureFiles + member x.xmlDocOutputFile = data.xmlDocOutputFile + member x.stats = data.stats + member x.generateFilterBlocks = data.generateFilterBlocks + member x.signer = data.signer + member x.container = data.container + member x.delaysign = data.delaysign + member x.publicsign = data.publicsign + member x.version = data.version + member x.metadataVersion = data.metadataVersion + member x.standalone = data.standalone + member x.extraStaticLinkRoots = data.extraStaticLinkRoots + member x.noSignatureData = data.noSignatureData + member x.onlyEssentialOptimizationData = data.onlyEssentialOptimizationData + member x.useOptimizationDataFile = data.useOptimizationDataFile + member x.jitTracking = data.jitTracking + member x.portablePDB = data.portablePDB + member x.embeddedPDB = data.embeddedPDB + member x.embedAllSource = data.embedAllSource + member x.embedSourceList = data.embedSourceList + member x.sourceLink = data.sourceLink + member x.packageManagerLines = data.packageManagerLines + member x.ignoreSymbolStoreSequencePoints = data.ignoreSymbolStoreSequencePoints + member x.internConstantStrings = data.internConstantStrings + member x.extraOptimizationIterations = data.extraOptimizationIterations + member x.win32icon = data.win32icon + member x.win32res = data.win32res + member x.win32manifest = data.win32manifest + member x.includewin32manifest = data.includewin32manifest + member x.linkResources = data.linkResources + member x.showFullPaths = data.showFullPaths + member x.errorStyle = data.errorStyle + member x.utf8output = data.utf8output + member x.flatErrors = data.flatErrors + member x.maxErrors = data.maxErrors + member x.baseAddress = data.baseAddress + member x.checksumAlgorithm = data.checksumAlgorithm + #if DEBUG + member x.showOptimizationData = data.showOptimizationData +#endif + member x.showTerms = data.showTerms + member x.writeTermsToFiles = data.writeTermsToFiles + member x.doDetuple = data.doDetuple + member x.doTLR = data.doTLR + member x.doFinalSimplify = data.doFinalSimplify + member x.optSettings = data.optSettings + member x.emitTailcalls = data.emitTailcalls + member x.deterministic = data.deterministic + member x.concurrentBuild = data.concurrentBuild + member x.pathMap = data.pathMap + member x.langVersion = data.langVersion + member x.preferredUiLang = data.preferredUiLang + member x.lcid = data.lcid + member x.optsOn = data.optsOn + member x.productNameForBannerText = data.productNameForBannerText + member x.showBanner = data.showBanner + member x.showTimes = data.showTimes + member x.showLoadedAssemblies = data.showLoadedAssemblies + member x.continueAfterParseFailure = data.continueAfterParseFailure +#if !NO_EXTENSIONTYPING + member x.showExtensionTypeMessages = data.showExtensionTypeMessages +#endif + member x.pause = data.pause + member x.alwaysCallVirt = data.alwaysCallVirt + member x.noDebugData = data.noDebugData + member x.isInteractive = data.isInteractive + member x.isInvalidationSupported = data.isInvalidationSupported + member x.emitDebugInfoInQuotations = data.emitDebugInfoInQuotations + member x.copyFSharpCore = data.copyFSharpCore + member x.shadowCopyReferences = data.shadowCopyReferences + member x.useSdkRefs = data.useSdkRefs + member x.sdkDirOverride = data.sdkDirOverride + member x.tryGetMetadataSnapshot = data.tryGetMetadataSnapshot + member x.internalTestSpanStackReferring = data.internalTestSpanStackReferring + member x.noConditionalErasure = data.noConditionalErasure + member x.xmlDocInfoLoader = data.xmlDocInfoLoader + + static member Create(builder, validate) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + TcConfig(builder, validate) + + member x.legacyReferenceResolver = data.legacyReferenceResolver + + member tcConfig.CloneToBuilder() = + { data with conditionalCompilationDefines=data.conditionalCompilationDefines } + + member tcConfig.ComputeCanContainEntryPoint(sourceFiles: string list) = + let n = sourceFiles.Length in + (sourceFiles |> List.mapi (fun i _ -> (i = n-1)), tcConfig.target.IsExe) + + // This call can fail if no CLR is found (this is the path to mscorlib) + member tcConfig.GetTargetFrameworkDirectories() = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + try + [ + // Check if we are given an explicit framework root - if so, use that + match tcConfig.clrRoot with + | Some x -> + let clrRoot = tcConfig.MakePathAbsolute x + yield clrRoot + let clrFacades = Path.Combine(clrRoot, "Facades") + if FileSystem.DirectoryExistsShim(clrFacades) then yield clrFacades + + | None -> +// "there is no really good notion of runtime directory on .NETCore" +#if NETSTANDARD + let runtimeRoot = Path.GetDirectoryName(typeof.Assembly.Location) +#else + let runtimeRoot = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() +#endif + let runtimeRootWithoutSlash = runtimeRoot.TrimEnd('/', '\\') + let runtimeRootFacades = Path.Combine(runtimeRootWithoutSlash, "Facades") + let runtimeRootWPF = Path.Combine(runtimeRootWithoutSlash, "WPF") + + match tcConfig.resolutionEnvironment with + | LegacyResolutionEnvironment.CompilationAndEvaluation -> + // Default compilation-and-execution-time references on .NET Framework and Mono, e.g. for F# Interactive + // + // In the current way of doing things, F# Interactive refers to implementation assemblies. + yield runtimeRoot + if FileSystem.DirectoryExistsShim runtimeRootFacades then + yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades + if FileSystem.DirectoryExistsShim runtimeRootWPF then + yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF + + match tcConfig.FxResolver.GetFrameworkRefsPackDirectory() with + | Some path when FileSystem.DirectoryExistsShim(path) -> + yield path + | _ -> () + + | LegacyResolutionEnvironment.EditingOrCompilation _ -> +#if ENABLE_MONO_SUPPORT + if runningOnMono then + // Default compilation-time references on Mono + // + // On Mono, the default references come from the implementation assemblies. + // This is because we have had trouble reliably using MSBuild APIs to compute DotNetFrameworkReferenceAssembliesRootDirectory on Mono. + yield runtimeRoot + if FileSystem.DirectoryExistsShim runtimeRootFacades then + yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades + if FileSystem.DirectoryExistsShim runtimeRootWPF then + yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF + // On Mono we also add a default reference to the 4.5-api and 4.5-api/Facades directories. + let runtimeRootApi = runtimeRootWithoutSlash + "-api" + let runtimeRootApiFacades = Path.Combine(runtimeRootApi, "Facades") + if FileSystem.DirectoryExistsShim runtimeRootApi then + yield runtimeRootApi + if FileSystem.DirectoryExistsShim runtimeRootApiFacades then + yield runtimeRootApiFacades + else +#endif + // Default compilation-time references on .NET Framework + // + // This is the normal case for "fsc.exe a.fs". We refer to the reference assemblies folder. + let frameworkRoot = tcConfig.legacyReferenceResolver.Impl.DotNetFrameworkReferenceAssembliesRootDirectory + let frameworkRootVersion = Path.Combine(frameworkRoot, tcConfig.targetFrameworkVersion) + yield frameworkRootVersion + let facades = Path.Combine(frameworkRootVersion, "Facades") + if FileSystem.DirectoryExistsShim facades then + yield facades + match tcConfig.FxResolver.GetFrameworkRefsPackDirectory() with + | Some path when FileSystem.DirectoryExistsShim(path) -> + yield path + | _ -> () + ] + with e -> + errorRecovery e range0; [] + + member tcConfig.ComputeLightSyntaxInitialStatus filename = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + let lower = String.lowercase filename + let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix lower) FSharpLightSyntaxFileSuffixes + if lightOnByDefault then (tcConfig.light <> Some false) else (tcConfig.light = Some true ) + + member tcConfig.GetAvailableLoadedSources() = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + let resolveLoadedSource (m, originalPath, path) = + try + if not(FileSystem.FileExistsShim(path)) then + let secondTrial = + tcConfig.includes + |> List.tryPick (fun root -> + let path = ComputeMakePathAbsolute root originalPath + if FileSystem.FileExistsShim(path) then Some path else None) + + match secondTrial with + | Some path -> Some(m,path) + | None -> + error(LoadedSourceNotFoundIgnoring(path,m)) + None + else Some(m,path) + with e -> errorRecovery e m; None + + tcConfig.loadedSources + |> List.choose resolveLoadedSource + |> List.distinct + + // This is not the complete set of search paths, it is just the set + // that is special to F# (as compared to MSBuild resolution) + member tcConfig.GetSearchPathsForLibraryFiles() = + [ yield! tcConfig.GetTargetFrameworkDirectories() + yield! List.map tcConfig.MakePathAbsolute tcConfig.includes + yield tcConfig.implicitIncludeDir + yield tcConfig.fsharpBinariesDir ] + + member tcConfig.MakePathAbsolute path = + let result = ComputeMakePathAbsolute tcConfig.implicitIncludeDir path + result + + member _.ResolveSourceFile(m, filename, pathLoadedFrom) = + data.ResolveSourceFile(m, filename, pathLoadedFrom) + + member _.PrimaryAssemblyDllReference() = primaryAssemblyReference + + member _.CoreLibraryDllReference() = fslibReference + + member _.GetNativeProbingRoots() = data.GetNativeProbingRoots() + + /// A closed set of assemblies where, for any subset S: + /// - the TcImports object built for S (and thus the F# Compiler CCUs for the assemblies in S) + /// is a resource that can be shared between any two IncrementalBuild objects that reference + /// precisely S + /// + /// Determined by looking at the set of assemblies referenced by f# . + /// + /// Returning true may mean that the file is locked and/or placed into the + /// 'framework' reference set that is potentially shared across multiple compilations. + member tcConfig.IsSystemAssembly (filename: string) = + try + FileSystem.FileExistsShim filename && + ((tcConfig.GetTargetFrameworkDirectories() |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) || + (tcConfig.FxResolver.GetSystemAssemblies().Contains (FileSystemUtils.fileNameWithoutExtension filename)) || + tcConfig.FxResolver.IsInReferenceAssemblyPackDirectory filename) + with _ -> + false + + member tcConfig.GenerateSignatureData = + not tcConfig.standalone && not tcConfig.noSignatureData + + member tcConfig.GenerateOptimizationData = + tcConfig.GenerateSignatureData + + member tcConfig.assumeDotNetFramework = + tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib + +/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, +/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. +type TcConfigProvider = + | TcConfigProvider of (CompilationThreadToken -> TcConfig) + member x.Get ctok = (let (TcConfigProvider f) = x in f ctok) + + /// Get a TcConfigProvider which will return only the exact TcConfig. + static member Constant tcConfig = TcConfigProvider(fun _ctok -> tcConfig) + + /// Get a TcConfigProvider which will continue to respect changes in the underlying + /// TcConfigBuilder rather than delivering snapshots. + static member BasedOnMutableBuilder tcConfigB = TcConfigProvider(fun _ctok -> TcConfig.Create(tcConfigB, validate=false)) + +let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName diff --git a/src/fsharp/CompilerConfig.fsi b/src/fsharp/CompilerConfig.fsi new file mode 100644 index 00000000000..4a80fea97d1 --- /dev/null +++ b/src/fsharp/CompilerConfig.fsi @@ -0,0 +1,571 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The configuration of the compiler (TcConfig and TcConfigBuilder) +module internal FSharp.Compiler.CompilerConfig + +open System +open FSharp.Compiler.IO +open Internal.Utilities +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.Xml +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.AbstractIL.ILPdbWriter +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text +open FSharp.Compiler.BuildGraph + +exception FileNameNotResolved of (*filename*) string * (*description of searched locations*) string * range +exception LoadedSourceNotFoundIgnoring of (*filename*) string * range + +/// Represents a reference to an F# assembly. May be backed by a real assembly on disk (read by Abstract IL), or a cross-project +/// reference in FSharp.Compiler.Service. +type IRawFSharpAssemblyData = + + /// The raw list AutoOpenAttribute attributes in the assembly + abstract GetAutoOpenAttributes: unit -> string list + + /// The raw list InternalsVisibleToAttribute attributes in the assembly + abstract GetInternalsVisibleToAttributes: unit -> string list + + /// The raw IL module definition in the assembly, if any. This is not present for cross-project references + /// in the language service + abstract TryGetILModuleDef: unit -> ILModuleDef option + + abstract HasAnyFSharpSignatureDataAttribute: bool + + abstract HasMatchingFSharpSignatureDataAttribute: bool + + /// The raw F# signature data in the assembly, if any + abstract GetRawFSharpSignatureData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + + /// The raw F# optimization data in the assembly, if any + abstract GetRawFSharpOptimizationData: range * ilShortAssemName: string * fileName: string -> (string * (unit -> ReadOnlyByteMemory)) list + + /// The table of type forwarders in the assembly + abstract GetRawTypeForwarders: unit -> ILExportedTypesAndForwarders + + /// The identity of the module + abstract ILScopeRef: ILScopeRef + + abstract ILAssemblyRefs: ILAssemblyRef list + + abstract ShortAssemblyName: string + +type TimeStampCache = + new: defaultTimeStamp: DateTime -> TimeStampCache + member GetFileTimeStamp: string -> DateTime + member GetProjectReferenceTimeStamp: IProjectReference -> DateTime + +and [] + ProjectAssemblyDataResult = + | Available of IRawFSharpAssemblyData + | Unavailable of useOnDiskInstead: bool + +and IProjectReference = + + /// The name of the assembly file generated by the project + abstract FileName: string + + /// Evaluate raw contents of the assembly file generated by the project. + /// 'None' may be returned if an in-memory view of the contents is, for some reason, + /// not available. In this case the on-disk view of the contents will be preferred. + abstract EvaluateRawContents: unit -> NodeCode + + /// Get the logical timestamp that would be the timestamp of the assembly file generated by the project. + /// + /// For project references this is maximum of the timestamps of all dependent files. + /// The project is not actually built, nor are any assemblies read, but the timestamps for each dependent file + /// are read via the FileSystem. If the files don't exist, then a default timestamp is used. + /// + /// The operation returns None only if it is not possible to create an IncrementalBuilder for the project at all, e.g. if there + /// are fatal errors in the options for the project. + abstract TryGetLogicalTimeStamp: TimeStampCache -> DateTime option + +type AssemblyReference = + | AssemblyReference of range * string * IProjectReference option + + member Range: range + + member Text: string + + member ProjectReference: IProjectReference option + + member SimpleAssemblyNameIs: string -> bool + +type UnresolvedAssemblyReference = UnresolvedAssemblyReference of string * AssemblyReference list + +[] +type CompilerTarget = + | WinExe + | ConsoleExe + | Dll + | Module + member IsExe: bool + +[] +type CopyFSharpCoreFlag = Yes | No + +/// Represents the file or string used for the --version flag +type VersionFlag = + | VersionString of string + | VersionFile of string + | VersionNone + member GetVersionInfo: implicitIncludeDir:string -> ILVersionInfo + member GetVersionString: implicitIncludeDir:string -> string + +type Directive = + | Resolution + | Include + +type LStatus = + | Unprocessed + | Processed + +type TokenizeOption = + | AndCompile + | Only + | Unfiltered + +type PackageManagerLine = + { Directive: Directive + LineStatus: LStatus + Line: string + Range: range } + + static member AddLineWithKey: string -> Directive -> string -> range -> Map -> Map + static member RemoveUnprocessedLines: string -> Map -> Map + static member SetLinesAsProcessed: string -> Map -> Map + static member StripDependencyManagerKey: string -> string -> string + +[] +type TcConfigBuilder = + { mutable primaryAssembly: PrimaryAssembly + mutable noFeedback: bool + mutable stackReserveSize: int32 option + mutable implicitIncludeDir: string + mutable openDebugInformationForLaterStaticLinking: bool + defaultFSharpBinariesDir: string + mutable compilingFslib: bool + mutable useIncrementalBuilder: bool + mutable includes: string list + mutable implicitOpens: string list + mutable useFsiAuxLib: bool + mutable framework: bool + mutable resolutionEnvironment: LegacyResolutionEnvironment + mutable implicitlyResolveAssemblies: bool + /// Set if the user has explicitly turned indentation-aware syntax on/off + mutable light: bool option + mutable conditionalCompilationDefines: string list + /// Sources added into the build with #load + mutable loadedSources: (range * string * string) list + mutable compilerToolPaths: string list + mutable referencedDLLs: AssemblyReference list + mutable packageManagerLines: Map + mutable projectReferences: IProjectReference list + mutable knownUnresolvedReferences: UnresolvedAssemblyReference list + reduceMemoryUsage: ReduceMemoryFlag + mutable subsystemVersion: int * int + mutable useHighEntropyVA: bool + mutable inputCodePage: int option + mutable embedResources: string list + mutable errorSeverityOptions: FSharpDiagnosticOptions + mutable mlCompatibility:bool + mutable checkOverflow:bool + mutable showReferenceResolutions:bool + mutable outputDir: string option + mutable outputFile: string option + mutable platform: ILPlatform option + mutable prefer32Bit: bool + mutable useSimpleResolution: bool + mutable target: CompilerTarget + mutable debuginfo: bool + mutable testFlagEmitFeeFeeAs100001: bool + mutable dumpDebugInfo: bool + mutable debugSymbolFile: string option + mutable typeCheckOnly: bool + mutable parseOnly: bool + mutable importAllReferencesOnly: bool + mutable simulateException: string option + mutable printAst: bool + mutable tokenize: TokenizeOption + mutable testInteractionParser: bool + mutable reportNumDecls: bool + mutable printSignature: bool + mutable printSignatureFile: string + mutable printAllSignatureFiles: bool + mutable xmlDocOutputFile: string option + mutable stats: bool + mutable generateFilterBlocks: bool + mutable signer: string option + mutable container: string option + mutable delaysign: bool + mutable publicsign: bool + mutable version: VersionFlag + mutable metadataVersion: string option + mutable standalone: bool + mutable extraStaticLinkRoots: string list + mutable noSignatureData: bool + mutable onlyEssentialOptimizationData: bool + mutable useOptimizationDataFile: bool + mutable jitTracking: bool + mutable portablePDB: bool + mutable embeddedPDB: bool + mutable embedAllSource: bool + mutable embedSourceList: string list + mutable sourceLink: string + mutable ignoreSymbolStoreSequencePoints: bool + mutable internConstantStrings: bool + mutable extraOptimizationIterations: int + mutable win32icon: string + mutable win32res: string + mutable win32manifest: string + mutable includewin32manifest: bool + mutable linkResources: string list + mutable legacyReferenceResolver: LegacyReferenceResolver + mutable showFullPaths: bool + mutable errorStyle: ErrorStyle + mutable utf8output: bool + mutable flatErrors: bool + mutable maxErrors: int + mutable abortOnError: bool + mutable baseAddress: int32 option + mutable checksumAlgorithm: HashAlgorithm + #if DEBUG + mutable showOptimizationData: bool +#endif + mutable showTerms : bool + mutable writeTermsToFiles: bool + mutable doDetuple : bool + mutable doTLR : bool + mutable doFinalSimplify: bool + mutable optsOn : bool + mutable optSettings : Optimizer.OptimizationSettings + mutable emitTailcalls: bool + mutable deterministic: bool + mutable concurrentBuild: bool + mutable preferredUiLang: string option + mutable lcid : int option + mutable productNameForBannerText: string + mutable showBanner : bool + mutable showTimes: bool + mutable showLoadedAssemblies: bool + mutable continueAfterParseFailure: bool +#if !NO_EXTENSIONTYPING + mutable showExtensionTypeMessages: bool +#endif + mutable pause: bool + mutable alwaysCallVirt: bool + mutable noDebugData: bool + + /// If true, indicates all type checking and code generation is in the context of fsi.exe + isInteractive: bool + isInvalidationSupported: bool + mutable emitDebugInfoInQuotations: bool + mutable exename: string option + mutable copyFSharpCore: CopyFSharpCoreFlag + mutable shadowCopyReferences: bool + mutable useSdkRefs: bool + mutable fxResolver: FxResolver option + rangeForErrors: range + sdkDirOverride: string option + + /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, + /// and from which we can read the metadata. Only used when metadataOnly=true. + mutable tryGetMetadataSnapshot : ILReaderTryGetMetadataSnapshot + + /// if true - 'let mutable x = Span.Empty', the value 'x' is a stack referring span. Used for internal testing purposes only until we get true stack spans. + mutable internalTestSpanStackReferring : bool + + /// Prevent erasure of conditional attributes and methods so tooling is able analyse them. + mutable noConditionalErasure: bool + + mutable pathMap : PathMap + + mutable langVersion : LanguageVersion + + mutable xmlDocInfoLoader : IXmlDocumentationInfoLoader option + } + + static member CreateNew: + legacyReferenceResolver: LegacyReferenceResolver * + defaultFSharpBinariesDir: string * + reduceMemoryUsage: ReduceMemoryFlag * + implicitIncludeDir: string * + isInteractive: bool * + isInvalidationSupported: bool * + defaultCopyFSharpCore: CopyFSharpCoreFlag * + tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * + sdkDirOverride: string option * + rangeForErrors: range + -> TcConfigBuilder + + member DecideNames: string list -> outfile: string * pdbfile: string option * assemblyName: string + + member TurnWarningOff: range * string -> unit + + member TurnWarningOn: range * string -> unit + + member AddIncludePath: range * string * string -> unit + + member AddCompilerToolsByPath: string -> unit + + member AddReferencedAssemblyByPath: range * string -> unit + + member RemoveReferencedAssemblyByPath: range * string -> unit + + member AddEmbeddedSourceFile: string -> unit + + member AddEmbeddedResource: string -> unit + + member AddPathMapping: oldPrefix: string * newPrefix: string -> unit + + static member SplitCommandLineResourceInfo: string -> string * string * ILResourceAccess + + // Directories to start probing in for native DLLs for FSI dynamic loading + member GetNativeProbingRoots: unit -> seq + + member AddReferenceDirective: dependencyProvider: DependencyProvider * m: range * path: string * directive: Directive -> unit + + member AddLoadedSource: m: range * originalPath: string * pathLoadedFrom: string -> unit + + member FxResolver: FxResolver + + member SetUseSdkRefs: useSdkRefs: bool -> unit + + member SetPrimaryAssembly: primaryAssembly: PrimaryAssembly -> unit + +/// Immutable TcConfig, modifications are made via a TcConfigBuilder +[] +type TcConfig = + member primaryAssembly: PrimaryAssembly + member noFeedback: bool + member stackReserveSize: int32 option + member implicitIncludeDir: string + member openDebugInformationForLaterStaticLinking: bool + member fsharpBinariesDir: string + member compilingFslib: bool + member useIncrementalBuilder: bool + member includes: string list + member implicitOpens: string list + member useFsiAuxLib: bool + member framework: bool + member implicitlyResolveAssemblies: bool + /// Set if the user has explicitly turned indentation-aware syntax on/off + member light: bool option + member conditionalCompilationDefines: string list + member subsystemVersion: int * int + member useHighEntropyVA: bool + member compilerToolPaths: string list + member referencedDLLs: AssemblyReference list + member reduceMemoryUsage: ReduceMemoryFlag + member inputCodePage: int option + member embedResources: string list + member errorSeverityOptions: FSharpDiagnosticOptions + member mlCompatibility:bool + member checkOverflow:bool + member showReferenceResolutions:bool + member outputDir: string option + member outputFile: string option + member platform: ILPlatform option + member prefer32Bit: bool + member useSimpleResolution: bool + member target: CompilerTarget + member debuginfo: bool + member testFlagEmitFeeFeeAs100001: bool + member dumpDebugInfo: bool + member debugSymbolFile: string option + member typeCheckOnly: bool + member parseOnly: bool + member importAllReferencesOnly: bool + member simulateException: string option + member printAst: bool + member tokenize: TokenizeOption + member testInteractionParser: bool + member reportNumDecls: bool + member printSignature: bool + member printSignatureFile: string + member printAllSignatureFiles: bool + member xmlDocOutputFile: string option + member stats: bool + member generateFilterBlocks: bool + member signer: string option + member container: string option + member delaysign: bool + member publicsign: bool + member version: VersionFlag + member metadataVersion: string option + member standalone: bool + member extraStaticLinkRoots: string list + member noSignatureData: bool + member onlyEssentialOptimizationData: bool + member useOptimizationDataFile: bool + member jitTracking: bool + member portablePDB: bool + member embeddedPDB: bool + member embedAllSource: bool + member embedSourceList: string list + member sourceLink: string + member ignoreSymbolStoreSequencePoints: bool + member internConstantStrings: bool + member extraOptimizationIterations: int + member win32icon: string + member win32res: string + member win32manifest: string + member includewin32manifest: bool + member linkResources: string list + member showFullPaths: bool + member errorStyle: ErrorStyle + member utf8output: bool + member flatErrors: bool + + member maxErrors: int + member baseAddress: int32 option + member checksumAlgorithm: HashAlgorithm +#if DEBUG + member showOptimizationData: bool +#endif + member showTerms : bool + member writeTermsToFiles: bool + member doDetuple : bool + member doTLR : bool + member doFinalSimplify: bool + member optSettings : Optimizer.OptimizationSettings + member emitTailcalls: bool + member deterministic: bool + member concurrentBuild: bool + member pathMap: PathMap + member preferredUiLang: string option + member optsOn : bool + member productNameForBannerText: string + member showBanner : bool + member showTimes: bool + member showLoadedAssemblies: bool + member continueAfterParseFailure: bool +#if !NO_EXTENSIONTYPING + member showExtensionTypeMessages: bool +#endif + member pause: bool + member alwaysCallVirt: bool + member noDebugData: bool + + /// If true, indicates all type checking and code generation is in the context of fsi.exe + member isInteractive: bool + member isInvalidationSupported: bool + + member xmlDocInfoLoader: IXmlDocumentationInfoLoader option + + member FxResolver: FxResolver + + member ComputeLightSyntaxInitialStatus: string -> bool + + member GetTargetFrameworkDirectories: unit -> string list + + /// Get the loaded sources that exist and issue a warning for the ones that don't + member GetAvailableLoadedSources: unit -> (range*string) list + + member ComputeCanContainEntryPoint: sourceFiles:string list -> bool list *bool + + /// File system query based on TcConfig settings + member ResolveSourceFile: range * filename: string * pathLoadedFrom: string -> string + + /// File system query based on TcConfig settings + member MakePathAbsolute: string -> string + + member resolutionEnvironment: LegacyResolutionEnvironment + + member copyFSharpCore: CopyFSharpCoreFlag + + member shadowCopyReferences: bool + + member useSdkRefs: bool + + member sdkDirOverride: string option + + member legacyReferenceResolver: LegacyReferenceResolver + + member emitDebugInfoInQuotations: bool + + member langVersion: LanguageVersion + + static member Create: TcConfigBuilder * validate: bool -> TcConfig + + member tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot + + member targetFrameworkVersion : string + + member knownUnresolvedReferences: UnresolvedAssemblyReference list + + member packageManagerLines: Map + + member loadedSources: (range * string * string) list + + /// Prevent erasure of conditional attributes and methods so tooling is able analyse them. + member noConditionalErasure: bool + + /// if true - 'let mutable x = Span.Empty', the value 'x' is a stack referring span. Used for internal testing purposes only until we get true stack spans. + member internalTestSpanStackReferring : bool + + member GetSearchPathsForLibraryFiles: unit -> string list + + member IsSystemAssembly: string -> bool + + member PrimaryAssemblyDllReference: unit -> AssemblyReference + + member CoreLibraryDllReference: unit -> AssemblyReference + + /// Allow forking and subsuequent modification of the TcConfig via a new TcConfigBuilder + member CloneToBuilder: unit -> TcConfigBuilder + + /// Indicates if the compilation will result in F# signature data resource in the generated binary + member GenerateSignatureData: bool + + /// Indicates if the compilation will result in an F# optimization data resource in the generated binary + member GenerateOptimizationData: bool + + /// Check if the primary assembly is mscorlib + member assumeDotNetFramework: bool + +/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, +/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. +[] +type TcConfigProvider = + + member Get: CompilationThreadToken -> TcConfig + + /// Get a TcConfigProvider which will return only the exact TcConfig. + static member Constant: TcConfig -> TcConfigProvider + + /// Get a TcConfigProvider which will continue to respect changes in the underlying + /// TcConfigBuilder rather than delivering snapshots. + static member BasedOnMutableBuilder: TcConfigBuilder -> TcConfigProvider + +val TryResolveFileUsingPaths: paths: string list * m: range * name: string -> string option + +val ResolveFileUsingPaths: paths: string list * m: range * name: string -> string + +val GetWarningNumber: m: range * warningNumber: string -> int option + +/// Get the name used for FSharp.Core +val GetFSharpCoreLibraryName: unit -> string + +/// Signature file suffixes +val FSharpSigFileSuffixes: string list + +/// Implementation file suffixes +val FSharpImplFileSuffixes: string list + +/// Script file suffixes +val FSharpScriptFileSuffixes: string list + +/// File suffixes where #light is the default +val FSharpLightSyntaxFileSuffixes: string list + +val doNotRequireNamespaceOrModuleSuffixes: string list + +val mlCompatSuffixes: string list diff --git a/src/fsharp/CompilerDiagnostics.fs b/src/fsharp/CompilerDiagnostics.fs new file mode 100644 index 00000000000..d0f80e1da0e --- /dev/null +++ b/src/fsharp/CompilerDiagnostics.fs @@ -0,0 +1,1955 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to prepare, post-process, filter and emit compiler diagnsotics +module internal FSharp.Compiler.CompilerDiagnostics + +open System +open System.Diagnostics +open System.IO +open System.Text + +open Internal.Utilities.Library.Extras +open Internal.Utilities.Library +open Internal.Utilities.Text + +open FSharp.Compiler +open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.ConstraintSolver +open FSharp.Compiler.DiagnosticMessage +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Infos +open FSharp.Compiler.IO +open FSharp.Compiler.Lexhelp +open FSharp.Compiler.MethodCalls +open FSharp.Compiler.MethodOverrides +open FSharp.Compiler.NameResolution +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.SignatureConformance +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps + +#if DEBUG +[] +module internal CompilerService = + let showAssertForUnexpectedException = ref true +#endif // DEBUG + +/// This exception is an old-style way of reporting a diagnostic +exception HashIncludeNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashReferenceNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashLoadedSourceHasIssues of informationals: exn list * warnings: exn list * errors: exn list * range + +/// This exception is an old-style way of reporting a diagnostic +exception HashLoadedScriptConsideredSource of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashDirectiveNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionFull of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionForHtmlDoc of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionSuggestAlternative of string * string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionNoDescription of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception InternalCommandLineOption of string * range + +let GetRangeOfDiagnostic(err: PhasedDiagnostic) = + let rec RangeFromException = function + | ErrorFromAddingConstraint(_, err2, _) -> RangeFromException err2 +#if !NO_EXTENSIONTYPING + | ExtensionTyping.ProvidedTypeResolutionNoRange e -> RangeFromException e + | ExtensionTyping.ProvidedTypeResolution(m, _) +#endif + | ReservedKeyword(_, m) + | IndentationProblem(_, m) + | ErrorFromAddingTypeEquation(_, _, _, _, _, m) + | ErrorFromApplyingDefault(_, _, _, _, _, m) + | ErrorsFromAddingSubsumptionConstraint(_, _, _, _, _, _, m) + | FunctionExpected(_, _, m) + | BakedInMemberConstraintName(_, m) + | StandardOperatorRedefinitionWarning(_, m) + | BadEventTransformation m + | ParameterlessStructCtor m + | FieldNotMutable (_, _, m) + | Recursion (_, _, _, _, m) + | InvalidRuntimeCoercion(_, _, _, m) + | IndeterminateRuntimeCoercion(_, _, _, m) + | IndeterminateStaticCoercion (_, _, _, m) + | StaticCoercionShouldUseBox (_, _, _, m) + | CoercionTargetSealed(_, _, m) + | UpcastUnnecessary m + | QuotationTranslator.IgnoringPartOfQuotedTermWarning (_, m) + + | TypeTestUnnecessary m + | RuntimeCoercionSourceSealed(_, _, m) + | OverrideDoesntOverride(_, _, _, _, _, m) + | UnionPatternsBindDifferentNames m + | UnionCaseWrongArguments (_, _, _, m) + | TypeIsImplicitlyAbstract m + | RequiredButNotSpecified (_, _, _, _, m) + | FunctionValueUnexpected (_, _, m) + | UnitTypeExpected (_, _, m) + | UnitTypeExpectedWithEquality (_, _, m) + | UnitTypeExpectedWithPossiblePropertySetter (_, _, _, _, m) + | UnitTypeExpectedWithPossibleAssignment (_, _, _, _, m) + | UseOfAddressOfOperator m + | DeprecatedThreadStaticBindingWarning m + | NonUniqueInferredAbstractSlot (_, _, _, _, _, m) + | DefensiveCopyWarning (_, m) + | LetRecCheckedAtRuntime m + | UpperCaseIdentifierInPattern m + | NotUpperCaseConstructor m + | RecursiveUseCheckedAtRuntime (_, _, m) + | LetRecEvaluatedOutOfOrder (_, _, _, m) + | Error (_, m) + | ErrorWithSuggestions (_, m, _, _) + | SyntaxError (_, m) + | InternalError (_, m) + | InterfaceNotRevealed(_, _, m) + | WrappedError (_, m) + | PatternMatchCompilation.MatchIncomplete (_, _, m) + | PatternMatchCompilation.EnumMatchIncomplete (_, _, m) + | PatternMatchCompilation.RuleNeverMatched m + | ValNotMutable(_, _, m) + | ValNotLocal(_, _, m) + | MissingFields(_, m) + | OverrideInIntrinsicAugmentation m + | IntfImplInIntrinsicAugmentation m + | OverrideInExtrinsicAugmentation m + | IntfImplInExtrinsicAugmentation m + | ValueRestriction(_, _, _, _, _, m) + | LetRecUnsound (_, _, m) + | ObsoleteError (_, m) + | ObsoleteWarning (_, m) + | Experimental (_, m) + | PossibleUnverifiableCode m + | UserCompilerMessage (_, _, m) + | Deprecated(_, m) + | LibraryUseOnly m + | FieldsFromDifferentTypes (_, _, _, m) + | IndeterminateType m + | TyconBadArgs(_, _, _, m) -> + Some m + + | FieldNotContained(_, _, _, arf, _, _) -> Some arf.Range + | ValueNotContained(_, _, _, aval, _, _) -> Some aval.Range + | ConstrNotContained(_, _, _, aval, _, _) -> Some aval.Id.idRange + | ExnconstrNotContained(_, _, aexnc, _, _) -> Some aexnc.Range + + | VarBoundTwice id + | UndefinedName(_, _, id, _) -> + Some id.idRange + + | Duplicate(_, _, m) + | NameClash(_, _, _, m, _, _, _) + | UnresolvedOverloading(_, _, _, m) + | UnresolvedConversionOperator (_, _, _, m) + | VirtualAugmentationOnNullValuedType m + | NonVirtualAugmentationOnNullValuedType m + | NonRigidTypar(_, _, _, _, _, m) + | ConstraintSolverTupleDiffLengths(_, _, _, m, _) + | ConstraintSolverInfiniteTypes(_, _, _, _, m, _) + | ConstraintSolverMissingConstraint(_, _, _, m, _) + | ConstraintSolverTypesNotInEqualityRelation(_, _, _, m, _, _) + | ConstraintSolverError(_, m, _) + | ConstraintSolverTypesNotInSubsumptionRelation(_, _, _, m, _) + | ConstraintSolverRelatedInformation(_, m, _) + | SelfRefObjCtor(_, m) -> + Some m + + | NotAFunction(_, _, mfun, _) -> + Some mfun + + | NotAFunctionButIndexer(_, _, _, mfun, _, _) -> + Some mfun + + | IllegalFileNameChar _ -> Some rangeCmdArgs + + | UnresolvedReferenceError(_, m) + | UnresolvedPathReference(_, _, m) + | DeprecatedCommandLineOptionFull(_, m) + | DeprecatedCommandLineOptionForHtmlDoc(_, m) + | DeprecatedCommandLineOptionSuggestAlternative(_, _, m) + | DeprecatedCommandLineOptionNoDescription(_, m) + | InternalCommandLineOption(_, m) + | HashIncludeNotAllowedInNonScript m + | HashReferenceNotAllowedInNonScript m + | HashDirectiveNotAllowedInNonScript m + | FileNameNotResolved(_, _, m) + | LoadedSourceNotFoundIgnoring(_, m) + | MSBuildReferenceResolutionWarning(_, _, m) + | MSBuildReferenceResolutionError(_, _, m) + | AssemblyNotResolved(_, m) + | HashLoadedSourceHasIssues(_, _, _, m) + | HashLoadedScriptConsideredSource m -> + Some m + // Strip TargetInvocationException wrappers + | :? System.Reflection.TargetInvocationException as e -> + RangeFromException e.InnerException +#if !NO_EXTENSIONTYPING + | :? TypeProviderError as e -> e.Range |> Some +#endif + + | _ -> None + + RangeFromException err.Exception + +let GetDiagnosticNumber(err: PhasedDiagnostic) = + let rec GetFromException(e: exn) = + match e with + (* DO NOT CHANGE THESE NUMBERS *) + | ErrorFromAddingTypeEquation _ -> 1 + | FunctionExpected _ -> 2 + | NotAFunctionButIndexer _ -> 3217 + | NotAFunction _ -> 3 + | FieldNotMutable _ -> 5 + | Recursion _ -> 6 + | InvalidRuntimeCoercion _ -> 7 + | IndeterminateRuntimeCoercion _ -> 8 + | PossibleUnverifiableCode _ -> 9 + | SyntaxError _ -> 10 + // 11 cannot be reused + // 12 cannot be reused + | IndeterminateStaticCoercion _ -> 13 + | StaticCoercionShouldUseBox _ -> 14 + // 15 cannot be reused + | RuntimeCoercionSourceSealed _ -> 16 + | OverrideDoesntOverride _ -> 17 + | UnionPatternsBindDifferentNames _ -> 18 + | UnionCaseWrongArguments _ -> 19 + | UnitTypeExpected _ -> 20 + | UnitTypeExpectedWithEquality _ -> 20 + | UnitTypeExpectedWithPossiblePropertySetter _ -> 20 + | UnitTypeExpectedWithPossibleAssignment _ -> 20 + | RecursiveUseCheckedAtRuntime _ -> 21 + | LetRecEvaluatedOutOfOrder _ -> 22 + | NameClash _ -> 23 + // 24 cannot be reused + | PatternMatchCompilation.MatchIncomplete _ -> 25 + | PatternMatchCompilation.RuleNeverMatched _ -> 26 + | ValNotMutable _ -> 27 + | ValNotLocal _ -> 28 + | MissingFields _ -> 29 + | ValueRestriction _ -> 30 + | LetRecUnsound _ -> 31 + | FieldsFromDifferentTypes _ -> 32 + | TyconBadArgs _ -> 33 + | ValueNotContained _ -> 34 + | Deprecated _ -> 35 + | ConstrNotContained _ -> 36 + | Duplicate _ -> 37 + | VarBoundTwice _ -> 38 + | UndefinedName _ -> 39 + | LetRecCheckedAtRuntime _ -> 40 + | UnresolvedOverloading _ -> 41 + | LibraryUseOnly _ -> 42 + | ErrorFromAddingConstraint _ -> 43 + | ObsoleteWarning _ -> 44 + | ReservedKeyword _ -> 46 + | SelfRefObjCtor _ -> 47 + | VirtualAugmentationOnNullValuedType _ -> 48 + | UpperCaseIdentifierInPattern _ -> 49 + | InterfaceNotRevealed _ -> 50 + | UseOfAddressOfOperator _ -> 51 + | DefensiveCopyWarning _ -> 52 + | NotUpperCaseConstructor _ -> 53 + | TypeIsImplicitlyAbstract _ -> 54 + // 55 cannot be reused + | DeprecatedThreadStaticBindingWarning _ -> 56 + | Experimental _ -> 57 + | IndentationProblem _ -> 58 + | CoercionTargetSealed _ -> 59 + | OverrideInIntrinsicAugmentation _ -> 60 + | NonVirtualAugmentationOnNullValuedType _ -> 61 + | UserCompilerMessage (_, n, _) -> n + | ExnconstrNotContained _ -> 63 + | NonRigidTypar _ -> 64 + // 65 cannot be reused + | UpcastUnnecessary _ -> 66 + | TypeTestUnnecessary _ -> 67 + | QuotationTranslator.IgnoringPartOfQuotedTermWarning _ -> 68 + | IntfImplInIntrinsicAugmentation _ -> 69 + | NonUniqueInferredAbstractSlot _ -> 70 + | ErrorFromApplyingDefault _ -> 71 + | IndeterminateType _ -> 72 + | InternalError _ -> 73 + | UnresolvedReferenceNoRange _ + | UnresolvedReferenceError _ + | UnresolvedPathReferenceNoRange _ + | UnresolvedPathReference _ -> 74 + | DeprecatedCommandLineOptionFull _ + | DeprecatedCommandLineOptionForHtmlDoc _ + | DeprecatedCommandLineOptionSuggestAlternative _ + | DeprecatedCommandLineOptionNoDescription _ + | InternalCommandLineOption _ -> 75 + | HashIncludeNotAllowedInNonScript _ + | HashReferenceNotAllowedInNonScript _ + | HashDirectiveNotAllowedInNonScript _ -> 76 + | BakedInMemberConstraintName _ -> 77 + | FileNameNotResolved _ -> 78 + | LoadedSourceNotFoundIgnoring _ -> 79 + // 80 cannot be reused + | ParameterlessStructCtor _ -> 81 + | MSBuildReferenceResolutionWarning _ -> 82 + | MSBuildReferenceResolutionError _ -> 83 + | AssemblyNotResolved _ -> 84 + | HashLoadedSourceHasIssues _ -> 85 + | StandardOperatorRedefinitionWarning _ -> 86 + | InvalidInternalsVisibleToAssemblyName _ -> 87 + // 88 cannot be reused + | OverrideInExtrinsicAugmentation _ -> 89 + | IntfImplInExtrinsicAugmentation _ -> 90 + | BadEventTransformation _ -> 91 + | HashLoadedScriptConsideredSource _ -> 92 + | UnresolvedConversionOperator _ -> 93 + // avoid 94-100 for safety + | ObsoleteError _ -> 101 +#if !NO_EXTENSIONTYPING + | ExtensionTyping.ProvidedTypeResolutionNoRange _ + | ExtensionTyping.ProvidedTypeResolution _ -> 103 +#endif + | PatternMatchCompilation.EnumMatchIncomplete _ -> 104 + (* DO NOT CHANGE THE NUMBERS *) + + // Strip TargetInvocationException wrappers + | :? System.Reflection.TargetInvocationException as e -> + GetFromException e.InnerException + + | WrappedError(e, _) -> GetFromException e + + | Error ((n, _), _) -> n + | ErrorWithSuggestions ((n, _), _, _, _) -> n + | Failure _ -> 192 + | IllegalFileNameChar(fileName, invalidChar) -> fst (FSComp.SR.buildUnexpectedFileNameCharacter(fileName, string invalidChar)) +#if !NO_EXTENSIONTYPING + | :? TypeProviderError as e -> e.Number +#endif + | ErrorsFromAddingSubsumptionConstraint (_, _, _, _, _, ContextInfo.DowncastUsedInsteadOfUpcast _, _) -> fst (FSComp.SR.considerUpcast("", "")) + | _ -> 193 + GetFromException err.Exception + +let GetWarningLevel err = + match err.Exception with + // Level 5 warnings + | RecursiveUseCheckedAtRuntime _ + | LetRecEvaluatedOutOfOrder _ + | DefensiveCopyWarning _ -> 5 + + | Error((n, _), _) + | ErrorWithSuggestions((n, _), _, _, _) -> + // 1178, tcNoComparisonNeeded1, "The struct, record or union type '%s' is not structurally comparable because the type parameter %s does not satisfy the 'comparison' constraint..." + // 1178, tcNoComparisonNeeded2, "The struct, record or union type '%s' is not structurally comparable because the type '%s' does not satisfy the 'comparison' constraint...." + // 1178, tcNoEqualityNeeded1, "The struct, record or union type '%s' does not support structural equality because the type parameter %s does not satisfy the 'equality' constraint..." + // 1178, tcNoEqualityNeeded2, "The struct, record or union type '%s' does not support structural equality because the type '%s' does not satisfy the 'equality' constraint...." + if (n = 1178) then 5 else 2 + // Level 2 + | _ -> 2 + +let IsWarningOrInfoEnabled (err, severity) n level specificWarnOn = + List.contains n specificWarnOn || + // Some specific warnings/informational are never on by default, i.e. unused variable warnings + match n with + | 1182 -> false // chkUnusedValue - off by default + | 3180 -> false // abImplicitHeapAllocation - off by default + | 3366 -> false //tcIndexNotationDeprecated - currently off by default + | 3517 -> false // optFailedToInlineSuggestedValue - off by default + | 3388 -> false // tcSubsumptionImplicitConversionUsed - off by default + | 3389 -> false // tcBuiltInImplicitConversionUsed - off by default + | 3390 -> false // tcImplicitConversionUsedForMethodArg - off by default + | _ -> + (severity = FSharpDiagnosticSeverity.Info) || + (severity = FSharpDiagnosticSeverity.Warning && level >= GetWarningLevel err) + +let SplitRelatedDiagnostics(err: PhasedDiagnostic) : PhasedDiagnostic * PhasedDiagnostic list = + let ToPhased e = {Exception=e; Phase = err.Phase} + let rec SplitRelatedException = function + | ConstraintSolverRelatedInformation(fopt, m2, e) -> + let e, related = SplitRelatedException e + ConstraintSolverRelatedInformation(fopt, m2, e.Exception)|>ToPhased, related + | ErrorFromAddingTypeEquation(g, denv, t1, t2, e, m) -> + let e, related = SplitRelatedException e + ErrorFromAddingTypeEquation(g, denv, t1, t2, e.Exception, m)|>ToPhased, related + | ErrorFromApplyingDefault(g, denv, tp, defaultType, e, m) -> + let e, related = SplitRelatedException e + ErrorFromApplyingDefault(g, denv, tp, defaultType, e.Exception, m)|>ToPhased, related + | ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e, contextInfo, m) -> + let e, related = SplitRelatedException e + ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e.Exception, contextInfo, m)|>ToPhased, related + | ErrorFromAddingConstraint(x, e, m) -> + let e, related = SplitRelatedException e + ErrorFromAddingConstraint(x, e.Exception, m)|>ToPhased, related + | WrappedError (e, m) -> + let e, related = SplitRelatedException e + WrappedError(e.Exception, m)|>ToPhased, related + // Strip TargetInvocationException wrappers + | :? System.Reflection.TargetInvocationException as e -> + SplitRelatedException e.InnerException + | e -> + ToPhased e, [] + SplitRelatedException err.Exception + + +let DeclareMessage = DeclareResourceString + +do FSComp.SR.RunStartupValidation() +let SeeAlsoE() = DeclareResourceString("SeeAlso", "%s") +let ConstraintSolverTupleDiffLengthsE() = DeclareResourceString("ConstraintSolverTupleDiffLengths", "%d%d") +let ConstraintSolverInfiniteTypesE() = DeclareResourceString("ConstraintSolverInfiniteTypes", "%s%s") +let ConstraintSolverMissingConstraintE() = DeclareResourceString("ConstraintSolverMissingConstraint", "%s") +let ConstraintSolverTypesNotInEqualityRelation1E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation1", "%s%s") +let ConstraintSolverTypesNotInEqualityRelation2E() = DeclareResourceString("ConstraintSolverTypesNotInEqualityRelation2", "%s%s") +let ConstraintSolverTypesNotInSubsumptionRelationE() = DeclareResourceString("ConstraintSolverTypesNotInSubsumptionRelation", "%s%s%s") +let ErrorFromAddingTypeEquation1E() = DeclareResourceString("ErrorFromAddingTypeEquation1", "%s%s%s") +let ErrorFromAddingTypeEquation2E() = DeclareResourceString("ErrorFromAddingTypeEquation2", "%s%s%s") +let ErrorFromApplyingDefault1E() = DeclareResourceString("ErrorFromApplyingDefault1", "%s") +let ErrorFromApplyingDefault2E() = DeclareResourceString("ErrorFromApplyingDefault2", "") +let ErrorsFromAddingSubsumptionConstraintE() = DeclareResourceString("ErrorsFromAddingSubsumptionConstraint", "%s%s%s") +let UpperCaseIdentifierInPatternE() = DeclareResourceString("UpperCaseIdentifierInPattern", "") +let NotUpperCaseConstructorE() = DeclareResourceString("NotUpperCaseConstructor", "") +let FunctionExpectedE() = DeclareResourceString("FunctionExpected", "") +let BakedInMemberConstraintNameE() = DeclareResourceString("BakedInMemberConstraintName", "%s") +let BadEventTransformationE() = DeclareResourceString("BadEventTransformation", "") +let ParameterlessStructCtorE() = DeclareResourceString("ParameterlessStructCtor", "") +let InterfaceNotRevealedE() = DeclareResourceString("InterfaceNotRevealed", "%s") +let TyconBadArgsE() = DeclareResourceString("TyconBadArgs", "%s%d%d") +let IndeterminateTypeE() = DeclareResourceString("IndeterminateType", "") +let NameClash1E() = DeclareResourceString("NameClash1", "%s%s") +let NameClash2E() = DeclareResourceString("NameClash2", "%s%s%s%s%s") +let Duplicate1E() = DeclareResourceString("Duplicate1", "%s") +let Duplicate2E() = DeclareResourceString("Duplicate2", "%s%s") +let UndefinedName2E() = DeclareResourceString("UndefinedName2", "") +let FieldNotMutableE() = DeclareResourceString("FieldNotMutable", "") +let FieldsFromDifferentTypesE() = DeclareResourceString("FieldsFromDifferentTypes", "%s%s") +let VarBoundTwiceE() = DeclareResourceString("VarBoundTwice", "%s") +let RecursionE() = DeclareResourceString("Recursion", "%s%s%s%s") +let InvalidRuntimeCoercionE() = DeclareResourceString("InvalidRuntimeCoercion", "%s%s%s") +let IndeterminateRuntimeCoercionE() = DeclareResourceString("IndeterminateRuntimeCoercion", "%s%s") +let IndeterminateStaticCoercionE() = DeclareResourceString("IndeterminateStaticCoercion", "%s%s") +let StaticCoercionShouldUseBoxE() = DeclareResourceString("StaticCoercionShouldUseBox", "%s%s") +let TypeIsImplicitlyAbstractE() = DeclareResourceString("TypeIsImplicitlyAbstract", "") +let NonRigidTypar1E() = DeclareResourceString("NonRigidTypar1", "%s%s") +let NonRigidTypar2E() = DeclareResourceString("NonRigidTypar2", "%s%s") +let NonRigidTypar3E() = DeclareResourceString("NonRigidTypar3", "%s%s") +let OBlockEndSentenceE() = DeclareResourceString("BlockEndSentence", "") +let UnexpectedEndOfInputE() = DeclareResourceString("UnexpectedEndOfInput", "") +let UnexpectedE() = DeclareResourceString("Unexpected", "%s") +let NONTERM_interactionE() = DeclareResourceString("NONTERM.interaction", "") +let NONTERM_hashDirectiveE() = DeclareResourceString("NONTERM.hashDirective", "") +let NONTERM_fieldDeclE() = DeclareResourceString("NONTERM.fieldDecl", "") +let NONTERM_unionCaseReprE() = DeclareResourceString("NONTERM.unionCaseRepr", "") +let NONTERM_localBindingE() = DeclareResourceString("NONTERM.localBinding", "") +let NONTERM_hardwhiteLetBindingsE() = DeclareResourceString("NONTERM.hardwhiteLetBindings", "") +let NONTERM_classDefnMemberE() = DeclareResourceString("NONTERM.classDefnMember", "") +let NONTERM_defnBindingsE() = DeclareResourceString("NONTERM.defnBindings", "") +let NONTERM_classMemberSpfnE() = DeclareResourceString("NONTERM.classMemberSpfn", "") +let NONTERM_valSpfnE() = DeclareResourceString("NONTERM.valSpfn", "") +let NONTERM_tyconSpfnE() = DeclareResourceString("NONTERM.tyconSpfn", "") +let NONTERM_anonLambdaExprE() = DeclareResourceString("NONTERM.anonLambdaExpr", "") +let NONTERM_attrUnionCaseDeclE() = DeclareResourceString("NONTERM.attrUnionCaseDecl", "") +let NONTERM_cPrototypeE() = DeclareResourceString("NONTERM.cPrototype", "") +let NONTERM_objectImplementationMembersE() = DeclareResourceString("NONTERM.objectImplementationMembers", "") +let NONTERM_ifExprCasesE() = DeclareResourceString("NONTERM.ifExprCases", "") +let NONTERM_openDeclE() = DeclareResourceString("NONTERM.openDecl", "") +let NONTERM_fileModuleSpecE() = DeclareResourceString("NONTERM.fileModuleSpec", "") +let NONTERM_patternClausesE() = DeclareResourceString("NONTERM.patternClauses", "") +let NONTERM_beginEndExprE() = DeclareResourceString("NONTERM.beginEndExpr", "") +let NONTERM_recdExprE() = DeclareResourceString("NONTERM.recdExpr", "") +let NONTERM_tyconDefnE() = DeclareResourceString("NONTERM.tyconDefn", "") +let NONTERM_exconCoreE() = DeclareResourceString("NONTERM.exconCore", "") +let NONTERM_typeNameInfoE() = DeclareResourceString("NONTERM.typeNameInfo", "") +let NONTERM_attributeListE() = DeclareResourceString("NONTERM.attributeList", "") +let NONTERM_quoteExprE() = DeclareResourceString("NONTERM.quoteExpr", "") +let NONTERM_typeConstraintE() = DeclareResourceString("NONTERM.typeConstraint", "") +let NONTERM_Category_ImplementationFileE() = DeclareResourceString("NONTERM.Category.ImplementationFile", "") +let NONTERM_Category_DefinitionE() = DeclareResourceString("NONTERM.Category.Definition", "") +let NONTERM_Category_SignatureFileE() = DeclareResourceString("NONTERM.Category.SignatureFile", "") +let NONTERM_Category_PatternE() = DeclareResourceString("NONTERM.Category.Pattern", "") +let NONTERM_Category_ExprE() = DeclareResourceString("NONTERM.Category.Expr", "") +let NONTERM_Category_TypeE() = DeclareResourceString("NONTERM.Category.Type", "") +let NONTERM_typeArgsActualE() = DeclareResourceString("NONTERM.typeArgsActual", "") +let TokenName1E() = DeclareResourceString("TokenName1", "%s") +let TokenName1TokenName2E() = DeclareResourceString("TokenName1TokenName2", "%s%s") +let TokenName1TokenName2TokenName3E() = DeclareResourceString("TokenName1TokenName2TokenName3", "%s%s%s") +let RuntimeCoercionSourceSealed1E() = DeclareResourceString("RuntimeCoercionSourceSealed1", "%s") +let RuntimeCoercionSourceSealed2E() = DeclareResourceString("RuntimeCoercionSourceSealed2", "%s") +let CoercionTargetSealedE() = DeclareResourceString("CoercionTargetSealed", "%s") +let UpcastUnnecessaryE() = DeclareResourceString("UpcastUnnecessary", "") +let TypeTestUnnecessaryE() = DeclareResourceString("TypeTestUnnecessary", "") +let OverrideDoesntOverride1E() = DeclareResourceString("OverrideDoesntOverride1", "%s") +let OverrideDoesntOverride2E() = DeclareResourceString("OverrideDoesntOverride2", "%s") +let OverrideDoesntOverride3E() = DeclareResourceString("OverrideDoesntOverride3", "%s") +let OverrideDoesntOverride4E() = DeclareResourceString("OverrideDoesntOverride4", "%s") +let UnionCaseWrongArgumentsE() = DeclareResourceString("UnionCaseWrongArguments", "%d%d") +let UnionPatternsBindDifferentNamesE() = DeclareResourceString("UnionPatternsBindDifferentNames", "") +let RequiredButNotSpecifiedE() = DeclareResourceString("RequiredButNotSpecified", "%s%s%s") +let UseOfAddressOfOperatorE() = DeclareResourceString("UseOfAddressOfOperator", "") +let DefensiveCopyWarningE() = DeclareResourceString("DefensiveCopyWarning", "%s") +let DeprecatedThreadStaticBindingWarningE() = DeclareResourceString("DeprecatedThreadStaticBindingWarning", "") +let FunctionValueUnexpectedE() = DeclareResourceString("FunctionValueUnexpected", "%s") +let UnitTypeExpectedE() = DeclareResourceString("UnitTypeExpected", "%s") +let UnitTypeExpectedWithEqualityE() = DeclareResourceString("UnitTypeExpectedWithEquality", "%s") +let UnitTypeExpectedWithPossiblePropertySetterE() = DeclareResourceString("UnitTypeExpectedWithPossiblePropertySetter", "%s%s%s") +let UnitTypeExpectedWithPossibleAssignmentE() = DeclareResourceString("UnitTypeExpectedWithPossibleAssignment", "%s%s") +let UnitTypeExpectedWithPossibleAssignmentToMutableE() = DeclareResourceString("UnitTypeExpectedWithPossibleAssignmentToMutable", "%s%s") +let RecursiveUseCheckedAtRuntimeE() = DeclareResourceString("RecursiveUseCheckedAtRuntime", "") +let LetRecUnsound1E() = DeclareResourceString("LetRecUnsound1", "%s") +let LetRecUnsound2E() = DeclareResourceString("LetRecUnsound2", "%s%s") +let LetRecUnsoundInnerE() = DeclareResourceString("LetRecUnsoundInner", "%s") +let LetRecEvaluatedOutOfOrderE() = DeclareResourceString("LetRecEvaluatedOutOfOrder", "") +let LetRecCheckedAtRuntimeE() = DeclareResourceString("LetRecCheckedAtRuntime", "") +let SelfRefObjCtor1E() = DeclareResourceString("SelfRefObjCtor1", "") +let SelfRefObjCtor2E() = DeclareResourceString("SelfRefObjCtor2", "") +let VirtualAugmentationOnNullValuedTypeE() = DeclareResourceString("VirtualAugmentationOnNullValuedType", "") +let NonVirtualAugmentationOnNullValuedTypeE() = DeclareResourceString("NonVirtualAugmentationOnNullValuedType", "") +let NonUniqueInferredAbstractSlot1E() = DeclareResourceString("NonUniqueInferredAbstractSlot1", "%s") +let NonUniqueInferredAbstractSlot2E() = DeclareResourceString("NonUniqueInferredAbstractSlot2", "") +let NonUniqueInferredAbstractSlot3E() = DeclareResourceString("NonUniqueInferredAbstractSlot3", "%s%s") +let NonUniqueInferredAbstractSlot4E() = DeclareResourceString("NonUniqueInferredAbstractSlot4", "") +let Failure3E() = DeclareResourceString("Failure3", "%s") +let Failure4E() = DeclareResourceString("Failure4", "%s") +let MatchIncomplete1E() = DeclareResourceString("MatchIncomplete1", "") +let MatchIncomplete2E() = DeclareResourceString("MatchIncomplete2", "%s") +let MatchIncomplete3E() = DeclareResourceString("MatchIncomplete3", "%s") +let MatchIncomplete4E() = DeclareResourceString("MatchIncomplete4", "") +let RuleNeverMatchedE() = DeclareResourceString("RuleNeverMatched", "") +let EnumMatchIncomplete1E() = DeclareResourceString("EnumMatchIncomplete1", "") +let ValNotMutableE() = DeclareResourceString("ValNotMutable", "%s") +let ValNotLocalE() = DeclareResourceString("ValNotLocal", "") +let Obsolete1E() = DeclareResourceString("Obsolete1", "") +let Obsolete2E() = DeclareResourceString("Obsolete2", "%s") +let ExperimentalE() = DeclareResourceString("Experimental", "%s") +let PossibleUnverifiableCodeE() = DeclareResourceString("PossibleUnverifiableCode", "") +let DeprecatedE() = DeclareResourceString("Deprecated", "%s") +let LibraryUseOnlyE() = DeclareResourceString("LibraryUseOnly", "") +let MissingFieldsE() = DeclareResourceString("MissingFields", "%s") +let ValueRestriction1E() = DeclareResourceString("ValueRestriction1", "%s%s%s") +let ValueRestriction2E() = DeclareResourceString("ValueRestriction2", "%s%s%s") +let ValueRestriction3E() = DeclareResourceString("ValueRestriction3", "%s") +let ValueRestriction4E() = DeclareResourceString("ValueRestriction4", "%s%s%s") +let ValueRestriction5E() = DeclareResourceString("ValueRestriction5", "%s%s%s") +let RecoverableParseErrorE() = DeclareResourceString("RecoverableParseError", "") +let ReservedKeywordE() = DeclareResourceString("ReservedKeyword", "%s") +let IndentationProblemE() = DeclareResourceString("IndentationProblem", "%s") +let OverrideInIntrinsicAugmentationE() = DeclareResourceString("OverrideInIntrinsicAugmentation", "") +let OverrideInExtrinsicAugmentationE() = DeclareResourceString("OverrideInExtrinsicAugmentation", "") +let IntfImplInIntrinsicAugmentationE() = DeclareResourceString("IntfImplInIntrinsicAugmentation", "") +let IntfImplInExtrinsicAugmentationE() = DeclareResourceString("IntfImplInExtrinsicAugmentation", "") +let UnresolvedReferenceNoRangeE() = DeclareResourceString("UnresolvedReferenceNoRange", "%s") +let UnresolvedPathReferenceNoRangeE() = DeclareResourceString("UnresolvedPathReferenceNoRange", "%s%s") +let HashIncludeNotAllowedInNonScriptE() = DeclareResourceString("HashIncludeNotAllowedInNonScript", "") +let HashReferenceNotAllowedInNonScriptE() = DeclareResourceString("HashReferenceNotAllowedInNonScript", "") +let HashDirectiveNotAllowedInNonScriptE() = DeclareResourceString("HashDirectiveNotAllowedInNonScript", "") +let FileNameNotResolvedE() = DeclareResourceString("FileNameNotResolved", "%s%s") +let AssemblyNotResolvedE() = DeclareResourceString("AssemblyNotResolved", "%s") +let HashLoadedSourceHasIssues0E() = DeclareResourceString("HashLoadedSourceHasIssues0", "") +let HashLoadedSourceHasIssues1E() = DeclareResourceString("HashLoadedSourceHasIssues1", "") +let HashLoadedSourceHasIssues2E() = DeclareResourceString("HashLoadedSourceHasIssues2", "") +let HashLoadedScriptConsideredSourceE() = DeclareResourceString("HashLoadedScriptConsideredSource", "") +let InvalidInternalsVisibleToAssemblyName1E() = DeclareResourceString("InvalidInternalsVisibleToAssemblyName1", "%s%s") +let InvalidInternalsVisibleToAssemblyName2E() = DeclareResourceString("InvalidInternalsVisibleToAssemblyName2", "%s") +let LoadedSourceNotFoundIgnoringE() = DeclareResourceString("LoadedSourceNotFoundIgnoring", "%s") +let MSBuildReferenceResolutionErrorE() = DeclareResourceString("MSBuildReferenceResolutionError", "%s%s") +let TargetInvocationExceptionWrapperE() = DeclareResourceString("TargetInvocationExceptionWrapper", "%s") + +#if DEBUG +let mutable showParserStackOnParseError = false +#endif + +let getErrorString key = SR.GetString key + +let (|InvalidArgument|_|) (exn: exn) = match exn with :? ArgumentException as e -> Some e.Message | _ -> None + +let OutputPhasedErrorR (os: StringBuilder) (err: PhasedDiagnostic) (canSuggestNames: bool) = + + let suggestNames suggestionsF idText = + if canSuggestNames then + let buffer = ErrorResolutionHints.SuggestionBuffer idText + if not buffer.Disabled then + suggestionsF buffer.Add + if not buffer.IsEmpty then + os.Append " " |> ignore + os.Append(FSComp.SR.undefinedNameSuggestionsIntro()) |> ignore + for value in buffer do + os.AppendLine() |> ignore + os.Append " " |> ignore + os.Append(DecompileOpName value) |> ignore + + let rec OutputExceptionR (os: StringBuilder) error = + + match error with + | ConstraintSolverTupleDiffLengths(_, tl1, tl2, m, m2) -> + os.Append(ConstraintSolverTupleDiffLengthsE().Format tl1.Length tl2.Length) |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + + | ConstraintSolverInfiniteTypes(denv, contextInfo, t1, t2, m, m2) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + os.Append(ConstraintSolverInfiniteTypesE().Format t1 t2) |> ignore + + match contextInfo with + | ContextInfo.ReturnInComputationExpression -> + os.Append(" " + FSComp.SR.returnUsedInsteadOfReturnBang()) |> ignore + | ContextInfo.YieldInComputationExpression -> + os.Append(" " + FSComp.SR.yieldUsedInsteadOfYieldBang()) |> ignore + | _ -> () + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + + | ConstraintSolverMissingConstraint(denv, tpr, tpc, m, m2) -> + os.Append(ConstraintSolverMissingConstraintE().Format (NicePrint.stringOfTyparConstraint denv (tpr, tpc))) |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + + | ConstraintSolverTypesNotInEqualityRelation(denv, (TType_measure _ as t1), (TType_measure _ as t2), m, m2, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + + os.Append(ConstraintSolverTypesNotInEqualityRelation1E().Format t1 t2 ) |> ignore + + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + + | ConstraintSolverTypesNotInEqualityRelation(denv, t1, t2, m, m2, contextInfo) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + + match contextInfo with + | ContextInfo.IfExpression range when equals range m -> os.Append(FSComp.SR.ifExpression(t1, t2)) |> ignore + | ContextInfo.CollectionElement (isArray, range) when equals range m -> + if isArray then + os.Append(FSComp.SR.arrayElementHasWrongType(t1, t2)) |> ignore + else + os.Append(FSComp.SR.listElementHasWrongType(t1, t2)) |> ignore + | ContextInfo.OmittedElseBranch range when equals range m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore + | ContextInfo.ElseBranchResult range when equals range m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1, t2)) |> ignore + | ContextInfo.FollowingPatternMatchClause range when equals range m -> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1, t2)) |> ignore + | ContextInfo.PatternMatchGuard range when equals range m -> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2)) |> ignore + | _ -> os.Append(ConstraintSolverTypesNotInEqualityRelation2E().Format t1 t2) |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m)) |> ignore + + | ConstraintSolverTypesNotInSubsumptionRelation(denv, t1, t2, m, m2) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, cxs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + os.Append(ConstraintSolverTypesNotInSubsumptionRelationE().Format t2 t1 cxs) |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore + + | ConstraintSolverError(msg, m, m2) -> + os.Append msg |> ignore + if m.StartLine <> m2.StartLine then + os.Append(SeeAlsoE().Format (stringOfRange m2)) |> ignore + + | ConstraintSolverRelatedInformation(fopt, _, e) -> + match e with + | ConstraintSolverError _ -> OutputExceptionR os e + | _ -> () + fopt |> Option.iter (Printf.bprintf os " %s") + + | ErrorFromAddingTypeEquation(g, denv, t1, t2, ConstraintSolverTypesNotInEqualityRelation(_, t1', t2', m, _, contextInfo), _) + when typeEquiv g t1 t1' + && typeEquiv g t2 t2' -> + let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + match contextInfo with + | ContextInfo.IfExpression range when equals range m -> os.Append(FSComp.SR.ifExpression(t1, t2)) |> ignore + | ContextInfo.CollectionElement (isArray, range) when equals range m -> + if isArray then + os.Append(FSComp.SR.arrayElementHasWrongType(t1, t2)) |> ignore + else + os.Append(FSComp.SR.listElementHasWrongType(t1, t2)) |> ignore + | ContextInfo.OmittedElseBranch range when equals range m -> os.Append(FSComp.SR.missingElseBranch(t2)) |> ignore + | ContextInfo.ElseBranchResult range when equals range m -> os.Append(FSComp.SR.elseBranchHasWrongType(t1, t2)) |> ignore + | ContextInfo.FollowingPatternMatchClause range when equals range m -> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1, t2)) |> ignore + | ContextInfo.PatternMatchGuard range when equals range m -> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2)) |> ignore + | ContextInfo.TupleInRecordFields -> + os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore + os.Append(Environment.NewLine + FSComp.SR.commaInsteadOfSemicolonInRecord()) |> ignore + | _ when t2 = "bool" && t1.EndsWithOrdinal(" ref") -> + os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore + os.Append(Environment.NewLine + FSComp.SR.derefInsteadOfNot()) |> ignore + | _ -> os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs) |> ignore + + | ErrorFromAddingTypeEquation(_, _, _, _, (ConstraintSolverTypesNotInEqualityRelation (_, _, _, _, _, contextInfo) as e), _) + when (match contextInfo with ContextInfo.NoContext -> false | _ -> true) -> + OutputExceptionR os e + + | ErrorFromAddingTypeEquation(_, _, _, _, (ConstraintSolverTypesNotInSubsumptionRelation _ | ConstraintSolverError _ as e), _) -> + OutputExceptionR os e + + | ErrorFromAddingTypeEquation(g, denv, t1, t2, e, _) -> + if not (typeEquiv g t1 t2) then + let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + if t1<>t2 + tpcs then os.Append(ErrorFromAddingTypeEquation2E().Format t1 t2 tpcs) |> ignore + + OutputExceptionR os e + + | ErrorFromApplyingDefault(_, denv, _, defaultType, e, _) -> + let defaultType = NicePrint.minimalStringOfType denv defaultType + os.Append(ErrorFromApplyingDefault1E().Format defaultType) |> ignore + OutputExceptionR os e + os.Append(ErrorFromApplyingDefault2E().Format) |> ignore + + | ErrorsFromAddingSubsumptionConstraint(g, denv, t1, t2, e, contextInfo, _) -> + match contextInfo with + | ContextInfo.DowncastUsedInsteadOfUpcast isOperator -> + let t1, t2, _ = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + if isOperator then + os.Append(FSComp.SR.considerUpcastOperator(t1, t2) |> snd) |> ignore + else + os.Append(FSComp.SR.considerUpcast(t1, t2) |> snd) |> ignore + | _ -> + if not (typeEquiv g t1 t2) then + let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv t1 t2 + if t1 <> (t2 + tpcs) then + os.Append(ErrorsFromAddingSubsumptionConstraintE().Format t2 t1 tpcs) |> ignore + else + OutputExceptionR os e + else + OutputExceptionR os e + + | UpperCaseIdentifierInPattern _ -> + os.Append(UpperCaseIdentifierInPatternE().Format) |> ignore + + | NotUpperCaseConstructor _ -> + os.Append(NotUpperCaseConstructorE().Format) |> ignore + + | ErrorFromAddingConstraint(_, e, _) -> + OutputExceptionR os e + +#if !NO_EXTENSIONTYPING + | ExtensionTyping.ProvidedTypeResolutionNoRange e + + | ExtensionTyping.ProvidedTypeResolution(_, e) -> + OutputExceptionR os e + + | :? TypeProviderError as e -> + os.Append(e.ContextualErrorMessage) |> ignore +#endif + + | UnresolvedOverloading(denv, callerArgs, failure, m) -> + + // extract eventual information (return type and type parameters) + // from ConstraintTraitInfo + let knownReturnType, genericParameterTypes = + match failure with + | NoOverloadsFound (cx=Some cx) + | PossibleCandidates (cx=Some cx) -> cx.ReturnType, cx.ArgumentTypes + | _ -> None, [] + + // prepare message parts (known arguments, known return type, known generic parameters) + let argsMessage, returnType, genericParametersMessage = + + let retTy = + knownReturnType + |> Option.defaultValue (TType.TType_var (Typar.NewUnlinked())) + + let argRepr = + callerArgs.ArgumentNamesAndTypes + |> List.map (fun (name,tTy) -> tTy, {ArgReprInfo.Name = name |> Option.map (fun name -> Ident(name, range.Zero)); ArgReprInfo.Attribs = []}) + + let argsL,retTyL,genParamTysL = NicePrint.prettyLayoutsOfUnresolvedOverloading denv argRepr retTy genericParameterTypes + + match callerArgs.ArgumentNamesAndTypes with + | [] -> None, LayoutRender.showL retTyL, LayoutRender.showL genParamTysL + | items -> + let args = LayoutRender.showL argsL + let prefixMessage = + match items with + | [_] -> FSComp.SR.csNoOverloadsFoundArgumentsPrefixSingular + | _ -> FSComp.SR.csNoOverloadsFoundArgumentsPrefixPlural + Some (prefixMessage args) + , LayoutRender.showL retTyL + , LayoutRender.showL genParamTysL + + let knownReturnType = + match knownReturnType with + | None -> None + | Some _ -> Some (FSComp.SR.csNoOverloadsFoundReturnType returnType) + + let genericParametersMessage = + match genericParameterTypes with + | [] -> None + | [_] -> Some (FSComp.SR.csNoOverloadsFoundTypeParametersPrefixSingular genericParametersMessage) + | _ -> Some (FSComp.SR.csNoOverloadsFoundTypeParametersPrefixPlural genericParametersMessage) + + let overloadMethodInfo displayEnv m (x: OverloadInformation) = + let paramInfo = + match x.error with + | :? ArgDoesNotMatchError as x -> + let nameOrOneBasedIndexMessage = + x.calledArg.NameOpt + |> Option.map (fun n -> FSComp.SR.csOverloadCandidateNamedArgumentTypeMismatch n.idText) + |> Option.defaultValue (FSComp.SR.csOverloadCandidateIndexedArgumentTypeMismatch ((vsnd x.calledArg.Position) + 1)) //snd + sprintf " // %s" nameOrOneBasedIndexMessage + | _ -> "" + + (NicePrint.stringOfMethInfo x.infoReader m displayEnv x.methodSlot.Method) + paramInfo + + let nl = Environment.NewLine + let formatOverloads (overloads: OverloadInformation list) = + overloads + |> List.map (overloadMethodInfo denv m) + |> List.sort + |> List.map FSComp.SR.formatDashItem + |> String.concat nl + + // assemble final message composing the parts + let msg = + let optionalParts = + [knownReturnType; genericParametersMessage; argsMessage] + |> List.choose id + |> String.concat (nl + nl) + |> function | "" -> nl + | result -> nl + nl + result + nl + nl + + match failure with + | NoOverloadsFound (methodName, overloads, _) -> + FSComp.SR.csNoOverloadsFound methodName + + optionalParts + + (FSComp.SR.csAvailableOverloads (formatOverloads overloads)) + | PossibleCandidates (methodName, [], _) -> + FSComp.SR.csMethodIsOverloaded methodName + | PossibleCandidates (methodName, overloads, _) -> + FSComp.SR.csMethodIsOverloaded methodName + + optionalParts + + FSComp.SR.csCandidates (formatOverloads overloads) + + os.Append msg |> ignore + + | UnresolvedConversionOperator(denv, fromTy, toTy, _) -> + let t1, t2, _tpcs = NicePrint.minimalStringsOfTwoTypes denv fromTy toTy + os.Append(FSComp.SR.csTypeDoesNotSupportConversion(t1, t2)) |> ignore + + | FunctionExpected _ -> + os.Append(FunctionExpectedE().Format) |> ignore + + | BakedInMemberConstraintName(nm, _) -> + os.Append(BakedInMemberConstraintNameE().Format nm) |> ignore + + | StandardOperatorRedefinitionWarning(msg, _) -> + os.Append msg |> ignore + + | BadEventTransformation _ -> + os.Append(BadEventTransformationE().Format) |> ignore + + | ParameterlessStructCtor _ -> + os.Append(ParameterlessStructCtorE().Format) |> ignore + + | InterfaceNotRevealed(denv, ity, _) -> + os.Append(InterfaceNotRevealedE().Format (NicePrint.minimalStringOfType denv ity)) |> ignore + + | NotAFunctionButIndexer(_, _, name, _, _, old) -> + if old then + match name with + | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName name) |> ignore + | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer()) |> ignore + else + match name with + | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName2 name) |> ignore + | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer2()) |> ignore + + | NotAFunction(_, _, _, marg) -> + if marg.StartColumn = 0 then + os.Append(FSComp.SR.notAFunctionButMaybeDeclaration()) |> ignore + else + os.Append(FSComp.SR.notAFunction()) |> ignore + + | TyconBadArgs(_, tcref, d, _) -> + let exp = tcref.TyparsNoRange.Length + if exp = 0 then + os.Append(FSComp.SR.buildUnexpectedTypeArgs(fullDisplayTextOfTyconRef tcref, d)) |> ignore + else + os.Append(TyconBadArgsE().Format (fullDisplayTextOfTyconRef tcref) exp d) |> ignore + + | IndeterminateType _ -> + os.Append(IndeterminateTypeE().Format) |> ignore + + | NameClash(nm, k1, nm1, _, k2, nm2, _) -> + if nm = nm1 && nm1 = nm2 && k1 = k2 then + os.Append(NameClash1E().Format k1 nm1) |> ignore + else + os.Append(NameClash2E().Format k1 nm1 nm k2 nm2) |> ignore + + | Duplicate(k, s, _) -> + if k = "member" then + os.Append(Duplicate1E().Format (DecompileOpName s)) |> ignore + else + os.Append(Duplicate2E().Format k (DecompileOpName s)) |> ignore + + | UndefinedName(_, k, id, suggestionsF) -> + os.Append(k (DecompileOpName id.idText)) |> ignore + suggestNames suggestionsF id.idText + + | InternalUndefinedItemRef(f, smr, ccuName, s) -> + let _, errs = f(smr, ccuName, s) + os.Append errs |> ignore + + | FieldNotMutable _ -> + os.Append(FieldNotMutableE().Format) |> ignore + + | FieldsFromDifferentTypes (_, fref1, fref2, _) -> + os.Append(FieldsFromDifferentTypesE().Format fref1.FieldName fref2.FieldName) |> ignore + + | VarBoundTwice id -> + os.Append(VarBoundTwiceE().Format (DecompileOpName id.idText)) |> ignore + + | Recursion (denv, id, ty1, ty2, _) -> + let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(RecursionE().Format (DecompileOpName id.idText) t1 t2 tpcs) |> ignore + + | InvalidRuntimeCoercion(denv, ty1, ty2, _) -> + let t1, t2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(InvalidRuntimeCoercionE().Format t1 t2 tpcs) |> ignore + + | IndeterminateRuntimeCoercion(denv, ty1, ty2, _) -> + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(IndeterminateRuntimeCoercionE().Format t1 t2) |> ignore + + | IndeterminateStaticCoercion(denv, ty1, ty2, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(IndeterminateStaticCoercionE().Format t1 t2) |> ignore + + | StaticCoercionShouldUseBox(denv, ty1, ty2, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(StaticCoercionShouldUseBoxE().Format t1 t2) |> ignore + + | TypeIsImplicitlyAbstract _ -> + os.Append(TypeIsImplicitlyAbstractE().Format) |> ignore + + | NonRigidTypar(denv, tpnmOpt, typarRange, ty1, ty, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let (ty1, ty), _cxs = PrettyTypes.PrettifyTypePair denv.g (ty1, ty) + match tpnmOpt with + | None -> + os.Append(NonRigidTypar1E().Format (stringOfRange typarRange) (NicePrint.stringOfTy denv ty)) |> ignore + | Some tpnm -> + match ty1 with + | TType_measure _ -> + os.Append(NonRigidTypar2E().Format tpnm (NicePrint.stringOfTy denv ty)) |> ignore + | _ -> + os.Append(NonRigidTypar3E().Format tpnm (NicePrint.stringOfTy denv ty)) |> ignore + + | SyntaxError (ctxt, _) -> + let ctxt = unbox>(ctxt) + + let (|EndOfStructuredConstructToken|_|) token = + match token with + | Parser.TOKEN_ODECLEND + | Parser.TOKEN_OBLOCKSEP + | Parser.TOKEN_OEND + | Parser.TOKEN_ORIGHT_BLOCK_END + | Parser.TOKEN_OBLOCKEND | Parser.TOKEN_OBLOCKEND_COMING_SOON | Parser.TOKEN_OBLOCKEND_IS_HERE -> Some() + | _ -> None + + let tokenIdToText tid = + match tid with + | Parser.TOKEN_IDENT -> getErrorString("Parser.TOKEN.IDENT") + | Parser.TOKEN_BIGNUM + | Parser.TOKEN_INT8 + | Parser.TOKEN_UINT8 + | Parser.TOKEN_INT16 + | Parser.TOKEN_UINT16 + | Parser.TOKEN_INT32 + | Parser.TOKEN_UINT32 + | Parser.TOKEN_INT64 + | Parser.TOKEN_UINT64 + | Parser.TOKEN_UNATIVEINT + | Parser.TOKEN_NATIVEINT -> getErrorString("Parser.TOKEN.INT") + | Parser.TOKEN_IEEE32 + | Parser.TOKEN_IEEE64 -> getErrorString("Parser.TOKEN.FLOAT") + | Parser.TOKEN_DECIMAL -> getErrorString("Parser.TOKEN.DECIMAL") + | Parser.TOKEN_CHAR -> getErrorString("Parser.TOKEN.CHAR") + + | Parser.TOKEN_BASE -> getErrorString("Parser.TOKEN.BASE") + | Parser.TOKEN_LPAREN_STAR_RPAREN -> getErrorString("Parser.TOKEN.LPAREN.STAR.RPAREN") + | Parser.TOKEN_DOLLAR -> getErrorString("Parser.TOKEN.DOLLAR") + | Parser.TOKEN_INFIX_STAR_STAR_OP -> getErrorString("Parser.TOKEN.INFIX.STAR.STAR.OP") + | Parser.TOKEN_INFIX_COMPARE_OP -> getErrorString("Parser.TOKEN.INFIX.COMPARE.OP") + | Parser.TOKEN_COLON_GREATER -> getErrorString("Parser.TOKEN.COLON.GREATER") + | Parser.TOKEN_COLON_COLON ->getErrorString("Parser.TOKEN.COLON.COLON") + | Parser.TOKEN_PERCENT_OP -> getErrorString("Parser.TOKEN.PERCENT.OP") + | Parser.TOKEN_INFIX_AT_HAT_OP -> getErrorString("Parser.TOKEN.INFIX.AT.HAT.OP") + | Parser.TOKEN_INFIX_BAR_OP -> getErrorString("Parser.TOKEN.INFIX.BAR.OP") + | Parser.TOKEN_PLUS_MINUS_OP -> getErrorString("Parser.TOKEN.PLUS.MINUS.OP") + | Parser.TOKEN_PREFIX_OP -> getErrorString("Parser.TOKEN.PREFIX.OP") + | Parser.TOKEN_COLON_QMARK_GREATER -> getErrorString("Parser.TOKEN.COLON.QMARK.GREATER") + | Parser.TOKEN_INFIX_STAR_DIV_MOD_OP -> getErrorString("Parser.TOKEN.INFIX.STAR.DIV.MOD.OP") + | Parser.TOKEN_INFIX_AMP_OP -> getErrorString("Parser.TOKEN.INFIX.AMP.OP") + | Parser.TOKEN_AMP -> getErrorString("Parser.TOKEN.AMP") + | Parser.TOKEN_AMP_AMP -> getErrorString("Parser.TOKEN.AMP.AMP") + | Parser.TOKEN_BAR_BAR -> getErrorString("Parser.TOKEN.BAR.BAR") + | Parser.TOKEN_LESS -> getErrorString("Parser.TOKEN.LESS") + | Parser.TOKEN_GREATER -> getErrorString("Parser.TOKEN.GREATER") + | Parser.TOKEN_QMARK -> getErrorString("Parser.TOKEN.QMARK") + | Parser.TOKEN_QMARK_QMARK -> getErrorString("Parser.TOKEN.QMARK.QMARK") + | Parser.TOKEN_COLON_QMARK-> getErrorString("Parser.TOKEN.COLON.QMARK") + | Parser.TOKEN_INT32_DOT_DOT -> getErrorString("Parser.TOKEN.INT32.DOT.DOT") + | Parser.TOKEN_DOT_DOT -> getErrorString("Parser.TOKEN.DOT.DOT") + | Parser.TOKEN_DOT_DOT_HAT -> getErrorString("Parser.TOKEN.DOT.DOT") + | Parser.TOKEN_QUOTE -> getErrorString("Parser.TOKEN.QUOTE") + | Parser.TOKEN_STAR -> getErrorString("Parser.TOKEN.STAR") + | Parser.TOKEN_HIGH_PRECEDENCE_TYAPP -> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.TYAPP") + | Parser.TOKEN_COLON -> getErrorString("Parser.TOKEN.COLON") + | Parser.TOKEN_COLON_EQUALS -> getErrorString("Parser.TOKEN.COLON.EQUALS") + | Parser.TOKEN_LARROW -> getErrorString("Parser.TOKEN.LARROW") + | Parser.TOKEN_EQUALS -> getErrorString("Parser.TOKEN.EQUALS") + | Parser.TOKEN_GREATER_BAR_RBRACK -> getErrorString("Parser.TOKEN.GREATER.BAR.RBRACK") + | Parser.TOKEN_MINUS -> getErrorString("Parser.TOKEN.MINUS") + | Parser.TOKEN_ADJACENT_PREFIX_OP -> getErrorString("Parser.TOKEN.ADJACENT.PREFIX.OP") + | Parser.TOKEN_FUNKY_OPERATOR_NAME -> getErrorString("Parser.TOKEN.FUNKY.OPERATOR.NAME") + | Parser.TOKEN_COMMA-> getErrorString("Parser.TOKEN.COMMA") + | Parser.TOKEN_DOT -> getErrorString("Parser.TOKEN.DOT") + | Parser.TOKEN_BAR-> getErrorString("Parser.TOKEN.BAR") + | Parser.TOKEN_HASH -> getErrorString("Parser.TOKEN.HASH") + | Parser.TOKEN_UNDERSCORE -> getErrorString("Parser.TOKEN.UNDERSCORE") + | Parser.TOKEN_SEMICOLON -> getErrorString("Parser.TOKEN.SEMICOLON") + | Parser.TOKEN_SEMICOLON_SEMICOLON-> getErrorString("Parser.TOKEN.SEMICOLON.SEMICOLON") + | Parser.TOKEN_LPAREN-> getErrorString("Parser.TOKEN.LPAREN") + | Parser.TOKEN_RPAREN | Parser.TOKEN_RPAREN_COMING_SOON | Parser.TOKEN_RPAREN_IS_HERE -> getErrorString("Parser.TOKEN.RPAREN") + | Parser.TOKEN_LQUOTE -> getErrorString("Parser.TOKEN.LQUOTE") + | Parser.TOKEN_LBRACK -> getErrorString("Parser.TOKEN.LBRACK") + | Parser.TOKEN_LBRACE_BAR -> getErrorString("Parser.TOKEN.LBRACE.BAR") + | Parser.TOKEN_LBRACK_BAR -> getErrorString("Parser.TOKEN.LBRACK.BAR") + | Parser.TOKEN_LBRACK_LESS -> getErrorString("Parser.TOKEN.LBRACK.LESS") + | Parser.TOKEN_LBRACE -> getErrorString("Parser.TOKEN.LBRACE") + | Parser.TOKEN_BAR_RBRACK -> getErrorString("Parser.TOKEN.BAR.RBRACK") + | Parser.TOKEN_BAR_RBRACE -> getErrorString("Parser.TOKEN.BAR.RBRACE") + | Parser.TOKEN_GREATER_RBRACK -> getErrorString("Parser.TOKEN.GREATER.RBRACK") + | Parser.TOKEN_RQUOTE_DOT _ + | Parser.TOKEN_RQUOTE -> getErrorString("Parser.TOKEN.RQUOTE") + | Parser.TOKEN_RBRACK -> getErrorString("Parser.TOKEN.RBRACK") + | Parser.TOKEN_RBRACE | Parser.TOKEN_RBRACE_COMING_SOON | Parser.TOKEN_RBRACE_IS_HERE -> getErrorString("Parser.TOKEN.RBRACE") + | Parser.TOKEN_PUBLIC -> getErrorString("Parser.TOKEN.PUBLIC") + | Parser.TOKEN_PRIVATE -> getErrorString("Parser.TOKEN.PRIVATE") + | Parser.TOKEN_INTERNAL -> getErrorString("Parser.TOKEN.INTERNAL") + | Parser.TOKEN_CONSTRAINT -> getErrorString("Parser.TOKEN.CONSTRAINT") + | Parser.TOKEN_INSTANCE -> getErrorString("Parser.TOKEN.INSTANCE") + | Parser.TOKEN_DELEGATE -> getErrorString("Parser.TOKEN.DELEGATE") + | Parser.TOKEN_INHERIT -> getErrorString("Parser.TOKEN.INHERIT") + | Parser.TOKEN_CONSTRUCTOR-> getErrorString("Parser.TOKEN.CONSTRUCTOR") + | Parser.TOKEN_DEFAULT -> getErrorString("Parser.TOKEN.DEFAULT") + | Parser.TOKEN_OVERRIDE-> getErrorString("Parser.TOKEN.OVERRIDE") + | Parser.TOKEN_ABSTRACT-> getErrorString("Parser.TOKEN.ABSTRACT") + | Parser.TOKEN_CLASS-> getErrorString("Parser.TOKEN.CLASS") + | Parser.TOKEN_MEMBER -> getErrorString("Parser.TOKEN.MEMBER") + | Parser.TOKEN_STATIC -> getErrorString("Parser.TOKEN.STATIC") + | Parser.TOKEN_NAMESPACE-> getErrorString("Parser.TOKEN.NAMESPACE") + | Parser.TOKEN_OBLOCKBEGIN -> getErrorString("Parser.TOKEN.OBLOCKBEGIN") + | EndOfStructuredConstructToken -> getErrorString("Parser.TOKEN.OBLOCKEND") + | Parser.TOKEN_THEN + | Parser.TOKEN_OTHEN -> getErrorString("Parser.TOKEN.OTHEN") + | Parser.TOKEN_ELSE + | Parser.TOKEN_OELSE -> getErrorString("Parser.TOKEN.OELSE") + | Parser.TOKEN_LET _ + | Parser.TOKEN_OLET _ -> getErrorString("Parser.TOKEN.OLET") + | Parser.TOKEN_OBINDER + | Parser.TOKEN_BINDER -> getErrorString("Parser.TOKEN.BINDER") + | Parser.TOKEN_OAND_BANG + | Parser.TOKEN_AND_BANG -> getErrorString("Parser.TOKEN.AND.BANG") + | Parser.TOKEN_ODO -> getErrorString("Parser.TOKEN.ODO") + | Parser.TOKEN_OWITH -> getErrorString("Parser.TOKEN.OWITH") + | Parser.TOKEN_OFUNCTION -> getErrorString("Parser.TOKEN.OFUNCTION") + | Parser.TOKEN_OFUN -> getErrorString("Parser.TOKEN.OFUN") + | Parser.TOKEN_ORESET -> getErrorString("Parser.TOKEN.ORESET") + | Parser.TOKEN_ODUMMY -> getErrorString("Parser.TOKEN.ODUMMY") + | Parser.TOKEN_DO_BANG + | Parser.TOKEN_ODO_BANG -> getErrorString("Parser.TOKEN.ODO.BANG") + | Parser.TOKEN_YIELD -> getErrorString("Parser.TOKEN.YIELD") + | Parser.TOKEN_YIELD_BANG -> getErrorString("Parser.TOKEN.YIELD.BANG") + | Parser.TOKEN_OINTERFACE_MEMBER-> getErrorString("Parser.TOKEN.OINTERFACE.MEMBER") + | Parser.TOKEN_ELIF -> getErrorString("Parser.TOKEN.ELIF") + | Parser.TOKEN_RARROW -> getErrorString("Parser.TOKEN.RARROW") + | Parser.TOKEN_SIG -> getErrorString("Parser.TOKEN.SIG") + | Parser.TOKEN_STRUCT -> getErrorString("Parser.TOKEN.STRUCT") + | Parser.TOKEN_UPCAST -> getErrorString("Parser.TOKEN.UPCAST") + | Parser.TOKEN_DOWNCAST -> getErrorString("Parser.TOKEN.DOWNCAST") + | Parser.TOKEN_NULL -> getErrorString("Parser.TOKEN.NULL") + | Parser.TOKEN_RESERVED -> getErrorString("Parser.TOKEN.RESERVED") + | Parser.TOKEN_MODULE | Parser.TOKEN_MODULE_COMING_SOON | Parser.TOKEN_MODULE_IS_HERE -> getErrorString("Parser.TOKEN.MODULE") + | Parser.TOKEN_AND -> getErrorString("Parser.TOKEN.AND") + | Parser.TOKEN_AS -> getErrorString("Parser.TOKEN.AS") + | Parser.TOKEN_ASSERT -> getErrorString("Parser.TOKEN.ASSERT") + | Parser.TOKEN_OASSERT -> getErrorString("Parser.TOKEN.ASSERT") + | Parser.TOKEN_ASR-> getErrorString("Parser.TOKEN.ASR") + | Parser.TOKEN_DOWNTO -> getErrorString("Parser.TOKEN.DOWNTO") + | Parser.TOKEN_EXCEPTION -> getErrorString("Parser.TOKEN.EXCEPTION") + | Parser.TOKEN_FALSE -> getErrorString("Parser.TOKEN.FALSE") + | Parser.TOKEN_FOR -> getErrorString("Parser.TOKEN.FOR") + | Parser.TOKEN_FUN -> getErrorString("Parser.TOKEN.FUN") + | Parser.TOKEN_FUNCTION-> getErrorString("Parser.TOKEN.FUNCTION") + | Parser.TOKEN_FINALLY -> getErrorString("Parser.TOKEN.FINALLY") + | Parser.TOKEN_LAZY -> getErrorString("Parser.TOKEN.LAZY") + | Parser.TOKEN_OLAZY -> getErrorString("Parser.TOKEN.LAZY") + | Parser.TOKEN_MATCH -> getErrorString("Parser.TOKEN.MATCH") + | Parser.TOKEN_MATCH_BANG -> getErrorString("Parser.TOKEN.MATCH.BANG") + | Parser.TOKEN_MUTABLE -> getErrorString("Parser.TOKEN.MUTABLE") + | Parser.TOKEN_NEW -> getErrorString("Parser.TOKEN.NEW") + | Parser.TOKEN_OF -> getErrorString("Parser.TOKEN.OF") + | Parser.TOKEN_OPEN -> getErrorString("Parser.TOKEN.OPEN") + | Parser.TOKEN_OR -> getErrorString("Parser.TOKEN.OR") + | Parser.TOKEN_VOID -> getErrorString("Parser.TOKEN.VOID") + | Parser.TOKEN_EXTERN-> getErrorString("Parser.TOKEN.EXTERN") + | Parser.TOKEN_INTERFACE -> getErrorString("Parser.TOKEN.INTERFACE") + | Parser.TOKEN_REC -> getErrorString("Parser.TOKEN.REC") + | Parser.TOKEN_TO -> getErrorString("Parser.TOKEN.TO") + | Parser.TOKEN_TRUE -> getErrorString("Parser.TOKEN.TRUE") + | Parser.TOKEN_TRY -> getErrorString("Parser.TOKEN.TRY") + | Parser.TOKEN_TYPE | Parser.TOKEN_TYPE_COMING_SOON | Parser.TOKEN_TYPE_IS_HERE -> getErrorString("Parser.TOKEN.TYPE") + | Parser.TOKEN_VAL -> getErrorString("Parser.TOKEN.VAL") + | Parser.TOKEN_INLINE -> getErrorString("Parser.TOKEN.INLINE") + | Parser.TOKEN_WHEN -> getErrorString("Parser.TOKEN.WHEN") + | Parser.TOKEN_WHILE -> getErrorString("Parser.TOKEN.WHILE") + | Parser.TOKEN_WITH-> getErrorString("Parser.TOKEN.WITH") + | Parser.TOKEN_IF -> getErrorString("Parser.TOKEN.IF") + | Parser.TOKEN_DO -> getErrorString("Parser.TOKEN.DO") + | Parser.TOKEN_GLOBAL -> getErrorString("Parser.TOKEN.GLOBAL") + | Parser.TOKEN_DONE -> getErrorString("Parser.TOKEN.DONE") + | Parser.TOKEN_IN | Parser.TOKEN_JOIN_IN -> getErrorString("Parser.TOKEN.IN") + | Parser.TOKEN_HIGH_PRECEDENCE_PAREN_APP-> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.PAREN.APP") + | Parser.TOKEN_HIGH_PRECEDENCE_BRACK_APP-> getErrorString("Parser.TOKEN.HIGH.PRECEDENCE.BRACK.APP") + | Parser.TOKEN_BEGIN -> getErrorString("Parser.TOKEN.BEGIN") + | Parser.TOKEN_END -> getErrorString("Parser.TOKEN.END") + | Parser.TOKEN_HASH_LIGHT + | Parser.TOKEN_HASH_LINE + | Parser.TOKEN_HASH_IF + | Parser.TOKEN_HASH_ELSE + | Parser.TOKEN_HASH_ENDIF -> getErrorString("Parser.TOKEN.HASH.ENDIF") + | Parser.TOKEN_INACTIVECODE -> getErrorString("Parser.TOKEN.INACTIVECODE") + | Parser.TOKEN_LEX_FAILURE-> getErrorString("Parser.TOKEN.LEX.FAILURE") + | Parser.TOKEN_WHITESPACE -> getErrorString("Parser.TOKEN.WHITESPACE") + | Parser.TOKEN_COMMENT -> getErrorString("Parser.TOKEN.COMMENT") + | Parser.TOKEN_LINE_COMMENT -> getErrorString("Parser.TOKEN.LINE.COMMENT") + | Parser.TOKEN_STRING_TEXT -> getErrorString("Parser.TOKEN.STRING.TEXT") + | Parser.TOKEN_BYTEARRAY -> getErrorString("Parser.TOKEN.BYTEARRAY") + | Parser.TOKEN_STRING -> getErrorString("Parser.TOKEN.STRING") + | Parser.TOKEN_KEYWORD_STRING -> getErrorString("Parser.TOKEN.KEYWORD_STRING") + | Parser.TOKEN_EOF -> getErrorString("Parser.TOKEN.EOF") + | Parser.TOKEN_CONST -> getErrorString("Parser.TOKEN.CONST") + | Parser.TOKEN_FIXED -> getErrorString("Parser.TOKEN.FIXED") + | Parser.TOKEN_INTERP_STRING_BEGIN_END -> getErrorString("Parser.TOKEN.INTERP.STRING.BEGIN.END") + | Parser.TOKEN_INTERP_STRING_BEGIN_PART -> getErrorString("Parser.TOKEN.INTERP.STRING.BEGIN.PART") + | Parser.TOKEN_INTERP_STRING_PART -> getErrorString("Parser.TOKEN.INTERP.STRING.PART") + | Parser.TOKEN_INTERP_STRING_END -> getErrorString("Parser.TOKEN.INTERP.STRING.END") + | unknown -> + Debug.Assert(false, "unknown token tag") + let result = sprintf "%+A" unknown + Debug.Assert(false, result) + result + +#if DEBUG + if showParserStackOnParseError then + printfn "parser stack:" + for rps in ctxt.ReducibleProductions do + printfn " ----" + //printfn " state %d" state + for rp in rps do + printfn " non-terminal %+A (idx %d): ... " (Parser.prodIdxToNonTerminal rp) rp +#endif + + match ctxt.CurrentToken with + | None -> os.Append(UnexpectedEndOfInputE().Format) |> ignore + | Some token -> + match (token |> Parser.tagOfToken |> Parser.tokenTagToTokenId), token with + | EndOfStructuredConstructToken, _ -> os.Append(OBlockEndSentenceE().Format) |> ignore + | Parser.TOKEN_LEX_FAILURE, Parser.LEX_FAILURE str -> Printf.bprintf os "%s" str (* Fix bug://2431 *) + | token, _ -> os.Append(UnexpectedE().Format (token |> tokenIdToText)) |> ignore + + (* Search for a state producing a single recognized non-terminal in the states on the stack *) + let foundInContext = + + (* Merge a bunch of expression non terminals *) + let (|NONTERM_Category_Expr|_|) = function + | Parser.NONTERM_argExpr|Parser.NONTERM_minusExpr|Parser.NONTERM_parenExpr|Parser.NONTERM_atomicExpr + | Parser.NONTERM_appExpr|Parser.NONTERM_tupleExpr|Parser.NONTERM_declExpr|Parser.NONTERM_braceExpr|Parser.NONTERM_braceBarExpr + | Parser.NONTERM_typedSequentialExprBlock + | Parser.NONTERM_interactiveExpr -> Some() + | _ -> None + + (* Merge a bunch of pattern non terminals *) + let (|NONTERM_Category_Pattern|_|) = function + | Parser.NONTERM_constrPattern|Parser.NONTERM_parenPattern|Parser.NONTERM_atomicPattern -> Some() + | _ -> None + + (* Merge a bunch of if/then/else non terminals *) + let (|NONTERM_Category_IfThenElse|_|) = function + | Parser.NONTERM_ifExprThen|Parser.NONTERM_ifExprElifs|Parser.NONTERM_ifExprCases -> Some() + | _ -> None + + (* Merge a bunch of non terminals *) + let (|NONTERM_Category_SignatureFile|_|) = function + | Parser.NONTERM_signatureFile|Parser.NONTERM_moduleSpfn|Parser.NONTERM_moduleSpfns -> Some() + | _ -> None + let (|NONTERM_Category_ImplementationFile|_|) = function + | Parser.NONTERM_implementationFile|Parser.NONTERM_fileNamespaceImpl|Parser.NONTERM_fileNamespaceImpls -> Some() + | _ -> None + let (|NONTERM_Category_Definition|_|) = function + | Parser.NONTERM_fileModuleImpl|Parser.NONTERM_moduleDefn|Parser.NONTERM_interactiveDefns + |Parser.NONTERM_moduleDefns|Parser.NONTERM_moduleDefnsOrExpr -> Some() + | _ -> None + + let (|NONTERM_Category_Type|_|) = function + | Parser.NONTERM_typ|Parser.NONTERM_tupleType -> Some() + | _ -> None + + let (|NONTERM_Category_Interaction|_|) = function + | Parser.NONTERM_interactiveItemsTerminator|Parser.NONTERM_interaction|Parser.NONTERM__startinteraction -> Some() + | _ -> None + + + // Canonicalize the categories and check for a unique category + ctxt.ReducibleProductions |> List.exists (fun prods -> + match prods + |> List.map Parser.prodIdxToNonTerminal + |> List.map (function + | NONTERM_Category_Type -> Parser.NONTERM_typ + | NONTERM_Category_Expr -> Parser.NONTERM_declExpr + | NONTERM_Category_Pattern -> Parser.NONTERM_atomicPattern + | NONTERM_Category_IfThenElse -> Parser.NONTERM_ifExprThen + | NONTERM_Category_SignatureFile -> Parser.NONTERM_signatureFile + | NONTERM_Category_ImplementationFile -> Parser.NONTERM_implementationFile + | NONTERM_Category_Definition -> Parser.NONTERM_moduleDefn + | NONTERM_Category_Interaction -> Parser.NONTERM_interaction + | nt -> nt) + |> Set.ofList + |> Set.toList with + | [Parser.NONTERM_interaction] -> os.Append(NONTERM_interactionE().Format) |> ignore; true + | [Parser.NONTERM_hashDirective] -> os.Append(NONTERM_hashDirectiveE().Format) |> ignore; true + | [Parser.NONTERM_fieldDecl] -> os.Append(NONTERM_fieldDeclE().Format) |> ignore; true + | [Parser.NONTERM_unionCaseRepr] -> os.Append(NONTERM_unionCaseReprE().Format) |> ignore; true + | [Parser.NONTERM_localBinding] -> os.Append(NONTERM_localBindingE().Format) |> ignore; true + | [Parser.NONTERM_hardwhiteLetBindings] -> os.Append(NONTERM_hardwhiteLetBindingsE().Format) |> ignore; true + | [Parser.NONTERM_classDefnMember] -> os.Append(NONTERM_classDefnMemberE().Format) |> ignore; true + | [Parser.NONTERM_defnBindings] -> os.Append(NONTERM_defnBindingsE().Format) |> ignore; true + | [Parser.NONTERM_classMemberSpfn] -> os.Append(NONTERM_classMemberSpfnE().Format) |> ignore; true + | [Parser.NONTERM_valSpfn] -> os.Append(NONTERM_valSpfnE().Format) |> ignore; true + | [Parser.NONTERM_tyconSpfn] -> os.Append(NONTERM_tyconSpfnE().Format) |> ignore; true + | [Parser.NONTERM_anonLambdaExpr] -> os.Append(NONTERM_anonLambdaExprE().Format) |> ignore; true + | [Parser.NONTERM_attrUnionCaseDecl] -> os.Append(NONTERM_attrUnionCaseDeclE().Format) |> ignore; true + | [Parser.NONTERM_cPrototype] -> os.Append(NONTERM_cPrototypeE().Format) |> ignore; true + | [Parser.NONTERM_objExpr|Parser.NONTERM_objectImplementationMembers] -> os.Append(NONTERM_objectImplementationMembersE().Format) |> ignore; true + | [Parser.NONTERM_ifExprThen|Parser.NONTERM_ifExprElifs|Parser.NONTERM_ifExprCases] -> os.Append(NONTERM_ifExprCasesE().Format) |> ignore; true + | [Parser.NONTERM_openDecl] -> os.Append(NONTERM_openDeclE().Format) |> ignore; true + | [Parser.NONTERM_fileModuleSpec] -> os.Append(NONTERM_fileModuleSpecE().Format) |> ignore; true + | [Parser.NONTERM_patternClauses] -> os.Append(NONTERM_patternClausesE().Format) |> ignore; true + | [Parser.NONTERM_beginEndExpr] -> os.Append(NONTERM_beginEndExprE().Format) |> ignore; true + | [Parser.NONTERM_recdExpr] -> os.Append(NONTERM_recdExprE().Format) |> ignore; true + | [Parser.NONTERM_tyconDefn] -> os.Append(NONTERM_tyconDefnE().Format) |> ignore; true + | [Parser.NONTERM_exconCore] -> os.Append(NONTERM_exconCoreE().Format) |> ignore; true + | [Parser.NONTERM_typeNameInfo] -> os.Append(NONTERM_typeNameInfoE().Format) |> ignore; true + | [Parser.NONTERM_attributeList] -> os.Append(NONTERM_attributeListE().Format) |> ignore; true + | [Parser.NONTERM_quoteExpr] -> os.Append(NONTERM_quoteExprE().Format) |> ignore; true + | [Parser.NONTERM_typeConstraint] -> os.Append(NONTERM_typeConstraintE().Format) |> ignore; true + | [NONTERM_Category_ImplementationFile] -> os.Append(NONTERM_Category_ImplementationFileE().Format) |> ignore; true + | [NONTERM_Category_Definition] -> os.Append(NONTERM_Category_DefinitionE().Format) |> ignore; true + | [NONTERM_Category_SignatureFile] -> os.Append(NONTERM_Category_SignatureFileE().Format) |> ignore; true + | [NONTERM_Category_Pattern] -> os.Append(NONTERM_Category_PatternE().Format) |> ignore; true + | [NONTERM_Category_Expr] -> os.Append(NONTERM_Category_ExprE().Format) |> ignore; true + | [NONTERM_Category_Type] -> os.Append(NONTERM_Category_TypeE().Format) |> ignore; true + | [Parser.NONTERM_typeArgsActual] -> os.Append(NONTERM_typeArgsActualE().Format) |> ignore; true + | _ -> + false) + +#if DEBUG + if not foundInContext then + Printf.bprintf os ". (no 'in' context found: %+A)" (List.map (List.map Parser.prodIdxToNonTerminal) ctxt.ReducibleProductions) +#else + foundInContext |> ignore // suppress unused variable warning in RELEASE +#endif + let fix (s: string) = s.Replace(SR.GetString("FixKeyword"), "").Replace(SR.GetString("FixSymbol"), "").Replace(SR.GetString("FixReplace"), "") + match (ctxt.ShiftTokens + |> List.map Parser.tokenTagToTokenId + |> List.filter (function Parser.TOKEN_error | Parser.TOKEN_EOF -> false | _ -> true) + |> List.map tokenIdToText + |> Set.ofList + |> Set.toList) with + | [tokenName1] -> os.Append(TokenName1E().Format (fix tokenName1)) |> ignore + | [tokenName1;tokenName2] -> os.Append(TokenName1TokenName2E().Format (fix tokenName1) (fix tokenName2)) |> ignore + | [tokenName1;tokenName2;tokenName3] -> os.Append(TokenName1TokenName2TokenName3E().Format (fix tokenName1) (fix tokenName2) (fix tokenName3)) |> ignore + | _ -> () + (* + Printf.bprintf os ".\n\n state = %A\n token = %A\n expect (shift) %A\n expect (reduce) %A\n prods=%A\n non terminals: %A" + ctxt.StateStack + ctxt.CurrentToken + (List.map Parser.tokenTagToTokenId ctxt.ShiftTokens) + (List.map Parser.tokenTagToTokenId ctxt.ReduceTokens) + ctxt.ReducibleProductions + (List.mapSquared Parser.prodIdxToNonTerminal ctxt.ReducibleProductions) + *) + + | RuntimeCoercionSourceSealed(denv, ty, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + if isTyparTy denv.g ty + then os.Append(RuntimeCoercionSourceSealed1E().Format (NicePrint.stringOfTy denv ty)) |> ignore + else os.Append(RuntimeCoercionSourceSealed2E().Format (NicePrint.stringOfTy denv ty)) |> ignore + + | CoercionTargetSealed(denv, ty, _) -> + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let ty, _cxs= PrettyTypes.PrettifyType denv.g ty + os.Append(CoercionTargetSealedE().Format (NicePrint.stringOfTy denv ty)) |> ignore + + | UpcastUnnecessary _ -> + os.Append(UpcastUnnecessaryE().Format) |> ignore + + | TypeTestUnnecessary _ -> + os.Append(TypeTestUnnecessaryE().Format) |> ignore + + | QuotationTranslator.IgnoringPartOfQuotedTermWarning (msg, _) -> + Printf.bprintf os "%s" msg + + | OverrideDoesntOverride(denv, impl, minfoVirtOpt, g, amap, m) -> + let sig1 = DispatchSlotChecking.FormatOverride denv impl + match minfoVirtOpt with + | None -> + os.Append(OverrideDoesntOverride1E().Format sig1) |> ignore + | Some minfoVirt -> + // https://github.com/Microsoft/visualfsharp/issues/35 + // Improve error message when attempting to override generic return type with unit: + // we need to check if unit was used as a type argument + let rec hasUnitTType_app (types: TType list) = + match types with + | TType_app (maybeUnit, []) :: ts -> + match maybeUnit.TypeAbbrev with + | Some ttype when isUnitTy g ttype -> true + | _ -> hasUnitTType_app ts + | _ :: ts -> hasUnitTType_app ts + | [] -> false + + match minfoVirt.ApparentEnclosingType with + | TType_app (t, types) when t.IsFSharpInterfaceTycon && hasUnitTType_app types -> + // match abstract member with 'unit' passed as generic argument + os.Append(OverrideDoesntOverride4E().Format sig1) |> ignore + | _ -> + os.Append(OverrideDoesntOverride2E().Format sig1) |> ignore + let sig2 = DispatchSlotChecking.FormatMethInfoSig g amap m denv minfoVirt + if sig1 <> sig2 then + os.Append(OverrideDoesntOverride3E().Format sig2) |> ignore + + | UnionCaseWrongArguments (_, n1, n2, _) -> + os.Append(UnionCaseWrongArgumentsE().Format n2 n1) |> ignore + + | UnionPatternsBindDifferentNames _ -> + os.Append(UnionPatternsBindDifferentNamesE().Format) |> ignore + + | ValueNotContained (denv, infoReader, mref, implVal, sigVal, f) -> + let text1, text2 = NicePrint.minimalStringsOfTwoValues denv infoReader (mkLocalValRef implVal) (mkLocalValRef sigVal) + os.Append(f((fullDisplayTextOfModRef mref), text1, text2)) |> ignore + + | ConstrNotContained (denv, infoReader, enclosingTycon, v1, v2, f) -> + let enclosingTcref = mkLocalEntityRef enclosingTycon + os.Append(f((NicePrint.stringOfUnionCase denv infoReader enclosingTcref v1), (NicePrint.stringOfUnionCase denv infoReader enclosingTcref v2))) |> ignore + + | ExnconstrNotContained (denv, infoReader, v1, v2, f) -> + os.Append(f((NicePrint.stringOfExnDef denv infoReader (mkLocalEntityRef v1)), (NicePrint.stringOfExnDef denv infoReader (mkLocalEntityRef v2)))) |> ignore + + | FieldNotContained (denv, infoReader, enclosingTycon, v1, v2, f) -> + let enclosingTcref = mkLocalEntityRef enclosingTycon + os.Append(f((NicePrint.stringOfRecdField denv infoReader enclosingTcref v1), (NicePrint.stringOfRecdField denv infoReader enclosingTcref v2))) |> ignore + + | RequiredButNotSpecified (_, mref, k, name, _) -> + let nsb = StringBuilder() + name nsb; + os.Append(RequiredButNotSpecifiedE().Format (fullDisplayTextOfModRef mref) k (nsb.ToString())) |> ignore + + | UseOfAddressOfOperator _ -> + os.Append(UseOfAddressOfOperatorE().Format) |> ignore + + | DefensiveCopyWarning(s, _) -> os.Append(DefensiveCopyWarningE().Format s) |> ignore + + | DeprecatedThreadStaticBindingWarning _ -> + os.Append(DeprecatedThreadStaticBindingWarningE().Format) |> ignore + + | FunctionValueUnexpected (denv, ty, _) -> + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let errorText = FunctionValueUnexpectedE().Format (NicePrint.stringOfTy denv ty) + os.Append errorText |> ignore + + | UnitTypeExpected (denv, ty, _) -> + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let warningText = UnitTypeExpectedE().Format (NicePrint.stringOfTy denv ty) + os.Append warningText |> ignore + + | UnitTypeExpectedWithEquality (denv, ty, _) -> + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let warningText = UnitTypeExpectedWithEqualityE().Format (NicePrint.stringOfTy denv ty) + os.Append warningText |> ignore + + | UnitTypeExpectedWithPossiblePropertySetter (denv, ty, bindingName, propertyName, _) -> + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let warningText = UnitTypeExpectedWithPossiblePropertySetterE().Format (NicePrint.stringOfTy denv ty) bindingName propertyName + os.Append warningText |> ignore + + | UnitTypeExpectedWithPossibleAssignment (denv, ty, isAlreadyMutable, bindingName, _) -> + let ty, _cxs = PrettyTypes.PrettifyType denv.g ty + let warningText = + if isAlreadyMutable then + UnitTypeExpectedWithPossibleAssignmentToMutableE().Format (NicePrint.stringOfTy denv ty) bindingName + else + UnitTypeExpectedWithPossibleAssignmentE().Format (NicePrint.stringOfTy denv ty) bindingName + os.Append warningText |> ignore + + | RecursiveUseCheckedAtRuntime _ -> + os.Append(RecursiveUseCheckedAtRuntimeE().Format) |> ignore + + | LetRecUnsound (_, [v], _) -> + os.Append(LetRecUnsound1E().Format v.DisplayName) |> ignore + + | LetRecUnsound (_, path, _) -> + let bos = StringBuilder() + (path.Tail @ [path.Head]) |> List.iter (fun (v: ValRef) -> bos.Append(LetRecUnsoundInnerE().Format v.DisplayName) |> ignore) + os.Append(LetRecUnsound2E().Format (List.head path).DisplayName (bos.ToString())) |> ignore + + | LetRecEvaluatedOutOfOrder (_, _, _, _) -> + os.Append(LetRecEvaluatedOutOfOrderE().Format) |> ignore + + | LetRecCheckedAtRuntime _ -> + os.Append(LetRecCheckedAtRuntimeE().Format) |> ignore + + | SelfRefObjCtor(false, _) -> + os.Append(SelfRefObjCtor1E().Format) |> ignore + + | SelfRefObjCtor(true, _) -> + os.Append(SelfRefObjCtor2E().Format) |> ignore + + | VirtualAugmentationOnNullValuedType _ -> + os.Append(VirtualAugmentationOnNullValuedTypeE().Format) |> ignore + + | NonVirtualAugmentationOnNullValuedType _ -> + os.Append(NonVirtualAugmentationOnNullValuedTypeE().Format) |> ignore + + | NonUniqueInferredAbstractSlot(_, denv, bindnm, bvirt1, bvirt2, _) -> + os.Append(NonUniqueInferredAbstractSlot1E().Format bindnm) |> ignore + let ty1 = bvirt1.ApparentEnclosingType + let ty2 = bvirt2.ApparentEnclosingType + // REVIEW: consider if we need to show _cxs (the type parameter constraints) + let t1, t2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2 + os.Append(NonUniqueInferredAbstractSlot2E().Format) |> ignore + if t1 <> t2 then + os.Append(NonUniqueInferredAbstractSlot3E().Format t1 t2) |> ignore + os.Append(NonUniqueInferredAbstractSlot4E().Format) |> ignore + + | Error ((_, s), _) -> os.Append s |> ignore + + | ErrorWithSuggestions ((_, s), _, idText, suggestionF) -> + os.Append(DecompileOpName s) |> ignore + suggestNames suggestionF idText + + | InternalError (s, _) + + | InvalidArgument s + + | Failure s as exn -> + ignore exn // use the argument, even in non DEBUG + let f1 = SR.GetString("Failure1") + let f2 = SR.GetString("Failure2") + match s with + | f when f = f1 -> os.Append(Failure3E().Format s) |> ignore + | f when f = f2 -> os.Append(Failure3E().Format s) |> ignore + | _ -> os.Append(Failure4E().Format s) |> ignore +#if DEBUG + Printf.bprintf os "\nStack Trace\n%s\n" (exn.ToString()) + Debug.Assert(false, sprintf "Unexpected exception seen in compiler: %s\n%s" s (exn.ToString())) +#endif + + | WrappedError (exn, _) -> OutputExceptionR os exn + + | PatternMatchCompilation.MatchIncomplete (isComp, cexOpt, _) -> + os.Append(MatchIncomplete1E().Format) |> ignore + match cexOpt with + | None -> () + | Some (cex, false) -> os.Append(MatchIncomplete2E().Format cex) |> ignore + | Some (cex, true) -> os.Append(MatchIncomplete3E().Format cex) |> ignore + if isComp then + os.Append(MatchIncomplete4E().Format) |> ignore + + | PatternMatchCompilation.EnumMatchIncomplete (isComp, cexOpt, _) -> + os.Append(EnumMatchIncomplete1E().Format) |> ignore + match cexOpt with + | None -> () + | Some (cex, false) -> os.Append(MatchIncomplete2E().Format cex) |> ignore + | Some (cex, true) -> os.Append(MatchIncomplete3E().Format cex) |> ignore + if isComp then + os.Append(MatchIncomplete4E().Format) |> ignore + + | PatternMatchCompilation.RuleNeverMatched _ -> os.Append(RuleNeverMatchedE().Format) |> ignore + + | ValNotMutable(_, valRef, _) -> os.Append(ValNotMutableE().Format(valRef.DisplayName)) |> ignore + + | ValNotLocal _ -> os.Append(ValNotLocalE().Format) |> ignore + + | ObsoleteError (s, _) + + | ObsoleteWarning (s, _) -> + os.Append(Obsolete1E().Format) |> ignore + if s <> "" then os.Append(Obsolete2E().Format s) |> ignore + + | Experimental (s, _) -> os.Append(ExperimentalE().Format s) |> ignore + + | PossibleUnverifiableCode _ -> os.Append(PossibleUnverifiableCodeE().Format) |> ignore + + | UserCompilerMessage (msg, _, _) -> os.Append msg |> ignore + + | Deprecated(s, _) -> os.Append(DeprecatedE().Format s) |> ignore + + | LibraryUseOnly _ -> os.Append(LibraryUseOnlyE().Format) |> ignore + + | MissingFields(sl, _) -> os.Append(MissingFieldsE().Format (String.concat "," sl + ".")) |> ignore + + | ValueRestriction(denv, infoReader, hassig, v, _, _) -> + let denv = { denv with showImperativeTyparAnnotations=true } + let tau = v.TauType + if hassig then + if isFunTy denv.g tau && (arityOfVal v).HasNoArgs then + os.Append(ValueRestriction1E().Format + v.DisplayName + (NicePrint.stringOfQualifiedValOrMember denv infoReader (mkLocalValRef v)) + v.DisplayName) |> ignore + else + os.Append(ValueRestriction2E().Format + v.DisplayName + (NicePrint.stringOfQualifiedValOrMember denv infoReader (mkLocalValRef v)) + v.DisplayName) |> ignore + else + match v.MemberInfo with + | Some membInfo when + begin match membInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet + | SynMemberKind.Constructor -> true (* can't infer extra polymorphism *) + | _ -> false (* can infer extra polymorphism *) + end -> + os.Append(ValueRestriction3E().Format (NicePrint.stringOfQualifiedValOrMember denv infoReader (mkLocalValRef v))) |> ignore + | _ -> + if isFunTy denv.g tau && (arityOfVal v).HasNoArgs then + os.Append(ValueRestriction4E().Format + v.DisplayName + (NicePrint.stringOfQualifiedValOrMember denv infoReader (mkLocalValRef v)) + v.DisplayName) |> ignore + else + os.Append(ValueRestriction5E().Format + v.DisplayName + (NicePrint.stringOfQualifiedValOrMember denv infoReader (mkLocalValRef v)) + v.DisplayName) |> ignore + + + | Parsing.RecoverableParseError -> os.Append(RecoverableParseErrorE().Format) |> ignore + + | ReservedKeyword (s, _) -> os.Append(ReservedKeywordE().Format s) |> ignore + + | IndentationProblem (s, _) -> os.Append(IndentationProblemE().Format s) |> ignore + + | OverrideInIntrinsicAugmentation _ -> os.Append(OverrideInIntrinsicAugmentationE().Format) |> ignore + + | OverrideInExtrinsicAugmentation _ -> os.Append(OverrideInExtrinsicAugmentationE().Format) |> ignore + + | IntfImplInIntrinsicAugmentation _ -> os.Append(IntfImplInIntrinsicAugmentationE().Format) |> ignore + + | IntfImplInExtrinsicAugmentation _ -> os.Append(IntfImplInExtrinsicAugmentationE().Format) |> ignore + + | UnresolvedReferenceError(assemblyName, _) + + | UnresolvedReferenceNoRange assemblyName -> + os.Append(UnresolvedReferenceNoRangeE().Format assemblyName) |> ignore + + | UnresolvedPathReference(assemblyName, pathname, _) + + | UnresolvedPathReferenceNoRange(assemblyName, pathname) -> + os.Append(UnresolvedPathReferenceNoRangeE().Format pathname assemblyName) |> ignore + + | DeprecatedCommandLineOptionFull(fullText, _) -> + os.Append fullText |> ignore + + | DeprecatedCommandLineOptionForHtmlDoc(optionName, _) -> + os.Append(FSComp.SR.optsDCLOHtmlDoc optionName) |> ignore + + | DeprecatedCommandLineOptionSuggestAlternative(optionName, altOption, _) -> + os.Append(FSComp.SR.optsDCLODeprecatedSuggestAlternative(optionName, altOption)) |> ignore + + | InternalCommandLineOption(optionName, _) -> + os.Append(FSComp.SR.optsInternalNoDescription optionName) |> ignore + + | DeprecatedCommandLineOptionNoDescription(optionName, _) -> + os.Append(FSComp.SR.optsDCLONoDescription optionName) |> ignore + + | HashIncludeNotAllowedInNonScript _ -> + os.Append(HashIncludeNotAllowedInNonScriptE().Format) |> ignore + + | HashReferenceNotAllowedInNonScript _ -> + os.Append(HashReferenceNotAllowedInNonScriptE().Format) |> ignore + + | HashDirectiveNotAllowedInNonScript _ -> + os.Append(HashDirectiveNotAllowedInNonScriptE().Format) |> ignore + + | FileNameNotResolved(filename, locations, _) -> + os.Append(FileNameNotResolvedE().Format filename locations) |> ignore + + | AssemblyNotResolved(originalName, _) -> + os.Append(AssemblyNotResolvedE().Format originalName) |> ignore + + | IllegalFileNameChar(fileName, invalidChar) -> + os.Append(FSComp.SR.buildUnexpectedFileNameCharacter(fileName, string invalidChar)|>snd) |> ignore + + | HashLoadedSourceHasIssues(infos, warnings, errors, _) -> + let Emit(l: exn list) = + OutputExceptionR os (List.head l) + if isNil warnings && isNil errors then + os.Append(HashLoadedSourceHasIssues0E().Format) |> ignore + Emit infos + elif isNil errors then + os.Append(HashLoadedSourceHasIssues1E().Format) |> ignore + Emit warnings + else + os.Append(HashLoadedSourceHasIssues2E().Format) |> ignore + Emit errors + + | HashLoadedScriptConsideredSource _ -> + os.Append(HashLoadedScriptConsideredSourceE().Format) |> ignore + + | InvalidInternalsVisibleToAssemblyName(badName, fileNameOption) -> + match fileNameOption with + | Some file -> os.Append(InvalidInternalsVisibleToAssemblyName1E().Format badName file) |> ignore + | None -> os.Append(InvalidInternalsVisibleToAssemblyName2E().Format badName) |> ignore + + | LoadedSourceNotFoundIgnoring(filename, _) -> + os.Append(LoadedSourceNotFoundIgnoringE().Format filename) |> ignore + + | MSBuildReferenceResolutionWarning(code, message, _) + + | MSBuildReferenceResolutionError(code, message, _) -> + os.Append(MSBuildReferenceResolutionErrorE().Format message code) |> ignore + + // Strip TargetInvocationException wrappers + | :? System.Reflection.TargetInvocationException as e -> + OutputExceptionR os e.InnerException + + | :? FileNotFoundException as e -> Printf.bprintf os "%s" e.Message + + | :? DirectoryNotFoundException as e -> Printf.bprintf os "%s" e.Message + + | :? ArgumentException as e -> Printf.bprintf os "%s" e.Message + + | :? NotSupportedException as e -> Printf.bprintf os "%s" e.Message + + | :? IOException as e -> Printf.bprintf os "%s" e.Message + + | :? UnauthorizedAccessException as e -> Printf.bprintf os "%s" e.Message + + | e -> + os.Append(TargetInvocationExceptionWrapperE().Format e.Message) |> ignore +#if DEBUG + Printf.bprintf os "\nStack Trace\n%s\n" (e.ToString()) + if !showAssertForUnexpectedException then + Debug.Assert(false, sprintf "Unknown exception seen in compiler: %s" (e.ToString())) +#endif + + OutputExceptionR os err.Exception + + +// remove any newlines and tabs +let OutputPhasedDiagnostic (os: StringBuilder) (err: PhasedDiagnostic) (flattenErrors: bool) (suggestNames: bool) = + let buf = StringBuilder() + + OutputPhasedErrorR buf err suggestNames + let s = if flattenErrors then NormalizeErrorString (buf.ToString()) else buf.ToString() + + os.Append s |> ignore + +let SanitizeFileName fileName implicitIncludeDir = + // The assert below is almost ok, but it fires in two cases: + // - fsi.exe sometimes passes "stdin" as a dummy filename + // - if you have a #line directive, e.g. + // # 1000 "Line01.fs" + // then it also asserts. But these are edge cases that can be fixed later, e.g. in bug 4651. + //System.Diagnostics.Debug.Assert(FileSystem.IsPathRootedShim fileName, sprintf "filename should be absolute: '%s'" fileName) + try + let fullPath = FileSystem.GetFullPathShim fileName + let currentDir = implicitIncludeDir + + // if the file name is not rooted in the current directory, return the full path + if not(fullPath.StartsWithOrdinal currentDir) then + fullPath + // if the file name is rooted in the current directory, return the relative path + else + fullPath.Replace(currentDir+"\\", "") + with _ -> + fileName + +[] +type DiagnosticLocation = + { Range: range + File: string + TextRepresentation: string + IsEmpty: bool } + +[] +type DiagnosticCanonicalInformation = + { ErrorNumber: int + Subcategory: string + TextRepresentation: string } + +[] +type DiagnosticDetailedInfo = + { Location: DiagnosticLocation option + Canonical: DiagnosticCanonicalInformation + Message: string } + +[] +type Diagnostic = + | Short of FSharpDiagnosticSeverity * string + | Long of FSharpDiagnosticSeverity * DiagnosticDetailedInfo + +/// returns sequence that contains Diagnostic for the given error + Diagnostic for all related errors +let CollectDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, severity: FSharpDiagnosticSeverity, err: PhasedDiagnostic, suggestNames: bool) = + let outputWhere (showFullPaths, errorStyle) m: DiagnosticLocation = + if equals m rangeStartup || equals m rangeCmdArgs then + { Range = m; TextRepresentation = ""; IsEmpty = true; File = "" } + else + let file = m.FileName + let file = if showFullPaths then + FileSystem.GetFullFilePathInDirectoryShim implicitIncludeDir file + else + SanitizeFileName file implicitIncludeDir + let text, m, file = + match errorStyle with + | ErrorStyle.EmacsErrors -> + let file = file.Replace("\\", "/") + (sprintf "File \"%s\", line %d, characters %d-%d: " file m.StartLine m.StartColumn m.EndColumn), m, file + + // We're adjusting the columns here to be 1-based - both for parity with C# and for MSBuild, which assumes 1-based columns for error output + | ErrorStyle.DefaultErrors -> + let file = file.Replace('/', Path.DirectorySeparatorChar) + let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) m.End + (sprintf "%s(%d,%d): " file m.StartLine m.StartColumn), m, file + + // We may also want to change TestErrors to be 1-based + | ErrorStyle.TestErrors -> + let file = file.Replace("/", "\\") + let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) + sprintf "%s(%d,%d-%d,%d): " file m.StartLine m.StartColumn m.EndLine m.EndColumn, m, file + + | ErrorStyle.GccErrors -> + let file = file.Replace('/', Path.DirectorySeparatorChar) + let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) + sprintf "%s:%d:%d: " file m.StartLine m.StartColumn, m, file + + // Here, we want the complete range information so Project Systems can generate proper squiggles + | ErrorStyle.VSErrors -> + // Show prefix only for real files. Otherwise, we just want a truncated error like: + // parse error FS0031: blah blah + if not (equals m range0) && not (equals m rangeStartup) && not (equals m rangeCmdArgs) then + let file = file.Replace("/", "\\") + let m = mkRange m.FileName (mkPos m.StartLine (m.StartColumn + 1)) (mkPos m.EndLine (m.EndColumn + 1) ) + sprintf "%s(%d,%d,%d,%d): " file m.StartLine m.StartColumn m.EndLine m.EndColumn, m, file + else + "", m, file + { Range = m; TextRepresentation = text; IsEmpty = false; File = file } + + match err.Exception with + | ReportedError _ -> + assert ("" = "Unexpected ReportedError") // this should never happen + Seq.empty + | StopProcessing -> + assert ("" = "Unexpected StopProcessing") // this should never happen + Seq.empty + | _ -> + let errors = ResizeArray() + let report err = + let OutputWhere err = + match GetRangeOfDiagnostic err with + | Some m -> Some(outputWhere (showFullPaths, errorStyle) m) + | None -> None + + let OutputCanonicalInformation(subcategory, errorNumber) : DiagnosticCanonicalInformation = + let message = + match severity with + | FSharpDiagnosticSeverity.Error -> "error" + | FSharpDiagnosticSeverity.Warning -> "warning" + | FSharpDiagnosticSeverity.Info + | FSharpDiagnosticSeverity.Hidden -> "info" + let text = + match errorStyle with + // Show the subcategory for --vserrors so that we can fish it out in Visual Studio and use it to determine error stickiness. + | ErrorStyle.VSErrors -> sprintf "%s %s FS%04d: " subcategory message errorNumber + | _ -> sprintf "%s FS%04d: " message errorNumber + { ErrorNumber = errorNumber; Subcategory = subcategory; TextRepresentation = text} + + let mainError, relatedErrors = SplitRelatedDiagnostics err + let where = OutputWhere mainError + let canonical = OutputCanonicalInformation(err.Subcategory(), GetDiagnosticNumber mainError) + let message = + let os = StringBuilder() + OutputPhasedDiagnostic os mainError flattenErrors suggestNames + os.ToString() + + let entry: DiagnosticDetailedInfo = { Location = where; Canonical = canonical; Message = message } + + errors.Add ( Diagnostic.Long(severity, entry ) ) + + let OutputRelatedError(err: PhasedDiagnostic) = + match errorStyle with + // Give a canonical string when --vserror. + | ErrorStyle.VSErrors -> + let relWhere = OutputWhere mainError // mainError? + let relCanonical = OutputCanonicalInformation(err.Subcategory(), GetDiagnosticNumber mainError) // Use main error for code + let relMessage = + let os = StringBuilder() + OutputPhasedDiagnostic os err flattenErrors suggestNames + os.ToString() + + let entry: DiagnosticDetailedInfo = { Location = relWhere; Canonical = relCanonical; Message = relMessage} + errors.Add( Diagnostic.Long (severity, entry) ) + + | _ -> + let os = StringBuilder() + OutputPhasedDiagnostic os err flattenErrors suggestNames + errors.Add( Diagnostic.Short(severity, os.ToString()) ) + + relatedErrors |> List.iter OutputRelatedError + + match err with +#if !NO_EXTENSIONTYPING + | {Exception = :? TypeProviderError as tpe} -> + tpe.Iter (fun e -> + let newErr = {err with Exception = e} + report newErr + ) +#endif + | x -> report x + + errors:> seq<_> + +/// used by fsc.exe and fsi.exe, but not by VS +/// prints error and related errors to the specified StringBuilder +let rec OutputDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, severity) os (err: PhasedDiagnostic) = + + // 'true' for "canSuggestNames" is passed last here because we want to report suggestions in fsc.exe and fsi.exe, just not in regular IDE usage. + let errors = CollectDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorStyle, severity, err, true) + for e in errors do + Printf.bprintf os "\n" + match e with + | Diagnostic.Short(_, txt) -> + os.Append txt |> ignore + | Diagnostic.Long(_, details) -> + match details.Location with + | Some l when not l.IsEmpty -> os.Append l.TextRepresentation |> ignore + | _ -> () + os.Append( details.Canonical.TextRepresentation ) |> ignore + os.Append( details.Message ) |> ignore + +let OutputDiagnosticContext prefix fileLineFunction os err = + match GetRangeOfDiagnostic err with + | None -> () + | Some m -> + let filename = m.FileName + let lineA = m.StartLine + let lineB = m.EndLine + let line = fileLineFunction filename lineA + if line<>"" then + let iA = m.StartColumn + let iB = m.EndColumn + let iLen = if lineA = lineB then max (iB - iA) 1 else 1 + Printf.bprintf os "%s%s\n" prefix line + Printf.bprintf os "%s%s%s\n" prefix (String.make iA '-') (String.make iLen '^') + +let ReportDiagnosticAsInfo options (err, severity) = + match severity with + | FSharpDiagnosticSeverity.Error -> false + | FSharpDiagnosticSeverity.Warning -> false + | FSharpDiagnosticSeverity.Info -> + let n = GetDiagnosticNumber err + IsWarningOrInfoEnabled (err, severity) n options.WarnLevel options.WarnOn && + not (List.contains n options.WarnOff) + | FSharpDiagnosticSeverity.Hidden -> false + +let ReportDiagnosticAsWarning options (err, severity) = + match severity with + | FSharpDiagnosticSeverity.Error -> false + | FSharpDiagnosticSeverity.Warning -> + let n = GetDiagnosticNumber err + IsWarningOrInfoEnabled (err, severity) n options.WarnLevel options.WarnOn && + not (List.contains n options.WarnOff) + // Informational become warning if explicitly on and not explicitly off + | FSharpDiagnosticSeverity.Info -> + let n = GetDiagnosticNumber err + List.contains n options.WarnOn && + not (List.contains n options.WarnOff) + | FSharpDiagnosticSeverity.Hidden -> false + +let ReportDiagnosticAsError options (err, severity) = + match severity with + | FSharpDiagnosticSeverity.Error -> true + // Warnings become errors in some situations + | FSharpDiagnosticSeverity.Warning -> + let n = GetDiagnosticNumber err + IsWarningOrInfoEnabled (err, severity) n options.WarnLevel options.WarnOn && + not (List.contains n options.WarnAsWarn) && + ((options.GlobalWarnAsError && not (List.contains n options.WarnOff)) || + List.contains n options.WarnAsError) + // Informational become errors if explicitly WarnAsError + | FSharpDiagnosticSeverity.Info -> + let n = GetDiagnosticNumber err + List.contains n options.WarnAsError + | FSharpDiagnosticSeverity.Hidden -> false + +//---------------------------------------------------------------------------- +// Scoped #nowarn pragmas + + +/// Build an ErrorLogger that delegates to another ErrorLogger but filters warnings turned off by the given pragma declarations +// +// NOTE: we allow a flag to turn of strict file checking. This is because file names sometimes don't match due to use of +// #line directives, e.g. for pars.fs/pars.fsy. In this case we just test by line number - in most cases this is sufficient +// because we install a filtering error handler on a file-by-file basis for parsing and type-checking. +// However this is indicative of a more systematic problem where source-line +// sensitive operations (lexfilter and warning filtering) do not always +// interact well with #line directives. +type ErrorLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, errorLogger: ErrorLogger) = + inherit ErrorLogger("ErrorLoggerFilteringByScopedPragmas") + + override x.DiagnosticSink (phasedError, severity) = + if severity = FSharpDiagnosticSeverity.Error then + errorLogger.DiagnosticSink (phasedError, severity) + else + let report = + let warningNum = GetDiagnosticNumber phasedError + match GetRangeOfDiagnostic phasedError with + | Some m -> + not (scopedPragmas |> List.exists (fun pragma -> + match pragma with + | ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma) -> + warningNum = warningNumFromPragma && + (not checkFile || m.FileIndex = pragmaRange.FileIndex) && + posGeq m.Start pragmaRange.Start)) + | None -> true + if report then errorLogger.DiagnosticSink(phasedError, severity) + + override x.ErrorCount = errorLogger.ErrorCount + +let GetErrorLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, errorLogger) = + (ErrorLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, errorLogger) :> ErrorLogger) diff --git a/src/fsharp/CompilerDiagnostics.fsi b/src/fsharp/CompilerDiagnostics.fsi new file mode 100644 index 00000000000..e336a83c18a --- /dev/null +++ b/src/fsharp/CompilerDiagnostics.fsi @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to prepare, post-process, filter and emit compiler diagnsotics +module internal FSharp.Compiler.CompilerDiagnostics + +open System.Text +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +#if DEBUG +module internal CompilerService = + val showAssertForUnexpectedException: bool ref + +/// For extra diagnostics +val mutable showParserStackOnParseError: bool +#endif // DEBUG + +/// This exception is an old-style way of reporting a diagnostic +exception HashIncludeNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashReferenceNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashLoadedSourceHasIssues of informationals: exn list * warnings: exn list * errors: exn list * range + +/// This exception is an old-style way of reporting a diagnostic +exception HashLoadedScriptConsideredSource of range + +/// This exception is an old-style way of reporting a diagnostic +exception HashDirectiveNotAllowedInNonScript of range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionFull of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionForHtmlDoc of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionSuggestAlternative of string * string * range + +/// This exception is an old-style way of reporting a diagnostic +exception DeprecatedCommandLineOptionNoDescription of string * range + +/// This exception is an old-style way of reporting a diagnostic +exception InternalCommandLineOption of string * range + +/// Get the location associated with an error +val GetRangeOfDiagnostic: PhasedDiagnostic -> range option + +/// Get the number associated with an error +val GetDiagnosticNumber: PhasedDiagnostic -> int + +/// Split errors into a "main" error and a set of associated errors +val SplitRelatedDiagnostics: PhasedDiagnostic -> PhasedDiagnostic * PhasedDiagnostic list + +/// Output an error to a buffer +val OutputPhasedDiagnostic: StringBuilder -> PhasedDiagnostic -> flattenErrors: bool -> suggestNames: bool -> unit + +/// Output an error or warning to a buffer +val OutputDiagnostic: implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * severity: FSharpDiagnosticSeverity -> StringBuilder -> PhasedDiagnostic -> unit + +/// Output extra context information for an error or warning to a buffer +val OutputDiagnosticContext: prefix:string -> fileLineFunction:(string -> int -> string) -> StringBuilder -> PhasedDiagnostic -> unit + +/// Part of LegacyHostedCompilerForTesting +[] +type DiagnosticLocation = + { Range: range + File: string + TextRepresentation: string + IsEmpty: bool } + +/// Part of LegacyHostedCompilerForTesting +[] +type DiagnosticCanonicalInformation = + { ErrorNumber: int + Subcategory: string + TextRepresentation: string } + +/// Part of LegacyHostedCompilerForTesting +[] +type DiagnosticDetailedInfo = + { Location: DiagnosticLocation option + Canonical: DiagnosticCanonicalInformation + Message: string } + +/// Part of LegacyHostedCompilerForTesting +[] +type Diagnostic = + | Short of FSharpDiagnosticSeverity * string + | Long of FSharpDiagnosticSeverity * DiagnosticDetailedInfo + +/// Part of LegacyHostedCompilerForTesting +val CollectDiagnostic: implicitIncludeDir:string * showFullPaths: bool * flattenErrors: bool * errorStyle: ErrorStyle * severity: FSharpDiagnosticSeverity * PhasedDiagnostic * suggestNames: bool -> seq + +/// Get an error logger that filters the reporting of warnings based on scoped pragma information +val GetErrorLoggerFilteringByScopedPragmas: checkFile:bool * ScopedPragma list * ErrorLogger -> ErrorLogger + +val SanitizeFileName: fileName: string -> implicitIncludeDir: string -> string + +/// Indicates if we should report a diagnostic as a warning +val ReportDiagnosticAsInfo: FSharpDiagnosticOptions -> (PhasedDiagnostic * FSharpDiagnosticSeverity) -> bool + +/// Indicates if we should report a diagnostic as a warning +val ReportDiagnosticAsWarning: FSharpDiagnosticOptions -> (PhasedDiagnostic * FSharpDiagnosticSeverity) -> bool + +/// Indicates if we should report a warning as an error +val ReportDiagnosticAsError: FSharpDiagnosticOptions -> (PhasedDiagnostic * FSharpDiagnosticSeverity) -> bool + + diff --git a/src/fsharp/CompilerGlobalState.fs b/src/fsharp/CompilerGlobalState.fs index a54fc0426ae..3683d171bf0 100644 --- a/src/fsharp/CompilerGlobalState.fs +++ b/src/fsharp/CompilerGlobalState.fs @@ -2,12 +2,11 @@ /// Defines the global environment for all type checking. -namespace FSharp.Compiler +module FSharp.Compiler.CompilerGlobalState open System.Collections.Generic -open FSharp.Compiler.Range -open FSharp.Compiler.PrettyNaming - +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text /// Generates compiler-generated names. Each name generated also includes the StartLine number of the range passed in /// at the point of first generation. @@ -19,7 +18,7 @@ open FSharp.Compiler.PrettyNaming type NiceNameGenerator() = let lockObj = obj() - let basicNameCounts = new Dictionary(100) + let basicNameCounts = Dictionary(100) member x.FreshCompilerGeneratedName (name, m: range) = lock lockObj (fun () -> @@ -47,8 +46,8 @@ type StableNiceNameGenerator() = let lockObj = obj() - let names = new Dictionary<(string * int64), string>(100) - let basicNameCounts = new Dictionary(100) + let names = Dictionary(100) + let basicNameCounts = Dictionary(100) member x.GetUniqueCompilerGeneratedName (name, m: range, uniq) = lock lockObj (fun () -> @@ -75,21 +74,30 @@ type StableNiceNameGenerator() = type internal CompilerGlobalState () = /// A global generator of compiler generated names - // ++GLOBAL MUTABLE STATE (concurrency safe by locking inside NiceNameGenerator) let globalNng = NiceNameGenerator() - /// A global generator of stable compiler generated names - // MUTABLE STATE (concurrency safe by locking inside StableNiceNameGenerator) let globalStableNameGenerator = StableNiceNameGenerator () /// A name generator used by IlxGen for static fields, some generated arguments and other things. - /// REVIEW: this will mean the hosted compiler service is not deterministic. We should at least create a new one - /// of these for each compilation. let ilxgenGlobalNng = NiceNameGenerator () - member __.NiceNameGenerator = globalNng + member _.NiceNameGenerator = globalNng + + member _.StableNameGenerator = globalStableNameGenerator + + member _.IlxGenNiceNameGenerator = ilxgenGlobalNng + +/// Unique name generator for stamps attached to lambdas and object expressions +type Unique = int64 - member __.StableNameGenerator = globalStableNameGenerator +//++GLOBAL MUTABLE STATE (concurrency-safe) +let newUnique = + let i = ref 0L + fun () -> System.Threading.Interlocked.Increment i - member __.IlxGenNiceNameGenerator = ilxgenGlobalNng +/// Unique name generator for stamps attached to to val_specs, tycon_specs etc. +//++GLOBAL MUTABLE STATE (concurrency-safe) +let newStamp = + let i = ref 0L + fun () -> System.Threading.Interlocked.Increment i diff --git a/src/fsharp/CompilerGlobalState.fsi b/src/fsharp/CompilerGlobalState.fsi new file mode 100644 index 00000000000..4a1e646ffc0 --- /dev/null +++ b/src/fsharp/CompilerGlobalState.fsi @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines the global environment for all type checking. + +module internal FSharp.Compiler.CompilerGlobalState + +open FSharp.Compiler.Text + +/// Generates compiler-generated names. Each name generated also includes the StartLine number of the range passed in +/// at the point of first generation. +/// +/// This type may be accessed concurrently, though in practice it is only used from the compilation thread. +/// It is made concurrency-safe since a global instance of the type is allocated in tast.fs, and it is good +/// policy to make all globally-allocated objects concurrency safe in case future versions of the compiler +/// are used to host multiple concurrent instances of compilation. +type NiceNameGenerator = + + new: unit -> NiceNameGenerator + member FreshCompilerGeneratedName: name:string * m:range -> string + member Reset: unit -> unit + +/// Generates compiler-generated names marked up with a source code location, but if given the same unique value then +/// return precisely the same name. Each name generated also includes the StartLine number of the range passed in +/// at the point of first generation. +/// +/// This type may be accessed concurrently, though in practice it is only used from the compilation thread. +/// It is made concurrency-safe since a global instance of the type is allocated in tast.fs. +type StableNiceNameGenerator = + + new: unit -> StableNiceNameGenerator + member GetUniqueCompilerGeneratedName: name:string * m:range * uniq:int64 -> string + member Reset: unit -> unit + +type internal CompilerGlobalState = + + new: unit -> CompilerGlobalState + + /// A name generator used by IlxGen for static fields, some generated arguments and other things. + member IlxGenNiceNameGenerator: NiceNameGenerator + + /// A global generator of compiler generated names + member NiceNameGenerator: NiceNameGenerator + + /// A global generator of stable compiler generated names + member StableNameGenerator: StableNiceNameGenerator + +type Unique = int64 + +/// Concurrency-safe +val newUnique: (unit -> int64) + +/// Unique name generator for stamps attached to to val_specs, tycon_specs etc. +/// Concurrency-safe +val newStamp: (unit -> int64) diff --git a/src/fsharp/CompilerImports.fs b/src/fsharp/CompilerImports.fs new file mode 100644 index 00000000000..b5196f1b88f --- /dev/null +++ b/src/fsharp/CompilerImports.fs @@ -0,0 +1,1980 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to coordinate assembly resolution and manage the TcImports table of referenced +/// assemblies. +module internal FSharp.Compiler.CompilerImports + +open System +open System.Collections.Generic +open System.Diagnostics +open System.IO + +open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.FSharpEnvironment +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Import +open FSharp.Compiler.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTreePickle +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.BuildGraph + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +open FSharp.Core.CompilerServices +#endif + +let (++) x s = x @ [s] + +//---------------------------------------------------------------------------- +// Signature and optimization data blobs +//-------------------------------------------------------------------------- + +let IsSignatureDataResource (r: ILResource) = + r.Name.StartsWithOrdinal FSharpSignatureDataResourceName || + r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 + +let IsOptimizationDataResource (r: ILResource) = + r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName|| + r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 + +let GetSignatureDataResourceName (r: ILResource) = + if r.Name.StartsWithOrdinal FSharpSignatureDataResourceName then + String.dropPrefix r.Name FSharpSignatureDataResourceName + elif r.Name.StartsWithOrdinal FSharpSignatureDataResourceName2 then + String.dropPrefix r.Name FSharpSignatureDataResourceName2 + else failwith "GetSignatureDataResourceName" + +let GetOptimizationDataResourceName (r: ILResource) = + if r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName then + String.dropPrefix r.Name FSharpOptimizationDataResourceName + elif r.Name.StartsWithOrdinal FSharpOptimizationDataResourceName2 then + String.dropPrefix r.Name FSharpOptimizationDataResourceName2 + else failwith "GetOptimizationDataResourceName" + +let IsReflectedDefinitionsResource (r: ILResource) = + r.Name.StartsWithOrdinal(QuotationPickler.SerializedReflectedDefinitionsResourceNameBase) + +let MakeILResource rName bytes = + { Name = rName + Location = ILResourceLocation.Local(ByteStorage.FromByteArray(bytes)) + Access = ILResourceAccess.Public + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx } + +let PickleToResource inMem file (g: TcGlobals) scope rName p x = + let file = PathMap.apply g.pathMap file + + let bytes = pickleObjWithDanglingCcus inMem file g scope p x + let byteStorage = + if inMem then + ByteStorage.FromMemoryAndCopy(bytes.AsMemory(), useBackingMemoryMappedFile = true) + else + ByteStorage.FromByteArray(bytes.AsMemory().ToArray()) + + (bytes :> IDisposable).Dispose() + + { Name = rName + Location = ILResourceLocation.Local(byteStorage) + Access = ILResourceAccess.Public + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx } + +let GetSignatureData (file, ilScopeRef, ilModule, byteReader) : PickledDataWithReferences = + unpickleObjWithDanglingCcus file ilScopeRef ilModule unpickleCcuInfo (byteReader()) + +let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: CcuThunk, filename, inMem) : ILResource = + let mspec = ccu.Contents + let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping mspec + // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers + // don't complain when they see the resource. + let rName = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName + + let includeDir = + if String.IsNullOrEmpty tcConfig.implicitIncludeDir then "" + else + tcConfig.implicitIncludeDir + |> FileSystem.GetFullPathShim + |> PathMap.applyDir tcGlobals.pathMap + + PickleToResource inMem filename tcGlobals ccu (rName+ccu.AssemblyName) pickleCcuInfo + { mspec=mspec + compileTimeWorkingDir=includeDir + usesQuotations = ccu.UsesFSharp20PlusQuotations } + +let GetOptimizationData (file, ilScopeRef, ilModule, byteReader) = + unpickleObjWithDanglingCcus file ilScopeRef ilModule Optimizer.u_CcuOptimizationInfo (byteReader()) + +let WriteOptimizationData (tcGlobals, filename, inMem, ccu: CcuThunk, modulInfo) = + // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers + // don't complain when they see the resource. + let rName = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpOptimizationDataResourceName2 else FSharpOptimizationDataResourceName + PickleToResource inMem filename tcGlobals ccu (rName+ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo + +let EncodeSignatureData(tcConfig: TcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) = + if tcConfig.GenerateSignatureData then + let resource = WriteSignatureData (tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) + // The resource gets written to a file for FSharp.Core + let useDataFiles = (tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib) && not isIncrementalBuild + + if useDataFiles then + let sigDataFileName = (FileSystemUtils.chopExtension outfile)+".sigdata" + let bytes = resource.GetBytes() + use fileStream = FileSystem.OpenFileForWriteShim(sigDataFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None) + + bytes.CopyTo fileStream + let resources = + [ resource ] + let sigAttr = mkSignatureDataVersionAttr tcGlobals (parseILVersion FSharpBinaryMetadataFormatRevision) + [sigAttr], resources + else + [], [] + +let EncodeOptimizationData(tcGlobals, tcConfig: TcConfig, outfile, exportRemapping, data, isIncrementalBuild) = + if tcConfig.GenerateOptimizationData then + let data = map2Of2 (Optimizer.RemapOptimizationInfo tcGlobals exportRemapping) data + // As with the sigdata file, the optdata gets written to a file for FSharp.Core + let useDataFiles = (tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib) && not isIncrementalBuild + + if useDataFiles then + let ccu, modulInfo = data + let bytes = pickleObjWithDanglingCcus isIncrementalBuild outfile tcGlobals ccu Optimizer.p_CcuOptimizationInfo modulInfo + let optDataFileName = (FileSystemUtils.chopExtension outfile)+".optdata" + use fileStream = FileSystem.OpenFileForWriteShim(optDataFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None) + fileStream.Write(bytes) + + let ccu, optData = + if tcConfig.onlyEssentialOptimizationData then + map2Of2 Optimizer.AbstractOptimizationInfoToEssentials data + else + data + [ WriteOptimizationData (tcGlobals, outfile, isIncrementalBuild, ccu, optData) ] + else + [ ] + +exception AssemblyNotResolved of (*originalName*) string * range + +exception MSBuildReferenceResolutionWarning of (*MSBuild warning code*)string * (*Message*)string * range + +exception MSBuildReferenceResolutionError of (*MSBuild warning code*)string * (*Message*)string * range + +let OpenILBinary(filename, reduceMemoryUsage, pdbDirPath, shadowCopyReferences, tryGetMetadataSnapshot) = + let opts: ILReaderOptions = + { metadataOnly = MetadataOnlyFlag.Yes + reduceMemoryUsage = reduceMemoryUsage + pdbDirPath = pdbDirPath + tryGetMetadataSnapshot = tryGetMetadataSnapshot } + + let location = +#if FX_NO_APP_DOMAINS + // In order to use memory mapped files on the shadow copied version of the Assembly, we `preload the assembly + // We swallow all exceptions so that we do not change the exception contract of this API + if shadowCopyReferences then + try + System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename).Location + with e -> filename + else +#else + ignore shadowCopyReferences +#endif + filename + AssemblyReader.GetILModuleReader(location, opts) + +[] +type ResolveAssemblyReferenceMode = Speculative | ReportErrors + +#if !NO_EXTENSIONTYPING +type ResolvedExtensionReference = ResolvedExtensionReference of string * AssemblyReference list * Tainted list +#endif + +#if DEBUG +[] +#endif +type AssemblyResolution = + { /// The original reference to the assembly. + originalReference: AssemblyReference + + /// Path to the resolvedFile + resolvedPath: string + + /// Create the tooltip text for the assembly reference + prepareToolTip: unit -> string + + /// Whether or not this is an installed system assembly (for example, System.dll) + sysdir: bool + + /// Lazily populated ilAssemblyRef for this reference. + mutable ilAssemblyRef: ILAssemblyRef option + } + override this.ToString() = sprintf "%s%s" (if this.sysdir then "[sys]" else "") this.resolvedPath + + member this.ProjectReference = this.originalReference.ProjectReference + + /// Compute the ILAssemblyRef for a resolved assembly. This is done by reading the binary if necessary. The result + /// is cached. + /// + /// Only used in F# Interactive + member this.GetILAssemblyRef(reduceMemoryUsage, tryGetMetadataSnapshot) = + match this.ilAssemblyRef with + | Some assemblyRef -> assemblyRef + | None -> + match this.ProjectReference with + | Some _ -> failwith "IProjectReference is not allowed to be used in GetILAssemblyRef" + | None -> () + + let assemblyRef = + let readerSettings: ILReaderOptions = + { pdbDirPath=None + reduceMemoryUsage = reduceMemoryUsage + metadataOnly = MetadataOnlyFlag.Yes + tryGetMetadataSnapshot = tryGetMetadataSnapshot } + use reader = OpenILModuleReader this.resolvedPath readerSettings + mkRefToILAssembly reader.ILModuleDef.ManifestOfAssembly + this.ilAssemblyRef <- Some assemblyRef + assemblyRef + +type ImportedBinary = + { FileName: string + RawMetadata: IRawFSharpAssemblyData +#if !NO_EXTENSIONTYPING + ProviderGeneratedAssembly: System.Reflection.Assembly option + IsProviderGenerated: bool + ProviderGeneratedStaticLinkMap: ProvidedAssemblyStaticLinkingMap option +#endif + ILAssemblyRefs: ILAssemblyRef list + ILScopeRef: ILScopeRef } + +type ImportedAssembly = + { ILScopeRef: ILScopeRef + FSharpViewOfMetadata: CcuThunk + AssemblyAutoOpenAttributes: string list + AssemblyInternalsVisibleToAttributes: string list +#if !NO_EXTENSIONTYPING + IsProviderGenerated: bool + mutable TypeProviders: Tainted list +#endif + FSharpOptimizationData: Microsoft.FSharp.Control.Lazy> } + +type AvailableImportedAssembly = + | ResolvedImportedAssembly of ImportedAssembly + | UnresolvedImportedAssembly of string + +type CcuLoadFailureAction = + | RaiseError + | ReturnNone + +type TcImportsLockToken() = + interface LockToken + +type TcImportsLock = Lock + +let RequireTcImportsLock (_tcitok: TcImportsLockToken, _thingProtected: 'T) = () + +type TcConfig with + + member tcConfig.TryResolveLibWithDirectories (r: AssemblyReference) = + let m, nm = r.Range, r.Text + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + // Only want to resolve certain extensions (otherwise, 'System.Xml' is ambiguous). + // MSBuild resolution is limited to .exe and .dll so do the same here. + let ext = Path.GetExtension nm + let isNetModule = String.Compare(ext, ".netmodule", StringComparison.OrdinalIgnoreCase)=0 + + // See if the language service has already produced the contents of the assembly for us, virtually + match r.ProjectReference with + | Some _ -> + let resolved = r.Text + let sysdir = tcConfig.IsSystemAssembly resolved + Some + { originalReference = r + resolvedPath = resolved + prepareToolTip = (fun () -> resolved) + sysdir = sysdir + ilAssemblyRef = None } + | None -> + + if String.Compare(ext, ".dll", StringComparison.OrdinalIgnoreCase)=0 + || String.Compare(ext, ".exe", StringComparison.OrdinalIgnoreCase)=0 + || isNetModule then + + let searchPaths = + // if this is a #r reference (not from dummy range), make sure the directory of the declaring + // file is included in the search path. This should ideally already be one of the search paths, but + // during some global checks it won't be. We append to the end of the search list so that this is the last + // place that is checked. + let isPoundRReference (r: range) = + not (equals r range0) && + not (equals r rangeStartup) && + not (equals r rangeCmdArgs) && + FileSystem.IsPathRootedShim r.FileName + + if isPoundRReference m then + tcConfig.GetSearchPathsForLibraryFiles() @ [Path.GetDirectoryName(m.FileName)] + else + tcConfig.GetSearchPathsForLibraryFiles() + + let resolved = TryResolveFileUsingPaths(searchPaths, m, nm) + match resolved with + | Some resolved -> + let sysdir = tcConfig.IsSystemAssembly resolved + Some + { originalReference = r + resolvedPath = resolved + prepareToolTip = (fun () -> + let fusionName = System.Reflection.AssemblyName.GetAssemblyName(resolved).ToString() + let line(append: string) = append.Trim([|' '|])+"\n" + line resolved + line fusionName) + sysdir = sysdir + ilAssemblyRef = None } + | None -> None + else None + + member tcConfig.ResolveLibWithDirectories (ccuLoadFailureAction, r: AssemblyReference) = + let m, nm = r.Range, r.Text + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + // test for both libraries and executables + let ext = Path.GetExtension nm + let isExe = (String.Compare(ext, ".exe", StringComparison.OrdinalIgnoreCase) = 0) + let isDLL = (String.Compare(ext, ".dll", StringComparison.OrdinalIgnoreCase) = 0) + let isNetModule = (String.Compare(ext, ".netmodule", StringComparison.OrdinalIgnoreCase) = 0) + + let rs = + if isExe || isDLL || isNetModule then + [r] + else + [AssemblyReference(m, nm+".dll", None);AssemblyReference(m, nm+".exe", None);AssemblyReference(m, nm+".netmodule", None)] + + match rs |> List.tryPick (fun r -> tcConfig.TryResolveLibWithDirectories(r)) with + | Some res -> Some res + | None -> + match ccuLoadFailureAction with + | CcuLoadFailureAction.RaiseError -> + let searchMessage = String.concat "\n " (tcConfig.GetSearchPathsForLibraryFiles()) + raise (FileNameNotResolved(nm, searchMessage, m)) + | CcuLoadFailureAction.ReturnNone -> None + + member tcConfig.MsBuildResolve (references, mode, errorAndWarningRange, showMessages) = + let logMessage showMessages = + if showMessages && tcConfig.showReferenceResolutions then (fun (message: string)->dprintf "%s\n" message) + else ignore + + let logDiagnostic showMessages = + (fun isError code message-> + if showMessages && mode = ResolveAssemblyReferenceMode.ReportErrors then + if isError then + errorR(MSBuildReferenceResolutionError(code, message, errorAndWarningRange)) + else + match code with + // These are warnings that mean 'not resolved' for some assembly. + // Note that we don't get to know the name of the assembly that couldn't be resolved. + // Ignore these and rely on the logic below to emit an error for each unresolved reference. + | "MSB3246" // Resolved file has a bad image, no metadata, or is otherwise inaccessible. + | "MSB3106" + -> () + | _ -> + if code = "MSB3245" then + errorR(MSBuildReferenceResolutionWarning(code, message, errorAndWarningRange)) + else + warning(MSBuildReferenceResolutionWarning(code, message, errorAndWarningRange))) + + let targetProcessorArchitecture = + match tcConfig.platform with + | None -> "MSIL" + | Some X86 -> "x86" + | Some AMD64 -> "amd64" + | Some IA64 -> "ia64" + + try + tcConfig.legacyReferenceResolver.Impl.Resolve + (tcConfig.resolutionEnvironment, + references, + tcConfig.targetFrameworkVersion, + tcConfig.GetTargetFrameworkDirectories(), + targetProcessorArchitecture, + tcConfig.fsharpBinariesDir, // FSharp binaries directory + tcConfig.includes, // Explicit include directories + tcConfig.implicitIncludeDir, // Implicit include directory (likely the project directory) + logMessage showMessages, logDiagnostic showMessages) + with + | LegacyResolutionFailure -> error(Error(FSComp.SR.buildAssemblyResolutionFailed(), errorAndWarningRange)) + + + // NOTE!! if mode=Speculative then this method must not report ANY warnings or errors through 'warning' or 'error'. Instead + // it must return warnings and errors as data + // + // NOTE!! if mode=ReportErrors then this method must not raise exceptions. It must just report the errors and recover + static member TryResolveLibsUsingMSBuildRules (tcConfig: TcConfig, + originalReferences: AssemblyReference list, + errorAndWarningRange: range, + mode: ResolveAssemblyReferenceMode) : AssemblyResolution list * UnresolvedAssemblyReference list = + + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + if tcConfig.useSimpleResolution then + failwith "MSBuild resolution is not supported." + if originalReferences=[] then [], [] + else + // Group references by name with range values in the grouped value list. + // In the grouped reference, store the index of the last use of the reference. + let groupedReferences = + originalReferences + |> List.indexed + |> Seq.groupBy(fun (_, reference) -> reference.Text) + |> Seq.map(fun (assemblyName, assemblyAndIndexGroup)-> + let assemblyAndIndexGroup = assemblyAndIndexGroup |> List.ofSeq + let highestPosition = assemblyAndIndexGroup |> List.maxBy fst |> fst + let assemblyGroup = assemblyAndIndexGroup |> List.map snd + assemblyName, highestPosition, assemblyGroup) + |> Array.ofSeq + + // First, try to resolve everything as a file using simple resolution + let resolvedAsFile = + groupedReferences + |> Array.map(fun (_filename, maxIndexOfReference, references)-> + let assemblyResolution = references |> List.choose (fun r -> tcConfig.TryResolveLibWithDirectories r) + (maxIndexOfReference, assemblyResolution)) + |> Array.filter(fun (_, refs)->refs |> isNil |> not) + + let toMsBuild = [|0..groupedReferences.Length-1|] + |> Array.map(fun i->(p13 groupedReferences.[i]), (p23 groupedReferences.[i]), i) + |> Array.filter (fun (_, i0, _)->resolvedAsFile|>Array.exists(fun (i1, _) -> i0=i1)|>not) + |> Array.map(fun (ref, _, i)->ref, string i) + + let resolutions = tcConfig.MsBuildResolve(toMsBuild, mode, errorAndWarningRange, (*showMessages*)true) + + // Map back to original assembly resolutions. + let resolvedByMsbuild = + resolutions + |> Array.map(fun resolvedFile -> + let i = int resolvedFile.baggage + let _, maxIndexOfReference, ms = groupedReferences.[i] + let assemblyResolutions = + ms|>List.map(fun originalReference -> + Debug.Assert(FileSystem.IsPathRootedShim(resolvedFile.itemSpec), sprintf "msbuild-resolved path is not absolute: '%s'" resolvedFile.itemSpec) + let canonicalItemSpec = FileSystem.GetFullPathShim(resolvedFile.itemSpec) + { originalReference=originalReference + resolvedPath=canonicalItemSpec + prepareToolTip = (fun () -> resolvedFile.prepareToolTip (originalReference.Text, canonicalItemSpec)) + sysdir= tcConfig.IsSystemAssembly canonicalItemSpec + ilAssemblyRef = None }) + (maxIndexOfReference, assemblyResolutions)) + + // When calculating the resulting resolutions, we're going to use the index of the reference + // in the original specification and resort it to match the ordering that we had. + let resultingResolutions = + [resolvedByMsbuild;resolvedAsFile] + |> Array.concat + |> Array.sortBy fst + |> Array.map snd + |> List.ofArray + |> List.concat + + // O(N^2) here over a small set of referenced assemblies. + let IsResolved(originalName: string) = + if resultingResolutions |> List.exists(fun resolution -> resolution.originalReference.Text = originalName) then true + else + // MSBuild resolution may have unified the result of two duplicate references. Try to re-resolve now. + // If re-resolution worked then this was a removed duplicate. + tcConfig.MsBuildResolve([|originalName, ""|], mode, errorAndWarningRange, (*showMessages*)false).Length<>0 + + let unresolvedReferences = + groupedReferences + //|> Array.filter(p13 >> IsNotFileOrIsAssembly) + |> Array.filter(p13 >> IsResolved >> not) + |> List.ofArray + + // If mode=Speculative, then we haven't reported any errors. + // We report the error condition by returning an empty list of resolutions + if mode = ResolveAssemblyReferenceMode.Speculative && (List.length unresolvedReferences) > 0 then + [], (List.ofArray groupedReferences) |> List.map (fun (name, _, r) -> (name, r)) |> List.map UnresolvedAssemblyReference + else + resultingResolutions, unresolvedReferences |> List.map (fun (name, _, r) -> (name, r)) |> List.map UnresolvedAssemblyReference + +[] +type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list, unresolved: UnresolvedAssemblyReference list) = + + let originalReferenceToResolution = results |> List.map (fun r -> r.originalReference.Text, r) |> Map.ofList + let resolvedPathToResolution = results |> List.map (fun r -> r.resolvedPath, r) |> Map.ofList + + /// Add some resolutions to the map of resolution results. + member _.AddResolutionResults newResults = TcAssemblyResolutions(tcConfig, results @ newResults, unresolved) + + /// Add some unresolved results. + member _.AddUnresolvedReferences newUnresolved = TcAssemblyResolutions(tcConfig, results, unresolved @ newUnresolved) + + /// Get information about referenced DLLs + member _.GetAssemblyResolutions() = results + + member _.GetUnresolvedReferences() = unresolved + + member _.TryFindByOriginalReference(assemblyReference: AssemblyReference) = originalReferenceToResolution.TryFind assemblyReference.Text + + /// Only used by F# Interactive + member _.TryFindByExactILAssemblyRef assemblyRef = + results |> List.tryFind (fun ar-> + let r = ar.GetILAssemblyRef(tcConfig.reduceMemoryUsage, tcConfig.tryGetMetadataSnapshot) + r = assemblyRef) + + /// Only used by F# Interactive + member _.TryFindBySimpleAssemblyName simpleAssemName = + results |> List.tryFind (fun ar-> + let r = ar.GetILAssemblyRef(tcConfig.reduceMemoryUsage, tcConfig.tryGetMetadataSnapshot) + r.Name = simpleAssemName) + + member _.TryFindByResolvedPath nm = resolvedPathToResolution.TryFind nm + + member _.TryFindByOriginalReferenceText nm = originalReferenceToResolution.TryFind nm + + static member ResolveAssemblyReferences (tcConfig: TcConfig, assemblyList: AssemblyReference list, knownUnresolved: UnresolvedAssemblyReference list) : TcAssemblyResolutions = + let resolved, unresolved = + if tcConfig.useSimpleResolution then + let resolutions = + assemblyList + |> List.map (fun assemblyReference -> + try + Choice1Of2 (tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, assemblyReference) |> Option.get) + with e -> + errorRecovery e assemblyReference.Range + Choice2Of2 assemblyReference) + let successes = resolutions |> List.choose (function Choice1Of2 x -> Some x | _ -> None) + let failures = resolutions |> List.choose (function Choice2Of2 x -> Some (UnresolvedAssemblyReference(x.Text, [x])) | _ -> None) + successes, failures + else + // we don't want to do assembly resolution concurrently, we assume MSBuild doesn't handle this + TcConfig.TryResolveLibsUsingMSBuildRules (tcConfig, assemblyList, rangeStartup, ResolveAssemblyReferenceMode.ReportErrors) + TcAssemblyResolutions(tcConfig, resolved, unresolved @ knownUnresolved) + + static member GetAllDllReferences (tcConfig: TcConfig) = [ + let primaryReference = tcConfig.PrimaryAssemblyDllReference() + + let assumeDotNetFramework = primaryReference.SimpleAssemblyNameIs("mscorlib") + + if not tcConfig.compilingFslib then + yield tcConfig.CoreLibraryDllReference() + if assumeDotNetFramework then + // When building desktop then we need these additional dependencies + yield AssemblyReference(rangeStartup, "System.Numerics.dll", None) + yield AssemblyReference(rangeStartup, "System.dll", None) + let asm = AssemblyReference(rangeStartup, "netstandard.dll", None) + let found = + if tcConfig.useSimpleResolution then + match tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.ReturnNone, asm) with + | Some _ -> true + | None -> false + else + let resolutions = tcConfig.MsBuildResolve([|asm.Text, ""|], ResolveAssemblyReferenceMode.Speculative, rangeStartup, (*showMessages*)false) + resolutions.Length = 1 + if found then yield asm + + if tcConfig.framework then + let references, _useDotNetFramework = tcConfig.FxResolver.GetDefaultReferences(tcConfig.useFsiAuxLib) + for s in references do + yield AssemblyReference(rangeStartup, (if s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then s else s+".dll"), None) + + yield! tcConfig.referencedDLLs + ] + + static member SplitNonFoundationalResolutions (tcConfig: TcConfig) = + let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig + let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (tcConfig, assemblyList, tcConfig.knownUnresolvedReferences) + let frameworkDLLs, nonFrameworkReferences = resolutions.GetAssemblyResolutions() |> List.partition (fun r -> r.sysdir) + let unresolved = resolutions.GetUnresolvedReferences() +#if DEBUG + let mutable itFailed = false + let addedText = "\nIf you want to debug this right now, attach a debugger, and put a breakpoint in 'CompileOps.fs' near the text '!itFailed', and you can re-step through the assembly resolution logic." + + for UnresolvedAssemblyReference(referenceText, _ranges) in unresolved do + if referenceText.Contains("mscorlib") then + Debug.Assert(false, sprintf "whoops, did not resolve mscorlib: '%s'%s" referenceText addedText) + itFailed <- true + + for x in frameworkDLLs do + if not(FileSystem.IsPathRootedShim(x.resolvedPath)) then + Debug.Assert(false, sprintf "frameworkDLL should be absolute path: '%s'%s" x.resolvedPath addedText) + itFailed <- true + + for x in nonFrameworkReferences do + if not(FileSystem.IsPathRootedShim(x.resolvedPath)) then + Debug.Assert(false, sprintf "nonFrameworkReference should be absolute path: '%s'%s" x.resolvedPath addedText) + itFailed <- true + + if itFailed then + // idea is, put a breakpoint here and then step through + let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig + let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (tcConfig, assemblyList, []) + let _frameworkDLLs, _nonFrameworkReferences = resolutions.GetAssemblyResolutions() |> List.partition (fun r -> r.sysdir) + () +#endif + frameworkDLLs, nonFrameworkReferences, unresolved + + static member BuildFromPriorResolutions (tcConfig: TcConfig, resolutions, knownUnresolved) = + let references = resolutions |> List.map (fun r -> r.originalReference) + TcAssemblyResolutions.ResolveAssemblyReferences (tcConfig, references, knownUnresolved) + + static member GetAssemblyResolutionInformation(tcConfig: TcConfig) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + let assemblyList = TcAssemblyResolutions.GetAllDllReferences tcConfig + let resolutions = TcAssemblyResolutions.ResolveAssemblyReferences (tcConfig, assemblyList, []) + resolutions.GetAssemblyResolutions(), resolutions.GetUnresolvedReferences() + +//---------------------------------------------------------------------------- +// Abstraction for project reference + +let GetNameOfILModule (m: ILModuleDef) = + match m.Manifest with + | Some manifest -> manifest.Name + | None -> m.Name + +let MakeScopeRefForILModule (ilModule: ILModuleDef) = + match ilModule.Manifest with + | Some m -> ILScopeRef.Assembly (mkRefToILAssembly m) + | None -> ILScopeRef.Module (mkRefToILModule ilModule) + +let GetCustomAttributesOfILModule (ilModule: ILModuleDef) = + (match ilModule.Manifest with Some m -> m.CustomAttrs | None -> ilModule.CustomAttrs).AsList + +let GetAutoOpenAttributes ilModule = + ilModule |> GetCustomAttributesOfILModule |> List.choose TryFindAutoOpenAttr + +let GetInternalsVisibleToAttributes ilModule = + ilModule |> GetCustomAttributesOfILModule |> List.choose TryFindInternalsVisibleToAttr + +type RawFSharpAssemblyDataBackedByFileOnDisk (ilModule: ILModuleDef, ilAssemblyRefs) = + let externalSigAndOptData = ["FSharp.Core"] + interface IRawFSharpAssemblyData with + + member _.GetAutoOpenAttributes() = GetAutoOpenAttributes ilModule + + member _.GetInternalsVisibleToAttributes() = GetInternalsVisibleToAttributes ilModule + + member _.TryGetILModuleDef() = Some ilModule + + member _.GetRawFSharpSignatureData(m, ilShortAssemName, filename) = + let resources = ilModule.Resources.AsList + let sigDataReaders = + [ for iresource in resources do + if IsSignatureDataResource iresource then + let ccuName = GetSignatureDataResourceName iresource + yield (ccuName, fun () -> iresource.GetBytes()) ] + + let sigDataReaders = + if sigDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then + let sigFileName = Path.ChangeExtension(filename, "sigdata") + if not (FileSystem.FileExistsShim sigFileName) then + error(Error(FSComp.SR.buildExpectedSigdataFile (FileSystem.GetFullPathShim sigFileName), m)) + [ (ilShortAssemName, fun () -> FileSystem.OpenFileForReadShim(sigFileName, useMemoryMappedFile=true, shouldShadowCopy=true).AsByteMemory().AsReadOnly())] + else + sigDataReaders + sigDataReaders + + member _.GetRawFSharpOptimizationData(m, ilShortAssemName, filename) = + let optDataReaders = + ilModule.Resources.AsList + |> List.choose (fun r -> if IsOptimizationDataResource r then Some(GetOptimizationDataResourceName r, (fun () -> r.GetBytes())) else None) + + // Look for optimization data in a file + let optDataReaders = + if optDataReaders.IsEmpty && List.contains ilShortAssemName externalSigAndOptData then + let optDataFile = Path.ChangeExtension(filename, "optdata") + if not (FileSystem.FileExistsShim optDataFile) then + error(Error(FSComp.SR.buildExpectedFileAlongSideFSharpCore(optDataFile, FileSystem.GetFullPathShim optDataFile), m)) + [ (ilShortAssemName, (fun () -> FileSystem.OpenFileForReadShim(optDataFile, useMemoryMappedFile=true, shouldShadowCopy=true).AsByteMemory().AsReadOnly()))] + else + optDataReaders + optDataReaders + + member _.GetRawTypeForwarders() = + match ilModule.Manifest with + | Some manifest -> manifest.ExportedTypes + | None -> mkILExportedTypes [] + + member _.ShortAssemblyName = GetNameOfILModule ilModule + + member _.ILScopeRef = MakeScopeRefForILModule ilModule + + member _.ILAssemblyRefs = ilAssemblyRefs + + member _.HasAnyFSharpSignatureDataAttribute = + let attrs = GetCustomAttributesOfILModule ilModule + List.exists IsSignatureDataVersionAttr attrs + + member _.HasMatchingFSharpSignatureDataAttribute = + let attrs = GetCustomAttributesOfILModule ilModule + List.exists (IsMatchingSignatureDataVersionAttr (parseILVersion FSharpBinaryMetadataFormatRevision)) attrs + +[] +type RawFSharpAssemblyData (ilModule: ILModuleDef, ilAssemblyRefs) = + + interface IRawFSharpAssemblyData with + + member _.GetAutoOpenAttributes() = GetAutoOpenAttributes ilModule + + member _.GetInternalsVisibleToAttributes() = GetInternalsVisibleToAttributes ilModule + + member _.TryGetILModuleDef() = Some ilModule + + member _.GetRawFSharpSignatureData(_, _, _) = + let resources = ilModule.Resources.AsList + [ for iresource in resources do + if IsSignatureDataResource iresource then + let ccuName = GetSignatureDataResourceName iresource + yield (ccuName, fun () -> iresource.GetBytes()) ] + + member _.GetRawFSharpOptimizationData(_, _, _) = + ilModule.Resources.AsList + |> List.choose (fun r -> if IsOptimizationDataResource r then Some(GetOptimizationDataResourceName r, (fun () -> r.GetBytes())) else None) + + member _.GetRawTypeForwarders() = + match ilModule.Manifest with + | Some manifest -> manifest.ExportedTypes + | None -> mkILExportedTypes [] + + member _.ShortAssemblyName = GetNameOfILModule ilModule + + member _.ILScopeRef = MakeScopeRefForILModule ilModule + + member _.ILAssemblyRefs = ilAssemblyRefs + + member _.HasAnyFSharpSignatureDataAttribute = + let attrs = GetCustomAttributesOfILModule ilModule + List.exists IsSignatureDataVersionAttr attrs + + member _.HasMatchingFSharpSignatureDataAttribute = + let attrs = GetCustomAttributesOfILModule ilModule + List.exists (IsMatchingSignatureDataVersionAttr (parseILVersion FSharpBinaryMetadataFormatRevision)) attrs + +//---------------------------------------------------------------------------- +// TcImports +//-------------------------------------------------------------------------- + +[] +type TcImportsSafeDisposal(tciLock: TcImportsLock, disposeActions: ResizeArray unit>,disposeTypeProviderActions: ResizeArray unit>) = + + let mutable isDisposed = false + + let dispose () = + tciLock.AcquireLock (fun tcitok -> + + RequireTcImportsLock (tcitok, isDisposed) + RequireTcImportsLock (tcitok, disposeTypeProviderActions) + RequireTcImportsLock (tcitok, disposeActions) + + // disposing deliberately only closes this tcImports, not the ones up the chain + isDisposed <- true + if verbose then + dprintf "disposing of TcImports, %d binaries\n" disposeActions.Count + + let actions1 = disposeTypeProviderActions |> Seq.toArray + let actions2 = disposeActions |> Seq.toArray + + disposeTypeProviderActions.Clear() + disposeActions.Clear() + + for action in actions1 do action() + for action in actions2 do action() + ) + + override _.Finalize() = + dispose () + + interface IDisposable with + + member this.Dispose() = + if not isDisposed then + GC.SuppressFinalize this + dispose () + +#if !NO_EXTENSIONTYPING +// These are hacks in order to allow TcImports to be held as a weak reference inside a type provider. +// The reason is due to older type providers compiled using an older TypeProviderSDK, that SDK used reflection on fields and properties to determine the contract. +// The reflection code has now since been removed, see here: https://github.com/fsprojects/FSharp.TypeProviders.SDK/pull/305. But we still need to work on older type providers. +// One day we can remove these hacks when we deemed most if not all type providers were re-compiled using the newer TypeProviderSDK. +// Yuck. +type TcImportsDllInfoHack = + { + FileName: string + } + +and TcImportsWeakHack (tciLock: TcImportsLock, tcImports: WeakReference) = + let mutable dllInfos: TcImportsDllInfoHack list = [] + + member _.SetDllInfos (value: ImportedBinary list) = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, dllInfos) + dllInfos <- value |> List.map (fun x -> { FileName = x.FileName }) + + member _.Base: TcImportsWeakHack option = + match tcImports.TryGetTarget() with + | true, strong -> + match strong.Base with + | Some (baseTcImports: TcImports) -> + Some baseTcImports.Weak + | _ -> + None + | _ -> + None + + member _.SystemRuntimeContainsType typeName = + match tcImports.TryGetTarget () with + | true, strong -> strong.SystemRuntimeContainsType typeName + | _ -> false +#endif +/// Represents a table of imported assemblies with their resolutions. +/// Is a disposable object, but it is recommended not to explicitly call Dispose unless you absolutely know nothing will be using its contents after the disposal. +/// Otherwise, simply allow the GC to collect this and it will properly call Dispose from the finalizer. +and [] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolutions, importsBase: TcImports option, dependencyProviderOpt: DependencyProvider option) +#if !NO_EXTENSIONTYPING + as this +#endif + = + + let tciLock = TcImportsLock() + + //---- Start protected by tciLock ------- + let mutable resolutions = initialResolutions + let mutable dllInfos: ImportedBinary list = [] + let mutable dllTable: NameMap = NameMap.empty + let mutable ccuInfos: ImportedAssembly list = [] + let mutable ccuTable: NameMap = NameMap.empty + let mutable ccuThunks = ResizeArray unit)>() + let disposeActions = ResizeArray() + let disposeTypeProviderActions = ResizeArray() + +#if !NO_EXTENSIONTYPING + let mutable generatedTypeRoots = Dictionary() + let tcImportsWeak = TcImportsWeakHack (tciLock, WeakReference<_> this) +#endif + + let disposal = new TcImportsSafeDisposal(tciLock, disposeActions, disposeTypeProviderActions) + //---- End protected by tciLock ------- + + let mutable disposed = false // this doesn't need locking, it's only for debugging + let mutable tcGlobals = None // this doesn't need locking, it's set during construction of the TcImports + + let CheckDisposed() = + if disposed then assert false + + let dispose () = + CheckDisposed() + (disposal :> IDisposable).Dispose() + + // Get a snapshot of the current unFixedUp ccuThunks. + // for each of those thunks, remove them from the dictionary, so any parallel threads can't do this work + // If it successfully removed it from the dictionary then do the fixup + // If the thunk remains unresolved add it back to the ccuThunks dictionary for further processing + // If not then move on to the next thunk + let fixupOrphanCcus () = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, ccuThunks) + let contents = ccuThunks |> Seq.toArray + let unsuccessful = + [ for ccuThunk, func in contents do + if ccuThunk.IsUnresolvedReference then + func() + if ccuThunk.IsUnresolvedReference then + yield (ccuThunk, func) ] + ccuThunks <- ResizeArray unsuccessful + + let availableToOptionalCcu = function + | ResolvedCcu ccu -> Some ccu + | UnresolvedCcu _ -> None + + static let ccuHasType (ccu: CcuThunk) (nsname: string list) (tname: string) = + let matchNameSpace (entityOpt: Entity option) n = + match entityOpt with + | None -> None + | Some entity -> + entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind n + + match (Some ccu.Contents, nsname) ||> List.fold matchNameSpace with + | Some ns -> + match Map.tryFind tname ns.ModuleOrNamespaceType.TypesByMangledName with + | Some _ -> true + | None -> false + | None -> false + + member internal tcImports.Base = + CheckDisposed() + importsBase + + member tcImports.CcuTable = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, ccuTable) + CheckDisposed() + ccuTable + + member tcImports.DllTable = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, dllTable) + CheckDisposed() + dllTable + +#if !NO_EXTENSIONTYPING + member tcImports.Weak = + CheckDisposed() + tcImportsWeak +#endif + + member tcImports.RegisterCcu ccuInfo = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, ccuInfos) + RequireTcImportsLock(tcitok, ccuTable) + ccuInfos <- ccuInfos ++ ccuInfo + // Assembly Ref Resolution: remove this use of ccu.AssemblyName + ccuTable <- NameMap.add ccuInfo.FSharpViewOfMetadata.AssemblyName ccuInfo ccuTable + + member tcImports.RegisterDll dllInfo = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, dllInfos) + RequireTcImportsLock(tcitok, dllTable) + dllInfos <- dllInfos ++ dllInfo +#if !NO_EXTENSIONTYPING + tcImportsWeak.SetDllInfos dllInfos +#endif + dllTable <- NameMap.add (getNameOfScopeRef dllInfo.ILScopeRef) dllInfo dllTable + + member tcImports.GetDllInfos() : ImportedBinary list = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, dllInfos) + match importsBase with + | Some importsBase -> importsBase.GetDllInfos() @ dllInfos + | None -> dllInfos + + member tcImports.AllAssemblyResolutions() = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, resolutions) + let ars = resolutions.GetAssemblyResolutions() + match importsBase with + | Some importsBase-> importsBase.AllAssemblyResolutions() @ ars + | None -> ars + + member tcImports.TryFindDllInfo (ctok: CompilationThreadToken, m, assemblyName, lookupOnly) = + CheckDisposed() + let rec look (t: TcImports) = + match NameMap.tryFind assemblyName t.DllTable with + | Some res -> Some res + | None -> + match t.Base with + | Some t2 -> look t2 + | None -> None + match look tcImports with + | Some res -> Some res + | None -> + tcImports.ImplicitLoadIfAllowed(ctok, m, assemblyName, lookupOnly) + look tcImports + + member tcImports.FindDllInfo (ctok, m, assemblyName) = + match tcImports.TryFindDllInfo (ctok, m, assemblyName, lookupOnly=false) with + | Some res -> res + | None -> error(Error(FSComp.SR.buildCouldNotResolveAssembly assemblyName, m)) + + member tcImports.GetImportedAssemblies() = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, ccuInfos) + match importsBase with + | Some importsBase -> List.append (importsBase.GetImportedAssemblies()) ccuInfos + | None -> ccuInfos + + member tcImports.GetCcusExcludingBase() = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, ccuInfos) + ccuInfos |> List.map (fun x -> x.FSharpViewOfMetadata) + + member tcImports.GetCcusInDeclOrder() = + CheckDisposed() + List.map (fun x -> x.FSharpViewOfMetadata) (tcImports.GetImportedAssemblies()) + + // This is the main "assembly reference --> assembly" resolution routine. + member tcImports.FindCcuInfo (ctok, m, assemblyName, lookupOnly) = + CheckDisposed() + let rec look (t: TcImports) = + match NameMap.tryFind assemblyName t.CcuTable with + | Some res -> Some res + | None -> + match t.Base with + | Some t2 -> look t2 + | None -> None + + match look tcImports with + | Some res -> ResolvedImportedAssembly res + | None -> + tcImports.ImplicitLoadIfAllowed(ctok, m, assemblyName, lookupOnly) + match look tcImports with + | Some res -> ResolvedImportedAssembly res + | None -> UnresolvedImportedAssembly assemblyName + + member tcImports.FindCcu (ctok, m, assemblyName, lookupOnly) = + CheckDisposed() + match tcImports.FindCcuInfo(ctok, m, assemblyName, lookupOnly) with + | ResolvedImportedAssembly importedAssembly -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) + | UnresolvedImportedAssembly assemblyName -> UnresolvedCcu assemblyName + + member tcImports.FindCcuFromAssemblyRef(ctok, m, assemblyRef: ILAssemblyRef) = + CheckDisposed() + match tcImports.FindCcuInfo(ctok, m, assemblyRef.Name, lookupOnly=false) with + | ResolvedImportedAssembly importedAssembly -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) + | UnresolvedImportedAssembly _ -> UnresolvedCcu(assemblyRef.QualifiedName) + + member tcImports.TryFindXmlDocumentationInfo(assemblyName: string) = + CheckDisposed() + let rec look (t: TcImports) = + match NameMap.tryFind assemblyName t.CcuTable with + | Some res -> Some res + | None -> + match t.Base with + | Some t2 -> look t2 + | None -> None + + match look tcImports with + | Some res -> res.FSharpViewOfMetadata.Deref.XmlDocumentationInfo + | _ -> None + +#if !NO_EXTENSIONTYPING + member tcImports.GetProvidedAssemblyInfo(ctok, m, assembly: Tainted) = + let anameOpt = assembly.PUntaint((fun assembly -> match assembly with null -> None | a -> Some (a.GetName())), m) + match anameOpt with + | None -> false, None + | Some aname -> + let ilShortAssemName = aname.Name + match tcImports.FindCcu (ctok, m, ilShortAssemName, lookupOnly=true) with + | ResolvedCcu ccu -> + if ccu.IsProviderGenerated then + let dllinfo = tcImports.FindDllInfo(ctok, m, ilShortAssemName) + true, dllinfo.ProviderGeneratedStaticLinkMap + else + false, None + + | UnresolvedCcu _ -> + let g = tcImports.GetTcGlobals() + let ilScopeRef = ILScopeRef.Assembly (ILAssemblyRef.FromAssemblyName aname) + let fileName = aname.Name + ".dll" + let bytes = assembly.PApplyWithProvider((fun (assembly, provider) -> assembly.GetManifestModuleContents provider), m).PUntaint(id, m) + let tcConfig = tcConfigP.Get ctok + let ilModule, ilAssemblyRefs = + let opts: ILReaderOptions = + { reduceMemoryUsage = tcConfig.reduceMemoryUsage + pdbDirPath = None + metadataOnly = MetadataOnlyFlag.Yes + tryGetMetadataSnapshot = tcConfig.tryGetMetadataSnapshot } + let reader = OpenILModuleReaderFromBytes fileName bytes opts + reader.ILModuleDef, reader.ILAssemblyRefs + + let theActualAssembly = assembly.PUntaint((fun x -> x.Handle), m) + let dllinfo = + { RawMetadata= RawFSharpAssemblyDataBackedByFileOnDisk (ilModule, ilAssemblyRefs) + FileName=fileName + ProviderGeneratedAssembly=Some theActualAssembly + IsProviderGenerated=true + ProviderGeneratedStaticLinkMap= if g.isInteractive then None else Some (ProvidedAssemblyStaticLinkingMap.CreateNew()) + ILScopeRef = ilScopeRef + ILAssemblyRefs = ilAssemblyRefs } + tcImports.RegisterDll dllinfo + + let ccuContents = Construct.NewCcuContents ilScopeRef m ilShortAssemName (Construct.NewEmptyModuleOrNamespaceType Namespace) + + let ccuData: CcuData = + { IsFSharp=false + UsesFSharp20PlusQuotations=false + InvalidateEvent=(Event<_>()).Publish + IsProviderGenerated = true + QualifiedName= Some (assembly.PUntaint((fun a -> a.FullName), m)) + Contents = ccuContents + ILScopeRef = ilScopeRef + Stamp = newStamp() + SourceCodeDirectory = "" + FileName = Some fileName + MemberSignatureEquality = (fun ty1 ty2 -> typeEquivAux EraseAll g ty1 ty2) + ImportProvidedType = (fun ty -> ImportProvidedType (tcImports.GetImportMap()) m ty) + TryGetILModuleDef = (fun () -> Some ilModule) + TypeForwarders = Map.empty + XmlDocumentationInfo = + match tcConfig.xmlDocInfoLoader with + | Some xmlDocInfoLoader -> xmlDocInfoLoader.TryLoad(fileName, ilModule) + | _ -> None + } + + let ccu = CcuThunk.Create(ilShortAssemName, ccuData) + let ccuinfo = + { FSharpViewOfMetadata=ccu + ILScopeRef = ilScopeRef + AssemblyAutoOpenAttributes = [] + AssemblyInternalsVisibleToAttributes = [] + IsProviderGenerated = true + TypeProviders=[] + FSharpOptimizationData = notlazy None } + tcImports.RegisterCcu ccuinfo + // Yes, it is generative + true, dllinfo.ProviderGeneratedStaticLinkMap + + member tcImports.RecordGeneratedTypeRoot root = + tciLock.AcquireLock <| fun tcitok -> + // checking if given ProviderGeneratedType was already recorded before (probably for another set of static parameters) + let (ProviderGeneratedType(_, ilTyRef, _)) = root + let index = + RequireTcImportsLock(tcitok, generatedTypeRoots) + match generatedTypeRoots.TryGetValue ilTyRef with + | true, (index, _) -> index + | false, _ -> generatedTypeRoots.Count + generatedTypeRoots.[ilTyRef] <- (index, root) + + member tcImports.ProviderGeneratedTypeRoots = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, generatedTypeRoots) + generatedTypeRoots.Values + |> Seq.sortBy fst + |> Seq.map snd + |> Seq.toList +#endif + + member private tcImports.AttachDisposeAction action = + tciLock.AcquireLock <| fun tcitok -> + CheckDisposed() + RequireTcImportsLock(tcitok, disposeActions) + disposeActions.Add action + +#if !NO_EXTENSIONTYPING + member private tcImports.AttachDisposeTypeProviderAction action = + CheckDisposed() + disposeTypeProviderActions.Add action +#endif + + // Note: the returned binary reader is associated with the tcImports, i.e. when the tcImports are closed + // then the reader is closed. + member tcImports.OpenILBinaryModule(ctok, filename, m) = + try + CheckDisposed() + let tcConfig = tcConfigP.Get ctok + let pdbDirPath = + // We open the pdb file if one exists parallel to the binary we + // are reading, so that --standalone will preserve debug information. + if tcConfig.openDebugInformationForLaterStaticLinking then + let pdbDir = try FileSystem.GetDirectoryNameShim filename with _ -> "." + let pdbFile = (try FileSystemUtils.chopExtension filename with _ -> filename) + ".pdb" + + if FileSystem.FileExistsShim pdbFile then + if verbose then dprintf "reading PDB file %s from directory %s\n" pdbFile pdbDir + Some pdbDir + else + None + else + None + + let ilILBinaryReader = + OpenILBinary (filename, tcConfig.reduceMemoryUsage, pdbDirPath, tcConfig.shadowCopyReferences, tcConfig.tryGetMetadataSnapshot) + + tcImports.AttachDisposeAction(fun _ -> (ilILBinaryReader :> IDisposable).Dispose()) + ilILBinaryReader.ILModuleDef, ilILBinaryReader.ILAssemblyRefs + with e -> + error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), m)) + + (* auxModTable is used for multi-module assemblies *) + member tcImports.MkLoaderForMultiModuleILAssemblies ctok m = + CheckDisposed() + let auxModTable = HashMultiMap(10, HashIdentity.Structural) + fun viewedScopeRef -> + + let tcConfig = tcConfigP.Get ctok + match viewedScopeRef with + | ILScopeRef.Module modref -> + let key = modref.Name + if not (auxModTable.ContainsKey key) then + let resolution = tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, AssemblyReference(m, key, None)) |> Option.get + let ilModule, _ = tcImports.OpenILBinaryModule(ctok, resolution.resolvedPath, m) + auxModTable.[key] <- ilModule + auxModTable.[key] + + | _ -> + error(InternalError("Unexpected ILScopeRef.Local or ILScopeRef.Assembly in exported type table", m)) + + member tcImports.IsAlreadyRegistered nm = + CheckDisposed() + tcImports.GetDllInfos() |> List.exists (fun dll -> + match dll.ILScopeRef with + | ILScopeRef.Assembly a -> a.Name = nm + | _ -> false) + + member tcImports.DependencyProvider = + CheckDisposed() + match dependencyProviderOpt with + | None -> + Debug.Assert(false, "this should never be called on FrameworkTcImports") + new DependencyProvider(null, null) + | Some dependencyProvider -> dependencyProvider + + member tcImports.GetImportMap() = + CheckDisposed() + let loaderInterface = + { new AssemblyLoader with + member x.FindCcuFromAssemblyRef (ctok, m, ilAssemblyRef) = + tcImports.FindCcuFromAssemblyRef (ctok, m, ilAssemblyRef) + + member x.TryFindXmlDocumentationInfo assemblyName = + tcImports.TryFindXmlDocumentationInfo(assemblyName) + +#if !NO_EXTENSIONTYPING + member x.GetProvidedAssemblyInfo (ctok, m, assembly) = tcImports.GetProvidedAssemblyInfo (ctok, m, assembly) + member x.RecordGeneratedTypeRoot root = tcImports.RecordGeneratedTypeRoot root +#endif + } + ImportMap(tcImports.GetTcGlobals(), loaderInterface) + + // Note the tcGlobals are only available once mscorlib and fslib have been established. For TcImports, + // they are logically only needed when converting AbsIL data structures into F# data structures, and + // when converting AbsIL types in particular, since these types are normalized through the tables + // in the tcGlobals (E.g. normalizing 'System.Int32' to 'int'). On the whole ImportILAssembly doesn't + // actually convert AbsIL types - it only converts the outer shell of type definitions - the vast majority of + // types such as those in method signatures are currently converted on-demand. However ImportILAssembly does have to + // convert the types that are constraints in generic parameters, which was the original motivation for making sure that + // ImportILAssembly had a tcGlobals available when it really needs it. + member tcImports.GetTcGlobals() : TcGlobals = + CheckDisposed() + match tcGlobals with + | Some g -> g + | None -> + match importsBase with + | Some b -> b.GetTcGlobals() + | None -> failwith "unreachable: GetGlobals - are the references to mscorlib.dll and FSharp.Core.dll valid?" + + member private tcImports.SetTcGlobals g = + CheckDisposed() + tcGlobals <- Some g + +#if !NO_EXTENSIONTYPING + member private tcImports.InjectProvidedNamespaceOrTypeIntoEntity + (typeProviderEnvironment, + tcConfig: TcConfig, + m, entity: Entity, + injectedNamespace, remainingNamespace, + provider, + st: Tainted option) = + match remainingNamespace with + | next :: rest -> + // Inject the namespace entity + match entity.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind next with + | Some childEntity -> + tcImports.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, childEntity, next :: injectedNamespace, rest, provider, st) + | None -> + // Build up the artificial namespace if there is not a real one. + let cpath = CompPath(ILScopeRef.Local, injectedNamespace |> List.rev |> List.map (fun n -> (n, ModuleOrNamespaceKind.Namespace)) ) + let mid = ident (next, rangeStartup) + let mty = Construct.NewEmptyModuleOrNamespaceType Namespace + let newNamespace = Construct.NewModuleOrNamespace (Some cpath) taccessPublic mid XmlDoc.Empty [] (MaybeLazy.Strict mty) + entity.ModuleOrNamespaceType.AddModuleOrNamespaceByMutation newNamespace + tcImports.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, newNamespace, next :: injectedNamespace, rest, provider, st) + | [] -> + match st with + | Some st -> + // Inject the wrapper type into the provider assembly. + // + // Generated types get properly injected into the provided (i.e. generated) assembly CCU in tc.fs + + let importProvidedType t = ImportProvidedType (tcImports.GetImportMap()) m t + let isSuppressRelocate = tcConfig.isInteractive || st.PUntaint((fun st -> st.IsSuppressRelocate), m) + let newEntity = Construct.NewProvidedTycon(typeProviderEnvironment, st, importProvidedType, isSuppressRelocate, m) + entity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity + | None -> () + + entity.entity_tycon_repr <- + match entity.TypeReprInfo with + // This is the first extension + | TNoRepr -> + TProvidedNamespaceRepr(typeProviderEnvironment, [provider]) + + // Add to the existing list of extensions + | TProvidedNamespaceRepr(resolutionFolder, prior) as repr -> + if not(prior |> List.exists(fun r->Tainted.EqTainted r provider)) then + TProvidedNamespaceRepr(resolutionFolder, provider :: prior) + else + repr + + | _ -> failwith "Unexpected representation in namespace entity referred to by a type provider" + + member tcImportsStrong.ImportTypeProviderExtensions + (ctok, tcConfig: TcConfig, + fileNameOfRuntimeAssembly, + ilScopeRefOfRuntimeAssembly, + runtimeAssemblyAttributes: ILAttribute list, + entityToInjectInto, invalidateCcu: Event<_>, m) = + + let startingErrorCount = CompileThreadStatic.ErrorLogger.ErrorCount + + // Find assembly level TypeProviderAssemblyAttributes. These will point to the assemblies that + // have class which implement ITypeProvider and which have TypeProviderAttribute on them. + let designTimeAssemblyNames = + runtimeAssemblyAttributes + |> List.choose TryDecodeTypeProviderAssemblyAttr + // If no design-time assembly is specified, use the runtime assembly + |> List.map (function null -> fileNameOfRuntimeAssembly | s -> s) + // For each simple name of a design-time assembly, we take the first matching one in the order they are + // specified in the attributes + |> List.distinctBy (fun s -> try Path.GetFileNameWithoutExtension s with _ -> s) + + if not (List.isEmpty designTimeAssemblyNames) then + + // Find the SystemRuntimeAssemblyVersion value to report in the TypeProviderConfig. + let primaryAssemblyVersion = + let primaryAssemblyRef = tcConfig.PrimaryAssemblyDllReference() + let resolution = tcConfig.ResolveLibWithDirectories (CcuLoadFailureAction.RaiseError, primaryAssemblyRef) |> Option.get + // MSDN: this method causes the file to be opened and closed, but the assembly is not added to this domain + let name = System.Reflection.AssemblyName.GetAssemblyName(resolution.resolvedPath) + name.Version + + let typeProviderEnvironment = + { resolutionFolder = tcConfig.implicitIncludeDir + outputFile = tcConfig.outputFile + showResolutionMessages = tcConfig.showExtensionTypeMessages + referencedAssemblies = Array.distinct [| for r in tcImportsStrong.AllAssemblyResolutions() -> r.resolvedPath |] + temporaryFolder = FileSystem.GetTempPathShim() } + + // The type provider should not hold strong references to disposed + // TcImport objects. So the callbacks provided in the type provider config + // dispatch via a thunk which gets set to a non-resource-capturing + // failing function when the object is disposed. + let systemRuntimeContainsType = + // NOTE: do not touch this, edit: but we did, we had no choice - TPs cannot hold a strong reference on TcImports "ever". + let tcImports = tcImportsWeak + let mutable systemRuntimeContainsTypeRef = fun typeName -> tcImports.SystemRuntimeContainsType typeName + tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> systemRuntimeContainsTypeRef <- fun _ -> raise (ObjectDisposedException("The type provider has been disposed"))) + fun arg -> systemRuntimeContainsTypeRef arg + + let providers = [ + for designTimeAssemblyName in designTimeAssemblyNames do + yield! GetTypeProvidersOfAssembly(fileNameOfRuntimeAssembly, + ilScopeRefOfRuntimeAssembly, + designTimeAssemblyName, + typeProviderEnvironment, + tcConfig.isInvalidationSupported, + tcConfig.isInteractive, + systemRuntimeContainsType, + primaryAssemblyVersion, + tcConfig.compilerToolPaths, + m) ] + // Note, type providers are disposable objects. The TcImports owns the provider objects - when/if it is disposed, the providers are disposed. + // We ignore all exceptions from provider disposal. + for provider in providers do + tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> + try + provider.PUntaintNoFailure(fun x -> x.Dispose()) + with e -> + ()) + + // Add the invalidation signal handlers to each provider + for provider in providers do + provider.PUntaint((fun tp -> + + // Register the type provider invalidation handler. + // + // We are explicit about what the handler closure captures to help reason about the + // lifetime of captured objects, especially in case the type provider instance gets leaked + // or keeps itself alive mistakenly, e.g. via some global state in the type provider instance. + // + // The closure captures + // 1. an Event value, ultimately this is made available in all CCus as ccu.InvalidateEvent + // 2. any handlers registered to ccu.InvalidateEvent + // 3. a message string + // + // Note that the invalidation handler does not explicitly capture the TcImports. + // The only place where handlers are registered is to ccu.InvalidateEvent is in IncrementalBuilder.fs. + + let capturedInvalidateCcu = invalidateCcu + let capturedMessage = "The provider '" + fileNameOfRuntimeAssembly + "' reported a change" + let handler = tp.Invalidate.Subscribe(fun _ -> capturedInvalidateCcu.Trigger capturedMessage) + + // When the TcImports is disposed we detach the invalidation callback + tcImportsStrong.AttachDisposeTypeProviderAction(fun () -> try handler.Dispose() with _ -> ())), m) + + match providers with + | [] -> + warning(Error(FSComp.SR.etHostingAssemblyFoundWithoutHosts(fileNameOfRuntimeAssembly, typeof.FullName), m)) + | _ -> + +#if DEBUG + if typeProviderEnvironment.showResolutionMessages then + dprintfn "Found extension type hosting hosting assembly '%s' with the following extensions:" fileNameOfRuntimeAssembly + providers |> List.iter(fun provider ->dprintfn " %s" (DisplayNameOfTypeProvider(provider.TypeProvider, m))) +#endif + + for provider in providers do + try + // Inject an entity for the namespace, or if one already exists, then record this as a provider + // for that namespace. + let rec loop (providedNamespace: Tainted) = + let path = GetProvidedNamespaceAsPath(m, provider, providedNamespace.PUntaint((fun r -> r.NamespaceName), m)) + tcImportsStrong.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, entityToInjectInto, [], path, provider, None) + + // Inject entities for the types returned by provider.GetTypes(). + // + // NOTE: The types provided by GetTypes() are available for name resolution + // when the namespace is "opened". This is part of the specification of the language + // feature. + let ptys = providedNamespace.PApplyArray(GetProvidedTypes, "GetTypes", m) + for st in ptys do + tcImportsStrong.InjectProvidedNamespaceOrTypeIntoEntity (typeProviderEnvironment, tcConfig, m, entityToInjectInto, [], path, provider, Some st) + + for providedNestedNamespace in providedNamespace.PApplyArray((fun provider -> provider.GetNestedNamespaces()), "GetNestedNamespaces", m) do + loop providedNestedNamespace + + RequireCompilationThread ctok // IProvidedType.GetNamespaces is an example of a type provider call + let providedNamespaces = provider.PApplyArray((fun r -> r.GetNamespaces()), "GetNamespaces", m) + + for providedNamespace in providedNamespaces do + loop providedNamespace + with e -> + errorRecovery e m + + if startingErrorCount Option.isSome + + // Add a referenced assembly + // + // Retargetable assembly refs are required for binaries that must run + // against DLLs supported by multiple publishers. For example + // Compact Framework binaries must use this. However it is not + // clear when else it is required, e.g. for Mono. + + member tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo: ImportedBinary) = + CheckDisposed() + let tcConfig = tcConfigP.Get ctok + assert dllinfo.RawMetadata.TryGetILModuleDef().IsSome + let ilModule = dllinfo.RawMetadata.TryGetILModuleDef().Value + let ilScopeRef = dllinfo.ILScopeRef + let aref = + match ilScopeRef with + | ILScopeRef.Assembly aref -> aref + | _ -> error(InternalError("PrepareToImportReferencedILAssembly: cannot reference .NET netmodules directly, reference the containing assembly instead", m)) + + let nm = aref.Name + if verbose then dprintn ("Converting IL assembly to F# data structures "+nm) + let auxModuleLoader = tcImports.MkLoaderForMultiModuleILAssemblies ctok m + let invalidateCcu = Event<_>() + let ccu = ImportILAssembly(tcImports.GetImportMap, m, auxModuleLoader, tcConfig.xmlDocInfoLoader, ilScopeRef, tcConfig.implicitIncludeDir, Some filename, ilModule, invalidateCcu.Publish) + + let ccuinfo = + { FSharpViewOfMetadata=ccu + ILScopeRef = ilScopeRef + AssemblyAutoOpenAttributes = GetAutoOpenAttributes ilModule + AssemblyInternalsVisibleToAttributes = GetInternalsVisibleToAttributes ilModule +#if !NO_EXTENSIONTYPING + IsProviderGenerated = false + TypeProviders = [] +#endif + FSharpOptimizationData = notlazy None } + tcImports.RegisterCcu ccuinfo + + let phase2 () = +#if !NO_EXTENSIONTYPING + ccuinfo.TypeProviders <- tcImports.ImportTypeProviderExtensions (ctok, tcConfig, filename, ilScopeRef, ilModule.ManifestOfAssembly.CustomAttrs.AsList, ccu.Contents, invalidateCcu, m) +#endif + [ResolvedImportedAssembly ccuinfo] + phase2 + + member tcImports.PrepareToImportReferencedFSharpAssembly (ctok, m, filename, dllinfo: ImportedBinary) = + CheckDisposed() +#if !NO_EXTENSIONTYPING + let tcConfig = tcConfigP.Get ctok +#endif + let ilModule = dllinfo.RawMetadata + let ilScopeRef = dllinfo.ILScopeRef + let ilShortAssemName = getNameOfScopeRef ilScopeRef + if verbose then dprintn ("Converting F# assembly to F# data structures "+(getNameOfScopeRef ilScopeRef)) + if verbose then dprintn ("Relinking interface info from F# assembly "+ilShortAssemName) + let optDataReaders = ilModule.GetRawFSharpOptimizationData(m, ilShortAssemName, filename) + + let ccuRawDataAndInfos = + ilModule.GetRawFSharpSignatureData(m, ilShortAssemName, filename) + |> List.map (fun (ccuName, sigDataReader) -> + let data = GetSignatureData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), sigDataReader) + + let optDatas = Map.ofList optDataReaders + + let minfo: PickledCcuInfo = data.RawData + let mspec = minfo.mspec + +#if !NO_EXTENSIONTYPING + let invalidateCcu = Event<_>() +#endif + + let codeDir = minfo.compileTimeWorkingDir + let ccuData: CcuData = + { ILScopeRef=ilScopeRef + Stamp = newStamp() + FileName = Some filename + QualifiedName= Some(ilScopeRef.QualifiedName) + SourceCodeDirectory = codeDir (* note: in some cases we fix up this information later *) + IsFSharp=true + Contents = mspec +#if !NO_EXTENSIONTYPING + InvalidateEvent=invalidateCcu.Publish + IsProviderGenerated = false + ImportProvidedType = (fun ty -> ImportProvidedType (tcImports.GetImportMap()) m ty) +#endif + TryGetILModuleDef = ilModule.TryGetILModuleDef + UsesFSharp20PlusQuotations = minfo.usesQuotations + MemberSignatureEquality= (fun ty1 ty2 -> typeEquivAux EraseAll (tcImports.GetTcGlobals()) ty1 ty2) + TypeForwarders = ImportILAssemblyTypeForwarders(tcImports.GetImportMap, m, ilModule.GetRawTypeForwarders()) + XmlDocumentationInfo = + match tcConfig.xmlDocInfoLoader, ilModule.TryGetILModuleDef() with + | Some xmlDocInfoLoader, Some ilModuleDef -> xmlDocInfoLoader.TryLoad(filename, ilModuleDef) + | _ -> None + } + + let ccu = CcuThunk.Create(ccuName, ccuData) + + let optdata = + lazy + (match Map.tryFind ccuName optDatas with + | None -> + if verbose then dprintf "*** no optimization data for CCU %s, was DLL compiled with --no-optimization-data??\n" ccuName + None + | Some info -> + let data = GetOptimizationData (filename, ilScopeRef, ilModule.TryGetILModuleDef(), info) + let fixupThunk () = data.OptionalFixup(fun nm -> availableToOptionalCcu(tcImports.FindCcu(ctok, m, nm, lookupOnly=false))) + + // Make a note of all ccuThunks that may still need to be fixed up when other dlls are loaded + tciLock.AcquireLock (fun tcitok -> + RequireTcImportsLock(tcitok, ccuThunks) + for ccuThunk in data.FixupThunks do + if ccuThunk.IsUnresolvedReference then + ccuThunks.Add(ccuThunk, fun () -> fixupThunk () |> ignore) + ) + + if verbose then dprintf "found optimization data for CCU %s\n" ccuName + Some (fixupThunk ())) + + let ccuinfo = + { FSharpViewOfMetadata=ccu + AssemblyAutoOpenAttributes = ilModule.GetAutoOpenAttributes() + AssemblyInternalsVisibleToAttributes = ilModule.GetInternalsVisibleToAttributes() + FSharpOptimizationData=optdata +#if !NO_EXTENSIONTYPING + IsProviderGenerated = false + TypeProviders = [] +#endif + ILScopeRef = ilScopeRef } + + let phase2() = +#if !NO_EXTENSIONTYPING + match ilModule.TryGetILModuleDef() with + | None -> () // no type providers can be used without a real IL Module present + | Some ilModule -> + let tps = tcImports.ImportTypeProviderExtensions (ctok, tcConfig, filename, ilScopeRef, ilModule.ManifestOfAssembly.CustomAttrs.AsList, ccu.Contents, invalidateCcu, m) + ccuinfo.TypeProviders <- tps +#else + () +#endif + data, ccuinfo, phase2) + + // Register all before relinking to cope with mutually-referential ccus + ccuRawDataAndInfos |> List.iter (p23 >> tcImports.RegisterCcu) + let phase2 () = + (* Relink *) + (* dprintf "Phase2: %s\n" filename; REMOVE DIAGNOSTICS *) + ccuRawDataAndInfos + |> List.iter (fun (data, _, _) -> + let fixupThunk () = data.OptionalFixup(fun nm -> availableToOptionalCcu(tcImports.FindCcu(ctok, m, nm, lookupOnly=false))) |> ignore + fixupThunk() + for ccuThunk in data.FixupThunks do + if ccuThunk.IsUnresolvedReference then + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, ccuThunks) + ccuThunks.Add(ccuThunk, fixupThunk) + ) +#if !NO_EXTENSIONTYPING + ccuRawDataAndInfos |> List.iter (fun (_, _, phase2) -> phase2()) +#endif + ccuRawDataAndInfos |> List.map p23 |> List.map ResolvedImportedAssembly + phase2 + + // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable. + member tcImports.TryRegisterAndPrepareToImportReferencedDll (ctok, r: AssemblyResolution) : NodeCode<(_ * (unit -> AvailableImportedAssembly list)) option> = + node { + CheckDisposed() + let m = r.originalReference.Range + let filename = r.resolvedPath + let! contentsOpt = + node { + match r.ProjectReference with + | Some ilb -> + return! ilb.EvaluateRawContents() + | None -> + return ProjectAssemblyDataResult.Unavailable true + } + + // If we have a project reference but did not get any valid contents, + // just return None and do not attempt to read elsewhere. + match contentsOpt with + | ProjectAssemblyDataResult.Unavailable false -> + return None + | _ -> + + let assemblyData = + match contentsOpt with + | ProjectAssemblyDataResult.Available ilb -> ilb + | ProjectAssemblyDataResult.Unavailable _ -> + let ilModule, ilAssemblyRefs = tcImports.OpenILBinaryModule(ctok, filename, m) + RawFSharpAssemblyDataBackedByFileOnDisk (ilModule, ilAssemblyRefs) :> IRawFSharpAssemblyData + + let ilShortAssemName = assemblyData.ShortAssemblyName + let ilScopeRef = assemblyData.ILScopeRef + + if tcImports.IsAlreadyRegistered ilShortAssemName then + let dllinfo = tcImports.FindDllInfo(ctok, m, ilShortAssemName) + let phase2() = [tcImports.FindCcuInfo(ctok, m, ilShortAssemName, lookupOnly=true)] + return Some(dllinfo, phase2) + else + let dllinfo = + { RawMetadata=assemblyData + FileName=filename +#if !NO_EXTENSIONTYPING + ProviderGeneratedAssembly=None + IsProviderGenerated=false + ProviderGeneratedStaticLinkMap = None +#endif + ILScopeRef = ilScopeRef + ILAssemblyRefs = assemblyData.ILAssemblyRefs } + tcImports.RegisterDll dllinfo + let phase2 = + if assemblyData.HasAnyFSharpSignatureDataAttribute then + if not assemblyData.HasMatchingFSharpSignatureDataAttribute then + errorR(Error(FSComp.SR.buildDifferentVersionMustRecompile filename, m)) + tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo) + else + try + tcImports.PrepareToImportReferencedFSharpAssembly (ctok, m, filename, dllinfo) + with e -> error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), m)) + else + tcImports.PrepareToImportReferencedILAssembly (ctok, m, filename, dllinfo) + return Some(dllinfo, phase2) + } + + // NOTE: When used in the Language Service this can cause the transitive checking of projects. Hence it must be cancellable. + member tcImports.RegisterAndImportReferencedAssemblies (ctok, nms: AssemblyResolution list) = + node { + CheckDisposed() + + let! results = + nms + |> List.map (fun nm -> + node { + try + return! tcImports.TryRegisterAndPrepareToImportReferencedDll (ctok, nm) + with e -> + errorR(Error(FSComp.SR.buildProblemReadingAssembly(nm.resolvedPath, e.Message), nm.originalReference.Range)) + return None + } + ) + |> NodeCode.Sequential + + let dllinfos, phase2s = results |> Array.choose id |> List.ofArray |> List.unzip + fixupOrphanCcus() + let ccuinfos = (List.collect (fun phase2 -> phase2()) phase2s) + return dllinfos, ccuinfos + } + + /// Note that implicit loading is not used for compilations from MSBuild, which passes ``--noframework`` + /// Implicit loading is done in non-cancellation mode. Implicit loading is never used in the language service, so + /// no cancellation is needed. + member tcImports.ImplicitLoadIfAllowed (ctok, m, assemblyName, lookupOnly) = + CheckDisposed() + // If the user is asking for the default framework then also try to resolve other implicit assemblies as they are discovered. + // Using this flag to mean 'allow implicit discover of assemblies'. + let tcConfig = tcConfigP.Get ctok + if not lookupOnly && tcConfig.implicitlyResolveAssemblies then + let tryFile speculativeFileName = + let foundFile = tcImports.TryResolveAssemblyReference (ctok, AssemblyReference (m, speculativeFileName, None), ResolveAssemblyReferenceMode.Speculative) + match foundFile with + | OkResult (warns, res) -> + ReportWarnings warns + tcImports.RegisterAndImportReferencedAssemblies(ctok, res) + |> NodeCode.RunImmediateWithoutCancellation + |> ignore + true + | ErrorResult (_warns, _err) -> + // Throw away warnings and errors - this is speculative loading + false + + if tryFile (assemblyName + ".dll") then () + else tryFile (assemblyName + ".exe") |> ignore + +#if !NO_EXTENSIONTYPING + member tcImports.TryFindProviderGeneratedAssemblyByName(ctok, assemblyName: string) : System.Reflection.Assembly option = + // The assembly may not be in the resolutions, but may be in the load set including EST injected assemblies + match tcImports.TryFindDllInfo (ctok, range0, assemblyName, lookupOnly=true) with + | Some res -> + // Provider-generated assemblies don't necessarily have an on-disk representation we can load. + res.ProviderGeneratedAssembly + | _ -> None +#endif + + /// Only used by F# Interactive + member tcImports.TryFindExistingFullyQualifiedPathBySimpleAssemblyName simpleAssemName : string option = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, resolutions) + resolutions.TryFindBySimpleAssemblyName simpleAssemName |> Option.map (fun r -> r.resolvedPath) + + /// Only used by F# Interactive + member tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(assemblyRef: ILAssemblyRef) : string option = + tciLock.AcquireLock <| fun tcitok -> + RequireTcImportsLock(tcitok, resolutions) + resolutions.TryFindByExactILAssemblyRef assemblyRef |> Option.map (fun r -> r.resolvedPath) + + member tcImports.TryResolveAssemblyReference(ctok, assemblyReference: AssemblyReference, mode: ResolveAssemblyReferenceMode) : OperationResult = + tciLock.AcquireLock <| fun tcitok -> + let tcConfig = tcConfigP.Get ctok + + RequireTcImportsLock(tcitok, resolutions) + // First try to lookup via the original reference text. + match resolutions.TryFindByOriginalReference assemblyReference with + | Some assemblyResolution -> + ResultD [assemblyResolution] + | None -> +#if NO_MSBUILD_REFERENCE_RESOLUTION + try + ResultD [tcConfig.ResolveLibWithDirectories assemblyReference] + with e -> + ErrorD e +#else + // Next try to lookup up by the exact full resolved path. + match resolutions.TryFindByResolvedPath assemblyReference.Text with + | Some assemblyResolution -> + ResultD [assemblyResolution] + | None -> + if tcConfigP.Get(ctok).useSimpleResolution then + let action = + match mode with + | ResolveAssemblyReferenceMode.ReportErrors -> CcuLoadFailureAction.RaiseError + | ResolveAssemblyReferenceMode.Speculative -> CcuLoadFailureAction.ReturnNone + match tcConfig.ResolveLibWithDirectories (action, assemblyReference) with + | Some resolved -> + resolutions <- resolutions.AddResolutionResults [resolved] + ResultD [resolved] + | None -> + ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) + else + // This is a previously unencountered assembly. Resolve it and add it to the list. + // But don't cache resolution failures because the assembly may appear on the disk later. + let resolved, unresolved = TcConfig.TryResolveLibsUsingMSBuildRules(tcConfig, [ assemblyReference ], assemblyReference.Range, mode) + match resolved, unresolved with + | assemblyResolution :: _, _ -> + resolutions <- resolutions.AddResolutionResults resolved + ResultD [assemblyResolution] + | _, _ :: _ -> + resolutions <- resolutions.AddUnresolvedReferences unresolved + ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) + | [], [] -> + // Note, if mode=ResolveAssemblyReferenceMode.Speculative and the resolution failed then TryResolveLibsUsingMSBuildRules returns + // the empty list and we convert the failure into an AssemblyNotResolved here. + ErrorD(AssemblyNotResolved(assemblyReference.Text, assemblyReference.Range)) +#endif + + member tcImports.ResolveAssemblyReference(ctok, assemblyReference, mode) : AssemblyResolution list = + CommitOperationResult(tcImports.TryResolveAssemblyReference(ctok, assemblyReference, mode)) + + // Note: This returns a TcImports object. However, framework TcImports are not currently disposed. The only reason + // we dispose TcImports is because we need to dispose type providers, and type providers are never included in the framework DLL set. + // If a framework set ever includes type providers, you will not have to worry about explicitly calling Dispose as the Finalizer will handle it. + static member BuildFrameworkTcImports (tcConfigP: TcConfigProvider, frameworkDLLs, nonFrameworkDLLs) = + node { + let ctok = CompilationThreadToken() + let tcConfig = tcConfigP.Get ctok + let tcResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(tcConfig, frameworkDLLs, []) + let tcAltResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(tcConfig, nonFrameworkDLLs, []) + + let frameworkTcImports = new TcImports(tcConfigP, tcResolutions, None, None) + + // Fetch the primaryAssembly from the referenced assemblies otherwise + let primaryAssemblyReference = + let path = frameworkDLLs |> List.tryFind(fun dll -> String.Compare(Path.GetFileNameWithoutExtension(dll.resolvedPath), tcConfig.primaryAssembly.Name, StringComparison.OrdinalIgnoreCase) = 0) + match path with + | Some p -> AssemblyReference(range0, p.resolvedPath, None) + | None -> tcConfig.PrimaryAssemblyDllReference() + + let primaryAssemblyResolution = frameworkTcImports.ResolveAssemblyReference(ctok, primaryAssemblyReference, ResolveAssemblyReferenceMode.ReportErrors) + let! primaryAssem = frameworkTcImports.RegisterAndImportReferencedAssemblies(ctok, primaryAssemblyResolution) + let primaryScopeRef = + match primaryAssem with + | _, [ResolvedImportedAssembly ccu] -> ccu.FSharpViewOfMetadata.ILScopeRef + | _ -> failwith "unexpected" + + let primaryAssemblyResolvedPath = + match primaryAssemblyResolution with + | [primaryAssemblyResolution] -> primaryAssemblyResolution.resolvedPath + | _ -> failwith "unexpected" + + let resolvedAssemblies = tcResolutions.GetAssemblyResolutions() + + let readerSettings: ILReaderOptions = + { pdbDirPath=None + reduceMemoryUsage = tcConfig.reduceMemoryUsage + metadataOnly = MetadataOnlyFlag.Yes + tryGetMetadataSnapshot = tcConfig.tryGetMetadataSnapshot } + + let tryFindAssemblyByExportedType manifest (exportedType: ILExportedTypeOrForwarder) = + match exportedType.ScopeRef, primaryScopeRef with + | ILScopeRef.Assembly aref1, ILScopeRef.Assembly aref2 when aref1.EqualsIgnoringVersion aref2 -> + mkRefToILAssembly manifest + |> Some + | _ -> + None + + let tryFindAssemblyThatForwardsToPrimaryAssembly manifest = + manifest.ExportedTypes.TryFindByName "System.Object" + |> Option.bind (tryFindAssemblyByExportedType manifest) + + // Determine what other assemblies could have been the primary assembly + // by checking to see if "System.Object" is an exported type. + let assembliesThatForwardToPrimaryAssembly = + resolvedAssemblies + |> List.choose (fun resolvedAssembly -> + if primaryAssemblyResolvedPath <> resolvedAssembly.resolvedPath then + let reader = OpenILModuleReader resolvedAssembly.resolvedPath readerSettings + reader.ILModuleDef.Manifest + |> Option.bind tryFindAssemblyThatForwardsToPrimaryAssembly + else + None) + + let! fslibCcu, fsharpCoreAssemblyScopeRef = + node { + if tcConfig.compilingFslib then + // When compiling FSharp.Core.dll, the fslibCcu reference to FSharp.Core.dll is a delayed ccu thunk fixed up during type checking + return CcuThunk.CreateDelayed getFSharpCoreLibraryName, ILScopeRef.Local + else + let coreLibraryReference = tcConfig.CoreLibraryDllReference() + + let resolvedAssemblyRef = + match tcResolutions.TryFindByOriginalReference coreLibraryReference with + | Some resolution -> Some resolution + | _ -> + // Are we using a "non-canonical" FSharp.Core? + match tcAltResolutions.TryFindByOriginalReference coreLibraryReference with + | Some resolution -> Some resolution + | _ -> tcResolutions.TryFindByOriginalReferenceText getFSharpCoreLibraryName // was the ".dll" elided? + + match resolvedAssemblyRef with + | Some coreLibraryResolution -> + match! frameworkTcImports.RegisterAndImportReferencedAssemblies(ctok, [coreLibraryResolution]) with + | _, [ResolvedImportedAssembly fslibCcuInfo ] -> return fslibCcuInfo.FSharpViewOfMetadata, fslibCcuInfo.ILScopeRef + | _ -> + return error(InternalError("BuildFrameworkTcImports: no successful import of "+coreLibraryResolution.resolvedPath, coreLibraryResolution.originalReference.Range)) + | None -> + return error(InternalError(sprintf "BuildFrameworkTcImports: no resolution of '%s'" coreLibraryReference.Text, rangeStartup)) + } + + // Load the rest of the framework DLLs all at once (they may be mutually recursive) + let! _assemblies = frameworkTcImports.RegisterAndImportReferencedAssemblies (ctok, resolvedAssemblies) + + // These are the DLLs we can search for well-known types + let sysCcus = + [| for ccu in frameworkTcImports.GetCcusInDeclOrder() do + yield ccu |] + + let tryFindSysTypeCcu path typeName = + sysCcus |> Array.tryFind (fun ccu -> ccuHasType ccu path typeName) + + let ilGlobals = mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef) + + // OK, now we have both mscorlib.dll and FSharp.Core.dll we can create TcGlobals + let tcGlobals = TcGlobals(tcConfig.compilingFslib, ilGlobals, fslibCcu, + tcConfig.implicitIncludeDir, tcConfig.mlCompatibility, + tcConfig.isInteractive, tryFindSysTypeCcu, tcConfig.emitDebugInfoInQuotations, + tcConfig.noDebugData, tcConfig.pathMap, tcConfig.langVersion) + +#if DEBUG + // the global_g reference cell is used only for debug printing + global_g <- Some tcGlobals +#endif + frameworkTcImports.SetTcGlobals tcGlobals + return tcGlobals, frameworkTcImports + } + + member tcImports.ReportUnresolvedAssemblyReferences knownUnresolved = + // Report that an assembly was not resolved. + let reportAssemblyNotResolved(file, originalReferences: AssemblyReference list) = + originalReferences |> List.iter(fun originalReference -> errorR(AssemblyNotResolved(file, originalReference.Range))) + knownUnresolved + |> List.map (function UnresolvedAssemblyReference(file, originalReferences) -> file, originalReferences) + |> List.iter reportAssemblyNotResolved + + static member BuildNonFrameworkTcImports + (tcConfigP: TcConfigProvider, baseTcImports, + nonFrameworkReferences, knownUnresolved, dependencyProvider) = + + node { + let ctok = CompilationThreadToken() + let tcConfig = tcConfigP.Get ctok + let tcResolutions = TcAssemblyResolutions.BuildFromPriorResolutions(tcConfig, nonFrameworkReferences, knownUnresolved) + let references = tcResolutions.GetAssemblyResolutions() + let tcImports = new TcImports(tcConfigP, tcResolutions, Some baseTcImports, Some dependencyProvider) + let! _assemblies = tcImports.RegisterAndImportReferencedAssemblies(ctok, references) + tcImports.ReportUnresolvedAssemblyReferences knownUnresolved + return tcImports + } + + static member BuildTcImports(tcConfigP: TcConfigProvider, dependencyProvider) = + node { + let ctok = CompilationThreadToken() + let tcConfig = tcConfigP.Get ctok + let frameworkDLLs, nonFrameworkReferences, knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(tcConfig) + let! tcGlobals, frameworkTcImports = TcImports.BuildFrameworkTcImports (tcConfigP, frameworkDLLs, nonFrameworkReferences) + let! tcImports = TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, nonFrameworkReferences, knownUnresolved, dependencyProvider) + return tcGlobals, tcImports + } + + interface IDisposable with + member tcImports.Dispose() = + dispose () + + override tcImports.ToString() = "TcImports(...)" + +/// Process #r in F# Interactive. +/// Adds the reference to the tcImports and add the ccu to the type checking environment. +let RequireDLL (ctok, tcImports: TcImports, tcEnv, thisAssemblyName, referenceRange, file) = + let resolutions = CommitOperationResult(tcImports.TryResolveAssemblyReference(ctok, AssemblyReference(referenceRange, file, None), ResolveAssemblyReferenceMode.ReportErrors)) + let dllinfos, ccuinfos = + tcImports.RegisterAndImportReferencedAssemblies(ctok, resolutions) + |> NodeCode.RunImmediateWithoutCancellation + + let asms = + ccuinfos |> List.map (function + | ResolvedImportedAssembly asm -> asm + | UnresolvedImportedAssembly assemblyName -> error(Error(FSComp.SR.buildCouldNotResolveAssemblyRequiredByFile(assemblyName, file), referenceRange))) + + let g = tcImports.GetTcGlobals() + let amap = tcImports.GetImportMap() + let _openDecls, tcEnv = (tcEnv, asms) ||> List.collectFold (fun tcEnv asm -> AddCcuToTcEnv(g, amap, referenceRange, tcEnv, thisAssemblyName, asm.FSharpViewOfMetadata, asm.AssemblyAutoOpenAttributes, asm.AssemblyInternalsVisibleToAttributes)) + tcEnv, (dllinfos, asms) diff --git a/src/fsharp/CompilerImports.fsi b/src/fsharp/CompilerImports.fsi new file mode 100644 index 00000000000..4b91bb7c52d --- /dev/null +++ b/src/fsharp/CompilerImports.fsi @@ -0,0 +1,214 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to coordinate assembly resolution and manage the TcImports table of referenced +/// assemblies. +module internal FSharp.Compiler.CompilerImports + +open System +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Optimizer +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.BuildGraph +open FSharp.Compiler.Text +open FSharp.Core.CompilerServices + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +/// This exception is an old-style way of reporting a diagnostic +exception AssemblyNotResolved of (*originalName*) string * range + +/// This exception is an old-style way of reporting a diagnostic +exception MSBuildReferenceResolutionWarning of (*MSBuild warning code*)string * (*Message*)string * range + +/// This exception is an old-style way of reporting a diagnostic +exception MSBuildReferenceResolutionError of (*MSBuild warning code*)string * (*Message*)string * range + +/// Determine if an IL resource attached to an F# assembly is an F# signature data resource +val IsSignatureDataResource: ILResource -> bool + +/// Determine if an IL resource attached to an F# assembly is an F# optimization data resource +val IsOptimizationDataResource: ILResource -> bool + +/// Determine if an IL resource attached to an F# assembly is an F# quotation data resource for reflected definitions +val IsReflectedDefinitionsResource: ILResource -> bool + +val GetSignatureDataResourceName: ILResource -> string + +/// Encode the F# interface data into a set of IL attributes and resources +val EncodeSignatureData: + tcConfig:TcConfig * + tcGlobals:TcGlobals * + exportRemapping:Remap * + generatedCcu: CcuThunk * + outfile: string * + isIncrementalBuild: bool + -> ILAttribute list * ILResource list + +val EncodeOptimizationData: + tcGlobals:TcGlobals * + tcConfig:TcConfig * + outfile: string * + exportRemapping:Remap * + (CcuThunk * #CcuOptimizationInfo) * + isIncrementalBuild: bool + -> ILResource list + +[] +type ResolveAssemblyReferenceMode = + | Speculative + | ReportErrors + +type AssemblyResolution = + { /// The original reference to the assembly. + originalReference: AssemblyReference + + /// Path to the resolvedFile + resolvedPath: string + + /// Create the tooltip text for the assembly reference + prepareToolTip: unit -> string + + /// Whether or not this is an installed system assembly (for example, System.dll) + sysdir: bool + + /// Lazily populated ilAssemblyRef for this reference. + mutable ilAssemblyRef: ILAssemblyRef option + } + +#if !NO_EXTENSIONTYPING +type ResolvedExtensionReference = ResolvedExtensionReference of string * AssemblyReference list * Tainted list +#endif + +/// Represents a resolved imported binary +[] +type ImportedBinary = + { FileName: string + RawMetadata: IRawFSharpAssemblyData +#if !NO_EXTENSIONTYPING + ProviderGeneratedAssembly: System.Reflection.Assembly option + IsProviderGenerated: bool + ProviderGeneratedStaticLinkMap: ProvidedAssemblyStaticLinkingMap option +#endif + ILAssemblyRefs: ILAssemblyRef list + ILScopeRef: ILScopeRef} + +/// Represents a resolved imported assembly +[] +type ImportedAssembly = + { ILScopeRef: ILScopeRef + FSharpViewOfMetadata: CcuThunk + AssemblyAutoOpenAttributes: string list + AssemblyInternalsVisibleToAttributes: string list +#if !NO_EXTENSIONTYPING + IsProviderGenerated: bool + mutable TypeProviders: Tainted list +#endif + FSharpOptimizationData: Lazy> + } + + +[] +/// Tables of assembly resolutions +type TcAssemblyResolutions = + + member GetAssemblyResolutions: unit -> AssemblyResolution list + + static member SplitNonFoundationalResolutions: tcConfig: TcConfig -> AssemblyResolution list * AssemblyResolution list * UnresolvedAssemblyReference list + + static member BuildFromPriorResolutions: tcConfig: TcConfig * AssemblyResolution list * UnresolvedAssemblyReference list -> TcAssemblyResolutions + + static member GetAssemblyResolutionInformation: tcConfig: TcConfig -> AssemblyResolution list * UnresolvedAssemblyReference list + +[] +type RawFSharpAssemblyData = + + new : ilModule: ILModuleDef * ilAssemblyRefs: ILAssemblyRef list -> RawFSharpAssemblyData + + interface IRawFSharpAssemblyData + +/// Represents a table of imported assemblies with their resolutions. +/// Is a disposable object, but it is recommended not to explicitly call Dispose unless you absolutely know nothing will be using its contents after the disposal. +/// Otherwise, simply allow the GC to collect this and it will properly call Dispose from the finalizer. +[] +type TcImports = + interface IDisposable + //new: TcImports option -> TcImports + member DllTable: NameMap with get + + member GetImportedAssemblies: unit -> ImportedAssembly list + + member GetCcusInDeclOrder: unit -> CcuThunk list + + /// This excludes any framework imports (which may be shared between multiple builds) + member GetCcusExcludingBase: unit -> CcuThunk list + + member FindDllInfo: CompilationThreadToken * range * string -> ImportedBinary + + member TryFindDllInfo: CompilationThreadToken * range * string * lookupOnly: bool -> option + + member FindCcuFromAssemblyRef: CompilationThreadToken * range * ILAssemblyRef -> CcuResolutionResult + +#if !NO_EXTENSIONTYPING + member ProviderGeneratedTypeRoots: ProviderGeneratedType list +#endif + + member GetImportMap: unit -> Import.ImportMap + + member DependencyProvider: DependencyProvider + + /// Try to resolve a referenced assembly based on TcConfig settings. + member TryResolveAssemblyReference: CompilationThreadToken * AssemblyReference * ResolveAssemblyReferenceMode -> OperationResult + + /// Resolve a referenced assembly and report an error if the resolution fails. + member ResolveAssemblyReference: CompilationThreadToken * AssemblyReference * ResolveAssemblyReferenceMode -> AssemblyResolution list + + /// Try to find the given assembly reference by simple name. Used in magic assembly resolution. Effectively does implicit + /// unification of assemblies by simple assembly name. + member TryFindExistingFullyQualifiedPathBySimpleAssemblyName: string -> string option + + /// Try to find the given assembly reference. + member TryFindExistingFullyQualifiedPathByExactAssemblyRef: ILAssemblyRef -> string option + +#if !NO_EXTENSIONTYPING + /// Try to find a provider-generated assembly + member TryFindProviderGeneratedAssemblyByName: CompilationThreadToken * assemblyName:string -> System.Reflection.Assembly option +#endif + /// Report unresolved references that also weren't consumed by any type providers. + member ReportUnresolvedAssemblyReferences: UnresolvedAssemblyReference list -> unit + + member SystemRuntimeContainsType: string -> bool + + member internal Base: TcImports option + + static member BuildFrameworkTcImports: + TcConfigProvider * + AssemblyResolution list * + AssemblyResolution list + -> NodeCode + + static member BuildNonFrameworkTcImports: + TcConfigProvider * + TcImports * + AssemblyResolution list * + UnresolvedAssemblyReference list * + DependencyProvider + -> NodeCode + + static member BuildTcImports: + tcConfigP: TcConfigProvider * + dependencyProvider: DependencyProvider + -> NodeCode + +/// Process #r in F# Interactive. +/// Adds the reference to the tcImports and add the ccu to the type checking environment. +val RequireDLL: ctok: CompilationThreadToken * tcImports: TcImports * tcEnv: TcEnv * thisAssemblyName: string * referenceRange: range * file: string -> TcEnv * (ImportedBinary list * ImportedAssembly list) diff --git a/src/fsharp/CompilerOptions.fs b/src/fsharp/CompilerOptions.fs new file mode 100644 index 00000000000..0cf6ece074f --- /dev/null +++ b/src/fsharp/CompilerOptions.fs @@ -0,0 +1,1740 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// # FSComp.SR.opts + +module internal FSharp.Compiler.CompilerOptions + +open System +open System.IO +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILPdbWriter +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Features +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.ErrorLogger + +open Internal.Utilities + +module Attributes = + open System.Runtime.CompilerServices + + //[] + [] + do() + +//---------------------------------------------------------------------------- +// Compiler option parser +// +// The argument parser is used by both the VS plug-in and the fsc.exe to +// parse the include file path and other front-end arguments. +// +// The language service uses this function too. It's important to continue +// processing flags even if an error is seen in one so that the best possible +// intellisense can be show. +//-------------------------------------------------------------------------- + +[] +type OptionSwitch = + | On + | Off + +type OptionSpec = + | OptionClear of bool ref + | OptionFloat of (float -> unit) + | OptionInt of (int -> unit) + | OptionSwitch of (OptionSwitch -> unit) + | OptionIntList of (int -> unit) + | OptionIntListSwitch of (int -> OptionSwitch -> unit) + | OptionRest of (string -> unit) + | OptionSet of bool ref + | OptionString of (string -> unit) + | OptionStringList of (string -> unit) + | OptionStringListSwitch of (string -> OptionSwitch -> unit) + | OptionUnit of (unit -> unit) + | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" + | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) + +and CompilerOption = CompilerOption of name: string * argumentDescriptionString: string * actionSpec: OptionSpec * deprecationError: Option * helpText: string option +and CompilerOptionBlock = PublicOptions of heading: string * options: CompilerOption list | PrivateOptions of options: CompilerOption list + +let GetOptionsOfBlock block = + match block with + | PublicOptions (_, opts) -> opts + | PrivateOptions opts -> opts + +let FilterCompilerOptionBlock pred block = + match block with + | PublicOptions(heading, opts) -> PublicOptions(heading, List.filter pred opts) + | PrivateOptions opts -> PrivateOptions(List.filter pred opts) + +let compilerOptionUsage (CompilerOption(s, tag, spec, _, _)) = + let s = if s="--" then "" else s (* s="flag" for "--flag" options. s="--" for "--" option. Adjust printing here for "--" case. *) + match spec with + | OptionUnit _ | OptionSet _ | OptionClear _ | OptionHelp _ -> sprintf "--%s" s + | OptionStringList _ -> sprintf "--%s:%s" s tag + | OptionIntList _ -> sprintf "--%s:%s" s tag + | OptionSwitch _ -> sprintf "--%s[+|-]" s + | OptionStringListSwitch _ -> sprintf "--%s[+|-]:%s" s tag + | OptionIntListSwitch _ -> sprintf "--%s[+|-]:%s" s tag + | OptionString _ -> sprintf "--%s:%s" s tag + | OptionInt _ -> sprintf "--%s:%s" s tag + | OptionFloat _ -> sprintf "--%s:%s" s tag + | OptionRest _ -> sprintf "--%s ..." s + | OptionGeneral _ -> if tag="" then sprintf "%s" s else sprintf "%s:%s" s tag (* still being decided *) + +let PrintCompilerOption (CompilerOption(_s, _tag, _spec, _, help) as compilerOption) = + let flagWidth = 42 // fixed width for printing of flags, e.g. --debug:{full|pdbonly|portable|embedded} + let defaultLineWidth = 80 // the fallback width + let lineWidth = + try + Console.BufferWidth + with e -> defaultLineWidth + let lineWidth = if lineWidth=0 then defaultLineWidth else lineWidth (* Have seen BufferWidth=0 on Linux/Mono *) + // Lines have this form: + // flagWidth chars - for flags description or padding on continuation lines. + // single space - space. + // description - words upto but excluding the final character of the line. + printf "%-40s" (compilerOptionUsage compilerOption) + let printWord column (word:string) = + // Have printed upto column. + // Now print the next word including any preceding whitespace. + // Returns the column printed to (suited to folding). + if column + 1 (*space*) + word.Length >= lineWidth then // NOTE: "equality" ensures final character of the line is never printed + printfn "" (* newline *) + printf "%-40s %s" ""(*<--flags*) word + flagWidth + 1 + word.Length + else + printf " %s" word + column + 1 + word.Length + let words = match help with None -> [| |] | Some s -> s.Split [| ' ' |] + let _finalColumn = Array.fold printWord flagWidth words + printfn "" (* newline *) + +let PrintPublicOptions (heading, opts) = + if not (isNil opts) then + printfn "" + printfn "" + printfn "\t\t%s" heading + List.iter PrintCompilerOption opts + +let PrintCompilerOptionBlocks blocks = + let equals x y = x=y + let publicBlocks = List.choose (function PrivateOptions _ -> None | PublicOptions (heading, opts) -> Some (heading, opts)) blocks + let consider doneHeadings (heading, _opts) = + if Set.contains heading doneHeadings then + doneHeadings + else + let headingOptions = List.filter (fst >> equals heading) publicBlocks |> List.collect snd + PrintPublicOptions (heading, headingOptions) + Set.add heading doneHeadings + List.fold consider Set.empty publicBlocks |> ignore> + +(* For QA *) +let dumpCompilerOption prefix (CompilerOption(str, _, spec, _, _)) = + printf "section='%-25s' ! option=%-30s kind=" prefix str + match spec with + | OptionUnit _ -> printf "OptionUnit" + | OptionSet _ -> printf "OptionSet" + | OptionClear _ -> printf "OptionClear" + | OptionHelp _ -> printf "OptionHelp" + | OptionStringList _ -> printf "OptionStringList" + | OptionIntList _ -> printf "OptionIntList" + | OptionSwitch _ -> printf "OptionSwitch" + | OptionStringListSwitch _ -> printf "OptionStringListSwitch" + | OptionIntListSwitch _ -> printf "OptionIntListSwitch" + | OptionString _ -> printf "OptionString" + | OptionInt _ -> printf "OptionInt" + | OptionFloat _ -> printf "OptionFloat" + | OptionRest _ -> printf "OptionRest" + | OptionGeneral _ -> printf "OptionGeneral" + printf "\n" +let dumpCompilerOptionBlock = function + | PublicOptions (heading, opts) -> List.iter (dumpCompilerOption heading) opts + | PrivateOptions opts -> List.iter (dumpCompilerOption "NoSection") opts +let DumpCompilerOptionBlocks blocks = List.iter dumpCompilerOptionBlock blocks + +let isSlashOpt (opt:string) = + opt.[0] = '/' && (opt.Length = 1 || not (opt.[1..].Contains "/")) + +module ResponseFile = + + type ResponseFileData = ResponseFileLine list + and ResponseFileLine = + | CompilerOptionSpec of string + | Comment of string + + let parseFile path: Choice = + let parseLine (l: string) = + match l with + | s when String.IsNullOrWhiteSpace s -> None + | s when l.StartsWithOrdinal("#") -> Some (ResponseFileLine.Comment (s.TrimStart('#'))) + | s -> Some (ResponseFileLine.CompilerOptionSpec (s.Trim())) + + try + use stream = FileSystem.OpenFileForReadShim(path) + use reader = new StreamReader(stream, true) + let data = + seq { while not reader.EndOfStream do yield reader.ReadLine () } + |> Seq.choose parseLine + |> List.ofSeq + Choice1Of2 data + with e -> + Choice2Of2 e + +let ParseCompilerOptions (collectOtherArgument: string -> unit, blocks: CompilerOptionBlock list, args) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + + let specs = List.collect GetOptionsOfBlock blocks + + // returns a tuple - the option token, the option argument string + let parseOption (s: string) = + // grab the option token + let opts = s.Split([|':'|]) + let mutable opt = opts.[0] + if opt = "" then + () + // if it doesn't start with a '-' or '/', reject outright + elif opt.[0] <> '-' && opt.[0] <> '/' then + opt <- "" + elif opt <> "--" then + // is it an abbreviated or MSFT-style option? + // if so, strip the first character and move on with your life + if opt.Length = 2 || isSlashOpt opt then + opt <- opt.[1 ..] + // else, it should be a non-abbreviated option starting with "--" + elif opt.Length > 3 && opt.StartsWithOrdinal("--") then + opt <- opt.[2 ..] + else + opt <- "" + + // get the argument string + let optArgs = if opts.Length > 1 then String.Join(":", opts.[1 ..]) else "" + opt, optArgs + + let getOptionArg compilerOption (argString: string) = + if argString = "" then + errorR(Error(FSComp.SR.buildOptionRequiresParameter(compilerOptionUsage compilerOption), rangeCmdArgs)) + argString + + let getOptionArgList compilerOption (argString: string) = + if argString = "" then + errorR(Error(FSComp.SR.buildOptionRequiresParameter(compilerOptionUsage compilerOption), rangeCmdArgs)) + [] + else + argString.Split([|',';';'|]) |> List.ofArray + + let getSwitchOpt (opt: string) = + // if opt is a switch, strip the '+' or '-' + if opt <> "--" && opt.Length > 1 && (opt.EndsWithOrdinal("+") || opt.EndsWithOrdinal("-")) then + opt.[0 .. opt.Length - 2] + else + opt + + let getSwitch (s: string) = + let s = (s.Split([|':'|])).[0] + if s <> "--" && s.EndsWithOrdinal("-") then OptionSwitch.Off else OptionSwitch.On + + let rec processArg args = + match args with + | [] -> () + | rsp: string :: t when rsp.StartsWithOrdinal("@") -> + let responseFileOptions = + let fullpath = + try + Some (rsp.TrimStart('@') |> FileSystem.GetFullPathShim) + with _ -> + None + + match fullpath with + | None -> + errorR(Error(FSComp.SR.optsResponseFileNameInvalid rsp, rangeCmdArgs)) + [] + | Some path when not (FileSystem.FileExistsShim path) -> + errorR(Error(FSComp.SR.optsResponseFileNotFound(rsp, path), rangeCmdArgs)) + [] + | Some path -> + match ResponseFile.parseFile path with + | Choice2Of2 _ -> + errorR(Error(FSComp.SR.optsInvalidResponseFile(rsp, path), rangeCmdArgs)) + [] + | Choice1Of2 rspData -> + let onlyOptions l = + match l with + | ResponseFile.ResponseFileLine.Comment _ -> None + | ResponseFile.ResponseFileLine.CompilerOptionSpec opt -> Some opt + rspData |> List.choose onlyOptions + + processArg (responseFileOptions @ t) + | opt :: t -> + let optToken, argString = parseOption opt + + let reportDeprecatedOption errOpt = + match errOpt with + | Some e -> warning e + | None -> () + + let rec attempt l = + match l with + | CompilerOption(s, _, OptionHelp f, d, _) :: _ when optToken = s && argString = "" -> + reportDeprecatedOption d + f blocks; t + | CompilerOption(s, _, OptionUnit f, d, _) :: _ when optToken = s && argString = "" -> + reportDeprecatedOption d + f (); t + | CompilerOption(s, _, OptionSwitch f, d, _) :: _ when getSwitchOpt optToken = s && argString = "" -> + reportDeprecatedOption d + f (getSwitch opt); t + | CompilerOption(s, _, OptionSet f, d, _) :: _ when optToken = s && argString = "" -> + reportDeprecatedOption d + f.Value <- true; t + | CompilerOption(s, _, OptionClear f, d, _) :: _ when optToken = s && argString = "" -> + reportDeprecatedOption d + f.Value <- false; t + | CompilerOption(s, _, OptionString f, d, _) as compilerOption :: _ when optToken = s -> + reportDeprecatedOption d + let oa = getOptionArg compilerOption argString + if oa <> "" then + f (getOptionArg compilerOption oa) + t + | CompilerOption(s, _, OptionInt f, d, _) as compilerOption :: _ when optToken = s -> + reportDeprecatedOption d + let oa = getOptionArg compilerOption argString + if oa <> "" then + f (try int32 oa with _ -> + errorR(Error(FSComp.SR.buildArgInvalidInt(getOptionArg compilerOption argString), rangeCmdArgs)); 0) + t + | CompilerOption(s, _, OptionFloat f, d, _) as compilerOption :: _ when optToken = s -> + reportDeprecatedOption d + let oa = getOptionArg compilerOption argString + if oa <> "" then + f (try float oa with _ -> + errorR(Error(FSComp.SR.buildArgInvalidFloat(getOptionArg compilerOption argString), rangeCmdArgs)); 0.0) + t + | CompilerOption(s, _, OptionRest f, d, _) :: _ when optToken = s -> + reportDeprecatedOption d + List.iter f t; [] + | CompilerOption(s, _, OptionIntList f, d, _) as compilerOption :: _ when optToken = s -> + reportDeprecatedOption d + let al = getOptionArgList compilerOption argString + if al <> [] then + List.iter (fun i -> f (try int32 i with _ -> errorR(Error(FSComp.SR.buildArgInvalidInt i, rangeCmdArgs)); 0)) al + t + | CompilerOption(s, _, OptionIntListSwitch f, d, _) as compilerOption :: _ when getSwitchOpt optToken = s -> + reportDeprecatedOption d + let al = getOptionArgList compilerOption argString + if al <> [] then + let switch = getSwitch opt + List.iter (fun i -> f (try int32 i with _ -> errorR(Error(FSComp.SR.buildArgInvalidInt i, rangeCmdArgs)); 0) switch) al + t + // here + | CompilerOption(s, _, OptionStringList f, d, _) as compilerOption :: _ when optToken = s -> + reportDeprecatedOption d + let al = getOptionArgList compilerOption argString + if al <> [] then + List.iter f (getOptionArgList compilerOption argString) + t + | CompilerOption(s, _, OptionStringListSwitch f, d, _) as compilerOption :: _ when getSwitchOpt optToken = s -> + reportDeprecatedOption d + let al = getOptionArgList compilerOption argString + if al <> [] then + let switch = getSwitch opt + List.iter (fun s -> f s switch) (getOptionArgList compilerOption argString) + t + | CompilerOption(_, _, OptionGeneral (pred, exec), d, _) :: _ when pred args -> + reportDeprecatedOption d + let rest = exec args in rest // arguments taken, rest remaining + | _ :: more -> attempt more + | [] -> + if opt.Length = 0 || opt.[0] = '-' || isSlashOpt opt + then + // want the whole opt token - delimiter and all + let unrecOpt = opt.Split([|':'|]).[0] + errorR(Error(FSComp.SR.buildUnrecognizedOption unrecOpt, rangeCmdArgs)) + t + else + (collectOtherArgument opt; t) + let rest = attempt specs + processArg rest + + processArg args + +//---------------------------------------------------------------------------- +// Compiler options +//-------------------------------------------------------------------------- + +let lexFilterVerbose = false +let mutable enableConsoleColoring = true // global state + +let setFlag r n = + match n with + | 0 -> r false + | 1 -> r true + | _ -> raise (Failure "expected 0/1") + +let SetOptimizeOff(tcConfigB: TcConfigBuilder) = + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 } + tcConfigB.doDetuple <- false + tcConfigB.doTLR <- false + tcConfigB.doFinalSimplify <- false + +let SetOptimizeOn(tcConfigB: TcConfigBuilder) = + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 } + tcConfigB.doDetuple <- true + tcConfigB.doTLR <- true + tcConfigB.doFinalSimplify <- true + +let SetOptimizeSwitch (tcConfigB: TcConfigBuilder) switch = + if (switch = OptionSwitch.On) then SetOptimizeOn tcConfigB else SetOptimizeOff tcConfigB + +let SetTailcallSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.emitTailcalls <- (switch = OptionSwitch.On) + +let SetDeterministicSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.deterministic <- (switch = OptionSwitch.On) + +let AddPathMapping (tcConfigB: TcConfigBuilder) (pathPair: string) = + match pathPair.Split([|'='|], 2) with + | [| oldPrefix; newPrefix |] -> + tcConfigB.AddPathMapping (oldPrefix, newPrefix) + | _ -> + error(Error(FSComp.SR.optsInvalidPathMapFormat(), rangeCmdArgs)) + +let jitoptimizeSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some (switch = OptionSwitch.On) } + +let localoptimizeSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some (switch = OptionSwitch.On) } + +let crossOptimizeSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some (switch = OptionSwitch.On) } + +let splittingSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.optSettings <- { tcConfigB.optSettings with abstractBigTargets = switch = OptionSwitch.On } + +let callVirtSwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.alwaysCallVirt <- switch = OptionSwitch.On + +let useHighEntropyVASwitch (tcConfigB: TcConfigBuilder) switch = + tcConfigB.useHighEntropyVA <- switch = OptionSwitch.On + +let subSystemVersionSwitch (tcConfigB: TcConfigBuilder) (text: string) = + let fail() = error(Error(FSComp.SR.optsInvalidSubSystemVersion text, rangeCmdArgs)) + + // per spec for 357994: Validate input string, should be two positive integers x.y when x>=4 and y>=0 and both <= 65535 + if String.IsNullOrEmpty text then + fail() + else + match text.Split('.') with + | [| majorStr; minorStr|] -> + match (Int32.TryParse majorStr), (Int32.TryParse minorStr) with + | (true, major), (true, minor) + when major >= 4 && major <= 65535 + && minor >=0 && minor <= 65535 -> + tcConfigB.subsystemVersion <- (major, minor) + | _ -> fail() + | _ -> fail() + +let SetUseSdkSwitch (tcConfigB: TcConfigBuilder) switch = + let useSdkRefs = (switch = OptionSwitch.On) + tcConfigB.SetUseSdkRefs useSdkRefs + +let (++) x s = x @ [s] + +let SetTarget (tcConfigB: TcConfigBuilder)(s: string) = + match s.ToLowerInvariant() with + | "exe" -> tcConfigB.target <- CompilerTarget.ConsoleExe + | "winexe" -> tcConfigB.target <- CompilerTarget.WinExe + | "library" -> tcConfigB.target <- CompilerTarget.Dll + | "module" -> tcConfigB.target <- CompilerTarget.Module + | _ -> error(Error(FSComp.SR.optsUnrecognizedTarget s, rangeCmdArgs)) + +let SetDebugSwitch (tcConfigB: TcConfigBuilder) (dtype: string option) (s: OptionSwitch) = + match dtype with + | Some s -> + match s with + | "portable" -> + tcConfigB.portablePDB <- true + tcConfigB.embeddedPDB <- false + tcConfigB.jitTracking <- true + tcConfigB.ignoreSymbolStoreSequencePoints <- true + | "pdbonly" -> + tcConfigB.portablePDB <- false + tcConfigB.embeddedPDB <- false + tcConfigB.jitTracking <- false + | "embedded" -> + tcConfigB.portablePDB <- true + tcConfigB.embeddedPDB <- true + tcConfigB.jitTracking <- true + tcConfigB.ignoreSymbolStoreSequencePoints <- true +#if FX_NO_PDB_WRITER + // When building on the coreclr, full means portable + | "full" -> + tcConfigB.portablePDB <- true + tcConfigB.embeddedPDB <- false + tcConfigB.jitTracking <- true +#else + | "full" -> + tcConfigB.portablePDB <- false + tcConfigB.embeddedPDB <- false + tcConfigB.jitTracking <- true +#endif + + | _ -> error(Error(FSComp.SR.optsUnrecognizedDebugType s, rangeCmdArgs)) + | None -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On + tcConfigB.debuginfo <- s = OptionSwitch.On + +let SetEmbedAllSourceSwitch (tcConfigB: TcConfigBuilder) switch = + if (switch = OptionSwitch.On) then tcConfigB.embedAllSource <- true else tcConfigB.embedAllSource <- false + +let setOutFileName tcConfigB path = + let outputDir = Path.GetDirectoryName(path) + tcConfigB.outputDir <- Some outputDir + tcConfigB.outputFile <- Some path + +let setSignatureFile tcConfigB s = + tcConfigB.printSignature <- true + tcConfigB.printSignatureFile <- s + +let setAllSignatureFiles tcConfigB () = + tcConfigB.printAllSignatureFiles <- true + +// option tags +let tagString = "" +let tagExe = "exe" +let tagWinExe = "winexe" +let tagLibrary = "library" +let tagModule = "module" +let tagFile = "" +let tagFileList = "" +let tagDirList = "" +let tagPathList = "" +let tagResInfo = "" +let tagFullPDBOnlyPortable = "{full|pdbonly|portable|embedded}" +let tagWarnList = "" +let tagSymbolList = "" +let tagAddress = "
" +let tagAlgorithm = "{SHA1|SHA256}" +let tagInt = "" +let tagPathMap = "" +let tagNone = "" +let tagLangVersionValues = "{?|version|latest|preview}" + +// PrintOptionInfo +//---------------- + +/// Print internal "option state" information for diagnostics and regression tests. +let PrintOptionInfo (tcConfigB:TcConfigBuilder) = + printfn " jitOptUser . . . . . . : %+A" tcConfigB.optSettings.jitOptUser + printfn " localOptUser . . . . . : %+A" tcConfigB.optSettings.localOptUser + printfn " crossAssemblyOptimizationUser . . : %+A" tcConfigB.optSettings.crossAssemblyOptimizationUser + printfn " lambdaInlineThreshold : %+A" tcConfigB.optSettings.lambdaInlineThreshold + printfn " ignoreSymStoreSeqPts . : %+A" tcConfigB.ignoreSymbolStoreSequencePoints + printfn " doDetuple . . . . . . : %+A" tcConfigB.doDetuple + printfn " doTLR . . . . . . . . : %+A" tcConfigB.doTLR + printfn " doFinalSimplify. . . . : %+A" tcConfigB.doFinalSimplify + printfn " jitTracking . . . . . : %+A" tcConfigB.jitTracking + printfn " portablePDB. . . . . . : %+A" tcConfigB.portablePDB + printfn " embeddedPDB. . . . . . : %+A" tcConfigB.embeddedPDB + printfn " embedAllSource . . . . : %+A" tcConfigB.embedAllSource + printfn " embedSourceList. . . . : %+A" tcConfigB.embedSourceList + printfn " sourceLink . . . . . . : %+A" tcConfigB.sourceLink + printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo + printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment + printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText + printfn " copyFSharpCore . . . . : %+A" tcConfigB.copyFSharpCore + tcConfigB.includes |> List.sort + |> List.iter (printfn " include . . . . . . . : %A") + +// OptionBlock: Input files +//------------------------- + +let inputFileFlagsBoth (tcConfigB : TcConfigBuilder) = [ + CompilerOption("reference", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None, Some (FSComp.SR.optsReference())) + CompilerOption("compilertool", tagFile, OptionString (fun s -> tcConfigB.AddCompilerToolsByPath s), None, Some (FSComp.SR.optsCompilerTool())) + ] + +let referenceFlagAbbrev (tcConfigB : TcConfigBuilder) = + CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), None, Some(FSComp.SR.optsShortFormOf("--reference"))) + +let compilerToolFlagAbbrev (tcConfigB : TcConfigBuilder) = + CompilerOption("t", tagFile, OptionString (fun s -> tcConfigB.AddCompilerToolsByPath s), None, Some(FSComp.SR.optsShortFormOf("--compilertool"))) + +let inputFileFlagsFsc tcConfigB = inputFileFlagsBoth tcConfigB + +let inputFileFlagsFsiBase (_tcConfigB: TcConfigBuilder) = +#if NETSTANDARD + [ CompilerOption("usesdkrefs", tagNone, OptionSwitch (SetUseSdkSwitch _tcConfigB), None, Some (FSComp.SR.useSdkRefs())) ] +#else + List.empty +#endif + +let inputFileFlagsFsi (tcConfigB: TcConfigBuilder) = + List.append (inputFileFlagsBoth tcConfigB) (inputFileFlagsFsiBase tcConfigB) + +// OptionBlock: Errors and warnings +//--------------------------------- + +let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) = + let trimFS (s:string) = if s.StartsWithOrdinal "FS" then s.Substring 2 else s + let trimFStoInt (s:string) = + match Int32.TryParse (trimFS s) with + | true, n -> Some n + | false, _ -> None + [ + CompilerOption("warnaserror", tagNone, OptionSwitch(fun switch -> + tcConfigB.errorSeverityOptions <- + { tcConfigB.errorSeverityOptions with + GlobalWarnAsError = switch <> OptionSwitch.Off }), None, Some (FSComp.SR.optsWarnaserrorPM())) + + CompilerOption("warnaserror", tagWarnList, OptionStringListSwitch (fun n switch -> + match trimFStoInt n with + | Some n -> + let options = tcConfigB.errorSeverityOptions + tcConfigB.errorSeverityOptions <- + if switch = OptionSwitch.Off then + { options with + WarnAsError = ListSet.remove (=) n options.WarnAsError + WarnAsWarn = ListSet.insert (=) n options.WarnAsWarn } + else + { options with + WarnAsError = ListSet.insert (=) n options.WarnAsError + WarnAsWarn = ListSet.remove (=) n options.WarnAsWarn } + | None -> ()), None, Some (FSComp.SR.optsWarnaserror())) + + CompilerOption("warn", tagInt, OptionInt (fun n -> + tcConfigB.errorSeverityOptions <- + { tcConfigB.errorSeverityOptions with + WarnLevel = if (n >= 0 && n <= 5) then n else error(Error (FSComp.SR.optsInvalidWarningLevel n, rangeCmdArgs)) } + ), None, Some (FSComp.SR.optsWarn())) + + CompilerOption("nowarn", tagWarnList, OptionStringList (fun n -> + tcConfigB.TurnWarningOff(rangeCmdArgs, trimFS n)), None, Some (FSComp.SR.optsNowarn())) + + CompilerOption("warnon", tagWarnList, OptionStringList (fun n -> + tcConfigB.TurnWarningOn(rangeCmdArgs, trimFS n)), None, Some (FSComp.SR.optsWarnOn())) + + CompilerOption("consolecolors", tagNone, OptionSwitch (fun switch -> + enableConsoleColoring <- switch = OptionSwitch.On), None, Some (FSComp.SR.optsConsoleColors())) + ] + + +// OptionBlock: Output files +//-------------------------- + +let outputFileFlagsFsi (_tcConfigB: TcConfigBuilder) = [] + +let outputFileFlagsFsc (tcConfigB: TcConfigBuilder) = + [ + CompilerOption + ("out", tagFile, + OptionString (setOutFileName tcConfigB), None, + Some (FSComp.SR.optsNameOfOutputFile()) ) + + CompilerOption + ("target", tagExe, + OptionString (SetTarget tcConfigB), None, + Some (FSComp.SR.optsBuildConsole())) + + CompilerOption + ("target", tagWinExe, + OptionString (SetTarget tcConfigB), None, + Some (FSComp.SR.optsBuildWindows())) + + CompilerOption + ("target", tagLibrary, + OptionString (SetTarget tcConfigB), None, + Some (FSComp.SR.optsBuildLibrary())) + + CompilerOption + ("target", tagModule, + OptionString (SetTarget tcConfigB), None, + Some (FSComp.SR.optsBuildModule())) + + CompilerOption + ("delaysign", tagNone, + OptionSwitch (fun s -> tcConfigB.delaysign <- (s = OptionSwitch.On)), None, + Some (FSComp.SR.optsDelaySign())) + + CompilerOption + ("publicsign", tagNone, + OptionSwitch (fun s -> tcConfigB.publicsign <- (s = OptionSwitch.On)), None, + Some (FSComp.SR.optsPublicSign())) + + CompilerOption + ("doc", tagFile, + OptionString (fun s -> tcConfigB.xmlDocOutputFile <- Some s), None, + Some (FSComp.SR.optsWriteXml())) + + CompilerOption + ("keyfile", tagFile, + OptionString (fun s -> tcConfigB.signer <- Some s), None, + Some (FSComp.SR.optsStrongKeyFile())) + + CompilerOption + ("platform", tagString, + OptionString (fun s -> + tcConfigB.platform <- + match s with + | "x86" -> Some X86 + | "x64" -> Some AMD64 + | "Itanium" -> Some IA64 + | "anycpu32bitpreferred" -> + tcConfigB.prefer32Bit <- true + None + | "anycpu" -> None + | _ -> error(Error(FSComp.SR.optsUnknownPlatform s, rangeCmdArgs))), None, + Some(FSComp.SR.optsPlatform())) + + CompilerOption + ("nooptimizationdata", tagNone, + OptionUnit (fun () -> tcConfigB.onlyEssentialOptimizationData <- true), None, + Some (FSComp.SR.optsNoOpt())) + + CompilerOption + ("nointerfacedata", tagNone, + OptionUnit (fun () -> tcConfigB.noSignatureData <- true), None, + Some (FSComp.SR.optsNoInterface())) + + CompilerOption + ("sig", tagFile, + OptionString (setSignatureFile tcConfigB), None, + Some (FSComp.SR.optsSig())) + + CompilerOption + ("allsigs", tagNone, + OptionUnit (setAllSignatureFiles tcConfigB), None, + Some (FSComp.SR.optsAllSigs())) + + CompilerOption + ("nocopyfsharpcore", tagNone, + OptionUnit (fun () -> tcConfigB.copyFSharpCore <- CopyFSharpCoreFlag.No), None, + Some (FSComp.SR.optsNoCopyFsharpCore())) + ] + + +// OptionBlock: Resources +//----------------------- + +let resourcesFlagsFsi (_tcConfigB: TcConfigBuilder) = [] +let resourcesFlagsFsc (tcConfigB: TcConfigBuilder) = + [ + CompilerOption + ("win32icon", tagFile, + OptionString (fun s -> tcConfigB.win32icon <- s), None, + Some (FSComp.SR.optsWin32icon())) + CompilerOption + ("win32res", tagFile, + OptionString (fun s -> tcConfigB.win32res <- s), None, + Some (FSComp.SR.optsWin32res())) + + CompilerOption + ("win32manifest", tagFile, + OptionString (fun s -> tcConfigB.win32manifest <- s), None, + Some (FSComp.SR.optsWin32manifest())) + + CompilerOption + ("nowin32manifest", tagNone, + OptionUnit (fun () -> tcConfigB.includewin32manifest <- false), None, + Some (FSComp.SR.optsNowin32manifest())) + + CompilerOption + ("resource", tagResInfo, + OptionString (fun s -> tcConfigB.AddEmbeddedResource s), None, + Some (FSComp.SR.optsResource())) + + CompilerOption + ("linkresource", tagResInfo, + OptionString (fun s -> tcConfigB.linkResources <- tcConfigB.linkResources ++ s), None, + Some (FSComp.SR.optsLinkresource())) + ] + + +// OptionBlock: Code generation +//----------------------------- + +let codeGenerationFlags isFsi (tcConfigB: TcConfigBuilder) = + let debug = + [ CompilerOption + ("debug", tagNone, + OptionSwitch (SetDebugSwitch tcConfigB None), None, + Some (FSComp.SR.optsDebugPM())) + + CompilerOption + ("debug", tagFullPDBOnlyPortable, + OptionString (fun s -> SetDebugSwitch tcConfigB (Some s) OptionSwitch.On), None, + Some (FSComp.SR.optsDebug(if isFsi then "pdbonly" else "full"))) + ] + let embed = + [ CompilerOption + ("embed", tagNone, + OptionSwitch (SetEmbedAllSourceSwitch tcConfigB), None, + Some (FSComp.SR.optsEmbedAllSource())) + + CompilerOption + ("embed", tagFileList, + OptionStringList (fun f -> tcConfigB.AddEmbeddedSourceFile f), None, + Some ( FSComp.SR.optsEmbedSource())) + + CompilerOption + ("sourcelink", tagFile, + OptionString (fun f -> tcConfigB.sourceLink <- f), None, + Some ( FSComp.SR.optsSourceLink())) + ] + + let codegen = + [ CompilerOption + ("optimize", tagNone, + OptionSwitch (SetOptimizeSwitch tcConfigB), None, + Some (FSComp.SR.optsOptimize())) + + CompilerOption + ("tailcalls", tagNone, + OptionSwitch (SetTailcallSwitch tcConfigB), None, + Some (FSComp.SR.optsTailcalls())) + + CompilerOption + ("deterministic", tagNone, + OptionSwitch (SetDeterministicSwitch tcConfigB), None, + Some (FSComp.SR.optsDeterministic())) + + CompilerOption + ("pathmap", tagPathMap, + OptionStringList (AddPathMapping tcConfigB), None, + Some (FSComp.SR.optsPathMap())) + + CompilerOption + ("crossoptimize", tagNone, + OptionSwitch (crossOptimizeSwitch tcConfigB), None, + Some (FSComp.SR.optsCrossoptimize())) + ] + if isFsi then debug @ codegen + else debug @ embed @ codegen + +// OptionBlock: Language +//---------------------- + +let defineSymbol tcConfigB s = tcConfigB.conditionalCompilationDefines <- s :: tcConfigB.conditionalCompilationDefines + +let mlCompatibilityFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("mlcompatibility", tagNone, + OptionUnit (fun () -> tcConfigB.mlCompatibility<-true; tcConfigB.TurnWarningOff(rangeCmdArgs, "62")), None, + Some (FSComp.SR.optsMlcompatibility())) + +/// LanguageVersion management +let setLanguageVersion specifiedVersion = + + let languageVersion = LanguageVersion(specifiedVersion) + let dumpAllowedValues () = + printfn "%s" (FSComp.SR.optsSupportedLangVersions()) + for v in languageVersion.ValidOptions do printfn "%s" v + for v in languageVersion.ValidVersions do printfn "%s" v + exit 0 + + if specifiedVersion = "?" then dumpAllowedValues () + if not (languageVersion.ContainsVersion specifiedVersion) then error(Error(FSComp.SR.optsUnrecognizedLanguageVersion specifiedVersion, rangeCmdArgs)) + languageVersion + +let languageFlags tcConfigB = + [ + // -langversion:? Display the allowed values for language version + // -langversion: Specify language version such as + // 'default' (latest major version), or + // 'latest' (latest version, including minor versions), + // 'preview' (features for preview) + // or specific versions like '4.7' + CompilerOption("langversion", tagLangVersionValues, OptionString (fun switch -> tcConfigB.langVersion <- setLanguageVersion(switch)), None, Some (FSComp.SR.optsLangVersion())) + + CompilerOption("checked", tagNone, OptionSwitch (fun switch -> tcConfigB.checkOverflow <- (switch = OptionSwitch.On)), None, Some (FSComp.SR.optsChecked())) + CompilerOption("define", tagString, OptionString (defineSymbol tcConfigB), None, Some (FSComp.SR.optsDefine())) + mlCompatibilityFlag tcConfigB + ] + +// OptionBlock: Advanced user options +//----------------------------------- + +let libFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("lib", tagDirList, + OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), None, + Some (FSComp.SR.optsLib())) + +let codePageFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("codepage", tagInt, + OptionInt (fun n -> + try + System.Text.Encoding.GetEncoding n |> ignore + with :? ArgumentException as err -> + error(Error(FSComp.SR.optsProblemWithCodepage(n, err.Message), rangeCmdArgs)) + + tcConfigB.inputCodePage <- Some n), None, + Some (FSComp.SR.optsCodepage())) + +let preferredUiLang (tcConfigB: TcConfigBuilder) = + CompilerOption + ("preferreduilang", tagString, + OptionString (fun s -> tcConfigB.preferredUiLang <- Some s), None, + Some(FSComp.SR.optsPreferredUiLang())) + +let utf8OutputFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("utf8output", tagNone, + OptionUnit (fun () -> tcConfigB.utf8output <- true), None, + Some (FSComp.SR.optsUtf8output())) + +let fullPathsFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("fullpaths", tagNone, + OptionUnit (fun () -> tcConfigB.showFullPaths <- true), None, + Some (FSComp.SR.optsFullpaths())) + +let cliRootFlag (_tcConfigB: TcConfigBuilder) = + CompilerOption + ("cliroot", tagString, + OptionString (fun _ -> ()), Some(DeprecatedCommandLineOptionFull(FSComp.SR.optsClirootDeprecatedMsg(), rangeCmdArgs)), + Some(FSComp.SR.optsClirootDescription())) + +let SetTargetProfile (tcConfigB: TcConfigBuilder) v = + let primaryAssembly = + match v with + // Indicates we assume "mscorlib.dll", i.e .NET Framework, Mono and Profile 47 + | "mscorlib" -> PrimaryAssembly.Mscorlib + // Indicates we assume "System.Runtime.dll", i.e .NET Standard 1.x, .NET Core App 1.x and above, and Profile 7/78/259 + | "netcore" -> PrimaryAssembly.System_Runtime + // Indicates we assume "netstandard.dll", i.e .NET Standard 2.0 and above + | "netstandard" -> PrimaryAssembly.NetStandard + | _ -> error(Error(FSComp.SR.optsInvalidTargetProfile v, rangeCmdArgs)) + tcConfigB.SetPrimaryAssembly primaryAssembly + +let advancedFlagsBoth tcConfigB = + [ + yield codePageFlag tcConfigB + yield utf8OutputFlag tcConfigB + yield preferredUiLang tcConfigB + yield fullPathsFlag tcConfigB + yield libFlag tcConfigB + yield CompilerOption + ("simpleresolution", + tagNone, + OptionUnit (fun () -> tcConfigB.useSimpleResolution<-true), None, + Some (FSComp.SR.optsSimpleresolution())) + + yield CompilerOption + ("targetprofile", tagString, + OptionString (SetTargetProfile tcConfigB), None, + Some(FSComp.SR.optsTargetProfile())) + ] + +let noFrameworkFlag isFsc tcConfigB = + CompilerOption + ("noframework", tagNone, + OptionUnit (fun () -> + tcConfigB.framework <- false + if isFsc then + tcConfigB.implicitlyResolveAssemblies <- false), None, + Some (FSComp.SR.optsNoframework())) + +let advancedFlagsFsi tcConfigB = + advancedFlagsBoth tcConfigB @ + [ + yield noFrameworkFlag false tcConfigB + ] + +let advancedFlagsFsc tcConfigB = + advancedFlagsBoth tcConfigB @ + [ + yield CompilerOption + ("baseaddress", tagAddress, + OptionString (fun s -> tcConfigB.baseAddress <- Some(int32 s)), None, + Some (FSComp.SR.optsBaseaddress())) + + yield CompilerOption + ("checksumalgorithm", tagAlgorithm, + OptionString (fun s -> + tcConfigB.checksumAlgorithm <- + match s.ToUpperInvariant() with + | "SHA1" -> HashAlgorithm.Sha1 + | "SHA256" -> HashAlgorithm.Sha256 + | _ -> error(Error(FSComp.SR.optsUnknownChecksumAlgorithm s, rangeCmdArgs))), None, + Some (FSComp.SR.optsChecksumAlgorithm())) + + yield noFrameworkFlag true tcConfigB + + yield CompilerOption + ("standalone", tagNone, + OptionUnit (fun _ -> + tcConfigB.openDebugInformationForLaterStaticLinking <- true + tcConfigB.standalone <- true + tcConfigB.implicitlyResolveAssemblies <- true), None, + Some (FSComp.SR.optsStandalone())) + + yield CompilerOption + ("staticlink", tagFile, + OptionString (fun s -> + tcConfigB.extraStaticLinkRoots <- tcConfigB.extraStaticLinkRoots @ [s] + tcConfigB.implicitlyResolveAssemblies <- true), None, + Some (FSComp.SR.optsStaticlink())) + +#if ENABLE_MONO_SUPPORT + if runningOnMono then + yield CompilerOption + ("resident", tagFile, + OptionUnit (fun () -> ()), None, + Some (FSComp.SR.optsResident())) +#endif + + yield CompilerOption + ("pdb", tagString, + OptionString (fun s -> tcConfigB.debugSymbolFile <- Some s), None, + Some (FSComp.SR.optsPdb())) + + yield CompilerOption + ("highentropyva", tagNone, + OptionSwitch (useHighEntropyVASwitch tcConfigB), None, + Some (FSComp.SR.optsUseHighEntropyVA())) + + yield CompilerOption + ("subsystemversion", tagString, + OptionString (subSystemVersionSwitch tcConfigB), None, + Some (FSComp.SR.optsSubSystemVersion())) + + yield CompilerOption + ("quotations-debug", tagNone, + OptionSwitch(fun switch -> tcConfigB.emitDebugInfoInQuotations <- switch = OptionSwitch.On), None, + Some(FSComp.SR.optsEmitDebugInfoInQuotations())) + + ] + +// OptionBlock: Internal options (test use only) +//-------------------------------------------------- + +let testFlag tcConfigB = + CompilerOption + ("test", tagString, + OptionString (fun s -> + match s with + | "StackSpan" -> tcConfigB.internalTestSpanStackReferring <- true + | "ErrorRanges" -> tcConfigB.errorStyle <- ErrorStyle.TestErrors + | "Tracking" -> tracking <- true (* general purpose on/off diagnostics flag *) + | "NoNeedToTailcall" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportNoNeedToTailcall = true } + | "FunctionSizes" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportFunctionSizes = true } + | "TotalSizes" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportTotalSizes = true } + | "HasEffect" -> tcConfigB.optSettings <- { tcConfigB.optSettings with reportHasEffect = true } + | "NoErrorText" -> FSComp.SR.SwallowResourceText <- true + | "EmitFeeFeeAs100001" -> tcConfigB.testFlagEmitFeeFeeAs100001 <- true + | "DumpDebugInfo" -> tcConfigB.dumpDebugInfo <- true + | "ShowLoadedAssemblies" -> tcConfigB.showLoadedAssemblies <- true + | "ContinueAfterParseFailure" -> tcConfigB.continueAfterParseFailure <- true + | "ParallelOff" -> tcConfigB.concurrentBuild <- false +#if DEBUG + | "ShowParserStackOnParseError" -> showParserStackOnParseError <- true +#endif + | str -> warning(Error(FSComp.SR.optsUnknownArgumentToTheTestSwitch str, rangeCmdArgs))), None, + None) + +// Not shown in fsc.exe help, no warning on use, motivation is for use from tooling. +let editorSpecificFlags (tcConfigB: TcConfigBuilder) = + [ CompilerOption("vserrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.VSErrors), None, None) + CompilerOption("validate-type-providers", tagNone, OptionUnit id, None, None) // preserved for compatibility's sake, no longer has any effect + CompilerOption("LCID", tagInt, OptionInt ignore, None, None) + CompilerOption("flaterrors", tagNone, OptionUnit (fun () -> tcConfigB.flatErrors <- true), None, None) + CompilerOption("sqmsessionguid", tagNone, OptionString ignore, None, None) + CompilerOption("gccerrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.GccErrors), None, None) + CompilerOption("exename", tagNone, OptionString (fun s -> tcConfigB.exename <- Some s), None, None) + CompilerOption("maxerrors", tagInt, OptionInt (fun n -> tcConfigB.maxErrors <- n), None, None) + CompilerOption("noconditionalerasure", tagNone, OptionUnit (fun () -> tcConfigB.noConditionalErasure <- true), None, None) ] + +let internalFlags (tcConfigB:TcConfigBuilder) = + [ + CompilerOption + ("stamps", tagNone, + OptionUnit ignore, + Some(InternalCommandLineOption("--stamps", rangeCmdArgs)), None) + + CompilerOption + ("ranges", tagNone, + OptionSet DebugPrint.layoutRanges, + Some(InternalCommandLineOption("--ranges", rangeCmdArgs)), None) + + CompilerOption + ("terms", tagNone, + OptionUnit (fun () -> tcConfigB.showTerms <- true), + Some(InternalCommandLineOption("--terms", rangeCmdArgs)), None) + + CompilerOption + ("termsfile", tagNone, + OptionUnit (fun () -> tcConfigB.writeTermsToFiles <- true), + Some(InternalCommandLineOption("--termsfile", rangeCmdArgs)), None) + +#if DEBUG + CompilerOption + ("debug-parse", tagNone, + OptionUnit (fun () -> Internal.Utilities.Text.Parsing.Flags.debug <- true), + Some(InternalCommandLineOption("--debug-parse", rangeCmdArgs)), None) +#endif + + CompilerOption + ("pause", tagNone, + OptionUnit (fun () -> tcConfigB.pause <- true), + Some(InternalCommandLineOption("--pause", rangeCmdArgs)), None) + + CompilerOption + ("detuple", tagNone, + OptionInt (setFlag (fun v -> tcConfigB.doDetuple <- v)), + Some(InternalCommandLineOption("--detuple", rangeCmdArgs)), None) + + CompilerOption + ("simulateException", tagNone, + OptionString (fun s -> tcConfigB.simulateException <- Some s), + Some(InternalCommandLineOption("--simulateException", rangeCmdArgs)), Some "Simulate an exception from some part of the compiler") + + CompilerOption + ("stackReserveSize", tagNone, + OptionString (fun s -> tcConfigB.stackReserveSize <- Some(int32 s)), + Some(InternalCommandLineOption("--stackReserveSize", rangeCmdArgs)), Some "for an exe, set stack reserve size") + + CompilerOption + ("tlr", tagInt, + OptionInt (setFlag (fun v -> tcConfigB.doTLR <- v)), + Some(InternalCommandLineOption("--tlr", rangeCmdArgs)), None) + + CompilerOption + ("finalSimplify", tagInt, + OptionInt (setFlag (fun v -> tcConfigB.doFinalSimplify <- v)), + Some(InternalCommandLineOption("--finalSimplify", rangeCmdArgs)), None) + + CompilerOption + ("parseonly", tagNone, + OptionUnit (fun () -> tcConfigB.parseOnly <- true), + Some(InternalCommandLineOption("--parseonly", rangeCmdArgs)), None) + + CompilerOption + ("typecheckonly", tagNone, + OptionUnit (fun () -> tcConfigB.typeCheckOnly <- true), + Some(InternalCommandLineOption("--typecheckonly", rangeCmdArgs)), None) + + CompilerOption + ("ast", tagNone, + OptionUnit (fun () -> tcConfigB.printAst <- true), + Some(InternalCommandLineOption("--ast", rangeCmdArgs)), None) + + CompilerOption + ("tokenize", tagNone, + OptionUnit (fun () -> tcConfigB.tokenize <- TokenizeOption.Only), + Some(InternalCommandLineOption("--tokenize", rangeCmdArgs)), None) + + CompilerOption + ("tokenize-unfiltered", tagNone, + OptionUnit (fun () -> tcConfigB.tokenize <- TokenizeOption.Unfiltered), + Some(InternalCommandLineOption("--tokenize-unfiltered", rangeCmdArgs)), None) + + CompilerOption + ("testInteractionParser", tagNone, + OptionUnit (fun () -> tcConfigB.testInteractionParser <- true), + Some(InternalCommandLineOption("--testInteractionParser", rangeCmdArgs)), None) + + CompilerOption + ("testparsererrorrecovery", tagNone, + OptionUnit (fun () -> tcConfigB.reportNumDecls <- true), + Some(InternalCommandLineOption("--testparsererrorrecovery", rangeCmdArgs)), None) + + CompilerOption + ("inlinethreshold", tagInt, + OptionInt (fun n -> tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = n }), + Some(InternalCommandLineOption("--inlinethreshold", rangeCmdArgs)), None) + + CompilerOption + ("extraoptimizationloops", tagNone, + OptionInt (fun n -> tcConfigB.extraOptimizationIterations <- n), + Some(InternalCommandLineOption("--extraoptimizationloops", rangeCmdArgs)), None) + + CompilerOption + ("abortonerror", tagNone, + OptionUnit (fun () -> tcConfigB.abortOnError <- true), + Some(InternalCommandLineOption("--abortonerror", rangeCmdArgs)), None) + + CompilerOption + ("implicitresolution", tagNone, + OptionUnit (fun _ -> tcConfigB.implicitlyResolveAssemblies <- true), + Some(InternalCommandLineOption("--implicitresolution", rangeCmdArgs)), None) + + // "Display assembly reference resolution information") + CompilerOption + ("resolutions", tagNone, + OptionUnit (fun () -> tcConfigB.showReferenceResolutions <- true), + Some(InternalCommandLineOption("", rangeCmdArgs)), None) + + // "The base registry key to use for assembly resolution. This part in brackets here: HKEY_LOCAL_MACHINE\[SOFTWARE\Microsoft\.NETFramework]\v2.0.50727\AssemblyFoldersEx") + CompilerOption + ("resolutionframeworkregistrybase", tagString, + OptionString (fun _ -> ()), + Some(InternalCommandLineOption("", rangeCmdArgs)), None) + + // "The base registry key to use for assembly resolution. This part in brackets here: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\[AssemblyFoldersEx]") + CompilerOption + ("resolutionassemblyfoldersuffix", tagString, + OptionString (fun _ -> ()), + Some(InternalCommandLineOption("resolutionassemblyfoldersuffix", rangeCmdArgs)), None) + + // "Additional reference resolution conditions. For example \"OSVersion=5.1.2600.0, PlatformID=id") + CompilerOption + ("resolutionassemblyfoldersconditions", tagString, + OptionString (fun _ -> ()), + Some(InternalCommandLineOption("resolutionassemblyfoldersconditions", rangeCmdArgs)), None) + + // "Resolve assembly references using MSBuild resolution rules rather than directory based (Default=true except when running fsc.exe under mono)") + CompilerOption + ("msbuildresolution", tagNone, + OptionUnit (fun () -> tcConfigB.useSimpleResolution<-false), + Some(InternalCommandLineOption("msbuildresolution", rangeCmdArgs)), None) + + CompilerOption + ("alwayscallvirt", tagNone, + OptionSwitch(callVirtSwitch tcConfigB), + Some(InternalCommandLineOption("alwayscallvirt", rangeCmdArgs)), None) + + CompilerOption + ("nodebugdata", tagNone, + OptionUnit (fun () -> tcConfigB.noDebugData<-true), + Some(InternalCommandLineOption("--nodebugdata", rangeCmdArgs)), None) + + testFlag tcConfigB ] @ + + editorSpecificFlags tcConfigB @ + [ CompilerOption + ("jit", tagNone, + OptionSwitch (jitoptimizeSwitch tcConfigB), + Some(InternalCommandLineOption("jit", rangeCmdArgs)), None) + + CompilerOption + ("localoptimize", tagNone, + OptionSwitch(localoptimizeSwitch tcConfigB), + Some(InternalCommandLineOption("localoptimize", rangeCmdArgs)), None) + + CompilerOption + ("splitting", tagNone, + OptionSwitch(splittingSwitch tcConfigB), + Some(InternalCommandLineOption("splitting", rangeCmdArgs)), None) + + CompilerOption + ("versionfile", tagString, + OptionString (fun s -> tcConfigB.version <- VersionFile s), + Some(InternalCommandLineOption("versionfile", rangeCmdArgs)), None) + + // "Display timing profiles for compilation" + CompilerOption + ("times", tagNone, + OptionUnit (fun () -> tcConfigB.showTimes <- true), + Some(InternalCommandLineOption("times", rangeCmdArgs)), None) + +#if !NO_EXTENSIONTYPING + // "Display information about extension type resolution") + CompilerOption + ("showextensionresolution", tagNone, + OptionUnit (fun () -> tcConfigB.showExtensionTypeMessages <- true), + Some(InternalCommandLineOption("showextensionresolution", rangeCmdArgs)), None) +#endif + + CompilerOption + ("metadataversion", tagString, + OptionString (fun s -> tcConfigB.metadataVersion <- Some s), + Some(InternalCommandLineOption("metadataversion", rangeCmdArgs)), None) + ] + +// OptionBlock: Deprecated flags (fsc, service only) +//-------------------------------------------------- + +let compilingFsLibFlag (tcConfigB: TcConfigBuilder) = + CompilerOption + ("compiling-fslib", tagNone, + OptionUnit (fun () -> + tcConfigB.compilingFslib <- true + tcConfigB.TurnWarningOff(rangeStartup, "42")), + Some(InternalCommandLineOption("--compiling-fslib", rangeCmdArgs)), None) + +let compilingFsLib20Flag = + CompilerOption ("compiling-fslib-20", tagNone, OptionString (fun _ -> () ), None, None) + +let compilingFsLib40Flag = + CompilerOption ("compiling-fslib-40", tagNone, OptionUnit (fun () -> ()), None, None) + +let compilingFsLibNoBigIntFlag = + CompilerOption ("compiling-fslib-nobigint", tagNone, OptionUnit (fun () -> () ), None, None) + +let mlKeywordsFlag = + CompilerOption + ("ml-keywords", tagNone, + OptionUnit (fun () -> ()), + Some(DeprecatedCommandLineOptionNoDescription("--ml-keywords", rangeCmdArgs)), None) + +let gnuStyleErrorsFlag tcConfigB = + CompilerOption + ("gnu-style-errors", tagNone, + OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.EmacsErrors), + Some(DeprecatedCommandLineOptionNoDescription("--gnu-style-errors", rangeCmdArgs)), None) + +let deprecatedFlagsBoth tcConfigB = + [ + CompilerOption + ("light", tagNone, + OptionUnit (fun () -> tcConfigB.light <- Some true), + Some(DeprecatedCommandLineOptionNoDescription("--light", rangeCmdArgs)), None) + + CompilerOption + ("indentation-syntax", tagNone, + OptionUnit (fun () -> tcConfigB.light <- Some true), + Some(DeprecatedCommandLineOptionNoDescription("--indentation-syntax", rangeCmdArgs)), None) + + CompilerOption + ("no-indentation-syntax", tagNone, + OptionUnit (fun () -> tcConfigB.light <- Some false), + Some(DeprecatedCommandLineOptionNoDescription("--no-indentation-syntax", rangeCmdArgs)), None) + ] + +let deprecatedFlagsFsi tcConfigB = deprecatedFlagsBoth tcConfigB + +let deprecatedFlagsFsc tcConfigB = + deprecatedFlagsBoth tcConfigB @ + [ + cliRootFlag tcConfigB + CompilerOption + ("jit-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true }), + Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) + + CompilerOption + ("no-jit-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false }), + Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) + + CompilerOption + ("jit-tracking", tagNone, + OptionUnit (fun _ -> tcConfigB.jitTracking <- true ), + Some(DeprecatedCommandLineOptionNoDescription("--jit-tracking", rangeCmdArgs)), None) + + CompilerOption + ("no-jit-tracking", tagNone, + OptionUnit (fun _ -> tcConfigB.jitTracking <- false ), + Some(DeprecatedCommandLineOptionNoDescription("--no-jit-tracking", rangeCmdArgs)), None) + + CompilerOption + ("progress", tagNone, + OptionUnit (fun () -> progress <- true), + Some(DeprecatedCommandLineOptionNoDescription("--progress", rangeCmdArgs)), None) + + compilingFsLibFlag tcConfigB + compilingFsLib20Flag + compilingFsLib40Flag + compilingFsLibNoBigIntFlag + + CompilerOption + ("version", tagString, + OptionString (fun s -> tcConfigB.version <- VersionString s), + Some(DeprecatedCommandLineOptionNoDescription("--version", rangeCmdArgs)), None) + + CompilerOption + ("local-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true }), + Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) + + CompilerOption + ("no-local-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false }), + Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) + + CompilerOption + ("cross-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some true }), + Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) + + CompilerOption + ("no-cross-optimize", tagNone, + OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some false }), + Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) + + CompilerOption + ("no-string-interning", tagNone, + OptionUnit (fun () -> tcConfigB.internConstantStrings <- false), + Some(DeprecatedCommandLineOptionNoDescription("--no-string-interning", rangeCmdArgs)), None) + + CompilerOption + ("statistics", tagNone, + OptionUnit (fun () -> tcConfigB.stats <- true), + Some(DeprecatedCommandLineOptionNoDescription("--statistics", rangeCmdArgs)), None) + + CompilerOption + ("generate-filter-blocks", tagNone, + OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- true), + Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) + + //CompilerOption + // ("no-generate-filter-blocks", tagNone, + // OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- false), + // Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) + + CompilerOption + ("max-errors", tagInt, + OptionInt (fun n -> tcConfigB.maxErrors <- n), + Some(DeprecatedCommandLineOptionSuggestAlternative("--max-errors", "--maxerrors", rangeCmdArgs)), None) + + CompilerOption + ("debug-file", tagNone, + OptionString (fun s -> tcConfigB.debugSymbolFile <- Some s), + Some(DeprecatedCommandLineOptionSuggestAlternative("--debug-file", "--pdb", rangeCmdArgs)), None) + + CompilerOption + ("no-debug-file", tagNone, + OptionUnit (fun () -> tcConfigB.debuginfo <- false), + Some(DeprecatedCommandLineOptionSuggestAlternative("--no-debug-file", "--debug-", rangeCmdArgs)), None) + + CompilerOption + ("Ooff", tagNone, + OptionUnit (fun () -> SetOptimizeOff tcConfigB), + Some(DeprecatedCommandLineOptionSuggestAlternative("-Ooff", "--optimize-", rangeCmdArgs)), None) + + + CompilerOption + ("keycontainer", tagString, + OptionString(fun s -> + if FSharpEnvironment.isRunningOnCoreClr then error(Error(FSComp.SR.containerSigningUnsupportedOnThisPlatform(), rangeCmdArgs)) + else tcConfigB.container <- Some s), + if FSharpEnvironment.isRunningOnCoreClr then None + else Some(DeprecatedCommandLineOptionSuggestAlternative("--keycontainer", "--keyfile", rangeCmdArgs)) + ,None) + + mlKeywordsFlag + gnuStyleErrorsFlag tcConfigB ] + + +// OptionBlock: Miscellaneous options +//----------------------------------- + +let DisplayBannerText tcConfigB = + if tcConfigB.showBanner then ( + printfn "%s" tcConfigB.productNameForBannerText + printfn "%s" (FSComp.SR.optsCopyright()) + ) + +/// FSC only help. (FSI has it's own help function). +let displayHelpFsc tcConfigB (blocks:CompilerOptionBlock list) = + DisplayBannerText tcConfigB + PrintCompilerOptionBlocks blocks + exit 0 + +let displayVersion tcConfigB = + printfn "%s" tcConfigB.productNameForBannerText + exit 0 + +let miscFlagsBoth tcConfigB = + [ CompilerOption("nologo", tagNone, OptionUnit (fun () -> tcConfigB.showBanner <- false), None, Some (FSComp.SR.optsNologo())) + CompilerOption("version", tagNone, OptionUnit (fun () -> displayVersion tcConfigB), None, Some (FSComp.SR.optsVersion())) + ] + +let miscFlagsFsc tcConfigB = + miscFlagsBoth tcConfigB @ + [ CompilerOption("help", tagNone, OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, Some (FSComp.SR.optsHelp())) + CompilerOption("@", tagNone, OptionUnit ignore, None, Some (FSComp.SR.optsResponseFile())) + ] +let miscFlagsFsi tcConfigB = miscFlagsBoth tcConfigB + + +// OptionBlock: Abbreviations of existing options +//----------------------------------------------- + +let abbreviatedFlagsBoth tcConfigB = + [ + CompilerOption("d", tagString, OptionString (defineSymbol tcConfigB), None, Some(FSComp.SR.optsShortFormOf("--define"))) + CompilerOption("O", tagNone, OptionSwitch (SetOptimizeSwitch tcConfigB), None, Some(FSComp.SR.optsShortFormOf("--optimize[+|-]"))) + CompilerOption("g", tagNone, OptionSwitch (SetDebugSwitch tcConfigB None), None, Some(FSComp.SR.optsShortFormOf("--debug"))) + CompilerOption("i", tagString, OptionUnit (fun () -> tcConfigB.printSignature <- true), None, Some(FSComp.SR.optsShortFormOf("--sig"))) + CompilerOption("r", tagFile, OptionString (fun s -> tcConfigB.AddReferencedAssemblyByPath (rangeStartup, s)), + None, Some(FSComp.SR.optsShortFormOf("--reference"))) + CompilerOption("I", tagDirList, OptionStringList (fun s -> tcConfigB.AddIncludePath (rangeStartup, s, tcConfigB.implicitIncludeDir)), + None, Some (FSComp.SR.optsShortFormOf("--lib"))) + ] + +let abbreviatedFlagsFsi tcConfigB = abbreviatedFlagsBoth tcConfigB + +let abbreviatedFlagsFsc tcConfigB = + abbreviatedFlagsBoth tcConfigB @ + [ // FSC only abbreviated options + CompilerOption + ("o", tagString, + OptionString (setOutFileName tcConfigB), None, + Some(FSComp.SR.optsShortFormOf("--out"))) + + CompilerOption + ("a", tagString, + OptionUnit (fun () -> tcConfigB.target <- CompilerTarget.Dll), None, + Some(FSComp.SR.optsShortFormOf("--target library"))) + + // FSC help abbreviations. FSI has it's own help options... + CompilerOption + ("?", tagNone, + OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, + Some(FSComp.SR.optsShortFormOf("--help"))) + + CompilerOption + ("help", tagNone, + OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, + Some(FSComp.SR.optsShortFormOf("--help"))) + + CompilerOption + ("full-help", tagNone, + OptionHelp (fun blocks -> displayHelpFsc tcConfigB blocks), None, + Some(FSComp.SR.optsShortFormOf("--help"))) + ] + +let GetAbbrevFlagSet tcConfigB isFsc = + let mutable argList: string list = [] + for c in ((if isFsc then abbreviatedFlagsFsc else abbreviatedFlagsFsi) tcConfigB) do + match c with + | CompilerOption(arg, _, OptionString _, _, _) + | CompilerOption(arg, _, OptionStringList _, _, _) -> argList <- argList @ ["-"+arg;"/"+arg] + | _ -> () + Set.ofList argList + +// check for abbreviated options that accept spaces instead of colons, and replace the spaces +// with colons when necessary +let PostProcessCompilerArgs (abbrevArgs: string Set) (args: string []) = + let mutable i = 0 + let mutable idx = 0 + let len = args.Length + let mutable arga: string[] = Array.create len "" + + while i < len do + if not(abbrevArgs.Contains(args.[i])) || i = (len - 1) then + arga.[idx] <- args.[i] + i <- i+1 + else + arga.[idx] <- args.[i] + ":" + args.[i+1] + i <- i + 2 + idx <- idx + 1 + Array.toList arga.[0 .. (idx - 1)] + +// OptionBlock: QA options +//------------------------ + +let testingAndQAFlags _tcConfigB = + [ + CompilerOption + ("dumpAllCommandLineOptions", tagNone, + OptionHelp(fun blocks -> DumpCompilerOptionBlocks blocks), + None, None) // "Command line options") + ] + + +// Core compiler options, overview +//-------------------------------- + +(* The "core" compiler options are "the ones defined here". + Currently, fsi.exe has some additional options, defined in fsi.fs. + + The compiler options are put into blocks, named as Flags. + Some block options differ between fsc and fsi, in this case they split as FlagsFsc and FlagsFsi. + + The "service.fs" (language service) flags are the same as the fsc flags (except help options are removed). + REVIEW: is this correct? what about fsx files in VS and fsi options? + + Block | notes + ---------------------------|-------------------- + outputFileFlags | + inputFileFlags | + resourcesFlags | + codeGenerationFlags | + errorsAndWarningsFlags | + languageFlags | + miscFlags | + advancedFlags | + internalFlags | + abbreviatedFlags | + deprecatedFlags | REVIEW: some of these may have been valid for fsi.exe? + fsiSpecificFlags | These are defined later, in fsi.fs + ---------------------------|-------------------- +*) + +// Core compiler options exported to fsc.fs, service.fs and fsi.fs +//---------------------------------------------------------------- + +/// The core/common options used by fsc.exe. [not currently extended by fsc.fs]. +let GetCoreFscCompilerOptions (tcConfigB: TcConfigBuilder) = + [ PublicOptions(FSComp.SR.optsHelpBannerOutputFiles(), outputFileFlagsFsc tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerInputFiles(), inputFileFlagsFsc tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerResources(), resourcesFlagsFsc tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerCodeGen(), codeGenerationFlags false tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerErrsAndWarns(), errorsAndWarningsFlags tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerLanguage(), languageFlags tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerMisc(), miscFlagsFsc tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), advancedFlagsFsc tcConfigB) + PrivateOptions(List.concat [ internalFlags tcConfigB + abbreviatedFlagsFsc tcConfigB + deprecatedFlagsFsc tcConfigB + testingAndQAFlags tcConfigB]) + ] + +/// The core/common options used by the F# VS Language Service. +/// Filter out OptionHelp which does printing then exit. This is not wanted in the context of VS!! +let GetCoreServiceCompilerOptions (tcConfigB:TcConfigBuilder) = + let isHelpOption = function CompilerOption(_, _, OptionHelp _, _, _) -> true | _ -> false + List.map (FilterCompilerOptionBlock (isHelpOption >> not)) (GetCoreFscCompilerOptions tcConfigB) + +/// The core/common options used by fsi.exe. [note, some additional options are added in fsi.fs]. +let GetCoreFsiCompilerOptions (tcConfigB: TcConfigBuilder) = + [ PublicOptions(FSComp.SR.optsHelpBannerOutputFiles(), outputFileFlagsFsi tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerInputFiles(), inputFileFlagsFsi tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerResources(), resourcesFlagsFsi tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerCodeGen(), codeGenerationFlags true tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerErrsAndWarns(), errorsAndWarningsFlags tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerLanguage(), languageFlags tcConfigB) + // Note: no HTML block for fsi.exe + PublicOptions(FSComp.SR.optsHelpBannerMisc(), miscFlagsFsi tcConfigB) + PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), advancedFlagsFsi tcConfigB) + PrivateOptions(List.concat [ internalFlags tcConfigB + abbreviatedFlagsFsi tcConfigB + deprecatedFlagsFsi tcConfigB + testingAndQAFlags tcConfigB]) + ] + +let ApplyCommandLineArgs(tcConfigB: TcConfigBuilder, sourceFiles: string list, argv) = + try + let sourceFilesAcc = ResizeArray sourceFiles + let collect name = if not (FileSystemUtils.isDll name) then sourceFilesAcc.Add name + ParseCompilerOptions(collect, GetCoreServiceCompilerOptions tcConfigB, argv) + ResizeArray.toList sourceFilesAcc + with e -> + errorRecovery e range0 + sourceFiles + + +//---------------------------------------------------------------------------- +// PrintWholeAssemblyImplementation +//---------------------------------------------------------------------------- + +let mutable showTermFileCount = 0 +let PrintWholeAssemblyImplementation g (tcConfig:TcConfig) outfile header expr = + if tcConfig.showTerms then + if tcConfig.writeTermsToFiles then + let filename = outfile + ".terms" + use f = FileSystem.OpenFileForWriteShim(filename + "-" + string showTermFileCount + "-" + header, FileMode.Create).GetWriter() + showTermFileCount <- showTermFileCount + 1 + LayoutRender.outL f (Display.squashTo 192 (DebugPrint.implFilesL g expr)) + else + dprintf "\n------------------\nshowTerm: %s:\n" header + LayoutRender.outL stderr (Display.squashTo 192 (DebugPrint.implFilesL g expr)) + dprintf "\n------------------\n" + +//---------------------------------------------------------------------------- +// ReportTime +//---------------------------------------------------------------------------- + +let mutable tPrev = None +let mutable nPrev = None +let ReportTime (tcConfig:TcConfig) descr = + + match nPrev with + | None -> () + | Some prevDescr -> + if tcConfig.pause then + dprintf "[done '%s', entering '%s'] press to continue... " prevDescr descr + Console.ReadLine() |> ignore + // Intentionally putting this right after the pause so a debugger can be attached. + match tcConfig.simulateException with + | Some("fsc-oom") -> raise(OutOfMemoryException()) + | Some("fsc-an") -> raise(ArgumentNullException("simulated")) + | Some("fsc-invop") -> raise(InvalidOperationException()) + | Some("fsc-av") -> raise(AccessViolationException()) + | Some("fsc-aor") -> raise(ArgumentOutOfRangeException()) + | Some("fsc-dv0") -> raise(DivideByZeroException()) + | Some("fsc-nfn") -> raise(NotFiniteNumberException()) + | Some("fsc-oe") -> raise(OverflowException()) + | Some("fsc-atmm") -> raise(ArrayTypeMismatchException()) + | Some("fsc-bif") -> raise(BadImageFormatException()) + | Some("fsc-knf") -> raise(System.Collections.Generic.KeyNotFoundException()) + | Some("fsc-ior") -> raise(IndexOutOfRangeException()) + | Some("fsc-ic") -> raise(InvalidCastException()) + | Some("fsc-ip") -> raise(InvalidProgramException()) + | Some("fsc-ma") -> raise(MemberAccessException()) + | Some("fsc-ni") -> raise(NotImplementedException()) + | Some("fsc-nr") -> raise(NullReferenceException()) + | Some("fsc-oc") -> raise(OperationCanceledException()) + | Some("fsc-fail") -> failwith "simulated" + | _ -> () + + + + + if (tcConfig.showTimes || verbose) then + // Note that timing calls are relatively expensive on the startup path so we don't + // make this call unless showTimes has been turned on. + let timeNow = System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds + let maxGen = GC.MaxGeneration + let gcNow = [| for i in 0 .. maxGen -> GC.CollectionCount i |] + let ptime = System.Diagnostics.Process.GetCurrentProcess() + let wsNow = ptime.WorkingSet64/1000000L + + match tPrev, nPrev with + | Some (timePrev, gcPrev:int []), Some prevDescr -> + let spanGC = [| for i in 0 .. maxGen -> GC.CollectionCount i - gcPrev.[i] |] + dprintf "TIME: %4.1f Delta: %4.1f Mem: %3d" + timeNow (timeNow - timePrev) + wsNow + dprintf " G0: %3d G1: %2d G2: %2d [%s]\n" + spanGC.[Operators.min 0 maxGen] spanGC.[Operators.min 1 maxGen] spanGC.[Operators.min 2 maxGen] + prevDescr + + | _ -> () + tPrev <- Some (timeNow, gcNow) + + nPrev <- Some descr + +let ignoreFailureOnMono1_1_16 f = try f() with _ -> () + +let foreBackColor () = + try + let c = Console.ForegroundColor // may fail, perhaps on Mac, and maybe ForegroundColor is Black + let b = Console.BackgroundColor // may fail, perhaps on Mac, and maybe BackgroundColor is White + Some (c, b) + with + e -> None + +let DoWithColor newColor f = + match enableConsoleColoring, foreBackColor() with + | false, _ + | true, None -> + // could not get console colours, so no attempt to change colours, can not set them back + f() + | true, Some (c, _) -> + try + ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- newColor) + f() + finally + ignoreFailureOnMono1_1_16 (fun () -> Console.ForegroundColor <- c) + +let DoWithDiagnosticColor severity f = + match foreBackColor() with + | None -> f() + | Some (_, backColor) -> + let infoColor = if backColor = ConsoleColor.White then ConsoleColor.Blue else ConsoleColor.Green + let warnColor = if backColor = ConsoleColor.White then ConsoleColor.DarkBlue else ConsoleColor.Cyan + let errorColor = ConsoleColor.Red + let color = + match severity with + | FSharpDiagnosticSeverity.Error -> errorColor + | FSharpDiagnosticSeverity.Warning -> warnColor + | _ -> infoColor + DoWithColor color f diff --git a/src/fsharp/CompilerOptions.fsi b/src/fsharp/CompilerOptions.fsi new file mode 100644 index 00000000000..a2f9c8cd10c --- /dev/null +++ b/src/fsharp/CompilerOptions.fsi @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Compiler Option Parser +module internal FSharp.Compiler.CompilerOptions + +open System +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.Diagnostics + +// For command-line options that can be suffixed with +/- +[] +type OptionSwitch = + | On + | Off + +/// The spec value describes the action of the argument, +/// and whether it expects a following parameter. +type OptionSpec = + | OptionClear of bool ref + | OptionFloat of (float -> unit) + | OptionInt of (int -> unit) + | OptionSwitch of (OptionSwitch -> unit) + | OptionIntList of (int -> unit) + | OptionIntListSwitch of (int -> OptionSwitch -> unit) + | OptionRest of (string -> unit) + | OptionSet of bool ref + | OptionString of (string -> unit) + | OptionStringList of (string -> unit) + | OptionStringListSwitch of (string -> OptionSwitch -> unit) + | OptionUnit of (unit -> unit) + | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" + | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) + +and CompilerOption = + | CompilerOption of name: string * argumentDescriptionString: string * actionSpec: OptionSpec * deprecationError: Option * helpText: string option + +and CompilerOptionBlock = + | PublicOptions of heading: string * options: CompilerOption list + | PrivateOptions of options: CompilerOption list + +val PrintCompilerOptionBlocks: CompilerOptionBlock list -> unit // for printing usage + +val DumpCompilerOptionBlocks: CompilerOptionBlock list -> unit // for QA + +val FilterCompilerOptionBlock: (CompilerOption -> bool) -> CompilerOptionBlock -> CompilerOptionBlock + +/// Parse and process a set of compiler options +val ParseCompilerOptions: (string -> unit) * CompilerOptionBlock list * string list -> unit + +val DisplayBannerText: TcConfigBuilder -> unit + +val GetCoreFscCompilerOptions: TcConfigBuilder -> CompilerOptionBlock list + +val GetCoreFsiCompilerOptions: TcConfigBuilder -> CompilerOptionBlock list + +val GetCoreServiceCompilerOptions: TcConfigBuilder -> CompilerOptionBlock list + +/// Apply args to TcConfigBuilder and return new list of source files +val ApplyCommandLineArgs: tcConfigB: TcConfigBuilder * sourceFiles: string list * argv: string list -> string list + +// Expose the "setters" for some user switches, to enable setting of defaults +val SetOptimizeSwitch: TcConfigBuilder -> OptionSwitch -> unit + +val SetTailcallSwitch: TcConfigBuilder -> OptionSwitch -> unit + +val SetDebugSwitch: TcConfigBuilder -> string option -> OptionSwitch -> unit + +val PrintOptionInfo: TcConfigBuilder -> unit + +val SetTargetProfile: TcConfigBuilder -> string -> unit + +// Miscellany +val ignoreFailureOnMono1_1_16: (unit -> unit) -> unit + +val mutable enableConsoleColoring: bool + +val DoWithColor: ConsoleColor -> (unit -> 'a) -> 'a + +val DoWithDiagnosticColor: FSharpDiagnosticSeverity -> (unit -> 'a) -> 'a + +val ReportTime: TcConfig -> string -> unit + +val GetAbbrevFlagSet: TcConfigBuilder -> bool -> Set + +val PostProcessCompilerArgs: string Set -> string [] -> string list diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 0360d253dd1..34f20beda0c 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -27,30 +27,45 @@ // can-unify predicates used in method overload resolution and trait constraint // satisfaction. // +// The two main principles are: +// 1. Ensure any solution that is found is sound (no logic is skipped), +// 2. Because of method overloading and SRTP constraints and other constructs, processing of +// constraints is algorithmic and must proceed in a definite, fixed order. +// Once we start doing resolutions in a particular order we must keep doing them +// in the same order. +// +// There is little use of back-tracking/undo or "retry" in the constraint solver, except in the +// limited case ofs of SRTP solving and method overloading, and some other adhoc limited cases +// like checking for "printf" format strings. As a result there are cases involving +// method overloading and SRTP that the solver "can't solve". This is intentional and by-design. //------------------------------------------------------------------------- - module internal FSharp.Compiler.ConstraintSolver open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Rational open FSharp.Compiler open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Infos open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.AttributeChecking -open FSharp.Compiler.Lib -open FSharp.Compiler.MethodCalls -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range -open FSharp.Compiler.Rational +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.Import open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.Infos +open FSharp.Compiler.MethodCalls +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeRelations //------------------------------------------------------------------------- @@ -62,30 +77,35 @@ open FSharp.Compiler.TypeRelations let compgenId = mkSynId range0 unassignedTyparName let NewCompGenTypar (kind, rigid, staticReq, dynamicReq, error) = - NewTypar(kind, rigid, Typar(compgenId, staticReq, true), error, dynamicReq, [], false, false) + Construct.NewTypar(kind, rigid, SynTypar(compgenId, staticReq, true), error, dynamicReq, [], false, false) let AnonTyparId m = mkSynId m unassignedTyparName let NewAnonTypar (kind, m, rigid, var, dyn) = - NewTypar (kind, rigid, Typar(AnonTyparId m, var, true), false, dyn, [], false, false) + Construct.NewTypar (kind, rigid, SynTypar(AnonTyparId m, var, true), false, dyn, [], false, false) let NewNamedInferenceMeasureVar (_m, rigid, var, id) = - NewTypar(TyparKind.Measure, rigid, Typar(id, var, false), false, TyparDynamicReq.No, [], false, false) + Construct.NewTypar(TyparKind.Measure, rigid, SynTypar(id, var, false), false, TyparDynamicReq.No, [], false, false) -let NewInferenceMeasurePar () = NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, false) +let NewInferenceMeasurePar () = + NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) -let NewErrorTypar () = NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true) +let NewErrorTypar () = + NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, true) -let NewErrorMeasureVar () = NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, NoStaticReq, TyparDynamicReq.No, true) +let NewErrorMeasureVar () = + NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, true) -let NewInferenceType () = mkTyparTy (NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, NoStaticReq, true), false, TyparDynamicReq.No, [], false, false)) +let NewInferenceType () = + mkTyparTy (Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, SynTypar(compgenId, TyparStaticReq.None, true), false, TyparDynamicReq.No, [], false, false)) -let NewErrorType () = mkTyparTy (NewErrorTypar ()) +let NewErrorType () = + mkTyparTy (NewErrorTypar ()) let NewErrorMeasure () = Measure.Var (NewErrorMeasureVar ()) let NewByRefKindInferenceType (g: TcGlobals) m = - let tp = NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, HeadTypeStaticReq, true), false, TyparDynamicReq.No, [], false, false) + let tp = Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, SynTypar(compgenId, TyparStaticReq.HeadType, true), false, TyparDynamicReq.No, [], false, false) if g.byrefkind_InOut_tcr.CanDeref then tp.SetConstraints [TyparConstraint.DefaultsTo(10, TType_app(g.byrefkind_InOut_tcr, []), m)] mkTyparTy tp @@ -118,7 +138,6 @@ let FreshenMethInfo m (minfo: MethInfo) = let _, _, tptys = FreshMethInst m (minfo.GetFormalTyparsOfDeclaringType m) minfo.DeclaringTypeInst minfo.FormalMethodTypars tptys - //------------------------------------------------------------------------- // Unification of types: solve/record equality constraints // Subsumption of types: solve/record subtyping constraints @@ -171,45 +190,71 @@ type ContextInfo = /// The type equation comes from a sequence expression. | SequenceExpression of TType -exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range +/// Captures relevant information for a particular failed overload resolution. +type OverloadInformation = + { + methodSlot: CalledMeth + infoReader : InfoReader + error: exn + } + +/// Cases for overload resolution failure that exists in the implementation of the compiler. +type OverloadResolutionFailure = + | NoOverloadsFound of + methodName: string * + candidates: OverloadInformation list * + cx: TraitConstraintInfo option + | PossibleCandidates of + methodName: string * + candidates: OverloadInformation list * + cx: TraitConstraintInfo option + +type OverallTy = + /// Each branch of the expression must have the type indicated + | MustEqual of TType + + /// Each branch of the expression must convert to the type indicated + | MustConvertTo of isMethodArg: bool * ty: TType + + /// Represents a point where no subsumption/widening is possible + member x.Commit = + match x with + | MustEqual ty -> ty + | MustConvertTo (_, ty) -> ty + +exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo -exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * TType * TType * range * range +exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * argTy: TType * paramTy: TType * callRange: range * parameterRange: range -exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Tast.Typar * Tast.TyparConstraint * range * range +exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range exception ConstraintSolverError of string * range * range exception ConstraintSolverRelatedInformation of string option * range * exn -exception ErrorFromApplyingDefault of tcGlobals: TcGlobals * displayEnv: DisplayEnv * Tast.Typar * TType * exn * range +exception ErrorFromApplyingDefault of tcGlobals: TcGlobals * displayEnv: DisplayEnv * Typar * TType * exn * range -exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * range +exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * actualTy: TType * expectedTy: TType * exn * range -exception ErrorsFromAddingSubsumptionConstraint of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * ContextInfo * range +exception ErrorsFromAddingSubsumptionConstraint of tcGlobals: TcGlobals * displayEnv: DisplayEnv * actualTy: TType * expectedTy: TType * exn * ContextInfo * parameterRange: range exception ErrorFromAddingConstraint of displayEnv: DisplayEnv * exn * range -exception PossibleOverload of displayEnv: DisplayEnv * string * exn * range - -exception UnresolvedOverloading of displayEnv: DisplayEnv * exn list * string * range +exception UnresolvedOverloading of displayEnv: DisplayEnv * callerArgs: CallerArgs * failure: OverloadResolutionFailure * range exception UnresolvedConversionOperator of displayEnv: DisplayEnv * TType * TType * range -let GetPossibleOverloads amap m denv (calledMethGroup: (CalledMeth<_> * exn) list) = - calledMethGroup |> List.map (fun (cmeth, e) -> - PossibleOverload(denv, NicePrint.stringOfMethInfo amap m denv cmeth.Method, e, m)) - -type TcValF = (ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) +type TcValF = ValRef -> ValUseFlag -> TType list -> range -> Expr * TType type ConstraintSolverState = { g: TcGlobals - amap: Import.ImportMap + amap: ImportMap InfoReader: InfoReader @@ -220,7 +265,7 @@ type ConstraintSolverState = /// That is, there will be one entry in this table for each free type variable in /// each outstanding, unsolved, ungeneralized trait constraint. Constraints are removed from the table and resolved /// each time a solution to an index variable is found. - mutable ExtraCxs: HashMultiMap + mutable ExtraCxs: HashMultiMap } static member New(g, amap, infoReader, tcVal) = @@ -281,6 +326,22 @@ let rec occursCheck g un ty = // Predicates on types //------------------------------------------------------------------------- +/// Some additional solutions are forced prior to generalization (permitWeakResolution=true). These are, roughly speaking, rules +/// for binary-operand constraints arising from constructs such as "1.0 + x" where "x" is an unknown type. THe constraint here +/// involves two type parameters - one for the left, and one for the right. The left is already known to be Double. +/// In this situation (and in the absence of other evidence prior to generalization), constraint solving forces an assumption that +/// the right is also Double - this is "weak" because there is only weak evidence for it. +/// +/// permitWeakResolution also applies to resolutions of multi-type-variable constraints via method overloads. Method overloading gets applied even if +/// only one of the two type variables is known. +/// +/// During code gen we run with permitWeakResolution on, but we only apply it where one of the argument types for the built-in constraint resolution is +/// a variable type. +type PermitWeakResolution = + | Yes + | No + member x.Permit = match x with Yes -> true | No -> false + let rec isNativeIntegerTy g ty = typeEquivAux EraseMeasures g g.nativeint_ty ty || typeEquivAux EraseMeasures g g.unativeint_ty ty || @@ -300,10 +361,10 @@ let isUnsignedIntegerTy g ty = typeEquivAux EraseMeasures g g.unativeint_ty ty || typeEquivAux EraseMeasures g g.uint64_ty ty -let rec isIntegerOrIntegerEnumTy g ty = +let rec IsIntegerOrIntegerEnumTy g ty = isSignedIntegerTy g ty || isUnsignedIntegerTy g ty || - (isEnumTy g ty && isIntegerOrIntegerEnumTy g (underlyingTypeOfEnumTy g ty)) + (isEnumTy g ty && IsIntegerOrIntegerEnumTy g (underlyingTypeOfEnumTy g ty)) let isIntegerTy g ty = isSignedIntegerTy g ty || @@ -324,7 +385,7 @@ let isFpTy g ty = let isDecimalTy g ty = typeEquivAux EraseMeasures g g.decimal_ty ty -let IsNonDecimalNumericOrIntegralEnumType g ty = isIntegerOrIntegerEnumTy g ty || isFpTy g ty +let IsNonDecimalNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty let IsNumericOrIntegralEnumType g ty = IsNonDecimalNumericOrIntegralEnumType g ty || isDecimalTy g ty @@ -334,14 +395,27 @@ let IsNumericType g ty = IsNonDecimalNumericType g ty || isDecimalTy g ty let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty -// Get measure of type, float<_> or float32<_> or decimal<_> but not float=float<1> or float32=float32<1> or decimal=decimal<1> -let GetMeasureOfType g ty = - match ty with - | AppTy g (tcref, [tyarg]) -> - match stripTyEqns g tyarg with - | TType_measure ms when not (measureEquiv g ms Measure.One) -> Some (tcref, ms) - | _ -> None - | _ -> None +let IsCharOrStringType g ty = isCharTy g ty || isStringTy g ty + +/// Checks the argument type for a built-in solution to an op_Addition, op_Subtraction or op_Modulus constraint. +let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty) + +/// Checks the argument type for a built-in solution to a bitwise operator constraint +let IsBitwiseOpType g ty = IsIntegerOrIntegerEnumTy g ty || (isEnumTy g ty) + +/// Check the other type in a built-in solution for a binary operator. +/// For weak resolution, require a relevant primitive on one side. +/// For strong resolution, a variable type is permitted. +let IsBinaryOpOtherArgType g permitWeakResolution ty = + match permitWeakResolution with + | PermitWeakResolution.No -> + not (isTyparTy g ty) + + | PermitWeakResolution.Yes -> true + +/// Checks the argument type for a built-in solution to a get_Sign constraint. +let IsSignType g ty = + isSignedIntegerTy g ty || isFpTy g ty || isDecimalTy g ty type TraitConstraintSolution = | TTraitUnsolved @@ -415,12 +489,12 @@ let FilterEachThenUndo f meths = trace.Undo() match CheckNoErrorsAndGetWarnings res with | None -> None - | Some warns -> Some (calledMeth, warns, trace)) + | Some (warns, res) -> Some (calledMeth, warns, trace, res)) let ShowAccessDomain ad = match ad with | AccessibleFromEverywhere -> "public" - | AccessibleFrom(_, _) -> "accessible" + | AccessibleFrom _ -> "accessible" | AccessibleFromSomeFSharpCode -> "public, protected or internal" | AccessibleFromSomewhere -> "" @@ -429,8 +503,42 @@ let ShowAccessDomain ad = exception NonRigidTypar of displayEnv: DisplayEnv * string option * range * TType * TType * range -exception LocallyAbortOperationThatFailsToResolveOverload +/// Signal that there is still an unresolved overload in the constraint problem. The +/// unresolved overload constraint remains in the constraint state, and we skip any +/// further processing related to whichever overall adjustment to constraint solver state +/// is being processed. +/// +// NOTE: The addition of this abort+skip appears to be a mistake which has crept into F# type inference, +// and its status is currently under review. See https://github.com/dotnet/fsharp/pull/8294 and others. +// +// Here is the history: +// 1. The local abort was added as part of an attempted performance optimization https://github.com/dotnet/fsharp/pull/1650 +// This change was released in the VS2017 GA release. +// +// 2. However, it also impacts the logic of type inference, by skipping checking. +// Because of this an attempt was made to revert it in https://github.com/dotnet/fsharp/pull/4173. +// +// Unfortunately, existing code had begun to depend on the new behaviours enabled by the +// change, and the revert was abandoned before release in https://github.com/dotnet/fsharp/pull/4348 +// +// Comments on soundness: +// The use of the abort is normally sound because the SRTP constraint +// will be subject to further processing at a later point. +// +// However, it seems likely that the abort may result in other processing associated +// with an overall constraint being skipped (e.g. the processing related to subsequent elements +// of a tuple constraint). +exception AbortForFailedOverloadResolution + +/// This is used at (nearly all) entry points into the constraint solver to make sure that the +/// AbortForFailedOverloadResolution is caught and processing continues. +let inline TryD_IgnoreAbortForFailedOverloadResolution f1 f2 = + TryD f1 (function AbortForFailedOverloadResolution -> CompleteD | exn -> f2 exn) +/// used to provide detail about non matched argument in overload resolution error message +exception ArgDoesNotMatchError of error: ErrorsFromAddingSubsumptionConstraint * calledMeth: CalledMeth * calledArg: CalledArg * callerArg: CallerArg + +/// Represents a very local condition where we prefer to report errors before stripping type abbreviations. exception LocallyAbortOperationThatLosesAbbrevs let localAbortD = ErrorD LocallyAbortOperationThatLosesAbbrevs @@ -516,14 +624,14 @@ and SolveTypStaticReqTypar (csenv: ConstraintSolverEnv) trace req (tpr: Typar) = and SolveTypStaticReq (csenv: ConstraintSolverEnv) trace req ty = match req with - | NoStaticReq -> CompleteD - | HeadTypeStaticReq -> + | TyparStaticReq.None -> CompleteD + | TyparStaticReq.HeadType -> // requires that a type constructor be known at compile time match stripTyparEqns ty with | TType_measure ms -> let vs = ListMeasureVarOccsWithNonZeroExponents ms trackErrors { - for (tpr, _) in vs do + for tpr, _ in vs do return! SolveTypStaticReqTypar csenv trace req tpr } | _ -> @@ -617,8 +725,18 @@ let SimplifyMeasure g vars ms = else NewNamedInferenceMeasureVar (v.Range, TyparRigidity.Flexible, v.StaticReq, v.Id) let remainingvars = ListSet.remove typarEq v vars let newvarExpr = if SignRational e < 0 then Measure.Inv (Measure.Var newvar) else Measure.Var newvar - let newms = (ProdMeasures (List.map (fun (c, e') -> Measure.RationalPower (Measure.Con c, NegRational (DivRational e' e))) (ListMeasureConOccsWithNonZeroExponents g false ms) - @ List.map (fun (v', e') -> if typarEq v v' then newvarExpr else Measure.RationalPower (Measure.Var v', NegRational (DivRational e' e))) (ListMeasureVarOccsWithNonZeroExponents ms))) + let nonZeroCon = ListMeasureConOccsWithNonZeroExponents g false ms + let nonZeroVar = ListMeasureVarOccsWithNonZeroExponents ms + let newms = + ProdMeasures [ + for (c, e') in nonZeroCon do + Measure.RationalPower (Measure.Con c, NegRational (DivRational e' e)) + for (v', e') in nonZeroVar do + if typarEq v v' then + newvarExpr + else + Measure.RationalPower (Measure.Var v', NegRational (DivRational e' e)) + ] SubstMeasure v newms match vs with | [] -> (remainingvars, Some newvar) @@ -628,7 +746,7 @@ let SimplifyMeasure g vars ms = // Normalize a type ty that forms part of a unit-of-measure-polymorphic type scheme. // Generalizable are the unit-of-measure variables that remain to be simplified. Generalized // is a list of unit-of-measure variables that have already been generalized. -let rec SimplifyMeasuresInType g resultFirst ((generalizable, generalized) as param) ty = +let rec SimplifyMeasuresInType g resultFirst (generalizable, generalized as param) ty = match stripTyparEqns ty with | TType_ucase(_, l) | TType_app (_, l) @@ -732,7 +850,7 @@ let SimplifyMeasuresInTypeScheme g resultFirst (generalizable: Typar list) ty co match uvars with | [] -> generalizable | _ :: _ -> - let (_, generalized) = SimplifyMeasuresInType g resultFirst (SimplifyMeasuresInConstraints g (uvars, []) constraints) ty + let _, generalized = SimplifyMeasuresInType g resultFirst (SimplifyMeasuresInConstraints g (uvars, []) constraints) ty let generalized' = NormalizeExponentsInTypeScheme generalized ty vars @ List.rev generalized' @@ -760,32 +878,31 @@ let CheckWarnIfRigid (csenv: ConstraintSolverEnv) ty1 (r: Typar) ty = /// Add the constraint "ty1 = ty" to the constraint problem, where ty1 is a type variable. /// Propagate all effects of adding this constraint, e.g. to solve other variables -let rec SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty1 ty = trackErrors { - let m = csenv.m - do! DepthCheck ndeep m - match ty1 with - | TType_var r | TType_measure (Measure.Var r) -> - // The types may still be equivalent due to abbreviations, which we are trying not to eliminate - if typeEquiv csenv.g ty1 ty then () else - // The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/Microsoft/visualfsharp/issues/1170 - if occursCheck csenv.g r ty then return! ErrorD (ConstraintSolverInfiniteTypes(csenv.DisplayEnv, csenv.eContextInfo, ty1, ty, m, m2)) else - // Note: warn _and_ continue! - do! CheckWarnIfRigid csenv ty1 r ty - // Record the solution before we solve the constraints, since - // We may need to make use of the equation when solving the constraints. - // Record a entry in the undo trace if one is provided - trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) - - // Only solve constraints if this is not an error var - if r.IsFromError then () else - // Check to see if this type variable is relevant to any trait constraints. - // If so, re-solve the relevant constraints. - if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then - do! RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep false trace r) - // Re-solve the other constraints associated with this type variable - return! solveTypMeetsTyparConstraints csenv ndeep m2 trace ty r +let rec SolveTyparEqualsTypePart1 (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty1 r ty = trackErrors { + // The types may still be equivalent due to abbreviations, which we are trying not to eliminate + if typeEquiv csenv.g ty1 ty then () else + // The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/Microsoft/visualfsharp/issues/1170 + if occursCheck csenv.g r ty then return! ErrorD (ConstraintSolverInfiniteTypes(csenv.DisplayEnv, csenv.eContextInfo, ty1, ty, csenv.m, m2)) else + // Note: warn _and_ continue! + do! CheckWarnIfRigid csenv ty1 r ty + // Record the solution before we solve the constraints, since + // We may need to make use of the equation when solving the constraints. + // Record a entry in the undo trace if one is provided + trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) + } + +and SolveTyparEqualsTypePart2 (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (r: Typar) ty = trackErrors { + // Only solve constraints if this is not an error var + if r.IsFromError then () else + + // Check to see if this type variable is relevant to any trait constraints. + // If so, re-solve the relevant constraints. + if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then + do! RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep PermitWeakResolution.No trace r) + + // Re-solve the other constraints associated with this type variable + return! solveTypMeetsTyparConstraints csenv ndeep m2 trace ty r - | _ -> failwith "SolveTyparEqualsType" } /// Apply the constraints on 'typar' to the type 'ty' @@ -826,10 +943,32 @@ and solveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty | TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys | TyparConstraint.CoercesTo(ty2, m2) -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace None ty2 ty | TyparConstraint.MayResolveMember(traitInfo, m2) -> - SolveMemberConstraint csenv false false ndeep m2 trace traitInfo |> OperationResult.ignore + SolveMemberConstraint csenv false PermitWeakResolution.No ndeep m2 trace traitInfo |> OperationResult.ignore } +and SolveTyparEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) ty1 ty = trackErrors { + let m = csenv.m + do! DepthCheck ndeep m + match ty1 with + | TType_var r | TType_measure (Measure.Var r) -> + do! SolveTyparEqualsTypePart1 csenv m2 trace ty1 r ty + do! SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty + | _ -> failwith "SolveTyparEqualsType" + } + +// Like SolveTyparEqualsType but asserts all typar equalities simultaneously instead of one by one +and SolveTyparsEqualTypes (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) tptys tys = trackErrors { + do! (tptys, tys) ||> Iterate2D (fun tpty ty -> + match tpty with + | TType_var r | TType_measure (Measure.Var r) -> SolveTyparEqualsTypePart1 csenv m2 trace tpty r ty + | _ -> failwith "SolveTyparsEqualTypes") + do! (tptys, tys) ||> Iterate2D (fun tpty ty -> + match tpty with + | TType_var r | TType_measure (Measure.Var r) -> SolveTyparEqualsTypePart2 csenv ndeep m2 trace r ty + | _ -> failwith "SolveTyparsEqualTypes") + } + and SolveAnonInfoEqualsAnonInfo (csenv: ConstraintSolverEnv) m2 (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = if evalTupInfoIsStruct anonInfo1.TupInfo <> evalTupInfoIsStruct anonInfo2.TupInfo then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m,m2)) else (match anonInfo1.Assembly, anonInfo2.Assembly with @@ -897,13 +1036,13 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr | _, TType_var r when (r.Rigidity <> TyparRigidity.Rigid) && not csenv.MatchingOnly -> SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1> - | (_, TType_app (tc2, [ms])) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) + | _, TType_app (tc2, [ms]) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One) - | (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) + | TType_app (tc2, [ms]), _ when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One) | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 - | TType_app (_, _), TType_app (_, _) -> localAbortD + | TType_app _, TType_app _ -> localAbortD | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 @@ -929,8 +1068,9 @@ and private SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln t // Back out of expansions of type abbreviations to give improved error messages. // Note: any "normalization" of equations on type variables must respect the trace parameter TryD (fun () -> SolveTypeEqualsType csenv ndeep m2 trace cxsln ty1 ty2) - (function LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInEqualityRelation(csenv.DisplayEnv, ty1, ty2, csenv.m, m2, csenv.eContextInfo)) - | err -> ErrorD err) + (function + | LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInEqualityRelation(csenv.DisplayEnv, ty1, ty2, csenv.m, m2, csenv.eContextInfo)) + | err -> ErrorD err) and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = match origl1, origl2 with @@ -994,10 +1134,10 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional | TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2 // Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1> - | (_, TType_app (tc2, [ms])) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) + | _, TType_app (tc2, [ms]) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One) - | (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) + | TType_app (tc2, [ms]), _ when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One) // Special subsumption rule for byref tags @@ -1059,8 +1199,9 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional and SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace cxsln ty1 ty2 = let denv = csenv.DisplayEnv TryD (fun () -> SolveTypeSubsumesType csenv ndeep m2 trace cxsln ty1 ty2) - (function LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInSubsumptionRelation(denv, ty1, ty2, csenv.m, m2)) - | err -> ErrorD err) + (function + | LocallyAbortOperationThatLosesAbbrevs -> ErrorD(ConstraintSolverTypesNotInSubsumptionRelation(denv, ty1, ty2, csenv.m, m2)) + | err -> ErrorD err) //------------------------------------------------------------------------- // Solve and record non-equality constraints @@ -1080,7 +1221,7 @@ and DepthCheck ndeep m = // If this is a type that's parameterized on a unit-of-measure (expected to be numeric), unify its measure with 1 and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty = - match GetMeasureOfType csenv.g ty with + match getMeasureOfType csenv.g ty with | Some (tcref, _) -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty (mkAppTy tcref [TType_measure Measure.One]) | None -> @@ -1093,16 +1234,9 @@ and SolveDimensionlessNumericType (csenv: ConstraintSolverEnv) ndeep m2 trace ty /// don't. The type-directed static optimization rules in the library code that makes use of this /// will deal with the problem. /// -/// 2. Some additional solutions are forced prior to generalization (permitWeakResolution=true). These are, roughly speaking, rules -/// for binary-operand constraints arising from constructs such as "1.0 + x" where "x" is an unknown type. THe constraint here -/// involves two type parameters - one for the left, and one for the right. The left is already known to be Double. -/// In this situation (and in the absence of other evidence prior to generalization), constraint solving forces an assumption that -/// the right is also Double - this is "weak" because there is only weak evidence for it. -/// -/// permitWeakResolution also applies to resolutions of multi-type-variable constraints via method overloads. Method overloading gets applied even if -/// only one of the two type variables is known -/// -and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace (TTrait(tys, nm, memFlags, argtys, rty, sln)): OperationResult = trackErrors { +/// 2. Some additional solutions are forced prior to generalization (permitWeakResolution= Yes or YesDuringCodeGen). See above +and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace traitInfo : OperationResult = trackErrors { + let (TTrait(tys, nm, memFlags, traitObjAndArgTys, rty, sln)) = traitInfo // Do not re-solve if already solved if sln.Value.IsSome then return true else let g = csenv.g @@ -1115,20 +1249,21 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // Remove duplicates from the set of types in the support let tys = ListSet.setify (typeAEquiv g aenv) tys + // Rebuild the trait info after removing duplicates - let traitInfo = TTrait(tys, nm, memFlags, argtys, rty, sln) + let traitInfo = TTrait(tys, nm, memFlags, traitObjAndArgTys, rty, sln) let rty = GetFSharpViewOfReturnType g rty // Assert the object type if the constraint is for an instance member if memFlags.IsInstance then - match tys, argtys with - | [ty], (h :: _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty + match tys, traitObjAndArgTys with + | [ty], h :: _ -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2)) // Trait calls are only supported on pseudo type (variables) for e in tys do - do! SolveTypStaticReq csenv trace HeadTypeStaticReq e + do! SolveTypStaticReq csenv trace TyparStaticReq.HeadType e - let argtys = if memFlags.IsInstance then List.tail argtys else argtys + let argtys = if memFlags.IsInstance then List.tail traitObjAndArgTys else traitObjAndArgTys let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo @@ -1162,21 +1297,19 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // decimal<'u> * 'a (let checkRuleAppliesInPreferenceToMethods argty1 argty2 = // Check that at least one of the argument types is numeric - (IsNumericOrIntegralEnumType g argty1) && - // Check that the support of type variables is empty. That is, - // if we're canonicalizing, then having one of the types nominal is sufficient. - // If not, then both must be nominal (i.e. not a type variable). - (permitWeakResolution || not (isTyparTy g argty2)) && + IsNumericOrIntegralEnumType g argty1 && + // Check the other type is nominal, unless using weak resolution + IsBinaryOpOtherArgType g permitWeakResolution argty2 && // This next condition checks that either // - Neither type contributes any methods OR // - We have the special case "decimal<_> * decimal". In this case we have some // possibly-relevant methods from "decimal" but we ignore them in this case. - (isNil minfos || (Option.isSome (GetMeasureOfType g argty1) && isDecimalTy g argty2)) in + (isNil minfos || (Option.isSome (getMeasureOfType g argty1) && isDecimalTy g argty2)) in checkRuleAppliesInPreferenceToMethods argty1 argty2 || checkRuleAppliesInPreferenceToMethods argty2 argty1) -> - match GetMeasureOfType g argty1 with + match getMeasureOfType g argty1 with | Some (tcref, ms1) -> let ms2 = freshMeasure () do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 (mkAppTy tcref [TType_measure ms2]) @@ -1185,7 +1318,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload | _ -> - match GetMeasureOfType g argty2 with + match getMeasureOfType g argty2 with | Some (tcref, ms2) -> let ms1 = freshMeasure () do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure ms1]) @@ -1201,8 +1334,8 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argty1;argty2] when // Ignore any explicit +/- overloads from any basic integral types (minfos |> List.forall (fun minfo -> isIntegerTy g minfo.ApparentEnclosingType ) && - ( (IsNumericOrIntegralEnumType g argty1 || (nm = "op_Addition" && (isCharTy g argty1 || isStringTy g argty1))) && (permitWeakResolution || not (isTyparTy g argty2)) - || (IsNumericOrIntegralEnumType g argty2 || (nm = "op_Addition" && (isCharTy g argty2 || isStringTy g argty2))) && (permitWeakResolution || not (isTyparTy g argty1)))) -> + ( IsAddSubModType nm g argty1 && IsBinaryOpOtherArgType g permitWeakResolution argty2 + || IsAddSubModType nm g argty2 && IsBinaryOpOtherArgType g permitWeakResolution argty1)) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 return TTraitBuiltIn @@ -1210,8 +1343,8 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argty1;argty2] when // Ignore any explicit overloads from any basic integral types (minfos |> List.forall (fun minfo -> isIntegerTy g minfo.ApparentEnclosingType ) && - ( (IsRelationalType g argty1 && (permitWeakResolution || not (isTyparTy g argty2))) - || (IsRelationalType g argty2 && (permitWeakResolution || not (isTyparTy g argty1))))) -> + ( IsRelationalType g argty1 && IsBinaryOpOtherArgType g permitWeakResolution argty2 + || IsRelationalType g argty2 && IsBinaryOpOtherArgType g permitWeakResolution argty1)) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.bool_ty return TTraitBuiltIn @@ -1219,7 +1352,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // We pretend for uniformity that the numeric types have a static property called Zero and One // As with constants, only zero is polymorphic in its units | [], [ty], false, "get_Zero", [] - when IsNumericType g ty -> + when IsNumericType g ty || isCharTy g ty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty return TTraitBuiltIn @@ -1229,34 +1362,36 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty return TTraitBuiltIn - | [], _, false, ("DivideByInt"), [argty1;argty2] + | [], _, false, "DivideByInt", [argty1;argty2] when isFpTy g argty1 || isDecimalTy g argty1 -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 return TTraitBuiltIn // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item' - | [], [ty], true, ("get_Item"), [argty1] + | [], [ty], true, "get_Item", [argty1] when isStringTy g ty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 g.int_ty do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.char_ty return TTraitBuiltIn - | [], [ty], true, ("get_Item"), argtys + | [], [ty], true, "get_Item", argtys when isArrayTy g ty -> - if rankOfArrayTy g ty <> argtys.Length then do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argtys.Length), m, m2)) + if rankOfArrayTy g ty <> argtys.Length then + do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argtys.Length), m, m2)) for argty in argtys do do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty let ety = destArrayTy g ty do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ety return TTraitBuiltIn - | [], [ty], true, ("set_Item"), argtys + | [], [ty], true, "set_Item", argtys when isArrayTy g ty -> - if rankOfArrayTy g ty <> argtys.Length - 1 then do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argtys.Length - 1)), m, m2)) + if rankOfArrayTy g ty <> argtys.Length - 1 then + do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argtys.Length - 1)), m, m2)) let argtys, ety = List.frontAndBack argtys for argty in argtys do do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty @@ -1265,8 +1400,8 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return TTraitBuiltIn | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argty1;argty2] - when (isIntegerOrIntegerEnumTy g argty1 || (isEnumTy g argty1)) && (permitWeakResolution || not (isTyparTy g argty2)) - || (isIntegerOrIntegerEnumTy g argty2 || (isEnumTy g argty2)) && (permitWeakResolution || not (isTyparTy g argty1)) -> + when IsBitwiseOpType g argty1 && IsBinaryOpOtherArgType g permitWeakResolution argty2 + || IsBitwiseOpType g argty2 && IsBinaryOpOtherArgType g permitWeakResolution argty1 -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 @@ -1274,39 +1409,39 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return TTraitBuiltIn | [], _, false, ("op_LeftShift" | "op_RightShift"), [argty1;argty2] - when isIntegerOrIntegerEnumTy g argty1 -> + when IsIntegerOrIntegerEnumTy g argty1 -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 do! SolveDimensionlessNumericType csenv ndeep m2 trace argty1 return TTraitBuiltIn - | _, _, false, ("op_UnaryPlus"), [argty] + | _, _, false, "op_UnaryPlus", [argty] when IsNumericOrIntegralEnumType g argty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty return TTraitBuiltIn - | _, _, false, ("op_UnaryNegation"), [argty] + | _, _, false, "op_UnaryNegation", [argty] when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty return TTraitBuiltIn - | _, _, true, ("get_Sign"), [] - when (let argty = tys.Head in isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty) -> + | _, _, true, "get_Sign", [] + when IsSignType g tys.Head -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.int32_ty return TTraitBuiltIn | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argty] - when isIntegerOrIntegerEnumTy g argty -> + when IsIntegerOrIntegerEnumTy g argty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty do! SolveDimensionlessNumericType csenv ndeep m2 trace argty return TTraitBuiltIn - | _, _, false, ("Abs"), [argty] + | _, _, false, "Abs", [argty] when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty @@ -1314,7 +1449,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload | _, _, false, "Sqrt", [argty1] when isFpTy g argty1 -> - match GetMeasureOfType g argty1 with + match getMeasureOfType g argty1 with | Some (tcref, _) -> let ms1 = freshMeasure () do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))]) @@ -1331,7 +1466,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty return TTraitBuiltIn - | _, _, false, ("op_Explicit"), [argty] + | _, _, false, "op_Explicit", [argty] when (// The input type. (IsNonDecimalNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && // The output type @@ -1344,7 +1479,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return TTraitBuiltIn - | _, _, false, ("op_Explicit"), [argty] + | _, _, false, "op_Explicit", [argty] when (// The input type. (IsNumericOrIntegralEnumType g argty || isStringTy g argty) && // The output type @@ -1360,10 +1495,10 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 return TTraitBuiltIn - | _, _, false, ("Atan2"), [argty1; argty2] + | _, _, false, "Atan2", [argty1; argty2] when isFpTy g argty1 -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 - match GetMeasureOfType g argty1 with + match getMeasureOfType g argty1 with | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure Measure.One]) return TTraitBuiltIn @@ -1419,7 +1554,10 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(DecompileOpName nm), m, m2)) else match nm, argtys with - | "op_Explicit", [argty] -> return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion((NicePrint.prettyStringOfTy denv argty), (NicePrint.prettyStringOfTy denv rty)), m, m2)) + | "op_Explicit", [argty] -> + let argTyString = NicePrint.prettyStringOfTy denv argty + let rtyString = NicePrint.prettyStringOfTy denv rty + return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion(argTyString, rtyString), m, m2)) | _ -> let tyString = match tys with @@ -1445,13 +1583,17 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // curried members may not be used to satisfy constraints |> List.choose (fun minfo -> if minfo.IsCurried then None else - let callerArgs = argtys |> List.map (fun argty -> CallerArg(argty, m, false, dummyExpr)) + let callerArgs = + { Unnamed = [ (argtys |> List.map (fun argty -> CallerArg(argty, m, false, dummyExpr))) ] + Named = [ [ ] ] } let minst = FreshenMethInfo m minfo let objtys = minfo.GetObjArgTypes(amap, m, minst) - Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, [(callerArgs, [])], false, false, None))) + Some(CalledMeth(csenv.InfoReader, None, false, FreshenMethInfo, m, AccessibleFromEverywhere, minfo, minst, minst, None, objtys, callerArgs, false, false, None))) let methOverloadResult, errors = - trace.CollectThenUndoOrCommit (fun (a, _) -> Option.isSome a) (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) (0, 0) AccessibleFromEverywhere calledMethGroup false (Some rty)) + trace.CollectThenUndoOrCommit + (fun (a, _) -> Option.isSome a) + (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) CallerArgs.Empty AccessibleFromEverywhere calledMethGroup false (Some (MustEqual rty))) match anonRecdPropSearch, recdPropSearch, methOverloadResult with | Some (anonInfo, tinst, i), None, None -> @@ -1489,7 +1631,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload // If there's nothing left to learn then raise the errors. // Note: we should likely call MemberConstraintIsReadyForResolution here when permitWeakResolution=false but for stability // reasons we use the more restrictive isNil frees. - if (permitWeakResolution && MemberConstraintIsReadyForWeakResolution csenv traitInfo) || isNil frees then + if (permitWeakResolution.Permit && MemberConstraintIsReadyForWeakResolution csenv traitInfo) || isNil frees then do! errors // Otherwise re-record the trait waiting for canonicalization else @@ -1497,7 +1639,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload match errors with | ErrorResult (_, UnresolvedOverloading _) when not ignoreUnresolvedOverload && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> - return! ErrorD LocallyAbortOperationThatFailsToResolveOverload + return! ErrorD AbortForFailedOverloadResolution | _ -> return TTraitUnsolved } @@ -1542,10 +1684,13 @@ and MemberConstraintSolutionOfMethInfo css m minfo minst = let mref = IL.mkRefToILMethod (ilMeth.DeclaringTyconRef.CompiledRepresentationForNamedType, ilMeth.RawMetadata) let iltref = ilMeth.ILExtensionMethodDeclaringTyconRef |> Option.map (fun tcref -> tcref.CompiledRepresentationForNamedType) ILMethSln(ilMeth.ApparentEnclosingType, iltref, mref, minst) + | FSMeth(_, ty, vref, _) -> FSMethSln(ty, vref, minst) + | MethInfo.DefaultStructCtor _ -> error(InternalError("the default struct constructor was the unexpected solution to a trait constraint", m)) + #if !NO_EXTENSIONTYPING | ProvidedMeth(amap, mi, _, m) -> let g = amap.g @@ -1554,16 +1699,17 @@ and MemberConstraintSolutionOfMethInfo css m minfo minst = let objArgVars, objArgs = (if minfo.IsInstance then [mkLocal m "this" minfo.ApparentEnclosingType] else []) |> List.unzip let callMethInfoOpt, callExpr, callExprTy = ProvidedMethodCalls.BuildInvokerExpressionForProvidedMethodCall css.TcVal (g, amap, mi, objArgs, NeverMutates, false, ValUseFlag.NormalValUse, allArgs, m) let closedExprSln = ClosedExprSln (mkLambdas m [] (objArgVars@allArgVars) (callExpr, callExprTy) ) + // If the call is a simple call to an IL method with all the arguments in the natural order, then revert to use ILMethSln. // This is important for calls to operators on generated provided types. There is an (unchecked) condition // that generative providers do not re=order arguments or insert any more information into operator calls. match callMethInfoOpt, callExpr with - | Some methInfo, Expr.Op (TOp.ILCall (_useCallVirt, _isProtected, _, _isNewObj, NormalValUse, _isProp, _noTailCall, ilMethRef, _actualTypeInst, actualMethInst, _ilReturnTys), [], args, m) + | Some methInfo, Expr.Op (TOp.ILCall (_, _, _, _, NormalValUse, _, _, ilMethRef, _, methInst, _), [], args, m) when (args, (objArgVars@allArgVars)) ||> List.lengthsEqAndForall2 (fun a b -> match a with Expr.Val (v, _, _) -> valEq v.Deref b | _ -> false) -> - let declaringType = Import.ImportProvidedType amap m (methInfo.PApply((fun x -> x.DeclaringType), m)) + let declaringType = ImportProvidedType amap m (methInfo.PApply((fun x -> x.DeclaringType), m)) if isILAppTy g declaringType then let extOpt = None // EXTENSION METHODS FROM TYPE PROVIDERS: for extension methods coming from the type providers we would have something here. - ILMethSln(declaringType, extOpt, ilMethRef, actualMethInst) + ILMethSln(declaringType, extOpt, ilMethRef, methInst) else closedExprSln | _ -> @@ -1578,13 +1724,13 @@ and TransactMemberConstraintSolution traitInfo (trace: OptionalTrace) sln = /// Only consider overload resolution if canonicalizing or all the types are now nominal. /// That is, don't perform resolution if more nominal information may influence the set of available overloads -and GetRelevantMethodsForTrait (csenv: ConstraintSolverEnv) permitWeakResolution nm (TTrait(tys, _, memFlags, argtys, rty, soln) as traitInfo): MethInfo list = +and GetRelevantMethodsForTrait (csenv: ConstraintSolverEnv) (permitWeakResolution: PermitWeakResolution) nm (TTrait(tys, _, memFlags, argtys, rty, soln) as traitInfo): MethInfo list = let results = - if permitWeakResolution || MemberConstraintSupportIsReadyForDeterminingOverloads csenv traitInfo then + if permitWeakResolution.Permit || MemberConstraintSupportIsReadyForDeterminingOverloads csenv traitInfo then let m = csenv.m let minfos = match memFlags.MemberKind with - | MemberKind.Constructor -> + | SynMemberKind.Constructor -> tys |> List.map (GetIntrinsicConstructorInfosOfType csenv.SolverState.InfoReader m) | _ -> tys |> List.map (GetIntrinsicMethInfosOfType csenv.SolverState.InfoReader (Some nm) AccessibleFromSomeFSharpCode AllowMultiIntfInstantiations.Yes IgnoreOverrides m) @@ -1602,6 +1748,7 @@ and GetRelevantMethodsForTrait (csenv: ConstraintSolverEnv) permitWeakResolution |> List.exists (fun minfo2 -> MethInfosEquivByNameAndSig EraseAll true csenv.g csenv.amap m minfo2 minfo1))) else [] + // The trait name "op_Explicit" also covers "op_Implicit", so look for that one too. if nm = "op_Explicit" then results @ GetRelevantMethodsForTrait csenv permitWeakResolution "op_Implicit" (TTrait(tys, "op_Implicit", memFlags, argtys, rty, soln)) @@ -1666,9 +1813,9 @@ and SolveRelevantMemberConstraintsForTypar (csenv: ConstraintSolverEnv) ndeep pe SolveMemberConstraint csenv true permitWeakResolution (ndeep+1) m2 trace traitInfo) and CanonicalizeRelevantMemberConstraints (csenv: ConstraintSolverEnv) ndeep trace tps = - SolveRelevantMemberConstraints csenv ndeep true trace tps + SolveRelevantMemberConstraints csenv ndeep PermitWeakResolution.Yes trace tps -and AddMemberConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace traitInfo support frees = +and AddMemberConstraint (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) traitInfo support (frees: Typar list) = let g = csenv.g let aenv = csenv.EquivEnv let cxst = csenv.SolverState.ExtraCxs @@ -1771,7 +1918,7 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ - | TyparConstraint.SimpleChoice (_, _), TyparConstraint.SimpleChoice (_, _) -> + | TyparConstraint.SimpleChoice _, TyparConstraint.SimpleChoice _ -> CompleteD | _ -> CompleteD @@ -1891,7 +2038,7 @@ and SolveTypeSupportsComparison (csenv: ConstraintSolverEnv) ndeep m2 trace ty = AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsComparison m) | ValueNone -> // Check it isn't ruled out by the user - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when HasFSharpAttribute g g.attrib_NoComparisonAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportComparison1(NicePrint.minimalStringOfType denv ty), m, m2)) | _ -> @@ -1934,7 +2081,7 @@ and SolveTypeSupportsEquality (csenv: ConstraintSolverEnv) ndeep m2 trace ty = | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsEquality m) | _ -> - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportEquality1(NicePrint.minimalStringOfType denv ty), m, m2)) | _ -> @@ -2011,6 +2158,8 @@ and SolveTypeIsNonNullableValueType (csenv: ConstraintSolverEnv) ndeep m2 trace if isStructTy g underlyingTy then if isNullableTy g underlyingTy then return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeParameterCannotBeNullable(), m, m)) + else + return! CompleteD else return! ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresStructType(NicePrint.minimalStringOfType denv ty), m, m2)) } @@ -2038,8 +2187,10 @@ and SolveTypeChoice (csenv: ConstraintSolverEnv) ndeep m2 trace ty tys = AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SimpleChoice(tys, m)) | _ -> if List.exists (typeEquivAux Erasure.EraseMeasures g ty) tys then CompleteD - else ErrorD (ConstraintSolverError(FSComp.SR.csTypeNotCompatibleBecauseOfPrintf((NicePrint.minimalStringOfType denv ty), (String.concat "," (List.map (NicePrint.prettyStringOfTy denv) tys))), m, m2)) - + else + let tyString = NicePrint.minimalStringOfType denv ty + let tysString = tys |> List.map (NicePrint.prettyStringOfTy denv) |> String.concat "," + ErrorD (ConstraintSolverError(FSComp.SR.csTypeNotCompatibleBecauseOfPrintf(tyString, tysString), m, m2)) and SolveTypeIsReferenceType (csenv: ConstraintSolverEnv) ndeep m2 trace ty = let g = csenv.g @@ -2059,22 +2210,31 @@ and SolveTypeRequiresDefaultConstructor (csenv: ConstraintSolverEnv) ndeep m2 tr let denv = csenv.DisplayEnv let ty = stripTyEqnsAndMeasureEqns g origTy match tryDestTyparTy g ty with - | ValueSome destTypar -> - AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.RequiresDefaultConstructor m) + | ValueSome tp -> + AddConstraint csenv ndeep m2 trace tp (TyparConstraint.RequiresDefaultConstructor m) | _ -> - if isStructTy g ty && TypeHasDefaultValue g m ty then - CompleteD + if isStructTy g ty then + if isStructTupleTy g ty then + destStructTupleTy g ty |> IterateD (SolveTypeRequiresDefaultValue csenv ndeep m trace) + elif isStructAnonRecdTy g ty then + match tryDestAnonRecdTy g ty with + | ValueNone -> CompleteD + | ValueSome (_, ptys) -> ptys |> IterateD (SolveTypeRequiresDefaultValue csenv ndeep m trace) + elif TypeHasDefaultValue g m ty then + CompleteD + else + ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresPublicDefaultConstructor(NicePrint.minimalStringOfType denv origTy), m, m2)) else if GetIntrinsicConstructorInfosOfType csenv.InfoReader m ty |> List.exists (fun x -> x.IsNullary && IsMethInfoAccessible amap m AccessibleFromEverywhere x) then - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when HasFSharpAttribute g g.attrib_AbstractClassAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresNonAbstract(NicePrint.minimalStringOfType denv origTy), m, m2)) | _ -> CompleteD else - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when tcref.PreEstablishedHasDefaultConstructor || // F# 3.1 feature: records with CLIMutable attribute should satisfy 'default constructor' constraint @@ -2083,17 +2243,46 @@ and SolveTypeRequiresDefaultConstructor (csenv: ConstraintSolverEnv) ndeep m2 tr | _ -> ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresPublicDefaultConstructor(NicePrint.minimalStringOfType denv origTy), m, m2)) +// Note, this constraint arises structurally when processing the element types of struct tuples and struct anonymous records. +// +// In the case of type variables, it requires that the type variable already have been pre-established to be either a (non-nullable) struct +// or a reference type. +and SolveTypeRequiresDefaultValue (csenv: ConstraintSolverEnv) ndeep m2 trace origTy = + let g = csenv.g + let m = csenv.m + let ty = stripTyEqnsAndMeasureEqns g origTy + if isTyparTy g ty then + if isNonNullableStructTyparTy g ty then + SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty + elif isReferenceTyparTy g ty then + SolveTypeSupportsNull csenv ndeep m2 trace ty + else + ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresStructOrReferenceConstraint(), m, m2)) + else + if isStructTy g ty then + SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty + else + SolveTypeSupportsNull csenv ndeep m2 trace ty + // Parameterized compatibility relation between member signatures. The real work // is done by "equateTypes" and "subsumeTypes" and "subsumeArg" and CanMemberSigsMatchUpToCheck (csenv: ConstraintSolverEnv) - permitOptArgs // are we allowed to supply optional and/or "param" arguments? - alwaysCheckReturn // always check the return type? - unifyTypes // used to equate the formal method instantiation with the actual method instantiation for a generic method, and the return types - subsumeTypes // used to compare the "obj" type - (subsumeArg: CalledArg -> CallerArg<_> -> OperationResult) // used to compare the arguments for compatibility - reqdRetTyOpt - (calledMeth: CalledMeth<_>): ImperativeOperationResult = + // are we allowed to supply optional and/or "param" arguments? + permitOptArgs + // always check the return type? + alwaysCheckReturn + // Used to equate the formal method instantiation with the actual method instantiation + // for a generic method, and the return types + (unifyTypes: TType -> TType -> OperationResult) + // Used to compare the "obj" type + (subsumeTypes: TType -> TType -> OperationResult) + // Used to convert the "return" for MustConvertTo + (subsumeOrConvertTypes: bool -> TType -> TType -> OperationResult) + // Used to convert the arguments + (subsumeOrConvertArg: CalledArg -> CallerArg<_> -> OperationResult) + (reqdRetTyOpt: OverallTy option) + (calledMeth: CalledMeth<_>): OperationResult = trackErrors { let g = csenv.g let amap = csenv.amap @@ -2111,41 +2300,60 @@ and CanMemberSigsMatchUpToCheck if minst.Length <> uminst.Length then return! ErrorD(Error(FSComp.SR.csTypeInstantiationLengthMismatch(), m)) else - do! Iterate2D unifyTypes minst uminst - if not (permitOptArgs || isNil unnamedCalledOptArgs) then - return! ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(), m)) - else - let calledObjArgTys = calledMeth.CalledObjArgTys(m) + let! usesTDC1 = MapCombineTDC2D unifyTypes minst uminst + let! usesTDC2 = + trackErrors { + if not (permitOptArgs || isNil unnamedCalledOptArgs) then + return! ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(), m)) + else + let calledObjArgTys = calledMeth.CalledObjArgTys(m) - // Check all the argument types. + // Check all the argument types. - if calledObjArgTys.Length <> callerObjArgTys.Length then - if calledObjArgTys.Length <> 0 then - return! ErrorD(Error (FSComp.SR.csMemberIsNotStatic(minfo.LogicalName), m)) + if calledObjArgTys.Length <> callerObjArgTys.Length then + if calledObjArgTys.Length <> 0 then + return! ErrorD(Error (FSComp.SR.csMemberIsNotStatic(minfo.LogicalName), m)) + else + return! ErrorD(Error (FSComp.SR.csMemberIsNotInstance(minfo.LogicalName), m)) + else + return! MapCombineTDC2D subsumeTypes calledObjArgTys callerObjArgTys + } + + let! usesTDC3 = + calledMeth.ArgSets |> MapCombineTDCD (fun argSet -> trackErrors { + if argSet.UnnamedCalledArgs.Length <> argSet.UnnamedCallerArgs.Length then + return! ErrorD(Error(FSComp.SR.csArgumentLengthMismatch(), m)) else - return! ErrorD(Error (FSComp.SR.csMemberIsNotInstance(minfo.LogicalName), m)) - else - do! Iterate2D subsumeTypes calledObjArgTys callerObjArgTys - for argSet in calledMeth.ArgSets do - if argSet.UnnamedCalledArgs.Length <> argSet.UnnamedCallerArgs.Length then - return! ErrorD(Error(FSComp.SR.csArgumentLengthMismatch(), m)) - else - do! Iterate2D subsumeArg argSet.UnnamedCalledArgs argSet.UnnamedCallerArgs - match calledMeth.ParamArrayCalledArgOpt with - | Some calledArg -> - if isArray1DTy g calledArg.CalledArgumentType then - let paramArrayElemTy = destArrayTy g calledArg.CalledArgumentType - let reflArgInfo = calledArg.ReflArgInfo // propagate the reflected-arg info to each param array argument - match calledMeth.ParamArrayCallerArgs with - | Some args -> - for callerArg in args do - do! subsumeArg (CalledArg((0, 0), false, NotOptional, NoCallerInfo, false, false, None, reflArgInfo, paramArrayElemTy)) callerArg - | _ -> () - | _ -> () - for argSet in calledMeth.ArgSets do - for arg in argSet.AssignedNamedArgs do - do! subsumeArg arg.CalledArg arg.CallerArg - for (AssignedItemSetter(_, item, caller)) in assignedItemSetters do + return! MapCombineTDC2D subsumeOrConvertArg argSet.UnnamedCalledArgs argSet.UnnamedCallerArgs + }) + + let! usesTDC4 = + match calledMeth.ParamArrayCalledArgOpt with + | Some calledArg -> + if isArray1DTy g calledArg.CalledArgumentType then + let paramArrayElemTy = destArrayTy g calledArg.CalledArgumentType + let reflArgInfo = calledArg.ReflArgInfo // propagate the reflected-arg info to each param array argument + match calledMeth.ParamArrayCallerArgs with + | Some args -> + args |> MapCombineTDCD (fun callerArg -> + subsumeOrConvertArg (CalledArg((0, 0), false, NotOptional, NoCallerInfo, false, false, None, reflArgInfo, paramArrayElemTy)) callerArg + ) + + + | _ -> ResultD TypeDirectedConversionUsed.No + else + ResultD TypeDirectedConversionUsed.No + | _ -> ResultD TypeDirectedConversionUsed.No + + let! usesTDC5 = + calledMeth.ArgSets |> MapCombineTDCD (fun argSet -> + argSet.AssignedNamedArgs |> MapCombineTDCD (fun arg -> + subsumeOrConvertArg arg.CalledArg arg.CallerArg + ) + ) + + let! usesTDC6 = + assignedItemSetters |> MapCombineTDCD (fun (AssignedItemSetter(_, item, caller)) -> let name, calledArgTy = match item with | AssignedPropSetter(_, pminfo, pminst) -> @@ -2159,19 +2367,28 @@ and CanMemberSigsMatchUpToCheck | AssignedRecdFieldSetter(rfinfo) -> let calledArgTy = rfinfo.FieldType - rfinfo.Name, calledArgTy + rfinfo.LogicalName, calledArgTy - do! subsumeArg (CalledArg((-1, 0), false, NotOptional, NoCallerInfo, false, false, Some (mkSynId m name), ReflectedArgInfo.None, calledArgTy)) caller - // - Always take the return type into account for + subsumeOrConvertArg (CalledArg((-1, 0), false, NotOptional, NoCallerInfo, false, false, Some (mkSynId m name), ReflectedArgInfo.None, calledArgTy)) caller + ) + + // - Always take the return type into account for resolving overloading of // -- op_Explicit, op_Implicit // -- methods using tupling of unfilled out args // - Never take into account return type information for constructors - match reqdRetTyOpt with - | Some _ when (minfo.IsConstructor || not alwaysCheckReturn && isNil unnamedCalledOutArgs) -> () - | Some reqdRetTy -> - let methodRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling - return! unifyTypes reqdRetTy methodRetTy - | _ -> () + let! usesTDC7 = + match reqdRetTyOpt with + | Some _ when ( (* minfo.IsConstructor || *) not alwaysCheckReturn && isNil unnamedCalledOutArgs) -> + ResultD TypeDirectedConversionUsed.No + | Some (MustConvertTo(isMethodArg, reqdTy)) when g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> + let methodRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling + subsumeOrConvertTypes isMethodArg reqdTy methodRetTy + | Some reqdRetTy -> + let methodRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling + unifyTypes reqdRetTy.Commit methodRetTy + | _ -> + ResultD TypeDirectedConversionUsed.No + return Array.reduce TypeDirectedConversionUsed.Combine [| usesTDC1; usesTDC2; usesTDC3; usesTDC4; usesTDC5; usesTDC6; usesTDC7 |] } // Assert a subtype constraint, and wrap an ErrorsFromAddingSubsumptionConstraint error around any failure @@ -2182,67 +2399,137 @@ and CanMemberSigsMatchUpToCheck // // "ty2 casts to ty1" // "a value of type ty2 can be used where a value of type ty1 is expected" -and private SolveTypeSubsumesTypeWithReport (csenv: ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = - TryD (fun () -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m trace cxsln ty1 ty2) - (function - | LocallyAbortOperationThatFailsToResolveOverload -> CompleteD - | res -> - match csenv.eContextInfo with - | ContextInfo.RuntimeTypeTest isOperator -> - // test if we can cast other way around - match CollectThenUndo (fun newTrace -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m (OptionalTrace.WithTrace newTrace) cxsln ty2 ty1) with - | OkResult _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, ContextInfo.DowncastUsedInsteadOfUpcast isOperator, m)) - | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, ContextInfo.NoContext, m)) - | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, csenv.eContextInfo, m))) +and private SolveTypeSubsumesTypeWithWrappedContextualReport (csenv: ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 wrapper = + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m trace cxsln ty1 ty2) + (fun res -> + match csenv.eContextInfo with + | ContextInfo.RuntimeTypeTest isOperator -> + // test if we can cast other way around + match CollectThenUndo (fun newTrace -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m (OptionalTrace.WithTrace newTrace) cxsln ty2 ty1) with + | OkResult _ -> ErrorD (wrapper (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, ContextInfo.DowncastUsedInsteadOfUpcast isOperator, m))) + | _ -> ErrorD (wrapper (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, ContextInfo.NoContext, m))) + | _ -> ErrorD (wrapper (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, csenv.eContextInfo, m)))) +and private SolveTypeSubsumesTypeWithReport (csenv: ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = + SolveTypeSubsumesTypeWithWrappedContextualReport csenv ndeep m trace cxsln ty1 ty2 id + // ty1: actual // ty2: expected and private SolveTypeEqualsTypeWithReport (csenv: ConstraintSolverEnv) ndeep m trace cxsln actual expected = - TryD (fun () -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m trace cxsln actual expected) - (function - | LocallyAbortOperationThatFailsToResolveOverload -> CompleteD - | res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g, csenv.DisplayEnv, actual, expected, res, m))) + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m trace cxsln actual expected) + (fun res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g, csenv.DisplayEnv, actual, expected, res, m))) and ArgsMustSubsumeOrConvert (csenv: ConstraintSolverEnv) + ad ndeep trace cxsln isConstraint + enforceNullableOptionalsKnownTypes // use known types from nullable optional args? (calledArg: CalledArg) (callerArg: CallerArg<'T>) = trackErrors { let g = csenv.g let m = callerArg.Range - let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg - do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArg.Type - if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.Type) then + let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg + match eqn with + | Some (ty1, ty2, msg) -> + do! SolveTypeEqualsTypeWithReport csenv ndeep m trace cxsln ty1 ty2 + msg csenv.DisplayEnv + | None -> () + match usesTDC with + | TypeDirectedConversionUsed.Yes warn -> do! WarnD(warn csenv.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArg.CallerArgumentType + if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) - else () + else + return usesTDC } -and MustUnify csenv ndeep trace cxsln ty1 ty2 = - SolveTypeEqualsTypeWithReport csenv ndeep csenv.m trace cxsln ty1 ty2 +// This is a slight variation on ArgsMustSubsumeOrConvert that adds contextual error report to the +// subsumption check. The two could likely be combines. +and ArgsMustSubsumeOrConvertWithContextualReport + (csenv: ConstraintSolverEnv) + ad + ndeep + trace + cxsln + isConstraint + calledMeth + calledArg + (callerArg: CallerArg) = + trackErrors { + let callerArgTy = callerArg.CallerArgumentType + let m = callerArg.Range + let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint true calledArg callerArg + match eqn with + | Some (ty1, ty2, msg) -> + do! SolveTypeEqualsType csenv ndeep m trace cxsln ty1 ty2 + msg csenv.DisplayEnv + | None -> () + match usesTDC with + | TypeDirectedConversionUsed.Yes warn -> do! WarnD(warn csenv.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + do! SolveTypeSubsumesTypeWithWrappedContextualReport csenv ndeep m trace cxsln calledArgTy callerArgTy (fun e -> ArgDoesNotMatchError(e :?> _, calledMeth, calledArg, callerArg)) + return usesTDC + } -and MustUnifyInsideUndo csenv ndeep trace cxsln ty1 ty2 = - SolveTypeEqualsTypeWithReport csenv ndeep csenv.m (WithTrace trace) cxsln ty1 ty2 +and TypesEquiv csenv ndeep trace cxsln ty1 ty2 = + trackErrors { + do! SolveTypeEqualsTypeWithReport csenv ndeep csenv.m trace cxsln ty1 ty2 + return TypeDirectedConversionUsed.No + } -and ArgsMustSubsumeOrConvertInsideUndo (csenv: ConstraintSolverEnv) ndeep trace cxsln isConstraint calledArg (CallerArg(callerArgTy, m, _, _) as callerArg) = - let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg - SolveTypeSubsumesTypeWithReport csenv ndeep m (WithTrace trace) cxsln calledArgTy callerArgTy +and TypesMustSubsume (csenv: ConstraintSolverEnv) ndeep trace cxsln m calledArgTy callerArgTy = + trackErrors { + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArgTy + return TypeDirectedConversionUsed.No + } -and TypesMustSubsumeOrConvertInsideUndo (csenv: ConstraintSolverEnv) ndeep trace cxsln m calledArgTy callerArgTy = - SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArgTy +and ReturnTypesMustSubsumeOrConvert (csenv: ConstraintSolverEnv) ad ndeep trace cxsln isConstraint m isMethodArg reqdTy actualTy = + trackErrors { + let reqdTy, usesTDC, eqn = AdjustRequiredTypeForTypeDirectedConversions csenv.InfoReader ad isMethodArg isConstraint reqdTy actualTy m + match eqn with + | Some (ty1, ty2, msg) -> + do! SolveTypeEqualsType csenv ndeep m trace cxsln ty1 ty2 + msg csenv.DisplayEnv + | None -> () + match usesTDC with + | TypeDirectedConversionUsed.Yes warn -> do! WarnD(warn csenv.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln reqdTy actualTy + return usesTDC + } -and ArgsEquivInsideUndo (csenv: ConstraintSolverEnv) isConstraint calledArg (CallerArg(callerArgTy, m, _, _) as callerArg) = - let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg - if typeEquiv csenv.g calledArgTy callerArgTy then CompleteD else ErrorD(Error(FSComp.SR.csArgumentTypesDoNotMatch(), m)) +and ArgsEquivOrConvert (csenv: ConstraintSolverEnv) ad ndeep trace cxsln isConstraint calledArg (callerArg: CallerArg<_>) = + trackErrors { + let callerArgTy = callerArg.CallerArgumentType + let m = callerArg.Range + let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint true calledArg callerArg + match eqn with + | Some (ty1, ty2, msg) -> + do! SolveTypeEqualsType csenv ndeep m trace cxsln ty1 ty2 + msg csenv.DisplayEnv + | None -> () + match usesTDC with + | TypeDirectedConversionUsed.Yes warn -> do! WarnD(warn csenv.DisplayEnv) + | TypeDirectedConversionUsed.No -> () + if not (typeEquiv csenv.g calledArgTy callerArgTy) then + return! ErrorD(Error(FSComp.SR.csArgumentTypesDoNotMatch(), m)) + else + return usesTDC + } and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nNamedCallerArgs) methodName ad (calledMethGroup: CalledMeth<_> list) isSequential = let amap = csenv.amap let m = csenv.m let denv = csenv.DisplayEnv + let infoReader = csenv.InfoReader match (calledMethGroup |> List.partition (CalledMeth.GetMethod >> IsMethInfoAccessible amap m ad)), (calledMethGroup |> List.partition (fun cmeth -> cmeth.HasCorrectObjArgs(m))), @@ -2256,7 +2543,7 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN Error (FSComp.SR.csMemberIsNotAccessible(methodName, (ShowAccessDomain ad)), m) else Error (FSComp.SR.csMemberIsNotAccessible2(methodName, (ShowAccessDomain ad)), m) - | _, ([], (cmeth :: _)), _, _, _ -> + | _, ([], cmeth :: _), _, _, _ -> // Check all the argument types. if cmeth.CalledObjArgTys(m).Length <> 0 then @@ -2267,13 +2554,13 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN // One method, incorrect name/arg assignment | _, _, _, _, ([], [cmeth]) -> let minfo = cmeth.Method - let msgNum, msgText = FSComp.SR.csRequiredSignatureIs(NicePrint.stringOfMethInfo amap m denv minfo) + let msgNum, msgText = FSComp.SR.csRequiredSignatureIs(NicePrint.stringOfMethInfo infoReader m denv minfo) match cmeth.UnassignedNamedArgs with | CallerNamedArg(id, _) :: _ -> if minfo.IsConstructor then let suggestFields (addToBuffer: string -> unit) = for p in minfo.DeclaringTyconRef.AllInstanceFieldsAsList do - addToBuffer(p.Name.Replace("@", "")) + addToBuffer(p.LogicalName.Replace("@", "")) ErrorWithSuggestions((msgNum, FSComp.SR.csCtorHasNoArgumentOrReturnProperty(methodName, id.idText, msgText)), id.idRange, id.idText, suggestFields) else @@ -2285,7 +2572,7 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN let minfo = cmeth.Method let nReqd = cmeth.TotalNumUnnamedCalledArgs let nActual = cmeth.TotalNumUnnamedCallerArgs - let signature = NicePrint.stringOfMethInfo amap m denv minfo + let signature = NicePrint.stringOfMethInfo infoReader m denv minfo if nActual = nReqd then let nreqdTyArgs = cmeth.NumCalledTyArgs let nactualTyArgs = cmeth.NumCallerTyArgs @@ -2310,7 +2597,7 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN else if nReqd > nActual then let diff = nReqd - nActual - let missingArgs = List.drop nReqd cmeth.AllUnnamedCalledArgs + let missingArgs = List.skip nReqd cmeth.AllUnnamedCalledArgs match NamesOfCalledArgs missingArgs with | [] -> if nActual = 0 then @@ -2327,14 +2614,14 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN Error (FSComp.SR.csMemberSignatureMismatchArityNamed(methodName, (nReqd+nReqdNamed), nActual, nReqdNamed, signature), m) // One or more accessible, all the same arity, none correct - | ((cmeth :: cmeths2), _), _, _, _, _ when not cmeth.HasCorrectArity && cmeths2 |> List.forall (fun cmeth2 -> cmeth.TotalNumUnnamedCalledArgs = cmeth2.TotalNumUnnamedCalledArgs) -> + | (cmeth :: cmeths2, _), _, _, _, _ when not cmeth.HasCorrectArity && cmeths2 |> List.forall (fun cmeth2 -> cmeth.TotalNumUnnamedCalledArgs = cmeth2.TotalNumUnnamedCalledArgs) -> Error (FSComp.SR.csMemberNotAccessible(methodName, nUnnamedCallerArgs, methodName, cmeth.TotalNumUnnamedCalledArgs), m) // Many methods, all with incorrect number of generic arguments - | _, _, _, ([], (cmeth :: _)), _ -> + | _, _, _, ([], cmeth :: _), _ -> let msg = FSComp.SR.csIncorrectGenericInstantiation((ShowAccessDomain ad), methodName, cmeth.NumCallerTyArgs) Error (msg, m) // Many methods of different arities, all incorrect - | _, _, ([], (cmeth :: _)), _, _ -> + | _, _, ([], cmeth :: _), _, _ -> let minfo = cmeth.Method Error (FSComp.SR.csMemberOverloadArityMismatch(methodName, cmeth.TotalNumUnnamedCallerArgs, (List.sum minfo.NumArgs)), m) | _ -> @@ -2352,11 +2639,11 @@ and ReportNoCandidatesError (csenv: ConstraintSolverEnv) (nUnnamedCallerArgs, nN |> ErrorD and ReportNoCandidatesErrorExpr csenv callerArgCounts methodName ad calledMethGroup = - let isSequential e = match e with | Expr.Sequential (_, _, _, _, _) -> true | _ -> false + let isSequential e = match e with | Expr.Sequential _ -> true | _ -> false ReportNoCandidatesError csenv callerArgCounts methodName ad calledMethGroup isSequential and ReportNoCandidatesErrorSynExpr csenv callerArgCounts methodName ad calledMethGroup = - let isSequential e = match e with | SynExpr.Sequential (_, _, _, _, _) -> true | _ -> false + let isSequential e = match e with | SynExpr.Sequential _ -> true | _ -> false ReportNoCandidatesError csenv callerArgCounts methodName ad calledMethGroup isSequential // Resolve the overloading of a method @@ -2367,14 +2654,15 @@ and ResolveOverloading methodName // The name of the method being called, for error reporting ndeep // Depth of inference cx // We're doing overload resolution as part of constraint solving, where special rules apply for op_Explicit and op_Implicit constraints. - callerArgCounts // How many named/unnamed args id the caller provide? + (callerArgs: CallerArgs) ad // The access domain of the caller, e.g. a module, type etc. calledMethGroup // The set of methods being called permitOptArgs // Can we supply optional arguments? - reqdRetTyOpt // The expected return type, if known + (reqdRetTyOpt: OverallTy option) // The expected return type, if known + : CalledMeth option * OperationResult = let g = csenv.g - let amap = csenv.amap + let infoReader = csenv.InfoReader let m = csenv.m let denv = csenv.DisplayEnv let isOpConversion = methodName = "op_Explicit" || methodName = "op_Implicit" @@ -2390,7 +2678,7 @@ and ResolveOverloading None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace | _, [] when not isOpConversion -> - None, ReportNoCandidatesErrorExpr csenv callerArgCounts methodName ad calledMethGroup, NoTrace + None, ReportNoCandidatesErrorExpr csenv callerArgs.CallerArgCounts methodName ad calledMethGroup, NoTrace | _, _ -> @@ -2402,37 +2690,43 @@ and ResolveOverloading // Exact match rule. // // See what candidates we have based on current inferred type information - // and _exact_ matches of argument types. - match candidates |> FilterEachThenUndo (fun newTrace calledMeth -> + // and exact matches of argument types. + let exactMatchCandidates = + candidates |> FilterEachThenUndo (fun newTrace calledMeth -> let cxsln = Option.map (fun traitInfo -> (traitInfo, MemberConstraintSolutionOfMethInfo csenv.SolverState m calledMeth.Method calledMeth.CalledTyArgs)) cx CanMemberSigsMatchUpToCheck csenv permitOptArgs alwaysCheckReturn - (MustUnifyInsideUndo csenv ndeep newTrace cxsln) - (TypesMustSubsumeOrConvertInsideUndo csenv ndeep (WithTrace newTrace) cxsln m) - (ArgsEquivInsideUndo csenv cx.IsSome) + (TypesEquiv csenv ndeep (WithTrace newTrace) cxsln) // instantiations equivalent + (TypesMustSubsume csenv ndeep (WithTrace newTrace) cxsln m) // obj can subsume + (ReturnTypesMustSubsumeOrConvert csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome m) // return can subsume or convert + (ArgsEquivOrConvert csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome) // args exact reqdRetTyOpt - calledMeth) with - | [(calledMeth, warns, _)] -> - Some calledMeth, OkResult (warns, ()), NoTrace // Can't re-play the trace since ArgsEquivInsideUndo was used + calledMeth) + + match exactMatchCandidates with + | [(calledMeth, warns, _, _usesTDC)] -> + Some calledMeth, OkResult (warns, ()), NoTrace | _ -> // Now determine the applicable methods. // Subsumption on arguments is allowed. - let applicable = candidates |> FilterEachThenUndo (fun newTrace candidate -> - let cxsln = Option.map (fun traitInfo -> (traitInfo, MemberConstraintSolutionOfMethInfo csenv.SolverState m candidate.Method candidate.CalledTyArgs)) cx - CanMemberSigsMatchUpToCheck - csenv - permitOptArgs - alwaysCheckReturn - (MustUnifyInsideUndo csenv ndeep newTrace cxsln) - (TypesMustSubsumeOrConvertInsideUndo csenv ndeep (WithTrace newTrace) cxsln m) - (ArgsMustSubsumeOrConvertInsideUndo csenv ndeep newTrace cxsln cx.IsSome) - reqdRetTyOpt - candidate) - - let failOverloading (msg: string) errors = + let applicable = + candidates |> FilterEachThenUndo (fun newTrace candidate -> + let cxsln = Option.map (fun traitInfo -> (traitInfo, MemberConstraintSolutionOfMethInfo csenv.SolverState m candidate.Method candidate.CalledTyArgs)) cx + CanMemberSigsMatchUpToCheck + csenv + permitOptArgs + alwaysCheckReturn + (TypesEquiv csenv ndeep (WithTrace newTrace) cxsln) // instantiations equivalent + (TypesMustSubsume csenv ndeep (WithTrace newTrace) cxsln m) // obj can subsume + (ReturnTypesMustSubsumeOrConvert csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome m) // return can subsume or convert + (ArgsMustSubsumeOrConvertWithContextualReport csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome candidate) // args can subsume + reqdRetTyOpt + candidate) + + let failOverloading overloadResolutionFailure = // Try to extract information to give better error for ambiguous op_Explicit and op_Implicit let convOpData = if isOpConversion then @@ -2445,13 +2739,10 @@ and ResolveOverloading match convOpData with | Some (fromTy, toTy) -> - UnresolvedConversionOperator (denv, fromTy, toTy, m) + UnresolvedConversionOperator (denv, fromTy, toTy.Commit, m) | None -> - // Otherwise collect a list of possible overloads - let overloads = GetPossibleOverloads amap m denv errors - // if list of overloads is not empty - append line with "The available overloads are shown below..." - let msg = if isNil overloads then msg else sprintf "%s %s" msg (FSComp.SR.csSeeAvailableOverloads ()) - UnresolvedOverloading (denv, overloads, msg, m) + // Otherwise pass the overload resolution failure for error printing in CompileOps + UnresolvedOverloading (denv, callerArgs, overloadResolutionFailure, m) match applicable with | [] -> @@ -2465,17 +2756,19 @@ and ResolveOverloading csenv permitOptArgs alwaysCheckReturn - (MustUnifyInsideUndo csenv ndeep newTrace cxsln) - (TypesMustSubsumeOrConvertInsideUndo csenv ndeep (WithTrace newTrace) cxsln m) - (ArgsMustSubsumeOrConvertInsideUndo csenv ndeep newTrace cxsln cx.IsSome) + (TypesEquiv csenv ndeep (WithTrace newTrace) cxsln) + (TypesMustSubsume csenv ndeep (WithTrace newTrace) cxsln m) + (ReturnTypesMustSubsumeOrConvert csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome m) + (ArgsMustSubsumeOrConvertWithContextualReport csenv ad ndeep (WithTrace newTrace) cxsln cx.IsSome calledMeth) reqdRetTyOpt calledMeth) with | OkResult _ -> None - | ErrorResult(_, exn) -> Some (calledMeth, exn)) + | ErrorResult(_warnings, exn) -> + Some {methodSlot = calledMeth; infoReader = infoReader; error = exn }) - None, ErrorD (failOverloading (FSComp.SR.csNoOverloadsFound methodName) errors), NoTrace + None, ErrorD (failOverloading (NoOverloadsFound (methodName, errors, cx))), NoTrace - | [(calledMeth, warns, t)] -> + | [(calledMeth, warns, t, _usesTDC)] -> Some calledMeth, OkResult (warns, ()), WithTrace t | applicableMeths -> @@ -2502,7 +2795,7 @@ and ResolveOverloading (calledArg1.CalledArgumentType, calledArg2.CalledArgumentType) ||> compareCond (fun ty1 ty2 -> // Func<_> is always considered better than any other delegate type - match tryDestAppTy csenv.g ty1 with + match tryTcrefOfAppTy csenv.g ty1 with | ValueSome tcref1 when tcref1.DisplayName = "Func" && (match tcref1.PublicPath with Some p -> p.EnclosingPath = [| "System" |] | _ -> false) && @@ -2513,14 +2806,26 @@ and ResolveOverloading | _ when isInByrefTy csenv.g ty2 && typeEquiv csenv.g ty1 (destByrefTy csenv.g ty2) -> true + // T is always better than Nullable from F# 5.0 onwards + | _ when g.langVersion.SupportsFeature(LanguageFeature.NullableOptionalInterop) && + isNullableTy csenv.g ty2 && + typeEquiv csenv.g ty1 (destNullableTy csenv.g ty2) -> + true + | _ -> false) if c <> 0 then c else 0 - let better (candidate: CalledMeth<_>, candidateWarnings, _) (other: CalledMeth<_>, otherWarnings, _) = + /// Check whether one overload is better than another + let better (candidate: CalledMeth<_>, candidateWarnings, _, usesTDC1) (other: CalledMeth<_>, otherWarnings, _, usesTDC2) = let candidateWarnCount = List.length candidateWarnings let otherWarnCount = List.length otherWarnings + + // Prefer methods that don't use type-directed conversion + let c = compare (match usesTDC1 with TypeDirectedConversionUsed.No -> 1 | _ -> 0) (match usesTDC2 with TypeDirectedConversionUsed.No -> 1 | _ -> 0) + if c <> 0 then c else + // Prefer methods that don't give "this code is less generic" warnings // Note: Relies on 'compare' respecting true > false let c = compare (candidateWarnCount = 0) (otherWarnCount = 0) @@ -2534,7 +2839,7 @@ and ResolveOverloading // Prefer methods with more precise param array arg type let c = if candidate.UsesParamArrayConversion && other.UsesParamArrayConversion then - compareTypes candidate.ParamArrayElementType other.ParamArrayElementType + compareTypes (candidate.GetParamArrayElementType()) (other.GetParamArrayElementType()) else 0 if c <> 0 then c else @@ -2549,7 +2854,7 @@ and ResolveOverloading let c = compare (not candidate.HasOptArgs) (not other.HasOptArgs) if c <> 0 then c else - // check regular args. The argument counts will only be different if one is using param args + // check regular unnamed args. The argument counts will only be different if one is using param args let c = if candidate.TotalNumUnnamedCalledArgs = other.TotalNumUnnamedCalledArgs then // For extension members, we also include the object argument type, if any in the comparison set @@ -2590,14 +2895,38 @@ and ResolveOverloading 0 if c <> 0 then c else - // Prefer non-generic methods // Note: Relies on 'compare' respecting true > false let c = compare candidate.CalledTyArgs.IsEmpty other.CalledTyArgs.IsEmpty if c <> 0 then c else + // F# 5.0 rule - prior to F# 5.0 named arguments (on the caller side) were not being taken + // into account when comparing overloads. So adding a name to an argument might mean + // overloads ould no longer be distinguished. We thus look at *all* arguments (whether + // optional or not) as an additional comparison technique. + let c = + if g.langVersion.SupportsFeature(LanguageFeature.NullableOptionalInterop) then + let cs = + let args1 = candidate.AllCalledArgs |> List.concat + let args2 = other.AllCalledArgs |> List.concat + if args1.Length = args2.Length then + (args1, args2) ||> List.map2 compareArg + else + [] + // "all args are at least as good, and one argument is actually better" + if cs |> List.forall (fun x -> x >= 0) && cs |> List.exists (fun x -> x > 0) then + 1 + // "all args are at least as bad, and one argument is actually worse" + elif cs |> List.forall (fun x -> x <= 0) && cs |> List.exists (fun x -> x < 0) then + -1 + // "argument lists are incomparable" + else + 0 + else + 0 + if c <> 0 then c else + 0 - let bestMethods = let indexedApplicableMeths = applicableMeths |> List.indexed @@ -2605,58 +2934,63 @@ and ResolveOverloading if indexedApplicableMeths |> List.forall (fun (j, other) -> i = j || let res = better candidate other - //eprintfn "\n-------\nCandidate: %s\nOther: %s\nResult: %d\n" (NicePrint.stringOfMethInfo amap m denv (fst candidate).Method) (NicePrint.stringOfMethInfo amap m denv (fst other).Method) res res > 0) then Some candidate else None) match bestMethods with - | [(calledMeth, warns, t)] -> Some calledMeth, OkResult (warns, ()), WithTrace t + | [(calledMeth, warns, t, _usesTDC)] -> Some calledMeth, OkResult (warns, ()), WithTrace t | bestMethods -> - let methodNames = - let methods = - // use the most precise set - // - if after filtering bestMethods still contains something - use it - // - otherwise use applicableMeths or initial set of candidate methods - match bestMethods with - | [] -> - match applicableMeths with - | [] -> candidates - | m -> m |> List.map (fun (x, _, _) -> x) - | m -> m |> List.map (fun (x, _, _) -> x) - - methods - |> List.map (fun cmeth -> NicePrint.stringOfMethInfo amap m denv cmeth.Method) - |> List.sort - let msg = FSComp.SR.csMethodIsOverloaded methodName - let msg = - match methodNames with - | [] -> msg - | names -> sprintf "%s %s" msg (FSComp.SR.csCandidates (String.concat ", " names)) - None, ErrorD (failOverloading msg []), NoTrace + let methods = + let getMethodSlotsAndErrors methodSlot errors = + [ match errors with + | [] -> yield { methodSlot = methodSlot; error = Unchecked.defaultof; infoReader = infoReader } + | errors -> for error in errors do yield { methodSlot = methodSlot; error = error; infoReader = infoReader } ] + + + // use the most precise set + // - if after filtering bestMethods still contains something - use it + // - otherwise use applicableMeths or initial set of candidate methods + [ match bestMethods with + | [] -> + match applicableMeths with + | [] -> for methodSlot in candidates do yield getMethodSlotsAndErrors methodSlot [] + | m -> for methodSlot, errors, _, _ in m do yield getMethodSlotsAndErrors methodSlot errors + | m -> for methodSlot, errors, _, _ in m do yield getMethodSlotsAndErrors methodSlot errors ] + + let methods = List.concat methods + + None, ErrorD (failOverloading (PossibleCandidates(methodName, methods,cx))), NoTrace // If we've got a candidate solution: make the final checks - no undo here! // Allow subsumption on arguments. Include the return type. // Unify return types. match calledMethOpt with - | Some calledMeth -> + | Some calledMeth -> + + // Static IL interfaces methods are not supported in lower F# versions. + if calledMeth.Method.IsILMethod && not calledMeth.Method.IsInstance && isInterfaceTy g calledMeth.Method.ApparentEnclosingType then + checkLanguageFeatureRuntimeErrorRecover csenv.InfoReader LanguageFeature.DefaultInterfaceMemberConsumption m + checkLanguageFeatureErrorRecover g.langVersion LanguageFeature.DefaultInterfaceMemberConsumption m + calledMethOpt, trackErrors { do! errors let cxsln = Option.map (fun traitInfo -> (traitInfo, MemberConstraintSolutionOfMethInfo csenv.SolverState m calledMeth.Method calledMeth.CalledTyArgs)) cx match calledMethTrace with | NoTrace -> - return! - // No trace available for CanMemberSigsMatchUpToCheck with ArgsMustSubsumeOrConvert + let! _usesTDC = CanMemberSigsMatchUpToCheck csenv permitOptArgs true - (MustUnify csenv ndeep trace cxsln) - (TypesMustSubsumeOrConvertInsideUndo csenv ndeep trace cxsln m)// REVIEW: this should not be an "InsideUndo" operation - (ArgsMustSubsumeOrConvert csenv ndeep trace cxsln cx.IsSome) + (TypesEquiv csenv ndeep trace cxsln) // instantiations equal + (TypesMustSubsume csenv ndeep trace cxsln m) // obj can subsume + (ReturnTypesMustSubsumeOrConvert csenv ad ndeep trace cxsln cx.IsSome m) // return can subsume or convert + (ArgsMustSubsumeOrConvert csenv ad ndeep trace cxsln cx.IsSome true) // args can subsume or convert reqdRetTyOpt calledMeth + return () | WithTrace calledMethTrc -> // Re-play existing trace @@ -2665,43 +2999,56 @@ and ResolveOverloading // Unify return type match reqdRetTyOpt with | None -> () - | Some _ when calledMeth.Method.IsConstructor -> () - | Some reqdRetTy -> + | Some reqdRetTy -> let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling - if isByrefTy g reqdRetTy then + if isByrefTy g reqdRetTy.Commit then return! ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m)) else - return! MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy + match reqdRetTy with + | MustConvertTo(isMethodArg, reqdRetTy) when g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions -> + let! _usesTDC = ReturnTypesMustSubsumeOrConvert csenv ad ndeep trace cxsln isMethodArg m isMethodArg reqdRetTy actualRetTy + return () + | _ -> + let! _usesTDC = TypesEquiv csenv ndeep trace cxsln reqdRetTy.Commit actualRetTy + return () + } | None -> None, errors +let ResolveOverloadingForCall denv css m methodName ndeep cx callerArgs ad calledMethGroup permitOptArgs reqdRetTyOpt = + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + ResolveOverloading csenv NoTrace methodName ndeep cx callerArgs ad calledMethGroup permitOptArgs reqdRetTyOpt /// This is used before analyzing the types of arguments in a single overload resolution let UnifyUniqueOverloading - (csenv: ConstraintSolverEnv) + denv + css + m callerArgCounts methodName ad (calledMethGroup: CalledMeth list) reqdRetTy // The expected return type, if known = + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv let m = csenv.m // See what candidates we have based on name and arity let candidates = calledMethGroup |> List.filter (fun cmeth -> cmeth.IsCandidate(m, ad)) let ndeep = 0 match calledMethGroup, candidates with | _, [calledMeth] -> trackErrors { - do! + let! _usesTDC = // Only one candidate found - we thus know the types we expect of arguments CanMemberSigsMatchUpToCheck csenv true // permitOptArgs true // always check return type - (MustUnify csenv ndeep NoTrace None) - (TypesMustSubsumeOrConvertInsideUndo csenv ndeep NoTrace None m) - (ArgsMustSubsumeOrConvert csenv ndeep NoTrace None false) // UnifyUniqueOverloading is not called in case of trait call - pass isConstraint=false + (TypesEquiv csenv ndeep NoTrace None) + (TypesMustSubsume csenv ndeep NoTrace None m) + (ReturnTypesMustSubsumeOrConvert csenv ad ndeep NoTrace None false m) + (ArgsMustSubsumeOrConvert csenv ad ndeep NoTrace None false false) (Some reqdRetTy) calledMeth return true @@ -2716,15 +3063,17 @@ let UnifyUniqueOverloading | _ -> ResultD false -let EliminateConstraintsForGeneralizedTypars csenv (trace: OptionalTrace) (generalizedTypars: Typars) = - // Remove the global constraints where this type variable appears in the support of the constraint - generalizedTypars - |> List.iter (fun tp -> +/// Remove the global constraints where these type variables appear in the support of the constraint +let EliminateConstraintsForGeneralizedTypars denv css m (trace: OptionalTrace) (generalizedTypars: Typars) = + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + for tp in generalizedTypars do let tpn = tp.Stamp let cxst = csenv.SolverState.ExtraCxs let cxs = cxst.FindAll tpn - cxs |> List.iter (fun cx -> trace.Exec (fun () -> cxst.Remove tpn) (fun () -> (csenv.SolverState.ExtraCxs.Add (tpn, cx)))) - ) + for cx in cxs do + trace.Exec + (fun () -> cxst.Remove tpn) + (fun () -> (csenv.SolverState.ExtraCxs.Add (tpn, cx))) //------------------------------------------------------------------------- @@ -2735,7 +3084,8 @@ let EliminateConstraintsForGeneralizedTypars csenv (trace: OptionalTrace) (gener //------------------------------------------------------------------------- let AddCxTypeEqualsType contextInfo denv css m actual expected = - SolveTypeEqualsTypeWithReport (MakeConstraintSolverEnv contextInfo css m denv) 0 m NoTrace None actual expected + let csenv = MakeConstraintSolverEnv contextInfo css m denv + SolveTypeEqualsTypeWithReport csenv 0 m NoTrace None actual expected |> RaiseOperationResult let UndoIfFailed f = @@ -2750,7 +3100,7 @@ let UndoIfFailed f = // Don't report warnings if we failed trace.Undo() false - | Some warns -> + | Some (warns, _) -> // Report warnings if we succeeded ReportWarnings warns true @@ -2761,26 +3111,32 @@ let UndoIfFailedOrWarnings f = try f trace |> CheckNoErrorsAndGetWarnings - with e -> None + with _ -> None match res with - | Some [] -> + | Some ([], _)-> true | _ -> trace.Undo() false let AddCxTypeEqualsTypeUndoIfFailed denv css m ty1 ty2 = - UndoIfFailed (fun trace -> SolveTypeEqualsTypeKeepAbbrevs (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m (WithTrace trace) ty1 ty2) + UndoIfFailed (fun trace -> + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + SolveTypeEqualsTypeKeepAbbrevs csenv 0 m (WithTrace trace) ty1 ty2) let AddCxTypeEqualsTypeUndoIfFailedOrWarnings denv css m ty1 ty2 = - UndoIfFailedOrWarnings (fun trace -> SolveTypeEqualsTypeKeepAbbrevs (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m (WithTrace trace) ty1 ty2) + UndoIfFailedOrWarnings (fun trace -> + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + SolveTypeEqualsTypeKeepAbbrevs csenv 0 m (WithTrace trace) ty1 ty2) let AddCxTypeEqualsTypeMatchingOnlyUndoIfFailed denv css m ty1 ty2 = let csenv = { MakeConstraintSolverEnv ContextInfo.NoContext css m denv with MatchingOnly = true } UndoIfFailed (fun trace -> SolveTypeEqualsTypeKeepAbbrevs csenv 0 m (WithTrace trace) ty1 ty2) let AddCxTypeMustSubsumeTypeUndoIfFailed denv css m ty1 ty2 = - UndoIfFailed (fun trace -> SolveTypeSubsumesTypeKeepAbbrevs (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m (WithTrace trace) None ty1 ty2) + UndoIfFailed (fun trace -> + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + SolveTypeSubsumesTypeKeepAbbrevs csenv 0 m (WithTrace trace) None ty1 ty2) let AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed denv css m ty1 ty2 = let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv @@ -2788,188 +3144,178 @@ let AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed denv css m ty1 ty2 = UndoIfFailed (fun trace -> SolveTypeSubsumesTypeKeepAbbrevs csenv 0 m (WithTrace trace) None ty1 ty2) let AddCxTypeMustSubsumeType contextInfo denv css m trace ty1 ty2 = - SolveTypeSubsumesTypeWithReport (MakeConstraintSolverEnv contextInfo css m denv) 0 m trace None ty1 ty2 + let csenv = MakeConstraintSolverEnv contextInfo css m denv + SolveTypeSubsumesTypeWithReport csenv 0 m trace None ty1 ty2 |> RaiseOperationResult let AddCxMethodConstraint denv css m trace traitInfo = - TryD (fun () -> + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> trackErrors { do! - SolveMemberConstraint (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) true false 0 m trace traitInfo + SolveMemberConstraint csenv true PermitWeakResolution.No 0 m trace traitInfo |> OperationResult.ignore }) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeMustSupportNull denv css m trace ty = - TryD (fun () -> SolveTypeSupportsNull (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeSupportsNull csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeMustSupportComparison denv css m trace ty = - TryD (fun () -> SolveTypeSupportsComparison (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeSupportsComparison csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeMustSupportEquality denv css m trace ty = - TryD (fun () -> SolveTypeSupportsEquality (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeSupportsEquality csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeMustSupportDefaultCtor denv css m trace ty = - TryD (fun () -> SolveTypeRequiresDefaultConstructor (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeRequiresDefaultConstructor csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeIsReferenceType denv css m trace ty = - TryD (fun () -> SolveTypeIsReferenceType (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeIsReferenceType csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeIsValueType denv css m trace ty = - TryD (fun () -> SolveTypeIsNonNullableValueType (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeIsNonNullableValueType csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeIsUnmanaged denv css m trace ty = - TryD (fun () -> SolveTypeIsUnmanaged (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeIsUnmanaged csenv 0 m trace ty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeIsEnum denv css m trace ty underlying = - TryD (fun () -> SolveTypeIsEnum (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty underlying) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeIsEnum csenv 0 m trace ty underlying) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult let AddCxTypeIsDelegate denv css m trace ty aty bty = - TryD (fun () -> SolveTypeIsDelegate (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m trace ty aty bty) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTypeIsDelegate csenv 0 m trace ty aty bty) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult -let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors { - let css = - { g = g - amap = amap - TcVal = tcVal - ExtraCxs = HashMultiMap(10, HashIdentity.Structural) - InfoReader = new InfoReader(g, amap) } +let AddCxTyparDefaultsTo denv css m ctxtInfo tp ridx ty = + let csenv = MakeConstraintSolverEnv ctxtInfo css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> AddConstraint csenv 0 m NoTrace tp (TyparConstraint.DefaultsTo(ridx, ty, m))) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + |> RaiseOperationResult +let SolveTypeAsError denv css m ty = + let ty2 = NewErrorType () + assert (destTyparTy css.g ty2).IsFromError + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + SolveTypeEqualsTypeKeepAbbrevs csenv 0 m NoTrace ty ty2 |> ignore + +let ApplyTyparDefaultAtPriority denv css priority (tp: Typar) = + tp.Constraints |> List.iter (fun tpc -> + match tpc with + | TyparConstraint.DefaultsTo(priority2, ty2, m) when priority2 = priority -> + let ty1 = mkTyparTy tp + if not tp.IsSolved && not (typeEquiv css.g ty1 ty2) then + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> + SolveTyparEqualsType csenv 0 m NoTrace ty1 ty2) + (fun res -> + SolveTypeAsError denv css m ty1 + ErrorD(ErrorFromApplyingDefault(css.g, denv, tp, ty2, res, m))) + |> RaiseOperationResult + | _ -> ()) + +let CreateCodegenState tcVal g amap = + { g = g + amap = amap + TcVal = tcVal + ExtraCxs = HashMultiMap(10, HashIdentity.Structural) + InfoReader = InfoReader(g, amap) } + +/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code +let CodegenWitnessExprForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors { + let css = CreateCodegenState tcVal g amap let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - let! _res = SolveMemberConstraint csenv true true 0 m NoTrace traitInfo - let sln = - match traitInfo.Solution with - | None -> Choice5Of5() - | Some sln -> - match sln with - | ILMethSln(origTy, extOpt, mref, minst) -> - let metadataTy = convertToTypeWithMetadataIfPossible g origTy - let tcref = tcrefOfAppTy g metadataTy - let mdef = IL.resolveILMethodRef tcref.ILTyconRawMetadata mref - let ilMethInfo = - match extOpt with - | None -> MethInfo.CreateILMeth(amap, m, origTy, mdef) - | Some ilActualTypeRef -> - let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef - MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef) - Choice1Of5 (ilMethInfo, minst) - | FSMethSln(ty, vref, minst) -> - Choice1Of5 (FSMeth(g, ty, vref, None), minst) - | FSRecdFieldSln(tinst, rfref, isSetProp) -> - Choice2Of5 (tinst, rfref, isSetProp) - | FSAnonRecdFieldSln(anonInfo, tinst, i) -> - Choice3Of5 (anonInfo, tinst, i) - | BuiltInSln -> - Choice5Of5 () - | ClosedExprSln expr -> - Choice4Of5 expr - return! - match sln with - | Choice1Of5(minfo, methArgTys) -> - let argExprs = - // FIX for #421894 - typechecker assumes that coercion can be applied for the trait calls arguments but codegen doesn't emit coercion operations - // result - generation of non-verifiable code - // fix - apply coercion for the arguments (excluding 'receiver' argument in instance calls) - - // flatten list of argument types (looks like trait calls with curried arguments are not supported so we can just convert argument list in straightforward way) - let argTypes = - minfo.GetParamTypes(amap, m, methArgTys) - |> List.concat - // do not apply coercion to the 'receiver' argument - let receiverArgOpt, argExprs = - if minfo.IsInstance then - match argExprs with - | h :: t -> Some h, t - | argExprs -> None, argExprs - else None, argExprs - let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr) - match receiverArgOpt with - | Some r -> r :: convertedArgs - | None -> convertedArgs - - // Fix bug 1281: If we resolve to an instance method on a struct and we haven't yet taken - // the address of the object then go do that - if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then - let h, t = List.headAndTail argExprs - let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false PossiblyMutates h None m - ResultD (Some (wrap (Expr.Op (TOp.TraitCall (traitInfo), [], (h' :: t), m)))) - else - ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs )) - - | Choice2Of5 (tinst, rfref, isSet) -> - let res = - match isSet, rfref.RecdField.IsStatic, argExprs.Length with - | true, true, 1 -> - Some (mkStaticRecdFieldSet (rfref, tinst, argExprs.[0], m)) - | true, false, 2 -> - // If we resolve to an instance field on a struct and we haven't yet taken - // the address of the object then go do that - if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then - let h = List.head argExprs - let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m - Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m))) - else - Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m)) - | false, true, 0 -> - Some (mkStaticRecdFieldGet (rfref, tinst, m)) - | false, false, 1 -> - if rfref.Tycon.IsStructOrEnumTycon && isByrefTy g (tyOfExpr g argExprs.[0]) then - Some (mkRecdFieldGetViaExprAddr (argExprs.[0], rfref, tinst, m)) - else - Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m)) - | _ -> None - ResultD res - | Choice3Of5 (anonInfo, tinst, i) -> - let res = - let tupInfo = anonInfo.TupInfo - if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then - Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m)) - else - Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m)) - ResultD res - - | Choice4Of5 expr -> ResultD (Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m))) + let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo + return GenWitnessExpr amap g m traitInfo argExprs + } - | Choice5Of5 () -> ResultD None +/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses +let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + let ftps, _renaming, tinst = FreshenTypeInst m typars + let traitInfos = GetTraitConstraintInfosOfTypars g ftps + do! SolveTyparsEqualTypes csenv 0 m NoTrace tinst tyargs + return GenWitnessArgs amap g m traitInfos } +/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses +let CodegenWitnessArgForTraitConstraint tcVal g amap m traitInfo = trackErrors { + let css = CreateCodegenState tcVal g amap + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) + let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo + return GenWitnessExprLambda amap g m traitInfo + } +/// For some code like "let f() = ([] = [])", a free choice is made for a type parameter +/// for an interior type variable. This chooses a solution for a type parameter subject +/// to its constraints and applies that solution by using a constraint. let ChooseTyparSolutionAndSolve css denv tp = let g = css.g let amap = css.amap let max, m = ChooseTyparSolutionAndRange g amap tp let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv - TryD (fun () -> SolveTyparEqualsType csenv 0 m NoTrace (mkTyparTy tp) max) - (fun err -> ErrorD(ErrorFromApplyingDefault(g, denv, tp, max, err, m))) + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> SolveTyparEqualsType csenv 0 m NoTrace (mkTyparTy tp) max) + (fun err -> ErrorD(ErrorFromApplyingDefault(g, denv, tp, max, err, m))) |> RaiseOperationResult - let CheckDeclaredTypars denv css m typars1 typars2 = - TryD (fun () -> + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> CollectThenUndo (fun trace -> - SolveTypeEqualsTypeEqns (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) 0 m (WithTrace trace) None + SolveTypeEqualsTypeEqns csenv 0 m (WithTrace trace) None (List.map mkTyparTy typars1) (List.map mkTyparTy typars2))) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) + (fun res -> + ErrorD (ErrorFromAddingConstraint(denv, res, m))) + |> RaiseOperationResult + +let CanonicalizePartialInferenceProblem css denv m tps = + // Canonicalize constraints prior to generalization + let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv + TryD_IgnoreAbortForFailedOverloadResolution + (fun () -> CanonicalizeRelevantMemberConstraints csenv 0 NoTrace tps) + (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult /// An approximation used during name resolution for intellisense to eliminate extension members which will not @@ -2984,7 +3330,7 @@ let IsApplicableMethApprox g amap m (minfo: MethInfo) availObjTy = amap = amap TcVal = (fun _ -> failwith "should not be called") ExtraCxs = HashMultiMap(10, HashIdentity.Structural) - InfoReader = new InfoReader(g, amap) } + InfoReader = InfoReader(g, amap) } let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) let minst = FreshenMethInfo m minfo match minfo.GetObjArgTypes(amap, m, minst) with diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi index 1fce009f616..fb0d76a2b4e 100644 --- a/src/fsharp/ConstraintSolver.fsi +++ b/src/fsharp/ConstraintSolver.fsi @@ -3,147 +3,218 @@ /// Solves constraints using a mutable constraint-solver state module internal FSharp.Compiler.ConstraintSolver -open FSharp.Compiler open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Range open FSharp.Compiler.Import -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals open FSharp.Compiler.Infos -open FSharp.Compiler.MethodCalls open FSharp.Compiler.InfoReader +open FSharp.Compiler.MethodCalls +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps /// Create a type variable representing the use of a "_" in F# code -val NewAnonTypar : TyparKind * range * TyparRigidity * TyparStaticReq * TyparDynamicReq -> Typar +val NewAnonTypar: TyparKind * range * TyparRigidity * TyparStaticReq * TyparDynamicReq -> Typar /// Create an inference type variable -val NewInferenceType : unit -> TType +val NewInferenceType: unit -> TType /// Create an inference type variable for the kind of a byref pointer -val NewByRefKindInferenceType : TcGlobals -> range -> TType +val NewByRefKindInferenceType: TcGlobals -> range -> TType /// Create an inference type variable representing an error condition when checking an expression -val NewErrorType : unit -> TType +val NewErrorType: unit -> TType /// Create an inference type variable representing an error condition when checking a measure -val NewErrorMeasure : unit -> Measure +val NewErrorMeasure: unit -> Measure /// Create a list of inference type variables, one for each element in the input list -val NewInferenceTypes : 'a list -> TType list +val NewInferenceTypes: 'a list -> TType list /// Given a set of formal type parameters and their constraints, make new inference type variables for /// each and ensure that the constraints on the new type variables are adjusted to refer to these. -val FreshenAndFixupTypars : range -> TyparRigidity -> Typars -> TType list -> Typars -> Typars * TyparInst * TType list +val FreshenAndFixupTypars: range -> TyparRigidity -> Typars -> TType list -> Typars -> Typars * TyparInst * TType list -val FreshenTypeInst : range -> Typars -> Typars * TyparInst * TType list +val FreshenTypeInst: range -> Typars -> Typars * TyparInst * TType list -val FreshenTypars : range -> Typars -> TType list +val FreshenTypars: range -> Typars -> TType list -val FreshenMethInfo : range -> MethInfo -> TType list +val FreshenMethInfo: range -> MethInfo -> TType list [] /// Information about the context of a type equation. type ContextInfo = -/// No context was given. -| NoContext -/// The type equation comes from an IF expression. -| IfExpression of range -/// The type equation comes from an omitted else branch. -| OmittedElseBranch of range -/// The type equation comes from a type check of the result of an else branch. -| ElseBranchResult of range -/// The type equation comes from the verification of record fields. -| RecordFields -/// The type equation comes from the verification of a tuple in record fields. -| TupleInRecordFields -/// The type equation comes from a list or array constructor -| CollectionElement of bool * range -/// The type equation comes from a return in a computation expression. -| ReturnInComputationExpression -/// The type equation comes from a yield in a computation expression. -| YieldInComputationExpression -/// The type equation comes from a runtime type test. -| RuntimeTypeTest of bool -/// The type equation comes from an downcast where a upcast could be used. -| DowncastUsedInsteadOfUpcast of bool -/// The type equation comes from a return type of a pattern match clause (not the first clause). -| FollowingPatternMatchClause of range -/// The type equation comes from a pattern match guard. -| PatternMatchGuard of range -/// The type equation comes from a sequence expression. -| SequenceExpression of TType + + /// No context was given. + | NoContext + + /// The type equation comes from an IF expression. + | IfExpression of range + + /// The type equation comes from an omitted else branch. + | OmittedElseBranch of range + + /// The type equation comes from a type check of the result of an else branch. + | ElseBranchResult of range + + /// The type equation comes from the verification of record fields. + | RecordFields + + /// The type equation comes from the verification of a tuple in record fields. + | TupleInRecordFields + + /// The type equation comes from a list or array constructor + | CollectionElement of bool * range + + /// The type equation comes from a return in a computation expression. + | ReturnInComputationExpression + + /// The type equation comes from a yield in a computation expression. + | YieldInComputationExpression + + /// The type equation comes from a runtime type test. + | RuntimeTypeTest of bool + + /// The type equation comes from an downcast where a upcast could be used. + | DowncastUsedInsteadOfUpcast of bool + + /// The type equation comes from a return type of a pattern match clause (not the first clause). + | FollowingPatternMatchClause of range + + /// The type equation comes from a pattern match guard. + | PatternMatchGuard of range + + /// The type equation comes from a sequence expression. + | SequenceExpression of TType + +/// Captures relevant information for a particular failed overload resolution. +type OverloadInformation = + { + methodSlot: CalledMeth + infoReader: InfoReader + error: exn + } + +/// Cases for overload resolution failure that exists in the implementation of the compiler. +type OverloadResolutionFailure = + | NoOverloadsFound of methodName: string + * candidates: OverloadInformation list + * cx: TraitConstraintInfo option + | PossibleCandidates of methodName: string + * candidates: OverloadInformation list // methodNames may be different (with operators?), this is refactored from original logic to assemble overload failure message + * cx: TraitConstraintInfo option + +/// Represents known information prior to checking an expression or pattern, e.g. it's expected type +type OverallTy = + /// Each branch of the expression must have the type indicated + | MustEqual of TType + + /// Each branch of the expression must convert to the type indicated + | MustConvertTo of isMethodArg: bool * ty: TType + + /// Represents a point where no subsumption/widening is possible + member Commit: TType exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range exception ConstraintSolverTypesNotInEqualityRelation of displayEnv: DisplayEnv * TType * TType * range * range * ContextInfo -exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * TType * TType * range * range +exception ConstraintSolverTypesNotInSubsumptionRelation of displayEnv: DisplayEnv * argTy: TType * paramTy: TType * callRange: range * parameterRange: range exception ConstraintSolverMissingConstraint of displayEnv: DisplayEnv * Typar * TyparConstraint * range * range exception ConstraintSolverError of string * range * range exception ConstraintSolverRelatedInformation of string option * range * exn exception ErrorFromApplyingDefault of tcGlobals: TcGlobals * displayEnv: DisplayEnv * Typar * TType * exn * range -exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * range -exception ErrorsFromAddingSubsumptionConstraint of tcGlobals: TcGlobals * displayEnv: DisplayEnv * TType * TType * exn * ContextInfo * range +exception ErrorFromAddingTypeEquation of tcGlobals: TcGlobals * displayEnv: DisplayEnv * actualTy: TType * expectedTy: TType * exn * range +exception ErrorsFromAddingSubsumptionConstraint of tcGlobals: TcGlobals * displayEnv: DisplayEnv * actualTy: TType * expectedTy: TType * exn * ContextInfo * parameterRange: range exception ErrorFromAddingConstraint of displayEnv: DisplayEnv * exn * range exception UnresolvedConversionOperator of displayEnv: DisplayEnv * TType * TType * range -exception PossibleOverload of displayEnv: DisplayEnv * string * exn * range -exception UnresolvedOverloading of displayEnv: DisplayEnv * exn list * string * range +exception UnresolvedOverloading of displayEnv: DisplayEnv * callerArgs: CallerArgs * failure: OverloadResolutionFailure * range exception NonRigidTypar of displayEnv: DisplayEnv * string option * range * TType * TType * range +exception ArgDoesNotMatchError of error: ErrorsFromAddingSubsumptionConstraint * calledMeth: CalledMeth * calledArg: CalledArg * callerArg: CallerArg /// A function that denotes captured tcVal, Used in constraint solver and elsewhere to get appropriate expressions for a ValRef. -type TcValF = (ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) +type TcValF = ValRef -> ValUseFlag -> TType list -> range -> Expr * TType [] type ConstraintSolverState = - static member New: TcGlobals * Import.ImportMap * InfoReader * TcValF -> ConstraintSolverState - -type ConstraintSolverEnv + static member New: TcGlobals * ImportMap * InfoReader * TcValF -> ConstraintSolverState -val BakedInTraitConstraintNames : Set - -val MakeConstraintSolverEnv : ContextInfo -> ConstraintSolverState -> range -> DisplayEnv -> ConstraintSolverEnv +val BakedInTraitConstraintNames: Set [] type Trace type OptionalTrace = -| NoTrace -| WithTrace of Trace - -val SimplifyMeasuresInTypeScheme : TcGlobals -> bool -> Typars -> TType -> TyparConstraint list -> Typars -val SolveTyparEqualsType : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult -val SolveTypeEqualsTypeKeepAbbrevs : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult -val CanonicalizeRelevantMemberConstraints : ConstraintSolverEnv -> int -> OptionalTrace -> Typars -> OperationResult -val ResolveOverloading : ConstraintSolverEnv -> OptionalTrace -> string -> ndeep: int -> TraitConstraintInfo option -> int * int -> AccessorDomain -> CalledMeth list -> bool -> TType option -> CalledMeth option * OperationResult -val UnifyUniqueOverloading : ConstraintSolverEnv -> int * int -> string -> AccessorDomain -> CalledMeth list -> TType -> OperationResult -val EliminateConstraintsForGeneralizedTypars : ConstraintSolverEnv -> OptionalTrace -> Typars -> unit - -val CheckDeclaredTypars : DisplayEnv -> ConstraintSolverState -> range -> Typars -> Typars -> unit - -val AddConstraint : ConstraintSolverEnv -> int -> Range.range -> OptionalTrace -> Typar -> TyparConstraint -> OperationResult -val AddCxTypeEqualsType : ContextInfo -> DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> unit -val AddCxTypeEqualsTypeUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool -val AddCxTypeEqualsTypeUndoIfFailedOrWarnings : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool -val AddCxTypeEqualsTypeMatchingOnlyUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool -val AddCxTypeMustSubsumeType : ContextInfo -> DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> unit -val AddCxTypeMustSubsumeTypeUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool -val AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed : DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool -val AddCxMethodConstraint : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TraitConstraintInfo -> unit -val AddCxTypeMustSupportNull : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeMustSupportComparison : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeMustSupportEquality : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeMustSupportDefaultCtor : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeIsReferenceType : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeIsValueType : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeIsUnmanaged : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit -val AddCxTypeIsEnum : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> unit -val AddCxTypeIsDelegate : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> TType -> unit - -val CodegenWitnessThatTypeSupportsTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult + | NoTrace + | WithTrace of Trace + +val SimplifyMeasuresInTypeScheme: TcGlobals -> bool -> Typars -> TType -> TyparConstraint list -> Typars + +val ResolveOverloadingForCall: DisplayEnv -> ConstraintSolverState -> range -> methodName: string -> ndeep: int -> cx: TraitConstraintInfo option -> callerArgs: CallerArgs -> AccessorDomain -> calledMethGroup: CalledMeth list -> permitOptArgs: bool -> reqdRetTyOpt: OverallTy option -> CalledMeth option * OperationResult +val UnifyUniqueOverloading: DisplayEnv -> ConstraintSolverState -> range -> int * int -> string -> AccessorDomain -> CalledMeth list -> OverallTy -> OperationResult + +/// Remove the global constraints where these type variables appear in the support of the constraint +val EliminateConstraintsForGeneralizedTypars: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> Typars -> unit + +val CheckDeclaredTypars: DisplayEnv -> ConstraintSolverState -> range -> Typars -> Typars -> unit + +val AddCxTypeEqualsType: ContextInfo -> DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> unit + +val AddCxTypeEqualsTypeUndoIfFailed: DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool + +val AddCxTypeEqualsTypeUndoIfFailedOrWarnings: DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool + +val AddCxTypeEqualsTypeMatchingOnlyUndoIfFailed: DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool + +val AddCxTypeMustSubsumeType: ContextInfo -> DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> unit + +val AddCxTypeMustSubsumeTypeUndoIfFailed: DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool + +val AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed: DisplayEnv -> ConstraintSolverState -> range -> TType -> TType -> bool + +val AddCxMethodConstraint: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TraitConstraintInfo -> unit + +val AddCxTypeMustSupportNull: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeMustSupportComparison: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeMustSupportEquality: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeMustSupportDefaultCtor: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeIsReferenceType: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeIsValueType: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeIsUnmanaged: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> unit + +val AddCxTypeIsEnum: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> unit + +val AddCxTypeIsDelegate: DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> TType -> unit + +val AddCxTyparDefaultsTo: DisplayEnv -> ConstraintSolverState -> range -> ContextInfo -> Typar -> int -> TType -> unit + +val SolveTypeAsError: DisplayEnv -> ConstraintSolverState -> range -> TType -> unit + +val ApplyTyparDefaultAtPriority: DisplayEnv -> ConstraintSolverState -> priority: int -> Typar -> unit + +/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code +val CodegenWitnessExprForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult + +/// Generate the arguments passed when using a generic construct that accepts traits witnesses +val CodegenWitnessesForTyparInst : TcValF -> TcGlobals -> ImportMap -> range -> Typars -> TType list -> OperationResult list> + +/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses +val CodegenWitnessArgForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> OperationResult> + +/// For some code like "let f() = ([] = [])", a free choice is made for a type parameter +/// for an interior type variable. This chooses a solution for a type parameter subject +/// to its constraints and applies that solution by using a constraint. val ChooseTyparSolutionAndSolve : ConstraintSolverState -> DisplayEnv -> Typar -> unit -val IsApplicableMethApprox : TcGlobals -> ImportMap -> range -> MethInfo -> TType -> bool +val IsApplicableMethApprox: TcGlobals -> ImportMap -> range -> MethInfo -> TType -> bool + +val CanonicalizePartialInferenceProblem: ConstraintSolverState -> DisplayEnv -> range -> Typars -> unit diff --git a/src/fsharp/CreateILModule.fs b/src/fsharp/CreateILModule.fs new file mode 100644 index 00000000000..8807031c3a8 --- /dev/null +++ b/src/fsharp/CreateILModule.fs @@ -0,0 +1,495 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CreateILModule + +open System +open System.IO +open System.Reflection + +open Internal.Utilities +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.NativeRes +open FSharp.Compiler.AbstractIL.StrongNameSign +open FSharp.Compiler.BinaryResourceFormats +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IlxGen +open FSharp.Compiler.IO +open FSharp.Compiler.OptimizeInputs +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals + +/// Helpers for finding attributes +module AttributeHelpers = + + /// Try to find an attribute that takes a string argument + let TryFindStringAttribute (g: TcGlobals) attrib attribs = + match g.TryFindSysAttrib attrib with + | None -> None + | Some attribRef -> + match TryFindFSharpAttribute g attribRef attribs with + | Some (Attrib(_, _, [ AttribStringArg s ], _, _, _, _)) -> Some s + | _ -> None + + let TryFindIntAttribute (g: TcGlobals) attrib attribs = + match g.TryFindSysAttrib attrib with + | None -> None + | Some attribRef -> + match TryFindFSharpAttribute g attribRef attribs with + | Some (Attrib(_, _, [ AttribInt32Arg i ], _, _, _, _)) -> Some i + | _ -> None + + let TryFindBoolAttribute (g: TcGlobals) attrib attribs = + match g.TryFindSysAttrib attrib with + | None -> None + | Some attribRef -> + match TryFindFSharpAttribute g attribRef attribs with + | Some (Attrib(_, _, [ AttribBoolArg p ], _, _, _, _)) -> Some p + | _ -> None + + let (|ILVersion|_|) (versionString: string) = + try Some (parseILVersion versionString) + with e -> + None + +//---------------------------------------------------------------------------- +// ValidateKeySigningAttributes, GetStrongNameSigner +//---------------------------------------------------------------------------- + +/// Represents the configuration settings used to perform strong-name signing +type StrongNameSigningInfo = StrongNameSigningInfo of delaysign: bool * publicsign: bool * signer: string option * container: string option + +/// Validate the attributes and configuration settings used to perform strong-name signing +let ValidateKeySigningAttributes (tcConfig : TcConfig, tcGlobals, topAttrs) = + let delaySignAttrib = AttributeHelpers.TryFindBoolAttribute tcGlobals "System.Reflection.AssemblyDelaySignAttribute" topAttrs.assemblyAttrs + let signerAttrib = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyKeyFileAttribute" topAttrs.assemblyAttrs + let containerAttrib = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyKeyNameAttribute" topAttrs.assemblyAttrs + + // if delaySign is set via an attribute, validate that it wasn't set via an option + let delaysign = + match delaySignAttrib with + | Some delaysign -> + if tcConfig.delaysign then + warning(Error(FSComp.SR.fscDelaySignWarning(), rangeCmdArgs)) + tcConfig.delaysign + else + delaysign + | _ -> tcConfig.delaysign + + // if signer is set via an attribute, validate that it wasn't set via an option + let signer = + match signerAttrib with + | Some signer -> + if tcConfig.signer.IsSome && tcConfig.signer <> Some signer then + warning(Error(FSComp.SR.fscKeyFileWarning(), rangeCmdArgs)) + tcConfig.signer + else + Some signer + | None -> tcConfig.signer + + // if container is set via an attribute, validate that it wasn't set via an option, and that they keyfile wasn't set + // if keyfile was set, use that instead (silently) + // REVIEW: This is C# behavior, but it seems kind of sketchy that we fail silently + let container = + match containerAttrib with + | Some container -> + if not FSharpEnvironment.isRunningOnCoreClr then + warning(Error(FSComp.SR.containerDeprecated(), rangeCmdArgs)) + if tcConfig.container.IsSome && tcConfig.container <> Some container then + warning(Error(FSComp.SR.fscKeyNameWarning(), rangeCmdArgs)) + tcConfig.container + else + Some container + | None -> tcConfig.container + + StrongNameSigningInfo (delaysign, tcConfig.publicsign, signer, container) + +/// Get the object used to perform strong-name signing +let GetStrongNameSigner signingInfo = + let (StrongNameSigningInfo(delaysign, publicsign, signer, container)) = signingInfo + // REVIEW: favor the container over the key file - C# appears to do this + match container with + | Some container -> + Some (ILStrongNameSigner.OpenKeyContainer container) + | None -> + match signer with + | None -> None + | Some s -> + try + if publicsign || delaysign then + Some (ILStrongNameSigner.OpenPublicKeyOptions s publicsign) + else + Some (ILStrongNameSigner.OpenKeyPairFile s) + with _ -> + // Note :: don't use errorR here since we really want to fail and not produce a binary + error(Error(FSComp.SR.fscKeyFileCouldNotBeOpened s, rangeCmdArgs)) + +//---------------------------------------------------------------------------- +// Building the contents of the finalized IL module +//---------------------------------------------------------------------------- + +module MainModuleBuilder = + + let injectedCompatTypes = + set [ "System.Tuple`1" + "System.Tuple`2" + "System.Tuple`3" + "System.Tuple`4" + "System.Tuple`5" + "System.Tuple`6" + "System.Tuple`7" + "System.Tuple`8" + "System.ITuple" + "System.Tuple" + "System.Collections.IStructuralComparable" + "System.Collections.IStructuralEquatable" ] + + let typesForwardedToMscorlib = + set [ "System.AggregateException" + "System.Threading.CancellationTokenRegistration" + "System.Threading.CancellationToken" + "System.Threading.CancellationTokenSource" + "System.Lazy`1" + "System.IObservable`1" + "System.IObserver`1" ] + + let typesForwardedToSystemNumerics = + set [ "System.Numerics.BigInteger" ] + + let createMscorlibExportList (tcGlobals: TcGlobals) = + // We want to write forwarders out for all injected types except for System.ITuple, which is internal + // Forwarding System.ITuple will cause FxCop failures on 4.0 + Set.union (Set.filter (fun t -> t <> "System.ITuple") injectedCompatTypes) typesForwardedToMscorlib |> + Seq.map (fun t -> mkTypeForwarder tcGlobals.ilg.primaryAssemblyScopeRef t (mkILNestedExportedTypes List.empty) (mkILCustomAttrs List.empty) ILTypeDefAccess.Public ) + |> Seq.toList + + let createSystemNumericsExportList (tcConfig: TcConfig) (tcImports: TcImports) = + let refNumericsDllName = + if (tcConfig.primaryAssembly.Name = "mscorlib") then "System.Numerics" + else "System.Runtime.Numerics" + let numericsAssemblyRef = + match tcImports.GetImportedAssemblies() |> List.tryFind(fun a -> a.FSharpViewOfMetadata.AssemblyName = refNumericsDllName) with + | Some asm -> + match asm.ILScopeRef with + | ILScopeRef.Assembly aref -> Some aref + | _ -> None + | None -> None + match numericsAssemblyRef with + | Some aref -> + let systemNumericsAssemblyRef = ILAssemblyRef.Create(refNumericsDllName, aref.Hash, aref.PublicKey, aref.Retargetable, aref.Version, aref.Locale) + typesForwardedToSystemNumerics |> + Seq.map (fun t -> + { ScopeRef = ILScopeRef.Assembly systemNumericsAssemblyRef + Name = t + Attributes = enum(0x00200000) ||| TypeAttributes.Public + Nested = mkILNestedExportedTypes [] + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx }) |> + Seq.toList + | None -> [] + + let fileVersion findStringAttr (assemblyVersion: ILVersionInfo) = + let attrName = "System.Reflection.AssemblyFileVersionAttribute" + match findStringAttr attrName with + | None -> assemblyVersion + | Some (AttributeHelpers.ILVersion v) -> v + | Some _ -> + // Warning will be reported by CheckExpressions.fs + assemblyVersion + + let productVersion findStringAttr (fileVersion: ILVersionInfo) = + let attrName = "System.Reflection.AssemblyInformationalVersionAttribute" + let toDotted (version: ILVersionInfo) = sprintf "%d.%d.%d.%d" version.Major version.Minor version.Build version.Revision + match findStringAttr attrName with + | None | Some "" -> fileVersion |> toDotted + | Some (AttributeHelpers.ILVersion v) -> v |> toDotted + | Some v -> + // Warning will be reported by CheckExpressions.fs + v + + let productVersionToILVersionInfo (version: string) : ILVersionInfo = + let parseOrZero i (v:string) = + let v = + // When i = 3 then this is the 4th part of the version. The last part of the version can be trailed by any characters so we trim them off + if i <> 3 then + v + else + ((false, ""), v) + ||> Seq.fold(fun (finished, v) c -> + match finished with + | false when Char.IsDigit(c) -> false, v + c.ToString() + | _ -> true, v) + |> snd + match UInt16.TryParse v with + | true, i -> i + | false, _ -> 0us + let validParts = + version.Split('.') + |> Array.mapi(fun i v -> parseOrZero i v) + |> Seq.toList + match validParts @ [0us; 0us; 0us; 0us] with + | major :: minor :: build :: rev :: _ -> ILVersionInfo(major, minor, build, rev) + | x -> failwithf "error converting product version '%s' to binary, tried '%A' " version x + + + let CreateMainModule + (ctok, tcConfig: TcConfig, tcGlobals, tcImports: TcImports, + pdbfile, assemblyName, outfile, topAttrs, + sigDataAttributes: ILAttribute list, sigDataResources: ILResource list, optDataResources: ILResource list, + codegenResults, assemVerFromAttrib, metadataVersion, secDecls) = + + RequireCompilationThread ctok + let ilTypeDefs = + //let topTypeDef = mkILTypeDefForGlobalFunctions tcGlobals.ilg (mkILMethods [], emptyILFields) + mkILTypeDefs codegenResults.ilTypeDefs + + let mainModule = + let hashAlg = AttributeHelpers.TryFindIntAttribute tcGlobals "System.Reflection.AssemblyAlgorithmIdAttribute" topAttrs.assemblyAttrs + let locale = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyCultureAttribute" topAttrs.assemblyAttrs + let flags = match AttributeHelpers.TryFindIntAttribute tcGlobals "System.Reflection.AssemblyFlagsAttribute" topAttrs.assemblyAttrs with | Some f -> f | _ -> 0x0 + + // You're only allowed to set a locale if the assembly is a library + if (locale <> None && locale.Value <> "") && tcConfig.target <> CompilerTarget.Dll then + error(Error(FSComp.SR.fscAssemblyCultureAttributeError(), rangeCmdArgs)) + + // Add the type forwarders to any .NET DLL post-.NET-2.0, to give binary compatibility + let exportedTypesList = + if tcConfig.compilingFslib then + List.append (createMscorlibExportList tcGlobals) (createSystemNumericsExportList tcConfig tcImports) + else + [] + + let ilModuleName = GetGeneratedILModuleName tcConfig.target assemblyName + let isDLL = (tcConfig.target = CompilerTarget.Dll || tcConfig.target = CompilerTarget.Module) + mkILSimpleModule assemblyName ilModuleName isDLL tcConfig.subsystemVersion tcConfig.useHighEntropyVA ilTypeDefs hashAlg locale flags (mkILExportedTypes exportedTypesList) metadataVersion + + let disableJitOptimizations = not tcConfig.optSettings.JitOptimizationsEnabled + + let tcVersion = tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) + + let reflectedDefinitionAttrs, reflectedDefinitionResources = + codegenResults.quotationResourceInfo + |> List.map (fun (referencedTypeDefs, reflectedDefinitionBytes) -> + let reflectedDefinitionResourceName = QuotationPickler.SerializedReflectedDefinitionsResourceNameBase+"-"+assemblyName+"-"+string(newUnique())+"-"+string(hash reflectedDefinitionBytes) + let reflectedDefinitionAttrs = + let qf = QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat tcGlobals + if qf.SupportsDeserializeEx then + [ mkCompilationMappingAttrForQuotationResource tcGlobals (reflectedDefinitionResourceName, referencedTypeDefs) ] + else + [ ] + let reflectedDefinitionResource = + { Name=reflectedDefinitionResourceName + Location = ILResourceLocation.Local(ByteStorage.FromByteArray(reflectedDefinitionBytes)) + Access= ILResourceAccess.Public + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx } + reflectedDefinitionAttrs, reflectedDefinitionResource) + |> List.unzip + |> (fun (attrs, resource) -> List.concat attrs, resource) + + let manifestAttrs = + mkILCustomAttrs + [ if not tcConfig.internConstantStrings then + yield mkILCustomAttribute + (tcGlobals.FindSysILTypeRef "System.Runtime.CompilerServices.CompilationRelaxationsAttribute", + [tcGlobals.ilg.typ_Int32], [ILAttribElem.Int32( 8)], []) + yield! sigDataAttributes + yield! codegenResults.ilAssemAttrs + if Option.isSome pdbfile then + yield (tcGlobals.mkDebuggableAttributeV2 (tcConfig.jitTracking, tcConfig.ignoreSymbolStoreSequencePoints, disableJitOptimizations, false (* enableEnC *) )) + yield! reflectedDefinitionAttrs ] + + // Make the manifest of the assembly + let manifest = + if tcConfig.target = CompilerTarget.Module then None else + let man = mainModule.ManifestOfAssembly + let ver = + match assemVerFromAttrib with + | None -> tcVersion + | Some v -> v + Some { man with Version= Some ver + CustomAttrsStored = storeILCustomAttrs manifestAttrs + DisableJitOptimizations=disableJitOptimizations + JitTracking= tcConfig.jitTracking + IgnoreSymbolStoreSequencePoints = tcConfig.ignoreSymbolStoreSequencePoints + SecurityDeclsStored=storeILSecurityDecls secDecls } + + let resources = + mkILResources + [ for file in tcConfig.embedResources do + let name, bytes, pub = + let file, name, pub = TcConfigBuilder.SplitCommandLineResourceInfo file + let file = tcConfig.ResolveSourceFile(rangeStartup, file, tcConfig.implicitIncludeDir) + let bytes = FileSystem.OpenFileForReadShim(file).ReadAllBytes() + name, bytes, pub + yield { Name=name + // TODO: We probably can directly convert ByteMemory to ByteStorage, without reading all bytes. + Location=ILResourceLocation.Local(ByteStorage.FromByteArray(bytes)) + Access=pub + CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx } + + yield! reflectedDefinitionResources + yield! sigDataResources + yield! optDataResources + for ri in tcConfig.linkResources do + let file, name, pub = TcConfigBuilder.SplitCommandLineResourceInfo ri + yield { Name=name + Location=ILResourceLocation.File(ILModuleRef.Create(name=file, hasMetadata=false, hash=Some (sha1HashBytes (FileSystem.OpenFileForReadShim(file).ReadAllBytes()))), 0) + Access=pub + CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs + MetadataIndex = NoMetadataIdx } ] + + let assemblyVersion = + match tcConfig.version with + | VersionNone -> assemVerFromAttrib + | _ -> Some tcVersion + + let findAttribute name = + AttributeHelpers.TryFindStringAttribute tcGlobals name topAttrs.assemblyAttrs + + //NOTE: the culture string can be turned into a number using this: + // sprintf "%04x" (CultureInfo.GetCultureInfo("en").KeyboardLayoutId ) + let assemblyVersionResources assemblyVersion = + match assemblyVersion with + | None -> [] + | Some assemblyVersion -> + let FindAttribute key attrib = + match findAttribute attrib with + | Some text -> [(key, text)] + | _ -> [] + + let fileVersionInfo = fileVersion findAttribute assemblyVersion + + let productVersionString = productVersion findAttribute fileVersionInfo + + let stringFileInfo = + // 000004b0: + // Specifies an 8-digit hexadecimal number stored as a Unicode string. The + // four most significant digits represent the language identifier. The four least + // significant digits represent the code page for which the data is formatted. + // Each Microsoft Standard Language identifier contains two parts: the low-order 10 bits + // specify the major language, and the high-order 6 bits specify the sublanguage. + // For a table of valid identifiers see Language Identifiers. // + // see e.g. http://msdn.microsoft.com/en-us/library/aa912040.aspx 0000 is neutral and 04b0(hex)=1252(dec) is the code page. + [ ("000004b0", [ yield ("Assembly Version", (sprintf "%d.%d.%d.%d" assemblyVersion.Major assemblyVersion.Minor assemblyVersion.Build assemblyVersion.Revision)) + yield ("FileVersion", (sprintf "%d.%d.%d.%d" fileVersionInfo.Major fileVersionInfo.Minor fileVersionInfo.Build fileVersionInfo.Revision)) + yield ("ProductVersion", productVersionString) + match tcConfig.outputFile with + | Some f -> yield ("OriginalFilename", Path.GetFileName f) + | None -> () + yield! FindAttribute "Comments" "System.Reflection.AssemblyDescriptionAttribute" + yield! FindAttribute "FileDescription" "System.Reflection.AssemblyTitleAttribute" + yield! FindAttribute "ProductName" "System.Reflection.AssemblyProductAttribute" + yield! FindAttribute "CompanyName" "System.Reflection.AssemblyCompanyAttribute" + yield! FindAttribute "LegalCopyright" "System.Reflection.AssemblyCopyrightAttribute" + yield! FindAttribute "LegalTrademarks" "System.Reflection.AssemblyTrademarkAttribute" ]) ] + + // These entries listed in the MSDN documentation as "standard" string entries are not yet settable + + // InternalName: + // The Value member identifies the file's internal name, if one exists. For example, this + // string could contain the module name for Windows dynamic-link libraries (DLLs), a virtual + // device name for Windows virtual devices, or a device name for MS-DOS device drivers. + // OriginalFilename: + // The Value member identifies the original name of the file, not including a path. This + // enables an application to determine whether a file has been renamed by a user. This name + // may not be MS-DOS 8.3-format if the file is specific to a non-FAT file system. + // PrivateBuild: + // The Value member describes by whom, where, and why this private version of the + // file was built. This string should only be present if the VS_FF_PRIVATEBUILD flag + // is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, + // Value could be 'Built by OSCAR on \OSCAR2'. + // SpecialBuild: + // The Value member describes how this version of the file differs from the normal version. + // This entry should only be present if the VS_FF_SPECIALBUILD flag is set in the dwFileFlags + // member of the VS_FIXEDFILEINFO structure. For example, Value could be 'Private build + // for Olivetti solving mouse problems on M250 and M250E computers'. + + // "If you use the Var structure to list the languages your application + // or DLL supports instead of using multiple version resources, + // use the Value member to contain an array of DWORD values indicating the + // language and code page combinations supported by this file. The + // low-order word of each DWORD must contain a Microsoft language identifier, + // and the high-order word must contain the IBM code page number. + // Either high-order or low-order word can be zero, indicating that + // the file is language or code page independent. If the Var structure is + // omitted, the file will be interpreted as both language and code page independent. " + let varFileInfo = [ (0x0, 0x04b0) ] + + let fixedFileInfo = + let dwFileFlagsMask = 0x3f // REVIEW: HARDWIRED + let dwFileFlags = 0x00 // REVIEW: HARDWIRED + let dwFileOS = 0x04 // REVIEW: HARDWIRED + let dwFileType = 0x01 // REVIEW: HARDWIRED + let dwFileSubtype = 0x00 // REVIEW: HARDWIRED + let lwFileDate = 0x00L // REVIEW: HARDWIRED + (fileVersionInfo, productVersionString |> productVersionToILVersionInfo, dwFileFlagsMask, dwFileFlags, dwFileOS, dwFileType, dwFileSubtype, lwFileDate) + + let vsVersionInfoResource = + VersionResourceFormat.VS_VERSION_INFO_RESOURCE(fixedFileInfo, stringFileInfo, varFileInfo) + + let resource = + [| yield! ResFileFormat.ResFileHeader() + yield! vsVersionInfoResource |] + + [ resource ] + + // a user cannot specify both win32res and win32manifest + if not(tcConfig.win32manifest = "") && not(tcConfig.win32res = "") then + error(Error(FSComp.SR.fscTwoResourceManifests(), rangeCmdArgs)) + + let win32Manifest = + // use custom manifest if provided + if not(tcConfig.win32manifest = "") then tcConfig.win32manifest + + // don't embed a manifest if target is not an exe, if manifest is specifically excluded, if another native resource is being included, or if running on mono + elif not(tcConfig.target.IsExe) || not(tcConfig.includewin32manifest) || not(tcConfig.win32res = "") || runningOnMono then "" + // otherwise, include the default manifest + else + let path = Path.Combine(AppContext.BaseDirectory, @"default.win32manifest") + if FileSystem.FileExistsShim(path) then path + else Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), @"default.win32manifest") + + let nativeResources = + [ for av in assemblyVersionResources assemblyVersion do + yield ILNativeResource.Out av + if not(tcConfig.win32res = "") then + yield ILNativeResource.Out (FileSystem.OpenFileForReadShim(tcConfig.win32res).ReadAllBytes()) + if tcConfig.includewin32manifest && not(win32Manifest = "") && not runningOnMono then + yield ILNativeResource.Out [| yield! ResFileFormat.ResFileHeader() + yield! (ManifestResourceFormat.VS_MANIFEST_RESOURCE((FileSystem.OpenFileForReadShim(win32Manifest).ReadAllBytes()), tcConfig.target = CompilerTarget.Dll)) |] + if tcConfig.win32res = "" && tcConfig.win32icon <> "" && tcConfig.target <> CompilerTarget.Dll then + use ms = new MemoryStream() + use iconStream = FileSystem.OpenFileForReadShim(tcConfig.win32icon) + Win32ResourceConversions.AppendIconToResourceStream(ms, iconStream) + yield ILNativeResource.Out [| yield! ResFileFormat.ResFileHeader() + yield! ms.ToArray() |] ] + + // Add attributes, version number, resources etc. + {mainModule with + StackReserveSize = tcConfig.stackReserveSize + Name = (if tcConfig.target = CompilerTarget.Module then FileSystemUtils.fileNameOfPath outfile else mainModule.Name) + SubSystemFlags = (if tcConfig.target = CompilerTarget.WinExe then 2 else 3) + Resources= resources + ImageBase = (match tcConfig.baseAddress with None -> 0x00400000l | Some b -> b) + IsDLL=(tcConfig.target = CompilerTarget.Dll || tcConfig.target=CompilerTarget.Module) + Platform = tcConfig.platform + Is32Bit=(match tcConfig.platform with Some X86 -> true | _ -> false) + Is64Bit=(match tcConfig.platform with Some AMD64 | Some IA64 -> true | _ -> false) + Is32BitPreferred = if tcConfig.prefer32Bit && not tcConfig.target.IsExe then (error(Error(FSComp.SR.invalidPlatformTarget(), rangeCmdArgs))) else tcConfig.prefer32Bit + CustomAttrsStored= + storeILCustomAttrs + (mkILCustomAttrs + [ if tcConfig.target = CompilerTarget.Module then + yield! sigDataAttributes + yield! codegenResults.ilNetModuleAttrs ]) + NativeResources=nativeResources + Manifest = manifest } diff --git a/src/fsharp/CreateILModule.fsi b/src/fsharp/CreateILModule.fsi new file mode 100644 index 00000000000..686f587c635 --- /dev/null +++ b/src/fsharp/CreateILModule.fsi @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.CreateILModule + +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.StrongNameSign +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.IlxGen +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree + +/// Represents the configuration settings used to perform strong-name signing +type StrongNameSigningInfo + +/// Validate the attributes and configuration settings used to perform strong-name signing +val ValidateKeySigningAttributes: tcConfig:TcConfig * tcGlobals:TcGlobals * TopAttribs -> StrongNameSigningInfo + +/// Get the object used to perform strong-name signing +val GetStrongNameSigner: signingInfo: StrongNameSigningInfo -> ILStrongNameSigner option + +/// Helpers for finding attributes +module AttributeHelpers = + val TryFindStringAttribute: g: TcGlobals -> attrib: string -> attribs: Attribs -> string option + +module MainModuleBuilder = + + /// Put together all the pieces of information to create the overall IL ModuleDef for + /// the generated assembly + val CreateMainModule: + ctok: CompilationThreadToken * + tcConfig: TcConfig * + tcGlobals: TcGlobals * + tcImports: TcImports * + pdbfile: 't option * + assemblyName: string * + outfile: string * + topAttrs: TopAttribs * + sigDataAttributes: ILAttribute list * + sigDataResources: ILResource list * + optDataResources: ILResource list * + codegenResults: IlxGenResults * + assemVerFromAttrib: ILVersionInfo option * + metadataVersion: string * + secDecls: ILSecurityDecls + -> ILModuleDef + + /// For unit testing + val fileVersion: findStringAttr: (string -> string option) -> assemblyVersion: ILVersionInfo -> ILVersionInfo + + /// For unit testing + val productVersion: findStringAttr: (string -> string option) -> fileVersion: ILVersionInfo -> string + + /// For unit testing + val productVersionToILVersionInfo: string -> ILVersionInfo diff --git a/src/fsharp/DependencyManager.Integration.fs b/src/fsharp/DependencyManager.Integration.fs deleted file mode 100644 index 9f1ecd35f39..00000000000 --- a/src/fsharp/DependencyManager.Integration.fs +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -/// Helper members to integrate DependencyManagers into F# codebase -module internal FSharp.Compiler.DependencyManagerIntegration - -open System -open System.IO -open System.Reflection -open FSharp.Compiler.DotNetFrameworkDependencies -open FSharp.Compiler.ErrorLogger -open Internal.Utilities.FSharpEnvironment - -// Contract strings -let dependencyManagerPattern = "*DependencyManager*.dll" -let dependencyManagerAttributeName= "DependencyManagerAttribute" -let resolveDependenciesMethodName = "ResolveDependencies" -let namePropertyName = "Name" -let keyPropertyName = "Key" - -module ReflectionHelper = - let assemblyHasAttribute (theAssembly: Assembly) attributeName = - try - CustomAttributeExtensions.GetCustomAttributes(theAssembly) - |> Seq.exists (fun a -> a.GetType().Name = attributeName) - with | _ -> false - - let getAttributeNamed (theType: Type) attributeName = - try - theType.GetTypeInfo().GetCustomAttributes false - |> Seq.tryFind (fun a -> a.GetType().Name = attributeName) - with | _ -> None - - let getInstanceProperty<'treturn> (theType: Type) propertyName = - try - let property = theType.GetProperty(propertyName, typeof<'treturn>) - if isNull property then - None - elif not (property.GetGetMethod().IsStatic) - && property.GetIndexParameters() = Array.empty - then - Some property - else - None - with | _ -> None - - let getInstanceMethod<'treturn> (theType: Type) (parameterTypes: Type array) methodName = - try - let theMethod = theType.GetMethod(methodName, parameterTypes) - if isNull theMethod then - None - else - Some theMethod - with | _ -> None - - let stripTieWrapper (e:Exception) = - match e with - | :? TargetInvocationException as e-> - e.InnerException - | _ -> e - -(* Shape of Dependency Manager contract, resolved using reflection *) -type internal IDependencyManagerProvider = - abstract Name: string - abstract Key: string - abstract ResolveDependencies: scriptDir: string * mainScriptName: string * scriptName: string * packageManagerTextLines: string seq * tfm: string -> bool * string list * string list - abstract DependencyAdding: IEvent - abstract DependencyAdded: IEvent - abstract DependencyFailed: IEvent - -[] -type ReferenceType = -| RegisteredDependencyManager of IDependencyManagerProvider -| Library of string -| UnknownType - -type ReflectionDependencyManagerProvider(theType: Type, nameProperty: PropertyInfo, keyProperty: PropertyInfo, resolveDeps: MethodInfo, outputDir: string option) = - let instance = Activator.CreateInstance(theType, [|outputDir :> obj|]) - let nameProperty = nameProperty.GetValue >> string - let keyProperty = keyProperty.GetValue >> string - - let dependencyAddingEvent = Event<_>() - let dependencyAddedEvent = Event<_>() - let dependencyFailedEvent = Event<_>() - - static member InstanceMaker (theType: System.Type, outputDir: string option) = - match ReflectionHelper.getAttributeNamed theType dependencyManagerAttributeName, - ReflectionHelper.getInstanceProperty theType namePropertyName, - ReflectionHelper.getInstanceProperty theType keyPropertyName, - ReflectionHelper.getInstanceMethod theType [| typeof; typeof; typeof; typeof; typeof |] resolveDependenciesMethodName - with - | None, _, _, _ -> None - | _, None, _, _ -> None - | _, _, None, _ -> None - | _, _, _, None -> None - | Some _, Some nameProperty, Some keyProperty, Some resolveDependenciesMethod -> - Some (fun () -> new ReflectionDependencyManagerProvider(theType, nameProperty, keyProperty, resolveDependenciesMethod, outputDir) :> IDependencyManagerProvider) - - interface IDependencyManagerProvider with - member __.Name = instance |> nameProperty - member __.Key = instance |> keyProperty - member this.ResolveDependencies(scriptDir, mainScriptName, scriptName, packageManagerTextLines, tfm) = - let key = (this :> IDependencyManagerProvider).Key - let triggerEvent (evt: Event) = - for prLine in packageManagerTextLines do - evt.Trigger(key, prLine) - triggerEvent dependencyAddingEvent - let arguments = [| box scriptDir; box mainScriptName; box scriptName; box packageManagerTextLines; box tfm |] - let succeeded, generatedScripts, additionalIncludeFolders = resolveDeps.Invoke(instance, arguments) :?> _ - if succeeded then triggerEvent dependencyAddedEvent - else triggerEvent dependencyFailedEvent - succeeded, generatedScripts, additionalIncludeFolders - member __.DependencyAdding = dependencyAddingEvent.Publish - member __.DependencyAdded = dependencyAddedEvent.Publish - member __.DependencyFailed = dependencyFailedEvent.Publish - -// Resolution Path = Location of FSharp.Compiler.Private.dll -let assemblySearchPaths = lazy ( - [ - let assemblyLocation = typeof.GetTypeInfo().Assembly.Location - yield Path.GetDirectoryName assemblyLocation - yield AppDomain.CurrentDomain.BaseDirectory - ]) - -let enumerateDependencyManagerAssemblies compilerTools m = - getCompilerToolsDesignTimeAssemblyPaths compilerTools - |> Seq.append (assemblySearchPaths.Force()) - |> Seq.collect (fun path -> - try - if Directory.Exists(path) then Directory.EnumerateFiles(path, dependencyManagerPattern) - else Seq.empty - with _ -> Seq.empty) - |> Seq.choose (fun path -> - try - Some(AbstractIL.Internal.Library.Shim.FileSystem.AssemblyLoadFrom path) - with - | e -> - let e = ReflectionHelper.stripTieWrapper e - warning(Error(FSComp.SR.couldNotLoadDependencyManagerExtension(path,e.Message),m)) - None) - |> Seq.filter (fun a -> ReflectionHelper.assemblyHasAttribute a dependencyManagerAttributeName) - -let registeredDependencyManagers = ref None - -let RegisteredDependencyManagers (compilerTools: string list) (outputDir: string option) m = - match !registeredDependencyManagers with - | Some managers -> managers - | None -> - let defaultProviders =[] - - let loadedProviders = - enumerateDependencyManagerAssemblies compilerTools m - |> Seq.collect (fun a -> a.GetTypes()) - |> Seq.choose (fun t -> ReflectionDependencyManagerProvider.InstanceMaker(t, outputDir)) - |> Seq.map (fun maker -> maker ()) - - defaultProviders - |> Seq.append loadedProviders - |> Seq.map (fun pm -> pm.Key, pm) - |> Map.ofSeq - -let createPackageManagerUnknownError (compilerTools: string list) (outputDir:string option) packageManagerKey m = - let registeredKeys = String.Join(", ", RegisteredDependencyManagers compilerTools outputDir m |> Seq.map (fun kv -> kv.Value.Key)) - let searchPaths = assemblySearchPaths.Force() - Error(FSComp.SR.packageManagerUnknown(packageManagerKey, String.Join(", ", searchPaths, compilerTools), registeredKeys),m) - -let tryFindDependencyManagerInPath (compilerTools:string list) (outputDir:string option) m (path:string) : ReferenceType = - try - if path.Contains ":" && not (System.IO.Path.IsPathRooted path) then - let managers = RegisteredDependencyManagers compilerTools outputDir m - match managers |> Seq.tryFind (fun kv -> path.StartsWith(kv.Value.Key + ":" )) with - | None -> - errorR(createPackageManagerUnknownError compilerTools outputDir (path.Split(':').[0]) m) - ReferenceType.UnknownType - | Some kv -> ReferenceType.RegisteredDependencyManager kv.Value - else - ReferenceType.Library path - with - | e -> - let e = ReflectionHelper.stripTieWrapper e - errorR(Error(FSComp.SR.packageManagerError(e.Message),m)) - ReferenceType.UnknownType - -let removeDependencyManagerKey (packageManagerKey:string) (path:string) = path.Substring(packageManagerKey.Length + 1).Trim() - -let tryFindDependencyManagerByKey (compilerTools: string list) (outputDir:string option) m (key:string) : IDependencyManagerProvider option = - try - RegisteredDependencyManagers compilerTools outputDir m |> Map.tryFind key - with - | e -> - let e = ReflectionHelper.stripTieWrapper e - errorR(Error(FSComp.SR.packageManagerError(e.Message), m)) - None - -let resolve (packageManager:IDependencyManagerProvider) implicitIncludeDir mainScriptName fileName m packageManagerTextLines = - try - Some(packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, packageManagerTextLines, executionTfm)) - with e -> - let e = ReflectionHelper.stripTieWrapper e - errorR(Error(FSComp.SR.packageManagerError(e.Message), m)) - None diff --git a/src/fsharp/DependencyManager.Integration.fsi b/src/fsharp/DependencyManager.Integration.fsi deleted file mode 100644 index 62af44898d0..00000000000 --- a/src/fsharp/DependencyManager.Integration.fsi +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -/// Helper members to integrate DependencyManagers into F# codebase -module internal FSharp.Compiler.DependencyManagerIntegration - -open FSharp.Compiler.Range - -type IDependencyManagerProvider = - abstract Name: string - abstract Key: string - abstract ResolveDependencies: scriptDir: string * mainScriptName: string * scriptName: string * packageManagerTextLines: string seq * tfm: string -> bool * string list * string list - abstract DependencyAdding: IEvent - abstract DependencyAdded: IEvent - abstract DependencyFailed: IEvent - -[] -type ReferenceType = -| RegisteredDependencyManager of IDependencyManagerProvider -| Library of string -| UnknownType - -val tryFindDependencyManagerInPath: string list -> string option -> range -> string -> ReferenceType -val tryFindDependencyManagerByKey: string list -> string option -> range -> string -> IDependencyManagerProvider option -val removeDependencyManagerKey: string -> string -> string -val createPackageManagerUnknownError: string list -> string option -> string -> range -> exn -val resolve: IDependencyManagerProvider -> string -> string -> string -> range -> string seq -> (bool * string list * string list) option diff --git a/src/fsharp/DependencyManager/AssemblyResolveHandler.fs b/src/fsharp/DependencyManager/AssemblyResolveHandler.fs new file mode 100644 index 00000000000..bd12e6a955d --- /dev/null +++ b/src/fsharp/DependencyManager/AssemblyResolveHandler.fs @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Compiler.DependencyManager + +open System +open System.IO +open System.Reflection +open Internal.Utilities.FSharpEnvironment + +/// Signature for ResolutionProbe callback +/// host implements this, it's job is to return a list of assembly paths to probe. +type AssemblyResolutionProbe = delegate of Unit -> seq + +/// Type that encapsulates AssemblyResolveHandler for managed packages +type AssemblyResolveHandlerCoreclr (assemblyProbingPaths: AssemblyResolutionProbe) as this = + let assemblyLoadContextType: Type = Type.GetType("System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader", false) + + let loadFromAssemblyPathMethod = + assemblyLoadContextType.GetMethod("LoadFromAssemblyPath", [| typeof |]) + + let eventInfo, handler, defaultAssemblyLoadContext = + let eventInfo = assemblyLoadContextType.GetEvent("Resolving") + let mi = + let gmi = this.GetType().GetMethod("ResolveAssemblyNetStandard", BindingFlags.Instance ||| BindingFlags.NonPublic) + gmi.MakeGenericMethod(assemblyLoadContextType) + + eventInfo, + Delegate.CreateDelegate(eventInfo.EventHandlerType, this, mi), + assemblyLoadContextType.GetProperty("Default", BindingFlags.Static ||| BindingFlags.Public).GetValue(null, null) + + do eventInfo.AddEventHandler(defaultAssemblyLoadContext, handler) + + member _.ResolveAssemblyNetStandard (ctxt: 'T) (assemblyName: AssemblyName): Assembly = + let loadAssembly path = + loadFromAssemblyPathMethod.Invoke(ctxt, [| path |]) :?> Assembly + + let assemblyPaths = + match assemblyProbingPaths with + | null -> Seq.empty + | _ -> assemblyProbingPaths.Invoke() + + try + // args.Name is a displayname formatted assembly version. + // E.g: "System.IO.FileSystem, Version=4.1.1.0, Culture=en-US, PublicKeyToken=b03f5f7f11d50a3a" + let simpleName = assemblyName.Name + let assemblyPathOpt = assemblyPaths |> Seq.tryFind(fun path -> Path.GetFileNameWithoutExtension(path) = simpleName) + match assemblyPathOpt with + | Some path -> loadAssembly path + | None -> Unchecked.defaultof + + with | _ -> Unchecked.defaultof + + interface IDisposable with + member _x.Dispose() = + eventInfo.RemoveEventHandler(defaultAssemblyLoadContext, handler) + +/// Type that encapsulates AssemblyResolveHandler for managed packages +type AssemblyResolveHandlerDeskTop (assemblyProbingPaths: AssemblyResolutionProbe) = + + let resolveAssemblyNET (assemblyName: AssemblyName): Assembly = + + let loadAssembly assemblyPath = + Assembly.LoadFrom(assemblyPath) + + let assemblyPaths = + match assemblyProbingPaths with + | null -> Seq.empty + | _ -> assemblyProbingPaths.Invoke() + + try + // args.Name is a displayname formatted assembly version. + // E.g: "System.IO.FileSystem, Version=4.1.1.0, Culture=en-US, PublicKeyToken=b03f5f7f11d50a3a" + let simpleName = assemblyName.Name + let assemblyPathOpt = assemblyPaths |> Seq.tryFind(fun path -> Path.GetFileNameWithoutExtension(path) = simpleName) + match assemblyPathOpt with + | Some path -> loadAssembly path + | None -> Unchecked.defaultof + + with | _ -> Unchecked.defaultof + + let handler = ResolveEventHandler(fun _ (args: ResolveEventArgs) -> resolveAssemblyNET (AssemblyName(args.Name))) + do AppDomain.CurrentDomain.add_AssemblyResolve(handler) + + interface IDisposable with + member _x.Dispose() = + AppDomain.CurrentDomain.remove_AssemblyResolve(handler) + +type AssemblyResolveHandler (assemblyProbingPaths: AssemblyResolutionProbe) = + + let handler = + if isRunningOnCoreClr then + new AssemblyResolveHandlerCoreclr(assemblyProbingPaths) :> IDisposable + else + new AssemblyResolveHandlerDeskTop(assemblyProbingPaths) :> IDisposable + + interface IDisposable with + member _.Dispose() = handler.Dispose() diff --git a/src/fsharp/DependencyManager/AssemblyResolveHandler.fsi b/src/fsharp/DependencyManager/AssemblyResolveHandler.fsi new file mode 100644 index 00000000000..9718eb9f2d4 --- /dev/null +++ b/src/fsharp/DependencyManager/AssemblyResolveHandler.fsi @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Compiler.DependencyManager + +open System + +/// Signature for ResolutionProbe callback +/// host implements this, it's job is to return a list of assembly paths to probe. +type AssemblyResolutionProbe = delegate of Unit -> seq + +/// Handle Assembly resolution +type AssemblyResolveHandler = + + /// Construct a new DependencyProvider + new: assemblyProbingPaths: AssemblyResolutionProbe -> AssemblyResolveHandler + + interface IDisposable diff --git a/src/fsharp/DependencyManager/DependencyProvider.fs b/src/fsharp/DependencyManager/DependencyProvider.fs new file mode 100644 index 00000000000..95d2a7d280d --- /dev/null +++ b/src/fsharp/DependencyManager/DependencyProvider.fs @@ -0,0 +1,454 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Compiler.DependencyManager + +open System +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open Internal.Utilities +open Internal.Utilities.FSharpEnvironment +open FSharp.Reflection +open System.Collections.Concurrent + +module Option = + + /// Convert string into Option string where null and String.Empty result in None + let ofString s = + if String.IsNullOrEmpty(s) then None + else Some(s) + +[] +module ReflectionHelper = + let dependencyManagerPattern = "*DependencyManager*.dll" + + let dependencyManagerAttributeName= "DependencyManagerAttribute" + + let resolveDependenciesMethodName = "ResolveDependencies" + + let namePropertyName = "Name" + + let keyPropertyName = "Key" + + let helpMessagesPropertyName = "HelpMessages" + + let arrEmpty = Array.empty + + let seqEmpty = Seq.empty + + let assemblyHasAttribute (theAssembly: Assembly) attributeName = + try + CustomAttributeExtensions.GetCustomAttributes(theAssembly) + |> Seq.exists (fun a -> a.GetType().Name = attributeName) + with | _ -> false + + let getAttributeNamed (theType: Type) attributeName = + try + theType.GetTypeInfo().GetCustomAttributes false + |> Seq.tryFind (fun a -> a.GetType().Name = attributeName) + with | _ -> None + + let getInstanceProperty<'treturn> (theType: Type) propertyName = + try + let property = theType.GetProperty(propertyName, BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, Unchecked.defaultof, typeof<'treturn>, Array.empty, Array.empty) + if isNull property then + None + else + let getMethod = property.GetGetMethod() + if not (isNull getMethod) && not getMethod.IsStatic then + Some property + else + None + with | _ -> None + + let getInstanceMethod<'treturn> (theType: Type) (parameterTypes: Type array) methodName = + try + let theMethod = theType.GetMethod(methodName, parameterTypes) + if isNull theMethod then + None + else + Some theMethod + with | _ -> None + + let stripTieWrapper (e:Exception) = + match e with + | :? TargetInvocationException as e-> + e.InnerException + | _ -> e + +/// Indicate the type of error to report +[] +type ErrorReportType = + | Warning + | Error + +type ResolvingErrorReport = delegate of ErrorReportType * int * string -> unit + +(* Shape of Dependency Manager contract, resolved using reflection *) +/// The results of ResolveDependencies +type IResolveDependenciesResult = + + /// Succeded? + abstract Success: bool + + /// The resolution output log + abstract StdOut: string[] + + /// The resolution error log (* process stderror *) + abstract StdError: string[] + + /// The resolution paths - the full paths to selcted resolved dll's. + /// In scripts this is equivalent to #r @"c:\somepath\to\packages\ResolvedPackage\1.1.1\lib\netstandard2.0\ResolvedAssembly.dll" + abstract Resolutions: seq + + /// The source code file paths + abstract SourceFiles: seq + + /// The roots to package directories + /// This points to the root of each located package. + /// The layout of the package manager will be package manager specific. + /// however, the dependency manager dll understands the nuget package layout + /// and so if the package contains folders similar to the nuget layout then + /// the dependency manager will be able to probe and resolve any native dependencies + /// required by the nuget package. + /// + /// This path is also equivalent to + /// #I @"c:\somepath\to\packages\1.1.1\ResolvedPackage" + abstract Roots: seq + + +[] +type IDependencyManagerProvider = + abstract Name: string + abstract Key: string + abstract HelpMessages: string[] + abstract ResolveDependencies: scriptDir: string * mainScriptName: string * scriptName: string * scriptExt: string * packageManagerTextLines: (string * string) seq * tfm: string * rid: string * timeout: int-> IResolveDependenciesResult + +type ReflectionDependencyManagerProvider(theType: Type, + nameProperty: PropertyInfo, + keyProperty: PropertyInfo, + helpMessagesProperty: PropertyInfo option, + resolveDeps: MethodInfo option, + resolveDepsEx: MethodInfo option, + resolveDepsExWithTimeout: MethodInfo option, + resolveDepsExWithScriptInfoAndTimeout: MethodInfo option, + outputDir: string option) = + let instance = Activator.CreateInstance(theType, [| outputDir :> obj |]) + let nameProperty = nameProperty.GetValue >> string + let keyProperty = keyProperty.GetValue >> string + let helpMessagesProperty = + let toStringArray(o:obj) = o :?> string[] + match helpMessagesProperty with + | Some helpMessagesProperty -> helpMessagesProperty.GetValue >> toStringArray + | None -> fun _ -> Array.empty + + static member InstanceMaker (theType: Type, outputDir: string option) = + match getAttributeNamed theType dependencyManagerAttributeName, + getInstanceProperty theType namePropertyName, + getInstanceProperty theType keyPropertyName, + getInstanceProperty theType helpMessagesPropertyName + with + | None, _, _, _ + | _, None, _, _ + | _, _, None, _ -> None + | Some _, Some nameProperty, Some keyProperty, None -> + let resolveMethod = getInstanceMethod theType [| typeof; typeof; typeof; typeof; typeof |] resolveDependenciesMethodName + let resolveMethodEx = getInstanceMethod theType [| typeof; typeof<(string * string) seq>; typeof; typeof |] resolveDependenciesMethodName + let resolveMethodExWithTimeout = getInstanceMethod theType [| typeof; typeof<(string * string) seq>; typeof; typeof; typeof |] resolveDependenciesMethodName + let resolveDepsExWithScriptInfoAndTimeout = getInstanceMethod theType [| typeof; typeof; typeof; typeof<(string * string) seq>; typeof; typeof; typeof |] resolveDependenciesMethodName + Some (fun () -> ReflectionDependencyManagerProvider(theType, nameProperty, keyProperty, None, resolveMethod, resolveMethodEx, resolveMethodExWithTimeout, resolveDepsExWithScriptInfoAndTimeout,outputDir) :> IDependencyManagerProvider) + | Some _, Some nameProperty, Some keyProperty, Some helpMessagesProperty -> + let resolveMethod = getInstanceMethod theType [| typeof; typeof; typeof; typeof; typeof |] resolveDependenciesMethodName + let resolveMethodEx = getInstanceMethod theType [| typeof; typeof<(string * string) seq>; typeof; typeof |] resolveDependenciesMethodName + let resolveMethodExWithTimeout = getInstanceMethod theType [| typeof; typeof<(string * string) seq>; typeof; typeof; typeof; |] resolveDependenciesMethodName + let resolveDepsExWithScriptInfoAndTimeout = getInstanceMethod theType [| typeof; typeof; typeof; typeof<(string * string) seq>; typeof; typeof; typeof |] resolveDependenciesMethodName + Some (fun () -> ReflectionDependencyManagerProvider(theType, nameProperty, keyProperty, Some helpMessagesProperty, resolveMethod, resolveMethodEx, resolveMethodExWithTimeout, resolveDepsExWithScriptInfoAndTimeout, outputDir) :> IDependencyManagerProvider) + + static member MakeResultFromObject(result: obj) = { + new IResolveDependenciesResult with + /// Succeded? + member _.Success = + match getInstanceProperty (result.GetType()) "Success" with + | None -> false + | Some p -> p.GetValue(result) :?> bool + + /// The resolution output log + member _.StdOut = + match getInstanceProperty (result.GetType()) "StdOut" with + | None -> Array.empty + | Some p -> p.GetValue(result) :?> string array + + /// The resolution error log (* process stderror *) + member _.StdError = + match getInstanceProperty (result.GetType()) "StdError" with + | None -> Array.empty + | Some p -> p.GetValue(result) :?> string array + + /// The resolution paths + member _.Resolutions = + match getInstanceProperty (result.GetType()) "Resolutions" with + | None -> Seq.empty + | Some p -> p.GetValue(result) :?> string seq + + /// The source code file paths + member _.SourceFiles = + match getInstanceProperty (result.GetType()) "SourceFiles" with + | None -> Seq.empty + | Some p -> p.GetValue(result) :?> string seq + + /// The roots to package directories + member _.Roots = + match getInstanceProperty (result.GetType()) "Roots" with + | None -> Seq.empty + | Some p -> p.GetValue(result) :?> string seq + } + + static member MakeResultFromFields(success: bool, stdOut: string array, stdError: string array, resolutions: string seq, sourceFiles: string seq, roots: string seq) = { + new IResolveDependenciesResult with + /// Succeded? + member _.Success = success + + /// The resolution output log + member _.StdOut = stdOut + + /// The resolution error log (* process stderror *) + member _.StdError = stdError + + /// The resolution paths + member _.Resolutions = resolutions + + /// The source code file paths + member _.SourceFiles = sourceFiles + + /// The roots to package directories + member _.Roots = roots + } + + + interface IDependencyManagerProvider with + + /// Name of dependency Manager + member _.Name = instance |> nameProperty + + /// Key of dependency Manager: used for #r "key: ... " E.g nuget + member _.Key = instance |> keyProperty + + /// Key of dependency Manager: used for #help + member _.HelpMessages = instance |> helpMessagesProperty + + /// Resolve the dependencies for the given arguments + member this.ResolveDependencies(scriptDir, mainScriptName, scriptName, scriptExt, packageManagerTextLines, tfm, rid, timeout): IResolveDependenciesResult = + // The ResolveDependencies method, has two signatures, the original signaature in the variable resolveDeps and the updated signature resolveDepsEx + // the resolve method can return values in two different tuples: + // (bool * string list * string list * string list) + // (bool * string list * string list) + // We use reflection to get the correct method and to determine what we got back. + let method, arguments = + if resolveDepsExWithScriptInfoAndTimeout.IsSome then + resolveDepsExWithScriptInfoAndTimeout, [| box scriptDir; box scriptName; box scriptExt; box packageManagerTextLines; box tfm; box rid; box timeout |] + elif resolveDepsExWithTimeout.IsSome then + resolveDepsExWithTimeout, [| box scriptExt; box packageManagerTextLines; box tfm; box rid; box timeout |] + elif resolveDepsEx.IsSome then + resolveDepsEx, [| box scriptExt; box packageManagerTextLines; box tfm; box rid |] + elif resolveDeps.IsSome then + resolveDeps, [| box scriptDir + box mainScriptName + box scriptName + box (packageManagerTextLines + |> Seq.filter(fun (dv, _) -> dv = "r") + |> Seq.map snd) + box tfm |] + else + None, [||] + + match method with + | Some m -> + let result = m.Invoke(instance, arguments) + + // Verify the number of arguments returned in the tuple returned by resolvedependencies, it can be: + // 1 - object with properties + // 3 - (bool * string list * string list) + // Support legacy api return shape (bool, string seq, string seq) --- original paket packagemanager + if FSharpType.IsTuple (result.GetType()) then + // Verify the number of arguments returned in the tuple returned by resolvedependencies, it can be: + // 3 - (bool * string list * string list) + let success, sourceFiles, packageRoots = + let tupleFields = result |> FSharpValue.GetTupleFields + match tupleFields |> Array.length with + | 3 -> tupleFields.[0] :?> bool, tupleFields.[1] :?> string list |> List.toSeq, tupleFields.[2] :?> string list |> List.distinct |> List.toSeq + | _ -> false, seqEmpty, seqEmpty + ReflectionDependencyManagerProvider.MakeResultFromFields(success, Array.empty, Array.empty, Seq.empty, sourceFiles, packageRoots) + else + ReflectionDependencyManagerProvider.MakeResultFromObject(result) + + | None -> + ReflectionDependencyManagerProvider.MakeResultFromFields(false, Array.empty, Array.empty, Seq.empty, Seq.empty, Seq.empty) + + +/// Provides DependencyManagement functions. +/// Class is IDisposable +type DependencyProvider (assemblyProbingPaths: AssemblyResolutionProbe, nativeProbingRoots: NativeResolutionProbe) = + + // Note: creating a NativeDllResolveHandler currently installs process-wide handlers + let dllResolveHandler = new NativeDllResolveHandler(nativeProbingRoots) + + // Note: creating a AssemblyResolveHandler currently installs process-wide handlers + let assemblyResolveHandler = + match assemblyProbingPaths with + | null -> { new IDisposable with member _.Dispose() = () } + | _ -> new AssemblyResolveHandler(assemblyProbingPaths) :> IDisposable + + // Resolution Path = Location of FSharp.Compiler.Service.dll + let assemblySearchPaths = lazy ( + [ + let assemblyLocation = typeof.GetTypeInfo().Assembly.Location + yield Path.GetDirectoryName assemblyLocation + yield AppDomain.CurrentDomain.BaseDirectory + ]) + + let enumerateDependencyManagerAssemblies compilerTools (reportError: ResolvingErrorReport) = + getCompilerToolsDesignTimeAssemblyPaths compilerTools + |> Seq.append (assemblySearchPaths.Force()) + |> Seq.collect (fun path -> + try + if Directory.Exists(path) then Directory.EnumerateFiles(path, dependencyManagerPattern) + else Seq.empty + with _ -> Seq.empty) + |> Seq.choose (fun path -> + try + Some(Assembly.LoadFrom path) + with + | e -> + let e = stripTieWrapper e + let n, m = FSComp.SR.couldNotLoadDependencyManagerExtension(path,e.Message) + reportError.Invoke(ErrorReportType.Warning, n, m) + None) + |> Seq.filter (fun a -> assemblyHasAttribute a dependencyManagerAttributeName) + + let mutable registeredDependencyManagers: Map option= None + + let RegisteredDependencyManagers (compilerTools: string seq) (outputDir: string option) (reportError: ResolvingErrorReport) = + match registeredDependencyManagers with + | Some managers -> + managers + | None -> + let managers = + let defaultProviders = [] + + let loadedProviders = + enumerateDependencyManagerAssemblies compilerTools reportError + |> Seq.collect (fun a -> a.GetTypes()) + |> Seq.choose (fun t -> ReflectionDependencyManagerProvider.InstanceMaker(t, outputDir)) + |> Seq.map (fun maker -> maker ()) + + defaultProviders + |> Seq.append loadedProviders + |> Seq.map (fun pm -> pm.Key, pm) + |> Map.ofSeq + + registeredDependencyManagers <- + if managers.Count > 0 then + Some managers + else + None + managers + + let cache = ConcurrentDictionary<_,Result>(HashIdentity.Structural) + + new (nativeProbingRoots: NativeResolutionProbe) = new DependencyProvider(null, nativeProbingRoots) + + new () = new DependencyProvider(null, null) + + /// Returns a formatted help messages for registered dependencymanagers for the host to present + member _.GetRegisteredDependencyManagerHelpText (compilerTools, outputDir, errorReport) = [| + let managers = RegisteredDependencyManagers compilerTools (Option.ofString outputDir) errorReport + for kvp in managers do + let dm = kvp.Value + yield! dm.HelpMessages + |] + /// Returns a formatted error message for the host to present + member _.CreatePackageManagerUnknownError (compilerTools: string seq, outputDir: string, packageManagerKey: string, reportError: ResolvingErrorReport) = + let registeredKeys = String.Join(", ", RegisteredDependencyManagers compilerTools (Option.ofString outputDir) reportError |> Seq.map (fun kv -> kv.Value.Key)) + let searchPaths = assemblySearchPaths.Force() + FSComp.SR.packageManagerUnknown(packageManagerKey, String.Join(", ", searchPaths, compilerTools), registeredKeys) + + /// Fetch a dependencymanager that supports a specific key + member this.TryFindDependencyManagerInPath (compilerTools: string seq, outputDir: string, reportError: ResolvingErrorReport, path: string): string * IDependencyManagerProvider = + try + if path.Contains ":" && not (Path.IsPathRooted path) then + let managers = RegisteredDependencyManagers compilerTools (Option.ofString outputDir) reportError + + match managers |> Seq.tryFind (fun kv -> path.StartsWith(kv.Value.Key + ":" )) with + | None -> + let err, msg = this.CreatePackageManagerUnknownError(compilerTools, outputDir, path.Split(':').[0], reportError) + reportError.Invoke(ErrorReportType.Error, err, msg) + null, Unchecked.defaultof + + | Some kv -> path, kv.Value + else + path, Unchecked.defaultof + with + | e -> + let e = stripTieWrapper e + let err, msg = FSComp.SR.packageManagerError(e.Message) + reportError.Invoke(ErrorReportType.Error, err, msg) + null, Unchecked.defaultof + + /// Fetch a dependencymanager that supports a specific key + member _.TryFindDependencyManagerByKey (compilerTools: string seq, outputDir: string, reportError: ResolvingErrorReport, key: string): IDependencyManagerProvider = + try + RegisteredDependencyManagers compilerTools (Option.ofString outputDir) reportError + |> Map.tryFind key + |> Option.defaultValue Unchecked.defaultof + + with + | e -> + let e = stripTieWrapper e + let err, msg = FSComp.SR.packageManagerError(e.Message) + reportError.Invoke(ErrorReportType.Error, err, msg) + Unchecked.defaultof + + /// Resolve reference for a list of package manager lines + member _.Resolve (packageManager:IDependencyManagerProvider, + scriptExt: string, + packageManagerTextLines: (string * string) seq, + reportError: ResolvingErrorReport, + executionTfm: string, + []executionRid: string, + []implicitIncludeDir: string, + []mainScriptName: string, + []fileName: string, + []timeout: int): IResolveDependenciesResult = + + let key = (packageManager.Key, scriptExt, Seq.toArray packageManagerTextLines, executionTfm, executionRid, implicitIncludeDir, mainScriptName, fileName) + + let result = + cache.GetOrAdd(key, System.Func<_,_>(fun _ -> + try + let executionRid = + if isNull executionRid then + RidHelpers.platformRid + else + executionRid + Ok (packageManager.ResolveDependencies(implicitIncludeDir, mainScriptName, fileName, scriptExt, packageManagerTextLines, executionTfm, executionRid, timeout)) + + with e -> + let e = stripTieWrapper e + Error (FSComp.SR.packageManagerError(e.Message)) + )) + match result with + | Ok res -> + dllResolveHandler.RefreshPathsInEnvironment(res.Roots) + res + | Error (errorNumber, errorData) -> + reportError.Invoke(ErrorReportType.Error, errorNumber, errorData) + ReflectionDependencyManagerProvider.MakeResultFromFields(false, arrEmpty, arrEmpty, seqEmpty, seqEmpty, seqEmpty) + + interface IDisposable with + + member _.Dispose() = + + // Unregister everything + registeredDependencyManagers <- None + (dllResolveHandler :> IDisposable).Dispose() + assemblyResolveHandler.Dispose() diff --git a/src/fsharp/DependencyManager/DependencyProvider.fsi b/src/fsharp/DependencyManager/DependencyProvider.fsi new file mode 100644 index 00000000000..5f9710b126b --- /dev/null +++ b/src/fsharp/DependencyManager/DependencyProvider.fsi @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +/// Helper members to integrate DependencyManagers into F# codebase +namespace FSharp.Compiler.DependencyManager + +open System.Runtime.InteropServices + +/// The results of ResolveDependencies +type IResolveDependenciesResult = + + /// Succeded? + abstract Success: bool + + /// The resolution output log + abstract StdOut: string[] + + /// The resolution error log (process stderr) + abstract StdError: string[] + + /// The resolution paths - the full paths to selected resolved dll's. + /// In scripts this is equivalent to #r @"c:\somepath\to\packages\ResolvedPackage\1.1.1\lib\netstandard2.0\ResolvedAssembly.dll" + abstract Resolutions: seq + + /// The source code file paths + abstract SourceFiles: seq + + /// The roots to package directories + /// This points to the root of each located package. + /// The layout of the package manager will be package manager specific. + /// however, the dependency manager dll understands the nuget package layout + /// and so if the package contains folders similar to the nuget layout then + /// the dependency manager will be able to probe and resolve any native dependencies + /// required by the nuget package. + /// + /// This path is also equivalent to + /// #I @"c:\somepath\to\packages\1.1.1\ResolvedPackage" + abstract Roots: seq + +/// Wraps access to a DependencyManager implementation +[] +type IDependencyManagerProvider = + + /// Name of the dependency manager + abstract Name: string + + /// Key that identifies the types of dependencies that this DependencyManager operates on + /// E.g + /// nuget: indicates that this DM is for nuget packages + /// paket: indicates that this DM is for paket scripts, which manage nuget packages, github source dependencies etc ... + abstract Key: string + + /// The help messages for this dependency manager inster + abstract HelpMessages: string[] + + /// Resolve the dependencies, for the given set of arguments, go find the .dll references, scripts and additional include values. + abstract ResolveDependencies: scriptDir: string * mainScriptName: string * scriptName: string * scriptExt: string * packageManagerTextLines: (string * string) seq * tfm: string * rid: string * timeout: int -> IResolveDependenciesResult + +/// Todo describe this API +[] +type ErrorReportType = + | Warning + | Error + +type ResolvingErrorReport = delegate of ErrorReportType * int * string -> unit + +/// Provides DependencyManagement functions. +/// +/// The class incrementally collects IDependencyManagerProvider, indexed by key, and +/// queries them. These are found and instantiated with respect to the compilerTools and outputDir +/// provided each time the TryFindDependencyManagerByKey and TryFindDependencyManagerInPath are +/// executed, which are assumed to be invariant over the lifetime of the DependencyProvider. +type DependencyProvider = + interface System.IDisposable + + /// Construct a new DependencyProvider with no dynamic load handlers (only for compilation/analysis) + new: unit -> DependencyProvider + + /// Construct a new DependencyProvider with only native resolution + new: nativeProbingRoots: NativeResolutionProbe -> DependencyProvider + + /// Construct a new DependencyProvider with managed and native resolution + new: assemblyProbingPaths: AssemblyResolutionProbe * nativeProbingRoots: NativeResolutionProbe -> DependencyProvider + + /// Returns a formatted help messages for registered dependencymanagers for the host to present + member GetRegisteredDependencyManagerHelpText: string seq * string * ResolvingErrorReport -> string[] + + /// Returns a formatted error message for the host to present + member CreatePackageManagerUnknownError: string seq * string * string * ResolvingErrorReport -> int * string + + /// Resolve reference for a list of package manager lines + member Resolve : packageManager: IDependencyManagerProvider * scriptExt: string * packageManagerTextLines: (string * string) seq * reportError: ResolvingErrorReport * executionTfm: string * []executionRid: string * []implicitIncludeDir: string * []mainScriptName: string * []fileName: string * []timeout: int -> IResolveDependenciesResult + + /// Fetch a dependencymanager that supports a specific key + member TryFindDependencyManagerByKey: compilerTools: string seq * outputDir: string * reportError: ResolvingErrorReport * key: string -> IDependencyManagerProvider + + /// TryFindDependencyManagerInPath - given a #r "key:sometext" go and find a DependencyManager that satisfies the key + member TryFindDependencyManagerInPath: compilerTools: string seq * outputDir: string * reportError: ResolvingErrorReport * path: string -> string * IDependencyManagerProvider diff --git a/src/fsharp/DependencyManager/NativeDllResolveHandler.fs b/src/fsharp/DependencyManager/NativeDllResolveHandler.fs new file mode 100644 index 00000000000..b389ef1976b --- /dev/null +++ b/src/fsharp/DependencyManager/NativeDllResolveHandler.fs @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Compiler.DependencyManager + +open System +open System.Collections.Concurrent +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open Internal.Utilities +open Internal.Utilities.FSharpEnvironment +open FSharp.Compiler.IO + +/// Signature for Native library resolution probe callback +/// host implements this, it's job is to return a list of package roots to probe. +type NativeResolutionProbe = delegate of Unit -> seq + +/// Type that encapsulates Native library probing for managed packages +type NativeDllResolveHandlerCoreClr (nativeProbingRoots: NativeResolutionProbe) = + + let nativeLibraryTryLoad = + let nativeLibraryType: Type = Type.GetType("System.Runtime.InteropServices.NativeLibrary, System.Runtime.InteropServices", false) + nativeLibraryType.GetMethod("TryLoad", [| typeof; typeof.MakeByRefType() |]) + + let loadNativeLibrary path = + let arguments = [| path:>obj; IntPtr.Zero:>obj |] + if nativeLibraryTryLoad.Invoke(null, arguments) :?> bool then + arguments.[1] :?> IntPtr + else + IntPtr.Zero + + let probingFileNames (name: string) = + // coreclr native library probing algorithm: https://github.com/dotnet/coreclr/blob/9773db1e7b1acb3ec75c9cc0e36bd62dcbacd6d5/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Unix.cs + let isRooted = Path.IsPathRooted name + let useSuffix s = not (name.Contains(s + ".") || name.EndsWith(s)) // linux devs often append version # to libraries I.e mydll.so.5.3.2 + let usePrefix = name.IndexOf(Path.DirectorySeparatorChar) = -1 // If name has directory information no add no prefix + && name.IndexOf(Path.AltDirectorySeparatorChar) = -1 + && name.IndexOf(Path.PathSeparator) = -1 + && name.IndexOf(Path.VolumeSeparatorChar) = -1 + let prefix = [| "lib" |] + let suffix = [| + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + ".dll" + ".exe" + elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then + ".dylib" + else + ".so" + |] + + [| + yield name // Bare name + if not isRooted then + for s in suffix do + if useSuffix s then // Suffix without prefix + yield (sprintf "%s%s" name s) + if usePrefix then + for p in prefix do // Suffix with prefix + yield (sprintf "%s%s%s" p name s) + elif usePrefix then + for p in prefix do // Prefix + yield (sprintf "%s%s" p name) + |] + + let resolveUnmanagedDll (_: Assembly) (name: string): IntPtr = + // Enumerate probing roots looking for a dll that matches the probing name in the probed locations + let probeForNativeLibrary root rid name = + // Look for name in root + probingFileNames name |> Array.tryPick(fun name -> + let path = Path.Combine(root, "runtimes", rid, "native", name) + if FileSystem.FileExistsShim(path) then + Some path + else + None) + + let probe = + match nativeProbingRoots with + | null -> None + | _ -> + nativeProbingRoots.Invoke() + |> Seq.tryPick(fun root -> + probingFileNames name |> Seq.tryPick(fun name -> + let path = Path.Combine(root, name) + if FileSystem.FileExistsShim(path) then + Some path + else + RidHelpers.probingRids |> Seq.tryPick(fun rid -> probeForNativeLibrary root rid name))) + + match probe with + | Some path -> loadNativeLibrary(path) + | None -> IntPtr.Zero + + // netstandard 2.1 has this property, unfortunately we don't build with that yet + //public event Func ResolvingUnmanagedDll + let assemblyLoadContextType: Type = Type.GetType("System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader", false) + let eventInfo, handler, defaultAssemblyLoadContext = + assemblyLoadContextType.GetEvent("ResolvingUnmanagedDll"), + Func resolveUnmanagedDll, + assemblyLoadContextType.GetProperty("Default", BindingFlags.Static ||| BindingFlags.Public).GetValue(null, null) + + do eventInfo.AddEventHandler(defaultAssemblyLoadContext, handler) + + interface IDisposable with + member _x.Dispose() = eventInfo.RemoveEventHandler(defaultAssemblyLoadContext, handler) + + +type NativeDllResolveHandler (nativeProbingRoots: NativeResolutionProbe) = + let handler: IDisposable option = + if isRunningOnCoreClr then + Some (new NativeDllResolveHandlerCoreClr(nativeProbingRoots) :> IDisposable) + else + None + + let appendPathSeparator (p: string) = + let separator = string Path.PathSeparator + if not(p.EndsWith(separator, StringComparison.OrdinalIgnoreCase)) then + p + separator + else + p + + let addedPaths = ConcurrentBag() + + let addProbeToProcessPath probePath = + let probe = appendPathSeparator probePath + let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH")) + if not (path.Contains(probe)) then + Environment.SetEnvironmentVariable("PATH", path + probe) + addedPaths.Add probe + + let removeProbeFromProcessPath probePath = + if not(String.IsNullOrWhiteSpace(probePath)) then + let probe = appendPathSeparator probePath + let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH")) + if path.Contains(probe) then Environment.SetEnvironmentVariable("PATH", path.Replace(probe, "")) + + member internal _.RefreshPathsInEnvironment(roots: string seq) = + for probePath in roots do + addProbeToProcessPath probePath + + interface IDisposable with + member _.Dispose() = + match handler with + | None -> () + | Some handler -> handler.Dispose() + + let mutable probe:string = null + while (addedPaths.TryTake(&probe)) do + removeProbeFromProcessPath probe diff --git a/src/fsharp/DependencyManager/NativeDllResolveHandler.fsi b/src/fsharp/DependencyManager/NativeDllResolveHandler.fsi new file mode 100644 index 00000000000..d0845bb94f3 --- /dev/null +++ b/src/fsharp/DependencyManager/NativeDllResolveHandler.fsi @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Compiler.DependencyManager + +open System + +/// Signature for Native library resolution probe callback +/// host implements this, it's job is to return a list of package roots to probe. +type NativeResolutionProbe = delegate of Unit -> seq + +// Cut down AssemblyLoadContext, for loading native libraries +type NativeDllResolveHandler = + + /// Construct a new NativeDllResolveHandler + new: nativeProbingRoots: NativeResolutionProbe -> NativeDllResolveHandler + + member internal RefreshPathsInEnvironment: string seq -> unit + + interface IDisposable diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.cs.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.cs.xlf new file mode 100644 index 00000000000..02d19934c7f --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.cs.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Rozšíření správce závislostí {0} nešlo načíst. Zpráva: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + Klíč správce balíčků {0} nebyl zaregistrován v {1}. Aktuálně registrováno: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.de.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.de.xlf new file mode 100644 index 00000000000..bb1db43a2ce --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.de.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Die Abhängigkeits-Manager-Erweiterung "{0}" konnte nicht geladen werden. Meldung: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + Der Paket-Manager-Schlüssel "{0}" wurde in "{1}" nicht registriert. Aktuell registriert: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.es.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.es.xlf new file mode 100644 index 00000000000..5a958efd39a --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.es.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + No se pudo cargar la extensión del administrador de dependencias {0}. Mensaje: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + La clave del administrador de paquetes "{0}" no se registró en {1}. Registrada actualmente: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.fr.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.fr.xlf new file mode 100644 index 00000000000..519a389da70 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.fr.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Impossible de charger l'extension du gestionnaire de dépendances {0}. Message : {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + La clé '{0}' du gestionnaire de packages n'était pas inscrite dans {1}. L'inscription a été effectuée : {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.it.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.it.xlf new file mode 100644 index 00000000000..8151d104801 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.it.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Non è stato possibile caricare l'estensione {0} di gestione delle dipendenze. Messaggio: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + La chiave di gestione pacchetti '{0}' non è stata registrata in {1}. Attualmente registrata: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ja.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ja.xlf new file mode 100644 index 00000000000..1e890345fef --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ja.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + 依存関係マネージャーの拡張機能 {0} を読み込むことができませんでした。メッセージ: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + パッケージ マネージャー キー '{0}' は {1} に登録されていませんでした。現在登録済み: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ko.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ko.xlf new file mode 100644 index 00000000000..cd143f21947 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ko.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + 종속성 관리자 확장 {0}을(를) 로드할 수 없습니다. 메시지: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + 패키지 관리자 키 '{0}'이(가) {1}에 등록되지 않았습니다. 현재 {2}이(가) 등록되었습니다. + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pl.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pl.xlf new file mode 100644 index 00000000000..d56ae456b17 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pl.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Nie można załadować rozszerzenia menedżera zależności {0}. Komunikat: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + Klucz menedżera pakietów „{0}” nie został zarejestrowany w elemencie {1}. Obecnie zarejestrowane: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pt-BR.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pt-BR.xlf new file mode 100644 index 00000000000..c763930afc8 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.pt-BR.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Não foi possível carregar a extensão do gerenciador de dependências {0}. Mensagem: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + A chave '{0}' do gerenciador de pacotes não foi registrada em {1}. Registrada no momento: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ru.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ru.xlf new file mode 100644 index 00000000000..cdd5ac74a2c --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.ru.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + Не удалось загрузить расширение диспетчера зависимостей {0}. Сообщение: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + Ключ "{0}" диспетчера пакетов не был зарегистрирован в {1}. Текущий зарегистрированный ключ: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.tr.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.tr.xlf new file mode 100644 index 00000000000..530c0738210 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.tr.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + {0} bağımlılık yöneticisi uzantısı yüklenemedi. İleti: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + '{0}' paket yöneticisi anahtarı {1} içinde kayıtlı değil. Şu anda kayıtlı: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hans.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hans.xlf new file mode 100644 index 00000000000..458e8ea5f6e --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hans.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + 无法加载依赖项管理器扩展 {0}。消息: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + 未在 {1} 中注册包管理器密钥“{0}”。当前注册: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hant.xlf b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hant.xlf new file mode 100644 index 00000000000..58f0ebd8588 --- /dev/null +++ b/src/fsharp/DependencyManager/xlf/DependencyManager.txt.zh-Hant.xlf @@ -0,0 +1,22 @@ + + + + + + The dependency manager extension {0} could not be loaded. Message: {1} + 無法載入相依性管理員延伸模組 {0}。訊息: {1} + + + + {0} + {0} + + + + Package manager key '{0}' was not registered in {1}. Currently registered: {2} + 套件管理員金鑰 '{0}' 未在 {1} 中註冊。目前已註冊: {2} + + + + + \ No newline at end of file diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs index 309e358ff97..af0b8c6233a 100644 --- a/src/fsharp/DetupleArgs.fs +++ b/src/fsharp/DetupleArgs.fs @@ -2,16 +2,17 @@ module internal FSharp.Compiler.Detuple -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Ast -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps -// // This pass has one aim. // - to eliminate tuples allocated at call sites (due to uncurried style) // @@ -154,10 +155,8 @@ let (|TyappAndApp|_|) e = | Expr.App _ -> Some(f, fty, tys, args, m) (* has args, so not combine ty args *) | f -> Some(f, fty, tys, args, m) | _ -> None -//------------------------------------------------------------------------- -// GetValsBoundInExpr -//------------------------------------------------------------------------- +[] module GlobalUsageAnalysis = let bindAccBounds vals (_isInDTree, v) = Zset.add v vals @@ -167,11 +166,6 @@ module GlobalUsageAnalysis = let z = FoldExpr folder z0 expr z - - //------------------------------------------------------------------------- - // GlobalUsageAnalysis - state and ops - //------------------------------------------------------------------------- - type accessor = TupleGet of int * TType list /// Expr information. @@ -212,7 +206,6 @@ module GlobalUsageAnalysis = let z = if isInDTree then {z with DecisionTreeBindings = Zset.add v z.DecisionTreeBindings} else z let z = if z.IterationIsAtTopLevel then {z with TopLevelBindings = Zset.add v z.TopLevelBindings} else z z - /// Log the definition of a non-recursive binding let logNonRecBinding z (bind: Binding) = @@ -295,7 +288,7 @@ module GlobalUsageAnalysis = let context = [] recognise context origExpr - let targetIntercept exprF z = function TTarget(_argvs, body, _) -> Some (foldUnderLambda exprF z body) + let targetIntercept exprF z = function TTarget(_argvs, body, _, _) -> Some (foldUnderLambda exprF z body) let tmethodIntercept exprF z = function TObjExprMethod(_, _, _, _, e, _m) -> Some (foldUnderLambda exprF z e) {ExprFolder0 with @@ -307,7 +300,6 @@ module GlobalUsageAnalysis = tmethodIntercept = tmethodIntercept } - //------------------------------------------------------------------------- // GlobalUsageAnalysis - entry point //------------------------------------------------------------------------- @@ -317,24 +309,13 @@ module GlobalUsageAnalysis = let z = FoldImplFile folder z0 expr z - -open GlobalUsageAnalysis - -//------------------------------------------------------------------------- -// misc -//------------------------------------------------------------------------- - let internalError str = raise(Failure(str)) let mkLocalVal m name ty topValInfo = - let compgen = false in (* REVIEW: review: should this be true? *) - NewVal(name, m, None, ty, Immutable, compgen, topValInfo, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) - - -//------------------------------------------------------------------------- -// TupleStructure = tuple structure -//------------------------------------------------------------------------- + let compgen = false + Construct.NewVal(name, m, None, ty, Immutable, compgen, topValInfo, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) +/// Represents inferred information about a tuple value type TupleStructure = | UnknownTS | TupleTS of TupleStructure list @@ -409,7 +390,7 @@ let rec minimalCallPattern callPattern = match minimalCallPattern tss with | [] -> [] (* drop trailing UnknownTS *) | tss -> UnknownTS :: tss (* non triv tss tail *) - | (TupleTS ts) :: tss -> TupleTS ts :: minimalCallPattern tss + | TupleTS ts :: tss -> TupleTS ts :: minimalCallPattern tss /// Combines a list of callpatterns into one common callpattern. let commonCallPattern callPatterns = @@ -482,7 +463,7 @@ let mkTransform g (f: Val) m tps x1Ntys rty (callPattern, tyfringes: (TType list | _ -> Some(ValReprInfo (ValReprInfo.InferTyparInfo tps, List.collect ValReprInfoForTS callPattern, ValReprInfo.unnamedRetVal)) (* type(transformedVal) tyfringes types replace initial arg types of f *) let tys1r = List.collect fst tyfringes (* types for collapsed initial r args *) - let tysrN = List.drop tyfringes.Length x1Ntys (* types for remaining args *) + let tysrN = List.skip tyfringes.Length x1Ntys (* types for remaining args *) let argtys = tys1r @ tysrN let fCty = mkLambdaTy tps argtys rty let transformedVal = @@ -619,17 +600,16 @@ let determineTransforms g (z : GlobalUsageAnalysis.Results) = let vtransforms = Zmap.ofList valOrder vtransforms vtransforms - - //------------------------------------------------------------------------- // pass - penv - env of pass //------------------------------------------------------------------------- type penv = - { // The planned transforms - transforms : Zmap - ccu : CcuThunk - g : TcGlobals } + { // The planned transforms + transforms: Zmap + ccu: CcuThunk + g: TcGlobals + } let hasTransfrom penv f = Zmap.tryFind f penv.transforms @@ -649,10 +629,10 @@ type env = prefix: string - m: Range.range + m: range } - override __.ToString() = "" + override _.ToString() = "" let suffixE env s = {env with prefix = env.prefix + s} @@ -683,7 +663,7 @@ let buildProjections env bindings x xtys = xtys |> List.mapi (fun i xty -> let vi, vix = newLocalN env i xty - let bind = mkBind NoSequencePointAtInvisibleBinding vi (mkTupleFieldGet env.eg (tupInfoRef, x, xtys, i, env.m)) + let bind = mkBind DebugPointAtBinding.NoneAtInvisible vi (mkTupleFieldGet env.eg (tupInfoRef, x, xtys, i, env.m)) bind, vix) |> List.unzip @@ -710,7 +690,7 @@ let rec collapseArg env bindings ts (x: Expr) = let bindings, xs = buildProjections env bindings x xtys collapseArg env bindings (TupleTS tss) (mkRefTupled env.eg m xs xtys) -and collapseArgs env bindings n (callPattern) args = +and collapseArgs env bindings n callPattern args = match callPattern, args with | [], args -> bindings, args | ts :: tss, arg :: args -> @@ -733,7 +713,7 @@ let fixupApp (penv: penv) (fx, fty, tys, args, m) = // Is it a val app, where the val has a transform? match fx with - | Expr.Val (vref, _, m) -> + | Expr.Val (vref, _, vm) -> let f = vref.Deref match hasTransfrom penv f with | Some trans -> @@ -741,7 +721,7 @@ let fixupApp (penv: penv) (fx, fty, tys, args, m) = let callPattern = trans.transformCallPattern let transformedVal = trans.transformedVal let fCty = transformedVal.Type - let fCx = exprForVal m transformedVal + let fCx = exprForVal vm transformedVal (* [[f tps args ]] -> transformedVal tps [[COLLAPSED: args]] *) let env = {prefix = "arg";m = m;eg=penv.g} let bindings = [] @@ -753,7 +733,6 @@ let fixupApp (penv: penv) (fx, fty, tys, args, m) = | _ -> Expr.App (fx, fty, tys, args, m) (* no change, f is expr *) - //------------------------------------------------------------------------- // pass - mubinds - translation support //------------------------------------------------------------------------- @@ -803,7 +782,7 @@ let passBind penv (TBind(fOrig, repr, letSeqPtOpt) as bind) = let transformedFormals = trans.transformedFormals let p = transformedFormals.Length if (vss.Length < p) then internalError "passBinds: |vss|

None - let passImplFile penv assembly = - assembly |> RewriteImplFile {PreIntercept =None - PreInterceptBinding=None - PostTransform= postTransformExpr penv - IsUnderQuotations=false } - + assembly |> RewriteImplFile { PreIntercept =None + PreInterceptBinding=None + PostTransform= postTransformExpr penv + IsUnderQuotations=false } //------------------------------------------------------------------------- // entry point //------------------------------------------------------------------------- let DetupleImplFile ccu g expr = - // collect expr info - wanting usage contexts and bindings - let (z : Results) = GetUsageInfoOfImplFile g expr + // Collect expr info - wanting usage contexts and bindings + let z = GetUsageInfoOfImplFile g expr + // For each Val, decide Some "transform", or None if not changing let vtrans = determineTransforms g z diff --git a/src/fsharp/DetupleArgs.fsi b/src/fsharp/DetupleArgs.fsi index c76c02b1c40..6db0ef42b8b 100644 --- a/src/fsharp/DetupleArgs.fsi +++ b/src/fsharp/DetupleArgs.fsi @@ -2,32 +2,36 @@ module internal FSharp.Compiler.Detuple -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.Tast +open Internal.Utilities.Collections open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree -val DetupleImplFile : CcuThunk -> TcGlobals -> TypedImplFile -> TypedImplFile +val DetupleImplFile: CcuThunk -> TcGlobals -> TypedImplFile -> TypedImplFile module GlobalUsageAnalysis = - val GetValsBoundInExpr : Expr -> Zset + val GetValsBoundInExpr: Expr -> Zset type accessor - /// Results is "expr information". - /// This could extend to be a full graph view of the expr. - /// Later could support "safe" change operations, and optimisations could be in terms of those. type Results = - { /// v -> context / APP inst args - Uses : Zmap; + { + /// v -> context / APP inst args + Uses: Zmap + /// v -> binding repr - Defns : Zmap; + Defns: Zmap + /// bound in a decision tree? - DecisionTreeBindings : Zset; + DecisionTreeBindings: Zset + /// v -> recursive? * v list -- the others in the mutual binding - RecursiveBindings : Zmap; + RecursiveBindings: Zmap + /// val not defined under lambdas - TopLevelBindings : Zset; + TopLevelBindings: Zset + /// top of expr toplevel? (true) - IterationIsAtTopLevel : bool; + IterationIsAtTopLevel: bool } - val GetUsageInfoOfImplFile : TcGlobals -> TypedImplFile -> Results + + val GetUsageInfoOfImplFile: TcGlobals -> TypedImplFile -> Results diff --git a/src/fsharp/Diagnostics.fs b/src/fsharp/Diagnostics.fs new file mode 100644 index 00000000000..350703012ed --- /dev/null +++ b/src/fsharp/Diagnostics.fs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// This file contains simple types related to diagnsotics that are made public in the +// FSharp.Compiler.Service API but which are also used throughout the +// F# compiler. +namespace FSharp.Compiler.Diagnostics + +[] +type FSharpDiagnosticSeverity = + | Hidden + | Info + | Warning + | Error + +type FSharpDiagnosticOptions = + { + WarnLevel: int + GlobalWarnAsError: bool + WarnOff: int list + WarnOn: int list + WarnAsError: int list + WarnAsWarn: int list + } + static member Default = + { + WarnLevel = 3 + GlobalWarnAsError = false + WarnOff = [] + WarnOn = [] + WarnAsError = [] + WarnAsWarn = [] + } + diff --git a/src/fsharp/Diagnostics.fsi b/src/fsharp/Diagnostics.fsi new file mode 100644 index 00000000000..b1dc86be20b --- /dev/null +++ b/src/fsharp/Diagnostics.fsi @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// This file contains simple types related to diagnsotics that are made public in the +// FSharp.Compiler.Service API but which are also used throughout the +// F# compiler. + +namespace FSharp.Compiler.Diagnostics + +[] +type FSharpDiagnosticSeverity = + | Hidden + | Info + | Warning + | Error + +type FSharpDiagnosticOptions = + { WarnLevel: int + GlobalWarnAsError: bool + WarnOff: int list + WarnOn: int list + WarnAsError: int list + WarnAsWarn: int list } + + static member Default: FSharpDiagnosticOptions + diff --git a/src/fsharp/Directory.Build.props b/src/fsharp/Directory.Build.props index 151415117e4..ba0693c81e5 100644 --- a/src/fsharp/Directory.Build.props +++ b/src/fsharp/Directory.Build.props @@ -2,8 +2,16 @@ + + + true + + - true true false $(ArtifactsPackagesDir)\$(Configuration) diff --git a/src/fsharp/DotNetFrameworkDependencies.fs b/src/fsharp/DotNetFrameworkDependencies.fs deleted file mode 100644 index a454ec80594..00000000000 --- a/src/fsharp/DotNetFrameworkDependencies.fs +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -// Functions to retrieve framework dependencies -module internal FSharp.Compiler.DotNetFrameworkDependencies - - open System - open System.Collections.Generic - open System.Diagnostics - open System.Globalization - open System.IO - open System.Reflection - open Internal.Utilities - - type private TypeInThisAssembly = class end - - let fSharpCompilerLocation = - let location = Path.GetDirectoryName(typeof.Assembly.Location) - match FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some location) with - | Some path -> path - | None -> -#if DEBUG - Debug.Print(sprintf "FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some '%s') returned None Location customized incorrectly: algorithm here: https://github.com/dotnet/fsharp/blob/03f3f1c35f82af26593d025dabca57a6ef3ea9a1/src/utils/CompilerLocationUtils.fs#L171" location) -#endif - // Use the location of this dll - location - - let getFSharpCoreLibraryName = "FSharp.Core" - let getFsiLibraryName = "FSharp.Compiler.Interactive.Settings" - let getDefaultFSharpCoreLocation = Path.Combine(fSharpCompilerLocation, getFSharpCoreLibraryName + ".dll") - let getDefaultFsiLibraryLocation = Path.Combine(fSharpCompilerLocation, getFsiLibraryName + ".dll") - let implementationAssemblyDir = Path.GetDirectoryName(typeof.Assembly.Location) - let isRunningOnCoreClr = (typeof.Assembly).FullName.StartsWith("System.Private.CoreLib", StringComparison.InvariantCultureIgnoreCase) - - // Use the ValueTuple that is executing with the compiler if it is from System.ValueTuple - // or the System.ValueTuple.dll that sits alongside the compiler. (Note we always ship one with the compiler) - let getDefaultSystemValueTupleReference () = - try - let asm = typeof>.Assembly - if asm.FullName.StartsWith("System.ValueTuple", StringComparison.OrdinalIgnoreCase) then - Some asm.Location - else - let valueTuplePath = Path.Combine(fSharpCompilerLocation, "System.ValueTuple.dll") - if File.Exists(valueTuplePath) then - Some valueTuplePath - else - None - with _ -> None - - // Algorithm: - // use implementation location of obj type, on shared frameworks it will always be in: - // - // dotnet\shared\Microsoft.NETCore.App\sdk-version\System.Private.CoreLib.dll - // - // if that changes we will need to find another way to do this. Hopefully the sdk will eventually provide an API - // use the well know location for obj to traverse the file system towards the - // - // packs\Microsoft.NETCore.App.Ref\sdk-version\netcoreappn.n - // we will rely on the sdk-version match on the two paths to ensure that we get the product that ships with the - // version of the runtime we are executing on - // Use the reference assemblies for the highest netcoreapp tfm that we find in that location. - let version, frameworkRefsPackDirectoryRoot = - try - let version = DirectoryInfo(implementationAssemblyDir).Name - let microsoftNETCoreAppRef = Path.Combine(implementationAssemblyDir, "../../../packs/Microsoft.NETCore.App.Ref") - if Directory.Exists(microsoftNETCoreAppRef) then - Some version, Some microsoftNETCoreAppRef - else - Some version, None - with | _ -> None, None - - // Tries to figure out the tfm for the compiler instance. - // On coreclr it uses the deps.json file - let netcoreTfm = - let file = - try - let asm = Assembly.GetEntryAssembly() - match asm with - | null -> "" - | asm -> - let depsJsonPath = Path.ChangeExtension(asm.Location, "deps.json") - if File.Exists(depsJsonPath) then - File.ReadAllText(depsJsonPath) - else - "" - with _ -> "" - - let tfmPrefix=".NETCoreApp,Version=v" - let pattern = "\"name\": \"" + tfmPrefix - let startPos = - let startPos = file.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) - if startPos >= 0 then startPos + (pattern.Length) else startPos - - let length = - if startPos >= 0 then - let ep = file.IndexOf("\"", startPos) - if ep >= 0 then ep - startPos else ep - else -1 - match startPos, length with - | -1, _ - | _, -1 -> - if isRunningOnCoreClr then - // Running on coreclr but no deps.json was deployed with the host so default to 3.0 - Some "netcoreapp3.0" - else - // Running on desktop - None - | pos, length -> - // use value from the deps.json file - Some ("netcoreapp" + file.Substring(pos, length)) - - // Tries to figure out the tfm for the compiler instance on the Windows desktop. - // On full clr it uses the mscorlib version number - let getWindowsDesktopTfm () = - let defaultMscorlibVersion = 4,8,3815,0 - let desktopProductVersionMonikers = [| - // major, minor, build, revision, moniker - 4, 8, 3815, 0, "net48" - 4, 7, 3190, 0, "net472" - 4, 7, 2600, 0, "net471" - 4, 7, 2053, 0, "net47" - 4, 6, 1590, 0, "net462" - 4, 6, 1055, 0, "net461" - 4, 6, 81, 0, "net46" - 4, 0, 30319, 34209, "net452" - 4, 0, 30319, 18408, "net451" - 4, 0, 30319, 17929, "net45" - 4, 0, 30319, 1, "net4" - |] - - let majorPart, minorPart, buildPart, privatePart= - try - let attrOpt = typeof.Assembly.GetCustomAttributes(typeof) |> Seq.tryHead - match attrOpt with - | Some attr -> - let fv = (downcast attr : AssemblyFileVersionAttribute).Version.Split([|'.'|]) |> Array.map(fun e -> Int32.Parse(e)) - fv.[0], fv.[1], fv.[2], fv.[3] - | _ -> defaultMscorlibVersion - with _ -> defaultMscorlibVersion - - // Get the ProductVersion of this framework compare with table yield compatible monikers - let _, _, _, _, moniker = - desktopProductVersionMonikers - |> Array.find (fun (major, minor, build, revision, _) -> - (majorPart >= major) && - (minorPart >= minor) && - (buildPart >= build) && - (privatePart >= revision)) - moniker - - /// Gets the tfm E.g netcore3.0, net472 - let executionTfm = - match netcoreTfm with - | Some tfm -> tfm - | _ -> getWindowsDesktopTfm () - let isInReferenceAssemblyPackDirectory filename = - match frameworkRefsPackDirectoryRoot with - | Some root -> - let path = Path.GetDirectoryName(filename) - path.StartsWith(root, StringComparison.OrdinalIgnoreCase) - | _ -> false - - let frameworkRefsPackDirectory = - let tfmPrefix = "netcoreapp" - let tfmCompare c1 c2 = - let deconstructTfmApp (netcoreApp: DirectoryInfo) = - let name = netcoreApp.Name - try - if name.StartsWith(tfmPrefix, StringComparison.InvariantCultureIgnoreCase) then - Some (Double.Parse(name.Substring(tfmPrefix.Length), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture)) - else - None - with _ -> None - - if c1 = c2 then 0 - else - match (deconstructTfmApp c1), (deconstructTfmApp c2) with - | Some c1, Some c2 -> int(c1 - c2) - | None, Some _ -> -1 - | Some _, None -> 1 - | _ -> 0 - - match version, frameworkRefsPackDirectoryRoot with - | Some version, Some root -> - try - let ref = Path.Combine(root, version, "ref") - let highestTfm = DirectoryInfo(ref).GetDirectories() - |> Array.sortWith tfmCompare - |> Array.tryLast - - match highestTfm with - | Some tfm -> Some (Path.Combine(ref, tfm.Name)) - | None -> None - with | _ -> None - | _ -> None - - let getDependenciesOf assemblyReferences = - let assemblies = new Dictionary() - - // Identify path to a dll in the framework directory from a simple name - let frameworkPathFromSimpleName simpleName = - let root = Path.Combine(implementationAssemblyDir, simpleName) - let pathOpt = - [| ""; ".dll"; ".exe" |] - |> Seq.tryPick(fun ext -> - let path = root + ext - if File.Exists(path) then Some path - else None) - match pathOpt with - | Some path -> path - | None -> root - - // Collect all assembly dependencies into assemblies dictionary - let rec traverseDependencies reference = - // Reference can be either path to a file on disk or a Assembly Simple Name - let referenceName, path = - try - if File.Exists(reference) then - // Reference is a path to a file on disk - Path.GetFileNameWithoutExtension(reference), reference - else - // Reference is a SimpleAssembly name - reference, frameworkPathFromSimpleName reference - - with _ -> reference, frameworkPathFromSimpleName reference - - if not (assemblies.ContainsKey(referenceName)) then - try - if File.Exists(path) then - // System.Private.CoreLib doesn't load with reflection - if referenceName = "System.Private.CoreLib" then - assemblies.Add(referenceName, path) - else - try - let asm = System.Reflection.Assembly.LoadFrom(path) - assemblies.Add(referenceName, path) - for reference in asm.GetReferencedAssemblies() do - traverseDependencies reference.Name - with e -> () - with e -> () - - assemblyReferences |> List.iter(traverseDependencies) - assemblies - - // This list is the default set of references for "non-project" files. - // - // These DLLs are - // (a) included in the environment used for all .fsx files (see service.fs) - // (b) included in environment for files 'orphaned' from a project context - // -- for orphaned files (files in VS without a project context) - let getDesktopDefaultReferences useFsiAuxLib = [ - yield "mscorlib" - yield "System" - yield "System.Xml" - yield "System.Runtime.Remoting" - yield "System.Runtime.Serialization.Formatters.Soap" - yield "System.Data" - yield "System.Drawing" - yield "System.Core" - - yield getFSharpCoreLibraryName - if useFsiAuxLib then yield getFsiLibraryName - - // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources - match getDefaultSystemValueTupleReference () with - | None -> () - | Some v -> yield v - - // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed - // when an F# script references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers - // to FSharp.Core for profile 7, 78, 259 or .NET Standard. - yield "netstandard" - yield "System.Runtime" // lots of types - yield "System.Linq" // System.Linq.Expressions.Expression - yield "System.Reflection" // System.Reflection.ParameterInfo - yield "System.Linq.Expressions" // System.Linq.IQueryable - yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken - yield "System.IO" // System.IO.TextWriter - yield "System.Net.Requests" // System.Net.WebResponse etc. - yield "System.Collections" // System.Collections.Generic.List - yield "System.Runtime.Numerics" // BigInteger - yield "System.Threading" // OperationCanceledException - yield "System.Web" - yield "System.Web.Services" - yield "System.Windows.Forms" - yield "System.Numerics" - ] - - let fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework = - let results = - if assumeDotNetFramework then - getDesktopDefaultReferences useFsiAuxLib - else - let dependencies = - let getImplementationReferences () = - // Coreclr supports netstandard assemblies only for now - (getDependenciesOf [ - yield! Directory.GetFiles(implementationAssemblyDir, "*.dll") - yield getDefaultFSharpCoreLocation - if useFsiAuxLib then yield getDefaultFsiLibraryLocation - ]).Values |> Seq.toList - - if useSdkRefs then - // Go fetch references - match frameworkRefsPackDirectory with - | Some path -> - try [ yield! Directory.GetFiles(path, "*.dll") - yield getDefaultFSharpCoreLocation - if useFsiAuxLib then yield getDefaultFsiLibraryLocation - ] - with | _ -> List.empty - | None -> - getImplementationReferences () - else - getImplementationReferences () - dependencies - results - - let defaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib assumeDotNetFramework useSdkRefs = - fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework - - // A set of assemblies to always consider to be system assemblies. A common set of these can be used a shared - // resources between projects in the compiler services. Also all assemblies where well-known system types exist - // referenced from TcGlobals must be listed here. - let systemAssemblies = - HashSet [ - yield "mscorlib" - yield "netstandard" - yield "System.Runtime" - yield getFSharpCoreLibraryName - - yield "System" - yield "System.Xml" - yield "System.Runtime.Remoting" - yield "System.Runtime.Serialization.Formatters.Soap" - yield "System.Data" - yield "System.Deployment" - yield "System.Design" - yield "System.Messaging" - yield "System.Drawing" - yield "System.Net" - yield "System.Web" - yield "System.Web.Services" - yield "System.Windows.Forms" - yield "System.Core" - yield "System.Runtime" - yield "System.Observable" - yield "System.Numerics" - yield "System.ValueTuple" - - // Additions for coreclr and portable profiles - yield "System.Collections" - yield "System.Collections.Concurrent" - yield "System.Console" - yield "System.Diagnostics.Debug" - yield "System.Diagnostics.Tools" - yield "System.Globalization" - yield "System.IO" - yield "System.Linq" - yield "System.Linq.Expressions" - yield "System.Linq.Queryable" - yield "System.Net.Requests" - yield "System.Reflection" - yield "System.Reflection.Emit" - yield "System.Reflection.Emit.ILGeneration" - yield "System.Reflection.Extensions" - yield "System.Resources.ResourceManager" - yield "System.Runtime.Extensions" - yield "System.Runtime.InteropServices" - yield "System.Runtime.InteropServices.PInvoke" - yield "System.Runtime.Numerics" - yield "System.Text.Encoding" - yield "System.Text.Encoding.Extensions" - yield "System.Text.RegularExpressions" - yield "System.Threading" - yield "System.Threading.Tasks" - yield "System.Threading.Tasks.Parallel" - yield "System.Threading.Thread" - yield "System.Threading.ThreadPool" - yield "System.Threading.Timer" - - yield "FSharp.Compiler.Interactive.Settings" - yield "Microsoft.Win32.Registry" - yield "System.Diagnostics.Tracing" - yield "System.Globalization.Calendars" - yield "System.Reflection.Primitives" - yield "System.Runtime.Handles" - yield "Microsoft.Win32.Primitives" - yield "System.IO.FileSystem" - yield "System.Net.Primitives" - yield "System.Net.Sockets" - yield "System.Private.Uri" - yield "System.AppContext" - yield "System.Buffers" - yield "System.Collections.Immutable" - yield "System.Diagnostics.DiagnosticSource" - yield "System.Diagnostics.Process" - yield "System.Diagnostics.TraceSource" - yield "System.Globalization.Extensions" - yield "System.IO.Compression" - yield "System.IO.Compression.ZipFile" - yield "System.IO.FileSystem.Primitives" - yield "System.Net.Http" - yield "System.Net.NameResolution" - yield "System.Net.WebHeaderCollection" - yield "System.ObjectModel" - yield "System.Reflection.Emit.Lightweight" - yield "System.Reflection.Metadata" - yield "System.Reflection.TypeExtensions" - yield "System.Runtime.InteropServices.RuntimeInformation" - yield "System.Runtime.Loader" - yield "System.Security.Claims" - yield "System.Security.Cryptography.Algorithms" - yield "System.Security.Cryptography.Cng" - yield "System.Security.Cryptography.Csp" - yield "System.Security.Cryptography.Encoding" - yield "System.Security.Cryptography.OpenSsl" - yield "System.Security.Cryptography.Primitives" - yield "System.Security.Cryptography.X509Certificates" - yield "System.Security.Principal" - yield "System.Security.Principal.Windows" - yield "System.Threading.Overlapped" - yield "System.Threading.Tasks.Extensions" - yield "System.Xml.ReaderWriter" - yield "System.Xml.XDocument" - ] - - // The set of references entered into the TcConfigBuilder for scripts prior to computing the load closure. - let basicReferencesForScriptLoadClosure useFsiAuxLib useSdkRefs assumeDotNetFramework = - fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs old mode 100755 new mode 100644 index 2f515d566a8..6757b628cf9 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module public FSharp.Compiler.ErrorLogger +module FSharp.Compiler.ErrorLogger -open FSharp.Compiler -open FSharp.Compiler.Range +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Features +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text open System - -//------------------------------------------------------------------------ -// General error recovery mechanism -//----------------------------------------------------------------------- +open System.Diagnostics /// Represents the style being used to format errors [] @@ -52,7 +51,7 @@ let NoSuggestions : Suggestions = ignore /// Thrown when we stop processing the F# Interactive entry or #load. exception StopProcessingExn of exn option with - override this.Message = "Processing of a script fragment has stopped because an exception has been raised" + override _.Message = "Processing of a script fragment has stopped because an exception has been raised" override this.ToString() = match this :> exn with @@ -61,21 +60,15 @@ exception StopProcessingExn of exn option with let (|StopProcessing|_|) exn = match exn with StopProcessingExn _ -> Some () | _ -> None -let StopProcessing<'T> = StopProcessingExn None -exception NumberedError of (int * string) * range with // int is e.g. 191 in FS0191 - override this.Message = - match this :> exn with - | NumberedError((_, msg), _) -> msg - | _ -> "impossible" +let StopProcessing<'T> = StopProcessingExn None -exception Error of (int * string) * range with // int is e.g. 191 in FS0191 // eventually remove this type, it is a transitional artifact of the old unnumbered error style +exception Error of (int * string) * range with // int is e.g. 191 in FS0191 override this.Message = match this :> exn with | Error((_, msg), _) -> msg | _ -> "impossible" - exception InternalError of msg: string * range with override this.Message = match this :> exn with @@ -83,17 +76,26 @@ exception InternalError of msg: string * range with | _ -> "impossible" exception UserCompilerMessage of string * int * range + exception LibraryUseOnly of range + exception Deprecated of string * range + exception Experimental of string * range + exception PossibleUnverifiableCode of range exception UnresolvedReferenceNoRange of (*assemblyName*) string + exception UnresolvedReferenceError of (*assemblyName*) string * range -exception UnresolvedPathReferenceNoRange of (*assemblyName*) string * (*path*) string -exception UnresolvedPathReference of (*assemblyName*) string * (*path*) string * range +exception UnresolvedPathReferenceNoRange of (*assemblyName*) string * (*path*) string with + override this.Message = + match this :> exn with + | UnresolvedPathReferenceNoRange(assemblyName, path) -> sprintf "Assembly: %s, full path: %s" assemblyName path + | _ -> "impossible" +exception UnresolvedPathReference of (*assemblyName*) string * (*path*) string * range exception ErrorWithSuggestions of (int * string) * range * string * Suggestions with // int is e.g. 191 in FS0191 override this.Message = @@ -125,7 +127,7 @@ let inline protectAssemblyExplorationNoReraise dflt1 dflt2 f = // Attach a range if this is a range dual exception. let rec AttachRange m (exn:exn) = - if Range.equals m range0 then exn + if equals m range0 then exn else match exn with // Strip TargetInvocationException wrappers @@ -133,22 +135,17 @@ let rec AttachRange m (exn:exn) = | UnresolvedReferenceNoRange a -> UnresolvedReferenceError(a, m) | UnresolvedPathReferenceNoRange(a, p) -> UnresolvedPathReference(a, p, m) | Failure msg -> InternalError(msg + " (Failure)", m) - | :? System.ArgumentException as exn -> InternalError(exn.Message + " (ArgumentException)", m) + | :? ArgumentException as exn -> InternalError(exn.Message + " (ArgumentException)", m) | notARangeDual -> notARangeDual - -//---------------------------------------------------------------------------- -// Error logger interface - type Exiter = abstract Exit : int -> 'T - let QuitProcessExiter = { new Exiter with - member __.Exit n = + member _.Exit n = try - System.Environment.Exit n + Environment.Exit n with _ -> () FSComp.SR.elSysEnvExitDidntExit() @@ -191,7 +188,7 @@ module BuildPhaseSubcategory = [] let Internal = "internal" // Compiler ICE -[] +[] type PhasedDiagnostic = { Exception:exn; Phase:BuildPhase } @@ -244,12 +241,12 @@ type PhasedDiagnostic = // Just treat as an unknown-to-LanguageService error. -> false | unknownSubcategory -> - System.Diagnostics.Debug.Assert(false, sprintf "Subcategory '%s' could not be correlated with a build phase." unknownSubcategory) + Debug.Assert(false, sprintf "Subcategory '%s' could not be correlated with a build phase." unknownSubcategory) // Recovery is to treat this as a 'build' error. Downstream, the project system and language service will treat this as // if it came from the build and not the language service. false - /// Return true if this phase is one that's known to be part of the 'compile'. This is the initial phase of the entire compilation that + /// Return true if this phase is one that's known to be part of the 'compile'. This is the initial phase of the entire compilation that /// the language service knows about. member pe.IsPhaseInCompile() = let isPhaseInCompile = @@ -259,30 +256,30 @@ type PhasedDiagnostic = // Sanity check ensures that Phase matches Subcategory #if DEBUG if isPhaseInCompile then - System.Diagnostics.Debug.Assert(PhasedDiagnostic.IsSubcategoryOfCompile(pe.Subcategory()), "Subcategory did not match isPhaseInCompile=true") + Debug.Assert(PhasedDiagnostic.IsSubcategoryOfCompile(pe.Subcategory()), "Subcategory did not match isPhaseInCompile=true") else - System.Diagnostics.Debug.Assert(not(PhasedDiagnostic.IsSubcategoryOfCompile(pe.Subcategory())), "Subcategory did not match isPhaseInCompile=false") + Debug.Assert(not(PhasedDiagnostic.IsSubcategoryOfCompile(pe.Subcategory())), "Subcategory did not match isPhaseInCompile=false") #endif isPhaseInCompile [] -[] +[] type ErrorLogger(nameForDebugging:string) = abstract ErrorCount: int // The 'Impl' factoring enables a developer to place a breakpoint at the non-Impl // code just below and get a breakpoint for all error logger implementations. - abstract DiagnosticSink: phasedError: PhasedDiagnostic * isError: bool -> unit - member __.DebugDisplay() = sprintf "ErrorLogger(%s)" nameForDebugging + abstract DiagnosticSink: phasedError: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + member _.DebugDisplay() = sprintf "ErrorLogger(%s)" nameForDebugging let DiscardErrorsLogger = { new ErrorLogger("DiscardErrorsLogger") with - member x.DiagnosticSink(phasedError, isError) = () + member x.DiagnosticSink(phasedError, severity) = () member x.ErrorCount = 0 } let AssertFalseErrorLogger = { new ErrorLogger("AssertFalseErrorLogger") with // TODO: reenable these asserts in the compiler service - member x.DiagnosticSink(phasedError, isError) = (* assert false; *) () + member x.DiagnosticSink(phasedError, severity) = (* assert false; *) () member x.ErrorCount = (* assert false; *) 0 } @@ -290,26 +287,30 @@ type CapturingErrorLogger(nm) = inherit ErrorLogger(nm) let mutable errorCount = 0 let diagnostics = ResizeArray() - override x.DiagnosticSink(phasedError, isError) = - if isError then errorCount <- errorCount + 1 - diagnostics.Add (phasedError, isError) - override x.ErrorCount = errorCount - member x.Diagnostics = diagnostics |> Seq.toList - member x.CommitDelayedDiagnostics(errorLogger:ErrorLogger) = + + override _.DiagnosticSink(phasedError, severity) = + if severity = FSharpDiagnosticSeverity.Error then errorCount <- errorCount + 1 + diagnostics.Add (phasedError, severity) + + override _.ErrorCount = errorCount + + member _.Diagnostics = diagnostics |> Seq.toList + + member _.CommitDelayedDiagnostics(errorLogger:ErrorLogger) = // Eagerly grab all the errors and warnings from the mutable collection let errors = diagnostics.ToArray() errors |> Array.iter errorLogger.DiagnosticSink - /// Type holds thread-static globals for use by the compile. type internal CompileThreadStatic = - [] + [] static val mutable private buildPhase : BuildPhase - [] + [] static val mutable private errorLogger : ErrorLogger - static member BuildPhaseUnchecked with get() = CompileThreadStatic.buildPhase (* This can be a null value *) + static member BuildPhaseUnchecked = CompileThreadStatic.buildPhase (* This can be a null value *) + static member BuildPhase with get() = match box CompileThreadStatic.buildPhase with @@ -342,33 +343,33 @@ module ErrorLoggerExtensions = let PreserveStackTrace exn = try if not tryAndDetectDev15 then - let preserveStackTrace = typeof.GetMethod("InternalPreserveStackTrace", BindingFlags.Instance ||| BindingFlags.NonPublic) + let preserveStackTrace = typeof.GetMethod("InternalPreserveStackTrace", BindingFlags.Instance ||| BindingFlags.NonPublic) preserveStackTrace.Invoke(exn, null) |> ignore with _ -> // This is probably only the mono case. - System.Diagnostics.Debug.Assert(false, "Could not preserve stack trace for watson exception.") + Debug.Assert(false, "Could not preserve stack trace for watson exception.") () /// Reraise an exception if it is one we want to report to Watson. let ReraiseIfWatsonable(exn:exn) = match exn with // These few SystemExceptions which we don't report to Watson are because we handle these in some way in Build.fs - | :? System.Reflection.TargetInvocationException -> () - | :? System.NotSupportedException -> () + | :? TargetInvocationException -> () + | :? NotSupportedException -> () | :? System.IO.IOException -> () // This covers FileNotFoundException and DirectoryNotFoundException - | :? System.UnauthorizedAccessException -> () + | :? UnauthorizedAccessException -> () | Failure _ // This gives reports for compiler INTERNAL ERRORs - | :? System.SystemException -> + | :? SystemException -> PreserveStackTrace exn raise exn | _ -> () type ErrorLogger with - member x.ErrorR exn = + member x.EmitDiagnostic (exn, severity) = match exn with | InternalError (s, _) - | Failure s as exn -> System.Diagnostics.Debug.Assert(false, sprintf "Unexpected exception raised in compiler: %s\n%s" s (exn.ToString())) + | Failure s as exn -> Debug.Assert(false, sprintf "Unexpected exception raised in compiler: %s\n%s" s (exn.ToString())) | _ -> () match exn with @@ -376,22 +377,23 @@ module ErrorLoggerExtensions = | ReportedError _ -> PreserveStackTrace exn raise exn - | _ -> x.DiagnosticSink(PhasedDiagnostic.Create(exn, CompileThreadStatic.BuildPhase), true) + | _ -> x.DiagnosticSink(PhasedDiagnostic.Create(exn, CompileThreadStatic.BuildPhase), severity) + + member x.ErrorR exn = + x.EmitDiagnostic (exn, FSharpDiagnosticSeverity.Error) member x.Warning exn = - match exn with - | StopProcessing - | ReportedError _ -> - PreserveStackTrace exn - raise exn - | _ -> x.DiagnosticSink(PhasedDiagnostic.Create(exn, CompileThreadStatic.BuildPhase), false) + x.EmitDiagnostic (exn, FSharpDiagnosticSeverity.Warning) + + member x.InformationalWarning exn = + x.EmitDiagnostic (exn, FSharpDiagnosticSeverity.Info) member x.Error exn = x.ErrorR exn raise (ReportedError (Some exn)) - member x.SimulateError (ph: PhasedDiagnostic) = - x.DiagnosticSink (ph, true) + member x.SimulateError (ph: PhasedDiagnostic) = + x.DiagnosticSink (ph, FSharpDiagnosticSeverity.Error) raise (ReportedError (Some ph.Exception)) member x.ErrorRecovery (exn: exn) (m: range) = @@ -399,7 +401,7 @@ module ErrorLoggerExtensions = // Throws StopProcessing and exceptions raised by the DiagnosticSink(exn) handler. match exn with (* Don't send ThreadAbortException down the error channel *) - | :? System.Threading.ThreadAbortException | WrappedError((:? System.Threading.ThreadAbortException), _) -> () + | :? System.Threading.ThreadAbortException | WrappedError(:? System.Threading.ThreadAbortException, _) -> () | ReportedError _ | WrappedError(ReportedError _, _) -> () | StopProcessing | WrappedError(StopProcessing, _) -> PreserveStackTrace exn @@ -434,7 +436,7 @@ let PushThreadBuildPhaseUntilUnwind (phase:BuildPhase) = CompileThreadStatic.BuildPhase <- phase - { new System.IDisposable with + { new IDisposable with member x.Dispose() = CompileThreadStatic.BuildPhase <- oldBuildPhase (* maybe null *) } /// NOTE: The change will be undone when the returned "unwind" object disposes @@ -444,17 +446,18 @@ let PushErrorLoggerPhaseUntilUnwind(errorLoggerTransformer : ErrorLogger -> #Err let mutable newInstalled = true let newIsInstalled() = if newInstalled then () else (assert false; (); (*failwith "error logger used after unwind"*)) // REVIEW: ok to throw? let chkErrorLogger = { new ErrorLogger("PushErrorLoggerPhaseUntilUnwind") with - member __.DiagnosticSink(phasedError, isError) = newIsInstalled(); newErrorLogger.DiagnosticSink(phasedError, isError) - member __.ErrorCount = newIsInstalled(); newErrorLogger.ErrorCount } + member _.DiagnosticSink(phasedError, isError) = newIsInstalled(); newErrorLogger.DiagnosticSink(phasedError, isError) + member _.ErrorCount = newIsInstalled(); newErrorLogger.ErrorCount } CompileThreadStatic.ErrorLogger <- chkErrorLogger - { new System.IDisposable with - member __.Dispose() = + { new IDisposable with + member _.Dispose() = CompileThreadStatic.ErrorLogger <- oldErrorLogger newInstalled <- false } let SetThreadBuildPhaseNoUnwind(phase:BuildPhase) = CompileThreadStatic.BuildPhase <- phase + let SetThreadErrorLoggerNoUnwind errorLogger = CompileThreadStatic.ErrorLogger <- errorLogger // Global functions are still used by parser and TAST ops. @@ -465,39 +468,49 @@ let errorR exn = CompileThreadStatic.ErrorLogger.ErrorR exn /// Raises a warning with error recovery and returns unit. let warning exn = CompileThreadStatic.ErrorLogger.Warning exn +/// Raises a warning with error recovery and returns unit. +let informationalWarning exn = CompileThreadStatic.ErrorLogger.InformationalWarning exn + /// Raises a special exception and returns 'T - can be caught later at an errorRecovery point. let error exn = CompileThreadStatic.ErrorLogger.Error exn /// Simulates an error. For test purposes only. let simulateError (p : PhasedDiagnostic) = CompileThreadStatic.ErrorLogger.SimulateError p -let diagnosticSink (phasedError, isError) = CompileThreadStatic.ErrorLogger.DiagnosticSink (phasedError, isError) -let errorSink pe = diagnosticSink (pe, true) -let warnSink pe = diagnosticSink (pe, false) +let diagnosticSink (phasedError, severity) = CompileThreadStatic.ErrorLogger.DiagnosticSink (phasedError, severity) + +let errorSink pe = diagnosticSink (pe, FSharpDiagnosticSeverity.Error) + +let warnSink pe = diagnosticSink (pe, FSharpDiagnosticSeverity.Warning) + let errorRecovery exn m = CompileThreadStatic.ErrorLogger.ErrorRecovery exn m + let stopProcessingRecovery exn m = CompileThreadStatic.ErrorLogger.StopProcessingRecovery exn m -let errorRecoveryNoRange exn = CompileThreadStatic.ErrorLogger.ErrorRecoveryNoRange exn +let errorRecoveryNoRange exn = CompileThreadStatic.ErrorLogger.ErrorRecoveryNoRange exn let report f = f() let deprecatedWithError s m = errorR(Deprecated(s, m)) -// Note: global state, but only for compiling FSharp.Core.dll -let mutable reportLibraryOnlyFeatures = true -let libraryOnlyError m = if reportLibraryOnlyFeatures then errorR(LibraryUseOnly m) -let libraryOnlyWarning m = if reportLibraryOnlyFeatures then warning(LibraryUseOnly m) +let libraryOnlyError m = errorR(LibraryUseOnly m) + +let libraryOnlyWarning m = warning(LibraryUseOnly m) + let deprecatedOperator m = deprecatedWithError (FSComp.SR.elDeprecatedOperator()) m + let mlCompatWarning s m = warning(UserCompilerMessage(FSComp.SR.mlCompatMessage s, 62, m)) +let mlCompatError s m = errorR(UserCompilerMessage(FSComp.SR.mlCompatError s, 62, m)) + let suppressErrorReporting f = let errorLogger = CompileThreadStatic.ErrorLogger try let errorLogger = { new ErrorLogger("suppressErrorReporting") with - member __.DiagnosticSink(_phasedError, _isError) = () - member __.ErrorCount = 0 } + member _.DiagnosticSink(_phasedError, _isError) = () + member _.ErrorCount = 0 } SetThreadErrorLoggerNoUnwind errorLogger f() finally @@ -507,13 +520,12 @@ let conditionallySuppressErrorReporting cond f = if cond then suppressErrorRepor //------------------------------------------------------------------------ // Errors as data: Sometimes we have to reify errors as data, e.g. if backtracking -// -// REVIEW: consider using F# computation expressions here +/// The result type of a computational modality to colelct warnings and possibly fail [] type OperationResult<'T> = - | OkResult of (* warnings: *) exn list * 'T - | ErrorResult of (* warnings: *) exn list * exn + | OkResult of warnings: exn list * 'T + | ErrorResult of warnings: exn list * exn type ImperativeOperationResult = OperationResult @@ -530,14 +542,18 @@ let CommitOperationResult res = let RaiseOperationResult res : unit = CommitOperationResult res let ErrorD err = ErrorResult([], err) + let WarnD err = OkResult([err], ()) + let CompleteD = OkResult([], ()) + let ResultD x = OkResult([], x) + let CheckNoErrorsAndGetWarnings res = match res with - | OkResult (warns, _) -> Some warns + | OkResult (warns, res2) -> Some (warns, res2) | ErrorResult _ -> None - + /// The bind in the monad. Stop on first error. Accumulate warnings and continue. let (++) res f = match res with @@ -607,8 +623,14 @@ let TryD f g = | res -> res let rec RepeatWhileD nDeep body = body nDeep ++ (fun x -> if x then RepeatWhileD (nDeep+1) body else CompleteD) -let AtLeastOneD f l = MapD f l ++ (fun res -> ResultD (List.exists id res)) +let inline AtLeastOneD f l = MapD f l ++ (fun res -> ResultD (List.exists id res)) + +let inline AtLeastOne2D f xs ys = List.zip xs ys |> AtLeastOneD (fun (x,y) -> f x y) + +let inline MapReduceD mapper zero reducer l = MapD mapper l ++ (fun res -> ResultD (match res with [] -> zero | _ -> List.reduce reducer res)) + +let inline MapReduce2D mapper zero reducer xs ys = List.zip xs ys |> MapReduceD (fun (x,y) -> mapper x y) zero reducer [] module OperationResult = @@ -618,8 +640,7 @@ module OperationResult = | ErrorResult(warnings, err) -> ErrorResult(warnings, err) // Code below is for --flaterrors flag that is only used by the IDE - -let stringThatIsAProxyForANewlineInFlatErrors = new System.String [|char 29 |] +let stringThatIsAProxyForANewlineInFlatErrors = String [|char 29 |] let NewlineifyErrorString (message:string) = message.Replace(stringThatIsAProxyForANewlineInFlatErrors, Environment.NewLine) @@ -650,28 +671,29 @@ let NormalizeErrorString (text : string) = i <- i + delta buf.ToString() -type public FSharpErrorSeverityOptions = - { - WarnLevel: int - GlobalWarnAsError: bool - WarnOff: int list - WarnOn: int list - WarnAsError: int list - WarnAsWarn: int list - } - static member Default = - { - WarnLevel = 3 - GlobalWarnAsError = false - WarnOff = [] - WarnOn = [] - WarnAsError = [] - WarnAsWarn = [] - } - - -// See https://github.com/Microsoft/visualfsharp/issues/6417, if a compile of the FSharp.Compiler.Services.dll or other compiler -// binary produces exactly 65536 methods then older versions of the compiler raise a bug. If you hit this bug again then try adding -// this back in. -// let dummyMethodFOrBug6417A() = () -// let dummyMethodFOrBug6417B() = () +let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = + if not (langVersion.SupportsFeature langFeature) then + let featureStr = langVersion.GetFeatureString langFeature + let currentVersionStr = langVersion.SpecifiedVersionString + let suggestedVersionStr = langVersion.GetFeatureVersionString langFeature + Some (Error(FSComp.SR.chkFeatureNotLanguageSupported(featureStr, currentVersionStr, suggestedVersionStr), m)) + else + None + +let internal checkLanguageFeatureError langVersion langFeature m = + match tryLanguageFeatureErrorAux langVersion langFeature m with + | Some e -> error e + | None -> () + +let internal checkLanguageFeatureErrorRecover langVersion langFeature m = + match tryLanguageFeatureErrorAux langVersion langFeature m with + | Some e -> errorR e + | None -> () + +let internal tryLanguageFeatureErrorOption langVersion langFeature m = + tryLanguageFeatureErrorAux langVersion langFeature m + +let internal languageFeatureNotSupportedInLibraryError (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = + let featureStr = langVersion.GetFeatureString langFeature + let suggestedVersionStr = langVersion.GetFeatureVersionString langFeature + error (Error(FSComp.SR.chkFeatureNotSupportedInLibrary(featureStr, suggestedVersionStr), m)) diff --git a/src/fsharp/ErrorLogger.fsi b/src/fsharp/ErrorLogger.fsi new file mode 100644 index 00000000000..97f4069ce84 --- /dev/null +++ b/src/fsharp/ErrorLogger.fsi @@ -0,0 +1,340 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.ErrorLogger + +open System +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Features +open FSharp.Compiler.Text + +/// Represents the style being used to format errors +[] +type ErrorStyle = + | DefaultErrors + | EmacsErrors + | TestErrors + | VSErrors + | GccErrors + +/// Thrown when we want to add some range information to a .NET exception +exception WrappedError of exn * range + +/// Thrown when immediate, local error recovery is not possible. This indicates +/// we've reported an error but need to make a non-local transfer of control. +/// Error recovery may catch this and continue (see 'errorRecovery') +/// +/// The exception that caused the report is carried as data because in some +/// situations (LazyWithContext) we may need to re-report the original error +/// when a lazy thunk is re-evaluated. +exception ReportedError of exn option + +val findOriginalException: err:exn -> exn + +type Suggestions = (string -> unit) -> unit + +val NoSuggestions: Suggestions + +/// Thrown when we stop processing the F# Interactive entry or #load. +exception StopProcessingExn of exn option + +val ( |StopProcessing|_| ): exn:exn -> unit option + +val StopProcessing<'T> : exn + +exception Error of (int * string) * range + +exception InternalError of msg: string * range + +exception UserCompilerMessage of string * int * range + +exception LibraryUseOnly of range + +exception Deprecated of string * range + +exception Experimental of string * range + +exception PossibleUnverifiableCode of range + +exception UnresolvedReferenceNoRange of string + +exception UnresolvedReferenceError of string * range + +exception UnresolvedPathReferenceNoRange of string * string + +exception UnresolvedPathReference of string * string * range + +exception ErrorWithSuggestions of (int * string) * range * string * Suggestions + +val inline protectAssemblyExploration: dflt:'a -> f:(unit -> 'a) -> 'a + +val inline protectAssemblyExplorationF: dflt:(string * string -> 'a) -> f:(unit -> 'a) -> 'a + +val inline protectAssemblyExplorationNoReraise: dflt1:'a -> dflt2:'a -> f:(unit -> 'a) -> 'a + +val AttachRange: m:range -> exn:exn -> exn + +type Exiter = + abstract member Exit: int -> 'T + +val QuitProcessExiter: Exiter + +/// Closed enumeration of build phases. +[] +type BuildPhase = + | DefaultPhase + | Compile + | Parameter + | Parse + | TypeCheck + | CodeGen + | Optimize + | IlxGen + | IlGen + | Output + | Interactive + +/// Literal build phase subcategory strings. +module BuildPhaseSubcategory = + [] val DefaultPhase: string = "" + [] val Compile: string = "compile" + [] val Parameter: string = "parameter" + [] val Parse: string = "parse" + [] val TypeCheck: string = "typecheck" + [] val CodeGen: string = "codegen" + [] val Optimize: string = "optimize" + [] val IlxGen: string = "ilxgen" + [] val IlGen: string = "ilgen" + [] val Output: string = "output" + [] val Interactive: string = "interactive" + [] val Internal: string = "internal" + +type PhasedDiagnostic = + { Exception: exn + Phase: BuildPhase } + + /// Construct a phased error + static member Create: exn:exn * phase:BuildPhase -> PhasedDiagnostic + + /// Return true if the textual phase given is from the compile part of the build process. + /// This set needs to be equal to the set of subcategories that the language service can produce. + static member IsSubcategoryOfCompile: subcategory:string -> bool + + member DebugDisplay: unit -> string + + /// Return true if this phase is one that's known to be part of the 'compile'. This is the initial phase of the entire compilation that + /// the language service knows about. + member IsPhaseInCompile: unit -> bool + + /// This is the textual subcategory to display in error and warning messages (shows only under --vserrors): + /// + /// file1.fs(72): subcategory warning FS0072: This is a warning message + /// + member Subcategory: unit -> string + +[] +type ErrorLogger = + + new: nameForDebugging:string -> ErrorLogger + + member DebugDisplay: unit -> string + + abstract member DiagnosticSink: phasedError:PhasedDiagnostic * severity:FSharpDiagnosticSeverity -> unit + + abstract member ErrorCount: int + +val DiscardErrorsLogger: ErrorLogger + +val AssertFalseErrorLogger: ErrorLogger + +type CapturingErrorLogger = + inherit ErrorLogger + + new: nm:string -> CapturingErrorLogger + + member CommitDelayedDiagnostics: errorLogger:ErrorLogger -> unit + + override DiagnosticSink: phasedError:PhasedDiagnostic * severity:FSharpDiagnosticSeverity -> unit + + member Diagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + override ErrorCount: int + +[] +type CompileThreadStatic = + + static member BuildPhase: BuildPhase with get, set + + static member BuildPhaseUnchecked: BuildPhase with get + + static member ErrorLogger: ErrorLogger with get, set + +[] +module ErrorLoggerExtensions = + + val tryAndDetectDev15: bool + + /// Instruct the exception not to reset itself when thrown again. + val PreserveStackTrace: exn:'a -> unit + + /// Reraise an exception if it is one we want to report to Watson. + val ReraiseIfWatsonable: exn:exn -> unit + + type ErrorLogger with + member ErrorR: exn:exn -> unit + member Warning: exn:exn -> unit + member Error: exn:exn -> 'b + member SimulateError: ph:PhasedDiagnostic -> 'a + member ErrorRecovery: exn:exn -> m:range -> unit + member StopProcessingRecovery: exn:exn -> m:range -> unit + member ErrorRecoveryNoRange: exn:exn -> unit + +/// NOTE: The change will be undone when the returned "unwind" object disposes +val PushThreadBuildPhaseUntilUnwind: phase:BuildPhase -> IDisposable + +/// NOTE: The change will be undone when the returned "unwind" object disposes +val PushErrorLoggerPhaseUntilUnwind: errorLoggerTransformer:(ErrorLogger -> #ErrorLogger) -> IDisposable + +val SetThreadBuildPhaseNoUnwind: phase:BuildPhase -> unit + +val SetThreadErrorLoggerNoUnwind: errorLogger:ErrorLogger -> unit + +/// Reports an error diagnostic and continues +val errorR: exn:exn -> unit + +/// Reports a warning diagnostic +val warning: exn:exn -> unit + +/// Reports an error and raises a ReportedError exception +val error: exn:exn -> 'a + +/// Reports an informational diagnostic +val informationalWarning: exn:exn -> unit + +val simulateError: p:PhasedDiagnostic -> 'a + +val diagnosticSink: phasedError:PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit + +val errorSink: pe:PhasedDiagnostic -> unit + +val warnSink: pe:PhasedDiagnostic -> unit + +val errorRecovery: exn:exn -> m:range -> unit + +val stopProcessingRecovery: exn:exn -> m:range -> unit + +val errorRecoveryNoRange: exn:exn -> unit + +val report: f:(unit -> 'a) -> 'a + +val deprecatedWithError: s:string -> m:range -> unit + +val libraryOnlyError: m:range -> unit + +val libraryOnlyWarning: m:range -> unit + +val deprecatedOperator: m:range -> unit + +val mlCompatWarning: s:string -> m:range -> unit + +val mlCompatError: s:string -> m:range -> unit + +val suppressErrorReporting: f:(unit -> 'a) -> 'a + +val conditionallySuppressErrorReporting: cond:bool -> f:(unit -> 'a) -> 'a + +/// The result type of a computational modality to colelct warnings and possibly fail +[] +type OperationResult<'T> = + | OkResult of warnings: exn list * 'T + | ErrorResult of warnings: exn list * exn + +type ImperativeOperationResult = OperationResult + +val ReportWarnings: warns:#exn list -> unit + +val CommitOperationResult: res:OperationResult<'a> -> 'a + +val RaiseOperationResult: res:OperationResult -> unit + +val ErrorD: err:exn -> OperationResult<'a> + +val WarnD: err:exn -> OperationResult + +val CompleteD: OperationResult + +val ResultD: x:'a -> OperationResult<'a> + +val CheckNoErrorsAndGetWarnings: res:OperationResult<'a> -> (exn list * 'a) option + +val ( ++ ): res:OperationResult<'a> -> f:('a -> OperationResult<'b>) -> OperationResult<'b> + +/// Stop on first error. Accumulate warnings and continue. +val IterateD: f:('a -> OperationResult) -> xs:'a list -> OperationResult + +val WhileD: gd:(unit -> bool) -> body:(unit -> OperationResult) -> OperationResult + +val MapD: f:('a -> OperationResult<'b>) -> xs:'a list -> OperationResult<'b list> + +type TrackErrorsBuilder = + + new: unit -> TrackErrorsBuilder + + member Bind: res:OperationResult<'h> * k:('h -> OperationResult<'i>) -> OperationResult<'i> + + member Combine: expr1:OperationResult<'c> * expr2:('c -> OperationResult<'d>) -> OperationResult<'d> + + member Delay: fn:(unit -> 'b) -> (unit -> 'b) + + member For: seq:'e list * k:('e -> OperationResult) -> OperationResult + + member Return: res:'g -> OperationResult<'g> + + member ReturnFrom: res:'f -> 'f + + member Run: fn:(unit -> 'a) -> 'a + + member While: gd:(unit -> bool) * k:(unit -> OperationResult) -> OperationResult + + member Zero: unit -> OperationResult + +val trackErrors: TrackErrorsBuilder + +val OptionD: f:('a -> OperationResult) -> xs:'a option -> OperationResult + +val IterateIdxD: f:(int -> 'a -> OperationResult) -> xs:'a list -> OperationResult + +/// Stop on first error. Accumulate warnings and continue. +val Iterate2D: f:('a -> 'b -> OperationResult) -> xs:'a list -> ys:'b list -> OperationResult + +val TryD: f:(unit -> OperationResult<'a>) -> g:(exn -> OperationResult<'a>) -> OperationResult<'a> + +val RepeatWhileD: nDeep:int -> body:(int -> OperationResult) -> OperationResult + +val inline AtLeastOneD: f:('a -> OperationResult) -> l:'a list -> OperationResult + +val inline AtLeastOne2D: f:('a -> 'b -> OperationResult) -> xs:'a list -> ys:'b list -> OperationResult + +val inline MapReduceD: mapper:('a -> OperationResult<'b>) -> zero: 'b -> reducer: ('b -> 'b -> 'b) -> l:'a list -> OperationResult<'b> + +val inline MapReduce2D: mapper:('a -> 'b -> OperationResult<'c>) -> zero: 'c -> reducer: ('c -> 'c -> 'c) -> xs:'a list -> ys:'b list -> OperationResult<'c> + +module OperationResult = + val inline ignore: res:OperationResult<'a> -> OperationResult + +// For --flaterrors flag that is only used by the IDE +val stringThatIsAProxyForANewlineInFlatErrors: String + +val NewlineifyErrorString: message:string -> string + +/// fixes given string by replacing all control chars with spaces. +/// NOTE: newlines are recognized and replaced with stringThatIsAProxyForANewlineInFlatErrors (ASCII 29, the 'group separator'), +/// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo +val NormalizeErrorString: text:string -> string + +val checkLanguageFeatureError: langVersion:LanguageVersion -> langFeature:LanguageFeature -> m:range -> unit + +val checkLanguageFeatureErrorRecover: langVersion:LanguageVersion -> langFeature:LanguageFeature -> m:range -> unit + +val tryLanguageFeatureErrorOption: langVersion:LanguageVersion -> langFeature:LanguageFeature -> m:range -> exn option + +val languageFeatureNotSupportedInLibraryError: langVersion:LanguageVersion -> langFeature:LanguageFeature -> m:range -> 'a diff --git a/src/fsharp/ErrorResolutionHints.fs b/src/fsharp/ErrorResolutionHints.fs index ee80985935e..64cdc8cd4e3 100644 --- a/src/fsharp/ErrorResolutionHints.fs +++ b/src/fsharp/ErrorResolutionHints.fs @@ -4,13 +4,16 @@ module internal FSharp.Compiler.ErrorResolutionHints open Internal.Utilities -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library open System.Collections open System.Collections.Generic let maxSuggestions = 5 + let minThresholdForSuggestions = 0.7 + let highConfidenceThreshold = 0.85 + let minStringLengthForSuggestion = 3 /// We report a candidate if its edit distance is <= the threshold. @@ -35,18 +38,18 @@ let DemangleOperator (nm: string) = type SuggestionBufferEnumerator(tail: int, data: KeyValuePair []) = let mutable current = data.Length interface IEnumerator with - member __.Current + member _.Current with get () = let kvpr = &data.[current] kvpr.Value - interface System.Collections.IEnumerator with - member __.Current with get () = box data.[current].Value - member __.MoveNext() = + interface IEnumerator with + member _.Current with get () = box data.[current].Value + member _.MoveNext() = current <- current - 1 current > tail || (current = tail && data.[current] <> Unchecked.defaultof<_>) - member __.Reset () = current <- data.Length + member _.Reset () = current <- data.Length interface System.IDisposable with - member __.Dispose () = () + member _.Dispose () = () type SuggestionBuffer(idText: string) = let data = Array.zeroCreate>(maxSuggestions) @@ -68,7 +71,7 @@ type SuggestionBuffer(idText: string) = data.[pos - 1] <- KeyValuePair(k,v) if tail > 0 then tail <- tail - 1 - member __.Add (suggestion: string) = + member _.Add (suggestion: string) = if not disableSuggestions then if suggestion = idText then // some other parse error happened disableSuggestions <- true @@ -85,11 +88,11 @@ type SuggestionBuffer(idText: string) = suggestion.EndsWithOrdinal dotIdText || (similarity >= minThresholdForSuggestions && IsInEditDistanceProximity uppercaseText suggestedText) then - insert(similarity, suggestion) |> ignore + insert(similarity, suggestion) - member __.Disabled with get () = disableSuggestions + member _.Disabled with get () = disableSuggestions - member __.IsEmpty with get () = disableSuggestions || (tail = maxSuggestions - 1) + member _.IsEmpty with get () = disableSuggestions || (tail = maxSuggestions - 1) interface IEnumerable with member this.GetEnumerator () = diff --git a/src/fsharp/ErrorResolutionHints.fsi b/src/fsharp/ErrorResolutionHints.fsi new file mode 100644 index 00000000000..bddc8db70ca --- /dev/null +++ b/src/fsharp/ErrorResolutionHints.fsi @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Functions to format error message details +module internal FSharp.Compiler.ErrorResolutionHints + +open System.Collections +open System.Collections.Generic + +/// We report a candidate if its edit distance is <= the threshold. +/// The threshold is set to about a quarter of the number of characters. +val IsInEditDistanceProximity: idText:string -> suggestion:string -> bool + +/// Demangles a suggestion +val DemangleOperator: nm:string -> string + +type SuggestionBuffer = + + interface IEnumerable + interface IEnumerable + + new: idText:string -> SuggestionBuffer + + member Add: suggestion:string -> unit + + member Disabled: bool + + member IsEmpty: bool diff --git a/src/fsharp/ExtensionTyping.fs b/src/fsharp/ExtensionTyping.fs index 8e73e241fed..8b838f6ef9b 100644 --- a/src/fsharp/ExtensionTyping.fs +++ b/src/fsharp/ExtensionTyping.fs @@ -6,17 +6,21 @@ namespace FSharp.Compiler #if !NO_EXTENSIONTYPING -module internal ExtensionTyping = - open System - open System.IO - open System.Collections.Generic - open System.Reflection - open Microsoft.FSharp.Core.CompilerServices - open FSharp.Compiler.ErrorLogger - open FSharp.Compiler.Range - open FSharp.Compiler.AbstractIL.IL - open FSharp.Compiler.AbstractIL.Internal.Library // frontAndBack - open Internal.Utilities.FSharpEnvironment +open System +open System.Collections.Concurrent +open System.IO +open System.Collections.Generic +open System.Reflection +open Internal.Utilities.Library +open Internal.Utilities.FSharpEnvironment +open FSharp.Core.CompilerServices +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range + +module ExtensionTyping = type TypeProviderDesignation = TypeProviderDesignation of string @@ -27,19 +31,28 @@ module internal ExtensionTyping = /// Represents some of the configuration parameters passed to type provider components type ResolutionEnvironment = - { resolutionFolder : string - outputFile : string option - showResolutionMessages : bool - referencedAssemblies : string[] - temporaryFolder : string } + { resolutionFolder: string + outputFile: string option + showResolutionMessages: bool + referencedAssemblies: string[] + temporaryFolder: string } /// Load a the design-time part of a type-provider into the host process, and look for types /// marked with the TypeProviderAttribute attribute. let GetTypeProviderImplementationTypes (runTimeAssemblyFileName, designTimeAssemblyNameString, m:range, compilerToolPaths:string list) = // Report an error, blaming the particular type provider component - let raiseError (e: exn) = - raise (TypeProviderError(FSComp.SR.etProviderHasWrongDesignerAssembly(typeof.Name, designTimeAssemblyNameString, e.Message), runTimeAssemblyFileName, m)) + let raiseError designTimeAssemblyPathOpt (e: exn) = + let attrName = typeof.Name + let exnTypeName = e.GetType().FullName + let exnMsg = e.Message + match designTimeAssemblyPathOpt with + | None -> + let msg = FSComp.SR.etProviderHasWrongDesignerAssemblyNoPath(attrName, designTimeAssemblyNameString, exnTypeName, exnMsg) + raise (TypeProviderError(msg, runTimeAssemblyFileName, m)) + | Some designTimeAssemblyPath -> + let msg = FSComp.SR.etProviderHasWrongDesignerAssembly(attrName, designTimeAssemblyNameString, designTimeAssemblyPath, exnTypeName, exnMsg) + raise (TypeProviderError(msg, runTimeAssemblyFileName, m)) let designTimeAssemblyOpt = getTypeProviderAssembly (runTimeAssemblyFileName, designTimeAssemblyNameString, compilerToolPaths, raiseError) @@ -54,18 +67,28 @@ module internal ExtensionTyping = yield t ] filtered with e -> - raiseError e + let folder = Path.GetDirectoryName loadedDesignTimeAssembly.Location + let exnTypeName = e.GetType().FullName + let exnMsg = e.Message + match e with + | :? FileLoadException -> + let msg = FSComp.SR.etProviderHasDesignerAssemblyDependency(designTimeAssemblyNameString, folder, exnTypeName, exnMsg) + raise (TypeProviderError(msg, runTimeAssemblyFileName, m)) + + | _ -> + let msg = FSComp.SR.etProviderHasDesignerAssemblyException(designTimeAssemblyNameString, folder, exnTypeName, exnMsg) + raise (TypeProviderError(msg, runTimeAssemblyFileName, m)) | None -> [] let StripException (e: exn) = match e with - | :? System.Reflection.TargetInvocationException as e -> e.InnerException + | :? TargetInvocationException as e -> e.InnerException | :? TypeInitializationException as e -> e.InnerException | _ -> e /// Create an instance of a type provider from the implementation type for the type provider in the /// design-time assembly by using reflection-invoke on a constructor for the type provider. - let CreateTypeProvider (typeProviderImplementationType: System.Type, + let CreateTypeProvider (typeProviderImplementationType: Type, runtimeAssemblyPath, resolutionEnvironment: ResolutionEnvironment, isInvalidationSupported: bool, @@ -104,52 +127,6 @@ module internal ExtensionTyping = // No appropriate constructor found raise (TypeProviderError(FSComp.SR.etProviderDoesNotHaveValidConstructor(), typeProviderImplementationType.FullName, m)) - let GetTypeProvidersOfAssembly - (runTimeAssemblyFileName: string, - ilScopeRefOfRuntimeAssembly: ILScopeRef, - designTimeAssemblyNameString: string, - resolutionEnvironment: ResolutionEnvironment, - isInvalidationSupported: bool, - isInteractive: bool, - systemRuntimeContainsType : string -> bool, - systemRuntimeAssemblyVersion : System.Version, - compilerToolPaths: string list, - m:range) = - - let providerSpecs = - try - let designTimeAssemblyName = - try - if designTimeAssemblyNameString.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then - Some (System.Reflection.AssemblyName (Path.GetFileNameWithoutExtension designTimeAssemblyNameString)) - else - Some (System.Reflection.AssemblyName designTimeAssemblyNameString) - with :? ArgumentException -> - errorR(Error(FSComp.SR.etInvalidTypeProviderAssemblyName(runTimeAssemblyFileName, designTimeAssemblyNameString), m)) - None - - [ match designTimeAssemblyName, resolutionEnvironment.outputFile with - // Check if the attribute is pointing to the file being compiled, in which case ignore it - // This checks seems like legacy but is included for compat. - | Some designTimeAssemblyName, Some path when String.Compare(designTimeAssemblyName.Name, Path.GetFileNameWithoutExtension path, StringComparison.OrdinalIgnoreCase) = 0 -> - () - | Some _, _ -> - for t in GetTypeProviderImplementationTypes (runTimeAssemblyFileName, designTimeAssemblyNameString, m, compilerToolPaths) do - let resolver = CreateTypeProvider (t, runTimeAssemblyFileName, resolutionEnvironment, isInvalidationSupported, isInteractive, systemRuntimeContainsType, systemRuntimeAssemblyVersion, m) - match box resolver with - | null -> () - | _ -> yield (resolver, ilScopeRefOfRuntimeAssembly) - | None, _ -> - () ] - - with :? TypeProviderError as tpe -> - tpe.Iter(fun e -> errorR(NumberedError((e.Number, e.ContextualErrorMessage), m)) ) - [] - - let providers = Tainted<_>.CreateAll providerSpecs - - providers - let unmarshal (t: Tainted<_>) = t.PUntaintNoFailure id /// Try to access a member on a provided type, catching and reporting errors @@ -189,10 +166,6 @@ module internal ExtensionTyping = tpe.Iter (fun e -> errorR(Error(FSComp.SR.etUnexpectedExceptionFromProvidedMemberMember(memberMemberName, typeName, memberName, e.ContextualErrorMessage), m))) mi.PApplyNoFailure(fun _ -> recover) - /// Get the string to show for the name of a type provider - let DisplayNameOfTypeProvider(resolver: Tainted, m: range) = - resolver.PUntaint((fun tp -> tp.GetType().Name), m) - /// Validate a provided namespace name let ValidateNamespaceName(name, typeProvider: Tainted, m, nsp: string) = if nsp<>null then // Null namespace designates the global namespace. @@ -211,6 +184,10 @@ module internal ExtensionTyping = BindingFlags.Instance ||| BindingFlags.Public + type CustomAttributeData = System.Reflection.CustomAttributeData + type CustomAttributeNamedArgument = System.Reflection.CustomAttributeNamedArgument + type CustomAttributeTypedArgument = System.Reflection.CustomAttributeTypedArgument + // NOTE: for the purposes of remapping the closure of generated types, the FullName is sufficient. // We do _not_ rely on object identity or any other notion of equivalence provided by System.Type // itself. The mscorlib implementations of System.Type equality relations are not suitable: for @@ -221,11 +198,12 @@ module internal ExtensionTyping = // providers can implement wrap-and-filter "views" over existing System.Type clusters without needing // to preserve object identity when presenting the types to the F# compiler. - let providedSystemTypeComparer = - let key (ty: System.Type) = (ty.Assembly.FullName, ty.FullName) - { new IEqualityComparer with - member __.GetHashCode(ty: Type) = hash (key ty) - member __.Equals(ty1: Type, ty2: Type) = (key ty1 = key ty2) } + type ProvidedTypeComparer() = + let key (ty: ProvidedType) = (ty.Assembly.FullName, ty.FullName) + static member val Instance = ProvidedTypeComparer() + interface IEqualityComparer with + member _.GetHashCode(ty: ProvidedType) = hash (key ty) + member _.Equals(ty1: ProvidedType, ty2: ProvidedType) = (key ty1 = key ty2) /// The context used to interpret information in the closure of System.Type, System.MethodInfo and other /// info objects coming from the type provider. @@ -235,9 +213,10 @@ module internal ExtensionTyping = /// /// Laziness is used "to prevent needless computation for every type during remapping". However it /// appears that the laziness likely serves no purpose and could be safely removed. - type ProvidedTypeContext = + and ProvidedTypeContext = | NoEntries - | Entries of Dictionary * Lazy> + // The dictionaries are safe because the ProvidedType with the ProvidedTypeContext are only accessed one thread at a time during type-checking. + | Entries of ConcurrentDictionary * Lazy> static member Empty = NoEntries @@ -246,7 +225,7 @@ module internal ExtensionTyping = member ctxt.GetDictionaries() = match ctxt with | NoEntries -> - Dictionary(providedSystemTypeComparer), Dictionary(providedSystemTypeComparer) + ConcurrentDictionary(ProvidedTypeComparer.Instance), ConcurrentDictionary(ProvidedTypeComparer.Instance) | Entries (lookupILTR, lookupILTCR) -> lookupILTR, lookupILTCR.Force() @@ -271,22 +250,22 @@ module internal ExtensionTyping = match ctxt with | NoEntries -> NoEntries | Entries(d1, d2) -> - Entries(d1, lazy (let dict = new Dictionary(providedSystemTypeComparer) - for KeyValue (st, tcref) in d2.Force() do dict.Add(st, f tcref) + Entries(d1, lazy (let dict = ConcurrentDictionary(ProvidedTypeComparer.Instance) + for KeyValue (st, tcref) in d2.Force() do dict.TryAdd(st, f tcref) |> ignore dict)) - type CustomAttributeData = System.Reflection.CustomAttributeData - type CustomAttributeNamedArgument = System.Reflection.CustomAttributeNamedArgument - type CustomAttributeTypedArgument = System.Reflection.CustomAttributeTypedArgument - - [] - type ProvidedType (x: System.Type, ctxt: ProvidedTypeContext) = + and [] + ProvidedType (x: Type, ctxt: ProvidedTypeContext) = inherit ProvidedMemberInfo(x, ctxt) + let isMeasure = + lazy + x.CustomAttributes + |> Seq.exists (fun a -> a.Constructor.DeclaringType.FullName = typeof.FullName) let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes) interface IProvidedCustomAttributeProvider with - member __.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider - member __.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider - member __.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider + member _.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider + member _.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider + member _.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider // The type provider spec distinguishes between // - calls that can be made on provided types (i.e. types given by ReturnType, ParameterType, and generic argument types) @@ -295,85 +274,94 @@ module internal ExtensionTyping = // Alternatively we could use assertions to enforce this. // Suppress relocation of generated types - member __.IsSuppressRelocate = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 - member __.IsErased = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 - member __.IsGenericType = x.IsGenericType - member __.Namespace = x.Namespace - member __.FullName = x.FullName - member __.IsArray = x.IsArray - member __.Assembly = x.Assembly |> ProvidedAssembly.Create ctxt - member __.GetInterfaces() = x.GetInterfaces() |> ProvidedType.CreateArray ctxt - member __.GetMethods() = x.GetMethods bindingFlags |> ProvidedMethodInfo.CreateArray ctxt - member __.GetEvents() = x.GetEvents bindingFlags |> ProvidedEventInfo.CreateArray ctxt - member __.GetEvent nm = x.GetEvent(nm, bindingFlags) |> ProvidedEventInfo.Create ctxt - member __.GetProperties() = x.GetProperties bindingFlags |> ProvidedPropertyInfo.CreateArray ctxt - member __.GetProperty nm = x.GetProperty(nm, bindingFlags) |> ProvidedPropertyInfo.Create ctxt - member __.GetConstructors() = x.GetConstructors bindingFlags |> ProvidedConstructorInfo.CreateArray ctxt - member __.GetFields() = x.GetFields bindingFlags |> ProvidedFieldInfo.CreateArray ctxt - member __.GetField nm = x.GetField(nm, bindingFlags) |> ProvidedFieldInfo.Create ctxt - member __.GetAllNestedTypes() = x.GetNestedTypes(bindingFlags ||| BindingFlags.NonPublic) |> ProvidedType.CreateArray ctxt - member __.GetNestedTypes() = x.GetNestedTypes bindingFlags |> ProvidedType.CreateArray ctxt + member _.IsSuppressRelocate = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 + member _.IsErased = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 + member _.IsGenericType = x.IsGenericType + member _.Namespace = x.Namespace + member _.FullName = x.FullName + member _.IsArray = x.IsArray + member _.Assembly: ProvidedAssembly = x.Assembly |> ProvidedAssembly.Create + member _.GetInterfaces() = x.GetInterfaces() |> ProvidedType.CreateArray ctxt + member _.GetMethods() = x.GetMethods bindingFlags |> ProvidedMethodInfo.CreateArray ctxt + member _.GetEvents() = x.GetEvents bindingFlags |> ProvidedEventInfo.CreateArray ctxt + member _.GetEvent nm = x.GetEvent(nm, bindingFlags) |> ProvidedEventInfo.Create ctxt + member _.GetProperties() = x.GetProperties bindingFlags |> ProvidedPropertyInfo.CreateArray ctxt + member _.GetProperty nm = x.GetProperty(nm, bindingFlags) |> ProvidedPropertyInfo.Create ctxt + member _.GetConstructors() = x.GetConstructors bindingFlags |> ProvidedConstructorInfo.CreateArray ctxt + member _.GetFields() = x.GetFields bindingFlags |> ProvidedFieldInfo.CreateArray ctxt + member _.GetField nm = x.GetField(nm, bindingFlags) |> ProvidedFieldInfo.Create ctxt + member _.GetAllNestedTypes() = x.GetNestedTypes(bindingFlags ||| BindingFlags.NonPublic) |> ProvidedType.CreateArray ctxt + member _.GetNestedTypes() = x.GetNestedTypes bindingFlags |> ProvidedType.CreateArray ctxt /// Type.GetNestedType(string) can return null if there is no nested type with given name - member __.GetNestedType nm = x.GetNestedType (nm, bindingFlags) |> ProvidedType.Create ctxt + member _.GetNestedType nm = x.GetNestedType (nm, bindingFlags) |> ProvidedType.Create ctxt /// Type.GetGenericTypeDefinition() either returns type or throws exception, null is not permitted - member __.GetGenericTypeDefinition() = x.GetGenericTypeDefinition() |> ProvidedType.CreateWithNullCheck ctxt "GenericTypeDefinition" + member _.GetGenericTypeDefinition() = x.GetGenericTypeDefinition() |> ProvidedType.CreateWithNullCheck ctxt "GenericTypeDefinition" /// Type.BaseType can be null when Type is interface or object - member __.BaseType = x.BaseType |> ProvidedType.Create ctxt - member __.GetStaticParameters(provider: ITypeProvider) = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt + member _.BaseType = x.BaseType |> ProvidedType.Create ctxt + member _.GetStaticParameters(provider: ITypeProvider) = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt /// Type.GetElementType can be null if i.e. Type is not array\pointer\byref type - member __.GetElementType() = x.GetElementType() |> ProvidedType.Create ctxt - member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt - member __.ApplyStaticArguments(provider: ITypeProvider, fullTypePathAfterArguments, staticArgs: obj[]) = + member _.GetElementType() = x.GetElementType() |> ProvidedType.Create ctxt + member _.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt + member _.ApplyStaticArguments(provider: ITypeProvider, fullTypePathAfterArguments, staticArgs: obj[]) = provider.ApplyStaticArguments(x, fullTypePathAfterArguments, staticArgs) |> ProvidedType.Create ctxt - member __.IsVoid = (typeof.Equals x || (x.Namespace = "System" && x.Name = "Void")) - member __.IsGenericParameter = x.IsGenericParameter - member __.IsValueType = x.IsValueType - member __.IsByRef = x.IsByRef - member __.IsPointer = x.IsPointer - member __.IsPublic = x.IsPublic - member __.IsNestedPublic = x.IsNestedPublic - member __.IsEnum = x.IsEnum - member __.IsClass = x.IsClass - member __.IsSealed = x.IsSealed - member __.IsAbstract = x.IsAbstract - member __.IsInterface = x.IsInterface - member __.GetArrayRank() = x.GetArrayRank() - member __.GenericParameterPosition = x.GenericParameterPosition - member __.RawSystemType = x + member _.IsVoid = (typeof.Equals x || (x.Namespace = "System" && x.Name = "Void")) + member _.IsGenericParameter = x.IsGenericParameter + member _.IsValueType = x.IsValueType + member _.IsByRef = x.IsByRef + member _.IsPointer = x.IsPointer + member _.IsPublic = x.IsPublic + member _.IsNestedPublic = x.IsNestedPublic + member _.IsEnum = x.IsEnum + member _.IsClass = x.IsClass + member _.IsMeasure = isMeasure.Value + member _.IsSealed = x.IsSealed + member _.IsAbstract = x.IsAbstract + member _.IsInterface = x.IsInterface + member _.GetArrayRank() = x.GetArrayRank() + member _.GenericParameterPosition = x.GenericParameterPosition + member _.RawSystemType = x /// Type.GetEnumUnderlyingType either returns type or raises exception, null is not permitted - member __.GetEnumUnderlyingType() = + member _.GetEnumUnderlyingType() = x.GetEnumUnderlyingType() - |> ProvidedType.CreateWithNullCheck ctxt "EnumUnderlyingType" + |> ProvidedType.CreateWithNullCheck ctxt "EnumUnderlyingType" + member _.MakePointerType() = ProvidedType.CreateNoContext(x.MakePointerType()) + member _.MakeByRefType() = ProvidedType.CreateNoContext(x.MakeByRefType()) + member _.MakeArrayType() = ProvidedType.CreateNoContext(x.MakeArrayType()) + member _.MakeArrayType rank = ProvidedType.CreateNoContext(x.MakeArrayType(rank)) + member _.MakeGenericType (args: ProvidedType[]) = + let argTypes = args |> Array.map (fun arg -> arg.RawSystemType) + ProvidedType.CreateNoContext(x.MakeGenericType(argTypes)) + member _.AsProvidedVar name = ProvidedVar.Create ctxt (Quotations.Var(name, x)) static member Create ctxt x = match x with null -> null | t -> ProvidedType (t, ctxt) static member CreateWithNullCheck ctxt name x = match x with null -> nullArg name | t -> ProvidedType (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedType.Create ctxt) static member CreateNoContext (x: Type) = ProvidedType.Create ProvidedTypeContext.Empty x - static member Void = ProvidedType.CreateNoContext typeof - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedType as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() - member __.TryGetILTypeRef() = ctxt.TryGetILTypeRef x - member __.TryGetTyconRef() = ctxt.TryGetTyconRef x - member __.Context = ctxt + static member Void = ProvidedType.CreateNoContext typeof + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedType as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() + member _.Context = ctxt + member this.TryGetILTypeRef() = this.Context.TryGetILTypeRef this + member this.TryGetTyconRef() = this.Context.TryGetTyconRef this static member ApplyContext (pt: ProvidedType, ctxt) = ProvidedType(pt.Handle, ctxt) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) and [] IProvidedCustomAttributeProvider = - abstract GetDefinitionLocationAttribute : provider: ITypeProvider -> (string * int * int) option - abstract GetXmlDocAttributes : provider: ITypeProvider -> string[] - abstract GetHasTypeProviderEditorHideMethodsAttribute : provider: ITypeProvider -> bool + abstract GetDefinitionLocationAttribute: provider: ITypeProvider -> (string * int * int) option + abstract GetXmlDocAttributes: provider: ITypeProvider -> string[] + abstract GetHasTypeProviderEditorHideMethodsAttribute: provider: ITypeProvider -> bool abstract GetAttributeConstructorArgs: provider: ITypeProvider * attribName: string -> (obj option list * (string * obj option) list) option and ProvidedCustomAttributeProvider = - static member Create (attributes :(ITypeProvider -> seq)) : IProvidedCustomAttributeProvider = + static member Create (attributes :ITypeProvider -> seq): IProvidedCustomAttributeProvider = let (|Member|_|) (s: string) (x: CustomAttributeNamedArgument) = if x.MemberName = s then Some x.TypedValue else None let (|Arg|_|) (x: CustomAttributeTypedArgument) = match x.Value with null -> None | v -> Some v let findAttribByName tyFullName (a: CustomAttributeData) = (a.Constructor.DeclaringType.FullName = tyFullName) - let findAttrib (ty: System.Type) a = findAttribByName ty.FullName a + let findAttrib (ty: Type) a = findAttribByName ty.FullName a { new IProvidedCustomAttributeProvider with - member __.GetAttributeConstructorArgs (provider, attribName) = + member _.GetAttributeConstructorArgs (provider, attribName) = attributes provider |> Seq.tryFind (findAttribByName attribName) |> Option.map (fun a -> @@ -387,22 +375,22 @@ module internal ExtensionTyping = |> List.map (fun arg -> arg.MemberName, match arg.TypedValue with Arg null -> None | Arg obj -> Some obj | _ -> None) ctorArgs, namedArgs) - member __.GetHasTypeProviderEditorHideMethodsAttribute provider = + member _.GetHasTypeProviderEditorHideMethodsAttribute provider = attributes provider - |> Seq.exists (findAttrib typeof) + |> Seq.exists (findAttrib typeof) - member __.GetDefinitionLocationAttribute provider = + member _.GetDefinitionLocationAttribute provider = attributes provider - |> Seq.tryFind (findAttrib typeof) + |> Seq.tryFind (findAttrib typeof) |> Option.map (fun a -> (defaultArg (a.NamedArguments |> Seq.tryPick (function Member "FilePath" (Arg (:? string as v)) -> Some v | _ -> None)) null, defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Line" (Arg (:? int as v)) -> Some v | _ -> None)) 0, defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Column" (Arg (:? int as v)) -> Some v | _ -> None)) 0)) - member __.GetXmlDocAttributes provider = + member _.GetXmlDocAttributes provider = attributes provider |> Seq.choose (fun a -> - if findAttrib typeof a then + if findAttrib typeof a then match a.ConstructorArguments |> Seq.toList with | [ Arg(:? string as s) ] -> Some s | _ -> None @@ -411,73 +399,73 @@ module internal ExtensionTyping = |> Seq.toArray } and [] - ProvidedMemberInfo (x: System.Reflection.MemberInfo, ctxt) = + ProvidedMemberInfo (x: MemberInfo, ctxt) = let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes) - member __.Name = x.Name + member _.Name = x.Name /// DeclaringType can be null if MemberInfo belongs to Module, not to Type - member __.DeclaringType = ProvidedType.Create ctxt x.DeclaringType + member _.DeclaringType = ProvidedType.Create ctxt x.DeclaringType interface IProvidedCustomAttributeProvider with - member __.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider - member __.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider - member __.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider - member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName) + member _.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider + member _.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider + member _.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider + member _.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName) and [] - ProvidedParameterInfo (x: System.Reflection.ParameterInfo, ctxt) = + ProvidedParameterInfo (x: ParameterInfo, ctxt) = let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes) - member __.Name = x.Name - member __.IsOut = x.IsOut - member __.IsIn = x.IsIn - member __.IsOptional = x.IsOptional - member __.RawDefaultValue = x.RawDefaultValue - member __.HasDefaultValue = x.Attributes.HasFlag(System.Reflection.ParameterAttributes.HasDefault) + member _.Name = x.Name + member _.IsOut = x.IsOut + member _.IsIn = x.IsIn + member _.IsOptional = x.IsOptional + member _.RawDefaultValue = x.RawDefaultValue + member _.HasDefaultValue = x.Attributes.HasFlag(ParameterAttributes.HasDefault) /// ParameterInfo.ParameterType cannot be null - member __.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType + member _.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType static member Create ctxt x = match x with null -> null | t -> ProvidedParameterInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedParameterInfo.Create ctxt) // TODO null wrong? interface IProvidedCustomAttributeProvider with - member __.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider - member __.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider - member __.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider - member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName) - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedParameterInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + member _.GetHasTypeProviderEditorHideMethodsAttribute provider = provide().GetHasTypeProviderEditorHideMethodsAttribute provider + member _.GetDefinitionLocationAttribute provider = provide().GetDefinitionLocationAttribute provider + member _.GetXmlDocAttributes provider = provide().GetXmlDocAttributes provider + member _.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName) + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedParameterInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() and [] - ProvidedAssembly (x: System.Reflection.Assembly, _ctxt) = - member __.GetName() = x.GetName() - member __.FullName = x.FullName - member __.GetManifestModuleContents(provider: ITypeProvider) = provider.GetGeneratedAssemblyContents x - static member Create ctxt x = match x with null -> null | t -> ProvidedAssembly (t, ctxt) - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedAssembly as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + ProvidedAssembly (x: Assembly) = + member _.GetName() = x.GetName() + member _.FullName = x.FullName + member _.GetManifestModuleContents(provider: ITypeProvider) = provider.GetGeneratedAssemblyContents x + static member Create (x: Assembly) = match x with null -> null | t -> ProvidedAssembly t + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedAssembly as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() and [] - ProvidedMethodBase (x: System.Reflection.MethodBase, ctxt) = + ProvidedMethodBase (x: MethodBase, ctxt) = inherit ProvidedMemberInfo(x, ctxt) - member __.Context = ctxt - member __.IsGenericMethod = x.IsGenericMethod - member __.IsStatic = x.IsStatic - member __.IsFamily = x.IsFamily - member __.IsFamilyOrAssembly = x.IsFamilyOrAssembly - member __.IsFamilyAndAssembly = x.IsFamilyAndAssembly - member __.IsVirtual = x.IsVirtual - member __.IsFinal = x.IsFinal - member __.IsPublic = x.IsPublic - member __.IsAbstract = x.IsAbstract - member __.IsHideBySig = x.IsHideBySig - member __.IsConstructor = x.IsConstructor - member __.GetParameters() = x.GetParameters() |> ProvidedParameterInfo.CreateArray ctxt - member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt - member __.Handle = x + member _.Context = ctxt + member _.IsGenericMethod = x.IsGenericMethod + member _.IsStatic = x.IsStatic + member _.IsFamily = x.IsFamily + member _.IsFamilyOrAssembly = x.IsFamilyOrAssembly + member _.IsFamilyAndAssembly = x.IsFamilyAndAssembly + member _.IsVirtual = x.IsVirtual + member _.IsFinal = x.IsFinal + member _.IsPublic = x.IsPublic + member _.IsAbstract = x.IsAbstract + member _.IsHideBySig = x.IsHideBySig + member _.IsConstructor = x.IsConstructor + member _.GetParameters() = x.GetParameters() |> ProvidedParameterInfo.CreateArray ctxt + member _.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt + member _.Handle = x static member TaintedGetHashCode (x: Tainted) = Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) - member __.GetStaticParametersForMethod(provider: ITypeProvider) = + member _.GetStaticParametersForMethod(provider: ITypeProvider) = let bindingFlags = BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.Public let staticParams = @@ -485,17 +473,20 @@ module internal ExtensionTyping = | :? ITypeProvider2 as itp2 -> itp2.GetStaticParametersForMethod x | _ -> - // To allow a type provider to depend only on FSharp.Core 4.3.0.0, it can alternatively implement an appropriate method called GetStaticParametersForMethod - let meth = provider.GetType().GetMethod( "GetStaticParametersForMethod", bindingFlags, null, [| typeof |], null) + // To allow a type provider to depend only on FSharp.Core 4.3.0.0, it can alternatively + // implement an appropriate method called GetStaticParametersForMethod + let meth = + provider.GetType().GetMethod( "GetStaticParametersForMethod", bindingFlags, null, + [| typeof |], null) if isNull meth then [| |] else let paramsAsObj = try meth.Invoke(provider, bindingFlags ||| BindingFlags.InvokeMethod, null, [| box x |], null) with err -> raise (StripException (StripException err)) - paramsAsObj :?> System.Reflection.ParameterInfo[] + paramsAsObj :?> ParameterInfo[] staticParams |> ProvidedParameterInfo.CreateArray ctxt - member __.ApplyStaticArgumentsForMethod(provider: ITypeProvider, fullNameAfterArguments: string, staticArgs: obj[]) = + member _.ApplyStaticArgumentsForMethod(provider: ITypeProvider, fullNameAfterArguments: string, staticArgs: obj[]) = let bindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.InvokeMethod let mb = @@ -503,8 +494,12 @@ module internal ExtensionTyping = | :? ITypeProvider2 as itp2 -> itp2.ApplyStaticArgumentsForMethod(x, fullNameAfterArguments, staticArgs) | _ -> + // To allow a type provider to depend only on FSharp.Core 4.3.0.0, it can alternatively implement a method called GetStaticParametersForMethod - let meth = provider.GetType().GetMethod( "ApplyStaticArgumentsForMethod", bindingFlags, null, [| typeof; typeof; typeof |], null) + let meth = + provider.GetType().GetMethod( "ApplyStaticArgumentsForMethod", bindingFlags, null, + [| typeof; typeof; typeof |], null) + match meth with | null -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) | _ -> @@ -513,265 +508,323 @@ module internal ExtensionTyping = with err -> raise (StripException (StripException err)) match mbAsObj with - | :? System.Reflection.MethodBase as mb -> mb + | :? MethodBase as mb -> mb | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) match mb with - | :? System.Reflection.MethodInfo as mi -> (mi |> ProvidedMethodInfo.Create ctxt : ProvidedMethodInfo) :> ProvidedMethodBase - | :? System.Reflection.ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.Create ctxt : ProvidedConstructorInfo) :> ProvidedMethodBase + | :? MethodInfo as mi -> (mi |> ProvidedMethodInfo.Create ctxt: ProvidedMethodInfo) :> ProvidedMethodBase + | :? ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.Create ctxt: ProvidedConstructorInfo) :> ProvidedMethodBase | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented()) and [] - ProvidedFieldInfo (x: System.Reflection.FieldInfo, ctxt) = + ProvidedFieldInfo (x: FieldInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) static member Create ctxt x = match x with null -> null | t -> ProvidedFieldInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedFieldInfo.Create ctxt) - member __.IsInitOnly = x.IsInitOnly - member __.IsStatic = x.IsStatic - member __.IsSpecialName = x.IsSpecialName - member __.IsLiteral = x.IsLiteral - member __.GetRawConstantValue() = x.GetRawConstantValue() + member _.IsInitOnly = x.IsInitOnly + member _.IsStatic = x.IsStatic + member _.IsSpecialName = x.IsSpecialName + member _.IsLiteral = x.IsLiteral + member _.GetRawConstantValue() = x.GetRawConstantValue() /// FieldInfo.FieldType cannot be null - member __.FieldType = x.FieldType |> ProvidedType.CreateWithNullCheck ctxt "FieldType" - member __.Handle = x - member __.IsPublic = x.IsPublic - member __.IsFamily = x.IsFamily - member __.IsPrivate = x.IsPrivate - member __.IsFamilyOrAssembly = x.IsFamilyOrAssembly - member __.IsFamilyAndAssembly = x.IsFamilyAndAssembly - override __.Equals y = assert false; match y with :? ProvidedFieldInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + member _.FieldType = x.FieldType |> ProvidedType.CreateWithNullCheck ctxt "FieldType" + member _.Handle = x + member _.IsPublic = x.IsPublic + member _.IsFamily = x.IsFamily + member _.IsPrivate = x.IsPrivate + member _.IsFamilyOrAssembly = x.IsFamilyOrAssembly + member _.IsFamilyAndAssembly = x.IsFamilyAndAssembly + override _.Equals y = assert false; match y with :? ProvidedFieldInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) and [] - ProvidedMethodInfo (x: System.Reflection.MethodInfo, ctxt) = + ProvidedMethodInfo (x: MethodInfo, ctxt) = inherit ProvidedMethodBase(x, ctxt) - member __.ReturnType = x.ReturnType |> ProvidedType.CreateWithNullCheck ctxt "ReturnType" + member _.ReturnType = x.ReturnType |> ProvidedType.CreateWithNullCheck ctxt "ReturnType" static member Create ctxt x = match x with null -> null | t -> ProvidedMethodInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedMethodInfo.Create ctxt) - member __.Handle = x - member __.MetadataToken = x.MetadataToken - override __.Equals y = assert false; match y with :? ProvidedMethodInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + member _.Handle = x + member _.MetadataToken = x.MetadataToken + override _.Equals y = assert false; match y with :? ProvidedMethodInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() and [] - ProvidedPropertyInfo (x: System.Reflection.PropertyInfo, ctxt) = + ProvidedPropertyInfo (x: PropertyInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) - member __.GetGetMethod() = x.GetGetMethod() |> ProvidedMethodInfo.Create ctxt - member __.GetSetMethod() = x.GetSetMethod() |> ProvidedMethodInfo.Create ctxt - member __.CanRead = x.CanRead - member __.CanWrite = x.CanWrite - member __.GetIndexParameters() = x.GetIndexParameters() |> ProvidedParameterInfo.CreateArray ctxt + member _.GetGetMethod() = x.GetGetMethod() |> ProvidedMethodInfo.Create ctxt + member _.GetSetMethod() = x.GetSetMethod() |> ProvidedMethodInfo.Create ctxt + member _.CanRead = x.CanRead + member _.CanWrite = x.CanWrite + member _.GetIndexParameters() = x.GetIndexParameters() |> ProvidedParameterInfo.CreateArray ctxt /// PropertyInfo.PropertyType cannot be null - member __.PropertyType = x.PropertyType |> ProvidedType.CreateWithNullCheck ctxt "PropertyType" + member _.PropertyType = x.PropertyType |> ProvidedType.CreateWithNullCheck ctxt "PropertyType" static member Create ctxt x = match x with null -> null | t -> ProvidedPropertyInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedPropertyInfo.Create ctxt) - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedPropertyInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedPropertyInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() static member TaintedGetHashCode (x: Tainted) = Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) and [] - ProvidedEventInfo (x: System.Reflection.EventInfo, ctxt) = + ProvidedEventInfo (x: EventInfo, ctxt) = inherit ProvidedMemberInfo(x, ctxt) - member __.GetAddMethod() = x.GetAddMethod() |> ProvidedMethodInfo.Create ctxt - member __.GetRemoveMethod() = x.GetRemoveMethod() |> ProvidedMethodInfo.Create ctxt + member _.GetAddMethod() = x.GetAddMethod() |> ProvidedMethodInfo.Create ctxt + member _.GetRemoveMethod() = x.GetRemoveMethod() |> ProvidedMethodInfo.Create ctxt /// EventInfo.EventHandlerType cannot be null - member __.EventHandlerType = x.EventHandlerType |> ProvidedType.CreateWithNullCheck ctxt "EventHandlerType" + member _.EventHandlerType = x.EventHandlerType |> ProvidedType.CreateWithNullCheck ctxt "EventHandlerType" static member Create ctxt x = match x with null -> null | t -> ProvidedEventInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedEventInfo.Create ctxt) - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedEventInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedEventInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() static member TaintedGetHashCode (x: Tainted) = Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) and [] - ProvidedConstructorInfo (x: System.Reflection.ConstructorInfo, ctxt) = + ProvidedConstructorInfo (x: ConstructorInfo, ctxt) = inherit ProvidedMethodBase(x, ctxt) static member Create ctxt x = match x with null -> null | t -> ProvidedConstructorInfo (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedConstructorInfo.Create ctxt) - member __.Handle = x - override __.Equals y = assert false; match y with :? ProvidedConstructorInfo as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = assert false; x.GetHashCode() - - [] - type ProvidedExpr (x: Quotations.Expr, ctxt) = - member __.Type = x.Type |> ProvidedType.Create ctxt - member __.Handle = x - member __.Context = ctxt - member __.UnderlyingExpressionString = x.ToString() + member _.Handle = x + override _.Equals y = assert false; match y with :? ProvidedConstructorInfo as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = assert false; x.GetHashCode() + + and ProvidedExprType = + | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr[] +#if PROVIDED_ADDRESS_OF + | ProvidedAddressOfExpr of ProvidedExpr +#endif + | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr[] + | ProvidedWhileLoopExpr of ProvidedExpr * ProvidedExpr + | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar[] * ProvidedExpr + | ProvidedForIntegerRangeLoopExpr of ProvidedVar * ProvidedExpr * ProvidedExpr * ProvidedExpr + | ProvidedSequentialExpr of ProvidedExpr * ProvidedExpr + | ProvidedTryWithExpr of ProvidedExpr * ProvidedVar * ProvidedExpr * ProvidedVar * ProvidedExpr + | ProvidedTryFinallyExpr of ProvidedExpr * ProvidedExpr + | ProvidedLambdaExpr of ProvidedVar * ProvidedExpr + | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[] + | ProvidedConstantExpr of obj * ProvidedType + | ProvidedDefaultExpr of ProvidedType + | ProvidedNewTupleExpr of ProvidedExpr[] + | ProvidedTupleGetExpr of ProvidedExpr * int + | ProvidedTypeAsExpr of ProvidedExpr * ProvidedType + | ProvidedTypeTestExpr of ProvidedExpr * ProvidedType + | ProvidedLetExpr of ProvidedVar * ProvidedExpr * ProvidedExpr + | ProvidedVarSetExpr of ProvidedVar * ProvidedExpr + | ProvidedIfThenElseExpr of ProvidedExpr * ProvidedExpr * ProvidedExpr + | ProvidedVarExpr of ProvidedVar + + and [] + ProvidedExpr (x: Quotations.Expr, ctxt) = + member _.Type = x.Type |> ProvidedType.Create ctxt + member _.Handle = x + member _.Context = ctxt + member _.UnderlyingExpressionString = x.ToString() + member _.GetExprType() = + match x with + | Quotations.Patterns.NewObject(ctor, args) -> + Some (ProvidedNewObjectExpr (ProvidedConstructorInfo.Create ctxt ctor, [| for a in args -> ProvidedExpr.Create ctxt a |])) + | Quotations.Patterns.WhileLoop(guardExpr, bodyExpr) -> + Some (ProvidedWhileLoopExpr (ProvidedExpr.Create ctxt guardExpr, ProvidedExpr.Create ctxt bodyExpr)) + | Quotations.Patterns.NewDelegate(ty, vs, expr) -> + Some (ProvidedNewDelegateExpr(ProvidedType.Create ctxt ty, ProvidedVar.CreateArray ctxt (List.toArray vs), ProvidedExpr.Create ctxt expr)) + | Quotations.Patterns.Call(objOpt, meth, args) -> + Some (ProvidedCallExpr((match objOpt with None -> None | Some obj -> Some (ProvidedExpr.Create ctxt obj)), + ProvidedMethodInfo.Create ctxt meth, [| for a in args -> ProvidedExpr.Create ctxt a |])) + | Quotations.Patterns.DefaultValue ty -> + Some (ProvidedDefaultExpr (ProvidedType.Create ctxt ty)) + | Quotations.Patterns.Value(obj, ty) -> + Some (ProvidedConstantExpr (obj, ProvidedType.Create ctxt ty)) + | Quotations.Patterns.Coerce(arg, ty) -> + Some (ProvidedTypeAsExpr (ProvidedExpr.Create ctxt arg, ProvidedType.Create ctxt ty)) + | Quotations.Patterns.NewTuple args -> + Some (ProvidedNewTupleExpr(ProvidedExpr.CreateArray ctxt (Array.ofList args))) + | Quotations.Patterns.TupleGet(arg, n) -> + Some (ProvidedTupleGetExpr (ProvidedExpr.Create ctxt arg, n)) + | Quotations.Patterns.NewArray(ty, args) -> + Some (ProvidedNewArrayExpr(ProvidedType.Create ctxt ty, ProvidedExpr.CreateArray ctxt (Array.ofList args))) + | Quotations.Patterns.Sequential(e1, e2) -> + Some (ProvidedSequentialExpr(ProvidedExpr.Create ctxt e1, ProvidedExpr.Create ctxt e2)) + | Quotations.Patterns.Lambda(v, body) -> + Some (ProvidedLambdaExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt body)) + | Quotations.Patterns.TryFinally(b1, b2) -> + Some (ProvidedTryFinallyExpr (ProvidedExpr.Create ctxt b1, ProvidedExpr.Create ctxt b2)) + | Quotations.Patterns.TryWith(b, v1, e1, v2, e2) -> + Some (ProvidedTryWithExpr (ProvidedExpr.Create ctxt b, ProvidedVar.Create ctxt v1, ProvidedExpr.Create ctxt e1, ProvidedVar.Create ctxt v2, ProvidedExpr.Create ctxt e2)) +#if PROVIDED_ADDRESS_OF + | Quotations.Patterns.AddressOf e -> Some (ProvidedAddressOfExpr (ProvidedExpr.Create ctxt e)) +#endif + | Quotations.Patterns.TypeTest(e, ty) -> + Some (ProvidedTypeTestExpr(ProvidedExpr.Create ctxt e, ProvidedType.Create ctxt ty)) + | Quotations.Patterns.Let(v, e, b) -> + Some (ProvidedLetExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e, ProvidedExpr.Create ctxt b)) + | Quotations.Patterns.ForIntegerRangeLoop (v, e1, e2, e3) -> + Some (ProvidedForIntegerRangeLoopExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e1, ProvidedExpr.Create ctxt e2, ProvidedExpr.Create ctxt e3)) + | Quotations.Patterns.VarSet(v, e) -> + Some (ProvidedVarSetExpr (ProvidedVar.Create ctxt v, ProvidedExpr.Create ctxt e)) + | Quotations.Patterns.IfThenElse(g, t, e) -> + Some (ProvidedIfThenElseExpr (ProvidedExpr.Create ctxt g, ProvidedExpr.Create ctxt t, ProvidedExpr.Create ctxt e)) + | Quotations.Patterns.Var v -> + Some (ProvidedVarExpr (ProvidedVar.Create ctxt v)) + | _ -> None static member Create ctxt t = match box t with null -> null | _ -> ProvidedExpr (t, ctxt) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedExpr.Create ctxt) - override __.Equals y = match y with :? ProvidedExpr as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = x.GetHashCode() - - [] - type ProvidedVar (x: Quotations.Var, ctxt) = - member __.Type = x.Type |> ProvidedType.Create ctxt - member __.Name = x.Name - member __.IsMutable = x.IsMutable - member __.Handle = x - member __.Context = ctxt + override _.Equals y = match y with :? ProvidedExpr as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = x.GetHashCode() + + and [] + ProvidedVar (x: Quotations.Var, ctxt) = + member _.Type = x.Type |> ProvidedType.Create ctxt + member _.Name = x.Name + member _.IsMutable = x.IsMutable + member _.Handle = x + member _.Context = ctxt static member Create ctxt t = match box t with null -> null | _ -> ProvidedVar (t, ctxt) - static member Fresh (nm, ty: ProvidedType) = ProvidedVar.Create ty.Context (new Quotations.Var(nm, ty.Handle)) static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedVar.Create ctxt) - override __.Equals y = match y with :? ProvidedVar as y -> x.Equals y.Handle | _ -> false - override __.GetHashCode() = x.GetHashCode() - - - /// Detect a provided new-object expression - let (|ProvidedNewObjectExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.NewObject(ctor, args) -> - Some (ProvidedConstructorInfo.Create x.Context ctor, [| for a in args -> ProvidedExpr.Create x.Context a |]) - | _ -> None - - /// Detect a provided while-loop expression - let (|ProvidedWhileLoopExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.WhileLoop(guardExpr, bodyExpr) -> - Some (ProvidedExpr.Create x.Context guardExpr, ProvidedExpr.Create x.Context bodyExpr) - | _ -> None - - /// Detect a provided new-delegate expression - let (|ProvidedNewDelegateExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.NewDelegate(ty, vs, expr) -> - Some (ProvidedType.Create x.Context ty, ProvidedVar.CreateArray x.Context (List.toArray vs), ProvidedExpr.Create x.Context expr) - | _ -> None - - /// Detect a provided call expression - let (|ProvidedCallExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Call(objOpt, meth, args) -> - Some ((match objOpt with None -> None | Some obj -> Some (ProvidedExpr.Create x.Context obj)), - ProvidedMethodInfo.Create x.Context meth, - [| for a in args -> ProvidedExpr.Create x.Context a |]) - | _ -> None - - /// Detect a provided default-value expression - let (|ProvidedDefaultExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.DefaultValue ty -> Some (ProvidedType.Create x.Context ty) - | _ -> None - - /// Detect a provided constant expression - let (|ProvidedConstantExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Value(obj, ty) -> Some (obj, ProvidedType.Create x.Context ty) - | _ -> None - - /// Detect a provided type-as expression - let (|ProvidedTypeAsExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Coerce(arg, ty) -> Some (ProvidedExpr.Create x.Context arg, ProvidedType.Create x.Context ty) - | _ -> None - - /// Detect a provided new-tuple expression - let (|ProvidedNewTupleExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.NewTuple args -> Some (ProvidedExpr.CreateArray x.Context (Array.ofList args)) - | _ -> None - - /// Detect a provided tuple-get expression - let (|ProvidedTupleGetExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.TupleGet(arg, n) -> Some (ProvidedExpr.Create x.Context arg, n) - | _ -> None - - /// Detect a provided new-array expression - let (|ProvidedNewArrayExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.NewArray(ty, args) -> Some (ProvidedType.Create x.Context ty, ProvidedExpr.CreateArray x.Context (Array.ofList args)) - | _ -> None - - /// Detect a provided sequential expression - let (|ProvidedSequentialExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Sequential(e1, e2) -> Some (ProvidedExpr.Create x.Context e1, ProvidedExpr.Create x.Context e2) - | _ -> None - - /// Detect a provided lambda expression - let (|ProvidedLambdaExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Lambda(v, body) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context body) - | _ -> None - - /// Detect a provided try/finally expression - let (|ProvidedTryFinallyExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.TryFinally(b1, b2) -> Some (ProvidedExpr.Create x.Context b1, ProvidedExpr.Create x.Context b2) - | _ -> None - - /// Detect a provided try/with expression - let (|ProvidedTryWithExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.TryWith(b, v1, e1, v2, e2) -> Some (ProvidedExpr.Create x.Context b, ProvidedVar.Create x.Context v1, ProvidedExpr.Create x.Context e1, ProvidedVar.Create x.Context v2, ProvidedExpr.Create x.Context e2) - | _ -> None - -#if PROVIDED_ADDRESS_OF - let (|ProvidedAddressOfExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.AddressOf e -> Some (ProvidedExpr.Create x.Context e) - | _ -> None -#endif + override _.Equals y = match y with :? ProvidedVar as y -> x.Equals y.Handle | _ -> false + override _.GetHashCode() = x.GetHashCode() + + [] + module Shim = + + type TypeProvidersInstantiationContext = + { RuntimeAssemblyFilename: string + DesignerAssemblyName: string + ResolutionEnvironment: ResolutionEnvironment + IsInvalidationSupported: bool + IsInteractive: bool + SystemRuntimeContainsType: string -> bool + SystemRuntimeAssemblyVersion: Version + CompilerToolsPath: string list + LogError: TypeProviderError -> unit + Range: range } + + type IExtensionTypingProvider = + abstract InstantiateTypeProvidersOfAssembly: TypeProvidersInstantiationContext -> ITypeProvider list + abstract GetProvidedTypes: pn: IProvidedNamespace -> ProvidedType[] + abstract ResolveTypeName: pn: IProvidedNamespace * typeName: string -> ProvidedType + abstract GetInvokerExpression: provider: ITypeProvider * methodBase: ProvidedMethodBase * paramExprs: ProvidedVar[] -> ProvidedExpr + abstract DisplayNameOfTypeProvider: typeProvider: ITypeProvider * fullName: bool -> string + + [] + type DefaultExtensionTypingProvider() = + interface IExtensionTypingProvider with + member this.InstantiateTypeProvidersOfAssembly + ({ RuntimeAssemblyFilename = runtimeAssemblyFilename + DesignerAssemblyName = designerAssemblyName + ResolutionEnvironment = resolutionEnvironment + IsInvalidationSupported = isInvalidationSupported + IsInteractive = isInteractive + SystemRuntimeContainsType = systemRuntimeContainsType + SystemRuntimeAssemblyVersion = systemRuntimeAssemblyVersion + CompilerToolsPath = compilerToolsPath + LogError = logError + Range = m }) = + + try + let designTimeAssemblyName = + try + if designerAssemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then + Some (AssemblyName (Path.GetFileNameWithoutExtension designerAssemblyName)) + else + Some (AssemblyName designerAssemblyName) + with :? ArgumentException -> + errorR(Error(FSComp.SR.etInvalidTypeProviderAssemblyName(runtimeAssemblyFilename, designerAssemblyName), m)) + None + + [ match designTimeAssemblyName, resolutionEnvironment.outputFile with + // Check if the attribute is pointing to the file being compiled, in which case ignore it + // This checks seems like legacy but is included for compat. + | Some designTimeAssemblyName, Some path + when String.Compare(designTimeAssemblyName.Name, Path.GetFileNameWithoutExtension path, StringComparison.OrdinalIgnoreCase) = 0 -> + () + + | Some _, _ -> + let provImplTypes = GetTypeProviderImplementationTypes (runtimeAssemblyFilename, designerAssemblyName, m, compilerToolsPath) + for t in provImplTypes do + let resolver = + CreateTypeProvider (t, runtimeAssemblyFilename, resolutionEnvironment, isInvalidationSupported, + isInteractive, systemRuntimeContainsType, systemRuntimeAssemblyVersion, m) + match box resolver with + | null -> () + | _ -> yield resolver + + | None, _ -> + () ] + + with :? TypeProviderError as tpe -> + logError tpe + [] + + member this.GetProvidedTypes(pn: IProvidedNamespace) = + let types = pn.GetTypes() + if isNull types then null + else types |> Array.map ProvidedType.CreateNoContext + + member this.ResolveTypeName(pn: IProvidedNamespace, typeName: string) = + pn.ResolveTypeName typeName |> ProvidedType.CreateNoContext + + member this.GetInvokerExpression(provider: ITypeProvider, methodBase: ProvidedMethodBase, paramExprs: ProvidedVar[]) = + provider.GetInvokerExpression(methodBase.Handle, [| for p in paramExprs -> Quotations.Expr.Var (p.Handle) |]) |> ProvidedExpr.Create methodBase.Context + + member this.DisplayNameOfTypeProvider(tp: ITypeProvider, fullName: bool) = + if fullName then tp.GetType().FullName else tp.GetType().Name + + let mutable ExtensionTypingProvider = DefaultExtensionTypingProvider() :> IExtensionTypingProvider + + let internal defaultLogger (tpe: TypeProviderError) = + tpe.Iter(fun e -> errorR(Error((e.Number, e.ContextualErrorMessage), e.Range))) - /// Detect a provided type-test expression - let (|ProvidedTypeTestExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.TypeTest(e, ty) -> Some (ProvidedExpr.Create x.Context e, ProvidedType.Create x.Context ty) - | _ -> None - - /// Detect a provided 'let' expression - let (|ProvidedLetExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Let(v, e, b) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e, ProvidedExpr.Create x.Context b) - | _ -> None - - - /// Detect a provided expression which is a for-loop over integers - let (|ProvidedForIntegerRangeLoopExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.ForIntegerRangeLoop (v, e1, e2, e3) -> - Some (ProvidedVar.Create x.Context v, - ProvidedExpr.Create x.Context e1, - ProvidedExpr.Create x.Context e2, - ProvidedExpr.Create x.Context e3) - | _ -> None - - /// Detect a provided 'set variable' expression - let (|ProvidedVarSetExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.VarSet(v, e) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e) - | _ -> None - - /// Detect a provided 'IfThenElse' expression - let (|ProvidedIfThenElseExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.IfThenElse(g, t, e) -> Some (ProvidedExpr.Create x.Context g, ProvidedExpr.Create x.Context t, ProvidedExpr.Create x.Context e) - | _ -> None - - /// Detect a provided 'Var' expression - let (|ProvidedVarExpr|_|) (x: ProvidedExpr) = - match x.Handle with - | Quotations.Patterns.Var v -> Some (ProvidedVar.Create x.Context v) - | _ -> None + let GetTypeProvidersOfAssembly + (runtimeAssemblyFilename: string, + ilScopeRefOfRuntimeAssembly: ILScopeRef, + designTimeName: string, + resolutionEnvironment: ResolutionEnvironment, + isInvalidationSupported: bool, + isInteractive: bool, + systemRuntimeContainsType : string -> bool, + systemRuntimeAssemblyVersion : Version, + compilerToolPaths: string list, + m: range) = + + let providers = + ExtensionTypingProvider.InstantiateTypeProvidersOfAssembly + { RuntimeAssemblyFilename = runtimeAssemblyFilename; + DesignerAssemblyName = designTimeName; + ResolutionEnvironment = resolutionEnvironment; + IsInvalidationSupported = isInvalidationSupported; + IsInteractive = isInteractive; + SystemRuntimeContainsType =systemRuntimeContainsType; + SystemRuntimeAssemblyVersion = systemRuntimeAssemblyVersion; + CompilerToolsPath = compilerToolPaths; + LogError = Shim.defaultLogger; + Range = m } + + Tainted<_>.CreateAll (providers |> List.map (fun p -> p, ilScopeRefOfRuntimeAssembly, ExtensionTypingProvider.DisplayNameOfTypeProvider(p, true))) /// Get the provided invoker expression for a particular use of a method. let GetInvokerExpression (provider: ITypeProvider, methodBase: ProvidedMethodBase, paramExprs: ProvidedVar[]) = - provider.GetInvokerExpression(methodBase.Handle, [| for p in paramExprs -> Quotations.Expr.Var (p.Handle) |]) |> ProvidedExpr.Create methodBase.Context + ExtensionTypingProvider.GetInvokerExpression(provider, methodBase, paramExprs) + + /// Get all provided types from provided namespace + let GetProvidedTypes (pn: IProvidedNamespace) = + ExtensionTypingProvider.GetProvidedTypes(pn) + + // Get the string to show for the name of a type provider + let DisplayNameOfTypeProvider (resolver: Tainted, m: range) = + resolver.PUntaint((fun tp -> ExtensionTypingProvider.DisplayNameOfTypeProvider(tp, false)), m) /// Compute the Name or FullName property of a provided type, reporting appropriate errors let CheckAndComputeProvidedNameProperty(m, st: Tainted, proj, propertyString) = @@ -795,7 +848,7 @@ module internal ExtensionTyping = /// Verify that a provided type has the expected name - let ValidateExpectedName m expectedPath expectedName (st : Tainted) = + let ValidateExpectedName m expectedPath expectedName (st: Tainted) = let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name") if name <> expectedName then raise (TypeProviderError(FSComp.SR.etProvidedTypeHasUnexpectedName(expectedName, name), st.TypeProviderDesignation, m)) @@ -817,7 +870,7 @@ module internal ExtensionTyping = errorR(Error(FSComp.SR.etProvidedTypeHasUnexpectedPath(expectedPath, path), m)) /// Eagerly validate a range of conditions on a provided type, after static instantiation (if any) has occurred - let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, expectedPath : string[], expectedName : string) = + let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, expectedPath: string[], expectedName: string) = // Do all the calling into st up front with recovery let fullName, namespaceName, usedMembers = let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name") @@ -825,7 +878,7 @@ module internal ExtensionTyping = let fullName = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal ValidateExpectedName m expectedPath expectedName st // Must be able to call (GetMethods|GetEvents|GetProperties|GetNestedTypes|GetConstructors)(bindingFlags). - let usedMembers : Tainted[] = + let usedMembers: Tainted[] = // These are the members the compiler will actually use [| for x in TryTypeMemberArray(st, fullName, "GetMethods", m, fun st -> st.GetMethods()) -> x.Coerce m for x in TryTypeMemberArray(st, fullName, "GetEvents", m, fun st -> st.GetEvents()) -> x.Coerce m @@ -854,13 +907,16 @@ module internal ExtensionTyping = let miDeclaringType = TryMemberMember(mi, fullName, memberName, "DeclaringType", m, ProvidedType.CreateNoContext(typeof), fun mi -> mi.DeclaringType) match miDeclaringType with // Generated nested types may have null DeclaringType - | Tainted.Null when (mi.OfType().IsSome) -> () + | Tainted.Null when mi.OfType().IsSome -> () | Tainted.Null -> errorR(Error(FSComp.SR.etNullMemberDeclaringType(fullName, memberName), m)) | _ -> let miDeclaringTypeFullName = - TryMemberMember(miDeclaringType, fullName, memberName, "FullName", m, "invalid declaring type full name", fun miDeclaringType -> miDeclaringType.FullName) + TryMemberMember (miDeclaringType, fullName, memberName, "FullName", m, + "invalid declaring type full name", + fun miDeclaringType -> miDeclaringType.FullName) |> unmarshal + if not (ProvidedType.TaintedEquals (st, miDeclaringType)) then errorR(Error(FSComp.SR.etNullMemberDeclaringTypeDifferentFromProvidedType(fullName, memberName, miDeclaringTypeFullName), m)) @@ -919,7 +975,7 @@ module internal ExtensionTyping = | None -> errorR(Error(FSComp.SR.etUnsupportedMemberKind(memberName, fullName), m)) - let ValidateProvidedTypeDefinition(m, st: Tainted, expectedPath : string[], expectedName : string) = + let ValidateProvidedTypeDefinition(m, st: Tainted, expectedPath: string[], expectedName: string) = // Validate the Name, Namespace and FullName properties let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name") @@ -953,7 +1009,7 @@ module internal ExtensionTyping = // Check if the provided namespace name is an exact match of the required namespace name if displayName = providedNamespaceName then - let resolvedType = providedNamespace.PApply((fun providedNamespace -> ProvidedType.CreateNoContext(providedNamespace.ResolveTypeName typeName)), range=m) + let resolvedType = providedNamespace.PApply((fun providedNamespace -> ExtensionTypingProvider.ResolveTypeName(providedNamespace, typeName)), range=m) match resolvedType with | Tainted.Null -> None | result -> @@ -1057,7 +1113,7 @@ module internal ExtensionTyping = /// Given a mangled name reference to a non-nested provided type, resolve it. /// If necessary, demangle its static arguments before applying them. - let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: string[], typeLogicalName: string, m: range) = + let TryLinkProvidedType(resolver: Tainted, moduleOrNamespace: string[], typeLogicalName: string, range: range) = // Demangle the static parameters let typeName, argNamesAndValues = @@ -1074,23 +1130,24 @@ module internal ExtensionTyping = | _ -> // Take the static arguments (as strings, taken from the text in the reference we're relinking), // and convert them to objects of the appropriate type, based on the expected kind. - let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, resolver) -> typeBeforeArguments.GetStaticParameters resolver), range=range0) + let staticParameters = + typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, resolver) -> + typeBeforeArguments.GetStaticParameters resolver),range=range0) - let staticParameters = staticParameters.PApplyArray(id, "", m) + let staticParameters = staticParameters.PApplyArray(id, "", range) let staticArgs = staticParameters |> Array.map (fun sp -> - let typeBeforeArgumentsName = typeBeforeArguments.PUntaint ((fun st -> st.Name), m) - let spName = sp.PUntaint ((fun sp -> sp.Name), m) + let typeBeforeArgumentsName = typeBeforeArguments.PUntaint ((fun st -> st.Name), range) + let spName = sp.PUntaint ((fun sp -> sp.Name), range) match argSpecsTable.TryGetValue spName with | true, arg -> /// Find the name of the representation type for the static parameter let spReprTypeName = sp.PUntaint((fun sp -> - let pt = sp.ParameterType - let ut = pt.RawSystemType - let uet = if pt.IsEnum then ut.GetEnumUnderlyingType() else ut - uet.FullName), m) + let pt = sp.ParameterType + let uet = if pt.IsEnum then pt.GetEnumUnderlyingType() else pt + uet.FullName), range) match spReprTypeName with | "System.SByte" -> box (sbyte arg) @@ -1110,8 +1167,8 @@ module internal ExtensionTyping = | s -> error(Error(FSComp.SR.etUnknownStaticArgumentKind(s, typeLogicalName), range0)) | _ -> - if sp.PUntaint ((fun sp -> sp.IsOptional), m) then - match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with + if sp.PUntaint ((fun sp -> sp.IsOptional), range) then + match sp.PUntaint((fun sp -> sp.RawDefaultValue), range) with | null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, typeBeforeArgumentsName, typeBeforeArgumentsName, spName), range0)) | v -> v else @@ -1138,16 +1195,16 @@ module internal ExtensionTyping = GetPartsOfNamespaceRecover namespaceName /// Get the parts of the name that encloses the .NET type including nested types. - let GetFSharpPathToProvidedType (st: Tainted, m) = + let GetFSharpPathToProvidedType (st: Tainted, range) = // Can't use st.Fullname because it may be like IEnumerable // We want [System;Collections;Generic] - let namespaceParts = GetPartsOfNamespaceRecover(st.PUntaint((fun st -> st.Namespace), m)) + let namespaceParts = GetPartsOfNamespaceRecover(st.PUntaint((fun st -> st.Namespace), range)) let rec walkUpNestedClasses(st: Tainted, soFar) = match st with | Tainted.Null -> soFar - | st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), soFar) @ [st.PUntaint((fun st -> st.Name), m)] + | st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), range), soFar) @ [st.PUntaint((fun st -> st.Name), range)] - walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), namespaceParts) + walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), range), namespaceParts) /// Get the ILAssemblyRef for a provided assembly. Do not take into account @@ -1158,29 +1215,29 @@ module internal ExtensionTyping = /// Get the ILTypeRef for the provided type (including for nested types). Do not take into account /// any type relocations or static linking for generated types. - let GetOriginalILTypeRefOfProvidedType (st: Tainted, m) = + let GetOriginalILTypeRefOfProvidedType (st: Tainted, range) = - let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> st.Assembly), m), m) + let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> st.Assembly), range), range) let scoperef = ILScopeRef.Assembly aref - let enc, nm = ILPathToProvidedType (st, m) + let enc, nm = ILPathToProvidedType (st, range) let tref = ILTypeRef.Create(scoperef, enc, nm) tref /// Get the ILTypeRef for the provided type (including for nested types). Take into account /// any type relocations or static linking for generated types. - let GetILTypeRefOfProvidedType (st: Tainted, m) = - match st.PUntaint((fun st -> st.TryGetILTypeRef()), m) with + let GetILTypeRefOfProvidedType (st: Tainted, range) = + match st.PUntaint((fun st -> st.TryGetILTypeRef()), range) with | Some ilTypeRef -> ilTypeRef - | None -> GetOriginalILTypeRefOfProvidedType (st, m) + | None -> GetOriginalILTypeRefOfProvidedType (st, range) type ProviderGeneratedType = ProviderGeneratedType of (*ilOrigTyRef*)ILTypeRef * (*ilRenamedTyRef*)ILTypeRef * ProviderGeneratedType list /// The table of information recording remappings from type names in the provided assembly to type /// names in the statically linked, embedded assembly, plus what types are nested in side what types. type ProvidedAssemblyStaticLinkingMap = - { ILTypeMap: System.Collections.Generic.Dictionary } + { ILTypeMap: Dictionary } static member CreateNew() = - { ILTypeMap = System.Collections.Generic.Dictionary() } + { ILTypeMap = Dictionary() } /// Check if this is a direct reference to a non-embedded generated type. This is not permitted at any name resolution. /// We check by seeing if the type is absent from the remapping context. diff --git a/src/fsharp/ExtensionTyping.fsi b/src/fsharp/ExtensionTyping.fsi index d6584d4188b..819d0a79ef4 100755 --- a/src/fsharp/ExtensionTyping.fsi +++ b/src/fsharp/ExtensionTyping.fsi @@ -6,26 +6,25 @@ namespace FSharp.Compiler #if !NO_EXTENSIONTYPING -module internal ExtensionTyping = +open System +open System.Collections.Concurrent +open System.Collections.Generic +open FSharp.Core.CompilerServices +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Text - open System - open System.IO - open System.Collections.Generic - open Microsoft.FSharp.Core.CompilerServices - open FSharp.Compiler.AbstractIL.IL - open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler.Range +module ExtensionTyping = - type TypeProviderDesignation = TypeProviderDesignation of string + type internal TypeProviderDesignation = TypeProviderDesignation of string /// Raised when a type provider has thrown an exception. - exception ProvidedTypeResolution of range * exn + exception internal ProvidedTypeResolution of range * exn /// Raised when an type provider has thrown an exception. - exception ProvidedTypeResolutionNoRange of exn + exception internal ProvidedTypeResolutionNoRange of exn /// Get the list of relative paths searched for type provider design-time components - val toolingCompatiblePaths: unit -> string list + val internal toolingCompatiblePaths: unit -> string list /// Carries information about the type provider resolution environment. type ResolutionEnvironment = @@ -45,20 +44,20 @@ module internal ExtensionTyping = } /// Find and instantiate the set of ITypeProvider components for the given assembly reference - val GetTypeProvidersOfAssembly : - runtimeAssemblyFilename: string - * ilScopeRefOfRuntimeAssembly:ILScopeRef - * designerAssemblyName: string - * ResolutionEnvironment - * bool - * isInteractive: bool - * systemRuntimeContainsType : (string -> bool) - * systemRuntimeAssemblyVersion : System.Version - * compilerToolsPath : string list - * range -> Tainted list + val internal GetTypeProvidersOfAssembly : + runtimeAssemblyFilename: string * + ilScopeRefOfRuntimeAssembly:ILScopeRef * + designTimeName: string * + resolutionEnvironment: ResolutionEnvironment * + isInvalidationSupported: bool * + isInteractive: bool * + systemRuntimeContainsType : (string -> bool) * + systemRuntimeAssemblyVersion : Version * + compilerToolPaths : string list * + range -> Tainted list /// Given an extension type resolver, supply a human-readable name suitable for error messages. - val DisplayNameOfTypeProvider : Tainted * range -> string + val internal DisplayNameOfTypeProvider : Tainted * range -> string /// The context used to interpret information in the closure of System.Type, System.MethodInfo and other /// info objects coming from the type provider. @@ -74,20 +73,20 @@ module internal ExtensionTyping = [] type ProvidedTypeContext = - member TryGetILTypeRef : System.Type -> ILTypeRef option + member TryGetILTypeRef : ProvidedType -> ILTypeRef option - member TryGetTyconRef : System.Type -> obj option + member TryGetTyconRef : ProvidedType -> obj option static member Empty : ProvidedTypeContext - static member Create : Dictionary * Dictionary -> ProvidedTypeContext + static member Create : ConcurrentDictionary * ConcurrentDictionary -> ProvidedTypeContext - member GetDictionaries : unit -> Dictionary * Dictionary + member GetDictionaries : unit -> ConcurrentDictionary * ConcurrentDictionary /// Map the TyconRef objects, if any member RemapTyconRefs : (obj -> obj) -> ProvidedTypeContext - type [] + and [] ProvidedType = inherit ProvidedMemberInfo member IsSuppressRelocate : bool @@ -120,6 +119,7 @@ module internal ExtensionTyping = member IsEnum : bool member IsInterface : bool member IsClass : bool + member IsMeasure: bool member IsSealed : bool member IsAbstract : bool member IsPublic : bool @@ -128,8 +128,14 @@ module internal ExtensionTyping = member GetElementType : unit -> ProvidedType member GetGenericArguments : unit -> ProvidedType[] member GetArrayRank : unit -> int - member RawSystemType : System.Type + member RawSystemType : Type member GetEnumUnderlyingType : unit -> ProvidedType + member MakePointerType: unit -> ProvidedType + member MakeByRefType: unit -> ProvidedType + member MakeArrayType: unit -> ProvidedType + member MakeArrayType: rank: int -> ProvidedType + member MakeGenericType: args: ProvidedType[] -> ProvidedType + member AsProvidedVar : name: string -> ProvidedVar static member Void : ProvidedType static member CreateNoContext : Type -> ProvidedType member TryGetILTypeRef : unit -> ILTypeRef option @@ -137,7 +143,7 @@ module internal ExtensionTyping = static member ApplyContext : ProvidedType * ProvidedTypeContext -> ProvidedType member Context : ProvidedTypeContext interface IProvidedCustomAttributeProvider - static member TaintedEquals : Tainted * Tainted -> bool + static member internal TaintedEquals : Tainted * Tainted -> bool and [] IProvidedCustomAttributeProvider = @@ -176,8 +182,8 @@ module internal ExtensionTyping = member GetParameters : unit -> ProvidedParameterInfo[] member GetGenericArguments : unit -> ProvidedType[] member GetStaticParametersForMethod : ITypeProvider -> ProvidedParameterInfo[] - static member TaintedGetHashCode : Tainted -> int - static member TaintedEquals : Tainted * Tainted -> bool + static member internal TaintedGetHashCode : Tainted -> int + static member internal TaintedEquals : Tainted * Tainted -> bool and [] ProvidedMethodInfo = @@ -210,7 +216,7 @@ module internal ExtensionTyping = member IsFamilyAndAssembly : bool member IsFamilyOrAssembly : bool member IsPrivate : bool - static member TaintedEquals : Tainted * Tainted -> bool + static member internal TaintedEquals : Tainted * Tainted -> bool and [] ProvidedPropertyInfo = @@ -221,8 +227,8 @@ module internal ExtensionTyping = member CanRead : bool member CanWrite : bool member PropertyType : ProvidedType - static member TaintedGetHashCode : Tainted -> int - static member TaintedEquals : Tainted * Tainted -> bool + static member internal TaintedGetHashCode : Tainted -> int + static member internal TaintedEquals : Tainted * Tainted -> bool and [] ProvidedEventInfo = @@ -230,145 +236,193 @@ module internal ExtensionTyping = member GetAddMethod : unit -> ProvidedMethodInfo member GetRemoveMethod : unit -> ProvidedMethodInfo member EventHandlerType : ProvidedType - static member TaintedGetHashCode : Tainted -> int - static member TaintedEquals : Tainted * Tainted -> bool + static member internal TaintedGetHashCode : Tainted -> int + static member internal TaintedEquals : Tainted * Tainted -> bool and [] ProvidedConstructorInfo = inherit ProvidedMethodBase + + and ProvidedExprType = + | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr[] +#if PROVIDED_ADDRESS_OF + | ProvidedAddressOfExpr of ProvidedExpr +#endif + | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr[] + | ProvidedWhileLoopExpr of ProvidedExpr * ProvidedExpr + | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar[] * ProvidedExpr + | ProvidedForIntegerRangeLoopExpr of ProvidedVar * ProvidedExpr * ProvidedExpr * ProvidedExpr + | ProvidedSequentialExpr of ProvidedExpr * ProvidedExpr + | ProvidedTryWithExpr of ProvidedExpr * ProvidedVar * ProvidedExpr * ProvidedVar * ProvidedExpr + | ProvidedTryFinallyExpr of ProvidedExpr * ProvidedExpr + | ProvidedLambdaExpr of ProvidedVar * ProvidedExpr + | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[] + | ProvidedConstantExpr of obj * ProvidedType + | ProvidedDefaultExpr of ProvidedType + | ProvidedNewTupleExpr of ProvidedExpr[] + | ProvidedTupleGetExpr of ProvidedExpr * int + | ProvidedTypeAsExpr of ProvidedExpr * ProvidedType + | ProvidedTypeTestExpr of ProvidedExpr * ProvidedType + | ProvidedLetExpr of ProvidedVar * ProvidedExpr * ProvidedExpr + | ProvidedVarSetExpr of ProvidedVar * ProvidedExpr + | ProvidedIfThenElseExpr of ProvidedExpr * ProvidedExpr * ProvidedExpr + | ProvidedVarExpr of ProvidedVar - [] - type ProvidedExpr = + and [] + ProvidedExpr = member Type : ProvidedType /// Convert the expression to a string for diagnostics member UnderlyingExpressionString : string + member GetExprType : unit -> ProvidedExprType option - [] - type ProvidedVar = + and [] + ProvidedVar = member Type : ProvidedType member Name : string member IsMutable : bool - static member Fresh : string * ProvidedType -> ProvidedVar override Equals : obj -> bool override GetHashCode : unit -> int - /// Detect a provided new-array expression - val (|ProvidedNewArrayExpr|_|) : ProvidedExpr -> (ProvidedType * ProvidedExpr[]) option - -#if PROVIDED_ADDRESS_OF - val (|ProvidedAddressOfExpr|_|) : ProvidedExpr -> ProvidedExpr option -#endif - - /// Detect a provided new-object expression - val (|ProvidedNewObjectExpr|_|) : ProvidedExpr -> (ProvidedConstructorInfo * ProvidedExpr[]) option - - /// Detect a provided while-loop expression - val (|ProvidedWhileLoopExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedExpr) option - - /// Detect a provided new-delegate expression - val (|ProvidedNewDelegateExpr|_|) : ProvidedExpr -> (ProvidedType * ProvidedVar[] * ProvidedExpr) option - - /// Detect a provided expression which is a for-loop over integers - val (|ProvidedForIntegerRangeLoopExpr|_|) : ProvidedExpr -> (ProvidedVar * ProvidedExpr * ProvidedExpr * ProvidedExpr) option - - /// Detect a provided sequential expression - val (|ProvidedSequentialExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedExpr) option - - /// Detect a provided try/with expression - val (|ProvidedTryWithExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedVar * ProvidedExpr * ProvidedVar * ProvidedExpr) option - - /// Detect a provided try/finally expression - val (|ProvidedTryFinallyExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedExpr) option - - /// Detect a provided lambda expression - val (|ProvidedLambdaExpr|_|) : ProvidedExpr -> (ProvidedVar * ProvidedExpr) option - - /// Detect a provided call expression - val (|ProvidedCallExpr|_|) : ProvidedExpr -> (ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[]) option - - /// Detect a provided constant expression - val (|ProvidedConstantExpr|_|) : ProvidedExpr -> (obj * ProvidedType) option - - /// Detect a provided default-value expression - val (|ProvidedDefaultExpr|_|) : ProvidedExpr -> ProvidedType option - - /// Detect a provided new-tuple expression - val (|ProvidedNewTupleExpr|_|) : ProvidedExpr -> ProvidedExpr[] option - - /// Detect a provided tuple-get expression - val (|ProvidedTupleGetExpr|_|) : ProvidedExpr -> (ProvidedExpr * int) option - - /// Detect a provided type-as expression - val (|ProvidedTypeAsExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedType) option - - /// Detect a provided type-test expression - val (|ProvidedTypeTestExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedType) option - - /// Detect a provided 'let' expression - val (|ProvidedLetExpr|_|) : ProvidedExpr -> (ProvidedVar * ProvidedExpr * ProvidedExpr) option - - /// Detect a provided 'set variable' expression - val (|ProvidedVarSetExpr|_|) : ProvidedExpr -> (ProvidedVar * ProvidedExpr) option - - /// Detect a provided 'IfThenElse' expression - val (|ProvidedIfThenElseExpr|_|) : ProvidedExpr -> (ProvidedExpr * ProvidedExpr * ProvidedExpr) option - - /// Detect a provided 'Var' expression - val (|ProvidedVarExpr|_|) : ProvidedExpr -> ProvidedVar option - /// Get the provided expression for a particular use of a method. - val GetInvokerExpression : ITypeProvider * ProvidedMethodBase * ProvidedVar[] -> ProvidedExpr + val internal GetInvokerExpression : ITypeProvider * ProvidedMethodBase * ProvidedVar[] -> ProvidedExpr + /// Get all provided types from provided namespace + val internal GetProvidedTypes: pn: IProvidedNamespace -> ProvidedType[] + /// Validate that the given provided type meets some of the rules for F# provided types - val ValidateProvidedTypeAfterStaticInstantiation : range * Tainted * expectedPath : string[] * expectedName : string-> unit + val internal ValidateProvidedTypeAfterStaticInstantiation : range * Tainted * expectedPath : string[] * expectedName : string-> unit /// Try to apply a provided type to the given static arguments. If successful also return a function /// to check the type name is as expected (this function is called by the caller of TryApplyProvidedType /// after other checks are made). - val TryApplyProvidedType : typeBeforeArguments:Tainted * optGeneratedTypePath: string list option * staticArgs:obj[] * range -> (Tainted * (unit -> unit)) option + val internal TryApplyProvidedType : typeBeforeArguments:Tainted * optGeneratedTypePath: string list option * staticArgs:obj[] * range -> (Tainted * (unit -> unit)) option /// Try to apply a provided method to the given static arguments. - val TryApplyProvidedMethod : methBeforeArguments:Tainted * staticArgs:obj[] * range -> Tainted option + val internal TryApplyProvidedMethod : methBeforeArgs:Tainted * staticArgs:obj[] * range -> Tainted option /// Try to resolve a type in the given extension type resolver - val TryResolveProvidedType : Tainted * range * string[] * typeName: string -> Tainted option + val internal TryResolveProvidedType : Tainted * range * string[] * typeName: string -> Tainted option /// Try to resolve a type in the given extension type resolver - val TryLinkProvidedType : Tainted * string[] * typeLogicalName: string * range: range -> Tainted option + val internal TryLinkProvidedType : Tainted * string[] * typeLogicalName: string * range: range -> Tainted option /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed. - val GetProvidedNamespaceAsPath : range * Tainted * string -> string list + val internal GetProvidedNamespaceAsPath : range * Tainted * string -> string list /// Decompose the enclosing name of a type (including any class nestings) into a list of parts. /// e.g. System.Object -> ["System"; "Object"] - val GetFSharpPathToProvidedType : Tainted * range:range-> string list + val internal GetFSharpPathToProvidedType : Tainted * range:range-> string list /// Get the ILTypeRef for the provided type (including for nested types). Take into account /// any type relocations or static linking for generated types. - val GetILTypeRefOfProvidedType : Tainted * range:range -> FSharp.Compiler.AbstractIL.IL.ILTypeRef + val internal GetILTypeRefOfProvidedType : Tainted * range:range -> ILTypeRef /// Get the ILTypeRef for the provided type (including for nested types). Do not take into account /// any type relocations or static linking for generated types. - val GetOriginalILTypeRefOfProvidedType : Tainted * range:range -> FSharp.Compiler.AbstractIL.IL.ILTypeRef + val internal GetOriginalILTypeRefOfProvidedType : Tainted * range:range -> ILTypeRef /// Represents the remapping information for a generated provided type and its nested types. /// /// There is one overall tree for each root 'type X = ... type generation expr...' specification. - type ProviderGeneratedType = ProviderGeneratedType of (*ilOrigTyRef*)ILTypeRef * (*ilRenamedTyRef*)ILTypeRef * ProviderGeneratedType list + type internal ProviderGeneratedType = ProviderGeneratedType of (*ilOrigTyRef*)ILTypeRef * (*ilRenamedTyRef*)ILTypeRef * ProviderGeneratedType list /// The table of information recording remappings from type names in the provided assembly to type /// names in the statically linked, embedded assembly, plus what types are nested in side what types. - type ProvidedAssemblyStaticLinkingMap = + type internal ProvidedAssemblyStaticLinkingMap = { /// The table of remappings from type names in the provided assembly to type /// names in the statically linked, embedded assembly. - ILTypeMap: System.Collections.Generic.Dictionary } + ILTypeMap: Dictionary } /// Create a new static linking map, ready to populate with data. static member CreateNew : unit -> ProvidedAssemblyStaticLinkingMap /// Check if this is a direct reference to a non-embedded generated type. This is not permitted at any name resolution. /// We check by seeing if the type is absent from the remapping context. - val IsGeneratedTypeDirectReference : Tainted * range -> bool + val internal IsGeneratedTypeDirectReference: Tainted * range -> bool + + /// The public API hook for instantiating type providers and getting provided types. + [] + module Shim = + + /// Context for instantiating type providers. + type TypeProvidersInstantiationContext = + { /// Type providers runtime component filename. + RuntimeAssemblyFilename: string + /// Type providers design-time component name, + /// that have a class that implements ITypeProvider, and on which there is a type provider attribute. + DesignerAssemblyName: string + /// Type providers resolution environment. + ResolutionEnvironment: ResolutionEnvironment + /// Is invalidation supported for type providers. + IsInvalidationSupported: bool + /// Is instantiation called from F# interactive. + IsInteractive: bool + /// Query information about types available in target system runtime library. + SystemRuntimeContainsType: string -> bool + /// System.Runtime assembly version + SystemRuntimeAssemblyVersion: Version + /// Compiler tools path + CompilerToolsPath: string list + /// Error logging function + LogError: TypeProviderError -> unit + /// Range + Range: range } + + /// + /// Contains API for instantiating type providers and getting provided types. + /// + /// + /// This interface operates with Provided- wrappers and can be used to host type providers out-of-process. + /// For example, in the FCS process for an IDE, the implementation of this interface can receive data from another process + /// in which type providers are instantiated using DefaultExtensionTypingProvider. + /// + type IExtensionTypingProvider = + /// + /// Called by the FCS to find and instantiate the set of ITypeProvider components for the given assembly reference. + /// + /// Instantiation context. + /// List of found and instantiated ITypeProvider components. + abstract InstantiateTypeProvidersOfAssembly: context: TypeProvidersInstantiationContext -> ITypeProvider list + + /// + /// Called by the FCS to get top-level provided types from provided namespace. + /// + /// Provided namespace in which to search. + /// Top-level provided types from namespace. + abstract GetProvidedTypes: pn: IProvidedNamespace -> ProvidedType[] + + /// + /// Called by the FCS to query a type provider for a type name. + /// + /// Provided namespace in which to search. + /// Name of the searched type. + /// Resolver should return a type called name in namespace NamespaceName or null if the type is unknown. + abstract ResolveTypeName: pn: IProvidedNamespace * typeName: string -> ProvidedType + + /// + /// Called by the FCS to ask for an Expression tree to replace the given MethodBase with. + /// + /// ITypeProvider component. + /// MethodBase that was given to the compiler by a type returned by a GetType(s) call. + /// Expressions that represent the parameters to this call. + /// An expression that the compiler will use in place of the given method base. + abstract GetInvokerExpression: provider: ITypeProvider * methodBase: ProvidedMethodBase * paramExprs: ProvidedVar[] -> ProvidedExpr + + /// + /// Get the name of the type provider to display in error messages. + /// + /// ITypeProvider component. + /// Get full name including namespace. + /// Type provider name. + abstract DisplayNameOfTypeProvider: typeProvider: ITypeProvider * fullName: bool -> string + + /// Default IExtensionTypingProvider implementation for creating type providers in the current FCS process. + [] + type DefaultExtensionTypingProvider = + interface IExtensionTypingProvider + + /// IExtensionTypingProvider implementation currently used by FCS. + val mutable ExtensionTypingProvider: IExtensionTypingProvider #endif diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index de26c9b349a..3648742e205 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1,9 +1,10 @@ -# ----------------------------------------------------------------------------- -# use a completely new error number and add new messages at the end of the file -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- +# use a completely new error number and keep messages in their surrounding groups +# ------------------------------------------------------------------------------- undefinedNameNamespace,"The namespace '%s' is not defined." undefinedNameNamespaceOrModule,"The namespace or module '%s' is not defined." undefinedNameFieldConstructorOrMember,"The field, constructor or member '%s' is not defined." +undefinedNameFieldConstructorOrMemberWhenTypeIsKnown,"The type '%s' does not define the field, constructor or member '%s'." undefinedNameValueConstructorNamespaceOrType,"The value, constructor, namespace or type '%s' is not defined." undefinedNameValueOfConstructor,"The value or constructor '%s' is not defined." undefinedNameValueNamespaceTypeOrModule,"The value, namespace, type or module '%s' is not defined." @@ -17,12 +18,12 @@ undefinedNameTypeParameter,"The type parameter %s is not defined." undefinedNamePatternDiscriminator,"The pattern discriminator '%s' is not defined." replaceWithSuggestion,"Replace with '%s'" addIndexerDot,"Add . for indexer access." -listElementHasWrongType,"All elements of a list must be of the same type as the first element, which here is '%s'. This element has type '%s'." -arrayElementHasWrongType,"All elements of an array must be of the same type as the first element, which here is '%s'. This element has type '%s'." +listElementHasWrongType,"All elements of a list must be implicitly convertible to the type of the first element, which here is '%s'. This element has type '%s'." +arrayElementHasWrongType,"All elements of an array must be implicitly convertible to the type of the first element, which here is '%s'. This element has type '%s'." missingElseBranch,"This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type '%s'." ifExpression,"The 'if' expression needs to have type '%s' to satisfy context type requirements. It currently has type '%s'." -elseBranchHasWrongType,"All branches of an 'if' expression must return values of the same type as the first branch, which here is '%s'. This branch returns a value of type '%s'." -followingPatternMatchClauseHasWrongType,"All branches of a pattern match expression must return values of the same type as the first branch, which here is '%s'. This branch returns a value of type '%s'." +elseBranchHasWrongType,"All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '%s'. This branch returns a value of type '%s'." +followingPatternMatchClauseHasWrongType,"All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '%s'. This branch returns a value of type '%s'." patternMatchGuardIsNotBool,"A pattern match guard must be of type 'bool', but this 'when' expression is of type '%s'." commaInsteadOfSemicolonInRecord,"A ';' is used to separate field values in records. Consider replacing ',' with ';'." derefInsteadOfNot,"The '!' operator is used to dereference a ref cell. Consider using 'not expr' here." @@ -30,11 +31,10 @@ buildUnexpectedTypeArgs,"The non-generic type '%s' does not expect any type argu returnUsedInsteadOfReturnBang,"Consider using 'return!' instead of 'return'." yieldUsedInsteadOfYieldBang,"Consider using 'yield!' instead of 'yield'." tupleRequiredInAbstractMethod,"\nA tuple type is required for one or more arguments. Consider wrapping the given arguments in additional parentheses or review the definition of the interface." +202,unsupportedAttribute,"This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." 203,buildInvalidWarningNumber,"Invalid warning number '%s'" 204,buildInvalidVersionString,"Invalid version string '%s'" 205,buildInvalidVersionFile,"Invalid version file '%s'" -buildProductName,"Microsoft (R) F# Compiler version %s" -buildProductNameCommunity,"F# Compiler for F# %s" 206,buildProblemWithFilename,"Problem with filename '%s': %s" 207,buildNoInputsSpecified,"No inputs specified" 209,buildPdbRequiresDebug,"The '--pdb' option requires the '--debug' option to be used" @@ -52,6 +52,8 @@ buildProductNameCommunity,"F# Compiler for F# %s" 224,buildOptionRequiresParameter,"Option requires parameter: %s" 225,buildCouldNotFindSourceFile,"Source file '%s' could not be found" 226,buildInvalidSourceFileExtension,"The file extension of '%s' is not recognized. Source files must have extension .fs, .fsi, .fsx, .fsscript, .ml or .mli." +226,buildInvalidSourceFileExtensionUpdated,"The file extension of '%s' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript" +226,buildInvalidSourceFileExtensionML,"The file extension of '%s' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'." 227,buildCouldNotResolveAssembly,"Could not resolve assembly '%s'" 228,buildCouldNotResolveAssemblyRequiredByFile,"Could not resolve assembly '%s' required by '%s'" 229,buildErrorOpeningBinaryFile,"Error opening binary file '%s': %s" @@ -190,7 +192,7 @@ ExceptionDefsNotCompatibleFieldOrderDiffers,"The exception definitions are not c 361,typrelOverrideImplementsMoreThenOneSlot,"The override '%s' implements more than one abstract slot, e.g. '%s' and '%s'" 362,typrelDuplicateInterface,"Duplicate or redundant interface" 363,typrelNeedExplicitImplementation,"The interface '%s' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface." -364,typrelNamedArgumentHasBeenAssignedMoreThenOnce,"A named argument has been assigned more than one value" +364,typrelNamedArgumentHasBeenAssignedMoreThenOnce,"The named argument '%s' has been assigned more than one value" 365,typrelNoImplementationGiven,"No implementation was given for '%s'" 366,typrelNoImplementationGivenWithSuggestion,"No implementation was given for '%s'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." 365,typrelNoImplementationGivenSeveral,"No implementation was given for those members: %s" @@ -330,6 +332,7 @@ csTypeNotCompatibleBecauseOfPrintf,"The type '%s' is not compatible with any of csGenericConstructRequiresReferenceSemantics,"A generic construct requires that the type '%s' have reference semantics, but it does not, i.e. it is a struct" csGenericConstructRequiresNonAbstract,"A generic construct requires that the type '%s' be non-abstract" csGenericConstructRequiresPublicDefaultConstructor,"A generic construct requires that the type '%s' have a public default constructor" +csGenericConstructRequiresStructOrReferenceConstraint,"A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation." 483,csTypeInstantiationLengthMismatch,"Type instantiation length mismatch" 484,csOptionalArgumentNotPermittedHere,"Optional arguments not permitted here" 485,csMemberIsNotStatic,"%s is not a static member" @@ -361,9 +364,16 @@ csCtorHasNoArgumentOrReturnProperty,"The object constructor '%s' has no argument 508,csNoMemberTakesTheseArguments3,"No %s member or object constructor named '%s' takes %d arguments. The named argument '%s' doesn't correspond to any argument or settable return property for any overload." 509,csMethodNotFound,"Method or object constructor '%s' not found" csNoOverloadsFound,"No overloads match for method '%s'." +csNoOverloadsFoundArgumentsPrefixSingular,"Known type of argument: %s" +csNoOverloadsFoundArgumentsPrefixPlural,"Known types of arguments: %s" +csNoOverloadsFoundTypeParametersPrefixSingular,"Known type parameter: %s" +csNoOverloadsFoundTypeParametersPrefixPlural,"Known type parameters: %s" +csNoOverloadsFoundReturnType,"Known return type: %s" csMethodIsOverloaded,"A unique overload for method '%s' could not be determined based on type information prior to this program point. A type annotation may be needed." -csCandidates,"Candidates: %s" -csSeeAvailableOverloads,"The available overloads are shown below." +csCandidates,"Candidates:\n%s" +csAvailableOverloads,"Available overloads:\n%s" +csOverloadCandidateNamedArgumentTypeMismatch,"Argument '%s' doesn't match" +csOverloadCandidateIndexedArgumentTypeMismatch,"Argument at index %d doesn't match" 512,parsDoCannotHaveVisibilityDeclarations,"Accessibility modifiers are not permitted on 'do' bindings, but '%s' was given." 513,parsEofInHashIf,"End of file in #if section begun at or after here" 514,parsEofInString,"End of file in string begun at or before here" @@ -470,12 +480,12 @@ parsSyntaxModuleSigEndDeprecated,"The syntax 'module ... : sig .. end' is not us 634,tcNonZeroConstantCannotHaveGenericUnit,"Non-zero constants cannot have generic units. For generic zero, write 0.0<_>." 635,tcSeqResultsUseYield,"In sequence expressions, results are generated using 'yield'" tcUnexpectedBigRationalConstant,"Unexpected big rational constant" -636,tcInvalidTypeForUnitsOfMeasure,"Units-of-measure supported only on float, float32, decimal and signed integer types" +636,tcInvalidTypeForUnitsOfMeasure,"Units-of-measure are only supported on float, float32, decimal, and integer types." tcUnexpectedConstUint16Array,"Unexpected Const_uint16array" tcUnexpectedConstByteArray,"Unexpected Const_bytearray" 640,tcParameterRequiresName,"A parameter with attributes must also be given a name, e.g. '[] Name : Type'" 641,tcReturnValuesCannotHaveNames,"Return values cannot have names" -tcMemberKindPropertyGetSetNotExpected,"MemberKind.PropertyGetSet only expected in parse trees" +tcMemberKindPropertyGetSetNotExpected,"SynMemberKind.PropertyGetSet only expected in parse trees" 201,tcNamespaceCannotContainValues,"Namespaces cannot contain values. Consider using a module to hold your value declarations." 644,tcNamespaceCannotContainExtensionMembers,"Namespaces cannot contain extension members except in the same file and namespace declaration group where the type is defined. Consider using a module to hold declarations of extension members." 645,tcMultipleVisibilityAttributes,"Multiple visibility attributes have been specified for this identifier" @@ -586,7 +596,7 @@ tcExpressionWithIfRequiresParenthesis,"This list or array expression includes an 748,tcConstructRequiresComputationExpressions,"This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'." 749,tcConstructRequiresSequenceOrComputations,"This construct may only be used within sequence or computation expressions" 750,tcConstructRequiresComputationExpression,"This construct may only be used within computation expressions" -751,tcInvalidIndexerExpression,"Invalid indexer expression" +751,tcInvalidIndexerExpression,"Incomplete expression or invalid use of indexer syntax" 752,tcObjectOfIndeterminateTypeUsedRequireTypeConstraint,"The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints" 753,tcCannotInheritFromVariableType,"Cannot inherit from a variable type" 754,tcObjectConstructorsOnTypeParametersCannotTakeArguments,"Calls to object constructors on type parameters cannot be given arguments" @@ -708,9 +718,9 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of 871,tcConstructorsIllegalForThisType,"Constructors cannot be defined for this type" 872,tcRecursiveBindingsWithMembersMustBeDirectAugmentation,"Recursive bindings that include member specifications can only occur as a direct augmentation of a type" 873,tcOnlySimplePatternsInLetRec,"Only simple variable patterns can be bound in 'let rec' constructs" -874,tcOnlyRecordFieldsAndSimpleLetCanBeMutable,"Only record fields and simple, non-recursive 'let' bindings may be marked mutable" +874,tcOnlyRecordFieldsAndSimpleLetCanBeMutable,"Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces" 875,tcMemberIsNotSufficientlyGeneric,"This member is not sufficiently generic" -876,tcLiteralAttributeRequiresConstantValue,"A declaration may only be the [] attribute if a constant value is also given, e.g. 'val x : int = 1'" +876,tcLiteralAttributeRequiresConstantValue,"A declaration may only be the [] attribute if a constant value is also given, e.g. 'val x: int = 1'" 877,tcValueInSignatureRequiresLiteralAttribute,"A declaration may only be given a value in a signature if the declaration has the [] attribute" 878,tcThreadStaticAndContextStaticMustBeStatic,"Thread-static and context-static variables must be static and given the [] attribute to indicate that the value is initialized to the default value on each new thread" 879,tcVolatileFieldsMustBeMutable,"Volatile fields must be marked 'mutable' and cannot be thread-static" @@ -844,8 +854,10 @@ optsPlatform,"Limit which platforms this code can run on: x86, Itanium, x64, any optsNoOpt,"Only include optimization information essential for implementing inlined constructs. Inhibits cross-module inlining but improves binary compatibility." optsNoInterface,"Don't add a resource to the generated assembly containing F#-specific metadata" optsSig,"Print the inferred interface of the assembly to a file" +optsAllSigs,"Print the inferred interfaces of all compilation files to associated signature files" optsReference,"Reference an assembly (Short form: -r)" optsCompilerTool,"Reference an assembly or directory containing a design time tool (Short form: -t)" +optsWin32icon,"Specify a Win32 icon file (.ico)" optsWin32res,"Specify a Win32 resource file (.res)" optsWin32manifest,"Specify a Win32 manifest file" optsNowin32manifest,"Do not include the default Win32 manifest" @@ -874,6 +886,7 @@ optsDefine,"Define conditional compilation symbols (Short form: -d)" optsMlcompatibility,"Ignore ML compatibility warnings" optsNologo,"Suppress compiler copyright message" optsHelp,"Display this usage message (Short form: -?)" +optsVersion,"Display compiler version banner and exit" optsResponseFile,"Read response file for more options" optsCodepage,"Specify the codepage used to read source files" optsUtf8output,"Output messages in UTF-8 encoding" @@ -1013,7 +1026,7 @@ lexUnexpectedChar,"Unexpected character '%s'" 1153,lexInvalidFloat,"Invalid floating point number" 1154,lexOusideDecimal,"This number is outside the allowable range for decimal literals" 1155,lexOusideThirtyTwoBitFloat,"This number is outside the allowable range for 32-bit floats" -1156,lexInvalidNumericLiteral,"This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)." +1156,lexInvalidNumericLiteral,"This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)." 1157,lexInvalidByteLiteral,"This is not a valid byte literal" 1158,lexInvalidCharLiteral,"This is not a valid character literal" 1159,lexThisUnicodeOnlyInStringLiterals,"This Unicode encoding is only valid in string literals" @@ -1067,6 +1080,13 @@ parsNonAtomicType,"The use of the type syntax 'int C' and 'C ' is not perm #1203 - used for error in FSharp.Core CompilerMessage message #1204 - used for error in FSharp.Core CompilerMessage message mlCompatMessage,"This construct is for ML compatibility. %s. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'." +mlCompatError,"This construct is deprecated. %s. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'." +mlCompatKeyword,"In previous versions of F# '%s' was a reserved keyword but the use of this keyword is now deprecated" +mlCompatLightOffNoLongerSupported,"The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported" +mlCompatSigColonNoLongerSupported,"The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead" +mlCompatSigEndNoLongerSupported,"The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead" +mlCompatMultiPrefixTyparsNoLongerSupported,"The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported" +mlCompatStructEndNoLongerSupported,"The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead" #1205,chkDuplicateInherittedVirtualMethod,"Duplicate virtual methods. There are multiple virtual methods named '%s' with the same signature in the parent (inherited) type. This may be a result of instantiating the parent type." 1206,ilFieldDoesNotHaveValidOffsetForStructureLayout,"The type '%s' has been marked as having an Explicit layout, but the field '%s' has not been marked with the 'FieldOffset' attribute" 1207,tcInterfacesShouldUseInheritNotInterface,"Interfaces inherited by other interfaces should be declared using 'inherit ...' instead of 'interface ...'" @@ -1074,6 +1094,7 @@ mlCompatMessage,"This construct is for ML compatibility. %s. You can disable thi 1208,parsInvalidPrefixOperatorDefinition,"Invalid operator definition. Prefix operator definitions must use a valid prefix operator name." buildCompilingExtensionIsForML,"The file extensions '.ml' and '.mli' are for ML compatibility" lexIndentOffForML,"Consider using a file with extension '.ml' or '.mli' instead" +lexIfOCaml,"IF-FSHARP/IF-CAML regions are no longer supported" 1209,activePatternIdentIsNotFunctionTyped,"Active pattern '%s' is not a function" 1210,activePatternChoiceHasFreeTypars,"Active pattern '%s' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x'" 1211,ilFieldHasOffsetForSequentialLayout,"The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)" @@ -1170,7 +1191,8 @@ fscTooManyErrors,"Exiting - too many errors" 3028,etProvidedTypeHasUnexpectedName,"Expected provided type named '%s' but provided type has 'Name' with value '%s'" 3029,etEventNoAdd,"Event '%s' on provided type '%s' has no value from GetAddMethod()" 3030,etEventNoRemove,"Event '%s' on provided type '%s' has no value from GetRemoveMethod()" -3031,etProviderHasWrongDesignerAssembly,"Assembly attribute '%s' refers to a designer assembly '%s' which cannot be loaded or doesn't exist. %s" +3031,etProviderHasWrongDesignerAssemblyNoPath,"Assembly attribute '%s' refers to a designer assembly '%s' which cannot be loaded or doesn't exist. The exception reported was: %s - %s" +3031,etProviderHasWrongDesignerAssembly,"Assembly attribute '%s' refers to a designer assembly '%s' which cannot be loaded from path '%s'. The exception reported was: %s - %s" 3032,etProviderDoesNotHaveValidConstructor,"The type provider does not have a valid constructor. A constructor taking either no arguments or one argument of type 'TypeProviderConfig' was expected." 3033,etProviderError,"The type provider '%s' reported an error: %s" 3034,etIncorrectParameterExpression,"The type provider '%s' used an invalid parameter in the ParameterExpression: %s" @@ -1184,6 +1206,8 @@ fscTooManyErrors,"Exiting - too many errors" 3045,etInvalidStaticArgument,"Invalid static argument to provided type. Expected an argument of kind '%s'." 3046,etErrorApplyingStaticArgumentsToType,"An error occured applying the static arguments to a provided type" 3047,etUnknownStaticArgumentKind,"Unknown static argument kind '%s' when resolving a reference to a provided type or method '%s'" +3048,etProviderHasDesignerAssemblyDependency,"The type provider designer assembly '%s' could not be loaded from folder '%s' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: %s - %s" +3049,etProviderHasDesignerAssemblyException,"The type provider designer assembly '%s' could not be loaded from folder '%s'. The exception reported was: %s - %s" invalidNamespaceForProvidedType,"invalid namespace for provided type" invalidFullNameForProvidedType,"invalid full name for provided type" #3050,etGenerateAttributeRequiresInternal,"The 'Generate' attribute must be used with a type definition with 'internal' visibility" @@ -1215,6 +1239,15 @@ invalidFullNameForProvidedType,"invalid full name for provided type" 3085,tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings,"A custom operation may not be used in conjunction with a non-value or recursive 'let' binding in another part of this computation expression" 3086,tcCustomOperationMayNotBeUsedHere,"A custom operation may not be used in conjunction with 'use', 'try/with', 'try/finally', 'if/then/else' or 'match' operators within this computation expression" 3087,tcCustomOperationMayNotBeOverloaded,"The custom operation '%s' refers to a method which is overloaded. The implementations of custom operations may not be overloaded." +featureOverloadsForCustomOperations,"overloads for custom operations" +featureExpandedMeasurables,"more types support units of measure" +featurePrintfBinaryFormat,"binary formatting for integers" +featureIndexerNotationWithoutDot,"expr[idx] notation for indexing and slicing" +featureRefCellNotationInformationals,"informational messages related to reference cells" +featureDiscardUseValue,"discard pattern in use binding" +featureNonVariablePatternsToRightOfAsPatterns,"non-variable patterns to the right of 'as' patterns" +featureAttributesToRightOfModuleKeyword,"attributes to the right of the 'module' keyword" +featureMLCompatRevisions,"ML compatibility revisions" 3090,tcIfThenElseMayNotBeUsedWithinQueries,"An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead." 3091,ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen,"Invalid argument to 'methodhandleof' during codegen" 3092,etProvidedTypeReferenceMissingArgument,"A reference to a provided type was missing a value for the static parameter '%s'. You may need to recompile one or more referenced assemblies." @@ -1354,6 +1387,7 @@ tcGlobalsSystemTypeNotFound,"The system type '%s' was required but no referenced 3215,parsUnexpectedSymbolEqualsInsteadOfIn,"Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead?" 3216,packageManagerUnknown,"Package manager key '%s' was not registered in %s. Currently registered: %s" 3217,packageManagerError,"%s" +tcAnonRecdInvalid,"Invalid Anonymous Record type declaration." tcAnonRecdCcuMismatch,"Two anonymous record types are from different assemblies '%s' and '%s'" tcAnonRecdFieldNameMismatch,"This anonymous record does not exactly match the expected shape. Add the missing fields %s and remove the extra fields %s." tcAnonRecdFieldNameSubset,"This anonymous record does not have enough fields. Add the missing fields %s." @@ -1366,6 +1400,7 @@ keywordDescriptionAssert,"Used to verify code during debugging." keywordDescriptionBase,"Used as the name of the base class object." keywordDescriptionBegin,"In verbose syntax, indicates the start of a code block." keywordDescriptionClass,"In verbose syntax, indicates the start of a class definition." +keywordDescriptionConst,"Keyword to specify a constant literal as a type parameter argument in Type Providers." keywordDescriptionDefault,"Indicates an implementation of an abstract method; used together with an abstract method declaration to create a virtual method." keywordDescriptionDelegate,"Used to declare a delegate." keywordDescriptionDo,"Used in looping constructs or to execute imperative code." @@ -1437,8 +1472,10 @@ keywordDescriptionUntypedQuotation,"Delimits a untyped code quotation." 3216,itemNotFoundInTypeDuringDynamicCodeGen,"%s '%s' not found in type '%s' from assembly '%s'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version." descriptionWordIs,"is" notAFunction,"This value is not a function and cannot be applied." -notAFunctionButMaybeIndexerWithName,"This value is not a function and cannot be applied. Did you intend to access the indexer via %s.[index] instead?" -notAFunctionButMaybeIndexer,"This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?" +notAFunctionButMaybeIndexerWithName,"This value is not a function and cannot be applied. Did you intend to access the indexer via '%s.[index]'?" +notAFunctionButMaybeIndexer,"This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?" +notAFunctionButMaybeIndexerWithName2,"This value is not a function and cannot be applied. Did you intend to access the indexer via '%s[index]'?" +notAFunctionButMaybeIndexer2,"This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?" 3217,notAFunctionButMaybeIndexerErrorCode,"" notAFunctionButMaybeDeclaration,"This value is not a function and cannot be applied. Did you forget to terminate a declaration?" 3218,ArgumentsInSigAndImplMismatch,"The argument names in the signature '%s' and implementation '%s' do not match. The argument name from the signature file will be used. This may cause problems when debugging or profiling." @@ -1471,13 +1508,124 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3247,couldNotLoadDependencyManagerExtension,"The dependency manager extension %s could not be loaded. Message: %s" 3250,expressionHasNoName,"Expression does not have a name." 3251,chkNoFirstClassNameOf,"Using the 'nameof' operator as a first-class function value is not permitted." +3252,tcIllegalByrefsInOpenTypeDeclaration,"Byref types are not allowed in an open type declaration." 3300,chkInvalidFunctionParameterType,"The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL." 3301,chkInvalidFunctionReturnType,"The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL." 3302,packageManagementRequiresVFive,"The package management feature requires language version 5.0 use /langversion:preview" 3303,fromEndSlicingRequiresVFive,"From the end slicing with requires language version 5.0, use /langversion:preview." +3304,poundiNotSupportedByRegisteredDependencyManagers,"#i is not supported by the registered PackageManagers" +3343,tcRequireMergeSourcesOrBindN,"The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '%s' method or appropriate 'MergeSource' and 'Bind' methods" +3344,tcAndBangNotSupported,"This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature." +3345,tcInvalidUseBangBindingNoAndBangs,"use! may not be combined with and!" +3350,chkFeatureNotLanguageSupported,"Feature '%s' is not available in F# %s. Please use language version %s or greater." +3351,chkFeatureNotRuntimeSupported,"Feature '%s' is not supported by target runtime." +3352,typrelInterfaceMemberNoMostSpecificImplementation,"Interface member '%s' does not have a most specific implementation." +3353,chkFeatureNotSupportedInLibrary,"Feature '%s' requires the F# library for language version %s or greater." +3360,parsEqualsMissingInTypeDefinition,"Unexpected token in type definition. Expected '=' after the type '%s'." useSdkRefs,"Use reference assemblies for .NET framework references when available (Enabled by default)." -fSharpBannerVersion,"%s for F# %s" optsLangVersion,"Display the allowed values for language version, specify language version such as 'latest' or 'preview'" optsSupportedLangVersions,"Supported language versions:" nativeResourceFormatError,"Stream does not begin with a null resource and is not in '.RES' format." nativeResourceHeaderMalformed,"Resource header beginning at offset %s is malformed." +formatDashItem," - %s" +featureSingleUnderscorePattern,"single underscore pattern" +featureWildCardInForLoop,"wild card in for loop" +featureRelaxWhitespace,"whitespace relexation" +featureNameOf,"nameof" +featureImplicitYield,"implicit yield" +featureOpenTypeDeclaration,"open type declaration" +featureDotlessFloat32Literal,"dotless float32 literal" +featurePackageManagement,"package management" +featureFromEndSlicing,"from-end slicing" +featureFixedIndexSlice3d4d,"fixed-index slice 3d/4d" +featureAndBang,"applicative computation expressions" +featureResumableStateMachines,"resumable state machines" +featureNullableOptionalInterop,"nullable optional interop" +featureDefaultInterfaceMemberConsumption,"default interface member consumption" +featureStringInterpolation,"string interpolation" +featureWitnessPassing,"witness passing for trait constraints in F# quotations" +featureAdditionalImplicitConversions,"additional type-directed conversions" +featureStructActivePattern,"struct representation for active patterns" +featureRelaxWhitespace2,"whitespace relaxation v2" +3353,fsiInvalidDirective,"Invalid directive '#%s %s'" +3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." +3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." +3355,tcNotAnIndexerNamedIndexingNotYetEnabled,"The value '%s' is not a function and does not support index notation." +3355,tcNotAnIndexerIndexingNotYetEnabled,"This expression is not a function and does not support index notation." +3360,typrelInterfaceWithConcreteAndVariable,"'%s' cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." +3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." +featureInterfacesWithMultipleGenericInstantiation,"interfaces with multiple generic instantiation" +3362,tcLiteralFieldAssignmentWithArg,"Cannot assign '%s' to a value marked literal" +3363,tcLiteralFieldAssignmentNoArg,"Cannot assign a value to another value marked literal" +3364,tcInvalidUseOfReverseIndex,"Invalid use of reverse index in list expression." +3365,tcHighPrecedenceFunctionApplicationToListDeprecated,"The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'." +3366,tcIndexNotationDeprecated,"The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code." +3367,tcHighPrecedenceFunctionApplicationToListReserved,"The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'." +3368,tcParenThenAdjacentListArgumentReserved,"The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'." +3368,tcListThenAdjacentListArgumentReserved,"The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'." +3368,tcOtherThenAdjacentListArgumentReserved,"The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'." +3369,tcParenThenAdjacentListArgumentNeedsAdjustment,"The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'." +3369,tcListThenAdjacentListArgumentNeedsAdjustment,"The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'." +3369,tcOtherThenAdjacentListArgumentNeedsAdjustment,"The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'." +3370,chkInfoRefcellDeref,"The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'." +3370,chkInfoRefcellAssign,"The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'." +3370,chkInfoRefcellIncr,"The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'." +3370,chkInfoRefcellDecr,"The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'." +forFormatInvalidForInterpolated,"Interpolated strings may not use '%%' format specifiers unless each is given an expression, e.g. '%%d{{1+1}}'." +forFormatInvalidForInterpolated2,".NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%%' format specifiers." +forFormatInvalidForInterpolated3,"The '%%P' specifier may not be used explicitly." +forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable or type FormattableString may not use '%%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used." +3371,tcInterpolationMixedWithPercent,"Mismatch in interpolated string. Interpolated strings may not use '%%' format specifiers unless each is given an expression, e.g. '%%d{{1+1}}'" +3372,tcInvalidAlignmentInInterpolatedString,"Invalid alignment in interpolated string" +3373,lexSingleQuoteInSingleQuote,"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal." +3374,lexTripleQuoteInTripleQuote,"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression." +3376,tcUnableToParseInterpolatedString,"Invalid interpolated string. %s" +3377,lexByteStringMayNotBeInterpolated,"a byte string may not be interpolated" +3378,parsEofInInterpolatedStringFill,"Incomplete interpolated string expression fill begun at or before here" +3379,parsEofInInterpolatedString,"Incomplete interpolated string begun at or before here" +3380,parsEofInInterpolatedVerbatimString,"Incomplete interpolated verbatim string begun at or before here" +3381,parsEofInInterpolatedTripleQuoteString,"Incomplete interpolated triple-quote string begun at or before here" +3382,parsEmptyFillInInterpolatedString,"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected." +3383,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string." +3384,scriptSdkNotDetermined,"The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '%s --version' in the directory '%s' was: '%s' and the exit code was '%d'." +3384,scriptSdkNotDeterminedUnexpected,"The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '%s'." +3384,scriptSdkNotDeterminedNoHost,"The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed." +3385,tcInvalidStructReturn,"The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions" +3387,tcAmbiguousImplicitConversion,"This expression has type '%s' and is only made compatible with type '%s' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:%s" +3388,tcSubsumptionImplicitConversionUsed,"This expression implicitly converts type '%s' to type '%s'. See https://aka.ms/fsharp-implicit-convs." +3389,tcBuiltInImplicitConversionUsed,"This expression uses a built-in implicit conversion to convert type '%s' to type '%s'. See https://aka.ms/fsharp-implicit-convs." +3390,tcImplicitConversionUsedForMethodArg,"This expression uses the implicit conversion '%s' to convert type '%s' to type '%s'." +3391,tcImplicitConversionUsedForNonMethodArg,"This expression uses the implicit conversion '%s' to convert type '%s' to type '%s'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\"." +#3501 "This construct is not supported by your version of the F# compiler" CompilerMessage(ExperimentalAttributeMessages.NotSupportedYet, 3501, IsError=true) +3390,xmlDocBadlyFormed,"This XML comment is invalid: '%s'" +3390,xmlDocMissingParameterName,"This XML comment is invalid: missing 'name' attribute for parameter or parameter reference" +3390,xmlDocMissingCrossReference,"This XML comment is invalid: missing 'cref' attribute for cross-reference" +3390,xmlDocInvalidParameterName,"This XML comment is invalid: unknown parameter '%s'" +3390,xmlDocDuplicateParameter,"This XML comment is invalid: multiple documentation entries for parameter '%s'" +3390,xmlDocUnresolvedCrossReference,"This XML comment is invalid: unresolved cross-reference '%s'" +3390,xmlDocMissingParameter,"This XML comment is incomplete: no documentation for parameter '%s'" +3391,tcLiteralAttributeCannotUseActivePattern,"A [] declaration cannot use an active pattern for its identifier" +3392,containerDeprecated,"The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead." +3393,containerSigningUnsupportedOnThisPlatform,"Key container signing is not supported on this platform." +3401,ilxgenInvalidConstructInStateMachineDuringCodegen,"The resumable code construct '%s' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code." +3402,tcInvalidResumableConstruct,"The construct '%s' may only be used in valid resumable code." +3501,tcResumableCodeFunctionMustBeInline,"Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'" +3501,tcResumableCodeArgMustHaveRightName,"Invalid resumable code. Resumable code parameter must have name beginning with '__expand'" +3501,tcResumableCodeArgMustHaveRightKind,"Invalid resumable code. A resumable code parameter must be of delegate or function type" +3501,tcResumableCodeContainsLetRec,"Invalid resumable code. A 'let rec' occured in the resumable code specification" +3510,tcResumableCodeNotSupported,"Using resumable code or resumable state machines requires /langversion:preview" +3511,reprStateMachineNotCompilable,"This state machine is not statically compilable. %s. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning." +3512,reprStateMachineNotCompilableNoAlternative,"This state machine is not statically compilable and no alternative is available. %s. Use an 'if __useResumableCode then else ' to give an alternative." +3513,tcResumableCodeInvocation,"Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code." +reprResumableCodeInvokeNotReduced,"A resumable code invocation at '%s' could not be reduced" +reprResumableCodeContainsLetRec,"A 'let rec' occured in the resumable code specification" +reprResumableCodeContainsDynamicResumeAtInBody,"A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method" +reprResumableCodeContainsResumptionInTryFinally,"A try/finally may not contain resumption points" +reprResumableCodeContainsResumptionInHandlerOrFilter,"The 'with' block of a try/with may not contain resumption points" +reprResumableCodeContainsFastIntegerForLoop,"A fast integer for loop may not contain resumption points" +reprResumableCodeValueHasNoDefinition,"The resumable code value(s) '%s' does not have a definition" +reprResumableCodeDefinitionWasGeneric,"A delegate or function producing resumable code in a state machine has type parameters" +reprStateMachineInvalidForm,"The state machine has an unexpected form" +3517,optFailedToInlineSuggestedValue,"The value '%s' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only." +3518,implMissingInlineIfLambda,"The 'InlineIfLambda' attribute is present in the signature but not the implementation." +3519,tcInlineIfLambdaUsedOnNonInlineFunctionOrMethod,"The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type." diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx index cf3d3c92b29..bf1c66b0f29 100644 --- a/src/fsharp/FSStrings.resx +++ b/src/fsharp/FSStrings.resx @@ -154,14 +154,11 @@ Type constraint mismatch. The type \n '{0}' \nis not compatible with type\n '{1}' {2}\n - Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. + Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. Discriminated union cases and exception labels must be uppercase identifiers - - Possible overload: '{0}'. {1}. - This function takes too many arguments, or is used in a context where a function is not expected @@ -444,6 +441,18 @@ keyword 'fixed' + + interpolated string + + + interpolated string (first part) + + + interpolated string (part) + + + interpolated string (final part) + keyword 'constraint' @@ -564,6 +573,9 @@ keyword 'and' + ! + keyword 'and!' + keyword 'as' @@ -1068,6 +1080,9 @@ Assembly reference '{0}' was not found or is invalid + + One or more informational messages in loaded file.\n + One or more warnings in loaded file.\n diff --git a/src/fsharp/FSharp.Build/FSBuild.txt b/src/fsharp/FSharp.Build/FSBuild.txt index 47d1ee7431d..b429a789bdc 100644 --- a/src/fsharp/FSharp.Build/FSBuild.txt +++ b/src/fsharp/FSharp.Build/FSBuild.txt @@ -1,3 +1,6 @@ # FSharp.Build resource strings toolpathUnknown,"ToolPath is unknown; specify the path to the tool." -fSharpBannerVersion,"%s for F# %s" +mapSourceRootsContainsDuplicate,"SourceRoot contains duplicate items '%s' with conflicting metadata '%s': '%s' and '%s'" +mapSourceRootsPathMustEndWithSlashOrBackslash,"SourceRoot paths are required to end with a slash or backslash: '%s'" +mapSourceRootsNoTopLevelSourceRoot,"SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true" +mapSourceRootsNoSuchTopLevelSourceRoot,"The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '%s'" \ No newline at end of file diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj index cc91a603606..3999f24600b 100644 --- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj +++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj @@ -4,21 +4,21 @@ Library - $(ProtoTargetFramework) - net472;netcoreapp3.0 - netcoreapp3.0 + netstandard2.0 + netstandard2.0 FSharp.Build - $(NoWarn);45;55;62;75;1204 + $(NoWarn);75 true - $(OtherFlags) --maxerrors:20 --extraoptimizationloops:1 - true $(DefineConstants);LOCALIZATION_FSBUILD + NU1701;FS0075 + true - + + @@ -27,29 +27,35 @@ + Microsoft.FSharp.NetSdk.props {{FSharpCoreShippedPackageVersion}} - $(FSharpCoreShippedPackageVersion) + $(FSharpCoreShippedPackageVersionProperty) {{FSharpCorePreviewPackageVersion}} $(FSharpCorePreviewPackageVersion) + {{FSCorePackageVersion}} + $(FSCorePackageVersion) - - + + + - - + + - diff --git a/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs b/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs index 3428d60ad8f..1a8efbe5b66 100644 --- a/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs +++ b/src/fsharp/FSharp.Build/FSharpEmbedResourceText.fs @@ -29,7 +29,7 @@ type FSharpEmbedResourceText() = let xmlBoilerPlateString = @" - + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -52,10 +53,8 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and $(TargetsForTfmSpecificContentInPackage);PackageFSharpDesignTimeTools - - - $(DefaultFSharpCorePreviewPackageVersion) - $(RestoreSources); https://dotnet.myget.org/F/fsharp/api/v3/index.json + + $(RestoreAdditionalProjectSources);https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json @@ -66,17 +65,6 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and - - - - Pkg$([System.String]::Copy('%(ResolvedCompileFileDefinitions.NugetPackageId)').Replace('.','_')) - $(%(EnhancedResolvedFile.PackageRootProperty))\content\%(ResolvedCompileFileDefinitions.FileName)%(ResolvedCompileFileDefinitions.Extension).fsx - - - - fsharp41 @@ -103,27 +91,107 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and $(FSharpToolsDirectory)/$(FSharpDesignTimeProtocol)/%(_ResolvedOutputFiles.NearestTargetFramework)/%(_ResolvedOutputFiles.FileName)%(_ResolvedOutputFiles.Extension) - + + + + + + true + + + + + + + + <_MappedSourceRoot Remove="@(_MappedSourceRoot)" /> + + + + + - - - - + + - - - - Pkg$([System.String]::Copy('%(ResolvedCompileFileDefinitions.NugetPackageId)').Replace('.','_')) - $(%(FsxResolvedFile.PackageRootProperty)) - $(%(FsxResolvedFile.PackageRootProperty))\content\%(ResolvedCompileFileDefinitions.FileName)%(ResolvedCompileFileDefinitions.Extension).fsx - - + + + true + + + + + + + + + + + <_TopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"> + $([MSBuild]::ValueOrDefault('%(Identity)', '').Replace(',', ',,').Replace('=', '==')) + $([MSBuild]::ValueOrDefault('%(MappedPath)', '').Replace(',', ',,').Replace('=', '==')) + + + + + + @(_TopLevelSourceRoot->'%(EscapedKey)=%(EscapedValue)', ','),$(PathMap) + diff --git a/src/fsharp/FSharp.Build/Microsoft.FSharp.Overrides.NetSdk.targets b/src/fsharp/FSharp.Build/Microsoft.FSharp.Overrides.NetSdk.targets index ce837dbf213..fd2e3569f09 100644 --- a/src/fsharp/FSharp.Build/Microsoft.FSharp.Overrides.NetSdk.targets +++ b/src/fsharp/FSharp.Build/Microsoft.FSharp.Overrides.NetSdk.targets @@ -29,6 +29,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and + diff --git a/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets b/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets index 5453eb96389..e8a9a7ecf1e 100644 --- a/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets +++ b/src/fsharp/FSharp.Build/Microsoft.FSharp.Targets @@ -187,6 +187,7 @@ this file. + @@ -198,11 +199,11 @@ this file. + - @@ -266,6 +267,7 @@ this file. + @@ -326,6 +328,8 @@ this file. VisualStudioStyleErrors="$(VisualStudioStyleErrors)" WarningLevel="$(WarningLevel)" WarningsAsErrors="$(WarningsAsErrors)" + WarnOn="$(WarnOn)" + Win32IconFile ="$(ApplicationIcon)" Win32ManifestFile="$(Win32Manifest)" Win32ResourceFile="$(Win32Resource)"> @@ -412,10 +416,10 @@ this file. ContinueOnError="true" Overwrite="true"/> - - + + + <_FsGeneratedTfmAttributesSource Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" /> - + + $([System.String]::new('%(Reference.HintPath)').EndsWith('$(_OldRefAssemTPLocation)', System.StringComparison.OrdinalIgnoreCase))" /> - - - - $(NewFSharpCompilerLocation)FSharp.Data.TypeProviders.dll - - - - + $([System.String]::new('%(Reference.HintPath)').EndsWith('$(_OldSdkTPLocationSuffix)', System.StringComparison.OrdinalIgnoreCase))" /> - $(NewFSharpCompilerLocation)FSharp.Data.TypeProviders.dll - - diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.cs.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.cs.xlf index e34a840079e..f3957078a6d 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.cs.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.cs.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} pro F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot obsahuje duplicitní položky {0} s konfliktními metadaty {1}: {2} a {3} + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Hodnota SourceRoot.ContainingRoot nebyla v položkách SourceRoot nalezena nebo odpovídající položka není zdrojový kořen nejvyšší úrovně: {0} + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Pokud má DeterministicSourcePaths hodnotu true, položky SourceRoot musí zahrnovat nejméně jednu položku nejvyšší úrovně (nevnořenou). + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Cesty SourceRoot musí končit lomítkem nebo zpětným lomítkem: {0} diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.de.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.de.xlf index 8014aa45590..477037aa75c 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.de.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.de.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} für F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot enthält doppelte Elemente "{0}" mit widersprüchlichen Metadaten "{1}": "{2}" und "{3}" + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Der Wert von "SourceRoot.ContainingRoot" wurde in SourceRoot-Elementen nicht gefunden, oder das entsprechende Element ist kein Quellstamm der obersten Ebene: {0} + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + SourceRoot-Elemente müssen mindestens ein Element der obersten Ebene (nicht geschachtelt) enthalten, wenn "DeterministicSourcePaths" auf TRUE festgelegt ist. + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + SourceRoot-Pfade müssen mit einem Schrägstrich oder einem umgekehrten Schrägstrich enden: {0} diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.es.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.es.xlf index e70e526aa75..6b05b744965 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.es.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.es.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} para F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot contiene elementos "{0}" duplicados con metadatos en conflicto "{1}": "{2}" y "{3}" + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + No se encontró el valor de SourceRoot.ContainingRoot en los elementos SourceRoot o el elemento correspondiente no es una raíz de origen de nivel superior: "{0}" + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Los elementos SourceRoot deben incluir al menos un elemento de nivel superior (no anidado) cuando DeterministicSourcePaths es verdadero. + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Se requiere que las rutas de acceso SourceRoot finalicen con una barra diagonal o una barra diagonal inversa: "{0}" diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.fr.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.fr.xlf index 967ceecc6e4..ec8548c8bfb 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.fr.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.fr.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} pour F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot contient des éléments en double '{0}' avec des métadonnées '{1}' en conflit : '{2}' et '{3}' + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + La valeur de SourceRoot.ContainingRoot est introuvable dans les éléments SourceRoot, ou l'élément correspondant n'est pas une racine source de niveau supérieur : '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Les éléments SourceRoot doivent inclure au moins un élément de niveau supérieur (non imbriqué) quand DeterministicSourcePaths a la valeur true + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Les chemins SourceRoot doivent finir par une barre oblique ou une barre oblique inverse : '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.it.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.it.xlf index a0c02bd7658..437de29bead 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.it.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.it.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} per F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot contiene elementi duplicati '{0}' con metadati in conflitto '{1}': '{2}' e '{3}' + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Il valore di SourceRoot.ContainingRoot non è stato trovato negli elementi SourceRoot oppure l'elemento corrispondente non è una radice di origine di primo livello: '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Quando DeterministicSourcePaths è true, gli elementi SourceRoot devono includere almeno un elemento di primo livello (non annidato) + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + I percorsi di SourceRoot devono terminare con una barra o una barra rovesciata: '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ja.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ja.xlf index 558d9a4705d..37ca2edfd14 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ja.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ja.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - F# {1} のための {0} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot に、競合するメタデータ '{1}': '{2}' および '{3}' を持つ重複する項目 '{0}' が含まれています + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + SourceRoot.ContainingRoot の値が SourceRoot 項目にないか、対応する項目が最上位ソース ルートではありません: '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + DeterministicSourcePaths が true の場合、SourceRoot 項目には (入れ子になっていない) 最上位項目が少なくとも 1 つ必要です + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + SourceRoot パスの最後はスラッシュまたはバックスラッシュでなければなりません: '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ko.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ko.xlf index d007db16c3c..39c759776fe 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ko.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ko.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - F# {1}용 {0} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot에 충돌하는 메타데이터 '{1}': '{2}' 및 '{3}'이(가) 포함된 중복 항목 '{0}'이(가) 있습니다. + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + SourceRoot.ContainingRoot 값을 SourceRoot 항목에서 찾을 수 없거나 해당 항목이 최상위 소스 루트가 아닙니다. '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + SourceRoot 항목은 DeterministicSourcePaths가 true인 경우 최상위(중첩되지 않은) 항목을 하나 이상 포함해야 합니다. + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + SourceRoot 경로는 슬래시 또는 백슬래시로 끝나야 합니다. '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pl.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pl.xlf index 565fdd2b8d2..32fdb5b663f 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pl.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pl.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} dla języka F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot zawiera zduplikowane elementy "{0}" z metadanymi powodującymi konflikt "{1}": "{2}" i "{3}" + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Nie odnaleziono wartości SourceRoot.ContainingRoot w elementach SourceRoot bądź odpowiadający element nie jest źródłowym elementem głównym najwyższego poziomu: „{0}” + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Elementy SourceRoot muszą zawierać co najmniej jeden niezagnieżdżony element najwyższego poziomu, gdy właściwość DeterministicSourcePaths ma wartość true + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Ścieżki elementów SourceRoot muszą kończyć się ukośnikiem lub ukośnikiem odwrotnym: „{0}” diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pt-BR.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pt-BR.xlf index 2d6ac4cf6ca..9bce840006f 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pt-BR.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.pt-BR.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} para F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + O SourceRoot contém itens duplicados '{0}' com metadados conflitantes '{1}': '{2}' e '{3}' + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Valor de SourceRoot.ContainingRoot não foi encontrado em itens SourceRoot ou o item correspondente não é uma raiz de origem de nível superior: '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Os itens SourceRoot precisarão incluir pelo menos um item de nível superior (não aninhado) quando DeterministicSourcePaths for true + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Os caminhos SourceRoot precisam terminar com uma barra ou uma barra invertida: '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ru.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ru.xlf index 23dc6215bd4..3c9144d4669 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ru.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.ru.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - {0} для F# {1} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot содержит повторяющиеся элементы "{0}" с конфликтующими метаданными "{1}": "{2}" и "{3}" + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + Значение объекта SourceRoot.ContainingRoot не найдено в элементах SourceRoot, либо соответствующий элемент не является исходным корнем верхнего уровня: "{0}" + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + Элементы SourceRoot должны включать по меньшей мере один элемент верхнего уровня (невложенный), когда DeterministicSourcePaths имеет значение "true" + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + Пути SourceRoot должны заканчиваться прямой или обратной косой чертой: "{0}" diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.tr.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.tr.xlf index b56fc715900..088c2835935 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.tr.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.tr.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - F# {1} için {0} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot, çakışan '{1}' meta verilerine sahip yinelenen '{0}' öğeleri içeriyor: '{2}' ve '{3}' + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + SourceRoot.ContainingRoot değeri, SourceRoot öğelerinde bulunamadı veya karşılık gelen öğe, üst düzey kaynak kökü değil: '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + DeterministicSourcePaths true olduğunda SourceRoot öğeleri en az bir üst düzey (iç içe geçmemiş) öğe içermelidir + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + SourceRoot yolunun sonunda eğik çizgi veya ters eğik çizgi olması gerekir: '{0}' diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hans.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hans.xlf index f514600395d..0b59943b8c8 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hans.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hans.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - F# {1} 的 {0} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot 包含重复项“{0}”,其元数据“{1}”存在冲突:“{2}”和“{3}” + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + 未在 SourceRoot 项中找到 SourceRoot.ContainingRoot 的值,或者对应项不是顶级源根目录:“{0}” + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + 当 DeterministicSourcePaths 为 true 时,SourceRoot 项必须包括至少一个顶级(未嵌套)项 + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + 要求 SourceRoot 路径以斜杠或反斜杠结尾:“{0}” diff --git a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hant.xlf b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hant.xlf index e3f63746fa4..b64cea9c947 100644 --- a/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hant.xlf +++ b/src/fsharp/FSharp.Build/xlf/FSBuild.txt.zh-Hant.xlf @@ -2,9 +2,24 @@ - - {0} for F# {1} - F # {1} 的 {0} + + SourceRoot contains duplicate items '{0}' with conflicting metadata '{1}': '{2}' and '{3}' + SourceRoot 包含具有衝突之中繼資料 '{1}' 的重複項目 '{0}': '{2}' 及 '{3}' + + + + The value of SourceRoot.ContainingRoot was not found in SourceRoot items, or the corresponding item is not a top-level source root: '{0}' + SourceRoot 項目中找不到 SourceRoot.ContainingRoot 的值,或相對應的項目不是最上層來源根目錄: '{0}' + + + + SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true + 在 DeterministicSourcePaths 為 true 的情況下,SourceRoot 項目必須包含至少一個最上層 (非巢狀) 項目 + + + + SourceRoot paths are required to end with a slash or backslash: '{0}' + SourceRoot 路徑必須以斜線或反斜線作為結尾: '{0}' diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj index 75af428f4f1..950d3294e9d 100644 --- a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj +++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj @@ -4,13 +4,9 @@ Library - net472;netstandard2.0 - netstandard2.0 + netstandard2.0 FSharp.Compiler.Interactive.Settings - $(NoWarn);45;55;62;75;1182;1204 true - $(OtherFlags) --maxerrors:20 --extraoptimizationloops:1 - true diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.proj b/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.proj deleted file mode 100644 index d02ae419bc4..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.proj +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - $(MSBuildThisFileDirectory)FSharp.Compiler.LanguageServer.DesignTime.targets - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.targets b/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.targets deleted file mode 100644 index ea8f3e28664..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.DesignTime.targets +++ /dev/null @@ -1,52 +0,0 @@ - - - - - true - false - true - true - false - false - false - true - false - true - false - - - - - - - _ComputeTargetFrameworkItems - _PopulateTargetFrameworks - - - - - <_TargetFramework Include="$(TargetFramework)" /> - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj b/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj deleted file mode 100644 index 0bb08991405..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/FSharp.Compiler.LanguageServer.fsproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - - Exe - .exe - net472;netcoreapp3.0 - netcoreapp3.0 - true - Implements the Language Server Protocol (LSP) for F#. - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_PublishedProjectOutputGroupFiles Include="$(PublishDir)\**" /> - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs b/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs deleted file mode 100644 index ae8575195dd..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/JsonDUConverter.fs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System -open FSharp.Reflection -open Newtonsoft.Json - -type JsonDUConverter() = - inherit JsonConverter() - override __.CanConvert(typ) = FSharpType.IsUnion(typ) - override __.WriteJson(writer, value, _serializer) = - writer.WriteValue(value.ToString().ToLowerInvariant()) - override __.ReadJson(reader, typ, x, serializer) = - let cases = FSharpType.GetUnionCases(typ) - let str = serializer.Deserialize(reader, typeof) :?> string - let case = cases |> Array.find (fun c -> String.Compare(c.Name, str, StringComparison.OrdinalIgnoreCase) = 0) - FSharpValue.MakeUnion(case, [||]) diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs b/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs deleted file mode 100644 index 937dda00e46..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/JsonOptionConverter.fs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System -open FSharp.Reflection -open Newtonsoft.Json - -type JsonOptionConverter() = - inherit JsonConverter() - override __.CanConvert(typ) = typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof> - override __.WriteJson(writer, value, serializer) = - let value = match value with - | null -> null - | _ -> - let _, fields = FSharpValue.GetUnionFields(value, value.GetType()) - fields.[0] - serializer.Serialize(writer, value) - override __.ReadJson(reader, typ, _, serializer) = - let innerType = typ.GetGenericArguments().[0] - let innerType = - if innerType.IsValueType then (typedefof>).MakeGenericType([|innerType|]) - else innerType - let value = serializer.Deserialize(reader, innerType) - let cases = FSharpType.GetUnionCases(typ) - if value = null then FSharpValue.MakeUnion(cases.[0], [||]) - else FSharpValue.MakeUnion(cases.[1], [|value|]) diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/LspExternalAccess.fs b/src/fsharp/FSharp.Compiler.LanguageServer/LspExternalAccess.fs deleted file mode 100644 index 48e4b0b4051..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/LspExternalAccess.fs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open StreamJsonRpc - -[] -module FunctionNames = - [] - let OptionsSet = "options/set" - - [] - let TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics" - -type Options = - { usePreviewTextHover: bool - usePreviewDiagnostics: bool } - static member Default() = - { usePreviewTextHover = false - usePreviewDiagnostics = false } - static member AllOn() = - { usePreviewTextHover = true - usePreviewDiagnostics = true } - -module Extensions = - type JsonRpc with - member jsonRpc.SetOptionsAsync (options: Options) = - async { - do! jsonRpc.InvokeAsync(OptionsSet, options) |> Async.AwaitTask - } diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/LspTypes.fs b/src/fsharp/FSharp.Compiler.LanguageServer/LspTypes.fs deleted file mode 100644 index 264e526fcd2..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/LspTypes.fs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open Newtonsoft.Json.Linq -open Newtonsoft.Json - -// Interfaces as defined at https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/. -// The properties on these types are camlCased to match the underlying JSON properties to avoid attributes on every -// field: -// [] - -/// Represents a zero-based line and column of a text document. -type Position = - { line: int - character: int } - -type Range = - { start: Position - ``end``: Position } - -type DocumentUri = string - -type Location = - { uri: DocumentUri - range: Range } - -type DiagnosticRelatedInformation = - { location: Location - message: string } - -type Diagnostic = - { range: Range - severity: int option - code: string - source: string option - message: string - relatedInformation: DiagnosticRelatedInformation[] option } - static member Error = 1 - static member Warning = 2 - static member Information = 3 - static member Hint = 4 - -type PublishDiagnosticsParams = - { uri: DocumentUri - diagnostics: Diagnostic[] } - -type ClientCapabilities = - { workspace: JToken option // TODO: WorkspaceClientCapabilities - textDocument: JToken option // TODO: TextDocumentClientCapabilities, publishDiagnostics: { relatedInformation: bool option } - experimental: JToken option - supportsVisualStudioExtensions: bool option } - -[)>] -type Trace = - | Off - | Messages - | Verbose - -type WorkspaceFolder = - { uri: DocumentUri - name: string } - -/// Note, this type has many more optional values that can be expanded as support is added. -type ServerCapabilities = - { hoverProvider: bool } - static member DefaultCapabilities() = - { ServerCapabilities.hoverProvider = true } - -type InitializeResult = - { capabilities: ServerCapabilities } - -[)>] -type MarkupKind = - | PlainText - | Markdown - -type MarkupContent = - { kind: MarkupKind - value: string } - -type Hover = - { contents: MarkupContent - range: Range option } - -type TextDocumentIdentifier = - { uri: DocumentUri } diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/Methods.fs b/src/fsharp/FSharp.Compiler.LanguageServer/Methods.fs deleted file mode 100644 index 453b7f82280..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/Methods.fs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System -open System.Runtime.InteropServices -open System.Threading -open Newtonsoft.Json.Linq -open StreamJsonRpc - -// https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/ -type Methods() = - - let state = State() - - /// Helper to run Async<'T> with a CancellationToken. - let runAsync (cancellationToken: CancellationToken) (computation: Async<'T>) = Async.StartAsTask(computation, cancellationToken=cancellationToken) - - member __.State = state - - //-------------------------------------------------------------------------- - // official LSP methods - //-------------------------------------------------------------------------- - - [] - member __.Initialize - ( - processId: Nullable, - [] rootPath: string, - [] rootUri: DocumentUri, - [] initializationOptions: JToken, - capabilities: ClientCapabilities, - [] trace: string, - [] workspaceFolders: WorkspaceFolder[], - [] cancellationToken: CancellationToken - ) = - state.Initialize rootPath rootUri (fun projectOptions -> TextDocument.PublishDiagnostics(state, projectOptions) |> Async.Start) - { InitializeResult.capabilities = ServerCapabilities.DefaultCapabilities() } - - [] - member __.Initialized () = () - - [] - member __.Shutdown(): obj = state.DoShutdown(); null - - [] - member __.Exit() = state.DoExit() - - [] - member __.cancelRequest (id: JToken) = state.DoCancel() - - [] - member __.TextDocumentHover - ( - textDocument: TextDocumentIdentifier, - position: Position, - [] cancellationToken: CancellationToken - ) = - TextDocument.Hover state textDocument position |> runAsync cancellationToken - - //-------------------------------------------------------------------------- - // unofficial LSP methods that we implement separately - //-------------------------------------------------------------------------- - - [] - member __.OptionsSet - ( - options: Options - ) = - eprintfn "got options %A" options - state.Options <- options - state.InvalidateAllProjects() diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/Program.fs b/src/fsharp/FSharp.Compiler.LanguageServer/Program.fs deleted file mode 100644 index 13d0c9709fb..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/Program.fs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System - -module Program = - - [] - let main(args: string[]) = - async { - let server = new Server(Console.OpenStandardOutput(), Console.OpenStandardInput()) - server.StartListening() - do! server.WaitForExitAsync() - return 0 - } |> Async.RunSynchronously diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/Server.fs b/src/fsharp/FSharp.Compiler.LanguageServer/Server.fs deleted file mode 100644 index 28d5e49a583..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/Server.fs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System -open System.IO -open StreamJsonRpc - -type Server(sendingStream: Stream, receivingStream: Stream) = - - let formatter = JsonMessageFormatter() - let converter = JsonOptionConverter() // special handler to convert between `Option<'T>` and `obj/null`. - do formatter.JsonSerializer.Converters.Add(converter) - let handler = new HeaderDelimitedMessageHandler(sendingStream, receivingStream, formatter) - let methods = Methods() - let rpc = new JsonRpc(handler, methods) - do methods.State.JsonRpc <- Some rpc - - member __.StartListening() = - rpc.StartListening() - - member __.WaitForExitAsync() = - async { - do! Async.AwaitEvent (methods.State.Shutdown) - do! Async.AwaitEvent (methods.State.Exit) - } - - interface IDisposable with - member __.Dispose() = - rpc.Dispose() diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/State.fs b/src/fsharp/FSharp.Compiler.LanguageServer/State.fs deleted file mode 100644 index 0812bb9a7f7..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/State.fs +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System -open System.Collections.Concurrent -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.Text.RegularExpressions -open FSharp.Compiler.SourceCodeServices -open StreamJsonRpc - -module internal Solution = - // easy unit testing - let getProjectPaths (solutionContent: string) (solutionDir: string) = - // This looks scary, but is much more lightweight than carrying along MSBuild just to have it parse the solution file. - // - // A valid line in .sln looks like: - // Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ConsoleApp2", "ConsoleApp2\ConsoleApp2.fsproj", "{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}" - // and we're hoping to extract this: ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // - // therefore: - // ^Project text 'Project' at the start of the line - // .* any number of characters - // \"" double quote character (it's doubled up to escape from the raw string literal here) - // ( start of capture group - // [^\""] not a quote - // * many of those - // \.fsproj literal string ".fsproj" - // ) end of capture group - // \"" double quote - let pattern = Regex(@"^Project.*\""([^\""]*\.fsproj)\""") - let lines = solutionContent.Split('\n') - let relativeProjects = - lines - |> Array.map pattern.Match - |> Array.filter (fun m -> m.Success) - |> Array.map (fun m -> m.Groups.[1].Value) - // .sln files by convention uses backslashes, which might not be appropriate at runtime - |> Array.map (fun p -> p.Replace('\\', Path.DirectorySeparatorChar)) - let projects = - relativeProjects - |> Array.map (fun p -> if Path.IsPathRooted(p) then p else Path.Combine(solutionDir, p)) - projects - -type State() = - - let checker = FSharpChecker.Create() - - let sourceFileToProjectMap = ConcurrentDictionary() - - let shutdownEvent = new Event<_>() - let exitEvent = new Event<_>() - let cancelEvent = new Event<_>() - let projectInvalidatedEvent = new Event<_>() - - let fileChanged (args: FileSystemEventArgs) = - match sourceFileToProjectMap.TryGetValue args.FullPath with - | true, projectOptions -> projectInvalidatedEvent.Trigger(projectOptions) - | false, _ -> () - let fileRenamed (args: RenamedEventArgs) = - match sourceFileToProjectMap.TryGetValue args.FullPath with - | true, projectOptions -> projectInvalidatedEvent.Trigger(projectOptions) - | false, _ -> () - let fileWatcher = new FileSystemWatcher() - do fileWatcher.IncludeSubdirectories <- true - do fileWatcher.Changed.Add(fileChanged) - do fileWatcher.Created.Add(fileChanged) - do fileWatcher.Deleted.Add(fileChanged) - do fileWatcher.Renamed.Add(fileRenamed) - - let execProcess (name: string) (args: string) = - let startInfo = ProcessStartInfo(name, args) - eprintfn "executing: %s %s" name args - startInfo.CreateNoWindow <- true - startInfo.RedirectStandardOutput <- true - startInfo.UseShellExecute <- false - let lines = List() - use proc = new Process() - proc.StartInfo <- startInfo - proc.OutputDataReceived.Add(fun args -> lines.Add(args.Data)) - proc.Start() |> ignore - proc.BeginOutputReadLine() - proc.WaitForExit() - lines.ToArray() - - let linesWithPrefixClean (prefix: string) (lines: string[]) = - lines - |> Array.filter (isNull >> not) - |> Array.map (fun line -> line.TrimStart(' ')) - |> Array.filter (fun line -> line.StartsWith(prefix)) - |> Array.map (fun line -> line.Substring(prefix.Length)) - - let getProjectOptions (rootDir: string) = - if isNull rootDir then [||] - else - fileWatcher.Path <- rootDir - fileWatcher.EnableRaisingEvents <- true - - /// This function is meant to be temporary. Until we figure out what a language server for a project - /// system looks like, we have to guess based on the files we find in the root. - let getProjectOptions (projectPath: string) = - let projectDir = Path.GetDirectoryName(projectPath) - let normalizePath (path: string) = - if Path.IsPathRooted(path) then path - else Path.Combine(projectDir, path) - - // To avoid essentially re-creating a copy of MSBuild alongside this tool, we instead fake a design- - // time build with this project. The output of building this helper project is text that's easily - // parsable. See the helper project for more information. - let reporterProject = Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "FSharp.Compiler.LanguageServer.DesignTime.proj") - let detectedTfmSentinel = "DetectedTargetFramework=" - let detectedCommandLineArgSentinel = "DetectedCommandLineArg=" - - let execTfmReporter = - sprintf "build \"%s\" \"/p:ProjectFile=%s\"" reporterProject projectPath - |> execProcess "dotnet" - - let execArgReporter (tfm: string) = - sprintf "build \"%s\" \"/p:ProjectFile=%s\" \"/p:TargetFramework=%s\"" reporterProject projectPath tfm - |> execProcess "dotnet" - - // find the target frameworks - let targetFrameworks = - execTfmReporter - |> linesWithPrefixClean detectedTfmSentinel - - let getArgs (tfm: string) = - execArgReporter tfm - |> linesWithPrefixClean detectedCommandLineArgSentinel - - let tfmAndArgs = - targetFrameworks - |> Array.map (fun tfm -> tfm, getArgs tfm) - - let separateArgs (args: string[]) = - args - |> Array.partition (fun a -> a.StartsWith("-")) - |> (fun (options, files) -> - let normalizedFiles = files |> Array.map normalizePath - options, normalizedFiles) - - // TODO: for now we're only concerned with the first TFM - let _tfm, args = Array.head tfmAndArgs - - let otherOptions, sourceFiles = separateArgs args - - let projectOptions: FSharpProjectOptions = - { ProjectFileName = projectPath - ProjectId = None - SourceFiles = sourceFiles - OtherOptions = otherOptions - ReferencedProjects = [||] // TODO: populate from @(ProjectReference) - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime.Now - UnresolvedReferences = None - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = None } - projectOptions - let topLevelProjects = Directory.GetFiles(rootDir, "*.fsproj") - let watchableProjectPaths = - match topLevelProjects with - | [||] -> - match Directory.GetFiles(rootDir, "*.sln") with - // TODO: what to do with multiple .sln or a combo of .sln/.fsproj? - | [| singleSolution |] -> - let content = File.ReadAllText(singleSolution) - let solutionDir = Path.GetDirectoryName(singleSolution) - Solution.getProjectPaths content solutionDir - | _ -> [||] - | _ -> topLevelProjects - let watchableProjectOptions = - watchableProjectPaths - |> Array.map getProjectOptions - - // associate source files with project options - let watchFile file projectOptions = - sourceFileToProjectMap.AddOrUpdate(file, projectOptions, fun _ _ -> projectOptions) - - for projectOptions in watchableProjectOptions do - // watch .fsproj - watchFile projectOptions.ProjectFileName projectOptions |> ignore - // TODO: watch .deps.json - for sourceFile in projectOptions.SourceFiles do - let sourceFileFullPath = - if Path.IsPathRooted(sourceFile) then sourceFile - else - let projectDir = Path.GetDirectoryName(projectOptions.ProjectFileName) - Path.Combine(projectDir, sourceFile) - watchFile sourceFileFullPath projectOptions |> ignore - - watchableProjectOptions - - member __.Checker = checker - - /// Initialize the LSP at the specified location. According to the spec, `rootUri` is to be preferred over `rootPath`. - member __.Initialize (rootPath: string) (rootUri: DocumentUri) (computeDiagnostics: FSharpProjectOptions -> unit) = - let rootDir = - if not (isNull rootUri) then Uri(rootUri).LocalPath - else rootPath - let projectOptions = getProjectOptions rootDir - projectInvalidatedEvent.Publish.Add computeDiagnostics // compute diagnostics on project invalidation - for projectOption in projectOptions do - computeDiagnostics projectOption // compute initial set of diagnostics - - [] - member __.Shutdown = shutdownEvent.Publish - - [] - member __.Exit = exitEvent.Publish - - [] - member __.Cancel = cancelEvent.Publish - - [] - member __.ProjectInvalidated = projectInvalidatedEvent.Publish - - member __.DoShutdown() = shutdownEvent.Trigger() - - member __.DoExit() = exitEvent.Trigger() - - member __.DoCancel() = cancelEvent.Trigger() - - member __.InvalidateAllProjects() = - for projectOptions in sourceFileToProjectMap.Values do - projectInvalidatedEvent.Trigger(projectOptions) - - member val Options = Options.Default() with get, set - - member val JsonRpc: JsonRpc option = None with get, set diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/TextDocument.fs b/src/fsharp/FSharp.Compiler.LanguageServer/TextDocument.fs deleted file mode 100644 index 489b55ebce1..00000000000 --- a/src/fsharp/FSharp.Compiler.LanguageServer/TextDocument.fs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer - -open System.Threading - -module TextDocument = - - let mutable publishDiagnosticsCancellationTokenSource = new CancellationTokenSource() - - let Hover (state: State) (textDocument: TextDocumentIdentifier) (position: Position) = - async { - eprintfn "hover at %d, %d" position.line position.character - if not state.Options.usePreviewTextHover then return None - else - let startCol, endCol = - if position.character = 0 then 0, 1 - else position.character, position.character + 1 - return Some { contents = { kind = MarkupKind.PlainText - value = "serving textDocument/hover from LSP" } - range = Some { start = { line = position.line; character = startCol } - ``end`` = { line = position.line; character = endCol } } - } - } - - let PublishDiagnostics(state: State, projectOptions: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions) = - // TODO: honor TextDocumentClientCapabilities.publishDiagnostics.relatedInformation - // cancel any existing request to publish diagnostics - publishDiagnosticsCancellationTokenSource.Cancel() - publishDiagnosticsCancellationTokenSource <- new CancellationTokenSource() - async { - if not state.Options.usePreviewDiagnostics then return () - else - eprintfn "starting diagnostics computation" - match state.JsonRpc with - | None -> eprintfn "state.JsonRpc was null; should not be?" - | Some jsonRpc -> - let! results = state.Checker.ParseAndCheckProject projectOptions - let diagnostics = results.Errors - let diagnosticsPerFile = - diagnostics - |> Array.fold (fun state t -> - let existing = Map.tryFind t.FileName state |> Option.defaultValue [] - Map.add t.FileName (t :: existing) state) Map.empty - for sourceFile in projectOptions.SourceFiles do - let diagnostics = - Map.tryFind sourceFile diagnosticsPerFile - |> Option.defaultValue [] - |> List.map (fun d -> - // F# errors count lines starting at 1, but LSP starts at 0 - let range: Range = - { start = { line = d.StartLineAlternate - 1; character = d.StartColumn } - ``end`` = { line = d.EndLineAlternate - 1; character = d.EndColumn } } - let severity = - match d.Severity with - | FSharp.Compiler.SourceCodeServices.FSharpErrorSeverity.Warning -> Diagnostic.Warning - | FSharp.Compiler.SourceCodeServices.FSharpErrorSeverity.Error -> Diagnostic.Error - let res: Diagnostic = - { range = range - severity = Some severity - code = "FS" + d.ErrorNumber.ToString("0000") - source = Some d.FileName - message = d.Message - relatedInformation = None } - res) - |> List.toArray - let args: PublishDiagnosticsParams = - { uri = System.Uri(sourceFile).AbsoluteUri - diagnostics = diagnostics } - - // fire each notification separately - jsonRpc.NotifyAsync(TextDocumentPublishDiagnostics, args) |> Async.AwaitTask |> Async.Start - } - |> (fun computation -> Async.StartAsTask(computation, cancellationToken=publishDiagnosticsCancellationTokenSource.Token)) - |> Async.AwaitTask diff --git a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.fsproj b/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.fsproj deleted file mode 100644 index 8a49e311df8..00000000000 --- a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.fsproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - netstandard2.0 - true - Provides embedding F# language scripting. - FSharp.Compiler.Private.Scripting.nuspec - true - - - - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.nuspec b/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.nuspec deleted file mode 100644 index 42a7c538eb2..00000000000 --- a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharp.Compiler.Private.Scripting.nuspec +++ /dev/null @@ -1,24 +0,0 @@ - - - - $CommonMetadataElements$ - en-US - - - - - - - $CommonFileElements$ - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharpScript.fs b/src/fsharp/FSharp.Compiler.Private.Scripting/FSharpScript.fs deleted file mode 100644 index 9417cca120d..00000000000 --- a/src/fsharp/FSharp.Compiler.Private.Scripting/FSharpScript.fs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.Scripting - -open System -open System.Threading -open FSharp.Compiler -open FSharp.Compiler.Interactive.Shell - -type FSharpScript(?additionalArgs: string[]) = - - let additionalArgs = defaultArg additionalArgs [||] - let config = FsiEvaluationSession.GetDefaultConfiguration() - let computedProfile = - // If we are being executed on the desktop framework (we can tell because the assembly containing int is mscorlib) then profile must be mscorlib otherwise use netcore - if typeof.Assembly.GetName().Name = "mscorlib" then "mscorlib" - else "netcore" - let baseArgs = [| typeof.Assembly.Location; "--noninteractive"; "--targetprofile:" + computedProfile; "--quiet" |] - let argv = Array.append baseArgs additionalArgs - let fsi = FsiEvaluationSession.Create (config, argv, stdin, stdout, stderr) - - [] - member __.AssemblyReferenceAdded = fsi.AssemblyReferenceAdded - - member __.ValueBound = fsi.ValueBound - - [] - member __.IncludePathAdded = fsi.IncludePathAdded - - [] - member __.DependencyAdding = fsi.DependencyAdding - - [] - member __.DependencyAdded = fsi.DependencyAdded - - [] - member __.DependencyFailed = fsi.DependencyFailed - - member __.Fsi = fsi - - member __.Eval(code: string, ?cancellationToken: CancellationToken) = - let cancellationToken = defaultArg cancellationToken CancellationToken.None - let ch, errors = fsi.EvalInteractionNonThrowing(code, cancellationToken) - match ch with - | Choice1Of2 v -> Ok(v), errors - | Choice2Of2 ex -> Error(ex), errors - - /// Get the available completion items from the code at the specified location. - /// - /// The input text on which completions will be calculated - /// The 1-based line index - /// The 0-based column index - member __.GetCompletionItems(text: string, line: int, column: int) = - async { - let! parseResults, checkResults, _projectResults = fsi.ParseAndCheckInteraction(text) - let lineText = text.Split('\n').[line - 1] - let partialName = QuickParse.GetPartialLongNameEx(lineText, column - 1) - let! declarationListInfos = checkResults.GetDeclarationListInfo(Some parseResults, line, lineText, partialName) - return declarationListInfos.Items - } - - interface IDisposable with - member __.Dispose() = - (fsi :> IDisposable).Dispose() diff --git a/src/fsharp/FSharp.Compiler.Private/.gitignore b/src/fsharp/FSharp.Compiler.Private/.gitignore deleted file mode 100644 index fa6bb93f549..00000000000 --- a/src/fsharp/FSharp.Compiler.Private/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -illex.fs -ilpars.fs -ilpars.fsi -lex.fs -pars.fs -pars.fsi -pplex.fs -pppars.fs -pppars.fsi diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj deleted file mode 100644 index 8710d929be5..00000000000 --- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj +++ /dev/null @@ -1,748 +0,0 @@ - - - - - - Library - net472;netstandard2.0 - netstandard2.0 - FSharp.Compiler.Private - $(NoWarn);45;55;62;75;1204 - true - $(DefineConstants);COMPILER - $(DefineConstants);MSBUILD_AT_LEAST_15 - $(DefineConstants);LOCALIZATION_FCOMP - $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 - true - - - - - $(BaseOutputPath)\$(Configuration)\$(TargetFramework) - - - - - - - - - - - - - - - - - - - - - - - - - - FSComp.txt - - - FSStrings.resx - - - Logger.fsi - - - Logger.fs - - - ErrorText\sformat.fsi - - - ErrorText\sformat.fs - - - ErrorText\sr.fsi - - - ErrorText\sr.fs - - - Driver\LanguageFeatures.fsi - - - Driver\LanguageFeatures.fs - - - LexYaccRuntime\prim-lexing.fsi - - - LexYaccRuntime\prim-lexing.fs - - - LexYaccRuntime\prim-parsing.fsi - - - LexYaccRuntime\prim-parsing.fs - - - Utilities\ResizeArray.fsi - - - Utilities\ResizeArray.fs - - - Utilities\HashMultiMap.fsi - - - Utilities\HashMultiMap.fs - - - Utilities\EditDistance.fs - - - Utilities\TaggedCollections.fsi - - - Utilities\TaggedCollections.fs - - - Utilities\ildiag.fsi - - - Utilities\ildiag.fs - - - Utilities\illib.fs - - - Utilities\filename.fsi - - - Utilities\filename.fs - - - Utilities\zmap.fsi - - - Utilities\zmap.fs - - - Utilities\zset.fsi - - - Utilities\zset.fs - - - Utilities\bytes.fsi - - - Utilities\bytes.fs - - - Utilities\XmlAdapters.fs - - - Utilities\InternalCollections.fsi - - - Utilities\InternalCollections.fs - - - Utilities\QueueList.fs - - - Utilities\lib.fs - - - Utilities\rational.fsi - - - Utilities\rational.fs - - - Utilities\PathMap.fsi - - - Utilities\PathMap.fs - - - ErrorLogging\range.fsi - - - ErrorLogging\range.fs - - - ErrorLogging\ErrorLogger.fs - - - ErrorLogging\ErrorResolutionHints.fs - - - --unicode --lexlib Internal.Utilities.Text.Lexing - AbsIL\illex.fsl - - - --module FSharp.Compiler.AbstractIL.Internal.AsciiParser --open FSharp.Compiler.AbstractIL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - AbsIL\ilpars.fsy - - - AbsIL\il.fsi - - - AbsIL\il.fs - - - AbsIL\ilx.fsi - - - AbsIL\ilx.fs - - - AbsIL\ilascii.fsi - - - AbsIL\ilascii.fs - - - AbsIL\ilprint.fsi - - - AbsIL\ilprint.fs - - - AbsIL\ilmorph.fsi - - - AbsIL\ilmorph.fs - - - AbsIL\ilsign.fs - - - AbsIL\ilnativeres.fsi - - - AbsIL\ilnativeres.fs - - - AbsIL\ilsupp.fsi - - - AbsIL\ilsupp.fs - - - AbsIL\ilpars.fs - - - AbsIL\illex.fs - - - AbsIL\ilbinary.fsi - - - AbsIL\ilbinary.fs - - - AbsIL\ilread.fsi - - - AbsIL\ilread.fs - - - AbsIL\ilwritepdb.fsi - - - AbsIL\ilwritepdb.fs - - - AbsIL\ilwrite.fsi - - - AbsIL\ilwrite.fs - - - AbsIL\ilreflect.fs - - - ReferenceResolution\ReferenceResolver.fs - - - ReferenceResolution/reshapedmsbuild.fs - - - - ReferenceResolution/LegacyMSBuildReferenceResolver.fsi - - - ReferenceResolution/LegacyMSBuildReferenceResolver.fs - - - - ReferenceResolution/SimulatedMSBuildReferenceResolver.fs - - - CompilerLocation\CompilerLocationUtils.fs - - - PrettyNaming\PrettyNaming.fs - - - ILXErase\ilxsettings.fs - - - ILXErase\EraseClosures.fsi - - - ILXErase\EraseClosures.fs - - - ILXErase\EraseUnions.fsi - - - ILXErase\EraseUnions.fs - - - --unicode --lexlib Internal.Utilities.Text.Lexing - ParserAndUntypedAST\pplex.fsl - - - --module FSharp.Compiler.PPParser --open FSharp.Compiler --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - ParserAndUntypedAST\pppars.fsy - - - --unicode --lexlib Internal.Utilities.Text.Lexing - ParserAndUntypedAST\lex.fsl - - - --module FSharp.Compiler.Parser --open FSharp.Compiler --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing - ParserAndUntypedAST\pars.fsy - - - ParserAndUntypedAST\UnicodeLexing.fsi - - - ParserAndUntypedAST\UnicodeLexing.fs - - - ParserAndUntypedAST\layout.fsi - - - ParserAndUntypedAST\layout.fs - - - ParserAndUntypedAST\ast.fs - - - ParserAndUntypedAST\pppars.fs - - - ParserAndUntypedAST\pars.fs - - - ParserAndUntypedAST\lexhelp.fsi - - - ParserAndUntypedAST\lexhelp.fs - - - ParserAndUntypedAST\pplex.fs - - - ParserAndUntypedAST\lex.fs - - - ParserAndUntypedAST\lexfilter.fs - - - TypedAST\tainted.fsi - - - TypedAST\tainted.fs - - - TypedAST\ExtensionTyping.fsi - - - TypedAST\ExtensionTyping.fs - - - TypedAST\QuotationPickler.fsi - - - TypedAST\QuotationPickler.fs - - - TypedAST\CompilerGlobalState.fs - - - TypedAST\tast.fs - - - TypedAST\TcGlobals.fs - - - TypedAST\TastOps.fsi - - - TypedAST\TastOps.fs - - - TypedAST\TastPickle.fsi - - - TypedAST\TastPickle.fs - - - Logic\import.fsi - - - Logic\import.fs - - - Logic\infos.fs - - - Logic\AccessibilityLogic.fs - - - Logic\AttributeChecking.fs - - - Logic\InfoReader.fs - - - Logic\NicePrint.fs - - - Logic\AugmentWithHashCompare.fsi - - - Logic\AugmentWithHashCompare.fs - - - Logic\NameResolution.fsi - - - Logic\NameResolution.fs - - - Logic\TypeRelations.fs - - - Logic\SignatureConformance.fs - - - Logic\MethodOverrides.fs - - - Logic\MethodCalls.fs - - - Logic\PatternMatchCompilation.fsi - - - Logic\PatternMatchCompilation.fs - - - Logic\ConstraintSolver.fsi - - - Logic\ConstraintSolver.fs - - - Logic\CheckFormatStrings.fsi - - - Logic\CheckFormatStrings.fs - - - Logic\FindUnsolved.fsi - - - Logic\FindUnsolved.fs - - - Logic\QuotationTranslator.fsi - - - Logic\QuotationTranslator.fs - - - Logic\PostInferenceChecks.fsi - - - Logic\PostInferenceChecks.fs - - - Logic\TypeChecker.fsi - - - Logic\TypeChecker.fs - - - Optimize\Optimizer.fsi - - - Optimize\Optimizer.fs - - - Optimize\DetupleArgs.fsi - - - Optimize\DetupleArgs.fs - - - Optimize\InnerLambdasToTopLevelFuncs.fsi - - - Optimize\InnerLambdasToTopLevelFuncs.fs - - - Optimize\LowerCallsAndSeqs.fsi - - - Optimize\LowerCallsAndSeqs.fs - - - Optimize\autobox.fsi - - - Optimize\autobox.fs - - - CodeGen\IlxGen.fsi - - - CodeGen\IlxGen.fs - - - - Driver\DotNetFrameworkDependencies.fs - - - Driver\DependencyManager.Integration.fsi - - - Driver\DependencyManager.Integration.fs - - - Driver\CompileOps.fsi - - - Driver\CompileOps.fs - - - Driver\CompileOptions.fsi - - - Driver\CompileOptions.fs - - - Driver\fsc.fsi - - - Driver\fsc.fs - - - - - Symbols/SymbolHelpers.fsi - - - Symbols/SymbolHelpers.fs - - - Symbols/Symbols.fsi - - - Symbols/Symbols.fs - - - Symbols/Exprs.fsi - - - Symbols/Exprs.fs - - - Symbols/SymbolPatterns.fsi - - - Symbols/SymbolPatterns.fs - - - Service/Reactor.fsi - - - Service/Reactor.fs - - - - - Service/IncrementalBuild.fsi - - - Service/IncrementalBuild.fs - - - Service/ServiceCompilerDiagnostics.fsi - - - Service/ServiceCompilerDiagnostics.fs - - - Service/ServiceConstants.fs - - - Service/ServiceDeclarationLists.fsi - - - Service/ServiceDeclarationLists.fs - - - Service/ServiceLexing.fsi - - - Service/ServiceLexing.fs - - - Service/ServiceParseTreeWalk.fs - - - Service/ServiceNavigation.fsi - - - Service/ServiceNavigation.fs - - - Service/ServiceParamInfoLocations.fsi - - - Service/ServiceParamInfoLocations.fs - - - Service/ServiceUntypedParse.fsi - - - Service/ServiceUntypedParse.fs - - - Service/ServiceAssemblyContent.fsi - - - Service/ServiceAssemblyContent.fs - - - Service/ServiceXmlDocParser.fsi - - - Service/ServiceXmlDocParser.fs - - - Service/SimulatedMSBuildReferenceResolver.fs - - - Service/ExternalSymbol.fsi - - - Service/ExternalSymbol.fs - - - Service/QuickParse.fsi - - - Service/QuickParse.fs - - - Service/FSharpCheckerResults.fsi - - - Service/FSharpCheckerResults.fs - - - Service/service.fsi - - - Service/service.fs - - - Service/ServiceErrorResolutionHints.fsi - - - Service/ServiceErrorResolutionHints.fs - - - Service/ServiceInterfaceStubGenerator.fsi - - - Service/ServiceInterfaceStubGenerator.fs - - - Service/ServiceStructure.fsi - - - Service/ServiceStructure.fs - - - Service/ServiceAnalysis.fsi - - - Service/ServiceAnalysis.fs - - - - - FSIstrings.txt - - - InteractiveSession/fsi.fsi - - - InteractiveSession/fsi.fs - - - - Misc/LegacyHostedCompilerForTesting.fs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.netcore.nuspec b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.netcore.nuspec deleted file mode 100644 index 9fb4c25cf40..00000000000 --- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.netcore.nuspec +++ /dev/null @@ -1,42 +0,0 @@ - - - - FSharp.Compiler.Private.netcore - - .NET Core compatible version of the fsharp compiler service dll - Supported Platforms: - .NET Core (netstandard2.0) - - en-US - true - $version$ - $authors$ - $licenseUrl$ - $projectUrl$ - $tags$ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj index 75a7353bb96..8241f891960 100644 --- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj +++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj @@ -3,7 +3,6 @@ - true net472 FSharp.Compiler.Server.Shared true diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharpInteractiveServer.fs b/src/fsharp/FSharp.Compiler.Server.Shared/FSharpInteractiveServer.fs index 60da7a58c0f..eca486f48cc 100644 --- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharpInteractiveServer.fs +++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharpInteractiveServer.fs @@ -27,10 +27,6 @@ open System.Runtime.Remoting.Lifetime type internal FSharpInteractiveServer() = inherit System.MarshalByRefObject() abstract Interrupt : unit -> unit -#if FSI_SERVER_INTELLISENSE - abstract Completions : prefix:string -> string array - abstract GetDeclarations : text:string * names:string array -> (string * string * string * int) array -#endif default x.Interrupt() = () [] diff --git a/src/fsharp/FSharp.Compiler.Service/Directory.Build.props b/src/fsharp/FSharp.Compiler.Service/Directory.Build.props new file mode 100644 index 00000000000..fe085e2ed50 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Service/Directory.Build.props @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj new file mode 100644 index 00000000000..1c52a5464dd --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -0,0 +1,1010 @@ + + + + + + net472;netstandard2.0 + Library + $(NoWarn);44 + $(NoWarn);57 + $(NoWarn);75 + $(NoWarn);1204 + $(NoWarn);NU5125 + FSharp.Compiler.Service + true + $(DefineConstants);COMPILER + $(DefineConstants);ENABLE_MONO_SUPPORT + $(OtherFlags) /warnon:3218 /warnon:1182 /warnon:3390 --extraoptimizationloops:1 --times + true + $(IntermediateOutputPath)$(TargetFramework)\ + $(IntermediateOutputPath)$(TargetFramework)\ + + + + $(IntermediateOutputPath)$(TargetFramework)\ + $(IntermediateOutputPath)$(TargetFramework)\ + + + + FSharp.Compiler.Service + FSharp.Compiler.Service.nuspec + true + The F# Compiler Services package For F# $(FSLanguageVersion) exposes additional functionality for implementing F# language bindings, additional tools based on the compiler or refactoring tools. The package also includes F# interactive service that can be used for embedding F# scripting into your applications. Contains code from the F# Software Foundation. + /blob/main/release-notes.md#FSharp-Compiler-Service-$(FSharpCompilerServiceReleaseNotesVersion) + F#, fsharp, interactive, compiler, editor + preview + $(MSBuildThisFileDirectory)logo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FSComp.txt + + + FSIstrings.txt + + + FSStrings.resx + FSStrings.resources + + + ErrorText\sformat.fsi + + + ErrorText\sformat.fs + + + ErrorText\sr.fsi + + + ErrorText\sr.fs + + + Facilities\Logger.fsi + + + Facilities\Logger.fs + + + Facilities\LanguageFeatures.fsi + + + Facilities\LanguageFeatures.fs + + + Utilities\ResizeArray.fsi + + + Utilities\ResizeArray.fs + + + Utilities\HashMultiMap.fsi + + + Utilities\HashMultiMap.fs + + + Utilities\EditDistance.fsi + + + Utilities\EditDistance.fs + + + Utilities\TaggedCollections.fsi + + + Utilities\TaggedCollections.fs + + + Utilities\illib.fsi + + + Utilities\illib.fs + + + Utilities\FileSystem.fsi + + + Utilities\FileSystem.fs + + + Utilities\ildiag.fsi + + + Utilities\ildiag.fs + + + Utilities\zmap.fsi + + + Utilities\zmap.fs + + + Utilities\zset.fsi + + + Utilities\zset.fs + + + Utilities\XmlAdapters.fsi + + + Utilities\XmlAdapters.fs + + + Utilities\InternalCollections.fsi + + + Utilities\InternalCollections.fs + + + Utilities\QueueList.fsi + + + Utilities\QueueList.fs + + + Utilities\lib.fsi + + + Utilities\lib.fs + + + Utilities\block.fsi + + + Utilities\block.fs + + + Utilities\rational.fsi + + + Utilities\rational.fs + + + Utilities\PathMap.fsi + + + Utilities\PathMap.fs + + + Utilities\RidHelpers.fs + + + ErrorLogging\range.fsi + + + ErrorLogging\range.fs + + + ErrorLogging\Diagnostics.fsi + + + ErrorLogging\Diagnostics.fs + + + ErrorLogging\TextLayoutRender.fsi + + + ErrorLogging\TextLayoutRender.fs + + + ErrorLogging\ErrorLogger.fsi + + + ErrorLogging\ErrorLogger.fs + + + ErrorLogging\ErrorResolutionHints.fsi + + + ErrorLogging\ErrorResolutionHints.fs + + + LexYaccRuntime\prim-lexing.fsi + + + LexYaccRuntime\prim-lexing.fs + + + LexYaccRuntime\prim-parsing.fsi + + + LexYaccRuntime\prim-parsing.fs + + + --unicode --lexlib Internal.Utilities.Text.Lexing + AbsIL\illex.fsl + + + AbsIL\illex.fsl + + + --module FSharp.Compiler.AbstractIL.AsciiParser --open FSharp.Compiler.AbstractIL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing + AbsIL\ilpars.fsy + + + AbsIL\FsYacc\ilpars.fsy + + + AbsIL\il.fsi + + + AbsIL\il.fs + + + AbsIL\ilx.fsi + + + AbsIL\ilx.fs + + + AbsIL\ilascii.fsi + + + AbsIL\ilascii.fs + + + AbsIL\FsYaccOut\ilpars.fs + + + AbsIL\FsLexOut\illex.fs + + + AbsIL\ilprint.fsi + + + AbsIL\ilprint.fs + + + AbsIL\ilmorph.fsi + + + AbsIL\ilmorph.fs + + + AbsIL\ilsign.fsi + + + AbsIL\ilsign.fs + + + AbsIL\ilnativeres.fsi + + + AbsIL\ilnativeres.fs + + + AbsIL\ilsupp.fsi + + + AbsIL\ilsupp.fs + + + AbsIL\ilbinary.fsi + + + AbsIL\ilbinary.fs + + + AbsIL\ilread.fsi + + + AbsIL\ilread.fs + + + AbsIL\ilwritepdb.fsi + + + AbsIL\ilwritepdb.fs + + + AbsIL\ilwrite.fsi + + + AbsIL\ilwrite.fs + + + AbsIL\ilreflect.fsi + + + AbsIL\ilreflect.fs + + + ReferenceResolution\ReferenceResolver.fsi + + + ReferenceResolution\ReferenceResolver.fs + + + + ReferenceResolution/LegacyMSBuildReferenceResolver.fsi + + + ReferenceResolution/LegacyMSBuildReferenceResolver.fs + + + ReferenceResolution/SimulatedMSBuildReferenceResolver.fsi + + + ReferenceResolution/SimulatedMSBuildReferenceResolver.fs + + + + CompilerLocation\CompilerLocationUtils.fsi + + + CompilerLocation\CompilerLocationUtils.fs + + + PrettyNaming\PrettyNaming.fsi + + + PrettyNaming\PrettyNaming.fs + + + ILXErase\EraseClosures.fsi + + + ILXErase\EraseClosures.fs + + + ILXErase\EraseUnions.fsi + + + ILXErase\EraseUnions.fs + + + --unicode --lexlib Internal.Utilities.Text.Lexing + ParserAndUntypedAST\pplex.fsl + + + --module FSharp.Compiler.PPParser --open FSharp.Compiler --open FSharp.Compiler.Syntax --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing + ParserAndUntypedAST\pppars.fsy + + + --unicode --lexlib Internal.Utilities.Text.Lexing + ParserAndUntypedAST\lex.fsl + + + -v --module FSharp.Compiler.Parser --open FSharp.Compiler --open FSharp.Compiler.Syntax --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing + ParserAndUntypedAST\pars.fsy + + + ParserAndUntypedAST\FsLex\pplex.fsl + + + ParserAndUntypedAST\FsLex\lex.fsl + + + ParserAndUntypedAST\FsYacc\pppars.fsy + + + ParserAndUntypedAST\FsYacc\pars.fsy + + + ParserAndUntypedAST\UnicodeLexing.fsi + + + ParserAndUntypedAST\UnicodeLexing.fs + + + ParserAndUntypedAST\XmlDoc.fsi + + + ParserAndUntypedAST\XmlDoc.fs + + + ParserAndUntypedAST\SyntaxTree.fsi + + + ParserAndUntypedAST\SyntaxTree.fs + + + ParserAndUntypedAST\SyntaxTreeOps.fsi + + + ParserAndUntypedAST\SyntaxTreeOps.fs + + + ParserAndUntypedAST\ParseHelpers.fsi + + + ParserAndUntypedAST\ParseHelpers.fs + + + ParserAndUntypedAST\FsYaccOutput\pppars.fs + + + ParserAndUntypedAST\FsYaccOutput\pars.fs + + + ParserAndUntypedAST\lexhelp.fsi + + + ParserAndUntypedAST\lexhelp.fs + + + ParserAndUntypedAST\FsLexOutput\pplex.fs + + + ParserAndUntypedAST\FsLexOutput\lex.fs + + + ParserAndUntypedAST\LexFilter.fsi + + + ParserAndUntypedAST\LexFilter.fs + + + TypedTree\tainted.fsi + + + TypedTree\tainted.fs + + + TypedTree\ExtensionTyping.fsi + + + TypedTree\ExtensionTyping.fs + + + TypedTree\QuotationPickler.fsi + + + TypedTree\QuotationPickler.fs + + + TypedTree\CompilerGlobalState.fsi + + + TypedTree\CompilerGlobalState.fs + + + TypedTree\TypedTree.fs + + + TypedTree\TypedTreeBasics.fsi + + + TypedTree\TypedTreeBasics.fs + + + TypedTree\TcGlobals.fs + + + TypedTree\TypedTreeOps.fsi + + + TypedTree\TypedTreeOps.fs + + + TypedTree\TypedTreePickle.fsi + + + TypedTree\TypedTreePickle.fs + + + Logic\import.fsi + + + Logic\import.fs + + + Logic\infos.fsi + + + Logic\infos.fs + + + Logic\AccessibilityLogic.fsi + + + Logic\AccessibilityLogic.fs + + + Logic\AttributeChecking.fsi + + + Logic\AttributeChecking.fs + + + Logic\TypeRelations.fsi + + + Logic\TypeRelations.fs + + + Logic\InfoReader.fsi + + + Logic\InfoReader.fs + + + Logic\NicePrint.fsi + + + Logic\NicePrint.fs + + + Logic\AugmentWithHashCompare.fsi + + + Logic\AugmentWithHashCompare.fs + + + Logic\NameResolution.fsi + + + Logic\NameResolution.fs + + + Logic\SignatureConformance.fsi + + + Logic\SignatureConformance.fs + + + Logic\MethodOverrides.fsi + + + Logic\MethodOverrides.fs + + + Logic\MethodCalls.fsi + + + Logic\MethodCalls.fs + + + Logic\PatternMatchCompilation.fsi + + + Logic\PatternMatchCompilation.fs + + + Logic\ConstraintSolver.fsi + + + Logic\ConstraintSolver.fs + + + Logic\CheckFormatStrings.fsi + + + Logic\CheckFormatStrings.fs + + + Logic\FindUnsolved.fsi + + + Logic\FindUnsolved.fs + + + Logic\QuotationTranslator.fsi + + + Logic\QuotationTranslator.fs + + + Logic\PostInferenceChecks.fsi + + + Logic\PostInferenceChecks.fs + + + Logic\CheckExpressions.fsi + + + Logic\CheckExpressions.fs + + + Logic\CheckComputationExpressions.fsi + + + Logic\CheckComputationExpressions.fs + + + Logic\CheckDeclarations.fsi + + + Logic\CheckDeclarations.fs + + + Optimize\Optimizer.fsi + + + Optimize\Optimizer.fs + + + Optimize\DetupleArgs.fsi + + + Optimize\DetupleArgs.fs + + + Optimize\InnerLambdasToTopLevelFuncs.fsi + + + Optimize\InnerLambdasToTopLevelFuncs.fs + + + Optimize\LowerCallsAndSeqs.fsi + + + Optimize\LowerCallsAndSeqs.fs + + + Optimize\LowerStateMachines.fsi + + + Optimize\LowerStateMachines.fs + + + Optimize\autobox.fsi + + + Optimize\autobox.fs + + + CodeGen\IlxGen.fsi + + + CodeGen\IlxGen.fs + + + Driver\FxResolver.fs + + + Driver\AssemblyResolveHandler.fsi + + + Driver\AssemblyResolveHandler.fs + + + Driver\NativeDllResolveHandler.fsi + + + Driver\NativeDllResolveHandler.fs + + + Driver\DependencyProvider.fsi + + + Driver\DependencyProvider.fs + + + Driver\BuildGraph.fsi + + + Driver\BuildGraph.fs + + + Driver\CompilerConfig.fsi + + + Driver\CompilerConfig.fs + + + Driver\CompilerImports.fsi + + + Driver\CompilerImports.fs + + + Driver\CompilerDiagnostics.fsi + + + Driver\CompilerDiagnostics.fs + + + Driver\ParseAndCheckInputs.fsi + + + Driver\ParseAndCheckInputs.fs + + + Driver\ScriptClosure.fsi + + + Driver\ScriptClosure.fs + + + Driver\CompilerOptions.fsi + + + Driver\CompilerOptions.fs + + + Driver\OptimizeInputs.fsi + + + Driver\OptimizeInputs.fs + + + Driver\XmlDocFileWriter.fsi + + + Driver\XmlDocFileWriter.fs + + + Driver\BinaryResourceFormats.fsi + + + Driver\BinaryResourceFormats.fs + + + Driver\StaticLinking.fsi + + + Driver\StaticLinking.fs + + + Driver\CreateILModule.fsi + + + Driver\CreateILModule.fs + + + Driver\fsc.fsi + + + Driver\fsc.fs + + + + + Symbols/SymbolHelpers.fsi + + + Symbols/SymbolHelpers.fs + + + Symbols/Symbols.fsi + + + Symbols/Symbols.fs + + + Symbols/Exprs.fsi + + + Symbols/Exprs.fs + + + Symbols/SymbolPatterns.fsi + + + Symbols/SymbolPatterns.fs + + + + + Service/SemanticClassification.fsi + + + Service/SemanticClassification.fs + + + Service/ItemKey.fsi + + + Service/ItemKey.fs + + + Service/SemanticClassificationKey.fsi + + + Service/SemanticClassificationKey.fs + + + Service/IncrementalBuild.fsi + + + Service/IncrementalBuild.fs + + + Service/ServiceCompilerDiagnostics.fsi + + + Service/ServiceCompilerDiagnostics.fs + + + Service/ServiceConstants.fs + + + Service/ServiceDeclarationLists.fsi + + + Service/ServiceDeclarationLists.fs + + + Service/ServiceLexing.fsi + + + Service/ServiceLexing.fs + + + Service/ServiceParseTreeWalk.fsi + + + Service/ServiceParseTreeWalk.fs + + + Service/ServiceNavigation.fsi + + + Service/ServiceNavigation.fs + + + Service/ServiceParamInfoLocations.fsi + + + Service/ServiceParamInfoLocations.fs + + + Service/FSharpParseFileResults.fsi + + + Service/FSharpParseFileResults.fs + + + Service/ServiceParsedInputOps.fsi + + + Service/ServiceParsedInputOps.fs + + + Service/ServiceAssemblyContent.fsi + + + Service/ServiceAssemblyContent.fs + + + Service/ServiceXmlDocParser.fsi + + + Service/ServiceXmlDocParser.fs + + + Service/ExternalSymbol.fsi + + + Service/ExternalSymbol.fs + + + Service/QuickParse.fsi + + + Service/QuickParse.fs + + + Service/FSharpCheckerResults.fsi + + + Service/FSharpCheckerResults.fs + + + Service/service.fsi + + + Service/service.fs + + + Service/ServiceInterfaceStubGenerator.fsi + + + Service/ServiceInterfaceStubGenerator.fs + + + Service/ServiceStructure.fsi + + + Service/ServiceStructure.fs + + + Service/ServiceAnalysis.fsi + + + Service/ServiceAnalysis.fs + + + InteractiveSession/fsi.fsi + + + InteractiveSession/fsi.fs + + + + + Misc/LegacyHostedCompilerForTesting.fs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.nuspec b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.nuspec new file mode 100644 index 00000000000..065f1cdb31c --- /dev/null +++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.nuspec @@ -0,0 +1,50 @@ + + + + $CommonMetadataElements$ + en-US + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $CommonFileElements$ + + + + + + + + + + + + diff --git a/fcs/misc/logo.png b/src/fsharp/FSharp.Compiler.Service/logo.png similarity index 100% rename from fcs/misc/logo.png rename to src/fsharp/FSharp.Compiler.Service/logo.png diff --git a/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props b/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props deleted file mode 100644 index 7cd41381b5d..00000000000 --- a/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - true - - - - - diff --git a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj deleted file mode 100644 index 6c0d52fd849..00000000000 --- a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - true - netcoreapp3.0 - Microsoft.FSharp.Compiler.nuspec - true - .NET Core compatible version of the F# compiler fsc.exe. - - - - - TargetFramework=netcoreapp3.0 - - - TargetFramework=netcoreapp3.0 - - - TargetFramework=netcoreapp3.0 - - - TargetFramework=netstandard2.0 - - - - - - diff --git a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.nuspec b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.nuspec deleted file mode 100644 index 94a727bbcce..00000000000 --- a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.nuspec +++ /dev/null @@ -1,73 +0,0 @@ - - - - $CommonMetadataElements$ - en-US - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $CommonFileElements$ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj b/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj deleted file mode 100644 index 4bc3e61c164..00000000000 --- a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuget.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - true - net45;netstandard2.0 - FSharp.Core - FSharp.Core.nuspec - true - FSharp.Core redistributables from Visual F# Tools version $(FSPackageMajorVersion) For F# $(FSCoreMajorVersion). Contains code from the F# Software Foundation. - - - - - false - - - - - - diff --git a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuspec b/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuspec deleted file mode 100644 index e7f9bcb7da2..00000000000 --- a/src/fsharp/FSharp.Core.nuget/FSharp.Core.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - $CommonMetadataElements$ - en-US - - - - - - - $CommonFileElements$ - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.Core.nuget/Directory.Build.props b/src/fsharp/FSharp.Core/Directory.Build.props similarity index 100% rename from src/fsharp/FSharp.Core.nuget/Directory.Build.props rename to src/fsharp/FSharp.Core/Directory.Build.props diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj index 360dc74e37e..6b1e945d68f 100644 --- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj +++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj @@ -1,18 +1,41 @@ - + Library - net45;netstandard2.0 - netstandard2.0 - $(NoWarn);45;55;62;75;1204 + netstandard2.1;netstandard2.0 + $(NoWarn);62 + $(NoWarn);75 + $(NoWarn);1204 true $(DefineConstants);FSHARP_CORE BUILDING_WITH_LKG;$(DefineConstants) - $(OtherFlags) --warnon:1182 --compiling-fslib --compiling-fslib-40 --maxerrors:20 --extraoptimizationloops:1 --nowarn:57 - true + + $(OtherFlags) --warnon:3218 + + $(OtherFlags) --warnon:1182 + + $(OtherFlags) --warnon:3390 + + $(OtherFlags) --nowarn:57 + + + $(OtherFlags) --nowarn:3511 --nowarn:3513 + $(OtherFlags) --compiling-fslib --compiling-fslib-40 --maxerrors:100 --extraoptimizationloops:1 + + preview + + true true + + true + FSharp.Core + $(FSCorePackageVersion) + FSharp.Core.nuspec + true + FSharp.Core redistributables from F# Tools version $(FSCorePackageVersion) For F# $(FSLanguageVersion). Contains code from the F# Software Foundation. + /blob/main/release-notes.md#FSharp-Core-$(FSCoreReleaseNotesVersion) @@ -125,10 +148,10 @@ Numerics/z.fs - + Printf/sformat.fsi - + Printf/sformat.fs @@ -155,12 +178,24 @@ Control/event.fs + + Control/resumable.fsi + + + Control/resumable.fs + Control/async.fsi Control/async.fs + + Control/tasks.fsi + + + Control/tasks.fs + Control/eventmodule.fsi @@ -179,6 +214,12 @@ MailboxProcessor/mailbox.fs + + Queries/Nullable.fsi + + + Queries/Nullable.fs + Queries/Linq.fsi @@ -214,17 +255,13 @@ - - - - - + + + $(BaseOutputPath)\$(Configuration)\$(TargetFramework) + - - + - - diff --git a/src/fsharp/FSharp.Core/FSharp.Core.nuspec b/src/fsharp/FSharp.Core/FSharp.Core.nuspec new file mode 100644 index 00000000000..4efa4c5c661 --- /dev/null +++ b/src/fsharp/FSharp.Core/FSharp.Core.nuspec @@ -0,0 +1,31 @@ + + + + $CommonMetadataElements$ + en-US + + + + + + + + + + $CommonFileElements$ + + + + + + + + + + + + + + + + diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index fb9432075c4..8bc7fcf5615 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -1,150 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -#nowarn "1204" - -namespace Microsoft.FSharp.Linq - - -open Microsoft.FSharp -open Microsoft.FSharp.Collections -open Microsoft.FSharp.Core -open Microsoft.FSharp.Core.Operators -open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - -module NullableOperators = - open System - let (?>=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value >= y - - let (?>) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value > y - - let (?<=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value <= y - - let (?<) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value < y - - let (?=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value = y - - let (?<>) (x : Nullable<'T>) (y: 'T) = not (x ?= y) - - let (>=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x >= y.Value - - let (>?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x > y.Value - - let (<=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x <= y.Value - - let () = y.HasValue && x < y.Value - - let (=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x = y.Value - - let (<>?) (x : 'T) (y: Nullable<'T>) = not (x =? y) - - let (?>=?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value >= y.Value) - - let (?>?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value > y.Value) - - let (?<=?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value <= y.Value) - - let (?) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value < y.Value) - - let (?=?) (x : Nullable<'T>) (y: Nullable<'T>) = (not x.HasValue && not y.HasValue) || (x.HasValue && y.HasValue && x.Value = y.Value) - - let (?<>?) (x : Nullable<'T>) (y: Nullable<'T>) = not (x ?=? y) - - let inline (?+) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value + y) else Nullable() - - let inline (+?) x (y: Nullable<_>) = if y.HasValue then Nullable(x + y.Value) else Nullable() - - let inline (?+?) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value + y.Value) else Nullable() - - let inline (?-) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value - y) else Nullable() - - let inline (-?) x (y: Nullable<_>) = if y.HasValue then Nullable(x - y.Value) else Nullable() - - let inline (?-?) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value - y.Value) else Nullable() - - let inline ( ?* ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value * y) else Nullable() - - let inline ( *? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x * y.Value) else Nullable() - - let inline ( ?*? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value * y.Value) else Nullable() - - let inline ( ?% ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value % y) else Nullable() - - let inline ( %? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x % y.Value) else Nullable() - - let inline ( ?%? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value % y.Value) else Nullable() - - let inline ( ?/ ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value / y) else Nullable() - - let inline ( /? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x / y.Value) else Nullable() - - let inline ( ?/? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value / y.Value) else Nullable() - -[] -[] -module Nullable = - - open System - - [] - let inline uint8 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.byte value.Value) else Nullable() - - [] - let inline int8 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.sbyte value.Value) else Nullable() - - [] - let inline byte (value:Nullable<_>) = if value.HasValue then Nullable(Operators.byte value.Value) else Nullable() - - [] - let inline sbyte (value:Nullable<_>) = if value.HasValue then Nullable(Operators.sbyte value.Value) else Nullable() - - [] - let inline int16 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int16 value.Value) else Nullable() - - [] - let inline uint16 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint16 value.Value) else Nullable() - - [] - let inline int (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int value.Value) else Nullable() - - [] - let inline enum (value:Nullable< int32 >) = if value.HasValue then Nullable(Operators.enum value.Value) else Nullable() - - [] - let inline int32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int32 value.Value) else Nullable() - - [] - let inline uint32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint32 value.Value) else Nullable() - - [] - let inline int64 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int64 value.Value) else Nullable() - - [] - let inline uint64 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint64 value.Value) else Nullable() - - [] - let inline float32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float32 value.Value) else Nullable() - - [] - let inline float (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float value.Value) else Nullable() - - [] - let inline single (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float32 value.Value) else Nullable() - - [] - let inline double (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float value.Value) else Nullable() - - [] - let inline nativeint (value:Nullable<_>) = if value.HasValue then Nullable(Operators.nativeint value.Value) else Nullable() - - [] - let inline unativeint (value:Nullable<_>) = if value.HasValue then Nullable(Operators.unativeint value.Value) else Nullable() - - [] - let inline decimal (value:Nullable<_>) = if value.HasValue then Nullable(Operators.decimal value.Value) else Nullable() - - [] - let inline char (value:Nullable<_>) = if value.HasValue then Nullable(Operators.char value.Value) else Nullable() - namespace Microsoft.FSharp.Linq.RuntimeHelpers open System @@ -162,6 +17,8 @@ open Microsoft.FSharp.Quotations open Microsoft.FSharp.Quotations.Patterns open Microsoft.FSharp.Quotations.DerivedPatterns +#nowarn "1204" + module LeafExpressionConverter = // The following is recognized as a LINQ 'member initialization pattern' in a quotation. @@ -503,88 +360,87 @@ module LeafExpressionConverter = | PlusQ (_, [ty1; ty2; ty3], [x1; x2]) when (ty1 = typeof) && (ty2 = typeof) && (ty3 = typeof) -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr - | GenericEqualityQ (_, _, [x1; x2]) - | EqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal - | NotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual - | GreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan - | GreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual - | LessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan - | LessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual - | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - - | StaticEqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal - | StaticNotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual - | StaticGreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual - | StaticLessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan - | StaticLessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual - - | NullableEqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Equal - | NullableNotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.NotEqual - | NullableGreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.GreaterThan - | NullableGreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.GreaterThanOrEqual - | NullableLessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.LessThan - | NullableLessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.LessThanOrEqual - - | EqualsNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Equal - | NotEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.NotEqual - | GreaterNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.GreaterThan - | GreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.GreaterThanOrEqual - | LessNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.LessThan - | LessEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.LessThanOrEqual - - | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal - | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual - | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan - | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual - | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual - + | GenericEqualityQ _ + | EqualsQ _ -> transBinOp inp env false args false Expression.Equal + | NotEqQ _ -> transBinOp inp env false args false Expression.NotEqual + | GreaterQ _ -> transBinOp inp env false args false Expression.GreaterThan + | GreaterEqQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual + | LessQ _ -> transBinOp inp env false args false Expression.LessThan + | LessEqQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual + | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr + + | StaticEqualsQ _ -> transBinOp inp env false args false Expression.Equal + | StaticNotEqQ _ -> transBinOp inp env false args false Expression.NotEqual + | StaticGreaterQ _ -> transBinOp inp env false args false Expression.GreaterThan + | StaticGreaterEqQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual + | StaticLessQ _ -> transBinOp inp env false args false Expression.LessThan + | StaticLessEqQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual + + | NullableEqualsQ _ -> transBinOp inp env false args true Expression.Equal + | NullableNotEqQ _ -> transBinOp inp env false args true Expression.NotEqual + | NullableGreaterQ _ -> transBinOp inp env false args true Expression.GreaterThan + | NullableGreaterEqQ _ -> transBinOp inp env false args true Expression.GreaterThanOrEqual + | NullableLessQ _ -> transBinOp inp env false args true Expression.LessThan + | NullableLessEqQ _ -> transBinOp inp env false args true Expression.LessThanOrEqual + + | EqualsNullableQ _ -> transBinOp inp env true args false Expression.Equal + | NotEqNullableQ _ -> transBinOp inp env true args false Expression.NotEqual + | GreaterNullableQ _ -> transBinOp inp env true args false Expression.GreaterThan + | GreaterEqNullableQ _ -> transBinOp inp env true args false Expression.GreaterThanOrEqual + | LessNullableQ _ -> transBinOp inp env true args false Expression.LessThan + | LessEqNullableQ _ -> transBinOp inp env true args false Expression.LessThanOrEqual + + | NullableEqualsNullableQ _ -> transBinOp inp env false args false Expression.Equal + | NullableNotEqNullableQ _ -> transBinOp inp env false args false Expression.NotEqual + | NullableGreaterNullableQ _ -> transBinOp inp env false args false Expression.GreaterThan + | NullableGreaterEqNullableQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual + | NullableLessNullableQ _ -> transBinOp inp env false args false Expression.LessThan + | NullableLessEqNullableQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual + // Detect the F# quotation encoding of decimal literals | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) -> Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr - | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr - | PlusQ (_, _, [x1; x2]) -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | DivideQ (_, _, [x1; x2]) -> Expression.Divide (ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | MinusQ (_, _, [x1; x2]) -> Expression.Subtract(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | MultiplyQ (_, _, [x1; x2]) -> Expression.Multiply(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | ModuloQ (_, _, [x1; x2]) -> Expression.Modulo (ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - - | ShiftLeftQ (_, _, [x1; x2]) -> Expression.LeftShift(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | ShiftRightQ (_, _, [x1; x2]) -> Expression.RightShift(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | BitwiseAndQ (_, _, [x1; x2]) -> Expression.And(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | BitwiseOrQ (_, _, [x1; x2]) -> Expression.Or(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | BitwiseXorQ (_, _, [x1; x2]) -> Expression.ExclusiveOr(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr + | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr + | PlusQ _ -> transBinOp inp env false args false Expression.Add + | DivideQ _ -> transBinOp inp env false args false Expression.Divide + | MinusQ _ -> transBinOp inp env false args false Expression.Subtract + | MultiplyQ _ -> transBinOp inp env false args false Expression.Multiply + | ModuloQ _ -> transBinOp inp env false args false Expression.Modulo + + | ShiftLeftQ _ -> transBinOp inp env false args false Expression.LeftShift + | ShiftRightQ _ -> transBinOp inp env false args false Expression.RightShift + | BitwiseAndQ _ -> transBinOp inp env false args false Expression.And + | BitwiseOrQ _ -> transBinOp inp env false args false Expression.Or + | BitwiseXorQ _ -> transBinOp inp env false args false Expression.ExclusiveOr | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - - | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr - | CheckedPlusQ (_, _, [x1; x2]) -> Expression.AddChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | CheckedMinusQ (_, _, [x1; x2]) -> Expression.SubtractChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - | CheckedMultiplyQ (_, _, [x1; x2]) -> Expression.MultiplyChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr - - - | NullablePlusQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Add - | PlusNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Add - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add - - | NullableMinusQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Subtract - | MinusNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Subtract - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract - - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Multiply - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Multiply - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply - - | NullableDivideQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Divide - | DivideNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Divide - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide - - | NullableModuloQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Modulo - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Modulo - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo - - | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr + + | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr + | CheckedPlusQ _ -> transBinOp inp env false args false Expression.AddChecked + | CheckedMinusQ _ -> transBinOp inp env false args false Expression.SubtractChecked + | CheckedMultiplyQ _ -> transBinOp inp env false args false Expression.MultiplyChecked + + | NullablePlusQ _ -> transBinOp inp env false args true Expression.Add + | PlusNullableQ _ -> transBinOp inp env true args false Expression.Add + | NullablePlusNullableQ _ -> transBinOp inp env false args false Expression.Add + + | NullableMinusQ _ -> transBinOp inp env false args true Expression.Subtract + | MinusNullableQ _ -> transBinOp inp env true args false Expression.Subtract + | NullableMinusNullableQ _ -> transBinOp inp env false args false Expression.Subtract + + | NullableMultiplyQ _ -> transBinOp inp env false args true Expression.Multiply + | MultiplyNullableQ _ -> transBinOp inp env true args false Expression.Multiply + | NullableMultiplyNullableQ _ -> transBinOp inp env false args false Expression.Multiply + + | NullableDivideQ _ -> transBinOp inp env false args true Expression.Divide + | DivideNullableQ _ -> transBinOp inp env true args false Expression.Divide + | NullableDivideNullableQ _ -> transBinOp inp env false args false Expression.Divide + + | NullableModuloQ _ -> transBinOp inp env false args true Expression.Modulo + | ModuloNullableQ _ -> transBinOp inp env true args false Expression.Modulo + | NullableModuloNullableQ _ -> transBinOp inp env false args false Expression.Modulo + + | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableFloatQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDoubleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr @@ -640,10 +496,19 @@ module LeafExpressionConverter = // Throw away markers inserted to satisfy C#'s design where they pass an argument // or type T to an argument expecting Expression. | ImplicitExpressionConversionHelperQ (_, [_], [x1]) -> ConvExprToLinqInContext env x1 - - | _ -> - let argsP = ConvExprsToLinq env args - Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr + + /// Use witnesses if they are available + | CallWithWitnesses (objArgOpt, _, minfo2, witnessArgs, args) -> + let fullArgs = witnessArgs @ args + let replacementExpr = + match objArgOpt with + | None -> Expr.Call(minfo2, fullArgs) + | Some objArg -> Expr.Call(objArg, minfo2, fullArgs) + ConvExprToLinqInContext env replacementExpr + + | _ -> + let argsP = ConvExprsToLinq env args + Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr #if !NO_CURRIED_FUNCTION_OPTIMIZATIONS // f x1 x2 x3 x4 --> InvokeFast4 @@ -794,17 +659,21 @@ module LeafExpressionConverter = let convType = lambdaTy.MakeGenericType tyargs let convDelegate = Expression.Lambda(convType, bodyP, [| vP |]) |> asExpr Expression.Call(typeof, "ToFSharpFunc", tyargs, [| convDelegate |]) |> asExpr - | _ -> - raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) + failConvert inp - and transBinOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor : _ * _ -> _) = - let e1 = ConvExprToLinqInContext env x1 - let e2 = ConvExprToLinqInContext env x2 - let e1 = if addConvertLeft then Expression.Convert(e1, typedefof>.MakeGenericType [| e1.Type |]) |> asExpr else e1 - let e2 = if addConvertRight then Expression.Convert(e2, typedefof>.MakeGenericType [| e2.Type |]) |> asExpr else e2 - exprErasedConstructor(e1, e2) |> asExpr + and failConvert inp = + raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) + and transBinOp inp env addConvertLeft args addConvertRight (exprErasedConstructor : _ * _ -> _) = + match args with + | [x1; x2] -> + let e1 = ConvExprToLinqInContext env x1 + let e2 = ConvExprToLinqInContext env x2 + let e1 = if addConvertLeft then Expression.Convert(e1, typedefof>.MakeGenericType [| e1.Type |]) |> asExpr else e1 + let e2 = if addConvertRight then Expression.Convert(e2, typedefof>.MakeGenericType [| e2.Type |]) |> asExpr else e2 + exprErasedConstructor(e1, e2) |> asExpr + | _ -> failConvert inp and ConvObjArg env objOpt coerceTo : Expression = match objOpt with diff --git a/src/fsharp/FSharp.Core/Linq.fsi b/src/fsharp/FSharp.Core/Linq.fsi index 90bc343d0f5..24f61321b16 100644 --- a/src/fsharp/FSharp.Core/Linq.fsi +++ b/src/fsharp/FSharp.Core/Linq.fsi @@ -1,307 +1,90 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace Microsoft.FSharp.Linq - - open System - open System.Linq.Expressions - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - /// Operators for working with nullable values - [] - module NullableOperators = - open System - /// The '>=' operator where a nullable value appears on the left - val ( ?>= ) : Nullable<'T> -> 'T -> bool when 'T : comparison - /// The '>' operator where a nullable value appears on the left - val ( ?> ) : Nullable<'T> -> 'T -> bool when 'T : comparison - /// The '<=' operator where a nullable value appears on the left - val ( ?<= ) : Nullable<'T> -> 'T -> bool when 'T : comparison - /// The '<' operator where a nullable value appears on the left - val ( ?< ) : Nullable<'T> -> 'T -> bool when 'T : comparison - /// The '=' operator where a nullable value appears on the left - val ( ?= ) : Nullable<'T> -> 'T -> bool when 'T : equality - /// The '<>' operator where a nullable value appears on the left - val ( ?<> ) : Nullable<'T> -> 'T -> bool when 'T : equality - - /// The '>=' operator where a nullable value appears on the right - val ( >=? ) : 'T -> Nullable<'T> -> bool when 'T : comparison - /// The '>' operator where a nullable value appears on the right - val ( >? ) : 'T -> Nullable<'T> -> bool when 'T : comparison - /// The '<=' operator where a nullable value appears on the right - val ( <=? ) : 'T -> Nullable<'T> -> bool when 'T : comparison - /// The '<' operator where a nullable value appears on the right - val ( Nullable<'T> -> bool when 'T : comparison - /// The '=' operator where a nullable value appears on the right - val ( =? ) : 'T -> Nullable<'T> -> bool when 'T : equality - /// The '<>' operator where a nullable value appears on the right - val ( <>? ) : 'T -> Nullable<'T> -> bool when 'T : equality - - /// The '>=' operator where a nullable value appears on both left and right sides - val ( ?>=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison - /// The '>' operator where a nullable value appears on both left and right sides - val ( ?>? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison - /// The '<=' operator where a nullable value appears on both left and right sides - val ( ?<=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison - /// The '<' operator where a nullable value appears on both left and right sides - val ( ? -> Nullable<'T> -> bool when 'T : comparison - /// The '=' operator where a nullable value appears on both left and right sides - val ( ?=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : equality - /// The '<>' operator where a nullable value appears on both left and right sides - val ( ?<>? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : equality - - - /// The addition operator where a nullable value appears on the left - val inline ( ?+ ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The addition operator where a nullable value appears on the right - val inline ( +? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The addition operator where a nullable value appears on both left and right sides - val inline ( ?+? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - - /// The subtraction operator where a nullable value appears on the left - val inline ( ?- ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The subtraction operator where a nullable value appears on the right - val inline ( -? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The subtraction operator where a nullable value appears on both left and right sides - val inline ( ?-? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - - /// The multiplication operator where a nullable value appears on the left - val inline ( ?* ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The multiplication operator where a nullable value appears on the right - val inline ( *? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The multiplication operator where a nullable value appears on both left and right sides - val inline ( ?*? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - - /// The modulus operator where a nullable value appears on the left - val inline ( ?% ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The modulus operator where a nullable value appears on the right - val inline ( %? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The modulus operator where a nullable value appears on both left and right sides - val inline ( ?%? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - - /// The division operator where a nullable value appears on the left - val inline ( ?/ ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The division operator where a nullable value appears on the right - val inline ( /? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - /// The division operator where a nullable value appears on both left and right sides - val inline ( ?/? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int - - /// Functions for converting nullable values - [] - [] - module Nullable = - - /// Converts the argument to byte. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted byte - [] - val inline byte : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> byte) and default ^T : int - - /// Converts the argument to byte. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted byte - [] - val inline uint8 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint8) and default ^T : int - - /// Converts the argument to signed byte. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted sbyte - [] - val inline sbyte : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> sbyte) and default ^T : int - - - /// Converts the argument to signed byte. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted sbyte - [] - val inline int8 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int8) and default ^T : int - - /// Converts the argument to signed 16-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted int16 - [] - val inline int16 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int16) and default ^T : int - - /// Converts the argument to unsigned 16-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted uint16 - [] - val inline uint16 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint16) and default ^T : int - - /// Converts the argument to signed 32-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted int - [] - val inline int : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int) and default ^T : int - - /// Converts the argument to a particular enum type. - /// The input value. - /// The converted enum type. - [] - val inline enum : value:Nullable< int32 > -> Nullable< ^U > when ^U : enum - - /// Converts the argument to signed 32-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted int32 - [] - val inline int32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int32) and default ^T : int - - /// Converts the argument to unsigned 32-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted uint32 - [] - val inline uint32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint32) and default ^T : int - - /// Converts the argument to signed 64-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted int64 - [] - val inline int64 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int64) and default ^T : int - - /// Converts the argument to unsigned 64-bit integer. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted uint64 - [] - val inline uint64 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint64) and default ^T : int - - /// Converts the argument to 32-bit float. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted float32 - [] - val inline float32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> float32) and default ^T : int - - /// Converts the argument to 64-bit float. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted float - [] - val inline float : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> float) and default ^T : int - - /// Converts the argument to 32-bit float. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted float32 - [] - val inline single : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> single) and default ^T : int - - /// Converts the argument to 64-bit float. This is a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted float - [] - val inline double : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> double) and default ^T : int - - /// Converts the argument to signed native integer. This is a direct conversion for all - /// primitive numeric types. Otherwise the operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted nativeint - [] - val inline nativeint : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> nativeint) and default ^T : int - - /// Converts the argument to unsigned native integer using a direct conversion for all - /// primitive numeric types. Otherwise the operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted unativeint - [] - val inline unativeint : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> unativeint) and default ^T : int - - /// Converts the argument to System.Decimal using a direct conversion for all - /// primitive numeric types. The operation requires an appropriate - /// static conversion method on the input type. - /// The input value. - /// The converted decimal. - [] - val inline decimal : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> decimal) and default ^T : int - - /// Converts the argument to character. Numeric inputs are converted according to the UTF-16 - /// encoding for characters. The operation requires an appropriate static conversion method on the input type. - /// The input value. - /// The converted char. - [] - val inline char : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> char) and default ^T : int - namespace Microsoft.FSharp.Linq.RuntimeHelpers - open System - open System.Linq.Expressions - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - module LeafExpressionConverter = - open Microsoft.FSharp.Quotations - - /// When used in a quotation, this function indicates a specific conversion - /// should be performed when converting the quotation to a LINQ expression. - /// - /// This function should not be called directly. - // - // NOTE: when an F# expression tree is converted to a Linq expression tree using ToLinqExpression - // the transformation of LinqExpressionHelper(e) is the same as the transformation of - // 'e'. This allows ImplicitExpressionConversionHelper to be used as a marker to satisfy the C# design where - // certain expression trees are constructed using methods with a signature that expects an - // expression tree of type Expression but are passed an expression tree of type T. - //[] - val ImplicitExpressionConversionHelper : 'T -> Expression<'T> - - /// When used in a quotation, this function indicates a specific conversion - /// should be performed when converting the quotation to a LINQ expression. - /// - /// This function should not be called directly. - //[] - val MemberInitializationHelper : 'T -> 'T - - /// When used in a quotation, this function indicates a specific conversion - /// should be performed when converting the quotation to a LINQ expression. - /// - /// This function should not be called directly. - //[] - val NewAnonymousObjectHelper : 'T -> 'T - - /// Converts a subset of F# quotations to a LINQ expression, for the subset of LINQ expressions represented by the - /// expression syntax in the C# language. - val QuotationToExpression : Expr -> Expression - - /// Converts a subset of F# quotations to a LINQ expression, for the subset of LINQ expressions represented by the - /// expression syntax in the C# language. - val QuotationToLambdaExpression : Expr<'T> -> Expression<'T> - - /// Evaluates a subset of F# quotations by first converting to a LINQ expression, for the subset of LINQ expressions represented by the - /// expression syntax in the C# language. - val EvaluateQuotation : Expr -> obj - - /// A runtime helper used to evaluate nested quotation literals. - val SubstHelper : Expr * Var[] * obj[] -> Expr<'T> - - /// A runtime helper used to evaluate nested quotation literals. - val SubstHelperRaw : Expr * Var[] * obj[] -> Expr - - val internal (|SpecificCallToMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option) +open System +open System.Linq.Expressions +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections +open Microsoft.FSharp.Quotations + +/// +/// Contains functionality to convert F# quotations to LINQ expression trees. +/// +/// +/// +/// Library functionality associated with converting F# quotations to .NET LINQ expression trees. +/// +module LeafExpressionConverter = + /// + /// When used in a quotation, this function indicates a specific conversion + /// should be performed when converting the quotation to a LINQ expression. + /// + /// This function should not be called directly. + /// + // + // NOTE: when an F# expression tree is converted to a Linq expression tree using ToLinqExpression + // the transformation of LinqExpressionHelper(e) is the same as the transformation of + // 'e'. This allows ImplicitExpressionConversionHelper to be used as a marker to satisfy the C# design where + // certain expression trees are constructed using methods with a signature that expects an + // expression tree of type Expression but are passed an expression tree of type T. + //[] + val ImplicitExpressionConversionHelper : 'T -> Expression<'T> + + /// + /// When used in a quotation, this function indicates a specific conversion + /// should be performed when converting the quotation to a LINQ expression. + /// + /// This function should not be called directly. + /// + //[] + val MemberInitializationHelper : 'T -> 'T + + /// + /// When used in a quotation, this function indicates a specific conversion + /// should be performed when converting the quotation to a LINQ expression. + /// + /// This function should not be called directly. + /// + //[] + val NewAnonymousObjectHelper : 'T -> 'T + + /// + /// Converts a subset of F# quotations to a LINQ expression, for the subset of LINQ expressions represented by the + /// expression syntax in the C# language. + /// + /// + /// + val QuotationToExpression : Expr -> Expression + + /// + /// Converts a subset of F# quotations to a LINQ expression, for the subset of LINQ expressions represented by the + /// expression syntax in the C# language. + /// + /// + /// + val QuotationToLambdaExpression : Expr<'T> -> Expression<'T> + + /// + /// Evaluates a subset of F# quotations by first converting to a LINQ expression, for the subset of LINQ expressions represented by the + /// expression syntax in the C# language. + /// + /// + /// + val EvaluateQuotation : Expr -> obj + + /// + /// A runtime helper used to evaluate nested quotation literals. + /// + /// + /// + val SubstHelper : Expr * Var[] * obj[] -> Expr<'T> + + /// + /// A runtime helper used to evaluate nested quotation literals. + /// + /// + /// + val SubstHelperRaw : Expr * Var[] * obj[] -> Expr + + val internal (|SpecificCallToMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option) diff --git a/src/fsharp/FSharp.Core/MutableTuple.fs b/src/fsharp/FSharp.Core/MutableTuple.fs index 89c84dca36a..79e7d5c73ed 100644 --- a/src/fsharp/FSharp.Core/MutableTuple.fs +++ b/src/fsharp/FSharp.Core/MutableTuple.fs @@ -22,14 +22,16 @@ open Microsoft.FSharp.Core // This terminology mistake also runs all the way through Query.fs. // ---------------------------------------------------------------------------- -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1> = val private item1 : 'T1 member x.Item1 = x.item1 new (Item1) = { item1 = Item1 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -39,7 +41,8 @@ type AnonymousObject<'T1, 'T2> = new (Item1, Item2) = { item1 = Item1; item2 = Item2 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -53,7 +56,8 @@ type AnonymousObject<'T1, 'T2, 'T3> = new (Item1, Item2, Item3) = { item1 = Item1; item2 = Item2; item3 = Item3 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3, 'T4> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -71,7 +75,8 @@ type AnonymousObject<'T1, 'T2, 'T3, 'T4> = -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -91,7 +96,8 @@ type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5> = new (Item1, Item2, Item3, Item4, Item5) = { item1 = Item1; item2 = Item2; item3 = Item3; item4 = Item4 ; item5 = Item5 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5, 'T6> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -114,7 +120,8 @@ type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5, 'T6> = new (Item1, Item2, Item3, Item4, Item5, Item6) = { item1 = Item1; item2 = Item2; item3 = Item3; item4 = Item4 ; item5 = Item5 ; item6 = Item6 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7> = val private item1 : 'T1 member x.Item1 = x.item1 @@ -139,7 +146,8 @@ type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7> = new (Item1, Item2, Item3, Item4, Item5, Item6, Item7) = { item1 = Item1; item2 = Item2; item3 = Item3; item4 = Item4 ; item5 = Item5 ; item6 = Item6 ; item7 = Item7 } -/// This type shouldn't be used directly from user code. +/// This type shouldn't be used directly from user code. +/// type AnonymousObject<'T1, 'T2, 'T3, 'T4, 'T5, 'T6, 'T7, 'T8> = val private item1 : 'T1 member x.Item1 = x.item1 diff --git a/src/fsharp/FSharp.Core/Nullable.fs b/src/fsharp/FSharp.Core/Nullable.fs new file mode 100644 index 00000000000..02d58b2a8ac --- /dev/null +++ b/src/fsharp/FSharp.Core/Nullable.fs @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Linq + +#nowarn "1204" + +open System +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + +module NullableOperators = + let (?>=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value >= y + + let (?>) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value > y + + let (?<=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value <= y + + let (?<) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value < y + + let (?=) (x : Nullable<'T>) (y: 'T) = x.HasValue && x.Value = y + + let (?<>) (x : Nullable<'T>) (y: 'T) = not (x ?= y) + + let (>=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x >= y.Value + + let (>?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x > y.Value + + let (<=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x <= y.Value + + let () = y.HasValue && x < y.Value + + let (=?) (x : 'T) (y: Nullable<'T>) = y.HasValue && x = y.Value + + let (<>?) (x : 'T) (y: Nullable<'T>) = not (x =? y) + + let (?>=?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value >= y.Value) + + let (?>?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value > y.Value) + + let (?<=?) (x : Nullable<'T>) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value <= y.Value) + + let (?) (y: Nullable<'T>) = (x.HasValue && y.HasValue && x.Value < y.Value) + + let (?=?) (x : Nullable<'T>) (y: Nullable<'T>) = (not x.HasValue && not y.HasValue) || (x.HasValue && y.HasValue && x.Value = y.Value) + + let (?<>?) (x : Nullable<'T>) (y: Nullable<'T>) = not (x ?=? y) + + let inline (?+) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value + y) else Nullable() + + let inline (+?) x (y: Nullable<_>) = if y.HasValue then Nullable(x + y.Value) else Nullable() + + let inline (?+?) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value + y.Value) else Nullable() + + let inline (?-) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value - y) else Nullable() + + let inline (-?) x (y: Nullable<_>) = if y.HasValue then Nullable(x - y.Value) else Nullable() + + let inline (?-?) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value - y.Value) else Nullable() + + let inline ( ?* ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value * y) else Nullable() + + let inline ( *? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x * y.Value) else Nullable() + + let inline ( ?*? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value * y.Value) else Nullable() + + let inline ( ?% ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value % y) else Nullable() + + let inline ( %? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x % y.Value) else Nullable() + + let inline ( ?%? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value % y.Value) else Nullable() + + let inline ( ?/ ) (x : Nullable<_>) y = if x.HasValue then Nullable(x.Value / y) else Nullable() + + let inline ( /? ) x (y: Nullable<_>) = if y.HasValue then Nullable(x / y.Value) else Nullable() + + let inline ( ?/? ) (x : Nullable<_>) (y: Nullable<_>) = if x.HasValue && y.HasValue then Nullable(x.Value / y.Value) else Nullable() + +[] +[] +module Nullable = + [] + let inline uint8 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.byte value.Value) else Nullable() + + [] + let inline int8 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.sbyte value.Value) else Nullable() + + [] + let inline byte (value:Nullable<_>) = if value.HasValue then Nullable(Operators.byte value.Value) else Nullable() + + [] + let inline sbyte (value:Nullable<_>) = if value.HasValue then Nullable(Operators.sbyte value.Value) else Nullable() + + [] + let inline int16 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int16 value.Value) else Nullable() + + [] + let inline uint16 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint16 value.Value) else Nullable() + + [] + let inline int (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int value.Value) else Nullable() + + [] + let inline uint (value: Nullable<_>) = if value.HasValue then Nullable(Operators.uint value.Value) else Nullable() + + [] + let inline enum (value:Nullable< int32 >) = if value.HasValue then Nullable(Operators.enum value.Value) else Nullable() + + [] + let inline int32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int32 value.Value) else Nullable() + + [] + let inline uint32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint32 value.Value) else Nullable() + + [] + let inline int64 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.int64 value.Value) else Nullable() + + [] + let inline uint64 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.uint64 value.Value) else Nullable() + + [] + let inline float32 (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float32 value.Value) else Nullable() + + [] + let inline float (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float value.Value) else Nullable() + + [] + let inline single (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float32 value.Value) else Nullable() + + [] + let inline double (value:Nullable<_>) = if value.HasValue then Nullable(Operators.float value.Value) else Nullable() + + [] + let inline nativeint (value:Nullable<_>) = if value.HasValue then Nullable(Operators.nativeint value.Value) else Nullable() + + [] + let inline unativeint (value:Nullable<_>) = if value.HasValue then Nullable(Operators.unativeint value.Value) else Nullable() + + [] + let inline decimal (value:Nullable<_>) = if value.HasValue then Nullable(Operators.decimal value.Value) else Nullable() + + [] + let inline char (value:Nullable<_>) = if value.HasValue then Nullable(Operators.char value.Value) else Nullable() diff --git a/src/fsharp/FSharp.Core/Nullable.fsi b/src/fsharp/FSharp.Core/Nullable.fsi new file mode 100644 index 00000000000..6479a0d1732 --- /dev/null +++ b/src/fsharp/FSharp.Core/Nullable.fsi @@ -0,0 +1,428 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Linq + +open System +open Microsoft.FSharp.Core + +/// Operators for working with nullable values, primarily used on F# queries. +[] +module NullableOperators = + /// The '>=' operator where a nullable value appears on the left + /// + /// + val ( ?>= ) : Nullable<'T> -> 'T -> bool when 'T : comparison + + /// The '>' operator where a nullable value appears on the left + /// + /// + val ( ?> ) : Nullable<'T> -> 'T -> bool when 'T : comparison + + /// The '<=' operator where a nullable value appears on the left + /// + /// + val ( ?<= ) : Nullable<'T> -> 'T -> bool when 'T : comparison + + /// The '<' operator where a nullable value appears on the left + /// + /// + val ( ?< ) : Nullable<'T> -> 'T -> bool when 'T : comparison + + /// The '=' operator where a nullable value appears on the left + /// + /// + val ( ?= ) : Nullable<'T> -> 'T -> bool when 'T : equality + + /// The '<>' operator where a nullable value appears on the left + /// + /// + val ( ?<> ) : Nullable<'T> -> 'T -> bool when 'T : equality + + /// The '>=' operator where a nullable value appears on the right + /// + /// + val ( >=? ) : 'T -> Nullable<'T> -> bool when 'T : comparison + + /// The '>' operator where a nullable value appears on the right + /// + /// + val ( >? ) : 'T -> Nullable<'T> -> bool when 'T : comparison + + /// The '<=' operator where a nullable value appears on the right + /// + /// + val ( <=? ) : 'T -> Nullable<'T> -> bool when 'T : comparison + + /// The '<' operator where a nullable value appears on the right + /// + /// + val ( Nullable<'T> -> bool when 'T : comparison + + /// The '=' operator where a nullable value appears on the right + /// + /// + val ( =? ) : 'T -> Nullable<'T> -> bool when 'T : equality + + /// The '<>' operator where a nullable value appears on the right + /// + /// + val ( <>? ) : 'T -> Nullable<'T> -> bool when 'T : equality + + /// The '>=' operator where a nullable value appears on both left and right sides + /// + /// + val ( ?>=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison + + /// The '>' operator where a nullable value appears on both left and right sides + /// + /// + val ( ?>? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison + + /// The '<=' operator where a nullable value appears on both left and right sides + /// + /// + val ( ?<=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : comparison + + /// The '<' operator where a nullable value appears on both left and right sides + /// + /// + val ( ? -> Nullable<'T> -> bool when 'T : comparison + + /// The '=' operator where a nullable value appears on both left and right sides + /// + /// + val ( ?=? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : equality + + /// The '<>' operator where a nullable value appears on both left and right sides + /// + /// + val ( ?<>? ) : Nullable<'T> -> Nullable<'T> -> bool when 'T : equality + + /// The addition operator where a nullable value appears on the left + /// + /// + val inline ( ?+ ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The addition operator where a nullable value appears on the right + /// + /// + val inline ( +? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The addition operator where a nullable value appears on both left and right sides + /// + /// + val inline ( ?+? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The subtraction operator where a nullable value appears on the left + /// + /// + val inline ( ?- ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The subtraction operator where a nullable value appears on the right + /// + /// + val inline ( -? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The subtraction operator where a nullable value appears on both left and right sides + /// + /// + val inline ( ?-? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The multiplication operator where a nullable value appears on the left + /// + /// + val inline ( ?* ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The multiplication operator where a nullable value appears on the right + /// + /// + val inline ( *? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The multiplication operator where a nullable value appears on both left and right sides + /// + /// + val inline ( ?*? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The modulus operator where a nullable value appears on the left + /// + /// + val inline ( ?% ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The modulus operator where a nullable value appears on the right + /// + /// + val inline ( %? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The modulus operator where a nullable value appears on both left and right sides + /// + /// + val inline ( ?%? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The division operator where a nullable value appears on the left + /// + /// + val inline ( ?/ ) : Nullable< ^T1 > -> ^T2 -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The division operator where a nullable value appears on the right + /// + /// + val inline ( /? ) : ^T1 -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + + /// The division operator where a nullable value appears on both left and right sides + /// + /// + val inline ( ?/? ) : Nullable< ^T1 > -> Nullable< ^T2 > -> Nullable< ^T3 > when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int + +/// Functions for converting nullable values +[] +[] +module Nullable = + + /// Converts the argument to byte. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted byte + /// + /// + [] + val inline byte : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> byte) and default ^T : int + + /// Converts the argument to byte. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted byte + /// + /// + [] + val inline uint8 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint8) and default ^T : int + + /// Converts the argument to signed byte. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted sbyte + /// + /// + [] + val inline sbyte : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> sbyte) and default ^T : int + + /// Converts the argument to signed byte. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted sbyte + /// + /// + [] + val inline int8 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int8) and default ^T : int + + /// Converts the argument to signed 16-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted int16 + /// + /// + [] + val inline int16 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int16) and default ^T : int + + /// Converts the argument to unsigned 16-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted uint16 + /// + /// + [] + val inline uint16 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint16) and default ^T : int + + /// Converts the argument to signed 32-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted int + /// + /// + [] + val inline int : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int) and default ^T : int + + /// Converts the argument to an unsigned 32-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted unsigned integer + /// + /// + [] + val inline uint: value: Nullable< ^T > -> Nullable when ^T :(static member op_Explicit: ^T -> uint) and default ^T : uint + + /// Converts the argument to a particular enum type. + /// + /// The input value. + /// + /// The converted enum type. + /// + /// + [] + val inline enum : value:Nullable< int32 > -> Nullable< ^U > when ^U : enum + + /// Converts the argument to signed 32-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted int32 + /// + /// + [] + val inline int32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int32) and default ^T : int + + /// Converts the argument to unsigned 32-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted uint32 + /// + /// + [] + val inline uint32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint32) and default ^T : int + + /// Converts the argument to signed 64-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted int64 + /// + /// + [] + val inline int64 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> int64) and default ^T : int + + /// Converts the argument to unsigned 64-bit integer. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted uint64 + /// + /// + [] + val inline uint64 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> uint64) and default ^T : int + + /// Converts the argument to 32-bit float. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted float32 + /// + /// + [] + val inline float32 : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> float32) and default ^T : int + + /// Converts the argument to 64-bit float. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted float + /// + /// + [] + val inline float : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> float) and default ^T : int + + /// Converts the argument to 32-bit float. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted float32 + /// + /// + [] + val inline single : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> single) and default ^T : int + + /// Converts the argument to 64-bit float. This is a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted float + /// + /// + [] + val inline double : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> double) and default ^T : int + + /// Converts the argument to signed native integer. This is a direct conversion for all + /// primitive numeric types. Otherwise the operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted nativeint + /// + /// + [] + val inline nativeint : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> nativeint) and default ^T : int + + /// Converts the argument to unsigned native integer using a direct conversion for all + /// primitive numeric types. Otherwise the operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted unativeint + /// + /// + [] + val inline unativeint : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> unativeint) and default ^T : int + + /// Converts the argument to System.Decimal using a direct conversion for all + /// primitive numeric types. The operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted decimal. + /// + /// + [] + val inline decimal : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> decimal) and default ^T : int + + /// Converts the argument to character. Numeric inputs are converted according to the UTF-16 + /// encoding for characters. The operation requires an appropriate static conversion method on the input type. + /// + /// The input value. + /// + /// The converted char. + /// + /// + [] + val inline char : value:Nullable< ^T > -> Nullable when ^T : (static member op_Explicit : ^T -> char) and default ^T : int diff --git a/src/fsharp/FSharp.Core/Query.fs b/src/fsharp/FSharp.Core/Query.fs index 92ee2451844..8d54ff85228 100644 --- a/src/fsharp/FSharp.Core/Query.fs +++ b/src/fsharp/FSharp.Core/Query.fs @@ -18,7 +18,7 @@ open Microsoft.FSharp.Linq.RuntimeHelpers [] type QuerySource<'T, 'Q> (source: seq<'T>) = - member __.Source = source + member _.Source = source [] module Helpers = @@ -50,98 +50,98 @@ module ForwardDeclarations = } type QueryBuilder() = - member __.For (source:QuerySource<'T, 'Q>, body: 'T -> QuerySource<'Result, 'Q2>) : QuerySource<'Result, 'Q> = + member _.For (source: QuerySource<'T, 'Q>, body: 'T -> QuerySource<'Result, 'Q2>) : QuerySource<'Result, 'Q> = QuerySource (Seq.collect (fun x -> (body x).Source) source.Source) - member __.Zero () = + member _.Zero () = QuerySource Seq.empty - member __.Yield value = + member _.Yield value = QuerySource (Seq.singleton value) - member __.YieldFrom (computation: QuerySource<'T, 'Q>) : QuerySource<'T, 'Q> = + member _.YieldFrom (computation: QuerySource<'T, 'Q>) : QuerySource<'T, 'Q> = computation // Indicates to the F# compiler that an implicit quotation is added to use of 'query' - member __.Quote (quotation:Quotations.Expr<'T>) = + member _.Quote (quotation: Quotations.Expr<'T>) = quotation - member __.Source (source: IQueryable<'T>) = + member _.Source (source: IQueryable<'T>) = QuerySource source - member __.Source (source: IEnumerable<'T>) : QuerySource<'T, System.Collections.IEnumerable> = + member _.Source (source: IEnumerable<'T>) : QuerySource<'T, System.Collections.IEnumerable> = QuerySource source - member __.Contains (source:QuerySource<'T, 'Q>, key) = + member _.Contains (source: QuerySource<'T, 'Q>, key) = Enumerable.Contains(source.Source, key) - member __.Select (source:QuerySource<'T, 'Q>, projection) : QuerySource<'U, 'Q> = + member _.Select (source: QuerySource<'T, 'Q>, projection) : QuerySource<'U, 'Q> = QuerySource (Seq.map projection source.Source) - member __.Where (source:QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = + member _.Where (source: QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = QuerySource (Enumerable.Where (source.Source, Func<_, _>(predicate)) ) - member __.Last (source:QuerySource<'T, 'Q>) = + member _.Last (source: QuerySource<'T, 'Q>) = Enumerable.Last source.Source - member __.LastOrDefault (source:QuerySource<'T, 'Q>) = + member _.LastOrDefault (source: QuerySource<'T, 'Q>) = Enumerable.LastOrDefault source.Source - member __.ExactlyOne (source:QuerySource<'T, 'Q>) = + member _.ExactlyOne (source: QuerySource<'T, 'Q>) = Enumerable.Single source.Source - member __.ExactlyOneOrDefault (source:QuerySource<'T, 'Q>) = + member _.ExactlyOneOrDefault (source: QuerySource<'T, 'Q>) = Enumerable.SingleOrDefault source.Source - member __.Count (source:QuerySource<'T, 'Q>) = + member _.Count (source: QuerySource<'T, 'Q>) = Enumerable.Count source.Source - member __.Distinct (source: QuerySource<'T, 'Q> when 'T : equality) : QuerySource<'T, 'Q> = + member _.Distinct (source: QuerySource<'T, 'Q> when 'T : equality) : QuerySource<'T, 'Q> = QuerySource (Enumerable.Distinct source.Source) - member __.Exists(source: QuerySource<'T, 'Q>, predicate) = + member _.Exists(source: QuerySource<'T, 'Q>, predicate) = Enumerable.Any (source.Source, Func<_, _>(predicate)) - member __.All (source: QuerySource<'T, 'Q>, predicate) = + member _.All (source: QuerySource<'T, 'Q>, predicate) = Enumerable.All (source.Source, Func<_, _>(predicate)) - member __.Head (source: QuerySource<'T, 'Q>) = + member _.Head (source: QuerySource<'T, 'Q>) = Enumerable.First source.Source - member __.Nth (source: QuerySource<'T, 'Q>, index) = + member _.Nth (source: QuerySource<'T, 'Q>, index) = Enumerable.ElementAt (source.Source, index) - member __.Skip (source: QuerySource<'T, 'Q>, count) : QuerySource<'T, 'Q> = + member _.Skip (source: QuerySource<'T, 'Q>, count) : QuerySource<'T, 'Q> = QuerySource (Enumerable.Skip (source.Source, count)) - member __.SkipWhile (source: QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = + member _.SkipWhile (source: QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = QuerySource (Enumerable.SkipWhile (source.Source, Func<_, _>(predicate))) - member __.Take (source: QuerySource<'T, 'Q>, count) : QuerySource<'T, 'Q> = + member _.Take (source: QuerySource<'T, 'Q>, count) : QuerySource<'T, 'Q> = QuerySource (Enumerable.Take (source.Source, count)) - member __.TakeWhile (source: QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = + member _.TakeWhile (source: QuerySource<'T, 'Q>, predicate) : QuerySource<'T, 'Q> = QuerySource (Enumerable.TakeWhile (source.Source, Func<_, _>(predicate))) - member __.Find (source: QuerySource<'T, 'Q>, predicate) = + member _.Find (source: QuerySource<'T, 'Q>, predicate) = Enumerable.First (source.Source, Func<_, _>(predicate)) - member __.HeadOrDefault (source:QuerySource<'T, 'Q>) = + member _.HeadOrDefault (source: QuerySource<'T, 'Q>) = Enumerable.FirstOrDefault source.Source - member __.MinBy<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison> (source:QuerySource<'T, 'Q>, valueSelector: 'T -> 'Key) = + member _.MinBy<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison> (source: QuerySource<'T, 'Q>, valueSelector: 'T -> 'Key) = Enumerable.Min(source.Source, Func<'T, 'Key>(valueSelector)) - member __.MaxBy<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison> (source:QuerySource<'T, 'Q>, valueSelector: 'T -> 'Key) = + member _.MaxBy<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison> (source: QuerySource<'T, 'Q>, valueSelector: 'T -> 'Key) = Enumerable.Max(source.Source, Func<'T, 'Key>(valueSelector)) - member __.MinByNullable<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison and 'Key: (new: unit -> 'Key) and 'Key: struct and 'Key:> ValueType> (source:QuerySource<'T, 'Q>, valueSelector: 'T -> Nullable<'Key>) = + member _.MinByNullable<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison and 'Key: (new: unit -> 'Key) and 'Key: struct and 'Key:> ValueType> (source: QuerySource<'T, 'Q>, valueSelector: 'T -> Nullable<'Key>) = Enumerable.Min(source.Source, Func<'T, Nullable<'Key>>(valueSelector)) - member __.MaxByNullable<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison and 'Key: (new: unit -> 'Key) and 'Key: struct and 'Key:> ValueType> (source:QuerySource<'T, 'Q>, valueSelector: 'T -> Nullable<'Key>) = + member _.MaxByNullable<'T, 'Q, 'Key when 'Key: equality and 'Key: comparison and 'Key: (new: unit -> 'Key) and 'Key: struct and 'Key:> ValueType> (source: QuerySource<'T, 'Q>, valueSelector: 'T -> Nullable<'Key>) = Enumerable.Max(source.Source, Func<'T, Nullable<'Key>>(valueSelector)) - member inline __.SumByNullable<'T, 'Q, ^Value + member inline _.SumByNullable<'T, 'Q, ^Value when ^Value :> ValueType and ^Value : struct and ^Value : (new : unit -> ^Value) @@ -160,7 +160,7 @@ type QueryBuilder() = acc <- plus acc (v.Value : ^Value) Nullable acc - member inline __.AverageByNullable< 'T, 'Q, ^Value + member inline _.AverageByNullable< 'T, 'Q, ^Value when ^Value :> ValueType and ^Value : struct and ^Value : (new : unit -> ^Value) @@ -183,7 +183,7 @@ type QueryBuilder() = count <- count + 1 if count = 0 then Nullable() else Nullable(LanguagePrimitives.DivideByInt< (^Value) > acc count) - member inline __.AverageBy< 'T, 'Q, ^Value + member inline _.AverageBy< 'T, 'Q, ^Value when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) and ^Value : (static member DivideByInt : ^Value * int -> ^Value) and ^Value : (static member Zero : ^Value) @@ -202,62 +202,62 @@ type QueryBuilder() = invalidOp "source" LanguagePrimitives.DivideByInt< (^U) > acc count - member inline __.SumBy< 'T, 'Q, ^Value + member inline _.SumBy< 'T, 'Q, ^Value when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) and ^Value : (static member Zero : ^Value) and default ^Value : int > - (source:QuerySource<'T, 'Q>, projection : ('T -> ^Value)) : ^Value = + (source: QuerySource<'T, 'Q>, projection : ('T -> ^Value)) : ^Value = Seq.sumBy projection source.Source - member __.GroupBy (source: QuerySource<'T, 'Q>, keySelector : _ -> 'Key) : QuerySource<_, 'Q> when 'Key : equality = + member _.GroupBy (source: QuerySource<'T, 'Q>, keySelector: _ -> 'Key) : QuerySource<_, 'Q> when 'Key : equality = QuerySource (Enumerable.GroupBy(source.Source, Func<_, _>(keySelector))) - member __.SortBy (source: QuerySource<'T, 'Q>, keySelector : 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.SortBy (source: QuerySource<'T, 'Q>, keySelector: 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.OrderBy(source.Source, Func<_, _>(keySelector))) - member __.SortByDescending (source: QuerySource<'T, 'Q>, keySelector : 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.SortByDescending (source: QuerySource<'T, 'Q>, keySelector: 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.OrderByDescending(source.Source, Func<_, _>(keySelector))) - member __.ThenBy (source: QuerySource<'T, 'Q>, keySelector : 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.ThenBy (source: QuerySource<'T, 'Q>, keySelector: 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.ThenBy(checkThenBySource source.Source, Func<_, _>(keySelector))) - member __.ThenByDescending (source: QuerySource<'T, 'Q>, keySelector : 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.ThenByDescending (source: QuerySource<'T, 'Q>, keySelector: 'T -> 'Key) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.ThenByDescending(checkThenBySource source.Source, Func<_, _>(keySelector))) - member __.SortByNullable (source: QuerySource<'T, 'Q>, keySelector : 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.SortByNullable (source: QuerySource<'T, 'Q>, keySelector: 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.OrderBy(source.Source, Func<_, _>(keySelector))) - member __.SortByNullableDescending (source: QuerySource<'T, 'Q>, keySelector : 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.SortByNullableDescending (source: QuerySource<'T, 'Q>, keySelector: 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.OrderByDescending(source.Source, Func<_, _>(keySelector))) - member __.ThenByNullable (source: QuerySource<'T, 'Q>, keySelector : 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.ThenByNullable (source: QuerySource<'T, 'Q>, keySelector: 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.ThenBy(checkThenBySource source.Source, Func<_, _>(keySelector))) - member __.ThenByNullableDescending (source: QuerySource<'T, 'Q>, keySelector : 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = + member _.ThenByNullableDescending (source: QuerySource<'T, 'Q>, keySelector: 'T -> Nullable<'Key>) : QuerySource<'T, 'Q> when 'Key : equality and 'Key : comparison = QuerySource (Enumerable.ThenByDescending(checkThenBySource source.Source, Func<_, _>(keySelector))) - member __.GroupValBy<'T, 'Key, 'Result, 'Q when 'Key : equality > (source:QuerySource<'T, 'Q>, resultSelector: 'T -> 'Result, keySelector: 'T -> 'Key) : QuerySource, 'Q> = + member _.GroupValBy<'T, 'Key, 'Result, 'Q when 'Key : equality > (source: QuerySource<'T, 'Q>, resultSelector: 'T -> 'Result, keySelector: 'T -> 'Key) : QuerySource, 'Q> = QuerySource (Enumerable.GroupBy(source.Source, Func<'T, 'Key>(keySelector), Func<'T, 'Result>(resultSelector))) - member __.Join (outerSource: QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector) : QuerySource<_, 'Q> = + member _.Join (outerSource: QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector) : QuerySource<_, 'Q> = QuerySource (Enumerable.Join(outerSource.Source, innerSource.Source, Func<_, _>(outerKeySelector), Func<_, _>(innerKeySelector), Func<_, _, _>(resultSelector))) - member __.GroupJoin (outerSource: QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector: _ -> seq<_> -> _) : QuerySource<_, 'Q> = + member _.GroupJoin (outerSource: QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector: _ -> seq<_> -> _) : QuerySource<_, 'Q> = QuerySource (Enumerable.GroupJoin(outerSource.Source, innerSource.Source, Func<_, _>(outerKeySelector), Func<_, _>(innerKeySelector), Func<_, _, _>(fun x g -> resultSelector x g))) - member __.LeftOuterJoin (outerSource:QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector: _ -> seq<_> -> _) : QuerySource<_, 'Q> = + member _.LeftOuterJoin (outerSource: QuerySource<_, 'Q>, innerSource: QuerySource<_, 'Q>, outerKeySelector, innerKeySelector, resultSelector: _ -> seq<_> -> _) : QuerySource<_, 'Q> = QuerySource (Enumerable.GroupJoin(outerSource.Source, innerSource.Source, Func<_, _>(outerKeySelector), Func<_, _>(innerKeySelector), Func<_, _, _>(fun x g -> resultSelector x (g.DefaultIfEmpty())))) - member __.RunQueryAsValue (q:Quotations.Expr<'T>) : 'T = + member _.RunQueryAsValue (q: Quotations.Expr<'T>) : 'T = ForwardDeclarations.Query.Execute q - member __.RunQueryAsEnumerable (q:Quotations.Expr>) : IEnumerable<'T> = + member _.RunQueryAsEnumerable (q: Quotations.Expr>) : IEnumerable<'T> = let queryAfterEliminatingNestedQueries = ForwardDeclarations.Query.EliminateNestedQueries q let queryAfterCleanup = Microsoft.FSharp.Linq.RuntimeHelpers.Adapters.CleanupLeaf queryAfterEliminatingNestedQueries (LeafExpressionConverter.EvaluateQuotation queryAfterCleanup :?> QuerySource<'T, IEnumerable>).Source - member __.RunQueryAsQueryable (q:Quotations.Expr>) : IQueryable<'T> = + member _.RunQueryAsQueryable (q: Quotations.Expr>) : IQueryable<'T> = ForwardDeclarations.Query.Execute q member this.Run q = this.RunQueryAsQueryable q @@ -340,7 +340,7 @@ module Query = /// This reverses this encoding, but does not de-tuple the input variable into multiple variables. let (|LambdaNoDetupling|_|) (lam: Expr) = /// Strip off the 'let' bindings for an LambdaNoDetupling - let rec stripSuccessiveProjLets (p:Var) n expr = + let rec stripSuccessiveProjLets (p: Var) n expr = match expr with | Let(v1, (TupleGet(Var pA, m) as e1), rest) when p = pA && m = n-> @@ -399,14 +399,14 @@ module Query = let MakeGenericInstanceMethod (methHandle:System.RuntimeMethodHandle) = let methInfo = methHandle |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo - (fun (obj:Expr, tyargs: Type list, args: Expr list) -> Expr.Call (obj, BindGenericStaticMethod methInfo tyargs, args)) + (fun (obj: Expr, tyargs: Type list, args: Expr list) -> Expr.Call (obj, BindGenericStaticMethod methInfo tyargs, args)) let ImplicitExpressionConversionHelperMethodInfo = methodhandleof (fun e -> LeafExpressionConverter.ImplicitExpressionConversionHelper e) |> System.Reflection.MethodInfo.GetMethodFromHandle :?> MethodInfo - let MakeImplicitExpressionConversion (x:Expr) = Expr.Call (ImplicitExpressionConversionHelperMethodInfo.MakeGenericMethod [| x.Type |], [ x ]) + let MakeImplicitExpressionConversion (x: Expr) = Expr.Call (ImplicitExpressionConversionHelperMethodInfo.MakeGenericMethod [| x.Type |], [ x ]) let NT = typedefof> @@ -459,14 +459,14 @@ module Query = let MakeOrCallContainsOrElementAt FQ FE = let (CQ, MQ), (CE, ME) = MakersCallers2 FQ FE - let Make (isIQ, srcItemTy:Type, src:Expr, key:Expr) = + let Make (isIQ, srcItemTy: Type, src: Expr, key: Expr) = if isIQ then //let key = MakeImplicitExpressionConversion key MQ ([srcItemTy], [src; key]) else ME ([srcItemTy], [src; key]) - let Call (isIQ, srcItemTy, src:obj, key:Expr) = + let Call (isIQ, srcItemTy, src:obj, key: Expr) = let key = key |> LeafExpressionConverter.EvaluateQuotation let C = if isIQ then CQ else CE C ([srcItemTy], [src; box key]) @@ -484,7 +484,7 @@ module Query = let MakeOrCallMinByOrMaxBy FQ FE = let (CQ, MQ), (CE, ME) = MakersCallers2 FQ FE - let Make (isIQ, src:Expr, v:Var, valSelector:Expr) = + let Make (isIQ, src: Expr, v: Var, valSelector: Expr) = let srcItemTy = v.Type let keyElemTy = valSelector.Type let valSelector = FuncExprToDelegateExpr (srcItemTy, keyElemTy, v, valSelector) @@ -495,7 +495,7 @@ module Query = else ME ([srcItemTy; keyElemTy], [src; valSelector]) - let Call (isIQ, srcItemTy:Type, _keyItemTy:Type, src:obj, keyElemTy:Type, v:Var, res:Expr) = + let Call (isIQ, srcItemTy: Type, _keyItemTy: Type, src:obj, keyElemTy: Type, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, keyElemTy, v, res) CQ ([srcItemTy; keyElemTy], [src; box selector]) @@ -505,30 +505,30 @@ module Query = Make, Call let (MakeMinBy: bool * Expr * Var * Expr -> Expr), (CallMinBy : bool * Type * Type * obj * Type * Var * Expr -> obj) = - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Min(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, 'Result>) -> Enumerable.Min(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Min(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, 'Result>) -> Enumerable.Min(x, y)) MakeOrCallMinByOrMaxBy FQ FE let MakeMaxBy, CallMaxBy = - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Max(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Max(x, y)) let FE = methodhandleof (fun (x, y: Func<_, 'Result>) -> Enumerable.Max(x, y)) MakeOrCallMinByOrMaxBy FQ FE let MakeMinByNullable, CallMinByNullable = // Note there is no separate LINQ overload for Min on nullables - the one implementation just magically skips nullable elements - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Min(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, 'Result>) -> Enumerable.Min(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Min(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, 'Result>) -> Enumerable.Min(x, y)) MakeOrCallMinByOrMaxBy FQ FE let MakeMaxByNullable, CallMaxByNullable = // Note there is no separate LINQ overload for Max on nullables - the one implementation just magically skips nullable elements - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Max(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, 'Result>) -> Enumerable.Max(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Max(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, 'Result>) -> Enumerable.Max(x, y)) MakeOrCallMinByOrMaxBy FQ FE let MakeOrCallAnyOrAllOrFirstFind FQ FE = let (CQ, MQ), (CE, ME) = MakersCallers2 FQ FE - let Make (isIQ, src:Expr, v:Var, predicate:Expr) = + let Make (isIQ, src: Expr, v: Var, predicate: Expr) = let srcItemTy= v.Type let predicate = FuncExprToDelegateExpr (srcItemTy, boolTy, v, predicate) @@ -538,7 +538,7 @@ module Query = else ME ([srcItemTy], [src; predicate]) - let Call (isIQ, srcItemTy:Type, src:obj, v:Var, res:Expr) = + let Call (isIQ, srcItemTy: Type, src:obj, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, boolTy, v, res) CQ ([srcItemTy], [src; box selector]) @@ -548,18 +548,18 @@ module Query = Make, Call let MakeAny, CallAny = - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Any(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.Any(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Any(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.Any(x, y)) MakeOrCallAnyOrAllOrFirstFind FQ FE let MakeAll, CallAll = - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.All(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.All(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.All(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.All(x, y)) MakeOrCallAnyOrAllOrFirstFind FQ FE let MakeFirstFind, CallFirstFind = - let FQ = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.First(x, y)) - let FE = methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.First(x, y)) + let FQ = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.First(x, y)) + let FE = methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.First(x, y)) MakeOrCallAnyOrAllOrFirstFind FQ FE let MakeOrCallAverageByOrSumByGeneric (isNullable, fq_double, fq_single, fq_decimal, fq_int32, fq_int64, fe_double, fe_single, fe_decimal, fe_int32, fe_int64, FE) = @@ -572,7 +572,7 @@ module Query = let (CE, ME) = MakersCallersInstance FE let failDueToUnsupportedInputTypeInSumByOrAverageBy() = invalidOp (SR.GetString(SR.failDueToUnsupportedInputTypeInSumByOrAverageBy)) - let Make (qb:Expr, isIQ, src:Expr, v:Var, res:Expr) = + let Make (qb: Expr, isIQ, src: Expr, v: Var, res: Expr) = let srcItemTy = v.Type let resTy = res.Type let resTyNoNullable = @@ -611,7 +611,7 @@ module Query = let selector = Expr.Lambda (v, res) ME (qb, [srcItemTy; qTy; resTyNoNullable], [src; selector]) - let Call (qb:obj, isIQ, srcItemTy:Type, resTyNoNullable:Type, src:obj, resTy:Type, v:Var, res:Expr) = + let Call (qb:obj, isIQ, srcItemTy: Type, resTyNoNullable: Type, src:obj, resTy: Type, v: Var, res: Expr) = if isIQ then let selector = FuncExprToLinqFunc2Expression (srcItemTy, resTy, v, res) let caller = @@ -654,65 +654,65 @@ module Query = Make, Call let MakeAverageBy, CallAverageBy = - let FQ_double = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Average(x, y)) - let FQ_single = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Average(x, y)) - let FQ_decimal = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Average(x, y)) - let FQ_int32 = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Average(x, y)) - let FQ_int64 = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Average(x, y)) - let FE_double = methodhandleof (fun (x, y:Func<_, double>) -> Enumerable.Average(x, y)) - let FE_single = methodhandleof (fun (x, y:Func<_, single>) -> Enumerable.Average(x, y)) - let FE_decimal = methodhandleof (fun (x, y:Func<_, decimal>) -> Enumerable.Average(x, y)) - let FE_int32 = methodhandleof (fun (x, y:Func<_, int32>) -> Enumerable.Average(x, y)) - let FE_int64 = methodhandleof (fun (x, y:Func<_, int64>) -> Enumerable.Average(x, y)) - let FE = methodhandleof (fun (query:QueryBuilder, arg1:QuerySource<_, _>, arg2:_->double) -> query.AverageBy(arg1, arg2)) + let FQ_double = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Average(x, y)) + let FQ_single = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Average(x, y)) + let FQ_decimal = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Average(x, y)) + let FQ_int32 = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Average(x, y)) + let FQ_int64 = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Average(x, y)) + let FE_double = methodhandleof (fun (x, y: Func<_, double>) -> Enumerable.Average(x, y)) + let FE_single = methodhandleof (fun (x, y: Func<_, single>) -> Enumerable.Average(x, y)) + let FE_decimal = methodhandleof (fun (x, y: Func<_, decimal>) -> Enumerable.Average(x, y)) + let FE_int32 = methodhandleof (fun (x, y: Func<_, int32>) -> Enumerable.Average(x, y)) + let FE_int64 = methodhandleof (fun (x, y: Func<_, int64>) -> Enumerable.Average(x, y)) + let FE = methodhandleof (fun (query:QueryBuilder, arg1: QuerySource<_, _>, arg2:_->double) -> query.AverageBy(arg1, arg2)) MakeOrCallAverageByOrSumByGeneric (false, FQ_double, FQ_single, FQ_decimal, FQ_int32, FQ_int64, FE_double, FE_single, FE_decimal, FE_int32, FE_int64, FE) let MakeAverageByNullable, CallAverageByNullable = - let FQ_double = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Average(x, y)) - let FQ_single = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Average(x, y)) - let FQ_decimal = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Average(x, y)) - let FQ_int32 = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Average(x, y)) - let FQ_int64 = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Average(x, y)) - let FE_double = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Average(x, y)) - let FE_single = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Average(x, y)) - let FE_decimal = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Average(x, y)) - let FE_int32 = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Average(x, y)) - let FE_int64 = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Average(x, y)) - let FE = methodhandleof (fun (query:QueryBuilder, arg1:QuerySource<_, _>, arg2:_->Nullable) -> query.AverageByNullable(arg1, arg2)) + let FQ_double = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Average(x, y)) + let FQ_single = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Average(x, y)) + let FQ_decimal = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Average(x, y)) + let FQ_int32 = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Average(x, y)) + let FQ_int64 = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Average(x, y)) + let FE_double = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Average(x, y)) + let FE_single = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Average(x, y)) + let FE_decimal = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Average(x, y)) + let FE_int32 = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Average(x, y)) + let FE_int64 = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Average(x, y)) + let FE = methodhandleof (fun (query:QueryBuilder, arg1: QuerySource<_, _>, arg2:_->Nullable) -> query.AverageByNullable(arg1, arg2)) MakeOrCallAverageByOrSumByGeneric (true, FQ_double, FQ_single, FQ_decimal, FQ_int32, FQ_int64, FE_double, FE_single, FE_decimal, FE_int32, FE_int64, FE) let MakeSumBy, CallSumBy = - let FQ_double = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_single = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_decimal = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_int32 = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_int64 = methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Sum(x, y)) - let FE_double = methodhandleof (fun (x, y:Func<_, double>) -> Enumerable.Sum(x, y)) - let FE_single = methodhandleof (fun (x, y:Func<_, single>) -> Enumerable.Sum(x, y)) - let FE_decimal = methodhandleof (fun (x, y:Func<_, decimal>) -> Enumerable.Sum(x, y)) - let FE_int32 = methodhandleof (fun (x, y:Func<_, int32>) -> Enumerable.Sum(x, y)) - let FE_int64 = methodhandleof (fun (x, y:Func<_, int64>) -> Enumerable.Sum(x, y)) - let FE = methodhandleof (fun (query:QueryBuilder, arg1:QuerySource<_, _>, arg2:_->double) -> query.SumBy(arg1, arg2)) + let FQ_double = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_single = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_decimal = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_int32 = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_int64 = methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Sum(x, y)) + let FE_double = methodhandleof (fun (x, y: Func<_, double>) -> Enumerable.Sum(x, y)) + let FE_single = methodhandleof (fun (x, y: Func<_, single>) -> Enumerable.Sum(x, y)) + let FE_decimal = methodhandleof (fun (x, y: Func<_, decimal>) -> Enumerable.Sum(x, y)) + let FE_int32 = methodhandleof (fun (x, y: Func<_, int32>) -> Enumerable.Sum(x, y)) + let FE_int64 = methodhandleof (fun (x, y: Func<_, int64>) -> Enumerable.Sum(x, y)) + let FE = methodhandleof (fun (query:QueryBuilder, arg1: QuerySource<_, _>, arg2:_->double) -> query.SumBy(arg1, arg2)) MakeOrCallAverageByOrSumByGeneric (false, FQ_double, FQ_single, FQ_decimal, FQ_int32, FQ_int64, FE_double, FE_single, FE_decimal, FE_int32, FE_int64, FE) let MakeSumByNullable, CallSumByNullable = - let FQ_double = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_single = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_decimal = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_int32 = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Sum(x, y)) - let FQ_int64 = methodhandleof (fun (x, y:Expression>>) -> System.Linq.Queryable.Sum(x, y)) - let FE_double = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Sum(x, y)) - let FE_single = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Sum(x, y)) - let FE_decimal = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Sum(x, y)) - let FE_int32 = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Sum(x, y)) - let FE_int64 = methodhandleof (fun (x, y:Func<_, Nullable>) -> Enumerable.Sum(x, y)) - let FE = methodhandleof (fun (query:QueryBuilder, arg1:QuerySource<_, _>, arg2:_->Nullable) -> query.SumByNullable(arg1, arg2)) + let FQ_double = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_single = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_decimal = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_int32 = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Sum(x, y)) + let FQ_int64 = methodhandleof (fun (x, y: Expression>>) -> System.Linq.Queryable.Sum(x, y)) + let FE_double = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Sum(x, y)) + let FE_single = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Sum(x, y)) + let FE_decimal = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Sum(x, y)) + let FE_int32 = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Sum(x, y)) + let FE_int64 = methodhandleof (fun (x, y: Func<_, Nullable>) -> Enumerable.Sum(x, y)) + let FE = methodhandleof (fun (query:QueryBuilder, arg1: QuerySource<_, _>, arg2:_->Nullable) -> query.SumByNullable(arg1, arg2)) MakeOrCallAverageByOrSumByGeneric (true, FQ_double, FQ_single, FQ_decimal, FQ_int32, FQ_int64, FE_double, FE_single, FE_decimal, FE_int32, FE_int64, FE) let MakeOrCallSimpleOp FQ FE = let (CQ, MQ), (CE, ME) = MakersCallers2 FQ FE - let Make (isIQ, srcItemTy, src:Expr) = + let Make (isIQ, srcItemTy, src: Expr) = if isIQ then MQ ([srcItemTy], [src]) else @@ -745,9 +745,9 @@ module Query = | No = 1 let MakeSelect = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Select(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.Select(x, y))) - fun (canElim, isIQ, src:Expr, v:Var, f:Expr) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Select(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.Select(x, y))) + fun (canElim, isIQ, src: Expr, v: Var, f: Expr) -> // Eliminate degenerate 'Select(x => x)', except for the very outer-most cases match f with @@ -767,7 +767,7 @@ module Query = let MakeAppend = let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y) -> System.Linq.Queryable.Concat(x, y))) let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y) -> Enumerable.Concat(x, y))) - fun (isIQ, srcItemTy, src1:Expr, src2:Expr) -> + fun (isIQ, srcItemTy, src1: Expr, src2: Expr) -> if isIQ then FQ ([srcItemTy], [src1; src2]) else @@ -788,9 +788,9 @@ module Query = MakeAsQueryable (ty, MakeEnumerableEmpty ty) let MakeSelectMany = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x:IQueryable<_>, y:Expression>, z:Expression>) -> System.Linq.Queryable.SelectMany(x, y, z))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x:IEnumerable<_>, y:Func<_, _>, z:Func<_, _, _>) -> Enumerable.SelectMany(x, y, z))) - fun (isIQ, resTy:Type, src:Expr, srcItemVar:Var, interimSelectorBody:Expr, interimVar:Var, targetSelectorBody:Expr) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x: IQueryable<_>, y: Expression>, z: Expression>) -> System.Linq.Queryable.SelectMany(x, y, z))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x: IEnumerable<_>, y: Func<_, _>, z: Func<_, _, _>) -> Enumerable.SelectMany(x, y, z))) + fun (isIQ, resTy: Type, src: Expr, srcItemVar: Var, interimSelectorBody: Expr, interimVar: Var, targetSelectorBody: Expr) -> let srcItemTy = srcItemVar.Type let interimTy = interimVar.Type let interimSelector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, MakeIEnumerableTy interimTy), [srcItemVar], interimSelectorBody) @@ -804,9 +804,9 @@ module Query = FE ([srcItemTy; interimTy; resTy], [src; interimSelector; targetSelector]) let MakeWhere = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.Where(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.Where(x, y))) - fun (isIQ, src:Expr, v:Var, f) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.Where(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.Where(x, y))) + fun (isIQ, src: Expr, v: Var, f) -> let selector = Expr.NewDelegate (MakeQueryFuncTy(v.Type, typeof), [v], f) if isIQ then @@ -816,7 +816,7 @@ module Query = FE ([v.Type], [src; selector]) let MakeOrderByOrThenBy FQ FE = - fun (isIQ, src:Expr, v:Var, keySelector:Expr) -> + fun (isIQ, src: Expr, v: Var, keySelector: Expr) -> let srcItemTy = v.Type let keyItemTy = keySelector.Type let selector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, keyItemTy), [v], keySelector) @@ -827,23 +827,23 @@ module Query = FE ([srcItemTy; keyItemTy], [src; selector]) let MakeOrderBy = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.OrderBy(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.OrderBy(x, y))) + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.OrderBy(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.OrderBy(x, y))) MakeOrderByOrThenBy FQ FE let MakeOrderByDescending = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.OrderByDescending(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.OrderByDescending(x, y))) + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.OrderByDescending(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.OrderByDescending(x, y))) MakeOrderByOrThenBy FQ FE let MakeThenBy = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.ThenBy(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.ThenBy(x, y))) + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.ThenBy(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.ThenBy(x, y))) MakeOrderByOrThenBy FQ FE let MakeThenByDescending = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.ThenByDescending(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.ThenByDescending(x, y))) + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.ThenByDescending(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.ThenByDescending(x, y))) MakeOrderByOrThenBy FQ FE // The keyItemTy differentiates these @@ -858,7 +858,7 @@ module Query = let GenMakeSkipWhileOrTakeWhile FQ FE = let FQ = MakeGenericStaticMethod FQ let FE = MakeGenericStaticMethod FE - fun (isIQ, src:Expr, v:Var, predicate) -> + fun (isIQ, src: Expr, v: Var, predicate) -> let srcItemTy = v.Type let selector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, boolTy), [v], predicate) if isIQ then @@ -870,7 +870,7 @@ module Query = let MakeSkipOrTake FQ FE = let FQ = MakeGenericStaticMethod FQ let FE = MakeGenericStaticMethod FE - fun (isIQ, srcItemTy, src:Expr, count) -> + fun (isIQ, srcItemTy, src: Expr, count) -> if isIQ then FQ ([srcItemTy], [src; count]) else @@ -888,27 +888,27 @@ module Query = let MakeSkipWhile = GenMakeSkipWhileOrTakeWhile - (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.SkipWhile(x, y))) - (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.SkipWhile(x, y))) + (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.SkipWhile(x, y))) + (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.SkipWhile(x, y))) let MakeTakeWhile = GenMakeSkipWhileOrTakeWhile - (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.TakeWhile(x, y))) - (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.TakeWhile(x, y))) + (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.TakeWhile(x, y))) + (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.TakeWhile(x, y))) let MakeDistinct = let FQ = MakeGenericStaticMethod (methodhandleof (fun x -> System.Linq.Queryable.Distinct x)) let FE = MakeGenericStaticMethod (methodhandleof (fun x -> Enumerable.Distinct x)) - fun (isIQ, srcItemTy, src:Expr) -> + fun (isIQ, srcItemTy, src: Expr) -> if isIQ then FQ ([srcItemTy], [src]) else FE ([srcItemTy], [src]) let MakeGroupBy = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>) -> System.Linq.Queryable.GroupBy(x, y))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>) -> Enumerable.GroupBy(x, y))) - fun (isIQ, src:Expr, v:Var, keySelector:Expr) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>) -> System.Linq.Queryable.GroupBy(x, y))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>) -> Enumerable.GroupBy(x, y))) + fun (isIQ, src: Expr, v: Var, keySelector: Expr) -> let srcItemTy = v.Type let keyTy = keySelector.Type let keySelector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, keyTy), [v], keySelector) @@ -920,9 +920,9 @@ module Query = FE ([srcItemTy; keyTy], [src; keySelector]) let MakeGroupValBy = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y:Expression>, z:Expression>) -> System.Linq.Queryable.GroupBy(x, y, z))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y:Func<_, _>, z:Func<_, _>) -> Enumerable.GroupBy(x, y, z))) - fun (isIQ, srcItemTy, keyTy, elementTy, src:Expr, v1, keySelector, v2, elementSelector) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (x, y: Expression>, z: Expression>) -> System.Linq.Queryable.GroupBy(x, y, z))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (x, y: Func<_, _>, z: Func<_, _>) -> Enumerable.GroupBy(x, y, z))) + fun (isIQ, srcItemTy, keyTy, elementTy, src: Expr, v1, keySelector, v2, elementSelector) -> let keySelector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, keyTy), [v1], keySelector) let elementSelector = Expr.NewDelegate (MakeQueryFuncTy(srcItemTy, elementTy), [v2], elementSelector) @@ -934,9 +934,9 @@ module Query = FE ([srcItemTy; keyTy; elementTy], [src; keySelector; elementSelector]) let MakeJoin = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3:Expression>, a4:Expression>, a5:Expression>) -> System.Linq.Queryable.Join(a1, a2, a3, a4, a5))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3:Func<_, _>, a4:Func<_, _>, a5:Func<_, _, _>) -> Enumerable.Join(a1, a2, a3, a4, a5))) - fun (isIQ, outerSourceTy, innerSourceTy, keyTy, resTy, outerSource:Expr, innerSource:Expr, outerKeyVar, outerKeySelector, innerKeyVar, innerKeySelector, outerResultKeyVar, innerResultKeyVar, elementSelector) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3: Expression>, a4: Expression>, a5: Expression>) -> System.Linq.Queryable.Join(a1, a2, a3, a4, a5))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3: Func<_, _>, a4: Func<_, _>, a5: Func<_, _, _>) -> Enumerable.Join(a1, a2, a3, a4, a5))) + fun (isIQ, outerSourceTy, innerSourceTy, keyTy, resTy, outerSource: Expr, innerSource: Expr, outerKeyVar, outerKeySelector, innerKeyVar, innerKeySelector, outerResultKeyVar, innerResultKeyVar, elementSelector) -> let outerKeySelector = Expr.NewDelegate (MakeQueryFuncTy(outerSourceTy, keyTy), [outerKeyVar], outerKeySelector) let innerKeySelector = Expr.NewDelegate (MakeQueryFuncTy(innerSourceTy, keyTy), [innerKeyVar], innerKeySelector) let elementSelector = Expr.NewDelegate (MakeQueryFunc2Ty(outerSourceTy, innerSourceTy, resTy), [outerResultKeyVar; innerResultKeyVar], elementSelector) @@ -950,9 +950,9 @@ module Query = FE ([outerSourceTy; innerSourceTy; keyTy; resTy], [outerSource; innerSource; outerKeySelector; innerKeySelector; elementSelector]) let MakeGroupJoin = - let FQ = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3:Expression>, a4:Expression>, a5:Expression>) -> System.Linq.Queryable.GroupJoin(a1, a2, a3, a4, a5))) - let FE = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3:Func<_, _>, a4:Func<_, _>, a5:Func<_, _, _>) -> Enumerable.GroupJoin(a1, a2, a3, a4, a5))) - fun (isIQ, outerSourceTy, innerSourceTy, keyTy, resTy, outerSource:Expr, innerSource:Expr, outerKeyVar, outerKeySelector, innerKeyVar, innerKeySelector, outerResultKeyVar, innerResultGroupVar, elementSelector) -> + let FQ = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3: Expression>, a4: Expression>, a5: Expression>) -> System.Linq.Queryable.GroupJoin(a1, a2, a3, a4, a5))) + let FE = MakeGenericStaticMethod (methodhandleof (fun (a1, a2, a3: Func<_, _>, a4: Func<_, _>, a5: Func<_, _, _>) -> Enumerable.GroupJoin(a1, a2, a3, a4, a5))) + fun (isIQ, outerSourceTy, innerSourceTy, keyTy, resTy, outerSource: Expr, innerSource: Expr, outerKeyVar, outerKeySelector, innerKeyVar, innerKeySelector, outerResultKeyVar, innerResultGroupVar, elementSelector) -> let outerKeySelector = Expr.NewDelegate (MakeQueryFuncTy(outerSourceTy, keyTy), [outerKeyVar], outerKeySelector) let innerKeySelector = Expr.NewDelegate (MakeQueryFuncTy(innerSourceTy, keyTy), [innerKeyVar], innerKeySelector) let elementSelector = Expr.NewDelegate (MakeQueryFunc2Ty(outerSourceTy, MakeIEnumerableTy innerSourceTy, resTy), [outerResultKeyVar; innerResultGroupVar], elementSelector) @@ -964,8 +964,8 @@ module Query = else FE ([outerSourceTy; innerSourceTy; keyTy; resTy], [outerSource; innerSource; outerKeySelector; innerKeySelector; elementSelector]) - let RewriteExpr f (q : Expr) = - let rec walk (p : Expr) = + let RewriteExpr f (q: Expr) = + let rec walk (p: Expr) = match f walk p with | Some r -> r | None -> @@ -975,7 +975,7 @@ module Query = | ExprShape.ShapeVar _ -> p walk q - let (|LetExprReduction|_|) (p : Expr) = + let (|LetExprReduction|_|) (p: Expr) = match p with | Let(v, e, body) -> let body = body.Substitute (fun v2 -> if v = v2 then Some e else None) @@ -983,7 +983,7 @@ module Query = | _ -> None - let (|MacroReduction|_|) (p : Expr) = + let (|MacroReduction|_|) (p: Expr) = match p with | Applications(Lambdas(vs, body), args) @@ -1042,11 +1042,11 @@ module Query = let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run v)) - let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v : Expr<'a>) -> b.Run v) : 'a) + let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr<'a>) -> b.Run v) : 'a) - let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v : Expr> ) -> b.Run v)) + let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr> ) -> b.Run v)) - let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, source:QuerySource, body) -> b.For(source, body))) + let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, source: QuerySource, body) -> b.For(source, body))) let (|CallQueryBuilderYield|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value) -> b.Yield value)) @@ -1054,9 +1054,9 @@ module Query = let (|CallQueryBuilderZero|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder) -> b.Zero())) - let (|CallQueryBuilderSourceIQueryable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value:IQueryable<_>) -> b.Source value)) + let (|CallQueryBuilderSourceIQueryable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value: IQueryable<_>) -> b.Source value)) - let (|CallQueryBuilderSourceIEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value:IEnumerable<_>) -> b.Source value)) + let (|CallQueryBuilderSourceIEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value: IEnumerable<_>) -> b.Source value)) let (|CallSortBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2) -> query.SortBy(arg1, arg2))) @@ -1124,13 +1124,13 @@ module Query = let (|CallLeftOuterJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.LeftOuterJoin(arg1, arg2, arg3, arg4, arg5))) - let (|CallAverageBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1:QuerySource, arg2:(double->double)) -> query.AverageBy(arg1, arg2))) + let (|CallAverageBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->double)) -> query.AverageBy(arg1, arg2))) - let (|CallSumBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1:QuerySource, arg2:(double->double)) -> query.SumBy(arg1, arg2))) + let (|CallSumBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->double)) -> query.SumBy(arg1, arg2))) - let (|CallAverageByNullable|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1:QuerySource, arg2:(double->Nullable)) -> query.AverageByNullable(arg1, arg2))) + let (|CallAverageByNullable|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->Nullable)) -> query.AverageByNullable(arg1, arg2))) - let (|CallSumByNullable|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1:QuerySource, arg2:(double->Nullable)) -> query.SumByNullable(arg1, arg2))) + let (|CallSumByNullable|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->Nullable)) -> query.SumByNullable(arg1, arg2))) let (|CallCount|_|) = (|SpecificCall1|_|) (methodhandleof (fun (query:QueryBuilder, arg1) -> query.Count arg1)) @@ -1200,7 +1200,7 @@ module Query = /// function will accept mutable tuples. In this case, the function is implemented by replacing /// uses of the immutConsumingVar in the body of immutConsumingExpr with a tuple expression built /// from the elements of mutConsumingVar, and then simplifying the overall result. - let ConvertImmutableConsumerToMutableConsumer conv (immutConsumingVar:Var, immutConsumingExpr:Expr) : Var * Expr = + let ConvertImmutableConsumerToMutableConsumer conv (immutConsumingVar: Var, immutConsumingExpr: Expr) : Var * Expr = match conv with | NoConv -> (immutConsumingVar, immutConsumingExpr) | _ -> @@ -1268,7 +1268,7 @@ module Query = /// /// The output query will use either Queryable.* or Enumerable.* operators depending on whether /// the inputs to the queries have type IQueryable or IEnumerable. - let rec TransInner canElim check (immutQuery:Expr) = + let rec TransInner canElim check (immutQuery: Expr) = //assert (IsIQueryableTy immutQuery.Type || IsQuerySourceTy immutQuery.Type || IsIEnumerableTy immutQuery.Type) // printfn "TransInner: %A" tm match immutQuery with @@ -1328,7 +1328,7 @@ module Query = let mutElemTy = ConvImmutableTypeToMutableType selectorConv immutResElemTy /// Commit the result of TransInner in the case where the result is immediately inside a 'SelectMany' - let (mutInterimSelectorBodyPreCoerce:Expr), mutInterimVar, mutTargetSelector = + let (mutInterimSelectorBodyPreCoerce: Expr), mutInterimVar, mutTargetSelector = match mutSelectorBodyInfo with | TransInnerResult.Select(_, _, mutInterimSelectorSource, mutInterimVar, mutTargetSelector) -> CommitTransInnerResult mutInterimSelectorSource, mutInterimVar, mutTargetSelector @@ -1474,7 +1474,7 @@ module Query = Lambda(immutInnerKeyVar, immutInnerKeySelector) LambdasNoDetupling([immutOuterResultGroupVar; immutInnerResultKeyVar], immutElementSelector)]) -> - let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar:Var, mutOuterKeySelector, mutInnerKeyVar:Var, mutInnerKeySelector:Expr) = + let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar: Var, mutOuterKeySelector, mutInnerKeyVar: Var, mutInnerKeySelector: Expr) = TransJoinInputs check (immutOuterSource, immutInnerSource, immutOuterKeyVar, immutOuterKeySelector, immutInnerKeyVar, immutInnerKeySelector) let mutOuterResultVar, mutElementSelector = ConvertImmutableConsumerToMutableConsumer outerSourceConv (immutOuterResultGroupVar, MacroExpand immutElementSelector) @@ -1498,7 +1498,7 @@ module Query = Lambda(immutInnerKeyVar, immutInnerKeySelector) LambdasNoDetupling([immutOuterResultGroupVar; immutInnerResultGroupVar], immutElementSelector)]) -> - let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar:Var, mutOuterKeySelector, mutInnerKeyVar:Var, mutInnerKeySelector:Expr) = + let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar: Var, mutOuterKeySelector, mutInnerKeyVar: Var, mutInnerKeySelector: Expr) = TransJoinInputs check (immutOuterSource, immutInnerSource, immutOuterKeyVar, immutOuterKeySelector, immutInnerKeyVar, immutInnerKeySelector) let mutOuterResultGroupVar, mutElementSelector = ConvertImmutableConsumerToMutableConsumer outerSourceConv (immutOuterResultGroupVar, MacroExpand immutElementSelector) @@ -1527,7 +1527,7 @@ module Query = // Replace uses of 'innerResultGroupVar' with 'innerResultGroupVar.DefaultIfEmpty()' and call MakeGroupJoin let immutElementSelector = immutElementSelector.Substitute (fun v -> if v = immutInnerResultGroupVar then Some (MakeDefaultIfEmpty ([immutInnerSourceTy], [Expr.Var immutInnerResultGroupVar])) else None) - let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar:Var, mutOuterKeySelector, mutInnerKeyVar:Var, mutInnerKeySelector:Expr) = + let (mutOuterSource, outerSourceConv, mutInnerSource, innerSourceConv, mutOuterKeyVar: Var, mutOuterKeySelector, mutInnerKeyVar: Var, mutInnerKeySelector: Expr) = TransJoinInputs check (immutOuterSource, immutInnerSource, immutOuterKeyVar, immutOuterKeySelector, immutInnerKeyVar, immutInnerKeySelector) let mutOuterResultGroupVar, mutElementSelector = ConvertImmutableConsumerToMutableConsumer outerSourceConv (immutOuterResultGroupVar, MacroExpand immutElementSelector) @@ -1795,7 +1795,7 @@ module Query = /// Evaluate the inner core of a query that actually produces a sequence of results. /// Do this by converting to an expression tree for a LINQ query and evaluating that. - let EvalNonNestedInner canElim (queryProducingSequence:Expr) = + let EvalNonNestedInner canElim (queryProducingSequence: Expr) = let linqQuery = TransInnerWithFinalConsume canElim queryProducingSequence let linqQueryAfterEliminatingNestedQueries = EliminateNestedQueries linqQuery @@ -1826,7 +1826,7 @@ module Query = result /// Evaluate the outer calls of a query until the inner core that actually produces a sequence of results is reached. - let rec EvalNonNestedOuter canElim (tm:Expr) = + let rec EvalNonNestedOuter canElim (tm: Expr) = match tm with | CallMinBy (_, [srcItemTy; qTy; keyItemTy], source, Lambda(v, valSelector)) -> diff --git a/src/fsharp/FSharp.Core/Query.fsi b/src/fsharp/FSharp.Core/Query.fsi index bda2b9f2ca4..118cf4b0e9d 100644 --- a/src/fsharp/FSharp.Core/Query.fsi +++ b/src/fsharp/FSharp.Core/Query.fsi @@ -11,363 +11,438 @@ namespace Microsoft.FSharp.Linq open System.Collections.Generic [] + /// /// A partial input or result in an F# query. This type is used to support the F# query syntax. + /// + /// + /// + /// Library functionality for F# query syntax and interoperability with .NET LINQ Expressions. See + /// also F# Query Expressions in the F# Language Guide. + /// type QuerySource<'T, 'Q> = /// /// A method used to support the F# query syntax. /// - new : seq<'T> -> QuerySource<'T,'Q> + new: seq<'T> -> QuerySource<'T,'Q> + /// /// A property used to support the F# query syntax. /// - member Source : seq<'T> + member Source: seq<'T> [] - /// The type used to support the F# query syntax. Use 'query { ... }' to use the query syntax. + /// The type used to support the F# query syntax. Use 'query { ... }' to use the query syntax. See + /// also F# Query Expressions in the F# Language Guide. type QueryBuilder = /// Create an instance of this builder. Use 'query { ... }' to use the query syntax. - new : unit -> QueryBuilder + new: unit -> QueryBuilder /// /// A method used to support the F# query syntax. Inputs to queries are implicitly wrapped by a call to one of the overloads of this method. /// - member Source : source:IQueryable<'T> -> QuerySource<'T,'Q> + /// + /// + member Source: source:IQueryable<'T> -> QuerySource<'T,'Q> /// /// A method used to support the F# query syntax. Inputs to queries are implicitly wrapped by a call to one of the overloads of this method. /// - member Source : source:IEnumerable<'T> -> QuerySource<'T,IEnumerable> + /// + /// + member Source: source:IEnumerable<'T> -> QuerySource<'T,IEnumerable> /// /// A method used to support the F# query syntax. Projects each element of a sequence to another sequence and combines the resulting sequences into one sequence. /// - member For : source:QuerySource<'T,'Q> * body:('T -> QuerySource<'Result,'Q2>) -> QuerySource<'Result,'Q> + /// + /// + member For: source:QuerySource<'T,'Q> * body:('T -> QuerySource<'Result,'Q2>) -> QuerySource<'Result,'Q> /// /// A method used to support the F# query syntax. Returns an empty sequence that has the specified type argument. /// - member Zero : unit -> QuerySource<'T,'Q> + /// + /// + member Zero: unit -> QuerySource<'T,'Q> /// /// A method used to support the F# query syntax. Returns a sequence of length one that contains the specified value. /// - member Yield : value:'T -> QuerySource<'T,'Q> + /// + /// + member Yield: value:'T -> QuerySource<'T,'Q> /// /// A method used to support the F# query syntax. Returns a sequence that contains the specified values. /// - member YieldFrom : computation:QuerySource<'T,'Q> -> QuerySource<'T,'Q> + /// + /// + member YieldFrom: computation:QuerySource<'T,'Q> -> QuerySource<'T,'Q> /// /// A method used to support the F# query syntax. Indicates that the query should be passed as a quotation to the Run method. /// - member Quote : Quotations.Expr<'T> -> Quotations.Expr<'T> + /// + /// + member Quote: Quotations.Expr<'T> -> Quotations.Expr<'T> /// /// A method used to support the F# query syntax. Runs the given quotation as a query using LINQ IQueryable rules. /// - member Run : Quotations.Expr> -> IQueryable<'T> - member internal RunQueryAsQueryable : Quotations.Expr> -> IQueryable<'T> - member internal RunQueryAsEnumerable : Quotations.Expr> -> seq<'T> - member internal RunQueryAsValue : Quotations.Expr<'T> -> 'T + /// + /// + member Run: Quotations.Expr> -> IQueryable<'T> + member internal RunQueryAsQueryable: Quotations.Expr> -> IQueryable<'T> + member internal RunQueryAsEnumerable: Quotations.Expr> -> seq<'T> + member internal RunQueryAsValue: Quotations.Expr<'T> -> 'T /// A query operator that determines whether the selected elements contains a specified element. /// + /// + /// [] - member Contains : source:QuerySource<'T,'Q> * key:'T -> bool + member Contains: source:QuerySource<'T,'Q> * key:'T -> bool /// A query operator that returns the number of selected elements. /// + /// + /// [] - member Count : source:QuerySource<'T,'Q> -> int + member Count: source:QuerySource<'T,'Q> -> int /// A query operator that selects the last element of those selected so far. /// + /// + /// [] - member Last : source:QuerySource<'T,'Q> -> 'T + member Last: source:QuerySource<'T,'Q> -> 'T /// A query operator that selects the last element of those selected so far, or a default value if no element is found. /// + /// + /// [] - member LastOrDefault : source:QuerySource<'T,'Q> -> 'T + member LastOrDefault: source:QuerySource<'T,'Q> -> 'T /// A query operator that selects the single, specific element selected so far /// + /// + /// [] - member ExactlyOne : source:QuerySource<'T,'Q> -> 'T + member ExactlyOne: source:QuerySource<'T,'Q> -> 'T /// A query operator that selects the single, specific element of those selected so far, or a default value if that element is not found. /// + /// + /// [] - member ExactlyOneOrDefault : source:QuerySource<'T,'Q> -> 'T + member ExactlyOneOrDefault: source:QuerySource<'T,'Q> -> 'T /// A query operator that selects the first element of those selected so far, or a default value if the sequence contains no elements. /// + /// + /// [] - member HeadOrDefault : source:QuerySource<'T,'Q> -> 'T + member HeadOrDefault: source:QuerySource<'T,'Q> -> 'T /// A query operator that projects each of the elements selected so far. /// + /// + /// [] - member Select : source:QuerySource<'T,'Q> * [] projection:('T -> 'Result) -> QuerySource<'Result,'Q> + member Select: source:QuerySource<'T,'Q> * [] projection:('T -> 'Result) -> QuerySource<'Result,'Q> /// A query operator that selects those elements based on a specified predicate. /// + /// + /// [] - member Where : source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> QuerySource<'T,'Q> + member Where: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> QuerySource<'T,'Q> /// A query operator that selects a value for each element selected so far and returns the minimum resulting value. /// + /// + /// [] - member MinBy : source:QuerySource<'T,'Q> * [] valueSelector:('T -> 'Value) -> 'Value when 'Value : equality and 'Value : comparison + member MinBy: source:QuerySource<'T,'Q> * [] valueSelector:('T -> 'Value) -> 'Value when 'Value: equality and 'Value: comparison /// A query operator that selects a value for each element selected so far and returns the maximum resulting value. /// + /// + /// [] - member MaxBy : source:QuerySource<'T,'Q> * [] valueSelector:('T -> 'Value) -> 'Value when 'Value : equality and 'Value : comparison + member MaxBy: source:QuerySource<'T,'Q> * [] valueSelector:('T -> 'Value) -> 'Value when 'Value: equality and 'Value: comparison /// A query operator that groups the elements selected so far according to a specified key selector. /// + /// + /// [] - member GroupBy : source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource,'Q> when 'Key : equality + member GroupBy: source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource,'Q> when 'Key: equality /// A query operator that sorts the elements selected so far in ascending order by the given sorting key. /// + /// + /// [] - member SortBy : source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member SortBy: source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that sorts the elements selected so far in descending order by the given sorting key. /// + /// + /// [] - member SortByDescending : source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member SortByDescending: source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that performs a subsequent ordering of the elements selected so far in ascending order by the given sorting key. /// This operator may only be used immediately after a 'sortBy', 'sortByDescending', 'thenBy' or 'thenByDescending', or their nullable variants. /// + /// + /// [] - member ThenBy : source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member ThenBy: source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that performs a subsequent ordering of the elements selected so far in descending order by the given sorting key. /// This operator may only be used immediately after a 'sortBy', 'sortByDescending', 'thenBy' or 'thenByDescending', or their nullable variants. /// + /// + /// [] - member ThenByDescending : source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member ThenByDescending: source:QuerySource<'T,'Q> * [] keySelector:('T -> 'Key) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that selects a value for each element selected so far and groups the elements by the given key. /// + /// + /// [] - member GroupValBy<'T,'Key,'Value,'Q> : source:QuerySource<'T,'Q> * [] resultSelector:('T -> 'Value) * [] keySelector:('T -> 'Key) -> QuerySource,'Q> when 'Key : equality + member GroupValBy<'T,'Key,'Value,'Q> : source:QuerySource<'T,'Q> * [] resultSelector:('T -> 'Value) * [] keySelector:('T -> 'Key) -> QuerySource,'Q> when 'Key: equality /// A query operator that correlates two sets of selected values based on matching keys. /// Normal usage is 'join y in elements2 on (key1 = key2)'. /// + /// + /// [] - member Join : outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> 'Inner -> 'Result) -> QuerySource<'Result,'Q> + member Join: outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> 'Inner -> 'Result) -> QuerySource<'Result,'Q> /// A query operator that correlates two sets of selected values based on matching keys and groups the results. /// Normal usage is 'groupJoin y in elements2 on (key1 = key2) into group'. /// + /// + /// [] - member GroupJoin : outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> seq<'Inner> -> 'Result) -> QuerySource<'Result,'Q> + member GroupJoin: outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> seq<'Inner> -> 'Result) -> QuerySource<'Result,'Q> /// A query operator that correlates two sets of selected values based on matching keys and groups the results. /// If any group is empty, a group with a single default value is used instead. /// Normal usage is 'leftOuterJoin y in elements2 on (key1 = key2) into group'. /// + /// + /// [] - member LeftOuterJoin : outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> seq<'Inner> -> 'Result) -> QuerySource<'Result,'Q> + member LeftOuterJoin: outerSource:QuerySource<'Outer,'Q> * innerSource:QuerySource<'Inner,'Q> * outerKeySelector:('Outer -> 'Key) * innerKeySelector:('Inner -> 'Key) * resultSelector:('Outer -> seq<'Inner> -> 'Result) -> QuerySource<'Result,'Q> #if SUPPORT_ZIP_IN_QUERIES /// /// When used in queries, this operator corresponds to the LINQ Zip operator. /// + /// + /// [] - member Zip : firstSource:QuerySource<'T1> * secondSource:QuerySource<'T2> * resultSelector:('T1 -> 'T2 -> 'Result) -> QuerySource<'Result> + member Zip: firstSource:QuerySource<'T1> * secondSource:QuerySource<'T2> * resultSelector:('T1 -> 'T2 -> 'Result) -> QuerySource<'Result> #endif /// A query operator that selects a nullable value for each element selected so far and returns the sum of these values. /// If any nullable does not have a value, it is ignored. /// + /// + /// [] - member inline SumByNullable : source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable< ^Value >) -> Nullable< ^Value > - when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) - and ^Value : (static member Zero : ^Value) - and default ^Value : int + member inline SumByNullable: source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable< ^Value >) -> Nullable< ^Value > + when ^Value: (static member ( + ): ^Value * ^Value -> ^Value) + and ^Value: (static member Zero: ^Value) + and default ^Value: int /// A query operator that selects a nullable value for each element selected so far and returns the minimum of these values. /// If any nullable does not have a value, it is ignored. /// + /// + /// [] - member MinByNullable : source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable<'Value>) -> Nullable<'Value> - when 'Value : equality - and 'Value : comparison + member MinByNullable: source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable<'Value>) -> Nullable<'Value> + when 'Value: equality + and 'Value: comparison /// A query operator that selects a nullable value for each element selected so far and returns the maximum of these values. /// If any nullable does not have a value, it is ignored. /// + /// + /// [] - member MaxByNullable : source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable<'Value>) -> Nullable<'Value> when 'Value : equality and 'Value : comparison + member MaxByNullable: source:QuerySource<'T,'Q> * [] valueSelector:('T -> Nullable<'Value>) -> Nullable<'Value> when 'Value: equality and 'Value: comparison /// A query operator that selects a nullable value for each element selected so far and returns the average of these values. /// If any nullable does not have a value, it is ignored. /// + /// + /// [] - member inline AverageByNullable : source:QuerySource<'T,'Q> * [] projection:('T -> Nullable< ^Value >) -> Nullable< ^Value > - when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) - and ^Value : (static member DivideByInt : ^Value * int -> ^Value) - and ^Value : (static member Zero : ^Value) - and default ^Value : float + member inline AverageByNullable: source:QuerySource<'T,'Q> * [] projection:('T -> Nullable< ^Value >) -> Nullable< ^Value > + when ^Value: (static member ( + ): ^Value * ^Value -> ^Value) + and ^Value: (static member DivideByInt: ^Value * int -> ^Value) + and ^Value: (static member Zero: ^Value) + and default ^Value: float /// A query operator that selects a value for each element selected so far and returns the average of these values. /// + /// + /// [] - member inline AverageBy : source:QuerySource<'T,'Q> * [] projection:('T -> ^Value) -> ^Value - when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) - and ^Value : (static member DivideByInt : ^Value * int -> ^Value) - and ^Value : (static member Zero : ^Value) - and default ^Value : float + member inline AverageBy: source:QuerySource<'T,'Q> * [] projection:('T -> ^Value) -> ^Value + when ^Value: (static member ( + ): ^Value * ^Value -> ^Value) + and ^Value: (static member DivideByInt: ^Value * int -> ^Value) + and ^Value: (static member Zero: ^Value) + and default ^Value: float /// A query operator that selects distinct elements from the elements selected so far. /// + /// + /// [] - member Distinct: source:QuerySource<'T,'Q> -> QuerySource<'T,'Q> when 'T : equality + member Distinct: source:QuerySource<'T,'Q> -> QuerySource<'T,'Q> when 'T: equality /// A query operator that determines whether any element selected so far satisfies a condition. /// + /// + /// [] member Exists: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> bool /// A query operator that selects the first element selected so far that satisfies a specified condition. /// + /// + /// [] member Find: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> 'T /// A query operator that determines whether all elements selected so far satisfies a condition. /// + /// + /// [] member All: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> bool /// A query operator that selects the first element from those selected so far. /// + /// + /// [] member Head: source:QuerySource<'T,'Q> -> 'T /// A query operator that selects the element at a specified index amongst those selected so far. /// + /// + /// [] member Nth: source:QuerySource<'T,'Q> * index:int -> 'T /// A query operator that bypasses a specified number of the elements selected so far and selects the remaining elements. /// + /// + /// [] member Skip: source:QuerySource<'T,'Q> * count:int -> QuerySource<'T,'Q> /// A query operator that bypasses elements in a sequence as long as a specified condition is true and then selects the remaining elements. /// + /// + /// [] member SkipWhile: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> QuerySource<'T,'Q> /// A query operator that selects a value for each element selected so far and returns the sum of these values. /// + /// + /// [] - member inline SumBy : source:QuerySource<'T,'Q> * [] projection:('T -> ^Value) -> ^Value - when ^Value : (static member ( + ) : ^Value * ^Value -> ^Value) - and ^Value : (static member Zero : ^Value) - and default ^Value : int + member inline SumBy: source:QuerySource<'T,'Q> * [] projection:('T -> ^Value) -> ^Value + when ^Value: (static member ( + ): ^Value * ^Value -> ^Value) + and ^Value: (static member Zero: ^Value) + and default ^Value: int /// A query operator that selects a specified number of contiguous elements from those selected so far. /// + /// + /// [] member Take: source:QuerySource<'T,'Q> * count:int-> QuerySource<'T,'Q> /// A query operator that selects elements from a sequence as long as a specified condition is true, and then skips the remaining elements. /// + /// + /// [] member TakeWhile: source:QuerySource<'T,'Q> * [] predicate:('T -> bool) -> QuerySource<'T,'Q> /// A query operator that sorts the elements selected so far in ascending order by the given nullable sorting key. /// + /// + /// [] - member SortByNullable : source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member SortByNullable: source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that sorts the elements selected so far in descending order by the given nullable sorting key. /// + /// + /// [] - member SortByNullableDescending : source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member SortByNullableDescending: source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that performs a subsequent ordering of the elements selected so far in ascending order by the given nullable sorting key. /// This operator may only be used immediately after a 'sortBy', 'sortByDescending', 'thenBy' or 'thenByDescending', or their nullable variants. /// + /// + /// [] - member ThenByNullable : source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison + member ThenByNullable: source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison /// A query operator that performs a subsequent ordering of the elements selected so far in descending order by the given nullable sorting key. /// This operator may only be used immediately after a 'sortBy', 'sortByDescending', 'thenBy' or 'thenByDescending', or their nullable variants. /// + /// + /// [] - member ThenByNullableDescending : source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key : equality and 'Key : comparison - - -#if __DEBUG - [] - [] - type QueryQuoteBuilder = - inherit QueryBuilder - new : unit -> QueryQuoteBuilder - member Run : Quotations.Expr<'T> -> Quotations.Expr<'T> - - [] - [] - type QueryLinqExprBuilder = - inherit QueryBuilder - new : unit -> QueryLinqExprBuilder - member Run : Quotations.Expr<'T> -> System.Linq.Expressions.Expression - - [] - type QueryExprBuilder = - inherit QueryBuilder - new : unit -> QueryExprBuilder - member Run : Quotations.Expr<'T> -> Quotations.Expr - - [] - type QueryExprPreTransBuilder = - inherit QueryBuilder - new : unit -> QueryExprPreTransBuilder - member Run : Quotations.Expr<'T> -> Quotations.Expr - - [] - type QueryExprPreEliminateNestedBuilder = - inherit QueryBuilder - new : unit -> QueryExprPreEliminateNestedBuilder - member Run : Quotations.Expr<'T> -> Quotations.Expr -#endif - + member ThenByNullableDescending: source:QuerySource<'T,'Q> * [] keySelector:('T -> Nullable<'Key>) -> QuerySource<'T,'Q> when 'Key: equality and 'Key: comparison namespace Microsoft.FSharp.Linq.QueryRunExtensions open Microsoft.FSharp.Core + /// + /// A module used to support the F# query syntax. + /// + /// + /// + /// Contains modules used to support the F# query syntax. + /// module LowPriority = type Microsoft.FSharp.Linq.QueryBuilder with /// /// A method used to support the F# query syntax. Runs the given quotation as a query using LINQ rules. /// [] - member Run : Microsoft.FSharp.Quotations.Expr<'T> -> 'T + member Run: Microsoft.FSharp.Quotations.Expr<'T> -> 'T + /// + /// A module used to support the F# query syntax. + /// module HighPriority = type Microsoft.FSharp.Linq.QueryBuilder with /// /// A method used to support the F# query syntax. Runs the given quotation as a query using LINQ IEnumerable rules. /// [] - member Run : Microsoft.FSharp.Quotations.Expr> -> Microsoft.FSharp.Collections.seq<'T> - - - - - - + member Run: Microsoft.FSharp.Quotations.Expr> -> Microsoft.FSharp.Collections.seq<'T> diff --git a/src/fsharp/FSharp.Core/QueryExtensions.fs b/src/fsharp/FSharp.Core/QueryExtensions.fs index bfddf7e57ef..f21c93ba648 100644 --- a/src/fsharp/FSharp.Core/QueryExtensions.fs +++ b/src/fsharp/FSharp.Core/QueryExtensions.fs @@ -283,5 +283,3 @@ module internal Adapters = tipf expr let MakeSeqConv conv = match conv with NoConv -> NoConv | _ -> SeqConv conv - - diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index 0ac47bd39a6..c7c0b7a5937 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -23,7 +23,9 @@ namespace Microsoft.FSharp.Collections let inline indexNotFound() = raise (KeyNotFoundException(SR.GetString(SR.keyNotFoundAlt))) [] - let length (array: _[]) = array.Length + let length (array: _[]) = + checkNonNull "array" array + array.Length [] let inline last (array: 'T[]) = @@ -236,7 +238,7 @@ namespace Microsoft.FSharp.Collections res [] - let inline iter action (array: 'T[]) = + let inline iter ([] action) (array: 'T[]) = checkNonNull "array" array for i = 0 to array.Length-1 do action array.[i] @@ -256,7 +258,7 @@ namespace Microsoft.FSharp.Collections Microsoft.FSharp.Primitives.Basics.Array.subUnchecked 0 i temp [] - let inline map (mapping: 'T -> 'U) (array: 'T[]) = + let inline map ([] mapping: 'T -> 'U) (array: 'T[]) = checkNonNull "array" array let res: 'U[] = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked array.Length for i = 0 to res.Length-1 do @@ -1108,7 +1110,7 @@ namespace Microsoft.FSharp.Collections acc [] - let inline minBy projection (array: _[]) = + let inline minBy ([] projection) (array: _[]) = checkNonNull "array" array if array.Length = 0 then invalidArg "array" LanguagePrimitives.ErrorStrings.InputArrayEmptyString let mutable accv = array.[0] @@ -1165,7 +1167,7 @@ namespace Microsoft.FSharp.Collections LanguagePrimitives.DivideByInt< ^U> acc array.Length [] - let inline compareWith (comparer: 'T -> 'T -> int) (array1: 'T[]) (array2: 'T[]) = + let inline compareWith ([] comparer: 'T -> 'T -> int) (array1: 'T[]) (array2: 'T[]) = checkNonNull "array1" array1 checkNonNull "array2" array2 @@ -1268,6 +1270,88 @@ namespace Microsoft.FSharp.Collections let count' = Operators.min count len Microsoft.FSharp.Primitives.Basics.Array.subUnchecked 0 count' array + [] + let removeAt (index: int) (source: 'T[]) : 'T[] = + checkNonNull "source" source + if index < 0 || index >= source.Length then invalidArg "index" "index must be within bounds of the array" + + let length = source.Length - 1 + let result = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked length + if index > 0 then + Array.Copy(source, result, index) + if length - index > 0 then + Array.Copy(source, index + 1, result, index, length - index) + + result + + [] + let removeManyAt (index: int) (count: int) (source: 'T[]) : 'T[] = + checkNonNull "source" source + if index < 0 || index > source.Length - count then invalidArg "index" "index must be within bounds of the array" + + let length = source.Length - count + let result = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked length + + if index > 0 then + Array.Copy(source, result, index) + if length - index > 0 then + Array.Copy(source, index + count, result, index, length - index) + + result + + [] + let updateAt (index: int) (value: 'T) (source: 'T[]) : 'T[] = + checkNonNull "source" source + if index < 0 || index >= source.Length then invalidArg "index" "index must be within bounds of the array" + + let length = source.Length + let result = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked length + + if length > 0 then + Array.Copy(source, result, length) + result.[index] <- value + + result + + [] + let insertAt (index: int) (value: 'T) (source: 'T[]) : 'T[] = + checkNonNull "source" source + if index < 0 || index > source.Length then invalidArg "index" "index must be within bounds of the array" + + let length = source.Length + 1 + let result = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked length + + if index > 0 then + Array.Copy(source, result, index) + + result.[index] <- value + + if source.Length - index > 0 then + Array.Copy(source, index, result, index + 1, source.Length - index) + + result + + [] + let insertManyAt (index: int) (values: seq<'T>) (source: 'T[]) : 'T[] = + checkNonNull "source" source + if index < 0 || index > source.Length then invalidArg "index" "index must be within bounds of the array" + + let valuesArray = Seq.toArray values + if valuesArray.Length = 0 then source + else + let length = source.Length + valuesArray.Length + let result = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked length + + if index > 0 then + Array.Copy(source, result, index) + + Array.Copy(valuesArray, 0, result, index, valuesArray.Length) + + if source.Length - index > 0 then + Array.Copy(source, index, result, index + valuesArray.Length, source.Length - index) + + result + module Parallel = open System.Threading.Tasks @@ -1376,4 +1460,4 @@ namespace Microsoft.FSharp.Collections res2.[iFalse] <- array.[i] iFalse <- iFalse + 1 - res1, res2 + res1, res2 \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/array.fsi b/src/fsharp/FSharp.Core/array.fsi index 5ede87a3c6d..0950c5e9a80 100644 --- a/src/fsharp/FSharp.Core/array.fsi +++ b/src/fsharp/FSharp.Core/array.fsi @@ -2,1216 +2,1957 @@ namespace Microsoft.FSharp.Collections - open System - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - open System.Collections.Generic - - /// Basic operations on arrays. - [] - [] - module Array = - - /// Returns a new array that contains all pairings of elements from the first and second arrays. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// The resulting array of pairs. - [] - val allPairs: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] - - /// Builds a new array that contains the elements of the first array followed by the elements of the second array. - /// The first input array. - /// The second input array. - /// The resulting array. - /// Thrown when either of the input arrays is null. - [] - val append: array1:'T[] -> array2:'T[] -> 'T[] - - /// Returns the average of the elements in the array. - /// The input array. - /// Thrown when array is empty. - /// The average of the elements in the array. - /// Thrown when the input array is null. - [] - val inline average : array:^T[] -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member DivideByInt : ^T*int -> ^T) - and ^T : (static member Zero : ^T) - - - /// Returns the average of the elements generated by applying the function to each element of the array. - /// The function to transform the array elements before averaging. - /// The input array. - /// Thrown when array is empty. - /// The computed average. - /// Thrown when the input array is null. - [] - val inline averageBy : projection:('T -> ^U) -> array:'T[] -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member DivideByInt : ^U*int -> ^U) - and ^U : (static member Zero : ^U) - - /// Reads a range of elements from the first array and write them into the second. - /// The source array. - /// The starting index of the source array. - /// The target array. - /// The starting index of the target array. - /// The number of elements to copy. - /// Thrown when either of the input arrays is null. - /// Thrown when any of sourceIndex, targetIndex or count are negative, - /// or when there aren't enough elements in source or target. - [] - val inline blit: source:'T[] -> sourceIndex:int -> target:'T[] -> targetIndex:int -> count:int -> unit - - /// For each element of the array, applies the given function. Concatenates all the results and return the combined array. - /// The function to create sub-arrays from the input array elements. - /// The input array. - /// The concatenation of the sub-arrays. - /// Thrown when the input array is null. - [] - val collect : mapping:('T -> 'U[]) -> array:'T[] -> 'U[] - - /// Compares two arrays using the given comparison function, element by element. +open System +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections +open System.Collections.Generic + +/// Contains operations for working with arrays. +/// +/// +/// See also F# Language Guide - Arrays. +/// +[] +[] +module Array = + + /// Returns a new array that contains all pairings of elements from the first and second arrays. + /// + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// + /// The resulting array of pairs. + /// + /// + /// + [] + val allPairs: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] + + /// Builds a new array that contains the elements of the first array followed by the elements of the second array. + /// + /// The first input array. + /// The second input array. + /// + /// The resulting array. + /// + /// Thrown when either of the input arrays is null. + /// + /// + /// + [] + val append: array1:'T[] -> array2:'T[] -> 'T[] + + /// Returns the average of the elements in the array. + /// + /// The input array. + /// + /// Thrown when array is empty. + /// Thrown when the input array is null. + /// + /// The average of the elements in the array. + /// + /// + /// + [] + val inline average : array:^T[] -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) + and ^T : (static member DivideByInt : ^T*int -> ^T) + and ^T : (static member Zero : ^T) + + + /// Returns the average of the elements generated by applying the function to each element of the array. + /// + /// The function to transform the array elements before averaging. + /// The input array. + /// + /// Thrown when array is empty. + /// + /// The computed average. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline averageBy : projection:('T -> ^U) -> array:'T[] -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) + and ^U : (static member DivideByInt : ^U*int -> ^U) + and ^U : (static member Zero : ^U) + + /// Reads a range of elements from the first array and write them into the second. + /// + /// The source array. + /// The starting index of the source array. + /// The target array. + /// The starting index of the target array. + /// The number of elements to copy. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when any of sourceIndex, targetIndex or count are negative, + /// or when there aren't enough elements in source or target. + /// + /// + /// + [] + val inline blit: source:'T[] -> sourceIndex:int -> target:'T[] -> targetIndex:int -> count:int -> unit + + /// For each element of the array, applies the given function. Concatenates all the results and return the combined array. + /// + /// The function to create sub-arrays from the input array elements. + /// The input array. + /// + /// The concatenation of the sub-arrays. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val collect : mapping:('T -> 'U[]) -> array:'T[] -> 'U[] + + /// Compares two arrays using the given comparison function, element by element. + /// + /// A function that takes an element from each array and returns an int. + /// If it evaluates to a non-zero value iteration is stopped and that value is returned. + /// The first input array. + /// The second input array. + /// + /// Returns the first non-zero result from the comparison function. If the first array has + /// a larger element, the return value is always positive. If the second array has a larger + /// element, the return value is always negative. When the elements are equal in the two + /// arrays, 1 is returned if the first array is longer, 0 is returned if they are equal in + /// length, and -1 is returned when the second array is longer. + /// + /// Thrown when either of the input arrays + /// is null. + /// + /// + /// + [] + val inline compareWith: comparer:('T -> 'T -> int) -> array1:'T[] -> array2:'T[] -> int + + /// Builds a new array that contains the elements of each of the given sequence of arrays. + /// + /// The input sequence of arrays. + /// + /// The concatenation of the sequence of input arrays. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + [] + val concat: arrays:seq<'T[]> -> 'T[] + + /// Tests if the array contains the specified element. + /// + /// The value to locate in the input array. + /// The input array. + /// + /// True if the input array contains the specified element; false otherwise. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline contains: value:'T -> array:'T[] -> bool when 'T : equality + + /// Builds a new array that contains the elements of the given array. + /// + /// The input array. + /// + /// A copy of the input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val copy: array:'T[] -> 'T[] + + /// Applies a key-generating function to each element of an array and returns an array yielding unique + /// keys and their number of occurrences in the original array. + /// + /// A function transforming each item of the input array into a key to be + /// compared against the others. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val countBy : projection:('T -> 'Key) -> array:'T[] -> ('Key * int)[] when 'Key : equality + + /// Creates an array whose elements are all initially the given value. + /// + /// The length of the array to create. + /// The value for the elements. + /// + /// The created array. + /// + /// Thrown when count is negative. + /// + /// + /// + [] + val create: count:int -> value:'T -> 'T[] + + /// Returns the first element of the array, or + /// None if the array is empty. + /// + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The first element of the array or None. + /// + /// + /// + [] + val tryHead: array:'T[] -> 'T option + + /// Applies the given function to successive elements, returning the first + /// result where the function returns Some(x) for some x. If the function + /// never returns Some(x) then None is returned. + /// + /// The function to transform the array elements into options. + /// The input array. + /// + /// The first transformed element that is Some(x). + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val tryPick: chooser:('T -> 'U option) -> array:'T[] -> 'U option + + /// Fills a range of elements of the array with the given value. + /// + /// The target array. + /// The index of the first element to set. + /// The number of elements to set. + /// The value to set. + /// + /// Thrown when the input array is null. + /// Thrown when either targetIndex or count is negative. + /// + /// + /// + [] + val fill: target:'T[] -> targetIndex:int -> count:int -> value:'T -> unit + + /// Applies the given function to successive elements, returning the first + /// result where the function returns Some(x) for some x. If the function + /// never returns Some(x) then is raised. + /// + /// The function to generate options from the elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown if every result from + /// chooser is None. + /// + /// The first result. + /// + /// + /// + [] + val pick: chooser:('T -> 'U option) -> array:'T[] -> 'U + + /// Applies the given function to each element of the array. Returns + /// the array comprised of the results x for each element where + /// the function returns Some(x) + /// + /// The function to generate options from the elements. + /// The input array. + /// + /// The array of results. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val choose: chooser:('T -> 'U option) -> array:'T[] -> 'U[] + + /// Divides the input array into chunks of size at most chunkSize. + /// + /// The maximum size of each chunk. + /// The input array. + /// + /// The array divided into chunks. + /// + /// Thrown when the input array is null. + /// Thrown when chunkSize is not positive. + /// + /// + /// + [] + val chunkBySize: chunkSize:int -> array:'T[] -> 'T[][] + + /// Returns an array that contains no duplicate entries according to generic hash and + /// equality comparisons on the entries. + /// If an element occurs multiple times in the array then the later occurrences are discarded. + /// + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val distinct: array:'T[] -> 'T[] when 'T : equality + + /// Returns an array that contains no duplicate entries according to the + /// generic hash and equality comparisons on the keys returned by the given key-generating function. + /// If an element occurs multiple times in the array then the later occurrences are discarded. + /// + /// A function transforming the array items into comparable keys. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val distinctBy: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : equality + + /// Splits the input array into at most count chunks. + /// + /// The maximum number of chunks. + /// The input array. + /// + /// The array split into chunks. + /// + /// Thrown when the input array is null. + /// Thrown when count is not positive. + /// + /// + /// + [] + val splitInto: count:int -> array:'T[] -> 'T[][] + + /// Returns an empty array of the given type. + /// The empty array. + [] + /// + /// + /// + [] + val empty<'T> : 'T[] + + /// Returns the only element of the array. + /// + /// The input array. + /// + /// The only element of the array. + /// + /// Thrown when the input array is null. + /// Thrown when the input does not have precisely one element. + /// + /// + /// + [] + val exactlyOne: array:'T[] -> 'T + + /// Returns the only element of the array or None if array is empty or contains more than one element. + /// + /// The input array. + /// + /// The only element of the array or None. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val tryExactlyOne: array:'T[] -> 'T option + + /// Returns a new list with the distinct elements of the input array which do not appear in the itemsToExclude sequence, + /// using generic hash and equality comparisons to compare values. + /// + /// A sequence whose elements that also occur in the input array will cause those elements to be + /// removed from the result. + /// An array whose elements that are not also in itemsToExclude will be returned. + /// + /// An array that contains the distinct elements of array that do not appear in itemsToExclude. + /// + /// Thrown when either itemsToExclude or array is null. + /// + /// + /// + [] + val except: itemsToExclude:seq<'T> -> array:'T[] -> 'T[] when 'T : equality + + /// Tests if any element of the array satisfies the given predicate. + /// + /// The predicate is applied to the elements of the input array. If any application + /// returns true then the overall result is true and no further elements are tested. + /// Otherwise, false is returned. + /// + /// The function to test the input elements. + /// The input array. + /// + /// True if any result from predicate is true. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val exists: predicate:('T -> bool) -> array:'T[] -> bool + + /// Tests if any pair of corresponding elements of the arrays satisfies the given predicate. + /// + /// The predicate is applied to matching elements in the two collections up to the lesser of the + /// two lengths of the collections. If any application returns true then the overall result is + /// true and no further elements are tested. Otherwise, if one collections is longer + /// than the other then the ArgumentException exception is raised. + /// Otherwise, false is returned. + /// + /// The function to test the input elements. + /// The first input array. + /// The second input array. + /// + /// True if any result from predicate is true. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// + /// + [] + val exists2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns "true". + /// + /// The function to test the input elements. + /// The input array. + /// + /// An array containing the elements for which the given predicate returns true. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val filter: predicate:('T -> bool) -> array:'T[] -> 'T[] + + /// Returns the first element for which the given function returns 'true'. + /// Raise if no such element exists. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown if predicate + /// never returns true. + /// + /// The first element for which predicate returns true. + /// + /// + /// + [] + val find: predicate:('T -> bool) -> array:'T[] -> 'T + + /// Returns the last element for which the given function returns 'true'. + /// Raise if no such element exists. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown if predicate + /// never returns true. + /// Thrown when the input array is null. + /// + /// The last element for which predicate returns true. + /// + /// + /// + [] + val findBack: predicate:('T -> bool) -> array:'T[] -> 'T + + /// Returns the index of the first element in the array + /// that satisfies the given predicate. Raise if + /// none of the elements satisfy the predicate. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown if predicate + /// never returns true. + /// Thrown when the input array is null. + /// + /// The index of the first element in the array that satisfies the given predicate. + /// + /// + /// + [] + val findIndex: predicate:('T -> bool) -> array:'T[] -> int + + /// Returns the index of the last element in the array + /// that satisfies the given predicate. Raise if + /// none of the elements satisfy the predicate. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown if predicate + /// never returns true. + /// Thrown when the input array is null. + /// + /// The index of the last element in the array that satisfies the given predicate. + /// + /// + /// + [] + val findIndexBack: predicate:('T -> bool) -> array:'T[] -> int + + /// Tests if all elements of the array satisfy the given predicate. + /// + /// The predicate is applied to the elements of the input collection. If any application + /// returns false then the overall result is false and no further elements are tested. + /// Otherwise, true is returned. + /// + /// The function to test the input elements. + /// The input array. + /// + /// True if all of the array elements satisfy the predicate. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val forall: predicate:('T -> bool) -> array:'T[] -> bool + + + /// Tests if all corresponding elements of the array satisfy the given predicate pairwise. + /// + /// The predicate is applied to matching elements in the two collections up to the lesser of the + /// two lengths of the collections. If any application returns false then the overall result is + /// false and no further elements are tested. Otherwise, if one collection is longer + /// than the other then the ArgumentException exception is raised. + /// Otherwise, true is returned. + /// + /// The function to test the input elements. + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// True if all of the array elements satisfy the predicate. + /// + /// + /// + [] + val forall2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool + + /// Applies a function to each element of the collection, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN then computes + /// f (... (f s i0)...) iN + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The input array. + /// + /// The final state. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> array: 'T[] -> 'State + + /// Applies a function to each element of the array, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN then computes + /// f i0 (...(f iN s)) + /// + /// The function to update the state given the input elements. + /// The input array. + /// The initial state. + /// + /// The state object after the folding function is applied to each element of the array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> array:'T[] -> state:'State -> 'State + + /// Applies a function to pairs of elements drawn from the two collections, + /// left-to-right, threading an accumulator argument + /// through the computation. The two input + /// arrays must have the same lengths, otherwise an ArgumentException is + /// raised. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// The final state. + /// + /// + /// + [] + val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> array1:'T1[] -> array2:'T2[] -> 'State + + /// Apply a function to pairs of elements drawn from the two collections, right-to-left, + /// threading an accumulator argument through the computation. The two input + /// arrays must have the same lengths, otherwise an ArgumentException is + /// raised. + /// + /// The function to update the state given the input elements. + /// The first input array. + /// The second input array. + /// The initial state. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// The final state. + /// + /// + /// + [] + val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> array1:'T1[] -> array2:'T2[] -> state:'State -> 'State + + /// Gets an element from an array. + /// + /// The input array. + /// The input index. + /// + /// The value of the array at the given index. + /// + /// Thrown when the input array is null. + /// Thrown when the index is negative or the input array does not contain enough elements. + /// + /// + /// + [] + val get: array:'T[] -> index:int -> 'T + + /// Returns the first element of the array. + /// + /// The input array. + /// + /// The first element of the array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// + /// + [] + val head: array:'T[] -> 'T + + /// Applies a key-generating function to each element of an array and yields an array of + /// unique keys. Each unique key contains an array of all elements that match + /// to this key. + /// + /// A function that transforms an element of the array into a comparable key. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val groupBy : projection:('T -> 'Key) -> array:'T[] -> ('Key * 'T[])[] when 'Key : equality + + /// Builds a new array whose elements are the corresponding elements of the input array + /// paired with the integer index (from 0) of each element. + /// + /// The input array. + /// + /// The array of indexed elements. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val indexed: array:'T[] -> (int * 'T)[] + + /// Creates an array given the dimension and a generator function to compute the elements. + /// + /// The number of elements to initialize. + /// The function to generate the initial values for each index. + /// + /// The created array. + /// + /// Thrown when count is negative. + /// + /// + /// + [] + val inline init: count:int -> initializer:(int -> 'T) -> 'T[] + + /// Creates an array where the entries are initially the default value Unchecked.defaultof<'T>. + /// + /// The length of the array to create. + /// + /// The created array. + /// + /// Thrown when count is negative. + /// + /// + /// + [] + val zeroCreate: count:int -> 'T[] + + /// Returns true if the given array is empty, otherwise false. + /// + /// The input array. + /// + /// True if the array is empty. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val isEmpty: array:'T[] -> bool + + /// Applies the given function to each element of the array. + /// + /// The function to apply. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline iter: action:('T -> unit) -> array:'T[] -> unit + + /// Applies the given function to pair of elements drawn from matching indices in two arrays. The + /// two arrays must have the same lengths, otherwise an ArgumentException is + /// raised. + /// + /// The function to apply. + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// + /// + [] + val iter2: action:('T1 -> 'T2 -> unit) -> array1:'T1[] -> array2:'T2[] -> unit + + /// Applies the given function to each element of the array. The integer passed to the + /// function indicates the index of element. + /// + /// The function to apply to each index and element. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val iteri: action:(int -> 'T -> unit) -> array:'T[] -> unit + + /// Applies the given function to pair of elements drawn from matching indices in two arrays, + /// also passing the index of the elements. The two arrays must have the same lengths, + /// otherwise an ArgumentException is raised. + /// + /// The function to apply to each index and pair of elements. + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// + /// + [] + val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> array1:'T1[] -> array2:'T2[] -> unit + + /// Returns the last element of the array. + /// + /// The input array. + /// + /// The last element of the array. + /// + /// Thrown when the input array is null. + /// Thrown when the input does not have any elements. + /// + /// + /// + [] + val inline last: array:'T[] -> 'T + + /// Gets an element from an array. + /// + /// The input index. + /// The input array. + /// + /// The value of the array at the given index. + /// + /// Thrown when the input array is null. + /// Thrown when the index is negative or the input array does not contain enough elements. + /// + /// + /// + [] + val item: index:int -> array:'T[] -> 'T + + /// Returns the length of an array. You can also use property arr.Length. + /// + /// The input array. + /// + /// The length of the array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val length: array:'T[] -> int + + /// Returns the last element of the array. + /// Return None if no such element exists. + /// + /// The input array. + /// + /// The last element of the array or None. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + [] + val tryLast: array:'T[] -> 'T option + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. + /// + /// The function to transform elements of the array. + /// The input array. + /// + /// The array of transformed elements. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline map: mapping:('T -> 'U) -> array:'T[] -> 'U[] + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding elements of the two collections pairwise. The two input + /// arrays must have the same lengths, otherwise an ArgumentException is + /// raised. + /// + /// The function to transform the pairs of the input elements. + /// The first input array. + /// The second input array. + /// + /// Thrown when the input arrays differ in length. + /// Thrown when either of the input arrays is null. + /// + /// The array of transformed elements. + /// + /// + /// + [] + val map2: mapping:('T1 -> 'T2 -> 'U) -> array1:'T1[] -> array2:'T2[] -> 'U[] + + /// Combines map and fold. Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the input array. The function is also used to accumulate a final value. + /// + /// The function to transform elements from the input array and accumulate the final value. + /// The initial state. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The array of transformed elements, and the final accumulated value. + /// + /// + /// + [] + val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> array:'T[] -> 'Result[] * 'State + + /// Combines map and foldBack. Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the input array. The function is also used to accumulate a final value. + /// + /// The function to transform elements from the input array and accumulate the final value. + /// The input array. + /// The initial state. + /// + /// Thrown when the input array is null. + /// + /// The array of transformed elements, and the final accumulated value. + /// + /// + /// + [] + val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> array:'T[] -> state:'State -> 'Result[] * 'State + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding triples from the three collections. The three input + /// arrays must have the same length, otherwise an ArgumentException is + /// raised. + /// + /// The function to transform the pairs of the input elements. + /// The first input array. + /// The second input array. + /// The third input array. + /// + /// Thrown when the input arrays differ in length. + /// Thrown when any of the input arrays is null. + /// + /// The array of transformed elements. + /// + /// + /// + [] + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> 'U[] + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding elements of the two collections pairwise, also passing the index of + /// the elements. The two input arrays must have the same lengths, otherwise an ArgumentException is + /// raised. + /// + /// The function to transform pairs of input elements and their indices. + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// The array of transformed elements. + /// + /// + /// + [] + val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> array1:'T1[] -> array2:'T2[] -> 'U[] + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. The integer index passed to the + /// function indicates the index of element being transformed. + /// + /// The function to transform elements and their indices. + /// The input array. + /// + /// The array of transformed elements. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val mapi: mapping:(int -> 'T -> 'U) -> array:'T[] -> 'U[] + + /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. + /// + /// Throws ArgumentException for empty arrays. + /// + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The maximum element. + /// + /// + /// + [] + val inline max : array:'T[] -> 'T when 'T : comparison + + /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. + /// + /// Throws ArgumentException for empty arrays. + /// + /// The function to transform the elements into a type supporting comparison. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The maximum element. + /// + /// + /// + [] + val inline maxBy : projection:('T -> 'U) -> array:'T[] -> 'T when 'U : comparison + + /// Returns the lowest of all elements of the array, compared via Operators.min. + /// + /// Throws ArgumentException for empty arrays + /// + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The minimum element. + /// + /// + /// + [] + val inline min : array:'T[] -> 'T when 'T : comparison + + /// Returns the lowest of all elements of the array, compared via Operators.min on the function result. + /// + /// Throws ArgumentException for empty arrays. + /// + /// The function to transform the elements into a type supporting comparison. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The minimum element. + /// + /// + /// + [] + val inline minBy : projection:('T -> 'U) -> array:'T[] -> 'T when 'U : comparison + + /// Builds an array from the given list. + /// + /// The input list. + /// + /// The array of elements from the list. + /// + /// + /// + [] + val ofList: list:'T list -> 'T[] + + /// Builds a new array from the given enumerable object. + /// + /// The input sequence. + /// + /// The array of elements from the sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + [] + val ofSeq: source:seq<'T> -> 'T[] + + /// Returns an array of each element in the input array and its predecessor, with the + /// exception of the first element which is only returned as the predecessor of the second element. + /// + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + [] + val pairwise: array:'T[] -> ('T * 'T)[] + + /// Splits the collection into two collections, containing the + /// elements for which the given predicate returns "true" and "false" + /// respectively. + /// + /// The function to test the input elements. + /// The input array. + /// + /// A pair of arrays. The first containing the elements the predicate evaluated to true, + /// and the second containing those evaluated to false. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val partition: predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[] + + /// Returns an array with all elements permuted according to the + /// specified permutation. + /// + /// The function that maps input indices to output indices. + /// The input array. + /// + /// The output array. + /// + /// Thrown when the input array is null. + /// Thrown when indexMap does not produce a valid permutation. + /// + /// + /// + [] + val permute : indexMap:(int -> int) -> array:'T[] -> 'T[] + + /// Applies a function to each element of the array, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN + /// then computes f (... (f i0 i1)...) iN. + /// Raises ArgumentException if the array has size zero. + /// + /// The function to reduce a pair of elements to a single element. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The final result of the reductions. + /// + /// + /// + [] + val reduce: reduction:('T -> 'T -> 'T) -> array:'T[] -> 'T + + /// Applies a function to each element of the array, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN + /// then computes f i0 (...(f iN-1 iN)). + /// + /// A function that takes in the next-to-last element of the list and the + /// current accumulated result to produce the next accumulated result. + /// The input array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// + /// The final result of the reductions. + /// + /// + /// + [] + val reduceBack: reduction:('T -> 'T -> 'T) -> array:'T[] -> 'T + + /// Creates an array by replicating the given initial value. + /// + /// The number of elements to replicate. + /// The value to replicate + /// + /// The generated array. + /// + /// Thrown when count is negative. + /// + /// + /// + [] + val replicate: count:int -> initial:'T -> 'T[] + + /// Returns a new array with the elements in reverse order. + /// + /// The input array. + /// + /// The reversed array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val rev: array:'T[] -> 'T[] + + /// Like fold, but return the intermediary and final results. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The input array. + /// + /// The array of state values. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> array:'T[] -> 'State[] + + /// Like foldBack, but return both the intermediary and final results. + /// + /// The function to update the state given the input elements. + /// The input array. + /// The initial state. + /// + /// The array of state values. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> array:'T[] -> state:'State -> 'State[] + + /// Returns an array that contains one item only. + /// + /// The input item. + /// + /// The result array of one item. + /// + /// + /// + [] + val inline singleton: value:'T -> 'T[] + + /// Sets an element of an array. + /// + /// The input array. + /// The input index. + /// The input value. + /// + /// Thrown when the input array is null. + /// Thrown when the index is negative or the input array does not contain enough elements. + /// + /// + /// + [] + val set: array:'T[] -> index:int -> value:'T -> unit + + /// Builds a new array that contains the elements of the given array, excluding the first N elements. + /// + /// The number of elements to skip. If negative the full array will be returned as a copy. + /// The input array. + /// + /// A copy of the input array, after removing the first N elements. + /// + /// Thrown when the input array is null. + /// Thrown when count exceeds the number of + /// elements in the array. + /// + /// + /// + [] + val skip: count:int -> array:'T[] -> 'T[] + + /// Bypasses elements in an array while the given predicate returns True, and then returns + /// the remaining elements in a new array. + /// + /// A function that evaluates an element of the array to a boolean value. + /// The input array. + /// + /// The created sub array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val skipWhile: predicate:('T -> bool) -> array:'T[] -> 'T[] + + /// Builds a new array that contains the given subrange specified by + /// starting index and length. + /// + /// The input array. + /// The index of the first element of the sub array. + /// The length of the sub array. + /// + /// The created sub array. + /// + /// Thrown when the input array is null. + /// Thrown when either startIndex or count is negative, + /// or when there aren't enough elements in the input array. + /// + /// + /// + [] + val sub: array:'T[] -> startIndex:int -> count:int -> 'T[] + + /// Sorts the elements of an array, returning a new array. Elements are compared using . + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The input array. + /// + /// The sorted array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sort: array:'T[] -> 'T[] when 'T : comparison + + /// Sorts the elements of an array, using the given projection for the keys and returning a new array. + /// Elements are compared using . + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The function to transform array elements into the type that is compared. + /// The input array. + /// + /// The sorted array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sortBy: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : comparison + + /// Sorts the elements of an array, using the given comparison function as the order, returning a new array. + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The function to compare pairs of array elements. + /// The input array. + /// + /// The sorted array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sortWith: comparer:('T -> 'T -> int) -> array:'T[] -> 'T[] + + /// Sorts the elements of an array by mutating the array in-place, using the given projection for the keys. + /// Elements are compared using . + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The function to transform array elements into the type that is compared. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sortInPlaceBy: projection:('T -> 'Key) -> array:'T[] -> unit when 'Key : comparison + + + + /// Sorts the elements of an array by mutating the array in-place, using the given comparison function as the order. + /// + /// The function to compare pairs of array elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sortInPlaceWith: comparer:('T -> 'T -> int) -> array:'T[] -> unit + + /// Sorts the elements of an array by mutating the array in-place, using the given comparison function. + /// Elements are compared using . + /// + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val sortInPlace: array:'T[] -> unit when 'T : comparison + + /// Splits an array into two arrays, at the given index. + /// + /// The index at which the array is split. + /// The input array. + /// + /// The two split arrays. + /// + /// Thrown when the input array is null. + /// Thrown when split index exceeds the number of elements + /// in the array. + /// + /// + /// + [] + val splitAt: index:int -> array:'T[] -> ('T[] * 'T[]) + + /// Sorts the elements of an array, in descending order, returning a new array. Elements are compared using . + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The input array. + /// + /// The sorted array. + /// + /// + /// + [] + val inline sortDescending: array:'T[] -> 'T[] when 'T : comparison + + /// Sorts the elements of an array, in descending order, using the given projection for the keys and returning a new array. + /// Elements are compared using . + /// + /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. + /// For a stable sort, consider using . + /// + /// The function to transform array elements into the type that is compared. + /// The input array. + /// + /// The sorted array. + /// + /// + /// + [] + val inline sortByDescending: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : comparison + + /// Returns the sum of the elements in the array. + /// + /// The input array. + /// + /// The resulting sum. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline sum : array: ^T[] -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) + and ^T : (static member Zero : ^T) + + + /// Returns the sum of the results generated by applying the function to each element of the array. + /// + /// The function to transform the array elements into the type to be summed. + /// The input array. + /// + /// The resulting sum. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val inline sumBy : projection:('T -> ^U) -> array:'T[] -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) + and ^U : (static member Zero : ^U) + + /// Returns the first N elements of the array. + /// Throws InvalidOperationException + /// if the count exceeds the number of elements in the array. Array.truncate + /// returns as many items as the array contains instead of throwing an exception. + /// + /// The number of items to take. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// Thrown when the input array is empty. + /// Thrown when count exceeds the number of elements + /// in the list. + /// + /// + /// + [] + val take: count:int -> array:'T[] -> 'T[] + + /// Returns an array that contains all elements of the original array while the + /// given predicate returns True, and then returns no further elements. + /// + /// A function that evaluates to false when no more items should be returned. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val takeWhile: predicate:('T -> bool) -> array:'T[] -> 'T[] + + /// Returns a new array containing the elements of the original except the first element. + /// + /// The input array. + /// + /// Thrown when the array is empty. + /// Thrown when the input array is null. + /// + /// A new array containing the elements of the original except the first element. + /// + /// + /// + [] + val tail: array:'T[] -> 'T[] + + /// Builds a list from the given array. + /// + /// The input array. + /// + /// The list of array elements. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val toList: array:'T[] -> 'T list + + /// Views the given array as a sequence. + /// + /// The input array. + /// + /// The sequence of array elements. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val toSeq: array:'T[] -> seq<'T> + + /// Returns the transpose of the given sequence of arrays. + /// + /// The input sequence of arrays. + /// + /// The transposed array. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input arrays differ in length. + /// + /// + /// + [] + val transpose: arrays:seq<'T[]> -> 'T[][] + + /// Returns at most N elements in a new array. + /// + /// The maximum number of items to return. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val truncate: count:int -> array:'T[] -> 'T[] + + /// Returns the first element for which the given function returns True. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input array. + /// + /// The first element that satisfies the predicate, or None. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val tryFind: predicate:('T -> bool) -> array:'T[] -> 'T option + + /// Returns the last element for which the given function returns True. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The last element that satisfies the predicate, or None. + /// + /// + /// + [] + val tryFindBack: predicate:('T -> bool) -> array:'T[] -> 'T option + + /// Returns the index of the first element in the array + /// that satisfies the given predicate. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The index of the first element that satisfies the predicate, or None. + /// + /// + /// + [] + val tryFindIndex : predicate:('T -> bool) -> array:'T[] -> int option + + /// Tries to find the nth element in the array. + /// Returns None if index is negative or the input array does not contain enough elements. + /// + /// The index of element to retrieve. + /// The input array. + /// + /// The nth element of the array or None. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val tryItem: index:int -> array:'T[] -> 'T option + + /// Returns the index of the last element in the array + /// that satisfies the given predicate. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The index of the last element that satisfies the predicate, or None. + /// + /// + /// + [] + val tryFindIndexBack : predicate:('T -> bool) -> array:'T[] -> int option + + /// Returns an array that contains the elements generated by the given computation. + /// The given initial state argument is passed to the element generator. + /// + /// A function that takes in the current state and returns an option tuple of the next + /// element of the array and the next state value. + /// The initial state value. + /// + /// The result array. + /// + /// + /// + [] + val unfold<'T,'State> : generator:('State -> ('T * 'State) option) -> state:'State -> 'T[] + + /// Splits an array of pairs into two arrays. + /// + /// The input array. + /// + /// The two arrays. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val unzip: array:('T1 * 'T2)[] -> ('T1[] * 'T2[]) + + /// Splits an array of triples into three arrays. + /// + /// The input array. + /// + /// The tuple of three arrays. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val unzip3: array:('T1 * 'T2 * 'T3)[] -> ('T1[] * 'T2[] * 'T3[]) + + /// Returns a new array containing only the elements of the array + /// for which the given predicate returns "true". + /// + /// The function to test the input elements. + /// The input array. + /// + /// An array containing the elements for which the given predicate returns true. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val where: predicate:('T -> bool) -> array:'T[] -> 'T[] + + /// Returns an array of sliding windows containing elements drawn from the input + /// array. Each window is returned as a fresh array. + /// + /// The number of elements in each window. + /// The input array. + /// + /// The result array. + /// + /// Thrown when the input array is null. + /// Thrown when windowSize is not positive. + /// + /// + /// + [] + val windowed : windowSize:int -> array:'T[] -> 'T[][] + + /// Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an ArgumentException is + /// raised. + /// + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// The array of tupled elements. + /// + /// + /// + [] + val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] + + /// Combines three arrays into an array of pairs. The three arrays must have equal lengths, otherwise an ArgumentException is + /// raised. + /// + /// The first input array. + /// The second input array. + /// The third input array. + /// + /// Thrown when any of the input arrays are null. + /// Thrown when the input arrays differ in length. + /// + /// The array of tupled elements. + /// + /// + /// + [] + val zip3: array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> ('T1 * 'T2 * 'T3)[] + + + /// Return a new array with the item at a given index removed. + /// + /// The index of the item to be removed. + /// The input array. + /// + /// The result array. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// [| 0; 1; 2 |] |> Array.removeAt 1 // evaluates to [| 0; 2 |] + /// + /// + [] + val removeAt : index: int -> source: 'T[] -> 'T[] + + /// Return a new array with the number of items starting at a given index removed. + /// + /// The index of the item to be removed. + /// The number of items to remove. + /// The input array. + /// + /// The result array. + /// + /// Thrown when index is outside 0..source.Length - count + /// + /// + /// + /// [| 0; 1; 2; 3 |] |> Array.removeManyAt 1 2 // evaluates to [| 0; 3 |] + /// + /// + [] + val removeManyAt : index: int -> count: int -> source: 'T[] -> 'T[] + + /// Return a new array with the item at a given index set to the new value. + /// + /// The index of the item to be replaced. + /// The new value. + /// The input array. + /// + /// The result array. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// [| 0; 1; 2 |] |> Array.updateAt 1 9 // evaluates to [| 0; 9; 2 |] + /// + /// + [] + val updateAt : index: int -> value: 'T -> source: 'T[] -> 'T[] + + /// Return a new array with a new item inserted before the given index. + /// + /// The index where the item should be inserted. + /// The value to insert. + /// The input array. + /// + /// The result array. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// [| 0; 1; 2 |] |> Array.insertAt 1 9 // evaluates to [| 0; 9; 1; 2 |] + /// + /// + [] + val insertAt : index: int -> value: 'T -> source: 'T[] -> 'T[] + + /// Return a new array with new items inserted before the given index. + /// + /// The index where the items should be inserted. + /// The values to insert. + /// The input array. + /// + /// The result array. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// [| 0; 1; 2 |] |> Array.insertManyAt 1 [8; 9] // evaluates to [| 0; 8; 9; 1; 2 |] + /// + /// + [] + val insertManyAt : index: int -> values: seq<'T> -> source: 'T[] -> 'T[] + + /// Provides parallel operations on arrays + module Parallel = + + /// Apply the given function to each element of the array. Return + /// the array comprised of the results x for each element where + /// the function returns Some(x). /// - /// A function that takes an element from each array and returns an int. - /// If it evaluates to a non-zero value iteration is stopped and that value is returned. - /// The first input array. - /// The second input array. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// Returns the first non-zero result from the comparison function. If the first array has - /// a larger element, the return value is always positive. If the second array has a larger - /// element, the return value is always negative. When the elements are equal in the two - /// arrays, 1 is returned if the first array is longer, 0 is returned if they are equal in - /// length, and -1 is returned when the second array is longer. - /// - /// Thrown when either of the input arrays - /// is null. - [] - val inline compareWith: comparer:('T -> 'T -> int) -> array1:'T[] -> array2:'T[] -> int - - /// Builds a new array that contains the elements of each of the given sequence of arrays. - /// The input sequence of arrays. - /// The concatenation of the sequence of input arrays. - /// Thrown when the input sequence is null. - [] - val concat: arrays:seq<'T[]> -> 'T[] - - /// Tests if the array contains the specified element. - /// The value to locate in the input array. - /// The input array. - /// True if the input array contains the specified element; false otherwise. - /// Thrown when the input array is null. - [] - val inline contains: value:'T -> array:'T[] -> bool when 'T : equality - - /// Builds a new array that contains the elements of the given array. - /// The input array. - /// A copy of the input array. - /// Thrown when the input array is null. - [] - val copy: array:'T[] -> 'T[] - - /// Applies a key-generating function to each element of an array and returns an array yielding unique - /// keys and their number of occurrences in the original array. - /// - /// A function transforming each item of the input array into a key to be - /// compared against the others. - /// The input array. - /// - /// The result array. - /// - /// Thrown when the input array is null. - [] - val countBy : projection:('T -> 'Key) -> array:'T[] -> ('Key * int)[] when 'Key : equality - - /// Creates an array whose elements are all initially the given value. - /// The length of the array to create. - /// The value for the elements. - /// The created array. - /// Thrown when count is negative. - [] - val create: count:int -> value:'T -> 'T[] - - /// Returns the first element of the array, or - /// None if the array is empty. - /// The input array. - /// Thrown when the input array is null. - /// The first element of the array or None. - [] - val tryHead: array:'T[] -> 'T option - - /// Applies the given function to successive elements, returning the first - /// result where function returns Some(x) for some x. If the function - /// never returns Some(x) then None is returned. - /// The function to transform the array elements into options. - /// The input array. - /// The first transformed element that is Some(x). - /// Thrown when the input array is null. - [] - val tryPick: chooser:('T -> 'U option) -> array:'T[] -> 'U option - - /// Fills a range of elements of the array with the given value. - /// The target array. - /// The index of the first element to set. - /// The number of elements to set. - /// The value to set. - /// Thrown when the input array is null. - /// Thrown when either targetIndex or count is negative. - [] - val fill: target:'T[] -> targetIndex:int -> count:int -> value:'T -> unit - - /// Applies the given function to successive elements, returning the first - /// result where function returns Some(x) for some x. If the function - /// never returns Some(x) then KeyNotFoundException is raised. - /// The function to generate options from the elements. - /// The input array. - /// Thrown when the input array is null. - /// Thrown if every result from - /// chooser is None. - /// The first result. - [] - val pick: chooser:('T -> 'U option) -> array:'T[] -> 'U - - /// Applies the given function to each element of the array. Returns - /// the array comprised of the results "x" for each element where - /// the function returns Some(x) /// The function to generate options from the elements. /// The input array. + /// /// The array of results. - /// Thrown when the input array is null. + /// + /// Thrown when the input array is null. + /// + /// + /// [] val choose: chooser:('T -> 'U option) -> array:'T[] -> 'U[] - /// Divides the input array into chunks of size at most chunkSize. - /// The maximum size of each chunk. - /// The input array. - /// The array divided into chunks. - /// Thrown when the input array is null. - /// Thrown when chunkSize is not positive. - [] - val chunkBySize: chunkSize:int -> array:'T[] -> 'T[][] - - /// Returns an array that contains no duplicate entries according to generic hash and - /// equality comparisons on the entries. - /// If an element occurs multiple times in the array then the later occurrences are discarded. - /// - /// The input array. - /// - /// The result array. - /// - /// Thrown when the input array is null. - [] - val distinct: array:'T[] -> 'T[] when 'T : equality - - /// Returns an array that contains no duplicate entries according to the - /// generic hash and equality comparisons on the keys returned by the given key-generating function. - /// If an element occurs multiple times in the array then the later occurrences are discarded. - /// - /// A function transforming the array items into comparable keys. - /// The input array. - /// - /// The result array. - /// - /// Thrown when the input array is null. - [] - val distinctBy: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : equality - - /// Splits the input array into at most count chunks. - /// The maximum number of chunks. - /// The input array. - /// The array split into chunks. - /// Thrown when the input array is null. - /// Thrown when count is not positive. - [] - val splitInto: count:int -> array:'T[] -> 'T[][] - - /// Returns an empty array of the given type. - /// The empty array. - [] - [] - val empty<'T> : 'T[] - - /// Returns the only element of the array. - /// - /// The input array. - /// - /// The only element of the array. - /// - /// Thrown when the input array is null. - /// Thrown when the input does not have precisely one element. - [] - val exactlyOne: array:'T[] -> 'T - - /// Returns the only element of the array or None if array is empty or contains more than one element. - /// - /// The input array. - /// - /// The only element of the array or None. - /// - /// Thrown when the input array is null. - [] - val tryExactlyOne: array:'T[] -> 'T option - - /// Returns a new list with the distinct elements of the input array which do not appear in the itemsToExclude sequence, - /// using generic hash and equality comparisons to compare values. - /// - /// A sequence whose elements that also occur in the input array will cause those elements to be - /// removed from the result. - /// An array whose elements that are not also in itemsToExclude will be returned. - /// - /// An array that contains the distinct elements of array that do not appear in itemsToExclude. - /// - /// Thrown when either itemsToExclude or array is null. - [] - val except: itemsToExclude:seq<'T> -> array:'T[] -> 'T[] when 'T : equality - - /// Tests if any element of the array satisfies the given predicate. - /// - /// The predicate is applied to the elements of the input array. If any application - /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. - /// The function to test the input elements. - /// The input array. - /// True if any result from predicate is true. - /// Thrown when the input array is null. - [] - val exists: predicate:('T -> bool) -> array:'T[] -> bool - - /// Tests if any pair of corresponding elements of the arrays satisfies the given predicate. + /// For each element of the array, apply the given function. Concatenate all the results and return the combined array. /// - /// The predicate is applied to matching elements in the two collections up to the lesser of the - /// two lengths of the collections. If any application returns true then the overall result is - /// true and no further elements are tested. Otherwise, if one collections is longer - /// than the other then the ArgumentException exception is raised. - /// Otherwise, false is returned. - /// The function to test the input elements. - /// The first input array. - /// The second input array. - /// True if any result from predicate is true. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - [] - val exists2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool - - /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns "true". - /// The function to test the input elements. - /// The input array. - /// An array containing the elements for which the given predicate returns true. - /// Thrown when the input array is null. - [] - val filter: predicate:('T -> bool) -> array:'T[] -> 'T[] - - /// Returns the first element for which the given function returns 'true'. - /// Raise KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input array. - /// Thrown when the input array is null. - /// Thrown if predicate - /// never returns true. - /// The first element for which predicate returns true. - [] - val find: predicate:('T -> bool) -> array:'T[] -> 'T - - /// Returns the last element for which the given function returns 'true'. - /// Raise KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input array. - /// Thrown if predicate - /// never returns true. - /// Thrown when the input array is null. - /// The last element for which predicate returns true. - [] - val findBack: predicate:('T -> bool) -> array:'T[] -> 'T - - /// Returns the index of the first element in the array - /// that satisfies the given predicate. Raise KeyNotFoundException if - /// none of the elements satisfy the predicate. - /// The function to test the input elements. - /// The input array. - /// Thrown if predicate - /// never returns true. - /// Thrown when the input array is null. - /// The index of the first element in the array that satisfies the given predicate. - [] - val findIndex: predicate:('T -> bool) -> array:'T[] -> int - - /// Returns the index of the last element in the array - /// that satisfies the given predicate. Raise KeyNotFoundException if - /// none of the elements satisfy the predicate. - /// The function to test the input elements. - /// The input array. - /// Thrown if predicate - /// never returns true. - /// Thrown when the input array is null. - /// The index of the last element in the array that satisfies the given predicate. - [] - val findIndexBack: predicate:('T -> bool) -> array:'T[] -> int - - /// Tests if all elements of the array satisfy the given predicate. - /// - /// The predicate is applied to the elements of the input collection. If any application - /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. - /// The function to test the input elements. - /// The input array. - /// True if all of the array elements satisfy the predicate. - /// Thrown when the input array is null. - [] - val forall: predicate:('T -> bool) -> array:'T[] -> bool - - - /// Tests if all corresponding elements of the array satisfy the given predicate pairwise. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// The predicate is applied to matching elements in the two collections up to the lesser of the - /// two lengths of the collections. If any application returns false then the overall result is - /// false and no further elements are tested. Otherwise, if one collection is longer - /// than the other then the ArgumentException exception is raised. - /// Otherwise, true is returned. - /// The function to test the input elements. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// True if all of the array elements satisfy the predicate. - [] - val forall2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool - - /// Applies a function to each element of the collection, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN then computes - /// f (... (f s i0)...) iN - /// The function to update the state given the input elements. - /// The initial state. - /// The input array. - /// The final state. - /// Thrown when the input array is null. - [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> array: 'T[] -> 'State - - /// Applies a function to each element of the array, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN then computes - /// f i0 (...(f iN s)) - /// The function to update the state given the input elements. + /// /// The input array. - /// The initial state. - /// The state object after the folding function is applied to each element of the array. - /// Thrown when the input array is null. - [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> array:'T[] -> state:'State -> 'State - - /// Applies a function to pairs of elements drawn from the two collections, - /// left-to-right, threading an accumulator argument - /// through the computation. The two input - /// arrays must have the same lengths, otherwise an ArgumentException is - /// raised. - /// The function to update the state given the input elements. - /// The initial state. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// The final state. - [] - val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> array1:'T1[] -> array2:'T2[] -> 'State - - /// Apply a function to pairs of elements drawn from the two collections, right-to-left, - /// threading an accumulator argument through the computation. The two input - /// arrays must have the same lengths, otherwise an ArgumentException is - /// raised. - /// The function to update the state given the input elements. - /// The first input array. - /// The second input array. - /// The initial state. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// The final state. - [] - val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> array1:'T1[] -> array2:'T2[] -> state:'State -> 'State - - /// Gets an element from an array. - /// The input array. - /// The input index. - /// The value of the array at the given index. - /// Thrown when the input array is null. - /// Thrown when the index is negative or the input array does not contain enough elements. - [] - val get: array:'T[] -> index:int -> 'T - - /// Returns the first element of the array. /// - /// The input array. + /// 'U[] /// - /// The first element of the array. + /// Thrown when the input array is null. + /// + /// + /// + [] + val collect : mapping:('T -> 'U[]) -> array:'T[] -> 'U[] + + /// Build a new array whose elements are the results of applying the given function + /// to each of the elements of the array. /// - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - [] - val head: array:'T[] -> 'T - - /// Applies a key-generating function to each element of an array and yields an array of - /// unique keys. Each unique key contains an array of all elements that match - /// to this key. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// A function that transforms an element of the array into a comparable key. + /// /// The input array. /// - /// The result array. + /// The array of results. /// - /// Thrown when the input array is null. - [] - val groupBy : projection:('T -> 'Key) -> array:'T[] -> ('Key * 'T[])[] when 'Key : equality - - /// Builds a new array whose elements are the corresponding elements of the input array - /// paired with the integer index (from 0) of each element. - /// The input array. - /// The array of indexed elements. - /// Thrown when the input array is null. - [] - val indexed: array:'T[] -> (int * 'T)[] - - /// Creates an array given the dimension and a generator function to compute the elements. - /// The number of elements to initialize. - /// The function to generate the initial values for each index. - /// The created array. - /// Thrown when count is negative. - [] - val inline init: count:int -> initializer:(int -> 'T) -> 'T[] - - /// Creates an array where the entries are initially the default value Unchecked.defaultof<'T>. - /// The length of the array to create. - /// The created array. - /// Thrown when count is negative. - [] - val zeroCreate: count:int -> 'T[] - - /// Returns true if the given array is empty, otherwise false. - /// The input array. - /// True if the array is empty. - /// Thrown when the input array is null. - [] - val isEmpty: array:'T[] -> bool - - /// Applies the given function to each element of the array. - /// The function to apply. - /// The input array. - /// Thrown when the input array is null. - [] - val inline iter: action:('T -> unit) -> array:'T[] -> unit - - /// Applies the given function to pair of elements drawn from matching indices in two arrays. The - /// two arrays must have the same lengths, otherwise an ArgumentException is - /// raised. - /// The function to apply. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - [] - val iter2: action:('T1 -> 'T2 -> unit) -> array1:'T1[] -> array2:'T2[] -> unit - - /// Applies the given function to each element of the array. The integer passed to the - /// function indicates the index of element. - /// The function to apply to each index and element. - /// The input array. - /// Thrown when the input array is null. - [] - val iteri: action:(int -> 'T -> unit) -> array:'T[] -> unit - - /// Applies the given function to pair of elements drawn from matching indices in two arrays, - /// also passing the index of the elements. The two arrays must have the same lengths, - /// otherwise an ArgumentException is raised. - /// The function to apply to each index and pair of elements. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - [] - val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> array1:'T1[] -> array2:'T2[] -> unit - - /// Returns the last element of the array. - /// The input array. - /// The last element of the array. - /// Thrown when the input array is null. - /// Thrown when the input does not have any elements. - [] - val inline last: array:'T[] -> 'T - - /// Gets an element from an array. - /// The input index. - /// The input array. - /// The value of the array at the given index. - /// Thrown when the input array is null. - /// Thrown when the index is negative or the input array does not contain enough elements. - [] - val item: index:int -> array:'T[] -> 'T - - /// Returns the length of an array. You can also use property arr.Length. - /// The input array. - /// The length of the array. - /// Thrown when the input array is null. - [] - val length: array:'T[] -> int - - /// Returns the last element of the array. - /// Return None if no such element exists. - /// The input array. - /// The last element of the array or None. - /// Thrown when the input sequence is null. - [] - val tryLast: array:'T[] -> 'T option - - /// Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the array. - /// The function to transform elements of the array. - /// The input array. - /// The array of transformed elements. - /// Thrown when the input array is null. + /// Thrown when the input array is null. + /// + /// + /// [] - val inline map: mapping:('T -> 'U) -> array:'T[] -> 'U[] - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding elements of the two collections pairwise. The two input - /// arrays must have the same lengths, otherwise an ArgumentException is - /// raised. - /// The function to transform the pairs of the input elements. - /// The first input array. - /// The second input array. - /// Thrown when the input arrays differ in length. - /// Thrown when either of the input arrays is null. - /// The array of transformed elements. - [] - val map2: mapping:('T1 -> 'T2 -> 'U) -> array1:'T1[] -> array2:'T2[] -> 'U[] - - /// Combines map and fold. Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the input array. The function is also used to accumulate a final value. - /// The function to transform elements from the input array and accumulate the final value. - /// The initial state. - /// The input array. - /// Thrown when the input array is null. - /// The array of transformed elements, and the final accumulated value. - [] - val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> array:'T[] -> 'Result[] * 'State - - /// Combines map and foldBack. Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the input array. The function is also used to accumulate a final value. - /// The function to transform elements from the input array and accumulate the final value. - /// The input array. - /// The initial state. - /// Thrown when the input array is null. - /// The array of transformed elements, and the final accumulated value. - [] - val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> array:'T[] -> state:'State -> 'Result[] * 'State - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding triples from the three collections. The three input - /// arrays must have the same length, otherwise an ArgumentException is - /// raised. - /// The function to transform the pairs of the input elements. - /// The first input array. - /// The second input array. - /// The third input array. - /// Thrown when the input arrays differ in length. - /// Thrown when any of the input arrays is null. - /// The array of transformed elements. - [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> 'U[] - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding elements of the two collections pairwise, also passing the index of - /// the elements. The two input arrays must have the same lengths, otherwise an ArgumentException is - /// raised. - /// The function to transform pairs of input elements and their indices. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// The array of transformed elements. - [] - val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> array1:'T1[] -> array2:'T2[] -> 'U[] - - /// Builds a new array whose elements are the results of applying the given function + val map : mapping:('T -> 'U) -> array:'T[] -> 'U[] + + /// Build a new array whose elements are the results of applying the given function /// to each of the elements of the array. The integer index passed to the /// function indicates the index of element being transformed. - /// The function to transform elements and their indices. - /// The input array. - /// The array of transformed elements. - /// Thrown when the input array is null. - [] - val mapi: mapping:(int -> 'T -> 'U) -> array:'T[] -> 'U[] - - /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. - /// - /// Throws ArgumentException for empty arrays. - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The maximum element. - [] - val inline max : array:'T[] -> 'T when 'T : comparison - - /// Returns the greatest of all elements of the array, compared via Operators.max on the function result. - /// - /// Throws ArgumentException for empty arrays. - /// The function to transform the elements into a type supporting comparison. - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The maximum element. - [] - val inline maxBy : projection:('T -> 'U) -> array:'T[] -> 'T when 'U : comparison - - /// Returns the lowest of all elements of the array, compared via Operators.min. - /// - /// Throws ArgumentException for empty arrays - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The minimum element. - [] - val inline min : array:'T[] -> 'T when 'T : comparison - - /// Returns the lowest of all elements of the array, compared via Operators.min on the function result. - /// - /// Throws ArgumentException for empty arrays. - /// The function to transform the elements into a type supporting comparison. - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The minimum element. - [] - val inline minBy : projection:('T -> 'U) -> array:'T[] -> 'T when 'U : comparison - - /// Builds an array from the given list. - /// The input list. - /// The array of elements from the list. - [] - val ofList: list:'T list -> 'T[] - - /// Builds a new array from the given enumerable object. - /// The input sequence. - /// The array of elements from the sequence. - /// Thrown when the input sequence is null. - [] - val ofSeq: source:seq<'T> -> 'T[] - - /// Returns an array of each element in the input array and its predecessor, with the - /// exception of the first element which is only returned as the predecessor of the second element. - /// - /// The input array. - /// - /// The result array. - /// - /// Thrown when the input sequence is null. - [] - val pairwise: array:'T[] -> ('T * 'T)[] - - /// Splits the collection into two collections, containing the - /// elements for which the given predicate returns "true" and "false" - /// respectively. - /// The function to test the input elements. - /// The input array. - /// A pair of arrays. The first containing the elements the predicate evaluated to true, - /// and the second containing those evaluated to false. - /// Thrown when the input array is null. - [] - val partition: predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[] - - /// Returns an array with all elements permuted according to the - /// specified permutation. - /// The function that maps input indices to output indices. - /// The input array. - /// The output array. - /// Thrown when the input array is null. - /// Thrown when indexMap does not produce a valid permutation. - [] - val permute : indexMap:(int -> int) -> array:'T[] -> 'T[] - - /// Applies a function to each element of the array, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN - /// then computes f (... (f i0 i1)...) iN. - /// Raises ArgumentException if the array has size zero. - /// The function to reduce a pair of elements to a single element. - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The final result of the reductions. - [] - val reduce: reduction:('T -> 'T -> 'T) -> array:'T[] -> 'T - - /// Applies a function to each element of the array, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN - /// then computes f i0 (...(f iN-1 iN)). - /// A function that takes in the next-to-last element of the list and the - /// current accumulated result to produce the next accumulated result. - /// The input array. - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// The final result of the reductions. - [] - val reduceBack: reduction:('T -> 'T -> 'T) -> array:'T[] -> 'T - - /// Creates an array by replicating the given initial value. - /// The number of elements to replicate. - /// The value to replicate - /// The generated array. - /// Thrown when count is negative. - [] - val replicate: count:int -> initial:'T -> 'T[] - - /// Returns a new array with the elements in reverse order. - /// The input array. - /// The reversed array. - /// Thrown when the input array is null. - [] - val rev: array:'T[] -> 'T[] - - /// Like fold, but return the intermediary and final results. - /// The function to update the state given the input elements. - /// The initial state. - /// The input array. - /// The array of state values. - /// Thrown when the input array is null. - [] - val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> array:'T[] -> 'State[] - - /// Like foldBack, but return both the intermediary and final results. - /// The function to update the state given the input elements. - /// The input array. - /// The initial state. - /// The array of state values. - /// Thrown when the input array is null. - [] - val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> array:'T[] -> state:'State -> 'State[] - - /// Returns an array that contains one item only. /// - /// The input item. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// The result array of one item. - [] - val inline singleton: value:'T -> 'T[] - - /// Sets an element of an array. - /// The input array. - /// The input index. - /// The input value. - /// Thrown when the input array is null. - /// Thrown when the index is negative or the input array does not contain enough elements. - [] - val set: array:'T[] -> index:int -> value:'T -> unit - - /// Builds a new array that contains the elements of the given array, excluding the first N elements. - /// The number of elements to skip. + /// /// The input array. - /// A copy of the input array, after removing the first N elements. - /// Thrown when the input array is null. - /// Thrown when count is negative or exceeds the number of - /// elements in the array. - [] - val skip: count:int -> array:'T[] -> 'T[] - - /// Bypasses elements in an array while the given predicate returns True, and then returns - /// the remaining elements in a new array. - /// A function that evaluates an element of the array to a boolean value. - /// The input array. - /// The created sub array. - /// Thrown when the input array is null. - [] - val skipWhile: predicate:('T -> bool) -> array:'T[] -> 'T[] - - /// Builds a new array that contains the given subrange specified by - /// starting index and length. - /// The input array. - /// The index of the first element of the sub array. - /// The length of the sub array. - /// The created sub array. - /// Thrown when the input array is null. - /// Thrown when either startIndex or count is negative, - /// or when there aren't enough elements in the input array. - [] - val sub: array:'T[] -> startIndex:int -> count:int -> 'T[] - - /// Sorts the elements of an array, returning a new array. Elements are compared using Operators.compare. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The input array. - /// The sorted array. - /// Thrown when the input array is null. - [] - val sort: array:'T[] -> 'T[] when 'T : comparison - - /// Sorts the elements of an array, using the given projection for the keys and returning a new array. - /// Elements are compared using Operators.compare. + /// The array of results. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The function to transform array elements into the type that is compared. - /// The input array. - /// The sorted array. - /// Thrown when the input array is null. - [] - val sortBy: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : comparison + /// Thrown when the input array is null. + /// + /// + /// + [] + val mapi: mapping:(int -> 'T -> 'U) -> array:'T[] -> 'U[] - /// Sorts the elements of an array, using the given comparison function as the order, returning a new array. + /// Apply the given function to each element of the array. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The function to compare pairs of array elements. - /// The input array. - /// The sorted array. - /// Thrown when the input array is null. - [] - val sortWith: comparer:('T -> 'T -> int) -> array:'T[] -> 'T[] - - /// Sorts the elements of an array by mutating the array in-place, using the given projection for the keys. - /// Elements are compared using Operators.compare. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The function to transform array elements into the type that is compared. - /// The input array. - /// Thrown when the input array is null. - [] - val sortInPlaceBy: projection:('T -> 'Key) -> array:'T[] -> unit when 'Key : comparison - - - - /// Sorts the elements of an array by mutating the array in-place, using the given comparison function as the order. - /// The function to compare pairs of array elements. - /// The input array. - /// Thrown when the input array is null. - [] - val sortInPlaceWith: comparer:('T -> 'T -> int) -> array:'T[] -> unit - - /// Sorts the elements of an array by mutating the array in-place, using the given comparison function. - /// Elements are compared using Operators.compare. + /// /// The input array. - /// Thrown when the input array is null. - [] - val sortInPlace: array:'T[] -> unit when 'T : comparison - - /// Splits an array into two arrays, at the given index. - /// The index at which the array is split. - /// The input array. - /// The two split arrays. /// - /// Thrown when the input array is null. - /// Thrown when split index exceeds the number of elements - /// in the array. - [] - val splitAt: index:int -> array:'T[] -> ('T[] * 'T[]) + /// Thrown when the input array is null. + /// + /// + /// + [] + val iter : action:('T -> unit) -> array:'T[] -> unit - /// Sorts the elements of an array, in descending order, returning a new array. Elements are compared using Operators.compare. + /// Apply the given function to each element of the array. The integer passed to the + /// function indicates the index of element. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The input array. - /// The sorted array. - [] - val inline sortDescending: array:'T[] -> 'T[] when 'T : comparison - - /// Sorts the elements of an array, in descending order, using the given projection for the keys and returning a new array. - /// Elements are compared using Operators.compare. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to elements of the input array is not specified. /// - /// This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved. - /// For a stable sort, consider using Seq.sort. - /// The function to transform array elements into the type that is compared. - /// The input array. - /// The sorted array. - [] - val inline sortByDescending: projection:('T -> 'Key) -> array:'T[] -> 'T[] when 'Key : comparison - - /// Returns the sum of the elements in the array. - /// The input array. - /// The resulting sum. - /// Thrown when the input array is null. - [] - val inline sum : array: ^T[] -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member Zero : ^T) - - - /// Returns the sum of the results generated by applying the function to each element of the array. - /// The function to transform the array elements into the type to be summed. - /// The input array. - /// The resulting sum. - /// Thrown when the input array is null. - [] - val inline sumBy : projection:('T -> ^U) -> array:'T[] -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member Zero : ^U) - - /// Returns the first N elements of the array. - /// Throws InvalidOperationException - /// if the count exceeds the number of elements in the array. Array.truncate - /// returns as many items as the array contains instead of throwing an exception. - /// - /// The number of items to take. + /// /// The input array. /// - /// The result array. + /// Thrown when the input array is null. + /// + /// + /// + [] + val iteri: action:(int -> 'T -> unit) -> array:'T[] -> unit + + /// Create an array given the dimension and a generator function to compute the elements. /// - /// Thrown when the input array is null. - /// Thrown when the input array is empty. - /// Thrown when count exceeds the number of elements - /// in the list. - [] - val take: count:int -> array:'T[] -> 'T[] - - /// Returns an array that contains all elements of the original array while the - /// given predicate returns True, and then returns no further elements. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to indices is not specified. /// - /// A function that evaluates to false when no more items should be returned. - /// The input array. + /// + /// /// - /// The result array. + /// The array of results. + /// + /// + /// + [] + val init : count:int -> initializer:(int -> 'T) -> 'T[] + + /// Split the collection into two collections, containing the + /// elements for which the given predicate returns "true" and "false" + /// respectively /// - /// Thrown when the input array is null. - [] - val takeWhile: predicate:('T -> bool) -> array:'T[] -> 'T[] - - /// Returns a new array containing the elements of the original except the first element. + /// Performs the operation in parallel using . + /// The order in which the given function is applied to indices is not specified. /// - /// The input array. - /// Thrown when the array is empty. - /// Thrown when the input array is null. - /// A new array containing the elements of the original except the first element. - [] - val tail: array:'T[] -> 'T[] - - /// Builds a list from the given array. - /// The input array. - /// The list of array elements. - /// Thrown when the input array is null. - [] - val toList: array:'T[] -> 'T list - - /// Views the given array as a sequence. - /// The input array. - /// The sequence of array elements. - /// Thrown when the input array is null. - [] - val toSeq: array:'T[] -> seq<'T> - - /// Returns the transpose of the given sequence of arrays. - /// The input sequence of arrays. - /// The transposed array. - /// Thrown when the input sequence is null. - /// Thrown when the input arrays differ in length. - [] - val transpose: arrays:seq<'T[]> -> 'T[][] - - /// Returns at most N elements in a new array. - /// The maximum number of items to return. - /// The input array. - /// The result array. - /// Thrown when the input array is null. - [] - val truncate: count:int -> array:'T[] -> 'T[] - - /// Returns the first element for which the given function returns True. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input array. - /// The first element that satisfies the predicate, or None. - /// Thrown when the input array is null. - [] - val tryFind: predicate:('T -> bool) -> array:'T[] -> 'T option - - /// Returns the last element for which the given function returns True. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input array. - /// Thrown when the input array is null. - /// The last element that satisfies the predicate, or None. - [] - val tryFindBack: predicate:('T -> bool) -> array:'T[] -> 'T option - - /// Returns the index of the first element in the array - /// that satisfies the given predicate. /// The function to test the input elements. /// The input array. - /// Thrown when the input array is null. - /// The index of the first element that satisfies the predicate, or None. - [] - val tryFindIndex : predicate:('T -> bool) -> array:'T[] -> int option - - /// Tries to find the nth element in the array. - /// Returns None if index is negative or the input array does not contain enough elements. - /// The index of element to retrieve. - /// The input array. - /// The nth element of the array or None. - /// Thrown when the input array is null. - [] - val tryItem: index:int -> array:'T[] -> 'T option - - /// Returns the index of the last element in the array - /// that satisfies the given predicate. - /// The function to test the input elements. - /// The input array. - /// Thrown when the input array is null. - /// The index of the last element that satisfies the predicate, or None. - [] - val tryFindIndexBack : predicate:('T -> bool) -> array:'T[] -> int option - - /// Returns an array that contains the elements generated by the given computation. - /// The given initial state argument is passed to the element generator. - /// A function that takes in the current state and returns an option tuple of the next - /// element of the array and the next state value. - /// The initial state value. - /// The result array. - [] - val unfold<'T,'State> : generator:('State -> ('T * 'State) option) -> state:'State -> 'T[] - - /// Splits an array of pairs into two arrays. - /// The input array. - /// The two arrays. - /// Thrown when the input array is null. - [] - val unzip: array:('T1 * 'T2)[] -> ('T1[] * 'T2[]) - - /// Splits an array of triples into three arrays. - /// The input array. - /// The tuple of three arrays. - /// Thrown when the input array is null. - [] - val unzip3: array:('T1 * 'T2 * 'T3)[] -> ('T1[] * 'T2[] * 'T3[]) - - /// Returns a new array containing only the elements of the array - /// for which the given predicate returns "true". - /// The function to test the input elements. - /// The input array. - /// An array containing the elements for which the given predicate returns true. /// - /// Thrown when the input array is null. - [] - val where: predicate:('T -> bool) -> array:'T[] -> 'T[] - - /// Returns an array of sliding windows containing elements drawn from the input - /// array. Each window is returned as a fresh array. - /// The number of elements in each window. - /// The input array. - /// The result array. - /// Thrown when the input array is null. - /// Thrown when windowSize is not positive. - [] - val windowed : windowSize:int -> array:'T[] -> 'T[][] - - /// Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an ArgumentException is - /// raised. - /// The first input array. - /// The second input array. - /// Thrown when either of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// The array of tupled elements. - [] - val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] - - /// Combines three arrays into an array of pairs. The three arrays must have equal lengths, otherwise an ArgumentException is - /// raised. - /// The first input array. - /// The second input array. - /// The third input array. - /// Thrown when any of the input arrays are null. - /// Thrown when the input arrays differ in length. - /// The array of tupled elements. - [] - val zip3: array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> ('T1 * 'T2 * 'T3)[] - - /// Provides parallel operations on arrays - module Parallel = - - /// Apply the given function to each element of the array. Return - /// the array comprised of the results "x" for each element where - /// the function returns Some(x). - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// The function to generate options from the elements. - /// The input array. - /// 'U[] - /// Thrown when the input array is null. - [] - val choose: chooser:('T -> 'U option) -> array:'T[] -> 'U[] - - /// For each element of the array, apply the given function. Concatenate all the results and return the combined array. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// - /// The input array. - /// 'U[] - /// Thrown when the input array is null. - [] - val collect : mapping:('T -> 'U[]) -> array:'T[] -> 'U[] - - /// Build a new array whose elements are the results of applying the given function - /// to each of the elements of the array. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// - /// The input array. - /// 'U[] - /// Thrown when the input array is null. - [] - val map : mapping:('T -> 'U) -> array:'T[] -> 'U[] - - /// Build a new array whose elements are the results of applying the given function - /// to each of the elements of the array. The integer index passed to the - /// function indicates the index of element being transformed. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// - /// The input array. - /// 'U[] - /// Thrown when the input array is null. - [] - val mapi: mapping:(int -> 'T -> 'U) -> array:'T[] -> 'U[] - - /// Apply the given function to each element of the array. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// - /// The input array. - /// Thrown when the input array is null. - [] - val iter : action:('T -> unit) -> array:'T[] -> unit - - /// Apply the given function to each element of the array. The integer passed to the - /// function indicates the index of element. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to elements of the input array is not specified. - /// - /// The input array. - /// Thrown when the input array is null. - [] - val iteri: action:(int -> 'T -> unit) -> array:'T[] -> unit - - /// Create an array given the dimension and a generator function to compute the elements. - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to indices is not specified. - /// - /// - /// 'T[] - [] - val init : count:int -> initializer:(int -> 'T) -> 'T[] - - /// Split the collection into two collections, containing the - /// elements for which the given predicate returns "true" and "false" - /// respectively - /// - /// Performs the operation in parallel using System.Threading.Parallel.For. - /// The order in which the given function is applied to indices is not specified. - /// The function to test the input elements. - /// The input array. - /// 'T[] * 'T[] - /// Thrown when the input array is null. - [] - val partition : predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[] + /// The two arrays of results. + /// + /// Thrown when the input array is null. + /// + /// + /// + [] + val partition : predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[] diff --git a/src/fsharp/FSharp.Core/array2.fsi b/src/fsharp/FSharp.Core/array2.fsi index 86a3d5be5c4..ec60c34a095 100644 --- a/src/fsharp/FSharp.Core/array2.fsi +++ b/src/fsharp/FSharp.Core/array2.fsi @@ -2,226 +2,268 @@ namespace Microsoft.FSharp.Collections - open System - open Microsoft.FSharp.Collections - open Microsoft.FSharp.Core - - [] - [] - /// Basic operations on 2-dimensional arrays. - /// - /// F# and CLI multi-dimensional arrays are typically zero-based. - /// However, CLI multi-dimensional arrays used in conjunction with external - /// libraries (e.g. libraries associated with Visual Basic) be - /// non-zero based, using a potentially different base for each dimension. - /// The operations in this module will accept such arrays, and - /// the basing on an input array will be propagated to a matching output - /// array on the Array2D.map and Array2D.mapi operations. - /// Non-zero-based arrays can also be created using Array2D.zeroCreateBased, - /// Array2D.createBased and Array2D.initBased. - module Array2D = - - /// Fetches the base-index for the first dimension of the array. - /// - /// The input array. - /// - /// The base-index of the first dimension of the array. - [] - val base1: array:'T[,] -> int - - /// Fetches the base-index for the second dimension of the array. - /// - /// The input array. - /// - /// The base-index of the second dimension of the array. - [] - val base2: array:'T[,] -> int - - /// Builds a new array whose elements are the same as the input array. - /// - /// For non-zero-based arrays the basing on an input array will be propagated to the output - /// array. - /// - /// The input array. - /// - /// A copy of the input array. - [] - val copy: array:'T[,] -> 'T[,] - - /// Reads a range of elements from the first array and write them into the second. - /// - /// The source array. - /// The first-dimension index to begin copying from in the source array. - /// The second-dimension index to begin copying from in the source array. - /// The target array. - /// The first-dimension index to begin copying into in the target array. - /// The second-dimension index to begin copying into in the target array. - /// The number of elements to copy across the first dimension of the arrays. - /// The number of elements to copy across the second dimension of the arrays. - /// Thrown when any of the indices are negative or if either of - /// the counts are larger than the dimensions of the array allow. - [] - val blit: source:'T[,] -> sourceIndex1:int -> sourceIndex2:int -> target:'T[,] -> targetIndex1:int -> targetIndex2:int -> length1:int -> length2:int -> unit - - /// Creates an array given the dimensions and a generator function to compute the elements. - /// - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// A function to produce elements of the array given the two indices. - /// - /// The generated array. - /// Thrown when either of the lengths is negative. - [] - val init: length1:int -> length2:int -> initializer:(int -> int -> 'T) -> 'T[,] - - /// Creates an array whose elements are all initially the given value. - /// - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// The value to populate the new array. - /// - /// The created array. - /// Thrown when length1 or length2 is negative. - [] - val create: length1:int -> length2:int -> value:'T -> 'T[,] - - /// Creates an array where the entries are initially Unchecked.defaultof<'T>. - /// - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// - /// The created array. - /// Thrown when length1 or length2 is negative. - [] - val zeroCreate : length1:int -> length2:int -> 'T[,] - - /// Creates a based array given the dimensions and a generator function to compute the elements. - /// - /// The base for the first dimension of the array. - /// The base for the second dimension of the array. - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// A function to produce elements of the array given the two indices. - /// - /// The created array. - /// Thrown when base1, base2, length1, or length2 is negative. - [] - val initBased: base1:int -> base2:int -> length1:int -> length2:int -> initializer:(int -> int -> 'T) -> 'T[,] - - /// Creates a based array whose elements are all initially the given value. - /// - /// The base for the first dimension of the array. - /// The base for the second dimension of the array. - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// The value to populate the new array. - /// - /// The created array. - /// Thrown when base1, base2, length1, or length2 is negative. - [] - val createBased: base1:int -> base2:int -> length1:int -> length2:int -> initial: 'T -> 'T[,] - - /// Creates a based array where the entries are initially Unchecked.defaultof<'T>. - /// - /// The base for the first dimension of the array. - /// The base for the second dimension of the array. - /// The length of the first dimension of the array. - /// The length of the second dimension of the array. - /// - /// The created array. - /// Thrown when base1, base2, length1, or length2 is negative. - [] - val zeroCreateBased : base1:int -> base2:int -> length1:int -> length2:int -> 'T[,] - - /// Applies the given function to each element of the array. - /// - /// A function to apply to each element of the array. - /// The input array. - [] - val iter: action:('T -> unit) -> array:'T[,] -> unit - - /// Applies the given function to each element of the array. The integer indices passed to the - /// function indicates the index of element. - /// - /// A function to apply to each element of the array with the indices available as an argument. - /// The input array. - [] - val iteri: action:(int -> int -> 'T -> unit) -> array:'T[,] -> unit - - /// Returns the length of an array in the first dimension. - /// - /// The input array. - /// - /// The length of the array in the first dimension. - [] - val length1: array:'T[,] -> int - - /// Returns the length of an array in the second dimension. - /// - /// The input array. - /// - /// The length of the array in the second dimension. - [] - val length2: array:'T[,] -> int - - /// Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the array. - /// - /// For non-zero-based arrays the basing on an input array will be propagated to the output - /// array. - /// - /// A function that is applied to transform each item of the input array. - /// The input array. - /// - /// An array whose elements have been transformed by the given mapping. - [] - val map: mapping:('T -> 'U) -> array:'T[,] -> 'U[,] - - /// Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the array. The integer indices passed to the - /// function indicates the element being transformed. - /// - /// For non-zero-based arrays the basing on an input array will be propagated to the output - /// array. - /// - /// A function that is applied to transform each element of the array. The two integers - /// provide the index of the element. - /// The input array. - /// - /// An array whose elements have been transformed by the given mapping. - [] - val mapi: mapping:(int -> int -> 'T -> 'U) -> array:'T[,] -> 'U[,] - - - /// Builds a new array whose elements are the same as the input array but - /// where a non-zero-based input array generates a corresponding zero-based - /// output array. - /// - /// The input array. - /// - /// The zero-based output array. - [] - val rebase: array:'T[,] -> 'T[,] - - /// Sets the value of an element in an array. You can also use the syntax array.[index1,index2] <- value. - /// - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// The value to set in the array. - /// Thrown when the indices are negative or exceed the bounds of the array. - [] - val set: array:'T[,] -> index1:int -> index2:int -> value:'T -> unit - - /// Fetches an element from a 2D array. You can also use the syntax array.[index1,index2]. - /// - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// - /// The value of the array at the given index. - /// Thrown when the indices are negative or exceed the bounds of the array. - [] - val get: array:'T[,] -> index1:int -> index2:int -> 'T +open System +open Microsoft.FSharp.Collections +open Microsoft.FSharp.Core + +[] +[] +/// Contains operations for working with 2-dimensional arrays. +/// +/// +/// See also F# Language Guide - Arrays. +/// +/// F# and CLI multi-dimensional arrays are typically zero-based. +/// However, CLI multi-dimensional arrays used in conjunction with external +/// libraries (e.g. libraries associated with Visual Basic) be +/// non-zero based, using a potentially different base for each dimension. +/// The operations in this module will accept such arrays, and +/// the basing on an input array will be propagated to a matching output +/// array on the Array2D.map and Array2D.mapi operations. +/// Non-zero-based arrays can also be created using Array2D.zeroCreateBased, +/// Array2D.createBased and Array2D.initBased. +/// +module Array2D = + + /// Fetches the base-index for the first dimension of the array. + /// + /// The input array. + /// + /// The base-index of the first dimension of the array. + /// + /// + [] + val base1: array:'T[,] -> int + + /// Fetches the base-index for the second dimension of the array. + /// + /// The input array. + /// + /// The base-index of the second dimension of the array. + /// + /// + [] + val base2: array:'T[,] -> int + + /// Builds a new array whose elements are the same as the input array. + /// + /// For non-zero-based arrays the basing on an input array will be propagated to the output + /// array. + /// + /// The input array. + /// + /// A copy of the input array. + /// + /// + [] + val copy: array:'T[,] -> 'T[,] + + /// Reads a range of elements from the first array and write them into the second. + /// + /// The source array. + /// The first-dimension index to begin copying from in the source array. + /// The second-dimension index to begin copying from in the source array. + /// The target array. + /// The first-dimension index to begin copying into in the target array. + /// The second-dimension index to begin copying into in the target array. + /// The number of elements to copy across the first dimension of the arrays. + /// The number of elements to copy across the second dimension of the arrays. + /// Thrown when any of the indices are negative or if either of + /// the counts are larger than the dimensions of the array allow. + /// + /// + [] + val blit: source:'T[,] -> sourceIndex1:int -> sourceIndex2:int -> target:'T[,] -> targetIndex1:int -> targetIndex2:int -> length1:int -> length2:int -> unit + + /// Creates an array given the dimensions and a generator function to compute the elements. + /// + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// A function to produce elements of the array given the two indices. + /// + /// The generated array. + /// Thrown when either of the lengths is negative. + /// + /// + [] + val init: length1:int -> length2:int -> initializer:(int -> int -> 'T) -> 'T[,] + + /// Creates an array whose elements are all initially the given value. + /// + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// The value to populate the new array. + /// + /// The created array. + /// Thrown when length1 or length2 is negative. + /// + /// + [] + val create: length1:int -> length2:int -> value:'T -> 'T[,] + + /// Creates an array where the entries are initially Unchecked.defaultof<'T>. + /// + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// + /// The created array. + /// Thrown when length1 or length2 is negative. + /// + /// + [] + val zeroCreate : length1:int -> length2:int -> 'T[,] + + /// Creates a based array given the dimensions and a generator function to compute the elements. + /// + /// The base for the first dimension of the array. + /// The base for the second dimension of the array. + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// A function to produce elements of the array given the two indices. + /// + /// The created array. + /// Thrown when base1, base2, length1, or length2 is negative. + /// + /// + [] + val initBased: base1:int -> base2:int -> length1:int -> length2:int -> initializer:(int -> int -> 'T) -> 'T[,] + + /// Creates a based array whose elements are all initially the given value. + /// + /// The base for the first dimension of the array. + /// The base for the second dimension of the array. + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// The value to populate the new array. + /// + /// The created array. + /// Thrown when base1, base2, length1, or length2 is negative. + /// + /// + [] + val createBased: base1:int -> base2:int -> length1:int -> length2:int -> initial: 'T -> 'T[,] + + /// Creates a based array where the entries are initially Unchecked.defaultof<'T>. + /// + /// The base for the first dimension of the array. + /// The base for the second dimension of the array. + /// The length of the first dimension of the array. + /// The length of the second dimension of the array. + /// + /// The created array. + /// Thrown when base1, base2, length1, or length2 is negative. + /// + /// + [] + val zeroCreateBased : base1:int -> base2:int -> length1:int -> length2:int -> 'T[,] + + /// Applies the given function to each element of the array. + /// + /// A function to apply to each element of the array. + /// The input array. + /// + /// + [] + val iter: action:('T -> unit) -> array:'T[,] -> unit + + /// Applies the given function to each element of the array. The integer indices passed to the + /// function indicates the index of element. + /// + /// A function to apply to each element of the array with the indices available as an argument. + /// The input array. + /// + /// + [] + val iteri: action:(int -> int -> 'T -> unit) -> array:'T[,] -> unit + + /// Returns the length of an array in the first dimension. + /// + /// The input array. + /// + /// The length of the array in the first dimension. + /// + /// + [] + val length1: array:'T[,] -> int + + /// Returns the length of an array in the second dimension. + /// + /// The input array. + /// + /// The length of the array in the second dimension. + /// + /// + [] + val length2: array:'T[,] -> int + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. + /// + /// For non-zero-based arrays the basing on an input array will be propagated to the output + /// array. + /// + /// A function that is applied to transform each item of the input array. + /// The input array. + /// + /// An array whose elements have been transformed by the given mapping. + /// + /// + [] + val map: mapping:('T -> 'U) -> array:'T[,] -> 'U[,] + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. The integer indices passed to the + /// function indicates the element being transformed. + /// + /// For non-zero-based arrays the basing on an input array will be propagated to the output + /// array. + /// + /// A function that is applied to transform each element of the array. The two integers + /// provide the index of the element. + /// The input array. + /// + /// An array whose elements have been transformed by the given mapping. + /// + /// + [] + val mapi: mapping:(int -> int -> 'T -> 'U) -> array:'T[,] -> 'U[,] + + + /// Builds a new array whose elements are the same as the input array but + /// where a non-zero-based input array generates a corresponding zero-based + /// output array. + /// + /// The input array. + /// + /// The zero-based output array. + /// + /// + [] + val rebase: array:'T[,] -> 'T[,] + + /// Sets the value of an element in an array. You can also use the syntax array.[index1,index2] <- value. + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// The value to set in the array. + /// Thrown when the indices are negative or exceed the bounds of the array. + /// + /// + [] + val set: array:'T[,] -> index1:int -> index2:int -> value:'T -> unit + + /// Fetches an element from a 2D array. You can also use the syntax array.[index1,index2]. + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// + /// The value of the array at the given index. + /// Thrown when the indices are negative or exceed the bounds of the array. + /// + /// + [] + val get: array:'T[,] -> index1:int -> index2:int -> 'T diff --git a/src/fsharp/FSharp.Core/array3.fsi b/src/fsharp/FSharp.Core/array3.fsi index e5372c9084d..49b585aa8eb 100644 --- a/src/fsharp/FSharp.Core/array3.fsi +++ b/src/fsharp/FSharp.Core/array3.fsi @@ -2,193 +2,274 @@ namespace Microsoft.FSharp.Collections - open System - open Microsoft.FSharp.Collections - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.Operators - - [] - [] - /// Basic operations on rank 3 arrays. - module Array3D = - - /// Creates an array whose elements are all initially the given value. - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The value of the array elements. - /// The created array. - [] - val create: length1:int -> length2:int -> length3:int -> initial:'T -> 'T[,,] - - /// Creates an array given the dimensions and a generator function to compute the elements. - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The function to create an initial value at each index into the array. - /// The created array. - [] - val init: length1:int -> length2:int -> length3:int -> initializer:(int -> int -> int -> 'T) -> 'T[,,] - - /// Fetches an element from a 3D array. You can also use the syntax 'array.[index1,index2,index3]' - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// The index along the third dimension. - /// The value at the given index. - [] - val get: array:'T[,,] -> index1:int -> index2:int -> index3:int -> 'T - - /// Applies the given function to each element of the array. - /// The function to apply to each element of the array. - /// The input array. - [] - val iter: action:('T -> unit) -> array:'T[,,] -> unit - - /// Applies the given function to each element of the array. The integer indices passed to the - /// function indicates the index of element. - /// The function to apply to each element of the array. - /// The input array. - [] - val iteri: action:(int -> int -> int -> 'T -> unit) -> array:'T[,,] -> unit - - /// Returns the length of an array in the first dimension - /// The input array. - /// The length of the array in the first dimension. - [] - val length1: array:'T[,,] -> int - - /// Returns the length of an array in the second dimension. - /// The input array. - /// The length of the array in the second dimension. - [] - val length2: array:'T[,,] -> int - - /// Returns the length of an array in the third dimension. - /// The input array. - /// The length of the array in the third dimension. - [] - val length3: array:'T[,,] -> int - - /// Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the array. - /// - /// For non-zero-based arrays the basing on an input array will be propagated to the output - /// array. - /// The function to transform each element of the array. - /// The input array. - /// The array created from the transformed elements. - [] - val map: mapping:('T -> 'U) -> array:'T[,,] -> 'U[,,] - - /// Builds a new array whose elements are the results of applying the given function - /// to each of the elements of the array. The integer indices passed to the - /// function indicates the element being transformed. - /// - /// For non-zero-based arrays the basing on an input array will be propagated to the output - /// array. - /// The function to transform the elements at each index in the array. - /// The input array. - /// The array created from the transformed elements. - [] - val mapi: mapping:(int -> int -> int -> 'T -> 'U) -> array:'T[,,] -> 'U[,,] - - /// Sets the value of an element in an array. You can also - /// use the syntax 'array.[index1,index2,index3] <- value'. - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// The index along the third dimension. - /// The value to set at the given index. - [] - val set: array:'T[,,] -> index1:int -> index2:int -> index3:int -> value:'T -> unit - - /// Creates an array where the entries are initially the "default" value. - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The created array. - [] - val zeroCreate: length1:int -> length2:int -> length3:int -> 'T[,,] - - - - [] - [] - /// Basic operations on rank 4 arrays. - module Array4D = - - /// Creates an array whose elements are all initially the given value - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The length of the fourth dimension. - /// The initial value for each element of the array. - /// The created array. - [] - val create: length1:int -> length2:int -> length3:int -> length4:int -> initial:'T -> 'T[,,,] - - /// Creates an array given the dimensions and a generator function to compute the elements. - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The length of the fourth dimension. - /// The function to create an initial value at each index in the array. - /// The created array. - [] - val init: length1:int -> length2:int -> length3:int -> length4:int -> initializer:(int -> int -> int -> int -> 'T) -> 'T[,,,] - - /// Returns the length of an array in the first dimension - /// The input array. - /// The length of the array in the first dimension. - [] - val length1: array:'T[,,,] -> int - - /// Returns the length of an array in the second dimension. - /// The input array. - /// The length of the array in the second dimension. - [] - val length2: array:'T[,,,] -> int - - /// Returns the length of an array in the third dimension. - /// The input array. - /// The length of the array in the third dimension. - [] - val length3: array:'T[,,,] -> int - - /// Returns the length of an array in the fourth dimension. - /// The input array. - /// The length of the array in the fourth dimension. - [] - val length4: array:'T[,,,] -> int - - /// Creates an array where the entries are initially the "default" value. - /// The length of the first dimension. - /// The length of the second dimension. - /// The length of the third dimension. - /// The length of the fourth dimension. - /// The created array. - [] - val zeroCreate: length1:int -> length2:int -> length3:int -> length4:int -> 'T[,,,] - - /// Fetches an element from a 4D array. You can also use the syntax 'array.[index1,index2,index3,index4]' - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// The index along the third dimension. - /// The index along the fourth dimension. - /// The value at the given index. - [] - val get: array:'T[,,,] -> index1:int -> index2:int -> index3:int -> index4:int -> 'T - - /// Sets the value of an element in an array. You can also - /// use the syntax 'array.[index1,index2,index3,index4] <- value'. - /// The input array. - /// The index along the first dimension. - /// The index along the second dimension. - /// The index along the third dimension. - /// The index along the fourth dimension. - /// The value to set. - [] - val set: array:'T[,,,] -> index1:int -> index2:int -> index3:int -> index4:int -> value:'T -> unit +open System +open Microsoft.FSharp.Collections +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.Operators + +[] +[] +/// Contains operations for working with rank 3 arrays. +/// +/// +/// See also F# Language Guide - Arrays. +/// +module Array3D = + + /// Creates an array whose elements are all initially the given value. + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// The value of the array elements. + /// + /// The created array. + /// + /// + [] + val create: length1:int -> length2:int -> length3:int -> initial:'T -> 'T[,,] + + /// Creates an array given the dimensions and a generator function to compute the elements. + /// + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// The function to create an initial value at each index into the array. + /// + /// The created array. + /// + /// + [] + val init: length1:int -> length2:int -> length3:int -> initializer:(int -> int -> int -> 'T) -> 'T[,,] + + /// Fetches an element from a 3D array. You can also use the syntax 'array.[index1,index2,index3]' + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// The index along the third dimension. + /// + /// The value at the given index. + /// + /// + [] + val get: array:'T[,,] -> index1:int -> index2:int -> index3:int -> 'T + + /// Applies the given function to each element of the array. + /// + /// The function to apply to each element of the array. + /// The input array. + /// + /// + [] + val iter: action:('T -> unit) -> array:'T[,,] -> unit + + /// Applies the given function to each element of the array. The integer indices passed to the + /// function indicates the index of element. + /// + /// The function to apply to each element of the array. + /// The input array. + /// + /// + [] + val iteri: action:(int -> int -> int -> 'T -> unit) -> array:'T[,,] -> unit + + /// Returns the length of an array in the first dimension + /// + /// The input array. + /// + /// The length of the array in the first dimension. + /// + /// + [] + val length1: array:'T[,,] -> int + + /// Returns the length of an array in the second dimension. + /// + /// The input array. + /// + /// The length of the array in the second dimension. + /// + /// + [] + val length2: array:'T[,,] -> int + + /// Returns the length of an array in the third dimension. + /// + /// The input array. + /// + /// The length of the array in the third dimension. + /// + /// + [] + val length3: array:'T[,,] -> int + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. + /// + /// For non-zero-based arrays the basing on an input array will be propagated to the output + /// array. + /// The function to transform each element of the array. + /// The input array. + /// + /// The array created from the transformed elements. + /// + /// + [] + val map: mapping:('T -> 'U) -> array:'T[,,] -> 'U[,,] + + /// Builds a new array whose elements are the results of applying the given function + /// to each of the elements of the array. The integer indices passed to the + /// function indicates the element being transformed. + /// + /// For non-zero-based arrays the basing on an input array will be propagated to the output + /// array. + /// The function to transform the elements at each index in the array. + /// The input array. + /// + /// The array created from the transformed elements. + /// + /// + [] + val mapi: mapping:(int -> int -> int -> 'T -> 'U) -> array:'T[,,] -> 'U[,,] + + /// Sets the value of an element in an array. You can also + /// use the syntax 'array.[index1,index2,index3] <- value'. + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// The index along the third dimension. + /// The value to set at the given index. + /// + /// + [] + val set: array:'T[,,] -> index1:int -> index2:int -> index3:int -> value:'T -> unit + + /// Creates an array where the entries are initially the "default" value. + /// + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// + /// The created array. + /// + /// + [] + val zeroCreate: length1:int -> length2:int -> length3:int -> 'T[,,] + + + +[] +[] +/// Contains operations for working with rank 4 arrays. +module Array4D = + + /// Creates an array whose elements are all initially the given value + /// + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// The length of the fourth dimension. + /// The initial value for each element of the array. + /// + /// The created array. + /// + /// + [] + val create: length1:int -> length2:int -> length3:int -> length4:int -> initial:'T -> 'T[,,,] + + /// Creates an array given the dimensions and a generator function to compute the elements. + /// + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// The length of the fourth dimension. + /// The function to create an initial value at each index in the array. + /// + /// The created array. + /// + /// + [] + val init: length1:int -> length2:int -> length3:int -> length4:int -> initializer:(int -> int -> int -> int -> 'T) -> 'T[,,,] + + /// Returns the length of an array in the first dimension + /// + /// The input array. + /// + /// The length of the array in the first dimension. + /// + /// + [] + val length1: array:'T[,,,] -> int + + /// Returns the length of an array in the second dimension. + /// + /// The input array. + /// + /// The length of the array in the second dimension. + /// + /// + [] + val length2: array:'T[,,,] -> int + + /// Returns the length of an array in the third dimension. + /// + /// The input array. + /// + /// The length of the array in the third dimension. + /// + /// + [] + val length3: array:'T[,,,] -> int + + /// Returns the length of an array in the fourth dimension. + /// + /// The input array. + /// + /// The length of the array in the fourth dimension. + /// + /// + [] + val length4: array:'T[,,,] -> int + + /// Creates an array where the entries are initially the "default" value. + /// + /// The length of the first dimension. + /// The length of the second dimension. + /// The length of the third dimension. + /// The length of the fourth dimension. + /// + /// The created array. + /// + /// + [] + val zeroCreate: length1:int -> length2:int -> length3:int -> length4:int -> 'T[,,,] + + /// Fetches an element from a 4D array. You can also use the syntax 'array.[index1,index2,index3,index4]' + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// The index along the third dimension. + /// The index along the fourth dimension. + /// + /// The value at the given index. + /// + /// + [] + val get: array:'T[,,,] -> index1:int -> index2:int -> index3:int -> index4:int -> 'T + + /// Sets the value of an element in an array. You can also + /// use the syntax 'array.[index1,index2,index3,index4] <- value'. + /// + /// The input array. + /// The index along the first dimension. + /// The index along the second dimension. + /// The index along the third dimension. + /// The index along the fourth dimension. + /// The value to set. + /// + /// + [] + val set: array:'T[,,,] -> index1:int -> index2:int -> index3:int -> index4:int -> value:'T -> unit diff --git a/src/fsharp/FSharp.Core/async.fs b/src/fsharp/FSharp.Core/async.fs index 4655b0d73f3..6afa26489de 100644 --- a/src/fsharp/FSharp.Core/async.fs +++ b/src/fsharp/FSharp.Core/async.fs @@ -23,11 +23,11 @@ namespace Microsoft.FSharp.Control let linkedCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, failureCTS.Token) - member this.Token = linkedCTS.Token + member _.Token = linkedCTS.Token - member this.Cancel() = failureCTS.Cancel() + member _.Cancel() = failureCTS.Cancel() - member this.Dispose() = + member _.Dispose() = linkedCTS.Dispose() failureCTS.Dispose() @@ -66,6 +66,8 @@ namespace Microsoft.FSharp.Control [] type AsyncReturn = | AsyncReturn + with + static member inline Fake() = Unchecked.defaultof type cont<'T> = ('T -> AsyncReturn) type econt = (ExceptionDispatchInfo -> AsyncReturn) @@ -74,9 +76,6 @@ namespace Microsoft.FSharp.Control [] type Trampoline() = - let fake () = Unchecked.defaultof - let unfake (_ : AsyncReturn) = () - [] static let bindLimitBeforeHijack = 300 @@ -93,97 +92,124 @@ namespace Microsoft.FSharp.Control /// Use this trampoline on the synchronous stack if none exists, and execute /// the given function. The function might write its continuation into the trampoline. [] - member __.Execute (firstAction: unit -> AsyncReturn) = + member _.Execute (firstAction: unit -> AsyncReturn) = - let thisIsTopTrampoline = - if Trampoline.thisThreadHasTrampoline then - false - else - Trampoline.thisThreadHasTrampoline <- true - true + let thisThreadHadTrampoline = Trampoline.thisThreadHasTrampoline + Trampoline.thisThreadHasTrampoline <- true try let mutable keepGoing = true let mutable action = firstAction while keepGoing do try - action() |> unfake + action() |> ignore match storedCont with | None -> keepGoing <- false | Some cont -> storedCont <- None action <- cont - // Let the exception propagate all the way to the trampoline to get a full .StackTrace entry + + // Catch exceptions at the trampoline to get a full .StackTrace entry + // This is because of this problem https://stackoverflow.com/questions/5301535/exception-call-stack-truncated-without-any-re-throwing + // where only a limited number of stack frames are included in the .StackTrace property + // of a .NET exception when it is thrown, up to the first catch handler. + // + // So when running async code, there aren't any intermediate catch handlers (though there + // may be intermediate try/finally frames), there is just this one catch handler at the + // base of the stack. + // + // If an exception is thrown we must have storedExnCont via OnExceptionRaised. with exn -> match storedExnCont with | None -> + // Here, the exception escapes the trampoline. This should not happen since all + // exception-generating code should use ProtectCode. However some + // direct uses of combinators (not using async {...}) may cause + // code to execute unprotected, e.g. async.While((fun () -> failwith ".."), ...) executes the first + // guardExpr unprotected. reraise() + | Some econt -> storedExnCont <- None let edi = ExceptionDispatchInfo.RestoreOrCapture exn action <- (fun () -> econt edi) finally - if thisIsTopTrampoline then - Trampoline.thisThreadHasTrampoline <- false - fake() + Trampoline.thisThreadHasTrampoline <- thisThreadHadTrampoline + AsyncReturn.Fake() /// Increment the counter estimating the size of the synchronous stack and /// return true if time to jump on trampoline. - member __.IncrementBindCount() = + member _.IncrementBindCount() = bindCount <- bindCount + 1 bindCount >= bindLimitBeforeHijack /// Prepare to abandon the synchronous stack of the current execution and save the continuation in the trampoline. - member __.Set action = + member _.Set action = assert storedCont.IsNone bindCount <- 0 storedCont <- Some action - fake() + AsyncReturn.Fake() /// Save the exception continuation during propagation of an exception, or prior to raising an exception - member __.OnExceptionRaised (action: econt) = + member _.OnExceptionRaised (action: econt) = assert storedExnCont.IsNone storedExnCont <- Some action - type TrampolineHolder() as this = + type TrampolineHolder() = let mutable trampoline = null - let fake () = Unchecked.defaultof - static let unfake (_: AsyncReturn) = () - - // Preallocate this delegate and keep it in the trampoline holder. - let sendOrPostCallbackWithTrampoline = - SendOrPostCallback (fun o -> - let f = unbox<(unit -> AsyncReturn)> o - this.ExecuteWithTrampoline f |> unfake) - - // Preallocate this delegate and keep it in the trampoline holder. - let waitCallbackForQueueWorkItemWithTrampoline = - WaitCallback (fun o -> - let f = unbox<(unit -> AsyncReturn)> o - this.ExecuteWithTrampoline f |> unfake) - - // Preallocate this delegate and keep it in the trampoline holder. - let threadStartCallbackForStartThreadWithTrampoline = - ParameterizedThreadStart (fun o -> - let f = unbox<(unit -> AsyncReturn)> o - this.ExecuteWithTrampoline f |> unfake) + // On-demand allocate this delegate and keep it in the trampoline holder. + let mutable sendOrPostCallbackWithTrampoline : SendOrPostCallback = null + let getSendOrPostCallbackWithTrampoline(this: TrampolineHolder) = + match sendOrPostCallbackWithTrampoline with + | null -> + sendOrPostCallbackWithTrampoline <- + SendOrPostCallback (fun o -> + let f = unbox AsyncReturn> o + // Reminder: the ignore below ignores an AsyncReturn. + this.ExecuteWithTrampoline f |> ignore) + | _ -> () + sendOrPostCallbackWithTrampoline + + // On-demand allocate this delegate and keep it in the trampoline holder. + let mutable waitCallbackForQueueWorkItemWithTrampoline : WaitCallback = null + let getWaitCallbackForQueueWorkItemWithTrampoline(this: TrampolineHolder) = + match waitCallbackForQueueWorkItemWithTrampoline with + | null -> + waitCallbackForQueueWorkItemWithTrampoline <- + WaitCallback (fun o -> + let f = unbox AsyncReturn> o + this.ExecuteWithTrampoline f |> ignore) + | _ -> () + waitCallbackForQueueWorkItemWithTrampoline + + // On-demand allocate this delegate and keep it in the trampoline holder. + let mutable threadStartCallbackForStartThreadWithTrampoline : ParameterizedThreadStart = null + let getThreadStartCallbackForStartThreadWithTrampoline(this: TrampolineHolder) = + match threadStartCallbackForStartThreadWithTrampoline with + | null -> + threadStartCallbackForStartThreadWithTrampoline <- + ParameterizedThreadStart (fun o -> + let f = unbox AsyncReturn> o + this.ExecuteWithTrampoline f |> ignore) + | _ -> () + threadStartCallbackForStartThreadWithTrampoline /// Execute an async computation after installing a trampoline on its synchronous stack. [] - member __.ExecuteWithTrampoline firstAction = - trampoline <- new Trampoline() + member _.ExecuteWithTrampoline firstAction = + trampoline <- Trampoline() trampoline.Execute firstAction member this.PostWithTrampoline (syncCtxt: SynchronizationContext) (f: unit -> AsyncReturn) = - syncCtxt.Post (sendOrPostCallbackWithTrampoline, state=(f |> box)) - fake() + syncCtxt.Post (getSendOrPostCallbackWithTrampoline(this), state=(f |> box)) + AsyncReturn.Fake() member this.QueueWorkItemWithTrampoline (f: unit -> AsyncReturn) = - if not (ThreadPool.QueueUserWorkItem(waitCallbackForQueueWorkItemWithTrampoline, f |> box)) then + if not (ThreadPool.QueueUserWorkItem(getWaitCallbackForQueueWorkItemWithTrampoline(this), f |> box)) then failwith "failed to queue user work item" - fake() + AsyncReturn.Fake() member this.PostOrQueueWithTrampoline (syncCtxt: SynchronizationContext) f = match syncCtxt with @@ -191,16 +217,16 @@ namespace Microsoft.FSharp.Control | _ -> this.PostWithTrampoline syncCtxt f // This should be the only call to Thread.Start in this library. We must always install a trampoline. - member __.StartThreadWithTrampoline (f: unit -> AsyncReturn) = - (new Thread(threadStartCallbackForStartThreadWithTrampoline, IsBackground=true)).Start(f|>box) - fake() + member this.StartThreadWithTrampoline (f: unit -> AsyncReturn) = + Thread(getThreadStartCallbackForStartThreadWithTrampoline(this), IsBackground=true).Start(f|>box) + AsyncReturn.Fake() /// Save the exception continuation during propagation of an exception, or prior to raising an exception - member inline __.OnExceptionRaised econt = + member inline _.OnExceptionRaised econt = trampoline.OnExceptionRaised econt /// Call a continuation, but first check if an async computation should trampoline on its synchronous stack. - member inline __.HijackCheckThenCall (cont: 'T -> AsyncReturn) res = + member inline _.HijackCheckThenCall (cont: 'T -> AsyncReturn) res = if trampoline.IncrementBindCount() then trampoline.Set (fun () -> cont res) else @@ -245,57 +271,63 @@ namespace Microsoft.FSharp.Control member ctxt.WithExceptionContinuation econt = AsyncActivation<'T> { contents with aux = { ctxt.aux with econt = econt } } /// Produce a new execution context for a composite async - member ctxt.WithContinuation cont = AsyncActivation<'U> { cont = cont; aux = contents.aux } + member _.WithContinuation cont = AsyncActivation<'U> { cont = cont; aux = contents.aux } /// Produce a new execution context for a composite async - member ctxt.WithContinuations(cont, econt) = AsyncActivation<'U> { cont = cont; aux = { contents.aux with econt = econt } } + member _.WithContinuations(cont, econt) = AsyncActivation<'U> { cont = cont; aux = { contents.aux with econt = econt } } /// Produce a new execution context for a composite async member ctxt.WithContinuations(cont, econt, ccont) = AsyncActivation<'T> { contents with cont = cont; aux = { ctxt.aux with econt = econt; ccont = ccont } } /// The extra information relevant to the execution of the async - member ctxt.aux = contents.aux + member _.aux = contents.aux /// The success continuation relevant to the execution of the async - member ctxt.cont = contents.cont + member _.cont = contents.cont /// The exception continuation relevant to the execution of the async - member ctxt.econt = contents.aux.econt + member _.econt = contents.aux.econt /// The cancellation continuation relevant to the execution of the async - member ctxt.ccont = contents.aux.ccont + member _.ccont = contents.aux.ccont /// The cancellation token relevant to the execution of the async - member ctxt.token = contents.aux.token + member _.token = contents.aux.token /// The trampoline holder being used to protect execution of the async - member ctxt.trampolineHolder = contents.aux.trampolineHolder + member _.trampolineHolder = contents.aux.trampolineHolder /// Check if cancellation has been requested - member ctxt.IsCancellationRequested = contents.aux.token.IsCancellationRequested + member _.IsCancellationRequested = contents.aux.token.IsCancellationRequested /// Call the cancellation continuation of the active computation - member ctxt.OnCancellation () = - contents.aux.ccont (new OperationCanceledException (contents.aux.token)) + member _.OnCancellation () = + contents.aux.ccont (OperationCanceledException (contents.aux.token)) /// Check for trampoline hijacking. - member inline ctxt.HijackCheckThenCall cont arg = - contents.aux.trampolineHolder.HijackCheckThenCall cont arg + // Note, this must make tailcalls, so may not be an instance member taking a byref argument, + /// nor call any members taking byref arguments. + static member inline HijackCheckThenCall (ctxt: AsyncActivation<'T>) cont arg = + ctxt.aux.trampolineHolder.HijackCheckThenCall cont arg /// Call the success continuation of the asynchronous execution context after checking for /// cancellation and trampoline hijacking. - member ctxt.OnSuccess result = + // - Cancellation check + // - Hijack check + // + // Note, this must make tailcalls, so may not be an instance member taking a byref argument. + static member Success (ctxt: AsyncActivation<'T>) result = if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - ctxt.HijackCheckThenCall ctxt.cont result + AsyncActivation<'T>.HijackCheckThenCall ctxt ctxt.cont result - /// Call the exception continuation directly - member ctxt.CallExceptionContinuation edi = - contents.aux.econt edi + // For backwards API Compat + [] + member ctxt.OnSuccess (result: 'T) = AsyncActivation<'T>.Success ctxt result /// Save the exception continuation during propagation of an exception, or prior to raising an exception - member ctxt.OnExceptionRaised() = + member _.OnExceptionRaised() = contents.aux.trampolineHolder.OnExceptionRaised contents.aux.econt /// Make an initial async activation. @@ -305,8 +337,28 @@ namespace Microsoft.FSharp.Control /// Queue the success continuation of the asynchronous execution context as a work item in the thread pool /// after installing a trampoline member ctxt.QueueContinuationWithTrampoline (result: 'T) = - let ctxt = ctxt - ctxt.aux.trampolineHolder.QueueWorkItemWithTrampoline(fun () -> ctxt.cont result) + let cont = ctxt.cont + ctxt.aux.trampolineHolder.QueueWorkItemWithTrampoline(fun () -> cont result) + + /// Ensure that any exceptions raised by the immediate execution of "userCode" + /// are sent to the exception continuation. This is done by allowing the exception to propagate + /// to the trampoline, and the saved exception continuation is called there. + /// + /// It is also valid for MakeAsync primitive code to call the exception continuation directly. + [] + member ctxt.ProtectCode userCode = + let mutable ok = false + try + let res = userCode() + ok <- true + res + finally + if not ok then + ctxt.OnExceptionRaised() + + member ctxt.PostWithTrampoline (syncCtxt: SynchronizationContext) (f: unit -> AsyncReturn) = + let holder = contents.aux.trampolineHolder + ctxt.ProtectCode (fun () -> holder.PostWithTrampoline syncCtxt f) /// Call the success continuation of the asynchronous execution context member ctxt.CallContinuation(result: 'T) = @@ -323,17 +375,7 @@ namespace Microsoft.FSharp.Control let mutable i = 0 /// Execute the latch - member this.Enter() = Interlocked.CompareExchange(&i, 1, 0) = 0 - - /// Ensures that a function is only called once - [] - type Once() = - let latch = Latch() - - /// Execute the function at most once - member this.Do f = - if latch.Enter() then - f() + member _.Enter() = Interlocked.CompareExchange(&i, 1, 0) = 0 /// Represents the result of an asynchronous computation [] @@ -355,7 +397,7 @@ namespace Microsoft.FSharp.Control let inline fake () = Unchecked.defaultof - let unfake (_: AsyncReturn) = () + let inline unfake (_: AsyncReturn) = () /// The mutable global CancellationTokenSource, see Async.DefaultCancellationToken let mutable defaultCancellationTokenSource = new CancellationTokenSource() @@ -365,10 +407,13 @@ namespace Microsoft.FSharp.Control // Note: direct calls to this function may end up in user assemblies via inlining [] let Invoke (computation: Async<'T>) (ctxt: AsyncActivation<_>) : AsyncReturn = - ctxt.HijackCheckThenCall computation.Invoke ctxt + AsyncActivation<'T>.HijackCheckThenCall ctxt computation.Invoke ctxt - /// Apply userCode to x. If no exception is raised then call the normal continuation. Used to implement + /// Apply 'userCode' to 'arg'. If no exception is raised then call the normal continuation. Used to implement /// 'finally' and 'when cancelled'. + /// + /// - Apply 'userCode' to argument with exception protection + /// - Hijack check before invoking the continuation [] let CallThenContinue userCode arg (ctxt: AsyncActivation<_>) : AsyncReturn = let mutable result = Unchecked.defaultof<_> @@ -382,13 +427,16 @@ namespace Microsoft.FSharp.Control ctxt.OnExceptionRaised() if ok then - ctxt.HijackCheckThenCall ctxt.cont result + AsyncActivation<'T>.HijackCheckThenCall ctxt ctxt.cont result else fake() /// Apply 'part2' to 'result1' and invoke the resulting computation. - // - // Note: direct calls to this function end up in user assemblies via inlining + /// + /// Note: direct calls to this function end up in user assemblies via inlining + /// + /// - Apply 'part2' to argument with exception protection + /// - Hijack check before invoking the resulting computation [] let CallThenInvoke (ctxt: AsyncActivation<_>) result1 part2 : AsyncReturn = let mutable result = Unchecked.defaultof<_> @@ -408,7 +456,7 @@ namespace Microsoft.FSharp.Control /// Like `CallThenInvoke` but does not do a hijack check for historical reasons (exact code compat) [] - let CallThenInvokeNoHijackCheck (ctxt: AsyncActivation<_>) userCode result1 = + let CallThenInvokeNoHijackCheck (ctxt: AsyncActivation<_>) result1 userCode = let mutable res = Unchecked.defaultof<_> let mutable ok = false @@ -424,15 +472,18 @@ namespace Microsoft.FSharp.Control else fake() - /// Apply 'catchFilter' to 'arg'. If the result is 'Some' invoke the resulting computation. If the result is 'None' + /// Apply 'filterFunction' to 'arg'. If the result is 'Some' invoke the resulting computation. If the result is 'None' /// then send 'result1' to the exception continuation. + /// + /// - Apply 'filterFunction' to argument with exception protection + /// - Hijack check before invoking the resulting computation or exception continuation [] - let CallFilterThenInvoke (ctxt: AsyncActivation<'T>) catchFilter (edi: ExceptionDispatchInfo) : AsyncReturn = - let mutable resOpt = Unchecked.defaultof<_> + let CallFilterThenInvoke (ctxt: AsyncActivation<'T>) filterFunction (edi: ExceptionDispatchInfo) : AsyncReturn = + let mutable resOpt = None let mutable ok = false try - resOpt <- catchFilter (edi.GetAssociatedSourceException()) + resOpt <- filterFunction (edi.GetAssociatedSourceException()) ok <- true finally if not ok then @@ -441,165 +492,226 @@ namespace Microsoft.FSharp.Control if ok then match resOpt with | None -> - ctxt.HijackCheckThenCall ctxt.econt edi + AsyncActivation<'T>.HijackCheckThenCall ctxt ctxt.econt edi | Some res -> Invoke res ctxt else fake() - /// Internal way of making an async from code, for exact code compat. - /// Perform a cancellation check and ensure that any exceptions raised by - /// the immediate execution of "userCode" are sent to the exception continuation. - [] - let ProtectedCode (ctxt: AsyncActivation<'T>) userCode = - if ctxt.IsCancellationRequested then - ctxt.OnCancellation () - else - let mutable ok = false - try - let res = userCode ctxt - ok <- true - res - finally - if not ok then - ctxt.OnExceptionRaised() - /// Build a primitive without any exception or resync protection [] let MakeAsync body = { Invoke = body } [] - // Note: direct calls to this function end up in user assemblies via inlining + let MakeAsyncWithCancelCheck body = + MakeAsync (fun ctxt -> + if ctxt.IsCancellationRequested then + ctxt.OnCancellation () + else + body ctxt) + + /// Execute part1, then apply part2, then execute the result of that + /// + /// Note: direct calls to this function end up in user assemblies via inlining + /// - Initial cancellation check + /// - Initial hijack check (see Invoke) + /// - No hijack check after applying 'part2' to argument (see CallThenInvoke) + /// - No cancellation check after applying 'part2' to argument (see CallThenInvoke) + /// - Apply 'part2' to argument with exception protection (see CallThenInvoke) + [] let Bind (ctxt: AsyncActivation<'T>) (part1: Async<'U>) (part2: 'U -> Async<'T>) : AsyncReturn = if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - Invoke part1 (ctxt.WithContinuation(fun result1 -> CallThenInvokeNoHijackCheck ctxt part2 result1 )) + // Note, no cancellation check is done before calling 'part2'. This is + // because part1 may bind a resource, while part2 is a try/finally, and, if + // the resource creation completes, we want to enter part2 before cancellation takes effect. + Invoke part1 (ctxt.WithContinuation(fun result1 -> CallThenInvokeNoHijackCheck ctxt result1 part2)) - [] /// Re-route all continuations to execute the finally function. - let TryFinally (ctxt: AsyncActivation<'T>) computation finallyFunction = + /// - Cancellation check after 'entering' the try/finally and before running the body + /// - Hijack check after 'entering' the try/finally and before running the body (see Invoke) + /// - Run 'finallyFunction' with exception protection (see CallThenContinue) + /// - Hijack check before any of the continuations (see CallThenContinue) + [] + let TryFinally (ctxt: AsyncActivation<'T>) (computation: Async<'T>) finallyFunction = + // Note, we don't test for cancellation before entering a try/finally. This prevents + // a resource being created without being disposed. + + // The new continuation runs the finallyFunction and resumes the old continuation + // If an exception is thrown we continue with the previous exception continuation. + let cont result = + CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.cont result)) + + // The new exception continuation runs the finallyFunction and then runs the previous exception continuation. + // If an exception is thrown we continue with the previous exception continuation. + let econt edi = + CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.econt edi)) + + // The cancellation continuation runs the finallyFunction and then runs the previous cancellation continuation. + // If an exception is thrown we continue with the previous cancellation continuation (the exception is lost) + let ccont cexn = + CallThenContinue finallyFunction () (ctxt.WithContinuations(cont=(fun () -> ctxt.ccont cexn), econt = (fun _ -> ctxt.ccont cexn))) + + let ctxt = ctxt.WithContinuations(cont=cont, econt=econt, ccont=ccont) if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - // The new continuation runs the finallyFunction and resumes the old continuation - // If an exception is thrown we continue with the previous exception continuation. - let cont result = - CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.cont result)) - // The new exception continuation runs the finallyFunction and then runs the previous exception continuation. - // If an exception is thrown we continue with the previous exception continuation. - let econt exn = - CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.econt exn)) - // The cancellation continuation runs the finallyFunction and then runs the previous cancellation continuation. - // If an exception is thrown we continue with the previous cancellation continuation (the exception is lost) - let ccont cexn = - CallThenContinue finallyFunction () (ctxt.WithContinuations(cont=(fun () -> ctxt.ccont cexn), econt = (fun _ -> ctxt.ccont cexn))) - let newCtxt = ctxt.WithContinuations(cont=cont, econt=econt, ccont=ccont) - computation.Invoke newCtxt + computation.Invoke ctxt /// Re-route the exception continuation to call to catchFunction. If catchFunction returns None then call the exception continuation. /// If it returns Some, invoke the resulting async. + /// - Cancellation check before entering the try + /// - No hijack check after 'entering' the try/with + /// - Cancellation check before applying the 'catchFunction' + /// - Apply `catchFunction' to argument with exception protection (see CallFilterThenInvoke) + /// - Hijack check before invoking the resulting computation or exception continuation (see CallFilterThenInvoke) [] - let TryWith (ctxt: AsyncActivation<'T>) computation catchFunction = + let TryWith (ctxt: AsyncActivation<'T>) (computation: Async<'T>) catchFunction = if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - let newCtxt = + let ctxt = ctxt.WithExceptionContinuation(fun edi -> if ctxt.IsCancellationRequested then ctxt.OnCancellation () else CallFilterThenInvoke ctxt catchFunction edi) - computation.Invoke newCtxt - /// Internal way of making an async from code, for exact code compat. - /// When run, ensures that any exceptions raised by the immediate execution of "f" are - /// sent to the exception continuation. - let CreateProtectedAsync f = - MakeAsync (fun ctxt -> ProtectedCode ctxt f) + computation.Invoke ctxt - /// Internal way of making an async from result, for exact code compat. + /// Make an async for an AsyncResult + // - No cancellation check + // - No hijack check let CreateAsyncResultAsync res = MakeAsync (fun ctxt -> match res with | AsyncResult.Ok r -> ctxt.cont r - | AsyncResult.Error edi -> ctxt.CallExceptionContinuation edi - | AsyncResult.Canceled oce -> ctxt.ccont oce) + | AsyncResult.Error edi -> ctxt.econt edi + | AsyncResult.Canceled cexn -> ctxt.ccont cexn) - // Generate async computation which calls its continuation with the given result + /// Generate async computation which calls its continuation with the given result + /// - Cancellation check (see OnSuccess) + /// - Hijack check (see OnSuccess) let inline CreateReturnAsync res = // Note: this code ends up in user assemblies via inlining - MakeAsync (fun ctxt -> ctxt.OnSuccess res) - - // The primitive bind operation. Generate a process that runs the first process, takes - // its result, applies f and then runs the new process produced. Hijack if necessary and - // run 'f' with exception protection + MakeAsync (fun ctxt -> AsyncActivation.Success ctxt res) + + /// Runs the first process, takes its result, applies f and then runs the new process produced. + /// - Initial cancellation check (see Bind) + /// - Initial hijack check (see Bind) + /// - No hijack check after applying 'part2' to argument (see Bind) + /// - No cancellation check after applying 'part2' to argument (see Bind) + /// - Apply 'part2' to argument with exception protection (see Bind) let inline CreateBindAsync part1 part2 = // Note: this code ends up in user assemblies via inlining MakeAsync (fun ctxt -> Bind ctxt part1 part2) - // Call the given function with exception protection, but first - // check for cancellation. + /// Call the given function with exception protection. + /// - No initial cancellation check + /// - Hijack check after applying part2 to argument (see CallThenInvoke) let inline CreateCallAsync part2 result1 = // Note: this code ends up in user assemblies via inlining MakeAsync (fun ctxt -> - if ctxt.IsCancellationRequested then - ctxt.OnCancellation () - else - CallThenInvoke ctxt result1 part2) + CallThenInvoke ctxt result1 part2) + /// Call the given function with exception protection. + /// - Initial cancellation check + /// - Hijack check after applying computation to argument (see CallThenInvoke) + /// - Apply 'computation' to argument with exception protection (see CallThenInvoke) let inline CreateDelayAsync computation = // Note: this code ends up in user assemblies via inlining - CreateCallAsync computation () + MakeAsyncWithCancelCheck (fun ctxt -> + CallThenInvoke ctxt () computation) /// Implements the sequencing construct of async computation expressions + /// - Initial cancellation check (see CreateBindAsync) + /// - Initial hijack check (see CreateBindAsync) + /// - No hijack check after applying 'part2' to argument (see CreateBindAsync) + /// - No cancellation check after applying 'part2' to argument (see CreateBindAsync) + /// - Apply 'part2' to argument with exception protection (see CreateBindAsync) let inline CreateSequentialAsync part1 part2 = // Note: this code ends up in user assemblies via inlining CreateBindAsync part1 (fun () -> part2) /// Create an async for a try/finally + /// - Cancellation check after 'entering' the try/finally and before running the body + /// - Hijack check after 'entering' the try/finally and before running the body (see TryFinally) + /// - Apply 'finallyFunction' with exception protection (see TryFinally) let inline CreateTryFinallyAsync finallyFunction computation = MakeAsync (fun ctxt -> TryFinally ctxt computation finallyFunction) /// Create an async for a try/with filtering exceptions through a pattern match - let inline CreateTryWithFilterAsync catchFunction computation = - MakeAsync (fun ctxt -> TryWith ctxt computation (fun edi -> catchFunction edi)) + /// - Cancellation check before entering the try (see TryWith) + /// - Cancellation check before entering the with (see TryWith) + /// - Apply `filterFunction' to argument with exception protection (see TryWith) + /// - Hijack check before invoking the resulting computation or exception continuation + let inline CreateTryWithFilterAsync filterFunction computation = + MakeAsync (fun ctxt -> TryWith ctxt computation filterFunction) /// Create an async for a try/with filtering + /// - Cancellation check before entering the try (see TryWith) + /// - Cancellation check before entering the with (see TryWith) + /// - Apply `catchFunction' to argument with exception protection (see TryWith) + /// - Hijack check before invoking the resulting computation or exception continuation let inline CreateTryWithAsync catchFunction computation = - CreateTryWithFilterAsync (fun exn -> Some (catchFunction exn)) computation + MakeAsync (fun ctxt -> TryWith ctxt computation (fun exn -> Some (catchFunction exn))) /// Call the finallyFunction if the computation results in a cancellation, and then continue with cancellation. /// If the finally function gives an exception then continue with cancellation regardless. + /// - No cancellation check before entering the when-cancelled + /// - No hijack check before entering the when-cancelled + /// - Apply `finallyFunction' to argument with exception protection (see CallThenContinue) + /// - Hijack check before continuing with cancellation (see CallThenContinue) let CreateWhenCancelledAsync (finallyFunction: OperationCanceledException -> unit) computation = MakeAsync (fun ctxt -> let ccont = ctxt.ccont - let newCtxt = - ctxt.WithCancellationContinuation(fun exn -> - CallThenContinue finallyFunction exn (ctxt.WithContinuations(cont = (fun _ -> ccont exn), econt = (fun _ -> ccont exn)))) - computation.Invoke newCtxt) + let ctxt = + ctxt.WithCancellationContinuation(fun cexn -> + CallThenContinue finallyFunction cexn (ctxt.WithContinuations(cont = (fun _ -> ccont cexn), econt = (fun _ -> ccont cexn)))) + computation.Invoke ctxt) /// A single pre-allocated computation that fetched the current cancellation token let cancellationTokenAsync = MakeAsync (fun ctxt -> ctxt.cont ctxt.aux.token) /// A single pre-allocated computation that returns a unit result + /// - Cancellation check (see CreateReturnAsync) + /// - Hijack check (see CreateReturnAsync) let unitAsync = CreateReturnAsync() /// Implement use/Dispose + /// + /// - No initial cancellation check before applying computation to its argument. See CreateTryFinallyAsync + /// and CreateCallAsync. We enter the try/finally before any cancel checks. + /// - Cancellation check after 'entering' the implied try/finally and before running the body (see CreateTryFinallyAsync) + /// - Hijack check after 'entering' the implied try/finally and before running the body (see CreateTryFinallyAsync) + /// - Run 'disposeFunction' with exception protection (see CreateTryFinallyAsync) let CreateUsingAsync (resource:'T :> IDisposable) (computation:'T -> Async<'a>) : Async<'a> = - let mutable x = 0 - let disposeFunction _ = - if Interlocked.CompareExchange(&x, 1, 0) = 0 then - Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose resource - CreateTryFinallyAsync disposeFunction (CreateCallAsync computation resource) |> CreateWhenCancelledAsync disposeFunction + let disposeFunction () = Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose resource + CreateTryFinallyAsync disposeFunction (CreateCallAsync computation resource) + /// - Initial cancellation check (see CreateBindAsync) + /// - Initial hijack check (see CreateBindAsync) + /// - Cancellation check after (see unitAsync) + /// - No hijack check after (see unitAsync) let inline CreateIgnoreAsync computation = CreateBindAsync computation (fun _ -> unitAsync) /// Implement the while loop construct of async computation expressions + /// - No initial cancellation check before first execution of guard + /// - No initial hijack check before first execution of guard + /// - No cancellation check before each execution of guard (see CreateBindAsync) + /// - Hijack check before each execution of guard (see CreateBindAsync) + /// - Cancellation check before each execution of the body after guard (CreateBindAsync) + /// - No hijack check before each execution of the body after guard (see CreateBindAsync) + /// - Cancellation check after guard fails (see unitAsync) + /// - Hijack check after guard fails (see unitAsync) + /// - Apply 'guardFunc' with exception protection (see ProtectCode) + // + // Note: There are allocations during loop set up, but no allocations during iterations of the loop let CreateWhileAsync guardFunc computation = if guardFunc() then let mutable whileAsync = Unchecked.defaultof<_> @@ -608,39 +720,107 @@ namespace Microsoft.FSharp.Control else unitAsync +#if REDUCED_ALLOCATIONS_BUT_RUNS_SLOWER + /// Implement the while loop construct of async computation expressions + /// - Initial cancellation check before each execution of guard + /// - No initial hijack check before each execution of guard + /// - No cancellation check before each execution of the body after guard + /// - Hijack check before each execution of the body after guard (see Invoke) + /// - Cancellation check after guard fails (see OnSuccess) + /// - Hijack check after guard fails (see OnSuccess) + /// - Apply 'guardFunc' with exception protection (see ProtectCode) + // + // Note: There are allocations during loop set up, but no allocations during iterations of the loop + // One allocation for While async + // One allocation for While async context function + MakeAsync (fun ctxtGuard -> + // One allocation for ctxtLoop reference cell + let mutable ctxtLoop = Unchecked.defaultof<_> + // One allocation for While recursive closure + let rec WhileLoop () = + if ctxtGuard.IsCancellationRequested then + ctxtGuard.OnCancellation () + elif ctxtGuard.ProtectCode guardFunc then + Invoke computation ctxtLoop + else + ctxtGuard.OnSuccess () + // One allocation for While body activation context + ctxtLoop <- ctxtGuard.WithContinuation(WhileLoop) + WhileLoop ()) +#endif + /// Implement the for loop construct of async commputation expressions + /// - No initial cancellation check before GetEnumerator call. + /// - No initial cancellation check before entering protection of implied try/finally + /// - Cancellation check after 'entering' the implied try/finally and before loop + /// - Hijack check after 'entering' the implied try/finally and after MoveNext call + /// - Do not apply 'GetEnumerator' with exception protection. However for an 'async' + /// in an 'async { ... }' the exception protection will be provided by the enclosing + // Delay or Bind or similar construct. + /// - Apply 'MoveNext' with exception protection + /// - Apply 'Current' with exception protection + + // Note: No allocations during iterations of the loop apart from those from + // applying the loop body to the element let CreateForLoopAsync (source: seq<_>) computation = CreateUsingAsync (source.GetEnumerator()) (fun ie -> CreateWhileAsync (fun () -> ie.MoveNext()) (CreateDelayAsync (fun () -> computation ie.Current))) +#if REDUCED_ALLOCATIONS_BUT_RUNS_SLOWER + CreateUsingAsync (source.GetEnumerator()) (fun ie -> + // One allocation for While async + // One allocation for While async context function + MakeAsync (fun ctxtGuard -> + // One allocation for ctxtLoop reference cell + let mutable ctxtLoop = Unchecked.defaultof<_> + // Two allocations for protected functions + let guardFunc() = ie.MoveNext() + let currentFunc() = ie.Current + // One allocation for ForLoop recursive closure + let rec ForLoop () = + if ctxtGuard.IsCancellationRequested then + ctxtGuard.OnCancellation () + elif ctxtGuard.ProtectCode guardFunc then + let x = ctxtGuard.ProtectCode currentFunc + CallThenInvoke ctxtLoop x computation + else + ctxtGuard.OnSuccess () + // One allocation for loop activation context + ctxtLoop <- ctxtGuard.WithContinuation(ForLoop) + ForLoop ())) +#endif + + /// - Initial cancellation check + /// - Call syncCtxt.Post with exception protection. THis may fail as it is arbitrary user code let CreateSwitchToAsync (syncCtxt: SynchronizationContext) = - CreateProtectedAsync (fun ctxt -> - ctxt.trampolineHolder.PostWithTrampoline syncCtxt ctxt.cont) + MakeAsyncWithCancelCheck (fun ctxt -> + ctxt.PostWithTrampoline syncCtxt ctxt.cont) + /// - Initial cancellation check + /// - Create Thread and call Start() with exception protection. We don't expect this + /// to fail but protect nevertheless. let CreateSwitchToNewThreadAsync() = - CreateProtectedAsync (fun ctxt -> - ctxt.trampolineHolder.StartThreadWithTrampoline ctxt.cont) + MakeAsyncWithCancelCheck (fun ctxt -> + ctxt.ProtectCode (fun () -> ctxt.trampolineHolder.StartThreadWithTrampoline ctxt.cont)) + /// - Initial cancellation check + /// - Call ThreadPool.QueueUserWorkItem with exception protection. We don't expect this + /// to fail but protect nevertheless. let CreateSwitchToThreadPoolAsync() = - CreateProtectedAsync (fun ctxt -> - ctxt.trampolineHolder.QueueWorkItemWithTrampoline ctxt.cont) + MakeAsyncWithCancelCheck (fun ctxt -> + ctxt.ProtectCode (fun () -> ctxt.trampolineHolder.QueueWorkItemWithTrampoline ctxt.cont)) /// Post back to the sync context regardless of which continuation is taken + /// - Call syncCtxt.Post with exception protection let DelimitSyncContext (ctxt: AsyncActivation<_>) = match SynchronizationContext.Current with | null -> ctxt | syncCtxt -> - ctxt.WithContinuations(cont = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.cont x)), - econt = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.econt x)), - ccont = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.ccont x))) - - // When run, ensures that each of the continuations of the process are run in the same synchronization context. - let CreateDelimitedUserCodeAsync f = - CreateProtectedAsync (fun ctxt -> - let ctxtWithSync = DelimitSyncContext ctxt - f ctxtWithSync) + ctxt.WithContinuations(cont = (fun x -> ctxt.PostWithTrampoline syncCtxt (fun () -> ctxt.cont x)), + econt = (fun edi -> ctxt.PostWithTrampoline syncCtxt (fun () -> ctxt.econt edi)), + ccont = (fun cexn -> ctxt.PostWithTrampoline syncCtxt (fun () -> ctxt.ccont cexn))) [] [] @@ -655,21 +835,22 @@ namespace Microsoft.FSharp.Control let trampolineHolder = ctxt.trampolineHolder - member __.ContinueImmediate res = + member _.ContinueImmediate res = let action () = ctxt.cont res let inline executeImmediately () = trampolineHolder.ExecuteWithTrampoline action let currentSyncCtxt = SynchronizationContext.Current match syncCtxt, currentSyncCtxt with | null, null -> executeImmediately () - // See bug 370350; this logic is incorrect from the perspective of how SynchronizationContext is meant to work, - // but the logic works for mainline scenarios (WinForms/WPF/ASP.NET) and we won't change it again. + // This logic was added in F# 2.0 though is incorrect from the perspective of + // how SynchronizationContext is meant to work. However the logic works for + // mainline scenarios (WinForms/WPF) and for compatibility reasons we won't change it. | _ when Object.Equals(syncCtxt, currentSyncCtxt) && thread.Equals Thread.CurrentThread -> executeImmediately () | _ -> trampolineHolder.PostOrQueueWithTrampoline syncCtxt action - member __.ContinueWithPostOrQueue res = + member _.PostOrQueueWithTrampoline res = trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> ctxt.cont res) /// A utility type to provide a synchronization point between an asynchronous computation @@ -691,7 +872,7 @@ namespace Microsoft.FSharp.Control let mutable disposed = false // All writers of result are protected by lock on syncRoot. - let syncRoot = new Object() + let syncRoot = obj() member x.GetWaitHandle() = lock syncRoot (fun () -> @@ -755,9 +936,9 @@ namespace Microsoft.FSharp.Control if reuseThread then cont.ContinueImmediate res else - cont.ContinueWithPostOrQueue res + cont.PostOrQueueWithTrampoline res | otherwise -> - otherwise |> List.iter (fun cont -> cont.ContinueWithPostOrQueue res |> unfake) |> fake + otherwise |> List.iter (fun cont -> cont.PostOrQueueWithTrampoline res |> unfake) |> fake member x.ResultAvailable = result.IsSome @@ -812,7 +993,7 @@ namespace Microsoft.FSharp.Control /// Create an instance of an arbitrary delegate type delegating to the given F# function type FuncDelegate<'T>(f) = - member __.Invoke(sender:obj, a:'T) : unit = ignore sender; f a + member _.Invoke(sender:obj, a:'T) : unit = ignore sender; f a static member Create<'Delegate when 'Delegate :> Delegate>(f) = let obj = FuncDelegate<'T>(f) let invokeMeth = (typeof>).GetMethod("Invoke", BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance) @@ -820,14 +1001,14 @@ namespace Microsoft.FSharp.Control [] let QueueAsync cancellationToken cont econt ccont computation = - let trampolineHolder = new TrampolineHolder() + let trampolineHolder = TrampolineHolder() trampolineHolder.QueueWorkItemWithTrampoline (fun () -> let ctxt = AsyncActivation.Create cancellationToken trampolineHolder cont econt ccont computation.Invoke ctxt) /// Run the asynchronous workflow and wait for its result. [] - let RunSynchronouslyInAnotherThread (token:CancellationToken, computation, timeout) = + let QueueAsyncAndWaitForResultSynchronously (token:CancellationToken) computation timeout = let token, innerCTS = // If timeout is provided, we govern the async by our own CTS, to cancel // when execution times out. Otherwise, the user-supplied token governs the async. @@ -839,12 +1020,12 @@ namespace Microsoft.FSharp.Control use resultCell = new ResultCell>() QueueAsync - token - (fun res -> resultCell.RegisterResult(AsyncResult.Ok res, reuseThread=true)) - (fun edi -> resultCell.RegisterResult(AsyncResult.Error edi, reuseThread=true)) - (fun exn -> resultCell.RegisterResult(AsyncResult.Canceled exn, reuseThread=true)) - computation - |> unfake + token + (fun res -> resultCell.RegisterResult(AsyncResult.Ok res, reuseThread=true)) + (fun edi -> resultCell.RegisterResult(AsyncResult.Error edi, reuseThread=true)) + (fun exn -> resultCell.RegisterResult(AsyncResult.Canceled exn, reuseThread=true)) + computation + |> unfake let res = resultCell.TryWaitForResultSynchronously(?timeout = timeout) match res with @@ -863,9 +1044,9 @@ namespace Microsoft.FSharp.Control res.Commit() [] - let RunSynchronouslyInCurrentThread (cancellationToken:CancellationToken, computation) = + let RunImmediate (cancellationToken:CancellationToken) computation = use resultCell = new ResultCell>() - let trampolineHolder = new TrampolineHolder() + let trampolineHolder = TrampolineHolder() trampolineHolder.ExecuteWithTrampoline (fun () -> let ctxt = @@ -883,21 +1064,10 @@ namespace Microsoft.FSharp.Control [] let RunSynchronously cancellationToken (computation: Async<'T>) timeout = - // Reuse the current ThreadPool thread if possible. Unfortunately - // Thread.IsThreadPoolThread isn't available on all profiles so - // we approximate it by testing synchronization context for null. - match SynchronizationContext.Current, timeout with - | null, None -> RunSynchronouslyInCurrentThread (cancellationToken, computation) - // When the timeout is given we need a dedicated thread - // which cancels the computation. - // Performing the cancellation in the ThreadPool eg. by using - // Timer from System.Threading or CancellationTokenSource.CancelAfter - // (which internally uses Timer) won't work properly - // when the ThreadPool is busy. - // - // And so when the timeout is given we always use the current thread - // for the cancellation and run the computation in another thread. - | _ -> RunSynchronouslyInAnotherThread (cancellationToken, computation, timeout) + // Reuse the current ThreadPool thread if possible. + match Thread.CurrentThread.IsThreadPoolThread, timeout with + | true, None -> RunImmediate cancellationToken computation + | _ -> QueueAsyncAndWaitForResultSynchronously cancellationToken computation timeout [] let Start cancellationToken (computation:Async) = @@ -911,7 +1081,7 @@ namespace Microsoft.FSharp.Control [] let StartWithContinuations cancellationToken (computation:Async<'T>) cont econt ccont = - let trampolineHolder = new TrampolineHolder() + let trampolineHolder = TrampolineHolder() trampolineHolder.ExecuteWithTrampoline (fun () -> let ctxt = AsyncActivation.Create cancellationToken trampolineHolder (cont >> fake) (econt >> fake) (ccont >> fake) computation.Invoke ctxt) @@ -920,7 +1090,7 @@ namespace Microsoft.FSharp.Control [] let StartAsTask cancellationToken (computation:Async<'T>) taskCreationOptions = let taskCreationOptions = defaultArg taskCreationOptions TaskCreationOptions.None - let tcs = new TaskCompletionSource<_>(taskCreationOptions) + let tcs = TaskCompletionSource<_>(taskCreationOptions) // The contract: // a) cancellation signal should always propagate to the computation @@ -935,44 +1105,92 @@ namespace Microsoft.FSharp.Control |> unfake task - // Helper to attach continuation to the given task. + // Call the appropriate continuation on completion of a task [] - let taskContinueWith (task: Task<'T>) (ctxt: AsyncActivation<'T>) useCcontForTaskCancellation = - - let continuation (completedTask: Task<_>) : unit = - ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> - if completedTask.IsCanceled then - if useCcontForTaskCancellation then - ctxt.OnCancellation () - else - let edi = ExceptionDispatchInfo.Capture(TaskCanceledException completedTask) - ctxt.CallExceptionContinuation edi - elif completedTask.IsFaulted then - let edi = ExceptionDispatchInfo.RestoreOrCapture completedTask.Exception - ctxt.CallExceptionContinuation edi - else - ctxt.cont completedTask.Result) |> unfake - - task.ContinueWith(Action>(continuation)) |> ignore |> fake + let OnTaskCompleted (completedTask: Task<'T>) (ctxt: AsyncActivation<'T>) = + assert completedTask.IsCompleted + if completedTask.IsCanceled then + let edi = ExceptionDispatchInfo.Capture(TaskCanceledException completedTask) + ctxt.econt edi + elif completedTask.IsFaulted then + let edi = ExceptionDispatchInfo.RestoreOrCapture completedTask.Exception + ctxt.econt edi + else + ctxt.cont completedTask.Result + // Call the appropriate continuation on completion of a task. A cancelled task + // calls the exception continuation with TaskCanceledException, since it may not represent cancellation of + // the overall async (they may be governed by different cancellation tokens, or + // the task may not have a cancellation token at all). [] - let taskContinueWithUnit (task: Task) (ctxt: AsyncActivation) useCcontForTaskCancellation = + let OnUnitTaskCompleted (completedTask: Task) (ctxt: AsyncActivation) = + assert completedTask.IsCompleted + if completedTask.IsCanceled then + let edi = ExceptionDispatchInfo.Capture(TaskCanceledException(completedTask)) + ctxt.econt edi + elif completedTask.IsFaulted then + let edi = ExceptionDispatchInfo.RestoreOrCapture completedTask.Exception + ctxt.econt edi + else + ctxt.cont () - let continuation (completedTask: Task) : unit = + // Helper to attach continuation to the given task, which is assumed not to be completed. + // When the task completes the continuation will be run synchronously on the thread + // completing the task. This will install a new trampoline on that thread and continue the + // execution of the async there. + [] + let AttachContinuationToTask (task: Task<'T>) (ctxt: AsyncActivation<'T>) = + task.ContinueWith(Action>(fun completedTask -> ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> - if completedTask.IsCanceled then - if useCcontForTaskCancellation then - ctxt.OnCancellation () - else - let edi = ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask)) - ctxt.CallExceptionContinuation edi - elif completedTask.IsFaulted then - let edi = ExceptionDispatchInfo.RestoreOrCapture completedTask.Exception - ctxt.CallExceptionContinuation edi - else - ctxt.cont ()) |> unfake - - task.ContinueWith(Action(continuation)) |> ignore |> fake + OnTaskCompleted completedTask ctxt) + |> unfake), TaskContinuationOptions.ExecuteSynchronously) + |> ignore + |> fake + + // Helper to attach continuation to the given task, which is assumed not to be completed + // When the task completes the continuation will be run synchronously on the thread + // completing the task. This will install a new trampoline on that thread and continue the + // execution of the async there. + [] + let AttachContinuationToUnitTask (task: Task) (ctxt: AsyncActivation) = + task.ContinueWith(Action(fun completedTask -> + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> + OnUnitTaskCompleted completedTask ctxt) + |> unfake), TaskContinuationOptions.ExecuteSynchronously) + |> ignore + |> fake + + /// Removes a registration places on a cancellation token + let DisposeCancellationRegistration (registration: byref) = + match registration with + | Some r -> + registration <- None + r.Dispose() + | None -> () + + /// Cleans up a Timer, helper for Async.Sleep + let DisposeTimer (timer: byref) = + match timer with + | None -> () + | Some t -> + timer <- None + t.Dispose() + + /// Unregisters a RegisteredWaitHandle, helper for AwaitWaitHandle + let UnregisterWaitHandle (rwh: byref) = + match rwh with + | None -> () + | Some r -> + r.Unregister null |> ignore + rwh <- None + + /// Unregisters a delegate handler, helper for AwaitEvent + let RemoveHandler (event: IEvent<_, _>) (del: byref<'Delegate option>) = + match del with + | Some d -> + del <- None + event.RemoveHandler d + | None -> () [] type AsyncIAsyncResult<'T>(callback: System.AsyncCallback, state:obj) = @@ -1018,10 +1236,10 @@ namespace Microsoft.FSharp.Control completedSynchronously <- false interface System.IAsyncResult with - member x.IsCompleted = result.ResultAvailable - member x.CompletedSynchronously = completedSynchronously - member x.AsyncWaitHandle = result.GetWaitHandle() - member x.AsyncState = state + member _.IsCompleted = result.ResultAvailable + member _.CompletedSynchronously = completedSynchronously + member _.AsyncWaitHandle = result.GetWaitHandle() + member _.AsyncState = state interface System.IDisposable with member x.Dispose() = x.Close() @@ -1029,9 +1247,9 @@ namespace Microsoft.FSharp.Control module AsBeginEndHelpers = let beginAction (computation, callback, state) = let aiar = new AsyncIAsyncResult<'T>(callback, state) - let cont v = aiar.SetResult (AsyncResult.Ok v) - let econt v = aiar.SetResult (AsyncResult.Error v) - let ccont v = aiar.SetResult (AsyncResult.Canceled v) + let cont res = aiar.SetResult (AsyncResult.Ok res) + let econt edi = aiar.SetResult (AsyncResult.Error edi) + let ccont cexn = aiar.SetResult (AsyncResult.Canceled cexn) StartWithContinuations aiar.Token computation cont econt ccont aiar.CheckForNotSynchronous() (aiar :> IAsyncResult) @@ -1059,29 +1277,29 @@ namespace Microsoft.FSharp.Control [] type AsyncBuilder() = - member __.Zero () = unitAsync + member _.Zero () = unitAsync - member __.Delay generator = CreateDelayAsync generator + member _.Delay generator = CreateDelayAsync generator - member inline __.Return value = CreateReturnAsync value + member inline _.Return value = CreateReturnAsync value - member inline __.ReturnFrom (computation:Async<_>) = computation + member inline _.ReturnFrom (computation:Async<_>) = computation - member inline __.Bind (computation, binder) = CreateBindAsync computation binder + member inline _.Bind (computation, binder) = CreateBindAsync computation binder - member __.Using (resource, binder) = CreateUsingAsync resource binder + member _.Using (resource, binder) = CreateUsingAsync resource binder - member __.While (guard, computation) = CreateWhileAsync guard computation + member _.While (guard, computation) = CreateWhileAsync guard computation - member __.For (sequence, body) = CreateForLoopAsync sequence body + member _.For (sequence, body) = CreateForLoopAsync sequence body - member inline __.Combine (computation1, computation2) = CreateSequentialAsync computation1 computation2 + member inline _.Combine (computation1, computation2) = CreateSequentialAsync computation1 computation2 - member inline __.TryFinally (computation, compensation) = CreateTryFinallyAsync compensation computation + member inline _.TryFinally (computation, compensation) = CreateTryFinallyAsync compensation computation - member inline __.TryWith (computation, catchHandler) = CreateTryWithAsync catchHandler computation + member inline _.TryWith (computation, catchHandler) = CreateTryWithAsync catchHandler computation - // member inline __.TryWithFilter (computation, catchHandler) = CreateTryWithFilterAsync catchHandler computation + // member inline _.TryWithFilter (computation, catchHandler) = CreateTryWithFilterAsync catchHandler computation [] module AsyncBuilderImpl = @@ -1095,47 +1313,40 @@ namespace Microsoft.FSharp.Control static member CancelCheck () = unitAsync static member FromContinuations (callback: ('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) : Async<'T> = - MakeAsync (fun ctxt -> - if ctxt.IsCancellationRequested then - ctxt.OnCancellation () - else - let mutable underCurrentThreadStack = true - let mutable contToTailCall = None - let thread = Thread.CurrentThread - let latch = Latch() - let once cont x = - if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) - if Thread.CurrentThread.Equals thread && underCurrentThreadStack then - contToTailCall <- Some(fun () -> cont x) - else if Trampoline.ThisThreadHasTrampoline then - let syncCtxt = SynchronizationContext.Current - ctxt.trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> cont x) |> unfake - else - ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont x ) |> unfake - try - callback (once ctxt.cont, (fun exn -> once ctxt.econt (ExceptionDispatchInfo.RestoreOrCapture exn)), once ctxt.ccont) - with exn -> - if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) - let edi = ExceptionDispatchInfo.RestoreOrCapture exn - ctxt.econt edi |> unfake + MakeAsyncWithCancelCheck (fun ctxt -> + let mutable underCurrentThreadStack = true + let mutable contToTailCall = None + let thread = Thread.CurrentThread + let latch = Latch() + let once cont x = + if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) + if Thread.CurrentThread.Equals thread && underCurrentThreadStack then + contToTailCall <- Some(fun () -> cont x) + elif Trampoline.ThisThreadHasTrampoline then + let syncCtxt = SynchronizationContext.Current + ctxt.trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> cont x) |> unfake + else + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont x ) |> unfake + try + callback (once ctxt.cont, (fun exn -> once ctxt.econt (ExceptionDispatchInfo.RestoreOrCapture exn)), once ctxt.ccont) + with exn -> + if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) + let edi = ExceptionDispatchInfo.RestoreOrCapture exn + ctxt.econt edi |> unfake - underCurrentThreadStack <- false + underCurrentThreadStack <- false - match contToTailCall with - | Some k -> k() - | _ -> fake()) + match contToTailCall with + | Some k -> k() + | _ -> fake()) static member DefaultCancellationToken = defaultCancellationTokenSource.Token static member CancelDefaultToken() = - let cts = defaultCancellationTokenSource - // set new CancellationTokenSource before calling Cancel - otherwise if Cancel throws token will stay unchanged defaultCancellationTokenSource <- new CancellationTokenSource() - cts.Cancel() - // we do not dispose the old default CTS - let GC collect it static member Catch (computation: Async<'T>) = @@ -1162,46 +1373,46 @@ namespace Microsoft.FSharp.Control AsyncPrimitives.StartAsTask cancellationToken computation taskCreationOptions static member StartChildAsTask (computation, ?taskCreationOptions) = - async { let! cancellationToken = cancellationTokenAsync - return AsyncPrimitives.StartAsTask cancellationToken computation taskCreationOptions } + async { + let! cancellationToken = cancellationTokenAsync + return AsyncPrimitives.StartAsTask cancellationToken computation taskCreationOptions + } - static member Parallel (computations: seq>) = Async.Parallel(computations, ?maxDegreeOfParallelism=None) + static member Parallel (computations: seq>) = + Async.Parallel(computations, ?maxDegreeOfParallelism=None) static member Parallel (computations: seq>, ?maxDegreeOfParallelism: int) = match maxDegreeOfParallelism with | Some x when x < 1 -> raise(System.ArgumentException(String.Format(SR.GetString(SR.maxDegreeOfParallelismNotPositive), x), "maxDegreeOfParallelism")) | _ -> () - MakeAsync (fun ctxt -> - let tasks, result = + MakeAsyncWithCancelCheck (fun ctxt -> + // manually protect eval of seq + let result = try - Seq.toArray computations, None // manually protect eval of seq + Choice1Of2 (Seq.toArray computations) with exn -> - let edi = ExceptionDispatchInfo.RestoreOrCapture exn - null, Some (ctxt.CallExceptionContinuation edi) + Choice2Of2 (ExceptionDispatchInfo.RestoreOrCapture exn) match result with - | Some r -> r - | None -> - if tasks.Length = 0 then - // must not be in a 'protect' if we call cont explicitly; if cont throws, it should unwind the stack, preserving Dev10 behavior - ctxt.cont [| |] - else - ProtectedCode ctxt (fun ctxt -> - let ctxtWithSync = DelimitSyncContext ctxt // manually resync - let mutable count = tasks.Length + | Choice2Of2 edi -> ctxt.econt edi + | Choice1Of2 [| |] -> ctxt.cont [| |] + | Choice1Of2 computations -> + ctxt.ProtectCode (fun () -> + let ctxt = DelimitSyncContext ctxt // manually resync + let mutable count = computations.Length let mutable firstExn = None - let results = Array.zeroCreate tasks.Length + let results = Array.zeroCreate computations.Length // Attempt to cancel the individual operations if an exception happens on any of the other threads - let innerCTS = new LinkedSubSource(ctxtWithSync.token) + let innerCTS = new LinkedSubSource(ctxt.token) let finishTask remaining = if (remaining = 0) then innerCTS.Dispose() match firstExn with - | None -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont results) - | Some (Choice1Of2 exn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) - | Some (Choice2Of2 cexn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont cexn) + | None -> ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.cont results) + | Some (Choice1Of2 exn) -> ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.econt exn) + | Some (Choice2Of2 cexn) -> ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.ccont cexn) else fake() @@ -1231,13 +1442,14 @@ namespace Microsoft.FSharp.Control let maxDegreeOfParallelism = match maxDegreeOfParallelism with | None -> None - | Some maxDegreeOfParallelism -> if maxDegreeOfParallelism >= tasks.Length then None else Some maxDegreeOfParallelism + | Some x when x >= computations.Length -> None + | Some _ as x -> x // Simple case (no maxDegreeOfParallelism) just queue all the work, if we have maxDegreeOfParallelism set we start that many workers // which will make progress on the actual computations match maxDegreeOfParallelism with | None -> - tasks |> Array.iteri (fun i p -> + computations |> Array.iteri (fun i p -> QueueAsync innerCTS.Token // on success, record the result @@ -1251,11 +1463,11 @@ namespace Microsoft.FSharp.Control | Some maxDegreeOfParallelism -> let mutable i = -1 let rec worker (trampolineHolder : TrampolineHolder) = - if i < tasks.Length then + if i < computations.Length then let j = Interlocked.Increment &i - if j < tasks.Length then + if j < computations.Length then if innerCTS.Token.IsCancellationRequested then - let cexn = new OperationCanceledException (innerCTS.Token) + let cexn = OperationCanceledException (innerCTS.Token) recordFailure (Choice2Of2 cexn) |> unfake worker trampolineHolder |> unfake else @@ -1266,47 +1478,51 @@ namespace Microsoft.FSharp.Control (fun res -> recordSuccess j res |> unfake; worker trampolineHolder) (fun edi -> recordFailure (Choice1Of2 edi) |> unfake; worker trampolineHolder) (fun cexn -> recordFailure (Choice2Of2 cexn) |> unfake; worker trampolineHolder) - tasks.[j].Invoke taskCtxt |> unfake + computations.[j].Invoke taskCtxt |> unfake fake() for x = 1 to maxDegreeOfParallelism do - let trampolineHolder = new TrampolineHolder() + let trampolineHolder = TrampolineHolder() trampolineHolder.QueueWorkItemWithTrampoline (fun () -> worker trampolineHolder) |> unfake fake())) - static member Sequential (computations: seq>) = Async.Parallel(computations, maxDegreeOfParallelism=1) + static member Sequential (computations: seq>) = + Async.Parallel(computations, maxDegreeOfParallelism=1) static member Choice(computations: Async<'T option> seq) : Async<'T option> = - MakeAsync (fun ctxt -> + MakeAsyncWithCancelCheck (fun ctxt -> + // manually protect eval of seq let result = - try Seq.toArray computations |> Choice1Of2 - with exn -> ExceptionDispatchInfo.RestoreOrCapture exn |> Choice2Of2 + try + Choice1Of2 (Seq.toArray computations) + with exn -> + Choice2Of2 (ExceptionDispatchInfo.RestoreOrCapture exn) match result with - | Choice2Of2 edi -> ctxt.CallExceptionContinuation edi - | Choice1Of2 [||] -> ctxt.cont None + | Choice2Of2 edi -> ctxt.econt edi + | Choice1Of2 [| |] -> ctxt.cont None | Choice1Of2 computations -> - ProtectedCode ctxt (fun ctxt -> - let ctxtWithSync = DelimitSyncContext ctxt + let ctxt = DelimitSyncContext ctxt + ctxt.ProtectCode (fun () -> let mutable count = computations.Length let mutable noneCount = 0 let mutable someOrExnCount = 0 - let innerCts = new LinkedSubSource(ctxtWithSync.token) + let innerCts = new LinkedSubSource(ctxt.token) let scont (result: 'T option) = let result = match result with | Some _ -> if Interlocked.Increment &someOrExnCount = 1 then - innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont result) + innerCts.Cancel(); ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.cont result) else fake() | None -> if Interlocked.Increment &noneCount = computations.Length then - innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont None) + innerCts.Cancel(); ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.cont None) else fake() @@ -1318,7 +1534,7 @@ namespace Microsoft.FSharp.Control let econt (exn: ExceptionDispatchInfo) = let result = if Interlocked.Increment &someOrExnCount = 1 then - innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) + innerCts.Cancel(); ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.econt exn) else fake() @@ -1327,10 +1543,10 @@ namespace Microsoft.FSharp.Control result - let ccont (exn: OperationCanceledException) = + let ccont (cexn: OperationCanceledException) = let result = if Interlocked.Increment &someOrExnCount = 1 then - innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont exn) + innerCts.Cancel(); ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.ccont cexn) else fake() @@ -1339,8 +1555,8 @@ namespace Microsoft.FSharp.Control result - for c in computations do - QueueAsync innerCts.Token scont econt ccont c |> unfake + for computation in computations do + QueueAsync innerCts.Token scont econt ccont computation |> unfake fake())) @@ -1354,7 +1570,7 @@ namespace Microsoft.FSharp.Control static member StartImmediateAsTask (computation: Async<'T>, ?cancellationToken ) : Task<'T>= let cancellationToken = defaultArg cancellationToken defaultCancellationTokenSource.Token - let ts = new TaskCompletionSource<'T>() + let ts = TaskCompletionSource<'T>() let task = ts.Task Async.StartWithContinuations( computation, @@ -1368,121 +1584,121 @@ namespace Microsoft.FSharp.Control let cancellationToken = defaultArg cancellationToken defaultCancellationTokenSource.Token AsyncPrimitives.StartWithContinuations cancellationToken computation id (fun edi -> edi.ThrowAny()) ignore - static member Sleep millisecondsDueTime : Async = - CreateDelimitedUserCodeAsync (fun ctxt -> - let mutable timer = None: Timer option - let cont = ctxt.cont - let ccont = ctxt.ccont - let latch = new Latch() - let registration = - ctxt.token.Register( - (fun _ -> - if latch.Enter() then - match timer with - | None -> () - | Some t -> t.Dispose() - ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ccont(new OperationCanceledException(ctxt.token))) |> unfake), - null) + static member Sleep (millisecondsDueTime: int64) : Async = + MakeAsyncWithCancelCheck (fun ctxt -> + let ctxt = DelimitSyncContext ctxt let mutable edi = null + let latch = Latch() + let mutable timer: Timer option = None + let mutable registration: CancellationTokenRegistration option = None + registration <- + ctxt.token.Register(Action(fun () -> + if latch.Enter() then + // Make sure we're not cancelled again + DisposeCancellationRegistration ®istration + DisposeTimer &timer + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.ccont(OperationCanceledException(ctxt.token))) |> unfake) + ) |> Some try - timer <- new Timer((fun _ -> + timer <- new Timer(TimerCallback(fun _ -> if latch.Enter() then - // NOTE: If the CTS for the token would have been disposed, disposal of the registration would throw - // However, our contract is that until async computation ceases execution (and invokes ccont) - // the CTS will not be disposed. Execution of savedCCont is guarded by latch, so we are safe unless - // user violates the contract. - registration.Dispose() - // Try to Dispose of the Timer. - // Note: there is a race here: the Timer time very occasionally - // calls the callback _before_ the timer object has been recorded anywhere. This makes it difficult to dispose the - // timer in this situation. In this case we just let the timer be collected by finalization. - match timer with - | None -> () - | Some t -> t.Dispose() + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + DisposeTimer &timer // Now we're done, so call the continuation - ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont()) |> unfake), - null, dueTime=millisecondsDueTime, period = -1) |> Some + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.cont()) |> unfake), + null, dueTime=millisecondsDueTime, period = -1L) |> Some with exn -> if latch.Enter() then - // post exception to econt only if we successfully enter the latch (no other continuations were called) + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + // Prepare to call exception continuation edi <- ExceptionDispatchInfo.RestoreOrCapture exn + // Call exception continuation if necessary match edi with | null -> fake() | _ -> ctxt.econt edi) + static member Sleep (millisecondsDueTime: int32) : Async = + Async.Sleep (millisecondsDueTime |> int64) + + static member Sleep (dueTime: TimeSpan) = + if dueTime < TimeSpan.Zero then + raise (ArgumentOutOfRangeException("dueTime")) + else + Async.Sleep (dueTime.TotalMilliseconds |> Checked.int64) + /// Wait for a wait handle. Both timeout and cancellation are supported static member AwaitWaitHandle(waitHandle: WaitHandle, ?millisecondsTimeout:int) = - let millisecondsTimeout = defaultArg millisecondsTimeout Threading.Timeout.Infinite - if millisecondsTimeout = 0 then - async.Delay(fun () -> + MakeAsyncWithCancelCheck (fun ctxt -> + let millisecondsTimeout = defaultArg millisecondsTimeout Threading.Timeout.Infinite + if millisecondsTimeout = 0 then let ok = waitHandle.WaitOne(0, exitContext=false) - async.Return ok) - else - CreateDelimitedUserCodeAsync(fun ctxt -> - let aux = ctxt.aux - let rwh = ref (None: RegisteredWaitHandle option) + ctxt.cont ok + else + let ctxt = DelimitSyncContext ctxt + let mutable edi = null let latch = Latch() - let rec cancelHandler = - Action(fun _ -> + let mutable rwh: RegisteredWaitHandle option = None + let mutable registration: CancellationTokenRegistration option = None + registration <- + ctxt.token.Register(Action(fun () -> if latch.Enter() then - // if we got here - then we need to unregister RegisteredWaitHandle + trigger cancellation - // entrance to TP callback is protected by latch - so savedCont will never be called - lock rwh (fun () -> - match !rwh with - | None -> () - | Some rwh -> rwh.Unregister null |> ignore) - Async.Start (async { do (ctxt.ccont (OperationCanceledException(aux.token)) |> unfake) })) + // Make sure we're not cancelled again + DisposeCancellationRegistration ®istration + + UnregisterWaitHandle &rwh - and registration: CancellationTokenRegistration = aux.token.Register(cancelHandler, null) + // Call the cancellation continuation + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.ccont(OperationCanceledException(ctxt.token))) |> unfake)) + |> Some - let savedCont = ctxt.cont try - lock rwh (fun () -> - rwh := Some(ThreadPool.RegisterWaitForSingleObject - (waitObject=waitHandle, - callBack=WaitOrTimerCallback(fun _ timeOut -> - if latch.Enter() then - lock rwh (fun () -> rwh.Value.Value.Unregister null |> ignore) - rwh := None - registration.Dispose() - ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCont (not timeOut)) |> unfake), - state=null, - millisecondsTimeOutInterval=millisecondsTimeout, - executeOnlyOnce=true)) - fake()) - with _ -> + rwh <- ThreadPool.RegisterWaitForSingleObject(waitObject=waitHandle, + callBack=WaitOrTimerCallback(fun _ timeOut -> + if latch.Enter() then + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + UnregisterWaitHandle &rwh + // Call the success continuation + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxt.cont (not timeOut)) |> unfake), + state=null, + millisecondsTimeOutInterval=millisecondsTimeout, + executeOnlyOnce=true) + |> Some + with exn -> if latch.Enter() then - registration.Dispose() - reraise() // reraise exception only if we successfully enter the latch (no other continuations were called) - else - fake() - ) - - static member AwaitIAsyncResult(iar: IAsyncResult, ?millisecondsTimeout): Async = - async { if iar.CompletedSynchronously then - return true - else - return! Async.AwaitWaitHandle(iar.AsyncWaitHandle, ?millisecondsTimeout=millisecondsTimeout) } + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + // Prepare to call exception continuation + edi <- ExceptionDispatchInfo.RestoreOrCapture exn + // Call exception continuation if necessary + match edi with + | null -> + fake() + | _ -> + // Call the exception continuation + ctxt.econt edi) - /// Bind the result of a result cell, calling the appropriate continuation. - static member BindResult (result: AsyncResult<'T>) : Async<'T> = - MakeAsync (fun ctxt -> - (match result with - | Ok v -> ctxt.cont v - | Error exn -> ctxt.CallExceptionContinuation exn - | Canceled exn -> ctxt.ccont exn) ) + static member AwaitIAsyncResult(iar: IAsyncResult, ?millisecondsTimeout) = + async { + if iar.CompletedSynchronously then + return true + else + return! Async.AwaitWaitHandle(iar.AsyncWaitHandle, ?millisecondsTimeout=millisecondsTimeout) + } /// Await and use the result of a result cell. The resulting async doesn't support cancellation /// or timeout directly, rather the underlying computation must fill the result if cancellation /// or timeout occurs. - static member AwaitAndBindResult_NoDirectCancelOrTimeout(resultCell: ResultCell>) : Async<'T> = + static member AwaitAndBindResult_NoDirectCancelOrTimeout(resultCell: ResultCell>) = async { let! result = resultCell.AwaitResult_NoDirectCancelOrTimeout - return! Async.BindResult result + return! CreateAsyncResultAsync result } /// Await the result of a result cell belonging to a child computation. The resulting async supports timeout and if @@ -1500,81 +1716,80 @@ namespace Microsoft.FSharp.Control else return raise (System.TimeoutException()) } | _ -> - async { try - if resultCell.ResultAvailable then - let res = resultCell.GrabResult() - return res.Commit() - else - let! ok = Async.AwaitWaitHandle (resultCell.GetWaitHandle(), ?millisecondsTimeout=millisecondsTimeout) - if ok then + async { + try + if resultCell.ResultAvailable then + let res = resultCell.GrabResult() + return res.Commit() + else + let! ok = Async.AwaitWaitHandle (resultCell.GetWaitHandle(), ?millisecondsTimeout=millisecondsTimeout) + if ok then let res = resultCell.GrabResult() return res.Commit() - else // timed out + else // timed out // issue cancellation signal innerCTS.Cancel() // wait for computation to quiesce let! _ = Async.AwaitWaitHandle (resultCell.GetWaitHandle()) return raise (System.TimeoutException()) - finally - resultCell.Close() } + finally + resultCell.Close() + } static member FromBeginEnd(beginAction, endAction, ?cancelAction): Async<'T> = - async { let! cancellationToken = cancellationTokenAsync - let resultCell = new ResultCell<_>() - - let once = Once() + async { + let! ct = cancellationTokenAsync + let resultCell = new ResultCell<_>() - let registration: CancellationTokenRegistration = + let latch = Latch() + let mutable registration: CancellationTokenRegistration option = None + registration <- + ct.Register(Action(fun () -> + if latch.Enter() then + // Make sure we're not cancelled again + DisposeCancellationRegistration ®istration - let onCancel (_:obj) = - // Call the cancellation routine + // Call the cancellation function. Ignore any exceptions from the + // cancellation function. match cancelAction with - | None -> - // Register the result. This may race with a successful result, but - // ResultCell allows a race and throws away whichever comes last. - once.Do(fun () -> - let canceledResult = Canceled (OperationCanceledException cancellationToken) - resultCell.RegisterResult(canceledResult, reuseThread=true) |> unfake - ) + | None -> () | Some cancel -> - // If we get an exception from a cooperative cancellation function - // we assume the operation has already completed. try cancel() with _ -> () - cancellationToken.Register(Action(onCancel), null) - - let callback = - new System.AsyncCallback(fun iar -> - if not iar.CompletedSynchronously then - // The callback has been activated, so ensure cancellation is not possible - // beyond this point. - match cancelAction with - | Some _ -> - registration.Dispose() - | None -> - once.Do(fun () -> registration.Dispose()) - - // Run the endAction and collect its result. - let res = - try - Ok(endAction iar) - with exn -> - let edi = ExceptionDispatchInfo.RestoreOrCapture exn - Error edi - - // Register the result. This may race with a cancellation result, but - // ResultCell allows a race and throws away whichever comes last. - resultCell.RegisterResult(res, reuseThread=true) |> unfake) - - let (iar:IAsyncResult) = beginAction (callback, (null:obj)) - if iar.CompletedSynchronously then - registration.Dispose() - return endAction iar - else - // Note: ok to use "NoDirectCancel" here because cancellation has been registered above - // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method - return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell } + // Register the cancellation result. + let canceledResult = Canceled (OperationCanceledException ct) + resultCell.RegisterResult(canceledResult, reuseThread=true) |> unfake)) + |> Some + + let callback = + AsyncCallback(fun iar -> + if not iar.CompletedSynchronously then + if latch.Enter() then + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + + // Run the endAction and collect its result. + let res = + try + Ok(endAction iar) + with exn -> + let edi = ExceptionDispatchInfo.RestoreOrCapture exn + Error edi + + // Register the result. + resultCell.RegisterResult(res, reuseThread=true) |> unfake) + + let (iar:IAsyncResult) = beginAction (callback, (null:obj)) + if iar.CompletedSynchronously then + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration + return endAction iar + else + // Note: ok to use "NoDirectCancel" here because cancellation has been registered above + // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method + return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell + } static member FromBeginEnd(arg, beginAction, endAction, ?cancelAction): Async<'T> = @@ -1597,44 +1812,52 @@ namespace Microsoft.FSharp.Control beginAction, AsBeginEndHelpers.endAction<'T>, AsBeginEndHelpers.cancelAction<'T> static member AwaitEvent(event:IEvent<'Delegate, 'T>, ?cancelAction) : Async<'T> = - async { let! cancellationToken = cancellationTokenAsync - let resultCell = new ResultCell<_>() - // Set up the handlers to listen to events and cancellation - let once = new Once() - let rec registration: CancellationTokenRegistration= - let onCancel _ = - // We've been cancelled. Call the given cancellation routine + async { + let! ct = cancellationTokenAsync + let resultCell = new ResultCell<_>() + // Set up the handlers to listen to events and cancellation + let latch = Latch() + let mutable registration: CancellationTokenRegistration option = None + let mutable del: 'Delegate option = None + registration <- + ct.Register(Action(fun () -> + if latch.Enter() then + // Make sure we're not cancelled again + DisposeCancellationRegistration ®istration + + // Stop listening to events + RemoveHandler event &del + + // Call the given cancellation routine if we've been given one + // Exceptions from a cooperative cancellation are ignored. match cancelAction with - | None -> - // We've been cancelled without a cancel action. Stop listening to events - event.RemoveHandler del - // Register the result. This may race with a successful result, but - // ResultCell allows a race and throws away whichever comes last. - once.Do(fun () -> resultCell.RegisterResult(Canceled (OperationCanceledException cancellationToken), reuseThread=true) |> unfake) + | None -> () | Some cancel -> - // If we get an exception from a cooperative cancellation function - // we assume the operation has already completed. try cancel() with _ -> () - cancellationToken.Register(Action(onCancel), null) + + // Register the cancellation result. + resultCell.RegisterResult(Canceled (OperationCanceledException ct), reuseThread=true) |> unfake + )) |> Some + + let del = + FuncDelegate<'T>.Create<'Delegate>(fun eventArgs -> + if latch.Enter() then + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration - and del = - FuncDelegate<'T>.Create<'Delegate>(fun eventArgs -> // Stop listening to events - event.RemoveHandler del - // The callback has been activated, so ensure cancellation is not possible beyond this point - once.Do(fun () -> registration.Dispose()) - let res = Ok eventArgs - // Register the result. This may race with a cancellation result, but - // ResultCell allows a race and throws away whichever comes last. - resultCell.RegisterResult(res, reuseThread=true) |> unfake) - - // Start listening to events - event.AddHandler del - - // Return the async computation that allows us to await the result - // Note: ok to use "NoDirectCancel" here because cancellation has been registered above - // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method - return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell } + RemoveHandler event &del + + // Register the successful result. + resultCell.RegisterResult(Ok eventArgs, reuseThread=true) |> unfake) + + // Start listening to events + event.AddHandler del + + // Return the async computation that allows us to await the result + // Note: ok to use "NoDirectCancel" here because cancellation has been registered above + // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method + return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell } static member Ignore (computation: Async<'T>) = CreateIgnoreAsync computation @@ -1645,60 +1868,86 @@ namespace Microsoft.FSharp.Control static member StartChild (computation:Async<'T>, ?millisecondsTimeout) = async { let resultCell = new ResultCell<_>() - let! cancellationToken = cancellationTokenAsync + let! ct = cancellationTokenAsync let innerCTS = new CancellationTokenSource() // innerCTS does not require disposal let mutable ctsRef = innerCTS - let reg = cancellationToken.Register( - (fun _ -> - match ctsRef with - | null -> () - | otherwise -> otherwise.Cancel()), - null) + let registration = + ct.Register(Action(fun () -> + match ctsRef with + | null -> () + | otherwise -> otherwise.Cancel())) + do QueueAsync innerCTS.Token // since innerCTS is not ever Disposed, can call reg.Dispose() without a safety Latch - (fun res -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Ok res, reuseThread=true)) - (fun edi -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Error edi, reuseThread=true)) - (fun err -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Canceled err, reuseThread=true)) + (fun res -> ctsRef <- null; registration.Dispose(); resultCell.RegisterResult (Ok res, reuseThread=true)) + (fun edi -> ctsRef <- null; registration.Dispose(); resultCell.RegisterResult (Error edi, reuseThread=true)) + (fun err -> ctsRef <- null; registration.Dispose(); resultCell.RegisterResult (Canceled err, reuseThread=true)) computation |> unfake return Async.AwaitAndBindChildResult(innerCTS, resultCell, millisecondsTimeout) } static member SwitchToContext syncContext = - async { match syncContext with - | null -> - // no synchronization context, just switch to the thread pool - do! Async.SwitchToThreadPool() - | syncCtxt -> - // post the continuation to the synchronization context - return! CreateSwitchToAsync syncCtxt } + async { + match syncContext with + | null -> + // no synchronization context, just switch to the thread pool + do! Async.SwitchToThreadPool() + | syncCtxt -> + // post the continuation to the synchronization context + return! CreateSwitchToAsync syncCtxt + } static member OnCancel interruption = - async { let! cancellationToken = cancellationTokenAsync - // latch protects CancellationTokenRegistration.Dispose from being called twice - let latch = Latch() - let rec handler (_ : obj) = - try - if latch.Enter() then registration.Dispose() - interruption () - with _ -> () - and registration: CancellationTokenRegistration = cancellationToken.Register(Action(handler), null) - return { new System.IDisposable with - member this.Dispose() = - // dispose CancellationTokenRegistration only if cancellation was not requested. - // otherwise - do nothing, disposal will be performed by the handler itself - if not cancellationToken.IsCancellationRequested then - if latch.Enter() then registration.Dispose() } } + async { + let! ct = cancellationTokenAsync + // latch protects cancellation and disposal contention + let latch = Latch() + let mutable registration: CancellationTokenRegistration option = None + registration <- + ct.Register(Action(fun () -> + if latch.Enter() then + // Make sure we're not cancelled again + DisposeCancellationRegistration ®istration + try + interruption () + with _ -> ())) + |> Some + let disposer = + { new System.IDisposable with + member _.Dispose() = + // dispose CancellationTokenRegistration only if cancellation was not requested. + // otherwise - do nothing, disposal will be performed by the handler itself + if not ct.IsCancellationRequested then + if latch.Enter() then + // Ensure cancellation is not possible beyond this point + DisposeCancellationRegistration ®istration } + return disposer + } static member TryCancelled (computation: Async<'T>, compensation) = CreateWhenCancelledAsync compensation computation static member AwaitTask (task:Task<'T>) : Async<'T> = - CreateDelimitedUserCodeAsync (fun ctxt -> taskContinueWith task ctxt false) + MakeAsyncWithCancelCheck (fun ctxt -> + if task.IsCompleted then + // Run synchronously without installing new trampoline + OnTaskCompleted task ctxt + else + // Continue asynchronously, via syncContext if necessary, installing new trampoline + let ctxt = DelimitSyncContext ctxt + ctxt.ProtectCode (fun () -> AttachContinuationToTask task ctxt)) static member AwaitTask (task:Task) : Async = - CreateDelimitedUserCodeAsync (fun ctxt -> taskContinueWithUnit task ctxt false) + MakeAsyncWithCancelCheck (fun ctxt -> + if task.IsCompleted then + // Continue synchronously without installing new trampoline + OnUnitTaskCompleted task ctxt + else + // Continue asynchronously, via syncContext if necessary, installing new trampoline + let ctxt = DelimitSyncContext ctxt + ctxt.ProtectCode (fun () -> AttachContinuationToUnitTask task ctxt)) module CommonExtensions = @@ -1712,14 +1961,16 @@ namespace Microsoft.FSharp.Control [] // give the extension member a 'nice', unmangled compiled name, unique within this module member stream.AsyncRead count = - async { let buffer = Array.zeroCreate count - let mutable i = 0 - while i < count do - let! n = stream.AsyncRead(buffer, i, count - i) - i <- i + n - if n = 0 then - raise(System.IO.EndOfStreamException(SR.GetString(SR.failedReadEnoughBytes))) - return buffer } + async { + let buffer = Array.zeroCreate count + let mutable i = 0 + while i < count do + let! n = stream.AsyncRead(buffer, i, count - i) + i <- i + n + if n = 0 then + raise(System.IO.EndOfStreamException(SR.GetString(SR.failedReadEnoughBytes))) + return buffer + } [] // give the extension member a 'nice', unmangled compiled name, unique within this module member stream.AsyncWrite(buffer:byte[], ?offset:int, ?count:int) = @@ -1740,7 +1991,6 @@ namespace Microsoft.FSharp.Control member x.OnCompleted() = () } module WebExtensions = - open AsyncPrimitives type System.Net.WebRequest with [] // give the extension member a 'nice', unmangled compiled name, unique within this module @@ -1757,7 +2007,7 @@ namespace Microsoft.FSharp.Control | :? System.Net.WebException as webExn when webExn.Status = System.Net.WebExceptionStatus.RequestCanceled && canceled -> - Some (Async.BindResult(AsyncResult.Canceled (OperationCanceledException webExn.Message))) + Some (CreateAsyncResultAsync(AsyncResult.Canceled (OperationCanceledException webExn.Message))) | _ -> None) @@ -1765,13 +2015,13 @@ namespace Microsoft.FSharp.Control member inline private this.Download(event: IEvent<'T, _>, handler: _ -> 'T, start, result) = let downloadAsync = Async.FromContinuations (fun (cont, econt, ccont) -> - let userToken = new obj() + let userToken = obj() let rec delegate' (_: obj) (args: #ComponentModel.AsyncCompletedEventArgs) = // ensure we handle the completed event from correct download call if userToken = args.UserState then event.RemoveHandler handle if args.Cancelled then - ccont (new OperationCanceledException()) + ccont (OperationCanceledException()) elif isNotNull args.Error then econt args.Error else @@ -1784,7 +2034,7 @@ namespace Microsoft.FSharp.Control async { use! _holder = Async.OnCancel(fun _ -> this.CancelAsync()) return! downloadAsync - } + } [] // give the extension member a 'nice', unmangled compiled name, unique within this module member this.AsyncDownloadString (address:Uri) : Async = diff --git a/src/fsharp/FSharp.Core/async.fsi b/src/fsharp/FSharp.Core/async.fsi index fe4da64debd..75869a2e4ba 100644 --- a/src/fsharp/FSharp.Core/async.fsi +++ b/src/fsharp/FSharp.Core/async.fsi @@ -11,24 +11,37 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Control open Microsoft.FSharp.Collections - /// A compositional asynchronous computation, which, when run, will eventually produce a value - /// of type T, or else raises an exception. + /// + /// An asynchronous computation, which, when run, will eventually produce a value of type T, or else raises an exception. + /// /// - /// Asynchronous computations are normally specified using an F# computation expression. + /// + /// This type has no members. Asynchronous computations are normally specified either by using an async expression + /// or the static methods in the type. /// - /// When run, asynchronous computations have two modes: as a work item (executing synchronous - /// code), or as a wait item (waiting for an event or I/O completion). + /// See also F# Language Guide - Async Workflows. + /// /// - /// When run, asynchronous computations can be governed by CancellationToken. This can usually - /// be specified when the async computation is started. The associated CancellationTokenSource - /// may be used to cancel the asynchronous computation. Asynchronous computations built using - /// computation expressions can check the cancellation condition regularly. Synchronous - /// computations within an asynchronous computation do not automatically check this condition. + /// + /// Library functionality for asynchronous programming, events and agents. See also + /// Asynchronous Programming, + /// Events and + /// Lazy Expressions in the + /// F# Language Guide. + /// + /// + /// Async Programming [] type Async<'T> - /// This static class holds members for creating and manipulating asynchronous computations. + /// Holds static members for creating and manipulating asynchronous computations. + /// + /// + /// See also F# Language Guide - Async Workflows. + /// + /// + /// Async Programming [] [] @@ -43,49 +56,81 @@ namespace Microsoft.FSharp.Control /// /// The timeout parameter is given in milliseconds. A value of -1 is equivalent to /// System.Threading.Timeout.Infinite. + /// /// The computation to run. /// The amount of time in milliseconds to wait for the result of the - /// computation before raising a System.TimeoutException. If no value is provided - /// for timeout then a default of -1 is used to correspond to System.Threading.Timeout.Infinite. + /// computation before raising a . If no value is provided + /// for timeout then a default of -1 is used to correspond to . /// If a cancellable cancellationToken is provided, timeout parameter will be ignored /// The cancellation token to be associated with the computation. /// If one is not supplied, the default cancellation token is used. + /// /// The result of the computation. + /// + /// Starting Async Computations + /// + /// static member RunSynchronously : computation:Async<'T> * ?timeout : int * ?cancellationToken:CancellationToken-> 'T /// Starts the asynchronous computation in the thread pool. Do not await its result. /// /// If no cancellation token is provided then the default cancellation token is used. + /// /// The computation to run asynchronously. /// The cancellation token to be associated with the computation. /// If one is not supplied, the default cancellation token is used. + /// + /// Starting Async Computations + /// + /// static member Start : computation:Async * ?cancellationToken:CancellationToken -> unit /// Executes a computation in the thread pool. + /// /// If no cancellation token is provided then the default cancellation token is used. - /// A System.Threading.Tasks.Task that will be completed + /// + /// A that will be completed /// in the corresponding state once the computation terminates (produces the result, throws exception or gets canceled) - /// + /// + /// Starting Async Computations + /// + /// static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T> - /// Creates an asynchronous computation which starts the given computation as a System.Threading.Tasks.Task + /// Creates an asynchronous computation which starts the given computation as a + /// + /// Starting Async Computations + /// + /// static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async> /// Creates an asynchronous computation that executes computation. /// If this computation completes successfully then return Choice1Of2 with the returned /// value. If this computation raises an exception before it completes then return Choice2Of2 /// with the raised exception. + /// /// The input computation that returns the type T. + /// /// A computation that returns a choice of type T or exception. + /// + /// Cancellation and Exceptions + /// + /// static member Catch : computation:Async<'T> -> Async> /// Creates an asynchronous computation that executes computation. /// If this computation is cancelled before it completes then the computation generated by /// running compensation is executed. + /// /// The input asynchronous computation. /// The function to be run if the computation is cancelled. + /// /// An asynchronous computation that runs the compensation if the input computation /// is cancelled. + /// + /// Cancellation and Exceptions + /// + /// static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T> /// Generates a scoped, cooperative cancellation handler for use within an asynchronous workflow. @@ -97,28 +142,49 @@ namespace Microsoft.FSharp.Control /// interruption is executed on the thread that is performing the cancellation. This can /// be used to arrange for a computation to be asynchronously notified that a cancellation /// has occurred, e.g. by setting a flag, or deregistering a pending I/O action. + /// /// The function that is executed on the thread performing the /// cancellation. + /// /// An asynchronous computation that triggers the interruption if it is cancelled /// before being disposed. + /// + /// Cancellation and Exceptions + /// + /// static member OnCancel : interruption: (unit -> unit) -> Async /// Creates an asynchronous computation that returns the CancellationToken governing the execution /// of the computation. + /// /// In async { let! token = Async.CancellationToken ...} token can be used to initiate other /// asynchronous operations that will cancel cooperatively with this workflow. + /// /// An asynchronous computation capable of retrieving the CancellationToken from a computation /// expression. + /// + /// Cancellation and Exceptions + /// + /// static member CancellationToken : Async /// Raises the cancellation condition for the most recent set of asynchronous computations started /// without any specific CancellationToken. Replaces the global CancellationTokenSource with a new /// global token source for any asynchronous computations created after this point without any /// specific CancellationToken. + /// + /// Cancellation and Exceptions + /// + /// static member CancelDefaultToken : unit -> unit /// Gets the default cancellation token for executing asynchronous computations. + /// /// The default CancellationToken. + /// + /// Cancellation and Exceptions + /// + /// static member DefaultCancellationToken : CancellationToken //---------- Parallelism @@ -128,7 +194,7 @@ namespace Microsoft.FSharp.Control /// /// This method should normally be used as the immediate /// right-hand-side of a let! binding in an F# asynchronous workflow, that is, - /// + /// /// async { ... /// let! completor1 = childComputation1 |> Async.StartChild /// let! completor2 = childComputation2 |> Async.StartChild @@ -136,14 +202,21 @@ namespace Microsoft.FSharp.Control /// let! result1 = completor1 /// let! result2 = completor2 /// ... } + /// /// /// When used in this way, each use of StartChild starts an instance of childComputation /// and returns a completor object representing a computation to wait for the completion of the operation. /// When executed, the completor awaits the completion of childComputation. + /// /// The child computation. /// The timeout value in milliseconds. If one is not provided - /// then the default value of -1 corresponding to System.Threading.Timeout.Infinite. + /// then the default value of -1 corresponding to . + /// /// A new computation that waits for the input computation to finish. + /// + /// Cancellation and Exceptions + /// + /// static member StartChild : computation:Async<'T> * ?millisecondsTimeout : int -> Async> /// Creates an asynchronous computation that executes all the given asynchronous computations, @@ -157,8 +230,14 @@ namespace Microsoft.FSharp.Control /// The overall computation will respond to cancellation while executing the child computations. /// If cancelled, the computation will cancel any remaining child computations but will still wait /// for the other child computations to complete. + /// /// A sequence of distinct computations to be parallelized. + /// /// A computation that returns an array of values from the sequence of input computations. + /// + /// Composing Async Computations + /// + /// static member Parallel : computations:seq> -> Async<'T[]> /// Creates an asynchronous computation that executes all the given asynchronous computations, @@ -172,8 +251,15 @@ namespace Microsoft.FSharp.Control /// The overall computation will respond to cancellation while executing the child computations. /// If cancelled, the computation will cancel any remaining child computations but will still wait /// for the other child computations to complete. + /// /// A sequence of distinct computations to be parallelized. + /// The maximum degree of parallelism in the parallel execution. + /// /// A computation that returns an array of values from the sequence of input computations. + /// + /// Composing Async Computations + /// + /// static member Parallel : computations:seq> * ?maxDegreeOfParallelism : int -> Async<'T[]> /// Creates an asynchronous computation that executes all the given asynchronous computations sequentially. @@ -186,8 +272,14 @@ namespace Microsoft.FSharp.Control /// The overall computation will respond to cancellation while executing the child computations. /// If cancelled, the computation will cancel any remaining child computations but will still wait /// for the other child computations to complete. + /// /// A sequence of distinct computations to be run in sequence. + /// /// A computation that returns an array of values from the sequence of input computations. + /// + /// Composing Async Computations + /// + /// static member Sequential : computations:seq> -> Async<'T[]> /// Creates an asynchronous computation that executes all given asynchronous computations in parallel, @@ -201,35 +293,63 @@ namespace Microsoft.FSharp.Control /// The overall computation will respond to cancellation while executing the child computations. /// If cancelled, the computation will cancel any remaining child computations but will still wait /// for the other child computations to complete. + /// /// A sequence of computations to be parallelized. + /// /// A computation that returns the first succeeding computation. + /// + /// Composing Async Computations + /// + /// static member Choice : computations:seq> -> Async<'T option> //---------- Thread Control /// Creates an asynchronous computation that creates a new thread and runs /// its continuation in that thread. + /// /// A computation that will execute on a new thread. + /// + /// Threads and Contexts + /// + /// static member SwitchToNewThread : unit -> Async /// Creates an asynchronous computation that queues a work item that runs /// its continuation. + /// /// A computation that generates a new work item in the thread pool. + /// + /// Threads and Contexts + /// + /// static member SwitchToThreadPool : unit -> Async /// Creates an asynchronous computation that runs /// its continuation using syncContext.Post. If syncContext is null /// then the asynchronous computation is equivalent to SwitchToThreadPool(). + /// /// The synchronization context to accept the posted computation. + /// /// An asynchronous computation that uses the syncContext context to execute. + /// + /// Threads and Contexts + /// + /// static member SwitchToContext : syncContext:System.Threading.SynchronizationContext -> Async /// Creates an asynchronous computation that captures the current /// success, exception and cancellation continuations. The callback must /// eventually call exactly one of the given continuations. + /// /// The function that accepts the current success, exception, and cancellation /// continuations. + /// /// An asynchronous computation that provides the callback with the current continuations. + /// + /// Composing Async Computations + /// + /// static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> /// Creates an asynchronous computation that waits for a single invocation of a CLI @@ -242,93 +362,177 @@ namespace Microsoft.FSharp.Control /// /// If cancelAction is not specified, then cancellation causes the computation /// to cancel immediately. + /// /// The event to handle once. /// An optional function to execute instead of cancelling when a /// cancellation is issued. + /// /// An asynchronous computation that waits for the event to be invoked. + /// + /// Awaiting Results + /// + /// static member AwaitEvent: event:IEvent<'Del,'T> * ?cancelAction : (unit -> unit) -> Async<'T> when 'Del : delegate<'T,unit> and 'Del :> System.Delegate /// Creates an asynchronous computation that will wait on the given WaitHandle. /// /// The computation returns true if the handle indicated a result within the given timeout. + /// /// The WaitHandle that can be signalled. /// The timeout value in milliseconds. If one is not provided - /// then the default value of -1 corresponding to System.Threading.Timeout.Infinite. + /// then the default value of -1 corresponding to . + /// /// An asynchronous computation that waits on the given WaitHandle. + /// + /// Awaiting Results + /// + /// static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout:int -> Async /// Creates an asynchronous computation that will wait on the IAsyncResult. /// /// The computation returns true if the handle indicated a result within the given timeout. + /// /// The IAsyncResult to wait on. /// The timeout value in milliseconds. If one is not provided - /// then the default value of -1 corresponding to System.Threading.Timeout.Infinite. + /// then the default value of -1 corresponding to . + /// /// An asynchronous computation that waits on the given IAsyncResult. + /// + /// Awaiting Results + /// + /// static member AwaitIAsyncResult: iar: System.IAsyncResult * ?millisecondsTimeout:int -> Async - /// Return an asynchronous computation that will wait for the given task to complete and return - /// its result. + /// Return an asynchronous computation that will wait for the given task to complete and return + /// its result. + /// + /// The task to await. + /// + /// If an exception occurs in the asynchronous computation then an exception is re-raised by this + /// function. + /// + /// If the task is cancelled then is raised. Note + /// that the task may be governed by a different cancellation token to the overall async computation + /// where the AwaitTask occurs. In practice you should normally start the task with the + /// cancellation token returned by let! ct = Async.CancellationToken, and catch + /// any at the point where the + /// overall async is started. + /// + /// + /// Awaiting Results + /// + /// static member AwaitTask: task: Task<'T> -> Async<'T> - /// Return an asynchronous computation that will wait for the given task to complete and return - /// its result. + + /// Return an asynchronous computation that will wait for the given task to complete and return + /// its result. + /// + /// The task to await. + /// + /// If an exception occurs in the asynchronous computation then an exception is re-raised by this + /// function. + /// + /// If the task is cancelled then is raised. Note + /// that the task may be governed by a different cancellation token to the overall async computation + /// where the AwaitTask occurs. In practice you should normally start the task with the + /// cancellation token returned by let! ct = Async.CancellationToken, and catch + /// any at the point where the + /// overall async is started. + /// + /// + /// Awaiting Results + /// + /// static member AwaitTask: task: Task -> Async - /// Creates an asynchronous computation that will sleep for the given time. This is scheduled - /// using a System.Threading.Timer object. The operation will not block operating system threads - /// for the duration of the wait. + /// + /// Creates an asynchronous computation that will sleep for the given time. This is scheduled + /// using a System.Threading.Timer object. The operation will not block operating system threads + /// for the duration of the wait. + /// + /// /// The number of milliseconds to sleep. + /// /// An asynchronous computation that will sleep for the given time. - /// Thrown when the due time is negative + /// + /// Thrown when the due time is negative /// and not infinite. + /// + /// Awaiting Results + /// + /// static member Sleep: millisecondsDueTime:int -> Async - /// Creates an asynchronous computation in terms of a Begin/End pair of actions in - /// the style used in CLI APIs. For example, - /// Async.FromBeginEnd(ws.BeginGetWeather,ws.EndGetWeather) - /// When the computation is run, beginFunc is executed, with - /// a callback which represents the continuation of the computation. - /// When the callback is invoked, the overall result is fetched using endFunc. + /// + /// Creates an asynchronous computation that will sleep for the given time. This is scheduled + /// using a System.Threading.Timer object. The operation will not block operating system threads + /// for the duration of the wait. + /// /// - /// The computation will respond to cancellation while waiting for the completion + /// The amount of time to sleep. + /// + /// An asynchronous computation that will sleep for the given time. + /// + /// Thrown when the due time is negative. + /// + /// Awaiting Results + /// + /// + static member Sleep: dueTime:TimeSpan -> Async + + /// + /// Creates an asynchronous computation in terms of a Begin/End pair of actions in + /// the style used in CLI APIs. + /// + /// + /// + /// The computation will respond to cancellation while waiting for the completion /// of the operation. If a cancellation occurs, and cancelAction is specified, then it is /// executed, and the computation continues to wait for the completion of the operation. /// /// If cancelAction is not specified, then cancellation causes the computation /// to stop immediately, and subsequent invocations of the callback are ignored. + /// /// The function initiating a traditional CLI asynchronous operation. /// The function completing a traditional CLI asynchronous operation. /// An optional function to be executed when a cancellation is requested. + /// /// An asynchronous computation wrapping the given Begin/End functions. + /// + /// Legacy .NET Async Interoperability + /// + /// static member FromBeginEnd : beginAction:(System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> - /// Creates an asynchronous computation in terms of a Begin/End pair of actions in - /// the style used in CLI APIs. This overload should be used if the operation is - /// qualified by one argument. For example, - /// Async.FromBeginEnd(place,ws.BeginGetWeather,ws.EndGetWeather) - /// When the computation is run, beginFunc is executed, with - /// a callback which represents the continuation of the computation. - /// When the callback is invoked, the overall result is fetched using endFunc. + /// + /// Creates an asynchronous computation in terms of a Begin/End pair of actions in + /// the style used in .NET 2.0 APIs. + /// /// /// The computation will respond to cancellation while waiting for the completion /// of the operation. If a cancellation occurs, and cancelAction is specified, then it is /// executed, and the computation continues to wait for the completion of the operation. - /// - /// If cancelAction is not specified, then cancellation causes the computation - /// to stop immediately, and subsequent invocations of the callback are ignored. + /// + /// If cancelAction is not specified, then cancellation causes the computation + /// to stop immediately, and subsequent invocations of the callback are ignored. + /// + /// /// The argument for the operation. /// The function initiating a traditional CLI asynchronous operation. /// The function completing a traditional CLI asynchronous operation. /// An optional function to be executed when a cancellation is requested. + /// /// An asynchronous computation wrapping the given Begin/End functions. + /// + /// Legacy .NET Async Interoperability + /// + /// static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> - /// Creates an asynchronous computation in terms of a Begin/End pair of actions in - /// the style used in CLI APIs. This overload should be used if the operation is - /// qualified by two arguments. For example, - /// Async.FromBeginEnd(arg1,arg2,ws.BeginGetWeather,ws.EndGetWeather) - /// When the computation is run, beginFunc is executed, with - /// a callback which represents the continuation of the computation. - /// When the callback is invoked, the overall result is fetched using endFunc. + /// + /// Creates an asynchronous computation in terms of a Begin/End pair of actions in + /// the style used in .NET 2.0 APIs. /// /// The computation will respond to cancellation while waiting for the completion /// of the operation. If a cancellation occurs, and cancelAction is specified, then it is @@ -336,21 +540,22 @@ namespace Microsoft.FSharp.Control /// /// If cancelAction is not specified, then cancellation causes the computation /// to stop immediately, and subsequent invocations of the callback are ignored. + /// /// The first argument for the operation. /// The second argument for the operation. /// The function initiating a traditional CLI asynchronous operation. /// The function completing a traditional CLI asynchronous operation. /// An optional function to be executed when a cancellation is requested. + /// /// An asynchronous computation wrapping the given Begin/End functions. + /// + /// Legacy .NET Async Interoperability + /// + /// static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> /// Creates an asynchronous computation in terms of a Begin/End pair of actions in - /// the style used in CLI APIs. This overload should be used if the operation is - /// qualified by three arguments. For example, - /// Async.FromBeginEnd(arg1,arg2,arg3,ws.BeginGetWeather,ws.EndGetWeather) - /// When the computation is run, beginFunc is executed, with - /// a callback which represents the continuation of the computation. - /// When the callback is invoked, the overall result is fetched using endFunc. + /// the style used in .NET 2.0 APIs. /// /// The computation will respond to cancellation while waiting for the completion /// of the operation. If a cancellation occurs, and cancelAction is specified, then it is @@ -358,49 +563,32 @@ namespace Microsoft.FSharp.Control /// /// If cancelAction is not specified, then cancellation causes the computation /// to stop immediately, and subsequent invocations of the callback are ignored. + /// /// The first argument for the operation. /// The second argument for the operation. /// The third argument for the operation. /// The function initiating a traditional CLI asynchronous operation. /// The function completing a traditional CLI asynchronous operation. /// An optional function to be executed when a cancellation is requested. + /// /// An asynchronous computation wrapping the given Begin/End functions. + /// + /// Legacy .NET Async Interoperability + /// + /// static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * System.AsyncCallback * obj -> System.IAsyncResult) * endAction:(System.IAsyncResult -> 'T) * ?cancelAction : (unit -> unit) -> Async<'T> - /// Creates three functions that can be used to implement the .NET Asynchronous + /// Creates three functions that can be used to implement the .NET 1.0 Asynchronous /// Programming Model (APM) for a given asynchronous computation. - /// - /// The functions should normally be published as members with prefix Begin, - /// End and Cancel, and can be used within a type definition as follows: - /// - /// let beginAction,endAction,cancelAction = Async.AsBeginEnd (fun arg -> computation) - /// member x.BeginSomeOperation(arg,callback,state:obj) = beginAction(arg,callback,state) - /// member x.EndSomeOperation(iar) = endAction(iar) - /// member x.CancelSomeOperation(iar) = cancelAction(iar) - /// - /// - /// If the asynchronous computation takes no arguments, then AsBeginEnd is used as follows: - /// - /// let beginAction,endAction,cancelAction = Async.AsBeginEnd (fun () -> computation) - /// member x.BeginSomeOperation(callback,state:obj) = beginAction((),callback,state) - /// member x.EndSomeOperation(iar) = endAction(iar) - /// member x.CancelSomeOperation(iar) = cancelAction(iar) - /// - /// - /// - /// If the asynchronous computation takes two arguments, then AsBeginEnd is used as follows: - /// - /// let beginAction,endAction,cancelAction = Async.AsBeginEnd (fun arg1 arg2 -> computation) - /// member x.BeginSomeOperation(arg1,arg2,callback,state:obj) = beginAction((),callback,state) - /// member x.EndSomeOperation(iar) = endAction(iar) - /// member x.CancelSomeOperation(iar) = cancelAction(iar) - /// - /// - /// In each case, the resulting API will be familiar to programmers in other CLI languages and - /// is a useful way to publish asynchronous computations in CLI components. + /// /// A function generating the asynchronous computation to split into the traditional /// .NET Asynchronous Programming Model. + /// /// A tuple of the begin, end, and cancel members. + /// + /// Legacy .NET Async Interoperability + /// + /// static member AsBeginEnd : computation:('Arg -> Async<'T>) -> // The 'Begin' member ('Arg * System.AsyncCallback * obj -> System.IAsyncResult) * @@ -411,25 +599,39 @@ namespace Microsoft.FSharp.Control /// Creates an asynchronous computation that runs the given computation and ignores /// its result. + /// /// The input computation. + /// /// A computation that is equivalent to the input computation, but disregards the result. + /// + /// Composing Async Computations + /// + /// static member Ignore : computation: Async<'T> -> Async /// Runs an asynchronous computation, starting immediately on the current operating system /// thread. Call one of the three continuations when the operation completes. + /// /// If no cancellation token is provided then the default cancellation token /// is used. + /// /// The asynchronous computation to execute. /// The function called on success. /// The function called on exception. /// The function called on cancellation. /// The CancellationToken to associate with the computation. /// The default is used if this parameter is not provided. + /// + /// Starting Async Computations + /// + /// static member StartWithContinuations: computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken-> unit + /// + /// static member internal StartWithContinuationsUsingDispatchInfo: computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(ExceptionDispatchInfo -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * @@ -437,56 +639,89 @@ namespace Microsoft.FSharp.Control /// Runs an asynchronous computation, starting immediately on the current operating system /// thread. + /// /// If no cancellation token is provided then the default cancellation token is used. + /// /// The asynchronous computation to execute. /// The CancellationToken to associate with the computation. /// The default is used if this parameter is not provided. + /// + /// Starting Async Computations + /// + /// static member StartImmediate: computation:Async * ?cancellationToken:CancellationToken-> unit /// Runs an asynchronous computation, starting immediately on the current operating system - /// thread, but also returns the execution as System.Threading.Tasks.Task + /// thread, but also returns the execution as /// + /// /// If no cancellation token is provided then the default cancellation token is used. /// You may prefer using this method if you want to achive a similar behviour to async await in C# as /// async computation starts on the current thread with an ability to return a result. /// + /// /// The asynchronous computation to execute. /// The CancellationToken to associate with the computation. /// The default is used if this parameter is not provided. - /// A System.Threading.Tasks.Task that will be completed + /// + /// A that will be completed /// in the corresponding state once the computation terminates (produces the result, throws exception or gets canceled) + /// + /// Starting Async Computations + /// + /// static member StartImmediateAsTask: computation:Async<'T> * ?cancellationToken:CancellationToken-> Task<'T> /// The F# compiler emits references to this type to implement F# async expressions. + /// + /// Async Internals type AsyncReturn /// The F# compiler emits references to this type to implement F# async expressions. [] + /// + /// Async Internals type AsyncActivation<'T> = /// The F# compiler emits calls to this function to implement F# async expressions. /// /// A value indicating asynchronous execution. + /// + /// member IsCancellationRequested: bool /// The F# compiler emits calls to this function to implement F# async expressions. /// /// A value indicating asynchronous execution. - member OnSuccess: 'T -> AsyncReturn + /// + /// + static member Success: AsyncActivation<'T> -> result: 'T -> AsyncReturn /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// A value indicating asynchronous execution. + /// + /// + member OnSuccess: result: 'T -> AsyncReturn + + /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// member OnExceptionRaised: unit -> unit /// The F# compiler emits calls to this function to implement F# async expressions. /// /// A value indicating asynchronous execution. + /// + /// member OnCancellation: unit -> AsyncReturn /// Used by MailboxProcessor member internal QueueContinuationWithTrampoline: 'T -> AsyncReturn + /// Used by MailboxProcessor member internal CallContinuation: 'T -> AsyncReturn @@ -499,6 +734,8 @@ namespace Microsoft.FSharp.Control [] /// Entry points for generated code + /// + /// Async Internals module AsyncPrimitives = /// The F# compiler emits calls to this function to implement F# async expressions. @@ -519,7 +756,7 @@ namespace Microsoft.FSharp.Control /// The F# compiler emits calls to this function to implement constructs for F# async expressions. /// /// The async activation. - /// The result of the first part of the computation. + /// The result of the first part of the computation. /// A function returning the second part of the computation. /// /// A value indicating asynchronous execution. @@ -528,6 +765,7 @@ namespace Microsoft.FSharp.Control /// The F# compiler emits calls to this function to implement the let! construct for F# async expressions. /// /// The async activation. + /// The first part of the computation. /// A function returning the second part of the computation. /// /// An async activation suitable for running part1 of the asynchronous execution. @@ -570,6 +808,8 @@ namespace Microsoft.FSharp.Control [] [] /// The type of the async operator, used to build workflows for asynchronous computations. + /// + /// Async Programming type AsyncBuilder = /// Creates an asynchronous computation that enumerates the sequence seq /// on demand and runs body for each element. @@ -578,11 +818,15 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of for in the /// async { ... } computation expression syntax. + /// /// The sequence to enumerate. /// A function to take an item from the sequence and create /// an asynchronous computation. Can be seen as the body of the for expression. + /// /// An asynchronous computation that will enumerate the sequence and run body /// for each element. + /// + /// member For: sequence:seq<'T> * body:('T -> Async) -> Async /// Creates an asynchronous computation that just returns (). @@ -592,6 +836,8 @@ namespace Microsoft.FSharp.Control /// The existence of this method permits the use of empty else branches in the /// async { ... } computation expression syntax. /// An asynchronous computation that returns (). + /// + /// member Zero : unit -> Async /// Creates an asynchronous computation that first runs computation1 @@ -601,9 +847,13 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of expression sequencing in the /// async { ... } computation expression syntax. + /// /// The first part of the sequenced computation. /// The second part of the sequenced computation. + /// /// An asynchronous computation that runs both of the computations sequentially. + /// + /// member inline Combine : computation1:Async * computation2:Async<'T> -> Async<'T> /// Creates an asynchronous computation that runs computation repeatedly @@ -613,10 +863,14 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of while in the /// async { ... } computation expression syntax. + /// /// The function to determine when to stop executing computation. /// The function to be executed. Equivalent to the body /// of a while expression. + /// /// An asynchronous computation that behaves similarly to a while loop when run. + /// + /// member While : guard:(unit -> bool) * computation:Async -> Async /// Creates an asynchronous computation that returns the result v. @@ -625,23 +879,35 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of return in the /// async { ... } computation expression syntax. + /// /// The value to return from the computation. + /// /// An asynchronous computation that returns value when executed. + /// + /// member inline Return : value:'T -> Async<'T> /// Delegates to the input computation. /// /// The existence of this method permits the use of return! in the /// async { ... } computation expression syntax. + /// /// The input computation. + /// /// The input computation. + /// + /// member inline ReturnFrom : computation:Async<'T> -> Async<'T> /// Creates an asynchronous computation that runs generator. /// /// A cancellation check is performed when the computation is executed. + /// /// The function to run. + /// /// An asynchronous computation that runs generator. + /// + /// member Delay : generator:(unit -> Async<'T>) -> Async<'T> /// Creates an asynchronous computation that runs binder(resource). @@ -652,10 +918,14 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of use and use! in the /// async { ... } computation expression syntax. + /// /// The resource to be used and disposed. /// The function that takes the resource and returns an asynchronous /// computation. + /// /// An asynchronous computation that binds and eventually disposes resource. + /// + /// member Using: resource:'T * binder:('T -> Async<'U>) -> Async<'U> when 'T :> System.IDisposable /// Creates an asynchronous computation that runs computation, and when @@ -665,10 +935,14 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of let! in the /// async { ... } computation expression syntax. + /// /// The computation to provide an unbound result. /// The function to bind the result of computation. + /// /// An asynchronous computation that performs a monadic bind on the result /// of computation. + /// + /// member inline Bind: computation: Async<'T> * binder: ('T -> Async<'U>) -> Async<'U> /// Creates an asynchronous computation that runs computation. The action compensation is executed @@ -679,11 +953,15 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of try/finally in the /// async { ... } computation expression syntax. + /// /// The input computation. /// The action to be run after computation completes or raises an /// exception (including cancellation). + /// /// An asynchronous computation that executes computation and compensation afterwards or /// when an exception is raised. + /// + /// member inline TryFinally : computation:Async<'T> * compensation:(unit -> unit) -> Async<'T> /// Creates an asynchronous computation that runs computation and returns its result. @@ -696,8 +974,11 @@ namespace Microsoft.FSharp.Control /// /// The input computation. /// The function to run when computation throws an exception. + /// /// An asynchronous computation that executes computation and calls catchHandler if an /// exception is thrown. + /// + /// member inline TryWith : computation:Async<'T> * catchHandler:(exn -> Async<'T>) -> Async<'T> // member inline TryWithFilter : computation:Async<'T> * catchHandler:(exn -> Async<'T> option) -> Async<'T> @@ -710,6 +991,8 @@ namespace Microsoft.FSharp.Control [] /// A module of extension members providing asynchronous operations for some basic CLI types related to concurrency and I/O. + /// + /// Async Programming module CommonExtensions = type System.IO.Stream with @@ -718,27 +1001,40 @@ namespace Microsoft.FSharp.Control /// The buffer to read into. /// An optional offset as a number of bytes in the stream. /// An optional number of bytes to read from the stream. + /// /// An asynchronous computation that will read from the stream into the given buffer. - /// Thrown when the sum of offset and count is longer than + /// + /// Thrown when the sum of offset and count is longer than /// the buffer length. - /// Thrown when offset or count is negative. + /// Thrown when offset or count is negative. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncRead : buffer:byte[] * ?offset:int * ?count:int -> Async /// Returns an asynchronous computation that will read the given number of bytes from the stream. + /// /// The number of bytes to read. + /// /// An asynchronous computation that returns the read byte[] when run. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncRead : count:int -> Async /// Returns an asynchronous computation that will write the given bytes to the stream. + /// /// The buffer to write from. /// An optional offset as a number of bytes in the stream. /// An optional number of bytes to write to the stream. + /// /// An asynchronous computation that will write the given bytes to the stream. - /// Thrown when the sum of offset and count is longer than + /// + /// Thrown when the sum of offset and count is longer than /// the buffer length. - /// Thrown when offset or count is negative. + /// Thrown when offset or count is negative. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncWrite : buffer:byte[] * ?offset:int * ?count:int -> Async @@ -747,46 +1043,69 @@ namespace Microsoft.FSharp.Control type IObservable<'T> with /// Permanently connects a listener function to the observable. The listener will /// be invoked for each observation. + /// /// The function to be called for each observation. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member Add: callback:('T -> unit) -> unit /// Connects a listener function to the observable. The listener will /// be invoked for each observation. The listener can be removed by /// calling Dispose on the returned IDisposable object. + /// /// The function to be called for each observation. + /// /// An object that will remove the listener if disposed. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member Subscribe: callback:('T -> unit) -> System.IDisposable /// A module of extension members providing asynchronous operations for some basic Web operations. + /// + /// Async Programming [] module WebExtensions = type System.Net.WebRequest with /// Returns an asynchronous computation that, when run, will wait for a response to the given WebRequest. /// An asynchronous computation that waits for response to the WebRequest. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncGetResponse : unit -> Async type System.Net.WebClient with /// Returns an asynchronous computation that, when run, will wait for the download of the given URI. + /// /// The URI to retrieve. + /// /// An asynchronous computation that will wait for the download of the URI. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncDownloadString : address:System.Uri -> Async /// Returns an asynchronous computation that, when run, will wait for the download of the given URI. + /// /// The URI to retrieve. + /// /// An asynchronous computation that will wait for the download of the URI. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncDownloadData : address:System.Uri -> Async /// Returns an asynchronous computation that, when run, will wait for the download of the given URI to specified file. + /// /// The URI to retrieve. /// The filename to save download to. + /// /// An asynchronous computation that will wait for the download of the URI to specified file. + /// + /// [] // give the extension member a nice, unmangled compiled name, unique within this module member AsyncDownloadFile : address:System.Uri * fileName: string -> Async diff --git a/src/fsharp/FSharp.Core/collections.fs b/src/fsharp/FSharp.Core/collections.fs index 547fe99fd54..f15cb4894a3 100644 --- a/src/fsharp/FSharp.Core/collections.fs +++ b/src/fsharp/FSharp.Core/collections.fs @@ -19,19 +19,19 @@ namespace Microsoft.FSharp.Collections let Reference<'T when 'T : not struct > : IEqualityComparer<'T> = { new IEqualityComparer<'T> with - member __.GetHashCode(x) = LanguagePrimitives.PhysicalHash(x) - member __.Equals(x,y) = LanguagePrimitives.PhysicalEquality x y } + member _.GetHashCode(x) = LanguagePrimitives.PhysicalHash(x) + member _.Equals(x,y) = LanguagePrimitives.PhysicalEquality x y } let inline NonStructural< 'T when 'T : equality and 'T : (static member ( = ) : 'T * 'T -> bool) > = { new IEqualityComparer<'T> with - member __.GetHashCode(x) = NonStructuralComparison.hash x - member __.Equals(x, y) = NonStructuralComparison.(=) x y } + member _.GetHashCode(x) = NonStructuralComparison.hash x + member _.Equals(x, y) = NonStructuralComparison.(=) x y } let inline FromFunctions hasher equality : IEqualityComparer<'T> = let eq = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(equality) { new IEqualityComparer<'T> with - member __.GetHashCode(x) = hasher x - member __.Equals(x,y) = eq.Invoke(x,y) } + member _.GetHashCode(x) = hasher x + member _.Equals(x,y) = eq.Invoke(x,y) } module ComparisonIdentity = @@ -41,10 +41,10 @@ namespace Microsoft.FSharp.Collections let inline NonStructural< 'T when 'T : (static member ( < ) : 'T * 'T -> bool) and 'T : (static member ( > ) : 'T * 'T -> bool) > : IComparer<'T> = { new IComparer<'T> with - member __.Compare(x,y) = NonStructuralComparison.compare x y } + member _.Compare(x,y) = NonStructuralComparison.compare x y } let FromFunction comparer = let comparer = OptimizedClosures.FSharpFunc<'T,'T,int>.Adapt(comparer) { new IComparer<'T> with - member __.Compare(x,y) = comparer.Invoke(x,y) } + member _.Compare(x,y) = comparer.Invoke(x,y) } diff --git a/src/fsharp/FSharp.Core/collections.fsi b/src/fsharp/FSharp.Core/collections.fsi index ad7f4363d1b..429b4633999 100644 --- a/src/fsharp/FSharp.Core/collections.fsi +++ b/src/fsharp/FSharp.Core/collections.fsi @@ -3,50 +3,84 @@ /// This namespace contains some common collections in a style primarily designed for use from F#. namespace Microsoft.FSharp.Collections - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - open Microsoft.FSharp.Primitives.Basics - open System - open System.Collections.Generic - /// Common notions of comparison identity used with sorted data structures. - module ComparisonIdentity = - - /// Structural comparison. Compare using Operators.compare. - val inline Structural<'T> : IComparer<'T> when 'T : comparison +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections +open Microsoft.FSharp.Primitives.Basics +open System +open System.Collections.Generic - /// Non-structural comparison. Compare using NonStructuralComparison.compare. - val inline NonStructural< ^T > : IComparer< ^T > when ^T : (static member ( < ) : ^T * ^T -> bool) and ^T : (static member ( > ) : ^T * ^T -> bool) +/// Common notions of value ordering implementing the +/// interface, for constructing sorted data structures and performing sorting operations. +module ComparisonIdentity = + + /// Get an implementation of comparison semantics using structural comparison. + /// + /// An object implementing using . + /// + /// + val inline Structural<'T> : IComparer<'T> when 'T : comparison - /// Compare using the given comparer function. - /// A function to compare two values. - /// An object implementing IComparer using the supplied comparer. - val FromFunction : comparer:('T -> 'T -> int) -> IComparer<'T> - - /// Common notions of value identity used with hash tables. - module HashIdentity = + /// Get an implementation of comparison semantics using non-structural comparison. + /// + /// An object implementing using . + /// + /// + val inline NonStructural< ^T > : IComparer< ^T > when ^T : (static member ( < ) : ^T * ^T -> bool) and ^T : (static member ( > ) : ^T * ^T -> bool) - /// Structural hashing. Hash using Operators.(=) and Operators.hash. - val inline Structural<'T> : IEqualityComparer<'T> when 'T : equality - - /// Non-structural hashing. Equality using NonStructuralComparison.(=) and NonStructuralComparison.hash. - val inline NonStructural<'T> : IEqualityComparer< ^T > when ^T : equality and ^T : (static member ( = ) : ^T * ^T -> bool) - - val inline LimitedStructural<'T> : limit: int -> IEqualityComparer<'T> when 'T : equality - - /// Physical hashing (hash on reference identity of objects, and the contents of value types). - /// Hash using LanguagePrimitives.PhysicalEquality and LanguagePrimitives.PhysicalHash, - /// That is, for value types use GetHashCode and Object.Equals (if no other optimization available), - /// and for reference types use System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode and - /// reference equality. - val Reference<'T> : IEqualityComparer<'T> when 'T : not struct - - /// Hash using the given hashing and equality functions. - /// A function to generate a hash code from a value. - /// A function to test equality of two values. - /// An object implementing IEqualityComparer using the supplied functions. - - // inline justification: allows inlining of hash functions - val inline FromFunctions<'T> : hasher:('T -> int) -> equality:('T -> 'T -> bool) -> IEqualityComparer<'T> + /// Get an implementation of comparison semantics using the given function. + /// + /// A function to compare two values. + /// + /// An object implementing using the supplied function. + /// + /// + val FromFunction : comparer:('T -> 'T -> int) -> IComparer<'T> + +/// Common notions of value identity implementing the +/// interface, for constructing objects and other collections +module HashIdentity = + /// Get an implementation of equality semantics using structural equality and structural hashing. + /// + /// An object implementing using and . + /// + /// + val inline Structural<'T> : IEqualityComparer<'T> when 'T : equality + + /// Get an implementation of equality semantics using non-structural equality and non-structural hashing. + /// + /// + /// An object implementing using + /// and . + /// + /// + /// + val inline NonStructural<'T> : IEqualityComparer< ^T > when ^T : equality and ^T : (static member ( = ) : ^T * ^T -> bool) + + /// Get an implementation of equality semantics semantics using structural equality and structural hashing. + /// + /// An object implementing . + /// + /// + val inline LimitedStructural<'T> : limit: int -> IEqualityComparer<'T> when 'T : equality + + /// Get an implementation of equality semantics using reference equality and reference hashing. + /// + /// + /// An object implementing using + /// and . + /// + /// + /// + val Reference<'T> : IEqualityComparer<'T> when 'T : not struct + /// Get an implementation of equality semantics using the given functions. + /// + /// A function to generate a hash code from a value. + /// A function to test equality of two values. + /// + /// An object implementing using the given functions. + /// + /// + val inline FromFunctions<'T> : hasher:('T -> int) -> equality:('T -> 'T -> bool) -> IEqualityComparer<'T> diff --git a/src/fsharp/FSharp.Core/event.fs b/src/fsharp/FSharp.Core/event.fs index 8643b669c3e..8e1d0826f33 100644 --- a/src/fsharp/FSharp.Core/event.fs +++ b/src/fsharp/FSharp.Core/event.fs @@ -10,6 +10,19 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Control open System.Reflection open System.Diagnostics + + module private Atomic = + open System.Threading + + let inline setWith (thunk: 'a -> 'a) (value: byref<'a>) = + let mutable exchanged = false + let mutable oldValue = value + while not exchanged do + let comparand = oldValue + let newValue = thunk comparand + oldValue <- Interlocked.CompareExchange(&value, newValue, comparand) + if obj.ReferenceEquals(comparand, oldValue) then + exchanged <- true [] type DelegateEvent<'Delegate when 'Delegate :> System.Delegate>() = @@ -21,9 +34,9 @@ namespace Microsoft.FSharp.Control member x.Publish = { new IDelegateEvent<'Delegate> with member x.AddHandler(d) = - multicast <- System.Delegate.Combine(multicast, d) - member x.RemoveHandler(d) = - multicast <- System.Delegate.Remove(multicast, d) } + Atomic.setWith (fun value -> System.Delegate.Combine(value, d)) &multicast + member x.RemoveHandler(d) = + Atomic.setWith (fun value -> System.Delegate.Remove(value, d)) &multicast } type EventDelegee<'Args>(observer: System.IObserver<'Args>) = static let makeTuple = @@ -54,7 +67,7 @@ namespace Microsoft.FSharp.Control type EventWrapper<'Delegate,'Args> = delegate of 'Delegate * obj * 'Args -> unit [] - type Event<'Delegate, 'Args when 'Delegate : delegate<'Args, unit> and 'Delegate :> System.Delegate>() = + type Event<'Delegate, 'Args when 'Delegate : delegate<'Args, unit> and 'Delegate :> System.Delegate and 'Delegate: not struct>() = let mutable multicast : 'Delegate = Unchecked.defaultof<_> @@ -85,6 +98,8 @@ namespace Microsoft.FSharp.Control mi member x.Trigger(sender:obj,args: 'Args) = + // Copy multicast value into local variable to avoid changing during member call. + let multicast = multicast match box multicast with | null -> () | _ -> @@ -97,17 +112,14 @@ namespace Microsoft.FSharp.Control // CreateDelegate creates a delegate that is fast to invoke. invoker.Invoke(multicast, sender, args) |> ignore - member x.Publish = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 + member x.Publish = { new obj() with member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with + interface IEvent<'Delegate,'Args> with member e.AddHandler(d) = - multicast <- System.Delegate.Combine(multicast, d) :?> 'Delegate + Atomic.setWith (fun value -> System.Delegate.Combine(value, d) :?> 'Delegate) &multicast member e.RemoveHandler(d) = - multicast <- System.Delegate.Remove(multicast, d) :?> 'Delegate + Atomic.setWith (fun value -> System.Delegate.Remove(value, d) :?> 'Delegate) &multicast interface System.IObservable<'Args> with member e.Subscribe(observer) = let obj = new EventDelegee<'Args>(observer) @@ -126,17 +138,14 @@ namespace Microsoft.FSharp.Control match x.multicast with | null -> () | d -> d.Invoke(null,arg) |> ignore - member x.Publish = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 + member x.Publish = { new obj() with member x.ToString() = "" - interface IEvent<'T> - interface IDelegateEvent> with + interface IEvent<'T> with member e.AddHandler(d) = - x.multicast <- (System.Delegate.Combine(x.multicast, d) :?> Handler<'T>) + Atomic.setWith (fun value -> System.Delegate.Combine(value, d) :?> Handler<'T>) &x.multicast member e.RemoveHandler(d) = - x.multicast <- (System.Delegate.Remove(x.multicast, d) :?> Handler<'T>) + Atomic.setWith (fun value -> System.Delegate.Remove(value, d) :?> Handler<'T>) &x.multicast interface System.IObservable<'T> with member e.Subscribe(observer) = let h = new Handler<_>(fun sender args -> observer.OnNext(args)) diff --git a/src/fsharp/FSharp.Core/event.fsi b/src/fsharp/FSharp.Core/event.fsi index 23bc85ceea6..20b1bb9a3b9 100644 --- a/src/fsharp/FSharp.Core/event.fsi +++ b/src/fsharp/FSharp.Core/event.fsi @@ -2,46 +2,79 @@ namespace Microsoft.FSharp.Control - open System - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Control - open Microsoft.FSharp.Collections - - /// Event implementations for an arbitrary type of delegate. - [] - type DelegateEvent<'Delegate when 'Delegate :> System.Delegate> = - /// Creates an event object suitable for implementing an arbitrary type of delegate. - /// The event object. - new : unit -> DelegateEvent<'Delegate> - /// Triggers the event using the given parameters. - /// The parameters for the event. - member Trigger : args:obj[] -> unit - /// Publishes the event as a first class event value. - member Publish : IDelegateEvent<'Delegate> - - /// Event implementations for a delegate types following the standard .NET Framework convention of a first 'sender' argument. - [] - type Event<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate > = - /// Creates an event object suitable for delegate types following the standard .NET Framework convention of a first 'sender' argument. - /// The created event. - new : unit -> Event<'Delegate,'Args> - /// Triggers the event using the given sender object and parameters. The sender object may be null. - /// The object triggering the event. - /// The parameters for the event. - member Trigger : sender:obj * args:'Args -> unit - /// Publishes the event as a first class event value. - member Publish : IEvent<'Delegate,'Args> - - - /// Event implementations for the IEvent<_> type. - [] - type Event<'T> = - /// Creates an observable object. - /// The created event. - new : unit -> Event<'T> - /// Triggers an observation using the given parameters. - /// The event parameters. - member Trigger : arg:'T -> unit - /// Publishes an observation as a first class value. - member Publish : IEvent<'T> +open System +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.Operators +open Microsoft.FSharp.Control +open Microsoft.FSharp.Collections + +/// Event implementations for an arbitrary type of delegate. +/// +/// Events and Observables +[] +type DelegateEvent<'Delegate when 'Delegate :> System.Delegate> = + /// Creates an event object suitable for implementing an arbitrary type of delegate. + /// The event object. + /// + /// + new : unit -> DelegateEvent<'Delegate> + + /// Triggers the event using the given parameters. + /// The parameters for the event. + /// + /// + member Trigger : args:obj[] -> unit + + /// Publishes the event as a first class event value. + /// + /// + member Publish : IDelegateEvent<'Delegate> + +/// Event implementations for a delegate types following the standard .NET Framework convention of a first 'sender' argument. +/// +/// Events and Observables +[] +type Event<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate and 'Delegate : not struct> = + + /// Creates an event object suitable for delegate types following the standard .NET Framework convention of a first 'sender' argument. + /// The created event. + /// + /// + new : unit -> Event<'Delegate,'Args> + + /// Triggers the event using the given sender object and parameters. The sender object may be null. + /// + /// The object triggering the event. + /// The parameters for the event. + /// + /// + member Trigger : sender:obj * args:'Args -> unit + + /// Publishes the event as a first class event value. + /// + /// + member Publish : IEvent<'Delegate,'Args> + +/// Event implementations for the IEvent<_> type. +/// +/// Events and Observables +[] +type Event<'T> = + + /// Creates an observable object. + /// The created event. + /// + /// + new : unit -> Event<'T> + + /// Triggers the event using the given parameters. + /// + /// The event parameters. + /// + /// + member Trigger : arg:'T -> unit + + /// Publishes the event as a first class value. + /// + /// + member Publish : IEvent<'T> diff --git a/src/fsharp/FSharp.Core/eventmodule.fsi b/src/fsharp/FSharp.Core/eventmodule.fsi index c3f5f3cc9fb..4e520b559f6 100644 --- a/src/fsharp/FSharp.Core/eventmodule.fsi +++ b/src/fsharp/FSharp.Core/eventmodule.fsi @@ -7,26 +7,34 @@ namespace Microsoft.FSharp.Control [] [] + /// Contains operations for working with values of type . + /// + /// Events and Observables module Event = /// Fires the output event when either of the input events fire. /// The first input event. /// The second input event. + /// /// An event that fires when either of the input events fire. [] val merge: event1:IEvent<'Del1,'T> -> event2:IEvent<'Del2,'T> -> IEvent<'T> /// Returns a new event that passes values transformed by the given function. - /// The function to transform event values. + /// + /// The function to transform event values. /// The input event. + /// /// An event that passes the transformed values. [] val map: mapping:('T -> 'U) -> sourceEvent:IEvent<'Del,'T> -> IEvent<'U> /// Returns a new event that listens to the original event and triggers the resulting /// event only when the argument to the event passes the given function. + /// /// The function to determine which triggers from the event to propagate. /// The input event. + /// /// An event that only passes values that pass the predicate. [] val filter: predicate:('T -> bool) -> sourceEvent:IEvent<'Del,'T> -> IEvent<'T> @@ -34,8 +42,10 @@ namespace Microsoft.FSharp.Control /// Returns a new event that listens to the original event and triggers the /// first resulting event if the application of the predicate to the event arguments /// returned true, and the second event if it returned false. + /// /// The function to determine which output event to trigger. /// The input event. + /// /// A tuple of events. The first is triggered when the predicate evaluates to true /// and the second when the predicate evaluates to false. [] @@ -44,8 +54,10 @@ namespace Microsoft.FSharp.Control /// Returns a new event that listens to the original event and triggers the /// first resulting event if the application of the function to the event arguments /// returned a Choice1Of2, and the second event if it returns a Choice2Of2. + /// /// The function to transform event values into one of two types. /// The input event. + /// /// A tuple of events. The first fires whenever splitter evaluates to Choice1of1 and /// the second fires whenever splitter evaluates to Choice2of2. [] @@ -53,8 +65,10 @@ namespace Microsoft.FSharp.Control /// Returns a new event which fires on a selection of messages from the original event. /// The selection function takes an original message to an optional new message. + /// /// The function to select and transform event values to pass on. /// The input event. + /// /// An event that fires only when the chooser returns Some. [] val choose: chooser:('T -> 'U option) -> sourceEvent:IEvent<'Del,'T> -> IEvent<'U> @@ -65,13 +79,16 @@ namespace Microsoft.FSharp.Control /// records the current value of the state parameter. The internal state is not locked during the /// execution of the accumulation function, so care should be taken that the /// input IEvent not triggered by multiple threads simultaneously. + /// /// The function to update the state with each event value. /// The initial state. /// The input event. + /// /// An event that fires on the updated state values. val scan: collector:('U -> 'T -> 'U) -> state:'U -> sourceEvent:IEvent<'Del,'T> -> IEvent<'U> /// Runs the given function each time the given event is triggered. + /// /// The function to call when the event is triggered. /// The input event. [] @@ -81,7 +98,9 @@ namespace Microsoft.FSharp.Control /// The Nth triggering of the input event passes the arguments from the N-1th and Nth triggering as /// a pair. The argument passed to the N-1th triggering is held in hidden internal state until the /// Nth triggering occurs. + /// /// The input event. + /// /// An event that triggers on pairs of consecutive values passed from the source event. [] val pairwise: sourceEvent:IEvent<'Del,'T> -> IEvent<'T * 'T> diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index b3fa821511a..5fd4e32b29e 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -81,16 +81,16 @@ module ExtraTopLevelOperators = member s.Remove(_ : 'Key) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : bool) interface IReadOnlyDictionary<'Key, 'T> with - member __.Item with get key = t.[makeSafeKey key] - member __.Keys = t.Keys |> Seq.map getKey - member __.TryGetValue(key, r) = + member _.Item with get key = t.[makeSafeKey key] + member _.Keys = t.Keys |> Seq.map getKey + member _.TryGetValue(key, r) = match t.TryGetValue (makeSafeKey key) with | false, _ -> false | true, value -> r <- value true - member __.Values = (t :> IReadOnlyDictionary<_,_>).Values - member __.ContainsKey k = t.ContainsKey (makeSafeKey k) + member _.Values = (t :> IReadOnlyDictionary<_,_>).Values + member _.ContainsKey k = t.ContainsKey (makeSafeKey k) interface ICollection> with member s.Add(_) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) @@ -106,7 +106,7 @@ module ExtraTopLevelOperators = member s.Count = t.Count interface IReadOnlyCollection> with - member __.Count = t.Count + member _.Count = t.Count interface IEnumerable> with member s.GetEnumerator() = @@ -128,15 +128,15 @@ module ExtraTopLevelOperators = kvps.[index] {new IEnumerator<_> with - member __.Current = current () + member _.Current = current () interface System.Collections.IEnumerator with - member __.Current = box(current()) - member __.MoveNext() = + member _.Current = box(current()) + member _.MoveNext() = if index < endIndex then index <- index + 1 index < endIndex else false - member __.Reset() = index <- -1 + member _.Reset() = index <- -1 interface System.IDisposable with member self.Dispose() = () } #endif @@ -268,6 +268,11 @@ module ExtraTopLevelOperators = [] [] [] + #if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE + [] + [] + [] + #endif [] [] do() @@ -306,12 +311,12 @@ namespace Microsoft.FSharp.Core.CompilerServices type TypeProviderAssemblyAttribute(assemblyName : string) = inherit System.Attribute() new () = TypeProviderAssemblyAttribute(null) - member __.AssemblyName = assemblyName + member _.AssemblyName = assemblyName [] type TypeProviderXmlDocAttribute(commentText: string) = inherit System.Attribute() - member __.CommentText = commentText + member _.CommentText = commentText [] type TypeProviderDefinitionLocationAttribute() = diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi index 6b43ddef90a..c1dea425552 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi @@ -4,6 +4,9 @@ namespace Microsoft.FSharp.Core [] +/// A set of extra operators and functions. This module is automatically opened in all F# code. +/// +/// Basic Operators module ExtraTopLevelOperators = open System @@ -13,81 +16,127 @@ module ExtraTopLevelOperators = open Microsoft.FSharp.Text /// Print to stdout using the given format. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] - val printf : format:Printf.TextWriterFormat<'T> -> 'T + val printf: format:Printf.TextWriterFormat<'T> -> 'T /// Print to stdout using the given format, and add a newline. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] - val printfn : format:Printf.TextWriterFormat<'T> -> 'T + val printfn: format:Printf.TextWriterFormat<'T> -> 'T /// Print to stderr using the given format. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] - val eprintf : format:Printf.TextWriterFormat<'T> -> 'T + val eprintf: format:Printf.TextWriterFormat<'T> -> 'T /// Print to stderr using the given format, and add a newline. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] - val eprintfn : format:Printf.TextWriterFormat<'T> -> 'T + val eprintfn: format:Printf.TextWriterFormat<'T> -> 'T /// Print to a string using the given format. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] - val sprintf : format:Printf.StringFormat<'T> -> 'T + val sprintf: format:Printf.StringFormat<'T> -> 'T /// Print to a string buffer and raise an exception with the given - /// result. Helper printers must return strings. + /// result. Helper printers must return strings. + /// /// The formatter. + /// /// The formatted result. + /// + /// [] val failwithf: format:Printf.StringFormat<'T,'Result> -> 'T /// Print to a file using the given format. + /// /// The file TextWriter. /// The formatter. + /// /// The formatted result. + /// + /// [] val fprintf : textWriter:System.IO.TextWriter -> format:Printf.TextWriterFormat<'T> -> 'T /// Print to a file using the given format, and add a newline. + /// /// The file TextWriter. /// The formatter. + /// /// The formatted result. + /// + /// [] val fprintfn : textWriter:System.IO.TextWriter -> format:Printf.TextWriterFormat<'T> -> 'T /// Builds a set from a sequence of objects. The objects are indexed using generic comparison. + /// /// The input sequence of elements. + /// /// The created set. + /// + /// [] val set : elements:seq<'T> -> Set<'T> /// Builds an asynchronous workflow using computation expression syntax. + /// + /// [] val async : Microsoft.FSharp.Control.AsyncBuilder /// Converts the argument to 32-bit float. + /// /// This is a direct conversion for all /// primitive numeric types. For strings, the input is converted using Single.Parse() with InvariantCulture settings. Otherwise the operation requires and invokes a ToSingle method on the input type. + /// + /// [] val inline single : value:^T -> single when ^T : (static member op_Explicit : ^T -> single) and default ^T : int /// Converts the argument to 64-bit float. + /// /// This is a direct conversion for all /// primitive numeric types. For strings, the input is converted using Double.Parse() with InvariantCulture settings. Otherwise the operation requires and invokes a ToDouble method on the input type. + /// + /// [] val inline double : value:^T -> double when ^T : (static member op_Explicit : ^T -> double) and default ^T : int /// Converts the argument to byte. /// This is a direct conversion for all /// primitive numeric types. For strings, the input is converted using Byte.Parse() on strings and otherwise requires a ToByte method on the input type. + /// + /// [] val inline uint8 : value:^T -> uint8 when ^T : (static member op_Explicit : ^T -> uint8) and default ^T : int @@ -95,15 +144,18 @@ module ExtraTopLevelOperators = /// This is a direct conversion for all /// primitive numeric types. For strings, the input is converted using SByte.Parse() with InvariantCulture settings. /// Otherwise the operation requires and invokes a ToSByte method on the input type. + /// + /// [] val inline int8 : value:^T -> int8 when ^T : (static member op_Explicit : ^T -> int8) and default ^T : int - module Checked = /// Converts the argument to byte. /// This is a direct, checked conversion for all /// primitive numeric types. For strings, the input is converted using Byte.Parse() on strings and otherwise requires a ToByte method on the input type. + /// + /// [] val inline uint8 : value:^T -> byte when ^T : (static member op_Explicit : ^T -> uint8) and default ^T : int @@ -111,38 +163,53 @@ module ExtraTopLevelOperators = /// This is a direct, checked conversion for all /// primitive numeric types. For strings, the input is converted using SByte.Parse() with InvariantCulture settings. /// Otherwise the operation requires and invokes a ToSByte method on the input type. + /// + /// [] val inline int8 : value:^T -> sbyte when ^T : (static member op_Explicit : ^T -> int8) and default ^T : int /// Builds a read-only lookup table from a sequence of key/value pairs. The key objects are indexed using generic hashing and equality. + /// + /// [] val dict : keyValuePairs:seq<'Key * 'Value> -> System.Collections.Generic.IDictionary<'Key,'Value> when 'Key : equality /// Builds a read-only lookup table from a sequence of key/value pairs. The key objects are indexed using generic hashing and equality. + /// + /// [] val readOnlyDict : keyValuePairs:seq<'Key * 'Value> -> System.Collections.Generic.IReadOnlyDictionary<'Key,'Value> when 'Key : equality /// Builds a 2D array from a sequence of sequences of elements. + /// + /// [] val array2D : rows:seq<#seq<'T>> -> 'T[,] /// Special prefix operator for splicing typed expressions into quotation holes. + /// + /// [] val (~%) : expression:Microsoft.FSharp.Quotations.Expr<'T> -> 'T /// Special prefix operator for splicing untyped expressions into quotation holes. + /// + /// [] val (~%%) : expression:Microsoft.FSharp.Quotations.Expr -> 'T /// An active pattern to force the execution of values of type Lazy<_>. + /// + /// [] val (|Lazy|) : input:Lazy<'T> -> 'T /// Builds a query using query syntax and operators. + /// + /// val query : Microsoft.FSharp.Linq.QueryBuilder - namespace Microsoft.FSharp.Core.CompilerServices open System @@ -153,8 +220,12 @@ namespace Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Control open Microsoft.FSharp.Quotations - /// Represents the product of two measure expressions when returned as a generic argument of a provided type. + /// + /// + /// Library functionality for supporting type providers and code generated by the F# compiler. See + /// also F# Type Providers in the F# Language Guide. + /// type MeasureProduct<'Measure1, 'Measure2> /// Represents the inverse of a measure expressions when returned as a generic argument of a provided type. @@ -167,6 +238,7 @@ namespace Microsoft.FSharp.Core.CompilerServices [] type TypeProviderAttribute = inherit System.Attribute + /// Creates an instance of the attribute /// TypeProviderAttribute new : unit -> TypeProviderAttribute @@ -176,43 +248,57 @@ namespace Microsoft.FSharp.Core.CompilerServices | SuppressRelocate = 0x80000000 | IsErased = 0x40000000 - /// Place attribute on runtime assembly to indicate that there is a corresponding design-time - /// assembly that contains a type provider. Runtime and designer assembly may be the same. + /// Place this attribute on a runtime assembly to indicate that there is a corresponding design-time + /// assembly that contains a type provider. Runtime and design-time assembly may be the same. [] type TypeProviderAssemblyAttribute = inherit System.Attribute + /// Creates an instance of the attribute /// TypeProviderAssemblyAttribute new : unit -> TypeProviderAssemblyAttribute + /// Creates an instance of the attribute /// TypeProviderAssemblyAttribute /// The name of the design-time assembly for this type provider. new : assemblyName : string -> TypeProviderAssemblyAttribute + + /// Gets the assembly name. member AssemblyName : string - /// The TypeProviderXmlDocAttribute attribute can be added to types and members. - /// The language service will display the CommentText property from the attribute - /// in the appropriate place when the user hovers over a type or member. + /// A type provider may provide an instance of this attribute to indicate the documentation to show for + /// a provided type or member. [] type TypeProviderXmlDocAttribute = inherit System.Attribute + /// Creates an instance of the attribute /// TypeProviderXmlDocAttribute new : commentText : string -> TypeProviderXmlDocAttribute + + /// Gets the comment text. member CommentText : string + /// A type provider may provide an instance of this attribute to indicate the definition location for a provided type or member. [] type TypeProviderDefinitionLocationAttribute = inherit System.Attribute new : unit -> TypeProviderDefinitionLocationAttribute + + /// Gets or sets the file path for the definition location. member FilePath : string with get, set + + /// Gets or sets the line for the location. member Line : int with get, set + + /// Gets or sets the column for the location. member Column : int with get, set [] /// Indicates that a code editor should hide all System.Object methods from the intellisense menus for instances of a provided type type TypeProviderEditorHideMethodsAttribute = inherit System.Attribute + /// Creates an instance of the attribute /// TypeProviderEditorHideMethodsAttribute new : unit -> TypeProviderEditorHideMethodsAttribute @@ -246,7 +332,6 @@ namespace Microsoft.FSharp.Core.CompilerServices /// Checks if given type exists in target system runtime library member SystemRuntimeContainsType : string -> bool - /// /// Represents a namespace provided by a type provider component. /// @@ -278,32 +363,39 @@ namespace Microsoft.FSharp.Core.CompilerServices inherit System.IDisposable /// - /// Namespace name the this TypeProvider injects types into. + /// Gets the namespaces provided by the type provider. /// abstract GetNamespaces : unit -> IProvidedNamespace[] /// /// Get the static parameters for a provided type. /// + /// /// A type returned by GetTypes or ResolveTypeName + /// /// abstract GetStaticParameters : typeWithoutArguments:Type -> ParameterInfo[] /// /// Apply static arguments to a provided type that accepts static arguments. /// + /// /// The provider must return a type with the given mangled name. + /// /// the provided type definition which has static parameters /// the full path of the type, including encoded representations of static parameters /// the static parameters, indexed by name + /// /// abstract ApplyStaticArguments : typeWithoutArguments:Type * typePathWithArguments:string[] * staticArguments:obj[] -> Type /// /// Called by the compiler to ask for an Expression tree to replace the given MethodBase with. /// + /// /// MethodBase that was given to the compiler by a type returned by a GetType(s) call. /// Expressions that represent the parameters to this call. + /// /// An expression that the compiler will use in place of the given method base. abstract GetInvokerExpression : syntheticMethodBase:MethodBase * parameters:Expr[] -> Expr @@ -324,9 +416,10 @@ namespace Microsoft.FSharp.Core.CompilerServices /// /// Get the static parameters for a provided method. /// + /// /// A method returned by GetMethod on a provided type + /// /// The static parameters of the provided method, if any - abstract GetStaticParametersForMethod : methodWithoutArguments:MethodBase -> ParameterInfo[] /// @@ -336,6 +429,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// the provided method definition which has static parameters /// the full name of the method that must be returned, including encoded representations of static parameters /// the values of the static parameters, indexed by name + /// /// The provided method definition corresponding to the given static parameter values abstract ApplyStaticArgumentsForMethod : methodWithoutArguments:MethodBase * methodNameWithArguments:string * staticArguments:obj[] -> MethodBase diff --git a/src/fsharp/FSharp.Core/list.fs b/src/fsharp/FSharp.Core/list.fs index bf37ab08a19..f99b71013a9 100644 --- a/src/fsharp/FSharp.Core/list.fs +++ b/src/fsharp/FSharp.Core/list.fs @@ -42,11 +42,7 @@ namespace Microsoft.FSharp.Collections [] let concat lists = Microsoft.FSharp.Primitives.Basics.List.concat lists - let inline countByImpl (comparer:IEqualityComparer<'SafeKey>) (projection:'T->'SafeKey) (getKey:'SafeKey->'Key) (list:'T list) = - match list with - | [] -> [] - | _ -> - + let inline countByImpl (comparer:IEqualityComparer<'SafeKey>) (projection:'T->'SafeKey) (getKey:'SafeKey->'Key) (list:'T list) = let dict = Dictionary comparer let rec loop srcList = match srcList with @@ -67,9 +63,12 @@ namespace Microsoft.FSharp.Collections [] let countBy (projection:'T->'Key) (list:'T list) = - if typeof<'Key>.IsValueType - then countByValueType projection list - else countByRefType projection list + match list with + | [] -> [] + | _ -> + if typeof<'Key>.IsValueType + then countByValueType projection list + else countByRefType projection list [] let map mapping list = Microsoft.FSharp.Primitives.Basics.List.map mapping list @@ -171,13 +170,13 @@ namespace Microsoft.FSharp.Collections [] let init length initializer = Microsoft.FSharp.Primitives.Basics.List.init length initializer - let rec initConstAcc n x acc = - if n <= 0 then acc else initConstAcc (n-1) x (x :: acc) - [] let replicate count initial = if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) - initConstAcc count initial [] + let mutable result = [] + for i in 0..count-1 do + result <- initial :: result + result [] let iter2 action list1 list2 = @@ -440,9 +439,12 @@ namespace Microsoft.FSharp.Collections [] let groupBy (projection:'T->'Key) (list:'T list) = - if typeof<'Key>.IsValueType - then groupByValueType projection list - else groupByRefType projection list + match list with + | [] -> [] + | _ -> + if typeof<'Key>.IsValueType + then groupByValueType projection list + else groupByRefType projection list [] let partition predicate list = Microsoft.FSharp.Primitives.Basics.List.partition predicate list @@ -690,3 +692,89 @@ namespace Microsoft.FSharp.Collections [] let unfold<'T, 'State> (generator:'State -> ('T*'State) option) (state:'State) = Microsoft.FSharp.Primitives.Basics.List.unfold generator state + + [] + let removeAt (index: int) (source: 'T list) : 'T list = + if index < 0 then invalidArg "index" "index must be within bounds of the list" + + let mutable i = 0 + let mutable coll = ListCollector() + let mutable curr = source + while i < index do // traverse and save the linked list until item to be removed + match curr with + | [] -> invalidArg "index" "index must be within bounds of the list" + | h::t -> + coll.Add(h) + curr <- t + i <- i + 1 + if curr.IsEmpty then invalidArg "index" "index must be within bounds of the list" + else coll.AddManyAndClose(curr.Tail) // when i = index, Head is the item which is ignored and Tail is the rest of the list + + [] + let removeManyAt (index: int) (count: int) (source: 'T list) : 'T list = + if index < 0 then invalidArg "index" "index must be within bounds of the list" + + let mutable i = 0 + let mutable coll = ListCollector() + let mutable curr = source + while i < index + count do // traverse and save the linked list until the last item to be removed + match curr with + | [] -> invalidArg "index" "index must be within bounds of the list" + | h::t -> + if i < index then coll.Add(h) //items before index we keep + curr <- t + i <- i + 1 + coll.AddManyAndClose(curr) // when i = index + count, we keep the rest of the list + + [] + let updateAt (index: int) (value: 'T) (source: 'T list) : 'T list = + if index < 0 then invalidArg "index" "index must be within bounds of the list" + + let mutable i = 0 + let mutable coll = ListCollector() + let mutable curr = source + while i < index do // Traverse and save the linked list until index + match curr with + | [] -> invalidArg "index" "index must be within bounds of the list" + | h::t -> + coll.Add(h) + curr <- t + i <- i + 1 + coll.Add(value) // add value instead of Head + if curr.IsEmpty then invalidArg "index" "index must be within bounds of the list" + else coll.AddManyAndClose(curr.Tail) + + [] + let insertAt (index: int) (value: 'T) (source: 'T list) : 'T list = + if index < 0 then invalidArg "index" "index must be within bounds of the list" + + let mutable i = 0 + let mutable coll = ListCollector() + let mutable curr = source + while i < index do // traverse and save the linked list until index + match curr with + | [] -> invalidArg "index" "index must be within bounds of the list" + | h::t -> + coll.Add(h) + curr <- t + i <- i + 1 + + coll.Add(value) + coll.AddManyAndClose(curr) // insert item BEFORE the item at the index + + [] + let insertManyAt (index: int) (values: seq<'T>) (source: 'T list) : 'T list = + if index < 0 then invalidArg "index" "index must be within bounds of the list" + + let mutable i = 0 + let mutable coll = ListCollector() + let mutable curr = source + while i < index do // traverse and save the linked list until index + match curr with + | [] -> invalidArg "index" "index must be within bounds of the list" + | h::t -> + coll.Add(h) + curr <- t + i <- i + 1 + coll.AddMany(values) // insert values BEFORE the item at the index + coll.AddManyAndClose(curr) \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/list.fsi b/src/fsharp/FSharp.Core/list.fsi index 26c5dad94e1..0a1c0135d4d 100644 --- a/src/fsharp/FSharp.Core/list.fsi +++ b/src/fsharp/FSharp.Core/list.fsi @@ -2,913 +2,1668 @@ namespace Microsoft.FSharp.Collections - open System - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - /// Basic operations on lists. - [] - [] - module List = - - /// Returns a new list that contains all pairings of elements from the first and second lists. - /// The first input list. - /// The second input list. - /// The resulting list of pairs. - [] - val allPairs: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list - - /// Returns a new list that contains the elements of the first list - /// followed by elements of the second. - /// The first input list. - /// The second input list. - /// The resulting list. - [] - val append: list1:'T list -> list2:'T list -> 'T list - - /// Returns the average of the elements in the list. - /// - /// Raises System.ArgumentException if list is empty. - /// The input list. - /// Thrown when the list is empty. - /// The resulting average. - [] - val inline average : list:^T list -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member DivideByInt : ^T*int -> ^T) - and ^T : (static member Zero : ^T) - - /// Returns the average of the elements generated by applying the function to each element of the list. - /// - /// Raises System.ArgumentException if list is empty. - /// The function to transform the list elements into the type to be averaged. - /// The input list. - /// Thrown when the list is empty. - /// The resulting average. - [] - val inline averageBy : projection:('T -> ^U) -> list:'T list -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member DivideByInt : ^U*int -> ^U) - and ^U : (static member Zero : ^U) - - /// Applies the given function to each element of the list. Returns - /// the list comprised of the results x for each element where - /// the function returns Some(x) - /// The function to generate options from the elements. - /// The input list. - /// The list comprising the values selected from the chooser function. - [] - val choose: chooser:('T -> 'U option) -> list:'T list -> 'U list - - /// Divides the input list into chunks of size at most chunkSize. - /// The maximum size of each chunk. - /// The input list. - /// The list divided into chunks. - /// Thrown when chunkSize is not positive. - [] - val chunkBySize: chunkSize:int -> list:'T list -> 'T list list - - /// For each element of the list, applies the given function. Concatenates all the results and return the combined list. - /// The function to transform each input element into a sublist to be concatenated. - /// The input list. - /// The concatenation of the transformed sublists. - [] - val collect: mapping:('T -> 'U list) -> list:'T list -> 'U list - - /// Compares two lists using the given comparison function, element by element. - /// - /// A function that takes an element from each list and returns an int. - /// If it evaluates to a non-zero value iteration is stopped and that value is returned. - /// The first input list. - /// The second input list. - /// - /// Returns the first non-zero result from the comparison function. If the first list has a - /// larger element, the return value is always positive. If the second list has a larger - /// element, the return value is always negative. When the elements are equal in the two - /// lists, 1 is returned if the first list is longer, 0 is returned if they are equal in - /// length, and -1 is returned when the second list is longer. - [] - val inline compareWith: comparer:('T -> 'T -> int) -> list1:'T list -> list2:'T list -> int - - /// Returns a new list that contains the elements of each the lists in order. - /// The input sequence of lists. - /// The resulting concatenated list. - [] - val concat: lists:seq<'T list> -> 'T list - - /// Tests if the list contains the specified element. - /// The value to locate in the input list. - /// The input list. - /// True if the input list contains the specified element; false otherwise. - [] - val inline contains: value:'T -> source:'T list -> bool when 'T : equality - - /// Returns a list that contains no duplicate entries according to generic hash and - /// equality comparisons on the entries. - /// If an element occurs multiple times in the list then the later occurrences are discarded. - /// - /// The input list. - /// - /// The result list. - [] - val distinct: list:'T list -> 'T list when 'T : equality - - /// Returns a list that contains no duplicate entries according to the - /// generic hash and equality comparisons on the keys returned by the given key-generating function. - /// If an element occurs multiple times in the list then the later occurrences are discarded. - /// - /// A function transforming the list items into comparable keys. - /// The input list. - /// - /// The result list. - [] - val distinctBy: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : equality - - /// Applies a key-generating function to each element of a list and returns a list yielding unique - /// keys and their number of occurrences in the original list. - /// - /// A function transforming each item of the input list into a key to be - /// compared against the others. - /// The input list. - /// - /// The result list. - [] - val countBy : projection:('T -> 'Key) -> list:'T list -> ('Key * int) list when 'Key : equality - - /// Splits the input list into at most count chunks. - /// The maximum number of chunks. - /// The input list. - /// The list split into chunks. - /// Thrown when count is not positive. - [] - val splitInto: count:int -> list:'T list -> 'T list list - - /// Returns an empty list of the given type. - [] - [] - val empty<'T> : 'T list - - /// Returns a new list with the distinct elements of the input list which do not appear in the itemsToExclude sequence, - /// using generic hash and equality comparisons to compare values. - /// - /// A sequence whose elements that also occur in the input list will cause those elements to be - /// removed from the result. - /// A list whose elements that are not also in itemsToExclude will be returned. - /// - /// A list that contains the distinct elements of list that do not appear in itemsToExclude. - /// - /// Thrown when itemsToExclude is null. - [] - val except: itemsToExclude:seq<'T> -> list:'T list -> 'T list when 'T : equality - - /// Returns the only element of the list. - /// - /// The input list. - /// - /// The only element of the list. - /// - /// Thrown when the input does not have precisely one element. - [] - val exactlyOne: list:'T list -> 'T - - /// Returns the only element of the list or None if it is empty or contains more than one element. - /// - /// The input list. - /// - /// The only element of the list or None. - [] - val tryExactlyOne: list:'T list -> 'T option - - /// Tests if any element of the list satisfies the given predicate. - /// - /// The predicate is applied to the elements of the input list. If any application - /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. - /// The function to test the input elements. - /// The input list. - /// True if any element satisfies the predicate. - [] - val exists: predicate:('T -> bool) -> list:'T list -> bool - - /// Tests if any pair of corresponding elements of the lists satisfies the given predicate. - /// - /// The predicate is applied to matching elements in the two collections up to the lesser of the - /// two lengths of the collections. If any application returns true then the overall result is - /// true and no further elements are tested. Otherwise, if one collections is longer - /// than the other then the System.ArgumentException exception is raised. - /// Otherwise, false is returned. - /// The function to test the input elements. - /// The first input list. - /// The second input list. - /// Thrown when the input lists differ in length. - /// True if any pair of elements satisfy the predicate. - [] - val exists2: predicate:('T1 -> 'T2 -> bool) -> list1:'T1 list -> list2:'T2 list -> bool - - /// Returns the first element for which the given function returns True. - /// Raises KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input list. - /// Thrown if the predicate evaluates to false for - /// all the elements of the list. - /// The first element that satisfies the predicate. - [] - val find: predicate:('T -> bool) -> list:'T list -> 'T - - /// Returns the last element for which the given function returns True. - /// Raises KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input list. - /// Thrown if the predicate evaluates to false for - /// all the elements of the list. - /// The last element that satisfies the predicate. - [] - val findBack: predicate:('T -> bool) -> list:'T list -> 'T - - /// Returns the index of the first element in the list - /// that satisfies the given predicate. - /// Raises KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input list. - /// Thrown if the predicate evaluates to false for all the - /// elements of the list. - /// The index of the first element that satisfies the predicate. - [] - val findIndex: predicate:('T -> bool) -> list:'T list -> int - - /// Returns the index of the last element in the list - /// that satisfies the given predicate. - /// Raises KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input list. - /// Thrown if the predicate evaluates to false for all the - /// elements of the list. - /// The index of the last element that satisfies the predicate. - [] - val findIndexBack: predicate:('T -> bool) -> list:'T list -> int - - /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns "true" - /// The function to test the input elements. - /// The input list. - /// A list containing only the elements that satisfy the predicate. - [] - val filter: predicate:('T -> bool) -> list:'T list -> 'T list - - /// Applies a function to each element of the collection, threading an accumulator argument - /// through the computation. Take the second argument, and apply the function to it - /// and the first element of the list. Then feed this result into the function along - /// with the second element and so on. Return the final result. - /// If the input function is f and the elements are i0...iN then - /// computes f (... (f s i0) i1 ...) iN. - /// The function to update the state given the input elements. - /// The initial state. - /// The input list. - /// The final state value. - [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State - - /// Applies a function to corresponding elements of two collections, threading an accumulator argument - /// through the computation. The collections must have identical sizes. - /// If the input function is f and the elements are i0...iN and j0...jN - /// then computes f (... (f s i0 j0)...) iN jN. - /// The function to update the state given the input elements. - /// The initial state. - /// The first input list. - /// The second input list. - /// The final state value. - [] - val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> list1:'T1 list -> list2:'T2 list -> 'State - - /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN then - /// computes f i0 (...(f iN s)). - /// The function to update the state given the input elements. - /// The input list. - /// The initial state. - /// The state object after the folding function is applied to each element of the list. - [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State - - /// Applies a function to corresponding elements of two collections, threading an accumulator argument - /// through the computation. The collections must have identical sizes. - /// If the input function is f and the elements are i0...iN and j0...jN - /// then computes f i0 j0 (...(f iN jN s)). - /// The function to update the state given the input elements. - /// The first input list. - /// The second input list. - /// The initial state. - /// The final state value. - [] - val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> list1:'T1 list -> list2:'T2 list -> state:'State -> 'State - - /// Tests if all elements of the collection satisfy the given predicate. - /// - /// The predicate is applied to the elements of the input list. If any application - /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. - /// The function to test the input elements. - /// The input list. - /// True if all of the elements satisfy the predicate. - [] - val forall: predicate:('T -> bool) -> list:'T list -> bool - - /// Tests if all corresponding elements of the collection satisfy the given predicate pairwise. - /// - /// The predicate is applied to matching elements in the two collections up to the lesser of the - /// two lengths of the collections. If any application returns false then the overall result is - /// false and no further elements are tested. Otherwise, if one collection is longer - /// than the other then the System.ArgumentException exception is raised. - /// Otherwise, true is returned. - /// The function to test the input elements. - /// The first input list. - /// The second input list. - /// Thrown when the input lists differ in length. - /// True if all of the pairs of elements satisfy the predicate. - [] - val forall2: predicate:('T1 -> 'T2 -> bool) -> list1:'T1 list -> list2:'T2 list -> bool - - /// Applies a key-generating function to each element of a list and yields a list of - /// unique keys. Each unique key contains a list of all elements that match - /// to this key. - /// - /// A function that transforms an element of the list into a comparable key. - /// The input list. - /// - /// The result list. - [] - val groupBy : projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list when 'Key : equality - - /// Returns the first element of the list. - /// - /// The input list. - /// Thrown when the list is empty. - /// The first element of the list. - [] - val head: list:'T list -> 'T - - /// Returns a new list whose elements are the corresponding elements - /// of the input list paired with the index (from 0) of each element. - /// The input list. - /// The list of indexed elements. - [] - val indexed: list:'T list -> (int * 'T) list - - /// Creates a list by calling the given generator on each index. - /// The length of the list to generate. - /// The function to generate an element from an index. - /// The list of generated elements. - [] - val init: length:int -> initializer:(int -> 'T) -> 'T list - - /// Returns true if the list contains no elements, false otherwise. - /// The input list. - /// True if the list is empty. - [] - val isEmpty: list:'T list -> bool - - /// Indexes into the list. The first element has index 0. - /// The index to retrieve. - /// The input list. - /// The value at the given index. - /// Thrown when the index is negative or the input list does not contain enough elements. - [] - val item: index:int -> list:'T list -> 'T - - /// Applies the given function to each element of the collection. - /// The function to apply to elements from the input list. - /// The input list. - [] - val inline iter: action:('T -> unit) -> list:'T list -> unit - - /// Applies the given function to two collections simultaneously. The - /// collections must have identical size. - /// The function to apply to pairs of elements from the input lists. - /// The first input list. - /// The second input list. - [] - val iter2: action:('T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit - - /// Applies the given function to each element of the collection. The integer passed to the - /// function indicates the index of element. - /// The function to apply to the elements of the list along with their index. - /// The input list. - [] - val inline iteri: action:(int -> 'T -> unit) -> list:'T list -> unit - - /// Applies the given function to two collections simultaneously. The - /// collections must have identical size. The integer passed to the - /// function indicates the index of element. - /// The function to apply to a pair of elements from the input lists along with their index. - /// The first input list. - /// The second input list. - [] - val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit - - /// Returns the last element of the list. - /// The input list. - /// The last element of the list. - /// Thrown when the input does not have any elements. - [] - val last: list:'T list -> 'T - - /// Returns the length of the list. - /// The input list. - /// The length of the list. - [] - val length: list:'T list -> int - - /// Returns the last element of the list. - /// Return None if no such element exists. - /// The input list. - /// The last element of the list or None. - [] - val tryLast: list:'T list -> 'T option - - /// Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. - /// The function to transform elements from the input list. - /// The input list. - /// The list of transformed elements. - [] - val map: mapping:('T -> 'U) -> list:'T list -> 'U list - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding elements of the two collections pairwise. - /// The function to transform pairs of elements from the input lists. - /// The first input list. - /// The second input list. - /// The list of transformed elements. - [] - val map2: mapping:('T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding elements of the three collections simultaneously. - /// The function to transform triples of elements from the input lists. - /// The first input list. - /// The second input list. - /// The third input list. - /// The list of transformed elements. - [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> 'U list - - /// Combines map and fold. Builds a new list whose elements are the results of applying the given function - /// to each of the elements of the input list. The function is also used to accumulate a final value. - /// The function to transform elements from the input list and accumulate the final value. - /// The initial state. - /// The input list. - /// The list of transformed elements, and the final accumulated value. - [] - val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> list:'T list -> 'Result list * 'State - - /// Combines map and foldBack. Builds a new list whose elements are the results of applying the given function - /// to each of the elements of the input list. The function is also used to accumulate a final value. - /// The function to transform elements from the input list and accumulate the final value. - /// The input list. - /// The initial state. - /// The list of transformed elements, and the final accumulated value. - [] - val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> list:'T list -> state:'State -> 'Result list * 'State - - /// Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The integer index passed to the - /// function indicates the index (from 0) of element being transformed. - /// The function to transform elements and their indices. - /// The input list. - /// The list of transformed elements. - [] - val mapi: mapping:(int -> 'T -> 'U) -> list:'T list -> 'U list - - /// Like mapi, but mapping corresponding elements from two lists of equal length. - /// The function to transform pairs of elements from the two lists and their index. - /// The first input list. - /// The second input list. - /// The list of transformed elements. - [] - val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list - - /// Return the greatest of all elements of the list, compared via Operators.max. - /// - /// Raises System.ArgumentException if list is empty - /// The input list. - /// Thrown when the list is empty. - /// The maximum element. - [] - val inline max : list:'T list -> 'T when 'T : comparison - - /// Returns the greatest of all elements of the list, compared via Operators.max on the function result. - /// - /// Raises System.ArgumentException if list is empty. - /// The function to transform the list elements into the type to be compared. - /// The input list. - /// Thrown when the list is empty. - /// The maximum element. - [] - val inline maxBy : projection:('T -> 'U) -> list:'T list -> 'T when 'U : comparison - - /// Returns the lowest of all elements of the list, compared via Operators.min. - /// - /// Raises System.ArgumentException if list is empty - /// The input list. - /// Thrown when the list is empty. - /// The minimum value. - [] - val inline min : list:'T list -> 'T when 'T : comparison - - /// Returns the lowest of all elements of the list, compared via Operators.min on the function result - /// - /// Raises System.ArgumentException if list is empty. - /// The function to transform list elements into the type to be compared. - /// The input list. - /// Thrown when the list is empty. - /// The minimum value. - [] - val inline minBy : projection:('T -> 'U) -> list:'T list -> 'T when 'U : comparison - - /// Indexes into the list. The first element has index 0. - /// The input list. - /// The index to retrieve. - /// The value at the given index. - /// Thrown when the index is negative or the input list does not contain enough elements. - [] - [] - val nth: list:'T list -> index:int -> 'T - - /// Builds a list from the given array. - /// The input array. - /// The list of elements from the array. - [] - val ofArray : array:'T[] -> 'T list - - /// Builds a new list from the given enumerable object. - /// The input sequence. - /// The list of elements from the sequence. - [] - val ofSeq: source:seq<'T> -> 'T list - - /// Returns a list of each element in the input list and its predecessor, with the - /// exception of the first element which is only returned as the predecessor of the second element. - /// - /// The input list. - /// - /// The result list. - [] - val pairwise: list:'T list -> ('T * 'T) list - - /// Splits the collection into two collections, containing the - /// elements for which the given predicate returns True and False - /// respectively. Element order is preserved in both of the created lists. - /// The function to test the input elements. - /// The input list. - /// A list containing the elements for which the predicate evaluated to false and a list - /// containing the elements for which the predicate evaluated to true. - [] - val partition: predicate:('T -> bool) -> list:'T list -> ('T list * 'T list) - - /// Applies the given function to successive elements, returning the first - /// result where function returns Some(x) for some x. If no such - /// element exists then raise System.Collections.Generic.KeyNotFoundException - /// The function to generate options from the elements. - /// The input list. - /// Thrown when the list is empty. - /// The first resulting value. - [] - val pick: chooser:('T -> 'U option) -> list:'T list -> 'U - - /// Returns a list with all elements permuted according to the - /// specified permutation. - /// The function to map input indices to output indices. - /// The input list. - /// The permuted list. - /// Thrown when indexMap does not produce a valid permutation. - [] - val permute : indexMap:(int -> int) -> list:'T list -> 'T list - - /// Apply a function to each element of the collection, threading an accumulator argument - /// through the computation. Apply the function to the first two elements of the list. - /// Then feed this result into the function along with the third element and so on. - /// Return the final result. If the input function is f and the elements are i0...iN then computes - /// f (... (f i0 i1) i2 ...) iN. - /// - /// Raises System.ArgumentException if list is empty - /// The function to reduce two list elements to a single element. - /// The input list. - /// Thrown when the list is empty. - /// The final reduced value. - [] - val reduce: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T - - /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN then computes - /// f i0 (...(f iN-1 iN)). - /// A function that takes in the next-to-last element of the list and the - /// current accumulated result to produce the next accumulated result. - /// The input list. - /// Thrown when the list is empty. - /// The final result of the reductions. - [] - val reduceBack: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T - - /// Creates a list by replicating the given initial value. - /// The number of elements to replicate. - /// The value to replicate - /// The generated list. - [] - val replicate: count:int -> initial:'T -> 'T list - - /// Returns a new list with the elements in reverse order. - /// The input list. - /// The reversed list. - [] - val rev: list:'T list -> 'T list - - /// Applies a function to each element of the collection, threading an accumulator argument - /// through the computation. Take the second argument, and apply the function to it - /// and the first element of the list. Then feed this result into the function along - /// with the second element and so on. Returns the list of intermediate results and the final result. - /// The function to update the state given the input elements. - /// The initial state. - /// The input list. - /// The list of states. - [] - val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State list - - /// Like foldBack, but returns both the intermediary and final results - /// The function to update the state given the input elements. - /// The input list. - /// The initial state. - /// The list of states. - [] - val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State list - - /// Returns a list that contains one item only. - /// - /// The input item. - /// - /// The result list of one item. - [] - val inline singleton: value:'T -> 'T list - - /// Returns the list after removing the first N elements. - /// The number of elements to skip. - /// The input list. - /// The list after removing the first N elements. - /// Thrown when count is negative or exceeds the number of - /// elements in the list. - [] - val skip: count:int -> list: 'T list -> 'T list - - /// Bypasses elements in a list while the given predicate returns True, and then returns - /// the remaining elements of the list. - /// A function that evaluates an element of the list to a boolean value. - /// The input list. - /// The result list. - [] - val skipWhile: predicate:('T -> bool) -> list:'T list -> 'T list - - /// Sorts the given list using the given comparison function. - /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. - /// The function to compare the list elements. - /// The input list. - /// The sorted list. - [] - val sortWith: comparer:('T -> 'T -> int) -> list:'T list -> 'T list - - /// Sorts the given list using keys given by the given projection. Keys are compared using Operators.compare. - /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. - /// The function to transform the list elements into the type to be compared. - /// The input list. - /// The sorted list. - [] - val sortBy: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : comparison - - /// Sorts the given list using Operators.compare. - /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. - /// The input list. - /// The sorted list. - [] - val sort: list:'T list -> 'T list when 'T : comparison - - /// Splits a list into two lists, at the given index. - /// The index at which the list is split. - /// The input list. - /// The two split lists. - /// - /// Thrown when split index exceeds the number of elements - /// in the list. - [] - val splitAt: index:int -> list:'T list -> ('T list * 'T list) - - /// Sorts the given list in descending order using keys given by the given projection. Keys are compared using Operators.compare. - /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. - /// The function to transform the list elements into the type to be compared. - /// The input list. - /// The sorted list. - [] - val inline sortByDescending: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : comparison - - /// Sorts the given list in descending order using Operators.compare. - /// - /// This is a stable sort, i.e. the original order of equal elements is preserved. - /// The input list. - /// The sorted list. - [] - val inline sortDescending: list:'T list -> 'T list when 'T : comparison - - /// Returns the sum of the elements in the list. - /// The input list. - /// The resulting sum. - [] - val inline sum : list:^T list -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member Zero : ^T) - - /// Returns the sum of the results generated by applying the function to each element of the list. - /// The function to transform the list elements into the type to be summed. - /// The input list. - /// The resulting sum. - [] - val inline sumBy : projection:('T -> ^U) -> list:'T list -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member Zero : ^U) - - /// Returns the list after removing the first element. - /// - /// The input list. - /// Thrown when the list is empty. - /// The list after removing the first element. - [] - val tail: list:'T list -> 'T list - - /// Returns the first N elements of the list. - /// Throws InvalidOperationException - /// if the count exceeds the number of elements in the list. List.truncate - /// returns as many items as the list contains instead of throwing an exception. - /// - /// The number of items to take. - /// The input list. - /// - /// The result list. - /// - /// Thrown when the input list is empty. - /// Thrown when count exceeds the number of elements - /// in the list. - [] - val take: count:int -> list:'T list -> 'T list - - /// Returns a list that contains all elements of the original list while the - /// given predicate returns True, and then returns no further elements. - /// - /// A function that evaluates to false when no more items should be returned. - /// The input list. - /// - /// The result list. - [] - val takeWhile: predicate:('T -> bool) -> list:'T list -> 'T list - - /// Builds an array from the given list. - /// The input list. - /// The array containing the elements of the list. - [] - val toArray: list:'T list -> 'T[] - - /// Views the given list as a sequence. - /// The input list. - /// The sequence of elements in the list. - [] - val toSeq: list:'T list -> seq<'T> - - /// Returns the first element of the list, or - /// None if the list is empty. - /// The input list. - /// The first element of the list or None. - [] - val tryHead: list:'T list -> 'T option - - /// Returns the transpose of the given sequence of lists. - /// The input sequence of list. - /// The transposed list. - /// Thrown when the input sequence is null. - /// Thrown when the input lists differ in length. - [] - val transpose: lists:seq<'T list> -> 'T list list - - /// Returns at most N elements in a new list. - /// The maximum number of items to return. - /// The input list. - /// The result list. - [] - val truncate: count:int -> list:'T list -> 'T list - - /// Applies the given function to successive elements, returning Some(x) the first - /// result where function returns Some(x) for some x. If no such element - /// exists then return None. - /// The function to generate options from the elements. - /// The input list. - /// The first resulting value or None. - [] - val tryPick: chooser:('T -> 'U option) -> list:'T list -> 'U option - - /// Returns the first element for which the given function returns True. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input list. - /// The first element for which the predicate returns true, or None if - /// every element evaluates to false. - [] - val tryFind: predicate:('T -> bool) -> list:'T list -> 'T option - - /// Returns the last element for which the given function returns True. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input list. - /// The last element for which the predicate returns true, or None if - /// every element evaluates to false. - [] - val tryFindBack: predicate:('T -> bool) -> list:'T list -> 'T option - - /// Returns the index of the first element in the list - /// that satisfies the given predicate. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input list. - /// The index of the first element for which the predicate returns true, or None if - /// every element evaluates to false. - [] - val tryFindIndex: predicate:('T -> bool) -> list:'T list -> int option - - /// Tries to find the nth element in the list. - /// Returns None if index is negative or the list does not contain enough elements. - /// The index to retrieve. - /// The input list. - /// The value at the given index or None. - [] - val tryItem: index:int -> list:'T list -> 'T option - - /// Returns the index of the last element in the list - /// that satisfies the given predicate. - /// Return None if no such element exists. - /// The function to test the input elements. - /// The input list. - /// The index of the last element for which the predicate returns true, or None if - /// every element evaluates to false. - [] - val tryFindIndexBack: predicate:('T -> bool) -> list:'T list -> int option - - /// Returns a list that contains the elements generated by the given computation. - /// The given initial state argument is passed to the element generator. - /// A function that takes in the current state and returns an option tuple of the next - /// element of the list and the next state value. - /// The initial state value. - /// The result list. - [] - val unfold<'T,'State> : generator:('State -> ('T * 'State) option) -> state:'State -> 'T list - - /// Splits a list of pairs into two lists. - /// The input list. - /// Two lists of split elements. - [] - val unzip: list:('T1 * 'T2) list -> ('T1 list * 'T2 list) - - /// Splits a list of triples into three lists. - /// The input list. - /// Three lists of split elements. - [] - val unzip3: list:('T1 * 'T2 * 'T3) list -> ('T1 list * 'T2 list * 'T3 list) - - /// Returns a new list containing only the elements of the list - /// for which the given predicate returns "true" - /// The function to test the input elements. - /// The input list. - /// A list containing only the elements that satisfy the predicate. - [] - val where: predicate:('T -> bool) -> list:'T list -> 'T list - - /// Returns a list of sliding windows containing elements drawn from the input - /// list. Each window is returned as a fresh list. - /// The number of elements in each window. - /// The input list. - /// The result list. - /// Thrown when windowSize is not positive. - [] - val windowed : windowSize:int -> list:'T list -> 'T list list - - /// Combines the two lists into a list of pairs. The two lists must have equal lengths. - /// The first input list. - /// The second input list. - /// A single list containing pairs of matching elements from the input lists. - [] - val zip: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list - - /// Combines the three lists into a list of triples. The lists must have equal lengths. - /// The first input list. - /// The second input list. - /// The third input list. - /// A single list containing triples of matching elements from the input lists. - [] - val zip3: list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> ('T1 * 'T2 * 'T3) list +open System +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +/// Contains operations for working with values of type . +/// +/// Operations for collections such as lists, arrays, sets, maps and sequences. See also +/// F# Collection Types in the F# Language Guide. +/// +[] +[] +module List = + + /// Returns a new list that contains all pairings of elements from the first and second lists. + /// + /// The first input list. + /// The second input list. + /// + /// The resulting list of pairs. + /// + /// + /// + /// let people = ["Kirk"; "Spock"; "McCoy"] + /// let numbers = [1;2] + /// people |> List.allPairs numbers + /// + /// The sample evaluates to + /// + /// [(1, "Kirk"); (1, "Spock"); (1, "McCoy"); (2, "Kirk"); (2, "Spock"); (2, "McCoy")] + /// + /// + [] + val allPairs: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list + + /// Returns a new list that contains the elements of the first list + /// followed by elements of the second. + /// + /// The first input list. + /// The second input list. + /// + /// The resulting list. + /// + /// + /// + /// List.append [1..3] [4..7] // evaluates [1; 2; 3; 4; 5; 6; 7] + /// + /// [4..7] |> List.append [1..3] // evaluates [1; 2; 3; 4; 5; 6; 7] + /// + /// + [] + val append: list1: 'T list -> list2: 'T list -> 'T list + + /// Returns the average of the elements in the list. + /// + /// Raises if list is empty. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The resulting average. + /// + /// + /// + /// [1.0 .. 9.0] |> List.average // evaluates 5.0 + /// + /// + /// + /// + /// + /// [1 .. 9] |> List.average + /// + /// The sample does not compile because The type 'int' does not support the operator 'DivideByInt' + /// (see averageBy examples for a solution) + /// + [] + val inline average : list:^T list -> ^T + when ^T : (static member (+) : ^T * ^T -> ^T) + and ^T : (static member DivideByInt : ^T*int -> ^T) + and ^T : (static member Zero : ^T) + + /// Returns the average of the elements generated by applying the function to each element of the list. + /// + /// Raises if list is empty. + /// The function to transform the list elements into the type to be averaged. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The resulting average. + /// + /// Average the age of persons by extracting the age from records + /// + /// type People = { + /// name: string + /// age: int } + /// let getAgeAsFloat person = float person.age + /// let people = + /// [ { name = "Kirk"; age = 26 } + /// { name = "Spock"; age = 90 } + /// { name = "McCoy"; age = 37 } ] + /// people |> List.averageBy getAgeAsFloat // evaluates 51.0 + /// + /// + /// + /// Average a list of integer numbers by converting to float + /// + /// [1 .. 9] |> List.averageBy float // evaluates 5.0 + /// + /// + [] + val inline averageBy: projection:('T -> ^U) -> list:'T list -> ^U + when ^U : (static member (+) : ^U * ^U -> ^U) + and ^U : (static member DivideByInt : ^U*int -> ^U) + and ^U : (static member Zero : ^U) + + /// Applies the given function to each element of the list. Returns + /// the list comprised of the results x for each element where + /// the function returns Some(x) + /// + /// The function to generate options from the elements. + /// The input list. + /// + /// The list comprising the values selected from the chooser function. + /// + /// + /// + /// type Happiness = AlwaysHappy | MostOfTheTimeGrumpy + /// type People = { + /// name: string + /// happiness: Happiness } + /// let takeJustHappyPersons person = + /// match person.happiness with + /// | AlwaysHappy -> Some person.name + /// | MostOfTheTimeGrumpy -> None + /// let candidatesForTheTrip = + /// [ { name = "SpongeBob"; happiness = AlwaysHappy } + /// { name = "Patrick"; happiness = AlwaysHappy } + /// { name = "Squidward"; happiness = MostOfTheTimeGrumpy } ] + /// candidatesForTheTrip |> List.choose takeJustHappyPersons + /// + /// The sample evaluates to [ "SpongeBob"; "Patrick" ] + /// + /// + /// + /// + /// // Using the identity function "id" (is defined like fun x -> x) + /// let input1 = [ Some 1; None; Some 3; None ] + /// input1 |> List.choose id // evaluates [1; 3] + /// + /// let input2: int option list = [] + /// input2 |> List.choose id // evaluates [] (notice that has the type "int list") + /// + /// let input3: string option list =[ None; None ] + /// input3 |> List.choose id // evaluates [] (notice that has the type "string list") + /// + /// + [] + val choose: chooser:('T -> 'U option) -> list:'T list -> 'U list + + /// Divides the input list into chunks of size at most chunkSize. + /// + /// The maximum size of each chunk. + /// The input list. + /// + /// The list divided into chunks. + /// + /// Thrown when chunkSize is not positive. + /// + /// + /// + /// [1 .. 10 ] |> List.chunkBySize 3 // evaluates + /// + /// Evaluates to [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]; [10]] . Please notice the last chunk. + /// + /// + /// let output2 = [1 .. 5 ] |> List.chunkBySize 10 + /// + /// Evaluates to [[1; 2; 3; 4; 5]] + /// + /// + /// let input : string list = [] + /// let output3 = input |> List.chunkBySize 10 + /// + /// Evaluates to []. Please notice that has the type string list list. + /// + [] + val chunkBySize: chunkSize:int -> list:'T list -> 'T list list + + /// For each element of the list, applies the given function. Concatenates all the results and return the combined list. + /// + /// The function to transform each input element into a sublist to be concatenated. + /// The input list. + /// + /// The concatenation of the transformed sublists. + /// + /// For each positive number in the array we are generating all the previous positive numbers + /// + /// [1..4] |> List.collect (fun x -> [1..x]) + /// + /// The sample evaluates to [1; 1; 2; 1; 2; 3; 1; 2; 3; 4] (added extra spaces for easy reading) + /// + [] + val collect: mapping:('T -> 'U list) -> list:'T list -> 'U list + + /// Compares two lists using the given comparison function, element by element. + /// + /// A function that takes an element from each list and returns an int. + /// If it evaluates to a non-zero value iteration is stopped and that value is returned. + /// The first input list. + /// The second input list. + /// + /// Returns the first non-zero result from the comparison function. If the first list has a + /// larger element, the return value is always positive. If the second list has a larger + /// element, the return value is always negative. When the elements are equal in the two + /// lists, 1 is returned if the first list is longer, 0 is returned if they are equal in + /// length, and -1 is returned when the second list is longer. + /// + /// + [] + val inline compareWith: comparer:('T -> 'T -> int) -> list1:'T list -> list2:'T list -> int + + /// Returns a new list that contains the elements of each the lists in order. + /// + /// The input sequence of lists. + /// + /// The resulting concatenated list. + /// + /// + /// + /// let input = [ [1;2] + /// [3;4;5] + /// [6;7;8;9] ] + /// input |> List.concat // evaluates [1; 2; 3; 4; 5; 6; 7; 8; 9] + /// + /// + [] + val concat: lists:seq<'T list> -> 'T list + + /// Tests if the list contains the specified element. + /// + /// The value to locate in the input list. + /// The input list. + /// + /// True if the input list contains the specified element; false otherwise. + /// + /// + /// + /// [1..9] |> List.contains 0 // evaluates false + /// + /// [1..9] |> List.contains 3 // evaluates true + /// + /// let input = [1, "SpongeBob"; 2, "Patrick"; 3, "Squidward"; 4, "Mr. Krabs"] + /// input |> List.contains (2, "Patrick") // evaluates true + /// input |> List.contains (22, "Patrick") // evaluates false + /// + /// + [] + val inline contains: value:'T -> source:'T list -> bool when 'T : equality + + /// Returns a list that contains no duplicate entries according to generic hash and + /// equality comparisons on the entries. + /// If an element occurs multiple times in the list then the later occurrences are discarded. + /// + /// The input list. + /// + /// The result list. + /// + /// + /// + /// let input = [6;1;2;3;1;4;5;5] + /// input |> List.distinct // evaluates [6; 1; 2; 3; 4; 5] + /// + /// + [] + val distinct: list:'T list -> 'T list when 'T : equality + + /// Returns a list that contains no duplicate entries according to the + /// generic hash and equality comparisons on the keys returned by the given key-generating function. + /// If an element occurs multiple times in the list then the later occurrences are discarded. + /// + /// A function transforming the list items into comparable keys. + /// The input list. + /// + /// The result list. + /// + /// + /// + /// let isEven x = 0 = x % 2 + /// let input = [6;1;2;3;1;4;5;5] + /// input |> List.distinctBy isEven // evaluates [6; 1] + /// + /// + [] + val distinctBy: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : equality + + /// Applies a key-generating function to each element of a list and returns a list yielding unique + /// keys and their number of occurrences in the original list. + /// + /// A function transforming each item of the input list into a key to be + /// compared against the others. + /// The input list. + /// + /// The result list. + /// + /// Counting the number of occurrences of chars + /// + /// let input = ['H'; 'a'; 'p'; 'p'; 'i'; 'n'; 'e'; 's'; 's'] + /// input |> List.countBy id + /// + /// Evalutes [('H', 1); ('a', 1); ('p', 2); ('i', 1); ('n', 1); ('e', 1); ('s', 2)] + /// + [] + val countBy : projection:('T -> 'Key) -> list:'T list -> ('Key * int) list when 'Key : equality + + /// Splits the input list into at most count chunks. + /// + /// The maximum number of chunks. + /// The input list. + /// + /// The list split into chunks. + /// + /// Thrown when count is not positive. + /// + /// + /// + /// [1..10] |> List.splitInto 2 // evaluates [[1; 2; 3; 4; 5]; [6; 7; 8; 9; 10]] + /// [1..10] |> List.splitInto 4 // evaluates [[1; 2; 3]; [4; 5; 6]; [7; 8]; [9; 10]] + /// + /// + [] + val splitInto: count:int -> list:'T list -> 'T list list + + /// Returns an empty list of the given type. + [] + [] + val empty<'T> : 'T list + + /// Returns a new list with the distinct elements of the input list which do not appear in the itemsToExclude sequence, + /// using generic hash and equality comparisons to compare values. + /// + /// A sequence whose elements that also occur in the input list will cause those elements to be + /// removed from the result. + /// A list whose elements that are not also in itemsToExclude will be returned. + /// + /// A list that contains the distinct elements of list that do not appear in itemsToExclude. + /// + /// Thrown when itemsToExclude is null. + /// + /// + /// + /// let input = [1, "Kirk"; 2, "Spock"; 3, "Kenobi"] + /// input |> List.except [3, "Kenobi"] // evaluates [(1, "Kirk"); (2, "Spock")] + /// + /// + /// + /// + /// + /// [0..10] |> List.except [1..5] // evaluates [0; 6; 7; 8; 9; 10] + /// [1..5] |> List.except [0..10] // evaluates [] + /// + /// + [] + val except: itemsToExclude:seq<'T> -> list:'T list -> 'T list when 'T : equality + + /// Returns the only element of the list. + /// + /// The input list. + /// + /// The only element of the list. + /// + /// Thrown when the input does not have precisely one element. + /// + /// + /// + /// ["the chosen one"] |> List.exactlyOne // evaluates "the chosen one" + /// + /// + /// + /// + /// + /// let input : string list = [] + /// input |> List.exactlyOne + /// + /// Will throw the exception: System.ArgumentException: The input sequence was empty + /// + /// + /// + /// + /// [1..5] |> List.exactlyOne + /// + /// Will throw the exception: System.ArgumentException: The input sequence contains more than one element + /// + [] + val exactlyOne: list:'T list -> 'T + + /// Returns the only element of the list or None if it is empty or contains more than one element. + /// + /// The input list. + /// + /// The only element of the list or None. + /// + /// + /// + /// [1] |> List.tryExactlyOne // evaluates Some 1 + /// [1;2] |> List.tryExactlyOne // evaluates None + /// ([] : int list) |> List.tryExactlyOne // evaluates None + /// + /// + [] + val tryExactlyOne: list:'T list -> 'T option + + /// Tests if any element of the list satisfies the given predicate. + /// + /// The predicate is applied to the elements of the input list. If any application + /// returns true then the overall result is true and no further elements are tested. + /// Otherwise, false is returned. + /// The function to test the input elements. + /// The input list. + /// + /// True if any element satisfies the predicate. + /// + /// + /// + /// let input = [1, "Kirk"; 2, "Spock"; 3, "Kenobi"] + /// + /// input |> List.exists (fun x -> x = (3, "Kenobi")) // evaluates true + /// + /// input |> List.exists (fun (n, name) -> n > 5) // evaluates false + /// + /// + [] + val exists: predicate:('T -> bool) -> list:'T list -> bool + + /// Tests if any pair of corresponding elements of the lists satisfies the given predicate. + /// + /// The predicate is applied to matching elements in the two collections up to the lesser of the + /// two lengths of the collections. If any application returns true then the overall result is + /// true and no further elements are tested. Otherwise, if one collections is longer + /// than the other then the exception is raised. + /// Otherwise, false is returned. + /// + /// The function to test the input elements. + /// The first input list. + /// The second input list. + /// + /// Thrown when the input lists differ in length. + /// + /// True if any pair of elements satisfy the predicate. + /// + /// Check if the sum of pairs (from 2 different lists) have at least one even number + /// + /// let anEvenSum a b = 0 = (a + b) % 2 + /// + /// ([1..4], [2..5]) + /// ||> List.exists2 anEvenSum // evaluates false + /// + /// ([1..4], [2;4;5;6]) + /// ||> List.exists2 anEvenSum // evaluates true + /// + /// + [] + val exists2: predicate:('T1 -> 'T2 -> bool) -> list1:'T1 list -> list2:'T2 list -> bool + + /// Returns the first element for which the given function returns True. + /// Raises KeyNotFoundException if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// Thrown if the predicate evaluates to false for + /// all the elements of the list. + /// + /// The first element that satisfies the predicate. + /// + /// + /// + /// let isEven x = 0 = x % 2 + /// let isGreaterThan x y = y > x + /// let input = [1, "Luke"; 2, "Kirk"; 3, "Spock"; 4, "Kenobi"] + /// + /// input |> List.find (fun (x,_) -> isEven x) // evaluates (2, "Kirk") + /// input |> List.find (fun (x,_) -> x |> isGreaterThan 6) // raises an exception + /// + /// + [] + val find: predicate:('T -> bool) -> list:'T list -> 'T + + /// Returns the last element for which the given function returns True. + /// Raises KeyNotFoundException if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// Thrown if the predicate evaluates to false for + /// all the elements of the list. + /// + /// The last element that satisfies the predicate. + /// + /// + /// + /// let isEven x = 0 = x % 2 + /// let isGreaterThan x y = y > x + /// let input = [1, "Luke"; 2, "Kirk"; 3, "Spock"; 4, "Kenobi"] + /// + /// input |> List.findBack (fun (x,_) -> isEven x) // evaluates (4, "Kenobi") + /// input |> List.findBack (fun (x,_) -> x |> isGreaterThan 6) // raises an exception + /// + /// + [] + val findBack: predicate:('T -> bool) -> list:'T list -> 'T + + /// Returns the index of the first element in the list + /// that satisfies the given predicate. + /// Raises KeyNotFoundException if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// Thrown if the predicate evaluates to false for all the + /// elements of the list. + /// + /// The index of the first element that satisfies the predicate. + /// + /// + /// + /// let isEven x = 0 = x % 2 + /// let isGreaterThan x y = y > x + /// let input = [1, "Luke"; 2, "Kirk"; 3, "Spock"; 4, "Kenobi"] + /// + /// input |> List.findIndex (fun (x,_) -> isEven x) // evaluates 1 + /// input |> List.findIndex (fun (x,_) -> x |> isGreaterThan 6) // raises an exception + /// + /// + [] + val findIndex: predicate:('T -> bool) -> list:'T list -> int + + /// Returns the index of the last element in the list + /// that satisfies the given predicate. + /// Raises KeyNotFoundException if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// Thrown if the predicate evaluates to false for all the + /// elements of the list. + /// + /// The index of the last element that satisfies the predicate. + /// + /// + /// + /// let isEven x = 0 = x % 2 + /// let isGreaterThan x y = y > x + /// let input = [1, "Luke"; 2, "Kirk"; 3, "Spock"; 4, "Kenobi"] + /// + /// input |> List.findIndexBack (fun (x,_) -> isEven x) // evaluates 3 + /// input |> List.findIndexBack (fun (x,_) -> x |> isGreaterThan 6) // raises an exception + /// + /// + [] + val findIndexBack: predicate:('T -> bool) -> list:'T list -> int + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns "true" + /// + /// The function to test the input elements. + /// The input list. + /// + /// A list containing only the elements that satisfy the predicate. + /// + /// + /// + /// let input = [1, "Luke"; 2, "Kirk"; 3, "Kenobi"; 4, "Spock"] + /// let isComingFromStarTrek (x,_) = isEven x + /// + /// input |> List.filter isComingFromStarTrek + /// + /// Evaluates to [(2, "Kirk"); (4, "Spock")] + /// + [] + val filter: predicate:('T -> bool) -> list:'T list -> 'T list + + /// Applies a function to each element of the collection, threading an accumulator argument + /// through the computation. Take the second argument, and apply the function to it + /// and the first element of the list. Then feed this result into the function along + /// with the second element and so on. Return the final result. + /// If the input function is f and the elements are i0...iN then + /// computes f (... (f s i0) i1 ...) iN. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The input list. + /// + /// The final state value. + /// + /// Making the sum of squares for the first 5 natural numbers + /// + /// (0, [1..5]) ||> List.fold (fun s v -> s + v * v) // evaluates 55 + /// + /// + /// + /// Shopping for fruits hungry, you tend to take more of each as the hunger grows + /// + /// type Fruit = Apple | Pear | Orange + /// type BagItem = { fruit: Fruit; quantity: int } + /// let takeMore (previous: BagItem list) fruit = + /// let toTakeThisTime = + /// match previous with + /// | bagItem :: otherBagItems -> bagItem.quantity + 1 + /// | [] -> 1 + /// { fruit = fruit; quantity = toTakeThisTime } :: previous + /// let input = [ Apple; Pear; Orange ] + /// + /// ([], input) ||> List.fold takeMore + /// + /// Evaluates to + /// + /// [{ fruit = Orange; quantity = 3 } + /// { fruit = Pear; quantity = 2 } + /// { fruit = Apple; quantity = 1 }] + /// + /// + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State + + /// Applies a function to corresponding elements of two collections, threading an accumulator argument + /// through the computation. The collections must have identical sizes. + /// If the input function is f and the elements are i0...iN and j0...jN + /// then computes f (... (f s i0 j0)...) iN jN. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The first input list. + /// The second input list. + /// + /// The final state value. + /// + /// + [] + val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> list1:'T1 list -> list2:'T2 list -> 'State + + /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN then + /// computes f i0 (...(f iN s)). + /// + /// The function to update the state given the input elements. + /// The input list. + /// The initial state. + /// + /// The state object after the folding function is applied to each element of the list. + /// + /// Making the sum of squares for the first 5 natural numbers + /// + /// ([1..5], 0) ||> List.foldBack (fun v s -> s + v * v) // evaluates 55 + /// + /// + /// + /// Shopping for fruits hungry, you tend to take more of each as the hunger grows + /// + /// type Fruit = Apple | Pear | Orange + /// type BagItem = { fruit: Fruit; quantity: int } + /// let takeMore fruit (previous: BagItem list) = + /// let toTakeThisTime = + /// match previous with + /// | bagItem :: otherBagItems -> bagItem.quantity + 1 + /// | [] -> 1 + /// { fruit = fruit; quantity = toTakeThisTime } :: previous + /// let input = [ Apple; Pear; Orange ] + /// + /// (input, []) ||> List.foldBack takeMore + /// + /// Evaluates to + /// + /// [{ fruit = Apple; quantity = 3 } + /// { fruit = Pear; quantity = 2 } + /// { fruit = Orange; quantity = 1 }] + /// + /// + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State + + /// Applies a function to corresponding elements of two collections, threading an accumulator argument + /// through the computation. The collections must have identical sizes. + /// If the input function is f and the elements are i0...iN and j0...jN + /// then computes f i0 j0 (...(f iN jN s)). + /// + /// The function to update the state given the input elements. + /// The first input list. + /// The second input list. + /// The initial state. + /// + /// The final state value. + /// + /// + [] + val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> list1:'T1 list -> list2:'T2 list -> state:'State -> 'State + + /// Tests if all elements of the collection satisfy the given predicate. + /// + /// The predicate is applied to the elements of the input list. If any application + /// returns false then the overall result is false and no further elements are tested. + /// Otherwise, true is returned. + /// The function to test the input elements. + /// The input list. + /// + /// True if all of the elements satisfy the predicate. + /// + /// + [] + val forall: predicate:('T -> bool) -> list:'T list -> bool + + /// Tests if all corresponding elements of the collection satisfy the given predicate pairwise. + /// + /// The predicate is applied to matching elements in the two collections up to the lesser of the + /// two lengths of the collections. If any application returns false then the overall result is + /// false and no further elements are tested. Otherwise, if one collection is longer + /// than the other then the exception is raised. + /// Otherwise, true is returned. + /// The function to test the input elements. + /// The first input list. + /// The second input list. + /// + /// Thrown when the input lists differ in length. + /// + /// True if all of the pairs of elements satisfy the predicate. + /// + /// + [] + val forall2: predicate:('T1 -> 'T2 -> bool) -> list1:'T1 list -> list2:'T2 list -> bool + + /// Applies a key-generating function to each element of a list and yields a list of + /// unique keys. Each unique key contains a list of all elements that match + /// to this key. + /// + /// A function that transforms an element of the list into a comparable key. + /// The input list. + /// + /// The result list. + /// + /// + [] + val groupBy : projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list when 'Key : equality + + /// Returns the first element of the list. + /// + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The first element of the list. + [] + val head: list:'T list -> 'T + + /// Returns a new list whose elements are the corresponding elements + /// of the input list paired with the index (from 0) of each element. + /// + /// The input list. + /// + /// The list of indexed elements. + /// + /// + [] + val indexed: list:'T list -> (int * 'T) list + + /// Creates a list by calling the given generator on each index. + /// + /// The length of the list to generate. + /// The function to generate an element from an index. + /// + /// The list of generated elements. + /// + /// + [] + val init: length:int -> initializer:(int -> 'T) -> 'T list + + /// Returns true if the list contains no elements, false otherwise. + /// + /// The input list. + /// + /// True if the list is empty. + /// + /// + [] + val isEmpty: list:'T list -> bool + + /// Indexes into the list. The first element has index 0. + /// + /// The index to retrieve. + /// The input list. + /// + /// The value at the given index. + /// + /// Thrown when the index is negative or the input list does not contain enough elements. + /// + /// + [] + val item: index:int -> list:'T list -> 'T + + /// Applies the given function to each element of the collection. + /// + /// The function to apply to elements from the input list. + /// The input list. + /// + /// + [] + val inline iter: action:('T -> unit) -> list:'T list -> unit + + /// Applies the given function to two collections simultaneously. The + /// collections must have identical size. + /// + /// The function to apply to pairs of elements from the input lists. + /// The first input list. + /// The second input list. + /// + /// + [] + val iter2: action:('T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit + + /// Applies the given function to each element of the collection. The integer passed to the + /// function indicates the index of element. + /// + /// The function to apply to the elements of the list along with their index. + /// The input list. + /// + /// + [] + val inline iteri: action:(int -> 'T -> unit) -> list:'T list -> unit + + /// Applies the given function to two collections simultaneously. The + /// collections must have identical size. The integer passed to the + /// function indicates the index of element. + /// + /// The function to apply to a pair of elements from the input lists along with their index. + /// The first input list. + /// The second input list. + /// + /// + [] + val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> list1:'T1 list -> list2:'T2 list -> unit + + /// Returns the last element of the list. + /// + /// The input list. + /// + /// The last element of the list. + /// + /// Thrown when the input does not have any elements. + /// + /// + [] + val last: list:'T list -> 'T + + /// Returns the length of the list. + /// + /// The input list. + /// + /// The length of the list. + /// + /// + [] + val length: list:'T list -> int + + /// Returns the last element of the list. + /// Return None if no such element exists. + /// + /// The input list. + /// + /// The last element of the list or None. + /// + /// + [] + val tryLast: list:'T list -> 'T option + + /// Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. + /// + /// The function to transform elements from the input list. + /// The input list. + /// + /// The list of transformed elements. + /// + /// + [] + val map: mapping:('T -> 'U) -> list:'T list -> 'U list + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding elements of the two collections pairwise. + /// + /// The function to transform pairs of elements from the input lists. + /// The first input list. + /// The second input list. + /// + /// The list of transformed elements. + /// + /// + [] + val map2: mapping:('T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding elements of the three collections simultaneously. + /// + /// The function to transform triples of elements from the input lists. + /// The first input list. + /// The second input list. + /// The third input list. + /// + /// The list of transformed elements. + /// + /// + [] + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> 'U list + + /// Combines map and fold. Builds a new list whose elements are the results of applying the given function + /// to each of the elements of the input list. The function is also used to accumulate a final value. + /// + /// The function to transform elements from the input list and accumulate the final value. + /// The initial state. + /// The input list. + /// + /// The list of transformed elements, and the final accumulated value. + /// + /// + [] + val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> list:'T list -> 'Result list * 'State + + /// Combines map and foldBack. Builds a new list whose elements are the results of applying the given function + /// to each of the elements of the input list. The function is also used to accumulate a final value. + /// + /// The function to transform elements from the input list and accumulate the final value. + /// The input list. + /// The initial state. + /// + /// The list of transformed elements, and the final accumulated value. + /// + /// + [] + val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> list:'T list -> state:'State -> 'Result list * 'State + + /// Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The integer index passed to the + /// function indicates the index (from 0) of element being transformed. + /// + /// The function to transform elements and their indices. + /// The input list. + /// + /// The list of transformed elements. + /// + /// + [] + val mapi: mapping:(int -> 'T -> 'U) -> list:'T list -> 'U list + + /// Like mapi, but mapping corresponding elements from two lists of equal length. + /// + /// The function to transform pairs of elements from the two lists and their index. + /// The first input list. + /// The second input list. + /// + /// The list of transformed elements. + /// + /// + [] + val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list + + /// Return the greatest of all elements of the list, compared via Operators.max. + /// + /// Raises if list is empty + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The maximum element. + /// + /// + [] + val inline max : list:'T list -> 'T when 'T : comparison + + /// Returns the greatest of all elements of the list, compared via Operators.max on the function result. + /// + /// Raises if list is empty. + /// The function to transform the list elements into the type to be compared. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The maximum element. + /// + /// + [] + val inline maxBy : projection:('T -> 'U) -> list:'T list -> 'T when 'U : comparison + + /// Returns the lowest of all elements of the list, compared via Operators.min. + /// + /// Raises if list is empty + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The minimum value. + /// + /// + [] + val inline min : list:'T list -> 'T when 'T : comparison + + /// Returns the lowest of all elements of the list, compared via Operators.min on the function result + /// + /// Raises if list is empty. + /// The function to transform list elements into the type to be compared. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The minimum value. + /// + /// + [] + val inline minBy : projection:('T -> 'U) -> list:'T list -> 'T when 'U : comparison + + /// Indexes into the list. The first element has index 0. + /// + /// The input list. + /// The index to retrieve. + /// + /// The value at the given index. + /// + /// Thrown when the index is negative or the input list does not contain enough elements. + [] + [] + val nth: list:'T list -> index:int -> 'T + + /// Builds a list from the given array. + /// + /// The input array. + /// + /// The list of elements from the array. + /// + /// + [] + val ofArray : array:'T[] -> 'T list + + /// Builds a new list from the given enumerable object. + /// + /// The input sequence. + /// + /// The list of elements from the sequence. + /// + /// + [] + val ofSeq: source:seq<'T> -> 'T list + + /// Returns a list of each element in the input list and its predecessor, with the + /// exception of the first element which is only returned as the predecessor of the second element. + /// + /// The input list. + /// + /// The result list. + /// + /// + [] + val pairwise: list:'T list -> ('T * 'T) list + + /// Splits the collection into two collections, containing the + /// elements for which the given predicate returns True and False + /// respectively. Element order is preserved in both of the created lists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// A list containing the elements for which the predicate evaluated to false and a list + /// containing the elements for which the predicate evaluated to true. + /// + /// + [] + val partition: predicate:('T -> bool) -> list:'T list -> ('T list * 'T list) + + /// Applies the given function to successive elements, returning the first + /// result where function returns Some(x) for some x. If no such + /// element exists then raise + /// + /// The function to generate options from the elements. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The first resulting value. + /// + /// + [] + val pick: chooser:('T -> 'U option) -> list:'T list -> 'U + + /// Returns a list with all elements permuted according to the + /// specified permutation. + /// + /// The function to map input indices to output indices. + /// The input list. + /// + /// The permuted list. + /// + /// Thrown when indexMap does not produce a valid permutation. + /// + /// + [] + val permute : indexMap:(int -> int) -> list:'T list -> 'T list + + /// Apply a function to each element of the collection, threading an accumulator argument + /// through the computation. Apply the function to the first two elements of the list. + /// Then feed this result into the function along with the third element and so on. + /// Return the final result. If the input function is f and the elements are i0...iN then computes + /// f (... (f i0 i1) i2 ...) iN. + /// + /// Raises if list is empty + /// + /// The function to reduce two list elements to a single element. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The final reduced value. + /// + /// + [] + val reduce: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T + + /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN then computes + /// f i0 (...(f iN-1 iN)). + /// + /// A function that takes in the next-to-last element of the list and the + /// current accumulated result to produce the next accumulated result. + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The final result of the reductions. + /// + /// + [] + val reduceBack: reduction:('T -> 'T -> 'T) -> list:'T list -> 'T + + /// Creates a list by replicating the given initial value. + /// + /// The number of elements to replicate. + /// The value to replicate + /// + /// The generated list. + /// + /// + [] + val replicate: count:int -> initial:'T -> 'T list + + /// Returns a new list with the elements in reverse order. + /// + /// The input list. + /// + /// The reversed list. + /// + /// + [] + val rev: list:'T list -> 'T list + + /// Applies a function to each element of the collection, threading an accumulator argument + /// through the computation. Take the second argument, and apply the function to it + /// and the first element of the list. Then feed this result into the function along + /// with the second element and so on. Returns the list of intermediate results and the final result. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The input list. + /// + /// The list of states. + /// + /// + [] + val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State list + + /// Like foldBack, but returns both the intermediary and final results + /// + /// The function to update the state given the input elements. + /// The input list. + /// The initial state. + /// + /// The list of states. + /// + /// + [] + val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State list + + /// Returns a list that contains one item only. + /// + /// The input item. + /// + /// The result list of one item. + /// + /// + [] + val inline singleton: value:'T -> 'T list + + /// Returns the list after removing the first N elements. + /// + /// The number of elements to skip. If the number is 0 or negative the input list is returned. + /// The input list. + /// + /// The list after removing the first N elements. + /// + /// Thrown when count exceeds the number of + /// elements in the list. + /// + /// + [] + val skip: count:int -> list: 'T list -> 'T list + + /// Bypasses elements in a list while the given predicate returns True, and then returns + /// the remaining elements of the list. + /// + /// A function that evaluates an element of the list to a boolean value. + /// The input list. + /// + /// The result list. + /// + /// + [] + val skipWhile: predicate:('T -> bool) -> list:'T list -> 'T list + + /// Sorts the given list using the given comparison function. + /// + /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// The function to compare the list elements. + /// The input list. + /// + /// The sorted list. + /// + /// + [] + val sortWith: comparer:('T -> 'T -> int) -> list:'T list -> 'T list + + /// Sorts the given list using keys given by the given projection. Keys are compared using . + /// + /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// The function to transform the list elements into the type to be compared. + /// The input list. + /// + /// The sorted list. + /// + /// + [] + val sortBy: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : comparison + + /// Sorts the given list using . + /// + /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// The input list. + /// + /// The sorted list. + /// + /// + [] + val sort: list:'T list -> 'T list when 'T : comparison + + /// Splits a list into two lists, at the given index. + /// + /// The index at which the list is split. + /// The input list. + /// + /// The two split lists. + /// + /// Thrown when split index exceeds the number of elements + /// in the list. + /// + /// + [] + val splitAt: index:int -> list:'T list -> ('T list * 'T list) + + /// Sorts the given list in descending order using keys given by the given projection. Keys are compared using . + /// + /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// The function to transform the list elements into the type to be compared. + /// The input list. + /// + /// The sorted list. + /// + /// + [] + val inline sortByDescending: projection:('T -> 'Key) -> list:'T list -> 'T list when 'Key : comparison + + /// Sorts the given list in descending order using . + /// + /// This is a stable sort, i.e. the original order of equal elements is preserved. + /// The input list. + /// + /// The sorted list. + /// + /// + [] + val inline sortDescending: list:'T list -> 'T list when 'T : comparison + + /// Returns the sum of the elements in the list. + /// + /// The input list. + /// + /// The resulting sum. + /// + /// + [] + val inline sum : list:^T list -> ^T + when ^T : (static member (+) : ^T * ^T -> ^T) + and ^T : (static member Zero : ^T) + + /// Returns the sum of the results generated by applying the function to each element of the list. + /// + /// The function to transform the list elements into the type to be summed. + /// The input list. + /// + /// The resulting sum. + /// + /// + [] + val inline sumBy : projection:('T -> ^U) -> list:'T list -> ^U + when ^U : (static member (+) : ^U * ^U -> ^U) + and ^U : (static member Zero : ^U) + + /// Returns the list after removing the first element. + /// + /// The input list. + /// + /// Thrown when the list is empty. + /// + /// The list after removing the first element. + /// + /// + [] + val tail: list:'T list -> 'T list + + /// Returns the first N elements of the list. + /// Throws InvalidOperationException + /// if the count exceeds the number of elements in the list. List.truncate + /// returns as many items as the list contains instead of throwing an exception. + /// + /// The number of items to take. + /// The input list. + /// + /// The result list. + /// + /// Thrown when the input list is empty. + /// Thrown when count exceeds the number of elements + /// in the list. + /// + /// + [] + val take: count:int -> list:'T list -> 'T list + + /// Returns a list that contains all elements of the original list while the + /// given predicate returns True, and then returns no further elements. + /// + /// A function that evaluates to false when no more items should be returned. + /// The input list. + /// + /// The result list. + /// + /// + [] + val takeWhile: predicate:('T -> bool) -> list:'T list -> 'T list + + /// Builds an array from the given list. + /// + /// The input list. + /// + /// The array containing the elements of the list. + /// + /// + [] + val toArray: list:'T list -> 'T[] + + /// Views the given list as a sequence. + /// + /// The input list. + /// + /// The sequence of elements in the list. + /// + /// + [] + val toSeq: list:'T list -> seq<'T> + + /// Returns the first element of the list, or + /// None if the list is empty. + /// + /// The input list. + /// + /// The first element of the list or None. + /// + /// + [] + val tryHead: list:'T list -> 'T option + + /// Returns the transpose of the given sequence of lists. + /// + /// The input sequence of list. + /// + /// The transposed list. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input lists differ in length. + /// + /// + [] + val transpose: lists:seq<'T list> -> 'T list list + + /// Returns at most N elements in a new list. + /// + /// The maximum number of items to return. + /// The input list. + /// + /// The result list. + /// + /// + [] + val truncate: count:int -> list:'T list -> 'T list + + /// Applies the given function to successive elements, returning Some(x) the first + /// result where function returns Some(x) for some x. If no such element + /// exists then return None. + /// + /// The function to generate options from the elements. + /// The input list. + /// + /// The first resulting value or None. + /// + /// + [] + val tryPick: chooser:('T -> 'U option) -> list:'T list -> 'U option + + /// Returns the first element for which the given function returns True. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// The first element for which the predicate returns true, or None if + /// every element evaluates to false. + /// + /// + [] + val tryFind: predicate:('T -> bool) -> list:'T list -> 'T option + + /// Returns the last element for which the given function returns True. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// The last element for which the predicate returns true, or None if + /// every element evaluates to false. + /// + /// + [] + val tryFindBack: predicate:('T -> bool) -> list:'T list -> 'T option + + /// Returns the index of the first element in the list + /// that satisfies the given predicate. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// The index of the first element for which the predicate returns true, or None if + /// every element evaluates to false. + /// + /// + [] + val tryFindIndex: predicate:('T -> bool) -> list:'T list -> int option + + /// Tries to find the nth element in the list. + /// Returns None if index is negative or the list does not contain enough elements. + /// + /// The index to retrieve. + /// The input list. + /// + /// The value at the given index or None. + /// + /// + [] + val tryItem: index:int -> list:'T list -> 'T option + + /// Returns the index of the last element in the list + /// that satisfies the given predicate. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input list. + /// + /// The index of the last element for which the predicate returns true, or None if + /// every element evaluates to false. + /// + /// + [] + val tryFindIndexBack: predicate:('T -> bool) -> list:'T list -> int option + + /// Returns a list that contains the elements generated by the given computation. + /// The given initial state argument is passed to the element generator. + /// + /// A function that takes in the current state and returns an option tuple of the next + /// element of the list and the next state value. + /// The initial state value. + /// + /// The result list. + /// + /// + [] + val unfold<'T,'State> : generator:('State -> ('T * 'State) option) -> state:'State -> 'T list + + /// Splits a list of pairs into two lists. + /// + /// The input list. + /// + /// Two lists of split elements. + /// + /// + [] + val unzip: list:('T1 * 'T2) list -> ('T1 list * 'T2 list) + + /// Splits a list of triples into three lists. + /// + /// The input list. + /// + /// Three lists of split elements. + /// + /// + [] + val unzip3: list:('T1 * 'T2 * 'T3) list -> ('T1 list * 'T2 list * 'T3 list) + + /// Returns a new list containing only the elements of the list + /// for which the given predicate returns "true" + /// + /// The function to test the input elements. + /// The input list. + /// + /// A list containing only the elements that satisfy the predicate. + /// + /// + [] + val where: predicate:('T -> bool) -> list:'T list -> 'T list + + /// Returns a list of sliding windows containing elements drawn from the input + /// list. Each window is returned as a fresh list. + /// + /// The number of elements in each window. + /// The input list. + /// + /// The result list. + /// + /// Thrown when windowSize is not positive. + /// + /// + [] + val windowed : windowSize:int -> list:'T list -> 'T list list + + /// Combines the two lists into a list of pairs. The two lists must have equal lengths. + /// + /// The first input list. + /// The second input list. + /// + /// A single list containing pairs of matching elements from the input lists. + /// + /// + [] + val zip: list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list + + /// Combines the three lists into a list of triples. The lists must have equal lengths. + /// + /// The first input list. + /// The second input list. + /// The third input list. + /// + /// A single list containing triples of matching elements from the input lists. + /// + /// + [] + val zip3: list1:'T1 list -> list2:'T2 list -> list3:'T3 list -> ('T1 * 'T2 * 'T3) list + + /// Return a new list with the item at a given index removed. + /// + /// The index of the item to be removed. + /// The input list. + /// + /// The result list. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// [ 0; 1; 2 ] |> List.removeAt 1 // evaluates to [ 0; 2 ] + /// + /// + [] + val removeAt: index: int -> source: 'T list -> 'T list + + /// Return a new list with the number of items starting at a given index removed. + /// + /// The index of the item to be removed. + /// The number of items to remove. + /// The input list. + /// + /// The result list. + /// + /// Thrown when index is outside 0..source.Length - count + /// + /// + /// + /// [ 0; 1; 2; 3 ] |> List.removeManyAt 1 2 // evaluates to [ 0; 3 ] + /// + /// + [] + val removeManyAt: index: int -> count: int -> source: 'T list -> 'T list + + /// Return a new list with the item at a given index set to the new value. + /// + /// The index of the item to be replaced. + /// The new value. + /// The input list. + /// + /// The result list. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// [ 0; 1; 2 ] |> List.updateAt 1 9 // evaluates to [ 0; 9; 2 ] + /// + /// + [] + val updateAt: index: int -> value: 'T -> source: 'T list -> 'T list + + /// Return a new list with a new item inserted before the given index. + /// + /// The index where the item should be inserted. + /// The value to insert. + /// The input list. + /// + /// The result list. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// [ 0; 1; 2 ] |> List.insertAt 1 9 // evaluates to [ 0; 9; 1; 2 ] + /// + /// + [] + val insertAt: index: int -> value: 'T -> source: 'T list -> 'T list + + /// Return a new list with new items inserted before the given index. + /// + /// The index where the items should be inserted. + /// The values to insert. + /// The input list. + /// + /// The result list. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// [ 0; 1; 2 ] |> List.insertManyAt 1 [ 8; 9 ] // evaluates to [ 0; 8; 9; 1; 2 ] + /// + /// + [] + val insertManyAt: index: int -> values: seq<'T> -> source: 'T list -> 'T list diff --git a/src/fsharp/FSharp.Core/local.fs b/src/fsharp/FSharp.Core/local.fs index 8e1b17ea916..e02cccb7494 100644 --- a/src/fsharp/FSharp.Core/local.fs +++ b/src/fsharp/FSharp.Core/local.fs @@ -83,7 +83,7 @@ open System.Collections.Generic module internal List = - let arrayZeroCreate (n:int) = (# "newarr !0" type ('T) n : 'T array #) + let inline arrayZeroCreate (n:int) = (# "newarr !0" type ('T) n : 'T array #) [] let nonempty x = match x with [] -> false | _ -> true @@ -194,10 +194,6 @@ module internal List = cons let groupBy (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (list: 'T list) = - match list with - | [] -> [] - | _ -> - let dict = Dictionary<_, _ list []> comparer // Build the groupings @@ -1050,7 +1046,7 @@ module internal Array = let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(f) let mutable acc = acc let res = zeroCreateUnchecked len - for i = 0 to array.Length-1 do + for i = 0 to len-1 do let h', s' = f.Invoke(acc, array.[i]) res.[i] <- h' acc <- s' @@ -1081,22 +1077,21 @@ module internal Array = let unstableSortInPlaceBy (projection: 'T -> 'U) (array : array<'T>) = let len = array.Length - if len < 2 then () - else - let keys = zeroCreateUnchecked array.Length - for i = 0 to array.Length - 1 do + if len > 1 then + let keys = zeroCreateUnchecked len + for i = 0 to len - 1 do keys.[i] <- projection array.[i] Array.Sort<_, _>(keys, array, fastComparerForArraySort()) let unstableSortInPlace (array : array<'T>) = - let len = array.Length - if len < 2 then () - else Array.Sort<_>(array, fastComparerForArraySort()) + if array.Length > 1 then + Array.Sort<_>(array, fastComparerForArraySort()) let stableSortWithKeysAndComparer (cFast:IComparer<'Key>) (c:IComparer<'Key>) (array:array<'T>) (keys:array<'Key>) = - // 'places' is an array or integers storing the permutation performed by the sort - let places = zeroCreateUnchecked array.Length - for i = 0 to array.Length - 1 do + // 'places' is an array or integers storing the permutation performed by the sort + let len = array.Length + let places = zeroCreateUnchecked len + for i = 0 to len - 1 do places.[i] <- i System.Array.Sort<_, _>(keys, places, cFast) // 'array2' is a copy of the original values @@ -1104,7 +1099,6 @@ module internal Array = // Walk through any chunks where the keys are equal let mutable i = 0 - let len = array.Length let intCompare = fastComparerForArraySort() while i < len do @@ -1126,18 +1120,16 @@ module internal Array = let stableSortInPlaceBy (projection: 'T -> 'U) (array : array<'T>) = let len = array.Length - if len < 2 then () - else + if len > 1 then // 'keys' is an array storing the projected keys - let keys = zeroCreateUnchecked array.Length - for i = 0 to array.Length - 1 do + let keys = zeroCreateUnchecked len + for i = 0 to len - 1 do keys.[i] <- projection array.[i] stableSortWithKeys array keys let stableSortInPlace (array : array<'T>) = let len = array.Length - if len < 2 then () - else + if len > 1 then let cFast = LanguagePrimitives.FastGenericComparerCanBeNull<'T> match cFast with | null -> @@ -1154,7 +1146,7 @@ module internal Array = if len > 1 then let keys = (array.Clone() :?> array<'T>) let comparer = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(comparer) - let c = { new IComparer<'T> with member __.Compare(x, y) = comparer.Invoke(x, y) } + let c = { new IComparer<'T> with member _.Compare(x, y) = comparer.Invoke(x, y) } stableSortWithKeysAndComparer c c array keys let inline subUnchecked startIndex count (array : 'T[]) = diff --git a/src/fsharp/FSharp.Core/mailbox.fs b/src/fsharp/FSharp.Core/mailbox.fs index b2bec129719..96782fa1e15 100644 --- a/src/fsharp/FSharp.Core/mailbox.fs +++ b/src/fsharp/FSharp.Core/mailbox.fs @@ -103,7 +103,7 @@ namespace Microsoft.FSharp.Control else waitOneWithCancellation timeout - member __.inbox = + member _.inbox = match inboxStore with | null -> inboxStore <- new System.Collections.Generic.List<'Msg>(1) | _ -> () @@ -311,7 +311,7 @@ namespace Microsoft.FSharp.Control } interface System.IDisposable with - member __.Dispose() = + member _.Dispose() = if isNotNull pulse then (pulse :> IDisposable).Dispose() #if DEBUG @@ -337,17 +337,17 @@ namespace Microsoft.FSharp.Control let mutable started = false let errorEvent = new Event() - member __.CurrentQueueLength = mailbox.CurrentQueueLength // nb. unprotected access gives an approximation of the queue length + member _.CurrentQueueLength = mailbox.CurrentQueueLength // nb. unprotected access gives an approximation of the queue length - member __.DefaultTimeout + member _.DefaultTimeout with get() = defaultTimeout and set v = defaultTimeout <- v [] - member __.Error = errorEvent.Publish + member _.Error = errorEvent.Publish #if DEBUG - member __.UnsafeMessageQueueContents = mailbox.UnsafeContents + member _.UnsafeMessageQueueContents = mailbox.UnsafeContents #endif member x.Start() = @@ -367,9 +367,9 @@ namespace Microsoft.FSharp.Control Async.Start(computation=p, cancellationToken=cancellationToken) - member __.Post message = mailbox.Post message + member _.Post message = mailbox.Post message - member __.TryPostAndReply(buildMessage : (_ -> 'Msg), ?timeout) : 'Reply option = + member _.TryPostAndReply(buildMessage : (_ -> 'Msg), ?timeout) : 'Reply option = let timeout = defaultArg timeout defaultTimeout use resultCell = new ResultCell<_>() let msg = buildMessage (new AsyncReplyChannel<_>(fun reply -> @@ -384,7 +384,7 @@ namespace Microsoft.FSharp.Control | None -> raise (TimeoutException(SR.GetString(SR.mailboxProcessorPostAndReplyTimedOut))) | Some res -> res - member __.PostAndTryAsyncReply(buildMessage, ?timeout) : Async<'Reply option> = + member _.PostAndTryAsyncReply(buildMessage, ?timeout) : Async<'Reply option> = let timeout = defaultArg timeout defaultTimeout let resultCell = new ResultCell<_>() let msg = buildMessage (new AsyncReplyChannel<_>(fun reply -> @@ -419,20 +419,20 @@ namespace Microsoft.FSharp.Control | None -> return! raise (TimeoutException(SR.GetString(SR.mailboxProcessorPostAndAsyncReplyTimedOut))) | Some res -> return res } - member __.Receive(?timeout) = + member _.Receive(?timeout) = mailbox.Receive(timeout=defaultArg timeout defaultTimeout) - member __.TryReceive(?timeout) = + member _.TryReceive(?timeout) = mailbox.TryReceive(timeout=defaultArg timeout defaultTimeout) - member __.Scan(scanner: 'Msg -> (Async<'T>) option, ?timeout) = + member _.Scan(scanner: 'Msg -> (Async<'T>) option, ?timeout) = mailbox.Scan(scanner, timeout=defaultArg timeout defaultTimeout) - member __.TryScan(scanner: 'Msg -> (Async<'T>) option, ?timeout) = + member _.TryScan(scanner: 'Msg -> (Async<'T>) option, ?timeout) = mailbox.TryScan(scanner, timeout=defaultArg timeout defaultTimeout) interface System.IDisposable with - member __.Dispose() = (mailbox :> IDisposable).Dispose() + member _.Dispose() = (mailbox :> IDisposable).Dispose() static member Start(body, ?cancellationToken) = let mailboxProcessor = new MailboxProcessor<'Msg>(body, ?cancellationToken=cancellationToken) diff --git a/src/fsharp/FSharp.Core/mailbox.fsi b/src/fsharp/FSharp.Core/mailbox.fsi index 6d818299e06..b864b99ad43 100644 --- a/src/fsharp/FSharp.Core/mailbox.fsi +++ b/src/fsharp/FSharp.Core/mailbox.fsi @@ -2,161 +2,213 @@ namespace Microsoft.FSharp.Control - open System.Threading - - open Microsoft.FSharp.Core - open Microsoft.FSharp.Control - - [] - /// A handle to a capability to reply to a PostAndReply message. - type AsyncReplyChannel<'Reply> = - /// Sends a reply to a PostAndReply message. - /// The value to send. - member Reply : value:'Reply -> unit - - /// A message-processing agent which executes an asynchronous computation. - /// - /// The agent encapsulates a message queue that supports multiple-writers and - /// a single reader agent. Writers send messages to the agent by using the Post - /// method and its variations. - /// - /// The agent may wait for messages using the Receive or TryReceive methods or - /// scan through all available messages using the Scan or TryScan method. - [] - type MailboxProcessor<'Msg> = - - /// Creates an agent. The body function is used to generate the asynchronous - /// computation executed by the agent. This function is not executed until - /// Start is called. - /// The function to produce an asynchronous computation that will be executed - /// as the read loop for the MailboxProcessor when Start is called. - /// An optional cancellation token for the body. - /// Defaults to Async.DefaultCancellationToken. - /// The created MailboxProcessor. - new : body:(MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> - - /// Creates and starts an agent. The body function is used to generate the asynchronous - /// computation executed by the agent. - /// The function to produce an asynchronous computation that will be executed - /// as the read loop for the MailboxProcessor when Start is called. - /// An optional cancellation token for the body. - /// Defaults to Async.DefaultCancellationToken. - /// The created MailboxProcessor. - static member Start : body:(MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> - - /// Posts a message to the message queue of the MailboxProcessor, asynchronously. - /// The message to post. - member Post : message:'Msg -> unit - - /// Posts a message to an agent and await a reply on the channel, synchronously. - /// - /// The message is generated by applying buildMessage to a new reply channel - /// to be incorporated into the message. The receiving agent must process this - /// message and invoke the Reply method on this reply channel precisely once. - /// The function to incorporate the AsyncReplyChannel into - /// the message to be sent. - /// An optional timeout parameter (in milliseconds) to wait for a reply message. - /// Defaults to -1 which corresponds to System.Threading.Timeout.Infinite. - /// The reply from the agent. - member PostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> 'Reply - - /// Posts a message to an agent and await a reply on the channel, asynchronously. - /// - /// The message is generated by applying buildMessage to a new reply channel - /// to be incorporated into the message. The receiving agent must process this - /// message and invoke the Reply method on this reply channel precisely once. - /// The function to incorporate the AsyncReplyChannel into - /// the message to be sent. - /// An optional timeout parameter (in milliseconds) to wait for a reply message. - /// Defaults to -1 which corresponds to System.Threading.Timeout.Infinite. - /// An asynchronous computation that will wait for the reply from the agent. - member PostAndAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> Async<'Reply> - - /// Like PostAndReply, but returns None if no reply within the timeout period. - /// The function to incorporate the AsyncReplyChannel into - /// the message to be sent. - /// An optional timeout parameter (in milliseconds) to wait for a reply message. - /// Defaults to -1 which corresponds to System.Threading.Timeout.Infinite. - /// The reply from the agent or None if the timeout expires. - member TryPostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> 'Reply option - - /// Like AsyncPostAndReply, but returns None if no reply within the timeout period. - /// The function to incorporate the AsyncReplyChannel into - /// the message to be sent. - /// An optional timeout parameter (in milliseconds) to wait for a reply message. - /// Defaults to -1 which corresponds to System.Threading.Timeout.Infinite. - /// An asynchronous computation that will return the reply or None if the timeout expires. - member PostAndTryAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> Async<'Reply option> - - /// Waits for a message. This will consume the first message in arrival order. - /// - /// This method is for use within the body of the agent. - /// - /// This method is for use within the body of the agent. For each agent, at most - /// one concurrent reader may be active, so no more than one concurrent call to - /// Receive, TryReceive, Scan and/or TryScan may be active. - /// An optional timeout in milliseconds. Defaults to -1 which corresponds - /// to System.Threading.Timeout.Infinite. - /// An asynchronous computation that returns the received message. - /// Thrown when the timeout is exceeded. - member Receive : ?timeout:int -> Async<'Msg> - - /// Waits for a message. This will consume the first message in arrival order. - /// - /// This method is for use within the body of the agent. - /// - /// Returns None if a timeout is given and the timeout is exceeded. - /// - /// This method is for use within the body of the agent. For each agent, at most - /// one concurrent reader may be active, so no more than one concurrent call to - /// Receive, TryReceive, Scan and/or TryScan may be active. - /// An optional timeout in milliseconds. Defaults to -1 which - /// corresponds to System.Threading.Timeout.Infinite. - /// An asynchronous computation that returns the received message or - /// None if the timeout is exceeded. - member TryReceive : ?timeout:int -> Async<'Msg option> - - /// Scans for a message by looking through messages in arrival order until scanner - /// returns a Some value. Other messages remain in the queue. - /// - /// Returns None if a timeout is given and the timeout is exceeded. - /// - /// This method is for use within the body of the agent. For each agent, at most - /// one concurrent reader may be active, so no more than one concurrent call to - /// Receive, TryReceive, Scan and/or TryScan may be active. - /// The function to return None if the message is to be skipped - /// or Some if the message is to be processed and removed from the queue. - /// An optional timeout in milliseconds. Defaults to -1 which corresponds - /// to System.Threading.Timeout.Infinite. - /// An asynchronous computation that scanner built off the read message. - /// Thrown when the timeout is exceeded. - member Scan : scanner:('Msg -> (Async<'T>) option) * ?timeout:int -> Async<'T> - - /// Scans for a message by looking through messages in arrival order until scanner - /// returns a Some value. Other messages remain in the queue. - /// - /// This method is for use within the body of the agent. For each agent, at most - /// one concurrent reader may be active, so no more than one concurrent call to - /// Receive, TryReceive, Scan and/or TryScan may be active. - /// The function to return None if the message is to be skipped - /// or Some if the message is to be processed and removed from the queue. - /// An optional timeout in milliseconds. Defaults to -1 which corresponds - /// to System.Threading.Timeout.Infinite. - /// An asynchronous computation that scanner built off the read message. - member TryScan : scanner:('Msg -> (Async<'T>) option) * ?timeout:int -> Async<'T option> - - /// Starts the agent. - member Start : unit -> unit - - /// Raises a timeout exception if a message not received in this amount of time. By default - /// no timeout is used. - member DefaultTimeout : int with get, set - - /// Occurs when the execution of the agent results in an exception. - [] - member Error : IEvent - - interface System.IDisposable - - /// Returns the number of unprocessed messages in the message queue of the agent. - member CurrentQueueLength : int +open System.Threading + +open Microsoft.FSharp.Core +open Microsoft.FSharp.Control + +[] +/// A handle to a capability to reply to a PostAndReply message. +/// +/// Agents +type AsyncReplyChannel<'Reply> = + /// Sends a reply to a PostAndReply message. + /// The value to send. + member Reply : value:'Reply -> unit + +/// A message-processing agent which executes an asynchronous computation. +/// +/// The agent encapsulates a message queue that supports multiple-writers and +/// a single reader agent. Writers send messages to the agent by using the Post +/// method and its variations. +/// +/// The agent may wait for messages using the Receive or TryReceive methods or +/// scan through all available messages using the Scan or TryScan method. +/// +/// Agents +[] +type MailboxProcessor<'Msg> = + + /// Creates an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. This function is not executed until + /// Start is called. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + new: body:(MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + + /// Creates and starts an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + static member Start : body:(MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + + /// Posts a message to the message queue of the MailboxProcessor, asynchronously. + /// + /// The message to post. + /// + /// + member Post : message:'Msg -> unit + + /// Posts a message to an agent and await a reply on the channel, synchronously. + /// + /// The message is generated by applying buildMessage to a new reply channel + /// to be incorporated into the message. The receiving agent must process this + /// message and invoke the Reply method on this reply channel precisely once. + /// The function to incorporate the AsyncReplyChannel into + /// the message to be sent. + /// An optional timeout parameter (in milliseconds) to wait for a reply message. + /// Defaults to -1 which corresponds to . + /// + /// The reply from the agent. + /// + /// + member PostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> 'Reply + + /// Posts a message to an agent and await a reply on the channel, asynchronously. + /// + /// The message is generated by applying buildMessage to a new reply channel + /// to be incorporated into the message. The receiving agent must process this + /// message and invoke the Reply method on this reply channel precisely once. + /// The function to incorporate the AsyncReplyChannel into + /// the message to be sent. + /// An optional timeout parameter (in milliseconds) to wait for a reply message. + /// Defaults to -1 which corresponds to . + /// + /// An asynchronous computation that will wait for the reply from the agent. + /// + /// + member PostAndAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> Async<'Reply> + + /// Like PostAndReply, but returns None if no reply within the timeout period. + /// + /// The function to incorporate the AsyncReplyChannel into + /// the message to be sent. + /// An optional timeout parameter (in milliseconds) to wait for a reply message. + /// Defaults to -1 which corresponds to . + /// + /// The reply from the agent or None if the timeout expires. + /// + /// + member TryPostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> 'Reply option + + /// Like AsyncPostAndReply, but returns None if no reply within the timeout period. + /// + /// The function to incorporate the AsyncReplyChannel into + /// the message to be sent. + /// An optional timeout parameter (in milliseconds) to wait for a reply message. + /// Defaults to -1 which corresponds to . + /// + /// An asynchronous computation that will return the reply or None if the timeout expires. + /// + /// + member PostAndTryAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout : int -> Async<'Reply option> + + /// Waits for a message. This will consume the first message in arrival order. + /// + /// This method is for use within the body of the agent. + /// + /// This method is for use within the body of the agent. For each agent, at most + /// one concurrent reader may be active, so no more than one concurrent call to + /// Receive, TryReceive, Scan and/or TryScan may be active. + /// An optional timeout in milliseconds. Defaults to -1 which corresponds + /// to . + /// + /// An asynchronous computation that returns the received message. + /// Thrown when the timeout is exceeded. + /// + /// + member Receive : ?timeout:int -> Async<'Msg> + + /// Waits for a message. This will consume the first message in arrival order. + /// + /// This method is for use within the body of the agent. + /// + /// Returns None if a timeout is given and the timeout is exceeded. + /// + /// This method is for use within the body of the agent. For each agent, at most + /// one concurrent reader may be active, so no more than one concurrent call to + /// Receive, TryReceive, Scan and/or TryScan may be active. + /// An optional timeout in milliseconds. Defaults to -1 which + /// corresponds to . + /// + /// An asynchronous computation that returns the received message or + /// None if the timeout is exceeded. + /// + /// + member TryReceive : ?timeout:int -> Async<'Msg option> + + /// Scans for a message by looking through messages in arrival order until scanner + /// returns a Some value. Other messages remain in the queue. + /// + /// Returns None if a timeout is given and the timeout is exceeded. + /// + /// This method is for use within the body of the agent. For each agent, at most + /// one concurrent reader may be active, so no more than one concurrent call to + /// Receive, TryReceive, Scan and/or TryScan may be active. + /// + /// The function to return None if the message is to be skipped + /// or Some if the message is to be processed and removed from the queue. + /// An optional timeout in milliseconds. Defaults to -1 which corresponds + /// to . + /// + /// An asynchronous computation that scanner built off the read message. + /// + /// Thrown when the timeout is exceeded. + /// + /// + member Scan : scanner:('Msg -> (Async<'T>) option) * ?timeout:int -> Async<'T> + + /// Scans for a message by looking through messages in arrival order until scanner + /// returns a Some value. Other messages remain in the queue. + /// + /// This method is for use within the body of the agent. For each agent, at most + /// one concurrent reader may be active, so no more than one concurrent call to + /// Receive, TryReceive, Scan and/or TryScan may be active. + /// + /// The function to return None if the message is to be skipped + /// or Some if the message is to be processed and removed from the queue. + /// An optional timeout in milliseconds. Defaults to -1 which corresponds + /// to . + /// + /// An asynchronous computation that scanner built off the read message. + /// + /// + member TryScan : scanner:('Msg -> (Async<'T>) option) * ?timeout:int -> Async<'T option> + + /// Starts the agent. + /// + /// + member Start : unit -> unit + + /// Raises a timeout exception if a message not received in this amount of time. By default + /// no timeout is used. + /// + /// + member DefaultTimeout : int with get, set + + /// Occurs when the execution of the agent results in an exception. + /// + /// + [] + member Error : IEvent + + /// Returns the number of unprocessed messages in the message queue of the agent. + /// + /// + member CurrentQueueLength : int + + interface System.IDisposable diff --git a/src/fsharp/FSharp.Core/map.fs b/src/fsharp/FSharp.Core/map.fs index 0c7554586f9..9fe6644f45a 100644 --- a/src/fsharp/FSharp.Core/map.fs +++ b/src/fsharp/FSharp.Core/map.fs @@ -4,27 +4,50 @@ namespace Microsoft.FSharp.Collections open System open System.Collections.Generic +open System.Collections open System.Diagnostics +open System.Runtime.CompilerServices open System.Text open Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators -[] [] -type MapTree<'Key, 'Value when 'Key : comparison > = - | MapEmpty - | MapOne of 'Key * 'Value - | MapNode of 'Key * 'Value * MapTree<'Key, 'Value> * MapTree<'Key, 'Value> * int - +[] +type internal MapTree<'Key, 'Value>(k: 'Key, v: 'Value, h: int) = + member _.Height = h + member _.Key = k + member _.Value = v + new(k: 'Key, v: 'Value) = MapTree(k,v,1) + +[] +[] +[] +type internal MapTreeNode<'Key, 'Value>(k:'Key, v:'Value, left:MapTree<'Key, 'Value>, right: MapTree<'Key, 'Value>, h: int) = + inherit MapTree<'Key,'Value>(k, v, h) + member _.Left = left + member _.Right = right + + [] module MapTree = - - let rec sizeAux acc m = - match m with - | MapEmpty -> acc - | MapOne _ -> acc + 1 - | MapNode (_, _, l, r, _) -> sizeAux (sizeAux (acc+1) l) r - + + let empty = null + + let inline isEmpty (m:MapTree<'Key, 'Value>) = isNull m + + let inline private asNode(value:MapTree<'Key,'Value>) : MapTreeNode<'Key,'Value> = + value :?> MapTreeNode<'Key,'Value> + + let rec sizeAux acc (m:MapTree<'Key, 'Value>) = + if isEmpty m then + acc + else + if m.Height = 1 then + acc + 1 + else + let mn = asNode m + sizeAux (sizeAux (acc+1) mn.Left) mn.Right + let size x = sizeAux 0 x #if TRACE_SETS_AND_MAPS @@ -51,108 +74,94 @@ module MapTree = (totalSizeOnMapLookup / float numLookups)) System.Console.WriteLine("#largestMapSize = {0}, largestMapStackTrace = {1}", largestMapSize, largestMapStackTrace) - let MapOne n = + let MapTree (k,v) = report() numOnes <- numOnes + 1 totalSizeOnNodeCreation <- totalSizeOnNodeCreation + 1.0 - MapTree.MapOne n + MapTree (k,v) - let MapNode (x, l, v, r, h) = + let MapTreeNode (x, l, v, r, h) = report() numNodes <- numNodes + 1 - let n = MapTree.MapNode (x, l, v, r, h) + let n = MapTreeNode (x, l, v, r, h) totalSizeOnNodeCreation <- totalSizeOnNodeCreation + float (size n) n #endif - let empty = MapEmpty - - let height (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> 0 - | MapOne _ -> 1 - | MapNode (_, _, _, _, h) -> h - - let isEmpty (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> true - | _ -> false - + let inline height (m: MapTree<'Key, 'Value>) = + if isEmpty m then 0 + else m.Height + + [] + let tolerance = 2 + let mk l k v r : MapTree<'Key, 'Value> = - match l, r with - | MapEmpty, MapEmpty -> MapOne (k, v) - | _ -> - let hl = height l - let hr = height r - let m = if hl < hr then hr else hl - MapNode (k, v, l, r, m+1) - - let rebalance t1 (k: 'Key) (v: 'Value) t2 = - let t1h = height t1 + let hl = height l + let hr = height r + let m = if hl < hr then hr else hl + if m = 0 then // m=0 ~ isEmpty l && isEmpty r + MapTree(k,v) + else + MapTreeNode(k,v,l,r,m+1) :> MapTree<'Key, 'Value> // new map is higher by 1 than the highest + + let rebalance t1 (k: 'Key) (v: 'Value) t2 : MapTree<'Key, 'Value> = + let t1h = height t1 let t2h = height t2 - if t2h > t1h + 2 then (* right is heavier than left *) - match t2 with - | MapNode (t2k, t2v, t2l, t2r, _) -> - // one of the nodes must have height > height t1 + 1 - if height t2l > t1h + 1 then - // balance left: combination - match t2l with - | MapNode (t2lk, t2lv, t2ll, t2lr, _) -> - mk (mk t1 k v t2ll) t2lk t2lv (mk t2lr t2k t2v t2r) - | _ -> failwith "rebalance" - else - // rotate left - mk (mk t1 k v t2l) t2k t2v t2r - | _ -> failwith "rebalance" + if t2h > t1h + tolerance then (* right is heavier than left *) + let t2' = asNode(t2) + (* one of the nodes must have height > height t1 + 1 *) + if height t2'.Left > t1h + 1 then (* balance left: combination *) + let t2l = asNode(t2'.Left) + mk (mk t1 k v t2l.Left) t2l.Key t2l.Value (mk t2l.Right t2'.Key t2'.Value t2'.Right) + else (* rotate left *) + mk (mk t1 k v t2'.Left) t2'.Key t2'.Value t2'.Right else - if t1h > t2h + 2 then (* left is heavier than right *) - match t1 with - | MapNode (t1k, t1v, t1l, t1r, _) -> - // one of the nodes must have height > height t2 + 1 - if height t1r > t2h + 1 then - // balance right: combination - match t1r with - | MapNode (t1rk, t1rv, t1rl, t1rr, _) -> - mk (mk t1l t1k t1v t1rl) t1rk t1rv (mk t1rr k v t2) - | _ -> failwith "rebalance" - else - mk t1l t1k t1v (mk t1r k v t2) - | _ -> failwith "rebalance" + if t1h > t2h + tolerance then (* left is heavier than right *) + let t1' = asNode(t1) + (* one of the nodes must have height > height t2 + 1 *) + if height t1'.Right > t2h + 1 then + (* balance right: combination *) + let t1r = asNode(t1'.Right) + mk (mk t1'.Left t1'.Key t1'.Value t1r.Left) t1r.Key t1r.Value (mk t1r.Right k v t2) + else + mk t1'.Left t1'.Key t1'.Value (mk t1'.Right k v t2) else mk t1 k v t2 - - let rec add (comparer: IComparer<'Key>) k (v: 'Value) (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> MapOne (k, v) - | MapOne (k2, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then MapNode (k, v, MapEmpty, m, 2) - elif c = 0 then MapOne (k, v) - else MapNode (k, v, m, MapEmpty, 2) - | MapNode (k2, v2, l, r, h) -> - let c = comparer.Compare(k, k2) - if c < 0 then rebalance (add comparer k v l) k2 v2 r - elif c = 0 then MapNode (k, v, l, r, h) - else rebalance l k2 v2 (add comparer k v r) - - let rec tryGetValue (comparer: IComparer<'Key>) k (v: byref<'Value>) (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> false - | MapOne (k2, v2) -> - let c = comparer.Compare(k, k2) - if c = 0 then v <- v2; true - else false - | MapNode (k2, v2, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then tryGetValue comparer k &v l - elif c = 0 then v <- v2; true - else tryGetValue comparer k &v r - + + let rec add (comparer: IComparer<'Key>) k (v: 'Value) (m: MapTree<'Key, 'Value>) : MapTree<'Key, 'Value> = + if isEmpty m then MapTree(k,v) + else + let c = comparer.Compare(k,m.Key) + if m.Height = 1 then + if c < 0 then MapTreeNode (k,v,empty,m,2) :> MapTree<'Key, 'Value> + elif c = 0 then MapTree(k,v) + else MapTreeNode (k,v,m,empty,2) :> MapTree<'Key, 'Value> + else + let mn = asNode m + if c < 0 then rebalance (add comparer k v mn.Left) mn.Key mn.Value mn.Right + elif c = 0 then MapTreeNode(k,v,mn.Left,mn.Right,mn.Height) :> MapTree<'Key, 'Value> + else rebalance mn.Left mn.Key mn.Value (add comparer k v mn.Right) + + let rec tryGetValue (comparer: IComparer<'Key>) k (v: byref<'Value>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then false + else + let c = comparer.Compare(k, m.Key) + if c = 0 then v <- m.Value; true + else + if m.Height = 1 then false + else + let mn = asNode m + tryGetValue comparer k &v (if c < 0 then mn.Left else mn.Right) + + [] + let throwKeyNotFound() = raise (KeyNotFoundException()) + + [] let find (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = let mutable v = Unchecked.defaultof<'Value> if tryGetValue comparer k &v m then v else - raise (KeyNotFoundException()) + throwKeyNotFound() let tryFind (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = let mutable v = Unchecked.defaultof<'Value> @@ -164,187 +173,264 @@ module MapTree = let partition1 (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) k v (acc1, acc2) = if f.Invoke (k, v) then (add comparer k v acc1, acc2) else (acc1, add comparer k v acc2) - let rec partitionAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) m acc = - match m with - | MapEmpty -> acc - | MapOne (k, v) -> partition1 comparer f k v acc - | MapNode (k, v, l, r, _) -> - let acc = partitionAux comparer f r acc - let acc = partition1 comparer f k v acc - partitionAux comparer f l acc - + let rec partitionAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) acc = + if isEmpty m then acc + else + if m.Height = 1 then + partition1 comparer f m.Key m.Value acc + else + let mn = asNode m + let acc = partitionAux comparer f mn.Right acc + let acc = partition1 comparer f mn.Key mn.Value acc + partitionAux comparer f mn.Left acc + let partition (comparer: IComparer<'Key>) f m = partitionAux comparer (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m (empty, empty) let filter1 (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) k v acc = if f.Invoke (k, v) then add comparer k v acc else acc - let rec filterAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) m acc = - match m with - | MapEmpty -> acc - | MapOne (k, v) -> filter1 comparer f k v acc - | MapNode (k, v, l, r, _) -> - let acc = filterAux comparer f l acc - let acc = filter1 comparer f k v acc - filterAux comparer f r acc + let rec filterAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) acc = + if isEmpty m then acc + else + if m.Height = 1 then + filter1 comparer f m.Key m.Value acc + else + let mn = asNode m + let acc = filterAux comparer f mn.Left acc + let acc = filter1 comparer f mn.Key mn.Value acc + filterAux comparer f mn.Right acc + let filter (comparer: IComparer<'Key>) f m = filterAux comparer (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m empty let rec spliceOutSuccessor (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> failwith "internal error: Map.spliceOutSuccessor" - | MapOne (k2, v2) -> k2, v2, MapEmpty - | MapNode (k2, v2, l, r, _) -> - match l with - | MapEmpty -> k2, v2, r - | _ -> let k3, v3, l' = spliceOutSuccessor l in k3, v3, mk l' k2 v2 r + if isEmpty m then failwith "internal error: Map.spliceOutSuccessor" + else + if m.Height = 1 then + m.Key, m.Value, empty + else + let mn = asNode m + if isEmpty mn.Left then mn.Key, mn.Value, mn.Right + else let k3, v3, l' = spliceOutSuccessor mn.Left in k3, v3, mk l' mn.Key mn.Value mn.Right let rec remove (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> empty - | MapOne (k2, _) -> - let c = comparer.Compare(k, k2) - if c = 0 then MapEmpty else m - | MapNode (k2, v2, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then rebalance (remove comparer k l) k2 v2 r - elif c = 0 then - match l, r with - | MapEmpty, _ -> r - | _, MapEmpty -> l - | _ -> - let sk, sv, r' = spliceOutSuccessor r - mk l sk sv r' - else rebalance l k2 v2 (remove comparer k r) + if isEmpty m then empty + else + let c = comparer.Compare(k, m.Key) + if m.Height = 1 then + if c = 0 then empty else m + else + let mn = asNode m + if c < 0 then rebalance (remove comparer k mn.Left) mn.Key mn.Value mn.Right + elif c = 0 then + if isEmpty mn.Left then mn.Right + elif isEmpty mn.Right then mn.Left + else + let sk, sv, r' = spliceOutSuccessor mn.Right + mk mn.Left sk sv r' + else rebalance mn.Left mn.Key mn.Value (remove comparer k mn.Right) + + + let rec change (comparer: IComparer<'Key>) k (u: 'Value option -> 'Value option) (m: MapTree<'Key, 'Value>) : MapTree<'Key,'Value> = + if isEmpty m then + match u None with + | None -> m + | Some v -> MapTree (k, v) + else + if m.Height = 1 then + let c = comparer.Compare(k, m.Key) + if c < 0 then + match u None with + | None -> m + | Some v -> MapTreeNode (k, v, empty, m, 2) :> MapTree<'Key,'Value> + elif c = 0 then + match u (Some m.Value) with + | None -> empty + | Some v -> MapTree (k, v) + else + match u None with + | None -> m + | Some v -> MapTreeNode (k, v, m, empty, 2) :> MapTree<'Key,'Value> + else + let mn = asNode m + let c = comparer.Compare(k, mn.Key) + if c < 0 then + rebalance (change comparer k u mn.Left) mn.Key mn.Value mn.Right + elif c = 0 then + match u (Some mn.Value) with + | None -> + if isEmpty mn.Left then mn.Right + elif isEmpty mn.Right then mn.Left + else + let sk, sv, r' = spliceOutSuccessor mn.Right + mk mn.Left sk sv r' + | Some v -> MapTreeNode (k, v, mn.Left, mn.Right, mn.Height) :> MapTree<'Key,'Value> + else + rebalance mn.Left mn.Key mn.Value (change comparer k u mn.Right) let rec mem (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> false - | MapOne (k2, _) -> (comparer.Compare(k, k2) = 0) - | MapNode (k2, _, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then mem comparer k l - else (c = 0 || mem comparer k r) + if isEmpty m then false + else + let c = comparer.Compare(k, m.Key) + if m.Height = 1 then + c = 0 + else + let mn = asNode m + if c < 0 then mem comparer k mn.Left + else (c = 0 || mem comparer k mn.Right) + let rec iterOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = - match m with - | MapEmpty -> () - | MapOne (k2, v2) -> f.Invoke (k2, v2) - | MapNode (k2, v2, l, r, _) -> iterOpt f l; f.Invoke (k2, v2); iterOpt f r + if isEmpty m then () + else + if m.Height = 1 then + f.Invoke (m.Key, m.Value) + else + let mn = asNode m + iterOpt f mn.Left; f.Invoke (mn.Key, mn.Value); iterOpt f mn.Right + let iter f m = iterOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m - let rec tryPickOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) m = - match m with - | MapEmpty -> None - | MapOne (k2, v2) -> f.Invoke (k2, v2) - | MapNode (k2, v2, l, r, _) -> - match tryPickOpt f l with - | Some _ as res -> res - | None -> - match f.Invoke (k2, v2) with - | Some _ as res -> res - | None -> - tryPickOpt f r + let rec tryPickOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then None + else + if m.Height = 1 then + f.Invoke (m.Key, m.Value) + else + let mn = asNode m + match tryPickOpt f mn.Left with + | Some _ as res -> res + | None -> + match f.Invoke (mn.Key, mn.Value) with + | Some _ as res -> res + | None -> + tryPickOpt f mn.Right + let tryPick f m = tryPickOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m - let rec existsOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) m = - match m with - | MapEmpty -> false - | MapOne (k2, v2) -> f.Invoke (k2, v2) - | MapNode (k2, v2, l, r, _) -> existsOpt f l || f.Invoke (k2, v2) || existsOpt f r + let rec existsOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then false + else + if m.Height = 1 then + f.Invoke (m.Key, m.Value) + else + let mn = asNode m + existsOpt f mn.Left || f.Invoke (mn.Key, mn.Value) || existsOpt f mn.Right + let exists f m = existsOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m - let rec forallOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) m = - match m with - | MapEmpty -> true - | MapOne (k2, v2) -> f.Invoke (k2, v2) - | MapNode (k2, v2, l, r, _) -> forallOpt f l && f.Invoke (k2, v2) && forallOpt f r + let rec forallOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then true + else + if m.Height = 1 then + f.Invoke (m.Key, m.Value) + else + let mn = asNode m + forallOpt f mn.Left && f.Invoke (mn.Key, mn.Value) && forallOpt f mn.Right + + let forall f m = forallOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m - let rec map f m = - match m with - | MapEmpty -> empty - | MapOne (k, v) -> MapOne (k, f v) - | MapNode (k, v, l, r, h) -> - let l2 = map f l - let v2 = f v - let r2 = map f r - MapNode (k, v2, l2, r2, h) - - let rec mapiOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) m = - match m with - | MapEmpty -> empty - | MapOne (k, v) -> MapOne (k, f.Invoke (k, v)) - | MapNode (k, v, l, r, h) -> - let l2 = mapiOpt f l - let v2 = f.Invoke (k, v) - let r2 = mapiOpt f r - MapNode (k, v2, l2, r2, h) + let rec map (f:'Value -> 'Result) (m: MapTree<'Key, 'Value>) : MapTree<'Key, 'Result> = + if isEmpty m then empty + else + if m.Height = 1 then + MapTree (m.Key, f m.Value) + else + let mn = asNode m + let l2 = map f mn.Left + let v2 = f mn.Value + let r2 = map f mn.Right + MapTreeNode (mn.Key, v2, l2, r2, mn.Height) :> MapTree<'Key, 'Result> + + let rec mapiOpt (f: OptimizedClosures.FSharpFunc<'Key, 'Value, 'Result>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then empty + else + if m.Height = 1 then + MapTree (m.Key, f.Invoke (m.Key, m.Value)) + else + let mn = asNode m + let l2 = mapiOpt f mn.Left + let v2 = f.Invoke (mn.Key, mn.Value) + let r2 = mapiOpt f mn.Right + MapTreeNode (mn.Key, v2, l2, r2, mn.Height) :> MapTree<'Key, 'Result> + let mapi f m = mapiOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m - let rec foldBackOpt (f: OptimizedClosures.FSharpFunc<_, _, _, _>) m x = - match m with - | MapEmpty -> x - | MapOne (k, v) -> f.Invoke (k, v, x) - | MapNode (k, v, l, r, _) -> - let x = foldBackOpt f r x - let x = f.Invoke (k, v, x) - foldBackOpt f l x + let rec foldBackOpt (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + if isEmpty m then x + else + if m.Height = 1 then + f.Invoke (m.Key, m.Value, x) + else + let mn = asNode m + let x = foldBackOpt f mn.Right x + let x = f.Invoke (mn.Key, mn.Value, x) + foldBackOpt f mn.Left x + let foldBack f m x = foldBackOpt (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m x - let rec foldOpt (f: OptimizedClosures.FSharpFunc<_, _, _, _>) x m = - match m with - | MapEmpty -> x - | MapOne (k, v) -> f.Invoke (x, k, v) - | MapNode (k, v, l, r, _) -> - let x = foldOpt f x l - let x = f.Invoke (x, k, v) - foldOpt f x r + let rec foldOpt (f: OptimizedClosures.FSharpFunc<_, _, _, _>) x (m: MapTree<'Key, 'Value>) = + if isEmpty m then x + else + if m.Height = 1 then + f.Invoke (x, m.Key, m.Value) + else + let mn = asNode m + let x = foldOpt f x mn.Left + let x = f.Invoke (x, mn.Key, mn.Value) + foldOpt f x mn.Right let fold f x m = foldOpt (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) x m - let foldSectionOpt (comparer: IComparer<'Key>) lo hi (f: OptimizedClosures.FSharpFunc<_, _, _, _>) m x = - let rec foldFromTo (f: OptimizedClosures.FSharpFunc<_, _, _, _>) m x = - match m with - | MapEmpty -> x - | MapOne (k, v) -> - let cLoKey = comparer.Compare(lo, k) - let cKeyHi = comparer.Compare(k, hi) - let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (k, v, x) else x - x - | MapNode (k, v, l, r, _) -> - let cLoKey = comparer.Compare(lo, k) - let cKeyHi = comparer.Compare(k, hi) - let x = if cLoKey < 0 then foldFromTo f l x else x - let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (k, v, x) else x - let x = if cKeyHi < 0 then foldFromTo f r x else x - x + let foldSectionOpt (comparer: IComparer<'Key>) lo hi (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + let rec foldFromTo (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + if isEmpty m then x + else + if m.Height = 1 then + let cLoKey = comparer.Compare(lo, m.Key) + let cKeyHi = comparer.Compare(m.Key, hi) + let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (m.Key, m.Value, x) else x + x + else + let mn = asNode m + let cLoKey = comparer.Compare(lo, mn.Key) + let cKeyHi = comparer.Compare(mn.Key, hi) + let x = if cLoKey < 0 then foldFromTo f mn.Left x else x + let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (mn.Key, mn.Value, x) else x + let x = if cKeyHi < 0 then foldFromTo f mn.Right x else x + x if comparer.Compare(lo, hi) = 1 then x else foldFromTo f m x let foldSection (comparer: IComparer<'Key>) lo hi f m x = foldSectionOpt comparer lo hi (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m x - let toList m = - let rec loop m acc = - match m with - | MapEmpty -> acc - | MapOne (k, v) -> (k, v) :: acc - | MapNode (k, v, l, r, _) -> loop l ((k, v) :: loop r acc) + let toList (m: MapTree<'Key, 'Value>) = + let rec loop (m: MapTree<'Key, 'Value>) acc = + if isEmpty m then acc + else + if m.Height = 1 then + (m.Key, m.Value) :: acc + else + let mn = asNode m + loop mn.Left ((mn.Key, mn.Value) :: loop mn.Right acc) + loop m [] let toArray m = @@ -359,7 +445,7 @@ module MapTree = mkFromEnumerator comparer (add comparer x y acc) e else acc - let ofArray comparer (arr : array<_>) = + let ofArray comparer (arr : array<'Key * 'Value>) = let mutable res = empty for (x, y) in arr do res <- add comparer x y res @@ -389,12 +475,17 @@ module MapTree = // collapseLHS: // a) Always returns either [] or a list starting with MapOne. // b) The "fringe" of the set stack is unchanged. - let rec collapseLHS stack = + let rec collapseLHS (stack:MapTree<'Key, 'Value> list) = match stack with | [] -> [] - | MapEmpty :: rest -> collapseLHS rest - | MapOne _ :: _ -> stack - | (MapNode (k, v, l, r, _)) :: rest -> collapseLHS (l :: MapOne (k, v) :: r :: rest) + | m :: rest -> + if isEmpty m then collapseLHS rest + else + if m.Height = 1 then + stack + else + let mn = asNode m + collapseLHS (mn.Left :: MapTree (mn.Key, mn.Value) :: mn.Right :: rest) let mkIterator m = { stack = collapseLHS [m]; started = false } @@ -404,24 +495,32 @@ module MapTree = let alreadyFinished() = raise (InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) + + let unexpectedStackForCurrent() = + failwith "Please report error: Map iterator, unexpected stack for current" + + let unexpectedStackForMoveNext() = + failwith "Please report error: Map iterator, unexpected stack for moveNext" let current i = if i.started then match i.stack with - | MapOne (k, v) :: _ -> new KeyValuePair<_, _>(k, v) - | [] -> alreadyFinished() - | _ -> failwith "Please report error: Map iterator, unexpected stack for current" + | [] -> alreadyFinished() + | m :: _ -> + if m.Height = 1 then KeyValuePair<_, _>(m.Key, m.Value) + else unexpectedStackForCurrent() else notStarted() let rec moveNext i = if i.started then match i.stack with - | MapOne _ :: rest -> - i.stack <- collapseLHS rest - not i.stack.IsEmpty | [] -> false - | _ -> failwith "Please report error: Map iterator, unexpected stack for moveNext" + | m :: rest -> + if m.Height = 1 then + i.stack <- collapseLHS rest + not i.stack.IsEmpty + else unexpectedStackForMoveNext() else i.started <- true (* The first call to MoveNext "starts" the enumeration. *) not i.stack.IsEmpty @@ -429,15 +528,15 @@ module MapTree = let mkIEnumerator m = let mutable i = mkIterator m { new IEnumerator<_> with - member __.Current = current i + member _.Current = current i interface System.Collections.IEnumerator with - member __.Current = box (current i) - member __.MoveNext() = moveNext i - member __.Reset() = i <- mkIterator m + member _.Current = box (current i) + member _.MoveNext() = moveNext i + member _.Reset() = i <- mkIterator m interface System.IDisposable with - member __.Dispose() = ()} + member _.Dispose() = ()} [>)>] [] @@ -464,23 +563,23 @@ type Map<[]'Key, [ - new Map<'Key, 'Value>(comparer, MapTree<_, _>.MapEmpty) + new Map<'Key, 'Value>(comparer, MapTree.empty) [] - member __.OnSerializing(context: System.Runtime.Serialization.StreamingContext) = + member _.OnSerializing(context: System.Runtime.Serialization.StreamingContext) = ignore context serializedData <- MapTree.toArray tree |> Array.map (fun (k, v) -> KeyValuePair(k, v)) // Do not set this to null, since concurrent threads may also be serializing the data //[] - //member __.OnSerialized(context: System.Runtime.Serialization.StreamingContext) = + //member _.OnSerialized(context: System.Runtime.Serialization.StreamingContext) = // serializedData <- null [] - member __.OnDeserialized(context: System.Runtime.Serialization.StreamingContext) = + member _.OnDeserialized(context: System.Runtime.Serialization.StreamingContext) = ignore context comparer <- LanguagePrimitives.FastGenericComparer<'Key> - tree <- serializedData |> Array.map (fun (KeyValue(k, v)) -> (k, v)) |> MapTree.ofArray comparer + tree <- serializedData |> Array.map (fun kvp -> kvp.Key, kvp.Value) |> MapTree.ofArray comparer serializedData <- null static member Empty : Map<'Key, 'Value> = @@ -512,6 +611,9 @@ type Map<[]'Key, [(comparer, MapTree.add comparer key value tree) + member m.Change(key, f) : Map<'Key, 'Value> = + new Map<'Key, 'Value>(comparer, MapTree.change comparer key f tree) + [] member m.IsEmpty = MapTree.isEmpty tree @@ -545,8 +647,8 @@ type Map<[]'Key, [(comparer, MapTree.map f tree) + member m.MapRange (f:'Value->'Result) = + new Map<'Key, 'Result>(comparer, MapTree.map f tree) member m.Map f = new Map<'Key, 'b>(comparer, MapTree.mapi f tree) @@ -586,6 +688,10 @@ type Map<[]'Key, [ ICollection<'Key> + + member m.Values = ValueCollection(m) :> ICollection<'Value> + static member ofList l : Map<'Key, 'Value> = let comparer = LanguagePrimitives.FastGenericComparer<'Key> new Map<_, _>(comparer, MapTree.ofList comparer l) @@ -607,7 +713,8 @@ type Map<[]'Key, [ false @@ -615,42 +722,40 @@ type Map<[]'Key, [> with - member __.GetEnumerator() = MapTree.mkIEnumerator tree + member _.GetEnumerator() = MapTree.mkIEnumerator tree - interface System.Collections.IEnumerable with - member __.GetEnumerator() = (MapTree.mkIEnumerator tree :> System.Collections.IEnumerator) + interface IEnumerable with + member _.GetEnumerator() = (MapTree.mkIEnumerator tree :> IEnumerator) interface IDictionary<'Key, 'Value> with member m.Item with get x = m.[x] - and set x v = ignore(x, v); raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + and set _ _ = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) - // REVIEW: this implementation could avoid copying the Values to an array - member m.Keys = ([| for kvp in m -> kvp.Key |] :> ICollection<'Key>) + member m.Keys = m.Keys - // REVIEW: this implementation could avoid copying the Values to an array - member m.Values = ([| for kvp in m -> kvp.Value |] :> ICollection<'Value>) + member m.Values = m.Values - member m.Add(k, v) = ignore(k, v); raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + member m.Add(_, _) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) member m.ContainsKey k = m.ContainsKey k member m.TryGetValue(k, r) = m.TryGetValue(k, &r) - member m.Remove(k : 'Key) = ignore k; (raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) : bool) + member m.Remove(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) interface ICollection> with - member __.Add x = ignore x; raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + member _.Add(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) - member __.Clear() = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + member _.Clear() = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) - member __.Remove x = ignore x; raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + member _.Remove(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) member m.Contains x = m.ContainsKey x.Key && Unchecked.equals m.[x.Key] x.Value - member __.CopyTo(arr, i) = MapTree.copyToArray tree arr i + member _.CopyTo(arr, i) = MapTree.copyToArray tree arr i - member __.IsReadOnly = true + member _.IsReadOnly = true member m.Count = m.Count @@ -673,11 +778,11 @@ type Map<[]'Key, [ kvp.Key } + member m.Keys = m.Keys :> IEnumerable<'Key> member m.TryGetValue(key, value: byref<'Value>) = m.TryGetValue(key, &value) - member m.Values = seq { for kvp in m -> kvp.Value } + member m.Values = m.Values :> IEnumerable<'Value> member m.ContainsKey key = m.ContainsKey key @@ -717,6 +822,70 @@ and [] member x.KeyValue = keyValue +and KeyCollection<'Key, 'Value when 'Key : comparison>(parent: Map<'Key, 'Value>) = + interface ICollection<'Key> with + member _.Add(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Clear() = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Remove(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Contains x = parent.ContainsKey x + + member _.CopyTo(arr, index) = + if isNull arr then nullArg "arr" + if index < 0 then invalidArg "index" "index must be positive" + if index + parent.Count > arr.Length then invalidArg "index" "array is smaller than index plus the number of items to copy" + + let mutable i = index + for item in parent do + arr.[i] <- item.Key + i <- i + 1 + + member _.IsReadOnly = true + + member _.Count = parent.Count + + interface IEnumerable<'Key> with + member _.GetEnumerator() = + (seq { for item in parent do item.Key}).GetEnumerator() + + interface IEnumerable with + member _.GetEnumerator() = + (seq { for item in parent do item.Key}).GetEnumerator() :> IEnumerator + +and ValueCollection<'Key, 'Value when 'Key : comparison>(parent: Map<'Key, 'Value>) = + interface ICollection<'Value> with + member _.Add(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Clear() = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Remove(_) = raise (NotSupportedException(SR.GetString(SR.mapCannotBeMutated))) + + member _.Contains x = parent.Exists(fun _ value -> Unchecked.equals value x) + + member _.CopyTo(arr, index) = + if isNull arr then nullArg "arr" + if index < 0 then invalidArg "index" "index must be positive" + if index + parent.Count > arr.Length then invalidArg "index" "array is smaller than index plus the number of items to copy" + + let mutable i = index + for item in parent do + arr.[i] <- item.Value + i <- i + 1 + + member _.IsReadOnly = true + + member _.Count = parent.Count + + interface IEnumerable<'Value> with + member _.GetEnumerator() = + (seq { for item in parent do item.Value}).GetEnumerator() + + interface IEnumerable with + member _.GetEnumerator() = + (seq { for item in parent do item.Value }).GetEnumerator() :> IEnumerator + [] [] module Map = @@ -729,6 +898,10 @@ module Map = let add key value (table: Map<_, _>) = table.Add (key, value) + [] + let change key f (table: Map<_, _>) = + table.Change (key, f) + [] let find key (table: Map<_, _>) = table.[key] @@ -785,7 +958,7 @@ module Map = [] let foldBack<'Key, 'T, 'State when 'Key : comparison> folder (table: Map<'Key, 'T>) (state:'State) = - MapTree.foldBack folder table.Tree state + MapTree.foldBack folder table.Tree state [] let toSeq (table: Map<_, _>) = @@ -793,11 +966,11 @@ module Map = [] let findKey predicate (table : Map<_, _>) = - table |> toSeq |> Seq.pick (fun (k, v) -> if predicate k v then Some k else None) + table |> Seq.pick (fun kvp -> let k = kvp.Key in if predicate k kvp.Value then Some k else None) [] let tryFindKey predicate (table : Map<_, _>) = - table |> toSeq |> Seq.tryPick (fun (k, v) -> if predicate k v then Some k else None) + table |> Seq.tryPick (fun kvp -> let k = kvp.Key in if predicate k kvp.Value then Some k else None) [] let ofList (elements: ('Key * 'Value) list) = @@ -827,3 +1000,9 @@ module Map = [] let count (table: Map<_, _>) = table.Count + + [] + let keys (table: Map<_, _>) = table.Keys + + [] + let values (table: Map<_, _>) = table.Values diff --git a/src/fsharp/FSharp.Core/map.fsi b/src/fsharp/FSharp.Core/map.fsi index 9a702596a4c..9759af14467 100644 --- a/src/fsharp/FSharp.Core/map.fsi +++ b/src/fsharp/FSharp.Core/map.fsi @@ -2,265 +2,444 @@ namespace Microsoft.FSharp.Collections - open System - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - /// Immutable maps. Keys are ordered by F# generic comparison. - /// - /// Maps based on generic comparison are efficient for small keys. They are not a suitable choice if keys are recursive data structures - /// or if keys require bespoke comparison semantics. - /// - /// All members of this class are thread-safe and may be used concurrently from multiple threads. - [] - [] - type Map<[]'Key,[]'Value when 'Key : comparison> = - /// Returns a new map with the binding added to the given map. - /// If a binding with the given key already exists in the input map, the existing binding is replaced by the new binding in the result map. - /// The input key. - /// The resulting map. - member Add: key:'Key * value:'Value -> Map<'Key,'Value> - - /// Returns true if there are no bindings in the map. - member IsEmpty: bool - - /// Builds a map that contains the bindings of the given IEnumerable. - /// The input sequence of key/value pairs. - /// The resulting map. - new : elements:seq<'Key * 'Value> -> Map<'Key,'Value> - - /// Tests if an element is in the domain of the map. - /// The input key. - /// True if the map contains the given key. - member ContainsKey: key:'Key -> bool - - /// The number of bindings in the map. - member Count: int - - /// Lookup an element in the map. Raise KeyNotFoundException if no binding - /// exists in the map. - /// The input key. - /// Thrown when the key is not found. - /// The value mapped to the key. - member Item : key:'Key -> 'Value with get - - /// Removes an element from the domain of the map. No exception is raised if the element is not present. - /// The input key. - /// The resulting map. - member Remove: key:'Key -> Map<'Key,'Value> - - /// Lookup an element in the map, returning a Some value if the element is in the domain - /// of the map and None if not. - /// The input key. - /// The mapped value, or None if the key is not in the map. - member TryFind: key:'Key -> 'Value option - - /// Lookup an element in the map, assigning to value if the element is in the domain - /// of the map and returning false if not. - /// The input key. - /// A reference to the output value. - /// true if the value is present, false if not. - member TryGetValue: key:'Key * [] value:byref<'Value> -> bool - - interface IDictionary<'Key, 'Value> - interface ICollection> - interface IEnumerable> - interface System.IComparable - interface System.Collections.IEnumerable - interface IReadOnlyCollection> - interface IReadOnlyDictionary<'Key,'Value> - override Equals : obj -> bool - - /// Functional programming operators related to the Map<_,_> type. - [] - [] - module Map = - - /// Returns a new map with the binding added to the given map. - /// If a binding with the given key already exists in the input map, the existing binding is replaced by the new binding in the result map. - /// The input key. - /// The input value. - /// The input map. - /// The resulting map. - [] - val add: key:'Key -> value:'T -> table:Map<'Key,'T> -> Map<'Key,'T> - - /// Returns a new map made from the given bindings. - /// The input list of key/value pairs. - /// The resulting map. - [] - val ofList: elements:('Key * 'T) list -> Map<'Key,'T> - - /// Returns a new map made from the given bindings. - /// The input array of key/value pairs. - /// The resulting map. - [] - val ofArray: elements:('Key * 'T)[] -> Map<'Key,'T> - - /// Returns a new map made from the given bindings. - /// The input sequence of key/value pairs. - /// The resulting map. - [] - val ofSeq: elements:seq<'Key * 'T> -> Map<'Key,'T> - - /// Views the collection as an enumerable sequence of pairs. - /// The sequence will be ordered by the keys of the map. - /// The input map. - /// The sequence of key/value pairs. - [] - val toSeq: table:Map<'Key,'T> -> seq<'Key * 'T> - - /// Returns a list of all key-value pairs in the mapping. - /// The list will be ordered by the keys of the map. - /// The input map. - /// The list of key/value pairs. - [] - val toList: table:Map<'Key,'T> -> ('Key * 'T) list - - /// Returns an array of all key-value pairs in the mapping. - /// The array will be ordered by the keys of the map. - /// The input map. - /// The array of key/value pairs. - [] - val toArray: table:Map<'Key,'T> -> ('Key * 'T)[] - - /// Is the map empty? - /// The input map. - /// True if the map is empty. - [] - val isEmpty: table:Map<'Key,'T> -> bool - - /// The empty map. - [] - [] - val empty<'Key,'T> : Map<'Key,'T> when 'Key : comparison - - /// Lookup an element in the map, raising KeyNotFoundException if no binding - /// exists in the map. - /// The input key. - /// The input map. - /// Thrown when the key does not exist in the map. - /// The value mapped to the given key. - [] - val find: key:'Key -> table:Map<'Key,'T> -> 'T - - /// Searches the map looking for the first element where the given function returns a Some value. - /// The function to generate options from the key/value pairs. - /// The input map. - /// The first result. - [] - val tryPick: chooser:('Key -> 'T -> 'U option) -> table:Map<'Key,'T> -> 'U option - - /// Searches the map looking for the first element where the given function returns a Some value - /// The function to generate options from the key/value pairs. - /// The input map. - /// The first result. - [] - val pick: chooser:('Key -> 'T -> 'U option) -> table:Map<'Key,'T> -> 'U - - /// Folds over the bindings in the map. - /// The function to update the state given the input key/value pairs. - /// The input map. - /// The initial state. - /// The final state value. - [] - val foldBack<'Key,'T,'State> : folder:('Key -> 'T -> 'State -> 'State) -> table:Map<'Key,'T> -> state:'State -> 'State when 'Key : comparison - - /// Folds over the bindings in the map - /// The function to update the state given the input key/value pairs. - /// The initial state. - /// The input map. - /// The final state value. - [] - val fold<'Key,'T,'State> : folder:('State -> 'Key -> 'T -> 'State) -> state:'State -> table:Map<'Key,'T> -> 'State when 'Key : comparison - - /// Applies the given function to each binding in the dictionary - /// The function to apply to each key/value pair. - /// The input map. - [] - val iter: action:('Key -> 'T -> unit) -> table:Map<'Key,'T> -> unit - - /// Returns true if the given predicate returns true for one of the - /// bindings in the map. - /// The function to test the input elements. - /// The input map. - /// True if the predicate returns true for one of the key/value pairs. - [] - val exists: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> bool - - /// Builds a new map containing only the bindings for which the given predicate returns 'true'. - /// The function to test the key/value pairs. - /// The input map. - /// The filtered map. - [] - val filter: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> Map<'Key, 'T> - - /// Returns true if the given predicate returns true for all of the - /// bindings in the map. - /// The function to test the input elements. - /// The input map. - /// True if the predicate evaluates to true for all of the bindings in the map. - [] - val forall: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> bool - - /// Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The key passed to the - /// function indicates the key of element being transformed. - /// The function to transform the key/value pairs. - /// The input map. - /// The resulting map of keys and transformed values. - [] - val map: mapping:('Key -> 'T -> 'U) -> table:Map<'Key,'T> -> Map<'Key,'U> - - /// Tests if an element is in the domain of the map. - /// The input key. - /// The input map. - /// True if the map contains the key. - [] - val containsKey: key:'Key -> table:Map<'Key,'T> -> bool - - /// Builds two new maps, one containing the bindings for which the given predicate returns 'true', - /// and the other the remaining bindings. - /// The function to test the input elements. - /// The input map. - /// A pair of maps in which the first contains the elements for which the predicate returned true - /// and the second containing the elements for which the predicated returned false. - [] - val partition: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> Map<'Key, 'T> * Map<'Key, 'T> - - /// Removes an element from the domain of the map. No exception is raised if the element is not present. - /// The input key. - /// The input map. - /// The resulting map. - [] - val remove: key:'Key -> table:Map<'Key,'T> -> Map<'Key,'T> - - /// Lookup an element in the map, returning a Some value if the element is in the domain - /// of the map and None if not. - /// The input key. - /// The input map. - /// The found Some value or None. - [] - val tryFind: key:'Key -> table:Map<'Key,'T> -> 'T option - - /// Evaluates the function on each mapping in the collection. Returns the key for the first mapping - /// where the function returns 'true'. Raise KeyNotFoundException if no such element exists. - /// The function to test the input elements. - /// The input map. - /// Thrown if the key does not exist in the map. - /// The first key for which the predicate evaluates true. - [] - val findKey: predicate:('Key -> 'T -> bool) -> table:Map<'Key,'T> -> 'Key - - /// Returns the key of the first mapping in the collection that satisfies the given predicate. - /// Returns 'None' if no such element exists. - /// The function to test the input elements. - /// The input map. - /// The first key for which the predicate returns true or None if the predicate evaluates to false for each key/value pair. - [] - val tryFindKey: predicate:('Key -> 'T -> bool) -> table:Map<'Key,'T> -> 'Key option - - /// The number of bindings in the map. - [] - val count: table:Map<'Key,'T> -> int \ No newline at end of file +open System +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +/// Immutable maps based on binary trees, where keys are ordered by F# generic comparison. By default +/// comparison is the F# structural comparison function or uses implementations of the IComparable interface on key values. +/// +/// See the module for further operations on maps. +/// +/// All members of this class are thread-safe and may be used concurrently from multiple threads. +[] +[] +type Map<[]'Key,[]'Value when 'Key : comparison> = + /// Returns a new map with the binding added to the given map. + /// If a binding with the given key already exists in the input map, the existing binding is replaced by the new binding in the result map. + /// The key to add. + /// The value to add. + /// + /// The resulting map. + /// + /// + member Add: key:'Key * value:'Value -> Map<'Key,'Value> + + /// Returns a new map with the value stored under key changed according to f. + /// + /// The input key. + /// The change function. + /// + /// The resulting map. + /// + /// + member Change: key:'Key * f:('Value option -> 'Value option) -> Map<'Key,'Value> + + /// Returns true if there are no bindings in the map. + /// + /// + member IsEmpty: bool + + /// Builds a map that contains the bindings of the given IEnumerable. + /// + /// The input sequence of key/value pairs. + /// + /// The resulting map. + /// + /// + new : elements:seq<'Key * 'Value> -> Map<'Key,'Value> + + /// Tests if an element is in the domain of the map. + /// + /// The input key. + /// + /// True if the map contains the given key. + /// + /// + member ContainsKey: key:'Key -> bool + + /// The number of bindings in the map. + /// + /// + member Count: int + + /// Lookup an element in the map. Raise KeyNotFoundException if no binding + /// exists in the map. + /// + /// The input key. + /// Thrown when the key is not found. + /// + /// The value mapped to the key. + /// + /// + member Item : key:'Key -> 'Value with get + + /// Removes an element from the domain of the map. No exception is raised if the element is not present. + /// + /// The input key. + /// + /// The resulting map. + /// + /// + member Remove: key:'Key -> Map<'Key,'Value> + + /// Lookup an element in the map, returning a Some value if the element is in the domain + /// of the map and None if not. + /// + /// The input key. + /// + /// The mapped value, or None if the key is not in the map. + /// + /// + member TryFind: key:'Key -> 'Value option + + /// Lookup an element in the map, assigning to value if the element is in the domain + /// of the map and returning false if not. + /// + /// The input key. + /// A reference to the output value. + /// + /// true if the value is present, false if not. + /// + /// + member TryGetValue: key: 'Key * [] value: byref<'Value> -> bool + + /// The keys in the map. + /// The sequence will be ordered by the keys of the map. + /// + /// + member Keys : ICollection<'Key> + + /// All the values in the map, including the duplicates. + /// The sequence will be ordered by the keys of the map. + /// + /// + member Values : ICollection<'Value> + + interface IDictionary<'Key, 'Value> + interface ICollection> + interface IEnumerable> + interface System.IComparable + interface System.Collections.IEnumerable + interface IReadOnlyCollection> + interface IReadOnlyDictionary<'Key,'Value> + override Equals : obj -> bool + +/// Contains operations for working with values of type . +[] +[] +module Map = + + /// Returns a new map with the binding added to the given map. + /// If a binding with the given key already exists in the input map, the existing binding is replaced by the new binding in the result map. + /// + /// The input key. + /// The input value. + /// The input map. + /// + /// The resulting map. + /// + /// + [] + val add: key:'Key -> value:'T -> table:Map<'Key,'T> -> Map<'Key,'T> + + /// Returns a new map with the value stored under key changed according to f. + /// + /// The input key. + /// The change function. + /// The input map. + /// + /// The resulting map. + /// + /// + [] + val change: key:'Key -> f:('T option -> 'T option) -> table:Map<'Key,'T> -> Map<'Key,'T> + + /// Returns a new map made from the given bindings. + /// + /// The input list of key/value pairs. + /// + /// The resulting map. + /// + /// + [] + val ofList: elements:('Key * 'T) list -> Map<'Key,'T> + + /// Returns a new map made from the given bindings. + /// + /// The input array of key/value pairs. + /// + /// The resulting map. + /// + /// + [] + val ofArray: elements:('Key * 'T)[] -> Map<'Key,'T> + + /// Returns a new map made from the given bindings. + /// + /// The input sequence of key/value pairs. + /// + /// The resulting map. + /// + /// + [] + val ofSeq: elements:seq<'Key * 'T> -> Map<'Key,'T> + + /// Views the collection as an enumerable sequence of pairs. + /// The sequence will be ordered by the keys of the map. + /// + /// The input map. + /// + /// The sequence of key/value pairs. + /// + /// + [] + val toSeq: table:Map<'Key,'T> -> seq<'Key * 'T> + + /// Returns a list of all key-value pairs in the mapping. + /// The list will be ordered by the keys of the map. + /// + /// The input map. + /// + /// The list of key/value pairs. + /// + /// + [] + val toList: table:Map<'Key,'T> -> ('Key * 'T) list + + /// Returns an array of all key-value pairs in the mapping. + /// The array will be ordered by the keys of the map. + /// + /// The input map. + /// + /// The array of key/value pairs. + /// + /// + [] + val toArray: table:Map<'Key,'T> -> ('Key * 'T)[] + + /// Is the map empty? + /// + /// The input map. + /// + /// True if the map is empty. + /// + /// + [] + val isEmpty: table:Map<'Key,'T> -> bool + + /// The empty map. + /// + /// + [] + [] + val empty<'Key,'T> : Map<'Key,'T> when 'Key : comparison + + /// Lookup an element in the map, raising KeyNotFoundException if no binding + /// exists in the map. + /// + /// The input key. + /// The input map. + /// Thrown when the key does not exist in the map. + /// + /// The value mapped to the given key. + /// + /// + [] + val find: key:'Key -> table:Map<'Key,'T> -> 'T + + /// Searches the map looking for the first element where the given function returns a Some value. + /// + /// The function to generate options from the key/value pairs. + /// The input map. + /// + /// The first result. + /// + /// + [] + val tryPick: chooser:('Key -> 'T -> 'U option) -> table:Map<'Key,'T> -> 'U option + + /// Searches the map looking for the first element where the given function returns a Some value + /// + /// The function to generate options from the key/value pairs. + /// The input map. + /// + /// The first result. + /// + /// + [] + val pick: chooser:('Key -> 'T -> 'U option) -> table:Map<'Key,'T> -> 'U + + /// Folds over the bindings in the map. + /// + /// The function to update the state given the input key/value pairs. + /// The input map. + /// The initial state. + /// + /// The final state value. + /// + /// + [] + val foldBack<'Key,'T,'State> : folder:('Key -> 'T -> 'State -> 'State) -> table:Map<'Key,'T> -> state:'State -> 'State when 'Key : comparison + + /// Folds over the bindings in the map + /// + /// The function to update the state given the input key/value pairs. + /// The initial state. + /// The input map. + /// + /// The final state value. + /// + /// + [] + val fold<'Key,'T,'State> : folder:('State -> 'Key -> 'T -> 'State) -> state:'State -> table:Map<'Key,'T> -> 'State when 'Key : comparison + + /// Applies the given function to each binding in the dictionary + /// + /// The function to apply to each key/value pair. + /// The input map. + /// + /// + [] + val iter: action:('Key -> 'T -> unit) -> table:Map<'Key,'T> -> unit + + /// Returns true if the given predicate returns true for one of the + /// bindings in the map. + /// + /// The function to test the input elements. + /// The input map. + /// + /// True if the predicate returns true for one of the key/value pairs. + /// + /// + [] + val exists: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> bool + + /// Builds a new map containing only the bindings for which the given predicate returns 'true'. + /// + /// The function to test the key/value pairs. + /// The input map. + /// + /// The filtered map. + /// + /// + [] + val filter: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> Map<'Key, 'T> + + /// Returns true if the given predicate returns true for all of the + /// bindings in the map. + /// + /// The function to test the input elements. + /// The input map. + /// + /// True if the predicate evaluates to true for all of the bindings in the map. + /// + /// + [] + val forall: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> bool + + /// Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The key passed to the + /// function indicates the key of element being transformed. + /// + /// The function to transform the key/value pairs. + /// The input map. + /// + /// The resulting map of keys and transformed values. + /// + /// + [] + val map: mapping:('Key -> 'T -> 'U) -> table:Map<'Key,'T> -> Map<'Key,'U> + + /// Tests if an element is in the domain of the map. + /// + /// The input key. + /// The input map. + /// + /// True if the map contains the key. + /// + /// + [] + val containsKey: key:'Key -> table:Map<'Key,'T> -> bool + + /// Builds two new maps, one containing the bindings for which the given predicate returns 'true', + /// and the other the remaining bindings. + /// + /// The function to test the input elements. + /// The input map. + /// + /// A pair of maps in which the first contains the elements for which the predicate returned true + /// and the second containing the elements for which the predicated returned false. + /// + /// + [] + val partition: predicate:('Key -> 'T -> bool) -> table:Map<'Key, 'T> -> Map<'Key, 'T> * Map<'Key, 'T> + + /// Removes an element from the domain of the map. No exception is raised if the element is not present. + /// + /// The input key. + /// The input map. + /// + /// The resulting map. + /// + /// + [] + val remove: key:'Key -> table:Map<'Key,'T> -> Map<'Key,'T> + + /// Lookup an element in the map, returning a Some value if the element is in the domain + /// of the map and None if not. + /// + /// The input key. + /// The input map. + /// + /// The found Some value or None. + /// + /// + [] + val tryFind: key:'Key -> table:Map<'Key,'T> -> 'T option + + /// Evaluates the function on each mapping in the collection. Returns the key for the first mapping + /// where the function returns 'true'. Raise KeyNotFoundException if no such element exists. + /// + /// The function to test the input elements. + /// The input map. + /// Thrown if the key does not exist in the map. + /// + /// The first key for which the predicate evaluates true. + /// + /// + [] + val findKey: predicate:('Key -> 'T -> bool) -> table:Map<'Key,'T> -> 'Key + + /// Returns the key of the first mapping in the collection that satisfies the given predicate. + /// Returns 'None' if no such element exists. + /// + /// The function to test the input elements. + /// The input map. + /// + /// The first key for which the predicate returns true or None if the predicate evaluates to false for each key/value pair. + /// + /// + [] + val tryFindKey: predicate:('Key -> 'T -> bool) -> table:Map<'Key,'T> -> 'Key option + + /// The number of bindings in the map. + /// + /// + [] + val count: table:Map<'Key,'T> -> int + + /// The keys in the map. + /// The sequence will be ordered by the keys of the map. + /// + /// + [] + val keys: table: Map<'Key, 'T> -> ICollection<'Key> + + /// The values in the map, including the duplicates. + /// The sequence will be ordered by the keys of the map. + /// + /// + [] + val values: table: Map<'Key, 'T> -> ICollection<'T> diff --git a/src/fsharp/FSharp.Core/math/z.fsi b/src/fsharp/FSharp.Core/math/z.fsi index e49b1b3d532..463d57f3db0 100644 --- a/src/fsharp/FSharp.Core/math/z.fsi +++ b/src/fsharp/FSharp.Core/math/z.fsi @@ -12,10 +12,15 @@ namespace Microsoft.FSharp.Math namespace Microsoft.FSharp.Core + /// An abbreviation for . + /// + /// Basic Types type bigint = System.Numerics.BigInteger [] - /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' + /// + /// Language Primitives module NumericLiterals = /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' @@ -24,15 +29,21 @@ namespace Microsoft.FSharp.Core /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromZero : value:unit -> 'T + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromOne : value:unit -> 'T + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromInt32 : value:int32 -> 'T + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromInt64 : value:int64 -> 'T + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromString : text:string -> 'T + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromInt64Dynamic : value:int64 -> obj + /// Provides a default implementations of F# numeric literal syntax for literals of the form 'dddI' val FromStringDynamic : text:string -> obj diff --git a/src/fsharp/FSharp.Core/nativeptr.fs b/src/fsharp/FSharp.Core/nativeptr.fs index db9f81bf8a5..ba5d7b162a3 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fs +++ b/src/fsharp/FSharp.Core/nativeptr.fs @@ -16,47 +16,78 @@ open System.Runtime.InteropServices [] module NativePtr = - [] [] - let inline ofNativeInt (address:nativeint) = (# "" address : nativeptr<'T> #) + let inline ofNativeInt (address: nativeint) = (# "" address : nativeptr<'T> #) [] [] - let inline toNativeInt (address: nativeptr<'T>) = (# "" address : nativeint #) + let inline toNativeInt (address: nativeptr<'T>) = (# "" address : nativeint #) + + [] + [] + let inline ofVoidPtr (address: voidptr) = (# "" address : nativeptr<'T> #) [] [] let inline toVoidPtr (address: nativeptr<'T>) = (# "" address : voidptr #) [] - [] - let inline ofVoidPtr (address: voidptr) = (# "" address : nativeptr<'T> #) + [] + let inline ofILSigPtr (address: ilsigptr<'T>) = (# "" address : nativeptr<'T> #) + + [] + [] + let inline toILSigPtr (address: nativeptr<'T>) = (# "" address : ilsigptr<'T> #) + + [] + [] + let inline toByRef (address: nativeptr<'T>) : byref<'T> = (# "" address : 'T byref #) [] [] - let inline add (address : nativeptr<'T>) (index:int) : nativeptr<'T> = toNativeInt address + nativeint index * (# "sizeof !0" type('T) : nativeint #) |> ofNativeInt + let inline add (address: nativeptr<'T>) (index: int) : nativeptr<'T> = toNativeInt address + nativeint index * (# "sizeof !0" type('T) : nativeint #) |> ofNativeInt [] [] - let inline get (address : nativeptr<'T>) index = (# "ldobj !0" type ('T) (add address index) : 'T #) + let inline get (address: nativeptr<'T>) index = (# "ldobj !0" type('T) (add address index) : 'T #) [] [] - let inline set (address : nativeptr<'T>) index (value : 'T) = (# "stobj !0" type ('T) (add address index) value #) + let inline set (address: nativeptr<'T>) index (value: 'T) = (# "stobj !0" type('T) (add address index) value #) [] [] - let inline read (address : nativeptr<'T>) = (# "ldobj !0" type ('T) address : 'T #) + let inline read (address: nativeptr<'T>) = (# "ldobj !0" type('T) address : 'T #) [] [] - let inline write (address : nativeptr<'T>) (value : 'T) = (# "stobj !0" type ('T) address value #) + let inline write (address: nativeptr<'T>) (value : 'T) = (# "stobj !0" type('T) address value #) [] [] - let inline stackalloc (count:int) : nativeptr<'T> = (# "localloc" (count * sizeof<'T>) : nativeptr<'T> #) + let inline stackalloc (count: int) : nativeptr<'T> = (# "localloc" (count * sizeof<'T>) : nativeptr<'T> #) + + [] + [] + let inline nullPtr<'T when 'T : unmanaged> : nativeptr<'T> = (# "" 0n : nativeptr<'T> #) + + [] + [] + let inline isNullPtr (address: nativeptr<'T>) = (# "ceq" nullPtr<'T> address : bool #) + + [] + [] + let inline clear (address: nativeptr<'T>) = (# "initobj !0" type('T) address #) [] - [] - let inline toByRef (address: nativeptr<'T>) : byref<'T> = (# "" address : 'T byref #) + [] + let inline initBlock (address: nativeptr<'T>) (value: byte) (count: uint32) = (# "initblk" address value count #) + + [] + [] + let inline copy (destination: nativeptr<'T>) (source: nativeptr<'T>) = (# "cpobj !0" type('T) destination source #) + + [] + [] + let inline copyBlock (destination: nativeptr<'T>) (source: nativeptr<'T>) (count: int) = (# "cpblk" destination source (count * sizeof<'T>) #) \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/nativeptr.fsi b/src/fsharp/FSharp.Core/nativeptr.fsi index db6a6d9e2f0..0c13ec823a5 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fsi +++ b/src/fsharp/FSharp.Core/nativeptr.fsi @@ -2,106 +2,226 @@ namespace Microsoft.FSharp.NativeInterop - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - [] - [] - /// Contains operations on native pointers. Use of these operators may - /// result in the generation of unverifiable code. - module NativePtr = - - [] - [] - [] - /// Returns a typed native pointer for a given machine address. - /// The pointer address. - /// A typed pointer. - val inline ofNativeInt : address:nativeint -> nativeptr<'T> - - [] - [] - [] - /// Returns an untyped native pointer for a given typed pointer. - /// The pointer address. - /// A typed pointer. - val inline toVoidPtr : address:nativeptr<'T> -> voidptr - - [] - [] - [] - /// Returns a typed native pointer for a untyped native pointer. - /// The untyped pointer. - /// A typed pointer. - val inline ofVoidPtr : voidptr -> nativeptr<'T> - - [] - [] - [] - /// Returns a machine address for a given typed native pointer. - /// The input pointer. - /// The machine address. - val inline toNativeInt : address:nativeptr<'T> -> nativeint - - - [] - [] - [] - /// Returns a typed native pointer by adding index * sizeof<'T> to the - /// given input pointer. - /// The input pointer. - /// The index by which to offset the pointer. - /// A typed pointer. - val inline add : address:nativeptr<'T> -> index:int -> nativeptr<'T> - - [] - [] - [] - /// Dereferences the typed native pointer computed by adding index * sizeof<'T> to the - /// given input pointer. - /// The input pointer. - /// The index by which to offset the pointer. - /// The value at the pointer address. - val inline get : address:nativeptr<'T> -> index:int -> 'T - - [] - [] - [] - /// Dereferences the given typed native pointer. - /// The input pointer. - /// The value at the pointer address. - val inline read : address:nativeptr<'T> -> 'T - - [] - [] - [] - /// Assigns the value into the memory location referenced by the given typed native pointer. - /// The input pointer. - /// The value to assign. - val inline write : address:nativeptr<'T> -> value:'T -> unit - - [] - [] - [] - /// Assigns the value into the memory location referenced by the typed native - /// pointer computed by adding index * sizeof<'T> to the given input pointer. - /// The input pointer. - /// The index by which to offset the pointer. - /// The value to assign. - val inline set : address:nativeptr<'T> -> index:int -> value:'T -> unit - - /// Allocates a region of memory on the stack. - /// The number of objects of type T to allocate. - /// A typed pointer to the allocated memory. - [] - [] - [] - val inline stackalloc : count:int -> nativeptr<'T> - - /// Converts a given typed native pointer to a managed pointer. - /// The input pointer. - /// The managed pointer. - [] - [] - [] - val inline toByRef : nativeptr<'T> -> byref<'T> +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +[] +[] +/// Contains operations on native pointers. Use of these operators may +/// result in the generation of unverifiable code. +/// +/// +/// Library functionality for native interopability. See +/// also F# External Functions in +/// the F# Language Guide. +/// +module NativePtr = + + /// Returns a typed native pointer for a given machine address. + /// + /// The machine address. + /// + /// A typed native pointer. + /// + /// + [] + [] + val inline ofNativeInt : address: nativeint -> nativeptr<'T> + + /// Returns a machine address for a given typed native pointer. + /// + /// The typed native pointer. + /// + /// The machine address. + /// + /// + [] + [] + val inline toNativeInt : address: nativeptr<'T> -> nativeint + + /// Returns a typed native pointer for a untyped native pointer. + /// + /// The untyped native pointer. + /// + /// A typed native pointer. + /// + /// + [] + [] + val inline ofVoidPtr : address: voidptr -> nativeptr<'T> + + /// Returns an untyped native pointer for a given typed native pointer. + /// + /// The typed native pointer. + /// + /// An untyped native pointer. + /// + /// + [] + [] + val inline toVoidPtr : address: nativeptr<'T> -> voidptr + + /// Returns a typed native pointer for a Common IL (Intermediate Language) signature pointer. + /// + /// The Common IL signature pointer. + /// + /// A typed native pointer. + /// + /// + [] + [] + val inline ofILSigPtr : address: ilsigptr<'T> -> nativeptr<'T> + + /// Returns a Common IL (Intermediate Language) signature pointer for a given typed native pointer. + /// + /// The typed native pointer. + /// + /// A Common IL signature pointer. + /// + /// + [] + [] + val inline toILSigPtr : address: nativeptr<'T> -> ilsigptr<'T> + + /// Converts a given typed native pointer to a managed pointer. + /// + /// The typed native pointer. + /// + /// The managed pointer. + /// + /// + [] + [] + val inline toByRef: address: nativeptr<'T> -> byref<'T> + + /// Returns a typed native pointer by adding index * sizeof<'T> to the + /// given input pointer. + /// + /// The input pointer. + /// The index by which to offset the pointer. + /// + /// A typed pointer. + /// + /// + [] + [] + val inline add : address: nativeptr<'T> -> index: int -> nativeptr<'T> + + /// Dereferences the typed native pointer computed by adding index * sizeof<'T> to the + /// given input pointer. + /// + /// The input pointer. + /// The index by which to offset the pointer. + /// + /// The value at the pointer address. + /// + /// + [] + [] + val inline get : address: nativeptr<'T> -> index: int -> 'T + + /// Dereferences the given typed native pointer. + /// + /// The input pointer. + /// + /// The value at the pointer address. + /// + /// + [] + [] + val inline read : address: nativeptr<'T> -> 'T + + /// Assigns the value into the memory location referenced by the given typed native pointer. + /// + /// The input pointer. + /// The value to assign. + /// + /// + [] + [] + val inline write : address: nativeptr<'T> -> value: 'T -> unit + + /// Assigns the value into the memory location referenced by the typed native + /// pointer computed by adding index * sizeof<'T> to the given input pointer. + /// + /// The input pointer. + /// The index by which to offset the pointer. + /// The value to assign. + /// + /// + [] + [] + val inline set : address: nativeptr<'T> -> index: int -> value: 'T -> unit + + /// Allocates a region of memory on the stack. + /// + /// The number of objects of type T to allocate. + /// + /// A typed pointer to the allocated memory. + /// + /// + [] + [] + val inline stackalloc: count: int -> nativeptr<'T> + + /// Gets the null native pointer. + /// + /// The null native pointer. + /// + /// + [] + [] + [] + val inline nullPtr<'T when 'T : unmanaged> : nativeptr<'T> + + /// Tests whether the given native pointer is null. + /// + /// The input pointer. + /// + /// Whether the given native pointer is null. + /// + /// + [] + [] + val inline isNullPtr: address: nativeptr<'T> -> bool + + /// Clears the value stored at the location of a given native pointer. + /// + /// The input pointer. + /// + /// + [] + [] + val inline clear : address: nativeptr<'T> -> unit + + /// Initializes a specified block of memory starting at a specific address to a given byte count and initial byte value. + /// + /// The input pointer. + /// The initial byte value. + /// The total repeat count of the byte value. + /// + /// + [] + [] + val inline initBlock : address: nativeptr<'T> -> value: byte -> count: uint32 -> unit + + /// Copies a value to a specified destination address from a specified source address. + /// + /// The destination pointer. + /// The source pointer. + /// + /// + [] + [] + val inline copy : destination: nativeptr<'T> -> source: nativeptr<'T> -> unit + + /// Copies a block of memory to a specified destination address starting from a specified source address until a specified byte count of (count * sizeof<'T>). + /// + /// The destination pointer. + /// The source pointer. + /// The source pointer. + /// + /// + [] + [] + val inline copyBlock : destination: nativeptr<'T> -> source: nativeptr<'T> -> count: int -> unit diff --git a/src/fsharp/FSharp.Core/observable.fsi b/src/fsharp/FSharp.Core/observable.fsi index 36cbee5700d..80c77039ee0 100644 --- a/src/fsharp/FSharp.Core/observable.fsi +++ b/src/fsharp/FSharp.Core/observable.fsi @@ -2,130 +2,168 @@ namespace Microsoft.FSharp.Control - open System - open Microsoft.FSharp.Core +open System +open Microsoft.FSharp.Core - [] - [] - /// Basic operations on first class event and other observable objects. - module Observable = +[] +[] +/// Contains operations for working with first class event and other observable objects. +/// +/// Events and Observables +module Observable = - /// Returns an observable for the merged observations from the sources. - /// The returned object propagates success and error values arising - /// from either source and completes when both the sources have completed. - /// - /// For each observer, the registered intermediate observing object is not - /// thread safe. That is, observations arising from the sources must not - /// be triggered concurrently on different threads. - /// The first Observable. - /// The second Observable. - /// An Observable that propagates information from both sources. - [] - val merge: source1:IObservable<'T> -> source2:IObservable<'T> -> IObservable<'T> + /// Returns an observable for the merged observations from the sources. + /// The returned object propagates success and error values arising + /// from either source and completes when both the sources have completed. + /// + /// For each observer, the registered intermediate observing object is not + /// thread safe. That is, observations arising from the sources must not + /// be triggered concurrently on different threads. + /// + /// The first Observable. + /// The second Observable. + /// + /// An Observable that propagates information from both sources. + /// + /// + [] + val merge: source1:IObservable<'T> -> source2:IObservable<'T> -> IObservable<'T> - /// Returns an observable which transforms the observations of the source by the - /// given function. The transformation function is executed once for each - /// subscribed observer. The returned object also propagates error observations - /// arising from the source and completes when the source completes. - /// The function applied to observations from the source. - /// The input Observable. - /// An Observable of the type specified by mapping. - [] - val map: mapping:('T -> 'U) -> source:IObservable<'T> -> IObservable<'U> + /// Returns an observable which transforms the observations of the source by the + /// given function. The transformation function is executed once for each + /// subscribed observer. The returned object also propagates error observations + /// arising from the source and completes when the source completes. + /// The function applied to observations from the source. + /// The input Observable. + /// + /// An Observable of the type specified by mapping. + /// + /// + [] + val map: mapping:('T -> 'U) -> source:IObservable<'T> -> IObservable<'U> - /// Returns an observable which filters the observations of the source - /// by the given function. The observable will see only those observations - /// for which the predicate returns true. The predicate is executed once for - /// each subscribed observer. The returned object also propagates error - /// observations arising from the source and completes when the source completes. - /// The function to apply to observations to determine if it should - /// be kept. - /// The input Observable. - /// An Observable that filters observations based on filter. - [] - val filter: predicate:('T -> bool) -> source:IObservable<'T> -> IObservable<'T> + /// Returns an observable which filters the observations of the source + /// by the given function. The observable will see only those observations + /// for which the predicate returns true. The predicate is executed once for + /// each subscribed observer. The returned object also propagates error + /// observations arising from the source and completes when the source completes. + /// + /// The function to apply to observations to determine if it should + /// be kept. + /// The input Observable. + /// + /// An Observable that filters observations based on filter. + /// + /// + [] + val filter: predicate:('T -> bool) -> source:IObservable<'T> -> IObservable<'T> - /// Returns two observables which partition the observations of the source by - /// the given function. The first will trigger observations for those values - /// for which the predicate returns true. The second will trigger observations - /// for those values where the predicate returns false. The predicate is - /// executed once for each subscribed observer. Both also propagate all error - /// observations arising from the source and each completes when the source - /// completes. - /// The function to determine which output Observable will trigger - /// a particular observation. - /// The input Observable. - /// A tuple of Observables. The first triggers when the predicate returns true, and - /// the second triggers when the predicate returns false. - [] - val partition: predicate:('T -> bool) -> source:IObservable<'T> -> (IObservable<'T> * IObservable<'T>) + /// Returns two observables which partition the observations of the source by + /// the given function. The first will trigger observations for those values + /// for which the predicate returns true. The second will trigger observations + /// for those values where the predicate returns false. The predicate is + /// executed once for each subscribed observer. Both also propagate all error + /// observations arising from the source and each completes when the source + /// completes. + /// + /// The function to determine which output Observable will trigger + /// a particular observation. + /// The input Observable. + /// + /// A tuple of Observables. The first triggers when the predicate returns true, and + /// the second triggers when the predicate returns false. + /// + /// + [] + val partition: predicate:('T -> bool) -> source:IObservable<'T> -> (IObservable<'T> * IObservable<'T>) - /// Returns two observables which split the observations of the source by the - /// given function. The first will trigger observations x for which the - /// splitter returns Choice1Of2 x. The second will trigger observations - /// y for which the splitter returns Choice2Of2 y The splitter is - /// executed once for each subscribed observer. Both also propagate error - /// observations arising from the source and each completes when the source - /// completes. - /// The function that takes an observation an transforms - /// it into one of the two output Choice types. - /// The input Observable. - /// A tuple of Observables. The first triggers when splitter returns Choice1of2 - /// and the second triggers when splitter returns Choice2of2. - [] - val split: splitter:('T -> Choice<'U1,'U2>) -> source:IObservable<'T> -> (IObservable<'U1> * IObservable<'U2>) + /// Returns two observables which split the observations of the source by the + /// given function. The first will trigger observations x for which the + /// splitter returns Choice1Of2 x. The second will trigger observations + /// y for which the splitter returns Choice2Of2 y The splitter is + /// executed once for each subscribed observer. Both also propagate error + /// observations arising from the source and each completes when the source + /// completes. + /// + /// The function that takes an observation an transforms + /// it into one of the two output Choice types. + /// The input Observable. + /// + /// A tuple of Observables. The first triggers when splitter returns Choice1of2 + /// and the second triggers when splitter returns Choice2of2. + /// + /// + [] + val split: splitter:('T -> Choice<'U1,'U2>) -> source:IObservable<'T> -> (IObservable<'U1> * IObservable<'U2>) - /// Returns an observable which chooses a projection of observations from the source - /// using the given function. The returned object will trigger observations x - /// for which the splitter returns Some x. The returned object also propagates - /// all errors arising from the source and completes when the source completes. - /// The function that returns Some for observations to be propagated - /// and None for observations to ignore. - /// The input Observable. - /// An Observable that only propagates some of the observations from the source. - [] - val choose: chooser:('T -> 'U option) -> source:IObservable<'T> -> IObservable<'U> + /// Returns an observable which chooses a projection of observations from the source + /// using the given function. The returned object will trigger observations x + /// for which the splitter returns Some x. The returned object also propagates + /// all errors arising from the source and completes when the source completes. + /// + /// The function that returns Some for observations to be propagated + /// and None for observations to ignore. + /// The input Observable. + /// + /// An Observable that only propagates some of the observations from the source. + /// + /// + [] + val choose: chooser:('T -> 'U option) -> source:IObservable<'T> -> IObservable<'U> - /// Returns an observable which, for each observer, allocates an item of state - /// and applies the given accumulating function to successive values arising from - /// the input. The returned object will trigger observations for each computed - /// state value, excluding the initial value. The returned object propagates - /// all errors arising from the source and completes when the source completes. - /// - /// For each observer, the registered intermediate observing object is not thread safe. - /// That is, observations arising from the source must not be triggered concurrently - /// on different threads. - /// The function to update the state with each observation. - /// The initial state. - /// The input Observable. - /// An Observable that triggers on the updated state values. - [] - val scan: collector:('U -> 'T -> 'U) -> state:'U -> source:IObservable<'T> -> IObservable<'U> + /// Returns an observable which, for each observer, allocates an item of state + /// and applies the given accumulating function to successive values arising from + /// the input. The returned object will trigger observations for each computed + /// state value, excluding the initial value. The returned object propagates + /// all errors arising from the source and completes when the source completes. + /// + /// For each observer, the registered intermediate observing object is not thread safe. + /// That is, observations arising from the source must not be triggered concurrently + /// on different threads. + /// The function to update the state with each observation. + /// The initial state. + /// The input Observable. + /// + /// An Observable that triggers on the updated state values. + /// + /// + [] + val scan: collector:('U -> 'T -> 'U) -> state:'U -> source:IObservable<'T> -> IObservable<'U> - /// Creates an observer which permanently subscribes to the given observable and which calls - /// the given function for each observation. - /// The function to be called on each observation. - /// The input Observable. - [] - val add : callback:('T -> unit) -> source:IObservable<'T> -> unit + /// Creates an observer which permanently subscribes to the given observable and which calls + /// the given function for each observation. + /// + /// The function to be called on each observation. + /// The input Observable. + /// + /// + [] + val add : callback:('T -> unit) -> source:IObservable<'T> -> unit - /// Creates an observer which subscribes to the given observable and which calls - /// the given function for each observation. - /// The function to be called on each observation. - /// The input Observable. - /// An object that will remove the callback if disposed. - [] - val subscribe : callback:('T -> unit) -> source:IObservable<'T> -> System.IDisposable + /// Creates an observer which subscribes to the given observable and which calls + /// the given function for each observation. + /// + /// The function to be called on each observation. + /// The input Observable. + /// + /// An object that will remove the callback if disposed. + /// + /// + [] + val subscribe : callback:('T -> unit) -> source:IObservable<'T> -> System.IDisposable - /// Returns a new observable that triggers on the second and subsequent triggerings of the input observable. - /// The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as - /// a pair. The argument passed to the N-1th triggering is held in hidden internal state until the - /// Nth triggering occurs. - /// - /// For each observer, the registered intermediate observing object is not thread safe. - /// That is, observations arising from the source must not be triggered concurrently - /// on different threads. - /// The input Observable. - /// An Observable that triggers on successive pairs of observations from the input Observable. - [] - val pairwise: source:IObservable<'T> -> IObservable<'T * 'T> + /// Returns a new observable that triggers on the second and subsequent triggerings of the input observable. + /// The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as + /// a pair. The argument passed to the N-1th triggering is held in hidden internal state until the + /// Nth triggering occurs. + /// + /// For each observer, the registered intermediate observing object is not thread safe. + /// That is, observations arising from the source must not be triggered concurrently + /// on different threads. + /// The input Observable. + /// + /// An Observable that triggers on successive pairs of observations from the input Observable. + /// + /// + [] + val pairwise: source:IObservable<'T> -> IObservable<'T * 'T> diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi index 739484ae8cf..aa85e6414c6 100644 --- a/src/fsharp/FSharp.Core/option.fsi +++ b/src/fsharp/FSharp.Core/option.fsi @@ -8,381 +8,745 @@ open Microsoft.FSharp.Collections [] -/// Basic operations on options. +/// Contains operations for working with options. +/// +/// Options module Option = /// Returns true if the option is not None. /// The input option. + /// /// True if the option is not None. + /// + /// + /// + /// None |> Option.isSome // evaluates to false + /// Some 42 |> Option.isSome // evaluates to true + /// + /// [] val inline isSome: option:'T option -> bool /// Returns true if the option is None. + /// /// The input option. + /// /// True if the option is None. + /// + /// + /// + /// None |> Option.isNone // evaluates to true + /// Some 42 |> Option.isNone // evaluates to false + /// + /// [] val inline isNone: option:'T option -> bool /// Gets the value of the option if the option is Some, otherwise returns the specified default value. + /// /// The specified default value. /// The input option. + /// /// The option if the option is Some, else the default value. + /// /// Identical to the built-in operator, except with the arguments swapped. + /// + /// + /// + /// (99, None) ||> Option.defaultValue // evaluates to 99 + /// (99, Some 42) ||> Option.defaultValue // evaluates to 42 + /// + /// [] val defaultValue: value:'T -> option:'T option -> 'T /// Gets the value of the option if the option is Some, otherwise evaluates and returns the result. + /// /// A thunk that provides a default value when evaluated. /// The input option. + /// /// The option if the option is Some, else the result of evaluating . /// is not evaluated unless is None. + /// + /// + /// + /// None |> Option.defaultWith (fun () -> 99) // evaluates to 99 + /// Some 42 |> Option.defaultWith (fun () -> 99) // evaluates to 42 + /// + /// [] val defaultWith: defThunk:(unit -> 'T) -> option:'T option -> 'T /// Returns if it is Some, otherwise returns . + /// /// The value to use if is None. /// The input option. + /// /// The option if the option is Some, else the alternate option. + /// + /// + /// + /// (None, None) ||> Option.orElse // evaluates to None + /// (Some 99, None) ||> Option.orElse // evaluates to Some 99 + /// (None, Some 42) ||> Option.orElse // evaluates to Some 42 + /// (Some 99, Some 42) ||> Option.orElse // evaluates to Some 42 + /// + /// [] val orElse: ifNone:'T option -> option:'T option -> 'T option /// Returns if it is Some, otherwise evaluates and returns the result. + /// /// A thunk that provides an alternate option when evaluated. /// The input option. + /// /// The option if the option is Some, else the result of evaluating . /// is not evaluated unless is None. + /// + /// + /// + /// None |> Option.orElseWith (fun () -> None) // evaluates to None + /// None |> Option.orElseWith (fun () -> (Some 99)) // evaluates to Some 99 + /// Some 42 |> Option.orElseWith (fun () -> None) // evaluates to Some 42 + /// Some 42 |> Option.orElseWith (fun () -> (Some 99)) // evaluates to Some 42 + /// + /// [] val orElseWith: ifNoneThunk:(unit -> 'T option) -> option:'T option -> 'T option /// Gets the value associated with the option. + /// /// The input option. + /// /// The value within the option. + /// /// Thrown when the option is None. + /// + /// + /// + /// Some 42 |> Option.get // evaluates to 42 + /// None |> Option.get // throws exception! + /// + /// [] val get: option:'T option -> 'T /// count inp evaluates to match inp with None -> 0 | Some _ -> 1. + /// /// The input option. + /// /// A zero if the option is None, a one otherwise. + /// + /// + /// + /// None |> Option.count // evaluates to 0 + /// Some 99 |> Option.count // evaluates to 1 + /// + /// [] val count: option:'T option -> int /// fold f s inp evaluates to match inp with None -> s | Some x -> f s x. + /// /// A function to update the state data when given a value from an option. /// The initial state. /// The input option. + /// /// The original state if the option is None, otherwise it returns the updated state with the folder /// and the option value. + /// + /// + /// + /// (0, None) ||> Option.fold (fun accum x -> accum + x * 2) // evaluates to 0 + /// (0, Some 1) ||> Option.fold (fun accum x -> accum + x * 2) // evaluates to 2 + /// (10, Some 1) ||> Option.fold (fun accum x -> accum + x * 2) // evaluates to 12 + /// + /// [] val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> option:'T option -> 'State /// fold f inp s evaluates to match inp with None -> s | Some x -> f x s. + /// /// A function to update the state data when given a value from an option. /// The input option. /// The initial state. + /// /// The original state if the option is None, otherwise it returns the updated state with the folder /// and the option value. + /// + /// + /// + /// (None, 0) ||> Option.foldBack (fun x accum -> accum + x * 2) // evaluates to 0 + /// (Some 1, 0) ||> Option.foldBack (fun x accum -> accum + x * 2) // evaluates to 2 + /// (Some 1, 10) ||> Option.foldBack (fun x accum -> accum + x * 2) // evaluates to 12 + /// + /// [] val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> option:'T option -> state:'State -> 'State /// exists p inp evaluates to match inp with None -> false | Some x -> p x. + /// /// A function that evaluates to a boolean when given a value from the option type. /// The input option. + /// /// False if the option is None, otherwise it returns the result of applying the predicate /// to the option value. + /// + /// + /// + /// None |> Option.exists (fun x -> x >= 5) // evaluates to false + /// Some 42 |> Option.exists (fun x -> x >= 5) // evaluates to true + /// Some 4 |> Option.exists (fun x -> x >= 5) // evaluates to false + /// + /// [] val exists: predicate:('T -> bool) -> option:'T option -> bool /// forall p inp evaluates to match inp with None -> true | Some x -> p x. + /// /// A function that evaluates to a boolean when given a value from the option type. /// The input option. + /// /// True if the option is None, otherwise it returns the result of applying the predicate /// to the option value. + /// + /// + /// + /// None |> Option.forall (fun x -> x >= 5) // evaluates to true + /// Some 42 |> Option.forall (fun x -> x >= 5) // evaluates to true + /// Some 4 |> Option.forall (fun x -> x >= 5) // evaluates to false + /// + /// [] val forall: predicate:('T -> bool) -> option:'T option -> bool /// Evaluates to true if is Some and its value is equal to . + /// /// The value to test for equality. /// The input option. + /// /// True if the option is Some and contains a value equal to , otherwise false. + /// + /// + /// + /// (99, None) ||> Option.contains // evaluates to false + /// (99, Some 99) ||> Option.contains // evaluates to true + /// (99, Some 100) ||> Option.contains // evaluates to false + /// + /// [] val inline contains: value:'T -> option:'T option -> bool when 'T : equality /// iter f inp executes match inp with None -> () | Some x -> f x. + /// /// A function to apply to the option value. /// The input option. + /// /// Unit if the option is None, otherwise it returns the result of applying the predicate + /// + /// + /// + /// None |> Option.iter (printfn "%s") // does nothing + /// Some "Hello world" |> Option.iter (printfn "%s") // prints "Hello world" + /// + /// /// to the option value. [] val iter: action:('T -> unit) -> option:'T option -> unit /// map f inp evaluates to match inp with None -> None | Some x -> Some (f x). + /// /// A function to apply to the option value. /// The input option. + /// /// An option of the input value after applying the mapping function, or None if the input is None. + /// + /// + /// + /// None |> Option.map (fun x -> x * 2) // evaluates to None + /// Some 42 |> Option.map (fun x -> x * 2) // evaluates to Some 84 + /// + /// [] val map: mapping:('T -> 'U) -> option:'T option -> 'U option /// map f option1 option2 evaluates to match option1, option2 with Some x, Some y -> Some (f x y) | _ -> None. + /// /// A function to apply to the option values. /// The first option. /// The second option. + /// /// An option of the input values after applying the mapping function, or None if either input is None. + /// + /// + /// + /// (None, None) ||> Option.map2 (fun x y -> x + y) // evaluates to None + /// (Some 5, None) ||> Option.map2 (fun x y -> x + y) // evaluates to None + /// (None, Some 10) ||> Option.map2 (fun x y -> x + y) // evaluates to None + /// (Some 5, Some 10) ||> Option.map2 (fun x y -> x + y) // evaluates to Some 15 + /// + /// [] - val map2: mapping:('T1 -> 'T2 -> 'U) -> 'T1 option -> 'T2 option -> 'U option + val map2: mapping:('T1 -> 'T2 -> 'U) -> option1: 'T1 option -> option2: 'T2 option -> 'U option /// map f option1 option2 option3 evaluates to match option1, option2, option3 with Some x, Some y, Some z -> Some (f x y z) | _ -> None. + /// /// A function to apply to the option values. /// The first option. /// The second option. /// The third option. + /// /// An option of the input values after applying the mapping function, or None if any input is None. + /// + /// + /// + /// (None, None, None) |||> Option.map3 (fun x y z -> x + y + z) // evaluates to None + /// (Some 100, None, None) |||> Option.map3 (fun x y z -> x + y + z) // evaluates to None + /// (None, Some 100, None) |||> Option.map3 (fun x y z -> x + y + z) // evaluates to None + /// (None, None, Some 100) |||> Option.map3 (fun x y z -> x + y + z) // evaluates to None + /// (Some 5, Some 100, Some 10) |||> Option.map3 (fun x y z -> x + y + z) // evaluates to Some 115 + /// + /// [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> 'T1 option -> 'T2 option -> 'T3 option -> 'U option + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> option1: 'T1 option -> option2: 'T2 option -> option3: 'T3 option -> 'U option /// bind f inp evaluates to match inp with None -> None | Some x -> f x + /// /// A function that takes the value of type T from an option and transforms it into /// an option containing a value of type U. /// The input option. + /// /// An option of the output type of the binder. + /// + /// + /// + /// let tryParse input = + /// match System.Int32.TryParse input with + /// | true, v -> Some v + /// | false, _ -> None + /// None |> Option.bind tryParse // evaluates to None + /// Some "42" |> Option.bind tryParse // evaluates to Some 42 + /// Some "Forty-two" |> Option.bind tryParse // evaluates to None + /// + /// [] val bind: binder:('T -> 'U option) -> option:'T option -> 'U option /// flatten inp evaluates to match inp with None -> None | Some x -> x + /// /// The input option. - /// An option of the output type of the binder. + /// + /// The input value if the value is Some; otherwise, None. + /// /// flatten is equivalent to bind id. + /// + /// + /// + /// None |> Option.flatten // evaluates to None + /// (Some (None)) |> Option.flatten // evaluates to None + /// (Some (Some 42)) |> Option.flatten // evaluates to Some 42 + /// + /// [] val flatten: option:'T option option -> 'T option /// filter f inp evaluates to match inp with None -> None | Some x -> if f x then Some x else None. + /// /// A function that evaluates whether the value contained in the option should remain, or be filtered out. /// The input option. + /// /// The input if the predicate evaluates to true; otherwise, None. + /// + /// + /// + /// None |> Option.filter (fun x -> x >= 5) // evaluates to None + /// Some 42 |> Option.filter (fun x -> x >= 5) // evaluates to Some 42 + /// Some 4 |> Option.filter (fun x -> x >= 5) // evaluates to None + /// + /// [] val filter: predicate:('T -> bool) -> option:'T option -> 'T option /// Convert the option to an array of length 0 or 1. + /// /// The input option. + /// /// The result array. + /// + /// + /// + /// None |> Option.toArray // evaluates to [||] + /// Some 42 |> Option.toArray // evaluates to [|42|] + /// + /// [] val toArray: option:'T option -> 'T[] /// Convert the option to a list of length 0 or 1. + /// /// The input option. + /// /// The result list. + /// + /// + /// + /// None |> Option.toList // evaluates to [] + /// Some 42 |> Option.toList // evaluates to [42] + /// + /// [] val toList: option:'T option -> 'T list - /// Convert the option to a Nullable value. + /// /// The input option. + /// /// The result value. + /// + /// + /// + /// None |> Option.toNullable // evaluates to new System.Nullable<int>() + /// Some 42 |> Option.toNullable // evaluates to new System.Nullable(42) + /// + /// [] val toNullable: option:'T option -> Nullable<'T> /// Convert a Nullable value to an option. + /// /// The input nullable value. + /// /// The result option. + /// + /// + /// + /// System.Nullable<int>() |> Option.ofNullable // evaluates to None + /// System.Nullable(42) |> Option.ofNullable // evaluates to Some 42 + /// + /// [] - val ofNullable: value:Nullable<'T> -> 'T option + val ofNullable: value:Nullable<'T> -> 'T option /// Convert a potentially null value to an option. + /// /// The input value. + /// /// The result option. + /// + /// + /// + /// (null: string) |> Option.ofObj // evaluates to None + /// "not a null string" |> Option.ofObj // evaluates to (Some "not a null string") + /// + /// [] val ofObj: value: 'T -> 'T option when 'T : null /// Convert an option to a potentially null value. + /// /// The input value. + /// /// The result value, which is null if the input was None. + /// + /// + /// + /// None |> Option.toObj // evaluates to null + /// Some "not a null string" |> Option.toObj // evaluates to "not a null string" + /// + /// [] val toObj: value: 'T option -> 'T when 'T : null -/// Basic operations on value options. +/// Contains operations for working with value options. +/// +/// Options module ValueOption = /// Returns true if the value option is not ValueNone. + /// /// The input value option. + /// /// True if the value option is not ValueNone. + /// + /// [] - val inline isSome: voption:'T voption -> bool + val inline isSome: voption: 'T voption -> bool /// Returns true if the value option is ValueNone. + /// /// The input value option. + /// /// True if the voption is ValueNone. + /// + /// [] - val inline isNone: voption:'T voption -> bool + val inline isNone: voption: 'T voption -> bool /// Gets the value of the value option if the option is ValueSome, otherwise returns the specified default value. + /// /// The specified default value. /// The input voption. + /// /// The voption if the voption is ValueSome, else the default value. /// Identical to the built-in operator, except with the arguments swapped. + /// + /// [] - val defaultValue: value:'T -> voption:'T voption -> 'T + val defaultValue: value:'T -> voption: 'T voption -> 'T /// Gets the value of the voption if the voption is ValueSome, otherwise evaluates and returns the result. + /// /// A thunk that provides a default value when evaluated. /// The input voption. + /// /// The voption if the voption is ValueSome, else the result of evaluating . /// is not evaluated unless is ValueNone. + /// + /// [] - val defaultWith: defThunk:(unit -> 'T) -> voption:'T voption -> 'T + val defaultWith: defThunk:(unit -> 'T) -> voption: 'T voption -> 'T - /// Returns if it is Some, otherwise returns . - /// The value to use if is None. - /// The input option. + /// Returns if it is Some, otherwise returns . + /// + /// The value to use if is None. + /// The input option. + /// /// The option if the option is Some, else the alternate option. + /// + /// [] - val orElse: ifNone:'T voption -> voption:'T voption -> 'T voption + val orElse: ifNone:'T voption -> voption: 'T voption -> 'T voption /// Returns if it is Some, otherwise evaluates and returns the result. + /// /// A thunk that provides an alternate value option when evaluated. /// The input value option. + /// /// The voption if the voption is ValueSome, else the result of evaluating . /// is not evaluated unless is ValueNone. + /// + /// [] - val orElseWith: ifNoneThunk:(unit -> 'T voption) -> voption:'T voption -> 'T voption + val orElseWith: ifNoneThunk:(unit -> 'T voption) -> voption: 'T voption -> 'T voption /// Gets the value associated with the option. + /// /// The input value option. + /// /// The value within the option. /// Thrown when the option is ValueNone. + /// + /// [] - val get: voption:'T voption -> 'T + val get: voption: 'T voption -> 'T /// count inp evaluates to match inp with ValueNone -> 0 | ValueSome _ -> 1. + /// /// The input value option. + /// /// A zero if the option is ValueNone, a one otherwise. + /// + /// [] - val count: voption:'T voption -> int + val count: voption: 'T voption -> int /// fold f s inp evaluates to match inp with ValueNone -> s | ValueSome x -> f s x. + /// /// A function to update the state data when given a value from a value option. /// The initial state. /// The input value option. + /// /// The original state if the option is ValueNone, otherwise it returns the updated state with the folder /// and the voption value. + /// + /// [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> voption:'T voption -> 'State + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> voption: 'T voption -> 'State /// fold f inp s evaluates to match inp with ValueNone -> s | ValueSome x -> f x s. + /// /// A function to update the state data when given a value from a value option. /// The input value option. /// The initial state. + /// /// The original state if the option is ValueNone, otherwise it returns the updated state with the folder /// and the voption value. + /// + /// [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> voption:'T voption -> state:'State -> 'State + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> voption: 'T voption -> state:'State -> 'State /// exists p inp evaluates to match inp with ValueNone -> false | ValueSome x -> p x. + /// /// A function that evaluates to a boolean when given a value from the option type. /// The input value option. + /// /// False if the option is ValueNone, otherwise it returns the result of applying the predicate /// to the option value. + /// + /// [] - val exists: predicate:('T -> bool) -> voption:'T voption -> bool + val exists: predicate:('T -> bool) -> voption: 'T voption -> bool /// forall p inp evaluates to match inp with ValueNone -> true | ValueSome x -> p x. + /// /// A function that evaluates to a boolean when given a value from the value option type. /// The input value option. + /// /// True if the option is None, otherwise it returns the result of applying the predicate /// to the option value. + /// + /// [] - val forall: predicate:('T -> bool) -> voption:'T voption -> bool + val forall: predicate:('T -> bool) -> voption: 'T voption -> bool /// Evaluates to true if is ValueSome and its value is equal to . + /// /// The value to test for equality. /// The input value option. + /// /// True if the option is ValueSome and contains a value equal to , otherwise false. + /// + /// [] - val inline contains: value:'T -> voption:'T voption -> bool when 'T : equality + val inline contains: value:'T -> voption: 'T voption -> bool when 'T : equality /// iter f inp executes match inp with ValueNone -> () | ValueSome x -> f x. + /// /// A function to apply to the voption value. /// The input value option. + /// /// Unit if the option is ValueNone, otherwise it returns the result of applying the predicate /// to the voption value. + /// + /// [] - val iter: action:('T -> unit) -> voption:'T voption -> unit + val iter: action:('T -> unit) -> voption: 'T voption -> unit /// map f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> ValueSome (f x). + /// /// A function to apply to the voption value. /// The input value option. + /// /// A value option of the input value after applying the mapping function, or ValueNone if the input is ValueNone. + /// + /// [] - val map: mapping:('T -> 'U) -> voption:'T voption -> 'U voption + val map: mapping:('T -> 'U) -> voption: 'T voption -> 'U voption /// map f voption1 voption2 evaluates to match voption1, voption2 with ValueSome x, ValueSome y -> ValueSome (f x y) | _ -> ValueNone. + /// /// A function to apply to the voption values. /// The first value option. /// The second value option. + /// /// A value option of the input values after applying the mapping function, or ValueNone if either input is ValueNone. + /// + /// [] val map2: mapping:('T1 -> 'T2 -> 'U) -> voption1: 'T1 voption -> voption2: 'T2 voption -> 'U voption /// map f voption1 voption2 voption3 evaluates to match voption1, voption2, voption3 with ValueSome x, ValueSome y, ValueSome z -> ValueSome (f x y z) | _ -> ValueNone. + /// /// A function to apply to the value option values. /// The first value option. /// The second value option. /// The third value option. + /// /// A value option of the input values after applying the mapping function, or ValueNone if any input is ValueNone. + /// + /// [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> 'T1 voption -> 'T2 voption -> 'T3 voption -> 'U voption + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> voption1: 'T1 voption -> voption2: 'T2 voption -> voption3: 'T3 voption -> 'U voption /// bind f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> f x + /// /// A function that takes the value of type T from a value option and transforms it into /// a value option containing a value of type U. /// The input value option. + /// /// An option of the output type of the binder. + /// + /// [] - val bind: binder:('T -> 'U voption) -> voption:'T voption -> 'U voption + val bind: binder:('T -> 'U voption) -> voption: 'T voption -> 'U voption /// flatten inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> x + /// /// The input value option. - /// A value option of the output type of the binder. + /// + /// The input value if the value is Some; otherwise, ValueNone. /// flatten is equivalent to bind id. + /// + /// [] - val flatten: voption:'T voption voption -> 'T voption + val flatten: voption: 'T voption voption -> 'T voption /// filter f inp evaluates to match inp with ValueNone -> ValueNone | ValueSome x -> if f x then ValueSome x else ValueNone. + /// /// A function that evaluates whether the value contained in the value option should remain, or be filtered out. /// The input value option. + /// /// The input if the predicate evaluates to true; otherwise, ValueNone. + /// + /// [] - val filter: predicate:('T -> bool) -> voption:'T voption -> 'T voption + val filter: predicate:('T -> bool) -> voption: 'T voption -> 'T voption /// Convert the value option to an array of length 0 or 1. + /// /// The input value option. + /// /// The result array. + /// + /// [] - val toArray: voption:'T voption -> 'T[] + val toArray: voption: 'T voption -> 'T[] /// Convert the value option to a list of length 0 or 1. + /// /// The input value option. + /// /// The result list. + /// + /// [] - val toList: voption:'T voption -> 'T list + val toList: voption: 'T voption -> 'T list /// Convert the value option to a Nullable value. + /// /// The input value option. + /// /// The result value. + /// + /// [] - val toNullable: voption:'T voption -> Nullable<'T> + val toNullable: voption: 'T voption -> Nullable<'T> /// Convert a Nullable value to a value option. + /// /// The input nullable value. + /// /// The result value option. + /// + /// [] - val ofNullable: value:Nullable<'T> -> 'T voption + val ofNullable: value:Nullable<'T> -> 'T voption /// Convert a potentially null value to a value option. + /// /// The input value. + /// /// The result value option. + /// + /// [] val ofObj: value: 'T -> 'T voption when 'T : null /// Convert an option to a potentially null value. + /// /// The input value. + /// /// The result value, which is null if the input was ValueNone. + /// + /// [] val toObj: value: 'T voption -> 'T when 'T : null diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fs b/src/fsharp/FSharp.Core/prim-types-prelude.fs index 74c84101707..63c370ba332 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fs +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fs @@ -28,39 +28,89 @@ namespace Microsoft.FSharp.Core type bool = System.Boolean type decimal = System.Decimal type int = int32 + type uint = uint32 type ``[]``<'T> = (# "!0[]" #) + type ``[,]``<'T> = (# "!0[0 ...,0 ...]" #) + type ``[,,]``<'T> = (# "!0[0 ...,0 ...,0 ...]" #) + type ``[,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + type ``[,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) - type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + + type ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]``<'T> = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) type array<'T> = 'T[] diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fsi b/src/fsharp/FSharp.Core/prim-types-prelude.fsi index ed68965bf28..d09a9d1d461 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fsi +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fsi @@ -9,79 +9,134 @@ namespace Microsoft.FSharp.Core open System - /// An abbreviation for the CLI type System.Object. + /// An abbreviation for the CLI type . + /// + /// Basic Types type obj = System.Object - /// An abbreviation for the CLI type System.Exception. + /// An abbreviation for the CLI type . + /// + /// Basic Types type exn = System.Exception - /// An abbreviation for the CLI type System.IntPtr. + /// An abbreviation for the CLI type . + /// + /// Basic Types type nativeint = System.IntPtr - /// An abbreviation for the CLI type System.UIntPtr. + /// An abbreviation for the CLI type . + /// + /// Basic Types type unativeint = System.UIntPtr - /// An abbreviation for the CLI type System.String. + /// An abbreviation for the CLI type . + /// + /// Basic Types type string = System.String - /// An abbreviation for the CLI type System.Single. + /// An abbreviation for the CLI type . + /// + /// Basic Types type float32 = System.Single - /// An abbreviation for the CLI type System.Double. + /// An abbreviation for the CLI type . + /// + /// Basic Types type float = System.Double - /// An abbreviation for the CLI type System.Single. + /// An abbreviation for the CLI type . Identical to . + /// + /// Basic Types type single = System.Single - /// An abbreviation for the CLI type System.Double. + /// An abbreviation for the CLI type . Identical to . + /// + /// Basic Types type double = System.Double - /// An abbreviation for the CLI type System.SByte. + /// An abbreviation for the CLI type . + /// + /// Basic Types type sbyte = System.SByte - /// An abbreviation for the CLI type System.Byte. + /// An abbreviation for the CLI type . + /// + /// Basic Types type byte = System.Byte - /// An abbreviation for the CLI type System.SByte. + /// An abbreviation for the CLI type . + /// + /// Basic Types type int8 = System.SByte - /// An abbreviation for the CLI type System.Byte. + /// An abbreviation for the CLI type . + /// + /// Basic Types type uint8 = System.Byte - /// An abbreviation for the CLI type System.Int16. + /// An abbreviation for the CLI type . + /// + /// Basic Types type int16 = System.Int16 - /// An abbreviation for the CLI type System.UInt16. + /// An abbreviation for the CLI type . + /// + /// Basic Types type uint16 = System.UInt16 - /// An abbreviation for the CLI type System.Int32. + /// An abbreviation for the CLI type . + /// + /// Basic Types type int32 = System.Int32 - /// An abbreviation for the CLI type System.UInt32. + /// An abbreviation for the CLI type . + /// + /// Basic Types type uint32 = System.UInt32 - /// An abbreviation for the CLI type System.Int64. + /// An abbreviation for the CLI type . + /// + /// Basic Types type int64 = System.Int64 - /// An abbreviation for the CLI type System.UInt64. + /// An abbreviation for the CLI type . + /// + /// Basic Types type uint64 = System.UInt64 - /// An abbreviation for the CLI type System.Char. + /// An abbreviation for the CLI type . + /// + /// Basic Types type char = System.Char - /// An abbreviation for the CLI type System.Boolean. + /// An abbreviation for the CLI type . + /// + /// Basic Types type bool = System.Boolean - /// An abbreviation for the CLI type System.Decimal. + /// An abbreviation for the CLI type . + /// + /// Basic Types type decimal = System.Decimal - /// An abbreviation for the CLI type System.Int32. + /// An abbreviation for the CLI type . + /// + /// Basic Types type int = int32 + /// An abbreviation for the CLI type . + /// + /// Basic Types + type uint = uint32 + /// Single dimensional, zero-based arrays, written int[], string[] etc. + /// /// Use the values in the Array module to manipulate values /// of this type, or the notation arr.[x] to get/set array /// values. + /// + /// Basic Types + /// type 'T ``[]`` = (# "!0[]" #) /// Two dimensional arrays, typically zero-based. @@ -91,6 +146,9 @@ namespace Microsoft.FSharp.Core /// values. /// /// Non-zero-based arrays can also be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,]`` = (# "!0[0 ... , 0 ... ]" #) /// Three dimensional arrays, typically zero-based. Non-zero-based arrays @@ -99,6 +157,9 @@ namespace Microsoft.FSharp.Core /// Use the values in the Array3D module /// to manipulate values of this type, or the notation arr.[x1,x2,x3] to get and set array /// values. + /// + /// Basic Types + /// type 'T ``[,,]`` = (# "!0[0 ...,0 ...,0 ...]" #) /// Four dimensional arrays, typically zero-based. Non-zero-based arrays @@ -107,145 +168,276 @@ namespace Microsoft.FSharp.Core /// Use the values in the Array4D module /// to manipulate values of this type, or the notation arr.[x1,x2,x3,x4] to get and set array /// values. + /// + /// Basic Types + /// type 'T ``[,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...]" #) /// Five dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Six dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Seven dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Eight dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Nine dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. + /// + /// Basic Types + /// type 'T ``[,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Ten dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Eleven dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twelve dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Thirteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Fourteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Fifteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Sixteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Seventeen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Eighteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Nineteen dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-one dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-two dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-three dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-four dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-five dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-six dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-seven dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-eight dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Twenty-nine dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Thirty dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Thirty-one dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Thirty-two dimensional arrays, typically zero-based. Non-zero-based arrays /// can be created using methods on the System.Array type. - type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) + /// + /// Basic Types + /// + type 'T ``[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]`` = + (# "!0[0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...,0 ...]" #) /// Single dimensional, zero-based arrays, written int[], string[] etc. /// - /// Use the values in the Array module to manipulate values + /// Use the values in the module to manipulate values /// of this type, or the notation arr.[x] to get/set array /// values. + /// + /// Basic Types type 'T array = 'T[] /// Represents an unmanaged pointer in F# code. /// /// This type should only be used when writing F# code that interoperates - /// with native code. Use of this type in F# code may result in - /// unverifiable code being generated. Conversions to and from the - /// nativeint type may be required. Values of this type can be generated + /// with native code. Use of this type in F# code may result in + /// unverifiable code being generated. Conversions to and from the + /// type may be required. Values of this type can be generated /// by the functions in the NativeInterop.NativePtr module. + /// + /// ByRef and Pointer Types type nativeptr<'T when 'T : unmanaged> = (# "native int" #) /// Represents an untyped unmanaged pointer in F# code. /// /// This type should only be used when writing F# code that interoperates - /// with native code. Use of this type in F# code may result in - /// unverifiable code being generated. Conversions to and from the - /// nativeint type may be required. Values of this type can be generated + /// with native code. Use of this type in F# code may result in + /// unverifiable code being generated. Conversions to and from the + /// type may be required. Values of this type can be generated /// by the functions in the NativeInterop.NativePtr module. + /// + /// ByRef and Pointer Types type voidptr = (# "void*" #) - /// This type is for internal use by the F# code generator. + /// Represents an Common IL (Intermediate Language) Signature Pointer. + /// + /// This type should only be used when writing F# code that interoperates + /// with other .NET languages that use generic Common IL Signature Pointers. + /// Use of this type in F# code may result in unverifiable code being generated. + /// Because of the rules of Common IL Signature Pointers, you cannot use this type in generic type parameters, + /// resulting in compiler errors. As a result, you should convert this type to + /// for use in F#. Note that Common IL Signature Pointers exposed by other .NET languages are converted to + /// or automatically by F#, + /// and F# also shows generic-specialized typed native pointers correctly to other .NET languages as Common IL Signature Pointers. + /// However, generic typed native pointers are shown as to other .NET languages. + /// For other languages to interpret generic F# typed native pointers correctly, you should expose this type or + /// instead of . + /// Values of this type can be generated by the functions in the NativeInterop.NativePtr module. + /// + /// ByRef and Pointer Types type ilsigptr<'T> = (# "!0*" #) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 51c38a9642c..02b11b4bb42 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -108,7 +108,7 @@ namespace Microsoft.FSharp.Core inherit System.Attribute() member x.Value = value - [] + [] [] type DefaultValueAttribute(check:bool) = inherit System.Attribute() @@ -135,7 +135,9 @@ namespace Microsoft.FSharp.Core type StructuralEqualityAttribute() = inherit System.Attribute() - [] + [] [] type NoEqualityAttribute() = inherit System.Attribute() @@ -150,25 +152,32 @@ namespace Microsoft.FSharp.Core type CustomComparisonAttribute() = inherit System.Attribute() - [] + [] [] type NoComparisonAttribute() = inherit System.Attribute() - [] + [] [] type ReflectedDefinitionAttribute(includeValue: bool) = inherit System.Attribute() new() = ReflectedDefinitionAttribute(false) member x.IncludeValue = includeValue - [] + [] [] type CompiledNameAttribute(compiledName:string) = inherit System.Attribute() member x.CompiledName = compiledName - [] + [] [] type StructAttribute() = inherit System.Attribute() @@ -242,6 +251,9 @@ namespace Microsoft.FSharp.Core [] let RequiresPreview : string = "Experimental library feature, requires '--langversion:preview'" + [] + let NotSupportedYet : string = "This construct is not supported by your version of the F# compiler" + [] [] type ExperimentalAttribute(message:string) = @@ -249,6 +261,11 @@ namespace Microsoft.FSharp.Core member x.Message = message + [] + [] + type InlineIfLambdaAttribute() = + inherit System.Attribute() + [] [] type CompilationArgumentCountsAttribute(counts:int[]) = @@ -307,10 +324,15 @@ namespace Microsoft.FSharp.Core [] [] - type NoDynamicInvocationAttribute() = + type NoDynamicInvocationAttribute(isLegacy: bool) = + inherit System.Attribute() - [] + new () = NoDynamicInvocationAttribute(false) + + member x.IsLegacy = isLegacy + + [] [] type OptionalArgumentAttribute() = inherit System.Attribute() @@ -352,11 +374,42 @@ namespace Microsoft.FSharp.Core [] type sbyte<[] 'Measure> = sbyte [] type int16<[] 'Measure> = int16 [] type int64<[] 'Measure> = int64 + + [] + [] + type nativeint<[] 'Measure> = nativeint + + [] + [] + type uint<[] 'Measure> = uint + + [] + [] + type byte<[] 'Measure> = byte + + [] + [] + type uint16<[] 'Measure> = uint16 + + [] + [] + type uint64<[] 'Measure> = uint64 + + [] + [] + type unativeint<[] 'Measure> = unativeint + + [] type double<[] 'Measure> = float<'Measure> + [] type single<[] 'Measure> = float32<'Measure> + [] type int8<[] 'Measure> = sbyte<'Measure> + [] type int32<[] 'Measure> = int<'Measure> + [] type uint8<[] 'Measure> = byte<'Measure> + [] type uint32<[] 'Measure> = uint<'Measure> - /// Represents a managed pointer in F# code. + /// Represents a managed pointer in F# code. type byref<'T> = (# "!0&" #) - /// Represents a managed pointer in F# code. + /// Represents a managed pointer in F# code. type byref<'T, 'Kind> = (# "!0&" #) /// Represents the types of byrefs in F# 4.5+ @@ -383,6 +436,7 @@ namespace Microsoft.FSharp.Core module internal BasicInlinedOperations = let inline unboxPrim<'T>(x:obj) = (# "unbox.any !0" type ('T) x : 'T #) let inline box (x:'T) = (# "box !0" type ('T) x : obj #) + let inline convPrim<'T1, 'T2>(x: 'T1) : 'T2 = unboxPrim<'T2> (box x) let inline not (b:bool) = (# "ceq" b false : bool #) let inline (=) (x:int) (y:int) = (# "ceq" x y : bool #) let inline (<>) (x:int) (y:int) = not(# "ceq" x y : bool #) @@ -447,14 +501,14 @@ namespace Microsoft.FSharp.Core let inline iscastPrim<'T when 'T : not struct>(x:obj) = (# "isinst !0" type ('T) x : 'T #) + let inline mask (n:int) (m:int) = (# "and" n m : int #) open BasicInlinedOperations module TupleUtils = - // adapted from System.Tuple :: CombineHashCodes - let inline mask (n:int) (m:int) = (# "and" n m : int #) + // adapted from System.Tuple::CombineHashCodes let inline opshl (x:int) (n:int) : int = (# "shl" x (mask n 31) : int #) let inline opxor (x:int) (y:int) : int = (# "xor" x y : int32 #) let inline combineTupleHashes (h1 : int) (h2 : int) = (opxor ((opshl h1 5) + h1) h2) @@ -575,7 +629,7 @@ namespace Microsoft.FSharp.Core then TypeNullnessSemantics_NullNotLiked else TypeNullnessSemantics_NullTrueValue - [] + type TypeInfo<'T>() = // Compute an on-demand per-instantiation static field static let info = getTypeInfo typeof<'T> @@ -766,9 +820,9 @@ namespace Microsoft.FSharp.Core let inline anyToString nullStr x = match box x with + | :? IFormattable as f -> f.ToString(null, CultureInfo.InvariantCulture) | null -> nullStr - | :? System.IFormattable as f -> f.ToString(null,System.Globalization.CultureInfo.InvariantCulture) - | obj -> obj.ToString() + | _ -> x.ToString() let anyToStringShowingNull x = anyToString "null" x @@ -1036,6 +1090,7 @@ namespace Microsoft.FSharp.Core // gives reliable results on null values. System.String.CompareOrdinal((# "" x : string #),(# "" y : string #)) when 'T : decimal = System.Decimal.Compare((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = System.DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) /// Generic comparison. Implements ER mode (where "0" is returned when NaNs are compared) @@ -1114,6 +1169,7 @@ namespace Microsoft.FSharp.Core // gives reliable results on null values. System.String.CompareOrdinal((# "" x : string #),(# "" y : string #)) when 'T : decimal = System.Decimal.Compare((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = System.DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) /// Generic less-than with static optimizations for some well-known cases. let inline GenericLessThanFast (x:'T) (y:'T) = @@ -1133,6 +1189,7 @@ namespace Microsoft.FSharp.Core when 'T : float32= (# "clt" x y : bool #) when 'T : char = (# "clt" x y : bool #) when 'T : decimal = System.Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) < 0 /// Generic greater-than with static optimizations for some well-known cases. let inline GenericGreaterThanFast (x:'T) (y:'T) = @@ -1152,6 +1209,7 @@ namespace Microsoft.FSharp.Core when 'T : float32 = (# "cgt" x y : bool #) when 'T : char = (# "cgt" x y : bool #) when 'T : decimal = System.Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) > 0 /// Generic less-than-or-equal with static optimizations for some well-known cases. let inline GenericLessOrEqualFast (x:'T) (y:'T) = @@ -1171,6 +1229,7 @@ namespace Microsoft.FSharp.Core when 'T : float32 = not (# "cgt.un" x y : bool #) when 'T : char = not(# "cgt" x y : bool #) when 'T : decimal = System.Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) <= 0 /// Generic greater-than-or-equal with static optimizations for some well-known cases. let inline GenericGreaterOrEqualFast (x:'T) (y:'T) = @@ -1190,6 +1249,8 @@ namespace Microsoft.FSharp.Core when 'T : float32 = not (# "clt.un" x y : bool #) when 'T : char = not (# "clt" x y : bool #) when 'T : decimal = System.Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #)) + + when 'T : DateTime = DateTime.Compare((# "" x : DateTime #), (# "" y : DateTime #)) >= 0 //------------------------------------------------------------------------- @@ -1473,6 +1534,7 @@ namespace Microsoft.FSharp.Core when 'T : char = (# "ceq" x y : bool #) when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #)) when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Equals((# "" x : DateTime #), (# "" y : DateTime #)) /// Implements generic equality between two values, with PER semantics for NaN (so equality on two NaN values returns false) // @@ -1495,6 +1557,8 @@ namespace Microsoft.FSharp.Core when 'T : unativeint = (# "ceq" x y : bool #) when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #)) when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Equals((# "" x : DateTime #), (# "" y : DateTime #)) + /// A compiler intrinsic generated during optimization of calls to GenericEqualityIntrinsic on tuple values. // @@ -1521,6 +1585,7 @@ namespace Microsoft.FSharp.Core when 'T : unativeint = (# "ceq" x y : bool #) when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #)) when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #)) + when 'T : DateTime = DateTime.Equals((# "" x : DateTime #), (# "" y : DateTime #)) let inline GenericInequalityFast (x:'T) (y:'T) = (not(GenericEqualityFast x y) : bool) @@ -1970,6 +2035,10 @@ namespace Microsoft.FSharp.Core let inline PhysicalHash obj = HashCompare.PhysicalHashFast obj + let inline typeeq<'T, 'U> = PhysicalEquality typeof<'T> typeof<'U> + let inline type2eq<'T1, 'T2, 'U> = typeeq<'T1, 'U> && typeeq<'T2, 'U> + let inline type3eq<'T1, 'T2, 'T3, 'U> = typeeq<'T1, 'U> && typeeq<'T2, 'U> && typeeq<'T3, 'U> + let GenericComparer = HashCompare.fsComparerER :> IComparer let GenericEqualityComparer = HashCompare.fsEqualityComparerUnlimitedHashingPER :> IEqualityComparer @@ -2076,7 +2145,7 @@ namespace Microsoft.FSharp.Core let inline MakeGenericComparer<'T>() = { new System.Collections.Generic.IComparer<'T> with - member __.Compare(x,y) = GenericComparison x y } + member _.Compare(x,y) = GenericComparison x y } let CharComparer = MakeGenericComparer() let StringComparer = MakeGenericComparer() @@ -2203,7 +2272,7 @@ namespace Microsoft.FSharp.Core let inline EnumOfValue (value : 'T) : 'Enum when 'Enum : enum<'T> = unboxPrim<'Enum>(box value) // According to the somewhat subtle rules of static optimizations, - // this condition is used whenever 'Enum is resolved to a nominal type + // this condition is used whenever 'Enum is resolved to a nominal when 'Enum : 'Enum = (retype value : 'Enum) let inline EnumToValue (enum : 'Enum) : 'T when 'Enum : enum<'T> = @@ -2223,6 +2292,24 @@ namespace Microsoft.FSharp.Core let inline Int16WithMeasure (f : int16) : int16<'Measure> = retype f let inline SByteWithMeasure (f : sbyte) : sbyte<'Measure> = retype f let inline Int64WithMeasure (f : int64) : int64<'Measure> = retype f + + [] + let inline IntPtrWithMeasure (f : nativeint) : nativeint<'Measure> = retype f + + [] + let inline UInt32WithMeasure (f : uint) : uint<'Measure> = retype f + + [] + let inline UInt16WithMeasure (f : uint16) : uint16<'Measure> = retype f + + [] + let inline UInt64WithMeasure (f : uint64) : uint64<'Measure> = retype f + + [] + let inline ByteWithMeasure (f : byte) : byte<'Measure> = retype f + + [] + let inline UIntPtrWithMeasure (f : unativeint) : unativeint<'Measure> = retype f let inline formatError() = raise (new System.FormatException(SR.GetString(SR.badFormatString))) @@ -2336,7 +2423,22 @@ namespace Microsoft.FSharp.Core | 'o' -> parseOctalUInt64 (s.Substring(p)) | _ -> UInt64.Parse(s.Substring(p), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture) + let inline ParseByte (s:string) = (# "conv.ovf.u1" (ParseUInt32 s) : byte #) + + let inline ParseSByte (s:string) = (# "conv.ovf.i1" (ParseInt32 s) : sbyte #) + + let inline ParseInt16 (s:string) = (# "conv.ovf.i2" (ParseInt32 s) : int16 #) + + let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #) + + let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #) + + let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #) + let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture) + + let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture) + [] type GenericZeroDynamicImplTable<'T>() = static let result : 'T = @@ -2349,6 +2451,7 @@ namespace Microsoft.FSharp.Core elif aty.Equals(typeof) then unboxPrim<'T> (box 0n) elif aty.Equals(typeof) then unboxPrim<'T> (box 0uy) elif aty.Equals(typeof) then unboxPrim<'T> (box 0us) + elif aty.Equals(typeof) then unboxPrim<'T> (box '\000') elif aty.Equals(typeof) then unboxPrim<'T> (box 0u) elif aty.Equals(typeof) then unboxPrim<'T> (box 0UL) elif aty.Equals(typeof) then unboxPrim<'T> (box 0un) @@ -2372,7 +2475,7 @@ namespace Microsoft.FSharp.Core elif aty.Equals(typeof) then unboxPrim<'T> (box 1n) elif aty.Equals(typeof) then unboxPrim<'T> (box 1uy) elif aty.Equals(typeof) then unboxPrim<'T> (box 1us) - elif aty.Equals(typeof) then unboxPrim<'T> (box (retype 1us : char)) + elif aty.Equals(typeof) then unboxPrim<'T> (box '\001') elif aty.Equals(typeof) then unboxPrim<'T> (box 1u) elif aty.Equals(typeof) then unboxPrim<'T> (box 1UL) elif aty.Equals(typeof) then unboxPrim<'T> (box 1un) @@ -2400,6 +2503,7 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = 0un when ^T : int16 = 0s when ^T : uint16 = 0us + when ^T : char = '\000' when ^T : sbyte = 0y when ^T : byte = 0uy when ^T : decimal = 0M @@ -2420,7 +2524,7 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = 1un when ^T : int16 = 1s when ^T : uint16 = 1us - when ^T : char = (retype 1us : char) + when ^T : char = '\001' when ^T : sbyte = 1y when ^T : byte = 1uy when ^T : decimal = 1M @@ -2429,197 +2533,671 @@ namespace Microsoft.FSharp.Core // That is, not in the generic implementation of '+' when ^T : ^T = (^T : (static member One : ^T) ()) - [] - type GenericDivideByIntDynamicImplTable<'T>() = - static let result : ('T -> int -> 'T) = + type System.Type with + + member inline this.GetSingleStaticMethodByTypes(name: string, parameterTypes: Type[]) = + let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic + this.GetMethod(name, staticBindingFlags, null, parameterTypes, null ) + + let UnaryDynamicImpl nm : ('T -> 'U) = + let aty = typeof<'T> + let minfo = aty.GetSingleStaticMethodByTypes(nm, [| aty |]) + (fun x -> unboxPrim<_>(minfo.Invoke(null,[| box x|]))) + + let BinaryDynamicImpl nm : ('T -> 'U -> 'V) = + let aty = typeof<'T> + let bty = typeof<'U> + let minfo = aty.GetSingleStaticMethodByTypes(nm, [| aty; bty |]) + (fun x y -> unboxPrim<_>(minfo.Invoke(null,[| box x; box y|]))) + + // Legacy dynamic implementation of operator resolution if no built in solution is used and no witness passed + type UnaryOpDynamicImplTable<'OpInfo,'T,'U>() = + static let mutable meth : MethodInfo = null + + static member Invoke opName (x: 'T) : 'U = // The dynamic implementation let aty = typeof<'T> - if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:decimal) (n:int) -> System.Decimal.Divide(x, System.Convert.ToDecimal(n)))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (n:int) -> (# "div" x ((# "conv.r8" n : float #)) : float #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (n:int) -> (# "div" x ((# "conv.r4" n : float32 #)) : float32 #))) - else - match aty.GetMethod("DivideByInt",[| aty; typeof |]) with - | null -> raise (NotSupportedException (SR.GetString(SR.dyInvDivByIntCoerce))) - | m -> (fun x n -> unboxPrim<_> (m.Invoke(null,[| box x; box n |]))) - - static member Result : ('T -> int -> 'T) = result - - let DivideByIntDynamic<'T> x y = GenericDivideByIntDynamicImplTable<('T)>.Result x y - - let inline DivideByInt< ^T when ^T : (static member DivideByInt : ^T * int -> ^T) > (x:^T) (y:int) : ^T = - DivideByIntDynamic<'T> x y - when ^T : float = (# "div" x ((# "conv.r8" (y:int) : float #)) : float #) - when ^T : float32 = (# "div" x ((# "conv.r4" (y:int) : float32 #)) : float32 #) - when ^T : decimal = System.Decimal.Divide((retype x:decimal), System.Convert.ToDecimal(y)) - when ^T : ^T = (^T : (static member DivideByInt : ^T * int -> ^T) (x, y)) - - // Dynamic implementation of addition operator resolution - [] - type AdditionDynamicImplTable<'T,'U,'V>() = - static let impl : ('T -> 'U -> 'V) = - // The dynamic implementation - let aty = typeof<'T> - let bty = typeof<'U> - let cty = typeof<'V> - let dyn() = - let ameth = aty.GetMethod("op_Addition",[| aty; bty |]) - let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Addition",[| aty; bty |]) - match ameth,bmeth with - | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce))) - | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |]))) - | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddOverload))) - - if aty.Equals(bty) && bty.Equals(cty) then - if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.i1" (# "add" x y : int32 #) : sbyte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.i2" (# "add" x y : int32 #) : int16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "add" x y : int32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "add" x y : int64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "add" x y : nativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.u1" (# "add" x y : uint32 #) : byte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.u2" (# "add" x y : uint32 #) : uint16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "add" x y : uint32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "add" x y : uint64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "add" x y : unativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "add" x y : float #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "add" x y : float32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y))) - else dyn() - else dyn() - - static member Impl : ('T -> 'U -> 'V) = impl - - let AdditionDynamic<'T,'U,'V> x y = AdditionDynamicImplTable<'T,'U,'V>.Impl x y - - // Dynamic implementation of checked addition operator resolution - [] - type CheckedAdditionDynamicImplTable<'T,'U,'V>() = - static let impl : ('T -> 'U -> 'V) = - // The dynamic implementation - let aty = typeof<'T> - let bty = typeof<'U> - let cty = typeof<'V> - let dyn() = - let ameth = aty.GetMethod("op_Addition",[| aty; bty |]) - let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Addition",[| aty; bty |]) - match ameth,bmeth with + match meth with + | null -> + let ameth = aty.GetSingleStaticMethodByTypes(opName, [| aty |]) + match ameth with + | null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce))) + | res -> + meth <- res + | _ -> () + unboxPrim<'U> (meth.Invoke(null,[| box x |])) + + // Legacy dynamic implementation of operator resolution, if no built in solution is used and no witness passed + type BinaryOpDynamicImplTable<'OpInfo,'T1,'T2,'U>() = + static let mutable meth : MethodInfo = null + + static member Invoke opName (x: 'T1) (y: 'T2) : 'U = + match meth with + | null -> + // The dynamic implementation + let aty = typeof<'T1> + let bty = typeof<'T2> + + let ameth = aty.GetSingleStaticMethodByTypes(opName, [| aty; bty |]) + let bmeth = + if aty.Equals(bty) then null else + bty.GetSingleStaticMethodByTypes(opName, [| aty; bty |]) + match ameth, bmeth with | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce))) - | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |]))) + | m, null | null, m -> + meth <- m | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddOverload))) - - if aty.Equals(bty) && bty.Equals(cty) then - if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.ovf.i1" (# "add.ovf" x y : int32 #) : sbyte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.ovf.i2" (# "add.ovf" x y : int32 #) : int16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "add.ovf" x y : int32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "add.ovf" x y : int64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "add.ovf" x y : nativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.ovf.u1.un" (# "add.ovf.un" x y : uint32 #) : byte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : uint16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:char) (y:char) -> (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : char #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "add.ovf.un" x y : uint32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "add.ovf.un" x y : uint64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "add.ovf.un" x y : unativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "add" x y : float #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "add" x y : float32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y))) - else dyn() - else dyn() - - - static member Impl : ('T -> 'U -> 'V) = impl - - let CheckedAdditionDynamic<'T,'U,'V> x y = CheckedAdditionDynamicImplTable<'T,'U,'V>.Impl x y - - - // Dynamic implementation of addition operator resolution - [] - type MultiplyDynamicImplTable<'T,'U,'V>() = - static let impl : ('T -> 'U -> 'V) = - // The dynamic implementation - let aty = typeof<'T> - let bty = typeof<'U> - let cty = typeof<'V> - let dyn() = - let ameth = aty.GetMethod("op_Multiply",[| aty; bty |]) - let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Multiply",[| aty; bty |]) - match ameth,bmeth with - | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultCoerce))) - | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |]))) - | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultOverload))) - - if aty.Equals(bty) && bty.Equals(cty) then - if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.i1" (# "mul" x y : int32 #) : sbyte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.i2" (# "mul" x y : int32 #) : int16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "mul" x y : int32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "mul" x y : int64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "mul" x y : nativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.u1" (# "mul" x y : uint32 #) : byte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.u2" (# "mul" x y : uint32 #) : uint16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "mul" x y : uint32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "mul" x y : uint64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "mul" x y : unativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "mul" x y : float #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "mul" x y : float32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y))) - else dyn() - else dyn() - - static member Impl : ('T -> 'U -> 'V) = impl - - let MultiplyDynamic<'T,'U,'V> x y = MultiplyDynamicImplTable<'T,'U,'V>.Impl x y - - // Dynamic implementation of checked addition operator resolution - [] - type CheckedMultiplyDynamicImplTable<'T,'U,'V>() = - static let impl : ('T -> 'U -> 'V) = - // The dynamic implementation - let aty = typeof<'T> - let bty = typeof<'U> - let cty = typeof<'V> - let dyn() = - let ameth = aty.GetMethod("op_Multiply",[| aty; bty |]) - let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Multiply",[| aty; bty |]) - match ameth,bmeth with - | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultCoerce))) - | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |]))) - | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultOverload))) - - if aty.Equals(bty) && bty.Equals(cty) then - if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.ovf.i1" (# "mul.ovf" x y : int32 #) : sbyte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.ovf.i2" (# "mul.ovf" x y : int32 #) : int16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "mul.ovf" x y : int32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "mul.ovf" x y : int64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "mul.ovf" x y : nativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.ovf.u1.un" (# "mul.ovf.un" x y : uint32 #) : byte #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.ovf.u2.un" (# "mul.ovf.un" x y : uint16 #) : uint16 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "mul.ovf.un" x y : uint32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "mul.ovf.un" x y : uint64 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "mul.ovf.un" x y : unativeint #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "mul" x y : float #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "mul" x y : float32 #))) - elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y))) - else dyn() - else dyn() - - static member Impl : ('T -> 'U -> 'V) = impl - - let CheckedMultiplyDynamic<'T,'U,'V> x y = CheckedMultiplyDynamicImplTable<'T,'U,'V>.Impl x y - - -namespace System - - open System - open System.Collections - open System.Collections.Generic - open System.Diagnostics - open System.Globalization - open System.Text - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.BasicInlinedOperations - open Microsoft.FSharp.Core.LanguagePrimitives - open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions - + | _ -> () + unboxPrim<'U> (meth.Invoke(null,[| box x; box y |])) + + type OpAdditionInfo = class end + + let AdditionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "add" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "add" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "add" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "add" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "add" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "add" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "add" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "add" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "add" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "add" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.u2" (# "add" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : char #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "add" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "add" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, string> then convPrim<_,'U> (String.Concat(convPrim<_,string> x, convPrim<_,string> y)) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Addition(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Addition" x y + + type OpSubtractionInfo = class end + let SubtractionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "sub" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "sub" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "sub" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "sub" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "sub" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "sub" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "sub" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "sub" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "sub" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "sub" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "sub" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "sub" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Subtraction(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Subtraction" x y + + type OpMultiplyInfo = class end + let MultiplyDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "mul" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "mul" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "mul" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "mul" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "mul" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "mul" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "mul" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "mul" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "mul" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "mul" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "mul" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "mul" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Multiply(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Multiply" x y + + type OpDivisionInfo = class end + let DivisionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U,int32> then convPrim<_,'U> (# "div" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U,float> then convPrim<_,'U> (# "div" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U,float32> then convPrim<_,'U> (# "div" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U,int64> then convPrim<_,'U> (# "div" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U,uint64> then convPrim<_,'U> (# "div.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U,uint32> then convPrim<_,'U> (# "div.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U,nativeint> then convPrim<_,'U> (# "div" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U,unativeint> then convPrim<_,'U> (# "div.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U,int16> then convPrim<_,'U> (# "conv.i2" (# "div" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U,uint16> then convPrim<_,'U> (# "conv.u2" (# "div.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U,sbyte> then convPrim<_,'U> (# "conv.i1" (# "div" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U,byte> then convPrim<_,'U> (# "conv.u1" (# "div.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Division(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Division" x y + + type OpModulusInfo = class end + let ModulusDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "rem" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "rem" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "rem" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "rem" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "rem.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "rem.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "rem" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "rem.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "rem" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "rem.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "rem" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "rem.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Modulus(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Modulus" x y + + type OpUnaryNegationInfo = class end + let UnaryNegationDynamic<'T,'U> (value: 'T) : 'U = + if type2eq<'T, 'U, int32> then convPrim<_,'U> (# "neg" (convPrim<_,int32> value) : int32 #) + elif type2eq<'T, 'U, float> then convPrim<_,'U> (# "neg" (convPrim<_,float> value) : float #) + elif type2eq<'T, 'U, float32> then convPrim<_,'U> (# "neg" (convPrim<_,float32> value) : float32 #) + elif type2eq<'T, 'U, int64> then convPrim<_,'U> (# "neg" (convPrim<_,int64> value) : int64 #) + elif type2eq<'T, 'U, nativeint> then convPrim<_,'U> (# "neg" (convPrim<_,nativeint> value) : nativeint #) + elif type2eq<'T, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "neg" (convPrim<_,int16> value) : int32 #) : int16 #) + elif type2eq<'T, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "neg" (convPrim<_,sbyte> value) : int32 #) : sbyte #) + elif type2eq<'T, 'U, decimal> then convPrim<_,'U> (Decimal.op_UnaryNegation(convPrim<_,decimal> value)) + else UnaryOpDynamicImplTable.Invoke "op_UnaryNegation" value + + type OpCheckedAdditionInfo = class end + let CheckedAdditionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "add.ovf" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "add" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "add" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "add.ovf" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "add.ovf.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "add.ovf.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "add.ovf" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "add.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "add.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "add.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "add.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "add.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "add.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, string> then convPrim<_,'U> (String.Concat(convPrim<_,string> x, convPrim<_,string> y)) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Addition(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Addition" x y + + type OpCheckedSubtractionInfo = class end + let CheckedSubtractionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "sub.ovf" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "sub" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "sub" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "sub.ovf" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "sub.ovf.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "sub.ovf.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "sub.ovf" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "sub.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "sub.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "sub.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "sub.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Subtraction(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Subtraction" x y + + type OpCheckedMultiplyInfo = class end + let CheckedMultiplyDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "mul.ovf" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, float> then convPrim<_,'U> (# "mul" (convPrim<_,float> x) (convPrim<_,float> y) : float #) + elif type3eq<'T1, 'T2, 'U, float32> then convPrim<_,'U> (# "mul" (convPrim<_,float32> x) (convPrim<_,float32> y) : float32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "mul.ovf" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "mul.ovf.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "mul.ovf.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "mul.ovf" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "mul.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "mul.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "mul.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "mul.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "mul.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Multiply(convPrim<_,decimal> x, convPrim<_,decimal> y)) + else BinaryOpDynamicImplTable.Invoke "op_Multiply" x y + + type OpCheckedUnaryNegationInfo = class end + let CheckedUnaryNegationDynamic<'T,'U> value = + if type2eq<'T, 'U, int32> then convPrim<_,'U> (# "sub.ovf" 0 (convPrim<_,int32> value) : int32 #) + elif type2eq<'T, 'U, float> then convPrim<_,'U> (# "neg" (convPrim<_,float> value) : float #) + elif type2eq<'T, 'U, float32> then convPrim<_,'U> (# "neg" (convPrim<_,float32> value) : float32 #) + elif type2eq<'T, 'U, int64> then convPrim<_,'U> (# "sub.ovf" 0L (convPrim<_,int64> value) : int64 #) + elif type2eq<'T, 'U, nativeint> then convPrim<_,'U> (# "sub.ovf" 0n (convPrim<_,nativeint> value) : nativeint #) + elif type2eq<'T, 'U, int16> then convPrim<_,'U> (# "sub.ovf" 0s (convPrim<_,int16> value) : int16 #) + elif type2eq<'T, 'U, sbyte> then convPrim<_,'U> (# "sub.ovf" 0y (convPrim<_,sbyte> value) : sbyte #) + elif type2eq<'T, 'U, decimal> then convPrim<_,'U> (Decimal.op_UnaryNegation(convPrim<_,decimal> value)) + else UnaryOpDynamicImplTable.Invoke "op_UnaryNegation" value + + type OpLeftShiftInfo = class end + let LeftShiftDynamic<'T1, 'T2, 'U> (value: 'T1) (shift: 'T2) : 'U = + if type2eq<'T1, 'U, sbyte> && typeeq<'T2, int> then convPrim<_,'U> (# "conv.i1" (# "shl" (convPrim<_,sbyte> value) (mask (convPrim<_,int32> shift) 7) : int32 #) : sbyte #) + elif type2eq<'T1, 'U, byte> && typeeq<'T2, int> then convPrim<_,'U> (# "conv.u1" (# "shl" (convPrim<_,byte> value) (mask (convPrim<_,int32> shift) 7) : uint32 #) : byte #) + elif type2eq<'T1, 'U, int16> && typeeq<'T2, int> then convPrim<_,'U> (# "conv.i2" (# "shl" (convPrim<_,int16> value) (mask (convPrim<_,int32> shift) 15) : int32 #) : int16 #) + elif type2eq<'T1, 'U, uint16> && typeeq<'T2, int> then convPrim<_,'U> (# "conv.u2" (# "shl" (convPrim<_,uint16> value) (mask (convPrim<_,int32> shift) 15) : uint32 #) : uint16 #) + elif type2eq<'T1, 'U, int32> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,int32> value) (mask (convPrim<_,int32> shift) 31) : int32 #) + elif type2eq<'T1, 'U, uint32> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,uint32> value) (mask (convPrim<_,int32> shift) 31) : uint32 #) + elif type2eq<'T1, 'U, int64> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,int64> value) (mask (convPrim<_,int32> shift) 63) : int64 #) + elif type2eq<'T1, 'U, uint64> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,uint64> value) (mask (convPrim<_,int32> shift) 63) : uint64 #) + elif type2eq<'T1, 'U, nativeint> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,nativeint> value) (convPrim<_,int32> shift) : nativeint #) + elif type2eq<'T1, 'U, unativeint> && typeeq<'T2, int> then convPrim<_,'U> (# "shl" (convPrim<_,unativeint> value) (convPrim<_,int32> shift) : unativeint #) + else BinaryOpDynamicImplTable.Invoke "op_LeftShift" value shift + + type OpRightShiftInfo = class end + let RightShiftDynamic<'T1, 'T2, 'U> (value: 'T1) (shift: 'T2) : 'U = + if type2eq<'T1, 'U, sbyte> && typeeq<'T2, int> then convPrim<_,'U> (# "shr" (convPrim<_,sbyte> value) (mask (convPrim<_,int32> shift) 7) : sbyte #) + elif type2eq<'T1, 'U, byte> && typeeq<'T2, int> then convPrim<_,'U> (# "shr.un" (convPrim<_,byte> value) (mask (convPrim<_,int32> shift) 7) : byte #) + elif type2eq<'T1, 'U, int16> && typeeq<'T2, int> then convPrim<_,'U> (# "shr" (convPrim<_,int16> value) (mask (convPrim<_,int32> shift) 15): int16 #) + elif type2eq<'T1, 'U, uint16> && typeeq<'T2, int> then convPrim<_,'U> (# "shr.un" (convPrim<_,uint16> value) (mask (convPrim<_,int32> shift) 15) : uint16 #) + elif type2eq<'T1, 'U, int32> && typeeq<'T2, int> then convPrim<_,'U> (# "shr" (convPrim<_,int32> value) (mask (convPrim<_,int32> shift) 31) : int32 #) + elif type2eq<'T1, 'U, uint32> && typeeq<'T2, int> then convPrim<_,'U> (# "shr.un" (convPrim<_,uint32> value) (mask (convPrim<_,int32> shift) 31) : uint32 #) + elif type2eq<'T1, 'U, int64> && typeeq<'T2, int> then convPrim<_,'U> (# "shr" (convPrim<_,int64> value) (mask (convPrim<_,int32> shift) 63) : int64 #) + elif type2eq<'T1, 'U, uint64> && typeeq<'T2, int> then convPrim<_,'U> (# "shr.un" (convPrim<_,uint64> value) (mask (convPrim<_,int32> shift) 63) : uint64 #) + elif type2eq<'T1, 'U, nativeint> && typeeq<'T2, int> then convPrim<_,'U> (# "shr" (convPrim<_,nativeint> value) (convPrim<_,int32> shift) : nativeint #) + elif type2eq<'T1, 'U, unativeint> && typeeq<'T2, int> then convPrim<_,'U> (# "shr.un" (convPrim<_,unativeint> value) (convPrim<_,int32> shift) : unativeint #) + else BinaryOpDynamicImplTable.Invoke "op_RightShift" value shift + + type OpBitwiseAndInfo = class end + let BitwiseAndDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "and" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "and" (convPrim<_,byte> x) (convPrim<_,byte> y) : byte #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "and" (convPrim<_,int16> x) (convPrim<_,int16> y) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "and" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint16 #) + elif type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "and" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "and" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "and" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "and" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "and" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "and" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + else BinaryOpDynamicImplTable.Invoke "op_BitwiseAnd" x y + + type OpBitwiseOrInfo = class end + let BitwiseOrDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "or" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "or" (convPrim<_,byte> x) (convPrim<_,byte> y) : byte #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "or" (convPrim<_,int16> x) (convPrim<_,int16> y) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "or" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint16 #) + elif type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "or" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "or" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "or" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "or" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "or" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "or" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + else BinaryOpDynamicImplTable.Invoke "op_BitwiseOr" x y + + type OpExclusiveOrInfo = class end + let ExclusiveOrDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "xor" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : sbyte #) + elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "xor" (convPrim<_,byte> x) (convPrim<_,byte> y) : byte #) + elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "xor" (convPrim<_,int16> x) (convPrim<_,int16> y) : int16 #) + elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "xor" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint16 #) + elif type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "xor" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) + elif type3eq<'T1, 'T2, 'U, uint32> then convPrim<_,'U> (# "xor" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : uint32 #) + elif type3eq<'T1, 'T2, 'U, int64> then convPrim<_,'U> (# "xor" (convPrim<_,int64> x) (convPrim<_,int64> y) : int64 #) + elif type3eq<'T1, 'T2, 'U, uint64> then convPrim<_,'U> (# "xor" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : uint64 #) + elif type3eq<'T1, 'T2, 'U, nativeint> then convPrim<_,'U> (# "xor" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : nativeint #) + elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "xor" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) + else BinaryOpDynamicImplTable.Invoke "op_ExclusiveOr" x y + + type OpLogicalNotInfo = class end + let LogicalNotDynamic<'T,'U> (value: 'T) : 'U = + if type2eq<'T, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "not" (convPrim<_,sbyte> value) : int32 #) : sbyte #) + elif type2eq<'T, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "not" (convPrim<_,byte> value) : uint32 #) : byte #) + elif type2eq<'T, 'U, int16> then convPrim<_,'U> (# "conv.i2" (# "not" (convPrim<_,int16> value) : int32 #) : int16 #) + elif type2eq<'T, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "not" (convPrim<_,uint16> value) : uint32 #) : uint16 #) + elif type2eq<'T, 'U, int32> then convPrim<_,'U> (# "not" (convPrim<_,int32> value) : int32 #) + elif type2eq<'T, 'U, uint32> then convPrim<_,'U> (# "not" (convPrim<_,uint32> value) : uint32 #) + elif type2eq<'T, 'U, int64> then convPrim<_,'U> (# "not" (convPrim<_,int64> value) : int64 #) + elif type2eq<'T, 'U, uint64> then convPrim<_,'U> (# "not" (convPrim<_,uint64> value) : uint64 #) + elif type2eq<'T, 'U, nativeint> then convPrim<_,'U> (# "not" (convPrim<_,nativeint> value) : nativeint #) + elif type2eq<'T, 'U, unativeint> then convPrim<_,'U> (# "not" (convPrim<_,unativeint> value) : unativeint #) + else UnaryOpDynamicImplTable.Invoke "op_LogicalNot" value + + type OpExplicitInfo = class end + let ExplicitDynamic<'T, 'U> (value: 'T) : 'U = + if typeeq<'U, byte> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u1" (convPrim<_,sbyte> value) : byte #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u1" (convPrim<_,byte> value) : byte #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u1" (convPrim<_,int16> value) : byte #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u1" (convPrim<_,uint16> value) : byte #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u1" (convPrim<_,int32> value) : byte #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u1" (convPrim<_,uint32> value) : byte #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u1" (convPrim<_,int64> value) : byte #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u1" (convPrim<_,uint64> value) : byte #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.u1" (convPrim<_,nativeint> value) : byte #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u1" (convPrim<_,unativeint> value) : byte #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u1" (convPrim<_,float> value) : byte #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u1" (convPrim<_,float32> value) : byte #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u1" (convPrim<_,char> value) : byte #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseByte (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, sbyte> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i1" (convPrim<_,sbyte> value) : sbyte #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i1" (convPrim<_,byte> value) : sbyte #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i1" (convPrim<_,int16> value) : sbyte #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i1" (convPrim<_,uint16> value) : sbyte #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i1" (convPrim<_,int32> value) : sbyte #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i1" (convPrim<_,uint32> value) : sbyte #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i1" (convPrim<_,int64> value) : sbyte #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i1" (convPrim<_,uint64> value) : sbyte #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i1" (convPrim<_,nativeint> value) : sbyte #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.i1" (convPrim<_,unativeint> value) : sbyte #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i1" (convPrim<_,float> value) : sbyte #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i1" (convPrim<_,float32> value) : sbyte #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.i1" (convPrim<_,char> value) : sbyte #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseSByte (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint16> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,sbyte> value) : uint16 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,byte> value) : uint16 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int16> value) : uint16 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint16> value) : uint16 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int32> value) : uint16 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint32> value) : uint16 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int64> value) : uint16 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint64> value) : uint16 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,nativeint> value) : uint16 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,unativeint> value) : uint16 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float> value) : uint16 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float32> value) : uint16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u2" (convPrim<_,char> value) : uint16 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt16 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int16> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i2" (convPrim<_,sbyte> value) : int16 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i2" (convPrim<_,byte> value) : int16 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i2" (convPrim<_,int16> value) : int16 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i2" (convPrim<_,uint16> value) : int16 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i2" (convPrim<_,int32> value) : int16 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i2" (convPrim<_,uint32> value) : int16 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i2" (convPrim<_,int64> value) : int16 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i2" (convPrim<_,uint64> value) : int16 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i2" (convPrim<_,nativeint> value) : int16 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.i2" (convPrim<_,unativeint> value) : int16 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i2" (convPrim<_,float> value) : int16 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i2" (convPrim<_,float32> value) : int16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.i2" (convPrim<_,char> value) : int16 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt16 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u4" (convPrim<_,sbyte> value) : uint32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u4" (convPrim<_,byte> value) : uint32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int16> value) : uint32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint16> value) : uint32 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int32> value) : uint32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint32> value) : uint32 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int64> value) : uint32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint64> value) : uint32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.u4" (convPrim<_,nativeint> value) : uint32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u4" (convPrim<_,unativeint> value) : uint32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u4" (convPrim<_,float> value) : uint32 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u4" (convPrim<_,float32> value) : uint32 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u4" (convPrim<_,char> value) : uint32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt32 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i4" (convPrim<_,sbyte> value) : int32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i4" (convPrim<_,byte> value) : int32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int16> value) : int32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint16> value) : int32 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int32> value) : int32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint32> value) : int32 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int64> value) : int32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint64> value) : int32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i4" (convPrim<_,nativeint> value) : int32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.i4" (convPrim<_,unativeint> value) : int32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i4" (convPrim<_,float> value) : int32 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,float32> value) : int32 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.i4" (convPrim<_,char> value) : int32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt32 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint64> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i8" (convPrim<_,sbyte> value) : uint64 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u8" (convPrim<_,byte> value) : uint64 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int16> value) : uint64 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint16> value) : uint64 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int32> value) : uint64 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint32> value) : uint64 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "" (convPrim<_,int64> value) : uint64 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i8" (convPrim<_,uint64> value) : uint64 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i8" (convPrim<_,nativeint> value) : uint64 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float> value) : uint64 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float32> value) : uint64 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u8" (convPrim<_,char> value) : uint64 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt64 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int64> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i8" (convPrim<_,sbyte> value) : int64 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u8" (convPrim<_,byte> value) : int64 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int16> value) : int64 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint16> value) : int64 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int32> value) : int64 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint32> value) : int64 #) + elif typeeq<'T, int64> then convPrim<_,'U> (convPrim<_,int64> value) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "" (convPrim<_,uint64> value) : int64 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i8" (convPrim<_,nativeint> value) : int64 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u8" (convPrim<_,unativeint> value) : int64 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float> value) : int64 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float32> value) : int64 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u8" (convPrim<_,char> value) : int64 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt64 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, float32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.r4" (convPrim<_,sbyte> value) : float32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,byte> value) : float32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int16> value) : float32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint16> value) : float32 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int32> value) : float32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint32> value) : float32 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int64> value) : float32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint64> value) : float32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r4" (convPrim<_,nativeint> value) : float32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,unativeint> value) : float32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float> value) : float32 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float32> value) : float32 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,char> value) : float32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseSingle (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, float> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.r8" (convPrim<_,sbyte> value) : float #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,byte> value) : float #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int16> value) : float #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint16> value) : float #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int32> value) : float #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint32> value) : float #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int64> value) : float #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint64> value) : float #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r8" (convPrim<_,nativeint> value) : float #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,unativeint> value) : float #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float> value) : float #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float32> value) : float #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,char> value) : float #) + elif typeeq<'T, decimal> then convPrim<_,'U> (Convert.ToDouble(convPrim<_,decimal> value)) + elif typeeq<'T, string> then convPrim<_,'U> (ParseDouble (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, unativeint> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i" (convPrim<_,sbyte> value) : unativeint #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u" (convPrim<_,byte> value) : unativeint #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i" (convPrim<_,int16> value) : unativeint #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint16> value) : unativeint #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i" (convPrim<_,int32> value) : unativeint #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint32> value) : unativeint #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i" (convPrim<_,int64> value) : unativeint #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint64> value) : unativeint #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "" (convPrim<_,nativeint> value) : unativeint #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "" (convPrim<_,unativeint> value) : unativeint #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u" (convPrim<_,float> value) : unativeint #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u" (convPrim<_,float32> value) : unativeint #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : unativeint #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUIntPtr (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, nativeint> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i" (convPrim<_,sbyte> value) : nativeint #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u" (convPrim<_,byte> value) : nativeint #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i" (convPrim<_,int16> value) : nativeint #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint16> value) : nativeint #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i" (convPrim<_,int32> value) : nativeint #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint32> value) : nativeint #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i" (convPrim<_,int64> value) : nativeint #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint64> value) : nativeint #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "" (convPrim<_,nativeint> value) : nativeint #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "" (convPrim<_,unativeint> value) : nativeint #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i" (convPrim<_,float> value) : nativeint #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i" (convPrim<_,float32> value) : nativeint #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : nativeint #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseIntPtr (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, char> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,sbyte> value) : char #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,byte> value) : char #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int16> value) : char #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint16> value) : char #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int32> value) : char #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint32> value) : char #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int64> value) : char #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint64> value) : char #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,nativeint> value) : char #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,unativeint> value) : char #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float> value) : char #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float32> value) : char #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u2" (convPrim<_,char> value) : char #) + elif typeeq<'T, string> then convPrim<_,'U> (System.Char.Parse (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, decimal> then + if typeeq<'T, sbyte> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,sbyte> value)) + elif typeeq<'T, byte> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,byte> value)) + elif typeeq<'T, int16> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int16> value)) + elif typeeq<'T, uint16> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint16> value)) + elif typeeq<'T, int32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int32> value)) + elif typeeq<'T, uint32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint32> value)) + elif typeeq<'T, int64> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int64> value)) + elif typeeq<'T, uint64> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint64> value)) + elif typeeq<'T, nativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.i8" (convPrim<_,nativeint> value) : int64 #)) + elif typeeq<'T, unativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #)) + elif typeeq<'T, float> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float> value)) + elif typeeq<'T, float32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float32> value)) + elif typeeq<'T, char> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,char> value)) + elif typeeq<'T, decimal> then convPrim<'T,'U> value + elif typeeq<'T, string> then convPrim<_,'U> (Decimal.Parse(convPrim<_,string> value, NumberStyles.Float,CultureInfo.InvariantCulture)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + else + UnaryOpDynamicImplTable.Invoke "op_Explicit" value + + type OpLessThanInfo = class end + let LessThanDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,float> x) (convPrim<_,float> y) : bool #) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (# "clt.un" (convPrim<_,char> x) (convPrim<_,char> y) : bool #) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_LessThan (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (# "clt" (String.CompareOrdinal (convPrim<_,string> x, convPrim<_,string> y)) 0 : bool #) + else BinaryOpDynamicImplTable.Invoke "op_LessThan" x y + + type OpGreaterThanInfo = class end + let GreaterThanDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,float> x) (convPrim<_,float> y) : bool #) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt.un" (convPrim<_,char> x) (convPrim<_,char> y) : bool #) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_GreaterThan (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (# "cgt" (String.CompareOrdinal (convPrim<_,string> x, convPrim<_,string> y)) 0 : bool #) + else BinaryOpDynamicImplTable.Invoke "op_GreaterThan" x y + + type OpLessThanOrEqualInfo = class end + let LessThanOrEqualDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #)) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #)) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #)) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #)) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #)) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #)) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #)) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #)) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #)) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #)) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,float> x) (convPrim<_,float> y) : bool #)) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #)) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt.un" (convPrim<_,char> x) (convPrim<_,char> y) : bool #)) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_LessThanOrEqual (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (not (# "cgt" (String.CompareOrdinal (convPrim<_,string> x, convPrim<_,string> y)) 0 : bool #)) + else BinaryOpDynamicImplTable.Invoke "op_LessThanOrEqual" x y + + type OpGreaterThanOrEqualInfo = class end + let GreaterThanOrEqualDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #)) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #)) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #)) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #)) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #)) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #)) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #)) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #)) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #)) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #)) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,float> x) (convPrim<_,float> y) : bool #)) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #)) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt.un" (convPrim<_,char> x) (convPrim<_,char> y) : bool #)) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_GreaterThanOrEqual (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (not (# "clt" (String.CompareOrdinal (convPrim<_,string> x, convPrim<_,string> y)) 0 : bool #)) + else BinaryOpDynamicImplTable.Invoke "op_GreaterThanOrEqual" x y + + type OpEqualityInfo = class end + let EqualityDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,float> x) (convPrim<_,float> y) : bool #) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (# "ceq" (convPrim<_,char> x) (convPrim<_,char> y) : bool #) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_Equality (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (String.Equals (convPrim<_,string> x, convPrim<_,string> y)) + else BinaryOpDynamicImplTable.Invoke "op_Equality" x y + + type OpInequalityInfo = class end + let InequalityDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = + if type2eq<'T1, 'T2, sbyte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : bool #)) + elif type2eq<'T1, 'T2, byte> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,byte> x) (convPrim<_,byte> y) : bool #)) + elif type2eq<'T1, 'T2, int16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,int16> x) (convPrim<_,int16> y) : bool #)) + elif type2eq<'T1, 'T2, uint16> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : bool #)) + elif type2eq<'T1, 'T2, int32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,int32> x) (convPrim<_,int32> y) : bool #)) + elif type2eq<'T1, 'T2, uint32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,uint32> x) (convPrim<_,uint32> y) : bool #)) + elif type2eq<'T1, 'T2, int64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,int64> x) (convPrim<_,int64> y) : bool #)) + elif type2eq<'T1, 'T2, uint64> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,uint64> x) (convPrim<_,uint64> y) : bool #)) + elif type2eq<'T1, 'T2, nativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,nativeint> x) (convPrim<_,nativeint> y) : bool #)) + elif type2eq<'T1, 'T2, unativeint> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : bool #)) + elif type2eq<'T1, 'T2, float> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,float> x) (convPrim<_,float> y) : bool #)) + elif type2eq<'T1, 'T2, float32> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,float32> x) (convPrim<_,float32> y) : bool #)) + elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,char> x) (convPrim<_,char> y) : bool #)) + elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_Inequality (convPrim<_,decimal> x, convPrim<_,decimal> y)) + elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (not (String.Equals (convPrim<_,string> x, convPrim<_,string> y))) + else BinaryOpDynamicImplTable.Invoke "op_Inequality" x y + + type DivideByIntInfo = class end + let DivideByIntDynamic<'T> (x: 'T) (n: int) : 'T = + if typeeq<'T, float> then convPrim<_,'T> (# "div" (convPrim<_,float> x) (# "conv.r8" n : float #) : float #) + elif typeeq<'T, float32> then convPrim<_,'T> (# "div" (convPrim<_,float32> x) (# "conv.r4" n : float32 #) : float32 #) + elif typeeq<'T, decimal> then convPrim<_,'T> (Decimal.Divide(convPrim<_,decimal> x, Convert.ToDecimal(n))) + else BinaryOpDynamicImplTable.Invoke "DivideByInt" x n + + let inline DivideByInt< ^T when ^T : (static member DivideByInt : ^T * int -> ^T) > (x: ^T) (y: int) : ^T = + DivideByIntDynamic<'T> x y + when ^T : float = (# "div" x ((# "conv.r8" y : float #)) : float #) + when ^T : float32 = (# "div" x ((# "conv.r4" y : float32 #)) : float32 #) + when ^T : decimal = Decimal.Divide((# "" x : decimal #), Convert.ToDecimal(y)) + when ^T : ^T = (^T : (static member DivideByInt : ^T * int -> ^T) (x, y)) namespace Microsoft.FSharp.Core @@ -2911,7 +3489,7 @@ namespace Microsoft.FSharp.Core //------------------------------------------------------------------------- [] - [] + [] [] [] [] @@ -2995,6 +3573,7 @@ namespace Microsoft.FSharp.Collections // Lists //------------------------------------------------------------------------- + open System open System.Collections.Generic open System.Diagnostics open Microsoft.FSharp.Core @@ -3224,6 +3803,8 @@ namespace Microsoft.FSharp.Core open System.Diagnostics open System.Collections.Generic open System.Globalization + open System.Text + open System.Numerics open Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators @@ -3269,10 +3850,6 @@ namespace Microsoft.FSharp.Core [] let (|Failure|_|) (error: exn) = if error.GetType().Equals(typeof) then Some error.Message else None - [] - let inline not (value: bool) = (# "ceq" value false : bool #) - - let inline (<) x y = GenericLessThan x y let inline (>) x y = GenericGreaterThan x y let inline (>=) x y = GenericGreaterOrEqual x y @@ -3357,9 +3934,9 @@ namespace Microsoft.FSharp.Core [] let defaultValueArg arg defaultValue = match arg with ValueNone -> defaultValue | ValueSome v -> v - [] + [] let inline (~-) (n: ^T) : ^T = - (^T : (static member (~-) : ^T -> ^T) (n)) + UnaryNegationDynamic<(^T), (^T)> n when ^T : int32 = (# "neg" n : int32 #) when ^T : float = (# "neg" n : float #) when ^T : float32 = (# "neg" n : float32 #) @@ -3368,7 +3945,10 @@ namespace Microsoft.FSharp.Core when ^T : nativeint = (# "neg" n : nativeint #) when ^T : sbyte = (# "neg" n : sbyte #) when ^T : decimal = (# "" (System.Decimal.op_UnaryNegation((# "" n : decimal #))) : ^T #) - + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + // That is, not in the generic implementation of '*' + when ^T : ^T = (^T : (static member (~-) : ^T -> ^T) (n)) let inline (+) (x: ^T) (y: ^U) : ^V = AdditionDynamic<(^T),(^U),(^V)> x y @@ -3387,15 +3967,13 @@ namespace Microsoft.FSharp.Core when ^T : byte and ^U : byte = (# "conv.u1" (# "add" x y : uint32 #) : byte #) when ^T : string and ^U : string = (# "" (System.String.Concat((# "" x : string #),(# "" y : string #))) : ^T #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Addition((# "" x : decimal #),(# "" y : decimal #))) : ^V #) - // According to the somewhat subtle rules of static optimizations, - // this condition is used whenever ^T is resolved to a nominal type - // That is, not in the generic implementation of '+' + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available when ^T : ^T = ((^T or ^U): (static member (+) : ^T * ^U -> ^V) (x,y)) - [] + [] let inline (-) (x: ^T) (y: ^U) : ^V = - ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y)) + SubtractionDynamic<(^T),(^U),(^V)> x y when ^T : int32 and ^U : int32 = (# "sub" x y : int32 #) when ^T : float and ^U : float = (# "sub" x y : float #) when ^T : float32 and ^U : float32 = (# "sub" x y : float32 #) @@ -3409,7 +3987,9 @@ namespace Microsoft.FSharp.Core when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "sub" x y : int32 #) : sbyte #) when ^T : byte and ^U : byte = (# "conv.u1" (# "sub" x y : uint32 #) : byte #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #) - + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y)) let inline ( * ) (x: ^T) (y: ^U) : ^V = MultiplyDynamic<(^T),(^U),(^V)> x y @@ -3427,13 +4007,12 @@ namespace Microsoft.FSharp.Core when ^T : byte and ^U : byte = (# "conv.u1" (# "mul" x y : uint32 #) : byte #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Multiply((# "" x : decimal #),(# "" y : decimal #))) : ^V #) // According to the somewhat subtle rules of static optimizations, - // this condition is used whenever ^T is resolved to a nominal type - // That is, not in the generic implementation of '*' + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available when ^T : ^T = ((^T or ^U): (static member (*) : ^T * ^U -> ^V) (x,y)) - [] + [] let inline ( / ) (x: ^T) (y: ^U) : ^V = - ((^T or ^U): (static member (/) : ^T * ^U -> ^V) (x,y)) + DivisionDynamic<(^T),(^U),(^V)> x y when ^T : int32 and ^U : int32 = (# "div" x y : int32 #) when ^T : float and ^U : float = (# "div" x y : float #) when ^T : float32 and ^U : float32 = (# "div" x y : float32 #) @@ -3447,10 +4026,13 @@ namespace Microsoft.FSharp.Core when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "div" x y : int32 #) : sbyte #) when ^T : byte and ^U : byte = (# "conv.u1" (# "div.un" x y : uint32 #) : byte #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Division((# "" x : decimal #),(# "" y : decimal #))) : ^V #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = ((^T or ^U): (static member (/) : ^T * ^U -> ^V) (x,y)) - [] + [] let inline ( % ) (x: ^T) (y: ^U) : ^V = - ((^T or ^U): (static member (%) : ^T * ^U -> ^V) (x,y)) + ModulusDynamic<(^T),(^U),(^V)> x y when ^T : int32 and ^U : int32 = (# "rem" x y : int32 #) when ^T : float and ^U : float = (# "rem" x y : float #) when ^T : float32 and ^U : float32 = (# "rem" x y : float32 #) @@ -3464,10 +4046,13 @@ namespace Microsoft.FSharp.Core when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "rem" x y : int32 #) : sbyte #) when ^T : byte and ^U : byte = (# "conv.u1" (# "rem.un" x y : uint32 #) : byte #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Modulus((# "" x : decimal #),(# "" y : decimal #))) : ^V #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = ((^T or ^U): (static member (%) : ^T * ^U -> ^V) (x,y)) - [] + [] let inline (~+) (value: ^T) : ^T = - (^T: (static member (~+) : ^T -> ^T) (value)) + value when ^T : int32 = value when ^T : float = value when ^T : float32 = value @@ -3481,12 +4066,11 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = value when ^T : byte = value when ^T : decimal = value + when ^T : ^T = (^T: (static member (~+) : ^T -> ^T) (value)) - let inline mask (n:int) (m:int) = (# "and" n m : int #) - - [] + [] let inline (<<<) (value: ^T) (shift:int) : ^T = - (^T: (static member (<<<) : ^T * int -> ^T) (value,shift)) + LeftShiftDynamic<(^T),int,(^T)> value shift when ^T : int32 = (# "shl" value (mask shift 31) : int #) when ^T : uint32 = (# "shl" value (mask shift 31) : uint32 #) when ^T : int64 = (# "shl" value (mask shift 63) : int64 #) @@ -3497,10 +4081,13 @@ namespace Microsoft.FSharp.Core when ^T : uint16 = (# "conv.u2" (# "shl" value (mask shift 15) : uint32 #) : uint16 #) when ^T : sbyte = (# "conv.i1" (# "shl" value (mask shift 7 ) : int32 #) : sbyte #) when ^T : byte = (# "conv.u1" (# "shl" value (mask shift 7 ) : uint32 #) : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (<<<) : ^T * int -> ^T) (value,shift)) - [] + [] let inline (>>>) (value: ^T) (shift:int) : ^T = - (^T: (static member (>>>) : ^T * int -> ^T) (value,shift)) + RightShiftDynamic<(^T),int,(^T)> value shift when ^T : int32 = (# "shr" value (mask shift 31) : int32 #) when ^T : uint32 = (# "shr.un" value (mask shift 31) : uint32 #) when ^T : int64 = (# "shr" value (mask shift 63) : int64 #) @@ -3511,10 +4098,13 @@ namespace Microsoft.FSharp.Core when ^T : uint16 = (# "conv.u2" (# "shr.un" value (mask shift 15) : uint32 #) : uint16 #) when ^T : sbyte = (# "conv.i1" (# "shr" value (mask shift 7 ) : int32 #) : sbyte #) when ^T : byte = (# "conv.u1" (# "shr.un" value (mask shift 7 ) : uint32 #) : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (>>>) : ^T * int -> ^T) (value, shift)) - [] + [] let inline (&&&) (x: ^T) (y: ^T) : ^T = - (^T: (static member (&&&) : ^T * ^T -> ^T) (x,y)) + BitwiseAndDynamic<(^T),(^T),(^T)> x y when ^T : int32 = (# "and" x y : int32 #) when ^T : int64 = (# "and" x y : int64 #) when ^T : uint64 = (# "and" x y : uint64 #) @@ -3525,10 +4115,13 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = (# "and" x y : unativeint #) when ^T : sbyte = (# "and" x y : sbyte #) when ^T : byte = (# "and" x y : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (&&&) : ^T * ^T -> ^T) (x, y)) - [] + [] let inline (|||) (x: ^T) (y: ^T) : ^T = - (^T: (static member (|||) : ^T * ^T -> ^T) (x,y)) + BitwiseOrDynamic<(^T),(^T),(^T)> x y when ^T : int32 = (# "or" x y : int32 #) when ^T : int64 = (# "or" x y : int64 #) when ^T : uint64 = (# "or" x y : uint64 #) @@ -3539,10 +4132,13 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = (# "or" x y : unativeint #) when ^T : sbyte = (# "or" x y : sbyte #) when ^T : byte = (# "or" x y : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (|||) : ^T * ^T -> ^T) (x, y)) - [] + [] let inline (^^^) (x: ^T) (y: ^T) : ^T = - (^T: (static member (^^^) : ^T * ^T -> ^T) (x,y)) + ExclusiveOrDynamic<(^T),(^T),(^T)> x y when ^T : int32 = (# "xor" x y : int32 #) when ^T : int64 = (# "xor" x y : int64 #) when ^T : uint64 = (# "xor" x y : uint64 #) @@ -3553,10 +4149,13 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = (# "xor" x y : unativeint #) when ^T : sbyte = (# "xor" x y : sbyte #) when ^T : byte = (# "xor" x y : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (^^^) : ^T * ^T -> ^T) (x, y)) - [] + [] let inline (~~~) (value: ^T) : ^T = - (^T: (static member (~~~) : ^T -> ^T) (value)) + LogicalNotDynamic<(^T),(^T)> value when ^T : int32 = (# "not" value : int32 #) when ^T : int64 = (# "not" value : int64 #) when ^T : uint64 = (# "not" value : uint64 #) @@ -3567,6 +4166,9 @@ namespace Microsoft.FSharp.Core when ^T : uint16 = (# "conv.u2" (# "not" value : uint32 #) : uint16 #) when ^T : sbyte = (# "conv.i1" (# "not" value : int32 #) : sbyte #) when ^T : byte = (# "conv.u1" (# "not" value : uint32 #) : byte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T: (static member (~~~) : ^T -> ^T) (value)) let inline castToString (x:'T) = (# "" x : string #) // internal @@ -3595,21 +4197,11 @@ namespace Microsoft.FSharp.Core [] let exit (exitcode:int) = System.Environment.Exit(exitcode); failwith "System.Environment.Exit did not exit!" - let inline parseByte (s:string) = (# "conv.ovf.u1" (ParseUInt32 s) : byte #) - let inline ParseSByte (s:string) = (# "conv.ovf.i1" (ParseInt32 s) : sbyte #) - let inline ParseInt16 (s:string) = (# "conv.ovf.i2" (ParseInt32 s) : int16 #) - let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #) - let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #) - let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #) - let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture) - let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture) - - - [] + [] [] let inline byte (value: ^T) = - (^T : (static member op_Explicit: ^T -> byte) (value)) - when ^T : string = parseByte (castToString value) + ExplicitDynamic<(^T), byte> value + when ^T : string = ParseByte (castToString value) when ^T : float = (# "conv.u1" value : byte #) when ^T : float32 = (# "conv.u1" value : byte #) when ^T : int64 = (# "conv.u1" value : byte #) @@ -3623,11 +4215,14 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u1" value : byte #) when ^T : unativeint = (# "conv.u1" value : byte #) when ^T : byte = (# "conv.u1" value : byte #) - - [] + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T : (static member op_Explicit: ^T -> byte) (value)) + + [] [] let inline sbyte (value: ^T) = - (^T : (static member op_Explicit: ^T -> sbyte) (value)) + ExplicitDynamic<(^T), sbyte> value when ^T : string = ParseSByte (castToString value) when ^T : float = (# "conv.i1" value : sbyte #) when ^T : float32 = (# "conv.i1" value : sbyte #) @@ -3642,11 +4237,14 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.i1" value : sbyte #) when ^T : unativeint = (# "conv.i1" value : sbyte #) when ^T : byte = (# "conv.i1" value : sbyte #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T : (static member op_Explicit: ^T -> sbyte) (value)) - [] + [] [] let inline uint16 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint16) (value)) + ExplicitDynamic<(^T), uint16> value when ^T : string = ParseUInt16 (castToString value) when ^T : float = (# "conv.u2" value : uint16 #) when ^T : float32 = (# "conv.u2" value : uint16 #) @@ -3661,11 +4259,14 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u2" value : uint16 #) when ^T : unativeint = (# "conv.u2" value : uint16 #) when ^T : byte = (# "conv.u2" value : uint16 #) + // According to the somewhat subtle rules of static optimizations, + // this condition is used whenever ^T is resolved to a nominal type or witnesses are available + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint16) (value)) - [] + [] [] let inline int16 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int16) (value)) + ExplicitDynamic<(^T), int16> value when ^T : string = ParseInt16 (castToString value) when ^T : float = (# "conv.i2" value : int16 #) when ^T : float32 = (# "conv.i2" value : int16 #) @@ -3680,18 +4281,17 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.i2" value : int16 #) when ^T : unativeint = (# "conv.i2" value : int16 #) when ^T : byte = (# "conv.i2" value : int16 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int16) (value)) - [] + [] [] let inline uint32 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint32) (value)) + ExplicitDynamic<(^T), uint32> value when ^T : string = ParseUInt32 (castToString value) when ^T : float = (# "conv.u4" value : uint32 #) when ^T : float32 = (# "conv.u4" value : uint32 #) - when ^T : int64 = (# "conv.u4" value : uint32 #) when ^T : nativeint = (# "conv.u4" value : uint32 #) - // For integers shorter that 32 bits, we must first // sign-widen the signed integer to 32 bits, and then // "convert" from signed int32 to unsigned int32 @@ -3699,45 +4299,47 @@ namespace Microsoft.FSharp.Core when ^T : int32 = (# "" value : uint32 #) when ^T : int16 = (# "" value : uint32 #) when ^T : sbyte = (# "" value : uint32 #) - when ^T : uint64 = (# "conv.u4" value : uint32 #) when ^T : uint32 = (# "conv.u4" value : uint32 #) when ^T : uint16 = (# "conv.u4" value : uint32 #) when ^T : char = (# "conv.u4" value : uint32 #) when ^T : unativeint = (# "conv.u4" value : uint32 #) when ^T : byte = (# "conv.u4" value : uint32 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint32) (value)) - [] + [] [] let inline int32 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int32) (value)) + ExplicitDynamic<(^T), int32> value when ^T : string = ParseInt32 (castToString value) when ^T : float = (# "conv.i4" value : int32 #) when ^T : float32 = (# "conv.i4" value : int32 #) when ^T : int64 = (# "conv.i4" value : int32 #) when ^T : nativeint = (# "conv.i4" value : int32 #) - // For integers shorter that 32 bits, we sign-widen the signed integer to 32 bits // This is a no-op on IL stack (ECMA 335 Part III 1.5 Tables 8 & 9) when ^T : int32 = (# "" value : int32 #) when ^T : int16 = (# "" value : int32 #) when ^T : sbyte = (# "" value : int32 #) - when ^T : uint64 = (# "conv.i4" value : int32 #) when ^T : uint32 = (# "" value : int32 #) // Signed<->Unsigned conversion is a no-op on IL stack when ^T : uint16 = (# "conv.i4" value : int32 #) when ^T : char = (# "conv.i4" value : int32 #) when ^T : unativeint = (# "conv.i4" value : int32 #) when ^T : byte = (# "conv.i4" value : int32 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int32) (value)) [] - let inline int value = int32 value + let inline int value = int32 value + + [] + let inline uint value = uint32 value [] let inline enum< ^T when ^T : enum > (value:int32) : ^T = EnumOfValue value [] - let ( |KeyValue| ) (keyValuePair : KeyValuePair<'T,'U>) = (keyValuePair.Key, keyValuePair.Value) + let (|KeyValue|) (keyValuePair : KeyValuePair<'T,'U>) = (keyValuePair.Key, keyValuePair.Value) [] let infinity = System.Double.PositiveInfinity @@ -3751,14 +4353,13 @@ namespace Microsoft.FSharp.Core [] let nanf = System.Single.NaN - [] + [] [] let inline uint64 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint64) (value)) + ExplicitDynamic<(^T), uint64> value when ^T : string = ParseUInt64 (castToString value) when ^T : float = (# "conv.u8" value : uint64 #) when ^T : float32 = (# "conv.u8" value : uint64 #) - // we must first sign-widen the signed integer to 64 bits, and then // "convert" from signed int64 to unsigned int64 // conv.i8 sign-widens the input, and on IL stack, @@ -3768,19 +4369,18 @@ namespace Microsoft.FSharp.Core when ^T : int16 = (# "conv.i8" value : uint64 #) when ^T : nativeint = (# "conv.i8" value : uint64 #) when ^T : sbyte = (# "conv.i8" value : uint64 #) - - when ^T : uint64 = (# "" value : uint64 #) when ^T : uint32 = (# "conv.u8" value : uint64 #) when ^T : uint16 = (# "conv.u8" value : uint64 #) when ^T : char = (# "conv.u8" value : uint64 #) when ^T : unativeint = (# "conv.u8" value : uint64 #) when ^T : byte = (# "conv.u8" value : uint64 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint64) (value)) - [] + [] [] let inline int64 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int64) (value)) + ExplicitDynamic<(^T), int64> value when ^T : string = ParseInt64 (castToString value) when ^T : float = (# "conv.i8" value : int64 #) when ^T : float32 = (# "conv.i8" value : int64 #) @@ -3789,7 +4389,6 @@ namespace Microsoft.FSharp.Core when ^T : int16 = (# "conv.i8" value : int64 #) when ^T : nativeint = (# "conv.i8" value : int64 #) when ^T : sbyte = (# "conv.i8" value : int64 #) - // When converting unsigned integer, we should zero-widen them, NOT sign-widen // No-op for uint64, conv.u8 for uint32, for smaller types conv.u8 and conv.i8 are identical. // For nativeint, conv.u8 works correctly both in 32 bit and 64 bit case. @@ -3799,11 +4398,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u8" value : int64 #) when ^T : unativeint = (# "conv.u8" value : int64 #) when ^T : byte = (# "conv.u8" value : int64 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int64) (value)) - [] + [] [] let inline float32 (value: ^T) = - (^T : (static member op_Explicit: ^T -> float32) (value)) + ExplicitDynamic<(^T), float32> value when ^T : string = ParseSingle (castToString value) when ^T : float = (# "conv.r4" value : float32 #) // NOTE: float32 should convert its argument to 32-bit float even when applied to a higher precision float stored in a register. See devdiv2#49888. @@ -3819,11 +4419,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.r.un conv.r4" value : float32 #) when ^T : unativeint = (# "conv.r.un conv.r4" value : float32 #) when ^T : byte = (# "conv.r.un conv.r4" value : float32 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> float32) (value)) - [] + [] [] let inline float (value: ^T) = - (^T : (static member op_Explicit: ^T -> float) (value)) + ExplicitDynamic<(^T), float> value when ^T : string = ParseDouble (castToString value) // NOTE: float should convert its argument to 64-bit float even when applied to a higher precision float stored in a register. See devdiv2#49888. when ^T : float = (# "conv.r8" value : float #) @@ -3839,12 +4440,13 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.r.un conv.r8" value : float #) when ^T : unativeint = (# "conv.r.un conv.r8" value : float #) when ^T : byte = (# "conv.r.un conv.r8" value : float #) - when ^T : decimal = (System.Convert.ToDouble((# "" value : decimal #))) + when ^T : decimal = (Convert.ToDouble((# "" value : decimal #))) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> float) (value)) - [] + [] [] let inline decimal (value: ^T) = - (^T : (static member op_Explicit: ^T -> decimal) (value)) + ExplicitDynamic<(^T), decimal> value when ^T : string = (System.Decimal.Parse(castToString value,NumberStyles.Float,CultureInfo.InvariantCulture)) when ^T : float = (System.Convert.ToDecimal((# "" value : float #))) when ^T : float32 = (System.Convert.ToDecimal((# "" value : float32 #))) @@ -3859,20 +4461,15 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = (System.Convert.ToDecimal(uint64 (# "" value : unativeint #))) when ^T : byte = (System.Convert.ToDecimal((# "" value : byte #))) when ^T : decimal = (# "" value : decimal #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> decimal) (value)) - // Recall type names. - // Framework names: sbyte, byte, int16, uint16, int32, uint32, int64, uint64, single, double. - // C# names: sbyte, byte, short, ushort, int, uint, long, ulong, single, double. - // F# names: sbyte, byte, int16, uint16, int, uint32, int64, uint64, float32, float. - - [] + [] [] let inline unativeint (value: ^T) = - (^T : (static member op_Explicit: ^T -> unativeint) (value)) + ExplicitDynamic<(^T), unativeint> value when ^T : string = ParseUIntPtr (castToString value) when ^T : float = (# "conv.u" value : unativeint #) when ^T : float32 = (# "conv.u" value : unativeint #) - // Narrower signed types we sign-extend. // Same length signed types we leave as such (so -1 gets reinterpreted as unsigned MaxValue). // Wider signed types we truncate. @@ -3882,28 +4479,26 @@ namespace Microsoft.FSharp.Core when ^T : int16 = (# "conv.i" value : unativeint #) when ^T : nativeint = (# "" value : unativeint #) when ^T : sbyte = (# "conv.i" value : unativeint #) - when ^T : uint64 = (# "conv.u" value : unativeint #) when ^T : uint32 = (# "conv.u" value : unativeint #) when ^T : uint16 = (# "conv.u" value : unativeint #) when ^T : char = (# "conv.u" value : unativeint #) when ^T : unativeint = (# "" value : unativeint #) when ^T : byte = (# "conv.u" value : unativeint #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) - [] + [] [] let inline nativeint (value: ^T) = - (^T : (static member op_Explicit: ^T -> nativeint) (value)) + ExplicitDynamic<(^T), nativeint> value when ^T : string = ParseIntPtr (castToString value) when ^T : float = (# "conv.i" value : nativeint #) when ^T : float32 = (# "conv.i" value : nativeint #) - when ^T : int64 = (# "conv.i" value : nativeint #) when ^T : int32 = (# "conv.i" value : nativeint #) when ^T : int16 = (# "conv.i" value : nativeint #) when ^T : nativeint = (# "conv.i" value : nativeint #) when ^T : sbyte = (# "conv.i" value : nativeint #) - // Narrower unsigned types we zero-extend. // Same length unsigned types we leave as such (so unsigned MaxValue (all-bits-set) gets reinterpreted as -1). // Wider unsigned types we truncate. @@ -3914,30 +4509,69 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : nativeint #) when ^T : unativeint = (# "" value : nativeint #) when ^T : byte = (# "conv.i" value : nativeint #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) [] - let inline string (value: ^T) = + let inline string (value: 'T) = anyToString "" value - // since we have static optimization conditionals for ints below, we need to special-case Enums. - // This way we'll print their symbolic value, as opposed to their integral one (Eg., "A", rather than "1") - when ^T struct = anyToString "" value - when ^T : float = (# "" value : float #).ToString("g",CultureInfo.InvariantCulture) - when ^T : float32 = (# "" value : float32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int64 = (# "" value : int64 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int32 = (# "" value : int32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int16 = (# "" value : int16 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : nativeint = (# "" value : nativeint #).ToString() - when ^T : sbyte = (# "" value : sbyte #).ToString("g",CultureInfo.InvariantCulture) - when ^T : uint64 = (# "" value : uint64 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : uint32 = (# "" value : uint32 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : int16 = (# "" value : int16 #).ToString("g",CultureInfo.InvariantCulture) - when ^T : unativeint = (# "" value : unativeint #).ToString() - when ^T : byte = (# "" value : byte #).ToString("g",CultureInfo.InvariantCulture) - [] + when 'T : string = + if value = unsafeDefault<'T> then "" + else (# "" value : string #) // force no-op + + // Using 'let x = (# ... #) in x.ToString()' leads to better IL, without it, an extra stloc and ldloca.s (get address-of) + // gets emitted, which are unnecessary. With it, the extra address-of-variable is not created + when 'T : float = let x = (# "" value : float #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : float32 = let x = (# "" value : float32 #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : decimal = let x = (# "" value : decimal #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : BigInteger = let x = (# "" value : BigInteger #) in x.ToString(null, CultureInfo.InvariantCulture) + + // no IFormattable + when 'T : char = let x = (# "" value : 'T #) in x.ToString() // use 'T, because char can be an enum + when 'T : bool = let x = (# "" value : bool #) in x.ToString() + when 'T : nativeint = let x = (# "" value : nativeint #) in x.ToString() + when 'T : unativeint = let x = (# "" value : unativeint #) in x.ToString() + + // Integral types can be enum: + // It is not possible to distinguish statically between Enum and (any type of) int. For signed types we have + // to use IFormattable::ToString, as the minus sign can be overridden. Using boxing we'll print their symbolic + // value if it's an enum, e.g.: 'ConsoleKey.Backspace' gives "Backspace", rather than "8") + when 'T : sbyte = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int16 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int32 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + when 'T : int64 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture) + + // unsigned integral types have equal behavior with 'T::ToString() vs IFormattable::ToString + // this allows us to issue the 'constrained' opcode with 'callvirt' + when 'T : byte = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint16 = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint32 = let x = (# "" value : 'T #) in x.ToString() + when 'T : uint64 = let x = (# "" value : 'T #) in x.ToString() + + + // other common mscorlib System struct types + when 'T : DateTime = let x = (# "" value : DateTime #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : DateTimeOffset = let x = (# "" value : DateTimeOffset #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : TimeSpan = let x = (# "" value : TimeSpan #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T : Guid = let x = (# "" value : Guid #) in x.ToString(null, CultureInfo.InvariantCulture) + when 'T struct = + match box value with + | :? IFormattable as f -> f.ToString(null, CultureInfo.InvariantCulture) + | _ -> value.ToString() + + // other commmon mscorlib reference types + when 'T : StringBuilder = + if value = unsafeDefault<'T> then "" + else let x = (# "" value : StringBuilder #) in x.ToString() + + when 'T : IFormattable = + if value = unsafeDefault<'T> then "" + else let x = (# "" value : IFormattable #) in x.ToString(null, CultureInfo.InvariantCulture) + + [] [] let inline char (value: ^T) = - (^T : (static member op_Explicit: ^T -> char) (value)) + ExplicitDynamic<(^T), char> value when ^T : string = (System.Char.Parse(castToString value)) when ^T : float = (# "conv.u2" value : char #) when ^T : float32 = (# "conv.u2" value : char #) @@ -3952,12 +4586,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u2" value : char #) when ^T : unativeint = (# "conv.u2" value : char #) when ^T : byte = (# "conv.u2" value : char #) - + when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value)) module NonStructuralComparison = /// Static less-than with static optimizations for some well-known cases. let inline (<) (x:^T) (y:^U) = - ((^T or ^U): (static member (<) : ^T * ^U -> bool) (x,y)) + LessThanDynamic<(^T), (^U), bool> x y when ^T : bool = (# "clt" x y : bool #) when ^T : sbyte = (# "clt" x y : bool #) when ^T : int16 = (# "clt" x y : bool #) @@ -3974,10 +4608,11 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "clt" x y : bool #) when ^T : decimal = System.Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #)) when ^T : string = (# "clt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #) + when ^T : ^T = ((^T or ^U): (static member (<) : ^T * ^U -> bool) (x,y)) /// Static greater-than with static optimizations for some well-known cases. let inline (>) (x:^T) (y:^U) = - ((^T or ^U): (static member (>) : ^T * ^U -> bool) (x,y)) + GreaterThanDynamic<(^T), (^U), bool> x y when 'T : bool = (# "cgt" x y : bool #) when 'T : sbyte = (# "cgt" x y : bool #) when 'T : int16 = (# "cgt" x y : bool #) @@ -3994,10 +4629,11 @@ namespace Microsoft.FSharp.Core when 'T : char = (# "cgt" x y : bool #) when 'T : decimal = System.Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #)) when ^T : string = (# "cgt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #) + when ^T : ^T = ((^T or ^U): (static member (>) : ^T * ^U -> bool) (x,y)) /// Static less-than-or-equal with static optimizations for some well-known cases. let inline (<=) (x:^T) (y:^U) = - ((^T or ^U): (static member (<=) : ^T * ^U -> bool) (x,y)) + LessThanOrEqualDynamic<(^T), (^U), bool> x y when 'T : bool = not (# "cgt" x y : bool #) when 'T : sbyte = not (# "cgt" x y : bool #) when 'T : int16 = not (# "cgt" x y : bool #) @@ -4014,10 +4650,11 @@ namespace Microsoft.FSharp.Core when 'T : char = not (# "cgt" x y : bool #) when 'T : decimal = System.Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #)) when ^T : string = not (# "cgt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #) + when ^T : ^T = ((^T or ^U): (static member (<=) : ^T * ^U -> bool) (x,y)) /// Static greater-than-or-equal with static optimizations for some well-known cases. let inline (>=) (x:^T) (y:^U) = - ((^T or ^U): (static member (>=) : ^T * ^U -> bool) (x,y)) + GreaterThanOrEqualDynamic<(^T), (^U), bool> x y when 'T : bool = not (# "clt" x y : bool #) when 'T : sbyte = not (# "clt" x y : bool #) when 'T : int16 = not (# "clt" x y : bool #) @@ -4034,11 +4671,11 @@ namespace Microsoft.FSharp.Core when 'T : char = not (# "clt" x y : bool #) when 'T : decimal = System.Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #)) when ^T : string = not (# "clt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #) - + when ^T : ^T = ((^T or ^U): (static member (>=) : ^T * ^U -> bool) (x,y)) /// Static greater-than-or-equal with static optimizations for some well-known cases. let inline (=) (x:^T) (y:^T) = - (^T : (static member (=) : ^T * ^T -> bool) (x,y)) + EqualityDynamic<(^T), (^T), bool> x y when ^T : bool = (# "ceq" x y : bool #) when ^T : sbyte = (# "ceq" x y : bool #) when ^T : int16 = (# "ceq" x y : bool #) @@ -4053,11 +4690,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "ceq" x y : bool #) when ^T : nativeint = (# "ceq" x y : bool #) when ^T : unativeint = (# "ceq" x y : bool #) - when ^T : string = System.String.Equals((# "" x : string #),(# "" y : string #)) - when ^T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #)) + when ^T : string = String.Equals((# "" x : string #),(# "" y : string #)) + when ^T : decimal = Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #)) + when ^T : ^T = (^T : (static member (=) : ^T * ^T -> bool) (x,y)) let inline (<>) (x:^T) (y:^T) = - (^T : (static member (<>) : ^T * ^T -> bool) (x,y)) + InequalityDynamic<(^T), (^T), bool> x y when ^T : bool = not (# "ceq" x y : bool #) when ^T : sbyte = not (# "ceq" x y : bool #) when ^T : int16 = not (# "ceq" x y : bool #) @@ -4074,7 +4712,7 @@ namespace Microsoft.FSharp.Core when ^T : unativeint = not (# "ceq" x y : bool #) when ^T : string = not (System.String.Equals((# "" x : string #),(# "" y : string #))) when ^T : decimal = System.Decimal.op_Inequality((# "" x:decimal #), (# "" y:decimal #)) - + when ^T : ^T = (^T : (static member (<>) : ^T * ^T -> bool) (x,y)) // static comparison (ER mode) with static optimizations for some well-known cases [] @@ -4177,7 +4815,7 @@ namespace Microsoft.FSharp.Core [] let inline typeof<'T> = BasicInlinedOperations.typeof<'T> - [] + [] let inline nameof (_: 'T) : string = raise (Exception "may not call directly, should always be optimized away") [] @@ -4198,6 +4836,9 @@ namespace Microsoft.FSharp.Core [] let id x = x + [] + let inline not (value: bool) = match value with true -> false | _ -> true + // std* are TypeFunctions with the effect of reading the property on instantiation. // So, direct uses of stdout should capture the current System.Console.Out at that point. [] @@ -4250,9 +4891,8 @@ namespace Microsoft.FSharp.Core // That is, not in the generic implementation of '+' when ^T : ^T = ((^T or ^U): (static member (+) : ^T * ^U -> ^V) (x,y)) - [] let inline (-) (x: ^T) (y: ^U) : ^V = - ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y)) + CheckedSubtractionDynamic<(^T),(^U),(^V)> x y when ^T : int32 and ^U : int32 = (# "sub.ovf" x y : int32 #) when ^T : float and ^U : float = (# "sub" x y : float #) when ^T : float32 and ^U : float32 = (# "sub" x y : float32 #) @@ -4266,10 +4906,11 @@ namespace Microsoft.FSharp.Core when ^T : sbyte and ^U : sbyte = (# "conv.ovf.i1" (# "sub.ovf" x y : int32 #) : sbyte #) when ^T : byte and ^U : byte = (# "conv.ovf.u1.un" (# "sub.ovf.un" x y : uint32 #) : byte #) when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #) + when ^T : ^T = ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y)) - [] + [] let inline (~-) (value: ^T) : ^T = - (^T : (static member (~-) : ^T -> ^T) (value)) + CheckedUnaryNegationDynamic<(^T),(^T)> value when ^T : int32 = (# "sub.ovf" 0 value : int32 #) when ^T : float = (# "neg" value : float #) when ^T : float32 = (# "neg" value : float32 #) @@ -4278,6 +4919,7 @@ namespace Microsoft.FSharp.Core when ^T : nativeint = (# "sub.ovf" 0n value : nativeint #) when ^T : sbyte = (# "sub.ovf" 0y value : sbyte #) when ^T : decimal = (# "" (System.Decimal.op_UnaryNegation((# "" value : decimal #))) : ^T #) + when ^T : ^T = (^T : (static member (~-) : ^T -> ^T) (value)) let inline ( * ) (x: ^T) (y: ^U) : ^V = CheckedMultiplyDynamic<(^T),(^U),(^V)> x y @@ -4299,11 +4941,11 @@ namespace Microsoft.FSharp.Core // That is, not in the generic implementation of '*' when ^T : ^T = ((^T or ^U): (static member (*) : ^T * ^U -> ^V) (x,y)) - [] + [] [] let inline byte (value: ^T) = - (^T : (static member op_Explicit: ^T -> byte) (value)) - when ^T : string = parseByte (castToString value) + ExplicitDynamic<(^T),byte> value + when ^T : string = ParseByte (castToString value) when ^T : float = (# "conv.ovf.u1" value : byte #) when ^T : float32 = (# "conv.ovf.u1" value : byte #) when ^T : int64 = (# "conv.ovf.u1" value : byte #) @@ -4317,11 +4959,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u1.un" value : byte #) when ^T : unativeint = (# "conv.ovf.u1.un" value : byte #) when ^T : byte = (# "conv.ovf.u1.un" value : byte #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> byte) (value)) - [] + [] [] let inline sbyte (value: ^T) = - (^T : (static member op_Explicit: ^T -> sbyte) (value)) + ExplicitDynamic<(^T),sbyte> value when ^T : string = ParseSByte (castToString value) when ^T : float = (# "conv.ovf.i1" value : sbyte #) when ^T : float32 = (# "conv.ovf.i1" value : sbyte #) @@ -4336,11 +4979,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.i1.un" value : sbyte #) when ^T : unativeint = (# "conv.ovf.i1.un" value : sbyte #) when ^T : byte = (# "conv.ovf.i1.un" value : sbyte #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> sbyte) (value)) - [] + [] [] let inline uint16 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint16) (value)) + ExplicitDynamic<(^T),uint16> value when ^T : string = ParseUInt16 (castToString value) when ^T : float = (# "conv.ovf.u2" value : uint16 #) when ^T : float32 = (# "conv.ovf.u2" value : uint16 #) @@ -4355,11 +4999,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u2.un" value : uint16 #) when ^T : unativeint = (# "conv.ovf.u2.un" value : uint16 #) when ^T : byte = (# "conv.ovf.u2.un" value : uint16 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint16) (value)) - [] + [] [] let inline char (value: ^T) = - (^T : (static member op_Explicit: ^T -> char) (value)) + ExplicitDynamic<(^T), char> value when ^T : string = (System.Char.Parse(castToString value)) when ^T : float = (# "conv.ovf.u2" value : char #) when ^T : float32 = (# "conv.ovf.u2" value : char #) @@ -4374,11 +5019,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u2.un" value : char #) when ^T : unativeint = (# "conv.ovf.u2.un" value : char #) when ^T : byte = (# "conv.ovf.u2.un" value : char #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value)) - [] + [] [] let inline int16 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int16) (value)) + ExplicitDynamic<(^T), int16> value when ^T : string = ParseInt16 (castToString value) when ^T : float = (# "conv.ovf.i2" value : int16 #) when ^T : float32 = (# "conv.ovf.i2" value : int16 #) @@ -4393,11 +5039,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.i2.un" value : int16 #) when ^T : unativeint = (# "conv.ovf.i2.un" value : int16 #) when ^T : byte = (# "conv.ovf.i2.un" value : int16 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int16) (value)) - [] + [] [] let inline uint32 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint32) (value)) + ExplicitDynamic<(^T), uint32> value when ^T : string = ParseUInt32 (castToString value) when ^T : float = (# "conv.ovf.u4" value : uint32 #) when ^T : float32 = (# "conv.ovf.u4" value : uint32 #) @@ -4412,11 +5059,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u4.un" value : uint32 #) when ^T : unativeint = (# "conv.ovf.u4.un" value : uint32 #) when ^T : byte = (# "conv.ovf.u4.un" value : uint32 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint32) (value)) - [] + [] [] let inline int32 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int32) (value)) + ExplicitDynamic<(^T), int32> value when ^T : string = ParseInt32 (castToString value) when ^T : float = (# "conv.ovf.i4" value : int32 #) when ^T : float32 = (# "conv.ovf.i4" value : int32 #) @@ -4431,15 +5079,15 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.i4.un" value : int32 #) when ^T : unativeint = (# "conv.ovf.i4.un" value : int32 #) when ^T : byte = (# "conv.ovf.i4.un" value : int32 #) - + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int32) (value)) [] let inline int value = int32 value - [] + [] [] let inline uint64 (value: ^T) = - (^T : (static member op_Explicit: ^T -> uint64) (value)) + ExplicitDynamic<(^T), uint64> value when ^T : string = ParseUInt64 (castToString value) when ^T : float = (# "conv.ovf.u8" value : uint64 #) when ^T : float32 = (# "conv.ovf.u8" value : uint64 #) @@ -4454,11 +5102,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u8.un" value : uint64 #) when ^T : unativeint = (# "conv.ovf.u8.un" value : uint64 #) when ^T : byte = (# "conv.ovf.u8.un" value : uint64 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint64) (value)) - [] + [] [] let inline int64 (value: ^T) = - (^T : (static member op_Explicit: ^T -> int64) (value)) + ExplicitDynamic<(^T), int64> value when ^T : string = ParseInt64 (castToString value) when ^T : float = (# "conv.ovf.i8" value : int64 #) when ^T : float32 = (# "conv.ovf.i8" value : int64 #) @@ -4473,11 +5122,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.i8.un" value : int64 #) when ^T : unativeint = (# "conv.ovf.i8.un" value : int64 #) when ^T : byte = (# "conv.ovf.i8.un" value : int64 #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> int64) (value)) - [] + [] [] let inline unativeint (value: ^T) = - (^T : (static member op_Explicit: ^T -> unativeint) (value)) + ExplicitDynamic<(^T), unativeint> value when ^T : string = ParseUIntPtr (castToString value) when ^T : float = (# "conv.ovf.u" value : unativeint #) when ^T : float32 = (# "conv.ovf.u" value : unativeint #) @@ -4492,11 +5142,12 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.u.un" value : unativeint #) when ^T : unativeint = (# "conv.ovf.u.un" value : unativeint #) when ^T : byte = (# "conv.ovf.u.un" value : unativeint #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) - [] + [] [] let inline nativeint (value: ^T) = - (^T : (static member op_Explicit: ^T -> nativeint) (value)) + ExplicitDynamic<(^T), nativeint> value when ^T : string = ParseIntPtr (castToString value) when ^T : float = (# "conv.ovf.i" value : nativeint #) when ^T : float32 = (# "conv.ovf.i" value : nativeint #) @@ -4511,6 +5162,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.ovf.i.un" value : nativeint #) when ^T : unativeint = (# "conv.ovf.i.un" value : nativeint #) when ^T : byte = (# "conv.ovf.i.un" value : nativeint #) + when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = @@ -4666,20 +5318,20 @@ namespace Microsoft.FSharp.Core state.Current { new IEnumerator<'T> with - member __.Current = current () + member _.Current = current () interface System.IDisposable with - member __.Dispose () = () + member _.Dispose () = () interface IEnumerator with - member __.Current = box (current ()) + member _.Current = box (current ()) - member __.Reset () = + member _.Reset () = state.Started <- false state.Complete <- false state.Current <- Unchecked.defaultof<_> - member __.MoveNext () = + member _.MoveNext () = if not state.Started then state.Started <- true state.Current <- n @@ -4697,7 +5349,7 @@ namespace Microsoft.FSharp.Core not state.Complete} { new IEnumerable<'T> with - member __.GetEnumerator () = variableStepRangeEnumerator () + member _.GetEnumerator () = variableStepRangeEnumerator () interface IEnumerable with member this.GetEnumerator () = (variableStepRangeEnumerator ()) :> IEnumerator } @@ -4724,15 +5376,15 @@ namespace Microsoft.FSharp.Core derefValue { new IEnumerator<'T> with - member __.Current = current () + member _.Current = current () interface System.IDisposable with - member __.Dispose () = () + member _.Dispose () = () interface IEnumerator with - member __.Current = box (current ()) - member __.Reset () = value <- n - LanguagePrimitives.GenericOne - member __.MoveNext () = + member _.Current = box (current ()) + member _.Reset () = value <- n - LanguagePrimitives.GenericOne + member _.MoveNext () = let derefValue = value if derefValue < m then value <- derefValue + LanguagePrimitives.GenericOne @@ -4743,10 +5395,10 @@ namespace Microsoft.FSharp.Core else false } { new IEnumerable<'T> with - member __.GetEnumerator () = singleStepRangeEnumerator () + member _.GetEnumerator () = singleStepRangeEnumerator () interface IEnumerable with - member __.GetEnumerator () = (singleStepRangeEnumerator ()) :> IEnumerator } + member _.GetEnumerator () = (singleStepRangeEnumerator ()) :> IEnumerator } // For RangeStepGeneric, zero and add are functions representing the static resolution of GenericZero and (+) // for the particular static type. @@ -5390,7 +6042,7 @@ namespace Microsoft.FSharp.Core if len <= 0 then String.Empty else source.Substring(start, len) - [] + [] let inline absImpl (x: ^T) : ^T = (^T: (static member Abs : ^T -> ^T) (x)) when ^T : int32 = let x : int32 = retype x in System.Math.Abs(x) @@ -5407,61 +6059,61 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = let x : sbyte = retype x in System.Math.Abs(x) when ^T : decimal = System.Math.Abs(retype x : decimal) - [] + [] let inline acosImpl(x: ^T) : ^T = (^T: (static member Acos : ^T -> ^T) (x)) when ^T : float = System.Math.Acos(retype x) when ^T : float32 = System.Math.Acos(toFloat (retype x)) |> toFloat32 - [] + [] let inline asinImpl(x: ^T) : ^T = (^T: (static member Asin : ^T -> ^T) (x)) when ^T : float = System.Math.Asin(retype x) when ^T : float32 = System.Math.Asin(toFloat (retype x)) |> toFloat32 - [] + [] let inline atanImpl(x: ^T) : ^T = (^T: (static member Atan : ^T -> ^T) (x)) when ^T : float = System.Math.Atan(retype x) when ^T : float32 = System.Math.Atan(toFloat (retype x)) |> toFloat32 - [] + [] let inline atan2Impl(x: ^T) (y: ^T) : 'U = (^T: (static member Atan2 : ^T * ^T -> 'U) (x,y)) when ^T : float = System.Math.Atan2(retype x, retype y) when ^T : float32 = System.Math.Atan2(toFloat (retype x), toFloat(retype y)) |> toFloat32 - [] + [] let inline ceilImpl(x: ^T) : ^T = (^T: (static member Ceiling : ^T -> ^T) (x)) when ^T : float = System.Math.Ceiling(retype x : float) when ^T : float32 = System.Math.Ceiling(toFloat (retype x)) |> toFloat32 - [] + [] let inline expImpl(x: ^T) : ^T = (^T: (static member Exp : ^T -> ^T) (x)) when ^T : float = System.Math.Exp(retype x) when ^T : float32 = System.Math.Exp(toFloat (retype x)) |> toFloat32 - [] + [] let inline floorImpl (x: ^T) : ^T = (^T: (static member Floor : ^T -> ^T) (x)) when ^T : float = System.Math.Floor(retype x : float) when ^T : float32 = System.Math.Floor(toFloat (retype x)) |> toFloat32 - [] + [] let inline truncateImpl (x: ^T) : ^T = (^T: (static member Truncate : ^T -> ^T) (x)) when ^T : float = System.Math.Truncate(retype x : float) when ^T : float32 = System.Math.Truncate(toFloat (retype x)) |> toFloat32 - [] + [] let inline roundImpl (x: ^T) : ^T = (^T: (static member Round : ^T -> ^T) (x)) when ^T : float = System.Math.Round(retype x : float) when ^T : float32 = System.Math.Round(toFloat (retype x)) |> toFloat32 - [] + [] let inline signImpl (x: ^T) : int = (^T: (member Sign : int) (x)) when ^T : int32 = System.Math.Sign(retype x : int32) @@ -5473,79 +6125,67 @@ namespace Microsoft.FSharp.Core when ^T : float32 = System.Math.Sign(toFloat (retype x)) when ^T : decimal = System.Math.Sign(retype x : decimal) - [] + [] let inline logImpl(x: ^T) : ^T = (^T: (static member Log : ^T -> ^T) (x)) when ^T : float = System.Math.Log(retype x) when ^T : float32 = System.Math.Log(toFloat (retype x)) |> toFloat32 - [] + [] let inline log10Impl(x: ^T) : ^T = (^T: (static member Log10 : ^T -> ^T) (x)) when ^T : float = System.Math.Log10(retype x) when ^T : float32 = System.Math.Log10(toFloat (retype x)) |> toFloat32 - [] + [] let inline sqrtImpl(x: ^T) : ^U = (^T: (static member Sqrt : ^T -> ^U) (x)) when ^T : float = System.Math.Sqrt(retype x : float) when ^T : float32 = System.Math.Sqrt(toFloat (retype x)) |> toFloat32 - [] + [] let inline cosImpl(x: ^T) : ^T = (^T: (static member Cos : ^T -> ^T) (x)) when ^T : float = System.Math.Cos(retype x) when ^T : float32 = System.Math.Cos(toFloat (retype x)) |> toFloat32 - [] + [] let inline coshImpl(x: ^T) : ^T = (^T: (static member Cosh : ^T -> ^T) (x)) when ^T : float = System.Math.Cosh(retype x) when ^T : float32 = System.Math.Cosh(toFloat (retype x)) |> toFloat32 - [] + [] let inline sinImpl(x: ^T) : ^T = (^T: (static member Sin : ^T -> ^T) (x)) when ^T : float = System.Math.Sin(retype x) when ^T : float32 = System.Math.Sin(toFloat (retype x)) |> toFloat32 - [] + [] let inline sinhImpl(x: ^T) : ^T = (^T: (static member Sinh : ^T -> ^T) (x)) when ^T : float = System.Math.Sinh(retype x) when ^T : float32 = System.Math.Sinh(toFloat (retype x)) |> toFloat32 - [] + [] let inline tanImpl(x: ^T) : ^T = (^T: (static member Tan : ^T -> ^T) (x)) when ^T : float = System.Math.Tan(retype x) when ^T : float32 = System.Math.Tan(toFloat (retype x)) |> toFloat32 - [] + [] let inline tanhImpl(x: ^T) : ^T = (^T: (static member Tanh : ^T -> ^T) (x)) when ^T : float = System.Math.Tanh(retype x) when ^T : float32 = System.Math.Tanh(toFloat (retype x)) |> toFloat32 - [] + [] let inline powImpl (x: ^T) (y: ^U) : ^T = (^T: (static member Pow : ^T * ^U -> ^T) (x,y)) when ^T : float = System.Math.Pow((retype x : float), (retype y: float)) when ^T : float32 = System.Math.Pow(toFloat (retype x), toFloat(retype y)) |> toFloat32 [] - let UnaryDynamicImpl nm : ('T -> 'U) = - let aty = typeof<'T> - let minfo = aty.GetMethod(nm, [| aty |]) - (fun x -> unboxPrim<_>(minfo.Invoke(null,[| box x|]))) - - let BinaryDynamicImpl nm : ('T -> 'U -> 'V) = - let aty = typeof<'T> - let bty = typeof<'U> - let minfo = aty.GetMethod(nm,[| aty;bty |]) - (fun x y -> unboxPrim<_>(minfo.Invoke(null,[| box x; box y|]))) - - [] type AbsDynamicImplTable<'T>() = static let result : ('T -> 'T) = let aty = typeof<'T> diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index fd6c7557ef1..1683853779c 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -8,16 +8,27 @@ namespace Microsoft.FSharp.Core open System + /// + /// Basic definitions of operators, options, functions, results, choices, attributes and plain text formatting. + /// + /// /// The type 'unit', which has only one value "()". This value is special and /// always uses the representation 'null'. + /// + /// Basic Types + /// type Unit = interface IComparable /// The type 'unit', which has only one value "()". This value is special and /// always uses the representation 'null'. + /// + /// Basic Types and unit = Unit /// Indicates the relationship between a compiled entity in a CLI binary and an element in F# source code. + /// + /// Attributes type SourceConstructFlags = /// Indicates that the compiled entity has no relationship to an element in F# source code. | None = 0 @@ -57,6 +68,8 @@ namespace Microsoft.FSharp.Core [] /// Indicates one or more adjustments to the compiled representation of an F# type or member. + /// + /// Attributes type CompilationRepresentationFlags = /// No special compilation representation. @@ -79,6 +92,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to class definition makes it sealed, which means it may not /// be extended or implemented. + /// + /// Attributes [] type SealedAttribute = inherit Attribute @@ -87,7 +102,9 @@ namespace Microsoft.FSharp.Core new : unit -> SealedAttribute /// Creates an instance of the attribute + /// /// Indicates whether the class is sealed. + /// /// SealedAttribute new : value:bool -> SealedAttribute @@ -96,6 +113,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to class definition makes it abstract, which means it need not /// implement all its methods. Instances of abstract classes may not be constructed directly. + /// + /// Attributes [] [] type AbstractClassAttribute = @@ -108,6 +127,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to the let-binding for the definition of a top-level /// value makes the quotation expression that implements the value available /// for use at runtime. + /// + /// Attributes [] [] type ReflectedDefinitionAttribute = @@ -118,7 +139,9 @@ namespace Microsoft.FSharp.Core new : unit -> ReflectedDefinitionAttribute /// Creates an instance of the attribute + /// /// Indicates whether to include the evaluated value of the definition as the outer node of the quotation + /// /// ReflectedDefinitionAttribute new : includeValue:bool -> ReflectedDefinitionAttribute @@ -126,14 +149,21 @@ namespace Microsoft.FSharp.Core member IncludeValue: bool /// This attribute is used to indicate a generic container type satisfies the F# 'equality' - /// constraint only if a generic argument also satisfies this constraint. For example, adding + /// constraint only if a generic argument also satisfies this constraint. + /// + /// + /// + /// For example, adding /// this attribute to parameter 'T on a type definition C<'T> means that a type C<X> only supports /// equality if the type X also supports equality and all other conditions for C<X> to support /// equality are also met. The type C<'T> can still be used with other type arguments, but a type such /// as C<(int -> int)> will not support equality because the type (int -> int) is an F# function type - /// and does not support equality. + /// and does not support equality. + /// + /// This attribute will be ignored if it is used on the generic parameters of functions or methods. + /// /// - /// This attribute will be ignored if it is used on the generic parameters of functions or methods. + /// Attributes [] [] type EqualityConditionalOnAttribute = @@ -144,14 +174,19 @@ namespace Microsoft.FSharp.Core new : unit -> EqualityConditionalOnAttribute /// This attribute is used to indicate a generic container type satisfies the F# 'comparison' - /// constraint only if a generic argument also satisfies this constraint. For example, adding + /// constraint only if a generic argument also satisfies this constraint. + /// + /// For example, adding /// this attribute to parameter 'T on a type definition C<'T> means that a type C<X> only supports /// comparison if the type X also supports comparison and all other conditions for C<X> to support /// comparison are also met. The type C<'T> can still be used with other type arguments, but a type such /// as C<(int -> int)> will not support comparison because the type (int -> int) is an F# function type - /// and does not support comparison. + /// and does not support comparison. /// - /// This attribute will be ignored if it is used on the generic parameters of functions or methods. + /// This attribute will be ignored if it is used on the generic parameters of functions or methods. + /// + /// + /// Attributes [] [] type ComparisonConditionalOnAttribute = @@ -162,7 +197,9 @@ namespace Microsoft.FSharp.Core new : unit -> ComparisonConditionalOnAttribute /// Adding this attribute to a type causes it to be represented using a CLI struct. - [] + /// + /// Attributes + [] [] type StructAttribute = inherit Attribute @@ -173,6 +210,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a type causes it to be interpreted as a unit of measure. /// This may only be used under very limited conditions. + /// + /// Attributes [] [] type MeasureAttribute = @@ -184,6 +223,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a type causes it to be interpreted as a refined type, currently limited to measure-parameterized types. /// This may only be used under very limited conditions. + /// + /// Attributes [] [] type MeasureAnnotatedAbbreviationAttribute = @@ -194,6 +235,8 @@ namespace Microsoft.FSharp.Core new : unit -> MeasureAnnotatedAbbreviationAttribute /// Adding this attribute to a type causes it to be represented using a CLI interface. + /// + /// Attributes [] [] type InterfaceAttribute = @@ -204,6 +247,8 @@ namespace Microsoft.FSharp.Core new : unit -> InterfaceAttribute /// Adding this attribute to a type causes it to be represented using a CLI class. + /// + /// Attributes [] [] type ClassAttribute = @@ -216,6 +261,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a type lets the 'null' literal be used for the type /// within F# code. This attribute may only be added to F#-defined class or /// interface types. + /// + /// Attributes [] [] type AllowNullLiteralAttribute = @@ -233,6 +280,8 @@ namespace Microsoft.FSharp.Core member Value: bool /// Adding this attribute to a value causes it to be compiled as a CLI constant literal. + /// + /// Attributes [] [] type LiteralAttribute = @@ -245,6 +294,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a property with event type causes it to be compiled with as a CLI /// metadata event, through a syntactic translation to a pair of 'add_EventName' and /// 'remove_EventName' methods. + /// + /// Attributes [] [] type CLIEventAttribute = @@ -256,6 +307,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a record type causes it to be compiled to a CLI representation /// with a default constructor with property getters and setters. + /// + /// Attributes [] [] type CLIMutableAttribute = @@ -268,6 +321,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a discriminated union with value false /// turns off the generation of standard helper member tester, constructor /// and accessor members for the generated CLI class for that type. + /// + /// Attributes [] [] type DefaultAugmentationAttribute = @@ -277,13 +332,17 @@ namespace Microsoft.FSharp.Core member Value: bool /// Creates an instance of the attribute + /// /// Indicates whether to generate helper members on the CLI class representing a discriminated /// union. + /// /// DefaultAugmentationAttribute new : value:bool -> DefaultAugmentationAttribute /// Adding this attribute to an F# mutable binding causes the "volatile" /// prefix to be used for all accesses to the field. + /// + /// Attributes [] [] type VolatileFieldAttribute = @@ -296,6 +355,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a function indicates it is the entrypoint for an application. /// If this attribute is not specified for an EXE then the initialization implicit in the /// module bindings in the last file in the compilation sequence are used as the entrypoint. + /// + /// Attributes [] [] type EntryPointAttribute = @@ -308,6 +369,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a record or union type disables the automatic generation /// of overrides for 'System.Object.Equals(obj)', 'System.Object.GetHashCode()' /// and 'System.IComparable' for the type. The type will by default use reference equality. + /// + /// Attributes [] [] type ReferenceEqualityAttribute = @@ -320,6 +383,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a record, union or struct type confirms the automatic /// generation of overrides for 'System.Object.Equals(obj)' and /// 'System.Object.GetHashCode()' for the type. + /// + /// Attributes [] [] type StructuralEqualityAttribute = @@ -331,6 +396,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a record, union, exception, or struct type confirms the /// automatic generation of implementations for 'System.IComparable' for the type. + /// + /// Attributes [] [] type StructuralComparisonAttribute = @@ -342,8 +409,10 @@ namespace Microsoft.FSharp.Core [] [] - /// Indicates that a member on a computation builder type is a custom query operator, - /// and indicates the name of that operator. + /// Indicates that a member on a computation builder type is a custom query operator, + /// and indicates the name of that operator. + /// + /// Attributes type CustomOperationAttribute = inherit Attribute @@ -379,6 +448,8 @@ namespace Microsoft.FSharp.Core [] /// Indicates that, when a custom operator is used in a computation expression, /// a parameter is automatically parameterized by the variable space of the computation expression + /// + /// Attributes type ProjectionParameterAttribute = /// Creates an instance of the attribute @@ -391,6 +462,8 @@ namespace Microsoft.FSharp.Core /// F# type system, this helps ensure that the F# generic equality function is not instantiated directly /// at this type. The attribute and checking does not constrain the use of comparison with base or child /// types of this type. + /// + /// Attributes [] [] type NoEqualityAttribute = @@ -401,6 +474,8 @@ namespace Microsoft.FSharp.Core new : unit -> NoEqualityAttribute /// Adding this attribute to a type indicates it is a type with a user-defined implementation of equality. + /// + /// Attributes [] [] type CustomEqualityAttribute = @@ -411,6 +486,8 @@ namespace Microsoft.FSharp.Core new : unit -> CustomEqualityAttribute /// Adding this attribute to a type indicates it is a type with a user-defined implementation of comparison. + /// + /// Attributes [] [] type CustomComparisonAttribute = @@ -424,7 +501,10 @@ namespace Microsoft.FSharp.Core /// This means that the type does not satisfy the F# 'comparison' constraint. Within the bounds of the /// F# type system, this helps ensure that the F# generic comparison function is not instantiated directly /// at this type. The attribute and checking does not constrain the use of comparison with base or child - /// types of this type. + /// types of this type. + /// + /// + /// Attributes [] [] type NoComparisonAttribute = @@ -436,8 +516,11 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a field declaration means that the field is /// not initialized. During type checking a constraint is asserted that the field type supports 'null'. - /// If the 'check' value is false then the constraint is not asserted. - [] + /// If the 'check' value is false then the constraint is not asserted. + /// + /// + /// Attributes + [] [] type DefaultValueAttribute = inherit Attribute @@ -450,11 +533,15 @@ namespace Microsoft.FSharp.Core new : unit -> DefaultValueAttribute /// Creates an instance of the attribute + /// /// Indicates whether to assert that the field type supports null. + /// /// DefaultValueAttribute new : check: bool -> DefaultValueAttribute /// This attribute is added automatically for all optional arguments. + /// + /// Attributes [] [] type OptionalArgumentAttribute = @@ -466,6 +553,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a type, value or member requires that /// uses of the construct must explicitly instantiate any generic type parameters. + /// + /// Attributes [] [] type RequiresExplicitTypeArgumentsAttribute = @@ -477,6 +566,8 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a non-function value with generic parameters indicates that /// uses of the construct can give rise to generic code through type inference. + /// + /// Attributes [] [] type GeneralizableValueAttribute = @@ -488,13 +579,17 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a value or function definition in an F# module changes the name used /// for the value in compiled CLI code. + /// + /// Attributes [] [] type CompiledNameAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// The name to use in compiled code. + /// /// CompiledNameAttribute new : compiledName:string -> CompiledNameAttribute @@ -503,13 +598,17 @@ namespace Microsoft.FSharp.Core /// Adding this attribute to a type with value 'false' disables the behaviour where F# makes the /// type Serializable by default. + /// + /// Attributes [] [] type AutoSerializableAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// Indicates whether the type should be serializable by default. + /// /// AutoSerializableAttribute new : value:bool -> AutoSerializableAttribute @@ -519,15 +618,19 @@ namespace Microsoft.FSharp.Core /// This attribute is added to generated assemblies to indicate the /// version of the data schema used to encode additional F# /// specific information in the resource attached to compiled F# libraries. + /// + /// Attributes [] [] type FSharpInterfaceDataVersionAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// The major version number. /// The minor version number. /// The release number. + /// /// FSharpInterfaceDataVersionAttribute new : major:int * minor:int * release:int -> FSharpInterfaceDataVersionAttribute @@ -542,31 +645,47 @@ namespace Microsoft.FSharp.Core /// This attribute is inserted automatically by the F# compiler to tag types /// and methods in the generated CLI code with flags indicating the correspondence - /// with original source constructs. It is used by the functions in the - /// Microsoft.FSharp.Reflection namespace to reverse-map compiled constructs to - /// their original forms. It is not intended for use from user code. + /// with original source constructs. + /// + /// This attribute is used by the functions in the + /// FSharp.Reflection namespace to reverse-map compiled constructs to + /// their original forms. It is not intended for use from user code. + /// + /// Attributes [] [] type CompilationMappingAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// Indicates the type of source construct. + /// /// CompilationMappingAttribute new : sourceConstructFlags:SourceConstructFlags -> CompilationMappingAttribute /// Creates an instance of the attribute + /// /// Indicates the type of source construct. + /// Indicates the index in the sequence of constructs. + /// /// CompilationMappingAttribute new : sourceConstructFlags:SourceConstructFlags * sequenceNumber: int -> CompilationMappingAttribute /// Creates an instance of the attribute + /// /// Indicates the type of source construct. + /// Indicates the index in the sequence of variants. + /// Indicates the index in the sequence of constructs. + /// /// CompilationMappingAttribute new : sourceConstructFlags:SourceConstructFlags * variantNumber : int * sequenceNumber : int -> CompilationMappingAttribute /// Creates an instance of the attribute + /// /// Indicates the type definitions needed to resolve the source construct. + /// The name of the resource needed to resolve the source construct. + /// /// CompilationMappingAttribute new : resourceName:string * typeDefinitions:System.Type[] -> CompilationMappingAttribute @@ -585,15 +704,23 @@ namespace Microsoft.FSharp.Core member TypeDefinitions : System.Type[] /// This attribute is inserted automatically by the F# compiler to tag - /// methods which are given the 'CompiledName' attribute. It is not intended - /// for use from user code. + /// methods which are given the 'CompiledName' attribute. + /// + /// This attribute is used by the functions in the + /// FSharp.Reflection namespace to reverse-map compiled constructs to + /// their original forms. It is not intended for use from user code. + /// + /// + /// Attributes [] [] type CompilationSourceNameAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// The name of the method in source. + /// /// CompilationSourceNameAttribute new : sourceName:string -> CompilationSourceNameAttribute @@ -602,44 +729,80 @@ namespace Microsoft.FSharp.Core /// This attribute is used to adjust the runtime representation for a type. /// For example, it may be used to note that the null representation - /// may be used for a type. This affects how some constructs are compiled. + /// may be used for a type. This affects how some constructs are compiled. + /// + /// + /// Attributes [] [] type CompilationRepresentationAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// Indicates adjustments to the compiled representation of the type or member. + /// /// CompilationRepresentationAttribute new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute /// Indicates one or more adjustments to the compiled representation of an F# type or member member Flags : CompilationRepresentationFlags + module internal ExperimentalAttributeMessages = + [] + val RequiresPreview : string = "Experimental library feature, requires '--langversion:preview'" + [] + val NotSupportedYet : string = "This construct is not supported by your version of the F# compiler" + /// This attribute is used to tag values that are part of an experimental library /// feature. + /// + /// Attributes [] [] type ExperimentalAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// The warning message to be emitted when code uses this construct. + /// /// ExperimentalAttribute new : message:string-> ExperimentalAttribute /// Indicates the warning message to be emitted when F# source code uses this construct member Message: string + /// Adding this attribute to a parameter of function type indicates that, if the overall function or method is inlined and the parameter is + /// determined to be a known lambda, then this function should be statically inlined throughout the body of the function of method. + /// + /// If the function parameter is called multiple times in the implementation of the function or method this attribute may cause code explosion and slow compilation times. + /// + /// Attributes + [] + [] + [] + type InlineIfLambdaAttribute = + inherit Attribute + + /// Creates an instance of the attribute + /// InlineIfLambdaAttribute + new : unit -> InlineIfLambdaAttribute + /// This attribute is generated automatically by the F# compiler to tag functions and members - /// that accept a partial application of some of their arguments and return a residual function + /// that accept a partial application of some of their arguments and return a residual function. + /// + /// + /// Attributes [] [] type CompilationArgumentCountsAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// Indicates the number of arguments in each argument group. + /// /// CompilationArgumentCountsAttribute new : counts:int[] -> CompilationArgumentCountsAttribute @@ -650,13 +813,17 @@ namespace Microsoft.FSharp.Core /// '%A' printf formatting patterns and other two-dimensional text-based display layouts. /// In this version of F# valid values are of the form PreText {PropertyName1} PostText {PropertyName2} ... {PropertyNameX} PostText. /// The property names indicate properties to evaluate and to display instead of the object itself. + /// + /// Attributes [] [] type StructuredFormatDisplayAttribute = inherit Attribute /// Creates an instance of the attribute + /// /// Indicates the text to display when using the '%A' printf formatting. + /// /// StructuredFormatDisplayAttribute new : value:string-> StructuredFormatDisplayAttribute @@ -666,6 +833,8 @@ namespace Microsoft.FSharp.Core member Value: string /// Indicates that a message should be emitted when F# source code uses this construct. + /// + /// Attributes [] [] type CompilerMessageAttribute = @@ -691,6 +860,8 @@ namespace Microsoft.FSharp.Core /// of unverifiable code. These values are inevitably marked 'inline' to ensure that /// the unverifiable constructs are not present in the actual code for the F# library, /// but are rather copied to the source code of the caller. + /// + /// Attributes [] [] type UnverifiableAttribute = @@ -705,6 +876,8 @@ namespace Microsoft.FSharp.Core /// causes the method body emitted for the inlined function to raise an exception if /// dynamically invoked, rather than including the unverifiable code in the generated /// assembly. + /// + /// Attributes [] [] type NoDynamicInvocationAttribute = @@ -714,8 +887,12 @@ namespace Microsoft.FSharp.Core /// NoDynamicInvocationAttribute new : unit -> NoDynamicInvocationAttribute + internal new : isLegacy: bool -> NoDynamicInvocationAttribute + /// This attribute is used to indicate that references to the elements of a module, record or union /// type require explicit qualified access. + /// + /// Attributes [] [] type RequireQualifiedAccessAttribute = @@ -725,13 +902,19 @@ namespace Microsoft.FSharp.Core /// RequireQualifiedAccessAttribute new : unit -> RequireQualifiedAccessAttribute - /// This attribute is used for two purposes. When applied to an assembly, it must be given a string - /// argument, and this argument must indicate a valid module or namespace in that assembly. Source + /// Indicates a construct is automatically opened when brought into scope through + /// an assembly reference or then opening of the containing namespace or module. + /// + /// When applied to an assembly, this attribute must be given a string + /// argument, and this indicates a valid module or namespace in that assembly. Source /// code files compiled with a reference to this assembly are processed in an environment - /// where the given path is automatically opened. + /// where the given path is automatically opened. + /// + /// When applied to a type or module within an assembly, then the attribute must not be given any arguments, and + /// the type or module is implicitly opened when its enclosing namespace or module is opened. + /// /// - /// When applied to a module within an assembly, then the attribute must not be given any arguments. - /// When the enclosing namespace is opened in user source code, the module is also implicitly opened. + /// Attributes [] [] type AutoOpenAttribute = @@ -742,8 +925,10 @@ namespace Microsoft.FSharp.Core new : unit -> AutoOpenAttribute /// Creates an attribute used to mark a namespace or module path to be 'automatically opened' when an assembly is referenced + /// /// The namespace or module to be automatically opened when an assembly is referenced /// or an enclosing module opened. + /// /// AutoOpenAttribute new : path:string-> AutoOpenAttribute @@ -752,71 +937,203 @@ namespace Microsoft.FSharp.Core member Path: string [] - /// The type of floating point numbers, annotated with a unit of measure. The unit - /// of measure is erased in compiled code and when values of this type + /// The type of double-precision floating point numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Double. + /// . + /// + /// Basic Types with Units of Measure type float<[] 'Measure> = float [] - /// The type of floating point numbers, annotated with a unit of measure. The unit - /// of measure is erased in compiled code and when values of this type + /// The type of single-precision floating point numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Single. + /// . + /// + /// + /// Basic Types with Units of Measure type float32<[] 'Measure> = float32 [] /// The type of decimal numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Decimal. + /// . + /// + /// Basic Types with Units of Measure type decimal<[] 'Measure> = decimal [] /// The type of 32-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Int32. + /// . + /// + /// Basic Types with Units of Measure type int<[] 'Measure> = int - + [] /// The type of 8-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.SByte. + /// . + /// + /// Basic Types with Units of Measure type sbyte<[] 'Measure> = sbyte [] /// The type of 16-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Int16. + /// . + /// + /// Basic Types with Units of Measure type int16<[] 'Measure> = int16 [] /// The type of 64-bit signed integer numbers, annotated with a unit of measure. The unit /// of measure is erased in compiled code and when values of this type /// are analyzed using reflection. The type is representationally equivalent to - /// System.Int64. + /// . + /// + /// Basic Types with Units of Measure type int64<[] 'Measure> = int64 + [] + [] + /// The type of machine-sized signed integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type nativeint<[] 'Measure> = nativeint + + [] + [] + /// The type of 32-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type uint<[] 'Measure> = uint + + [] + [] + /// The type of 8-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type byte<[] 'Measure> = byte + + [] + [] + /// The type of 16-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type uint16<[] 'Measure> = uint16 + + [] + [] + /// The type of 64-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type uint64<[] 'Measure> = uint64 + + [] + [] + /// The type of machine-sized unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type unativeint<[] 'Measure> = unativeint + + [] + /// The type of double-precision floating point numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type double<[] 'Measure> = float<'Measure> + + [] + /// The type of single-precision floating point numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type single<[] 'Measure> = float32<'Measure> + + [] + /// The type of 8-bit signed integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type int8<[] 'Measure> = sbyte<'Measure> + + [] + /// The type of 32-bit signed integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type int32<[] 'Measure> = int<'Measure> + + [] + /// The type of 8-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type uint8<[] 'Measure> = byte<'Measure> + + [] + /// The type of 32-bit unsigned integer numbers, annotated with a unit of measure. + /// The unit of measure is erased in compiled code and when values of this type + /// are analyzed using reflection. The type is representationally equivalent to + /// . + /// + /// Basic Types with Units of Measure + type uint32<[] 'Measure> = uint<'Measure> + /// Represents a managed pointer in F# code. #if BUILDING_WITH_LKG || BUILD_FROM_SOURCE [] #else [] #endif + /// ByRef and Pointer Types type byref<'T, 'Kind> = (# "!0&" #) /// Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to byref<'T, ByRefKinds.InOut> + /// ByRef and Pointer Types type byref<'T> = (# "!0&" #) - /// Represents the types of byrefs in F# 4.5+ + /// Represents the types of byrefs in F# 4.5+ #if BUILDING_WITH_LKG || BUILD_FROM_SOURCE [] #else [] #endif + /// ByRef and Pointer Types module ByRefKinds = /// Represents a byref that can be written @@ -844,93 +1161,123 @@ namespace Microsoft.FSharp.Core type InOut /// Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+. + /// ByRef and Pointer Types type inref<'T> = byref<'T, ByRefKinds.In> /// Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+. + /// ByRef and Pointer Types type outref<'T> = byref<'T, ByRefKinds.Out> /// Language primitives associated with the F# language + /// + /// Language Primitives module LanguagePrimitives = /// Compare two values for equality using partial equivalence relation semantics ([nan] <> [nan]) + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericEquality : e1:'T -> e2:'T -> bool when 'T : equality /// Compare two values for equality using equivalence relation semantics ([nan] = [nan]) + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericEqualityER : e1:'T -> e2:'T -> bool when 'T : equality /// Compare two values for equality + /// /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericEqualityWithComparer : comp:System.Collections.IEqualityComparer -> e1:'T -> e2:'T -> bool when 'T : equality /// Compare two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericComparison : e1:'T -> e2:'T -> int when 'T : comparison /// Compare two values. May be called as a recursive case from an implementation of System.IComparable to /// ensure consistent NaN comparison semantics. + /// /// The function to compare the values. /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericComparisonWithComparer : comp:System.Collections.IComparer -> e1:'T -> e2:'T -> int when 'T : comparison /// Compare two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericLessThan : e1:'T -> e2:'T -> bool when 'T : comparison /// Compare two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericGreaterThan : e1:'T -> e2:'T -> bool when 'T : comparison /// Compare two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericLessOrEqual : e1:'T -> e2:'T -> bool when 'T : comparison /// Compare two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline GenericGreaterOrEqual : e1:'T -> e2:'T -> bool when 'T : comparison /// Take the minimum of two values structurally according to the order given by GenericComparison + /// /// The first value. /// The second value. + /// /// The minimum value. val inline GenericMinimum : e1:'T -> e2:'T -> 'T when 'T : comparison /// Take the maximum of two values structurally according to the order given by GenericComparison + /// /// The first value. /// The second value. + /// /// The maximum value. val inline GenericMaximum : e1:'T -> e2:'T -> 'T when 'T : comparison /// Reference/physical equality. /// True if the inputs are reference-equal, false otherwise. + /// /// The first value. /// The second value. + /// /// The result of the comparison. val inline PhysicalEquality : e1:'T -> e2:'T -> bool when 'T : not struct /// The physical hash. Hashes on the object identity, except for value types, /// where we hash on the contents. + /// /// The input object. + /// /// The hashed value. val inline PhysicalHash : obj:'T -> int when 'T : not struct @@ -959,7 +1306,9 @@ namespace Microsoft.FSharp.Core /// Make an F# hash/equality object for the given type using node-limited hashing when hashing F# /// records, lists and union types. + /// /// The input limit on the number of nodes. + /// /// System.Collections.Generic.IEqualityComparer<'T> val inline FastLimitedGenericEqualityComparer<'T> : limit: int -> System.Collections.Generic.IEqualityComparer<'T> when 'T : equality @@ -973,85 +1322,165 @@ namespace Microsoft.FSharp.Core /// Hash a value according to its structure. This hash is not limited by an overall node count when hashing F# /// records, lists and union types. + /// /// The input object. + /// /// The hashed value. val inline GenericHash : obj:'T -> int /// Hash a value according to its structure. Use the given limit to restrict the hash when hashing F# /// records, lists and union types. + /// /// The limit on the number of nodes. /// The input object. + /// /// The hashed value. val inline GenericLimitedHash : limit: int -> obj:'T -> int /// Recursively hash a part of a value according to its structure. + /// /// The comparison function. /// The input object. + /// /// The hashed value. val inline GenericHashWithComparer : comparer : System.Collections.IEqualityComparer -> obj:'T -> int /// Build an enum value from an underlying value + /// /// The input value. + /// /// The value as an enumeration. val inline EnumOfValue : value:'T -> 'Enum when 'Enum : enum<'T> /// Get the underlying value for an enum value + /// /// The input enum. + /// /// The enumeration as a value. val inline EnumToValue : enum:'Enum -> 'T when 'Enum : enum<'T> /// Creates a float value with units-of-measure - /// The input float. + /// + /// The input float. + /// /// The float with units-of-measure. - val inline FloatWithMeasure : float -> float<'Measure> + val inline FloatWithMeasure : input: float -> float<'Measure> /// Creates a float32 value with units-of-measure - /// The input float. + /// + /// The input float. + /// /// The float with units-of-measure. - val inline Float32WithMeasure : float32 -> float32<'Measure> + val inline Float32WithMeasure : input: float32 -> float32<'Measure> /// Creates a decimal value with units-of-measure - /// The input decimal. + /// + /// The input decimal. + /// /// The decimal with units of measure. - val inline DecimalWithMeasure : decimal -> decimal<'Measure> + val inline DecimalWithMeasure : input: decimal -> decimal<'Measure> /// Creates an int32 value with units-of-measure - /// The input int. + /// + /// The input int. + /// /// The int with units of measure. - val inline Int32WithMeasure : int -> int<'Measure> + val inline Int32WithMeasure : input: int -> int<'Measure> /// Creates an int64 value with units-of-measure - /// The input int64. + /// + /// The input int64. + /// /// The int64 with units of measure. - val inline Int64WithMeasure : int64 -> int64<'Measure> + val inline Int64WithMeasure : input: int64 -> int64<'Measure> /// Creates an int16 value with units-of-measure - /// The input int16. + /// + /// The input int16. + /// /// The int16 with units-of-measure. - val inline Int16WithMeasure : int16 -> int16<'Measure> + val inline Int16WithMeasure : input: int16 -> int16<'Measure> /// Creates an sbyte value with units-of-measure - /// The input sbyte. + /// + /// The input sbyte. + /// /// The sbyte with units-of-measure. - val inline SByteWithMeasure : sbyte -> sbyte<'Measure> + val inline SByteWithMeasure : input: sbyte -> sbyte<'Measure> + + [] + /// Creates a nativeint value with units-of-measure + /// + /// The input nativeint. + /// + /// The nativeint with units-of-measure. + val inline IntPtrWithMeasure : input: nativeint -> nativeint<'Measure> + + [] + /// Creates a uint value with units-of-measure + /// + /// The input uint. + /// + /// The uint with units-of-measure. + val inline UInt32WithMeasure : input: uint -> uint<'Measure> + + [] + /// Creates a uint64 value with units-of-measure + /// + /// The input uint64. + /// + /// The uint64 with units-of-measure. + val inline UInt64WithMeasure : input: uint64 -> uint64<'Measure> + + [] + /// Creates a uint16 value with units-of-measure + /// + /// The input uint16. + /// + /// The uint16 with units-of-measure. + val inline UInt16WithMeasure : input: uint16 -> uint16<'Measure> + + [] + /// Creates a byte value with units-of-measure + /// + /// The input byte. + /// + /// The byte with units-of-measure. + val inline ByteWithMeasure : input: byte -> byte<'Measure> + + [] + /// Creates a unativeint value with units-of-measure + /// + /// The input unativeint. + /// + /// The unativeint with units-of-measure. + val inline UIntPtrWithMeasure : input: unativeint -> unativeint<'Measure> /// Parse an int32 according to the rules used by the overloaded 'int32' conversion operator when applied to strings + /// /// The input string. + /// /// The parsed value. - val ParseInt32 : s:string -> int32 + val ParseInt32 : s: string -> int32 /// Parse an uint32 according to the rules used by the overloaded 'uint32' conversion operator when applied to strings + /// /// The input string. + /// /// The parsed value. val ParseUInt32 : s:string -> uint32 /// Parse an int64 according to the rules used by the overloaded 'int64' conversion operator when applied to strings + /// /// The input string. + /// /// The parsed value. val ParseInt64 : s:string -> int64 /// Parse an uint64 according to the rules used by the overloaded 'uint64' conversion operator when applied to strings + /// /// The input string. + /// /// The parsed value. val ParseUInt64 : s:string -> uint64 @@ -1079,6 +1508,82 @@ namespace Microsoft.FSharp.Core [] val CheckedMultiplyDynamic : x:'T1 -> y:'T2 -> 'U + /// A compiler intrinsic that implements dynamic invocations to the '-' operator. + [] + val SubtractionDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '/' operator. + [] + val DivisionDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the unary '-' operator. + [] + val UnaryNegationDynamic : value:'T -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '%' operator. + [] + val ModulusDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the checked '-' operator. + [] + val CheckedSubtractionDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the checked unary '-' operator. + [] + val CheckedUnaryNegationDynamic : value:'T -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '<<<' operator. + [] + val LeftShiftDynamic : value:'T1 -> shift:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '>>>' operator. + [] + val RightShiftDynamic : value:'T1 -> shift:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '&&&' operator. + [] + val BitwiseAndDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations to the '|||' operator. + [] + val BitwiseOrDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '^^^' operator. + [] + val ExclusiveOrDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '~~~' operator. + [] + val LogicalNotDynamic : value:'T -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to conversion operators. + [] + val ExplicitDynamic : value:'T -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '<' operator. + [] + val LessThanDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '>' operator. + [] + val GreaterThanDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '<=' operator. + [] + val LessThanOrEqualDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '>=' operator. + [] + val GreaterThanOrEqualDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '=' operator. + [] + val EqualityDynamic : x:'T1 -> y:'T2 -> 'U + + /// A compiler intrinsic that implements dynamic invocations related to the '=' operator. + [] + val InequalityDynamic : x:'T1 -> y:'T2 -> 'U + /// A compiler intrinsic that implements dynamic invocations for the DivideByInt primitive. [] val DivideByIntDynamic : x:'T -> y:int -> 'T @@ -1092,8 +1597,10 @@ namespace Microsoft.FSharp.Core val internal anyToStringShowingNull : 'T -> string /// Divides a value by an integer. + /// /// The input value. /// The input int. + /// /// The division result. val inline DivideByInt< ^T > : x:^T -> y:int -> ^T when ^T : (static member DivideByInt : ^T * int -> ^T) @@ -1126,8 +1633,10 @@ namespace Microsoft.FSharp.Core val ( & ) : e1:bool -> e2:bool -> bool /// Binary 'and'. When used as a binary operator the right hand value is evaluated only on demand + /// /// The first value. /// The second value. + /// /// The result of the operation. val ( && ) : e1:bool -> e2:bool -> bool @@ -1137,21 +1646,25 @@ namespace Microsoft.FSharp.Core val ( or ) : e1:bool -> e2:bool -> bool /// Binary 'or'. When used as a binary operator the right hand value is evaluated only on demand + /// /// The first value. /// The second value. + /// /// The result of the operation. val ( || ) : e1:bool -> e2:bool -> bool /// Address-of. Uses of this value may result in the generation of unverifiable code. + /// /// The input object. + /// /// The managed pointer. - [] val inline ( ~& ) : obj:'T -> byref<'T> /// Address-of. Uses of this value may result in the generation of unverifiable code. + /// /// The input object. + /// /// The unmanaged pointer. - [] val inline ( ~&& ) : obj:'T -> nativeptr<'T> //------------------------------------------------------------------------- @@ -1347,7 +1860,7 @@ namespace Microsoft.FSharp.Core /// Helper types for active patterns with 2 choices. - //[] + /// Choices and Results [] [] type Choice<'T1,'T2> = @@ -1359,6 +1872,7 @@ namespace Microsoft.FSharp.Core | Choice2Of2 of 'T2 /// Helper types for active patterns with 3 choices. + /// Choices and Results [] [] type Choice<'T1,'T2,'T3> = @@ -1373,6 +1887,7 @@ namespace Microsoft.FSharp.Core | Choice3Of3 of 'T3 /// Helper types for active patterns with 4 choices. + /// Choices and Results [] [] type Choice<'T1,'T2,'T3,'T4> = @@ -1390,6 +1905,7 @@ namespace Microsoft.FSharp.Core | Choice4Of4 of 'T4 /// Helper types for active patterns with 5 choices. + /// Choices and Results [] [] type Choice<'T1,'T2,'T3,'T4,'T5> = @@ -1410,6 +1926,7 @@ namespace Microsoft.FSharp.Core | Choice5Of5 of 'T5 /// Helper types for active patterns with 6 choices. + /// Choices and Results [] [] type Choice<'T1,'T2,'T3,'T4,'T5,'T6> = @@ -1433,6 +1950,7 @@ namespace Microsoft.FSharp.Core | Choice6Of6 of 'T6 /// Helper types for active patterns with 7 choices. + /// Choices and Results [] [] type Choice<'T1,'T2,'T3,'T4,'T5,'T6,'T7> = @@ -1459,11 +1977,13 @@ namespace Microsoft.FSharp.Core | Choice7Of7 of 'T7 /// Non-exhaustive match failures will raise the MatchFailureException exception + /// Language Primitives [] exception MatchFailureException of string * int * int /// The CLI type used to represent F# first-class type function values. This type is for use /// by compiled F# code. + /// Language Primitives [] type FSharpTypeFunc = @@ -1477,6 +1997,7 @@ namespace Microsoft.FSharp.Core /// The CLI type used to represent F# function values. This type is not /// typically used directly, though may be used from other CLI languages. + /// Language Primitives [] type FSharpFunc<'T,'U> = @@ -1485,65 +2006,83 @@ namespace Microsoft.FSharp.Core new : unit -> FSharpFunc<'T,'U> /// Invoke an F# first class function value with one argument + /// /// + /// /// 'U - abstract member Invoke : func:'T -> 'U + abstract Invoke : func:'T -> 'U - /// Convert an F# first class function value to a value of type System.Converter + /// Convert an F# first class function value to a value of type + /// /// The input function. + /// /// A System.Converter of the function type. static member op_Implicit : func:('T -> 'U) -> System.Converter<'T,'U> - /// Convert an value of type System.Converter to a F# first class function value + /// Convert an value of type to a F# first class function value + /// /// The input System.Converter. + /// /// An F# function of the same type. static member op_Implicit : converter:System.Converter<'T,'U> -> ('T -> 'U) - /// Convert an F# first class function value to a value of type System.Converter + /// Convert an F# first class function value to a value of type + /// /// The input function. + /// /// System.Converter<'T,'U> static member ToConverter : func:('T -> 'U) -> System.Converter<'T,'U> - /// Convert an value of type System.Converter to a F# first class function value + /// Convert an value of type to a F# first class function value + /// /// The input System.Converter. + /// /// An F# function of the same type. static member FromConverter : converter:System.Converter<'T,'U> -> ('T -> 'U) /// Invoke an F# first class function value with five curried arguments. In some cases this /// will result in a more efficient application than applying the arguments successively. + /// /// The input function. /// The first arg. /// The second arg. /// The third arg. /// The fourth arg. /// The fifth arg. + /// /// The function result. static member InvokeFast : func: FSharpFunc<'T,('U -> 'V -> 'W -> 'X -> 'Y)> * arg1:'T * arg2:'U * arg3:'V * arg4:'W * arg5:'X -> 'Y /// Invoke an F# first class function value with four curried arguments. In some cases this /// will result in a more efficient application than applying the arguments successively. + /// /// The input function. /// The first arg. /// The second arg. /// The third arg. /// The fourth arg. + /// /// The function result. static member InvokeFast : func: FSharpFunc<'T,('U -> 'V -> 'W -> 'X)> * arg1:'T * arg2:'U * arg3:'V * arg4:'W -> 'X /// Invoke an F# first class function value with three curried arguments. In some cases this /// will result in a more efficient application than applying the arguments successively. + /// /// The input function. /// The first arg. /// The second arg. /// The third arg. + /// /// The function result. static member InvokeFast : func: FSharpFunc<'T,('U -> 'V -> 'W)> * arg1:'T * arg2:'U * arg3:'V -> 'W /// Invoke an F# first class function value with two curried arguments. In some cases this /// will result in a more efficient application than applying the arguments successively. + /// /// The input function. /// The first arg. /// The second arg. + /// /// The function result. static member InvokeFast : func: FSharpFunc<'T,('U -> 'V)> * arg1:'T * arg2:'U -> 'V @@ -1551,100 +2090,138 @@ namespace Microsoft.FSharp.Core [] /// Helper functions for converting F# first class function values to and from CLI representations /// of functions using delegates. + /// Language Primitives type FuncConvert = /// Convert the given Action delegate object to an F# function value + /// /// The input Action delegate. + /// /// The F# function. static member inline ToFSharpFunc : action:Action<'T> -> ('T -> unit) /// Convert the given Converter delegate object to an F# function value + /// /// The input Converter delegate. + /// /// The F# function. static member inline ToFSharpFunc : converter:Converter<'T,'U> -> ('T -> 'U) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F# function. static member inline FromAction : action:Action -> (unit -> unit) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F# function. static member inline FromAction : action:Action<'T> -> ('T -> unit) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F#funcfunction. static member inline FromAction : action:Action<'T1,'T2> -> ('T1 -> 'T2 -> unit) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F# function. static member inline FromAction : action:Action<'T1,'T2,'T3> -> ('T1 -> 'T2 -> 'T3 -> unit) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F# function. static member inline FromAction : action:Action<'T1,'T2,'T3,'T4> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> unit) /// Convert the given Action delegate object to an F# function value - /// The input Action delegate. + /// + /// The input Action delegate. + /// /// The F# function. static member inline FromAction : action:Action<'T1,'T2,'T3,'T4,'T5> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> unit) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F# function. static member inline FromFunc : func:Func<'T> -> (unit -> 'T) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F# function. static member inline FromFunc : func:Func<'T,'U> -> ('T -> 'U) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F#funcfunction. static member inline FromFunc : func:Func<'T1,'T2,'U> -> ('T1 -> 'T2 -> 'U) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F# function. static member inline FromFunc : func:Func<'T1,'T2,'T3,'U> -> ('T1 -> 'T2 -> 'T3 -> 'U) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F# function. static member inline FromFunc : func:Func<'T1,'T2,'T3,'T4,'U> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'U) /// Convert the given Func delegate object to an F# function value + /// /// The input Func delegate. + /// /// The F# function. static member inline FromFunc : func:Func<'T1,'T2,'T3,'T4,'T5,'U> -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'U) /// A utility function to convert function values from tupled to curried form + /// /// The input tupled function. + /// /// The output curried function. static member inline FuncFromTupled : func:('T1 * 'T2 -> 'U) -> ('T1 -> 'T2 -> 'U) /// A utility function to convert function values from tupled to curried form + /// /// The input tupled function. + /// /// The output curried function. static member inline FuncFromTupled : func:('T1 * 'T2 * 'T3 -> 'U) -> ('T1 -> 'T2 -> 'T3 -> 'U) /// A utility function to convert function values from tupled to curried form + /// /// The input tupled function. + /// /// The output curried function. static member inline FuncFromTupled : func:('T1 * 'T2 * 'T3 * 'T4 -> 'U) -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'U) /// A utility function to convert function values from tupled to curried form + /// /// The input tupled function. + /// /// The output curried function. static member inline FuncFromTupled : func:('T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'U) -> ('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'U) /// An implementation module used to hold some private implementations of function /// value invocation. + /// Language Primitives module OptimizedClosures = /// The CLI type used to represent F# function values that accept @@ -1655,14 +2232,18 @@ namespace Microsoft.FSharp.Core inherit FSharpFunc<'T1,('T2 -> 'U)> /// Invoke the optimized function value with two curried arguments + /// /// The first arg. /// The second arg. + /// /// The function result. - abstract member Invoke : arg1:'T1 * arg2:'T2 -> 'U + abstract Invoke : arg1:'T1 * arg2:'T2 -> 'U /// Adapt an F# first class function value to be an optimized function value that can /// accept two curried arguments without intervening execution. + /// /// The input function. + /// /// The adapted function. static member Adapt : func:('T1 -> 'T2 -> 'U) -> FSharpFunc<'T1,'T2,'U> @@ -1681,15 +2262,19 @@ namespace Microsoft.FSharp.Core /// Invoke an F# first class function value that accepts three curried arguments /// without intervening execution + /// /// The first arg. /// The second arg. /// The third arg. + /// /// The function result. - abstract member Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 -> 'U + abstract Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 -> 'U /// Adapt an F# first class function value to be an optimized function value that can /// accept three curried arguments without intervening execution. + /// /// The input function. + /// /// The adapted function. static member Adapt : func:('T1 -> 'T2 -> 'T3 -> 'U) -> FSharpFunc<'T1,'T2,'T3,'U> @@ -1707,16 +2292,20 @@ namespace Microsoft.FSharp.Core /// Invoke an F# first class function value that accepts four curried arguments /// without intervening execution + /// /// The first arg. /// The second arg. /// The third arg. /// The fourth arg. + /// /// The function result. - abstract member Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 * arg4:'T4 -> 'U + abstract Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 * arg4:'T4 -> 'U /// Adapt an F# first class function value to be an optimized function value that can /// accept four curried arguments without intervening execution. + /// /// The input function. + /// /// The optimized function. static member Adapt : func:('T1 -> 'T2 -> 'T3 -> 'T4 -> 'U) -> FSharpFunc<'T1,'T2,'T3,'T4,'U> @@ -1734,17 +2323,21 @@ namespace Microsoft.FSharp.Core /// Invoke an F# first class function value that accepts five curried arguments /// without intervening execution + /// /// The first arg. /// The second arg. /// The third arg. /// The fourth arg. /// The fifth arg. + /// /// The function result. - abstract member Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 * arg4:'T4 * arg5:'T5 -> 'U + abstract Invoke : arg1:'T1 * arg2:'T2 * arg3:'T3 * arg4:'T4 * arg5:'T5 -> 'U /// Adapt an F# first class function value to be an optimized function value that can /// accept five curried arguments without intervening execution. + /// /// The input function. + /// /// The optimized function. static member Adapt : func:('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'U) -> FSharpFunc<'T1,'T2,'T3,'T4,'T5,'U> @@ -1755,6 +2348,9 @@ namespace Microsoft.FSharp.Core /// The type of mutable references. Use the functions [!] and [:=] to get and /// set values of this type. + /// + /// Basic Types + /// [] [] type Ref<'T> = @@ -1766,6 +2362,7 @@ namespace Microsoft.FSharp.Core /// The type of mutable references. Use the functions [!] and [:=] to get and /// set values of this type. + /// Basic Types and 'T ref = Ref<'T> /// The type of optional values. When used from other CLI languages the @@ -1778,6 +2375,9 @@ namespace Microsoft.FSharp.Core /// None values will appear as the value null to other CLI languages. /// Instance methods on this type will appear as static methods to other CLI languages /// due to the use of null as a value representation. + /// + /// Options + /// [] [] [] @@ -1788,21 +2388,32 @@ namespace Microsoft.FSharp.Core | None : 'T option /// The representation of "Value of type 'T" + /// /// The input value. + /// /// An option representing the value. | Some : Value:'T -> 'T option /// Create an option value that is a 'None' value. + /// static member None : 'T option /// Create an option value that is a 'Some' value. + /// /// The input value + /// /// An option representing the value. + /// static member Some : value:'T -> 'T option /// Implicitly converts a value into an optional that is a 'Some' value. + /// /// The input value + /// + /// The F# compiler ignored this method when determining possible type-directed conversions. Instead, use Some or None explicitly. + /// /// An option representing the value. + /// static member op_Implicit : value:'T -> 'T option [] @@ -1825,6 +2436,8 @@ namespace Microsoft.FSharp.Core /// 'None' values will appear as the value null to other CLI languages. /// Instance methods on this type will appear as static methods to other CLI languages /// due to the use of null as a value representation. + /// + /// Options and 'T option = Option<'T> /// The type of optional values, represented as structs. @@ -1832,6 +2445,9 @@ namespace Microsoft.FSharp.Core /// Use the constructors ValueSome and ValueNone to create values of this type. /// Use the values in the ValueOption module to manipulate values of this type, /// or pattern match against the values directly. + /// + /// Options + /// [] [] [] @@ -1840,7 +2456,9 @@ namespace Microsoft.FSharp.Core | ValueNone: 'T voption /// The representation of "Value of type 'T" - /// The input value. + /// + /// The input value. + /// /// An option representing the value. | ValueSome: 'T -> 'T voption @@ -1848,11 +2466,15 @@ namespace Microsoft.FSharp.Core member Value : 'T /// Create a value option value that is a 'ValueNone' value. + /// static member None : 'T voption /// Create a value option value that is a 'Some' value. + /// /// The input value + /// /// A value option representing the value. + /// static member Some : value:'T -> 'T voption /// Return 'true' if the value option is a 'ValueSome' value. @@ -1862,8 +2484,13 @@ namespace Microsoft.FSharp.Core member IsNone : bool /// Implicitly converts a value into an optional that is a 'ValueSome' value. + /// /// The input value + /// + /// The F# compiler ignored this method when determining possible type-directed conversions. Instead, use Some or None explicitly. + /// /// A voption representing the value. + /// static member op_Implicit: value: 'T -> 'T voption /// The type of optional values, represented as structs. @@ -1871,9 +2498,13 @@ namespace Microsoft.FSharp.Core /// Use the constructors ValueSome and ValueNone to create values of this type. /// Use the values in the ValueOption module to manipulate values of this type, /// or pattern match against the values directly. + /// + /// Options and 'T voption = ValueOption<'T> /// Helper type for error handling without exceptions. + /// + /// Choices and Results [] [] [] @@ -1896,7 +2527,10 @@ namespace Microsoft.FSharp.Collections /// /// Use the constructors [] and :: (infix) to create values of this type, or /// the notation [1;2;3]. Use the values in the List module to manipulate - /// values of this type, or pattern match against the values directly. + /// values of this type, or pattern match against the values directly. + /// + /// + /// [] [] [] @@ -1922,25 +2556,32 @@ namespace Microsoft.FSharp.Collections /// Gets the element of the list at the given position. /// Lists are represented as linked lists so this is an O(n) operation. /// The index. + /// /// The value at the given index. member Item : index:int -> 'T with get /// Gets a slice of the list, the elements of the list from the given start index to the given end index. + /// /// The start index. /// The end index. + /// /// The sub list specified by the input indices. member GetSlice : startIndex:int option * endIndex:int option -> 'T list /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int /// Returns a list with head as its first element and tail as its subsequent elements + /// /// A new head value for the list. /// The existing list. + /// /// The list with head appended to the front of tail. static member Cons : head:'T * tail:'T list -> 'T list @@ -1949,17 +2590,28 @@ namespace Microsoft.FSharp.Collections interface IReadOnlyCollection<'T> interface IReadOnlyList<'T> - /// An abbreviation for the type of immutable singly-linked lists. + /// The type of immutable singly-linked lists. /// - /// Use the constructors [] and :: (infix) to create values of this type, or - /// the notation [1;2;3]. Use the values in the List module to manipulate - /// values of this type, or pattern match against the values directly. + /// See the module for further operations related to lists. + /// + /// Use the constructors [] and :: (infix) to create values of this type, or + /// the notation [1; 2; 3]. Use the values in the List module to manipulate + /// values of this type, or pattern match against the values directly. + /// + /// See also F# Language Guide - Lists. + /// and 'T list = List<'T> - /// An abbreviation for the CLI type System.Collections.Generic.List<_> + /// An abbreviation for the CLI type type ResizeArray<'T> = System.Collections.Generic.List<'T> - /// An abbreviation for the CLI type System.Collections.Generic.IEnumerable<_> + /// An abbreviation for the CLI type + /// + /// + /// See the module for further operations related to sequences. + /// + /// See also F# Language Guide - Sequences. + /// type seq<'T> = IEnumerable<'T> namespace Microsoft.FSharp.Core @@ -1970,184 +2622,244 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Collections /// Basic F# Operators. This module is automatically opened in all F# code. + /// + /// Basic Operators [] module Operators = /// Overloaded unary negation. + /// /// The value to negate. + /// /// The result of the operation. val inline ( ~- ) : n:^T -> ^T when ^T : (static member ( ~- ) : ^T -> ^T) and default ^T : int /// Overloaded addition operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline ( + ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded subtraction operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline ( - ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded multiplication operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline ( * ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded division operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline ( / ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( / ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded modulo operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline ( % ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( % ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded bitwise-AND operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline (&&&): x:^T -> y:^T -> ^T when ^T : (static member (&&&) : ^T * ^T -> ^T) and default ^T : int /// Overloaded bitwise-OR operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline (|||) : x:^T -> y:^T -> ^T when ^T : (static member (|||) : ^T * ^T -> ^T) and default ^T : int /// Overloaded bitwise-XOR operator + /// /// The first parameter. /// The second parameter. + /// /// The result of the operation. val inline (^^^) : x:^T -> y:^T -> ^T when ^T : (static member (^^^) : ^T * ^T -> ^T) and default ^T : int /// Overloaded byte-shift left operator by a specified number of bits + /// /// The input value. /// The amount to shift. + /// /// The result of the operation. val inline (<<<) : value:^T -> shift:int32 -> ^T when ^T : (static member (<<<) : ^T * int32 -> ^T) and default ^T : int /// Overloaded byte-shift right operator by a specified number of bits + /// /// The input value. /// The amount to shift. + /// /// The result of the operation. val inline (>>>) : value:^T -> shift:int32 -> ^T when ^T : (static member (>>>) : ^T * int32 -> ^T) and default ^T : int /// Overloaded bitwise-NOT operator + /// /// The input value. + /// /// The result of the operation. val inline (~~~) : value:^T -> ^T when ^T : (static member (~~~) : ^T -> ^T) and default ^T : int /// Overloaded prefix-plus operator + /// /// The input value. + /// /// The result of the operation. val inline (~+) : value:^T -> ^T when ^T : (static member (~+) : ^T -> ^T) and default ^T : int /// Structural less-than comparison + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( < ) : x:'T -> y:'T -> bool when 'T : comparison /// Structural greater-than + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( > ) : x:'T -> y:'T -> bool when 'T : comparison /// Structural greater-than-or-equal + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( >= ) : x:'T -> y:'T -> bool when 'T : comparison /// Structural less-than-or-equal comparison + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( <= ) : x:'T -> y:'T -> bool when 'T : comparison /// Structural equality + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( = ) : x:'T -> y:'T -> bool when 'T : equality /// Structural inequality + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( <> ) : x:'T -> y:'T -> bool when 'T : equality /// Compose two functions, the function on the left being applied first + /// /// The first function to apply. /// The second function to apply. + /// /// The composition of the input functions. val inline (>>): func1:('T1 -> 'T2) -> func2:('T2 -> 'T3) -> ('T1 -> 'T3) /// Compose two functions, the function on the right being applied first + /// /// The second function to apply. /// The first function to apply. + /// /// The composition of the input functions. val inline (<<): func2:('T2 -> 'T3) -> func1:('T1 -> 'T2) -> ('T1 -> 'T3) /// Apply a function to a value, the value being on the left, the function on the right + /// /// The argument. /// The function. + /// /// The function result. val inline (|>): arg:'T1 -> func:('T1 -> 'U) -> 'U /// Apply a function to two values, the values being a pair on the left, the function on the right + /// /// The first argument. /// The second argument. /// The function. + /// /// The function result. val inline (||>): arg1:'T1 * arg2:'T2 -> func:('T1 -> 'T2 -> 'U) -> 'U /// Apply a function to three values, the values being a triple on the left, the function on the right + /// /// The first argument. /// The second argument. /// The third argument. /// The function. + /// /// The function result. val inline (|||>): arg1:'T1 * arg2:'T2 * arg3:'T3 -> func:('T1 -> 'T2 -> 'T3 -> 'U) -> 'U /// Apply a function to a value, the value being on the right, the function on the left + /// /// The function. /// The argument. + /// /// The function result. val inline (<|): func:('T -> 'U) -> arg1:'T -> 'U /// Apply a function to two values, the values being a pair on the right, the function on the left + /// /// The function. /// The first argument. /// The second argument. + /// /// The function result. val inline (<||): func:('T1 -> 'T2 -> 'U) -> arg1:'T1 * arg2:'T2 -> 'U /// Apply a function to three values, the values being a triple on the right, the function on the left + /// /// The function. /// The first argument. /// The second argument. /// The third argument. + /// /// The function result. val inline (<|||): func:('T1 -> 'T2 -> 'T3 -> 'U) -> arg1:'T1 * arg2:'T2 * arg3:'T3 -> 'U /// Used to specify a default value for an optional argument in the implementation of a function + /// /// An option representing the argument. /// The default value of the argument. + /// /// The argument value. If it is None, the defaultValue is returned. [] val defaultArg : arg:'T option -> defaultValue:'T -> 'T /// Used to specify a default value for an optional argument in the implementation of a function + /// /// A value option representing the argument. /// The default value of the argument. + /// /// The argument value. If it is None, the defaultValue is returned. [] val defaultValueArg : arg:'T voption -> defaultValue:'T -> 'T @@ -2157,217 +2869,269 @@ namespace Microsoft.FSharp.Core val (^): s1:string -> s2:string -> string /// Raises an exception + /// /// The exception to raise. + /// /// The result value. [] val inline raise : exn:System.Exception -> 'T /// Rethrows an exception. This should only be used when handling an exception /// The result value. - [] [] [] val inline rethrow : unit -> 'T /// Rethrows an exception. This should only be used when handling an exception /// The result value. - [] [] val inline reraise : unit -> 'T - /// Builds a System.Exception object. + /// Builds a object. + /// /// The message for the Exception. + /// /// A System.Exception. val Failure : message:string -> exn - /// Matches System.Exception objects whose runtime type is precisely System.Exception + /// Matches objects whose runtime type is precisely + /// /// The input exception. + /// /// A string option. [] val (|Failure|_|) : error:exn -> string option /// Return the first element of a tuple, fst (a,b) = a. + /// /// The input tuple. + /// /// The first value. [] val inline fst : tuple:('T1 * 'T2) -> 'T1 /// Return the second element of a tuple, snd (a,b) = b. + /// /// The input tuple. + /// /// The second value. [] val inline snd : tuple:('T1 * 'T2) -> 'T2 /// Generic comparison. + /// /// The first value. /// The second value. + /// /// The result of the comparison. [] val inline compare: e1:'T -> e2:'T -> int when 'T : comparison /// Maximum based on generic comparison + /// /// The first value. /// The second value. + /// /// The maximum value. [] val inline max : e1:'T -> e2:'T -> 'T when 'T : comparison /// Minimum based on generic comparison + /// /// The first value. /// The second value. + /// /// The minimum value. [] val inline min : e1:'T -> e2:'T -> 'T when 'T : comparison /// Ignore the passed value. This is often used to throw away results of a computation. + /// /// The value to ignore. [] val inline ignore : value:'T -> unit /// Unbox a strongly typed value. + /// /// The boxed value. + /// /// The unboxed result. [] val inline unbox : value:obj -> 'T /// Boxes a strongly typed value. + /// /// The value to box. + /// /// The boxed object. [] val inline box : value:'T -> obj /// Try to unbox a strongly typed value. + /// /// The boxed value. + /// /// The unboxed result as an option. [] val inline tryUnbox : value:obj -> 'T option /// Determines whether the given value is null. + /// /// The value to check. + /// /// True when value is null, false otherwise. [] val inline isNull : value:'T -> bool when 'T : null /// Determines whether the given value is not null. + /// /// The value to check. + /// /// True when value is not null, false otherwise. [] val inline internal isNotNull : value:'T -> bool when 'T : null - /// Throw a System.Exception exception. + /// Throw a exception. + /// /// The exception message. + /// /// The result value. [] val inline failwith : message:string -> 'T - /// Throw a System.ArgumentException exception with + /// Throw a exception with /// the given argument name and message. + /// /// The argument name. /// The exception message. + /// /// The result value. [] val inline invalidArg : argumentName:string -> message:string -> 'T - /// Throw a System.ArgumentNullException exception + /// Throw a exception + /// /// The argument name. + /// /// The result value. [] val inline nullArg : argumentName:string -> 'T - /// Throw a System.InvalidOperationException exception + /// Throw a exception + /// /// The exception message. + /// /// The result value. [] val inline invalidOp : message:string -> 'T /// The identity function + /// /// The input value. + /// /// The same value. [] val id : x:'T -> 'T /// Create a mutable reference cell + /// /// The value to contain in the cell. + /// /// The created reference cell. [] val ref : value:'T -> 'T ref /// Assign to a mutable reference cell + /// /// The cell to mutate. /// The value to set inside the cell. val ( := ) : cell:'T ref -> value:'T -> unit /// Dereference a mutable reference cell + /// /// The cell to dereference. + /// /// The value contained in the cell. val ( ! ) : cell:'T ref -> 'T /// Decrement a mutable reference cell containing an integer + /// /// The reference cell. [] val decr: cell:int ref -> unit /// Increment a mutable reference cell containing an integer + /// /// The reference cell. [] val incr: cell:int ref -> unit /// Concatenate two lists. + /// /// The first list. /// The second list. + /// /// The concatenation of the lists. val (@): list1:'T list -> list2:'T list -> 'T list /// Negate a logical value. Not True equals False and not False equals True + /// /// The value to negate. + /// /// The result of the negation. [] val inline not : value:bool -> bool /// Builds a sequence using sequence expression syntax + /// /// The input sequence. + /// /// The result sequence. [] val seq : sequence:seq<'T> -> seq<'T> /// Exit the current hardware isolated process, if security settings permit, - /// otherwise raise an exception. Calls System.Environment.Exit. + /// otherwise raise an exception. Calls . + /// /// The exit code to use. + /// /// The result value. [] val exit: exitcode:int -> 'T when default 'T : obj - /// Equivalent to System.Double.PositiveInfinity + /// Equivalent to [] val infinity: float - /// Equivalent to System.Double.NaN + /// Equivalent to [] val nan: float - /// Equivalent to System.Single.PositiveInfinity + /// Equivalent to [] val infinityf: float32 - /// Equivalent to System.Single.NaN + /// Equivalent to [] val nanf: float32 - /// Reads the value of the property System.Console.In. + /// Reads the value of the property . [] val stdin<'T> : System.IO.TextReader - /// Reads the value of the property System.Console.Error. + /// Reads the value of the property . [] val stderr<'T> : System.IO.TextWriter - /// Reads the value of the property System.Console.Out. + /// Reads the value of the property . [] val stdout<'T> : System.IO.TextWriter /// The standard overloaded range operator, e.g. [n..m] for lists, seq {n..m} for sequences + /// /// The start value of the range. /// The end value of the range. + /// /// The sequence spanning the range. val inline (..) : start:^T -> finish:^T -> seq< ^T > when ^T : (static member (+) : ^T * ^T -> ^T) @@ -2377,9 +3141,11 @@ namespace Microsoft.FSharp.Core and default ^T : int /// The standard overloaded skip range operator, e.g. [n..skip..m] for lists, seq {n..skip..m} for sequences + /// /// The start value of the range. /// The step value of the range. /// The end value of the range. + /// /// The sequence spanning the range using the specified step size. val inline (.. ..) : start:^T -> step:^Step -> finish:^T -> seq< ^T > when (^T or ^Step) : (static member (+) : ^T * ^Step -> ^T) @@ -2390,8 +3156,10 @@ namespace Microsoft.FSharp.Core and default ^T : int /// Execute the function as a mutual-exclusion region using the input value as a lock. + /// /// The object to be locked. /// The action to perform during the lock. + /// /// The resulting value. [] val inline lock: lockObject:'Lock -> action:(unit -> 'T) -> 'T when 'Lock : not struct @@ -2399,8 +3167,10 @@ namespace Microsoft.FSharp.Core /// Clean up resources associated with the input object after the completion of the given function. /// Cleanup occurs even when an exception is raised by the protected /// code. + /// /// The resource to be disposed after action is called. /// The action that accepts the resource. + /// /// The resulting value. [] val using: resource:('T :> System.IDisposable) -> action:('T -> 'U) -> 'U @@ -2412,7 +3182,7 @@ namespace Microsoft.FSharp.Core val inline typeof<'T> : System.Type /// Returns the name of the given symbol. - [] + [] val inline nameof : 'T -> string /// An internal, library-only compiler intrinsic for compile-time @@ -2441,7 +3211,9 @@ namespace Microsoft.FSharp.Core /// for F# union, record and tuple types, hashing the complete contents of the /// type. The exact behaviour of the function can be adjusted on a /// type-by-type basis by implementing GetHashCode for each type. + /// /// The input object. + /// /// The computed hash. [] val inline hash: obj:'T -> int when 'T : equality @@ -2451,142 +3223,188 @@ namespace Microsoft.FSharp.Core /// types stops when the given limit of nodes is reached. The exact behaviour of /// the function can be adjusted on a type-by-type basis by implementing /// GetHashCode for each type. + /// /// The limit of nodes. /// The input object. + /// /// The computed hash. val inline limitedHash: limit: int -> obj:'T -> int when 'T : equality /// Absolute value of the given number. + /// /// The input value. + /// /// The absolute value of the input. [] val inline abs : value:^T -> ^T when ^T : (static member Abs : ^T -> ^T) and default ^T : int /// Inverse cosine of the given number + /// /// The input value. + /// /// The inverse cosine of the input. [] val inline acos : value:^T -> ^T when ^T : (static member Acos : ^T -> ^T) and default ^T : float /// Inverse sine of the given number + /// /// The input value. + /// /// The inverse sine of the input. [] val inline asin : value:^T -> ^T when ^T : (static member Asin : ^T -> ^T) and default ^T : float /// Inverse tangent of the given number + /// /// The input value. + /// /// The inverse tangent of the input. [] val inline atan : value:^T -> ^T when ^T : (static member Atan : ^T -> ^T) and default ^T : float /// Inverse tangent of x/y where x and y are specified separately + /// /// The y input value. /// The x input value. + /// /// The inverse tangent of the input ratio. [] val inline atan2 : y:^T1 -> x:^T1 -> 'T2 when ^T1 : (static member Atan2 : ^T1 * ^T1 -> 'T2) and default ^T1 : float /// Ceiling of the given number + /// /// The input value. + /// /// The ceiling of the input. [] val inline ceil : value:^T -> ^T when ^T : (static member Ceiling : ^T -> ^T) and default ^T : float /// Exponential of the given number + /// /// The input value. + /// /// The exponential of the input. [] val inline exp : value:^T -> ^T when ^T : (static member Exp : ^T -> ^T) and default ^T : float /// Floor of the given number + /// /// The input value. + /// /// The floor of the input. [] val inline floor : value:^T -> ^T when ^T : (static member Floor : ^T -> ^T) and default ^T : float /// Sign of the given number + /// /// The input value. + /// /// -1, 0, or 1 depending on the sign of the input. [] val inline sign : value:^T -> int when ^T : (member Sign : int) and default ^T : float /// Round the given number + /// /// The input value. + /// /// The nearest integer to the input value. [] val inline round : value:^T -> ^T when ^T : (static member Round : ^T -> ^T) and default ^T : float /// Natural logarithm of the given number + /// /// The input value. + /// /// The natural logarithm of the input. [] val inline log : value:^T -> ^T when ^T : (static member Log : ^T -> ^T) and default ^T : float /// Logarithm to base 10 of the given number + /// /// The input value. + /// /// The logarithm to base 10 of the input. [] val inline log10 : value:^T -> ^T when ^T : (static member Log10 : ^T -> ^T) and default ^T : float /// Square root of the given number + /// /// The input value. + /// /// The square root of the input. [] val inline sqrt : value:^T -> ^U when ^T : (static member Sqrt : ^T -> ^U) and default ^U : ^T and default ^T : ^U and default ^T : float /// Cosine of the given number + /// /// The input value. + /// /// The cosine of the input. [] val inline cos : value:^T -> ^T when ^T : (static member Cos : ^T -> ^T) and default ^T : float /// Hyperbolic cosine of the given number + /// /// The input value. + /// /// The hyperbolic cosine of the input. [] val inline cosh : value:^T -> ^T when ^T : (static member Cosh : ^T -> ^T) and default ^T : float /// Sine of the given number + /// /// The input value. + /// /// The sine of the input. [] val inline sin : value:^T -> ^T when ^T : (static member Sin : ^T -> ^T) and default ^T : float /// Hyperbolic sine of the given number + /// /// The input value. + /// /// The hyperbolic sine of the input. [] val inline sinh : value:^T -> ^T when ^T : (static member Sinh : ^T -> ^T) and default ^T : float /// Tangent of the given number + /// /// The input value. + /// /// The tangent of the input. [] val inline tan : value:^T -> ^T when ^T : (static member Tan : ^T -> ^T) and default ^T : float /// Hyperbolic tangent of the given number + /// /// The input value. + /// /// The hyperbolic tangent of the input. [] val inline tanh : value:^T -> ^T when ^T : (static member Tanh : ^T -> ^T) and default ^T : float /// Overloaded truncate operator. + /// /// The input value. + /// /// The truncated value. [] val inline truncate : value:^T -> ^T when ^T : (static member Truncate : ^T -> ^T) and default ^T : float /// Overloaded power operator. + /// /// The input base. /// The input exponent. + /// /// The base raised to the exponent. val inline ( ** ) : x:^T -> y:^U -> ^T when ^T : (static member Pow : ^T * ^U -> ^T) and default ^U : float and default ^T : float /// Overloaded power operator. If n > 0 then equivalent to x*...*x for n occurrences of x. + /// /// The input base. /// The input exponent. + /// /// The base raised to the exponent. [] val inline pown : x:^T -> n:int -> ^T when ^T : (static member One : ^T) @@ -2598,7 +3416,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Byte.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted byte [] val inline byte : value:^T -> byte when ^T : (static member op_Explicit : ^T -> byte) and default ^T : int @@ -2607,7 +3427,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using SByte.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted sbyte [] val inline sbyte : value:^T -> sbyte when ^T : (static member op_Explicit : ^T -> sbyte) and default ^T : int @@ -2616,7 +3438,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Int16.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int16 [] val inline int16 : value:^T -> int16 when ^T : (static member op_Explicit : ^T -> int16) and default ^T : int @@ -2625,7 +3449,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using UInt16.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint16 [] val inline uint16 : value:^T -> uint16 when ^T : (static member op_Explicit : ^T -> uint16) and default ^T : int @@ -2634,13 +3460,28 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Int32.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int [] val inline int : value:^T -> int when ^T : (static member op_Explicit : ^T -> int) and default ^T : int + /// Converts the argument to an unsigned 32-bit integer. This is a direct conversion for all + /// primitive numeric types. For strings, the input is converted using UInt32.Parse() + /// with InvariantCulture settings. Otherwise the operation requires an appropriate + /// static conversion method on the input type. + /// + /// The input value. + /// + /// The converted int + [] + val inline uint: value:^T -> uint when ^T: (static member op_Explicit: ^T -> uint) and default ^T: uint + /// Converts the argument to a particular enum type. + /// /// The input value. + /// /// The converted enum type. [] val inline enum : value:int32 -> ^U when ^U : enum @@ -2649,7 +3490,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Int32.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int32 [] val inline int32 : value:^T -> int32 when ^T : (static member op_Explicit : ^T -> int32) and default ^T : int @@ -2658,7 +3501,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using UInt32.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint32 [] val inline uint32 : value:^T -> uint32 when ^T : (static member op_Explicit : ^T -> uint32) and default ^T : int @@ -2667,7 +3512,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Int64.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int64 [] val inline int64 : value:^T -> int64 when ^T : (static member op_Explicit : ^T -> int64) and default ^T : int @@ -2676,7 +3523,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using UInt64.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint64 [] val inline uint64 : value:^T -> uint64 when ^T : (static member op_Explicit : ^T -> uint64) and default ^T : int @@ -2685,7 +3534,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Single.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted float32 [] val inline float32 : value:^T -> float32 when ^T : (static member op_Explicit : ^T -> float32) and default ^T : int @@ -2694,7 +3545,9 @@ namespace Microsoft.FSharp.Core /// primitive numeric types. For strings, the input is converted using Double.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted float [] val inline float : value:^T -> float when ^T : (static member op_Explicit : ^T -> float) and default ^T : int @@ -2702,7 +3555,9 @@ namespace Microsoft.FSharp.Core /// Converts the argument to signed native integer. This is a direct conversion for all /// primitive numeric types. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted nativeint [] val inline nativeint : value:^T -> nativeint when ^T : (static member op_Explicit : ^T -> nativeint) and default ^T : int @@ -2710,25 +3565,30 @@ namespace Microsoft.FSharp.Core /// Converts the argument to unsigned native integer using a direct conversion for all /// primitive numeric types. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted unativeint [] val inline unativeint : value:^T -> unativeint when ^T : (static member op_Explicit : ^T -> unativeint) and default ^T : int /// Converts the argument to a string using ToString. /// - /// For standard integer and floating point values the ToString conversion - /// uses CultureInfo.InvariantCulture. + /// For standard integer and floating point values the and any type that implements IFormattable + /// ToString conversion uses CultureInfo.InvariantCulture. /// The input value. + /// /// The converted string. [] - val inline string : value:^T -> string + val inline string : value:'T -> string /// Converts the argument to System.Decimal using a direct conversion for all /// primitive numeric types. For strings, the input is converted using UInt64.Parse() /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted decimal. [] val inline decimal : value:^T -> decimal when ^T : (static member op_Explicit : ^T -> decimal) and default ^T : int @@ -2736,56 +3596,72 @@ namespace Microsoft.FSharp.Core /// Converts the argument to character. Numeric inputs are converted according to the UTF-16 /// encoding for characters. String inputs must be exactly one character long. For other /// input types the operation requires an appropriate static conversion method on the input type. + /// /// The input value. + /// /// The converted char. [] val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int - /// An active pattern to match values of type System.Collections.Generic.KeyValuePair + /// An active pattern to match values of type + /// /// The input key/value pair. + /// /// A tuple containing the key and value. [] val ( |KeyValue| ): keyValuePair:KeyValuePair<'Key,'Value> -> 'Key * 'Value [] [] + /// Contains extension methods to allow the use of F# indexer notation with arrays. + /// This module is automatically opened in all F# code. module ArrayExtensions = type ``[,,,]``<'T> with /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. This refers to the dimension in the 4d array. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int type ``[,,]``<'T> with /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. This refers to the dimension in the 3d array. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int type ``[,]``<'T> with /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. This refers to the dimension in the 2d array. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int type ``[]``<'T> with /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int type System.String with /// Get the index for the element offset elements away from the end of the collection. + /// /// The rank of the index. /// The offset from the end. + /// /// The corresponding index from the start. [] member GetReverseIndex: rank: int * offset: int -> int @@ -2796,13 +3672,16 @@ namespace Microsoft.FSharp.Core module OperatorIntrinsics = /// Gets a slice of an array + /// /// The input array. /// The start index. /// The end index. + /// /// The sub array from the input indices. val inline GetArraySlice : source:'T[] -> start:int option -> finish:int option -> 'T[] /// Sets a slice of an array + /// /// The target array. /// The start index. /// The end index. @@ -2810,31 +3689,38 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice : target:'T[] -> start:int option -> finish:int option -> source:'T[] -> unit /// Gets a region slice of an array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. + /// /// The two dimensional sub array from the input indices. val inline GetArraySlice2D : source:'T[,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> 'T[,] /// Gets a vector slice of a 2D array. The index of the first dimension is fixed. + /// /// The source array. /// The index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. + /// /// The sub array from the input indices. val inline GetArraySlice2DFixed1 : source:'T[,] -> index1:int -> start2:int option -> finish2:int option -> 'T[] /// Gets a vector slice of a 2D array. The index of the second dimension is fixed. + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The fixed index of the second dimension. + /// /// The sub array from the input indices. val inline GetArraySlice2DFixed2 : source:'T[,] -> start1:int option -> finish1:int option -> index2: int -> 'T[] /// Sets a region slice of an array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2844,6 +3730,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice2D : target:'T[,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> source:'T[,] -> unit /// Sets a vector slice of a 2D array. The index of the first dimension is fixed. + /// /// The target array. /// The index of the first dimension. /// The start index of the second dimension. @@ -2852,6 +3739,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice2DFixed1 : target:'T[,] -> index1:int -> start2:int option -> finish2:int option -> source:'T[] -> unit /// Sets a vector slice of a 2D array. The index of the second dimension is fixed. + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2860,6 +3748,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice2DFixed2 : target:'T[,] -> start1:int option -> finish1:int option -> index2:int -> source:'T[] -> unit /// Gets a slice of an array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2867,73 +3756,87 @@ namespace Microsoft.FSharp.Core /// The end index of the second dimension. /// The start index of the third dimension. /// The end index of the third dimension. + /// /// The three dimensional sub array from the given indices. val inline GetArraySlice3D : source:'T[,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> start3:int option -> finish3:int option -> 'T[,,] /// Gets a 2D slice of a 3D array. + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. /// The start index of the third dimension. /// The end index of the third dimension. + /// /// The two dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedSingle1 : source:'T[,,] -> index1:int -> start2:int option -> finish2:int option -> start3:int option -> finish3:int option -> 'T[,] /// Gets a 2D slice of a 3D array. + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The fixed index of the second dimension. /// The start index of the third dimension. /// The end index of the third dimension. + /// /// The two dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedSingle2 : source:'T[,,] -> start1:int option -> finish1:int option -> index2: int -> start3:int option -> finish3:int option -> 'T[,] /// Gets a 2D slice of a 3D array. + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. /// The fixed index of the third dimension. + /// /// The two dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedSingle3 : source:'T[,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> index3: int -> 'T[,] /// Gets a 1D slice of a 3D array. + /// /// The source array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. /// The start index of the third dimension. /// The end index of the third dimension. + /// /// The one dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedDouble1 : source:'T[,,] -> index1:int -> index2:int -> start3:int option -> finish3:int option -> 'T[] /// Gets a 1D slice of a 3D array. + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. /// The fixed index of the third dimension. + /// /// The one dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedDouble2 : source:'T[,,] -> index1:int -> start2:int option -> finish2:int option -> index3:int -> 'T[] /// Gets a 1D slice of a 3D array. + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The fixed index of the second dimension. /// The fixed index of the third dimension. + /// /// The one dimensional sub array from the given indices. [] val inline GetArraySlice3DFixedDouble3 : source:'T[,,] -> start1:int option -> finish1:int option -> index2:int -> index3:int -> 'T[] /// Sets a slice of an array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2945,6 +3848,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice3D : target:'T[,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> start3:int option -> finish3:int option -> source:'T[,,] -> unit /// Sets a 2D slice of a 3D array + /// /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -2952,11 +3856,13 @@ namespace Microsoft.FSharp.Core /// The start index of the third dimension. /// The end index of the third dimension. /// The source array. + /// /// The two dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedSingle1 : target: 'T[,,] -> index1: int -> start2: int option -> finish2: int option -> start3: int option -> finish3: int option -> source: 'T[,] -> unit /// Sets a 2D slice of a 3D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2964,11 +3870,13 @@ namespace Microsoft.FSharp.Core /// The start index of the third dimension. /// The end index of the third dimension. /// The source array. + /// /// The two dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedSingle2 : target: 'T[,,] -> start1: int option -> finish1: int option -> index2: int -> start3: int option -> finish3: int option -> source: 'T[,] -> unit /// Sets a 2D slice of a 3D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -2976,44 +3884,52 @@ namespace Microsoft.FSharp.Core /// The end index of the second dimension. /// The fixed index of the third dimension. /// The source array. + /// /// The two dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedSingle3 : target: 'T[,,] -> start1: int option -> finish1: int option -> start2: int option -> finish2: int option -> index3: int -> source: 'T[,] -> unit /// Sets a 1D slice of a 3D array. - /// The source array. - /// The start index of the first dimension. - /// The end index of the first dimension. + /// + /// The target array. + /// The fixed index of the first dimension. /// The fixed index of the second dimension. - /// The fixed index of the third dimension. + /// The start index of the third dimension. + /// The end index of the third dimension. /// The source array. + /// /// The one dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedDouble1 : target: 'T[,,] -> index1: int -> index2: int -> start3: int option -> finish3: int option -> source: 'T[] -> unit /// Sets a 1D slice of a 3D array. - /// The source array. + /// + /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. /// The fixed index of the third dimension. /// The source array. + /// /// The one dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedDouble2 : target: 'T[,,] -> index1: int -> start2: int option -> finish2: int option -> index3: int -> source: 'T[] -> unit /// Sets a 1D slice of a 3D array. - /// The source array. + /// + /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. /// The fixed index of the second dimension. /// The fixed index of the third dimension. /// The source array. + /// /// The one dimensional sub array from the given indices. [] val inline SetArraySlice3DFixedDouble3 : target: 'T[,,] -> start1: int option -> finish1: int option -> index2: int -> index3: int -> source: 'T[] -> unit /// Gets a slice of an array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3023,10 +3939,12 @@ namespace Microsoft.FSharp.Core /// The end index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The four dimensional sub array from the given indices. val inline GetArraySlice4D : source:'T[,,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> 'T[,,,] /// Gets a 3D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3035,10 +3953,12 @@ namespace Microsoft.FSharp.Core /// The end index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The three dimensional sub array from the given indices. val inline GetArraySlice4DFixedSingle1 : source:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> 'T[,,] /// Gets a 3D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3047,10 +3967,12 @@ namespace Microsoft.FSharp.Core /// The end index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The three dimensional sub array from the given indices. val inline GetArraySlice4DFixedSingle2 : source:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> 'T[,,] /// Gets a 3D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3059,10 +3981,12 @@ namespace Microsoft.FSharp.Core /// The fixed index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The three dimensional sub array from the given indices. val inline GetArraySlice4DFixedSingle3 : source:'T[,,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> index3:int -> start4:int option -> finish4:int option -> 'T[,,] /// Gets a 3D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3071,10 +3995,12 @@ namespace Microsoft.FSharp.Core /// The start index of the third dimension. /// The end index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The three dimensional sub array from the given indices. val inline GetArraySlice4DFixedSingle4 : source:'T[,,,] -> start1:int option -> finish1:int option -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> index4:int -> 'T[,,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. @@ -3082,10 +4008,12 @@ namespace Microsoft.FSharp.Core /// The end index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble1 : source:'T[,,,] -> index1: int -> index2:int -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> 'T[,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3093,10 +4021,12 @@ namespace Microsoft.FSharp.Core /// The fixed index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble2 : source:'T[,,,] -> index1: int -> start2: int option -> finish2:int option -> index3:int -> start4:int option -> finish4:int option -> 'T[,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3104,10 +4034,12 @@ namespace Microsoft.FSharp.Core /// The start index of the third dimension. /// The end index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble3 : source:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> index4:int -> 'T[,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3115,10 +4047,12 @@ namespace Microsoft.FSharp.Core /// The fixed index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble4 : source:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> index3:int -> start4:int option -> finish4:int option -> 'T[,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3126,10 +4060,12 @@ namespace Microsoft.FSharp.Core /// The start index of the third dimension. /// The end index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble5 : source:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> start3:int option -> finish3:int option -> index4:int -> 'T[,] /// Gets a 2D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3137,51 +4073,61 @@ namespace Microsoft.FSharp.Core /// The end index of the second dimension. /// The fixed index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The two dimensional sub array from the given indices. val inline GetArraySlice4DFixedDouble6 : source:'T[,,,] -> start1:int option -> finish1:int option -> start2: int option -> finish2:int option -> index3:int -> index4:int -> 'T[,] /// Gets a 1D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. /// The fixed index of the third dimension. /// The start index of the fourth dimension. /// The end index of the fourth dimension. + /// /// The one dimensional sub array from the given indices. val inline GetArraySlice4DFixedTriple4 : source:'T[,,,] -> index1:int -> index2:int -> index3:int -> start4:int option -> finish4:int option -> 'T[] /// Gets a 1D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. /// The start index of the third dimension. /// The end index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The one dimensional sub array from the given indices. val inline GetArraySlice4DFixedTriple3 : source:'T[,,,] -> index1:int -> index2:int -> start3:int option -> finish3:int option -> index4:int -> 'T[] /// Gets a 1D slice of a 4D array + /// /// The source array. /// The fixed index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. /// The fixed index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The one dimensional sub array from the given indices. val inline GetArraySlice4DFixedTriple2 : source:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> index3:int -> index4:int -> 'T[] /// Gets a 1D slice of a 4D array + /// /// The source array. /// The start index of the first dimension. /// The end index of the first dimension. /// The fixed index of the second dimension. /// The fixed index of the third dimension. /// The fixed index of the fourth dimension. + /// /// The one dimensional sub array from the given indices. val inline GetArraySlice4DFixedTriple1 : source:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> index3:int -> index4:int -> 'T[] - /// Gets a 3D slice of a 4D array - /// The source array. + /// Sets a 3D slice of a 4D array + /// + /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. /// The end index of the second dimension. @@ -3193,6 +4139,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedSingle1 : target:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> source: 'T[,,] -> unit /// Sets a 3D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3205,6 +4152,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedSingle2 : target:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> source: 'T[,,] -> unit /// Sets a 3D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3217,6 +4165,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedSingle3 : target:'T[,,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> index3:int -> start4:int option -> finish4:int option -> source: 'T[,,] -> unit /// Sets a 3D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3229,6 +4178,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedSingle4 : target:'T[,,,] -> start1:int option -> finish1:int option -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> index4:int -> source: 'T[,,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. @@ -3240,6 +4190,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble1 : target:'T[,,,] -> index1: int -> index2:int -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> source: 'T[,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3251,6 +4202,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble2 : target:'T[,,,] -> index1: int -> start2: int option -> finish2:int option -> index3:int -> start4:int option -> finish4:int option -> source: 'T[,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3262,6 +4214,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble3 : target:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> start3:int option -> finish3:int option -> index4:int -> source: 'T[,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3273,6 +4226,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble4 : target:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> index3:int -> start4:int option -> finish4:int option -> source: 'T[,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3284,6 +4238,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble5 : target:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> start3:int option -> finish3:int option -> index4:int -> source: 'T[,] -> unit /// Sets a 2D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3295,6 +4250,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedDouble6 : target:'T[,,,] -> start1:int option -> finish1:int option -> start2: int option -> finish2:int option -> index3:int -> index4:int -> source: 'T[,] -> unit /// Sets a 1D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. @@ -3305,6 +4261,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedTriple4 : target:'T[,,,] -> index1:int -> index2:int -> index3:int -> start4:int option -> finish4:int option -> source: 'T[] -> unit /// Sets a 1D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The fixed index of the second dimension. @@ -3315,6 +4272,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedTriple3 : target:'T[,,,] -> index1:int -> index2:int -> start3:int option -> finish3:int option -> index4:int -> source: 'T[] -> unit /// Sets a 1D slice of a 4D array + /// /// The target array. /// The fixed index of the first dimension. /// The start index of the second dimension. @@ -3325,6 +4283,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedTriple2 : target:'T[,,,] -> index1:int -> start2: int option -> finish2:int option -> index3:int -> index4:int -> source: 'T[] -> unit /// Sets a 1D slice of a 4D array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3335,6 +4294,7 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4DFixedTriple1 : target:'T[,,,] -> start1:int option -> finish1:int option -> index2:int -> index3:int -> index4:int -> source: 'T[] -> unit /// Sets a slice of an array + /// /// The target array. /// The start index of the first dimension. /// The end index of the first dimension. @@ -3348,9 +4308,11 @@ namespace Microsoft.FSharp.Core val inline SetArraySlice4D : target:'T[,,,] -> start1:int option -> finish1:int option -> start2:int option -> finish2:int option -> start3:int option -> finish3:int option -> start4:int option -> finish4:int option -> source:'T[,,,] -> unit /// Gets a slice from a string + /// /// The source string. /// The index of the first character of the slice. /// The index of the last character of the slice. + /// /// The substring from the given indices. val inline GetStringSlice : source:string -> start:int option -> finish:int option -> string @@ -3558,10 +4520,12 @@ namespace Microsoft.FSharp.Core module Unchecked = /// Unboxes a strongly typed value. This is the inverse of box, unbox<t>(box<t> a) equals a. + /// /// The boxed value. + /// /// The unboxed result. [] - val inline unbox<'T> : obj -> 'T + val inline unbox<'T> : value: obj -> 'T /// Generate a default value for any type. This is null for reference types, /// For structs, this is struct value where all fields have the default value. @@ -3593,64 +4557,84 @@ namespace Microsoft.FSharp.Core module NonStructuralComparison = /// Compares the two values for less-than + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( < ) : x:^T -> y:^U -> bool when (^T or ^U) : (static member ( < ) : ^T * ^U -> bool) /// Compares the two values for greater-than + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( > ) : x:^T -> y:^U -> bool when (^T or ^U) : (static member ( > ) : ^T * ^U -> bool) /// Compares the two values for greater-than-or-equal + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( >= ) : x:^T -> y:^U -> bool when (^T or ^U) : (static member ( >= ) : ^T * ^U -> bool) /// Compares the two values for less-than-or-equal + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( <= ) : x:^T -> y:^U -> bool when (^T or ^U) : (static member ( <= ) : ^T * ^U -> bool) /// Compares the two values for equality + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( = ) : x:^T -> y:^T -> bool when ^T : (static member ( = ) : ^T * ^T -> bool) /// Compares the two values for inequality + /// /// The first parameter. /// The second parameter. + /// /// The result of the comparison. val inline ( <> ) : x:^T -> y:^T -> bool when ^T : (static member ( <> ) : ^T * ^T -> bool) /// Compares the two values + /// /// The first value. /// The second value. + /// /// The result of the comparison. [] val inline compare: e1:'T -> e2:^T -> int when ^T : (static member ( < ) : ^T * ^T -> bool) and ^T : (static member ( > ) : ^T * ^T -> bool) /// Maximum of the two values + /// /// The first value. /// The second value. + /// /// The maximum value. [] val inline max : e1:^T -> e2:^T -> ^T when ^T : (static member ( < ) : ^T * ^T -> bool) /// Minimum of the two values + /// /// The first value. /// The second value. + /// /// The minimum value. [] val inline min : e1:^T -> e2:^T -> ^T when ^T : (static member ( < ) : ^T * ^T -> bool) /// Calls GetHashCode() on the value - /// The value. + /// + /// The value. + /// /// The hash code. [] val inline hash :value:'T -> int when 'T : equality @@ -3658,136 +4642,152 @@ namespace Microsoft.FSharp.Core /// This module contains the basic arithmetic operations with overflow checks. module Checked = /// Overloaded unary negation (checks for overflow) + /// /// The input value. + /// /// The negated value. - [] val inline ( ~- ) : value:^T -> ^T when ^T : (static member ( ~- ) : ^T -> ^T) and default ^T : int /// Overloaded subtraction operator (checks for overflow) + /// /// The first value. /// The second value. + /// /// The first value minus the second value. - [] val inline ( - ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( - ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded addition operator (checks for overflow) + /// /// The first value. /// The second value. + /// /// The sum of the two input values. val inline ( + ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( + ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Overloaded multiplication operator (checks for overflow) + /// /// The first value. /// The second value. + /// /// The product of the two input values. - [] val inline ( * ) : x:^T1 -> y:^T2 -> ^T3 when (^T1 or ^T2) : (static member ( * ) : ^T1 * ^T2 -> ^T3) and default ^T2 : ^T3 and default ^T3 : ^T1 and default ^T3 : ^T2 and default ^T1 : ^T3 and default ^T1 : ^T2 and default ^T1 : int /// Converts the argument to byte. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.Byte.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted byte - [] [] val inline byte : value:^T -> byte when ^T : (static member op_Explicit : ^T -> byte) and default ^T : int /// Converts the argument to sbyte. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.SByte.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted sbyte - [] [] val inline sbyte : value:^T -> sbyte when ^T : (static member op_Explicit : ^T -> sbyte) and default ^T : int /// Converts the argument to int16. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.Int16.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int16 - [] [] val inline int16 : value:^T -> int16 when ^T : (static member op_Explicit : ^T -> int16) and default ^T : int /// Converts the argument to uint16. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.UInt16.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint16 - [] [] val inline uint16 : value:^T -> uint16 when ^T : (static member op_Explicit : ^T -> uint16) and default ^T : int /// Converts the argument to int. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.Int32.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int - [] [] val inline int : value:^T -> int when ^T : (static member op_Explicit : ^T -> int) and default ^T : int /// Converts the argument to int32. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.Int32.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int32 - [] [] val inline int32 : value:^T -> int32 when ^T : (static member op_Explicit : ^T -> int32) and default ^T : int /// Converts the argument to uint32. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.UInt32.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint32 - [] [] val inline uint32 : value:^T -> uint32 when ^T : (static member op_Explicit : ^T -> uint32) and default ^T : int /// Converts the argument to int64. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.Int64.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted int64 - [] [] val inline int64 : value:^T -> int64 when ^T : (static member op_Explicit : ^T -> int64) and default ^T : int /// Converts the argument to uint64. This is a direct, checked conversion for all - /// primitive numeric types. For strings, the input is converted using System.UInt64.Parse() + /// primitive numeric types. For strings, the input is converted using /// with InvariantCulture settings. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted uint64 - [] [] val inline uint64 : value:^T -> uint64 when ^T : (static member op_Explicit : ^T -> uint64) and default ^T : int - /// Converts the argument to nativeint. This is a direct, checked conversion for all + /// Converts the argument to . This is a direct, checked conversion for all /// primitive numeric types. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted nativeint - [] [] val inline nativeint : value:^T -> nativeint when ^T : (static member op_Explicit : ^T -> nativeint) and default ^T : int /// Converts the argument to unativeint. This is a direct, checked conversion for all /// primitive numeric types. Otherwise the operation requires an appropriate /// static conversion method on the input type. + /// /// The input value. + /// /// The converted unativeint - [] [] val inline unativeint : value:^T -> unativeint when ^T : (static member op_Explicit : ^T -> unativeint) and default ^T : int @@ -3795,9 +4795,10 @@ namespace Microsoft.FSharp.Core /// conversion according to the UTF-16 encoding for characters. String inputs must /// be exactly one character long. For other input types the operation requires an /// appropriate static conversion method on the input type. + /// /// The input value. + /// /// The converted char - [] [] val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int @@ -3807,19 +4808,25 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core /// Extensions related to Lazy values. + /// + /// Lazy Computation [] module LazyExtensions = type System.Lazy<'T> with /// Creates a lazy computation that evaluates to the result of the given function when forced. + /// /// The function to provide the value when needed. + /// /// The created Lazy object. [] // give the extension member a 'nice', unmangled compiled name, unique within this module static member Create : creator:(unit -> 'T) -> System.Lazy<'T> /// Creates a lazy computation that evaluates to the given value when forced. + /// /// The input value. + /// /// The created Lazy object. [] // give the extension member a 'nice', unmangled compiled name, unique within this module static member CreateFromValue : value:'T -> System.Lazy<'T> @@ -3834,7 +4841,9 @@ namespace Microsoft.FSharp.Control /// /// Use the values in the Lazy module to manipulate /// values of this type, and the notation lazy expr to create values - /// of type . + /// of type . + /// + /// Lazy Computation type Lazy<'T> = System.Lazy<'T> and [] @@ -3850,30 +4859,41 @@ namespace Microsoft.FSharp.Control /// F# gives special status to member properties compatible with type IDelegateEvent and /// tagged with the CLIEventAttribute. In this case the F# compiler generates appropriate /// CLI metadata to make the member appear to other CLI languages as a CLI event. + /// + /// Events and Observables type IDelegateEvent<'Delegate when 'Delegate :> System.Delegate > = /// Connect a handler delegate object to the event. A handler can /// be later removed using RemoveHandler. The listener will /// be invoked when the event is fired. + /// /// A delegate to be invoked when the event is fired. abstract AddHandler: handler:'Delegate -> unit /// Remove a listener delegate from an event listener store. + /// /// The delegate to be removed from the event listener store. abstract RemoveHandler: handler:'Delegate -> unit /// First class event values for CLI events conforming to CLI Framework standards. + /// + /// Events and Observables [] type IEvent<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate > = inherit IDelegateEvent<'Delegate> inherit IObservable<'Args> /// A delegate type associated with the F# event type IEvent<_> - /// The object that fired the event. + /// + /// The object that fired the event. /// The event arguments. + /// + /// Events and Observables [] type Handler<'T> = delegate of sender:obj * args:'T -> unit /// First-class listening points (i.e. objects that permit you to register a callback /// activated when the event is triggered). + /// + /// Events and Observables type IEvent<'T> = IEvent, 'T> diff --git a/src/fsharp/FSharp.Core/printf.fs b/src/fsharp/FSharp.Core/printf.fs index 26276c5fd63..0dbdb801c88 100644 --- a/src/fsharp/FSharp.Core/printf.fs +++ b/src/fsharp/FSharp.Core/printf.fs @@ -2,17 +2,43 @@ namespace Microsoft.FSharp.Core -type PrintfFormat<'Printer,'State,'Residue,'Result>(value:string) = - member x.Value = value +open System +open System.IO +open System.Text - override __.ToString() = value +open System.Collections.Concurrent +open System.Globalization +open System.Reflection + +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.Operators +open Microsoft.FSharp.Collections + +open LanguagePrimitives.IntrinsicOperators + +type PrintfFormat<'Printer, 'State, 'Residue, 'Result>(value:string, captures: obj[], captureTys: Type[]) = + + new (value) = new PrintfFormat<'Printer, 'State, 'Residue, 'Result>(value, null, null) + + member _.Value = value + + member _.Captures = captures + + member _.CaptureTypes = captureTys + + override _.ToString() = value -type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>(value:string) = - inherit PrintfFormat<'Printer,'State,'Residue,'Result>(value) +type PrintfFormat<'Printer, 'State, 'Residue, 'Result, 'Tuple>(value:string, captures, captureTys: Type[]) = + + inherit PrintfFormat<'Printer, 'State, 'Residue, 'Result>(value, captures, captureTys) + + new (value) = new PrintfFormat<'Printer, 'State, 'Residue, 'Result, 'Tuple>(value, null, null) -type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Residue,'Result> -type Format<'Printer,'State,'Residue,'Result,'Tuple> = PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> +type Format<'Printer, 'State, 'Residue, 'Result> = PrintfFormat<'Printer, 'State, 'Residue, 'Result> +type Format<'Printer, 'State, 'Residue, 'Result, 'Tuple> = PrintfFormat<'Printer, 'State, 'Residue, 'Result, 'Tuple> + +[] module internal PrintfImpl = /// Basic idea of implementation: @@ -36,18 +62,6 @@ module internal PrintfImpl = /// with just one reflection call /// 2. we can make combinable parts independent from particular printf implementation. Thus final result can be cached and shared. /// i.e when first call to printf "%s %s" will trigger creation of the specialization. Subsequent calls will pick existing specialization - open System - open System.IO - open System.Text - - open System.Collections.Generic - open System.Reflection - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Collections - open LanguagePrimitives.IntrinsicOperators - - open System.IO [] type FormatFlags = @@ -78,677 +92,442 @@ module internal PrintfImpl = Precision: int Width: int Flags: FormatFlags + InteropHoleDotNetFormat: string voption } - member this.IsStarPrecision = this.Precision = StarValue - member this.IsPrecisionSpecified = this.Precision <> NotSpecifiedValue - member this.IsStarWidth = this.Width = StarValue - member this.IsWidthSpecified = this.Width <> NotSpecifiedValue + member spec.IsStarPrecision = (spec.Precision = StarValue) + + member spec.IsPrecisionSpecified = (spec.Precision <> NotSpecifiedValue) + + member spec.IsStarWidth = (spec.Width = StarValue) + + member spec.IsWidthSpecified = (spec.Width <> NotSpecifiedValue) + + member spec.ArgCount = + let n = + if spec.TypeChar = 'a' then 2 + elif spec.IsStarWidth || spec.IsStarPrecision then + if spec.IsStarWidth = spec.IsStarPrecision then 3 + else 2 + else 1 - override this.ToString() = + let n = if spec.TypeChar = '%' then n - 1 else n + + assert (n <> 0) + + n + + override spec.ToString() = let valueOf n = match n with StarValue -> "*" | NotSpecifiedValue -> "-" | n -> n.ToString() System.String.Format ( "'{0}', Precision={1}, Width={2}, Flags={3}", - this.TypeChar, - (valueOf this.Precision), - (valueOf this.Width), - this.Flags + spec.TypeChar, + (valueOf spec.Precision), + (valueOf spec.Width), + spec.Flags ) + + member spec.IsDecimalFormat = + spec.TypeChar = 'M' + + member spec.GetPadAndPrefix allowZeroPadding = + let padChar = if allowZeroPadding && isPadWithZeros spec.Flags then '0' else ' '; + let prefix = + if isPlusForPositives spec.Flags then "+" + elif isSpaceForPositives spec.Flags then " " + else "" + padChar, prefix + + member spec.IsGFormat = + spec.IsDecimalFormat || System.Char.ToLower(spec.TypeChar) = 'g' + /// Set of helpers to parse format string module private FormatString = - let intFromString (s: string) pos = - let rec go acc i = - if Char.IsDigit s.[i] then - let n = int s.[i] - int '0' - go (acc * 10 + n) (i + 1) - else acc, i - go 0 pos - - let parseFlags (s: string) i = - let rec go flags i = + let intFromString (s: string) (i: byref) = + let mutable res = 0 + while (Char.IsDigit s.[i]) do + let n = int s.[i] - int '0' + res <- res * 10 + n + i <- i + 1 + res + + let parseFlags (s: string) (i: byref) = + let mutable flags = FormatFlags.None + let mutable fin = false + while not fin do match s.[i] with - | '0' -> go (flags ||| FormatFlags.PadWithZeros) (i + 1) - | '+' -> go (flags ||| FormatFlags.PlusForPositives) (i + 1) - | ' ' -> go (flags ||| FormatFlags.SpaceForPositives) (i + 1) - | '-' -> go (flags ||| FormatFlags.LeftJustify) (i + 1) - | _ -> flags, i - go FormatFlags.None i - - let parseWidth (s: string) i = - if s.[i] = '*' then StarValue, (i + 1) - elif Char.IsDigit s.[i] then intFromString s i - else NotSpecifiedValue, i - - let parsePrecision (s: string) i = + | '0' -> + flags <- flags ||| FormatFlags.PadWithZeros + i <- i + 1 + | '+' -> + flags <- flags ||| FormatFlags.PlusForPositives + i <- i + 1 + | ' ' -> + flags <- flags ||| FormatFlags.SpaceForPositives + i <- i + 1 + | '-' -> + flags <- flags ||| FormatFlags.LeftJustify + i <- i + 1 + | _ -> + fin <- true + flags + + let parseWidth (s: string) (i: byref) = + if s.[i] = '*' then + i <- i + 1 + StarValue + elif Char.IsDigit s.[i] then + intFromString s (&i) + else + NotSpecifiedValue + + let parsePrecision (s: string) (i: byref) = if s.[i] = '.' then - if s.[i + 1] = '*' then StarValue, i + 2 - elif Char.IsDigit s.[i + 1] then intFromString s (i + 1) + if s.[i + 1] = '*' then + i <- i + 2 + StarValue + elif Char.IsDigit s.[i + 1] then + i <- i + 1 + intFromString s (&i) else raise (ArgumentException("invalid precision value")) - else NotSpecifiedValue, i + else + NotSpecifiedValue - let parseTypeChar (s: string) i = - s.[i], (i + 1) + let parseTypeChar (s: string) (i: byref) = + let res = s.[i] + i <- i + 1 + res + + let parseInterpolatedHoleDotNetFormat typeChar (s: string) (i: byref) = + if typeChar = 'P' then + if i < s.Length && s.[i] = '(' then + let i2 = s.IndexOf(")", i) + if i2 = -1 then + ValueNone + else + let res = s.[i+1..i2-1] + i <- i2+1 + ValueSome res + else + ValueNone + else + ValueNone + + // Skip %P() added for hole in "...%d{x}..." + let skipInterpolationHole typeChar (fmt: string) (i: byref) = + if typeChar <> 'P' then + if i+1 < fmt.Length && fmt.[i] = '%' && fmt.[i+1] = 'P' then + i <- i + 2 + if i+1 < fmt.Length && fmt.[i] = '(' && fmt.[i+1] = ')' then + i <- i+2 - let findNextFormatSpecifier (s: string) i = - let rec go i (buf: Text.StringBuilder) = + let findNextFormatSpecifier (s: string) (i: byref) = + let buf = StringBuilder() + let mutable fin = false + while not fin do if i >= s.Length then - s.Length, buf.ToString() + fin <- true else let c = s.[i] if c = '%' then if i + 1 < s.Length then - let _, i1 = parseFlags s (i + 1) - let w, i2 = parseWidth s i1 - let p, i3 = parsePrecision s i2 - let typeChar, i4 = parseTypeChar s i3 + let mutable i2 = i+1 + let _ = parseFlags s &i2 + let w = parseWidth s &i2 + let p = parsePrecision s &i2 + let typeChar = parseTypeChar s &i2 + // shortcut for the simpliest case // if typeChar is not % or it has star as width\precision - resort to long path if typeChar = '%' && not (w = StarValue || p = StarValue) then buf.Append('%') |> ignore - go i4 buf + i <- i2 else - i, buf.ToString() + fin <- true else raise (ArgumentException("Missing format specifier")) else buf.Append c |> ignore - go (i + 1) buf - go i (Text.StringBuilder()) + i <- i + 1 + buf.ToString() + + [] + /// Represents one step in the execution of a format string + type Step = + | StepWithArg of prefix: string * conv: (obj -> string) + | StepWithTypedArg of prefix: string * conv: (obj -> Type -> string) + | StepString of prefix: string + | StepLittleT of prefix: string + | StepLittleA of prefix: string + | StepStar1 of prefix: string * conv: (obj -> int -> string) + | StepPercentStar1 of prefix: string + | StepStar2 of prefix: string * conv: (obj -> int -> int -> string) + | StepPercentStar2 of prefix: string + + // Count the number of string fragments in a sequence of steps + static member BlockCount(steps: Step[]) = + let mutable count = 0 + for step in steps do + match step with + | StepWithArg (prefix, _conv) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepWithTypedArg (prefix, _conv) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepString prefix -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + | StepLittleT(prefix) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepLittleA(prefix) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepStar1(prefix, _conv) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepPercentStar1(prefix) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepStar2(prefix, _conv) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + | StepPercentStar2(prefix) -> + if not (String.IsNullOrEmpty prefix) then count <- count + 1 + count <- count + 1 + count /// Abstracts generated printer from the details of particular environment: how to write text, how to produce results etc... [] - type PrintfEnv<'State, 'Residue, 'Result> = - val State: 'State - new(s: 'State) = { State = s } + type PrintfEnv<'State, 'Residue, 'Result>(state: 'State) = + member _.State = state + abstract Finish: unit -> 'Result + abstract Write: string -> unit + + /// Write the result of a '%t' format. If this is a string it is written. If it is a 'unit' value + /// the side effect has already happened abstract WriteT: 'Residue -> unit + + member env.WriteSkipEmpty(s: string) = + if not (String.IsNullOrEmpty s) then + env.Write s - type Utils = - static member inline Write (env: PrintfEnv<_, _, _>, a, b) = - env.Write a - env.Write b - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c) = - Utils.Write(env, a, b) - env.Write c - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d) = - Utils.Write(env, a, b) - Utils.Write(env, c, d) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e) = - Utils.Write(env, a, b, c) - Utils.Write(env, d, e) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f) = - Utils.Write(env, a, b, c, d) - Utils.Write(env, e, f) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g) = - Utils.Write(env, a, b, c, d, e) - Utils.Write(env, f, g) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h) = - Utils.Write(env, a, b, c, d, e, f) - Utils.Write(env, g, h) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i) = - Utils.Write(env, a, b, c, d, e, f, g) - Utils.Write(env, h, i) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j) = - Utils.Write(env, a, b, c, d, e, f, g, h) - Utils.Write(env, i, j) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j, k) = - Utils.Write(env, a, b, c, d, e, f, g, h, i) - Utils.Write(env, j, k) - static member inline Write (env: PrintfEnv<_, _, _>, a, b, c, d, e, f, g, h, i, j, k, l, m) = - Utils.Write(env, a, b, c, d, e, f, g, h, i, j, k) - Utils.Write(env, l, m) + member env.RunSteps (args: obj[], argTys: Type[], steps: Step[]) = + let mutable argIndex = 0 + let mutable tyIndex = 0 + + for step in steps do + match step with + | StepWithArg (prefix, conv) -> + env.WriteSkipEmpty prefix + let arg = args.[argIndex] + argIndex <- argIndex + 1 + env.Write(conv arg) + + | StepWithTypedArg (prefix, conv) -> + env.WriteSkipEmpty prefix + let arg = args.[argIndex] + let argTy = argTys.[tyIndex] + argIndex <- argIndex + 1 + tyIndex <- tyIndex + 1 + env.Write(conv arg argTy) + + | StepString prefix -> + env.WriteSkipEmpty prefix + + | StepLittleT(prefix) -> + env.WriteSkipEmpty prefix + let farg = args.[argIndex] + argIndex <- argIndex + 1 + let f = farg :?> ('State -> 'Residue) + env.WriteT(f env.State) + + | StepLittleA(prefix) -> + env.WriteSkipEmpty prefix + let farg = args.[argIndex] + argIndex <- argIndex + 1 + let arg = args.[argIndex] + argIndex <- argIndex + 1 + let f = farg :?> ('State -> obj -> 'Residue) + env.WriteT(f env.State arg) + + | StepStar1(prefix, conv) -> + env.WriteSkipEmpty prefix + let star1 = args.[argIndex] :?> int + argIndex <- argIndex + 1 + let arg1 = args.[argIndex] + argIndex <- argIndex + 1 + env.Write (conv arg1 star1) + + | StepPercentStar1(prefix) -> + argIndex <- argIndex + 1 + env.WriteSkipEmpty prefix + env.Write("%") + + | StepStar2(prefix, conv) -> + env.WriteSkipEmpty prefix + let star1 = args.[argIndex] :?> int + argIndex <- argIndex + 1 + let star2 = args.[argIndex] :?> int + argIndex <- argIndex + 1 + let arg1 = args.[argIndex] + argIndex <- argIndex + 1 + env.Write (conv arg1 star1 star2) + + | StepPercentStar2(prefix) -> + env.WriteSkipEmpty prefix + argIndex <- argIndex + 2 + env.Write("%") - /// Type of results produced by specialization - /// This is function that accepts thunk to create PrintfEnv on demand and returns concrete instance of Printer (curried function) - /// After all arguments is collected, specialization obtains concrete PrintfEnv from the thunk and use it to output collected data. - type PrintfFactory<'State, 'Residue, 'Result, 'Printer> = (unit -> PrintfEnv<'State, 'Residue, 'Result>) -> 'Printer + env.Finish() + + /// Type of results produced by specialization. + /// + /// This is a function that accepts a thunk to create PrintfEnv on demand (at the very last + /// appliction of an argument) and returns a concrete instance of an appriate curried printer. + /// + /// After all arguments are collected, specialization obtains concrete PrintfEnv from the thunk + /// and uses it to output collected data. + /// + /// Note the arguments must be captured in an *immutable* collection. For example consider + /// let f1 = printf "%d%d%d" 3 // activation captures '3' (args --> [3]) + /// let f2 = f1 4 // same activation captures 4 (args --> [3;4]) + /// let f3 = f1 5 // same activation captures 5 (args --> [3;5]) + /// f2 7 // same activation captures 7 (args --> [3;4;7]) + /// f3 8 // same activation captures 8 (args --> [3;5;8]) + /// + /// If we captured into an mutable array then these would interfere + type PrintfInitial<'State, 'Residue, 'Result> = (unit -> PrintfEnv<'State, 'Residue, 'Result>) + type PrintfFuncFactory<'Printer, 'State, 'Residue, 'Result> = + delegate of obj list * PrintfInitial<'State, 'Residue, 'Result> -> 'Printer [] - let MaxArgumentsInSpecialization = 5 - - /// Specializations are created via factory methods. These methods accepts 2 kinds of arguments - /// - parts of format string that corresponds to raw text - /// - functions that can transform collected values to strings - /// basic shape of the signature of specialization - /// + + + ... + - type Specializations<'State, 'Residue, 'Result> private ()= + let MaxArgumentsInSpecialization = 3 + + let revToArray extra (args: 'T list) = + // We've reached the end, now fill in the array, reversing steps, avoiding reallocating + let n = args.Length + let res = Array.zeroCreate (n+extra) + let mutable j = 0 + for arg in args do + res.[n-j-1] <- arg + j <- j + 1 + res + + type Specializations<'State, 'Residue, 'Result>() = - static member Final1<'A> - ( - s0, conv1, s1 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env = env() - Utils.Write(env, s0, (conv1 a), s1) - env.Finish() - ) + static member Final0(allSteps) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + let env = initial() + env.RunSteps(revToArray 0 args, null, allSteps) ) - static member FinalFastEnd1<'A> - ( - s0, conv1 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env = env() - Utils.Write(env, s0, (conv1 a)) - env.Finish() + static member CaptureFinal1<'A>(allSteps) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) -> + let env = initial() + let argArray = revToArray 1 args + argArray.[argArray.Length-1] <- box arg1 + env.RunSteps(argArray, null, allSteps) ) ) - static member FinalFastStart1<'A> - ( - conv1, s1 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env = env() - Utils.Write(env, (conv1 a), s1) - env.Finish() + static member CaptureFinal2<'A, 'B>(allSteps) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) (arg2: 'B) -> + let env = initial() + let argArray = revToArray 2 args + argArray.[argArray.Length-1] <- box arg2 + argArray.[argArray.Length-2] <- box arg1 + env.RunSteps(argArray, null, allSteps) ) ) - static member FinalFast1<'A> - ( - conv1 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env = env() - env.Write (conv1 a) - env.Finish() + static member CaptureFinal3<'A, 'B, 'C>(allSteps) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) (arg2: 'B) (arg3: 'C) -> + let env = initial() + let argArray = revToArray 3 args + argArray.[argArray.Length-1] <- box arg3 + argArray.[argArray.Length-2] <- box arg2 + argArray.[argArray.Length-3] <- box arg1 + env.RunSteps(argArray, null, allSteps) ) ) - static member Final2<'A, 'B> - ( - s0, conv1, s1, conv2, s2 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2) - env.Finish() + static member Capture1<'A, 'Tail>(next: PrintfFuncFactory<_, 'State, 'Residue, 'Result>) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) -> + let args = (box arg1 :: args) + next.Invoke(args, initial) : 'Tail ) ) - static member FinalFastEnd2<'A, 'B> - ( - s0, conv1, s1, conv2 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b)) - env.Finish() + static member CaptureLittleA<'A, 'Tail>(next: PrintfFuncFactory<_, 'State, 'Residue, 'Result>) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (f: 'State -> 'A -> 'Residue) (arg1: 'A) -> + let args = box arg1 :: box (fun s (arg:obj) -> f s (unbox arg)) :: args + next.Invoke(args, initial) : 'Tail ) ) - static member FinalFastStart2<'A, 'B> - ( - conv1, s1, conv2, s2 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2) - env.Finish() + static member Capture2<'A, 'B, 'Tail>(next: PrintfFuncFactory<_, 'State, 'Residue, 'Result>) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) (arg2: 'B) -> + let args = box arg2 :: box arg1 :: args + next.Invoke(args, initial) : 'Tail ) ) - static member FinalFast2<'A, 'B> - ( - conv1, s1, conv2 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b)) - env.Finish() + static member Capture3<'A, 'B, 'C, 'Tail>(next: PrintfFuncFactory<_, 'State, 'Residue, 'Result>) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun args initial -> + (fun (arg1: 'A) (arg2: 'B) (arg3: 'C) -> + let args = box arg3 :: box arg2 :: box arg1 :: args + next.Invoke(args, initial) : 'Tail ) ) - static member Final3<'A, 'B, 'C> - ( - s0, conv1, s1, conv2, s2, conv3, s3 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3) - env.Finish() - ) - ) - - static member FinalFastEnd3<'A, 'B, 'C> - ( - s0, conv1, s1, conv2, s2, conv3 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c)) - env.Finish() - ) + // Special case for format strings containing just one '%d' etc, i.e. StepWithArg then StepString. + // This avoids allocating an argument array, and unfolds the single iteration of RunSteps. + static member OneStepWithArg<'A>(prefix1, conv1, prefix2) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun _args initial -> + // Note this is the actual computed/stored closure for + // sprintf "prefix1 %d prefix2" + // for any simple format specifiers, where conv1 and conv2 will depend on the format specifiers etc. + (fun (arg1: 'A) -> + let env = initial() + env.WriteSkipEmpty prefix1 + env.Write(conv1 (box arg1)) + env.WriteSkipEmpty prefix2 + env.Finish()) ) - static member FinalFastStart3<'A, 'B, 'C> - ( - conv1, s1, conv2, s2, conv3, s3 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3) - env.Finish() - ) - ) - - static member FinalFast3<'A, 'B, 'C> - ( - conv1, s1, conv2, s2, conv3 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c)) - env.Finish() - ) - ) - - static member Final4<'A, 'B, 'C, 'D> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4) - env.Finish() - ) - ) - - static member FinalFastEnd4<'A, 'B, 'C, 'D> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d)) - env.Finish() - ) - ) - - static member FinalFastStart4<'A, 'B, 'C, 'D> - ( - conv1, s1, conv2, s2, conv3, s3, conv4, s4 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4) - env.Finish() - ) + // Special case for format strings containing two simple formats like '%d %s' etc, i.e. + ///StepWithArg then StepWithArg then StepString. This avoids allocating an argument array, + // and unfolds the two iteration of RunSteps. + static member TwoStepWithArg<'A, 'B>(prefix1, conv1, prefix2, conv2, prefix3) = + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun _args initial -> + // Note this is the actual computed/stored closure for + // sprintf "prefix1 %d prefix2 %s prefix3" + // for any simple format specifiers, where conv1 and conv2 will depend on the format specifiers etc. + (fun (arg1: 'A) (arg2: 'B) -> + let env = initial() + env.WriteSkipEmpty prefix1 + env.Write(conv1 (box arg1)) + env.WriteSkipEmpty prefix2 + env.Write(conv2 (box arg2)) + env.WriteSkipEmpty prefix3 + env.Finish()) ) - static member FinalFast4<'A, 'B, 'C, 'D> - ( - conv1, s1, conv2, s2, conv3, s3, conv4 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d)) - env.Finish() - ) - ) - - static member Final5<'A, 'B, 'C, 'D, 'E> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5, s5 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e), s5) - env.Finish() - ) - ) - - static member FinalFastEnd5<'A, 'B, 'C, 'D, 'E> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e)) - env.Finish() - ) - ) - - static member FinalFastStart5<'A, 'B, 'C, 'D, 'E> - ( - conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5, s5 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e), s5) - env.Finish() - ) - ) - - static member FinalFast5<'A, 'B, 'C, 'D, 'E> - ( - conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5 - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e)) - env.Finish() - ) - ) - - static member Chained1<'A, 'Tail> - ( - s0, conv1, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env() = - let env = env() - Utils.Write(env, s0, (conv1 a)) - env - next env : 'Tail - ) - ) - - static member ChainedFastStart1<'A, 'Tail> - ( - conv1, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) -> - let env() = - let env = env() - env.Write(conv1 a) - env - next env : 'Tail - ) - ) - - static member Chained2<'A, 'B, 'Tail> - ( - s0, conv1, s1, conv2, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env() = - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b)) - env - next env : 'Tail - ) - ) - - static member ChainedFastStart2<'A, 'B, 'Tail> - ( - conv1, s1, conv2, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) -> - let env() = - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b)) - env - next env : 'Tail - ) - ) - - static member Chained3<'A, 'B, 'C, 'Tail> - ( - s0, conv1, s1, conv2, s2, conv3, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env() = - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c)) - env - next env : 'Tail - ) - ) - - static member ChainedFastStart3<'A, 'B, 'C, 'Tail> - ( - conv1, s1, conv2, s2, conv3, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) -> - let env() = - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c)) - env - next env : 'Tail - ) - ) - - static member Chained4<'A, 'B, 'C, 'D, 'Tail> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env() = - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d)) - env - next env : 'Tail - ) - ) - - static member ChainedFastStart4<'A, 'B, 'C, 'D, 'Tail> - ( - conv1, s1, conv2, s2, conv3, s3, conv4, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D)-> - let env() = - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d)) - env - next env : 'Tail - ) - ) - - static member Chained5<'A, 'B, 'C, 'D, 'E, 'Tail> - ( - s0, conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env() = - let env = env() - Utils.Write(env, s0, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e)) - env - next env : 'Tail - ) - ) - - static member ChainedFastStart5<'A, 'B, 'C, 'D, 'E, 'Tail> - ( - conv1, s1, conv2, s2, conv3, s3, conv4, s4, conv5, - next - ) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (a: 'A) (b: 'B) (c: 'C) (d: 'D) (e: 'E)-> - let env() = - let env = env() - Utils.Write(env, (conv1 a), s1, (conv2 b), s2, (conv3 c), s3, (conv4 d), s4, (conv5 e)) - env - next env : 'Tail - ) - ) - - static member TFinal(s1: string, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (f: 'State -> 'Residue) -> - let env = env() - env.Write s1 - env.WriteT(f env.State) - env.Write s2 - env.Finish() - ) - ) - static member TChained<'Tail>(s1: string, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (f: 'State -> 'Residue) -> - let env() = - let env = env() - env.Write s1 - env.WriteT(f env.State) - env - next env: 'Tail - ) - ) - - static member LittleAFinal<'A>(s1: string, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (f: 'State -> 'A ->'Residue) (a: 'A) -> - let env = env() - env.Write s1 - env.WriteT(f env.State a) - env.Write s2 - env.Finish() - ) - ) - static member LittleAChained<'A, 'Tail>(s1: string, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (f: 'State -> 'A ->'Residue) (a: 'A) -> - let env() = - let env = env() - env.Write s1 - env.WriteT(f env.State a) - env - next env: 'Tail - ) - ) - - static member StarFinal1<'A>(s1: string, conv, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (star1: int) (a: 'A) -> - let env = env() - env.Write s1 - env.Write (conv a star1: string) - env.Write s2 - env.Finish() - ) - ) - - static member PercentStarFinal1(s1: string, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (_star1 : int) -> - let env = env() - env.Write s1 - env.Write("%") - env.Write s2 - env.Finish() - ) - ) - - static member StarFinal2<'A>(s1: string, conv, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (star1: int) (star2: int) (a: 'A) -> - let env = env() - env.Write s1 - env.Write (conv a star1 star2: string) - env.Write s2 - env.Finish() - ) - ) - - /// Handles case when '%*.*%' is used at the end of string - static member PercentStarFinal2(s1: string, s2: string) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (_star1 : int) (_star2 : int) -> - let env = env() - env.Write s1 - env.Write("%") - env.Write s2 - env.Finish() - ) - ) - - static member StarChained1<'A, 'Tail>(s1: string, conv, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (star1: int) (a: 'A) -> - let env() = - let env = env() - env.Write s1 - env.Write(conv a star1 : string) - env - next env : 'Tail - ) - ) - - /// Handles case when '%*%' is used in the middle of the string so it needs to be chained to another printing block - static member PercentStarChained1<'Tail>(s1: string, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (_star1 : int) -> - let env() = - let env = env() - env.Write s1 - env.Write("%") - env - next env: 'Tail - ) - ) - - static member StarChained2<'A, 'Tail>(s1: string, conv, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (star1: int) (star2: int) (a: 'A) -> - let env() = - let env = env() - env.Write s1 - env.Write(conv a star1 star2 : string) - env - next env : 'Tail - ) - ) - - /// Handles case when '%*.*%' is used in the middle of the string so it needs to be chained to another printing block - static member PercentStarChained2<'Tail>(s1: string, next: PrintfFactory<'State, 'Residue, 'Result,'Tail>) = - (fun (env: unit -> PrintfEnv<'State, 'Residue, 'Result>) -> - (fun (_star1 : int) (_star2 : int) -> - let env() = - let env = env() - env.Write s1 - env.Write("%") - env - next env : 'Tail - ) - ) - let inline (===) a b = Object.ReferenceEquals(a, b) - let invariantCulture = System.Globalization.CultureInfo.InvariantCulture let inline boolToString v = if v then "true" else "false" + let inline stringToSafeString v = match v with | null -> "" @@ -757,7 +536,18 @@ module internal PrintfImpl = [] let DefaultPrecision = 6 + /// A wrapper struct used to slightly strengthen the types of "ValueConverter" objects produced during composition of + /// the dynamic implementation. These are always functions but sometimes they take one argument, sometimes two. + [] + type ValueConverter private (f: obj) = + member x.FuncObj = f + + static member inline Make (f: obj -> string) = ValueConverter(box f) + static member inline Make (f: obj -> int -> string) = ValueConverter(box f) + static member inline Make (f: obj -> int-> int -> string) = ValueConverter(box f) + let getFormatForFloat (ch: char) (prec: int) = ch.ToString() + prec.ToString() + let normalizePrecision prec = min (max prec 0) 99 /// Contains helpers to convert printer functions to functions that prints value with respect to specified justification @@ -768,32 +558,33 @@ module internal PrintfImpl = /// - withPadding - adapts first category /// - withPaddingFormatted - adapts second category module Padding = + /// pad here is function that converts T to string with respect of justification /// basic - function that converts T to string without applying justification rules /// adaptPaddedFormatted returns boxed function that has various number of arguments depending on if width\precision flags has '*' value - let inline adaptPaddedFormatted (spec: FormatSpecifier) getFormat (basic: string -> 'T -> string) (pad: string -> int -> 'T -> string) = + let adaptPaddedFormatted (spec: FormatSpecifier) getFormat (basic: string -> obj -> string) (pad: string -> int -> obj -> string) : ValueConverter = if spec.IsStarWidth then if spec.IsStarPrecision then // width=*, prec=* - box(fun v width prec -> + ValueConverter.Make (fun v width prec -> let fmt = getFormat (normalizePrecision prec) pad fmt width v) else // width=*, prec=? let prec = if spec.IsPrecisionSpecified then normalizePrecision spec.Precision else DefaultPrecision let fmt = getFormat prec - box(fun v width -> + ValueConverter.Make (fun v width -> pad fmt width v) elif spec.IsStarPrecision then if spec.IsWidthSpecified then // width=val, prec=* - box(fun v prec -> + ValueConverter.Make (fun v prec -> let fmt = getFormat prec pad fmt spec.Width v) else // width=X, prec=* - box(fun v prec -> + ValueConverter.Make (fun v prec -> let fmt = getFormat prec basic fmt v) else @@ -801,75 +592,88 @@ module internal PrintfImpl = let fmt = getFormat prec if spec.IsWidthSpecified then // width=val, prec=* - box(fun v -> + ValueConverter.Make (fun v -> pad fmt spec.Width v) else // width=X, prec=* - box(fun v -> + ValueConverter.Make (fun v -> basic fmt v) /// pad here is function that converts T to string with respect of justification /// basic - function that converts T to string without applying justification rules /// adaptPadded returns boxed function that has various number of arguments depending on if width flags has '*' value - let inline adaptPadded (spec: FormatSpecifier) (basic: 'T -> string) (pad: int -> 'T -> string) = + let adaptPadded (spec: FormatSpecifier) (basic: obj -> string) (pad: int -> obj -> string) : ValueConverter = if spec.IsStarWidth then - // width=*, prec=? - box(fun v width -> - pad width v) + // width=*, prec=? + ValueConverter.Make (fun v width -> + pad width v) else if spec.IsWidthSpecified then // width=val, prec=* - box(fun v -> + ValueConverter.Make (fun v -> pad spec.Width v) else // width=X, prec=* - box(fun v -> + ValueConverter.Make (fun v -> basic v) - let inline withPaddingFormatted (spec: FormatSpecifier) getFormat (defaultFormat: string) (f: string -> 'T -> string) left right = + let withPaddingFormatted (spec: FormatSpecifier) getFormat (defaultFormat: string) (f: string -> obj -> string) left right : ValueConverter = if not (spec.IsWidthSpecified || spec.IsPrecisionSpecified) then - box (f defaultFormat) + ValueConverter.Make (f defaultFormat) else if isLeftJustify spec.Flags then adaptPaddedFormatted spec getFormat f left else adaptPaddedFormatted spec getFormat f right - let inline withPadding (spec: FormatSpecifier) (f: 'T -> string) left right = + let withPadding (spec: FormatSpecifier) (f: obj -> string) left right : ValueConverter = if not spec.IsWidthSpecified then - box f + ValueConverter.Make f else if isLeftJustify spec.Flags then adaptPadded spec f left else adaptPadded spec f right - let inline isNumber (x: ^T) = - not (^T: (static member IsPositiveInfinity: 'T -> bool) x) && not (^T: (static member IsNegativeInfinity: 'T -> bool) x) && not (^T: (static member IsNaN: 'T -> bool) x) - - let inline isInteger n = - n % LanguagePrimitives.GenericOne = LanguagePrimitives.GenericZero - - let inline isPositive n = - n >= LanguagePrimitives.GenericZero - - /// contains functions to handle left\right justifications for non-numeric types (strings\bools) + /// Contains functions to handle left/right justifications for non-numeric types (strings/bools) module Basic = - let inline leftJustify (f: 'T -> string) padChar = + let leftJustify (f: obj -> string) padChar = fun (w: int) v -> (f v).PadRight(w, padChar) - let inline rightJustify (f: 'T -> string) padChar = + let rightJustify (f: obj -> string) padChar = fun (w: int) v -> (f v).PadLeft(w, padChar) - /// contains functions to handle left\right and no justification case for numbers + let withPadding (spec: FormatSpecifier) f = + let padChar, _ = spec.GetPadAndPrefix false + Padding.withPadding spec f (leftJustify f padChar) (rightJustify f padChar) + + /// Contains functions to handle left/right and no justification case for numbers module GenericNumber = + + let isPositive (n: obj) = + match n with + | :? int8 as n -> n >= 0y + | :? uint8 -> true + | :? int16 as n -> n >= 0s + | :? uint16 -> true + | :? int32 as n -> n >= 0 + | :? uint32 -> true + | :? int64 as n -> n >= 0L + | :? uint64 -> true + | :? nativeint as n -> n >= 0n + | :? unativeint -> true + | :? single as n -> n >= 0.0f + | :? double as n -> n >= 0.0 + | :? decimal as n -> n >= 0.0M + | _ -> failwith "isPositive: unreachable" + /// handles right justification when pad char = '0' /// this case can be tricky: /// - negative numbers, -7 should be printed as '-007', not '00-7' /// - positive numbers when prefix for positives is set: 7 should be '+007', not '00+7' - let inline rightJustifyWithZeroAsPadChar (str: string) isNumber isPositive w (prefixForPositives: string) = + let rightJustifyWithZeroAsPadChar (str: string) isNumber isPositive w (prefixForPositives: string) = System.Diagnostics.Debug.Assert(prefixForPositives.Length = 0 || prefixForPositives.Length = 1) if isNumber then if isPositive then @@ -884,12 +688,12 @@ module internal PrintfImpl = str.PadLeft(w, ' ') /// handler right justification when pad char = ' ' - let inline rightJustifyWithSpaceAsPadChar (str: string) isNumber isPositive w (prefixForPositives: string) = + let rightJustifyWithSpaceAsPadChar (str: string) isNumber isPositive w (prefixForPositives: string) = System.Diagnostics.Debug.Assert(prefixForPositives.Length = 0 || prefixForPositives.Length = 1) (if isNumber && isPositive then prefixForPositives + str else str).PadLeft(w, ' ') /// handles left justification with formatting with 'G'\'g' - either for decimals or with 'g'\'G' is explicitly set - let inline leftJustifyWithGFormat (str: string) isNumber isInteger isPositive w (prefixForPositives: string) padChar = + let leftJustifyWithGFormat (str: string) isNumber isInteger isPositive w (prefixForPositives: string) padChar = if isNumber then let str = if isPositive then prefixForPositives + str else str // NOTE: difference - for 'g' format we use isInt check to detect situations when '5.0' is printed as '5' @@ -901,7 +705,7 @@ module internal PrintfImpl = else str.PadRight(w, ' ') // pad NaNs with ' ' - let inline leftJustifyWithNonGFormat (str: string) isNumber isPositive w (prefixForPositives: string) padChar = + let leftJustifyWithNonGFormat (str: string) isNumber isPositive w (prefixForPositives: string) padChar = if isNumber then let str = if isPositive then prefixForPositives + str else str str.PadRight(w, padChar) @@ -909,161 +713,223 @@ module internal PrintfImpl = str.PadRight(w, ' ') // pad NaNs with ' ' /// processes given string based depending on values isNumber\isPositive - let inline noJustificationCore (str: string) isNumber isPositive prefixForPositives = + let noJustificationCore (str: string) isNumber isPositive prefixForPositives = if isNumber && isPositive then prefixForPositives + str else str /// noJustification handler for f: 'T -> string - basic integer types - let inline noJustification f (prefix: string) isUnsigned = + let noJustification (f: obj -> string) (prefix: string) isUnsigned = if isUnsigned then - fun v -> noJustificationCore (f v) true true prefix + fun (v: obj) -> noJustificationCore (f v) true true prefix else - fun v -> noJustificationCore (f v) true (isPositive v) prefix + fun (v: obj) -> noJustificationCore (f v) true (isPositive v) prefix - /// noJustification handler for f: string -> 'T -> string - floating point types - let inline noJustificationWithFormat f (prefix: string) = - fun (fmt: string) v -> noJustificationCore (f fmt v) true (isPositive v) prefix - - /// leftJustify handler for f: 'T -> string - basic integer types - let inline leftJustify isGFormat f (prefix: string) padChar isUnsigned = + /// contains functions to handle left/right and no justification case for numbers + module Integer = + + let eliminateNative (v: obj) = + match v with + | :? nativeint as n -> + if IntPtr.Size = 4 then box (n.ToInt32()) + else box (n.ToInt64()) + | :? unativeint as n -> + if IntPtr.Size = 4 then box (uint32 (n.ToUInt32())) + else box (uint64 (n.ToUInt64())) + | _ -> v + + let rec toString (v: obj) = + match v with + | :? int32 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? int64 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? sbyte as n -> n.ToString(CultureInfo.InvariantCulture) + | :? byte as n -> n.ToString(CultureInfo.InvariantCulture) + | :? int16 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? uint16 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? uint32 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? uint64 as n -> n.ToString(CultureInfo.InvariantCulture) + | :? nativeint | :? unativeint -> toString (eliminateNative v) + | _ -> failwith "toString: unreachable" + + let rec toFormattedString fmt (v: obj) = + match v with + | :? int32 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? int64 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? sbyte as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? byte as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? int16 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? uint16 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? uint32 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? uint64 as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? nativeint | :? unativeint -> toFormattedString fmt (eliminateNative v) + | _ -> failwith "toFormattedString: unreachable" + + let rec toUnsigned (v: obj) = + match v with + | :? int32 as n -> box (uint32 n) + | :? int64 as n -> box (uint64 n) + | :? sbyte as n -> box (byte n) + | :? int16 as n -> box (uint16 n) + | :? nativeint | :? unativeint -> toUnsigned (eliminateNative v) + | _ -> v + + /// Left justification handler for f: 'T -> string - basic integer types + let leftJustify isGFormat (f: obj -> string) (prefix: string) padChar isUnsigned = if isUnsigned then if isGFormat then - fun (w: int) v -> - leftJustifyWithGFormat (f v) true (isInteger v) true w prefix padChar + fun (w: int) (v: obj) -> + GenericNumber.leftJustifyWithGFormat (f v) true true true w prefix padChar else - fun (w: int) v -> - leftJustifyWithNonGFormat (f v) true true w prefix padChar + fun (w: int) (v: obj) -> + GenericNumber.leftJustifyWithNonGFormat (f v) true true w prefix padChar else if isGFormat then - fun (w: int) v -> - leftJustifyWithGFormat (f v) true (isInteger v) (isPositive v) w prefix padChar + fun (w: int) (v: obj) -> + GenericNumber.leftJustifyWithGFormat (f v) true true (GenericNumber.isPositive v) w prefix padChar else - fun (w: int) v -> - leftJustifyWithNonGFormat (f v) true (isPositive v) w prefix padChar + fun (w: int) (v: obj) -> + GenericNumber.leftJustifyWithNonGFormat (f v) true (GenericNumber.isPositive v) w prefix padChar - /// leftJustify handler for f: string -> 'T -> string - floating point types - let inline leftJustifyWithFormat isGFormat f (prefix: string) padChar = - if isGFormat then - fun (fmt: string) (w: int) v -> - leftJustifyWithGFormat (f fmt v) true (isInteger v) (isPositive v) w prefix padChar - else - fun (fmt: string) (w: int) v -> - leftJustifyWithNonGFormat (f fmt v) true (isPositive v) w prefix padChar - - /// rightJustify handler for f: 'T -> string - basic integer types - let inline rightJustify f (prefixForPositives: string) padChar isUnsigned = + /// Right justification handler for f: 'T -> string - basic integer types + let rightJustify f (prefixForPositives: string) padChar isUnsigned = if isUnsigned then if padChar = '0' then - fun (w: int) v -> - rightJustifyWithZeroAsPadChar (f v) true true w prefixForPositives + fun (w: int) (v: obj) -> + GenericNumber.rightJustifyWithZeroAsPadChar (f v) true true w prefixForPositives else System.Diagnostics.Debug.Assert((padChar = ' ')) - fun (w: int) v -> - rightJustifyWithSpaceAsPadChar (f v) true true w prefixForPositives + fun (w: int) (v: obj) -> + GenericNumber.rightJustifyWithSpaceAsPadChar (f v) true true w prefixForPositives else if padChar = '0' then - fun (w: int) v -> - rightJustifyWithZeroAsPadChar (f v) true (isPositive v) w prefixForPositives + fun (w: int) (v: obj) -> + GenericNumber.rightJustifyWithZeroAsPadChar (f v) true (GenericNumber.isPositive v) w prefixForPositives else System.Diagnostics.Debug.Assert((padChar = ' ')) fun (w: int) v -> - rightJustifyWithSpaceAsPadChar (f v) true (isPositive v) w prefixForPositives - - /// rightJustify handler for f: string -> 'T -> string - floating point types - let inline rightJustifyWithFormat f (prefixForPositives: string) padChar = - if padChar = '0' then - fun (fmt: string) (w: int) v -> - rightJustifyWithZeroAsPadChar (f fmt v) true (isPositive v) w prefixForPositives - - else - System.Diagnostics.Debug.Assert((padChar = ' ')) - fun (fmt: string) (w: int) v -> - rightJustifyWithSpaceAsPadChar (f fmt v) true (isPositive v) w prefixForPositives - module Float = - let inline noJustification f (prefixForPositives: string) = - fun (fmt: string) v -> - GenericNumber.noJustificationCore (f fmt v) (isNumber v) (isPositive v) prefixForPositives + GenericNumber.rightJustifyWithSpaceAsPadChar (f v) true (GenericNumber.isPositive v) w prefixForPositives + + /// Computes a new function from 'f' that wraps the basic conversion given + /// by 'f' with padding for 0, spacing and justification, if the flags specify + /// it. If they don't, f is made into a value converter + let withPadding (spec: FormatSpecifier) isUnsigned (f: obj -> string) = + let allowZeroPadding = not (isLeftJustify spec.Flags) || spec.IsDecimalFormat + let padChar, prefix = spec.GetPadAndPrefix allowZeroPadding + Padding.withPadding spec + (GenericNumber.noJustification f prefix isUnsigned) + (leftJustify spec.IsGFormat f prefix padChar isUnsigned) + (rightJustify f prefix padChar isUnsigned) + + let getValueConverter (spec: FormatSpecifier) : ValueConverter = + match spec.TypeChar with + | 'd' | 'i' -> + withPadding spec false toString + | 'u' -> + withPadding spec true (toUnsigned >> toString) + | 'x' -> + withPadding spec true (toFormattedString "x") + | 'X' -> + withPadding spec true (toFormattedString "X") + | 'o' -> + withPadding spec true (fun (v: obj) -> + // Convert.ToInt64 throws for uint64 with values above int64 range so cast directly + match toUnsigned v with + | :? uint64 as u -> Convert.ToString(int64 u, 8) + | u -> Convert.ToString(Convert.ToInt64 u, 8)) + | 'B' -> + withPadding spec true (fun (v: obj) -> + match toUnsigned v with + | :? uint64 as u -> Convert.ToString(int64 u, 2) + | u -> Convert.ToString(Convert.ToInt64 u, 2)) + | _ -> invalidArg (nameof spec) "Invalid integer format" + + module FloatAndDecimal = + + let rec toFormattedString fmt (v: obj) = + match v with + | :? single as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? double as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | :? decimal as n -> n.ToString(fmt, CultureInfo.InvariantCulture) + | _ -> failwith "toFormattedString: unreachable" + + let isNumber (x: obj) = + match x with + | :? single as x -> + not (Single.IsPositiveInfinity(x)) && + not (Single.IsNegativeInfinity(x)) && + not (Single.IsNaN(x)) + | :? double as x -> + not (Double.IsPositiveInfinity(x)) && + not (Double.IsNegativeInfinity(x)) && + not (Double.IsNaN(x)) + | :? decimal -> true + | _ -> failwith "isNumber: unreachable" + + let isInteger (n: obj) = + match n with + | :? single as n -> n % 1.0f = 0.0f + | :? double as n -> n % 1. = 0. + | :? decimal as n -> n % 1.0M = 0.0M + | _ -> failwith "isInteger: unreachable" + + let noJustification (prefixForPositives: string) = + fun (fmt: string) (v: obj) -> + GenericNumber.noJustificationCore (toFormattedString fmt v) (isNumber v) (GenericNumber.isPositive v) prefixForPositives - let inline leftJustify isGFormat f (prefix: string) padChar = + let leftJustify isGFormat (prefix: string) padChar = if isGFormat then - fun (fmt: string) (w: int) v -> - GenericNumber.leftJustifyWithGFormat (f fmt v) (isNumber v) (isInteger v) (isPositive v) w prefix padChar + fun (fmt: string) (w: int) (v: obj) -> + GenericNumber.leftJustifyWithGFormat (toFormattedString fmt v) (isNumber v) (isInteger v) (GenericNumber.isPositive v) w prefix padChar else - fun (fmt: string) (w: int) v -> - GenericNumber.leftJustifyWithNonGFormat (f fmt v) (isNumber v) (isPositive v) w prefix padChar + fun (fmt: string) (w: int) (v: obj) -> + GenericNumber.leftJustifyWithNonGFormat (toFormattedString fmt v) (isNumber v) (GenericNumber.isPositive v) w prefix padChar - let inline rightJustify f (prefixForPositives: string) padChar = + let rightJustify (prefixForPositives: string) padChar = if padChar = '0' then - fun (fmt: string) (w: int) v -> - GenericNumber.rightJustifyWithZeroAsPadChar (f fmt v) (isNumber v) (isPositive v) w prefixForPositives + fun (fmt: string) (w: int) (v: obj) -> + GenericNumber.rightJustifyWithZeroAsPadChar (toFormattedString fmt v) (isNumber v) (GenericNumber.isPositive v) w prefixForPositives else System.Diagnostics.Debug.Assert((padChar = ' ')) - fun (fmt: string) (w: int) v -> - GenericNumber.rightJustifyWithSpaceAsPadChar (f fmt v) (isNumber v) (isPositive v) w prefixForPositives - - let isDecimalFormatSpecifier (spec: FormatSpecifier) = - spec.TypeChar = 'M' - - let getPadAndPrefix allowZeroPadding (spec: FormatSpecifier) = - let padChar = if allowZeroPadding && isPadWithZeros spec.Flags then '0' else ' '; - let prefix = - if isPlusForPositives spec.Flags then "+" - elif isSpaceForPositives spec.Flags then " " - else "" - padChar, prefix - - let isGFormat(spec: FormatSpecifier) = - isDecimalFormatSpecifier spec || System.Char.ToLower(spec.TypeChar) = 'g' - - let inline basicWithPadding (spec: FormatSpecifier) f = - let padChar, _ = getPadAndPrefix false spec - Padding.withPadding spec f (Basic.leftJustify f padChar) (Basic.rightJustify f padChar) - - let inline numWithPadding (spec: FormatSpecifier) isUnsigned f = - let allowZeroPadding = not (isLeftJustify spec.Flags) || isDecimalFormatSpecifier spec - let padChar, prefix = getPadAndPrefix allowZeroPadding spec - let isGFormat = isGFormat spec - Padding.withPadding spec (GenericNumber.noJustification f prefix isUnsigned) (GenericNumber.leftJustify isGFormat f prefix padChar isUnsigned) (GenericNumber.rightJustify f prefix padChar isUnsigned) - - let inline decimalWithPadding (spec: FormatSpecifier) getFormat defaultFormat f = - let padChar, prefix = getPadAndPrefix true spec - let isGFormat = isGFormat spec - Padding.withPaddingFormatted spec getFormat defaultFormat (GenericNumber.noJustificationWithFormat f prefix) (GenericNumber.leftJustifyWithFormat isGFormat f prefix padChar) (GenericNumber.rightJustifyWithFormat f prefix padChar) - - let inline floatWithPadding (spec: FormatSpecifier) getFormat defaultFormat f = - let padChar, prefix = getPadAndPrefix true spec - let isGFormat = isGFormat spec - Padding.withPaddingFormatted spec getFormat defaultFormat (Float.noJustification f prefix) (Float.leftJustify isGFormat f prefix padChar) (Float.rightJustify f prefix padChar) - - let inline identity v = v - let inline toString v = (^T : (member ToString: IFormatProvider -> string)(v, invariantCulture)) - let inline toFormattedString fmt = fun (v: ^T) -> (^T: (member ToString: string * IFormatProvider -> string)(v, fmt, invariantCulture)) - - let inline numberToString c spec alt unsignedConv = - if c = 'd' || c = 'i' then - numWithPadding spec false (alt >> toString: ^T -> string) - elif c = 'u' then - numWithPadding spec true (alt >> unsignedConv >> toString: ^T -> string) - elif c = 'x' then - numWithPadding spec true (alt >> toFormattedString "x": ^T -> string) - elif c = 'X' then - numWithPadding spec true (alt >> toFormattedString "X": ^T -> string ) - elif c = 'o' then - numWithPadding spec true (fun (v: ^T) -> Convert.ToString(int64(unsignedConv (alt v)), 8)) - else raise (ArgumentException()) - + fun (fmt: string) (w: int) (v: obj) -> + GenericNumber.rightJustifyWithSpaceAsPadChar (toFormattedString fmt v) (isNumber v) (GenericNumber.isPositive v) w prefixForPositives + + let withPadding (spec: FormatSpecifier) getFormat defaultFormat = + let padChar, prefix = spec.GetPadAndPrefix true + Padding.withPaddingFormatted spec getFormat defaultFormat + (noJustification prefix) + (leftJustify spec.IsGFormat prefix padChar) + (rightJustify prefix padChar) + type ObjectPrinter = - static member ObjectToString<'T>(spec: FormatSpecifier) = - basicWithPadding spec (fun (v: 'T) -> match box v with null -> "" | x -> x.ToString()) + + static member ObjectToString(spec: FormatSpecifier) : ValueConverter = + Basic.withPadding spec (fun (v: obj) -> + match v with + | null -> "" + | x -> x.ToString()) + + /// Convert an interpoland to a string + static member InterpolandToString(spec: FormatSpecifier) : ValueConverter = + let fmt = + match spec.InteropHoleDotNetFormat with + | ValueNone -> null + | ValueSome fmt -> "{0:" + fmt + "}" + Basic.withPadding spec (fun (vobj: obj) -> + match vobj with + | null -> "" + | x -> + match fmt with + | null -> x.ToString() + | fmt -> String.Format(fmt, x)) static member GenericToStringCore(v: 'T, opts: Microsoft.FSharp.Text.StructuredPrintfImpl.FormatOptions, bindingFlags) = - // printfn %0A is considered to mean 'print width zero' - match box v with - | null -> "" - | _ -> Microsoft.FSharp.Text.StructuredPrintfImpl.Display.anyToStringForPrintf opts bindingFlags (v, v.GetType()) + let vty = + match box v with + | null -> typeof<'T> + | _ -> v.GetType() + Microsoft.FSharp.Text.StructuredPrintfImpl.Display.anyToStringForPrintf opts bindingFlags (v, vty) - static member GenericToString<'T>(spec: FormatSpecifier) = + static member GenericToString<'T>(spec: FormatSpecifier) : ValueConverter = let bindingFlags = if isPlusForPositives spec.Flags then BindingFlags.Public ||| BindingFlags.NonPublic else BindingFlags.Public @@ -1077,100 +943,70 @@ module internal PrintfImpl = else o if spec.IsPrecisionSpecified then { o with PrintSize = spec.Precision} else o + match spec.IsStarWidth, spec.IsStarPrecision with | true, true -> - box (fun (v: 'T) (width: int) (prec: int) -> + ValueConverter.Make (fun (vobj: obj) (width: int) (prec: int) -> + let v = unbox<'T> vobj let opts = { opts with PrintSize = prec } let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) ) + | true, false -> - box (fun (v: 'T) (width: int) -> + ValueConverter.Make (fun (vobj: obj) (width: int) -> + let v = unbox<'T> vobj let opts = if not useZeroWidth then { opts with PrintWidth = width} else opts - ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) - ) + ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)) + | false, true -> - box (fun (v: 'T) (prec: int) -> + ValueConverter.Make (fun (vobj: obj) (prec: int) -> + let v = unbox<'T> vobj let opts = { opts with PrintSize = prec } - ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) - ) - | false, false -> - box (fun (v: 'T) -> - ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) - ) - - let basicNumberToString (ty: Type) (spec: FormatSpecifier) = - System.Diagnostics.Debug.Assert(not spec.IsPrecisionSpecified, "not spec.IsPrecisionSpecified") - - let ch = spec.TypeChar - - match Type.GetTypeCode ty with - | TypeCode.Int32 -> numberToString ch spec identity (uint32: int -> uint32) - | TypeCode.Int64 -> numberToString ch spec identity (uint64: int64 -> uint64) - | TypeCode.Byte -> numberToString ch spec identity (byte: byte -> byte) - | TypeCode.SByte -> numberToString ch spec identity (byte: sbyte -> byte) - | TypeCode.Int16 -> numberToString ch spec identity (uint16: int16 -> uint16) - | TypeCode.UInt16 -> numberToString ch spec identity (uint16: uint16 -> uint16) - | TypeCode.UInt32 -> numberToString ch spec identity (uint32: uint32 -> uint32) - | TypeCode.UInt64 -> numberToString ch spec identity (uint64: uint64 -> uint64) - | _ -> - if ty === typeof then - if IntPtr.Size = 4 then - numberToString ch spec (fun (v: IntPtr) -> v.ToInt32()) uint32 - else - numberToString ch spec (fun (v: IntPtr) -> v.ToInt64()) uint64 - elif ty === typeof then - if IntPtr.Size = 4 then - numberToString ch spec (fun (v: UIntPtr) -> v.ToUInt32()) uint32 - else - numberToString ch spec (fun (v: UIntPtr) -> v.ToUInt64()) uint64 + ObjectPrinter.GenericToStringCore(v, opts, bindingFlags) ) - else raise (ArgumentException(ty.Name + " not a basic integer type")) - - let basicFloatToString ty spec = + | false, false -> + ValueConverter.Make (fun (vobj: obj) -> + let v = unbox<'T> vobj + ObjectPrinter.GenericToStringCore(v, opts, bindingFlags)) + + let basicFloatToString spec = let defaultFormat = getFormatForFloat spec.TypeChar DefaultPrecision - match Type.GetTypeCode ty with - | TypeCode.Single -> floatWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v: float32) -> toFormattedString fmt v) - | TypeCode.Double -> floatWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v: float) -> toFormattedString fmt v) - | TypeCode.Decimal -> decimalWithPadding spec (getFormatForFloat spec.TypeChar) defaultFormat (fun fmt (v: decimal) -> toFormattedString fmt v) - | _ -> raise (ArgumentException(ty.Name + " not a basic floating point type")) + FloatAndDecimal.withPadding spec (getFormatForFloat spec.TypeChar) defaultFormat let private NonPublicStatics = BindingFlags.NonPublic ||| BindingFlags.Static - let private getValueConverter (ty: Type) (spec: FormatSpecifier) : obj = + let mi_GenericToString = typeof.GetMethod("GenericToString", NonPublicStatics) + + let private getValueConverter (ty: Type) (spec: FormatSpecifier) : ValueConverter = match spec.TypeChar with | 'b' -> - System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof") - basicWithPadding spec boolToString + Basic.withPadding spec (unbox >> boolToString) | 's' -> - System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof") - basicWithPadding spec stringToSafeString + Basic.withPadding spec (unbox >> stringToSafeString) | 'c' -> - System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof") - basicWithPadding spec (fun (c: char) -> c.ToString()) + Basic.withPadding spec (fun (c: obj) -> (unbox c).ToString()) | 'M' -> - System.Diagnostics.Debug.Assert(ty === typeof, "ty === typeof") - decimalWithPadding spec (fun _ -> "G") "G" (fun fmt (v: decimal) -> toFormattedString fmt v) // %M ignores precision - | 'd' | 'i' | 'x' | 'X' | 'u' | 'o'-> - basicNumberToString ty spec + FloatAndDecimal.withPadding spec (fun _ -> "G") "G" // %M ignores precision + | 'd' | 'i' | 'u' | 'B' | 'o' | 'x' | 'X' -> + Integer.getValueConverter spec | 'e' | 'E' | 'f' | 'F' | 'g' | 'G' -> - basicFloatToString ty spec + basicFloatToString spec | 'A' -> - let mi = typeof.GetMethod("GenericToString", NonPublicStatics) - let mi = mi.MakeGenericMethod ty - mi.Invoke(null, [| box spec |]) + let mi = mi_GenericToString.MakeGenericMethod ty + mi.Invoke(null, [| box spec |]) |> unbox | 'O' -> - let mi = typeof.GetMethod("ObjectToString", NonPublicStatics) - let mi = mi.MakeGenericMethod ty - mi.Invoke(null, [| box spec |]) + ObjectPrinter.ObjectToString(spec) + | 'P' -> + ObjectPrinter.InterpolandToString(spec) | _ -> raise (ArgumentException(SR.GetString(SR.printfBadFormatSpecifier))) let extractCurriedArguments (ty: Type) n = System.Diagnostics.Debug.Assert(n = 1 || n = 2 || n = 3, "n = 1 || n = 2 || n = 3") - let buf = Array.zeroCreate (n + 1) + let buf = Array.zeroCreate n let rec go (ty: Type) i = if i < n then match ty.GetGenericArguments() with @@ -1180,470 +1016,440 @@ module internal PrintfImpl = | _ -> failwith (String.Format("Expected function with {0} arguments", n)) else System.Diagnostics.Debug.Assert((i = n), "i = n") - buf.[i] <- ty - buf + (buf, ty) go ty 0 - - type private PrintfBuilderStack() = - let args = Stack 10 - let types = Stack 5 - - let stackToArray size start count (s: Stack<_>) = - let arr = Array.zeroCreate size - for i = 0 to count - 1 do - arr.[start + i] <- s.Pop() - arr - - member __.GetArgumentAndTypesAsArrays - ( - argsArraySize, argsArrayStartPos, argsArrayTotalCount, - typesArraySize, typesArrayStartPos, typesArrayTotalCount - ) = - let argsArray = stackToArray argsArraySize argsArrayStartPos argsArrayTotalCount args - let typesArray = stackToArray typesArraySize typesArrayStartPos typesArrayTotalCount types - argsArray, typesArray - - member __.PopContinuationWithType() = - System.Diagnostics.Debug.Assert(args.Count = 1, "args.Count = 1") - System.Diagnostics.Debug.Assert(types.Count = 1, "types.Count = 1") - - let cont = args.Pop() - let contTy = types.Pop() - - cont, contTy - - member __.PopValueUnsafe() = args.Pop() - member this.PushContinuationWithType (cont: obj, contTy: Type) = - System.Diagnostics.Debug.Assert(this.IsEmpty, "this.IsEmpty") - System.Diagnostics.Debug.Assert( - ( - let _arg, retTy = Microsoft.FSharp.Reflection.FSharpType.GetFunctionElements(cont.GetType()) - contTy.IsAssignableFrom retTy - ), - "incorrect type" - ) - this.PushArgumentWithType(cont, contTy) + type LargeStringPrintfEnv<'Result>(continuation, blockSize) = + inherit PrintfEnv(()) + let buf: string[] = Array.zeroCreate blockSize + let mutable ptr = 0 - member __.PushArgument(value: obj) = - args.Push value + override _.Finish() : 'Result = continuation (String.Concat buf) - member __.PushArgumentWithType(value: obj, ty) = - args.Push value - types.Push ty + override _.Write(s: string) = + buf.[ptr] <- s + ptr <- ptr + 1 - member __.HasContinuationOnStack expectedNumberOfArguments = - types.Count = expectedNumberOfArguments + 1 + override x.WriteT s = x.Write(s) - member __.IsEmpty = - System.Diagnostics.Debug.Assert(args.Count = types.Count, "args.Count = types.Count") - args.Count = 0 + type SmallStringPrintfEnv2() = + inherit PrintfEnv(()) + let mutable c = null - /// Parses format string and creates result printer function. - /// First it recursively consumes format string up to the end, then during unwinding builds printer using PrintfBuilderStack as storage for arguments. - /// idea of implementation is very simple: every step can either push argument to the stack (if current block of 5 format specifiers is not yet filled) - // or grab the content of stack, build intermediate printer and push it back to stack (so it can later be consumed by as argument) - type private PrintfBuilder<'S, 'Re, 'Res>() = + override _.Finish() : string = if isNull c then "" else c + override _.Write(s: string) = if isNull c then c <- s else c <- c + s + override x.WriteT s = x.Write(s) + + type SmallStringPrintfEnv4() = + inherit PrintfEnv(()) + let mutable s1 : string = null + let mutable s2 : string = null + let mutable s3 : string = null + let mutable s4 : string = null + + override _.Finish() : string = String.Concat(s1, s2, s3, s4) + override _.Write(s: string) = + if isNull s1 then s1 <- s + elif isNull s2 then s2 <- s + elif isNull s3 then s3 <- s + else s4 <- s + override x.WriteT s = x.Write(s) + + let StringPrintfEnv blockSize = + if blockSize <= 2 then + SmallStringPrintfEnv2() :> PrintfEnv<_,_,_> + elif blockSize <= 4 then + SmallStringPrintfEnv4() :> PrintfEnv<_,_,_> + else + LargeStringPrintfEnv(id, blockSize) :> PrintfEnv<_,_,_> + + let StringBuilderPrintfEnv<'Result>(k, buf) = + { new PrintfEnv(buf) with + override _.Finish() : 'Result = k () + override _.Write(s: string) = ignore(buf.Append s) + override _.WriteT(()) = () } + + let TextWriterPrintfEnv<'Result>(k, tw: IO.TextWriter) = + { new PrintfEnv(tw) with + override _.Finish() : 'Result = k() + override _.Write(s: string) = tw.Write s + override _.WriteT(()) = () } + + let MAX_CAPTURE = 3 + + /// Parses format string and creates resulting step list and printer factory function. + [] + type FormatParser<'Printer, 'State, 'Residue, 'Result>(fmt: string) = - let mutable count = 0 - let mutable optimizedArgCount = 0 -#if DEBUG - let verifyMethodInfoWasTaken (mi: System.Reflection.MemberInfo) = - if isNull mi then - ignore (System.Diagnostics.Debugger.Launch()) -#endif - - let buildSpecialChained(spec: FormatSpecifier, argTys: Type[], prefix: string, tail: obj, retTy) = + let buildCaptureFunc (spec: FormatSpecifier, allSteps, argTys: Type[], retTy, nextInfo) = + let (next:obj, nextCanCombine: bool, nextArgTys: Type[], nextRetTy, nextNextOpt) = nextInfo + assert (argTys.Length > 0) + + // See if we can compress a capture to a multi-capture + // CaptureN + Final --> CaptureFinalN + // Capture1 + Capture1 --> Capture2 + // Capture1 + Capture2 --> Capture3 + // Capture2 + Capture1 --> Capture3 + match argTys.Length, nextArgTys.Length with + | _ when spec.TypeChar = 'a' -> + // %a has an existential type which must be converted to obj + assert (argTys.Length = 2) + let captureMethName = "CaptureLittleA" + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod([| argTys.[1]; retTy |]) + let factoryObj = mi.Invoke(null, [| next |]) + factoryObj, false, argTys, retTy, None + + | n1, n2 when nextCanCombine && n1 + n2 <= MAX_CAPTURE -> + // 'next' is thrown away on this path and replaced by a combined Capture + let captureCount = n1 + n2 + let combinedArgTys = Array.append argTys nextArgTys + match nextNextOpt with + | None -> + let captureMethName = "CaptureFinal" + string captureCount + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod(combinedArgTys) + let factoryObj = mi.Invoke(null, [| allSteps |]) + factoryObj, true, combinedArgTys, nextRetTy, None + | Some nextNext -> + let captureMethName = "Capture" + string captureCount + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod(Array.append combinedArgTys [| nextRetTy |]) + let factoryObj = mi.Invoke(null, [| nextNext |]) + factoryObj, true, combinedArgTys, nextRetTy, nextNextOpt + + | captureCount, _ -> + let captureMethName = "Capture" + string captureCount + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod(Array.append argTys [| retTy |]) + let factoryObj = mi.Invoke(null, [| next |]) + factoryObj, true, argTys, retTy, Some next + + let buildStep (spec: FormatSpecifier) (argTys: Type[]) prefix = if spec.TypeChar = 'a' then - let mi = typeof>.GetMethod("LittleAChained", NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - - let mi = mi.MakeGenericMethod([| argTys.[1]; retTy |]) - let args = [| box prefix; tail |] - mi.Invoke(null, args) + StepLittleA prefix elif spec.TypeChar = 't' then - let mi = typeof>.GetMethod("TChained", NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let mi = mi.MakeGenericMethod([| retTy |]) - let args = [| box prefix; tail |] - mi.Invoke(null, args) - else - System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth, "spec.IsStarPrecision || spec.IsStarWidth ") - - let mi = - let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1 - let prefix = if spec.TypeChar = '%' then "PercentStarChained" else "StarChained" - let name = prefix + (string n) - typeof>.GetMethod(name, NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let argTypes, args = - if spec.TypeChar = '%' then - [| retTy |], [| box prefix; tail |] + StepLittleT prefix + elif spec.IsStarPrecision || spec.IsStarWidth then + let isTwoStar = (spec.IsStarWidth = spec.IsStarPrecision) + match isTwoStar, spec.TypeChar with + | false, '%' -> StepPercentStar1 prefix + | true, '%' -> StepPercentStar2 prefix + | _ -> + // For curried interpolated string format processing, the static types of the '%A' arguments + // are provided via the argument typed extracted from the curried function. They are known on first phase. + let argTy = match argTys with null -> typeof | _ -> argTys.[argTys.Length - 1] + let conv = getValueConverter argTy spec + if isTwoStar then + let convFunc = conv.FuncObj :?> (obj -> int -> int -> string) + StepStar2 (prefix, convFunc) else - let argTy = argTys.[argTys.Length - 2] - let conv = getValueConverter argTy spec - [| argTy; retTy |], [| box prefix; box conv; tail |] - - let mi = mi.MakeGenericMethod argTypes - mi.Invoke(null, args) - - let buildSpecialFinal(spec: FormatSpecifier, argTys: Type[], prefix: string, suffix: string) = - if spec.TypeChar = 'a' then - let mi = typeof>.GetMethod("LittleAFinal", NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let mi = mi.MakeGenericMethod(argTys.[1] : Type) - let args = [| box prefix; box suffix |] - mi.Invoke(null, args) - elif spec.TypeChar = 't' then - let mi = typeof>.GetMethod("TFinal", NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let args = [| box prefix; box suffix |] - mi.Invoke(null, args) + let convFunc = conv.FuncObj :?> (obj -> int -> string) + StepStar1 (prefix, convFunc) else - System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth, "spec.IsStarPrecision || spec.IsStarWidth ") - - let mi = - let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1 - let prefix = if spec.TypeChar = '%' then "PercentStarFinal" else "StarFinal" - let name = prefix + (string n) - typeof>.GetMethod(name, NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - - let mi, args = - if spec.TypeChar = '%' then - mi, [| box prefix; box suffix |] - else - let argTy = argTys.[argTys.Length - 2] - let mi = mi.MakeGenericMethod argTy - let conv = getValueConverter argTy spec - mi, [| box prefix; box conv; box suffix |] - - mi.Invoke(null, args) - - let buildPlainFinal(args: obj[], argTypes: Type[]) = - let argsCount = args.Length - let methodName,args = - if argsCount > 0 && args.[0].ToString() = "" then - if argsCount > 1 && args.[argsCount - 1].ToString() = "" then - let args = Array.sub args 1 (argsCount - 2) - optimizedArgCount <- optimizedArgCount + 2 - "FinalFast", args - else - optimizedArgCount <- optimizedArgCount + 1 - "FinalFastStart", args |> Array.skip 1 - elif argsCount > 0 && args.[argsCount - 1].ToString() = "" then - let args = Array.sub args 0 (argsCount - 1) - optimizedArgCount <- optimizedArgCount + 1 - "FinalFastEnd", args - else - "Final",args - - let mi = typeof>.GetMethod(methodName + argTypes.Length.ToString(), NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let mi = mi.MakeGenericMethod argTypes - mi.Invoke(null, args) - - let buildPlainChained(args: obj[], argTypes: Type[]) = - let argsCount = args.Length - let methodName,args = - if argsCount > 0 && args.[0].ToString() = "" then - optimizedArgCount <- optimizedArgCount + 1 - "ChainedFastStart", args |> Array.skip 1 - else - "Chained", args - - let mi = typeof>.GetMethod(methodName + (argTypes.Length - 1).ToString(), NonPublicStatics) -#if DEBUG - verifyMethodInfoWasTaken mi -#endif - let mi = mi.MakeGenericMethod argTypes - mi.Invoke(null, args) - - let builderStack = PrintfBuilderStack() - - let ContinuationOnStack = -1 - - let buildPlain numberOfArgs prefix = - let n = numberOfArgs * 2 - let hasCont = builderStack.HasContinuationOnStack numberOfArgs - - let extra = if hasCont then 1 else 0 - let plainArgs, plainTypes = - builderStack.GetArgumentAndTypesAsArrays(n + 1, 1, n, (numberOfArgs + extra), 0, numberOfArgs) - - plainArgs.[0] <- box prefix - - if hasCont then - let cont, contTy = builderStack.PopContinuationWithType() - plainArgs.[plainArgs.Length - 1] <- cont - plainTypes.[plainTypes.Length - 1] <- contTy - - buildPlainChained(plainArgs, plainTypes) + // For interpolated string format processing, the static types of the '%A' arguments + // are provided via CaptureTypes and are only known on second phase. + match argTys with + | null when spec.TypeChar = 'A' -> + let convFunc arg argTy = + let mi = mi_GenericToString.MakeGenericMethod [| argTy |] + let f = mi.Invoke(null, [| box spec |]) :?> ValueConverter + let f2 = f.FuncObj :?> (obj -> string) + f2 arg + + StepWithTypedArg (prefix, convFunc) + + | _ -> + // For curried interpolated string format processing, the static types of the '%A' arguments + // are provided via the argument typed extracted from the curried function. They are known on first phase. + let argTy = match argTys with null -> typeof | _ -> argTys.[0] + let conv = getValueConverter argTy spec + let convFunc = conv.FuncObj :?> (obj -> string) + StepWithArg (prefix, convFunc) + + let parseSpec (i: byref) = + i <- i + 1 + let flags = FormatString.parseFlags fmt &i + let width = FormatString.parseWidth fmt &i + let precision = FormatString.parsePrecision fmt &i + let typeChar = FormatString.parseTypeChar fmt &i + let interpHoleDotnetFormat = FormatString.parseInterpolatedHoleDotNetFormat typeChar fmt &i + + // Skip %P insertion points added after %d{...} etc. in interpolated strings + FormatString.skipInterpolationHole typeChar fmt &i + + let spec = + { TypeChar = typeChar + Precision = precision + Flags = flags + Width = width + InteropHoleDotNetFormat = interpHoleDotnetFormat } + spec + + // The steps, populated on-demand. This is for the case where the string is being used + // with interpolands captured in the Format object, including the %A capture types. + // + // We may initialize this twice, but the assignment is atomic and the computation will give functionally + // identical results each time, so it is ok. + let mutable stepsForCapturedFormat = Unchecked.defaultof<_> + + // The function factory, populated on-demand, for the case where the string is being used to make a curried function for printf. + // + // We may initialize this twice, but the assignment is atomic and the computation will give functionally + // identical results each time, so it is ok. + let mutable factory = Unchecked.defaultof> + let mutable printer = Unchecked.defaultof<'Printer> + + // The function factory, populated on-demand. + // + // We may initialize this twice, but the assignment is atomic and the computation will give functionally + // identical results each time, so it is ok. + let mutable stringCount = 0 + + // A simplified parser. For the case where the string is being used with interpolands captured in the Format object. + let rec parseAndCreateStepsForCapturedFormatAux steps (prefix: string) (i: byref) = + if i >= fmt.Length then + let step = StepString(prefix) + let allSteps = revToArray 1 steps + allSteps.[allSteps.Length-1] <- step + stringCount <- Step.BlockCount allSteps + stepsForCapturedFormat <- allSteps else - buildPlainFinal(plainArgs, plainTypes) - - let rec parseFromFormatSpecifier (prefix: string) (s: string) (funcTy: Type) i: int = + let spec = parseSpec &i + let suffix = FormatString.findNextFormatSpecifier fmt &i + let step = buildStep spec null prefix + parseAndCreateStepsForCapturedFormatAux (step::steps) suffix &i + + let parseAndCreateStepsForCapturedFormat () = + let mutable i = 0 + let prefix = FormatString.findNextFormatSpecifier fmt &i + parseAndCreateStepsForCapturedFormatAux [] prefix &i + + /// The more advanced parser which both builds the steps (with %A types extracted from the funcTy), + /// and produces a curried function value of the right type guided by funcTy + let rec parseAndCreateFuncFactoryAux steps (prefix: string) (funcTy: Type) (i: byref) = - if i >= s.Length then 0 + if i >= fmt.Length then + let step = StepString(prefix) + let allSteps = revToArray 1 steps + allSteps.[allSteps.Length-1] <- step + let last = Specializations<'State, 'Residue, 'Result>.Final0(allSteps) + stringCount <- Step.BlockCount allSteps + let nextInfo = (box last, true, [| |], funcTy, None) + (allSteps, nextInfo) else + assert (fmt.[i] = '%') + let spec = parseSpec &i + let suffix = FormatString.findNextFormatSpecifier fmt &i + let n = spec.ArgCount + let (argTys, retTy) = extractCurriedArguments funcTy n + let step = buildStep spec argTys prefix + let (allSteps, nextInfo) = parseAndCreateFuncFactoryAux (step::steps) suffix retTy &i + let nextInfoNew = buildCaptureFunc (spec, allSteps, argTys, retTy, nextInfo) + (allSteps, nextInfoNew) + + let parseAndCreateFunctionFactory () = + let funcTy = typeof<'Printer> + + // Find the first format specifier + let mutable i = 0 + let prefix = FormatString.findNextFormatSpecifier fmt &i - System.Diagnostics.Debug.Assert(s.[i] = '%', "s.[i] = '%'") - count <- count + 1 - - let flags, i = FormatString.parseFlags s (i + 1) - let width, i = FormatString.parseWidth s i - let precision, i = FormatString.parsePrecision s i - let typeChar, i = FormatString.parseTypeChar s i - let spec = { TypeChar = typeChar; Precision = precision; Flags = flags; Width = width} + let (allSteps, (factoryObj, _, combinedArgTys, _, _)) = parseAndCreateFuncFactoryAux [] prefix funcTy &i - let next, suffix = FormatString.findNextFormatSpecifier s i - - let argTys = - let n = - if spec.TypeChar = 'a' then 2 - elif spec.IsStarWidth || spec.IsStarPrecision then - if spec.IsStarWidth = spec.IsStarPrecision then 3 - else 2 - else 1 - - let n = if spec.TypeChar = '%' then n - 1 else n - - System.Diagnostics.Debug.Assert(n <> 0, "n <> 0") - - extractCurriedArguments funcTy n - - let retTy = argTys.[argTys.Length - 1] - - let numberOfArgs = parseFromFormatSpecifier suffix s retTy next - - if spec.TypeChar = 'a' || spec.TypeChar = 't' || spec.IsStarWidth || spec.IsStarPrecision then - if numberOfArgs = ContinuationOnStack then - - let cont, contTy = builderStack.PopContinuationWithType() - let currentCont = buildSpecialChained(spec, argTys, prefix, cont, contTy) - builderStack.PushContinuationWithType(currentCont, funcTy) - - ContinuationOnStack - else - if numberOfArgs = 0 then - System.Diagnostics.Debug.Assert(builderStack.IsEmpty, "builderStack.IsEmpty") - - let currentCont = buildSpecialFinal(spec, argTys, prefix, suffix) - builderStack.PushContinuationWithType(currentCont, funcTy) - ContinuationOnStack - else - let hasCont = builderStack.HasContinuationOnStack numberOfArgs - - let expectedNumberOfItemsOnStack = numberOfArgs * 2 - let sizeOfTypesArray = - if hasCont then numberOfArgs + 1 - else numberOfArgs - - let plainArgs, plainTypes = - builderStack.GetArgumentAndTypesAsArrays(expectedNumberOfItemsOnStack + 1, 1, expectedNumberOfItemsOnStack, sizeOfTypesArray, 0, numberOfArgs ) - - plainArgs.[0] <- box suffix - - let next = - if hasCont then - let nextCont, nextContTy = builderStack.PopContinuationWithType() - plainArgs.[plainArgs.Length - 1] <- nextCont - plainTypes.[plainTypes.Length - 1] <- nextContTy - buildPlainChained(plainArgs, plainTypes) - else - buildPlainFinal(plainArgs, plainTypes) - - let next = buildSpecialChained(spec, argTys, prefix, next, retTy) - builderStack.PushContinuationWithType(next, funcTy) - - ContinuationOnStack - else - if numberOfArgs = ContinuationOnStack then - let idx = argTys.Length - 2 - builderStack.PushArgument suffix - builderStack.PushArgumentWithType((getValueConverter argTys.[idx] spec), argTys.[idx]) - 1 - else - builderStack.PushArgument suffix - builderStack.PushArgumentWithType((getValueConverter argTys.[0] spec), argTys.[0]) - - if numberOfArgs = MaxArgumentsInSpecialization - 1 then - let cont = buildPlain (numberOfArgs + 1) prefix - builderStack.PushContinuationWithType(cont, funcTy) - ContinuationOnStack - else - numberOfArgs + 1 - - let parseFormatString (s: string) (funcTy: System.Type) : obj = - optimizedArgCount <- 0 - let prefixPos, prefix = FormatString.findNextFormatSpecifier s 0 - if prefixPos = s.Length then - box (fun (env: unit -> PrintfEnv<'S, 'Re, 'Res>) -> - let env = env() - env.Write prefix + // If there are no format specifiers then take a simple path + match allSteps with + | [| StepString prefix |] -> + PrintfFuncFactory<_, 'State, 'Residue, 'Result>(fun _args initial -> + let env = initial() + env.WriteSkipEmpty prefix env.Finish() - ) - else - let n = parseFromFormatSpecifier prefix s funcTy prefixPos - - if n = ContinuationOnStack || n = 0 then - builderStack.PopValueUnsafe() - else - buildPlain n prefix - - member __.Build<'T>(s: string) : PrintfFactory<'S, 'Re, 'Res, 'T> * int = - parseFormatString s typeof<'T> :?> _, (2 * count + 1) - optimizedArgCount // second component is used in SprintfEnv as value for internal buffer - - /// Type of element that is stored in cache - /// Pair: factory for the printer + number of text blocks that printer will produce (used to preallocate buffers) - type CachedItem<'T, 'State, 'Residue, 'Result> = PrintfFactory<'State, 'Residue, 'Result, 'T> * int - - /// 2-level cache. - /// 1st-level stores last value that was consumed by the current thread in thread-static field thus providing shortcuts for scenarios when - /// printf is called in tight loop - /// 2nd level is global dictionary that maps format string to the corresponding PrintfFactory - type Cache<'T, 'State, 'Residue, 'Result>() = - static let generate fmt = PrintfBuilder<'State, 'Residue, 'Result>().Build<'T>(fmt) - static let mutable map = System.Collections.Concurrent.ConcurrentDictionary>() - static let getOrAddFunc = Func<_, _>(generate) - static let get (key: string) = map.GetOrAdd(key, getOrAddFunc) - - [] - [] - static val mutable private last: string * CachedItem<'T, 'State, 'Residue, 'Result> + ) |> box + + // If there is one simple format specifier then we can create an even better factory function + | [| StepWithArg (prefix1, conv1); StepString prefix2 |] -> + let captureMethName = "OneStepWithArg" + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod(combinedArgTys) + let factoryObj = mi.Invoke(null, [| box prefix1; box conv1; box prefix2 |]) + factoryObj + + // If there are two simple format specifiers then we can create an even better factory function + | [| StepWithArg (prefix1, conv1); StepWithArg (prefix2, conv2); StepString prefix3 |] -> + let captureMethName = "TwoStepWithArg" + let mi = typeof>.GetMethod(captureMethName, NonPublicStatics) + let mi = mi.MakeGenericMethod(combinedArgTys) + let factoryObj = mi.Invoke(null, [| box prefix1; box conv1; box prefix2; box conv2; box prefix3 |]) + factoryObj + + | _ -> + factoryObj + + /// The format string, used to help identify the cache entry (the cache index types are taken + /// into account as well). + member _.FormatString = fmt + + /// The steps involved in executing the format string when interpolands are captured + /// + /// If %A patterns are involved these steps are only accurate when the %A capture types + /// are given in the format string through interpolation capture. + member _.GetStepsForCapturedFormat() = + match stepsForCapturedFormat with + | null -> parseAndCreateStepsForCapturedFormat () + | _ -> () + stepsForCapturedFormat + + /// The number of strings produced for a sprintf + member _.BlockCount = stringCount + + /// The factory function used to generate the result or the resulting function. + member _.GetCurriedPrinterFactory() = + match box factory with + | null -> + let factoryObj = parseAndCreateFunctionFactory () + let p = (factoryObj :?> PrintfFuncFactory<'Printer, 'State, 'Residue, 'Result>) + // We may initialize this twice, but the assignment is atomic and the computation will give functionally + // identical results each time it is ok + factory <- p + p + | _ -> factory + + /// This avoids reallocation and application of 'initial' for sprintf printers + member this.GetCurriedStringPrinter() = + match box printer with + | null -> + let f = this.GetCurriedPrinterFactory() + let initial() = (StringPrintfEnv stringCount |> box :?> PrintfEnv<'State, 'Residue, 'Result>) + let p = f.Invoke([], initial) + // We may initialize this twice, but the assignment is atomic and the computation will give functionally + // identical results each time it is ok + printer <- p + p + | _ -> printer + + + /// 2-level cache, keyed by format string and index types + type Cache<'Printer, 'State, 'Residue, 'Result>() = + + /// 1st level cache (type-indexed). Stores last value that was consumed by the current thread in + /// thread-static field thus providing shortcuts for scenarios when printf is called in tight loop. + [] + static val mutable private mostRecent: FormatParser<'Printer, 'State, 'Residue, 'Result> - static member Get(key: Format<'T, 'State, 'Residue, 'Result>) = - if not (Cache<'T, 'State, 'Residue, 'Result>.last === null) - && key.Value.Equals (fst Cache<'T, 'State, 'Residue, 'Result>.last) then - snd Cache<'T, 'State, 'Residue, 'Result>.last + // 2nd level cache (type-indexed). Dictionary that maps format string to the corresponding cache entry + static let mutable dict : ConcurrentDictionary> = null + + static member GetParser(format: Format<'Printer, 'State, 'Residue, 'Result>) = + let recent = Cache<'Printer, 'State, 'Residue, 'Result>.mostRecent + let fmt = format.Value + if isNull recent then + let parser = FormatParser(fmt) + Cache<'Printer, 'State, 'Residue, 'Result>.mostRecent <- parser + parser + elif fmt.Equals recent.FormatString then + recent else - let v = get key.Value - Cache<'T, 'State, 'Residue, 'Result>.last <- (key.Value, v) - v - - type StringPrintfEnv<'Result>(k, n) = - inherit PrintfEnv(()) - - let buf: string[] = Array.zeroCreate n - let mutable ptr = 0 - - override __.Finish() : 'Result = k (String.Concat buf) - override __.Write(s: string) = - buf.[ptr] <- s - ptr <- ptr + 1 - override __.WriteT s = - buf.[ptr] <- s - ptr <- ptr + 1 - - type SmallStringPrintfEnv<'Result>(k) = - inherit PrintfEnv(()) - - let mutable c = null - - override __.Finish() : 'Result = k c - override __.Write(s: string) = if isNull c then c <- s else c <- c + s - override __.WriteT s = if isNull c then c <- s else c <- c + s - - type StringBuilderPrintfEnv<'Result>(k, buf) = - inherit PrintfEnv(buf) - override __.Finish() : 'Result = k () - override __.Write(s: string) = ignore(buf.Append s) - override __.WriteT(()) = () - - type TextWriterPrintfEnv<'Result>(k, tw: IO.TextWriter) = - inherit PrintfEnv(tw) - override __.Finish() : 'Result = k() - override __.Write(s: string) = tw.Write s - override __.WriteT(()) = () - - let inline doPrintf fmt f = - let formatter, n = Cache<_, _, _, _>.Get fmt - let env() = f n - formatter env + // Initialize the 2nd level cache if necessary. Note there's a race condition but it doesn't + // matter if we initialize these values twice (and lose one entry) + if isNull dict then + dict <- ConcurrentDictionary<_,_>() + + let parser = + match dict.TryGetValue(fmt) with + | true, res -> res + | _ -> + let parser = FormatParser(fmt) + // There's a race condition - but the computation is functional and it doesn't matter if we do it twice + dict.TryAdd(fmt, parser) |> ignore + parser + Cache<'Printer, 'State, 'Residue, 'Result>.mostRecent <- parser + parser [] module Printf = - open System - open System.IO - open System.Text - open PrintfImpl - - type BuilderFormat<'T,'Result> = Format<'T, StringBuilder, unit, 'Result> - type StringFormat<'T,'Result> = Format<'T, unit, string, 'Result> - type TextWriterFormat<'T,'Result> = Format<'T, TextWriter, unit, 'Result> - type BuilderFormat<'T> = BuilderFormat<'T,unit> - type StringFormat<'T> = StringFormat<'T,string> + type BuilderFormat<'T, 'Result> = Format<'T, StringBuilder, unit, 'Result> + type StringFormat<'T, 'Result> = Format<'T, unit, string, 'Result> + type TextWriterFormat<'T, 'Result> = Format<'T, TextWriter, unit, 'Result> + type BuilderFormat<'T> = BuilderFormat<'T,unit> + type StringFormat<'T> = StringFormat<'T,string> type TextWriterFormat<'T> = TextWriterFormat<'T,unit> + let gprintf envf (format: Format<'Printer, 'State, 'Residue, 'Result>) = + let cacheItem = Cache.GetParser format + match format.Captures with + | null -> + // The ksprintf "...%d ...." arg path, producing a function + let factory = cacheItem.GetCurriedPrinterFactory() + let initial() = (envf cacheItem.BlockCount :> PrintfEnv<_,_,_>) + factory.Invoke([], initial) + | captures -> + // The ksprintf $"...%d{3}...." path, running the steps straight away to produce a string + let steps = cacheItem.GetStepsForCapturedFormat() + let env = envf cacheItem.BlockCount :> PrintfEnv<_,_,_> + let res = env.RunSteps(captures, format.CaptureTypes, steps) + unbox res // prove 'T = 'Result + //continuation res + [] let ksprintf continuation (format: StringFormat<'T, 'Result>) : 'T = - doPrintf format (fun n -> - if n <= 2 then - SmallStringPrintfEnv continuation :> PrintfEnv<_, _, _> - else - StringPrintfEnv(continuation, n) :> PrintfEnv<_, _, _> - ) + gprintf (fun stringCount -> LargeStringPrintfEnv(continuation, stringCount)) format [] let sprintf (format: StringFormat<'T>) = - doPrintf format (fun n -> - if n <= 2 then - SmallStringPrintfEnv id :> PrintfEnv<_, _, _> - else - StringPrintfEnv(id, n) :> PrintfEnv<_, _, _> - ) + // We inline gprintf by hand here to be sure to remove a few allocations + let cacheItem = Cache.GetParser format + match format.Captures with + | null -> + // The sprintf "...%d ...." arg path, producing a function + cacheItem.GetCurriedStringPrinter() + | captures -> + // The sprintf $"...%d{3}...." path, running the steps straight away to produce a string + let steps = cacheItem.GetStepsForCapturedFormat() + let env = StringPrintfEnv cacheItem.BlockCount + let res = env.RunSteps(captures, format.CaptureTypes, steps) + unbox res // proves 'T = string [] let kprintf continuation format = ksprintf continuation format [] - let kbprintf continuation (builder: StringBuilder) format = - doPrintf format (fun _ -> - StringBuilderPrintfEnv(continuation, builder) :> PrintfEnv<_, _, _> - ) + let kbprintf continuation (builder: StringBuilder) (format: BuilderFormat<'T, 'Result>) : 'T = + gprintf (fun _stringCount -> StringBuilderPrintfEnv(continuation, builder)) format [] - let kfprintf continuation textWriter format = - doPrintf format (fun _ -> - TextWriterPrintfEnv(continuation, textWriter) :> PrintfEnv<_, _, _> - ) + let kfprintf continuation textWriter (format: TextWriterFormat<'T, 'Result>) = + gprintf (fun _stringCount -> TextWriterPrintfEnv(continuation, textWriter)) format [] - let bprintf builder format = kbprintf ignore builder format + let bprintf builder format = + kbprintf ignore builder format [] - let fprintf (textWriter: TextWriter) format = kfprintf ignore textWriter format + let fprintf (textWriter: TextWriter) format = + kfprintf ignore textWriter format [] - let fprintfn (textWriter: TextWriter) format = kfprintf (fun _ -> textWriter.WriteLine()) textWriter format + let fprintfn (textWriter: TextWriter) format = + kfprintf (fun _ -> textWriter.WriteLine()) textWriter format [] - let failwithf format = ksprintf failwith format + let failwithf format = + ksprintf failwith format [] - let printf format = fprintf Console.Out format + let printf format = + fprintf Console.Out format [] - let eprintf format = fprintf Console.Error format + let eprintf format = + fprintf Console.Error format [] - let printfn format = fprintfn Console.Out format + let printfn format = + fprintfn Console.Out format [] - let eprintfn format = fprintfn Console.Error format + let eprintfn format = + fprintfn Console.Error format diff --git a/src/fsharp/FSharp.Core/printf.fsi b/src/fsharp/FSharp.Core/printf.fsi index 10e17ec68d8..4508a380f09 100644 --- a/src/fsharp/FSharp.Core/printf.fsi +++ b/src/fsharp/FSharp.Core/printf.fsi @@ -10,40 +10,93 @@ open System.IO open System.Text /// Type of a formatting expression. +/// /// Function type generated by printf. /// Type argument passed to %a formatters /// Value generated by the overall printf action (e.g. sprint generates a string) /// Value generated after post processing (e.g. failwithf generates a string internally then raises an exception) +/// +/// Language Primitives type PrintfFormat<'Printer,'State,'Residue,'Result> = /// Construct a format string /// The input string. + /// /// The PrintfFormat containing the formatted result. + /// + /// new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result> + /// Construct a format string + /// The input string. + /// The captured expressions in an interpolated string. + /// The types of expressions for %A holes in interpolated string. + /// The PrintfFormat containing the formatted result. + /// + /// + [] + new : value:string * captures: obj[] * captureTys: Type[] -> PrintfFormat<'Printer,'State,'Residue,'Result> + /// The raw text of the format string. + /// + /// member Value : string + + /// The captures associated with an interpolated string. + /// + /// + [] + member Captures: obj[] + + /// The capture types associated with an interpolated string. + /// + /// + [] + member CaptureTypes: System.Type[] /// Type of a formatting expression. +/// /// Function type generated by printf. /// Type argument passed to %a formatters /// Value generated by the overall printf action (e.g. sprint generates a string) /// Value generated after post processing (e.g. failwithf generates a string internally then raises an exception) /// Tuple of values generated by scan or match. +/// +/// Language Primitives +/// +/// type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> = inherit PrintfFormat<'Printer,'State,'Residue,'Result> /// Construct a format string + /// /// The input string. + /// /// The created format string. + /// + /// new: value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> + /// Construct a format string + /// + /// The input string. + /// The captured expressions in an interpolated string. + /// The types of expressions for %A holes in interpolated string. + /// + /// The created format string. + /// + /// + [] + new: value:string * captures: obj[] * captureTys: Type[] -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> + /// Type of a formatting expression. /// Function type generated by printf. /// Type argument passed to %a formatters /// Value generated by the overall printf action (e.g. sprint generates a string) /// Value generated after post processing (e.g. failwithf generates a string internally then raises an exception) +/// +/// Language Primitives type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Residue,'Result> /// Type of a formatting expression. @@ -52,206 +105,185 @@ type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Re /// Value generated by the overall printf action (e.g. sprint generates a string) /// Value generated after post processing (e.g. failwithf generates a string internally then raises an exception) /// Tuple of values generated by scan or match. +/// +/// Language Primitives type Format<'Printer,'State,'Residue,'Result,'Tuple> = PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> /// Extensible printf-style formatting for numbers and other datatypes /// /// Format specifications are strings with "%" markers indicating format -/// placeholders. Format placeholders consist of: -/// -/// %[flags][width][.precision][type] -/// -/// where the type is interpreted as follows: -/// -/// %b: bool, formatted as "true" or "false" -/// %s: string, formatted as its unescaped contents -/// %c: character literal -/// %d, %i: any basic integer type formatted as a decimal integer, signed if the basic integer type is signed. -/// %u: any basic integer type formatted as an unsigned decimal integer -/// %x, %X, %o: any basic integer type formatted as an unsigned hexadecimal -/// (a-f)/Hexadecimal (A-F)/Octal integer -/// -/// %e, %E, %f, %F, %g, %G: -/// any basic floating point type (float,float32) formatted -/// using a C-style floating point format specifications, i.e -/// -/// %e, %E: Signed value having the form [-]d.dddde[sign]ddd where -/// d is a single decimal digit, dddd is one or more decimal -/// digits, ddd is exactly three decimal digits, and sign -/// is + or - -/// -/// %f: Signed value having the form [-]dddd.dddd, where dddd is one -/// or more decimal digits. The number of digits before the -/// decimal point depends on the magnitude of the number, and -/// the number of digits after the decimal point depends on -/// the requested precision. -/// -/// %g, %G: Signed value printed in f or e format, whichever is -/// more compact for the given value and precision. -/// -/// -/// %M: System.Decimal value -/// -/// %O: Any value, printed by boxing the object and using it's ToString method(s) -/// -/// %A: Any value, printed with the default layout settings -/// -/// %a: A general format specifier, requires two arguments: -/// (1) a function which accepts two arguments: -/// (a) a context parameter of the appropriate type for the -/// given formatting function (e.g. an #System.IO.TextWriter) -/// (b) a value to print -/// and which either outputs or returns appropriate text. -/// -/// (2) the particular value to print -/// -/// -/// %t: A general format specifier, requires one argument: -/// (1) a function which accepts a context parameter of the -/// appropriate type for the given formatting function (e.g. -/// an System.IO.TextWriter)and which either outputs or returns -/// appropriate text. +/// placeholders. Format placeholders consist of %[flags][width][.precision][type]. /// -/// Basic integer types are: -/// byte,sbyte,int16,uint16,int32,uint32,int64,uint64,nativeint,unativeint -/// Basic floating point types are: -/// float, float32 -/// -/// The optional width is an integer indicating the minimal width of the -/// result. For instance, %6d prints an integer, prefixing it with spaces -/// to fill at least 6 characters. If width is '*', then an extra integer -/// argument is taken to specify the corresponding width. -/// -/// any number -/// '*': -/// -/// Valid flags are: -/// -/// 0: add zeros instead of spaces to make up the required width -/// '-': left justify the result within the width specified -/// '+': add a '+' character if the number is positive (to match a '-' sign -/// for negatives) -/// ' ': add an extra space if the number is positive (to match a '-' -/// sign for negatives) -/// -/// The printf '#' flag is invalid and a compile-time error will be reported if it is used. +/// Strings and Text [] module Printf = - /// Represents a statically-analyzed format associated with writing to a System.Text.StringBuilder. The first type parameter indicates the + /// Represents a statically-analyzed format associated with writing to a . The first type parameter indicates the /// arguments of the format operation and the last the overall return type. - type BuilderFormat<'T,'Result> = Format<'T, StringBuilder, unit, 'Result> + type BuilderFormat<'T,'Result> = Format<'T, StringBuilder, unit, 'Result> /// Represents a statically-analyzed format when formatting builds a string. The first type parameter indicates the /// arguments of the format operation and the last the overall return type. - type StringFormat<'T,'Result> = Format<'T, unit, string, 'Result> + type StringFormat<'T,'Result> = Format<'T, unit, string, 'Result> - /// Represents a statically-analyzed format associated with writing to a System.IO.TextWriter. The first type parameter indicates the + /// Represents a statically-analyzed format associated with writing to a . The first type parameter indicates the /// arguments of the format operation and the last the overall return type. type TextWriterFormat<'T,'Result> = Format<'T, TextWriter, unit, 'Result> - /// Represents a statically-analyzed format associated with writing to a System.Text.StringBuilder. The type parameter indicates the + /// Represents a statically-analyzed format associated with writing to a . The type parameter indicates the /// arguments and return type of the format operation. - type BuilderFormat<'T> = BuilderFormat<'T,unit> + type BuilderFormat<'T> = BuilderFormat<'T, unit> /// Represents a statically-analyzed format when formatting builds a string. The type parameter indicates the /// arguments and return type of the format operation. - type StringFormat<'T> = StringFormat<'T,string> + type StringFormat<'T> = StringFormat<'T,string> - /// Represents a statically-analyzed format associated with writing to a System.IO.TextWriter. The type parameter indicates the + /// Represents a statically-analyzed format associated with writing to a . The type parameter indicates the /// arguments and return type of the format operation. - type TextWriterFormat<'T> = TextWriterFormat<'T,unit> + type TextWriterFormat<'T> = TextWriterFormat<'T,unit> - /// Print to a System.Text.StringBuilder + /// Print to a + /// /// The StringBuilder to print to. /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val bprintf : builder:StringBuilder -> format:BuilderFormat<'T> -> 'T + val bprintf: builder:StringBuilder -> format:BuilderFormat<'T> -> 'T /// Print to a text writer. + /// /// The TextWriter to print to. /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val fprintf : textWriter:TextWriter -> format:TextWriterFormat<'T> -> 'T + val fprintf: textWriter:TextWriter -> format:TextWriterFormat<'T> -> 'T /// Print to a text writer, adding a newline + /// /// The TextWriter to print to. /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val fprintfn : textWriter:TextWriter -> format:TextWriterFormat<'T> -> 'T + val fprintfn: textWriter:TextWriter -> format:TextWriterFormat<'T> -> 'T /// Formatted printing to stderr + /// /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val eprintf : format:TextWriterFormat<'T> -> 'T + val eprintf: format:TextWriterFormat<'T> -> 'T /// Formatted printing to stderr, adding a newline + /// /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val eprintfn : format:TextWriterFormat<'T> -> 'T + val eprintfn: format:TextWriterFormat<'T> -> 'T /// Formatted printing to stdout + /// /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val printf : format:TextWriterFormat<'T> -> 'T + val printf: format:TextWriterFormat<'T> -> 'T /// Formatted printing to stdout, adding a newline. + /// /// The input formatter. + /// /// The return type and arguments of the formatter. + /// + /// [] - val printfn : format:TextWriterFormat<'T> -> 'T + val printfn: format:TextWriterFormat<'T> -> 'T /// Print to a string via an internal string buffer and return /// the result as a string. Helper printers must return strings. + /// /// The input formatter. + /// /// The formatted string. + /// + /// [] - val sprintf : format:StringFormat<'T> -> 'T + val sprintf: format:StringFormat<'T> -> 'T /// bprintf, but call the given 'final' function to generate the result. /// See kprintf. + /// /// The function called after formatting to generate the format result. /// The input StringBuilder. /// The input formatter. + /// /// The arguments of the formatter. + /// + /// [] - val kbprintf : continuation:(unit -> 'Result) -> builder:StringBuilder -> format:BuilderFormat<'T,'Result> -> 'T + val kbprintf: continuation:(unit -> 'Result) -> builder:StringBuilder -> format:BuilderFormat<'T,'Result> -> 'T /// fprintf, but call the given 'final' function to generate the result. /// See kprintf. + /// /// The function called after formatting to generate the format result. /// The input TextWriter. /// The input formatter. + /// /// The arguments of the formatter. + /// + /// [] - val kfprintf : continuation:(unit -> 'Result) -> textWriter:TextWriter -> format:TextWriterFormat<'T,'Result> -> 'T + val kfprintf: continuation:(unit -> 'Result) -> textWriter:TextWriter -> format:TextWriterFormat<'T,'Result> -> 'T /// printf, but call the given 'final' function to generate the result. /// For example, these let the printing force a flush after all output has /// been entered onto the channel, but not before. + /// /// The function called after formatting to generate the format result. /// The input formatter. + /// /// The arguments of the formatter. + /// + /// [] - val kprintf : continuation:(string -> 'Result) -> format:StringFormat<'T,'Result> -> 'T + val kprintf: continuation:(string -> 'Result) -> format:StringFormat<'T,'Result> -> 'T /// sprintf, but call the given 'final' function to generate the result. /// See kprintf. + /// /// The function called to generate a result from the formatted string. /// The input formatter. + /// /// The arguments of the formatter. + /// + /// [] - val ksprintf : continuation:(string -> 'Result) -> format:StringFormat<'T,'Result> -> 'T + val ksprintf: continuation:(string -> 'Result) -> format:StringFormat<'T,'Result> -> 'T /// Print to a string buffer and raise an exception with the given /// result. Helper printers must return strings. + /// /// The input formatter. + /// /// The arguments of the formatter. + /// + /// [] val failwithf: format:StringFormat<'T,'Result> -> 'T diff --git a/src/fsharp/FSharp.Core/quotations.fs b/src/fsharp/FSharp.Core/quotations.fs index f1d2dea11e0..94e6d36fe08 100644 --- a/src/fsharp/FSharp.Core/quotations.fs +++ b/src/fsharp/FSharp.Core/quotations.fs @@ -15,8 +15,8 @@ open Microsoft.FSharp.Collections open Microsoft.FSharp.Reflection open Microsoft.FSharp.Core.Printf open Microsoft.FSharp.Text.StructuredPrintfImpl -open Microsoft.FSharp.Text.StructuredPrintfImpl.LayoutOps -open Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedTextOps +open Microsoft.FSharp.Text.StructuredPrintfImpl.Layout +open Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedText #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation @@ -53,7 +53,7 @@ module Helpers = let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly let publicOrPrivateBindingFlags = BindingFlags.Public ||| BindingFlags.NonPublic - let isDelegateType (typ:Type) = + let isDelegateType (typ: Type) = if typ.IsSubclassOf(typeof) then match typ.GetMethod("Invoke", instanceBindingFlags) with | null -> false @@ -79,7 +79,7 @@ open Helpers [] [] [] -type Var(name: string, typ:Type, ?isMutable: bool) = +type Var(name: string, typ: Type, ?isMutable: bool) = inherit obj() static let getStamp = @@ -164,6 +164,10 @@ and | NewObjectOp of ConstructorInfo | InstanceMethodCallOp of MethodInfo | StaticMethodCallOp of MethodInfo + /// A new Call node type in F# 5.0, storing extra information about witnesses + | InstanceMethodCallWOp of MethodInfo * MethodInfo * int + /// A new Call node type in F# 5.0, storing extra information about witnesses + | StaticMethodCallWOp of MethodInfo * MethodInfo * int | CoerceOp of Type | NewArrayOp of Type | NewDelegateOp of Type @@ -182,8 +186,8 @@ and | WithValueOp of obj * Type | DefaultValueOp of Type -and [] - Expr(term:Tree, attribs:Expr list) = +and [] + Expr(term:Tree, attribs: Expr list) = member x.Tree = term member x.CustomAttributes = attribs @@ -194,6 +198,30 @@ and [] match t1, t2 with // We special-case ValueOp to ensure that ValueWithName = Value | CombTerm(ValueOp(v1, ty1, _), []), CombTerm(ValueOp(v2, ty2, _), []) -> (v1 = v2) && (ty1 = ty2) + + // We strip off InstanceMethodCallWOp to ensure that CallWithWitness = Call + | CombTerm(InstanceMethodCallWOp(minfo1, _minfoW1, nWitnesses1), obj1::args1WithoutObj), _ -> + if nWitnesses1 <= args1WithoutObj.Length then + let args1WithoutWitnesses = List.skip nWitnesses1 args1WithoutObj + eq (CombTerm(InstanceMethodCallOp(minfo1), obj1::args1WithoutWitnesses)) t2 + else + false + + // We strip off InstanceMethodCallWOp to ensure that CallWithWitness = Call + | _, CombTerm(InstanceMethodCallWOp(minfo2, _minfoW2, nWitnesses2), obj2::args2WithoutObj) when nWitnesses2 <= args2WithoutObj.Length -> + let args2WithoutWitnesses = List.skip nWitnesses2 args2WithoutObj + eq t1 (CombTerm(InstanceMethodCallOp(minfo2), obj2::args2WithoutWitnesses)) + + // We strip off StaticMethodCallWOp to ensure that CallWithWitness = Call + | CombTerm(StaticMethodCallWOp(minfo1, _minfoW1, nWitnesses1), args1), _ when nWitnesses1 <= args1.Length -> + let argsWithoutWitnesses1 = List.skip nWitnesses1 args1 + eq (CombTerm(StaticMethodCallOp(minfo1), argsWithoutWitnesses1)) t2 + + // We strip off StaticMethodCallWOp to ensure that CallWithWitness = Call + | _, CombTerm(StaticMethodCallWOp(minfo2, _minfoW2, nWitnesses2), args2) when nWitnesses2 <= args2.Length -> + let argsWithoutWitnesses2 = List.skip nWitnesses2 args2 + eq t1 (CombTerm(StaticMethodCallOp(minfo2), argsWithoutWitnesses2)) + | CombTerm(c1, es1), CombTerm(c2, es2) -> c1 = c2 && es1.Length = es2.Length && (es1 = es2) | VarTerm v1, VarTerm v2 -> (v1 = v2) | LambdaTerm (v1, e1), LambdaTerm(v2, e2) -> (v1 = v2) && (e1 = e2) @@ -208,13 +236,15 @@ and [] override x.ToString() = x.ToString false member x.ToString full = - Microsoft.FSharp.Text.StructuredPrintfImpl.Display.layout_to_string Microsoft.FSharp.Text.StructuredPrintfImpl.FormatOptions.Default (x.GetLayout full) + Display.layout_to_string FormatOptions.Default (x.GetLayout(full)) + + member x.DebugText = x.ToString(false) member x.GetLayout long = - let expr (e:Expr ) = e.GetLayout long - let exprs (es:Expr list) = es |> List.map expr + let expr (e: Expr ) = e.GetLayout long + let exprs (es: Expr list) = es |> List.map expr let parens ls = bracketL (commaListL ls) - let pairL l1 l2 = bracketL (l1 ^^ sepL Literals.comma ^^ l2) + let pairL l1 l2 = bracketL (l1 ^^ sepL comma ^^ l2) let listL ls = squareBracketL (commaListL ls) let combTaggedL nm ls = wordL nm ^^ parens ls let combL nm ls = combTaggedL (tagKeyword nm) ls @@ -222,7 +252,7 @@ and [] let someL e = combTaggedL (tagMethod "Some") [expr e] let typeL (o: Type) = wordL (tagClass (if long then o.FullName else o.Name)) let objL (o: 'T) = wordL (tagText (sprintf "%A" o)) - let varL (v:Var) = wordL (tagLocal v.Name) + let varL (v: Var) = wordL (tagLocal v.Name) let (|E|) (e: Expr) = e.Tree let (|Lambda|_|) (E x) = match x with LambdaTerm(a, b) -> Some (a, b) | _ -> None let (|IteratedLambda|_|) (e: Expr) = qOneOrMoreRLinear (|Lambda|_|) e @@ -231,7 +261,7 @@ and [] let cinfoL (cinfo: ConstructorInfo) = if long then objL cinfo else wordL (tagMethod cinfo.DeclaringType.Name) let pinfoL (pinfo: PropertyInfo) = if long then objL pinfo else wordL (tagProperty pinfo.Name) let finfoL (finfo: FieldInfo) = if long then objL finfo else wordL (tagField finfo.Name) - let rec (|NLambdas|_|) n (e:Expr) = + let rec (|NLambdas|_|) n (e: Expr) = match e with | _ when n <= 0 -> Some([], e) | Lambda(v, NLambdas ((-) n 1) (vs, b)) -> Some(v :: vs, b) @@ -250,17 +280,30 @@ and [] | CombTerm(ValueOp(v, _, Some nm), []) -> combL "ValueWithName" [objL v; wordL (tagLocal nm)] | CombTerm(ValueOp(v, _, None), []) -> combL "Value" [objL v] | CombTerm(WithValueOp(v, _), [defn]) -> combL "WithValue" [objL v; expr defn] - | CombTerm(InstanceMethodCallOp minfo, obj :: args) -> combL "Call" [someL obj; minfoL minfo; listL (exprs args)] - | CombTerm(StaticMethodCallOp minfo, args) -> combL "Call" [noneL; minfoL minfo; listL (exprs args)] - | CombTerm(InstancePropGetOp pinfo, (obj :: args)) -> combL "PropertyGet" [someL obj; pinfoL pinfo; listL (exprs args)] - | CombTerm(StaticPropGetOp pinfo, args) -> combL "PropertyGet" [noneL; pinfoL pinfo; listL (exprs args)] - | CombTerm(InstancePropSetOp pinfo, (obj :: args)) -> combL "PropertySet" [someL obj; pinfoL pinfo; listL (exprs args)] - | CombTerm(StaticPropSetOp pinfo, args) -> combL "PropertySet" [noneL; pinfoL pinfo; listL (exprs args)] - | CombTerm(InstanceFieldGetOp finfo, [obj]) -> combL "FieldGet" [someL obj; finfoL finfo] - | CombTerm(StaticFieldGetOp finfo, []) -> combL "FieldGet" [noneL; finfoL finfo] - | CombTerm(InstanceFieldSetOp finfo, [obj;v]) -> combL "FieldSet" [someL obj; finfoL finfo; expr v;] - | CombTerm(StaticFieldSetOp finfo, [v]) -> combL "FieldSet" [noneL; finfoL finfo; expr v;] - | CombTerm(CoerceOp ty, [arg]) -> combL "Coerce" [ expr arg; typeL ty] + + | CombTerm(InstanceMethodCallOp(minfo), obj::args) -> + combL "Call" [someL obj; minfoL minfo; listL (exprs args)] + + | CombTerm(StaticMethodCallOp(minfo), args) -> + combL "Call" [noneL; minfoL minfo; listL (exprs args)] + + | CombTerm(InstanceMethodCallWOp(minfo, _minfoW, nWitnesses), obj::argsWithoutObj) when nWitnesses <= argsWithoutObj.Length -> + let argsWithoutWitnesses = List.skip nWitnesses argsWithoutObj + combL "Call" [someL obj; minfoL minfo; listL (exprs argsWithoutWitnesses)] + + | CombTerm(StaticMethodCallWOp(minfo, _minfoW, nWitnesses), args) when nWitnesses <= args.Length -> + let argsWithoutWitnesses = List.skip nWitnesses args + combL "Call" [noneL; minfoL minfo; listL (exprs argsWithoutWitnesses)] + + | CombTerm(InstancePropGetOp(pinfo), (obj::args)) -> combL "PropertyGet" [someL obj; pinfoL pinfo; listL (exprs args)] + | CombTerm(StaticPropGetOp(pinfo), args) -> combL "PropertyGet" [noneL; pinfoL pinfo; listL (exprs args)] + | CombTerm(InstancePropSetOp(pinfo), (obj::args)) -> combL "PropertySet" [someL obj; pinfoL pinfo; listL (exprs args)] + | CombTerm(StaticPropSetOp(pinfo), args) -> combL "PropertySet" [noneL; pinfoL pinfo; listL (exprs args)] + | CombTerm(InstanceFieldGetOp(finfo), [obj]) -> combL "FieldGet" [someL obj; finfoL finfo] + | CombTerm(StaticFieldGetOp(finfo), []) -> combL "FieldGet" [noneL; finfoL finfo] + | CombTerm(InstanceFieldSetOp(finfo), [obj;v]) -> combL "FieldSet" [someL obj; finfoL finfo; expr v;] + | CombTerm(StaticFieldSetOp(finfo), [v]) -> combL "FieldSet" [noneL; finfoL finfo; expr v;] + | CombTerm(CoerceOp(ty), [arg]) -> combL "Coerce" [ expr arg; typeL ty] | CombTerm(NewObjectOp cinfo, args) -> combL "NewObject" ([ cinfoL cinfo ] @ exprs args) | CombTerm(DefaultValueOp ty, args) -> combL "DefaultValue" ([ typeL ty ] @ exprs args) | CombTerm(NewArrayOp ty, args) -> combL "NewArray" ([ typeL ty ] @ exprs args) @@ -273,6 +316,7 @@ and [] | CombTerm(TryFinallyOp, args) -> combL "TryFinally" (exprs args) | CombTerm(TryWithOp, [e1;Lambda(v1, e2);Lambda(v2, e3)]) -> combL "TryWith" [expr e1; varL v1; expr e2; varL v2; expr e3] | CombTerm(SequentialOp, args) -> combL "Sequential" (exprs args) + | CombTerm(NewDelegateOp ty, [e]) -> let nargs = (getDelegateInvoke ty).GetParameters().Length if nargs = 0 then @@ -305,7 +349,7 @@ module Patterns = /// as a computation. type Instantiable<'T> = (int -> Type) -> 'T - type ByteStream(bytes:byte[], initial:int, len:int) = + type ByteStream(bytes:byte[], initial: int, len: int) = let mutable pos = initial let lim = initial + len @@ -350,8 +394,8 @@ module Patterns = let (a, b) = removeVoid a, removeVoid b funTyC.MakeGenericType([| a;b |]) - let mkArrayTy (t:Type) = t.MakeArrayType() - let mkExprTy (t:Type) = exprTyC.MakeGenericType([| t |]) + let mkArrayTy (t: Type) = t.MakeArrayType() + let mkExprTy (t: Type) = exprTyC.MakeGenericType([| t |]) let rawExprTy = typeof @@ -510,7 +554,37 @@ module Patterns = let (|Call|_|) input = match input with | E(CombTerm(StaticMethodCallOp minfo, args)) -> Some(None, minfo, args) - | E(CombTerm(InstanceMethodCallOp minfo, (obj :: args))) -> Some(Some obj, minfo, args) + + | E(CombTerm(InstanceMethodCallOp minfo, (obj::args))) -> Some(Some(obj), minfo, args) + + // A StaticMethodCallWOp matches as if it were a StaticMethodCallOp + | E(CombTerm(StaticMethodCallWOp (minfo, _minfoW, nWitnesses), args)) when nWitnesses <= args.Length -> + Some(None, minfo, List.skip nWitnesses args) + + // A InstanceMethodCallWOp matches as if it were a InstanceMethodCallOp + | E(CombTerm(InstanceMethodCallWOp (minfo, _minfoW, nWitnesses), obj::argsWithoutObj)) when nWitnesses <= argsWithoutObj.Length -> + let argsWithoutWitnesses = List.skip nWitnesses argsWithoutObj + Some (Some obj, minfo, argsWithoutWitnesses) + + | _ -> None + + [] + let (|CallWithWitnesses|_|) input = + match input with + | E(CombTerm(StaticMethodCallWOp (minfo, minfoW, nWitnesses), args)) -> + if args.Length >= nWitnesses then + let witnessArgs, argsWithoutWitnesses = List.splitAt nWitnesses args + Some(None, minfo, minfoW, witnessArgs, argsWithoutWitnesses) + else + None + + | E(CombTerm(InstanceMethodCallWOp (minfo, minfoW, nWitnesses), obj::argsWithoutObj)) -> + if argsWithoutObj.Length >= nWitnesses then + let witnessArgs, argsWithoutWitnesses = List.splitAt nWitnesses argsWithoutObj + Some (Some obj, minfo, minfoW, witnessArgs, argsWithoutWitnesses) + else + None + | _ -> None let (|LetRaw|_|) input = @@ -531,7 +605,7 @@ module Patterns = let (|IteratedLambda|_|) (e: Expr) = qOneOrMoreRLinear (|Lambda|_|) e - let rec (|NLambdas|_|) n (e:Expr) = + let rec (|NLambdas|_|) n (e: Expr) = match e with | _ when n <= 0 -> Some([], e) | Lambda(v, NLambdas ((-) n 1) (vs, b)) -> Some(v :: vs, b) @@ -583,14 +657,14 @@ module Patterns = /// Returns type of lambda application - something like "(fun a -> ..) b" let rec typeOfAppliedLambda f = - let fty = ((typeOf f):Type) + let fty = ((typeOf f): Type) match fty.GetGenericArguments() with | [| _; b|] -> b - | _ -> raise <| System.InvalidOperationException (SR.GetString(SR.QillFormedAppOrLet)) + | _ -> invalidOp (SR.GetString(SR.QillFormedAppOrLet)) /// Returns type of the Raw quotation or fails if the quotation is ill formed /// if 'verify' is true, verifies all branches, otherwise ignores some of them when not needed - and typeOf<'T when 'T :> Expr> (e : 'T) : Type = + and typeOf<'T when 'T :> Expr> (e : 'T): Type = let (E t) = e match t with | VarTerm v -> v.Type @@ -621,6 +695,8 @@ module Patterns = | NewObjectOp ctor, _ -> ctor.DeclaringType | InstanceMethodCallOp minfo, _ -> minfo.ReturnType |> removeVoid | StaticMethodCallOp minfo, _ -> minfo.ReturnType |> removeVoid + | InstanceMethodCallWOp (_, minfoW, _), _ -> minfoW.ReturnType |> removeVoid + | StaticMethodCallWOp (_, minfoW, _), _ -> minfoW.ReturnType |> removeVoid | CoerceOp ty, _ -> ty | SequentialOp, [_;b] -> typeOf b | ForIntegerRangeLoopOp, _ -> typeof @@ -655,14 +731,14 @@ module Patterns = //-------------------------------------------------------------------------- // t2 is inherited from t1 / t2 implements interface t1 or t2 == t1 - let assignableFrom (t1:Type) (t2:Type) = + let assignableFrom (t1: Type) (t2: Type) = t1.IsAssignableFrom t2 - let checkTypesSR (expectedType: Type) (receivedType : Type) name (threeHoleSR : string) = + let checkTypesSR (expectedType: Type) (receivedType: Type) name (threeHoleSR : string) = if (expectedType <> receivedType) then invalidArg "receivedType" (String.Format(threeHoleSR, name, expectedType, receivedType)) - let checkTypesWeakSR (expectedType: Type) (receivedType : Type) name (threeHoleSR : string) = + let checkTypesWeakSR (expectedType: Type) (receivedType: Type) name (threeHoleSR : string) = if (not (assignableFrom expectedType receivedType)) then invalidArg "receivedType" (String.Format(threeHoleSR, name, expectedType, receivedType)) @@ -680,7 +756,7 @@ module Patterns = let checkObj (membInfo: MemberInfo) (obj: Expr) = // The MemberInfo may be a property associated with a union // find the actual related union type - let rec loop (ty:Type) = if FSharpType.IsUnion ty && FSharpType.IsUnion ty.BaseType then loop ty.BaseType else ty + let rec loop (ty: Type) = if FSharpType.IsUnion ty && FSharpType.IsUnion ty.BaseType then loop ty.BaseType else ty let declType = loop membInfo.DeclaringType if not (assignableFrom declType (typeOf obj)) then invalidArg "obj" (SR.GetString(SR.QincorrectInstanceType)) @@ -702,7 +778,7 @@ module Patterns = | Some case -> case.GetFields() | _ -> invalidArg "ty" (String.Format(SR.GetString(SR.notAUnionType), ty.FullName)) - let checkBind(v:Var, e) = + let checkBind(v: Var, e) = let ety = typeOf e checkTypesSR v.Type ety "let" (SR.GetString(SR.QtmmVarTypeNotMatchRHS)) @@ -713,7 +789,7 @@ module Patterns = let mkValue (v, ty) = mkFE0 (ValueOp(v, ty, None)) let mkValueWithName (v, ty, nm) = mkFE0 (ValueOp(v, ty, Some nm)) let mkValueWithDefn (v, ty, defn) = mkFE1 (WithValueOp(v, ty)) defn - let mkValueG (v:'T) = mkValue(box v, typeof<'T>) + let mkValueG (v: 'T) = mkValue(box v, typeof<'T>) let mkLiftedValueOpG (v, ty: System.Type) = let obj = if ty.IsEnum then System.Enum.ToObject(ty, box v) else box v ValueOp(obj, ty, None) @@ -740,7 +816,7 @@ module Patterns = mkLetRaw v // Tuples - let mkNewTupleWithType (ty, args:Expr list) = + let mkNewTupleWithType (ty, args: Expr list) = let mems = FSharpType.GetTupleElements ty |> Array.toList if (args.Length <> mems.Length) then invalidArg "args" (SR.GetString(SR.QtupleLengthsDiffer)) List.iter2(fun mt a -> checkTypesSR mt (typeOf a) "args" (SR.GetString(SR.QtmmTuple)) ) mems args @@ -764,7 +840,7 @@ module Patterns = let mkNewRecord (ty, args:list) = let mems = FSharpType.GetRecordFields(ty, publicOrPrivateBindingFlags) if (args.Length <> mems.Length) then invalidArg "args" (SR.GetString(SR.QincompatibleRecordLength)) - List.iter2 (fun (minfo:PropertyInfo) a -> checkTypesSR minfo.PropertyType (typeOf a) "recd" (SR.GetString(SR.QtmmIncorrectArgForRecord))) (Array.toList mems) args + List.iter2 (fun (minfo: PropertyInfo) a -> checkTypesSR minfo.PropertyType (typeOf a) "recd" (SR.GetString(SR.QtmmIncorrectArgForRecord))) (Array.toList mems) args mkFEN (NewRecordOp ty) args @@ -773,7 +849,7 @@ module Patterns = if Unchecked.defaultof = unionCase then raise (new ArgumentNullException()) let sargs = unionCase.GetFields() if (args.Length <> sargs.Length) then invalidArg "args" (SR.GetString(SR.QunionNeedsDiffNumArgs)) - List.iter2 (fun (minfo:PropertyInfo) a -> checkTypesSR minfo.PropertyType (typeOf a) "sum" (SR.GetString(SR.QtmmIncorrectArgForUnion))) (Array.toList sargs) args + List.iter2 (fun (minfo: PropertyInfo) a -> checkTypesSR minfo.PropertyType (typeOf a) "sum" (SR.GetString(SR.QtmmIncorrectArgForUnion))) (Array.toList sargs) args mkFEN (NewUnionCaseOp unionCase) args let mkUnionCaseTest (unionCase:UnionCaseInfo, expr) = @@ -805,14 +881,14 @@ module Patterns = | true -> mkFE0 (StaticFieldGetOp finfo) | false -> invalidArg "finfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) - let mkStaticFieldSet (finfo:FieldInfo, value:Expr) = + let mkStaticFieldSet (finfo:FieldInfo, value: Expr) = if Unchecked.defaultof = finfo then raise (new ArgumentNullException()) checkTypesSR (typeOf value) finfo.FieldType "value" (SR.GetString(SR.QtmmBadFieldType)) match finfo.IsStatic with | true -> mkFE1 (StaticFieldSetOp finfo) value | false -> invalidArg "finfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) - let mkInstanceFieldSet (obj, finfo:FieldInfo, value:Expr) = + let mkInstanceFieldSet (obj, finfo:FieldInfo, value: Expr) = if Unchecked.defaultof = finfo then raise (new ArgumentNullException()) checkTypesSR (typeOf value) finfo.FieldType "value" (SR.GetString(SR.QtmmBadFieldType)) match finfo.IsStatic with @@ -826,10 +902,10 @@ module Patterns = checkArgs (ci.GetParameters()) args mkFEN (NewObjectOp ci) args - let mkDefaultValue (ty:Type) = + let mkDefaultValue (ty: Type) = mkFE0 (DefaultValueOp ty) - let mkStaticPropGet (pinfo:PropertyInfo, args:list) = + let mkStaticPropGet (pinfo: PropertyInfo, args:list) = if Unchecked.defaultof = pinfo then raise (new ArgumentNullException()) if (not pinfo.CanRead) then invalidArg "pinfo" (SR.GetString(SR.QreadingSetOnly)) checkArgs (pinfo.GetIndexParameters()) args @@ -837,7 +913,7 @@ module Patterns = | true -> mkFEN (StaticPropGetOp pinfo) args | false -> invalidArg "pinfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) - let mkInstancePropGet (obj, pinfo:PropertyInfo, args:list) = + let mkInstancePropGet (obj, pinfo: PropertyInfo, args:list) = if Unchecked.defaultof = pinfo then raise (new ArgumentNullException()) if (not pinfo.CanRead) then invalidArg "pinfo" (SR.GetString(SR.QreadingSetOnly)) checkArgs (pinfo.GetIndexParameters()) args @@ -847,7 +923,7 @@ module Patterns = mkFEN (InstancePropGetOp pinfo) (obj :: args) | true -> invalidArg "pinfo" (SR.GetString(SR.QstaticWithReceiverObject)) - let mkStaticPropSet (pinfo:PropertyInfo, args:list, value:Expr) = + let mkStaticPropSet (pinfo: PropertyInfo, args:list, value: Expr) = if Unchecked.defaultof = pinfo then raise (new ArgumentNullException()) if (not pinfo.CanWrite) then invalidArg "pinfo" (SR.GetString(SR.QwritingGetOnly)) checkArgs (pinfo.GetIndexParameters()) args @@ -855,7 +931,7 @@ module Patterns = | true -> mkFEN (StaticPropSetOp pinfo) (args@[value]) | false -> invalidArg "pinfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) - let mkInstancePropSet (obj, pinfo:PropertyInfo, args:list, value:Expr) = + let mkInstancePropSet (obj, pinfo: PropertyInfo, args:list, value: Expr) = if Unchecked.defaultof = pinfo then raise (new ArgumentNullException()) if (not pinfo.CanWrite) then invalidArg "pinfo" (SR.GetString(SR.QwritingGetOnly)) checkArgs (pinfo.GetIndexParameters()) args @@ -874,6 +950,15 @@ module Patterns = mkFEN (InstanceMethodCallOp minfo) (obj :: args) | true -> invalidArg "minfo" (SR.GetString(SR.QstaticWithReceiverObject)) + let mkInstanceMethodCallW (obj, minfo: MethodInfo, minfoW: MethodInfo, nWitnesses: int, args: Expr list) = + if Unchecked.defaultof = minfo then raise (new ArgumentNullException()) + checkArgs (minfoW.GetParameters()) args + match minfoW.IsStatic with + | false -> + checkObj minfo obj + mkFEN (InstanceMethodCallWOp (minfo, minfoW, nWitnesses)) (obj::args) + | true -> invalidArg "minfo" (SR.GetString(SR.QstaticWithReceiverObject)) + let mkStaticMethodCall (minfo:MethodInfo, args:list) = if Unchecked.defaultof = minfo then raise (new ArgumentNullException()) checkArgs (minfo.GetParameters()) args @@ -881,7 +966,14 @@ module Patterns = | true -> mkFEN (StaticMethodCallOp minfo) args | false -> invalidArg "minfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) - let mkForLoop (v:Var, lowerBound, upperBound, body) = + let mkStaticMethodCallW (minfo: MethodInfo, minfoW: MethodInfo, nWitnesses: int, args: Expr list) = + if Unchecked.defaultof = minfo then raise (new ArgumentNullException()) + checkArgs (minfoW.GetParameters()) args + match minfo.IsStatic with + | true -> mkFEN (StaticMethodCallWOp (minfo, minfoW, nWitnesses)) args + | false -> invalidArg "minfo" (SR.GetString(SR.QnonStaticNoReceiverObject)) + + let mkForLoop (v: Var, lowerBound, upperBound, body) = checkTypesSR (typeof) (typeOf lowerBound) "lowerBound" (SR.GetString(SR.QtmmLowerUpperBoundMustBeInt)) checkTypesSR (typeof) (typeOf upperBound) "upperBound" (SR.GetString(SR.QtmmLowerUpperBoundMustBeInt)) checkTypesSR (typeof) (v.Type) "for" (SR.GetString(SR.QtmmLoopBodyMustBeLambdaTakingInteger)) @@ -934,20 +1026,20 @@ module Patterns = | Unique of 'T | Ambiguous of 'R - let typeEquals (s:Type) (t:Type) = s.Equals t + let typeEquals (s: Type) (t: Type) = s.Equals t - let typesEqual (ss:Type list) (tt:Type list) = + let typesEqual (ss: Type list) (tt: Type list) = (ss.Length = tt.Length) && List.forall2 typeEquals ss tt let instFormal (typarEnv: Type[]) (ty:Instantiable<'T>) = ty (fun i -> typarEnv.[i]) - let getGenericArguments(tc:Type) = + let getGenericArguments(tc: Type) = if tc.IsGenericType then tc.GetGenericArguments() else [| |] - let getNumGenericArguments(tc:Type) = + let getNumGenericArguments(tc: Type) = if tc.IsGenericType then tc.GetGenericArguments().Length else 0 - let bindMethodBySearch (parentT:Type, nm, marity, argtys, rty) = + let bindMethodBySearch (parentT: Type, nm, marity, argtys, rty) = let methInfos = parentT.GetMethods staticOrInstanceBindingFlags |> Array.toList // First, filter on name, if unique, then binding "done" let tyargTs = getGenericArguments parentT @@ -976,7 +1068,7 @@ module Patterns = res // return MethodInfo for (generic) type's (generic) method match List.tryFind select methInfos with - | None -> raise <| System.InvalidOperationException (SR.GetString SR.QcannotBindToMethod) + | None -> invalidOp (SR.GetString SR.QcannotBindToMethod) | Some methInfo -> methInfo let bindMethodHelper (parentT: Type, nm, marity, argtys, rty) = @@ -997,20 +1089,12 @@ module Patterns = else bindMethodBySearch(parentT, nm, marity, argtys, rty) - let bindModuleProperty (ty:Type, nm) = + let bindModuleProperty (ty: Type, nm) = match ty.GetProperty(nm, staticBindingFlags) with - | null -> raise <| System.InvalidOperationException (String.Format(SR.GetString(SR.QcannotBindProperty), nm, ty.ToString())) + | null -> invalidOp (String.Format(SR.GetString(SR.QcannotBindProperty), nm, ty.ToString())) | res -> res - // tries to locate unique function in a given type - // in case of multiple candidates returns None so bindModuleFunctionWithCallSiteArgs will be used for more precise resolution - let bindModuleFunction (ty:Type, nm) = - match ty.GetMethods staticBindingFlags |> Array.filter (fun mi -> mi.Name = nm) with - | [||] -> raise <| System.InvalidOperationException (String.Format(SR.GetString(SR.QcannotBindFunction), nm, ty.ToString())) - | [| res |] -> Some res - | _ -> None - - let bindModuleFunctionWithCallSiteArgs (ty:Type, nm, argTypes : Type list, tyArgs : Type list) = + let bindModuleFunctionWithCallSiteArgs (ty: Type, nm, argTypes: Type list, tyArgs: Type list) = let argTypes = List.toArray argTypes let tyArgs = List.toArray tyArgs let methInfo = @@ -1031,7 +1115,7 @@ module Patterns = let methodTyArgCount = if mi.IsGenericMethod then mi.GetGenericArguments().Length else 0 methodTyArgCount = tyArgs.Length ) - let fail() = raise <| System.InvalidOperationException (String.Format(SR.GetString(SR.QcannotBindFunction), nm, ty.ToString())) + let fail() = invalidOp (String.Format(SR.GetString(SR.QcannotBindFunction), nm, ty.ToString())) match candidates with | [||] -> fail() | [| solution |] -> solution @@ -1084,7 +1168,7 @@ module Patterns = | Some mi -> mi | None -> fail() - let mkNamedType (tc:Type, tyargs) = + let mkNamedType (tc: Type, tyargs) = match tyargs with | [] -> tc | _ -> tc.MakeGenericType(Array.ofList tyargs) @@ -1094,9 +1178,9 @@ module Patterns = | null -> raise (new ArgumentNullException(arg, err)) | _ -> y - let inst (tyargs:Type list) (i: Instantiable<'T>) = i (fun idx -> tyargs.[idx]) // Note, O n looks, but #tyargs is always small + let inst (tyargs: Type list) (i: Instantiable<'T>) = i (fun idx -> tyargs.[idx]) // Note, O n looks, but #tyargs is always small - let bindPropBySearchIfCandidateIsNull (ty : Type) propName retType argTypes candidate = + let bindPropBySearchIfCandidateIsNull (ty: Type) propName retType argTypes candidate = match candidate with | null -> let props = @@ -1113,7 +1197,7 @@ module Patterns = | _ -> null | pi -> pi - let bindCtorBySearchIfCandidateIsNull (ty : Type) argTypes candidate = + let bindCtorBySearchIfCandidateIsNull (ty: Type) argTypes candidate = match candidate with | null -> let ctors = @@ -1133,24 +1217,29 @@ module Patterns = let typ = mkNamedType (tc, tyargs) let argtyps : Type list = argTypes |> inst tyargs let retType : Type = retType |> inst tyargs |> removeVoid - typ.GetProperty(propName, staticOrInstanceBindingFlags, null, retType, Array.ofList argtyps, null) |> checkNonNullResult ("propName", String.Format(SR.GetString(SR.QfailedToBindProperty), propName)) // fxcop may not see "propName" as an arg + // fxcop may not see "propName" as an arg + typ.GetProperty(propName, staticOrInstanceBindingFlags, null, retType, Array.ofList argtyps, null) + |> checkNonNullResult ("propName", String.Format(SR.GetString(SR.QfailedToBindProperty), propName)) let bindField (tc, fldName, tyargs) = let typ = mkNamedType (tc, tyargs) - typ.GetField(fldName, staticOrInstanceBindingFlags) |> checkNonNullResult ("fldName", String.Format(SR.GetString(SR.QfailedToBindField), fldName)) // fxcop may not see "fldName" as an arg + typ.GetField(fldName, staticOrInstanceBindingFlags) + |> checkNonNullResult ("fldName", String.Format(SR.GetString(SR.QfailedToBindField), fldName)) // fxcop may not see "fldName" as an arg - let bindGenericCctor (tc:Type) = + let bindGenericCctor (tc: Type) = tc.GetConstructor(staticBindingFlags, null, [| |], null) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) - let bindGenericCtor (tc:Type, argTypes:Instantiable) = + let bindGenericCtor (tc: Type, argTypes: Instantiable) = let argtyps = instFormal (getGenericArguments tc) argTypes - tc.GetConstructor(instanceBindingFlags, null, Array.ofList argtyps, null) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) + tc.GetConstructor(instanceBindingFlags, null, Array.ofList argtyps, null) + |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) - let bindCtor (tc, argTypes:Instantiable, tyargs) = + let bindCtor (tc, argTypes: Instantiable, tyargs) = let typ = mkNamedType (tc, tyargs) let argtyps = argTypes |> inst tyargs - typ.GetConstructor(instanceBindingFlags, null, Array.ofList argtyps, null) |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) + typ.GetConstructor(instanceBindingFlags, null, Array.ofList argtyps, null) + |> checkNonNullResult ("tc", SR.GetString(SR.QfailedToBindConstructor)) let chop n xs = if n < 0 then invalidArg "n" (SR.GetString(SR.inputMustBeNonNegative)) @@ -1167,17 +1256,17 @@ module Patterns = if ngmeth.GetGenericArguments().Length = 0 then ngmeth(* non generic *) else ngmeth.MakeGenericMethod(Array.ofList methTypeArgs) - let bindGenericMeth (tc:Type, argTypes : list>, retType, methName, numMethTyargs) = + let bindGenericMeth (tc: Type, argTypes, retType, methName, numMethTyargs) = bindMethodHelper(tc, methName, numMethTyargs, argTypes, retType) - let bindMeth ((tc:Type, argTypes : list>, retType, methName, numMethTyargs), tyargs) = + let bindMeth ((tc: Type, argTypes, retType, methName, numMethTyargs), tyargs) = let ntyargs = tc.GetGenericArguments().Length let enclTypeArgs, methTypeArgs = chop ntyargs tyargs let ty = mkNamedType (tc, enclTypeArgs) let ngmeth = bindMethodHelper(ty, methName, numMethTyargs, argTypes, retType) instMeth(ngmeth, methTypeArgs) - let pinfoIsStatic (pinfo:PropertyInfo) = + let pinfoIsStatic (pinfo: PropertyInfo) = if pinfo.CanRead then pinfo.GetGetMethod(true).IsStatic elif pinfo.CanWrite then pinfo.GetSetMethod(true).IsStatic else false @@ -1327,7 +1416,7 @@ module Patterns = elif a = "." then st.localAssembly else match System.Reflection.Assembly.Load a with - | null -> raise <| System.InvalidOperationException(String.Format(SR.GetString(SR.QfailedToBindAssembly), a.ToString())) + | null -> invalidOp(String.Format(SR.GetString(SR.QfailedToBindAssembly), a.ToString())) | assembly -> assembly let u_NamedType st = @@ -1375,18 +1464,18 @@ module Patterns = /// The number of indexes in the mapping varn: int /// The active type instantiation for generic type parameters - typeInst : int -> Type } + typeInst: int -> Type } let addVar env v = { env with vars = env.vars.Add(env.varn, v); varn=env.varn+1 } - let mkTyparSubst (tyargs:Type[]) = + let mkTyparSubst (tyargs: Type[]) = let n = tyargs.Length fun idx -> if idx < n then tyargs.[idx] - else raise <| System.InvalidOperationException (SR.GetString(SR.QtypeArgumentOutOfRange)) + else invalidOp (SR.GetString(SR.QtypeArgumentOutOfRange)) - let envClosed (spliceTypes:Type[]) = + let envClosed (spliceTypes: Type[]) = { vars = Map.empty varn = 0 typeInst = mkTyparSubst spliceTypes } @@ -1400,7 +1489,7 @@ module Patterns = let a = u_constSpec st let b = u_dtypes st let args = u_list u_Expr st - (fun (env:BindingEnv) -> + (fun (env: BindingEnv) -> let args = List.map (fun e -> e env) args let a = match a with @@ -1456,13 +1545,39 @@ module Patterns = let case, i = u_tup2 u_UnionCaseInfo u_int st (fun tyargs -> getUnionCaseInfoField(case tyargs, i)) - and u_ModuleDefn st = + and u_ModuleDefn witnessInfo st = let (ty, nm, isProp) = u_tup3 u_NamedType u_string u_bool st if isProp then Unique(StaticPropGetOp(bindModuleProperty(ty, nm))) else - match bindModuleFunction(ty, nm) with - | Some mi -> Unique(StaticMethodCallOp mi) - | None -> Ambiguous(fun argTypes tyargs -> StaticMethodCallOp(bindModuleFunctionWithCallSiteArgs(ty, nm, argTypes, tyargs))) + let meths = ty.GetMethods staticBindingFlags |> Array.filter (fun mi -> mi.Name = nm) + match meths with + | [||] -> + invalidOp (String.Format(SR.GetString(SR.QcannotBindFunction), nm, ty.ToString())) + | [| minfo |] -> + match witnessInfo with + | None -> + Unique(StaticMethodCallOp(minfo)) + | Some (nmW, nWitnesses) -> + let methsW = ty.GetMethods(staticBindingFlags) |> Array.filter (fun mi -> mi.Name = nmW) + match methsW with + | [||] -> + invalidOp (String.Format(SR.GetString(SR.QcannotBindFunction), nmW, ty.ToString())) + | [| minfoW |] -> + Unique(StaticMethodCallWOp(minfo, minfoW, nWitnesses)) + | _ -> + Ambiguous(fun argTypes tyargs -> + let minfoW = bindModuleFunctionWithCallSiteArgs(ty, nm, argTypes, tyargs) + StaticMethodCallWOp(minfo, minfoW, nWitnesses)) + | _ -> + Ambiguous(fun argTypes tyargs -> + match witnessInfo with + | None -> + let minfo = bindModuleFunctionWithCallSiteArgs(ty, nm, argTypes, tyargs) + StaticMethodCallOp minfo + | Some (nmW, nWitnesses) -> + let minfo = bindModuleFunctionWithCallSiteArgs(ty, nm, List.skip nWitnesses argTypes, tyargs) + let minfoW = bindModuleFunctionWithCallSiteArgs(ty, nmW, argTypes, tyargs) + StaticMethodCallWOp(minfo, minfoW, nWitnesses)) and u_MethodInfoData st = u_tup5 u_NamedType (u_list u_dtype) u_dtype u_string u_int st @@ -1477,7 +1592,7 @@ module Patterns = let tag = u_byte_as_int st match tag with | 0 -> - match u_ModuleDefn st with + match u_ModuleDefn None st with | Unique(StaticMethodCallOp minfo) -> (minfo :> MethodBase) | Unique(StaticPropGetOp pinfo) -> (pinfo.GetGetMethod true :> MethodBase) | Ambiguous(_) -> raise (System.Reflection.AmbiguousMatchException()) @@ -1494,24 +1609,42 @@ module Patterns = let data = u_CtorInfoData st let cinfo = bindGenericCtor data (cinfo :> MethodBase) + | 3 -> + let methNameW = u_string st + let nWitnesses = u_int st + match u_ModuleDefn (Some (methNameW, nWitnesses)) st with + | Unique(StaticMethodCallOp(minfo)) -> (minfo :> MethodBase) + | Unique(StaticMethodCallWOp(_minfo, minfoW, _)) -> (minfoW :> MethodBase) + | Unique(StaticPropGetOp(pinfo)) -> (pinfo.GetGetMethod(true) :> MethodBase) + | Ambiguous(_) -> raise (System.Reflection.AmbiguousMatchException()) + | _ -> failwith "unreachable" | _ -> failwith "u_MethodBase" + and instModuleDefnOp r tyargs = + match r with + | StaticMethodCallOp(minfo) -> StaticMethodCallOp(instMeth(minfo, tyargs)) + | StaticMethodCallWOp(minfo, minfoW, n) -> StaticMethodCallWOp(instMeth(minfo, tyargs), instMeth(minfoW, tyargs), n) + // OK to throw away the tyargs here since this only non-generic values in modules get represented by static properties + | x -> x + and u_constSpec st = let tag = u_byte_as_int st if tag = 1 then - let bindModuleDefn r tyargs = - match r with - | StaticMethodCallOp minfo -> StaticMethodCallOp(instMeth(minfo, tyargs)) - // OK to throw away the tyargs here since this only non-generic values in modules get represented by static properties - | x -> x - match u_ModuleDefn st with - | Unique r -> Unique(bindModuleDefn r) - | Ambiguous f -> Ambiguous(fun argTypes tyargs -> bindModuleDefn (f argTypes tyargs) tyargs) + match u_ModuleDefn None st with + | Unique r -> Unique (instModuleDefnOp r) + | Ambiguous f -> Ambiguous (fun argTypes tyargs -> instModuleDefnOp (f argTypes tyargs) tyargs) + elif tag = 51 then + let nmW = u_string st + let nWitnesses = u_int st + match u_ModuleDefn (Some (nmW, nWitnesses)) st with + | Unique r -> Unique(instModuleDefnOp r) + | Ambiguous f -> Ambiguous(fun argTypes tyargs -> instModuleDefnOp (f argTypes tyargs) tyargs) else let constSpec = match tag with | 0 -> u_void st |> (fun () NoTyArgs -> IfThenElseOp) + // 1 taken above | 2 -> u_void st |> (fun () NoTyArgs -> LetRecOp) | 3 -> u_NamedType st |> (fun x tyargs -> NewRecordOp (mkNamedType (x, tyargs))) | 4 -> u_RecdField st |> (fun prop tyargs -> InstancePropGetOp(prop tyargs)) @@ -1559,6 +1692,16 @@ module Patterns = | 47 -> u_void st |> (fun () NoTyArgs -> TryFinallyOp) | 48 -> u_void st |> (fun () NoTyArgs -> TryWithOp) | 49 -> u_void st |> (fun () NoTyArgs -> VarSetOp) + | 50 -> + let m1 = u_MethodInfoData st + let m2 = u_MethodInfoData st + let n = u_int st + (fun tyargs -> + let minfo = bindMeth (m1, tyargs) + let minfoW = bindMeth (m2, tyargs) + if minfo.IsStatic then StaticMethodCallWOp(minfo, minfoW, n) + else InstanceMethodCallWOp(minfo, minfoW, n)) + // 51 taken above | _ -> failwithf "u_constSpec, unrecognized tag %d" tag Unique constSpec @@ -1578,7 +1721,7 @@ module Patterns = //-------------------------------------------------------------------------- /// Fill the holes in an Expr - let rec fillHolesInRawExpr (l:Expr[]) (E t as e) = + let rec fillHolesInRawExpr (l: Expr[]) (E t as e) = match t with | VarTerm _ -> e | LambdaTerm (v, b) -> EA(LambdaTerm(v, fillHolesInRawExpr l b ), e.CustomAttributes) @@ -1648,11 +1791,10 @@ module Patterns = let decodedTopResources = new Dictionary(10, HashIdentity.Structural) - [] type ReflectedDefinitionTableKey = | Key of ModuleHandle * int - static member GetKey(methodBase:MethodBase) = + static member GetKey(methodBase: MethodBase) = Key(methodBase.Module.ModuleHandle, methodBase.MetadataToken) [] @@ -1668,6 +1810,7 @@ module Patterns = reflectedDefinitionTable.Add(key, Entry exprBuilder))) decodedTopResources.Add((assem, resourceName), 0) + /// Get the reflected definition at the given (always generic) instantiation let tryGetReflectedDefinition (methodBase: MethodBase, tyargs: Type []) = checkNonNull "methodBase" methodBase let data = @@ -1713,7 +1856,7 @@ module Patterns = |> List.iter (fun (resourceName, defns) -> defns |> List.iter (fun (methodBase, exprBuilder) -> reflectedDefinitionTable.[ReflectedDefinitionTableKey.GetKey methodBase] <- Entry exprBuilder) - decodedTopResources.Add((assem, resourceName), 0)) + decodedTopResources.[(assem, resourceName)] <- 0) // we know it's in the table now, if it's ever going to be there reflectedDefinitionTable.TryGetValue key ) @@ -1732,7 +1875,8 @@ module Patterns = Some(exprBuilder (envClosed tyargs)) | None -> None - let tryGetReflectedDefinitionInstantiated (methodBase:MethodBase) = + /// Get the reflected definition at the generic instantiation + let tryGetReflectedDefinitionInstantiated (methodBase: MethodBase) = checkNonNull "methodBase" methodBase match methodBase with | :? MethodInfo as minfo -> @@ -1764,63 +1908,73 @@ type Expr with member x.GetFreeVars () = (freeInExpr x :> seq<_>) member x.Type = typeOf x - static member AddressOf (target:Expr) = + static member AddressOf (target: Expr) = mkAddressOf target - static member AddressSet (target:Expr, value:Expr) = + static member AddressSet (target: Expr, value: Expr) = mkAddressSet (target, value) - static member Application (functionExpr:Expr, argument:Expr) = + static member Application (functionExpr: Expr, argument: Expr) = mkApplication (functionExpr, argument) - static member Applications (functionExpr:Expr, arguments) = + static member Applications (functionExpr: Expr, arguments) = mkApplications (functionExpr, arguments) static member Call (methodInfo:MethodInfo, arguments) = checkNonNull "methodInfo" methodInfo mkStaticMethodCall (methodInfo, arguments) - static member Call (obj:Expr, methodInfo:MethodInfo, arguments) = + static member Call (obj: Expr, methodInfo:MethodInfo, arguments) = checkNonNull "methodInfo" methodInfo mkInstanceMethodCall (obj, methodInfo, arguments) - static member Coerce (source:Expr, target:Type) = + static member CallWithWitnesses (methodInfo: MethodInfo, methodInfoWithWitnesses: MethodInfo, witnesses, arguments) = + checkNonNull "methodInfo" methodInfo + checkNonNull "methodInfoWithWitnesses" methodInfoWithWitnesses + mkStaticMethodCallW (methodInfo, methodInfoWithWitnesses, List.length witnesses, witnesses@arguments) + + static member CallWithWitnesses (obj: Expr, methodInfo: MethodInfo, methodInfoWithWitnesses: MethodInfo, witnesses, arguments) = + checkNonNull "methodInfo" methodInfo + checkNonNull "methodInfoWithWitnesses" methodInfoWithWitnesses + mkInstanceMethodCallW (obj, methodInfo, methodInfoWithWitnesses, List.length witnesses, witnesses@arguments) + + static member Coerce (source: Expr, target: Type) = checkNonNull "target" target mkCoerce (target, source) - static member IfThenElse (guard:Expr, thenExpr:Expr, elseExpr:Expr) = + static member IfThenElse (guard: Expr, thenExpr: Expr, elseExpr: Expr) = mkIfThenElse (guard, thenExpr, elseExpr) - static member ForIntegerRangeLoop (loopVariable, start:Expr, endExpr:Expr, body:Expr) = + static member ForIntegerRangeLoop (loopVariable, start: Expr, endExpr: Expr, body: Expr) = mkForLoop(loopVariable, start, endExpr, body) static member FieldGet (fieldInfo:FieldInfo) = checkNonNull "fieldInfo" fieldInfo mkStaticFieldGet fieldInfo - static member FieldGet (obj:Expr, fieldInfo:FieldInfo) = + static member FieldGet (obj: Expr, fieldInfo:FieldInfo) = checkNonNull "fieldInfo" fieldInfo mkInstanceFieldGet (obj, fieldInfo) - static member FieldSet (fieldInfo:FieldInfo, value:Expr) = + static member FieldSet (fieldInfo:FieldInfo, value: Expr) = checkNonNull "fieldInfo" fieldInfo mkStaticFieldSet (fieldInfo, value) - static member FieldSet (obj:Expr, fieldInfo:FieldInfo, value:Expr) = + static member FieldSet (obj: Expr, fieldInfo:FieldInfo, value: Expr) = checkNonNull "fieldInfo" fieldInfo mkInstanceFieldSet (obj, fieldInfo, value) - static member Lambda (parameter:Var, body:Expr) = mkLambda (parameter, body) + static member Lambda (parameter: Var, body: Expr) = mkLambda (parameter, body) - static member Let (letVariable:Var, letExpr:Expr, body:Expr) = mkLet (letVariable, letExpr, body) + static member Let (letVariable: Var, letExpr: Expr, body: Expr) = mkLet (letVariable, letExpr, body) - static member LetRecursive (bindings, body:Expr) = mkLetRec (bindings, body) + static member LetRecursive (bindings, body: Expr) = mkLetRec (bindings, body) static member NewObject (constructorInfo:ConstructorInfo, arguments) = checkNonNull "constructorInfo" constructorInfo mkCtorCall (constructorInfo, arguments) - static member DefaultValue (expressionType:Type) = + static member DefaultValue (expressionType: Type) = checkNonNull "expressionType" expressionType mkDefaultValue expressionType @@ -1830,22 +1984,22 @@ type Expr with static member NewStructTuple (asm:Assembly, elements) = mkNewStructTuple (asm, elements) - static member NewRecord (recordType:Type, elements) = + static member NewRecord (recordType: Type, elements) = checkNonNull "recordType" recordType mkNewRecord (recordType, elements) - static member NewArray (elementType:Type, elements) = + static member NewArray (elementType: Type, elements) = checkNonNull "elementType" elementType mkNewArray(elementType, elements) - static member NewDelegate (delegateType:Type, parameters: Var list, body: Expr) = + static member NewDelegate (delegateType: Type, parameters: Var list, body: Expr) = checkNonNull "delegateType" delegateType mkNewDelegate(delegateType, mkIteratedLambdas (parameters, body)) static member NewUnionCase (unionCase, arguments) = mkNewUnionCase (unionCase, arguments) - static member PropertyGet (obj:Expr, property: PropertyInfo, ?indexerArgs) = + static member PropertyGet (obj: Expr, property: PropertyInfo, ?indexerArgs) = checkNonNull "property" property mkInstancePropGet (obj, property, defaultArg indexerArgs []) @@ -1853,46 +2007,46 @@ type Expr with checkNonNull "property" property mkStaticPropGet (property, defaultArg indexerArgs []) - static member PropertySet (obj:Expr, property:PropertyInfo, value:Expr, ?indexerArgs) = + static member PropertySet (obj: Expr, property: PropertyInfo, value: Expr, ?indexerArgs) = checkNonNull "property" property mkInstancePropSet(obj, property, defaultArg indexerArgs [], value) - static member PropertySet (property:PropertyInfo, value:Expr, ?indexerArgs) = + static member PropertySet (property: PropertyInfo, value: Expr, ?indexerArgs) = mkStaticPropSet(property, defaultArg indexerArgs [], value) - static member Quote (inner:Expr) = mkQuote (inner, true) + static member Quote (inner: Expr) = mkQuote (inner, true) - static member QuoteRaw (inner:Expr) = mkQuote (inner, false) + static member QuoteRaw (inner: Expr) = mkQuote (inner, false) - static member QuoteTyped (inner:Expr) = mkQuote (inner, true) + static member QuoteTyped (inner: Expr) = mkQuote (inner, true) - static member Sequential (first:Expr, second:Expr) = + static member Sequential (first: Expr, second: Expr) = mkSequential (first, second) - static member TryWith (body:Expr, filterVar:Var, filterBody:Expr, catchVar:Var, catchBody:Expr) = + static member TryWith (body: Expr, filterVar: Var, filterBody: Expr, catchVar: Var, catchBody: Expr) = mkTryWith (body, filterVar, filterBody, catchVar, catchBody) - static member TryFinally (body:Expr, compensation:Expr) = + static member TryFinally (body: Expr, compensation: Expr) = mkTryFinally (body, compensation) - static member TupleGet (tuple:Expr, index:int) = + static member TupleGet (tuple: Expr, index: int) = mkTupleGet (typeOf tuple, index, tuple) static member TypeTest (source: Expr, target: Type) = checkNonNull "target" target mkTypeTest (source, target) - static member UnionCaseTest (source:Expr, unionCase: UnionCaseInfo) = + static member UnionCaseTest (source: Expr, unionCase: UnionCaseInfo) = mkUnionCaseTest (unionCase, source) - static member Value (value:'T) = + static member Value (value: 'T) = mkValue (box value, typeof<'T>) static member Value(value: obj, expressionType: Type) = checkNonNull "expressionType" expressionType mkValue(value, expressionType) - static member ValueWithName (value:'T, name:string) = + static member ValueWithName (value: 'T, name:string) = checkNonNull "name" name mkValueWithName (box value, typeof<'T>, name) @@ -1901,7 +2055,7 @@ type Expr with checkNonNull "name" name mkValueWithName(value, expressionType, name) - static member WithValue (value:'T, definition: Expr<'T>) = + static member WithValue (value: 'T, definition: Expr<'T>) = let raw = mkValueWithDefn(box value, typeof<'T>, definition) new Expr<'T>(raw.Tree, raw.CustomAttributes) @@ -1909,28 +2063,27 @@ type Expr with checkNonNull "expressionType" expressionType mkValueWithDefn (value, expressionType, definition) - static member Var variable = mkVar variable - static member VarSet (variable, value:Expr) = + static member VarSet (variable, value: Expr) = mkVarSet (variable, value) - static member WhileLoop (guard:Expr, body:Expr) = + static member WhileLoop (guard: Expr, body: Expr) = mkWhileLoop (guard, body) - static member TryGetReflectedDefinition(methodBase:MethodBase) = + static member TryGetReflectedDefinition(methodBase: MethodBase) = checkNonNull "methodBase" methodBase tryGetReflectedDefinitionInstantiated methodBase - static member Cast(source:Expr) = cast source + static member Cast(source: Expr) = cast source - static member Deserialize(qualifyingType:Type, spliceTypes, spliceExprs, bytes: byte[]) = + static member Deserialize(qualifyingType: Type, spliceTypes, spliceExprs, bytes: byte[]) = checkNonNull "qualifyingType" qualifyingType checkNonNull "bytes" bytes deserialize (qualifyingType, [| |], Array.ofList spliceTypes, Array.ofList spliceExprs, bytes) - static member Deserialize40(qualifyingType:Type, referencedTypes, spliceTypes, spliceExprs, bytes: byte[]) = + static member Deserialize40(qualifyingType: Type, referencedTypes, spliceTypes, spliceExprs, bytes: byte[]) = checkNonNull "spliceExprs" spliceExprs checkNonNull "spliceTypes" spliceTypes checkNonNull "referencedTypeDefs" referencedTypes @@ -1955,30 +2108,43 @@ module DerivedPatterns = [] let (|Bool|_|) input = match input with ValueObj(:? bool as v) -> Some v | _ -> None + [] let (|String|_|) input = match input with ValueObj(:? string as v) -> Some v | _ -> None + [] let (|Single|_|) input = match input with ValueObj(:? single as v) -> Some v | _ -> None + [] let (|Double|_|) input = match input with ValueObj(:? double as v) -> Some v | _ -> None + [] let (|Char|_|) input = match input with ValueObj(:? char as v) -> Some v | _ -> None + [] let (|SByte|_|) input = match input with ValueObj(:? sbyte as v) -> Some v | _ -> None + [] let (|Byte|_|) input = match input with ValueObj(:? byte as v) -> Some v | _ -> None + [] let (|Int16|_|) input = match input with ValueObj(:? int16 as v) -> Some v | _ -> None + [] let (|UInt16|_|) input = match input with ValueObj(:? uint16 as v) -> Some v | _ -> None + [] let (|Int32|_|) input = match input with ValueObj(:? int32 as v) -> Some v | _ -> None + [] let (|UInt32|_|) input = match input with ValueObj(:? uint32 as v) -> Some v | _ -> None + [] let (|Int64|_|) input = match input with ValueObj(:? int64 as v) -> Some v | _ -> None + [] let (|UInt64|_|) input = match input with ValueObj(:? uint64 as v) -> Some v | _ -> None + [] let (|Unit|_|) input = match input with Comb0(ValueOp(_, ty, None)) when ty = typeof -> Some() | _ -> None @@ -1986,7 +2152,7 @@ module DerivedPatterns = /// This reverses this encoding. let (|TupledLambda|_|) (lam: Expr) = /// Strip off the 'let' bindings for an TupledLambda - let rec stripSuccessiveProjLets (p:Var) n expr = + let rec stripSuccessiveProjLets (p: Var) n expr = match expr with | Let(v1, TupleGet(Var pA, m), rest) when p = pA && m = n-> @@ -2011,8 +2177,10 @@ module DerivedPatterns = [] let (|Lambdas|_|) (input: Expr) = qOneOrMoreRLinear (|TupledLambda|_|) input + [] let (|Applications|_|) (input: Expr) = qOneOrMoreLLinear (|TupledApplication|_|) input + /// Reverse the compilation of And and Or [] let (|AndAlso|_|) input = @@ -2109,6 +2277,8 @@ module ExprShape = | DefaultValueOp ty, _ -> mkDefaultValue ty | StaticMethodCallOp minfo, _ -> mkStaticMethodCall(minfo, arguments) | InstanceMethodCallOp minfo, obj :: args -> mkInstanceMethodCall(obj, minfo, args) + | StaticMethodCallWOp (minfo, minfoW, n), _ -> mkStaticMethodCallW(minfo, minfoW, n, arguments) + | InstanceMethodCallWOp (minfo, minfoW, n), obj::args -> mkInstanceMethodCallW(obj, minfo, minfoW, n, args) | CoerceOp ty, [arg] -> mkCoerce(ty, arg) | NewArrayOp ty, _ -> mkNewArray(ty, arguments) | NewDelegateOp ty, [arg] -> mkNewDelegate(ty, arg) @@ -2125,8 +2295,7 @@ module ExprShape = | ValueOp(v, ty, None), [] -> mkValue(v, ty) | ValueOp(v, ty, Some nm), [] -> mkValueWithName(v, ty, nm) | WithValueOp(v, ty), [e] -> mkValueWithDefn(v, ty, e) - | _ -> raise <| System.InvalidOperationException (SR.GetString(SR.QillFormedAppOrLet)) - + | _ -> invalidOp (SR.GetString(SR.QillFormedAppOrLet)) EA(e.Tree, attrs) diff --git a/src/fsharp/FSharp.Core/quotations.fsi b/src/fsharp/FSharp.Core/quotations.fsi index a782140fe43..98d299d38f4 100644 --- a/src/fsharp/FSharp.Core/quotations.fsi +++ b/src/fsharp/FSharp.Core/quotations.fsi @@ -10,30 +10,49 @@ open System open System.Reflection /// Information at the binding site of a variable +/// +/// +/// Library functionality for F# quotations. +/// See also F# Code Quotations in the F# Language Guide. +/// [] [] type Var = /// The type associated with the variable + /// + /// member Type : Type /// The declared name of the variable + /// + /// member Name : string /// Indicates if the variable represents a mutable storage location + /// + /// member IsMutable: bool /// Creates a new variable with the given name, type and mutability + /// /// The declared name of the variable. /// The type associated with the variable. /// Indicates if the variable represents a mutable storage location. Default is false. + /// /// The created variable. + /// + /// new : name:string * typ:Type * ?isMutable : bool -> Var /// Fetches or create a new variable with the given name and type from a global pool of shared variables /// indexed by name and type + /// /// The name of the variable. /// The type associated with the variable. + /// /// The retrieved or created variable. + /// + /// static member Global : name:string * typ:Type -> Var interface System.IComparable @@ -47,376 +66,614 @@ type Expr = /// to map variables to new values. The functions must give consistent results /// at each application. Variable renaming may occur on the target expression /// if variable capture occurs. + /// /// The function to map variables into expressions. + /// /// The expression with the given substitutions. + /// + /// member Substitute : substitution:(Var -> Expr option) -> Expr /// Gets the free expression variables of an expression as a list. /// A sequence of the free variables in the expression. + /// + /// member GetFreeVars : unit -> seq /// Returns type of an expression. + /// + /// member Type : Type /// Returns the custom attributes of an expression. + /// + /// member CustomAttributes : Expr list override Equals : obj:obj -> bool /// Builds an expression that represents getting the address of a value. + /// /// The target expression. + /// /// The resulting expression. + /// + /// static member AddressOf : target:Expr -> Expr /// Builds an expression that represents setting the value held at a particular address. + /// /// The target expression. /// The value to set at the address. + /// /// The resulting expression. + /// + /// static member AddressSet : target:Expr * value:Expr -> Expr /// Builds an expression that represents the application of a first class function value to a single argument. + /// /// The function to apply. /// The argument to the function. + /// /// The resulting expression. + /// + /// static member Application: functionExpr:Expr * argument:Expr -> Expr /// Builds an expression that represents the application of a first class function value to multiple arguments + /// /// The function to apply. /// The list of lists of arguments to the function. + /// /// The resulting expression. + /// + /// static member Applications: functionExpr:Expr * arguments:list> -> Expr /// Builds an expression that represents a call to an static method or module-bound function + /// /// The MethodInfo describing the method to call. /// The list of arguments to the method. + /// /// The resulting expression. + /// + /// static member Call : methodInfo:MethodInfo * arguments:list -> Expr /// Builds an expression that represents a call to an instance method associated with an object + /// /// The input object. /// The description of the method to call. /// The list of arguments to the method. + /// /// The resulting expression. + /// + /// static member Call : obj:Expr * methodInfo:MethodInfo * arguments:list -> Expr + /// Builds an expression that represents a call to an static method or module-bound function + /// + /// The MethodInfo describing the method to call. + /// The additional MethodInfo describing the method to call, accepting witnesses. + /// The list of witnesses to the method. + /// The list of arguments to the method. + /// + /// The resulting expression. + /// + /// + static member CallWithWitnesses: methodInfo: MethodInfo * methodInfoWithWitnesses: MethodInfo * witnesses: Expr list * arguments: Expr list -> Expr + + /// Builds an expression that represents a call to an instance method associated with an object + /// + /// The input object. + /// The description of the method to call. + /// The additional MethodInfo describing the method to call, accepting witnesses. + /// The list of witnesses to the method. + /// The list of arguments to the method. + /// + /// The resulting expression. + /// + /// + static member CallWithWitnesses: obj:Expr * methodInfo:MethodInfo * methodInfoWithWitnesses: MethodInfo * witnesses: Expr list * arguments:Expr list -> Expr + /// Builds an expression that represents the coercion of an expression to a type + /// /// The expression to coerce. /// The target type. + /// /// The resulting expression. + /// + /// static member Coerce : source:Expr * target:Type -> Expr /// Builds 'if ... then ... else' expressions. + /// /// The condition expression. /// The then sub-expression. /// The else sub-expression. + /// /// The resulting expression. + /// + /// static member IfThenElse : guard:Expr * thenExpr:Expr * elseExpr:Expr -> Expr /// Builds a 'for i = ... to ... do ...' expression that represent loops over integer ranges + /// /// The sub-expression declaring the loop variable. /// The sub-expression setting the initial value of the loop variable. /// The sub-expression declaring the final value of the loop variable. /// The sub-expression representing the body of the loop. + /// /// The resulting expression. + /// + /// static member ForIntegerRangeLoop: loopVariable:Var * start:Expr * endExpr:Expr * body:Expr -> Expr /// Builds an expression that represents the access of a static field + /// /// The description of the field to access. + /// /// The resulting expression. + /// + /// static member FieldGet: fieldInfo:FieldInfo -> Expr /// Builds an expression that represents the access of a field of an object + /// /// The input object. /// The description of the field to access. + /// /// The resulting expression. + /// + /// static member FieldGet: obj:Expr * fieldInfo:FieldInfo -> Expr /// Builds an expression that represents writing to a static field + /// /// The description of the field to write to. /// The value to the set to the field. + /// /// The resulting expression. + /// + /// static member FieldSet: fieldInfo:FieldInfo * value:Expr -> Expr /// Builds an expression that represents writing to a field of an object + /// /// The input object. /// The description of the field to write to. /// The value to set to the field. + /// /// The resulting expression. + /// + /// static member FieldSet: obj:Expr * fieldInfo:FieldInfo * value:Expr -> Expr /// Builds an expression that represents the construction of an F# function value + /// /// The parameter to the function. /// The body of the function. + /// /// The resulting expression. + /// + /// static member Lambda : parameter:Var * body:Expr -> Expr /// Builds expressions associated with 'let' constructs + /// /// The variable in the let expression. /// The expression bound to the variable. /// The sub-expression where the binding is in scope. + /// /// The resulting expression. + /// + /// static member Let : letVariable:Var * letExpr:Expr * body:Expr -> Expr /// Builds recursive expressions associated with 'let rec' constructs + /// /// The list of bindings for the let expression. /// The sub-expression where the bindings are in scope. + /// /// The resulting expression. + /// + /// static member LetRecursive : bindings:(Var * Expr) list * body:Expr -> Expr /// Builds an expression that represents the invocation of an object constructor + /// /// The description of the constructor. /// The list of arguments to the constructor. + /// /// The resulting expression. + /// + /// static member NewObject: constructorInfo:ConstructorInfo * arguments:Expr list -> Expr - /// Builds an expression that represents the invocation of a default object constructor + /// /// The type on which the constructor is invoked. + /// /// The resulting expression. + /// + /// static member DefaultValue: expressionType:Type -> Expr - /// Builds an expression that represents the creation of an F# tuple value + /// /// The list of elements of the tuple. + /// /// The resulting expression. + /// + /// static member NewTuple: elements:Expr list -> Expr /// Builds an expression that represents the creation of an F# tuple value + /// /// Runtime assembly containing System.ValueTuple definitions. /// The list of elements of the tuple. + /// /// The resulting expression. + /// + /// static member NewStructTuple: asm:Assembly * elements:Expr list -> Expr /// Builds record-construction expressions + /// /// The type of record. /// The list of elements of the record. + /// /// The resulting expression. + /// + /// static member NewRecord: recordType:Type * elements:Expr list -> Expr /// Builds an expression that represents the creation of an array value initialized with the given elements + /// /// The type for the elements of the array. /// The list of elements of the array. + /// /// The resulting expression. + /// + /// static member NewArray: elementType:Type * elements:Expr list -> Expr /// Builds an expression that represents the creation of a delegate value for the given type + /// /// The type of delegate. /// The parameters for the delegate. /// The body of the function. + /// /// The resulting expression. + /// + /// static member NewDelegate: delegateType:Type * parameters:Var list * body:Expr -> Expr /// Builds an expression that represents the creation of a union case value + /// /// The description of the union case. /// The list of arguments for the case. + /// /// The resulting expression. + /// + /// static member NewUnionCase: unionCase:UnionCaseInfo * arguments:Expr list -> Expr /// Builds an expression that represents reading a property of an object + /// /// The input object. /// The description of the property. /// List of indices for the property if it is an indexed property. + /// /// The resulting expression. + /// + /// static member PropertyGet: obj:Expr * property:PropertyInfo * ?indexerArgs: Expr list -> Expr /// Builds an expression that represents reading a static property + /// /// The description of the property. /// List of indices for the property if it is an indexed property. + /// /// The resulting expression. + /// + /// static member PropertyGet: property:PropertyInfo * ?indexerArgs: Expr list -> Expr /// Builds an expression that represents writing to a property of an object + /// /// The input object. /// The description of the property. /// The value to set. /// List of indices for the property if it is an indexed property. + /// /// The resulting expression. + /// + /// static member PropertySet: obj:Expr * property:PropertyInfo * value:Expr * ?indexerArgs: Expr list -> Expr /// Builds an expression that represents writing to a static property + /// /// The description of the property. /// The value to set. /// List of indices for the property if it is an indexed property. + /// /// The resulting expression. + /// + /// static member PropertySet: property:PropertyInfo * value:Expr * ?indexerArgs: Expr list -> Expr /// Builds an expression that represents a nested typed or raw quotation literal + /// /// The expression being quoted. + /// /// The resulting expression. [] + /// + /// static member Quote: inner:Expr -> Expr /// Builds an expression that represents a nested raw quotation literal + /// /// The expression being quoted. + /// /// The resulting expression. + /// + /// static member QuoteRaw: inner:Expr -> Expr /// Builds an expression that represents a nested typed quotation literal + /// /// The expression being quoted. + /// /// The resulting expression. + /// + /// static member QuoteTyped: inner:Expr -> Expr /// Builds an expression that represents the sequential execution of one expression followed by another + /// /// The first expression. /// The second expression. + /// /// The resulting expression. + /// + /// static member Sequential: first:Expr * second:Expr -> Expr /// Builds an expression that represents a try/with construct for exception filtering and catching. + /// /// The body of the try expression. /// /// /// The variable to bind to a caught exception. /// The expression evaluated when an exception is caught. + /// /// The resulting expression. + /// + /// static member TryWith: body:Expr * filterVar:Var * filterBody:Expr * catchVar:Var * catchBody:Expr -> Expr /// Builds an expression that represents a try/finally construct + /// /// The body of the try expression. /// The final part of the expression to be evaluated. + /// /// The resulting expression. + /// + /// static member TryFinally: body:Expr * compensation:Expr -> Expr /// Builds an expression that represents getting a field of a tuple + /// /// The input tuple. /// The index of the tuple element to get. + /// /// The resulting expression. + /// + /// static member TupleGet: tuple:Expr * index:int -> Expr /// Builds an expression that represents a type test. + /// /// The expression to test. /// The target type. + /// /// The resulting expression. + /// + /// static member TypeTest: source:Expr * target:Type -> Expr /// Builds an expression that represents a test of a value is of a particular union case + /// /// The expression to test. /// The description of the union case. + /// /// The resulting expression. + /// + /// static member UnionCaseTest: source:Expr * unionCase:UnionCaseInfo -> Expr /// Builds an expression that represents a constant value of a particular type + /// /// The untyped object. /// The type of the object. + /// /// The resulting expression. + /// + /// static member Value : value:obj * expressionType:Type -> Expr /// Builds an expression that represents a constant value + /// /// The typed value. + /// /// The resulting expression. + /// + /// static member Value : value:'T -> Expr /// Builds an expression that represents a constant value, arising from a variable of the given name + /// /// The typed value. /// The name of the variable. + /// /// The resulting expression. + /// + /// static member ValueWithName : value:'T * name: string -> Expr /// Builds an expression that represents a constant value of a particular type, arising from a variable of the given name + /// /// The untyped object. /// The type of the object. /// The name of the variable. + /// /// The resulting expression. + /// + /// static member ValueWithName : value:obj * expressionType:Type * name: string -> Expr /// Builds an expression that represents a value and its associated reflected definition as a quotation + /// /// The value being quoted. /// The definition of the value being quoted. + /// /// The resulting expression. + /// + /// static member WithValue: value: 'T * definition: Expr<'T> -> Expr<'T> - /// Builds an expression that represents a value and its associated reflected definition as a quotation + /// /// The untyped object. /// The type of the object. /// The definition of the value being quoted. + /// /// The resulting expression. + /// + /// static member WithValue: value: obj * expressionType:Type * definition: Expr -> Expr - - /// Builds an expression that represents a variable + /// /// The input variable. + /// /// The resulting expression. + /// + /// static member Var : variable:Var -> Expr /// Builds an expression that represents setting a mutable variable + /// /// The input variable. /// The value to set. + /// /// The resulting expression. + /// + /// static member VarSet : variable:Var * value:Expr -> Expr /// Builds an expression that represents a while loop + /// /// The predicate to control the loop iteration. /// The body of the while loop. + /// /// The resulting expression. + /// + /// static member WhileLoop : guard:Expr * body:Expr -> Expr - //---------------- - - /// Returns a new typed expression given an underlying runtime-typed expression. /// A type annotation is usually required to use this function, and /// using an incorrect type annotation may result in a later runtime exception. + /// /// The expression to cast. + /// /// The resulting typed expression. + /// + /// static member Cast : source:Expr -> Expr<'T> /// Try and find a stored reflection definition for the given method. Stored reflection /// definitions are added to an F# assembly through the use of the [<ReflectedDefinition>] attribute. + /// /// The description of the method to find. + /// /// The reflection definition or None if a match could not be found. + /// + /// static member TryGetReflectedDefinition : methodBase:MethodBase -> Expr option /// This function is called automatically when quotation syntax (<@ @>) and other sources of /// quotations are used. + /// /// A type in the assembly where the quotation occurs. /// The spliced types, to replace references to type variables. /// The spliced expressions to replace references to spliced expressions. /// The serialized form of the quoted expression. + /// /// The resulting expression. + /// + /// static member Deserialize : qualifyingType:System.Type * spliceTypes:list * spliceExprs:list * bytes:byte[] -> Expr /// This function is called automatically when quotation syntax (<@ @>) and other sources of /// quotations are used. + /// /// A type in the assembly where the quotation occurs. /// The type definitions referenced. /// The spliced types, to replace references to type variables. /// The spliced expressions to replace references to spliced expressions. /// The serialized form of the quoted expression. + /// /// The resulting expression. + /// + /// static member Deserialize40 : qualifyingType:Type * referencedTypes:Type[] * spliceTypes:Type[] * spliceExprs:Expr[] * bytes:byte[] -> Expr /// Permits interactive environments such as F# Interactive /// to explicitly register new pickled resources that represent persisted /// top level definitions. + /// /// The assembly associated with the resource. /// The unique name for the resources being added. /// The serialized resource to register with the environment. + /// + /// static member RegisterReflectedDefinitions: assembly:Assembly * resource:string * serializedValue:byte[] -> unit /// Permits interactive environments such as F# Interactive /// to explicitly register new pickled resources that represent persisted /// top level definitions. + /// /// The assembly associated with the resource. /// The unique name for the resources being added. /// The type definitions referenced. /// The serialized resource to register with the environment. + /// + /// static member RegisterReflectedDefinitions: assembly:Assembly * resource:string * serializedValue:byte[] * referencedTypes:Type[] -> unit /// Fetches or creates a new variable with the given name and type from a global pool of shared variables /// indexed by name and type. The type is given by the explicit or inferred type parameter + /// /// The variable name. + /// /// The created of fetched typed global variable. + /// + /// static member GlobalVar<'T> : name:string -> Expr<'T> /// Format the expression as a string + /// /// Indicates if method, property, constructor and type objects should be printed in detail. If false, these are abbreviated to their name. + /// /// The formatted string. member ToString : full: bool -> string - /// Type-carrying quoted expressions. Expressions are generated either /// by quotations in source text or programatically and [] @@ -424,352 +681,586 @@ and [] Expr<'T> = inherit Expr /// Gets the raw expression associated with this type-carrying expression + /// + /// member Raw : Expr - [] /// Contains a set of primitive F# active patterns to analyze F# expression objects module Patterns = /// An active pattern to recognize expressions that represent getting the address of a value + /// /// The input expression to match against. - /// Expr option + /// + /// When successful, the pattern binds the sub-expression of the input AddressOf expression + /// + /// [] val (|AddressOf|_|) : input:Expr -> Expr option /// An active pattern to recognize expressions that represent setting the value held at an address + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the target and value expressions of the input expression + /// + /// [] val (|AddressSet|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions that represent applications of first class function values + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the function and argument of the input expression + /// + /// [] val (|Application|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions that represent calls to static and instance methods, and functions defined in modules + /// /// The input expression to match against. - /// (Expr option * MethodInfo * Expr list) option + /// + /// When successful, the pattern binds the object, method and argument sub-expressions of the input expression + /// + /// [] val (|Call|_|) : input:Expr -> (Expr option * MethodInfo * Expr list) option + /// An active pattern to recognize expressions that represent calls to static and instance methods, and functions defined in modules, including witness arguments + /// + /// The input expression to match against. + /// + /// When successful, the pattern binds the object, method, witness-argument and argument sub-expressions of the input expression + /// + /// + [] + val (|CallWithWitnesses|_|) : input:Expr -> (Expr option * MethodInfo * MethodInfo * Expr list * Expr list) option + /// An active pattern to recognize expressions that represent coercions from one type to another + /// /// The input expression to match against. - /// (Expr * Type) option + /// + /// When successful, the pattern binds the source expression and target type of the input expression + /// + /// [] val (|Coerce|_|) : input:Expr -> (Expr * Type) option /// An active pattern to recognize expressions that represent getting a static or instance field + /// /// The input expression to match against. - /// (Expr option * FieldInfo) option + /// + /// When successful, the pattern binds the object and field of the input expression + /// + /// [] val (|FieldGet|_|) : input:Expr -> (Expr option * FieldInfo) option /// An active pattern to recognize expressions that represent setting a static or instance field + /// /// The input expression to match against. - /// (Expr option * FieldInfo * Expr) option + /// + /// When successful, the pattern binds the object, field and value of the input expression + /// + /// [] val (|FieldSet|_|) : input:Expr -> (Expr option * FieldInfo * Expr) option /// An active pattern to recognize expressions that represent loops over integer ranges + /// /// The input expression to match against. - /// (Var * Expr * Expr * Expr) option + /// + /// When successful, the pattern binds the value, start, finish and body of the input expression + /// + /// [] val (|ForIntegerRangeLoop|_|) : input:Expr -> (Var * Expr * Expr * Expr) option /// An active pattern to recognize expressions that represent while loops + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the guard and body of the input expression + /// + /// [] val (|WhileLoop|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions that represent conditionals + /// /// The input expression to match against. - /// (Expr * Expr * Expr) option + /// + /// When successful, the pattern binds the condition, then-branch and else-branch of the input expression + /// + /// [] val (|IfThenElse|_|) : input:Expr -> (Expr * Expr * Expr) option /// An active pattern to recognize expressions that represent first class function values + /// /// The input expression to match against. - /// (Var * Expr) option + /// + /// When successful, the pattern binds the variable and body of the input expression + /// + /// [] val (|Lambda|_|) : input:Expr -> (Var * Expr) option /// An active pattern to recognize expressions that represent let bindings + /// /// The input expression to match against. - /// (Var * Expr * Expr) option + /// + /// When successful, the pattern binds the variable, binding expression and body of the input expression + /// + /// [] val (|Let|_|) : input:Expr -> (Var * Expr * Expr) option /// An active pattern to recognize expressions that represent recursive let bindings of one or more variables + /// /// The input expression to match against. - /// ((Var * Expr) list * Expr) option + /// + /// When successful, the pattern binds the bindings and body of the input expression + /// + /// [] val (|LetRecursive|_|) : input:Expr -> ((Var * Expr) list * Expr) option /// An active pattern to recognize expressions that represent the construction of arrays + /// /// The input expression to match against. - /// (Type * Expr list) option + /// + /// When successful, the pattern binds the element type and values of the input expression + /// + /// [] val (|NewArray|_|) : input:Expr -> (Type * Expr list) option /// An active pattern to recognize expressions that represent invocations of a default constructor of a struct + /// /// The input expression to match against. - /// Type option + /// + /// When successful, the pattern binds the relevant type of the input expression + /// + /// [] val (|DefaultValue|_|) : input:Expr -> Type option /// An active pattern to recognize expressions that represent construction of delegate values + /// /// The input expression to match against. - /// (Type * Var list * Expr) option + /// + /// When successful, the pattern binds the delegate type, argument parameters and body of the input expression + /// + /// [] val (|NewDelegate|_|) : input:Expr -> (Type * Var list * Expr) option /// An active pattern to recognize expressions that represent invocation of object constructors + /// /// The input expression to match against. - /// (ConstructorInfo * Expr list) option + /// + /// When successful, the pattern binds the constructor and arguments of the input expression + /// + /// [] val (|NewObject|_|) : input:Expr -> (ConstructorInfo * Expr list) option /// An active pattern to recognize expressions that represent construction of record values + /// /// The input expression to match against. - /// (Type * Expr list) option + /// + /// When successful, the pattern binds the record type and field values of the input expression + /// + /// [] val (|NewRecord|_|) : input:Expr -> (Type * Expr list) option /// An active pattern to recognize expressions that represent construction of particular union case values + /// /// The input expression to match against. - /// (UnionCaseInfo * Expr list) option + /// + /// When successful, the pattern binds the union case and field values of the input expression + /// + /// [] val (|NewUnionCase|_|) : input:Expr -> (UnionCaseInfo * Expr list) option /// An active pattern to recognize expressions that represent construction of tuple values + /// /// The input expression to match against. - /// (Expr list) option + /// + /// When successful, the pattern binds the element expressions of the input expression + /// + /// [] val (|NewTuple|_|) : input:Expr -> (Expr list) option /// An active pattern to recognize expressions that represent construction of struct tuple values + /// /// The input expression to match against. - /// (Expr list) option + /// + /// When successful, the pattern binds the element expressions of the input expression + /// + /// [] val (|NewStructTuple|_|) : input:Expr -> (Expr list) option /// An active pattern to recognize expressions that represent the read of a static or instance property, or a non-function value declared in a module + /// /// The input expression to match against. - /// (Expr option * PropertyInfo * Expr list) option + /// + /// When successful, the pattern binds the object, property and indexer arguments of the input expression + /// + /// [] val (|PropertyGet|_|) : input:Expr -> (Expr option * PropertyInfo * Expr list) option /// An active pattern to recognize expressions that represent setting a static or instance property, or a non-function value declared in a module + /// /// The input expression to match against. - /// (Expr option * PropertyInfo * Expr list * Expr) option + /// + /// When successful, the pattern binds the object, property, indexer arguments and setter value of the input expression + /// + /// [] val (|PropertySet|_|) : input:Expr -> (Expr option * PropertyInfo * Expr list * Expr) option /// An active pattern to recognize expressions that represent a nested quotation literal + /// /// The input expression to match against. - /// Expr option + /// + /// When successful, the pattern binds the nested quotation expression of the input expression + /// + /// [] [] val (|Quote|_|) : input:Expr -> Expr option /// An active pattern to recognize expressions that represent a nested raw quotation literal + /// /// The input expression to match against. - /// Expr option + /// + /// When successful, the pattern binds the nested quotation expression of the input expression + /// + /// [] val (|QuoteRaw|_|) : input:Expr -> Expr option /// An active pattern to recognize expressions that represent a nested typed quotation literal + /// /// The input expression to match against. - /// Expr option + /// + /// When successful, the pattern binds the nested quotation expression of the input expression + /// + /// [] val (|QuoteTyped|_|) : input:Expr -> Expr option /// An active pattern to recognize expressions that represent sequential execution of one expression followed by another + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the two sub-expressions of the input expression + /// + /// [] val (|Sequential|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions that represent a try/with construct for exception filtering and catching + /// /// The input expression to match against. - /// (Expr * Var * Expr * Var * Expr) option + /// + /// When successful, the pattern binds the body, exception variable, filter expression and catch expression of the input expression + /// + /// [] val (|TryWith|_|) : input:Expr -> (Expr * Var * Expr * Var * Expr) option /// An active pattern to recognize expressions that represent a try/finally construct + /// /// The input expression to match against. - /// The body and handler parts of the try/finally expression + /// + /// When successful, the pattern binds the body and handler parts of the try/finally expression + /// + /// [] val (|TryFinally|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions that represent getting a tuple field + /// /// The input expression to match against. - /// The expression and tuple field being accessed + /// + /// When successful, the pattern binds the expression and tuple field being accessed + /// + /// [] val (|TupleGet|_|) : input:Expr -> (Expr * int) option /// An active pattern to recognize expressions that represent a dynamic type test + /// /// The input expression to match against. - /// The expression and type being tested + /// + /// When successful, the pattern binds the expression and type being tested + /// + /// [] val (|TypeTest|_|) : input:Expr -> (Expr * Type) option /// An active pattern to recognize expressions that represent a test if a value is of a particular union case + /// /// The input expression to match against. - /// The expression and union case being tested + /// + /// When successful, the pattern binds the expression and union case being tested + /// + /// [] val (|UnionCaseTest|_|) : input:Expr -> (Expr * UnionCaseInfo) option /// An active pattern to recognize expressions that represent a constant value. This also matches expressions matched by ValueWithName. + /// /// The input expression to match against. - /// The boxed value and its static type + /// + /// When successful, the pattern binds the boxed value and its static type + /// + /// [] val (|Value|_|) : input:Expr -> (obj * Type) option /// An active pattern to recognize expressions that represent a constant value + /// /// The input expression to match against. - /// The boxed value, its static type and its name + /// + /// When successful, the pattern binds the boxed value, its static type and its name + /// + /// [] val (|ValueWithName|_|) : input:Expr -> (obj * Type * string) option /// An active pattern to recognize expressions that are a value with an associated definition + /// /// The input expression to match against. - /// The boxed value, its static type and its definition + /// + /// When successful, the pattern binds the boxed value, its static type and its definition + /// + /// [] val (|WithValue|_|) : input:Expr -> (obj * Type * Expr) option /// An active pattern to recognize expressions that represent a variable + /// /// The input expression to match against. - /// Var option + /// + /// When successful, the pattern binds the variable of the input expression + /// + /// [] val (|Var|_|) : input:Expr -> Var option /// An active pattern to recognize expressions that represent setting a mutable variable + /// /// The input expression to match against. - /// (Var * Expr) option + /// + /// When successful, the pattern binds the variable and value expression of the input expression + /// + /// [] val (|VarSet|_|) : input:Expr -> (Var * Expr) option - [] /// Contains a set of derived F# active patterns to analyze F# expression objects module DerivedPatterns = /// An active pattern to recognize expressions that represent a (possibly curried or tupled) first class function value + /// /// The input expression to match against. - /// (Var list list * Expr) option + /// + /// When successful, the pattern binds the curried variables and body of the input expression + /// + /// [] val (|Lambdas|_|) : input:Expr -> (Var list list * Expr) option /// An active pattern to recognize expressions that represent the application of a (possibly curried or tupled) first class function value + /// /// The input expression to match against. - /// (Expr * Expr list list) option + /// + /// When successful, the pattern binds the function and curried arguments of the input expression + /// + /// [] val (|Applications|_|) : input:Expr -> (Expr * Expr list list) option /// An active pattern to recognize expressions of the form a && b + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the left and right parts of the input expression + /// + /// [] val (|AndAlso|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize expressions of the form a || b + /// /// The input expression to match against. - /// (Expr * Expr) option + /// + /// When successful, the pattern binds the left and right parts of the input expression + /// + /// [] val (|OrElse|_|) : input:Expr -> (Expr * Expr) option /// An active pattern to recognize () constant expressions + /// /// The input expression to match against. - /// unit option + /// + /// When successful, the pattern does not bind any results + /// + /// [] val (|Unit|_|) : input:Expr -> unit option /// An active pattern to recognize constant boolean expressions + /// /// The input expression to match against. - /// bool option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Bool|_|) : input:Expr -> bool option /// An active pattern to recognize constant string expressions + /// /// The input expression to match against. - /// string option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|String|_|) : input:Expr -> string option /// An active pattern to recognize constant 32-bit floating point number expressions + /// /// The input expression to match against. - /// float32 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Single|_|) : input:Expr -> float32 option /// An active pattern to recognize constant 64-bit floating point number expressions + /// /// The input expression to match against. - /// float option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Double|_|) : input:Expr -> float option /// An active pattern to recognize constant unicode character expressions + /// /// The input expression to match against. - /// char option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Char|_|) : input:Expr -> char option /// An active pattern to recognize constant signed byte expressions + /// /// The input expression to match against. - /// sbyte option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|SByte|_|) : input:Expr -> sbyte option /// An active pattern to recognize constant byte expressions + /// /// The input expression to match against. - /// byte option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Byte|_|) : input:Expr -> byte option /// An active pattern to recognize constant int16 expressions + /// /// The input expression to match against. - /// int16 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Int16|_|) : input:Expr -> int16 option /// An active pattern to recognize constant unsigned int16 expressions + /// /// The input expression to match against. - /// uint16 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|UInt16|_|) : input:Expr -> uint16 option /// An active pattern to recognize constant int32 expressions + /// /// The input expression to match against. - /// int32 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Int32|_|) : input:Expr -> int32 option /// An active pattern to recognize constant unsigned int32 expressions + /// /// The input expression to match against. - /// uint32 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|UInt32|_|) : input:Expr -> uint32 option /// An active pattern to recognize constant int64 expressions + /// /// The input expression to match against. - /// int64 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Int64|_|) : input:Expr -> int64 option /// An active pattern to recognize constant unsigned int64 expressions + /// /// The input expression to match against. - /// uint64 option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|UInt64|_|) : input:Expr -> uint64 option /// An active pattern to recognize constant decimal expressions + /// /// The input expression to match against. - /// decimal option + /// + /// When successful, the pattern binds the constant value from the input expression + /// + /// [] val (|Decimal|_|) : input:Expr -> decimal option @@ -777,28 +1268,44 @@ module DerivedPatterns = /// The returned elements are the optional target object (present if the target is an /// instance method), the generic type instantiation (non-empty if the target is a generic /// instantiation), and the arguments to the function or method. + /// /// The input template expression to specify the method to call. + /// /// The optional target object (present if the target is an /// instance method), the generic type instantiation (non-empty if the target is a generic /// instantiation), and the arguments to the function or method. + /// + /// [] val (|SpecificCall|_|) : templateParameter:Expr -> (Expr -> (Expr option * list * list) option) /// An active pattern to recognize methods that have an associated ReflectedDefinition + /// /// The description of the method. + /// /// The expression of the method definition if found, or None. + /// + /// [] val (|MethodWithReflectedDefinition|_|) : methodBase:MethodBase -> Expr option /// An active pattern to recognize property getters or values in modules that have an associated ReflectedDefinition + /// /// The description of the property. + /// /// The expression of the method definition if found, or None. + /// + /// [] val (|PropertyGetterWithReflectedDefinition|_|) : propertyInfo:PropertyInfo -> Expr option /// An active pattern to recognize property setters that have an associated ReflectedDefinition + /// /// The description of the property. + /// /// The expression of the method definition if found, or None. + /// + /// [] val (|PropertySetterWithReflectedDefinition|_|) : propertyInfo:PropertyInfo -> Expr option @@ -807,8 +1314,12 @@ module DerivedPatterns = module ExprShape = /// An active pattern that performs a complete decomposition viewing the expression tree as a binding structure + /// /// The input expression. + /// /// The decomposed Var, Lambda, or ConstApp. + /// + /// [] val (|ShapeVar|ShapeLambda|ShapeCombination|) : input:Expr -> ChoiceRe-build combination expressions. The first parameter should be an object /// returned by the ShapeCombination case of the active pattern in this module. + /// /// The input shape. /// The list of arguments. + /// /// The rebuilt expression. val RebuildShapeCombination : shape:obj * arguments:list -> Expr diff --git a/src/fsharp/FSharp.Core/reflect.fs b/src/fsharp/FSharp.Core/reflect.fs index 828fddac3d3..63b8d6d4651 100644 --- a/src/fsharp/FSharp.Core/reflect.fs +++ b/src/fsharp/FSharp.Core/reflect.fs @@ -13,6 +13,7 @@ open Microsoft.FSharp.Core.Operators open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators open Microsoft.FSharp.Collections open Microsoft.FSharp.Primitives.Basics +open System.Linq.Expressions module internal ReflectionUtils = @@ -63,6 +64,181 @@ module internal Impl = | null -> None | prop -> Some(fun (obj: obj) -> prop.GetValue (obj, instancePropertyFlags ||| bindingFlags, null, null, null)) + //----------------------------------------------------------------- + // EXPRESSION TREE COMPILATION + + let compilePropGetterFunc (prop: PropertyInfo) = + let param = Expression.Parameter (typeof, "param") + + let expr = + Expression.Lambda> ( + Expression.Convert ( + Expression.Property ( + Expression.Convert (param, prop.DeclaringType), + prop), + typeof), + param) + expr.Compile () + + let compileRecordOrUnionCaseReaderFunc (typ, props: PropertyInfo[]) = + let param = Expression.Parameter (typeof, "param") + let typedParam = Expression.Variable typ + + let expr = + Expression.Lambda> ( + Expression.Block ( + [ typedParam ], + Expression.Assign (typedParam, Expression.Convert (param, typ)), + Expression.NewArrayInit (typeof, [ + for prop in props -> + Expression.Convert (Expression.Property (typedParam, prop), typeof) :> Expression + ]) + ), + param) + expr.Compile () + + let compileRecordConstructorFunc (ctorInfo: ConstructorInfo) = + let ctorParams = ctorInfo.GetParameters () + let paramArray = Expression.Parameter (typeof, "paramArray") + + let expr = + Expression.Lambda> ( + Expression.Convert ( + Expression.New ( + ctorInfo, + [ + for paramIndex in 0 .. ctorParams.Length - 1 do + let p = ctorParams.[paramIndex] + + Expression.Convert ( + Expression.ArrayAccess (paramArray, Expression.Constant paramIndex), + p.ParameterType + ) :> Expression + ] + ), + typeof), + paramArray + ) + expr.Compile () + + let compileUnionCaseConstructorFunc (methodInfo: MethodInfo) = + let methodParams = methodInfo.GetParameters () + let paramArray = Expression.Parameter (typeof, "param") + + let expr = + Expression.Lambda> ( + Expression.Convert ( + Expression.Call ( + methodInfo, + [ + for paramIndex in 0 .. methodParams.Length - 1 do + let p = methodParams.[paramIndex] + + Expression.Convert ( + Expression.ArrayAccess (paramArray, Expression.Constant paramIndex), + p.ParameterType + ) :> Expression + ] + ), + typeof), + paramArray + ) + expr.Compile () + + let compileUnionTagReaderFunc (info: Choice) = + let param = Expression.Parameter (typeof, "param") + let tag = + match info with + | Choice1Of2 info -> Expression.Call (info, Expression.Convert (param, info.DeclaringType)) :> Expression + | Choice2Of2 info -> Expression.Property (Expression.Convert (param, info.DeclaringType), info) :> _ + + let expr = + Expression.Lambda> ( + tag, + param) + expr.Compile () + + let compileTupleConstructor tupleEncField getTupleConstructorMethod typ = + let rec constituentTuple (typ: Type) elements startIndex = + Expression.New ( + getTupleConstructorMethod typ, + [ + let genericArgs = typ.GetGenericArguments () + + for paramIndex in 0 .. genericArgs.Length - 1 do + let genericArg = genericArgs.[paramIndex] + + if paramIndex = tupleEncField then + constituentTuple genericArg elements (startIndex + paramIndex) :> Expression + else + Expression.Convert (Expression.ArrayAccess (elements, Expression.Constant (startIndex + paramIndex)), genericArg) + ]) + + let elements = Expression.Parameter (typeof, "elements") + + let expr = + Expression.Lambda> ( + Expression.Convert ( + constituentTuple typ elements 0, + typeof + ), + elements + ) + + expr.Compile () + + let compileTupleReader tupleEncField getTupleElementAccessors typ = + let rec writeTupleIntoArray (typ: Type) (tuple: Expression) outputArray startIndex = seq { + let elements = + match getTupleElementAccessors typ with + // typ is a struct tuple and its elements are accessed via fields + | Choice1Of2 (fi: FieldInfo[]) -> fi |> Array.map (fun fi -> Expression.Field (tuple, fi), fi.FieldType) + // typ is a class tuple and its elements are accessed via properties + | Choice2Of2 (pi: PropertyInfo[]) -> pi |> Array.map (fun pi -> Expression.Property (tuple, pi), pi.PropertyType) + + for index, (element, elementType) in elements |> Array.indexed do + if index = tupleEncField then + let innerTupleParam = Expression.Parameter (elementType, "innerTuple") + Expression.Block ( + [ innerTupleParam ], + [ + yield Expression.Assign (innerTupleParam, element) :> Expression + yield! writeTupleIntoArray elementType innerTupleParam outputArray (startIndex + index) + ] + ) :> Expression + else + Expression.Assign ( + Expression.ArrayAccess (outputArray, Expression.Constant (index + startIndex)), + Expression.Convert (element, typeof) + ) :> Expression } + + let param = Expression.Parameter (typeof, "outerTuple") + let outputArray = Expression.Variable (typeof, "output") + let rec outputLength tupleEncField (typ: Type) = + let genericArgs = typ.GetGenericArguments () + + if genericArgs.Length > tupleEncField then + tupleEncField + outputLength tupleEncField genericArgs.[genericArgs.Length - 1] + else + genericArgs.Length + + let expr = + Expression.Lambda> ( + Expression.Block ( + [ outputArray ], + [ + yield Expression.Assign ( + outputArray, + Expression.NewArrayBounds (typeof, Expression.Constant (outputLength tupleEncField typ)) + ) :> Expression + yield! writeTupleIntoArray typ (Expression.Convert (param, typ)) outputArray 0 + yield outputArray :> Expression + ] + ), + param) + + expr.Compile () + //----------------------------------------------------------------- // ATTRIBUTE DECOMPILATION @@ -70,7 +246,7 @@ module internal Impl = match attrs with | null | [| |] -> None | [| res |] -> let a = (res :?> CompilationMappingAttribute) in Some (a.SourceConstructFlags, a.SequenceNumber, a.VariantNumber) - | _ -> raise <| System.InvalidOperationException (SR.GetString (SR.multipleCompilationMappings)) + | _ -> invalidOp (SR.GetString (SR.multipleCompilationMappings)) let findCompilationMappingAttribute (attrs: obj[]) = match tryFindCompilationMappingAttribute attrs with @@ -166,9 +342,9 @@ module internal Impl = let nm = minfo.Name // chop "get_" or "New" off the front let nm = - if not (isListType typ) && not (isOptionType typ) then - if nm.Length > 4 && nm.[0..3] = "get_" then nm.[4..] - elif nm.Length > 3 && nm.[0..2] = "New" then nm.[3..] + if not (isListType typ) && not (isOptionType typ) && nm.Length > 3 then + if nm.StartsWith ("get_", StringComparison.Ordinal) then nm.[4..] + elif nm.StartsWith ("New", StringComparison.Ordinal) then nm.[3..] else nm else nm Some (n, nm) @@ -261,6 +437,12 @@ module internal Impl = let props = fieldsPropsOfUnionCase (typ, tag, bindingFlags) (fun (obj: obj) -> props |> Array.map (fun prop -> prop.GetValue (obj, bindingFlags, null, null, null))) + let getUnionCaseRecordReaderCompiled (typ: Type, tag: int, bindingFlags) = + let props = fieldsPropsOfUnionCase (typ, tag, bindingFlags) + let caseTyp = getUnionCaseTyp (typ, tag, bindingFlags) + let caseTyp = if isNull caseTyp then typ else caseTyp + compileRecordOrUnionCaseReaderFunc(caseTyp, props).Invoke + let getUnionTagReader (typ: Type, bindingFlags) : (obj -> int) = if isOptionType typ then (fun (obj: obj) -> match obj with null -> 0 | _ -> 1) @@ -272,9 +454,22 @@ module internal Impl = match getInstancePropertyReader (typ, "Tag", bindingFlags) with | Some reader -> (fun (obj: obj) -> reader obj :?> int) | None -> - (fun (obj: obj) -> - let m2b = typ.GetMethod("GetTag", BindingFlags.Static ||| bindingFlags, null, [| typ |], null) - m2b.Invoke(null, [|obj|]) :?> int) + let m2b = typ.GetMethod("GetTag", BindingFlags.Static ||| bindingFlags, null, [| typ |], null) + (fun (obj: obj) -> m2b.Invoke(null, [|obj|]) :?> int) + + let getUnionTagReaderCompiled (typ: Type, bindingFlags) : (obj -> int) = + if isOptionType typ then + (fun (obj: obj) -> match obj with null -> 0 | _ -> 1) + else + let tagMap = getUnionTypeTagNameMap (typ, bindingFlags) + if tagMap.Length <= 1 then + (fun (_obj: obj) -> 0) + else + match getInstancePropertyInfo (typ, "Tag", bindingFlags) with + | null -> + let m2b = typ.GetMethod("GetTag", BindingFlags.Static ||| bindingFlags, null, [| typ |], null) + compileUnionTagReaderFunc(Choice1Of2 m2b).Invoke + | info -> compileUnionTagReaderFunc(Choice2Of2 info).Invoke let getUnionTagMemberInfo (typ: Type, bindingFlags) = match getInstancePropertyInfo (typ, "Tag", bindingFlags) with @@ -292,7 +487,7 @@ module internal Impl = else "New" + constrname match typ.GetMethod(methname, BindingFlags.Static ||| bindingFlags) with - | null -> raise <| System.InvalidOperationException (String.Format (SR.GetString (SR.constructorForUnionCaseNotFound), methname)) + | null -> invalidOp (String.Format (SR.GetString (SR.constructorForUnionCaseNotFound), methname)) | meth -> meth let getUnionCaseConstructor (typ: Type, tag: int, bindingFlags) = @@ -300,6 +495,10 @@ module internal Impl = (fun args -> meth.Invoke(null, BindingFlags.Static ||| BindingFlags.InvokeMethod ||| bindingFlags, null, args, null)) + let getUnionCaseConstructorCompiled (typ: Type, tag: int, bindingFlags) = + let meth = getUnionCaseConstructorMethod (typ, tag, bindingFlags) + compileUnionCaseConstructorFunc(meth).Invoke + let checkUnionType (unionType, bindingFlags) = checkNonNull "unionType" unionType if not (isUnionType (unionType, bindingFlags)) then @@ -487,16 +686,19 @@ module internal Impl = (fun (args: obj[]) -> ctor.Invoke(BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public, null, args, null)) + let getTupleElementAccessors (typ: Type) = + if typ.IsValueType then + Choice1Of2 (typ.GetFields (instanceFieldFlags ||| BindingFlags.Public) |> orderTupleFields) + else + Choice2Of2 (typ.GetProperties (instancePropertyFlags ||| BindingFlags.Public) |> orderTupleProperties) + let rec getTupleReader (typ: Type) = let etys = typ.GetGenericArguments() // Get the reader for the outer tuple record let reader = - if typ.IsValueType then - let fields = (typ.GetFields (instanceFieldFlags ||| BindingFlags.Public) |> orderTupleFields) - ((fun (obj: obj) -> fields |> Array.map (fun field -> field.GetValue obj))) - else - let props = (typ.GetProperties (instancePropertyFlags ||| BindingFlags.Public) |> orderTupleProperties) - ((fun (obj: obj) -> props |> Array.map (fun prop -> prop.GetValue (obj, null)))) + match getTupleElementAccessors typ with + | Choice1Of2 fi -> fun obj -> fi |> Array.map (fun f -> f.GetValue obj) + | Choice2Of2 pi -> fun obj -> pi |> Array.map (fun p -> p.GetValue (obj, null)) if etys.Length < maxTuple then reader else @@ -585,6 +787,10 @@ module internal Impl = let props = fieldPropsOfRecordType(typ, bindingFlags) (fun (obj: obj) -> props |> Array.map (fun prop -> prop.GetValue (obj, null))) + let getRecordReaderCompiled(typ: Type, bindingFlags) = + let props = fieldPropsOfRecordType(typ, bindingFlags) + compileRecordOrUnionCaseReaderFunc(typ, props).Invoke + let getRecordConstructorMethod(typ: Type, bindingFlags) = let props = fieldPropsOfRecordType(typ, bindingFlags) let ctor = typ.GetConstructor(BindingFlags.Instance ||| bindingFlags, null, props |> Array.map (fun p -> p.PropertyType), null) @@ -598,6 +804,10 @@ module internal Impl = (fun (args: obj[]) -> ctor.Invoke(BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| bindingFlags, null, args, null)) + let getRecordConstructorCompiled(typ: Type, bindingFlags) = + let ctor = getRecordConstructorMethod(typ, bindingFlags) + compileRecordConstructorFunc(ctor).Invoke + /// EXCEPTION DECOMPILATION // Check the base type - if it is also an F# type then // for the moment we know it is a Discriminated Union @@ -651,7 +861,7 @@ type UnionCaseInfo(typ: System.Type, tag: int) = let getMethInfo() = getUnionCaseConstructorMethod (typ, tag, BindingFlags.Public ||| BindingFlags.NonPublic) - member __.Name = + member _.Name = match names with | None -> let conv = getUnionTagConverter (typ, BindingFlags.Public ||| BindingFlags.NonPublic) @@ -660,27 +870,27 @@ type UnionCaseInfo(typ: System.Type, tag: int) = | Some conv -> conv tag - member __.DeclaringType = typ + member _.DeclaringType = typ - member __.GetFields() = + member _.GetFields() = fieldsPropsOfUnionCase (typ, tag, BindingFlags.Public ||| BindingFlags.NonPublic) - member __.GetCustomAttributes() = + member _.GetCustomAttributes() = getMethInfo().GetCustomAttributes false - member __.GetCustomAttributes attributeType = + member _.GetCustomAttributes attributeType = getMethInfo().GetCustomAttributes(attributeType, false) - member __.GetCustomAttributesData() = + member _.GetCustomAttributesData() = getMethInfo().CustomAttributes |> Seq.toArray :> IList<_> - member __.Tag = tag + member _.Tag = tag override x.ToString() = typ.Name + "." + x.Name override x.GetHashCode() = typ.GetHashCode() + tag - override __.Equals(obj: obj) = + override _.Equals(obj: obj) = match obj with | :? UnionCaseInfo as uci -> uci.DeclaringType = typ && uci.Tag = tag | _ -> false @@ -772,7 +982,7 @@ type FSharpType = type DynamicFunction<'T1, 'T2>() = inherit FSharpFunc obj, obj>() - override __.Invoke(impl: obj -> obj) : obj = + override _.Invoke(impl: obj -> obj) : obj = box<('T1 -> 'T2)> (fun inp -> unbox<'T2>(impl (box<'T1>(inp)))) [] @@ -799,19 +1009,19 @@ type FSharpValue = invalidArg "record" (SR.GetString (SR.objIsNotARecord)) getRecordReader (typ, bindingFlags) record - static member PreComputeRecordFieldReader(info: PropertyInfo) = + static member PreComputeRecordFieldReader(info: PropertyInfo): obj -> obj = checkNonNull "info" info - (fun (obj: obj) -> info.GetValue (obj, null)) + compilePropGetterFunc(info).Invoke static member PreComputeRecordReader(recordType: Type, ?bindingFlags) : (obj -> obj[]) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkRecordType ("recordType", recordType, bindingFlags) - getRecordReader (recordType, bindingFlags) + getRecordReaderCompiled (recordType, bindingFlags) static member PreComputeRecordConstructor(recordType: Type, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkRecordType ("recordType", recordType, bindingFlags) - getRecordConstructor (recordType, bindingFlags) + getRecordConstructorCompiled (recordType, bindingFlags) static member PreComputeRecordConstructorInfo(recordType: Type, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public @@ -854,7 +1064,7 @@ type FSharpValue = static member PreComputeTupleReader(tupleType: Type) : (obj -> obj[]) = checkTupleType("tupleType", tupleType) - getTupleReader tupleType + (compileTupleReader tupleEncField getTupleElementAccessors tupleType).Invoke static member PreComputeTuplePropertyInfo(tupleType: Type, index: int) = checkTupleType("tupleType", tupleType) @@ -862,7 +1072,7 @@ type FSharpValue = static member PreComputeTupleConstructor(tupleType: Type) = checkTupleType("tupleType", tupleType) - getTupleConstructor tupleType + (compileTupleConstructor tupleEncField getTupleConstructorMethod tupleType).Invoke static member PreComputeTupleConstructorInfo(tupleType: Type) = checkTupleType("tupleType", tupleType) @@ -876,7 +1086,7 @@ type FSharpValue = static member PreComputeUnionConstructor (unionCase: UnionCaseInfo, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkNonNull "unionCase" unionCase - getUnionCaseConstructor (unionCase.DeclaringType, unionCase.Tag, bindingFlags) + getUnionCaseConstructorCompiled (unionCase.DeclaringType, unionCase.Tag, bindingFlags) static member PreComputeUnionConstructorInfo(unionCase: UnionCaseInfo, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public @@ -908,7 +1118,7 @@ type FSharpValue = checkNonNull "unionType" unionType let unionType = getTypeOfReprType (unionType, bindingFlags) checkUnionType (unionType, bindingFlags) - getUnionTagReader (unionType, bindingFlags) + getUnionTagReaderCompiled (unionType, bindingFlags) static member PreComputeUnionTagMemberInfo(unionType: Type, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public @@ -921,7 +1131,7 @@ type FSharpValue = let bindingFlags = defaultArg bindingFlags BindingFlags.Public checkNonNull "unionCase" unionCase let typ = unionCase.DeclaringType - getUnionCaseRecordReader (typ, unionCase.Tag, bindingFlags) + getUnionCaseRecordReaderCompiled (typ, unionCase.Tag, bindingFlags) static member GetExceptionFields (exn: obj, ?bindingFlags) = let bindingFlags = defaultArg bindingFlags BindingFlags.Public diff --git a/src/fsharp/FSharp.Core/reflect.fsi b/src/fsharp/FSharp.Core/reflect.fsi index 465529677a7..24cf082386b 100644 --- a/src/fsharp/FSharp.Core/reflect.fsi +++ b/src/fsharp/FSharp.Core/reflect.fsi @@ -10,37 +10,55 @@ open Microsoft.FSharp.Core open Microsoft.FSharp.Primitives.Basics open Microsoft.FSharp.Collections -//--------------------------------------------------------------------- -// F# reified type inspection. - /// Represents a case of a discriminated union type +/// +/// +/// Library functionality for accessing additional information about F# types and F# values at +/// runtime, augmenting that available through System.Reflection. +/// [] type UnionCaseInfo = /// The name of the case. + /// + /// member Name : string + /// The type in which the case occurs. + /// + /// member DeclaringType: Type /// Returns the custom attributes associated with the case. /// An array of custom attributes. + /// + /// member GetCustomAttributes: unit -> obj[] + /// Returns the custom attributes associated with the case matching the given attribute type. /// The type of attributes to return. + /// /// An array of custom attributes. + /// + /// member GetCustomAttributes: attributeType:System.Type -> obj[] /// Returns the custom attributes data associated with the case. /// An list of custom attribute data items. + /// + /// member GetCustomAttributesData: unit -> System.Collections.Generic.IList /// The fields associated with the case, represented by a PropertyInfo. /// The fields associated with the case. + /// + /// member GetFields: unit -> PropertyInfo [] /// The integer tag for the case. + /// + /// member Tag: int - [] /// Contains operations associated with constructing and analyzing values associated with F# types /// such as records, unions and tuples. @@ -48,42 +66,61 @@ type FSharpValue = /// Reads a field from a record value. /// - /// Assumes the given input is a record value. If not, ArgumentException is raised. + /// Assumes the given input is a record value. If not, is raised. + /// /// The record object. /// The PropertyInfo describing the field to read. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input is not a record value. + /// /// The field from the record. + /// + /// static member GetRecordField: record:obj * info:PropertyInfo -> obj /// Precompute a function for reading a particular field from a record. /// Assumes the given type is a RecordType with a field of the given name. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. /// /// Using the computed function will typically be faster than executing a corresponding call to Value.GetInfo /// because the path executed by the computed function is optimized given the knowledge that it will be /// used to read values of the given type. + /// /// The PropertyInfo of the field to read. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// A function to read the specified field from the record. + /// + /// static member PreComputeRecordFieldReader : info:PropertyInfo -> (obj -> obj) /// Creates an instance of a record type. /// /// Assumes the given input is a record type. + /// /// The type of record to make. /// The array of values to initialize the record. /// Optional binding flags for the record. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// The created record. + /// + /// static member MakeRecord: recordType:Type * values:obj [] * ?bindingFlags:BindingFlags -> obj /// Reads all the fields from a record value. /// - /// Assumes the given input is a record value. If not, ArgumentException is raised. + /// Assumes the given input is a record value. If not, is raised. /// The record object. /// Optional binding flags for the record. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// The array of fields from the record. + /// + /// static member GetRecordFields: record:obj * ?bindingFlags:BindingFlags -> obj[] /// Precompute a function for reading all the fields from a record. The fields are returned in the @@ -91,42 +128,61 @@ type FSharpValue = /// this type. /// /// Assumes the given type is a RecordType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. /// /// Using the computed function will typically be faster than executing a corresponding call to Value.GetInfo /// because the path executed by the computed function is optimized given the knowledge that it will be /// used to read values of the given type. + /// /// The type of record to read. /// Optional binding flags. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// An optimized reader for the given record type. + /// + /// static member PreComputeRecordReader : recordType:Type * ?bindingFlags:BindingFlags -> (obj -> obj[]) + /// Precompute a function for constructing a record value. /// /// Assumes the given type is a RecordType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. + /// /// The type of record to construct. /// Optional binding flags. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// A function to construct records of the given type. + /// + /// static member PreComputeRecordConstructor : recordType:Type * ?bindingFlags:BindingFlags -> (obj[] -> obj) /// Get a ConstructorInfo for a record type + /// /// The record type. /// Optional binding flags. + /// /// A ConstructorInfo for the given record type. + /// + /// static member PreComputeRecordConstructorInfo: recordType:Type * ?bindingFlags:BindingFlags -> ConstructorInfo /// Create a union case value. + /// /// The description of the union case to create. /// The array of arguments to construct the given case. /// Optional binding flags. + /// /// The constructed union case. + /// + /// static member MakeUnion: unionCase:UnionCaseInfo * args:obj [] * ?bindingFlags:BindingFlags -> obj /// Identify the union case and its fields for an object /// - /// Assumes the given input is a union case value. If not, ArgumentException is raised. + /// Assumes the given input is a union case value. If not, is raised. /// /// If the type is not given, then the runtime type of the input object is used to identify the /// relevant union type. The type should always be given if the input object may be null. For example, @@ -134,104 +190,161 @@ type FSharpValue = /// The input union case. /// The union type containing the value. /// Optional binding flags. - /// Thrown when the input type is not a union case value. + /// + /// Thrown when the input type is not a union case value. + /// /// The description of the union case and its fields. + /// + /// static member GetUnionFields: value:obj * unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo * obj [] /// Assumes the given type is a union type. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. /// /// Using the computed function is more efficient than calling GetUnionCase /// because the path executed by the computed function is optimized given the knowledge that it will be /// used to read values of the given type. + /// /// The type of union to optimize reading. /// Optional binding flags. + /// /// An optimized function to read the tags of the given union type. + /// + /// static member PreComputeUnionTagReader : unionType:Type * ?bindingFlags:BindingFlags -> (obj -> int) /// Precompute a property or static method for reading an integer representing the case tag of a union type. + /// /// The type of union to read. /// Optional binding flags. + /// /// The description of the union case reader. + /// + /// static member PreComputeUnionTagMemberInfo : unionType:Type * ?bindingFlags:BindingFlags -> MemberInfo /// Precompute a function for reading all the fields for a particular discriminator case of a union type /// /// Using the computed function will typically be faster than executing a corresponding call to GetFields + /// /// The description of the union case to read. /// Optional binding flags. + /// /// A function to for reading the fields of the given union case. + /// + /// static member PreComputeUnionReader : unionCase:UnionCaseInfo * ?bindingFlags:BindingFlags -> (obj -> obj[]) /// Precompute a function for constructing a discriminated union value for a particular union case. + /// /// The description of the union case. /// Optional binding flags. + /// /// A function for constructing values of the given union case. + /// + /// static member PreComputeUnionConstructor : unionCase:UnionCaseInfo * ?bindingFlags:BindingFlags -> (obj[] -> obj) /// A method that constructs objects of the given case + /// /// The description of the union case. /// Optional binding flags. + /// /// The description of the constructor of the given union case. + /// + /// static member PreComputeUnionConstructorInfo: unionCase:UnionCaseInfo * ?bindingFlags:BindingFlags -> MethodInfo /// Reads all the fields from a value built using an instance of an F# exception declaration /// - /// Assumes the given input is an F# exception value. If not, ArgumentException is raised. + /// Assumes the given input is an F# exception value. If not, is raised. + /// /// The exception instance. /// Optional binding flags. - /// Thrown when the input type is not an F# exception. + /// + /// Thrown when the input type is not an F# exception. + /// /// The fields from the given exception. + /// + /// static member GetExceptionFields: exn:obj * ?bindingFlags:BindingFlags -> obj[] /// Creates an instance of a tuple type /// - /// Assumes at least one element is given. If not, ArgumentException is raised. + /// Assumes at least one element is given. If not, is raised. + /// /// The array of tuple fields. /// The tuple type to create. - /// Thrown if no elements are given. + /// + /// Thrown if no elements are given. + /// /// An instance of the tuple type with the given elements. + /// + /// static member MakeTuple: tupleElements:obj[] * tupleType:Type -> obj /// Reads a field from a tuple value. /// - /// Assumes the given input is a tuple value. If not, ArgumentException is raised. + /// Assumes the given input is a tuple value. If not, is raised. + /// /// The input tuple. /// The index of the field to read. + /// /// The value of the field. + /// + /// static member GetTupleField: tuple:obj * index:int -> obj /// Reads all fields from a tuple. /// - /// Assumes the given input is a tuple value. If not, ArgumentException is raised. + /// Assumes the given input is a tuple value. If not, is raised. + /// /// The input tuple. - /// Thrown when the input is not a tuple value. + /// + /// Thrown when the input is not a tuple value. + /// /// An array of the fields from the given tuple. + /// + /// static member GetTupleFields: tuple:obj -> obj [] /// Precompute a function for reading the values of a particular tuple type /// /// Assumes the given type is a TupleType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. + /// /// The tuple type to read. - /// Thrown when the given type is not a tuple type. + /// + /// Thrown when the given type is not a tuple type. + /// /// A function to read values of the given tuple type. - static member PreComputeTupleReader : tupleType:Type -> (obj -> obj[]) + /// + /// + static member PreComputeTupleReader: tupleType:Type -> (obj -> obj[]) /// Gets information that indicates how to read a field of a tuple + /// /// The input tuple type. /// The index of the tuple element to describe. + /// /// The description of the tuple element and an optional type and index if the tuple is big. + /// + /// static member PreComputeTuplePropertyInfo: tupleType:Type * index:int -> PropertyInfo * (Type * int) option /// Precompute a function for reading the values of a particular tuple type /// /// Assumes the given type is a TupleType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. + /// /// The type of tuple to read. - /// Thrown when the given type is not a tuple type. + /// + /// Thrown when the given type is not a tuple type. + /// /// A function to read a particular tuple type. - static member PreComputeTupleConstructor : tupleType:Type -> (obj[] -> obj) + /// + /// + static member PreComputeTupleConstructor: tupleType:Type -> (obj[] -> obj) /// Gets a method that constructs objects of the given tuple type. /// For small tuples, no additional type will be returned. @@ -242,16 +355,24 @@ type FSharpValue = /// object of this type must be created and passed as the last argument /// to the ConstructorInfo. A recursive call to PreComputeTupleConstructorInfo /// can be used to determine the constructor for that the suffix type. + /// /// The input tuple type. + /// /// The description of the tuple type constructor and an optional extra type /// for large tuples. + /// + /// static member PreComputeTupleConstructorInfo: tupleType:Type -> ConstructorInfo * Type option /// Builds a typed function from object from a dynamic function implementation + /// /// The function type of the implementation. /// The untyped lambda of the function implementation. + /// /// A typed function from the given dynamic implementation. - static member MakeFunction : functionType:Type * implementation:(obj -> obj) -> obj + /// + /// + static member MakeFunction: functionType:Type * implementation:(obj -> obj) -> obj [] /// Contains operations associated with constructing and analyzing F# types such as records, unions and tuples @@ -259,117 +380,189 @@ type FSharpType = /// Reads all the fields from a record value, in declaration order /// - /// Assumes the given input is a record value. If not, ArgumentException is raised. + /// Assumes the given input is a record value. If not, is raised. + /// /// The input record type. /// Optional binding flags. + /// /// An array of descriptions of the properties of the record type. + /// + /// static member GetRecordFields: recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo[] /// Gets the cases of a union type. /// - /// Assumes the given type is a union type. If not, ArgumentException is raised during pre-computation. + /// Assumes the given type is a union type. If not, is raised during pre-computation. + /// /// The input union type. /// Optional binding flags. - /// Thrown when the input type is not a union type. + /// + /// Thrown when the input type is not a union type. + /// /// An array of descriptions of the cases of the given union type. + /// + /// static member GetUnionCases: unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo[] - /// Return true if the typ is a representation of an F# record type + /// /// The type to check. /// Optional binding flags. + /// /// True if the type check succeeds. + /// + /// static member IsRecord: typ:Type * ?bindingFlags:BindingFlags -> bool /// Returns true if the typ is a representation of an F# union type or the runtime type of a value of that type + /// /// The type to check. /// Optional binding flags. + /// /// True if the type check succeeds. + /// + /// static member IsUnion: typ:Type * ?bindingFlags:BindingFlags -> bool /// Reads all the fields from an F# exception declaration, in declaration order /// - /// Assumes exceptionType is an exception representation type. If not, ArgumentException is raised. + /// Assumes exceptionType is an exception representation type. If not, is raised. + /// /// The exception type to read. /// Optional binding flags. - /// Thrown if the given type is not an exception. + /// + /// Thrown if the given type is not an exception. + /// /// An array containing the PropertyInfo of each field in the exception. + /// + /// static member GetExceptionFields: exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo[] /// Returns true if the typ is a representation of an F# exception declaration + /// /// The type to check. /// Optional binding flags. + /// /// True if the type check is an F# exception. + /// + /// static member IsExceptionRepresentation: exceptionType:Type * ?bindingFlags:BindingFlags -> bool - /// Returns a System.Type representing the F# function type with the given domain and range + /// Returns a representing the F# function type with the given domain and range + /// /// The input type of the function. /// The output type of the function. + /// /// The function type with the given domain and range. + /// + /// static member MakeFunctionType: domain:Type * range:Type -> Type - /// Returns a System.Type representing an F# tuple type with the given element types + /// Returns a representing an F# tuple type with the given element types + /// /// An array of types for the tuple elements. + /// /// The type representing the tuple containing the input elements. + /// + /// static member MakeTupleType: types:Type[] -> Type - /// Returns a System.Type representing an F# tuple type with the given element types + /// Returns a representing an F# tuple type with the given element types + /// /// Runtime assembly containing System.Tuple definitions. /// An array of types for the tuple elements. + /// /// The type representing the tuple containing the input elements. + /// + /// static member MakeTupleType: asm:Assembly * types:Type[] -> Type - /// Returns a System.Type representing an F# struct tuple type with the given element types + /// Returns a representing an F# struct tuple type with the given element types + /// /// Runtime assembly containing System.ValueTuple definitions. /// An array of types for the tuple elements. + /// /// The type representing the struct tuple containing the input elements. + /// + /// static member MakeStructTupleType: asm:Assembly * types:Type[] -> Type /// Return true if the typ is a representation of an F# tuple type + /// /// The type to check. + /// /// True if the type check succeeds. + /// + /// static member IsTuple : typ:Type -> bool /// Return true if the typ is a representation of an F# function type or the runtime type of a closure implementing an F# function type + /// /// The type to check. + /// /// True if the type check succeeds. + /// + /// static member IsFunction : typ:Type -> bool - /// Return true if the typ is a System.Type value corresponding to the compiled form of an F# module + /// Return true if the typ is a value corresponding to the compiled form of an F# module + /// /// The type to check. + /// /// True if the type check succeeds. + /// + /// static member IsModule: typ:Type -> bool - /// Gets the tuple elements from the representation of an F# tuple type. + /// /// The input tuple type. + /// /// An array of the types contained in the given tuple type. + /// + /// static member GetTupleElements : tupleType:Type -> Type[] /// Gets the domain and range types from an F# function type or from the runtime type of a closure implementing an F# type + /// /// The input function type. + /// /// A tuple of the domain and range types of the input function. + /// + /// static member GetFunctionElements : functionType:Type -> Type * Type [] +/// Defines further accessing additional information about F# types and F# values at runtime. module FSharpReflectionExtensions = type FSharpValue with /// Creates an instance of a record type. /// /// Assumes the given input is a record type. + /// /// The type of record to make. /// The array of values to initialize the record. /// Optional flags that denotes accessibility of the private representation. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// The created record. + /// + /// static member MakeRecord: recordType:Type * values:obj [] * ?allowAccessToPrivateRepresentation : bool -> obj + /// Reads all the fields from a record value. /// - /// Assumes the given input is a record value. If not, ArgumentException is raised. + /// Assumes the given input is a record value. If not, is raised. + /// /// The record object. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// The array of fields from the record. + /// + /// static member GetRecordFields: record:obj * ?allowAccessToPrivateRepresentation : bool -> obj[] /// Precompute a function for reading all the fields from a record. The fields are returned in the @@ -377,150 +570,219 @@ module FSharpReflectionExtensions = /// this type. /// /// Assumes the given type is a RecordType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. /// /// Using the computed function will typically be faster than executing a corresponding call to Value.GetInfo /// because the path executed by the computed function is optimized given the knowledge that it will be /// used to read values of the given type. + /// /// The type of record to read. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// An optimized reader for the given record type. + /// + /// static member PreComputeRecordReader : recordType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj -> obj[]) + /// Precompute a function for constructing a record value. /// /// Assumes the given type is a RecordType. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. + /// /// The type of record to construct. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not a record type. + /// + /// Thrown when the input type is not a record type. + /// /// A function to construct records of the given type. + /// + /// static member PreComputeRecordConstructor : recordType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj[] -> obj) /// Get a ConstructorInfo for a record type + /// /// The record type. /// Optional flag that denotes accessibility of the private representation. + /// /// A ConstructorInfo for the given record type. + /// + /// static member PreComputeRecordConstructorInfo: recordType:Type * ?allowAccessToPrivateRepresentation : bool-> ConstructorInfo /// Create a union case value. + /// /// The description of the union case to create. /// The array of arguments to construct the given case. /// Optional flag that denotes accessibility of the private representation. + /// /// The constructed union case. + /// + /// static member MakeUnion: unionCase:UnionCaseInfo * args:obj [] * ?allowAccessToPrivateRepresentation : bool-> obj /// Identify the union case and its fields for an object /// - /// Assumes the given input is a union case value. If not, ArgumentException is raised. + /// Assumes the given input is a union case value. If not, is raised. /// /// If the type is not given, then the runtime type of the input object is used to identify the /// relevant union type. The type should always be given if the input object may be null. For example, /// option values may be represented using the 'null'. + /// /// The input union case. /// The union type containing the value. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not a union case value. + /// + /// Thrown when the input type is not a union case value. + /// /// The description of the union case and its fields. + /// + /// static member GetUnionFields: value:obj * unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo * obj [] /// Assumes the given type is a union type. - /// If not, ArgumentException is raised during pre-computation. + /// If not, is raised during pre-computation. /// /// Using the computed function is more efficient than calling GetUnionCase /// because the path executed by the computed function is optimized given the knowledge that it will be /// used to read values of the given type. + /// /// The type of union to optimize reading. /// Optional flag that denotes accessibility of the private representation. + /// /// An optimized function to read the tags of the given union type. + /// + /// static member PreComputeUnionTagReader : unionType:Type * ?allowAccessToPrivateRepresentation : bool -> (obj -> int) /// Precompute a property or static method for reading an integer representing the case tag of a union type. + /// /// The type of union to read. /// Optional flag that denotes accessibility of the private representation. + /// /// The description of the union case reader. + /// + /// static member PreComputeUnionTagMemberInfo : unionType:Type * ?allowAccessToPrivateRepresentation : bool -> MemberInfo /// Precompute a function for reading all the fields for a particular discriminator case of a union type /// /// Using the computed function will typically be faster than executing a corresponding call to GetFields + /// /// The description of the union case to read. /// Optional flag that denotes accessibility of the private representation. + /// /// A function to for reading the fields of the given union case. + /// + /// static member PreComputeUnionReader : unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> (obj -> obj[]) /// Precompute a function for constructing a discriminated union value for a particular union case. + /// /// The description of the union case. /// Optional flag that denotes accessibility of the private representation. + /// /// A function for constructing values of the given union case. + /// + /// static member PreComputeUnionConstructor : unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> (obj[] -> obj) /// A method that constructs objects of the given case + /// /// The description of the union case. /// Optional flag that denotes accessibility of the private representation. + /// /// The description of the constructor of the given union case. + /// + /// static member PreComputeUnionConstructorInfo: unionCase:UnionCaseInfo * ?allowAccessToPrivateRepresentation : bool -> MethodInfo /// Reads all the fields from a value built using an instance of an F# exception declaration /// - /// Assumes the given input is an F# exception value. If not, ArgumentException is raised. + /// Assumes the given input is an F# exception value. If not, is raised. + /// /// The exception instance. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not an F# exception. + /// + /// Thrown when the input type is not an F# exception. + /// /// The fields from the given exception. + /// + /// static member GetExceptionFields: exn:obj * ?allowAccessToPrivateRepresentation : bool -> obj[] type FSharpType with /// Reads all the fields from a record value, in declaration order /// - /// Assumes the given input is a record value. If not, ArgumentException is raised. + /// Assumes the given input is a record value. If not, is raised. + /// /// The input record type. /// Optional flag that denotes accessibility of the private representation. + /// /// An array of descriptions of the properties of the record type. + /// + /// static member GetRecordFields: recordType:Type * ?allowAccessToPrivateRepresentation : bool -> PropertyInfo[] /// Gets the cases of a union type. /// - /// Assumes the given type is a union type. If not, ArgumentException is raised during pre-computation. + /// Assumes the given type is a union type. If not, is raised during pre-computation. + /// /// The input union type. /// Optional flag that denotes accessibility of the private representation. - /// Thrown when the input type is not a union type. + /// + /// Thrown when the input type is not a union type. + /// /// An array of descriptions of the cases of the given union type. + /// + /// static member GetUnionCases: unionType:Type * ?allowAccessToPrivateRepresentation : bool -> UnionCaseInfo[] - /// Return true if the typ is a representation of an F# record type + /// /// The type to check. /// Optional flag that denotes accessibility of the private representation. + /// /// True if the type check succeeds. + /// + /// static member IsRecord: typ:Type * ?allowAccessToPrivateRepresentation : bool -> bool /// Returns true if the typ is a representation of an F# union type or the runtime type of a value of that type + /// /// The type to check. /// Optional flag that denotes accessibility of the private representation. + /// /// True if the type check succeeds. + /// + /// static member IsUnion: typ:Type * ?allowAccessToPrivateRepresentation : bool -> bool /// Reads all the fields from an F# exception declaration, in declaration order /// - /// Assumes exceptionType is an exception representation type. If not, ArgumentException is raised. + /// Assumes exceptionType is an exception representation type. If not, is raised. + /// /// The exception type to read. /// Optional flag that denotes accessibility of the private representation. - /// Thrown if the given type is not an exception. + /// + /// Thrown if the given type is not an exception. + /// /// An array containing the PropertyInfo of each field in the exception. + /// + /// static member GetExceptionFields: exceptionType:Type * ?allowAccessToPrivateRepresentation : bool -> PropertyInfo[] - /// Returns true if the typ is a representation of an F# exception declaration + /// Returns true if the exceptionType is a representation of an F# exception declaration + /// /// The type to check. /// Optional flag that denotes accessibility of the private representation. + /// /// True if the type check is an F# exception. + /// + /// static member IsExceptionRepresentation: exceptionType:Type * ?allowAccessToPrivateRepresentation : bool -> bool - -namespace Microsoft.FSharp.Reflection - -open Microsoft.FSharp.Core - module internal ReflectionUtils = type BindingFlags = System.Reflection.BindingFlags val toBindingFlags : allowAccessToNonPublicMembers : bool -> BindingFlags \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/result.fsi b/src/fsharp/FSharp.Core/result.fsi index 77e289bd17f..956b6c80988 100644 --- a/src/fsharp/FSharp.Core/result.fsi +++ b/src/fsharp/FSharp.Core/result.fsi @@ -5,26 +5,41 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators [] + /// Contains operations for working with values of type . + /// + /// Choices and Results module Result = /// map f inp evaluates to match inp with Error e -> Error e | Ok x -> Ok (f x). + /// /// A function to apply to the OK result value. /// The input result. + /// /// A result of the input value after applying the mapping function, or Error if the input is Error. + /// + /// [] val map : mapping:('T -> 'U) -> result:Result<'T, 'TError> -> Result<'U, 'TError> /// map f inp evaluates to match inp with Error x -> Error (f x) | Ok v -> Ok v. + /// /// A function to apply to the Error result value. /// The input result. + /// /// A result of the error value after applying the mapping function, or Ok if the input is Ok. + /// + /// [] val mapError: mapping:('TError -> 'U) -> result:Result<'T, 'TError> -> Result<'T, 'U> /// bind f inp evaluates to match inp with Error e -> Error e | Ok x -> f x + /// /// A function that takes the value of type T from a result and transforms it into /// a result containing a value of type U. /// The input result. + /// /// A result of the output type of the binder. + /// + /// [] val bind: binder:('T -> Result<'U, 'TError>) -> result:Result<'T, 'TError> -> Result<'U, 'TError> diff --git a/src/fsharp/FSharp.Core/resumable.fs b/src/fsharp/FSharp.Core/resumable.fs new file mode 100644 index 00000000000..caddd62fe91 --- /dev/null +++ b/src/fsharp/FSharp.Core/resumable.fs @@ -0,0 +1,375 @@ +// Original notice: +// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights +// to this software to the public domain worldwide. This software is distributed without any warranty. +// +// Updates: +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +#nowarn "9" +#nowarn "51" +namespace Microsoft.FSharp.Core.CompilerServices + +#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE +open System +open System.Runtime.CompilerServices +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.Printf +open Microsoft.FSharp.Core.CompilerServices +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators +open Microsoft.FSharp.Control +open Microsoft.FSharp.Collections + +type IResumableStateMachine<'Data> = + abstract ResumptionPoint: int + abstract Data: 'Data with get, set + +/// Acts as a template for struct state machines introduced by __stateMachine, and also as a reflective implementation +[] +type ResumableStateMachine<'Data> = + + [] + val mutable Data: 'Data + + [] + val mutable ResumptionPoint: int + + /// Represents the delegated runtime continuation of a resumable state machine created dynamically + [] + val mutable ResumptionDynamicInfo: ResumptionDynamicInfo<'Data> + + interface IResumableStateMachine<'Data> with + member sm.ResumptionPoint = sm.ResumptionPoint + member sm.Data with get() = sm.Data and set v = sm.Data <- v + + interface IAsyncStateMachine with + + // Used for dynamic execution. For "__stateMachine" it is replaced. + member sm.MoveNext() = + sm.ResumptionDynamicInfo.MoveNext(&sm) + + // Used when dynamic execution. For "__stateMachine" it is replaced. + member sm.SetStateMachine(state) = + sm.ResumptionDynamicInfo.SetStateMachine(&sm, state) + +and ResumptionFunc<'Data> = delegate of byref> -> bool + +and [] + ResumptionDynamicInfo<'Data>(initial: ResumptionFunc<'Data>) = + member val ResumptionFunc: ResumptionFunc<'Data> = initial with get, set + member val ResumptionData: obj = null with get, set + abstract MoveNext: machine: byref> -> unit + abstract SetStateMachine: machine: byref> * machineState: IAsyncStateMachine -> unit + +type ResumableCode<'Data, 'T> = delegate of byref> -> bool + +/// Defines the implementation of the MoveNext method for a struct state machine. +[] +type MoveNextMethodImpl<'Data> = delegate of byref> -> unit + +/// Defines the implementation of the SetStateMachine method for a struct state machine. +[] +type SetStateMachineMethodImpl<'Data> = delegate of byref> * IAsyncStateMachine -> unit + +/// Defines the implementation of the code reun after the creation of a struct state machine. +[] +type AfterCode<'Data, 'Result> = delegate of byref> -> 'Result + +[] +module StateMachineHelpers = + + /// Statically determines whether resumable code is being used + [] + let __useResumableCode<'T> : bool = false + + [] + let __resumableEntry () : int option = + failwith "__resumableEntry should always be guarded by __useResumableCode and only used in valid state machine implementations" + + [] + let __resumeAt<'T> (programLabel: int) : 'T = + ignore programLabel + failwith "__resumeAt should always be guarded by __useResumableCode and only used in valid state machine implementations" + + [] + let __stateMachine<'Data, 'Result> + (moveNextMethod: MoveNextMethodImpl<'Data>) + (setStateMachineMethod: SetStateMachineMethodImpl<'Data>) + (afterCode: AfterCode<'Data, 'Result>): 'Result = + ignore moveNextMethod + ignore setStateMachineMethod + ignore afterCode + failwith "__stateMachine should always be guarded by __useResumableCode and only used in valid state machine implementations" + +module ResumableCode = + + let inline SetResumptionFunc (sm: byref>) f = + sm.ResumptionDynamicInfo.ResumptionFunc <- f + + let inline GetResumptionFunc (sm: byref>) = + sm.ResumptionDynamicInfo.ResumptionFunc + + let inline Delay(f : unit -> ResumableCode<'Data, 'T>) : ResumableCode<'Data, 'T> = + ResumableCode<'Data, 'T>(fun sm -> (f()).Invoke(&sm)) + + /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression. + let inline Zero() : ResumableCode<'Data, unit> = + ResumableCode<'Data, unit>(fun sm -> true) + + /// Chains together a step with its following step. + /// Note that this requires that the first step has no result. + /// This prevents constructs like `task { return 1; return 2; }`. + let CombineDynamic(sm: byref>, code1: ResumableCode<'Data, unit>, code2: ResumableCode<'Data, 'T>) : bool = + if code1.Invoke(&sm) then + code2.Invoke(&sm) + else + let rec resume (mf: ResumptionFunc<'Data>) = + ResumptionFunc<'Data>(fun sm -> + if mf.Invoke(&sm) then + code2.Invoke(&sm) + else + sm.ResumptionDynamicInfo.ResumptionFunc <- (resume (GetResumptionFunc &sm)) + false) + + sm.ResumptionDynamicInfo.ResumptionFunc <- (resume (GetResumptionFunc &sm)) + false + + /// Chains together a step with its following step. + /// Note that this requires that the first step has no result. + /// This prevents constructs like `task { return 1; return 2; }`. + let inline Combine(code1: ResumableCode<'Data, unit>, code2: ResumableCode<'Data, 'T>) : ResumableCode<'Data, 'T> = + ResumableCode<'Data, 'T>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + // NOTE: The code for code1 may contain await points! Resuming may branch directly + // into this code! + let __stack_fin = code1.Invoke(&sm) + if __stack_fin then + code2.Invoke(&sm) + else + false + //-- RESUMABLE CODE END + else + CombineDynamic(&sm, code1, code2)) + + let rec WhileDynamic (sm: byref>, condition: unit -> bool, body: ResumableCode<'Data,unit>) : bool = + if condition() then + if body.Invoke (&sm) then + WhileDynamic (&sm, condition, body) + else + let rf = GetResumptionFunc &sm + sm.ResumptionDynamicInfo.ResumptionFunc <- (ResumptionFunc<'Data>(fun sm -> WhileBodyDynamicAux(&sm, condition, body, rf))) + false + else + true + and WhileBodyDynamicAux (sm: byref>, condition: unit -> bool, body: ResumableCode<'Data,unit>, rf: ResumptionFunc<_>) : bool = + if rf.Invoke (&sm) then + WhileDynamic (&sm, condition, body) + else + let rf = GetResumptionFunc &sm + sm.ResumptionDynamicInfo.ResumptionFunc <- (ResumptionFunc<'Data>(fun sm -> WhileBodyDynamicAux(&sm, condition, body, rf))) + false + + /// Builds a step that executes the body while the condition predicate is true. + let inline While ([] condition : unit -> bool, body : ResumableCode<'Data, unit>) : ResumableCode<'Data, unit> = + ResumableCode<'Data, unit>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + let mutable __stack_go = true + while __stack_go && condition() do + // NOTE: The body of the state machine code for 'while' may contain await points, so resuming + // the code will branch directly into the expanded 'body', branching directly into the while loop + let __stack_body_fin = body.Invoke(&sm) + // If the body completed, we go back around the loop (__stack_go = true) + // If the body yielded, we yield (__stack_go = false) + __stack_go <- __stack_body_fin + __stack_go + //-- RESUMABLE CODE END + else + WhileDynamic(&sm, condition, body)) + + let rec TryWithDynamic (sm: byref>, body: ResumableCode<'Data, 'T>, handler: exn -> ResumableCode<'Data, 'T>) : bool = + try + if body.Invoke(&sm) then + true + else + let rf = GetResumptionFunc &sm + sm.ResumptionDynamicInfo.ResumptionFunc <- (ResumptionFunc<'Data>(fun sm -> TryWithDynamic(&sm, ResumableCode<'Data,'T>(fun sm -> rf.Invoke(&sm)), handler))) + false + with exn -> + (handler exn).Invoke(&sm) + + /// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + let inline TryWith (body: ResumableCode<'Data, 'T>, catch: exn -> ResumableCode<'Data, 'T>) : ResumableCode<'Data, 'T> = + ResumableCode<'Data, 'T>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + let mutable __stack_fin = false + let mutable __stack_caught = false + let mutable __stack_savedExn = Unchecked.defaultof<_> + // This is a meaningless assignment but ensures a debug point gets laid down + // at the 'try' in the try/with for code as we enter into the handler. + __stack_fin <- __stack_fin || __stack_fin + try + // The try block may contain await points. + let __stack_body_fin = body.Invoke(&sm) + // If we make it to the assignment we prove we've made a step + __stack_fin <- __stack_body_fin + with exn -> + // Note, remarkExpr in the F# compiler detects this pattern as the code + // is inlined and elides the debug sequence point on the code. This is because the inlining will associate + // the sequence point with the 'try' of the TryFinally because that is the range + // given for the whole expression + // task.TryWith(....) + // If you change this code you should check debug sequence points and the generated + // code tests for try/with in tasks. + __stack_caught <- true + __stack_savedExn <- exn + + if __stack_caught then + // Place the catch code outside the catch block + (catch __stack_savedExn).Invoke(&sm) + else + __stack_fin + //-- RESUMABLE CODE END + + else + TryWithDynamic(&sm, body, catch)) + + let rec TryFinallyCompensateDynamic (sm: byref>, mf: ResumptionFunc<'Data>, savedExn: exn option) : bool = + let mutable fin = false + fin <- mf.Invoke(&sm) + if fin then + // reraise at the end of the finally block + match savedExn with + | None -> true + | Some exn -> raise exn + else + let rf = GetResumptionFunc &sm + sm.ResumptionDynamicInfo.ResumptionFunc <- (ResumptionFunc<'Data>(fun sm -> TryFinallyCompensateDynamic(&sm, rf, savedExn))) + false + + let rec TryFinallyAsyncDynamic (sm: byref>, body: ResumableCode<'Data, 'T>, compensation: ResumableCode<'Data,unit>) : bool = + let mutable fin = false + let mutable savedExn = None + try + fin <- body.Invoke(&sm) + with exn -> + savedExn <- Some exn + fin <- true + if fin then + TryFinallyCompensateDynamic(&sm, ResumptionFunc<'Data>(fun sm -> compensation.Invoke(&sm)), savedExn) + else + let rf = GetResumptionFunc &sm + sm.ResumptionDynamicInfo.ResumptionFunc <- (ResumptionFunc<'Data>(fun sm -> TryFinallyAsyncDynamic(&sm, ResumableCode<'Data,'T>(fun sm -> rf.Invoke(&sm)), compensation))) + false + + /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + let inline TryFinally (body: ResumableCode<'Data, 'T>, compensation: ResumableCode<'Data,unit>) = + ResumableCode<'Data, 'T>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + let mutable __stack_fin = false + // This is a meaningless assignment but ensures a debug point gets laid down + // at the 'try' in the try/finally. The 'try' is used as the range for the + // F# computation expression desugaring to 'TryFinally' and this range in turn gets applied + // to inlined code. + __stack_fin <- __stack_fin || __stack_fin + try + let __stack_body_fin = body.Invoke(&sm) + // If we make it to the assignment we prove we've made a step, an early 'ret' exit out of the try/with + // may skip this step. + __stack_fin <- __stack_body_fin + with _exn -> + // Note, remarkExpr in the F# compiler detects this pattern as the code + // is inlined and elides the debug sequence point on either the 'compensation' + // 'reraise' statement for the code. This is because the inlining will associate + // the sequence point with the 'try' of the TryFinally because that is the range + // given for the whole expression + // task.TryFinally(....) + // If you change this code you should check debug sequence points and the generated + // code tests for try/finally in tasks. + let __stack_ignore = compensation.Invoke(&sm) + reraise() + + if __stack_fin then + let __stack_ignore = compensation.Invoke(&sm) + () + __stack_fin + //-- RESUMABLE CODE END + else + TryFinallyAsyncDynamic(&sm, body, ResumableCode<_,_>(fun sm -> compensation.Invoke(&sm)))) + + /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + let inline TryFinallyAsync (body: ResumableCode<'Data, 'T>, compensation: ResumableCode<'Data,unit>) : ResumableCode<'Data, 'T> = + ResumableCode<'Data, 'T>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + let mutable __stack_fin = false + let mutable savedExn = None + // This is a meaningless assignment but ensures a debug point gets laid down + // at the 'try' in the try/finally. The 'try' is used as the range for the + // F# computation expression desugaring to 'TryFinally' and this range in turn gets applied + // to inlined code. + __stack_fin <- __stack_fin || __stack_fin + try + let __stack_body_fin = body.Invoke(&sm) + // If we make it to the assignment we prove we've made a step, an early 'ret' exit out of the try/with + // may skip this step. + __stack_fin <- __stack_body_fin + with exn -> + savedExn <- Some exn + __stack_fin <- true + + if __stack_fin then + let __stack_compensation_fin = compensation.Invoke(&sm) + __stack_fin <- __stack_compensation_fin + if __stack_fin then + match savedExn with + | None -> () + | Some exn -> raise exn + __stack_fin + //-- RESUMABLE CODE END + else + TryFinallyAsyncDynamic(&sm, body, compensation)) + + let inline Using (resource : 'Resource, body : 'Resource -> ResumableCode<'Data, 'T>) : ResumableCode<'Data, 'T> when 'Resource :> IDisposable = + // A using statement is just a try/finally with the finally block disposing if non-null. + TryFinally( + ResumableCode<'Data, 'T>(fun sm -> (body resource).Invoke(&sm)), + ResumableCode<'Data,unit>(fun sm -> + if not (isNull (box resource)) then + resource.Dispose() + true)) + + let inline For (sequence : seq<'T>, body : 'T -> ResumableCode<'Data, unit>) : ResumableCode<'Data, unit> = + // A for loop is just a using statement on the sequence's enumerator... + Using (sequence.GetEnumerator(), + // ... and its body is a while loop that advances the enumerator and runs the body on each element. + (fun e -> While((fun () -> e.MoveNext()), ResumableCode<'Data, unit>(fun sm -> (body e.Current).Invoke(&sm))))) + + let YieldDynamic (sm: byref>) : bool = + let cont = ResumptionFunc<'Data>(fun _sm -> true) + sm.ResumptionDynamicInfo.ResumptionFunc <- cont + false + + let inline Yield () : ResumableCode<'Data, unit> = + ResumableCode<'Data, unit>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + match __resumableEntry() with + | Some contID -> + sm.ResumptionPoint <- contID + //if verbose then printfn $"[{sm.Id}] Yield: returning false to indicate yield, contID = {contID}" + false + | None -> + //if verbose then printfn $"[{sm.Id}] Yield: returning true to indicate post-yield" + true + //-- RESUMABLE CODE END + else + YieldDynamic(&sm)) + +#endif diff --git a/src/fsharp/FSharp.Core/resumable.fsi b/src/fsharp/FSharp.Core/resumable.fsi new file mode 100644 index 00000000000..a7b4ff17ef1 --- /dev/null +++ b/src/fsharp/FSharp.Core/resumable.fsi @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Core.CompilerServices + +#if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE +open Microsoft.FSharp.Collections +open Microsoft.FSharp.Core +open System +open System.Runtime.CompilerServices + +/// Acts as a template for struct state machines introduced by __stateMachine, and also as a reflective implementation +[] +[] +type ResumableStateMachine<'Data> = + + /// When statically compiled, holds the data for the state machine + [] + val mutable Data: 'Data + + /// When statically compiled, holds the continuation goto-label further execution of the state machine + [] + val mutable ResumptionPoint: int + + /// Represents the delegated runtime continuation for a resumable state machine created dynamically + /// This field is removed from state machines generated using '__stateMachine'. Resumable code + /// used in state machines which accesses this field will raise a runtime exception. + [] + val mutable ResumptionDynamicInfo: ResumptionDynamicInfo<'Data> + + interface IResumableStateMachine<'Data> + + interface IAsyncStateMachine + +and + [] + IResumableStateMachine<'Data> = + /// Get the resumption point of the state machine + abstract ResumptionPoint: int + + /// Copy-out or copy-in the data of the state machine + abstract Data: 'Data with get, set + +/// Represents the delegated runtime continuation of a resumable state machine created dynamically +and + [] + ResumptionDynamicInfo<'Data> = + + /// Create dynamic information for a state machine + new: initial: ResumptionFunc<'Data> -> ResumptionDynamicInfo<'Data> + + /// The continuation of the state machine + member ResumptionFunc: ResumptionFunc<'Data> with get, set + + /// Additional data associated with the state machine + member ResumptionData: obj with get, set + + /// Executes the MoveNext implementation of the state machine + abstract MoveNext: machine: byref> -> unit + + /// Executes the SetStateMachine implementation of the state machine + abstract SetStateMachine: machine: byref> * machineState: IAsyncStateMachine -> unit + +/// Represents the runtime continuation of a resumable state machine created dynamically +and [] + ResumptionFunc<'Data> = delegate of byref> -> bool + +/// A special compiler-recognised delegate type for specifying blocks of resumable code +/// with access to the state machine. +[] +type ResumableCode<'Data, 'T> = delegate of byref> -> bool + +/// Contains functions for composing resumable code blocks +[] +[] +module ResumableCode = + + /// Sequences one section of resumable code after another + [] + val inline Combine: code1: ResumableCode<'Data, unit> * code2: ResumableCode<'Data, 'T> -> ResumableCode<'Data, 'T> + + /// Creates resumable code whose definition is a delayed function + [] + val inline Delay: f: (unit -> ResumableCode<'Data, 'T>) -> ResumableCode<'Data, 'T> + + /// Specifies resumable code which iterates an input sequence + [] + val inline For: sequence: seq<'T> * body: ('T -> ResumableCode<'Data, unit>) -> ResumableCode<'Data, unit> + + /// Specifies resumable code which iterates yields + [] + val inline Yield: unit -> ResumableCode<'Data, unit> + + /// Specifies resumable code which executes with try/finally semantics + [] + val inline TryFinally: body: ResumableCode<'Data, 'T> * compensation: ResumableCode<'Data,unit> -> ResumableCode<'Data, 'T> + + /// Specifies resumable code which executes with try/finally semantics + [] + val inline TryFinallyAsync: body: ResumableCode<'Data, 'T> * compensation: ResumableCode<'Data,unit> -> ResumableCode<'Data, 'T> + + /// Specifies resumable code which executes with try/with semantics + [] + val inline TryWith: body: ResumableCode<'Data, 'T> * catch: (exn -> ResumableCode<'Data, 'T>) -> ResumableCode<'Data, 'T> + + /// Specifies resumable code which executes with 'use' semantics + [] + val inline Using: resource: 'Resource * body: ('Resource -> ResumableCode<'Data, 'T>) -> ResumableCode<'Data, 'T> when 'Resource :> IDisposable + + /// Specifies resumable code which executes a loop + [] + val inline While: [] condition: (unit -> bool) * body: ResumableCode<'Data, unit> -> ResumableCode<'Data, unit> + + /// Specifies resumable code which does nothing + [] + val inline Zero: unit -> ResumableCode<'Data, unit> + + /// The dynamic implementation of the corresponding operation. This operation should not be used directly. + [] + val CombineDynamic: sm: byref> * code1: ResumableCode<'Data, unit> * code2: ResumableCode<'Data, 'T> -> bool + + /// The dynamic implementation of the corresponding operation. This operation should not be used directly. + [] + val WhileDynamic: sm: byref> * condition: (unit -> bool) * body: ResumableCode<'Data, unit> -> bool + + /// The dynamic implementation of the corresponding operation. This operation should not be used directly. + [] + val TryFinallyAsyncDynamic: sm: byref> * body: ResumableCode<'Data, 'T> * compensation: ResumableCode<'Data,unit> -> bool + + /// The dynamic implementation of the corresponding operation. This operation should not be used directly. + [] + val TryWithDynamic: sm: byref> * body: ResumableCode<'Data, 'T> * handler: (exn -> ResumableCode<'Data, 'T>) -> bool + + /// The dynamic implementation of the corresponding operation. This operation should not be used directly. + [] + val YieldDynamic: sm: byref> -> bool + +/// Defines the implementation of the MoveNext method for a struct state machine. +[] +type MoveNextMethodImpl<'Data> = delegate of byref> -> unit + +/// Defines the implementation of the SetStateMachine method for a struct state machine. +[] +type SetStateMachineMethodImpl<'Data> = delegate of byref> * IAsyncStateMachine -> unit + +/// Defines the implementation of the code run after the creation of a struct state machine. +[] +type AfterCode<'Data, 'Result> = delegate of byref> -> 'Result + +/// Contains compiler intrinsics related to the definition of state machines. +[] +module StateMachineHelpers = + + /// + /// When used in a conditional, statically determines whether the 'then' branch + /// represents valid resumable code and provides an alternative implementation + /// if not. + /// + [] + [] + val __useResumableCode<'T> : bool + + /// + /// Indicates a resumption point within resumable code + /// + [] + [] + val __resumableEntry: unit -> int option + + /// + /// Indicates to jump to a resumption point within resumable code. + /// This may be the first statement in a MoveNextMethodImpl. + /// The integer must be a valid resumption point within this resumable code. + /// + /// + [] + [] + val __resumeAt : programLabel: int -> 'T + + /// + /// Statically generates a closure struct type based on ResumableStateMachine, + /// At runtime an instance of the new struct type is populated and 'afterMethod' is called + /// to consume it. + /// + /// + /// + /// At compile-time, the ResumableStateMachine type guides the generation of a new struct type by the F# compiler + /// with closure-capture fields in a way similar to an object expression. + /// Any mention of the ResumableStateMachine type in any the 'methods' is rewritten to this + /// fresh struct type. The 'methods' are used to implement the interfaces on ResumableStateMachine and are also rewritten. + /// The 'after' method is then executed and must eliminate the ResumableStateMachine. For example, + /// its return type must not include ResumableStateMachine. + /// + /// Gives the implementation of the MoveNext method on IAsyncStateMachine. + /// Gives the implementation of the SetStateMachine method on IAsyncStateMachine. + /// Gives code to execute after the generation of the state machine and to produce the final result. + [] + [] + val __stateMachine<'Data, 'Result> : + moveNextMethod: MoveNextMethodImpl<'Data> -> + setStateMachineMethod: SetStateMachineMethodImpl<'Data> -> + afterCode: AfterCode<'Data, 'Result> + -> 'Result + +#endif diff --git a/src/fsharp/FSharp.Core/seq.fs b/src/fsharp/FSharp.Core/seq.fs index 71f16b6fa2e..1734142d5cd 100644 --- a/src/fsharp/FSharp.Core/seq.fs +++ b/src/fsharp/FSharp.Core/seq.fs @@ -66,20 +66,20 @@ namespace Microsoft.FSharp.Collections else state <- Finished false - member __.Reset() = noReset() + member _.Reset() = noReset() interface System.IDisposable with member this.Dispose() = this.Dispose() let map f (e : IEnumerator<_>) : IEnumerator<_>= upcast { new MapEnumerator<_>() with - member __.DoMoveNext (curr : byref<_>) = + member _.DoMoveNext (curr : byref<_>) = if e.MoveNext() then curr <- f e.Current true else false - member __.Dispose() = e.Dispose() + member _.Dispose() = e.Dispose() } let mapi f (e : IEnumerator<_>) : IEnumerator<_> = @@ -87,21 +87,21 @@ namespace Microsoft.FSharp.Collections let mutable i = -1 upcast { new MapEnumerator<_>() with - member __.DoMoveNext curr = + member _.DoMoveNext curr = i <- i + 1 if e.MoveNext() then curr <- f.Invoke(i, e.Current) true else false - member __.Dispose() = e.Dispose() + member _.Dispose() = e.Dispose() } let map2 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) : IEnumerator<_>= let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(f) upcast { new MapEnumerator<_>() with - member __.DoMoveNext curr = + member _.DoMoveNext curr = let n1 = e1.MoveNext() let n2 = e2.MoveNext() if n1 && n2 then @@ -109,7 +109,7 @@ namespace Microsoft.FSharp.Collections true else false - member __.Dispose() = + member _.Dispose() = try e1.Dispose() finally @@ -121,14 +121,14 @@ namespace Microsoft.FSharp.Collections let mutable i = -1 upcast { new MapEnumerator<_>() with - member __.DoMoveNext curr = + member _.DoMoveNext curr = i <- i + 1 if (e1.MoveNext() && e2.MoveNext()) then curr <- f.Invoke(i, e1.Current, e2.Current) true else false - member __.Dispose() = + member _.Dispose() = try e1.Dispose() finally @@ -139,7 +139,7 @@ namespace Microsoft.FSharp.Collections let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt(f) upcast { new MapEnumerator<_>() with - member __.DoMoveNext curr = + member _.DoMoveNext curr = let n1 = e1.MoveNext() let n2 = e2.MoveNext() let n3 = e3.MoveNext() @@ -149,7 +149,7 @@ namespace Microsoft.FSharp.Collections true else false - member __.Dispose() = + member _.Dispose() = try e1.Dispose() finally @@ -169,48 +169,48 @@ namespace Microsoft.FSharp.Collections | Some x -> x { new IEnumerator<'U> with - member __.Current = get() + member _.Current = get() interface IEnumerator with - member __.Current = box (get()) - member __.MoveNext() = + member _.Current = box (get()) + member _.MoveNext() = if not started then started <- true curr <- None while (curr.IsNone && e.MoveNext()) do curr <- f e.Current Option.isSome curr - member __.Reset() = noReset() + member _.Reset() = noReset() interface System.IDisposable with - member __.Dispose() = e.Dispose() } + member _.Dispose() = e.Dispose() } let filter f (e : IEnumerator<'T>) = let mutable started = false let this = { new IEnumerator<'T> with - member __.Current = check started; e.Current + member _.Current = check started; e.Current interface IEnumerator with - member __.Current = check started; box e.Current - member __.MoveNext() = + member _.Current = check started; box e.Current + member _.MoveNext() = let rec next() = if not started then started <- true e.MoveNext() && (f e.Current || next()) next() - member __.Reset() = noReset() + member _.Reset() = noReset() interface System.IDisposable with - member __.Dispose() = e.Dispose() } + member _.Dispose() = e.Dispose() } this let unfold f x : IEnumerator<_> = let mutable state = x upcast { new MapEnumerator<_>() with - member __.DoMoveNext curr = + member _.DoMoveNext curr = match f state with | None -> false | Some (r,s) -> curr <- r state <- s true - member __.Dispose() = () + member _.Dispose() = () } let upto lastOption f = @@ -244,32 +244,32 @@ namespace Microsoft.FSharp.Collections // forced or re-forced immediately. current.Force() { new IEnumerator<'U> with - member __.Current = getCurrent() + member _.Current = getCurrent() interface IEnumerator with - member __.Current = box (getCurrent()) - member __.MoveNext() = + member _.Current = box (getCurrent()) + member _.MoveNext() = if index = completed then false elif index = unstarted then setIndex 0 true else - if index = System.Int32.MaxValue then raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + if index = System.Int32.MaxValue then invalidOp (SR.GetString(SR.enumerationPastIntMaxValue)) if index = finalIndex then false else setIndex (index + 1) true - member __.Reset() = noReset() + member _.Reset() = noReset() interface System.IDisposable with - member __.Dispose() = () } + member _.Dispose() = () } [] type ArrayEnumerator<'T>(arr: 'T array) = let mutable curr = -1 let mutable len = arr.Length - member __.Get() = + member _.Get() = if curr >= 0 then if curr >= len then alreadyFinished() else arr.[curr] @@ -278,7 +278,7 @@ namespace Microsoft.FSharp.Collections interface IEnumerator<'T> with member x.Current = x.Get() interface System.Collections.IEnumerator with - member __.MoveNext() = + member _.MoveNext() = if curr >= len then false else curr <- curr + 1 @@ -335,10 +335,10 @@ namespace Microsoft.FSharp.Collections // yield n } type GenerateThen<'T>(g:Generator<'T>, cont : unit -> Generator<'T>) = - member __.Generator = g - member __.Cont = cont + member _.Generator = g + member _.Cont = cont interface Generator<'T> with - member __.Apply = (fun () -> + member _.Apply = (fun () -> match appG g with | Stop -> // OK, move onto the generator given by the continuation @@ -349,7 +349,7 @@ namespace Microsoft.FSharp.Collections | Goto next -> Goto(GenerateThen<_>.Bind(next, cont))) - member __.Disposer = + member _.Disposer = g.Disposer static member Bind (g:Generator<'T>, cont) = @@ -386,12 +386,12 @@ namespace Microsoft.FSharp.Collections let mutable g = g let mutable curr = None let mutable finished = false - member __.Generator = g + member _.Generator = g interface IEnumerator<'T> with - member __.Current = + member _.Current = match curr with | Some v -> v - | None -> raise <| System.InvalidOperationException (SR.GetString(SR.moveNextNotCalledOrFinished)) + | None -> invalidOp (SR.GetString(SR.moveNextNotCalledOrFinished)) interface System.Collections.IEnumerator with member x.Current = box (x :> IEnumerator<_>).Current @@ -408,21 +408,21 @@ namespace Microsoft.FSharp.Collections | Goto next -> (g <- next) (x :> IEnumerator).MoveNext() - member __.Reset() = IEnumerator.noReset() + member _.Reset() = IEnumerator.noReset() interface System.IDisposable with - member __.Dispose() = + member _.Dispose() = if not finished then disposeG g // Internal type, used to optimize Enumerator/Generator chains type LazyGeneratorWrappingEnumerator<'T>(e:IEnumerator<'T>) = - member __.Enumerator = e + member _.Enumerator = e interface Generator<'T> with - member __.Apply = (fun () -> + member _.Apply = (fun () -> if e.MoveNext() then Yield e.Current else Stop) - member __.Disposer= Some e.Dispose + member _.Disposer= Some e.Dispose let EnumerateFromGenerator(g:Generator<'T>) = match g with @@ -684,10 +684,10 @@ namespace Microsoft.FSharp.Collections (* Note: don't create or dispose any IEnumerable if n = 0 *) if count = 0 then empty else seq { use e = source.GetEnumerator() - for x in 0 .. count - 1 do + for x in count .. - 1 .. 1 do if not (e.MoveNext()) then - invalidOpFmt "tried to take {0} {1} past the end of the seq" - [|SR.GetString SR.notEnoughElements; x; (if x = 1 then "element" else "elements")|] + invalidOpFmt "{0}: tried to take {1} {2} past the end of the seq. Use Seq.truncate to get {3} or less elements" + [|SR.GetString SR.notEnoughElements; x; (if x = 1 then "element" else "elements"); count|] yield e.Current } [] @@ -980,46 +980,57 @@ namespace Microsoft.FSharp.Collections // * the prefix followed by elts from the enumerator are the initial sequence. // * the prefix contains only as many elements as the longest enumeration so far. let prefix = ResizeArray<_>() - let enumeratorR = ref None - // None = Unstarted. - // Some(Some e) = Started. - // Some None = Finished. + + // None = Unstarted. + // Some(Some e) = Started. + // Some None = Finished. + let mutable enumeratorR = None + let oneStepTo i = // If possible, step the enumeration to prefix length i (at most one step). // Be speculative, since this could have already happened via another thread. - if not (i < prefix.Count) then // is a step still required? + if i >= prefix.Count then // is a step still required? // If not yet started, start it (create enumerator). - match !enumeratorR with - | None -> enumeratorR := Some (Some (source.GetEnumerator())) - | Some _ -> () - match (!enumeratorR).Value with - | Some enumerator -> if enumerator.MoveNext() then - prefix.Add(enumerator.Current) - else - enumerator.Dispose() // Move failed, dispose enumerator, - enumeratorR := Some None // drop it and record finished. + let optEnumerator = + match enumeratorR with + | None -> + let optEnumerator = Some (source.GetEnumerator()) + enumeratorR <- Some optEnumerator + optEnumerator + | Some optEnumerator -> + optEnumerator + + match optEnumerator with + | Some enumerator -> + if enumerator.MoveNext() then + prefix.Add(enumerator.Current) + else + enumerator.Dispose() // Move failed, dispose enumerator, + enumeratorR <- Some None // drop it and record finished. | None -> () + let result = unfold (fun i -> - // i being the next position to be returned - // A lock is needed over the reads to prefix.Count since the list may be being resized - // NOTE: we could change to a reader/writer lock here - lock enumeratorR (fun () -> - if i < prefix.Count then - Some (prefix.[i],i+1) - else - oneStepTo i - if i < prefix.Count then - Some (prefix.[i],i+1) - else - None)) 0 + // i being the next position to be returned + // A lock is needed over the reads to prefix.Count since the list may be being resized + // NOTE: we could change to a reader/writer lock here + lock prefix (fun () -> + if i < prefix.Count then + Some (prefix.[i],i+1) + else + oneStepTo i + if i < prefix.Count then + Some (prefix.[i],i+1) + else + None)) 0 let cleanup() = - lock enumeratorR (fun () -> + lock prefix (fun () -> prefix.Clear() - match !enumeratorR with + match enumeratorR with | Some (Some e) -> IEnumerator.dispose e | _ -> () - enumeratorR := None) + enumeratorR <- None) + (new CachedSeq<_>(cleanup, result) :> seq<_>) [] @@ -1488,3 +1499,67 @@ namespace Microsoft.FSharp.Collections [|SR.GetString SR.inputMustBePositive; count|] mkDelayedSeq (fun () -> source |> toArray |> Array.splitInto count :> seq<_>) + + [] + let removeAt (index: int) (source: seq<'T>) : seq<'T> = + if index < 0 then invalidArg "index" "index must be within bounds of the array" + seq { + let mutable i = 0 + for item in source do + if i <> index then + yield item + i <- i + 1 + if i <= index then invalidArg "index" "index must be within bounds of the array" + } + + [] + let removeManyAt (index: int) (count: int) (source: seq<'T>) : seq<'T> = + if index < 0 then invalidArg "index" "index must be within bounds of the array" + seq { + let mutable i = 0 + for item in source do + if i < index || i >= index + count then + yield item + i <- i + 1 + if i <= index then invalidArg "index" "index must be within bounds of the array" + } + + [] + let updateAt (index: int) (value: 'T) (source: seq<'T>) : seq<'T> = + if index < 0 then invalidArg "index" "index must be within bounds of the array" + seq { + let mutable i = 0 + for item in source do + if i <> index then + yield item + else yield value + i <- i + 1 + if i <= index then invalidArg "index" "index must be within bounds of the array" + } + + [] + let insertAt (index: int) (value: 'T) (source: seq<'T>) : seq<'T> = + if index < 0 then invalidArg "index" "index must be within bounds of the array" + seq { + let mutable i = 0 + for item in source do + if i = index then + yield value + yield item + i <- i + 1 + if i = index then yield value + if i < index then invalidArg "index" "index must be within bounds of the array" + } + + [] + let insertManyAt (index: int) (values: seq<'T>) (source: seq<'T>) : seq<'T> = + if index < 0 then invalidArg "index" "index must be within bounds of the array" + seq { + let mutable i = 0 + for item in source do + if i = index then yield! values + yield item + i <- i + 1 + if i = index then yield! values // support inserting at the end + if i < index then invalidArg "index" "index must be within bounds of the array" + } \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/seq.fsi b/src/fsharp/FSharp.Core/seq.fsi index 9ed5bed0965..7a948e91ac3 100644 --- a/src/fsharp/FSharp.Core/seq.fsi +++ b/src/fsharp/FSharp.Core/seq.fsi @@ -2,1363 +2,1848 @@ namespace Microsoft.FSharp.Collections - open System - open System.Collections - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - - /// Basic operations on IEnumerables. - [] - [] - module Seq = - - /// Returns a new sequence that contains all pairings of elements from the first and second sequences. - /// The first sequence. - /// The second sequence. - /// The result sequence. - /// Thrown when either of the input sequences is null. - [] - val allPairs: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2> - - /// Wraps the two given enumerations as a single concatenated - /// enumeration. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed - /// concurrently. - /// - /// The first sequence. - /// The second sequence. - /// - /// The result sequence. - /// - /// Thrown when either of the two provided sequences is - /// null. - [] - val append: source1:seq<'T> -> source2:seq<'T> -> seq<'T> - - /// Returns the average of the elements in the sequence. - /// - /// The elements are averaged using the + operator, DivideByInt method and Zero property - /// associated with the element type. - /// - /// The input sequence. - /// - /// The average. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence has zero elements. - [] - val inline average : source:seq<(^T)> -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member DivideByInt : ^T * int -> ^T) - and ^T : (static member Zero : ^T) - - /// Returns the average of the results generated by applying the function to each element - /// of the sequence. - /// - /// The elements are averaged using the + operator, DivideByInt method and Zero property - /// associated with the generated type. - /// - /// A function applied to transform each element of the sequence. - /// The input sequence. - /// - /// The average. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence has zero elements. - [] - val inline averageBy : projection:('T -> ^U) -> source:seq<'T> -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member DivideByInt : ^U * int -> ^U) - and ^U : (static member Zero : ^U) - - /// Returns a sequence that corresponds to a cached version of the input sequence. - /// This result sequence will have the same elements as the input sequence. The result - /// can be enumerated multiple times. The input sequence will be enumerated at most - /// once and only as far as is necessary. Caching a sequence is typically useful when repeatedly - /// evaluating items in the original sequence is computationally expensive or if - /// iterating the sequence causes side-effects that the user does not want to be - /// repeated multiple times. - /// - /// Enumeration of the result sequence is thread safe in the sense that multiple independent IEnumerator - /// values may be used simultaneously from different threads (accesses to - /// the internal lookaside table are thread safe). Each individual IEnumerator - /// is not typically thread safe and should not be accessed concurrently. - /// - /// Once enumeration of the input sequence has started, - /// it's enumerator will be kept live by this object until the enumeration has completed. - /// At that point, the enumerator will be disposed. - /// - /// The enumerator may be disposed and underlying cache storage released by - /// converting the returned sequence object to type IDisposable, and calling the Dispose method - /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will - /// be used. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val cache: source:seq<'T> -> seq<'T> - - /// Wraps a loosely-typed System.Collections sequence as a typed sequence. - /// - /// The use of this function usually requires a type annotation. - /// An incorrect type annotation may result in runtime type - /// errors. - /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val cast: source:IEnumerable -> seq<'T> - - /// Applies the given function to each element of the list. Return - /// the list comprised of the results "x" for each element where - /// the function returns Some(x). - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not - /// be accessed concurrently. - /// - /// A function to transform items of type T into options of type U. - /// The input sequence of type T. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val choose: chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U> - - /// Divides the input sequence into chunks of size at most chunkSize. - /// The maximum size of each chunk. - /// The input sequence. - /// The sequence divided into chunks. - /// Thrown when the input sequence is null. - /// Thrown when chunkSize is not positive. - [] - val chunkBySize: chunkSize:int -> source:seq<'T> -> seq<'T[]> - - /// Applies the given function to each element of the sequence and concatenates all the - /// results. - /// - /// Remember sequence is lazy, effects are delayed until it is enumerated. - /// - /// A function to transform elements of the input sequence into the sequences - /// that will then be concatenated. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val collect: mapping:('T -> 'Collection) -> source:seq<'T> -> seq<'U> when 'Collection :> seq<'U> - - /// Compares two sequences using the given comparison function, element by element. - /// - /// A function that takes an element from each sequence and returns an int. - /// If it evaluates to a non-zero value iteration is stopped and that value is returned. - /// The first input sequence. - /// The second input sequence. - /// - /// Returns the first non-zero result from the comparison function. If the end of a sequence - /// is reached it returns a -1 if the first sequence is shorter and a 1 if the second sequence - /// is shorter. - /// - /// Thrown when either of the input sequences - /// is null. - [] - val compareWith: comparer:('T -> 'T -> int) -> source1:seq<'T> -> source2:seq<'T> -> int - - /// Combines the given enumeration-of-enumerations as a single concatenated - /// enumeration. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// The input enumeration-of-enumerations. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val concat: sources:seq<'Collection> -> seq<'T> when 'Collection :> seq<'T> - - /// Tests if the sequence contains the specified element. - /// The value to locate in the input sequence. - /// The input sequence. - /// True if the input sequence contains the specified element; false otherwise. - /// Thrown when the input sequence is null. - [] - val inline contains: value:'T -> source:seq<'T> -> bool when 'T : equality - - /// Applies a key-generating function to each element of a sequence and returns a sequence yielding unique - /// keys and their number of occurrences in the original sequence. - /// - /// Note that this function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// A function transforming each item of the input sequence into a key to be - /// compared against the others. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val countBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * int> when 'Key : equality - - /// Returns a sequence that is built from the given delayed specification of a - /// sequence. - /// - /// The input function is evaluated each time an IEnumerator for the sequence - /// is requested. - /// - /// The generating function for the sequence. - [] - val delay : generator:(unit -> seq<'T>) -> seq<'T> - - /// Returns a sequence that contains no duplicate entries according to generic hash and - /// equality comparisons on the entries. - /// If an element occurs multiple times in the sequence then the later occurrences are discarded. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val distinct: source:seq<'T> -> seq<'T> when 'T : equality - - /// Returns a sequence that contains no duplicate entries according to the - /// generic hash and equality comparisons on the keys returned by the given key-generating function. - /// If an element occurs multiple times in the sequence then the later occurrences are discarded. - /// - /// A function transforming the sequence items into comparable keys. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val distinctBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : equality - - /// Splits the input sequence into at most count chunks. - /// This function returns a sequence that digests the whole initial sequence as soon as that - /// sequence is iterated. As a result this function should not be used with large or infinite sequences. - /// The maximum number of chunks. - /// The input sequence. - /// The sequence split into chunks. - /// Thrown when the input sequence is null. - /// Thrown when count is not positive. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val splitInto: count:int -> source:seq<'T> -> seq<'T[]> - - /// Creates an empty sequence. - /// - /// An empty sequence. - [] - [] - val empty<'T> : seq<'T> - - /// Returns a new sequence with the distinct elements of the second sequence which do not appear in the first sequence, - /// using generic hash and equality comparisons to compare values. - /// - /// Note that this function returns a sequence that digests the whole of the first input sequence as soon as - /// the result sequence is iterated. As a result this function should not be used with - /// large or infinite sequences in the first parameter. The function makes no assumption on the ordering of the first input - /// sequence. - /// - /// A sequence whose elements that also occur in the second sequence will cause those elements to be - /// removed from the returned sequence. - /// A sequence whose elements that are not also in first will be returned. - /// - /// A sequence that contains the set difference of the elements of two sequences. - /// - /// Thrown when either of the two input sequences is null. - [] - val except: itemsToExclude:seq<'T> -> source:seq<'T> -> seq<'T> when 'T : equality - - /// Tests if any element of the sequence satisfies the given predicate. - /// - /// The predicate is applied to the elements of the input sequence. If any application - /// returns true then the overall result is true and no further elements are tested. - /// Otherwise, false is returned. - /// - /// A function to test each item of the input sequence. - /// The input sequence. - /// - /// True if any result from the predicate is true; false otherwise. - /// - /// Thrown when the input sequence is null. - [] - val exists: predicate:('T -> bool) -> source:seq<'T> -> bool - - /// Tests if any pair of corresponding elements of the input sequences satisfies the given predicate. - /// - /// The predicate is applied to matching elements in the two sequences up to the lesser of the - /// two lengths of the collections. If any application returns true then the overall result is - /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. - /// - /// A function to test each pair of items from the input sequences. - /// The first input sequence. - /// The second input sequence. - /// - /// True if any result from the predicate is true; false otherwise. - /// - /// Thrown when either of the two input sequences is null. - [] - val exists2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool - - /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns "true". This is a synonym for Seq.where. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// Remember sequence is lazy, effects are delayed until it is enumerated. - /// - /// A function to test whether each item in the input sequence should be included in the output. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val filter: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> - - /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns "true". - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// Remember sequence is lazy, effects are delayed until it is enumerated. - /// - /// A synonym for Seq.filter. - /// - /// A function to test whether each item in the input sequence should be included in the output. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val where: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> - - /// Returns the first element for which the given function returns True. - /// - /// A function to test whether an item in the sequence should be returned. - /// The input sequence. - /// - /// The first element for which the predicate returns True. - /// - /// Thrown if no element returns true when - /// evaluated by the predicate - /// Thrown when the input sequence is null - [] - val find: predicate:('T -> bool) -> source:seq<'T> -> 'T - - /// Returns the last element for which the given function returns True. - /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. - /// A function to test whether an item in the sequence should be returned. - /// The input sequence. - /// The last element for which the predicate returns True. - /// Thrown if no element returns true when - /// evaluated by the predicate - /// Thrown when the input sequence is null - /// This function consumes the whole input sequence before returning the result. - [] - val findBack: predicate:('T -> bool) -> source:seq<'T> -> 'T - - /// Returns the index of the first element for which the given function returns True. - /// - /// A function to test whether the index of a particular element should be returned. - /// The input sequence. - /// - /// The index of the first element for which the predicate returns True. - /// - /// Thrown if no element returns true when - /// evaluated by the predicate - /// Thrown when the input sequence is null - [] - val findIndex: predicate:('T -> bool) -> source:seq<'T> -> int - - /// Returns the index of the last element for which the given function returns True. - /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. - /// A function to test whether the index of a particular element should be returned. - /// The input sequence. - /// The index of the last element for which the predicate returns True. - /// Thrown if no element returns true when - /// evaluated by the predicate - /// Thrown when the input sequence is null - /// This function consumes the whole input sequence before returning the result. - [] - val findIndexBack: predicate:('T -> bool) -> source:seq<'T> -> int - - /// Applies a function to each element of the collection, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN - /// then computes f (... (f s i0)...) iN - /// - /// A function that updates the state with each element from the sequence. - /// The initial state. - /// The input sequence. - /// - /// The state object after the folding function is applied to each element of the sequence. - /// - /// Thrown when the input sequence is null. - [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State - - /// Applies a function to corresponding elements of two collections, threading an accumulator argument - /// through the computation. The two sequences need not have equal lengths: - /// when one sequence is exhausted any remaining elements in the other sequence are ignored. - /// If the input function is f and the elements are i0...iN and j0...jN - /// then computes f (... (f s i0 j0)...) iN jN. - /// The function to update the state given the input elements. - /// The initial state. - /// The first input sequence. - /// The second input sequence. - /// The final state value. - /// Thrown when the either of the input sequences is null. - [] - val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> source1:seq<'T1> -> source2:seq<'T2> -> 'State - - /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN - /// then computes f i0 (... (f iN s)...) - /// The function to update the state given the input elements. - /// The input sequence. - /// The initial state. - /// The state object after the folding function is applied to each element of the sequence. - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before returning the result. - [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> 'State - - /// Applies a function to corresponding elements of two collections, starting from the end of the shorter collection, - /// threading an accumulator argument through the computation. The two sequences need not have equal lengths. - /// If the input function is f and the elements are i0...iN and j0...jM, N < M - /// then computes f i0 j0 (... (f iN jN s)...). - /// The function to update the state given the input elements. - /// The first input sequence. - /// The second input sequence. - /// The initial state. - /// The final state value. - /// Thrown when the either of the input sequences is null. - [] - val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> source1:seq<'T1> -> source2:seq<'T2> -> state:'State -> 'State - - /// Tests if all elements of the sequence satisfy the given predicate. - /// - /// The predicate is applied to the elements of the input sequence. If any application - /// returns false then the overall result is false and no further elements are tested. - /// Otherwise, true is returned. - /// - /// A function to test an element of the input sequence. - /// The input sequence. - /// - /// True if every element of the sequence satisfies the predicate; false otherwise. - /// - /// Thrown when the input sequence is null. - [] - val forall: predicate:('T -> bool) -> source:seq<'T> -> bool - - /// Tests the all pairs of elements drawn from the two sequences satisfy the - /// given predicate. If one sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. - /// - /// A function to test pairs of elements from the input sequences. - /// The first input sequence. - /// The second input sequence. - /// - /// True if all pairs satisfy the predicate; false otherwise. - /// - /// Thrown when either of the input sequences is null. - [] - val forall2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool - - /// Applies a key-generating function to each element of a sequence and yields a sequence of - /// unique keys. Each unique key contains a sequence of all elements that match - /// to this key. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// A function that transforms an element of the sequence into a comparable key. - /// The input sequence. - /// - /// The result sequence. - [] - val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> when 'Key : equality - - /// Returns the first element of the sequence. - /// - /// The input sequence. - /// - /// The first element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input does not have any elements. - [] - val head: source:seq<'T> -> 'T - - /// Returns the first element of the sequence, or None if the sequence is empty. - /// - /// The input sequence. - /// - /// The first element of the sequence or None. - /// - /// Thrown when the input sequence is null. - [] - val tryHead: source:seq<'T> -> 'T option - - /// Returns the last element of the sequence. - /// The input sequence. - /// The last element of the sequence. - /// Thrown when the input sequence is null. - /// Thrown when the input does not have any elements. - [] - val last: source:seq<'T> -> 'T - - /// Returns the last element of the sequence. - /// Return None if no such element exists. - /// - /// The input sequence. - /// - /// The last element of the sequence or None. - /// - /// Thrown when the input sequence is null. - [] - val tryLast: source:seq<'T> -> 'T option - - /// Returns the only element of the sequence. - /// - /// The input sequence. - /// - /// The only element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input does not have precisely one element. - [] - val exactlyOne: source:seq<'T> -> 'T - - /// Returns the only element of the sequence or None if sequence is empty or contains more than one element. - /// - /// The input sequence. - /// - /// The only element of the sequence or None. - /// - /// Thrown when the input sequence is null. - [] - val tryExactlyOne: source:seq<'T> -> 'T option - - /// Returns true if the sequence contains no elements, false otherwise. - /// - /// The input sequence. - /// - /// True if the sequence is empty; false otherwise. - /// - /// Thrown when the input sequence is null. - [] - val isEmpty: source:seq<'T> -> bool - - /// Builds a new collection whose elements are the corresponding elements of the input collection - /// paired with the integer index (from 0) of each element. - /// The input sequence. - /// The result sequence. - /// Thrown when the input sequence is null. - [] - val indexed: source:seq<'T> -> seq - - /// Generates a new sequence which, when iterated, will return successive - /// elements by calling the given function, up to the given count. Each element is saved after its - /// initialization. The function is passed the index of the item being - /// generated. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// The maximum number of items to generate for the sequence. - /// A function that generates an item in the sequence from a given index. - /// - /// The result sequence. - /// - /// Thrown when count is negative. - [] - val init: count:int -> initializer:(int -> 'T) -> seq<'T> - - /// Generates a new sequence which, when iterated, will return successive - /// elements by calling the given function. The results of calling the function - /// will not be saved, that is the function will be reapplied as necessary to - /// regenerate the elements. The function is passed the index of the item being - /// generated. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// Iteration can continue up to Int32.MaxValue. - /// - /// A function that generates an item in the sequence from a given index. - /// - /// The result sequence. - [] - val initInfinite: initializer:(int -> 'T) -> seq<'T> - - /// Computes the element at the specified index in the collection. - /// The index of the element to retrieve. - /// The input sequence. - /// The element at the specified index of the sequence. - /// Thrown when the input sequence is null. - /// Thrown when the index is negative or the input sequence does not contain enough elements. - [] - val item: index:int -> source:seq<'T> -> 'T - - /// Applies the given function to each element of the collection. - /// - /// A function to apply to each element of the sequence. - /// The input sequence. - /// - /// Thrown when the input sequence is null. - [] - val iter: action:('T -> unit) -> source:seq<'T> -> unit - - /// Applies the given function to each element of the collection. The integer passed to the - /// function indicates the index of element. - /// - /// A function to apply to each element of the sequence that can also access the current index. - /// The input sequence. - /// - /// Thrown when the input sequence is null. - [] - val iteri: action:(int -> 'T -> unit) -> source:seq<'T> -> unit - - /// Applies the given function to two collections simultaneously. If one sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. - /// - /// A function to apply to each pair of elements from the input sequences. - /// The first input sequence. - /// The second input sequence. - /// - /// Thrown when either of the input sequences is null. - [] - val iter2: action:('T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit - - /// Applies the given function to two collections simultaneously. If one sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. The integer passed to the - /// function indicates the index of element. - /// - /// A function to apply to each pair of elements from the input sequences along with their index. - /// The first input sequence. - /// The second input sequence. - /// - /// Thrown when either of the input sequences is null. - [] - val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit - - /// Returns the length of the sequence - /// - /// The input sequence. - /// - /// The length of the sequence. - /// - /// Thrown when the input sequence is null. - [] - val length: source:seq<'T> -> int - - /// Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The given function will be applied - /// as elements are demanded using the MoveNext method on enumerators retrieved from the - /// object. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// A function to transform items from the input sequence. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U> - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. - /// - /// A function to transform pairs of items from the input sequences. - /// The first input sequence. - /// The second input sequence. - /// - /// The result sequence. - /// - /// Thrown when either of the input sequences is null. - [] - val map2: mapping:('T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U> - - /// Combines map and fold. Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The function is also used to accumulate a final value. - /// This function digests the whole initial sequence as soon as it is called. As a result this function should - /// not be used with large or infinite sequences. - /// The function to transform elements from the input collection and accumulate the final value. - /// The initial state. - /// The input collection. - /// Thrown when the input collection is null. - /// The collection of transformed elements, and the final accumulated value. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> source:seq<'T> -> seq<'Result> * 'State - - /// Combines map and foldBack. Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The function is also used to accumulate a final value. - /// This function digests the whole initial sequence as soon as it is called. As a result this function should - /// not be used with large or infinite sequences. - /// The function to transform elements from the input collection and accumulate the final value. - /// The input collection. - /// The initial state. - /// Thrown when the input collection is null. - /// The collection of transformed elements, and the final accumulated value. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> source:seq<'T> -> state:'State -> seq<'Result> * 'State - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding triples of elements from the three sequences. If one input sequence if shorter than - /// the others then the remaining elements of the longer sequences are ignored. - /// - /// The function to transform triples of elements from the input sequences. - /// The first input sequence. - /// The second input sequence. - /// The third input sequence. - /// - /// The result sequence. - /// - /// Thrown when any of the input sequences is null. - [] - val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'U> - - /// Builds a new collection whose elements are the results of applying the given function - /// to each of the elements of the collection. The integer index passed to the - /// function indicates the index (from 0) of element being transformed. - /// - /// A function to transform items from the input sequence that also supplies the current index. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val mapi: mapping:(int -> 'T -> 'U) -> source:seq<'T> -> seq<'U> - - /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than - /// the other then the remaining elements of the longer sequence are ignored. The integer index passed to the - /// function indicates the index (from 0) of element being transformed. - /// - /// A function to transform pairs of items from the input sequences that also supplies the current index. - /// The first input sequence. - /// The second input sequence. - /// - /// The result sequence. - /// - /// Thrown when either of the input sequences is null. - [] - val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U> - - /// Returns the greatest of all elements of the sequence, compared via Operators.max - /// - /// The input sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - /// - /// The largest element of the sequence. - [] - val inline max : source:seq<'T> -> 'T when 'T : comparison - - /// Returns the greatest of all elements of the sequence, compared via Operators.max on the function result. - /// - /// A function to transform items from the input sequence into comparable keys. - /// The input sequence. - /// - /// The largest element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val inline maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison - -(* - /// Returns the greatest function result from the elements of the sequence, compared via Operators.max. - /// - /// A function to transform items from the input sequence into comparable keys. - /// The input sequence. - /// - /// The largest element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val inline maxValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison -*) - - /// Returns the lowest of all elements of the sequence, compared via Operators.min. - /// - /// The input sequence. - /// - /// The smallest element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val inline min : source:seq<'T> -> 'T when 'T : comparison - - /// Returns the lowest of all elements of the sequence, compared via Operators.min on the function result. - /// - /// A function to transform items from the input sequence into comparable keys. - /// The input sequence. - /// - /// The smallest element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val inline minBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison - -(* - /// Returns the lowest function result from the elements of the sequence, compared via Operators.max. - /// - /// A function to transform items from the input sequence into comparable keys. - /// The input sequence. - /// - /// The smallest element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val inline minValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison -*) - - /// Computes the nth element in the collection. - /// - /// The index of element to retrieve. - /// The input sequence. - /// - /// The nth element of the sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the index is negative or the input sequence does not contain enough elements. - [] - [] - val nth: index:int -> source:seq<'T> -> 'T - - - [] - /// Views the given array as a sequence. - /// - /// The input array. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - val ofArray: source:'T[] -> seq<'T> - - [] - /// Views the given list as a sequence. - /// - /// The input list. - /// - /// The result sequence. - val ofList: source:'T list -> seq<'T> - - /// Returns a sequence of each element in the input sequence and its predecessor, with the - /// exception of the first element which is only returned as the predecessor of the second element. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val pairwise: source:seq<'T> -> seq<'T * 'T> - - /// Returns a sequence with all elements permuted according to the - /// specified permutation. - /// - /// Note that this function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. - /// - /// The function that maps input indices to output indices. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when indexMap does not produce a valid permutation. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val permute: indexMap:(int -> int) -> source:seq<'T> -> seq<'T> - - /// Applies the given function to successive elements, returning the first - /// x where the function returns "Some(x)". - /// - /// A function to transform each item of the input sequence into an option of the output type. - /// The input sequence. - /// - /// The selected element. - /// - /// Thrown when the input sequence is null. - /// Thrown when every item of the sequence - /// evaluates to None when the given function is applied. - [] - val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U - - /// Builds a new sequence object that delegates to the given sequence object. This ensures - /// the original sequence cannot be rediscovered and mutated by a type cast. For example, - /// if given an array the returned sequence will return the elements of the array, but - /// you cannot cast the returned sequence object to an array. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val readonly : source:seq<'T> -> seq<'T> - - /// Applies a function to each element of the sequence, threading an accumulator argument - /// through the computation. Begin by applying the function to the first two elements. - /// Then feed this result into the function along with the third element and so on. - /// Return the final result. - /// - /// A function that takes in the current accumulated result and the next - /// element of the sequence to produce the next accumulated result. - /// The input sequence. - /// - /// The final result of the reduction function. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val reduce: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T - - /// Creates a sequence by replicating the given initial value. - /// The number of elements to replicate. - /// The value to replicate - /// The generated sequence. - [] - val replicate: count:int -> initial:'T -> seq<'T> - - /// Applies a function to each element of the sequence, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN - /// then computes f i0 (...(f iN-1 iN)). - /// A function that takes in the next-to-last element of the sequence and the - /// current accumulated result to produce the next accumulated result. - /// The input sequence. - /// The final result of the reductions. - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - /// This function consumes the whole input sequence before returning the result. - [] - val reduceBack: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T - - /// Returns a new sequence with the elements in reverse order. - /// The input sequence. - /// The reversed sequence. - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before yielding the first element of the reversed sequence. - [] - val rev: source:seq<'T> -> seq<'T> - - /// Like fold, but computes on-demand and returns the sequence of intermediary and final results. - /// - /// A function that updates the state with each element from the sequence. - /// The initial state. - /// The input sequence. - /// - /// The resulting sequence of computed states. - /// - /// Thrown when the input sequence is null. - [] - val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> seq<'State> - - /// Like foldBack, but returns the sequence of intermediary and final results. - /// This function returns a sequence that digests the whole initial sequence as soon as that - /// sequence is iterated. As a result this function should not be used with large or infinite sequences. - /// - /// A function that updates the state with each element from the sequence. - /// The input sequence. - /// The initial state. - /// The resulting sequence of computed states. - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> seq<'State> - - /// Returns a sequence that yields one item only. - /// - /// The input item. - /// - /// The result sequence of one item. - [] - val singleton: value:'T -> seq<'T> - - /// Returns a sequence that skips N elements of the underlying sequence and then yields the - /// remaining elements of the sequence. - /// - /// The number of items to skip. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when count exceeds the number of elements - /// in the sequence. - [] - val skip: count:int -> source:seq<'T> -> seq<'T> - - /// Returns a sequence that, when iterated, skips elements of the underlying sequence while the - /// given predicate returns True, and then yields the remaining elements of the sequence. - /// - /// A function that evaluates an element of the sequence to a boolean value. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val skipWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> - - /// Yields a sequence ordered by keys. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// This is a stable sort, that is the original order of equal elements is preserved. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val sort : source:seq<'T> -> seq<'T> when 'T : comparison - - /// Yields a sequence ordered using the given comparison function. - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// This is a stable sort, that is the original order of equal elements is preserved. - /// The function to compare the collection elements. - /// The input sequence. - /// The result sequence. - /// This function consumes the whole input sequence before yielding the first element of the result sequence. - [] - val sortWith : comparer:('T -> 'T -> int) -> source:seq<'T> -> seq<'T> - - /// Applies a key-generating function to each element of a sequence and yield a sequence ordered - /// by keys. The keys are compared using generic comparison as implemented by Operators.compare. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// This is a stable sort, that is the original order of equal elements is preserved. - /// - /// A function to transform items of the input sequence into comparable keys. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison - - /// Yields a sequence ordered descending by keys. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// This is a stable sort, that is the original order of equal elements is preserved. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val inline sortDescending : source:seq<'T> -> seq<'T> when 'T : comparison - - /// Applies a key-generating function to each element of a sequence and yield a sequence ordered - /// descending by keys. The keys are compared using generic comparison as implemented by Operators.compare. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original - /// sequence. - /// - /// This is a stable sort, that is the original order of equal elements is preserved. - /// - /// A function to transform items of the input sequence into comparable keys. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val inline sortByDescending : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison - - /// Returns the sum of the elements in the sequence. - /// - /// The elements are summed using the + operator and Zero property associated with the generated type. - /// - /// The input sequence. - /// - /// The computed sum. - [] - val inline sum : source:seq<(^T)> -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member Zero : ^T) - - /// Returns the sum of the results generated by applying the function to each element of the sequence. - /// The generated elements are summed using the + operator and Zero property associated with the generated type. - /// - /// A function to transform items from the input sequence into the type that will be summed. - /// The input sequence. - /// - /// The computed sum. - [] - val inline sumBy : projection:('T -> ^U) -> source:seq<'T> -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member Zero : ^U) - - /// Returns a sequence that skips 1 element of the underlying sequence and then yields the - /// remaining elements of the sequence. - /// - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - [] - val tail: source:seq<'T> -> seq<'T> - - /// Returns the first N elements of the sequence. - /// Throws InvalidOperationException - /// if the count exceeds the number of elements in the sequence. Seq.truncate - /// returns as many items as the sequence contains instead of throwing an exception. - /// - /// The number of items to take. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - /// Thrown when the input sequence is empty. - /// Thrown when count exceeds the number of elements - /// in the sequence. - [] - val take: count:int -> source:seq<'T> -> seq<'T> - - /// Returns a sequence that, when iterated, yields elements of the underlying sequence while the - /// given predicate returns True, and then returns no further elements. - /// - /// A function that evaluates to false when no more items should be returned. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val takeWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> - - /// Builds an array from the given collection. - /// - /// The input sequence. - /// - /// The result array. - /// - /// Thrown when the input sequence is null. - [] - val toArray: source:seq<'T> -> 'T[] - - /// Builds a list from the given collection. - /// - /// The input sequence. - /// - /// The result list. - /// - /// Thrown when the input sequence is null. - [] - val toList: source:seq<'T> -> 'T list - - /// Returns the first element for which the given function returns True. - /// Return None if no such element exists. - /// - /// A function that evaluates to a Boolean when given an item in the sequence. - /// The input sequence. - /// - /// The found element or None. - /// - /// Thrown when the input sequence is null. - [] - val tryFind: predicate:('T -> bool) -> source:seq<'T> -> 'T option - - /// Returns the last element for which the given function returns True. - /// Return None if no such element exists. - /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. - /// A function that evaluates to a Boolean when given an item in the sequence. - /// The input sequence. - /// The found element or None. - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before returning the result. - [] - val tryFindBack: predicate:('T -> bool) -> source:seq<'T> -> 'T option - - /// Returns the index of the first element in the sequence - /// that satisfies the given predicate. Return None if no such element exists. - /// - /// A function that evaluates to a Boolean when given an item in the sequence. - /// The input sequence. - /// - /// The found index or None. - /// - /// Thrown when the input sequence is null. - [] - val tryFindIndex : predicate:('T -> bool) -> source:seq<'T> -> int option - - /// Tries to find the nth element in the sequence. - /// Returns None if index is negative or the input sequence does not contain enough elements. - /// The index of element to retrieve. - /// The input sequence. - /// The nth element of the sequence or None. - /// Thrown when the input sequence is null. - [] - val tryItem: index:int -> source:seq<'T> -> 'T option - - /// Returns the index of the last element in the sequence - /// that satisfies the given predicate. Return None if no such element exists. - /// This function digests the whole initial sequence as soon as it is called. As a - /// result this function should not be used with large or infinite sequences. - /// A function that evaluates to a Boolean when given an item in the sequence. - /// The input sequence. - /// The found index or None. - /// Thrown when the input sequence is null. - /// This function consumes the whole input sequence before returning the result. - [] - val tryFindIndexBack : predicate:('T -> bool) -> source:seq<'T> -> int option - - /// Applies the given function to successive elements, returning the first - /// result where the function returns "Some(x)". - /// - /// A function that transforms items from the input sequence into options. - /// The input sequence. - /// - /// The chosen element or None. - /// - /// Thrown when the input sequence is null. - [] - val tryPick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U option - - /// Returns the transpose of the given sequence of sequences. - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. - /// The input sequence. - /// The transposed sequence. - /// Thrown when the input sequence is null. - [] - val transpose: source:seq<'Collection> -> seq> when 'Collection :> seq<'T> - - /// Returns a sequence that when enumerated returns at most N elements. - /// - /// The maximum number of items to enumerate. - /// The input sequence. - /// - /// The result sequence. - /// - /// Thrown when the input sequence is null. - [] - val truncate: count:int -> source:seq<'T> -> seq<'T> - - /// Returns a sequence that contains the elements generated by the given computation. - /// The given initial state argument is passed to the element generator. - /// For each IEnumerator elements in the stream are generated on-demand by applying the element - /// generator, until a None value is returned by the element generator. Each call to the element - /// generator returns a new residual state. - /// - /// The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq. - /// - /// The returned sequence may be passed between threads safely. However, - /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// - /// A function that takes in the current state and returns an option tuple of the next - /// element of the sequence and the next state value. - /// The initial state value. - /// - /// The result sequence. - [] - val unfold : generator:('State -> ('T * 'State) option) -> state:'State -> seq<'T> - - /// Returns a sequence that yields sliding windows containing elements drawn from the input - /// sequence. Each window is returned as a fresh array. - /// The number of elements in each window. - /// The input sequence. - /// The result sequence. - /// Thrown when the input sequence is null. - /// Thrown when windowSize is not positive. - [] - val windowed: windowSize:int -> source:seq<'T> -> seq<'T[]> - - /// Combines the two sequences into a list of pairs. The two sequences need not have equal lengths: - /// when one sequence is exhausted any remaining elements in the other - /// sequence are ignored. - /// - /// The first input sequence. - /// The second input sequence. - /// - /// The result sequence. - /// - /// Thrown when either of the input sequences is null. - [] - val zip: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2> - - /// Combines the three sequences into a list of triples. The sequences need not have equal lengths: - /// when one sequence is exhausted any remaining elements in the other - /// sequences are ignored. - /// - /// The first input sequence. - /// The second input sequence. - /// The third input sequence. - /// - /// The result sequence. - /// - /// Thrown when any of the input sequences is null. - [] - val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3> +open System +open System.Collections +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +/// Contains operations for working with values of type . +[] +[] +module Seq = + + /// Returns a new sequence that contains all pairings of elements from the first and second sequences. + /// + /// The first sequence. + /// The second sequence. + /// + /// The result sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + /// + /// ([1; 2], [3; 4]) ||> Seq.allPairs + /// + /// Evaluates to + /// + /// seq [(1, 3); (1, 4); (2, 3); (2, 4)] + /// + /// + [] + val allPairs: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2> + + /// Wraps the two given enumerations as a single concatenated + /// enumeration. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed + /// concurrently. + /// + /// The first sequence. + /// The second sequence. + /// + /// The result sequence. + /// + /// Thrown when either of the two provided sequences is + /// null. + /// + /// + /// + /// ([1; 2], [3; 4]) ||> Seq.append + /// + /// Evaluates to seq [1; 2; 3; 4] + /// + [] + val append: source1:seq<'T> -> source2:seq<'T> -> seq<'T> + + /// Returns the average of the elements in the sequence. + /// + /// The elements are averaged using the + operator, DivideByInt method and Zero property + /// associated with the element type. + /// + /// The input sequence. + /// + /// The average. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence has zero elements. + /// + /// + /// + /// [1.0; 2.0; 3.0] |> Seq.average + /// + /// Evaluates to 2.0 + /// + /// + /// + /// + /// [] |> Seq.average + /// + /// Throws ArgumentException + /// + [] + val inline average : source:seq<(^T)> -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) + and ^T : (static member DivideByInt : ^T * int -> ^T) + and ^T : (static member Zero : ^T) + + /// Returns the average of the results generated by applying the function to each element + /// of the sequence. + /// + /// The elements are averaged using the + operator, DivideByInt method and Zero property + /// associated with the generated type. + /// + /// A function applied to transform each element of the sequence. + /// The input sequence. + /// + /// The average. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence has zero elements. + /// + /// + /// + /// type Foo = { Bar: float } + /// + /// [{Bar = 2.0}; {Bar = 4.0}] |> Seq.averageBy (fun foo -> foo.Bar) + /// + /// Evaluates to 3.0 + /// + /// + /// + /// + /// type Foo = { Bar: float } + /// [] |> Seq.averageBy (fun foo -> foo.Bar) + /// + /// Throws ArgumentException + /// + [] + val inline averageBy : projection:('T -> ^U) -> source:seq<'T> -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) + and ^U : (static member DivideByInt : ^U * int -> ^U) + and ^U : (static member Zero : ^U) + + /// Returns a sequence that corresponds to a cached version of the input sequence. + /// + /// + /// The result sequence will have the same elements as the input sequence. The result + /// can be enumerated multiple times. The input sequence will be enumerated at most + /// once and only as far as is necessary. Caching a sequence is typically useful when repeatedly + /// evaluating items in the original sequence is computationally expensive or if + /// iterating the sequence causes side-effects that the user does not want to be + /// repeated multiple times. + /// + /// Enumeration of the result sequence is thread safe in the sense that multiple independent IEnumerator + /// values may be used simultaneously from different threads (accesses to + /// the internal lookaside table are thread safe). Each individual IEnumerator + /// is not typically thread safe and should not be accessed concurrently. + /// + /// Once enumeration of the input sequence has started, + /// it's enumerator will be kept live by this object until the enumeration has completed. + /// At that point, the enumerator will be disposed. + /// + /// The enumerator may be disposed and underlying cache storage released by + /// converting the returned sequence object to type IDisposable, and calling the Dispose method + /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will + /// be used. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// let fibSeq =(0, 1) |> Seq.unfold (fun (a,b) -> Some(a + b, (b, a + b))) + /// + /// let fibSeq3 = fibSeq |> Seq.take 3 |> Seq.cache + /// fibSeq3 + /// + /// Evaluates to seq [1; 2; 3], + /// and it will not do the calculation again when called. + /// + [] + val cache: source:seq<'T> -> seq<'T> + + /// Wraps a loosely-typed System.Collections sequence as a typed sequence. + /// + /// The use of this function usually requires a type annotation. + /// An incorrect type annotation may result in runtime type + /// errors. + /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// ([1; 2; 3] :> IEnumerable) |> Seq.cast<int> + /// + /// Evaluates to seq [1; 2; 3], explicitly typed as int seq + /// + [] + val cast: source:IEnumerable -> seq<'T> + + /// Applies the given function to each element of the list. Return + /// the list comprised of the results "x" for each element where + /// the function returns Some(x). + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not + /// be accessed concurrently. + /// + /// A function to transform items of type T into options of type U. + /// The input sequence of type T. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// [Some 1; None; Some 2] |> Seq.choose id + /// + /// Evaluates to seq [1; 2] + /// + /// + /// + /// + /// [1; 2; 3] |> Seq.choose (fun n -> if n % 2 = 0 then Some n else None) + /// + /// Evaluates to seq [2] + /// + [] + val choose: chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U> + + /// Divides the input sequence into chunks of size at most chunkSize. + /// + /// The maximum size of each chunk. + /// The input sequence. + /// + /// The sequence divided into chunks. + /// + /// Thrown when the input sequence is null. + /// Thrown when chunkSize is not positive. + /// + /// + /// + /// [1; 2; 3] |> Seq.chunkBySize 2 + /// + /// Evaluates to seq [[|1; 2|]; [|3|]] + /// + /// + /// + /// + /// [1; 2; 3] |> Seq.chunkBySize -2 + /// + /// Throws ArgumentException + /// + [] + val chunkBySize: chunkSize:int -> source:seq<'T> -> seq<'T[]> + + /// Applies the given function to each element of the sequence and concatenates all the + /// results. + /// + /// Remember sequence is lazy, effects are delayed until it is enumerated. + /// + /// A function to transform elements of the input sequence into the sequences + /// that will then be concatenated. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// type Foo = { Bar: int seq } + /// [[{Bar = [1; 2]}; {Bar = [3; 4]}] |> Seq.collect (fun foo -> foo.Bar) + /// + /// Evaluates to seq [1; 2; 3; 4] + /// + /// + /// + /// + /// [[1; 2]; [3; 4]] |> Seq.collect id + /// + /// Evaluates to seq [1; 2; 3; 4] + /// + [] + val collect: mapping:('T -> 'Collection) -> source:seq<'T> -> seq<'U> when 'Collection :> seq<'U> + + /// Compares two sequences using the given comparison function, element by element. + /// + /// A function that takes an element from each sequence and returns an int. + /// If it evaluates to a non-zero value iteration is stopped and that value is returned. + /// The first input sequence. + /// The second input sequence. + /// + /// Returns the first non-zero result from the comparison function. If the end of a sequence + /// is reached it returns a -1 if the first sequence is shorter and a 1 if the second sequence + /// is shorter. + /// + /// Thrown when either of the input sequences + /// is null. + /// + /// + /// + /// ([1; 2], [1; 2]) ||> Seq.compareWith (fun a b -> a.CompareTo(b)) + /// + /// Evaluates to 0 + /// + /// + /// + /// + /// ([1; 2], [1; 3]) ||> Seq.compareWith (fun a b -> a.CompareTo(b)) + /// + /// Evaluates to -1 + /// + /// + /// + /// + /// ([1; 3], [1; 2]) ||> Seq.compareWith (fun a b -> a.CompareTo(b)) + /// + /// Evaluates to 1 + /// + /// + /// + /// + /// ([1; 2], [1]) ||> Seq.compareWith (fun a b -> a.CompareTo(b)) + /// + /// Evaluates to 1 + /// + /// + /// + /// + /// ([1], [1; 2]) ||> Seq.compareWith (fun a b -> a.CompareTo(b)) + /// + /// Evaluates to -1 + /// + [] + val compareWith: comparer:('T -> 'T -> int) -> source1:seq<'T> -> source2:seq<'T> -> int + + /// Combines the given enumeration-of-enumerations as a single concatenated + /// enumeration. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// The input enumeration-of-enumerations. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// [[1; 2]; [3]; [4; 5]] |> Seq.concat + /// + /// Evaluates to seq [1; 2; 3; 4; 5] + /// + [] + val concat: sources:seq<'Collection> -> seq<'T> when 'Collection :> seq<'T> + + /// Tests if the sequence contains the specified element. + /// + /// The value to locate in the input sequence. + /// The input sequence. + /// + /// True if the input sequence contains the specified element; false otherwise. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// [1; 2] |> Seq.contains 2 // evaluates to true + /// [1; 2] |> Seq.contains 5 // evaluates to false + /// + /// + [] + val inline contains: value:'T -> source:seq<'T> -> bool when 'T : equality + + /// Applies a key-generating function to each element of a sequence and returns a sequence yielding unique + /// keys and their number of occurrences in the original sequence. + /// + /// Note that this function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// sequence. + /// + /// A function transforming each item of the input sequence into a key to be + /// compared against the others. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// type Foo = { Bar: string } + /// + /// [{Bar = "a"}; {Bar = "b"}; {Bar = "a"}] + /// |> Seq.countBy (fun foo -> foo.Bar) + /// + /// Evaluates to seq [("a", 2); ("b", 1)] + /// + [] + val countBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * int> when 'Key : equality + + /// Returns a sequence that is built from the given delayed specification of a + /// sequence. + /// + /// The input function is evaluated each time an IEnumerator for the sequence + /// is requested. + /// + /// The generating function for the sequence. + /// The result sequence. + /// + /// + /// + /// Seq.delay (fun () -> Seq.ofList [1; 2; 3]) + /// + /// Evaluates to seq [1; 2; 3], executing + /// the generator function every time is consumed. + /// + [] + val delay: generator:(unit -> seq<'T>) -> seq<'T> + + /// Returns a sequence that contains no duplicate entries according to generic hash and + /// equality comparisons on the entries. + /// If an element occurs multiple times in the sequence then the later occurrences are discarded. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// [1; 1; 2; 3] |> Seq.distinct + /// + /// Evaluates to seq [1; 2; 3] + /// + [] + val distinct: source:seq<'T> -> seq<'T> when 'T : equality + + /// Returns a sequence that contains no duplicate entries according to the + /// generic hash and equality comparisons on the keys returned by the given key-generating function. + /// If an element occurs multiple times in the sequence then the later occurrences are discarded. + /// + /// A function transforming the sequence items into comparable keys. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + /// + /// [{Bar = 1 };{Bar = 1}; {Bar = 2}; {Bar = 3}] + /// |> Seq.distinctBy (fun foo -> foo.Bar) + /// + /// Evaluates to seq [{ Bar = 1 }; { Bar = 2 }; { Bar = 3 }] + /// + [] + val distinctBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : equality + + /// Splits the input sequence into at most count chunks. + /// This function returns a sequence that digests the whole initial sequence as soon as that + /// sequence is iterated. As a result this function should not be used with large or infinite sequences. + /// The maximum number of chunks. + /// The input sequence. + /// + /// The sequence split into chunks. + /// + /// Thrown when the input sequence is null. + /// Thrown when count is not positive. + /// + /// This function consumes the whole input sequence before yielding the first element of the result sequence. + /// + /// + [] + val splitInto: count:int -> source:seq<'T> -> seq<'T[]> + + /// Creates an empty sequence. + /// + /// An empty sequence. + /// + /// + [] + [] + val empty<'T> : seq<'T> + + /// Returns a new sequence with the distinct elements of the second sequence which do not appear in the first sequence, + /// using generic hash and equality comparisons to compare values. + /// + /// Note that this function returns a sequence that digests the whole of the first input sequence as soon as + /// the result sequence is iterated. As a result this function should not be used with + /// large or infinite sequences in the first parameter. The function makes no assumption on the ordering of the first input + /// sequence. + /// + /// A sequence whose elements that also occur in the second sequence will cause those elements to be + /// removed from the returned sequence. + /// A sequence whose elements that are not also in first will be returned. + /// + /// A sequence that contains the set difference of the elements of two sequences. + /// + /// Thrown when either of the two input sequences is null. + /// + /// + [] + val except: itemsToExclude:seq<'T> -> source:seq<'T> -> seq<'T> when 'T : equality + + /// Tests if any element of the sequence satisfies the given predicate. + /// + /// The predicate is applied to the elements of the input sequence. If any application + /// returns true then the overall result is true and no further elements are tested. + /// Otherwise, false is returned. + /// + /// A function to test each item of the input sequence. + /// The input sequence. + /// + /// True if any result from the predicate is true; false otherwise. + /// + /// Thrown when the input sequence is null. + [] + val exists: predicate:('T -> bool) -> source:seq<'T> -> bool + + /// Tests if any pair of corresponding elements of the input sequences satisfies the given predicate. + /// + /// The predicate is applied to matching elements in the two sequences up to the lesser of the + /// two lengths of the collections. If any application returns true then the overall result is + /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. + /// + /// A function to test each pair of items from the input sequences. + /// The first input sequence. + /// The second input sequence. + /// + /// True if any result from the predicate is true; false otherwise. + /// + /// Thrown when either of the two input sequences is null. + /// + /// + [] + val exists2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns "true". This is a synonym for Seq.where. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// Remember sequence is lazy, effects are delayed until it is enumerated. + /// + /// A function to test whether each item in the input sequence should be included in the output. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val filter: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns "true". + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// Remember sequence is lazy, effects are delayed until it is enumerated. + /// + /// A synonym for Seq.filter. + /// + /// A function to test whether each item in the input sequence should be included in the output. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val where: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> + + /// Returns the first element for which the given function returns True. + /// + /// A function to test whether an item in the sequence should be returned. + /// The input sequence. + /// + /// The first element for which the predicate returns True. + /// + /// Thrown if no element returns true when + /// evaluated by the predicate + /// Thrown when the input sequence is null + /// + /// + [] + val find: predicate:('T -> bool) -> source:seq<'T> -> 'T + + /// Returns the last element for which the given function returns True. + /// + /// This function digests the whole initial sequence as soon as it is called. As a + /// result this function should not be used with large or infinite sequences. + /// A function to test whether an item in the sequence should be returned. + /// The input sequence. + /// + /// The last element for which the predicate returns True. + /// Thrown if no element returns true when + /// evaluated by the predicate + /// Thrown when the input sequence is null + /// This function consumes the whole input sequence before returning the result. + /// + /// + [] + val findBack: predicate:('T -> bool) -> source:seq<'T> -> 'T + + /// Returns the index of the first element for which the given function returns True. + /// + /// A function to test whether the index of a particular element should be returned. + /// The input sequence. + /// + /// The index of the first element for which the predicate returns True. + /// + /// Thrown if no element returns true when + /// evaluated by the predicate + /// Thrown when the input sequence is null + /// + /// + [] + val findIndex: predicate:('T -> bool) -> source:seq<'T> -> int + + /// Returns the index of the last element for which the given function returns True. + /// + /// This function digests the whole initial sequence as soon as it is called. As a + /// result this function should not be used with large or infinite sequences. + /// + /// A function to test whether the index of a particular element should be returned. + /// The input sequence. + /// + /// The index of the last element for which the predicate returns True. + /// + /// Thrown if no element returns true when + /// evaluated by the predicate + /// Thrown when the input sequence is null + /// + /// + [] + val findIndexBack: predicate:('T -> bool) -> source:seq<'T> -> int + + /// Applies a function to each element of the collection, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN + /// then computes f (... (f s i0)...) iN + /// + /// A function that updates the state with each element from the sequence. + /// The initial state. + /// The input sequence. + /// + /// The state object after the folding function is applied to each element of the sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State + + /// Applies a function to corresponding elements of two collections, threading an accumulator argument + /// through the computation. + /// + /// The two sequences need not have equal lengths: + /// when one sequence is exhausted any remaining elements in the other sequence are ignored. + /// If the input function is f and the elements are i0...iN and j0...jN + /// then computes f (... (f s i0 j0)...) iN jN. + /// + /// The function to update the state given the input elements. + /// The initial state. + /// The first input sequence. + /// The second input sequence. + /// + /// The final state value. + /// Thrown when the either of the input sequences is null. + /// + /// + [] + val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> source1:seq<'T1> -> source2:seq<'T2> -> 'State + + /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN + /// then computes f i0 (... (f iN s)...) + /// + /// The function to update the state given the input elements. + /// The input sequence. + /// The initial state. + /// + /// The state object after the folding function is applied to each element of the sequence. + /// Thrown when the input sequence is null. + /// + /// This function consumes the whole input sequence before returning the result. + /// + /// + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> 'State + + /// Applies a function to corresponding elements of two collections, starting from the end of the shorter collection, + /// threading an accumulator argument through the computation. The two sequences need not have equal lengths. + /// If the input function is f and the elements are i0...iN and j0...jM, N < M + /// then computes f i0 j0 (... (f iN jN s)...). + /// + /// The function to update the state given the input elements. + /// The first input sequence. + /// The second input sequence. + /// The initial state. + /// + /// The final state value. + /// + /// Thrown when the either of the input sequences is null. + /// + /// + [] + val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> source1:seq<'T1> -> source2:seq<'T2> -> state:'State -> 'State + + /// Tests if all elements of the sequence satisfy the given predicate. + /// + /// The predicate is applied to the elements of the input sequence. If any application + /// returns false then the overall result is false and no further elements are tested. + /// Otherwise, true is returned. + /// + /// A function to test an element of the input sequence. + /// The input sequence. + /// + /// True if every element of the sequence satisfies the predicate; false otherwise. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val forall: predicate:('T -> bool) -> source:seq<'T> -> bool + + /// Tests the all pairs of elements drawn from the two sequences satisfy the + /// given predicate. If one sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. + /// + /// A function to test pairs of elements from the input sequences. + /// The first input sequence. + /// The second input sequence. + /// + /// True if all pairs satisfy the predicate; false otherwise. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val forall2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool + + /// Applies a key-generating function to each element of a sequence and yields a sequence of + /// unique keys. Each unique key contains a sequence of all elements that match + /// to this key. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// sequence. + /// + /// A function that transforms an element of the sequence into a comparable key. + /// The input sequence. + /// + /// The result sequence. + /// + /// + [] + val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> when 'Key : equality + + /// Returns the first element of the sequence. + /// + /// The input sequence. + /// + /// The first element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input does not have any elements. + /// + /// + [] + val head: source:seq<'T> -> 'T + + /// Returns the first element of the sequence, or None if the sequence is empty. + /// + /// The input sequence. + /// + /// The first element of the sequence or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryHead: source:seq<'T> -> 'T option + + /// Returns the last element of the sequence. + /// + /// The input sequence. + /// + /// The last element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input does not have any elements. + /// + /// + [] + val last: source:seq<'T> -> 'T + + /// Returns the last element of the sequence. + /// Return None if no such element exists. + /// + /// The input sequence. + /// + /// The last element of the sequence or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryLast: source:seq<'T> -> 'T option + + /// Returns the only element of the sequence. + /// + /// The input sequence. + /// + /// The only element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input does not have precisely one element. + /// + /// + [] + val exactlyOne: source:seq<'T> -> 'T + + /// Returns the only element of the sequence or None if sequence is empty or contains more than one element. + /// + /// The input sequence. + /// + /// The only element of the sequence or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryExactlyOne: source:seq<'T> -> 'T option + + /// Returns true if the sequence contains no elements, false otherwise. + /// + /// The input sequence. + /// + /// True if the sequence is empty; false otherwise. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val isEmpty: source:seq<'T> -> bool + + /// Builds a new collection whose elements are the corresponding elements of the input collection + /// paired with the integer index (from 0) of each element. + /// + /// The input sequence. + /// + /// The result sequence. + /// Thrown when the input sequence is null. + /// + /// + [] + val indexed: source:seq<'T> -> seq + + /// Generates a new sequence which, when iterated, will return successive + /// elements by calling the given function, up to the given count. Each element is saved after its + /// initialization. The function is passed the index of the item being + /// generated. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// The maximum number of items to generate for the sequence. + /// A function that generates an item in the sequence from a given index. + /// + /// The result sequence. + /// + /// Thrown when count is negative. + /// + /// + [] + val init: count:int -> initializer:(int -> 'T) -> seq<'T> + + /// Generates a new sequence which, when iterated, will return successive + /// elements by calling the given function. The results of calling the function + /// will not be saved, that is the function will be reapplied as necessary to + /// regenerate the elements. The function is passed the index of the item being + /// generated. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// Iteration can continue up to Int32.MaxValue. + /// + /// A function that generates an item in the sequence from a given index. + /// + /// The result sequence. + /// + /// + [] + val initInfinite: initializer:(int -> 'T) -> seq<'T> + + /// Computes the element at the specified index in the collection. + /// + /// The index of the element to retrieve. + /// The input sequence. + /// + /// The element at the specified index of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the index is negative or the input sequence does not contain enough elements. + /// + /// + [] + val item: index:int -> source:seq<'T> -> 'T + + /// Applies the given function to each element of the collection. + /// + /// A function to apply to each element of the sequence. + /// The input sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val iter: action:('T -> unit) -> source:seq<'T> -> unit + + /// Applies the given function to each element of the collection. The integer passed to the + /// function indicates the index of element. + /// + /// A function to apply to each element of the sequence that can also access the current index. + /// The input sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val iteri: action:(int -> 'T -> unit) -> source:seq<'T> -> unit + + /// Applies the given function to two collections simultaneously. If one sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. + /// + /// A function to apply to each pair of elements from the input sequences. + /// The first input sequence. + /// The second input sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val iter2: action:('T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit + + /// Applies the given function to two collections simultaneously. If one sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. The integer passed to the + /// function indicates the index of element. + /// + /// A function to apply to each pair of elements from the input sequences along with their index. + /// The first input sequence. + /// The second input sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit + + /// Returns the length of the sequence + /// + /// The input sequence. + /// + /// The length of the sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val length: source:seq<'T> -> int + + /// Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The given function will be applied + /// as elements are demanded using the MoveNext method on enumerators retrieved from the + /// object. + /// + /// The returned sequence may be passed between threads safely. However, + /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. + /// + /// A function to transform items from the input sequence. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U> + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. + /// + /// A function to transform pairs of items from the input sequences. + /// The first input sequence. + /// The second input sequence. + /// + /// The result sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val map2: mapping:('T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U> + + /// Combines map and fold. Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The function is also used to accumulate a final value. + /// + /// This function digests the whole initial sequence as soon as it is called. As a result this function should + /// not be used with large or infinite sequences. + /// + /// The function to transform elements from the input collection and accumulate the final value. + /// The initial state. + /// The input collection. + /// + /// Thrown when the input collection is null. + /// + /// The collection of transformed elements, and the final accumulated value. + /// + /// + [] + val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> source:seq<'T> -> seq<'Result> * 'State + + /// Combines map and foldBack. Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The function is also used to accumulate a final value. + /// + /// This function digests the whole initial sequence as soon as it is called. As a result this function should + /// not be used with large or infinite sequences. + /// + /// The function to transform elements from the input collection and accumulate the final value. + /// The input collection. + /// The initial state. + /// + /// Thrown when the input collection is null. + /// + /// The collection of transformed elements, and the final accumulated value. + /// + /// + [] + val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> source:seq<'T> -> state:'State -> seq<'Result> * 'State + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding triples of elements from the three sequences. If one input sequence if shorter than + /// the others then the remaining elements of the longer sequences are ignored. + /// + /// The function to transform triples of elements from the input sequences. + /// The first input sequence. + /// The second input sequence. + /// The third input sequence. + /// + /// The result sequence. + /// + /// Thrown when any of the input sequences is null. + /// + /// + [] + val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'U> + + /// Builds a new collection whose elements are the results of applying the given function + /// to each of the elements of the collection. The integer index passed to the + /// function indicates the index (from 0) of element being transformed. + /// + /// A function to transform items from the input sequence that also supplies the current index. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val mapi: mapping:(int -> 'T -> 'U) -> source:seq<'T> -> seq<'U> + + /// Builds a new collection whose elements are the results of applying the given function + /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than + /// the other then the remaining elements of the longer sequence are ignored. The integer index passed to the + /// function indicates the index (from 0) of element being transformed. + /// + /// A function to transform pairs of items from the input sequences that also supplies the current index. + /// The first input sequence. + /// The second input sequence. + /// + /// The result sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U> + + /// Returns the greatest of all elements of the sequence, compared via Operators.max + /// + /// The input sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// The largest element of the sequence. + /// + /// + [] + val inline max : source:seq<'T> -> 'T when 'T : comparison + + /// Returns the greatest of all elements of the sequence, compared via Operators.max on the function result. + /// + /// A function to transform items from the input sequence into comparable keys. + /// The input sequence. + /// + /// The largest element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// + [] + val inline maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison + + /// Returns the lowest of all elements of the sequence, compared via Operators.min. + /// + /// The input sequence. + /// + /// The smallest element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// + [] + val inline min : source:seq<'T> -> 'T when 'T : comparison + + /// Returns the lowest of all elements of the sequence, compared via Operators.min on the function result. + /// + /// A function to transform items from the input sequence into comparable keys. + /// The input sequence. + /// + /// The smallest element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// + [] + val inline minBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison + + /// Computes the nth element in the collection. + /// + /// The index of element to retrieve. + /// The input sequence. + /// + /// The nth element of the sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the index is negative or the input sequence does not contain enough elements. + /// + /// + [] + [] + val nth: index:int -> source:seq<'T> -> 'T + + /// + /// + [] + /// Views the given array as a sequence. + /// + /// The input array. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + val ofArray: source:'T[] -> seq<'T> + + /// + /// + [] + /// Views the given list as a sequence. + /// + /// The input list. + /// + /// The result sequence. + val ofList: source:'T list -> seq<'T> + + /// Returns a sequence of each element in the input sequence and its predecessor, with the + /// exception of the first element which is only returned as the predecessor of the second element. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val pairwise: source:seq<'T> -> seq<'T * 'T> + + /// Returns a sequence with all elements permuted according to the + /// specified permutation. + /// + /// This function consumes the whole input sequence before yielding the first element of the result sequence. + /// + /// The function that maps input indices to output indices. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when indexMap does not produce a valid permutation. + /// + /// + [] + val permute: indexMap:(int -> int) -> source:seq<'T> -> seq<'T> + + /// Applies the given function to successive elements, returning the first + /// x where the function returns "Some(x)". + /// + /// A function to transform each item of the input sequence into an option of the output type. + /// The input sequence. + /// + /// The selected element. + /// + /// Thrown when the input sequence is null. + /// Thrown when every item of the sequence + /// evaluates to None when the given function is applied. + /// + /// + [] + val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U + + /// Builds a new sequence object that delegates to the given sequence object. This ensures + /// the original sequence cannot be rediscovered and mutated by a type cast. For example, + /// if given an array the returned sequence will return the elements of the array, but + /// you cannot cast the returned sequence object to an array. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val readonly : source:seq<'T> -> seq<'T> + + /// Applies a function to each element of the sequence, threading an accumulator argument + /// through the computation. Begin by applying the function to the first two elements. + /// Then feed this result into the function along with the third element and so on. + /// Return the final result. + /// + /// A function that takes in the current accumulated result and the next + /// element of the sequence to produce the next accumulated result. + /// The input sequence. + /// + /// The final result of the reduction function. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// + [] + val reduce: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T + + /// Creates a sequence by replicating the given initial value. + /// + /// The number of elements to replicate. + /// The value to replicate + /// + /// The generated sequence. + /// + /// + [] + val replicate: count:int -> initial:'T -> seq<'T> + + /// Applies a function to each element of the sequence, starting from the end, threading an accumulator argument + /// through the computation. If the input function is f and the elements are i0...iN + /// then computes f i0 (...(f iN-1 iN)). + /// + /// A function that takes in the next-to-last element of the sequence and the + /// current accumulated result to produce the next accumulated result. + /// The input sequence. + /// + /// The final result of the reductions. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// This function consumes the whole input sequence before returning the result. + /// + /// + [] + val reduceBack: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T + + /// Returns a new sequence with the elements in reverse order. + /// + /// The input sequence. + /// + /// The reversed sequence. + /// + /// Thrown when the input sequence is null. + /// + /// This function consumes the whole input sequence before yielding the first element of the reversed sequence. + /// + /// + [] + val rev: source:seq<'T> -> seq<'T> + + /// Like fold, but computes on-demand and returns the sequence of intermediary and final results. + /// + /// A function that updates the state with each element from the sequence. + /// The initial state. + /// The input sequence. + /// + /// The resulting sequence of computed states. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> seq<'State> + + /// Like foldBack, but returns the sequence of intermediary and final results. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as that + /// sequence is iterated. As a result this function should not be used with large or infinite sequences. + /// + /// + /// A function that updates the state with each element from the sequence. + /// The input sequence. + /// The initial state. + /// + /// The resulting sequence of computed states. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> seq<'State> + + /// Returns a sequence that yields one item only. + /// + /// The input item. + /// + /// The result sequence of one item. + /// + /// + [] + val singleton: value:'T -> seq<'T> + + /// Returns a sequence that skips N elements of the underlying sequence and then yields the + /// remaining elements of the sequence. + /// + /// The number of items to skip. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when count exceeds the number of elements + /// in the sequence. + /// + /// + [] + val skip: count:int -> source:seq<'T> -> seq<'T> + + /// Returns a sequence that, when iterated, skips elements of the underlying sequence while the + /// given predicate returns True, and then yields the remaining elements of the sequence. + /// + /// A function that evaluates an element of the sequence to a boolean value. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val skipWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> + + /// Yields a sequence ordered by keys. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. + /// + /// The function makes no assumption on the ordering of the original + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val sort : source:seq<'T> -> seq<'T> when 'T : comparison + + /// Yields a sequence ordered using the given comparison function. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. + /// + /// The function makes no assumption on the ordering of the original + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// + /// The function to compare the collection elements. + /// The input sequence. + /// + /// The result sequence. + /// + /// + [] + val sortWith : comparer:('T -> 'T -> int) -> source:seq<'T> -> seq<'T> + + /// Applies a key-generating function to each element of a sequence and yield a sequence ordered + /// by keys. The keys are compared using generic comparison as implemented by . + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. + /// + /// The function makes no assumption on the ordering of the original + /// sequence and uses a stable sort, that is the original order of equal elements is preserved. + /// + /// A function to transform items of the input sequence into comparable keys. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison + + /// Yields a sequence ordered descending by keys. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// sequence. + /// + /// This is a stable sort, that is the original order of equal elements is preserved. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val inline sortDescending : source:seq<'T> -> seq<'T> when 'T : comparison + + /// Applies a key-generating function to each element of a sequence and yield a sequence ordered + /// descending by keys. The keys are compared using generic comparison as implemented by . + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// sequence. + /// + /// This is a stable sort, that is the original order of equal elements is preserved. + /// + /// A function to transform items of the input sequence into comparable keys. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val inline sortByDescending : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison + + /// Returns the sum of the elements in the sequence. + /// + /// The elements are summed using the + operator and Zero property associated with the generated type. + /// + /// The input sequence. + /// + /// The computed sum. + /// + /// + [] + val inline sum : source:seq<(^T)> -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) + and ^T : (static member Zero : ^T) + + /// Returns the sum of the results generated by applying the function to each element of the sequence. + /// + /// The generated elements are summed using the + operator and Zero property associated with the generated type. + /// + /// A function to transform items from the input sequence into the type that will be summed. + /// The input sequence. + /// + /// The computed sum. + /// + /// + [] + val inline sumBy : projection:('T -> ^U) -> source:seq<'T> -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) + and ^U : (static member Zero : ^U) + + /// Returns a sequence that skips 1 element of the underlying sequence and then yields the + /// remaining elements of the sequence. + /// + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// + /// + [] + val tail: source:seq<'T> -> seq<'T> + + /// Returns the first N elements of the sequence. + /// + /// Throws InvalidOperationException + /// if the count exceeds the number of elements in the sequence. Seq.truncate + /// returns as many items as the sequence contains instead of throwing an exception. + /// + /// The number of items to take. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// Thrown when the input sequence is empty. + /// Thrown when count exceeds the number of elements + /// in the sequence. + /// + /// + [] + val take: count:int -> source:seq<'T> -> seq<'T> + + /// Returns a sequence that, when iterated, yields elements of the underlying sequence while the + /// given predicate returns True, and then returns no further elements. + /// + /// A function that evaluates to false when no more items should be returned. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val takeWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> + + /// Builds an array from the given collection. + /// + /// The input sequence. + /// + /// The result array. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val toArray: source:seq<'T> -> 'T[] + + /// Builds a list from the given collection. + /// + /// The input sequence. + /// + /// The result list. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val toList: source:seq<'T> -> 'T list + + /// Returns the first element for which the given function returns True. + /// Return None if no such element exists. + /// + /// A function that evaluates to a Boolean when given an item in the sequence. + /// The input sequence. + /// + /// The found element or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryFind: predicate:('T -> bool) -> source:seq<'T> -> 'T option + + /// Returns the last element for which the given function returns True. + /// Return None if no such element exists. + /// + /// This function digests the whole initial sequence as soon as it is called. As a + /// result this function should not be used with large or infinite sequences. + /// + /// A function that evaluates to a Boolean when given an item in the sequence. + /// The input sequence. + /// + /// The found element or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryFindBack: predicate:('T -> bool) -> source:seq<'T> -> 'T option + + /// Returns the index of the first element in the sequence + /// that satisfies the given predicate. Return None if no such element exists. + /// + /// A function that evaluates to a Boolean when given an item in the sequence. + /// The input sequence. + /// + /// The found index or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryFindIndex : predicate:('T -> bool) -> source:seq<'T> -> int option + + /// Tries to find the nth element in the sequence. + /// Returns None if index is negative or the input sequence does not contain enough elements. + /// + /// The index of element to retrieve. + /// The input sequence. + /// + /// The nth element of the sequence or None. + /// Thrown when the input sequence is null. + /// + /// + [] + val tryItem: index:int -> source:seq<'T> -> 'T option + + /// Returns the index of the last element in the sequence + /// that satisfies the given predicate. Return None if no such element exists. + /// + /// This function digests the whole initial sequence as soon as it is called. As a + /// result this function should not be used with large or infinite sequences. + /// + /// A function that evaluates to a Boolean when given an item in the sequence. + /// The input sequence. + /// + /// The found index or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryFindIndexBack : predicate:('T -> bool) -> source:seq<'T> -> int option + + /// Applies the given function to successive elements, returning the first + /// result where the function returns "Some(x)". + /// + /// A function that transforms items from the input sequence into options. + /// The input sequence. + /// + /// The chosen element or None. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val tryPick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U option + + /// Returns the transpose of the given sequence of sequences. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. + /// + /// The input sequence. + /// + /// The transposed sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val transpose: source:seq<'Collection> -> seq> when 'Collection :> seq<'T> + + /// Returns a sequence that when enumerated returns at most N elements. + /// + /// The maximum number of items to enumerate. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when the input sequence is null. + /// + /// + [] + val truncate: count:int -> source:seq<'T> -> seq<'T> + + /// Returns a sequence that contains the elements generated by the given computation. + /// The given initial state argument is passed to the element generator. + /// For each IEnumerator elements in the stream are generated on-demand by applying the element + /// generator, until a None value is returned by the element generator. Each call to the element + /// generator returns a new residual state. + /// + /// The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq. + /// + /// A function that takes in the current state and returns an option tuple of the next + /// element of the sequence and the next state value. + /// The initial state value. + /// + /// The result sequence. + /// + /// + [] + val unfold : generator:('State -> ('T * 'State) option) -> state:'State -> seq<'T> + + /// Returns a sequence that yields sliding windows containing elements drawn from the input + /// sequence. Each window is returned as a fresh array. + /// + /// The number of elements in each window. + /// The input sequence. + /// + /// The result sequence. + /// Thrown when the input sequence is null. + /// Thrown when windowSize is not positive. + /// + /// + [] + val windowed: windowSize:int -> source:seq<'T> -> seq<'T[]> + + /// Combines the two sequences into a list of pairs. The two sequences need not have equal lengths: + /// when one sequence is exhausted any remaining elements in the other + /// sequence are ignored. + /// + /// The first input sequence. + /// The second input sequence. + /// + /// The result sequence. + /// + /// Thrown when either of the input sequences is null. + /// + /// + [] + val zip: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2> + + /// Combines the three sequences into a list of triples. The sequences need not have equal lengths: + /// when one sequence is exhausted any remaining elements in the other + /// sequences are ignored. + /// + /// The first input sequence. + /// The second input sequence. + /// The third input sequence. + /// + /// The result sequence. + /// + /// Thrown when any of the input sequences is null. + /// + /// + [] + val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3> + + /// Return a new sequence with the item at a given index removed. + /// + /// The index of the item to be removed. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// seq { 0; 1; 2 } |> Seq.removeAt 1 // evaluates to seq { 0; 2 } + /// + /// + [] + val removeAt: index: int -> source: seq<'T> -> seq<'T> + + /// Return a new sequence with the number of items starting at a given index removed. + /// + /// The index of the item to be removed. + /// The number of items to remove. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when index is outside 0..source.Length - count + /// + /// + /// + /// seq { 0; 1; 2; 3 } |> Seq.removeManyAt 1 2 // evaluates to seq { 0; 3 } + /// + /// + [] + val removeManyAt: index: int -> count: int -> source: seq<'T> -> seq<'T> + + /// Return a new sequence with the item at a given index set to the new value. + /// + /// The index of the item to be replaced. + /// The new value. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when index is outside 0..source.Length - 1 + /// + /// + /// + /// seq { 0; 1; 2 } |> Seq.updateAt 1 9 // evaluates to seq { 0; 9; 2 } + /// + /// + [] + val updateAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T> + + /// Return a new sequence with a new item inserted before the given index. + /// + /// The index where the item should be inserted. + /// The value to insert. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// seq { 0; 1; 2 } |> Seq.insertAt 1 9 // evaluates to seq { 0; 9; 1; 2 } + /// + /// + [] + val insertAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T> + + /// Return a new sequence with new items inserted before the given index. + /// + /// The index where the items should be inserted. + /// The values to insert. + /// The input sequence. + /// + /// The result sequence. + /// + /// Thrown when index is below 0 or greater than source.Length. + /// + /// + /// + /// seq { 0; 1; 2 } |> Seq.insertManyAt 1 [8; 9] // evaluates to seq { 0; 8; 9; 1; 2 } + /// + /// + [] + val insertManyAt: index: int -> values: seq<'T> -> source: seq<'T> -> seq<'T> diff --git a/src/fsharp/FSharp.Core/seqcore.fs b/src/fsharp/FSharp.Core/seqcore.fs index bc54d01e670..963eb4117b1 100644 --- a/src/fsharp/FSharp.Core/seqcore.fs +++ b/src/fsharp/FSharp.Core/seqcore.fs @@ -15,124 +15,157 @@ namespace Microsoft.FSharp.Collections module internal IEnumerator = - let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) - let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted))) - let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) - let check started = if not started then notStarted() - let dispose (r : System.IDisposable) = r.Dispose() - - let cast (e : IEnumerator) : IEnumerator<'T> = - { new IEnumerator<'T> with - member __.Current = unbox<'T> e.Current - interface IEnumerator with - member __.Current = unbox<'T> e.Current :> obj - member __.MoveNext() = e.MoveNext() - member __.Reset() = noReset() + let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) + let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted))) + let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) + let check started = if not started then notStarted() + let dispose (r : System.IDisposable) = r.Dispose() + + let cast (e : IEnumerator) : IEnumerator<'T> = + { new IEnumerator<'T> with + member _.Current = unbox<'T> e.Current + + interface IEnumerator with + member _.Current = unbox<'T> e.Current :> obj + member _.MoveNext() = e.MoveNext() + member _.Reset() = noReset() + + interface System.IDisposable with + member _.Dispose() = + match e with + | :? System.IDisposable as e -> e.Dispose() + | _ -> () } + + /// A concrete implementation of an enumerator that returns no values + [] + type EmptyEnumerator<'T>() = + let mutable started = false + interface IEnumerator<'T> with + member _.Current = + check started + (alreadyFinished() : 'T) + + interface System.Collections.IEnumerator with + member _.Current = + check started + (alreadyFinished() : obj) + + member _.MoveNext() = + if not started then started <- true + false + + member _.Reset() = noReset() + interface System.IDisposable with - member __.Dispose() = - match e with - | :? System.IDisposable as e -> e.Dispose() - | _ -> () } - - /// A concrete implementation of an enumerator that returns no values - [] - type EmptyEnumerator<'T>() = - let mutable started = false - interface IEnumerator<'T> with - member __.Current = - check started - (alreadyFinished() : 'T) - - interface System.Collections.IEnumerator with - member __.Current = - check started - (alreadyFinished() : obj) - member __.MoveNext() = - if not started then started <- true - false - member __.Reset() = noReset() - interface System.IDisposable with - member __.Dispose() = () + member _.Dispose() = () - let Empty<'T> () = (new EmptyEnumerator<'T>() :> IEnumerator<'T>) + let Empty<'T> () = (new EmptyEnumerator<'T>() :> IEnumerator<'T>) + + [] + type EmptyEnumerable<'T> = - [] - type EmptyEnumerable<'T> = | EmptyEnumerable + interface IEnumerable<'T> with - member __.GetEnumerator() = Empty<'T>() + member _.GetEnumerator() = Empty<'T>() + interface IEnumerable with - member __.GetEnumerator() = (Empty<'T>() :> IEnumerator) - - let readAndClear r = - lock r (fun () -> match !r with None -> None | Some _ as res -> r := None; res) - - let generateWhileSome openf compute closef : IEnumerator<'U> = - let mutable started = false - let mutable curr = None - let state = ref (Some(openf())) - let getCurr() = - check started - match curr with None -> alreadyFinished() | Some x -> x - let start() = if not started then (started <- true) - - let dispose() = readAndClear state |> Option.iter closef - let finish() = try dispose() finally curr <- None - { new IEnumerator<'U> with - member __.Current = getCurr() - interface IEnumerator with - member __.Current = box (getCurr()) - member __.MoveNext() = - start() - match !state with - | None -> false (* we started, then reached the end, then got another MoveNext *) - | Some s -> - match (try compute s with e -> finish(); reraise()) with - | None -> finish(); false - | Some _ as x -> curr <- x; true - - member __.Reset() = noReset() - interface System.IDisposable with - member __.Dispose() = dispose() } - - [] - type Singleton<'T>(v:'T) = - let mutable started = false - interface IEnumerator<'T> with - member __.Current = v - interface IEnumerator with - member __.Current = box v - member __.MoveNext() = if started then false else (started <- true; true) - member __.Reset() = noReset() - interface System.IDisposable with - member __.Dispose() = () - - let Singleton x = (new Singleton<'T>(x) :> IEnumerator<'T>) - - let EnumerateThenFinally f (e : IEnumerator<'T>) = - { new IEnumerator<'T> with - member __.Current = e.Current + member _.GetEnumerator() = (Empty<'T>() :> IEnumerator) + + type GeneratedEnumerable<'T, 'State>(openf: unit -> 'State, compute: 'State -> 'T option, closef: 'State -> unit) = + let mutable started = false + let mutable curr = None + let state = ref (Some (openf ())) + let getCurr() : 'T = + check started + match curr with + | None -> alreadyFinished() + | Some x -> x + + let readAndClear () = + lock state (fun () -> + match state.Value with + | None -> None + | Some _ as res -> + state.Value <- None + res) + + let start() = + if not started then + started <- true + + let dispose() = + readAndClear() |> Option.iter closef + + let finish() = + try dispose() + finally curr <- None + + interface IEnumerator<'T> with + member _.Current = getCurr() + interface IEnumerator with - member __.Current = (e :> IEnumerator).Current - member __.MoveNext() = e.MoveNext() - member __.Reset() = noReset() + member _.Current = box (getCurr()) + member _.MoveNext() = + start() + match state.Value with + | None -> false // we started, then reached the end, then got another MoveNext + | Some s -> + match (try compute s with e -> finish(); reraise()) with + | None -> finish(); false + | Some _ as x -> + curr <- x + true + + member _.Reset() = noReset() + interface System.IDisposable with - member __.Dispose() = - try - e.Dispose() - finally - f() - } + member _.Dispose() = dispose() + + [] + type Singleton<'T>(v:'T) = + let mutable started = false + + interface IEnumerator<'T> with + member _.Current = v + + interface IEnumerator with + member _.Current = box v + member _.MoveNext() = if started then false else (started <- true; true) + member _.Reset() = noReset() + + interface System.IDisposable with + member _.Dispose() = () - let inline checkNonNull argName arg = - if isNull arg then - nullArg argName + let Singleton x = (new Singleton<'T>(x) :> IEnumerator<'T>) - let mkSeq f = + let EnumerateThenFinally f (e : IEnumerator<'T>) = + { new IEnumerator<'T> with + member _.Current = e.Current + + interface IEnumerator with + member _.Current = (e :> IEnumerator).Current + member _.MoveNext() = e.MoveNext() + member _.Reset() = noReset() + + interface System.IDisposable with + member _.Dispose() = + try + e.Dispose() + finally + f() + } + + let inline checkNonNull argName arg = + if isNull arg then + nullArg argName + + let mkSeq f = { new IEnumerable<'U> with - member __.GetEnumerator() = f() + member _.GetEnumerator() = f() + interface IEnumerable with - member __.GetEnumerator() = (f() :> IEnumerator) } + member _.GetEnumerator() = (f() :> IEnumerator) } namespace Microsoft.FSharp.Core.CompilerServices @@ -147,6 +180,7 @@ namespace Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Primitives.Basics open System.Collections open System.Collections.Generic + open System.Runtime.CompilerServices module RuntimeHelpers = @@ -156,11 +190,11 @@ namespace Microsoft.FSharp.Core.CompilerServices static member Comparer = let gcomparer = HashIdentity.Structural<'T> { new IEqualityComparer> with - member __.GetHashCode(v) = gcomparer.GetHashCode(v.Value) - member __.Equals(v1,v2) = gcomparer.Equals(v1.Value,v2.Value) } + member _.GetHashCode(v) = gcomparer.GetHashCode(v.Value) + member _.Equals(v1,v2) = gcomparer.Equals(v1.Value,v2.Value) } let Generate openf compute closef = - mkSeq (fun () -> IEnumerator.generateWhileSome openf compute closef) + mkSeq (fun () -> new IEnumerator.GeneratedEnumerable<_,_>(openf, compute, closef) :> IEnumerator<'T>) let GenerateUsing (openf : unit -> ('U :> System.IDisposable)) compute = Generate openf compute (fun (s:'U) -> s.Dispose()) @@ -187,7 +221,7 @@ namespace Microsoft.FSharp.Core.CompilerServices [] type FinallyEnumerable<'T>(compensation: unit -> unit, restf: unit -> seq<'T>) = interface IEnumerable<'T> with - member __.GetEnumerator() = + member _.GetEnumerator() = try let ie = restf().GetEnumerator() match ie with @@ -215,7 +249,7 @@ namespace Microsoft.FSharp.Core.CompilerServices [] // false = unchecked val mutable private currElement : 'T - member __.Finish() = + member _.Finish() = finished <- true try match currInnerEnum with @@ -250,7 +284,7 @@ namespace Microsoft.FSharp.Core.CompilerServices if finished then IEnumerator.alreadyFinished() else x.currElement interface IFinallyEnumerator with - member __.AppendFinallyAction(f) = + member _.AppendFinallyAction(f) = compensations <- f :: compensations interface IEnumerator<'T> with @@ -291,7 +325,7 @@ namespace Microsoft.FSharp.Core.CompilerServices takeOuter() takeInner () - member __.Reset() = IEnumerator.noReset() + member _.Reset() = IEnumerator.noReset() interface System.IDisposable with member x.Dispose() = @@ -335,12 +369,9 @@ namespace Microsoft.FSharp.Core.CompilerServices (FinallyEnumerable(compensation, (fun () -> source)) :> seq<_>) let CreateEvent (addHandler : 'Delegate -> unit) (removeHandler : 'Delegate -> unit) (createHandler : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 { new obj() with member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with + interface IEvent<'Delegate,'Args> with member x.AddHandler(h) = addHandler h member x.RemoveHandler(h) = removeHandler h interface System.IObservable<'Args> with @@ -350,6 +381,10 @@ namespace Microsoft.FSharp.Core.CompilerServices { new System.IDisposable with member x.Dispose() = removeHandler h } } + let inline SetFreshConsTail cons tail = cons.( :: ).1 <- tail + + [] + let inline FreshConsNoTail head = head :: (# "ldnull" : 'T list #) [] type GeneratedSequenceBase<'T>() = @@ -390,16 +425,154 @@ namespace Microsoft.FSharp.Core.CompilerServices interface IEnumerable<'T> with member x.GetEnumerator() = x.GetFreshEnumerator() + interface IEnumerable with member x.GetEnumerator() = (x.GetFreshEnumerator() :> IEnumerator) + interface IEnumerator<'T> with member x.Current = if redirect then redirectTo.LastGenerated else x.LastGenerated - interface System.IDisposable with + + interface IDisposable with member x.Dispose() = if redirect then redirectTo.Close() else x.Close() + interface IEnumerator with member x.Current = box (if redirect then redirectTo.LastGenerated else x.LastGenerated) //[] member x.MoveNext() = x.MoveNextImpl() - member __.Reset() = raise <| new System.NotSupportedException() + member _.Reset() = raise <| new System.NotSupportedException() + + [] + type ListCollector<'T> = + [] + val mutable Result : 'T list + + [] + val mutable LastCons : 'T list + + member this.Add (value: 'T) = + match box this.Result with + | null -> + let ra = RuntimeHelpers.FreshConsNoTail value + this.Result <- ra + this.LastCons <- ra + | _ -> + let ra = RuntimeHelpers.FreshConsNoTail value + RuntimeHelpers.SetFreshConsTail this.LastCons ra + this.LastCons <- ra + + member this.AddMany (values: seq<'T>) = + // cook a faster iterator for lists and arrays + match values with + | :? ('T[]) as valuesAsArray -> + for v in valuesAsArray do + this.Add v + | :? ('T list) as valuesAsList -> + for v in valuesAsList do + this.Add v + | _ -> + for v in values do + this.Add v + + // In the particular case of closing with a final add of an F# list + // we can simply stitch the list into the end of the resulting list + member this.AddManyAndClose (values: seq<'T>) = + match values with + | :? ('T list) as valuesAsList -> + let res = + match box this.Result with + | null -> + valuesAsList + | _ -> + RuntimeHelpers.SetFreshConsTail this.LastCons valuesAsList + this.Result + this.Result <- Unchecked.defaultof<_> + this.LastCons <- Unchecked.defaultof<_> + res + | _ -> + this.AddMany values + this.Close() + + member this.Close() = + match box this.Result with + | null -> [] + | _ -> + RuntimeHelpers.SetFreshConsTail this.LastCons [] + let res = this.Result + this.Result <- Unchecked.defaultof<_> + this.LastCons <- Unchecked.defaultof<_> + res + + // Optimized for 0, 1 and 2 sized arrays + [] + type ArrayCollector<'T> = + [] + val mutable ResizeArray: ResizeArray<'T> + + [] + val mutable First: 'T + + [] + val mutable Second: 'T + + [] + val mutable Count: int + + member this.Add (value: 'T) = + match this.Count with + | 0 -> + this.Count <- 1 + this.First <- value + | 1 -> + this.Count <- 2 + this.Second <- value + | 2 -> + let ra = ResizeArray<'T>() + ra.Add(this.First) + ra.Add(this.Second) + ra.Add(value) + this.Count <- 3 + this.ResizeArray <- ra + | _ -> + this.ResizeArray.Add(value) + + member this.AddMany (values: seq<'T>) = + if this.Count > 2 then + this.ResizeArray.AddRange(values) + else + // cook a faster iterator for lists and arrays + match values with + | :? ('T[]) as valuesAsArray -> + for v in valuesAsArray do + this.Add v + | :? ('T list) as valuesAsList -> + for v in valuesAsList do + this.Add v + | _ -> + for v in values do + this.Add v + + member this.AddManyAndClose (values: seq<'T>) = + this.AddMany(values) + this.Close() + + member this.Close() = + match this.Count with + | 0 -> Array.Empty<'T>() + | 1 -> + let res = [| this.First |] + this.Count <- 0 + this.First <- Unchecked.defaultof<_> + res + | 2 -> + let res = [| this.First; this.Second |] + this.Count <- 0 + this.First <- Unchecked.defaultof<_> + this.Second <- Unchecked.defaultof<_> + res + | _ -> + let res = this.ResizeArray.ToArray() + this <- ArrayCollector<'T>() + res + diff --git a/src/fsharp/FSharp.Core/seqcore.fsi b/src/fsharp/FSharp.Core/seqcore.fsi index d0eda5641fe..6e2f4d30834 100644 --- a/src/fsharp/FSharp.Core/seqcore.fsi +++ b/src/fsharp/FSharp.Core/seqcore.fsi @@ -7,73 +7,63 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core open Microsoft.FSharp.Collections module internal IEnumerator = - val noReset : unit -> 'a - val notStarted : unit -> 'a - val alreadyFinished : unit -> 'a - val check : started:bool -> unit - val dispose : r:System.IDisposable -> unit - val cast : - e:System.Collections.IEnumerator -> - System.Collections.Generic.IEnumerator<'T> - [] + val noReset: unit -> 'a + val notStarted: unit -> 'a + val alreadyFinished: unit -> 'a + val check: started: bool -> unit + val dispose: r: IDisposable -> unit + val cast : e: IEnumerator -> IEnumerator<'T> + + [] type EmptyEnumerator<'T> = - class interface System.IDisposable - interface System.Collections.IEnumerator - interface System.Collections.Generic.IEnumerator<'T> - new : unit -> EmptyEnumerator<'T> - end - val Empty : unit -> System.Collections.Generic.IEnumerator<'T> + interface IEnumerator + interface IEnumerator<'T> + new: unit -> EmptyEnumerator<'T> + + val Empty: unit -> IEnumerator<'T> + [] type EmptyEnumerable<'T> = | EmptyEnumerable - with - interface System.Collections.IEnumerable - interface System.Collections.Generic.IEnumerable<'T> - end - - val readAndClear : r:'a option ref -> 'a option - val generateWhileSome : - openf:(unit -> 'a) -> - compute:('a -> 'U option) -> - closef:('a -> unit) -> System.Collections.Generic.IEnumerator<'U> + interface IEnumerable + interface IEnumerable<'T> + [] type Singleton<'T> = - class interface System.IDisposable - interface System.Collections.IEnumerator - interface System.Collections.Generic.IEnumerator<'T> - new : v:'T -> Singleton<'T> - end - val Singleton : x:'T -> System.Collections.Generic.IEnumerator<'T> - val EnumerateThenFinally : - f:(unit -> unit) -> - e:System.Collections.Generic.IEnumerator<'T> -> - System.Collections.Generic.IEnumerator<'T> - val inline checkNonNull : argName:string -> arg:'a -> unit when 'a : null - val mkSeq : - f:(unit -> System.Collections.Generic.IEnumerator<'U>) -> - System.Collections.Generic.IEnumerable<'U> + interface IEnumerator + interface IEnumerator<'T> + new: v: 'T -> Singleton<'T> + + val Singleton: x: 'T -> IEnumerator<'T> + + val inline checkNonNull: argName: string -> arg: 'a -> unit when 'a: null + + val mkSeq : + f: (unit -> IEnumerator<'U>) -> + IEnumerable<'U> namespace Microsoft.FSharp.Core.CompilerServices open System open System.Collections open System.Collections.Generic + open System.Runtime.CompilerServices open Microsoft.FSharp.Core open Microsoft.FSharp.Collections - + [] /// A group of functions used as part of the compiled representation of F# sequence expressions. module RuntimeHelpers = [] - type internal StructBox<'T when 'T : equality> = - new : value:'T -> StructBox<'T> - member Value : 'T - static member Comparer : IEqualityComparer> + type internal StructBox<'T when 'T: equality> = + new: value: 'T -> StructBox<'T> + member Value: 'T + static member Comparer: IEqualityComparer> - val internal mkConcatSeq : sources:(seq<#seq<'T>>) -> seq<'T> + val internal mkConcatSeq: sources: (seq<#seq<'T>>) -> seq<'T> /// The F# compiler emits calls to this function to /// implement the while operator for F# sequence expressions. @@ -82,7 +72,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// The input sequence. /// /// The result sequence. - val EnumerateWhile : guard:(unit -> bool) -> source:seq<'T> -> seq<'T> + val EnumerateWhile : guard: (unit -> bool) -> source: seq<'T> -> seq<'T> /// The F# compiler emits calls to this function to /// implement the try/finally operator for F# sequence expressions. @@ -91,17 +81,17 @@ namespace Microsoft.FSharp.Core.CompilerServices /// A computation to be included in an enumerator's Dispose method. /// /// The result sequence. - val EnumerateThenFinally : source:seq<'T> -> compensation:(unit -> unit) -> seq<'T> + val EnumerateThenFinally: source: seq<'T> -> compensation: (unit -> unit) -> seq<'T> /// The F# compiler emits calls to this function to implement the compiler-intrinsic - /// conversions from untyped System.Collections.IEnumerable sequences to typed sequences. + /// conversions from untyped IEnumerable sequences to typed sequences. /// /// An initializer function. /// A function to iterate and test if end of sequence is reached. /// A function to retrieve the current element. /// /// The resulting typed sequence. - val EnumerateFromFunctions: create:(unit -> 'T) -> moveNext:('T -> bool) -> current:('T -> 'U) -> seq<'U> + val EnumerateFromFunctions: create: (unit -> 'T) -> moveNext: ('T -> bool) -> current: ('T -> 'U) -> seq<'U> /// The F# compiler emits calls to this function to implement the use operator for F# sequence /// expressions. @@ -110,7 +100,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// The input sequence. /// /// The result sequence. - val EnumerateUsing : resource:'T -> source:('T -> 'Collection) -> seq<'U> when 'T :> IDisposable and 'Collection :> seq<'U> + val EnumerateUsing: resource: 'T -> source: ('T -> 'Collection) -> seq<'U> when 'T :> IDisposable and 'Collection :> seq<'U> /// Creates an anonymous event with the given handlers. /// @@ -119,7 +109,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// A function to produce the delegate type the event can trigger. /// /// The initialized event. - val CreateEvent : addHandler : ('Delegate -> unit) -> removeHandler : ('Delegate -> unit) -> createHandler : ((obj -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate,'Args> + val CreateEvent: addHandler: ('Delegate -> unit) -> removeHandler: ('Delegate -> unit) -> createHandler: ((obj -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate,'Args> [] /// The F# compiler emits implementations of this type for compiled sequence expressions. @@ -127,25 +117,76 @@ namespace Microsoft.FSharp.Core.CompilerServices /// The F# compiler emits implementations of this type for compiled sequence expressions. /// /// A new sequence generator for the expression. - new : unit -> GeneratedSequenceBase<'T> + new: unit -> GeneratedSequenceBase<'T> + /// The F# compiler emits implementations of this type for compiled sequence expressions. /// /// A new enumerator for the sequence. - abstract GetFreshEnumerator : unit -> IEnumerator<'T> + abstract GetFreshEnumerator: unit -> IEnumerator<'T> + /// The F# compiler emits implementations of this type for compiled sequence expressions. /// /// A reference to the sequence. /// /// A 0, 1, and 2 respectively indicate Stop, Yield, and Goto conditions for the sequence generator. - abstract GenerateNext : result:byref> -> int + abstract GenerateNext: result: byref> -> int + /// The F# compiler emits implementations of this type for compiled sequence expressions. abstract Close: unit -> unit + /// The F# compiler emits implementations of this type for compiled sequence expressions. abstract CheckClose: bool + /// The F# compiler emits implementations of this type for compiled sequence expressions. - abstract LastGenerated : 'T + abstract LastGenerated: 'T interface IEnumerable<'T> interface IEnumerable interface IEnumerator<'T> interface IEnumerator interface IDisposable + + /// Collects elements and builds a list + [] + type ListCollector<'T> = + [] + val mutable internal Result: 'T list + + [] + val mutable internal LastCons: 'T list + + /// Add an element to the collector + member Add: value: 'T -> unit + + /// Add multiple elements to the collector + member AddMany: values: seq<'T> -> unit + + /// Add multiple elements to the collector and return the resulting list + member AddManyAndClose: values: seq<'T> -> 'T list + + /// Return the resulting list + member Close: unit -> 'T list + + /// Collects elements and builds an array + [] + type ArrayCollector<'T> = + [] + val mutable internal ResizeArray: ResizeArray<'T> + [] + val mutable internal First: 'T + [] + val mutable internal Second: 'T + [] + val mutable internal Count: int + + /// Add an element to the collector + member Add: value: 'T -> unit + + /// Add multiple elements to the collector + member AddMany: values: seq<'T> -> unit + + /// Add multiple elements to the collector and return the resulting array + member AddManyAndClose: values: seq<'T> -> 'T[] + + /// Return the resulting list + member Close: unit -> 'T[] + diff --git a/src/fsharp/FSharp.Core/set.fs b/src/fsharp/FSharp.Core/set.fs index bd6bb970002..9978a574c97 100644 --- a/src/fsharp/FSharp.Core/set.fs +++ b/src/fsharp/FSharp.Core/set.fs @@ -14,21 +14,40 @@ open Microsoft.FSharp.Collections // A functional language implementation of binary trees -[] [] -type SetTree<'T> when 'T: comparison = - | SetEmpty // height = 0 - | SetNode of 'T * SetTree<'T> * SetTree<'T> * int // height = int - | SetOne of 'T // height = 1 - // OPTIMIZATION: store SetNode (k, SetEmpty, SetEmpty, 1) ---> SetOne k - +[] +type internal SetTree<'T>(k: 'T, h: int) = + member _.Height = h + member _.Key = k + new(k: 'T) = SetTree(k,1) + +[] +[] +[] +type internal SetTreeNode<'T>(v:'T, left:SetTree<'T>, right: SetTree<'T>, h: int) = + inherit SetTree<'T>(v,h) + member _.Left = left + member _.Right = right + [] module internal SetTree = - let rec countAux s acc = - match s with - | SetNode (_, l, r, _) -> countAux l (countAux r (acc+1)) - | SetOne (_) -> acc+1 - | SetEmpty -> acc + + let empty = null + + let inline isEmpty (t:SetTree<'T>) = isNull t + + let inline private asNode(value:SetTree<'T>) : SetTreeNode<'T> = + value :?> SetTreeNode<'T> + + let rec countAux (t:SetTree<'T>) acc = + if isEmpty t then + acc + else + if t.Height = 1 then + acc + 1 + else + let tn = asNode t + countAux tn.Left (countAux tn.Right (acc+1)) let count s = countAux s 0 @@ -54,223 +73,207 @@ module internal SetTree = (totalSizeOnSetAdd / float numAdds), (totalSizeOnSetLookup / float numLookups)) - let SetOne n = + let SetTree n = report() numOnes <- numOnes + 1 totalSizeOnNodeCreation <- totalSizeOnNodeCreation + 1.0 - SetTree.SetOne n + SetTree n - let SetNode (x, l, r, h) = + let SetTreeNode (x, l, r, h) = report() numNodes <- numNodes + 1 - let n = SetTree.SetNode (x, l, r, h) + let n = SetTreeNode (x, l, r, h) totalSizeOnNodeCreation <- totalSizeOnNodeCreation + float (count n) n -#else - let SetOne n = SetTree.SetOne n - - let SetNode (x, l, r, h) = SetTree.SetNode (x, l, r, h) #endif - let height t = - match t with - | SetEmpty -> 0 - | SetOne _ -> 1 - | SetNode (_, _, _, h) -> h - -#if CHECKED - let rec checkInvariant t = - // A good sanity check, loss of balance can hit perf - match t with - | SetEmpty -> true - | SetOne _ -> true - | SetNode (k, t1, t2, h) -> - let h1 = height t1 - let h2 = height t2 - (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant t1 && checkInvariant t2 -#endif + let inline height (t:SetTree<'T>) = + if isEmpty t then 0 + else t.Height - let tolerance = 2 + [] + let private tolerance = 2 - let mk l k r = - match l, r with - | SetEmpty, SetEmpty -> SetOne k - | _ -> - let hl = height l - let hr = height r - let m = if hl < hr then hr else hl - SetNode (k, l, r, m+1) + let mk l k r : SetTree<'T> = + let hl = height l + let hr = height r + let m = if hl < hr then hr else hl + if m = 0 then // m=0 ~ isEmpty l && isEmpty r + SetTree k + else + SetTreeNode (k, l, r, m+1) :> SetTree<'T> - let rebalance t1 k t2 = + let rebalance t1 v t2 = let t1h = height t1 let t2h = height t2 if t2h > t1h + tolerance then // right is heavier than left - match t2 with - | SetNode (t2k, t2l, t2r, _) -> - // one of the nodes must have height > height t1 + 1 - if height t2l > t1h + 1 then // balance left: combination - match t2l with - | SetNode (t2lk, t2ll, t2lr, _) -> - mk (mk t1 k t2ll) t2lk (mk t2lr t2k t2r) - | _ -> failwith "rebalance" - else // rotate left - mk (mk t1 k t2l) t2k t2r - | _ -> failwith "rebalance" + let t2' = asNode(t2) + // one of the nodes must have height > height t1 + 1 + if height t2'.Left > t1h + 1 then // balance left: combination + let t2l = asNode(t2'.Left) + mk (mk t1 v t2l.Left) t2l.Key (mk t2l.Right t2'.Key t2'.Right) + else // rotate left + mk (mk t1 v t2'.Left) t2.Key t2'.Right else - if t1h > t2h + tolerance then // left is heavier than right - match t1 with - | SetNode (t1k, t1l, t1r, _) -> - // one of the nodes must have height > height t2 + 1 - if height t1r > t2h + 1 then - // balance right: combination - match t1r with - | SetNode (t1rk, t1rl, t1rr, _) -> - mk (mk t1l t1k t1rl) t1rk (mk t1rr k t2) - | _ -> failwith "rebalance" - else - mk t1l t1k (mk t1r k t2) - | _ -> failwith "rebalance" - else mk t1 k t2 - - let rec add (comparer: IComparer<'T>) k t = - match t with - | SetNode (k2, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then rebalance (add comparer k l) k2 r - elif c = 0 then t - else rebalance l k2 (add comparer k r) - | SetOne k2 -> - // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated - let c = comparer.Compare(k, k2) - if c < 0 then SetNode (k, SetEmpty, t, 2) - elif c = 0 then t - else SetNode (k, t, SetEmpty, 2) - | SetEmpty -> SetOne k - - let rec balance comparer t1 k t2 = + if t1h > t2h + tolerance then // left is heavier than right + let t1' = asNode(t1) + // one of the nodes must have height > height t2 + 1 + if height t1'.Right > t2h + 1 then + // balance right: combination + let t1r = asNode(t1'.Right) + mk (mk t1'.Left t1.Key t1r.Left) t1r.Key (mk t1r.Right v t2) + else + mk t1'.Left t1'.Key (mk t1'.Right v t2) + else mk t1 v t2 + + let rec add (comparer: IComparer<'T>) k (t:SetTree<'T>) : SetTree<'T> = + if isEmpty t then SetTree k + else + let c = comparer.Compare(k, t.Key) + if t.Height = 1 then + // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated + if c < 0 then SetTreeNode (k, empty, t, 2) :> SetTree<'T> + elif c = 0 then t + else SetTreeNode (k, t, empty, 2) :> SetTree<'T> + else + let tn = asNode t + if c < 0 then rebalance (add comparer k tn.Left) tn.Key tn.Right + elif c = 0 then t + else rebalance tn.Left tn.Key (add comparer k tn.Right) + + let rec balance comparer (t1:SetTree<'T>) k (t2:SetTree<'T>) = // Given t1 < k < t2 where t1 and t2 are "balanced", // return a balanced tree for . // Recall: balance means subtrees heights differ by at most "tolerance" - match t1, t2 with - | SetEmpty, t2 -> add comparer k t2 // drop t1 = empty - | t1, SetEmpty -> add comparer k t1 // drop t2 = empty - | SetOne k1, t2 -> add comparer k (add comparer k1 t2) - | t1, SetOne k2 -> add comparer k (add comparer k2 t1) - | SetNode (k1, t11, t12, h1), SetNode (k2, t21, t22, h2) -> - // Have: (t11 < k1 < t12) < k < (t21 < k2 < t22) - // Either (a) h1, h2 differ by at most 2 - no rebalance needed. - // (b) h1 too small, i.e. h1+2 < h2 - // (c) h2 too small, i.e. h2+2 < h1 - if h1+tolerance < h2 then - // case: b, h1 too small - // push t1 into low side of t2, may increase height by 1 so rebalance - rebalance (balance comparer t1 k t21) k2 t22 - elif h2+tolerance < h1 then - // case: c, h2 too small - // push t2 into high side of t1, may increase height by 1 so rebalance - rebalance t11 k1 (balance comparer t12 k t2) + if isEmpty t1 then add comparer k t2 // drop t1 = empty + elif isEmpty t2 then add comparer k t1 // drop t2 = empty + else + if t1.Height = 1 then add comparer k (add comparer t1.Key t2) else - // case: a, h1 and h2 meet balance requirement - mk t1 k t2 + let t1n = asNode t1 + if t2.Height = 1 then add comparer k (add comparer t2.Key t1) + else + let t2n = asNode t2 + // Have: (t1l < k1 < t1r) < k < (t2l < k2 < t2r) + // Either (a) h1, h2 differ by at most 2 - no rebalance needed. + // (b) h1 too small, i.e. h1+2 < h2 + // (c) h2 too small, i.e. h2+2 < h1 + if t1n.Height + tolerance < t2n.Height then + // case: b, h1 too small + // push t1 into low side of t2, may increase height by 1 so rebalance + rebalance (balance comparer t1 k t2n.Left) t2n.Key t2n.Right + elif t2n.Height + tolerance < t1n.Height then + // case: c, h2 too small + // push t2 into high side of t1, may increase height by 1 so rebalance + rebalance t1n.Left t1n.Key (balance comparer t1n.Right k t2) + else + // case: a, h1 and h2 meet balance requirement + mk t1 k t2 - let rec split (comparer: IComparer<'T>) pivot t = + let rec split (comparer: IComparer<'T>) pivot (t:SetTree<'T>) = // Given a pivot and a set t // Return { x in t s.t. x < pivot }, pivot in t?, { x in t s.t. x > pivot } - match t with - | SetNode (k1, t11, t12, _) -> - let c = comparer.Compare(pivot, k1) - if c < 0 then // pivot t1 - let t11Lo, havePivot, t11Hi = split comparer pivot t11 - t11Lo, havePivot, balance comparer t11Hi k1 t12 - elif c = 0 then // pivot is k1 - t11, true, t12 - else // pivot t2 - let t12Lo, havePivot, t12Hi = split comparer pivot t12 - balance comparer t11 k1 t12Lo, havePivot, t12Hi - | SetOne k1 -> - let c = comparer.Compare(k1, pivot) - if c < 0 then t, false, SetEmpty // singleton under pivot - elif c = 0 then SetEmpty, true, SetEmpty // singleton is pivot - else SetEmpty, false, t // singleton over pivot - | SetEmpty -> - SetEmpty, false, SetEmpty - - let rec spliceOutSuccessor t = - match t with - | SetEmpty -> failwith "internal error: Set.spliceOutSuccessor" - | SetOne k2 -> k2, SetEmpty - | SetNode (k2, l, r, _) -> - match l with - | SetEmpty -> k2, r - | _ -> let k3, l' = spliceOutSuccessor l in k3, mk l' k2 r - - let rec remove (comparer: IComparer<'T>) k t = - match t with - | SetEmpty -> t - | SetOne k2 -> - let c = comparer.Compare(k, k2) - if c = 0 then SetEmpty - else t - | SetNode (k2, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then rebalance (remove comparer k l) k2 r - elif c = 0 then - match l, r with - | SetEmpty, _ -> r - | _, SetEmpty -> l - | _ -> - let sk, r' = spliceOutSuccessor r - mk l sk r' - else rebalance l k2 (remove comparer k r) - - let rec mem (comparer: IComparer<'T>) k t = - match t with - | SetNode (k2, l, r, _) -> - let c = comparer.Compare(k, k2) - if c < 0 then mem comparer k l - elif c = 0 then true - else mem comparer k r - | SetOne k2 -> (comparer.Compare(k, k2) = 0) - | SetEmpty -> false - - let rec iter f t = - match t with - | SetNode (k2, l, r, _) -> iter f l; f k2; iter f r - | SetOne k2 -> f k2 - | SetEmpty -> () - - let rec foldBackOpt (f:OptimizedClosures.FSharpFunc<_, _, _>) m x = - match m with - | SetNode (k, l, r, _) -> foldBackOpt f l (f.Invoke(k, (foldBackOpt f r x))) - | SetOne k -> f.Invoke(k, x) - | SetEmpty -> x + if isEmpty t then empty, false, empty + else + if t.Height = 1 then + let c = comparer.Compare(t.Key, pivot) + if c < 0 then t, false, empty // singleton under pivot + elif c = 0 then empty, true, empty // singleton is pivot + else empty, false, t // singleton over pivot + else + let tn = asNode t + let c = comparer.Compare(pivot, tn.Key) + if c < 0 then // pivot t1 + let t11Lo, havePivot, t11Hi = split comparer pivot tn.Left + t11Lo, havePivot, balance comparer t11Hi tn.Key tn.Right + elif c = 0 then // pivot is k1 + tn.Left, true, tn.Right + else // pivot t2 + let t12Lo, havePivot, t12Hi = split comparer pivot tn.Right + balance comparer tn.Left tn.Key t12Lo, havePivot, t12Hi + + let rec spliceOutSuccessor (t:SetTree<'T>) = + if isEmpty t then failwith "internal error: Set.spliceOutSuccessor" + else + if t.Height = 1 then t.Key, empty + else + let tn = asNode t + if isEmpty tn.Left then tn.Key, tn.Right + else let k3, l' = spliceOutSuccessor tn.Left in k3, mk l' tn.Key tn.Right + + let rec remove (comparer: IComparer<'T>) k (t:SetTree<'T>) = + if isEmpty t then t + else + let c = comparer.Compare(k, t.Key) + if t.Height = 1 then + if c = 0 then empty else t + else + let tn = asNode t + if c < 0 then rebalance (remove comparer k tn.Left) tn.Key tn.Right + elif c = 0 then + if isEmpty tn.Left then tn.Right + elif isEmpty tn.Right then tn.Left + else + let sk, r' = spliceOutSuccessor tn.Right + mk tn.Left sk r' + else rebalance tn.Left tn.Key (remove comparer k tn.Right) + + let rec mem (comparer: IComparer<'T>) k (t:SetTree<'T>) = + if isEmpty t then false + else + let c = comparer.Compare(k, t.Key) + if t.Height = 1 then (c = 0) + else + let tn = asNode t + if c < 0 then mem comparer k tn.Left + elif c = 0 then true + else mem comparer k tn.Right + + let rec iter f (t:SetTree<'T>) = + if isEmpty t then () + else + if t.Height = 1 then f t.Key + else + let tn = asNode t + iter f tn.Left; f tn.Key; iter f tn.Right + + let rec foldBackOpt (f:OptimizedClosures.FSharpFunc<_, _, _>) (t:SetTree<'T>) x = + if isEmpty t then x + else + if t.Height = 1 then f.Invoke(t.Key, x) + else + let tn = asNode t + foldBackOpt f tn.Left (f.Invoke(tn.Key, (foldBackOpt f tn.Right x))) let foldBack f m x = foldBackOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m x - let rec foldOpt (f:OptimizedClosures.FSharpFunc<_, _, _>) x m = - match m with - | SetNode (k, l, r, _) -> - let x = foldOpt f x l in - let x = f.Invoke(x, k) - foldOpt f x r - | SetOne k -> f.Invoke(x, k) - | SetEmpty -> x + let rec foldOpt (f:OptimizedClosures.FSharpFunc<_, _, _>) x (t:SetTree<'T>) = + if isEmpty t then x + else + if t.Height = 1 then f.Invoke(x, t.Key) + else + let tn = asNode t + let x = foldOpt f x tn.Left in + let x = f.Invoke(x, tn.Key) + foldOpt f x tn.Right let fold f x m = foldOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) x m - let rec forall f m = - match m with - | SetNode (k2, l, r, _) -> f k2 && forall f l && forall f r - | SetOne k2 -> f k2 - | SetEmpty -> true - - let rec exists f m = - match m with - | SetNode (k2, l, r, _) -> f k2 || exists f l || exists f r - | SetOne k2 -> f k2 - | SetEmpty -> false + let rec forall f (t:SetTree<'T>) = + if isEmpty t then true + else + if t.Height = 1 then f t.Key + else + let tn = asNode t + f tn.Key && forall f tn.Left && forall f tn.Right - let isEmpty m = match m with | SetEmpty -> true | _ -> false + let rec exists f (t:SetTree<'T>) = + if isEmpty t then false + else + if t.Height = 1 then f t.Key + else + let tn = asNode t + f tn.Key || exists f tn.Left || exists f tn.Right let subset comparer a b = forall (fun x -> mem comparer x b) a @@ -278,101 +281,110 @@ module internal SetTree = let properSubset comparer a b = forall (fun x -> mem comparer x b) a && exists (fun x -> not (mem comparer x a)) b - let rec filterAux comparer f s acc = - match s with - | SetNode (k, l, r, _) -> - let acc = if f k then add comparer k acc else acc - filterAux comparer f l (filterAux comparer f r acc) - | SetOne k -> if f k then add comparer k acc else acc - | SetEmpty -> acc - - let filter comparer f s = filterAux comparer f s SetEmpty - - let rec diffAux comparer m acc = - match acc with - | SetEmpty -> acc - | _ -> - match m with - | SetNode (k, l, r, _) -> diffAux comparer l (diffAux comparer r (remove comparer k acc)) - | SetOne k -> remove comparer k acc - | SetEmpty -> acc + let rec filterAux comparer f (t:SetTree<'T>) acc = + if isEmpty t then acc + else + if t.Height = 1 then + if f t.Key then add comparer t.Key acc else acc + else + let tn = asNode t + let acc = if f tn.Key then add comparer tn.Key acc else acc + filterAux comparer f tn.Left (filterAux comparer f tn.Right acc) + + let filter comparer f s = filterAux comparer f s empty + + let rec diffAux comparer (t:SetTree<'T>) acc = + if isEmpty acc then acc + else + if isEmpty t then acc + else + if t.Height = 1 then remove comparer t.Key acc + else + let tn = asNode t + diffAux comparer tn.Left (diffAux comparer tn.Right (remove comparer tn.Key acc)) let diff comparer a b = diffAux comparer b a - let rec union comparer t1 t2 = + let rec union comparer (t1:SetTree<'T>) (t2:SetTree<'T>) = // Perf: tried bruteForce for low heights, but nothing significant - match t1, t2 with - | SetNode (k1, t11, t12, h1), SetNode (k2, t21, t22, h2) -> // (t11 < k < t12) AND (t21 < k2 < t22) - // Divide and Conquer: - // Suppose t1 is largest. - // Split t2 using pivot k1 into lo and hi. - // Union disjoint subproblems and then combine. - if h1 > h2 then - let lo, _, hi = split comparer k1 t2 in - balance comparer (union comparer t11 lo) k1 (union comparer t12 hi) + if isEmpty t1 then t2 + elif isEmpty t2 then t1 + else + if t1.Height = 1 then add comparer t1.Key t2 else - let lo, _, hi = split comparer k2 t1 in - balance comparer (union comparer t21 lo) k2 (union comparer t22 hi) - | SetEmpty, t -> t - | t, SetEmpty -> t - | SetOne k1, t2 -> add comparer k1 t2 - | t1, SetOne k2 -> add comparer k2 t1 - - let rec intersectionAux comparer b m acc = - match m with - | SetNode (k, l, r, _) -> - let acc = intersectionAux comparer b r acc - let acc = if mem comparer k b then add comparer k acc else acc - intersectionAux comparer b l acc - | SetOne k -> - if mem comparer k b then add comparer k acc else acc - | SetEmpty -> acc - - let intersection comparer a b = intersectionAux comparer b a SetEmpty + if t2.Height = 1 then add comparer t2.Key t1 + else + let t1n = asNode t1 + let t2n = asNode t2 // (t1l < k < t1r) AND (t2l < k2 < t2r) + // Divide and Conquer: + // Suppose t1 is largest. + // Split t2 using pivot k1 into lo and hi. + // Union disjoint subproblems and then combine. + if t1n.Height > t2n.Height then + let lo, _, hi = split comparer t1n.Key t2 in + balance comparer (union comparer t1n.Left lo) t1n.Key (union comparer t1n.Right hi) + else + let lo, _, hi = split comparer t2n.Key t1 in + balance comparer (union comparer t2n.Left lo) t2n.Key (union comparer t2n.Right hi) + + let rec intersectionAux comparer b (t:SetTree<'T>) acc = + if isEmpty t then acc + else + if t.Height = 1 then + if mem comparer t.Key b then add comparer t.Key acc else acc + else + let tn = asNode t + let acc = intersectionAux comparer b tn.Right acc + let acc = if mem comparer tn.Key b then add comparer tn.Key acc else acc + intersectionAux comparer b tn.Left acc + + let intersection comparer a b = intersectionAux comparer b a empty let partition1 comparer f k (acc1, acc2) = if f k then (add comparer k acc1, acc2) else (acc1, add comparer k acc2) - let rec partitionAux comparer f s acc = - match s with - | SetNode (k, l, r, _) -> - let acc = partitionAux comparer f r acc - let acc = partition1 comparer f k acc - partitionAux comparer f l acc - | SetOne k -> partition1 comparer f k acc - | SetEmpty -> acc - - let partition comparer f s = partitionAux comparer f s (SetEmpty, SetEmpty) - - // It's easier to get many less-important algorithms right using this active pattern - let (|MatchSetNode|MatchSetEmpty|) s = - match s with - | SetNode (k2, l, r, _) -> MatchSetNode(k2, l, r) - | SetOne k2 -> MatchSetNode(k2, SetEmpty, SetEmpty) - | SetEmpty -> MatchSetEmpty - - let rec minimumElementAux s n = - match s with - | SetNode (k, l, _, _) -> minimumElementAux l k - | SetOne k -> k - | SetEmpty -> n - - and minimumElementOpt s = - match s with - | SetNode (k, l, _, _) -> Some(minimumElementAux l k) - | SetOne k -> Some k - | SetEmpty -> None - - and maximumElementAux s n = - match s with - | SetNode (k, _, r, _) -> maximumElementAux r k - | SetOne k -> k - | SetEmpty -> n - - and maximumElementOpt s = - match s with - | SetNode (k, _, r, _) -> Some(maximumElementAux r k) - | SetOne k -> Some k - | SetEmpty -> None + let rec partitionAux comparer f (t:SetTree<'T>) acc = + if isEmpty t then acc + else + if t.Height = 1 then partition1 comparer f t.Key acc + else + let tn = asNode t + let acc = partitionAux comparer f tn.Right acc + let acc = partition1 comparer f tn.Key acc + partitionAux comparer f tn.Left acc + + let partition comparer f s = partitionAux comparer f s (empty, empty) + + let rec minimumElementAux (t:SetTree<'T>) n = + if isEmpty t then n + else + if t.Height = 1 then t.Key + else + let tn = asNode t + minimumElementAux tn.Left tn.Key + + and minimumElementOpt (t:SetTree<'T>) = + if isEmpty t then None + else + if t.Height = 1 then Some t.Key + else + let tn = asNode t + Some(minimumElementAux tn.Left tn.Key) + + and maximumElementAux (t:SetTree<'T>) n = + if isEmpty t then n + else + if t.Height = 1 then t.Key + else + let tn = asNode t + maximumElementAux tn.Right tn.Key + + and maximumElementOpt (t:SetTree<'T>) = + if isEmpty t then None + else + if t.Height = 1 then Some t.Key + else + let tn = asNode t + Some(maximumElementAux tn.Right tn.Key) let minimumElement s = match minimumElementOpt s with @@ -394,12 +406,16 @@ module internal SetTree = // collapseLHS: // a) Always returns either [] or a list starting with SetOne. // b) The "fringe" of the set stack is unchanged. - let rec collapseLHS stack = + let rec collapseLHS (stack: SetTree<'T> list) = match stack with | [] -> [] - | SetEmpty :: rest -> collapseLHS rest - | SetOne _ :: _ -> stack - | SetNode (k, l, r, _) :: rest -> collapseLHS (l :: SetOne k :: r :: rest) + | x :: rest -> + if isEmpty x then collapseLHS rest + else + if x.Height = 1 then stack + else + let xn = asNode x + collapseLHS (xn.Left :: SetTree xn.Key :: xn.Right :: rest) let mkIterator s = { stack = collapseLHS [s]; started = false } @@ -410,20 +426,24 @@ module internal SetTree = let current i = if i.started then match i.stack with - | SetOne k :: _ -> k - | [] -> alreadyFinished() - | _ -> failwith "Please report error: Set iterator, unexpected stack for current" + | k :: _ -> k.Key + | [] -> alreadyFinished() else notStarted() + let unexpectedStackForMoveNext() = failwith "Please report error: Set iterator, unexpected stack for moveNext" + let unexpectedstateInSetTreeCompareStacks() = failwith "unexpected state in SetTree.compareStacks" + let rec moveNext i = if i.started then match i.stack with - | SetOne _ :: rest -> - i.stack <- collapseLHS rest - not i.stack.IsEmpty - | [] -> false - | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext" + | [] -> false + | t :: rest -> + if t.Height = 1 then + i.stack <- collapseLHS rest + not i.stack.IsEmpty + else + unexpectedStackForMoveNext() else i.started <- true; // The first call to MoveNext "starts" the enumeration. not i.stack.IsEmpty @@ -431,59 +451,86 @@ module internal SetTree = let mkIEnumerator s = let mutable i = mkIterator s { new IEnumerator<_> with - member __.Current = current i + member _.Current = current i interface IEnumerator with - member __.Current = box (current i) - member __.MoveNext() = moveNext i - member __.Reset() = i <- mkIterator s + member _.Current = box (current i) + member _.MoveNext() = moveNext i + member _.Reset() = i <- mkIterator s interface System.IDisposable with - member __.Dispose() = () } + member _.Dispose() = () } /// Set comparison. Note this can be expensive. - let rec compareStacks (comparer: IComparer<'T>) l1 l2 = + let rec compareStacks (comparer: IComparer<'T>) (l1:SetTree<'T> list) (l2:SetTree<'T> list) : int = + let cont() = + match l1, l2 with + | (x1 :: t1), _ when not (isEmpty x1) -> + if x1.Height = 1 then + compareStacks comparer (empty :: SetTree x1.Key :: t1) l2 + else + let x1n = asNode x1 + compareStacks comparer (x1n.Left :: (SetTreeNode (x1n.Key, empty, x1n.Right, 0) :> SetTree<'T>) :: t1) l2 + | _, (x2 :: t2) when not (isEmpty x2) -> + if x2.Height = 1 then + compareStacks comparer l1 (empty :: SetTree x2.Key :: t2) + else + let x2n = asNode x2 + compareStacks comparer l1 (x2n.Left :: (SetTreeNode (x2n.Key, empty, x2n.Right, 0) :> SetTree<'T> ) :: t2) + | _ -> unexpectedstateInSetTreeCompareStacks() + match l1, l2 with | [], [] -> 0 | [], _ -> -1 | _, [] -> 1 - | (SetEmpty _ :: t1), (SetEmpty :: t2) -> compareStacks comparer t1 t2 - | (SetOne n1k :: t1), (SetOne n2k :: t2) -> - let c = comparer.Compare(n1k, n2k) - if c <> 0 then c else compareStacks comparer t1 t2 - | (SetOne n1k :: t1), (SetNode (n2k, SetEmpty, n2r, _) :: t2) -> - let c = comparer.Compare(n1k, n2k) - if c <> 0 then c else compareStacks comparer (SetEmpty :: t1) (n2r :: t2) - | (SetNode (n1k, (SetEmpty as emp), n1r, _) :: t1), (SetOne n2k :: t2) -> - let c = comparer.Compare(n1k, n2k) - if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2) - | (SetNode (n1k, SetEmpty, n1r, _) :: t1), (SetNode (n2k, SetEmpty, n2r, _) :: t2) -> - let c = comparer.Compare(n1k, n2k) - if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2) - | (SetOne n1k :: t1), _ -> - compareStacks comparer (SetEmpty :: SetOne n1k :: t1) l2 - | (SetNode (n1k, n1l, n1r, _) :: t1), _ -> - compareStacks comparer (n1l :: SetNode (n1k, SetEmpty, n1r, 0) :: t1) l2 - | _, (SetOne n2k :: t2) -> - compareStacks comparer l1 (SetEmpty :: SetOne n2k :: t2) - | _, (SetNode (n2k, n2l, n2r, _) :: t2) -> - compareStacks comparer l1 (n2l :: SetNode (n2k, SetEmpty, n2r, 0) :: t2) - - let compare comparer s1 s2 = - match s1, s2 with - | SetEmpty, SetEmpty -> 0 - | SetEmpty, _ -> -1 - | _, SetEmpty -> 1 - | _ -> compareStacks comparer [s1] [s2] + | (x1 :: t1), (x2 :: t2) -> + if isEmpty x1 then + if isEmpty x2 then compareStacks comparer t1 t2 + else cont() + elif isEmpty x2 then cont() + else + if x1.Height = 1 then + if x2.Height = 1 then + let c = comparer.Compare(x1.Key, x2.Key) + if c <> 0 then c else compareStacks comparer t1 t2 + else + let x2n = asNode x2 + if isEmpty x2n.Left then + let c = comparer.Compare(x1.Key, x2n.Key) + if c <> 0 then c else compareStacks comparer (empty :: t1) (x2n.Right :: t2) + else cont() + else + let x1n = asNode x1 + if isEmpty x1n.Left then + if x2.Height = 1 then + let c = comparer.Compare(x1n.Key, x2.Key) + if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (empty :: t2) + else + let x2n = asNode x2 + if isEmpty x2n.Left then + let c = comparer.Compare(x1n.Key, x2n.Key) + if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (x2n.Right :: t2) + else cont() + else cont() + + let compare comparer (t1:SetTree<'T>) (t2:SetTree<'T>) = + if isEmpty t1 then + if isEmpty t2 then 0 + else -1 + else + if isEmpty t2 then 1 + else compareStacks comparer [t1] [t2] let choose s = minimumElement s - let toList s = - let rec loop m acc = - match m with - | SetNode (k, l, r, _) -> loop l (k :: loop r acc) - | SetOne k -> k :: acc - | SetEmpty -> acc - loop s [] + let toList (t:SetTree<'T>) = + let rec loop (t':SetTree<'T>) acc = + if isEmpty t' then acc + else + if t'.Height = 1 then t'.Key :: acc + else + let tn = asNode t' + loop tn.Left (tn.Key :: loop tn.Right acc) + loop t [] let copyToArray s (arr: _[]) i = let mutable j = i @@ -502,10 +549,10 @@ module internal SetTree = let ofSeq comparer (c: IEnumerable<_>) = use ie = c.GetEnumerator() - mkFromEnumerator comparer SetEmpty ie + mkFromEnumerator comparer empty ie let ofArray comparer l = - Array.fold (fun acc k -> add comparer k acc) SetEmpty l + Array.fold (fun acc k -> add comparer k acc) empty l [] [] @@ -532,20 +579,20 @@ type Set<[]'T when 'T: comparison >(comparer:IComparer<'T static let empty: Set<'T> = let comparer = LanguagePrimitives.FastGenericComparer<'T> - Set<'T>(comparer, SetEmpty) + Set<'T>(comparer, SetTree.empty) [] - member __.OnSerializing(context: System.Runtime.Serialization.StreamingContext) = + member _.OnSerializing(context: System.Runtime.Serialization.StreamingContext) = ignore context serializedData <- SetTree.toArray tree // Do not set this to null, since concurrent threads may also be serializing the data //[] - //member __.OnSerialized(context: System.Runtime.Serialization.StreamingContext) = + //member _.OnSerialized(context: System.Runtime.Serialization.StreamingContext) = // serializedData <- null [] - member __.OnDeserialized(context: System.Runtime.Serialization.StreamingContext) = + member _.OnDeserialized(context: System.Runtime.Serialization.StreamingContext) = ignore context comparer <- LanguagePrimitives.FastGenericComparer<'T> tree <- SetTree.ofArray comparer serializedData @@ -597,18 +644,18 @@ type Set<[]'T when 'T: comparison >(comparer:IComparer<'T SetTree.isEmpty s.Tree member s.Partition f : Set<'T> * Set<'T> = - match s.Tree with - | SetEmpty -> s, s - | _ -> let t1, t2 = SetTree.partition s.Comparer f s.Tree in Set(s.Comparer, t1), Set(s.Comparer, t2) + if SetTree.isEmpty s.Tree then s,s + else + let t1, t2 = SetTree.partition s.Comparer f s.Tree in Set(s.Comparer, t1), Set(s.Comparer, t2) member s.Filter f : Set<'T> = - match s.Tree with - | SetEmpty -> s - | _ -> Set(s.Comparer, SetTree.filter s.Comparer f s.Tree) + if SetTree.isEmpty s.Tree then s + else + Set(s.Comparer, SetTree.filter s.Comparer f s.Tree) member s.Map f : Set<'U> = let comparer = LanguagePrimitives.FastGenericComparer<'U> - Set(comparer, SetTree.fold (fun acc k -> SetTree.add comparer (f k) acc) (SetTree<_>.SetEmpty) s.Tree) + Set(comparer, SetTree.fold (fun acc k -> SetTree.add comparer (f k) acc) (SetTree.empty) s.Tree) member s.Exists f = SetTree.exists f s.Tree @@ -618,12 +665,10 @@ type Set<[]'T when 'T: comparison >(comparer:IComparer<'T [] static member (-) (set1: Set<'T>, set2: Set<'T>) = - match set1.Tree with - | SetEmpty -> set1 (* 0 - B = 0 *) - | _ -> - match set2.Tree with - | SetEmpty -> set1 (* A - 0 = A *) - | _ -> Set(set1.Comparer, SetTree.diff set1.Comparer set1.Tree set2.Tree) + if SetTree.isEmpty set1.Tree then set1 (* 0 - B = 0 *) + else + if SetTree.isEmpty set2.Tree then set1 (* A - 0 = A *) + else Set(set1.Comparer, SetTree.diff set1.Comparer set1.Tree set2.Tree) [] static member (+) (set1: Set<'T>, set2: Set<'T>) = @@ -631,20 +676,16 @@ type Set<[]'T when 'T: comparison >(comparer:IComparer<'T SetTree.report() SetTree.numUnions <- SetTree.numUnions + 1 #endif - match set2.Tree with - | SetEmpty -> set1 (* A U 0 = A *) - | _ -> - match set1.Tree with - | SetEmpty -> set2 (* 0 U B = B *) - | _ -> Set(set1.Comparer, SetTree.union set1.Comparer set1.Tree set2.Tree) + if SetTree.isEmpty set2.Tree then set1 (* A U 0 = A *) + else + if SetTree.isEmpty set1.Tree then set2 (* 0 U B = B *) + else Set(set1.Comparer, SetTree.union set1.Comparer set1.Tree set2.Tree) static member Intersection(a: Set<'T>, b: Set<'T>) : Set<'T> = - match b.Tree with - | SetEmpty -> b (* A INTER 0 = 0 *) - | _ -> - match a.Tree with - | SetEmpty -> a (* 0 INTER B = 0 *) - | _ -> Set(a.Comparer, SetTree.intersection a.Comparer a.Tree b.Tree) + if SetTree.isEmpty b.Tree then b (* A INTER 0 = 0 *) + else + if SetTree.isEmpty a.Tree then a (* 0 INTER B = 0 *) + else Set(a.Comparer, SetTree.intersection a.Comparer a.Tree b.Tree) static member Union(sets:seq>) : Set<'T> = Seq.fold (fun s1 s2 -> s1 + s2) Set<'T>.Empty sets @@ -688,7 +729,7 @@ type Set<[]'T when 'T: comparison >(comparer:IComparer<'T let mutable res = 0 for x in this do res <- combineHash res (hash x) - abs res + res override this.GetHashCode() = this.ComputeHashCode() diff --git a/src/fsharp/FSharp.Core/set.fsi b/src/fsharp/FSharp.Core/set.fsi index 9293a523312..68506895666 100644 --- a/src/fsharp/FSharp.Core/set.fsi +++ b/src/fsharp/FSharp.Core/set.fsi @@ -2,335 +2,503 @@ namespace Microsoft.FSharp.Collections - open System - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - /// Immutable sets based on binary trees, where comparison is the - /// F# structural comparison function, potentially using implementations - /// of the IComparable interface on key values. - /// - /// See the Set module for further operations on sets. - /// - /// All members of this class are thread-safe and may be used concurrently from multiple threads. - [] - [] - type Set<[]'T when 'T : comparison> = - - /// Create a set containing elements drawn from the given sequence. - /// The input sequence. - /// The result set. - new : elements:seq<'T> -> Set<'T> - - /// A useful shortcut for Set.add. Note this operation produces a new set - /// and does not mutate the original set. The new set will share many storage - /// nodes with the original. See the Set module for further operations on sets. - /// The value to add to the set. - /// The result set. - member Add : value:'T -> Set<'T> - - /// A useful shortcut for Set.remove. Note this operation produces a new set - /// and does not mutate the original set. The new set will share many storage - /// nodes with the original. See the Set module for further operations on sets. - /// The value to remove from the set. - /// The result set. - member Remove : value:'T -> Set<'T> - - /// The number of elements in the set - member Count : int - - /// A useful shortcut for Set.contains. See the Set module for further operations on sets. - /// The value to check. - /// True if the set contains value. - member Contains : value:'T -> bool - - /// A useful shortcut for Set.isEmpty. See the Set module for further operations on sets. - member IsEmpty : bool - - /// Returns a new set with the elements of the second set removed from the first. - /// The first input set. - /// The second input set. - /// A set containing elements of the first set that are not contained in the second set. - static member (-) : set1:Set<'T> * set2:Set<'T> -> Set<'T> - - /// Compute the union of the two sets. - /// The first input set. - /// The second input set. - /// The union of the two input sets. - static member (+) : set1:Set<'T> * set2:Set<'T> -> Set<'T> - - - /// Evaluates to "true" if all elements of the first set are in the second. - /// The set to test against. - /// True if this set is a subset of otherSet. - member IsSubsetOf: otherSet:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the first set are in the second, and at least - /// one element of the second is not in the first. - /// The set to test against. - /// True if this set is a proper subset of otherSet. - member IsProperSubsetOf: otherSet:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the second set are in the first. - /// The set to test against. - /// True if this set is a superset of otherSet. - member IsSupersetOf: otherSet:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the second set are in the first, and at least - /// one element of the first is not in the second. - /// The set to test against. - /// True if this set is a proper superset of otherSet. - member IsProperSupersetOf: otherSet:Set<'T> -> bool - - - /// Returns the lowest element in the set according to the ordering being used for the set. - member MinimumElement: 'T - - /// Returns the highest element in the set according to the ordering being used for the set. - member MaximumElement: 'T - - interface ICollection<'T> - interface IEnumerable<'T> - interface System.Collections.IEnumerable - interface System.IComparable - interface IReadOnlyCollection<'T> - override Equals : obj -> bool +open System +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +/// Immutable sets based on binary trees, where elements are ordered by F# generic comparison. By default +/// comparison is the F# structural comparison function or uses implementations of the IComparable interface on element values. +/// +/// See the module for further operations on sets. +/// +/// All members of this class are thread-safe and may be used concurrently from multiple threads. +[] +[] +type Set<[]'T when 'T : comparison> = + + /// Create a set containing elements drawn from the given sequence. + /// The input sequence. + /// + /// The result set. + /// + /// + new : elements:seq<'T> -> Set<'T> + + /// A useful shortcut for Set.add. Note this operation produces a new set + /// and does not mutate the original set. The new set will share many storage + /// nodes with the original. See the Set module for further operations on sets. + /// + /// The value to add to the set. + /// + /// The result set. + /// + /// + member Add : value:'T -> Set<'T> + + /// A useful shortcut for Set.remove. Note this operation produces a new set + /// and does not mutate the original set. The new set will share many storage + /// nodes with the original. See the Set module for further operations on sets. + /// + /// The value to remove from the set. + /// + /// The result set. + /// + /// + member Remove : value:'T -> Set<'T> + + /// The number of elements in the set + /// + /// + member Count : int + + /// A useful shortcut for Set.contains. See the Set module for further operations on sets. + /// + /// The value to check. + /// + /// True if the set contains value. + /// + /// + member Contains : value:'T -> bool + + /// A useful shortcut for Set.isEmpty. See the Set module for further operations on sets. + /// + /// + member IsEmpty : bool + + /// Returns a new set with the elements of the second set removed from the first. + /// + /// The first input set. + /// The second input set. + /// + /// A set containing elements of the first set that are not contained in the second set. + /// + /// + static member (-) : set1:Set<'T> * set2:Set<'T> -> Set<'T> + /// Compute the union of the two sets. + /// + /// The first input set. + /// The second input set. + /// + /// The union of the two input sets. + /// + /// + static member (+) : set1:Set<'T> * set2:Set<'T> -> Set<'T> + + /// Evaluates to "true" if all elements of the first set are in the second. + /// + /// The set to test against. + /// + /// True if this set is a subset of otherSet. + /// + /// + member IsSubsetOf: otherSet:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the first set are in the second, and at least + /// one element of the second is not in the first. + /// + /// The set to test against. + /// + /// True if this set is a proper subset of otherSet. + /// + /// + member IsProperSubsetOf: otherSet:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the second set are in the first. + /// + /// The set to test against. + /// + /// True if this set is a superset of otherSet. + /// + /// + member IsSupersetOf: otherSet:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the second set are in the first, and at least + /// one element of the first is not in the second. + /// + /// The set to test against. + /// + /// True if this set is a proper superset of otherSet. + /// + /// + member IsProperSupersetOf: otherSet:Set<'T> -> bool + + /// Returns the lowest element in the set according to the ordering being used for the set. + /// + /// + member MinimumElement: 'T + + /// Returns the highest element in the set according to the ordering being used for the set. + /// + /// + member MaximumElement: 'T + + interface ICollection<'T> + interface IEnumerable<'T> + interface System.Collections.IEnumerable + interface System.IComparable + interface IReadOnlyCollection<'T> + override Equals : obj -> bool namespace Microsoft.FSharp.Collections - - open System - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - [] - [] - - /// Functional programming operators related to the Set<_> type. - module Set = - - /// The empty set for the type 'T. - [] - [] - val empty<'T> : Set<'T> when 'T : comparison - - /// The set containing the given element. - /// The value for the set to contain. - /// The set containing value. - [] - val singleton: value:'T -> Set<'T> - - /// Returns a new set with an element added to the set. No exception is raised if - /// the set already contains the given element. - /// The value to add. - /// The input set. - /// A new set containing value. - [] - val add: value:'T -> set:Set<'T> -> Set<'T> - - /// Evaluates to "true" if the given element is in the given set. - /// The element to test. - /// The input set. - /// True if element is in set. - [] - val contains: element:'T -> set:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the first set are in the second - /// The potential subset. - /// The set to test against. - /// True if set1 is a subset of set2. - [] - val isSubset: set1: Set<'T> -> set2:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the first set are in the second, and at least - /// one element of the second is not in the first. - /// The potential subset. - /// The set to test against. - /// True if set1 is a proper subset of set2. - [] - val isProperSubset: set1: Set<'T> -> set2:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the second set are in the first. - /// The potential superset. - /// The set to test against. - /// True if set1 is a superset of set2. - [] - val isSuperset: set1: Set<'T> -> set2:Set<'T> -> bool - - /// Evaluates to "true" if all elements of the second set are in the first, and at least - /// one element of the first is not in the second. - /// The potential superset. - /// The set to test against. - /// True if set1 is a proper superset of set2. - [] - val isProperSuperset: set1: Set<'T> -> set2:Set<'T> -> bool - - - /// Returns the number of elements in the set. Same as size. - /// The input set. - /// The number of elements in the set. - [] - val count: set:Set<'T> -> int - - /// Tests if any element of the collection satisfies the given predicate. - /// If the input function is predicate and the elements are i0...iN - /// then computes p i0 or ... or p iN. - /// The function to test set elements. - /// The input set. - /// True if any element of set satisfies predicate. - [] - val exists: predicate:('T -> bool) -> set:Set<'T> -> bool - - /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns True. - /// The function to test set elements. - /// The input set. - /// The set containing only the elements for which predicate returns true. - [] - val filter: predicate:('T -> bool) -> set:Set<'T> -> Set<'T> - - /// Returns a new collection containing the results of applying the - /// given function to each element of the input set. - /// The function to transform elements of the input set. - /// The input set. - /// A set containing the transformed elements. - [] - val map: mapping:('T -> 'U) -> set:Set<'T> -> Set<'U> - - /// Applies the given accumulating function to all the elements of the set - /// The accumulating function. - /// The initial state. - /// The input set. - /// The final state. - [] - val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> set:Set<'T> -> 'State when 'T : comparison - - /// Applies the given accumulating function to all the elements of the set. - /// The accumulating function. - /// The input set. - /// The initial state. - /// The final state. - [] - val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> set:Set<'T> -> state:'State -> 'State when 'T : comparison - - /// Tests if all elements of the collection satisfy the given predicate. - /// If the input function is f and the elements are i0...iN and "j0...jN" - /// then computes p i0 && ... && p iN. - /// The function to test set elements. - /// The input set. - /// True if all elements of set satisfy predicate. - [] - val forall: predicate:('T -> bool) -> set:Set<'T> -> bool - - /// Computes the intersection of the two sets. - /// The first input set. - /// The second input set. - /// The intersection of set1 and set2. - [] - val intersect: set1:Set<'T> -> set2:Set<'T> -> Set<'T> - - /// Computes the intersection of a sequence of sets. The sequence must be non-empty. - /// The sequence of sets to intersect. - /// The intersection of the input sets. - [] - val intersectMany: sets:seq> -> Set<'T> - - /// Computes the union of the two sets. - /// The first input set. - /// The second input set. - /// The union of set1 and set2. - [] - val union: set1:Set<'T> -> set2:Set<'T> -> Set<'T> - - /// Computes the union of a sequence of sets. - /// The sequence of sets to union. - /// The union of the input sets. - [] - val unionMany: sets:seq> -> Set<'T> - - /// Returns "true" if the set is empty. - /// The input set. - /// True if set is empty. - [] - val isEmpty: set:Set<'T> -> bool - - /// Applies the given function to each element of the set, in order according - /// to the comparison function. - /// The function to apply to each element. - /// The input set. - [] - val iter: action:('T -> unit) -> set:Set<'T> -> unit - - /// Splits the set into two sets containing the elements for which the given predicate - /// returns true and false respectively. - /// The function to test set elements. - /// The input set. - /// A pair of sets with the first containing the elements for which predicate returns - /// true and the second containing the elements for which predicate returns false. - [] - val partition: predicate:('T -> bool) -> set:Set<'T> -> (Set<'T> * Set<'T>) - - /// Returns a new set with the given element removed. No exception is raised if - /// the set doesn't contain the given element. - /// The element to remove. - /// The input set. - /// The input set with value removed. - [] - val remove: value: 'T -> set:Set<'T> -> Set<'T> - - /// Returns the lowest element in the set according to the ordering being used for the set. - /// The input set. - /// The min value from the set. - [] - val minElement: set:Set<'T> -> 'T - - /// Returns the highest element in the set according to the ordering being used for the set. - /// The input set. - /// The max value from the set. - [] - val maxElement: set:Set<'T> -> 'T - - /// Builds a set that contains the same elements as the given list. - /// The input list. - /// A set containing the elements form the input list. - [] - val ofList: elements:'T list -> Set<'T> - - /// Builds a list that contains the elements of the set in order. - /// The input set. - /// An ordered list of the elements of set. - [] - val toList: set:Set<'T> -> 'T list - - /// Builds a set that contains the same elements as the given array. - /// The input array. - /// A set containing the elements of array. - [] - val ofArray: array:'T[] -> Set<'T> - - /// Builds an array that contains the elements of the set in order. - /// The input set. - /// An ordered array of the elements of set. - [] - val toArray: set:Set<'T> -> 'T[] - - /// Returns an ordered view of the collection as an enumerable object. - /// The input set. - /// An ordered sequence of the elements of set. - [] - val toSeq: set:Set<'T> -> seq<'T> - - /// Builds a new collection from the given enumerable object. - /// The input sequence. - /// The set containing elements. - [] - val ofSeq: elements:seq<'T> -> Set<'T> - - /// Returns a new set with the elements of the second set removed from the first. - /// The first input set. - /// The set whose elements will be removed from set1. - /// The set with the elements of set2 removed from set1. - [] - val difference: set1:Set<'T> -> set2:Set<'T> -> Set<'T> + +open System +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Collections + +[] +[] + +/// Contains operations for working with values of type . +module Set = + + /// The empty set for the type 'T. + /// + /// + [] + [] + val empty<'T> : Set<'T> when 'T : comparison + + /// The set containing the given element. + /// + /// The value for the set to contain. + /// + /// The set containing value. + /// + /// + [] + val singleton: value:'T -> Set<'T> + + /// Returns a new set with an element added to the set. No exception is raised if + /// the set already contains the given element. + /// + /// The value to add. + /// The input set. + /// + /// A new set containing value. + /// + /// + [] + val add: value:'T -> set:Set<'T> -> Set<'T> + + /// Evaluates to "true" if the given element is in the given set. + /// + /// The element to test. + /// The input set. + /// + /// True if element is in set. + /// + /// + [] + val contains: element:'T -> set:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the first set are in the second + /// + /// The potential subset. + /// The set to test against. + /// + /// True if set1 is a subset of set2. + /// + /// + [] + val isSubset: set1: Set<'T> -> set2:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the first set are in the second, and at least + /// one element of the second is not in the first. + /// + /// The potential subset. + /// The set to test against. + /// + /// True if set1 is a proper subset of set2. + /// + /// + [] + val isProperSubset: set1: Set<'T> -> set2:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the second set are in the first. + /// + /// The potential superset. + /// The set to test against. + /// + /// True if set1 is a superset of set2. + /// + /// + [] + val isSuperset: set1: Set<'T> -> set2:Set<'T> -> bool + + /// Evaluates to "true" if all elements of the second set are in the first, and at least + /// one element of the first is not in the second. + /// + /// The potential superset. + /// The set to test against. + /// + /// True if set1 is a proper superset of set2. + /// + /// + [] + val isProperSuperset: set1: Set<'T> -> set2:Set<'T> -> bool + + + /// Returns the number of elements in the set. Same as size. + /// + /// The input set. + /// + /// The number of elements in the set. + /// + /// + [] + val count: set:Set<'T> -> int + + /// Tests if any element of the collection satisfies the given predicate. + /// If the input function is predicate and the elements are i0...iN + /// then computes p i0 or ... or p iN. + /// + /// The function to test set elements. + /// The input set. + /// + /// True if any element of set satisfies predicate. + /// + /// + [] + val exists: predicate:('T -> bool) -> set:Set<'T> -> bool + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns True. + /// + /// The function to test set elements. + /// The input set. + /// + /// The set containing only the elements for which predicate returns true. + /// + /// + [] + val filter: predicate:('T -> bool) -> set:Set<'T> -> Set<'T> + + /// Returns a new collection containing the results of applying the + /// given function to each element of the input set. + /// + /// The function to transform elements of the input set. + /// The input set. + /// + /// A set containing the transformed elements. + /// + /// + [] + val map: mapping:('T -> 'U) -> set:Set<'T> -> Set<'U> + + /// Applies the given accumulating function to all the elements of the set + /// + /// The accumulating function. + /// The initial state. + /// The input set. + /// + /// The final state. + /// + /// + [] + val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> set:Set<'T> -> 'State when 'T : comparison + + /// Applies the given accumulating function to all the elements of the set. + /// + /// The accumulating function. + /// The input set. + /// The initial state. + /// + /// The final state. + /// + /// + [] + val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> set:Set<'T> -> state:'State -> 'State when 'T : comparison + + /// Tests if all elements of the collection satisfy the given predicate. + /// If the input function is f and the elements are i0...iN and "j0...jN" + /// then computes p i0 && ... && p iN. + /// + /// The function to test set elements. + /// The input set. + /// + /// True if all elements of set satisfy predicate. + /// + /// + [] + val forall: predicate:('T -> bool) -> set:Set<'T> -> bool + + /// Computes the intersection of the two sets. + /// + /// The first input set. + /// The second input set. + /// + /// The intersection of set1 and set2. + /// + /// + [] + val intersect: set1:Set<'T> -> set2:Set<'T> -> Set<'T> + + /// Computes the intersection of a sequence of sets. The sequence must be non-empty. + /// + /// The sequence of sets to intersect. + /// + /// The intersection of the input sets. + /// + /// + [] + val intersectMany: sets:seq> -> Set<'T> + + /// Computes the union of the two sets. + /// + /// The first input set. + /// The second input set. + /// + /// The union of set1 and set2. + /// + /// + [] + val union: set1:Set<'T> -> set2:Set<'T> -> Set<'T> + + /// Computes the union of a sequence of sets. + /// + /// The sequence of sets to union. + /// + /// The union of the input sets. + /// + /// + [] + val unionMany: sets:seq> -> Set<'T> + + /// Returns "true" if the set is empty. + /// + /// The input set. + /// + /// True if set is empty. + /// + /// + [] + val isEmpty: set:Set<'T> -> bool + + /// Applies the given function to each element of the set, in order according + /// to the comparison function. + /// + /// The function to apply to each element. + /// The input set. + /// + /// + [] + val iter: action:('T -> unit) -> set:Set<'T> -> unit + + /// Splits the set into two sets containing the elements for which the given predicate + /// returns true and false respectively. + /// + /// The function to test set elements. + /// The input set. + /// + /// A pair of sets with the first containing the elements for which predicate returns + /// true and the second containing the elements for which predicate returns false. + /// + /// + [] + val partition: predicate:('T -> bool) -> set:Set<'T> -> (Set<'T> * Set<'T>) + + /// Returns a new set with the given element removed. No exception is raised if + /// the set doesn't contain the given element. + /// + /// The element to remove. + /// The input set. + /// + /// The input set with value removed. + /// + /// + [] + val remove: value: 'T -> set:Set<'T> -> Set<'T> + + /// Returns the lowest element in the set according to the ordering being used for the set. + /// + /// The input set. + /// + /// The min value from the set. + /// + /// + [] + val minElement: set:Set<'T> -> 'T + + /// Returns the highest element in the set according to the ordering being used for the set. + /// + /// The input set. + /// + /// The max value from the set. + /// + /// + [] + val maxElement: set:Set<'T> -> 'T + + /// Builds a set that contains the same elements as the given list. + /// + /// The input list. + /// + /// A set containing the elements form the input list. + /// + /// + [] + val ofList: elements:'T list -> Set<'T> + + /// Builds a list that contains the elements of the set in order. + /// + /// The input set. + /// + /// An ordered list of the elements of set. + /// + /// + [] + val toList: set:Set<'T> -> 'T list + + /// Builds a set that contains the same elements as the given array. + /// + /// The input array. + /// + /// A set containing the elements of array. + /// + /// + [] + val ofArray: array:'T[] -> Set<'T> + + /// Builds an array that contains the elements of the set in order. + /// + /// The input set. + /// + /// An ordered array of the elements of set. + /// + /// + [] + val toArray: set:Set<'T> -> 'T[] + + /// Returns an ordered view of the collection as an enumerable object. + /// + /// The input set. + /// + /// An ordered sequence of the elements of set. + /// + /// + [] + val toSeq: set:Set<'T> -> seq<'T> + + /// Builds a new collection from the given enumerable object. + /// + /// The input sequence. + /// + /// The set containing elements. + /// + /// + [] + val ofSeq: elements:seq<'T> -> Set<'T> + + /// Returns a new set with the elements of the second set removed from the first. + /// + /// The first input set. + /// The set whose elements will be removed from set1. + /// + /// The set with the elements of set2 removed from set1. + /// + /// + [] + val difference: set1:Set<'T> -> set2:Set<'T> -> Set<'T> diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index e620e4cac6a..37e8fcd7d68 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -8,13 +8,40 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Core.Operators open Microsoft.FSharp.Core.Operators.Checked open Microsoft.FSharp.Collections + open Microsoft.FSharp.Primitives.Basics [] [] module String = + [] + /// LOH threshold is calculated from Internal.Utilities.Library.LOH_SIZE_THRESHOLD_BYTES, + /// and is equal to 80_000 / sizeof + let LOH_CHAR_THRESHOLD = 40_000 + + [] + let length (str:string) = if isNull str then 0 else str.Length + [] let concat sep (strings : seq) = - String.Join(sep, strings) + + let concatArray sep (strings: string []) = + match length sep with + | 0 -> String.Concat strings + // following line should be used when this overload becomes part of .NET Standard (it's only in .NET Core) + //| 1 -> String.Join(sep.[0], strings, 0, strings.Length) + | _ -> String.Join(sep, strings, 0, strings.Length) + + match strings with + | :? array as arr -> + concatArray sep arr + + | :? list as lst -> + lst + |> List.toArray + |> concatArray sep + + | _ -> + String.Join(sep, strings) [] let iter (action : (char -> unit)) (str:string) = @@ -34,29 +61,56 @@ namespace Microsoft.FSharp.Core if String.IsNullOrEmpty str then String.Empty else - let res = StringBuilder str.Length - str |> iter (fun c -> res.Append(mapping c) |> ignore) - res.ToString() + let result = str.ToCharArray() + let mutable i = 0 + for c in result do + result.[i] <- mapping c + i <- i + 1 + + new String(result) [] let mapi (mapping: int -> char -> char) (str:string) = - if String.IsNullOrEmpty str then + let len = length str + if len = 0 then String.Empty else - let res = StringBuilder str.Length + let result = str.ToCharArray() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(mapping) - str |> iteri (fun i c -> res.Append(f.Invoke(i, c)) |> ignore) - res.ToString() + + let mutable i = 0 + while i < len do + result.[i] <- f.Invoke(i, result.[i]) + i <- i + 1 + + new String(result) [] let filter (predicate: char -> bool) (str:string) = - if String.IsNullOrEmpty str then + let len = length str + + if len = 0 then String.Empty - else - let res = StringBuilder str.Length + + elif len > LOH_CHAR_THRESHOLD then + // By using SB here, which is twice slower than the optimized path, we prevent LOH allocations + // and 'stop the world' collections if the filtering results in smaller strings. + // We also don't pre-allocate SB here, to allow for less mem pressure when filter result is small. + let res = StringBuilder() str |> iter (fun c -> if predicate c then res.Append c |> ignore) res.ToString() + else + // Must do it this way, since array.fs is not yet in scope, but this is safe + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len + let mutable i = 0 + for c in str do + if predicate c then + target.[i] <- c + i <- i + 1 + + String(target, 0, i) + [] let collect (mapping: char -> string) (str:string) = if String.IsNullOrEmpty str then @@ -78,13 +132,38 @@ namespace Microsoft.FSharp.Core let replicate (count:int) (str:string) = if count < 0 then invalidArgInputMustBeNonNegative "count" count - if String.IsNullOrEmpty str then + let len = length str + if len = 0 || count = 0 then String.Empty + + elif len = 1 then + new String(str.[0], count) + + elif count <= 4 then + match count with + | 1 -> str + | 2 -> String.Concat(str, str) + | 3 -> String.Concat(str, str, str) + | _ -> String.Concat(str, str, str, str) + else - let res = StringBuilder(count * str.Length) - for i = 0 to count - 1 do - res.Append str |> ignore - res.ToString() + // Using the primitive, because array.fs is not yet in scope. It's safe: both len and count are positive. + let target = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (len * count) + let source = str.ToCharArray() + + // O(log(n)) performance loop: + // Copy first string, then keep copying what we already copied + // (i.e., doubling it) until we reach or pass the halfway point + Array.Copy(source, 0, target, 0, len) + let mutable i = len + while i * 2 < target.Length do + Array.Copy(target, 0, target, i, i) + i <- i * 2 + + // finally, copy the remain half, or less-then half + Array.Copy(target, 0, target, i, target.Length - i) + new String(target) + [] let forall predicate (str:string) = @@ -101,10 +180,3 @@ namespace Microsoft.FSharp.Core else let rec check i = (i < str.Length) && (predicate str.[i] || check (i+1)) check 0 - - [] - let length (str:string) = - if String.IsNullOrEmpty str then - 0 - else - str.Length diff --git a/src/fsharp/FSharp.Core/string.fsi b/src/fsharp/FSharp.Core/string.fsi index 59217506a6b..0bae31c3cb1 100644 --- a/src/fsharp/FSharp.Core/string.fsi +++ b/src/fsharp/FSharp.Core/string.fsi @@ -10,107 +10,280 @@ namespace Microsoft.FSharp.Core /// Functional programming operators for string processing. Further string operations /// are available via the member functions on strings and other functionality in /// System.String - /// and System.Text.RegularExpressions types. + /// and System.Text.RegularExpressions types. + /// + /// + /// Strings and Text [] [] module String = + /// Builds a new string whose characters are the results of applying the function mapping + /// to each of the characters of the input string and concatenating the resulting + /// strings. + /// + /// The function to produce a string from each character of the input string. + /// The input string. + /// + /// The concatenated string. + /// + /// The following samples shows how to interspace spaces in a text + /// + /// let input = "Stefan says: Hi!" + /// + /// input |> String.collect (sprintf "%c ") + /// + /// The sample evaluates to "S t e f a n s a y s : H i ! " + /// + /// + /// How to show the ASCII representation of a very secret text + /// + /// "Secret" |> String.collect (fun chr -> int chr |> sprintf "%d ") + /// + /// The sample evaluates to "83 101 99 114 101 116 " + /// + [] + val collect: mapping:(char -> string) -> str:string -> string + /// Returns a new string made by concatenating the given strings /// with separator sep, that is a1 + sep + ... + sep + aN. /// The separator string to be inserted between the strings /// of the input sequence. /// The sequence of strings to be concatenated. + /// /// A new string consisting of the concatenated strings separated by /// the separation string. - /// Thrown when strings is null. + /// Thrown when strings is null. + /// + /// + /// + /// let input1 = ["Stefan"; "says:"; "Hello"; "there!"] + /// + /// input1 |> String.concat " " // evaluates "Stefan says: Hello there!" + /// + /// let input2 = [0..9] |> List.map string + /// + /// input2 |> String.concat "" // evaluates "0123456789" + /// input2 |> String.concat ", " // evaluates "0, 1, 2, 3, 4, 5, 6, 7, 8, 9" + /// + /// let input3 = ["No comma"] + /// + /// input3 |> String.concat "," // evaluates "No comma" + /// + /// [] val concat: sep:string -> strings: seq -> string + /// Tests if any character of the string satisfies the given predicate. + /// + /// The function to test each character of the string. + /// The input string. + /// + /// True if any character returns true for the predicate and false otherwise. + /// + /// Looking for uppercase characters + /// + /// open System + /// + /// "Yoda" |> String.exists Char.IsUpper // evaluates true + /// + /// "nope" |> String.exists Char.IsUpper // evaluates false + /// + /// + [] + val exists: predicate:(char -> bool) -> str:string -> bool + + /// Builds a new string containing only the characters of the input string + /// for which the given predicate returns "true". + /// + /// Returns an empty string if the input string is null + /// + /// A function to test whether each character in the input sequence should be included in the output string. + /// The input string. + /// + /// The resulting string. + /// + /// Filtering out just alphanumeric characters + /// + /// open System + /// + /// let input = "0 1 2 3 4 5 6 7 8 9 a A m M" + /// + /// input |> String.filter Uri.IsHexDigit // evaluates "123456789aA" + /// + /// + /// Filtering out just digits + /// + /// open System + /// + /// "hello" |> String.filter Char.IsDigit // evaluates "" + /// + /// + [] + val filter: predicate:(char -> bool) -> str:string -> string + + /// Tests if all characters in the string satisfy the given predicate. + /// + /// The function to test each character of the string. + /// The input string. + /// + /// True if all characters return true for the predicate and false otherwise. + /// + /// Looking for lowercase characters + /// + /// open System + /// + /// "all are lower" |> String.forall Char.IsLower // evaluates false + /// + /// "allarelower" |> String.forall Char.IsLower // evaluates true + /// + /// + [] + val forall: predicate:(char -> bool) -> str:string -> bool + + /// Builds a new string whose characters are the results of applying the function mapping + /// to each index from 0 to count-1 and concatenating the resulting + /// strings. + /// + /// The number of strings to initialize. + /// The function to take an index and produce a string to + /// be concatenated with the others. + /// + /// The constructed string. + /// + /// Thrown when count is negative. + /// + /// Enumerate digits ASCII codes + /// + /// String.init 10 (fun i -> int '0' + i |> sprintf "%d ") + /// + /// The sample evaluates to: "48 49 50 51 52 53 54 55 56 57 " + /// + [] + val init: count:int -> initializer:(int -> string) -> string + /// Applies the function action to each character in the string. + /// /// The function to be applied to each character of the string. /// The input string. + /// + /// Printing the ASCII code for each characater in the string + /// + /// let input = "Hello" + /// input |> String.iter (fun c -> printfn "%c %d" c (int c)) + /// + /// The sample evaluates as unit, but prints: + /// + /// H 72 + /// e 101 + /// l 108 + /// l 108 + /// o 111 + /// + /// [] val iter: action:(char -> unit) -> str:string -> unit /// Applies the function action to the index of each character in the string and the /// character itself. + /// /// The function to apply to each character and index of the string. /// The input string. + /// + /// Numbering the characters and printing the associated ASCII code + /// for each characater in the input string + /// + /// let input = "Hello" + /// input |> String.iteri (fun i c -> printfn "%d. %c %d" (i + 1) c (int c)) + /// + /// The sample evaluates as unit, but prints: + /// + /// 1. H 72 + /// 2. e 101 + /// 3. l 108 + /// 4. l 108 + /// 5. o 111 + /// + /// [] val iteri: action:(int -> char -> unit) -> str:string -> unit + /// Returns the length of the string. + /// + /// The input string. + /// + /// The number of characters in the string. + /// + /// Getting the length of different strings + /// + /// String.length null // evaluates 0 + /// String.length "" // evaluates 0 + /// String.length "123" // evaluates 3 + /// + /// + [] + val length: str:string -> int + /// Builds a new string whose characters are the results of applying the function mapping /// to each of the characters of the input string. + /// /// The function to apply to the characters of the string. /// The input string. + /// /// The resulting string. + /// + /// Changing case to upper for all characters in the input string + /// + /// open System + /// + /// let input = "Hello there!" + /// + /// input |> String.map Char.ToUpper // evaluates "HELLO THERE!" + /// + /// [] val map: mapping:(char -> char) -> str:string -> string /// Builds a new string whose characters are the results of applying the function mapping /// to each character and index of the input string. + /// /// The function to apply to each character and index of the string. /// The input string. + /// /// The resulting string. + /// + /// Alternating case for all characters in the input string + /// + /// open System + /// + /// let alternateCase indx chr = + /// if 0 = indx % 2 then + /// Char.ToUpper chr + /// else + /// Char.ToLower chr + /// + /// let input = "Hello there!" + /// + /// input |> String.mapi alternateCase // evaluates "HeLlO ThErE!" + /// + /// [] val mapi: mapping:(int -> char -> char) -> str:string -> string - /// Builds a new string whose characters are the results of applying the function mapping - /// to each of the characters of the input string and concatenating the resulting - /// strings. - /// The function to produce a string from each character of the input string. - /// The input string. - /// The concatenated string. - [] - val collect: mapping:(char -> string) -> str:string -> string - - /// Builds a new string containing only the characters of the input string - /// for which the given predicate returns "true". - /// - /// Returns an empty string if the input string is null - /// - /// A function to test whether each character in the input sequence should be included in the output string. - /// The input string. - /// The resulting string. - [] - val filter: predicate:(char -> bool) -> str:string -> string - - /// Builds a new string whose characters are the results of applying the function mapping - /// to each index from 0 to count-1 and concatenating the resulting - /// strings. - /// The number of strings to initialize. - /// The function to take an index and produce a string to - /// be concatenated with the others. - /// The constructed string. - /// Thrown when count is negative. - [] - val init: count:int -> initializer:(int -> string) -> string - - /// Tests if all characters in the string satisfy the given predicate. - /// The function to test each character of the string. - /// The input string. - /// True if all characters return true for the predicate and false otherwise. - [] - val forall: predicate:(char -> bool) -> str:string -> bool - - /// Tests if any character of the string satisfies the given predicate. - /// The function to test each character of the string. - /// The input string. - /// True if any character returns true for the predicate and false otherwise. - [] - val exists: predicate:(char -> bool) -> str:string -> bool - /// Returns a string by concatenating count instances of str. + /// /// The number of copies of the input string will be copied. /// The input string. + /// /// The concatenated string. - /// Thrown when count is negative. + /// Thrown when count is negative. + /// + /// + /// + /// "Do it!" |> String.replicate 3 // evaluates "Do it!Do it!Do it!" + /// + /// [] val replicate: count:int -> str: string -> string - - /// Returns the length of the string. - /// The input string. - /// The number of characters in the string. - [] - val length: str:string -> int + diff --git a/src/fsharp/FSharp.Core/tasks.fs b/src/fsharp/FSharp.Core/tasks.fs new file mode 100644 index 00000000000..e0032a24aaa --- /dev/null +++ b/src/fsharp/FSharp.Core/tasks.fs @@ -0,0 +1,384 @@ +// Task builder for F# that compiles to allocation-free paths for synchronous code. +// +// Originally written in 2016 by Robert Peele (humbobst@gmail.com) +// New operator-based overload resolution for F# 4.0 compatibility by Gustavo Leon in 2018. +// Revised for insertion into FSHarp.Core by Microsoft, 2019. +// +// Original notice: +// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights +// to this software to the public domain worldwide. This software is distributed without any warranty. +// +// Updates: +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Control + + #if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE + open System + open System.Runtime.CompilerServices + open System.Threading + open System.Threading.Tasks + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open Microsoft.FSharp.Control + open Microsoft.FSharp.Collections + + /// The extra data stored in ResumableStateMachine for tasks + [] + type TaskStateMachineData<'T> = + + [] + val mutable Result : 'T + + [] + val mutable MethodBuilder : AsyncTaskMethodBuilder<'T> + + and TaskStateMachine<'TOverall> = ResumableStateMachine> + and TaskResumptionFunc<'TOverall> = ResumptionFunc> + and TaskResumptionDynamicInfo<'TOverall> = ResumptionDynamicInfo> + and TaskCode<'TOverall, 'T> = ResumableCode, 'T> + + type TaskBuilderBase() = + + member inline _.Delay(f : unit -> TaskCode<'TOverall, 'T>) : TaskCode<'TOverall, 'T> = + TaskCode<'TOverall, 'T>(fun sm -> (f()).Invoke(&sm)) + + /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression. + [] + member inline _.Zero() : TaskCode<'TOverall, unit> = ResumableCode.Zero() + + member inline _.Return (value: 'T) : TaskCode<'T, 'T> = + TaskCode<'T, _>(fun sm -> + sm.Data.Result <- value + true) + + /// Chains together a step with its following step. + /// Note that this requires that the first step has no result. + /// This prevents constructs like `task { return 1; return 2; }`. + member inline _.Combine(task1: TaskCode<'TOverall, unit>, task2: TaskCode<'TOverall, 'T>) : TaskCode<'TOverall, 'T> = + ResumableCode.Combine(task1, task2) + + /// Builds a step that executes the body while the condition predicate is true. + member inline _.While ([] condition : unit -> bool, body : TaskCode<'TOverall, unit>) : TaskCode<'TOverall, unit> = + ResumableCode.While(condition, body) + + /// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + member inline _.TryWith (body: TaskCode<'TOverall, 'T>, catch: exn -> TaskCode<'TOverall, 'T>) : TaskCode<'TOverall, 'T> = + ResumableCode.TryWith(body, catch) + + /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + member inline _.TryFinally (body: TaskCode<'TOverall, 'T>, [] compensation : unit -> unit) : TaskCode<'TOverall, 'T> = + ResumableCode.TryFinally(body, ResumableCode<_,_>(fun _sm -> compensation(); true)) + + member inline _.For (sequence : seq<'T>, body : 'T -> TaskCode<'TOverall, unit>) : TaskCode<'TOverall, unit> = + ResumableCode.For(sequence, body) + + #if NETSTANDARD2_1 + member inline internal this.TryFinallyAsync(body: TaskCode<'TOverall, 'T>, compensation : unit -> ValueTask) : TaskCode<'TOverall, 'T> = + ResumableCode.TryFinallyAsync(body, ResumableCode<_,_>(fun sm -> + if __useResumableCode then + let mutable __stack_condition_fin = true + let __stack_vtask = compensation() + if not __stack_vtask.IsCompleted then + let mutable awaiter = __stack_vtask.GetAwaiter() + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_condition_fin <- __stack_yield_fin + + if not __stack_condition_fin then + sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm) + + __stack_condition_fin + else + let vtask = compensation() + let mutable awaiter = vtask.GetAwaiter() + + let cont = + TaskResumptionFunc<'TOverall>( fun sm -> + awaiter.GetResult() |> ignore + true) + + // shortcut to continue immediately + if awaiter.IsCompleted then + true + else + sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion) + sm.ResumptionDynamicInfo.ResumptionFunc <- cont + false + )) + + member inline this.Using<'Resource, 'TOverall, 'T when 'Resource :> IAsyncDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) : TaskCode<'TOverall, 'T> = + this.TryFinallyAsync( + (fun sm -> (body resource).Invoke(&sm)), + (fun () -> + if not (isNull (box resource)) then + resource.DisposeAsync() + else + ValueTask())) + #endif + + + type TaskBuilder() = + + inherit TaskBuilderBase() + + // This is the dynamic implementation - this is not used + // for statically compiled tasks. An executor (resumptionFuncExecutor) is + // registered with the state machine, plus the initial resumption. + // The executor stays constant throughout the execution, it wraps each step + // of the execution in a try/with. The resumption is changed at each step + // to represent the continuation of the computation. + static member RunDynamic(code: TaskCode<'T, 'T>) : Task<'T> = + let mutable sm = TaskStateMachine<'T>() + let initialResumptionFunc = TaskResumptionFunc<'T>(fun sm -> code.Invoke(&sm)) + let resumptionInfo = + { new TaskResumptionDynamicInfo<'T>(initialResumptionFunc) with + member info.MoveNext(sm) = + let mutable savedExn = null + try + sm.ResumptionDynamicInfo.ResumptionData <- null + let step = info.ResumptionFunc.Invoke(&sm) + if step then + sm.Data.MethodBuilder.SetResult(sm.Data.Result) + else + let mutable awaiter = sm.ResumptionDynamicInfo.ResumptionData :?> ICriticalNotifyCompletion + assert not (isNull awaiter) + sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm) + + with exn -> + savedExn <- exn + // Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567 + match savedExn with + | null -> () + | exn -> sm.Data.MethodBuilder.SetException exn + + member _.SetStateMachine(sm, state) = + sm.Data.MethodBuilder.SetStateMachine(state) + } + sm.ResumptionDynamicInfo <- resumptionInfo + sm.Data.MethodBuilder <- AsyncTaskMethodBuilder<'T>.Create() + sm.Data.MethodBuilder.Start(&sm) + sm.Data.MethodBuilder.Task + + static member inline Run(code : TaskCode<'T, 'T>) : Task<'T> = + if __useResumableCode then + __stateMachine, Task<'T>> + (MoveNextMethodImpl<_>(fun sm -> + //-- RESUMABLE CODE START + __resumeAt sm.ResumptionPoint + let mutable __stack_exn : Exception = null + try + let __stack_code_fin = code.Invoke(&sm) + if __stack_code_fin then + sm.Data.MethodBuilder.SetResult(sm.Data.Result) + with exn -> + __stack_exn <- exn + // Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567 + match __stack_exn with + | null -> () + | exn -> sm.Data.MethodBuilder.SetException exn + //-- RESUMABLE CODE END + )) + (SetStateMachineMethodImpl<_>(fun sm state -> sm.Data.MethodBuilder.SetStateMachine(state))) + (AfterCode<_,_>(fun sm -> + sm.Data.MethodBuilder <- AsyncTaskMethodBuilder<'T>.Create() + sm.Data.MethodBuilder.Start(&sm) + sm.Data.MethodBuilder.Task)) + else + TaskBuilder.RunDynamic(code) + + member inline _.Run(code : TaskCode<'T, 'T>) : Task<'T> = + TaskBuilder.Run(code) + + type BackgroundTaskBuilder() = + + inherit TaskBuilderBase() + + static member RunDynamic(code: TaskCode<'T, 'T>) : Task<'T> = + // backgroundTask { .. } escapes to a background thread where necessary + // See spec of ConfigureAwait(false) at https://devblogs.microsoft.com/dotnet/configureawait-faq/ + if isNull SynchronizationContext.Current && obj.ReferenceEquals(TaskScheduler.Current, TaskScheduler.Default) then + TaskBuilder.RunDynamic(code) + else + Task.Run<'T>(fun () -> TaskBuilder.RunDynamic(code)) + + //// Same as TaskBuilder.Run except the start is inside Task.Run if necessary + member inline _.Run(code : TaskCode<'T, 'T>) : Task<'T> = + if __useResumableCode then + __stateMachine, Task<'T>> + (MoveNextMethodImpl<_>(fun sm -> + //-- RESUMABLE CODE START + __resumeAt sm.ResumptionPoint + try + let __stack_code_fin = code.Invoke(&sm) + if __stack_code_fin then + sm.Data.MethodBuilder.SetResult(sm.Data.Result) + with exn -> + sm.Data.MethodBuilder.SetException exn + //-- RESUMABLE CODE END + )) + (SetStateMachineMethodImpl<_>(fun sm state -> sm.Data.MethodBuilder.SetStateMachine(state))) + (AfterCode<_,Task<'T>>(fun sm -> + // backgroundTask { .. } escapes to a background thread where necessary + // See spec of ConfigureAwait(false) at https://devblogs.microsoft.com/dotnet/configureawait-faq/ + if isNull SynchronizationContext.Current && obj.ReferenceEquals(TaskScheduler.Current, TaskScheduler.Default) then + sm.Data.MethodBuilder <- AsyncTaskMethodBuilder<'T>.Create() + sm.Data.MethodBuilder.Start(&sm) + sm.Data.MethodBuilder.Task + else + let sm = sm // copy contents of state machine so we can capture it + Task.Run<'T>(fun () -> + let mutable sm = sm // host local mutable copy of contents of state machine on this thread pool thread + sm.Data.MethodBuilder <- AsyncTaskMethodBuilder<'T>.Create() + sm.Data.MethodBuilder.Start(&sm) + sm.Data.MethodBuilder.Task))) + else + BackgroundTaskBuilder.RunDynamic(code) + + module TaskBuilder = + + let task = TaskBuilder() + let backgroundTask = BackgroundTaskBuilder() + +namespace Microsoft.FSharp.Control.TaskBuilderExtensions + + open Microsoft.FSharp.Control + open System + open System.Runtime.CompilerServices + open System.Threading.Tasks + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + + module LowPriority = + // Low priority extensions + type TaskBuilderBase with + + static member inline BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'TResult1)> + (sm: byref<_>, task: ^TaskLike, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : bool = + + let mutable awaiter = (^TaskLike: (member GetAwaiter : unit -> ^Awaiter)(task)) + + let cont = + (TaskResumptionFunc<'TOverall>( fun sm -> + let result = (^Awaiter : (member GetResult : unit -> 'TResult1)(awaiter)) + (continuation result).Invoke(&sm))) + + // shortcut to continue immediately + if (^Awaiter : (member get_IsCompleted : unit -> bool)(awaiter)) then + cont.Invoke(&sm) + else + sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion) + sm.ResumptionDynamicInfo.ResumptionFunc <- cont + false + + member inline _.Bind< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'TResult1)> + (task: ^TaskLike, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + + TaskCode<'TOverall, _>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + // Get an awaiter from the awaitable + let mutable awaiter = (^TaskLike: (member GetAwaiter : unit -> ^Awaiter)(task)) + + let mutable __stack_fin = true + if not (^Awaiter : (member get_IsCompleted : unit -> bool)(awaiter)) then + // This will yield with __stack_yield_fin = false + // This will resume with __stack_yield_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_fin <- __stack_yield_fin + + if __stack_fin then + let result = (^Awaiter : (member GetResult : unit -> 'TResult1)(awaiter)) + (continuation result).Invoke(&sm) + else + sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm) + false + else + TaskBuilderBase.BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter , 'TOverall>(&sm, task, continuation) + //-- RESUMABLE CODE END + ) + + member inline this.ReturnFrom< ^TaskLike, ^Awaiter, 'T + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'T)> + (task: ^TaskLike) : TaskCode< 'T, 'T> = + + this.Bind(task, (fun v -> this.Return v)) + + member inline _.Using<'Resource, 'TOverall, 'T when 'Resource :> IDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) = + ResumableCode.Using(resource, body) + + module HighPriority = + // High priority extensions + type TaskBuilderBase with + static member BindDynamic (sm: byref<_>, task: Task<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : bool = + let mutable awaiter = task.GetAwaiter() + + let cont = + (TaskResumptionFunc<'TOverall>(fun sm -> + let result = awaiter.GetResult() + (continuation result).Invoke(&sm))) + + // shortcut to continue immediately + if awaiter.IsCompleted then + cont.Invoke(&sm) + else + sm.ResumptionDynamicInfo.ResumptionData <- (awaiter :> ICriticalNotifyCompletion) + sm.ResumptionDynamicInfo.ResumptionFunc <- cont + false + + member inline _.Bind (task: Task<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + + TaskCode<'TOverall, _>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + // Get an awaiter from the task + let mutable awaiter = task.GetAwaiter() + + let mutable __stack_fin = true + if not awaiter.IsCompleted then + // This will yield with __stack_yield_fin = false + // This will resume with __stack_yield_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_fin <- __stack_yield_fin + if __stack_fin then + let result = awaiter.GetResult() + (continuation result).Invoke(&sm) + else + sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm) + false + else + TaskBuilderBase.BindDynamic(&sm, task, continuation) + //-- RESUMABLE CODE END + ) + + member inline this.ReturnFrom (task: Task<'T>) : TaskCode<'T, 'T> = + this.Bind(task, (fun v -> this.Return v)) + + module MediumPriority = + open HighPriority + + // Medium priority extensions + type TaskBuilderBase with + member inline this.Bind (computation: Async<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + this.Bind (Async.StartAsTask computation, continuation) + + member inline this.ReturnFrom (computation: Async<'T>) : TaskCode<'T, 'T> = + this.ReturnFrom (Async.StartAsTask computation) + +#endif diff --git a/src/fsharp/FSharp.Core/tasks.fsi b/src/fsharp/FSharp.Core/tasks.fsi new file mode 100644 index 00000000000..ec2dea983b3 --- /dev/null +++ b/src/fsharp/FSharp.Core/tasks.fsi @@ -0,0 +1,315 @@ +// TaskBuilder.fs - TPL task computation expressions for F# +// +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Control + + #if !BUILDING_WITH_LKG && !BUILD_FROM_SOURCE + open System + open System.Runtime.CompilerServices + open System.Threading.Tasks + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Collections + + [] + [] + [] + /// + /// The extra data stored in ResumableStateMachine for tasks + /// + type TaskStateMachineData<'T> = + + /// + /// Holds the final result of the state machine + /// + [] + val mutable Result : 'T + + /// + /// Holds the MethodBuilder for the state machine + /// + [] + val mutable MethodBuilder : AsyncTaskMethodBuilder<'T> + + /// + /// This is used by the compiler as a template for creating state machine structs + /// + and [] + [] + TaskStateMachine<'TOverall> = ResumableStateMachine> + + /// + /// Represents the runtime continuation of a task state machine created dynamically + /// + and [] + [] + TaskResumptionFunc<'TOverall> = ResumptionFunc> + + /// + /// A special compiler-recognised delegate type for specifying blocks of task code + /// with access to the state machine. + /// + and [] + [] + TaskCode<'TOverall, 'T> = ResumableCode, 'T> + + /// + /// Contains methods to build tasks using the F# computation expression syntax + /// + [] + [] + type TaskBuilderBase = + + /// + /// Specifies the sequential composition of two units of task code. + /// + [] + member inline Combine: task1: TaskCode<'TOverall, unit> * task2: TaskCode<'TOverall, 'T> -> TaskCode<'TOverall, 'T> + + /// + /// Specifies the delayed execution of a unit of task code. + /// + [] + member inline Delay: f: (unit -> TaskCode<'TOverall, 'T>) -> TaskCode<'TOverall, 'T> + + /// + /// Specifies the iterative execution of a unit of task code. + /// + [] + member inline For: sequence: seq<'T> * body: ('T -> TaskCode<'TOverall, unit>) -> TaskCode<'TOverall, unit> + + /// + /// Specifies a unit of task code which returns a value + /// + [] + member inline Return: value: 'T -> TaskCode<'T, 'T> + + /// + /// Specifies a unit of task code which excuted using try/finally semantics + /// + [] + member inline TryFinally: body: TaskCode<'TOverall, 'T> * [] compensation: (unit -> unit) -> TaskCode<'TOverall, 'T> + + /// + /// Specifies a unit of task code which excuted using try/with semantics + /// + [] + member inline TryWith: body: TaskCode<'TOverall, 'T> * catch: (exn -> TaskCode<'TOverall, 'T>) -> TaskCode<'TOverall, 'T> + + #if NETSTANDARD2_1 + /// + /// Specifies a unit of task code which binds to the resource implementing IAsyncDisposable and disposes it asynchronously + /// + [] + member inline Using<'Resource, 'TOverall, 'T when 'Resource :> IAsyncDisposable> : resource: 'Resource * body: ('Resource -> TaskCode<'TOverall, 'T>) -> TaskCode<'TOverall, 'T> + #endif + + /// + /// Specifies the iterative execution of a unit of task code. + /// + [] + member inline While: condition: (unit -> bool) * body: TaskCode<'TOverall, unit> -> TaskCode<'TOverall, unit> + + /// + /// Specifies a unit of task code which produces no result + /// + [] + [] + member inline Zero: unit -> TaskCode<'TOverall, unit> + + /// + /// Contains methods to build tasks using the F# computation expression syntax + /// + [] + [] + type TaskBuilder = + inherit TaskBuilderBase + + /// + /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. + /// + [] + static member RunDynamic: code: TaskCode<'T, 'T> -> Task<'T> + + /// Hosts the task code in a state machine and starts the task. + [] + member inline Run: code: TaskCode<'T, 'T> -> Task<'T> + + /// + /// Contains methods to build tasks using the F# computation expression syntax + /// + [] + [] + type BackgroundTaskBuilder = + inherit TaskBuilderBase + + /// + /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. + /// + [] + static member RunDynamic: code: TaskCode<'T, 'T> -> Task<'T> + + /// + /// Hosts the task code in a state machine and starts the task, executing in the threadpool using Task.Run + /// + [] + member inline Run: code: TaskCode<'T, 'T> -> Task<'T> + + /// Contains the `task` computation expression builder. + [] + [] + module TaskBuilder = + + /// + /// Builds a task using computation expression syntax. + /// + /// + /// + [] + val task: TaskBuilder + + /// + /// Builds a task using computation expression syntax which switches to execute on a background thread if not + /// already doing so. + /// + /// + /// If the task is created on a foreground thread (where is non-null) + /// its body is executed on a background thread using . + /// If created on a background thread (where is null) it is executed immeidately + /// immediately on that thread. + /// + /// + /// + [] + val backgroundTask: BackgroundTaskBuilder + + +/// Contains the `task` computation expression builder. +namespace Microsoft.FSharp.Control.TaskBuilderExtensions + + open System + open System.Runtime.CompilerServices + open System.Threading.Tasks + open Microsoft.FSharp.Core + open Microsoft.FSharp.Control + + /// + /// Contains low-priority overloads for the `task` computation expression builder. + /// + // + // Note: they are low priority because they are auto-opened first, and F# has a rule + // that extension method opened later in sequence get higher priority + // + // AutoOpen is by assembly attribute to get sequencing of AutoOpen correct and + // so each gives different priority + [] + module LowPriority = + + type TaskBuilderBase with + /// + /// Specifies a unit of task code which draws a result from a task-like value + /// satisfying the GetAwaiter pattern and calls a continuation. + /// + [] + member inline Bind< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall > : + task: ^TaskLike * + continuation: ( 'TResult1 -> TaskCode<'TOverall, 'TResult2>) + -> TaskCode<'TOverall, 'TResult2> + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'TResult1) + + /// + /// Specifies a unit of task code which draws its result from a task-like value + /// satisfying the GetAwaiter pattern. + /// + [] + member inline ReturnFrom< ^TaskLike, ^Awaiter, 'T> : + task: ^TaskLike + -> TaskCode< 'T, 'T > + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'T) + + /// + /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. + /// + [] + static member inline BindDynamic< ^TaskLike, 'TResult1, 'TResult2, ^Awaiter, 'TOverall > : + sm: byref> * + task: ^TaskLike * + continuation: ( 'TResult1 -> TaskCode<'TOverall, 'TResult2>) + -> bool + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> 'TResult1) + + /// + /// Specifies a unit of task code which binds to the resource implementing IDisposable and disposes it synchronously + /// + [] + member inline Using: resource: 'Resource * body: ('Resource -> TaskCode<'TOverall, 'T>) -> TaskCode<'TOverall, 'T> when 'Resource :> IDisposable + + /// + /// Contains medium-priority overloads for the `task` computation expression builder. + /// + [] + module MediumPriority = + + type TaskBuilderBase with + + /// + /// Specifies a unit of task code which draws a result from an F# async value then calls a continuation. + /// + [] + member inline Bind: + computation: Async<'TResult1> * + continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>) + -> TaskCode<'TOverall, 'TResult2> + + /// + /// Specifies a unit of task code which draws a result from an F# async value. + /// + [] + member inline ReturnFrom: + computation: Async<'T> + -> TaskCode<'T, 'T> + + /// + /// Contains high-priority overloads for the `task` computation expression builder. + /// + [] + module HighPriority = + + type TaskBuilderBase with + /// + /// Specifies a unit of task code which draws a result from a task then calls a continuation. + /// + [] + member inline Bind: + task: Task<'TResult1> * + continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>) + -> TaskCode<'TOverall, 'TResult2> + + /// + /// Specifies a unit of task code which draws a result from a task. + /// + [] + member inline ReturnFrom: + task: Task<'T> + -> TaskCode<'T, 'T> + + /// + /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. + /// + [] + static member BindDynamic: + sm: byref> * + task: Task<'TResult1> * + continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>) + -> bool +#endif diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/.gitignore b/src/fsharp/FSharp.DependencyManager.Nuget/.gitignore new file mode 100644 index 00000000000..20ae51b38d5 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/.gitignore @@ -0,0 +1 @@ +FSharp.DependencyManager.Nuget.nuget.props \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSDependencyManager.txt b/src/fsharp/FSharp.DependencyManager.Nuget/FSDependencyManager.txt new file mode 100644 index 00000000000..77dece7bf41 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSDependencyManager.txt @@ -0,0 +1,12 @@ +# FSharp.Build resource strings +cantReferenceSystemPackage,"PackageManager can not reference the System Package '%s'" +requiresAValue,"%s requires a value" +unableToApplyImplicitArgument,"Unable to apply implicit argument number %d" +notUsed,"Not used" +loadNugetPackage,"Load Nuget Package" +version,"version" +highestVersion,"with the highest version" +sourceDirectoryDoesntExist,"The source directory '%s' not found" +timedoutResolvingPackages,"Timed out resolving packages, process: '%s' '%s'" +invalidTimeoutValue,"Invalid value for timeout '%s', valid values: none, -1 and integer milliseconds to wait" +missingTimeoutValue,"Missing value for timeout" \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Nuget.fsproj b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Nuget.fsproj new file mode 100644 index 00000000000..f268fa658a3 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Nuget.fsproj @@ -0,0 +1,62 @@ + + + + + + Library + netstandard2.0 + FSharp.DependencyManager.Nuget + true + $(DefineConstants);COMPILER + $(OtherFlags) --warnon:1182 + true + + + + + $(BaseOutputPath)\$(Configuration)\$(TargetFramework) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs new file mode 100644 index 00000000000..b5aba3ad10f --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs @@ -0,0 +1,277 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.DependencyManager.Nuget + +open System +open System.IO + +// Package reference information +type PackageReference = + { Include:string + Version:string + RestoreSources:string + Script:string + } + +// Resolved assembly information +type internal Resolution = + { NugetPackageId : string + NugetPackageVersion : string + PackageRoot : string + FullPath : string + AssetType: string + IsNotImplementationReference: string + InitializeSourcePath : string + NativePath : string + } + + +module internal ProjectFile = + + let fsxExt = ".fsx" + + let csxExt = ".csx" + + let findLoadsFromResolutions (resolutions:Resolution[]) = + resolutions + |> Array.filter(fun r -> + not(String.IsNullOrEmpty(r.NugetPackageId) || + String.IsNullOrEmpty(r.InitializeSourcePath)) && + File.Exists(r.InitializeSourcePath)) + |> Array.map(fun r -> r.InitializeSourcePath) + |> Array.distinct + + let findReferencesFromResolutions (resolutions:Resolution array) = + + let equals (s1:string) (s2:string) = + String.Compare(s1, s2, StringComparison.InvariantCultureIgnoreCase) = 0 + + resolutions + |> Array.filter(fun r -> not(String.IsNullOrEmpty(r.NugetPackageId) || + String.IsNullOrEmpty(r.FullPath)) && + not (equals r.IsNotImplementationReference "true") && + File.Exists(r.FullPath) && + equals r.AssetType "runtime") + |> Array.map(fun r -> r.FullPath) + |> Array.distinct + + + let findIncludesFromResolutions (resolutions:Resolution[]) = + let managedRoots = + resolutions + |> Array.filter(fun r -> + not(String.IsNullOrEmpty(r.NugetPackageId) || + String.IsNullOrEmpty(r.PackageRoot)) && + Directory.Exists(r.PackageRoot)) + |> Array.map(fun r -> r.PackageRoot) + + let nativeRoots = + resolutions + |> Array.filter(fun r -> + not(String.IsNullOrEmpty(r.NugetPackageId) || + String.IsNullOrEmpty(r.NativePath))) + |> Array.map(fun r -> + if Directory.Exists(r.NativePath) then Some r.NativePath + elif File.Exists(r.NativePath) then Some (Path.GetDirectoryName(r.NativePath).Replace('\\', '/')) + else None) + |> Array.filter(fun r -> r.IsSome) + |> Array.map(fun r -> r.Value) + + Array.concat [|managedRoots; nativeRoots|] |> Array.distinct + + + let getResolutionsFromFile resolutionsFile = + + let lines = + try + File.ReadAllText(resolutionsFile).Split([| '\r'; '\n'|], StringSplitOptions.None) + |> Array.filter(fun line -> not(String.IsNullOrEmpty(line))) + with + | _ -> [||] + + [| for line in lines do + let fields = line.Split(',') + if fields.Length < 8 then raise (InvalidOperationException(sprintf "Internal error - Invalid resolutions file format '%s'" line)) + else + { NugetPackageId = fields.[0] + NugetPackageVersion = fields.[1] + PackageRoot = fields.[2] + FullPath = fields.[3] + AssetType = fields.[4] + IsNotImplementationReference = fields.[5] + InitializeSourcePath = fields.[6] + NativePath = fields.[7] + } + |] + + let makeScriptFromReferences (references:string seq) poundRprefix = + let expandReferences = + references + |> Seq.fold(fun acc r -> acc + poundRprefix + r + "\"" + Environment.NewLine) "" + + let projectTemplate =""" +// Generated from #r "nuget:Package References" +// ============================================ +// +// DOTNET_HOST_PATH:(C:\Program Files\dotnet\dotnet.exe) +// MSBuildSDKsPath:(C:\Program Files\dotnet\sdk\3.1.200-preview-014883\Sdks) +// MSBuildExtensionsPath:(C:\Program Files\dotnet\sdk\3.1.200-preview-014883\) +// +// References +// +$(POUND_R) + +""" + projectTemplate.Replace("$(POUND_R)", expandReferences) + + let generateProjectBody = """ + + + + $(TARGETFRAMEWORK) + $(RUNTIMEIDENTIFIER) + false + <_NETCoreSdkIsPreview>false + true + + + true + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + 4.7.0 + 4.7.1-* + + + + + + +$(PACKAGEREFERENCES) + + + + + + + + + + + $(Id) + $(Version) + $([MSBuild]::EnsureTrailingSlash("$([System.IO.Path]::GetDirectoryName('%(NuspecFiles.Identity)'))").Replace('\', '/')) + package + + + + + + + + + + + + + + + <__InteractiveReferencedAssemblies Include = "@(ReferencePath)" /> + <__InteractiveReferencedAssembliesCopyLocal Include = "@(RuntimeCopyLocalItems)" Condition="'$(TargetFrameworkIdentifier)'!='.NETFramework'" /> + <__InteractiveReferencedAssembliesCopyLocal Include = "@(ReferenceCopyLocalPaths)" Condition="'$(TargetFrameworkIdentifier)'=='.NETFramework'" /> + <__ConflictsList Include="%(_ConflictPackageFiles.ConflictItemType)=%(_ConflictPackageFiles.Filename)%(_ConflictPackageFiles.Extension)" /> + + + + <__Conflicts>@(__ConflictsList, ';'); + + + + + $([System.String]::Copy('%(Identity)').Replace('\', '/')) + $([System.String]::Copy('%(__InteractiveReferencedAssemblies.PathInPackage)').Replace('\', '/')) + $([System.String]::Copy('%(InteractiveResolvedFile.NormalizedIdentity)').IndexOf('%(InteractiveResolvedFile.NormalizedPathInPackage)')) + $([System.String]::Copy('%(InteractiveResolvedFile.NormalizedIdentity)').Substring(0, %(InteractiveResolvedFile.PositionPathInPackage)).Replace('\', '/')) + %(InteractiveResolvedFile.PackageRoot)content\%(InteractiveResolvedFile.NugetPackageId)$(SCRIPTEXTENSION) + $([System.String]::Copy('%(__InteractiveReferencedAssemblies.PathInPackage)').StartsWith('ref/')) + %(__InteractiveReferencedAssemblies.NuGetPackageId) + %(__InteractiveReferencedAssemblies.NuGetPackageVersion) + + + + $([System.String]::Copy('%(Identity)').Replace('\', '/')) + $([System.String]::Copy('%(__InteractiveReferencedAssembliesCopyLocal.PathInPackage)').Replace('\', '/')) + $([System.String]::Copy('%(InteractiveResolvedFile.NormalizedIdentity)').IndexOf('%(InteractiveResolvedFile.NormalizedPathInPackage)')) + $([System.String]::Copy('%(InteractiveResolvedFile.NormalizedIdentity)').Substring(0, %(InteractiveResolvedFile.PositionPathInPackage)).Replace('\', '/')) + %(__InteractiveReferencedAssembliesCopyLocal.PackageRoot)content\%(__InteractiveReferencedAssembliesCopyLocal.NugetPackageId)$(SCRIPTEXTENSION) + $([System.String]::Copy('%(__InteractiveReferencedAssembliesCopyLocal.PathInPackage)').StartsWith('ref/')) + %(__InteractiveReferencedAssembliesCopyLocal.NuGetPackageId) + %(__InteractiveReferencedAssembliesCopyLocal.NuGetPackageVersion) + + + + $([MSBuild]::EnsureTrailingSlash("$([System.String]::Copy('%(FullPath)').Substring(0, $([System.String]::Copy('%(FullPath)').LastIndexOf('runtimes'))))").Replace('\','/')) + %(FullPath).Replace('\', '/')) + + + + $([MSBuild]::EnsureTrailingSlash("$([System.String]::Copy('%(FullPath)').Substring(0, $([System.String]::Copy('%(FullPath)').LastIndexOf('runtimes'))))").Replace('\','/')) + + + + + + + $([System.IO.Path]::GetDirectoryName('$(%(PropertyNames.FileName))')) + $([System.IO.Path]::GetFileName('%(ProvidedPackageRoots.ParentDirectory)')) + $([System.IO.Path]::GetFileName('$(%(PropertyNames.FileName))')) + package + $([MSBuild]::EnsureTrailingSlash('$(%(PropertyNames.FileName))')) + $([System.String]::Copy('%(ProvidedPackageRoots.PackageRoot)').Replace('\', '/')) + + + + + + + + + + + + + + + + +""" diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs new file mode 100644 index 00000000000..98dc44fb6c5 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs @@ -0,0 +1,169 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.DependencyManager.Nuget + +open System +open System.Diagnostics +open System.IO +open System.Reflection +open FSDependencyManager +open Internal.Utilities.FSharpEnvironment + +[] +type DependencyManagerAttribute() = inherit Attribute() + +/// The result of building the package resolution files. +type PackageBuildResolutionResult = + { success: bool + projectPath: string + stdOut: string array + stdErr: string array + resolutionsFile: string option } + +module internal Utilities = + + /// Return a string array delimited by commas + /// Note that a quoted string is not going to be mangled into pieces. + let trimChars = [| ' '; '\t'; '\''; '\"' |] + + let inline private isNotQuotedQuotation (text: string) n = n > 0 && text.[n-1] <> '\\' + + let getOptions text = + let split (option:string) = + let pos = option.IndexOf('=') + let stringAsOpt text = + if String.IsNullOrEmpty(text) then None + else Some text + let nameOpt = + if pos <= 0 then None + else stringAsOpt (option.Substring(0, pos).Trim(trimChars).ToLowerInvariant()) + let valueOpt = + let valueText = + if pos < 0 then option + else if pos < option.Length then + option.Substring(pos + 1) + else "" + stringAsOpt (valueText.Trim(trimChars)) + nameOpt,valueOpt + + let last = String.length text - 1 + let result = ResizeArray() + let mutable insideSQ = false + let mutable start = 0 + let isSeperator c = c = ',' + for i = 0 to last do + match text.[i], insideSQ with + | c, false when isSeperator c -> // split when seeing a separator + result.Add(text.Substring(start, i - start)) + insideSQ <- false + start <- i + 1 + | _, _ when i = last -> + result.Add(text.Substring(start, i - start + 1)) + | c, true when isSeperator c -> // keep reading if a separator is inside quotation + insideSQ <- true + | '\'', _ when isNotQuotedQuotation text i -> // open or close quotation + insideSQ <- not insideSQ // keep reading + | _ -> () + + result + |> List.ofSeq + |> List.map (fun option -> split option) + + let executeTool pathToExe arguments workingDir timeout = + match pathToExe with + | Some path -> + let errorsList = ResizeArray() + let outputList = ResizeArray() + let mutable errorslock = obj + let mutable outputlock = obj + let outputDataReceived (message: string) = + if not (isNull message) then + lock outputlock (fun () -> outputList.Add(message)) + + let errorDataReceived (message: string) = + if not (isNull message) then + lock errorslock (fun () -> errorsList.Add(message)) + + let psi = ProcessStartInfo() + psi.FileName <- path + psi.WorkingDirectory <- workingDir + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.Arguments <- arguments + psi.CreateNoWindow <- true + psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things + psi.UseShellExecute <- false + + use p = new Process() + p.StartInfo <- psi + + p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data) + p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data) + + if p.Start() then + p.BeginOutputReadLine() + p.BeginErrorReadLine() + if not(p.WaitForExit(timeout)) then + // Timed out resolving throw a diagnostic. + raise (TimeoutException(SR.timedoutResolvingPackages(psi.FileName, psi.Arguments))) + else + p.WaitForExit() + p.ExitCode = 0, outputList.ToArray(), errorsList.ToArray() + + | None -> false, Array.empty, Array.empty + + let buildProject projectPath binLogPath timeout = + let binLoggingArguments = + match binLogPath with + | Some(path) -> + let path = match path with + | Some path -> path // specific file + | None -> Path.Combine(Path.GetDirectoryName(projectPath), "msbuild.binlog") // auto-generated file + sprintf "/bl:\"%s\"" path + | None -> "" + + let timeout = + match timeout with + | Some(timeout) -> timeout + | None -> -1 + + let arguments prefix = + sprintf "%s -restore %s %c%s%c /nologo /t:InteractivePackageManagement" prefix binLoggingArguments '\"' projectPath '\"' + + let workingDir = Path.GetDirectoryName projectPath + + let success, stdOut, stdErr = + executeTool (getDotnetHostPath()) (arguments "msbuild -v:quiet") workingDir timeout + +#if DEBUG + File.WriteAllLines(Path.Combine(workingDir, "build_StandardOutput.txt"), stdOut) + File.WriteAllLines(Path.Combine(workingDir, "build_StandardError.txt"), stdErr) +#endif + + let outputFile = projectPath + ".resolvedReferences.paths" + let resolutionsFile = if success && File.Exists(outputFile) then Some outputFile else None + { success = success + projectPath = projectPath + stdOut = stdOut + stdErr = stdErr + resolutionsFile = resolutionsFile } + + let generateSourcesFromNugetConfigs scriptDirectory workingDir timeout = + let success, stdOut, stdErr = + executeTool (getDotnetHostPath()) "nuget list source --format short" scriptDirectory timeout +#if DEBUG + File.WriteAllLines(Path.Combine(workingDir, "nuget_StandardOutput.txt"), stdOut) + File.WriteAllLines(Path.Combine(workingDir, "nuget_StandardError.txt"), stdErr) +#else + ignore workingDir + ignore stdErr +#endif + seq { + if success then + for source in stdOut do + // String returned by dotnet nuget list source --format short + // is formatted similar to: + // E https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json + // So strip off the flags + let pos = source.IndexOf(" ") + if pos >= 0 then yield ("i", source.Substring(pos).Trim()) + } diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs new file mode 100644 index 00000000000..e63da04ccb5 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs @@ -0,0 +1,292 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.DependencyManager.Nuget + +open System +open System.Collections.Concurrent +open System.Diagnostics +open System.IO +open FSharp.DependencyManager.Nuget +open FSharp.DependencyManager.Nuget.Utilities +open FSharp.DependencyManager.Nuget.ProjectFile +open FSDependencyManager + +module FSharpDependencyManager = + + [] + do () + + let private concat (s:string) (v:string) : string = + match String.IsNullOrEmpty(s), String.IsNullOrEmpty(v) with + | false, false -> s + ";" + v + | false, true -> s + | true, false -> v + | _ -> "" + + let validateAndFormatRestoreSources (sources:string) = [| + let items = sources.Split(';') + for item in items do + let uri = Uri(item) + if uri.IsFile then + let directoryName = uri.LocalPath + if Directory.Exists(directoryName) then + yield sprintf """ $(RestoreAdditionalProjectSources);%s""" directoryName directoryName + else + raise (Exception(SR.sourceDirectoryDoesntExist(directoryName))) + else + yield sprintf """ $(RestoreAdditionalProjectSources);%s""" uri.OriginalString + |] + + let formatPackageReference p = + let { Include=inc; Version=ver; RestoreSources=src; Script=script } = p + seq { + match not (String.IsNullOrEmpty(inc)), not (String.IsNullOrEmpty(ver)), not (String.IsNullOrEmpty(script)) with + | true, true, false -> yield sprintf @" " inc ver + | true, true, true -> yield sprintf @" " inc ver script + | true, false, false -> yield sprintf @" " inc + | true, false, true -> yield sprintf @" " inc script + | _ -> () + match not (String.IsNullOrEmpty(src)) with + | true -> yield! validateAndFormatRestoreSources src + | _ -> () + } + + let parsePackageReferenceOption scriptExt (setBinLogPath: string option option -> unit) (setTimeout: int option -> unit) (line: string) = + let validatePackageName package packageName = + if String.Compare(packageName, package, StringComparison.OrdinalIgnoreCase) = 0 then + raise (ArgumentException(SR.cantReferenceSystemPackage(packageName))) + let rec parsePackageReferenceOption' (options: (string option * string option) list) (implicitArgumentCount: int) (packageReference: PackageReference option) = + let current = + match packageReference with + | Some p -> p + | None -> { Include = ""; Version = "*"; RestoreSources = ""; Script = "" } + match options with + | [] -> packageReference + | opt :: rest -> + let addInclude v = + validatePackageName v "mscorlib" + if scriptExt = fsxExt then + validatePackageName v "FSharp.Core" + validatePackageName v "System.ValueTuple" + validatePackageName v "NETStandard.Library" + validatePackageName v "Microsoft.NETFramework.ReferenceAssemblies" + Some { current with Include = v } + let setVersion v = Some { current with Version = v } + match opt with + | Some "include", Some v -> addInclude v |> parsePackageReferenceOption' rest implicitArgumentCount + | Some "include", None -> raise (ArgumentException(SR.requiresAValue("Include"))) + | Some "version", Some v -> setVersion v |> parsePackageReferenceOption' rest implicitArgumentCount + | Some "version", None -> setVersion "*" |> parsePackageReferenceOption' rest implicitArgumentCount + | Some "restoresources", Some v -> Some { current with RestoreSources = concat current.RestoreSources v } |> parsePackageReferenceOption' rest implicitArgumentCount + | Some "restoresources", None -> raise (ArgumentException(SR.requiresAValue("RestoreSources"))) + | Some "script", Some v -> Some { current with Script = v } |> parsePackageReferenceOption' rest implicitArgumentCount + | Some "timeout", None -> raise (ArgumentException(SR.missingTimeoutValue())) + | Some "timeout", value -> + match value with + | Some v when v.GetType() = typeof -> + let parsed, value = Int32.TryParse(v) + if parsed && value >= 0 then setTimeout (Some (Int32.Parse v)) + elif v = "none" then setTimeout (Some -1) + else raise (ArgumentException(SR.invalidTimeoutValue(v))) + | _ -> setTimeout None // auto-generated logging location + parsePackageReferenceOption' rest implicitArgumentCount packageReference + | Some "bl", value -> + match value with + | Some v when v.ToLowerInvariant() = "true" -> setBinLogPath (Some None) // auto-generated logging location + | Some v when v.ToLowerInvariant() = "false" -> setBinLogPath None // no logging + | Some path -> setBinLogPath (Some (Some path)) // explicit logging location + | None -> + // parser shouldn't get here because unkeyed values follow a different path, but for the sake of completeness and keeping the compiler happy, + // this is fine + setBinLogPath (Some None) // auto-generated logging location + parsePackageReferenceOption' rest implicitArgumentCount packageReference + | None, Some v -> + match v.ToLowerInvariant() with + | "bl" -> + // a bare 'bl' enables binary logging and is NOT interpreted as one of the positional arguments. On the off chance that the user actually wants + // to reference a package named 'bl' they still have the 'Include=bl' syntax as a fallback. + setBinLogPath (Some None) // auto-generated logging location + parsePackageReferenceOption' rest implicitArgumentCount packageReference + | "timeout" -> + // bare timeout is invalid + raise (ArgumentException(SR.missingTimeoutValue())) + | _ -> + match implicitArgumentCount with + | 0 -> addInclude v + | 1 -> setVersion v + | _ -> raise (ArgumentException(SR.unableToApplyImplicitArgument(implicitArgumentCount + 1))) + |> parsePackageReferenceOption' rest (implicitArgumentCount + 1) + | _ -> parsePackageReferenceOption' rest implicitArgumentCount packageReference + let options = getOptions line + parsePackageReferenceOption' options 0 None + + let parsePackageReference scriptExt (lines: string list) = + let mutable binLogPath = None + let mutable timeout = None + lines + |> List.choose (fun line -> parsePackageReferenceOption scriptExt (fun p -> binLogPath <- p) (fun t -> timeout <- t) line) + |> List.distinct + |> (fun l -> l, binLogPath, timeout) + + let parsePackageDirective scriptExt (lines: (string * string) list) = + let mutable binLogPath = None + let mutable timeout = None + lines + |> List.map(fun (directive, line) -> + match directive with + | "i" -> sprintf "RestoreSources=%s" line + | _ -> line) + |> List.choose (fun line -> parsePackageReferenceOption scriptExt (fun p -> binLogPath <- p) (fun t -> timeout <- t) line) + |> List.distinct + |> (fun l -> l, binLogPath, timeout) + +/// The results of ResolveDependencies +type ResolveDependenciesResult (success: bool, stdOut: string array, stdError: string array, resolutions: string seq, sourceFiles: string seq, roots: string seq) = + + /// Succeded? + member _.Success = success + + /// The resolution output log + member _.StdOut = stdOut + + /// The resolution error log (* process stderror *) + member _.StdError = stdError + + /// The resolution paths - the full paths to selected resolved dll's. + /// In scripts this is equivalent to #r @"c:\somepath\to\packages\ResolvedPackage\1.1.1\lib\netstandard2.0\ResolvedAssembly.dll" + member _.Resolutions = resolutions + + /// The source code file paths + member _.SourceFiles = sourceFiles + + /// The roots to package directories + /// This points to the root of each located package. + /// The layout of the package manager will be package manager specific. + /// however, the dependency manager dll understands the nuget package layout + /// and so if the package contains folders similar to the nuget layout then + /// the dependency manager will be able to probe and resolve any native dependencies + /// required by the nuget package. + /// + /// This path is also equivalent to + /// #I @"c:\somepath\to\packages\ResolvedPackage\1.1.1\" + member _.Roots = roots + +[] +type FSharpDependencyManager (outputDirectory:string option) = + + let key = "nuget" + let name = "MsBuild Nuget DependencyManager" + let workingDirectory = + let path = Path.Combine(Path.GetTempPath(), key, Process.GetCurrentProcess().Id.ToString() + "--"+ Guid.NewGuid().ToString()) + match outputDirectory with + | None -> path + | Some v -> Path.Combine(path, v) + + let generatedScripts = ConcurrentDictionary() + + let deleteScripts () = + try +#if !Debug + if Directory.Exists(workingDirectory) then + Directory.Delete(workingDirectory, true) +#else + () +#endif + with | _ -> () + + let deleteAtExit = + try + if not (Directory.Exists(workingDirectory)) then + Directory.CreateDirectory(workingDirectory) |> ignore + true + with | _ -> false + + let emitFile filename (body:string) = + try + // Create a file to write to + use sw = File.CreateText(filename) + sw.WriteLine(body) + with | _ -> () + + let prepareDependencyResolutionFiles (scriptExt: string, directiveLines: (string * string) seq, targetFrameworkMoniker: string, runtimeIdentifier: string, timeout: int): PackageBuildResolutionResult = + let scriptExt = + match scriptExt with + | ".csx" -> csxExt + | _ -> fsxExt + + let packageReferences, binLogPath, package_timeout = + directiveLines + |> List.ofSeq + |> FSharpDependencyManager.parsePackageDirective scriptExt + + let packageReferenceLines = + packageReferences + |> List.map FSharpDependencyManager.formatPackageReference + |> Seq.concat + + let packageReferenceText = String.Join(Environment.NewLine, packageReferenceLines) + + let projectPath = Path.Combine(workingDirectory, "Project.fsproj") + + let generateAndBuildProjectArtifacts = + let writeFile path body = + if not (generatedScripts.ContainsKey(body.GetHashCode().ToString())) then + emitFile path body + + let generateProjBody = + generateProjectBody.Replace("$(TARGETFRAMEWORK)", targetFrameworkMoniker) + .Replace("$(RUNTIMEIDENTIFIER)", runtimeIdentifier) + .Replace("$(PACKAGEREFERENCES)", packageReferenceText) + .Replace("$(SCRIPTEXTENSION)", scriptExt) + + let timeout = + match package_timeout with + | Some _ -> package_timeout + | None -> Some timeout + writeFile projectPath generateProjBody + buildProject projectPath binLogPath timeout + + generateAndBuildProjectArtifacts + + + do if deleteAtExit then AppDomain.CurrentDomain.ProcessExit |> Event.add(fun _ -> deleteScripts () ) + + member _.Name = name + + member _.Key = key + + member _.HelpMessages = [| + sprintf """ #r "nuget:FSharp.Data, 3.1.2";; // %s 'FSharp.Data' %s '3.1.2'""" (SR.loadNugetPackage()) (SR.version()) + sprintf """ #r "nuget:FSharp.Data";; // %s 'FSharp.Data' %s""" (SR.loadNugetPackage()) (SR.highestVersion()) + |] + + member this.ResolveDependencies(scriptDirectory: string, scriptName: string, scriptExt: string, packageManagerTextLines: (string * string) seq, targetFrameworkMoniker: string, runtimeIdentifier: string, timeout: int) : obj = + ignore scriptName + let poundRprefix = + match scriptExt with + | ".csx" -> "#r \"" + | _ -> "#r @\"" + + let generateAndBuildProjectArtifacts = + let configIncludes = generateSourcesFromNugetConfigs scriptDirectory workingDirectory timeout + let directiveLines = Seq.append packageManagerTextLines configIncludes + let resolutionResult = prepareDependencyResolutionFiles (scriptExt, directiveLines, targetFrameworkMoniker, runtimeIdentifier, timeout) + match resolutionResult.resolutionsFile with + | Some file -> + let resolutions = getResolutionsFromFile file + let references = (findReferencesFromResolutions resolutions) |> Array.toSeq + let scripts = + let generatedScriptPath = resolutionResult.projectPath + scriptExt + let generatedScriptBody = makeScriptFromReferences references poundRprefix + emitFile generatedScriptPath generatedScriptBody + let loads = (findLoadsFromResolutions resolutions) |> Array.toList + List.concat [ [generatedScriptPath]; loads] |> List.toSeq + let includes = (findIncludesFromResolutions resolutions) |> Array.toSeq + + ResolveDependenciesResult(resolutionResult.success, resolutionResult.stdOut, resolutionResult.stdErr, references, scripts, includes) + + | None -> + let empty = Seq.empty + ResolveDependenciesResult(resolutionResult.success, resolutionResult.stdOut, resolutionResult.stdErr, empty, empty, empty) + + generateAndBuildProjectArtifacts :> obj diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fsi b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fsi new file mode 100644 index 00000000000..d6b87149eb7 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fsi @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.DependencyManager.Nuget + +module internal FSharpDependencyManager = + val formatPackageReference: PackageReference -> seq + val parsePackageReference: scriptExt: string -> string list -> PackageReference list * string option option * int option + val parsePackageDirective: scriptExt: string -> (string * string) list -> PackageReference list * string option option * int option + +/// The results of ResolveDependencies +[] +type ResolveDependenciesResult = + + /// Succeded? + member Success: bool + + /// The resolution output log + member StdOut: string[] + + /// The resolution error log (process stderr) + member StdError: string[] + + /// The resolution paths - the full paths to selected resolved dll's. + /// In scripts this is equivalent to #r @"c:\somepath\to\packages\ResolvedPackage\1.1.1\lib\netstandard2.0\ResolvedAssembly.dll" + member Resolutions: seq + + /// The source code file paths + member SourceFiles: seq + + /// The roots to package directories + /// This points to the root of each located package. + /// The layout of the package manager will be package manager specific. + /// however, the dependency manager dll understands the nuget package layout + /// and so if the package contains folders similar to the nuget layout then + /// the dependency manager will be able to probe and resolve any native dependencies + /// required by the nuget package. + /// + /// This path is also equivant to + /// #I @"c:\somepath\to\packages\ResolvedPackage\1.1.1\" + member Roots: seq + +[] +type FSharpDependencyManager = + new: outputDirectory:string option -> FSharpDependencyManager + + member Name: string + + member Key:string + + member HelpMessages:string[] + + member ResolveDependencies: scriptDirectory: string * scriptName: string * scriptExt: string * packageManagerTextLines: (string * string) seq * targetFrameworkMoniker: string * runtimeIdentifier: string * timeout: int-> obj diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/README.md b/src/fsharp/FSharp.DependencyManager.Nuget/README.md new file mode 100644 index 00000000000..01927f4edcb --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/README.md @@ -0,0 +1,15 @@ +# `dotnet fsi`: NuGet Dependency Manager Plugin + +This extension ships by default since .NET 5. It can be used in F# interactive through `dotnet fsi` without further setup through `#r "nuget:"` references. + +```fsharp +#r "nuget: Newtonsoft.Json" +// Optionally, specify a version explicitly +// #r "nuget: Newtonsoft.Json,11.0.1" + +open Newtonsoft.Json + +let o = {| X = 2; Y = "Hello" |} + +printfn "%s" (JsonConvert.SerializeObject o)" +``` diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf new file mode 100644 index 00000000000..2866d233f47 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager se nemůže odkazovat na systémový balíček {0}. + + + + with the highest version + s nejvyšší verzí + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Neplatná hodnota pro časový limit {0}. Platné hodnoty: none, -1 a celočíselný počet milisekund, po které se má počkat + + + + Load Nuget Package + Načíst balíček NuGet + + + + Missing value for timeout + Chybí hodnota pro časový limit + + + + Not used + Nepoužito + + + + {0} requires a value + {0} vyžaduje hodnotu. + + + + The source directory '{0}' not found + Zdrojový adresář {0} se nenašel. + + + + Timed out resolving packages, process: '{0}' '{1}' + Při řešení balíčků vypršel časový limit. Proces: {0} {1} + + + + Unable to apply implicit argument number {0} + Nepovedlo se použít implicitní počet argumentů {0}. + + + + version + verze + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf new file mode 100644 index 00000000000..3d060a10414 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager kann nicht auf das Systempaket "{0}" verweisen. + + + + with the highest version + mit der höchsten Version + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Ungültiger Wert für Timeout "{0}", gültige Werte: keine, -1 und ganzzahlige Millisekundenwerte für die Wartezeit + + + + Load Nuget Package + NuGet-Paket laden + + + + Missing value for timeout + Fehlender Wert für Timeout + + + + Not used + Nicht verwendet + + + + {0} requires a value + Für "{0}" ist ein Wert erforderlich. + + + + The source directory '{0}' not found + Das Quellverzeichnis "{0}" wurde nicht gefunden. + + + + Timed out resolving packages, process: '{0}' '{1}' + Timeout beim Auflösen von Paketen, Prozess: "{0}" "{1}" + + + + Unable to apply implicit argument number {0} + Die Zahl für das implizierte Argument ({0}) kann nicht angewendet werden. + + + + version + Version + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.en.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.en.xlf similarity index 100% rename from src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.en.xlf rename to src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.en.xlf diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf new file mode 100644 index 00000000000..5b8974e7605 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager no puede hacer referencia al paquete del sistema "{0}". + + + + with the highest version + con la última versión + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Valor de tiempo de espera "{0}" no válido. Valores válidos: ninguno, -1 y un número entero de milisegundos de espera + + + + Load Nuget Package + Cargar paquete NuGet + + + + Missing value for timeout + Falta un valor para el tiempo de espera + + + + Not used + No se usa + + + + {0} requires a value + {0} requiere un valor + + + + The source directory '{0}' not found + No se encuentra el directorio de origen "{0}". + + + + Timed out resolving packages, process: '{0}' '{1}' + Se agotó el tiempo de espera en la resolución de paquetes, proceso: "{0}" "{1}" + + + + Unable to apply implicit argument number {0} + No se puede aplicar el número de argumento implícito {0}. + + + + version + versión + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf new file mode 100644 index 00000000000..58f97bce018 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager ne peut pas référencer le package système '{0}' + + + + with the highest version + avec la version la plus récente + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Valeur non valide pour le délai d'expiration : '{0}'. Valeurs valides : aucune valeur, -1 ou un nombre entier pour le délai d'attente en millisecondes + + + + Load Nuget Package + Charger le package NuGet + + + + Missing value for timeout + Valeur manquante pour le délai d'expiration + + + + Not used + Non utilisé + + + + {0} requires a value + {0} nécessite une valeur + + + + The source directory '{0}' not found + Le répertoire source '{0}' est introuvable + + + + Timed out resolving packages, process: '{0}' '{1}' + Expiration du délai de résolution des packages. Processus : '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + Impossible d'appliquer le numéro d'argument implicite {0} + + + + version + version + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf new file mode 100644 index 00000000000..e840741112b --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager non può fare riferimento al pacchetto di sistema '{0}' + + + + with the highest version + con la versione massima + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Valore non valido per il timeout '{0}'. I valori validi sono: nessuno, -1 e numeri interi per i millisecondi di attesa + + + + Load Nuget Package + Carica pacchetto NuGet + + + + Missing value for timeout + Manca il valore per il timeout + + + + Not used + Non usato + + + + {0} requires a value + Con {0} è richiesto un valore + + + + The source directory '{0}' not found + La directory di origine '{0}' non è stata trovata + + + + Timed out resolving packages, process: '{0}' '{1}' + Timeout durante la risoluzione dei pacchetti. Processo: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + Non è possibile applicare il numero di argomento implicito {0} + + + + version + versione + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf new file mode 100644 index 00000000000..f0437133108 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager がシステム パッケージ '{0}' を参照できません + + + + with the highest version + 最新バージョン + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + タイムアウト '{0}' の値が無効です。有効な値: なし、-1、および整数 (待機するミリ秒) + + + + Load Nuget Package + NuGet パッケージの読み込み + + + + Missing value for timeout + タイムアウトの値がありません + + + + Not used + 未使用 + + + + {0} requires a value + {0} には値が必要です + + + + The source directory '{0}' not found + ソース ディレクトリ '{0}' が見つかりません + + + + Timed out resolving packages, process: '{0}' '{1}' + パッケージの解決中にタイムアウトになりました。プロセス: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + 暗黙的な引数番号 {0} を適用できません + + + + version + バージョン + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf new file mode 100644 index 00000000000..53d85ca1b4f --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager에서 시스템 패키지 '{0}'을(를) 참조할 수 없습니다. + + + + with the highest version + 최상위 버전으로 + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + 시간 제한 '{0}'의 값이 잘못되었습니다. 유효한 값: 없음, -1 및 정수 대기 시간(밀리초) + + + + Load Nuget Package + NuGet 패키지 로드 + + + + Missing value for timeout + 시간 제한 값 누락 + + + + Not used + 사용 안 함 + + + + {0} requires a value + {0}에는 값이 있어야 합니다. + + + + The source directory '{0}' not found + 소스 디렉터리 '{0}'을(를) 찾을 수 없음 + + + + Timed out resolving packages, process: '{0}' '{1}' + 패키지를 확인하는 동안 시간이 초과되었습니다. 프로세스: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + 암시적 인수 번호 {0}을(를) 적용할 수 없습니다. + + + + version + 버전 + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf new file mode 100644 index 00000000000..9a908307899 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + Program PacketManager nie może odwoływać się do pakietu systemowego „{0}” + + + + with the highest version + z najwyższą wersją + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Nieprawidłowa wartość limitu czasu „{0}”; prawidłowe wartości: none, -1 i liczba całkowita określająca liczbę milisekund oczekiwania + + + + Load Nuget Package + Załaduj pakiet NuGet + + + + Missing value for timeout + Brak wartości limitu czasu + + + + Not used + Nieużywane + + + + {0} requires a value + Element {0} wymaga wartości. + + + + The source directory '{0}' not found + Nie znaleziono katalogu źródłowego „{0}” + + + + Timed out resolving packages, process: '{0}' '{1}' + Przekroczono limit czasu podczas rozpoznawania pakietów, proces: „{0}” „{1}” + + + + Unable to apply implicit argument number {0} + Nie można zastosować niejawnego argumentu o numerze {0} + + + + version + wersja + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf new file mode 100644 index 00000000000..af23785016a --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager não pode referenciar o pacote do sistema '{0}' + + + + with the highest version + com a versão mais recente + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Valor inválido para o tempo limite '{0}'. Valores válidos: none,-1 e milissegundos inteiros de espera + + + + Load Nuget Package + Carregar Pacote NuGet + + + + Missing value for timeout + Valor ausente para o tempo limite + + + + Not used + Não usado + + + + {0} requires a value + {0} requer um valor + + + + The source directory '{0}' not found + O diretório de origem '{0}' não foi localizado + + + + Timed out resolving packages, process: '{0}' '{1}' + Tempo limite atingido ao resolver os pacotes. Processo: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + Não é possível aplicar o número do argumento implícito {0} + + + + version + versão + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf new file mode 100644 index 00000000000..f57d66e3342 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager не может ссылаться на системный пакет "{0}" + + + + with the highest version + с наивысшей версией + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Недопустимое значение времени ожидания "{0}". Допустимые значения: none, –1 и integer, мс ожидания. + + + + Load Nuget Package + Загрузить пакет NuGet + + + + Missing value for timeout + Отсутствует значение времени ожидания + + + + Not used + Не используется + + + + {0} requires a value + {0} требует значение. + + + + The source directory '{0}' not found + Исходный каталог "{0}" не найден + + + + Timed out resolving packages, process: '{0}' '{1}' + Истекло время ожидания при разрешении пакетов. Процесс: "{0}" "{1}". + + + + Unable to apply implicit argument number {0} + Не удалось применить неявный аргумент с номером {0} + + + + version + версия + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf new file mode 100644 index 00000000000..d628c815565 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager, '{0}' Sistem Paketine başvuramıyor + + + + with the highest version + en yüksek sürümle + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + Zaman aşımı için '{0}' değeri geçersiz, geçerli değerler: none, -1 ve tamsayı milisaniye cinsinden bekleme süresi + + + + Load Nuget Package + NuGet Paketini Yükle + + + + Missing value for timeout + Zaman aşımı için değer eksik + + + + Not used + Kullanılmıyor + + + + {0} requires a value + {0}, bir değer gerektiriyor + + + + The source directory '{0}' not found + '{0}' kaynak dizini bulunamadı + + + + Timed out resolving packages, process: '{0}' '{1}' + Paketler çözümlenirken zaman aşımı gerçekleşti, işlem: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + Örtük bağımsız değişken sayısı ({0}) uygulanamıyor + + + + version + sürüm + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf new file mode 100644 index 00000000000..65cd28177b1 --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager 无法引用系统包“{0}” + + + + with the highest version + 具有最高版本 + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + 超时 "{0}" 的值无效,有效值: none、-1 和要等待的毫秒数(整数) + + + + Load Nuget Package + 加载 Nuget 包 + + + + Missing value for timeout + 缺少超时值 + + + + Not used + 未使用 + + + + {0} requires a value + {0} 需要一个值 + + + + The source directory '{0}' not found + 找不到源目录“{0}” + + + + Timed out resolving packages, process: '{0}' '{1}' + 解析包超时,进程: "{0}" "{1}" + + + + Unable to apply implicit argument number {0} + 无法应用隐式参数号 {0} + + + + version + 版本 + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf new file mode 100644 index 00000000000..580ca08a73f --- /dev/null +++ b/src/fsharp/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf @@ -0,0 +1,62 @@ + + + + + + PackageManager can not reference the System Package '{0}' + PackageManager 無法參考系統套件 '{0}' + + + + with the highest version + 具有最高版本 + + + + Invalid value for timeout '{0}', valid values: none, -1 and integer milliseconds to wait + 逾時 '{0}' 值無效,有效的值: 無、-1 和要等候的整數毫秒 + + + + Load Nuget Package + 載入 Nuget 套件 + + + + Missing value for timeout + 遺漏逾時值 + + + + Not used + 未使用 + + + + {0} requires a value + {0} 需要值 + + + + The source directory '{0}' not found + 找不到來源目錄 '{0}' + + + + Timed out resolving packages, process: '{0}' '{1}' + 解析套件時發生逾時,處理序: '{0}' '{1}' + + + + Unable to apply implicit argument number {0} + 無法套用隱含引數號碼 {0} + + + + version + 版本 + + + + + \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/.gitignore b/src/fsharp/FSharp.DependencyManager/.gitignore deleted file mode 100644 index b6f8be69852..00000000000 --- a/src/fsharp/FSharp.DependencyManager/.gitignore +++ /dev/null @@ -1 +0,0 @@ -FSharp.DependencyManager.nuget.props \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/FSDependencyManager.txt b/src/fsharp/FSharp.DependencyManager/FSDependencyManager.txt deleted file mode 100644 index a163aafc0f8..00000000000 --- a/src/fsharp/FSharp.DependencyManager/FSDependencyManager.txt +++ /dev/null @@ -1,2 +0,0 @@ -# FSharp.Build resource strings -notUsed,"Not used." \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.Utilities.fs b/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.Utilities.fs deleted file mode 100644 index 493a6ba7899..00000000000 --- a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.Utilities.fs +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.DependencyManager - -open System -open System.Collections -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.Versioning - -open Internal.Utilities.FSharpEnvironment - -#if !(NETSTANDARD || NETCOREAPP) -open Microsoft.Build.Evaluation -open Microsoft.Build.Framework -#endif - -[] -type DependencyManagerAttribute() = inherit System.Attribute() - -module Utilities = - - /// Return a string array delimited by commas - /// Note that a quoted string is not going to be mangled into pieces. - let trimChars = [| ' '; '\t'; '\''; '\"' |] - - let inline private isNotQuotedQuotation (text: string) n = n > 0 && text.[n-1] <> '\\' - - let getOptions text = - let split (option:string) = - let pos = option.IndexOf('=') - let stringAsOpt text = - if String.IsNullOrEmpty(text) then None - else Some text - let nameOpt = - if pos <= 0 then None - else stringAsOpt (option.Substring(0, pos).Trim(trimChars).ToLowerInvariant()) - let valueOpt = - let valueText = - if pos < 0 then option - else if pos < option.Length then - option.Substring(pos + 1) - else "" - stringAsOpt (valueText.Trim(trimChars)) - nameOpt,valueOpt - - let last = String.length text - 1 - let result = ResizeArray() - let mutable insideSQ = false - let mutable start = 0 - let isSeperator c = c = ',' - for i = 0 to last do - match text.[i], insideSQ with - | c, false when isSeperator c -> // split when seeing a separator - result.Add(text.Substring(start, i - start)) - insideSQ <- false - start <- i + 1 - | _, _ when i = last -> - result.Add(text.Substring(start, i - start + 1)) - | c, true when isSeperator c -> // keep reading if a separator is inside quotation - insideSQ <- true - | '\'', _ when isNotQuotedQuotation text i -> // open or close quotation - insideSQ <- not insideSQ // keep reading - | _ -> () - - result - |> List.ofSeq - |> List.map (fun option -> split option) - - // Path to the directory containing the fsharp compilers - let fsharpCompilerPath = Path.GetDirectoryName(typeof.GetTypeInfo().Assembly.Location) - - // We are running on dotnet core if the executing mscorlib is System.Private.CoreLib - let isRunningOnCoreClr = (typeof.Assembly).FullName.StartsWith("System.Private.CoreLib", StringComparison.InvariantCultureIgnoreCase) - - let isWindows = - match Environment.OSVersion.Platform with - | PlatformID.Unix -> false - | PlatformID.MacOSX -> false - | _ -> true - - let dotnet = - if isWindows then "dotnet.exe" else "dotnet" - - let sdks = "Sdks" - -#if !(NETSTANDARD || NETCOREAPP) - let msbuildExePath = - // Find msbuild.exe when invoked from desktop compiler. - // 1. Look relative to F# compiler location Normal retail build - // 2. Use VSAPPDIR Nightly when started from VS, or F5 - // 3. Use VSINSTALLDIR -- When app is run outside of VS, and - // is not copied relative to a vs install. - let vsRootFromVSAPPIDDIR = - let vsappiddir = Environment.GetEnvironmentVariable("VSAPPIDDIR") - if not (String.IsNullOrEmpty(vsappiddir)) then - Path.GetFullPath(Path.Combine(vsappiddir, "../..")) - else - null - - let roots = [| - Path.GetFullPath(Path.Combine(fsharpCompilerPath, "../../../../..")) - vsRootFromVSAPPIDDIR - Environment.GetEnvironmentVariable("VSINSTALLDIR") - |] - - let msbuildPath root = Path.GetFullPath(Path.Combine(root, "MSBuild/Current/Bin/MSBuild.exe")) - - let msbuildPathExists root = - if String.IsNullOrEmpty(root) then - false - else - File.Exists(msbuildPath root) - - let msbuildOption rootOpt = - match rootOpt with - | Some root -> Some (msbuildPath root) - | _ -> None - - roots |> Array.tryFind(fun root -> msbuildPathExists root) |> msbuildOption -#else - let dotnetHostPath = - // How to find dotnet.exe --- woe is me; probing rules make me sad. - // Algorithm: - // 1. Look for DOTNET_HOST_PATH environment variable - // this is the main user programable override .. provided by user to find a specific dotnet.exe - // 2. Probe for are we part of an .NetSDK install - // In an sdk install we are always installed in: sdk\3.0.100-rc2-014234\FSharp - // dotnet or dotnet.exe will be found in the directory that contains the sdk directory - // 3. We are loaded in-process to some other application ... Eg. try .net - // See if the host is dotnet.exe ... from netcoreapp3.0 on this is fairly unlikely - // 4. If it's none of the above we are going to have to rely on the path containing the way to find dotnet.exe - // - if isRunningOnCoreClr then - match (Environment.GetEnvironmentVariable("DOTNET_HOST_PATH")) with - | value when not (String.IsNullOrEmpty(value)) -> - Some value // Value set externally - | _ -> - // Probe for netsdk install - let dotnetLocation = - let dotnetApp = - let platform = Environment.OSVersion.Platform - if platform = PlatformID.Unix then "dotnet" else "dotnet.exe" - let assemblyLocation = typeof.GetTypeInfo().Assembly.Location - Path.Combine(assemblyLocation, "../../..", dotnetApp) - - if File.Exists(dotnetLocation) then - Some dotnetLocation - else - let main = Process.GetCurrentProcess().MainModule - if main.ModuleName ="dotnet" then - Some main.FileName - else - Some dotnet - else - None -#endif - - let drainStreamToFile (stream: StreamReader) filename = - use file = File.OpenWrite(filename) - use writer = new StreamWriter(file) - let rec copyLines () = - match stream.ReadLine() with - | null -> () - | line -> - writer.WriteLine(line) - copyLines () - copyLines () - - let executeBuild pathToExe arguments workingDir = - match pathToExe with - | Some path -> - - let psi = ProcessStartInfo() - psi.FileName <- path - psi.WorkingDirectory <- workingDir - psi.RedirectStandardOutput <- true - psi.RedirectStandardError <- true - psi.Arguments <- arguments - psi.CreateNoWindow <- true - psi.UseShellExecute <- false - - use p = new Process() - p.StartInfo <- psi - p.Start() |> ignore - - drainStreamToFile p.StandardOutput (Path.Combine(workingDir, "StandardOutput.txt")) - drainStreamToFile p.StandardError (Path.Combine(workingDir, "StandardError.txt")) - - p.WaitForExit() - p.ExitCode = 0 - - | None -> false - - let buildProject projectPath binLogPath = - let binLoggingArguments = - match binLogPath with - | Some(path) -> - let path = match path with - | Some path -> path // specific file - | None -> Path.Combine(Path.GetDirectoryName(projectPath), "msbuild.binlog") // auto-generated file - sprintf "/bl:\"%s\"" path - | None -> "" - - let arguments prefix = - sprintf "%s -restore %s %c%s%c /t:FSI-PackageManagement" prefix binLoggingArguments '\"' projectPath '\"' - - let workingDir = Path.GetDirectoryName projectPath - - let succeeded = -#if !(NETSTANDARD || NETCOREAPP) - // The Desktop build uses "msbuild" to build - executeBuild msbuildExePath (arguments "") workingDir -#else - // The coreclr uses "dotnet msbuild" to build - executeBuild dotnetHostPath (arguments "msbuild") workingDir -#endif - let outputFile = projectPath + ".fsx" - let resultOutFile = if succeeded && File.Exists(outputFile) then Some outputFile else None - succeeded, resultOutFile - - // Generate a project files for dependencymanager projects - let generateLibrarySource = @"// Generated dependencymanager library -namespace lib" - - let generateProjectBody = @" - - - $(TARGETFRAMEWORK) - false - - - - -$(PACKAGEREFERENCES) - - - - - - - - - - - - fsharp41 - tools - - - - - - - <_ResolvedOutputFiles - Include=""%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/*"" - Exclude=""%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/FSharp.Core.dll;%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/System.ValueTuple.dll"" - Condition=""'%(_ResolvedProjectReferencePaths.IsFSharpDesignTimeProvider)' == 'true'""> - %(_ResolvedProjectReferencePaths.NearestTargetFramework) - - - <_ResolvedOutputFiles - Include=""@(BuiltProjectOutputGroupKeyOutput)"" - Condition=""'$(IsFSharpDesignTimeProvider)' == 'true' and '%(BuiltProjectOutputGroupKeyOutput->Filename)%(BuiltProjectOutputGroupKeyOutput->Extension)' != 'FSharp.Core.dll' and '%(BuiltProjectOutputGroupKeyOutput->Filename)%(BuiltProjectOutputGroupKeyOutput->Extension)' != 'System.ValueTuple.dll'""> - $(TargetFramework) - - - - $(FSharpToolsDirectory)/$(FSharpDesignTimeProtocol)/%(_ResolvedOutputFiles.NearestTargetFramework)/%(_ResolvedOutputFiles.FileName)%(_ResolvedOutputFiles.Extension) - - - - - - - - Pkg$([System.String]::Copy('%(ResolvedCompileFileDefinitions.NugetPackageId)').Replace('.','_')) - $([MSBuild]::EnsureTrailingSlash('$(%(FsxResolvedFile.PackageRootProperty))')) - $(%(FsxResolvedFile.PackageRootProperty))\content\%(ResolvedCompileFileDefinitions.FileName)%(ResolvedCompileFileDefinitions.Extension).fsx - - - $([MSBuild]::EnsureTrailingSlash('$([System.String]::Copy('%(FullPath)').Substring(0, $([System.String]::Copy('%(FullPath)').LastIndexOf('runtimes'))))')) - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" diff --git a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fs b/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fs deleted file mode 100644 index 9c577e9ca84..00000000000 --- a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.DependencyManager - -open System -open System.Collections.Concurrent -open System.Diagnostics -open System.IO -open FSharp.DependencyManager -open FSharp.DependencyManager.Utilities - -module Attributes = - [] - do () - -type PackageReference = { Include:string; Version:string; RestoreSources:string; Script:string } - -module FSharpDependencyManager = - - let private concat (s:string) (v:string) : string = - match String.IsNullOrEmpty(s), String.IsNullOrEmpty(v) with - | false, false -> s + ";" + v - | false, true -> s - | true, false -> v - | _ -> "" - - let formatPackageReference p = - let { Include=inc; Version=ver; RestoreSources=src; Script=script } = p - seq { - match not (String.IsNullOrEmpty(inc)), not (String.IsNullOrEmpty(ver)), not (String.IsNullOrEmpty(script)) with - | true, true, false -> yield sprintf @" true" inc ver - | true, true, true -> yield sprintf @" true" inc ver script - | true, false, false -> yield sprintf @" true" inc - | true, false, true -> yield sprintf @" true" inc script - | _ -> () - match not (String.IsNullOrEmpty(src)) with - | true -> yield sprintf @" %s" (concat "$(RestoreAdditionalProjectSources)" src) - | _ -> () - } - - let parsePackageReference (lines: string list) = - let mutable binLogPath = None - let parsePackageReferenceOption (line: string) = - let validatePackageName package packageName = - if String.Compare(packageName, package, StringComparison.OrdinalIgnoreCase) = 0 then - raise (ArgumentException(sprintf "PackageManager can not reference the System Package '%s'" packageName)) // @@@@@@@@@@@@@@@@@@@@@@@ Globalize me please - let rec parsePackageReferenceOption' (options: (string option * string option) list) (implicitArgumentCount: int) (packageReference: PackageReference option) = - let current = - match packageReference with - | Some p -> p - | None -> { Include = ""; Version = "*"; RestoreSources = ""; Script = "" } - match options with - | [] -> packageReference - | opt :: rest -> - let addInclude v = - validatePackageName v "mscorlib" - validatePackageName v "FSharp.Core" - validatePackageName v "System.ValueTuple" - validatePackageName v "NETStandard.Library" - Some { current with Include = v } - let setVersion v = Some { current with Version = v } - match opt with - | Some "include", Some v -> addInclude v |> parsePackageReferenceOption' rest implicitArgumentCount - | Some "include", None -> raise (ArgumentException(sprintf "%s requires a value" "Include")) // @@@@@@@@@@@@@@@@@@@@@@@ Globalize me please - | Some "version", Some v -> setVersion v |> parsePackageReferenceOption' rest implicitArgumentCount - | Some "version", None -> raise (ArgumentException(sprintf "%s requires a value" "Version")) // @@@@@@@@@@@@@@@@@@@@@@@ Globalize me please - | Some "restoresources", Some v -> Some { current with RestoreSources = concat current.RestoreSources v } |> parsePackageReferenceOption' rest implicitArgumentCount - | Some "restoresources", None -> raise (ArgumentException(sprintf "%s requires a value" "RestoreSources")) // @@@@@@@@@@@@@@@@@@@@@@@ Globalize me please - | Some "script", Some v -> Some { current with Script = v } |> parsePackageReferenceOption' rest implicitArgumentCount - | Some "bl", value -> - match value with - | Some v when v.ToLowerInvariant() = "true" -> binLogPath <- Some None // auto-generated logging location - | Some v when v.ToLowerInvariant() = "false" -> binLogPath <- None // no logging - | Some path -> binLogPath <- Some(Some path) // explicit logging location - | None -> - // parser shouldn't get here because unkeyed values follow a different path, but for the sake of completeness and keeping the compiler happy, - // this is fine - binLogPath <- Some None // auto-generated logging location - parsePackageReferenceOption' rest implicitArgumentCount packageReference - | None, Some v -> - match v.ToLowerInvariant() with - | "bl" -> - // a bare 'bl' enables binary logging and is NOT interpreted as one of the positional arguments. On the off chance that the user actually wants - // to reference a package named 'bl' they still have the 'Include=bl' syntax as a fallback. - binLogPath <- Some None // auto-generated logging location - parsePackageReferenceOption' rest implicitArgumentCount packageReference - | _ -> - match implicitArgumentCount with - | 0 -> addInclude v - | 1 -> setVersion v - | _ -> raise (ArgumentException(sprintf "Unable to apply implicit argument number %d" (implicitArgumentCount + 1))) // @@@@@@@@@@@@@@@@@@@@@@@ Globalize me please - |> parsePackageReferenceOption' rest (implicitArgumentCount + 1) - | _ -> parsePackageReferenceOption' rest implicitArgumentCount packageReference - let options = getOptions line - parsePackageReferenceOption' options 0 None - lines - |> List.choose parsePackageReferenceOption - |> List.distinct - |> (fun l -> l, binLogPath) - -type [] FSharpDependencyManager (outputDir:string option) = - - let key = "nuget" - let name = "MsBuild Nuget DependencyManager" - let scriptsPath = - let path = Path.Combine(Path.GetTempPath(), key, Process.GetCurrentProcess().Id.ToString()) - match outputDir with - | None -> path - | Some v -> Path.Combine(path, v) - let generatedScripts = new ConcurrentDictionary() - let deleteScripts () = - try - if Directory.Exists(scriptsPath) then - () //Directory.Delete(scriptsPath, true) - with | _ -> () - - let deleteAtExit = - try - if not (File.Exists(scriptsPath)) then - Directory.CreateDirectory(scriptsPath) |> ignore - true - with | _ -> false - - let emitFile filename (body:string) = - try - // Create a file to write to - use sw = File.CreateText(filename) - sw.WriteLine(body) - with | _ -> () - - do if deleteAtExit then AppDomain.CurrentDomain.ProcessExit |> Event.add(fun _ -> deleteScripts () ) - - member __.Name = name - - member __.Key = key - - member __.ResolveDependencies(_scriptDir:string, _mainScriptName:string, _scriptName:string, packageManagerTextLines:string seq, tfm: string) : bool * string list * string list = - - let packageReferences, binLogPath = - packageManagerTextLines - |> List.ofSeq - |> FSharpDependencyManager.parsePackageReference - let packageReferenceLines = - packageReferences - |> List.map FSharpDependencyManager.formatPackageReference - |> Seq.concat - let packageReferenceText = String.Join(Environment.NewLine, packageReferenceLines) - - // Generate a project files - let generateAndBuildProjectArtifacts = - let writeFile path body = - if not (generatedScripts.ContainsKey(body.GetHashCode().ToString())) then - emitFile path body - - let fsProjectPath = Path.Combine(scriptsPath, "Project.fsproj") - - let generateProjBody = - generateProjectBody.Replace("$(TARGETFRAMEWORK)", tfm) - .Replace("$(PACKAGEREFERENCES)", packageReferenceText) - - writeFile (Path.Combine(scriptsPath, "Library.fs")) generateLibrarySource - writeFile fsProjectPath generateProjBody - - let succeeded, resultingFsx = buildProject fsProjectPath binLogPath - let fsx = - match resultingFsx with - | Some fsx -> [fsx] - | None -> [] - - succeeded, fsx, List.empty - - generateAndBuildProjectArtifacts diff --git a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fsproj b/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fsproj deleted file mode 100644 index 7faf2884f48..00000000000 --- a/src/fsharp/FSharp.DependencyManager/FSharp.DependencyManager.fsproj +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - Library - net472;netstandard2.0 - netstandard2.0 - FSharp.DependencyManager - $(NoWarn);45;55;62;75;1204 - true - $(DefineConstants);COMPILER - $(DefineConstants);MSBUILD_AT_LEAST_15 - $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 - true - - - - - $(BaseOutputPath)\$(Configuration)\$(TargetFramework) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.cs.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.cs.xlf deleted file mode 100644 index 1b2b7891240..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.cs.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.de.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.de.xlf deleted file mode 100644 index fad4a92c190..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.de.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.es.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.es.xlf deleted file mode 100644 index af7ece6ad9b..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.es.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.fr.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.fr.xlf deleted file mode 100644 index 42aa351aa0c..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.fr.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.it.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.it.xlf deleted file mode 100644 index da872e4f39d..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.it.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ja.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ja.xlf deleted file mode 100644 index e9e3444fcfb..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ja.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ko.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ko.xlf deleted file mode 100644 index 13f0865b931..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ko.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pl.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pl.xlf deleted file mode 100644 index e9718434a10..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pl.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pt-BR.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pt-BR.xlf deleted file mode 100644 index 6fb3374c226..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.pt-BR.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ru.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ru.xlf deleted file mode 100644 index 98624d79969..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.ru.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.tr.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.tr.xlf deleted file mode 100644 index a94d8e068e4..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.tr.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hans.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hans.xlf deleted file mode 100644 index 44e599a4143..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hans.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hant.xlf b/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hant.xlf deleted file mode 100644 index 83fa3521e6b..00000000000 --- a/src/fsharp/FSharp.DependencyManager/xlf/FSDependencyManager.txt.zh-Hant.xlf +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Not used. - Not used. - - - - - \ No newline at end of file diff --git a/src/fsharp/FindUnsolved.fs b/src/fsharp/FindUnsolved.fs index d11a1284176..40618fb8139 100644 --- a/src/fsharp/FindUnsolved.fs +++ b/src/fsharp/FindUnsolved.fs @@ -1,14 +1,14 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - /// Find unsolved, uninstantiated type variables module internal FSharp.Compiler.FindUnsolved +open Internal.Utilities.Collections +open Internal.Utilities.Library open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypeRelations @@ -109,7 +109,10 @@ let rec accExpr (cenv:cenv) (env:env) expr = | TTyconIsStruct(ty1) -> accTy cenv env ty1) - | Expr.Link _eref -> failwith "Unexpected reclink" + | Expr.WitnessArg (traitInfo, _m) -> + accTraitInfo cenv env traitInfo + + | Expr.Link _eref -> failwith "Unexpected Expr.Link" and accMethods cenv env baseValOpt l = List.iter (accMethod cenv env baseValOpt) l @@ -131,19 +134,22 @@ and accOp cenv env (op, tyargs, args, _m) = accExprs cenv env args match op with // Handle these as special cases since mutables are allowed inside their bodies - | TOp.ILCall (_, _, _, _, _, _, _, _, enclTypeArgs, methTypeArgs, tys) -> - accTypeInst cenv env enclTypeArgs - accTypeInst cenv env methTypeArgs - accTypeInst cenv env tys - | TOp.TraitCall (TTrait(tys, _nm, _, argtys, rty, _sln)) -> - argtys |> accTypeInst cenv env - rty |> Option.iter (accTy cenv env) - tys |> List.iter (accTy cenv env) + | TOp.ILCall (_, _, _, _, _, _, _, _, enclTypeInst, methInst, retTypes) -> + accTypeInst cenv env enclTypeInst + accTypeInst cenv env methInst + accTypeInst cenv env retTypes + | TOp.TraitCall traitInfo -> + accTraitInfo cenv env traitInfo - | TOp.ILAsm (_, tys) -> - accTypeInst cenv env tys + | TOp.ILAsm (_, retTypes) -> + accTypeInst cenv env retTypes | _ -> () +and accTraitInfo cenv env (TTrait(tys, _nm, _, argtys, rty, _sln)) = + argtys |> accTypeInst cenv env + rty |> Option.iter (accTy cenv env) + tys |> List.iter (accTy cenv env) + and accLambdas cenv env topValInfo e ety = match e with | Expr.TyChoose (_tps, e1, _m) -> accLambdas cenv env topValInfo e1 ety @@ -164,14 +170,14 @@ and accExprs cenv env exprs = and accTargets cenv env m ty targets = Array.iter (accTarget cenv env m ty) targets -and accTarget cenv env _m _ty (TTarget(_vs, e, _)) = +and accTarget cenv env _m _ty (TTarget(_vs, e, _, _)) = accExpr cenv env e and accDTree cenv env x = match x with | TDSuccess (es, _n) -> accExprs cenv env es | TDBind(bind, rest) -> accBind cenv env bind; accDTree cenv env rest - | TDSwitch (e, cases, dflt, m) -> accSwitch cenv env (e, cases, dflt, m) + | TDSwitch (_, e, cases, dflt, m) -> accSwitch cenv env (e, cases, dflt, m) and accSwitch cenv env (e, cases, dflt, _m) = accExpr cenv env e @@ -185,9 +191,10 @@ and accDiscrim cenv env d = | DecisionTreeTest.Const _ | DecisionTreeTest.IsNull -> () | DecisionTreeTest.IsInst (srcty, tgty) -> accTy cenv env srcty; accTy cenv env tgty - | DecisionTreeTest.ActivePatternCase (exp, tys, _, _, _) -> + | DecisionTreeTest.ActivePatternCase (exp, tys, _, _, _, _) -> accExpr cenv env exp accTypeInst cenv env tys + | DecisionTreeTest.Error _ -> () and accAttrib cenv env (Attrib(_, _k, args, props, _, _, _m)) = args |> List.iter (fun (AttribExpr(expr1, expr2)) -> @@ -246,11 +253,12 @@ and accModuleOrNamespaceDefs cenv env x = and accModuleOrNamespaceDef cenv env x = match x with - | TMDefRec(_, tycons, mbinds, _m) -> + | TMDefRec(_, _opens, tycons, mbinds, _m) -> accTycons cenv env tycons accModuleOrNamespaceBinds cenv env mbinds | TMDefLet(bind, _m) -> accBind cenv env bind | TMDefDo(e, _m) -> accExpr cenv env e + | TMDefOpens __ -> () | TMAbstract(def) -> accModuleOrNamespaceExpr cenv env def | TMDefs(defs) -> accModuleOrNamespaceDefs cenv env defs diff --git a/src/fsharp/FindUnsolved.fsi b/src/fsharp/FindUnsolved.fsi index c7c63d8335e..12c5c536bb0 100644 --- a/src/fsharp/FindUnsolved.fsi +++ b/src/fsharp/FindUnsolved.fsi @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - module internal FSharp.Compiler.FindUnsolved -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TcGlobals open FSharp.Compiler.Import diff --git a/src/fsharp/FxResolver.fs b/src/fsharp/FxResolver.fs new file mode 100644 index 00000000000..adc3b59417d --- /dev/null +++ b/src/fsharp/FxResolver.fs @@ -0,0 +1,892 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Functions to retrieve framework dependencies +namespace FSharp.Compiler + +open System +open System.Collections.Concurrent +open System.Collections.Generic +open System.Diagnostics +open System.Globalization +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open Internal.Utilities.FSharpEnvironment +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Text +open FSharp.Compiler.IO + +type internal FxResolverLockToken() = + interface LockToken + +type internal FxResolverLock = Lock + +/// Resolves the references for a chosen or currently-executing framework, for +/// - script execution +/// - script editing +/// - script compilation +/// - out-of-project sources editing +/// - default references for fsc.exe +/// - default references for fsi.exe +type internal FxResolver(assumeDotNetFramework: bool, projectDir: string, useSdkRefs: bool, isInteractive: bool, rangeForErrors: range, sdkDirOverride: string option) = + + let fxlock = FxResolverLock() + + static let RequireFxResolverLock (_fxtok: FxResolverLockToken, _thingProtected: 'T) = () + + /// We only try once for each directory (cleared on solution unload) to prevent conditions where + /// we repeatedly try to run dotnet.exe on every keystroke for a script + static let desiredDotNetSdkVersionForDirectoryCache = ConcurrentDictionary>() + + // Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever + // returns exit code, stdio and stderr as string arrays + let executeProcess pathToExe arguments (workingDir:string option) timeout = + if not (String.IsNullOrEmpty pathToExe) then + let errorsList = ResizeArray() + let outputList = ResizeArray() + let mutable errorslock = obj + let mutable outputlock = obj + let outputDataReceived (message: string) = + if not (isNull message) then + lock outputlock (fun () -> outputList.Add(message)) + + let errorDataReceived (message: string) = + if not (isNull message) then + lock errorslock (fun () -> errorsList.Add(message)) + + let psi = ProcessStartInfo() + psi.FileName <- pathToExe + if workingDir.IsSome then + psi.WorkingDirectory <- workingDir.Value + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.Arguments <- arguments + psi.CreateNoWindow <- true + psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things + psi.UseShellExecute <- false + + use p = new Process() + p.StartInfo <- psi + + p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data) + p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data) + + if p.Start() then + p.BeginOutputReadLine() + p.BeginErrorReadLine() + if not(p.WaitForExit(timeout)) then + // Timed out resolving throw a diagnostic. + raise (TimeoutException(sprintf "Timeout executing command '%s' '%s'" psi.FileName psi.Arguments)) + else + p.WaitForExit() +#if DEBUG + if workingDir.IsSome then + FileSystem.OpenFileForWriteShim(Path.Combine(workingDir.Value, "StandardOutput.txt")).WriteAllLines(outputList) + FileSystem.OpenFileForWriteShim(Path.Combine(workingDir.Value, "StandardError.txt")).WriteAllLines(errorsList) +#endif + p.ExitCode, outputList.ToArray(), errorsList.ToArray() + else + -1, Array.empty, Array.empty + + /// Find the relevant sdk version by running `dotnet --version` in the script/project location, + /// taking into account any global.json + let tryGetDesiredDotNetSdkVersionForDirectoryInfo() = + desiredDotNetSdkVersionForDirectoryCache.GetOrAdd(projectDir, (fun _ -> + match getDotnetHostPath() with + | Some dotnetHostPath -> + try + let workingDir = + if FileSystem.DirectoryExistsShim(projectDir) then + Some projectDir + else + None + let exitCode, output, errors = executeProcess dotnetHostPath "--version" workingDir 30000 + if exitCode <> 0 then + Result.Error (Error(FSComp.SR.scriptSdkNotDetermined(dotnetHostPath, projectDir, (errors |> String.concat "\n"), exitCode), rangeForErrors)) + else + Result.Ok (output |> String.concat "\n") + with err -> + Result.Error (Error(FSComp.SR.scriptSdkNotDetermined(dotnetHostPath, projectDir, err.Message, 1), rangeForErrors)) + | _ -> Result.Error (Error(FSComp.SR.scriptSdkNotDeterminedNoHost(), rangeForErrors)))) + + // We need to make sure the warning gets replayed each time, despite the lazy computations + // To do this we pass it back as data and eventually replay it at the entry points to FxResolver. + let tryGetDesiredDotNetSdkVersionForDirectory() = + match tryGetDesiredDotNetSdkVersionForDirectoryInfo() with + | Result.Ok res -> Some res, [] + | Result.Error exn -> None, [exn] + + // This is used to replay the warnings generated in the function above. + // It should not be used under the lazy on-demand computations in this type, nor should the warnings be explicitly ignored + let replayWarnings (res, warnings: exn list) = + for exn in warnings do warning exn + res + + /// Compute the .NET Core SDK directory relevant to projectDir, used to infer the default target framework assemblies. + /// + /// On-demand because (a) some FxResolver are ephemeral (b) we want to avoid recomputation + let trySdkDir = + lazy + // This path shouldn't be used with reflective processes + assert not isInteractive + match assumeDotNetFramework with + | true -> None, [] + | _ when not useSdkRefs -> None, [] + | _ -> + match sdkDirOverride with + | Some sdkDir -> Some sdkDir, [] + | None -> + let sdksDir = + match getDotnetHostDirectory() with + | Some dotnetDir -> + let candidate = FileSystem.GetFullPathShim(Path.Combine(dotnetDir, "sdk")) + if FileSystem.DirectoryExistsShim(candidate) then Some candidate else None + | None -> None + + match sdksDir with + | Some sdksDir -> + // Find the sdk version by running `dotnet --version` in the script/project location + let desiredSdkVer, warnings = tryGetDesiredDotNetSdkVersionForDirectory() + + let sdkDir = + DirectoryInfo(sdksDir).GetDirectories() + // Filter to the version reported by `dotnet --version` in the location, if that succeeded + // If it didn't succeed we will revert back to implementation assemblies, but still need an SDK + // to use, so we find the SDKs by looking for dotnet.runtimeconfig.json + |> Array.filter (fun di -> + match desiredSdkVer with + | None -> FileSystem.FileExistsShim(Path.Combine(di.FullName,"dotnet.runtimeconfig.json")) + | Some v -> di.Name = v) + |> Array.sortBy (fun di -> di.FullName) + |> Array.tryLast + |> Option.map (fun di -> di.FullName) + sdkDir, warnings + | _ -> + None, [] + + let tryGetSdkDir() = trySdkDir.Force() + + /// Get the framework implementation directory of the currently running process + let getRunningImplementationAssemblyDir() = + let filename = Path.GetDirectoryName(typeof.Assembly.Location) + if String.IsNullOrWhiteSpace filename then getFSharpCompilerLocation() else filename + + // Compute the framework implementation directory, either of the selected SDK or the currently running process as a backup + // F# interactive/reflective scenarios use the implementation directory of the currently running process + // + // On-demand because (a) some FxResolver are ephemeral (b) we want to avoid recomputation + let implementationAssemblyDir = + lazy + if isInteractive then + getRunningImplementationAssemblyDir(), [] + else + let sdkDir, warnings = tryGetSdkDir() + match sdkDir with + | Some dir -> + try + let dotnetConfigFile = Path.Combine(dir, "dotnet.runtimeconfig.json") + use stream = FileSystem.OpenFileForReadShim(dotnetConfigFile) + let dotnetConfig = stream.ReadAllText() + let pattern = "\"version\": \"" + let startPos = dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length + let endPos = dotnetConfig.IndexOf("\"", startPos) + let ver = dotnetConfig.[startPos..endPos-1] + let path = FileSystem.GetFullPathShim(Path.Combine(dir, "..", "..", "shared", "Microsoft.NETCore.App", ver)) + if FileSystem.DirectoryExistsShim(path) then + path, warnings + else + getRunningImplementationAssemblyDir(), warnings + with e -> + let warn = Error(FSComp.SR.scriptSdkNotDeterminedUnexpected(e.Message), rangeForErrors) + let path = getRunningImplementationAssemblyDir() + path, [warn] + | _ -> + let path = getRunningImplementationAssemblyDir() + path, [] + + let getImplementationAssemblyDir() = implementationAssemblyDir.Force() + + let getFSharpCoreLibraryName = "FSharp.Core" + + let getFsiLibraryName = "FSharp.Compiler.Interactive.Settings" + + // Use the FSharp.Core that is executing with the compiler as a backup reference + let getFSharpCoreImplementationReference() = Path.Combine(getFSharpCompilerLocation(), getFSharpCoreLibraryName + ".dll") + + // Use the FSharp.Compiler.Interactive.Settings executing with the compiler as a backup reference + let getFsiLibraryImplementationReference() = Path.Combine(getFSharpCompilerLocation(), getFsiLibraryName + ".dll") + + // Use the ValueTuple that is executing with the compiler if it is from System.ValueTuple + // or the System.ValueTuple.dll that sits alongside the compiler. (Note we always ship one with the compiler) + let getSystemValueTupleImplementationReference() = + let implDir = getImplementationAssemblyDir() |> replayWarnings + let probeFile = Path.Combine(implDir, "System.ValueTuple.dll") + if FileSystem.FileExistsShim(probeFile) then + Some probeFile + else + try + let asm = typeof>.Assembly + if asm.FullName.StartsWith("System.ValueTuple", StringComparison.OrdinalIgnoreCase) then + Some asm.Location + else + let valueTuplePath = Path.Combine(getFSharpCompilerLocation(), "System.ValueTuple.dll") + if FileSystem.FileExistsShim(valueTuplePath) then + Some valueTuplePath + else + None + with _ -> + // This is defensive coding, we don't expect this exception to happen + None + + // Algorithm: + // search the sdk for a versioned subdirectory of the sdk that matches or is lower than the version passed as an argument + // path is the path to the versioned directories + // it may be a subdirectory of a locally xcopied sdk or the global sdk + // version is nuget format version id e.g 5.0.1-preview-4.3 + // + let tryGetVersionedSubDirectory (path:string) (version:string) = + let zeroVersion = Version("0.0.0.0") + + // Split the version into a number + it's suffix + let computeVersion (version: string) = + let ver, suffix = + let suffixPos = version.IndexOf('-') + if suffixPos >= 0 then + version.Substring(0, suffixPos), version.Substring(suffixPos + 1) + else + version, "" + + match Version.TryParse(ver) with + | true, v -> v, suffix + | false, _ -> zeroVersion, suffix + + let compareVersion (v1:Version * string) (v2:Version * string) = + let fstCompare = (fst v1).CompareTo(fst v2) + if fstCompare <> 0 then + fstCompare + else + (snd v1).CompareTo(snd v2) + + let directories = getDotnetHostSubDirectories path + let targetVersion = computeVersion version + + if directories.Length > 0 then + directories + |> Array.map (fun di -> computeVersion di.Name, di) + |> Array.filter(fun (v, _) -> (compareVersion v targetVersion) <= 0) + |> Array.sortWith (fun (v1,_) (v2,_) -> compareVersion v1 v2) + |> Array.map snd + |> Array.tryLast + else + None + + // Algorithm: + // use implementation location of obj type, on shared frameworks it will always be in: + // + // dotnet\shared\Microsoft.NETCore.App\sdk-version\System.Private.CoreLib.dll + // + // if that changes we will need to find another way to do this. Hopefully the sdk will eventually provide an API + // use the well know location for obj to traverse the file system towards the + // + // packs\Microsoft.NETCore.App.Ref\sdk-version\netcoreappn.n + // we will rely on the sdk-version match on the two paths to ensure that we get the product that ships with the + // version of the runtime we are executing on + // Use the reference assemblies for the highest netcoreapp tfm that we find in that location. + // + // On-demand because (a) some FxResolver are ephemeral (b) we want to avoid recomputation + let tryNetCoreRefsPackDirectoryRoot = + lazy + try + // Use the reference assemblies for the highest netcoreapp tfm that we find in that location that is + // lower than or equal to the implementation version. + let implDir, warnings = getImplementationAssemblyDir() + let version = DirectoryInfo(implDir).Name + if version.StartsWith("x") then + // Is running on the desktop + (None, None), warnings + else + let di = tryGetVersionedSubDirectory "packs/Microsoft.NETCore.App.Ref" version + match di with + | Some di -> (Some(di.Name), Some(di.Parent.FullName)), warnings + | None -> (None, None), warnings + with e -> + let warn = Error(FSComp.SR.scriptSdkNotDeterminedUnexpected(e.Message), rangeForErrors) + // This is defensive coding, we don't expect this exception to happen + // NOTE: consider reporting this exception as a warning + (None, None), [warn] + + let tryGetNetCoreRefsPackDirectoryRoot() = tryNetCoreRefsPackDirectoryRoot.Force() + + // Tries to figure out the tfm for the compiler instance. + // On coreclr it uses the deps.json file + // + // On-demand because (a) some FxResolver are ephemeral (b) we want to avoid recomputation + let tryRunningDotNetCoreTfm = + lazy + let file = + try + let asm = Assembly.GetEntryAssembly() + match asm with + | null -> "" + | asm -> + let depsJsonPath = Path.ChangeExtension(asm.Location, "deps.json") + if FileSystem.FileExistsShim(depsJsonPath) then + use stream = FileSystem.OpenFileForReadShim(depsJsonPath) + stream.ReadAllText() + else + "" + with _ -> + // This is defensive coding, we don't expect this exception to happen + // NOTE: consider reporting this exception as a warning + "" + + let tfmPrefix=".NETCoreApp,Version=v" + let pattern = "\"name\": \"" + tfmPrefix + let startPos = + let startPos = file.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + if startPos >= 0 then startPos + pattern.Length else startPos + let length = + if startPos >= 0 then + let ep = file.IndexOf("\"", startPos) + if ep >= 0 then ep - startPos else ep + else -1 + match startPos, length with + | -1, _ + | _, -1 -> + if isRunningOnCoreClr then + // Running on coreclr but no deps.json was deployed with the host so default to 5.0 + Some "net5.0" + else + // Running on desktop + None + | pos, length -> + // use value from the deps.json file + let suffix = file.Substring(pos, length) + let prefix = + match Double.TryParse(suffix) with + | true, value when value < 5.0 -> "netcoreapp" + | _ -> "net" + Some (prefix + suffix) + + let tryGetRunningDotNetCoreTfm() = tryRunningDotNetCoreTfm.Force() + + // Tries to figure out the tfm for the compiler instance on the Windows desktop + // On full clr it uses the mscorlib version number + let getRunningDotNetFrameworkTfm () = + let defaultMscorlibVersion = 4,8,3815,0 + let desktopProductVersionMonikers = [| + // major, minor, build, revision, moniker + 4, 8, 3815, 0, "net48" + 4, 8, 3761, 0, "net48" + 4, 7, 3190, 0, "net472" + 4, 7, 3062, 0, "net472" + 4, 7, 2600, 0, "net471" + 4, 7, 2558, 0, "net471" + 4, 7, 2053, 0, "net47" + 4, 7, 2046, 0, "net47" + 4, 6, 1590, 0, "net462" + 4, 6, 57, 0, "net462" + 4, 6, 1055, 0, "net461" + 4, 6, 81, 0, "net46" + 4, 0, 30319, 34209, "net452" + 4, 0, 30319, 17020, "net452" + 4, 0, 30319, 18408, "net451" + 4, 0, 30319, 17929, "net45" + 4, 0, 30319, 1, "net4" + |] + + let majorPart, minorPart, buildPart, privatePart= + try + let attrOpt = typeof.Assembly.GetCustomAttributes(typeof) |> Seq.tryHead + match attrOpt with + | Some attr -> + let fv = (downcast attr : AssemblyFileVersionAttribute).Version.Split([|'.'|]) |> Array.map(fun e -> Int32.Parse(e)) + fv.[0], fv.[1], fv.[2], fv.[3] + | _ -> defaultMscorlibVersion + with _ -> defaultMscorlibVersion + + // Get the ProductVersion of this framework compare with table yield compatible monikers + match desktopProductVersionMonikers + |> Array.tryFind (fun (major, minor, build, revision, _) -> + (majorPart >= major) && + (minorPart >= minor) && + (buildPart >= build) && + (privatePart >= revision)) with + | Some (_,_,_,_,moniker) -> + moniker + | None -> + // no TFM could be found, assume latest stable? + "net48" + + let trySdkRefsPackDirectory = + lazy + let tfmPrefix = "netcoreapp" + let tfmCompare c1 c2 = + let deconstructTfmApp (netcoreApp: DirectoryInfo) = + let name = netcoreApp.Name + try + if name.StartsWith(tfmPrefix, StringComparison.InvariantCultureIgnoreCase) then + Some (Double.Parse(name.Substring(tfmPrefix.Length), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture)) + else + None + with _ -> + // This is defensive coding, we don't expect this exception to happen + // NOTE: consider reporting this exception as a warning + None + + if c1 = c2 then 0 + else + match (deconstructTfmApp c1), (deconstructTfmApp c2) with + | Some c1, Some c2 -> int(c1 - c2) + | None, Some _ -> -1 + | Some _, None -> 1 + | _ -> 0 + + match tryGetNetCoreRefsPackDirectoryRoot() with + | (Some version, Some root), warnings -> + try + let ref = Path.Combine(root, version, "ref") + let highestTfm = + DirectoryInfo(ref).GetDirectories() + |> Array.sortWith tfmCompare + |> Array.tryLast + + match highestTfm with + | Some tfm -> Some (Path.Combine(ref, tfm.Name)), warnings + | None -> None, warnings + with e -> + let warn = Error(FSComp.SR.scriptSdkNotDeterminedUnexpected(e.Message), rangeForErrors) + // This is defensive coding, we don't expect this exception to happen + // NOTE: consider reporting this exception as a warning + None, warnings @ [warn] + | _ -> None, [] + + let tryGetSdkRefsPackDirectory() = trySdkRefsPackDirectory.Force() + + let getDependenciesOf assemblyReferences = + let assemblies = Dictionary() + + // Identify path to a dll in the framework directory from a simple name + let frameworkPathFromSimpleName simpleName = + let implDir = getImplementationAssemblyDir() |> replayWarnings + let root = Path.Combine(implDir, simpleName) + let pathOpt = + [| ""; ".dll"; ".exe" |] + |> Seq.tryPick(fun ext -> + let path = root + ext + if FileSystem.FileExistsShim(path) then Some path + else None) + match pathOpt with + | Some path -> path + | None -> root + + // Collect all assembly dependencies into assemblies dictionary + let rec traverseDependencies reference = + // Reference can be either path to a file on disk or a Assembly Simple Name + let referenceName, path = + try + if FileSystem.FileExistsShim(reference) then + // Reference is a path to a file on disk + Path.GetFileNameWithoutExtension(reference), reference + else + // Reference is a SimpleAssembly name + reference, frameworkPathFromSimpleName reference + + with _ -> + // This is defensive coding, we don't expect this exception to happen + reference, frameworkPathFromSimpleName reference + + if not (assemblies.ContainsKey(referenceName)) then + try + if FileSystem.FileExistsShim(path) then + match referenceName with + | "System.Runtime.WindowsRuntime" + | "System.Runtime.WindowsRuntime.UI.Xaml" -> + // The Windows compatibility pack included in the runtime contains a reference to + // System.Runtime.WindowsRuntime, but to properly use that type the runtime also needs a + // reference to the Windows.md meta-package, which isn't referenced by default. To avoid + // a bug where types from `Windows, Version=255.255.255.255` can't be found we're going to + // not default include this assembly. It can still be manually referenced if it's needed + // via the System.Runtime.WindowsRuntime NuGet package. + // + // In the future this branch can be removed because WinRT support is being removed from the + // .NET 5 SDK (https://github.com/dotnet/runtime/pull/36715) + () + | "System.Private.CoreLib" -> + // System.Private.CoreLib doesn't load with reflection + assemblies.Add(referenceName, path) + | _ -> + try + let opts = + { metadataOnly = MetadataOnlyFlag.Yes // turn this off here as we need the actual IL code + reduceMemoryUsage = ReduceMemoryFlag.Yes + pdbDirPath = None + tryGetMetadataSnapshot = (fun _ -> None) (* tryGetMetadataSnapshot *) } + + let reader = OpenILModuleReader path opts + assemblies.Add(referenceName, path) + for reference in reader.ILAssemblyRefs do + traverseDependencies reference.Name + + // There are many native assemblies which can't be cracked, raising exceptions + with _ -> () + with _ -> () + + assemblyReferences |> List.iter traverseDependencies + assemblies + + // This list is the default set of references for "non-project" files. + // + // These DLLs are + // (a) included in the environment used for all .fsx files (see service.fs) + // (b) included in environment for files 'orphaned' from a project context + // -- for orphaned files (files in VS without a project context) + let getDotNetFrameworkDefaultReferences useFsiAuxLib = [ + yield "mscorlib" + yield "System" + yield "System.Xml" + yield "System.Runtime.Remoting" + yield "System.Runtime.Serialization.Formatters.Soap" + yield "System.Data" + yield "System.Drawing" + yield "System.Core" + yield "System.Configuration" + + yield getFSharpCoreLibraryName + if useFsiAuxLib then yield fsiLibraryName + + // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources + match getSystemValueTupleImplementationReference () with + | None -> () + | Some v -> yield v + + // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed + // when an F# script references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers + // to FSharp.Core for profile 7, 78, 259 or .NET Standard. + yield "netstandard" + yield "System.Runtime" // lots of types + yield "System.Linq" // System.Linq.Expressions.Expression + yield "System.Reflection" // System.Reflection.ParameterInfo + yield "System.Linq.Expressions" // System.Linq.IQueryable + yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken + yield "System.IO" // System.IO.TextWriter + yield "System.Net.Requests" // System.Net.WebResponse etc. + yield "System.Collections" // System.Collections.Generic.List + yield "System.Runtime.Numerics" // BigInteger + yield "System.Threading" // OperationCanceledException + yield "System.Web" + yield "System.Web.Services" + yield "System.Windows.Forms" + yield "System.Numerics" + ] + + let getDotNetCoreImplementationReferences useFsiAuxLib = + let implDir = getImplementationAssemblyDir() |> replayWarnings + let roots = + [ yield! Directory.GetFiles(implDir, "*.dll") + yield getFSharpCoreImplementationReference() + if useFsiAuxLib then yield getFsiLibraryImplementationReference() ] + (getDependenciesOf roots).Values |> Seq.toList + + // A set of assemblies to always consider to be system assemblies. A common set of these can be used a shared + // resources between projects in the compiler services. Also all assemblies where well-known system types exist + // referenced from TcGlobals must be listed here. + let systemAssemblies = + HashSet [ + // NOTE: duplicates are ok in this list + + // .NET Framework list + yield "mscorlib" + yield "netstandard" + yield "System" + yield getFSharpCoreLibraryName + yield "FSharp.Compiler.Interactive.Settings" + yield "Microsoft.CSharp" + yield "Microsoft.VisualBasic" + yield "Microsoft.VisualBasic.Core" + yield "Microsoft.Win32.Primitives" + yield "Microsoft.Win32.Registry" + yield "System.AppContext" + yield "System.Buffers" + yield "System.Collections" + yield "System.Collections.Concurrent" + yield "System.Collections.Immutable" + yield "System.Collections.NonGeneric" + yield "System.Collections.Specialized" + yield "System.ComponentModel" + yield "System.ComponentModel.Annotations" + yield "System.ComponentModel.DataAnnotations" + yield "System.ComponentModel.EventBasedAsync" + yield "System.ComponentModel.Primitives" + yield "System.ComponentModel.TypeConverter" + yield "System.Configuration" + yield "System.Console" + yield "System.Core" + yield "System.Data" + yield "System.Data.Common" + yield "System.Data.DataSetExtensions" + yield "System.Deployment" + yield "System.Design" + yield "System.Diagnostics.Contracts" + yield "System.Diagnostics.Debug" + yield "System.Diagnostics.DiagnosticSource" + yield "System.Diagnostics.FileVersionInfo" + yield "System.Diagnostics.Process" + yield "System.Diagnostics.StackTrace" + yield "System.Diagnostics.TextWriterTraceListener" + yield "System.Diagnostics.Tools" + yield "System.Diagnostics.TraceSource" + yield "System.Diagnostics.Tracing" + yield "System.Drawing" + yield "System.Drawing.Primitives" + yield "System.Dynamic.Runtime" + yield "System.Formats.Asn1" + yield "System.Globalization" + yield "System.Globalization.Calendars" + yield "System.Globalization.Extensions" + yield "System.IO" + yield "System.IO.Compression" + yield "System.IO.Compression.Brotli" + yield "System.IO.Compression.FileSystem" + yield "System.IO.Compression.ZipFile" + yield "System.IO.FileSystem" + yield "System.IO.FileSystem.DriveInfo" + yield "System.IO.FileSystem.Primitives" + yield "System.IO.FileSystem.Watcher" + yield "System.IO.IsolatedStorage" + yield "System.IO.MemoryMappedFiles" + yield "System.IO.Pipes" + yield "System.IO.UnmanagedMemoryStream" + yield "System.Linq" + yield "System.Linq.Expressions" + yield "System.Linq.Expressions" + yield "System.Linq.Parallel" + yield "System.Linq.Queryable" + yield "System.Memory" + yield "System.Messaging" + yield "System.Net" + yield "System.Net.Http" + yield "System.Net.Http.Json" + yield "System.Net.HttpListener" + yield "System.Net.Mail" + yield "System.Net.NameResolution" + yield "System.Net.NetworkInformation" + yield "System.Net.Ping" + yield "System.Net.Primitives" + yield "System.Net.Requests" + yield "System.Net.Security" + yield "System.Net.ServicePoint" + yield "System.Net.Sockets" + yield "System.Net.WebClient" + yield "System.Net.WebHeaderCollection" + yield "System.Net.WebProxy" + yield "System.Net.WebSockets" + yield "System.Net.WebSockets.Client" + yield "System.Numerics" + yield "System.Numerics.Vectors" + yield "System.ObjectModel" + yield "System.Observable" + yield "System.Private.Uri" + yield "System.Reflection" + yield "System.Reflection.DispatchProxy" + yield "System.Reflection.Emit" + yield "System.Reflection.Emit.ILGeneration" + yield "System.Reflection.Emit.Lightweight" + yield "System.Reflection.Extensions" + yield "System.Reflection.Metadata" + yield "System.Reflection.Primitives" + yield "System.Reflection.TypeExtensions" + yield "System.Resources.Reader" + yield "System.Resources.ResourceManager" + yield "System.Resources.Writer" + yield "System.Runtime" + yield "System.Runtime.CompilerServices.Unsafe" + yield "System.Runtime.CompilerServices.VisualC" + yield "System.Runtime.Extensions" + yield "System.Runtime.Handles" + yield "System.Runtime.InteropServices" + yield "System.Runtime.InteropServices.PInvoke" + yield "System.Runtime.InteropServices.RuntimeInformation" + yield "System.Runtime.InteropServices.WindowsRuntime" + yield "System.Runtime.Intrinsics" + yield "System.Runtime.Loader" + yield "System.Runtime.Numerics" + yield "System.Runtime.Remoting" + yield "System.Runtime.Serialization" + yield "System.Runtime.Serialization.Formatters" + yield "System.Runtime.Serialization.Formatters.Soap" + yield "System.Runtime.Serialization.Json" + yield "System.Runtime.Serialization.Primitives" + yield "System.Runtime.Serialization.Xml" + yield "System.Security" + yield "System.Security.Claims" + yield "System.Security.Cryptography.Algorithms" + yield "System.Security.Cryptography.Cng" + yield "System.Security.Cryptography.Csp" + yield "System.Security.Cryptography.Encoding" + yield "System.Security.Cryptography.OpenSsl" + yield "System.Security.Cryptography.Primitives" + yield "System.Security.Cryptography.X509Certificates" + yield "System.Security.Principal" + yield "System.Security.Principal.Windows" + yield "System.Security.SecureString" + yield "System.ServiceModel.Web" + yield "System.ServiceProcess" + yield "System.Text.Encoding" + yield "System.Text.Encoding.CodePages" + yield "System.Text.Encoding.Extensions" + yield "System.Text.Encodings.Web" + yield "System.Text.Json" + yield "System.Text.RegularExpressions" + yield "System.Threading" + yield "System.Threading.Channels" + yield "System.Threading.Overlapped" + yield "System.Threading.Tasks" + yield "System.Threading.Tasks.Dataflow" + yield "System.Threading.Tasks.Extensions" + yield "System.Threading.Tasks.Parallel" + yield "System.Threading.Thread" + yield "System.Threading.ThreadPool" + yield "System.Threading.Timer" + yield "System.Transactions" + yield "System.Transactions.Local" + yield "System.ValueTuple" + yield "System.Web" + yield "System.Web.HttpUtility" + yield "System.Web.Services" + yield "System.Windows" + yield "System.Windows.Forms" + yield "System.Xml" + yield "System.Xml.Linq" + yield "System.Xml.ReaderWriter" + yield "System.Xml.Serialization" + yield "System.Xml.XDocument" + yield "System.Xml.XmlDocument" + yield "System.Xml.XmlSerializer" + yield "System.Xml.XPath" + yield "System.Xml.XPath.XDocument" + yield "WindowsBase" + ] + + member _.GetSystemAssemblies() = systemAssemblies + + member _.IsInReferenceAssemblyPackDirectory filename = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + + match tryGetNetCoreRefsPackDirectoryRoot() |> replayWarnings with + | _, Some root -> + let path = Path.GetDirectoryName(filename) + path.StartsWith(root, StringComparison.OrdinalIgnoreCase) + | _ -> false + + member _.TryGetSdkDir() = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + tryGetSdkDir() |> replayWarnings + + /// Gets the selected target framework moniker, e.g netcore3.0, net472, and the running rid of the current machine + member _.GetTfmAndRid() = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + // Interactive processes read their own configuration to find the running tfm + + let tfm = + if isInteractive then + match tryGetRunningDotNetCoreTfm() with + | Some tfm -> tfm + | _ -> getRunningDotNetFrameworkTfm () + else + let sdkDir = tryGetSdkDir() |> replayWarnings + match sdkDir with + | Some dir -> + let dotnetConfigFile = Path.Combine(dir, "dotnet.runtimeconfig.json") + use stream = FileSystem.OpenFileForReadShim(dotnetConfigFile) + let dotnetConfig = stream.ReadAllText() + let pattern = "\"tfm\": \"" + let startPos = dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length + let endPos = dotnetConfig.IndexOf("\"", startPos) + let tfm = dotnetConfig.[startPos..endPos-1] + //printfn "GetTfmAndRid, tfm = '%s'" tfm + tfm + | None -> + match tryGetRunningDotNetCoreTfm() with + | Some tfm -> tfm + | _ -> getRunningDotNetFrameworkTfm () + + // Computer valid dotnet-rids for this environment: + // https://docs.microsoft.com/en-us/dotnet/core/rid-catalog + // + // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... + let runningRid = + let processArchitecture = RuntimeInformation.ProcessArchitecture + let baseRid = + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then "win" + elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then "osx" + else "linux" + match processArchitecture with + | Architecture.X64 -> baseRid + "-x64" + | Architecture.X86 -> baseRid + "-x86" + | Architecture.Arm64 -> baseRid + "-arm64" + | _ -> baseRid + "-arm" + + tfm, runningRid + + static member ClearStaticCaches() = + desiredDotNetSdkVersionForDirectoryCache.Clear() + + member _.GetFrameworkRefsPackDirectory() = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + tryGetSdkRefsPackDirectory() |> replayWarnings + + member _.TryGetDesiredDotNetSdkVersionForDirectory() = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + tryGetDesiredDotNetSdkVersionForDirectoryInfo() + + // The set of references entered into the TcConfigBuilder for scripts prior to computing the load closure. + member _.GetDefaultReferences useFsiAuxLib = + fxlock.AcquireLock <| fun fxtok -> + RequireFxResolverLock(fxtok, "assuming all member require lock") + let defaultReferences = + if assumeDotNetFramework then + getDotNetFrameworkDefaultReferences useFsiAuxLib, assumeDotNetFramework + else + if useSdkRefs then + // Go fetch references + let sdkDir = tryGetSdkRefsPackDirectory() |> replayWarnings + match sdkDir with + | Some path -> + try + let sdkReferences = + [ yield! Directory.GetFiles(path, "*.dll") + yield getFSharpCoreImplementationReference() + if useFsiAuxLib then yield getFsiLibraryImplementationReference() + ] |> List.filter(fun f -> systemAssemblies.Contains(Path.GetFileNameWithoutExtension(f))) + sdkReferences, false + with e -> + warning (Error(FSComp.SR.scriptSdkNotDeterminedUnexpected(e.Message), rangeForErrors)) + // This is defensive coding, we don't expect this exception to happen + if isRunningOnCoreClr then + // If running on .NET Core and something goes wrong with getting the + // .NET Core references then use .NET Core implementation assemblies for running process + getDotNetCoreImplementationReferences useFsiAuxLib, false + else + // If running on .NET Framework and something goes wrong with getting the + // .NET Core references then default back to .NET Framework and return a flag indicating this has been done + getDotNetFrameworkDefaultReferences useFsiAuxLib, true + | None -> + if isRunningOnCoreClr then + // If running on .NET Core and there is no Sdk refs pack directory + // then use .NET Core implementation assemblies for running process + getDotNetCoreImplementationReferences useFsiAuxLib, false + else + // If running on .NET Framework and there is no Sdk refs pack directory + // then default back to .NET Framework and return a flag indicating this has been done + getDotNetFrameworkDefaultReferences useFsiAuxLib, true + else + getDotNetCoreImplementationReferences useFsiAuxLib, assumeDotNetFramework + defaultReferences diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 9534358624d..911abb26323 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1,52 +1,55 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//-------------------------------------------------------------------------- -// The ILX generator. -//-------------------------------------------------------------------------- - +/// The ILX generator. module internal FSharp.Compiler.IlxGen open System.IO open System.Reflection open System.Collections.Generic +open FSharp.Compiler.IO open Internal.Utilities open Internal.Utilities.Collections - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types -open FSharp.Compiler.AbstractIL.Internal.BinaryConstants +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.BinaryConstants +open FSharp.Compiler.AbstractIL.ILX +open FSharp.Compiler.AbstractIL.ILX.Types open FSharp.Compiler.AttributeChecking -open FSharp.Compiler.Ast +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features open FSharp.Compiler.Infos open FSharp.Compiler.Import -open FSharp.Compiler.Layout -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint +open FSharp.Compiler.LowerCallsAndSeqs +open FSharp.Compiler.LowerStateMachines +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint open FSharp.Compiler.TypeRelations -let IsNonErasedTypar (tp: Typar) = +let IsNonErasedTypar (tp: Typar) = not tp.IsErased let DropErasedTypars (tps: Typar list) = tps |> List.filter IsNonErasedTypar -let DropErasedTyargs tys = +let DropErasedTyargs tys = tys |> List.filter (fun ty -> match ty with TType_measure _ -> false | _ -> true) -let AddNonUserCompilerGeneratedAttribs (g: TcGlobals) (mdef: ILMethodDef) = +let AddNonUserCompilerGeneratedAttribs (g: TcGlobals) (mdef: ILMethodDef) = g.AddMethodGeneratedAttributes mdef let debugDisplayMethodName = "__DebugDisplay" @@ -67,9 +70,11 @@ let mkLdfldMethodDef (ilMethName, reprAccess, isStatic, ilTy, ilFieldName, ilPro let ilReturn = mkILReturn ilPropType let ilMethodDef = if isStatic then - mkILNonGenericStaticMethod (ilMethName, reprAccess, [], ilReturn, mkMethodBody(true, [], 2, nonBranchingInstrsToCode [mkNormalLdsfld ilFieldSpec], None)) + let body = mkMethodBody(true, [], 2, nonBranchingInstrsToCode [mkNormalLdsfld ilFieldSpec], None, None) + mkILNonGenericStaticMethod (ilMethName, reprAccess, [], ilReturn, body) else - mkILNonGenericInstanceMethod (ilMethName, reprAccess, [], ilReturn, mkMethodBody (true, [], 2, nonBranchingInstrsToCode [ mkLdarg0; mkNormalLdfld ilFieldSpec], None)) + let body = mkMethodBody (true, [], 2, nonBranchingInstrsToCode [ mkLdarg0; mkNormalLdfld ilFieldSpec], None, None) + mkILNonGenericInstanceMethod (ilMethName, reprAccess, [], ilReturn, body) ilMethodDef.WithSpecialName /// Choose the constructor parameter names for fields @@ -102,7 +107,11 @@ let ChooseFreeVarNames takenNames ts = ts /// We can't tailcall to methods taking byrefs. This helper helps search for them -let IsILTypeByref = function ILType.Byref _ -> true | _ -> false +let rec IsILTypeByref inp = + match inp with + | ILType.Byref _ -> true + | ILType.Modified(_, _, nestedTy) -> IsILTypeByref nestedTy + | _ -> false let mainMethName = CompilerGeneratedName "main" @@ -113,15 +122,15 @@ type AttributeDecoder(namedArgs) = let findConst x = match NameMap.tryFind x nameMap with | Some(AttribExpr(_, Expr.Const (c, _, _))) -> Some c | _ -> None let findAppTr x = match NameMap.tryFind x nameMap with | Some(AttribExpr(_, Expr.App (_, _, [TType_app(tr, _)], _, _))) -> Some tr | _ -> None - member __.FindInt16 x dflt = match findConst x with | Some(Const.Int16 x) -> x | _ -> dflt + member _.FindInt16 x dflt = match findConst x with | Some(Const.Int16 x) -> x | _ -> dflt - member __.FindInt32 x dflt = match findConst x with | Some(Const.Int32 x) -> x | _ -> dflt + member _.FindInt32 x dflt = match findConst x with | Some(Const.Int32 x) -> x | _ -> dflt - member __.FindBool x dflt = match findConst x with | Some(Const.Bool x) -> x | _ -> dflt + member _.FindBool x dflt = match findConst x with | Some(Const.Bool x) -> x | _ -> dflt - member __.FindString x dflt = match findConst x with | Some(Const.String x) -> x | _ -> dflt + member _.FindString x dflt = match findConst x with | Some(Const.String x) -> x | _ -> dflt - member __.FindTypeName x dflt = match findAppTr x with | Some tr -> tr.DisplayName | _ -> dflt + member _.FindTypeName x dflt = match findAppTr x with | Some tr -> tr.DisplayName | _ -> dflt //-------------------------------------------------------------------------- // Statistics @@ -129,17 +138,17 @@ type AttributeDecoder(namedArgs) = let mutable reports = (fun _ -> ()) -let AddReport f = - let old = reports +let AddReport f = + let old = reports reports <- (fun oc -> old oc; f oc) -let ReportStatistics (oc: TextWriter) = +let ReportStatistics (oc: TextWriter) = reports oc let NewCounter nm = - let count = ref 0 - AddReport (fun oc -> if !count <> 0 then oc.WriteLine (string !count + " " + nm)) - (fun () -> incr count) + let mutable count = 0 + AddReport (fun oc -> if count <> 0 then oc.WriteLine (string count + " " + nm)) + (fun () -> count <- count + 1) let CountClosure = NewCounter "closures" @@ -151,7 +160,7 @@ let CountCallFuncInstructions = NewCounter "callfunc instructions (indirect call /// Non-local information related to internals of code generation within an assembly type IlxGenIntraAssemblyInfo = - { + { /// A table recording the generated name of the static backing fields for each mutable top level value where /// we may need to take the address of that value, e.g. static mutable module-bound values which are structs. These are /// only accessible intra-assembly. Across assemblies, taking the address of static mutable module-bound values is not permitted. @@ -173,33 +182,33 @@ type IlxGenBackend = [] type IlxGenOptions = - { + { /// Indicates the "fragment name" for the part of the assembly we are emitting, particularly for incremental /// emit using Reflection.Emit in F# Interactive. fragName: string - + /// Indicates if we are generating filter blocks generateFilterBlocks: bool - + /// Indicates if we are working around historical Reflection.Emit bugs workAroundReflectionEmitBugs: bool - + /// Indicates if we should/shouldn't emit constant arrays as static data blobs emitConstantArraysUsingStaticDataBlobs: bool - + /// If this is set, then the last module becomes the "main" module and its toplevel bindings are executed at startup - mainMethodInfo: Tast.Attribs option - + mainMethodInfo: Attribs option + /// Indicates if local optimizations are on - localOptimizationsAreOn: bool - + localOptimizationsEnabled: bool + /// Indicates if we are generating debug symbols generateDebugSymbols: bool - - /// Indicates that FeeFee debug values should be emitted as value 100001 for + + /// Indicates that FeeFee debug values should be emitted as value 100001 for /// easier detection in debug output testFlagEmitFeeFeeAs100001: bool - + ilxBackend: IlxGenBackend /// Indicates the code is being generated in FSI.EXE and is executed immediately after code generation @@ -211,40 +220,40 @@ type IlxGenOptions = isInteractiveItExpr: bool /// Whenever possible, use callvirt instead of call - alwaysCallVirt: bool + alwaysCallVirt: bool } /// Compilation environment for compiling a fragment of an assembly [] type cenv = - { + { /// The TcGlobals for the compilation g: TcGlobals - + /// The ImportMap for reading IL amap: ImportMap - - /// A callback for TcVal in the typechecker. Used to generalize values when finding witnesses. + + /// A callback for TcVal in the typechecker. Used to generalize values when finding witnesses. /// It is unfortunate this is needed but it is until we supply witnesses through the compilation. - TcVal: ConstraintSolver.TcValF - + tcVal: ConstraintSolver.TcValF + /// The TAST for the assembly being emitted viewCcu: CcuThunk - + /// The options for ILX code generation opts: IlxGenOptions - + /// Cache the generation of the "unit" type mutable ilUnitTy: ILType option - + /// Other information from the emit of this assembly intraAssemblyInfo: IlxGenIntraAssemblyInfo - + /// Cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType casApplied: Dictionary - + /// Used to apply forced inlining optimizations to witnesses generated late during codegen - mutable optimizeDuringCodeGen: (Expr -> Expr) + mutable optimizeDuringCodeGen: bool -> Expr -> Expr /// What depth are we at when generating an expression? mutable exprRecursionDepth: int @@ -261,7 +270,7 @@ let mkTypeOfExpr cenv m ilty = mkAsmExpr ([ mkNormalCall (mspec_Type_GetTypeFromHandle g) ], [], [mkAsmExpr ([ I_ldtoken (ILToken.ILType ilty) ], [], [], [g.system_RuntimeTypeHandle_ty], m)], [g.system_Type_ty], m) - + let mkGetNameExpr cenv (ilt: ILType) m = mkAsmExpr ([I_ldstr ilt.BasicQualifiedName], [], [], [cenv.g.string_ty], m) @@ -274,7 +283,7 @@ let useCallVirt cenv boxity (mspec: ILMethodSpec) isBaseCall = /// Describes where items are to be placed within the generated IL namespace/typespace. /// This should be cleaned up. type CompileLocation = - { Scope: IL.ILScopeRef + { Scope: ILScopeRef TopImplQualifiedName: string @@ -329,7 +338,7 @@ let NestedTypeRefForCompLoc cloc n = let tyname = mkTopName cloc.Namespace n mkILTyRef(cloc.Scope, tyname) | h :: t -> mkILNestedTyRef(cloc.Scope, mkTopName cloc.Namespace h :: t, n) - + let CleanUpGeneratedTypeName (nm: string) = if nm.IndexOfAny IllegalCharactersInTypeAndNamespaceNames = -1 then nm @@ -379,17 +388,23 @@ let ComputeTypeAccess (tref: ILTypeRef) hidden = match tref.Enclosing with | [] -> if hidden then ILTypeDefAccess.Private else ComputePublicTypeAccess() | _ -> ILTypeDefAccess.Nested (ComputeMemberAccess hidden) - + //-------------------------------------------------------------------------- // TypeReprEnv //-------------------------------------------------------------------------- /// Indicates how type parameters are mapped to IL type variables [] -type TypeReprEnv(reprs: Map, count: int) = +type TypeReprEnv(reprs: Map, count: int, templateReplacement: (TyconRef * ILType * TyparInst) option) = + + static let empty = TypeReprEnv(count = 0, reprs = Map.empty, templateReplacement = None) + /// Get the template replacement information used when using struct types for state machines based on a "template" struct + member __.TemplateReplacement = templateReplacement + + member __.WithTemplateReplacement(tcref, ilty, tpinst) = TypeReprEnv(reprs, count, Some (tcref, ilty, tpinst)) /// Lookup a type parameter - member __.Item (tp: Typar, m: range) = + member _.Item (tp: Typar, m: range) = try reprs.[tp.Stamp] with :? KeyNotFoundException -> errorR(InternalError("Undefined or unsolved type variable: " + showL(typarL tp), m)) @@ -400,7 +415,7 @@ type TypeReprEnv(reprs: Map, count: int) = /// then it is ignored, since it doesn't correspond to a .NET type parameter. member tyenv.AddOne (tp: Typar) = if IsNonErasedTypar tp then - TypeReprEnv(reprs.Add (tp.Stamp, uint16 count), count + 1) + TypeReprEnv(reprs.Add (tp.Stamp, uint16 count), count + 1, templateReplacement) else tyenv @@ -409,24 +424,26 @@ type TypeReprEnv(reprs: Map, count: int) = (tyenv, tps) ||> List.fold (fun tyenv tp -> tyenv.AddOne tp) /// Get the count of the non-erased type parameters in scope. - member __.Count = count + member _.Count = count /// Get the empty environment, where no type parameters are in scope. - static member Empty = - TypeReprEnv(count = 0, reprs = Map.empty) + static member Empty = empty + + /// Reset to the empty environment, where no type parameters are in scope. + member eenv.ResetTypars() = + TypeReprEnv(count = 0, reprs = Map.empty, templateReplacement = eenv.TemplateReplacement) /// Get the environment for a fixed set of type parameters - static member ForTypars tps = - TypeReprEnv.Empty.Add tps - + member eenv.ForTypars tps = + eenv.ResetTypars().Add tps + /// Get the environment for within a type definition - static member ForTycon (tycon: Tycon) = - TypeReprEnv.ForTypars (tycon.TyparsNoRange) - + member eenv.ForTycon (tycon: Tycon) = + eenv.ForTypars tycon.TyparsNoRange + /// Get the environment for generating a reference to items within a type definition - static member ForTyconRef (tycon: TyconRef) = - TypeReprEnv.ForTycon tycon.Deref - + member eenv.ForTyconRef (tycon: TyconRef) = + eenv.ForTycon tycon.Deref //-------------------------------------------------------------------------- // Generate type references @@ -437,7 +454,7 @@ let GenTyconRef (tcref: TyconRef) = assert(not tcref.IsTypeAbbrev) tcref.CompiledRepresentation -type VoidNotOK = +type VoidNotOK = | VoidNotOK | VoidOK @@ -458,7 +475,7 @@ type PtrsOK = let GenReadOnlyAttributeIfNecessary (g: TcGlobals) ty = let add = isInByrefTy g ty && g.attrib_IsReadOnlyAttribute.TyconRef.CanDeref if add then - let attr = mkILCustomAttribute g.ilg (g.attrib_IsReadOnlyAttribute.TypeRef, [], [], []) + let attr = mkILCustomAttribute (g.attrib_IsReadOnlyAttribute.TypeRef, [], [], []) Some attr else None @@ -481,7 +498,7 @@ and GenTyAppAux amap m tyenv repr tinst = match repr with | CompiledTypeRepr.ILAsmOpen ty -> let ilTypeInst = GenTypeArgsAux amap m tyenv tinst - let ty = IL.instILType ilTypeInst ty + let ty = instILType ilTypeInst ty ty | CompiledTypeRepr.ILAsmNamed (tref, boxity, ilTypeOpt) -> GenILTyAppAux amap m tyenv (tref, boxity, ilTypeOpt) tinst @@ -494,10 +511,12 @@ and GenILTyAppAux amap m tyenv (tref, boxity, ilTypeOpt) tinst = | Some ilType -> ilType // monomorphic types include a cached ilType to avoid reallocation of an ILType node -and GenNamedTyAppAux (amap: ImportMap) m tyenv ptrsOK tcref tinst = +and GenNamedTyAppAux (amap: ImportMap) m (tyenv: TypeReprEnv) ptrsOK tcref tinst = let g = amap.g + match tyenv.TemplateReplacement with + | Some (tcref2, ilty, _) when tyconRefEq g tcref tcref2 -> ilty + | _ -> let tinst = DropErasedTyargs tinst - // See above note on ptrsOK if ptrsOK = PtrTypesOK && tyconRefEq g tcref g.nativeptr_tcr && (freeInTypes CollectTypars tinst).FreeTypars.IsEmpty then GenNamedTyAppAux amap m tyenv ptrsOK g.ilsigptr_tcr tinst @@ -505,7 +524,7 @@ and GenNamedTyAppAux (amap: ImportMap) m tyenv ptrsOK tcref tinst = #if !NO_EXTENSIONTYPING match tcref.TypeReprInfo with // Generate the base type, because that is always the representation of the erased type, unless the assembly is being injected - | TProvidedTypeExtensionPoint info when info.IsErased -> + | TProvidedTypeRepr info when info.IsErased -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (info.BaseTypeForErased (m, g.obj_ty)) | _ -> #endif @@ -520,7 +539,7 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty = #endif match stripTyEqnsAndMeasureEqns g ty with | TType_app (tcref, tinst) -> GenNamedTyAppAux amap m tyenv ptrsOK tcref tinst - + | TType_tuple (tupInfo, args) -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args) @@ -551,9 +570,9 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty = and GenUnionCaseRef (amap: ImportMap) m tyenv i (fspecs: RecdField[]) = let g = amap.g fspecs |> Array.mapi (fun j fspec -> - let ilFieldDef = IL.mkILInstanceField(fspec.Name, GenType amap m tyenv fspec.FormalType, None, ILMemberAccess.Public) + let ilFieldDef = mkILInstanceField(fspec.LogicalName, GenType amap m tyenv fspec.FormalType, None, ILMemberAccess.Public) // These properties on the "field" of an alternative end up going on a property generated by cu_erase.fs - IlxUnionField + IlxUnionCaseField (ilFieldDef.With(customAttrs = mkILCustomAttrs [(mkCompilationMappingAttrWithVariantNumAndSeqNum g (int SourceConstructFlags.Field) i j )]))) @@ -565,7 +584,7 @@ and GenUnionRef (amap: ImportMap) m (tcref: TyconRef) = | ValueNone -> failwith "GenUnionRef m" | ValueSome funion -> cached funion.CompiledRepresentation (fun () -> - let tyenvinner = TypeReprEnv.ForTycon tycon + let tyenvinner = TypeReprEnv.Empty.ForTycon tycon match tcref.CompiledRepresentation with | CompiledTypeRepr.ILAsmOpen _ -> failwith "GenUnionRef m: unexpected ASM tyrep" | CompiledTypeRepr.ILAsmNamed (tref, _, _) -> @@ -663,70 +682,151 @@ let GenFieldSpecForStaticField (isInteractive, g, ilContainerTy, vspec: Val, nm, let ilFieldContainerTy = mkILTyForCompLoc (CompLocForInitClass cloc) mkILFieldSpecInTy (ilFieldContainerTy, fieldName, ilTy) -let GenRecdFieldRef m cenv tyenv (rfref: RecdFieldRef) tyargs = - let tyenvinner = TypeReprEnv.ForTycon rfref.Tycon - mkILFieldSpecInTy(GenTyApp cenv.amap m tyenv rfref.TyconRef.CompiledRepresentation tyargs, + +let GenRecdFieldRef m cenv (tyenv: TypeReprEnv) (rfref: RecdFieldRef) tyargs = + // Fixup references to the fields of a struct machine template + match tyenv.TemplateReplacement with + | Some (tcref2, ilty, inst) when tyconRefEq cenv.g rfref.TyconRef tcref2 -> + mkILFieldSpecInTy(ilty, + ComputeFieldName rfref.Tycon rfref.RecdField, + GenType cenv.amap m tyenv (instType inst rfref.RecdField.FormalType)) + | _ -> + let tyenvinner = TypeReprEnv.Empty.ForTycon rfref.Tycon + let ilty = GenTyApp cenv.amap m tyenv rfref.TyconRef.CompiledRepresentation tyargs + mkILFieldSpecInTy(ilty, ComputeFieldName rfref.Tycon rfref.RecdField, GenType cenv.amap m tyenvinner rfref.RecdField.FormalType) let GenExnType amap m tyenv (ecref: TyconRef) = GenTyApp amap m tyenv ecref.CompiledRepresentation [] - + +type ArityInfo = int list + //-------------------------------------------------------------------------- // Closure summaries -//-------------------------------------------------------------------------- +// +// Function, Object, Delegate and State Machine Closures +// ===================================================== +// +// For a normal expression closure, we generate: +// +// class Implementation : FSharpFunc<...> { +// override Invoke(..) { expr } +// } +// +// Local Type Functions +// ==================== +// +// The input expression is: +// let input-val : FORALL. body-type = LAM . body-expr : body-type +// ... +// +// This is called at some point: +// +// input-val +// +// Note 'input-val' is never used without applying it to some type arguments. +// +// Basic examples - first define some functions that extract information from generic parameters, and which are constrained: +// +// type TypeInfo<'T> = TypeInfo of System.Type +// type TypeName = TypeName of string +// +// let typeinfo<'T when 'T :> System.IComparable) = TypeInfo (typeof<'T>) +// let typename<'T when 'T :> System.IComparable) = TypeName (typeof<'T>.Name) +// +// Then here are examples: +// +// LAM <'T>{addWitness}. (typeinfo<'T>, typeinfo<'T[]>, (incr{ : 'T -> 'T)) : TypeInfo<'T> * TypeInfo<'T[]> * ('T -> 'T) +// directTypars = 'T +// cloFreeTyvars = empty +// +// or +// LAM <'T>. (typeinfo<'T>, typeinfo<'U>) : TypeInfo<'T> * TypeInfo<'U> +// directTypars = 'T +// cloFreeTyvars = 'U +// +// or +// LAM <'T>. (typeinfo<'T>, typeinfo<'U>, typename<'V>) : TypeInfo<'T> * TypeInfo<'U> * TypeName +// directTypars = 'T +// cloFreeTyvars = 'U,'V +// +// or, for witnesses: +// +// let inline incr{addWitnessForT} (x: 'T) = x + GenericZero<'T> // has witness argment for '+' +// +// LAM <'T when 'T :... op_Addition ...>{addWitnessForT}. (incr<'T>{addWitnessForT}, incr<'U>{addWitnessForU}, incr<'V>{addWitnessForV}) : ('T -> 'T) * ('U -> 'U) * ('V -> 'V) +// directTypars = 'T +// cloFreeTyvars = 'U,'V +// cloFreeTyvarsWitnesses = witnesses implied by cloFreeTyvars = {addWitnessForU, addWitnessForV} +// directTyparsWitnesses = witnesses implied by directTypars = {addWitnessForT} +// +// Define the free variable sets: +// +// cloFreeTyvars = free-tyvars-of(input-expr) +// +// where IsNamedLocalTypeFuncVal is true. +// +// The directTypars may have constraints that require some witnesses. Making those explicit with "{ ... }" syntax for witnesses: +// input-expr = {LAM {directWitnessInfoArgs}. body-expr : body-type } +// +// let x : FORALL<'T ... constrained ...> ... = clo{directWitnessInfos} +// +// Given this, we generate this shape of code: +// +// type Implementation(cloFreeTyvarsWitnesses) = +// member DirectInvoke(directTyparsWitnesses) : body-type = +// body-expr +// +// local x : obj = new Implementation(cloFreeTyvarsWitnesses) +// .... +// ldloc x +// unbox Implementation +// call Implementation::DirectInvoke(directTyparsWitnesses) +// +// First-class Type Functions +// ========================== +// +// If IsNamedLocalTypeFuncVal is false, we have a "non-local" or "first-class" type function closure +// that implements FSharpTypeFunc, and we generate: +// +// class Implementation : FSharpTypeFunc { +// override Specialize : overall-type { expr } +// } +// -type ArityInfo = int list - [] type IlxClosureInfo = { /// The whole expression for the closure cloExpr: Expr - + /// The name of the generated closure class cloName: string - + /// The counts of curried arguments for the closure cloArityInfo: ArityInfo - /// The formal return type - cloILFormalRetTy: ILType + /// The formal return type + ilCloFormalReturnTy: ILType /// An immutable array of free variable descriptions for the closure - cloILFreeVars: IlxClosureFreeVar[] + ilCloAllFreeVars: IlxClosureFreeVar[] /// The ILX specification for the closure cloSpec: IlxClosureSpec - /// The attributes that get attached to the closure class - cloAttribs: Attribs - /// The generic parameters for the closure, i.e. the type variables it captures - cloILGenericParams: IL.ILGenericParameterDefs + cloILGenericParams: ILGenericParameterDefs - /// The free variables for the closure, i.e. the values it captures + /// The captured variables for the closure cloFreeVars: Val list - /// ILX view of the lambdas for the closures - ilCloLambdas: IlxClosureLambdas - - /// The free type parameters occuring in the type of the closure (and not just its body) - /// This is used for local type functions, whose contract class must use these types - /// type Contract<'fv> = - /// abstract DirectInvoke: ty['fv] - /// type Implementation<'fv, 'fv2> : Contract<'fv> = - /// override DirectInvoke: ty['fv] = expr['fv, 'fv2] - /// - /// At the callsite we generate - /// unbox ty['fv] - /// callvirt clo.DirectInvoke - localTypeFuncILGenericArgs: ILType list + cloFreeTyvars: Typars - /// The free type parameters for the local type function as F# TAST types - localTypeFuncContractFreeTypars: Typar list + cloWitnessInfos: TraitWitnessInfos - localTypeFuncDirectILGenericParams: IL.ILGenericParameterDefs + /// ILX view of the lambdas for the closures + ilCloLambdas: IlxClosureLambdas - localTypeFuncInternalFreeTypars: Typar list } @@ -734,7 +834,7 @@ type IlxClosureInfo = // ValStorage //-------------------------------------------------------------------------- - + /// Describes the storage for a value [] type ValStorage = @@ -742,29 +842,58 @@ type ValStorage = | Null /// Indicates the value is stored in a static field. - | StaticField of ILFieldSpec * ValRef * (*hasLiteralAttr:*)bool * ILType * string * ILType * ILMethodRef * ILMethodRef * OptionalShadowLocal - - /// Indicates the value is "stored" as a property that recomputes it each time it is referenced. Used for simple constants that do not cause initialization triggers - | StaticProperty of ILMethodSpec * OptionalShadowLocal - - /// Indicates the value is "stored" as a IL static method (in a "main" class for a F# + | StaticPropertyWithField of + ilFieldSpec: ILFieldSpec * + valRef: ValRef * + hasLiteralAttr: bool * + ilTyForProperty: ILType * + name: string * + ilTy: ILType * + ilGetterMethRef: ILMethodRef * + ilSetterMethRef: ILMethodRef * + optShadowLocal: OptionalShadowLocal + + /// Indicates the value is represented as a property that recomputes it each time it is referenced. Used for simple constants that do not cause initialization triggers + | StaticProperty of + ilGetterMethSpec: ILMethodSpec * + optShadowLocal: OptionalShadowLocal + + /// Indicates the value is represented as an IL method (in a "main" class for a F# /// compilation unit, or as a member) according to its inferred or specified arity. - | Method of ValReprInfo * ValRef * ILMethodSpec * Range.range * ArgReprInfo list * TType list * ArgReprInfo + | Method of + topValInfo: ValReprInfo * + valRef: ValRef * + ilMethSpec: ILMethodSpec * + ilMethSpecWithWitnesses: ILMethodSpec * + m: range * + classTypars: Typars * + methTypars: Typars * + curriedArgInfos: CurriedArgInfos * + paramInfos: ArgReprInfo list * + witnessInfos: TraitWitnessInfos * + methodArgTys: TType list * + retInfo: ArgReprInfo /// Indicates the value is stored at the given position in the closure environment accessed via "ldarg 0" - | Env of ILType * int * ILFieldSpec * NamedLocalIlxClosureInfo ref option + | Env of + ilCloTyInner: ILType * + ilField: ILFieldSpec * + localCloInfo: (FreeTyvars * NamedLocalIlxClosureInfo ref) option /// Indicates that the value is an argument of a method being generated - | Arg of int + | Arg of index: int /// Indicates that the value is stored in local of the method being generated. NamedLocalIlxClosureInfo is normally empty. /// It is non-empty for 'local type functions', see comments on definition of NamedLocalIlxClosureInfo. - | Local of idx: int * realloc: bool * NamedLocalIlxClosureInfo ref option + | Local of + index: int * + realloc: bool * + localCloInfo: (FreeTyvars * NamedLocalIlxClosureInfo ref) option /// Indicates if there is a shadow local storage for a local, to make sure it gets a good name in debugging and OptionalShadowLocal = | NoShadowLocal - | ShadowLocal of ValStorage + | ShadowLocal of startMark: Mark * storage: ValStorage /// The representation of a NamedLocalClosure is based on a cloinfo. However we can't generate a cloinfo until we've /// decided the representations of other items in the recursive set. Hence we use two phases to decide representations in @@ -773,17 +902,17 @@ and NamedLocalIlxClosureInfo = | NamedLocalIlxClosureInfoGenerator of (IlxGenEnv -> IlxClosureInfo) | NamedLocalIlxClosureInfoGenerated of IlxClosureInfo - override __.ToString() = "" + override _.ToString() = "" /// Indicates the overall representation decisions for all the elements of a namespace of module and ModuleStorage = - { + { Vals: Lazy> - + SubModules: Lazy> } - override __.ToString() = "" + override _.ToString() = "" /// Indicate whether a call to the value can be implemented as /// a branch. At the moment these are only used for generating branch calls back to @@ -799,40 +928,92 @@ and BranchCallItem = // Arg infos for compiled form of F# method or value (TType * ArgReprInfo) list list * // Typars for F# method or value - Tast.Typars * - // Typars for F# method or value + Typars * + // num obj args in IL + int * + // num witness args in IL int * - // num obj args + // num actual args in IL int - override __.ToString() = "" - + override _.ToString() = "" + /// Represents a place we can branch to and Mark = | Mark of ILCodeLabel member x.CodeLabel = (let (Mark lab) = x in lab) -/// The overall environment at a particular point in an expression tree. +/// Represents "what to do next after we generate this expression" +and sequel = + | EndFilter + + /// Exit a 'handler' block. The integer says which local to save result in + | LeaveHandler of + isFinally: bool * + whereToSaveOpt: (int * ILType) option * + afterHandler: Mark * + hasResult: bool + + /// Branch to the given mark + | Br of Mark + + /// Execute the given comparison-then-branch instructions on the result of the expression + /// If the branch isn't taken then drop through. + | CmpThenBrOrContinue of Pops * ILInstr list + + /// Continue and leave the value on the IL computation stack + | Continue + + /// The value then do something else + | DiscardThen of sequel + + /// Return from the method + | Return + + /// End a scope of local variables. Used at end of 'let' and 'let rec' blocks to get tail recursive setting + /// of end-of-scope marks + | EndLocalScope of sequel * Mark + + /// Return from a method whose return type is void + | ReturnVoid + +and Pushes = ILType list +and Pops = int + +/// The overall environment at a particular point in the declaration/expression tree. and IlxGenEnv = { /// The representation decisions for the (non-erased) type parameters that are in scope tyenv: TypeReprEnv - + /// An ILType for some random type in this assembly someTypeInThisAssembly: ILType - + /// Indicates if we are generating code for the last file in a .EXE isFinalFile: bool /// Indicates the default "place" for stuff we're currently generating cloc: CompileLocation + /// The sequel to use for an "early exit" in a state machine, e.g. a return from the middle of an + /// async block + exitSequel: sequel + /// Hiding information down the signature chain, used to compute what's public to the assembly sigToImplRemapInfo: (Remap * SignatureHidingInfo) list + /// The open/open-type declarations in scope + imports: ILDebugImports option + /// All values in scope valsInScope: ValMap> - /// For optimizing direct tail recursion to a loop - mark says where to branch to. Length is 0 or 1. + /// All witnesses in scope and their mapping to storage for the witness value. + witnessesInScope: TraitWitnessInfoHashMap + + /// Suppress witnesses when not generating witness-passing code + suppressWitnesses: bool + + /// For optimizing direct tail recursion to a loop - mark says where to branch to. Length is 0 or 1. /// REVIEW: generalize to arbitrary nested local loops?? innerVals: (ValRef * (BranchCallItem * Mark)) list @@ -848,26 +1029,32 @@ and IlxGenEnv = /// Are we inside of a recursive let binding, while loop, or a for loop? isInLoop: bool + + /// Indicates that the .locals init flag should be set on a method and all its nested methods and lambdas + initLocals: bool } - override __.ToString() = "" + override _.ToString() = "" + +let discard = DiscardThen Continue +let discardAndReturnVoid = DiscardThen ReturnVoid let SetIsInLoop isInLoop eenv = if eenv.isInLoop = isInLoop then eenv else { eenv with isInLoop = isInLoop } -let ReplaceTyenv tyenv (eenv: IlxGenEnv) = {eenv with tyenv = tyenv } +let EnvForTypars tps eenv = {eenv with tyenv = eenv.tyenv.ForTypars tps } -let EnvForTypars tps eenv = {eenv with tyenv = TypeReprEnv.ForTypars tps } +let EnvForTycon tps eenv = {eenv with tyenv = eenv.tyenv.ForTycon tps } let AddTyparsToEnv typars (eenv: IlxGenEnv) = {eenv with tyenv = eenv.tyenv.Add typars} let AddSignatureRemapInfo _msg (rpi, mhi) eenv = { eenv with sigToImplRemapInfo = (mkRepackageRemapping rpi, mhi) :: eenv.sigToImplRemapInfo } - + let OutputStorage (pps: TextWriter) s = match s with - | StaticField _ -> pps.Write "(top)" + | StaticPropertyWithField _ -> pps.Write "(top)" | StaticProperty _ -> pps.Write "(top)" | Method _ -> pps.Write "(top)" | Local _ -> pps.Write "(local)" @@ -904,7 +1091,17 @@ let AddStorageForVal (g: TcGlobals) (v, s) eenv = else eenv -let AddStorageForLocalVals g vals eenv = List.foldBack (fun (v, s) acc -> AddStorageForVal g (v, notlazy s) acc) vals eenv +let AddStorageForLocalVals g vals eenv = + List.foldBack (fun (v, s) acc -> AddStorageForVal g (v, notlazy s) acc) vals eenv + +let AddTemplateReplacement eenv (tcref, ilty, inst) = + { eenv with tyenv = eenv.tyenv.WithTemplateReplacement (tcref, ilty, inst) } + +let AddStorageForLocalWitness eenv (w,s) = + { eenv with witnessesInScope = eenv.witnessesInScope.SetItem (w, s) } + +let AddStorageForLocalWitnesses witnesses eenv = + (eenv, witnesses) ||> List.fold AddStorageForLocalWitness //-------------------------------------------------------------------------- // Lookup eenv @@ -921,6 +1118,14 @@ let StorageForVal g m v eenv = let StorageForValRef g m (v: ValRef) eenv = StorageForVal g m v.Deref eenv +let ComputeGenerateWitnesses (g: TcGlobals) eenv = + g.generateWitnesses && not eenv.witnessesInScope.IsEmpty && not eenv.suppressWitnesses + +let TryStorageForWitness (_g: TcGlobals) eenv (w: TraitWitnessInfo) = + match eenv.witnessesInScope.TryGetValue w with + | true, storage -> Some storage + | _ -> None + let IsValRefIsDllImport g (vref: ValRef) = vref.Attribs |> HasFSharpAttributeOpt g g.attrib_DllImportAttribute @@ -928,13 +1133,14 @@ let IsValRefIsDllImport g (vref: ValRef) = /// as a method. let GetMethodSpecForMemberVal amap g (memberInfo: ValMemberInfo) (vref: ValRef) = let m = vref.Range - let tps, curriedArgInfos, returnTy, retInfo = - assert(vref.ValReprInfo.IsSome) - GetTopValTypeInCompiledForm g (Option.get vref.ValReprInfo) vref.Type m - let tyenvUnderTypars = TypeReprEnv.ForTypars tps + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let tps, witnessInfos, curriedArgInfos, returnTy, retInfo = + assert vref.ValReprInfo.IsSome + GetTopValTypeInCompiledForm g vref.ValReprInfo.Value numEnclosingTypars vref.Type m + let tyenvUnderTypars = TypeReprEnv.Empty.ForTypars tps let flatArgInfos = List.concat curriedArgInfos - let isCtor = (memberInfo.MemberFlags.MemberKind = MemberKind.Constructor) - let cctor = (memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor) + let isCtor = (memberInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) + let cctor = (memberInfo.MemberFlags.MemberKind = SynMemberKind.ClassConstructor) let parentTcref = vref.TopValDeclaringEntity let parentTypars = parentTcref.TyparsNoRange let numParentTypars = parentTypars.Length @@ -948,6 +1154,7 @@ let GetMethodSpecForMemberVal amap g (memberInfo: ValMemberInfo) (vref: ValRef) let ilTy = GenType amap m tyenvUnderTypars (mkAppTy parentTcref (List.map mkTyparTy ctps)) + let nm = vref.CompiledName g.CompilerGlobalState if isCompiledAsInstance || isCtor then // Find the 'this' argument type if any let thisTy, flatArgInfos = @@ -960,7 +1167,10 @@ let GetMethodSpecForMemberVal amap g (memberInfo: ValMemberInfo) (vref: ValRef) let thisTy = if isByrefTy g thisTy then destByrefTy g thisTy else thisTy let thisArgTys = argsOfAppTy g thisTy if numParentTypars <> thisArgTys.Length then - let msg = sprintf "CodeGen check: type checking did not quantify the correct number of type variables for this method, #parentTypars = %d, #mtps = %d, #thisArgTys = %d" numParentTypars mtps.Length thisArgTys.Length + let msg = + sprintf + "CodeGen check: type checking did not quantify the correct number of type variables for this method, #parentTypars = %d, #mtps = %d, #thisArgTys = %d" + numParentTypars mtps.Length thisArgTys.Length warning(InternalError(msg, m)) else List.iter2 @@ -974,16 +1184,30 @@ let GetMethodSpecForMemberVal amap g (memberInfo: ValMemberInfo) (vref: ValRef) let isSlotSig = memberInfo.MemberFlags.IsDispatchSlot || memberInfo.MemberFlags.IsOverrideOrExplicitImpl let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars isSlotSig methodArgTys let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps) - let mspec = mkILInstanceMethSpecInTy (ilTy, vref.CompiledName g.CompilerGlobalState, ilMethodArgTys, ilActualRetTy, ilMethodInst) + let mspec = mkILInstanceMethSpecInTy (ilTy, nm, ilMethodArgTys, ilActualRetTy, ilMethodInst) + let mspecW = + if not g.generateWitnesses || witnessInfos.IsEmpty then + mspec + else + let ilWitnessArgTys = GenTypes amap m tyenvUnderTypars (GenWitnessTys g witnessInfos) + let nmW = ExtraWitnessMethodName nm + mkILInstanceMethSpecInTy (ilTy, nmW, ilWitnessArgTys @ ilMethodArgTys, ilActualRetTy, ilMethodInst) - mspec, ctps, mtps, paramInfos, retInfo, methodArgTys + mspec, mspecW, ctps, mtps, curriedArgInfos, paramInfos, retInfo, witnessInfos, methodArgTys, returnTy else let methodArgTys, paramInfos = List.unzip flatArgInfos let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars false methodArgTys let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps) - let mspec = mkILStaticMethSpecInTy (ilTy, vref.CompiledName g.CompilerGlobalState , ilMethodArgTys, ilActualRetTy, ilMethodInst) + let mspec = mkILStaticMethSpecInTy (ilTy, nm, ilMethodArgTys, ilActualRetTy, ilMethodInst) + let mspecW = + if not g.generateWitnesses || witnessInfos.IsEmpty then + mspec + else + let ilWitnessArgTys = GenTypes amap m tyenvUnderTypars (GenWitnessTys g witnessInfos) + let nmW = ExtraWitnessMethodName nm + mkILStaticMethSpecInTy (ilTy, nmW, ilWitnessArgTys @ ilMethodArgTys, ilActualRetTy, ilMethodInst) - mspec, ctps, mtps, paramInfos, retInfo, methodArgTys + mspec, mspecW, ctps, mtps, curriedArgInfos, paramInfos, retInfo, witnessInfos, methodArgTys, returnTy /// Determine how a top-level value is represented, when representing as a field, by computing an ILFieldSpec let ComputeFieldSpecForVal(optIntraAssemblyInfo: IlxGenIntraAssemblyInfo option, isInteractive, g, ilTyForProperty, vspec: Val, nm, m, cloc, ilTy, ilGetterMethRef) = @@ -1016,27 +1240,34 @@ let ComputeStorageForFSharpValue amap (g:TcGlobals) cloc optIntraAssemblyInfo op let ilGetterMethRef = mkILMethRef (ilTypeRefForProperty, ILCallingConv.Static, "get_"+nm, 0, [], ilTy) let ilSetterMethRef = mkILMethRef (ilTypeRefForProperty, ILCallingConv.Static, "set_"+nm, 0, [ilTy], ILType.Void) let ilFieldSpec = ComputeFieldSpecForVal(optIntraAssemblyInfo, isInteractive, g, ilTyForProperty, vspec, nm, m, cloc, ilTy, ilGetterMethRef) - StaticField (ilFieldSpec, vref, hasLiteralAttr, ilTyForProperty, nm, ilTy, ilGetterMethRef, ilSetterMethRef, optShadowLocal) + StaticPropertyWithField (ilFieldSpec, vref, hasLiteralAttr, ilTyForProperty, nm, ilTy, ilGetterMethRef, ilSetterMethRef, optShadowLocal) /// Compute the representation information for an F#-declared member let ComputeStorageForFSharpMember amap g topValInfo memberInfo (vref: ValRef) m = - let mspec, _, _, paramInfos, retInfo, methodArgTys = GetMethodSpecForMemberVal amap g memberInfo vref - Method (topValInfo, vref, mspec, m, paramInfos, methodArgTys, retInfo) + let mspec, mspecW, ctps, mtps, curriedArgInfos, paramInfos, retInfo, witnessInfos, methodArgTys, _ = GetMethodSpecForMemberVal amap g memberInfo vref + Method (topValInfo, vref, mspec, mspecW, m, ctps, mtps, curriedArgInfos, paramInfos, witnessInfos, methodArgTys, retInfo) /// Compute the representation information for an F#-declared function in a module or an F#-declared extension member. /// Note, there is considerable overlap with ComputeStorageForFSharpMember/GetMethodSpecForMemberVal and these could be /// rationalized. -let ComputeStorageForFSharpFunctionOrFSharpExtensionMember amap (g:TcGlobals) cloc topValInfo (vref: ValRef) m = +let ComputeStorageForFSharpFunctionOrFSharpExtensionMember amap (g: TcGlobals) cloc topValInfo (vref: ValRef) m = let nm = vref.CompiledName g.CompilerGlobalState - let (tps, curriedArgInfos, returnTy, retInfo) = GetTopValTypeInCompiledForm g topValInfo vref.Type m - let tyenvUnderTypars = TypeReprEnv.ForTypars tps - let (methodArgTys, paramInfos) = curriedArgInfos |> List.concat |> List.unzip + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let tps, witnessInfos, curriedArgInfos, returnTy, retInfo = GetTopValTypeInCompiledForm g topValInfo numEnclosingTypars vref.Type m + let tyenvUnderTypars = TypeReprEnv.Empty.ForTypars tps + let methodArgTys, paramInfos = curriedArgInfos |> List.concat |> List.unzip let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars false methodArgTys let ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy let ilLocTy = mkILTyForCompLoc cloc let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy tps) let mspec = mkILStaticMethSpecInTy (ilLocTy, nm, ilMethodArgTys, ilRetTy, ilMethodInst) - Method (topValInfo, vref, mspec, m, paramInfos, methodArgTys, retInfo) + let mspecW = + if not g.generateWitnesses || witnessInfos.IsEmpty then + mspec + else + let ilWitnessArgTys = GenTypes amap m tyenvUnderTypars (GenWitnessTys g witnessInfos) + mkILStaticMethSpecInTy (ilLocTy, ExtraWitnessMethodName nm, (ilWitnessArgTys @ ilMethodArgTys), ilRetTy, ilMethodInst) + Method (topValInfo, vref, mspec, mspecW, m, [], tps, curriedArgInfos, paramInfos, witnessInfos, methodArgTys, retInfo) /// Determine if an F#-declared value, method or function is compiled as a method. let IsFSharpValCompiledAsMethod g (v: Val) = @@ -1063,13 +1294,13 @@ let ComputeStorageForTopVal (amap, g, optIntraAssemblyInfo: IlxGenIntraAssemblyI match vref.ValReprInfo with | None -> error(InternalError("ComputeStorageForTopVal: no arity found for " + showL(valRefL vref), vref.Range)) | Some a -> a - + let m = vref.Range let nm = vref.CompiledName g.CompilerGlobalState if vref.Deref.IsCompiledAsStaticPropertyWithoutField then let nm = "get_"+nm - let tyenvUnderTypars = TypeReprEnv.ForTypars [] + let tyenvUnderTypars = TypeReprEnv.Empty.ForTypars [] let ilRetTy = GenType amap m tyenvUnderTypars vref.Type let ty = mkILTyForCompLoc cloc let mspec = mkILStaticMethSpecInTy (ty, nm, [], ilRetTy, []) @@ -1138,7 +1369,7 @@ let rec AddBindingsForLocalModuleType allocVal cloc eenv (mty: ModuleOrNamespace eenv /// Record how all the top level F#-declared values, functions and members are represented, for a set of referenced assemblies. -let AddExternalCcusToIlxGenEnv amap g eenv ccus = +let AddExternalCcusToIlxGenEnv amap g eenv ccus = List.fold (AddStorageForExternalCcu amap g) eenv ccus /// Record how all the unrealized abstract slots are represented, for a type definition. @@ -1153,10 +1384,39 @@ let AddBindingsForTycon allocVal (cloc: CompileLocation) (tycon: Tycon) eenv = let rec AddBindingsForModuleDefs allocVal (cloc: CompileLocation) eenv mdefs = List.fold (AddBindingsForModuleDef allocVal cloc) eenv mdefs -/// Record how constructs are represented, for a module or namespace fragment definition. +and AddDebugImportsToEnv _cenv eenv (openDecls: OpenDeclaration list) = + let ilImports = + [| + for openDecl in openDecls do + for modul in openDecl.Modules do + if modul.IsNamespace then + ILDebugImport.ImportNamespace (fullDisplayTextOfModRef modul) + // Emit of 'open type' and 'open ' is causing problems + // See https://github.com/dotnet/fsharp/pull/12010#issuecomment-903339109 + // + // It may be nested types/modules in particular + //else + // ILDebugImport.ImportType (mkILNonGenericBoxedTy modul.CompiledRepresentationForNamedType) + //for t in openDecl.Types do + // let m = defaultArg openDecl.Range Range.range0 + // ILDebugImport.ImportType (GenType cenv.amap m TypeReprEnv.Empty t) + |] + |> Array.distinctBy (function + | ILDebugImport.ImportNamespace nsp -> nsp + | ILDebugImport.ImportType t -> t.QualifiedName) + + if ilImports.Length = 0 then + eenv + else + let imports = + { Parent = eenv.imports + Imports = ilImports } + + { eenv with imports = Some imports } + and AddBindingsForModuleDef allocVal cloc eenv x = match x with - | TMDefRec(_isRec, tycons, mbinds, _) -> + | TMDefRec(_isRec, _opens, tycons, mbinds, _) -> // Virtual don't have 'let' bindings and must be added to the environment let eenv = List.foldBack (AddBindingsForTycon allocVal cloc) tycons eenv let eenv = List.foldBack (AddBindingsForModule allocVal cloc) mbinds eenv @@ -1165,6 +1425,8 @@ and AddBindingsForModuleDef allocVal cloc eenv x = allocVal cloc bind.Var eenv | TMDefDo _ -> eenv + | TMDefOpens _-> + eenv | TMAbstract(ModuleOrNamespaceExprWithSig(mtyp, _, _)) -> AddBindingsForLocalModuleType allocVal cloc eenv mtyp | TMDefs mdefs -> @@ -1179,7 +1441,7 @@ and AddBindingsForModule allocVal cloc x eenv = let cloc = if mspec.IsNamespace then cloc else CompLocForFixedModule cloc.QualifiedNameOfFile cloc.TopImplQualifiedName mspec - + AddBindingsForModuleDef allocVal cloc eenv mdef /// Record how constructs are represented, for the values and functions defined in a module or namespace fragment. @@ -1208,7 +1470,7 @@ let AddIncrementalLocalAssemblyFragmentToIlxGenEnv (amap: ImportMap, isIncrement /// Generate IL debugging information. let GenILSourceMarker (g: TcGlobals) (m: range) = - ILSourceMarker.Create(document=g.memoize_file m.FileIndex, + ILDebugPoint.Create(document=g.memoize_file m.FileIndex, line=m.StartLine, /// NOTE: .NET && VS measure first column as column 1 column= m.StartColumn+1, @@ -1226,7 +1488,7 @@ let GenPossibleILSourceMarker cenv m = // Helpers for merging property definitions //-------------------------------------------------------------------------- -let HashRangeSorted (ht: IDictionary<_, (int * _)>) = +let HashRangeSorted (ht: IDictionary<_, int * _>) = [ for KeyValue(_k, v) in ht -> v ] |> List.sortBy fst |> List.map snd let MergeOptions m o1 o2 = @@ -1253,7 +1515,7 @@ let MergePropertyPair m (pd: ILPropertyDef) (pdef: ILPropertyDef) = type PropKey = PropKey of string * ILTypes * ILThisConvention -let AddPropertyDefToHash (m: range) (ht: Dictionary) (pdef: ILPropertyDef) = +let AddPropertyDefToHash (m: range) (ht: Dictionary) (pdef: ILPropertyDef) = let nm = PropKey(pdef.Name, pdef.Args, pdef.CallingConv) match ht.TryGetValue nm with | true, (idx, pd) -> @@ -1264,7 +1526,7 @@ let AddPropertyDefToHash (m: range) (ht: Dictionary(3, HashIdentity.Structural) + let ht = Dictionary<_, _>(3, HashIdentity.Structural) ilPropertyDefs |> List.iter (AddPropertyDefToHash m ht) HashRangeSorted ht @@ -1274,11 +1536,11 @@ let MergePropertyDefs m ilPropertyDefs = /// Information collected imperatively for each type definition type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) = - let gmethods = new ResizeArray(0) - let gfields = new ResizeArray(0) - let gproperties: Dictionary = new Dictionary<_, _>(3, HashIdentity.Structural) - let gevents = new ResizeArray(0) - let gnested = new TypeDefsBuilder() + let gmethods = ResizeArray(0) + let gfields = ResizeArray(0) + let gproperties: Dictionary = Dictionary<_, _>(3, HashIdentity.Structural) + let gevents = ResizeArray(0) + let gnested = TypeDefsBuilder() member b.Close() = tdef.With(methods = mkILMethods (tdef.Methods.AsList @ ResizeArray.toList gmethods), @@ -1299,13 +1561,13 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) = if not discard then gmethods.Add ilMethodDef - member b.NestedTypeDefs = gnested + member _.NestedTypeDefs = gnested - member b.GetCurrentFields() = gfields |> Seq.readonly + member _.GetCurrentFields() = gfields |> Seq.readonly /// Merge Get and Set property nodes, which we generate independently for F# code /// when we come across their corresponding methods. - member b.AddOrMergePropertyDef(pdef, m) = + member _.AddOrMergePropertyDef(pdef, m) = let discard = match tdefDiscards with | Some (_, pdefDiscard) -> pdefDiscard pdef @@ -1313,22 +1575,24 @@ type TypeDefBuilder(tdef: ILTypeDef, tdefDiscards) = if not discard then AddPropertyDefToHash m gproperties pdef - member b.PrependInstructionsToSpecificMethodDef(cond, instrs, tag) = + member _.PrependInstructionsToSpecificMethodDef(cond, instrs, tag, imports) = match ResizeArray.tryFindIndex cond gmethods with | Some idx -> gmethods.[idx] <- prependInstrsToMethod instrs gmethods.[idx] - | None -> gmethods.Add(mkILClassCtor (mkMethodBody (false, [], 1, nonBranchingInstrsToCode instrs, tag))) + | None -> + let body = mkMethodBody (false, [], 1, nonBranchingInstrsToCode instrs, tag, imports) + gmethods.Add(mkILClassCtor body) and TypeDefsBuilder() = - let tdefs: Internal.Utilities.Collections.HashMultiMap = HashMultiMap(0, HashIdentity.Structural) + let tdefs: HashMultiMap = HashMultiMap(0, HashIdentity.Structural) let mutable countDown = System.Int32.MaxValue member b.Close() = //The order we emit type definitions is not deterministic since it is using the reverse of a range from a hash table. We should use an approximation of source order. // Ideally it shouldn't matter which order we use. // However, for some tests FSI generated code appears sensitive to the order, especially for nested types. - - [ for (b, eliminateIfEmpty) in HashRangeSorted tdefs do + + [ for b, eliminateIfEmpty in HashRangeSorted tdefs do let tdef = b.Close() // Skip the type if it is empty if not eliminateIfEmpty @@ -1351,26 +1615,28 @@ and TypeDefsBuilder() = member b.AddTypeDef(tdef: ILTypeDef, eliminateIfEmpty, addAtEnd, tdefDiscards) = let idx = if addAtEnd then (countDown <- countDown - 1; countDown) else tdefs.Count - tdefs.Add (tdef.Name, (idx, (new TypeDefBuilder(tdef, tdefDiscards), eliminateIfEmpty))) + tdefs.Add (tdef.Name, (idx, (TypeDefBuilder(tdef, tdefDiscards), eliminateIfEmpty))) type AnonTypeGenerationTable() = - let dict = Dictionary(HashIdentity.Structural) - member __.Table = dict + // Dictionary is safe here as it will only be used during the codegen stage - will happen on a single thread. + let dict = Dictionary(HashIdentity.Structural) + member _.Table = dict /// Assembly generation buffers type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf = let g = cenv.g // The Abstract IL table of types - let gtdefs= new TypeDefsBuilder() + let gtdefs= TypeDefsBuilder() // The definitions of top level values, as quotations. - let mutable reflectedDefinitions: Dictionary = Dictionary(HashIdentity.Reference) + // Dictionary is safe here as it will only be used during the codegen stage - will happen on a single thread. + let mutable reflectedDefinitions: Dictionary = Dictionary(HashIdentity.Reference) let mutable extraBindingsToGenerate = [] // A memoization table for generating value types for big constant arrays let rawDataValueTypeGenerator = - new MemoizationTable<(CompileLocation * int), ILTypeSpec> - ((fun (cloc, size) -> + MemoizationTable( + (fun (cloc, size) -> let name = CompilerGeneratedName ("T" + string(newUnique()) + "_" + string size + "Bytes") // Type names ending ...$T_37Bytes let vtdef = mkRawDataValueTypeDef g.iltyp_ValueType (name, size, 0us) let vtref = NestedTypeRefForCompLoc cloc vtdef.Name @@ -1381,23 +1647,23 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu keyComparer=HashIdentity.Structural) let generateAnonType genToStringMethod (isStruct, ilTypeRef, nms) = - - let propTys = [ for (i, nm) in Array.indexed nms -> nm, ILType.TypeVar (uint16 i) ] + + let propTys = [ for i, nm in Array.indexed nms -> nm, ILType.TypeVar (uint16 i) ] // Note that this alternative below would give the same names as C#, but the generated // comparison/equality doesn't know about these names. //let flds = [ for (i, nm) in Array.indexed nms -> (nm, "<" + nm + ">" + "i__Field", ILType.TypeVar (uint16 i)) ] let ilCtorRef = mkILMethRef(ilTypeRef, ILCallingConv.Instance, ".ctor", 0, List.map snd propTys, ILType.Void) - let ilMethodRefs = - [| for (propName, propTy) in propTys -> + let ilMethodRefs = + [| for propName, propTy in propTys -> mkILMethRef (ilTypeRef, ILCallingConv.Instance, "get_" + propName, 0, [], propTy) |] let ilTy = mkILNamedTy (if isStruct then ILBoxity.AsValue else ILBoxity.AsObject) ilTypeRef (List.map snd propTys) if ilTypeRef.Scope.IsLocalRef then - let flds = [ for (i, nm) in Array.indexed nms -> (nm, nm + "@", ILType.TypeVar (uint16 i)) ] + let flds = [ for i, nm in Array.indexed nms -> (nm, nm + "@", ILType.TypeVar (uint16 i)) ] let ilGenericParams = [ for nm in nms -> @@ -1415,14 +1681,14 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu // Generate the IL fields let ilFieldDefs = mkILFields - [ for (_, fldName, fldTy) in flds -> + [ for _, fldName, fldTy in flds -> let fdef = mkILInstanceField (fldName, fldTy, None, ILMemberAccess.Private) fdef.With(customAttrs = mkILCustomAttrs [ g.DebuggerBrowsableNeverAttribute ]) ] - + // Generate property definitions for the fields compiled as properties let ilProperties = mkILProperties - [ for (i, (propName, _fldName, fldTy)) in List.indexed flds -> + [ for i, (propName, _fldName, fldTy) in List.indexed flds -> ILPropertyDef(name=propName, attributes=PropertyAttributes.None, setMethod=None, @@ -1432,40 +1698,42 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu init= None, args=[], customAttrs=mkILCustomAttrs [ mkCompilationMappingAttrWithSeqNum g (int SourceConstructFlags.Field) i ]) ] - + let ilMethods = - [ for (propName, fldName, fldTy) in flds -> + [ for propName, fldName, fldTy in flds -> mkLdfldMethodDef ("get_" + propName, ILMemberAccess.Public, false, ilTy, fldName, fldTy) yield! genToStringMethod ilTy ] let ilBaseTy = (if isStruct then g.iltyp_ValueType else g.ilg.typ_Object) - - let ilCtorDef = mkILSimpleStorageCtorWithParamNames(None, (if isStruct then None else Some ilBaseTy.TypeSpec), ilTy, [], flds, ILMemberAccess.Public) + + let ilBaseTySpec = (if isStruct then None else Some ilBaseTy.TypeSpec) + let ilCtorDef = mkILSimpleStorageCtorWithParamNames(ilBaseTySpec, ilTy, [], flds, ILMemberAccess.Public, None, None) // Create a tycon that looks exactly like a record definition, to help drive the generation of equality/comparison code let m = range0 let tps = [ for nm in nms -> - let stp = Typar(mkSynId m ("T"+nm), TyparStaticReq.NoStaticReq, true) - NewTypar (TyparKind.Type, TyparRigidity.WarnIfNotRigid, stp, false, TyparDynamicReq.Yes, [], true, true) ] + let stp = SynTypar(mkSynId m ("T"+nm), TyparStaticReq.None, true) + Construct.NewTypar (TyparKind.Type, TyparRigidity.WarnIfNotRigid, stp, false, TyparDynamicReq.Yes, [], true, true) ] let tycon = - let lmtyp = MaybeLazy.Strict (NewEmptyModuleOrNamespaceType ModuleOrType) + let lmtyp = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType) let cpath = CompPath(ilTypeRef.Scope, []) - NewTycon(Some cpath, ilTypeRef.Name, m, taccessPublic, taccessPublic, TyparKind.Type, LazyWithContext.NotLazy tps, XmlDoc.Empty, false, false, false, lmtyp) + Construct.NewTycon(Some cpath, ilTypeRef.Name, m, taccessPublic, taccessPublic, TyparKind.Type, LazyWithContext.NotLazy tps, XmlDoc.Empty, false, false, false, lmtyp) if isStruct then tycon.SetIsStructRecordOrUnion true tycon.entity_tycon_repr <- - TRecdRepr (MakeRecdFieldsTable - [ for (tp, (propName, _fldName, _fldTy)) in (List.zip tps flds) -> - NewRecdField false None (mkSynId m propName) false (mkTyparTy tp) true false [] [] XmlDoc.Empty taccessPublic false ]) + TFSharpRecdRepr + (Construct.MakeRecdFieldsTable + ((tps, flds) ||> List.map2 (fun tp (propName, _fldName, _fldTy) -> + Construct.NewRecdField false None (mkSynId m propName) false (mkTyparTy tp) true false [] [] XmlDoc.Empty taccessPublic false))) let tcref = mkLocalTyconRef tycon let _, typ = generalizeTyconRef tcref let tcaug = tcref.TypeContents - + tcaug.tcaug_interfaces <- [ (g.mk_IStructuralComparable_ty, true, m) (g.mk_IComparable_ty, true, m) @@ -1487,25 +1755,28 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu let ilTypeDefAttribs = mkILCustomAttrs [ g.CompilerGeneratedAttribute; mkCompilationMappingAttr g (int SourceConstructFlags.RecordType) ] - let ilInterfaceTys = [ for (ity, _, _) in tcaug.tcaug_interfaces -> GenType cenv.amap m (TypeReprEnv.ForTypars tps) ity ] + let ilInterfaceTys = [ for ity, _, _ in tcaug.tcaug_interfaces -> GenType cenv.amap m (TypeReprEnv.Empty.ForTypars tps) ity ] let ilTypeDef = mkILGenericClass (ilTypeRef.Name, ILTypeDefAccess.Public, ilGenericParams, ilBaseTy, ilInterfaceTys, mkILMethods (ilCtorDef :: ilMethods), ilFieldDefs, emptyILTypeDefs, ilProperties, mkILEvents [], ilTypeDefAttribs, ILTypeInit.BeforeField) - + let ilTypeDef = ilTypeDef.WithSealed(true).WithSerializable(true) mgbuf.AddTypeDef(ilTypeRef, ilTypeDef, false, true, None) - + let extraBindings = [ yield! AugmentWithHashCompare.MakeBindingsForCompareAugmentation g tycon yield! AugmentWithHashCompare.MakeBindingsForCompareWithComparerAugmentation g tycon yield! AugmentWithHashCompare.MakeBindingsForEqualityWithComparerAugmentation g tycon yield! AugmentWithHashCompare.MakeBindingsForEqualsAugmentation g tycon ] - let optimizedExtraBindings = extraBindings |> List.map (fun (TBind(a, b, c)) -> TBind(a, cenv.optimizeDuringCodeGen b, c)) + let optimizedExtraBindings = + extraBindings |> List.map (fun (TBind(a, b, c)) -> + // Disable method splitting for bindings related to anonymous records + TBind(a, cenv.optimizeDuringCodeGen true b, c)) extraBindingsToGenerate <- optimizedExtraBindings @ extraBindingsToGenerate @@ -1516,66 +1787,71 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu /// static init fields on script modules. let mutable scriptInitFspecs: (ILFieldSpec * range) list = [] - member __.AddScriptInitFieldSpec (fieldSpec, range) = + member _.AddScriptInitFieldSpec (fieldSpec, range) = scriptInitFspecs <- (fieldSpec, range) :: scriptInitFspecs - + /// This initializes the script in #load and fsc command-line order causing their /// side effects to be executed. - member mgbuf.AddInitializeScriptsInOrderToEntryPoint () = + member mgbuf.AddInitializeScriptsInOrderToEntryPoint (imports) = // Get the entry point and initialized any scripts in order. match explicitEntryPointInfo with | Some tref -> let InitializeCompiledScript(fspec, m) = - mgbuf.AddExplicitInitToSpecificMethodDef((fun (md: ILMethodDef) -> md.IsEntryPoint), tref, fspec, GenPossibleILSourceMarker cenv m, [], []) + let ilDebugPoint = GenPossibleILSourceMarker cenv m + mgbuf.AddExplicitInitToSpecificMethodDef((fun (md: ILMethodDef) -> md.IsEntryPoint), tref, fspec, ilDebugPoint, imports, [], []) scriptInitFspecs |> List.iter InitializeCompiledScript | None -> () - member __.GenerateRawDataValueType (cloc, size) = + member _.GenerateRawDataValueType (cloc, size) = // Byte array literals require a ValueType of size the required number of bytes. // With fsi.exe, S.R.Emit TypeBuilder CreateType has restrictions when a ValueType VT is nested inside a type T, and T has a field of type VT. // To avoid this situation, these ValueTypes are generated under the private implementation rather than in the current cloc. [was bug 1532]. let cloc = CompLocForPrivateImplementationDetails cloc rawDataValueTypeGenerator.Apply((cloc, size)) - member __.GenerateAnonType (genToStringMethod, anonInfo: AnonRecdTypeInfo) = + member _.GenerateAnonType (genToStringMethod, anonInfo: AnonRecdTypeInfo) = let isStruct = evalAnonInfoIsStruct anonInfo let key = anonInfo.Stamp if not (anonTypeTable.Table.ContainsKey key) then let info = generateAnonType genToStringMethod (isStruct, anonInfo.ILTypeRef, anonInfo.SortedNames) anonTypeTable.Table.[key] <- info - member __.LookupAnonType (anonInfo: AnonRecdTypeInfo) = + member this.LookupAnonType (genToStringMethod, anonInfo: AnonRecdTypeInfo) = match anonTypeTable.Table.TryGetValue anonInfo.Stamp with | true, res -> res - | _ -> failwithf "the anonymous record %A has not been generated in the pre-phase of generating this module" anonInfo.ILTypeRef + | _ -> + if anonInfo.ILTypeRef.Scope.IsLocalRef then + failwithf "the anonymous record %A has not been generated in the pre-phase of generating this module" anonInfo.ILTypeRef + this.GenerateAnonType (genToStringMethod, anonInfo) + anonTypeTable.Table.[anonInfo.Stamp] - member __.GrabExtraBindingsToGenerate () = + member _.GrabExtraBindingsToGenerate () = let result = extraBindingsToGenerate extraBindingsToGenerate <- [] result - member __.AddTypeDef (tref: ILTypeRef, tdef, eliminateIfEmpty, addAtEnd, tdefDiscards) = + member _.AddTypeDef (tref: ILTypeRef, tdef, eliminateIfEmpty, addAtEnd, tdefDiscards) = gtdefs.FindNestedTypeDefsBuilder(tref.Enclosing).AddTypeDef(tdef, eliminateIfEmpty, addAtEnd, tdefDiscards) - member __.GetCurrentFields (tref: ILTypeRef) = + member _.GetCurrentFields (tref: ILTypeRef) = gtdefs.FindNestedTypeDefBuilder(tref).GetCurrentFields() - member __.AddReflectedDefinition (vspec: Tast.Val, expr) = + member _.AddReflectedDefinition (vspec: Val, expr) = // preserve order by storing index of item let n = reflectedDefinitions.Count reflectedDefinitions.Add(vspec, (vspec.CompiledName cenv.g.CompilerGlobalState, n, expr)) - member __.ReplaceNameOfReflectedDefinition (vspec, newName) = + member _.ReplaceNameOfReflectedDefinition (vspec, newName) = match reflectedDefinitions.TryGetValue vspec with | true, (name, n, expr) when name <> newName -> reflectedDefinitions.[vspec] <- (newName, n, expr) | _ -> () - member __.AddMethodDef (tref: ILTypeRef, ilMethodDef) = + member _.AddMethodDef (tref: ILTypeRef, ilMethodDef) = gtdefs.FindNestedTypeDefBuilder(tref).AddMethodDef(ilMethodDef) if ilMethodDef.IsEntryPoint then explicitEntryPointInfo <- Some tref - member __.AddExplicitInitToSpecificMethodDef (cond, tref, fspec, sourceOpt, feefee, seqpt) = + member _.AddExplicitInitToSpecificMethodDef (cond, tref, fspec, sourceOpt, imports, feefee, seqpt) = // Authoring a .cctor with effects forces the cctor for the 'initialization' module by doing a dummy store & load of a field // Doing both a store and load keeps FxCop happier because it thinks the field is useful let instrs = @@ -1584,40 +1860,38 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu yield mkNormalStsfld fspec yield mkNormalLdsfld fspec yield AI_pop] - gtdefs.FindNestedTypeDefBuilder(tref).PrependInstructionsToSpecificMethodDef(cond, instrs, sourceOpt) + gtdefs.FindNestedTypeDefBuilder(tref).PrependInstructionsToSpecificMethodDef(cond, instrs, sourceOpt, imports) - member __.AddEventDef (tref, edef) = + member _.AddEventDef (tref, edef) = gtdefs.FindNestedTypeDefBuilder(tref).AddEventDef(edef) - member __.AddFieldDef (tref, ilFieldDef) = + member _.AddFieldDef (tref, ilFieldDef) = gtdefs.FindNestedTypeDefBuilder(tref).AddFieldDef(ilFieldDef) - member __.AddOrMergePropertyDef (tref, pdef, m) = + member _.AddOrMergePropertyDef (tref, pdef, m) = gtdefs.FindNestedTypeDefBuilder(tref).AddOrMergePropertyDef(pdef, m) - member __.Close() = + member _.Close() = // old implementation adds new element to the head of list so result was accumulated in reversed order let orderedReflectedDefinitions = - [for (KeyValue(vspec, (name, n, expr))) in reflectedDefinitions -> n, ((name, vspec), expr)] + [for KeyValue(vspec, (name, n, expr)) in reflectedDefinitions -> n, ((name, vspec), expr)] |> List.sortBy (fst >> (~-)) // invert the result to get 'order-by-descending' behavior (items in list are 0..* so we don't need to worry about int.MinValue) |> List.map snd gtdefs.Close(), orderedReflectedDefinitions - member __.cenv = cenv + member _.cenv = cenv - member __.GetExplicitEntryPointInfo() = explicitEntryPointInfo + member _.GetExplicitEntryPointInfo() = explicitEntryPointInfo /// Record the types of the things on the evaluation stack. /// Used for the few times we have to flush the IL evaluation stack and to compute maxStack. -type Pushes = ILType list -type Pops = int let pop (i: int) : Pops = i let Push tys: Pushes = tys let Push0 = Push [] let FeeFee (cenv: cenv) = (if cenv.opts.testFlagEmitFeeFeeAs100001 then 100001 else 0x00feefee) let FeeFeeInstr (cenv: cenv) doc = - I_seqpoint (ILSourceMarker.Create(document = doc, + I_seqpoint (ILDebugPoint.Create(document = doc, line = FeeFee cenv, column = 0, endLine = FeeFee cenv, @@ -1630,20 +1904,20 @@ type CodeGenBuffer(m: range, alreadyUsedArgs: int) = let g = mgbuf.cenv.g - let locals = new ResizeArray<((string * (Mark * Mark)) list * ILType * bool)>(10) - let codebuf = new ResizeArray(200) - let exnSpecs = new ResizeArray(10) + let locals = ResizeArray<(string * (Mark * Mark)) list * ILType * bool>(10) + let codebuf = ResizeArray(200) + let exnSpecs = ResizeArray(10) // Keep track of the current stack so we can spill stuff when we hit a "try" when some stuff - // is on the stack. + // is on the stack. let mutable stack: ILType list = [] let mutable nstack = 0 let mutable maxStack = 0 - let mutable hasSequencePoints = false + let mutable hasDebugPoints = false let mutable anyDocument = None // we collect an arbitrary document in order to emit the header FeeFee if needed - let codeLabelToPC: Dictionary = new Dictionary<_, _>(10) - let codeLabelToCodeLabel: Dictionary = new Dictionary<_, _>(10) + let codeLabelToPC: Dictionary = Dictionary<_, _>(10) + let codeLabelToCodeLabel: Dictionary = Dictionary<_, _>(10) let rec lab2pc n lbl = if n = System.Int32.MaxValue then error(InternalError("recursive label graph", m)) @@ -1651,21 +1925,21 @@ type CodeGenBuffer(m: range, | true, l -> lab2pc (n + 1) l | _ -> codeLabelToPC.[lbl] - let mutable lastSeqPoint = None + let mutable lastDebugPoint = None - // Add a nop to make way for the first sequence point. + // Add a nop to make way for the first debug point. do if mgbuf.cenv.opts.generateDebugSymbols then let doc = g.memoize_file m.FileIndex let i = FeeFeeInstr mgbuf.cenv doc - codebuf.Add i // for the FeeFee or a better sequence point + codebuf.Add i // for the FeeFee or a better debug point - member cgbuf.DoPushes (pushes: Pushes) = + member _.DoPushes (pushes: Pushes) = for ty in pushes do stack <- ty :: stack nstack <- nstack + 1 maxStack <- Operators.max maxStack nstack - member cgbuf.DoPops (n: Pops) = + member _.DoPops (n: Pops) = for i = 0 to n - 1 do match stack with | [] -> @@ -1676,8 +1950,8 @@ type CodeGenBuffer(m: range, stack <- t nstack <- nstack - 1 - member cgbuf.GetCurrentStack() = stack - member cgbuf.AssertEmptyStack() = + member _.GetCurrentStack() = stack + member _.AssertEmptyStack() = if not (isNil stack) then let msg = sprintf "stack flush didn't work, or extraneous expressions left on stack before stack restore, methodName = %s, stack = %+A, m = %s" @@ -1696,60 +1970,68 @@ type CodeGenBuffer(m: range, cgbuf.DoPushes pushes is |> List.iter codebuf.Add - member cgbuf.GetLastSequencePoint() = - lastSeqPoint - - member private cgbuf.EnsureNopBetweenDebugPoints() = - // Always add a nop between sequence points to help .NET get the stepping right + member _.GetLastDebugPoint() = + lastDebugPoint + + member private _.EnsureNopBetweenDebugPoints() = + // Always add a nop between debug points to help .NET get the stepping right // Don't do this after a FeeFee marker for hidden code if (codebuf.Count > 0 && (match codebuf.[codebuf.Count-1] with | I_seqpoint sm when sm.Line <> FeeFee mgbuf.cenv -> true | _ -> false)) then - + codebuf.Add(AI_nop) - member cgbuf.EmitSeqPoint src = + member cgbuf.EmitDebugPoint src = if mgbuf.cenv.opts.generateDebugSymbols then let attr = GenILSourceMarker g src let i = I_seqpoint attr - hasSequencePoints <- true + hasDebugPoints <- true - // Replace the FeeFee seqpoint at the entry with a better sequence point - if codebuf.Count = 1 then - assert (match codebuf.[0] with I_seqpoint _ -> true | _ -> false) - codebuf.[0] <- i + // Replace a FeeFee seqpoint with a better debug point + let n = codebuf.Count + let isSingleFeeFee = + match codebuf.[n-1] with + | I_seqpoint sm -> (sm.Line = FeeFee mgbuf.cenv) + | _ -> false + if isSingleFeeFee then + codebuf.[n-1] <- i else cgbuf.EnsureNopBetweenDebugPoints() codebuf.Add i - // Save the last sequence point away so we can make a decision graph look consistent (i.e. reassert the sequence point at each target) - lastSeqPoint <- Some src + // Save the last debug point away so we can make a decision graph look consistent (i.e. reassert the debug point at each target) + lastDebugPoint <- Some src anyDocument <- Some attr.Document - + // Emit FeeFee breakpoints for hidden code, see https://blogs.msdn.microsoft.com/jmstall/2005/06/19/line-hidden-and-0xfeefee-sequence-points/ member cgbuf.EmitStartOfHiddenCode() = if mgbuf.cenv.opts.generateDebugSymbols then let doc = g.memoize_file m.FileIndex let i = FeeFeeInstr mgbuf.cenv doc - hasSequencePoints <- true + hasDebugPoints <- true // don't emit just after another FeeFee - match codebuf.[codebuf.Count-1] with - | I_seqpoint sm when sm.Line = FeeFee mgbuf.cenv -> () - | _ -> + let n = codebuf.Count + let isSingleFeeFee = + match codebuf.[n-1] with + | I_seqpoint sm -> (sm.Line = FeeFee mgbuf.cenv) + | _ -> false + + if not isSingleFeeFee then cgbuf.EnsureNopBetweenDebugPoints() codebuf.Add i - member cgbuf.EmitExceptionClause clause = + member _.EmitExceptionClause clause = exnSpecs.Add clause - member cgbuf.GenerateDelayMark(_nm) = - let lab = IL.generateCodeLabel() + member _.GenerateDelayMark(_nm) = + let lab = generateCodeLabel() Mark lab - member cgbuf.SetCodeLabelToCodeLabel(lab1, lab2) = + member _.SetCodeLabelToCodeLabel(lab1, lab2) = #if DEBUG if codeLabelToCodeLabel.ContainsKey lab1 then let msg = sprintf "two values given for label %s, methodName = %s, m = %s" (formatCodeLabel lab1) methodName (stringOfRange m) @@ -1758,7 +2040,7 @@ type CodeGenBuffer(m: range, #endif codeLabelToCodeLabel.[lab1] <- lab2 - member cgbuf.SetCodeLabelToPC(lab, pc) = + member _.SetCodeLabelToPC(lab, pc) = #if DEBUG if codeLabelToPC.ContainsKey lab then let msg = sprintf "two values given for label %s, methodName = %s, m = %s" (formatCodeLabel lab) methodName (stringOfRange m) @@ -1769,10 +2051,20 @@ type CodeGenBuffer(m: range, member cgbuf.SetMark (mark1: Mark, mark2: Mark) = cgbuf.SetCodeLabelToCodeLabel(mark1.CodeLabel, mark2.CodeLabel) - + member cgbuf.SetMarkToHere (Mark lab) = cgbuf.SetCodeLabelToPC(lab, codebuf.Count) + member cgbuf.SetMarkToHereIfNecessary (inplabOpt: Mark option) = + match inplabOpt with + | None -> () + | Some inplab -> cgbuf.SetMarkToHere inplab + + member cgbuf.SetMarkOrEmitBranchIfNecessary (inplabOpt: Mark option, target: Mark) = + match inplabOpt with + | None -> cgbuf.EmitInstr (pop 0, Push0, I_br target.CodeLabel) + | Some inplab -> cgbuf.SetMark(inplab, target) + member cgbuf.SetStack s = stack <- s nstack <- s.Length @@ -1782,11 +2074,13 @@ type CodeGenBuffer(m: range, cgbuf.SetMarkToHere res res - member cgbuf.mgbuf = mgbuf - member cgbuf.MethodName = methodName - member cgbuf.PreallocatedArgCount = alreadyUsedArgs + member _.mgbuf = mgbuf + + member _.MethodName = methodName - member cgbuf.AllocLocal(ranges, ty, isFixed) = + member _.PreallocatedArgCount = alreadyUsedArgs + + member _.AllocLocal(ranges, ty, isFixed) = let j = locals.Count locals.Add((ranges, ty, isFixed)) j @@ -1794,22 +2088,22 @@ type CodeGenBuffer(m: range, member cgbuf.ReallocLocal(cond, ranges, ty, isFixed) = match ResizeArray.tryFindIndexi cond locals with | Some j -> - let (prevRanges, _, isFixed) = locals.[j] + let prevRanges, _, isFixed = locals.[j] locals.[j] <- ((ranges@prevRanges), ty, isFixed) j, true | None -> cgbuf.AllocLocal(ranges, ty, isFixed), false - member cgbuf.Close() = + member _.Close() = let instrs = codebuf.ToArray() - // Fixup the first instruction to be a FeeFee sequence point if needed + // Fixup the first instruction to be a FeeFee debug point if needed let instrs = instrs |> Array.mapi (fun idx i2 -> if idx = 0 && (match i2 with AI_nop -> true | _ -> false) && anyDocument.IsSome then - // This special dummy sequence point says skip the start of the method - hasSequencePoints <- true + // This special dummy debug point says skip the start of the method + hasDebugPoints <- true FeeFeeInstr mgbuf.cenv anyDocument.Value else i2) @@ -1820,20 +2114,18 @@ type CodeGenBuffer(m: range, for kvp in codeLabelToCodeLabel do dict.Add(kvp.Key, lab2pc 0 kvp.Key) dict - (ResizeArray.toList locals, maxStack, codeLabels, instrs, ResizeArray.toList exnSpecs, hasSequencePoints) + (ResizeArray.toList locals, maxStack, codeLabels, instrs, ResizeArray.toList exnSpecs, hasDebugPoints) module CG = let EmitInstr (cgbuf: CodeGenBuffer) pops pushes i = cgbuf.EmitInstr(pops, pushes, i) let EmitInstrs (cgbuf: CodeGenBuffer) pops pushes is = cgbuf.EmitInstrs(pops, pushes, is) - let EmitSeqPoint (cgbuf: CodeGenBuffer) src = cgbuf.EmitSeqPoint src + let EmitDebugPoint (cgbuf: CodeGenBuffer) src = cgbuf.EmitDebugPoint src let GenerateDelayMark (cgbuf: CodeGenBuffer) nm = cgbuf.GenerateDelayMark nm let SetMark (cgbuf: CodeGenBuffer) m1 m2 = cgbuf.SetMark(m1, m2) let SetMarkToHere (cgbuf: CodeGenBuffer) m1 = cgbuf.SetMarkToHere m1 let SetStack (cgbuf: CodeGenBuffer) s = cgbuf.SetStack s let GenerateMark (cgbuf: CodeGenBuffer) s = cgbuf.Mark s - - //-------------------------------------------------------------------------- // Compile constants //-------------------------------------------------------------------------- @@ -1843,13 +2135,13 @@ let GenString cenv cgbuf s = let GenConstArray cenv (cgbuf: CodeGenBuffer) eenv ilElementType (data:'a[]) (write: ByteBuffer -> 'a -> unit) = let g = cenv.g - let buf = ByteBuffer.Create data.Length + use buf = ByteBuffer.Create data.Length data |> Array.iter (write buf) - let bytes = buf.Close() + let bytes = buf.AsMemory().ToArray() let ilArrayType = mkILArr1DTy ilElementType if data.Length = 0 then CG.EmitInstrs cgbuf (pop 0) (Push [ilArrayType]) [ mkLdcInt32 0; I_newarr (ILArrayShape.SingleDimensional, ilElementType); ] - else + else let vtspec = cgbuf.mgbuf.GenerateRawDataValueType(eenv.cloc, bytes.Length) let ilFieldName = CompilerGeneratedName ("field" + string(newUnique())) let fty = ILType.Value vtspec @@ -1864,57 +2156,39 @@ let GenConstArray cenv (cgbuf: CodeGenBuffer) eenv ilElementType (data:'a[]) (wr [ mkLdcInt32 data.Length I_newarr (ILArrayShape.SingleDimensional, ilElementType) AI_dup - I_ldtoken (ILToken.ILField fspec) ] + I_ldtoken (ILToken.ILField fspec) ] CG.EmitInstrs cgbuf (pop 2) Push0 [ mkNormalCall (mkInitializeArrayMethSpec g) ] - -//-------------------------------------------------------------------------- -// We normally generate in the context of a "what to do next" continuation -//-------------------------------------------------------------------------- - -type sequel = - | EndFilter - /// Exit a 'handler' block - /// The integer says which local to save result in - | LeaveHandler of (bool (* finally? *) * int * Mark) - /// Branch to the given mark - | Br of Mark - | CmpThenBrOrContinue of Pops * ILInstr list - /// Continue and leave the value on the IL computation stack - | Continue - /// The value then do something else - | DiscardThen of sequel - /// Return from the method - | Return - /// End a scope of local variables. Used at end of 'let' and 'let rec' blocks to get tail recursive setting - /// of end-of-scope marks - | EndLocalScope of sequel * Mark - /// Return from a method whose return type is void - | ReturnVoid - -let discard = DiscardThen Continue -let discardAndReturnVoid = DiscardThen ReturnVoid - - //------------------------------------------------------------------------- // This is the main code generation routine. It is used to generate // the bodies of methods in a couple of places //------------------------------------------------------------------------- -let CodeGenThen cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, codeGenFunction, m) = - let cgbuf = new CodeGenBuffer(m, mgbuf, methodName, alreadyUsedArgs) +let CodeGenThen cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, selfArgOpt: Val option, codeGenFunction, m) = + let cgbuf = CodeGenBuffer(m, mgbuf, methodName, alreadyUsedArgs) let start = CG.GenerateMark cgbuf "mstart" + let finish = CG.GenerateDelayMark cgbuf "mfinish" let innerVals = entryPointInfo |> List.map (fun (v, kind) -> (v, (kind, start))) - (* Call the given code generator *) + // When debugging, put the "this" parameter in a local that has the right name + match selfArgOpt with + | Some selfArg when selfArg.LogicalName <> "this" && not (selfArg.LogicalName.StartsWith("_")) && not cenv.opts.localOptimizationsEnabled -> + let ilTy = selfArg.Type |> GenType cenv.amap m eenv.tyenv + let idx = cgbuf.AllocLocal([(selfArg.LogicalName, (start, finish)) ], ilTy, false) + cgbuf.EmitStartOfHiddenCode() + CG.EmitInstrs cgbuf (pop 0) Push0 [ mkLdarg0; I_stloc (uint16 idx) ] + | _ -> () + + // Call the given code generator codeGenFunction cgbuf {eenv with withinSEH=false liveLocals=IntMap.empty() innerVals = innerVals} + cgbuf.SetMarkToHere finish - let locals, maxStack, lab2pc, code, exnSpecs, hasSequencePoints = cgbuf.Close() + let locals, maxStack, lab2pc, code, exnSpecs, hasDebugPoints = cgbuf.Close() let localDebugSpecs: ILLocalDebugInfo list = locals @@ -1946,89 +2220,93 @@ let CodeGenThen cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, c code, exnSpecs, localDebugSpecs, - hasSequencePoints) + hasDebugPoints) -let CodeGenMethod cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, codeGenFunction, m) = +let CodeGenMethod cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, selfArgOpt, codeGenFunction, m) = - let locals, maxStack, lab2pc, instrs, exns, localDebugSpecs, hasSequencePoints = - CodeGenThen cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, codeGenFunction, m) + let locals, maxStack, lab2pc, instrs, exns, localDebugSpecs, hasDebugPoints = + CodeGenThen cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, selfArgOpt, codeGenFunction, m) - let code = IL.buildILCode methodName lab2pc instrs exns localDebugSpecs + let code = buildILCode methodName lab2pc instrs exns localDebugSpecs - // Attach a source range to the method. Only do this is it has some sequence points, because .NET 2.0/3.5 - // ILDASM has issues if you emit symbols with a source range but without any sequence points - let sourceRange = if hasSequencePoints then GenPossibleILSourceMarker cenv m else None + // Attach a source range to the method. Only do this if it has some debug points. + let sourceRange = if hasDebugPoints then GenPossibleILSourceMarker cenv m else None + + let ilImports = eenv.imports // The old union erasure phase increased maxstack by 2 since the code pushes some items, we do the same here let maxStack = maxStack + 2 - // Build an Abstract IL method - instrs, mkILMethodBody (true, locals, maxStack, code, sourceRange) + // Build an Abstract IL method + let body = mkILMethodBody (eenv.initLocals, locals, maxStack, code, sourceRange, ilImports) + + instrs, body let StartDelayedLocalScope nm cgbuf = - let startScope = CG.GenerateDelayMark cgbuf ("start_" + nm) - let endScope = CG.GenerateDelayMark cgbuf ("end_" + nm) - startScope, endScope + let startMark = CG.GenerateDelayMark cgbuf ("start_" + nm) + let endMark = CG.GenerateDelayMark cgbuf ("end_" + nm) + startMark, endMark let StartLocalScope nm cgbuf = - let startScope = CG.GenerateMark cgbuf ("start_" + nm) - let endScope = CG.GenerateDelayMark cgbuf ("end_" + nm) - startScope, endScope + let startMark = CG.GenerateMark cgbuf ("start_" + nm) + let endMark = CG.GenerateDelayMark cgbuf ("end_" + nm) + startMark, endMark -let LocalScope nm cgbuf (f: (Mark * Mark) -> 'a) : 'a = - let _, endScope as scopeMarks = StartLocalScope nm cgbuf +let LocalScope nm cgbuf (f: Mark * Mark -> 'a) : 'a = + let _, endMark as scopeMarks = StartLocalScope nm cgbuf let res = f scopeMarks - CG.SetMarkToHere cgbuf endScope + CG.SetMarkToHere cgbuf endMark res -let compileSequenceExpressions = true // try (System.Environment.GetEnvironmentVariable("COMPILED_SEQ") <> null) with _ -> false +let compileSequenceExpressions = true // try (System.Environment.GetEnvironmentVariable("FSHARP_COMPILED_SEQ") <> null) with _ -> false +let compileStateMachineExpressions = true // try (System.Environment.GetEnvironmentVariable("FSHARP_COMPILED_STATEMACHINES") <> null) with _ -> false //------------------------------------------------------------------------- // Sequence Point Logic //------------------------------------------------------------------------- -type EmitSequencePointState = - /// Indicates that we need a sequence point at first opportunity. Used on entrance to a method +type EmitDebugPointState = + /// Indicates that we need a debug point at first opportunity. Used on entrance to a method /// and whenever we drop into an expression within the stepping control structure. | SPAlways - /// Indicates we are not forced to emit a sequence point + /// Indicates we are not forced to emit a debug point | SPSuppress /// Determines if any code at all will be emitted for a binding let BindingEmitsNoCode g (b: Binding) = IsFSharpValCompiledAsMethod g b.Var -/// Determines what sequence point should be emitted when generating the r.h.s of a binding. -/// For example, if the r.h.s is a lambda then no sequence point is emitted. +/// Determines what debug point should be emitted when generating the r.h.s of a binding. +/// For example, if the r.h.s is a lambda then no debug point is emitted. /// /// Returns (isSticky, sequencePointForBind, sequencePointGenerationFlagForRhsOfBind) -let ComputeSequencePointInfoForBinding g (TBind(_, e, spBind) as bind) = +let ComputeDebugPointForBinding g (TBind(_, e, spBind) as bind) = if BindingEmitsNoCode g bind then false, None, SPSuppress else match spBind, stripExpr e with - | NoSequencePointAtInvisibleBinding, _ -> false, None, SPSuppress - | NoSequencePointAtStickyBinding, _ -> true, None, SPSuppress - | NoSequencePointAtDoBinding, _ -> false, None, SPAlways - | NoSequencePointAtLetBinding, _ -> false, None, SPSuppress - // Don't emit sequence points for lambdas. + | DebugPointAtBinding.NoneAtInvisible, _ -> false, None, SPSuppress + | DebugPointAtBinding.NoneAtSticky, _ -> true, None, SPSuppress + | DebugPointAtBinding.NoneAtDo, _ -> false, None, SPAlways + | DebugPointAtBinding.NoneAtLet, _ -> false, None, SPSuppress + // Don't emit debug points for lambdas. // SEQUENCE POINT REVIEW: don't emit for lazy either, nor any builder expressions, nor interface-implementing object expressions | _, (Expr.Lambda _ | Expr.TyLambda _) -> false, None, SPSuppress - | SequencePointAtBinding m, _ -> false, Some m, SPSuppress + | DebugPointAtBinding.Yes m, _ -> false, Some m, SPSuppress -/// Determines if a sequence will be emitted when we generate the code for a binding. +/// Determines if a debug point will be emitted when we generate the code for a binding. /// -/// False for Lambdas, BindingEmitsNoCode, NoSequencePointAtStickyBinding, NoSequencePointAtInvisibleBinding, and NoSequencePointAtLetBinding. -/// True for SequencePointAtBinding, NoSequencePointAtDoBinding. -let BindingEmitsSequencePoint g bind = - match ComputeSequencePointInfoForBinding g bind with +/// False for Lambdas, BindingEmitsNoCode, DebugPointAtBinding.NoneAtSticky, DebugPointAtBinding.NoneAtInvisible, and DebugPointAtBinding.NoneAtLet. +/// True for DebugPointAtBinding.Yes, DebugPointAtBinding.NoneAtDo. +let BindingEmitsDebugPoint g bind = + match ComputeDebugPointForBinding g bind with | _, None, SPSuppress -> false | _ -> true let BindingIsInvisible (TBind(_, _, spBind)) = match spBind with - | NoSequencePointAtInvisibleBinding _ -> true + | DebugPointAtBinding.NoneAtInvisible _ -> true | _ -> false /// Determines if the code generated for a binding is to be marked as hidden, e.g. the 'newobj' for a local function definition. @@ -2037,83 +2315,95 @@ let BindingEmitsHiddenCode (TBind(_, e, spBind)) = | _, (Expr.Lambda _ | Expr.TyLambda _) -> true | _ -> false -/// Determines if generating the code for a compound expression will emit a sequence point as the first instruction -/// through the processing of the constituent parts. Used to prevent the generation of sequence points for +/// Determines if generating the code for a compound expression will emit a debug point as the first instruction +/// through the processing of the constituent parts. Used to prevent the generation of debug points for /// compound expressions. -let rec FirstEmittedCodeWillBeSequencePoint g sp expr = +let rec FirstEmittedCodeWillBeDebugPoint g sp expr = match sp with | SPAlways -> match stripExpr expr with | Expr.Let (bind, body, _, _) -> - BindingEmitsSequencePoint g bind || - FirstEmittedCodeWillBeSequencePoint g sp bind.Expr || - (BindingEmitsNoCode g bind && FirstEmittedCodeWillBeSequencePoint g sp body) + BindingEmitsDebugPoint g bind || + FirstEmittedCodeWillBeDebugPoint g sp bind.Expr || + (BindingEmitsNoCode g bind && FirstEmittedCodeWillBeDebugPoint g sp body) | Expr.LetRec (binds, body, _, _) -> - binds |> List.exists (BindingEmitsSequencePoint g) || - (binds |> List.forall (BindingEmitsNoCode g) && FirstEmittedCodeWillBeSequencePoint g sp body) - | Expr.Sequential (_, _, NormalSeq, spSeq, _) -> + binds |> List.exists (BindingEmitsDebugPoint g) || + (binds |> List.forall (BindingEmitsNoCode g) && FirstEmittedCodeWillBeDebugPoint g sp body) + | Expr.Sequential (stmt1, expr2, NormalSeq, spSeq, _) -> match spSeq with - | SequencePointsAtSeq -> true - | SuppressSequencePointOnExprOfSequential -> true - | SuppressSequencePointOnStmtOfSequential -> false - | Expr.Match (SequencePointAtBinding _, _, _, _, _, _) -> true - | Expr.Op ((TOp.TryCatch (SequencePointAtTry _, _) - | TOp.TryFinally (SequencePointAtTry _, _) - | TOp.For (SequencePointAtForLoop _, _) - | TOp.While (SequencePointAtWhileLoop _, _)), _, _, _) -> true + | DebugPointAtSequential.SuppressNeither -> FirstEmittedCodeWillBeDebugPoint g sp stmt1 + | DebugPointAtSequential.SuppressExpr -> FirstEmittedCodeWillBeDebugPoint g sp stmt1 + | DebugPointAtSequential.SuppressStmt -> FirstEmittedCodeWillBeDebugPoint g sp expr2 + | DebugPointAtSequential.SuppressBoth -> false + | Expr.Sequential (expr1, stmt2, ThenDoSeq, spSeq, _) -> + match spSeq with + | DebugPointAtSequential.SuppressNeither -> FirstEmittedCodeWillBeDebugPoint g sp expr1 + | DebugPointAtSequential.SuppressExpr -> FirstEmittedCodeWillBeDebugPoint g sp stmt2 + | DebugPointAtSequential.SuppressStmt -> FirstEmittedCodeWillBeDebugPoint g sp expr1 + | DebugPointAtSequential.SuppressBoth -> false + | Expr.Match (DebugPointAtBinding.Yes _, _, _, _, _, _) -> true + | Expr.Match (_, _, TDSwitch(DebugPointAtSwitch.Yes _, _, _, _, _), _, _, _) -> true + | Expr.Op ((TOp.TryWith (DebugPointAtTry.Yes _, _) + | TOp.TryFinally (DebugPointAtTry.Yes _, _) + | TOp.For (DebugPointAtFor.Yes _, _) + | TOp.While (DebugPointAtWhile.Yes _, _)), _, _, _) -> true | _ -> false | SPSuppress -> - false + false -/// Suppress sequence points for some compound expressions - though not all - even if "SPAlways" is set. +/// Suppress debug points for some compound expressions - though not all - even if "SPAlways" is set. /// -/// Note this is only used when FirstEmittedCodeWillBeSequencePoint is false. -let EmitSequencePointForWholeExpr g sp expr = - assert (not (FirstEmittedCodeWillBeSequencePoint g sp expr)) +/// Note this is only used when FirstEmittedCodeWillBeDebugPoint is false. +let EmitDebugPointForWholeExpr g sp expr = + assert (not (FirstEmittedCodeWillBeDebugPoint g sp expr)) match sp with | SPAlways -> match stripExpr expr with - // In some cases, we emit sequence points for the 'whole' of a 'let' expression. + // In some cases, we emit debug points for the 'whole' of a 'let' expression. // Specifically, when - // + SPAlways (i.e. a sequence point is required as soon as meaningful) - // + binding is NoSequencePointAtStickyBinding, or NoSequencePointAtLetBinding. - // + not FirstEmittedCodeWillBeSequencePoint + // + SPAlways (i.e. a debug point is required as soon as meaningful) + // + binding is DebugPointAtBinding.NoneAtSticky, or DebugPointAtBinding.NoneAtLet. + // + not FirstEmittedCodeWillBeDebugPoint // For example if we start with // let someCode () = f x // and by inlining 'f' the expression becomes // let someCode () = (let sticky = x in y) - // then we place the sequence point for the whole TAST expression 'let sticky = x in y', i.e. textual range 'f x' in the source code, but + // then we place the debug point for the whole TAST expression 'let sticky = x in y', i.e. textual range 'f x' in the source code, but // _before_ the evaluation of 'x'. This will only happen for sticky 'let' introduced by inlining and other code generation // steps. We do _not_ do this for 'invisible' let which can be skipped. | Expr.Let (bind, _, _, _) when BindingIsInvisible bind -> false | Expr.LetRec (binds, _, _, _) when binds |> List.forall BindingIsInvisible -> false - // If the binding is a lambda then we don't emit a sequence point. + // If the binding is a lambda then we don't emit a debug point. | Expr.Let (bind, _, _, _) when BindingEmitsHiddenCode bind -> false | Expr.LetRec (binds, _, _, _) when binds |> List.forall BindingEmitsHiddenCode -> false - // If the binding is represented by a top-level generated constant value then we don't emit a sequence point. + // If the binding is represented by a top-level generated constant value then we don't emit a debug point. | Expr.Let (bind, _, _, _) when BindingEmitsNoCode g bind -> false | Expr.LetRec (binds, _, _, _) when binds |> List.forall (BindingEmitsNoCode g) -> false - // Suppress sequence points for the whole 'a;b' and do it at 'a' instead. + // Suppress debug points for the whole 'a;b' and do it at 'a' instead. | Expr.Sequential _ -> false - // Suppress sequence points at labels and gotos, it makes no sense to emit sequence points at these. We emit FeeFee instead + // Suppress debug points at labels and gotos, it makes no sense to emit debug points at these. We emit FeeFee instead | Expr.Op (TOp.Label _, _, _, _) -> false | Expr.Op (TOp.Goto _, _, _, _) -> false - // We always suppress at the whole 'match'/'try'/... expression because we do it at the individual parts. + // We suppress at 'match' with DebugPointAtBinding.NoneAtInvisible because + // it is the result of a typical 'match' compilation. For example, + // match expr with + // becomes + // let tmp = expr // generates a debug point, BEFORE tmp is evaluated + // match tmp with // a match marked with DebugPointAtBinding.NoneAtInvisible + // // decision tree accessing 'tmp' // - // These cases need documenting. For example, a typical 'match' gets compiled to - // let tmp = expr // generates a sequence point, BEFORE tmp is evaluated - // match tmp with // a match marked with NoSequencePointAtInvisibleLetBinding - // So since the 'let tmp = expr' has a sequence point, then no sequence point is needed for the 'match'. But the processing - // of the 'let' requests SPAlways for the body. - | Expr.Match _ -> false - | Expr.Op (TOp.TryCatch _, _, _, _) -> false + // So since the 'let tmp = expr' has a debug point, then no debug point is needed for the 'match'. + // + // Code 'a && b' and 'a || b' gets compiled to match with DebugPointAtBinding.NoneAtSticky + | Expr.Match (DebugPointAtBinding.NoneAtInvisible, _, _, _, _, _) -> false + | Expr.Op (TOp.TryWith _, _, _, _) -> false | Expr.Op (TOp.TryFinally _, _, _, _) -> false | Expr.Op (TOp.For _, _, _, _) -> false | Expr.Op (TOp.While _, _, _, _) -> false @@ -2127,8 +2417,8 @@ let EmitSequencePointForWholeExpr g sp expr = /// let f () = a /// body let EmitHiddenCodeMarkerForWholeExpr g sp expr = - assert (not (FirstEmittedCodeWillBeSequencePoint g sp expr)) - assert (not (EmitSequencePointForWholeExpr g sp expr)) + assert (not (FirstEmittedCodeWillBeDebugPoint g sp expr)) + assert (not (EmitDebugPointForWholeExpr g sp expr)) match sp with | SPAlways -> match stripExpr expr with @@ -2139,29 +2429,29 @@ let EmitHiddenCodeMarkerForWholeExpr g sp expr = false /// Some expressions must emit some preparation code, then emit the actual code. -let rec RangeOfSequencePointForWholeExpr g expr = +let rec RangeOfDebugPointForWholeExpr g expr = match stripExpr expr with | Expr.Let (bind, body, _, _) -> - match ComputeSequencePointInfoForBinding g bind with + match ComputeDebugPointForBinding g bind with // For sticky bindings, prefer the range of the overall expression. | true, _, _ -> expr.Range - | _, None, SPSuppress -> RangeOfSequencePointForWholeExpr g body + | _, None, SPSuppress -> RangeOfDebugPointForWholeExpr g body | _, Some m, _ -> m - | _, None, SPAlways -> RangeOfSequencePointForWholeExpr g bind.Expr - | Expr.LetRec (_, body, _, _) -> RangeOfSequencePointForWholeExpr g body - | Expr.Sequential (expr1, _, NormalSeq, _, _) -> RangeOfSequencePointForWholeExpr g expr1 + | _, None, SPAlways -> RangeOfDebugPointForWholeExpr g bind.Expr + | Expr.LetRec (_, body, _, _) -> RangeOfDebugPointForWholeExpr g body + | Expr.Sequential (expr1, _, NormalSeq, _, _) -> RangeOfDebugPointForWholeExpr g expr1 | _ -> expr.Range -/// Used to avoid emitting multiple sequence points in decision tree generation -let DoesGenExprStartWithSequencePoint g sp expr = - FirstEmittedCodeWillBeSequencePoint g sp expr || - EmitSequencePointForWholeExpr g sp expr +/// Used to avoid emitting multiple debug points in decision tree generation +let DoesGenExprStartWithDebugPoint g sp expr = + FirstEmittedCodeWillBeDebugPoint g sp expr || + EmitDebugPointForWholeExpr g sp expr -let ProcessSequencePointForExpr (cenv: cenv) (cgbuf: CodeGenBuffer) sp expr = +let ProcessDebugPointForExpr (cenv: cenv) (cgbuf: CodeGenBuffer) sp expr = let g = cenv.g - if not (FirstEmittedCodeWillBeSequencePoint g sp expr) then - if EmitSequencePointForWholeExpr g sp expr then - CG.EmitSeqPoint cgbuf (RangeOfSequencePointForWholeExpr g expr) + if not (FirstEmittedCodeWillBeDebugPoint g sp expr) then + if EmitDebugPointForWholeExpr g sp expr then + CG.EmitDebugPoint cgbuf (RangeOfDebugPointForWholeExpr g expr) elif EmitHiddenCodeMarkerForWholeExpr g sp expr then cgbuf.EmitStartOfHiddenCode() @@ -2197,168 +2487,229 @@ and GenExprWithStackGuard cenv cgbuf eenv sp expr sequel = | :? System.InsufficientExecutionStackException -> error(InternalError(sprintf "Expression is too large and/or complex to emit. Method name: '%s'. Recursive depth: %i." cgbuf.MethodName cenv.exprRecursionDepth, expr.Range)) +/// Process the debug point and check for alternative ways to generate this expression. +/// Returns 'true' if the expression was processed by alternative means. +and GenExprPreSteps (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = + let g = cenv.g + + ProcessDebugPointForExpr cenv cgbuf sp expr + + match (if compileSequenceExpressions then LowerComputedListOrArrayExpr cenv.tcVal g cenv.amap expr else None) with + | Some altExpr -> + GenExpr cenv cgbuf eenv sp altExpr sequel + true + | None -> + + match (if compileSequenceExpressions then ConvertSequenceExprToObject g cenv.amap expr else None) with + | Some info -> + GenSequenceExpr cenv cgbuf eenv info sequel + true + | None -> + + match LowerStateMachineExpr cenv.g expr with + | LoweredStateMachineResult.Lowered res -> + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.ResumableStateMachines expr.Range + GenStructStateMachine cenv cgbuf eenv res sequel + true + | LoweredStateMachineResult.UseAlternative (msg, altExpr) -> + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.ResumableStateMachines expr.Range + warning(Error(FSComp.SR.reprStateMachineNotCompilable(msg), expr.Range)) + GenExpr cenv cgbuf eenv sp altExpr sequel + true + | LoweredStateMachineResult.NoAlternative msg -> + checkLanguageFeatureError cenv.g.langVersion LanguageFeature.ResumableStateMachines expr.Range + errorR(Error(FSComp.SR.reprStateMachineNotCompilableNoAlternative(msg), expr.Range)) + GenDefaultValue cenv cgbuf eenv (tyOfExpr cenv.g expr, expr.Range) + true + | LoweredStateMachineResult.NotAStateMachine -> + match expr with + | IfUseResumableStateMachinesExpr g (_thenExpr, elseExpr) -> + GenExpr cenv cgbuf eenv sp elseExpr sequel + true + | _ -> + false + and GenExprAux (cenv: cenv) (cgbuf: CodeGenBuffer) eenv sp expr sequel = - let g = cenv.g - let expr = stripExpr expr + let g = cenv.g + let expr = stripExpr expr - ProcessSequencePointForExpr cenv cgbuf sp expr + // Process the debug point and see if there's a replacement technique to process this expression + if GenExprPreSteps cenv cgbuf eenv sp expr sequel then () else - // A sequence expression will always match Expr.App. - match (if compileSequenceExpressions then LowerCallsAndSeqs.LowerSeqExpr g cenv.amap expr else None) with - | Some info -> - GenSequenceExpr cenv cgbuf eenv info sequel - | None -> + match expr with + // Most generation of linear expressions is implemented routinely using tailcalls and the correct sequels. + // This is because the element of expansion happens to be the final thing generated in most cases. However + // for large lists we have to process the linearity separately + | Expr.Sequential _ + | Expr.Let _ + | LinearOpExpr _ + | Expr.Match _ -> + GenLinearExpr cenv cgbuf eenv sp expr sequel false id |> ignore + + | Expr.Const (c, m, ty) -> + GenConstant cenv cgbuf eenv (c, m, ty) sequel + + | Expr.LetRec (binds, body, m, _) -> + GenLetRec cenv cgbuf eenv (binds, body, m) sequel + + | Expr.Lambda _ | Expr.TyLambda _ -> + GenLambda cenv cgbuf eenv false [] expr sequel + + | Expr.App (Expr.Val (vref, _, m) as v, _, tyargs, [], _) when + List.forall (isMeasureTy g) tyargs && + ( + // inline only values that are stored in local variables + match StorageForValRef g m vref eenv with + | ValStorage.Local _ -> true + | _ -> false + ) -> + // application of local type functions with type parameters = measure types and body = local value - inline the body + GenExpr cenv cgbuf eenv sp v sequel + + | Expr.App (f, fty, tyargs, curriedArgs, m) -> + GenApp cenv cgbuf eenv (f, fty, tyargs, curriedArgs, m) sequel + + | Expr.Val (v, _, m) -> + GenGetVal cenv cgbuf eenv (v, m) sequel + + | Expr.Op (op, tyargs, args, m) -> + match op, args, tyargs with + | TOp.ExnConstr c, _, _ -> + GenAllocExn cenv cgbuf eenv (c, args, m) sequel + | TOp.UnionCase c, _, _ -> + GenAllocUnionCase cenv cgbuf eenv (c, tyargs, args, m) sequel + | TOp.Recd (isCtor, tycon), _, _ -> + GenAllocRecd cenv cgbuf eenv isCtor (tycon, tyargs, args, m) sequel + | TOp.AnonRecd anonInfo, _, _ -> + GenAllocAnonRecd cenv cgbuf eenv (anonInfo, tyargs, args, m) sequel + | TOp.AnonRecdGet (anonInfo, n), [e], _ -> + GenGetAnonRecdField cenv cgbuf eenv (anonInfo, e, tyargs, n, m) sequel + | TOp.TupleFieldGet (tupInfo, n), [e], _ -> + GenGetTupleField cenv cgbuf eenv (tupInfo, e, tyargs, n, m) sequel + | TOp.ExnFieldGet (ecref, n), [e], _ -> + GenGetExnField cenv cgbuf eenv (e, ecref, n, m) sequel + | TOp.UnionCaseFieldGet (ucref, n), [e], _ -> + GenGetUnionCaseField cenv cgbuf eenv (e, ucref, tyargs, n, m) sequel + | TOp.UnionCaseFieldGetAddr (ucref, n, _readonly), [e], _ -> + GenGetUnionCaseFieldAddr cenv cgbuf eenv (e, ucref, tyargs, n, m) sequel + | TOp.UnionCaseTagGet ucref, [e], _ -> + GenGetUnionCaseTag cenv cgbuf eenv (e, ucref, tyargs, m) sequel + | TOp.UnionCaseProof ucref, [e], _ -> + GenUnionCaseProof cenv cgbuf eenv (e, ucref, tyargs, m) sequel + | TOp.ExnFieldSet (ecref, n), [e;e2], _ -> + GenSetExnField cenv cgbuf eenv (e, ecref, n, e2, m) sequel + | TOp.UnionCaseFieldSet (ucref, n), [e;e2], _ -> + GenSetUnionCaseField cenv cgbuf eenv (e, ucref, tyargs, n, e2, m) sequel + | TOp.ValFieldGet f, [e], _ -> + GenGetRecdField cenv cgbuf eenv (e, f, tyargs, m) sequel + | TOp.ValFieldGet f, [], _ -> + GenGetStaticField cenv cgbuf eenv (f, tyargs, m) sequel + | TOp.ValFieldGetAddr (f, _readonly), [e], _ -> + GenGetRecdFieldAddr cenv cgbuf eenv (e, f, tyargs, m) sequel + | TOp.ValFieldGetAddr (f, _readonly), [], _ -> + GenGetStaticFieldAddr cenv cgbuf eenv (f, tyargs, m) sequel + | TOp.ValFieldSet f, [e1;e2], _ -> + GenSetRecdField cenv cgbuf eenv (e1, f, tyargs, e2, m) sequel + | TOp.ValFieldSet f, [e2], _ -> + GenSetStaticField cenv cgbuf eenv (f, tyargs, e2, m) sequel + | TOp.Tuple tupInfo, _, _ -> + GenAllocTuple cenv cgbuf eenv (tupInfo, args, tyargs, m) sequel + | TOp.ILAsm (instrs, retTypes), _, _ -> + GenAsmCode cenv cgbuf eenv (instrs, tyargs, args, retTypes, m) sequel + | TOp.While (sp, _), [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _)], [] -> + GenWhileLoop cenv cgbuf eenv (sp, e1, e2, m) sequel + | TOp.For (spStart, dir), [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [v], e3, _, _)], [] -> + GenForLoop cenv cgbuf eenv (spStart, v, e1, dir, e2, e3, m) sequel + | TOp.TryFinally (spTry, spFinally), [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], [resty] -> + GenTryFinally cenv cgbuf eenv (e1, e2, m, resty, spTry, spFinally) sequel + | TOp.TryWith (spTry, spWith), [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _);Expr.Lambda (_, _, _, [vh], eh, _, _)], [resty] -> + GenTryWith cenv cgbuf eenv (e1, vf, ef, vh, eh, m, resty, spTry, spWith) sequel + | TOp.ILCall (isVirtual, _, isStruct, isCtor, valUseFlag, _, noTailCall, ilMethRef, enclTypeInst, methInst, returnTypes), args, [] -> + GenILCall cenv cgbuf eenv (isVirtual, isStruct, isCtor, valUseFlag, noTailCall, ilMethRef, enclTypeInst, methInst, args, returnTypes, m) sequel + | TOp.RefAddrGet _readonly, [e], [ty] -> GenGetAddrOfRefCellField cenv cgbuf eenv (e, ty, m) sequel + | TOp.Coerce, [e], [tgty;srcty] -> GenCoerce cenv cgbuf eenv (e, tgty, m, srcty) sequel + | TOp.Reraise, [], [rtnty] -> GenReraise cenv cgbuf eenv (rtnty, m) sequel + | TOp.TraitCall traitInfo, args, [] -> GenTraitCall cenv cgbuf eenv (traitInfo, args, m) expr sequel + | TOp.LValueOp (LSet, v), [e], [] -> GenSetVal cenv cgbuf eenv (v, e, m) sequel + | TOp.LValueOp (LByrefGet, v), [], [] -> GenGetByref cenv cgbuf eenv (v, m) sequel + | TOp.LValueOp (LByrefSet, v), [e], [] -> GenSetByref cenv cgbuf eenv (v, e, m) sequel + | TOp.LValueOp (LAddrOf _, v), [], [] -> GenGetValAddr cenv cgbuf eenv (v, m) sequel + | TOp.Array, elems, [elemTy] -> GenNewArray cenv cgbuf eenv (elems, elemTy, m) sequel + | TOp.Bytes bytes, [], [] -> + if cenv.opts.emitConstantArraysUsingStaticDataBlobs then + GenConstArray cenv cgbuf eenv g.ilg.typ_Byte bytes (fun buf b -> buf.EmitByte b) + GenSequel cenv eenv.cloc cgbuf sequel + else + GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkByte g m) bytes), g.byte_ty, m) sequel + | TOp.UInt16s arr, [], [] -> + if cenv.opts.emitConstantArraysUsingStaticDataBlobs then + GenConstArray cenv cgbuf eenv g.ilg.typ_UInt16 arr (fun buf b -> buf.EmitUInt16 b) + GenSequel cenv eenv.cloc cgbuf sequel + else + GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkUInt16 g m) arr), g.uint16_ty, m) sequel + | TOp.Goto label, _, _ -> + if cgbuf.mgbuf.cenv.opts.generateDebugSymbols then + cgbuf.EmitStartOfHiddenCode() + CG.EmitInstr cgbuf (pop 0) Push0 AI_nop + CG.EmitInstr cgbuf (pop 0) Push0 (I_br label) + // NOTE: discard sequel + | TOp.Return, [e], _ -> + GenExpr cenv cgbuf eenv SPSuppress e eenv.exitSequel + // NOTE: discard sequel + | TOp.Return, [], _ -> + GenSequel cenv eenv.cloc cgbuf ReturnVoid + // NOTE: discard sequel + | TOp.Label label, _, _ -> + cgbuf.SetMarkToHere (Mark label) + GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel + | _ -> error(InternalError("Unexpected operator node expression", expr.Range)) + + | Expr.StaticOptimization (constraints, e2, e3, m) -> + GenStaticOptimization cenv cgbuf eenv (constraints, e2, e3, m) sequel + + | Expr.Obj (_, ty, _, _, [meth], [], m) when isDelegateTy g ty -> + GenDelegateExpr cenv cgbuf eenv expr (meth, m) sequel + + | Expr.Obj (_, ty, basev, basecall, overrides, interfaceImpls, m) -> + GenObjectExpr cenv cgbuf eenv expr (ty, basev, basecall, overrides, interfaceImpls, m) sequel + + | Expr.Quote (ast, conv, _, m, ty) -> + GenQuotation cenv cgbuf eenv (ast, conv, m, ty) sequel + + | Expr.WitnessArg (traitInfo, m) -> + GenWitnessArgFromTraitInfo cenv cgbuf eenv m traitInfo + GenSequel cenv eenv.cloc cgbuf sequel - match expr with - // Most generation of linear expressions is implemented routinely using tailcalls and the correct sequels. - // This is because the element of expansion happens to be the final thing generated in most cases. However - // for large lists we have to process the linearity separately - | Expr.Sequential _ - | Expr.Let _ - | LinearOpExpr _ - | Expr.Match _ -> - GenLinearExpr cenv cgbuf eenv sp expr sequel (* canProcessSequencePoint *) false id |> ignore - - | Expr.Const (c, m, ty) -> - GenConstant cenv cgbuf eenv (c, m, ty) sequel - | Expr.LetRec (binds, body, m, _) -> - GenLetRec cenv cgbuf eenv (binds, body, m) sequel - | Expr.Lambda _ | Expr.TyLambda _ -> - GenLambda cenv cgbuf eenv false None expr sequel - | Expr.App (Expr.Val (vref, _, m) as v, _, tyargs, [], _) when - List.forall (isMeasureTy g) tyargs && - ( - // inline only values that are stored in local variables - match StorageForValRef g m vref eenv with - | ValStorage.Local _ -> true - | _ -> false - ) -> - // application of local type functions with type parameters = measure types and body = local value - inline the body - GenExpr cenv cgbuf eenv sp v sequel - | Expr.App (f,fty, tyargs, args, m) -> - GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel - | Expr.Val (v, _, m) -> - GenGetVal cenv cgbuf eenv (v, m) sequel - - | Expr.Op (op, tyargs, args, m) -> - match op, args, tyargs with - | TOp.ExnConstr c, _, _ -> - GenAllocExn cenv cgbuf eenv (c, args, m) sequel - | TOp.UnionCase c, _, _ -> - GenAllocUnionCase cenv cgbuf eenv (c, tyargs, args, m) sequel - | TOp.Recd (isCtor, tycon), _, _ -> - GenAllocRecd cenv cgbuf eenv isCtor (tycon, tyargs, args, m) sequel - | TOp.AnonRecd anonInfo, _, _ -> - GenAllocAnonRecd cenv cgbuf eenv (anonInfo, tyargs, args, m) sequel - | TOp.AnonRecdGet (anonInfo, n), [e], _ -> - GenGetAnonRecdField cenv cgbuf eenv (anonInfo, e, tyargs, n, m) sequel - | TOp.TupleFieldGet (tupInfo, n), [e], _ -> - GenGetTupleField cenv cgbuf eenv (tupInfo, e, tyargs, n, m) sequel - | TOp.ExnFieldGet (ecref, n), [e], _ -> - GenGetExnField cenv cgbuf eenv (e, ecref, n, m) sequel - | TOp.UnionCaseFieldGet (ucref, n), [e], _ -> - GenGetUnionCaseField cenv cgbuf eenv (e, ucref, tyargs, n, m) sequel - | TOp.UnionCaseFieldGetAddr (ucref, n, _readonly), [e], _ -> - GenGetUnionCaseFieldAddr cenv cgbuf eenv (e, ucref, tyargs, n, m) sequel - | TOp.UnionCaseTagGet ucref, [e], _ -> - GenGetUnionCaseTag cenv cgbuf eenv (e, ucref, tyargs, m) sequel - | TOp.UnionCaseProof ucref, [e], _ -> - GenUnionCaseProof cenv cgbuf eenv (e, ucref, tyargs, m) sequel - | TOp.ExnFieldSet (ecref, n), [e;e2], _ -> - GenSetExnField cenv cgbuf eenv (e, ecref, n, e2, m) sequel - | TOp.UnionCaseFieldSet (ucref, n), [e;e2], _ -> - GenSetUnionCaseField cenv cgbuf eenv (e, ucref, tyargs, n, e2, m) sequel - | TOp.ValFieldGet f, [e], _ -> - GenGetRecdField cenv cgbuf eenv (e, f, tyargs, m) sequel - | TOp.ValFieldGet f, [], _ -> - GenGetStaticField cenv cgbuf eenv (f, tyargs, m) sequel - | TOp.ValFieldGetAddr (f, _readonly), [e], _ -> - GenGetRecdFieldAddr cenv cgbuf eenv (e, f, tyargs, m) sequel - | TOp.ValFieldGetAddr (f, _readonly), [], _ -> - GenGetStaticFieldAddr cenv cgbuf eenv (f, tyargs, m) sequel - | TOp.ValFieldSet f, [e1;e2], _ -> - GenSetRecdField cenv cgbuf eenv (e1, f, tyargs, e2, m) sequel - | TOp.ValFieldSet f, [e2], _ -> - GenSetStaticField cenv cgbuf eenv (f, tyargs, e2, m) sequel - | TOp.Tuple tupInfo, _, _ -> - GenAllocTuple cenv cgbuf eenv (tupInfo, args, tyargs, m) sequel - | TOp.ILAsm (code, returnTys), _, _ -> - GenAsmCode cenv cgbuf eenv (code, tyargs, args, returnTys, m) sequel - | TOp.While (sp, _), [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _)], [] -> - GenWhileLoop cenv cgbuf eenv (sp, e1, e2, m) sequel - | TOp.For (spStart, dir), [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [v], e3, _, _)], [] -> - GenForLoop cenv cgbuf eenv (spStart, v, e1, dir, e2, e3, m) sequel - | TOp.TryFinally (spTry, spFinally), [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], [resty] -> - GenTryFinally cenv cgbuf eenv (e1, e2, m, resty, spTry, spFinally) sequel - | TOp.TryCatch (spTry, spWith), [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _);Expr.Lambda (_, _, _, [vh], eh, _, _)], [resty] -> - GenTryCatch cenv cgbuf eenv (e1, vf, ef, vh, eh, m, resty, spTry, spWith) sequel - | TOp.ILCall (virt, _, valu, newobj, valUseFlags, _, isDllImport, ilMethRef, enclArgTys, methArgTys, returnTys), args, [] -> - GenILCall cenv cgbuf eenv (virt, valu, newobj, valUseFlags, isDllImport, ilMethRef, enclArgTys, methArgTys, args, returnTys, m) sequel - | TOp.RefAddrGet _readonly, [e], [ty] -> GenGetAddrOfRefCellField cenv cgbuf eenv (e, ty, m) sequel - | TOp.Coerce, [e], [tgty;srcty] -> GenCoerce cenv cgbuf eenv (e, tgty, m, srcty) sequel - | TOp.Reraise, [], [rtnty] -> GenReraise cenv cgbuf eenv (rtnty, m) sequel - | TOp.TraitCall ss, args, [] -> GenTraitCall cenv cgbuf eenv (ss, args, m) expr sequel - | TOp.LValueOp (LSet, v), [e], [] -> GenSetVal cenv cgbuf eenv (v, e, m) sequel - | TOp.LValueOp (LByrefGet, v), [], [] -> GenGetByref cenv cgbuf eenv (v, m) sequel - | TOp.LValueOp (LByrefSet, v), [e], [] -> GenSetByref cenv cgbuf eenv (v, e, m) sequel - | TOp.LValueOp (LAddrOf _, v), [], [] -> GenGetValAddr cenv cgbuf eenv (v, m) sequel - | TOp.Array, elems, [elemTy] -> GenNewArray cenv cgbuf eenv (elems, elemTy, m) sequel - | TOp.Bytes bytes, [], [] -> - if cenv.opts.emitConstantArraysUsingStaticDataBlobs then - GenConstArray cenv cgbuf eenv g.ilg.typ_Byte bytes (fun buf b -> buf.EmitByte b) - GenSequel cenv eenv.cloc cgbuf sequel - else - GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkByte g m) bytes), g.byte_ty, m) sequel - | TOp.UInt16s arr, [], [] -> - if cenv.opts.emitConstantArraysUsingStaticDataBlobs then - GenConstArray cenv cgbuf eenv g.ilg.typ_UInt16 arr (fun buf b -> buf.EmitUInt16 b) - GenSequel cenv eenv.cloc cgbuf sequel - else - GenNewArraySimple cenv cgbuf eenv (List.ofArray (Array.map (mkUInt16 g m) arr), g.uint16_ty, m) sequel - | TOp.Goto label, _, _ -> - if cgbuf.mgbuf.cenv.opts.generateDebugSymbols then - cgbuf.EmitStartOfHiddenCode() - CG.EmitInstr cgbuf (pop 0) Push0 AI_nop - CG.EmitInstr cgbuf (pop 0) Push0 (I_br label) - // NOTE: discard sequel - | TOp.Return, [e], _ -> - GenExpr cenv cgbuf eenv SPSuppress e Return - // NOTE: discard sequel - | TOp.Return, [], _ -> - GenSequel cenv eenv.cloc cgbuf ReturnVoid - // NOTE: discard sequel - | TOp.Label label, _, _ -> - cgbuf.SetMarkToHere (Mark label) - GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel - | _ -> error(InternalError("Unexpected operator node expression", expr.Range)) - | Expr.StaticOptimization (constraints, e2, e3, m) -> - GenStaticOptimization cenv cgbuf eenv (constraints, e2, e3, m) sequel - | Expr.Obj (_, ty, _, _, [meth], [], m) when isDelegateTy g ty -> - GenDelegateExpr cenv cgbuf eenv expr (meth, m) sequel - | Expr.Obj (_, ty, basev, basecall, overrides, interfaceImpls, m) -> - GenObjectExpr cenv cgbuf eenv expr (ty, basev, basecall, overrides, interfaceImpls, m) sequel - - | Expr.Quote (ast, conv, _, m, ty) -> GenQuotation cenv cgbuf eenv (ast, conv, m, ty) sequel - | Expr.Link _ -> failwith "Unexpected reclink" - | Expr.TyChoose (_, _, m) -> error(InternalError("Unexpected Expr.TyChoose", m)) + | Expr.Link _ -> failwith "Unexpected reclink" + + | Expr.TyChoose (_, _, m) -> error(InternalError("Unexpected Expr.TyChoose", m)) and GenExprs cenv cgbuf eenv es = List.iter (fun e -> GenExpr cenv cgbuf eenv SPSuppress e Continue) es -and CodeGenMethodForExpr cenv mgbuf (spReq, entryPointInfo, methodName, eenv, alreadyUsedArgs, expr0, sequel0) = +and CodeGenMethodForExpr cenv mgbuf (spReq, entryPointInfo, methodName, eenv, alreadyUsedArgs, selfArgOpt, expr0, sequel0) = + let eenv = { eenv with exitSequel = sequel0 } let _, code = - CodeGenMethod cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, + CodeGenMethod cenv mgbuf (entryPointInfo, methodName, eenv, alreadyUsedArgs, selfArgOpt, (fun cgbuf eenv -> GenExpr cenv cgbuf eenv spReq expr0 sequel0), expr0.Range) - code + code //-------------------------------------------------------------------------- // Generate sequels //-------------------------------------------------------------------------- -(* does the sequel discard its result, and if so what does it do next? *) +/// Adjust the sequel for an implicit discard (e.g. a discard that occurs by +/// not generating a 'unit' expression at all) and sequelAfterDiscard sequel = match sequel with + | LeaveHandler (isFinally, whereToSaveResultOpt, afterHandler, true) -> + // If we're not saving the result as we leave a handler and we're doing a discard + // then we can just adjust the sequel to record the fact we've implicitly done a discard + if isFinally || whereToSaveResultOpt.IsNone then + Some (LeaveHandler (isFinally, whereToSaveResultOpt, afterHandler, false)) + else + None | DiscardThen sequel -> Some sequel | EndLocalScope(sq, mark) -> sequelAfterDiscard sq |> Option.map (fun sq -> EndLocalScope(sq, mark)) | _ -> None @@ -2408,18 +2759,26 @@ and GenSequel cenv cloc cgbuf sequel = | EndLocalScope _ -> failwith "EndLocalScope unexpected" | Br x -> // Emit a NOP in debug code in case the branch instruction gets eliminated - // because it is a "branch to next instruction". This prevents two unrelated sequence points + // because it is a "branch to next instruction". This prevents two unrelated debug points // (the one before the branch and the one after) being coalesced together if cgbuf.mgbuf.cenv.opts.generateDebugSymbols then cgbuf.EmitStartOfHiddenCode() CG.EmitInstr cgbuf (pop 0) Push0 AI_nop + CG.EmitInstr cgbuf (pop 0) Push0 (I_br x.CodeLabel) - | LeaveHandler (isFinally, whereToSaveResult, x) -> - if isFinally then - CG.EmitInstr cgbuf (pop 1) Push0 AI_pop - else - EmitSetLocal cgbuf whereToSaveResult - CG.EmitInstr cgbuf (pop 0) Push0 (if isFinally then I_endfinally else I_leave(x.CodeLabel)) + + | LeaveHandler (isFinally, whereToSaveResultOpt, afterHandler, hasResult) -> + if hasResult then + if isFinally then + CG.EmitInstr cgbuf (pop 1) Push0 AI_pop + else + match whereToSaveResultOpt with + | None -> + CG.EmitInstr cgbuf (pop 1) Push0 AI_pop + | Some (whereToSaveResult, _) -> + EmitSetLocal cgbuf whereToSaveResult + CG.EmitInstr cgbuf (pop 0) Push0 (if isFinally then I_endfinally else I_leave(afterHandler.CodeLabel)) + | EndFilter -> CG.EmitInstr cgbuf (pop 1) Push0 I_endfilter ) @@ -2440,24 +2799,27 @@ and GenConstant cenv cgbuf eenv (c, m, ty) sequel = | Some e -> GenExpr cenv cgbuf eenv SPSuppress e Continue | None -> - match c with - | Const.Bool b -> CG.EmitInstr cgbuf (pop 0) (Push [g.ilg.typ_Bool]) (mkLdcInt32 (if b then 1 else 0)) - | Const.SByte i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) - | Const.Int16 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) - | Const.Int32 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 i) - | Const.Int64 i -> - // see https://github.com/Microsoft/visualfsharp/pull/3620 + let emitInt64Constant i = + // see https://github.com/dotnet/fsharp/pull/3620 + // and https://github.com/dotnet/fsharp/issue/8683 + // and https://github.com/dotnet/roslyn/blob/98f12bb/src/Compilers/Core/Portable/CodeGen/ILBuilderEmit.cs#L679 if i >= int64 System.Int32.MinValue && i <= int64 System.Int32.MaxValue then CG.EmitInstrs cgbuf (pop 0) (Push [ilTy]) [ mkLdcInt32 (int32 i); AI_conv DT_I8 ] elif i >= int64 System.UInt32.MinValue && i <= int64 System.UInt32.MaxValue then CG.EmitInstrs cgbuf (pop 0) (Push [ilTy]) [ mkLdcInt32 (int32 i); AI_conv DT_U8 ] else CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (iLdcInt64 i) + match c with + | Const.Bool b -> CG.EmitInstr cgbuf (pop 0) (Push [g.ilg.typ_Bool]) (mkLdcInt32 (if b then 1 else 0)) + | Const.SByte i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) + | Const.Int16 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) + | Const.Int32 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 i) + | Const.Int64 i -> emitInt64Constant i | Const.IntPtr i -> CG.EmitInstrs cgbuf (pop 0) (Push [ilTy]) [iLdcInt64 i; AI_conv DT_I ] | Const.Byte i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) | Const.UInt16 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) | Const.UInt32 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdcInt32 (int32 i)) - | Const.UInt64 i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (iLdcInt64 (int64 i)) + | Const.UInt64 i -> emitInt64Constant (int64 i) | Const.UIntPtr i -> CG.EmitInstrs cgbuf (pop 0) (Push [ilTy]) [iLdcInt64 (int64 i); AI_conv DT_U ] | Const.Double f -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (AI_ldc (DT_R8, ILConst.R8 f)) | Const.Single f -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (AI_ldc (DT_R4, ILConst.R4 f)) @@ -2550,79 +2912,73 @@ and GenAllocUnionCase cenv cgbuf eenv (c,tyargs,args,m) sequel = GenAllocUnionCaseCore cenv cgbuf eenv (c,tyargs,args.Length,m) GenSequel cenv eenv.cloc cgbuf sequel -and GenLinearExpr cenv cgbuf eenv sp expr sequel canProcessSequencePoint (contf: FakeUnit -> FakeUnit) = +and GenLinearExpr cenv cgbuf eenv sp expr sequel preSteps (contf: FakeUnit -> FakeUnit) = let expr = stripExpr expr - match expr with + match expr with | Expr.Sequential (e1, e2, specialSeqFlag, spSeq, _) -> - if canProcessSequencePoint then - ProcessSequencePointForExpr cenv cgbuf sp expr + // Process the debug point and see if there's a replacement technique to process this expression + if preSteps && GenExprPreSteps cenv cgbuf eenv sp expr sequel then contf Fake else - // Compiler generated sequential executions result in suppressions of sequence points on both + // Compiler generated sequential executions result in suppressions of debug points on both // left and right of the sequence - let spAction, spExpr = + let spStmt, spExpr = (match spSeq with - | SequencePointsAtSeq -> SPAlways, SPAlways - | SuppressSequencePointOnExprOfSequential -> SPSuppress, sp - | SuppressSequencePointOnStmtOfSequential -> sp, SPSuppress) + | DebugPointAtSequential.SuppressNeither -> SPAlways, SPAlways + | DebugPointAtSequential.SuppressStmt -> SPSuppress, sp + | DebugPointAtSequential.SuppressExpr -> sp, SPSuppress + | DebugPointAtSequential.SuppressBoth -> SPSuppress, SPSuppress) match specialSeqFlag with | NormalSeq -> - GenExpr cenv cgbuf eenv spAction e1 discard - GenLinearExpr cenv cgbuf eenv spExpr e2 sequel (* canProcessSequencePoint *) true contf + GenExpr cenv cgbuf eenv spStmt e1 discard + GenLinearExpr cenv cgbuf eenv spExpr e2 sequel true contf | ThenDoSeq -> - GenExpr cenv cgbuf eenv spExpr e1 Continue - GenExpr cenv cgbuf eenv spAction e2 discard - GenSequel cenv eenv.cloc cgbuf sequel + let g = cenv.g + let isUnit = isUnitTy g (tyOfExpr g e1) + if isUnit then + GenExpr cenv cgbuf eenv spExpr e1 discard + GenExpr cenv cgbuf eenv spStmt e2 discard + GenUnitThenSequel cenv eenv e2.Range eenv.cloc cgbuf sequel + else + GenExpr cenv cgbuf eenv spExpr e1 Continue + GenExpr cenv cgbuf eenv spStmt e2 discard + GenSequel cenv eenv.cloc cgbuf sequel contf Fake | Expr.Let (bind, body, _, _) -> - if canProcessSequencePoint then - ProcessSequencePointForExpr cenv cgbuf sp expr + // Process the debug point and see if there's a replacement technique to process this expression + if preSteps && GenExprPreSteps cenv cgbuf eenv sp expr sequel then contf Fake else // This case implemented here to get a guaranteed tailcall - // Make sure we generate the sequence point outside the scope of the variable - let startScope, endScope as scopeMarks = StartDelayedLocalScope "let" cgbuf + // Make sure we generate the debug point outside the scope of the variable + let startMark, endMark as scopeMarks = StartDelayedLocalScope "let" cgbuf let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind - let spBind = GenSequencePointForBind cenv cgbuf bind - GenBindingAfterSequencePoint cenv cgbuf eenv spBind bind (Some startScope) + let spBind = GenDebugPointForBind cenv cgbuf bind + GenBindingAfterDebugPoint cenv cgbuf eenv spBind bind false (Some startMark) - // Work out if we need a sequence point for the body. For any "user" binding then the body gets SPAlways. + // Work out if we need a debug point for the body. For any "user" binding then the body gets SPAlways. // For invisible compiler-generated bindings we just use "sp", unless its body is another invisible binding - // For sticky bindings arising from inlining we suppress any immediate sequence point in the body + // For sticky bindings arising from inlining we suppress any immediate debug point in the body let spBody = - match bind.SequencePointInfo with - | SequencePointAtBinding _ - | NoSequencePointAtLetBinding - | NoSequencePointAtDoBinding -> SPAlways - | NoSequencePointAtInvisibleBinding -> sp - | NoSequencePointAtStickyBinding -> SPSuppress - + match bind.DebugPoint with + | DebugPointAtBinding.Yes _ + | DebugPointAtBinding.NoneAtLet + | DebugPointAtBinding.NoneAtDo -> SPAlways + | DebugPointAtBinding.NoneAtInvisible -> sp + | DebugPointAtBinding.NoneAtSticky -> SPSuppress + // Generate the body - GenLinearExpr cenv cgbuf eenv spBody body (EndLocalScope(sequel, endScope)) (* canProcessSequencePoint *) true contf + GenLinearExpr cenv cgbuf eenv spBody body (EndLocalScope(sequel, endMark)) true contf | Expr.Match (spBind, _exprm, tree, targets, m, ty) -> - if canProcessSequencePoint then - ProcessSequencePointForExpr cenv cgbuf sp expr + // Process the debug point and see if there's a replacement technique to process this expression + if preSteps && GenExprPreSteps cenv cgbuf eenv sp expr sequel then contf Fake else match spBind with - | SequencePointAtBinding m -> CG.EmitSeqPoint cgbuf m - | NoSequencePointAtDoBinding - | NoSequencePointAtLetBinding - | NoSequencePointAtInvisibleBinding - | NoSequencePointAtStickyBinding -> () - - // The target of branch needs a sequence point. - // If we don't give it one it will get entirely the wrong sequence point depending on earlier codegen - // Note we're not interested in having pattern matching and decision trees reveal their inner working. - // Hence at each branch target we 'reassert' the overall sequence point that was active as we came into the match. - // - // NOTE: sadly this causes multiple sequence points to appear for the "initial" location of an if/then/else or match. - let activeSP = cgbuf.GetLastSequencePoint() - let repeatSP() = - match activeSP with - | None -> () - | Some src -> - if activeSP <> cgbuf.GetLastSequencePoint() then - CG.EmitSeqPoint cgbuf src + | DebugPointAtBinding.Yes m -> CG.EmitDebugPoint cgbuf m + | DebugPointAtBinding.NoneAtDo + | DebugPointAtBinding.NoneAtLet + | DebugPointAtBinding.NoneAtInvisible + | DebugPointAtBinding.NoneAtSticky -> () // First try the common cases where we don't need a join point. match tree with @@ -2632,13 +2988,13 @@ and GenLinearExpr cenv cgbuf eenv sp expr sequel canProcessSequencePoint (contf: | _ -> // Create a join point let stackAtTargets = cgbuf.GetCurrentStack() // the stack at the target of each clause - let (sequelOnBranches, afterJoin, stackAfterJoin, sequelAfterJoin) = GenJoinPoint cenv cgbuf "match" eenv ty m sequel + let sequelOnBranches, afterJoin, stackAfterJoin, sequelAfterJoin = GenJoinPoint cenv cgbuf "match" eenv ty m sequel // Stack: "stackAtTargets" is "stack prior to any match-testing" and also "stack at the start of each branch-RHS". // match-testing (dtrees) should not contribute to the stack. // Each branch-RHS (targets) may contribute to the stack, leaving it in the "stackAfterJoin" state, for the join point. // Since code is branching and joining, the cgbuf stack is maintained manually. - GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets repeatSP sequelOnBranches (contf << (fun Fake -> + GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets sequelOnBranches (contf << (fun Fake -> CG.SetMarkToHere cgbuf afterJoin //assert(cgbuf.GetCurrentStack() = stackAfterJoin) // REVIEW: Since gen_dtree* now sets stack, stack should be stackAfterJoin at this point... @@ -2661,16 +3017,16 @@ and GenLinearExpr cenv cgbuf eenv sp expr sequel canProcessSequencePoint (contf: Fake)) | LinearOpExpr (TOp.UnionCase c, tyargs, argsFront, argLast, m) -> - if canProcessSequencePoint then - ProcessSequencePointForExpr cenv cgbuf sp expr + // Process the debug point and see if there's a replacement technique to process this expression + if preSteps && GenExprPreSteps cenv cgbuf eenv sp expr sequel then contf Fake else GenExprs cenv cgbuf eenv argsFront - GenLinearExpr cenv cgbuf eenv SPSuppress argLast Continue (* canProcessSequencePoint *) true (contf << (fun Fake -> + GenLinearExpr cenv cgbuf eenv SPSuppress argLast Continue true (contf << (fun Fake -> GenAllocUnionCaseCore cenv cgbuf eenv (c, tyargs, argsFront.Length + 1, m) GenSequel cenv eenv.cloc cgbuf sequel Fake)) - | _ -> + | _ -> GenExpr cenv cgbuf eenv sp expr sequel contf Fake @@ -2695,14 +3051,14 @@ and GenAllocRecd cenv cgbuf eenv ctorInfo (tcref,argtys,args,m) sequel = | RecdExpr -> GenExprs cenv cgbuf eenv args // generate a reference to the record constructor - let tyenvinner = TypeReprEnv.ForTyconRef tcref + let tyenvinner = eenv.tyenv.ForTyconRef tcref CG.EmitInstr cgbuf (pop args.Length) (Push [ty]) (mkNormalNewobj (mkILCtorMethSpecForTy (ty, relevantFields |> List.map (fun f -> GenType cenv.amap m tyenvinner f.FormalType) ))) GenSequel cenv eenv.cloc cgbuf sequel and GenAllocAnonRecd cenv cgbuf eenv (anonInfo: AnonRecdTypeInfo, tyargs, args, m) sequel = - let anonCtor, _anonMethods, anonType = cgbuf.mgbuf.LookupAnonType anonInfo + let anonCtor, _anonMethods, anonType = cgbuf.mgbuf.LookupAnonType ((fun ilThisTy -> GenToStringMethod cenv eenv ilThisTy m), anonInfo) let boxity = anonType.Boxity GenExprs cenv cgbuf eenv args let ilTypeArgs = GenTypeArgs cenv.amap m eenv.tyenv tyargs @@ -2711,12 +3067,12 @@ and GenAllocAnonRecd cenv cgbuf eenv (anonInfo: AnonRecdTypeInfo, tyargs, args, GenSequel cenv eenv.cloc cgbuf sequel and GenGetAnonRecdField cenv cgbuf eenv (anonInfo: AnonRecdTypeInfo, e, tyargs, n, m) sequel = - let _anonCtor, anonMethods, anonType = cgbuf.mgbuf.LookupAnonType anonInfo + let _anonCtor, anonMethods, anonType = cgbuf.mgbuf.LookupAnonType ((fun ilThisTy -> GenToStringMethod cenv eenv ilThisTy m), anonInfo) let boxity = anonType.Boxity let ilTypeArgs = GenTypeArgs cenv.amap m eenv.tyenv tyargs let anonMethod = anonMethods.[n] let anonFieldType = ilTypeArgs.[n] - GenExpr cenv cgbuf eenv SPSuppress e Continue + GenExpr cenv cgbuf eenv SPSuppress e Continue CG.EmitInstr cgbuf (pop 1) (Push [anonFieldType]) (mkNormalCall (mkILMethSpec(anonMethod, boxity, ilTypeArgs, []))) GenSequel cenv eenv.cloc cgbuf sequel @@ -2724,11 +3080,15 @@ and GenNewArraySimple cenv cgbuf eenv (elems, elemTy, m) sequel = let ilElemTy = GenType cenv.amap m eenv.tyenv elemTy let ilArrTy = mkILArr1DTy ilElemTy - CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy]) [ (AI_ldc (DT_I4, ILConst.I4 (elems.Length))); I_newarr (ILArrayShape.SingleDimensional, ilElemTy) ] - elems |> List.iteri (fun i e -> - CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy; cenv.g.ilg.typ_Int32]) [ AI_dup; (AI_ldc (DT_I4, ILConst.I4 i)) ] - GenExpr cenv cgbuf eenv SPSuppress e Continue - CG.EmitInstr cgbuf (pop 3) Push0 (I_stelem_any (ILArrayShape.SingleDimensional, ilElemTy))) + if List.isEmpty elems && cenv.g.isArrayEmptyAvailable then + mkNormalCall (mkILMethSpecInTy (cenv.g.ilg.typ_Array, ILCallingConv.Static, "Empty", [], mkILArr1DTy (mkILTyvarTy 0us), [ilElemTy])) + |> CG.EmitInstr cgbuf (pop 0) (Push [ilArrTy]) + else + CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy]) [ (AI_ldc (DT_I4, ILConst.I4 elems.Length)); I_newarr (ILArrayShape.SingleDimensional, ilElemTy) ] + elems |> List.iteri (fun i e -> + CG.EmitInstrs cgbuf (pop 0) (Push [ilArrTy; cenv.g.ilg.typ_Int32]) [ AI_dup; (AI_ldc (DT_I4, ILConst.I4 i)) ] + GenExpr cenv cgbuf eenv SPSuppress e Continue + CG.EmitInstr cgbuf (pop 3) Push0 (I_stelem_any (ILArrayShape.SingleDimensional, ilElemTy))) GenSequel cenv eenv.cloc cgbuf sequel @@ -2774,7 +3134,7 @@ and GenNewArray cenv cgbuf eenv (elems: Expr list, elemTy, m) sequel = (fun buf -> function Const.Int32 b -> buf.EmitInt32 b | _ -> failwith "unreachable") | Expr.Const (Const.Int64 _, _, _) -> (function Const.Int64 _ -> true | _ -> false), - (fun buf -> function Const.Int64 b -> buf.EmitInt64 b | _ -> failwith "unreachable") + (fun buf -> function Const.Int64 b -> buf.EmitInt64 b | _ -> failwith "unreachable") | _ -> (function _ -> false), (fun _ _ -> failwith "unreachable") if elems' |> Array.forall (function Expr.Const (c, _, _) -> test c | _ -> false) then @@ -2786,34 +3146,32 @@ and GenNewArray cenv cgbuf eenv (elems: Expr list, elemTy, m) sequel = GenNewArraySimple cenv cgbuf eenv (elems, elemTy, m) sequel and GenCoerce cenv cgbuf eenv (e, tgty, m, srcty) sequel = - let g = cenv.g - // Is this an upcast? - if TypeRelations.TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgty srcty && - // Do an extra check - should not be needed - TypeRelations.TypeFeasiblySubsumesType 0 g cenv.amap m tgty TypeRelations.NoCoerce srcty then - begin - if (isInterfaceTy g tgty) then ( - GenExpr cenv cgbuf eenv SPSuppress e Continue - let ilToTy = GenType cenv.amap m eenv.tyenv tgty - // Section "III.1.8.1.3 Merging stack states" of ECMA-335 implies that no unboxing - // is required, but we still push the coerced type on to the code gen buffer. - CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [] - GenSequel cenv eenv.cloc cgbuf sequel - ) else ( - GenExpr cenv cgbuf eenv SPSuppress e sequel - ) - end - else - GenExpr cenv cgbuf eenv SPSuppress e Continue - if not (isObjTy g srcty) then - let ilFromTy = GenType cenv.amap m eenv.tyenv srcty - CG.EmitInstrs cgbuf (pop 1) (Push [g.ilg.typ_Object]) [ I_box ilFromTy ] - if not (isObjTy g tgty) then - let ilToTy = GenType cenv.amap m eenv.tyenv tgty - CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy ] - GenSequel cenv eenv.cloc cgbuf sequel + let g = cenv.g + // Is this an upcast? + if TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgty srcty && + // Do an extra check - should not be needed + TypeFeasiblySubsumesType 0 g cenv.amap m tgty NoCoerce srcty + then + if isInterfaceTy g tgty then + GenExpr cenv cgbuf eenv SPSuppress e Continue + let ilToTy = GenType cenv.amap m eenv.tyenv tgty + // Section "III.1.8.1.3 Merging stack states" of ECMA-335 implies that no unboxing + // is required, but we still push the coerced type on to the code gen buffer. + CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [] + GenSequel cenv eenv.cloc cgbuf sequel + else + GenExpr cenv cgbuf eenv SPSuppress e sequel + else + GenExpr cenv cgbuf eenv SPSuppress e Continue + if not (isObjTy g srcty) then + let ilFromTy = GenType cenv.amap m eenv.tyenv srcty + CG.EmitInstrs cgbuf (pop 1) (Push [g.ilg.typ_Object]) [ I_box ilFromTy ] + if not (isObjTy g tgty) then + let ilToTy = GenType cenv.amap m eenv.tyenv tgty + CG.EmitInstrs cgbuf (pop 1) (Push [ilToTy]) [ I_unbox_any ilToTy ] + GenSequel cenv eenv.cloc cgbuf sequel -and GenReraise cenv cgbuf eenv (rtnty, m) sequel = +and GenReraise cenv cgbuf eenv (rtnty, m) sequel = let ilReturnTy = GenType cenv.amap m eenv.tyenv rtnty CG.EmitInstrs cgbuf (pop 0) Push0 [I_rethrow] // [See comment related to I_throw]. @@ -2831,7 +3189,7 @@ and GenGetExnField cenv cgbuf eenv (e, ecref, fieldNum, m) sequel = let fld = List.item fieldNum exnc.TrueInstanceFieldsAsList let ftyp = GenType cenv.amap m eenv.tyenv fld.FormalType - let mspec = mkILNonGenericInstanceMethSpecInTy (ty, "get_" + fld.Name, [], ftyp) + let mspec = mkILNonGenericInstanceMethSpecInTy (ty, "get_" + fld.LogicalName, [], ftyp) CG.EmitInstr cgbuf (pop 1) (Push [ftyp]) (mkNormalCall mspec) GenSequel cenv eenv.cloc cgbuf sequel @@ -2850,13 +3208,13 @@ and GenSetExnField cenv cgbuf eenv (e, ecref, fieldNum, e2, m) sequel = and UnionCodeGen (cgbuf: CodeGenBuffer) = { new EraseUnions.ICodeGen with - member __.CodeLabel m = m.CodeLabel - member __.GenerateDelayMark() = CG.GenerateDelayMark cgbuf "unionCodeGenMark" - member __.GenLocal ilty = cgbuf.AllocLocal([], ilty, false) |> uint16 - member __.SetMarkToHere m = CG.SetMarkToHere cgbuf m - member __.MkInvalidCastExnNewobj () = mkInvalidCastExnNewobj cgbuf.mgbuf.cenv.g - member __.EmitInstr x = CG.EmitInstr cgbuf (pop 0) (Push []) x - member __.EmitInstrs xs = CG.EmitInstrs cgbuf (pop 0) (Push []) xs } + member _.CodeLabel m = m.CodeLabel + member _.GenerateDelayMark() = CG.GenerateDelayMark cgbuf "unionCodeGenMark" + member _.GenLocal ilty = cgbuf.AllocLocal([], ilty, false) |> uint16 + member _.SetMarkToHere m = CG.SetMarkToHere cgbuf m + member _.MkInvalidCastExnNewobj () = mkInvalidCastExnNewobj cgbuf.mgbuf.cenv.g + member _.EmitInstr x = CG.EmitInstr cgbuf (pop 0) (Push []) x + member _.EmitInstrs xs = CG.EmitInstrs cgbuf (pop 0) (Push []) xs } and GenUnionCaseProof cenv cgbuf eenv (e, ucref, tyargs, m) sequel = let g = cenv.g @@ -2915,12 +3273,12 @@ and GenGetRecdFieldAddr cenv cgbuf eenv (e, f, tyargs, m) sequel = let fref = GenRecdFieldRef m cenv eenv.tyenv f tyargs CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref fref.ActualType]) [ I_ldflda fref ] GenSequel cenv eenv.cloc cgbuf sequel - + and GenGetStaticFieldAddr cenv cgbuf eenv (f, tyargs, m) sequel = let fspec = GenRecdFieldRef m cenv eenv.tyenv f tyargs CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref fspec.ActualType]) [ I_ldsflda fspec ] GenSequel cenv eenv.cloc cgbuf sequel - + and GenGetRecdField cenv cgbuf eenv (e, f, tyargs, m) sequel = GenExpr cenv cgbuf eenv SPSuppress e Continue GenFieldGet false cenv cgbuf eenv (f, tyargs, m) @@ -2987,32 +3345,30 @@ and GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInf GenExpr cenv cgbuf eenv SPSuppress arg2 discard | _ -> (curriedArgInfos, args) ||> List.iter2 (fun argInfos x -> - GenUntupledArgExpr cenv cgbuf eenv m argInfos x Continue) + GenUntupledArgExpr cenv cgbuf eenv m argInfos x) /// Codegen arguments -and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr sequel = +and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr = let g = cenv.g let numRequiredExprs = List.length argInfos - assert (numRequiredExprs >= 1) - if numRequiredExprs = 1 then - GenExpr cenv cgbuf eenv SPSuppress expr sequel + if numRequiredExprs = 0 then + () + elif numRequiredExprs = 1 then + GenExpr cenv cgbuf eenv SPSuppress expr Continue elif isRefTupleExpr expr then let es = tryDestRefTupleExpr expr if es.Length <> numRequiredExprs then error(InternalError("GenUntupledArgExpr (2)", m)) es |> List.iter (fun x -> GenExpr cenv cgbuf eenv SPSuppress x Continue) - GenSequel cenv eenv.cloc cgbuf sequel else let ty = tyOfExpr g expr let locv, loce = mkCompGenLocal m "arg" ty let bind = mkCompGenBind locv expr LocalScope "untuple" cgbuf (fun scopeMarks -> let eenvinner = AllocStorageForBind cenv cgbuf scopeMarks eenv bind - GenBinding cenv cgbuf eenvinner bind + GenBinding cenv cgbuf eenvinner bind false let tys = destRefTupleTy g ty assert (tys.Length = numRequiredExprs) - // TODO - tupInfoRef - argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (tupInfoRef (* TODO *), loce, tys, i, m) Continue) - GenSequel cenv eenv.cloc cgbuf sequel + argInfos |> List.iteri (fun i _ -> GenGetTupleField cenv cgbuf eenvinner (tupInfoRef, loce, tys, i, m) Continue) ) @@ -3020,68 +3376,160 @@ and GenUntupledArgExpr cenv cgbuf eenv m argInfos expr sequel = // Generate calls (try to detect direct calls) //-------------------------------------------------------------------------- -and GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel = +and GenWitnessArgFromTraitInfo cenv cgbuf eenv m traitInfo = + let g = cenv.g + let storage = TryStorageForWitness g eenv traitInfo.TraitKey + match storage with + | None -> + let witnessExpr = + ConstraintSolver.CodegenWitnessArgForTraitConstraint cenv.tcVal g cenv.amap m traitInfo + |> CommitOperationResult + match witnessExpr with + | Choice1Of2 _traitInfo -> + System.Diagnostics.Debug.Assert(false, "expected storage for witness") + failwith "unexpected non-generation of witness " + | Choice2Of2 arg -> + let eenv = { eenv with suppressWitnesses = true } + GenExpr cenv cgbuf eenv SPSuppress arg Continue + | Some storage -> + let ty = GenWitnessTy g traitInfo.TraitKey + GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m eenv.tyenv ty) storage None + +and GenWitnessArgFromWitnessInfo cenv cgbuf eenv m witnessInfo = + let g = cenv.g + let storage = TryStorageForWitness g eenv witnessInfo + match storage with + | None -> + System.Diagnostics.Debug.Assert(false, "expected storage for witness") + failwith "unexpected non-generation of witness " + | Some storage -> + let ty = GenWitnessTy g witnessInfo + GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m eenv.tyenv ty) storage None + +and GenWitnessArgsFromWitnessInfos cenv cgbuf eenv m witnessInfos = + let g = cenv.g + let generateWitnesses = ComputeGenerateWitnesses g eenv + // Witness arguments are only generated in emitted 'inline' code where witness parameters are available. + if generateWitnesses then + for witnessInfo in witnessInfos do + GenWitnessArgFromWitnessInfo cenv cgbuf eenv m witnessInfo + +and GenWitnessArgs cenv cgbuf eenv m tps tyargs = + let g = cenv.g + let generateWitnesses = ComputeGenerateWitnesses g eenv + // Witness arguments are only generated in emitted 'inline' code where witness parameters are available. + if generateWitnesses then + let mwitnesses = + ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs + |> CommitOperationResult + + for witnessArg in mwitnesses do + match witnessArg with + | Choice1Of2 traitInfo -> + GenWitnessArgFromTraitInfo cenv cgbuf eenv m traitInfo + | Choice2Of2 arg -> + GenExpr cenv cgbuf eenv SPSuppress arg Continue + +and IsBranchTailcall (cenv: cenv) eenv (v: ValRef, tyargs, curriedArgs: _ list) sequel = + let g = cenv.g + match ListAssoc.tryFind g.valRefEq v eenv.innerVals with + | Some (kind, _) -> + not v.IsConstructor && + // when branch-calling methods we must have the right type parameters + (match kind with + | BranchCallClosure _ -> true + | BranchCallMethod (_, _, tps, _, _, _) -> + (List.lengthsEqAndForall2 (fun ty tp -> typeEquiv g ty (mkTyparTy tp)) tyargs tps)) && + // must be exact #args, ignoring tupling - we untuple if needed below + (let arityInfo = + match kind with + | BranchCallClosure arityInfo + | BranchCallMethod (arityInfo, _, _, _, _, _) -> arityInfo + arityInfo.Length = curriedArgs.Length + ) && + // no tailcall out of exception handler, etc. + (match sequelIgnoringEndScopesAndDiscard sequel with + | Return + | ReturnVoid -> true + | _ -> false) + | None -> false + +and GenApp (cenv: cenv) cgbuf eenv (f, fty, tyargs, curriedArgs, m) sequel = let g = cenv.g - match (f, tyargs, args) with - (* Look for tailcall to turn into branch *) - | (Expr.Val (v, _, _), _, _) when - match ListAssoc.tryFind g.valRefEq v eenv.innerVals with - | Some (kind, _) -> - (not v.IsConstructor && - (* when branch-calling methods we must have the right type parameters *) - (match kind with - | BranchCallClosure _ -> true - | BranchCallMethod (_, _, tps, _, _) -> - (List.lengthsEqAndForall2 (fun ty tp -> typeEquiv g ty (mkTyparTy tp)) tyargs tps)) && - (* must be exact #args, ignoring tupling - we untuple if needed below *) - (let arityInfo = - match kind with - | BranchCallClosure arityInfo - | BranchCallMethod (arityInfo, _, _, _, _) -> arityInfo - arityInfo.Length = args.Length - ) && - (* no tailcall out of exception handler, etc. *) - (match sequelIgnoringEndScopesAndDiscard sequel with Return | ReturnVoid -> true | _ -> false)) - | None -> false - -> - let (kind, mark) = ListAssoc.find g.valRefEq v eenv.innerVals // already checked above in when guard - let ntmargs = - match kind with - | BranchCallClosure arityInfo -> - let ntmargs = List.foldBack (+) arityInfo 0 - GenExprs cenv cgbuf eenv args - ntmargs - | BranchCallMethod (arityInfo, curriedArgInfos, _, ntmargs, numObjArgs) -> - assert (curriedArgInfos.Length = arityInfo.Length ) - assert (curriedArgInfos.Length = args.Length) - //assert (curriedArgInfos.Length = ntmargs ) - GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInfos args - if v.IsExtensionMember then - match curriedArgInfos, args with - | [[]], [_] when numObjArgs = 0 -> (ntmargs-1) - | [[_];[]], [_;_] when numObjArgs = 1 -> (ntmargs-1) - | _ -> ntmargs - else ntmargs - - for i = ntmargs - 1 downto 0 do - CG.EmitInstrs cgbuf (pop 1) Push0 [ I_starg (uint16 (i+cgbuf.PreallocatedArgCount)) ] + match (f, tyargs, curriedArgs) with + // Look for tailcall to turn into branch + | Expr.Val (v, _, _), _, _ when IsBranchTailcall cenv eenv (v, tyargs, curriedArgs) sequel -> + let kind, mark = ListAssoc.find g.valRefEq v eenv.innerVals // already checked above in when guard + + // Generate the arguments for the direct tail call. + // We push all the arguments on the IL stack then write them back to the argument slots using + // I_starg. This seems a little sloppy, we could generate-then-write for each of the arguments. + // + // The arguments pushed don't include the 'this' argument for a recursive closure call (in PreallocatedArgCount) + // The arguments _do_ include the 'this' argument for instance method calls. The arguments do _not_ include witness arguments. + match kind with + | BranchCallClosure arityInfo -> + GenExprs cenv cgbuf eenv curriedArgs + + let numArgs = List.sum arityInfo + + for i = numArgs - 1 downto 0 do + CG.EmitInstrs cgbuf (pop 1) Push0 [ I_starg (uint16 (cgbuf.PreallocatedArgCount+i)) ] + + | BranchCallMethod (arityInfo, curriedArgInfos, _, numObjArgs, numWitnessArgs, numMethodArgs) -> + assert (curriedArgInfos.Length = arityInfo.Length ) + assert (curriedArgInfos.Length = curriedArgs.Length) + + //assert (curriedArgInfos.Length = numArgs ) + // NOTE: we are not generating the witness arguments here + GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m numObjArgs curriedArgInfos curriedArgs + + // Extension methods with empty arguments are evidently not quite in sufficiently normalized form, + // so apply a fixup here. This feels like a mistake associated with BindUnitVars, where that is not triggering + // in this case. + let numArgs = + if v.IsExtensionMember then + match curriedArgInfos, curriedArgs with + // static extension method with empty arguments. + | [[]], [_] when numObjArgs = 0 -> 0 + // instance extension method with empty arguments. + | [[_];[]], [_;_] when numObjArgs = 0 -> 1 + | _ -> numMethodArgs + else numMethodArgs + + for i = numArgs - 1 downto 0 do + CG.EmitInstrs cgbuf (pop 1) Push0 [ I_starg (uint16 (cgbuf.PreallocatedArgCount+numObjArgs+numWitnessArgs+i)) ] + + // Note, we don't reassign the witness arguments as these wont' have changed, because the type parameters are identical + + for i = numObjArgs - 1 downto 0 do + CG.EmitInstrs cgbuf (pop 1) Push0 [ I_starg (uint16 (cgbuf.PreallocatedArgCount+i)) ] CG.EmitInstrs cgbuf (pop 0) Push0 [ I_br mark.CodeLabel ] GenSequelEndScopes cgbuf sequel - + // PhysicalEquality becomes cheap reference equality once // a nominal type is known. We can't replace it for variable types since // a "ceq" instruction can't be applied to variable type values. - | (Expr.Val (v, _, _), [ty], [arg1;arg2]) when + | Expr.Val (v, _, _), [ty], [arg1;arg2] when (valRefEq g v g.reference_equality_inner_vref) && isAppTy g ty -> - + GenExpr cenv cgbuf eenv SPSuppress arg1 Continue GenExpr cenv cgbuf eenv SPSuppress arg2 Continue CG.EmitInstr cgbuf (pop 2) (Push [g.ilg.typ_Bool]) AI_ceq GenSequel cenv eenv.cloc cgbuf sequel + | Expr.Val (v, _, m), _, _ + when valRefEq g v g.cgh__resumeAt_vref || + valRefEq g v g.cgh__resumableEntry_vref || + valRefEq g v g.cgh__stateMachine_vref + -> + errorR(Error(FSComp.SR.ilxgenInvalidConstructInStateMachineDuringCodegen(v.DisplayName), m)) + CG.EmitInstr cgbuf (pop 0) (Push [g.ilg.typ_Object]) AI_ldnull + GenSequel cenv eenv.cloc cgbuf sequel + // Emit "methodhandleof" calls as ldtoken instructions // // The token for the "GenericMethodDefinition" is loaded @@ -3092,21 +3540,21 @@ and GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel = // Generate ldtoken instruction for "methodhandleof(fun (a, b, c) -> f(a, b, c))" // where f is an F# function value or F# method | Expr.Lambda (_, _, _, _, Expr.App (OptionalCoerce(OptionalTyapp(Expr.Val (vref, _, _))), _, _, _, _), _, _) -> - + let storage = StorageForValRef g m vref eenv match storage with - | Method (_, _, mspec, _, _, _, _) -> + | Method (_, _, mspec, _, _, _, _, _, _, _, _, _) -> CG.EmitInstr cgbuf (pop 0) (Push [g.iltyp_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec)) | _ -> errorR(Error(FSComp.SR.ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen(), m)) - + // Generate ldtoken instruction for "methodhandleof(fun (a, b, c) -> obj.M(a, b, c))" // where M is an IL method. - | Expr.Lambda (_, _, _, _, Expr.Op (TOp.ILCall (_, _, valu, _, _, _, _, ilMethRef, actualTypeInst, actualMethInst, _), _, _, _), _, _) -> - - let boxity = (if valu then AsValue else AsObject) + | Expr.Lambda (_, _, _, _, Expr.Op (TOp.ILCall (_, _, isStruct, _, _, _, _, ilMethRef, enclTypeInst, methInst, _), _, _, _), _, _) -> + + let boxity = (if isStruct then AsValue else AsObject) let mkFormalParams gparams = gparams |> DropErasedTyargs |> List.mapi (fun n _gf -> mkILTyvarTy (uint16 n)) - let ilGenericMethodSpec = IL.mkILMethSpec (ilMethRef, boxity, mkFormalParams actualTypeInst, mkFormalParams actualMethInst) + let ilGenericMethodSpec = mkILMethSpec (ilMethRef, boxity, mkFormalParams enclTypeInst, mkFormalParams methInst) let i = I_ldtoken (ILToken.ILMethod ilGenericMethodSpec) CG.EmitInstr cgbuf (pop 0) (Push [g.iltyp_RuntimeMethodHandle]) i @@ -3122,65 +3570,72 @@ and GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel = when (let storage = StorageForValRef g m vref eenv match storage with - | Method (topValInfo, vref, _, _, _, _, _) -> + | Method (topValInfo, vref, _, _, _, _, _, _, _, _, _, _) -> (let tps, argtys, _, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m tps.Length = tyargs.Length && - argtys.Length <= args.Length) + argtys.Length <= curriedArgs.Length) | _ -> false) -> let storage = StorageForValRef g m vref eenv match storage with - | Method (topValInfo, vref, mspec, _, _, _, _) -> - let nowArgs, laterArgs = - let _, curriedArgInfos, _, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m - List.splitAt curriedArgInfos.Length args + | Method (topValInfo, vref, mspec, mspecW, _, ctps, mtps, curriedArgInfos, _, _, _, _) -> + + let nowArgs, laterArgs = List.splitAt curriedArgInfos.Length curriedArgs + + let actualRetTy = applyTys cenv.g vref.Type (tyargs, nowArgs) + + let _, witnessInfos, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm cenv.g topValInfo ctps.Length vref.Type m - let actualRetTy = applyTys g vref.Type (tyargs, nowArgs) - let _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm g topValInfo vref.Type m + let mspec = + let generateWitnesses = ComputeGenerateWitnesses g eenv + if not generateWitnesses || witnessInfos.IsEmpty then + mspec + else + mspecW let ilTyArgs = GenTypeArgs cenv.amap m eenv.tyenv tyargs - // For instance method calls chop off some type arguments, which are already - // carried by the class. Also work out if it's a virtual call. - let _, virtualCall, newobj, isSuperInit, isSelfInit, _, _, _ = GetMemberCallInfo g (vref, valUseFlags) in + // carried by the class. Also work out if it's a virtual call. + let _, virtualCall, newobj, isSuperInit, isSelfInit, takesInstanceArg, _, _ = GetMemberCallInfo g (vref, valUseFlags) // numEnclILTypeArgs will include unit-of-measure args, unfortunately. For now, just cut-and-paste code from GetMemberCallInfo // @REVIEW: refactor this let numEnclILTypeArgs = match vref.MemberInfo with - | Some _ when not (vref.IsExtensionMember) -> + | Some _ when not vref.IsExtensionMember -> List.length(vref.MemberApparentEntity.TyparsNoRange |> DropErasedTypars) | _ -> 0 - let (ilEnclArgTys, ilMethArgTys) = + let ilEnclArgTys, ilMethArgTys = if ilTyArgs.Length < numEnclILTypeArgs then error(InternalError("length mismatch", m)) List.splitAt numEnclILTypeArgs ilTyArgs let boxity = mspec.DeclaringType.Boxity let mspec = mkILMethSpec (mspec.MethodRef, boxity, ilEnclArgTys, ilMethArgTys) - + // "Unit" return types on static methods become "void" let mustGenerateUnitAfterCall = Option.isNone returnTy - + let ccallInfo = match valUseFlags with | PossibleConstrainedCall ty -> Some ty | _ -> None - + let isBaseCall = match valUseFlags with VSlotDirectCall -> true | _ -> false let isTailCall = if isNil laterArgs && not isSelfInit then let isDllImport = IsValRefIsDllImport g vref - let hasByrefArg = mspec.FormalArgTypes |> List.exists (function ILType.Byref _ -> true | _ -> false) + let hasByrefArg = mspec.FormalArgTypes |> List.exists IsILTypeByref let makesNoCriticalTailcalls = vref.MakesNoCriticalTailcalls - CanTailcall((boxity=AsValue), ccallInfo, eenv.withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, isSelfInit, makesNoCriticalTailcalls, sequel) + let hasStructObjArg = (boxity=AsValue) && takesInstanceArg + CanTailcall(hasStructObjArg, ccallInfo, eenv.withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, isSelfInit, makesNoCriticalTailcalls, sequel) else Normalcall - + let useICallVirt = virtualCall || useCallVirt cenv boxity mspec isBaseCall - + let callInstr = match valUseFlags with | PossibleConstrainedCall ty -> @@ -3195,6 +3650,12 @@ and GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel = if isSuperInit || isSelfInit then CG.EmitInstrs cgbuf (pop 0) (Push [mspec.DeclaringType ]) [ mkLdarg0 ] + if not cenv.g.generateWitnesses || witnessInfos.IsEmpty then + () // no witness args + else + let _ctyargs, mtyargs = List.splitAt ctps.Length tyargs + GenWitnessArgs cenv cgbuf eenv m mtps mtyargs + GenUntupledArgsDiscardingLoneUnit cenv cgbuf eenv m vref.NumObjArgs curriedArgInfos nowArgs // Generate laterArgs (for effects) and save @@ -3237,21 +3698,21 @@ and GenApp cenv cgbuf eenv (f, fty, tyargs, args, m) sequel = | Choice1Of2 (ilTy, loc) -> EmitGetLocal cgbuf ilTy loc | Choice2Of2 expr -> GenExpr cenv cgbuf eenv SPSuppress expr Continue) GenIndirectCall cenv cgbuf eenv (actualRetTy, [], laterArgs, m) sequel) - + | _ -> failwith "??" - + // This case is for getting/calling a value, when we can't call it directly. // However, we know the type instantiation for the value. // In this case we can often generate a type-specific local expression for the value. // This reduces the number of dynamic type applications. - | (Expr.Val (vref, _, _), _, _) -> - GenGetValRefAndSequel cenv cgbuf eenv m vref (Some (tyargs, args, m, sequel)) - + | Expr.Val (vref, _, _), _, _ -> + GenGetValRefAndSequel cenv cgbuf eenv m vref (Some (tyargs, curriedArgs, m, sequel)) + | _ -> (* worst case: generate a first-class function value and call *) GenExpr cenv cgbuf eenv SPSuppress f Continue - GenArgsAndIndirectCall cenv cgbuf eenv (fty, tyargs, args, m) sequel - + GenCurriedArgsAndIndirectCall cenv cgbuf eenv (fty, tyargs, curriedArgs, m) sequel + and CanTailcall (hasStructObjArg, ccallInfo, withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, isSelfInit, makesNoCriticalTailcalls, sequel) = // Can't tailcall with a struct object arg since it involves a byref @@ -3267,44 +3728,137 @@ and CanTailcall (hasStructObjArg, ccallInfo, withinSEH, hasByrefArg, mustGenerat | _ -> false) then Tailcall else Normalcall - + +/// Choose the names for TraitWitnessInfo representations in arguments and free variables +and ChooseWitnessInfoNames takenNames (witnessInfos: TraitWitnessInfo list) = + witnessInfos + |> List.map (fun w -> String.uncapitalize w.MemberName) + |> ChooseFreeVarNames takenNames + +/// Represent the TraitWitnessInfos as arguments, e.g. in local type functions +and ArgStorageForWitnessInfos (cenv: cenv) (eenv: IlxGenEnv) takenNames pretakenArgs m (witnessInfos: TraitWitnessInfo list) = + let names = ChooseWitnessInfoNames takenNames witnessInfos + (witnessInfos, List.indexed names) + ||> List.map2 (fun w (i, nm) -> + let ty = GenWitnessTy cenv.g w + let ilTy = GenType cenv.amap m eenv.tyenv ty + let ilParam = mkILParam (Some nm, ilTy) + let storage = Arg (i+pretakenArgs) + ilParam, (w, storage)) + |> List.unzip + +/// Represent the TraitWitnessInfos as free variables, e.g. in closures +and FreeVarStorageForWitnessInfos (cenv: cenv) (eenv: IlxGenEnv) takenNames ilCloTyInner m (witnessInfos: TraitWitnessInfo list) = + let names = ChooseWitnessInfoNames takenNames witnessInfos + (witnessInfos, names) + ||> List.map2 (fun w nm -> + let ty = GenWitnessTy cenv.g w + let ilTy = GenType cenv.amap m eenv.tyenv ty + let ilFv = mkILFreeVar (nm, true, ilTy) + let storage = + let ilField = mkILFieldSpecInTy (ilCloTyInner, ilFv.fvName, ilFv.fvType) + Env(ilCloTyInner, ilField, None) + ilFv, (w, storage)) + |> List.unzip + +//-------------------------------------------------------------------------- +// Locally erased type functions +//-------------------------------------------------------------------------- + +/// Check for type lambda with entirely erased type arguments that is stored as +/// local variable (not method or property). For example +// let foo() = +// let a = 0<_> +// () +// in debug code , here `a` will be a TyLamba. However the compiled representation of +// `a` is an integer. +and IsLocalErasedTyLambda g eenv (v: Val) e = + match e with + | Expr.TyLambda (_, tyargs, body, _, _) when + tyargs |> List.forall (fun tp -> tp.IsErased) && + (match StorageForVal g v.Range v eenv with Local _ -> true | _ -> false) -> + match stripExpr body with + | Expr.Lambda _ -> None + | _ -> Some body + | _ -> None + +//-------------------------------------------------------------------------- +// Named local type functions +//-------------------------------------------------------------------------- + +and IsNamedLocalTypeFuncVal g (v: Val) expr = + not v.IsCompiledAsTopLevel && + IsGenericValWithGenericConstraints g v && + (match stripExpr expr with Expr.TyLambda _ -> true | _ -> false) + +and AddDirectTyparWitnessParams cenv eenv cloinfo m = + let directTypars = + match cloinfo.cloExpr with + | Expr.TyLambda (_, tvs, _, _, _) -> tvs + | _ -> [] + + let directWitnessInfos = + let generateWitnesses = ComputeGenerateWitnesses cenv.g eenv + if generateWitnesses then + // The 0 here represents that a closure doesn't reside within a generic class - there are no "enclosing class type parameters" to lop off. + GetTraitWitnessInfosOfTypars cenv.g 0 directTypars + else + [] + + // Direct witnesses get passed as arguments to DirectInvoke + let ilDirectWitnessParams, ilDirectWitnessParamsStorage = + let pretakenArgs = 1 + ArgStorageForWitnessInfos cenv eenv [] pretakenArgs m directWitnessInfos + let eenv = eenv |> AddStorageForLocalWitnesses ilDirectWitnessParamsStorage + + directTypars, ilDirectWitnessParams, directWitnessInfos, eenv + and GenNamedLocalTyFuncCall cenv (cgbuf: CodeGenBuffer) eenv ty cloinfo tyargs m = let g = cenv.g - let ilContractClassTyargs = - cloinfo.localTypeFuncContractFreeTypars - |> List.map mkTyparTy - |> GenTypeArgs cenv.amap m eenv.tyenv let ilTyArgs = tyargs |> GenTypeArgs cenv.amap m eenv.tyenv - let _, (ilContractMethTyargs: ILGenericParameterDefs), (ilContractCloTySpec: ILTypeSpec), ilContractFormalRetTy = - GenNamedLocalTypeFuncContractInfo cenv eenv m cloinfo + let ilCloTy = cloinfo.cloSpec.ILType + let ilDirectGenericParams, ilDirectWitnessParams, directWitnessInfos = + let eenvinner = EnvForTypars cloinfo.cloFreeTyvars eenv + let directTypars = + match cloinfo.cloExpr with + | Expr.TyLambda (_, tvs, _, _, _) -> tvs + | _ -> [] + + let eenvinner = AddTyparsToEnv directTypars eenvinner - let ilContractTy = mkILBoxedTy ilContractCloTySpec.TypeRef ilContractClassTyargs + let ilDirectGenericParams = GenGenericParams cenv eenvinner directTypars + let _directTypars, ilDirectWitnessParams, directWitnessInfos, _eenv = AddDirectTyparWitnessParams cenv eenvinner cloinfo m + ilDirectGenericParams, ilDirectWitnessParams, directWitnessInfos - if not (ilContractMethTyargs.Length = ilTyArgs.Length) then errorR(Error(FSComp.SR.ilIncorrectNumberOfTypeArguments(), m)) + if not (List.length ilDirectGenericParams = ilTyArgs.Length) then errorR(Error(FSComp.SR.ilIncorrectNumberOfTypeArguments(), m)) - // Local TyFunc are represented as a $contract type. they currently get stored in a value of type object // Recover result (value or reference types) via unbox_any. - CG.EmitInstrs cgbuf (pop 1) (Push [ilContractTy]) [I_unbox_any ilContractTy] + CG.EmitInstrs cgbuf (pop 1) (Push [ilCloTy]) [I_unbox_any ilCloTy] + let actualRetTy = applyTys g ty (tyargs, []) - let ilDirectInvokeMethSpec = mkILInstanceMethSpecInTy(ilContractTy, "DirectInvoke", [], ilContractFormalRetTy, ilTyArgs) + let ilDirectWitnessParamsTys = ilDirectWitnessParams |> List.map (fun p -> p.Type) + let ilDirectInvokeMethSpec = mkILInstanceMethSpecInTy(ilCloTy, "DirectInvoke", ilDirectWitnessParamsTys, cloinfo.ilCloFormalReturnTy, ilTyArgs) + + GenWitnessArgsFromWitnessInfos cenv cgbuf eenv m directWitnessInfos + let ilActualRetTy = GenType cenv.amap m eenv.tyenv actualRetTy CountCallFuncInstructions() - CG.EmitInstr cgbuf (pop 1) (Push [ilActualRetTy]) (mkNormalCallvirt ilDirectInvokeMethSpec) + CG.EmitInstr cgbuf (pop (1+ilDirectWitnessParamsTys.Length)) (Push [ilActualRetTy]) (mkNormalCall ilDirectInvokeMethSpec) actualRetTy - + /// Generate an indirect call, converting to an ILX callfunc instruction -and GenArgsAndIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel = +and GenCurriedArgsAndIndirectCall cenv cgbuf eenv (functy, tyargs, curriedArgs, m) sequel = - // Generate the arguments to the indirect call - GenExprs cenv cgbuf eenv args - GenIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel + // Generate the curried arguments to the indirect call + GenExprs cenv cgbuf eenv curriedArgs + GenIndirectCall cenv cgbuf eenv (functy, tyargs, curriedArgs, m) sequel /// Generate an indirect call, converting to an ILX callfunc instruction -and GenIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel = +and GenIndirectCall cenv cgbuf eenv (functy, tyargs, curriedArgs, m) sequel = let g = cenv.g // Fold in the new types into the environment as we generate the formal types. @@ -3318,18 +3872,15 @@ and GenIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel = // This does two phases: REVIEW: the code is too complex for what it's achieving and should be rewritten let formalRetTy, appBuilder = - List.fold - (fun (formalFuncTy, sofar) _ -> - let dty, rty = destFunTy g formalFuncTy - (rty, (fun acc -> sofar (Apps_app(GenType cenv.amap m feenv dty, acc))))) - (formalFuncTy, id) - args + ((formalFuncTy, id), curriedArgs) ||> List.fold (fun (formalFuncTy, appBuilder) _ -> + let dty, rty = destFunTy cenv.g formalFuncTy + (rty, (fun acc -> appBuilder (Apps_app(GenType cenv.amap m feenv dty, acc))))) let ilxRetApps = Apps_done (GenType cenv.amap m feenv formalRetTy) List.foldBack (fun tyarg acc -> Apps_tyapp(GenType cenv.amap m eenv.tyenv tyarg, acc)) tyargs (appBuilder ilxRetApps) - let actualRetTy = applyTys g functy (tyargs, args) + let actualRetTy = applyTys g functy (tyargs, curriedArgs) let ilActualRetTy = GenType cenv.amap m eenv.tyenv actualRetTy // Check if any byrefs are involved to make sure we don't tailcall @@ -3340,13 +3891,13 @@ and GenIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel = | Apps_app(arg, apps) -> IsILTypeByref arg || check apps | _ -> false check ilxClosureApps - + let isTailCall = CanTailcall(false, None, eenv.withinSEH, hasByrefArg, false, false, false, false, sequel) CountCallFuncInstructions() // Generate the code code an ILX callfunc operation let instrs = EraseClosures.mkCallFunc g.ilxPubCloEnv (fun ty -> cgbuf.AllocLocal([], ty, false) |> uint16) eenv.tyenv.Count isTailCall ilxClosureApps - CG.EmitInstrs cgbuf (pop (1+args.Length)) (Push [ilActualRetTy]) instrs + CG.EmitInstrs cgbuf (pop (1+curriedArgs.Length)) (Push [ilActualRetTy]) instrs // Done compiling indirect call... GenSequel cenv eenv.cloc cgbuf sequel @@ -3355,41 +3906,53 @@ and GenIndirectCall cenv cgbuf eenv (functy, tyargs, args, m) sequel = // Generate try expressions //-------------------------------------------------------------------------- -and GenTry cenv cgbuf eenv scopeMarks (e1, m, resty, spTry) = +and GenTry cenv cgbuf eenv scopeMarks (e1, m, resultTy, spTry) = + let g = cenv.g let sp = match spTry with - | SequencePointAtTry m -> CG.EmitSeqPoint cgbuf m; SPAlways - | SequencePointInBodyOfTry -> SPAlways - | NoSequencePointAtTry -> SPSuppress + | DebugPointAtTry.Yes m -> CG.EmitDebugPoint cgbuf m; SPAlways + | DebugPointAtTry.Body -> SPAlways + | DebugPointAtTry.No -> SPSuppress let stack, eenvinner = EmitSaveStack cenv cgbuf eenv m scopeMarks let startTryMark = CG.GenerateMark cgbuf "startTryMark" let endTryMark = CG.GenerateDelayMark cgbuf "endTryMark" let afterHandler = CG.GenerateDelayMark cgbuf "afterHandler" - let eenvinner = {eenvinner with withinSEH = true} - let ilResultTy = GenType cenv.amap m eenvinner.tyenv resty + let ilResultTyOpt = + if isUnitTy g resultTy then + None + else + Some (GenType cenv.amap m eenvinner.tyenv resultTy) + + let whereToSaveOpt, eenvinner = + match ilResultTyOpt with + | None -> None, eenvinner + | Some ilResultTy -> + // Ensure that we have an g.CompilerGlobalState + assert(cenv.g.CompilerGlobalState |> Option.isSome) + let whereToSave, _realloc, eenvinner = + AllocLocal cenv cgbuf eenvinner true (cenv.g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName ("tryres", m), ilResultTy, false) (startTryMark, endTryMark) + Some (whereToSave, ilResultTy), eenvinner - let whereToSave, _realloc, eenvinner = - // Ensure that we have an g.CompilerGlobalState - assert(cenv.g.CompilerGlobalState |> Option.isSome) - AllocLocal cenv cgbuf eenvinner true (cenv.g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName ("tryres", m), ilResultTy, false) (startTryMark, endTryMark) + let exitSequel = LeaveHandler (false, whereToSaveOpt, afterHandler, true) + let eenvinner = {eenvinner with withinSEH = true; exitSequel = exitSequel} - // Generate the body of the try. In the normal case (SequencePointAtTry) we generate a sequence point + // Generate the body of the try. In the normal case (DebugPointAtTry.Yes) we generate a debug point // both on the 'try' keyword and on the start of the expression in the 'try'. For inlined code and - // compiler generated 'try' blocks (i.e. NoSequencePointAtTry, used for the try/finally implicit - // in a 'use' or 'foreach'), we suppress the sequence point - GenExpr cenv cgbuf eenvinner sp e1 (LeaveHandler (false, whereToSave, afterHandler)) + // compiler generated 'try' blocks (i.e. DebugPointAtTry.No, used for the try/finally implicit + // in a 'use' or 'foreach'), we suppress the debug point + GenExpr cenv cgbuf eenvinner sp e1 exitSequel CG.SetMarkToHere cgbuf endTryMark let tryMarks = (startTryMark.CodeLabel, endTryMark.CodeLabel) - whereToSave, eenvinner, stack, tryMarks, afterHandler, ilResultTy + whereToSaveOpt, eenvinner, stack, tryMarks, afterHandler -and GenTryCatch cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, spWith) sequel = +and GenTryWith cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, spWith) sequel = let g = cenv.g // Save the stack - gross because IL flushes the stack at the exn. handler // note: eenvinner notes spill vars are live LocalScope "trystack" cgbuf (fun scopeMarks -> - let whereToSave, eenvinner, stack, tryMarks, afterHandler, ilResultTy = GenTry cenv cgbuf eenv scopeMarks (e1, m, resty, spTry) + let whereToSaveOpt, eenvinner, stack, tryMarks, afterHandler = GenTry cenv cgbuf eenv scopeMarks (e1, m, resty, spTry) // Now the filter and catch blocks @@ -3397,66 +3960,68 @@ and GenTryCatch cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, if cenv.opts.generateFilterBlocks then let startOfFilter = CG.GenerateMark cgbuf "startOfFilter" let afterFilter = CG.GenerateDelayMark cgbuf "afterFilter" - let (sequelOnBranches, afterJoin, stackAfterJoin, sequelAfterJoin) = GenJoinPoint cenv cgbuf "filter" eenv g.int_ty m EndFilter - begin - // We emit the sequence point for the 'with' keyword span on the start of the filter - // block. However the targets of the filter block pattern matching should not get any - // sequence points (they will be 'true'/'false' values indicating if the exception has been - // caught or not). - // - // The targets of the handler block DO get sequence points. Thus the expected behaviour - // for a try/with with a complex pattern is that we hit the "with" before the filter is run - // and then jump to the handler for the successful catch (or continue with exception handling - // if the filter fails) - match spWith with - | SequencePointAtWith m -> CG.EmitSeqPoint cgbuf m - | NoSequencePointAtWith -> () - - - CG.SetStack cgbuf [g.ilg.typ_Object] - let _, eenvinner = AllocLocalVal cenv cgbuf vf eenvinner None (startOfFilter, afterFilter) - CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) - - GenStoreVal cenv cgbuf eenvinner vf.Range vf - - // Why SPSuppress? Because we do not emit a sequence point at the start of the List.filter - we've already put one on - // the 'with' keyword above - GenExpr cenv cgbuf eenvinner SPSuppress ef sequelOnBranches - CG.SetMarkToHere cgbuf afterJoin - CG.SetStack cgbuf stackAfterJoin - GenSequel cenv eenv.cloc cgbuf sequelAfterJoin - end + let sequelOnBranches, afterJoin, stackAfterJoin, sequelAfterJoin = GenJoinPoint cenv cgbuf "filter" eenv g.int_ty m EndFilter + let eenvinner = { eenvinner with exitSequel = sequelOnBranches } + // We emit the debug point for the 'with' keyword span on the start of the filter + // block. However the targets of the filter block pattern matching should not get any + // debug points (they will be 'true'/'false' values indicating if the exception has been + // caught or not). + // + // The targets of the handler block DO get debug points. Thus the expected behaviour + // for a try/with with a complex pattern is that we hit the "with" before the filter is run + // and then jump to the handler for the successful catch (or continue with exception handling + // if the filter fails) + match spWith with + | DebugPointAtWith.Yes m -> CG.EmitDebugPoint cgbuf m + | DebugPointAtWith.No -> () + + + CG.SetStack cgbuf [g.ilg.typ_Object] + let _, eenvinner = AllocLocalVal cenv cgbuf vf eenvinner None (startOfFilter, afterFilter) + CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) + + GenStoreVal cenv cgbuf eenvinner vf.Range vf + + // Why SPSuppress? Because we do not emit a debug point at the start of the List.filter - we've already put one on + // the 'with' keyword above + GenExpr cenv cgbuf eenvinner SPSuppress ef sequelOnBranches + CG.SetMarkToHere cgbuf afterJoin + CG.SetStack cgbuf stackAfterJoin + GenSequel cenv eenv.cloc cgbuf sequelAfterJoin let endOfFilter = CG.GenerateMark cgbuf "endOfFilter" let filterMarks = (startOfFilter.CodeLabel, endOfFilter.CodeLabel) CG.SetMarkToHere cgbuf afterFilter let startOfHandler = CG.GenerateMark cgbuf "startOfHandler" - begin - CG.SetStack cgbuf [g.ilg.typ_Object] - let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler) - CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) - GenStoreVal cenv cgbuf eenvinner vh.Range vh - - GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave, afterHandler)) - end + + CG.SetStack cgbuf [g.ilg.typ_Object] + let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler) + CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) + GenStoreVal cenv cgbuf eenvinner vh.Range vh + + let exitSequel = LeaveHandler (false, whereToSaveOpt, afterHandler, true) + GenExpr cenv cgbuf eenvinner SPAlways eh exitSequel + let endOfHandler = CG.GenerateMark cgbuf "endOfHandler" let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel) ILExceptionClause.FilterCatch(filterMarks, handlerMarks) else let startOfHandler = CG.GenerateMark cgbuf "startOfHandler" - begin - match spWith with - | SequencePointAtWith m -> CG.EmitSeqPoint cgbuf m - | NoSequencePointAtWith -> () - CG.SetStack cgbuf [g.ilg.typ_Object] - let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler) - CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) + match spWith with + | DebugPointAtWith.Yes m -> CG.EmitDebugPoint cgbuf m + | DebugPointAtWith.No -> () + + CG.SetStack cgbuf [g.ilg.typ_Object] + let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler) + CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception) - GenStoreVal cenv cgbuf eenvinner m vh + GenStoreVal cenv cgbuf eenvinner m vh - GenExpr cenv cgbuf eenvinner SPAlways eh (LeaveHandler (false, whereToSave, afterHandler)) - end + let exitSequel = LeaveHandler (false, whereToSaveOpt, afterHandler, true) + let eenvinner = { eenvinner with exitSequel = exitSequel } + GenExpr cenv cgbuf eenvinner SPAlways eh exitSequel + let endOfHandler = CG.GenerateMark cgbuf "endOfHandler" let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel) ILExceptionClause.TypeCatch(g.ilg.typ_Object, handlerMarks) @@ -3470,11 +4035,15 @@ and GenTryCatch cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, cgbuf.EmitStartOfHiddenCode() - (* Restore the stack and load the result *) - EmitRestoreStack cgbuf stack (* RESTORE *) + // Restore the stack and load the result + EmitRestoreStack cgbuf stack - EmitGetLocal cgbuf ilResultTy whereToSave - GenSequel cenv eenv.cloc cgbuf sequel + match whereToSaveOpt with + | Some (whereToSave, ilResultTy) -> + EmitGetLocal cgbuf ilResultTy whereToSave + GenSequel cenv eenv.cloc cgbuf sequel + | None -> + GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel ) @@ -3483,18 +4052,20 @@ and GenTryFinally cenv cgbuf eenv (bodyExpr, handlerExpr, m, resty, spTry, spFin // note: eenvinner notes spill vars are live LocalScope "trystack" cgbuf (fun scopeMarks -> - let whereToSave, eenvinner, stack, tryMarks, afterHandler, ilResultTy = GenTry cenv cgbuf eenv scopeMarks (bodyExpr, m, resty, spTry) + let whereToSaveOpt, eenvinner, stack, tryMarks, afterHandler = GenTry cenv cgbuf eenv scopeMarks (bodyExpr, m, resty, spTry) // Now the catch/finally block let startOfHandler = CG.GenerateMark cgbuf "startOfHandler" CG.SetStack cgbuf [] - + let sp = match spFinally with - | SequencePointAtFinally m -> CG.EmitSeqPoint cgbuf m; SPAlways - | NoSequencePointAtFinally -> SPSuppress + | DebugPointAtFinally.Yes m -> CG.EmitDebugPoint cgbuf m; SPAlways + | DebugPointAtFinally.Body -> SPAlways + | DebugPointAtFinally.No -> SPSuppress - GenExpr cenv cgbuf eenvinner sp handlerExpr (LeaveHandler (true, whereToSave, afterHandler)) + let exitSequel = LeaveHandler (true, whereToSaveOpt, afterHandler, true) + GenExpr cenv cgbuf eenvinner sp handlerExpr exitSequel let endOfHandler = CG.GenerateMark cgbuf "endOfHandler" let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel) cgbuf.EmitExceptionClause @@ -3507,8 +4078,12 @@ and GenTryFinally cenv cgbuf eenv (bodyExpr, handlerExpr, m, resty, spTry, spFin // Restore the stack and load the result cgbuf.EmitStartOfHiddenCode() EmitRestoreStack cgbuf stack - EmitGetLocal cgbuf ilResultTy whereToSave - GenSequel cenv eenv.cloc cgbuf sequel + match whereToSaveOpt with + | Some (whereToSave, ilResultTy) -> + EmitGetLocal cgbuf ilResultTy whereToSave + GenSequel cenv eenv.cloc cgbuf sequel + | None -> + GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel ) //-------------------------------------------------------------------------- @@ -3539,15 +4114,17 @@ and GenForLoop cenv cgbuf eenv (spFor, v, e1, dir, e2, loopBody, m) sequel = if isFSharpStyle then // Ensure that we have an g.CompilerGlobalState assert(g.CompilerGlobalState |> Option.isSome) - let v, _realloc, eenvinner = AllocLocal cenv cgbuf eenvinner true (g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName ("endLoop", m), g.ilg.typ_Int32, false) (start, finish) + let vName = g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName ("endLoop", m) + let v, _realloc, eenvinner = AllocLocal cenv cgbuf eenvinner true (vName, g.ilg.typ_Int32, false) (start, finish) v, eenvinner else -1, eenvinner - let _, eenvinner = AllocLocalVal cenv cgbuf v eenvinner None (start, finish) (* note: eenvStack noted stack spill vars are live *) + let _, eenvinner = AllocLocalVal cenv cgbuf v eenvinner None (start, finish) + match spFor with - | SequencePointAtForLoop spStart -> CG.EmitSeqPoint cgbuf spStart - | NoSequencePointAtForLoop -> () + | DebugPointAtFor.Yes spStart -> CG.EmitDebugPoint cgbuf spStart + | DebugPointAtFor.No -> () GenExpr cenv cgbuf eenv SPSuppress e1 Continue GenStoreVal cenv cgbuf eenvinner m v @@ -3555,7 +4132,7 @@ and GenForLoop cenv cgbuf eenv (spFor, v, e1, dir, e2, loopBody, m) sequel = GenExpr cenv cgbuf eenvinner SPSuppress e2 Continue EmitSetLocal cgbuf finishIdx EmitGetLocal cgbuf g.ilg.typ_Int32 finishIdx - GenGetLocalVal cenv cgbuf eenvinner e2.Range v None + GenGetLocalVal cenv cgbuf eenvinner e2.Range v None CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp ((if isUp then BI_blt else BI_bgt), finish.CodeLabel)) else @@ -3579,8 +4156,8 @@ and GenForLoop cenv cgbuf eenv (spFor, v, e1, dir, e2, loopBody, m) sequel = // FSharpForLoopDown: if v <> e2 - 1 then goto .inner // CSharpStyle: if v < e2 then goto .inner match spFor with - | SequencePointAtForLoop spStart -> CG.EmitSeqPoint cgbuf spStart - | NoSequencePointAtForLoop -> () //CG.EmitSeqPoint cgbuf e2.Range + | DebugPointAtFor.Yes spStart -> CG.EmitDebugPoint cgbuf spStart + | DebugPointAtFor.No -> () //CG.EmitDebugPoint cgbuf e2.Range GenGetLocalVal cenv cgbuf eenvinner e2.Range v None @@ -3606,22 +4183,23 @@ and GenForLoop cenv cgbuf eenv (spFor, v, e1, dir, e2, loopBody, m) sequel = // Generate while-loop //-------------------------------------------------------------------------- -and GenWhileLoop cenv cgbuf eenv (spWhile, e1, e2, m) sequel = +and GenWhileLoop cenv cgbuf eenv (spWhile, condExpr, bodyExpr, m) sequel = let eenv = SetIsInLoop true eenv let finish = CG.GenerateDelayMark cgbuf "while_finish" let startTest = CG.GenerateMark cgbuf "startTest" - match spWhile with - | SequencePointAtWhileLoop spStart -> CG.EmitSeqPoint cgbuf spStart - | NoSequencePointAtWhileLoop -> () + let spCondition = + match spWhile with + | DebugPointAtWhile.Yes spStart -> CG.EmitDebugPoint cgbuf spStart; SPSuppress + | DebugPointAtWhile.No -> SPSuppress - // SEQUENCE POINTS: Emit a sequence point to cover all of 'while e do' - GenExpr cenv cgbuf eenv SPSuppress e1 (CmpThenBrOrContinue (pop 1, [ I_brcmp(BI_brfalse, finish.CodeLabel) ])) + // SEQUENCE POINTS: Emit a debug point to cover all of 'while e do' + GenExpr cenv cgbuf eenv spCondition condExpr (CmpThenBrOrContinue (pop 1, [ I_brcmp(BI_brfalse, finish.CodeLabel) ])) - GenExpr cenv cgbuf eenv SPAlways e2 (DiscardThen (Br startTest)) + GenExpr cenv cgbuf eenv SPAlways bodyExpr (DiscardThen (Br startTest)) CG.SetMarkToHere cgbuf finish - // SEQUENCE POINTS: Emit a sequence point to cover 'done' if present + // SEQUENCE POINTS: Emit a debug point to cover 'done' if present GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel //-------------------------------------------------------------------------- @@ -3648,7 +4226,7 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = {fspec with DeclaringType= let ty = fspec.DeclaringType let tspec = ty.TypeSpec - mkILTy ty.Boxity (mkILTySpec(tspec.TypeRef, ilTyArgs)) } + mkILTy ty.Boxity (mkILTySpec(tspec.TypeRef, ilTyArgs)) } match i, ilTyArgs with | I_unbox_any (ILType.TypeVar _), [tyarg] -> I_unbox_any tyarg | I_box (ILType.TypeVar _), [tyarg] -> I_box tyarg @@ -3662,9 +4240,8 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = | I_stobj (a, b, ILType.TypeVar _), [tyarg] -> I_stobj (a, b, tyarg) | I_ldtoken (ILToken.ILType (ILType.TypeVar _)), [tyarg] -> I_ldtoken (ILToken.ILType tyarg) | I_sizeof (ILType.TypeVar _), [tyarg] -> I_sizeof tyarg - // currently unused, added for forward compat, see https://visualfsharp.codeplex.com/SourceControl/network/forks/jackpappas/fsharpcontrib/contribution/7134 - | I_cpobj (ILType.TypeVar _), [tyarg] -> I_cpobj tyarg - | I_initobj (ILType.TypeVar _), [tyarg] -> I_initobj tyarg + | I_cpobj (ILType.TypeVar _), [tyarg] -> I_cpobj tyarg + | I_initobj (ILType.TypeVar _), [tyarg] -> I_initobj tyarg | I_ldfld (al, vol, fspec), _ -> I_ldfld (al, vol, modFieldSpec fspec) | I_ldflda fspec, _ -> I_ldflda (modFieldSpec fspec) | I_stfld (al, vol, fspec), _ -> I_stfld (al, vol, modFieldSpec fspec) @@ -3694,7 +4271,7 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = // For these we can just generate the argument and change the test (from a brfalse to a brtrue and vice versa) | ([ AI_ceq ], [arg1; Expr.Const ((Const.Bool false | Const.SByte 0y| Const.Int16 0s | Const.Int32 0 | Const.Int64 0L | Const.Byte 0uy| Const.UInt16 0us | Const.UInt32 0u | Const.UInt64 0UL), _, _) ], - CmpThenBrOrContinue(1, [I_brcmp (((BI_brfalse | BI_brtrue) as bi), label1) ]), + CmpThenBrOrContinue(1, [I_brcmp (BI_brfalse | BI_brtrue as bi, label1) ]), _) -> let bi = match bi with BI_brtrue -> BI_brfalse | _ -> BI_brtrue @@ -3725,14 +4302,14 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = CG.EmitInstr cgbuf (pop 1) Push0 I_throw GenSequelEndScopes cgbuf sequel | _ -> - let after1 = CG.GenerateDelayMark cgbuf ("fake_join") - let after2 = CG.GenerateDelayMark cgbuf ("fake_join") - let after3 = CG.GenerateDelayMark cgbuf ("fake_join") + let after1 = CG.GenerateDelayMark cgbuf "fake_join" + let after2 = CG.GenerateDelayMark cgbuf "fake_join" + let after3 = CG.GenerateDelayMark cgbuf "fake_join" CG.EmitInstrs cgbuf (pop 0) Push0 [mkLdcInt32 0; I_brcmp (BI_brfalse, after2.CodeLabel) ] CG.SetMarkToHere cgbuf after1 CG.EmitInstrs cgbuf (pop 0) (Push [ilRetTy]) [AI_ldnull; I_unbox_any ilRetTy; I_br after3.CodeLabel ] - + CG.SetMarkToHere cgbuf after2 GenExpr cenv cgbuf eenv SPSuppress arg1 Continue CG.EmitInstr cgbuf (pop 1) Push0 I_throw @@ -3758,9 +4335,9 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_ble_un, label1)) | [ AI_ceq ], CmpThenBrOrContinue(1, [ I_brcmp (BI_brfalse, label1) ]) when not (anyfpType (tyOfExpr g args.Head)) -> CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_bne_un, label1)) - + // THESE ARE VALID ON FP w.r.t. NaN - + | [ AI_clt ], CmpThenBrOrContinue(1, [ I_brcmp (BI_brtrue, label1) ]) -> CG.EmitInstr cgbuf (pop 2) Push0 (I_brcmp(BI_blt, label1)) | [ AI_cgt ], CmpThenBrOrContinue(1, [ I_brcmp (BI_brtrue, label1) ]) -> @@ -3785,42 +4362,44 @@ and GenAsmCode cenv cgbuf eenv (il, tyargs, args, returnTys, m) sequel = // Generate expression quotations //-------------------------------------------------------------------------- -and GenQuotation cenv cgbuf eenv (ast, conv, m, ety) sequel = +and GenQuotation cenv cgbuf eenv (ast, qdataCell, m, ety) sequel = let g = cenv.g - let referencedTypeDefs, spliceTypes, spliceArgExprs, astSpec = - match !conv with - | Some res -> res + let suppressWitnesses = eenv.suppressWitnesses + let referencedTypeDefs, typeSplices, exprSplices, astSpec = + match qdataCell.Value with + | Some (data1, data2) -> + if suppressWitnesses then data1 else data2 + | None -> try - let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) - let astSpec = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast - let referencedTypeDefs, spliceTypes, spliceArgExprs = qscope.Close() - referencedTypeDefs, List.map fst spliceTypes, List.map fst spliceArgExprs, astSpec + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, cenv.tcVal, QuotationTranslator.IsReflectedDefinition.No) + let astSpec = QuotationTranslator.ConvExprPublic qscope suppressWitnesses ast + let referencedTypeDefs, typeSplices, exprSplices = qscope.Close() + referencedTypeDefs, List.map fst typeSplices, List.map fst exprSplices, astSpec with QuotationTranslator.InvalidQuotedTerm e -> error e let astSerializedBytes = QuotationPickler.pickle astSpec let someTypeInModuleExpr = mkTypeOfExpr cenv m eenv.someTypeInThisAssembly - let rawTy = mkRawQuotedExprTy g - let spliceTypeExprs = List.map (GenType cenv.amap m eenv.tyenv >> (mkTypeOfExpr cenv m)) spliceTypes + let rawTy = mkRawQuotedExprTy g + let typeSpliceExprs = List.map (GenType cenv.amap m eenv.tyenv >> (mkTypeOfExpr cenv m)) typeSplices let bytesExpr = Expr.Op (TOp.Bytes astSerializedBytes, [], [], m) let deserializeExpr = - match QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat g with - | QuotationTranslator.QuotationSerializationFormat.FSharp_40_Plus -> + let qf = QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat g + if qf.SupportsDeserializeEx then let referencedTypeDefExprs = List.map (mkILNonGenericBoxedTy >> mkTypeOfExpr cenv m) referencedTypeDefs let referencedTypeDefsExpr = mkArray (g.system_Type_ty, referencedTypeDefExprs, m) - let spliceTypesExpr = mkArray (g.system_Type_ty, spliceTypeExprs, m) - let spliceArgsExpr = mkArray (rawTy, spliceArgExprs, m) - mkCallDeserializeQuotationFSharp40Plus g m someTypeInModuleExpr referencedTypeDefsExpr spliceTypesExpr spliceArgsExpr bytesExpr - - | QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus -> + let typeSplicesExpr = mkArray (g.system_Type_ty, typeSpliceExprs, m) + let spliceArgsExpr = mkArray (rawTy, exprSplices, m) + mkCallDeserializeQuotationFSharp40Plus g m someTypeInModuleExpr referencedTypeDefsExpr typeSplicesExpr spliceArgsExpr bytesExpr + else let mkList ty els = List.foldBack (mkCons g ty) els (mkNil g m ty) - let spliceTypesExpr = mkList g.system_Type_ty spliceTypeExprs - let spliceArgsExpr = mkList rawTy spliceArgExprs - mkCallDeserializeQuotationFSharp20Plus g m someTypeInModuleExpr spliceTypesExpr spliceArgsExpr bytesExpr + let typeSplicesExpr = mkList g.system_Type_ty typeSpliceExprs + let spliceArgsExpr = mkList rawTy exprSplices + mkCallDeserializeQuotationFSharp20Plus g m someTypeInModuleExpr typeSplicesExpr spliceArgsExpr bytesExpr let afterCastExpr = // Detect a typed quotation and insert the cast if needed. The cast should not fail but does @@ -3843,7 +4422,8 @@ and GenILCall cenv cgbuf eenv (virt, valu, newobj, valUseFlags, isDllImport, ilM let boxity = (if valu then AsValue else AsObject) let mustGenerateUnitAfterCall = isNil returnTys let makesNoCriticalTailcalls = (newobj || not virt) // Don't tailcall for 'newobj', or 'call' to IL code - let tail = CanTailcall(valu, ccallInfo, eenv.withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, false, makesNoCriticalTailcalls, sequel) + let hasStructObjArg = valu && ilMethRef.CallingConv.IsInstance + let tail = CanTailcall(hasStructObjArg, ccallInfo, eenv.withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, false, makesNoCriticalTailcalls, sequel) let ilEnclArgTys = GenTypeArgs cenv.amap m eenv.tyenv enclArgTys let ilMethArgTys = GenTypeArgs cenv.amap m eenv.tyenv methArgTys @@ -3886,9 +4466,28 @@ and MakeNotSupportedExnExpr cenv eenv (argExpr, m) = let mref = mkILCtorMethSpecForTy(ilty, [g.ilg.typ_String]).MethodRef Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [ety]), [], [argExpr], m) -and GenTraitCall cenv cgbuf eenv (traitInfo, argExprs, m) expr sequel = +and GenTraitCall (cenv: cenv) cgbuf eenv (traitInfo: TraitConstraintInfo, argExprs, m) expr sequel = let g = cenv.g - let minfoOpt = CommitOperationResult (ConstraintSolver.CodegenWitnessThatTypeSupportsTraitConstraint cenv.TcVal g cenv.amap m traitInfo argExprs) + let generateWitnesses = ComputeGenerateWitnesses g eenv + let witness = + if generateWitnesses then + TryStorageForWitness g eenv traitInfo.TraitKey + else + None + + match witness with + | Some storage -> + + let ty = GenWitnessTy g traitInfo.TraitKey + let argExprs = if argExprs.Length = 0 then [ mkUnit g m ] else argExprs + GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m eenv.tyenv ty) storage (Some([], argExprs, m, sequel)) + + | None -> + + // If witnesses are available, we should now always find trait witnesses in scope + assert not generateWitnesses + + let minfoOpt = CommitOperationResult (ConstraintSolver.CodegenWitnessExprForTraitConstraint cenv.tcVal g cenv.amap m traitInfo argExprs) match minfoOpt with | None -> let exnArg = mkString g m (FSComp.SR.ilDynamicInvocationNotSupported(traitInfo.MemberName)) @@ -3896,7 +4495,7 @@ and GenTraitCall cenv cgbuf eenv (traitInfo, argExprs, m) expr sequel = let replacementExpr = mkThrow m (tyOfExpr g expr) exnExpr GenExpr cenv cgbuf eenv SPSuppress replacementExpr sequel | Some expr -> - let expr = cenv.optimizeDuringCodeGen expr + let expr = cenv.optimizeDuringCodeGen false expr GenExpr cenv cgbuf eenv SPSuppress expr sequel //-------------------------------------------------------------------------- @@ -3921,17 +4520,17 @@ and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel = | Arg idx -> CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 idx) ] - | StaticField (fspec, _vref, hasLiteralAttr, _ilTyForProperty, _, ilTy, _, _, _) -> + | StaticPropertyWithField (fspec, _vref, hasLiteralAttr, _ilTyForProperty, _, ilTy, _, _, _) -> if hasLiteralAttr then errorR(Error(FSComp.SR.ilAddressOfLiteralFieldIsInvalid(), m)) let ilTy = if ilTy.IsNominal && ilTy.Boxity = ILBoxity.AsValue then ILType.Byref ilTy else ilTy EmitGetStaticFieldAddr cgbuf ilTy fspec - | Env (_, _, ilField, _) -> + | Env (_, ilField, _) -> CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ mkLdarg0; mkNormalLdflda ilField ] | Local (_, _, Some _) | StaticProperty _ | Method _ | Env _ | Null -> errorR(Error(FSComp.SR.ilAddressOfValueHereIsInvalid(v.DisplayName), m)) - CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 669 (* random value for post-hoc diagnostic analysis on generated tree *) ) ] + CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 669 (* random value for post-hoc diagnostic analysis on generated tree *) ) ] GenSequel cenv eenv.cloc cgbuf sequel @@ -3954,7 +4553,7 @@ and GenDefaultValue cenv cgbuf eenv (ty, m) = if isRefTy g ty then CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) AI_ldnull else - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when (tyconRefEq g g.system_SByte_tcref tcref || tyconRefEq g g.system_Int16_tcref tcref || tyconRefEq g g.system_Int32_tcref tcref || @@ -3981,10 +4580,9 @@ and GenDefaultValue cenv cgbuf eenv (ty, m) = // "initobj" (Generated by EmitInitLocal) doesn't work on byref types // But ilzero(&ty) only gets generated in the built-in get-address function so // we can just rely on zeroinit of all IL locals. - if realloc then - match ilTy with - | ILType.Byref _ -> () - | _ -> EmitInitLocal cgbuf ilTy locIdx + if (realloc || not eenv.initLocals) && not (IsILTypeByref ilTy) then + EmitInitLocal cgbuf ilTy locIdx + EmitGetLocal cgbuf ilTy locIdx ) @@ -4071,17 +4669,26 @@ and GenFormalSlotsig m cenv eenv (TSlotSig(_, ty, ctps, mtps, paraml, returnTy)) let ilTy = GenType cenv.amap m eenv.tyenv ty let eenvForSlotSig = EnvForTypars (ctps @ mtps) eenv let ilParams = paraml |> List.map (GenSlotParam m cenv eenvForSlotSig) - let ilRetTy = GenReturnType cenv.amap m eenvForSlotSig.tyenv returnTy - let ilRet = mkILReturn ilRetTy - let ilRet = - match returnTy with - | None -> ilRet - | Some ty -> - match GenReadOnlyAttributeIfNecessary cenv.g ty with - | Some attr -> ilRet.WithCustomAttrs (mkILCustomAttrs (ilRet.CustomAttrs.AsList @ [attr])) - | None -> ilRet + let ilRet = GenFormalReturnType m cenv eenvForSlotSig returnTy ilTy, ilParams, ilRet +and GenOverridesSpec cenv eenv slotsig m = + let (TSlotSig(nameOfOverridenMethod, _, _, methodTypars, _, _)) = slotsig + let ilOverrideTy, ilOverrideParams, ilOverrideRet = GenFormalSlotsig m cenv eenv slotsig + let ilOverrideTyRef = ilOverrideTy.TypeRef + let ilOverrideMethRef = mkILMethRef(ilOverrideTyRef, ILCallingConv.Instance, nameOfOverridenMethod, List.length (DropErasedTypars methodTypars), typesOfILParams ilOverrideParams, ilOverrideRet.Type) + OverridesSpec(ilOverrideMethRef, ilOverrideTy) + +and GenFormalReturnType m cenv eenvFormal returnTy : ILReturn = + let ilRetTy = GenReturnType cenv.amap m eenvFormal.tyenv returnTy + let ilRet = mkILReturn ilRetTy + match returnTy with + | None -> ilRet + | Some ty -> + match GenReadOnlyAttributeIfNecessary cenv.g ty with + | Some attr -> ilRet.WithCustomAttrs (mkILCustomAttrs (ilRet.CustomAttrs.AsList @ [attr])) + | None -> ilRet + and instSlotParam inst (TSlotParam(nm, ty, inFlag, fl2, fl3, attrs)) = TSlotParam(nm, instType inst ty, inFlag, fl2, fl3, attrs) @@ -4102,23 +4709,23 @@ and GenActualSlotsig m cenv eenv (TSlotSig(_, ty, ctps, mtps, ilSlotParams, ilSl and GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) = let (TSlotSig(nameOfOverridenMethod, enclTypOfOverridenMethod, _, _, _, _)) = slotsig - if useMethodImpl then qualifiedMangledNameOfTyconRef (tcrefOfAppTy cenv.g enclTypOfOverridenMethod) nameOfOverridenMethod - else nameOfOverridenMethod + if useMethodImpl then + qualifiedInterfaceImplementationName cenv.g enclTypOfOverridenMethod nameOfOverridenMethod + else + nameOfOverridenMethod -and GenMethodImpl cenv eenv (useMethodImpl, (TSlotSig(nameOfOverridenMethod, _, _, _, _, _) as slotsig)) m = - let ilOverrideTy, ilOverrideParams, ilOverrideRet = GenFormalSlotsig m cenv eenv slotsig +and GenMethodImpl cenv eenv (useMethodImpl, slotsig) m = + let ilOverridesSpec = GenOverridesSpec cenv eenv slotsig m let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) nameOfOverridingMethod, (fun (ilTyForOverriding, methTyparsOfOverridingMethod) -> - let ilOverrideTyRef = ilOverrideTy.TypeRef - let ilOverrideMethRef = mkILMethRef(ilOverrideTyRef, ILCallingConv.Instance, nameOfOverridenMethod, List.length (DropErasedTypars methTyparsOfOverridingMethod), typesOfILParams ilOverrideParams, ilOverrideRet.Type) let eenvForOverrideBy = AddTyparsToEnv methTyparsOfOverridingMethod eenv let ilParamsOfOverridingMethod, ilReturnOfOverridingMethod = GenActualSlotsig m cenv eenvForOverrideBy slotsig methTyparsOfOverridingMethod [] let ilOverrideMethGenericParams = GenGenericParams cenv eenvForOverrideBy methTyparsOfOverridingMethod let ilOverrideMethGenericArgs = mkILFormalGenericArgs 0 ilOverrideMethGenericParams let ilOverrideBy = mkILInstanceMethSpecInTy(ilTyForOverriding, nameOfOverridingMethod, typesOfILParams ilParamsOfOverridingMethod, ilReturnOfOverridingMethod.Type, ilOverrideMethGenericArgs) - { Overrides = OverridesSpec(ilOverrideMethRef, ilOverrideTy) + { Overrides = ilOverridesSpec OverrideBy = ilOverrideBy }) and bindBaseOrThisVarOpt cenv eenv baseValOpt = @@ -4138,26 +4745,35 @@ and fixupMethodImplFlags (mdef: ILMethodDef) = and GenObjectMethod cenv eenvinner (cgbuf: CodeGenBuffer) useMethodImpl tmethod = let g = cenv.g - // Check if we're compiling the property as a .NET event - let (TObjExprMethod(slotsig, attribs, methTyparsOfOverridingMethod, methodParams, methodBodyExpr, m)) = tmethod + let (TObjExprMethod(slotsig, attribs, methTyparsOfOverridingMethod, methParams, methBodyExpr, m)) = tmethod let (TSlotSig(nameOfOverridenMethod, _, _, _, _, _)) = slotsig + + // Check if we're compiling the property as a .NET event if CompileAsEvent g attribs then [] else let eenvUnderTypars = AddTyparsToEnv methTyparsOfOverridingMethod eenvinner - let methodParams = List.concat methodParams - let methodParamsNonSelf = match methodParams with [] -> [] | _ :: t -> t // drop the 'this' arg when computing better argument names for IL parameters + let methParams = List.concat methParams + + // drop the 'this' arg when computing better argument names for IL parameters + let selfArgOpt, methParamsNonSelf = + match methParams with + | [] -> None, [] + | h :: t -> Some h, t + let ilParamsOfOverridingMethod, ilReturnOfOverridingMethod = - GenActualSlotsig m cenv eenvUnderTypars slotsig methTyparsOfOverridingMethod methodParamsNonSelf + GenActualSlotsig m cenv eenvUnderTypars slotsig methTyparsOfOverridingMethod methParamsNonSelf let ilAttribs = GenAttrs cenv eenvinner attribs - // Args are stored starting at #1 - let eenvForMeth = AddStorageForLocalVals g (methodParams |> List.mapi (fun i v -> (v, Arg i))) eenvUnderTypars + // Args are stored starting at #0, the args include the self parameter + let eenvForMeth = AddStorageForLocalVals g (methParams |> List.mapi (fun i v -> (v, Arg i))) eenvUnderTypars + let sequel = (if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return) - let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], nameOfOverridenMethod, eenvForMeth, 0, methodBodyExpr, sequel) - let nameOfOverridingMethod, methodImplGenerator = GenMethodImpl cenv eenvinner (useMethodImpl, slotsig) methodBodyExpr.Range + let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], nameOfOverridenMethod, eenvForMeth, 0, selfArgOpt, methBodyExpr, sequel) + + let nameOfOverridingMethod, methodImplGenerator = GenMethodImpl cenv eenvinner (useMethodImpl, slotsig) methBodyExpr.Range let mdef = mkILGenericVirtualMethod @@ -4166,43 +4782,241 @@ and GenObjectMethod cenv eenvinner (cgbuf: CodeGenBuffer) useMethodImpl tmethod GenGenericParams cenv eenvUnderTypars methTyparsOfOverridingMethod, ilParamsOfOverridingMethod, ilReturnOfOverridingMethod, - MethodBody.IL ilMethodBody) + MethodBody.IL (lazy ilMethodBody)) // fixup attributes to generate a method impl let mdef = if useMethodImpl then fixupMethodImplFlags mdef else mdef let mdef = fixupVirtualSlotFlags mdef let mdef = mdef.With(customAttrs = mkILCustomAttrs ilAttribs) [(useMethodImpl, methodImplGenerator, methTyparsOfOverridingMethod), mdef] -and GenObjectExpr cenv cgbuf eenvouter expr (baseType, baseValOpt, basecall, overrides, interfaceImpls, m) sequel = +and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel = + + let (LoweredStateMachine + (templateStructTy, dataTy, stateVars, thisVars, + (moveNextThisVar, moveNextBody), + (setStateMachineThisVar, setStateMachineStateVar, setStateMachineBody), + (afterCodeThisVar, afterCodeBody))) = res + let m = moveNextBody.Range let g = cenv.g - let cloinfo, _, eenvinner = GetIlxClosureInfo cenv m false None eenvouter expr + let amap = cenv.amap + + let stateVarsSet = stateVars |> List.map (fun vref -> vref.Deref) |> Zset.ofList valOrder + + // Find the free variables of the closure, to make them further fields of the object. + let cloinfo, _, eenvinner = + // State vars are only populated for state machine objects + // + // Like in GenSequenceExpression we pretend any stateVars and the stateMachineVar are bound in the outer environment. This prevents the being + // considered true free variables that need to be passed to the constructor. + // + // Note, the 'let' bindings for the stateVars have already been transformed to 'set' expressions, and thus the stateVars are now + // free variables of the expression. + let eenvouter = eenvouter |> AddStorageForLocalVals g (stateVars |> List.map (fun v -> v.Deref, Local(0, false, None))) + let eenvouter = eenvouter |> AddStorageForLocalVals g (thisVars |> List.map (fun v -> v.Deref, Local(0, false, None))) + let eenvouter = eenvouter |> AddStorageForLocalVals g [ (moveNextThisVar, Local(0, false, None)) ] + GetIlxClosureInfo cenv m ILBoxity.AsValue false false (mkLocalValRef moveNextThisVar :: thisVars) eenvouter moveNextBody - let cloAttribs = cloinfo.cloAttribs let cloFreeVars = cloinfo.cloFreeVars + + let ilCloFreeVars = cloinfo.ilCloAllFreeVars + let ilCloGenericFormals = cloinfo.cloILGenericParams + let ilCloGenericActuals = cloinfo.cloSpec.GenericArgs + let ilCloTypeRef = cloinfo.cloSpec.TypeRef + let ilCloTy = mkILValueTy ilCloTypeRef ilCloGenericActuals + + // The closure implements what ever interfaces the template implements. + let interfaceTys = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m templateStructTy + + let ilInterfaceTys = List.map (GenType cenv.amap m eenvinner.tyenv) interfaceTys + + let super = g.iltyp_ValueType + + let templateTyconRef, templateTypeArgs = destAppTy g templateStructTy + let templateTypeInst = mkTyconRefInst templateTyconRef templateTypeArgs + let eenvinner = AddTemplateReplacement eenvinner (templateTyconRef, ilCloTy, templateTypeInst) + + let infoReader = InfoReader.InfoReader(g, cenv.amap) + + // We codegen the IResumableStateMachine implementation for each generated struct type + let getResumptionPointThisVar, getResumptionPointBody = + let fieldName = "ResumptionPoint" + let thisVar = moveNextThisVar // reusing the this var from the MoveNext implementation + let finfo = + match infoReader.GetRecordOrClassFieldsOfType(Some fieldName, AccessibilityLogic.AccessorDomain.AccessibleFromSomewhere, m, templateStructTy) with + | [finfo] -> finfo + | _ -> error(InternalError(sprintf "expected class field %s not found" fieldName, m)) + thisVar, mkRecdFieldGetViaExprAddr (exprForVal m thisVar, finfo.RecdFieldRef, finfo.TypeInst, m) + + let (getDataThisVar, getDataBody), (setDataThisVar, setDataValueVar, setDataBody) = + let fieldName = "Data" + let thisVar = moveNextThisVar // reusing the this var from the MoveNext implementation + let setDataValueVar, setDataValueExpr = mkCompGenLocal m "value" dataTy + let finfo = + match infoReader.GetRecordOrClassFieldsOfType(Some fieldName, AccessibilityLogic.AccessorDomain.AccessibleFromSomewhere, m, templateStructTy) with + | [finfo] -> finfo + | _ -> error(InternalError(sprintf "expected class field %s not found" fieldName, m)) + (thisVar, mkRecdFieldGetViaExprAddr (exprForVal m thisVar, finfo.RecdFieldRef, finfo.TypeInst, m)), + (thisVar, setDataValueVar, mkRecdFieldSetViaExprAddr (exprForVal m thisVar, finfo.RecdFieldRef, finfo.TypeInst, setDataValueExpr, m)) + + let methods = + [ ((mkLocalValRef moveNextThisVar::thisVars), [], g.mk_IAsyncStateMachine_ty, "MoveNext", moveNextBody); + ([mkLocalValRef setStateMachineThisVar], [setStateMachineStateVar], g.mk_IAsyncStateMachine_ty, "SetStateMachine", setStateMachineBody); + ([mkLocalValRef getResumptionPointThisVar], [], g.mk_IResumableStateMachine_ty dataTy, "get_ResumptionPoint", getResumptionPointBody); + ([mkLocalValRef getDataThisVar], [], g.mk_IResumableStateMachine_ty dataTy, "get_Data", getDataBody); + ([mkLocalValRef setDataThisVar], [setDataValueVar], g.mk_IResumableStateMachine_ty dataTy, "set_Data", setDataBody); ] + + let mdefs = + [ for thisVals, argVals, interfaceTy, imethName, bodyR in methods do + let eenvinner = eenvinner |> AddStorageForLocalVals g [(moveNextThisVar, Arg 0) ] + let m = bodyR.Range + let implementedMeth = + match InfoReader.TryFindIntrinsicMethInfo infoReader m AccessibilityLogic.AccessorDomain.AccessibleFromSomewhere imethName interfaceTy with + | [meth] when meth.IsInstance -> meth + | _ -> error(InternalError(sprintf "expected method %s not found" imethName, m)) + let argTys = implementedMeth.GetParamTypes(cenv.amap, m, []) |> List.concat + let retTy = implementedMeth.GetCompiledReturnTy(cenv.amap, m, []) + let ilRetTy = GenReturnType cenv.amap m eenvinner.tyenv retTy + let ilArgTys = argTys |> GenTypes cenv.amap m eenvinner.tyenv + if ilArgTys.Length <> argVals.Length then + error(InternalError(sprintf "expected method arg count of %d, got %d for method %s" argVals.Length ilArgTys.Length imethName, m)) + let eenvinner = eenvinner |> AddStorageForLocalVals g (thisVals |> List.map (fun v -> (v.Deref, Arg 0))) + let eenvinner = eenvinner |> AddStorageForLocalVals g (argVals |> List.mapi (fun i v -> v, Arg (i+1))) + let sequel = if retTy.IsNone then discardAndReturnVoid else Return + let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], imethName, eenvinner, 1+argVals.Length, None, bodyR, sequel) + let ilParams = (ilArgTys,argVals) ||> List.map2 (fun ty v -> mkILParamNamed(v.LogicalName, ty)) + mkILNonGenericVirtualMethod(imethName, ILMemberAccess.Public, ilParams, mkILReturn ilRetTy, MethodBody.IL (notlazy ilCode)) ] + + let mimpls = + [ for (_thisVals, _argVals, interfaceTy, imethName, bodyR), mdef in (List.zip methods mdefs) do + let m = bodyR.Range + let implementedMeth = + match InfoReader.TryFindIntrinsicMethInfo infoReader m AccessibilityLogic.AccessorDomain.AccessibleFromSomewhere imethName interfaceTy with + | [meth] when meth.IsInstance -> meth + | _ -> error(InternalError(sprintf "expected method %s not found" imethName, m)) + + let slotsig = implementedMeth.GetSlotSig(amap, m) + let ilOverridesSpec = GenOverridesSpec cenv eenvinner slotsig m + let ilOverrideBy = mkILInstanceMethSpecInTy(ilCloTy, imethName, mdef.ParameterTypes, mdef.Return.Type, []) + { Overrides = ilOverridesSpec + OverrideBy = ilOverrideBy } ] + + let fdefs = + [ // Fields copied from the template struct + for templateFld in infoReader.GetRecordOrClassFieldsOfType (None, AccessibilityLogic.AccessorDomain.AccessibleFromSomewhere, m, templateStructTy) do + // Suppress the "ResumptionDynamicInfo" from generated state machines + if templateFld.LogicalName <> "ResumptionDynamicInfo" then + let access = ComputeMemberAccess false + let fty = GenType cenv.amap m eenvinner.tyenv templateFld.FieldType + let fdef = + ILFieldDef(name = templateFld.LogicalName, fieldType = fty, attributes = enum 0, data = None, literalValue = None, offset = None, marshal = None, customAttrs = mkILCustomAttrs []) + .WithAccess(access) + .WithStatic(false) + yield fdef + + // Fields for captured variables + for ilCloFreeVar in ilCloFreeVars do + let access = ComputeMemberAccess false + let fdef = + ILFieldDef(name = ilCloFreeVar.fvName, fieldType = ilCloFreeVar.fvType, attributes = enum 0, + data = None, literalValue = None, offset = None, marshal = None, customAttrs = mkILCustomAttrs []) + .WithAccess(access) + .WithStatic(false) + yield fdef ] + + let cloTypeDef = + ILTypeDef(name = ilCloTypeRef.Name, + layout = ILTypeDefLayout.Auto, + attributes = enum 0, + genericParams = ilCloGenericFormals, + customAttrs = mkILCustomAttrs([ g.CompilerGeneratedAttribute; mkCompilationMappingAttr g (int SourceConstructFlags.Closure) ]), + fields = mkILFields fdefs, + events= emptyILEvents, + properties = emptyILProperties, + methods= mkILMethods mdefs, + methodImpls = mkILMethodImpls mimpls, + nestedTypes = emptyILTypeDefs, + implements = ilInterfaceTys, + extends = Some super, + securityDecls = emptyILSecurityDecls) + .WithSealed(true) + .WithSpecialName(true) + .WithAccess(ComputeTypeAccess ilCloTypeRef true) + .WithLayout(ILTypeDefLayout.Auto) + .WithEncoding(ILDefaultPInvokeEncoding.Auto) + .WithInitSemantics(ILTypeInit.BeforeField) + + cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None) + + CountClosure() + LocalScope "machine" cgbuf (fun scopeMarks -> + let ilMachineAddrTy = ILType.Byref ilCloTy + + // The local for the state machine + let locIdx, realloc, _ = AllocLocal cenv cgbuf eenvinner true (g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName ("machine", m), ilCloTy, false) scopeMarks + + // The local for the state machine address + let locIdx2, _realloc2, _ = AllocLocal cenv cgbuf eenvinner true (g.CompilerGlobalState.Value.IlxGenNiceNameGenerator.FreshCompilerGeneratedName (afterCodeThisVar.DisplayName, m), ilMachineAddrTy, false) scopeMarks + + // Zero-initialize the machine + EmitInitLocal cgbuf ilCloTy locIdx + + // Initialize the address-of-machine local + CG.EmitInstr cgbuf (pop 0) (Push [ ilMachineAddrTy ]) (I_ldloca (uint16 locIdx) ) + CG.EmitInstr cgbuf (pop 1) (Push [ ]) (I_stloc (uint16 locIdx2) ) + + let eenvinner = eenvinner |> AddStorageForLocalVals g [(afterCodeThisVar, Local (locIdx2, realloc, None)) ] + + // Initialize the closure variables + for fv, ilv in Seq.zip cloFreeVars cloinfo.ilCloAllFreeVars do + if stateVarsSet.Contains fv then + // zero-initialize the state var + if realloc then + CG.EmitInstr cgbuf (pop 0) (Push [ ilMachineAddrTy ]) (I_ldloc (uint16 locIdx2) ) + GenDefaultValue cenv cgbuf eenvouter (fv.Type, m) + CG.EmitInstr cgbuf (pop 2) (Push [ ]) (mkNormalStfld (mkILFieldSpecInTy (ilCloTy, ilv.fvName, ilv.fvType))) + else + // initialize the captured var + CG.EmitInstr cgbuf (pop 0) (Push [ ilMachineAddrTy ]) (I_ldloc (uint16 locIdx2) ) + GenGetLocalVal cenv cgbuf eenvouter m fv None + CG.EmitInstr cgbuf (pop 2) (Push [ ]) (mkNormalStfld (mkILFieldSpecInTy (ilCloTy, ilv.fvName, ilv.fvType))) + + // Generate the start expression - eenvinner is used as it contains the binding for machineAddrVar + GenExpr cenv cgbuf eenvinner SPSuppress afterCodeBody sequel + + ) + +and GenObjectExpr cenv cgbuf eenvouter objExpr (baseType, baseValOpt, basecall, overrides, interfaceImpls, m) sequel = + let g = cenv.g + + // Find the free variables of the closure, to make them further fields of the object. + // + // Note, the 'let' bindings for the stateVars have already been transformed to 'set' expressions, and thus the stateVars are now + // free variables of the expression. + let cloinfo, _, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject false false [] eenvouter objExpr + let ilCloLambdas = cloinfo.ilCloLambdas let cloName = cloinfo.cloName + let cloSpec = cloinfo.cloSpec - let ilxCloSpec = cloinfo.cloSpec - let ilCloFreeVars = cloinfo.cloILFreeVars + let ilCloAllFreeVars = cloinfo.ilCloAllFreeVars let ilCloGenericFormals = cloinfo.cloILGenericParams - assert (isNil cloinfo.localTypeFuncDirectILGenericParams) let ilCloGenericActuals = cloinfo.cloSpec.GenericArgs - let ilCloRetTy = cloinfo.cloILFormalRetTy - let ilCloTypeRef = cloinfo.cloSpec.TypeRef + let ilCloRetTy = cloinfo.ilCloFormalReturnTy + let ilCloTypeRef = cloSpec.TypeRef let ilTyForOverriding = mkILBoxedTy ilCloTypeRef ilCloGenericActuals let eenvinner = bindBaseOrThisVarOpt cenv eenvinner baseValOpt - let ilCtorBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], cloName, eenvinner, 1, basecall, discardAndReturnVoid) + let ilCtorBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], cloName, eenvinner, 1, None, basecall, discardAndReturnVoid) let genMethodAndOptionalMethodImpl tmethod useMethodImpl = - [ for ((useMethodImpl, methodImplGeneratorFunction, methTyparsOfOverridingMethod), mdef) in GenObjectMethod cenv eenvinner cgbuf useMethodImpl tmethod do + [ for (useMethodImpl, methodImplGeneratorFunction, methTyparsOfOverridingMethod), mdef in GenObjectMethod cenv eenvinner cgbuf useMethodImpl tmethod do let mimpl = (if useMethodImpl then Some(methodImplGeneratorFunction (ilTyForOverriding, methTyparsOfOverridingMethod)) else None) yield (mimpl, mdef) ] let mimpls, mdefs = [ for ov in overrides do yield! genMethodAndOptionalMethodImpl ov (isInterfaceTy g baseType) - for (_, tmethods) in interfaceImpls do + for _, tmethods in interfaceImpls do for tmethod in tmethods do yield! genMethodAndOptionalMethodImpl tmethod true ] |> List.unzip @@ -4211,16 +5025,19 @@ and GenObjectExpr cenv cgbuf eenvouter expr (baseType, baseValOpt, basecall, ove let interfaceTys = interfaceImpls |> List.map (fst >> GenType cenv.amap m eenvinner.tyenv) - let attrs = GenAttrs cenv eenvinner cloAttribs let super = (if isInterfaceTy g baseType then g.ilg.typ_Object else ilCloRetTy) let interfaceTys = interfaceTys @ (if isInterfaceTy g baseType then [ilCloRetTy] else []) - let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, ilCloGenericFormals, attrs, ilCloFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, super, interfaceTys) + let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, ilCloGenericFormals, [], ilCloAllFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, super, interfaceTys, Some cloinfo.cloSpec) for cloTypeDef in cloTypeDefs do cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None) + CountClosure() - GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars - CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ EraseClosures.mkTyOfLambdas g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor, None)) + GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloinfo.cloWitnessInfos + for fv in cloinfo.cloFreeVars do + GenGetLocalVal cenv cgbuf eenvouter m fv None + + CG.EmitInstr cgbuf (pop ilCloAllFreeVars.Length) (Push [ EraseClosures.mkTyOfLambdas g.ilxPubCloEnv ilCloLambdas]) (I_newobj (cloSpec.Constructor, None)) GenSequel cenv eenvouter.cloc cgbuf sequel and GenSequenceExpr @@ -4238,8 +5055,8 @@ and GenSequenceExpr eenvouter |> AddStorageForLocalVals g (stateVars |> List.map (fun v -> v.Deref, Local(0, false, None))) // Get the free variables. Make a lambda to pretend that the 'nextEnumeratorValRef' is bound (it is an argument to GenerateNext) - let (cloAttribs, _, _, cloFreeTyvars, cloFreeVars, ilCloTypeRef: ILTypeRef, ilCloFreeVars, eenvinner) = - GetIlxClosureFreeVars cenv m None eenvouter [] (mkLambda m nextEnumeratorValRef.Deref (generateNextExpr, g.int32_ty)) + let (cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef: ILTypeRef, ilCloAllFreeVars, eenvinner) = + GetIlxClosureFreeVars cenv m [] ILBoxity.AsObject eenvouter [] (mkLambda m nextEnumeratorValRef.Deref (generateNextExpr, g.int32_ty)) let ilCloSeqElemTy = GenType cenv.amap m eenvinner.tyenv seqElemTy let cloRetTy = mkSeqTy g seqElemTy @@ -4247,90 +5064,105 @@ and GenSequenceExpr let ilCloRetTyOuter = GenType cenv.amap m eenvouter.tyenv cloRetTy let ilCloEnumeratorTy = GenType cenv.amap m eenvinner.tyenv (mkIEnumeratorTy g seqElemTy) let ilCloEnumerableTy = GenType cenv.amap m eenvinner.tyenv (mkSeqTy g seqElemTy) - let ilCloBaseTy = GenType cenv.amap m eenvinner.tyenv (mkAppTy g.seq_base_tcr [seqElemTy]) + let ilCloBaseTy = GenType cenv.amap m eenvinner.tyenv (g.mk_GeneratedSequenceBase_ty seqElemTy) let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars // Create a new closure class with a single "MoveNext" method that implements the iterator. let ilCloTyInner = mkILFormalBoxedTy ilCloTypeRef ilCloGenericParams let ilCloLambdas = Lambdas_return ilCloRetTyInner - let cloref = IlxClosureRef(ilCloTypeRef, ilCloLambdas, ilCloFreeVars) - let ilxCloSpec = IlxClosureSpec.Create(cloref, GenGenericArgs m eenvouter.tyenv cloFreeTyvars) - let formalClospec = IlxClosureSpec.Create(cloref, mkILFormalGenericArgs 0 ilCloGenericParams) + let cloref = IlxClosureRef(ilCloTypeRef, ilCloLambdas, ilCloAllFreeVars) + let ilxCloSpec = IlxClosureSpec.Create(cloref, GenGenericArgs m eenvouter.tyenv cloFreeTyvars, false) + let formalClospec = IlxClosureSpec.Create(cloref, mkILFormalGenericArgs 0 ilCloGenericParams, false) let getFreshMethod = let _, mbody = CodeGenMethod cenv cgbuf.mgbuf - ([], "GetFreshEnumerator", eenvinner, 1, + ([], "GetFreshEnumerator", eenvinner, 1, None, (fun cgbuf eenv -> + GenWitnessArgsFromWitnessInfos cenv cgbuf eenv m cloWitnessInfos for fv in cloFreeVars do - /// State variables always get zero-initialized + // State variables always get zero-initialized if stateVarsSet.Contains fv then GenDefaultValue cenv cgbuf eenv (fv.Type, m) else GenGetLocalVal cenv cgbuf eenv m fv None - CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyInner]) (I_newobj (formalClospec.Constructor, None)) + CG.EmitInstr cgbuf (pop ilCloAllFreeVars.Length) (Push [ilCloRetTyInner]) (I_newobj (formalClospec.Constructor, None)) GenSequel cenv eenv.cloc cgbuf Return), m) - mkILNonGenericVirtualMethod("GetFreshEnumerator", ILMemberAccess.Public, [], mkILReturn ilCloEnumeratorTy, MethodBody.IL mbody) + mkILNonGenericVirtualMethod("GetFreshEnumerator", ILMemberAccess.Public, [], mkILReturn ilCloEnumeratorTy, MethodBody.IL (lazy mbody)) |> AddNonUserCompilerGeneratedAttribs g let closeMethod = - // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump + // Note: We suppress the first debug point in the body of this method since it is the initial state machine jump let spReq = SPSuppress - let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "Close", eenvinner, 1, closeExpr, discardAndReturnVoid) - mkILNonGenericVirtualMethod("Close", ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL ilCode) + let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "Close", eenvinner, 1, None, closeExpr, discardAndReturnVoid) + mkILNonGenericVirtualMethod("Close", ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL (lazy ilCode)) let checkCloseMethod = - // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump + // Note: We suppress the first debug point in the body of this method since it is the initial state machine jump let spReq = SPSuppress - let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "get_CheckClose", eenvinner, 1, checkCloseExpr, Return) - mkILNonGenericVirtualMethod("get_CheckClose", ILMemberAccess.Public, [], mkILReturn g.ilg.typ_Bool, MethodBody.IL ilCode) + let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "get_CheckClose", eenvinner, 1, None, checkCloseExpr, Return) + mkILNonGenericVirtualMethod("get_CheckClose", ILMemberAccess.Public, [], mkILReturn g.ilg.typ_Bool, MethodBody.IL (lazy ilCode)) let generateNextMethod = - // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump + // Note: We suppress the first debug point in the body of this method since it is the initial state machine jump let spReq = SPSuppress // the 'next enumerator' byref arg is at arg position 1 let eenvinner = eenvinner |> AddStorageForLocalVals g [ (nextEnumeratorValRef.Deref, Arg 1) ] let ilParams = [mkILParamNamed("next", ILType.Byref ilCloEnumerableTy)] let ilReturn = mkILReturn g.ilg.typ_Int32 - let ilCode = MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "GenerateNext", eenvinner, 2, generateNextExpr, Return)) + let ilCode = MethodBody.IL (lazy (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq, [], "GenerateNext", eenvinner, 2, None, generateNextExpr, Return))) mkILNonGenericVirtualMethod("GenerateNext", ILMemberAccess.Public, ilParams, ilReturn, ilCode) let lastGeneratedMethod = - let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], "get_LastGenerated", eenvinner, 1, exprForValRef m currvref, Return) - mkILNonGenericVirtualMethod("get_LastGenerated", ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL ilCode) + let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], "get_LastGenerated", eenvinner, 1, None, exprForValRef m currvref, Return) + mkILNonGenericVirtualMethod("get_LastGenerated", ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL (lazy ilCode)) |> AddNonUserCompilerGeneratedAttribs g - let ilCtorBody = - mkILSimpleStorageCtor(None, Some ilCloBaseTy.TypeSpec, ilCloTyInner, [], [], ILMemberAccess.Assembly).MethodBody + let ilCtorBody = mkILSimpleStorageCtor(Some ilCloBaseTy.TypeSpec, ilCloTyInner, [], [], ILMemberAccess.Assembly, None, eenvouter.imports).MethodBody - let attrs = GenAttrs cenv eenvinner cloAttribs - let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, ilCloGenericParams, attrs, ilCloFreeVars, ilCloLambdas, ilCtorBody, [generateNextMethod;closeMethod;checkCloseMethod;lastGeneratedMethod;getFreshMethod], [], ilCloBaseTy, []) + let cloMethods = [generateNextMethod; closeMethod; checkCloseMethod; lastGeneratedMethod; getFreshMethod] + let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, ilCloGenericParams, [], ilCloAllFreeVars, ilCloLambdas, ilCtorBody, cloMethods, [], ilCloBaseTy, [], Some ilxCloSpec) for cloTypeDef in cloTypeDefs do cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None) CountClosure() + GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos for fv in cloFreeVars do /// State variables always get zero-initialized if stateVarsSet.Contains fv then GenDefaultValue cenv cgbuf eenvouter (fv.Type, m) else GenGetLocalVal cenv cgbuf eenvouter m fv None - - CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [ilCloRetTyOuter]) (I_newobj (ilxCloSpec.Constructor, None)) - GenSequel cenv eenvouter.cloc cgbuf sequel - + CG.EmitInstr cgbuf (pop ilCloAllFreeVars.Length) (Push [ilCloRetTyOuter]) (I_newobj (ilxCloSpec.Constructor, None)) + GenSequel cenv eenvouter.cloc cgbuf sequel /// Generate the class for a closure type definition -and GenClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, ext, ilIntfTys) = +and GenClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloAllFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, ext, ilIntfTys, cloSpec: IlxClosureSpec option) = let g = cenv.g let cloInfo = - { cloFreeVars=ilCloFreeVars + { cloFreeVars=ilCloAllFreeVars cloStructure=ilCloLambdas - cloCode=notlazy ilCtorBody } + cloCode=notlazy ilCtorBody + cloUseStaticField = (match cloSpec with None -> false | Some cloSpec -> cloSpec.UseStaticField) + } + + let mdefs, fdefs = + if cloInfo.cloUseStaticField then + let cloSpec = cloSpec.Value + let cloTy = mkILFormalBoxedTy cloSpec.TypeRef (mkILFormalTypars cloSpec.GenericArgs) + let fspec = mkILFieldSpec (cloSpec.GetStaticFieldSpec().FieldRef, cloTy) + let ctorSpec = mkILMethSpecForMethRefInTy (cloSpec.Constructor.MethodRef, cloTy, []) + let ilInstrs = [ I_newobj (ctorSpec, None); mkNormalStsfld fspec ] + let ilCode = mkILMethodBody (true, [], 8, nonBranchingInstrsToCode ilInstrs, None, None) + let cctor = mkILClassCtor (MethodBody.IL (notlazy ilCode)) + let ilFieldDef = mkILStaticField(fspec.Name, fspec.FormalType, None, None, ILMemberAccess.Assembly).WithInitOnly(true) + (cctor :: mdefs), [ ilFieldDef ] + else + mdefs, [] let tdef = ILTypeDef(name = tref.Name, @@ -4338,7 +5170,7 @@ and GenClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloFreeVars, attributes = enum 0, genericParams = ilGenParams, customAttrs = mkILCustomAttrs(attrs @ [mkCompilationMappingAttr g (int SourceConstructFlags.Closure) ]), - fields = emptyILFields, + fields = mkILFields fdefs, events= emptyILEvents, properties = emptyILProperties, methods= mkILMethods mdefs, @@ -4357,93 +5189,98 @@ and GenClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloFreeVars, let tdefs = EraseClosures.convIlxClosureDef g.ilxPubCloEnv tref.Enclosing tdef cloInfo tdefs - -and GenGenericParams cenv eenv tps = + +and GenStaticDelegateClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloAllFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, ext, ilIntfTys, staticCloInfo) = + let tdefs = GenClosureTypeDefs cenv (tref, ilGenParams, attrs, ilCloAllFreeVars, ilCloLambdas, ilCtorBody, mdefs, mimpls, ext, ilIntfTys, staticCloInfo) + + // Apply the abstract attribute, turning the sealed class into abstract sealed (i.e. static class). + // Remove the redundant constructor. + tdefs |> List.map (fun td -> td.WithAbstract(true) + .With(methods= mkILMethodsFromArray (td.Methods.AsArray |> Array.filter (fun m -> not m.IsConstructor)))) + +and GenGenericParams cenv eenv tps = tps |> DropErasedTypars |> List.map (GenGenericParam cenv eenv) and GenGenericArgs m (tyenv: TypeReprEnv) tps = tps |> DropErasedTypars |> List.map (fun c -> (mkILTyvarTy tyenv.[c, m])) -/// Generate the closure class for a function -and GenLambdaClosure cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc selfv expr = +/// Generate a local type function contract class and implementation +and GenClosureAsLocalTypeFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars expr m = + let g = cenv.g + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject true true thisVars eenv expr + let ilCloTypeRef = cloinfo.cloSpec.TypeRef + let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure cloinfo.cloArityInfo)) + // Now generate the actual closure implementation w.r.t. eenvinner + let directTypars, ilDirectWitnessParams, _directWitnessInfos, eenvinner = + AddDirectTyparWitnessParams cenv eenvinner cloinfo m + + let ilDirectGenericParams = GenGenericParams cenv eenvinner directTypars + + // The type-lambdas are dealt with by the local type function + let ilCloFormalReturnTy, ilCloLambdas = + let rec strip lambdas = + match lambdas with + | Lambdas_forall(_, r) -> strip r + | Lambdas_return returnTy -> returnTy, lambdas + | _ -> failwith "AdjustNamedLocalTypeFuncIlxClosureInfo: local functions can currently only be type functions" + strip cloinfo.ilCloLambdas + + let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, entryPointInfo, cloinfo.cloName, eenvinner, 1, None, body, Return) + let ilCtorBody = mkILMethodBody (true, [], 8, nonBranchingInstrsToCode (mkCallBaseConstructor(g.ilg.typ_Object, [])), None, eenv.imports) + let cloMethods = [ mkILGenericVirtualMethod("DirectInvoke", ILMemberAccess.Assembly, ilDirectGenericParams, ilDirectWitnessParams, mkILReturn ilCloFormalReturnTy, MethodBody.IL(lazy ilCloBody)) ] + + let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.ilCloAllFreeVars, ilCloLambdas, ilCtorBody, cloMethods, [], g.ilg.typ_Object, [], Some cloinfo.cloSpec) + cloinfo, ilCloTypeRef, cloTypeDefs + +and GenClosureAsFirstClassFunction cenv (cgbuf: CodeGenBuffer) eenv thisVars m expr = let g = cenv.g + let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m ILBoxity.AsObject false true thisVars eenv expr + let entryPointInfo = thisVars |> List.map (fun v -> (v, BranchCallClosure (cloinfo.cloArityInfo))) + let ilCloTypeRef = cloinfo.cloSpec.TypeRef + + let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, entryPointInfo, cloinfo.cloName, eenvinner, 1, None, body, Return) + let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.ilCloAllFreeVars, cloinfo.ilCloLambdas, ilCloBody, [], [], g.ilg.typ_Object, [], Some cloinfo.cloSpec) + cloinfo, ilCloTypeRef, cloTypeDefs + +/// Generate the closure class for a function +and GenLambdaClosure cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc thisVars expr = match expr with | Expr.Lambda (_, _, _, _, _, m, _) | Expr.TyLambda (_, _, _, m, _) -> - - let cloinfo, body, eenvinner = GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenv expr - - let entryPointInfo = - match selfv with - | Some v -> [(v, BranchCallClosure (cloinfo.cloArityInfo))] - | _ -> [] - let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, entryPointInfo, cloinfo.cloName, eenvinner, 1, body, Return) - let ilCloTypeRef = cloinfo.cloSpec.TypeRef - let cloTypeDefs = + let cloinfo, ilCloTypeRef, cloTypeDefs = if isLocalTypeFunc then - - // Work out the contract type and generate a class with an abstract method for this type - let (ilContractGenericParams, ilContractMethTyargs, ilContractTySpec: ILTypeSpec, ilContractFormalRetTy) = GenNamedLocalTypeFuncContractInfo cenv eenv m cloinfo - let ilContractTypeRef = ilContractTySpec.TypeRef - let ilContractTy = mkILFormalBoxedTy ilContractTypeRef ilContractGenericParams - let ilContractCtor = mkILNonGenericEmptyCtor None g.ilg.typ_Object - - let ilContractMeths = [ilContractCtor; mkILGenericVirtualMethod("DirectInvoke", ILMemberAccess.Assembly, ilContractMethTyargs, [], mkILReturn ilContractFormalRetTy, MethodBody.Abstract) ] - let ilContractTypeDef = - ILTypeDef(name = ilContractTypeRef.Name, - layout = ILTypeDefLayout.Auto, - attributes = enum 0, - genericParams = ilContractGenericParams, - customAttrs = mkILCustomAttrs [mkCompilationMappingAttr g (int SourceConstructFlags.Closure) ], - fields = emptyILFields, - events= emptyILEvents, - properties = emptyILProperties, - methods= mkILMethods ilContractMeths, - methodImpls= emptyILMethodImpls, - nestedTypes=emptyILTypeDefs, - implements = [], - extends= Some g.ilg.typ_Object, - securityDecls= emptyILSecurityDecls) - - // the contract type is an abstract type and not sealed - let ilContractTypeDef = - ilContractTypeDef - .WithAbstract(true) - .WithAccess(ComputeTypeAccess ilContractTypeRef true) - .WithSerializable(true) - .WithSpecialName(true) - .WithLayout(ILTypeDefLayout.Auto) - .WithInitSemantics(ILTypeInit.BeforeField) - .WithEncoding(ILDefaultPInvokeEncoding.Auto) - - cgbuf.mgbuf.AddTypeDef(ilContractTypeRef, ilContractTypeDef, false, false, None) - - let ilCtorBody = mkILMethodBody (true, [], 8, nonBranchingInstrsToCode (mkCallBaseConstructor(ilContractTy, [])), None ) - let cloMethods = [ mkILGenericVirtualMethod("DirectInvoke", ILMemberAccess.Assembly, cloinfo.localTypeFuncDirectILGenericParams, [], mkILReturn (cloinfo.cloILFormalRetTy), MethodBody.IL ilCloBody) ] - let cloTypeDefs = GenClosureTypeDefs cenv (ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.cloILFreeVars, cloinfo.ilCloLambdas, ilCtorBody, cloMethods, [], ilContractTy, []) - cloTypeDefs - + GenClosureAsLocalTypeFunction cenv cgbuf eenv thisVars expr m else - GenClosureTypeDefs cenv (ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.cloILFreeVars, cloinfo.ilCloLambdas, ilCloBody, [], [], g.ilg.typ_Object, []) + GenClosureAsFirstClassFunction cenv cgbuf eenv thisVars m expr + CountClosure() for cloTypeDef in cloTypeDefs do cgbuf.mgbuf.AddTypeDef(ilCloTypeRef, cloTypeDef, false, false, None) cloinfo, m | _ -> failwith "GenLambda: not a lambda" - -and GenLambdaVal cenv (cgbuf: CodeGenBuffer) eenv (cloinfo, m) = - let g = cenv.g - GenGetLocalVals cenv cgbuf eenv m cloinfo.cloFreeVars - CG.EmitInstr cgbuf - (pop cloinfo.cloILFreeVars.Length) - (Push [EraseClosures.mkTyOfLambdas g.ilxPubCloEnv cloinfo.ilCloLambdas]) - (I_newobj (cloinfo.cloSpec.Constructor, None)) -and GenLambda cenv cgbuf eenv isLocalTypeFunc selfv expr sequel = - let cloinfo, m = GenLambdaClosure cenv cgbuf eenv isLocalTypeFunc selfv expr - GenLambdaVal cenv cgbuf eenv (cloinfo, m) +and GenClosureAlloc cenv (cgbuf: CodeGenBuffer) eenv (cloinfo, m) = + let g = cenv.g + CountClosure() + if cloinfo.cloSpec.UseStaticField then + let fspec = cloinfo.cloSpec.GetStaticFieldSpec() + CG.EmitInstr cgbuf + (pop 0) + (Push [EraseClosures.mkTyOfLambdas g.ilxPubCloEnv cloinfo.ilCloLambdas]) + (mkNormalLdsfld fspec) + else + GenWitnessArgsFromWitnessInfos cenv cgbuf eenv m cloinfo.cloWitnessInfos + GenGetLocalVals cenv cgbuf eenv m cloinfo.cloFreeVars + CG.EmitInstr cgbuf + (pop cloinfo.ilCloAllFreeVars.Length) + (Push [EraseClosures.mkTyOfLambdas g.ilxPubCloEnv cloinfo.ilCloLambdas]) + (I_newobj (cloinfo.cloSpec.Constructor, None)) + +and GenLambda cenv cgbuf eenv isLocalTypeFunc thisVars expr sequel = + let cloinfo, m = GenLambdaClosure cenv cgbuf eenv isLocalTypeFunc thisVars expr + GenClosureAlloc cenv cgbuf eenv (cloinfo, m) GenSequel cenv eenv.cloc cgbuf sequel and GenTypeOfVal cenv eenv (v: Val) = @@ -4453,14 +5290,14 @@ and GenFreevar cenv m eenvouter tyenvinner (fv: Val) = let g = cenv.g match StorageForVal cenv.g m fv eenvouter with // Local type functions - | Local(_, _, Some _) | Env(_, _, _, Some _) -> g.ilg.typ_Object + | Local(_, _, Some _) | Env(_, _, Some _) -> g.ilg.typ_Object #if DEBUG // Check for things that should never make it into the free variable set. Only do this in debug for performance reasons - | (StaticField _ | StaticProperty _ | Method _ | Null) -> error(InternalError("GenFreevar: compiler error: unexpected unrealized value", fv.Range)) + | StaticPropertyWithField _ | StaticProperty _ | Method _ | Null -> error(InternalError("GenFreevar: compiler error: unexpected unrealized value", fv.Range)) #endif | _ -> GenType cenv.amap m tyenvinner fv.Type -and GetIlxClosureFreeVars cenv m selfv eenvouter takenNames expr = +and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenvouter takenNames expr = let g = cenv.g // Choose a base name for the closure @@ -4495,76 +5332,86 @@ and GetIlxClosureFreeVars cenv m selfv eenvouter takenNames expr = // Partition the free variables when some can be accessed from places besides the immediate environment // Also filter out the current value being bound, if any, as it is available from the "this" // pointer which gives the current closure itself. This is in the case e.g. let rec f = ... f ... + let freeLocals = cloFreeVarResults.FreeLocals |> Zset.elements let cloFreeVars = - cloFreeVarResults.FreeLocals - |> Zset.elements + freeLocals |> List.filter (fun fv -> + (thisVars |> List.forall (fun v -> not (valRefEq g (mkLocalValRef fv) v))) && + (match StorageForVal cenv.g m fv eenvouter with + | StaticPropertyWithField _ | StaticProperty _ | Method _ | Null -> false + | _ -> true)) + + // Any closure using values represented as local type functions also captures the type variables captured + // by that local type function + let cloFreeTyvars = + (cloFreeVarResults.FreeTyvars, freeLocals) ||> List.fold (fun ftyvs fv -> match StorageForVal cenv.g m fv eenvouter with - | (StaticField _ | StaticProperty _ | Method _ | Null) -> false - | _ -> - match selfv with - | Some v -> not (valRefEq g (mkLocalValRef fv) v) - | _ -> true) - - // The general shape is: - // {LAM . expr }[free-typars]: overall-type[contract-typars] - // Then - // internal-typars = free-typars - contract-typars - // - // In other words, the free type variables get divided into two sets - // -- "contract" ones, which are part of the return type. We separate these to enable use to - // bake our own function base contracts for local type functions - // - // -- "internal" ones, which get used internally in the implementation - let cloContractFreeTyvarSet = (freeInType CollectTypars (tyOfExpr g expr)).FreeTypars - - let cloInternalFreeTyvars = Zset.diff cloFreeVarResults.FreeTyvars.FreeTypars cloContractFreeTyvarSet |> Zset.elements - let cloContractFreeTyvars = cloContractFreeTyvarSet |> Zset.elements - - let cloFreeTyvars = cloContractFreeTyvars @ cloInternalFreeTyvars + | Env (_, _, Some (moreFtyvs, _)) + | Local (_, _, Some (moreFtyvs, _)) -> unionFreeTyvars ftyvs moreFtyvs + | _ -> ftyvs) - let cloAttribs = [] + let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements let eenvinner = eenvouter |> EnvForTypars cloFreeTyvars let ilCloTyInner = let ilCloGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars - mkILFormalBoxedTy ilCloTypeRef ilCloGenericParams + mkILFormalNamedTy boxity ilCloTypeRef ilCloGenericParams // If generating a named closure, add the closure itself as a var, available via "arg0" . // The latter doesn't apply for the delegate implementation of closures. // Build the environment that is active inside the closure itself - let eenvinner = eenvinner |> AddStorageForLocalVals g (match selfv with | Some v -> [(v.Deref, Arg 0)] | _ -> []) + let eenvinner = eenvinner |> AddStorageForLocalVals g (thisVars |> List.map (fun v -> (v.Deref, Arg 0))) + + // Work out if the closure captures any witnesses. + let cloWitnessInfos = + let generateWitnesses = ComputeGenerateWitnesses g eenvinner + if generateWitnesses then + // The 0 here represents that a closure doesn't reside within a generic class - there are no "enclosing class type parameters" to lop off. + GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars + else + [] + + // Captured witnesses get captured in free variable fields + let ilCloWitnessFreeVars, ilCloWitnessStorage = + FreeVarStorageForWitnessInfos cenv eenvinner takenNames ilCloTyInner m cloWitnessInfos + + // Allocate storage in the environment for the witnesses + let eenvinner = eenvinner |> AddStorageForLocalWitnesses ilCloWitnessStorage - let ilCloFreeVars = - let ilCloFreeVarNames = ChooseFreeVarNames takenNames (List.map nameOfVal cloFreeVars) - let ilCloFreeVars = (cloFreeVars, ilCloFreeVarNames) ||> List.map2 (fun fv nm -> mkILFreeVar (nm, fv.IsCompilerGenerated, GenFreevar cenv m eenvouter eenvinner.tyenv fv)) - ilCloFreeVars + let ilCloFreeVars, ilCloFreeVarStorage = + let names = + cloFreeVars + |> List.map nameOfVal + |> ChooseFreeVarNames takenNames - let ilCloFreeVarStorage = - (cloFreeVars, ilCloFreeVars) ||> List.mapi2 (fun i v fv -> + (cloFreeVars, names) + ||> List.map2 (fun fv nm -> let localCloInfo = - match StorageForVal g m v eenvouter with + match StorageForVal g m fv eenvouter with | Local(_, _, localCloInfo) - | Env(_, _, _, localCloInfo) -> localCloInfo + | Env(_, _, localCloInfo) -> localCloInfo | _ -> None - let ilField = mkILFieldSpecInTy (ilCloTyInner, fv.fvName, fv.fvType) + let ilFv = mkILFreeVar (nm, fv.IsCompilerGenerated, GenFreevar cenv m eenvouter eenvinner.tyenv fv) + let storage = + let ilField = mkILFieldSpecInTy (ilCloTyInner, ilFv.fvName, ilFv.fvType) + Env(ilCloTyInner, ilField, localCloInfo) + ilFv, (fv, storage)) + |> List.unzip - (v, Env(ilCloTyInner, i, ilField, localCloInfo))) + let ilCloAllFreeVars = Array.ofList (ilCloWitnessFreeVars @ ilCloFreeVars) let eenvinner = eenvinner |> AddStorageForLocalVals g ilCloFreeVarStorage // Return a various results - (cloAttribs, cloInternalFreeTyvars, cloContractFreeTyvars, cloFreeTyvars, cloFreeVars, ilCloTypeRef, Array.ofList ilCloFreeVars, eenvinner) - + (cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner) -and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr = +and GetIlxClosureInfo cenv m boxity isLocalTypeFunc canUseStaticField thisVars eenvouter expr = let g = cenv.g let returnTy = match expr with | Expr.Lambda (_, _, _, _, _, _, returnTy) | Expr.TyLambda (_, _, _, _, returnTy) -> returnTy - | Expr.Obj (_, ty, _, _, _, _, _) -> ty - | _ -> failwith "GetIlxClosureInfo: not a lambda expression" + | _ -> tyOfExpr g expr // Determine the structure of the closure. We do this before analyzing free variables to // determine the taken argument names. @@ -4585,21 +5432,22 @@ and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr = let takenNames = vs |> List.map (fun v -> v.CompiledName g.CompilerGlobalState) // Get the free variables and the information about the closure, add the free variables to the environment - let (cloAttribs, cloInternalFreeTyvars, cloContractFreeTyvars, _, cloFreeVars, ilCloTypeRef, ilCloFreeVars, eenvinner) = GetIlxClosureFreeVars cenv m selfv eenvouter takenNames expr + let cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilCloTypeRef, ilCloAllFreeVars, eenvinner = + GetIlxClosureFreeVars cenv m thisVars boxity eenvouter takenNames expr // Put the type and value arguments into the environment - let rec getClosureArgs eenv ntmargs tvsl (vs: Val list) = + let rec getClosureArgs eenv numArgs tvsl (vs: Val list) = match tvsl, vs with | tvs :: rest, _ -> let eenv = AddTyparsToEnv tvs eenv - let l, eenv = getClosureArgs eenv ntmargs rest vs + let l, eenv = getClosureArgs eenv numArgs rest vs let lambdas = (tvs, l) ||> List.foldBack (fun tv sofar -> Lambdas_forall(GenGenericParam cenv eenv tv, sofar)) lambdas, eenv | [], v :: rest -> let nm = v.CompiledName g.CompilerGlobalState let l, eenv = - let eenv = AddStorageForVal g (v, notlazy (Arg ntmargs)) eenv - getClosureArgs eenv (ntmargs+1) [] rest + let eenv = AddStorageForVal g (v, notlazy (Arg numArgs)) eenv + getClosureArgs eenv (numArgs+1) [] rest let lambdas = Lambdas_lambda (mkILParamNamed(nm, GenTypeOfVal cenv eenv v), l) lambdas, eenv | _ -> @@ -4613,110 +5461,33 @@ and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr = let narginfo = vs |> List.map (fun _ -> 1) // Generate the ILX view of the lambdas - let ilReturnTy = GenType cenv.amap m eenvinner.tyenv returnTy + let ilCloReturnTy = GenType cenv.amap m eenvinner.tyenv returnTy - // The general shape is: - // {LAM . expr }[free-typars]: overall-type[contract-typars] - // Then - // internal-typars = free-typars - contract-typars - // - // For a local type function closure, this becomes - // class Contract { - // abstract DirectInvoke : overall-type - // } - // - // class ContractImplementation : Contract { - // override DirectInvoke : overall-type { expr } - // } - // - // For a non-local type function closure, this becomes - // - // class FunctionImplementation : FSharpTypeFunc { - // override Specialize : overall-type { expr } - // } - // - // For a normal function closure, is empty, and this becomes - // - // class FunctionImplementation : overall-type { - // override Invoke(..) { expr } - // } + /// Compute the contract if it is a local type function + let ilCloGenericFormals = GenGenericParams cenv eenvinner cloFreeTyvars + let ilCloGenericActuals = GenGenericArgs m eenvouter.tyenv cloFreeTyvars - // In other words, the free type variables get divided into two sets - // -- "contract" ones, which are part of the return type. We separate these to enable use to - // bake our own function base contracts for local type functions - // - // -- "internal" ones, which get used internally in the implementation - // - // There are also "direct" and "indirect" type variables, which are part of the lambdas of the type function. - // Direct type variables are only used for local type functions, and indirect type variables only used for first class - // function values. + let useStaticField = canUseStaticField && (ilCloAllFreeVars.Length = 0) - /// Compute the contract if it is a local type function - let ilContractGenericParams = GenGenericParams cenv eenvinner cloContractFreeTyvars - let ilContractGenericActuals = GenGenericArgs m eenvouter.tyenv cloContractFreeTyvars - let ilInternalGenericParams = GenGenericParams cenv eenvinner cloInternalFreeTyvars - let ilInternalGenericActuals = GenGenericArgs m eenvouter.tyenv cloInternalFreeTyvars - - let ilCloGenericFormals = ilContractGenericParams @ ilInternalGenericParams - let ilCloGenericActuals = ilContractGenericActuals @ ilInternalGenericActuals - - let ilDirectGenericParams, ilReturnTy, ilCloLambdas = - if isLocalTypeFunc then - let rec strip lambdas acc = - match lambdas with - | Lambdas_forall(gp, r) -> strip r (gp :: acc) - | Lambdas_return returnTy -> List.rev acc, returnTy, lambdas - | _ -> failwith "AdjustNamedLocalTypeFuncIlxClosureInfo: local functions can currently only be type functions" - strip ilCloLambdas [] - else - [], ilReturnTy, ilCloLambdas - + let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilCloTypeRef, ilCloLambdas, ilCloAllFreeVars), ilCloGenericActuals, useStaticField) - let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilCloTypeRef, ilCloLambdas, ilCloFreeVars), ilCloGenericActuals) let cloinfo = { cloExpr=expr cloName=ilCloTypeRef.Name cloArityInfo =narginfo ilCloLambdas=ilCloLambdas - cloILFreeVars = ilCloFreeVars - cloILFormalRetTy=ilReturnTy + ilCloAllFreeVars = ilCloAllFreeVars + ilCloFormalReturnTy = ilCloReturnTy cloSpec = ilxCloSpec cloILGenericParams = ilCloGenericFormals cloFreeVars=cloFreeVars - cloAttribs=cloAttribs - localTypeFuncContractFreeTypars = cloContractFreeTyvars - localTypeFuncInternalFreeTypars = cloInternalFreeTyvars - localTypeFuncILGenericArgs = ilContractGenericActuals - localTypeFuncDirectILGenericParams = ilDirectGenericParams } + cloFreeTyvars=cloFreeTyvars + cloWitnessInfos = cloWitnessInfos } cloinfo, body, eenvinner -//-------------------------------------------------------------------------- -// Named local type functions -//-------------------------------------------------------------------------- - -and IsNamedLocalTypeFuncVal g (v: Val) expr = - not v.IsCompiledAsTopLevel && - IsGenericValWithGenericConstraints g v && - (match stripExpr expr with Expr.TyLambda _ -> true | _ -> false) - -/// Generate the information relevant to the contract portion of a named local type function -and GenNamedLocalTypeFuncContractInfo cenv eenv m cloinfo = - let ilCloTypeRef = cloinfo.cloSpec.TypeRef - let ilContractTypeRef = ILTypeRef.Create(scope=ilCloTypeRef.Scope, enclosing=ilCloTypeRef.Enclosing, name=ilCloTypeRef.Name + "$contract") - let eenvForContract = EnvForTypars cloinfo.localTypeFuncContractFreeTypars eenv - let ilContractGenericParams = GenGenericParams cenv eenv cloinfo.localTypeFuncContractFreeTypars - let tvs, contractRetTy = - match cloinfo.cloExpr with - | Expr.TyLambda (_, tvs, _, _, bty) -> tvs, bty - | e -> [], tyOfExpr cenv.g e - let eenvForContract = AddTyparsToEnv tvs eenvForContract - let ilContractMethTyargs = GenGenericParams cenv eenvForContract tvs - let ilContractFormalRetTy = GenType cenv.amap m eenvForContract.tyenv contractRetTy - ilContractGenericParams, ilContractMethTyargs, mkILTySpec(ilContractTypeRef, cloinfo.localTypeFuncILGenericArgs), ilContractFormalRetTy - /// Generate a new delegate construction including a closure class if necessary. This is a lot like generating function closures /// and object expression closures, and most of the code is shared. -and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_, delegateTy, _, _, _, _) as slotsig), _attribs, methTyparsOfOverridingMethod, tmvs, body, _), m) sequel = +and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod(TSlotSig(_, delegateTy, _, _, _, _) as slotsig, _attribs, methTyparsOfOverridingMethod, tmvs, body, _), m) sequel = let g = cenv.g // Get the instantiation of the delegate type @@ -4739,20 +5510,25 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_, deleg false with _ -> false - + // Work out the free type variables for the morphing thunk let takenNames = List.map nameOfVal tmvs - let (cloAttribs, _, _, cloFreeTyvars, cloFreeVars, ilDelegeeTypeRef, ilCloFreeVars, eenvinner) = GetIlxClosureFreeVars cenv m None eenvouter takenNames expr + let cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilDelegeeTypeRef, ilCloAllFreeVars, eenvinner = + GetIlxClosureFreeVars cenv m [] ILBoxity.AsObject eenvouter takenNames expr + let ilDelegeeGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars let ilDelegeeGenericActualsInner = mkILFormalGenericArgs 0 ilDelegeeGenericParams + // When creating a delegate that does not capture any variables, we can instead create a static closure and directly reference the method. + let useStaticClosure = cloFreeVars.IsEmpty + // Create a new closure class with a single "delegee" method that implements the delegate. let delegeeMethName = "Invoke" let ilDelegeeTyInner = mkILBoxedTy ilDelegeeTypeRef ilDelegeeGenericActualsInner let envForDelegeeUnderTypars = AddTyparsToEnv methTyparsOfOverridingMethod eenvinner - let numthis = 1 + let numthis = if useStaticClosure then 0 else 1 let tmvs, body = BindUnitVars g (tmvs, List.replicate (List.concat slotsig.FormalParams).Length ValReprInfo.unnamedTopArg1, body) // The slot sig contains a formal instantiation. When creating delegates we're only @@ -4760,40 +5536,74 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_, deleg let ilDelegeeParams, ilDelegeeRet = GenActualSlotsig m cenv envForDelegeeUnderTypars slotsig methTyparsOfOverridingMethod tmvs let envForDelegeeMeth = AddStorageForLocalVals g (List.mapi (fun i v -> (v, Arg (i+numthis))) tmvs) envForDelegeeUnderTypars - let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], delegeeMethName, envForDelegeeMeth, 1, body, (if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) + let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways, [], delegeeMethName, envForDelegeeMeth, 1, None, body, (if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) let delegeeInvokeMeth = - mkILNonGenericInstanceMethod - (delegeeMethName, ILMemberAccess.Assembly, + (if useStaticClosure then mkILNonGenericStaticMethod else mkILNonGenericInstanceMethod) + (delegeeMethName, + ILMemberAccess.Assembly, ilDelegeeParams, ilDelegeeRet, - MethodBody.IL ilMethodBody) - let delegeeCtorMeth = mkILSimpleStorageCtor(None, Some g.ilg.typ_Object.TypeSpec, ilDelegeeTyInner, [], [], ILMemberAccess.Assembly) + MethodBody.IL(lazy ilMethodBody)) + let delegeeCtorMeth = mkILSimpleStorageCtor(Some g.ilg.typ_Object.TypeSpec, ilDelegeeTyInner, [], [], ILMemberAccess.Assembly, None, eenvouter.imports) let ilCtorBody = delegeeCtorMeth.MethodBody let ilCloLambdas = Lambdas_return ilCtxtDelTy - let ilAttribs = GenAttrs cenv eenvinner cloAttribs - let cloTypeDefs = GenClosureTypeDefs cenv (ilDelegeeTypeRef, ilDelegeeGenericParams, ilAttribs, ilCloFreeVars, ilCloLambdas, ilCtorBody, [delegeeInvokeMeth], [], g.ilg.typ_Object, []) + let cloTypeDefs = + (if useStaticClosure then GenStaticDelegateClosureTypeDefs else GenClosureTypeDefs) + cenv (ilDelegeeTypeRef, ilDelegeeGenericParams, [], ilCloAllFreeVars, ilCloLambdas, ilCtorBody, [delegeeInvokeMeth], [], g.ilg.typ_Object, [], None) for cloTypeDef in cloTypeDefs do cgbuf.mgbuf.AddTypeDef(ilDelegeeTypeRef, cloTypeDef, false, false, None) CountClosure() + // Push the constructor for the delegee let ctxtGenericArgsForDelegee = GenGenericArgs m eenvouter.tyenv cloFreeTyvars - let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloFreeVars), ctxtGenericArgsForDelegee) - GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars - CG.EmitInstr cgbuf (pop ilCloFreeVars.Length) (Push [EraseClosures.mkTyOfLambdas g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor, None)) + if useStaticClosure then + GenUnit cenv eenvouter m cgbuf + else + let ilxCloSpec = IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloAllFreeVars), ctxtGenericArgsForDelegee, false) + GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos + GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars + + CG.EmitInstr cgbuf (pop ilCloAllFreeVars.Length) (Push [EraseClosures.mkTyOfLambdas g.ilxPubCloEnv ilCloLambdas]) (I_newobj (ilxCloSpec.Constructor, None)) + + // Push the function pointer to the Invoke method of the delegee let ilDelegeeTyOuter = mkILBoxedTy ilDelegeeTypeRef ctxtGenericArgsForDelegee - let ilDelegeeInvokeMethOuter = mkILNonGenericInstanceMethSpecInTy (ilDelegeeTyOuter, "Invoke", typesOfILParams ilDelegeeParams, ilDelegeeRet.Type) - let ilDelegeeCtorMethOuter = mkCtorMethSpecForDelegate g.ilg (ilCtxtDelTy, useUIntPtrForDelegateCtor) + let ilDelegeeInvokeMethOuter = + (if useStaticClosure then mkILNonGenericStaticMethSpecInTy else mkILNonGenericInstanceMethSpecInTy) + (ilDelegeeTyOuter, + "Invoke", + typesOfILParams ilDelegeeParams, + ilDelegeeRet.Type) CG.EmitInstr cgbuf (pop 0) (Push [g.ilg.typ_IntPtr]) (I_ldftn ilDelegeeInvokeMethOuter) + + // Instantiate the delegate + let ilDelegeeCtorMethOuter = mkCtorMethSpecForDelegate g.ilg (ilCtxtDelTy, useUIntPtrForDelegateCtor) CG.EmitInstr cgbuf (pop 2) (Push [ilCtxtDelTy]) (I_newobj(ilDelegeeCtorMethOuter, None)) GenSequel cenv eenvouter.cloc cgbuf sequel /// Generate statically-resolved conditionals used for type-directed optimizations. and GenStaticOptimization cenv cgbuf eenv (constraints, e2, e3, _m) sequel = + // Note: during IlxGen, even if answer is StaticOptimizationAnswer.Unknown we discard the static optimization + // This means 'when ^T : ^T' is discarded if not resolved. + // + // This doesn't apply when witnesses are available. In that case, "when ^T : ^T" is resolved as 'Yes', + // this is because all the uses of "when ^T : ^T" in FSharp.Core (e.g. for are for deciding between the + // witness-based implementation and the legacy dynamic implementation, e.g. + // + // let inline ( * ) (x: ^T) (y: ^U) : ^V = + // MultiplyDynamic<(^T),(^U),(^V)> x y + // ... + // when ^T : ^T = ((^T or ^U): (static member (*) : ^T * ^U -> ^V) (x,y)) + // + // When witnesses are not available we use the dynamic implementation. + let e = - if DecideStaticOptimizations cenv.g constraints = StaticOptimizationAnswer.Yes then e2 - else e3 + let generateWitnesses = ComputeGenerateWitnesses cenv.g eenv + if DecideStaticOptimizations cenv.g constraints generateWitnesses = StaticOptimizationAnswer.Yes then + e2 + else + e3 GenExpr cenv cgbuf eenv SPSuppress e sequel //------------------------------------------------------------------------- @@ -4840,11 +5650,15 @@ and GenJoinPoint cenv cgbuf pos eenv ty m sequel = Br afterJoin, afterJoin, stackAfterJoin, sequel // Accumulate the decision graph as we go -and GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets repeatSP sequel contf = - GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv tree targets repeatSP (IntMap.empty()) sequel (fun targetInfos -> - let sortedTargetInfos = - targetInfos +and GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets sequel contf = + let targetCounts = accTargetsOfDecisionTree tree [] |> List.countBy id |> Dictionary.ofList + let targetNext = ref 0 // used to make sure we generate the targets in-order, postponing if necessary + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv tree targets (targetNext, targetCounts) (IntMap.empty()) sequel (fun targetInfos -> + let sortedTargetInfos = + targetInfos |> Seq.sortBy (fun (KeyValue(targetIdx, _)) -> targetIdx) + |> Seq.filter (fun (KeyValue(_, (_, isTargetPostponed))) -> isTargetPostponed) + |> Seq.map (fun (KeyValue(_, (targetInfo, _))) -> targetInfo) |> List.ofSeq GenPostponedDecisionTreeTargets cenv cgbuf sortedTargetInfos stackAtTargets sequel contf ) @@ -4852,138 +5666,172 @@ and GenDecisionTreeAndTargets cenv cgbuf stackAtTargets eenv tree targets repeat and GenPostponedDecisionTreeTargets cenv cgbuf targetInfos stackAtTargets sequel contf = match targetInfos with | [] -> contf Fake - | (KeyValue(_, (targetInfo, isTargetPostponed))) :: rest -> - if isTargetPostponed then - let eenvAtTarget, spExprAtTarget, exprAtTarget, sequelAtTarget = GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel - GenLinearExpr cenv cgbuf eenvAtTarget spExprAtTarget exprAtTarget sequelAtTarget true (fun Fake -> - GenPostponedDecisionTreeTargets cenv cgbuf rest stackAtTargets sequel contf - ) - else + | targetInfo :: rest -> + let eenvAtTarget, spExprAtTarget, exprAtTarget, sequelAtTarget = GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel + GenLinearExpr cenv cgbuf eenvAtTarget spExprAtTarget exprAtTarget sequelAtTarget true (fun Fake -> GenPostponedDecisionTreeTargets cenv cgbuf rest stackAtTargets sequel contf - -and TryFindTargetInfo targetInfos n = - match IntMap.tryFind n targetInfos with - | Some (targetInfo, _) -> Some targetInfo - | None -> None + ) /// When inplabOpt is None, we are assuming a branch or fallthrough to the current code location /// /// When inplabOpt is "Some inplab", we are assuming an existing branch to "inplab" and can optionally /// set inplab to point to another location if no codegen is required. -and GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv tree targets repeatSP targetInfos sequel (contf: Zmap<_,_> -> FakeUnit) = +and GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv tree targets targetCounts targetInfos sequel (contf: Zmap<_,_> -> FakeUnit) = CG.SetStack cgbuf stackAtTargets // Set the expected initial stack. match tree with | TDBind(bind, rest) -> - match inplabOpt with Some inplab -> CG.SetMarkToHere cgbuf inplab | None -> () - let startScope, endScope as scopeMarks = StartDelayedLocalScope "dtreeBind" cgbuf + cgbuf.SetMarkToHereIfNecessary inplabOpt + let startMark, endMark as scopeMarks = StartDelayedLocalScope "dtreeBind" cgbuf let eenv = AllocStorageForBind cenv cgbuf scopeMarks eenv bind - let sp = GenSequencePointForBind cenv cgbuf bind - GenBindingAfterSequencePoint cenv cgbuf eenv sp bind (Some startScope) + let sp = GenDebugPointForBind cenv cgbuf bind + GenBindingAfterDebugPoint cenv cgbuf eenv sp bind false (Some startMark) + // We don't get the scope marks quite right for dtree-bound variables. This is because // we effectively lose an EndLocalScope for all dtrees that go to the same target // So we just pretend that the variable goes out of scope here. - CG.SetMarkToHere cgbuf endScope - GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv rest targets repeatSP targetInfos sequel contf + CG.SetMarkToHere cgbuf endMark + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv rest targets targetCounts targetInfos sequel contf | TDSuccess(es, targetIdx) -> - let targetInfos, genTargetInfoOpt = GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx targets repeatSP targetInfos sequel + let targetInfos, genTargetInfoOpt = GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx targets targetCounts targetInfos sequel match genTargetInfoOpt with | Some (eenvAtTarget, spExprAtTarget, exprAtTarget, sequelAtTarget) -> GenLinearExpr cenv cgbuf eenvAtTarget spExprAtTarget exprAtTarget sequelAtTarget true (fun Fake -> contf targetInfos) | _ -> contf targetInfos - | TDSwitch(e, cases, dflt, m) -> - GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases dflt m targets repeatSP targetInfos sequel contf + | TDSwitch(sp, e, cases, dflt, m) -> + + // Emit the debug point + match sp with + | DebugPointAtSwitch.Yes dpm -> CG.EmitDebugPoint cgbuf dpm + | DebugPointAtSwitch.No -> () + + GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases dflt m targets targetCounts targetInfos sequel contf and GetTarget (targets:_[]) n = if n >= targets.Length then failwith "GetTarget: target not found in decision tree" targets.[n] -and GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx targets repeatSP targetInfos sequel = - let (TTarget(vs, successExpr, spTarget)) = GetTarget targets targetIdx - match TryFindTargetInfo targetInfos targetIdx with - | Some (_, targetMarkAfterBinds: Mark, eenvAtTarget, _, _, _, _, _, _, _) -> +/// Generate a success node of a decision tree, binding the variables and going to the target +/// If inplabOpt is present, this label must get set to the first logical place to execute. +/// For example, if no variables get bound this can just be set to jump straight to the target. +and GenDecisionTreeSuccess cenv cgbuf inplabOpt stackAtTargets eenv es targetIdx targets (targetNext: int ref, targetCounts: Dictionary) targetInfos sequel = + let (TTarget(vs, successExpr, spTarget, stateVarFlagsOpt)) = GetTarget targets targetIdx + match IntMap.tryFind targetIdx targetInfos with + | Some (targetInfo, isTargetPostponed) -> + + let (targetMarkBeforeBinds, targetMarkAfterBinds: Mark, eenvAtTarget, _, _, _, _, _, _, _) = targetInfo - // If not binding anything we can go directly to the targetMarkAfterBinds point + // We have encountered this target before. See if we should generate it now + let targetCount = targetCounts.[targetIdx] + let generateTargetNow = isTargetPostponed && cenv.opts.localOptimizationsEnabled && targetCount = 1 && targetNext.Value = targetIdx + targetCounts.[targetIdx] <- targetCount - 1 + + // If not binding anything we can go directly to the targetMarkBeforeBinds point // This is useful to avoid lots of branches e.g. in match A | B | C -> e // In this case each case will just go straight to "e" if isNil vs then - match inplabOpt with - | None -> CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel) - | Some inplab -> CG.SetMark cgbuf inplab targetMarkAfterBinds + cgbuf.SetMarkOrEmitBranchIfNecessary (inplabOpt, targetMarkBeforeBinds) else - match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab - repeatSP() - // It would be better not to emit any expressions here, and instead push these assignments into the postponed target - // However not all targets are currently postponed (we only postpone in debug code), pending further testing of the performance - // impact of postponing. - (vs, es) ||> List.iter2 (GenBindingRhs cenv cgbuf eenv SPSuppress) - vs |> List.rev |> List.iter (fun v -> GenStoreVal cenv cgbuf eenvAtTarget v.Range v) + cgbuf.SetMarkToHereIfNecessary inplabOpt + cgbuf.EmitStartOfHiddenCode() + + (vs, es) ||> List.iter2 (fun v e -> + + GetStoreValCtxt cenv cgbuf eenvAtTarget v + // Emit the expression + GenBindingRhs cenv cgbuf eenv SPSuppress v e) + + vs |> List.rev |> List.iter (fun v -> + // Store the results + GenStoreVal cenv cgbuf eenvAtTarget v.Range v) + CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkAfterBinds.CodeLabel) + + let genTargetInfoOpt = + if generateTargetNow then + // Fenerate the targets in-order only + targetNext.Value <- targetNext.Value + 1 + Some(GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel) + else + None - targetInfos, None + // Update the targetInfos + let isTargetStillPostponed = isTargetPostponed && not generateTargetNow + let targetInfos = IntMap.add targetIdx (targetInfo, isTargetStillPostponed) targetInfos + targetInfos, genTargetInfoOpt | None -> + // We have not encountered this target before. Set up the generation of the target, even if we're + // going to postpone it - match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab let targetMarkBeforeBinds = CG.GenerateDelayMark cgbuf "targetBeforeBinds" let targetMarkAfterBinds = CG.GenerateDelayMark cgbuf "targetAfterBinds" - let startScope, endScope as scopeMarks = StartDelayedLocalScope "targetBinds" cgbuf - let binds = mkInvisibleBinds vs es + let startMark, endMark as scopeMarks = StartDelayedLocalScope "targetBinds" cgbuf + + // Allocate storage for variables (except those lifted to be state machine variables) + let binds = + match stateVarFlagsOpt with + | None -> mkInvisibleBinds vs es + | Some stateVarFlags -> + (vs, es, stateVarFlags) + |||> List.zip3 + |> List.choose (fun (v, e, isStateVar) -> if isStateVar then None else Some (mkInvisibleBind v e)) + let eenvAtTarget = AllocStorageForBinds cenv cgbuf scopeMarks eenv binds - let targetInfo = (targetMarkBeforeBinds, targetMarkAfterBinds, eenvAtTarget, successExpr, spTarget, repeatSP, vs, binds, startScope, endScope) - - // In debug mode push all decision tree targets to after the switching - let isTargetPostponed, genTargetInfoOpt = - if cenv.opts.localOptimizationsAreOn then - false, Some(GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel) + + let targetInfo = (targetMarkBeforeBinds, targetMarkAfterBinds, eenvAtTarget, successExpr, spTarget, vs, es, stateVarFlagsOpt, startMark, endMark) + + let targetCount = targetCounts.[targetIdx] + + // In debug mode, postpone all decision tree targets to after the switching. + // In release mode, if a target is the target of multiple incoming success nodes, postpone it to avoid + // making any backward branches + let generateTargetNow = cenv.opts.localOptimizationsEnabled && targetCount = 1 && targetNext.Value = targetIdx + targetCounts.[targetIdx] <- targetCount - 1 + + let genTargetInfoOpt = + if generateTargetNow then + // Here we are generating the target immediately + // Generate the targets in-order only + targetNext.Value <- targetNext.Value + 1 + cgbuf.SetMarkToHereIfNecessary inplabOpt + Some(GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel) else - CG.EmitInstr cgbuf (pop 0) Push0 (I_br targetMarkBeforeBinds.CodeLabel) - true, None + // Here we are postponing the generation of the target. + cgbuf.SetMarkOrEmitBranchIfNecessary (inplabOpt, targetMarkBeforeBinds) + None + let isTargetPostponed = not generateTargetNow let targetInfos = IntMap.add targetIdx (targetInfo, isTargetPostponed) targetInfos targetInfos, genTargetInfoOpt -and GenDecisionTreeTarget cenv cgbuf stackAtTargets (targetMarkBeforeBinds, targetMarkAfterBinds, eenvAtTarget, successExpr, spTarget, repeatSP, vs, binds, startScope, endScope) sequel = +and GenDecisionTreeTarget cenv cgbuf stackAtTargets targetInfo sequel = + let targetMarkBeforeBinds, targetMarkAfterBinds, eenvAtTarget, successExpr, spTarget, vs, es, stateVarFlagsOpt, startMark, endMark = targetInfo CG.SetMarkToHere cgbuf targetMarkBeforeBinds - let spExpr = (match spTarget with SequencePointAtTarget -> SPAlways | SuppressSequencePointAtTarget _ -> SPSuppress) + let spExpr = (match spTarget with DebugPointAtTarget.Yes -> SPAlways | DebugPointAtTarget.No _ -> SPSuppress) - // Repeat the sequence point to make sure each target branch has some sequence point (instead of inheriting - // a random sequence point from the previously generated IL code from the previous block. See comment on - // repeatSP() above. - // - // Only repeat the sequence point if we really have to, i.e. if the target expression doesn't start with a - // sequence point anyway - if isNil vs && DoesGenExprStartWithSequencePoint cenv.g spExpr successExpr then - () - else - match spTarget with - | SequencePointAtTarget -> repeatSP() - | SuppressSequencePointAtTarget -> cgbuf.EmitStartOfHiddenCode() + cgbuf.EmitStartOfHiddenCode() - CG.SetMarkToHere cgbuf startScope - GenBindings cenv cgbuf eenvAtTarget binds + CG.SetMarkToHere cgbuf startMark + let binds = mkInvisibleBinds vs es + GenBindings cenv cgbuf eenvAtTarget binds stateVarFlagsOpt CG.SetMarkToHere cgbuf targetMarkAfterBinds CG.SetStack cgbuf stackAtTargets - (eenvAtTarget, spExpr, successExpr, (EndLocalScope(sequel, endScope))) + (eenvAtTarget, spExpr, successExpr, (EndLocalScope(sequel, endMark))) -and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defaultTargetOpt switchm targets repeatSP targetInfos sequel contf = +and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defaultTargetOpt switchm targets targetCounts targetInfos sequel contf = let g = cenv.g let m = e.Range - match inplabOpt with None -> () | Some inplab -> CG.SetMarkToHere cgbuf inplab + cgbuf.SetMarkToHereIfNecessary inplabOpt - repeatSP() + cgbuf.EmitStartOfHiddenCode() match cases with // optimize a test against a boolean value, i.e. the all-important if-then-else | TCase(DecisionTreeTest.Const(Const.Bool b), successTree) :: _ -> let failureTree = (match defaultTargetOpt with None -> cases.Tail.Head.CaseTree | Some d -> d) - GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e None eenv (if b then successTree else failureTree) (if b then failureTree else successTree) targets repeatSP targetInfos sequel contf - - // // Remove a single test for a union case . Union case tests are always exa - //| [ TCase(DecisionTreeTest.UnionCase _, successTree) ] when (defaultTargetOpt.IsNone) -> - // GenDecisionTreeAndTargetsInner cenv cgbuf inplabOpt stackAtTargets eenv successTree targets repeatSP targetInfos sequel - // //GenDecisionTree cenv eenv.cloc cgbuf stackAtTargets e (Some (pop 1, Push [g.ilg.typ_Bool], Choice1Of2 (avoidHelpers, cuspec, idx))) eenv successTree failureTree targets repeatSP targetInfos sequel + GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e None false eenv (if b then successTree else failureTree) (if b then failureTree else successTree) targets targetCounts targetInfos sequel contf // Optimize a single test for a union case to an "isdata" test - much // more efficient code, and this case occurs in the generated equality testers where perf is important @@ -4995,7 +5843,19 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau let cuspec = GenUnionSpec cenv.amap m eenv.tyenv c.TyconRef tyargs let idx = c.Index let avoidHelpers = entityRefInThisAssembly g.compilingFslib c.TyconRef - GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e (Some (pop 1, Push [g.ilg.typ_Bool], Choice1Of2 (avoidHelpers, cuspec, idx))) eenv successTree failureTree targets repeatSP targetInfos sequel contf + let tester = (Some (pop 1, Push [g.ilg.typ_Bool], Choice1Of2 (avoidHelpers, cuspec, idx))) + GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e tester false eenv successTree failureTree targets targetCounts targetInfos sequel contf + + // Use GenDecisionTreeTest to generate a single test for null (when no box required) where the success + // is going to the immediate first node in the tree + | TCase(DecisionTreeTest.IsNull _, (TDSuccess([], 0) as successTree)) :: rest + when rest.Length = (match defaultTargetOpt with None -> 1 | Some _ -> 0) + && not (isTyparTy g (tyOfExpr g e)) -> + let failureTree = + match defaultTargetOpt with + | None -> rest.Head.CaseTree + | Some tg -> tg + GenDecisionTreeTest cenv eenv.cloc cgbuf stackAtTargets e None true eenv successTree failureTree targets targetCounts targetInfos sequel contf | _ -> let caseLabels = List.map (fun _ -> CG.GenerateDelayMark cgbuf "switch_case") cases @@ -5013,7 +5873,7 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau | DecisionTreeTest.Const(Const.Zero) -> GenExpr cenv cgbuf eenv SPSuppress e Continue BI_brfalse - | DecisionTreeTest.IsNull -> + | DecisionTreeTest.IsNull -> GenExpr cenv cgbuf eenv SPSuppress e Continue let srcTy = tyOfExpr g e if isTyparTy g srcTy then @@ -5026,8 +5886,8 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau BI_brtrue | _ -> failwith "internal error: GenDecisionTreeSwitch" CG.EmitInstr cgbuf (pop 1) Push0 (I_brcmp (bi, (List.head caseLabels).CodeLabel)) - GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets repeatSP targetInfos sequel caseLabels cases contf - + GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets targetCounts targetInfos sequel caseLabels cases contf + | DecisionTreeTest.ActivePatternCase _ -> error(InternalError("internal error in codegen: DecisionTreeTest.ActivePatternCase", switchm)) | DecisionTreeTest.UnionCase (hdc, tyargs) -> GenExpr cenv cgbuf eenv SPSuppress e Continue @@ -5038,21 +5898,21 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau match case with | TCase(DecisionTreeTest.UnionCase (c, _), _) -> (c.Index, label.CodeLabel) | _ -> failwith "error: mixed constructor/const test?") - + let avoidHelpers = entityRefInThisAssembly g.compilingFslib hdc.TyconRef EraseUnions.emitDataSwitch g.ilg (UnionCodeGen cgbuf) (avoidHelpers, cuspec, dests) CG.EmitInstrs cgbuf (pop 1) Push0 [ ] // push/pop to match the line above - GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets repeatSP targetInfos sequel caseLabels cases contf - + GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets targetCounts targetInfos sequel caseLabels cases contf + | DecisionTreeTest.Const c -> GenExpr cenv cgbuf eenv SPSuppress e Continue match c with | Const.Bool _ -> failwith "should have been done earlier" - | Const.SByte _ - | Const.Int16 _ - | Const.Int32 _ - | Const.Byte _ - | Const.UInt16 _ + | Const.SByte _ + | Const.Int16 _ + | Const.Int32 _ + | Const.Byte _ + | Const.UInt16 _ | Const.UInt32 _ | Const.Char _ -> if List.length cases <> List.length caseLabels then failwith "internal error: " @@ -5085,21 +5945,22 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau CG.EmitInstr cgbuf (pop 1) Push0 (I_switch destinationLabels) else error(InternalError("non-dense integer matches not implemented in codegen - these should have been removed by the pattern match compiler", switchm)) - GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets repeatSP targetInfos sequel caseLabels cases contf + GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets targetCounts targetInfos sequel caseLabels cases contf | _ -> error(InternalError("these matches should never be needed", switchm)) + | DecisionTreeTest.Error m -> error(InternalError("Trying to compile error recovery branch", m)) -and GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets repeatSP targetInfos sequel caseLabels cases (contf: Zmap<_,_> -> FakeUnit) = +and GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets targetCounts targetInfos sequel caseLabels cases (contf: Zmap<_,_> -> FakeUnit) = match defaultTargetOpt with - | Some defaultTarget -> - GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv defaultTarget targets repeatSP targetInfos sequel (fun targetInfos -> - GenDecisionTreeCases cenv cgbuf stackAtTargets eenv None targets repeatSP targetInfos sequel caseLabels cases contf + | Some defaultTarget -> + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv defaultTarget targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeCases cenv cgbuf stackAtTargets eenv None targets targetCounts targetInfos sequel caseLabels cases contf ) | None -> match caseLabels, cases with - | caseLabel :: caseLabelsTail, (TCase(_, caseTree)) :: casesTail -> - GenDecisionTreeAndTargetsInner cenv cgbuf (Some caseLabel) stackAtTargets eenv caseTree targets repeatSP targetInfos sequel (fun targetInfos -> - GenDecisionTreeCases cenv cgbuf stackAtTargets eenv None targets repeatSP targetInfos sequel caseLabelsTail casesTail contf + | caseLabel :: caseLabelsTail, TCase(_, caseTree) :: casesTail -> + GenDecisionTreeAndTargetsInner cenv cgbuf (Some caseLabel) stackAtTargets eenv caseTree targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeCases cenv cgbuf stackAtTargets eenv None targets targetCounts targetInfos sequel caseLabelsTail casesTail contf ) | _ -> contf targetInfos @@ -5107,7 +5968,7 @@ and GenDecisionTreeCases cenv cgbuf stackAtTargets eenv defaultTargetOpt targets // Used for the peephole optimization below and (|BoolExpr|_|) = function Expr.Const (Const.Bool b1, _, _) -> Some b1 | _ -> None -and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree failureTree targets repeatSP targetInfos sequel contf = +and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester isNullTest eenv successTree failureTree targets targetCounts targetInfos sequel contf = let g = cenv.g match successTree, failureTree with @@ -5115,14 +5976,15 @@ and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree // This comes up in the generated equality functions. REVIEW: do this as a peephole optimization elsewhere | TDSuccess(es1, n1), TDSuccess(es2, n2) when + not isNullTest && isNil es1 && isNil es2 && (match GetTarget targets n1, GetTarget targets n2 with - | TTarget(_, BoolExpr b1, _), TTarget(_, BoolExpr b2, _) -> b1 = not b2 + | TTarget(_, BoolExpr b1, _, _), TTarget(_, BoolExpr b2, _, _) -> b1 = not b2 | _ -> false) -> match GetTarget targets n1, GetTarget targets n2 with - | TTarget(_, BoolExpr b1, _), _ -> + | TTarget(_, BoolExpr b1, _, _), _ -> GenExpr cenv cgbuf eenv SPSuppress e Continue match tester with | Some (pops, pushes, i) -> @@ -5139,26 +6001,58 @@ and GenDecisionTreeTest cenv cloc cgbuf stackAtTargets e tester eenv successTree | _ -> failwith "internal error: GenDecisionTreeTest during bool elim" | _ -> - let failure = CG.GenerateDelayMark cgbuf "testFailure" match tester with | None -> - // generate the expression, then test it for "false" - GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, [ I_brcmp (BI_brfalse, failure.CodeLabel) ])) + + // Check if there is more logic in the decision tree for the failure branch + // (and no more logic for the success branch), for example + // when emitting the first part of 'expr1 || expr2'. + // + // If so, emit the failure logic, then came back and do the success target, then + // do any postponed failure target. + match successTree, failureTree with + | TDSuccess _, (TDBind _ | TDSwitch _) -> + + // OK, there is more logic in the decision tree on the failure branch + let success = CG.GenerateDelayMark cgbuf "testSuccess" + let testForSuccess = if isNullTest then BI_brfalse else BI_brtrue + GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, [ I_brcmp (testForSuccess, success.CodeLabel) ])) + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv failureTree targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeAndTargetsInner cenv cgbuf (Some success) stackAtTargets eenv successTree targets targetCounts targetInfos sequel contf + ) + + | _ -> + + // Either we're not yet done with the success branch, or there is no more logic + // in the decision tree on the failure branch. Continue doing the success branch + // logic first. + let failure = CG.GenerateDelayMark cgbuf "testFailure" + let testForFailure = if isNullTest then BI_brtrue else BI_brfalse + GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, [ I_brcmp (testForFailure, failure.CodeLabel) ])) + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv successTree targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeAndTargetsInner cenv cgbuf (Some failure) stackAtTargets eenv failureTree targets targetCounts targetInfos sequel contf + ) // Turn 'isdata' tests that branch into EI_brisdata tests | Some (_, _, Choice1Of2 (avoidHelpers, cuspec, idx)) -> + let failure = CG.GenerateDelayMark cgbuf "testFailure" GenExpr cenv cgbuf eenv SPSuppress e (CmpThenBrOrContinue(pop 1, EraseUnions.mkBrIsData g.ilg false (avoidHelpers, cuspec, idx, failure.CodeLabel))) + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv successTree targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeAndTargetsInner cenv cgbuf (Some failure) stackAtTargets eenv failureTree targets targetCounts targetInfos sequel contf + ) + | Some (pops, pushes, i) -> + let failure = CG.GenerateDelayMark cgbuf "testFailure" GenExpr cenv cgbuf eenv SPSuppress e Continue match i with | Choice1Of2 (avoidHelpers, cuspec, idx) -> CG.EmitInstrs cgbuf pops pushes (EraseUnions.mkIsData g.ilg (avoidHelpers, cuspec, idx)) | Choice2Of2 i -> CG.EmitInstr cgbuf pops pushes i CG.EmitInstr cgbuf (pop 1) Push0 (I_brcmp (BI_brfalse, failure.CodeLabel)) - GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv successTree targets repeatSP targetInfos sequel (fun targetInfos -> - GenDecisionTreeAndTargetsInner cenv cgbuf (Some failure) stackAtTargets eenv failureTree targets repeatSP targetInfos sequel contf - ) + GenDecisionTreeAndTargetsInner cenv cgbuf None stackAtTargets eenv successTree targets targetCounts targetInfos sequel (fun targetInfos -> + GenDecisionTreeAndTargetsInner cenv cgbuf (Some failure) stackAtTargets eenv failureTree targets targetCounts targetInfos sequel contf + ) /// Generate fixups for letrec bindings and GenLetRecFixup cenv cgbuf eenv (ilxCloSpec: IlxClosureSpec, e, ilField: ILFieldSpec, e2, _m) = @@ -5177,26 +6071,31 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) = | StaticProperty _ | Method _ // Note: Recursive data stored in static fields may require fixups e.g. let x = C(x) - // | StaticField _ + // | StaticPropertyWithField _ | Null -> false | _ -> true) - let computeFixupsForOneRecursiveVar boundv forwardReferenceSet fixups selfv access set e = + let computeFixupsForOneRecursiveVar boundv forwardReferenceSet (fixups: _ ref) thisVars access set e = match e with | Expr.Lambda _ | Expr.TyLambda _ | Expr.Obj _ -> - let isLocalTypeFunc = Option.isSome selfv && (IsNamedLocalTypeFuncVal cenv.g (Option.get selfv) e) - let selfv = (match e with Expr.Obj _ -> None | _ when isLocalTypeFunc -> None | _ -> Option.map mkLocalValRef selfv) - let clo, _, eenvclo = GetIlxClosureInfo cenv m isLocalTypeFunc selfv {eenv with letBoundVars=(mkLocalValRef boundv) :: eenv.letBoundVars} e - clo.cloFreeVars |> List.iter (fun fv -> + let isLocalTypeFunc = Option.isSome thisVars && (IsNamedLocalTypeFuncVal cenv.g (Option.get thisVars) e) + let thisVars = (match e with Expr.Obj _ -> [] | _ when isLocalTypeFunc -> [] | _ -> Option.map mkLocalValRef thisVars |> Option.toList) + let canUseStaticField = (match e with Expr.Obj _ -> false | _ -> true) + let clo, _, eenvclo = GetIlxClosureInfo cenv m ILBoxity.AsObject isLocalTypeFunc canUseStaticField thisVars {eenv with letBoundVars=(mkLocalValRef boundv) :: eenv.letBoundVars} e + for fv in clo.cloFreeVars do if Zset.contains fv forwardReferenceSet then match StorageForVal cenv.g m fv eenvclo with - | Env (_, _, ilField, _) -> fixups := (boundv, fv, (fun () -> GenLetRecFixup cenv cgbuf eenv (clo.cloSpec, access, ilField, exprForVal m fv, m))) :: !fixups - | _ -> error (InternalError("GenLetRec: " + fv.LogicalName + " was not in the environment", m)) ) - + | Env (_, ilField, _) -> + let fixup = (boundv, fv, (fun () -> GenLetRecFixup cenv cgbuf eenv (clo.cloSpec, access, ilField, exprForVal m fv, m))) + fixups.Value <- fixup :: fixups.Value + | _ -> error (InternalError("GenLetRec: " + fv.LogicalName + " was not in the environment", m)) + | Expr.Val (vref, _, _) -> let fv = vref.Deref let needsFixup = Zset.contains fv forwardReferenceSet - if needsFixup then fixups := (boundv, fv, (fun () -> GenExpr cenv cgbuf eenv SPSuppress (set e) discard)) :: !fixups + if needsFixup then + let fixup = (boundv, fv, (fun () -> GenExpr cenv cgbuf eenv SPSuppress (set e) discard)) + fixups.Value <- fixup :: fixups.Value | _ -> failwith "compute real fixup vars" @@ -5216,32 +6115,42 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) = // Generate the actual bindings let _ = (recursiveVars, allBinds) ||> List.fold (fun forwardReferenceSet (bind: Binding) -> - GenBinding cenv cgbuf eenv bind + GenBinding cenv cgbuf eenv bind false + // Record the variable as defined let forwardReferenceSet = Zset.remove bind.Var forwardReferenceSet + // Execute and discard any fixups that can now be committed - fixups := !fixups |> List.filter (fun (boundv, fv, action) -> if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then true else (action(); false)) + let newFixups = + fixups.Value |> List.filter (fun (boundv, fv, action) -> + if (Zset.contains boundv forwardReferenceSet || Zset.contains fv forwardReferenceSet) then + true + else + action() + false) + fixups.Value <- newFixups + forwardReferenceSet) () and GenLetRec cenv cgbuf eenv (binds, body, m) sequel = - let _, endScope as scopeMarks = StartLocalScope "letrec" cgbuf + let _, endMark as scopeMarks = StartLocalScope "letrec" cgbuf let eenv = AllocStorageForBinds cenv cgbuf scopeMarks eenv binds GenLetRecBindings cenv cgbuf eenv (binds, m) - GenExpr cenv cgbuf eenv SPAlways body (EndLocalScope(sequel, endScope)) + GenExpr cenv cgbuf eenv SPAlways body (EndLocalScope(sequel, endMark)) //------------------------------------------------------------------------- // Generate simple bindings //------------------------------------------------------------------------- -and GenSequencePointForBind cenv cgbuf bind = - let _, pt, sp = ComputeSequencePointInfoForBinding cenv.g bind - pt |> Option.iter (CG.EmitSeqPoint cgbuf) +and GenDebugPointForBind cenv cgbuf bind = + let _, pt, sp = ComputeDebugPointForBinding cenv.g bind + pt |> Option.iter (CG.EmitDebugPoint cgbuf) sp -and GenBinding cenv cgbuf eenv bind = - let sp = GenSequencePointForBind cenv cgbuf bind - GenBindingAfterSequencePoint cenv cgbuf eenv sp bind None +and GenBinding cenv cgbuf eenv (bind: Binding) (isStateVar: bool) = + let sp = GenDebugPointForBind cenv cgbuf bind + GenBindingAfterDebugPoint cenv cgbuf eenv sp bind isStateVar None and ComputeMemberAccessRestrictedBySig eenv vspec = let isHidden = @@ -5257,23 +6166,26 @@ and ComputeMethodAccessRestrictedBySig eenv vspec = vspec.IsIncrClassGeneratedMember // compiler generated members for class function 'let' bindings get assembly visibility ComputeMemberAccess isHidden -and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) startScopeMarkOpt = +and GenBindingAfterDebugPoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) isStateVar startMarkOpt = let g = cenv.g // Record the closed reflection definition if publishing // There is no real reason we're doing this so late in the day match vspec.PublicPath, vspec.ReflectedDefinition with - | Some _, Some e -> cgbuf.mgbuf.AddReflectedDefinition(vspec, e) + | Some _, Some e when not isStateVar -> cgbuf.mgbuf.AddReflectedDefinition(vspec, e) | _ -> () - let eenv = {eenv with letBoundVars= (mkLocalValRef vspec) :: eenv.letBoundVars} + let eenv = + if isStateVar then eenv + else { eenv with letBoundVars = (mkLocalValRef vspec) :: eenv.letBoundVars; + initLocals = eenv.initLocals && (match vspec.ApparentEnclosingEntity with Parent ref -> not (HasFSharpAttribute g g.attrib_SkipLocalsInitAttribute ref.Attribs) | _ -> true) } let access = ComputeMethodAccessRestrictedBySig eenv vspec // Workaround for .NET and Visual Studio restriction w.r.t debugger type proxys // Mark internal constructors in internal classes as public. let access = - if access = ILMemberAccess.Assembly && vspec.IsConstructor && IsHiddenTycon g eenv.sigToImplRemapInfo vspec.MemberApparentEntity.Deref then + if access = ILMemberAccess.Assembly && vspec.IsConstructor && IsHiddenTycon eenv.sigToImplRemapInfo vspec.MemberApparentEntity.Deref then ILMemberAccess.Public else access @@ -5284,34 +6196,40 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s | Null -> GenExpr cenv cgbuf eenv SPSuppress rhsExpr discard - CommitStartScope cgbuf startScopeMarkOpt + CommitStartScope cgbuf startMarkOpt // The initialization code for static 'let' and 'do' bindings gets compiled into the initialization .cctor for the whole file - | _ when vspec.IsClassConstructor && isNil vspec.TopValDeclaringEntity.TyparsNoRange -> + | _ when vspec.IsClassConstructor && isNil vspec.TopValDeclaringEntity.TyparsNoRange && not isStateVar -> let tps, _, _, _, cctorBody, _ = IteratedAdjustArityOfLambda g cenv.amap vspec.ValReprInfo.Value rhsExpr let eenv = EnvForTypars tps eenv - CommitStartScope cgbuf startScopeMarkOpt + CommitStartScope cgbuf startMarkOpt GenExpr cenv cgbuf eenv SPSuppress cctorBody discard - | Method (topValInfo, _, mspec, _, paramInfos, methodArgTys, retInfo) -> - let tps, ctorThisValOpt, baseValOpt, vsl, body', bodyty = IteratedAdjustArityOfLambda g cenv.amap topValInfo rhsExpr - let methodVars = List.concat vsl - CommitStartScope cgbuf startScopeMarkOpt - - let ilxMethInfoArgs = - (vspec, mspec, access, paramInfos, retInfo, topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body', bodyty) - // if we have any expression recursion depth, we should delay the generation of a method to prevent stack overflows - if cenv.exprRecursionDepth > 0 then - DelayGenMethodForBinding cenv cgbuf.mgbuf eenv ilxMethInfoArgs - else - GenMethodForBinding cenv cgbuf.mgbuf eenv ilxMethInfoArgs + | Method (topValInfo, _, mspec, mspecW, _, ctps, mtps, curriedArgInfos, paramInfos, witnessInfos, argTys, retInfo) when not isStateVar -> + + let methLambdaTypars, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaCurriedVars, methLambdaBody, methLambdaBodyTy = + IteratedAdjustArityOfLambda g cenv.amap topValInfo rhsExpr + + let methLambdaVars = List.concat methLambdaCurriedVars + + CommitStartScope cgbuf startMarkOpt + + let hasWitnessEntry = cenv.g.generateWitnesses && not witnessInfos.IsEmpty - | StaticProperty (ilGetterMethSpec, optShadowLocal) -> + GenMethodForBinding cenv cgbuf.mgbuf eenv (vspec, mspec, hasWitnessEntry, false, access, ctps, mtps, [], curriedArgInfos, paramInfos, argTys, retInfo, topValInfo, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaTypars, methLambdaVars, methLambdaBody, methLambdaBodyTy) + + // If generating witnesses, then generate the second entry point with additional arguments. + // Take a copy of the expression to ensure generated names are unique. + if hasWitnessEntry then + let copyOfLambdaBody = copyExpr cenv.g CloneAll methLambdaBody + GenMethodForBinding cenv cgbuf.mgbuf eenv (vspec, mspecW, hasWitnessEntry, true, access, ctps, mtps, witnessInfos, curriedArgInfos, paramInfos, argTys, retInfo, topValInfo, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaTypars, methLambdaVars, copyOfLambdaBody, methLambdaBodyTy) + + | StaticProperty (ilGetterMethSpec, optShadowLocal) when not isStateVar -> let ilAttribs = GenAttrs cenv eenv vspec.Attribs let ilTy = ilGetterMethSpec.FormalReturnType let ilPropDef = - ILPropertyDef(name = PrettyNaming.ChopPropertyName ilGetterMethSpec.Name, + ILPropertyDef(name = ChopPropertyName ilGetterMethSpec.Name, attributes = PropertyAttributes.None, setMethod = None, getMethod = Some ilGetterMethSpec.MethodRef, @@ -5320,26 +6238,31 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s init = None, args = [], customAttrs = mkILCustomAttrs ilAttribs) + cgbuf.mgbuf.AddOrMergePropertyDef(ilGetterMethSpec.MethodRef.DeclaringTypeRef, ilPropDef, m) let ilMethodDef = - let ilMethodBody = MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], ilGetterMethSpec.Name, eenv, 0, rhsExpr, Return)) + let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], ilGetterMethSpec.Name, eenv, 0, None, rhsExpr, Return) + let ilMethodBody = MethodBody.IL(lazy ilCode) (mkILStaticMethod ([], ilGetterMethSpec.Name, access, [], mkILReturn ilTy, ilMethodBody)).WithSpecialName |> AddNonUserCompilerGeneratedAttribs g CountMethodDef() cgbuf.mgbuf.AddMethodDef(ilGetterMethSpec.MethodRef.DeclaringTypeRef, ilMethodDef) - CommitStartScope cgbuf startScopeMarkOpt + CommitStartScope cgbuf startMarkOpt + match optShadowLocal with | NoShadowLocal -> () - | ShadowLocal storage -> + + | ShadowLocal (startMark, storage) -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None)) GenSetStorage m cgbuf storage + cgbuf.SetMarkToHere startMark - | StaticField (fspec, vref, hasLiteralAttr, ilTyForProperty, ilPropName, fty, ilGetterMethRef, ilSetterMethRef, optShadowLocal) -> + | StaticPropertyWithField (fspec, vref, hasLiteralAttr, ilTyForProperty, ilPropName, fty, ilGetterMethRef, ilSetterMethRef, optShadowLocal) -> let mut = vspec.IsMutable - + let canTarget(targets, goal: System.AttributeTargets) = match targets with | None -> true @@ -5353,7 +6276,7 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s match vref.LiteralValue with | Some konst -> ilFieldDef.WithLiteralDefaultValue( Some (GenFieldInit m konst) ) | None -> ilFieldDef - + let ilFieldDef = let isClassInitializer = (cgbuf.MethodName = ".cctor") ilFieldDef.WithInitOnly(not (mut || cenv.opts.isInteractiveItExpr || not isClassInitializer || hasLiteralAttr)) @@ -5369,15 +6292,20 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s let ilFieldDef = ilFieldDef.With(customAttrs = mkILCustomAttrs (ilAttribs @ [ g.DebuggerBrowsableNeverAttribute ])) [ (fspec.DeclaringTypeRef, ilFieldDef) ] - + let ilTypeRefForProperty = ilTyForProperty.TypeRef - for (tref, ilFieldDef) in ilFieldDefs do + for tref, ilFieldDef in ilFieldDefs do cgbuf.mgbuf.AddFieldDef(tref, ilFieldDef) CountStaticFieldDef() // ... and the get/set properties to access it. - if not hasLiteralAttr then + if hasLiteralAttr then + match optShadowLocal with + | NoShadowLocal -> () + | ShadowLocal (startMark, _storage) -> + cgbuf.SetMarkToHere startMark + else let ilAttribs = vspec.Attribs |> List.filter (fun (Attrib(_, _, _, _, _, targets, _)) -> canTarget(targets, System.AttributeTargets.Property)) @@ -5395,37 +6323,48 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s cgbuf.mgbuf.AddOrMergePropertyDef(ilTypeRefForProperty, ilPropDef, m) let getterMethod = - mkILStaticMethod([], ilGetterMethRef.Name, access, [], mkILReturn fty, - mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkNormalLdsfld fspec ], None)).WithSpecialName + let body = mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkNormalLdsfld fspec ], None, eenv.imports) + mkILStaticMethod([], ilGetterMethRef.Name, access, [], mkILReturn fty, body).WithSpecialName + cgbuf.mgbuf.AddMethodDef(ilTypeRefForProperty, getterMethod) + if mut || cenv.opts.isInteractiveItExpr then + let body = mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkLdarg0;mkNormalStsfld fspec], None, eenv.imports) let setterMethod = - mkILStaticMethod([], ilSetterMethRef.Name, access, [mkILParamNamed("value", fty)], mkILReturn ILType.Void, - mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkLdarg0;mkNormalStsfld fspec], None)).WithSpecialName + mkILStaticMethod([], ilSetterMethRef.Name, access, [mkILParamNamed("value", fty)], mkILReturn ILType.Void, body).WithSpecialName cgbuf.mgbuf.AddMethodDef(ilTypeRefForProperty, setterMethod) GenBindingRhs cenv cgbuf eenv sp vspec rhsExpr + CommitStartScope cgbuf startMarkOpt + match optShadowLocal with | NoShadowLocal -> - CommitStartScope cgbuf startScopeMarkOpt EmitSetStaticField cgbuf fspec - | ShadowLocal storage-> - CommitStartScope cgbuf startScopeMarkOpt + + | ShadowLocal (startMark, storage) -> CG.EmitInstr cgbuf (pop 0) (Push [fty]) AI_dup EmitSetStaticField cgbuf fspec GenSetStorage m cgbuf storage + cgbuf.SetMarkToHere startMark | _ -> let storage = StorageForVal cenv.g m vspec eenv match storage, rhsExpr with // locals are zero-init, no need to initialize them, except if you are in a loop and the local is mutable. | Local (_, realloc, _), Expr.Const (Const.Zero, _, _) when not realloc && not (eenv.isInLoop && vspec.IsMutable) -> - CommitStartScope cgbuf startScopeMarkOpt + CommitStartScope cgbuf startMarkOpt | _ -> + GetStoreValCtxt cenv cgbuf eenv vspec GenBindingRhs cenv cgbuf eenv SPSuppress vspec rhsExpr - CommitStartScope cgbuf startScopeMarkOpt + CommitStartScope cgbuf startMarkOpt GenStoreVal cenv cgbuf eenv vspec.Range vspec +and GetStoreValCtxt cenv cgbuf eenv (vspec: Val) = + // Emit the ldarg0 if needed + match StorageForVal cenv.g vspec.Range vspec eenv with + | Env (ilCloTy, _, _) -> CG.EmitInstr cgbuf (pop 0) (Push [ilCloTy]) mkLdarg0 + | _ -> () + //------------------------------------------------------------------------- // Generate method bindings //------------------------------------------------------------------------- @@ -5476,46 +6415,46 @@ and GenMarshal cenv attribs = match decoder.FindInt32 "SafeArraySubType" 0x0 with (* enumeration values for System.Runtime.InteropServices.VarType taken from mscorlib.il *) | 0x0 -> ILNativeVariant.Empty - | 0x1 -> ILNativeVariant.Null - | 0x02 -> ILNativeVariant.Int16 - | 0x03 -> ILNativeVariant.Int32 - | 0x0C -> ILNativeVariant.Variant - | 0x04 -> ILNativeVariant.Single - | 0x05 -> ILNativeVariant.Double - | 0x06 -> ILNativeVariant.Currency - | 0x07 -> ILNativeVariant.Date - | 0x08 -> ILNativeVariant.BSTR - | 0x09 -> ILNativeVariant.IDispatch - | 0x0a -> ILNativeVariant.Error - | 0x0b -> ILNativeVariant.Bool - | 0x0d -> ILNativeVariant.IUnknown - | 0x0e -> ILNativeVariant.Decimal - | 0x10 -> ILNativeVariant.Int8 - | 0x11 -> ILNativeVariant.UInt8 - | 0x12 -> ILNativeVariant.UInt16 - | 0x13 -> ILNativeVariant.UInt32 - | 0x15 -> ILNativeVariant.UInt64 - | 0x16 -> ILNativeVariant.Int - | 0x17 -> ILNativeVariant.UInt - | 0x18 -> ILNativeVariant.Void - | 0x19 -> ILNativeVariant.HRESULT - | 0x1a -> ILNativeVariant.PTR - | 0x1c -> ILNativeVariant.CArray - | 0x1d -> ILNativeVariant.UserDefined - | 0x1e -> ILNativeVariant.LPSTR - | 0x1B -> ILNativeVariant.SafeArray - | 0x1f -> ILNativeVariant.LPWSTR - | 0x24 -> ILNativeVariant.Record - | 0x40 -> ILNativeVariant.FileTime - | 0x41 -> ILNativeVariant.Blob - | 0x42 -> ILNativeVariant.Stream - | 0x43 -> ILNativeVariant.Storage - | 0x44 -> ILNativeVariant.StreamedObject - | 0x45 -> ILNativeVariant.StoredObject - | 0x46 -> ILNativeVariant.BlobObject - | 0x47 -> ILNativeVariant.CF - | 0x48 -> ILNativeVariant.CLSID - | 0x14 -> ILNativeVariant.Int64 + | 0x1 -> ILNativeVariant.Null + | 0x02 -> ILNativeVariant.Int16 + | 0x03 -> ILNativeVariant.Int32 + | 0x0C -> ILNativeVariant.Variant + | 0x04 -> ILNativeVariant.Single + | 0x05 -> ILNativeVariant.Double + | 0x06 -> ILNativeVariant.Currency + | 0x07 -> ILNativeVariant.Date + | 0x08 -> ILNativeVariant.BSTR + | 0x09 -> ILNativeVariant.IDispatch + | 0x0a -> ILNativeVariant.Error + | 0x0b -> ILNativeVariant.Bool + | 0x0d -> ILNativeVariant.IUnknown + | 0x0e -> ILNativeVariant.Decimal + | 0x10 -> ILNativeVariant.Int8 + | 0x11 -> ILNativeVariant.UInt8 + | 0x12 -> ILNativeVariant.UInt16 + | 0x13 -> ILNativeVariant.UInt32 + | 0x15 -> ILNativeVariant.UInt64 + | 0x16 -> ILNativeVariant.Int + | 0x17 -> ILNativeVariant.UInt + | 0x18 -> ILNativeVariant.Void + | 0x19 -> ILNativeVariant.HRESULT + | 0x1a -> ILNativeVariant.PTR + | 0x1c -> ILNativeVariant.CArray + | 0x1d -> ILNativeVariant.UserDefined + | 0x1e -> ILNativeVariant.LPSTR + | 0x1B -> ILNativeVariant.SafeArray + | 0x1f -> ILNativeVariant.LPWSTR + | 0x24 -> ILNativeVariant.Record + | 0x40 -> ILNativeVariant.FileTime + | 0x41 -> ILNativeVariant.Blob + | 0x42 -> ILNativeVariant.Stream + | 0x43 -> ILNativeVariant.Storage + | 0x44 -> ILNativeVariant.StreamedObject + | 0x45 -> ILNativeVariant.StoredObject + | 0x46 -> ILNativeVariant.BlobObject + | 0x47 -> ILNativeVariant.CF + | 0x48 -> ILNativeVariant.CLSID + | 0x14 -> ILNativeVariant.Int64 | _ -> ILNativeVariant.Empty let safeArrayUserDefinedSubType = // the argument is a System.Type obj, but it's written to MD as a UTF8 string @@ -5536,7 +6475,7 @@ and GenMarshal cenv attribs = let sizeParamIndex = match decoder.FindInt16 "SizeParamIndex" -1s with | -1s -> None - | res -> Some ((int)res, None) + | res -> Some (int res, None) let arraySubType = match decoder.FindInt32 "ArraySubType" -1 with | -1 -> None @@ -5580,81 +6519,103 @@ and GenParamAttribs cenv paramTy attribs = inFlag, outFlag, optionalFlag, defaultValue, Marshal, attribs /// Generate IL parameters -and GenParams cenv eenv (mspec: ILMethodSpec) (attribs: ArgReprInfo list) methodArgTys (implValsOpt: Val list option) = +and GenParams (cenv: cenv) eenv m (mspec: ILMethodSpec) witnessInfos (argInfos: ArgReprInfo list) methArgTys (implValsOpt: Val list option) = let g = cenv.g - let ilArgTys = mspec.FormalArgTypes - let argInfosAndTypes = - if List.length attribs = List.length ilArgTys then List.zip ilArgTys attribs - else ilArgTys |> List.map (fun ilArgTy -> ilArgTy, ValReprInfo.unnamedTopArg1) + let ilWitnessParams = GenWitnessParams cenv eenv m witnessInfos + let ilArgTys = mspec.FormalArgTypes |> List.skip witnessInfos.Length + + let ilArgTysAndInfos = + if argInfos.Length = ilArgTys.Length then + List.zip ilArgTys argInfos + else + assert false + ilArgTys |> List.map (fun ilArgTy -> ilArgTy, ValReprInfo.unnamedTopArg1) - let argInfosAndTypes = + let ilArgTysAndInfoAndVals = match implValsOpt with | Some implVals when (implVals.Length = ilArgTys.Length) -> - List.map2 (fun x y -> x, Some y) argInfosAndTypes implVals + List.map2 (fun x y -> x, Some y) ilArgTysAndInfos implVals | _ -> - List.map (fun x -> x, None) argInfosAndTypes - - (Set.empty, List.zip methodArgTys argInfosAndTypes) - ||> List.mapFold (fun takenNames (methodArgTy, ((ilArgTy, topArgInfo), implValOpt)) -> - let inFlag, outFlag, optionalFlag, defaultParamValue, Marshal, attribs = GenParamAttribs cenv methodArgTy topArgInfo.Attribs - - let idOpt = (match topArgInfo.Name with - | Some v -> Some v - | None -> match implValOpt with - | Some v -> Some v.Id - | None -> None) - - let nmOpt, takenNames = - match idOpt with - | Some id -> - let nm = - if takenNames.Contains(id.idText) then - // Ensure that we have an g.CompilerGlobalState - assert(g.CompilerGlobalState |> Option.isSome) - g.CompilerGlobalState.Value.NiceNameGenerator.FreshCompilerGeneratedName (id.idText, id.idRange) - else - id.idText - Some nm, takenNames.Add nm - | None -> - None, takenNames + List.map (fun x -> x, None) ilArgTysAndInfos + + let ilParams, _ = + (Set.empty, List.zip methArgTys ilArgTysAndInfoAndVals) + ||> List.mapFold (fun takenNames (methodArgTy, ((ilArgTy, topArgInfo), implValOpt)) -> + let inFlag, outFlag, optionalFlag, defaultParamValue, Marshal, attribs = GenParamAttribs cenv methodArgTy topArgInfo.Attribs + + let idOpt = + match topArgInfo.Name with + | Some v -> Some v + | None -> + match implValOpt with + | Some v -> Some v.Id + | None -> None + + let nmOpt, takenNames = + match idOpt with + | Some id -> + let nm = + if takenNames.Contains(id.idText) then + // Ensure that we have an g.CompilerGlobalState + assert(g.CompilerGlobalState |> Option.isSome) + g.CompilerGlobalState.Value.NiceNameGenerator.FreshCompilerGeneratedName (id.idText, id.idRange) + else + id.idText + Some nm, takenNames.Add(nm) + | None -> + None, takenNames - let ilAttribs = GenAttrs cenv eenv attribs - let ilAttribs = - match GenReadOnlyAttributeIfNecessary g methodArgTy with - | Some attr -> ilAttribs @ [attr] - | None -> ilAttribs + let ilAttribs = GenAttrs cenv eenv attribs - let param: ILParameter = - { Name=nmOpt - Type= ilArgTy - Default=defaultParamValue - Marshal=Marshal - IsIn=inFlag - IsOut=outFlag - IsOptional=optionalFlag - CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs) - MetadataIndex = NoMetadataIdx } - - param, takenNames) - |> fst + let ilAttribs = + match GenReadOnlyAttributeIfNecessary g methodArgTy with + | Some attr -> ilAttribs @ [attr] + | None -> ilAttribs + + let param : ILParameter = + { Name = nmOpt + Type = ilArgTy + Default = defaultParamValue + Marshal = Marshal + IsIn = inFlag + IsOut = outFlag + IsOptional = optionalFlag + CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs) + MetadataIndex = NoMetadataIdx } + + param, takenNames) + + ilWitnessParams @ ilParams /// Generate IL method return information -and GenReturnInfo cenv eenv ilRetTy (retInfo: ArgReprInfo) : ILReturn = +and GenReturnInfo cenv eenv returnTy ilRetTy (retInfo: ArgReprInfo) : ILReturn = let marshal, attribs = GenMarshal cenv retInfo.Attribs + let ilAttribs = GenAttrs cenv eenv attribs + + let ilAttribs = + match returnTy with + | Some retTy -> + match GenReadOnlyAttributeIfNecessary cenv.g retTy with + | Some attr -> ilAttribs @ [attr] + | None -> ilAttribs + | _ -> + ilAttribs + + let ilAttrs = mkILCustomAttrs ilAttribs { Type=ilRetTy Marshal=marshal - CustomAttrsStored= storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs)) + CustomAttrsStored= storeILCustomAttrs ilAttrs MetadataIndex = NoMetadataIdx } - + /// Generate an IL property for a member and GenPropertyForMethodDef compileAsInstance tref mdef (v: Val) (memberInfo: ValMemberInfo) ilArgTys ilPropTy ilAttrs compiledName = let name = match compiledName with | Some n -> n | _ -> v.PropertyName in (* chop "get_" *) ILPropertyDef(name = name, attributes = PropertyAttributes.None, - setMethod = (if memberInfo.MemberFlags.MemberKind= MemberKind.PropertySet then Some(mkRefToILMethod(tref, mdef)) else None), - getMethod = (if memberInfo.MemberFlags.MemberKind= MemberKind.PropertyGet then Some(mkRefToILMethod(tref, mdef)) else None), + setMethod = (if memberInfo.MemberFlags.MemberKind= SynMemberKind.PropertySet then Some(mkRefToILMethod(tref, mdef)) else None), + getMethod = (if memberInfo.MemberFlags.MemberKind= SynMemberKind.PropertyGet then Some(mkRefToILMethod(tref, mdef)) else None), callingConv = (if compileAsInstance then ILThisConvention.Instance else ILThisConvention.Static), propertyType = ilPropTy, init = None, @@ -5664,7 +6625,7 @@ and GenPropertyForMethodDef compileAsInstance tref mdef (v: Val) (memberInfo: Va /// Generate an ILEventDef for a [] member and GenEventForProperty cenv eenvForMeth (mspec: ILMethodSpec) (v: Val) ilAttrsThatGoOnPrimaryItem m returnTy = let evname = v.PropertyName - let delegateTy = Infos.FindDelegateTypeOfPropertyEvent cenv.g cenv.amap evname m returnTy + let delegateTy = FindDelegateTypeOfPropertyEvent cenv.g cenv.amap evname m returnTy let ilDelegateTy = GenType cenv.amap m eenvForMeth.tyenv delegateTy let ilThisTy = mspec.DeclaringType let addMethRef = mkILMethRef (ilThisTy.TypeRef, mspec.CallingConv, "add_" + evname, 0, [ilDelegateTy], ILType.Void) @@ -5678,43 +6639,53 @@ and GenEventForProperty cenv eenvForMeth (mspec: ILMethodSpec) (v: Val) ilAttrsT otherMethods= [], customAttrs = mkILCustomAttrs ilAttrsThatGoOnPrimaryItem) -and ComputeFlagFixupsForMemberBinding cenv (v: Val, memberInfo: ValMemberInfo) = - let g = cenv.g +and ComputeUseMethodImpl cenv (v: Val, slotsig: SlotSig) = + let oty = slotsig.ImplementedType + let otcref = tcrefOfAppTy cenv.g oty + let tcref = v.MemberApparentEntity + // REVIEW: it would be good to get rid of this special casing of Compare and GetHashCode during code generation + isInterfaceTy cenv.g oty && + (let isCompare = + Option.isSome tcref.GeneratedCompareToValues && + (typeEquiv cenv.g oty cenv.g.mk_IComparable_ty || + tyconRefEq cenv.g cenv.g.system_GenericIComparable_tcref otcref) + + not isCompare) && + + (let isGenericEquals = + Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq cenv.g cenv.g.system_GenericIEquatable_tcref otcref + + not isGenericEquals) && + (let isStructural = + (Option.isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralComparable_ty) || + (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralEquatable_ty) + + not isStructural) + +and ComputeMethodImplNameFixupForMemberBinding cenv (v: Val, memberInfo: ValMemberInfo) = if isNil memberInfo.ImplementedSlotSigs then - [fixupVirtualSlotFlags] + None else - memberInfo.ImplementedSlotSigs |> List.map (fun slotsig -> - let oty = slotsig.ImplementedType - let otcref = tcrefOfAppTy g oty - let tcref = v.MemberApparentEntity - - let useMethodImpl = - // REVIEW: it would be good to get rid of this special casing of Compare and GetHashCode during code generation - isInterfaceTy g oty && - (let isCompare = - Option.isSome tcref.GeneratedCompareToValues && - (typeEquiv g oty g.mk_IComparable_ty || - tyconRefEq g g.system_GenericIComparable_tcref otcref) - - not isCompare) && - - (let isGenericEquals = - Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq g g.system_GenericIEquatable_tcref otcref - - not isGenericEquals) && - (let isStructural = - (Option.isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv g oty g.mk_IStructuralComparable_ty) || - (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv g oty g.mk_IStructuralEquatable_ty) - - not isStructural) - - let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) + let slotsig = memberInfo.ImplementedSlotSigs |> List.last + let useMethodImpl = ComputeUseMethodImpl cenv (v, slotsig) + let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (useMethodImpl, slotsig) + Some nameOfOverridingMethod + +and ComputeFlagFixupsForMemberBinding cenv (v: Val, memberInfo: ValMemberInfo) = + [ if isNil memberInfo.ImplementedSlotSigs then + yield fixupVirtualSlotFlags + else + for slotsig in memberInfo.ImplementedSlotSigs do + let useMethodImpl = ComputeUseMethodImpl cenv (v, slotsig) if useMethodImpl then - fixupMethodImplFlags >> renameMethodDef nameOfOverridingMethod + yield fixupMethodImplFlags else - fixupVirtualSlotFlags >> renameMethodDef nameOfOverridingMethod) - + yield fixupVirtualSlotFlags + match ComputeMethodImplNameFixupForMemberBinding cenv (v, memberInfo) with + | Some nm -> yield renameMethodDef nm + | None -> () ] + and ComputeMethodImplAttribs cenv (_v: Val) attrs = let g = cenv.g let implflags = @@ -5743,41 +6714,63 @@ and ComputeMethodImplAttribs cenv (_v: Val) attrs = let hasAggressiveInliningImplFlag = (implflags &&& 0x0100) <> 0x0 hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningImplFlag, hasAggressiveInliningImplFlag, attrs -and DelayGenMethodForBinding cenv mgbuf eenv ilxMethInfoArgs = - cenv.delayedGenMethods.Enqueue (fun cenv -> GenMethodForBinding cenv mgbuf eenv ilxMethInfoArgs) - -and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, topValInfo, ctorThisValOpt, baseValOpt, tps, methodVars, methodArgTys, body, returnTy) = +and GenMethodForBinding + cenv mgbuf eenv + (v: Val, mspec, hasWitnessEntry, generateWitnessArgs, access, ctps, mtps, witnessInfos, curriedArgInfos, paramInfos, argTys, retInfo, topValInfo, + ctorThisValOpt, baseValOpt, methLambdaTypars, methLambdaVars, methLambdaBody, returnTy) = let g = cenv.g let m = v.Range + + // If a method has a witness-passing version of the code, then suppress + // the generation of any witness in the non-witness passing version of the code + let eenv = { eenv with suppressWitnesses = hasWitnessEntry && not generateWitnessArgs } + let selfMethodVars, nonSelfMethodVars, compileAsInstance = match v.MemberInfo with | Some _ when ValSpecIsCompiledAsInstance g v -> - match methodVars with + match methLambdaVars with | [] -> error(InternalError("Internal error: empty argument list for instance method", v.Range)) | h :: t -> [h], t, true - | _ -> [], methodVars, false + | _ -> [], methLambdaVars, false - let nonUnitNonSelfMethodVars, body = BindUnitVars g (nonSelfMethodVars, paramInfos, body) - let nonUnitMethodVars = selfMethodVars@nonUnitNonSelfMethodVars - let cmtps, curriedArgInfos, _, _ = GetTopValTypeInCompiledForm g topValInfo v.Type v.Range + let nonUnitNonSelfMethodVars, body = BindUnitVars cenv.g (nonSelfMethodVars, paramInfos, methLambdaBody) let eenv = bindBaseOrThisVarOpt cenv eenv ctorThisValOpt let eenv = bindBaseOrThisVarOpt cenv eenv baseValOpt // The type parameters of the method's type are different to the type parameters // for the big lambda ("tlambda") of the implementation of the method. - let eenvUnderMethLambdaTypars = EnvForTypars tps eenv - let eenvUnderMethTypeTypars = EnvForTypars cmtps eenv + let eenvUnderMethLambdaTypars = EnvForTypars methLambdaTypars eenv + let eenvUnderMethTypeClassTypars = EnvForTypars ctps eenv + let eenvUnderMethTypeTypars = AddTyparsToEnv mtps eenvUnderMethTypeClassTypars // Add the arguments to the environment. We add an implicit 'this' argument to constructors let isCtor = v.IsConstructor + + let methLambdaWitnessInfos = + if generateWitnessArgs then + GetTraitWitnessInfosOfTypars cenv.g ctps.Length methLambdaTypars + else + [] + + // If this assert fails then there is a mismatch in the number of trait constraints on the method type and the number + // on the method implementation. + assert (methLambdaWitnessInfos.Length = witnessInfos.Length) + let eenvForMeth = let eenvForMeth = eenvUnderMethLambdaTypars - let numImplicitArgs = if isCtor then 1 else 0 - let eenvForMeth = AddStorageForLocalVals g (List.mapi (fun i v -> (v, Arg (numImplicitArgs+i))) nonUnitMethodVars) eenvForMeth + let numArgsUsed = 0 + let numArgsUsed = numArgsUsed + (if isCtor then 1 else 0) + let eenvForMeth = eenvForMeth |> AddStorageForLocalVals cenv.g (selfMethodVars |> List.mapi (fun i v -> (v, Arg (numArgsUsed+i)))) + let numArgsUsed = numArgsUsed + selfMethodVars.Length + let eenvForMeth = eenvForMeth |> AddStorageForLocalWitnesses (methLambdaWitnessInfos |> List.mapi (fun i w -> (w, Arg (numArgsUsed+i)))) + let numArgsUsed = numArgsUsed + methLambdaWitnessInfos.Length + let eenvForMeth = eenvForMeth |> AddStorageForLocalVals cenv.g (List.mapi (fun i v -> (v, Arg (numArgsUsed+i))) nonUnitNonSelfMethodVars) + let eenvForMeth = if eenvForMeth.initLocals && HasFSharpAttribute g g.attrib_SkipLocalsInitAttribute v.Attribs then { eenvForMeth with initLocals = false } else eenvForMeth eenvForMeth - let tailCallInfo = [(mkLocalValRef v, BranchCallMethod (topValInfo.AritiesOfArgs, curriedArgInfos, tps, nonUnitMethodVars.Length, v.NumObjArgs))] + let tailCallInfo = + [(mkLocalValRef v, BranchCallMethod (topValInfo.AritiesOfArgs, curriedArgInfos, methLambdaTypars, selfMethodVars.Length, methLambdaWitnessInfos.Length, nonUnitNonSelfMethodVars.Length))] // Discard the result on a 'void' return type. For a constructor just return 'void' let sequel = @@ -5789,7 +6782,7 @@ and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, let hasPreserveSigNamedArg, ilMethodBody, hasDllImport = match TryFindFSharpAttributeOpt g g.attrib_DllImportAttribute v.Attribs with | Some (Attrib(_, _, [ AttribStringArg dll ], namedArgs, _, _, m)) -> - if not (isNil tps) then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(), m)) + if not (isNil methLambdaTypars) then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(), m)) let hasPreserveSigNamedArg, mbody = GenPInvokeMethod (v.CompiledName g.CompilerGlobalState, dll, namedArgs) hasPreserveSigNamedArg, mbody, true @@ -5798,29 +6791,47 @@ and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, | _ -> // Replace the body of ValInline.PseudoVal "must inline" methods with a 'throw' - // However still generate the code for reflection etc. + // For witness-passing methods, don't do this if `isLegacy` flag specified + // on the attribute. Older compilers let bodyExpr = - if HasFSharpAttribute g g.attrib_NoDynamicInvocationAttribute v.Attribs then - let exnArg = mkString g m (FSComp.SR.ilDynamicInvocationNotSupported(v.CompiledName g.CompilerGlobalState)) + let attr = TryFindFSharpBoolAttributeAssumeFalse cenv.g cenv.g.attrib_NoDynamicInvocationAttribute v.Attribs + if (not generateWitnessArgs && attr.IsSome) || + (generateWitnessArgs && attr = Some false) then + let exnArg = mkString cenv.g m (FSComp.SR.ilDynamicInvocationNotSupported(v.CompiledName g.CompilerGlobalState)) let exnExpr = MakeNotSupportedExnExpr cenv eenv (exnArg, m) mkThrow m returnTy exnExpr else body - - let ilCode = CodeGenMethodForExpr cenv mgbuf (SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0, bodyExpr, sequel) + + let selfValOpt = + match selfMethodVars with + | [h] -> Some h + | _ -> None + + let ilCodeLazy = lazy CodeGenMethodForExpr cenv mgbuf (SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0, selfValOpt, bodyExpr, sequel) // This is the main code generation for most methods - false, MethodBody.IL ilCode, false + false, MethodBody.IL(ilCodeLazy), false + + match ilMethodBody with + | MethodBody.IL(ilCodeLazy) -> + if cenv.exprRecursionDepth > 0 then + cenv.delayedGenMethods.Enqueue(fun _ -> ilCodeLazy.Force() |> ignore) + else + // Eagerly codegen if we are not in an expression depth. + ilCodeLazy.Force() |> ignore + | _ -> + () // Do not generate DllImport attributes into the code - they are implicit from the P/Invoke let attrs = v.Attribs |> List.filter (IsMatchingFSharpAttributeOpt g g.attrib_DllImportAttribute >> not) |> List.filter (IsMatchingFSharpAttribute g g.attrib_CompiledNameAttribute >> not) - + let attrsAppliedToGetterOrSetter, attrs = List.partition (fun (Attrib(_, _, _, _, isAppliedToGetterOrSetter, _, _)) -> isAppliedToGetterOrSetter) attrs - + let sourceNameAttribs, compiledName = match v.Attribs |> List.tryFind (IsMatchingFSharpAttribute g g.attrib_CompiledNameAttribute) with | Some (Attrib(_, _, [ AttribStringArg b ], _, _, _, _)) -> [ mkCompilationSourceNameAttr g v.LogicalName ], Some b @@ -5828,7 +6839,7 @@ and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, // check if the hasPreserveSigNamedArg and hasSynchronizedImplFlag implementation flags have been specified let hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningFlag, hasAggressiveInliningImplFlag, attrs = ComputeMethodImplAttribs cenv v attrs - + let securityAttributes, attrs = attrs |> List.partition (fun a -> IsSecurityAttribute g cenv.amap cenv.casApplied a m) let permissionSets = CreatePermissionSets cenv eenv securityAttributes @@ -5840,144 +6851,182 @@ and GenMethodForBinding cenv mgbuf eenv (v, mspec, access, paramInfos, retInfo, let ilAttrsThatGoOnPrimaryItem = [ yield! GenAttrs cenv eenv attrs - yield! GenCompilationArgumentCountsAttr cenv v ] - - let ilTypars = GenGenericParams cenv eenvUnderMethLambdaTypars tps - let ilParams = GenParams cenv eenv mspec paramInfos methodArgTys (Some nonUnitNonSelfMethodVars) - let ilReturn = GenReturnInfo cenv eenv mspec.FormalReturnType retInfo + yield! GenCompilationArgumentCountsAttr cenv v + + match v.MemberInfo with + | Some memberInfo when + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet -> + match GenReadOnlyAttributeIfNecessary g returnTy with Some ilAttr -> ilAttr | _ -> () + | _ -> () ] + + let ilTypars = GenGenericParams cenv eenvUnderMethLambdaTypars methLambdaTypars + let ilParams = GenParams cenv eenvUnderMethTypeTypars m mspec witnessInfos paramInfos argTys (Some nonUnitNonSelfMethodVars) + let ilReturn = GenReturnInfo cenv eenvUnderMethTypeTypars (Some returnTy) mspec.FormalReturnType retInfo let methName = mspec.Name let tref = mspec.MethodRef.DeclaringTypeRef - let EmitTheMethodDef (mdef: ILMethodDef) = - // Does the function have an explicit [] attribute? - let isExplicitEntryPoint = HasFSharpAttribute g g.attrib_EntryPointAttribute attrs - - let mdef = - mdef - .WithSecurity(not (List.isEmpty securityAttributes)) - .WithPInvoke(hasDllImport) - .WithPreserveSig(hasPreserveSigImplFlag || hasPreserveSigNamedArg) - .WithSynchronized(hasSynchronizedImplFlag) - .WithNoInlining(hasNoInliningFlag) - .WithAggressiveInlining(hasAggressiveInliningImplFlag) - .With(isEntryPoint=isExplicitEntryPoint, securityDecls=secDecls) - - let mdef = - if // operator names - mdef.Name.StartsWithOrdinal("op_") || - // active pattern names - mdef.Name.StartsWithOrdinal("|") || - // event add/remove method - v.val_flags.IsGeneratedEventVal then - mdef.WithSpecialName - else - mdef - CountMethodDef() - mgbuf.AddMethodDef(tref, mdef) - - match v.MemberInfo with // don't generate unimplemented abstracts | Some memberInfo when memberInfo.MemberFlags.IsDispatchSlot && not memberInfo.IsImplemented -> // skipping unimplemented abstract method () - | Some memberInfo when not v.IsExtensionMember -> - - let ilMethTypars = ilTypars |> List.drop mspec.DeclaringType.GenericArgs.Length - if memberInfo.MemberFlags.MemberKind = MemberKind.Constructor then - assert (isNil ilMethTypars) - let mdef = mkILCtor (access, ilParams, ilMethodBody) - let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) - EmitTheMethodDef mdef - - elif memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor then - assert (isNil ilMethTypars) - let mdef = mkILClassCtor ilMethodBody - let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) - EmitTheMethodDef mdef - - // Generate virtual/override methods + method-impl information if needed - else - let mdef = - if not compileAsInstance then - mkILStaticMethod (ilMethTypars, v.CompiledName g.CompilerGlobalState, access, ilParams, ilReturn, ilMethodBody) - elif (memberInfo.MemberFlags.IsDispatchSlot && memberInfo.IsImplemented) || - memberInfo.MemberFlags.IsOverrideOrExplicitImpl then + // compiling CLIEvent properties + | Some memberInfo + when not v.IsExtensionMember && + (match memberInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertySet | SynMemberKind.PropertyGet -> CompileAsEvent cenv.g v.Attribs + | _ -> false) -> - let flagFixups = ComputeFlagFixupsForMemberBinding cenv (v, memberInfo) - let mdef = mkILGenericVirtualMethod (v.CompiledName g.CompilerGlobalState, ILMemberAccess.Public, ilMethTypars, ilParams, ilReturn, ilMethodBody) - let mdef = List.fold (fun mdef f -> f mdef) mdef flagFixups + let useMethodImpl = + if compileAsInstance && + ((memberInfo.MemberFlags.IsDispatchSlot && memberInfo.IsImplemented) || + memberInfo.MemberFlags.IsOverrideOrExplicitImpl) then - // fixup can potentially change name of reflected definition that was already recorded - patch it if necessary - mgbuf.ReplaceNameOfReflectedDefinition(v, mdef.Name) - mdef - else - mkILGenericNonVirtualMethod (v.CompiledName g.CompilerGlobalState, access, ilMethTypars, ilParams, ilReturn, ilMethodBody) - - let isAbstract = - memberInfo.MemberFlags.IsDispatchSlot && - let tcref = v.MemberApparentEntity - not tcref.Deref.IsFSharpDelegateTycon - - let mdef = - if mdef.IsVirtual then - mdef.WithFinal(memberInfo.MemberFlags.IsFinal).WithAbstract(isAbstract) - else mdef - - match memberInfo.MemberFlags.MemberKind with - - | (MemberKind.PropertySet | MemberKind.PropertyGet) -> - if not (isNil ilMethTypars) then - error(InternalError("A property may not be more generic than the enclosing type - constrain the polymorphism in the expression", v.Range)) - - // Check if we're compiling the property as a .NET event - if CompileAsEvent g v.Attribs then + let useMethodImpl = memberInfo.ImplementedSlotSigs |> List.exists (fun slotsig -> ComputeUseMethodImpl cenv (v, slotsig)) + + let nameOfOverridingMethod = + match ComputeMethodImplNameFixupForMemberBinding cenv (v, memberInfo) with + | None -> mspec.Name + | Some nm -> nm + + // Fixup can potentially change name of reflected definition that was already recorded - patch it if necessary + mgbuf.ReplaceNameOfReflectedDefinition(v, nameOfOverridingMethod) + useMethodImpl + else + false + + // skip method generation for compiling the property as a .NET event + // Instead emit the pseudo-property as an event. + // on't do this if it's a private method impl. + if not useMethodImpl then + let edef = GenEventForProperty cenv eenvForMeth mspec v ilAttrsThatGoOnPrimaryItem m returnTy + mgbuf.AddEventDef(tref, edef) + + | _ -> + + let mdef = + match v.MemberInfo with + | Some memberInfo when not v.IsExtensionMember -> + + let ilMethTypars = ilTypars |> List.skip mspec.DeclaringType.GenericArgs.Length + if memberInfo.MemberFlags.MemberKind = SynMemberKind.Constructor then + assert (isNil ilMethTypars) + let mdef = mkILCtor (access, ilParams, ilMethodBody) + let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) + mdef + + elif memberInfo.MemberFlags.MemberKind = SynMemberKind.ClassConstructor then + assert (isNil ilMethTypars) + let mdef = mkILClassCtor ilMethodBody + let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) + mdef + + // Generate virtual/override methods + method-impl information if needed + else + let mdef = + if not compileAsInstance then + mkILStaticMethod (ilMethTypars, mspec.Name, access, ilParams, ilReturn, ilMethodBody) + + elif (memberInfo.MemberFlags.IsDispatchSlot && memberInfo.IsImplemented) || + memberInfo.MemberFlags.IsOverrideOrExplicitImpl then + + let flagFixups = ComputeFlagFixupsForMemberBinding cenv (v, memberInfo) + let mdef = mkILGenericVirtualMethod (mspec.Name, ILMemberAccess.Public, ilMethTypars, ilParams, ilReturn, ilMethodBody) + let mdef = List.fold (fun mdef f -> f mdef) mdef flagFixups + + // fixup can potentially change name of reflected definition that was already recorded - patch it if necessary + mgbuf.ReplaceNameOfReflectedDefinition(v, mdef.Name) + mdef + else + mkILGenericNonVirtualMethod (mspec.Name, access, ilMethTypars, ilParams, ilReturn, ilMethodBody) + + let isAbstract = + memberInfo.MemberFlags.IsDispatchSlot && + let tcref = v.MemberApparentEntity + not tcref.Deref.IsFSharpDelegateTycon + + let mdef = + if mdef.IsVirtual then + mdef.WithFinal(memberInfo.MemberFlags.IsFinal).WithAbstract(isAbstract) + else mdef + + match memberInfo.MemberFlags.MemberKind with + + | SynMemberKind.PropertySet | SynMemberKind.PropertyGet -> + if not (isNil ilMethTypars) then + error(InternalError("A property may not be more generic than the enclosing type - constrain the polymorphism in the expression", v.Range)) + + // Check if we're compiling the property as a .NET event + assert not (CompileAsEvent cenv.g v.Attribs) - // Emit the pseudo-property as an event, but not if its a private method impl - if mdef.Access <> ILMemberAccess.Private then - let edef = GenEventForProperty cenv eenvForMeth mspec v ilAttrsThatGoOnPrimaryItem m returnTy - mgbuf.AddEventDef(tref, edef) - // The method def is dropped on the floor here - - else // Emit the property, but not if its a private method impl if mdef.Access <> ILMemberAccess.Private then let vtyp = ReturnTypeOfPropertyVal g v let ilPropTy = GenType cenv.amap m eenvUnderMethTypeTypars.tyenv vtyp + let ilPropTy = GenReadOnlyModReqIfNecessary g vtyp ilPropTy let ilArgTys = v |> ArgInfosOfPropertyVal g |> List.map fst |> GenTypes cenv.amap m eenvUnderMethTypeTypars.tyenv let ilPropDef = GenPropertyForMethodDef compileAsInstance tref mdef v memberInfo ilArgTys ilPropTy (mkILCustomAttrs ilAttrsThatGoOnPrimaryItem) compiledName mgbuf.AddOrMergePropertyDef(tref, ilPropDef, m) - // Add the special name flag for all properties + // Add the special name flag for all properties let mdef = mdef.WithSpecialName.With(customAttrs= mkILCustomAttrs ((GenAttrs cenv eenv attrsAppliedToGetterOrSetter) @ sourceNameAttribs @ ilAttrsCompilerGenerated)) - EmitTheMethodDef mdef - | _ -> - let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) - EmitTheMethodDef mdef + mdef - | _ -> - let mdef = mkILStaticMethod (ilTypars, methName, access, ilParams, ilReturn, ilMethodBody) + | _ -> + let mdef = mdef.With(customAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated)) + mdef + + | _ -> + let mdef = mkILStaticMethod (ilTypars, methName, access, ilParams, ilReturn, ilMethodBody) + + // For extension properties, also emit attrsAppliedToGetterOrSetter on the getter or setter method + let ilAttrs = + match v.MemberInfo with + | Some memberInfo when v.IsExtensionMember -> + match memberInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertySet | SynMemberKind.PropertyGet -> ilAttrsThatGoOnPrimaryItem @ GenAttrs cenv eenv attrsAppliedToGetterOrSetter + | _ -> ilAttrsThatGoOnPrimaryItem + | _ -> ilAttrsThatGoOnPrimaryItem + + let ilCustomAttrs = mkILCustomAttrs (ilAttrs @ sourceNameAttribs @ ilAttrsCompilerGenerated) + let mdef = mdef.With(customAttrs= ilCustomAttrs) + mdef + + // Does the function have an explicit [] attribute? + let isExplicitEntryPoint = HasFSharpAttribute g g.attrib_EntryPointAttribute attrs + + let mdef = + mdef + .WithSecurity(not (List.isEmpty securityAttributes)) + .WithPInvoke(hasDllImport) + .WithPreserveSig(hasPreserveSigImplFlag || hasPreserveSigNamedArg) + .WithSynchronized(hasSynchronizedImplFlag) + .WithNoInlining(hasNoInliningFlag) + .WithAggressiveInlining(hasAggressiveInliningImplFlag) + .With(isEntryPoint=isExplicitEntryPoint, securityDecls=secDecls) + + let mdef = + if // operator names + mdef.Name.StartsWithOrdinal("op_") || + // active pattern names + mdef.Name.StartsWithOrdinal("|") || + // event add/remove method + v.val_flags.IsGeneratedEventVal then + mdef.WithSpecialName + else + mdef + CountMethodDef() + mgbuf.AddMethodDef(tref, mdef) - // For extension properties, also emit attrsAppliedToGetterOrSetter on the getter or setter method - let ilAttrs = - match v.MemberInfo with - | Some memberInfo when v.IsExtensionMember -> - match memberInfo.MemberFlags.MemberKind with - | (MemberKind.PropertySet | MemberKind.PropertyGet) -> ilAttrsThatGoOnPrimaryItem @ GenAttrs cenv eenv attrsAppliedToGetterOrSetter - | _ -> ilAttrsThatGoOnPrimaryItem - | _ -> ilAttrsThatGoOnPrimaryItem - - let ilCustomAttrs = mkILCustomAttrs (ilAttrs @ sourceNameAttribs @ ilAttrsCompilerGenerated) - let mdef = mdef.With(customAttrs= ilCustomAttrs) - EmitTheMethodDef mdef - and GenPInvokeMethod (nm, dll, namedArgs) = let decoder = AttributeDecoder namedArgs let hasPreserveSigNamedArg = decoder.FindBool "PreserveSig" true hasPreserveSigNamedArg, - MethodBody.PInvoke + let pinvoke = { Where=mkSimpleModRef dll Name=decoder.FindString "EntryPoint" nm CallingConv= @@ -5998,9 +7047,15 @@ and GenPInvokeMethod (nm, dll, namedArgs) = NoMangle= decoder.FindBool "ExactSpelling" false LastError= decoder.FindBool "SetLastError" false ThrowOnUnmappableChar= if (decoder.FindBool "ThrowOnUnmappableChar" false) then PInvokeThrowOnUnmappableChar.Enabled else PInvokeThrowOnUnmappableChar.UseAssembly - CharBestFit=if (decoder.FindBool "BestFitMapping" false) then PInvokeCharBestFit.Enabled else PInvokeCharBestFit.UseAssembly } + CharBestFit=if (decoder.FindBool "BestFitMapping" false) then PInvokeCharBestFit.Enabled else PInvokeCharBestFit.UseAssembly } : PInvokeMethod + MethodBody.PInvoke(lazy pinvoke) -and GenBindings cenv cgbuf eenv binds = List.iter (GenBinding cenv cgbuf eenv) binds +and GenBindings cenv cgbuf eenv binds stateVarFlagsOpt = + match stateVarFlagsOpt with + | None -> + binds |> List.iter (fun bind -> GenBinding cenv cgbuf eenv bind false) + | Some stateVarFlags -> + (binds, stateVarFlags) ||> List.iter2 (fun bind isStateVar -> GenBinding cenv cgbuf eenv bind isStateVar) //------------------------------------------------------------------------- // Generate locals and other storage of values @@ -6008,52 +7063,39 @@ and GenBindings cenv cgbuf eenv binds = List.iter (GenBinding cenv cgbuf eenv) b and GenSetVal cenv cgbuf eenv (vref, e, m) sequel = let storage = StorageForValRef cenv.g m vref eenv - match storage with - | Env (ilCloTy, _, _, _) -> - CG.EmitInstr cgbuf (pop 0) (Push [ilCloTy]) mkLdarg0 - | _ -> - () + GetStoreValCtxt cenv cgbuf eenv vref.Deref GenExpr cenv cgbuf eenv SPSuppress e Continue GenSetStorage vref.Range cgbuf storage GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel - -and GenGetValRefAndSequel cenv cgbuf eenv m (v: ValRef) fetchSequel = + +and GenGetValRefAndSequel cenv cgbuf eenv m (v: ValRef) storeSequel = let ty = v.Type - GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m eenv.tyenv ty) (StorageForValRef cenv.g m v eenv) fetchSequel + GenGetStorageAndSequel cenv cgbuf eenv m (ty, GenType cenv.amap m eenv.tyenv ty) (StorageForValRef cenv.g m v eenv) storeSequel and GenGetVal cenv cgbuf eenv (v: ValRef, m) sequel = GenGetValRefAndSequel cenv cgbuf eenv m v None GenSequel cenv eenv.cloc cgbuf sequel - -and GenBindingRhs cenv cgbuf eenv sp (vspec: Val) e = + +and GenBindingRhs cenv cgbuf eenv sp (vspec: Val) expr = let g = cenv.g - match e with + match expr with | Expr.TyLambda _ | Expr.Lambda _ -> - let isLocalTypeFunc = IsNamedLocalTypeFuncVal g vspec e - - match e with - | Expr.TyLambda (_, tyargs, body, _, ttype) when - ( - tyargs |> List.forall (fun tp -> tp.IsErased) && - (match StorageForVal g vspec.Range vspec eenv with Local _ -> true | _ -> false) && - (isLocalTypeFunc || - (match ttype with - TType_var typar -> match typar.Solution with Some(TType_app(t, _))-> t.IsStructOrEnumTycon | _ -> false - | _ -> false)) - ) -> - // type lambda with erased type arguments that is stored as local variable (not method or property)- inline body + + match IsLocalErasedTyLambda g eenv vspec expr with + | Some body -> GenExpr cenv cgbuf eenv sp body Continue - | _ -> - let selfv = if isLocalTypeFunc then None else Some (mkLocalValRef vspec) - GenLambda cenv cgbuf eenv isLocalTypeFunc selfv e Continue + | None -> + let isLocalTypeFunc = IsNamedLocalTypeFuncVal g vspec expr + let thisVars = if isLocalTypeFunc then [] else [ mkLocalValRef vspec ] + GenLambda cenv cgbuf eenv isLocalTypeFunc thisVars expr Continue | _ -> - GenExpr cenv cgbuf eenv sp e Continue + GenExpr cenv cgbuf eenv sp expr Continue -and CommitStartScope cgbuf startScopeMarkOpt = - match startScopeMarkOpt with +and CommitStartScope cgbuf startMarkOpt = + match startMarkOpt with | None -> () - | Some ss -> cgbuf.SetMarkToHere ss - + | Some startMark -> cgbuf.SetMarkToHere startMark + and EmitInitLocal cgbuf ty idx = CG.EmitInstrs cgbuf (pop 0) Push0 [I_ldloca (uint16 idx); (I_initobj ty) ] and EmitSetLocal cgbuf idx = CG.EmitInstr cgbuf (pop 1) Push0 (mkStloc (uint16 idx)) @@ -6071,14 +7113,14 @@ and GenSetStorage m cgbuf storage = | Local (idx, _, _) -> EmitSetLocal cgbuf idx - | StaticField (_, _, hasLiteralAttr, ilContainerTy, _, _, _, ilSetterMethRef, _) -> + | StaticPropertyWithField (_, _, hasLiteralAttr, ilContainerTy, _, _, _, ilSetterMethRef, _) -> if hasLiteralAttr then errorR(Error(FSComp.SR.ilLiteralFieldsCannotBeSet(), m)) CG.EmitInstr cgbuf (pop 1) Push0 (I_call(Normalcall, mkILMethSpecForMethRefInTy(ilSetterMethRef, ilContainerTy, []), None)) | StaticProperty (ilGetterMethSpec, _) -> error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name), m)) - | Method (_, _, mspec, m, _, _, _) -> + | Method (_, _, mspec, _, m, _, _, _, _, _, _, _) -> error(Error(FSComp.SR.ilStaticMethodIsNotLambda(mspec.Name), m)) | Null -> @@ -6087,30 +7129,35 @@ and GenSetStorage m cgbuf storage = | Arg _ -> error(Error(FSComp.SR.ilMutableVariablesCannotEscapeMethod(), m)) - | Env (_, _, ilField, _) -> + | Env (_, ilField, _) -> // Note: ldarg0 has already been emitted in GenSetVal CG.EmitInstr cgbuf (pop 2) Push0 (mkNormalStfld ilField) and CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel = match localCloInfo, storeSequel with - | Some {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}, _ -> error(InternalError("Unexpected generator", m)) - | Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo}, Some (tyargs, args, m, sequel) when not (isNil tyargs) -> + | Some (_, {contents =NamedLocalIlxClosureInfoGenerator _cloinfo}), _ -> + error(InternalError("Unexpected generator", m)) + + | Some (_, {contents =NamedLocalIlxClosureInfoGenerated cloinfo}), Some (tyargs, args, m, sequel) when not (isNil tyargs) -> let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv ty cloinfo tyargs m CommitGetStorageSequel cenv cgbuf eenv m actualRetTy None (Some ([], args, m, sequel)) + | _, None -> () + | _, Some ([], [], _, sequel) -> GenSequel cenv eenv.cloc cgbuf sequel + | _, Some (tyargs, args, m, sequel) -> - GenArgsAndIndirectCall cenv cgbuf eenv (ty, tyargs, args, m) sequel + GenCurriedArgsAndIndirectCall cenv cgbuf eenv (ty, tyargs, args, m) sequel -and GenGetStorageAndSequel cenv cgbuf eenv m (ty, ilTy) storage storeSequel = +and GenGetStorageAndSequel (cenv: cenv) cgbuf eenv m (ty, ilTy) storage storeSequel = let g = cenv.g match storage with | Local (idx, _, localCloInfo) -> EmitGetLocal cgbuf ilTy idx CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel - | StaticField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> + | StaticPropertyWithField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> // References to literals go directly to the field - no property is used if hasLiteralAttr then EmitGetStaticField cgbuf ilTy fspec @@ -6122,7 +7169,7 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (ty, ilTy) storage storeSequel = CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None)) CommitGetStorageSequel cenv cgbuf eenv m ty None storeSequel - | Method (topValInfo, vref, mspec, _, _, _, _) -> + | Method (topValInfo, vref, _, _, _, _, _, _, _, _, _, _) -> // Get a toplevel value as a first-class value. // We generate a lambda expression and that simply calls // the toplevel method. However we optimize the case where we are @@ -6135,45 +7182,44 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (ty, ilTy) storage storeSequel = // Then reduce out any arguments (i.e. apply the sequel immediately if we can...) match storeSequel with | None -> - GenLambda cenv cgbuf eenv false None expr Continue + GenLambda cenv cgbuf eenv false [] expr Continue | Some (tyargs', args, m, sequel) -> let specializedExpr = - if isNil args && isNil tyargs' then failwith ("non-lambda at use of method " + mspec.Name) - MakeApplicationAndBetaReduce g (expr, exprty, [tyargs'], args, m) + if isNil args && isNil tyargs' then failwith ("non-lambda at use of method " + vref.LogicalName) + MakeApplicationAndBetaReduce cenv.g (expr, exprty, [tyargs'], args, m) GenExpr cenv cgbuf eenv SPSuppress specializedExpr sequel | Null -> - CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (AI_ldnull) + CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) AI_ldnull CommitGetStorageSequel cenv cgbuf eenv m ty None storeSequel | Arg i -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (mkLdarg (uint16 i)) CommitGetStorageSequel cenv cgbuf eenv m ty None storeSequel - | Env (_, _, ilField, localCloInfo) -> - // Note: ldarg 0 is emitted in 'cu_erase' erasure of the ldenv instruction + | Env (_, ilField, localCloInfo) -> CG.EmitInstrs cgbuf (pop 0) (Push [ilTy]) [ mkLdarg0; mkNormalLdfld ilField ] CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel and GenGetLocalVals cenv cgbuf eenvouter m fvs = List.iter (fun v -> GenGetLocalVal cenv cgbuf eenvouter m v None) fvs -and GenGetLocalVal cenv cgbuf eenv m (vspec: Val) fetchSequel = - GenGetStorageAndSequel cenv cgbuf eenv m (vspec.Type, GenTypeOfVal cenv eenv vspec) (StorageForVal cenv.g m vspec eenv) fetchSequel +and GenGetLocalVal cenv cgbuf eenv m (vspec: Val) storeSequel = + GenGetStorageAndSequel cenv cgbuf eenv m (vspec.Type, GenTypeOfVal cenv eenv vspec) (StorageForVal cenv.g m vspec eenv) storeSequel -and GenGetLocalVRef cenv cgbuf eenv m (vref: ValRef) fetchSequel = - GenGetStorageAndSequel cenv cgbuf eenv m (vref.Type, GenTypeOfVal cenv eenv vref.Deref) (StorageForValRef cenv.g m vref eenv) fetchSequel +and GenGetLocalVRef cenv cgbuf eenv m (vref: ValRef) storeSequel = + GenGetStorageAndSequel cenv cgbuf eenv m (vref.Type, GenTypeOfVal cenv eenv vref.Deref) (StorageForValRef cenv.g m vref eenv) storeSequel and GenStoreVal cenv cgbuf eenv m (vspec: Val) = GenSetStorage vspec.Range cgbuf (StorageForVal cenv.g m vspec eenv) -/// Allocate IL locals -and AllocLocal cenv cgbuf eenv compgen (v, ty, isFixed) (scopeMarks: Mark * Mark) = +/// Allocate IL locals +and AllocLocal cenv cgbuf eenv compgen (v, ty, isFixed) (scopeMarks: Mark * Mark) : int * _ * _ = // The debug range for the local let ranges = if compgen then [] else [(v, scopeMarks)] // Get an index for the local let j, realloc = - if cenv.opts.localOptimizationsAreOn then + if cenv.opts.localOptimizationsEnabled then cgbuf.ReallocLocal((fun i (_, ty', isFixed') -> not isFixed' && not isFixed && not (IntMap.mem i eenv.liveLocals) && (ty = ty')), ranges, ty, isFixed) else cgbuf.AllocLocal(ranges, ty, isFixed), false @@ -6186,24 +7232,25 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = let ty = v.Type if isUnitTy g ty && not v.IsMutable then Null, eenv else - match repr with - | Some r when IsNamedLocalTypeFuncVal g v r -> - // known, named, non-escaping type functions + match repr with + | Some repr when IsNamedLocalTypeFuncVal g v repr -> + let ftyvs = (freeInExpr CollectTypars repr).FreeTyvars + // known, named, non-escaping type functions let cloinfoGenerate eenv = let eenvinner = {eenv with letBoundVars=(mkLocalValRef v) :: eenv.letBoundVars} - let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range true None eenvinner (Option.get repr) + let cloinfo, _, _ = GetIlxClosureInfo cenv v.Range ILBoxity.AsObject true true [] eenvinner repr cloinfo - + let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, g.ilg.typ_Object, false) scopeMarks - Local (idx, realloc, Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv - | _ -> - // normal local + Local (idx, realloc, Some(ftyvs, ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))), eenv + | _ -> + // normal local let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName g.CompilerGlobalState, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks Local (idx, realloc, None), eenv let eenv = AddStorageForVal g (v, notlazy repr) eenv - Some repr, eenv + repr, eenv and AllocStorageForBind cenv cgbuf scopeMarks eenv bind = AllocStorageForBinds cenv cgbuf scopeMarks eenv [bind] @@ -6218,11 +7265,13 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds = match reprOpt with | Some repr -> match repr with - | Local(_, _, Some g) - | Env(_, _, _, Some g) -> - match !g with - | NamedLocalIlxClosureInfoGenerator f -> g := NamedLocalIlxClosureInfoGenerated (f eenv) - | NamedLocalIlxClosureInfoGenerated _ -> () + | Local(_, _, Some (_, g)) + | Env(_, _, Some (_, g)) -> + match g.Value with + | NamedLocalIlxClosureInfoGenerator f -> + g.Value <- NamedLocalIlxClosureInfoGenerated (f eenv) + | NamedLocalIlxClosureInfoGenerated _ -> + () | _ -> () | _ -> ()) @@ -6231,17 +7280,18 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds = and AllocValForBind cenv cgbuf (scopeMarks: Mark * Mark) eenv (TBind(v, repr, _)) = match v.ValReprInfo with | None -> - AllocLocalVal cenv cgbuf v eenv (Some repr) scopeMarks + let repr, eenv = AllocLocalVal cenv cgbuf v eenv (Some repr) scopeMarks + Some repr, eenv | Some _ -> - None, AllocTopValWithinExpr cenv cgbuf eenv.cloc scopeMarks v eenv + None, AllocTopValWithinExpr cenv cgbuf (snd scopeMarks) eenv.cloc v eenv - -and AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v eenv = +and AllocTopValWithinExpr cenv cgbuf endMark cloc v eenv = let g = cenv.g + // decide whether to use a shadow local or not let useShadowLocal = cenv.opts.generateDebugSymbols && - not cenv.opts.localOptimizationsAreOn && + not cenv.opts.localOptimizationsEnabled && not v.IsCompilerGenerated && not v.IsMutable && // Don't use shadow locals for things like functions which are not compiled as static values/properties @@ -6249,10 +7299,9 @@ and AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v eenv = let optShadowLocal, eenv = if useShadowLocal then - let storageOpt, eenv = AllocLocalVal cenv cgbuf v eenv None scopeMarks - match storageOpt with - | None -> NoShadowLocal, eenv - | Some storage -> ShadowLocal storage, eenv + let startMark = CG.GenerateDelayMark cgbuf ("start_" + v.LogicalName) + let storage, eenv = AllocLocalVal cenv cgbuf v eenv None (startMark, endMark) + ShadowLocal (startMark, storage), eenv else NoShadowLocal, eenv @@ -6302,7 +7351,7 @@ and GenAttribArg amap g eenv x (ilArgTy: ILType) = match c with | Const.Bool b -> ILAttribElem.Bool b - | Const.Int32 i when isobj || tynm = "System.Int32" -> ILAttribElem.Int32 ( i) + | Const.Int32 i when isobj || tynm = "System.Int32" -> ILAttribElem.Int32 i | Const.Int32 i when tynm = "System.SByte" -> ILAttribElem.SByte (sbyte i) | Const.Int32 i when tynm = "System.Int16" -> ILAttribElem.Int16 (int16 i) | Const.Int32 i when tynm = "System.Byte" -> ILAttribElem.Byte (byte i) @@ -6380,11 +7429,11 @@ and GenAttr amap g eenv (Attrib(_, k, args, props, _, _, _)) = match k with | ILAttrib mref -> mkILMethSpec(mref, AsObject, [], []) | FSAttrib vref -> - assert(vref.IsMember) - let mspec, _, _, _, _, _ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref + assert vref.IsMember + let mspec, _, _, _, _, _, _, _, _, _ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref mspec let ilArgs = List.map2 (fun (AttribExpr(_, vexpr)) ty -> GenAttribArg amap g eenv vexpr ty) args mspec.FormalArgTypes - mkILCustomAttribMethRef g.ilg (mspec, ilArgs, props) + mkILCustomAttribMethRef (mspec, ilArgs, props) and GenAttrs cenv eenv attrs = List.map (GenAttr cenv.amap cenv.g eenv) attrs @@ -6397,22 +7446,22 @@ and GenCompilationArgumentCountsAttr cenv (v: Val) = if arities.Length > 1 then yield mkCompilationArgumentCountsAttr g arities | _ -> - () ] + () ] // Create a permission set for a list of security attributes and CreatePermissionSets cenv eenv (securityAttributes: Attrib list) = let g = cenv.g - [for ((Attrib(tcref, _, actions, _, _, _, _)) as attr) in securityAttributes do + [for Attrib(tcref, _, actions, _, _, _, _) as attr in securityAttributes do let action = match actions with | [AttribInt32Arg act] -> act | _ -> failwith "internal error: unrecognized security action" let secaction = (List.assoc action (Lazy.force ILSecurityActionRevMap)) let tref = tcref.CompiledRepresentationForNamedType let ilattr = GenAttr cenv.amap g eenv attr let _, ilNamedArgs = - match TryDecodeILAttribute g tref (mkILCustomAttrs [ilattr]) with + match TryDecodeILAttribute tref (mkILCustomAttrs [ilattr]) with | Some(ae, na) -> ae, na | _ -> [], [] let setArgs = ilNamedArgs |> List.map (fun (n, ilt, _, ilae) -> (n, ilt, ilae)) - yield IL.mkPermissionSet g.ilg (secaction, [(tref, setArgs)])] + yield mkPermissionSet (secaction, [(tref, setArgs)])] //-------------------------------------------------------------------------- // Generate the set of modules for an assembly, and the declarations in each module @@ -6447,39 +7496,51 @@ and GenModuleExpr cenv cgbuf qname lazyInitInfo eenv x = // We use one scope for all the bindings in the module, which makes them all appear with their "default" values // rather than incrementally as we step through the initializations in the module. This is a little unfortunate // but stems from the way we add module values all at once before we generate the module itself. - LocalScope "module" cgbuf (fun scopeMarks -> + LocalScope "module" cgbuf (fun (_, endMark) -> let sigToImplRemapInfo = ComputeRemappingFromImplementationToSignature cenv.g def mty let eenv = AddSignatureRemapInfo "defs" sigToImplRemapInfo eenv - let eenv = - // Allocate all the values, including any shadow locals for static fields - let allocVal cloc v = AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v - AddBindingsForModuleDef allocVal eenv.cloc eenv def - GenModuleDef cenv cgbuf qname lazyInitInfo eenv def) + + // Allocate all the values, including any shadow locals for static fields + let eenv = AddBindingsForModuleDef (AllocTopValWithinExpr cenv cgbuf endMark) eenv.cloc eenv def + let _eenvEnd = GenModuleDef cenv cgbuf qname lazyInitInfo eenv def + ()) and GenModuleDefs cenv cgbuf qname lazyInitInfo eenv mdefs = - mdefs |> List.iter (GenModuleDef cenv cgbuf qname lazyInitInfo eenv) + let _eenvEnd = (eenv, mdefs) ||> List.fold (GenModuleDef cenv cgbuf qname lazyInitInfo) + () and GenModuleDef cenv (cgbuf: CodeGenBuffer) qname lazyInitInfo eenv x = match x with - | TMDefRec(_isRec, tycons, mbinds, m) -> - tycons |> List.iter (fun tc -> - if tc.IsExceptionDecl - then GenExnDef cenv cgbuf.mgbuf eenv m tc - else GenTypeDef cenv cgbuf.mgbuf lazyInitInfo eenv m tc) - mbinds |> List.iter (GenModuleBinding cenv cgbuf qname lazyInitInfo eenv m) + | TMDefRec(_isRec, opens, tycons, mbinds, m) -> + let eenvinner = AddDebugImportsToEnv cenv eenv opens + for tc in tycons do + if tc.IsExceptionDecl then + GenExnDef cenv cgbuf.mgbuf eenvinner m tc + else + GenTypeDef cenv cgbuf.mgbuf lazyInitInfo eenvinner m tc + for mbind in mbinds do + GenModuleBinding cenv cgbuf qname lazyInitInfo eenvinner m mbind + eenvinner | TMDefLet(bind, _) -> - GenBindings cenv cgbuf eenv [bind] + GenBindings cenv cgbuf eenv [bind] None + eenv + + | TMDefOpens openDecls -> + let eenvinner = AddDebugImportsToEnv cenv eenv openDecls + eenvinner | TMDefDo(e, _) -> GenExpr cenv cgbuf eenv SPAlways e discard + eenv | TMAbstract mexpr -> GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr + eenv | TMDefs mdefs -> GenModuleDefs cenv cgbuf qname lazyInitInfo eenv mdefs - + eenv // Generate a module binding and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) lazyInitInfo eenv m x = @@ -6488,11 +7549,11 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la GenLetRecBindings cenv cgbuf eenv ([bind], m) | ModuleOrNamespaceBinding.Module (mspec, mdef) -> - let hidden = IsHiddenTycon cenv.g eenv.sigToImplRemapInfo mspec + let hidden = IsHiddenTycon eenv.sigToImplRemapInfo mspec let eenvinner = if mspec.IsNamespace then eenv else - {eenv with cloc = CompLocForFixedModule cenv.opts.fragName qname.Text mspec } + { eenv with cloc = CompLocForFixedModule cenv.opts.fragName qname.Text mspec; initLocals = eenv.initLocals && not (HasFSharpAttribute cenv.g cenv.g.attrib_SkipLocalsInitAttribute mspec.Attribs) } // Create the class to hold the contents of this module. No class needed if // we're compiling it as a namespace. @@ -6509,17 +7570,19 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la GenTypeDefForCompLoc (cenv, eenvinner, cgbuf.mgbuf, eenvinner.cloc, hidden, mspec.Attribs, staticClassTrigger, false, (* atEnd= *) true) // Generate the declarations in the module and its initialization code - GenModuleDef cenv cgbuf qname lazyInitInfo eenvinner mdef + let _envAtEnd = GenModuleDef cenv cgbuf qname lazyInitInfo eenvinner mdef // If the module has a .cctor for some mutable fields, we need to ensure that when // those fields are "touched" the InitClass .cctor is forced. The InitClass .cctor will // then fill in the value of the mutable fields. if not mspec.IsNamespace && (cgbuf.mgbuf.GetCurrentFields(TypeRefForCompLoc eenvinner.cloc) |> Seq.isEmpty |> not) then - GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf lazyInitInfo (TypeRefForCompLoc eenvinner.cloc) mspec.Range + GenForceWholeFileInitializationAsPartOfCCtor cenv cgbuf.mgbuf lazyInitInfo (TypeRefForCompLoc eenvinner.cloc) eenv.imports mspec.Range /// Generate the namespace fragments in a single file -and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, _, mexpr, hasExplicitEntryPoint, isScript, anonRecdTypes), optimizeDuringCodeGen) = +and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: TypedImplFileAfterOptimization) = + let (TImplFile (qname, _, mexpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = implFile.ImplFile + let optimizeDuringCodeGen = implFile.OptimizeDuringCodeGen let g = cenv.g let m = qname.Range @@ -6553,7 +7616,7 @@ and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, // - static "let" bindings in types // These functions only get executed/committed if we actually end up producing some code for the .cctor for the storage module. // The existence of .cctors adds costs to execution, so this is a half-sensible attempt to avoid adding them when possible. - let lazyInitInfo = new ResizeArray ILInstr list -> ILInstr list -> unit>() + let lazyInitInfo = ResizeArray ILInstr list -> ILInstr list -> unit>() // codegen .cctor/main for outer module let clocCcu = CompLocForCcu cenv.viewCcu @@ -6567,11 +7630,11 @@ and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, | Some _ when hasExplicitEntryPoint -> ".cctor" // Final file, implicit entry point | Some _ -> mainMethName - + // topInstrs is ILInstr[] and contains the abstract IL for this file's top-level actions. topCode is the ILMethodBody for that same code. let topInstrs, topCode = CodeGenMethod cenv mgbuf - ([], methodName, eenv, 0, + ([], methodName, eenv, 0, None, (fun cgbuf eenv -> GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr CG.EmitInstr cgbuf (pop 0) Push0 I_ret), m) @@ -6584,7 +7647,7 @@ and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, let doesSomething = CheckCodeDoesSomething topCode.Code // Make a FEEFEE instruction to mark hidden code regions - // We expect the first instruction to be a sequence point when generating debug symbols + // We expect the first instruction to be a debug point when generating debug symbols let feefee, seqpt = if topInstrs.Length > 1 then match topInstrs.[0] with @@ -6593,56 +7656,48 @@ and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, else [], [] - begin - - match mainInfoOpt with - - // Final file in .EXE - | Some mainInfo -> - // Generate an explicit main method. If necessary, make a class constructor as - // well for the bindings earlier in the file containing the entry point. - match mgbuf.GetExplicitEntryPointInfo() with - - // Final file, explicit entry point: place the code in a .cctor, and add code to main that forces the .cctor (if topCode has initialization effect). - | Some tref -> - if doesSomething then - lazyInitInfo.Add (fun fspec feefee seqpt -> - // This adds the explicit init of the .cctor to the explicit entry point main method - mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.IsEntryPoint), tref, fspec, GenPossibleILSourceMarker cenv m, feefee, seqpt)) - - let cctorMethDef = mkILClassCtor (MethodBody.IL topCode) - mgbuf.AddMethodDef(initClassTy.TypeRef, cctorMethDef) - - // Final file, implicit entry point. We generate no .cctor. - // void main@() { - // - // } - | None -> - - let ilAttrs = mkILCustomAttrs (GenAttrs cenv eenv mainInfo) - if not cenv.opts.isInteractive && not doesSomething then - let errorM = m.EndRange - warning (Error(FSComp.SR.ilMainModuleEmpty(), errorM)) - - // generate main@ - let ilMainMethodDef = - let mdef = mkILNonGenericStaticMethod(mainMethName, ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL topCode) - mdef.With(isEntryPoint= true, customAttrs = ilAttrs) - - mgbuf.AddMethodDef(initClassTy.TypeRef, ilMainMethodDef) + match mainInfoOpt with + // Final file in .EXE + | Some mainInfo -> + // Generate an explicit main method. If necessary, make a class constructor as + // well for the bindings earlier in the file containing the entry point. + match mgbuf.GetExplicitEntryPointInfo() with + // Final file, explicit entry point: place the code in a .cctor, and add code to main that forces the .cctor (if topCode has initialization effect). + | Some tref -> + if doesSomething then + lazyInitInfo.Add (fun fspec feefee seqpt -> + // This adds the explicit init of the .cctor to the explicit entry point main method + let ilDebugPoint = GenPossibleILSourceMarker cenv m + mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.IsEntryPoint), tref, fspec, ilDebugPoint, eenv.imports, feefee, seqpt)) + let cctorMethDef = mkILClassCtor (MethodBody.IL (lazy topCode)) + mgbuf.AddMethodDef(initClassTy.TypeRef, cctorMethDef) - // Library file: generate an optional .cctor if topCode has initialization effect + // Final file, implicit entry point. We generate no .cctor. + // void main@() { + // + // } | None -> - if doesSomething then + let ilAttrs = mkILCustomAttrs (GenAttrs cenv eenv mainInfo) + if not cenv.opts.isInteractive && not doesSomething then + let errorM = m.EndRange + warning (Error(FSComp.SR.ilMainModuleEmpty(), errorM)) - // Add the cctor - let cctorMethDef = mkILClassCtor (MethodBody.IL topCode) - mgbuf.AddMethodDef(initClassTy.TypeRef, cctorMethDef) + // generate main@ + let ilMainMethodDef = + let mdef = mkILNonGenericStaticMethod(mainMethName, ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL (lazy topCode)) + mdef.With(isEntryPoint= true, customAttrs = ilAttrs) + mgbuf.AddMethodDef(initClassTy.TypeRef, ilMainMethodDef) - end + + // Library file: generate an optional .cctor if topCode has initialization effect + | None -> + if doesSomething then + // Add the cctor + let cctorMethDef = mkILClassCtor (MethodBody.IL (lazy topCode)) + mgbuf.AddMethodDef(initClassTy.TypeRef, cctorMethDef) // Commit the directed initializations if doesSomething then @@ -6675,10 +7730,12 @@ and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile (qname, eenvafter -and GenForceWholeFileInitializationAsPartOfCCtor cenv (mgbuf: AssemblyBuilder) (lazyInitInfo: ResizeArray<_>) tref m = +and GenForceWholeFileInitializationAsPartOfCCtor cenv (mgbuf: AssemblyBuilder) (lazyInitInfo: ResizeArray<_>) tref imports m = // Authoring a .cctor with effects forces the cctor for the 'initialization' module by doing a dummy store & load of a field // Doing both a store and load keeps FxCop happier because it thinks the field is useful - lazyInitInfo.Add (fun fspec feefee seqpt -> mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.Name = ".cctor"), tref, fspec, GenPossibleILSourceMarker cenv m, feefee, seqpt)) + lazyInitInfo.Add (fun fspec feefee seqpt -> + let ilDebugPoint = GenPossibleILSourceMarker cenv m + mgbuf.AddExplicitInitToSpecificMethodDef((fun md -> md.Name = ".cctor"), tref, fspec, ilDebugPoint, imports, feefee, seqpt)) /// Generate an Equals method. @@ -6686,21 +7743,23 @@ and GenEqualsOverrideCallingIComparable cenv (tcref: TyconRef, ilThisTy, _ilThat let g = cenv.g let mspec = mkILNonGenericInstanceMethSpecInTy (g.iltyp_IComparable, "CompareTo", [g.ilg.typ_Object], g.ilg.typ_Int32) + let ilInstrs = + [ mkLdarg0 + mkLdarg 1us + if tcref.IsStructOrEnumTycon then + I_callconstraint ( Normalcall, ilThisTy, mspec, None) + else + I_callvirt ( Normalcall, mspec, None) + mkLdcInt32 0 + AI_ceq ] + + let ilMethodBody = mkMethodBody(true, [], 2, nonBranchingInstrsToCode ilInstrs, None, None) + mkILNonGenericVirtualMethod ("Equals", ILMemberAccess.Public, [mkILParamNamed ("obj", g.ilg.typ_Object)], mkILReturn g.ilg.typ_Bool, - mkMethodBody(true, [], 2, - nonBranchingInstrsToCode - [ yield mkLdarg0 - yield mkLdarg 1us - if tcref.IsStructOrEnumTycon then - yield I_callconstraint ( Normalcall, ilThisTy, mspec, None) - else - yield I_callvirt ( Normalcall, mspec, None) - yield mkLdcInt32 0 - yield AI_ceq ], - None)) + ilMethodBody) |> AddNonUserCompilerGeneratedAttribs g and GenFieldInit m c = @@ -6708,24 +7767,54 @@ and GenFieldInit m c = | ConstToILFieldInit fieldInit -> fieldInit | _ -> error(Error(FSComp.SR.ilTypeCannotBeUsedForLiteralField(), m)) +and GenWitnessParams cenv eenv m (witnessInfos: TraitWitnessInfos) = + ((Set.empty, 0), witnessInfos) ||> List.mapFold (fun (used,i) witnessInfo -> + let ty = GenWitnessTy cenv.g witnessInfo + let nm = String.uncapitalize witnessInfo.MemberName + let nm = if used.Contains nm then nm + string i else nm + let ilParam = + { Name=Some nm + Type= GenType cenv.amap m eenv.tyenv ty + Default=None + Marshal=None + IsIn=false + IsOut=false + IsOptional=false + CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs []) + MetadataIndex = NoMetadataIdx }: ILParameter + ilParam, (used.Add nm, i + 1)) + |> fst + and GenAbstractBinding cenv eenv tref (vref: ValRef) = - assert(vref.IsMember) + assert vref.IsMember let g = cenv.g let m = vref.Range let memberInfo = Option.get vref.MemberInfo let attribs = vref.Attribs let hasPreserveSigImplFlag, hasSynchronizedImplFlag, hasNoInliningFlag, hasAggressiveInliningImplFlag, attribs = ComputeMethodImplAttribs cenv vref.Deref attribs if memberInfo.MemberFlags.IsDispatchSlot && not memberInfo.IsImplemented then + let mspec, _mspecW, ctps, mtps, _curriedArgInfos, argInfos, retInfo, witnessInfos, methArgTys, returnTy = + GetMethodSpecForMemberVal cenv.amap cenv.g memberInfo vref + let ilAttrs = [ yield! GenAttrs cenv eenv attribs - yield! GenCompilationArgumentCountsAttr cenv vref.Deref ] - - let mspec, ctps, mtps, argInfos, retInfo, methodArgTys = GetMethodSpecForMemberVal cenv.amap g memberInfo vref + yield! GenCompilationArgumentCountsAttr cenv vref.Deref + + match vref.MemberInfo, returnTy with + | Some memberInfo, Some returnTy when + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || + memberInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet -> + match GenReadOnlyAttributeIfNecessary g returnTy with Some ilAttr -> ilAttr | _ -> () + | _ -> () ] + + assert witnessInfos.IsEmpty + let eenvForMeth = EnvForTypars (ctps@mtps) eenv let ilMethTypars = GenGenericParams cenv eenvForMeth mtps - let ilReturn = GenReturnInfo cenv eenvForMeth mspec.FormalReturnType retInfo - let ilParams = GenParams cenv eenvForMeth mspec argInfos methodArgTys None - + let ilReturn = GenReturnInfo cenv eenvForMeth returnTy mspec.FormalReturnType retInfo + let ilParams = GenParams cenv eenvForMeth m mspec [] argInfos methArgTys None + let compileAsInstance = ValRefIsCompiledAsInstanceMember g vref let mdef = mkILGenericVirtualMethod (vref.CompiledName g.CompilerGlobalState, ILMemberAccess.Public, ilMethTypars, ilParams, ilReturn, MethodBody.Abstract) @@ -6739,24 +7828,25 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) = .WithSynchronized(hasSynchronizedImplFlag) .WithNoInlining(hasNoInliningFlag) .WithAggressiveInlining(hasAggressiveInliningImplFlag) - + match memberInfo.MemberFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.Member -> + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.Member -> let mdef = mdef.With(customAttrs= mkILCustomAttrs ilAttrs) [mdef], [], [] - | MemberKind.PropertyGetSet -> error(Error(FSComp.SR.ilUnexpectedGetSetAnnotation(), m)) - | MemberKind.PropertySet | MemberKind.PropertyGet -> + | SynMemberKind.PropertyGetSet -> error(Error(FSComp.SR.ilUnexpectedGetSetAnnotation(), m)) + | SynMemberKind.PropertySet | SynMemberKind.PropertyGet -> let v = vref.Deref let vtyp = ReturnTypeOfPropertyVal g v if CompileAsEvent g attribs then - + let edef = GenEventForProperty cenv eenvForMeth mspec v ilAttrs m vtyp [], [], [edef] else let ilPropDef = let ilPropTy = GenType cenv.amap m eenvForMeth.tyenv vtyp + let ilPropTy = GenReadOnlyModReqIfNecessary g vtyp ilPropTy let ilArgTys = v |> ArgInfosOfPropertyVal g |> List.map fst |> GenTypes cenv.amap m eenvForMeth.tyenv GenPropertyForMethodDef compileAsInstance tref mdef v memberInfo ilArgTys ilPropTy (mkILCustomAttrs ilAttrs) None let mdef = mdef.WithSpecialName @@ -6770,38 +7860,43 @@ and GenToStringMethod cenv eenv ilThisTy m = let g = cenv.g [ match (eenv.valsInScope.TryFind g.sprintf_vref.Deref, eenv.valsInScope.TryFind g.new_format_vref.Deref) with - | Some(Lazy(Method(_, _, sprintfMethSpec, _, _, _, _))), Some(Lazy(Method(_, _, newFormatMethSpec, _, _, _, _))) -> + | Some(Lazy(Method(_, _, sprintfMethSpec, _, _, _, _, _, _, _, _, _))), Some(Lazy(Method(_, _, newFormatMethSpec, _, _, _, _, _, _, _, _, _))) -> // The type returned by the 'sprintf' call let funcTy = EraseClosures.mkILFuncTy g.ilxPubCloEnv ilThisTy g.ilg.typ_String + // Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat - let newFormatMethSpec = mkILMethSpec(newFormatMethSpec.MethodRef, AsObject, - [// 'T -> string' - funcTy - // rest follow from 'StringFormat' - GenUnitTy cenv eenv m - g.ilg.typ_String - g.ilg.typ_String - ilThisTy], []) + let newFormatMethSpec = + mkILMethSpec(newFormatMethSpec.MethodRef, AsObject, + [ // 'T -> string' + funcTy + // rest follow from 'StringFormat' + GenUnitTy cenv eenv m + g.ilg.typ_String + g.ilg.typ_String + ilThisTy], []) + // Instantiate with our own type let sprintfMethSpec = mkILMethSpec(sprintfMethSpec.MethodRef, AsObject, [], [funcTy]) + // Here's the body of the method. Call printf, then invoke the function it returns let callInstrs = EraseClosures.mkCallFunc g.ilxPubCloEnv (fun _ -> 0us) eenv.tyenv.Count Normalcall (Apps_app(ilThisTy, Apps_done g.ilg.typ_String)) - let mdef = - mkILNonGenericVirtualMethod ("ToString", ILMemberAccess.Public, [], - mkILReturn g.ilg.typ_String, - mkMethodBody (true, [], 2, nonBranchingInstrsToCode - ([ // load the hardwired format string - yield I_ldstr "%+A" - // make the printf format object - yield mkNormalNewobj newFormatMethSpec - // call sprintf - yield mkNormalCall sprintfMethSpec - // call the function returned by sprintf - yield mkLdarg0 - if ilThisTy.Boxity = ILBoxity.AsValue then - yield mkNormalLdobj ilThisTy ] @ - callInstrs), - None)) + + let ilInstrs = + [ // load the hardwired format string + I_ldstr "%+A" + // make the printf format object + mkNormalNewobj newFormatMethSpec + // call sprintf + mkNormalCall sprintfMethSpec + // call the function returned by sprintf + mkLdarg0 + if ilThisTy.Boxity = ILBoxity.AsValue then + mkNormalLdobj ilThisTy + yield! callInstrs ] + + let ilMethodBody = mkMethodBody (true, [], 2, nonBranchingInstrsToCode ilInstrs, None, eenv.imports) + + let mdef = mkILNonGenericVirtualMethod ("ToString", ILMemberAccess.Public, [], mkILReturn g.ilg.typ_String, ilMethodBody) let mdef = mdef.With(customAttrs = mkILCustomAttrs [ g.CompilerGeneratedAttribute ]) yield mdef | _ -> () ] @@ -6812,13 +7907,17 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = if tycon.IsTypeAbbrev then () else match tycon.TypeReprInfo with #if !NO_EXTENSIONTYPING - | TProvidedNamespaceExtensionPoint _ -> () - | TProvidedTypeExtensionPoint _ -> () + | TProvidedNamespaceRepr _ + | TProvidedTypeRepr _ #endif - | TNoRepr -> () - | TAsmRepr _ | TILObjectRepr _ | TMeasureableRepr _ -> () - | TFSharpObjectRepr _ | TRecdRepr _ | TUnionRepr _ -> - let eenvinner = ReplaceTyenv (TypeReprEnv.ForTycon tycon) eenv + | TNoRepr + | TAsmRepr _ + | TILObjectRepr _ + | TMeasureableRepr _ -> () + | TFSharpObjectRepr _ + | TFSharpRecdRepr _ + | TFSharpUnionRepr _ -> + let eenvinner = EnvForTycon tycon eenv let thisTy = generalizedTyconRef tcref let ilThisTy = GenType cenv.amap m eenvinner.tyenv thisTy @@ -6827,8 +7926,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let ilIntfTys = tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.map (GenType cenv.amap m eenvinner.tyenv) let ilTypeName = tref.Name - let hidden = IsHiddenTycon g eenv.sigToImplRemapInfo tycon - let hiddenRepr = hidden || IsHiddenTyconRepr g eenv.sigToImplRemapInfo tycon + let hidden = IsHiddenTycon eenv.sigToImplRemapInfo tycon + let hiddenRepr = hidden || IsHiddenTyconRepr eenv.sigToImplRemapInfo tycon let access = ComputeTypeAccess tref hidden // The implicit augmentation doesn't actually create CompareTo(object) or Object.Equals @@ -6836,7 +7935,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // // Note you only have to implement 'System.IComparable' to customize structural comparison AND equality on F# types // See also FinalTypeDefinitionChecksAtEndOfInferenceScope in tc.fs - // + // // Generate an Equals method implemented via IComparable if the type EXPLICITLY implements IComparable. // HOWEVER, if the type doesn't override Object.Equals already. let augmentOverrideMethodDefs = @@ -6871,7 +7970,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // REVIEW: no method impl generated for IStructuralHash or ICompare let methodImpls = [ for vref in tycon.MembersOfFSharpTyconByName |> NameMultiMap.range do - assert(vref.IsMember) + assert vref.IsMember let memberInfo = vref.MemberInfo.Value if memberInfo.MemberFlags.IsOverrideOrExplicitImpl && not (CompileAsEvent g vref.Attribs) then @@ -6894,7 +7993,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = yield methodImplGenerator (ilThisTy, memberMethodTypars) | _ -> () ] - + // Try to add a DefaultMemberAttribute for the 'Item' property let defaultMemberAttrs = // REVIEW: this should be based off tcaug_adhoc_list, which is in declaration order @@ -6905,8 +8004,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = | None -> None | Some memberInfo -> match name, memberInfo.MemberFlags.MemberKind with - | ("Item" | "op_IndexedLookup"), (MemberKind.PropertyGet | MemberKind.PropertySet) when not (isNil (ArgInfosOfPropertyVal g vref.Deref)) -> - Some( mkILCustomAttribute g.ilg (g.FindSysILTypeRef "System.Reflection.DefaultMemberAttribute", [g.ilg.typ_String], [ILAttribElem.String(Some name)], []) ) + | ("Item" | "op_IndexedLookup"), (SynMemberKind.PropertyGet | SynMemberKind.PropertySet) when not (isNil (ArgInfosOfPropertyVal g vref.Deref)) -> + Some( mkILCustomAttribute (g.FindSysILTypeRef "System.Reflection.DefaultMemberAttribute", [g.ilg.typ_String], [ILAttribElem.String(Some name)], []) ) | _ -> None) |> Option.toList @@ -6921,7 +8020,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let permissionSets = CreatePermissionSets cenv eenv securityAttrs let secDecls = if List.isEmpty securityAttrs then emptyILSecurityDecls else mkILSecurityDecls permissionSets - + let ilDebugDisplayAttributes = [ yield! GenAttrs cenv eenv debugDisplayAttrs if generateDebugDisplayAttribute then @@ -6942,12 +8041,13 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = match tyconRepr with | TFSharpObjectRepr o -> match o.fsobjmodel_kind with - | TTyconClass -> ILTypeDefKind.Class - | TTyconStruct -> ILTypeDefKind.ValueType - | TTyconInterface -> ILTypeDefKind.Interface - | TTyconEnum -> ILTypeDefKind.Enum - | TTyconDelegate _ -> ILTypeDefKind.Delegate - | TRecdRepr _ | TUnionRepr _ when tycon.IsStructOrEnumTycon -> ILTypeDefKind.ValueType + | TFSharpClass -> ILTypeDefKind.Class + | TFSharpStruct -> ILTypeDefKind.ValueType + | TFSharpInterface -> ILTypeDefKind.Interface + | TFSharpEnum -> ILTypeDefKind.Enum + | TFSharpDelegate _ -> ILTypeDefKind.Delegate + | TFSharpRecdRepr _ + | TFSharpUnionRepr _ when tycon.IsStructOrEnumTycon -> ILTypeDefKind.ValueType | _ -> ILTypeDefKind.Class let requiresExtraField = @@ -6958,7 +8058,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = tycon.AllFieldsArray |> Array.forall (fun f -> f.IsStatic) isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty - + // Compute a bunch of useful things for each field let isCLIMutable = (TryFindFSharpBoolAttribute g g.attrib_CLIMutableAttribute tycon.Attribs = Some true) let fieldSummaries = @@ -6979,19 +8079,19 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = IsHiddenRecdField eenv.sigToImplRemapInfo (tcref.MakeNestedRecdFieldRef fspec)) let ilType = GenType cenv.amap m eenvinner.tyenv fspec.FormalType let ilFieldName = ComputeFieldName tycon fspec - + yield (useGenuineField, ilFieldName, fspec.IsMutable, fspec.IsStatic, fspec.PropertyAttribs, ilType, isPropHidden, fspec) ] - + // Generate the IL fields let ilFieldDefs = - [ for (useGenuineField, ilFieldName, isFSharpMutable, isStatic, _, ilPropType, isPropHidden, fspec) in fieldSummaries do + [ for useGenuineField, ilFieldName, isFSharpMutable, isStatic, _, ilPropType, isPropHidden, fspec in fieldSummaries do let ilFieldOffset = match TryFindFSharpAttribute g g.attrib_FieldOffsetAttribute fspec.FieldAttribs with | Some (Attrib(_, _, [ AttribInt32Arg fieldOffset ], _, _, _, _)) -> Some fieldOffset - | Some (Attrib(_, _, _, _, _, _, m)) -> - errorR(Error(FSComp.SR.ilFieldOffsetAttributeCouldNotBeDecoded(), m)) + | Some attrib -> + errorR(Error(FSComp.SR.ilFieldOffsetAttributeCouldNotBeDecoded(), attrib.Range)) None | _ -> None @@ -7003,9 +8103,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = if useGenuineField then yield! fspec.PropertyAttribs yield! fspec.FieldAttribs ] - + let ilNotSerialized = HasFSharpAttributeOpt g g.attrib_NonSerializedAttribute attribs - + let fattribs = attribs // Do not generate FieldOffset as a true CLI custom attribute, since it is implied by other corresponding CLI metadata @@ -7015,18 +8115,19 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let ilFieldMarshal, fattribs = GenMarshal cenv fattribs - // The IL field is hidden if the property/field is hidden OR we're using a property AND the field is not mutable (because we can take the address of a mutable field). + // The IL field is hidden if the property/field is hidden OR we're using a property + // AND the field is not mutable (because we can take the address of a mutable field). // Otherwise fields are always accessed via their property getters/setters let isFieldHidden = isPropHidden || (not useGenuineField && not isFSharpMutable) - + let extraAttribs = match tyconRepr with - | TRecdRepr _ when not useGenuineField -> [ g.DebuggerBrowsableNeverAttribute ] // hide fields in records in debug display + | TFSharpRecdRepr _ when not useGenuineField -> [ g.DebuggerBrowsableNeverAttribute ] // hide fields in records in debug display | _ -> [] // don't hide fields in classes in debug display let access = ComputeMemberAccess isFieldHidden let literalValue = Option.map (GenFieldInit m) fspec.LiteralValue - + let fdef = ILFieldDef(name = ilFieldName, fieldType = ilPropType, @@ -7046,13 +8147,13 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = if requiresExtraField then yield mkILInstanceField("__dummy", g.ilg.typ_Int32, None, ILMemberAccess.Assembly) ] - + // Generate property definitions for the fields compiled as properties let ilPropertyDefsForFields = - [ for (i, (useGenuineField, _, isFSharpMutable, isStatic, propAttribs, ilPropType, _, fspec)) in Seq.indexed fieldSummaries do + [ for i, (useGenuineField, _, isFSharpMutable, isStatic, propAttribs, ilPropType, _, fspec) in Seq.indexed fieldSummaries do if not useGenuineField then let ilCallingConv = if isStatic then ILCallingConv.Static else ILCallingConv.Instance - let ilPropName = fspec.Name + let ilPropName = fspec.LogicalName let ilHasSetter = isCLIMutable || isFSharpMutable let ilFieldAttrs = GenAttrs cenv eenv propAttribs @ [mkCompilationMappingAttrWithSeqNum g (int SourceConstructFlags.Field) i] yield @@ -7065,21 +8166,21 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = init= None, args= [], customAttrs = mkILCustomAttrs ilFieldAttrs) ] - + let methodDefs = [ // Generate property getter methods for those fields that have properties - for (useGenuineField, ilFieldName, _, isStatic, _, ilPropType, isPropHidden, fspec) in fieldSummaries do + for useGenuineField, ilFieldName, _, isStatic, _, ilPropType, isPropHidden, fspec in fieldSummaries do if not useGenuineField then - let ilPropName = fspec.Name + let ilPropName = fspec.LogicalName let ilMethName = "get_" + ilPropName let access = ComputeMemberAccess isPropHidden yield mkLdfldMethodDef (ilMethName, access, isStatic, ilThisTy, ilFieldName, ilPropType) // Generate property setter methods for the mutable fields - for (useGenuineField, ilFieldName, isFSharpMutable, isStatic, _, ilPropType, isPropHidden, fspec) in fieldSummaries do + for useGenuineField, ilFieldName, isFSharpMutable, isStatic, _, ilPropType, isPropHidden, fspec in fieldSummaries do let ilHasSetter = (isCLIMutable || isFSharpMutable) && not useGenuineField if ilHasSetter then - let ilPropName = fspec.Name + let ilPropName = fspec.LogicalName let ilFieldSpec = mkILFieldSpecInTy(ilThisTy, ilFieldName, ilPropType) let ilMethName = "set_" + ilPropName let ilParams = [mkILParamNamed("value", ilPropType)] @@ -7087,20 +8188,18 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let iLAccess = ComputeMemberAccess isPropHidden let ilMethodDef = if isStatic then - mkILNonGenericStaticMethod - (ilMethName, iLAccess, ilParams, ilReturn, - mkMethodBody(true, [], 2, nonBranchingInstrsToCode ([ mkLdarg0;mkNormalStsfld ilFieldSpec]), None)) + let ilMethodBody = mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkLdarg0;mkNormalStsfld ilFieldSpec], None, eenv.imports) + mkILNonGenericStaticMethod (ilMethName, iLAccess, ilParams, ilReturn, ilMethodBody) else - mkILNonGenericInstanceMethod - (ilMethName, iLAccess, ilParams, ilReturn, - mkMethodBody(true, [], 2, nonBranchingInstrsToCode ([ mkLdarg0;mkLdarg 1us;mkNormalStfld ilFieldSpec]), None)) + let ilMethodBody = mkMethodBody(true, [], 2, nonBranchingInstrsToCode [ mkLdarg0;mkLdarg 1us;mkNormalStfld ilFieldSpec], None, eenv.imports) + mkILNonGenericInstanceMethod (ilMethName, iLAccess, ilParams, ilReturn, ilMethodBody) yield ilMethodDef.WithSpecialName if generateDebugDisplayAttribute then let (|Lazy|) (x: Lazy<_>) = x.Force() match (eenv.valsInScope.TryFind g.sprintf_vref.Deref, eenv.valsInScope.TryFind g.new_format_vref.Deref) with - | Some(Lazy(Method(_, _, sprintfMethSpec, _, _, _, _))), Some(Lazy(Method(_, _, newFormatMethSpec, _, _, _, _))) -> + | Some(Lazy(Method(_, _, sprintfMethSpec, _, _, _, _, _, _, _, _, _))), Some(Lazy(Method(_, _, newFormatMethSpec, _, _, _, _, _, _, _, _, _))) -> // The type returned by the 'sprintf' call let funcTy = EraseClosures.mkILFuncTy g.ilxPubCloEnv ilThisTy g.ilg.typ_String // Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat @@ -7114,25 +8213,26 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = g.ilg.typ_String], []) // Instantiate with our own type let sprintfMethSpec = mkILMethSpec(sprintfMethSpec.MethodRef, AsObject, [], [funcTy]) + // Here's the body of the method. Call printf, then invoke the function it returns let callInstrs = EraseClosures.mkCallFunc g.ilxPubCloEnv (fun _ -> 0us) eenv.tyenv.Count Normalcall (Apps_app(ilThisTy, Apps_done g.ilg.typ_String)) - let ilMethodDef = mkILNonGenericInstanceMethod (debugDisplayMethodName, ILMemberAccess.Assembly, [], - mkILReturn g.ilg.typ_Object, - mkMethodBody - (true, [], 2, - nonBranchingInstrsToCode - ([ // load the hardwired format string - yield I_ldstr "%+0.8A" - // make the printf format object - yield mkNormalNewobj newFormatMethSpec - // call sprintf - yield mkNormalCall sprintfMethSpec - // call the function returned by sprintf - yield mkLdarg0 - if ilThisTy.Boxity = ILBoxity.AsValue then - yield mkNormalLdobj ilThisTy ] @ - callInstrs), - None)) + + let ilInstrs = + [ // load the hardwired format string + I_ldstr "%+0.8A" + // make the printf format object + mkNormalNewobj newFormatMethSpec + // call sprintf + mkNormalCall sprintfMethSpec + // call the function returned by sprintf + mkLdarg0 + if ilThisTy.Boxity = ILBoxity.AsValue then + mkNormalLdobj ilThisTy + yield! callInstrs ] + + let ilMethodBody = mkMethodBody (true, [], 2, nonBranchingInstrsToCode ilInstrs, None, eenv.imports) + + let ilMethodDef = mkILNonGenericInstanceMethod (debugDisplayMethodName, ILMemberAccess.Assembly, [], mkILReturn g.ilg.typ_Object, ilMethodBody) yield ilMethodDef.WithSpecialName |> AddNonUserCompilerGeneratedAttribs g | None, _ -> //printfn "sprintf not found" @@ -7147,7 +8247,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // Build record constructors and the funky methods that go with records and delegate types. // Constructors and delegate methods have the same access as the representation match tyconRepr with - | TRecdRepr _ when not (tycon.IsEnumTycon) -> + | TFSharpRecdRepr _ when not tycon.IsEnumTycon -> // No constructor for enum types // Otherwise find all the non-static, non zero-init fields and build a constructor let relevantFields = @@ -7156,49 +8256,53 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let fieldNamesAndTypes = relevantFields - |> List.map (fun (_, ilFieldName, _, _, _, ilPropType, _, fspec) -> (fspec.Name, ilFieldName, ilPropType)) + |> List.map (fun (_, ilFieldName, _, _, _, ilPropType, _, fspec) -> (fspec.LogicalName, ilFieldName, ilPropType)) let isStructRecord = tycon.IsStructRecordOrUnionTycon // No type spec if the record is a value type let spec = if isStructRecord then None else Some(g.ilg.typ_Object.TypeSpec) - let ilMethodDef = mkILSimpleStorageCtorWithParamNames(None, spec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess) + let ilMethodDef = mkILSimpleStorageCtorWithParamNames(spec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess, None, eenv.imports) yield ilMethodDef // FSharp 1.0 bug 1988: Explicitly setting the ComVisible(true) attribute on an F# type causes an F# record to be emitted in a way that enables mutation for COM interop scenarios // FSharp 3.0 feature: adding CLIMutable to a record type causes emit of default constructor, and all fields get property setters // Records that are value types do not create a default constructor with CLIMutable or ComVisible if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute g g.attrib_ComVisibleAttribute tycon.Attribs = Some true)) then - yield mkILSimpleStorageCtor(None, Some g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess) - + yield mkILSimpleStorageCtor(Some g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess, None, eenv.imports) + if not (tycon.HasMember g "ToString" []) then yield! GenToStringMethod cenv eenv ilThisTy m + | TFSharpObjectRepr r when tycon.IsFSharpDelegateTycon -> // Build all the methods that go with a delegate type match r.fsobjmodel_kind with - | TTyconDelegate ss -> - let p, r = + | TFSharpDelegate slotSig -> + + let parameters, ret = // When "type delegateTy = delegate of unit -> returnTy", // suppress the unit arg from delegate .Invoke vslot. - let (TSlotSig(nm, ty, ctps, mtps, paraml, returnTy)) = ss + let (TSlotSig(nm, ty, ctps, mtps, paraml, returnTy)) = slotSig let paraml = match paraml with | [[tsp]] when isUnitTy g tsp.Type -> [] (* suppress unit arg *) | paraml -> paraml GenActualSlotsig m cenv eenvinner (TSlotSig(nm, ty, ctps, mtps, paraml, returnTy)) [] [] - yield! mkILDelegateMethods reprAccess g.ilg (g.iltyp_AsyncCallback, g.iltyp_IAsyncResult) (p, r) + + yield! mkILDelegateMethods reprAccess g.ilg (g.iltyp_AsyncCallback, g.iltyp_IAsyncResult) (parameters, ret) | _ -> () - | TUnionRepr _ when not (tycon.HasMember g "ToString" []) -> + + | TFSharpUnionRepr _ when not (tycon.HasMember g "ToString" []) -> yield! GenToStringMethod cenv eenv ilThisTy m | _ -> () ] - + let ilMethods = methodDefs @ augmentOverrideMethodDefs @ abstractMethodDefs let ilProperties = mkILProperties (ilPropertyDefsForFields @ abstractPropDefs) let ilEvents = mkILEvents abstractEventDefs let ilFields = mkILFields ilFieldDefs - + let tdef, tdefDiscards = let isSerializable = (TryFindFSharpBoolAttribute g g.attrib_AutoSerializableAttribute tycon.Attribs <> Some false) @@ -7208,10 +8312,10 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = let tdef = tdef.With(customAttrs = mkILCustomAttrs ilCustomAttrs, genericParams = ilGenParams) tdef, None - | TRecdRepr _ | TFSharpObjectRepr _ as tyconRepr -> + | TFSharpRecdRepr _ | TFSharpObjectRepr _ as tyconRepr -> let super = superOfTycon g tycon let ilBaseTy = GenType cenv.amap m eenvinner.tyenv super - + // Build a basic type definition let isObjectType = (match tyconRepr with TFSharpObjectRepr _ -> true | _ -> false) let ilAttrs = @@ -7221,7 +8325,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = then SourceConstructFlags.ObjectType elif hiddenRepr then SourceConstructFlags.RecordType ||| SourceConstructFlags.NonPublicRepresentation else SourceConstructFlags.RecordType)) ] - + // For now, generic types always use ILTypeInit.BeforeField. This is because // there appear to be some cases where ILTypeInit.OnAny causes problems for // the .NET CLR when used in conjunction with generic classes in cross-DLL @@ -7246,8 +8350,12 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // Set some the extra entries in the definition let isTheSealedAttribute = tyconRefEq g tcref g.attrib_SealedAttribute.TyconRef - let tdef = tdef.WithSealed(isSealedTy g thisTy || isTheSealedAttribute).WithSerializable(isSerializable).WithAbstract(isAbstract).WithImport(isComInteropTy g thisTy) - let tdef = tdef.With(methodImpls=mkILMethodImpls methodImpls) + let tdef = + tdef.WithSealed(isSealedTy g thisTy || isTheSealedAttribute) + .WithSerializable(isSerializable) + .WithAbstract(isAbstract) + .WithImport(isComInteropTy g thisTy) + .With(methodImpls=mkILMethodImpls methodImpls) let tdLayout, tdEncoding = match TryFindFSharpAttribute g g.attrib_StructLayoutAttribute tycon.Attribs with @@ -7277,7 +8385,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi | _ when (match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) -> - + // All structs are sequential by default // Structs with no instance fields get size 1, pack 0 if tycon.AllFieldsArray |> Array.exists (fun f -> not f.IsStatic) || @@ -7288,46 +8396,47 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = ILTypeDefLayout.Sequential { Size=None; Pack=None }, ILDefaultPInvokeEncoding.Ansi else ILTypeDefLayout.Sequential { Size=Some 1; Pack=Some 0us }, ILDefaultPInvokeEncoding.Ansi - + | _ -> ILTypeDefLayout.Auto, ILDefaultPInvokeEncoding.Ansi - + // if the type's layout is Explicit, ensure that each field has a valid offset let validateExplicit (fdef: ILFieldDef) = match fdef.Offset with // Remove field suffix "@" for pretty printing | None -> errorR(Error(FSComp.SR.ilFieldDoesNotHaveValidOffsetForStructureLayout(tdef.Name, fdef.Name.Replace("@", "")), (trimRangeToLine m))) | _ -> () - + // if the type's layout is Sequential, no offsets should be applied let validateSequential (fdef: ILFieldDef) = match fdef.Offset with | Some _ -> errorR(Error(FSComp.SR.ilFieldHasOffsetForSequentialLayout(), (trimRangeToLine m))) | _ -> () - + match tdLayout with - | ILTypeDefLayout.Explicit(_) -> List.iter validateExplicit ilFieldDefs - | ILTypeDefLayout.Sequential(_) -> List.iter validateSequential ilFieldDefs + | ILTypeDefLayout.Explicit _ -> List.iter validateExplicit ilFieldDefs + | ILTypeDefLayout.Sequential _ -> List.iter validateSequential ilFieldDefs | _ -> () - + let tdef = tdef.WithKind(ilTypeDefKind).WithLayout(tdLayout).WithEncoding(tdEncoding) tdef, None - | TUnionRepr _ -> + | TFSharpUnionRepr _ -> let alternatives = tycon.UnionCasesArray |> Array.mapi (fun i ucspec -> { altName=ucspec.CompiledName altFields=GenUnionCaseRef cenv.amap m eenvinner.tyenv i ucspec.RecdFieldsArray altCustomAttrs= mkILCustomAttrs (GenAttrs cenv eenv ucspec.Attribs @ [mkCompilationMappingAttrWithSeqNum g (int SourceConstructFlags.UnionCase) i]) }) let cuinfo = - { cudReprAccess=reprAccess - cudNullPermitted=IsUnionTypeWithNullAsTrueValue g tycon - cudHelpersAccess=reprAccess - cudHasHelpers=ComputeUnionHasHelpers g tcref - cudDebugProxies= generateDebugProxies - cudDebugDisplayAttributes= ilDebugDisplayAttributes - cudAlternatives= alternatives - cudWhere = None} + { UnionCasesAccessibility=reprAccess + IsNullPermitted=IsUnionTypeWithNullAsTrueValue g tycon + HelpersAccessibility=reprAccess + HasHelpers=ComputeUnionHasHelpers g tcref + GenerateDebugProxies= generateDebugProxies + DebugDisplayAttributes= ilDebugDisplayAttributes + UnionCases= alternatives + DebugPoint = None + DebugImports = eenv.imports } let layout = if isStructTy g thisTy then @@ -7367,7 +8476,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = .WithAccess(access) .WithInitSemantics(ILTypeInit.BeforeField) - let tdef2 = g.eraseClassUnionDef tref tdef cuinfo + let tdef2 = g.EraseClassUnionDef tref tdef cuinfo // Discard the user-supplied (i.e. prim-type.fs) implementations of the get_Empty, get_IsEmpty, get_Value and get_None and Some methods. // This is because we will replace their implementations by ones that load the unique @@ -7376,12 +8485,12 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // Also discard the F#-compiler supplied implementation of the Empty, IsEmpty, Value and None properties. let tdefDiscards = Some ((fun (md: ILMethodDef) -> - (cuinfo.cudHasHelpers = SpecialFSharpListHelpers && (md.Name = "get_Empty" || md.Name = "Cons" || md.Name = "get_IsEmpty")) || - (cuinfo.cudHasHelpers = SpecialFSharpOptionHelpers && (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some"))), + (cuinfo.HasHelpers = SpecialFSharpListHelpers && (md.Name = "get_Empty" || md.Name = "Cons" || md.Name = "get_IsEmpty")) || + (cuinfo.HasHelpers = SpecialFSharpOptionHelpers && (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some"))), (fun (pd: ILPropertyDef) -> - (cuinfo.cudHasHelpers = SpecialFSharpListHelpers && (pd.Name = "Empty" || pd.Name = "IsEmpty" )) || - (cuinfo.cudHasHelpers = SpecialFSharpOptionHelpers && (pd.Name = "Value" || pd.Name = "None")))) + (cuinfo.HasHelpers = SpecialFSharpListHelpers && (pd.Name = "Empty" || pd.Name = "IsEmpty" )) || + (cuinfo.HasHelpers = SpecialFSharpOptionHelpers && (pd.Name = "Value" || pd.Name = "None")))) tdef2, tdefDiscards @@ -7398,10 +8507,10 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) = // // In this case, the .cctor for this type must force the .cctor of the backing static class for the file. if tycon.TyparsNoRange.IsEmpty && tycon.MembersOfFSharpTyconSorted |> List.exists (fun vref -> vref.Deref.IsClassConstructor) then - GenForceWholeFileInitializationAsPartOfCCtor cenv mgbuf lazyInitInfo tref m + GenForceWholeFileInitializationAsPartOfCCtor cenv mgbuf lazyInitInfo tref eenv.imports m + - /// Generate the type for an F# exception declaration. and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = let g = cenv.g @@ -7411,19 +8520,19 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = | TExnFresh _ -> let ilThisTy = GenExnType cenv.amap m eenv.tyenv exncref let tref = ilThisTy.TypeRef - let isHidden = IsHiddenTycon g eenv.sigToImplRemapInfo exnc + let isHidden = IsHiddenTycon eenv.sigToImplRemapInfo exnc let access = ComputeTypeAccess tref isHidden let reprAccess = ComputeMemberAccess isHidden let fspecs = exnc.TrueInstanceFieldsAsList let ilMethodDefsForProperties, ilFieldDefs, ilPropertyDefs, fieldNamesAndTypes = [ for i, fld in Seq.indexed fspecs do - let ilPropName = fld.Name + let ilPropName = fld.LogicalName let ilPropType = GenType cenv.amap m eenv.tyenv fld.FormalType - let ilMethName = "get_" + fld.Name + let ilMethName = "get_" + fld.LogicalName let ilFieldName = ComputeFieldName exnc fld let ilMethodDef = mkLdfldMethodDef (ilMethName, reprAccess, false, ilThisTy, ilFieldName, ilPropType) - let ilFieldDef = IL.mkILInstanceField(ilFieldName, ilPropType, None, ILMemberAccess.Assembly) + let ilFieldDef = mkILInstanceField(ilFieldName, ilPropType, None, ILMemberAccess.Assembly) let ilPropDef = ILPropertyDef(name = ilPropName, attributes = PropertyAttributes.None, @@ -7438,13 +8547,13 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = |> List.unzip4 let ilCtorDef = - mkILSimpleStorageCtorWithParamNames(None, Some g.iltyp_Exception.TypeSpec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess) + mkILSimpleStorageCtorWithParamNames(Some g.iltyp_Exception.TypeSpec, ilThisTy, [], ChooseParamNames fieldNamesAndTypes, reprAccess, None, eenv.imports) // In compiled code, all exception types get a parameterless constructor for use with XML serialization // This does default-initialization of all fields let ilCtorDefNoArgs = if not (isNil fieldNamesAndTypes) then - [ mkILSimpleStorageCtor(None, Some g.iltyp_Exception.TypeSpec, ilThisTy, [], [], reprAccess) ] + [ mkILSimpleStorageCtor(Some g.iltyp_Exception.TypeSpec, ilThisTy, [], [], reprAccess, None, eenv.imports) ] else [] @@ -7452,45 +8561,20 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = // do not emit serialization related members if target framework lacks SerializationInfo or StreamingContext match g.iltyp_SerializationInfo, g.iltyp_StreamingContext with | Some serializationInfoType, Some streamingContextType -> + + let ilInstrsForSerialization = + [ mkLdarg0 + mkLdarg 1us + mkLdarg 2us + mkNormalCall (mkILCtorMethSpecForTy (g.iltyp_Exception, [serializationInfoType; streamingContextType])) ] + |> nonBranchingInstrsToCode + let ilCtorDefForSerialization = mkILCtor(ILMemberAccess.Family, [mkILParamNamed("info", serializationInfoType);mkILParamNamed("context", streamingContextType)], - mkMethodBody - (false, [], 8, - nonBranchingInstrsToCode - [ mkLdarg0 - mkLdarg 1us - mkLdarg 2us - mkNormalCall (mkILCtorMethSpecForTy (g.iltyp_Exception, [serializationInfoType; streamingContextType])) ], - None)) + mkMethodBody (false, [], 8, ilInstrsForSerialization, None, eenv.imports)) [ilCtorDefForSerialization] -(* - let getObjectDataMethodForSerialization = - let ilMethodDef = - mkILNonGenericVirtualMethod - ("GetObjectData", ILMemberAccess.Public, - [mkILParamNamed ("info", serializationInfoType);mkILParamNamed("context", g.iltyp_StreamingContext)], - mkILReturn ILType.Void, - (let code = - nonBranchingInstrsToCode - [ mkLdarg0 - mkLdarg 1us - mkLdarg 2us - mkNormalCall (mkILNonGenericInstanceMethSpecInTy (g.iltyp_Exception, "GetObjectData", [serializationInfoType; g.iltyp_StreamingContext], ILType.Void)) - ] - mkMethodBody(true, [], 8, code, None))) - // Here we must encode: [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] - // In ILDASM this is: .permissionset demand = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SerializationFormatter' = bool(true)}} - match g.tref_SecurityPermissionAttribute with - | None -> ilMethodDef - | Some securityPermissionAttributeType -> - { ilMethodDef with - SecurityDecls=mkILSecurityDecls [ IL.mkPermissionSet g.ilg (ILSecurityAction.Demand, [(securityPermissionAttributeType, [("SerializationFormatter", g.ilg.typ_Bool, ILAttribElem.Bool true)])])] - HasSecurity=true } - [ilCtorDefForSerialization; getObjectDataMethodForSerialization] -*) -//#endif | _ -> [] let ilTypeName = tref.Name @@ -7511,50 +8595,55 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) = mgbuf.AddTypeDef(tref, tdef, false, false, None) -let CodegenAssembly cenv eenv mgbuf fileImpls = - if not (isNil fileImpls) then - let a, b = List.frontAndBack fileImpls - let eenv = List.fold (GenTopImpl cenv mgbuf None) eenv a - let eenv = GenTopImpl cenv mgbuf cenv.opts.mainMethodInfo eenv b - - // Some constructs generate residue types and bindings. Generate these now. They don't result in any - // top-level initialization code. - begin - let extraBindings = mgbuf.GrabExtraBindingsToGenerate() - //printfn "#extraBindings = %d" extraBindings.Length - if extraBindings.Length > 0 then - let mexpr = TMDefs [ for b in extraBindings -> TMDefLet(b, range0) ] - let _emptyTopInstrs, _emptyTopCode = - CodeGenMethod cenv mgbuf ([], "unused", eenv, 0, (fun cgbuf eenv -> - let lazyInitInfo = ResizeArray() - let qname = QualifiedNameOfFile(mkSynId range0 "unused") - LocalScope "module" cgbuf (fun scopeMarks -> - let eenv = AddBindingsForModuleDef (fun cloc v -> AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v) eenv.cloc eenv mexpr - GenModuleDef cenv cgbuf qname lazyInitInfo eenv mexpr)), range0) - //printfn "#_emptyTopInstrs = %d" _emptyTopInstrs.Length - () - end - - mgbuf.AddInitializeScriptsInOrderToEntryPoint() +let CodegenAssembly cenv eenv mgbuf implFiles = + if not (isNil implFiles) then + let a, b = List.frontAndBack implFiles + let eenv = List.fold (GenImplFile cenv mgbuf None) eenv a + let eenv = GenImplFile cenv mgbuf cenv.opts.mainMethodInfo eenv b + + // Some constructs generate residue types and bindings. Generate these now. They don't result in any + // top-level initialization code. + let extraBindings = mgbuf.GrabExtraBindingsToGenerate() + //printfn "#extraBindings = %d" extraBindings.Length + if not (isNil extraBindings) then + let mexpr = TMDefs [ for b in extraBindings -> TMDefLet(b, range0) ] + let _emptyTopInstrs, _emptyTopCode = + CodeGenMethod cenv mgbuf ([], "unused", eenv, 0, None, (fun cgbuf eenv -> + let lazyInitInfo = ResizeArray() + let qname = QualifiedNameOfFile(mkSynId range0 "unused") + LocalScope "module" cgbuf (fun (_, endMark) -> + let eenv = AddBindingsForModuleDef (AllocTopValWithinExpr cenv cgbuf endMark) eenv.cloc eenv mexpr + let _eenvEnv = GenModuleDef cenv cgbuf qname lazyInitInfo eenv mexpr + ())), range0) + //printfn "#_emptyTopInstrs = %d" _emptyTopInstrs.Length + () + + mgbuf.AddInitializeScriptsInOrderToEntryPoint(eenv.imports) //------------------------------------------------------------------------- // When generating a module we just write into mutable // structures representing the contents of the module. //------------------------------------------------------------------------- -let GetEmptyIlxGenEnv (ilg: ILGlobals) ccu = +let GetEmptyIlxGenEnv (g: TcGlobals) ccu = let thisCompLoc = CompLocForCcu ccu { tyenv=TypeReprEnv.Empty cloc = thisCompLoc + exitSequel = Return valsInScope=ValMap<_>.Empty - someTypeInThisAssembly=ilg.typ_Object (* dummy value *) + witnessesInScope = EmptyTraitWitnessInfoHashMap g + suppressWitnesses = false + someTypeInThisAssembly= g.ilg.typ_Object // dummy value isFinalFile = false letBoundVars=[] liveLocals=IntMap.empty() innerVals = [] sigToImplRemapInfo = [] (* "module remap info" *) withinSEH = false - isInLoop = false } + isInLoop = false + initLocals = true + imports = None + } type IlxGenResults = { ilTypeDefs: ILTypeDef list @@ -7565,20 +8654,20 @@ type IlxGenResults = quotationResourceInfo: (ILTypeRef list * byte[]) list } -let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization fileImpls, assemAttribs, moduleAttribs) = +let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization implFiles, assemAttribs, moduleAttribs) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.IlxGen let g = cenv.g // Generate the implementations into the mgbuf - let mgbuf = new AssemblyBuilder(cenv, anonTypeTable) + let mgbuf = AssemblyBuilder(cenv, anonTypeTable) let eenv = { eenv with cloc = CompLocForFragment cenv.opts.fragName cenv.viewCcu } // Generate the PrivateImplementationDetails type GenTypeDefForCompLoc (cenv, eenv, mgbuf, CompLocForPrivateImplementationDetails eenv.cloc, useHiddenInitCode, [], ILTypeInit.BeforeField, true, (* atEnd= *) true) // Generate the whole assembly - CodegenAssembly cenv eenv mgbuf fileImpls + CodegenAssembly cenv eenv mgbuf implFiles let ilAssemAttrs = GenAttrs cenv eenv assemAttribs @@ -7590,29 +8679,22 @@ let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization file match reflectedDefinitions with | [] -> [] | _ -> - let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes) + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, cenv.tcVal, QuotationTranslator.IsReflectedDefinition.Yes) let defns = reflectedDefinitions |> List.choose (fun ((methName, v), e) -> try - let ety = tyOfExpr g e - let tps, taue, _ = - match e with - | Expr.TyLambda (_, tps, b, _, _) -> tps, b, applyForallTy g ety (List.map mkTyparTy tps) - | _ -> [], e, ety - let env = QuotationTranslator.QuotationTranslationEnv.Empty.BindTypars tps - let astExpr = QuotationTranslator.ConvExprPublic qscope env taue - let mbaseR = QuotationTranslator.ConvMethodBase qscope env (methName, v) - + let mbaseR, astExpr = QuotationTranslator.ConvReflectedDefinition qscope methName v e + Some(mbaseR, astExpr) with | QuotationTranslator.InvalidQuotedTerm e -> warning e; None) - let referencedTypeDefs, freeTypes, spliceArgExprs = qscope.Close() + let referencedTypeDefs, typeSplices, exprSplices = qscope.Close() - for (_freeType, m) in freeTypes do + for _typeSplice, m in typeSplices do error(InternalError("A free type variable was detected in a reflected definition", m)) - for (_spliceArgExpr, m) in spliceArgExprs do + for _exprSplice, m in exprSplices do error(Error(FSComp.SR.ilReflectedDefinitionsCannotUseSliceOperator(), m)) let defnsResourceBytes = defns |> QuotationPickler.PickleDefns @@ -7621,7 +8703,7 @@ let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization file let ilNetModuleAttrs = GenAttrs cenv eenv moduleAttribs - let casApplied = new Dictionary() + let casApplied = Dictionary() let securityAttrs, topAssemblyAttrs = assemAttribs |> List.partition (fun a -> IsSecurityAttribute g cenv.amap casApplied a rangeStartup) // remove any security attributes from the top-level assembly attribute list let permissionSets = CreatePermissionSets cenv eenv securityAttrs @@ -7644,10 +8726,10 @@ open System /// The lookup* functions are the conversions available from ilreflect. type ExecutionContext = - { LookupFieldRef: (ILFieldRef -> FieldInfo) - LookupMethodRef: (ILMethodRef -> MethodInfo) - LookupTypeRef: (ILTypeRef -> Type) - LookupType: (ILType -> Type) } + { LookupFieldRef: ILFieldRef -> FieldInfo + LookupMethodRef: ILMethodRef -> MethodInfo + LookupTypeRef: ILTypeRef -> Type + LookupType: ILType -> Type } // A helper to generate a default value for any System.Type. I couldn't find a System.Reflection // method to do this. @@ -7672,7 +8754,7 @@ let LookupGeneratedValue (amap: ImportMap) (ctxt: ExecutionContext) eenv (v: Val ctxt.LookupType ilTy // Lookup the compiled v value (as an object). match StorageForVal amap.g v.Range v eenv with - | StaticField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> + | StaticPropertyWithField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> let obj = if hasLiteralAttr then let staticTy = ctxt.LookupTypeRef fspec.DeclaringTypeRef @@ -7699,74 +8781,97 @@ let LookupGeneratedValue (amap: ImportMap) (ctxt: ExecutionContext) eenv (v: Val | Null -> Some (null, objTyp()) - | Local _ -> None + | Local _ -> None | Method _ -> None | Arg _ -> None | Env _ -> None with e -> -#if DEBUG +#if DEBUG printf "ilxGen.LookupGeneratedValue for v=%s caught exception:\n%A\n\n" v.LogicalName e #endif None +// Invoke the set_Foo method for a declaration with a value. Used to create variables with values programatically in fsi.exe. +let SetGeneratedValue (ctxt: ExecutionContext) (g: TcGlobals) eenv isForced (v: Val) (value: obj) = + try + match StorageForVal g v.Range v eenv with + | StaticPropertyWithField (fspec, _, hasLiteralAttr, _, _, _, _f, ilSetterMethRef, _) -> + if not hasLiteralAttr && (v.IsMutable || isForced) then + if isForced then + let staticTy = ctxt.LookupTypeRef fspec.DeclaringTypeRef + + let fieldInfo = staticTy.GetField(fspec.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) + fieldInfo.SetValue(null, value) + else + let staticTy = ctxt.LookupTypeRef ilSetterMethRef.DeclaringTypeRef + + let methInfo = staticTy.GetMethod(ilSetterMethRef.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) + methInfo.Invoke (null, [| value |]) |> ignore + | _ -> () + with + e -> +#if DEBUG + printf "ilxGen.SetGeneratedValue for v=%s caught exception:\n%A\n\n" v.LogicalName e +#endif + () + // Invoke the set_Foo method for a declaration with a default/null value. Used to release storage in fsi.exe let ClearGeneratedValue (ctxt: ExecutionContext) (g: TcGlobals) eenv (v: Val) = try match StorageForVal g v.Range v eenv with - | StaticField (fspec, _, hasLiteralAttr, _, _, _, _ilGetterMethRef, ilSetterMethRef, _) -> + | StaticPropertyWithField (fspec, _, hasLiteralAttr, _, _, _, _ilGetterMethRef, _ilSetterMethRef, _) -> if not hasLiteralAttr && v.IsMutable then - let staticTy = ctxt.LookupTypeRef ilSetterMethRef.DeclaringTypeRef let ty = ctxt.LookupType fspec.ActualType - - let methInfo = staticTy.GetMethod(ilSetterMethRef.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - methInfo.Invoke (null, [| defaultOf ty |]) |> ignore + SetGeneratedValue ctxt g eenv false v (defaultOf ty) | _ -> () with e -> -#if DEBUG +#if DEBUG printf "ilxGen.ClearGeneratedValue for v=%s caught exception:\n%A\n\n" v.LogicalName e #endif () /// The published API from the ILX code generator -type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: ConstraintSolver.TcValF, ccu: Tast.CcuThunk) = +type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: ConstraintSolver.TcValF, ccu: CcuThunk) = // The incremental state held by the ILX code generator - let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals.ilg ccu + let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals ccu let anonTypeTable = AnonTypeGenerationTable() - let intraAssemblyInfo = { StaticFieldInfo = new Dictionary<_, _>(HashIdentity.Structural) } - let casApplied = new Dictionary() + // Dictionaries are safe here as they will only be used during the codegen stage - will happen on a single thread. + let intraAssemblyInfo = { StaticFieldInfo = Dictionary<_, _>(HashIdentity.Structural) } + let casApplied = Dictionary() /// Register a set of referenced assemblies with the ILX code generator - member __.AddExternalCcus ccus = + member _.AddExternalCcus ccus = ilxGenEnv <- AddExternalCcusToIlxGenEnv amap tcGlobals ilxGenEnv ccus /// Register a fragment of the current assembly with the ILX code generator. If 'isIncrementalFragment' is true then the input /// is assumed to be a fragment 'typed' into FSI.EXE, otherwise the input is assumed to be the result of a '#load' - member __.AddIncrementalLocalAssemblyFragment (isIncrementalFragment, fragName, typedImplFiles) = + member _.AddIncrementalLocalAssemblyFragment (isIncrementalFragment, fragName, typedImplFiles) = ilxGenEnv <- AddIncrementalLocalAssemblyFragmentToIlxGenEnv (amap, isIncrementalFragment, tcGlobals, ccu, fragName, intraAssemblyInfo, ilxGenEnv, typedImplFiles) /// Generate ILX code for an assembly fragment - member __.GenerateCode (codeGenOpts, typedAssembly, assemAttribs, moduleAttribs) = + member _.GenerateCode (codeGenOpts, typedAssembly, assemAttribs, moduleAttribs) = let cenv: cenv = { g=tcGlobals - TcVal = tcVal + tcVal = tcVal viewCcu = ccu ilUnitTy = None amap = amap casApplied = casApplied intraAssemblyInfo = intraAssemblyInfo opts = codeGenOpts - optimizeDuringCodeGen = (fun x -> x) + optimizeDuringCodeGen = (fun _flag expr -> expr) exprRecursionDepth = 0 delayedGenMethods = Queue () } GenerateCode (cenv, anonTypeTable, ilxGenEnv, typedAssembly, assemAttribs, moduleAttribs) /// Invert the compilation of the given value and clear the storage of the value - member __.ClearGeneratedValue (ctxt, v) = ClearGeneratedValue ctxt tcGlobals ilxGenEnv v - - /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type - member __.LookupGeneratedValue (ctxt, v) = LookupGeneratedValue amap ctxt ilxGenEnv v + member _.ClearGeneratedValue (ctxt, v) = ClearGeneratedValue ctxt tcGlobals ilxGenEnv v + /// Invert the compilation of the given value and set the storage of the value, even if it is immutable + member _.ForceSetGeneratedValue (ctxt, v, value: obj) = SetGeneratedValue ctxt tcGlobals ilxGenEnv true v value + /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type + member _.LookupGeneratedValue (ctxt, v) = LookupGeneratedValue amap ctxt ilxGenEnv v diff --git a/src/fsharp/IlxGen.fsi b/src/fsharp/IlxGen.fsi index c93d95fdfe1..7fe28f1616b 100644 --- a/src/fsharp/IlxGen.fsi +++ b/src/fsharp/IlxGen.fsi @@ -5,9 +5,8 @@ module internal FSharp.Compiler.IlxGen open System open System.IO open System.Reflection -open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.Tast +open FSharp.Compiler.TypedTree open FSharp.Compiler.TcGlobals /// Indicates how the generated IL code is ultimately emitted @@ -17,89 +16,100 @@ type IlxGenBackend = [] type internal IlxGenOptions = - { fragName : string + { fragName: string /// Indicates if we are generating filter blocks - generateFilterBlocks : bool + generateFilterBlocks: bool /// Indicates if we should workaround old reflection emit bugs - workAroundReflectionEmitBugs : bool + workAroundReflectionEmitBugs: bool /// Indicates if static array data should be emitted using static blobs - emitConstantArraysUsingStaticDataBlobs : bool + emitConstantArraysUsingStaticDataBlobs: bool /// If this is set, then the last module becomes the "main" module - mainMethodInfo : Attribs option + mainMethodInfo: Attribs option /// Indicates if local optimizations are active - localOptimizationsAreOn : bool + localOptimizationsEnabled: bool /// Indicates if we are generating debug symbols or not - generateDebugSymbols : bool + generateDebugSymbols: bool /// A flag to help test emit of debug information - testFlagEmitFeeFeeAs100001 : bool + testFlagEmitFeeFeeAs100001: bool /// Indicates which backend we are generating code for - ilxBackend : IlxGenBackend + ilxBackend: IlxGenBackend /// Indicates the code is being generated in FSI.EXE and is executed immediately after code generation /// This includes all interactively compiled code, including #load, definitions, and expressions - isInteractive : bool + isInteractive: bool /// Indicates the code generated is an interactive 'it' expression. We generate a setter to allow clearing of the underlying /// storage, even though 'it' is not logically mutable - isInteractiveItExpr : bool + isInteractiveItExpr: bool /// Indicates that, whenever possible, use callvirt instead of call - alwaysCallVirt : bool } + alwaysCallVirt: bool + } /// The results of the ILX compilation of one fragment of an assembly type public IlxGenResults = - { /// The generated IL/ILX type definitions - ilTypeDefs : ILTypeDef list + { + /// The generated IL/ILX type definitions + ilTypeDefs: ILTypeDef list + /// The generated IL/ILX assembly attributes - ilAssemAttrs : ILAttribute list + ilAssemAttrs: ILAttribute list + /// The generated IL/ILX .NET module attributes - ilNetModuleAttrs : ILAttribute list + ilNetModuleAttrs: ILAttribute list + /// The attributes for the assembly in F# form - topAssemblyAttrs : Attribs + topAssemblyAttrs: Attribs + /// The security attributes to attach to the assembly - permissionSets : ILSecurityDecl list - /// The generated IL/ILX resources associated with F# quotations - quotationResourceInfo : (ILTypeRef list * byte[]) list } + permissionSets: ILSecurityDecl list + /// The generated IL/ILX resources associated with F# quotations + quotationResourceInfo: (ILTypeRef list * byte[]) list + } /// Used to support the compilation-inversion operations "ClearGeneratedValue" and "LookupGeneratedValue" type ExecutionContext = - { LookupFieldRef : (ILFieldRef -> FieldInfo) - LookupMethodRef : (ILMethodRef -> MethodInfo) - LookupTypeRef : (ILTypeRef -> Type) - LookupType : (ILType -> Type) } + { + LookupFieldRef: ILFieldRef -> FieldInfo + LookupMethodRef: ILMethodRef -> MethodInfo + LookupTypeRef: ILTypeRef -> Type + LookupType: ILType -> Type + } /// An incremental ILX code generator for a single assembly type public IlxAssemblyGenerator = /// Create an incremental ILX code generator for a single assembly - new : Import.ImportMap * TcGlobals * ConstraintSolver.TcValF * CcuThunk -> IlxAssemblyGenerator + new: Import.ImportMap * TcGlobals * ConstraintSolver.TcValF * CcuThunk -> IlxAssemblyGenerator /// Register a set of referenced assemblies with the ILX code generator - member AddExternalCcus : CcuThunk list -> unit + member AddExternalCcus: CcuThunk list -> unit /// Register a fragment of the current assembly with the ILX code generator. If 'isIncrementalFragment' is true then the input /// is assumed to be a fragment 'typed' into FSI.EXE, otherwise the input is assumed to be the result of a '#load' - member AddIncrementalLocalAssemblyFragment : isIncrementalFragment: bool * fragName:string * typedImplFiles: TypedImplFile list -> unit + member AddIncrementalLocalAssemblyFragment: isIncrementalFragment: bool * fragName:string * typedImplFiles: TypedImplFile list -> unit /// Generate ILX code for an assembly fragment - member GenerateCode : IlxGenOptions * TypedAssemblyAfterOptimization * Attribs * Attribs -> IlxGenResults + member GenerateCode: IlxGenOptions * TypedAssemblyAfterOptimization * Attribs * Attribs -> IlxGenResults /// Invert the compilation of the given value and clear the storage of the value - member ClearGeneratedValue : ExecutionContext * Val -> unit + member ClearGeneratedValue: ExecutionContext * Val -> unit - /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type - member LookupGeneratedValue : ExecutionContext * Val -> (obj * System.Type) option + /// Invert the compilation of the given value and set the storage of the value, even if it is immutable + member ForceSetGeneratedValue: ExecutionContext * Val * obj -> unit + /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type + member LookupGeneratedValue: ExecutionContext * Val -> (obj * Type) option -val ReportStatistics : TextWriter -> unit +val ReportStatistics: TextWriter -> unit /// Determine if an F#-declared value, method or function is compiled as a method. -val IsFSharpValCompiledAsMethod : TcGlobals -> Val -> bool +val IsFSharpValCompiledAsMethod: TcGlobals -> Val -> bool diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs index 5e655ed0e7e..cd5f95eb116 100644 --- a/src/fsharp/InfoReader.fs +++ b/src/fsharp/InfoReader.fs @@ -4,22 +4,26 @@ /// Select members from a type by name, searching the type hierarchy if needed module internal FSharp.Compiler.InfoReader -open System.Collections.Generic - -open FSharp.Compiler.AbstractIL.Internal.Library +open System.Collections.Concurrent +open Internal.Utilities.Library open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast open FSharp.Compiler.AttributeChecking open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features open FSharp.Compiler.Infos -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypeRelations /// Use the given function to select some of the member values from the members of an F# type -let private SelectImmediateMemberVals g optFilter f (tcref: TyconRef) = +let SelectImmediateMemberVals g optFilter f (tcref: TyconRef) = let chooser (vref: ValRef) = match vref.MemberInfo with // The 'when' condition is a workaround for the fact that values providing @@ -78,7 +82,7 @@ let rec GetImmediateIntrinsicMethInfosOfTypeAux (optFilter, ad) g amap m origTy GetImmediateIntrinsicMethInfosOfTypeAux (optFilter, ad) g amap m origTy betterMetadataTy |> List.filter (fun minfo -> not minfo.IsInstance) else - match tryDestAppTy g metadataTy with + match tryTcrefOfAppTy g metadataTy with | ValueNone -> [] | ValueSome tcref -> SelectImmediateMemberVals g optFilter (TrySelectMemberVal g optFilter origTy None) tcref @@ -103,7 +107,7 @@ type PropertyCollector(g, amap, m, ty, optFilter, ad) = PropInfosEquivByNameAndPartialSig EraseNone g amap m pinfo1 pinfo2 && pinfo1.IsDefiniteFSharpOverride = pinfo2.IsDefiniteFSharpOverride ) - let props = new Dictionary(hashIdentity) + let props = ConcurrentDictionary(hashIdentity) let add pinfo = match props.TryGetValue pinfo, pinfo with @@ -118,20 +122,20 @@ type PropertyCollector(g, amap, m, ty, optFilter, ad) = | _ -> props.[pinfo] <- pinfo - member x.Collect(membInfo: ValMemberInfo, vref: ValRef) = + member _.Collect(membInfo: ValMemberInfo, vref: ValRef) = match membInfo.MemberFlags.MemberKind with - | MemberKind.PropertyGet -> + | SynMemberKind.PropertyGet -> let pinfo = FSProp(g, ty, Some vref, None) if checkFilter optFilter vref.PropertyName && IsPropInfoAccessible g amap m ad pinfo then add pinfo - | MemberKind.PropertySet -> + | SynMemberKind.PropertySet -> let pinfo = FSProp(g, ty, None, Some vref) if checkFilter optFilter vref.PropertyName && IsPropInfoAccessible g amap m ad pinfo then add pinfo | _ -> () - member x.Close() = [ for KeyValue(_, pinfo) in props -> pinfo ] + member _.Close() = [ for KeyValue(_, pinfo) in props -> pinfo ] let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter, ad) g amap m origTy metadataTy = @@ -166,10 +170,10 @@ let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter, ad) g amap m origTy let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy GetImmediateIntrinsicPropInfosOfTypeAux (optFilter, ad) g amap m origTy betterMetadataTy else - match tryDestAppTy g metadataTy with + match tryTcrefOfAppTy g metadataTy with | ValueNone -> [] | ValueSome tcref -> - let propCollector = new PropertyCollector(g, amap, m, origTy, optFilter, ad) + let propCollector = PropertyCollector(g, amap, m, origTy, optFilter, ad) SelectImmediateMemberVals g None (fun membInfo vref -> propCollector.Collect(membInfo, vref); None) tcref |> ignore propCollector.Close() @@ -185,13 +189,58 @@ let rec GetImmediateIntrinsicPropInfosOfType (optFilter, ad) g amap m ty = let IsIndexerType g amap ty = isArray1DTy g ty || isListTy g ty || - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref -> let _, entityTy = generalizeTyconRef tcref let props = GetImmediateIntrinsicPropInfosOfType (None, AccessibleFromSomeFSharpCode) g amap range0 entityTy props |> List.exists (fun x -> x.PropertyName = "Item") | ValueNone -> false +/// Get the items that are considered the most specific in the hierarchy out of the given items by type. +/// REVIEW: Note complexity O(N^2) +let GetMostSpecificItemsByType g amap f xs = + [ for x in xs do + match f x with + | None -> () + | Some (xTy, m) -> + let isEqual = + xs + |> List.forall (fun y -> + match f y with + | None -> true + | Some (yTy, _) -> + if typeEquiv g xTy yTy then true + else not (TypeFeasiblySubsumesType 0 g amap m xTy CanCoerce yTy)) + if isEqual then + yield x ] + +/// Finds the most specific methods from a method collection by a given method's signature. +let GetMostSpecificMethodInfosByMethInfoSig g amap m (ty, minfo) minfos = + minfos + |> GetMostSpecificItemsByType g amap (fun (ty2, minfo2) -> + let isEqual = + typeEquiv g ty ty2 && + MethInfosEquivByPartialSig EraseNone true g amap m minfo minfo2 + if isEqual then + Some(minfo2.ApparentEnclosingType, m) + else + None) + +/// From the given method sets, filter each set down to the most specific ones. +let FilterMostSpecificMethInfoSets g amap m (minfoSets: NameMultiMap<_>) : NameMultiMap<_> = + minfoSets + |> Map.map (fun _ minfos -> + ([], minfos) + ||> List.fold (fun minfoSpecifics (ty, minfo) -> + let alreadySeen = + minfoSpecifics + |> List.exists (fun (tySpecific, minfoSpecific) -> + typeEquiv g ty tySpecific && + MethInfosEquivByPartialSig EraseNone true g amap m minfo minfoSpecific) + if alreadySeen then + minfoSpecifics + else + GetMostSpecificMethodInfosByMethInfoSig g amap m (ty, minfo) minfos @ minfoSpecifics)) /// Sets of methods up the hierarchy, ignoring duplicates by name and sig. /// Used to collect sets of virtual methods, protected methods, protected @@ -203,9 +252,47 @@ type HierarchyItem = | EventItem of EventInfo list | ILFieldItem of ILFieldInfo list +//------------------------------------------------------------------------- +// Collecting methods and properties taking into account hiding rules in the hierarchy + + +/// Indicates if we prefer overrides or abstract slots. +type FindMemberFlag = + /// Prefer items toward the top of the hierarchy, which we do if the items are virtual + /// but not when resolving base calls. + | IgnoreOverrides + /// Get overrides instead of abstract slots when measuring whether a class/interface implements all its required slots. + | PreferOverrides + +/// The input list is sorted from most-derived to least-derived type, so any System.Object methods +/// are at the end of the list. Return a filtered list where prior/subsequent members matching by name and +/// that are in the same equivalence class have been removed. We keep a name-indexed table to +/// be more efficient when we check to see if we've already seen a particular named method. +type private IndexedList<'T>(itemLists: 'T list list, itemsByName: NameMultiMap<'T>) = + + /// Get the item sets + member _.Items = itemLists + + /// Get the items with a particular name + member _.ItemsWithName(nm) = NameMultiMap.find nm itemsByName + + /// Add new items, extracting the names using the given function. + member _.AddItems(items, nmf) = IndexedList<'T>(items :: itemLists, List.foldBack (fun x acc -> NameMultiMap.add (nmf x) x acc) items itemsByName ) + + /// Get an empty set of items + static member Empty = IndexedList<'T>([], NameMultiMap.empty) + + /// Filter a set of new items to add according to the content of the list. Only keep an item + /// if it passes 'keepTest' for all matching items already in the list. + member x.FilterNewItems keepTest nmf itemsToAdd = + // Have we already seen an item with the same name and that is in the same equivalence class? + // If so, ignore this one. Note we can check against the original incoming 'ilist' because we are assuming that + // none the elements of 'itemsToAdd' are equivalent. + itemsToAdd |> List.filter (fun item -> List.forall (keepTest item) (x.ItemsWithName(nmf item))) + /// An InfoReader is an object to help us read and cache infos. /// We create one of these for each file we typecheck. -type InfoReader(g: TcGlobals, amap: Import.ImportMap) = +type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this = /// Get the declared IL fields of a type, not including inherited fields let GetImmediateIntrinsicILFieldsOfType (optFilter, ad) m ty = @@ -265,7 +352,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = /// Get the F#-declared record fields or class 'val' fields of a type let GetImmediateIntrinsicRecdOrClassFieldsOfType (optFilter, _ad) _m ty = - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueNone -> [] | ValueSome tcref -> // Note;secret fields are not allowed in lookups here, as we're only looking @@ -316,7 +403,7 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = let rfinfos = GetImmediateIntrinsicRecdOrClassFieldsOfType (optFilter, ad) m ty match acc with | Some(MethodItem(inheritedMethSets)) when not (isNil minfos) -> Some(MethodItem (minfos :: inheritedMethSets)) - | _ when not (isNil minfos) -> Some(MethodItem ([minfos])) + | _ when not (isNil minfos) -> Some(MethodItem [minfos]) | Some(PropertyItem(inheritedPropSets)) when not (isNil pinfos) -> Some(PropertyItem(pinfos :: inheritedPropSets)) | _ when not (isNil pinfos) -> Some(PropertyItem([pinfos])) | _ when not (isNil finfos) -> Some(ILFieldItem(finfos)) @@ -331,51 +418,257 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = ty None + let GetImmediateIntrinsicOverrideMethodSetsOfType optFilter m (interfaceTys: TType list) ty acc = + match tryAppTy g ty with + | ValueSome (tcref, _) when tcref.IsILTycon && tcref.ILTyconRawMetadata.IsInterface -> + let mimpls = tcref.ILTyconRawMetadata.MethodImpls.AsList + let mdefs = tcref.ILTyconRawMetadata.Methods + + // MethodImpls contains a list of methods that override. + // OverrideBy is the method that does the overriding. + // Overrides is the method being overriden. + (acc, mimpls) + ||> List.fold (fun acc ilMethImpl -> + let overridesName = ilMethImpl.Overrides.MethodRef.Name + let overrideBy = ilMethImpl.OverrideBy + let canAccumulate = + match optFilter with + | None -> true + | Some name when name = overridesName -> true + | _ -> false + if canAccumulate then + match mdefs.TryFindInstanceByNameAndCallingSignature (overrideBy.Name, overrideBy.MethodRef.CallingSignature) with + | Some mdef -> + let overridesILTy = ilMethImpl.Overrides.DeclaringType + let overridesTyFullName = overridesILTy.TypeRef.FullName + let overridesTyOpt = + interfaceTys + |> List.tryPick (fun ty -> + match tryTcrefOfAppTy g ty with + | ValueSome tcref when tcref.IsILTycon && tcref.ILTyconRawMetadata.Name = overridesTyFullName -> + generalizedTyconRef tcref + |> Some + | _ -> + None) + match overridesTyOpt with + | Some overridesTy -> + NameMultiMap.add overridesName (overridesTy, MethInfo.CreateILMeth(amap, m, ty, mdef)) acc + | _ -> + acc + | _ -> + acc + else + acc) + | _ -> acc + + /// Visiting each type in the hierarchy and accumulate most specific methods that are the OverrideBy target from types. + let GetIntrinsicMostSpecificOverrideMethodSetsUncached ((optFilter, _ad, allowMultiIntfInst), m, ty) : NameMultiMap<_> = + let interfaceTys = + FoldPrimaryHierarchyOfType (fun ty acc -> + if isInterfaceTy g ty then ty :: acc + else acc) g amap m allowMultiIntfInst ty [] + + (NameMultiMap.Empty, interfaceTys) + ||> List.fold (fun acc ty -> GetImmediateIntrinsicOverrideMethodSetsOfType optFilter m interfaceTys ty acc) + |> FilterMostSpecificMethInfoSets g amap m + + /// Add all the items to the IndexedList, preferring the ones in the super-types. This is used to hide methods + /// in super classes and/or hide overrides of methods in subclasses. + /// + /// Assume no items in 'items' are equivalent according to 'equivTest'. This is valid because each step in a + /// .NET class hierarchy introduces a consistent set of methods, none of which hide each other within the + /// given set. This is an important optimization because it means we don't have filter for equivalence between the + /// large overload sets introduced by methods like System.WriteLine. + /// + /// Assume items can be given names by 'nmf', where two items with different names are + /// not equivalent. + + static let FilterItemsInSubTypesBasedOnItemsInSuperTypes nmf keepTest itemLists = + let rec loop itemLists = + match itemLists with + | [] -> IndexedList.Empty + | items :: itemsInSuperTypes -> + let ilist = loop itemsInSuperTypes + let itemsToAdd = ilist.FilterNewItems keepTest nmf items + ilist.AddItems(itemsToAdd, nmf) + (loop itemLists).Items + + /// Add all the items to the IndexedList, preferring the ones in the sub-types. + static let FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf keepTest itemLists = + let rec loop itemLists (indexedItemsInSubTypes: IndexedList<_>) = + match itemLists with + | [] -> List.rev indexedItemsInSubTypes.Items + | items :: itemsInSuperTypes -> + let itemsToAdd = items |> List.filter (fun item -> keepTest item (indexedItemsInSubTypes.ItemsWithName(nmf item))) + let ilist = indexedItemsInSubTypes.AddItems(itemsToAdd, nmf) + loop itemsInSuperTypes ilist + + loop itemLists IndexedList.Empty + + static let ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes nmf equivTest itemLists = + FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf (fun item1 items -> not (items |> List.exists (fun item2 -> equivTest item1 item2))) itemLists + + /// Filter the overrides of methods or properties, either keeping the overrides or keeping the dispatch slots. + static let FilterOverrides findFlag (isVirt:'a->bool, isNewSlot, isDefiniteOverride, isFinal, equivSigs, nmf:'a->string) items = + let equivVirts x y = isVirt x && isVirt y && equivSigs x y + + match findFlag with + | PreferOverrides -> + items + // For each F#-declared override, get rid of any equivalent abstract member in the same type + // This is because F# abstract members with default overrides give rise to two members with the + // same logical signature in the same type, e.g. + // type ClassType1() = + // abstract VirtualMethod1: string -> int + // default x.VirtualMethod1(s) = 3 + + |> List.map (fun items -> + let definiteOverrides = items |> List.filter isDefiniteOverride + items |> List.filter (fun item -> (isDefiniteOverride item || not (List.exists (equivVirts item) definiteOverrides)))) + + // only keep virtuals that are not signature-equivalent to virtuals in subtypes + |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes nmf equivVirts + | IgnoreOverrides -> + let equivNewSlots x y = isNewSlot x && isNewSlot y && equivSigs x y + items + // Remove any F#-declared overrides. These may occur in the same type as the abstract member (unlike with .NET metadata) + // Include any 'newslot' declared methods. + |> List.map (List.filter (fun x -> not (isDefiniteOverride x))) + + // Remove any virtuals that are signature-equivalent to virtuals in subtypes, except for newslots + // That is, keep if it's + /// (a) not virtual + // (b) is a new slot or + // (c) not equivalent + // We keep virtual finals around for error detection later on + |> FilterItemsInSubTypesBasedOnItemsInSuperTypes nmf (fun newItem priorItem -> + (isVirt newItem && isFinal newItem) || not (isVirt newItem) || isNewSlot newItem || not (equivVirts newItem priorItem) ) + + // Remove any abstract slots in supertypes that are (a) hidden by another newslot and (b) implemented + // We leave unimplemented ones around to give errors, e.g. for + // [] + // type PA() = + // abstract M : int -> unit + // + // [] + // type PB<'a>() = + // inherit PA() + // abstract M : 'a -> unit + // + // [] + // type PC() = + // inherit PB() + // // Here, PA.M and PB.M have the same signature, so PA.M is unimplementable. + // // REVIEW: in future we may give a friendly error at this point + // + // type PD() = + // inherit PC() + // override this.M(x: int) = () + + |> FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf (fun item1 superTypeItems -> + not (isNewSlot item1 && + superTypeItems |> List.exists (equivNewSlots item1) && + superTypeItems |> List.exists (fun item2 -> isDefiniteOverride item1 && equivVirts item1 item2))) + + + /// Filter the overrides of methods, either keeping the overrides or keeping the dispatch slots. + static let FilterOverridesOfMethInfos findFlag g amap m minfos = + minfos + |> FilterOverrides findFlag + ((fun (minfo: MethInfo) -> minfo.IsVirtual), + (fun minfo -> minfo.IsNewSlot), + (fun minfo -> minfo.IsDefiniteFSharpOverride), + (fun minfo -> minfo.IsFinal), + MethInfosEquivByNameAndSig EraseNone true g amap m, + (fun minfo -> minfo.LogicalName)) + + /// Filter the overrides of properties, either keeping the overrides or keeping the dispatch slots. + static let FilterOverridesOfPropInfos findFlag g amap m props = + props + |> FilterOverrides findFlag + ((fun (pinfo: PropInfo) -> pinfo.IsVirtualProperty), + (fun pinfo -> pinfo.IsNewSlot), + (fun pinfo -> pinfo.IsDefiniteFSharpOverride), + (fun _ -> false), + PropInfosEquivByNameAndSig EraseNone g amap m, + (fun pinfo -> pinfo.PropertyName)) + + /// Exclude methods from super types which have the same signature as a method in a more specific type. + static let ExcludeHiddenOfMethInfosImpl g amap m (minfos: MethInfo list list) = + minfos + |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes + (fun minfo -> minfo.LogicalName) + (fun m1 m2 -> + // only hide those truly from super classes + not (tyconRefEq g m1.DeclaringTyconRef m2.DeclaringTyconRef) && + MethInfosEquivByNameAndPartialSig EraseNone true g amap m m1 m2) + + |> List.concat + + /// Exclude properties from super types which have the same name as a property in a more specific type. + static let ExcludeHiddenOfPropInfosImpl g amap m pinfos = + pinfos + |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes (fun (pinfo: PropInfo) -> pinfo.PropertyName) (PropInfosEquivByNameAndPartialSig EraseNone g amap m) + |> List.concat + /// Make a cache for function 'f' keyed by type (plus some additional 'flags') that only /// caches computations for monomorphic types. let MakeInfoCache f (flagsEq : System.Collections.Generic.IEqualityComparer<_>) = - new MemoizationTable<_, _> + MemoizationTable<_, _> (compute=f, // Only cache closed, monomorphic types (closed = all members for the type // have been processed). Generic type instantiations could be processed if we had // a decent hash function for these. - canMemoize=(fun (_flags, (_: range), ty) -> + canMemoize=(fun (_flags, _: range, ty) -> match stripTyEqns g ty with | TType_app(tcref, []) -> tcref.TypeContents.tcaug_closed | _ -> false), keyComparer= { new System.Collections.Generic.IEqualityComparer<_> with - member x.Equals((flags1, _, typ1), (flags2, _, typ2)) = + member _.Equals((flags1, _, typ1), (flags2, _, typ2)) = // Ignoring the ranges - that's OK. flagsEq.Equals(flags1, flags2) && match stripTyEqns g typ1, stripTyEqns g typ2 with | TType_app(tcref1, []), TType_app(tcref2, []) -> tyconRefEq g tcref1 tcref2 | _ -> false - member x.GetHashCode((flags, _, ty)) = + member _.GetHashCode((flags, _, ty)) = // Ignoring the ranges - that's OK. flagsEq.GetHashCode flags + (match stripTyEqns g ty with | TType_app(tcref, []) -> hash tcref.LogicalName | _ -> 0) }) - + let FindImplicitConversionsUncached (ad, m, ty) = + if isTyparTy g ty then + [] + // F# ignores the op_Implicit conversions defined on the 'Option' and 'ValueOption' types + elif isOptionTy g ty || isValueOptionTy g ty then + [] + else + this.TryFindIntrinsicMethInfo m ad "op_Implicit" ty + let hashFlags0 = - { new System.Collections.Generic.IEqualityComparer<_> with - member x.GetHashCode((filter: string option, ad: AccessorDomain, _allowMultiIntfInst1)) = hash filter + AccessorDomain.CustomGetHashCode ad - member x.Equals((filter1, ad1, allowMultiIntfInst1), (filter2, ad2, allowMultiIntfInst2)) = + { new System.Collections.Generic.IEqualityComparer with + member _.GetHashCode((filter: string option, ad: AccessorDomain, _allowMultiIntfInst1)) = hash filter + AccessorDomain.CustomGetHashCode ad + member _.Equals((filter1, ad1, allowMultiIntfInst1), (filter2, ad2, allowMultiIntfInst2)) = (filter1 = filter2) && AccessorDomain.CustomEquals(g, ad1, ad2) && allowMultiIntfInst1 = allowMultiIntfInst2 } let hashFlags1 = - { new System.Collections.Generic.IEqualityComparer<_> with - member x.GetHashCode((filter: string option, ad: AccessorDomain)) = hash filter + AccessorDomain.CustomGetHashCode ad - member x.Equals((filter1, ad1), (filter2, ad2)) = (filter1 = filter2) && AccessorDomain.CustomEquals(g, ad1, ad2) } + { new System.Collections.Generic.IEqualityComparer with + member _.GetHashCode((filter: string option, ad: AccessorDomain)) = hash filter + AccessorDomain.CustomGetHashCode ad + member _.Equals((filter1, ad1), (filter2, ad2)) = (filter1 = filter2) && AccessorDomain.CustomEquals(g, ad1, ad2) } let hashFlags2 = - { new System.Collections.Generic.IEqualityComparer<_> with - member x.GetHashCode((nm: string, ad: AccessorDomain)) = hash nm + AccessorDomain.CustomGetHashCode ad - member x.Equals((nm1, ad1), (nm2, ad2)) = (nm1 = nm2) && AccessorDomain.CustomEquals(g, ad1, ad2) } + { new System.Collections.Generic.IEqualityComparer with + member _.GetHashCode((nm: string, ad: AccessorDomain)) = hash nm + AccessorDomain.CustomGetHashCode ad + member _.Equals((nm1, ad1), (nm2, ad2)) = (nm1 = nm2) && AccessorDomain.CustomEquals(g, ad1, ad2) } + + let hashFlags3 = + { new System.Collections.Generic.IEqualityComparer with + member _.GetHashCode((ad: AccessorDomain)) = AccessorDomain.CustomGetHashCode ad + member _.Equals((ad1), (ad2)) = AccessorDomain.CustomEquals(g, ad1, ad2) } let methodInfoCache = MakeInfoCache GetIntrinsicMethodSetsUncached hashFlags0 let propertyInfoCache = MakeInfoCache GetIntrinsicPropertySetsUncached hashFlags0 @@ -383,44 +676,60 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = let ilFieldInfoCache = MakeInfoCache GetIntrinsicILFieldInfosUncached hashFlags1 let eventInfoCache = MakeInfoCache GetIntrinsicEventInfosUncached hashFlags1 let namedItemsCache = MakeInfoCache GetIntrinsicNamedItemsUncached hashFlags2 + let mostSpecificOverrideMethodInfoCache = MakeInfoCache GetIntrinsicMostSpecificOverrideMethodSetsUncached hashFlags0 let entireTypeHierarchyCache = MakeInfoCache GetEntireTypeHierarchyUncached HashIdentity.Structural let primaryTypeHierarchyCache = MakeInfoCache GetPrimaryTypeHierarchyUncached HashIdentity.Structural + let implicitConversionCache = MakeInfoCache FindImplicitConversionsUncached hashFlags3 + + // Runtime feature support + + let isRuntimeFeatureSupported (infoReader: InfoReader) runtimeFeature = + match g.System_Runtime_CompilerServices_RuntimeFeature_ty with + | Some runtimeFeatureTy -> + infoReader.GetILFieldInfosOfType (None, AccessorDomain.AccessibleFromEverywhere, range0, runtimeFeatureTy) + |> List.exists (fun (ilFieldInfo: ILFieldInfo) -> ilFieldInfo.FieldName = runtimeFeature) + | _ -> + false + + let isRuntimeFeatureDefaultImplementationsOfInterfacesSupported = + lazy isRuntimeFeatureSupported this "DefaultImplementationsOfInterfaces" - member x.g = g - member x.amap = amap + member _.g = g + member _.amap = amap /// Read the raw method sets of a type, including inherited ones. Cache the result for monomorphic types - member x.GetRawIntrinsicMethodSetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) = + member _.GetRawIntrinsicMethodSetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) = methodInfoCache.Apply(((optFilter, ad, allowMultiIntfInst), m, ty)) /// Read the raw property sets of a type, including inherited ones. Cache the result for monomorphic types - member x.GetRawIntrinsicPropertySetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) = + member _.GetRawIntrinsicPropertySetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) = propertyInfoCache.Apply(((optFilter, ad, allowMultiIntfInst), m, ty)) /// Read the record or class fields of a type, including inherited ones. Cache the result for monomorphic types. - member x.GetRecordOrClassFieldsOfType (optFilter, ad, m, ty) = + member _.GetRecordOrClassFieldsOfType (optFilter, ad, m, ty) = recdOrClassFieldInfoCache.Apply(((optFilter, ad), m, ty)) /// Read the IL fields of a type, including inherited ones. Cache the result for monomorphic types. - member x.GetILFieldInfosOfType (optFilter, ad, m, ty) = + member _.GetILFieldInfosOfType (optFilter, ad, m, ty) = ilFieldInfoCache.Apply(((optFilter, ad), m, ty)) - member x.GetImmediateIntrinsicEventsOfType (optFilter, ad, m, ty) = ComputeImmediateIntrinsicEventsOfType (optFilter, ad) m ty + member _.GetImmediateIntrinsicEventsOfType (optFilter, ad, m, ty) = + ComputeImmediateIntrinsicEventsOfType (optFilter, ad) m ty /// Read the events of a type, including inherited ones. Cache the result for monomorphic types. - member x.GetEventInfosOfType (optFilter, ad, m, ty) = + member _.GetEventInfosOfType (optFilter, ad, m, ty) = eventInfoCache.Apply(((optFilter, ad), m, ty)) /// Try and find a record or class field for a type. - member x.TryFindRecdOrClassFieldInfoOfType (nm, m, ty) = + member _.TryFindRecdOrClassFieldInfoOfType (nm, m, ty) = match recdOrClassFieldInfoCache.Apply((Some nm, AccessibleFromSomewhere), m, ty) with | [] -> ValueNone | [single] -> ValueSome single | flds -> // multiple fields with the same name can come from different classes, // so filter them by the given type name - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueNone -> ValueNone | ValueSome tcref -> match flds |> List.filter (fun rfinfo -> tyconRefEq g tcref rfinfo.TyconRef) with @@ -429,277 +738,160 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = | _ -> failwith "unexpected multiple fields with same name" // Because it should have been already reported as duplicate fields /// Try and find an item with the given name in a type. - member x.TryFindNamedItemOfType (nm, ad, m, ty) = + member _.TryFindNamedItemOfType (nm, ad, m, ty) = namedItemsCache.Apply(((nm, ad), m, ty)) + /// Read the raw method sets of a type that are the most specific overrides. Cache the result for monomorphic types + member _.GetIntrinsicMostSpecificOverrideMethodSetsOfType (optFilter, ad, allowMultiIntfInst, m, ty) = + mostSpecificOverrideMethodInfoCache.Apply(((optFilter, ad, allowMultiIntfInst), m, ty)) + /// Get the super-types of a type, including interface types. - member x.GetEntireTypeHierarchy (allowMultiIntfInst, m, ty) = + member _.GetEntireTypeHierarchy (allowMultiIntfInst, m, ty) = entireTypeHierarchyCache.Apply((allowMultiIntfInst, m, ty)) /// Get the super-types of a type, excluding interface types. - member x.GetPrimaryTypeHierarchy (allowMultiIntfInst, m, ty) = + member _.GetPrimaryTypeHierarchy (allowMultiIntfInst, m, ty) = primaryTypeHierarchyCache.Apply((allowMultiIntfInst, m, ty)) + /// Check if the given language feature is supported by the runtime. + member _.IsLanguageFeatureRuntimeSupported langFeature = + match langFeature with + // Both default and static interface method consumption features are tied to the runtime support of DIMs. + | LanguageFeature.DefaultInterfaceMemberConsumption -> isRuntimeFeatureDefaultImplementationsOfInterfacesSupported.Value + | _ -> true + + /// Get the declared constructors of any F# type + member infoReader.GetIntrinsicConstructorInfosOfTypeAux m origTy metadataTy = + protectAssemblyExploration [] (fun () -> + let g = infoReader.g + let amap = infoReader.amap + match metadataOfTy g metadataTy with + #if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> + let st = info.ProvidedType + [ for ci in st.PApplyArray((fun st -> st.GetConstructors()), "GetConstructors", m) do + yield ProvidedMeth(amap, ci.Coerce(m), None, m) ] + #endif + | ILTypeMetadata _ -> + let tinfo = ILTypeInfo.FromType g origTy + tinfo.RawMetadata.Methods.FindByName ".ctor" + |> List.filter (fun md -> md.IsConstructor) + |> List.map (fun mdef -> MethInfo.CreateILMeth (amap, m, origTy, mdef)) -/// Get the declared constructors of any F# type -let rec GetIntrinsicConstructorInfosOfTypeAux (infoReader: InfoReader) m origTy metadataTy = - protectAssemblyExploration [] (fun () -> - let g = infoReader.g - let amap = infoReader.amap - match metadataOfTy g metadataTy with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> - let st = info.ProvidedType - [ for ci in st.PApplyArray((fun st -> st.GetConstructors()), "GetConstructors", m) do - yield ProvidedMeth(amap, ci.Coerce(m), None, m) ] -#endif - | ILTypeMetadata _ -> - let tinfo = ILTypeInfo.FromType g origTy - tinfo.RawMetadata.Methods.FindByName ".ctor" - |> List.filter (fun md -> md.IsConstructor) - |> List.map (fun mdef -> MethInfo.CreateILMeth (amap, m, origTy, mdef)) - - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - // Tuple types also support constructors. In this case convert to the .NET Tuple type that carries metadata and try again - // Function types also support constructors. In this case convert to the FSharpFunc type that carries metadata and try again - if isAnyTupleTy g metadataTy || isFunTy g metadataTy then - let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy - GetIntrinsicConstructorInfosOfTypeAux infoReader m origTy betterMetadataTy - else - match tryDestAppTy g metadataTy with - | ValueNone -> [] - | ValueSome tcref -> - tcref.MembersOfFSharpTyconByName - |> NameMultiMap.find ".ctor" - |> List.choose(fun vref -> - match vref.MemberInfo with - | Some membInfo when (membInfo.MemberFlags.MemberKind = MemberKind.Constructor) -> Some vref - | _ -> None) - |> List.map (fun x -> FSMeth(g, origTy, x, None)) - ) - -let GetIntrinsicConstructorInfosOfType infoReader m ty = - GetIntrinsicConstructorInfosOfTypeAux infoReader m ty ty - - - -//------------------------------------------------------------------------- -// Collecting methods and properties taking into account hiding rules in the hierarchy - + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + // Tuple types also support constructors. In this case convert to the .NET Tuple type that carries metadata and try again + // Function types also support constructors. In this case convert to the FSharpFunc type that carries metadata and try again + if isAnyTupleTy g metadataTy || isFunTy g metadataTy then + let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy + infoReader.GetIntrinsicConstructorInfosOfTypeAux m origTy betterMetadataTy + else + match tryTcrefOfAppTy g metadataTy with + | ValueNone -> [] + | ValueSome tcref -> + tcref.MembersOfFSharpTyconByName + |> NameMultiMap.find ".ctor" + |> List.choose(fun vref -> + match vref.MemberInfo with + | Some membInfo when (membInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) -> Some vref + | _ -> None) + |> List.map (fun x -> FSMeth(g, origTy, x, None)) + ) + + static member ExcludeHiddenOfMethInfos g amap m minfos = + ExcludeHiddenOfMethInfosImpl g amap m minfos + + static member ExcludeHiddenOfPropInfos g amap m pinfos = + ExcludeHiddenOfPropInfosImpl g amap m pinfos + + /// Get the sets of intrinsic methods in the hierarchy (not including extension methods) + member infoReader.GetIntrinsicMethInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetRawIntrinsicMethodSetsOfType(optFilter, ad, allowMultiIntfInst, m, ty) + |> FilterOverridesOfMethInfos findFlag infoReader.g infoReader.amap m -/// Indicates if we prefer overrides or abstract slots. -type FindMemberFlag = - /// Prefer items toward the top of the hierarchy, which we do if the items are virtual - /// but not when resolving base calls. - | IgnoreOverrides - /// Get overrides instead of abstract slots when measuring whether a class/interface implements all its required slots. - | PreferOverrides - -/// The input list is sorted from most-derived to least-derived type, so any System.Object methods -/// are at the end of the list. Return a filtered list where prior/subsequent members matching by name and -/// that are in the same equivalence class have been removed. We keep a name-indexed table to -/// be more efficient when we check to see if we've already seen a particular named method. -type private IndexedList<'T>(itemLists: 'T list list, itemsByName: NameMultiMap<'T>) = - - /// Get the item sets - member x.Items = itemLists - - /// Get the items with a particular name - member x.ItemsWithName(nm) = NameMultiMap.find nm itemsByName - - /// Add new items, extracting the names using the given function. - member x.AddItems(items, nmf) = IndexedList<'T>(items :: itemLists, List.foldBack (fun x acc -> NameMultiMap.add (nmf x) x acc) items itemsByName ) - - /// Get an empty set of items - static member Empty = IndexedList<'T>([], NameMultiMap.empty) - - /// Filter a set of new items to add according to the content of the list. Only keep an item - /// if it passes 'keepTest' for all matching items already in the list. - member x.FilterNewItems keepTest nmf itemsToAdd = - // Have we already seen an item with the same name and that is in the same equivalence class? - // If so, ignore this one. Note we can check against the original incoming 'ilist' because we are assuming that - // none the elements of 'itemsToAdd' are equivalent. - itemsToAdd |> List.filter (fun item -> List.forall (keepTest item) (x.ItemsWithName(nmf item))) - -/// Add all the items to the IndexedList, preferring the ones in the super-types. This is used to hide methods -/// in super classes and/or hide overrides of methods in subclasses. -/// -/// Assume no items in 'items' are equivalent according to 'equivTest'. This is valid because each step in a -/// .NET class hierarchy introduces a consistent set of methods, none of which hide each other within the -/// given set. This is an important optimization because it means we don't have filter for equivalence between the -/// large overload sets introduced by methods like System.WriteLine. -/// -/// Assume items can be given names by 'nmf', where two items with different names are -/// not equivalent. - -let private FilterItemsInSubTypesBasedOnItemsInSuperTypes nmf keepTest itemLists = - let rec loop itemLists = - match itemLists with - | [] -> IndexedList.Empty - | items :: itemsInSuperTypes -> - let ilist = loop itemsInSuperTypes - let itemsToAdd = ilist.FilterNewItems keepTest nmf items - ilist.AddItems(itemsToAdd, nmf) - (loop itemLists).Items - -/// Add all the items to the IndexedList, preferring the ones in the sub-types. -let private FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf keepTest itemLists = - let rec loop itemLists (indexedItemsInSubTypes: IndexedList<_>) = - match itemLists with - | [] -> List.rev indexedItemsInSubTypes.Items - | items :: itemsInSuperTypes -> - let itemsToAdd = items |> List.filter (fun item -> keepTest item (indexedItemsInSubTypes.ItemsWithName(nmf item))) - let ilist = indexedItemsInSubTypes.AddItems(itemsToAdd, nmf) - loop itemsInSuperTypes ilist - - loop itemLists IndexedList.Empty - -let private ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes nmf equivTest itemLists = - FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf (fun item1 items -> not (items |> List.exists (fun item2 -> equivTest item1 item2))) itemLists - -/// Filter the overrides of methods or properties, either keeping the overrides or keeping the dispatch slots. -let private FilterOverrides findFlag (isVirt:'a->bool, isNewSlot, isDefiniteOverride, isFinal, equivSigs, nmf:'a->string) items = - let equivVirts x y = isVirt x && isVirt y && equivSigs x y - - match findFlag with - | PreferOverrides -> - items - // For each F#-declared override, get rid of any equivalent abstract member in the same type - // This is because F# abstract members with default overrides give rise to two members with the - // same logical signature in the same type, e.g. - // type ClassType1() = - // abstract VirtualMethod1: string -> int - // default x.VirtualMethod1(s) = 3 - - |> List.map (fun items -> - let definiteOverrides = items |> List.filter isDefiniteOverride - items |> List.filter (fun item -> (isDefiniteOverride item || not (List.exists (equivVirts item) definiteOverrides)))) - - // only keep virtuals that are not signature-equivalent to virtuals in subtypes - |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes nmf equivVirts - | IgnoreOverrides -> - let equivNewSlots x y = isNewSlot x && isNewSlot y && equivSigs x y - items - // Remove any F#-declared overrides. These may occur in the same type as the abstract member (unlike with .NET metadata) - // Include any 'newslot' declared methods. - |> List.map (List.filter (fun x -> not (isDefiniteOverride x))) - - // Remove any virtuals that are signature-equivalent to virtuals in subtypes, except for newslots - // That is, keep if it's - /// (a) not virtual - // (b) is a new slot or - // (c) not equivalent - // We keep virtual finals around for error detection later on - |> FilterItemsInSubTypesBasedOnItemsInSuperTypes nmf (fun newItem priorItem -> - (isVirt newItem && isFinal newItem) || not (isVirt newItem) || isNewSlot newItem || not (equivVirts newItem priorItem) ) - - // Remove any abstract slots in supertypes that are (a) hidden by another newslot and (b) implemented - // We leave unimplemented ones around to give errors, e.g. for - // [] - // type PA() = - // abstract M : int -> unit - // - // [] - // type PB<'a>() = - // inherit PA() - // abstract M : 'a -> unit - // - // [] - // type PC() = - // inherit PB() - // // Here, PA.M and PB.M have the same signature, so PA.M is unimplementable. - // // REVIEW: in future we may give a friendly error at this point - // - // type PD() = - // inherit PC() - // override this.M(x: int) = () - - |> FilterItemsInSuperTypesBasedOnItemsInSubTypes nmf (fun item1 superTypeItems -> - not (isNewSlot item1 && - superTypeItems |> List.exists (equivNewSlots item1) && - superTypeItems |> List.exists (fun item2 -> isDefiniteOverride item1 && equivVirts item1 item2))) + /// Get the sets intrinsic properties in the hierarchy (not including extension properties) + member infoReader.GetIntrinsicPropInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetRawIntrinsicPropertySetsOfType(optFilter, ad, allowMultiIntfInst, m, ty) + |> FilterOverridesOfPropInfos findFlag infoReader.g infoReader.amap m + + /// Get the flattened list of intrinsic methods in the hierarchy + member infoReader.GetIntrinsicMethInfosOfType optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetIntrinsicMethInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty |> List.concat + + /// Get the flattened list of intrinsic properties in the hierarchy + member infoReader.GetIntrinsicPropInfosOfType optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetIntrinsicPropInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty |> List.concat + + member infoReader.TryFindIntrinsicNamedItemOfType (nm, ad) findFlag m ty = + match infoReader.TryFindNamedItemOfType(nm, ad, m, ty) with + | Some item -> + match item with + | PropertyItem psets -> Some(PropertyItem (psets |> FilterOverridesOfPropInfos findFlag infoReader.g infoReader.amap m)) + | MethodItem msets -> Some(MethodItem (msets |> FilterOverridesOfMethInfos findFlag infoReader.g infoReader.amap m)) + | _ -> Some(item) + | None -> None + + /// Try to detect the existence of a method on a type. + member infoReader.TryFindIntrinsicMethInfo m ad nm ty = + infoReader.GetIntrinsicMethInfosOfType (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m ty + + /// Try to find a particular named property on a type. Only used to ensure that local 'let' definitions and property names + /// are distinct, a somewhat adhoc check in tc.fs. + member infoReader.TryFindIntrinsicPropInfo m ad nm ty = + infoReader.GetIntrinsicPropInfosOfType (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m ty + + member _.FindImplicitConversions m ad ty = + implicitConversionCache.Apply((ad, m, ty)) + +let private tryLanguageFeatureRuntimeErrorAux (infoReader: InfoReader) langFeature m error = + if not (infoReader.IsLanguageFeatureRuntimeSupported langFeature) then + let featureStr = infoReader.g.langVersion.GetFeatureString langFeature + error (Error(FSComp.SR.chkFeatureNotRuntimeSupported featureStr, m)) + false + else + true + +let checkLanguageFeatureRuntimeError infoReader langFeature m = + tryLanguageFeatureRuntimeErrorAux infoReader langFeature m error |> ignore + +let checkLanguageFeatureRuntimeErrorRecover infoReader langFeature m = + tryLanguageFeatureRuntimeErrorAux infoReader langFeature m errorR |> ignore + +let tryLanguageFeatureRuntimeErrorRecover infoReader langFeature m = + tryLanguageFeatureRuntimeErrorAux infoReader langFeature m errorR + +let GetIntrinsicConstructorInfosOfType (infoReader: InfoReader) m ty = + infoReader.GetIntrinsicConstructorInfosOfTypeAux m ty ty - -/// Filter the overrides of methods, either keeping the overrides or keeping the dispatch slots. -let private FilterOverridesOfMethInfos findFlag g amap m minfos = - minfos - |> FilterOverrides findFlag - ((fun (minfo: MethInfo) -> minfo.IsVirtual), - (fun minfo -> minfo.IsNewSlot), - (fun minfo -> minfo.IsDefiniteFSharpOverride), - (fun minfo -> minfo.IsFinal), - MethInfosEquivByNameAndSig EraseNone true g amap m, - (fun minfo -> minfo.LogicalName)) - -/// Filter the overrides of properties, either keeping the overrides or keeping the dispatch slots. -let private FilterOverridesOfPropInfos findFlag g amap m props = - props - |> FilterOverrides findFlag - ((fun (pinfo: PropInfo) -> pinfo.IsVirtualProperty), - (fun pinfo -> pinfo.IsNewSlot), - (fun pinfo -> pinfo.IsDefiniteFSharpOverride), - (fun _ -> false), - PropInfosEquivByNameAndSig EraseNone g amap m, - (fun pinfo -> pinfo.PropertyName)) - -/// Exclude methods from super types which have the same signature as a method in a more specific type. let ExcludeHiddenOfMethInfos g amap m (minfos: MethInfo list list) = - minfos - |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes - (fun minfo -> minfo.LogicalName) - (fun m1 m2 -> - // only hide those truly from super classes - not (tyconRefEq g m1.DeclaringTyconRef m2.DeclaringTyconRef) && - MethInfosEquivByNameAndPartialSig EraseNone true g amap m m1 m2) - - |> List.concat + InfoReader.ExcludeHiddenOfMethInfos g amap m minfos -/// Exclude properties from super types which have the same name as a property in a more specific type. let ExcludeHiddenOfPropInfos g amap m pinfos = - pinfos - |> ExcludeItemsInSuperTypesBasedOnEquivTestWithItemsInSubTypes (fun (pinfo: PropInfo) -> pinfo.PropertyName) (PropInfosEquivByNameAndPartialSig EraseNone g amap m) - |> List.concat + InfoReader.ExcludeHiddenOfPropInfos g amap m pinfos -/// Get the sets of intrinsic methods in the hierarchy (not including extension methods) let GetIntrinsicMethInfoSetsOfType (infoReader:InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = - infoReader.GetRawIntrinsicMethodSetsOfType(optFilter, ad, allowMultiIntfInst, m, ty) - |> FilterOverridesOfMethInfos findFlag infoReader.g infoReader.amap m + infoReader.GetIntrinsicMethInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty -/// Get the sets intrinsic properties in the hierarchy (not including extension properties) let GetIntrinsicPropInfoSetsOfType (infoReader:InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = - infoReader.GetRawIntrinsicPropertySetsOfType(optFilter, ad, allowMultiIntfInst, m, ty) - |> FilterOverridesOfPropInfos findFlag infoReader.g infoReader.amap m + infoReader.GetIntrinsicPropInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty -/// Get the flattened list of intrinsic methods in the hierarchy -let GetIntrinsicMethInfosOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty = - GetIntrinsicMethInfoSetsOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty |> List.concat +let GetIntrinsicMethInfosOfType (infoReader: InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetIntrinsicMethInfosOfType optFilter ad allowMultiIntfInst findFlag m ty -/// Get the flattened list of intrinsic properties in the hierarchy -let GetIntrinsicPropInfosOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty = - GetIntrinsicPropInfoSetsOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty |> List.concat +let GetIntrinsicPropInfosOfType (infoReader: InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = + infoReader.GetIntrinsicPropInfosOfType optFilter ad allowMultiIntfInst findFlag m ty -/// Perform type-directed name resolution of a particular named member in an F# type let TryFindIntrinsicNamedItemOfType (infoReader: InfoReader) (nm, ad) findFlag m ty = - match infoReader.TryFindNamedItemOfType(nm, ad, m, ty) with - | Some item -> - match item with - | PropertyItem psets -> Some(PropertyItem (psets |> FilterOverridesOfPropInfos findFlag infoReader.g infoReader.amap m)) - | MethodItem msets -> Some(MethodItem (msets |> FilterOverridesOfMethInfos findFlag infoReader.g infoReader.amap m)) - | _ -> Some(item) - | None -> None - -/// Try to detect the existence of a method on a type. -/// Used for -/// -- getting the GetEnumerator, get_Current, MoveNext methods for enumerable types -/// -- getting the Dispose method when resolving the 'use' construct -/// -- getting the various methods used to desugar the computation expression syntax -let TryFindIntrinsicMethInfo infoReader m ad nm ty = - GetIntrinsicMethInfosOfType infoReader (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m ty - -/// Try to find a particular named property on a type. Only used to ensure that local 'let' definitions and property names -/// are distinct, a somewhat adhoc check in tc.fs. -let TryFindPropInfo infoReader m ad nm ty = - GetIntrinsicPropInfosOfType infoReader (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m ty + infoReader.TryFindIntrinsicNamedItemOfType (nm, ad) findFlag m ty + +let TryFindIntrinsicMethInfo (infoReader: InfoReader) m ad nm ty = + infoReader.TryFindIntrinsicMethInfo m ad nm ty + +let TryFindIntrinsicPropInfo (infoReader: InfoReader) m ad nm ty = + infoReader.TryFindIntrinsicPropInfo m ad nm ty + +/// Get a set of most specific override methods. +let GetIntrinisicMostSpecificOverrideMethInfoSetsOfType (infoReader: InfoReader) m ty = + infoReader.GetIntrinsicMostSpecificOverrideMethodSetsOfType (None, AccessibleFromSomewhere, AllowMultiIntfInstantiations.Yes, m, ty) //------------------------------------------------------------------------- // Helpers related to delegates and events - these use method searching hence are in this file @@ -782,4 +974,147 @@ let PropTypOfEventInfo (infoReader: InfoReader) m ad (einfo: EventInfo) = let argsTy = ArgsTypOfEventInfo infoReader m ad einfo mkIEventType g delTy argsTy +/// Try to find the name of the metadata file for this external definition +let TryFindMetadataInfoOfExternalEntityRef (infoReader: InfoReader) m eref = + let g = infoReader.g + match eref with + | ERefLocal _ -> None + | ERefNonLocal nlref -> + // Generalize to get a formal signature + let formalTypars = eref.Typars m + let formalTypeInst = generalizeTypars formalTypars + let ty = TType_app(eref, formalTypeInst) + if isILAppTy g ty then + let formalTypeInfo = ILTypeInfo.FromType g ty + Some(nlref.Ccu.FileName, formalTypars, formalTypeInfo) + else None + +/// Try to find the xml doc associated with the assembly name and xml doc signature +let TryFindXmlDocByAssemblyNameAndSig (infoReader: InfoReader) assemblyName xmlDocSig = + infoReader.amap.assemblyLoader.TryFindXmlDocumentationInfo(assemblyName) + |> Option.bind (fun xmlDocInfo -> + xmlDocInfo.TryGetXmlDocBySig(xmlDocSig) + ) + +let private libFileOfEntityRef x = + match x with + | ERefLocal _ -> None + | ERefNonLocal nlref -> nlref.Ccu.FileName + +let GetXmlDocSigOfEntityRef infoReader m (eref: EntityRef) = + if eref.IsILTycon then + match TryFindMetadataInfoOfExternalEntityRef infoReader m eref with + | None -> None + | Some (ccuFileName, _, formalTypeInfo) -> Some(ccuFileName, "T:"+formalTypeInfo.ILTypeRef.FullName) + else + let ccuFileName = libFileOfEntityRef eref + let m = eref.Deref + if m.XmlDocSig = "" then + m.XmlDocSig <- XmlDocSigOfEntity eref + Some (ccuFileName, m.XmlDocSig) + +let GetXmlDocSigOfScopedValRef g (tcref: TyconRef) (vref: ValRef) = + let ccuFileName = libFileOfEntityRef tcref + let v = vref.Deref + if v.XmlDocSig = "" && v.HasDeclaringEntity then + let ap = buildAccessPath vref.TopValDeclaringEntity.CompilationPathOpt + let path = + if vref.TopValDeclaringEntity.IsModule then + let sep = if ap.Length > 0 then "." else "" + ap + sep + vref.TopValDeclaringEntity.CompiledName + else + ap + v.XmlDocSig <- XmlDocSigOfVal g false path v + Some (ccuFileName, v.XmlDocSig) + +let GetXmlDocSigOfRecdFieldRef (rfref: RecdFieldRef) = + let tcref = rfref.TyconRef + let ccuFileName = libFileOfEntityRef tcref + if rfref.RecdField.XmlDocSig = "" then + rfref.RecdField.XmlDocSig <- XmlDocSigOfProperty [tcref.CompiledRepresentationForNamedType.FullName; rfref.RecdField.LogicalName] + Some (ccuFileName, rfref.RecdField.XmlDocSig) + +let GetXmlDocSigOfUnionCaseRef (ucref: UnionCaseRef) = + let tcref = ucref.TyconRef + let ccuFileName = libFileOfEntityRef tcref + if ucref.UnionCase.XmlDocSig = "" then + ucref.UnionCase.XmlDocSig <- XmlDocSigOfUnionCase [tcref.CompiledRepresentationForNamedType.FullName; ucref.CaseName] + Some (ccuFileName, ucref.UnionCase.XmlDocSig) + +let GetXmlDocSigOfMethInfo (infoReader: InfoReader) m (minfo: MethInfo) = + let amap = infoReader.amap + match minfo with + | FSMeth (g, _, vref, _) -> + GetXmlDocSigOfScopedValRef g minfo.DeclaringTyconRef vref + | ILMeth (g, ilminfo, _) -> + let actualTypeName = ilminfo.DeclaringTyconRef.CompiledRepresentationForNamedType.FullName + let fmtps = ilminfo.FormalMethodTypars + let genArity = if fmtps.Length=0 then "" else sprintf "``%d" fmtps.Length + + match TryFindMetadataInfoOfExternalEntityRef infoReader m ilminfo.DeclaringTyconRef with + | None -> None + | Some (ccuFileName, formalTypars, formalTypeInfo) -> + let filminfo = ILMethInfo(g, formalTypeInfo.ToType, None, ilminfo.RawMetadata, fmtps) + let args = + if ilminfo.IsILExtensionMethod then + filminfo.GetRawArgTypes(amap, m, minfo.FormalMethodInst) + else + filminfo.GetParamTypes(amap, m, minfo.FormalMethodInst) + + // http://msdn.microsoft.com/en-us/library/fsbx0t7x.aspx + // If the name of the item itself has periods, they are replaced by the hash-sign ('#'). + // It is assumed that no item has a hash-sign directly in its name. For example, the fully + // qualified name of the String constructor would be "System.String.#ctor". + let normalizedName = ilminfo.ILName.Replace(".", "#") + + Some (ccuFileName, "M:"+actualTypeName+"."+normalizedName+genArity+XmlDocArgsEnc g (formalTypars, fmtps) args) + | DefaultStructCtor _ -> None +#if !NO_EXTENSIONTYPING + | ProvidedMeth _ -> None +#endif + +let GetXmlDocSigOfValRef g (vref: ValRef) = + if not vref.IsLocalRef then + let ccuFileName = vref.nlr.Ccu.FileName + let v = vref.Deref + if v.XmlDocSig = "" && v.HasDeclaringEntity then + v.XmlDocSig <- XmlDocSigOfVal g false vref.TopValDeclaringEntity.CompiledRepresentationForNamedType.Name v + Some (ccuFileName, v.XmlDocSig) + else + match vref.ApparentEnclosingEntity with + | Parent tcref -> + GetXmlDocSigOfScopedValRef g tcref vref + | _ -> + None + +let GetXmlDocSigOfProp infoReader m (pinfo: PropInfo) = + let g = pinfo.TcGlobals + match pinfo with +#if !NO_EXTENSIONTYPING + | ProvidedProp _ -> None // No signature is possible. If an xml comment existed it would have been returned by PropInfo.XmlDoc in infos.fs +#endif + | FSProp _ as fspinfo -> + match fspinfo.ArbitraryValRef with + | None -> None + | Some vref -> GetXmlDocSigOfScopedValRef g pinfo.DeclaringTyconRef vref + | ILProp(ILPropInfo(_, pdef)) -> + match TryFindMetadataInfoOfExternalEntityRef infoReader m pinfo.DeclaringTyconRef with + | Some (ccuFileName, formalTypars, formalTypeInfo) -> + let filpinfo = ILPropInfo(formalTypeInfo, pdef) + Some (ccuFileName, "P:"+formalTypeInfo.ILTypeRef.FullName+"."+pdef.Name+XmlDocArgsEnc g (formalTypars, []) (filpinfo.GetParamTypes(infoReader.amap, m))) + | _ -> None + +let GetXmlDocSigOfEvent infoReader m (einfo: EventInfo) = + match einfo with + | ILEvent _ -> + match TryFindMetadataInfoOfExternalEntityRef infoReader m einfo.DeclaringTyconRef with + | Some (ccuFileName, _, formalTypeInfo) -> + Some(ccuFileName, "E:"+formalTypeInfo.ILTypeRef.FullName+"."+einfo.EventName) + | _ -> None + | _ -> None +let GetXmlDocSigOfILFieldInfo infoReader m (finfo: ILFieldInfo) = + match TryFindMetadataInfoOfExternalEntityRef infoReader m finfo.DeclaringTyconRef with + | Some (ccuFileName, _, formalTypeInfo) -> + Some(ccuFileName, "F:"+formalTypeInfo.ILTypeRef.FullName+"."+finfo.FieldName) + | _ -> None diff --git a/src/fsharp/InfoReader.fsi b/src/fsharp/InfoReader.fsi new file mode 100644 index 00000000000..3247ed7ac9e --- /dev/null +++ b/src/fsharp/InfoReader.fsi @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + + +/// Select members from a type by name, searching the type hierarchy if needed +module internal FSharp.Compiler.InfoReader + +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Import +open FSharp.Compiler.Infos +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree + +/// Try to select an F# value when querying members, and if so return a MethInfo that wraps the F# value. +val TrySelectMemberVal: g:TcGlobals -> optFilter:string option -> ty:TType -> pri:ExtensionMethodPriority option -> _membInfo:'a -> vref:ValRef -> MethInfo option + +/// Query the immediate methods of an F# type, not taking into account inherited methods. The optFilter +/// parameter is an optional name to restrict the set of properties returned. +val GetImmediateIntrinsicMethInfosOfType: optFilter:string option * ad:AccessorDomain -> g:TcGlobals -> amap:ImportMap -> m:range -> ty:TType -> MethInfo list + +/// A helper type to help collect properties. +/// +/// Join up getters and setters which are not associated in the F# data structure +type PropertyCollector = + new: g:TcGlobals * amap:ImportMap * m:range * ty:TType * optFilter:string option * ad:AccessorDomain -> PropertyCollector + member Close: unit -> PropInfo list + member Collect: membInfo:ValMemberInfo * vref:ValRef -> unit + +/// Query the immediate properties of an F# type, not taking into account inherited properties. The optFilter +/// parameter is an optional name to restrict the set of properties returned. +val GetImmediateIntrinsicPropInfosOfType: optFilter:string option * ad:AccessorDomain -> g:TcGlobals -> amap:ImportMap -> m:range -> ty:TType -> PropInfo list + +/// Checks whether the given type has an indexer property. +val IsIndexerType: g:TcGlobals -> amap:ImportMap -> ty:TType -> bool + +/// Get the items that are considered the most specific in the hierarchy out of the given items by type. +val GetMostSpecificItemsByType: g:TcGlobals -> amap:ImportMap -> f:('a -> (TType * range) option) -> xs:'a list -> 'a list + +/// From the given method sets, filter each set down to the most specific ones. +val FilterMostSpecificMethInfoSets: g:TcGlobals -> amap:ImportMap -> m:range -> minfoSets:NameMultiMap -> NameMultiMap + +/// Sets of methods up the hierarchy, ignoring duplicates by name and sig. +/// Used to collect sets of virtual methods, protected methods, protected +/// properties etc. +type HierarchyItem = + | MethodItem of MethInfo list list + | PropertyItem of PropInfo list list + | RecdFieldItem of RecdFieldInfo + | EventItem of EventInfo list + | ILFieldItem of ILFieldInfo list + +/// Indicates if we prefer overrides or abstract slots. +type FindMemberFlag = + /// Prefer items toward the top of the hierarchy, which we do if the items are virtual + /// but not when resolving base calls. + | IgnoreOverrides + + /// Get overrides instead of abstract slots when measuring whether a class/interface implements all its required slots. + | PreferOverrides + +/// An InfoReader is an object to help us read and cache infos. +/// We create one of these for each file we typecheck. +type InfoReader = + + /// Get the declared IL fields of a type, not including inherited fields + new: g:TcGlobals * amap:ImportMap -> InfoReader + + /// Get the super-types of a type, including interface types. + member GetEntireTypeHierarchy: allowMultiIntfInst:AllowMultiIntfInstantiations * m:range * ty:TType -> TType list + + /// Read the events of a type, including inherited ones. Cache the result for monomorphic types. + member GetEventInfosOfType: optFilter:string option * ad:AccessorDomain * m:range * ty:TType -> EventInfo list + + /// Read the IL fields of a type, including inherited ones. Cache the result for monomorphic types. + member GetILFieldInfosOfType: optFilter:string option * ad:AccessorDomain * m:range * ty:TType -> ILFieldInfo list + member GetImmediateIntrinsicEventsOfType: optFilter:string option * ad:AccessorDomain * m:range * ty:TType -> EventInfo list + + /// Get the super-types of a type, excluding interface types. + member GetPrimaryTypeHierarchy: allowMultiIntfInst:AllowMultiIntfInstantiations * m:range * ty:TType -> TType list + + /// Read the raw method sets of a type, including inherited ones. Cache the result for monomorphic types + member GetRawIntrinsicMethodSetsOfType: optFilter:string option * ad:AccessorDomain * allowMultiIntfInst:AllowMultiIntfInstantiations * m:range * ty:TType -> MethInfo list list + + /// Read the record or class fields of a type, including inherited ones. Cache the result for monomorphic types. + member GetRecordOrClassFieldsOfType: optFilter:string option * ad:AccessorDomain * m:range * ty:TType -> RecdFieldInfo list + + /// Check if the given language feature is supported by the runtime. + member IsLanguageFeatureRuntimeSupported: langFeature:Features.LanguageFeature -> bool + + /// Try and find a record or class field for a type. + member TryFindRecdOrClassFieldInfoOfType: nm:string * m:range * ty:TType -> RecdFieldInfo voption + member amap: ImportMap + member g: TcGlobals + + /// Exclude methods from super types which have the same signature as a method in a more specific type. + static member ExcludeHiddenOfMethInfos: g:TcGlobals -> amap:ImportMap -> m:range -> minfos:MethInfo list list -> MethInfo list + + /// Exclude properties from super types which have the same name as a property in a more specific type. + static member ExcludeHiddenOfPropInfos: g:TcGlobals -> amap:ImportMap -> m:range -> pinfos:PropInfo list list -> PropInfo list + + /// Get the sets of intrinsic methods in the hierarchy (not including extension methods) + member GetIntrinsicMethInfoSetsOfType: optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> MethInfo list list + + /// Get the sets intrinsic properties in the hierarchy (not including extension properties) + member GetIntrinsicPropInfoSetsOfType: optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> PropInfo list list + + /// Get the flattened list of intrinsic methods in the hierarchy + member GetIntrinsicMethInfosOfType: optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> MethInfo list + + /// Get the flattened list of intrinsic properties in the hierarchy + member GetIntrinsicPropInfosOfType: optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> PropInfo list + + /// Perform type-directed name resolution of a particular named member in an F# type + member TryFindIntrinsicNamedItemOfType: nm:string * ad:AccessorDomain -> findFlag:FindMemberFlag -> m:range -> ty:TType -> HierarchyItem option + + /// Find the op_Implicit for a type + member FindImplicitConversions: m: range -> ad: AccessorDomain -> ty: TType -> MethInfo list + +val checkLanguageFeatureRuntimeError: infoReader:InfoReader -> langFeature:Features.LanguageFeature -> m:range -> unit + +val checkLanguageFeatureRuntimeErrorRecover: infoReader:InfoReader -> langFeature:Features.LanguageFeature -> m:range -> unit + +val tryLanguageFeatureRuntimeErrorRecover: infoReader:InfoReader -> langFeature:Features.LanguageFeature -> m:range -> bool + +/// Get the declared constructors of any F# type +val GetIntrinsicConstructorInfosOfType: infoReader:InfoReader -> m:range -> ty:TType -> MethInfo list + +/// Exclude methods from super types which have the same signature as a method in a more specific type. +val ExcludeHiddenOfMethInfos: g:TcGlobals -> amap:ImportMap -> m:range -> minfos:MethInfo list list -> MethInfo list + +/// Exclude properties from super types which have the same name as a property in a more specific type. +val ExcludeHiddenOfPropInfos: g:TcGlobals -> amap:ImportMap -> m:range -> pinfos:PropInfo list list -> PropInfo list + +/// Get the sets of intrinsic methods in the hierarchy (not including extension methods) +val GetIntrinsicMethInfoSetsOfType: infoReader:InfoReader -> optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> MethInfo list list + +/// Get the sets intrinsic properties in the hierarchy (not including extension properties) +val GetIntrinsicPropInfoSetsOfType: infoReader:InfoReader -> optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> PropInfo list list + +/// Get the flattened list of intrinsic methods in the hierarchy +val GetIntrinsicMethInfosOfType: infoReader:InfoReader -> optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> MethInfo list + +/// Get the flattened list of intrinsic properties in the hierarchy +val GetIntrinsicPropInfosOfType: infoReader:InfoReader -> optFilter:string option -> ad:AccessorDomain -> allowMultiIntfInst:AllowMultiIntfInstantiations -> findFlag:FindMemberFlag -> m:range -> ty:TType -> PropInfo list + +/// Perform type-directed name resolution of a particular named member in an F# type +val TryFindIntrinsicNamedItemOfType: infoReader:InfoReader -> nm:string * ad:AccessorDomain -> findFlag:FindMemberFlag -> m:range -> ty:TType -> HierarchyItem option + +/// Try to detect the existence of a method on a type. +val TryFindIntrinsicMethInfo: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> nm:string -> ty:TType -> MethInfo list + +/// Try to find a particular named property on a type. Only used to ensure that local 'let' definitions and property names +/// are distinct, a somewhat adhoc check in tc.fs. +val TryFindIntrinsicPropInfo: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> nm:string -> ty:TType -> PropInfo list + +/// Get a set of most specific override methods. +val GetIntrinisicMostSpecificOverrideMethInfoSetsOfType: infoReader:InfoReader -> m:range -> ty:TType -> NameMultiMap + +/// The Invoke MethInfo, the function argument types, the function return type +/// and the overall F# function type for the function type associated with a .NET delegate type +[] +type SigOfFunctionForDelegate = | SigOfFunctionForDelegate of MethInfo * TType list * TType * TType + +/// Given a delegate type work out the minfo, argument types, return type +/// and F# function type by looking at the Invoke signature of the delegate. +val GetSigOfFunctionForDelegate: infoReader:InfoReader -> delty:TType -> m:range -> ad:AccessorDomain -> SigOfFunctionForDelegate + +/// Try and interpret a delegate type as a "standard" .NET delegate type associated with an event, with a "sender" parameter. +val TryDestStandardDelegateType: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> delTy:TType -> (TType * TType) option + +/// Indicates if an event info is associated with a delegate type that is a "standard" .NET delegate type +/// with a sender parameter. +val IsStandardEventInfo: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> einfo:EventInfo -> bool + +val ArgsTypOfEventInfo: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> einfo:EventInfo -> TType + +val PropTypOfEventInfo: infoReader:InfoReader -> m:range -> ad:AccessorDomain -> einfo:EventInfo -> TType + +/// Try to find the name of the metadata file for this external definition +val TryFindMetadataInfoOfExternalEntityRef: infoReader:InfoReader -> m:range -> eref:EntityRef -> (string option * Typars * ILTypeInfo) option + +/// Try to find the xml doc associated with the assembly name and metadata key +val TryFindXmlDocByAssemblyNameAndSig: infoReader:InfoReader -> assemblyName: string -> xmlDocSig: string -> XmlDoc option + +val GetXmlDocSigOfEntityRef: infoReader:InfoReader -> m:range -> eref:EntityRef -> (string option * string) option + +val GetXmlDocSigOfScopedValRef: TcGlobals -> tcref:TyconRef -> vref:ValRef -> (string option * string) option + +val GetXmlDocSigOfRecdFieldRef: rfref:RecdFieldRef -> (string option * string) option + +val GetXmlDocSigOfUnionCaseRef: ucref:UnionCaseRef -> (string option * string) option + +val GetXmlDocSigOfMethInfo: infoReader: InfoReader -> m:range -> minfo:MethInfo -> (string option * string) option + +val GetXmlDocSigOfValRef: TcGlobals -> vref: ValRef -> (string option * string) option + +val GetXmlDocSigOfProp: infoReader:InfoReader -> m:range -> pinfo:PropInfo -> (string option * string) option + +val GetXmlDocSigOfEvent: infoReader:InfoReader -> m:range -> einfo:EventInfo -> (string option * string) option + +val GetXmlDocSigOfILFieldInfo: infoReader:InfoReader -> m:range -> finfo:ILFieldInfo -> (string option * string) option \ No newline at end of file diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index 5ced353f396..209900ce333 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -2,19 +2,23 @@ module internal FSharp.Compiler.InnerLambdasToTopLevelFuncs -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Ast +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.Detuple.GlobalUsageAnalysis open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Layout -open FSharp.Compiler.Detuple.GlobalUsageAnalysis -open FSharp.Compiler.Lib let verboseTLR = false @@ -81,7 +85,7 @@ let isDelayedRepr (f: Val) e = // REVIEW: these should just be replaced by direct calls to mkLocal, mkCompGenLocal etc. // REVIEW: However these set an arity whereas the others don't let mkLocalNameTypeArity compgen m name ty topValInfo = - NewVal(name, m, None, ty, Immutable, compgen, topValInfo, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) + Construct.NewVal(name, m, None, ty, Immutable, compgen, topValInfo, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) //------------------------------------------------------------------------- // definitions: TLR, arity, arity-met, arity-short @@ -133,7 +137,7 @@ let mkLocalNameTypeArity compgen m name ty topValInfo = let GetValsBoundUnderMustInline xinfo = let accRejectFrom (v: Val) repr rejectS = - if v.InlineInfo = ValInline.PseudoVal then + if v.InlineInfo = ValInline.Always then Zset.union (GetValsBoundInExpr repr) rejectS else rejectS let rejectS = Zset.empty valOrder @@ -153,7 +157,9 @@ let IsRefusedTLR g (f: Val) = // Special values are instance methods etc. on .NET types. For now leave these alone let specialVal = f.MemberInfo.IsSome let alreadyChosen = f.ValReprInfo.IsSome - let refuseTest = alreadyChosen || mutableVal || byrefVal || specialVal || dllImportStubOrOtherNeverInline + let isResumableCode = isReturnsResumableCodeTy g f.Type + let isInlineIfLambda = f.InlineIfLambda + let refuseTest = alreadyChosen || mutableVal || byrefVal || specialVal || dllImportStubOrOtherNeverInline || isResumableCode || isInlineIfLambda refuseTest let IsMandatoryTopLevel (f: Val) = @@ -332,7 +338,7 @@ type ReqdItemsForDefn = { reqdTypars: Zset reqdItems: Zset - m: Range.range + m: range } member env.ReqdSubEnvs = [ for x in env.reqdItems do match x with | ReqdSubEnv f -> yield f | ReqdVal _ -> () ] @@ -671,7 +677,7 @@ type PackedReqdItems = // step3: FlatEnvPacks //------------------------------------------------------------------------- -exception AbortTLR of Range.range +exception AbortTLR of range /// A naive packing of environments. /// Chooses to pass all env values as explicit args (no tupling). @@ -703,7 +709,7 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap List.distinctBy (fun v -> v.Stamp) // Remove genuinely toplevel, no need to close over these let vals = vals |> List.filter (IsMandatoryTopLevel >> not) @@ -762,7 +768,7 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap List.map (fun (subv, subaenv) -> mkBind NoSequencePointAtInvisibleBinding subaenv (aenvExprFor subv)) + vaenvs |> List.map (fun (subv, subaenv) -> mkBind DebugPointAtBinding.NoneAtInvisible subaenv (aenvExprFor subv)) List.map unpackCarrier (Zmap.toList cmap) @ List.collect unpackSubenv env.ReqdSubEnvs @@ -894,7 +900,7 @@ module Pass4_RewriteAssembly = /// /// Top-level status ends when stepping inside a lambda, where a lambda is: /// Expr.TyLambda, Expr.Lambda, Expr.Obj (and tmethods). - /// [... also, try_catch handlers, and switch targets...] + /// [... also, try_with handlers, and switch targets...] /// /// Top* repr bindings already at top-level do not need moving... /// [and should not be, since they may lift over unmoved defns on which they depend]. @@ -963,13 +969,14 @@ module Pass4_RewriteAssembly = // pass4: lowertop - convert_vterm_bind on TopLevel binds //------------------------------------------------------------------------- - let ConvertBind g (TBind(v, repr, _) as bind) = + let AdjustBindToTopVal g (TBind(v, repr, _)) = match v.ValReprInfo with - | None -> v.SetValReprInfo (Some (InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v repr )) + | None -> + v.SetValReprInfo (Some (InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v repr )) + // Things that don't have an arity from type inference but are top-level are compiler-generated + v.SetIsCompilerGenerated(true) | Some _ -> () - bind - //------------------------------------------------------------------------- // pass4: transBind (translate) //------------------------------------------------------------------------- @@ -1031,6 +1038,9 @@ module Pass4_RewriteAssembly = | None -> List.empty // no env for this mutual binding | Some envp -> envp.ep_pack // environment pack bindings + let forceTopBindToHaveArity penv (bind: Binding) = + if penv.topValS.Contains(bind.Var) then AdjustBindToTopVal penv.g bind + let TransBindings xisRec penv (binds: Bindings) = let tlrBs, nonTlrBs = binds |> List.partition (fun b -> Zset.contains b.Var penv.tlrS) let fclass = BindingGroupSharingSameReqdItems tlrBs @@ -1041,12 +1051,9 @@ module Pass4_RewriteAssembly = // QUERY: we repeat this logic in LowerCallsAndSeqs. Do we really need to do this here? // QUERY: yes and no - if we don't, we have an unrealizable term, and many decisions must // QUERY: correlate with LowerCallsAndSeqs. - let forceTopBindToHaveArity (bind: Binding) = - if penv.topValS.Contains(bind.Var) then ConvertBind penv.g bind - else bind - let nonTlrBs = nonTlrBs |> List.map forceTopBindToHaveArity - let tlrRebinds = tlrRebinds |> List.map forceTopBindToHaveArity + nonTlrBs |> List.iter (forceTopBindToHaveArity penv) + tlrRebinds |> List.iter (forceTopBindToHaveArity penv) // assemble into replacement bindings let bindAs, rebinds = match xisRec with @@ -1063,7 +1070,7 @@ module Pass4_RewriteAssembly = // Is it a val app, where the val f is TLR with arity wf? // CLEANUP NOTE: should be using a mkApps to make all applications match fx with - | Expr.Val (fvref: ValRef, _, m) when + | Expr.Val (fvref: ValRef, _, vm) when (Zset.contains fvref.Deref penv.tlrS) && (let wf = Zmap.force fvref.Deref penv.arityM ("TransApp - wf", nameOfVal) IsArityMet fvref wf tys args) -> @@ -1074,14 +1081,13 @@ module Pass4_RewriteAssembly = let envp = Zmap.force fc penv.envPackM ("TransApp - envp", string) let fHat = Zmap.force f penv.fHatM ("TransApp - fHat", nameOfVal) let tys = (List.map mkTyparTy envp.ep_etps) @ tys - let aenvExprs = List.map (exprForVal m) envp.ep_aenvs + let aenvExprs = List.map (exprForVal vm) envp.ep_aenvs let args = aenvExprs @ args - mkApps penv.g ((exprForVal m fHat, fHat.Type), [tys], args, m) (* change, direct fHat call with closure (reqdTypars, aenvs) *) + mkApps penv.g ((exprForVal vm fHat, fHat.Type), [tys], args, m) (* change, direct fHat call with closure (reqdTypars, aenvs) *) | _ -> if isNil tys && isNil args then fx else Expr.App (fx, fty, tys, args, m) - (* no change, f is expr *) //------------------------------------------------------------------------- // pass4: pass (over expr) @@ -1126,12 +1132,12 @@ module Pass4_RewriteAssembly = // ilobj - has implicit lambda exprs and recursive/base references | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, m) -> - let basecall, z = TransExpr penv z basecall - let overrides, z = List.mapFold (TransMethod penv) z overrides - let (iimpls:(TType*ObjExprMethod list)list), (z: RewriteState) = - List.mapFold (fun z (tType, objExprs) -> + let basecall, z = TransExpr penv z basecall + let overrides, z = List.mapFold (TransMethod penv) z overrides + let iimpls, z = + (z, iimpls) ||> List.mapFold (fun z (tType, objExprs) -> let objExprs', z' = List.mapFold (TransMethod penv) z objExprs - (tType, objExprs'), z') z iimpls + (tType, objExprs'), z') let expr = Expr.Obj (newUnique(), ty, basev, basecall, overrides, iimpls, m) let pds, z = ExtractPreDecs z MakePreDecs m pds expr, z (* if TopLevel, lift preDecs over the ilobj expr *) @@ -1165,12 +1171,20 @@ module Pass4_RewriteAssembly = | Expr.Const _ -> expr,z - | Expr.Quote (a,{contents=Some(typeDefs,argTypes,argExprs,data)},isFromQueryExpression,m,ty) -> - let argExprs,z = List.mapFold (TransExpr penv) z argExprs - Expr.Quote (a,{contents=Some(typeDefs,argTypes,argExprs,data)},isFromQueryExpression,m,ty),z + | Expr.Quote (a,dataCell,isFromQueryExpression,m,ty) -> + let doData (typeDefs,argTypes,argExprs,data) z = + let argExprs,z = List.mapFold (TransExpr penv) z argExprs + (typeDefs,argTypes,argExprs,data), z - | Expr.Quote (a,{contents=None},isFromQueryExpression,m,ty) -> - Expr.Quote (a,{contents=None},isFromQueryExpression,m,ty),z + let data, z = + match !dataCell with + | Some (data1, data2) -> + let data1, z = doData data1 z + let data2, z = doData data2 z + Some (data1, data2), z + | None -> None, z + + Expr.Quote (a,ref data,isFromQueryExpression,m,ty),z | Expr.Op (c,tyargs,args,m) -> let args,z = List.mapFold (TransExpr penv) z args @@ -1184,6 +1198,9 @@ module Pass4_RewriteAssembly = | Expr.TyChoose (_,_,m) -> error(Error(FSComp.SR.tlrUnexpectedTExpr(),m)) + | Expr.WitnessArg (_witnessInfo, _m) -> + expr, z + /// Walk over linear structured terms in tail-recursive loop, using a continuation /// to represent the rebuild-the-term stack and TransLinearExpr penv z expr (contf: Expr * RewriteState -> Expr * RewriteState) = @@ -1210,7 +1227,7 @@ module Pass4_RewriteAssembly = // tailcall TransLinearExpr penv z e (contf << (fun (e, z) -> let e = mkLetsFromBindings m rebinds e - MakePreDecs m pds (Expr.LetRec (binds, e, m, NewFreeVarsCache())), z)) + MakePreDecs m pds (Expr.LetRec (binds, e, m, Construct.NewFreeVarsCache())), z)) // let - can consider the mu-let bindings as mu-letrec bindings - so like as above | Expr.Let (bind, e, m, _) -> @@ -1261,11 +1278,13 @@ module Pass4_RewriteAssembly = | TDSuccess (es, n) -> let es, z = List.mapFold (TransExpr penv) z es TDSuccess(es, n), z + | TDBind (bind, rest) -> let bind, z = TransBindingRhs penv z bind let rest, z = TransDecisionTree penv z rest TDBind(bind, rest), z - | TDSwitch (e, cases, dflt, m) -> + + | TDSwitch (sp, e, cases, dflt, m) -> let e, z = TransExpr penv z e let TransDecisionTreeCase penv z (TCase (discrim, dtree)) = let dtree, z = TransDecisionTree penv z dtree @@ -1273,16 +1292,18 @@ module Pass4_RewriteAssembly = let cases, z = List.mapFold (TransDecisionTreeCase penv) z cases let dflt, z = Option.mapFold (TransDecisionTree penv) z dflt - TDSwitch (e, cases, dflt, m), z + TDSwitch (sp, e, cases, dflt, m), z - and TransDecisionTreeTarget penv z (TTarget(vs, e, spTarget)) = + and TransDecisionTreeTarget penv z (TTarget(vs, e, spTarget, flags)) = let z = EnterInner z let e, z = TransExpr penv z e let z = ExitInner z - TTarget(vs, e, spTarget), z + TTarget(vs, e, spTarget, flags), z and TransValBinding penv z bind = TransBindingRhs penv z bind + and TransValBindings penv z binds = List.mapFold (TransValBinding penv) z binds + and TransModuleExpr penv z x = match x with | ModuleOrNamespaceExprWithSig(mty, def, m) -> @@ -1290,11 +1311,12 @@ module Pass4_RewriteAssembly = ModuleOrNamespaceExprWithSig(mty, def, m), z and TransModuleDefs penv z x = List.mapFold (TransModuleDef penv) z x + and TransModuleDef penv (z: RewriteState) x: ModuleOrNamespaceExpr * RewriteState = match x with - | TMDefRec(isRec, tycons, mbinds, m) -> + | TMDefRec(isRec, opens, tycons, mbinds, m) -> let mbinds, z = TransModuleBindings penv z mbinds - TMDefRec(isRec, tycons, mbinds, m), z + TMDefRec(isRec, opens, tycons, mbinds, m), z | TMDefLet(bind, m) -> let bind, z = TransValBinding penv z bind TMDefLet(bind, m), z @@ -1304,10 +1326,14 @@ module Pass4_RewriteAssembly = | TMDefs defs -> let defs, z = TransModuleDefs penv z defs TMDefs defs, z + | TMDefOpens _ -> + x, z | TMAbstract mexpr -> let mexpr, z = TransModuleExpr penv z mexpr TMAbstract mexpr, z + and TransModuleBindings penv z binds = List.mapFold (TransModuleBinding penv) z binds + and TransModuleBinding penv z x = match x with | ModuleOrNamespaceBinding.Binding bind -> @@ -1332,7 +1358,7 @@ let RecreateUniqueBounds g expr = // entry point //------------------------------------------------------------------------- -let MakeTLRDecisions ccu g expr = +let MakeTopLevelRepresentationDecisions ccu g expr = try // pass1: choose the f to be TLR with arity(f) let tlrS, topValS, arityM = Pass1_DetermineTLRAndArities.DetermineTLRAndArities g expr diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fsi b/src/fsharp/InnerLambdasToTopLevelFuncs.fsi index 5a25c27ac59..a66bcdb0248 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fsi +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fsi @@ -2,7 +2,7 @@ module internal FSharp.Compiler.InnerLambdasToTopLevelFuncs -open FSharp.Compiler +open FSharp.Compiler.TypedTree open FSharp.Compiler.TcGlobals -val MakeTLRDecisions : Tast.CcuThunk -> TcGlobals -> Tast.TypedImplFile -> Tast.TypedImplFile +val MakeTopLevelRepresentationDecisions : CcuThunk -> TcGlobals -> TypedImplFile -> TypedImplFile diff --git a/src/fsharp/InternalCollections.fs b/src/fsharp/InternalCollections.fs index 6ffb9f06802..a2c3b3ad65a 100755 --- a/src/fsharp/InternalCollections.fs +++ b/src/fsharp/InternalCollections.fs @@ -12,18 +12,13 @@ type internal ValueStrength<'T when 'T : not struct> = | Weak of WeakReference<'T> #endif -type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStrongly:int, areSimilar, ?requiredToKeep, ?onStrongDiscard, ?keepMax: int) = +type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStrongly:int, areSimilar, ?requiredToKeep, ?keepMax: int) = /// The list of items stored. Youngest is at the end of the list. /// The choice of order is somewhat arbitrary. If the other way then adding /// items would be O(1) and removing O(N). let mutable refs:('Key*ValueStrength<'Value>) list = [] let mutable keepStrongly = keepStrongly - // Only set a strong discard function if keepMax is explicitly set to keepStrongly, i.e. there are no weak entries in this lookup. - do assert (onStrongDiscard.IsNone || Some keepStrongly = keepMax) - - let strongDiscard x = match onStrongDiscard with None -> () | Some f -> f x - // The 75 here determines how long the list should be passed the end of strongly held // references. Some operations are O(N) and we don't want to let things get out of // hand. @@ -56,8 +51,8 @@ type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStro /// Remove a particular key value. let RemoveImpl (data, key) = - let discard,keep = data |> List.partition (fun (similarKey,_)-> areSimilar(key,similarKey)) - keep, discard + let keep = data |> List.filter (fun (similarKey,_)-> not (areSimilar(key,similarKey))) + keep let TryGetKeyValueImpl(data,key) = match TryPeekKeyValueImpl(data,key) with @@ -69,33 +64,32 @@ type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStro /// Remove weak entries from the list that have been collected. let FilterAndHold(tok: 'Token) = ignore tok // reading 'refs' requires a token - [ for (key,value) in refs do + [ for key,value in refs do match value with | Strong(value) -> yield (key,value) | Weak(weakReference) -> #if FX_NO_GENERIC_WEAKREFERENCE match weakReference.Target with - | null -> assert onStrongDiscard.IsNone; () + | null -> () | value -> yield key,(value:?>'Value) ] #else match weakReference.TryGetTarget () with - | false, _ -> assert onStrongDiscard.IsNone; () + | false, _ -> () | true, value -> yield key, value ] #endif - let AssignWithStrength(tok,newData,discard1) = + let AssignWithStrength(tok,newData) = let actualLength = List.length newData let tossThreshold = max 0 (actualLength - keepMax) // Delete everything less than this threshold let weakThreshold = max 0 (actualLength - keepStrongly) // Weaken everything less than this threshold let newData = newData|> List.mapi( fun n kv -> n,kv ) // Place the index. - let newData,discard2 = newData |> List.partition (fun (n:int,v) -> n >= tossThreshold || requiredToKeep (snd v)) + let newData = newData |> List.filter (fun (n:int,v) -> n >= tossThreshold || requiredToKeep (snd v)) let newData = newData |> List.map( fun (n:int,(k,v)) -> let handle = if n(keepStro k,handle ) ignore tok // Updating refs requires tok refs <- newData - discard1 |> List.iter (snd >> strongDiscard) - discard2 |> List.iter (snd >> snd >> strongDiscard) member al.TryPeekKeyValue(tok, key) = // Returns the original key value as well since it may be different depending on equality test. @@ -117,43 +109,42 @@ type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct>(keepStro member al.TryGetKeyValue(tok, key) = let data = FilterAndHold(tok) let result,newData = TryGetKeyValueImpl(data,key) - AssignWithStrength(tok,newData,[]) + AssignWithStrength(tok,newData) result member al.TryGet(tok, key) = let data = FilterAndHold(tok) let result,newData = TryGetKeyValueImpl(data,key) - AssignWithStrength(tok,newData,[]) + AssignWithStrength(tok,newData) match result with | Some(_,value) -> Some(value) | None -> None member al.Put(tok, key,value) = let data = FilterAndHold(tok) - let data,discard = if Exists(data,key) then RemoveImpl (data,key) else data,[] + let data = if Exists(data,key) then RemoveImpl (data,key) else data let data = Add(data,key,value) - AssignWithStrength(tok,data,discard) // This will remove extras + AssignWithStrength(tok,data) // This will remove extras member al.Remove(tok, key) = let data = FilterAndHold(tok) - let newData,discard = RemoveImpl (data,key) - AssignWithStrength(tok,newData,discard) + let newData = RemoveImpl (data,key) + AssignWithStrength(tok,newData) member al.Clear(tok) = - let discards = FilterAndHold(tok) - AssignWithStrength(tok,[], discards) + let _discards = FilterAndHold(tok) + AssignWithStrength(tok,[]) member al.Resize(tok, newKeepStrongly, ?newKeepMax) = let newKeepMax = defaultArg newKeepMax 75 keepStrongly <- newKeepStrongly keepMax <- max newKeepStrongly newKeepMax - do assert (onStrongDiscard.IsNone || keepStrongly = keepMax) let keep = FilterAndHold(tok) - AssignWithStrength(tok,keep, []) + AssignWithStrength(tok,keep) -type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongly, areSame, ?isStillValid : 'Key*'Value->bool, ?areSimilar, ?requiredToKeep, ?onStrongDiscard, ?keepMax) = +type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongly, areSame, ?isStillValid : 'Key*'Value->bool, ?areSimilar, ?requiredToKeep, ?keepMax) = /// Default behavior of areSimilar function is areSame. let areSimilar = defaultArg areSimilar areSame @@ -161,7 +152,7 @@ type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongl /// The list of items in the cache. Youngest is at the end of the list. /// The choice of order is somewhat arbitrary. If the other way then adding /// items would be O(1) and removing O(N). - let cache = AgedLookup<'Token, 'Key,'Value>(keepStrongly=keepStrongly,areSimilar=areSimilar,?onStrongDiscard=onStrongDiscard,?keepMax=keepMax,?requiredToKeep=requiredToKeep) + let cache = AgedLookup<'Token, 'Key,'Value>(keepStrongly=keepStrongly,areSimilar=areSimilar,?keepMax=keepMax,?requiredToKeep=requiredToKeep) /// Whether or not this result value is still valid. let isStillValid = defaultArg isStillValid (fun _ -> true) @@ -184,6 +175,18 @@ type internal MruCache<'Token, 'Key,'Value when 'Value : not struct>(keepStrongl if areSame(similarKey, key) && isStillValid(key,value) then Some value else None | None -> None + + member bc.TryGetSimilarAny(tok, key) = + match cache.TryGetKeyValue(tok, key) with + | Some(_, value) -> Some value + | None -> None + + member bc.TryGetSimilar(tok, key) = + match cache.TryGetKeyValue(tok, key) with + | Some(_, value) -> + if isStillValid(key,value) then Some value + else None + | None -> None member bc.Set(tok, key:'Key,value:'Value) = cache.Put(tok, key,value) diff --git a/src/fsharp/InternalCollections.fsi b/src/fsharp/InternalCollections.fsi index 711fb91d848..3cd62bae5fa 100755 --- a/src/fsharp/InternalCollections.fsi +++ b/src/fsharp/InternalCollections.fsi @@ -2,55 +2,58 @@ namespace Internal.Utilities.Collections - /// Simple aging lookup table. When a member is accessed it's - /// moved to the top of the list and when there are too many elements - /// the least-recently-accessed element falls of the end. - /// - /// - areSimilar: Keep at most once association for two similar keys (as given by areSimilar) - type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct> = +/// Simple aging lookup table. When a member is accessed it's +/// moved to the top of the list and when there are too many elements +/// the least-recently-accessed element falls of the end. +/// +/// - areSimilar: Keep at most once association for two similar keys (as given by areSimilar) +type internal AgedLookup<'Token, 'Key, 'Value when 'Value : not struct> = new : keepStrongly:int * areSimilar:('Key * 'Key -> bool) * ?requiredToKeep:('Value -> bool) - * ?onStrongDiscard : ('Value -> unit) // this may only be set if keepTotal=keepStrongly, i.e. not weak entries * ?keepMax: int -> AgedLookup<'Token,'Key,'Value> + /// Lookup the value without making it the most recent. /// Returns the original key value because the areSame function /// may have unified two different keys. member TryPeekKeyValue : 'Token * key:'Key -> ('Key*'Value) option + /// Lookup a value and make it the most recent. /// Returns the original key value because the areSame function /// may have unified two different keys. member TryGetKeyValue : 'Token * key: 'Key -> ('Key*'Value) option + /// Lookup a value and make it the most recent. Return None if it wasn't there. member TryGet : 'Token * key:'Key -> 'Value option + /// Add an element to the collection. Make it the most recent. member Put : 'Token * 'Key * 'Value -> unit + /// Remove the given value from the collection. member Remove : 'Token * key:'Key -> unit + /// Remove all elements. member Clear : 'Token -> unit + /// Resize - member Resize : 'Token * keepStrongly: int * ?keepMax : int -> unit + member Resize : 'Token * newKeepStrongly: int * ?newKeepMax : int -> unit - /// Simple priority caching for a small number of key/value associations. - /// This cache may age-out results that have been Set by the caller. - /// Because of this, the caller must be able to tolerate values - /// that aren't what was originally passed to the Set function. - /// - /// Concurrency: This collection is thread-safe, though concurrent use may result in different - /// threads seeing different live sets of cached items, and may result in the onDiscard action - /// being called multiple times. In practice this means the collection is only safe for concurrent - /// access if there is no discard action to execute. - /// - /// - areSimilar: Keep at most once association for two similar keys (as given by areSimilar) - type internal MruCache<'Token, 'Key,'Value when 'Value : not struct> = +/// Simple priority caching for a small number of key/value associations. +/// This cache may age-out results that have been Set by the caller. +/// Because of this, the caller must be able to tolerate values +/// that aren't what was originally passed to the Set function. +/// +/// Concurrency: This collection is thread-safe, though concurrent use may result in different +/// threads seeing different live sets of cached items. +/// +/// - areSimilar: Keep at most once association for two similar keys (as given by areSimilar) +type internal MruCache<'Token, 'Key,'Value when 'Value : not struct> = new : keepStrongly:int * areSame:('Key * 'Key -> bool) * ?isStillValid:('Key * 'Value -> bool) * ?areSimilar:('Key * 'Key -> bool) * ?requiredToKeep:('Value -> bool) - * ?onDiscard:('Value -> unit) * ?keepMax:int -> MruCache<'Token,'Key,'Value> @@ -66,6 +69,12 @@ namespace Internal.Utilities.Collections /// Get the value for the given key or None, but only if entry is still valid member TryGet : 'Token * key:'Key -> 'Value option + /// Get the value for the given key or None if not still valid. Skips `areSame` checking unless `areSimilar` is not provided. + member TryGetSimilarAny : 'Token * key:'Key -> 'Value option + + /// Get the value for the given key or None, but only if entry is still valid. Skips `areSame` checking unless `areSimilar` is not provided. + member TryGetSimilar : 'Token * key:'Key -> 'Value option + /// Remove the given value from the mru cache. member RemoveAnySimilar : 'Token * key:'Key -> unit @@ -73,5 +82,5 @@ namespace Internal.Utilities.Collections member Set : 'Token * key:'Key * value:'Value -> unit /// Resize - member Resize : 'Token * keepStrongly: int * ?keepMax : int -> unit + member Resize : 'Token * newKeepStrongly: int * ?newKeepMax : int -> unit diff --git a/src/fsharp/LanguageFeatures.fs b/src/fsharp/LanguageFeatures.fs index eeac561751a..537910eccf9 100644 --- a/src/fsharp/LanguageFeatures.fs +++ b/src/fsharp/LanguageFeatures.fs @@ -3,8 +3,6 @@ /// Coordinating compiler operations - configuration, loading initial context, reporting errors etc. module internal FSharp.Compiler.Features -open System - //------------------------------------------------------------------------------------------------------------------ // Language version command line switch //------------------------------------------------------------------------------------------------------------------ @@ -21,28 +19,47 @@ type LanguageFeature = | SingleUnderscorePattern | WildCardInForLoop | RelaxWhitespace + | RelaxWhitespace2 | NameOf | ImplicitYield - | OpenStaticClasses + | OpenTypeDeclaration | DotlessFloat32Literal | PackageManagement | FromEndSlicing | FixedIndexSlice3d4d + | AndBang + | ResumableStateMachines + | NullableOptionalInterop + | DefaultInterfaceMemberConsumption + | WitnessPassing + | AdditionalTypeDirectedConversions + | InterfacesWithMultipleGenericInstantiation + | StringInterpolation + | OverloadsForCustomOperations + | ExpandedMeasurables + | StructActivePattern + | PrintfBinaryFormat + | IndexerNotationWithoutDot + | RefCellNotationInformationals + | UseBindingValueDiscard + | NonVariablePatternsToRightOfAsPatterns + | AttributesToRightOfModuleKeyword + | MLCompatRevisions /// LanguageVersion management -type LanguageVersion (specifiedVersionAsString) = +type LanguageVersion (versionText) = // When we increment language versions here preview is higher than current RTM version static let languageVersion46 = 4.6m static let languageVersion47 = 4.7m static let languageVersion50 = 5.0m static let previewVersion = 9999m // Language version when preview specified - static let defaultVersion = languageVersion47 // Language version when default specified + static let defaultVersion = languageVersion50 // Language version when default specified static let latestVersion = defaultVersion // Language version when latest specified - static let latestMajorVersion = languageVersion47 // Language version when latestmajor specified + static let latestMajorVersion = languageVersion50 // Language version when latestmajor specified static let validOptions = [| "preview"; "default"; "latest"; "latestmajor" |] - static let languageVersions = set [| languageVersion46; languageVersion47 (*; languageVersion50 *) |] + static let languageVersions = set [| languageVersion46; languageVersion47 ; languageVersion50 |] static let features = dict [ @@ -54,17 +71,38 @@ type LanguageVersion (specifiedVersionAsString) = // F# 5.0 LanguageFeature.FixedIndexSlice3d4d, languageVersion50 - LanguageFeature.FromEndSlicing, languageVersion50 + LanguageFeature.DotlessFloat32Literal, languageVersion50 + LanguageFeature.AndBang, languageVersion50 + LanguageFeature.NullableOptionalInterop, languageVersion50 + LanguageFeature.DefaultInterfaceMemberConsumption, languageVersion50 + LanguageFeature.OpenTypeDeclaration, languageVersion50 + LanguageFeature.PackageManagement, languageVersion50 + LanguageFeature.WitnessPassing, languageVersion50 + LanguageFeature.InterfacesWithMultipleGenericInstantiation, languageVersion50 + LanguageFeature.NameOf, languageVersion50 + LanguageFeature.StringInterpolation, languageVersion50 // F# preview - LanguageFeature.NameOf, previewVersion - LanguageFeature.OpenStaticClasses, previewVersion - LanguageFeature.DotlessFloat32Literal, languageVersion50 - LanguageFeature.PackageManagement, previewVersion + LanguageFeature.AdditionalTypeDirectedConversions, previewVersion + LanguageFeature.RelaxWhitespace2, previewVersion + LanguageFeature.OverloadsForCustomOperations, previewVersion + LanguageFeature.ExpandedMeasurables, previewVersion + LanguageFeature.FromEndSlicing, previewVersion + LanguageFeature.ResumableStateMachines, previewVersion + LanguageFeature.StructActivePattern, previewVersion + LanguageFeature.PrintfBinaryFormat, previewVersion + LanguageFeature.IndexerNotationWithoutDot, previewVersion + LanguageFeature.RefCellNotationInformationals, previewVersion + LanguageFeature.UseBindingValueDiscard, previewVersion + LanguageFeature.NonVariablePatternsToRightOfAsPatterns, previewVersion + LanguageFeature.AttributesToRightOfModuleKeyword, previewVersion + LanguageFeature.MLCompatRevisions,previewVersion ] + static let defaultLanguageVersion = LanguageVersion("default") + let specified = - match specifiedVersionAsString with + match versionText with | "?" -> 0m | "preview" -> previewVersion | "default" -> defaultVersion @@ -72,34 +110,102 @@ type LanguageVersion (specifiedVersionAsString) = | "latestmajor" -> latestMajorVersion | "4.6" -> languageVersion46 | "4.7" -> languageVersion47 -(* | "5.0" -> languageVersion50 *) + | "5.0" -> languageVersion50 | _ -> 0m + let versionToString v = + if v = previewVersion then "'preview'" + else string v + + let specifiedString = versionToString specified + /// Check if this feature is supported by the selected langversion - member __.SupportsFeature featureId = + member _.SupportsFeature featureId = match features.TryGetValue featureId with | true, v -> v <= specified | false, _ -> false /// Has preview been explicitly specified - member __.IsPreviewEnabled = + member _.IsExplicitlySpecifiedAs50OrBefore() = + match versionText with + | "4.6" -> true + | "4.7" -> true + | "5.0" -> true + | _ -> false + + /// Has preview been explicitly specified + member _.IsPreviewEnabled = specified = previewVersion /// Does the languageVersion support this version string - member __.ContainsVersion version = + member _.ContainsVersion version = match version with | "?" | "preview" | "default" | "latest" | "latestmajor" -> true | _ -> languageVersions.Contains specified /// Get a list of valid strings for help text - member __.ValidOptions = validOptions + member _.ValidOptions = validOptions /// Get a list of valid versions for help text - member __.ValidVersions = + member _.ValidVersions = [| for v in languageVersions |> Seq.sort -> sprintf "%M%s" v (if v = defaultVersion then " (Default)" else "") |] + /// Get the text used to specify the version + member _.VersionText = versionText + /// Get the specified LanguageVersion - member __.SpecifiedVersion = specified + member _.SpecifiedVersion = specified + + /// Get the specified LanguageVersion as a string + member _.SpecifiedVersionString = specifiedString + + /// Get a string name for the given feature. + member _.GetFeatureString feature = + match feature with + | LanguageFeature.SingleUnderscorePattern -> FSComp.SR.featureSingleUnderscorePattern() + | LanguageFeature.WildCardInForLoop -> FSComp.SR.featureWildCardInForLoop() + | LanguageFeature.RelaxWhitespace -> FSComp.SR.featureRelaxWhitespace() + | LanguageFeature.RelaxWhitespace2 -> FSComp.SR.featureRelaxWhitespace2() + | LanguageFeature.NameOf -> FSComp.SR.featureNameOf() + | LanguageFeature.ImplicitYield -> FSComp.SR.featureImplicitYield() + | LanguageFeature.OpenTypeDeclaration -> FSComp.SR.featureOpenTypeDeclaration() + | LanguageFeature.DotlessFloat32Literal -> FSComp.SR.featureDotlessFloat32Literal() + | LanguageFeature.PackageManagement -> FSComp.SR.featurePackageManagement() + | LanguageFeature.FromEndSlicing -> FSComp.SR.featureFromEndSlicing() + | LanguageFeature.FixedIndexSlice3d4d -> FSComp.SR.featureFixedIndexSlice3d4d() + | LanguageFeature.AndBang -> FSComp.SR.featureAndBang() + | LanguageFeature.ResumableStateMachines -> FSComp.SR.featureResumableStateMachines() + | LanguageFeature.NullableOptionalInterop -> FSComp.SR.featureNullableOptionalInterop() + | LanguageFeature.DefaultInterfaceMemberConsumption -> FSComp.SR.featureDefaultInterfaceMemberConsumption() + | LanguageFeature.WitnessPassing -> FSComp.SR.featureWitnessPassing() + | LanguageFeature.AdditionalTypeDirectedConversions -> FSComp.SR.featureAdditionalImplicitConversions() + | LanguageFeature.InterfacesWithMultipleGenericInstantiation -> FSComp.SR.featureInterfacesWithMultipleGenericInstantiation() + | LanguageFeature.StringInterpolation -> FSComp.SR.featureStringInterpolation() + | LanguageFeature.OverloadsForCustomOperations -> FSComp.SR.featureOverloadsForCustomOperations() + | LanguageFeature.ExpandedMeasurables -> FSComp.SR.featureExpandedMeasurables() + | LanguageFeature.StructActivePattern -> FSComp.SR.featureStructActivePattern() + | LanguageFeature.PrintfBinaryFormat -> FSComp.SR.featurePrintfBinaryFormat() + | LanguageFeature.IndexerNotationWithoutDot -> FSComp.SR.featureIndexerNotationWithoutDot() + | LanguageFeature.RefCellNotationInformationals -> FSComp.SR.featureRefCellNotationInformationals() + | LanguageFeature.UseBindingValueDiscard -> FSComp.SR.featureDiscardUseValue() + | LanguageFeature.NonVariablePatternsToRightOfAsPatterns -> FSComp.SR.featureNonVariablePatternsToRightOfAsPatterns() + | LanguageFeature.AttributesToRightOfModuleKeyword -> FSComp.SR.featureAttributesToRightOfModuleKeyword() + | LanguageFeature.MLCompatRevisions -> FSComp.SR.featureMLCompatRevisions() + + /// Get a version string associated with the given feature. + member _.GetFeatureVersionString feature = + match features.TryGetValue feature with + | true, v -> versionToString v + | _ -> invalidArg "feature" "Internal error: Unable to find feature." + + override x.Equals(yobj: obj) = + match yobj with + | :? LanguageVersion as y -> x.SpecifiedVersion = y.SpecifiedVersion + | _ -> false + + override x.GetHashCode() = hash x.SpecifiedVersion + + static member Default = defaultLanguageVersion diff --git a/src/fsharp/LanguageFeatures.fsi b/src/fsharp/LanguageFeatures.fsi index 37a58a50b49..a70d741a4dd 100644 --- a/src/fsharp/LanguageFeatures.fsi +++ b/src/fsharp/LanguageFeatures.fsi @@ -9,14 +9,32 @@ type LanguageFeature = | SingleUnderscorePattern | WildCardInForLoop | RelaxWhitespace + | RelaxWhitespace2 | NameOf | ImplicitYield - | OpenStaticClasses + | OpenTypeDeclaration | DotlessFloat32Literal | PackageManagement | FromEndSlicing | FixedIndexSlice3d4d - + | AndBang + | ResumableStateMachines + | NullableOptionalInterop + | DefaultInterfaceMemberConsumption + | WitnessPassing + | AdditionalTypeDirectedConversions + | InterfacesWithMultipleGenericInstantiation + | StringInterpolation + | OverloadsForCustomOperations + | ExpandedMeasurables + | StructActivePattern + | PrintfBinaryFormat + | IndexerNotationWithoutDot + | RefCellNotationInformationals + | UseBindingValueDiscard + | NonVariablePatternsToRightOfAsPatterns + | AttributesToRightOfModuleKeyword + | MLCompatRevisions /// LanguageVersion management type LanguageVersion = @@ -30,6 +48,9 @@ type LanguageVersion = /// Has preview been explicitly specified member IsPreviewEnabled: bool + /// Has been explicitly specified as 4.6, 4.7 or 5.0 + member IsExplicitlySpecifiedAs50OrBefore: unit -> bool + /// Does the selected LanguageVersion support the specified feature member SupportsFeature: LanguageFeature -> bool @@ -41,3 +62,17 @@ type LanguageVersion = /// Get the specified LanguageVersion member SpecifiedVersion: decimal + + /// Get the text used to specify the version, several of which may map to the same version + member VersionText: string + + /// Get the specified LanguageVersion as a string + member SpecifiedVersionString: string + + /// Get a string name for the given feature. + member GetFeatureString: feature: LanguageFeature -> string + + /// Get a version string associated with the given feature. + member GetFeatureVersionString: feature: LanguageFeature -> string + + static member Default: LanguageVersion diff --git a/src/fsharp/LegacyHostedCompilerForTesting.fs b/src/fsharp/LegacyHostedCompilerForTesting.fs index 821882d84d5..dfa036f7ee0 100644 --- a/src/fsharp/LegacyHostedCompilerForTesting.fs +++ b/src/fsharp/LegacyHostedCompilerForTesting.fs @@ -3,18 +3,18 @@ // This component is used by the 'fsharpqa' tests for faster in-memory compilation. It should be removed and the // proper compiler service API used instead. -namespace Legacy.FSharp.Compiler.Hosted +namespace FSharp.Compiler.CodeAnalysis.Hosted open System open System.IO -open System.Text open System.Text.RegularExpressions -open FSharp.Compiler +open FSharp.Compiler.Diagnostics open FSharp.Compiler.Driver open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library /// build issue location type internal Location = @@ -66,7 +66,7 @@ type internal InProcCompiler(legacyReferenceResolver) = { new Exiter with member this.Exit n = exitCode <- n; raise StopProcessing } try - typecheckAndCompile(ctok, argv, legacyReferenceResolver, false, ReduceMemoryFlag.Yes, CopyFSharpCoreFlag.Yes, exiter, loggerProvider.Provider, None, None) + mainCompile(ctok, argv, legacyReferenceResolver, false, ReduceMemoryFlag.Yes, CopyFSharpCoreFlag.Yes, exiter, loggerProvider.Provider, None, None) with | StopProcessing -> () | ReportedError _ | WrappedError(ReportedError _,_) -> @@ -91,16 +91,16 @@ type internal FscCompiler(legacyReferenceResolver) = /// converts short and long issue types to the same CompilationIssue representation let convert issue : CompilationIssue = match issue with - | Diagnostic.Short(isError, text) -> + | Diagnostic.Short(severity, text) -> { Location = emptyLocation Code = "" Subcategory = "" File = "" Text = text - Type = if isError then CompilationIssueType.Error else CompilationIssueType.Warning + Type = if (severity = FSharpDiagnosticSeverity.Error) then CompilationIssueType.Error else CompilationIssueType.Warning } - | Diagnostic.Long(isError, details) -> + | Diagnostic.Long(severity, details) -> let loc, file = match details.Location with | Some l when not l.IsEmpty -> @@ -117,7 +117,7 @@ type internal FscCompiler(legacyReferenceResolver) = Subcategory = details.Canonical.Subcategory File = file Text = details.Message - Type = if isError then CompilationIssueType.Error else CompilationIssueType.Warning + Type = if (severity = FSharpDiagnosticSeverity.Error) then CompilationIssueType.Error else CompilationIssueType.Warning } /// test if --test:ErrorRanges flag is set @@ -148,7 +148,7 @@ type internal FscCompiler(legacyReferenceResolver) = let errorRanges = args |> Seq.exists errorRangesArg let vsErrors = args |> Seq.exists vsErrorsArg - let (ok, result) = compiler.Compile(args) + let ok, result = compiler.Compile(args) let exitCode = if ok then 0 else 1 let lines = @@ -180,9 +180,9 @@ module internal CompilerHelpers = let parseCommandLine (commandLine : string) = let folder (inQuote : bool, currArg : string, argLst : string list) ch = match (ch, inQuote) with - | ('"', _) -> + | '"', _ -> (not inQuote, currArg, argLst) - | (' ', false) -> + | ' ', false -> if currArg.Length > 0 then (inQuote, "", currArg :: argLst) else (inQuote, "", argLst) | _ -> @@ -206,7 +206,7 @@ module internal CompilerHelpers = try try Directory.SetCurrentDirectory directory - let (exitCode, output) = FscCompiler(legacyReferenceResolver).Compile(args) + let exitCode, output = FscCompiler(legacyReferenceResolver).Compile(args) let consoleOut = sw.ToString().Split([|'\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries) let consoleError = ew.ToString().Split([|'\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries) exitCode, [| yield! consoleOut; yield! output |], consoleError diff --git a/src/fsharp/LegacyMSBuildReferenceResolver.fs b/src/fsharp/LegacyMSBuildReferenceResolver.fs index a07941509ff..4f244ca7977 100644 --- a/src/fsharp/LegacyMSBuildReferenceResolver.fs +++ b/src/fsharp/LegacyMSBuildReferenceResolver.fs @@ -1,25 +1,18 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module LegacyMSBuildReferenceResolver +module FSharp.Compiler.CodeAnalysis.LegacyMSBuildReferenceResolver open System open System.IO open System.Reflection - -#if FX_RESHAPED_MSBUILD - open FSharp.Compiler.MsBuildAdapters - open FSharp.Compiler.ToolLocationHelper -#endif - - open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler.ReferenceResolver + open Internal.Utilities.Library open Microsoft.Build.Tasks open Microsoft.Build.Utilities open Microsoft.Build.Framework - open FSharp.Compiler + open FSharp.Compiler.IO // Reflection wrapper for properties - type System.Object with + type Object with member this.GetPropertyValue(propName) = this.GetType().GetProperty(propName, BindingFlags.Public).GetValue(this, null) @@ -33,13 +26,11 @@ module LegacyMSBuildReferenceResolver | s -> s PF + @"\Reference Assemblies\Microsoft\Framework\.NETFramework" - /// When targeting .NET 2.0-3.5 on Windows, we expand the {WindowsFramework} and {ReferenceAssemblies} paths manually let internal ReplaceVariablesForLegacyFxOnWindows(dirs: string list) = let windowsFramework = Environment.GetEnvironmentVariable("windir")+ @"\Microsoft.NET\Framework" let referenceAssemblies = DotNetFrameworkReferenceAssembliesRootDirectory dirs |> List.map(fun d -> d.Replace("{WindowsFramework}",windowsFramework).Replace("{ReferenceAssemblies}",referenceAssemblies)) - // ATTENTION!: the following code needs to be updated every time we are switching to the new MSBuild version because new .NET framework version was released // 1. List of frameworks @@ -73,16 +64,18 @@ module LegacyMSBuildReferenceResolver [] let private Net472 = "v4.7.2" - let SupportedDesktopFrameworkVersions = [ Net472; Net471; Net47; Net462; Net461; Net46; Net452; Net451; Net45 ] + [] + let private Net48 = "v4.8" + + let SupportedDesktopFrameworkVersions = [ Net48; Net472; Net471; Net47; Net462; Net461; Net46; Net452; Net451; Net45 ] /// Get the path to the .NET Framework implementation assemblies by using ToolLocationHelper.GetPathToDotNetFramework /// This is only used to specify the "last resort" path for assembly resolution. - let GetPathToDotNetFrameworkImlpementationAssemblies(v) = + let GetPathToDotNetFrameworkImlpementationAssemblies v = let v = match v with | Net45 -> Some TargetDotNetFrameworkVersion.Version45 | Net451 -> Some TargetDotNetFrameworkVersion.Version451 -#if MSBUILD_AT_LEAST_15 | Net452 -> Some TargetDotNetFrameworkVersion.Version452 | Net46 -> Some TargetDotNetFrameworkVersion.Version46 | Net461 -> Some TargetDotNetFrameworkVersion.Version461 @@ -90,7 +83,7 @@ module LegacyMSBuildReferenceResolver | Net47 -> Some TargetDotNetFrameworkVersion.Version47 | Net471 -> Some TargetDotNetFrameworkVersion.Version471 | Net472 -> Some TargetDotNetFrameworkVersion.Version472 -#endif + | Net48 -> Some TargetDotNetFrameworkVersion.Version48 | _ -> assert false; None match v with | Some v -> @@ -99,7 +92,7 @@ module LegacyMSBuildReferenceResolver | x -> [x] | _ -> [] - let GetPathToDotNetFrameworkReferenceAssemblies(version) = + let GetPathToDotNetFrameworkReferenceAssemblies version = #if NETSTANDARD ignore version let r : string list = [] @@ -114,9 +107,8 @@ module LegacyMSBuildReferenceResolver let HighestInstalledRefAssembliesOrDotNETFramework () = let getHighestInstalledDotNETFramework () = try -// The Mono build still uses an ancient version of msbuild from around Dev 14 -#if MSBUILD_AT_LEAST_15 - if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version472)) <> null then Net472 + if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version48)) <> null then Net48 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version472)) <> null then Net472 elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version471)) <> null then Net471 elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version47)) <> null then Net47 elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version462)) <> null then Net462 @@ -125,32 +117,25 @@ module LegacyMSBuildReferenceResolver elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version46)) <> null then Net46 elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version452)) <> null then Net452 elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 -#else - if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 -#endif elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version45)) <> null then Net45 else Net45 // version is 4.5 assumed since this code is running. with _ -> Net45 -#if !FX_RESHAPED_MSBUILD // 1. First look to see if we can find the highest installed set of dotnet reference assemblies, if yes then select that framework // 2. Otherwise ask msbuild for the highestinstalled framework let checkFrameworkForReferenceAssemblies (dotNetVersion:string) = if not (String.IsNullOrEmpty(dotNetVersion)) then try let v = if dotNetVersion.StartsWith("v") then dotNetVersion.Substring(1) else dotNetVersion - let frameworkName = new System.Runtime.Versioning.FrameworkName(".NETFramework", new Version(v)) + let frameworkName = System.Runtime.Versioning.FrameworkName(".NETFramework", Version(v)) match ToolLocationHelper.GetPathToReferenceAssemblies(frameworkName) |> Seq.tryHead with - | Some p -> if Directory.Exists(p) then true else false + | Some p -> FileSystem.DirectoryExistsShim(p) | None -> false with _ -> false else false match SupportedDesktopFrameworkVersions |> Seq.tryFind(fun v -> checkFrameworkForReferenceAssemblies v) with | Some v -> v | None -> getHighestInstalledDotNETFramework() -#else - getHighestInstalledDotNETFramework() -#endif /// Derive the target framework directories. let DeriveTargetFrameworkDirectories (targetFrameworkVersion:string, logMessage) = @@ -239,7 +224,7 @@ module LegacyMSBuildReferenceResolver + lineIfExists fusionName /// Perform assembly resolution by instantiating the ResolveAssembly task directly from the MSBuild SDK. - let ResolveCore(resolutionEnvironment: ResolutionEnvironment, + let ResolveCore(resolutionEnvironment: LegacyResolutionEnvironment, references:(string*(*baggage*)string)[], targetFrameworkVersion: string, targetFrameworkDirectories: string list, @@ -248,8 +233,8 @@ module LegacyMSBuildReferenceResolver explicitIncludeDirs: string list, implicitIncludeDir: string, allowRawFileName: bool, - logMessage: (string -> unit), - logDiagnostic: (bool -> string -> string -> unit)) = + logMessage: string -> unit, + logDiagnostic: bool -> string -> string -> unit) = let frameworkRegistryBase, assemblyFoldersSuffix, assemblyFoldersConditions = "Software\Microsoft\.NetFramework", "AssemblyFoldersEx" , "" @@ -264,22 +249,15 @@ module LegacyMSBuildReferenceResolver let engine = { new IBuildEngine with - member __.BuildProjectFile(projectFileName, targetNames, globalProperties, targetOutputs) = true -#if FX_RESHAPED_MSBUILD - member __.LogCustomEvent(e) = protect (fun () -> logMessage ((e.GetPropertyValue("Message")) :?> string)) - member __.LogErrorEvent(e) = protect (fun () -> logDiagnostic true ((e.GetPropertyValue("Code")) :?> string) ((e.GetPropertyValue("Message")) :?> string)) - member __.LogMessageEvent(e) = protect (fun () -> logMessage ((e.GetPropertyValue("Message")) :?> string)) - member __.LogWarningEvent(e) = protect (fun () -> logDiagnostic false ((e.GetPropertyValue("Code")) :?> string) ((e.GetPropertyValue("Message")) :?> string)) -#else - member __.LogCustomEvent(e) = protect (fun () -> logMessage e.Message) - member __.LogErrorEvent(e) = protect (fun () -> logDiagnostic true e.Code e.Message) - member __.LogMessageEvent(e) = protect (fun () -> logMessage e.Message) - member __.LogWarningEvent(e) = protect (fun () -> logDiagnostic false e.Code e.Message) -#endif - member __.ColumnNumberOfTaskNode with get() = 1 - member __.LineNumberOfTaskNode with get() = 1 - member __.ContinueOnError with get() = true - member __.ProjectFileOfTaskNode with get() = "" } + member _.BuildProjectFile(projectFileName, targetNames, globalProperties, targetOutputs) = true + member _.LogCustomEvent(e) = protect (fun () -> logMessage e.Message) + member _.LogErrorEvent(e) = protect (fun () -> logDiagnostic true e.Code e.Message) + member _.LogMessageEvent(e) = protect (fun () -> logMessage e.Message) + member _.LogWarningEvent(e) = protect (fun () -> logDiagnostic false e.Code e.Message) + member _.ColumnNumberOfTaskNode with get() = 1 + member _.LineNumberOfTaskNode with get() = 1 + member _.ContinueOnError with get() = true + member _.ProjectFileOfTaskNode with get() = "" } // Derive the target framework directory if none was supplied. let targetFrameworkDirectories = @@ -300,9 +278,9 @@ module LegacyMSBuildReferenceResolver [| // When compiling scripts using fsc.exe, for some reason we have always historically put TargetFrameworkDirectory first // It is unclear why. This is the only place we look at the 'isdifference between ResolutionEnvironment.EditingOrCompilation and ResolutionEnvironment.EditingTime. match resolutionEnvironment with - | ResolutionEnvironment.EditingOrCompilation false -> yield "{TargetFrameworkDirectory}" - | ResolutionEnvironment.EditingOrCompilation true - | ResolutionEnvironment.CompilationAndEvaluation -> () + | LegacyResolutionEnvironment.EditingOrCompilation false -> yield "{TargetFrameworkDirectory}" + | LegacyResolutionEnvironment.EditingOrCompilation true + | LegacyResolutionEnvironment.CompilationAndEvaluation -> () // Quick-resolve straight to filename first if allowRawFileName then @@ -312,9 +290,9 @@ module LegacyMSBuildReferenceResolver yield implicitIncludeDir // Usually the project directory match resolutionEnvironment with - | ResolutionEnvironment.EditingOrCompilation true - | ResolutionEnvironment.CompilationAndEvaluation -> yield "{TargetFrameworkDirectory}" - | ResolutionEnvironment.EditingOrCompilation false -> () + | LegacyResolutionEnvironment.EditingOrCompilation true + | LegacyResolutionEnvironment.CompilationAndEvaluation -> yield "{TargetFrameworkDirectory}" + | LegacyResolutionEnvironment.EditingOrCompilation false -> () yield registry yield "{AssemblyFolders}" @@ -324,15 +302,10 @@ module LegacyMSBuildReferenceResolver |] let assemblies = -#if FX_RESHAPED_MSBUILD - ignore references - [||] -#else - [| for (referenceName,baggage) in references -> - let item = new Microsoft.Build.Utilities.TaskItem(referenceName) :> ITaskItem + [| for referenceName,baggage in references -> + let item = TaskItem(referenceName) :> ITaskItem item.SetMetadata("Baggage", baggage) item |] -#endif let rar = ResolveAssemblyReference(BuildEngine=engine, TargetFrameworkDirectories=targetFrameworkDirectories, FindRelatedFiles=false, FindDependencies=false, FindSatellites=false, @@ -344,7 +317,7 @@ module LegacyMSBuildReferenceResolver #if ENABLE_MONO_SUPPORT // The properties TargetedRuntimeVersion and CopyLocalDependenciesWhenParentReferenceInGac // are not available on Mono. So we only set them if available (to avoid a compile-time dependency). - if not FSharp.Compiler.AbstractIL.IL.runningOnMono then + if not runningOnMono then typeof.InvokeMember("TargetedRuntimeVersion",(BindingFlags.Instance ||| BindingFlags.SetProperty ||| BindingFlags.Public),null,rar,[| box targetedRuntimeVersionValue |]) |> ignore typeof.InvokeMember("CopyLocalDependenciesWhenParentReferenceInGac",(BindingFlags.Instance ||| BindingFlags.SetProperty ||| BindingFlags.Public),null,rar,[| box true |]) |> ignore #else @@ -355,7 +328,7 @@ module LegacyMSBuildReferenceResolver let succeeded = rar.Execute() if not succeeded then - raise ResolutionFailure + raise LegacyResolutionFailure let resolvedFiles = [| for p in rar.ResolvedFiles -> @@ -369,12 +342,12 @@ module LegacyMSBuildReferenceResolver resolvedFiles let getResolver () = - { new ReferenceResolver.Resolver with - member __.HighestInstalledNetFrameworkVersion() = HighestInstalledRefAssembliesOrDotNETFramework() - member __.DotNetFrameworkReferenceAssembliesRootDirectory = DotNetFrameworkReferenceAssembliesRootDirectory + { new ILegacyReferenceResolver with + member _.HighestInstalledNetFrameworkVersion() = HighestInstalledRefAssembliesOrDotNETFramework() + member _.DotNetFrameworkReferenceAssembliesRootDirectory = DotNetFrameworkReferenceAssembliesRootDirectory /// Perform the resolution on rooted and unrooted paths, and then combine the results. - member __.Resolve(resolutionEnvironment, references, targetFrameworkVersion, targetFrameworkDirectories, targetProcessorArchitecture, + member _.Resolve(resolutionEnvironment, references, targetFrameworkVersion, targetFrameworkDirectories, targetProcessorArchitecture, fsharpCoreDir, explicitIncludeDirs, implicitIncludeDir, logMessage, logDiagnostic) = // The {RawFileName} target is 'dangerous', in the sense that is uses Directory.GetCurrentDirectory() to resolve unrooted file paths. @@ -383,7 +356,7 @@ module LegacyMSBuildReferenceResolver // unrooted may still find 'local' assemblies by virtue of the fact that "implicitIncludeDir" is one of the places searched during // assembly resolution. let references = - [| for ((file,baggage) as data) in references -> + [| for file,baggage as data in references -> // However, MSBuild will not resolve 'relative' paths, even when e.g. implicitIncludeDir is part of the search. As a result, // if we have an unrooted path+filename, we'll assume this is relative to the project directory and root it. if FileSystem.IsPathRootedShim(file) then @@ -414,3 +387,4 @@ module LegacyMSBuildReferenceResolver // now unify the two sets of results Array.concat [| rootedResults; unrootedResults |] } + |> LegacyReferenceResolver diff --git a/src/fsharp/LegacyMSBuildReferenceResolver.fsi b/src/fsharp/LegacyMSBuildReferenceResolver.fsi index 1b4aa72858d..a3d17795009 100644 --- a/src/fsharp/LegacyMSBuildReferenceResolver.fsi +++ b/src/fsharp/LegacyMSBuildReferenceResolver.fsi @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module LegacyMSBuildReferenceResolver -open FSharp.Compiler +[] +module public FSharp.Compiler.CodeAnalysis.LegacyMSBuildReferenceResolver -val getResolver: unit -> ReferenceResolver.Resolver \ No newline at end of file +val getResolver: unit -> LegacyReferenceResolver \ No newline at end of file diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index 470b54709b8..6084c450f26 100644 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -4,24 +4,27 @@ /// Implements the offside rule and a couple of other lexical transformations. module internal FSharp.Compiler.LexFilter +open System.Collections.Generic open Internal.Utilities.Text.Lexing open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features -open FSharp.Compiler.Parser open FSharp.Compiler.Lexhelp +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Parser + let debug = false let stringOfPos (p: Position) = sprintf "(%d:%d)" p.OriginalLine p.Column + let outputPos os (p: Position) = Printf.fprintf os "(%d:%d)" p.OriginalLine p.Column /// Used for warning strings, which should display columns as 1-based and display /// the lines after taking '# line' directives into account (i.e. do not use /// p.OriginalLine) -let warningStringOfPos (p: Position) = sprintf "(%d:%d)" p.Line (p.Column + 1) +let warningStringOfPosition (p: Position) = warningStringOfCoords p.Line p.Column type Context = // Position is position of keyword. @@ -45,7 +48,7 @@ type Context = | CtxtTypeDefns of Position // 'type =', not removed when we find the "=" | CtxtNamespaceHead of Position * token - | CtxtModuleHead of Position * token + | CtxtModuleHead of Position * token * LexingModuleAttributes | CtxtMemberHead of Position | CtxtMemberBody of Position // If bool is true then this is "whole file" @@ -55,7 +58,7 @@ type Context = | CtxtModuleBody of Position * bool | CtxtNamespaceBody of Position | CtxtException of Position - | CtxtParen of Parser.token * Position + | CtxtParen of token * Position // Position is position of following token | CtxtSeqBlock of FirstInSequence * Position * AddBlockEnd // first bool indicates "was this 'with' followed immediately by a '|'"? @@ -63,7 +66,7 @@ type Context = member c.StartPos = match c with - | CtxtNamespaceHead (p, _) | CtxtModuleHead (p, _) | CtxtException p | CtxtModuleBody (p, _) | CtxtNamespaceBody p + | CtxtNamespaceHead (p, _) | CtxtModuleHead (p, _, _) | CtxtException p | CtxtModuleBody (p, _) | CtxtNamespaceBody p | CtxtLetDecl (_, p) | CtxtDo p | CtxtInterfaceHead p | CtxtTypeDefns p | CtxtParen (_, p) | CtxtMemberHead p | CtxtMemberBody p | CtxtWithAsLet p | CtxtWithAsAugment p @@ -85,7 +88,7 @@ type Context = | CtxtDo _ -> "do" | CtxtInterfaceHead _ -> "interface-decl" | CtxtTypeDefns _ -> "type" - | CtxtParen _ -> "paren" + | CtxtParen(_, p) -> sprintf "paren(%s)" (stringOfPos p) | CtxtMemberHead _ -> "member-head" | CtxtMemberBody _ -> "body" | CtxtSeqBlock (b, p, _addBlockEnd) -> sprintf "seqblock(%s, %s)" (match b with FirstInSeqBlock -> "first" | NotFirstInSeqBlock -> "subsequent") (stringOfPos p) @@ -106,6 +109,7 @@ type Context = and AddBlockEnd = AddBlockEnd | NoAddBlockEnd | AddOneSidedBlockEnd and FirstInSequence = FirstInSeqBlock | NotFirstInSeqBlock +and LexingModuleAttributes = LexingModuleAttributes | NotLexingModuleAttributes let isInfix token = @@ -175,7 +179,23 @@ let infixTokenLength token = | INFIX_STAR_STAR_OP d -> d.Length | COLON_QMARK_GREATER -> 3 | _ -> assert false; 1 - + +/// Matches against a left-parenthesis-like token that is valid in expressions. +// +// LBRACK_LESS and GREATER_RBRACK are not here because adding them in these active patterns +// causes more offside warnings, while removing them doesn't add offside warnings in attributes. +let (|TokenLExprParen|_|) tok = + match tok with + | BEGIN | LPAREN | LBRACE _ | LBRACE_BAR | LBRACK | LBRACK_BAR | LQUOTE _ | LESS true + -> Some () + | _ -> None + +/// Matches against a right-parenthesis-like token that is valid in expressions. +let (|TokenRExprParen|_|) tok = + match tok with + | END | RPAREN | RBRACE _ | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ | GREATER true + -> Some () + | _ -> None /// Determine the tokens that may align with the 'if' of an 'if/then/elif/else' without closing /// the construct @@ -197,7 +217,21 @@ let rec isIfBlockContinuator token = | ODUMMY token -> isIfBlockContinuator token | _ -> false -/// Determine the token that may align with the 'try' of a 'try/catch' or 'try/finally' without closing +/// Given LanguageFeature.RelaxWhitespace2, +/// Determine the token that may align with the 'match' of a 'match/with' without closing +/// the construct +let rec isMatchBlockContinuator token = + match token with + // These tokens may align with the "match" without closing the construct, e.g. + // match ... + // with ... + | WITH -> true + // The following arise during reprocessing of the inserted tokens when we hit a DONE + | ORIGHT_BLOCK_END | OBLOCKEND | ODECLEND -> true + | ODUMMY token -> isMatchBlockContinuator token + | _ -> false + +/// Determine the token that may align with the 'try' of a 'try/with' or 'try/finally' without closing /// the construct let rec isTryBlockContinuator token = match token with @@ -247,7 +281,7 @@ let rec isNamespaceContinuator token = // ... // namespace <-- here // .... - | Parser.EOF _ | NAMESPACE -> false + | EOF _ | NAMESPACE -> false | ODUMMY token -> isNamespaceContinuator token | _ -> true // anything else is a namespace continuator @@ -270,7 +304,7 @@ let rec isTypeContinuator token = // end with <--- 'end' HERE // static member M() = 1 // end - | RBRACE | WITH | BAR | AND | END -> true + | RBRACE _ | WITH | BAR | AND | END -> true // The following arise during reprocessing of the inserted tokens when we hit a DONE | ORIGHT_BLOCK_END | OBLOCKEND | ODECLEND -> true @@ -339,7 +373,7 @@ let rec isSeqBlockElementContinuator token = // ... // ), <------- NOTE RPAREN HERE // Shortcut.CtrlO) - | END | AND | WITH | THEN | RPAREN | RBRACE | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ -> true + | END | AND | WITH | THEN | RPAREN | RBRACE _ | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ -> true // The following arise during reprocessing of the inserted tokens when we hit a DONE | ORIGHT_BLOCK_END | OBLOCKEND | ODECLEND -> true @@ -367,7 +401,7 @@ let isAtomicExprEndToken token = | UINT8 _ | UINT16 _ | UINT32 _ | UINT64 _ | UNATIVEINT _ | DECIMAL _ | BIGNUM _ | STRING _ | BYTEARRAY _ | CHAR _ | IEEE32 _ | IEEE64 _ - | RPAREN | RBRACK | RBRACE | BAR_RBRACE | BAR_RBRACK | END + | RPAREN | RBRACK | RBRACE _ | BAR_RBRACE | BAR_RBRACK | END | NULL | FALSE | TRUE | UNDERSCORE -> true | _ -> false @@ -376,18 +410,22 @@ let isAtomicExprEndToken token = //-------------------------------------------------------------------------- let parenTokensBalance t1 t2 = match t1, t2 with - | (LPAREN, RPAREN) - | (LBRACE, RBRACE) - | (LBRACE_BAR, BAR_RBRACE) - | (LBRACK, RBRACK) - | (INTERFACE, END) - | (CLASS, END) - | (SIG, END) - | (STRUCT, END) - | (LBRACK_BAR, BAR_RBRACK) - | (LESS true, GREATER true) - | (BEGIN, END) -> true - | (LQUOTE q1, RQUOTE q2) when q1 = q2 -> true + | LPAREN, RPAREN + | LBRACE _, RBRACE _ + | LBRACE_BAR, BAR_RBRACE + | LBRACK, RBRACK + | INTERFACE, END + | CLASS, END + | SIG, END + | STRUCT, END + | INTERP_STRING_BEGIN_PART _, INTERP_STRING_END _ + | INTERP_STRING_BEGIN_PART _, INTERP_STRING_PART _ + | INTERP_STRING_PART _, INTERP_STRING_PART _ + | INTERP_STRING_PART _, INTERP_STRING_END _ + | LBRACK_BAR, BAR_RBRACK + | LESS true, GREATER true + | BEGIN, END -> true + | LQUOTE q1, RQUOTE q2 when q1 = q2 -> true | _ -> false /// Used to save some aspects of the lexbuffer state @@ -422,12 +460,18 @@ type TokenTupPool() = [] let maxSize = 100 - let stack = System.Collections.Generic.Stack(Array.init maxSize (fun _ -> TokenTup(Unchecked.defaultof<_>, Unchecked.defaultof<_>, Unchecked.defaultof<_>))) + let mutable currentPoolSize = 0 + let stack = Stack(10) - member _.Rent() = + member this.Rent() = if stack.Count = 0 then - assert false - TokenTup(Unchecked.defaultof<_>, Unchecked.defaultof<_>, Unchecked.defaultof<_>) + if currentPoolSize < maxSize then + stack.Push(TokenTup(Unchecked.defaultof<_>, Unchecked.defaultof<_>, Unchecked.defaultof<_>)) + currentPoolSize <- currentPoolSize + 1 + this.Rent() + else + assert false + TokenTup(Unchecked.defaultof<_>, Unchecked.defaultof<_>, Unchecked.defaultof<_>) else stack.Pop() @@ -472,7 +516,7 @@ let (|TyparsCloseOp|_|) (txt: string) = if List.isEmpty angles then None else let afterOp = - match (new System.String(Array.ofSeq afterAngles)) with + match (System.String(Array.ofSeq afterAngles)) with | "." -> Some DOT | "]" -> Some RBRACK | "-" -> Some MINUS @@ -493,24 +537,24 @@ let (|TyparsCloseOp|_|) (txt: string) = | "" -> None | s -> match List.ofSeq afterAngles with - | ('=' :: _) - | ('!' :: '=' :: _) - | ('<' :: _) - | ('>' :: _) - | ('$' :: _) -> Some (INFIX_COMPARE_OP s) - | ('&' :: _) -> Some (INFIX_AMP_OP s) - | ('|' :: _) -> Some (INFIX_BAR_OP s) - | ('!' :: _) - | ('?' :: _) - | ('~' :: _) -> Some (PREFIX_OP s) - | ('@' :: _) - | ('^' :: _) -> Some (INFIX_AT_HAT_OP s) - | ('+' :: _) - | ('-' :: _) -> Some (PLUS_MINUS_OP s) - | ('*' :: '*' :: _) -> Some (INFIX_STAR_STAR_OP s) - | ('*' :: _) - | ('/' :: _) - | ('%' :: _) -> Some (INFIX_STAR_DIV_MOD_OP s) + | '=' :: _ + | '!' :: '=' :: _ + | '<' :: _ + | '>' :: _ + | '$' :: _ -> Some (INFIX_COMPARE_OP s) + | '&' :: _ -> Some (INFIX_AMP_OP s) + | '|' :: _ -> Some (INFIX_BAR_OP s) + | '!' :: _ + | '?' :: _ + | '~' :: _ -> Some (PREFIX_OP s) + | '@' :: _ + | '^' :: _ -> Some (INFIX_AT_HAT_OP s) + | '+' :: _ + | '-' :: _ -> Some (PLUS_MINUS_OP s) + | '*' :: '*' :: _ -> Some (INFIX_STAR_STAR_OP s) + | '*' :: _ + | '/' :: _ + | '%' :: _ -> Some (INFIX_STAR_DIV_MOD_OP s) | _ -> None Some([| for _c in angles do yield GREATER |], afterOp) @@ -523,7 +567,7 @@ type PositionWithColumn = //---------------------------------------------------------------------------- // build a LexFilter //--------------------------------------------------------------------------*) -type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbuf: UnicodeLexing.Lexbuf) = +type LexFilterImpl (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbuf: UnicodeLexing.Lexbuf) = //---------------------------------------------------------------------------- // Part I. Building a new lex stream from an old @@ -551,21 +595,28 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Make sure we don't report 'eof' when inserting a token, and set the positions to the // last reported token position let lexbufStateForInsertedDummyTokens (lastTokenStartPos, lastTokenEndPos) = - new LexbufState(lastTokenStartPos, lastTokenEndPos, false) + LexbufState(lastTokenStartPos, lastTokenEndPos, false) let getLexbufState() = - new LexbufState(lexbuf.StartPos, lexbuf.EndPos, lexbuf.IsPastEndOfStream) + LexbufState(lexbuf.StartPos, lexbuf.EndPos, lexbuf.IsPastEndOfStream) let setLexbufState (p: LexbufState) = lexbuf.StartPos <- p.StartPos lexbuf.EndPos <- p.EndPos lexbuf.IsPastEndOfStream <- p.PastEOF + let posOfTokenTup (tokenTup: TokenTup) = + match tokenTup.Token with + // EOF token is processed as if on column -1 + // This forces the closure of all contexts. + | EOF _ -> tokenTup.LexbufState.StartPos.ColumnMinusOne, tokenTup.LexbufState.EndPos.ColumnMinusOne + | _ -> tokenTup.LexbufState.StartPos, tokenTup.LexbufState.EndPos + let startPosOfTokenTup (tokenTup: TokenTup) = match tokenTup.Token with // EOF token is processed as if on column -1 // This forces the closure of all contexts. - | Parser.EOF _ -> tokenTup.LexbufState.StartPos.ColumnMinusOne + | EOF _ -> tokenTup.LexbufState.StartPos.ColumnMinusOne | _ -> tokenTup.LexbufState.StartPos //---------------------------------------------------------------------------- @@ -603,7 +654,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Fetch a raw token, either from the old lexer or from our delayedStack //-------------------------------------------------------------------------- - let delayedStack = System.Collections.Generic.Stack() + let delayedStack = Stack() let mutable tokensThatNeedNoProcessingCount = 0 let delayToken tokenTup = delayedStack.Push tokenTup @@ -640,7 +691,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, initialLookaheadTokenTup let warn (s: TokenTup) msg = - warning(Lexhelp.IndentationProblem(msg, mkSynRange (startPosOfTokenTup s) s.LexbufState.EndPos)) + warning(IndentationProblem(msg, mkSynRange (startPosOfTokenTup s) s.LexbufState.EndPos)) // 'query { join x in ys ... }' // 'query { ... @@ -650,11 +701,11 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let detectJoinInCtxt stack = let rec check s = match s with - | CtxtParen(LBRACE, _) :: _ -> true + | CtxtParen(LBRACE _, _) :: _ -> true | (CtxtSeqBlock _ | CtxtDo _ | CtxtFor _) :: rest -> check rest | _ -> false match stack with - | (CtxtVanilla _ :: rest) -> check rest + | CtxtVanilla _ :: rest -> check rest | _ -> false //---------------------------------------------------------------------------- @@ -663,6 +714,10 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // // Undentation rules //-------------------------------------------------------------------------- + + let relaxWhitespace2 = lexbuf.SupportsFeature LanguageFeature.RelaxWhitespace2 + + //let indexerNotationWithoutDot = lexbuf.SupportsFeature LanguageFeature.IndexerNotationWithoutDot let pushCtxt tokenTup (newCtxt: Context) = let rec undentationLimit strict stack = @@ -670,14 +725,28 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | _, [] -> PositionWithColumn(newCtxt.StartPos, -1) // ignore Vanilla because a SeqBlock is always coming - | _, (CtxtVanilla _ :: rest) -> undentationLimit strict rest + | _, CtxtVanilla _ :: rest -> undentationLimit strict rest - | _, (CtxtSeqBlock _ :: rest) when not strict -> undentationLimit strict rest - | _, (CtxtParen _ :: rest) when not strict -> undentationLimit strict rest + | _, CtxtSeqBlock _ :: rest when not strict -> undentationLimit strict rest + | _, CtxtParen _ :: rest when not strict -> undentationLimit strict rest // 'begin match' limited by minimum of two // '(match' limited by minimum of two - | _, (((CtxtMatch _) as ctxt1) :: CtxtSeqBlock _ :: (CtxtParen ((BEGIN | LPAREN), _) as ctxt2) :: _rest) + | _, (CtxtMatch _ as ctxt1) :: CtxtSeqBlock _ :: (CtxtParen ((BEGIN | LPAREN), _) as ctxt2) :: _ + -> if ctxt1.StartCol <= ctxt2.StartCol + then PositionWithColumn(ctxt1.StartPos, ctxt1.StartCol) + else PositionWithColumn(ctxt2.StartPos, ctxt2.StartCol) + // Insert this rule to allow + // begin match 1 with + // | 1 -> () + // | 2 -> + // f() // <- No offside warning here + // end + // when relaxWhitespace2 + // Otherwise the rule of 'match ... with' limited by 'match' (given RelaxWhitespace2) + // will consider the CtxtMatch as the limiting context instead of allowing undentation until the parenthesis + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2_AllowedBefore11 + | _, (CtxtMatchClauses _ as ctxt1) :: (CtxtMatch _) :: CtxtSeqBlock _ :: (CtxtParen ((BEGIN | LPAREN), _) as ctxt2) :: _ when relaxWhitespace2 -> if ctxt1.StartCol <= ctxt2.StartCol then PositionWithColumn(ctxt1.StartPos, ctxt1.StartCol) else PositionWithColumn(ctxt2.StartPos, ctxt2.StartCol) @@ -688,27 +757,49 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // let f x = function // | Case1 -> ... // | Case2 -> ... - | (CtxtMatchClauses _), (CtxtFunction _ :: CtxtSeqBlock _ :: (CtxtLetDecl _ as limitCtxt) :: _rest) + | CtxtMatchClauses _, CtxtFunction _ :: CtxtSeqBlock _ :: (CtxtLetDecl _ as limitCtxt) :: _rest -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) // Otherwise 'function ...' places no limit until we hit a CtxtLetDecl etc... (Recursive) - | (CtxtMatchClauses _), (CtxtFunction _ :: rest) + | CtxtMatchClauses _, CtxtFunction _ :: rest -> undentationLimit false rest // 'try ... with' limited by 'try' | _, (CtxtMatchClauses _ :: (CtxtTry _ as limitCtxt) :: _rest) -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) + // 'match ... with' limited by 'match' (given RelaxWhitespace2) + | _, (CtxtMatchClauses _ :: (CtxtMatch _ as limitCtxt) :: _rest) when relaxWhitespace2 + -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) + // 'fun ->' places no limit until we hit a CtxtLetDecl etc... (Recursive) - | _, (CtxtFun _ :: rest) + | _, CtxtFun _ :: rest + -> undentationLimit false rest + + // 'let ... = f ... begin' limited by 'let' (given RelaxWhitespace2) + // 'let (' (pattern match) limited by 'let' (given RelaxWhitespace2) + // 'let [' (pattern match) limited by 'let' (given RelaxWhitespace2) + // 'let {' (pattern match) limited by 'let' (given RelaxWhitespace2) + // 'let [|' (pattern match) limited by 'let' (given RelaxWhitespace2) + // 'let x : {|' limited by 'let' (given RelaxWhitespace2) + // 'let x : Foo<' limited by 'let' (given RelaxWhitespace2) + // 'let (ActivePattern <@' limited by 'let' (given RelaxWhitespace2) + // 'let (ActivePattern <@@' limited by 'let' (given RelaxWhitespace2) + // Same for 'match', 'if', 'then', 'else', 'for', 'while', 'member', 'when', and everything: No need to specify rules like the 'then' and 'else's below over and over again + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2 + | _, CtxtParen (TokenLExprParen, _) :: rest + // 'let x = { y =' limited by 'let' (given RelaxWhitespace2) etc. + // 'let x = {| y =' limited by 'let' (given RelaxWhitespace2) etc. + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2 + | _, CtxtSeqBlock _ :: CtxtParen (TokenLExprParen, _) :: rest when relaxWhitespace2 -> undentationLimit false rest // 'f ...{' places no limit until we hit a CtxtLetDecl etc... // 'f ...[' places no limit until we hit a CtxtLetDecl etc... // 'f ...[|' places no limit until we hit a CtxtLetDecl etc... - | _, (CtxtParen ((LBRACE | LBRACK | LBRACK_BAR), _) :: CtxtSeqBlock _ :: rest) - | _, (CtxtParen ((LBRACE | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: CtxtSeqBlock _ :: rest) - | _, (CtxtSeqBlock _ :: CtxtParen((LBRACE | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: CtxtSeqBlock _ :: rest) + | _, CtxtParen ((LBRACE _ | LBRACK | LBRACK_BAR), _) :: CtxtSeqBlock _ :: rest + | _, CtxtParen ((LBRACE _ | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: CtxtSeqBlock _ :: rest + | _, CtxtSeqBlock _ :: CtxtParen((LBRACE _ | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: CtxtSeqBlock _ :: rest -> undentationLimit false rest // MAJOR PERMITTED UNDENTATION This is allowing: @@ -717,7 +808,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // x + x // This is a serious thing to allow, but is required since there is no "return" in this language. // Without it there is no way of escaping special cases in large bits of code without indenting the main case. - | CtxtSeqBlock _, (CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _rest) + | CtxtSeqBlock _, CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _rest -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) // Permitted inner-construct precise block alignment: @@ -728,7 +819,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // type ... // with ... // end - | CtxtWithAsAugment _, ((CtxtInterfaceHead _ | CtxtMemberHead _ | CtxtException _ | CtxtTypeDefns _) as limitCtxt :: _rest) + | CtxtWithAsAugment _, (CtxtInterfaceHead _ | CtxtMemberHead _ | CtxtException _ | CtxtTypeDefns _ as limitCtxt :: _rest) -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) // Permit undentation via parentheses (or begin/end) following a 'then', 'else' or 'do': @@ -753,7 +844,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // ... <-- this is before the "with" // end - | _, ((CtxtWithAsAugment _ | CtxtThen _ | CtxtElse _ | CtxtDo _ ) :: rest) + | _, (CtxtWithAsAugment _ | CtxtThen _ | CtxtElse _ | CtxtDo _ ) :: rest -> undentationLimit false rest @@ -771,7 +862,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // let fffffff() = function 1 -> // 0 // | 2 -> ... <---- not allowed - | _, (CtxtFunction _ :: rest) + | _, CtxtFunction _ :: rest -> undentationLimit false rest // 'module ... : sig' limited by 'module' @@ -785,35 +876,35 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // 'if ... else {' limited by 'if' // 'if ... else [' limited by 'if' // 'if ... else [|' limited by 'if' - | _, (CtxtParen ((SIG | STRUCT | BEGIN), _) :: CtxtSeqBlock _ :: (CtxtModuleBody (_, false) as limitCtxt) :: _) - | _, (CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR), _) :: CtxtSeqBlock _ :: CtxtThen _ :: (CtxtIf _ as limitCtxt) :: _) - | _, (CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR | LBRACK_LESS), _) :: CtxtSeqBlock _ :: CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _) + | _, CtxtParen ((SIG | STRUCT | BEGIN), _) :: CtxtSeqBlock _ :: (CtxtModuleBody (_, false) as limitCtxt) :: _ + | _, CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE _ | LBRACE_BAR | LBRACK_BAR), _) :: CtxtSeqBlock _ :: CtxtThen _ :: (CtxtIf _ as limitCtxt) :: _ + | _, CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE _ | LBRACE_BAR | LBRACK_BAR | LBRACK_LESS), _) :: CtxtSeqBlock _ :: CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _ // 'f ... (' in seqblock limited by 'f' // 'f ... {' in seqblock limited by 'f' NOTE: this is covered by the more generous case above // 'f ... [' in seqblock limited by 'f' // 'f ... [|' in seqblock limited by 'f' // 'f ... Foo<' in seqblock limited by 'f' - | _, (CtxtParen ((BEGIN | LPAREN | LESS true | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: (CtxtSeqBlock _ as limitCtxt) :: _) + | _, CtxtParen ((BEGIN | LPAREN | LESS true | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: (CtxtSeqBlock _ as limitCtxt) :: _ // 'type C = class ... ' limited by 'type' // 'type C = interface ... ' limited by 'type' // 'type C = struct ... ' limited by 'type' - | _, (CtxtParen ((CLASS | STRUCT | INTERFACE), _) :: CtxtSeqBlock _ :: (CtxtTypeDefns _ as limitCtxt) :: _) + | _, CtxtParen ((CLASS | STRUCT | INTERFACE), _) :: CtxtSeqBlock _ :: (CtxtTypeDefns _ as limitCtxt) :: _ -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol + 1) // 'type C(' limited by 'type' - | _, (CtxtSeqBlock _ :: CtxtParen(LPAREN, _) :: (CtxtTypeDefns _ as limitCtxt) :: _ ) + | _, CtxtSeqBlock _ :: CtxtParen(LPAREN, _) :: (CtxtTypeDefns _ as limitCtxt) :: _ // 'static member C(' limited by 'static', likewise others - | _, (CtxtSeqBlock _ :: CtxtParen(LPAREN, _) :: (CtxtMemberHead _ as limitCtxt) :: _ ) + | _, CtxtSeqBlock _ :: CtxtParen(LPAREN, _) :: (CtxtMemberHead _ as limitCtxt) :: _ // 'static member P with get() = ' limited by 'static', likewise others - | _, (CtxtWithAsLet _ :: (CtxtMemberHead _ as limitCtxt) :: _ ) + | _, CtxtWithAsLet _ :: (CtxtMemberHead _ as limitCtxt) :: _ when lexbuf.SupportsFeature LanguageFeature.RelaxWhitespace -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol + 1) // REVIEW: document these - | _, (CtxtSeqBlock _ :: CtxtParen((BEGIN | LPAREN | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: (CtxtSeqBlock _ as limitCtxt) :: _) - | (CtxtSeqBlock _), (CtxtParen ((BEGIN | LPAREN | LBRACE | LBRACE_BAR | LBRACK | LBRACK_BAR), _) :: CtxtSeqBlock _ :: ((CtxtTypeDefns _ | CtxtLetDecl _ | CtxtMemberBody _ | CtxtWithAsLet _) as limitCtxt) :: _) + | _, CtxtSeqBlock _ :: CtxtParen((BEGIN | LPAREN | LBRACK | LBRACK_BAR), _) :: CtxtVanilla _ :: (CtxtSeqBlock _ as limitCtxt) :: _ + | CtxtSeqBlock _, CtxtParen ((BEGIN | LPAREN | LBRACE _ | LBRACE_BAR | LBRACK | LBRACK_BAR), _) :: CtxtSeqBlock _ :: (CtxtTypeDefns _ | CtxtLetDecl _ | CtxtMemberBody _ | CtxtWithAsLet _ as limitCtxt) :: _ -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol + 1) // Permitted inner-construct (e.g. "then" block and "else" block in overall @@ -829,22 +920,24 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // while ... // do expr // done - | (CtxtDo _), ((CtxtFor _ | CtxtWhile _) as limitCtxt) :: _rest + | CtxtDo _, (CtxtFor _ | CtxtWhile _ as limitCtxt) :: _rest -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) // These contexts all require indentation by at least one space - | _, ((CtxtInterfaceHead _ | CtxtNamespaceHead _ | CtxtModuleHead _ | CtxtException _ | CtxtModuleBody (_, false) | CtxtIf _ | CtxtWithAsLet _ | CtxtLetDecl _ | CtxtMemberHead _ | CtxtMemberBody _) as limitCtxt :: _) + | _, (CtxtInterfaceHead _ | CtxtNamespaceHead _ | CtxtModuleHead _ | CtxtException _ | CtxtModuleBody (_, false) | CtxtIf _ | CtxtWithAsLet _ | CtxtLetDecl _ | CtxtMemberHead _ | CtxtMemberBody _ as limitCtxt :: _) -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol + 1) // These contexts can have their contents exactly aligning - | _, ((CtxtParen _ | CtxtFor _ | CtxtWhen _ | CtxtWhile _ | CtxtTypeDefns _ | CtxtMatch _ | CtxtModuleBody (_, true) | CtxtNamespaceBody _ | CtxtTry _ | CtxtMatchClauses _ | CtxtSeqBlock _) as limitCtxt :: _) + | _, (CtxtParen _ | CtxtFor _ | CtxtWhen _ | CtxtWhile _ | CtxtTypeDefns _ | CtxtMatch _ | CtxtModuleBody (_, true) | CtxtNamespaceBody _ | CtxtTry _ | CtxtMatchClauses _ | CtxtSeqBlock _ as limitCtxt :: _) -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol) match newCtxt with // Don't bother to check pushes of Vanilla blocks since we've // always already pushed a SeqBlock at this position. - | CtxtVanilla _ -> () + | CtxtVanilla _ + // String interpolation inner expressions are not limited (e.g. multiline strings) + | CtxtParen((INTERP_STRING_BEGIN_PART _ | INTERP_STRING_PART _),_) -> () | _ -> let p1 = undentationLimit true offsideStack let c2 = newCtxt.StartCol @@ -852,9 +945,9 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, warn tokenTup (if debug then sprintf "possible incorrect indentation: this token is offside of context at position %s, newCtxt = %A, stack = %A, newCtxtPos = %s, c1 = %d, c2 = %d" - (warningStringOfPos p1.Position) newCtxt offsideStack (stringOfPos (newCtxt.StartPos)) p1.Column c2 + (warningStringOfPosition p1.Position) newCtxt offsideStack (stringOfPos newCtxt.StartPos) p1.Column c2 else - FSComp.SR.lexfltTokenIsOffsideOfContextStartedEarlier(warningStringOfPos p1.Position)) + FSComp.SR.lexfltTokenIsOffsideOfContextStartedEarlier(warningStringOfPosition p1.Position)) let newOffsideStack = newCtxt :: offsideStack if debug then dprintf "--> pushing, stack = %A\n" newOffsideStack offsideStack <- newOffsideStack @@ -889,13 +982,17 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let tokenEndPos = leftTokenTup.LexbufState.EndPos (tokenEndPos = lparenStartPos) - let nextTokenIsAdjacentLParenOrLBrack (tokenTup: TokenTup) = + let nextTokenIsAdjacentLBrack (tokenTup: TokenTup) = let lookaheadTokenTup = peekNextTokenTup() match lookaheadTokenTup.Token with - | (LPAREN | LBRACK) -> - if isAdjacent tokenTup lookaheadTokenTup then Some(lookaheadTokenTup.Token) else None - | _ -> - None + | LBRACK -> isAdjacent tokenTup lookaheadTokenTup + | _ -> false + + let nextTokenIsAdjacentLParen (tokenTup: TokenTup) = + let lookaheadTokenTup = peekNextTokenTup() + match lookaheadTokenTup.Token with + | LPAREN -> isAdjacent tokenTup lookaheadTokenTup + | _ -> false let nextTokenIsAdjacent firstTokenTup = let lookaheadTokenTup = peekNextTokenTup() @@ -914,9 +1011,9 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, stack <- (lookaheadTokenTup, true) :: stack let lookaheadTokenStartPos = startPosOfTokenTup lookaheadTokenTup match lookaheadToken with - | Parser.EOF _ | SEMICOLON_SEMICOLON -> false + | EOF _ | SEMICOLON_SEMICOLON -> false | _ when indentation && lookaheadTokenStartPos < tokenEndPos -> false - | (RPAREN | RBRACK) -> + | RPAREN | RBRACK -> let nParen = nParen - 1 if nParen > 0 then scanAhead nParen @@ -933,7 +1030,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // On successful parse of a set of type parameters, look for an adjacent (, e.g. // M(args) // and insert a HIGH_PRECEDENCE_PAREN_APP - if not hasAfterOp && (match nextTokenIsAdjacentLParenOrLBrack lookaheadTokenTup with Some LPAREN -> true | _ -> false) then + if not hasAfterOp && nextTokenIsAdjacentLParen lookaheadTokenTup then let dotTokenTup = peekNextTokenTup() stack <- (pool.UseLocation(dotTokenTup, HIGH_PRECEDENCE_PAREN_APP), false) :: stack true @@ -947,11 +1044,11 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // On successful parse of a set of type parameters, look for an adjacent (, e.g. // M>(args) // and insert a HIGH_PRECEDENCE_PAREN_APP - if afterOp.IsNone && (match nextTokenIsAdjacentLParenOrLBrack lookaheadTokenTup with Some LPAREN -> true | _ -> false) then + if afterOp.IsNone && nextTokenIsAdjacentLParen lookaheadTokenTup then let dotTokenTup = peekNextTokenTup() stack <- (pool.UseLocation(dotTokenTup, HIGH_PRECEDENCE_PAREN_APP), false) :: stack true - | (LPAREN | LESS _ | LBRACK | LBRACK_LESS | INFIX_COMPARE_OP " + | LPAREN | LESS _ | LBRACK | LBRACK_LESS | INFIX_COMPARE_OP " scanAhead (nParen+1) // These tokens CAN occur in non-parenthesized positions in the grammar of types or type parameter definitions @@ -1018,7 +1115,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | GREATER _ -> delayToken (pool.UseLocation(tokenTup, GREATER res)) pool.Return tokenTup - | (INFIX_COMPARE_OP (TyparsCloseOp(greaters, afterOp) as opstr)) -> + | INFIX_COMPARE_OP (TyparsCloseOp(greaters, afterOp) as opstr) -> match afterOp with | None -> () | Some tok -> delayToken (pool.UseShiftedLocation(tokenTup, tok, greaters.Length, 0)) @@ -1046,19 +1143,19 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let tokenBalancesHeadContext token stack = match token, stack with - | END, (CtxtWithAsAugment(_) :: _) - | (ELSE | ELIF), (CtxtIf _ :: _) - | DONE, (CtxtDo _ :: _) + | END, CtxtWithAsAugment _ :: _ + | (ELSE | ELIF), CtxtIf _ :: _ + | DONE, CtxtDo _ :: _ // WITH balances except in the following contexts.... Phew - an overused keyword! - | WITH, ( ((CtxtMatch _ | CtxtException _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtTry _ | CtxtTypeDefns _ | CtxtMemberBody _) :: _) + | WITH, ( (CtxtMatch _ | CtxtException _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtTry _ | CtxtTypeDefns _ | CtxtMemberBody _) :: _ // This is the nasty record/object-expression case - | (CtxtSeqBlock _ :: CtxtParen((LBRACE | LBRACE_BAR), _) :: _) ) - | FINALLY, (CtxtTry _ :: _) -> + | CtxtSeqBlock _ :: CtxtParen((LBRACE _ | LBRACE_BAR), _) :: _ ) + | FINALLY, CtxtTry _ :: _ -> true // for x in ienum ... // let x = ... in - | IN, ((CtxtFor _ | CtxtLetDecl _) :: _) -> + | IN, (CtxtFor _ | CtxtLetDecl _) :: _ -> true // 'query { join x in ys ... }' // 'query { ... @@ -1069,13 +1166,13 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, true // NOTE: ;; does not terminate a 'namespace' body. - | SEMICOLON_SEMICOLON, (CtxtSeqBlock _ :: CtxtNamespaceBody _ :: _) -> + | SEMICOLON_SEMICOLON, CtxtSeqBlock _ :: CtxtNamespaceBody _ :: _ -> true - | SEMICOLON_SEMICOLON, (CtxtSeqBlock _ :: CtxtModuleBody (_, true) :: _) -> + | SEMICOLON_SEMICOLON, CtxtSeqBlock _ :: CtxtModuleBody (_, true) :: _ -> true - | t2, (CtxtParen(t1, _) :: _) -> + | t2, CtxtParen(t1, _) :: _ -> parenTokensBalance t1 t2 | _ -> @@ -1088,7 +1185,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, //-------------------------------------------------------------------------- - let rec hwTokenFetch (useBlockRule) = + let rec hwTokenFetch useBlockRule = let tokenTup = popNextTokenTup() let tokenReplaced = rulesForBothSoftWhiteAndHardWhite tokenTup if tokenReplaced then hwTokenFetch useBlockRule else @@ -1100,12 +1197,12 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let isSameLine() = match token with - | Parser.EOF _ -> false + | EOF _ -> false | _ -> (startPosOfTokenTup (peekNextTokenTup())).OriginalLine = tokenStartPos.OriginalLine let isControlFlowOrNotSameLine() = match token with - | Parser.EOF _ -> false + | EOF _ -> false | _ -> not (isSameLine()) || (match peekNextToken() with TRY | MATCH | MATCH_BANG | IF | LET _ | FOR | WHILE -> true | _ -> false) @@ -1113,18 +1210,18 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Look for '=' or '.Id.id.id = ' after an identifier let rec isLongIdentEquals token = match token with - | Parser.GLOBAL - | Parser.IDENT _ -> + | GLOBAL + | IDENT _ -> let rec loop() = let tokenTup = popNextTokenTup() let res = match tokenTup.Token with - | Parser.EOF _ -> false + | EOF _ -> false | DOT -> let tokenTup = popNextTokenTup() let res = match tokenTup.Token with - | Parser.EOF _ -> false + | EOF _ -> false | IDENT _ -> loop() | _ -> false delayToken tokenTup @@ -1161,6 +1258,34 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, returnToken (lexbufStateForInsertedDummyTokens (startPosOfTokenTup tokenTup, tokenTup.LexbufState.EndPos)) tok let isSemiSemi = match token with SEMICOLON_SEMICOLON -> true | _ -> false + let relaxWhitespace2OffsideRule = + // Offside rule for CtxtLetDecl (in types or modules) / CtxtMemberHead / CtxtTypeDefns... (given RelaxWhitespace2) + // This should not be applied to contexts with optional closing tokens! (CtxtFun, CtxtFunction, CtxtDo, CtxtMemberBody, CtxtSeqBlock etc) + // let ( member Foo ( for x in ( while ( + // ... ... ... ... + // ) = ... ) = ... ) do ... ) do ... + // let [ member Foo [ for x in [ while f [ + // ... ... ... ... + // ] = ... ] = ... ] do ... ] do ... + // let { member Foo { for x in { while f { + // ... ... ... ... + // } = ... } = ... } do ... } do ... + // let [| member Foo [| for x in [| while f [| + // ... ... ... ... + // |] = ... |] = ... |] do ... |] do ... + // let x : {| member Foo : {| for x in f {| while f {| + // ... ... ... ... + // |} = ... |} = ... |} do ... |} do ... + // let x : Foo< member x : Foo< for x in foo< for x in foo< + // ... ... ... ... + // > = ... > = ... > = ... > = ... + // type Foo( + // ... + // ) = ... + // ODUMMY is a context closer token, after its context is closed + match token with + | ODUMMY TokenRExprParen -> relaxWhitespace2 + | _ -> false // If you see a 'member' keyword while you are inside the body of another member, then it usually means there is a syntax error inside this method // and the upcoming 'member' is the start of the next member in the class. For better parser recovery and diagnostics, it is best to pop out of the @@ -1176,7 +1301,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, false // no member currently on the stack, nothing to pop else // there is a member context - if List.exists (function CtxtParen(LBRACE, _) -> true | _ -> false) ctxtStack then + if List.exists (function CtxtParen(LBRACE _, _) -> true | _ -> false) ctxtStack then false // an LBRACE could mean an object expression, and object expressions can have 'member' tokens in them, so do not pop, to be safe elif List.count (function CtxtParen(LPAREN, _) -> true | _ -> false) ctxtStack >= 2 then false // static member constraints always are embedded in at least two LPARENS, so do not pop, to be safe @@ -1213,22 +1338,17 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let tokenForcesHeadContextClosure token stack = not (isNil stack) && match token with - | Parser.EOF _ -> true + | EOF _ -> true | SEMICOLON_SEMICOLON -> not (tokenBalancesHeadContext token stack) - | END + | TokenRExprParen | ELSE | ELIF | DONE | IN - | RPAREN - | GREATER true - | RBRACE - | BAR_RBRACE - | RBRACK - | BAR_RBRACK | WITH | FINALLY - | RQUOTE _ -> + | INTERP_STRING_PART _ + | INTERP_STRING_END _ -> not (tokenBalancesHeadContext token stack) && // Only close the context if some context is going to match at some point in the stack. // If none match, the token will go through, and error recovery will kick in in the parser and report the extra token, @@ -1241,7 +1361,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // a TYPE or MODULE. So the lexfilter helps out by looking ahead for these tokens and (1) closing expression contexts and (2) inserting extra 'coming soon' tokens // that the expression rules in the FsYacc parser can 'shift' to make progress parsing the incomplete expressions, without using the 'recover' action. let insertComingSoonTokens(keywordName, comingSoon, isHere) = - // compiling the source for FSharp.Core.dll uses crazy syntax like + // compiling the source for FSharp.Core.dll uses unconventional syntax like // (# "unbox.any !0" type ('T) x : 'T #) // where the type keyword is used inside an expression, so we must exempt FSharp.Core from some extra failed-parse-diagnostics-recovery-processing of the 'type' keyword let mutable effectsToDo = [] @@ -1254,7 +1374,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | _ :: (CtxtNamespaceBody _ | CtxtModuleBody _) :: _ -> true // The context pair below is created a namespace/module scope when user explicitly uses 'begin'...'end', // and these can legally contain type definitions, so ignore this combo as uninteresting and recurse deeper - | _ :: CtxtParen((BEGIN|STRUCT), _) :: CtxtSeqBlock(_, _, _) :: _ -> nextOuterMostInterestingContextIsNamespaceOrModule(offsideStack.Tail.Tail) + | _ :: CtxtParen((BEGIN|STRUCT), _) :: CtxtSeqBlock _ :: _ -> nextOuterMostInterestingContextIsNamespaceOrModule(offsideStack.Tail.Tail) // at the top of the stack there is an implicit module | _ :: [] -> true // anything else is a non-namespace/module @@ -1262,7 +1382,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, while not offsideStack.IsEmpty && (not(nextOuterMostInterestingContextIsNamespaceOrModule offsideStack)) && (match offsideStack.Head with // open-parens of sorts - | CtxtParen((LPAREN|LBRACK|LBRACE|LBRACE_BAR|LBRACK_BAR), _) -> true + | CtxtParen(TokenLExprParen, _) -> true // seq blocks | CtxtSeqBlock _ -> true // vanillas @@ -1313,7 +1433,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | _ when tokenForcesHeadContextClosure token offsideStack -> let ctxt = offsideStack.Head - if debug then dprintf "IN/ELSE/ELIF/DONE/RPAREN/RBRACE/END at %a terminates context at position %a\n" outputPos tokenStartPos outputPos ctxt.StartPos + if debug then dprintf "IN/ELSE/ELIF/DONE/RPAREN/RBRACE/END/INTERP at %a terminates context at position %a\n" outputPos tokenStartPos outputPos ctxt.StartPos popCtxt() match endTokenForACtxt ctxt with | Some tok -> @@ -1342,7 +1462,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Balancing rule. Encountering an 'in' balances with a 'let'. i.e. even a non-offside 'in' closes a 'let' // The 'IN' token is thrown away and becomes an ODECLEND - | IN, (CtxtLetDecl (blockLet, offsidePos) :: _) -> + | IN, CtxtLetDecl (blockLet, offsidePos) :: _ -> if debug then dprintf "IN at %a (becomes %s)\n" outputPos tokenStartPos (if blockLet then "ODECLEND" else "IN") if tokenStartCol < offsidePos.Column then warn tokenTup (FSComp.SR.lexfltIncorrentIndentationOfIn()) popCtxt() @@ -1352,7 +1472,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Balancing rule. Encountering a 'done' balances with a 'do'. i.e. even a non-offside 'done' closes a 'do' // The 'DONE' token is thrown away and becomes an ODECLEND - | DONE, (CtxtDo offsidePos :: _) -> + | DONE, CtxtDo offsidePos :: _ -> if debug then dprintf "DONE at %a terminates CtxtDo(offsidePos=%a)\n" outputPos tokenStartPos outputPos offsidePos popCtxt() // reprocess as the DONE may close a DO context @@ -1361,16 +1481,24 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, hwTokenFetch useBlockRule // Balancing rule. Encountering a ')' or '}' balances with a '(' or '{', even if not offside - | ((END | RPAREN | RBRACE | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ | GREATER true) as t2), (CtxtParen (t1, _) :: _) + | ((TokenRExprParen | INTERP_STRING_END _ | INTERP_STRING_PART _) as t2), (CtxtParen (t1, _) :: _) when parenTokensBalance t1 t2 -> if debug then dprintf "RPAREN/RBRACE/BAR_RBRACE/RBRACK/BAR_RBRACK/RQUOTE/END at %a terminates CtxtParen()\n" outputPos tokenStartPos popCtxt() - // Queue a dummy token at this position to check if any closing rules apply - delayToken(pool.UseLocation(tokenTup, ODUMMY token)) + match t2 with + // $".... { ... } ... { ....} " pushes a block context at second { + // ~~~~~~~~ + // ^---------INTERP_STRING_PART + | INTERP_STRING_PART _ -> + pushCtxt tokenTup (CtxtParen (token, tokenTup.LexbufState.EndPos)) + pushCtxtSeqBlock(false, NoAddBlockEnd) + | _ -> + // Queue a dummy token at this position to check if any closing rules apply + delayToken(pool.UseLocation(tokenTup, ODUMMY token)) returnToken tokenLexbufState token // Balancing rule. Encountering a 'end' can balance with a 'with' but only when not offside - | END, (CtxtWithAsAugment offsidePos :: _) + | END, CtxtWithAsAugment offsidePos :: _ when not (tokenStartCol + 1 <= offsidePos.Column) -> if debug then dprintf "END at %a terminates CtxtWithAsAugment()\n" outputPos tokenStartPos popCtxt() @@ -1379,7 +1507,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Transition rule. CtxtNamespaceHead ~~~> CtxtSeqBlock // Applied when a token other then a long identifier is seen - | _, (CtxtNamespaceHead (namespaceTokenPos, prevToken) :: _) -> + | _, CtxtNamespaceHead (namespaceTokenPos, prevToken) :: _ -> match prevToken, token with | (NAMESPACE | DOT | REC | GLOBAL), (REC | IDENT _ | GLOBAL) when namespaceTokenPos.Column < tokenStartPos.Column -> replaceCtxt tokenTup (CtxtNamespaceHead (namespaceTokenPos, token)) @@ -1392,7 +1520,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, popCtxt() // Don't push a new context if next token is EOF, since that raises an offside warning match tokenTup.Token with - | Parser.EOF _ -> + | EOF _ -> returnToken tokenLexbufState token | _ -> delayToken tokenTup @@ -1402,19 +1530,27 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Transition rule. CtxtModuleHead ~~~> push CtxtModuleBody; push CtxtSeqBlock // Applied when a ':' or '=' token is seen - // Otherwise it's a 'head' module declaration, so ignore it - | _, (CtxtModuleHead (moduleTokenPos, prevToken) :: _) -> - match prevToken, token with - | MODULE, GLOBAL when moduleTokenPos.Column < tokenStartPos.Column -> - replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token)) + // Otherwise it's a 'head' module declaration, so ignore it + + // Here prevToken is either 'module', 'rec', 'global' (invalid), '.', or ident, because we skip attribute tokens and access modifier tokens + | _, CtxtModuleHead (moduleTokenPos, prevToken, lexingModuleAttributes) :: _ -> + match prevToken, token with + | _, GREATER_RBRACK when lexingModuleAttributes = LexingModuleAttributes + && moduleTokenPos.Column < tokenStartPos.Column -> + replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, prevToken, NotLexingModuleAttributes)) returnToken tokenLexbufState token - | MODULE, (PUBLIC | PRIVATE | INTERNAL) when moduleTokenPos.Column < tokenStartPos.Column -> + | _ when lexingModuleAttributes = LexingModuleAttributes + && moduleTokenPos.Column < tokenStartPos.Column -> returnToken tokenLexbufState token - | (MODULE | DOT | REC), (REC | IDENT _) when moduleTokenPos.Column < tokenStartPos.Column -> - replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token)) + | MODULE, (PUBLIC | PRIVATE | INTERNAL) when moduleTokenPos.Column < tokenStartPos.Column -> returnToken tokenLexbufState token + | MODULE, GLOBAL + | (MODULE | REC | DOT), (REC | IDENT _) | IDENT _, DOT when moduleTokenPos.Column < tokenStartPos.Column -> - replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token)) + replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, token, NotLexingModuleAttributes)) + returnToken tokenLexbufState token + | MODULE, LBRACK_LESS when moduleTokenPos.Column < tokenStartPos.Column -> + replaceCtxt tokenTup (CtxtModuleHead (moduleTokenPos, prevToken, LexingModuleAttributes)) returnToken tokenLexbufState token | _, (EQUALS | COLON) -> if debug then dprintf "CtxtModuleHead: COLON/EQUALS, pushing CtxtModuleBody and CtxtSeqBlock\n" @@ -1427,19 +1563,19 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, popCtxt() // Don't push a new context if next token is EOF, since that raises an offside warning match tokenTup.Token with - | Parser.EOF _ -> + | EOF _ -> returnToken tokenLexbufState token - | _ -> + | _ -> + // We have reached other tokens without encountering '=' or ':', so this is a module declaration spanning the whole file delayToken tokenTup pushCtxt tokenTup (CtxtModuleBody (moduleTokenPos, true)) pushCtxtSeqBlockAt (tokenTup, true, AddBlockEnd) hwTokenFetch false - // Offside rule for SeqBlock. // f x // g x // ... - | _, (CtxtSeqBlock(_, offsidePos, addBlockEnd) :: rest) when + | _, CtxtSeqBlock(_, offsidePos, addBlockEnd) :: rest when // NOTE: ;; does not terminate a 'namespace' body. ((isSemiSemi && not (match rest with (CtxtNamespaceBody _ | CtxtModuleBody (_, true)) :: _ -> true | _ -> false)) || @@ -1449,7 +1585,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // type x = // A of string <-- note missing '|' here - bad style, and perhaps should be disallowed // | B of int - | BAR, (CtxtTypeDefns _ :: _) -> 2 + | BAR, CtxtTypeDefns _ :: _ -> 2 // This ensures we close a type context seq block when the '|' marks // of a type definition are aligned with the 'type' token. @@ -1459,7 +1595,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // | B // // <-- close the type context sequence block here *) - | _, (CtxtTypeDefns posType :: _) when offsidePos.Column = posType.Column && not (isTypeSeqBlockElementContinuator token) -> -1 + | _, CtxtTypeDefns posType :: _ when offsidePos.Column = posType.Column && not (isTypeSeqBlockElementContinuator token) -> -1 // This ensures we close a namespace body when we see the next namespace definition // @@ -1467,7 +1603,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // ... // // namespace <-- close the namespace body context here - | _, (CtxtNamespaceBody posNamespace :: _) when offsidePos.Column = posNamespace.Column && (match token with NAMESPACE -> true | _ -> false) -> -1 + | _, CtxtNamespaceBody posNamespace :: _ when offsidePos.Column = posNamespace.Column && (match token with NAMESPACE -> true | _ -> false) -> -1 | _ -> // Allow a grace of >2 column positions for infix tokens, permits @@ -1504,7 +1640,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // fff // eeeee // - | _, (CtxtVanilla(offsidePos, _) :: _) when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtVanilla(offsidePos, _) :: _ when isSemiSemi || tokenStartCol <= offsidePos.Column -> if debug then dprintf "offside token at column %d indicates end of CtxtVanilla started at %a!\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() @@ -1513,14 +1649,14 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // [< ... >] // decl - | _, (CtxtSeqBlock(NotFirstInSeqBlock, offsidePos, addBlockEnd) :: _) + | _, CtxtSeqBlock(NotFirstInSeqBlock, offsidePos, addBlockEnd) :: _ when (match token with GREATER_RBRACK -> true | _ -> false) -> // Attribute-end tokens mean CtxtSeqBlock rule is NOT applied to the next token replaceCtxt tokenTup (CtxtSeqBlock (FirstInSeqBlock, offsidePos, addBlockEnd)) reprocessWithoutBlockRule() // Offside rule for SeqBlock - avoiding inserting OBLOCKSEP on first item in block - | _, (CtxtSeqBlock (FirstInSeqBlock, offsidePos, addBlockEnd) :: _) when useBlockRule -> + | _, CtxtSeqBlock (FirstInSeqBlock, offsidePos, addBlockEnd) :: _ when useBlockRule -> // This is the first token in a block, or a token immediately // following an infix operator (see above). // Return the token, but only after processing any additional rules @@ -1548,11 +1684,11 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // let x3 = expr // ... // ~~> insert OBLOCKSEP - | _, (CtxtSeqBlock (NotFirstInSeqBlock, offsidePos, addBlockEnd) :: rest) + | _, CtxtSeqBlock (NotFirstInSeqBlock, offsidePos, addBlockEnd) :: rest when useBlockRule - && not (let isTypeCtxt = (match rest with | (CtxtTypeDefns _ :: _) -> true | _ -> false) + && not (let isTypeCtxt = (match rest with | CtxtTypeDefns _ :: _ -> true | _ -> false) // Don't insert 'OBLOCKSEP' between namespace declarations - let isNamespaceCtxt = (match rest with | (CtxtNamespaceBody _ :: _) -> true | _ -> false) + let isNamespaceCtxt = (match rest with | CtxtNamespaceBody _ :: _ -> true | _ -> false) if isNamespaceCtxt then (match token with NAMESPACE -> true | _ -> false) elif isTypeCtxt then isTypeSeqBlockElementContinuator token else isSeqBlockElementContinuator token) @@ -1575,14 +1711,18 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // let .... = // ... // <*> - | _, (CtxtLetDecl (true, offsidePos) :: _) when - isSemiSemi || (if isLetContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtLetDecl (true, offsidePos) :: _ when + isSemiSemi || (if relaxWhitespace2OffsideRule || isLetContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from LET(offsidePos=%a)! delaying token, returning ODECLEND\n" tokenStartCol outputPos offsidePos popCtxt() insertToken ODECLEND - - | _, (CtxtDo offsidePos :: _) - when isSemiSemi || (if isDoContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + + // do ignore ( + // 1 + // ), 2 // This is a 'unit * int', so for backwards compatibility, do not treat ')' as a continuator, don't apply relaxWhitespace2OffsideRule + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2_AllowedBefore9 + | _, CtxtDo offsidePos :: _ + when isSemiSemi || (if (*relaxWhitespace2OffsideRule ||*) isDoContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from DO(offsidePos=%a)! delaying token, returning ODECLEND\n" tokenStartCol outputPos offsidePos popCtxt() insertToken ODECLEND @@ -1592,14 +1732,14 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // ... // ... - | _, (CtxtInterfaceHead offsidePos :: _) - when isSemiSemi || (if isInterfaceContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtInterfaceHead offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isInterfaceContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from INTERFACE(offsidePos=%a)! pop and reprocess\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() - | _, (CtxtTypeDefns offsidePos :: _) - when isSemiSemi || (if isTypeContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtTypeDefns offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isTypeContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from TYPE(offsidePos=%a)! pop and reprocess\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() @@ -1611,89 +1751,102 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // module M = ... // ... // NOTE: ;; does not terminate a whole file module body. - | _, ((CtxtModuleBody (offsidePos, wholeFile)) :: _) when (isSemiSemi && not wholeFile) || tokenStartCol <= offsidePos.Column -> + | _, CtxtModuleBody (offsidePos, wholeFile) :: _ when (isSemiSemi && not wholeFile) || (if relaxWhitespace2OffsideRule then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from MODULE with offsidePos %a! delaying token\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() // NOTE: ;; does not terminate a 'namespace' body. - | _, ((CtxtNamespaceBody offsidePos) :: _) when (* isSemiSemi || *) (if isNamespaceContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtNamespaceBody offsidePos :: _ when (* isSemiSemi || *) (if relaxWhitespace2OffsideRule || isNamespaceContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from NAMESPACE with offsidePos %a! delaying token\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() - | _, ((CtxtException offsidePos) :: _) when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtException offsidePos :: _ when isSemiSemi || (if relaxWhitespace2OffsideRule then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from EXCEPTION with offsidePos %a! delaying token\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() - // Pop CtxtMemberBody when offside. Insert an ODECLEND to indicate the end of the member - | _, ((CtxtMemberBody offsidePos) :: _) when isSemiSemi || tokenStartCol <= offsidePos.Column -> + // Pop CtxtMemberBody when offside. Insert an ODECLEND to indicate the end of the member + // member _.d() = seq { + // 1 + // }; static member e() = [ + // 1 // This is not offside for backcompat, don't apply relaxWhitespace2OffsideRule + // ] + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2_AllowedBefore9 + | _, CtxtMemberBody offsidePos :: _ when isSemiSemi || (if (*relaxWhitespace2OffsideRule*)false then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from MEMBER/OVERRIDE head with offsidePos %a!\n" tokenStartCol outputPos offsidePos popCtxt() insertToken ODECLEND // Pop CtxtMemberHead when offside - | _, ((CtxtMemberHead offsidePos) :: _) when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtMemberHead offsidePos :: _ when isSemiSemi || (if relaxWhitespace2OffsideRule then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "token at column %d is offside from MEMBER/OVERRIDE head with offsidePos %a!\n" tokenStartCol outputPos offsidePos popCtxt() reprocess() - | _, (CtxtIf offsidePos :: _) - when isSemiSemi || (if isIfBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtIf offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isIfBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtIf\n" popCtxt() reprocess() - | _, (CtxtWithAsLet offsidePos :: _) - when isSemiSemi || (if isLetContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtWithAsLet offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isLetContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtWithAsLet\n" popCtxt() insertToken OEND - | _, (CtxtWithAsAugment offsidePos :: _) - when isSemiSemi || (if isWithAugmentBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtWithAsAugment offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isWithAugmentBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtWithAsAugment, isWithAugmentBlockContinuator = %b\n" (isWithAugmentBlockContinuator token) popCtxt() insertToken ODECLEND - | _, (CtxtMatch offsidePos :: _) - when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtMatch offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || relaxWhitespace2 && isMatchBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtMatch\n" popCtxt() reprocess() - | _, (CtxtFor offsidePos :: _) - when isSemiSemi || (if isForLoopContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtFor offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isForLoopContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtFor\n" popCtxt() reprocess() - | _, (CtxtWhile offsidePos :: _) - when isSemiSemi || (if isWhileBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtWhile offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isWhileBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtWhile\n" popCtxt() reprocess() - | _, (CtxtWhen offsidePos :: _) - when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtWhen offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtWhen\n" popCtxt() reprocess() - | _, (CtxtFun offsidePos :: _) - when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtFun offsidePos :: _ + // fun () -> async { + // 1 + // }, 2 // This is a '(unit -> seq) * int', so for backwards compatibility, do not treat '}' as a continuator, don't apply relaxWhitespace2OffsideRule + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2_AllowedBefore9 + when isSemiSemi || (if (*relaxWhitespace2OffsideRule*)false then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtFun\n" popCtxt() insertToken OEND - - | _, (CtxtFunction offsidePos :: _) - when isSemiSemi || tokenStartCol <= offsidePos.Column -> + // function () -> async { + // 1 + // }, 2 // This is a '(unit -> seq) * int', so for backwards compatibility, do not treat '}' as a continuator, don't apply relaxWhitespace2OffsideRule + // Test here: Tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs, RelaxWhitespace2_AllowedBefore9 + | _, CtxtFunction offsidePos :: _ + when isSemiSemi || (if (*relaxWhitespace2OffsideRule*)false then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> popCtxt() reprocess() - | _, (CtxtTry offsidePos :: _) - when isSemiSemi || (if isTryBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> + | _, CtxtTry offsidePos :: _ + when isSemiSemi || (if relaxWhitespace2OffsideRule || isTryBlockContinuator token then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtTry\n" popCtxt() reprocess() @@ -1704,7 +1857,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // // then // ... - | _, (CtxtThen offsidePos :: _) when isSemiSemi || (if isThenBlockContinuator token then tokenStartCol + 1 else tokenStartCol)<= offsidePos.Column -> + | _, CtxtThen offsidePos :: _ when isSemiSemi || (if relaxWhitespace2OffsideRule || isThenBlockContinuator token then tokenStartCol + 1 else tokenStartCol)<= offsidePos.Column -> if debug then dprintf "offside from CtxtThen, popping\n" popCtxt() reprocess() @@ -1712,13 +1865,13 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // else ... // .... // - | _, (CtxtElse (offsidePos) :: _) when isSemiSemi || tokenStartCol <= offsidePos.Column -> + | _, CtxtElse (offsidePos) :: _ when isSemiSemi || (if relaxWhitespace2OffsideRule then tokenStartCol + 1 else tokenStartCol) <= offsidePos.Column -> if debug then dprintf "offside from CtxtElse, popping\n" popCtxt() reprocess() // leadingBar=false permits match patterns without an initial '|' - | _, (CtxtMatchClauses (leadingBar, offsidePos) :: _) + | _, CtxtMatchClauses (leadingBar, offsidePos) :: _ when (isSemiSemi || (match token with // BAR occurs in pattern matching 'with' blocks @@ -1726,7 +1879,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let cond1 = tokenStartCol + (if leadingBar then 0 else 2) < offsidePos.Column let cond2 = tokenStartCol + (if leadingBar then 1 else 2) < offsidePos.Column if (cond1 <> cond2) then - errorR(Lexhelp.IndentationProblem(FSComp.SR.lexfltSeparatorTokensOfPatternMatchMisaligned(), mkSynRange (startPosOfTokenTup tokenTup) tokenTup.LexbufState.EndPos)) + errorR(IndentationProblem(FSComp.SR.lexfltSeparatorTokensOfPatternMatchMisaligned(), mkSynRange (startPosOfTokenTup tokenTup) tokenTup.LexbufState.EndPos)) cond1 | END -> tokenStartCol + (if leadingBar then -1 else 1) < offsidePos.Column | _ -> tokenStartCol + (if leadingBar then -1 else 1) < offsidePos.Column)) -> @@ -1736,21 +1889,21 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // namespace ... ~~~> CtxtNamespaceHead - | NAMESPACE, (_ :: _) -> + | NAMESPACE, _ :: _ -> if debug then dprintf "NAMESPACE: entering CtxtNamespaceHead, awaiting end of long identifier to push CtxtSeqBlock\n" pushCtxt tokenTup (CtxtNamespaceHead (tokenStartPos, token)) returnToken tokenLexbufState token // module ... ~~~> CtxtModuleHead - | MODULE, (_ :: _) -> + | MODULE, _ :: _ -> insertComingSoonTokens("MODULE", MODULE_COMING_SOON, MODULE_IS_HERE) if debug then dprintf "MODULE: entering CtxtModuleHead, awaiting EQUALS to go to CtxtSeqBlock (%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtModuleHead (tokenStartPos, token)) + pushCtxt tokenTup (CtxtModuleHead (tokenStartPos, token, NotLexingModuleAttributes)) pool.Return tokenTup hwTokenFetch useBlockRule // exception ... ~~~> CtxtException - | EXCEPTION, (_ :: _) -> + | EXCEPTION, _ :: _ -> if debug then dprintf "EXCEPTION: entering CtxtException(%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtException tokenStartPos) returnToken tokenLexbufState token @@ -1758,7 +1911,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // let ... ~~~> CtxtLetDecl // -- this rule only applies to // - 'static let' - | LET isUse, (ctxt :: _) when (match ctxt with CtxtMemberHead _ -> true | _ -> false) -> + | LET isUse, ctxt :: _ when (match ctxt with CtxtMemberHead _ -> true | _ -> false) -> if debug then dprintf "LET: entering CtxtLetDecl(), awaiting EQUALS to go to CtxtSeqBlock (%a)\n" outputPos tokenStartPos let startPos = match ctxt with CtxtMemberHead startPos -> startPos | _ -> tokenStartPos popCtxt() // get rid of the CtxtMemberHead @@ -1769,7 +1922,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // -- this rule only applies to // - 'let' 'right-on' a SeqBlock line // - 'let' in a CtxtMatchClauses, which is a parse error, but we need to treat as OLET to get various O...END tokens to enable parser to recover - | LET isUse, (ctxt :: _) -> + | LET isUse, ctxt :: _ -> let blockLet = match ctxt with | CtxtSeqBlock _ -> true | CtxtMatchClauses _ -> true | _ -> false @@ -1778,12 +1931,19 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, returnToken tokenLexbufState (if blockLet then OLET isUse else token) // let! ... ~~~> CtxtLetDecl - | BINDER b, (ctxt :: _) -> + | BINDER b, ctxt :: _ -> let blockLet = match ctxt with CtxtSeqBlock _ -> true | _ -> false if debug then dprintf "LET: entering CtxtLetDecl(blockLet=%b), awaiting EQUALS to go to CtxtSeqBlock (%a)\n" blockLet outputPos tokenStartPos pushCtxt tokenTup (CtxtLetDecl(blockLet, tokenStartPos)) returnToken tokenLexbufState (if blockLet then OBINDER b else token) + // and! ... ~~~> CtxtLetDecl + | AND_BANG isUse, ctxt :: _ -> + let blockLet = match ctxt with CtxtSeqBlock _ -> true | _ -> false + if debug then dprintf "AND!: entering CtxtLetDecl(blockLet=%b), awaiting EQUALS to go to CtxtSeqBlock (%a)\n" blockLet outputPos tokenStartPos + pushCtxt tokenTup (CtxtLetDecl(blockLet,tokenStartPos)) + returnToken tokenLexbufState (if blockLet then OAND_BANG isUse else token) + | (VAL | STATIC | ABSTRACT | MEMBER | OVERRIDE | DEFAULT), ctxtStack when thereIsACtxtMemberBodyOnTheStackAndWeShouldPopStackForUpcomingMember ctxtStack -> if debug then dprintf "STATIC/MEMBER/OVERRIDE/DEFAULT: already inside CtxtMemberBody, popping all that context before starting next member...\n" // save this token, we'll consume it again later... @@ -1808,13 +1968,13 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // override ... ~~~> CtxtMemberHead // default ... ~~~> CtxtMemberHead // val ... ~~~> CtxtMemberHead - | (VAL | STATIC | ABSTRACT | MEMBER | OVERRIDE | DEFAULT), (ctxt :: _) when (match ctxt with CtxtMemberHead _ -> false | _ -> true) -> + | (VAL | STATIC | ABSTRACT | MEMBER | OVERRIDE | DEFAULT), ctxt :: _ when (match ctxt with CtxtMemberHead _ -> false | _ -> true) -> if debug then dprintf "STATIC/MEMBER/OVERRIDE/DEFAULT: entering CtxtMemberHead, awaiting EQUALS to go to CtxtSeqBlock (%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtMemberHead tokenStartPos) returnToken tokenLexbufState token // public new... ~~~> CtxtMemberHead - | (PUBLIC | PRIVATE | INTERNAL), (_ctxt :: _) when (match peekNextToken() with NEW -> true | _ -> false) -> + | (PUBLIC | PRIVATE | INTERNAL), _ctxt :: _ when (match peekNextToken() with NEW -> true | _ -> false) -> if debug then dprintf "PUBLIC/PRIVATE/INTERNAL NEW: entering CtxtMemberHead, awaiting EQUALS to go to CtxtSeqBlock (%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtMemberHead tokenStartPos) returnToken tokenLexbufState token @@ -1826,12 +1986,12 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, returnToken tokenLexbufState token // 'let ... = ' ~~~> CtxtSeqBlock - | EQUALS, (CtxtLetDecl _ :: _) -> + | EQUALS, CtxtLetDecl _ :: _ -> if debug then dprintf "CtxtLetDecl: EQUALS, pushing CtxtSeqBlock\n" pushCtxtSeqBlock(true, AddBlockEnd) returnToken tokenLexbufState token - | EQUALS, (CtxtTypeDefns _ :: _) -> + | EQUALS, CtxtTypeDefns _ :: _ -> if debug then dprintf "CtxType: EQUALS, pushing CtxtSeqBlock\n" pushCtxtSeqBlock(true, AddBlockEnd) returnToken tokenLexbufState token @@ -1844,6 +2004,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, else returnToken tokenLexbufState token + // 'with id = ' ~~~> CtxtSeqBlock // 'with M.id = ' ~~~> CtxtSeqBlock // 'with id1 = 1 @@ -1856,8 +2017,8 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // id2 = ... ' ~~~> CtxtSeqBlock // '{ id1 = 1 // M.id2 = ... ' ~~~> CtxtSeqBlock - | EQUALS, ((CtxtWithAsLet _) :: _) // This detects 'with = '. - | EQUALS, ((CtxtVanilla (_, true)) :: (CtxtSeqBlock _) :: (CtxtWithAsLet _ | CtxtParen((LBRACE | LBRACE_BAR), _)) :: _) -> + | EQUALS, CtxtWithAsLet _ :: _ // This detects 'with = '. + | EQUALS, CtxtVanilla (_, true) :: CtxtSeqBlock _ :: (CtxtWithAsLet _ | CtxtParen((LBRACE _ | LBRACE_BAR), _)) :: _ -> if debug then dprintf "CtxtLetDecl/CtxtWithAsLet: EQUALS, pushing CtxtSeqBlock\n" // We don't insert begin/end block tokens for single-line bindings since we can't properly distinguish single-line *) // record update expressions such as "{ t with gbuckets=Array.copy t.gbuckets; gcount=t.gcount }" *) @@ -1874,16 +2035,22 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // 'static member ... =' ~~~> CtxtMemberBody, CtxtSeqBlock // 'default ... =' ~~~> CtxtMemberBody, CtxtSeqBlock // 'override ... =' ~~~> CtxtMemberBody, CtxtSeqBlock - | EQUALS, ((CtxtMemberHead offsidePos) :: _) -> + | EQUALS, CtxtMemberHead offsidePos :: _ -> if debug then dprintf "CtxtMemberHead: EQUALS, pushing CtxtSeqBlock\n" - replaceCtxt tokenTup (CtxtMemberBody (offsidePos)) + replaceCtxt tokenTup (CtxtMemberBody offsidePos) pushCtxtSeqBlock(true, AddBlockEnd) returnToken tokenLexbufState token // '(' tokens are balanced with ')' tokens and also introduce a CtxtSeqBlock - | (BEGIN | LPAREN | SIG | LBRACE | LBRACE_BAR | LBRACK | LBRACK_BAR | LQUOTE _ | LESS true), _ -> + // $".... { ... } ... { ....} " pushes a block context at first { + // ~~~~~~~~ + // ^---------INTERP_STRING_BEGIN_PART + | (TokenLExprParen | SIG | INTERP_STRING_BEGIN_PART _), _ -> if debug then dprintf "LPAREN etc., pushes CtxtParen, pushing CtxtSeqBlock, tokenStartPos = %a\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtParen (token, tokenStartPos)) + let pos = match token with + | INTERP_STRING_BEGIN_PART _ -> tokenTup.LexbufState.EndPos + | _ -> tokenStartPos + pushCtxt tokenTup (CtxtParen (token, pos)) pushCtxtSeqBlock(false, NoAddBlockEnd) returnToken tokenLexbufState token @@ -1907,9 +2074,9 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // comprehension/match | (CtxtWhile _ | CtxtFor _ | CtxtWhen _ | CtxtMatchClauses _ | CtxtFun _) :: _ -> true // comprehension - | (CtxtSeqBlock _ :: CtxtParen ((LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR), _) :: _) -> true + | CtxtSeqBlock _ :: CtxtParen ((LBRACK | LBRACE _ | LBRACE_BAR | LBRACK_BAR), _) :: _ -> true // comprehension - | (CtxtSeqBlock _ :: (CtxtDo _ | CtxtWhile _ | CtxtFor _ | CtxtWhen _ | CtxtMatchClauses _ | CtxtTry _ | CtxtThen _ | CtxtElse _) :: _) -> true + | CtxtSeqBlock _ :: (CtxtDo _ | CtxtWhile _ | CtxtFor _ | CtxtWhen _ | CtxtMatchClauses _ | CtxtTry _ | CtxtThen _ | CtxtElse _) :: _ -> true | _ -> false) -> if debug then dprintf "RARROW, pushing CtxtSeqBlock, tokenStartPos = %a\n" outputPos tokenStartPos pushCtxtSeqBlock(false, AddOneSidedBlockEnd) @@ -1923,7 +2090,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // do ~~> CtxtDo;CtxtSeqBlock (unconditionally) | (DO | DO_BANG), _ -> if debug then dprintf "DO: pushing CtxtSeqBlock, tokenStartPos = %a\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtDo (tokenStartPos)) + pushCtxt tokenTup (CtxtDo tokenStartPos) pushCtxtSeqBlock(true, AddBlockEnd) returnToken tokenLexbufState (match token with DO -> ODO | DO_BANG -> ODO_BANG | _ -> failwith "unreachable") @@ -1944,7 +2111,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, pushCtxtSeqBlock(false, NoAddBlockEnd) returnToken tokenLexbufState token - | WITH, ((CtxtTry _ | CtxtMatch _) :: _) -> + | WITH, (CtxtTry _ | CtxtMatch _) :: _ -> let lookaheadTokenTup = peekNextTokenTup() let lookaheadTokenStartPos = startPosOfTokenTup lookaheadTokenTup let leadingBar = match (peekNextToken()) with BAR -> true | _ -> false @@ -1952,17 +2119,17 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, pushCtxt lookaheadTokenTup (CtxtMatchClauses(leadingBar, lookaheadTokenStartPos)) returnToken tokenLexbufState OWITH - | FINALLY, (CtxtTry _ :: _) -> + | FINALLY, CtxtTry _ :: _ -> if debug then dprintf "FINALLY, pushing pushCtxtSeqBlock, tokenStartPos = %a\n" outputPos tokenStartPos pushCtxtSeqBlock(true, AddBlockEnd) returnToken tokenLexbufState token - | WITH, (((CtxtException _ | CtxtTypeDefns _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtMemberBody _) as limCtxt) :: _) - | WITH, ((CtxtSeqBlock _) as limCtxt :: CtxtParen((LBRACE | LBRACE_BAR), _) :: _) -> + | WITH, (CtxtException _ | CtxtTypeDefns _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtMemberBody _ as limCtxt) :: _ + | WITH, (CtxtSeqBlock _ as limCtxt :: CtxtParen((LBRACE _ | LBRACE_BAR), _) :: _) -> let lookaheadTokenTup = peekNextTokenTup() let lookaheadTokenStartPos = startPosOfTokenTup lookaheadTokenTup match lookaheadTokenTup.Token with - | RBRACE + | RBRACE _ | IDENT _ // The next clause detects the access annotations after the 'with' in: // member x.PublicGetSetProperty @@ -2029,6 +2196,11 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, let offsidePos = tokenStartPos pushCtxt tokenTup (CtxtWithAsLet offsidePos) returnToken tokenLexbufState OWITH + + // Recovery for `interface ... with` member without further indented member implementations + elif lookaheadTokenStartPos.Column <= limCtxt.StartCol && (match limCtxt with CtxtInterfaceHead _ -> true | _ -> false) then + returnToken tokenLexbufState token + else // In these situations // interface I with @@ -2075,7 +2247,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | ELSE, _ -> let lookaheadTokenTup = peekNextTokenTup() - let lookaheadTokenStartPos = startPosOfTokenTup lookaheadTokenTup + let lookaheadTokenStartPos, lookaheadTokenEndPos = posOfTokenTup lookaheadTokenTup match peekNextToken() with | IF when isSameLine() -> // We convert ELSE IF to ELIF since it then opens the block at the right point, @@ -2086,8 +2258,10 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, popNextTokenTup() |> pool.Return if debug then dprintf "ELSE IF: replacing ELSE IF with ELIF, pushing CtxtIf, CtxtVanilla(%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtIf tokenStartPos) - returnToken tokenLexbufState ELIF - + // Combine the original range of both tokens as the range for the ELIF keyword. + let correctedTokenLexbufState = LexbufState(tokenStartPos, lookaheadTokenEndPos, false) + returnToken correctedTokenLexbufState ELIF + | _ -> if debug then dprintf "ELSE: replacing ELSE with OELSE, pushing CtxtSeqBlock, CtxtElse(%a)\n" outputPos lookaheadTokenStartPos pushCtxt tokenTup (CtxtElse tokenStartPos) @@ -2096,32 +2270,32 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | (ELIF | IF), _ -> if debug then dprintf "IF, pushing CtxtIf(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtIf (tokenStartPos)) + pushCtxt tokenTup (CtxtIf tokenStartPos) returnToken tokenLexbufState token | (MATCH | MATCH_BANG), _ -> if debug then dprintf "MATCH, pushing CtxtMatch(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtMatch (tokenStartPos)) + pushCtxt tokenTup (CtxtMatch tokenStartPos) returnToken tokenLexbufState token | FOR, _ -> if debug then dprintf "FOR, pushing CtxtFor(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtFor (tokenStartPos)) + pushCtxt tokenTup (CtxtFor tokenStartPos) returnToken tokenLexbufState token | WHILE, _ -> if debug then dprintf "WHILE, pushing CtxtWhile(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtWhile (tokenStartPos)) + pushCtxt tokenTup (CtxtWhile tokenStartPos) returnToken tokenLexbufState token - | WHEN, ((CtxtSeqBlock _) :: _) -> + | WHEN, CtxtSeqBlock _ :: _ -> if debug then dprintf "WHEN, pushing CtxtWhen(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtWhen (tokenStartPos)) + pushCtxt tokenTup (CtxtWhen tokenStartPos) returnToken tokenLexbufState token | FUN, _ -> if debug then dprintf "FUN, pushing CtxtFun(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtFun (tokenStartPos)) + pushCtxt tokenTup (CtxtFun tokenStartPos) returnToken tokenLexbufState OFUN | INTERFACE, _ -> @@ -2156,7 +2330,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | TRY, _ -> if debug then dprintf "Try, pushing CtxtTry(%a)\n" outputPos tokenStartPos - pushCtxt tokenTup (CtxtTry (tokenStartPos)) + pushCtxt tokenTup (CtxtTry tokenStartPos) // The ideal spec would be to push a begin/end block pair here, but we can only do that // if we are able to balance the WITH with the TRY. We can't do that because of the numerous ways // WITH is used in the grammar (see what happens when we hit a WITH below. @@ -2168,10 +2342,10 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | OBLOCKBEGIN, _ -> returnToken tokenLexbufState token - | ODUMMY(_), _ -> + | ODUMMY _, _ -> if debug then dprintf "skipping dummy token as no offside rules apply\n" pool.Return tokenTup - hwTokenFetch (useBlockRule) + hwTokenFetch useBlockRule // Ordinary tokens start a vanilla block | _, CtxtSeqBlock _ :: _ -> @@ -2182,37 +2356,55 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | _ -> returnToken tokenLexbufState token + and insertHighPrecedenceApp (tokenTup: TokenTup) = + let dotTokenTup = peekNextTokenTup() + if debug then dprintf "inserting HIGH_PRECEDENCE_PAREN_APP at dotTokenPos = %a\n" outputPos (startPosOfTokenTup dotTokenTup) + let hpa = + if nextTokenIsAdjacentLParen tokenTup then + HIGH_PRECEDENCE_PAREN_APP + elif nextTokenIsAdjacentLBrack tokenTup then + HIGH_PRECEDENCE_BRACK_APP + else + failwith "unreachable" + delayToken(pool.UseLocation(dotTokenTup, hpa)) + delayToken tokenTup + true + and rulesForBothSoftWhiteAndHardWhite(tokenTup: TokenTup) = match tokenTup.Token with - // Insert HIGH_PRECEDENCE_PAREN_APP if needed - | IDENT _ when (nextTokenIsAdjacentLParenOrLBrack tokenTup).IsSome -> - let dotTokenTup = peekNextTokenTup() - if debug then dprintf "inserting HIGH_PRECEDENCE_PAREN_APP at dotTokenPos = %a\n" outputPos (startPosOfTokenTup dotTokenTup) - let hpa = - match nextTokenIsAdjacentLParenOrLBrack tokenTup with - | Some LPAREN -> HIGH_PRECEDENCE_PAREN_APP - | Some LBRACK -> HIGH_PRECEDENCE_BRACK_APP - | _ -> failwith "unreachable" - delayToken(pool.UseLocation(dotTokenTup, hpa)) - delayToken tokenTup + | HASH_IDENT ident -> + let hashPos = LexbufState(tokenTup.StartPos, tokenTup.StartPos.ShiftColumnBy(1), false) + let identPos = LexbufState(tokenTup.StartPos.ShiftColumnBy(1), tokenTup.EndPos, false) + delayToken(TokenTup(IDENT(ident), identPos, tokenTup.LastTokenPos)) + delayToken(TokenTup(HASH, hashPos, tokenTup.LastTokenPos)) true + // Insert HIGH_PRECEDENCE_BRACK_APP if needed + // ident[3] + | IDENT _ when nextTokenIsAdjacentLBrack tokenTup -> + insertHighPrecedenceApp tokenTup + + // Insert HIGH_PRECEDENCE_PAREN_APP if needed + // ident(3) + | IDENT _ when nextTokenIsAdjacentLParen tokenTup -> + insertHighPrecedenceApp tokenTup + // Insert HIGH_PRECEDENCE_TYAPP if needed - | (DELEGATE | IDENT _ | IEEE64 _ | IEEE32 _ | DECIMAL _ | INT8 _ | INT16 _ | INT32 _ | INT64 _ | NATIVEINT _ | UINT8 _ | UINT16 _ | UINT32 _ | UINT64 _ | BIGNUM _) when peekAdjacentTypars false tokenTup -> + | DELEGATE | IDENT _ | IEEE64 _ | IEEE32 _ | DECIMAL _ | INT8 _ | INT16 _ | INT32 _ | INT64 _ | NATIVEINT _ | UINT8 _ | UINT16 _ | UINT32 _ | UINT64 _ | UNATIVEINT _ | BIGNUM _ when peekAdjacentTypars false tokenTup -> let lessTokenTup = popNextTokenTup() delayToken (pool.UseLocation(lessTokenTup, match lessTokenTup.Token with LESS _ -> LESS true | _ -> failwith "unreachable")) if debug then dprintf "softwhite inserting HIGH_PRECEDENCE_TYAPP at dotTokenPos = %a\n" outputPos (startPosOfTokenTup lessTokenTup) delayToken (pool.UseLocation(lessTokenTup, HIGH_PRECEDENCE_TYAPP)) - delayToken (tokenTup) + delayToken tokenTup pool.Return lessTokenTup true // ..^1 will get parsed as DOT_DOT_HAT 1 while 1..^2 will get parsed as 1 DOT_DOT HAT 2 // because of processing rule underneath this. - | (DOT_DOT_HAT) -> - let hatPos = new LexbufState(tokenTup.EndPos.ShiftColumnBy(-1), tokenTup.EndPos, false) + | DOT_DOT_HAT -> + let hatPos = LexbufState(tokenTup.EndPos.ShiftColumnBy(-1), tokenTup.EndPos, false) delayToken(let rented = pool.Rent() in rented.Token <- INFIX_AT_HAT_OP("^"); rented.LexbufState <- hatPos; rented.LastTokenPos <- tokenTup.LastTokenPos; rented) delayToken(pool.UseShiftedLocation(tokenTup, DOT_DOT, 0, -1)) pool.Return tokenTup @@ -2220,14 +2412,14 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Split this token to allow "1..2" for range specification | INT32_DOT_DOT (i, v) -> - let dotDotPos = new LexbufState(tokenTup.EndPos.ShiftColumnBy(-2), tokenTup.EndPos, false) + let dotDotPos = LexbufState(tokenTup.EndPos.ShiftColumnBy(-2), tokenTup.EndPos, false) delayToken(let rented = pool.Rent() in rented.Token <- DOT_DOT; rented.LexbufState <- dotDotPos; rented.LastTokenPos <- tokenTup.LastTokenPos; rented) delayToken(pool.UseShiftedLocation(tokenTup, INT32(i, v), 0, -2)) pool.Return tokenTup true // Split @>. and @@>. into two | RQUOTE_DOT (s, raw) -> - let dotPos = new LexbufState(tokenTup.EndPos.ShiftColumnBy(-1), tokenTup.EndPos, false) + let dotPos = LexbufState(tokenTup.EndPos.ShiftColumnBy(-1), tokenTup.EndPos, false) delayToken(let rented = pool.Rent() in rented.Token <- DOT; rented.LexbufState <- dotPos; rented.LastTokenPos <- tokenTup.LastTokenPos; rented) delayToken(pool.UseShiftedLocation(tokenTup, RQUOTE(s, raw), 0, -1)) pool.Return tokenTup @@ -2251,11 +2443,17 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | MINUS -> true | _ -> false let nextTokenTup = popNextTokenTup() + /// Merge the location of the prefix token and the literal let delayMergedToken tok = - delayToken(let rented = pool.Rent() in rented.Token <- tok; rented.LexbufState <- new LexbufState(tokenTup.LexbufState.StartPos, nextTokenTup.LexbufState.EndPos, nextTokenTup.LexbufState.PastEOF); rented.LastTokenPos <- tokenTup.LastTokenPos; rented) + let rented = pool.Rent() + rented.Token <- tok + rented.LexbufState <- LexbufState(tokenTup.LexbufState.StartPos, nextTokenTup.LexbufState.EndPos, nextTokenTup.LexbufState.PastEOF) + rented.LastTokenPos <- tokenTup.LastTokenPos + delayToken(rented) pool.Return nextTokenTup pool.Return tokenTup + let noMerge() = let tokenName = match tokenTup.Token with @@ -2277,7 +2475,7 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, | INT32(v, bad) -> delayMergedToken(INT32((if plus then v else -v), (plus && bad))) // note: '-' makes a 'bad' max int 'good'. '+' does not | INT32_DOT_DOT(v, bad) -> delayMergedToken(INT32_DOT_DOT((if plus then v else -v), (plus && bad))) // note: '-' makes a 'bad' max int 'good'. '+' does not | INT64(v, bad) -> delayMergedToken(INT64((if plus then v else -v), (plus && bad))) // note: '-' makes a 'bad' max int 'good'. '+' does not - | NATIVEINT v -> delayMergedToken(NATIVEINT(if plus then v else -v)) + | NATIVEINT(v, bad) -> delayMergedToken(NATIVEINT((if plus then v else -v), (plus && bad))) // note: '-' makes a 'bad' max int 'good'. '+' does not | IEEE32 v -> delayMergedToken(IEEE32(if plus then v else -v)) | IEEE64 v -> delayMergedToken(IEEE64(if plus then v else -v)) | DECIMAL v -> delayMergedToken(DECIMAL(if plus then v else System.Decimal.op_UnaryNegation v)) @@ -2311,26 +2509,26 @@ type LexFilterImpl (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, // Part VI. Publish the new lexer function. //-------------------------------------------------------------------------- - member __.LexBuffer = lexbuf - member __.Lexer _ = + member _.LexBuffer = lexbuf + + member _.GetToken() = if not initialized then let _firstTokenTup = peekInitial() () - if lightSyntaxStatus.Status + if lightStatus.Status then hwTokenFetch true else swTokenFetch() - // LexFilterImpl does the majority of the work for offsides rules and other magic. // LexFilter just wraps it with light post-processing that introduces a few more 'coming soon' symbols, to // make it easier for the parser to 'look ahead' and safely shift tokens in a number of recovery scenarios. -type LexFilter (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbuf: UnicodeLexing.Lexbuf) = - let inner = new LexFilterImpl (lightSyntaxStatus, compilingFsLib, lexer, lexbuf) +type LexFilter (lightStatus: LightSyntaxStatus, compilingFsLib, lexer, lexbuf: UnicodeLexing.Lexbuf) = + let inner = LexFilterImpl(lightStatus, compilingFsLib, lexer, lexbuf) // We don't interact with lexbuf state at all, any inserted tokens have same state/location as the real one read, so // we don't have to do any of the wrapped lexbuf magic that you see in LexFilterImpl. - let delayedStack = System.Collections.Generic.Stack() + let delayedStack = Stack() let delayToken tok = delayedStack.Push tok let popNextToken() = @@ -2338,7 +2536,7 @@ type LexFilter (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, lex let tokenTup = delayedStack.Pop() tokenTup else - inner.Lexer() + inner.GetToken() let insertComingSoonTokens comingSoon isHere = if debug then dprintf "inserting 6 copies of %+A before %+A\n" comingSoon isHere @@ -2346,21 +2544,18 @@ type LexFilter (lightSyntaxStatus: LightSyntaxStatus, compilingFsLib, lexer, lex for i in 1..6 do delayToken comingSoon - member __.LexBuffer = inner.LexBuffer - member __.Lexer _ = - let rec loop() = - let token = popNextToken() - match token with - | RBRACE -> - insertComingSoonTokens RBRACE_COMING_SOON RBRACE_IS_HERE - loop() - | RPAREN -> - insertComingSoonTokens RPAREN_COMING_SOON RPAREN_IS_HERE - loop() - | OBLOCKEND -> - insertComingSoonTokens OBLOCKEND_COMING_SOON OBLOCKEND_IS_HERE - loop() - | _ -> token - loop() - -let token lexargs skip = Lexer.token lexargs skip + member _.LexBuffer = inner.LexBuffer + + member lexer.GetToken () = + let token = popNextToken() + match token with + | RBRACE _ -> + insertComingSoonTokens RBRACE_COMING_SOON RBRACE_IS_HERE + lexer.GetToken() + | RPAREN -> + insertComingSoonTokens RPAREN_COMING_SOON RPAREN_IS_HERE + lexer.GetToken() + | OBLOCKEND -> + insertComingSoonTokens OBLOCKEND_COMING_SOON OBLOCKEND_IS_HERE + lexer.GetToken() + | _ -> token diff --git a/src/fsharp/LexFilter.fsi b/src/fsharp/LexFilter.fsi new file mode 100644 index 00000000000..174f58e959c --- /dev/null +++ b/src/fsharp/LexFilter.fsi @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// LexFilter - process the token stream prior to parsing. +/// Implements the offside rule and a couple of other lexical transformations. +module internal FSharp.Compiler.LexFilter + +open Internal.Utilities.Text.Lexing +open FSharp.Compiler.Lexhelp +open FSharp.Compiler.Parser + +/// Match the close of '>' of a set of type parameters. +/// This is done for tokens such as '>>' by smashing the token +val (|TyparsCloseOp|_|) : txt: string -> ((bool -> token)[] * token option) option + +/// A stateful filter over the token stream that adjusts it for indentation-aware syntax rules +/// Process the token stream prior to parsing. Implements the offside rule and other lexical transformations. +type LexFilter = + + /// Create a lex filter + new: lightStatus: LightSyntaxStatus * compilingFsLib: bool * lexer: (LexBuffer -> token) * lexbuf: LexBuffer -> LexFilter + + /// The LexBuffer associated with the filter + member LexBuffer: LexBuffer + + /// Get the next token + member GetToken: unit -> token diff --git a/src/fsharp/Logger.fs b/src/fsharp/Logger.fs index b1968240d23..a7356377b79 100644 --- a/src/fsharp/Logger.fs +++ b/src/fsharp/Logger.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler +namespace FSharp.Compiler.Diagnostics open System.Diagnostics.Tracing open System @@ -11,6 +11,8 @@ type LogCompilerFunctionId = | Service_IncrementalBuildersCache_BuildingNewCache = 3 | Service_IncrementalBuildersCache_GettingCache = 4 | CompileOps_TypeCheckOneInputAndFinishEventually = 5 + | IncrementalBuild_CreateItemKeyStoreAndSemanticClassification = 6 + | IncrementalBuild_TypeCheck = 7 /// This is for ETW tracing across FSharp.Compiler. [] @@ -54,16 +56,16 @@ type FSharpCompilerEventSource() = [] module Logger = - let Log(functionId) = + let Log functionId = FSharpCompilerEventSource.Instance.Log(functionId) let LogMessage message functionId = FSharpCompilerEventSource.Instance.LogMessage(message, functionId) - let LogBlockStart(functionId) = + let LogBlockStart functionId = FSharpCompilerEventSource.Instance.BlockStart(functionId) - let LogBlockStop(functionId) = + let LogBlockStop functionId = FSharpCompilerEventSource.Instance.BlockStop(functionId) let LogBlockMessageStart message functionId = @@ -72,14 +74,14 @@ module Logger = let LogBlockMessageStop message functionId = FSharpCompilerEventSource.Instance.BlockMessageStop(message, functionId) - let LogBlock(functionId) = + let LogBlock functionId = FSharpCompilerEventSource.Instance.BlockStart(functionId) { new IDisposable with - member __.Dispose() = + member _.Dispose() = FSharpCompilerEventSource.Instance.BlockStop(functionId) } let LogBlockMessage message functionId = FSharpCompilerEventSource.Instance.BlockMessageStart(message, functionId) { new IDisposable with - member __.Dispose() = + member _.Dispose() = FSharpCompilerEventSource.Instance.BlockMessageStop(message, functionId) } diff --git a/src/fsharp/Logger.fsi b/src/fsharp/Logger.fsi index cb84dde5f54..fcaffdc642b 100644 --- a/src/fsharp/Logger.fsi +++ b/src/fsharp/Logger.fsi @@ -1,17 +1,17 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler +namespace FSharp.Compiler.Diagnostics open System -// FIXME: We cannot make this internal yet until F# gets a compiler switch to make cases public when the type itself is internal. -// https://github.com/Microsoft/visualfsharp/issues/4821 -type (* internal *) LogCompilerFunctionId = +type internal LogCompilerFunctionId = | Service_ParseAndCheckFileInProject = 1 | Service_CheckOneFile = 2 | Service_IncrementalBuildersCache_BuildingNewCache = 3 | Service_IncrementalBuildersCache_GettingCache = 4 | CompileOps_TypeCheckOneInputAndFinishEventually = 5 + | IncrementalBuild_CreateItemKeyStoreAndSemanticClassification = 6 + | IncrementalBuild_TypeCheck = 7 [] module internal Logger = diff --git a/src/fsharp/LowerCallsAndSeqs.fs b/src/fsharp/LowerCallsAndSeqs.fs index d46f7201dce..ec6a327b6e3 100644 --- a/src/fsharp/LowerCallsAndSeqs.fs +++ b/src/fsharp/LowerCallsAndSeqs.fs @@ -2,20 +2,21 @@ module internal FSharp.Compiler.LowerCallsAndSeqs -open FSharp.Compiler.AbstractIL +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.Infos open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib open FSharp.Compiler.InfoReader +open FSharp.Compiler.Infos open FSharp.Compiler.MethodCalls +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypeRelations +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps //---------------------------------------------------------------------------- // Eta-expansion of calls to top-level-methods @@ -29,7 +30,7 @@ let InterceptExpr g cont expr = | None -> None // App (Val v, tys, args) - | Expr.App ((Expr.Val (vref, flags, _) as f0), f0ty, tyargsl, argsl, m) -> + | Expr.App (Expr.Val (vref, flags, _) as f0, f0ty, tyargsl, argsl, m) -> // Only transform if necessary, i.e. there are not enough arguments match vref.ValReprInfo with | Some(topValInfo) -> @@ -57,14 +58,13 @@ let LowerImplFile g assembly = PostTransform= (fun _ -> None) IsUnderQuotations=false } assembly - //---------------------------------------------------------------------------- -// State machine compilation for sequence expressions +// General helpers let mkLambdaNoType g m uv e = mkLambda m uv (e, tyOfExpr g e) -let callNonOverloadedMethod g amap m methName ty args = +let callNonOverloadedILMethod g amap m methName ty args = match TryFindIntrinsicMethInfo (InfoReader(g, amap)) m AccessibleFromSomeFSharpCode methName ty with | [] -> error(InternalError("No method called '"+methName+"' was found", m)) | ILMeth(g, ilMethInfo, _) :: _ -> @@ -74,6 +74,8 @@ let callNonOverloadedMethod g amap m methName ty args = | _ -> error(InternalError("The method called '"+methName+"' resolved to a non-IL type", m)) +//---------------------------------------------------------------------------- +// State machine compilation for sequence expressions type LoweredSeqFirstPhaseResult = { @@ -89,10 +91,10 @@ type LoweredSeqFirstPhaseResult = /// 'pcMap' is the mapping from code labels to values for 'pc' /// /// The phase2 function returns the core of the generate, dispose and checkDispose implementations. - phase2 : ((* pc: *) ValRef * (* current: *) ValRef * (* nextVar: *) ValRef * Map -> Expr * Expr * Expr) + phase2 : ValRef * (* current: *) ValRef * (* nextVar: *) ValRef * Map -> Expr * Expr * Expr /// The labels allocated for one portion of the sequence expression - labels : int list + entryPoints : int list /// Indicates if any actual work is done in dispose, i.e. is there a 'try-finally' (or 'use') in the computation. significantClose : bool @@ -101,11 +103,119 @@ type LoweredSeqFirstPhaseResult = stateVars: ValRef list /// The vars captured by the non-synchronous path - capturedVars: FreeVars + asyncVars: FreeVars } let isVarFreeInExpr v e = Zset.contains v (freeInExpr CollectTyparsAndLocals e).FreeLocals +let (|Seq|_|) g expr = + match expr with + // use 'seq { ... }' as an indicator + | ValApp g g.seq_vref ([elemTy], [e], _m) -> Some (e, elemTy) + | _ -> None + +let IsPossibleSequenceExpr g overallExpr = + match overallExpr with Seq g _ -> true | _ -> false + +/// Detect a 'yield x' within a 'seq { ... }' +let (|SeqYield|_|) g expr = + match expr with + | ValApp g g.seq_singleton_vref (_, [arg], m) -> Some (arg, m) + | _ -> None + +/// Detect a 'expr; expr' within a 'seq { ... }' +let (|SeqAppend|_|) g expr = + match expr with + | ValApp g g.seq_append_vref (_, [arg1; arg2], m) -> Some (arg1, arg2, m) + | _ -> None + +/// Detect a 'while gd do expr' within a 'seq { ... }' +let (|SeqWhile|_|) g expr = + match expr with + | ValApp g g.seq_generated_vref (_, [Expr.Lambda (_, _, _, [dummyv], gd, _, _);arg2], m) + when not (isVarFreeInExpr dummyv gd) -> + + // The debug point for 'while' is attached to the second argument, see TcSequenceExpression + let mWhile = arg2.Range + Some (gd, arg2, mWhile, m) + + | _ -> + None + +let (|SeqTryFinally|_|) g expr = + match expr with + | ValApp g g.seq_finally_vref (_, [arg1;Expr.Lambda (_, _, _, [dummyv], compensation, _, _) as arg2], m) + when not (isVarFreeInExpr dummyv compensation) -> + + // The debug point for 'try' and 'finally' are attached to the first and second arguments + // respectively, see TcSequenceExpression + let mTry = arg1.Range + let mFinally = arg2.Range + + Some (arg1, compensation, mTry, mFinally, m) + + | _ -> + None + +let (|SeqUsing|_|) g expr = + match expr with + | ValApp g g.seq_using_vref ([_;_;elemTy], [resource;Expr.Lambda (_, _, _, [v], body, mBind, _)], m) -> + Some (resource, v, body, elemTy, mBind, m) + | _ -> + None + +let (|SeqForEach|_|) g expr = + match expr with + // Nested for loops are represented by calls to Seq.collect + | ValApp g g.seq_collect_vref ([_inpElemTy;_enumty2;genElemTy], [Expr.Lambda (_, _, _, [v], body, mFor, _); inp], m) -> + // The debug point mFor at the 'for' gets attached to the first argument, see TcSequenceExpression + Some (inp, v, body, genElemTy, mFor, m) + + // "for x in e -> e2" is converted to a call to Seq.map by the F# type checker. This could be removed, except it is also visible in F# quotations. + | ValApp g g.seq_map_vref ([_inpElemTy;genElemTy], [Expr.Lambda (_, _, _, [v], body, mFor, _); inp], m) -> + // The debug point mFor at the 'for' gets attached to the first argument, see TcSequenceExpression + Some (inp, v, mkCallSeqSingleton g body.Range genElemTy body, genElemTy, mFor, m) + + | _ -> None + +let (|SeqDelay|_|) g expr = + match expr with + | ValApp g g.seq_delay_vref ([elemTy], [Expr.Lambda (_, _, _, [v], e, _, _)], _m) + when not (isVarFreeInExpr v e) -> + Some (e, elemTy) + | _ -> None + +let (|SeqEmpty|_|) g expr = + match expr with + | ValApp g g.seq_empty_vref (_, [], m) -> Some m + | _ -> None + +let (|SeqToList|_|) g expr = + match expr with + | ValApp g g.seq_to_list_vref (_, [seqExpr], m) -> Some (seqExpr, m) + | _ -> None + +let (|SeqToArray|_|) g expr = + match expr with + | ValApp g g.seq_to_array_vref (_, [seqExpr], m) -> Some (seqExpr, m) + | _ -> None + +let tyConfirmsToSeq g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + tyconRefEq g tcref g.tcref_System_Collections_Generic_IEnumerable + | _ -> false + +let (|SeqElemTy|_|) g amap m ty = + match SearchEntireHierarchyOfType (tyConfirmsToSeq g) g amap m ty with + | None -> + // printfn "FAILED - yield! did not yield a sequence! %s" (stringOfRange m) + None + | Some seqTy -> + // printfn "found yield!" + let inpElemTy = List.head (argsOfAppTy g seqTy) + Some inpElemTy + /// Analyze a TAST expression to detect the elaborated form of a sequence expression. /// Then compile it to a state machine represented as a TAST containing goto, return and label nodes. /// The returned state machine will also contain references to state variables (from internal 'let' bindings), @@ -116,123 +226,60 @@ let isVarFreeInExpr v e = Zset.contains v (freeInExpr CollectTyparsAndLocals e). /// The analysis is done in two phases. The first phase determines the state variables and state labels (as Abstract IL code labels). /// We then allocate an integer pc for each state label and proceed with the second phase, which builds two related state machine /// expressions: one for 'MoveNext' and one for 'Dispose'. -let LowerSeqExpr g amap overallExpr = - /// Detect a 'yield x' within a 'seq { ... }' - let (|SeqYield|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, _tyargsl, [arg], m) when valRefEq g vref g.seq_singleton_vref -> - Some (arg, m) - | _ -> - None - - /// Detect a 'expr; expr' within a 'seq { ... }' - let (|SeqAppend|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, _tyargsl, [arg1;arg2], m) when valRefEq g vref g.seq_append_vref -> - Some (arg1, arg2, m) - | _ -> - None - - /// Detect a 'while gd do expr' within a 'seq { ... }' - let (|SeqWhile|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, _tyargsl, [Expr.Lambda (_, _, _, [dummyv], gd, _, _);arg2], m) - when valRefEq g vref g.seq_generated_vref && - not (isVarFreeInExpr dummyv gd) -> - Some (gd, arg2, m) - | _ -> - None - - let (|SeqTryFinally|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, _tyargsl, [arg1;Expr.Lambda (_, _, _, [dummyv], compensation, _, _)], m) - when valRefEq g vref g.seq_finally_vref && - not (isVarFreeInExpr dummyv compensation) -> - Some (arg1, compensation, m) - | _ -> - None - - let (|SeqUsing|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, [_;_;elemTy], [resource;Expr.Lambda (_, _, _, [v], body, _, _)], m) - when valRefEq g vref g.seq_using_vref -> - Some (resource, v, body, elemTy, m) - | _ -> - None - - let (|SeqFor|_|) expr = - match expr with - // Nested for loops are represented by calls to Seq.collect - | Expr.App (Expr.Val (vref, _, _), _f0ty, [_inpElemTy;_enumty2;genElemTy], [Expr.Lambda (_, _, _, [v], body, _, _); inp], m) when valRefEq g vref g.seq_collect_vref -> - Some (inp, v, body, genElemTy, m) - // "for x in e -> e2" is converted to a call to Seq.map by the F# type checker. This could be removed, except it is also visible in F# quotations. - | Expr.App (Expr.Val (vref, _, _), _f0ty, [_inpElemTy;genElemTy], [Expr.Lambda (_, _, _, [v], body, _, _); inp], m) when valRefEq g vref g.seq_map_vref -> - Some (inp, v, mkCallSeqSingleton g body.Range genElemTy body, genElemTy, m) - | _ -> None - - let (|SeqDelay|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, [elemTy], [Expr.Lambda (_, _, _, [v], e, _, _)], _m) when valRefEq g vref g.seq_delay_vref && not (isVarFreeInExpr v e) -> Some (e, elemTy) - | _ -> None - - let (|SeqEmpty|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _f0ty, _tyargsl, [], m) when valRefEq g vref g.seq_empty_vref -> Some (m) - | _ -> None - - let (|Seq|_|) expr = - match expr with - // use 'seq { ... }' as an indicator - | Expr.App (Expr.Val (vref, _, _), _f0ty, [elemTy], [e], _m) when valRefEq g vref g.seq_vref -> Some (e, elemTy) - | _ -> None - +let ConvertSequenceExprToObject g amap overallExpr = /// Implement a decision to represent a 'let' binding as a non-escaping local variable (rather than a state machine variable) - let RepresentBindingAsLocal (bind: Binding) res2 m = - // printfn "LowerSeq: found local variable %s" bind.Var.DisplayName - { res2 with + let RepresentBindingAsLocal (bind: Binding) resBody m = + if verbose then + printfn "LowerSeq: found local variable %s" bind.Var.DisplayName + + { resBody with phase2 = (fun ctxt -> - let generate2, dispose2, checkDispose2 = res2.phase2 ctxt - let generate = mkLetBind m bind generate2 - let dispose = dispose2 - let checkDispose = checkDispose2 + let generateBody, disposeBody, checkDisposeBody = resBody.phase2 ctxt + let generate = mkLetBind m bind generateBody + let dispose = disposeBody + let checkDispose = checkDisposeBody generate, dispose, checkDispose) - stateVars = res2.stateVars } + stateVars = resBody.stateVars } /// Implement a decision to represent a 'let' binding as a state machine variable - let RepresentBindingAsStateMachineLocal (bind: Binding) res2 m = - // printfn "LowerSeq: found state variable %s" bind.Var.DisplayName + let RepresentBindingAsStateMachineLocal (bind: Binding) resBody m = + if verbose then + printfn "LowerSeq: found state variable %s" bind.Var.DisplayName + let (TBind(v, e, sp)) = bind let sp, spm = match sp with - | SequencePointAtBinding m -> SequencePointsAtSeq, m - | _ -> SuppressSequencePointOnExprOfSequential, e.Range + | DebugPointAtBinding.Yes m -> DebugPointAtSequential.SuppressNeither, m + | _ -> DebugPointAtSequential.SuppressStmt, e.Range let vref = mkLocalValRef v - { res2 with + { resBody with phase2 = (fun ctxt -> - let generate2, dispose2, checkDispose2 = res2.phase2 ctxt + let generateBody, disposeBody, checkDisposeBody = resBody.phase2 ctxt let generate = mkCompGenSequential m (mkSequential sp m (mkValSet spm vref e) - generate2) + generateBody) // zero out the current value to free up its memory (mkValSet m vref (mkDefault (m, vref.Type))) - let dispose = dispose2 - let checkDispose = checkDispose2 + let dispose = disposeBody + let checkDispose = checkDisposeBody generate, dispose, checkDispose) - stateVars = vref :: res2.stateVars } + stateVars = vref :: resBody.stateVars } + + let RepresentBindingsAsLifted mkBinds resBody = + if verbose then + printfn "found top level let " - let RepresentBindingsAsLifted mkBinds res2 = - // printfn "found top level let " - { res2 with + { resBody with phase2 = (fun ctxt -> - let generate2, dispose2, checkDispose2 = res2.phase2 ctxt - let generate = mkBinds generate2 - let dispose = dispose2 - let checkDispose = checkDispose2 + let generateBody, disposeBody, checkDisposeBody = resBody.phase2 ctxt + let generate = mkBinds generateBody + let dispose = disposeBody + let checkDispose = checkDisposeBody generate, dispose, checkDispose) } - let rec Lower + let rec ConvertSeqExprCode isWholeExpr isTailCall // is this sequence in tailcall position? noDisposeContinuationLabel // represents the label for the code where there is effectively nothing to do to dispose the iterator for the current state @@ -240,106 +287,104 @@ let LowerSeqExpr g amap overallExpr = expr = match expr with - | SeqYield(e, m) -> + | SeqYield g (e, m) -> // printfn "found Seq.singleton" //this.pc <- NEXT //curr <- e //return true //NEXT: - let label = IL.generateCodeLabel() + let label = generateCodeLabel() Some { phase2 = (fun (pcVar, currVar, _nextv, pcMap) -> let generate = - mkCompGenSequential m + mkSequential DebugPointAtSequential.SuppressNeither m (mkValSet m pcVar (mkInt32 g m pcMap.[label])) - (mkSequential SequencePointsAtSeq m + (mkCompGenSequential m (mkValSet m currVar e) (mkCompGenSequential m (Expr.Op (TOp.Return, [], [mkOne g m], m)) (Expr.Op (TOp.Label label, [], [], m)))) let dispose = - mkCompGenSequential m - (Expr.Op (TOp.Label label, [], [], m)) + mkLabelled m label (Expr.Op (TOp.Goto currentDisposeContinuationLabel, [], [], m)) let checkDispose = - mkCompGenSequential m - (Expr.Op (TOp.Label label, [], [], m)) + mkLabelled m label (Expr.Op (TOp.Return, [], [mkBool g m (not (noDisposeContinuationLabel = currentDisposeContinuationLabel))], m)) generate, dispose, checkDispose) - labels=[label] + entryPoints=[label] stateVars=[] significantClose = false - capturedVars = emptyFreeVars + asyncVars = emptyFreeVars } - | SeqDelay(delayedExpr, _elemTy) -> + | SeqDelay g (delayedExpr, _elemTy) -> // printfn "found Seq.delay" // note, using 'isWholeExpr' here prevents 'seq { yield! e }' and 'seq { 0 .. 1000 }' from being compiled - Lower isWholeExpr isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel delayedExpr + ConvertSeqExprCode isWholeExpr isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel delayedExpr - | SeqAppend(e1, e2, m) -> + | SeqAppend g (e1, e2, m) -> // printfn "found Seq.append" - let res1 = Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel e1 - let res2 = Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 + let res1 = ConvertSeqExprCode false false noDisposeContinuationLabel currentDisposeContinuationLabel e1 + let res2 = ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 match res1, res2 with | Some res1, Some res2 -> - let capturedVars = - if res1.labels.IsEmpty then - res2.capturedVars + let asyncVars = + if res1.entryPoints.IsEmpty then + res2.asyncVars else // All of 'e2' is needed after resuming at any of the labels - unionFreeVars res1.capturedVars (freeInExpr CollectLocals e2) + unionFreeVars res1.asyncVars (freeInExpr CollectLocals e2) Some { phase2 = (fun ctxt -> let generate1, dispose1, checkDispose1 = res1.phase2 ctxt let generate2, dispose2, checkDispose2 = res2.phase2 ctxt - let generate = mkCompGenSequential m generate1 generate2 + let generate = mkSequential DebugPointAtSequential.SuppressNeither m generate1 generate2 // Order shouldn't matter here, since disposals actions are linked together by goto's (each ends in a goto). // However leaving as is for now. let dispose = mkCompGenSequential m dispose2 dispose1 let checkDispose = mkCompGenSequential m checkDispose2 checkDispose1 generate, dispose, checkDispose) - labels= res1.labels @ res2.labels + entryPoints= res1.entryPoints @ res2.entryPoints stateVars = res1.stateVars @ res2.stateVars significantClose = res1.significantClose || res2.significantClose - capturedVars = capturedVars } + asyncVars = asyncVars } | _ -> None - | SeqWhile(guardExpr, bodyExpr, m) -> + | SeqWhile g (guardExpr, bodyExpr, mWhile, m) -> // printfn "found Seq.while" - let resBody = Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr + let resBody = ConvertSeqExprCode false false noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr match resBody with | Some res2 -> - let capturedVars = - if res2.labels.IsEmpty then - res2.capturedVars // the whole loopis synchronous, no labels + let asyncVars = + if res2.entryPoints.IsEmpty then + res2.asyncVars // the whole loop is synchronous, no labels else freeInExpr CollectLocals expr // everything is needed on subsequent iterations Some { phase2 = (fun ctxt -> let generate2, dispose2, checkDispose2 = res2.phase2 ctxt - let generate = mkWhile g (SequencePointAtWhileLoop guardExpr.Range, NoSpecialWhileLoopMarker, guardExpr, generate2, m) + let generate = mkWhile g (DebugPointAtWhile.Yes mWhile, NoSpecialWhileLoopMarker, guardExpr, generate2, m) let dispose = dispose2 let checkDispose = checkDispose2 generate, dispose, checkDispose) - labels = res2.labels + entryPoints = res2.entryPoints stateVars = res2.stateVars significantClose = res2.significantClose - capturedVars = capturedVars } + asyncVars = asyncVars } | _ -> None - | SeqUsing(resource, v, body, elemTy, m) -> + | SeqUsing g (resource, v, body, elemTy, mBind, m) -> // printfn "found Seq.using" let reduction = - mkLet (SequencePointAtBinding body.Range) m v resource + mkLet (DebugPointAtBinding.Yes mBind) m v resource (mkCallSeqFinally g m elemTy body (mkUnitDelayLambda g m (mkCallDispose g m v.Type (exprForVal m v)))) - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction + ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction - | SeqFor(inp, v, body, genElemTy, m) -> + | SeqForEach g (inp, v, body, genElemTy, mFor, m) -> // printfn "found Seq.for" let inpElemTy = v.Type let inpEnumTy = mkIEnumeratorTy g inpElemTy @@ -349,33 +394,32 @@ let LowerSeqExpr g amap overallExpr = // let v = enum.Current // body ]] let reduction = - mkCallSeqUsing g m inpEnumTy genElemTy (callNonOverloadedMethod g amap m "GetEnumerator" (mkSeqTy g inpElemTy) [inp]) + mkCallSeqUsing g m inpEnumTy genElemTy (callNonOverloadedILMethod g amap m "GetEnumerator" (mkSeqTy g inpElemTy) [inp]) (mkLambdaNoType g m enumv - (mkCallSeqGenerated g m genElemTy (mkUnitDelayLambda g m (callNonOverloadedMethod g amap m "MoveNext" inpEnumTy [enume])) - (mkInvisibleLet m v (callNonOverloadedMethod g amap m "get_Current" inpEnumTy [enume]) + (mkCallSeqGenerated g m genElemTy (mkUnitDelayLambda g mFor (callNonOverloadedILMethod g amap m "MoveNext" inpEnumTy [enume])) + (mkInvisibleLet m v (callNonOverloadedILMethod g amap m "get_Current" inpEnumTy [enume]) (mkCoerceIfNeeded g (mkSeqTy g genElemTy) (tyOfExpr g body) body)))) - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction + ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction - | SeqTryFinally(e1, compensation, m) -> + | SeqTryFinally g (e1, compensation, mTry, mFinally, m) -> // printfn "found Seq.try/finally" - let innerDisposeContinuationLabel = IL.generateCodeLabel() - let resBody = Lower false false noDisposeContinuationLabel innerDisposeContinuationLabel e1 + let innerDisposeContinuationLabel = generateCodeLabel() + let resBody = ConvertSeqExprCode false false noDisposeContinuationLabel innerDisposeContinuationLabel e1 match resBody with | Some res1 -> - let capturedVars = unionFreeVars res1.capturedVars (freeInExpr CollectLocals compensation) - Some { phase2 = (fun ((pcVar, _currv, _, pcMap) as ctxt) -> + let asyncVars = unionFreeVars res1.asyncVars (freeInExpr CollectLocals compensation) + Some { phase2 = (fun (pcVar, _currv, _, pcMap as ctxt) -> let generate1, dispose1, checkDispose1 = res1.phase2 ctxt let generate = // copy the compensation expression - one copy for the success continuation and one for the exception let compensation = copyExpr g CloneAllAndMarkExprValsAsCompilerGenerated compensation mkCompGenSequential m // set the PC to the inner finally, so that if an exception happens we run the right finally - (mkCompGenSequential m - (mkValSet m pcVar (mkInt32 g m pcMap.[innerDisposeContinuationLabel])) + (mkSequential DebugPointAtSequential.SuppressStmt m + (mkValSet mTry pcVar (mkInt32 g m pcMap.[innerDisposeContinuationLabel])) generate1 ) // set the PC past the try/finally before trying to run it, to make sure we only run it once - (mkCompGenSequential m - (Expr.Op (TOp.Label innerDisposeContinuationLabel, [], [], m)) + (mkLabelled m innerDisposeContinuationLabel (mkCompGenSequential m (mkValSet m pcVar (mkInt32 g m pcMap.[currentDisposeContinuationLabel])) compensation)) @@ -384,48 +428,46 @@ let LowerSeqExpr g amap overallExpr = mkCompGenSequential m dispose1 // set the PC past the try/finally before trying to run it, to make sure we only run it once - (mkCompGenSequential m - (Expr.Op (TOp.Label innerDisposeContinuationLabel, [], [], m)) - (mkCompGenSequential m - (mkValSet m pcVar (mkInt32 g m pcMap.[currentDisposeContinuationLabel])) + (mkLabelled m innerDisposeContinuationLabel + (mkSequential DebugPointAtSequential.SuppressStmt m + (mkValSet mFinally pcVar (mkInt32 g m pcMap.[currentDisposeContinuationLabel])) (mkCompGenSequential m compensation (Expr.Op (TOp.Goto currentDisposeContinuationLabel, [], [], m))))) let checkDispose = mkCompGenSequential m checkDispose1 - (mkCompGenSequential m - (Expr.Op (TOp.Label innerDisposeContinuationLabel, [], [], m)) + (mkLabelled m innerDisposeContinuationLabel (Expr.Op (TOp.Return, [], [mkTrue g m (* yes, we must dispose!!! *) ], m))) generate, dispose, checkDispose) - labels = innerDisposeContinuationLabel :: res1.labels + entryPoints = innerDisposeContinuationLabel :: res1.entryPoints stateVars = res1.stateVars significantClose = true - capturedVars = capturedVars } + asyncVars = asyncVars } | _ -> None - | SeqEmpty m -> + | SeqEmpty g m -> // printfn "found Seq.empty" Some { phase2 = (fun _ -> let generate = mkUnit g m let dispose = Expr.Op (TOp.Goto currentDisposeContinuationLabel, [], [], m) let checkDispose = Expr.Op (TOp.Goto currentDisposeContinuationLabel, [], [], m) generate, dispose, checkDispose) - labels = [] + entryPoints = [] stateVars = [] significantClose = false - capturedVars = emptyFreeVars } + asyncVars = emptyFreeVars } - | Expr.Sequential (x1, x2, NormalSeq, ty, m) -> - match Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel x2 with + | Expr.Sequential (expr1, expr2, NormalSeq, sp, m) -> + match ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel expr2 with | Some res2-> // printfn "found sequential execution" Some { res2 with phase2 = (fun ctxt -> let generate2, dispose2, checkDispose2 = res2.phase2 ctxt - let generate = Expr.Sequential (x1, generate2, NormalSeq, ty, m) + let generate = Expr.Sequential (expr1, generate2, NormalSeq, sp, m) let dispose = dispose2 let checkDispose = checkDispose2 generate, dispose, checkDispose) } @@ -435,17 +477,17 @@ let LowerSeqExpr g amap overallExpr = // Restriction: compilation of sequence expressions containing non-toplevel constrained generic functions is not supported when bind.Var.IsCompiledAsTopLevel || not (IsGenericValWithGenericConstraints g bind.Var) -> - let resBody = Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr - match resBody with - | Some res2 -> + let resBodyOpt = ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr + match resBodyOpt with + | Some resBody -> if bind.Var.IsCompiledAsTopLevel then - Some (RepresentBindingsAsLifted (mkLetBind m bind) res2) - elif not (res2.capturedVars.FreeLocals.Contains(bind.Var)) then + Some (RepresentBindingsAsLifted (mkLetBind m bind) resBody) + elif not (resBody.asyncVars.FreeLocals.Contains(bind.Var)) then // printfn "found state variable %s" bind.Var.DisplayName - Some (RepresentBindingAsLocal bind res2 m) + Some (RepresentBindingAsLocal bind resBody m) else // printfn "found state variable %s" bind.Var.DisplayName - Some (RepresentBindingAsStateMachineLocal bind res2 m) + Some (RepresentBindingAsStateMachineLocal bind resBody m) | None -> None @@ -458,7 +500,7 @@ let LowerSeqExpr g amap overallExpr = // Rule 1 - IsCompiledAsTopLevel require no state local value bind.Var.IsCompiledAsTopLevel || // Rule 2 - funky constrained local funcs not allowed - not (IsGenericValWithGenericContraints g bind.Var)) && + not (IsGenericValWithGenericConstraints g bind.Var)) && binds |> List.count (fun bind -> // Rule 3 - Recursive non-lambda and repack values are allowed match stripExpr bind.Expr with @@ -468,7 +510,7 @@ let LowerSeqExpr g amap overallExpr = | Expr.Val (v, _, _) when not (recvars.ContainsVal v.Deref) -> false | _ -> true) <= 1) -> - match Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 with + match ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 with | Some res2 -> let topLevelBinds, nonTopLevelBinds = binds |> List.partition (fun bind -> bind.Var.IsCompiledAsTopLevel) // Represent the closure-capturing values as state machine locals. They may still be recursively-referential @@ -479,38 +521,47 @@ let LowerSeqExpr g amap overallExpr = | None -> None *) - | Expr.Match (spBind, exprm, pt, targets, m, ty) when targets |> Array.forall (fun (TTarget(vs, _e, _spTarget)) -> isNil vs) -> + // LIMITATION: non-trivial pattern matches involving or-patterns or active patterns where bindings can't be + // transferred to the r.h.s. are not yet compiled. + // + // TODO: remove this limitation + | Expr.Match (spBind, exprm, pt, targets, m, ty) -> // lower all the targets. abandon if any fail to lower - let tglArray = targets |> Array.map (fun (TTarget(_vs, targetExpr, _spTarget)) -> Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel targetExpr) - // LIMITATION: non-trivial pattern matches involving or-patterns or active patterns where bindings can't be - // transferred to the r.h.s. are not yet compiled. + let tglArray = targets |> Array.map (fun (TTarget(_vs, targetExpr, _spTarget, _)) -> ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel targetExpr) if tglArray |> Array.forall Option.isSome then let tglArray = Array.map Option.get tglArray let tgl = Array.toList tglArray - let labs = tgl |> List.collect (fun res -> res.labels) - let (capturedVars, _) = - ((emptyFreeVars, false), Array.zip targets tglArray) - ||> Array.fold (fun (fvs, seenLabel) ((TTarget(_vs, e, _spTarget)), res) -> - if seenLabel then unionFreeVars fvs (freeInExpr CollectLocals e), true - else res.capturedVars, not res.labels.IsEmpty) - let stateVars = tgl |> List.collect (fun res -> res.stateVars) + let labs = tgl |> List.collect (fun res -> res.entryPoints) + + let asyncVars = + (emptyFreeVars, Array.zip targets tglArray) + ||> Array.fold (fun fvs (TTarget(_vs, _, _spTarget, _), res) -> + if res.entryPoints.IsEmpty then fvs else unionFreeVars fvs res.asyncVars) + + let stateVars = + (targets, tglArray) ||> Array.zip |> Array.toList |> List.collect (fun (TTarget(vs, _, _, _), res) -> + let stateVars = vs |> List.filter (fun v -> res.asyncVars.FreeLocals.Contains(v)) |> List.map mkLocalValRef + stateVars @ res.stateVars) + let significantClose = tgl |> List.exists (fun res -> res.significantClose) + Some { phase2 = (fun ctxt -> let gtgs, disposals, checkDisposes = (Array.toList targets, tgl) - ||> List.map2 (fun (TTarget(vs, _, spTarget)) res -> + ||> List.map2 (fun (TTarget(vs, _, spTarget, _)) res -> + let flags = vs |> List.map (fun v -> res.asyncVars.FreeLocals.Contains(v)) let generate, dispose, checkDispose = res.phase2 ctxt - let gtg = TTarget(vs, generate, spTarget) + let gtg = TTarget(vs, generate, spTarget, Some flags) gtg, dispose, checkDispose) |> List.unzip3 let generate = primMkMatch (spBind, exprm, pt, Array.ofList gtgs, m, ty) let dispose = if isNil disposals then mkUnit g m else List.reduce (mkCompGenSequential m) disposals let checkDispose = if isNil checkDisposes then mkFalse g m else List.reduce (mkCompGenSequential m) checkDisposes generate, dispose, checkDispose) - labels=labs + entryPoints=labs stateVars = stateVars significantClose = significantClose - capturedVars = capturedVars } + asyncVars = asyncVars } else None @@ -535,60 +586,54 @@ let LowerSeqExpr g amap overallExpr = // printfn "FAILED - not worth compiling an unrecognized immediate yield! %s " (stringOfRange m) None else - let tyConfirmsToSeq g ty = isAppTy g ty && tyconRefEq g (tcrefOfAppTy g ty) g.tcref_System_Collections_Generic_IEnumerable - match SearchEntireHierarchyOfType (tyConfirmsToSeq g) g amap m (tyOfExpr g arbitrarySeqExpr) with - | None -> - // printfn "FAILED - yield! did not yield a sequence! %s" (stringOfRange m) - None - | Some ty -> + match tyOfExpr g arbitrarySeqExpr with + | SeqElemTy g amap m inpElemTy -> // printfn "found yield!" - let inpElemTy = List.head (argsOfAppTy g ty) if isTailCall then //this.pc <- NEXT //nextEnumerator <- e //return 2 //NEXT: - let label = IL.generateCodeLabel() + let label = generateCodeLabel() Some { phase2 = (fun (pcVar, _currv, nextVar, pcMap) -> let generate = - mkCompGenSequential m + mkSequential DebugPointAtSequential.SuppressStmt m (mkValSet m pcVar (mkInt32 g m pcMap.[label])) - (mkSequential SequencePointsAtSeq m + (mkCompGenSequential m (mkAddrSet m nextVar arbitrarySeqExpr) (mkCompGenSequential m (Expr.Op (TOp.Return, [], [mkTwo g m], m)) (Expr.Op (TOp.Label label, [], [], m)))) let dispose = - mkCompGenSequential m - (Expr.Op (TOp.Label label, [], [], m)) + mkLabelled m label (Expr.Op (TOp.Goto currentDisposeContinuationLabel, [], [], m)) let checkDispose = - mkCompGenSequential m - (Expr.Op (TOp.Label label, [], [], m)) + mkLabelled m label (Expr.Op (TOp.Return, [], [mkFalse g m], m)) generate, dispose, checkDispose) - labels=[label] + entryPoints=[label] stateVars=[] significantClose = false - capturedVars = emptyFreeVars } + asyncVars = emptyFreeVars } else let v, ve = mkCompGenLocal m "v" inpElemTy - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel (mkCallSeqCollect g m inpElemTy inpElemTy (mkLambdaNoType g m v (mkCallSeqSingleton g m inpElemTy ve)) arbitrarySeqExpr) + ConvertSeqExprCode false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel (mkCallSeqCollect g m inpElemTy inpElemTy (mkLambdaNoType g m v (mkCallSeqSingleton g m inpElemTy ve)) arbitrarySeqExpr) + | _ -> None match overallExpr with - | Seq(e, ty) -> + | Seq g (e, ty) -> // printfn "found seq { ... } or Seq.delay (fun () -> ...) in FSharp.Core.dll" let m = e.Range - let initLabel = IL.generateCodeLabel() - let noDisposeContinuationLabel = IL.generateCodeLabel() + let initLabel = generateCodeLabel() + let noDisposeContinuationLabel = generateCodeLabel() // Perform phase1 - match Lower true true noDisposeContinuationLabel noDisposeContinuationLabel e with + match ConvertSeqExprCode true true noDisposeContinuationLabel noDisposeContinuationLabel e with | Some res -> // After phase1, create the variables for the state machine and work out a program counter for each label. - let labs = res.labels + let labs = res.entryPoints let stateVars = res.stateVars // printfn "successfully lowered, found %d state variables and %d labels!" stateVars.Length labs.Length let pcVar, pcExpr = mkMutableCompGenLocal m "pc" g.int32_ty @@ -619,8 +664,7 @@ let LowerSeqExpr g amap overallExpr = (mkCompGenSequential m // set the pc to "finished" (mkValSet m pcVarRef (mkInt32 g m pcDone)) - (mkCompGenSequential m - (Expr.Op (TOp.Label noDisposeContinuationLabel, [], [], m)) + (mkLabelled m noDisposeContinuationLabel (mkCompGenSequential m // zero out the current value to free up its memory (mkValSet m currVarRef (mkDefault (m, currVarRef.Type))) @@ -633,32 +677,33 @@ let LowerSeqExpr g amap overallExpr = let checkDisposeExprWithCleanup = mkCompGenSequential m checkDisposeExprCore - (mkCompGenSequential m - (Expr.Op (TOp.Label noDisposeContinuationLabel, [], [], m)) + (mkLabelled m noDisposeContinuationLabel (Expr.Op (TOp.Return, [], [mkFalse g m], m))) // A utility to add a jump table to the three generated methods let addJumpTable isDisposal expr = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m ) - let mkGotoLabelTarget lab = mbuilder.AddResultTarget(Expr.Op (TOp.Goto lab, [], [], m), SuppressSequencePointAtTarget) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) + let mkGotoLabelTarget lab = mbuilder.AddResultTarget(Expr.Op (TOp.Goto lab, [], [], m), DebugPointAtTarget.No) let dtree = - TDSwitch(pcExpr, - [ - // Add an empty disposal action for the initial state (pc = 0) - if isDisposal then - yield mkCase(DecisionTreeTest.Const(Const.Int32 pcInit), mkGotoLabelTarget noDisposeContinuationLabel) - - // Yield one target for each PC, where the action of the target is to goto the appropriate label - for pc in pcs do - yield mkCase(DecisionTreeTest.Const(Const.Int32 pc), mkGotoLabelTarget pc2lab.[pc]) - - // Yield one target for the 'done' program counter, where the action of the target is to continuation label - yield mkCase(DecisionTreeTest.Const(Const.Int32 pcDone), mkGotoLabelTarget noDisposeContinuationLabel) ], - Some(mkGotoLabelTarget pc2lab.[pcInit]), - m) + TDSwitch( + DebugPointAtSwitch.No, + pcExpr, + [ + // Add an empty disposal action for the initial state (pc = 0) + if isDisposal then + yield mkCase(DecisionTreeTest.Const(Const.Int32 pcInit), mkGotoLabelTarget noDisposeContinuationLabel) + + // Yield one target for each PC, where the action of the target is to goto the appropriate label + for pc in pcs do + yield mkCase(DecisionTreeTest.Const(Const.Int32 pc), mkGotoLabelTarget pc2lab.[pc]) + + // Yield one target for the 'done' program counter, where the action of the target is to continuation label + yield mkCase(DecisionTreeTest.Const(Const.Int32 pcDone), mkGotoLabelTarget noDisposeContinuationLabel) ], + Some(mkGotoLabelTarget pc2lab.[pcInit]), + m) let table = mbuilder.Close(dtree, m, g.int_ty) - mkCompGenSequential m table (mkCompGenSequential m (Expr.Op (TOp.Label initLabel, [], [], m)) expr) + mkCompGenSequential m table (mkLabelled m initLabel expr) // A utility to handle the cases where exceptions are raised by the disposal logic. // We wrap the disposal state machine in a loop that repeatedly drives the disposal logic of the @@ -673,8 +718,8 @@ let LowerSeqExpr g amap overallExpr = let handleExceptionsInDispose disposalExpr = let exnV, exnE = mkMutableCompGenLocal m "exn" g.exn_ty let exnVref = mkLocalValRef exnV - let startLabel = IL.generateCodeLabel() - let doneDisposeLabel = IL.generateCodeLabel () + let startLabel = generateCodeLabel() + let doneDisposeLabel = generateCodeLabel () // try ``disposalExpr'' with e -> exn <- e let eV, eE = mkLocal m "e" g.exn_ty let efV, _ = mkLocal m "ef" g.exn_ty @@ -691,7 +736,7 @@ let LowerSeqExpr g amap overallExpr = efV, Expr.Const ((Const.Bool true), m, g.bool_ty), eV, assignToExn, m, g.unit_ty, - NoSequencePointAtTry, NoSequencePointAtWith) + DebugPointAtTry.No, DebugPointAtWith.No) // Make the loop // @@ -706,16 +751,16 @@ let LowerSeqExpr g amap overallExpr = // goto startLabel // DONE_DISPOSE: let whileLoop = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m) - let addResultTarget e = mbuilder.AddResultTarget(e, SuppressSequencePointAtTarget) + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m) + let addResultTarget e = mbuilder.AddResultTarget(e, DebugPointAtTarget.No) let dtree = - TDSwitch(pcExpr, - [ mkCase((DecisionTreeTest.Const(Const.Int32 pcDone)), addResultTarget (Expr.Op (TOp.Goto doneDisposeLabel, [], [], m)) ) ], - Some (addResultTarget (mkUnit g m)), - m) + TDSwitch(DebugPointAtSwitch.No, + pcExpr, + [ mkCase((DecisionTreeTest.Const(Const.Int32 pcDone)), addResultTarget (Expr.Op (TOp.Goto doneDisposeLabel, [], [], m)) ) ], + Some (addResultTarget (mkUnit g m)), + m) let pcIsEndStateComparison = mbuilder.Close(dtree, m, g.unit_ty) - mkCompGenSequential m - (Expr.Op ((TOp.Label startLabel), [], [], m)) + mkLabelled m startLabel (mkCompGenSequential m pcIsEndStateComparison (mkCompGenSequential m @@ -734,7 +779,7 @@ let LowerSeqExpr g amap overallExpr = // --loop-- // if exn != null then raise exn mkLet - NoSequencePointAtLetBinding m exnV (Expr.Const (Const.Zero, m, g.exn_ty)) + DebugPointAtBinding.NoneAtLet m exnV (Expr.Const (Const.Zero, m, g.exn_ty)) (mkCompGenSequential m whileLoop doRaise) // Add the jump table to the GenerateNext method @@ -747,8 +792,7 @@ let LowerSeqExpr g amap overallExpr = let disposalExpr = mkCompGenSequential m disposalExprCore - (mkCompGenSequential m - (Expr.Op (TOp.Label noDisposeContinuationLabel, [], [], m)) + (mkLabelled m noDisposeContinuationLabel (mkCompGenSequential m // set the pc to "finished" (mkValSet m pcVarRef (mkInt32 g m pcDone)) @@ -772,4 +816,229 @@ let LowerSeqExpr g amap overallExpr = None | _ -> None +/// Build the 'test and dispose' part of a 'use' statement +let BuildDisposableCleanup tcVal (g: TcGlobals) infoReader m (v: Val) = + let disposeMethod = + match GetIntrinsicMethInfosOfType infoReader (Some "Dispose") AccessibleFromSomewhere AllowMultiIntfInstantiations.Yes IgnoreOverrides m g.system_IDisposable_ty with + | [x] -> x + | _ -> error(InternalError(FSComp.SR.tcCouldNotFindIDisposable(), m)) + // For struct types the test is simpler + if isStructTy g v.Type then + assert (TypeFeasiblySubsumesType 0 g infoReader.amap m g.system_IDisposable_ty CanCoerce v.Type) + // We can use NeverMutates here because the variable is going out of scope, there is no need to take a defensive + // copy of it. + let disposeExpr, _ = BuildMethodCall tcVal g infoReader.amap NeverMutates m false disposeMethod NormalValUse [] [exprForVal v.Range v] [] + //callNonOverloadedILMethod g infoReader.amap m "Dispose" g.system_IDisposable_ty [exprForVal v.Range v] + + disposeExpr + else + let disposeObjVar, disposeObjExpr = mkCompGenLocal m "objectToDispose" g.system_IDisposable_ty + let disposeExpr, _ = BuildMethodCall tcVal g infoReader.amap PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] + let inpe = mkCoerceExpr(exprForVal v.Range v, g.obj_ty, m, v.Type) + mkIsInstConditional g m g.system_IDisposable_ty inpe disposeObjVar disposeExpr (mkUnit g m) + +let mkCallCollectorMethod tcVal (g: TcGlobals) infoReader m name collExpr args = + let listCollectorTy = tyOfExpr g collExpr + let addMethod = + match GetIntrinsicMethInfosOfType infoReader (Some name) AccessibleFromSomewhere AllowMultiIntfInstantiations.Yes IgnoreOverrides m listCollectorTy with + | [x] -> x + | _ -> error(InternalError("no " + name + " method found on Collector", m)) + let expr, _ = BuildMethodCall tcVal g infoReader.amap DefinitelyMutates m false addMethod NormalValUse [] [collExpr] args + expr + +let mkCallCollectorAdd tcVal (g: TcGlobals) infoReader m collExpr arg = + mkCallCollectorMethod tcVal g infoReader m "Add" collExpr [arg] + +let mkCallCollectorAddMany tcVal (g: TcGlobals) infoReader m collExpr arg = + mkCallCollectorMethod tcVal g infoReader m "AddMany" collExpr [arg] + +let mkCallCollectorAddManyAndClose tcVal (g: TcGlobals) infoReader m collExpr arg = + mkCallCollectorMethod tcVal g infoReader m "AddManyAndClose" collExpr [arg] + +let mkCallCollectorClose tcVal (g: TcGlobals) infoReader m collExpr = + mkCallCollectorMethod tcVal g infoReader m "Close" collExpr [] + +let LowerComputedListOrArraySeqExpr tcVal g amap m collectorTy overallSeqExpr = + let infoReader = InfoReader(g, amap) + let collVal, collExpr = mkMutableCompGenLocal m "@collector" collectorTy + //let collExpr = mkValAddr m false (mkLocalValRef collVal) + let rec ConvertSeqExprCode isUninteresting isTailcall expr = + match expr with + | SeqYield g (e, m) -> + let exprR = mkCallCollectorAdd tcVal (g: TcGlobals) infoReader m collExpr e + Result.Ok (false, exprR) + + | SeqDelay g (delayedExpr, _elemTy) -> + ConvertSeqExprCode isUninteresting isTailcall delayedExpr + + | SeqAppend g (e1, e2, m) -> + let res1 = ConvertSeqExprCode false false e1 + let res2 = ConvertSeqExprCode false isTailcall e2 + match res1, res2 with + | Result.Ok (_, e1R), Result.Ok (closed2, e2R) -> + let exprR = mkSequential DebugPointAtSequential.SuppressNeither m e1R e2R + Result.Ok (closed2, exprR) + | Result.Error msg, _ | _, Result.Error msg -> Result.Error msg + + | SeqWhile g (guardExpr, bodyExpr, mWhile, m) -> + let resBody = ConvertSeqExprCode false false bodyExpr + match resBody with + | Result.Ok (_, bodyExprR) -> + let exprR = mkWhile g (DebugPointAtWhile.Yes mWhile, NoSpecialWhileLoopMarker, guardExpr, bodyExprR, m) + Result.Ok (false, exprR) + | Result.Error msg -> Result.Error msg + + | SeqUsing g (resource, v, bodyExpr, _elemTy, mBind, m) -> + let resBody = ConvertSeqExprCode false false bodyExpr + match resBody with + | Result.Ok (_, bodyExprR) -> + // printfn "found Seq.using" + let cleanupE = BuildDisposableCleanup tcVal g infoReader m v + let exprR = + mkLet (DebugPointAtBinding.Yes mBind) m v resource + (mkTryFinally g (bodyExprR, cleanupE, m, tyOfExpr g bodyExpr, DebugPointAtTry.Body, DebugPointAtFinally.No)) + Result.Ok (false, exprR) + | Result.Error msg -> Result.Error msg + + | SeqForEach g (inp, v, bodyExpr, _genElemTy, mFor, m) -> + let resBody = ConvertSeqExprCode false false bodyExpr + match resBody with + | Result.Ok (_, bodyExprR) -> + // printfn "found Seq.for" + let inpElemTy = v.Type + let inpEnumTy = mkIEnumeratorTy g inpElemTy + let enumv, enumve = mkCompGenLocal m "enum" inpEnumTy + let guardExpr = callNonOverloadedILMethod g amap m "MoveNext" inpEnumTy [enumve] + let cleanupE = BuildDisposableCleanup tcVal g infoReader m enumv + let exprR = + mkInvisibleLet m enumv (callNonOverloadedILMethod g amap m "GetEnumerator" (mkSeqTy g inpElemTy) [inp]) + (mkTryFinally g + (mkWhile g (DebugPointAtWhile.Yes mFor, NoSpecialWhileLoopMarker, guardExpr, + (mkInvisibleLet m v + (callNonOverloadedILMethod g amap m "get_Current" inpEnumTy [enumve])) + bodyExprR, m), + cleanupE, m, tyOfExpr g bodyExpr, DebugPointAtTry.Body, DebugPointAtFinally.Body)) + Result.Ok (false, exprR) + | Result.Error msg -> Result.Error msg + + | SeqTryFinally g (bodyExpr, compensation, mTry, mFinally, m) -> + let resBody = ConvertSeqExprCode false false bodyExpr + match resBody with + | Result.Ok (_, bodyExprR) -> + let exprR = + mkTryFinally g (bodyExprR, compensation, m, tyOfExpr g bodyExpr, DebugPointAtTry.Yes mTry, DebugPointAtFinally.Yes mFinally) + Result.Ok (false, exprR) + | Result.Error msg -> Result.Error msg + + | SeqEmpty g m -> + let exprR = mkUnit g m + Result.Ok(false, exprR) + + | Expr.Sequential (x1, bodyExpr, NormalSeq, ty, m) -> + let resBody = ConvertSeqExprCode isUninteresting isTailcall bodyExpr + match resBody with + | Result.Ok (closed, bodyExprR) -> + let exprR = Expr.Sequential (x1, bodyExprR, NormalSeq, ty, m) + Result.Ok(closed, exprR) + | Result.Error msg -> Result.Error msg + + | Expr.Let (bind, bodyExpr, m, _) -> + let resBody = ConvertSeqExprCode isUninteresting isTailcall bodyExpr + match resBody with + | Result.Ok (closed, bodyExprR) -> + let exprR = mkLetBind m bind bodyExprR + Result.Ok(closed, exprR) + | Result.Error msg -> Result.Error msg + + | Expr.LetRec (binds, bodyExpr, m, _) -> + let resBody = ConvertSeqExprCode isUninteresting isTailcall bodyExpr + match resBody with + | Result.Ok (closed, bodyExprR) -> + let exprR = mkLetRecBinds m binds bodyExprR + Result.Ok(closed, exprR) + | Result.Error msg -> Result.Error msg + + | Expr.Match (spBind, exprm, pt, targets, m, ty) -> + // lower all the targets. abandon if any fail to lower + let resTargets = + targets |> Array.map (fun (TTarget(vs, targetExpr, spTarget, flags)) -> + match ConvertSeqExprCode false false targetExpr with + | Result.Ok (_, targetExprR) -> + Result.Ok (TTarget(vs, targetExprR, spTarget, flags)) + | Result.Error msg -> Result.Error msg ) + if resTargets |> Array.forall (function Result.Ok _ -> true | _ -> false) then + let tglArray = Array.map (function Result.Ok v -> v | _ -> failwith "unreachable") resTargets + + let exprR = primMkMatch (spBind, exprm, pt, tglArray, m, ty) + Result.Ok(false, exprR) + else + resTargets |> Array.pick (function Result.Error msg -> Some (Result.Error msg) | _ -> None) + + // yield! e ---> (for x in e -> x) + + | arbitrarySeqExpr -> + let m = arbitrarySeqExpr.Range + if isUninteresting then + // printfn "FAILED - not worth compiling an unrecognized Seq.toList at %s " (stringOfRange m) + Result.Error () + else + // If we're the final in a sequential chain then we can AddMany, Close and return + if isTailcall then + let exprR = mkCallCollectorAddManyAndClose tcVal (g: TcGlobals) infoReader m collExpr arbitrarySeqExpr + // Return 'true' to indicate the collector was closed and the overall result of the expression is the result + Result.Ok(true, exprR) + else + let exprR = mkCallCollectorAddMany tcVal (g: TcGlobals) infoReader m collExpr arbitrarySeqExpr + Result.Ok(false, exprR) + + + // Perform conversion + match ConvertSeqExprCode true true overallSeqExpr with + | Result.Ok (closed, overallSeqExprR) -> + mkInvisibleLet m collVal (mkDefault (m, collectorTy)) + (if closed then + // If we ended with AddManyAndClose then we're done + overallSeqExprR + else + mkCompGenSequential m + overallSeqExprR + (mkCallCollectorClose tcVal g infoReader m collExpr)) + |> Some + | Result.Error () -> + None + +let (|OptionalCoerce|) expr = + match expr with + | Expr.Op (TOp.Coerce, _, [arg], _) -> arg + | _ -> expr + +// Making 'seq' optional means this kicks in for FSharp.Core, see TcArrayOrListComputedExpression +// which only adds a 'seq' call outside of FSharp.Core +let (|OptionalSeq|_|) g amap expr = + match expr with + // use 'seq { ... }' as an indicator + | Seq g (e, elemTy) -> + Some (e, elemTy) + | _ -> + // search for the relevant element type + match tyOfExpr g expr with + | SeqElemTy g amap expr.Range elemTy -> + Some (expr, elemTy) + | _ -> None + +let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr = + // If ListCollector is in FSharp.Core then this optimization kicks in + if g.ListCollector_tcr.CanDeref then + + match overallExpr with + | SeqToList g (OptionalCoerce (OptionalSeq g amap (overallSeqExpr, overallElemTy)), m) -> + let collectorTy = g.mk_ListCollector_ty overallElemTy + LowerComputedListOrArraySeqExpr tcVal g amap m collectorTy overallSeqExpr + + | SeqToArray g (OptionalCoerce (OptionalSeq g amap (overallSeqExpr, overallElemTy)), m) -> + let collectorTy = g.mk_ArrayCollector_ty overallElemTy + LowerComputedListOrArraySeqExpr tcVal g amap m collectorTy overallSeqExpr + | _ -> None + else + None diff --git a/src/fsharp/LowerCallsAndSeqs.fsi b/src/fsharp/LowerCallsAndSeqs.fsi index 5abcb8288dc..87492550623 100644 --- a/src/fsharp/LowerCallsAndSeqs.fsi +++ b/src/fsharp/LowerCallsAndSeqs.fsi @@ -2,10 +2,10 @@ module internal FSharp.Compiler.LowerCallsAndSeqs -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals open FSharp.Compiler.Import -open FSharp.Compiler.Range +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.Text /// An "expr -> expr" pass that eta-expands under-applied values of /// known arity to lambda expressions and beta-var-reduces to bind @@ -19,4 +19,8 @@ val LowerImplFile: g: TcGlobals -> assembly: TypedImplFile -> TypedImplFile /// a program counter (pc) that records the current state, and a current generated value (current). /// All these variables are then represented as fields in a hosting closure object along with any additional /// free variables of the sequence expression. -val LowerSeqExpr: g: TcGlobals -> amap: ImportMap -> overallExpr: Expr -> (ValRef * ValRef * ValRef * ValRef list * Expr * Expr * Expr * TType * range) option +val ConvertSequenceExprToObject: g: TcGlobals -> amap: ImportMap -> overallExpr: Expr -> (ValRef * ValRef * ValRef * ValRef list * Expr * Expr * Expr * TType * range) option + +val IsPossibleSequenceExpr: g: TcGlobals -> overallExpr: Expr -> bool + +val LowerComputedListOrArrayExpr: tcVal: ConstraintSolver.TcValF -> g: TcGlobals -> amap: ImportMap -> Expr -> Expr option diff --git a/src/fsharp/LowerStateMachines.fs b/src/fsharp/LowerStateMachines.fs new file mode 100644 index 00000000000..c0d4986f168 --- /dev/null +++ b/src/fsharp/LowerStateMachines.fs @@ -0,0 +1,905 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.LowerStateMachines + +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps + +let mkLabelled m l e = mkCompGenSequential m (Expr.Op (TOp.Label l, [], [], m)) e + +type StateMachineConversionFirstPhaseResult = + { + /// Represents the expanded expression prior to decisions about labels + phase1: Expr + + /// The second phase of the transformation. It is run after all code labels and their mapping to program counters have been determined + /// after the first phase. + phase2: Map -> Expr + + /// The labels allocated for this portion of the computation + entryPoints: int list + + /// The state variables allocated for one portion of the sequence expression (i.e. the local let-bound variables which become state variables) + stateVars: ValRef list + + /// All this values get represented via the 'this' pointer + thisVars: ValRef list + + /// The vars captured by the non-synchronous resumable path + resumableVars: FreeVars + } + +#if DEBUG +let sm_verbose = try System.Environment.GetEnvironmentVariable("FSharp_StateMachineVerbose") <> null with _ -> false +#else +let sm_verbose = false +#endif + +let rec (|OptionalResumeAtExpr|) g expr = + match expr with + | IfUseResumableStateMachinesExpr g (OptionalResumeAtExpr g res, _) -> res + | Expr.Sequential(ResumeAtExpr g pcExpr, codeExpr, NormalSeq, _, _m) -> (Some pcExpr, codeExpr) + | _ -> (None, expr) + +/// Implement a decision to represent a 'let' binding as a non-escaping local variable (rather than a state machine variable) +let RepresentBindingAsTopLevelOrLocal (bind: Binding) (res2: StateMachineConversionFirstPhaseResult) m = + if sm_verbose then + printfn "LowerStateMachine: found local variable %s" bind.Var.DisplayName + + { res2 with + phase1 = mkLetBind m bind res2.phase1 + phase2 = (fun ctxt -> mkLetBind m bind (res2.phase2 ctxt)) } + +/// Implement a decision to represent a 'let' binding as the 'this' pointer of the state machine, +/// because it is rebinding the 'this' variable +let RepresentBindingAsThis (bind: Binding) (res2: StateMachineConversionFirstPhaseResult) _m = + if sm_verbose then + printfn "LowerStateMachine: found local variable %s" bind.Var.DisplayName + + { res2 with + thisVars = mkLocalValRef bind.Var :: res2.thisVars + // Drop the let binding on the floor as it is only rebinding the 'this' variable + phase1 = res2.phase1 + phase2 = res2.phase2 } + +/// Implement a decision to represent a 'let' binding as a state machine variable +let RepresentBindingAsStateVar g (bind: Binding) (resBody: StateMachineConversionFirstPhaseResult) m = + if sm_verbose then + printfn "LowerStateMachine: found state variable %s" bind.Var.DisplayName + + let (TBind(v, e, sp)) = bind + let sp, spm = + match sp with + | DebugPointAtBinding.Yes m -> DebugPointAtSequential.SuppressNeither, m + | _ -> DebugPointAtSequential.SuppressStmt, e.Range + let vref = mkLocalValRef v + { resBody with + phase1 = mkSequential sp m (mkValSet spm vref e) resBody.phase1 + phase2 = (fun ctxt -> + let generateBody = resBody.phase2 ctxt + let generate = + mkSequential sp m + (mkValSet spm vref e) + // Within all resumable code, a return value of 'true' indicates success/completion path, when we can clear + // state machine locals. + (if typeEquiv g (tyOfExpr g generateBody) g.bool_ty then + mkCond DebugPointAtBinding.NoneAtInvisible DebugPointAtTarget.No m g.bool_ty generateBody + (mkCompGenSequential m + (mkValSet m vref (mkDefault (m, vref.Type))) + (mkTrue g m)) + (mkFalse g m) + else + generateBody) + generate ) + stateVars = vref :: resBody.stateVars } + +let isExpandVar g (v: Val) = + isReturnsResumableCodeTy g v.TauType && + not v.IsCompiledAsTopLevel + +// We allow a prefix of bindings prior to the state machine, e.g. +// task { .. } +// becomes +// let builder@ = task +// .... +let isStateMachineBindingVar g (v: Val) = + isExpandVar g v || + (let nm = v.LogicalName + (nm.StartsWith "builder@" || v.IsMemberThisVal) && + not v.IsCompiledAsTopLevel) + +type env = + { + ResumableCodeDefns: ValMap + TemplateStructTy: TType option + //MachineAddrExpr: Expr option + } + + static member Empty = + { ResumableCodeDefns = ValMap.Empty + TemplateStructTy = None + //MachineAddrExpr = None + } + +/// Detect prefix of expanded, optimized state machine expressions +/// This is run on every expression during codegen +let rec IsStateMachineExpr g overallExpr = + match overallExpr with + // 'let' binding of initial code + | Expr.Let (defn, bodyExpr, m, _) when isStateMachineBindingVar g defn.Var -> + match IsStateMachineExpr g bodyExpr with + | None -> None + | Some altExpr as r -> + match altExpr with + | None -> r + | Some e -> Some (Some (mkLetBind m defn e)) + // Recognise 'if __useResumableCode ...' + | IfUseResumableStateMachinesExpr g (thenExpr, elseExpr) -> + match IsStateMachineExpr g thenExpr with + | None -> None + | Some _ -> Some (Some elseExpr) + | StructStateMachineExpr g _ -> Some None + | _ -> None + +type LoweredStateMachine = + LoweredStateMachine of + templateStructTy: TType * + dataTy: TType * + stateVars: ValRef list * + thisVars: ValRef list * + moveNext: (Val * Expr) * + setStateMachine: (Val * Val * Expr) * + afterCode: (Val * Expr) + +type LoweredStateMachineResult = + /// A state machine was recognised and was compilable + | Lowered of LoweredStateMachine + + /// A state machine was recognised and was not compilable and an alternative is available + | UseAlternative of message: string * alternativeExpr: Expr + + /// A state machine was recognised and was not compilable and no alternative is available + | NoAlternative of message: string + + /// The construct was not a state machine + | NotAStateMachine + +/// Used to scope the action of lowering a state machine expression +type LowerStateMachine(g: TcGlobals) = + + let mutable pcCount = 0 + let genPC() = + pcCount <- pcCount + 1 + pcCount + + // Record definitions for any resumable code + let rec BindResumableCodeDefinitions (env: env) expr = + + match expr with + // Bind 'let __expand_ABC = bindExpr in bodyExpr' + | Expr.Let (defn, bodyExpr, _, _) when isStateMachineBindingVar g defn.Var -> + if sm_verbose then printfn "binding %A --> %A..." defn.Var defn.Expr + let envR = { env with ResumableCodeDefns = env.ResumableCodeDefns.Add defn.Var defn.Expr } + BindResumableCodeDefinitions envR bodyExpr + + // Eliminate 'if __useResumableCode ...' + | IfUseResumableStateMachinesExpr g (thenExpr, _) -> + if sm_verbose then printfn "eliminating 'if __useResumableCode...'" + BindResumableCodeDefinitions env thenExpr + + | _ -> + (env, expr) + + let rec TryReduceApp (env: env) expr (args: Expr list) = + if isNil args then None else + match expr with + | Expr.TyLambda _ + | Expr.Lambda _ -> + let macroTypars, macroParamsCurried, macroBody, _rty = stripTopLambda (expr, tyOfExpr g expr) + let m = macroBody.Range + if not (isNil macroTypars) then + //warning(Error(FSComp.SR.stateMachineMacroTypars(), m)) + None + else + let macroParams = List.concat macroParamsCurried + let macroVal2 = mkLambdas m macroTypars macroParams (macroBody, tyOfExpr g macroBody) + if args.Length < macroParams.Length then + //warning(Error(FSComp.SR.stateMachineMacroUnderapplied(), m)) + None + else + let nowArgs, laterArgs = List.splitAt macroParams.Length args + let expandedExpr = MakeApplicationAndBetaReduce g (macroVal2, (tyOfExpr g macroVal2), [], nowArgs, m) + if sm_verbose then printfn "reduced application f = %A nowArgs= %A --> %A" macroVal2 nowArgs expandedExpr + if isNil laterArgs then + Some expandedExpr + else + if sm_verbose then printfn "application was partial, reducing further args %A" laterArgs + TryReduceApp env expandedExpr laterArgs + + | NewDelegateExpr g (_, macroParamsCurried, macroBody, _, _) -> + let m = expr.Range + let macroParams = List.concat macroParamsCurried + let macroVal2 = mkLambdas m [] macroParams (macroBody, tyOfExpr g macroBody) + if args.Length < macroParams.Length then + //warning(Error(FSComp.SR.stateMachineMacroUnderapplied(), m)) + None + else + let nowArgs, laterArgs = List.splitAt macroParams.Length args + let expandedExpr = MakeApplicationAndBetaReduce g (macroVal2, (tyOfExpr g macroVal2), [], nowArgs, m) + if sm_verbose then printfn "reduced application f = %A nowArgs= %A --> %A" macroVal2 nowArgs expandedExpr + if isNil laterArgs then + Some expandedExpr + else + if sm_verbose then printfn "application was partial, reducing further args %A" laterArgs + TryReduceApp env expandedExpr laterArgs + + | Expr.Let (bind, bodyExpr, m, _) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (mkLetBind m bind bodyExpr2) + | None -> None + + | Expr.LetRec (binds, bodyExpr, m, _) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (mkLetRecBinds m binds bodyExpr2) + | None -> None + + | Expr.Sequential (x1, bodyExpr, sp, ty, m) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (Expr.Sequential (x1, bodyExpr2, sp, ty, m)) + | None -> None + + // This construct arises from the 'mkDefault' in the 'Throw' case of an incomplete pattern match + | Expr.Const (Const.Zero, m, ty) -> + Some (Expr.Const (Const.Zero, m, ty)) + + | Expr.Match (spBind, exprm, dtree, targets, m, ty) -> + let mutable newTyOpt = None + let targets2 = + targets |> Array.choose (fun (TTarget(vs, targetExpr, spTarget, flags)) -> + // Incomplete exception matching expressions give rise to targets with I_throw. + // and System.Runtime.ExceptionServices.ExceptionDispatchInfo::Throw(...) + // + // Keep these in the residue. + // + // In theory the type of the expression should be adjusted but code generation doesn't record the + // type in the IL + let targetExpr2Opt = + match targetExpr, newTyOpt with + | Expr.Op (TOp.ILAsm ([ I_throw ], [_oldTy]), a, b, c), Some newTy -> + let targetExpr2 = Expr.Op (TOp.ILAsm ([ I_throw ], [newTy]), a, b, c) + Some targetExpr2 + | Expr.Sequential (Expr.Op (TOp.ILCall ( _, _, _, _, _, _, _, ilMethodRef, _, _, _), _, _, _) as e1, Expr.Const (Const.Zero, m, _oldTy), a, b, c), Some newTy when ilMethodRef.Name = "Throw" -> + let targetExpr2 = Expr.Sequential (e1, Expr.Const (Const.Zero, m, newTy), a, b, c) + Some targetExpr2 + | _ -> + + match TryReduceApp env targetExpr args with + | Some targetExpr2 -> + newTyOpt <- Some (tyOfExpr g targetExpr2) + Some targetExpr2 + | None -> + None + match targetExpr2Opt with + | Some targetExpr2 -> Some (TTarget(vs, targetExpr2, spTarget, flags)) + | None -> None) + if targets2.Length = targets.Length then + Some (Expr.Match (spBind, exprm, dtree, targets2, m, ty)) + else + None + + | WhileExpr (sp1, sp2, guardExpr, bodyExpr, m) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (mkWhile g (sp1, sp2, guardExpr, bodyExpr2, m)) + | None -> None + + | TryFinallyExpr (sp1, sp2, ty, bodyExpr, compensation, m) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (mkTryFinally g (bodyExpr2, compensation, m, ty, sp1, sp2)) + | None -> None + + | TryWithExpr (spTry, spWith, resTy, bodyExpr, filterVar, filterExpr, handlerVar, handlerExpr, m) -> + match TryReduceApp env bodyExpr args with + | Some bodyExpr2 -> Some (mkTryWith g (bodyExpr2, filterVar, filterExpr, handlerVar, handlerExpr, m, resTy, spTry, spWith)) + | None -> None + + | _ -> + None + + // Apply a single expansion of resumable code at the outermost position in an arbitrary expression + let rec TryReduceExpr (env: env) expr args remake = + if sm_verbose then printfn "expanding defns and reducing %A..." expr + //if sm_verbose then printfn "checking %A for possible resumable code application..." expr + match expr with + // defn --> [expand_code] + | Expr.Val (defnRef, _, _) when env.ResumableCodeDefns.ContainsVal defnRef.Deref -> + let defn = env.ResumableCodeDefns.[defnRef.Deref] + if sm_verbose then printfn "found resumable code %A --> %A" defnRef defn + // Expand the resumable code definition + match TryReduceApp env defn args with + | Some expandedExpr -> + if sm_verbose then printfn "expanded resumable code %A --> %A..." defnRef expandedExpr + Some expandedExpr + | None -> + Some (remake defn) + + // defn.Invoke x --> let arg = x in [defn][arg/x] + | ResumableCodeInvoke g (_, f, args2, _, rebuild) -> + if sm_verbose then printfn "found delegate invoke in possible reduction, f = %A, args now %A..." f (args2 @ args) + TryReduceExpr env f (args2 @ args) (fun f2 -> remake (rebuild (f2, args2))) + + // defn x --> let arg = x in [defn][arg/x] + | Expr.App (f, _fty, _tyargs, args2, _m) -> + if sm_verbose then printfn "found function invoke in possible reduction, f = %A, args now %A..." f (args2 @ args) + TryReduceExpr env f (args2 @ args) (fun f2 -> remake (Expr.App (f2, _fty, _tyargs, args2, _m))) + + | _ -> + //let (env, expr) = BindResumableCodeDefinitions env expr + match TryReduceApp env expr args with + | Some expandedExpr -> + if sm_verbose then printfn "reduction = %A, args = %A --> %A..." expr args expandedExpr + Some expandedExpr + | None -> + None + + // Repeated top-down rewrite + let makeRewriteEnv (env: env) = + { PreIntercept = Some (fun cont e -> match TryReduceExpr env e [] id with Some e2 -> Some (cont e2) | None -> None) + PostTransform = (fun _ -> None) + PreInterceptBinding = None + IsUnderQuotations=true } + + let ConvertStateMachineLeafExpression (env: env) expr = + if sm_verbose then printfn "ConvertStateMachineLeafExpression for %A..." expr + expr |> RewriteExpr (makeRewriteEnv env) + + let ConvertStateMachineLeafDecisionTree (env: env) expr = + if sm_verbose then printfn "ConvertStateMachineLeafDecisionTree for %A..." expr + expr |> RewriteDecisionTree (makeRewriteEnv env) + + /// Repeatedly find outermost expansion definitions and apply outermost expansions + let rec RepeatBindAndApplyOuterDefinitions (env: env) expr = + if sm_verbose then printfn "RepeatBindAndApplyOuterDefinitions for %A..." expr + let env2, expr2 = BindResumableCodeDefinitions env expr + match TryReduceExpr env2 expr2 [] id with + | Some res -> RepeatBindAndApplyOuterDefinitions env2 res + | None -> env2, expr2 + + // Detect a state machine with a single method override + let (|ExpandedStateMachineInContext|_|) inputExpr = + // All expanded resumable code state machines e.g. 'task { .. }' begin with a bind of @builder or 'defn' + let env, expr = BindResumableCodeDefinitions env.Empty inputExpr + match expr with + | StructStateMachineExpr g + (dataTy, + (moveNextThisVar, moveNextBody), + (setStateMachineThisVar, setStateMachineStateVar, setStateMachineBody), + (afterCodeThisVar, afterCodeBody)) -> + let templateStructTy = g.mk_ResumableStateMachine_ty dataTy + let env = { env with TemplateStructTy = Some templateStructTy } + if sm_verbose then printfn "Found struct machine..." + if sm_verbose then printfn "Found struct machine jump table call..." + let setStateMachineBodyR = ConvertStateMachineLeafExpression env setStateMachineBody + let afterCodeBodyR = ConvertStateMachineLeafExpression env afterCodeBody + let remake2 (moveNextExprR, stateVars, thisVars) = + if sm_verbose then + printfn "----------- AFTER REWRITE moveNextExprWithJumpTable ----------------------" + printfn "%s" (DebugPrint.showExpr g moveNextExprR) + printfn "----------- AFTER REWRITE setStateMachineBodyR ----------------------" + printfn "%s" (DebugPrint.showExpr g setStateMachineBodyR) + printfn "----------- AFTER REWRITE afterCodeBodyR ----------------------" + printfn "%s" (DebugPrint.showExpr g afterCodeBodyR) + LoweredStateMachine + (templateStructTy, dataTy, stateVars, thisVars, + (moveNextThisVar, moveNextExprR), + (setStateMachineThisVar, setStateMachineStateVar, setStateMachineBodyR), + (afterCodeThisVar, afterCodeBodyR)) + Some (env, remake2, moveNextBody) + | _ -> + None + + // A utility to add a jump table an expression + let addPcJumpTable m (pcs: int list) (pc2lab: Map) pcExpr expr = + if pcs.IsEmpty then + expr + else + let initLabel = generateCodeLabel() + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m ) + let mkGotoLabelTarget lab = mbuilder.AddResultTarget(Expr.Op (TOp.Goto lab, [], [], m), DebugPointAtTarget.No) + let dtree = + TDSwitch( + DebugPointAtSwitch.No, + pcExpr, + [ // Yield one target for each PC, where the action of the target is to goto the appropriate label + for pc in pcs do + yield mkCase(DecisionTreeTest.Const(Const.Int32 pc), mkGotoLabelTarget pc2lab.[pc]) ], + // The default is to go to pcInit + Some(mkGotoLabelTarget initLabel), + m) + + let table = mbuilder.Close(dtree, m, g.int_ty) + mkCompGenSequential m table (mkLabelled m initLabel expr) + + /// Detect constructs allowed in state machines + let rec ConvertResumableCode env (pcValInfo: ((Val * Expr) * Expr) option) expr : Result = + if sm_verbose then + printfn "---------ConvertResumableCode-------------------" + printfn "%s" (DebugPrint.showExpr g expr) + printfn "---------" + + let env, expr = RepeatBindAndApplyOuterDefinitions env expr + + if sm_verbose then + printfn "After RepeatBindAndApplyOuterDefinitions:\n%s" (DebugPrint.showExpr g expr) + printfn "---------" + + // Detect the different permitted constructs in the expanded state machine + let res = + match expr with + | ResumableCodeInvoke g (_, _, _, m, _) -> + Result.Error (FSComp.SR.reprResumableCodeInvokeNotReduced(m.ToShortString())) + + // Eliminate 'if __useResumableCode ...' within. + | IfUseResumableStateMachinesExpr g (thenExpr, _) -> + ConvertResumableCode env pcValInfo thenExpr + + | ResumableEntryMatchExpr g (noneBranchExpr, someVar, someBranchExpr, _rebuild) -> + ConvertResumableEntry env pcValInfo (noneBranchExpr, someVar, someBranchExpr, _rebuild) + + | ResumeAtExpr g pcExpr -> + ConvertResumableResumeAt env (pcExpr, expr.Range) + + // The expanded code for state machines may use sequential binding and sequential execution. + // + // let __stack_step = e1 in e2 + // e1; e2 + // + // A binding 'let .. = ... in ... ' is considered part of the state machine logic + // if it uses a binding variable starting with '__stack_*'. + // If this case 'e1' becomes part of the state machine too. + | SequentialResumableCode g (e1, e2, _m, recreate) -> + ConvertResumableSequential env pcValInfo (e1, e2, _m, recreate) + + // The expanded code for state machines may use while loops... + | WhileExpr (sp1, sp2, guardExpr, bodyExpr, m) -> + ConvertResumableWhile env pcValInfo (sp1, sp2, guardExpr, bodyExpr, m) + + // The expanded code for state machines should not normally contain try/finally as any resumptions will repeatedly execute the finally. + // However we include the synchronous version of the construct here for completeness. + | TryFinallyExpr (sp1, sp2, ty, e1, e2, m) -> + ConvertResumableTryFinally env pcValInfo (sp1, sp2, ty, e1, e2, m) + + // The expanded code for state machines may use for loops, however the + // body must be synchronous. + | ForLoopExpr (sp1, sp2, e1, e2, v, e3, m) -> + ConvertResumableFastIntegerForLoop env pcValInfo (sp1, sp2, e1, e2, v, e3, m) + + // The expanded code for state machines may use try/with.... + | TryWithExpr (spTry, spWith, resTy, bodyExpr, filterVar, filterExpr, handlerVar, handlerExpr, m) -> + ConvertResumableTryWith env pcValInfo (spTry, spWith, resTy, bodyExpr, filterVar, filterExpr, handlerVar, handlerExpr, m) + + // control-flow match + | Expr.Match (spBind, exprm, dtree, targets, m, ty) -> + ConvertResumableMatch env pcValInfo (spBind, exprm, dtree, targets, m, ty) + + // Non-control-flow let binding can appear as part of state machine. The body is considered state-machine code, + // the expression being bound is not. + | Expr.Let (bind, bodyExpr, m, _) + // Restriction: compilation of sequence expressions containing non-toplevel constrained generic functions is not supported + when bind.Var.IsCompiledAsTopLevel || not (IsGenericValWithGenericConstraints g bind.Var) -> + ConvertResumableLet env pcValInfo (bind, bodyExpr, m) + + | Expr.LetRec _ -> + Result.Error (FSComp.SR.reprResumableCodeContainsLetRec()) + + // Arbitrary expression + | _ -> + let exprR = ConvertStateMachineLeafExpression env expr + { phase1 = exprR + phase2 = (fun _ctxt -> exprR) + entryPoints = [] + stateVars = [] + thisVars = [] + resumableVars = emptyFreeVars } + |> Result.Ok + + if sm_verbose then + match res with + | Result.Ok res -> + printfn "-------------------" + printfn "Phase 1 Done for %s" (DebugPrint.showExpr g res.phase1) + printfn "Phase 1 Done, resumableVars = %A" (res.resumableVars.FreeLocals |> Zset.elements |> List.map (fun v -> v.CompiledName(g.CompilerGlobalState)) |> String.concat ",") + printfn "Phase 1 Done, stateVars = %A" (res.stateVars |> List.map (fun v -> v.CompiledName(g.CompilerGlobalState)) |> String.concat ",") + printfn "Phase 1 Done, thisVars = %A" (res.thisVars |> List.map (fun v -> v.CompiledName(g.CompilerGlobalState)) |> String.concat ",") + printfn "-------------------" + | Result.Error msg-> + printfn "Phase 1 failed: %s" msg + printfn "Phase 1 failed for %s" (DebugPrint.showExpr g expr) + res + + and ConvertResumableEntry env pcValInfo (noneBranchExpr, someVar, someBranchExpr, _rebuild) = + if sm_verbose then printfn "ResumableEntryMatchExpr" + // printfn "found sequential" + let reenterPC = genPC() + let envSome = { env with ResumableCodeDefns = env.ResumableCodeDefns.Add someVar (mkInt g someVar.Range reenterPC) } + let resNone = ConvertResumableCode env pcValInfo noneBranchExpr + let resSome = ConvertResumableCode envSome pcValInfo someBranchExpr + + match resNone, resSome with + | Result.Ok resNone, Result.Ok resSome -> + let resumableVars = unionFreeVars (freeInExpr CollectLocals resNone.phase1) resSome.resumableVars + let m = someBranchExpr.Range + let recreate reenterLabOpt e1 e2 = + let lab = (match reenterLabOpt with Some l -> l | _ -> generateCodeLabel()) + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m (tyOfExpr g noneBranchExpr) (mkFalse g m) (mkLabelled m lab e1) e2 + { phase1 = recreate None resNone.phase1 resSome.phase1 + phase2 = (fun ctxt -> + let generate2 = resSome.phase2 ctxt + let generate1 = resNone.phase2 ctxt + let generate = recreate (Some ctxt.[reenterPC]) generate1 generate2 + generate) + entryPoints= resSome.entryPoints @ [reenterPC] @ resNone.entryPoints + stateVars = resSome.stateVars @ resNone.stateVars + thisVars = resSome.thisVars @ resNone.thisVars + resumableVars = resumableVars } + |> Result.Ok + | Result.Error err, _ | _, Result.Error err -> Result.Error err + + and ConvertResumableResumeAt env (pcExpr , m)= + if sm_verbose then printfn "ResumeAtExpr" + // Macro-evaluate the pcExpr + let pcExprVal = ConvertStateMachineLeafExpression env pcExpr + match pcExprVal with + | Int32Expr contIdPC -> + let recreate contLabOpt = + Expr.Op (TOp.Goto (match contLabOpt with Some l -> l | _ -> generateCodeLabel()), [], [], m) + + { phase1 = recreate None + phase2 = (fun ctxt -> + let generate = recreate (Some ctxt.[contIdPC]) + generate) + entryPoints = [] + stateVars = [] + thisVars = [] + resumableVars = emptyFreeVars } + |> Result.Ok + | _ -> + Result.Error(FSComp.SR.reprResumableCodeContainsDynamicResumeAtInBody()) + + and ConvertResumableSequential env pcValInfo (e1, e2, _m, recreate) = + if sm_verbose then printfn "SequentialResumableCode" + // printfn "found sequential" + let res1 = ConvertResumableCode env pcValInfo e1 + let res2 = ConvertResumableCode env pcValInfo e2 + match res1, res2 with + | Result.Ok res1, Result.Ok res2 -> + let resumableVars = + if res1.entryPoints.IsEmpty then + // res1 is synchronous + res2.resumableVars + else + // res1 is not synchronous. All of 'e2' is needed after resuming at any of the labels + unionFreeVars res1.resumableVars (freeInExpr CollectLocals res2.phase1) + + { phase1 = recreate res1.phase1 res2.phase1 + phase2 = (fun ctxt -> + let generate1 = res1.phase2 ctxt + let generate2 = res2.phase2 ctxt + let generate = recreate generate1 generate2 + generate) + entryPoints= res1.entryPoints @ res2.entryPoints + stateVars = res1.stateVars @ res2.stateVars + thisVars = res1.thisVars @ res2.thisVars + resumableVars = resumableVars } + |> Result.Ok + | Result.Error err, _ | _, Result.Error err -> Result.Error err + + and ConvertResumableWhile env pcValInfo (sp1, sp2, guardExpr, bodyExpr, m) = + if sm_verbose then printfn "WhileExpr" + + let resg = ConvertResumableCode env pcValInfo guardExpr + let resb = ConvertResumableCode env pcValInfo bodyExpr + match resg, resb with + | Result.Ok resg, Result.Ok resb -> + let eps = resg.entryPoints @ resb.entryPoints + // All free variables get captured if there are any entrypoints at all + let resumableVars = if eps.IsEmpty then emptyFreeVars else unionFreeVars (freeInExpr CollectLocals resg.phase1) (freeInExpr CollectLocals resb.phase1) + { phase1 = mkWhile g (sp1, sp2, resg.phase1, resb.phase1, m) + phase2 = (fun ctxt -> + let egR = resg.phase2 ctxt + let ebR = resb.phase2 ctxt + + // Clear the pcVal on backward branch, causing jump tables at entry to nested try-blocks to not activate + let ebR2 = + match pcValInfo with + | None -> ebR + | Some ((pcVal, _), _) -> + mkCompGenThenDoSequential m + ebR + (mkValSet m (mkLocalValRef pcVal) (mkZero g m)) + + mkWhile g (sp1, sp2, egR, ebR2, m)) + entryPoints= eps + stateVars = resg.stateVars @ resb.stateVars + thisVars = resg.thisVars @ resb.thisVars + resumableVars = resumableVars } + |> Result.Ok + | Result.Error err, _ | _, Result.Error err -> Result.Error err + + and ConvertResumableTryFinally env pcValInfo (sp1, sp2, ty, e1, e2, m) = + if sm_verbose then printfn "TryFinallyExpr" + let res1 = ConvertResumableCode env pcValInfo e1 + let res2 = ConvertResumableCode env pcValInfo e2 + match res1, res2 with + | Result.Ok res1, Result.Ok res2 -> + let eps = res1.entryPoints @ res2.entryPoints + if eps.Length > 0 then + Result.Error (FSComp.SR.reprResumableCodeContainsResumptionInTryFinally()) + else + { phase1 = mkTryFinally g (res1.phase1, res2.phase1, m, ty, sp1, sp2) + phase2 = (fun ctxt -> + let egR = res1.phase2 ctxt + let ebR = res2.phase2 ctxt + mkTryFinally g (egR, ebR, m, ty, sp1, sp2)) + entryPoints= eps + stateVars = res1.stateVars @ res2.stateVars + thisVars = res1.thisVars @ res2.thisVars + resumableVars = emptyFreeVars (* eps is empty, hence synchronous, no capture *) } + |> Result.Ok + | Result.Error err, _ | _, Result.Error err -> Result.Error err + + and ConvertResumableFastIntegerForLoop env pcValInfo (sp1, sp2, e1, e2, v, e3, m) = + if sm_verbose then printfn "ForLoopExpr" + let res1 = ConvertResumableCode env pcValInfo e1 + let res2 = ConvertResumableCode env pcValInfo e2 + let res3 = ConvertResumableCode env pcValInfo e3 + match res1, res2, res3 with + | Result.Ok res1, Result.Ok res2, Result.Ok res3 -> + let eps = res1.entryPoints @ res2.entryPoints @ res3.entryPoints + if eps.Length > 0 then + Result.Error(FSComp.SR.reprResumableCodeContainsFastIntegerForLoop()) + else + { phase1 = mkFor g (sp1, v, res1.phase1, sp2, res2.phase1, res3.phase1, m) + phase2 = (fun ctxt -> + let e1R = res1.phase2 ctxt + let e2R = res2.phase2 ctxt + let e3R = res3.phase2 ctxt + + // Clear the pcVal on backward branch, causing jump tables at entry to nested try-blocks to not activate + let e3R2 = + match pcValInfo with + | None -> e3R + | Some ((pcVal, _), _) -> + mkCompGenThenDoSequential m + e3R + (mkValSet m (mkLocalValRef pcVal) (mkZero g m)) + + mkFor g (sp1, v, e1R, sp2, e2R, e3R2, m)) + entryPoints= eps + stateVars = res1.stateVars @ res2.stateVars @ res3.stateVars + thisVars = res1.thisVars @ res2.thisVars @ res3.thisVars + resumableVars = emptyFreeVars (* eps is empty, hence synchronous, no capture *) } + |> Result.Ok + | Result.Error err, _, _ | _, Result.Error err, _ | _, _, Result.Error err -> Result.Error err + + and ConvertResumableTryWith env pcValInfo (spTry, spWith, resTy, bodyExpr, filterVar, filterExpr, handlerVar, handlerExpr, m) = + if sm_verbose then printfn "TryWithExpr" + let resBody = ConvertResumableCode env pcValInfo bodyExpr + let resFilter = ConvertResumableCode env pcValInfo filterExpr + let resHandler = ConvertResumableCode env pcValInfo handlerExpr + match resBody, resFilter, resHandler with + | Result.Ok resBody, Result.Ok resFilter, Result.Ok resHandler -> + let epsNope = resFilter.entryPoints @ resHandler.entryPoints + if epsNope.Length > 0 then + Result.Error(FSComp.SR.reprResumableCodeContainsResumptionInHandlerOrFilter()) + else + { phase1 = mkTryWith g (resBody.phase1, filterVar, resFilter.phase1, handlerVar, resHandler.phase1, m, resTy, spTry, spWith) + phase2 = (fun ctxt -> + // We can't jump into a try/catch block. So we jump to the start of the try/catch and add a new jump table + let pcsAndLabs = ctxt |> Map.toList + let innerPcs = resBody.entryPoints + if innerPcs.IsEmpty then + let vBodyR = resBody.phase2 ctxt + let filterExprR = resFilter.phase2 ctxt + let handlerExprR = resHandler.phase2 ctxt + mkTryWith g (vBodyR, filterVar, filterExprR, handlerVar, handlerExprR, m, resTy, spTry, spWith) + else + let innerPcSet = innerPcs |> Set.ofList + let outerLabsForInnerPcs = pcsAndLabs |> List.filter (fun (pc, _outerLab) -> innerPcSet.Contains pc) |> List.map snd + // generate the inner labels + let pcsAndInnerLabs = pcsAndLabs |> List.map (fun (pc, l) -> (pc, if innerPcSet.Contains pc then generateCodeLabel() else l)) + let innerPc2Lab = Map.ofList pcsAndInnerLabs + + let vBodyR = resBody.phase2 innerPc2Lab + let filterExprR = resFilter.phase2 ctxt + let handlerExprR = resHandler.phase2 ctxt + + // Add a jump table at the entry to the try + let vBodyRWithJumpTable = + match pcValInfo with + | None -> vBodyR + | Some ((_, pcValExpr), _) -> addPcJumpTable m innerPcs innerPc2Lab pcValExpr vBodyR + let coreExpr = mkTryWith g (vBodyRWithJumpTable, filterVar, filterExprR, handlerVar, handlerExprR, m, resTy, spTry, spWith) + // Place all the outer labels just before the try + let labelledExpr = (coreExpr, outerLabsForInnerPcs) ||> List.fold (fun e l -> mkLabelled m l e) + + labelledExpr) + entryPoints= resBody.entryPoints @ resFilter.entryPoints @ resHandler.entryPoints + stateVars = resBody.stateVars @ resFilter.stateVars @ resHandler.stateVars + thisVars = resBody.thisVars @ resFilter.thisVars @ resHandler.thisVars + resumableVars = unionFreeVars resBody.resumableVars (unionFreeVars(freeInExpr CollectLocals resFilter.phase1) (freeInExpr CollectLocals resHandler.phase1)) } + |> Result.Ok + | Result.Error err, _, _ | _, Result.Error err, _ | _, _, Result.Error err -> Result.Error err + + and ConvertResumableMatch env pcValInfo (spBind, exprm, dtree, targets, m, ty) = + if sm_verbose then printfn "MatchExpr" + // lower all the targets. + let dtreeR = ConvertStateMachineLeafDecisionTree env dtree + let tglArray = + targets |> Array.map (fun (TTarget(_vs, targetExpr, _spTarget, _)) -> + ConvertResumableCode env pcValInfo targetExpr) + match (tglArray |> Array.forall (function Result.Ok _ -> true | Result.Error _ -> false)) with + | true -> + let tglArray = tglArray |> Array.map (function Result.Ok v -> v | _ -> failwith "unreachable") + let tgl = tglArray |> Array.toList + let entryPoints = tgl |> List.collect (fun res -> res.entryPoints) + let resumableVars = + (emptyFreeVars, Array.zip targets tglArray) + ||> Array.fold (fun fvs (TTarget(_vs, _, _spTarget, _), res) -> + if res.entryPoints.IsEmpty then fvs else unionFreeVars fvs res.resumableVars) + let stateVars = + (targets, tglArray) ||> Array.zip |> Array.toList |> List.collect (fun (TTarget(vs, _, _, _), res) -> + let stateVars = vs |> List.filter (fun v -> res.resumableVars.FreeLocals.Contains(v)) |> List.map mkLocalValRef + stateVars @ res.stateVars) + let thisVars = tglArray |> Array.toList |> List.collect (fun res -> res.thisVars) + { phase1 = + let gtgs = + (targets, tglArray) ||> Array.map2 (fun (TTarget(vs, _, spTarget, _)) res -> + let flags = vs |> List.map (fun v -> res.resumableVars.FreeLocals.Contains(v)) + TTarget(vs, res.phase1, spTarget, Some flags)) + primMkMatch (spBind, exprm, dtreeR, gtgs, m, ty) + + phase2 = (fun ctxt -> + let gtgs = + (targets, tglArray) ||> Array.map2 (fun (TTarget(vs, _, spTarget, _)) res -> + let flags = vs |> List.map (fun v -> res.resumableVars.FreeLocals.Contains(v)) + TTarget(vs, res.phase2 ctxt, spTarget, Some flags)) + let generate = primMkMatch (spBind, exprm, dtreeR, gtgs, m, ty) + generate) + + entryPoints = entryPoints + stateVars = stateVars + resumableVars = resumableVars + thisVars = thisVars } + |> Result.Ok + | _ -> tglArray |> Array.find (function Result.Ok _ -> false | Result.Error _ -> true) + + and ConvertResumableLet env pcValInfo (bind, bodyExpr, m) = + // Non-control-flow let binding can appear as part of state machine. The body is considered state-machine code, + // the expression being bound is not. + if sm_verbose then printfn "LetExpr (non-control-flow, rewrite rhs)" + + // Rewrite the expression on the r.h.s. of the binding + let bindExpr = ConvertStateMachineLeafExpression env bind.Expr + let bind = mkBind bind.DebugPoint bind.Var bindExpr + if sm_verbose then printfn "LetExpr (non-control-flow, body)" + + let resBody = ConvertResumableCode env pcValInfo bodyExpr + + match resBody with + | Result.Ok resBody -> + // The isByrefTy check is an adhoc check to avoid capturing the 'this' parameter of a struct state machine + // You might think we could do this: + // + // let sm = &this + // ... await point ... + // ... sm .... + // However the 'sm' won't be set on that path. + if isByrefTy g bind.Var.Type && + (match env.TemplateStructTy with + | None -> false + | Some ty -> typeEquiv g ty (destByrefTy g bind.Var.Type)) then + RepresentBindingAsThis bind resBody m + |> Result.Ok + elif bind.Var.IsCompiledAsTopLevel || + not (resBody.resumableVars.FreeLocals.Contains(bind.Var)) || + bind.Var.LogicalName.StartsWith stackVarPrefix then + if sm_verbose then printfn "LetExpr (non-control-flow, rewrite rhs, RepresentBindingAsTopLevelOrLocal)" + RepresentBindingAsTopLevelOrLocal bind resBody m + |> Result.Ok + else + if sm_verbose then printfn "LetExpr (non-control-flow, rewrite rhs, RepresentBindingAsStateVar)" + // printfn "found state variable %s" bind.Var.DisplayName + RepresentBindingAsStateVar g bind resBody m + |> Result.Ok + | Result.Error msg -> + Result.Error msg + + member _.Apply(overallExpr, altExprOpt) = + + let fallback msg = + match altExprOpt with + | None -> + LoweredStateMachineResult.NoAlternative msg + | Some altExpr -> + LoweredStateMachineResult.UseAlternative (msg, altExpr) + + match overallExpr with + | ExpandedStateMachineInContext (env, remake, moveNextExpr) -> + let m = moveNextExpr.Range + match moveNextExpr with + | OptionalResumeAtExpr g (pcExprOpt, codeExpr) -> + let env, codeExprR = RepeatBindAndApplyOuterDefinitions env codeExpr + let frees = (freeInExpr CollectLocals overallExpr).FreeLocals + + if frees |> Zset.exists (isExpandVar g) then + let nonfree = frees |> Zset.elements |> List.filter (isExpandVar g) |> List.map (fun v -> v.DisplayName) |> String.concat "," + let msg = FSComp.SR.reprResumableCodeValueHasNoDefinition(nonfree) + fallback msg + else + let pcExprROpt = pcExprOpt |> Option.map (ConvertStateMachineLeafExpression env) + let pcValInfo = + match pcExprROpt with + | None -> None + | Some e -> Some (mkMutableCompGenLocal e.Range "pcVal" g.int32_ty, e) + + if sm_verbose then + printfn "Found state machine override method and code expression..." + printfn "----------- OVERALL EXPRESSION FOR STATE MACHINE CONVERSION ----------------------" + printfn "%s" (DebugPrint.showExpr g overallExpr) + printfn "----------- INPUT TO STATE MACHINE CONVERSION ----------------------" + printfn "%s" (DebugPrint.showExpr g codeExpr) + printfn "----------- START STATE MACHINE CONVERSION ----------------------" + + // Perform phase1 of the conversion + let phase1 = ConvertResumableCode env pcValInfo codeExprR + match phase1 with + | Result.Error msg -> + fallback msg + | Result.Ok phase1 -> + + // Work out the initial mapping of pcs to labels + let pcs = [ 1 .. pcCount ] + let labs = pcs |> List.map (fun _ -> generateCodeLabel()) + let pc2lab = Map.ofList (List.zip pcs labs) + + // Execute phase2, building the core of the method + if sm_verbose then printfn "----------- PHASE2 ----------------------" + + // Perform phase2 to build the final expression + let moveNextExprR = phase1.phase2 pc2lab + + if sm_verbose then printfn "----------- ADDING JUMP TABLE ----------------------" + + // Add the jump table + let moveNextExprWithJumpTable = + match pcValInfo with + | None -> moveNextExprR + | Some ((v,pcValExprR),pcExprR) -> mkCompGenLet m v pcExprR (addPcJumpTable m pcs pc2lab pcValExprR moveNextExprR) + + if sm_verbose then printfn "----------- REMAKE ----------------------" + + // Build the result + let res = remake (moveNextExprWithJumpTable, phase1.stateVars, phase1.thisVars) + LoweredStateMachineResult.Lowered res + + | _ -> + let msg = FSComp.SR.reprStateMachineInvalidForm() + fallback msg + +let LowerStateMachineExpr g (overallExpr: Expr) : LoweredStateMachineResult = + // Detect a state machine and convert it + let stateMachine = IsStateMachineExpr g overallExpr + + match stateMachine with + | None -> LoweredStateMachineResult.NotAStateMachine + | Some altExprOpt -> + + LowerStateMachine(g).Apply(overallExpr, altExprOpt) diff --git a/src/fsharp/LowerStateMachines.fsi b/src/fsharp/LowerStateMachines.fsi new file mode 100644 index 00000000000..5a37c4ada6f --- /dev/null +++ b/src/fsharp/LowerStateMachines.fsi @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.LowerStateMachines + +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TcGlobals + +type LoweredStateMachine = + LoweredStateMachine of + templateStructTy: TType * + dataTy: TType * + stateVars: ValRef list * + thisVars: ValRef list * + moveNext: (Val * Expr) * + setStateMachine: (Val * Val * Expr) * + afterCode: (Val * Expr) + +type LoweredStateMachineResult = + /// A state machine was recognised and was compilable + | Lowered of LoweredStateMachine + + /// A state machine was recognised and was not compilable and an alternative is available + | UseAlternative of message: string * alternativeExpr: Expr + + /// A state machine was recognised and was not compilable and no alternative is available + | NoAlternative of message: string + + /// The construct was not a state machine + | NotAStateMachine + +/// Analyze a TAST expression to detect the elaborated form of a state machine expression, a special kind +/// of object expression that uses special code generation constructs. +val LowerStateMachineExpr: + g: TcGlobals -> + overallExpr: Expr -> + LoweredStateMachineResult + diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 37f031e7824..3367224af9d 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -3,30 +3,35 @@ /// Logic associated with resolving method calls. module internal FSharp.Compiler.MethodCalls +open Internal.Utilities + +open Internal.Utilities.Library open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.AttributeChecking open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Lib +open FSharp.Compiler.Features +open FSharp.Compiler.InfoReader open FSharp.Compiler.Infos -open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.IO open FSharp.Compiler.NameResolution -open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint open FSharp.Compiler.TypeRelations -open FSharp.Compiler.AttributeChecking -open Internal.Utilities #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping #endif - //------------------------------------------------------------------------- // Sets of methods involved in overload resolution and trait constraint // satisfaction. @@ -42,18 +47,22 @@ open FSharp.Compiler.ExtensionTyping /// expression, e.g. a lambda expression may be converted to a delegate as /// an adhoc conversion. /// -/// The bool indicates if named using a '?' +/// The bool indicates if named using a '?', making the caller argument explicit-optional type CallerArg<'T> = /// CallerArg(ty, range, isOpt, exprInfo) - | CallerArg of TType * range * bool * 'T - member x.Type = (let (CallerArg(ty, _, _, _)) = x in ty) + | CallerArg of ty: TType * range: range * isOpt: bool * exprInfo: 'T + + member x.CallerArgumentType = (let (CallerArg(ty, _, _, _)) = x in ty) + member x.Range = (let (CallerArg(_, m, _, _)) = x in m) - member x.IsOptional = (let (CallerArg(_, _, isOpt, _)) = x in isOpt) + + member x.IsExplicitOptional = (let (CallerArg(_, _, isOpt, _)) = x in isOpt) + member x.Expr = (let (CallerArg(_, _, _, expr)) = x in expr) /// Represents the information about an argument in the method being called type CalledArg = - { Position: (int * int) + { Position: struct (int * int) IsParamArray : bool OptArgInfo : OptionalArgInfo CallerInfo : CallerInfo @@ -77,12 +86,16 @@ let CalledArg (pos, isParamArray, optArgInfo, callerInfo, isInArg, isOutArg, nam /// Represents a match between a caller argument and a called argument, arising from either /// a named argument or an unnamed argument. type AssignedCalledArg<'T> = + { /// The identifier for a named argument, if any NamedArgIdOpt : Ident option + /// The called argument in the method CalledArg: CalledArg + /// The argument on the caller side CallerArg: CallerArg<'T> } + member x.Position = x.CalledArg.Position /// Represents the possibilities for a named-setter argument (a property, field, or a record field setter) @@ -96,16 +109,274 @@ type AssignedItemSetter<'T> = AssignedItemSetter of Ident * AssignedItemSetterTa type CallerNamedArg<'T> = | CallerNamedArg of Ident * CallerArg<'T> + member x.Ident = (let (CallerNamedArg(id, _)) = x in id) + member x.Name = x.Ident.idText + member x.CallerArg = (let (CallerNamedArg(_, a)) = x in a) +/// Represents the list of unnamed / named arguments at method call site +/// remark: The usage of list list is due to tupling and currying of arguments, +/// stemming from SynValInfo in the AST. +[] +type CallerArgs<'T> = + { + Unnamed: CallerArg<'T> list list + Named: CallerNamedArg<'T> list list + } + static member Empty : CallerArgs<'T> = { Unnamed = []; Named = [] } + member x.CallerArgCounts = List.length x.Unnamed, List.length x.Named + member x.CurriedCallerArgs = List.zip x.Unnamed x.Named + member x.ArgumentNamesAndTypes = + let unnamed = x.Unnamed |> List.collect (List.map (fun i -> None, i.CallerArgumentType)) + let named = x.Named |> List.collect (List.map (fun i -> Some i.Name, i.CallerArg.CallerArgumentType)) + unnamed @ named + //------------------------------------------------------------------------- // Callsite conversions //------------------------------------------------------------------------- -// F# supports three adhoc conversions at method callsites (note C# supports more, though ones -// such as implicit conversions interact badly with type inference). +let AdjustDelegateTy (infoReader: InfoReader) actualTy reqdTy m = + let g = infoReader.g + let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader reqdTy m AccessibleFromSomewhere + let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys + if (fst (stripFunTy g actualTy)).Length = delArgTys.Length then + fty + else + reqdTy + + +// Adhoc based on op_Implicit +// +// NOTE: +// no generic method op_Implicit as yet +// +// Search for an adhoc conversion based on op_Implicit, optionally returing a new equational type constraint to +// eliminate articifical constrained type variables. +// +// Allow adhoc for X --> Y where there is an op_Implicit from X to Y, and there is +// no feasible subtype relationship between X and Y. +// +// Also allow adhoc for X --> ? where the ? is a type inference variable constrained +// by a coercion constraint to Y for which there is an op_Implicit from X to Y, and there is +// no feasible subtype relationship between X and Y. +// +// Implicit conversions are only activated if the types precisely match based on known type information +// at the point of resolution. For example +// let f (x: 'T) : Nullable<'T> = x +// is enough, whereas +// let f (x: 'T) : Nullable<_> = x +// let f x : Nullable<'T> = x +// are not enough to activate. + +let TryFindRelevantImplicitConversion (infoReader: InfoReader) ad reqdTy actualTy m = + let g = infoReader.g + let amap = infoReader.amap + if g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions then + + // shortcut + if typeEquiv g reqdTy actualTy then None else + let reqdTy2 = + if isTyparTy g reqdTy then + let tp = destTyparTy g reqdTy + match tp.Constraints |> List.choose (function TyparConstraint.CoercesTo (c, _) -> Some c | _ -> None) with + | [reqdTy2] when tp.Rigidity = TyparRigidity.Flexible -> reqdTy2 + | _ -> reqdTy + else reqdTy + + // Implicit conversions only activate if a precise implicit conversion exists and: + // 1. no feasible subtype relationship between X and Y (an approximation), OR + // 2. T --> some-type-containing-precisely-T + // Note that even for (2) implicit conversions are still only activated if the + // types *precisely* and *completely* match based on *known* type information at the point of resolution. + + if not (isTyparTy g reqdTy2) && + (not (TypeFeasiblySubsumesType 0 g amap m reqdTy2 CanCoerce actualTy) || + isTyparTy g actualTy && (let ftyvs = freeInType CollectAll reqdTy2 in ftyvs.FreeTypars.Contains(destTyparTy g actualTy))) then + + let implicits = + infoReader.FindImplicitConversions m ad actualTy @ + infoReader.FindImplicitConversions m ad reqdTy2 + + let implicits = + implicits |> List.filter (fun minfo -> + not minfo.IsInstance && + minfo.FormalMethodTyparInst.IsEmpty && + (match minfo.GetParamTypes(amap, m, []) with + | [[a]] -> typeEquiv g a actualTy + | _ -> false) && + (let rty = minfo.GetFSharpReturnTy(amap, m, []) + typeEquiv g rty reqdTy2) + ) + + match implicits with + | [minfo] -> + Some (minfo, (reqdTy, reqdTy2, ignore)) + | minfo :: _ -> + Some (minfo, (reqdTy, reqdTy2, fun denv -> + let reqdTy2Text, actualTyText, _cxs = NicePrint.minimalStringsOfTwoTypes denv reqdTy2 actualTy + let implicitsText = NicePrint.multiLineStringOfMethInfos infoReader m denv implicits + errorR(Error(FSComp.SR.tcAmbiguousImplicitConversion(actualTyText, reqdTy2Text, implicitsText), m)))) + | _ -> None + else + None + else + None + +[] +type TypeDirectedConversion = + | BuiltIn + | Implicit of MethInfo + +[] +type TypeDirectedConversionUsed = + | Yes of (DisplayEnv -> exn) + | No + static member Combine a b = + match a with + | Yes _ -> a + | No -> b + +let MapCombineTDCD mapper xs = + MapReduceD mapper TypeDirectedConversionUsed.No TypeDirectedConversionUsed.Combine xs + +let MapCombineTDC2D mapper xs ys = + MapReduce2D mapper TypeDirectedConversionUsed.No TypeDirectedConversionUsed.Combine xs ys + +let rec AdjustRequiredTypeForTypeDirectedConversions (infoReader: InfoReader) ad isMethodArg isConstraint (reqdTy: TType) actualTy m = + let g = infoReader.g + + let warn info denv = + let reqdTyText, actualTyText, _cxs = NicePrint.minimalStringsOfTwoTypes denv reqdTy actualTy + match info with + | TypeDirectedConversion.BuiltIn -> + Error(FSComp.SR.tcBuiltInImplicitConversionUsed(actualTyText, reqdTyText), m) + | TypeDirectedConversion.Implicit convMeth -> + let methText = NicePrint.stringOfMethInfo infoReader m denv convMeth + if isMethodArg then + Error(FSComp.SR.tcImplicitConversionUsedForMethodArg(methText, actualTyText, reqdTyText), m) + else + Error(FSComp.SR.tcImplicitConversionUsedForNonMethodArg(methText, actualTyText, reqdTyText), m) + + if isConstraint then + reqdTy, TypeDirectedConversionUsed.No, None + else + + // Delegate --> function + if isDelegateTy g reqdTy && isFunTy g actualTy then + AdjustDelegateTy infoReader actualTy reqdTy m, TypeDirectedConversionUsed.No, None + + // (T -> U) --> Expression U> LINQ-style quotation + elif isLinqExpressionTy g reqdTy && isDelegateTy g (destLinqExpressionTy g reqdTy) && isFunTy g actualTy then + let delegateTy = destLinqExpressionTy g reqdTy + AdjustRequiredTypeForTypeDirectedConversions infoReader ad isMethodArg isConstraint delegateTy actualTy m + + // Adhoc int32 --> int64 + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.int64_ty reqdTy && typeEquiv g g.int32_ty actualTy then + g.int32_ty, TypeDirectedConversionUsed.Yes(warn TypeDirectedConversion.BuiltIn), None + + // Adhoc int32 --> nativeint + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.nativeint_ty reqdTy && typeEquiv g g.int32_ty actualTy then + g.int32_ty, TypeDirectedConversionUsed.Yes(warn TypeDirectedConversion.BuiltIn), None + + // Adhoc int32 --> float64 + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.float_ty reqdTy && typeEquiv g g.int32_ty actualTy then + g.int32_ty, TypeDirectedConversionUsed.Yes(warn TypeDirectedConversion.BuiltIn), None + + // Adhoc based on op_Implicit, perhaps returing a new equational type constraint to + // eliminate articifical constrained type variables. + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions then + match TryFindRelevantImplicitConversion infoReader ad reqdTy actualTy m with + | Some (minfo, eqn) -> actualTy, TypeDirectedConversionUsed.Yes(warn (TypeDirectedConversion.Implicit minfo)), Some eqn + | None -> reqdTy, TypeDirectedConversionUsed.No, None + + else reqdTy, TypeDirectedConversionUsed.No, None + +// If the called method argument is a delegate type, and the caller is known to be a function type, then the caller may provide a function +// If the called method argument is an Expression type, and the caller is known to be a function type, then the caller may provide a T +// If the called method argument is an [] Quotations.Expr, and the caller is not known to be a quoted expression type, then the caller may provide a T +let AdjustCalledArgTypeForTypeDirectedConversionsAndAutoQuote (infoReader: InfoReader) ad (callerArgTy: TType) calledArgTy (calledArg: CalledArg) m = + let g = infoReader.g + + if calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then + destQuotedExprTy g calledArgTy, TypeDirectedConversionUsed.No, None + else + AdjustRequiredTypeForTypeDirectedConversions infoReader ad true false calledArgTy callerArgTy m + +/// Adjust the called argument type to take into account whether the caller's argument is CSharpMethod(?arg=Some(3)) or CSharpMethod(arg=1) +let AdjustCalledArgTypeForOptionals (infoReader: InfoReader) ad enforceNullableOptionalsKnownTypes (calledArg: CalledArg) calledArgTy (callerArg: CallerArg<_>) = + let g = infoReader.g + let m = callerArg.Range + + let callerArgTy = callerArg.CallerArgumentType + if callerArg.IsExplicitOptional then + match calledArg.OptArgInfo with + // CSharpMethod(?x = arg), optional C#-style argument, may have nullable type + | CallerSide _ -> + if g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop then + if isNullableTy g calledArgTy then + mkOptionTy g (destNullableTy g calledArgTy), TypeDirectedConversionUsed.No, None + else + mkOptionTy g calledArgTy, TypeDirectedConversionUsed.No, None + else + calledArgTy, TypeDirectedConversionUsed.No, None + + // FSharpMethod(?x = arg), optional F#-style argument + | CalleeSide -> + // In this case, the called argument will already have option type + calledArgTy, TypeDirectedConversionUsed.No, None + + | NotOptional -> + // This condition represents an error but the error is raised in later processing + AdjustCalledArgTypeForTypeDirectedConversionsAndAutoQuote infoReader ad callerArgTy calledArgTy calledArg m + else + match calledArg.OptArgInfo with + // CSharpMethod(x = arg), non-optional C#-style argument, may have type Nullable. + | NotOptional when not (g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop) -> + AdjustCalledArgTypeForTypeDirectedConversionsAndAutoQuote infoReader ad callerArgTy calledArgTy calledArg m + + // The arg should have type ty. However for backwards compat, we also allow arg to have type Nullable + | NotOptional + // CSharpMethod(x = arg), optional C#-style argument, may have type Nullable. + | CallerSide _ -> + if isNullableTy g calledArgTy && g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop then + // If inference has worked out it's a nullable then use this + if isNullableTy g callerArgTy then + calledArgTy, TypeDirectedConversionUsed.No, None + + // If inference has worked out it's a struct (e.g. an int) then use this + elif isStructTy g callerArgTy then + let calledArgTy2 = destNullableTy g calledArgTy + AdjustRequiredTypeForTypeDirectedConversions infoReader ad true false calledArgTy2 callerArgTy m + + // If neither and we are at the end of overload resolution then use the Nullable + elif enforceNullableOptionalsKnownTypes then + calledArgTy, TypeDirectedConversionUsed.No, None + + // If at the beginning of inference then use a type variable. + else + match calledArg.OptArgInfo with + // If inference has not solved the kind of Nullable on the called arg and is not optional then use this. + | NotOptional when isTyparTy g (destNullableTy g calledArgTy) -> + calledArgTy, TypeDirectedConversionUsed.No, None + | _ -> + let compgenId = mkSynId range0 unassignedTyparName + let tp = mkTyparTy (Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, SynTypar(compgenId, TyparStaticReq.None, true), false, TyparDynamicReq.No, [], false, false)) + tp, TypeDirectedConversionUsed.No, None + else + AdjustCalledArgTypeForTypeDirectedConversionsAndAutoQuote infoReader ad callerArgTy calledArgTy calledArg m + + // FSharpMethod(x = arg), optional F#-style argument, should have option type + | CalleeSide -> + let calledArgTy2 = + if isOptionTy g calledArgTy then + destOptionTy g calledArgTy + else + calledArgTy + AdjustCalledArgTypeForTypeDirectedConversionsAndAutoQuote infoReader ad callerArgTy calledArgTy2 calledArg m + +// F# supports adhoc conversions at some specific points // // 1. The use of "(fun x y -> ...)" when a delegate it expected. This is not part of // the ":>" coercion relationship or inference constraint problem as @@ -122,15 +393,16 @@ type CallerNamedArg<'T> = // and record the presence of the syntax "&e" in the pre-inferred actual type for the method argument. // The function AdjustCalledArgType detects this and refuses to apply the default byref-to-ref transformation. // +// 4. Other type directed conversions in 'AdjustRequiredTypeForTypeDirectedConversions' +// // The function AdjustCalledArgType also adjusts for optional arguments. -let AdjustCalledArgType (infoReader: InfoReader) isConstraint (calledArg: CalledArg) (callerArg: CallerArg<_>) = +let AdjustCalledArgType (infoReader: InfoReader) ad isConstraint enforceNullableOptionalsKnownTypes (calledArg: CalledArg) (callerArg: CallerArg<_>) = let g = infoReader.g // #424218 - when overload resolution is part of constraint solving - do not perform type-directed conversions let calledArgTy = calledArg.CalledArgumentType - let callerArgTy = callerArg.Type - let m = callerArg.Range + let callerArgTy = callerArg.CallerArgumentType if isConstraint then - calledArgTy + calledArgTy, TypeDirectedConversionUsed.No, None else // If the called method argument is an inref type, then the caller may provide a byref or value @@ -141,58 +413,18 @@ let AdjustCalledArgType (infoReader: InfoReader) isConstraint (calledArg: Called else destByrefTy g calledArgTy #else - calledArgTy + calledArgTy, TypeDirectedConversionUsed.No, None #endif // If the called method argument is a (non inref) byref type, then the caller may provide a byref or ref. elif isByrefTy g calledArgTy then if isByrefTy g callerArgTy then - calledArgTy + calledArgTy, TypeDirectedConversionUsed.No, None else - mkRefCellTy g (destByrefTy g calledArgTy) + mkRefCellTy g (destByrefTy g calledArgTy), TypeDirectedConversionUsed.No, None else - // If the called method argument is a delegate type, and the caller is known to be a function type, then the caller may provide a function - // If the called method argument is an Expression type, and the caller is known to be a function type, then the caller may provide a T - // If the called method argument is an [] Quotations.Expr, and the caller is not known to be a quoted expression type, then the caller may provide a T - let calledArgTy = - let adjustDelegateTy calledTy = - let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomewhere - let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys - if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length - then fty - else calledArgTy - - if isDelegateTy g calledArgTy && isFunTy g callerArgTy then - adjustDelegateTy calledArgTy - - elif isLinqExpressionTy g calledArgTy && isFunTy g callerArgTy then - let origArgTy = calledArgTy - let calledArgTy = destLinqExpressionTy g calledArgTy - if isDelegateTy g calledArgTy then - adjustDelegateTy calledArgTy - else - // BUG 435170: called arg is Expr<'t> where 't is not delegate - such conversion is not legal -> return original type - origArgTy - - elif calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then - destQuotedExprTy g calledArgTy - - else calledArgTy - - // Adjust the called argument type to take into account whether the caller's argument is M(?arg=Some(3)) or M(arg=1) - // If the called method argument is Callee-side optional with type Option, and the caller argument is not explicitly optional (callerArg.IsOptional), then the caller may provide a T - // If the called method argument is Caller-side optional with type Nullable, and the caller argument is not explicitly optional (callerArg.IsOptional), then the caller may provide a T - let calledArgTy = - match calledArg.OptArgInfo with - | NotOptional -> calledArgTy - | CalleeSide when not callerArg.IsOptional && isOptionTy g calledArgTy -> destOptionTy g calledArgTy - // This will be added in https://github.com/dotnet/fsharp/pull/7276 - //| CallerSide _ when not callerArg.IsOptional && isNullableTy g calledArgTy -> destNullableTy g calledArgTy - | CalleeSide - | CallerSide _ -> calledArgTy - - calledArgTy + AdjustCalledArgTypeForOptionals infoReader ad enforceNullableOptionalsKnownTypes calledArg calledArgTy callerArg //------------------------------------------------------------------------- // CalledMeth @@ -201,18 +433,24 @@ let AdjustCalledArgType (infoReader: InfoReader) isConstraint (calledArg: Called type CalledMethArgSet<'T> = { /// The called arguments corresponding to "unnamed" arguments UnnamedCalledArgs : CalledArg list + /// Any unnamed caller arguments not otherwise assigned UnnamedCallerArgs : CallerArg<'T> list + /// The called "ParamArray" argument, if any ParamArrayCalledArgOpt : CalledArg option + /// Any unnamed caller arguments assigned to a "param array" argument ParamArrayCallerArgs : CallerArg<'T> list + /// Named args AssignedNamedArgs: AssignedCalledArg<'T> list } + member x.NumUnnamedCallerArgs = x.UnnamedCallerArgs.Length + member x.NumAssignedNamedArgs = x.AssignedNamedArgs.Length - member x.NumUnnamedCalledArgs = x.UnnamedCalledArgs.Length + member x.NumUnnamedCalledArgs = x.UnnamedCalledArgs.Length let MakeCalledArgs amap m (minfo: MethInfo) minst = // Mark up the arguments with their position, so we can sort them back into order later @@ -236,27 +474,45 @@ type CalledMeth<'T> (infoReader: InfoReader, nameEnv: NameResolutionEnv option, isCheckingAttributeCall, - freshenMethInfo, // a function to help generate fresh type variables the property setters methods in generic classes + /// A function to help generate fresh type variables the property setters methods in generic classes + freshenMethInfo, + /// Range m, - ad, // the access domain of the place where the call is taking place - minfo: MethInfo, // the method we're attempting to call - calledTyArgs, // the 'called type arguments', i.e. the fresh generic instantiation of the method we're attempting to call - callerTyArgs: TType list, // the 'caller type arguments', i.e. user-given generic instantiation of the method we're attempting to call - pinfoOpt: PropInfo option, // the property related to the method we're attempting to call, if any - callerObjArgTys: TType list, // the types of the actual object argument, if any - curriedCallerArgs: (CallerArg<'T> list * CallerNamedArg<'T> list) list, // the data about any arguments supplied by the caller - allowParamArgs: bool, // do we allow the use of a param args method in its "expanded" form? - allowOutAndOptArgs: bool, // do we allow the use of the transformation that converts out arguments as tuple returns? - tyargsOpt : TType option) // method parameters + /// The access domain of the place where the call is taking place + ad, + /// The method we're attempting to call + minfo: MethInfo, + /// The 'called type arguments', i.e. the fresh generic instantiation of the method we're attempting to call + calledTyArgs, + /// The 'caller type arguments', i.e. user-given generic instantiation of the method we're attempting to call + callerTyArgs: TType list, + /// The property related to the method we're attempting to call, if any + pinfoOpt: PropInfo option, + /// The types of the actual object argument, if any + callerObjArgTys: TType list, + /// The 'caller method arguments', i.e. a list of user-given parameter expressions, split between unnamed and named arguments + callerArgs: CallerArgs<'T>, + /// Do we allow the use of a param args method in its "expanded" form? + allowParamArgs: bool, + /// Do we allow the use of the transformation that converts out arguments as tuple returns? + allowOutAndOptArgs: bool, + /// Method parameters + tyargsOpt: TType option) = let g = infoReader.g - let methodRetTy = minfo.GetFSharpReturnTy(infoReader.amap, m, calledTyArgs) + let methodRetTy = if minfo.IsConstructor then minfo.ApparentEnclosingType else minfo.GetFSharpReturnTy(infoReader.amap, m, calledTyArgs) let fullCurriedCalledArgs = MakeCalledArgs infoReader.amap m minfo calledTyArgs do assert (fullCurriedCalledArgs.Length = fullCurriedCalledArgs.Length) + // Detect the special case where an indexer setter using param aray takes 'value' argument after ParamArray arguments + let isIndexerSetter = + match pinfoOpt with + | Some pinfo when pinfo.HasSetter && minfo.LogicalName.StartsWith "set_" && (List.concat fullCurriedCalledArgs).Length >= 2 -> true + | _ -> false + let argSetInfos = - (curriedCallerArgs, fullCurriedCalledArgs) ||> List.map2 (fun (unnamedCallerArgs, namedCallerArgs) fullCalledArgs -> + (callerArgs.CurriedCallerArgs, fullCurriedCalledArgs) ||> List.map2 (fun (unnamedCallerArgs, namedCallerArgs) fullCalledArgs -> // Find the arguments not given by name let unnamedCalledArgs = fullCalledArgs |> List.filter (fun calledArg -> @@ -265,7 +521,7 @@ type CalledMeth<'T> | None -> true) // See if any of them are 'out' arguments being returned as part of a return tuple - let minArgs, unnamedCalledArgs, unnamedCalledOptArgs, unnamedCalledOutArgs = + let unnamedCalledArgs, unnamedCalledOptArgs, unnamedCalledOutArgs = let nUnnamedCallerArgs = unnamedCallerArgs.Length let nUnnamedCalledArgs = unnamedCalledArgs.Length if allowOutAndOptArgs && nUnnamedCallerArgs < nUnnamedCalledArgs then @@ -273,25 +529,49 @@ type CalledMeth<'T> // Check if all optional/out arguments are byref-out args if unnamedCalledOptOrOutArgs |> List.forall (fun x -> x.IsOutArg && isByrefTy g x.CalledArgumentType) then - nUnnamedCallerArgs - 1, unnamedCalledArgsTrimmed, [], unnamedCalledOptOrOutArgs + unnamedCalledArgsTrimmed, [], unnamedCalledOptOrOutArgs // Check if all optional/out arguments are optional args elif unnamedCalledOptOrOutArgs |> List.forall (fun x -> x.OptArgInfo.IsOptional) then - nUnnamedCallerArgs - 1, unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs, [] + unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs, [] // Otherwise drop them on the floor else - nUnnamedCalledArgs - 1, unnamedCalledArgs, [], [] + unnamedCalledArgs, [], [] else - nUnnamedCalledArgs - 1, unnamedCalledArgs, [], [] + unnamedCalledArgs, [], [] let (unnamedCallerArgs, paramArrayCallerArgs), unnamedCalledArgs, paramArrayCalledArgOpt = + + let nUnnamedCallerArgs = unnamedCallerArgs.Length + let nUnnamedCalledArgs = unnamedCalledArgs.Length let supportsParamArgs = allowParamArgs && - minArgs >= 0 && - unnamedCalledArgs |> List.last |> (fun calledArg -> calledArg.IsParamArray && isArray1DTy g calledArg.CalledArgumentType) - - if supportsParamArgs && unnamedCallerArgs.Length >= minArgs then - let a, b = List.frontAndBack unnamedCalledArgs - List.splitAt minArgs unnamedCallerArgs, a, Some(b) + nUnnamedCalledArgs >= 1 && + nUnnamedCallerArgs >= nUnnamedCalledArgs-1 && + let possibleParamArg = + if isIndexerSetter then + unnamedCalledArgs.[nUnnamedCalledArgs-2] + else + unnamedCalledArgs.[nUnnamedCalledArgs-1] + possibleParamArg.IsParamArray && isArray1DTy g possibleParamArg.CalledArgumentType + + if supportsParamArgs then + if isIndexerSetter then + // Note, for an indexer setter nUnnamedCalledArgs will be at least two, and normally exactly 2 + let unnamedCalledArgs2 = + unnamedCalledArgs.[0..unnamedCalledArgs.Length-3] @ + [unnamedCalledArgs.[unnamedCalledArgs.Length-1]] + let paramArrayCalledArg = + unnamedCalledArgs.[unnamedCalledArgs.Length-2] + let unnamedCallerArgs2 = + unnamedCallerArgs.[0..nUnnamedCalledArgs-3] @ + [unnamedCallerArgs.[nUnnamedCallerArgs-1]] + let paramArrayCallerArgs = + unnamedCallerArgs.[nUnnamedCalledArgs-2..nUnnamedCallerArgs-2] + (unnamedCallerArgs2, paramArrayCallerArgs), unnamedCalledArgs2, Some paramArrayCalledArg + else + let unnamedCalledArgs2, paramArrayCalledArg = List.frontAndBack unnamedCalledArgs + let unnamedCallerArgs2, paramArrayCallerArgs = List.splitAt (nUnnamedCalledArgs-1) unnamedCallerArgs + (unnamedCallerArgs2, paramArrayCallerArgs), unnamedCalledArgs2, Some paramArrayCalledArg else (unnamedCallerArgs, []), unnamedCalledArgs, None @@ -321,7 +601,7 @@ type CalledMeth<'T> [] let assignedNamedProps, unassignedNamedItems = - let returnedObjTy = if minfo.IsConstructor then minfo.ApparentEnclosingType else methodRetTy + let returnedObjTy = methodRetTy unassignedNamedItems |> List.splitChoose (fun (CallerNamedArg(id, e) as arg) -> let nm = id.idText let pinfos = GetIntrinsicPropInfoSetsOfType infoReader (Some nm) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides id.idRange returnedObjTy @@ -358,10 +638,10 @@ type CalledMeth<'T> | _ -> Choice2Of2(arg)) - let names = namedCallerArgs |> List.map (fun (CallerNamedArg(nm, _)) -> nm.idText) - - if (List.noRepeats String.order names).Length <> namedCallerArgs.Length then - errorR(Error(FSComp.SR.typrelNamedArgumentHasBeenAssignedMoreThenOnce(), m)) + let names = System.Collections.Generic.HashSet<_>() + for CallerNamedArg(nm, _) in namedCallerArgs do + if not (names.Add nm.idText) then + errorR(Error(FSComp.SR.typrelNamedArgumentHasBeenAssignedMoreThenOnce nm.idText, m)) let argSet = { UnnamedCalledArgs=unnamedCalledArgs; UnnamedCallerArgs=unnamedCallerArgs; ParamArrayCalledArgOpt=paramArrayCalledArgOpt; ParamArrayCallerArgs=paramArrayCallerArgs; AssignedNamedArgs=assignedNamedArgs } @@ -378,32 +658,33 @@ type CalledMeth<'T> member x.amap = infoReader.amap - /// the method we're attempting to call + /// The method we're attempting to call member x.Method = minfo - /// the instantiation of the method we're attempting to call + /// The instantiation of the method we're attempting to call member x.CalledTyArgs = calledTyArgs - /// the instantiation of the method we're attempting to call + member x.AllCalledArgs = fullCurriedCalledArgs + + /// The instantiation of the method we're attempting to call member x.CalledTyparInst = let tps = minfo.FormalMethodTypars if tps.Length = calledTyArgs.Length then mkTyparInst tps calledTyArgs else [] - /// the formal instantiation of the method we're attempting to call + /// The formal instantiation of the method we're attempting to call member x.CallerTyArgs = callerTyArgs - /// The types of the actual object arguments, if any + /// The types of the actual object arguments, if any member x.CallerObjArgTys = callerObjArgTys - /// The argument analysis for each set of curried arguments + /// The argument analysis for each set of curried arguments member x.ArgSets = argSets - /// return type after implicit deference of byref returns is taken into account + /// The return type after implicit deference of byref returns is taken into account member x.CalledReturnTypeAfterByrefDeref = - let retTy = methodRetTy - if isByrefTy g retTy then destByrefTy g retTy else retTy + if isByrefTy g methodRetTy then destByrefTy g methodRetTy else methodRetTy - /// return type after tupling of out args is taken into account + /// Return type after tupling of out args is taken into account member x.CalledReturnTypeAfterOutArgTupling = let retTy = x.CalledReturnTypeAfterByrefDeref if isNil unnamedCalledOutArgs then @@ -413,22 +694,22 @@ type CalledMeth<'T> if isUnitTy g retTy then mkRefTupledTy g outArgTys else mkRefTupledTy g (retTy :: outArgTys) - /// named setters + /// Named setters member x.AssignedItemSetters = assignedNamedProps - /// the property related to the method we're attempting to call, if any + /// The property related to the method we're attempting to call, if any member x.AssociatedPropertyInfo = pinfoOpt - /// unassigned args + /// Unassigned args member x.UnassignedNamedArgs = unassignedNamedItems - /// args assigned to specify values for attribute fields and properties (these are not necessarily "property sets") + /// Args assigned to specify values for attribute fields and properties (these are not necessarily "property sets") member x.AttributeAssignedNamedArgs = attributeAssignedNamedItems - /// unnamed called optional args: pass defaults for these + /// Unnamed called optional args: pass defaults for these member x.UnnamedCalledOptArgs = unnamedCalledOptArgs - /// unnamed called out args: return these as part of the return tuple + /// Unnamed called out args: return these as part of the return tuple member x.UnnamedCalledOutArgs = unnamedCalledOutArgs static member GetMethod (x: CalledMeth<'T>) = x.Method @@ -441,12 +722,15 @@ type CalledMeth<'T> member x.UsesParamArrayConversion = x.ArgSets |> List.exists (fun argSet -> argSet.ParamArrayCalledArgOpt.IsSome) + member x.IsIndexParamArraySetter = isIndexerSetter && x.UsesParamArrayConversion + member x.ParamArrayCalledArgOpt = x.ArgSets |> List.tryPick (fun argSet -> argSet.ParamArrayCalledArgOpt) member x.ParamArrayCallerArgs = x.ArgSets |> List.tryPick (fun argSet -> if Option.isSome argSet.ParamArrayCalledArgOpt then Some argSet.ParamArrayCallerArgs else None ) - member x.ParamArrayElementType = - assert (x.UsesParamArrayConversion) + member x.GetParamArrayElementType() = + // turned as a method to avoid assert in variable inspector + assert x.UsesParamArrayConversion x.ParamArrayCalledArgOpt.Value.CalledArgumentType |> destArrayTy x.amap.g member x.NumAssignedProps = x.AssignedItemSetters.Length @@ -498,6 +782,8 @@ type CalledMeth<'T> member x.TotalNumAssignedNamedArgs = x.ArgSets |> List.sumBy (fun x -> x.NumAssignedNamedArgs) + override x.ToString() = "call to " + minfo.ToString() + let NamesOfCalledArgs (calledArgs: CalledArg list) = calledArgs |> List.choose (fun x -> x.NameOpt) @@ -514,119 +800,493 @@ type ArgumentAnalysis = let InferLambdaArgsForLambdaPropagation origRhsExpr = let rec loop e = match e with - | SynExpr.Lambda (_, _, _, rest, _) -> 1 + loop rest + | SynExpr.Lambda (body = rest) -> 1 + loop rest | SynExpr.MatchLambda _ -> 1 | _ -> 0 loop origRhsExpr -let ExamineArgumentForLambdaPropagation (infoReader: InfoReader) (arg: AssignedCalledArg) = +let ExamineArgumentForLambdaPropagation (infoReader: InfoReader) ad (arg: AssignedCalledArg) = let g = infoReader.g + // Find the explicit lambda arguments of the caller. Ignore parentheses. let argExpr = match arg.CallerArg.Expr with SynExpr.Paren (x, _, _, _) -> x | x -> x let countOfCallerLambdaArg = InferLambdaArgsForLambdaPropagation argExpr + // Adjust for Expression<_>, Func<_, _>, ... - let adjustedCalledArgTy = AdjustCalledArgType infoReader false arg.CalledArg arg.CallerArg + let adjustedCalledArgTy, _, _ = AdjustCalledArgType infoReader ad false false arg.CalledArg arg.CallerArg if countOfCallerLambdaArg > 0 then // Decompose the explicit function type of the target - let calledLambdaArgTys, _calledLambdaRetTy = Tastops.stripFunTy g adjustedCalledArgTy + let calledLambdaArgTys, _calledLambdaRetTy = stripFunTy g adjustedCalledArgTy if calledLambdaArgTys.Length >= countOfCallerLambdaArg then // success CallerLambdaHasArgTypes calledLambdaArgTys elif isDelegateTy g (if isLinqExpressionTy g adjustedCalledArgTy then destLinqExpressionTy g adjustedCalledArgTy else adjustedCalledArgTy) then - ArgDoesNotMatch // delegate arity mismatch + // delegate arity mismatch + ArgDoesNotMatch else - NoInfo // not a function type on the called side - no information - else CalledArgMatchesType(adjustedCalledArgTy) // not a lambda on the caller side - push information from caller to called + // not a function type on the called side - no information + NoInfo + else + // not a lambda on the caller side - push information from caller to called + CalledArgMatchesType(adjustedCalledArgTy) + -let ExamineMethodForLambdaPropagation (x: CalledMeth) = - let unnamedInfo = x.AssignedUnnamedArgs |> List.mapSquared (ExamineArgumentForLambdaPropagation x.infoReader) - let namedInfo = x.AssignedNamedArgs |> List.mapSquared (fun arg -> (arg.NamedArgIdOpt.Value, ExamineArgumentForLambdaPropagation x.infoReader arg)) +let ExamineMethodForLambdaPropagation (x: CalledMeth) ad = + let unnamedInfo = x.AssignedUnnamedArgs |> List.mapSquared (ExamineArgumentForLambdaPropagation x.infoReader ad) + let namedInfo = x.AssignedNamedArgs |> List.mapSquared (fun arg -> (arg.NamedArgIdOpt.Value, ExamineArgumentForLambdaPropagation x.infoReader ad arg)) if unnamedInfo |> List.existsSquared (function CallerLambdaHasArgTypes _ -> true | _ -> false) || - namedInfo |> List.existsSquared (function (_, CallerLambdaHasArgTypes _) -> true | _ -> false) then + namedInfo |> List.existsSquared (function _, CallerLambdaHasArgTypes _ -> true | _ -> false) then Some (unnamedInfo, namedInfo) else None //------------------------------------------------------------------------- -// Adjust caller arguments as part of building a method call +// Additional helpers for building method calls and doing TAST generation //------------------------------------------------------------------------- -/// Build a call to the System.Object constructor taking no arguments, -let BuildObjCtorCall (g: TcGlobals) m = - let ilMethRef = (mkILCtorMethSpecForTy(g.ilg.typ_Object, [])).MethodRef - Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty]), [], [], m) +/// Is this a 'base' call (in the sense of C#) +let IsBaseCall objArgs = + match objArgs with + | [Expr.Val (v, _, _)] when v.IsBaseVal -> true + | _ -> false + +/// Compute whether we insert a 'coerce' on the 'this' pointer for an object model call +/// For example, when calling an interface method on a struct, or a method on a constrained +/// variable type. +let ComputeConstrainedCallInfo g amap m (objArgs, minfo: MethInfo) = + match objArgs with + | [objArgExpr] when not minfo.IsExtensionMember -> + let methObjTy = minfo.ApparentEnclosingType + let objArgTy = tyOfExpr g objArgExpr + if TypeDefinitelySubsumesTypeNoCoercion 0 g amap m methObjTy objArgTy + // Constrained calls to class types can only ever be needed for the three class types that + // are base types of value types + || (isClassTy g methObjTy && + (not (typeEquiv g methObjTy g.system_Object_ty || + typeEquiv g methObjTy g.system_Value_ty || + typeEquiv g methObjTy g.system_Enum_ty))) then + None + else + // The object argument is a value type or variable type and the target method is an interface or System.Object + // type. A .NET 2.0 generic constrained call is required + Some objArgTy + | _ -> + None -/// Implements the elaborated form of adhoc conversions from functions to delegates at member callsites -let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, invokeMethInfo: MethInfo, delArgTys, f, fty, m) = - let slotsig = invokeMethInfo.GetSlotSig(amap, m) - let delArgVals, expr = - let topValInfo = ValReprInfo([], List.replicate (max 1 (List.length delArgTys)) ValReprInfo.unnamedTopArg, ValReprInfo.unnamedRetVal) +/// Adjust the 'this' pointer before making a call +/// Take the address of a struct, and coerce to an interface/base/constraint type if necessary +let TakeObjAddrForMethodCall g amap (minfo: MethInfo) isMutable m objArgs f = + let ccallInfo = ComputeConstrainedCallInfo g amap m (objArgs, minfo) - // Try to pull apart an explicit lambda and use it directly - // Don't do this in the case where we're adjusting the arguments of a function used to build a .NET-compatible event handler - let lambdaContents = - if Option.isSome eventInfoOpt then - None - else - tryDestTopLambda g amap topValInfo (f, fty) + let wrap, objArgs = - match lambdaContents with - | None -> - - if List.exists (isByrefTy g) delArgTys then - error(Error(FSComp.SR.tcFunctionRequiresExplicitLambda(List.length delArgTys), m)) + match objArgs with + | [objArgExpr] -> - let delArgVals = delArgTys |> List.mapi (fun i argty -> fst (mkCompGenLocal m ("delegateArg" + string i) argty)) - let expr = - let args = - match eventInfoOpt with - | Some einfo -> - match delArgVals with - | [] -> error(nonStandardEventError einfo.EventName m) - | h :: _ when not (isObjTy g h.Type) -> error(nonStandardEventError einfo.EventName m) - | h :: t -> [exprForVal m h; mkRefTupledVars g m t] - | None -> - if isNil delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals - mkApps g ((f, fty), [], args, m) - delArgVals, expr - - | Some _ -> - let _, _, _, vsl, body, _ = IteratedAdjustArityOfLambda g amap topValInfo f - List.concat vsl, body + let hasCallInfo = ccallInfo.IsSome + let mustTakeAddress = hasCallInfo || minfo.ObjArgNeedsAddress(amap, m) + let objArgTy = tyOfExpr g objArgExpr - let meth = TObjExprMethod(slotsig, [], [], [delArgVals], expr, m) - mkObjExpr(delegateTy, None, BuildObjCtorCall g m, [meth], [], m) + let isMutable = + match isMutable with + | DefinitelyMutates + | NeverMutates + | AddressOfOp -> isMutable + | PossiblyMutates -> + // Check to see if the method is read-only. Perf optimization. + // If there is an extension member whose first arg is an inref, we must return NeverMutates. + if mustTakeAddress && (minfo.IsReadOnly || minfo.IsReadOnlyExtensionMember (amap, m)) then + NeverMutates + else + isMutable -let CoerceFromFSharpFuncToDelegate g amap infoReader ad callerArgTy m callerArgExpr delegateTy = - let (SigOfFunctionForDelegate(invokeMethInfo, delArgTys, _, _)) = GetSigOfFunctionForDelegate infoReader delegateTy m ad - BuildNewDelegateExpr (None, g, amap, delegateTy, invokeMethInfo, delArgTys, callerArgExpr, callerArgTy, m) + let wrap, objArgExprAddr, isReadOnly, _isWriteOnly = + mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m + + // Extension members and calls to class constraints may need a coercion for their object argument + let objArgExprCoerced = + if not hasCallInfo && + not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.ApparentEnclosingType objArgTy) then + mkCoerceExpr(objArgExprAddr, minfo.ApparentEnclosingType, m, objArgTy) + else + objArgExprAddr -// Handle adhoc argument conversions -let AdjustCallerArgExprForCoercions (g: TcGlobals) amap infoReader ad isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr = + // Check to see if the extension member uses the extending type as a byref. + // If so, make sure we don't allow readonly/immutable values to be passed byref from an extension member. + // An inref will work though. + if isReadOnly && mustTakeAddress && minfo.IsExtensionMember then + minfo.TryObjArgByrefType(amap, m, minfo.FormalMethodInst) + |> Option.iter (fun ty -> + if not (isInByrefTy g ty) then + errorR(Error(FSComp.SR.tcCannotCallExtensionMethodInrefToByref(minfo.DisplayName), m))) + - if isByrefTy g calledArgTy && isRefCellTy g callerArgTy then - None, Expr.Op (TOp.RefAddrGet false, [destRefCellTy g callerArgTy], [callerArgExpr], m) + wrap, [objArgExprCoerced] -#if IMPLICIT_ADDRESS_OF - elif isInByrefTy g calledArgTy && not (isByrefTy g callerArgTy) then - let wrap, callerArgExprAddress, _readonly, _writeonly = mkExprAddrOfExpr g true false NeverMutates callerArgExpr None m - Some wrap, callerArgExprAddress -#endif + | _ -> + id, objArgs + let e, ety = f ccallInfo objArgs + wrap e, ety - elif isDelegateTy g calledArgTy && isFunTy g callerArgTy then - None, CoerceFromFSharpFuncToDelegate g amap infoReader ad callerArgTy m callerArgExpr calledArgTy +/// Build an expression node that is a call to a .NET method. +let BuildILMethInfoCall g amap m isProp (minfo: ILMethInfo) valUseFlags minst direct args = + let valu = isStructTy g minfo.ApparentEnclosingType + let ctor = minfo.IsConstructor + if minfo.IsClassConstructor then + error (InternalError (minfo.ILName+": cannot call a class constructor", m)) + let useCallvirt = + not valu && not direct && minfo.IsVirtual + let isProtected = minfo.IsProtectedAccessibility + let ilMethRef = minfo.ILMethodRef + let newobj = ctor && (match valUseFlags with NormalValUse -> true | _ -> false) + let exprTy = if ctor then minfo.ApparentEnclosingType else minfo.GetFSharpReturnTy(amap, m, minst) + let retTy = if not ctor && (stripILModifiedFromTy ilMethRef.ReturnType) = ILType.Void then [] else [exprTy] + let isDllImport = minfo.IsDllImport g + Expr.Op (TOp.ILCall (useCallvirt, isProtected, valu, newobj, valUseFlags, isProp, isDllImport, ilMethRef, minfo.DeclaringTypeInst, minst, retTy), [], args, m), + exprTy - elif isLinqExpressionTy g calledArgTy && isDelegateTy g (destLinqExpressionTy g calledArgTy) && isFunTy g callerArgTy then - let delegateTy = destLinqExpressionTy g calledArgTy - let expr = CoerceFromFSharpFuncToDelegate g amap infoReader ad callerArgTy m callerArgExpr delegateTy - None, mkCallQuoteToLinqLambdaExpression g m delegateTy (Expr.Quote (expr, ref None, false, m, mkQuotedExprTy g delegateTy)) - // auto conversions to quotations (to match auto conversions to LINQ expressions) - elif reflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then - match reflArgInfo with - | ReflectedArgInfo.Quote true -> - None, mkCallLiftValueWithDefn g m calledArgTy callerArgExpr - | ReflectedArgInfo.Quote false -> +/// Build a call to an F# method. +/// +/// Consume the arguments in chunks and build applications. This copes with various F# calling signatures +/// all of which ultimately become 'methods'. +/// +/// QUERY: this looks overly complex considering that we are doing a fundamentally simple +/// thing here. +let BuildFSharpMethodApp g m (vref: ValRef) vexp vexprty (args: Exprs) = + let arities = (arityOfVal vref.Deref).AritiesOfArgs + + let args3, (leftover, retTy) = + let exprL expr = exprL g expr + ((args, vexprty), arities) ||> List.mapFold (fun (args, fty) arity -> + match arity, args with + | (0|1), [] when typeEquiv g (domainOfFunTy g fty) g.unit_ty -> mkUnit g m, (args, rangeOfFunTy g fty) + | 0, arg :: argst -> + let msg = LayoutRender.showL (Layout.sepListL (Layout.rightL (TaggedText.tagText ";")) (List.map exprL args)) + warning(InternalError(sprintf "Unexpected zero arity, args = %s" msg, m)) + arg, (argst, rangeOfFunTy g fty) + | 1, arg :: argst -> arg, (argst, rangeOfFunTy g fty) + | 1, [] -> error(InternalError("expected additional arguments here", m)) + | _ -> + if args.Length < arity then + error(InternalError("internal error in getting arguments, n = "+string arity+", #args = "+string args.Length, m)) + let tupargs, argst = List.splitAt arity args + let tuptys = tupargs |> List.map (tyOfExpr g) + (mkRefTupled g m tupargs tuptys), + (argst, rangeOfFunTy g fty) ) + if not leftover.IsEmpty then error(InternalError("Unexpected "+string(leftover.Length)+" remaining arguments in method application", m)) + mkApps g ((vexp, vexprty), [], args3, m), + retTy + +/// Build a call to an F# method. +let BuildFSharpMethodCall g m (ty, vref: ValRef) valUseFlags minst args = + let vexp = Expr.Val (vref, valUseFlags, m) + let vexpty = vref.Type + let tpsorig, tau = vref.TypeScheme + let vtinst = argsOfAppTy g ty @ minst + if tpsorig.Length <> vtinst.Length then error(InternalError("BuildFSharpMethodCall: unexpected List.length mismatch", m)) + let expr = mkTyAppExpr m (vexp, vexpty) vtinst + let exprty = instType (mkTyparInst tpsorig vtinst) tau + BuildFSharpMethodApp g m vref expr exprty args + + +/// Make a call to a method info. Used by the optimizer and code generator to build +/// calls to the type-directed solutions to member constraints. +let MakeMethInfoCall amap m minfo minst args = + let valUseFlags = NormalValUse // correct unless if we allow wild trait constraints like "T has a ctor and can be used as a parent class" + + match minfo with + + | ILMeth(g, ilminfo, _) -> + let direct = not minfo.IsVirtual + let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant + BuildILMethInfoCall g amap m isProp ilminfo valUseFlags minst direct args |> fst + + | FSMeth(g, ty, vref, _) -> + BuildFSharpMethodCall g m (ty, vref) valUseFlags minst args |> fst + + | DefaultStructCtor(_, ty) -> + mkDefault (m, ty) + +#if !NO_EXTENSIONTYPING + | ProvidedMeth(amap, mi, _, m) -> + let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant + let ilMethodRef = Import.ImportProvidedMethodBaseAsILMethodRef amap m mi + let isConstructor = mi.PUntaint((fun c -> c.IsConstructor), m) + let valu = mi.PUntaint((fun c -> c.DeclaringType.IsValueType), m) + let actualTypeInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here + let actualMethInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here + let ilReturnTys = Option.toList (minfo.GetCompiledReturnTy(amap, m, [])) // GENERIC TYPE PROVIDERS: for generics, we would have more here + // REVIEW: Should we allow protected calls? + Expr.Op (TOp.ILCall (false, false, valu, isConstructor, valUseFlags, isProp, false, ilMethodRef, actualTypeInst, actualMethInst, ilReturnTys), [], args, m) + +#endif + +#if !NO_EXTENSIONTYPING +// This imports a provided method, and checks if it is a known compiler intrinsic like "1 + 2" +let TryImportProvidedMethodBaseAsLibraryIntrinsic (amap: Import.ImportMap, m: range, mbase: Tainted) = + let methodName = mbase.PUntaint((fun x -> x.Name), m) + let declaringType = Import.ImportProvidedType amap m (mbase.PApply((fun x -> x.DeclaringType), m)) + match tryTcrefOfAppTy amap.g declaringType with + | ValueSome declaringEntity -> + if not declaringEntity.IsLocalRef && ccuEq declaringEntity.nlr.Ccu amap.g.fslibCcu then + let n = mbase.PUntaint((fun x -> x.GetParameters().Length), m) + match amap.g.knownIntrinsics.TryGetValue ((declaringEntity.LogicalName, None, methodName, n)) with + | true, vref -> Some vref + | _ -> + match amap.g.knownFSharpCoreModules.TryGetValue declaringEntity.LogicalName with + | true, modRef -> + modRef.ModuleOrNamespaceType.AllValsByLogicalName + |> Seq.tryPick (fun (KeyValue(_, v)) -> if (v.CompiledName amap.g.CompilerGlobalState) = methodName then Some (mkNestedValRef modRef v) else None) + | _ -> None + else + None + | _ -> + None +#endif + + +/// Build an expression that calls a given method info. +/// This is called after overload resolution, and also to call other +/// methods such as 'setters' for properties. +// tcVal: used to convert an F# value into an expression. See tc.fs. +// isProp: is it a property get? +// minst: the instantiation to apply for a generic method +// objArgs: the 'this' argument, if any +// args: the arguments, if any +let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objArgs args = + let direct = IsBaseCall objArgs + + TakeObjAddrForMethodCall g amap minfo isMutable m objArgs (fun ccallInfo objArgs -> + let allArgs = objArgs @ args + let valUseFlags = + if direct && (match valUseFlags with NormalValUse -> true | _ -> false) then + VSlotDirectCall + else + match ccallInfo with + | Some ty -> + // printfn "possible constrained call to '%s' at %A" minfo.LogicalName m + PossibleConstrainedCall ty + | None -> + valUseFlags + + match minfo with +#if !NO_EXTENSIONTYPING + // By this time this is an erased method info, e.g. one returned from an expression + // REVIEW: copied from tastops, which doesn't allow protected methods + | ProvidedMeth (amap, providedMeth, _, _) -> + // TODO: there is a fair bit of duplication here with mk_il_minfo_call. We should be able to merge these + + /// Build an expression node that is a call to a extension method in a generated assembly + let enclTy = minfo.ApparentEnclosingType + // prohibit calls to methods that are declared in specific array types (Get, Set, Address) + // these calls are provided by the runtime and should not be called from the user code + if isArrayTy g enclTy then + let tpe = TypeProviderError(FSComp.SR.tcRuntimeSuppliedMethodCannotBeUsedInUserCode(minfo.DisplayName), providedMeth.TypeProviderDesignation, m) + error tpe + let valu = isStructTy g enclTy + let isCtor = minfo.IsConstructor + if minfo.IsClassConstructor then + error (InternalError (minfo.LogicalName + ": cannot call a class constructor", m)) + let useCallvirt = not valu && not direct && minfo.IsVirtual + let isProtected = minfo.IsProtectedAccessibility + let exprTy = if isCtor then enclTy else minfo.GetFSharpReturnTy(amap, m, minst) + match TryImportProvidedMethodBaseAsLibraryIntrinsic (amap, m, providedMeth) with + | Some fsValRef -> + //reraise() calls are converted to TOp.Reraise in the type checker. So if a provided expression includes a reraise call + // we must put it in that form here. + if valRefEq amap.g fsValRef amap.g.reraise_vref then + mkReraise m exprTy, exprTy + else + let vexp, vexpty = tcVal fsValRef valUseFlags (minfo.DeclaringTypeInst @ minst) m + BuildFSharpMethodApp g m fsValRef vexp vexpty allArgs + | None -> + let ilMethRef = Import.ImportProvidedMethodBaseAsILMethodRef amap m providedMeth + let isNewObj = isCtor && (match valUseFlags with NormalValUse -> true | _ -> false) + let actualTypeInst = + if isRefTupleTy g enclTy then argsOfAppTy g (mkCompiledTupleTy g false (destRefTupleTy g enclTy)) // provided expressions can include method calls that get properties of tuple types + elif isFunTy g enclTy then [ domainOfFunTy g enclTy; rangeOfFunTy g enclTy ] // provided expressions can call Invoke + else minfo.DeclaringTypeInst + let actualMethInst = minst + let retTy = if not isCtor && (ilMethRef.ReturnType = ILType.Void) then [] else [exprTy] + let noTailCall = false + let expr = Expr.Op (TOp.ILCall (useCallvirt, isProtected, valu, isNewObj, valUseFlags, isProp, noTailCall, ilMethRef, actualTypeInst, actualMethInst, retTy), [], allArgs, m) + expr, exprTy + +#endif + + // Build a call to a .NET method + | ILMeth(_, ilMethInfo, _) -> + BuildILMethInfoCall g amap m isProp ilMethInfo valUseFlags minst direct allArgs + + // Build a call to an F# method + | FSMeth(_, _, vref, _) -> + + // Go see if this is a use of a recursive definition... Note we know the value instantiation + // we want to use so we pass that in order not to create a new one. + let vexp, vexpty = tcVal vref valUseFlags (minfo.DeclaringTypeInst @ minst) m + BuildFSharpMethodApp g m vref vexp vexpty allArgs + + // Build a 'call' to a struct default constructor + | DefaultStructCtor (g, ty) -> + if not (TypeHasDefaultValue g m ty) then + errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) + mkDefault (m, ty), ty) + +let ILFieldStaticChecks g amap infoReader ad m (finfo : ILFieldInfo) = + CheckILFieldInfoAccessible g amap m ad finfo + if not finfo.IsStatic then error (Error (FSComp.SR.tcFieldIsNotStatic(finfo.FieldName), m)) + + // Static IL interfaces fields are not supported in lower F# versions. + if isInterfaceTy g finfo.ApparentEnclosingType then + checkLanguageFeatureRuntimeErrorRecover infoReader LanguageFeature.DefaultInterfaceMemberConsumption m + checkLanguageFeatureErrorRecover g.langVersion LanguageFeature.DefaultInterfaceMemberConsumption m + + CheckILFieldAttributes g finfo m + +let ILFieldInstanceChecks g amap ad m (finfo : ILFieldInfo) = + if finfo.IsStatic then error (Error (FSComp.SR.tcStaticFieldUsedWhenInstanceFieldExpected(), m)) + CheckILFieldInfoAccessible g amap m ad finfo + CheckILFieldAttributes g finfo m + +let MethInfoChecks g amap isInstance tyargsOpt objArgs ad m (minfo: MethInfo) = + if minfo.IsInstance <> isInstance then + if isInstance then + error (Error (FSComp.SR.csMethodIsNotAnInstanceMethod(minfo.LogicalName), m)) + else + error (Error (FSComp.SR.csMethodIsNotAStaticMethod(minfo.LogicalName), m)) + + // keep the original accessibility domain to determine type accessibility + let adOriginal = ad + // Eliminate the 'protected' portion of the accessibility domain for instance accesses + let ad = + match objArgs, ad with + | [objArg], AccessibleFrom(paths, Some tcref) -> + let objArgTy = tyOfExpr g objArg + let ty = generalizedTyconRef tcref + // We get to keep our rights if the type we're in subsumes the object argument type + if TypeFeasiblySubsumesType 0 g amap m ty CanCoerce objArgTy then + ad + // We get to keep our rights if this is a base call + elif IsBaseCall objArgs then + ad + else + AccessibleFrom(paths, None) + | _ -> ad + + if not (IsTypeAndMethInfoAccessible amap m adOriginal ad minfo) then + error (Error (FSComp.SR.tcMethodNotAccessible(minfo.LogicalName), m)) + + if isAnyTupleTy g minfo.ApparentEnclosingType && not minfo.IsExtensionMember && + (minfo.LogicalName.StartsWithOrdinal("get_Item") || minfo.LogicalName.StartsWithOrdinal("get_Rest")) then + warning (Error (FSComp.SR.tcTupleMemberNotNormallyUsed(), m)) + + CheckMethInfoAttributes g m tyargsOpt minfo |> CommitOperationResult + +//------------------------------------------------------------------------- +// Adjust caller arguments as part of building a method call +//------------------------------------------------------------------------- + +/// Build a call to the System.Object constructor taking no arguments, +let BuildObjCtorCall (g: TcGlobals) m = + let ilMethRef = (mkILCtorMethSpecForTy(g.ilg.typ_Object, [])).MethodRef + Expr.Op (TOp.ILCall (false, false, false, false, CtorValUsedAsSuperInit, false, true, ilMethRef, [], [], [g.obj_ty]), [], [], m) + +/// Implements the elaborated form of adhoc conversions from functions to delegates at member callsites +let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, invokeMethInfo: MethInfo, delArgTys, f, fty, m) = + let slotsig = invokeMethInfo.GetSlotSig(amap, m) + let delArgVals, expr = + let topValInfo = ValReprInfo([], List.replicate (max 1 (List.length delArgTys)) ValReprInfo.unnamedTopArg, ValReprInfo.unnamedRetVal) + + // Try to pull apart an explicit lambda and use it directly + // Don't do this in the case where we're adjusting the arguments of a function used to build a .NET-compatible event handler + let lambdaContents = + if Option.isSome eventInfoOpt then + None + else + tryDestTopLambda g amap topValInfo (f, fty) + + match lambdaContents with + | None -> + + if List.exists (isByrefTy g) delArgTys then + error(Error(FSComp.SR.tcFunctionRequiresExplicitLambda(List.length delArgTys), m)) + + let delArgVals = delArgTys |> List.mapi (fun i argty -> fst (mkCompGenLocal m ("delegateArg" + string i) argty)) + let expr = + let args = + match eventInfoOpt with + | Some einfo -> + match delArgVals with + | [] -> error(nonStandardEventError einfo.EventName m) + | h :: _ when not (isObjTy g h.Type) -> error(nonStandardEventError einfo.EventName m) + | h :: t -> [exprForVal m h; mkRefTupledVars g m t] + | None -> + if isNil delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals + mkApps g ((f, fty), [], args, m) + delArgVals, expr + + | Some _ -> + let _, _, _, vsl, body, _ = IteratedAdjustArityOfLambda g amap topValInfo f + List.concat vsl, body + + let meth = TObjExprMethod(slotsig, [], [], [delArgVals], expr, m) + mkObjExpr(delegateTy, None, BuildObjCtorCall g m, [meth], [], m) + +let CoerceFromFSharpFuncToDelegate g amap infoReader ad callerArgTy m callerArgExpr delegateTy = + let (SigOfFunctionForDelegate(invokeMethInfo, delArgTys, _, _)) = GetSigOfFunctionForDelegate infoReader delegateTy m ad + BuildNewDelegateExpr (None, g, amap, delegateTy, invokeMethInfo, delArgTys, callerArgExpr, callerArgTy, m) + +// Handle adhoc argument conversions +let rec AdjustExprForTypeDirectedConversions tcVal (g: TcGlobals) amap infoReader ad reqdTy actualTy m expr = + if isDelegateTy g reqdTy && isFunTy g actualTy then + CoerceFromFSharpFuncToDelegate g amap infoReader ad actualTy m expr reqdTy + + elif isLinqExpressionTy g reqdTy && isDelegateTy g (destLinqExpressionTy g reqdTy) && isFunTy g actualTy then + let delegateTy = destLinqExpressionTy g reqdTy + let expr2 = AdjustExprForTypeDirectedConversions tcVal g amap infoReader ad delegateTy actualTy m expr + mkCallQuoteToLinqLambdaExpression g m delegateTy (Expr.Quote (expr2, ref None, false, m, mkQuotedExprTy g delegateTy)) + + // Adhoc int32 --> int64 + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.int64_ty reqdTy && typeEquiv g g.int32_ty actualTy then + mkCallToInt64Operator g m actualTy expr + + // Adhoc int32 --> nativeint + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.nativeint_ty reqdTy && typeEquiv g g.int32_ty actualTy then + mkCallToIntPtrOperator g m actualTy expr + + // Adhoc int32 --> float64 + elif g.langVersion.SupportsFeature LanguageFeature.AdditionalTypeDirectedConversions && typeEquiv g g.float_ty reqdTy && typeEquiv g g.int32_ty actualTy then + mkCallToDoubleOperator g m actualTy expr + + else + match TryFindRelevantImplicitConversion infoReader ad reqdTy actualTy m with + | Some (minfo, _) -> + MethInfoChecks g amap false None [] ad m minfo + let callExpr, _ = BuildMethodCall tcVal g amap Mutates.NeverMutates m false minfo ValUseFlag.NormalValUse [] [] [expr] + assert (let resTy = tyOfExpr g callExpr in typeEquiv g reqdTy resTy) + callExpr + | None -> mkCoerceIfNeeded g reqdTy actualTy expr + // TODO: consider Nullable + + +// Handle adhoc argument conversions +let AdjustCallerArgExpr tcVal (g: TcGlobals) amap infoReader ad isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr = + if isByrefTy g calledArgTy && isRefCellTy g callerArgTy then + None, Expr.Op (TOp.RefAddrGet false, [destRefCellTy g callerArgTy], [callerArgExpr], m) + +#if IMPLICIT_ADDRESS_OF + elif isInByrefTy g calledArgTy && not (isByrefTy g callerArgTy) then + let wrap, callerArgExprAddress, _readonly, _writeonly = mkExprAddrOfExpr g true false NeverMutates callerArgExpr None m + Some wrap, callerArgExprAddress +#endif + + // auto conversions to quotations (to match auto conversions to LINQ expressions) + elif reflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then + match reflArgInfo with + | ReflectedArgInfo.Quote true -> + None, mkCallLiftValueWithDefn g m calledArgTy callerArgExpr + | ReflectedArgInfo.Quote false -> None, Expr.Quote (callerArgExpr, ref None, false, m, calledArgTy) | ReflectedArgInfo.None -> failwith "unreachable" // unreachable due to reflArgInfo.AutoQuote condition @@ -634,9 +1294,216 @@ let AdjustCallerArgExprForCoercions (g: TcGlobals) amap infoReader ad isOutArg c elif isOutArg then None, callerArgExpr - // Note: not all these casts are reported in quotations else - None, mkCoerceIfNeeded g calledArgTy callerArgTy callerArgExpr + let callerArgExpr2 = AdjustExprForTypeDirectedConversions tcVal g amap infoReader ad calledArgTy callerArgTy m callerArgExpr + None, callerArgExpr2 + +/// Some of the code below must allocate temporary variables or bind other variables to particular values. +/// As usual we represent variable allocators by expr -> expr functions +/// which we then use to wrap the whole expression. These will either do nothing or pre-bind a variable. It doesn't +/// matter what order they are applied in as long as they are all composed together. +let emptyPreBinder (e: Expr) = e + +/// Get the expression that must be inserted on the caller side for a CallerSide optional arg, +/// i.e. one where there is no corresponding caller arg. +let rec GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g (calledArg: CalledArg) currCalledArgTy currDfltVal eCallerMemberName mMethExpr = + match currDfltVal with + | MissingValue -> + // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. + emptyPreBinder, mkAsmExpr ([ mkNormalLdsfld (fspec_Missing_Value g); AI_nop ], [], [], [currCalledArgTy], mMethExpr) + + | DefaultValue -> + emptyPreBinder, mkDefault(mMethExpr, currCalledArgTy) + + | Constant fieldInit -> + match currCalledArgTy with + | NullableTy g inst when fieldInit <> ILFieldInit.Null -> + let nullableTy = mkILNonGenericBoxedTy(g.FindSysILTypeRef "System.Nullable`1") + let ctor = mkILCtorMethSpecForTy(nullableTy, [ILType.TypeVar 0us]).MethodRef + let ctorArgs = [Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, inst)] + emptyPreBinder, Expr.Op (TOp.ILCall (false, false, true, true, NormalValUse, false, false, ctor, [inst], [], [currCalledArgTy]), [], ctorArgs, mMethExpr) + | ByrefTy g inst -> + GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg inst (PassByRef(inst, currDfltVal)) eCallerMemberName mMethExpr + | _ -> + match calledArg.CallerInfo, eCallerMemberName with + | CallerLineNumber, _ when typeEquiv g currCalledArgTy g.int_ty -> + emptyPreBinder, Expr.Const (Const.Int32(mMethExpr.StartLine), mMethExpr, currCalledArgTy) + | CallerFilePath, _ when typeEquiv g currCalledArgTy g.string_ty -> + let fileName = mMethExpr.FileName |> FileSystem.GetFullPathShim |> PathMap.apply g.pathMap + emptyPreBinder, Expr.Const (Const.String fileName, mMethExpr, currCalledArgTy) + | CallerMemberName, Some callerName when (typeEquiv g currCalledArgTy g.string_ty) -> + emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy) + | _ -> + emptyPreBinder, Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, currCalledArgTy) + + | WrapperForIDispatch -> + match g.TryFindSysILTypeRef "System.Runtime.InteropServices.DispatchWrapper" with + | None -> error(Error(FSComp.SR.fscSystemRuntimeInteropServicesIsRequired(), mMethExpr)) + | Some tref -> + let ty = mkILNonGenericBoxedTy tref + let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef + let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) + emptyPreBinder, expr + + | WrapperForIUnknown -> + match g.TryFindSysILTypeRef "System.Runtime.InteropServices.UnknownWrapper" with + | None -> error(Error(FSComp.SR.fscSystemRuntimeInteropServicesIsRequired(), mMethExpr)) + | Some tref -> + let ty = mkILNonGenericBoxedTy tref + let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef + let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) + emptyPreBinder, expr + + | PassByRef (ty, dfltVal2) -> + let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty + let wrapper2, rhs = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg currCalledArgTy dfltVal2 eCallerMemberName mMethExpr + (wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr false (mkLocalValRef v) + +/// Get the expression that must be inserted on the caller side for a CalleeSide optional arg where +/// no caller argument has been provided. Normally this is 'None', however CallerMemberName and friends +/// can be used with 'CalleeSide' optional arguments +let GetDefaultExpressionForCalleeSideOptionalArg g (calledArg: CalledArg) eCallerMemberName (mMethExpr: range) = + let calledArgTy = calledArg.CalledArgumentType + let calledNonOptTy = + if isOptionTy g calledArgTy then + destOptionTy g calledArgTy + else + calledArgTy // should be unreachable + + match calledArg.CallerInfo, eCallerMemberName with + | CallerLineNumber, _ when typeEquiv g calledNonOptTy g.int_ty -> + let lineExpr = Expr.Const(Const.Int32 mMethExpr.StartLine, mMethExpr, calledNonOptTy) + mkSome g calledNonOptTy lineExpr mMethExpr + | CallerFilePath, _ when typeEquiv g calledNonOptTy g.string_ty -> + let fileName = mMethExpr.FileName |> FileSystem.GetFullPathShim |> PathMap.apply g.pathMap + let filePathExpr = Expr.Const (Const.String(fileName), mMethExpr, calledNonOptTy) + mkSome g calledNonOptTy filePathExpr mMethExpr + | CallerMemberName, Some(callerName) when typeEquiv g calledNonOptTy g.string_ty -> + let memberNameExpr = Expr.Const (Const.String callerName, mMethExpr, calledNonOptTy) + mkSome g calledNonOptTy memberNameExpr mMethExpr + | _ -> + mkNone g calledNonOptTy mMethExpr + +/// Get the expression that must be inserted on the caller side for an optional arg where +/// no caller argument has been provided. +let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCallerMemberName mItem (mMethExpr: range) = + let calledArgTy = calledArg.CalledArgumentType + let preBinder, expr = + match calledArg.OptArgInfo with + | NotOptional -> + error(InternalError("Unexpected NotOptional", mItem)) + + | CallerSide dfltVal -> + GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName mMethExpr + + | CalleeSide -> + emptyPreBinder, GetDefaultExpressionForCalleeSideOptionalArg g calledArg eCallerMemberName mMethExpr + + // Combine the variable allocators (if any) + let callerArg = CallerArg(calledArgTy, mMethExpr, false, expr) + preBinder, { NamedArgIdOpt = None; CalledArg = calledArg; CallerArg = callerArg } + +let MakeNullableExprIfNeeded (infoReader: InfoReader) calledArgTy callerArgTy callerArgExpr m = + let g = infoReader.g + let amap = infoReader.amap + if isNullableTy g callerArgTy then + callerArgExpr + else + let calledNonOptTy = destNullableTy g calledArgTy + let minfo = GetIntrinsicConstructorInfosOfType infoReader m calledArgTy |> List.head + let callerArgExprCoerced = mkCoerceIfNeeded g calledNonOptTy callerArgTy callerArgExpr + MakeMethInfoCall amap m minfo [] [callerArgExprCoerced] + +// Adjust all the optional arguments, filling in values for defaults, +let AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName (infoReader: InfoReader) ad (assignedArg: AssignedCalledArg<_>) = + let g = infoReader.g + let amap = infoReader.amap + let callerArg = assignedArg.CallerArg + let (CallerArg(callerArgTy, m, isOptCallerArg, callerArgExpr)) = callerArg + let calledArg = assignedArg.CalledArg + let isOutArg = calledArg.IsOutArg + let reflArgInfo = calledArg.ReflArgInfo + let calledArgTy = calledArg.CalledArgumentType + match calledArg.OptArgInfo with + | NotOptional when not (g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop) -> + if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) + assignedArg + + // For non-nullable, non-optional arguments no conversion is needed. + // We return precisely the assignedArg. This also covers the case where there + // can be a lingering permitted type mismatch between caller argument and called argument, + // specifically caller can by `byref` and called `outref`. No coercion is inserted in the + // expression tree in this case. + | NotOptional when not (isNullableTy g calledArgTy) -> + if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) + assignedArg + + | _ -> + + let callerArgExpr2 = + match calledArg.OptArgInfo with + | NotOptional -> + // T --> Nullable widening at callsites + if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) + if isNullableTy g calledArgTy then + if isNullableTy g callerArgTy then + callerArgExpr + else + let calledNonOptTy = destNullableTy g calledArgTy + let _, callerArgExpr2 = AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg calledNonOptTy reflArgInfo callerArgTy m callerArgExpr + MakeNullableExprIfNeeded infoReader calledArgTy callerArgTy callerArgExpr2 m + else + failwith "unreachable" // see case above + + | CallerSide dfltVal -> + let calledArgTy = calledArg.CalledArgumentType + + if isOptCallerArg then + // CSharpMethod(?x=b) + if isOptionTy g callerArgTy then + if isNullableTy g calledArgTy then + // CSharpMethod(?x=b) when 'b' has optional type and 'x' has nullable type --> CSharpMethod(x=Option.toNullable b) + mkOptionToNullable g m (destOptionTy g callerArgTy) callerArgExpr + else + // CSharpMethod(?x=b) when 'b' has optional type and 'x' has non-nullable type --> CSharpMethod(x=Option.defaultValue DEFAULT v) + let _wrapper, defaultExpr = GetDefaultExpressionForCallerSideOptionalArg tcFieldInit g calledArg calledArgTy dfltVal eCallerMemberName m + let ty = destOptionTy g callerArgTy + mkOptionDefaultValue g m ty defaultExpr callerArgExpr + else + // This should be unreachable but the error will be reported elsewhere + callerArgExpr + else + if isNullableTy g calledArgTy then + if isNullableTy g callerArgTy then + // CSharpMethod(x=b) when 'x' has nullable type + // CSharpMethod(x=b) when both 'x' and 'b' have nullable type --> CSharpMethod(x=b) + callerArgExpr + else + // CSharpMethod(x=b) when 'x' has nullable type and 'b' does not --> CSharpMethod(x=Nullable(b)) + let calledNonOptTy = destNullableTy g calledArgTy + let _, callerArgExpr2 = AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg calledNonOptTy reflArgInfo callerArgTy m callerArgExpr + MakeNullableExprIfNeeded infoReader calledArgTy callerArgTy callerArgExpr2 m + else + // CSharpMethod(x=b) --> CSharpMethod(?x=b) + let _, callerArgExpr2 = AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg calledArgTy reflArgInfo callerArgTy m callerArgExpr + callerArgExpr2 + + | CalleeSide -> + if isOptCallerArg then + // FSharpMethod(?x=b) --> FSharpMethod(?x=b) + callerArgExpr + else + // FSharpMethod(x=b) when FSharpMethod(A) --> FSharpMethod(?x=Some(b :> A)) + if isOptionTy g calledArgTy then + let calledNonOptTy = destOptionTy g calledArgTy + let _, callerArgExpr2 = AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg calledNonOptTy reflArgInfo callerArgTy m callerArgExpr + mkSome g calledNonOptTy callerArgExpr2 m + else + assert false + callerArgExpr // defensive code - this case is unreachable + + let callerArg2 = CallerArg(tyOfExpr g callerArgExpr2, m, isOptCallerArg, callerArgExpr2) + { assignedArg with CallerArg=callerArg2 } // Handle CallerSide optional arguments. // @@ -657,7 +1524,8 @@ let AdjustCallerArgExprForCoercions (g: TcGlobals) amap infoReader ad isOutArg c // - VB also allows you to pass intrinsic values as optional values to parameters // typed as Object. What we do in this case is we box the intrinsic value." // -let AdjustOptionalCallerArgExprs tcFieldInit eCallerMemberName g (calledMeth: CalledMeth<_>) mItem mMethExpr = +let AdjustCallerArgsForOptionals tcVal tcFieldInit eCallerMemberName (infoReader: InfoReader) ad (calledMeth: CalledMeth<_>) mItem mMethExpr = + let g = infoReader.g let assignedNamedArgs = calledMeth.ArgSets |> List.collect (fun argSet -> argSet.AssignedNamedArgs) let unnamedCalledArgs = calledMeth.ArgSets |> List.collect (fun argSet -> argSet.UnnamedCalledArgs) @@ -666,522 +1534,123 @@ let AdjustOptionalCallerArgExprs tcFieldInit eCallerMemberName g (calledMeth: Ca (unnamedCalledArgs, unnamedCallerArgs) ||> List.map2 (fun called caller -> { NamedArgIdOpt = None; CalledArg=called; CallerArg=caller }) - let emptyPreBinder (e: Expr) = e - - // Adjust all the optional arguments that require a default value to be inserted into the call + // Adjust all the optional arguments that require a default value to be inserted into the call, + // i.e. there is no corresponding caller arg. let optArgs, optArgPreBinder = - (emptyPreBinder, calledMeth.UnnamedCalledOptArgs) ||> List.mapFold (fun wrapper calledArg -> - let calledArgTy = calledArg.CalledArgumentType - let wrapper2, expr = - match calledArg.OptArgInfo with - | NotOptional -> - error(InternalError("Unexpected NotOptional", mItem)) - - | CallerSide dfltVal -> - - let rec build currCalledArgTy currDfltVal = - match currDfltVal with - | MissingValue -> - // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. - emptyPreBinder, mkAsmExpr ([ mkNormalLdsfld (fspec_Missing_Value g); AI_nop ], [], [], [currCalledArgTy], mMethExpr) - - | DefaultValue -> - emptyPreBinder, mkDefault(mMethExpr, currCalledArgTy) - - | Constant fieldInit -> - match currCalledArgTy with - | NullableTy g inst when fieldInit <> ILFieldInit.Null -> - let nullableTy = mkILNonGenericBoxedTy(g.FindSysILTypeRef "System.Nullable`1") - let ctor = mkILCtorMethSpecForTy(nullableTy, [ILType.TypeVar 0us]).MethodRef - let ctorArgs = [Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, inst)] - emptyPreBinder, Expr.Op (TOp.ILCall (false, false, true, true, NormalValUse, false, false, ctor, [inst], [], [currCalledArgTy]), [], ctorArgs, mMethExpr) - | ByrefTy g inst -> - build inst (PassByRef(inst, currDfltVal)) - | _ -> - match calledArg.CallerInfo, eCallerMemberName with - | CallerLineNumber, _ when typeEquiv g currCalledArgTy g.int_ty -> - emptyPreBinder, Expr.Const (Const.Int32(mMethExpr.StartLine), mMethExpr, currCalledArgTy) - | CallerFilePath, _ when typeEquiv g currCalledArgTy g.string_ty -> - let fileName = mMethExpr.FileName |> FileSystem.GetFullPathShim |> PathMap.apply g.pathMap - emptyPreBinder, Expr.Const (Const.String fileName, mMethExpr, currCalledArgTy) - | CallerMemberName, Some callerName when (typeEquiv g currCalledArgTy g.string_ty) -> - emptyPreBinder, Expr.Const (Const.String callerName, mMethExpr, currCalledArgTy) - | _ -> - emptyPreBinder, Expr.Const (tcFieldInit mMethExpr fieldInit, mMethExpr, currCalledArgTy) - - | WrapperForIDispatch -> - match g.TryFindSysILTypeRef "System.Runtime.InteropServices.DispatchWrapper" with - | None -> error(Error(FSComp.SR.fscSystemRuntimeInteropServicesIsRequired(), mMethExpr)) - | Some tref -> - let ty = mkILNonGenericBoxedTy tref - let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef - let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) - emptyPreBinder, expr - - | WrapperForIUnknown -> - match g.TryFindSysILTypeRef "System.Runtime.InteropServices.UnknownWrapper" with - | None -> error(Error(FSComp.SR.fscSystemRuntimeInteropServicesIsRequired(), mMethExpr)) - | Some tref -> - let ty = mkILNonGenericBoxedTy tref - let mref = mkILCtorMethSpecForTy(ty, [g.ilg.typ_Object]).MethodRef - let expr = Expr.Op (TOp.ILCall (false, false, false, true, NormalValUse, false, false, mref, [], [], [g.obj_ty]), [], [mkDefault(mMethExpr, currCalledArgTy)], mMethExpr) - emptyPreBinder, expr - - | PassByRef (ty, dfltVal2) -> - let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty - let wrapper2, rhs = build currCalledArgTy dfltVal2 - (wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr false (mkLocalValRef v) - build calledArgTy dfltVal - - | CalleeSide -> - let calledNonOptTy = - if isOptionTy g calledArgTy then - destOptionTy g calledArgTy - else - calledArgTy // should be unreachable - - match calledArg.CallerInfo, eCallerMemberName with - | CallerLineNumber, _ when typeEquiv g calledNonOptTy g.int_ty -> - let lineExpr = Expr.Const(Const.Int32 mMethExpr.StartLine, mMethExpr, calledNonOptTy) - emptyPreBinder, mkSome g calledNonOptTy lineExpr mMethExpr - | CallerFilePath, _ when typeEquiv g calledNonOptTy g.string_ty -> - let fileName = mMethExpr.FileName |> FileSystem.GetFullPathShim |> PathMap.apply g.pathMap - let filePathExpr = Expr.Const (Const.String(fileName), mMethExpr, calledNonOptTy) - emptyPreBinder, mkSome g calledNonOptTy filePathExpr mMethExpr - | CallerMemberName, Some(callerName) when typeEquiv g calledNonOptTy g.string_ty -> - let memberNameExpr = Expr.Const (Const.String callerName, mMethExpr, calledNonOptTy) - emptyPreBinder, mkSome g calledNonOptTy memberNameExpr mMethExpr - | _ -> - emptyPreBinder, mkNone g calledNonOptTy mMethExpr + (emptyPreBinder, calledMeth.UnnamedCalledOptArgs) ||> List.mapFold (fun preBinder calledArg -> + let preBinder2, arg = GetDefaultExpressionForOptionalArg tcFieldInit g calledArg eCallerMemberName mItem mMethExpr + arg, (preBinder >> preBinder2)) - // Combine the variable allocators (if any) - let wrapper = (wrapper >> wrapper2) - let callerArg = CallerArg(calledArgTy, mMethExpr, false, expr) - { NamedArgIdOpt = None; CalledArg = calledArg; CallerArg = callerArg }, wrapper) - - // Adjust all the optional arguments - let wrapOptionalArg (assignedArg: AssignedCalledArg<_>) = - let (CallerArg(callerArgTy, m, isOptCallerArg, callerArgExpr)) = assignedArg.CallerArg - match assignedArg.CalledArg.OptArgInfo with - | NotOptional -> - if isOptCallerArg then errorR(Error(FSComp.SR.tcFormalArgumentIsNotOptional(), m)) - assignedArg - | _ -> - let callerArgExpr2 = - match assignedArg.CalledArg.OptArgInfo with - | CallerSide _ -> - if isOptCallerArg then - // M(?x=bopt) when M(A) --> M(?x=bopt.Value) for caller-side - // STRUCT OPTIONS: if we allow struct options as optional arguments then we should take - // the address correctly. - mkUnionCaseFieldGetUnprovenViaExprAddr (callerArgExpr, mkSomeCase g, [destOptionTy g callerArgTy], 0, m) - else - // M(x=b) when M(A) --> M(?x=b) for caller-side - callerArgExpr - - | CalleeSide -> - if isOptCallerArg then - // M(?x=bopt) when M(A) --> M(?x=Some(bopt.Value)) - callerArgExpr - else - // M(x=b) when M(A) --> M(?x=Some(b :> A)) - let calledArgTy = assignedArg.CalledArg.CalledArgumentType - if isOptionTy g calledArgTy then - let calledNonOptTy = destOptionTy g calledArgTy - mkSome g calledNonOptTy (mkCoerceIfNeeded g calledNonOptTy callerArgTy callerArgExpr) m - else - callerArgExpr // should be unreachable - - | _ -> failwith "Unreachable" - { assignedArg with CallerArg=CallerArg(tyOfExpr g callerArgExpr2, m, isOptCallerArg, callerArgExpr2) } - - let adjustedNormalUnnamedArgs = List.map wrapOptionalArg unnamedArgs - let adjustedAssignedNamedArgs = List.map wrapOptionalArg assignedNamedArgs + let adjustedNormalUnnamedArgs = List.map (AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName infoReader ad) unnamedArgs + let adjustedAssignedNamedArgs = List.map (AdjustCallerArgForOptional tcVal tcFieldInit eCallerMemberName infoReader ad) assignedNamedArgs optArgs, optArgPreBinder, adjustedNormalUnnamedArgs, adjustedAssignedNamedArgs /// Adjust any 'out' arguments, passing in the address of a mutable local -let AdjustOutCallerArgExprs g (calledMeth: CalledMeth<_>) mMethExpr = +let AdjustOutCallerArgs g (calledMeth: CalledMeth<_>) mMethExpr = calledMeth.UnnamedCalledOutArgs |> List.map (fun calledArg -> let calledArgTy = calledArg.CalledArgumentType let outArgTy = destByrefTy g calledArgTy - let outv, outArgExpr = mkMutableCompGenLocal mMethExpr PrettyNaming.outArgCompilerGeneratedName outArgTy // mutable! - let expr = mkDefault (mMethExpr, outArgTy) - let callerArg = CallerArg (calledArgTy, mMethExpr, false, mkValAddr mMethExpr false (mkLocalValRef outv)) - let outArg = { NamedArgIdOpt=None;CalledArg=calledArg;CallerArg=callerArg } - outArg, outArgExpr, mkCompGenBind outv expr) - |> List.unzip3 - -let AdjustParamArrayCallerArgExprs g amap infoReader ad (calledMeth: CalledMeth<_>) mMethExpr = - let argSets = calledMeth.ArgSets - - let paramArrayCallerArgs = argSets |> List.collect (fun argSet -> argSet.ParamArrayCallerArgs) - match calledMeth.ParamArrayCalledArgOpt with - | None -> - [], [] - | Some paramArrayCalledArg -> - let paramArrayCalledArgElementType = destArrayTy g paramArrayCalledArg.CalledArgumentType - - let paramArrayPreBinders, es = - paramArrayCallerArgs - |> List.map (fun callerArg -> - let (CallerArg(callerArgTy, m, isOutArg, callerArgExpr)) = callerArg - AdjustCallerArgExprForCoercions g amap infoReader ad isOutArg paramArrayCalledArgElementType paramArrayCalledArg.ReflArgInfo callerArgTy m callerArgExpr) - |> List.unzip - - let arg = - [ { NamedArgIdOpt = None - CalledArg=paramArrayCalledArg - CallerArg=CallerArg(paramArrayCalledArg.CalledArgumentType, mMethExpr, false, Expr.Op (TOp.Array, [paramArrayCalledArgElementType], es, mMethExpr)) } ] - paramArrayPreBinders, arg - -/// Build the argument list for a method call. Adjust for param array, optional arguments, byref arguments and coercions. -/// For example, if you pass an F# reference cell to a byref then we must get the address of the -/// contents of the ref. Likewise lots of adjustments are made for optional arguments etc. -let AdjustCallerArgExprs tcFieldInit eCallerMemberName g amap infoReader ad (calledMeth: CalledMeth<_>) objArgs lambdaVars mItem mMethExpr = - let calledMethInfo = calledMeth.Method - - // Some of the code below must allocate temporary variables or bind other variables to particular values. - // As usual we represent variable allocators by expr -> expr functions - // which we then use to wrap the whole expression. These will either do nothing or pre-bind a variable. It doesn't - // matter what order they are applied in as long as they are all composed together. - let emptyPreBinder (e: Expr) = e - - // For unapplied 'e.M' we first evaluate 'e' outside the lambda, i.e. 'let v = e in (fun arg -> v.M(arg))' - let objArgPreBinder, objArgs = - match objArgs, lambdaVars with - | [objArg], Some _ -> - if calledMethInfo.IsExtensionMember && calledMethInfo.ObjArgNeedsAddress(amap, mMethExpr) then - error(Error(FSComp.SR.tcCannotPartiallyApplyExtensionMethodForByref(calledMethInfo.DisplayName), mMethExpr)) - let objArgTy = tyOfExpr g objArg - let v, ve = mkCompGenLocal mMethExpr "objectArg" objArgTy - (fun body -> mkCompGenLet mMethExpr v objArg body), [ve] - | _ -> - emptyPreBinder, objArgs - - // Handle param array and optional arguments - let paramArrayPreBinders, paramArrayArgs = - AdjustParamArrayCallerArgExprs g amap infoReader ad calledMeth mMethExpr - - let optArgs, optArgPreBinder, adjustedNormalUnnamedArgs, adjustedFinalAssignedNamedArgs = - AdjustOptionalCallerArgExprs tcFieldInit eCallerMemberName g calledMeth mItem mMethExpr - - let outArgs, outArgExprs, outArgTmpBinds = - AdjustOutCallerArgExprs g calledMeth mMethExpr - - let allArgs = - adjustedNormalUnnamedArgs @ - adjustedFinalAssignedNamedArgs @ - paramArrayArgs @ - optArgs @ - outArgs - - let allArgs = - allArgs |> List.sortBy (fun x -> x.Position) - - let allArgsPreBinders, allArgsCoerced = - allArgs - |> List.map (fun assignedArg -> - let isOutArg = assignedArg.CalledArg.IsOutArg - let reflArgInfo = assignedArg.CalledArg.ReflArgInfo - let calledArgTy = assignedArg.CalledArg.CalledArgumentType - let (CallerArg(callerArgTy, m, _, e)) = assignedArg.CallerArg - - AdjustCallerArgExprForCoercions g amap infoReader ad isOutArg calledArgTy reflArgInfo callerArgTy m e) - |> List.unzip - - objArgPreBinder, objArgs, allArgsPreBinders, allArgs, allArgsCoerced, optArgPreBinder, paramArrayPreBinders, outArgExprs, outArgTmpBinds - -//------------------------------------------------------------------------- -// Additional helpers for building method calls and doing TAST generation -//------------------------------------------------------------------------- - -/// Is this a 'base' call (in the sense of C#) -let IsBaseCall objArgs = - match objArgs with - | [Expr.Val (v, _, _)] when v.BaseOrThisInfo = BaseVal -> true - | _ -> false - -/// Compute whether we insert a 'coerce' on the 'this' pointer for an object model call -/// For example, when calling an interface method on a struct, or a method on a constrained -/// variable type. -let ComputeConstrainedCallInfo g amap m (objArgs, minfo: MethInfo) = - match objArgs with - | [objArgExpr] when not minfo.IsExtensionMember -> - let methObjTy = minfo.ApparentEnclosingType - let objArgTy = tyOfExpr g objArgExpr - if TypeDefinitelySubsumesTypeNoCoercion 0 g amap m methObjTy objArgTy - // Constrained calls to class types can only ever be needed for the three class types that - // are base types of value types - || (isClassTy g methObjTy && - (not (typeEquiv g methObjTy g.system_Object_ty || - typeEquiv g methObjTy g.system_Value_ty || - typeEquiv g methObjTy g.system_Enum_ty))) then - None - else - // The object argument is a value type or variable type and the target method is an interface or System.Object - // type. A .NET 2.0 generic constrained call is required - Some objArgTy - | _ -> - None - -/// Adjust the 'this' pointer before making a call -/// Take the address of a struct, and coerce to an interface/base/constraint type if necessary -let TakeObjAddrForMethodCall g amap (minfo: MethInfo) isMutable m objArgs f = - let ccallInfo = ComputeConstrainedCallInfo g amap m (objArgs, minfo) - - let wrap, objArgs = - - match objArgs with - | [objArgExpr] -> - - let hasCallInfo = ccallInfo.IsSome - let mustTakeAddress = hasCallInfo || minfo.ObjArgNeedsAddress(amap, m) - let objArgTy = tyOfExpr g objArgExpr - - let isMutable = - match isMutable with - | DefinitelyMutates - | NeverMutates - | AddressOfOp -> isMutable - | PossiblyMutates -> - // Check to see if the method is read-only. Perf optimization. - // If there is an extension member whose first arg is an inref, we must return NeverMutates. - if mustTakeAddress && (minfo.IsReadOnly || minfo.IsReadOnlyExtensionMember (amap, m)) then - NeverMutates - else - isMutable - - let wrap, objArgExprAddr, isReadOnly, _isWriteOnly = - mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m - - // Extension members and calls to class constraints may need a coercion for their object argument - let objArgExprCoerced = - if not hasCallInfo && - not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.ApparentEnclosingType objArgTy) then - mkCoerceExpr(objArgExprAddr, minfo.ApparentEnclosingType, m, objArgTy) - else - objArgExprAddr - - // Check to see if the extension member uses the extending type as a byref. - // If so, make sure we don't allow readonly/immutable values to be passed byref from an extension member. - // An inref will work though. - if isReadOnly && mustTakeAddress && minfo.IsExtensionMember then - minfo.TryObjArgByrefType(amap, m, minfo.FormalMethodInst) - |> Option.iter (fun ty -> - if not (isInByrefTy g ty) then - errorR(Error(FSComp.SR.tcCannotCallExtensionMethodInrefToByref(minfo.DisplayName), m))) - - - wrap, [objArgExprCoerced] - - | _ -> - id, objArgs - let e, ety = f ccallInfo objArgs - wrap e, ety - -//------------------------------------------------------------------------- -// Build method calls. -//------------------------------------------------------------------------- - -/// Build an expression node that is a call to a .NET method. -let BuildILMethInfoCall g amap m isProp (minfo: ILMethInfo) valUseFlags minst direct args = - let valu = isStructTy g minfo.ApparentEnclosingType - let ctor = minfo.IsConstructor - if minfo.IsClassConstructor then - error (InternalError (minfo.ILName+": cannot call a class constructor", m)) - let useCallvirt = - not valu && not direct && minfo.IsVirtual - let isProtected = minfo.IsProtectedAccessibility - let ilMethRef = minfo.ILMethodRef - let newobj = ctor && (match valUseFlags with NormalValUse -> true | _ -> false) - let exprTy = if ctor then minfo.ApparentEnclosingType else minfo.GetFSharpReturnTy(amap, m, minst) - let retTy = if not ctor && ilMethRef.ReturnType = ILType.Void then [] else [exprTy] - let isDllImport = minfo.IsDllImport g - Expr.Op (TOp.ILCall (useCallvirt, isProtected, valu, newobj, valUseFlags, isProp, isDllImport, ilMethRef, minfo.DeclaringTypeInst, minst, retTy), [], args, m), - exprTy - - -/// Build a call to an F# method. -/// -/// Consume the arguments in chunks and build applications. This copes with various F# calling signatures -/// all of which ultimately become 'methods'. -/// -/// QUERY: this looks overly complex considering that we are doing a fundamentally simple -/// thing here. -let BuildFSharpMethodApp g m (vref: ValRef) vexp vexprty (args: Exprs) = - let arities = (arityOfVal vref.Deref).AritiesOfArgs - - let args3, (leftover, retTy) = - let exprL expr = exprL g expr - ((args, vexprty), arities) ||> List.mapFold (fun (args, fty) arity -> - match arity, args with - | (0|1), [] when typeEquiv g (domainOfFunTy g fty) g.unit_ty -> mkUnit g m, (args, rangeOfFunTy g fty) - | 0, (arg :: argst) -> - let msg = Layout.showL (Layout.sepListL (Layout.rightL (Layout.TaggedTextOps.tagText ";")) (List.map exprL args)) - warning(InternalError(sprintf "Unexpected zero arity, args = %s" msg, m)) - arg, (argst, rangeOfFunTy g fty) - | 1, (arg :: argst) -> arg, (argst, rangeOfFunTy g fty) - | 1, [] -> error(InternalError("expected additional arguments here", m)) - | _ -> - if args.Length < arity then - error(InternalError("internal error in getting arguments, n = "+string arity+", #args = "+string args.Length, m)) - let tupargs, argst = List.splitAt arity args - let tuptys = tupargs |> List.map (tyOfExpr g) - (mkRefTupled g m tupargs tuptys), - (argst, rangeOfFunTy g fty) ) - if not leftover.IsEmpty then error(InternalError("Unexpected "+string(leftover.Length)+" remaining arguments in method application", m)) - mkApps g ((vexp, vexprty), [], args3, m), - retTy - -/// Build a call to an F# method. -let BuildFSharpMethodCall g m (ty, vref: ValRef) valUseFlags minst args = - let vexp = Expr.Val (vref, valUseFlags, m) - let vexpty = vref.Type - let tpsorig, tau = vref.TypeScheme - let vtinst = argsOfAppTy g ty @ minst - if tpsorig.Length <> vtinst.Length then error(InternalError("BuildFSharpMethodCall: unexpected List.length mismatch", m)) - let expr = mkTyAppExpr m (vexp, vexpty) vtinst - let exprty = instType (mkTyparInst tpsorig vtinst) tau - BuildFSharpMethodApp g m vref expr exprty args - + let outv, outArgExpr = mkMutableCompGenLocal mMethExpr outArgCompilerGeneratedName outArgTy // mutable! + let expr = mkDefault (mMethExpr, outArgTy) + let callerArg = CallerArg (calledArgTy, mMethExpr, false, mkValAddr mMethExpr false (mkLocalValRef outv)) + let outArg = { NamedArgIdOpt=None;CalledArg=calledArg;CallerArg=callerArg } + outArg, outArgExpr, mkCompGenBind outv expr) + |> List.unzip3 -/// Make a call to a method info. Used by the optimizer and code generator to build -/// calls to the type-directed solutions to member constraints. -let MakeMethInfoCall amap m minfo minst args = - let valUseFlags = NormalValUse // correct unless if we allow wild trait constraints like "T has a ctor and can be used as a parent class" - match minfo with - | ILMeth(g, ilminfo, _) -> - let direct = not minfo.IsVirtual - let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant - BuildILMethInfoCall g amap m isProp ilminfo valUseFlags minst direct args |> fst - | FSMeth(g, ty, vref, _) -> - BuildFSharpMethodCall g m (ty, vref) valUseFlags minst args |> fst - | DefaultStructCtor(_, ty) -> - mkDefault (m, ty) -#if !NO_EXTENSIONTYPING - | ProvidedMeth(amap, mi, _, m) -> - let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant - let ilMethodRef = Import.ImportProvidedMethodBaseAsILMethodRef amap m mi - let isConstructor = mi.PUntaint((fun c -> c.IsConstructor), m) - let valu = mi.PUntaint((fun c -> c.DeclaringType.IsValueType), m) - let actualTypeInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here - let actualMethInst = [] // GENERIC TYPE PROVIDERS: for generics, we would have something here - let ilReturnTys = Option.toList (minfo.GetCompiledReturnTy(amap, m, [])) // GENERIC TYPE PROVIDERS: for generics, we would have more here - // REVIEW: Should we allow protected calls? - Expr.Op (TOp.ILCall (false, false, valu, isConstructor, valUseFlags, isProp, false, ilMethodRef, actualTypeInst, actualMethInst, ilReturnTys), [], args, m) +/// Adjust any '[]' arguments, converting to an array +let AdjustParamArrayCallerArgs tcVal g amap infoReader ad (calledMeth: CalledMeth<_>) mMethExpr = + let argSets = calledMeth.ArgSets -#endif + let paramArrayCallerArgs = argSets |> List.collect (fun argSet -> argSet.ParamArrayCallerArgs) -#if !NO_EXTENSIONTYPING -// This imports a provided method, and checks if it is a known compiler intrinsic like "1 + 2" -let TryImportProvidedMethodBaseAsLibraryIntrinsic (amap: Import.ImportMap, m: range, mbase: Tainted) = - let methodName = mbase.PUntaint((fun x -> x.Name), m) - let declaringType = Import.ImportProvidedType amap m (mbase.PApply((fun x -> x.DeclaringType), m)) - if isAppTy amap.g declaringType then - let declaringEntity = tcrefOfAppTy amap.g declaringType - if not declaringEntity.IsLocalRef && ccuEq declaringEntity.nlr.Ccu amap.g.fslibCcu then - match amap.g.knownIntrinsics.TryGetValue ((declaringEntity.LogicalName, methodName)) with - | true, vref -> Some vref - | _ -> - match amap.g.knownFSharpCoreModules.TryGetValue declaringEntity.LogicalName with - | true, modRef -> - modRef.ModuleOrNamespaceType.AllValsByLogicalName - |> Seq.tryPick (fun (KeyValue(_, v)) -> if (v.CompiledName amap.g.CompilerGlobalState) = methodName then Some (mkNestedValRef modRef v) else None) - | _ -> None - else - None - else - None -#endif + match calledMeth.ParamArrayCalledArgOpt with + | None -> + [], [] + + | Some paramArrayCalledArg -> + let paramArrayCalledArgElementType = destArrayTy g paramArrayCalledArg.CalledArgumentType + + let paramArrayPreBinders, paramArrayExprs = + paramArrayCallerArgs + |> List.map (fun callerArg -> + let (CallerArg(callerArgTy, m, isOutArg, callerArgExpr)) = callerArg + AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg paramArrayCalledArgElementType paramArrayCalledArg.ReflArgInfo callerArgTy m callerArgExpr) + |> List.unzip + + let paramArrayExpr = Expr.Op (TOp.Array, [paramArrayCalledArgElementType], paramArrayExprs, mMethExpr) + let paramArrayCallerArg = + [ { NamedArgIdOpt = None + CalledArg=paramArrayCalledArg + CallerArg=CallerArg(paramArrayCalledArg.CalledArgumentType, mMethExpr, false, paramArrayExpr) } ] -/// Build an expression that calls a given method info. -/// This is called after overload resolution, and also to call other -/// methods such as 'setters' for properties. -// tcVal: used to convert an F# value into an expression. See tc.fs. -// isProp: is it a property get? -// minst: the instantiation to apply for a generic method -// objArgs: the 'this' argument, if any -// args: the arguments, if any -let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objArgs args = - let direct = IsBaseCall objArgs + paramArrayPreBinders, paramArrayCallerArg - TakeObjAddrForMethodCall g amap minfo isMutable m objArgs (fun ccallInfo objArgs -> - let allArgs = objArgs @ args - let valUseFlags = - if direct && (match valUseFlags with NormalValUse -> true | _ -> false) then - VSlotDirectCall - else - match ccallInfo with - | Some ty -> - // printfn "possible constrained call to '%s' at %A" minfo.LogicalName m - PossibleConstrainedCall ty - | None -> - valUseFlags +/// Build the argument list for a method call. Adjust for param array, optional arguments, byref arguments and coercions. +/// For example, if you pass an F# reference cell to a byref then we must get the address of the +/// contents of the ref. Likewise lots of adjustments are made for optional arguments etc. +let AdjustCallerArgs tcVal tcFieldInit eCallerMemberName (infoReader: InfoReader) ad (calledMeth: CalledMeth<_>) objArgs lambdaVars mItem mMethExpr = + let g = infoReader.g + let amap = infoReader.amap + let calledMethInfo = calledMeth.Method - match minfo with -#if !NO_EXTENSIONTYPING - // By this time this is an erased method info, e.g. one returned from an expression - // REVIEW: copied from tastops, which doesn't allow protected methods - | ProvidedMeth (amap, providedMeth, _, _) -> - // TODO: there is a fair bit of duplication here with mk_il_minfo_call. We should be able to merge these - - /// Build an expression node that is a call to a extension method in a generated assembly - let enclTy = minfo.ApparentEnclosingType - // prohibit calls to methods that are declared in specific array types (Get, Set, Address) - // these calls are provided by the runtime and should not be called from the user code - if isArrayTy g enclTy then - let tpe = TypeProviderError(FSComp.SR.tcRuntimeSuppliedMethodCannotBeUsedInUserCode(minfo.DisplayName), providedMeth.TypeProviderDesignation, m) - error tpe - let valu = isStructTy g enclTy - let isCtor = minfo.IsConstructor - if minfo.IsClassConstructor then - error (InternalError (minfo.LogicalName + ": cannot call a class constructor", m)) - let useCallvirt = not valu && not direct && minfo.IsVirtual - let isProtected = minfo.IsProtectedAccessibility - let exprTy = if isCtor then enclTy else minfo.GetFSharpReturnTy(amap, m, minst) - match TryImportProvidedMethodBaseAsLibraryIntrinsic (amap, m, providedMeth) with - | Some fsValRef -> - //reraise() calls are converted to TOp.Reraise in the type checker. So if a provided expression includes a reraise call - // we must put it in that form here. - if valRefEq amap.g fsValRef amap.g.reraise_vref then - mkReraise m exprTy, exprTy - else - let vexp, vexpty = tcVal fsValRef valUseFlags (minfo.DeclaringTypeInst @ minst) m - BuildFSharpMethodApp g m fsValRef vexp vexpty allArgs - | None -> - let ilMethRef = Import.ImportProvidedMethodBaseAsILMethodRef amap m providedMeth - let isNewObj = isCtor && (match valUseFlags with NormalValUse -> true | _ -> false) - let actualTypeInst = - if isRefTupleTy g enclTy then argsOfAppTy g (mkCompiledTupleTy g false (destRefTupleTy g enclTy)) // provided expressions can include method calls that get properties of tuple types - elif isFunTy g enclTy then [ domainOfFunTy g enclTy; rangeOfFunTy g enclTy ] // provided expressions can call Invoke - else minfo.DeclaringTypeInst - let actualMethInst = minst - let retTy = if not isCtor && (ilMethRef.ReturnType = ILType.Void) then [] else [exprTy] - let noTailCall = false - let expr = Expr.Op (TOp.ILCall (useCallvirt, isProtected, valu, isNewObj, valUseFlags, isProp, noTailCall, ilMethRef, actualTypeInst, actualMethInst, retTy), [], allArgs, m) - expr, exprTy + // For unapplied 'e.M' we first evaluate 'e' outside the lambda, i.e. 'let v = e in (fun arg -> v.CSharpMethod(arg))' + let objArgPreBinder, objArgs = + match objArgs, lambdaVars with + | [objArg], Some _ -> + if calledMethInfo.IsExtensionMember && calledMethInfo.ObjArgNeedsAddress(amap, mMethExpr) then + error(Error(FSComp.SR.tcCannotPartiallyApplyExtensionMethodForByref(calledMethInfo.DisplayName), mMethExpr)) + let objArgTy = tyOfExpr g objArg + let v, ve = mkCompGenLocal mMethExpr "objectArg" objArgTy + (fun body -> mkCompGenLet mMethExpr v objArg body), [ve] + | _ -> + emptyPreBinder, objArgs -#endif - - // Build a call to a .NET method - | ILMeth(_, ilMethInfo, _) -> - BuildILMethInfoCall g amap m isProp ilMethInfo valUseFlags minst direct allArgs + // Handle param array and optional arguments + let paramArrayPreBinders, paramArrayArgs = + AdjustParamArrayCallerArgs tcVal g amap infoReader ad calledMeth mMethExpr - // Build a call to an F# method - | FSMeth(_, _, vref, _) -> + let optArgs, optArgPreBinder, adjustedNormalUnnamedArgs, adjustedFinalAssignedNamedArgs = + AdjustCallerArgsForOptionals tcVal tcFieldInit eCallerMemberName infoReader ad calledMeth mItem mMethExpr - // Go see if this is a use of a recursive definition... Note we know the value instantiation - // we want to use so we pass that in order not to create a new one. - let vexp, vexpty = tcVal vref valUseFlags (minfo.DeclaringTypeInst @ minst) m - BuildFSharpMethodApp g m vref vexp vexpty allArgs + let outArgs, outArgExprs, outArgTmpBinds = + AdjustOutCallerArgs g calledMeth mMethExpr + + let adjustedNormalUnnamedArgs, setterValueArgs = + // IsIndexParamArraySetter onlye occurs for + // expr.[indexes] <- value + // where the 'value' arg to the setter is always the last unnamed argument (there is no syntax to use a named argument for it) + // Indeed in this case there will be no named/optional/out arguments. + if calledMeth.IsIndexParamArraySetter && not adjustedNormalUnnamedArgs.IsEmpty then + let a,b = List.frontAndBack adjustedNormalUnnamedArgs + a, [b] + else + adjustedNormalUnnamedArgs, [] - // Build a 'call' to a struct default constructor - | DefaultStructCtor (g, ty) -> - if not (TypeHasDefaultValue g m ty) then - errorR(Error(FSComp.SR.tcDefaultStructConstructorCall(), m)) - mkDefault (m, ty), ty) + let allArgs = + adjustedNormalUnnamedArgs @ + adjustedFinalAssignedNamedArgs @ + paramArrayArgs @ + setterValueArgs @ + optArgs @ + outArgs + + let allArgs = + allArgs |> List.sortBy (fun x -> x.Position) + + let allArgsPreBinders, allArgsCoerced = + allArgs + |> List.map (fun assignedArg -> + let isOutArg = assignedArg.CalledArg.IsOutArg + let reflArgInfo = assignedArg.CalledArg.ReflArgInfo + let calledArgTy = assignedArg.CalledArg.CalledArgumentType + let (CallerArg(callerArgTy, m, _, e)) = assignedArg.CallerArg + + AdjustCallerArgExpr tcVal g amap infoReader ad isOutArg calledArgTy reflArgInfo callerArgTy m e) + |> List.unzip + + objArgPreBinder, objArgs, allArgsPreBinders, allArgs, allArgsCoerced, optArgPreBinder, paramArrayPreBinders, outArgExprs, outArgTmpBinds //------------------------------------------------------------------------- @@ -1194,7 +1663,7 @@ let BuildMethodCall tcVal g amap isMutable m isProp minfo valUseFlags minst objA module ProvidedMethodCalls = let private convertConstExpr g amap m (constant : Tainted) = - let (obj, objTy) = constant.PApply2(id, m) + let obj, objTy = constant.PApply2(id, m) let ty = Import.ImportProvidedType amap m objTy let normTy = normalizeEnumTy g ty obj.PUntaint((fun v -> @@ -1241,13 +1710,13 @@ module ProvidedMethodCalls = elif st.PUntaint((fun st -> st.IsArray), m) then let et = st.PApply((fun st -> st.GetElementType()), m) let rank = st.PUntaint((fun st -> st.GetArrayRank()), m) - (loop et).PApply((fun st -> ProvidedType.CreateNoContext(if rank = 1 then st.RawSystemType.MakeArrayType() else st.RawSystemType.MakeArrayType(rank))), m) + (loop et).PApply((fun st -> if rank = 1 then st.MakeArrayType() else st.MakeArrayType(rank)), m) elif st.PUntaint((fun st -> st.IsByRef), m) then let et = st.PApply((fun st -> st.GetElementType()), m) - (loop et).PApply((fun st -> ProvidedType.CreateNoContext(st.RawSystemType.MakeByRefType())), m) + (loop et).PApply((fun st -> st.MakeByRefType()), m) elif st.PUntaint((fun st -> st.IsPointer), m) then let et = st.PApply((fun st -> st.GetElementType()), m) - (loop et).PApply((fun st -> ProvidedType.CreateNoContext(st.RawSystemType.MakePointerType())), m) + (loop et).PApply((fun st -> st.MakePointerType()), m) else let isGeneric = st.PUntaint((fun st -> st.IsGenericType), m) let headType = if isGeneric then st.PApply((fun st -> st.GetGenericTypeDefinition()), m) else st @@ -1266,17 +1735,17 @@ module ProvidedMethodCalls = let typars = headTypeAsFSharpType.Typars(m) // Drop the generic arguments that don't correspond to type arguments, i.e. are units-of-measure let genericArgs = - [| for (genericArg, tp) in Seq.zip genericArgs typars do + [| for genericArg, tp in Seq.zip genericArgs typars do if tp.Kind = TyparKind.Type then yield genericArg |] - if genericArgs.Length = 0 then + if genericArgs.Length = 0 then headType else let erasedArgTys = genericArgs |> Array.map loop headType.PApply((fun st -> - let erasedArgTys = erasedArgTys |> Array.map (fun a -> a.PUntaintNoFailure (fun x -> x.RawSystemType)) - ProvidedType.CreateNoContext(st.RawSystemType.MakeGenericType erasedArgTys)), m) + let erasedArgTys = erasedArgTys |> Array.map (fun a -> a.PUntaintNoFailure(id)) + st.MakeGenericType erasedArgTys), m) else st loop inputType @@ -1301,123 +1770,99 @@ module ProvidedMethodCalls = match ea with | Tainted.Null -> error(Error(FSComp.SR.etNullProvidedExpression(ea.TypeProviderDesignation), m)) | _ -> - match ea.PApplyOption((function ProvidedTypeAsExpr x -> Some x | _ -> None), m) with - | Some info -> - let (expr, targetTy) = info.PApply2(id, m) + let exprType = ea.PApplyOption((fun x -> x.GetExprType()), m) + let exprType = match exprType with | Some exprType -> exprType | None -> fail() + match exprType.PUntaint(id, m) with + | ProvidedTypeAsExpr (expr, targetTy) -> + let expr, targetTy = exprType.PApply2((fun _ -> (expr, targetTy)), m) let srcExpr = exprToExpr expr let targetTy = Import.ImportProvidedType amap m (targetTy.PApply(id, m)) let sourceTy = Import.ImportProvidedType amap m (expr.PApply ((fun e -> e.Type), m)) let te = mkCoerceIfNeeded g targetTy sourceTy srcExpr None, (te, tyOfExpr g te) - | None -> - match ea.PApplyOption((function ProvidedTypeTestExpr x -> Some x | _ -> None), m) with - | Some info -> - let (expr, targetTy) = info.PApply2(id, m) + | ProvidedTypeTestExpr (expr, targetTy) -> + let expr, targetTy = exprType.PApply2((fun _ -> (expr, targetTy)), m) let srcExpr = exprToExpr expr let targetTy = Import.ImportProvidedType amap m (targetTy.PApply(id, m)) let te = mkCallTypeTest g m targetTy srcExpr None, (te, tyOfExpr g te) - | None -> - match ea.PApplyOption((function ProvidedIfThenElseExpr x -> Some x | _ -> None), m) with - | Some info -> - let test, thenBranch, elseBranch = info.PApply3(id, m) + | ProvidedIfThenElseExpr (test, thenBranch, elseBranch) -> + let test, thenBranch, elseBranch = exprType.PApply3((fun _ -> (test, thenBranch, elseBranch)), m) let testExpr = exprToExpr test let ifTrueExpr = exprToExpr thenBranch let ifFalseExpr = exprToExpr elseBranch - let te = mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m (tyOfExpr g ifTrueExpr) testExpr ifTrueExpr ifFalseExpr + let te = mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m (tyOfExpr g ifTrueExpr) testExpr ifTrueExpr ifFalseExpr None, (te, tyOfExpr g te) - | None -> - match ea.PApplyOption((function ProvidedVarExpr x -> Some x | _ -> None), m) with - | Some info -> - let _, vTe = varToExpr info + | ProvidedVarExpr providedVar -> + let _, vTe = varToExpr (exprType.PApply((fun _ -> providedVar), m)) None, (vTe, tyOfExpr g vTe) - | None -> - match ea.PApplyOption((function ProvidedConstantExpr x -> Some x | _ -> None), m) with - | Some info -> - let ce = convertConstExpr g amap m info + | ProvidedConstantExpr (obj, prType) -> + let ce = convertConstExpr g amap m (exprType.PApply((fun _ -> (obj, prType)), m)) None, (ce, tyOfExpr g ce) - | None -> - match ea.PApplyOption((function ProvidedNewTupleExpr x -> Some x | _ -> None), m) with - | Some info -> - let elems = info.PApplyArray(id, "GetInvokerExpression", m) + | ProvidedNewTupleExpr info -> + let elems = exprType.PApplyArray((fun _ -> info), "GetInvokerExpression", m) let elemsT = elems |> Array.map exprToExpr |> Array.toList let exprT = mkRefTupledNoTypes g m elemsT None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedNewArrayExpr x -> Some x | _ -> None), m) with - | Some info -> - let ty, elems = info.PApply2(id, m) + | ProvidedNewArrayExpr (ty, elems) -> + let ty, elems = exprType.PApply2((fun _ -> (ty, elems)), m) let tyT = Import.ImportProvidedType amap m ty let elems = elems.PApplyArray(id, "GetInvokerExpression", m) let elemsT = elems |> Array.map exprToExpr |> Array.toList let exprT = Expr.Op (TOp.Array, [tyT], elemsT, m) None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedTupleGetExpr x -> Some x | _ -> None), m) with - | Some info -> - let inp, n = info.PApply2(id, m) + | ProvidedTupleGetExpr (inp, n) -> + let inp, n = exprType.PApply2((fun _ -> (inp, n)), m) let inpT = inp |> exprToExpr // if type of expression is erased type then we need convert it to the underlying base type - let typeOfExpr = + let typeOfExpr = let t = tyOfExpr g inpT stripTyEqnsWrtErasure EraseMeasures g t let tupInfo, tysT = tryDestAnyTupleTy g typeOfExpr let exprT = mkTupleFieldGet g (tupInfo, inpT, tysT, n.PUntaint(id, m), m) None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedLambdaExpr x -> Some x | _ -> None), m) with - | Some info -> - let v, b = info.PApply2(id, m) + | ProvidedLambdaExpr (v, b) -> + let v, b = exprType.PApply2((fun _ -> (v, b)), m) let vT = addVar v let bT = exprToExpr b removeVar v let exprT = mkLambda m vT (bT, tyOfExpr g bT) None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedLetExpr x -> Some x | _ -> None), m) with - | Some info -> - let v, e, b = info.PApply3(id, m) + | ProvidedLetExpr (v, e, b) -> + let v, e, b = exprType.PApply3((fun _ -> (v, e, b)), m) let eT = exprToExpr e let vT = addVar v let bT = exprToExpr b removeVar v let exprT = mkCompGenLet m vT eT bT None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedVarSetExpr x -> Some x | _ -> None), m) with - | Some info -> - let v, e = info.PApply2(id, m) + | ProvidedVarSetExpr (v, e) -> + let v, e = exprType.PApply2((fun _ -> (v, e)), m) let eT = exprToExpr e let vTopt, _ = varToExpr v match vTopt with | None -> fail() - | Some vT -> + | Some vT -> let exprT = mkValSet m (mkLocalValRef vT) eT None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedWhileLoopExpr x -> Some x | _ -> None), m) with - | Some info -> - let guardExpr, bodyExpr = info.PApply2(id, m) + | ProvidedWhileLoopExpr (guardExpr, bodyExpr) -> + let guardExpr, bodyExpr = (exprType.PApply2((fun _ -> (guardExpr, bodyExpr)), m)) let guardExprT = exprToExpr guardExpr let bodyExprT = exprToExpr bodyExpr - let exprT = mkWhile g (SequencePointInfoForWhileLoop.NoSequencePointAtWhileLoop, SpecialWhileLoopMarker.NoSpecialWhileLoopMarker, guardExprT, bodyExprT, m) + let exprT = mkWhile g (DebugPointAtWhile.No, SpecialWhileLoopMarker.NoSpecialWhileLoopMarker, guardExprT, bodyExprT, m) None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedForIntegerRangeLoopExpr x -> Some x | _ -> None), m) with - | Some info -> - let v, e1, e2, e3 = info.PApply4(id, m) + | ProvidedForIntegerRangeLoopExpr (v, e1, e2, e3) -> + let v, e1, e2, e3 = exprType.PApply4((fun _ -> (v, e1, e2, e3)), m) let e1T = exprToExpr e1 let e2T = exprToExpr e2 let vT = addVar v let e3T = exprToExpr e3 removeVar v - let exprT = mkFastForLoop g (SequencePointInfoForForLoop.NoSequencePointAtForLoop, m, vT, e1T, true, e2T, e3T) + let exprT = mkFastForLoop g (DebugPointAtFor.No, m, vT, e1T, true, e2T, e3T) None, (exprT, tyOfExpr g exprT) - | None -> - match ea.PApplyOption((function ProvidedNewDelegateExpr x -> Some x | _ -> None), m) with - | Some info -> - let delegateTy, boundVars, delegateBodyExpr = info.PApply3(id, m) + | ProvidedNewDelegateExpr (delegateTy, boundVars, delegateBodyExpr) -> + let delegateTy, boundVars, delegateBodyExpr = exprType.PApply3((fun _ -> (delegateTy, boundVars, delegateBodyExpr)), m) let delegateTyT = Import.ImportProvidedType amap m delegateTy let vs = boundVars.PApplyArray(id, "GetInvokerExpression", m) |> Array.toList let vsT = List.map addVar vs @@ -1428,44 +1873,33 @@ module ProvidedMethodCalls = let infoReader = InfoReader(g, amap) let exprT = CoerceFromFSharpFuncToDelegate g amap infoReader AccessorDomain.AccessibleFromSomewhere lambdaExprTy m lambdaExpr delegateTyT None, (exprT, tyOfExpr g exprT) - | None -> #if PROVIDED_ADDRESS_OF - match ea.PApplyOption((function ProvidedAddressOfExpr x -> Some x | _ -> None), m) with - | Some e -> - let eT = exprToExpr e + | ProvidedAddressOfExpr e -> + let eT = exprToExpr (exprType.PApply((fun _ -> e), m)) let wrap,ce, _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates eT None m let ce = wrap ce None, (ce, tyOfExpr g ce) - | None -> #endif - match ea.PApplyOption((function ProvidedDefaultExpr x -> Some x | _ -> None), m) with - | Some pty -> - let ty = Import.ImportProvidedType amap m pty + | ProvidedDefaultExpr pty -> + let ty = Import.ImportProvidedType amap m (exprType.PApply((fun _ -> pty), m)) let ce = mkDefault (m, ty) None, (ce, tyOfExpr g ce) - | None -> - match ea.PApplyOption((function ProvidedCallExpr c -> Some c | _ -> None), m) with - | Some info -> - methodCallToExpr top ea info - | None -> - match ea.PApplyOption((function ProvidedSequentialExpr c -> Some c | _ -> None), m) with - | Some info -> - let e1, e2 = info.PApply2(id, m) + | ProvidedCallExpr (e1, e2, e3) -> + methodCallToExpr top ea (exprType.PApply((fun _ -> (e1, e2, e3)), m)) + | ProvidedSequentialExpr (e1, e2) -> + let e1, e2 = exprType.PApply2((fun _ -> (e1, e2)), m) let e1T = exprToExpr e1 let e2T = exprToExpr e2 let ce = mkCompGenSequential m e1T e2T None, (ce, tyOfExpr g ce) - | None -> - match ea.PApplyOption((function ProvidedTryFinallyExpr c -> Some c | _ -> None), m) with - | Some info -> - let e1, e2 = info.PApply2(id, m) + | ProvidedTryFinallyExpr (e1, e2) -> + let e1, e2 = exprType.PApply2((fun _ -> (e1, e2)), m) let e1T = exprToExpr e1 let e2T = exprToExpr e2 - let ce = mkTryFinally g (e1T, e2T, m, tyOfExpr g e1T, SequencePointInfoForTry.NoSequencePointAtTry, SequencePointInfoForFinally.NoSequencePointAtFinally) + let ce = mkTryFinally g (e1T, e2T, m, tyOfExpr g e1T, DebugPointAtTry.No, DebugPointAtFinally.No) None, (ce, tyOfExpr g ce) - | None -> - match ea.PApplyOption((function ProvidedTryWithExpr c -> Some c | _ -> None), m) with - | Some info -> + | ProvidedTryWithExpr (e1, e2, e3, e4, e5) -> + let info = exprType.PApply((fun _ -> (e1, e2, e3, e4, e5)), m) let bT = exprToExpr (info.PApply((fun (x, _, _, _, _) -> x), m)) let v1 = info.PApply((fun (_, x, _, _, _) -> x), m) let v1T = addVar v1 @@ -1475,18 +1909,14 @@ module ProvidedMethodCalls = let v2T = addVar v2 let e2T = exprToExpr (info.PApply((fun (_, _, _, _, x) -> x), m)) removeVar v2 - let ce = mkTryWith g (bT, v1T, e1T, v2T, e2T, m, tyOfExpr g bT, SequencePointInfoForTry.NoSequencePointAtTry, SequencePointInfoForWith.NoSequencePointAtWith) + let ce = mkTryWith g (bT, v1T, e1T, v2T, e2T, m, tyOfExpr g bT, DebugPointAtTry.No, DebugPointAtWith.No) None, (ce, tyOfExpr g ce) - | None -> - match ea.PApplyOption((function ProvidedNewObjectExpr c -> Some c | _ -> None), m) with - | Some info -> - None, ctorCallToExpr info - | None -> - fail() + | ProvidedNewObjectExpr (e1, e2) -> + None, ctorCallToExpr (exprType.PApply((fun _ -> (e1, e2)), m)) and ctorCallToExpr (ne: Tainted<_>) = - let (ctor, args) = ne.PApply2(id, m) + let ctor, args = ne.PApply2(id, m) let targetMethInfo = ProvidedMeth(amap, ctor.PApply((fun ne -> upcast ne), m), None, m) let objArgs = [] let arguments = [ for ea in args.PApplyArray(id, "GetInvokerExpression", m) -> exprToExpr ea ] @@ -1507,7 +1937,7 @@ module ProvidedMethodCalls = varConv.Remove vRaw |> ignore and methodCallToExpr top _origExpr (mce: Tainted<_>) = - let (objOpt, meth, args) = mce.PApply3(id, m) + let objOpt, meth, args = mce.PApply3(id, m) let targetMethInfo = ProvidedMeth(amap, meth.PApply((fun mce -> upcast mce), m), None, m) let objArgs = match objOpt.PApplyOption(id, m) with @@ -1535,8 +1965,8 @@ module ProvidedMethodCalls = match varConv.TryGetValue vRaw with | true, v -> v | _ -> - let typeProviderDesignation = ExtensionTyping.DisplayNameOfTypeProvider (pe.TypeProvider, m) - error(NumberedError(FSComp.SR.etIncorrectParameterExpression(typeProviderDesignation, vRaw.Name), m)) + let typeProviderDesignation = DisplayNameOfTypeProvider (pe.TypeProvider, m) + error(Error(FSComp.SR.etIncorrectParameterExpression(typeProviderDesignation, vRaw.Name), m)) and exprToExpr expr = let _, (resExpr, _) = exprToExprAndWitness false expr @@ -1557,7 +1987,7 @@ module ProvidedMethodCalls = |> Array.map (fun pty -> eraseSystemType (amap, m, pty)) let paramVars = erasedParamTys - |> Array.mapi (fun i erasedParamTy -> erasedParamTy.PApply((fun ty -> ProvidedVar.Fresh("arg" + i.ToString(), ty)), m)) + |> Array.mapi (fun i erasedParamTy -> erasedParamTy.PApply((fun ty -> ty.AsProvidedVar("arg" + i.ToString())), m)) // encode "this" as the first ParameterExpression, if applicable @@ -1565,12 +1995,12 @@ module ProvidedMethodCalls = match objArgs with | [objArg] -> let erasedThisTy = eraseSystemType (amap, m, mi.PApply((fun mi -> mi.DeclaringType), m)) - let thisVar = erasedThisTy.PApply((fun ty -> ProvidedVar.Fresh("this", ty)), m) + let thisVar = erasedThisTy.PApply((fun ty -> ty.AsProvidedVar("this")), m) Some objArg, Array.append [| thisVar |] paramVars | [] -> None, paramVars | _ -> failwith "multiple objArgs?" - let ea = mi.PApplyWithProvider((fun (methodInfo, provider) -> ExtensionTyping.GetInvokerExpression(provider, methodInfo, [| for p in paramVars -> p.PUntaintNoFailure id |])), m) + let ea = mi.PApplyWithProvider((fun (methodInfo, provider) -> GetInvokerExpression(provider, methodInfo, [| for p in paramVars -> p.PUntaintNoFailure id |])), m) convertProvidedExpressionToExprAndWitness tcVal (thisArg, allArgs, paramVars, g, amap, mut, isProp, isSuperInit, m, ea) @@ -1589,55 +2019,176 @@ module ProvidedMethodCalls = raise( tpe.WithContext(typeName, methName) ) // loses original stack trace #endif - - let RecdFieldInstanceChecks g amap ad m (rfinfo: RecdFieldInfo) = if rfinfo.IsStatic then error (Error (FSComp.SR.tcStaticFieldUsedWhenInstanceFieldExpected(), m)) CheckRecdFieldInfoAttributes g rfinfo m |> CommitOperationResult CheckRecdFieldInfoAccessible amap m ad rfinfo -let ILFieldInstanceChecks g amap ad m (finfo : ILFieldInfo) = - if finfo.IsStatic then error (Error (FSComp.SR.tcStaticFieldUsedWhenInstanceFieldExpected(), m)) - CheckILFieldInfoAccessible g amap m ad finfo - CheckILFieldAttributes g finfo m - -let MethInfoChecks g amap isInstance tyargsOpt objArgs ad m (minfo: MethInfo) = - if minfo.IsInstance <> isInstance then - if isInstance then - error (Error (FSComp.SR.csMethodIsNotAnInstanceMethod(minfo.LogicalName), m)) - else - error (Error (FSComp.SR.csMethodIsNotAStaticMethod(minfo.LogicalName), m)) - - // keep the original accessibility domain to determine type accessibility - let adOriginal = ad - // Eliminate the 'protected' portion of the accessibility domain for instance accesses - let ad = - match objArgs, ad with - | [objArg], AccessibleFrom(paths, Some tcref) -> - let objArgTy = tyOfExpr g objArg - let ty = generalizedTyconRef tcref - // We get to keep our rights if the type we're in subsumes the object argument type - if TypeFeasiblySubsumesType 0 g amap m ty CanCoerce objArgTy then - ad - // We get to keep our rights if this is a base call - elif IsBaseCall objArgs then - ad - else - AccessibleFrom(paths, None) - | _ -> ad - - if not (IsTypeAndMethInfoAccessible amap m adOriginal ad minfo) then - error (Error (FSComp.SR.tcMethodNotAccessible(minfo.LogicalName), m)) - - if isAnyTupleTy g minfo.ApparentEnclosingType && not minfo.IsExtensionMember && - (minfo.LogicalName.StartsWithOrdinal("get_Item") || minfo.LogicalName.StartsWithOrdinal("get_Rest")) then - warning (Error (FSComp.SR.tcTupleMemberNotNormallyUsed(), m)) - - CheckMethInfoAttributes g m tyargsOpt minfo |> CommitOperationResult - -exception FieldNotMutable of DisplayEnv * Tast.RecdFieldRef * range +exception FieldNotMutable of DisplayEnv * RecdFieldRef * range let CheckRecdFieldMutation m denv (rfinfo: RecdFieldInfo) = if not rfinfo.RecdField.IsMutable then errorR (FieldNotMutable (denv, rfinfo.RecdFieldRef, m)) +/// Generate a witness for the given (solved) constraint. Five possiblilities are taken +/// into account. +/// 1. The constraint is solved by a .NET-declared method or an F#-declared method +/// 2. The constraint is solved by an F# record field +/// 3. The constraint is solved by an F# anonymous record field +/// 4. The constraint is considered solved by a "built in" solution +/// 5. The constraint is solved by a closed expression given by a provided method from a type provider +/// +/// In each case an expression is returned where the method is applied to the given arguments, or the +/// field is dereferenced. +/// +/// None is returned in the cases where the trait has not been solved (e.g. is part of generic code) +/// or there is an unexpected mismatch of some kind. +let GenWitnessExpr amap g m (traitInfo: TraitConstraintInfo) argExprs = + + let sln = + match traitInfo.Solution with + | None -> Choice5Of5() + | Some sln -> + + // Given the solution information, reconstruct the MethInfo for the solution + match sln with + | ILMethSln(origTy, extOpt, mref, minst) -> + let metadataTy = convertToTypeWithMetadataIfPossible g origTy + let tcref = tcrefOfAppTy g metadataTy + let mdef = resolveILMethodRef tcref.ILTyconRawMetadata mref + let ilMethInfo = + match extOpt with + | None -> MethInfo.CreateILMeth(amap, m, origTy, mdef) + | Some ilActualTypeRef -> + let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef + MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef) + Choice1Of5 (ilMethInfo, minst) + + | FSMethSln(ty, vref, minst) -> + Choice1Of5 (FSMeth(g, ty, vref, None), minst) + + | FSRecdFieldSln(tinst, rfref, isSetProp) -> + Choice2Of5 (tinst, rfref, isSetProp) + + | FSAnonRecdFieldSln(anonInfo, tinst, i) -> + Choice3Of5 (anonInfo, tinst, i) + + | ClosedExprSln expr -> + Choice4Of5 expr + + | BuiltInSln -> + Choice5Of5 () + + match sln with + | Choice1Of5(minfo, methArgTys) -> + let argExprs = + // FIX for #421894 - typechecker assumes that coercion can be applied for the trait + // calls arguments but codegen doesn't emit coercion operations + // result - generation of non-verifiable code + // fix - apply coercion for the arguments (excluding 'receiver' argument in instance calls) + + // flatten list of argument types (looks like trait calls with curried arguments are not supported so + // we can just convert argument list in straight-forward way) + let argTypes = + minfo.GetParamTypes(amap, m, methArgTys) + |> List.concat + + // do not apply coercion to the 'receiver' argument + let receiverArgOpt, argExprs = + if minfo.IsInstance then + match argExprs with + | h :: t -> Some h, t + | argExprs -> None, argExprs + else None, argExprs + + // For methods taking no arguments, 'argExprs' will be a single unit expression here + let argExprs = + match argTypes, argExprs with + | [], [_] -> [] + | _ -> argExprs + + let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr) + match receiverArgOpt with + | Some r -> r :: convertedArgs + | None -> convertedArgs + + // Fix bug 1281: If we resolve to an instance method on a struct and we haven't yet taken + // the address of the object then go do that + if minfo.IsStruct && minfo.IsInstance then + match argExprs with + | h :: t when not (isByrefTy g (tyOfExpr g h)) -> + let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false PossiblyMutates h None m + Some (wrap (Expr.Op (TOp.TraitCall traitInfo, [], (h' :: t), m))) + | _ -> + Some (MakeMethInfoCall amap m minfo methArgTys argExprs) + else + Some (MakeMethInfoCall amap m minfo methArgTys argExprs) + + | Choice2Of5 (tinst, rfref, isSet) -> + match isSet, rfref.RecdField.IsStatic, argExprs.Length with + // static setter + | true, true, 1 -> + Some (mkStaticRecdFieldSet (rfref, tinst, argExprs.[0], m)) + + // instance setter + | true, false, 2 -> + // If we resolve to an instance field on a struct and we haven't yet taken + // the address of the object then go do that + if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then + let h = List.head argExprs + let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m + Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m))) + else + Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m)) + + // static getter + | false, true, 0 -> + Some (mkStaticRecdFieldGet (rfref, tinst, m)) + + // instance getter + | false, false, 1 -> + if rfref.Tycon.IsStructOrEnumTycon && isByrefTy g (tyOfExpr g argExprs.[0]) then + Some (mkRecdFieldGetViaExprAddr (argExprs.[0], rfref, tinst, m)) + else + Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m)) + + | _ -> None + + | Choice3Of5 (anonInfo, tinst, i) -> + let tupInfo = anonInfo.TupInfo + if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then + Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m)) + else + Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m)) + + | Choice4Of5 expr -> + Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m)) + + | Choice5Of5 () -> + match traitInfo.Solution with + | None -> None // the trait has been generalized + | Some _-> + // For these operators, the witness is just a call to the coresponding FSharp.Core operator + match g.TryMakeOperatorAsBuiltInWitnessInfo isStringTy isArrayTy traitInfo argExprs with + | Some (info, tyargs, actualArgExprs) -> + tryMkCallCoreFunctionAsBuiltInWitness g info tyargs actualArgExprs m + | None -> + // For all other built-in operators, the witness is a call to the coresponding BuiltInWitnesses operator + // These are called as F# methods not F# functions + tryMkCallBuiltInWitness g traitInfo argExprs m + +/// Generate a lambda expression for the given solved trait. +let GenWitnessExprLambda amap g m (traitInfo: TraitConstraintInfo) = + let witnessInfo = traitInfo.TraitKey + let argtysl = GenWitnessArgTys g witnessInfo + let vse = argtysl |> List.mapiSquared (fun i j ty -> mkCompGenLocal m ("arg" + string i + "_" + string j) ty) + let vsl = List.mapSquared fst vse + match GenWitnessExpr amap g m traitInfo (List.concat (List.mapSquared snd vse)) with + | Some expr -> + Choice2Of2 (mkMemberLambdas m [] None None vsl (expr, tyOfExpr g expr)) + | None -> + Choice1Of2 traitInfo + +/// Generate the arguments passed for a set of (solved) traits in non-generic code +let GenWitnessArgs amap g m (traitInfos: TraitConstraintInfo list) = + [ for traitInfo in traitInfos -> GenWitnessExprLambda amap g m traitInfo ] diff --git a/src/fsharp/MethodCalls.fsi b/src/fsharp/MethodCalls.fsi new file mode 100644 index 00000000000..3a98ae34513 --- /dev/null +++ b/src/fsharp/MethodCalls.fsi @@ -0,0 +1,428 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Logic associated with resolving method calls. +module internal FSharp.Compiler.MethodCalls + +open FSharp.Compiler +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Import +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Infos +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +/// In the following, 'T gets instantiated to: +/// 1. the expression being supplied for an argument +/// 2. "unit", when simply checking for the existence of an overload that satisfies +/// a signature, or when finding the corresponding witness. +/// Note the parametricity helps ensure that overload resolution doesn't depend on the +/// expression on the callside (though it is in some circumstances allowed +/// to depend on some type information inferred syntactically from that +/// expression, e.g. a lambda expression may be converted to a delegate as +/// an adhoc conversion. +/// +/// The bool indicates if named using a '?', making the caller argument explicit-optional +type CallerArg<'T> = + | CallerArg of ty: TType * range: range * isOpt: bool * exprInfo: 'T + + member CallerArgumentType: TType + + member Expr: 'T + + member IsExplicitOptional: bool + + member Range: range + +type CalledArg = + { Position: struct (int * int) + IsParamArray: bool + OptArgInfo: OptionalArgInfo + CallerInfo: CallerInfo + IsInArg: bool + IsOutArg: bool + ReflArgInfo: ReflectedArgInfo + NameOpt: Ident option + CalledArgumentType: TType } + +val CalledArg: pos:struct (int * int) * isParamArray:bool * optArgInfo:OptionalArgInfo * callerInfo:CallerInfo * isInArg:bool * isOutArg:bool * nameOpt:Ident option * reflArgInfo:ReflectedArgInfo * calledArgTy:TType -> CalledArg + +/// Represents a match between a caller argument and a called argument, arising from either +/// a named argument or an unnamed argument. +type AssignedCalledArg<'T> = + { /// The identifier for a named argument, if any + NamedArgIdOpt : Ident option + + /// The called argument in the method + CalledArg: CalledArg + + /// The argument on the caller side + CallerArg: CallerArg<'T> } + member Position: struct (int * int) + +/// Represents the possibilities for a named-setter argument (a property, field, or a record field setter) +type AssignedItemSetterTarget = + | AssignedPropSetter of PropInfo * MethInfo * TypeInst + | AssignedILFieldSetter of ILFieldInfo + | AssignedRecdFieldSetter of RecdFieldInfo + +/// Represents the resolution of a caller argument as a named-setter argument +type AssignedItemSetter<'T> = + | AssignedItemSetter of + Ident * AssignedItemSetterTarget * CallerArg<'T> + +type CallerNamedArg<'T> = + | CallerNamedArg of Ident * CallerArg<'T> + + member CallerArg: CallerArg<'T> + + member Ident: Ident + + member Name: string + +/// Represents the list of unnamed / named arguments at method call site +/// remark: The usage of list list is due to tupling and currying of arguments, +/// stemming from SynValInfo in the AST. +[] +type CallerArgs<'T> = + { Unnamed: CallerArg<'T> list list + Named: CallerNamedArg<'T> list list } + + member ArgumentNamesAndTypes: (string option * TType) list + + member CallerArgCounts: int * int + + member CurriedCallerArgs: (CallerArg<'T> list * CallerNamedArg<'T> list) list + + static member Empty: CallerArgs<'T> + +/// Indicates whether a type directed conversion (e.g. int32 to int64, or op_Implicit) +/// has been used in F# code +[] +type TypeDirectedConversionUsed = + | Yes of (DisplayEnv -> exn) + | No + static member Combine: TypeDirectedConversionUsed -> TypeDirectedConversionUsed -> TypeDirectedConversionUsed + +/// Performs a set of constraint solver operations returning TypeDirectedConversionUsed and +/// combines their results. +val MapCombineTDCD: mapper:('a -> OperationResult) -> xs:'a list -> OperationResult + +/// Performs a set of constraint solver operations returning TypeDirectedConversionUsed and +/// combines their results. +val MapCombineTDC2D: mapper:('a -> 'b -> OperationResult) -> xs:'a list -> ys:'b list -> OperationResult + +/// F# supports some adhoc conversions to make expression fit known overall type +val AdjustRequiredTypeForTypeDirectedConversions: + infoReader:InfoReader -> + ad: AccessorDomain -> + isMethodArg: bool -> + isConstraint: bool -> + reqdTy: TType -> + actualTy:TType -> + m: range + -> TType * TypeDirectedConversionUsed * (TType * TType * (DisplayEnv -> unit)) option + +/// F# supports some adhoc conversions to make expression fit known overall type +val AdjustCalledArgType: + infoReader:InfoReader -> + ad: AccessorDomain -> + isConstraint:bool -> + enforceNullableOptionalsKnownTypes:bool -> + calledArg:CalledArg -> + callerArg:CallerArg<'a> + -> TType * TypeDirectedConversionUsed * (TType * TType * (DisplayEnv -> unit)) option + +type CalledMethArgSet<'T> = + { /// The called arguments corresponding to "unnamed" arguments + UnnamedCalledArgs : CalledArg list + + /// Any unnamed caller arguments not otherwise assigned + UnnamedCallerArgs : CallerArg<'T> list + + /// The called "ParamArray" argument, if any + ParamArrayCalledArgOpt : CalledArg option + + /// Any unnamed caller arguments assigned to a "param array" argument + ParamArrayCallerArgs : CallerArg<'T> list + + /// Named args + AssignedNamedArgs: AssignedCalledArg<'T> list } + + member NumAssignedNamedArgs: int + + member NumUnnamedCalledArgs: int + + member NumUnnamedCallerArgs: int + +/// Represents the syntactic matching between a caller of a method and the called method. +/// +/// The constructor takes all the information about the caller and called side of a method, match up named arguments, property setters etc., +/// and returns a CalledMeth object for further analysis. +type CalledMeth<'T> = + + new: infoReader:InfoReader * + nameEnv:NameResolutionEnv option * + isCheckingAttributeCall:bool * + freshenMethInfo:(range -> MethInfo -> TypeInst) * + m:range * + ad:AccessorDomain * + minfo:MethInfo * + calledTyArgs:TType list * + callerTyArgs:TType list * + pinfoOpt:PropInfo option * + callerObjArgTys:TType list * + callerArgs:CallerArgs<'T> * + allowParamArgs:bool * + allowOutAndOptArgs:bool * + tyargsOpt:TType option -> CalledMeth<'T> + + static member GetMethod: x:CalledMeth<'T> -> MethInfo + + member CalledObjArgTys: m:range -> TType list + + member GetParamArrayElementType: unit -> TType + + member HasCorrectObjArgs: m:range -> bool + + member IsAccessible: m:range * ad:AccessorDomain -> bool + + member IsCandidate: m:range * ad:AccessorDomain -> bool + + member AllCalledArgs: CalledArg list list + + member AllUnnamedCalledArgs: CalledArg list + + /// The argument analysis for each set of curried arguments + member ArgSets: CalledMethArgSet<'T> list + + /// Named setters + member AssignedItemSetters: AssignedItemSetter<'T> list + + member AssignedNamedArgs: AssignedCalledArg<'T> list list + + member AssignedUnnamedArgs: AssignedCalledArg<'T> list list + + member AssignsAllNamedArgs: bool + + /// The property related to the method we're attempting to call, if any + member AssociatedPropertyInfo: PropInfo option + + /// Args assigned to specify values for attribute fields and properties (these are not necessarily "property sets") + member AttributeAssignedNamedArgs: CallerNamedArg<'T> list + + /// The return type after implicit deference of byref returns is taken into account + member CalledReturnTypeAfterByrefDeref: TType + + /// Return type after tupling of out args is taken into account + member CalledReturnTypeAfterOutArgTupling: TType + + /// The instantiation of the method we're attempting to call + member CalledTyArgs: TType list + + /// The instantiation of the method we're attempting to call + member CalledTyparInst: TypedTreeOps.TyparInst + + /// The types of the actual object arguments, if any + member CallerObjArgTys: TType list + + /// The formal instantiation of the method we're attempting to call + member CallerTyArgs: TType list + + member HasCorrectArity: bool + + member HasCorrectGenericArity: bool + + member HasOptArgs: bool + + member HasOutArgs: bool + + member IsIndexParamArraySetter: bool + + /// The method we're attempting to call + member Method: MethInfo + + member NumArgSets: int + + member NumAssignedProps: int + + member NumCalledTyArgs: int + + member NumCallerTyArgs: int + + member ParamArrayCalledArgOpt: CalledArg option + + member ParamArrayCallerArgs: CallerArg<'T> list option + + member TotalNumAssignedNamedArgs: int + + member TotalNumUnnamedCalledArgs: int + + member TotalNumUnnamedCallerArgs: int + + /// Unassigned args + member UnassignedNamedArgs: CallerNamedArg<'T> list + + /// Unnamed called optional args: pass defaults for these + member UnnamedCalledOptArgs: CalledArg list + + /// Unnamed called out args: return these as part of the return tuple + member UnnamedCalledOutArgs: CalledArg list + + member UsesParamArrayConversion: bool + + member amap: ImportMap + + member infoReader: InfoReader + +val NamesOfCalledArgs: calledArgs:CalledArg list -> Ident list + +type ArgumentAnalysis = + | NoInfo + | ArgDoesNotMatch + | CallerLambdaHasArgTypes of TType list + | CalledArgMatchesType of TType + +val ExamineMethodForLambdaPropagation: x:CalledMeth -> ad:AccessorDomain -> (ArgumentAnalysis list list * (Ident * ArgumentAnalysis) list list) option + +/// Is this a 'base' call +val IsBaseCall: objArgs:Expr list -> bool + +val BuildILMethInfoCall: g:TcGlobals -> amap:ImportMap -> m:range -> isProp:bool -> minfo:ILMethInfo -> valUseFlags:ValUseFlag -> minst:TType list -> direct:bool -> args:Exprs -> Expr * TType + +/// Make a call to a method info. Used by the optimizer and code generator to build +/// calls to the type-directed solutions to member constraints. +val MakeMethInfoCall: amap:ImportMap -> m:range -> minfo:MethInfo -> minst:TType list -> args:Exprs -> Expr + +/// Build an expression that calls a given method info. +/// This is called after overload resolution, and also to call other +/// methods such as 'setters' for properties. +// tcVal: used to convert an F# value into an expression. See tc.fs. +// isProp: is it a property get? +// minst: the instantiation to apply for a generic method +// objArgs: the 'this' argument, if any +// args: the arguments, if any +val BuildMethodCall: + tcVal:(ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) -> + g:TcGlobals -> + amap:ImportMap -> + isMutable:TypedTreeOps.Mutates -> + m:range -> + isProp:bool -> + minfo:MethInfo -> + valUseFlags:ValUseFlag -> + minst:TType list -> + objArgs:Expr list -> + args:Expr list + -> Expr * TType + +/// Build a call to the System.Object constructor taking no arguments, +val BuildObjCtorCall: g:TcGlobals -> m:range -> Expr + +/// Implements the elaborated form of adhoc conversions from functions to delegates at member callsites +val BuildNewDelegateExpr: eventInfoOpt:EventInfo option * g:TcGlobals * amap:ImportMap * delegateTy:TType * invokeMethInfo:MethInfo * delArgTys:TType list * f:Expr * fty:TType * m:range -> Expr + +val CoerceFromFSharpFuncToDelegate: g:TcGlobals -> amap:ImportMap -> infoReader:InfoReader -> ad:AccessorDomain -> callerArgTy:TType -> m:range -> callerArgExpr:Expr -> delegateTy:TType -> Expr + +val AdjustExprForTypeDirectedConversions: + tcVal:(ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) -> + g: TcGlobals -> + amap:ImportMap -> + infoReader:InfoReader -> + ad:AccessorDomain -> + reqdTy:TType -> + actualTy:TType -> + m:range -> + expr:Expr + -> Expr + +val AdjustCallerArgExpr: + tcVal:(ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) -> + g:TcGlobals -> + amap:ImportMap -> + infoReader:InfoReader -> + ad:AccessorDomain -> + isOutArg:bool -> + calledArgTy:TType -> + reflArgInfo:ReflectedArgInfo -> + callerArgTy:TType -> + m:range -> + callerArgExpr:Expr -> + 'a option * Expr + +/// Build the argument list for a method call. Adjust for param array, optional arguments, byref arguments and coercions. +/// For example, if you pass an F# reference cell to a byref then we must get the address of the +/// contents of the ref. Likewise lots of adjustments are made for optional arguments etc. +val AdjustCallerArgs: + tcVal:(ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) -> + tcFieldInit:(range -> AbstractIL.IL.ILFieldInit -> Const) -> + eCallerMemberName:string option -> + infoReader:InfoReader -> + ad:AccessorDomain -> + calledMeth:CalledMeth -> + objArgs:Expr list -> + lambdaVars:'a option -> + mItem:range -> + mMethExpr:range -> + (Expr -> Expr) * Expr list * + 'b option list * AssignedCalledArg list * + Expr list * (Expr -> Expr) * + 'c option list * Expr list * + Binding list + +val RecdFieldInstanceChecks: g:TcGlobals -> amap:ImportMap -> ad:AccessorDomain -> m:range -> rfinfo:RecdFieldInfo -> unit + +val ILFieldStaticChecks: g:TcGlobals -> amap:ImportMap -> infoReader:InfoReader -> ad:AccessorDomain -> m:range -> finfo:ILFieldInfo -> unit + +val ILFieldInstanceChecks: g:TcGlobals -> amap:ImportMap -> ad:AccessorDomain -> m:range -> finfo:ILFieldInfo -> unit + +val MethInfoChecks: g:TcGlobals -> amap:ImportMap -> isInstance:bool -> tyargsOpt:'a option -> objArgs:Expr list -> ad:AccessorDomain -> m:range -> minfo:MethInfo -> unit + +exception FieldNotMutable of TypedTreeOps.DisplayEnv * RecdFieldRef * range + +val CheckRecdFieldMutation: m:range -> denv:TypedTreeOps.DisplayEnv -> rfinfo:RecdFieldInfo -> unit + +/// Generate a witness for the given (solved) constraint. Five possiblilities are taken +/// into account. +/// 1. The constraint is solved by a .NET-declared method or an F#-declared method +/// 2. The constraint is solved by an F# record field +/// 3. The constraint is solved by an F# anonymous record field +/// 4. The constraint is considered solved by a "built in" solution +/// 5. The constraint is solved by a closed expression given by a provided method from a type provider +/// +/// In each case an expression is returned where the method is applied to the given arguments, or the +/// field is dereferenced. +/// +/// None is returned in the cases where the trait has not been solved (e.g. is part of generic code) +/// or there is an unexpected mismatch of some kind. +val GenWitnessExpr: amap:ImportMap -> g:TcGlobals -> m:range -> traitInfo:TraitConstraintInfo -> argExprs:Expr list -> Expr option + +/// Generate a lambda expression for the given solved trait. +val GenWitnessExprLambda: amap:ImportMap -> g:TcGlobals -> m:range -> traitInfo:TraitConstraintInfo -> Choice + +/// Generate the arguments passed for a set of (solved) traits in non-generic code +val GenWitnessArgs: amap:ImportMap -> g:TcGlobals -> m:range -> traitInfos:TraitConstraintInfo list -> Choice list + +#if !NO_EXTENSIONTYPING +module ProvidedMethodCalls = + val BuildInvokerExpressionForProvidedMethodCall: + tcVal:(ValRef -> ValUseFlag -> TType list -> range -> Expr * TType) -> + g:TcGlobals * + amap:ImportMap * + mi:Tainted * + objArgs:Expr list * + mut:TypedTreeOps.Mutates * + isProp:bool * + isSuperInit:ValUseFlag * + allArgs:Exprs * + m:range -> + Tainted option * Expr * TType +#endif diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs index c621706b9b8..9acba857687 100644 --- a/src/fsharp/MethodOverrides.fs +++ b/src/fsharp/MethodOverrides.fs @@ -3,19 +3,23 @@ /// Primary logic related to method overrides. module internal FSharp.Compiler.MethodOverrides +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Ast +open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Lib +open FSharp.Compiler.InfoReader open FSharp.Compiler.Infos -open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Features open FSharp.Compiler.NameResolution -open FSharp.Compiler.Range -open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeRelations //------------------------------------------------------------------------- @@ -40,10 +44,34 @@ type OverrideInfo = member x.ReturnType = let (Override(_, _, _, _, _, b, _, _)) = x in b member x.IsCompilerGenerated = let (Override(_, _, _, _, _, _, _, b)) = x in b -// If the bool is true then the slot is optional, i.e. is an interface slot -// which does not _have_ to be implemented, because an inherited implementation -// is available. -type RequiredSlot = RequiredSlot of MethInfo * (* isOptional: *) bool +type RequiredSlot = + | RequiredSlot of MethInfo * isOptional: bool + | DefaultInterfaceImplementationSlot of MethInfo * isOptional: bool * possiblyNoMostSpecific: bool + + /// A slot which does not have to be implemented, because an inherited implementation is available. + member this.IsOptional = + match this with + | RequiredSlot(_, isOptional) + | DefaultInterfaceImplementationSlot(_, isOptional, _) -> isOptional + + /// A slot which has a default interface implementation. + /// A combination of this flag and the lack of IsOptional means the slot may have been reabstracted. + member this.HasDefaultInterfaceImplementation = + match this with + | DefaultInterfaceImplementationSlot _ -> true + | _ -> false + + /// A slot that *might* have ambiguity due to multiple inheritance; happens with default interface implementations. + member this.PossiblyNoMostSpecificImplementation = + match this with + | DefaultInterfaceImplementationSlot(_, _, possiblyNoMostSpecific) -> possiblyNoMostSpecific + | _ -> false + + /// Gets the method info. + member this.MethodInfo = + match this with + | RequiredSlot(methInfo, _) + | DefaultInterfaceImplementationSlot(methInfo, _, _) -> methInfo type SlotImplSet = SlotImplSet of RequiredSlot list * NameMultiMap * OverrideInfo list * PropInfo list @@ -60,7 +88,7 @@ module DispatchSlotChecking = match argTys with | [] -> [[(denv.g.unit_ty, ValReprInfo.unnamedTopArg1)]] | _ -> argTys |> List.mapSquared (fun ty -> (ty, ValReprInfo.unnamedTopArg1)) - Layout.bufferL os (NicePrint.prettyLayoutOfMemberSig denv (memberToParentInst, id.idText, mtps, argInfos, retTy)) + LayoutRender.bufferL os (NicePrint.prettyLayoutOfMemberSig denv (memberToParentInst, id.idText, mtps, argInfos, retTy)) /// Print the signature of a MethInfo to a buffer as part of an error message let PrintMethInfoSigToBuffer g amap m denv os minfo = @@ -69,7 +97,7 @@ module DispatchSlotChecking = let retTy = (retTy |> GetFSharpViewOfReturnType g) let argInfos = argTys |> List.mapSquared (fun ty -> (ty, ValReprInfo.unnamedTopArg1)) let nm = minfo.LogicalName - Layout.bufferL os (NicePrint.prettyLayoutOfMemberSig denv (ttpinst, nm, fmtps, argInfos, retTy)) + LayoutRender.bufferL os (NicePrint.prettyLayoutOfMemberSig denv (ttpinst, nm, fmtps, argInfos, retTy)) /// Format the signature of an override as a string as part of an error message let FormatOverride denv d = bufs (fun buf -> PrintOverrideToBuffer denv buf d) @@ -87,7 +115,7 @@ module DispatchSlotChecking = /// Get the override info for a value being used to implement a dispatch slot. let GetTypeMemberOverrideInfo g reqdTy (overrideBy: ValRef) = - let _, argInfos, retTy, _ = GetTypeOfMemberInMemberForm g overrideBy + let _, _, argInfos, retTy, _ = GetTypeOfMemberInMemberForm g overrideBy let nm = overrideBy.LogicalName let argTys = argInfos |> List.mapSquared fst @@ -125,8 +153,8 @@ module DispatchSlotChecking = /// Get the override information for an object expression method being used to implement dispatch slots let GetObjectExprOverrideInfo g amap (implty, id: Ident, memberFlags, ty, arityInfo, bindingAttribs, rhsExpr) = - // Dissect the type - let tps, argInfos, retTy, _ = GetMemberTypeInMemberForm g memberFlags arityInfo ty id.idRange + // Dissect the type. The '0' indicates there are no enclosing generic class type parameters relevant here. + let tps, _, argInfos, retTy, _ = GetMemberTypeInMemberForm g memberFlags arityInfo 0 ty id.idRange let argTys = argInfos |> List.mapSquared fst // Dissect the implementation let _, ctorThisValOpt, baseValOpt, vsl, rhsExpr, _ = destTopLambda g amap arityInfo (rhsExpr, ty) @@ -167,14 +195,18 @@ module DispatchSlotChecking = let IsTyparKindMatch (CompiledSig(_, _, fvmtps, _)) (Override(_, _, _, (mtps, _), _, _, _, _)) = List.lengthsEqAndForall2 (fun (tp1: Typar) (tp2: Typar) -> tp1.Kind = tp2.Kind) mtps fvmtps - /// Check if an override is a partial match for the requirements for a dispatch slot - let IsPartialMatch g (dispatchSlot: MethInfo) compiledSig (Override(_, _, _, (mtps, _), argTys, _retTy, _, _) as overrideBy) = - IsNameMatch dispatchSlot overrideBy && + /// Check if an override is a partial match for the requirements for a dispatch slot except for the name. + let IsSigPartialMatch g (dispatchSlot: MethInfo) compiledSig (Override(_, _, _, (mtps, _), argTys, _retTy, _, _) as overrideBy) = let (CompiledSig (vargtys, _, fvmtps, _)) = compiledSig mtps.Length = fvmtps.Length && IsTyparKindMatch compiledSig overrideBy && argTys.Length = vargtys.Length && - IsImplMatch g dispatchSlot overrideBy + IsImplMatch g dispatchSlot overrideBy + + /// Check if an override is a partial match for the requirements for a dispatch slot. + let IsPartialMatch g dispatchSlot compiledSig overrideBy = + IsNameMatch dispatchSlot overrideBy && + IsSigPartialMatch g dispatchSlot compiledSig overrideBy /// Compute the reverse of a type parameter renaming. let ReverseTyparRenaming g tinst = @@ -184,10 +216,10 @@ module DispatchSlotChecking = let ComposeTyparInsts inst1 inst2 = inst1 |> List.map (map2Of2 (instType inst2)) - /// Check if an override exactly matches the requirements for a dispatch slot - let IsExactMatch g amap m dispatchSlot (Override(_, _, _, (mtps, mtpinst), argTys, retTy, _, _) as overrideBy) = + /// Check if an override exactly matches the requirements for a dispatch slot except for the name. + let IsSigExactMatch g amap m dispatchSlot (Override(_, _, _, (mtps, mtpinst), argTys, retTy, _, _) as overrideBy) = let compiledSig = CompiledSigOfMeth g amap m dispatchSlot - IsPartialMatch g dispatchSlot compiledSig overrideBy && + IsSigPartialMatch g dispatchSlot compiledSig overrideBy && let (CompiledSig (vargtys, vrty, fvmtps, ttpinst)) = compiledSig // Compare the types. CompiledSigOfMeth, GetObjectExprOverrideInfo and GetTypeMemberOverrideInfo have already @@ -231,6 +263,11 @@ module DispatchSlotChecking = typarsAEquiv g aenv fvmtps mtps + /// Check if an override exactly matches the requirements for a dispatch slot. + let IsExactMatch g amap m dispatchSlot overrideBy = + IsNameMatch dispatchSlot overrideBy && + IsSigExactMatch g amap m dispatchSlot overrideBy + /// Check if an override implements a dispatch slot let OverrideImplementsDispatchSlot g amap m dispatchSlot availPriorOverride = IsExactMatch g amap m dispatchSlot availPriorOverride && @@ -243,15 +280,16 @@ module DispatchSlotChecking = |> NameMultiMap.find dispatchSlot.LogicalName |> List.exists (OverrideImplementsDispatchSlot g amap m dispatchSlot) - /// Check all dispatch slots are implemented by some override. - let CheckDispatchSlotsAreImplemented (denv, g, amap, m, + let CheckDispatchSlotsAreImplemented (denv, infoReader: InfoReader, m, nenv, sink: TcResultsSink, isOverallTyAbstract, reqdTy, dispatchSlots: RequiredSlot list, availPriorOverrides: OverrideInfo list, overrides: OverrideInfo list) = + let g = infoReader.g + let amap = infoReader.amap let isReqdTyInterface = isInterfaceTy g reqdTy let showMissingMethodsAndRaiseErrors = (isReqdTyInterface || not isOverallTyAbstract) @@ -269,7 +307,13 @@ module DispatchSlotChecking = // we accumulate those to compose a more complete error message, see noimpl() bellow. let missingOverloadImplementation = ResizeArray() - for (RequiredSlot(dispatchSlot, isOptional)) in dispatchSlots do + for reqdSlot in dispatchSlots do + let dispatchSlot = reqdSlot.MethodInfo + + // Always try to raise a target runtime error if we have a DIM. + if reqdSlot.HasDefaultInterfaceImplementation then + checkLanguageFeatureRuntimeErrorRecover infoReader LanguageFeature.DefaultInterfaceMemberConsumption m + let maybeResolvedSlot = NameMultiMap.find dispatchSlot.LogicalName overridesKeyed |> List.filter (OverrideImplementsDispatchSlot g amap m dispatchSlot) @@ -278,17 +322,24 @@ module DispatchSlotChecking = | [ovd] -> if not ovd.IsCompilerGenerated then let item = Item.MethodGroup(ovd.LogicalName, [dispatchSlot],None) - CallNameResolutionSink sink (ovd.Range, nenv, item,item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, denv,AccessorDomain.AccessibleFromSomewhere) + CallNameResolutionSink sink (ovd.Range, nenv, item, dispatchSlot.FormalMethodTyparInst, ItemOccurence.Implemented, AccessorDomain.AccessibleFromSomewhere) | [] -> - if not isOptional && + if not reqdSlot.IsOptional && // Check that no available prior override implements this dispatch slot not (DispatchSlotIsAlreadyImplemented g amap m availPriorOverridesKeyed dispatchSlot) then + // Always try to raise a language version error if we have a DIM that is not explicitly implemented. + if reqdSlot.HasDefaultInterfaceImplementation then + checkLanguageFeatureErrorRecover g.langVersion LanguageFeature.DefaultInterfaceMemberConsumption m + + if reqdSlot.PossiblyNoMostSpecificImplementation then + errorR(Error(FSComp.SR.typrelInterfaceMemberNoMostSpecificImplementation(NicePrint.stringOfMethInfo infoReader m denv dispatchSlot), m)) + // error reporting path let compiledSig = CompiledSigOfMeth g amap m dispatchSlot let noimpl() = - missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo amap m denv dispatchSlot)) + missingOverloadImplementation.Add((isReqdTyInterface, lazy NicePrint.stringOfMethInfo infoReader m denv dispatchSlot)) match overrides |> List.filter (IsPartialMatch g dispatchSlot compiledSig) with | [] -> @@ -302,7 +353,7 @@ module DispatchSlotChecking = | [ Override(_, _, _, (mtps, _), argTys, _, _, _) as overrideBy ] -> let moreThanOnePossibleDispatchSlot = dispatchSlots - |> List.filter (fun (RequiredSlot(dispatchSlot, _)) -> IsNameMatch dispatchSlot overrideBy && IsImplMatch g dispatchSlot overrideBy) + |> List.filter (fun reqdSlot-> IsNameMatch reqdSlot.MethodInfo overrideBy && IsImplMatch g reqdSlot.MethodInfo overrideBy) |> isNilOrSingleton |> not @@ -318,12 +369,12 @@ module DispatchSlotChecking = elif not (IsTyparKindMatch compiledSig overrideBy) then fail(Error(FSComp.SR.typrelMemberDoesNotHaveCorrectKindsOfGenericParameters(FormatOverride denv overrideBy, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) else - fail(Error(FSComp.SR.typrelMemberCannotImplement(FormatOverride denv overrideBy, NicePrint.stringOfMethInfo amap m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) + fail(Error(FSComp.SR.typrelMemberCannotImplement(FormatOverride denv overrideBy, NicePrint.stringOfMethInfo infoReader m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) | overrideBy :: _ -> errorR(Error(FSComp.SR.typrelOverloadNotFound(FormatMethInfoSig g amap m denv dispatchSlot, FormatMethInfoSig g amap m denv dispatchSlot), overrideBy.Range)) | [ overrideBy ] -> - if dispatchSlots |> List.exists (fun (RequiredSlot(dispatchSlot, _)) -> OverrideImplementsDispatchSlot g amap m dispatchSlot overrideBy) then + if dispatchSlots |> List.exists (fun reqdSlot -> OverrideImplementsDispatchSlot g amap m reqdSlot.MethodInfo overrideBy) then noimpl() else // Error will be reported below in CheckOverridesAreAllUsedOnce @@ -371,17 +422,133 @@ module DispatchSlotChecking = res + /// This is to find override methods that are at the most specific in the hierarchy of interface types. + let GetMostSpecificOverrideInterfaceMethodSets (infoReader: InfoReader) allReqdTys = + let g = infoReader.g + let amap = infoReader.amap + + let multipleSets = + allReqdTys + // Widdle down to the most specific interfaces. + |> GetMostSpecificItemsByType g amap (fun (ty, m) -> + if isInterfaceTy g ty then + Some(ty, m) + else + None) + + // Get the most specific method overrides for each interface type. + |> List.choose (fun (ty, m) -> + let mostSpecificOverrides = GetIntrinisicMostSpecificOverrideMethInfoSetsOfType infoReader m ty + if mostSpecificOverrides.IsEmpty then None + else Some mostSpecificOverrides) + + match multipleSets with + | [] -> NameMultiMap.Empty + | [set] -> set + | _ -> + multipleSets + // Merge method sets together. + |> List.reduce (fun final minfoSets -> + Map.fold (fun acc key minfos -> + match acc.TryGetValue key with + | true, minfos2 -> Map.add key (minfos @ minfos2) acc + | _ -> Map.add key minfos acc) final minfoSets) + + // Filter for most specifics when the sets have merged together. + |> FilterMostSpecificMethInfoSets g amap range0 + + /// Finds the override interface methods from the most specific overrides by the given method. + let GetMostSpecificOverrideInterfaceMethodsByMethod g amap m (mostSpecificOverrides: NameMultiMap) (minfo: MethInfo) = + let overrideBy = GetInheritedMemberOverrideInfo g amap m OverrideCanImplement.CanImplementAnyInterfaceSlot minfo + let minfoTy = generalizedTyconRef minfo.ApparentEnclosingTyconRef + NameMultiMap.find minfo.LogicalName mostSpecificOverrides + |> List.filter (fun (overridenTy, minfo2) -> + typeEquiv g overridenTy minfoTy && + IsSigExactMatch g amap m minfo2 overrideBy) + + /// Get a collection of slots for the given interface type. + let GetInterfaceDispatchSlots (infoReader: InfoReader) ad m availImpliedInterfaces mostSpecificOverrides interfaceTy = + let g = infoReader.g + let amap = infoReader.amap + + if isInterfaceTy g interfaceTy then + // Check if the interface has an inherited implementation + // If so, you do not have to implement all the methods - each + // specific method is "optionally" implemented. + let isInterfaceOptional = ListSet.contains (typeEquiv g) interfaceTy availImpliedInterfaces + [ for minfo in GetImmediateIntrinsicMethInfosOfType (None, ad) g amap m interfaceTy do + if minfo.IsNewSlot then + // If the interface itself is considered optional, then we are finished and do not need anymore context. + // Even if the method is actually not abstract. + if isInterfaceOptional then + yield RequiredSlot (minfo, true) + + // F# defined interface methods have no notion of optional/abstract or DIMs. + elif not minfo.IsILMethod then + yield RequiredSlot (minfo, false) + + // IL methods might have default implementations. + else + let isMethodOptional (minfo: MethInfo) = + // A DIM is considered *not* 'optional' if it is not language supported. + g.langVersion.SupportsFeature LanguageFeature.DefaultInterfaceMemberConsumption && + not minfo.IsAbstract + + match GetMostSpecificOverrideInterfaceMethodsByMethod g amap m mostSpecificOverrides minfo with + // No override. + | [] -> + if minfo.IsAbstract then + // Regular interface methods are never optional. + yield RequiredSlot (minfo, false) + else + yield DefaultInterfaceImplementationSlot (minfo, isMethodOptional minfo, false) + + // One override, one default implementation. + | [ (_, minfo2) ] -> + yield DefaultInterfaceImplementationSlot (minfo, isMethodOptional minfo2, false) + + // We found multiple override methods, means we might have ambiguity. + | _ -> + // If DIMs are not language supported, then do not consider a slot to have a specific implementation. + let possiblyNoMostSpecific = + g.langVersion.SupportsFeature LanguageFeature.DefaultInterfaceMemberConsumption + + yield DefaultInterfaceImplementationSlot (minfo, false, possiblyNoMostSpecific) ] + else + [] + + /// Get a collection of slots for the given class type. + let GetClassDispatchSlots (infoReader: InfoReader) ad m reqdTy = + [ if not (isInterfaceTy infoReader.g reqdTy) then + // In the normal case, the requirements for a class are precisely all the abstract slots up the whole hierarchy. + // So here we get and yield all of those. + for minfo in reqdTy |> GetIntrinsicMethInfosOfType infoReader None ad AllowMultiIntfInstantiations.Yes IgnoreOverrides m do + if minfo.IsDispatchSlot then + yield RequiredSlot(minfo, not minfo.IsAbstract) ] + + /// Get a collection of slots for the given type and implied types. + let GetDispatchSlotSet (infoReader: InfoReader) ad m availImpliedInterfaces mostSpecificOverrides reqdTy impliedTys = + let g = infoReader.g + + if isInterfaceTy g reqdTy then + [ for impliedTy in impliedTys do + yield (impliedTy, GetInterfaceDispatchSlots infoReader ad m availImpliedInterfaces mostSpecificOverrides impliedTy) ] + else + [ (reqdTy, GetClassDispatchSlots infoReader ad m reqdTy) ] + /// Check all implementations implement some dispatch slot. - let CheckOverridesAreAllUsedOnce(denv, g, amap, isObjExpr, reqdTy, + let CheckOverridesAreAllUsedOnce(denv, g, infoReader: InfoReader, isObjExpr, reqdTy, dispatchSlotsKeyed: NameMultiMap, availPriorOverrides: OverrideInfo list, overrides: OverrideInfo list) = + let amap = infoReader.amap + let availPriorOverridesKeyed = availPriorOverrides |> NameMultiMap.initBy (fun ov -> ov.LogicalName) for overrideBy in overrides do if not overrideBy.IsFakeEventProperty then let m = overrideBy.Range let relevantVirts = NameMultiMap.find overrideBy.LogicalName dispatchSlotsKeyed - let relevantVirts = relevantVirts |> List.map (fun (RequiredSlot(dispatchSlot, _)) -> dispatchSlot) + let relevantVirts = relevantVirts |> List.map (fun reqdSlot -> reqdSlot.MethodInfo) match relevantVirts |> List.filter (fun dispatchSlot -> OverrideImplementsDispatchSlot g amap m dispatchSlot overrideBy) with | [] -> @@ -406,18 +573,18 @@ module DispatchSlotChecking = | [dispatchSlot] -> if dispatchSlot.IsFinal && (isObjExpr || not (typeEquiv g reqdTy dispatchSlot.ApparentEnclosingType)) then - errorR(Error(FSComp.SR.typrelMethodIsSealed(NicePrint.stringOfMethInfo amap m denv dispatchSlot), m)) + errorR(Error(FSComp.SR.typrelMethodIsSealed(NicePrint.stringOfMethInfo infoReader m denv dispatchSlot), m)) | dispatchSlots -> match dispatchSlots |> List.filter (fun dispatchSlot -> isInterfaceTy g dispatchSlot.ApparentEnclosingType || not (DispatchSlotIsAlreadyImplemented g amap m availPriorOverridesKeyed dispatchSlot)) with | h1 :: h2 :: _ -> - errorR(Error(FSComp.SR.typrelOverrideImplementsMoreThenOneSlot((FormatOverride denv overrideBy), (NicePrint.stringOfMethInfo amap m denv h1), (NicePrint.stringOfMethInfo amap m denv h2)), m)) + errorR(Error(FSComp.SR.typrelOverrideImplementsMoreThenOneSlot((FormatOverride denv overrideBy), (NicePrint.stringOfMethInfo infoReader m denv h1), (NicePrint.stringOfMethInfo infoReader m denv h2)), m)) | _ -> // dispatch slots are ordered from the derived classes to base // so we can check the topmost dispatch slot if it is final match dispatchSlots with - | meth :: _ when meth.IsFinal -> errorR(Error(FSComp.SR.tcCannotOverrideSealedMethod((sprintf "%s::%s" (meth.ApparentEnclosingType.ToString()) (meth.LogicalName))), m)) + | meth :: _ when meth.IsFinal -> errorR(Error(FSComp.SR.tcCannotOverrideSealedMethod (sprintf "%s::%s" (meth.ApparentEnclosingType.ToString()) meth.LogicalName), m)) | _ -> () @@ -429,13 +596,13 @@ module DispatchSlotChecking = /// allReqdTys = {C;I2;I3} /// /// allReqdTys can include one class/record/union type. - let GetSlotImplSets (infoReader: InfoReader) denv isObjExpr allReqdTys = + let GetSlotImplSets (infoReader: InfoReader) denv ad isObjExpr allReqdTys = let g = infoReader.g let amap = infoReader.amap let availImpliedInterfaces : TType list = - [ for (reqdTy, m) in allReqdTys do + [ for reqdTy, m in allReqdTys do if not (isInterfaceTy g reqdTy) then let baseTyOpt = if isObjExpr then Some reqdTy else GetSuperTypeOfType g amap m reqdTy match baseTyOpt with @@ -454,7 +621,7 @@ module DispatchSlotChecking = // For each implemented type, reduce its list of implied interfaces by subtracting out those implied // by another implemented interface type. // - // REVIEW: Note complexity O(ity*jty) + // REVIEW: Note complexity O(N^2) let reqdTyInfos = intfSets |> List.map (fun (i, reqdTy, impliedTys, m) -> let reduced = @@ -464,26 +631,17 @@ module DispatchSlotChecking = else acc ) (i, reqdTy, m, reduced)) - // Check that, for each implemented type, at least one implemented type is implied. This is enough to capture - // duplicates. - for (_i, reqdTy, m, impliedTys) in reqdTyInfos do - if isInterfaceTy g reqdTy && isNil impliedTys then - errorR(Error(FSComp.SR.typrelDuplicateInterface(), m)) - - // Check that no interface type is implied twice - // - // Note complexity O(reqdTy*reqdTy) - for (i, _reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do - for (j, _, _, impliedTys2) in reqdTyInfos do - if i > j then - let overlap = ListSet.intersect (TypesFeasiblyEquiv 0 g amap reqdTyRange) impliedTys impliedTys2 - overlap |> List.iter (fun overlappingTy -> - if not (isNil (GetImmediateIntrinsicMethInfosOfType (None, AccessibleFromSomewhere) g amap reqdTyRange overlappingTy |> List.filter (fun minfo -> minfo.IsVirtual))) then - errorR(Error(FSComp.SR.typrelNeedExplicitImplementation(NicePrint.minimalStringOfType denv (List.head overlap)), reqdTyRange))) + // Find the full set of most derived interfaces, used roots to search for default interface implementations of interface methods. + let mostSpecificOverrides = GetMostSpecificOverrideInterfaceMethodSets infoReader allReqdTys // Get the SlotImplSet for each implemented type // This contains the list of required members and the list of available members - [ for (_, reqdTy, reqdTyRange, impliedTys) in reqdTyInfos do + [ for i, reqdTy, reqdTyRange, impliedTys in reqdTyInfos do + + // Check that, for each implemented type, at least one implemented type is implied. This is enough to capture + // duplicates. + if isInterfaceTy g reqdTy && isNil impliedTys then + errorR(Error(FSComp.SR.typrelDuplicateInterface(), reqdTyRange)) // Build a set of the implied interface types, for quicker lookup, by nominal type let isImpliedInterfaceTable = @@ -498,28 +656,7 @@ module DispatchSlotChecking = isImpliedInterfaceTable.ContainsKey (tcrefOfAppTy g ty) && impliedTys |> List.exists (TypesFeasiblyEquiv 0 g amap reqdTyRange ty) - //let isSlotImpl (minfo: MethInfo) = - // not minfo.IsAbstract && minfo.IsVirtual - - // Compute the abstract slots that require implementations - let dispatchSlots = - [ if isInterfaceTy g reqdTy then - for impliedTy in impliedTys do - // Check if the interface has an inherited implementation - // If so, you do not have to implement all the methods - each - // specific method is "optionally" implemented. - let isOptional = - ListSet.contains (typeEquiv g) impliedTy availImpliedInterfaces - for reqdSlot in GetImmediateIntrinsicMethInfosOfType (None, AccessibleFromSomewhere) g amap reqdTyRange impliedTy do - yield RequiredSlot(reqdSlot, isOptional) - else - - // In the normal case, the requirements for a class are precisely all the abstract slots up the whole hierarchy. - // So here we get and yield all of those. - for minfo in reqdTy |> GetIntrinsicMethInfosOfType infoReader None AccessibleFromSomewhere AllowMultiIntfInstantiations.Yes IgnoreOverrides reqdTyRange do - if minfo.IsDispatchSlot then - yield RequiredSlot(minfo, (*isOptional=*) not minfo.IsAbstract) ] - + let dispatchSlotSet = GetDispatchSlotSet infoReader ad reqdTyRange availImpliedInterfaces mostSpecificOverrides reqdTy impliedTys // Compute the methods that are available to implement abstract slots from the base class // @@ -534,16 +671,28 @@ module DispatchSlotChecking = match baseTyOpt with | None -> reqdTy | Some baseTy -> baseTy - [ // Get any class hierarchy methods on this type + [ // Get any class hierarchy methods or default interface methods on this type on this type // // NOTE: What we have below is an over-approximation that will get too many methods // and not always correctly relate them to the slots they implement. For example, // we may get an override from a base class and believe it implements a fresh, new abstract // slot in a subclass. - for minfos in infoReader.GetRawIntrinsicMethodSetsOfType(None, AccessibleFromSomewhere, AllowMultiIntfInstantiations.Yes, reqdTyRange, reqdTy) do + for minfos in infoReader.GetRawIntrinsicMethodSetsOfType(None, ad, AllowMultiIntfInstantiations.Yes, reqdTyRange, reqdTy) do for minfo in minfos do if not minfo.IsAbstract then yield GetInheritedMemberOverrideInfo g amap reqdTyRange CanImplementAnyClassHierarchySlot minfo ] + + /// Check that no interface type is implied twice + for j, _, _, impliedTys2 in reqdTyInfos do + if i > j then + for ty, dispatchSlots in dispatchSlotSet do + if impliedTys2 |> List.exists (TypesFeasiblyEquiv 0 g amap reqdTyRange ty) then + if dispatchSlots + |> List.exists (fun reqdSlot -> + let minfo = reqdSlot.MethodInfo + // If the slot is optional, then we do not need an explicit implementation. + minfo.IsNewSlot && not reqdSlot.IsOptional) then + errorR(Error(FSComp.SR.typrelNeedExplicitImplementation(NicePrint.minimalStringOfType denv ty), reqdTyRange)) // We also collect up the properties. This is used for abstract slot inference when overriding properties let isRelevantRequiredProperty (x: PropInfo) = @@ -551,10 +700,11 @@ module DispatchSlotChecking = isImpliedInterfaceType x.ApparentEnclosingType let reqdProperties = - GetIntrinsicPropInfosOfType infoReader None AccessibleFromSomewhere AllowMultiIntfInstantiations.Yes IgnoreOverrides reqdTyRange reqdTy + GetIntrinsicPropInfosOfType infoReader None ad AllowMultiIntfInstantiations.Yes IgnoreOverrides reqdTyRange reqdTy |> List.filter isRelevantRequiredProperty - let dispatchSlotsKeyed = dispatchSlots |> NameMultiMap.initBy (fun (RequiredSlot(v, _)) -> v.LogicalName) + let dispatchSlots = dispatchSlotSet |> List.map snd |> List.concat + let dispatchSlotsKeyed = dispatchSlots |> NameMultiMap.initBy (fun reqdSlot -> reqdSlot.MethodInfo.LogicalName) yield SlotImplSet(dispatchSlots, dispatchSlotsKeyed, availPriorOverrides, reqdProperties) ] @@ -577,7 +727,7 @@ module DispatchSlotChecking = let allImmediateMembers = tycon.MembersOfFSharpTyconSorted @ tycon.AllGeneratedValues // Get all the members we have to implement, organized by each type we explicitly implement - let slotImplSets = GetSlotImplSets infoReader denv false allReqdTys + let slotImplSets = GetSlotImplSets infoReader denv AccessibleFromSomewhere false allReqdTys let allImpls = List.zip allReqdTys slotImplSets @@ -608,7 +758,7 @@ module DispatchSlotChecking = // We check all the abstracts related to the class hierarchy and then check each interface implementation - for ((reqdTy, m), slotImplSet) in allImpls do + for (reqdTy, m), slotImplSet in allImpls do let (SlotImplSet(dispatchSlots, dispatchSlotsKeyed, availPriorOverrides, _)) = slotImplSet try @@ -622,7 +772,7 @@ module DispatchSlotChecking = if isImplementation && not (isInterfaceTy g overallTy) then let overrides = allImmediateMembersThatMightImplementDispatchSlots |> List.map snd - let allCorrect = CheckDispatchSlotsAreImplemented (denv, g, amap, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, overrides) + let allCorrect = CheckDispatchSlotsAreImplemented (denv, infoReader, m, nenv, sink, tcaug.tcaug_abstract, reqdTy, dispatchSlots, availPriorOverrides, overrides) // Tell the user to mark the thing abstract if it was missing implementations if not allCorrect && not tcaug.tcaug_abstract && not (isInterfaceTy g reqdTy) then @@ -633,7 +783,7 @@ module DispatchSlotChecking = |> List.filter (fst >> mustOverrideSomething reqdTy) |> List.map snd - CheckOverridesAreAllUsedOnce (denv, g, amap, false, reqdTy, dispatchSlotsKeyed, availPriorOverrides, overridesToCheck) + CheckOverridesAreAllUsedOnce (denv, g, infoReader, false, reqdTy, dispatchSlotsKeyed, availPriorOverrides, overridesToCheck) with e -> errorRecovery e m @@ -647,10 +797,11 @@ module DispatchSlotChecking = let slotsigs = overrideBy.MemberInfo.Value.ImplementedSlotSigs slotsigs |> List.map (ReparentSlotSigToUseMethodTypars g overrideBy.Range overrideBy) else - [ for ((reqdTy, m), (SlotImplSet(_dispatchSlots, dispatchSlotsKeyed, _, _))) in allImpls do + [ for (reqdTy, m), SlotImplSet(_dispatchSlots, dispatchSlotsKeyed, _, _) in allImpls do let overrideByInfo = GetTypeMemberOverrideInfo g reqdTy overrideBy let overridenForThisSlotImplSet = - [ for (RequiredSlot(dispatchSlot, _)) in NameMultiMap.find overrideByInfo.LogicalName dispatchSlotsKeyed do + [ for reqdSlot in NameMultiMap.find overrideByInfo.LogicalName dispatchSlotsKeyed do + let dispatchSlot = reqdSlot.MethodInfo if OverrideImplementsDispatchSlot g amap m dispatchSlot overrideByInfo then if tyconRefEq g overrideByInfo.BoundingTyconRef dispatchSlot.DeclaringTyconRef then match dispatchSlot.ArbitraryValRef with @@ -674,13 +825,6 @@ module DispatchSlotChecking = overrideBy.MemberInfo.Value.ImplementedSlotSigs <- overriden) - - -//------------------------------------------------------------------------- -// "Type Completion" inference and a few other checks at the end of the inference scope -//------------------------------------------------------------------------- - - /// "Type Completion" inference and a few other checks at the end of the inference scope let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv, sink, isImplementation, denv) (tycon: Tycon) = @@ -728,7 +872,6 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader: InfoReader, nenv if hasExplicitObjectEqualsOverride && not hasExplicitObjectGetHashCode then warning(Error(FSComp.SR.typrelExplicitImplementationOfEquals(tycon.DisplayName), m)) - // remember these values to ensure we don't generate these methods during codegen tcaug.SetHasObjectGetHashCode hasExplicitObjectGetHashCode @@ -747,7 +890,7 @@ let GetAbstractMethInfosForSynMethodDecl(infoReader: InfoReader, ad, memberName: let minfos = match typToSearchForAbstractMembers with | _, Some(SlotImplSet(_, dispatchSlotsKeyed, _, _)) -> - NameMultiMap.find memberName.idText dispatchSlotsKeyed |> List.map (fun (RequiredSlot(dispatchSlot, _)) -> dispatchSlot) + NameMultiMap.find memberName.idText dispatchSlotsKeyed |> List.map (fun reqdSlot -> reqdSlot.MethodInfo) | ty, None -> GetIntrinsicMethInfosOfType infoReader (Some memberName.idText) ad AllowMultiIntfInstantiations.Yes IgnoreOverrides bindm ty let dispatchSlots = minfos |> List.filter (fun minfo -> minfo.IsDispatchSlot) diff --git a/src/fsharp/MethodOverrides.fsi b/src/fsharp/MethodOverrides.fsi new file mode 100644 index 00000000000..1e5a07350a6 --- /dev/null +++ b/src/fsharp/MethodOverrides.fsi @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Primary logic related to method overrides. +module internal FSharp.Compiler.MethodOverrides + +open Internal.Utilities.Library +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Import +open FSharp.Compiler.Infos +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +type OverrideCanImplement = + | CanImplementAnyInterfaceSlot + | CanImplementAnyClassHierarchySlot + | CanImplementAnySlot + | CanImplementNoSlots + +/// The overall information about a method implementation in a class or object expression +type OverrideInfo = + | Override of OverrideCanImplement * TyconRef * Ident * (Typars * TyparInst) * TType list list * TType option * bool * bool + + member ArgTypes: TType list list + + member BoundingTyconRef: TyconRef + + member CanImplement: OverrideCanImplement + + member IsCompilerGenerated: bool + + member IsFakeEventProperty: bool + + member LogicalName: string + + member Range: range + + member ReturnType: TType option + +type RequiredSlot = + | RequiredSlot of MethInfo * isOptional: bool + | DefaultInterfaceImplementationSlot of MethInfo * isOptional: bool * possiblyNoMostSpecific: bool + + /// Indicates a slot which has a default interface implementation. + /// A combination of this flag and the lack of IsOptional means the slot may have been reabstracted. + member HasDefaultInterfaceImplementation: bool + + /// Indicates a slot which does not have to be implemented, because an inherited implementation is available. + member IsOptional: bool + + /// Gets the method info. + member MethodInfo: MethInfo + + /// A slot that *might* have ambiguity due to multiple inheritance; happens with default interface implementations. + member PossiblyNoMostSpecificImplementation: bool + +type SlotImplSet = SlotImplSet of RequiredSlot list * NameMultiMap * OverrideInfo list * PropInfo list + +exception TypeIsImplicitlyAbstract of range + +exception OverrideDoesntOverride of DisplayEnv * OverrideInfo * MethInfo option * TcGlobals * ImportMap * range + +module DispatchSlotChecking = + /// Format the signature of an override as a string as part of an error message + val FormatOverride: denv:DisplayEnv -> d:OverrideInfo -> string + + /// Format the signature of a MethInfo as a string as part of an error message + val FormatMethInfoSig: g:TcGlobals -> amap:ImportMap -> m:range -> denv:DisplayEnv -> d:MethInfo -> string + + /// Get the override information for an object expression method being used to implement dispatch slots + val GetObjectExprOverrideInfo: g:TcGlobals -> amap:ImportMap -> implty:TType * id:Ident * memberFlags:SynMemberFlags * ty:TType * arityInfo:ValReprInfo * bindingAttribs:Attribs * rhsExpr:Expr -> OverrideInfo * (Val option * Val * Val list list * Attribs * Expr) + + /// Check if an override exactly matches the requirements for a dispatch slot. + val IsExactMatch: g:TcGlobals -> amap:ImportMap -> m:range -> dispatchSlot:MethInfo -> overrideBy:OverrideInfo -> bool + + /// Check all dispatch slots are implemented by some override. + val CheckDispatchSlotsAreImplemented: denv:DisplayEnv * infoReader:InfoReader * m:range * nenv:NameResolutionEnv * sink:TcResultsSink * isOverallTyAbstract:bool * reqdTy:TType * dispatchSlots:RequiredSlot list * availPriorOverrides:OverrideInfo list * overrides:OverrideInfo list -> bool + + /// Check all implementations implement some dispatch slot. + val CheckOverridesAreAllUsedOnce: denv:DisplayEnv * g:TcGlobals * infoReader:InfoReader * isObjExpr:bool * reqdTy:TType * dispatchSlotsKeyed:NameMultiMap * availPriorOverrides:OverrideInfo list * overrides:OverrideInfo list -> unit + + /// Get the slots of a type that can or must be implemented. + val GetSlotImplSets: infoReader:InfoReader -> denv:DisplayEnv -> ad:AccessorDomain -> isObjExpr:bool -> allReqdTys:(TType * range) list -> SlotImplSet list + +/// "Type Completion" inference and a few other checks at the end of the inference scope +val FinalTypeDefinitionChecksAtEndOfInferenceScope: infoReader:InfoReader * nenv:NameResolutionEnv * sink:TcResultsSink * isImplementation:bool * denv:DisplayEnv -> tycon:Tycon -> unit + +/// Get the methods relevant to determining if a uniquely-identified-override exists based on the syntactic information +/// at the member signature prior to type inference. This is used to pre-assign type information if it does +val GetAbstractMethInfosForSynMethodDecl: infoReader:InfoReader * ad:AccessorDomain * memberName:Ident * bindm:range * typToSearchForAbstractMembers:(TType * SlotImplSet option) * valSynData:SynValInfo -> MethInfo list * MethInfo list + +/// Get the properties relevant to determining if a uniquely-identified-override exists based on the syntactic information +/// at the member signature prior to type inference. This is used to pre-assign type information if it does +val GetAbstractPropInfosForSynPropertyDecl: infoReader:InfoReader * ad:AccessorDomain * memberName:Ident * bindm:range * typToSearchForAbstractMembers:(TType * SlotImplSet option) * _k:'a * _valSynData:'b -> PropInfo list + diff --git a/src/fsharp/FSharp.Compiler.LanguageServer/Directory.Build.props b/src/fsharp/Microsoft.FSharp.Compiler/Directory.Build.props similarity index 100% rename from src/fsharp/FSharp.Compiler.LanguageServer/Directory.Build.props rename to src/fsharp/Microsoft.FSharp.Compiler/Directory.Build.props diff --git a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.csproj b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.csproj new file mode 100644 index 00000000000..26620118b48 --- /dev/null +++ b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.csproj @@ -0,0 +1,29 @@ + + + + true + net5.0 + Microsoft.FSharp.Compiler.nuspec + true + .NET Core compatible version of the F# compiler fsc.exe. + /blob/main/release-notes.md#FSharp-Tools-$(FSProductVersionReleaseNotesVersion) + + + + + TargetFramework=net5.0 + + + TargetFramework=net5.0 + + + TargetFramework=netstandard2.0 + + + TargetFramework=netstandard2.0 + + + + + + diff --git a/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec new file mode 100644 index 00000000000..f4877b8258c --- /dev/null +++ b/src/fsharp/Microsoft.FSharp.Compiler/Microsoft.FSharp.Compiler.nuspec @@ -0,0 +1,78 @@ + + + + $CommonMetadataElements$ + en-US + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $CommonFileElements$ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 30f456fd86c..4785453d27c 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -4,28 +4,34 @@ /// Name environment and name resolution module internal FSharp.Compiler.NameResolution +open System.Collections.Generic + open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Library.ResultOrException + open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Internal.Library.ResultOrException open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.Infos open FSharp.Compiler.AccessibilityLogic open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.InfoReader -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Text +open FSharp.Compiler.Infos open FSharp.Compiler.Features -open System.Collections.Generic +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping @@ -35,7 +41,7 @@ open FSharp.Compiler.ExtensionTyping type NameResolver(g: TcGlobals, amap: Import.ImportMap, infoReader: InfoReader, - instantiationGenerator: (range -> Typars -> TypeInst)) = + instantiationGenerator: range -> Typars -> TypeInst) = /// Used to transform typars into new inference typars // instantiationGenerator is a function to help us create the @@ -76,9 +82,17 @@ let TryFindTypeWithRecdField (modref: ModuleOrNamespaceRef) (id: Ident) = |> QueueList.tryFind (fun tycon -> tycon.GetFieldByName id.idText |> Option.isSome) /// Get the active pattern elements defined by a given value, if any -let ActivePatternElemsOfValRef vref = +let ActivePatternElemsOfValRef g (vref: ValRef) = match TryGetActivePatternInfo vref with - | Some apinfo -> apinfo.ActiveTags |> List.mapi (fun i _ -> APElemRef(apinfo, vref, i)) + | Some apinfo -> + + let isStructRetTy = + if apinfo.IsTotal then + false + else + let _, apReturnTy = stripFunTy g vref.TauType + isStructTy g apReturnTy + apinfo.ActiveTags |> List.mapi (fun i _ -> APElemRef(apinfo, vref, i, isStructRetTy)) | None -> [] /// Try to make a reference to a value in a module. @@ -95,19 +109,18 @@ let TryMkValRefInModRef modref vspec = (fun () -> Some (mkNestedValRef modref vspec)) /// Get the active pattern elements defined by a given value, if any -let ActivePatternElemsOfVal modref vspec = +let ActivePatternElemsOfVal g modref vspec = // If the assembly load set is incomplete then don't add anything to the table match TryMkValRefInModRef modref vspec with | None -> [] - | Some vref -> ActivePatternElemsOfValRef vref - + | Some vref -> ActivePatternElemsOfValRef g vref /// Get the active pattern elements defined in a module, if any. Cache in the slot in the module type. -let ActivePatternElemsOfModuleOrNamespace (modref: ModuleOrNamespaceRef) : NameMap = +let ActivePatternElemsOfModuleOrNamespace g (modref: ModuleOrNamespaceRef) : NameMap = let mtyp = modref.ModuleOrNamespaceType cacheOptRef mtyp.ActivePatternElemRefLookupTable (fun () -> mtyp.AllValsAndMembers - |> Seq.collect (ActivePatternElemsOfVal modref) + |> Seq.collect (ActivePatternElemsOfVal g modref) |> Seq.fold (fun acc apref -> NameMap.add apref.Name apref acc) Map.empty) //--------------------------------------------------------------------------- @@ -127,15 +140,17 @@ let (|AbbrevOrAppTy|_|) (ty: TType) = type ArgumentContainer = /// The named argument is an argument of a method | Method of MethInfo - /// The named argument is a static parameter to a provided type or a parameter to an F# exception constructor + /// The named argument is a static parameter to a provided type. | Type of TyconRef - /// The named argument is a static parameter to a union case constructor - | UnionCase of UnionCaseInfo // Note: Active patterns are encoded like this: // let (|A|B|) x = if x < 0 then A else B // A and B are reported as results using 'Item.ActivePatternResult' // match () with | A | B -> () // A and B are reported using 'Item.ActivePatternCase' +let emptyTypeInst : TypeInst = [] +type EnclosingTypeInst = TypeInst +let emptyEnclosingTypeInst : EnclosingTypeInst = emptyTypeInst + [] /// Represents an item that results from name resolution type Item = @@ -144,10 +159,10 @@ type Item = | Value of ValRef /// Represents the resolution of a name to an F# union case. - | UnionCase of UnionCaseInfo * bool + | UnionCase of UnionCaseInfo * hasRequireQualifiedAccessAttr: bool /// Represents the resolution of a name to an F# active pattern result. - | ActivePatternResult of ActivePatternInfo * TType * int * range + | ActivePatternResult of apinfo: ActivePatternInfo * apOverallTy: TType * index: int * range: range /// Represents the resolution of a name to an F# active pattern case within the body of an active pattern. | ActivePatternCase of ActivePatternElemRef @@ -155,9 +170,12 @@ type Item = /// Represents the resolution of a name to an F# exception definition. | ExnCase of TyconRef - /// Represents the resolution of a name to an F# record field. + /// Represents the resolution of a name to an F# record or exception field. | RecdField of RecdFieldInfo + /// Represents the resolution of a name to a union case field. + | UnionCaseField of UnionCaseInfo * fieldIndex: int + /// Represents the resolution of a name to a field of an anonymous record type. | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range @@ -203,7 +221,7 @@ type Item = | TypeVar of string * Typar /// Represents the resolution of a name to a module or namespace - | ModuleOrNamespaces of Tast.ModuleOrNamespaceRef list + | ModuleOrNamespaces of ModuleOrNamespaceRef list /// Represents the resolution of a name to an operator | ImplicitOp of Ident * TraitConstraintSln option ref @@ -225,34 +243,51 @@ type Item = let minfos = minfos |> List.sortBy (fun minfo -> minfo.NumArgs |> List.sum) Item.CtorGroup (nm, minfos) + member d.DisplayNameCore = + match d with + | Item.Value v -> v.DisplayNameCore + | Item.ActivePatternCase apref -> apref.Name + | Item.UnionCase(uinfo, _) -> uinfo.DisplayNameCore + | Item.ExnCase tcref -> tcref.DisplayNameCore + | Item.RecdField rfinfo -> rfinfo.DisplayNameCore + | Item.UnionCaseField (uci, fieldIndex) -> uci.UnionCase.GetFieldByIndex(fieldIndex).DisplayNameCore + | Item.AnonRecdField (anonInfo, _tys, i, _m) -> anonInfo.SortedNames.[i] + | Item.NewDef id -> id.idText + | Item.ILField finfo -> finfo.FieldName + | Item.Event einfo -> einfo.EventName + | Item.Property(_, FSProp(_, _, Some v, _) :: _) + | Item.Property(_, FSProp(_, _, _, Some v) :: _) -> v.DisplayNameCore + | Item.Property(nm, _) -> nm |> DecompileOpName + | Item.MethodGroup(_, FSMeth(_, _, v, _) :: _, _) -> v.DisplayNameCore + | Item.MethodGroup(nm, _, _) -> nm |> DecompileOpName + | Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName + | Item.FakeInterfaceCtor (AbbrevOrAppTy tcref) + | Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayNameCore + | Item.Types(nm, _) -> nm |> DemangleGenericTypeName + | Item.UnqualifiedType(tcref :: _) -> tcref.DisplayNameCore + | Item.TypeVar (nm, _) -> nm + | Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayNameCore + | Item.ArgName (id, _, _) -> id.idText + | Item.SetterArg (id, _) -> id.idText + | Item.CustomOperation (customOpName, _, _) -> customOpName + | Item.CustomBuilder (nm, _) -> nm + | _ -> "" + member d.DisplayName = match d with | Item.Value v -> v.DisplayName - | Item.ActivePatternCase apref -> apref.Name - | Item.UnionCase(uinfo, _) -> DecompileOpName uinfo.UnionCase.DisplayName - | Item.ExnCase tcref -> tcref.LogicalName - | Item.RecdField rfinfo -> DecompileOpName rfinfo.RecdField.Name - | Item.AnonRecdField (anonInfo, _tys, i, _m) -> anonInfo.SortedNames.[i] - | Item.NewDef id -> id.idText - | Item.ILField finfo -> finfo.FieldName - | Item.Event einfo -> einfo.EventName + | Item.UnionCase(uinfo, _) -> uinfo.DisplayName + | Item.ExnCase tcref -> tcref.DisplayName + | Item.RecdField rfinfo -> rfinfo.DisplayName + | Item.UnionCaseField (uci, fieldIndex) -> uci.UnionCase.GetFieldByIndex(fieldIndex).DisplayName | Item.Property(_, FSProp(_, _, Some v, _) :: _) | Item.Property(_, FSProp(_, _, _, Some v) :: _) -> v.DisplayName - | Item.Property(nm, _) -> PrettyNaming.DemangleOperatorName nm - | Item.MethodGroup(_, (FSMeth(_, _, v, _) :: _), _) -> v.DisplayName - | Item.MethodGroup(nm, _, _) -> PrettyNaming.DemangleOperatorName nm - | Item.CtorGroup(nm, _) -> DemangleGenericTypeName nm - | Item.FakeInterfaceCtor (AbbrevOrAppTy tcref) - | Item.DelegateCtor (AbbrevOrAppTy tcref) -> DemangleGenericTypeName tcref.DisplayName - | Item.Types(nm, _) -> DemangleGenericTypeName nm + | Item.MethodGroup(_, FSMeth(_, _, v, _) :: _, _) -> v.DisplayName + | Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayName | Item.UnqualifiedType(tcref :: _) -> tcref.DisplayName + | Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayName | Item.TypeVar (nm, _) -> nm - | Item.ModuleOrNamespaces(modref :: _) -> modref.DemangledModuleOrNamespaceName - | Item.ArgName (id, _, _) -> id.idText - | Item.SetterArg (id, _) -> id.idText - | Item.CustomOperation (customOpName, _, _) -> customOpName - | Item.CustomBuilder (nm, _) -> nm - | _ -> "" + | _ -> d.DisplayNameCore |> ConvertNameToDisplayName let valRefHash (vref: ValRef) = match vref.TryDeref with @@ -271,7 +306,7 @@ let ItemWithNoInst item = ({ Item = item; TyparInst = emptyTyparInst } : ItemWit let (|ItemWithInst|) (x: ItemWithInst) = (x.Item, x.TyparInst) /// Represents a record field resolution and the information if the usage is deprecated. -type FieldResolution = FieldResolution of RecdFieldRef * bool +type FieldResolution = FieldResolution of RecdFieldInfo * bool /// Information about an extension member held in the name resolution environment type ExtensionMember = @@ -327,6 +362,9 @@ type NameResolutionEnv = /// Values, functions, methods and other items available by unqualified name eUnqualifiedItems: UnqualifiedItems + /// Enclosing type instantiations that are associated with an unqualified type item + eUnqualifiedEnclosingTypeInsts: TyconRefMap + /// Data Tags and Active Pattern Tags available by unqualified name ePatItems: NameMap @@ -343,15 +381,19 @@ type NameResolutionEnv = /// open Collections <--- give a warning /// let v = new Collections.Generic.List() <--- give a warning" - eModulesAndNamespaces: NameMultiMap + eModulesAndNamespaces: NameMultiMap /// Fully qualified modules and namespaces. 'open' does not change this. - eFullyQualifiedModulesAndNamespaces: NameMultiMap + eFullyQualifiedModulesAndNamespaces: NameMultiMap /// RecdField labels in scope. RecdField labels are those where type are inferred /// by label rather than by known type annotation. /// Bools indicate if from a record, where no warning is given on indeterminate lookup - eFieldLabels: NameMultiMap + eFieldLabels: NameMultiMap + + /// Record or unions that may have type instantiations associated with them + /// when record labels or union cases are used in an unqualified context. + eUnqualifiedRecordOrUnionTypeInsts: TyconRefMap /// Tycons indexed by the various names that may be used to access them, e.g. /// "List" --> multiple TyconRef's for the various tycons accessible by this name. @@ -384,7 +426,9 @@ type NameResolutionEnv = eModulesAndNamespaces = Map.empty eFullyQualifiedModulesAndNamespaces = Map.empty eFieldLabels = Map.empty + eUnqualifiedRecordOrUnionTypeInsts = TyconRefMap.Empty eUnqualifiedItems = LayeredMap.Empty + eUnqualifiedEnclosingTypeInsts = TyconRefMap.Empty ePatItems = Map.empty eTyconsByAccessNames = LayeredMultiMap.Empty eTyconsByDemangledNameAndArity = LayeredMap.Empty @@ -430,23 +474,37 @@ type ResultCollectionSettings = /// during type checking. let NextExtensionMethodPriority() = uint64 (newStamp()) +/// Checks if the type is used for C# style extension members. +let IsTyconRefUsedForCSharpStyleExtensionMembers g m (tcref: TyconRef) = + // Type must be non-generic and have 'Extension' attribute + isNil(tcref.Typars m) && TyconRefHasAttribute g m g.attrib_ExtensionAttribute tcref + +/// Checks if the type is used for C# style extension members. +let IsTypeUsedForCSharpStyleExtensionMembers g m ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> IsTyconRefUsedForCSharpStyleExtensionMembers g m tcref + | _ -> false + +/// A 'plain' method is an extension method not interpreted as an extension method. +let IsMethInfoPlainCSharpStyleExtensionMember g m isEnclExtTy (minfo: MethInfo) = + // Method must be static, have 'Extension' attribute, must not be curried, must have at least one argument + isEnclExtTy && + not minfo.IsInstance && + not minfo.IsExtensionMember && + (match minfo.NumArgs with [x] when x >= 1 -> true | _ -> false) && + MethInfoHasAttribute g m g.attrib_ExtensionAttribute minfo + /// Get the info for all the .NET-style extension members listed as static members in the type. let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap: Import.ImportMap) m (tcrefOfStaticClass: TyconRef) = let g = amap.g - // Type must be non-generic and have 'Extension' attribute - if isNil(tcrefOfStaticClass.Typars m) && TyconRefHasAttribute g m g.attrib_ExtensionAttribute tcrefOfStaticClass then + + if IsTyconRefUsedForCSharpStyleExtensionMembers g m tcrefOfStaticClass then let pri = NextExtensionMethodPriority() let ty = generalizedTyconRef tcrefOfStaticClass - // Get the 'plain' methods, not interpreted as extension methods let minfos = GetImmediateIntrinsicMethInfosOfType (None, AccessorDomain.AccessibleFromSomeFSharpCode) g amap m ty [ for minfo in minfos do - // Method must be static, have 'Extension' attribute, must not be curried, must have at least one argument - if not minfo.IsInstance && - not minfo.IsExtensionMember && - (match minfo.NumArgs with [x] when x >= 1 -> true | _ -> false) && - MethInfoHasAttribute g m g.attrib_ExtensionAttribute minfo - then + if IsMethInfoPlainCSharpStyleExtensionMember g m true minfo then let ilExtMem = ILExtMem (tcrefOfStaticClass, minfo, pri) // The results are indexed by the TyconRef of the first 'this' argument, if any. @@ -511,7 +569,7 @@ let SelectPropInfosFromExtMembers (infoReader: InfoReader) ad optFilter declarin let amap = infoReader.amap // NOTE: multiple "open"'s push multiple duplicate values into eIndexedExtensionMembers, hence use a set. let seen = HashSet(ExtensionMember.Comparer g) - let propCollector = new PropertyCollector(g, amap, m, declaringTy, optFilter, ad) + let propCollector = PropertyCollector(g, amap, m, declaringTy, optFilter, ad) for emem in extMemInfos do if seen.Add emem then match emem with @@ -536,11 +594,11 @@ let ExtensionPropInfosOfTypeInScope collectionSettings (infoReader:InfoReader) ( let extMemsFromHierarchy = infoReader.GetEntireTypeHierarchy(AllowMultiIntfInstantiations.Yes, m, ty) |> List.collect (fun ty -> - if isAppTy g ty then - let tcref = tcrefOfAppTy g ty + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> let extMemInfos = nenv.eIndexedExtensionMembers.Find tcref SelectPropInfosFromExtMembers infoReader ad optFilter ty m extMemInfos - else []) + | _ -> []) extMemsDangling @ extMemsFromHierarchy @@ -550,15 +608,30 @@ let AllPropInfosOfTypeInScope collectionSettings infoReader nenv optFilter ad fi @ ExtensionPropInfosOfTypeInScope collectionSettings infoReader nenv optFilter ad m ty /// Get the available methods of a type (both declared and inherited) -let IntrinsicMethInfosOfType (infoReader:InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = +let IntrinsicMethInfosOfType (infoReader: InfoReader) optFilter ad allowMultiIntfInst findFlag m ty = let g = infoReader.g let amap = infoReader.amap let minfos = GetIntrinsicMethInfoSetsOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty let minfos = minfos |> ExcludeHiddenOfMethInfos g amap m minfos +let TrySelectExtensionMethInfoOfILExtMem m amap apparentTy (actualParent, minfo, pri) = + match minfo with + | ILMeth(_,ilminfo,_) -> + MethInfo.CreateILExtensionMeth (amap, m, apparentTy, actualParent, Some pri, ilminfo.RawMetadata) |> Some + // F#-defined IL-style extension methods are not seen as extension methods in F# code + | FSMeth(g,_,vref,_) -> + FSMeth(g, apparentTy, vref, Some pri) |> Some +#if !NO_EXTENSIONTYPING + // // Provided extension methods are not yet supported + | ProvidedMeth(amap,providedMeth,_,m) -> + ProvidedMeth(amap, providedMeth, Some pri,m) |> Some +#endif + | DefaultStructCtor _ -> + None + /// Select from a list of extension methods -let SelectMethInfosFromExtMembers (infoReader:InfoReader) optFilter apparentTy m extMemInfos = +let SelectMethInfosFromExtMembers (infoReader: InfoReader) optFilter apparentTy m extMemInfos = let g = infoReader.g // NOTE: multiple "open"'s push multiple duplicate values into eIndexedExtensionMembers let seen = HashSet(ExtensionMember.Comparer g) @@ -575,24 +648,14 @@ let SelectMethInfosFromExtMembers (infoReader:InfoReader) optFilter apparentTy m | _ -> () | ILExtMem (actualParent, minfo, pri) when (match optFilter with None -> true | Some nm -> nm = minfo.LogicalName) -> // Make a reference to the type containing the extension members - match minfo with - | ILMeth(_, ilminfo, _) -> - yield (MethInfo.CreateILExtensionMeth (infoReader.amap, m, apparentTy, actualParent, Some pri, ilminfo.RawMetadata)) - // F#-defined IL-style extension methods are not seen as extension methods in F# code - | FSMeth(g, _, vref, _) -> - yield (FSMeth(g, apparentTy, vref, Some pri)) -#if !NO_EXTENSIONTYPING - // // Provided extension methods are not yet supported - | ProvidedMeth(amap, providedMeth, _, m) -> - yield (ProvidedMeth(amap, providedMeth, Some pri, m)) -#endif - | DefaultStructCtor _ -> - () + match TrySelectExtensionMethInfoOfILExtMem m infoReader.amap apparentTy (actualParent, minfo, pri) with + | Some minfo -> yield minfo + | None -> () | _ -> () ] /// Query the available extension properties of a methods (including extension methods for inherited types) -let ExtensionMethInfosOfTypeInScope (collectionSettings:ResultCollectionSettings) (infoReader:InfoReader) (nenv: NameResolutionEnv) optFilter m ty = +let ExtensionMethInfosOfTypeInScope (collectionSettings: ResultCollectionSettings) (infoReader: InfoReader) (nenv: NameResolutionEnv) optFilter m ty = let extMemsDangling = SelectMethInfosFromExtMembers infoReader optFilter ty m nenv.eUnindexedExtensionMembers if collectionSettings = ResultCollectionSettings.AtMostOneResult && not (isNil extMemsDangling) then extMemsDangling @@ -601,11 +664,11 @@ let ExtensionMethInfosOfTypeInScope (collectionSettings:ResultCollectionSettings infoReader.GetEntireTypeHierarchy(AllowMultiIntfInstantiations.Yes, m, ty) |> List.collect (fun ty -> let g = infoReader.g - if isAppTy g ty then - let tcref = tcrefOfAppTy g ty + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> let extValRefs = nenv.eIndexedExtensionMembers.Find tcref SelectMethInfosFromExtMembers infoReader optFilter ty m extValRefs - else []) + | _ -> []) extMemsDangling @ extMemsFromHierarchy /// Get all the available methods of a type (both intrinsic and extension) @@ -663,9 +726,9 @@ let AddFakeNameToNameEnv nm nenv item = {nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.Add (nm, item) } /// Add an F# value to the table of available active patterns -let AddValRefsToActivePatternsNameEnv ePatItems (vref: ValRef) = +let AddValRefsToActivePatternsNameEnv g ePatItems (vref: ValRef) = let ePatItems = - (ActivePatternElemsOfValRef vref, ePatItems) + (ActivePatternElemsOfValRef g vref, ePatItems) ||> List.foldBack (fun apref tab -> NameMap.add apref.Name (Item.ActivePatternCase apref) tab) @@ -678,15 +741,15 @@ let AddValRefsToActivePatternsNameEnv ePatItems (vref: ValRef) = ePatItems /// Add a set of F# values to the environment. -let AddValRefsToNameEnvWithPriority bulkAddMode pri nenv (vrefs: ValRef []) = +let AddValRefsToNameEnvWithPriority g bulkAddMode pri nenv (vrefs: ValRef []) = if vrefs.Length = 0 then nenv else { nenv with eUnqualifiedItems = AddValRefsToItems bulkAddMode nenv.eUnqualifiedItems vrefs eIndexedExtensionMembers = (nenv.eIndexedExtensionMembers, vrefs) ||> Array.fold (AddValRefToExtensionMembers pri) - ePatItems = (nenv.ePatItems, vrefs) ||> Array.fold AddValRefsToActivePatternsNameEnv } + ePatItems = (nenv.ePatItems, vrefs) ||> Array.fold (AddValRefsToActivePatternsNameEnv g) } /// Add a single F# value to the environment. -let AddValRefToNameEnv nenv (vref: ValRef) = +let AddValRefToNameEnv g nenv (vref: ValRef) = let pri = NextExtensionMethodPriority() { nenv with eUnqualifiedItems = @@ -695,17 +758,17 @@ let AddValRefToNameEnv nenv (vref: ValRef) = else nenv.eUnqualifiedItems eIndexedExtensionMembers = AddValRefToExtensionMembers pri nenv.eIndexedExtensionMembers vref - ePatItems = AddValRefsToActivePatternsNameEnv nenv.ePatItems vref } + ePatItems = AddValRefsToActivePatternsNameEnv g nenv.ePatItems vref } /// Add a set of active pattern result tags to the environment. -let AddActivePatternResultTagsToNameEnv (apinfo: PrettyNaming.ActivePatternInfo) nenv ty m = +let AddActivePatternResultTagsToNameEnv (apinfo: ActivePatternInfo) nenv apOverallTy m = if List.isEmpty apinfo.Names then nenv else - let apresl = List.indexed apinfo.Names + let apResultNameList = List.indexed apinfo.Names { nenv with eUnqualifiedItems = - (apresl, nenv.eUnqualifiedItems) - ||> List.foldBack (fun (j, nm) acc -> acc.Add(nm, Item.ActivePatternResult(apinfo, ty, j, m))) } + (apResultNameList, nenv.eUnqualifiedItems) + ||> List.foldBack (fun (j, nm) acc -> acc.Add(nm, Item.ActivePatternResult(apinfo, apOverallTy, j, m))) } /// Generalize a union case, from Cons --> List.Cons let GeneralizeUnionCaseRef (ucref: UnionCaseRef) = @@ -717,7 +780,7 @@ let AddTyconsByDemangledNameAndArity (bulkAddMode: BulkAdd) (tcrefs: TyconRef[]) if tcrefs.Length = 0 then tab else let entries = tcrefs - |> Array.map (fun tcref -> KeyTyconByDemangledNameAndArity tcref.LogicalName tcref.TyparsNoRange tcref) + |> Array.map (fun tcref -> Construct.KeyTyconByDecodedName tcref.LogicalName tcref) match bulkAddMode with | BulkAdd.Yes -> tab.AddAndMarkAsCollapsible entries @@ -728,7 +791,7 @@ let AddTyconByAccessNames bulkAddMode (tcrefs: TyconRef[]) (tab: LayeredMultiMap if tcrefs.Length = 0 then tab else let entries = tcrefs - |> Array.collect (fun tcref -> KeyTyconByAccessNames tcref.LogicalName tcref) + |> Array.collect (fun tcref -> Construct.KeyTyconByAccessNames tcref.LogicalName tcref) match bulkAddMode with | BulkAdd.Yes -> tab.AddAndMarkAsCollapsible entries @@ -758,59 +821,386 @@ let AddUnionCases2 bulkAddMode (eUnqualifiedItems: UnqualifiedItems) (ucrefs: Un let item = Item.UnionCase(GeneralizeUnionCaseRef ucref, false) acc.Add (ucref.CaseName, item)) -let AddStaticContentOfTyconRefToNameEnv (g:TcGlobals) (amap: Import.ImportMap) ad m (nenv: NameResolutionEnv) (tcref:TyconRef) = - // If OpenStaticClasses is not enabled then don't do this - if amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses then - let ty = generalizedTyconRef tcref - let infoReader = InfoReader(g,amap) - let items = - [| let methGroups = - AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None ad PreferOverrides m ty - |> List.groupBy (fun m -> m.LogicalName) - - for (methName, methGroup) in methGroups do - let methGroup = methGroup |> List.filter (fun m -> not m.IsInstance && not m.IsClassConstructor) - if not methGroup.IsEmpty then - yield KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None)) - - let propInfos = - AllPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None ad PreferOverrides m ty - |> List.groupBy (fun m -> m.PropertyName) - - for (propName, propInfos) in propInfos do - let propInfos = propInfos |> List.filter (fun m -> m.IsStatic) - for propInfo in propInfos do - yield KeyValuePair(propName , Item.Property(propName,[propInfo])) - - let fields = - infoReader.GetILFieldInfosOfType(None, ad, m, ty) - |> List.groupBy (fun f -> f.FieldName) - - for (fieldName, fieldInfos) in fields do - let fieldInfos = fieldInfos |> List.filter (fun fi -> fi.IsStatic) - for fieldInfo in fieldInfos do - yield KeyValuePair(fieldName, Item.ILField(fieldInfo)) - |] - - { nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items } - else - nenv +//------------------------------------------------------------------------- +// TypeNameResolutionInfo +//------------------------------------------------------------------------- + +/// Indicates whether we are resolving type names to type definitions or to constructor methods. +type TypeNameResolutionFlag = + | ResolveTypeNamesToCtors + | ResolveTypeNamesToTypeRefs + +[] +[] +/// Represents information about the generic argument count of a type name when resolving it. +/// +/// In some situations we resolve "List" to any type definition with that name regardless of the number +/// of generic arguments. In others, we know precisely how many generic arguments are needed. +type TypeNameResolutionStaticArgsInfo = + /// Indicates indefinite knowledge of type arguments + | Indefinite + /// Indicates definite knowledge of type arguments + | Definite of int + + /// Indicates definite knowledge of empty type arguments + static member DefiniteEmpty = TypeNameResolutionStaticArgsInfo.Definite 0 + + static member FromTyArgs (numTyArgs: int) = TypeNameResolutionStaticArgsInfo.Definite numTyArgs + + member x.HasNoStaticArgsInfo = match x with TypeNameResolutionStaticArgsInfo.Indefinite -> true | _-> false + + member x.NumStaticArgs = match x with TypeNameResolutionStaticArgsInfo.Indefinite -> 0 | TypeNameResolutionStaticArgsInfo.Definite n -> n + + // Get the first possible mangled name of the type, assuming the args are generic args + member x.MangledNameForType nm = + if x.NumStaticArgs = 0 || TryDemangleGenericNameAndPos nm <> ValueNone then nm + else nm + "`" + string x.NumStaticArgs + +[] +/// Represents information which guides name resolution of types. +type TypeNameResolutionInfo = + | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo + + static member Default = TypeNameResolutionInfo (ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.Indefinite) + static member ResolveToTypeRefs statResInfo = TypeNameResolutionInfo (ResolveTypeNamesToTypeRefs, statResInfo) + member x.StaticArgsInfo = match x with TypeNameResolutionInfo(_, staticResInfo) -> staticResInfo + member x.ResolutionFlag = match x with TypeNameResolutionInfo(flag, _) -> flag + member x.DropStaticArgsInfo = match x with TypeNameResolutionInfo(flag2, _) -> TypeNameResolutionInfo(flag2, TypeNameResolutionStaticArgsInfo.Indefinite) + +/// A flag which indicates if direct references to generated provided types are allowed. Normally these +/// are disallowed. +[] +type PermitDirectReferenceToGeneratedType = + | Yes + | No + +#if !NO_EXTENSIONTYPING + +/// Check for direct references to generated provided types. +let CheckForDirectReferenceToGeneratedType (tcref: TyconRef, genOk, m) = + match genOk with + | PermitDirectReferenceToGeneratedType.Yes -> () + | PermitDirectReferenceToGeneratedType.No -> + match tcref.TypeReprInfo with + | TProvidedTypeRepr info when not info.IsErased -> + if IsGeneratedTypeDirectReference (info.ProvidedType, m) then + error (Error(FSComp.SR.etDirectReferenceToGeneratedTypeNotAllowed(tcref.DisplayName), m)) + | _ -> () + +/// This adds a new entity for a lazily discovered provided type into the TAST structure. +let AddEntityForProvidedType (amap: Import.ImportMap, modref: ModuleOrNamespaceRef, resolutionEnvironment, st: Tainted, m) = + let importProvidedType t = Import.ImportProvidedType amap m t + let isSuppressRelocate = amap.g.isInteractive || st.PUntaint((fun st -> st.IsSuppressRelocate), m) + let tycon = Construct.NewProvidedTycon(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) + modref.ModuleOrNamespaceType.AddProvidedTypeEntity tycon + let tcref = modref.NestedTyconRef tycon + System.Diagnostics.Debug.Assert(modref.TryDeref.IsSome) + tcref + + +/// Given a provided type or provided namespace, resolve the type name using the type provider API. +/// If necessary, incorporate the provided type or namespace into the entity. +let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespaceRef) = + match modref.TypeReprInfo with + | TProvidedNamespaceRepr(resolutionEnvironment, resolvers) -> + match modref.Deref.PublicPath with + | Some(PubPath path) -> + resolvers + |> List.choose (fun r-> TryResolveProvidedType(r, m, path, typeName)) + |> List.map (fun st -> AddEntityForProvidedType (amap, modref, resolutionEnvironment, st, m)) + | None -> [] + + // We have a provided type, look up its nested types (populating them on-demand if necessary) + | TProvidedTypeRepr info -> + let sty = info.ProvidedType + let resolutionEnvironment = info.ResolutionEnvironment + +#if DEBUG + if resolutionEnvironment.showResolutionMessages then + dprintfn "resolving name '%s' in TProvidedTypeRepr '%s'" typeName (sty.PUntaint((fun sty -> sty.FullName), m)) +#endif + + match sty.PApply((fun sty -> sty.GetNestedType typeName), m) with + | Tainted.Null -> + //if staticResInfo.NumStaticArgs > 0 then + // error(Error(FSComp.SR.etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters(), m)) + [] + | nestedSty -> + [AddEntityForProvidedType (amap, modref, resolutionEnvironment, nestedSty, m) ] + | _ -> [] +#endif + +//------------------------------------------------------------------------- +// Resolve (possibly mangled) type names in entity +//------------------------------------------------------------------------- + +/// Qualified lookups of type names where the number of generic arguments is known +/// from context, e.g. Module.Type. The full names suh as ``List`1`` can +/// be used to qualify access if needed +let LookupTypeNameInEntityHaveArity nm (staticResInfo: TypeNameResolutionStaticArgsInfo) (mty: ModuleOrNamespaceType) = + let attempt1 = mty.TypesByMangledName.TryFind (staticResInfo.MangledNameForType nm) + match attempt1 with + | None -> mty.TypesByMangledName.TryFind nm + | _ -> attempt1 + +/// Implements unqualified lookups of type names where the number of generic arguments is NOT known +/// from context. +// +// This is used in five places: +// - static member lookups, e.g. MyType.StaticMember(3) +// - e.g. MyModule.MyType.StaticMember(3) +// - type-qualified field names, e.g. { RecordType.field = 3 } +// - type-qualified constructor names, e.g. match x with UnionType.A -> 3 +// - identifiers to constructors for better error messages, e.g. 'String(3)' after 'open System' +// - the special single-constructor rule in TcTyconCores +// +// Because of the potential ambiguity multiple results can be returned. +// Explicit type annotations can be added where needed to specify the generic arity. +// +// In theory the full names such as ``RecordType`1`` can +// also be used to qualify access if needed, though this is almost never needed. +let LookupTypeNameNoArity nm (byDemangledNameAndArity: LayeredMap) (byAccessNames: LayeredMultiMap) = + match TryDemangleGenericNameAndPos nm with + | ValueSome pos -> + let demangled = DecodeGenericTypeNameWithPos pos nm + match byDemangledNameAndArity.TryGetValue demangled with + | true, res -> [res] + | _ -> + match byAccessNames.TryGetValue nm with + | true, res -> res + | _ -> [] + | _ -> + byAccessNames.[nm] + +/// Qualified lookup of type names in an entity +let LookupTypeNameInEntityNoArity _m nm (mtyp: ModuleOrNamespaceType) = + LookupTypeNameNoArity nm mtyp.TypesByDemangledNameAndArity mtyp.TypesByAccessNames + +/// Lookup a type name in an entity. +let LookupTypeNameInEntityMaybeHaveArity (amap, m, ad, nm, staticResInfo: TypeNameResolutionStaticArgsInfo, modref: ModuleOrNamespaceRef) = + let mtyp = modref.ModuleOrNamespaceType + let tcrefs = + match staticResInfo with + | TypeNameResolutionStaticArgsInfo.Indefinite -> + LookupTypeNameInEntityNoArity m nm mtyp + |> List.map modref.NestedTyconRef + | TypeNameResolutionStaticArgsInfo.Definite _ -> + match LookupTypeNameInEntityHaveArity nm staticResInfo mtyp with + | Some tycon -> [modref.NestedTyconRef tycon] + | None -> [] +#if !NO_EXTENSIONTYPING + let tcrefs = + match tcrefs with + | [] -> ResolveProvidedTypeNameInEntity (amap, m, nm, modref) + | _ -> tcrefs +#else + amap |> ignore +#endif + let tcrefs = tcrefs |> List.filter (IsEntityAccessible amap m ad) + tcrefs + +/// Get all the accessible nested types of an existing type. +let GetNestedTyconRefsOfType (infoReader: InfoReader) (amap: Import.ImportMap) (ad, optFilter, staticResInfo, checkForGenerated, m) ty = + let g = amap.g + argsOfAppTy g ty, + infoReader.GetPrimaryTypeHierarchy(AllowMultiIntfInstantiations.Yes, m, ty) |> List.collect (fun ty -> + match ty with + | AppTy g (tcref, _) -> + let tycon = tcref.Deref + let mty = tycon.ModuleOrNamespaceType + // No dotting through type generators to get to a nested type! +#if !NO_EXTENSIONTYPING + if checkForGenerated then + CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) +#else + checkForGenerated |> ignore +#endif + + match optFilter with + | Some nm -> + LookupTypeNameInEntityMaybeHaveArity (amap, m, ad, nm, staticResInfo, tcref) + | None -> +#if !NO_EXTENSIONTYPING + match tycon.TypeReprInfo with + | TProvidedTypeRepr info -> + [ for nestedType in info.ProvidedType.PApplyArray((fun sty -> sty.GetNestedTypes()), "GetNestedTypes", m) do + let nestedTypeName = nestedType.PUntaint((fun t -> t.Name), m) + yield! + LookupTypeNameInEntityMaybeHaveArity (amap, m, ad, nestedTypeName, staticResInfo, tcref) ] + + | _ -> +#endif + mty.TypesByAccessNames.Values + |> List.choose (fun entity -> + let tcref = tcref.NestedTyconRef entity + if IsEntityAccessible amap m ad tcref then Some tcref else None) + | _ -> []) + +/// Make a type that refers to a nested type. +/// +/// Handle the .NET/C# business where nested generic types implicitly accumulate the type parameters +/// from their enclosing types. +let MakeNestedType (ncenv: NameResolver) (tinst: TType list) m (tcrefNested: TyconRef) = + let tps = List.skip tinst.Length (tcrefNested.Typars m) + let tinstNested = ncenv.InstantiationGenerator m tps + mkAppTy tcrefNested (tinst @ tinstNested) + +/// Get all the accessible nested types of an existing type. +let GetNestedTypesOfType (ad, ncenv: NameResolver, optFilter, staticResInfo, checkForGenerated, m) ty = + let tinst, tcrefsNested = GetNestedTyconRefsOfType ncenv.InfoReader ncenv.amap (ad, optFilter, staticResInfo, checkForGenerated, m) ty + tcrefsNested + |> List.map (MakeNestedType ncenv tinst m) + +let ChooseMethInfosForNameEnv g m ty (minfos: MethInfo list) = + let isExtTy = IsTypeUsedForCSharpStyleExtensionMembers g m ty + + minfos + |> List.filter (fun minfo -> + not (minfo.IsInstance || minfo.IsClassConstructor || minfo.IsConstructor) && typeEquiv g minfo.ApparentEnclosingType ty && + not (IsMethInfoPlainCSharpStyleExtensionMember g m isExtTy minfo) && + not (IsMangledOpName minfo.LogicalName)) + |> List.groupBy (fun minfo -> minfo.LogicalName) + |> List.filter (fun (_, methGroup) -> not methGroup.IsEmpty) + |> List.map (fun (methName, methGroup) -> KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None))) + +let ChoosePropInfosForNameEnv g ty (pinfos: PropInfo list) = + pinfos + |> List.filter (fun pinfo -> + pinfo.IsStatic && typeEquiv g pinfo.ApparentEnclosingType ty) + |> List.groupBy (fun pinfo -> pinfo.PropertyName) + |> List.filter (fun (_, propGroup) -> not propGroup.IsEmpty) + |> List.map (fun (propName, propGroup) -> KeyValuePair(propName, Item.Property(propName, propGroup))) + +let ChooseFSharpFieldInfosForNameEnv g ty (rfinfos: RecdFieldInfo list) = + rfinfos + |> List.filter (fun rfinfo -> rfinfo.IsStatic && typeEquiv g rfinfo.DeclaringType ty) + |> List.map (fun rfinfo -> KeyValuePair(rfinfo.LogicalName, Item.RecdField rfinfo)) + +let ChooseILFieldInfosForNameEnv g ty (finfos: ILFieldInfo list) = + finfos + |> List.filter (fun finfo -> finfo.IsStatic && typeEquiv g finfo.ApparentEnclosingType ty) + |> List.map (fun finfo -> KeyValuePair(finfo.FieldName, Item.ILField finfo)) + +let ChooseEventInfosForNameEnv g ty (einfos: EventInfo list) = + einfos + |> List.filter (fun einfo -> einfo.IsStatic && typeEquiv g einfo.ApparentEnclosingType ty) + |> List.map (fun einfo -> KeyValuePair(einfo.EventName, Item.Event einfo)) + +/// Add static content from a type. +/// Rules: +/// 1. Add nested types - access to their constructors. +/// 2. Add static parts of type - i.e. C# style extension members, record labels, and union cases. +/// 3. Add static extention methods. +/// 4. Add static extension properties. +/// 5. Add static events. +/// 6. Add static fields. +/// 7. Add static properies. +/// 8. Add static methods and combine extension methods of the same group. +let rec AddStaticContentOfTypeToNameEnv (g:TcGlobals) (amap: Import.ImportMap) ad m (nenv: NameResolutionEnv) (ty: TType) = + let infoReader = InfoReader(g,amap) + + let nenv = AddNestedTypesOfTypeToNameEnv infoReader amap ad m nenv ty + let nenv = AddStaticPartsOfTypeToNameEnv amap m nenv ty + + // The order of items matter such as intrinsic members will always be favored over extension members of the same name. + // Extension property members will always be favored over extenion methods of the same name. + let items = + [| + // Extension methods + yield! + ExtensionMethInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None m ty + |> ChooseMethInfosForNameEnv g m ty + + // Extension properties + yield! + ExtensionPropInfosOfTypeInScope ResultCollectionSettings.AllResults infoReader nenv None ad m ty + |> ChoosePropInfosForNameEnv g ty + + // Events + yield! + infoReader.GetEventInfosOfType(None, ad, m, ty) + |> ChooseEventInfosForNameEnv g ty + + // FSharp fields + yield! + infoReader.GetRecordOrClassFieldsOfType(None, ad, m, ty) + |> ChooseFSharpFieldInfosForNameEnv g ty + + // IL fields + yield! + infoReader.GetILFieldInfosOfType(None, ad, m, ty) + |> ChooseILFieldInfosForNameEnv g ty + + // Properties + yield! + IntrinsicPropInfosOfTypeInScope infoReader None ad PreferOverrides m ty + |> ChoosePropInfosForNameEnv g ty + |] + + let nenv = { nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible items } + + let methodGroupItems = + // Methods + IntrinsicMethInfosOfType infoReader None ad AllowMultiIntfInstantiations.Yes PreferOverrides m ty + |> ChooseMethInfosForNameEnv g m ty + // Combine methods and extension method groups of the same type + |> List.map (fun pair -> + match pair.Value with + | Item.MethodGroup(name, methInfos, orig) -> + match nenv.eUnqualifiedItems.TryFind pair.Key with + // First method of the found group must be an extension and have the same enclosing type as the type we are opening. + // If the first method is an extension, we are assuming the rest of the methods in the group are also extensions. + | Some(Item.MethodGroup(_, (methInfo :: _ as methInfos2), _)) when methInfo.IsExtensionMember && typeEquiv g methInfo.ApparentEnclosingType ty -> + KeyValuePair (pair.Key, Item.MethodGroup(name, methInfos @ methInfos2, orig)) + | _ -> + pair + | _ -> + pair) + |> Array.ofList + + { nenv with eUnqualifiedItems = nenv.eUnqualifiedItems.AddAndMarkAsCollapsible methodGroupItems } -/// Add any implied contents of a type definition to the environment. -let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) amap ad m nenv (tcref: TyconRef) = +and private AddNestedTypesOfTypeToNameEnv infoReader (amap: Import.ImportMap) ad m nenv ty = + let tinst, tcrefs = GetNestedTyconRefsOfType infoReader amap (ad, None, TypeNameResolutionStaticArgsInfo.Indefinite, true, m) ty + let tcrefGroup = + tcrefs + |> List.groupBy (fun tcref -> tcref.LogicalName) + + (nenv, tcrefGroup) + ||> List.fold (fun nenv (_, tcrefs) -> + AddTyconRefsWithEnclosingTypeInstToNameEnv BulkAdd.Yes false amap.g amap ad m false nenv (tinst, tcrefs)) + +and private AddTyconRefsWithEnclosingTypeInstToNameEnv bulkAddMode ownDefinition g amap ad m root nenv (tinstEnclosing: TypeInst, tcrefs: TyconRef list) = + let nenv = + (nenv, tcrefs) + ||> List.fold (fun nenv tcref -> + if tinstEnclosing.IsEmpty then nenv + else { nenv with eUnqualifiedEnclosingTypeInsts = nenv.eUnqualifiedEnclosingTypeInsts.Add tcref tinstEnclosing }) + AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap ad m root nenv tcrefs + +and private AddStaticPartsOfTypeToNameEnv (amap: Import.ImportMap) m nenv ty = + match tryAppTy amap.g ty with + | ValueSome (tcref, tinst) -> + AddStaticPartsOfTyconRefToNameEnv BulkAdd.Yes false amap.g amap m nenv (Some tinst) tcref + | _ -> + nenv +and private AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv tinstOpt (tcref: TyconRef) = let isIL = tcref.IsILTycon let ucrefs = if isIL then [] else tcref.UnionCasesAsList |> List.map tcref.MakeNestedUnionCaseRef let flds = if isIL then [| |] else tcref.AllFieldsArray + // C# style extension members let eIndexedExtensionMembers, eUnindexedExtensionMembers = - let ilStyleExtensionMeths = GetCSharpStyleIndexedExtensionMembersForTyconRef amap m tcref + let ilStyleExtensionMeths = GetCSharpStyleIndexedExtensionMembersForTyconRef amap m tcref ((nenv.eIndexedExtensionMembers, nenv.eUnindexedExtensionMembers), ilStyleExtensionMeths) ||> List.fold (fun (tab1, tab2) extMemInfo -> match extMemInfo with | Choice1Of2 (tcref, extMemInfo) -> tab1.Add (tcref, extMemInfo), tab2 | Choice2Of2 extMemInfo -> tab1, extMemInfo :: tab2) let isILOrRequiredQualifiedAccess = isIL || (not ownDefinition && HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute tcref.Attribs) + + // Record labels let eFieldLabels = if isILOrRequiredQualifiedAccess || not tcref.IsRecordTycon || flds.Length = 0 then nenv.eFieldLabels @@ -820,6 +1210,47 @@ let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) else AddRecdField (tcref.MakeNestedRecdFieldRef f) acc) let eUnqualifiedItems = + let tab = nenv.eUnqualifiedItems + if isILOrRequiredQualifiedAccess || List.isEmpty ucrefs then + tab + else + // Union cases for unqualfied + AddUnionCases2 bulkAddMode tab ucrefs + + let ePatItems = + if isILOrRequiredQualifiedAccess || List.isEmpty ucrefs then + nenv.ePatItems + else + // Union cases for patterns + AddUnionCases1 nenv.ePatItems ucrefs + + let eUnqualifiedRecordOrUnionTypeInsts = + if isILOrRequiredQualifiedAccess || not (tcref.IsRecordTycon || tcref.IsUnionTycon) then + nenv.eUnqualifiedRecordOrUnionTypeInsts + else + match tinstOpt with + | None + | Some [] -> nenv.eUnqualifiedEnclosingTypeInsts + | Some tinst -> + nenv.eUnqualifiedRecordOrUnionTypeInsts.Add tcref tinst + + { nenv with + eFieldLabels = eFieldLabels + eUnqualifiedRecordOrUnionTypeInsts = eUnqualifiedRecordOrUnionTypeInsts + eUnqualifiedItems = eUnqualifiedItems + ePatItems = ePatItems + eIndexedExtensionMembers = eIndexedExtensionMembers + eUnindexedExtensionMembers = eUnindexedExtensionMembers } + +and private CanAutoOpenTyconRef (g: TcGlobals) m (tcref: TyconRef) = + g.langVersion.SupportsFeature LanguageFeature.OpenTypeDeclaration && + not tcref.IsILTycon && + TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute tcref.Attribs = Some true && + tcref.Typars(m).Length = 0 + +/// Add any implied contents of a type definition to the environment. +and private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) amap ad m nenv (tcref: TyconRef) = + let nenv = let tab = nenv.eUnqualifiedItems // add the type name for potential use as a constructor // The rules are @@ -846,38 +1277,20 @@ let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g: TcGlobals) else tab - let tab = - if isILOrRequiredQualifiedAccess || List.isEmpty ucrefs then - tab - else - AddUnionCases2 bulkAddMode tab ucrefs - - tab - - let ePatItems = - if isILOrRequiredQualifiedAccess || List.isEmpty ucrefs then - nenv.ePatItems - else - AddUnionCases1 nenv.ePatItems ucrefs - - let nenv = - { nenv with - eFieldLabels = eFieldLabels - eUnqualifiedItems = eUnqualifiedItems - ePatItems = ePatItems - eIndexedExtensionMembers = eIndexedExtensionMembers - eUnindexedExtensionMembers = eUnindexedExtensionMembers } + { nenv with eUnqualifiedItems = tab } + let nenv = AddStaticPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap m nenv None tcref let nenv = - if TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute tcref.Attribs = Some true && isStaticClass g tcref then - AddStaticContentOfTyconRefToNameEnv g amap ad m nenv tcref + if CanAutoOpenTyconRef g m tcref then + let ty = generalizedTyconRef tcref + AddStaticContentOfTypeToNameEnv g amap ad m nenv ty else - nenv + nenv nenv /// Add a set of type definitions to the name resolution environment -let AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap ad m root nenv tcrefs = +and AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap ad m root nenv tcrefs = if isNil tcrefs then nenv else let env = List.fold (AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition g amap ad m) nenv tcrefs // Add most of the contents of the tycons en-masse, then flatten the tables if we're opening a module or namespace @@ -983,7 +1396,7 @@ and AddModuleOrNamespaceContentsToNameEnv (g: TcGlobals) amap (ad: AccessorDomai mty.AllValsAndMembers.ToList() |> List.choose (fun x -> if IsAccessible ad x.Accessibility then TryMkValRefInModRef modref x else None) |> List.toArray - let nenv = AddValRefsToNameEnvWithPriority BulkAdd.Yes pri nenv vrefs + let nenv = AddValRefsToNameEnvWithPriority g BulkAdd.Yes pri nenv vrefs let nestedModules = MakeNestedModuleRefs modref let nenv = (nenv, nestedModules) ||> AddModuleOrNamespaceRefsToNameEnv g amap m root ad nenv @@ -996,14 +1409,17 @@ and AddModuleOrNamespaceContentsToNameEnv (g: TcGlobals) amap (ad: AccessorDomai // open M1 // // The list contains [M1b; M1a] -and AddEntitiesContentsToNameEnv g amap ad m root nenv modrefs = - (modrefs, nenv) ||> List.foldBack (fun modref acc -> AddEntityContentsToNameEnv g amap ad m root acc modref) +and AddModuleOrNamespaceRefsContentsToNameEnv g amap ad m root nenv modrefs = + (modrefs, nenv) ||> List.foldBack (fun modref acc -> AddModuleOrNamespaceRefContentsToNameEnv g amap ad m root acc modref) -and AddEntityContentsToNameEnv g amap ad m root nenv (modref: EntityRef) = - if modref.IsModuleOrNamespace then - AddModuleOrNamespaceContentsToNameEnv g amap ad m root nenv modref - else - AddStaticContentOfTyconRefToNameEnv g amap ad m nenv modref +and AddTypeContentsToNameEnv g amap ad m nenv (typ: TType) = + assert (isAppTy g typ) + assert not (tcrefOfAppTy g typ).IsModuleOrNamespace + AddStaticContentOfTypeToNameEnv g amap ad m nenv typ + +and AddModuleOrNamespaceRefContentsToNameEnv g amap ad m root nenv (modref: EntityRef) = + assert modref.IsModuleOrNamespace + AddModuleOrNamespaceContentsToNameEnv g amap ad m root nenv modref /// Add a single modules or namespace to the name resolution environment let AddModuleOrNamespaceRefToNameEnv g amap m root ad nenv (modref: EntityRef) = @@ -1036,25 +1452,42 @@ let AddDeclaredTyparsToNameEnv check nenv typars = //------------------------------------------------------------------------- /// Convert a reference to a named type into a type that includes -/// a fresh set of inference type variables for the type parameters of the union type. +/// a fresh set of inference type variables for the type parameters. let FreshenTycon (ncenv: NameResolver) m (tcref: TyconRef) = let tinst = ncenv.InstantiationGenerator m (tcref.Typars m) let improvedTy = ncenv.g.decompileType tcref tinst improvedTy +/// Convert a reference to a named type into a type that includes +/// a set of enclosing type instantiations and a fresh set of inference type variables for the type parameters. +let FreshenTyconWithEnclosingTypeInst (ncenv: NameResolver) m (tinstEnclosing: TypeInst) (tcref: TyconRef) = + let tps = ncenv.InstantiationGenerator m (tcref.Typars m) + let tinst = List.skip tinstEnclosing.Length tps + let improvedTy = ncenv.g.decompileType tcref (tinstEnclosing @ tinst) + improvedTy + /// Convert a reference to a union case into a UnionCaseInfo that includes /// a fresh set of inference type variables for the type parameters of the union type. -let FreshenUnionCaseRef (ncenv: NameResolver) m (ucref: UnionCaseRef) = +let FreshenUnionCaseRef (ncenv: NameResolver) m (ucref: UnionCaseRef) = let tinst = ncenv.InstantiationGenerator m (ucref.TyconRef.Typars m) UnionCaseInfo(tinst, ucref) -/// This must be called after fetching unqualified items that may need to be freshened -let FreshenUnqualifiedItem (ncenv: NameResolver) m res = +/// Generate a new reference to a record field with a fresh type instantiation +let FreshenRecdFieldRef (ncenv: NameResolver) m (rfref: RecdFieldRef) = + RecdFieldInfo(ncenv.InstantiationGenerator m (rfref.Tycon.Typars m), rfref) + +/// This must be called after fetching unqualified items that may need to be freshened +/// or have type instantiations +let ResolveUnqualifiedItem (ncenv: NameResolver) nenv m res = match res with - | Item.UnionCase(UnionCaseInfo(_, ucref), _) -> Item.UnionCase(FreshenUnionCaseRef ncenv m ucref, false) + | Item.UnionCase(UnionCaseInfo(_, ucref), _) -> + match nenv.eUnqualifiedRecordOrUnionTypeInsts.TryFind ucref.TyconRef with + | Some tinst -> + Item.UnionCase(UnionCaseInfo(tinst, ucref), false) + | _ -> + Item.UnionCase(FreshenUnionCaseRef ncenv m ucref, false) | _ -> res - //------------------------------------------------------------------------- // Resolve module paths, value, field etc. lookups. Doing this involves // searching through many possibilities and disambiguating. Hence first @@ -1083,7 +1516,7 @@ let AddResults res1 res2 = | Exception _, Result l -> Result l | Result x, Exception _ -> Result x // If we have error messages for the same symbol, then we can merge suggestions. - | Exception (UndefinedName(n1, f, id1, suggestions1)), Exception (UndefinedName(n2, _, id2, suggestions2)) when n1 = n2 && id1.idText = id2.idText && Range.equals id1.idRange id2.idRange -> + | Exception (UndefinedName(n1, f, id1, suggestions1)), Exception (UndefinedName(n2, _, id2, suggestions2)) when n1 = n2 && id1.idText = id2.idText && equals id1.idRange id2.idRange -> Exception(UndefinedName(n1, f, id1, fun addToBuffer -> suggestions1 addToBuffer; suggestions2 addToBuffer)) // This prefers error messages coming from deeper failing long identifier paths | Exception (UndefinedName(n1, _, _, _) as e1), Exception (UndefinedName(n2, _, _, _) as e2) -> @@ -1119,129 +1552,39 @@ let MapResults f = function | Exception err -> Exception err let AtMostOneResult m res = - match res with - | Exception err -> raze err - | Result [] -> raze (Error(FSComp.SR.nrInvalidModuleExprType(), m)) - | Result (res :: _) -> success res - -let AtMostOneResultQuery query2 res1 = - match res1 with - | Exception _ -> AddResults res1 (query2()) - | Result [] -> query2() - | _ -> res1 - -let inline (+++) res1 query2 = AtMostOneResultQuery query2 res1 - -//------------------------------------------------------------------------- -// TypeNameResolutionInfo -//------------------------------------------------------------------------- - -/// Indicates whether we are resolving type names to type definitions or to constructor methods. -type TypeNameResolutionFlag = - | ResolveTypeNamesToCtors - | ResolveTypeNamesToTypeRefs - -[] -[] -/// Represents information about the generic argument count of a type name when resolving it. -/// -/// In some situations we resolve "List" to any type definition with that name regardless of the number -/// of generic arguments. In others, we know precisely how many generic arguments are needed. -type TypeNameResolutionStaticArgsInfo = - /// Indicates indefinite knowledge of type arguments - | Indefinite - /// Indicates definite knowledge of type arguments - | Definite of int - - /// Indicates definite knowledge of empty type arguments - static member DefiniteEmpty = TypeNameResolutionStaticArgsInfo.Definite 0 - - static member FromTyArgs (numTyArgs: int) = TypeNameResolutionStaticArgsInfo.Definite numTyArgs - - member x.HasNoStaticArgsInfo = match x with TypeNameResolutionStaticArgsInfo.Indefinite -> true | _-> false - - member x.NumStaticArgs = match x with TypeNameResolutionStaticArgsInfo.Indefinite -> 0 | TypeNameResolutionStaticArgsInfo.Definite n -> n - - // Get the first possible mangled name of the type, assuming the args are generic args - member x.MangledNameForType nm = - if x.NumStaticArgs = 0 || TryDemangleGenericNameAndPos nm <> ValueNone then nm - else nm + "`" + string x.NumStaticArgs - -[] -/// Represents information which guides name resolution of types. -type TypeNameResolutionInfo = - | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo + match res with + | Exception err -> raze err + | Result [] -> raze (Error(FSComp.SR.nrInvalidModuleExprType(), m)) + | Result (res :: _) -> success res - static member Default = TypeNameResolutionInfo (ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.Indefinite) - static member ResolveToTypeRefs statResInfo = TypeNameResolutionInfo (ResolveTypeNamesToTypeRefs, statResInfo) - member x.StaticArgsInfo = match x with TypeNameResolutionInfo(_, staticResInfo) -> staticResInfo - member x.ResolutionFlag = match x with TypeNameResolutionInfo(flag, _) -> flag - member x.DropStaticArgsInfo = match x with TypeNameResolutionInfo(flag2, _) -> TypeNameResolutionInfo(flag2, TypeNameResolutionStaticArgsInfo.Indefinite) +let AtMostOneResultQuery query2 res1 = + match res1 with + | Exception _ -> AddResults res1 (query2()) + | Result [] -> query2() + | _ -> res1 +let inline (+++) res1 query2 = AtMostOneResultQuery query2 res1 //------------------------------------------------------------------------- -// Resolve (possibly mangled) type names +// Resolve (possibly mangled) type names in environment //------------------------------------------------------------------------- -/// Qualified lookups of type names where the number of generic arguments is known -/// from context, e.g. Module.Type. The full names suh as ``List`1`` can -/// be used to qualify access if needed -let LookupTypeNameInEntityHaveArity nm (staticResInfo: TypeNameResolutionStaticArgsInfo) (mty: ModuleOrNamespaceType) = - let attempt1 = mty.TypesByMangledName.TryFind (staticResInfo.MangledNameForType nm) - match attempt1 with - | None -> mty.TypesByMangledName.TryFind nm - | _ -> attempt1 - /// Unqualified lookups of type names where the number of generic arguments is known /// from context, e.g. List. Rebindings due to 'open' may have rebound identifiers. let LookupTypeNameInEnvHaveArity fq nm numTyArgs (nenv: NameResolutionEnv) = let key = match TryDemangleGenericNameAndPos nm with - | ValueSome pos -> DecodeGenericTypeName pos nm + | ValueSome pos -> DecodeGenericTypeNameWithPos pos nm | _ -> NameArityPair(nm, numTyArgs) match nenv.TyconsByDemangledNameAndArity(fq).TryFind key with | None -> nenv.TyconsByAccessNames(fq).TryFind nm |> Option.map List.head | res -> res -/// Implements unqualified lookups of type names where the number of generic arguments is NOT known -/// from context. -// -// This is used in five places: -// - static member lookups, e.g. MyType.StaticMember(3) -// - e.g. MyModule.MyType.StaticMember(3) -// - type-qualified field names, e.g. { RecordType.field = 3 } -// - type-qualified constructor names, e.g. match x with UnionType.A -> 3 -// - identifiers to constructors for better error messages, e.g. 'String(3)' after 'open System' -// - the special single-constructor rule in TcTyconCores -// -// Because of the potential ambiguity multiple results can be returned. -// Explicit type annotations can be added where needed to specify the generic arity. -// -// In theory the full names such as ``RecordType`1`` can -// also be used to qualify access if needed, though this is almost never needed. - -let LookupTypeNameNoArity nm (byDemangledNameAndArity: LayeredMap) (byAccessNames: LayeredMultiMap) = - match TryDemangleGenericNameAndPos nm with - | ValueSome pos -> - let demangled = DecodeGenericTypeName pos nm - match byDemangledNameAndArity.TryGetValue demangled with - | true, res -> [res] - | _ -> - match byAccessNames.TryGetValue nm with - | true, res -> res - | _ -> [] - | _ -> - byAccessNames.[nm] - /// Qualified lookup of type names in the environment let LookupTypeNameInEnvNoArity fq nm (nenv: NameResolutionEnv) = LookupTypeNameNoArity nm (nenv.TyconsByDemangledNameAndArity fq) (nenv.TyconsByAccessNames fq) -/// Qualified lookup of type names in an entity -let LookupTypeNameInEntityNoArity m nm (mtyp: ModuleOrNamespaceType) = - LookupTypeNameNoArity nm (mtyp.TypesByDemangledNameAndArity m) mtyp.TypesByAccessNames - /// Qualified lookup of type names in an entity where we may know a generic argument count let LookupTypeNameInEnvMaybeHaveArity fq nm (typeNameResInfo: TypeNameResolutionInfo) nenv = if typeNameResInfo.StaticArgsInfo.HasNoStaticArgsInfo then @@ -1249,142 +1592,6 @@ let LookupTypeNameInEnvMaybeHaveArity fq nm (typeNameResInfo: TypeNameResolution else LookupTypeNameInEnvHaveArity fq nm typeNameResInfo.StaticArgsInfo.NumStaticArgs nenv |> Option.toList -/// A flag which indicates if direct references to generated provided types are allowed. Normally these -/// are disallowed. -[] -type PermitDirectReferenceToGeneratedType = - | Yes - | No - - -#if !NO_EXTENSIONTYPING - -/// Check for direct references to generated provided types. -let CheckForDirectReferenceToGeneratedType (tcref: TyconRef, genOk, m) = - match genOk with - | PermitDirectReferenceToGeneratedType.Yes -> () - | PermitDirectReferenceToGeneratedType.No -> - match tcref.TypeReprInfo with - | TProvidedTypeExtensionPoint info when not info.IsErased -> - //printfn "checking direct reference to generated type '%s'" tcref.DisplayName - if ExtensionTyping.IsGeneratedTypeDirectReference (info.ProvidedType, m) then - error (Error(FSComp.SR.etDirectReferenceToGeneratedTypeNotAllowed(tcref.DisplayName), m)) - | _ -> () - - -/// This adds a new entity for a lazily discovered provided type into the TAST structure. -let AddEntityForProvidedType (amap: Import.ImportMap, modref: ModuleOrNamespaceRef, resolutionEnvironment, st: Tainted, m) = - let importProvidedType t = Import.ImportProvidedType amap m t - let isSuppressRelocate = amap.g.isInteractive || st.PUntaint((fun st -> st.IsSuppressRelocate), m) - let tycon = Construct.NewProvidedTycon(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) - modref.ModuleOrNamespaceType.AddProvidedTypeEntity tycon - let tcref = modref.NestedTyconRef tycon - System.Diagnostics.Debug.Assert(modref.TryDeref.IsSome) - tcref - - -/// Given a provided type or provided namespace, resolve the type name using the type provider API. -/// If necessary, incorporate the provided type or namespace into the entity. -let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespaceRef) = - match modref.TypeReprInfo with - | TProvidedNamespaceExtensionPoint(resolutionEnvironment, resolvers) -> - match modref.Deref.PublicPath with - | Some(PubPath path) -> - resolvers - |> List.choose (fun r-> ExtensionTyping.TryResolveProvidedType(r, m, path, typeName)) - |> List.map (fun st -> AddEntityForProvidedType (amap, modref, resolutionEnvironment, st, m)) - | None -> [] - - // We have a provided type, look up its nested types (populating them on-demand if necessary) - | TProvidedTypeExtensionPoint info -> - let sty = info.ProvidedType - let resolutionEnvironment = info.ResolutionEnvironment - -#if DEBUG - if resolutionEnvironment.showResolutionMessages then - dprintfn "resolving name '%s' in TProvidedTypeExtensionPoint '%s'" typeName (sty.PUntaint((fun sty -> sty.FullName), m)) -#endif - - match sty.PApply((fun sty -> sty.GetNestedType typeName), m) with - | Tainted.Null -> - //if staticResInfo.NumStaticArgs > 0 then - // error(Error(FSComp.SR.etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters(), m)) - [] - | nestedSty -> - [AddEntityForProvidedType (amap, modref, resolutionEnvironment, nestedSty, m) ] - | _ -> [] -#endif - -/// Lookup a type name in an entity. -let LookupTypeNameInEntityMaybeHaveArity (amap, m, ad, nm, staticResInfo: TypeNameResolutionStaticArgsInfo, modref: ModuleOrNamespaceRef) = - let mtyp = modref.ModuleOrNamespaceType - let tcrefs = - match staticResInfo with - | TypeNameResolutionStaticArgsInfo.Indefinite -> - LookupTypeNameInEntityNoArity m nm mtyp - |> List.map modref.NestedTyconRef - | TypeNameResolutionStaticArgsInfo.Definite _ -> - match LookupTypeNameInEntityHaveArity nm staticResInfo mtyp with - | Some tycon -> [modref.NestedTyconRef tycon] - | None -> [] -#if !NO_EXTENSIONTYPING - let tcrefs = - match tcrefs with - | [] -> ResolveProvidedTypeNameInEntity (amap, m, nm, modref) - | _ -> tcrefs -#else - amap |> ignore -#endif - let tcrefs = tcrefs |> List.filter (IsEntityAccessible amap m ad) - tcrefs - - -/// Make a type that refers to a nested type. -/// -/// Handle the .NET/C# business where nested generic types implicitly accumulate the type parameters -/// from their enclosing types. -let MakeNestedType (ncenv: NameResolver) (tinst: TType list) m (tcrefNested: TyconRef) = - let tps = List.drop tinst.Length (tcrefNested.Typars m) - let tinstNested = ncenv.InstantiationGenerator m tps - mkAppTy tcrefNested (tinst @ tinstNested) - -/// Get all the accessible nested types of an existing type. -let GetNestedTypesOfType (ad, ncenv: NameResolver, optFilter, staticResInfo, checkForGenerated, m) ty = - let g = ncenv.g - ncenv.InfoReader.GetPrimaryTypeHierarchy(AllowMultiIntfInstantiations.Yes, m, ty) |> List.collect (fun ty -> - match ty with - | AppTy g (tcref, tinst) -> - let tycon = tcref.Deref - let mty = tycon.ModuleOrNamespaceType - // No dotting through type generators to get to a nested type! -#if !NO_EXTENSIONTYPING - if checkForGenerated then - CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) -#else - checkForGenerated |> ignore -#endif - - match optFilter with - | Some nm -> - let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, m, ad, nm, staticResInfo, tcref) - tcrefs |> List.map (MakeNestedType ncenv tinst m) - | None -> -#if !NO_EXTENSIONTYPING - match tycon.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> - [ for nestedType in info.ProvidedType.PApplyArray((fun sty -> sty.GetNestedTypes()), "GetNestedTypes", m) do - let nestedTypeName = nestedType.PUntaint((fun t -> t.Name), m) - for nestedTcref in LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, m, ad, nestedTypeName, staticResInfo, tcref) do - yield MakeNestedType ncenv tinst m nestedTcref ] - - | _ -> -#endif - mty.TypesByAccessNames.Values - |> List.choose (fun entity -> - let ty = tcref.NestedTyconRef entity |> MakeNestedType ncenv tinst m - if IsTypeAccessible g ncenv.amap m ad ty then Some ty else None) - | _ -> []) - //------------------------------------------------------------------------- // Report environments to visual studio. We stuff intermediary results // into a global variable. A little unpleasant. @@ -1410,25 +1617,6 @@ type ItemOccurence = /// This is a usage of a module or namespace name in open statement | Open -type OpenDeclaration = - { LongId: Ident list - Range: range option - Modules: ModuleOrNamespaceRef list - AppliedScope: range - IsOwnNamespace: bool } - - static member Create(longId: Ident list, modules: ModuleOrNamespaceRef list, appliedScope: range, isOwnNamespace: bool) = - { LongId = longId - Range = - match longId with - | [] -> None - | first :: rest -> - let last = rest |> List.tryLast |> Option.defaultValue first - Some (mkRange appliedScope.FileName first.idRange.Start last.idRange.End) - Modules = modules - AppliedScope = appliedScope - IsOwnNamespace = isOwnNamespace } - type FormatStringCheckContext = { SourceText: ISourceText LineStartPositions: int[] } @@ -1436,8 +1624,9 @@ type FormatStringCheckContext = /// An abstract type for reporting the results of name resolution and type checking. type ITypecheckResultsSink = abstract NotifyEnvWithScope: range * NameResolutionEnv * AccessorDomain -> unit - abstract NotifyExprHasType: pos * TType * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit - abstract NotifyNameResolution: pos * item: Item * itemMethodGroup: Item * TyparInst * ItemOccurence * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit + abstract NotifyExprHasType: TType * NameResolutionEnv * AccessorDomain * range -> unit + abstract NotifyNameResolution: pos * item: Item * TyparInst * ItemOccurence * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit + abstract NotifyMethodGroupNameResolution : pos * item: Item * itemMethodGroup: Item * TyparInst * ItemOccurence * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit abstract NotifyFormatSpecifierLocation: range * int -> unit abstract NotifyOpenDeclaration: OpenDeclaration -> unit abstract CurrentSourceText: ISourceText option @@ -1449,10 +1638,15 @@ let (|ValRefOfEvent|_|) (evt: EventInfo) = evt.ArbitraryValRef let rec (|RecordFieldUse|_|) (item: Item) = match item with - | Item.RecdField(RecdFieldInfo(_, RFRef(tcref, name))) -> Some (name, tcref) + | Item.RecdField(RecdFieldInfo(_, RecdFieldRef(tcref, name))) -> Some (name, tcref) | Item.SetterArg(_, RecordFieldUse f) -> Some f | _ -> None +let (|UnionCaseFieldUse|_|) (item: Item) = + match item with + | Item.UnionCaseField (uci, fieldIndex) -> Some (fieldIndex, uci.UnionCaseRef) + | _ -> None + let rec (|ILFieldUse|_|) (item: Item) = match item with | Item.ILField finfo -> Some finfo @@ -1521,7 +1715,7 @@ let (|ValUse|_|) (item: Item) = let (|ActivePatternCaseUse|_|) (item: Item) = match item with - | Item.ActivePatternCase(APElemRef(_, vref, idx)) -> Some (vref.SigRange, vref.DefinitionRange, idx) + | Item.ActivePatternCase(APElemRef(_, vref, idx, _)) -> Some (vref.SigRange, vref.DefinitionRange, idx) | Item.ActivePatternResult(ap, _, idx, _) -> Some (ap.Range, ap.Range, idx) | _ -> None @@ -1532,10 +1726,10 @@ let tyconRefDefnEq g (eref1: EntityRef) (eref2: EntityRef) = tyconRefEq g eref1 eref2 || // Signature items considered equal to implementation items - not (Range.equals eref1.DefinitionRange Range.rangeStartup) && - not (Range.equals eref1.DefinitionRange Range.range0) && - not (Range.equals eref1.DefinitionRange Range.rangeCmdArgs) && - (Range.equals eref1.DefinitionRange eref2.DefinitionRange || Range.equals eref1.SigRange eref2.SigRange) && + not (equals eref1.DefinitionRange rangeStartup) && + not (equals eref1.DefinitionRange range0) && + not (equals eref1.DefinitionRange rangeCmdArgs) && + (equals eref1.DefinitionRange eref2.DefinitionRange || equals eref1.SigRange eref2.SigRange) && eref1.LogicalName = eref2.LogicalName let valRefDefnHash (_g: TcGlobals) (vref1: ValRef) = @@ -1545,10 +1739,10 @@ let valRefDefnEq g (vref1: ValRef) (vref2: ValRef) = valRefEq g vref1 vref2 || // Signature items considered equal to implementation items - not (Range.equals vref1.DefinitionRange Range.rangeStartup) && - not (Range.equals vref1.DefinitionRange Range.range0) && - not (Range.equals vref1.DefinitionRange Range.rangeCmdArgs) && - (Range.equals vref1.DefinitionRange vref2.DefinitionRange || Range.equals vref1.SigRange vref2.SigRange) && + not (equals vref1.DefinitionRange rangeStartup) && + not (equals vref1.DefinitionRange range0) && + not (equals vref1.DefinitionRange rangeCmdArgs) && + (equals vref1.DefinitionRange vref2.DefinitionRange || equals vref1.SigRange vref2.SigRange) && vref1.LogicalName = vref2.LogicalName let unionCaseRefDefnEq g (uc1: UnionCaseRef) (uc2: UnionCaseRef) = @@ -1567,7 +1761,7 @@ let ItemsAreEffectivelyEqual g orig other = | TType_var tp1, TType_var tp2 -> not tp1.IsCompilerGenerated && not tp1.IsFromError && not tp2.IsCompilerGenerated && not tp2.IsFromError && - Range.equals tp1.Range tp2.Range + equals tp1.Range tp2.Range | AbbrevOrAppTy tcref1, AbbrevOrAppTy tcref2 -> tyconRefDefnEq g tcref1 tcref2 | _ -> false) @@ -1576,7 +1770,7 @@ let ItemsAreEffectivelyEqual g orig other = valRefDefnEq g vref1 vref2 | ActivePatternCaseUse (range1, range1i, idx1), ActivePatternCaseUse (range2, range2i, idx2) -> - (idx1 = idx2) && (Range.equals range1 range2 || Range.equals range1i range2i) + (idx1 = idx2) && (equals range1 range2 || equals range1i range2i) | MethodUse minfo1, MethodUse minfo2 -> MethInfo.MethInfosUseIdenticalDefinitions minfo1 minfo2 || @@ -1593,12 +1787,12 @@ let ItemsAreEffectivelyEqual g orig other = | _ -> false | Item.ArgName (id1, _, _), Item.ArgName (id2, _, _) -> - (id1.idText = id2.idText && Range.equals id1.idRange id2.idRange) + (id1.idText = id2.idText && equals id1.idRange id2.idRange) - | (Item.ArgName (id, _, _), ValUse vref) | (ValUse vref, Item.ArgName (id, _, _)) -> - ((Range.equals id.idRange vref.DefinitionRange || Range.equals id.idRange vref.SigRange) && id.idText = vref.DisplayName) + | Item.ArgName (id, _, _), ValUse vref | ValUse vref, Item.ArgName (id, _, _) -> + ((equals id.idRange vref.DefinitionRange || equals id.idRange vref.SigRange) && id.idText = vref.DisplayName) - | Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> Tastops.anonInfoEquiv anon1 anon2 && i1 = i2 + | Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> anonInfoEquiv anon1 anon2 && i1 = i2 | ILFieldUse f1, ILFieldUse f2 -> ILFieldInfo.ILFieldInfosUseIdenticalDefinitions f1 f2 @@ -1609,6 +1803,9 @@ let ItemsAreEffectivelyEqual g orig other = | RecordFieldUse(name1, tcref1), RecordFieldUse(name2, tcref2) -> name1 = name2 && tyconRefDefnEq g tcref1 tcref2 + | UnionCaseFieldUse(fieldIndex1, ucref1), UnionCaseFieldUse(fieldIndex2, ucref2) -> + unionCaseRefDefnEq g ucref1 ucref2 && fieldIndex1 = fieldIndex2 + | EventUse evt1, EventUse evt2 -> EventInfo.EventInfosUseIdenticalDefinitions evt1 evt2 || // Allow for equality up to signature matching @@ -1634,27 +1831,28 @@ let ItemsAreEffectivelyEqualHash (g: TcGlobals) orig = | ILFieldUse ilfinfo -> ilfinfo.ComputeHashCode() | UnionCaseUse ucase -> hash ucase.CaseName | RecordFieldUse (name, _) -> hash name + | UnionCaseFieldUse (fieldIndex, case) -> hash (case.CaseName, fieldIndex) | EventUse einfo -> einfo.ComputeHashCode() | Item.ModuleOrNamespaces (mref :: _) -> hash mref.DefinitionRange | _ -> 389329 [] -type CapturedNameResolution(p: pos, i: Item, tpinst, io: ItemOccurence, de: DisplayEnv, nre: NameResolutionEnv, ad: AccessorDomain, m: range) = - member this.Pos = p +type CapturedNameResolution(i: Item, tpinst, io: ItemOccurence, nre: NameResolutionEnv, ad: AccessorDomain, m: range) = + member this.Pos = m.End member this.Item = i member this.ItemWithInst = ({ Item = i; TyparInst = tpinst } : ItemWithInst) member this.ItemOccurence = io - member this.DisplayEnv = de + member this.DisplayEnv = nre.DisplayEnv member this.NameResolutionEnv = nre member this.AccessorDomain = ad member this.Range = m member this.DebugToString() = - sprintf "%A: %+A" (p.Line, p.Column) i + sprintf "%A: %+A" (this.Pos.Line, this.Pos.Column) i /// Represents container for all name resolutions that were met so far when typechecking some particular file type TcResolutions (capturedEnvs: ResizeArray, - capturedExprTypes: ResizeArray, + capturedExprTypes: ResizeArray, capturedNameResolutions: ResizeArray, capturedMethodGroupResolutions: ResizeArray) = @@ -1669,7 +1867,7 @@ type TcResolutions [] type TcSymbolUseData = - { Item: Item + { ItemWithInst: ItemWithInst ItemOccurence: ItemOccurence DisplayEnv: DisplayEnv Range: range } @@ -1684,10 +1882,10 @@ type TcSymbolUses(g, capturedNameResolutions: ResizeArray ResizeArray.mapToSmallArrayChunks (fun cnr -> { Item=cnr.Item; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range }) + |> ResizeArray.mapToSmallArrayChunks (fun cnr -> { ItemWithInst=cnr.ItemWithInst; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range }) let capturedNameResolutions = () - do ignore capturedNameResolutions // don't capture this! + do capturedNameResolutions // don't capture this! member this.GetUsesOfSymbol item = // This member returns what is potentially a very large array, which may approach the size constraints of the Large Object Heap. @@ -1695,35 +1893,62 @@ type TcSymbolUses(g, capturedNameResolutions: ResizeArray ItemsAreEffectivelyEqual g item symbolUse.Item) then + if protectAssemblyExploration false (fun () -> ItemsAreEffectivelyEqual g item symbolUse.ItemWithInst.Item) then yield symbolUse |] member this.AllUsesOfSymbols = allUsesOfSymbols member this.GetFormatSpecifierLocationsAndArity() = formatSpecifierLocations + static member Empty = TcSymbolUses(Unchecked.defaultof<_>, ResizeArray(), Array.empty) + /// An accumulator for the results being emitted into the tcSink. -type TcResultsSinkImpl(g, ?sourceText: ISourceText) = +type TcResultsSinkImpl(tcGlobals, ?sourceText: ISourceText) = let capturedEnvs = ResizeArray<_>() let capturedExprTypings = ResizeArray<_>() - let capturedNameResolutions = ResizeArray<_>() + let capturedNameResolutions = ResizeArray() + let capturedMethodGroupResolutions = ResizeArray() + let capturedOpenDeclarations = ResizeArray() let capturedFormatSpecifierLocations = ResizeArray<_>() let capturedNameResolutionIdentifiers = - new System.Collections.Generic.HashSet + HashSet ( { new IEqualityComparer<_> with - member __.GetHashCode((p: pos, i)) = p.Line + 101 * p.Column + hash i - member __.Equals((p1, i1), (p2, i2)) = posEq p1 p2 && i1 = i2 } ) + member _.GetHashCode((p: pos, i)) = p.Line + 101 * p.Column + hash i + member _.Equals((p1, i1), (p2, i2)) = posEq p1 p2 && i1 = i2 } ) let capturedModulesAndNamespaces = - new System.Collections.Generic.HashSet + HashSet ( { new IEqualityComparer with - member __.GetHashCode ((m, _)) = hash m - member __.Equals ((m1, item1), (m2, item2)) = Range.equals m1 m2 && ItemsAreEffectivelyEqual g item1 item2 } ) + member _.GetHashCode ((m, _)) = hash m + member _.Equals ((m1, item1), (m2, item2)) = equals m1 m2 && ItemsAreEffectivelyEqual tcGlobals item1 item2 } ) - let capturedMethodGroupResolutions = ResizeArray<_>() - let capturedOpenDeclarations = ResizeArray() - let allowedRange (m: range) = not m.IsSynthetic + let allowedRange (m: range) = + not m.IsSynthetic + + let isAlreadyDone endPos item m = + // Desugaring some F# constructs (notably computation expressions with custom operators) + // results in duplication of textual variables. So we ensure we never record two name resolutions + // for the same identifier at the same location. + + match item with + | Item.ModuleOrNamespaces _ -> + not (capturedModulesAndNamespaces.Add (m, item)) + | _ -> + + let keyOpt = + match item with + | Item.Value vref -> Some (endPos, vref.DisplayName) + | Item.ArgName (id, _, _) -> Some (endPos, id.idText) + | _ -> None + + match keyOpt with + | Some key -> not (capturedNameResolutionIdentifiers.Add key) + | _ -> false + + let remove m = + capturedNameResolutions.RemoveAll(fun cnr -> equals cnr.Range m) |> ignore + capturedMethodGroupResolutions.RemoveAll(fun cnr -> equals cnr.Range m) |> ignore let formatStringCheckContext = lazy @@ -1745,47 +1970,37 @@ type TcResultsSinkImpl(g, ?sourceText: ISourceText) = TcResolutions(capturedEnvs, capturedExprTypings, capturedNameResolutions, capturedMethodGroupResolutions) member this.GetSymbolUses() = - TcSymbolUses(g, capturedNameResolutions, capturedFormatSpecifierLocations.ToArray()) + TcSymbolUses(tcGlobals, capturedNameResolutions, capturedFormatSpecifierLocations.ToArray()) member this.GetOpenDeclarations() = capturedOpenDeclarations |> Seq.distinctBy (fun x -> x.Range, x.AppliedScope, x.IsOwnNamespace) |> Seq.toArray + member this.GetFormatSpecifierLocations() = + capturedFormatSpecifierLocations.ToArray() + interface ITypecheckResultsSink with member sink.NotifyEnvWithScope(m, nenv, ad) = if allowedRange m then capturedEnvs.Add((m, nenv, ad)) - member sink.NotifyExprHasType(endPos, ty, denv, nenv, ad, m) = + member sink.NotifyExprHasType(ty, nenv, ad, m) = if allowedRange m then - capturedExprTypings.Add((endPos, ty, denv, nenv, ad, m)) + capturedExprTypings.Add((ty, nenv, ad, m)) - member sink.NotifyNameResolution(endPos, item, itemMethodGroup, tpinst, occurenceType, denv, nenv, ad, m, replace) = - // Desugaring some F# constructs (notably computation expressions with custom operators) - // results in duplication of textual variables. So we ensure we never record two name resolutions - // for the same identifier at the same location. + member sink.NotifyNameResolution(endPos, item, tpinst, occurenceType, nenv, ad, m, replace) = if allowedRange m then if replace then - capturedNameResolutions.RemoveAll(fun cnr -> Range.equals cnr.Range m) |> ignore - capturedMethodGroupResolutions.RemoveAll(fun cnr -> Range.equals cnr.Range m) |> ignore - else - let alreadyDone = - match item with - | Item.ModuleOrNamespaces _ -> - not (capturedModulesAndNamespaces.Add (m, item)) - | _ -> - let keyOpt = - match item with - | Item.Value vref -> Some (endPos, vref.DisplayName) - | Item.ArgName (id, _, _) -> Some (endPos, id.idText) - | _ -> None - - match keyOpt with - | Some key -> not (capturedNameResolutionIdentifiers.Add key) - | _ -> false + remove m + elif not (isAlreadyDone endPos item m) then + capturedNameResolutions.Add(CapturedNameResolution(item, tpinst, occurenceType, nenv, ad, m)) - if not alreadyDone then - capturedNameResolutions.Add(CapturedNameResolution(endPos, item, tpinst, occurenceType, denv, nenv, ad, m)) - capturedMethodGroupResolutions.Add(CapturedNameResolution(endPos, itemMethodGroup, [], occurenceType, denv, nenv, ad, m)) + member sink.NotifyMethodGroupNameResolution(endPos, item, itemMethodGroup, tpinst, occurenceType, nenv, ad, m, replace) = + if allowedRange m then + if replace then + remove m + elif not (isAlreadyDone endPos item m) then + capturedNameResolutions.Add(CapturedNameResolution(item, tpinst, occurenceType, nenv, ad, m)) + capturedMethodGroupResolutions.Add(CapturedNameResolution(itemMethodGroup, [], occurenceType, nenv, ad, m)) member sink.NotifyFormatSpecifierLocation(m, numArgs) = capturedFormatSpecifierLocations.Add((m, numArgs)) @@ -1824,21 +2039,26 @@ let CallEnvSink (sink: TcResultsSink) (scopem, nenv, ad) = | Some sink -> sink.NotifyEnvWithScope(scopem, nenv, ad) /// Report a specific name resolution at a source range -let CallNameResolutionSink (sink: TcResultsSink) (m: range, nenv, item, itemMethodGroup, tpinst, occurenceType, denv, ad) = +let CallNameResolutionSink (sink: TcResultsSink) (m: range, nenv, item, tpinst, occurenceType, ad) = match sink.CurrentSink with | None -> () - | Some sink -> sink.NotifyNameResolution(m.End, item, itemMethodGroup, tpinst, occurenceType, denv, nenv, ad, m, false) + | Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, false) -let CallNameResolutionSinkReplacing (sink: TcResultsSink) (m: range, nenv, item, itemMethodGroup, tpinst, occurenceType, denv, ad) = +let CallMethodGroupNameResolutionSink (sink: TcResultsSink) (m: range, nenv, item, itemMethodGroup, tpinst, occurenceType, ad) = match sink.CurrentSink with | None -> () - | Some sink -> sink.NotifyNameResolution(m.End, item, itemMethodGroup, tpinst, occurenceType, denv, nenv, ad, m, true) + | Some sink -> sink.NotifyMethodGroupNameResolution(m.End, item, itemMethodGroup, tpinst, occurenceType, nenv, ad, m, false) + +let CallNameResolutionSinkReplacing (sink: TcResultsSink) (m: range, nenv, item, tpinst, occurenceType, ad) = + match sink.CurrentSink with + | None -> () + | Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, true) /// Report a specific expression typing at a source range -let CallExprHasTypeSink (sink: TcResultsSink) (m: range, nenv, ty, denv, ad) = +let CallExprHasTypeSink (sink: TcResultsSink) (m: range, nenv, ty, ad) = match sink.CurrentSink with | None -> () - | Some sink -> sink.NotifyExprHasType(m.End, ty, denv, nenv, ad, m) + | Some sink -> sink.NotifyExprHasType(ty, nenv, ad, m) let CallOpenDeclarationSink (sink: TcResultsSink) (openDeclaration: OpenDeclaration) = match sink.CurrentSink with @@ -1893,6 +2113,7 @@ let CheckAllTyparsInferrable amap m item = | Item.UnionCase _ | Item.ExnCase _ | Item.RecdField _ + | Item.UnionCaseField _ | Item.AnonRecdField _ | Item.NewDef _ | Item.ILField _ @@ -1916,9 +2137,9 @@ let CheckAllTyparsInferrable amap m item = /// ultimately calls ResolutionInfo.Method to record it for /// later use by Visual Studio. type ResolutionInfo = - | ResolutionInfo of (*entityPath, reversed*)(range * EntityRef) list * (*warnings/errors*)(ResultTyparChecker -> unit) + | ResolutionInfo of (*entityPath, reversed*)(range * EntityRef) list * (*warnings/errors*)(ResultTyparChecker -> unit) * tinstEnclosing: EnclosingTypeInst - static member SendEntityPathToSink(sink, ncenv: NameResolver, nenv, occ, ad, ResolutionInfo(entityPath, warnings), typarChecker) = + static member SendEntityPathToSink(sink, ncenv: NameResolver, nenv, occ, ad, ResolutionInfo(entityPath, warnings, _), typarChecker) = entityPath |> List.iter (fun (m, eref: EntityRef) -> CheckEntityAttributes ncenv.g eref m |> CommitOperationResult CheckTyconAccessible ncenv.amap m ad eref |> ignore @@ -1927,21 +2148,27 @@ type ResolutionInfo = Item.ModuleOrNamespaces [eref] else Item.Types(eref.DisplayName, [FreshenTycon ncenv m eref]) - CallNameResolutionSink sink (m, nenv, item, item, emptyTyparInst, occ, nenv.eDisplayEnv, ad)) + CallNameResolutionSink sink (m, nenv, item, emptyTyparInst, occ, ad)) warnings typarChecker static member Empty = - ResolutionInfo([], (fun _ -> ())) + ResolutionInfo([], (fun _ -> ()), emptyEnclosingTypeInst) member x.AddEntity info = - let (ResolutionInfo(entityPath, warnings)) = x - ResolutionInfo(info :: entityPath, warnings) + let (ResolutionInfo(entityPath, warnings, tinstEnclosing)) = x + ResolutionInfo(info :: entityPath, warnings, tinstEnclosing) member x.AddWarning f = - let (ResolutionInfo(entityPath, warnings)) = x - ResolutionInfo(entityPath, (fun typarChecker -> f typarChecker; warnings typarChecker)) + let (ResolutionInfo(entityPath, warnings, tinstEnclosing)) = x + ResolutionInfo(entityPath, (fun typarChecker -> f typarChecker; warnings typarChecker), tinstEnclosing) + member x.WithEnclosingTypeInst tinstEnclosing = + let (ResolutionInfo(entityPath, warnings, _)) = x + ResolutionInfo(entityPath, warnings, tinstEnclosing) + member x.EnclosingTypeInst = + match x with + | ResolutionInfo(tinstEnclosing=tinstEnclosing) -> tinstEnclosing /// Resolve ambiguities between types overloaded by generic arity, based on number of type arguments. /// Also check that we're not returning direct references to generated provided types. @@ -1965,24 +2192,24 @@ let CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities // remove later duplicates (if we've opened the same module more than once) |> List.distinctBy (fun (_, tcref) -> tcref.Stamp) // List.sortBy is a STABLE sort (the order matters!) - |> List.sortBy (fun (_, tcref) -> tcref.Typars(m).Length) + |> List.sortBy (fun (resInfo, tcref) -> tcref.Typars(m).Length - resInfo.EnclosingTypeInst.Length) let tcrefs = match tcrefs with - | ((_resInfo, tcref) :: _) when + | (resInfo, tcref) :: _ when // multiple types tcrefs.Length > 1 && // no explicit type instantiation typeNameResInfo.StaticArgsInfo.HasNoStaticArgsInfo && // some type arguments required on all types (note sorted by typar count above) - not (List.isEmpty (tcref.Typars m)) && + ((tcref.Typars m).Length - resInfo.EnclosingTypeInst.Length) > 0 && // plausible types have different arities (tcrefs |> Seq.distinctBy (fun (_, tcref) -> tcref.Typars(m).Length) |> Seq.length > 1) -> - [ for (resInfo, tcref) in tcrefs do + [ for resInfo, tcref in tcrefs do let resInfo = resInfo.AddWarning (fun _typarChecker -> errorR(Error(FSComp.SR.nrTypeInstantiationNeededToDisambiguateTypesWithSameName(tcref.DisplayName, tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m))) yield (resInfo, tcref) ] - | [(resInfo, tcref)] when typeNameResInfo.StaticArgsInfo.HasNoStaticArgsInfo && not (List.isEmpty (tcref.Typars m)) && typeNameResInfo.ResolutionFlag = ResolveTypeNamesToTypeRefs -> + | [(resInfo, tcref)] when typeNameResInfo.StaticArgsInfo.HasNoStaticArgsInfo && ((tcref.Typars m).Length - resInfo.EnclosingTypeInst.Length) > 0 && typeNameResInfo.ResolutionFlag = ResolveTypeNamesToTypeRefs -> let resInfo = resInfo.AddWarning (fun (ResultTyparChecker typarChecker) -> if not (typarChecker()) then @@ -1993,7 +2220,7 @@ let CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities tcrefs #if !NO_EXTENSIONTYPING - for (_, tcref) in tcrefs do + for _, tcref in tcrefs do // Type generators can't be returned by name resolution, unless PermitDirectReferenceToGeneratedType.Yes CheckForDirectReferenceToGeneratedType (tcref, genOk, m) #else @@ -2004,108 +2231,91 @@ let CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities //------------------------------------------------------------------------- -// Consume ids that refer to a namespace +// Consume ids that refer to a namespace, module, or type //------------------------------------------------------------------------- -/// Perform name resolution for an identifier which must resolve to be a namespace or module. -let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: ResultCollectionSettings) (amap: Import.ImportMap) m allowStaticClasses first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl = - - // If the selected language version doesn't support open static classes then turn them off. - let allowStaticClasses = allowStaticClasses && amap.g.langVersion.SupportsFeature LanguageFeature.OpenStaticClasses +/// Perform name resolution for an identifier which must resolve to be a module or namespace. +let rec ResolveLongIdentAsModuleOrNamespace sink (atMostOne: ResultCollectionSettings) (amap: Import.ImportMap) m first fullyQualified (nenv: NameResolutionEnv) ad (id:Ident) (rest: Ident list) isOpenDecl = if first && id.idText = MangledGlobalName then match rest with | [] -> error (Error(FSComp.SR.nrGlobalUsedOnlyAsFirstName(), id.idRange)) | id2 :: rest2 -> - ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink atMostOne amap m allowStaticClasses false FullyQualified nenv ad id2 rest2 isOpenDecl + ResolveLongIdentAsModuleOrNamespace sink atMostOne amap m false FullyQualified nenv ad id2 rest2 isOpenDecl else - let moduleOrNamespaces = nenv.ModulesAndNamespaces fullyQualified - let namespaceNotFound = lazy( - let suggestModulesAndNamespaces (addToBuffer: string -> unit) = - for kv in moduleOrNamespaces do - for modref in kv.Value do - if IsEntityAccessible amap m ad modref then - addToBuffer modref.DisplayName - addToBuffer modref.DemangledModuleOrNamespaceName + let notFoundAux (id: Ident) depth error (tcrefs: TyconRef seq) = + let suggestNames (addToBuffer: string -> unit) = + for tcref in tcrefs do + if IsEntityAccessible amap m ad tcref then + addToBuffer tcref.DisplayName + + UndefinedName(depth, error, id, suggestNames) - UndefinedName(0, FSComp.SR.undefinedNameNamespaceOrModule, id, suggestModulesAndNamespaces)) + let moduleOrNamespaces = nenv.ModulesAndNamespaces fullyQualified + let namespaceNotFound = + lazy + seq { for kv in moduleOrNamespaces do + for modref in kv.Value do + modref } + |> notFoundAux id 0 FSComp.SR.undefinedNameNamespaceOrModule // Avoid generating the same error and name suggestion thunk twice It's not clear this is necessary // since it's just saving an allocation. let mutable moduleNotFoundErrorCache = None let moduleNotFound (modref: ModuleOrNamespaceRef) (mty: ModuleOrNamespaceType) (id: Ident) depth = match moduleNotFoundErrorCache with - | Some (oldId, error) when Range.equals oldId id.idRange -> error + | Some (oldId, error) when equals oldId id.idRange -> error | _ -> - let suggestNames (addToBuffer: string -> unit) = - for kv in mty.ModulesAndNamespacesByDemangledName do - if IsEntityAccessible amap m ad (modref.NestedTyconRef kv.Value) then - addToBuffer kv.Value.DisplayName - addToBuffer kv.Value.DemangledModuleOrNamespaceName - - let error = raze (UndefinedName(depth, FSComp.SR.undefinedNameNamespace, id, suggestNames)) + let error = + seq { for kv in mty.ModulesAndNamespacesByDemangledName do + modref.NestedTyconRef kv.Value } + |> notFoundAux id depth FSComp.SR.undefinedNameNamespace + let error = raze error moduleNotFoundErrorCache <- Some(id.idRange, error) error let notifyNameResolution (modref: ModuleOrNamespaceRef) m = let item = Item.ModuleOrNamespaces [modref] let occurence = if isOpenDecl then ItemOccurence.Open else ItemOccurence.Use - CallNameResolutionSink sink (m, nenv, item, item, emptyTyparInst, occurence, nenv.DisplayEnv, ad) - - let erefs = - let modrefs = - match moduleOrNamespaces.TryGetValue id.idText with - | true, modrefs -> modrefs - | _ -> [] - - let tcrefs = - if allowStaticClasses then - LookupTypeNameInEnvNoArity fullyQualified id.idText nenv |> List.filter (isStaticClass amap.g) - else [] + CallNameResolutionSink sink (m, nenv, item, emptyTyparInst, occurence, ad) - modrefs @ tcrefs + let modrefs = + match moduleOrNamespaces.TryGetValue id.idText with + | true, modrefs -> modrefs + | _ -> [] - if not erefs.IsEmpty then + if not modrefs.IsEmpty then /// Look through the sub-namespaces and/or modules - let rec look depth allowStaticClasses (modref: ModuleOrNamespaceRef) (lid: Ident list) = + let rec look depth (modref: ModuleOrNamespaceRef) (lid: Ident list) = let mty = modref.ModuleOrNamespaceType match lid with | [] -> success [ (depth, modref, mty) ] | id :: rest -> - let especs = - let mspecs = - match mty.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with - | true, res -> [res] - | _ -> [] - let tspecs = - if allowStaticClasses then - LookupTypeNameInEntityNoArity id.idRange id.idText mty - |> List.filter (modref.NestedTyconRef >> isStaticClass amap.g) - else [] - mspecs @ tspecs + let modrefs = + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, res -> [res] + | _ -> [] - if not especs.IsEmpty then - especs + if not modrefs.IsEmpty then + modrefs |> List.map (fun espec -> let subref = modref.NestedTyconRef espec if IsEntityAccessible amap m ad subref then notifyNameResolution subref id.idRange - let allowStaticClasses = allowStaticClasses && (subref.IsModuleOrNamespace || isStaticClass amap.g subref) - look (depth+1) allowStaticClasses subref rest + look (depth+1) subref rest else moduleNotFound modref mty id depth) |> List.reduce AddResults else moduleNotFound modref mty id depth - erefs - |> List.map (fun eref -> - if IsEntityAccessible amap m ad eref then - notifyNameResolution eref id.idRange - let allowStaticClasses = allowStaticClasses && (eref.IsModuleOrNamespace || isStaticClass amap.g eref) - look 1 allowStaticClasses eref rest + modrefs + |> List.map (fun modref -> + if IsEntityAccessible amap m ad modref then + notifyNameResolution modref id.idRange + look 1 modref rest else raze (namespaceNotFound.Force())) |> List.reduce AddResults @@ -2113,8 +2323,8 @@ let rec ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink (atMostOne: Resul raze (namespaceNotFound.Force()) // Note - 'rest' is annotated due to a bug currently in Unity (see: https://github.com/dotnet/fsharp/pull/7427) -let ResolveLongIndentAsModuleOrNamespaceThen sink atMostOne amap m fullyQualified (nenv: NameResolutionEnv) ad id (rest: Ident list) isOpenDecl f = - match ResolveLongIndentAsModuleOrNamespaceOrStaticClass sink ResultCollectionSettings.AllResults amap m false true fullyQualified nenv ad id [] isOpenDecl with +let ResolveLongIdentAsModuleOrNamespaceThen sink atMostOne amap m fullyQualified (nenv: NameResolutionEnv) ad id (rest: Ident list) isOpenDecl f = + match ResolveLongIdentAsModuleOrNamespace sink ResultCollectionSettings.AllResults amap m true fullyQualified nenv ad id [] isOpenDecl with | Result modrefs -> match rest with | [] -> error(Error(FSComp.SR.nrUnexpectedEmptyLongId(), id.idRange)) @@ -2194,10 +2404,10 @@ let TryFindAnonRecdFieldOfType g typ nm = | None -> None | ValueNone -> None -let CoreDisplayName(pinfo: PropInfo) = +let DisplayNameCoreMangled(pinfo: PropInfo) = match pinfo with - | FSProp(_, _, _, Some set) -> set.CoreDisplayName - | FSProp(_, _, Some get, _) -> get.CoreDisplayName + | FSProp(_, _, _, Some set) -> set.DisplayNameCoreMangled + | FSProp(_, _, Some get, _) -> get.DisplayNameCoreMangled | FSProp _ -> failwith "unexpected (property must have either getter or setter)" | ILProp(ILPropInfo(_, def)) -> def.Name #if !NO_EXTENSIONTYPING @@ -2207,7 +2417,7 @@ let CoreDisplayName(pinfo: PropInfo) = let DecodeFSharpEvent (pinfos: PropInfo list) ad g (ncenv: NameResolver) m = match pinfos with | [pinfo] when pinfo.IsFSharpEventProperty -> - let nm = CoreDisplayName pinfo + let nm = DisplayNameCoreMangled pinfo let minfos1 = GetImmediateIntrinsicMethInfosOfType (Some("add_"+nm), ad) g ncenv.amap m pinfo.ApparentEnclosingType let minfos2 = GetImmediateIntrinsicMethInfosOfType (Some("remove_"+nm), ad) g ncenv.amap m pinfo.ApparentEnclosingType match minfos1, minfos2 with @@ -2218,7 +2428,7 @@ let DecodeFSharpEvent (pinfos: PropInfo list) ad g (ncenv: NameResolver) m = // FOUND PROPERTY-AS-EVENT BUT DIDN'T FIND CORRESPONDING ADD/REMOVE METHODS Some(Item.Property (nm, pinfos)) | pinfo :: _ -> - let nm = CoreDisplayName pinfo + let nm = DisplayNameCoreMangled pinfo Some(Item.Property (nm, pinfos)) | _ -> None @@ -2233,6 +2443,13 @@ let GetRecordLabelsForType g nenv ty = result.Add k |> ignore result +/// Get the nested types of the given type and check the nested types based on the type name resolution info. +let CheckNestedTypesOfType (ncenv: NameResolver) (resInfo: ResolutionInfo) ad nm (typeNameResInfo: TypeNameResolutionInfo) m ty = + let tinstEnclosing, tcrefsNested = GetNestedTyconRefsOfType ncenv.InfoReader ncenv.amap (ad, Some nm, typeNameResInfo.StaticArgsInfo, true, m) ty + let tcrefsNested = tcrefsNested |> List.map (fun tcrefNested -> (resInfo, tcrefNested)) + let tcrefsNested = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefsNested, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, m) + tcrefsNested |> List.map (fun (_, tcrefNested) -> MakeNestedType ncenv tinstEnclosing m tcrefNested) + // REVIEW: this shows up on performance logs. Consider for example endless resolutions of "List.map" to // the empty set of results, or "x.Length" for a list or array type. This indicates it could be worth adding a cache here. let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad (id: Ident) (rest: Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) ty = @@ -2308,7 +2525,7 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf let nestedSearchAccessible = match rest with | [] -> - let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, typeNameResInfo.StaticArgsInfo, true, m) ty + let nestedTypes = CheckNestedTypesOfType ncenv resInfo ad nm typeNameResInfo m ty if isNil nestedTypes then NoResultsOrUsefulErrors else @@ -2320,7 +2537,7 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf | ResolveTypeNamesToTypeRefs -> OneSuccess (resInfo, Item.Types (nm, nestedTypes), rest) | id2 :: rest2 -> - let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, TypeNameResolutionStaticArgsInfo.Indefinite, true, m) ty + let nestedTypes = CheckNestedTypesOfType ncenv resInfo ad nm (TypeNameResolutionInfo.ResolveToTypeRefs TypeNameResolutionStaticArgsInfo.Indefinite) m ty ResolveLongIdentInNestedTypes ncenv nenv lookupKind resInfo (depth+1) id m ad id2 rest2 findFlag typeNameResInfo nestedTypes match nestedSearchAccessible with @@ -2345,18 +2562,31 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf match lookupKind with | LookupKind.Expr | LookupKind.Pattern -> - if isAppTy g ty then - let tcref = tcrefOfAppTy g ty + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> for uc in tcref.UnionCasesArray do addToBuffer uc.DisplayName + | _ -> () | _ -> () - raze (UndefinedName (depth, FSComp.SR.undefinedNameFieldConstructorOrMember, id, suggestMembers)) + let errorTextF s = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + FSComp.SR.undefinedNameFieldConstructorOrMemberWhenTypeIsKnown(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars, s) + | _ -> + FSComp.SR.undefinedNameFieldConstructorOrMember(s) + + raze (UndefinedName (depth, errorTextF, id, suggestMembers)) and ResolveLongIdentInNestedTypes (ncenv: NameResolver) nenv lookupKind resInfo depth id m ad (id2: Ident) (rest: Ident list) findFlag typeNameResInfo tys = tys |> CollectAtMostOneResult (fun ty -> - let resInfo = if isAppTy ncenv.g ty then resInfo.AddEntity(id.idRange, tcrefOfAppTy ncenv.g ty) else resInfo + let resInfo = + match tryTcrefOfAppTy ncenv.g ty with + | ValueSome tcref -> + resInfo.AddEntity(id.idRange, tcref) + | _ -> + resInfo ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id2 rest findFlag typeNameResInfo ty |> AtMostOneResult m) @@ -2370,12 +2600,15 @@ let ResolveLongIdentInType sink ncenv nenv lookupKind m ad id findFlag typeNameR ResolutionInfo.SendEntityPathToSink (sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) item, rest -let private ResolveLongIdentInTyconRef (ncenv: NameResolver) nenv lookupKind resInfo depth m ad id rest typeNameResInfo tcref = +let private ResolveLongIdentInTyconRef (ncenv: NameResolver) nenv lookupKind (resInfo: ResolutionInfo) depth m ad id rest typeNameResInfo tcref = #if !NO_EXTENSIONTYPING // No dotting through type generators to get to a member! CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) #endif - let ty = FreshenTycon ncenv m tcref + let ty = + match resInfo.EnclosingTypeInst with + | [] -> FreshenTycon ncenv m tcref + | tinstEnclosing -> FreshenTyconWithEnclosingTypeInst ncenv m tinstEnclosing tcref ty |> ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad id rest IgnoreOverrides typeNameResInfo let private ResolveLongIdentInTyconRefs atMostOne (ncenv: NameResolver) nenv lookupKind depth m ad id rest typeNameResInfo idRange tcrefs = @@ -2426,7 +2659,7 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv (type | id2 :: rest2 -> let tcrefs = - let typeNameResInfo = TypeNameResolutionInfo (ResolveTypeNamesToTypeRefs, TypeNameResolutionStaticArgsInfo.Indefinite) + let typeNameResInfo = TypeNameResolutionInfo.ResolveToTypeRefs typeNameResInfo.StaticArgsInfo CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv LookupKind.Expr (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs @@ -2436,7 +2669,7 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv (type let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) match typeNameResInfo.ResolutionFlag with | ResolveTypeNamesToTypeRefs -> - success [ for (resInfo, tcref) in tcrefs do + success [ for resInfo, tcref in tcrefs do let ty = FreshenTycon ncenv m tcref let item = (resInfo, Item.Types(id.idText, [ty]), []) yield item ] @@ -2491,24 +2724,43 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv (type /// An identifier has resolved to a type name in an expression (corresponding to one or more TyconRefs). /// Return either a set of constructors (later refined by overload resolution), or a set of TyconRefs. -let ChooseTyconRefInExpr (ncenv: NameResolver, m, ad, nenv, id: Ident, typeNameResInfo: TypeNameResolutionInfo, resInfo: ResolutionInfo, tcrefs) = - let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo, tcref)) +let ChooseTyconRefInExpr (ncenv: NameResolver, m, ad, nenv, id: Ident, typeNameResInfo: TypeNameResolutionInfo, tcrefs) = let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, m) + + let tys = + tcrefs + |> List.map (fun (resInfo, tcref) -> + match resInfo.EnclosingTypeInst with + | [] -> + (resInfo, FreshenTycon ncenv m tcref) + | tinstEnclosing -> + (resInfo, FreshenTyconWithEnclosingTypeInst ncenv m tinstEnclosing tcref)) + match typeNameResInfo.ResolutionFlag with | ResolveTypeNamesToCtors -> - let tys = tcrefs |> List.map (fun (resInfo, tcref) -> (resInfo, FreshenTycon ncenv m tcref)) tys - |> CollectAtMostOneResult (fun (resInfo, ty) -> ResolveObjectConstructorPrim ncenv nenv.eDisplayEnv resInfo id.idRange ad ty) - |> MapResults (fun (resInfo, item) -> (resInfo, item, [])) + |> CollectAtMostOneResult (fun (resInfo, ty) -> ResolveObjectConstructorPrim ncenv nenv.eDisplayEnv resInfo id.idRange ad ty) + |> MapResults Operators.id | ResolveTypeNamesToTypeRefs -> - let tys = tcrefs |> List.map (fun (resInfo, tcref) -> (resInfo, FreshenTycon ncenv m tcref)) - success (tys |> List.map (fun (resInfo, ty) -> (resInfo, Item.Types(id.idText, [ty]), []))) + success (tys |> List.map (fun (resInfo, ty) -> (resInfo, Item.Types(id.idText, [ty])))) + +/// Resolves the given tycons. +/// For each tycon, return resolution info that could contain enclosing type instantations. +let ResolveUnqualifiedTyconRefs nenv tcrefs = + let resInfo = ResolutionInfo.Empty + + tcrefs + |> List.map (fun tcref -> + match nenv.eUnqualifiedEnclosingTypeInsts.TryFind tcref with + | None -> + (resInfo, tcref) + | Some tinst -> + (resInfo.WithEnclosingTypeInst tinst, tcref)) /// Resolve F# "A.B.C" syntax in expressions /// Not all of the sequence will necessarily be swallowed, i.e. we return some identifiers /// that may represent further actions, e.g. further lookups. let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified m ad nenv (typeNameResInfo: TypeNameResolutionInfo) (id: Ident) (rest: Ident list) isOpenDecl = - let resInfo = ResolutionInfo.Empty let canSuggestThisItem (item:Item) = // All items can be suggested except nameof when it comes from FSharp.Core.dll and the nameof feature is not enabled match item with @@ -2521,7 +2773,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified if first && id.idText = MangledGlobalName then match rest with | [] -> - error (Error(FSComp.SR.nrGlobalUsedOnlyAsFirstName(), id.idRange)) + raze (Error(FSComp.SR.nrGlobalUsedOnlyAsFirstName(), id.idRange)) | [next] -> ResolveExprLongIdentPrim sink ncenv false fullyQualified m ad nenv typeNameResInfo next [] isOpenDecl | id2 :: rest2 -> @@ -2539,52 +2791,57 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified // Do not use type names from the environment if an explicit type instantiation is // given and the number of type parameters do not match let tcrefs = - tcrefs |> List.filter (fun tcref -> + tcrefs + |> ResolveUnqualifiedTyconRefs nenv + |> List.filter (fun (resInfo, tcref) -> typeNameResInfo.StaticArgsInfo.HasNoStaticArgsInfo || - typeNameResInfo.StaticArgsInfo.NumStaticArgs = tcref.Typars(m).Length) + typeNameResInfo.StaticArgsInfo.NumStaticArgs = tcref.Typars(m).Length - resInfo.EnclosingTypeInst.Length) - let search = ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, resInfo, tcrefs) + let search = ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, tcrefs) match AtMostOneResult m search with - | Result _ as res -> - let resInfo, item, rest = ForceRaise res + | Result (resInfo, item) -> ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) - Some(item, rest) - | Exception e -> typeError <- Some e; None + Some(resInfo.EnclosingTypeInst, item, rest) + | Exception e -> + typeError <- Some e + None | true, res -> - let fresh = FreshenUnqualifiedItem ncenv m res + let fresh = ResolveUnqualifiedItem ncenv nenv m res match fresh with | Item.Value value -> let isNameOfOperator = valRefEq ncenv.g ncenv.g.nameof_vref value - if isNameOfOperator && not (ncenv.languageSupportsNameOf) then + if isNameOfOperator && not ncenv.languageSupportsNameOf then // Do not resolve `nameof` if the feature is unsupported, even if it is FSharp.Core None else - Some (fresh, []) - | _ -> Some (fresh, []) + Some (emptyEnclosingTypeInst, fresh, rest) + | _ -> Some (emptyEnclosingTypeInst, fresh, rest) | _ -> None match envSearch with - | Some res -> res + | Some res -> success res | None -> let innerSearch = // Check if it's a type name, e.g. a constructor call or a type instantiation let ctorSearch = - let tcrefs = LookupTypeNameInEnvMaybeHaveArity fullyQualified id.idText typeNameResInfo nenv - ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, resInfo, tcrefs) + let tcrefs = + LookupTypeNameInEnvMaybeHaveArity fullyQualified id.idText typeNameResInfo nenv + |> ResolveUnqualifiedTyconRefs nenv + ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, tcrefs) let implicitOpSearch() = if IsMangledOpName id.idText then - success [(resInfo, Item.ImplicitOp(id, ref None), [])] + success [(ResolutionInfo.Empty, Item.ImplicitOp(id, ref None))] else NoResultsOrUsefulErrors ctorSearch +++ implicitOpSearch - let resInfo, item, rest = + let res = match AtMostOneResult m innerSearch with - | Result _ as res -> ForceRaise res + | Result _ as res -> res | _ -> let failingCase = match typeError with @@ -2603,21 +2860,21 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified for modref in kv.Value do if IsEntityAccessible ncenv.amap m ad modref then addToBuffer modref.DisplayName - addToBuffer modref.DemangledModuleOrNamespaceName // check if the user forgot to use qualified access for e in nenv.eTyconsByDemangledNameAndArity do let hasRequireQualifiedAccessAttribute = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute e.Value.Attribs if hasRequireQualifiedAccessAttribute then - if e.Value.IsUnionTycon && e.Value.UnionCasesArray |> Array.exists (fun c -> c.DisplayName = id.idText) then + if e.Value.IsUnionTycon && e.Value.UnionCasesArray |> Array.exists (fun c -> c.LogicalName = id.idText) then addToBuffer (e.Value.DisplayName + "." + id.idText) raze (UndefinedName(0, FSComp.SR.undefinedNameValueOfConstructor, id, suggestNamesAndTypes)) - ForceRaise failingCase - + failingCase + match res with + | Exception e -> raze e + | Result (resInfo, item) -> ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) - item, rest - + success (resInfo.EnclosingTypeInst, item, rest) // A compound identifier. // It still might be a value in the environment, or something in an F# module, namespace, type, or nested type @@ -2635,83 +2892,83 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified | _ -> false if ValIsInEnv id.idText then - nenv.eUnqualifiedItems.[id.idText], rest + success (emptyEnclosingTypeInst, nenv.eUnqualifiedItems.[id.idText], rest) else // Otherwise modules are searched first. REVIEW: modules and types should be searched together. // For each module referenced by 'id', search the module as if it were an F# module and/or a .NET namespace. let moduleSearch ad () = - ResolveLongIndentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m fullyQualified nenv ad id rest isOpenDecl - (ResolveExprLongIdentInModuleOrNamespace ncenv nenv typeNameResInfo ad) + ResolveLongIdentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m fullyQualified nenv ad id rest isOpenDecl + (ResolveExprLongIdentInModuleOrNamespace ncenv nenv typeNameResInfo ad) // REVIEW: somewhat surprisingly, this shows up on performance traces, with tcrefs non-nil. // This seems strange since we would expect in the vast majority of cases tcrefs is empty here. let tyconSearch ad () = let tcrefs = LookupTypeNameInEnvNoArity fullyQualified id.idText nenv + if isNil tcrefs then NoResultsOrUsefulErrors else match rest with | id2 :: rest2 -> - let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo, tcref)) + let tcrefs = ResolveUnqualifiedTyconRefs nenv tcrefs let tcrefs = - let typeNameResInfo = TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.Indefinite) + let typeNameResInfo = TypeNameResolutionInfo.ResolveToTypeRefs typeNameResInfo.StaticArgsInfo CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) ResolveLongIdentInTyconRefs ResultCollectionSettings.AtMostOneResult ncenv nenv LookupKind.Expr 1 m ad id2 rest2 typeNameResInfo id.idRange tcrefs | _ -> NoResultsOrUsefulErrors let search = - let envSearch () = - match fullyQualified with - | FullyQualified -> - NoResultsOrUsefulErrors - | OpenQualified -> - match nenv.eUnqualifiedItems.TryGetValue id.idText with - | true, Item.UnqualifiedType _ - | false, _ -> NoResultsOrUsefulErrors - | true, res -> OneSuccess (resInfo, FreshenUnqualifiedItem ncenv m res, rest) - - moduleSearch ad () +++ tyconSearch ad +++ envSearch - - let resInfo, item, rest = + let envSearch () = + match fullyQualified with + | FullyQualified -> + NoResultsOrUsefulErrors + | OpenQualified -> + match nenv.eUnqualifiedItems.TryGetValue id.idText with + | true, Item.UnqualifiedType _ + | false, _ -> NoResultsOrUsefulErrors + | true, res -> OneSuccess (ResolutionInfo.Empty, ResolveUnqualifiedItem ncenv nenv m res, rest) + + moduleSearch ad () +++ tyconSearch ad +++ envSearch + + let res = match AtMostOneResult m search with - | Result _ as res -> ForceRaise res + | Result _ as res -> res | _ -> let innerSearch = search +++ (moduleSearch AccessibleFromSomeFSharpCode) +++ (tyconSearch AccessibleFromSomeFSharpCode) let suggestEverythingInScope (addToBuffer: string -> unit) = - for kv in nenv.ModulesAndNamespaces fullyQualified do - for modref in kv.Value do - if IsEntityAccessible ncenv.amap m ad modref then - addToBuffer modref.DisplayName - addToBuffer modref.DemangledModuleOrNamespaceName + for (KeyValue(_,modrefs)) in nenv.ModulesAndNamespaces fullyQualified do + for modref in modrefs do + if IsEntityAccessible ncenv.amap m ad modref then + addToBuffer modref.DisplayName - for e in nenv.TyconsByDemangledNameAndArity fullyQualified do - if IsEntityAccessible ncenv.amap m ad e.Value then - addToBuffer e.Value.DisplayName + for (KeyValue(_,tcref)) in nenv.TyconsByDemangledNameAndArity fullyQualified do + if IsEntityAccessible ncenv.amap m ad tcref then + addToBuffer tcref.DisplayName - for e in nenv.eUnqualifiedItems do - if canSuggestThisItem e.Value then - addToBuffer e.Value.DisplayName + for (KeyValue(_,item)) in nenv.eUnqualifiedItems do + if canSuggestThisItem item then + addToBuffer item.DisplayName match innerSearch with - | Exception (UndefinedName(0, _, id1, suggestionsF)) when Range.equals id.idRange id1.idRange -> - let mergeSuggestions addToBuffer = - suggestionsF addToBuffer - suggestEverythingInScope addToBuffer - - let failingCase = raze (UndefinedName(0, FSComp.SR.undefinedNameValueNamespaceTypeOrModule, id, mergeSuggestions)) - ForceRaise failingCase - | Exception err -> ForceRaise(Exception err) - | Result (res :: _) -> ForceRaise(Result res) + | Exception (UndefinedName(0, _, id1, suggestionsF)) when equals id.idRange id1.idRange -> + let mergeSuggestions addToBuffer = + suggestionsF addToBuffer + suggestEverythingInScope addToBuffer + raze (UndefinedName(0, FSComp.SR.undefinedNameValueNamespaceTypeOrModule, id, mergeSuggestions)) + | Exception err -> raze err + | Result (res :: _) -> success res | Result [] -> - let failingCase = raze (UndefinedName(0, FSComp.SR.undefinedNameValueNamespaceTypeOrModule, id, suggestEverythingInScope)) - ForceRaise failingCase + raze (UndefinedName(0, FSComp.SR.undefinedNameValueNamespaceTypeOrModule, id, suggestEverythingInScope)) - ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) - item, rest + match res with + | Exception e -> raze e + | Result (resInfo, item, rest) -> + ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) + success (resInfo.EnclosingTypeInst, item, rest) let ResolveExprLongIdent sink (ncenv: NameResolver) m ad nenv typeNameResInfo lid = match lid with - | [] -> error (Error(FSComp.SR.nrInvalidExpression(textOfLid lid), m)) + | [] -> raze (Error(FSComp.SR.nrInvalidExpression(textOfLid lid), m)) | id :: rest -> ResolveExprLongIdentPrim sink ncenv true OpenQualified m ad nenv typeNameResInfo id rest false //------------------------------------------------------------------------- @@ -2733,8 +2990,8 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv nu success (resInfo, Item.ExnCase (modref.NestedTyconRef exnc), rest) | _ -> // An active pattern constructor in a module - match (ActivePatternElemsOfModuleOrNamespace modref).TryGetValue id.idText with - | true, (APElemRef(_, vref, _) as apref) when IsValAccessible ad vref -> + match (ActivePatternElemsOfModuleOrNamespace ncenv.g modref).TryGetValue id.idText with + | true, (APElemRef(_, vref, _, _) as apref) when IsValAccessible ad vref -> success (resInfo, Item.ActivePatternCase apref, rest) | _ -> match mty.AllValsByLogicalName.TryGetValue id.idText with @@ -2782,7 +3039,6 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv nu for kv in mty.ModulesAndNamespacesByDemangledName do if IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef kv.Value) then addToBuffer kv.Value.DisplayName - addToBuffer kv.Value.DemangledModuleOrNamespaceName for e in nenv.TyconsByDemangledNameAndArity FullyQualifiedFlag.OpenQualified do if IsEntityAccessible ncenv.amap m ad e.Value then @@ -2812,7 +3068,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa // For the special case of // let C = x match nenv.ePatItems.TryGetValue id.idText with - | true, res when not newDef -> FreshenUnqualifiedItem ncenv m res + | true, res when not newDef -> ResolveUnqualifiedItem ncenv nenv m res | _ -> // Single identifiers in patterns - variable bindings if not newDef && @@ -2825,7 +3081,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa // Long identifiers in patterns else let moduleSearch ad () = - ResolveLongIndentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m fullyQualified nenv ad id rest false + ResolveLongIdentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m fullyQualified nenv ad id rest false (ResolvePatternLongIdentInModuleOrNamespace ncenv nenv numTyArgsOpt ad) let tyconSearch ad = @@ -2871,8 +3127,10 @@ let ResolvePatternLongIdent sink (ncenv: NameResolver) warnOnUpper newDef m ad n // X.ListEnumerator // does not resolve // let ResolveNestedTypeThroughAbbreviation (ncenv: NameResolver) (tcref: TyconRef) m = - if tcref.IsTypeAbbrev && tcref.Typars(m).IsEmpty && isAppTy ncenv.g tcref.TypeAbbrev.Value && isNil (argsOfAppTy ncenv.g tcref.TypeAbbrev.Value) then - tcrefOfAppTy ncenv.g tcref.TypeAbbrev.Value + if tcref.IsTypeAbbrev && tcref.Typars(m).IsEmpty then + match tryAppTy ncenv.g tcref.TypeAbbrev.Value with + | ValueSome (abbrevTcref, []) -> abbrevTcref + | _ -> tcref else tcref @@ -2893,7 +3151,7 @@ let rec ResolveTypeLongIdentInTyconRefPrim (ncenv: NameResolver) (typeNameResInf | tcref :: _ -> success tcref | [] -> let suggestTypes (addToBuffer: string -> unit) = - for e in tcref.ModuleOrNamespaceType.TypesByDemangledNameAndArity id.idRange do + for e in tcref.ModuleOrNamespaceType.TypesByDemangledNameAndArity do addToBuffer e.Value.DisplayName raze (UndefinedName(depth, FSComp.SR.undefinedNameType, id, suggestTypes)) @@ -2908,12 +3166,12 @@ let rec ResolveTypeLongIdentInTyconRefPrim (ncenv: NameResolver) (typeNameResInf let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, TypeNameResolutionStaticArgsInfo.Indefinite, tcref) if isNil tcrefs then NoResultsOrUsefulErrors else let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo, tcref)) - let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo.DropStaticArgsInfo, genOk, m) + let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, m) match tcrefs with | _ :: _ -> tcrefs |> CollectAtMostOneResult (fun (resInfo, tcref) -> ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad resInfo genOk (depth+1) m tcref id2 rest2) | [] -> let suggestTypes (addToBuffer: string -> unit) = - for e in tcref.ModuleOrNamespaceType.TypesByDemangledNameAndArity id.idRange do + for e in tcref.ModuleOrNamespaceType.TypesByDemangledNameAndArity do addToBuffer e.Value.DisplayName raze (UndefinedName(depth, FSComp.SR.undefinedNameType, id, suggestTypes)) @@ -2930,7 +3188,7 @@ let ResolveTypeLongIdentInTyconRef sink (ncenv: NameResolver) nenv typeNameResIn ForceRaise (ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad ResolutionInfo.Empty PermitDirectReferenceToGeneratedType.No 0 m tcref id rest) ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.Use, ad, resInfo, ResultTyparChecker(fun () -> true)) let item = Item.Types(tcref.DisplayName, [FreshenTycon ncenv m tcref]) - CallNameResolutionSink sink (rangeOfLid lid, nenv, item, item, emptyTyparInst, ItemOccurence.UseInType, nenv.eDisplayEnv, ad) + CallNameResolutionSink sink (rangeOfLid lid, nenv, item, emptyTyparInst, ItemOccurence.UseInType, ad) tcref /// Create an UndefinedName error with details @@ -2939,7 +3197,6 @@ let SuggestTypeLongIdentInModuleOrNamespace depth (modref: ModuleOrNamespaceRef) for e in modref.ModuleOrNamespaceType.AllEntities do if IsEntityAccessible amap m ad (modref.NestedTyconRef e) then addToBuffer e.DisplayName - addToBuffer e.DemangledModuleOrNamespaceName let errorTextF s = FSComp.SR.undefinedNameTypeIn(s, fullDisplayTextOfModRef modref) UndefinedName(depth, errorTextF, id, suggestPossibleTypes) @@ -2959,7 +3216,7 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace sink nenv (ncenv: NameRe match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with | true, AccessibleEntityRef ncenv.amap m ad modref submodref -> let item = Item.ModuleOrNamespaces [submodref] - CallNameResolutionSink sink (id.idRange, nenv, item, item, emptyTyparInst, ItemOccurence.Use, nenv.DisplayEnv, ad) + CallNameResolutionSink sink (id.idRange, nenv, item, emptyTyparInst, ItemOccurence.Use, ad) let resInfo = resInfo.AddEntity(id.idRange, submodref) ResolveTypeLongIdentInModuleOrNamespace sink nenv ncenv typeNameResInfo ad genOk resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType id2 rest2 | _ -> @@ -2967,7 +3224,6 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace sink nenv (ncenv: NameRe for kv in modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName do if IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef kv.Value) then addToBuffer kv.Value.DisplayName - addToBuffer kv.Value.DemangledModuleOrNamespaceName raze (UndefinedName(depth, FSComp.SR.undefinedNameNamespaceOrModule, id, suggestPossibleModules)) @@ -2977,7 +3233,7 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace sink nenv (ncenv: NameRe | _ :: _ -> tcrefs |> CollectResults (fun tcref -> ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad resInfo genOk (depth+1) m tcref id2 rest2) | [] -> let suggestTypes (addToBuffer: string -> unit) = - for e in modref.ModuleOrNamespaceType.TypesByDemangledNameAndArity id.idRange do + for e in modref.ModuleOrNamespaceType.TypesByDemangledNameAndArity do addToBuffer e.Value.DisplayName raze (UndefinedName(depth, FSComp.SR.undefinedNameType, id, suggestTypes)) @@ -2998,7 +3254,15 @@ let rec ResolveTypeLongIdentPrim sink (ncenv: NameResolver) occurence first full | [] -> match LookupTypeNameInEnvHaveArity fullyQualified id.idText staticResInfo.NumStaticArgs nenv with | Some res -> - let res = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities ([(ResolutionInfo.Empty, res)], typeNameResInfo, genOk, unionRanges m id.idRange) + let resInfo = + match fullyQualified with + | OpenQualified -> + match nenv.eUnqualifiedEnclosingTypeInsts.TryFind res with + | Some tinst -> ResolutionInfo.Empty.WithEnclosingTypeInst tinst + | _ -> ResolutionInfo.Empty + | _ -> + ResolutionInfo.Empty + let res = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities ([(resInfo, res)], typeNameResInfo, genOk, unionRanges m id.idRange) assert (res.Length = 1) success res.Head | None -> @@ -3014,7 +3278,6 @@ let rec ResolveTypeLongIdentPrim sink (ncenv: NameResolver) occurence first full for kv in nenv.TyconsByDemangledNameAndArity fullyQualified do if IsEntityAccessible ncenv.amap m ad kv.Value then addToBuffer kv.Value.DisplayName - addToBuffer kv.Value.DemangledModuleOrNamespaceName match occurence with | ItemOccurence.UseInAttribute -> if kv.Value.DisplayName.EndsWithOrdinal("Attribute") then @@ -3029,20 +3292,24 @@ let rec ResolveTypeLongIdentPrim sink (ncenv: NameResolver) occurence first full | FullyQualified -> NoResultsOrUsefulErrors | OpenQualified -> - match LookupTypeNameInEnvHaveArity fullyQualified id.idText staticResInfo.NumStaticArgs nenv with + match LookupTypeNameInEnvHaveArity fullyQualified id.idText 0 nenv with | Some tcref when IsEntityAccessible ncenv.amap m2 ad tcref -> let resInfo = ResolutionInfo.Empty.AddEntity(id.idRange, tcref) + let resInfo = + match nenv.eUnqualifiedEnclosingTypeInsts.TryFind tcref with + | Some tinstEnclosing -> resInfo.WithEnclosingTypeInst tinstEnclosing + | _ -> resInfo OneResult (ResolveTypeLongIdentInTyconRefPrim ncenv typeNameResInfo ad resInfo genOk 1 m2 tcref id2 rest2) | _ -> NoResultsOrUsefulErrors let modulSearch = - ResolveLongIndentAsModuleOrNamespaceThen sink ResultCollectionSettings.AllResults ncenv.amap m2 fullyQualified nenv ad id rest false + ResolveLongIdentAsModuleOrNamespaceThen sink ResultCollectionSettings.AllResults ncenv.amap m2 fullyQualified nenv ad id rest false (ResolveTypeLongIdentInModuleOrNamespace sink nenv ncenv typeNameResInfo ad genOk) |?> List.concat let modulSearchFailed() = - ResolveLongIndentAsModuleOrNamespaceThen sink ResultCollectionSettings.AllResults ncenv.amap m2 fullyQualified nenv AccessibleFromSomeFSharpCode id rest false + ResolveLongIdentAsModuleOrNamespaceThen sink ResultCollectionSettings.AllResults ncenv.amap m2 fullyQualified nenv AccessibleFromSomeFSharpCode id rest false (ResolveTypeLongIdentInModuleOrNamespace sink nenv ncenv typeNameResInfo.DropStaticArgsInfo AccessibleFromSomeFSharpCode genOk) |?> List.concat @@ -3068,7 +3335,7 @@ let rec ResolveTypeLongIdentPrim sink (ncenv: NameResolver) occurence first full /// Resolve a long identifier representing a type and report it -let ResolveTypeLongIdent sink (ncenv: NameResolver) occurence fullyQualified nenv ad (lid: Ident list) staticResInfo genOk = +let ResolveTypeLongIdentAux sink (ncenv: NameResolver) occurence fullyQualified nenv ad (lid: Ident list) staticResInfo genOk = let m = rangeOfLid lid let res = match lid with @@ -3082,9 +3349,14 @@ let ResolveTypeLongIdent sink (ncenv: NameResolver) occurence fullyQualified nen | Result (resInfo, tcref) -> ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, ResultTyparChecker(fun () -> true)) let item = Item.Types(tcref.DisplayName, [FreshenTycon ncenv m tcref]) - CallNameResolutionSink sink (m, nenv, item, item, emptyTyparInst, occurence, nenv.eDisplayEnv, ad) + CallNameResolutionSink sink (m, nenv, item, emptyTyparInst, occurence, ad) | _ -> () - res |?> snd + res + +/// Resolve a long identifier representing a type and report it +let ResolveTypeLongIdent sink ncenv occurence fullyQualified nenv ad lid staticResInfo genOk = + let res = ResolveTypeLongIdentAux sink ncenv occurence fullyQualified nenv ad lid staticResInfo genOk + (res |?> fun (resInfo, tcref) -> (resInfo.EnclosingTypeInst, tcref)) //------------------------------------------------------------------------- // Resolve F#/IL "." syntax in records etc. @@ -3099,7 +3371,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv: NameResolver) nenv ad (resInfo: match TryFindTypeWithRecdField modref id with | Some tycon when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef tycon) -> let showDeprecated = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs - success [resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id, showDeprecated), rest] + success [resInfo, FieldResolution(FreshenRecdFieldRef ncenv m (modref.RecdFieldRefInNestedTycon tycon id), showDeprecated), rest] | _ -> raze (UndefinedName(depth, FSComp.SR.undefinedNameRecordLabelOrNamespace, id, NoSuggestions)) // search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 } @@ -3111,7 +3383,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv: NameResolver) nenv ad (resInfo: let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField (depth+1) m ad id2 rest2 typeNameResInfo id.idRange tcrefs // choose only fields - let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(rfref, false), rest) | _ -> None) + let tyconSearch = tyconSearch |?> List.choose (function resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch | _ -> NoResultsOrUsefulErrors @@ -3183,7 +3455,7 @@ let SuggestLabelsOfRelatedRecords g (nenv: NameResolutionEnv) (id: Ident) (allFi for e in nenv.eTyconsByDemangledNameAndArity do let hasRequireQualifiedAccessAttribute = HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute e.Value.Attribs if hasRequireQualifiedAccessAttribute then - if e.Value.IsRecordTycon && e.Value.AllFieldsArray |> Seq.exists (fun x -> x.Name = id.idText) then + if e.Value.IsRecordTycon && e.Value.AllFieldsArray |> Seq.exists (fun x -> x.LogicalName = id.idText) then addToBuffer (e.Value.DisplayName + "." + id.idText) UndefinedName(0, FSComp.SR.undefinedNameRecordLabel, id, suggestLabels) @@ -3205,13 +3477,19 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi // Eliminate duplicates arising from multiple 'open' frefs |> ListSet.setify (fun fref1 fref2 -> tyconRefEq g fref1.TyconRef fref2.TyconRef) - |> List.map (fun x -> ResolutionInfo.Empty, FieldResolution(x, false)) - - if isAppTy g ty then + |> List.map (fun x -> + let rfinfo = + match nenv.eUnqualifiedRecordOrUnionTypeInsts.TryFind x.TyconRef with + | Some tinst -> RecdFieldInfo(tinst, x) + | _ -> FreshenRecdFieldRef ncenv m x + ResolutionInfo.Empty, FieldResolution(rfinfo, false)) + + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText, m, ty) with - | ValueSome (RecdFieldInfo(_, rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref, false)] + | ValueSome (RecdFieldInfo(_, rfref)) -> [ResolutionInfo.Empty, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false)] | _ -> - if isRecdTy g ty then + if tcref.IsRecordTycon then // record label doesn't belong to record type -> suggest other labels of same record let suggestLabels (addToBuffer: string -> unit) = for label in SuggestOtherLabelsOfSameRecordType g nenv ty id allFields do @@ -3222,7 +3500,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi error(ErrorWithSuggestions(errorText, m, id.idText, suggestLabels)) else lookup() - else + | _ -> lookup() | _ -> let lid = (mp@[id]) @@ -3235,7 +3513,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty, tcref)) let tyconSearch = ResolveLongIdentInTyconRefs ResultCollectionSettings.AllResults ncenv nenv LookupKind.RecdField 1 m ad id2 rest2 typeNameResInfo tn.idRange tcrefs // choose only fields - let tyconSearch = tyconSearch |?> List.choose (function (resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest) -> Some(resInfo, FieldResolution(rfref, false), rest) | _ -> None) + let tyconSearch = tyconSearch |?> List.choose (function resInfo, Item.RecdField(RecdFieldInfo(_, rfref)), rest -> Some(resInfo, FieldResolution(FreshenRecdFieldRef ncenv m rfref, false), rest) | _ -> None) tyconSearch | _ -> NoResultsOrUsefulErrors @@ -3243,7 +3521,7 @@ let ResolveFieldPrim sink (ncenv: NameResolver) nenv ad ty (mp, id: Ident) allFi match lid with | [] -> NoResultsOrUsefulErrors | id2 :: rest2 -> - ResolveLongIndentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m OpenQualified nenv ad id2 rest2 false + ResolveLongIdentAsModuleOrNamespaceThen sink ResultCollectionSettings.AtMostOneResult ncenv.amap m OpenQualified nenv ad id2 rest2 false (ResolveFieldInModuleOrNamespace ncenv nenv ad) let resInfo, item, rest = @@ -3266,11 +3544,6 @@ let ResolveField sink ncenv nenv ad ty (mp, id) allFields = ResolutionInfo.SendEntityPathToSink(sink, ncenv, nenv, ItemOccurence.UseInType, ad, resInfo, checker) rfref) -/// Generate a new reference to a record field with a fresh type instantiation -let FreshenRecdFieldRef (ncenv: NameResolver) m (rfref: RecdFieldRef) = - Item.RecdField(RecdFieldInfo(ncenv.InstantiationGenerator m (rfref.Tycon.Typars m), rfref)) - - /// Resolve F#/IL "." syntax in expressions (2). /// /// We have an expr. on the left, and we do an access, e.g. @@ -3280,8 +3553,7 @@ let FreshenRecdFieldRef (ncenv: NameResolver) m (rfref: RecdFieldRef) = /// determine any valid members // // QUERY (instantiationGenerator cleanup): it would be really nice not to flow instantiationGenerator to here. -let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Ident) rest findFlag = - let typeNameResInfo = TypeNameResolutionInfo.Default +let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Ident) rest (typeNameResInfo: TypeNameResolutionInfo) findFlag = let adhocDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m ad id rest findFlag typeNameResInfo ty) match adhocDotSearchAccessible with | Exception _ -> @@ -3296,7 +3568,7 @@ let private ResolveExprDotLongIdent (ncenv: NameResolver) m ad nenv ty (id: Iden | true, rfref :: _ -> // NOTE (instantiationGenerator cleanup): we need to freshen here because we don't know the type. // But perhaps the caller should freshen?? - let item = FreshenRecdFieldRef ncenv m rfref + let item = Item.RecdField(FreshenRecdFieldRef ncenv m rfref) OneSuccess (ResolutionInfo.Empty, item, rest) | _ -> NoResultsOrUsefulErrors @@ -3353,22 +3625,24 @@ type AfterResolution = /// /// Called for 'TypeName.Bar' - for VS IntelliSense, we can filter out instance members from method groups let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv typeNameResInfo lid = - let item1, rest = ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid + match ResolveExprLongIdent sink ncenv wholem ad nenv typeNameResInfo lid with + | Exception e -> Exception e + | Result (tinstEnclosing, item1, rest) -> let itemRange = ComputeItemRange wholem lid rest let item = FilterMethodGroups ncenv itemRange item1 true match item1, item with | Item.MethodGroup(name, minfos1, _), Item.MethodGroup(_, [], _) when not (isNil minfos1) -> - error(Error(FSComp.SR.methodIsNotStatic name, wholem)) - | _ -> () + raze(Error(FSComp.SR.methodIsNotStatic name, wholem)) + | _ -> // Fake idents e.g. 'Microsoft.FSharp.Core.None' have identical ranges for each part let isFakeIdents = match lid with | [] | [_] -> false | head :: ids -> - ids |> List.forall (fun id -> Range.equals id.idRange head.idRange) + ids |> List.forall (fun id -> equals id.idRange head.idRange) let callSink (refinedItem, tpinst) = if not isFakeIdents then @@ -3380,7 +3654,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameReso | Item.ActivePatternResult _ -> ItemOccurence.Binding | _ -> ItemOccurence.Use - CallNameResolutionSink sink (itemRange, nenv, refinedItem, item, tpinst, occurence, nenv.DisplayEnv, ad) + CallMethodGroupNameResolutionSink sink (itemRange, nenv, refinedItem, item, tpinst, occurence, ad) let callSinkWithSpecificOverload (minfo: MethInfo, pinfoOpt: PropInfo option, tpinst) = let refinedItem = @@ -3401,7 +3675,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink: TcResultsSink) (ncenv: NameReso callSink (item, emptyTyparInst) AfterResolution.DoNothing - item, itemRange, rest, afterResolution + success (tinstEnclosing, item, itemRange, rest, afterResolution) let (|NonOverridable|_|) namedItem = match namedItem with @@ -3409,16 +3683,14 @@ let (|NonOverridable|_|) namedItem = | Item.Property(_, pinfos) when pinfos |> List.exists(fun pinfo -> pinfo.IsVirtualProperty) -> None | _ -> Some () - - /// Called for 'expression.Bar' - for VS IntelliSense, we can filter out static members from method groups /// Also called for 'GenericType.Bar' - for VS IntelliSense, we can filter out non-static members from method groups -let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv ty lid findFlag thisIsActuallyATyAppNotAnExpr = +let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameResolver) wholem ad nenv ty lid (staticResInfo: TypeNameResolutionInfo) findFlag thisIsActuallyATyAppNotAnExpr = let resolveExpr findFlag = let resInfo, item, rest = match lid with | id :: rest -> - ResolveExprDotLongIdent ncenv wholem ad nenv ty id rest findFlag + ResolveExprDotLongIdent ncenv wholem ad nenv ty id rest staticResInfo findFlag | _ -> error(InternalError("ResolveExprDotLongIdentAndComputeRange", wholem)) let itemRange = ComputeItemRange wholem lid rest resInfo, item, rest, itemRange @@ -3444,7 +3716,7 @@ let ResolveExprDotLongIdentAndComputeRange (sink: TcResultsSink) (ncenv: NameRes let staticOnly = thisIsActuallyATyAppNotAnExpr let refinedItem = FilterMethodGroups ncenv itemRange refinedItem staticOnly let unrefinedItem = FilterMethodGroups ncenv itemRange unrefinedItem staticOnly - CallNameResolutionSink sink (itemRange, nenv, refinedItem, unrefinedItem, tpinst, ItemOccurence.Use, nenv.DisplayEnv, ad) + CallMethodGroupNameResolutionSink sink (itemRange, nenv, refinedItem, unrefinedItem, tpinst, ItemOccurence.Use, ad) let callSinkWithSpecificOverload (minfo: MethInfo, pinfoOpt: PropInfo option, tpinst) = let refinedItem = @@ -3510,7 +3782,9 @@ let IsUnionCaseUnseen ad g amap m (ucref: UnionCaseRef) = let ItemIsUnseen ad g amap m item = match item with - | Item.Value x -> IsValUnseen ad g m x + | Item.Value x -> + let isUnseenNameOfOperator = valRefEq g g.nameof_vref x && not (g.langVersion.SupportsFeature LanguageFeature.NameOf) + isUnseenNameOfOperator || IsValUnseen ad g m x | Item.UnionCase(x, _) -> IsUnionCaseUnseen ad g amap m x.UnionCaseRef | Item.ExnCase x -> IsTyconUnseen ad g amap m x | _ -> false @@ -3519,7 +3793,10 @@ let ItemOfTyconRef ncenv m (x: TyconRef) = Item.Types (x.DisplayName, [FreshenTycon ncenv m x]) let ItemOfTy g x = - let nm = if isAppTy g x then (tcrefOfAppTy g x).DisplayName else "?" + let nm = + match tryTcrefOfAppTy g x with + | ValueSome tcref -> tcref.DisplayName + | _ -> "?" Item.Types (nm, [x]) // Filter out 'PrivateImplementationDetail' classes @@ -3534,7 +3811,7 @@ let rec PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f plid (m | true, mty -> PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f rest (modref.NestedTyconRef mty) | _ -> [] -let PartialResolveLongIndentAsModuleOrNamespaceThen (nenv: NameResolutionEnv) plid f = +let PartialResolveLongIdentAsModuleOrNamespaceThen (nenv: NameResolutionEnv) plid f = match plid with | id :: rest -> match nenv.eModulesAndNamespaces.TryGetValue id with @@ -3755,7 +4032,7 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso else match tryDestAnonRecdTy g ty with | ValueSome (anonInfo, tys) -> - [ for (i, id) in Array.indexed anonInfo.SortedIds do + [ for i, id in Array.indexed anonInfo.SortedIds do yield Item.AnonRecdField(anonInfo, tys, i, id.idRange) ] | _ -> [] @@ -3779,7 +4056,7 @@ let rec ResolvePartialLongIdentInType (ncenv: NameResolver) nenv isApplicableMet let rfinfos = ncenv.InfoReader.GetRecordOrClassFieldsOfType(None, ad, m, ty) - |> List.filter (fun fref -> fref.Name = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) + |> List.filter (fun fref -> fref.LogicalName = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) let nestedTypes = ty @@ -3903,7 +4180,7 @@ let rec private EntityRefContainsSomethingAccessible (ncenv: NameResolver) m ad let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv isApplicableMeth m ad (modref: ModuleOrNamespaceRef) plid allowObsolete = let g = ncenv.g let mty = modref.ModuleOrNamespaceType - + match plid with | [] -> let tycons = @@ -3940,15 +4217,15 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is // Collect up the accessible discriminated union cases in the module @ (UnionCaseRefsInModuleOrNamespace modref |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) + |> List.filter (fun ucref -> not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute ucref.TyconRef.Attribs)) |> List.map (fun x -> Item.UnionCase(GeneralizeUnionCaseRef x, false))) // Collect up the accessible active patterns in the module - @ (ActivePatternElemsOfModuleOrNamespace modref + @ (ActivePatternElemsOfModuleOrNamespace g modref |> NameMap.range |> List.filter (fun apref -> apref.ActivePatternVal |> IsValUnseen ad g m |> not) |> List.map Item.ActivePatternCase) - // Collect up the accessible F# exception declarations in the module @ (mty.ExceptionDefinitionsByDemangledName |> NameMap.range @@ -3998,7 +4275,7 @@ let TryToResolveLongIdentAsType (ncenv: NameResolver) (nenv: NameResolutionEnv) match v with | Item.Value x -> let ty = x.Type - let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty + let ty = if x.IsCtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty Some ty | _ -> None | _ -> None @@ -4033,11 +4310,12 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE | FullyQualified -> [] | OpenQualified -> nenv.eUnqualifiedItems.Values - |> List.filter (function + |> Seq.filter (function | Item.UnqualifiedType _ -> false | Item.Value v -> not v.IsMember | _ -> true) - |> List.filter (ItemIsUnseen ad g ncenv.amap m >> not) + |> Seq.filter (ItemIsUnseen ad g ncenv.amap m >> not) + |> Seq.toList let activePatternItems = match fullyQualified with @@ -4065,17 +4343,19 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE let tycons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values - |> List.filter (fun tcref -> + |> Seq.filter (fun tcref -> not (tcref.LogicalName.Contains ",") && not tcref.IsExceptionDecl && not (IsTyconUnseen ad g ncenv.amap m tcref)) - |> List.map (ItemOfTyconRef ncenv m) + |> Seq.map (ItemOfTyconRef ncenv m) + |> Seq.toList // Get all the constructors accessible from here let constructors = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) - |> List.collect (InfosForTyconConstructors ncenv m ad) + |> Seq.filter (IsTyconUnseen ad g ncenv.amap m >> not) + |> Seq.collect (InfosForTyconConstructors ncenv m ad) + |> Seq.toList unqualifiedItems @ activePatternItems @ moduleAndNamespaceItems @ tycons @ constructors @@ -4083,7 +4363,7 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE // Look in the namespaces 'id' let namespaces = - PartialResolveLongIndentAsModuleOrNamespaceThen nenv [id] (fun modref -> + PartialResolveLongIdentAsModuleOrNamespaceThen nenv [id] (fun modref -> let allowObsolete = rest <> [] && allowObsolete if EntityRefContainsSomethingAccessible ncenv m ad modref then ResolvePartialLongIdentInModuleOrNamespace ncenv nenv isApplicableMeth m ad modref rest allowObsolete @@ -4098,7 +4378,7 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE match v with | Item.Value x -> let ty = x.Type - let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty + let ty = if x.IsCtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty (ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest ty), true | _ -> [], false | _ -> [], false) @@ -4225,11 +4505,12 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv: let recdTyCons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values - |> List.filter (fun tcref -> + |> Seq.filter (fun tcref -> not (tcref.LogicalName.Contains ",") && tcref.IsRecordTycon && not (IsTyconUnseen ad g ncenv.amap m tcref)) - |> List.map (ItemOfTyconRef ncenv m) + |> Seq.map (ItemOfTyconRef ncenv m) + |> Seq.toList let recdFields = nenv.eFieldLabels @@ -4244,7 +4525,7 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv: | id :: rest -> // Get results let modsOrNs = - PartialResolveLongIndentAsModuleOrNamespaceThen nenv [id] (fun modref -> + PartialResolveLongIdentAsModuleOrNamespaceThen nenv [id] (fun modref -> let allowObsolete = rest <> [] && allowObsolete if EntityRefContainsSomethingAccessible ncenv m ad modref then ResolvePartialLongIdentInModuleOrNamespaceForRecordFields ncenv nenv m ad modref rest allowObsolete @@ -4306,7 +4587,7 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( if not statics then match tryDestAnonRecdTy g ty with | ValueSome (anonInfo, tys) -> - for (i, id) in Array.indexed anonInfo.SortedIds do + for i, id in Array.indexed anonInfo.SortedIds do yield Item.AnonRecdField(anonInfo, tys, i, id.idRange) | _ -> () @@ -4464,7 +4745,7 @@ let rec ResolvePartialLongIdentInTypeForItem (ncenv: NameResolver) nenv m ad sta let rfinfos = ncenv.InfoReader.GetRecordOrClassFieldsOfType(None, ad, m, ty) - |> List.filter (fun fref -> fref.Name = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) + |> List.filter (fun fref -> fref.LogicalName = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) let nestedTypes = ty |> GetNestedTypesOfType (ad, ncenv, Some id, TypeNameResolutionStaticArgsInfo.Indefinite, false, m) @@ -4528,11 +4809,12 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver) yield! UnionCaseRefsInModuleOrNamespace modref |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) + |> List.filter (fun ucref -> not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute ucref.TyconRef.Attribs)) |> List.map (fun x -> Item.UnionCase(GeneralizeUnionCaseRef x, false)) | Item.ActivePatternCase _ -> // Collect up the accessible active patterns in the module yield! - ActivePatternElemsOfModuleOrNamespace modref + ActivePatternElemsOfModuleOrNamespace g modref |> NameMap.range |> List.filter (fun apref -> apref.ActivePatternVal |> IsValUnseen ad g m |> not) |> List.map Item.ActivePatternCase @@ -4602,7 +4884,7 @@ let rec PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f pli PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f rest (modref.NestedTyconRef mty) | _ -> Seq.empty -let PartialResolveLongIndentAsModuleOrNamespaceThenLazy (nenv: NameResolutionEnv) plid f = +let PartialResolveLongIdentAsModuleOrNamespaceThenLazy (nenv: NameResolutionEnv) plid f = seq { match plid with | id :: rest -> @@ -4677,7 +4959,7 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a // Look in the namespaces 'id' yield! - PartialResolveLongIndentAsModuleOrNamespaceThenLazy nenv [id] (fun modref -> + PartialResolveLongIdentAsModuleOrNamespaceThenLazy nenv [id] (fun modref -> if EntityRefContainsSomethingAccessible ncenv m ad modref then ResolvePartialLongIdentInModuleOrNamespaceForItem ncenv nenv m ad modref rest item else Seq.empty) @@ -4686,7 +4968,7 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a match nenv.eUnqualifiedItems.TryGetValue id with | true, Item.Value x -> let ty = x.Type - let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty + let ty = if x.IsCtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item ty | _ -> // type.lookup: lookup a static something in a type diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi index ea3bbd8aeaf..ec2f3186af0 100755 --- a/src/fsharp/NameResolution.fsi +++ b/src/fsharp/NameResolution.fsi @@ -2,48 +2,48 @@ module internal FSharp.Compiler.NameResolution -open FSharp.Compiler +open Internal.Utilities.Library open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast open FSharp.Compiler.Infos -open FSharp.Compiler.Range open FSharp.Compiler.Import open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.PrettyNaming +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals /// A NameResolver is a context for name resolution. It primarily holds an InfoReader. type NameResolver = - new : g:TcGlobals * amap:ImportMap * infoReader:InfoReader * instantiationGenerator:(range -> Typars -> TypeInst) -> NameResolver - member InfoReader : InfoReader - member amap : ImportMap - member g : TcGlobals - member languageSupportsNameOf : bool + + new: g:TcGlobals * amap:ImportMap * infoReader:InfoReader * instantiationGenerator:(range -> Typars -> TypeInst) -> NameResolver + + member InfoReader: InfoReader + + member amap: ImportMap + + member g: TcGlobals + + member languageSupportsNameOf: bool /// Get the active pattern elements defined in a module, if any. Cache in the slot in the module type. -val ActivePatternElemsOfModuleOrNamespace : ModuleOrNamespaceRef -> NameMap +val ActivePatternElemsOfModuleOrNamespace: g: TcGlobals -> ModuleOrNamespaceRef -> NameMap [] /// Represents the item with which a named argument is associated. type ArgumentContainer = /// The named argument is an argument of a method | Method of MethInfo - /// The named argument is a static parameter to a provided type or a parameter to an F# exception constructor - | Type of TyconRef - /// The named argument is a static parameter to a union case constructor - | UnionCase of UnionCaseInfo -//--------------------------------------------------------------------------- -// -//------------------------------------------------------------------------- + /// The named argument is a static parameter to a provided type. + | Type of TyconRef /// Detect a use of a nominal type, including type abbreviations. /// When reporting symbols, we care about abbreviations, e.g. 'int' and 'int32' count as two separate symbols. -val (|AbbrevOrAppTy|_|) : TType -> TyconRef option +val (|AbbrevOrAppTy|_|): TType -> TyconRef option + +type EnclosingTypeInst = TypeInst [] /// Represents an item that results from name resolution @@ -52,10 +52,10 @@ type Item = | Value of ValRef /// Represents the resolution of a name to an F# union case. - | UnionCase of UnionCaseInfo * bool + | UnionCase of UnionCaseInfo * hasRequireQualifiedAccessAttr: bool /// Represents the resolution of a name to an F# active pattern result. - | ActivePatternResult of ActivePatternInfo * TType * int * range + | ActivePatternResult of apinfo: ActivePatternInfo * apOverallTy: TType * index: int * range: range /// Represents the resolution of a name to an F# active pattern case within the body of an active pattern. | ActivePatternCase of ActivePatternElemRef @@ -63,9 +63,12 @@ type Item = /// Represents the resolution of a name to an F# exception definition. | ExnCase of TyconRef - /// Represents the resolution of a name to an F# record field. + /// Represents the resolution of a name to an F# record or exception field. | RecdField of RecdFieldInfo + /// Represents the resolution of a name to a union case field. + | UnionCaseField of UnionCaseInfo * fieldIndex: int + /// Represents the resolution of a name to a field of an anonymous record type. | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range @@ -111,7 +114,7 @@ type Item = | TypeVar of string * Typar /// Represents the resolution of a name to a module or namespace - | ModuleOrNamespaces of Tast.ModuleOrNamespaceRef list + | ModuleOrNamespaces of ModuleOrNamespaceRef list /// Represents the resolution of a name to an operator | ImplicitOp of Ident * TraitConstraintSln option ref @@ -125,44 +128,102 @@ type Item = /// Represents the potential resolution of an unqualified name to a type. | UnqualifiedType of TyconRef list - member DisplayName : string + /// The text for the item to use in the declaration list. + /// This does not include backticks, parens etc. + /// + /// Note: here "Core" means "without added backticks or parens" + member DisplayNameCore: string + + /// The full text for the item to show in error messages and to use in code. + /// This includes backticks, parens etc. + member DisplayName: string [] /// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at /// a particular usage point. type ItemWithInst = - { Item : Item + { Item: Item TyparInst: TyparInst } -val (|ItemWithInst|) : ItemWithInst -> Item * TyparInst -val ItemWithNoInst : Item -> ItemWithInst +val (|ItemWithInst|): ItemWithInst -> Item * TyparInst +val ItemWithNoInst: Item -> ItemWithInst /// Represents a record field resolution and the information if the usage is deprecated. -type FieldResolution = FieldResolution of RecdFieldRef * bool +type FieldResolution = FieldResolution of RecdFieldInfo * bool /// Information about an extension member held in the name resolution environment -[] -type ExtensionMember +type ExtensionMember = + /// F#-style Extrinsic extension member, defined in F# code + | FSExtMem of ValRef * ExtensionMethodPriority + + /// ILExtMem(declaringTyconRef, ilMetadata, pri) + /// + /// IL-style extension member, backed by some kind of method with an [] attribute + | ILExtMem of TyconRef * MethInfo * ExtensionMethodPriority + + /// Describes the sequence order of the introduction of an extension method. Extension methods that are introduced + /// later through 'open' get priority in overload resolution. + member Priority: ExtensionMethodPriority /// The environment of information used to resolve names [] type NameResolutionEnv = - {eDisplayEnv: DisplayEnv - eUnqualifiedItems: LayeredMap - ePatItems: NameMap - eModulesAndNamespaces: NameMultiMap - eFullyQualifiedModulesAndNamespaces: NameMultiMap - eFieldLabels: NameMultiMap - eTyconsByAccessNames: LayeredMultiMap - eFullyQualifiedTyconsByAccessNames: LayeredMultiMap - eTyconsByDemangledNameAndArity: LayeredMap - eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap - eIndexedExtensionMembers: TyconRefMultiMap - eUnindexedExtensionMembers: ExtensionMember list - eTypars: NameMap } - static member Empty : g:TcGlobals -> NameResolutionEnv - member DisplayEnv : DisplayEnv - member FindUnqualifiedItem : string -> Item + { /// Display environment information for output + eDisplayEnv: DisplayEnv + + /// Values and Data Tags available by unqualified name + eUnqualifiedItems: LayeredMap + + /// Enclosing type instantiations that are associated with an unqualified type item + eUnqualifiedEnclosingTypeInsts: TyconRefMap + + /// Data Tags and Active Pattern Tags available by unqualified name + ePatItems: NameMap + + /// Modules accessible via "." notation. Note this is a multi-map. + /// Adding a module abbreviation adds it a local entry to this List.map. + /// Likewise adding a ccu or opening a path adds entries to this List.map. + eModulesAndNamespaces: NameMultiMap + + /// Fully qualified modules and namespaces. 'open' does not change this. + eFullyQualifiedModulesAndNamespaces: NameMultiMap + + /// RecdField labels in scope. RecdField labels are those where type are inferred + /// by label rather than by known type annotation. + /// Bools indicate if from a record, where no warning is given on indeterminate lookup + eFieldLabels: NameMultiMap + + /// Record or unions that may have type instantiations associated with them + /// when record labels or union cases are used in an unqualified context. + eUnqualifiedRecordOrUnionTypeInsts: TyconRefMap + + /// Tycons indexed by the various names that may be used to access them, e.g. + /// "List" --> multiple TyconRef's for the various tycons accessible by this name. + /// "List`1" --> TyconRef + eTyconsByAccessNames: LayeredMultiMap + + eFullyQualifiedTyconsByAccessNames: LayeredMultiMap + + /// Tycons available by unqualified, demangled names (i.e. (List,1) --> TyconRef) + eTyconsByDemangledNameAndArity: LayeredMap + + /// Tycons available by unqualified, demangled names (i.e. (List,1) --> TyconRef) + eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap + + /// Extension members by type and name + eIndexedExtensionMembers: TyconRefMultiMap + + /// Other extension members unindexed by type + eUnindexedExtensionMembers: ExtensionMember list + + /// Typars (always available by unqualified names). Further typars can be + /// in the tpenv, a structure folded through each top-level definition. + eTypars: NameMap + + } + static member Empty: g:TcGlobals -> NameResolutionEnv + member DisplayEnv: DisplayEnv + member FindUnqualifiedItem: string -> Item type FullyQualifiedFlag = | FullyQualified @@ -172,56 +233,60 @@ type FullyQualifiedFlag = type BulkAdd = Yes | No /// Find a field in anonymous record type -val internal TryFindAnonRecdFieldOfType : TcGlobals -> TType -> string -> Item option +val internal TryFindAnonRecdFieldOfType: TcGlobals -> TType -> string -> Item option /// Add extra items to the environment for Visual Studio, e.g. static members -val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv +val internal AddFakeNamedValRefToNameEnv: string -> NameResolutionEnv -> ValRef -> NameResolutionEnv /// Add some extra items to the environment for Visual Studio, e.g. record members -val internal AddFakeNameToNameEnv : string -> NameResolutionEnv -> Item -> NameResolutionEnv +val internal AddFakeNameToNameEnv: string -> NameResolutionEnv -> Item -> NameResolutionEnv /// Add a single F# value to the environment. -val internal AddValRefToNameEnv : NameResolutionEnv -> ValRef -> NameResolutionEnv +val internal AddValRefToNameEnv: TcGlobals -> NameResolutionEnv -> ValRef -> NameResolutionEnv /// Add active pattern result tags to the environment. -val internal AddActivePatternResultTagsToNameEnv : ActivePatternInfo -> NameResolutionEnv -> TType -> range -> NameResolutionEnv +val internal AddActivePatternResultTagsToNameEnv: ActivePatternInfo -> NameResolutionEnv -> TType -> range -> NameResolutionEnv /// Add a list of type definitions to the name resolution environment -val internal AddTyconRefsToNameEnv : BulkAdd -> bool -> TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> TyconRef list -> NameResolutionEnv +val internal AddTyconRefsToNameEnv : BulkAdd -> bool -> TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> TyconRef list -> NameResolutionEnv /// Add an F# exception definition to the name resolution environment -val internal AddExceptionDeclsToNameEnv : BulkAdd -> NameResolutionEnv -> TyconRef -> NameResolutionEnv +val internal AddExceptionDeclsToNameEnv : BulkAdd -> NameResolutionEnv -> TyconRef -> NameResolutionEnv /// Add a module abbreviation to the name resolution environment -val internal AddModuleAbbrevToNameEnv : Ident -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv +val internal AddModuleAbbrevToNameEnv : Ident -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv /// Add a list of module or namespace to the name resolution environment, including any sub-modules marked 'AutoOpen' -val internal AddModuleOrNamespaceRefsToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv +val internal AddModuleOrNamespaceRefsToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv /// Add a single modules or namespace to the name resolution environment -val internal AddModuleOrNamespaceRefToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef -> NameResolutionEnv +val internal AddModuleOrNamespaceRefToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef -> NameResolutionEnv /// Add a list of modules or namespaces to the name resolution environment -val internal AddEntitiesContentsToNameEnv : TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv +val internal AddModuleOrNamespaceRefsContentsToNameEnv: TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv + +/// Add the content of a type to the name resolution environment +val internal AddTypeContentsToNameEnv: TcGlobals -> ImportMap -> AccessorDomain -> range -> NameResolutionEnv -> TType -> NameResolutionEnv /// A flag which indicates if it is an error to have two declared type parameters with identical names /// in the name resolution environment. type CheckForDuplicateTyparFlag = - | CheckForDuplicateTypars - | NoCheckForDuplicateTypars + | CheckForDuplicateTypars + | NoCheckForDuplicateTypars /// Add some declared type parameters to the name resolution environment -val internal AddDeclaredTyparsToNameEnv : CheckForDuplicateTyparFlag -> NameResolutionEnv -> Typar list -> NameResolutionEnv +val internal AddDeclaredTyparsToNameEnv: CheckForDuplicateTyparFlag -> NameResolutionEnv -> Typar list -> NameResolutionEnv /// Qualified lookup of type names in the environment -val internal LookupTypeNameInEnvNoArity : FullyQualifiedFlag -> string -> NameResolutionEnv -> TyconRef list +val internal LookupTypeNameInEnvNoArity: FullyQualifiedFlag -> string -> NameResolutionEnv -> TyconRef list /// Indicates whether we are resolving type names to type definitions or to constructor methods. type TypeNameResolutionFlag = - /// Indicates we are resolving type names to constructor methods. - | ResolveTypeNamesToCtors - /// Indicates we are resolving type names to type definitions - | ResolveTypeNamesToTypeRefs + /// Indicates we are resolving type names to constructor methods. + | ResolveTypeNamesToCtors + + /// Indicates we are resolving type names to type definitions + | ResolveTypeNamesToTypeRefs /// Represents information about the generic argument count of a type name when resolving it. /// @@ -229,17 +294,21 @@ type TypeNameResolutionFlag = /// of generic arguments. In others, we know precisely how many generic arguments are needed. [] type TypeNameResolutionStaticArgsInfo = - /// Indicates definite knowledge of empty type arguments, i.e. the logical equivalent of name< > - static member DefiniteEmpty : TypeNameResolutionStaticArgsInfo - /// Deduce definite knowledge of type arguments - static member FromTyArgs : numTyArgs:int -> TypeNameResolutionStaticArgsInfo + + /// Indicates definite knowledge of empty type arguments, i.e. the logical equivalent of name< > + static member DefiniteEmpty: TypeNameResolutionStaticArgsInfo + + /// Deduce definite knowledge of type arguments + static member FromTyArgs: numTyArgs:int -> TypeNameResolutionStaticArgsInfo /// Represents information which guides name resolution of types. [] type TypeNameResolutionInfo = - | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo - static member Default : TypeNameResolutionInfo - static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo + | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo + + static member Default: TypeNameResolutionInfo + + static member ResolveToTypeRefs: TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo /// Represents the kind of the occurrence when reporting a name in name resolution [] @@ -254,61 +323,62 @@ type internal ItemOccurence = | Open /// Check for equality, up to signature matching -val ItemsAreEffectivelyEqual : TcGlobals -> Item -> Item -> bool +val ItemsAreEffectivelyEqual: TcGlobals -> Item -> Item -> bool /// Hash compatible with ItemsAreEffectivelyEqual -val ItemsAreEffectivelyEqualHash : TcGlobals -> Item -> int +val ItemsAreEffectivelyEqualHash: TcGlobals -> Item -> int [] type internal CapturedNameResolution = /// line and column - member Pos : pos + member Pos: pos /// Named item - member Item : Item + member Item: Item /// The active instantiation for any generic type parameters member ItemWithInst: ItemWithInst /// Information about the occurrence of the symbol - member ItemOccurence : ItemOccurence + member ItemOccurence: ItemOccurence /// Information about printing. For example, should redundant keywords be hidden? - member DisplayEnv : DisplayEnv + member DisplayEnv: DisplayEnv /// Naming environment--for example, currently open namespaces. - member NameResolutionEnv : NameResolutionEnv + member NameResolutionEnv: NameResolutionEnv /// The access rights of code at the location - member AccessorDomain : AccessorDomain + member AccessorDomain: AccessorDomain /// The starting and ending position - member Range : range + member Range: range [] type internal TcResolutions = /// Name resolution environments for every interesting region in the file. These regions may /// overlap, in which case the smallest region applicable should be used. - member CapturedEnvs : ResizeArray + member CapturedEnvs: ResizeArray /// Information of exact types found for expressions, that can be to the left of a dot. /// typ - the inferred type for an expression - member CapturedExpressionTypings : ResizeArray + member CapturedExpressionTypings: ResizeArray /// Exact name resolutions - member CapturedNameResolutions : ResizeArray + member CapturedNameResolutions: ResizeArray - /// Represents all the resolutions of names to groups of methods. - member CapturedMethodGroupResolutions : ResizeArray + /// Represents additional resolutions of names to groups of methods. + /// CapturedNameResolutions should be checked when no captured method group is found. + /// See TypeCheckInfo.GetCapturedNameResolutions for example. + member CapturedMethodGroupResolutions: ResizeArray /// Represents the empty set of resolutions - static member Empty : TcResolutions - + static member Empty: TcResolutions [] type TcSymbolUseData = - { Item: Item + { ItemWithInst: ItemWithInst ItemOccurence: ItemOccurence DisplayEnv: DisplayEnv Range: range } @@ -318,88 +388,79 @@ type TcSymbolUseData = type internal TcSymbolUses = /// Get all the uses of a particular item within the file - member GetUsesOfSymbol : Item -> TcSymbolUseData[] + member GetUsesOfSymbol: Item -> TcSymbolUseData[] /// All the uses of all items within the file - member AllUsesOfSymbols : TcSymbolUseData[][] + member AllUsesOfSymbols: TcSymbolUseData[][] /// Get the locations of all the printf format specifiers in the file - member GetFormatSpecifierLocationsAndArity : unit -> (range * int)[] - -/// Represents open declaration statement. -type internal OpenDeclaration = - { /// Long identifier as it's presented in source code. - LongId: Ident list - - /// Full range of the open declaration. - Range : range option - - /// Modules or namespaces which is opened with this declaration. - Modules: ModuleOrNamespaceRef list - - /// Scope in which open declaration is visible. - AppliedScope: range - - /// If it's `namespace Xxx.Yyy` declaration. - IsOwnNamespace: bool } - - /// Create a new instance of OpenDeclaration. - static member Create : longId: Ident list * modules: ModuleOrNamespaceRef list * appliedScope: range * isOwnNamespace: bool -> OpenDeclaration - + member GetFormatSpecifierLocationsAndArity: unit -> (range * int)[] + + /// Empty collection of symbol uses + static member Empty: TcSymbolUses + /// Source text and an array of line end positions, used for format string parsing type FormatStringCheckContext = { /// Source text SourceText: ISourceText + /// Array of line start positions - LineStartPositions: int[] } + LineStartPositions: int[] + } /// An abstract type for reporting the results of name resolution and type checking type ITypecheckResultsSink = /// Record that an environment is active over the given scope range - abstract NotifyEnvWithScope : range * NameResolutionEnv * AccessorDomain -> unit + abstract NotifyEnvWithScope: range * NameResolutionEnv * AccessorDomain -> unit /// Record that an expression has a specific type at the given range. - abstract NotifyExprHasType : pos * TType * DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit + abstract NotifyExprHasType: TType * NameResolutionEnv * AccessorDomain * range -> unit /// Record that a name resolution occurred at a specific location in the source - abstract NotifyNameResolution : pos * Item * Item * TyparInst * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range * bool -> unit + abstract NotifyNameResolution: pos * Item * TyparInst * ItemOccurence * NameResolutionEnv * AccessorDomain * range * bool -> unit + + /// Record that a method group name resolution occurred at a specific location in the source + abstract NotifyMethodGroupNameResolution: pos * Item * Item * TyparInst * ItemOccurence * NameResolutionEnv * AccessorDomain * range * bool -> unit /// Record that a printf format specifier occurred at a specific location in the source - abstract NotifyFormatSpecifierLocation : range * int -> unit + abstract NotifyFormatSpecifierLocation: range * int -> unit /// Record that an open declaration occured in a given scope range - abstract NotifyOpenDeclaration : OpenDeclaration -> unit + abstract NotifyOpenDeclaration: OpenDeclaration -> unit /// Get the current source - abstract CurrentSourceText : ISourceText option + abstract CurrentSourceText: ISourceText option /// Cached line-end normalized source text and an array of line end positions, used for format string parsing - abstract FormatStringCheckContext : FormatStringCheckContext option + abstract FormatStringCheckContext: FormatStringCheckContext option /// An implementation of ITypecheckResultsSink to collect information during type checking type internal TcResultsSinkImpl = /// Create a TcResultsSinkImpl - new : tcGlobals : TcGlobals * ?sourceText: ISourceText -> TcResultsSinkImpl + new: tcGlobals: TcGlobals * ?sourceText: ISourceText -> TcResultsSinkImpl /// Get all the resolutions reported to the sink - member GetResolutions : unit -> TcResolutions + member GetResolutions: unit -> TcResolutions /// Get all the uses of all symbols reported to the sink - member GetSymbolUses : unit -> TcSymbolUses + member GetSymbolUses: unit -> TcSymbolUses /// Get all open declarations reported to the sink - member GetOpenDeclarations : unit -> OpenDeclaration[] + member GetOpenDeclarations: unit -> OpenDeclaration[] + + /// Get the format specifier locations + member GetFormatSpecifierLocations: unit -> (range * int)[] interface ITypecheckResultsSink /// An abstract type for reporting the results of name resolution and type checking, and which allows /// temporary suspension and/or redirection of reporting. type TcResultsSink = - { mutable CurrentSink : ITypecheckResultsSink option } - static member NoSink : TcResultsSink - static member WithSink : ITypecheckResultsSink -> TcResultsSink + { mutable CurrentSink: ITypecheckResultsSink option } + static member NoSink: TcResultsSink + static member WithSink: ITypecheckResultsSink -> TcResultsSink /// Indicates if we only need one result or all possible results from a resolution. @@ -409,34 +470,37 @@ type ResultCollectionSettings = | AtMostOneResult /// Temporarily redirect reporting of name resolution and type checking results -val internal WithNewTypecheckResultsSink : ITypecheckResultsSink * TcResultsSink -> System.IDisposable +val internal WithNewTypecheckResultsSink: ITypecheckResultsSink * TcResultsSink -> System.IDisposable /// Temporarily suspend reporting of name resolution and type checking results -val internal TemporarilySuspendReportingTypecheckResultsToSink : TcResultsSink -> System.IDisposable +val internal TemporarilySuspendReportingTypecheckResultsToSink: TcResultsSink -> System.IDisposable /// Report the active name resolution environment for a source range -val internal CallEnvSink : TcResultsSink -> range * NameResolutionEnv * AccessorDomain -> unit +val internal CallEnvSink : TcResultsSink -> range * NameResolutionEnv * AccessorDomain -> unit /// Report a specific name resolution at a source range -val internal CallNameResolutionSink : TcResultsSink -> range * NameResolutionEnv * Item * Item * TyparInst * ItemOccurence * DisplayEnv * AccessorDomain -> unit +val internal CallNameResolutionSink: TcResultsSink -> range * NameResolutionEnv * Item * TyparInst * ItemOccurence * AccessorDomain -> unit + +/// Report a specific method group name resolution at a source range +val internal CallMethodGroupNameResolutionSink: TcResultsSink -> range * NameResolutionEnv * Item * Item * TyparInst * ItemOccurence * AccessorDomain -> unit /// Report a specific name resolution at a source range, replacing any previous resolutions -val internal CallNameResolutionSinkReplacing : TcResultsSink -> range * NameResolutionEnv * Item * Item * TyparInst * ItemOccurence * DisplayEnv * AccessorDomain -> unit +val internal CallNameResolutionSinkReplacing: TcResultsSink -> range * NameResolutionEnv * Item * TyparInst * ItemOccurence * AccessorDomain -> unit /// Report a specific name resolution at a source range -val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * DisplayEnv * AccessorDomain -> unit +val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * AccessorDomain -> unit /// Report an open declaration -val internal CallOpenDeclarationSink : TcResultsSink -> OpenDeclaration -> unit +val internal CallOpenDeclarationSink: TcResultsSink -> OpenDeclaration -> unit /// Get all the available properties of a type (both intrinsic and extension) -val internal AllPropInfosOfTypeInScope : ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> FindMemberFlag -> range -> TType -> PropInfo list +val internal AllPropInfosOfTypeInScope: ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> FindMemberFlag -> range -> TType -> PropInfo list /// Get all the available properties of a type (only extension) -val internal ExtensionPropInfosOfTypeInScope : ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> range -> TType -> PropInfo list +val internal ExtensionPropInfosOfTypeInScope: ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> range -> TType -> PropInfo list /// Get the available methods of a type (both declared and inherited) -val internal AllMethInfosOfTypeInScope : ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> FindMemberFlag -> range -> TType -> MethInfo list +val internal AllMethInfosOfTypeInScope: ResultCollectionSettings -> InfoReader -> NameResolutionEnv -> string option -> AccessorDomain -> FindMemberFlag -> range -> TType -> MethInfo list /// Used to report an error condition where name resolution failed due to an indeterminate type exception internal IndeterminateType of range @@ -445,7 +509,7 @@ exception internal IndeterminateType of range exception internal UpperCaseIdentifierInPattern of range /// Generate a new reference to a record field with a fresh type instantiation -val FreshenRecdFieldRef :NameResolver -> Range.range -> Tast.RecdFieldRef -> Item +val FreshenRecdFieldRef :NameResolver -> range -> RecdFieldRef -> RecdFieldInfo /// Indicates the kind of lookup being performed. Note, this type should be made private to nameres.fs. [] @@ -469,35 +533,35 @@ type PermitDirectReferenceToGeneratedType = | Yes | No -/// Resolve a long identifier to a namespace, module or static class. -val internal ResolveLongIndentAsModuleOrNamespaceOrStaticClass : TcResultsSink -> ResultCollectionSettings -> Import.ImportMap -> range -> allowStaticClasses: bool -> first: bool -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident -> Ident list -> isOpenDecl: bool -> ResultOrException<(int * ModuleOrNamespaceRef * ModuleOrNamespaceType) list > +/// Resolve a long identifier to a namespace, module. +val internal ResolveLongIdentAsModuleOrNamespace: TcResultsSink -> ResultCollectionSettings -> ImportMap -> range -> first: bool -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident -> Ident list -> isOpenDecl: bool -> ResultOrException<(int * ModuleOrNamespaceRef * ModuleOrNamespaceType) list > /// Resolve a long identifier to an object constructor. -val internal ResolveObjectConstructor : NameResolver -> DisplayEnv -> range -> AccessorDomain -> TType -> ResultOrException +val internal ResolveObjectConstructor : NameResolver -> DisplayEnv -> range -> AccessorDomain -> TType -> ResultOrException /// Resolve a long identifier using type-qualified name resolution. -val internal ResolveLongIdentInType : TcResultsSink -> NameResolver -> NameResolutionEnv -> LookupKind -> range -> AccessorDomain -> Ident -> FindMemberFlag -> TypeNameResolutionInfo -> TType -> Item * Ident list +val internal ResolveLongIdentInType : TcResultsSink -> NameResolver -> NameResolutionEnv -> LookupKind -> range -> AccessorDomain -> Ident -> FindMemberFlag -> TypeNameResolutionInfo -> TType -> Item * Ident list /// Resolve a long identifier when used in a pattern. -val internal ResolvePatternLongIdent : TcResultsSink -> NameResolver -> WarnOnUpperFlag -> bool -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item +val internal ResolvePatternLongIdent : TcResultsSink -> NameResolver -> WarnOnUpperFlag -> bool -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item /// Resolve a long identifier representing a type name -val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResolver -> NameResolutionEnv -> TypeNameResolutionInfo -> AccessorDomain -> range -> ModuleOrNamespaceRef -> Ident list -> TyconRef +val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResolver -> NameResolutionEnv -> TypeNameResolutionInfo -> AccessorDomain -> range -> ModuleOrNamespaceRef -> Ident list -> TyconRef /// Resolve a long identifier to a type definition -val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException +val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException /// Resolve a long identifier to a field -val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> Ident list -> FieldResolution list +val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> Ident list -> FieldResolution list /// Resolve a long identifier occurring in an expression position -val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * Ident list +val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> ResultOrException /// Resolve a (possibly incomplete) long identifier to a loist of possible class or record fields -val internal ResolvePartialLongIdentToClassOrRecdFields : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> bool -> Item list +val internal ResolvePartialLongIdentToClassOrRecdFields: NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> bool -> Item list /// Return the fields for the given class or record -val internal ResolveRecordOrClassFieldsOfType : NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list +val internal ResolveRecordOrClassFieldsOfType : NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list /// Specifies extra work to do after overload resolution [] @@ -517,19 +581,19 @@ type AfterResolution = | RecordResolution of Item option * (TyparInst -> unit) * (MethInfo * PropInfo option * TyparInst -> unit) * (unit -> unit) /// Resolve a long identifier occurring in an expression position. -val internal ResolveLongIdentAsExprAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * range * Ident list * AfterResolution +val internal ResolveLongIdentAsExprAndComputeRange: TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> ResultOrException /// Resolve a long identifier occurring in an expression position, qualified by a type. -val internal ResolveExprDotLongIdentAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TType -> Ident list -> FindMemberFlag -> bool -> Item * range * Ident list * AfterResolution +val internal ResolveExprDotLongIdentAndComputeRange: TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TType -> Ident list -> TypeNameResolutionInfo -> FindMemberFlag -> bool -> Item * range * Ident list * AfterResolution /// A generator of type instantiations used when no more specific type instantiation is known. -val FakeInstantiationGenerator : range -> Typar list -> TType list +val FakeInstantiationGenerator: range -> Typar list -> TType list /// Try to resolve a long identifier as type. -val TryToResolveLongIdentAsType : NameResolver -> NameResolutionEnv -> range -> string list -> TType option +val TryToResolveLongIdentAsType: NameResolver -> NameResolutionEnv -> range -> string list -> TType option /// Resolve a (possibly incomplete) long identifier to a set of possible resolutions. -val ResolvePartialLongIdent : NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> range -> AccessorDomain -> string list -> bool -> Item list +val ResolvePartialLongIdent: NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> range -> AccessorDomain -> string list -> bool -> Item list [] type ResolveCompletionTargets = @@ -537,8 +601,11 @@ type ResolveCompletionTargets = | SettablePropertiesAndFields /// Resolve a (possibly incomplete) long identifier to a set of possible resolutions, qualified by type. -val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> ResolveCompletionTargets -> Range.range -> AccessorDomain -> bool -> TType -> Item list +val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> ResolveCompletionTargets -> range -> AccessorDomain -> bool -> TType -> Item list + +val GetVisibleNamespacesAndModulesAtPoint: NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list -val GetVisibleNamespacesAndModulesAtPoint : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list +val IsItemResolvable: NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool -val IsItemResolvable : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool +val TrySelectExtensionMethInfoOfILExtMem: range -> ImportMap -> TType -> TyconRef * MethInfo * ExtensionMethodPriority -> MethInfo option + \ No newline at end of file diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs old mode 100644 new mode 100755 index 6479d6c6729..3689cfcad5d --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -1,85 +1,193 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//-------------------------------------------------------------------------- -// Print Signatures/Types, for signatures, intellisense, quick info, FSI responses -//-------------------------------------------------------------------------- - +/// Print Signatures/Types, for signatures, intellisense, quick info, FSI responses module internal FSharp.Compiler.NicePrint -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open System +open System.Globalization +open System.IO +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Rational open FSharp.Compiler -open FSharp.Compiler.Rational -open FSharp.Compiler.Ast +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AttributeChecking open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib open FSharp.Compiler.Infos open FSharp.Compiler.InfoReader -open FSharp.Compiler.AttributeChecking -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps -open FSharp.Compiler.PrettyNaming - -open Microsoft.FSharp.Core.Printf +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Text.TaggedText +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.AccessibilityLogic + +open FSharp.Core.Printf [] module internal PrintUtilities = let bracketIfL x lyt = if x then bracketL lyt else lyt + let squareAngleL x = LeftL.leftBracketAngle ^^ x ^^ RightL.rightBracketAngle - let angleL x = sepL Literals.leftAngle ^^ x ^^ rightL Literals.rightAngle - let braceL x = wordL Literals.leftBrace ^^ x ^^ wordL Literals.rightBrace - let braceBarL x = wordL Literals.leftBraceBar ^^ x ^^ wordL Literals.rightBraceBar + + let angleL x = sepL leftAngle ^^ x ^^ rightL rightAngle + + let braceL x = wordL leftBrace ^^ x ^^ wordL rightBrace + + let braceMultiLineL x = (wordL leftBrace @@-- x) @@ wordL rightBrace + + let braceBarL x = wordL leftBraceBar ^^ x ^^ wordL rightBraceBar + + // Use a space before a colon if there is an unusual character to the left + let addColonL l = + if endsWithL ">" l || endsWithL ")" l || endsWithL "`" l then + l ^^ WordL.colon + else + l ^^ RightL.colon let comment str = wordL (tagText (sprintf "(* %s *)" str)) - let layoutsL (ls: layout list) : layout = + let isDiscard (name: string) = name.StartsWith("_") + + let ensureFloat (s: string) = + if String.forall (fun c -> Char.IsDigit c || c = '-') s then + s + ".0" + else s + + let layoutsL (ls: Layout list) : Layout = match ls with | [] -> emptyL | [x] -> x | x :: xs -> List.fold (^^) x xs - let suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty = - isEnumTy g ty || isDelegateTy g ty || ExistsHeadTypeInEntireHierarchy g amap m ty g.exn_tcr || ExistsHeadTypeInEntireHierarchy g amap m ty g.tcref_System_Attribute + // Layout a curried function type. Over multiple lines breaking takes some care, e.g. + // + // val SampleFunctionTupledAllBreakA: + // longLongLongArgName1: string * longLongLongArgName2: TType * + // longLongLongArgName3: TType * longLongLongArgName4: TType + // -> TType list + // + // val SampleFunctionTupledAllBreakA: + // longLongLongArgName1: string * + // longLongLongArgName2: TType * + // longLongLongArgName3: TType * + // longLongLongArgName4: TType + // -> TType list + // + // val SampleFunctionCurriedOneBreakA: + // arg1: string -> arg2: TType -> arg3: TType + // -> arg4: TType -> TType list + // + // val SampleFunctionCurriedAllBreaksA: + // longLongLongArgName1: string + // -> longLongLongArgName2: TType + // -> longLongLongArgName3: TType + // -> longLongLongArgName4: TType + // -> TType list + // + // val SampleFunctionMixedA: + // longLongLongArgName1: string * + // longLongLongArgName2: string + // -> longLongLongArgName3: string * + // longLongLongArgName4: string * + // longLongLongArgName5: TType + // -> longLongLongArgName6: TType * + // longLongLongArgName7: TType * + // -> longLongLongArgName8: TType * + // longLongLongArgName9: TType * + // longLongLongArgName10: TType + // -> TType list + let curriedLayoutsL retTyDelim (argtysL: Layout list) (rtyL: Layout) = + let arrowAndRetyL = wordL (tagPunctuation retTyDelim) ^^ rtyL + let argtysL = + argtysL + |> List.mapi (fun i argtyL -> if i = 0 then argtyL else wordL (tagPunctuation "->") ^^ argtyL) + |> List.reduce (++) + argtysL --- arrowAndRetyL + + let tagNavArbValRef (valRefOpt: ValRef option) tag = + match valRefOpt with + | Some vref -> + tag |> mkNav vref.DefinitionRange + | None -> + tag + let suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty = + isEnumTy g ty || isDelegateTy g ty || ExistsHeadTypeInEntireHierarchy g amap m ty g.exn_tcr let applyMaxMembers maxMembers (allDecls: _ list) = match maxMembers with | Some n when allDecls.Length > n -> (allDecls |> List.truncate n) @ [wordL (tagPunctuation "...")] | _ -> allDecls - /// fix up a name coming from IL metadata by quoting "funny" names (keywords, otherwise invalid identifiers) - let adjustILName n = - n |> Lexhelp.Keywords.QuoteIdentifierIfNeeded - // Put the "+ N overloads" into the layout let shrinkOverloads layoutFunction resultFunction group = match group with | [x] -> [resultFunction x (layoutFunction x)] - | (x :: rest) -> [ resultFunction x (layoutFunction x -- leftL (tagText (match rest.Length with 1 -> FSComp.SR.nicePrintOtherOverloads1() | n -> FSComp.SR.nicePrintOtherOverloadsN(n)))) ] + | x :: rest -> [ resultFunction x (layoutFunction x -- leftL (tagText (match rest.Length with 1 -> FSComp.SR.nicePrintOtherOverloads1() | n -> FSComp.SR.nicePrintOtherOverloadsN(n)))) ] | _ -> [] - let layoutTyconRefImpl isAttribute (denv: DisplayEnv) (tcref: TyconRef) = + let tagEntityRefName(denv: DisplayEnv) (xref: EntityRef) name = + if xref.IsNamespace then tagNamespace name + elif xref.IsModule then tagModule name + elif xref.IsTypeAbbrev then + let ty = xref.TypeAbbrev.Value + match stripTyEqns denv.g ty with + | TType_app(tcref, _) when tcref.IsStructOrEnumTycon -> + tagStruct name + | _ -> + tagAlias name + elif xref.IsFSharpDelegateTycon then tagDelegate name + elif xref.IsILEnumTycon || xref.IsFSharpEnumTycon then tagEnum name + elif xref.IsStructOrEnumTycon then tagStruct name + elif isInterfaceTyconRef xref then tagInterface name + elif xref.IsUnionTycon then tagUnion name + elif xref.IsRecordTycon then tagRecord name + else tagClass name + + let usePrefix (denv: DisplayEnv) (tcref: TyconRef) = + match denv.genericParameterStyle with + | GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay + | GenericParameterStyle.Prefix -> true + | GenericParameterStyle.Suffix -> false + + let layoutTyconRefImpl isAttribute (denv: DisplayEnv) (tcref: TyconRef) = + + let prefix = usePrefix denv tcref + let isArray = not prefix && isArrayTyconRef denv.g tcref let demangled = - let name = - if denv.includeStaticParametersInTypeNames then - tcref.DisplayNameWithStaticParameters - elif tcref.DisplayName = tcref.DisplayNameWithStaticParameters then - tcref.DisplayName // has no static params - else - tcref.DisplayName+"<...>" // shorten - if isAttribute && name.EndsWithOrdinal("Attribute") then - String.dropSuffix name "Attribute" - else - name - let tyconTextL = - tagEntityRefName tcref demangled + if isArray then + tcref.DisplayNameCore // no backticks for arrays "int[]" + else + let name = + if denv.includeStaticParametersInTypeNames then + tcref.DisplayNameWithStaticParameters + elif tcref.DisplayName = tcref.DisplayNameWithStaticParameters then + tcref.DisplayName // has no static params + else + tcref.DisplayName+"<...>" // shorten + if isAttribute && name.EndsWithOrdinal("Attribute") then + String.dropSuffix name "Attribute" + else + name + + let tyconTagged = + tagEntityRefName denv tcref demangled |> mkNav tcref.DefinitionRange - |> wordL + + let tyconTextL = + if isArray then + tyconTagged |> rightL + else + tyconTagged |> wordL + if denv.shortTypeNames then tyconTextL else @@ -99,10 +207,108 @@ module internal PrintUtilities = let tcref = attrib.TyconRef squareAngleL (layoutTyconRefImpl true denv tcref) -module private PrintIL = + /// layout the xml docs immediately before another block + let layoutXmlDoc (denv: DisplayEnv) alwaysAddEmptyLine (xml: XmlDoc) restL = + if denv.showDocumentation then + let xmlDocL = + let linesL = + [ for lineText in xml.UnprocessedLines do + // These lines may have new-lines in them and we need to split them so we can format it + for line in lineText.Split('\n') do + // note here that we don't add a space after the triple-slash, because + // the implicit spacing hasn't been trimmed here. + yield ("///" + line) |> tagText |> wordL + ] + + // Always add an empty line before any "///" comment + let linesL = + if linesL.Length > 0 || alwaysAddEmptyLine then + [ yield "" |> tagText |> wordL + yield! linesL ] + else + linesL + + linesL |> aboveListL + + xmlDocL @@ restL + else restL + + let layoutXmlDocFromSig (denv: DisplayEnv) (infoReader: InfoReader) alwaysAddEmptyLine (possibleXmlDoc: XmlDoc) restL (info: (string option * string) option) = + let xmlDoc = + if possibleXmlDoc.IsEmpty then + match info with + | Some(Some ccuFileName, xmlDocSig) -> + infoReader.amap.assemblyLoader.TryFindXmlDocumentationInfo(Path.GetFileNameWithoutExtension ccuFileName) + |> Option.bind (fun xmlDocInfo -> + xmlDocInfo.TryGetXmlDocBySig(xmlDocSig) + ) + |> Option.defaultValue possibleXmlDoc + | _ -> + possibleXmlDoc + else + possibleXmlDoc + layoutXmlDoc denv alwaysAddEmptyLine xmlDoc restL + + let layoutXmlDocOfVal (denv: DisplayEnv) (infoReader: InfoReader) (vref: ValRef) restL = + if denv.showDocumentation then + GetXmlDocSigOfValRef denv.g vref + |> layoutXmlDocFromSig denv infoReader true vref.XmlDoc restL + else + restL + + let layoutXmlDocOfMethInfo (denv: DisplayEnv) (infoReader: InfoReader) (minfo: MethInfo) restL = + if denv.showDocumentation then + GetXmlDocSigOfMethInfo infoReader Range.range0 minfo + |> layoutXmlDocFromSig denv infoReader true minfo.XmlDoc restL + else + restL + + let layoutXmlDocOfPropInfo (denv: DisplayEnv) (infoReader: InfoReader) (pinfo: PropInfo) restL = + if denv.showDocumentation then + GetXmlDocSigOfProp infoReader Range.range0 pinfo + |> layoutXmlDocFromSig denv infoReader true pinfo.XmlDoc restL + else + restL + + let layoutXmlDocOfEventInfo (denv: DisplayEnv) (infoReader: InfoReader) (einfo: EventInfo) restL = + if denv.showDocumentation then + GetXmlDocSigOfEvent infoReader Range.range0 einfo + |> layoutXmlDocFromSig denv infoReader true einfo.XmlDoc restL + else + restL + + let layoutXmlDocOfILFieldInfo (denv: DisplayEnv) (infoReader: InfoReader) (finfo: ILFieldInfo) restL = + if denv.showDocumentation then + GetXmlDocSigOfILFieldInfo infoReader Range.range0 finfo + |> layoutXmlDocFromSig denv infoReader true XmlDoc.Empty restL + else + restL + + let layoutXmlDocOfRecdField (denv: DisplayEnv) (infoReader: InfoReader) isClassDecl (rfref: RecdFieldRef) restL = + if denv.showDocumentation then + GetXmlDocSigOfRecdFieldRef rfref + |> layoutXmlDocFromSig denv infoReader isClassDecl rfref.RecdField.XmlDoc restL + else + restL + + let layoutXmlDocOfUnionCase (denv: DisplayEnv) (infoReader: InfoReader) (ucref: UnionCaseRef) restL = + if denv.showDocumentation then + GetXmlDocSigOfUnionCaseRef ucref + |> layoutXmlDocFromSig denv infoReader false ucref.UnionCase.XmlDoc restL + else + restL + + let layoutXmlDocOfEntity (denv: DisplayEnv) (infoReader: InfoReader) (eref: EntityRef) restL = + if denv.showDocumentation then + GetXmlDocSigOfEntityRef infoReader Range.range0 eref + |> layoutXmlDocFromSig denv infoReader true eref.XmlDoc restL + else + restL + +module PrintIL = let fullySplitILTypeRef (tref: ILTypeRef) = - (List.collect IL.splitNamespace (tref.Enclosing @ [PrettyNaming.DemangleGenericTypeName tref.Name])) + (List.collect splitNamespace (tref.Enclosing @ [DemangleGenericTypeName tref.Name])) let layoutILTypeRefName denv path = let path = @@ -120,7 +326,7 @@ module private PrintIL = | [ "System"; "Int32" ] -> ["int" ] | [ "System"; "Int64" ] -> ["int64" ] | [ "System"; "UInt16" ] -> ["uint16" ] - | [ "System"; "UInt32" ] -> ["uint32" ] + | [ "System"; "UInt32" ] -> ["uint" ] | [ "System"; "UInt64" ] -> ["uint64" ] | [ "System"; "IntPtr" ] -> ["nativeint" ] | [ "System"; "UIntPtr" ] -> ["unativeint" ] @@ -137,42 +343,26 @@ module private PrintIL = let path = fullySplitILTypeRef tref layoutILTypeRefName denv path - /// this fixes up a name just like adjustILName but also handles F# - /// operators - let adjustILMethodName n = - let demangleOperatorNameIfNeeded s = - if IsMangledOpName s - then DemangleOperatorName s - else s - n |> Lexhelp.Keywords.QuoteIdentifierIfNeeded |> demangleOperatorNameIfNeeded - - let isStaticILEvent (e: ILEventDef) = - e.AddMethod.CallingSignature.CallingConv.IsStatic || - e.RemoveMethod.CallingSignature.CallingConv.IsStatic - let layoutILArrayShape (ILArrayShape sh) = SepL.leftBracket ^^ wordL (tagPunctuation (sh |> List.tail |> List.map (fun _ -> ",") |> String.concat "")) ^^ RightL.rightBracket // drop off one "," so that a n-dimensional array has n - 1 ","'s - let layoutILGenericParameterDefs (ps: ILGenericParameterDefs) = - ps |> List.map (fun x -> "'" + x.Name |> (tagTypeParameter >> wordL)) - - let paramsL (ps: layout list) : layout = + let paramsL (ps: Layout list) : Layout = match ps with | [] -> emptyL | _ -> - let body = Layout.commaListL ps + let body = commaListL ps SepL.leftAngle ^^ body ^^ RightL.rightAngle - let pruneParams (className: string) (ilTyparSubst: layout list) = + let pruneParams (className: string) (ilTyparSubst: Layout list) = let numParams = // can't find a way to see the number of generic parameters for *this* class (the GenericParams also include type variables for enclosing classes); this will have to do let rightMost = className |> SplitNamesForILPath |> List.last - match System.Int32.TryParse(rightMost, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture) with + match Int32.TryParse(rightMost, NumberStyles.Integer, CultureInfo.InvariantCulture) with | true, n -> n | false, _ -> 0 // looks like it's non-generic ilTyparSubst |> List.rev |> List.truncate numParams |> List.rev - let rec layoutILType (denv: DisplayEnv) (ilTyparSubst: layout list) (ty: ILType) : layout = + let rec layoutILType (denv: DisplayEnv) (ilTyparSubst: Layout list) (ty: ILType) : Layout = match ty with | ILType.Void -> WordL.structUnit // These are type-theoretically totally different type-theoretically `void` is Fin 0 and `unit` is Fin (S 0) ... but, this looks like as close as we can get. | ILType.Array (sh, t) -> layoutILType denv ilTyparSubst t ^^ layoutILArrayShape sh @@ -185,7 +375,7 @@ module private PrintIL = | ILType.Modified (_, _, t) -> layoutILType denv ilTyparSubst t // Just recurse through them to the contained ILType /// Layout a function pointer signature using type-only-F#-style. No argument names are printed. - and private layoutILCallingSignature denv ilTyparSubst cons (signature: ILCallingSignature) = + and layoutILCallingSignature denv ilTyparSubst cons (signature: ILCallingSignature) = // We need a special case for // constructors (Their return types are reported as `void`, but this is // incorrect; so if we're dealing with a constructor we require that the @@ -194,7 +384,7 @@ module private PrintIL = let res = match cons with | Some className -> - let names = SplitNamesForILPath (PrettyNaming.DemangleGenericTypeName className) + let names = SplitNamesForILPath (DemangleGenericTypeName className) // special case for constructor return-type (viz., the class itself) layoutILTypeRefName denv names ^^ (pruneParams className ilTyparSubst |> paramsL) | None -> @@ -205,124 +395,16 @@ module private PrintIL = | [x] -> x ^^ WordL.arrow ^^ res | _ -> sepListL WordL.star args ^^ WordL.arrow ^^ res - /// Layout a function pointer signature using type-only-F#-style. No argument names are printed. - // - // Note, this duplicates functionality in formatParamDataToBuffer - and layoutILParameter denv ilTyparSubst (p: ILParameter) = - let preL = - let isParamArray = TryFindILAttribute denv.g.attrib_ParamArrayAttribute p.CustomAttrs - match isParamArray, p.Name, p.IsOptional with - // Layout an optional argument - | _, Some nm, true -> LeftL.questionMark ^^ sepL (tagParameter nm) ^^ SepL.colon - // Layout an unnamed argument - | _, None, _ -> LeftL.colon - // Layout a named argument - | true, Some nm, _ -> - layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute ^^ wordL (tagParameter nm) ^^ SepL.colon - | false, Some nm, _ -> leftL (tagParameter nm) ^^ SepL.colon - preL ^^ (layoutILType denv ilTyparSubst p.Type) - - - /// Layout a function pointer signature using type-only-F#-style. No argument names are printed. - and layoutILParameters denv ilTyparSubst cons (parameters: ILParameters, retType: ILType) = - // We need a special case for constructors (Their return types are reported as `void`, but this is - // incorrect; so if we're dealing with a constructor we require that the - // return type be passed along as the `cons` parameter.) - let res = - match cons with - | Some className -> - let names = SplitNamesForILPath (PrettyNaming.DemangleGenericTypeName className) - layoutILTypeRefName denv names ^^ (pruneParams className ilTyparSubst |> paramsL) - | None -> retType |> layoutILType denv ilTyparSubst - - match parameters with - | [] -> WordL.structUnit ^^ WordL.arrow ^^ res - | [x] -> layoutILParameter denv ilTyparSubst x ^^ WordL.arrow ^^ res - | args -> sepListL WordL.star (List.map (layoutILParameter denv ilTyparSubst) args) ^^ WordL.arrow ^^ res - - - /// Layout a method's signature using type-only-F#-style. No argument names are printed. - /// - /// In the case that we've a constructor, we - /// pull off the class name from the `path`; naturally, it's the - /// most-deeply-nested element. - // - // For C# and provided members: - // new: argType1 * ... * argTypeN -> retType - // Method: argType1 * ... * argTypeN -> retType - // - let layoutILMethodDef denv ilTyparSubst className (m: ILMethodDef) = - let myParms = m.GenericParams |> layoutILGenericParameterDefs - let ilTyparSubst = ilTyparSubst @ myParms - let name = adjustILMethodName m.Name - let (nameL, isCons) = - match () with - | _ when m.IsConstructor -> (WordL.keywordNew, Some className) // we need the unadjusted name here to be able to grab the number of generic parameters - | _ when m.IsStatic -> (WordL.keywordStatic ^^ WordL.keywordMember ^^ wordL (tagMethod name) ^^ (myParms |> paramsL), None) - | _ -> (WordL.keywordMember ^^ wordL (tagMethod name) ^^ (myParms |> paramsL), None) - let signatureL = (m.Parameters, m.Return.Type) |> layoutILParameters denv ilTyparSubst isCons - nameL ^^ WordL.colon ^^ signatureL - - let layoutILFieldDef (denv: DisplayEnv) (ilTyparSubst: layout list) (f: ILFieldDef) = - let staticL = if f.IsStatic then WordL.keywordStatic else emptyL - let name = adjustILName f.Name - let nameL = wordL (tagField name) - let typL = layoutILType denv ilTyparSubst f.FieldType - staticL ^^ WordL.keywordVal ^^ nameL ^^ WordL.colon ^^ typL - - let layoutILEventDef denv ilTyparSubst (e: ILEventDef) = - let staticL = if isStaticILEvent e then WordL.keywordStatic else emptyL - let name = adjustILName e.Name - let nameL = wordL (tagEvent name) - let typL = - match e.EventType with - | Some t -> layoutILType denv ilTyparSubst t - | _ -> emptyL - staticL ^^ WordL.keywordEvent ^^ nameL ^^ WordL.colon ^^ typL - - let layoutILPropertyDef denv ilTyparSubst (p: ILPropertyDef) = - let staticL = if p.CallingConv = ILThisConvention.Static then WordL.keywordStatic else emptyL - let name = adjustILName p.Name - let nameL = wordL (tagProperty name) - - let layoutGetterType (getterRef: ILMethodRef) = - if isNil getterRef.ArgTypes then - layoutILType denv ilTyparSubst getterRef.ReturnType - else - layoutILCallingSignature denv ilTyparSubst None getterRef.CallingSignature - - let layoutSetterType (setterRef: ILMethodRef) = - let argTypes = setterRef.ArgTypes - if isNil argTypes then - emptyL // shouldn't happen - else - let frontArgs, lastArg = List.frontAndBack argTypes - let argsL = frontArgs |> List.map (layoutILType denv ilTyparSubst) |> sepListL WordL.star - argsL ^^ WordL.arrow ^^ (layoutILType denv ilTyparSubst lastArg) - - let typL = - match p.GetMethod, p.SetMethod with - | None, None -> layoutILType denv ilTyparSubst p.PropertyType // shouldn't happen - | Some getterRef, _ -> layoutGetterType getterRef - | None, Some setterRef -> layoutSetterType setterRef - - let specGetSetL = - match p.GetMethod, p.SetMethod with - | None, None - | Some _, None -> emptyL - | None, Some _ -> WordL.keywordWith ^^ WordL.keywordSet - | Some _, Some _ -> WordL.keywordWith ^^ WordL.keywordGet ^^ RightL.comma ^^ WordL.keywordSet - staticL ^^ WordL.keywordMember ^^ nameL ^^ WordL.colon ^^ typL ^^ specGetSetL - let layoutILFieldInit x = let textOpt = match x with | Some init -> match init with | ILFieldInit.Bool x -> - if x - then Some Literals.keywordTrue - else Some Literals.keywordFalse + if x then + Some keywordTrue + else + Some keywordFalse | ILFieldInit.Char c -> ("'" + (char c).ToString () + "'") |> (tagStringLiteral >> Some) | ILFieldInit.Int8 x -> ((x |> int32 |> string) + "y") |> (tagNumericLiteral >> Some) | ILFieldInit.Int16 x -> ((x |> int32 |> string) + "s") |> (tagNumericLiteral >> Some) @@ -333,18 +415,12 @@ module private PrintIL = | ILFieldInit.UInt32 x -> (x |> int64 |> string) + "u" |> (tagNumericLiteral >> Some) | ILFieldInit.UInt64 x -> ((x |> int64 |> string) + "UL") |> (tagNumericLiteral >> Some) | ILFieldInit.Single d -> - let s = d.ToString ("g12", System.Globalization.CultureInfo.InvariantCulture) - let s = - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s - then s + ".0" - else s + let s = d.ToString ("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s (s + "f") |> (tagNumericLiteral >> Some) | ILFieldInit.Double d -> - let s = d.ToString ("g12", System.Globalization.CultureInfo.InvariantCulture) - let s = - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s - then (s + ".0") - else s + let s = d.ToString ("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s s |> (tagNumericLiteral >> Some) | _ -> None | None -> None @@ -352,196 +428,16 @@ module private PrintIL = | None -> WordL.equals ^^ (comment "value unavailable") | Some s -> WordL.equals ^^ wordL s - let layoutILEnumDefParts nm litVal = - WordL.bar ^^ wordL (tagEnum (adjustILName nm)) ^^ layoutILFieldInit litVal - - let layoutILEnumDef (f: ILFieldDef) = layoutILEnumDefParts f.Name f.LiteralValue - - // filtering methods for hiding things we oughtn't show - let isStaticILProperty (p: ILPropertyDef) = - match p.GetMethod, p.SetMethod with - | Some getter, _ -> getter.CallingSignature.CallingConv.IsStatic - | None, Some setter -> setter.CallingSignature.CallingConv.IsStatic - | None, None -> true - - let isPublicILMethod (m: ILMethodDef) = - (m.Access = ILMemberAccess.Public) + let layoutILEnumCase nm litVal = + let nameL = ConvertNameToDisplayLayout (tagEnum >> wordL) nm + WordL.bar ^^ nameL ^^ layoutILFieldInit litVal - let isPublicILEvent typeDef (e: ILEventDef) = - try - isPublicILMethod(resolveILMethodRef typeDef e.AddMethod) && - isPublicILMethod(resolveILMethodRef typeDef e.RemoveMethod) - with _ -> - false - - let isPublicILProperty typeDef (m: ILPropertyDef) = - try - match m.GetMethod with - | Some ilMethRef -> isPublicILMethod (resolveILMethodRef typeDef ilMethRef) - | None -> - match m.SetMethod with - | None -> false - | Some ilMethRef -> isPublicILMethod (resolveILMethodRef typeDef ilMethRef) - // resolveILMethodRef is a possible point of failure if Abstract IL type equality checking fails - // to link the method ref to a method def for some reason, e.g. some feature of IL type - // equality checking has not been implemented. Since this is just intellisense pretty printing code - // it is better to swallow the exception here, though we don't know of any - // specific cases where this happens - with _ -> - false - - let isPublicILCtor (m: ILMethodDef) = - (m.Access = ILMemberAccess.Public && m.IsConstructor) - - let isNotSpecialName (m: ILMethodDef) = - not m.IsSpecialName - - let isPublicILField (f: ILFieldDef) = - (f.Access = ILMemberAccess.Public) - - let isPublicILTypeDef (c: ILTypeDef) : bool = - match c.Access with - | ILTypeDefAccess.Public - | ILTypeDefAccess.Nested ILMemberAccess.Public -> true - | _ -> false - - let isShowEnumField (f: ILFieldDef) : bool = f.Name <> "value__" // this appears to be the hard-coded underlying storage field - let noShow = set [ "System.Object" ; "Object"; "System.ValueType" ; "ValueType"; "obj" ] // hide certain 'obvious' base classes - let isShowBase (n: layout) : bool = - not (noShow.Contains(showL n)) - - let rec layoutILTypeDef (denv: DisplayEnv) (typeDef: ILTypeDef) : layout = - let ilTyparSubst = typeDef.GenericParams |> layoutILGenericParameterDefs - - let renderL pre body post = - match pre with - | Some pre -> - match body with - | [] -> emptyL // empty type - | _ -> (pre @@-- aboveListL body) @@ post - | None -> - aboveListL body - - if typeDef.IsClass || typeDef.IsStruct || typeDef.IsInterface then - let pre = - if typeDef.IsStruct then Some WordL.keywordStruct - else None - - let baseTypeL = - [ match typeDef.Extends with - | Some b -> - let baseName = layoutILType denv ilTyparSubst b - if isShowBase baseName then - yield WordL.keywordInherit ^^ baseName - | None -> - // for interface show inherited interfaces - if typeDef.IsInterface then - for b in typeDef.Implements do - let baseName = layoutILType denv ilTyparSubst b - if isShowBase baseName then - yield WordL.keywordInherit ^^ baseName ] - - let memberBlockLs (fieldDefs: ILFieldDefs, methodDefs: ILMethodDefs, propertyDefs: ILPropertyDefs, eventDefs: ILEventDefs) = - let ctors = - methodDefs.AsList - |> List.filter isPublicILCtor - |> List.sortBy (fun md -> md.Parameters.Length) - |> shrinkOverloads (layoutILMethodDef denv ilTyparSubst typeDef.Name) (fun _ xL -> xL) - - let fields = - fieldDefs.AsList - |> List.filter isPublicILField - |> List.map (layoutILFieldDef denv ilTyparSubst) - - let props = - propertyDefs.AsList - |> List.filter (isPublicILProperty typeDef) - |> List.map (fun pd -> (pd.Name, pd.Args.Length), layoutILPropertyDef denv ilTyparSubst pd) - - let events = - eventDefs.AsList - |> List.filter (isPublicILEvent typeDef) - |> List.map (layoutILEventDef denv ilTyparSubst) - - let meths = - methodDefs.AsList - |> List.filter isPublicILMethod - |> List.filter isNotSpecialName - |> List.map (fun md -> (md.Name, md.Parameters.Length), md) - // collect into overload groups - |> List.groupBy (fst >> fst) - |> List.collect (fun (_, group) -> group |> List.sortBy fst |> shrinkOverloads (snd >> layoutILMethodDef denv ilTyparSubst typeDef.Name) (fun x xL -> (fst x, xL))) - - let members = - (props @ meths) - |> List.sortBy fst - |> List.map snd // (properties and members) are sorted by name/arity - - ctors @ fields @ members @ events - - let bodyStatic = - memberBlockLs - (typeDef.Fields.AsList |> List.filter (fun fd -> fd.IsStatic) |> mkILFields, - typeDef.Methods.AsList |> List.filter (fun md -> md.IsStatic) |> mkILMethods, - typeDef.Properties.AsList |> List.filter isStaticILProperty |> mkILProperties, - typeDef.Events.AsList |> List.filter isStaticILEvent |> mkILEvents) - - let bodyInstance = - memberBlockLs - (typeDef.Fields.AsList |> List.filter (fun fd -> not (fd.IsStatic)) |> mkILFields, - typeDef.Methods.AsList |> List.filter (fun md -> not (md.IsStatic)) |> mkILMethods, - typeDef.Properties.AsList |> List.filter (fun pd -> not (isStaticILProperty pd)) |> mkILProperties, - typeDef.Events.AsList |> List.filter (fun ed -> not (isStaticILEvent ed)) |> mkILEvents ) - - let body = bodyInstance @ bodyStatic // instance "member" before "static member" - - // Only show at most maxMembers members... - let body = applyMaxMembers denv.maxMembers body - - let types = - typeDef.NestedTypes.AsList - |> List.filter isPublicILTypeDef - |> List.sortBy(fun t -> adjustILName t.Name) - |> List.map (layoutILNestedClassDef denv) - - let post = WordL.keywordEnd - renderL pre (baseTypeL @ body @ types ) post - - elif typeDef.IsEnum then - let fldsL = - typeDef.Fields.AsList - |> List.filter isShowEnumField - |> List.map layoutILEnumDef - |> applyMaxMembers denv.maxMembers - - renderL None fldsL emptyL - - else // Delegate - let rhs = - match typeDef.Methods.AsList |> List.filter (fun m -> m.Name = "Invoke") with // the delegate delegates to the type of `Invoke` - | m :: _ -> layoutILCallingSignature denv ilTyparSubst None m.CallingSignature - | _ -> comment "`Invoke` method could not be found" - WordL.keywordDelegate ^^ WordL.keywordOf ^^ rhs - - and layoutILNestedClassDef (denv: DisplayEnv) (typeDef: ILTypeDef) = - let name = adjustILName typeDef.Name - let nameL = wordL (tagClass name) - let ilTyparSubst = typeDef.GenericParams |> layoutILGenericParameterDefs - let paramsL = pruneParams typeDef.Name ilTyparSubst |> paramsL - if denv.suppressNestedTypes then - WordL.keywordNested ^^ WordL.keywordType ^^ nameL ^^ paramsL - else - let pre = WordL.keywordNested ^^ WordL.keywordType ^^ nameL ^^ paramsL - let body = layoutILTypeDef denv typeDef - (pre ^^ WordL.equals) @@-- body - - -module private PrintTypes = +module PrintTypes = // Note: We need nice printing of constants in order to print literals and attributes let layoutConst g ty c = let str = match c with - | Const.Bool x -> if x then Literals.keywordTrue else Literals.keywordFalse + | Const.Bool x -> if x then keywordTrue else keywordFalse | Const.SByte x -> (x |> string)+"y" |> tagNumericLiteral | Const.Byte x -> (x |> string)+"uy" |> tagNumericLiteral | Const.Int16 x -> (x |> string)+"s" |> tagNumericLiteral @@ -553,15 +449,13 @@ module private PrintTypes = | Const.IntPtr x -> (x |> string)+"n" |> tagNumericLiteral | Const.UIntPtr x -> (x |> string)+"un" |> tagNumericLiteral | Const.Single d -> - ((let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit(c) || c = '-') s - then s + ".0" - else s) + "f") |> tagNumericLiteral + let s = d.ToString("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s + (s + "f") |> tagNumericLiteral | Const.Double d -> - let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - (if String.forall (fun c -> System.Char.IsDigit(c) || c = '-') s - then s + ".0" - else s) |> tagNumericLiteral + let s = d.ToString("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s + s |> tagNumericLiteral | Const.Char c -> "'" + c.ToString() + "'" |> tagStringLiteral | Const.String bs -> "\"" + bs + "\"" |> tagNumericLiteral | Const.Unit -> "()" |> tagPunctuation @@ -590,23 +484,26 @@ module private PrintTypes = let layoutTyconRef denv tycon = layoutTyconRefImpl false denv tycon /// Layout the flags of a member - let layoutMemberFlags memFlags = + let layoutMemberFlags (memFlags: SynMemberFlags) = let stat = - if memFlags.IsInstance || (memFlags.MemberKind = MemberKind.Constructor) then emptyL + if memFlags.IsInstance || (memFlags.MemberKind = SynMemberKind.Constructor) then emptyL else WordL.keywordStatic + let stat = - if memFlags.IsDispatchSlot then stat ++ WordL.keywordAbstract - elif memFlags.IsOverrideOrExplicitImpl then stat ++ WordL.keywordOverride + if memFlags.IsOverrideOrExplicitImpl then stat ++ WordL.keywordOverride else stat + let stat = - if memFlags.IsOverrideOrExplicitImpl then stat else - match memFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.PropertyGetSet -> stat - | MemberKind.Member - | MemberKind.PropertyGet - | MemberKind.PropertySet -> stat ++ WordL.keywordMember + if memFlags.IsDispatchSlot then stat ++ WordL.keywordAbstract + elif memFlags.IsOverrideOrExplicitImpl then stat + else + match memFlags.MemberKind with + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.PropertyGetSet -> stat + | SynMemberKind.Member + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet -> stat ++ WordL.keywordMember // let stat = if memFlags.IsFinal then stat ++ wordL "final" else stat in stat @@ -614,7 +511,7 @@ module private PrintTypes = /// Layout a single attribute arg, following the cases of 'gen_attr_arg' in ilxgen.fs /// This is the subset of expressions we display in the NicePrint pretty printer /// See also dataExprL - there is overlap between these that should be removed - let rec private layoutAttribArg denv arg = + let rec layoutAttribArg denv arg = match arg with | Expr.Const (c, _, ty) -> if isEnumTy denv.g ty then @@ -643,35 +540,22 @@ module private PrintTypes = | EnumExpr denv.g arg1 -> WordL.keywordEnum ++ bracketL (layoutAttribArg denv arg1) - | _ -> comment "(* unsupported attribute argument *)" /// Layout arguments of an attribute 'arg1, ..., argN' - and private layoutAttribArgs denv args = - sepListL (rightL (tagPunctuation ",")) (List.map (fun (AttribExpr(e1, _)) -> layoutAttribArg denv e1) args) + and layoutAttribArgs denv args = + let argsL = args |> List.map (fun (AttribExpr(e1, _)) -> layoutAttribArg denv e1) + sepListL (rightL (tagPunctuation ",")) argsL /// Layout an attribute 'Type(arg1, ..., argN)' // // REVIEW: we are ignoring "props" here - and layoutAttrib denv (Attrib(_, k, args, _props, _, _, _)) = + and layoutAttrib denv (Attrib(tcref, _, args, _props, _, _, _)) = + let tcrefL = layoutTyconRefImpl true denv tcref let argsL = bracketL (layoutAttribArgs denv args) - match k with - | ILAttrib ilMethRef -> - let trimmedName = - let name = ilMethRef.DeclaringTypeRef.Name - if name.EndsWithOrdinal("Attribute") then - String.dropSuffix name "Attribute" - else - name - let tref = ilMethRef.DeclaringTypeRef - let tref = ILTypeRef.Create(scope= tref.Scope, enclosing=tref.Enclosing, name=trimmedName) - PrintIL.layoutILTypeRef denv tref ++ argsL - | FSAttrib vref -> - // REVIEW: this is not trimming "Attribute" - let _, _, rty, _ = GetTypeOfMemberInMemberForm denv.g vref - let rty = GetFSharpViewOfReturnType denv.g rty - let tcref = tcrefOfAppTy denv.g rty - layoutTyconRef denv tcref ++ argsL + match args with + | [] -> tcrefL + | _ -> tcrefL ++ argsL and layoutILAttribElement denv arg = match arg with @@ -681,7 +565,7 @@ module private PrintTypes = | ILAttribElem.Char x -> wordL (tagStringLiteral ("'" + x.ToString() + "'" )) | ILAttribElem.SByte x -> wordL (tagNumericLiteral ((x |> string)+"y")) | ILAttribElem.Int16 x -> wordL (tagNumericLiteral ((x |> string)+"s")) - | ILAttribElem.Int32 x -> wordL (tagNumericLiteral ((x |> string))) + | ILAttribElem.Int32 x -> wordL (tagNumericLiteral (x |> string)) | ILAttribElem.Int64 x -> wordL (tagNumericLiteral ((x |> string)+"L")) | ILAttribElem.Byte x -> wordL (tagNumericLiteral ((x |> string)+"uy")) | ILAttribElem.UInt16 x -> wordL (tagNumericLiteral ((x |> string)+"us")) @@ -689,17 +573,15 @@ module private PrintTypes = | ILAttribElem.UInt64 x -> wordL (tagNumericLiteral ((x |> string)+"UL")) | ILAttribElem.Single x -> let str = - let s = x.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - (if String.forall (fun c -> System.Char.IsDigit(c) || c = '-') s - then s + ".0" - else s) + "f" + let s = x.ToString("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s + s + "f" wordL (tagNumericLiteral str) | ILAttribElem.Double x -> let str = - let s = x.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit(c) || c = '-') s - then s + ".0" - else s + let s = x.ToString("g12", CultureInfo.InvariantCulture) + let s = ensureFloat s + s wordL (tagNumericLiteral str) | ILAttribElem.Null -> wordL (tagKeyword "null") | ILAttribElem.Array (_, xs) -> @@ -716,38 +598,58 @@ module private PrintTypes = PrintIL.layoutILType denv [] ty ++ argsL /// Layout '[]' above another block - and layoutAttribs denv ty kind attrs restL = + and layoutAttribs denv startOpt isLiteral kind attrs restL = - if denv.showAttributes then - // Don't display DllImport attributes in generated signatures - let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_DllImportAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_ContextStaticAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_ThreadStaticAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_EntryPointAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_MarshalAsAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_ReflectedDefinitionAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_StructLayoutAttribute >> not) - let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_AutoSerializableAttribute >> not) + let attrsL = + [ if denv.showAttributes then + // Don't display DllImport and other attributes in generated signatures + let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_DllImportAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_ContextStaticAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_ThreadStaticAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_EntryPointAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttributeOpt denv.g denv.g.attrib_MarshalAsAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_ReflectedDefinitionAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_StructLayoutAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_AutoSerializableAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_LiteralAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_MeasureAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_StructAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_ClassAttribute >> not) + let attrs = attrs |> List.filter (IsMatchingFSharpAttribute denv.g denv.g.attrib_InterfaceAttribute >> not) + + for attr in attrs do + layoutAttrib denv attr + + // Always show the 'Struct', 'Class, 'Interface' attributes if needed + match startOpt with + | Some "struct" -> + wordL (tagClass "Struct") + | Some "class" -> + wordL (tagClass "Class") + | Some "interface" -> + wordL (tagClass "Interface") + | _ -> + () + + // Always show the 'Literal' attribute if needed + if isLiteral then + wordL (tagClass "Literal") + + // Always show the 'Measure' attribute if needed + if kind = TyparKind.Measure then + wordL (tagClass "Measure") + ] + + match attrsL with + | [] -> restL + | _ -> squareAngleL (sepListL (rightL (tagPunctuation ";")) attrsL) @@ restL - match attrs with - | [] -> restL - | _ -> - squareAngleL (sepListL (rightL (tagPunctuation ";")) (List.map (layoutAttrib denv) attrs)) @@ - restL - elif Tastops.isStructRecordOrUnionTyconTy denv.g ty || - ((Tastops.isUnionTy denv.g ty || Tastops.isRecdTy denv.g ty) && HasFSharpAttribute denv.g denv.g.attrib_StructAttribute attrs) then - squareAngleL (wordL (tagClass "Struct")) @@ restL - else - match kind with - | TyparKind.Type -> restL - | TyparKind.Measure -> squareAngleL (wordL (tagClass "Measure")) @@ restL - and layoutTyparAttribs denv kind attrs restL = match attrs, kind with | [], TyparKind.Type -> restL | _, _ -> squareAngleL (sepListL (rightL (tagPunctuation ";")) ((match kind with TyparKind.Type -> [] | TyparKind.Measure -> [wordL (tagText "Measure")]) @ List.map (layoutAttrib denv) attrs)) ^^ restL - and private layoutTyparRef denv (typar: Typar) = + and layoutTyparRef denv (typar: Typar) = wordL (tagTypeParameter (sprintf "%s%s%s" @@ -764,12 +666,12 @@ module private PrintTypes = /// ('a :> Type) - inplace coercion constraint not singleton. /// ('a.opM: S->T) - inplace operator constraint. /// - and private layoutTyparRefWithInfo denv (env: SimplifyTypes.TypeSimplificationInfo) (typar: Typar) = + and layoutTyparRefWithInfo denv (env: SimplifyTypes.TypeSimplificationInfo) (typar: Typar) = let varL = layoutTyparRef denv typar let varL = if denv.showAttributes then layoutTyparAttribs denv typar.Kind typar.Attribs varL else varL match Zmap.tryFind typar env.inplaceConstraints with - | Some (typarConstraintTy) -> + | Some typarConstraintTy -> if Zset.contains typar env.singletons then leftL (tagPunctuation "#") ^^ layoutTypeWithInfo denv env typarConstraintTy else @@ -804,70 +706,82 @@ module private PrintTypes = wordL (tagKeyword "when") ^^ sepListL (wordL (tagKeyword "and")) cxsL /// Layout constraints, taking TypeSimplificationInfo into account - and private layoutConstraintWithInfo denv env (tp, tpc) = - let longConstraintPrefix l = layoutTyparRefWithInfo denv env tp ^^ WordL.colon ^^ l + and layoutConstraintWithInfo denv env (tp, tpc) = + let longConstraintPrefix l = (layoutTyparRefWithInfo denv env tp |> addColonL) ^^ l match tpc with | TyparConstraint.CoercesTo(tpct, _) -> [layoutTyparRefWithInfo denv env tp ^^ wordL (tagOperator ":>") --- layoutTypeWithInfo denv env tpct] + | TyparConstraint.MayResolveMember(traitInfo, _) -> [layoutTraitWithInfo denv env traitInfo] + | TyparConstraint.DefaultsTo(_, ty, _) -> - if denv.showTyparDefaultConstraints then [wordL (tagKeyword "default") ^^ layoutTyparRefWithInfo denv env tp ^^ WordL.colon ^^ layoutTypeWithInfo denv env ty] + if denv.showTyparDefaultConstraints then + [wordL (tagKeyword "default") ^^ (layoutTyparRefWithInfo denv env tp |> addColonL) ^^ layoutTypeWithInfo denv env ty] else [] + | TyparConstraint.IsEnum(ty, _) -> if denv.shortConstraints then [wordL (tagKeyword "enum")] else [longConstraintPrefix (layoutTypeAppWithInfoAndPrec denv env (wordL (tagKeyword "enum")) 2 true [ty])] + | TyparConstraint.SupportsComparison _ -> if denv.shortConstraints then [wordL (tagKeyword "comparison")] else [wordL (tagKeyword "comparison") |> longConstraintPrefix] + | TyparConstraint.SupportsEquality _ -> if denv.shortConstraints then [wordL (tagKeyword "equality")] else [wordL (tagKeyword "equality") |> longConstraintPrefix] + | TyparConstraint.IsDelegate(aty, bty, _) -> if denv.shortConstraints then [WordL.keywordDelegate] else - [layoutTypeAppWithInfoAndPrec denv env (WordL.keywordDelegate) 2 true [aty;bty] |> longConstraintPrefix] + [layoutTypeAppWithInfoAndPrec denv env WordL.keywordDelegate 2 true [aty;bty] |> longConstraintPrefix] + | TyparConstraint.SupportsNull _ -> [wordL (tagKeyword "null") |> longConstraintPrefix] + | TyparConstraint.IsNonNullableStruct _ -> if denv.shortConstraints then [wordL (tagText "value type")] else [WordL.keywordStruct |> longConstraintPrefix] + | TyparConstraint.IsUnmanaged _ -> if denv.shortConstraints then [wordL (tagKeyword "unmanaged")] else [wordL (tagKeyword "unmanaged") |> longConstraintPrefix] + | TyparConstraint.IsReferenceType _ -> if denv.shortConstraints then [wordL (tagText "reference type")] else [(wordL (tagKeyword "not") ^^ wordL(tagKeyword "struct")) |> longConstraintPrefix] + | TyparConstraint.SimpleChoice(tys, _) -> [bracketL (sepListL (sepL (tagPunctuation "|")) (List.map (layoutTypeWithInfo denv env) tys)) |> longConstraintPrefix] + | TyparConstraint.RequiresDefaultConstructor _ -> if denv.shortConstraints then [wordL (tagKeyword "default") ^^ wordL (tagKeyword "constructor")] else [bracketL ( - wordL (tagKeyword "new") ^^ - wordL (tagPunctuation ":") ^^ + (WordL.keywordNew |> addColonL) ^^ WordL.structUnit ^^ WordL.arrow ^^ (layoutTyparRefWithInfo denv env tp)) |> longConstraintPrefix] - and private layoutTraitWithInfo denv env (TTrait(tys, nm, memFlags, argtys, rty, _)) = - let nm = DemangleOperatorName nm + and layoutTraitWithInfo denv env (TTrait(tys, nm, memFlags, argtys, rty, _)) = + let nameL = ConvertValNameToDisplayLayout false (tagMember >> wordL) nm if denv.shortConstraints then - WordL.keywordMember ^^ wordL (tagMember nm) + WordL.keywordMember ^^ nameL else let rty = GetFSharpViewOfReturnType denv.g rty let stat = layoutMemberFlags memFlags @@ -876,13 +790,14 @@ module private PrintTypes = match tys with | [ty] -> layoutTypeWithInfo denv env ty | tys -> bracketL (layoutTypesWithInfoAndPrec denv env 2 (wordL (tagKeyword "or")) tys) - tysL ^^ wordL (tagPunctuation ":") --- - bracketL (stat ++ wordL (tagMember nm) ^^ wordL (tagPunctuation ":") --- - ((layoutTypesWithInfoAndPrec denv env 2 (wordL (tagPunctuation "*")) argtys --- wordL (tagPunctuation "->")) --- (layoutTypeWithInfo denv env rty))) + let argtysL = layoutTypesWithInfoAndPrec denv env 2 (wordL (tagPunctuation "*")) argtys + let rtyL = layoutReturnType denv env rty + let sigL = curriedLayoutsL "->" [argtysL] rtyL + (tysL |> addColonL) --- bracketL (stat ++ (nameL |> addColonL) --- sigL) - /// Layout a unit expression - and private layoutMeasure denv unt = + /// Layout a unit of measure expression + and layoutMeasure denv unt = let sortVars vs = vs |> List.sortBy (fun (v: Typar, _) -> v.DisplayName) let sortCons cs = cs |> List.sortBy (fun (c: TyconRef, _) -> c.DisplayName) let negvs, posvs = ListMeasureVarOccsWithNonZeroExponents unt |> sortVars |> List.partition (fun (_, e) -> SignRational e < 0) @@ -900,7 +815,7 @@ module private PrintTypes = | _ -> prefix ^^ sepL (tagPunctuation "/") ^^ (if List.length negvs + List.length negcs > 1 then sepL (tagPunctuation "(") ^^ postfix ^^ sepL (tagPunctuation ")") else postfix) /// Layout type arguments, either NAME or (ty, ..., ty) NAME *) - and private layoutTypeAppWithInfoAndPrec denv env tcL prec prefix args = + and layoutTypeAppWithInfoAndPrec denv env tcL prec prefix args = if prefix then match args with | [] -> tcL @@ -914,31 +829,30 @@ module private PrintTypes = /// Layout a type, taking precedence into account to insert brackets where needed and layoutTypeWithInfoAndPrec denv env prec ty = - + let g = denv.g match stripTyparEqns ty with // Always prefer to format 'byref' as 'inref' - | ty when isInByrefTy denv.g ty && (match ty with TType_app (tc, _) when denv.g.inref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) -> - layoutTypeWithInfoAndPrec denv env prec (mkInByrefTy denv.g (destByrefTy denv.g ty)) + | ty when isInByrefTy g ty && (match ty with TType_app (tc, _) when g.inref_tcr.CanDeref && tyconRefEq g tc g.byref2_tcr -> true | _ -> false) -> + layoutTypeWithInfoAndPrec denv env prec (mkInByrefTy g (destByrefTy g ty)) // Always prefer to format 'byref' as 'outref' - | ty when isOutByrefTy denv.g ty && (match ty with TType_app (tc, _) when denv.g.outref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) -> - layoutTypeWithInfoAndPrec denv env prec (mkOutByrefTy denv.g (destByrefTy denv.g ty)) + | ty when isOutByrefTy g ty && (match ty with TType_app (tc, _) when g.outref_tcr.CanDeref && tyconRefEq g tc g.byref2_tcr -> true | _ -> false) -> + layoutTypeWithInfoAndPrec denv env prec (mkOutByrefTy g (destByrefTy g ty)) // Always prefer to format 'byref' as 'byref' - | ty when isByrefTy denv.g ty && (match ty with TType_app (tc, _) when denv.g.byref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) -> - layoutTypeWithInfoAndPrec denv env prec (mkByrefTy denv.g (destByrefTy denv.g ty)) + | ty when isByrefTy g ty && (match ty with TType_app (tc, _) when g.byref_tcr.CanDeref && tyconRefEq g tc g.byref2_tcr -> true | _ -> false) -> + layoutTypeWithInfoAndPrec denv env prec (mkByrefTy g (destByrefTy g ty)) // Always prefer 'float' to 'float<1>' - | TType_app (tc, args) when tc.IsMeasureableReprTycon && List.forall (isDimensionless denv.g) args -> - layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided denv.g tc args) - - // Layout a type application - | TType_app (tc, args) -> - layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec tc.IsPrefixDisplay args + | TType_app (tc, args) when tc.IsMeasureableReprTycon && List.forall (isDimensionless g) args -> + layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided g tc args) - | TType_ucase (UCRef(tc, _), args) -> - layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec tc.IsPrefixDisplay args + // Layout a type application + | TType_ucase (UnionCaseRef(tc, _), args) + | TType_app (tc, args) -> + let prefix = usePrefix denv tc + layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec prefix args // Layout a tuple type | TType_anon (anonInfo, tys) -> @@ -950,10 +864,11 @@ module private PrintTypes = // Layout a tuple type | TType_tuple (tupInfo, t) -> + let elsL = layoutTypesWithInfoAndPrec denv env 2 (wordL (tagPunctuation "*")) t if evalTupInfoIsStruct tupInfo then - WordL.keywordStruct --- bracketL (layoutTypesWithInfoAndPrec denv env 2 (wordL (tagPunctuation "*")) t) + WordL.keywordStruct --- bracketL elsL else - bracketIfL (prec <= 2) (layoutTypesWithInfoAndPrec denv env 2 (wordL (tagPunctuation "*")) t) + bracketIfL (prec <= 2) elsL // Layout a first-class generic type. | TType_forall (tps, tau) -> @@ -961,15 +876,14 @@ module private PrintTypes = match tps with | [] -> tauL | [h] -> layoutTyparRefWithInfo denv env h ^^ rightL (tagPunctuation ".") --- tauL - | (h :: t) -> spaceListL (List.map (layoutTyparRefWithInfo denv env) (h :: t)) ^^ rightL (tagPunctuation ".") --- tauL + | h :: t -> spaceListL (List.map (layoutTyparRefWithInfo denv env) (h :: t)) ^^ rightL (tagPunctuation ".") --- tauL - // Layout a function type. | TType_fun _ -> - let rec loop soFarL ty = - match stripTyparEqns ty with - | TType_fun (dty, rty) -> loop (soFarL --- (layoutTypeWithInfoAndPrec denv env 4 dty ^^ wordL (tagPunctuation "->"))) rty - | rty -> soFarL --- layoutTypeWithInfoAndPrec denv env 5 rty - bracketIfL (prec <= 4) (loop emptyL ty) + let argtys, rty = stripFunTy g ty + let rtyL = layoutTypeWithInfoAndPrec denv env 5 rty + let argtysL = argtys |> List.map (layoutTypeWithInfoAndPrec denv env 4) + let funcTyL = curriedLayoutsL "->" argtysL rtyL + bracketIfL (prec <= 4) funcTyL // Layout a type variable . | TType_var r -> @@ -978,55 +892,78 @@ module private PrintTypes = | TType_measure unt -> layoutMeasure denv unt /// Layout a list of types, separated with the given separator, either '*' or ',' - and private layoutTypesWithInfoAndPrec denv env prec sep typl = + and layoutTypesWithInfoAndPrec denv env prec sep typl = sepListL sep (List.map (layoutTypeWithInfoAndPrec denv env prec) typl) + and layoutReturnType denv env rty = layoutTypeWithInfoAndPrec denv env 4 rty + /// Layout a single type, taking TypeSimplificationInfo into account - and private layoutTypeWithInfo denv env ty = + and layoutTypeWithInfo denv env ty = layoutTypeWithInfoAndPrec denv env 5 ty and layoutType denv ty = layoutTypeWithInfo denv SimplifyTypes.typeSimplificationInfo0 ty + // Format each argument, including its name and type + let layoutArgInfo denv env (ty, argInfo: ArgReprInfo) = + let g = denv.g + + // Detect an optional argument + let isOptionalArg = HasFSharpAttribute g g.attrib_OptionalArgumentAttribute argInfo.Attribs + let isParamArray = HasFSharpAttribute g g.attrib_ParamArrayAttribute argInfo.Attribs + + match argInfo.Name, isOptionalArg, isParamArray, tryDestOptionTy g ty with + // Layout an optional argument + | Some id, true, _, ValueSome ty -> + let idL = ConvertValNameToDisplayLayout false (tagParameter >> rightL) id.idText + LeftL.questionMark ^^ + (idL |> addColonL) ^^ + layoutTypeWithInfoAndPrec denv env 2 ty + + // Layout an unnamed argument + | None, _, _, _ -> + layoutTypeWithInfoAndPrec denv env 2 ty + + // Layout a named argument + | Some id, _, isParamArray, _ -> + let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText + let prefix = + if isParamArray then + layoutBuiltinAttribute denv g.attrib_ParamArrayAttribute ^^ idL + else + idL + (prefix |> addColonL) ^^ layoutTypeWithInfoAndPrec denv env 2 ty + + let layoutCurriedArgInfos denv env argInfos = + argInfos + |> List.mapSquared (layoutArgInfo denv env) + |> List.map (sepListL (wordL (tagPunctuation "*"))) + + let layoutGenericParameterTypes denv env genParamTys = + match genParamTys with + | [] -> emptyL + | _ -> + wordL (tagPunctuation "<") + ^^ + ( + genParamTys + |> List.map (layoutTypeWithInfoAndPrec denv env 4) + |> sepListL (wordL (tagPunctuation ",")) + ) + ^^ + wordL (tagPunctuation ">") + /// Layout a single type used as the type of a member or value let layoutTopType denv env argInfos rty cxs = // Parenthesize the return type to match the topValInfo - let rtyL = layoutTypeWithInfoAndPrec denv env 4 rty + let rtyL = layoutReturnType denv env rty let cxsL = layoutConstraintsWithInfo denv env cxs match argInfos with | [] -> rtyL --- cxsL | _ -> - - // Format each argument, including its name and type - let argL (ty, argInfo: ArgReprInfo) = - - // Detect an optional argument - let isOptionalArg = HasFSharpAttribute denv.g denv.g.attrib_OptionalArgumentAttribute argInfo.Attribs - let isParamArray = HasFSharpAttribute denv.g denv.g.attrib_ParamArrayAttribute argInfo.Attribs - match argInfo.Name, isOptionalArg, isParamArray, tryDestOptionTy denv.g ty with - // Layout an optional argument - | Some(id), true, _, ValueSome ty -> - leftL (tagPunctuation "?") ^^ sepL (tagParameter id.idText) ^^ SepL.colon ^^ layoutTypeWithInfoAndPrec denv env 2 ty - // Layout an unnamed argument - | None, _, _, _ -> - layoutTypeWithInfoAndPrec denv env 2 ty - // Layout a named argument - | Some id, _, isParamArray, _ -> - let prefix = - if isParamArray then - layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute ^^ leftL (tagParameter id.idText) - else - leftL (tagParameter id.idText) - prefix ^^ SepL.colon ^^ layoutTypeWithInfoAndPrec denv env 2 ty - - let delimitReturnValue = tagPunctuation (if denv.useColonForReturnType then ":" else "->") - - let allArgsL = - argInfos - |> List.mapSquared argL - |> List.map (sepListL (wordL (tagPunctuation "*"))) - |> List.map (fun x -> (x ^^ wordL delimitReturnValue)) - (List.foldBack (---) allArgsL rtyL) --- cxsL + let retTyDelim = if denv.useColonForReturnType then ":" else "->" + let allArgsL = layoutCurriedArgInfos denv env argInfos + curriedLayoutsL retTyDelim allArgsL rtyL --- cxsL /// Layout type parameters let layoutTyparDecls denv nmL prefix (typars: Typars) = @@ -1042,8 +979,10 @@ module private PrintTypes = | _ -> let tpcsL = layoutConstraintsWithInfo denv env tpcs let coreL = sepListL (sepL (tagPunctuation ",")) (List.map (layoutTyparRefWithInfo denv env) typars) - (if prefix || not (isNil tpcs) then nmL ^^ angleL (coreL --- tpcsL) else bracketL coreL --- nmL) - + if prefix || not (isNil tpcs) then + nmL ^^ angleL (coreL --- tpcsL) + else + bracketL coreL --- nmL let layoutTyparConstraint denv (tp, tpc) = match layoutConstraintWithInfo denv SimplifyTypes.typeSimplificationInfo0 (tp, tpc) with @@ -1073,15 +1012,19 @@ module private PrintTypes = let cxs = cxs |> List.filter (fun (tp, _) -> not (parentTyparTys |> List.exists (fun ty -> match tryDestTyparTy denv.g ty with ValueSome destTypar -> typarEq tp destTypar | _ -> false))) prettyTyparInst, prettyLayoutOfTopTypeInfoAux denv argInfos retTy cxs - // Layout: type spec - class, datatype, record, abbrev + let prettyArgInfos denv allTyparInst = + function + | [] -> [(denv.g.unit_ty, ValReprInfo.unnamedTopArg1)] + | infos -> infos |> List.map (map1Of2 (instType allTyparInst)) - let private prettyLayoutOfMemberSigCore denv memberToParentInst (typarInst, methTypars: Typars, argInfos, retTy) = + // Layout: type spec - class, datatype, record, abbrev + let prettyLayoutOfMemberSigCore denv memberToParentInst (typarInst, methTypars: Typars, argInfos, retTy) = let niceMethodTypars, allTyparInst = let methTyparNames = methTypars |> List.mapi (fun i tp -> if (PrettyTypes.NeedsPrettyTyparName tp) then sprintf "a%d" (List.length memberToParentInst + i) else tp.Name) PrettyTypes.NewPrettyTypars memberToParentInst methTypars methTyparNames let retTy = instType allTyparInst retTy - let argInfos = argInfos |> List.map (fun infos -> if isNil infos then [(denv.g.unit_ty, ValReprInfo.unnamedTopArg1)] else infos |> List.map (map1Of2 (instType allTyparInst))) + let argInfos = argInfos |> List.map (prettyArgInfos denv allTyparInst) // Also format dummy types corresponding to any type variables on the container to make sure they // aren't chosen as names for displayed variables. @@ -1101,11 +1044,56 @@ module private PrintTypes = let prettyLayoutOfMemberSig denv (memberToParentInst, nm, methTypars, argInfos, retTy) = let _, niceMethodTypars, tauL = prettyLayoutOfMemberSigCore denv memberToParentInst (emptyTyparInst, methTypars, argInfos, retTy) - let nameL = - let nameL = DemangleOperatorNameAsLayout tagMember nm - let nameL = if denv.showTyparBinding then layoutTyparDecls denv nameL true niceMethodTypars else nameL - nameL - nameL ^^ wordL (tagPunctuation ":") ^^ tauL + let nameL = ConvertValNameToDisplayLayout false (tagMember >> wordL) nm + let nameL = + if denv.showTyparBinding then + layoutTyparDecls denv nameL true niceMethodTypars + else + nameL + (nameL |> addColonL) ^^ tauL + + /// layouts the elements of an unresolved overloaded method call: + /// argInfos: unammed and named arguments + /// retTy: return type + /// genParamTy: generic parameter types + let prettyLayoutsOfUnresolvedOverloading denv argInfos retTy genParamTys = + let _niceMethodTypars, typarInst = + let memberToParentInst = List.empty + let typars = argInfos |> List.choose (function TType.TType_var typar,_ -> Some typar | _ -> None) + let methTyparNames = typars |> List.mapi (fun i tp -> if (PrettyTypes.NeedsPrettyTyparName tp) then sprintf "a%d" (List.length memberToParentInst + i) else tp.Name) + PrettyTypes.NewPrettyTypars memberToParentInst typars methTyparNames + let retTy = instType typarInst retTy + let argInfos = prettyArgInfos denv typarInst argInfos + let argInfos,retTy,genParamTys, cxs = + // using 0, 1, 2 as discriminant for return, arguments and generic parameters + // respectively, in order to easily retrieve each of the types with their + // expected quality below. + let typesWithDiscrimants = + [ + yield 0, retTy + for ty,_ in argInfos do + yield 1, ty + for ty in genParamTys do + yield 2, ty + ] + let typesWithDiscrimants,typarsAndCxs = PrettyTypes.PrettifyDiscriminantAndTypePairs denv.g typesWithDiscrimants + let retTy = typesWithDiscrimants |> List.find (function 0, _ -> true | _ -> false) |> snd + let argInfos = + typesWithDiscrimants + |> List.choose (function 1,ty -> Some ty | _ -> None) + |> List.map2 (fun (_, argInfo) tTy -> tTy, argInfo) argInfos + let genParamTys = + typesWithDiscrimants + |> List.choose (function 2,ty -> Some ty | _ -> None) + + argInfos, retTy, genParamTys, typarsAndCxs + + let env = SimplifyTypes.CollectInfo true (List.collect (List.map fst) [argInfos]) cxs + let cxsL = layoutConstraintsWithInfo denv env env.postfixConstraints + + (List.foldBack (---) (layoutCurriedArgInfos denv env [argInfos]) cxsL, + layoutReturnType denv env retTy, + layoutGenericParameterTypes denv env genParamTys) let prettyLayoutOfType denv ty = let ty, cxs = PrettyTypes.PrettifyType denv.g ty @@ -1121,90 +1109,165 @@ module private PrintTypes = ty.GetAssemblyName() /// Printing TAST objects -module private PrintTastMemberOrVals = - open PrintTypes - let private prettyLayoutOfMember denv typarInst (v: Val) = +module PrintTastMemberOrVals = + open PrintTypes + + let mkInlineL denv (v: Val) nameL = + if v.MustInline && not denv.suppressInlineKeyword then + wordL (tagKeyword "inline") ++ nameL + else + nameL + + let layoutMemberName (denv: DisplayEnv) (v: ValRef) niceMethodTypars tagFunction name = + let nameL = ConvertValNameToDisplayLayout v.IsBaseVal (tagFunction >> mkNav v.DefinitionRange >> wordL) name + let nameL = + if denv.showMemberContainers then + layoutTyconRef denv v.MemberApparentEntity ^^ SepL.dot ^^ nameL + else + nameL + let nameL = if denv.showTyparBinding then layoutTyparDecls denv nameL true niceMethodTypars else nameL + let nameL = layoutAccessibility denv v.Accessibility nameL + nameL + + let prettyLayoutOfMemberShortOption denv typarInst (v: Val) short = let v = mkLocalValRef v let membInfo = Option.get v.MemberInfo - let stat = PrintTypes.layoutMemberFlags membInfo.MemberFlags + let stat = layoutMemberFlags membInfo.MemberFlags let _tps, argInfos, rty, _ = GetTypeOfMemberInFSharpForm denv.g v - let mkNameL niceMethodTypars tagFunction name = - let nameL = - DemangleOperatorNameAsLayout (tagFunction >> mkNav v.DefinitionRange) name - let nameL = - if denv.showMemberContainers then - layoutTyconRef denv v.MemberApparentEntity ^^ SepL.dot ^^ nameL - else - nameL - let nameL = if denv.showTyparBinding then layoutTyparDecls denv nameL true niceMethodTypars else nameL - let nameL = layoutAccessibility denv v.Accessibility nameL - nameL - - match membInfo.MemberFlags.MemberKind with - | MemberKind.Member -> - let prettyTyparInst, niceMethodTypars, tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty - let nameL = mkNameL niceMethodTypars tagMember v.LogicalName - let resL = stat --- (nameL ^^ WordL.colon ^^ tauL) - prettyTyparInst, resL - | MemberKind.ClassConstructor - | MemberKind.Constructor -> - let prettyTyparInst, _, tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty - let newL = layoutAccessibility denv v.Accessibility WordL.keywordNew - let resL = stat ++ newL ^^ wordL (tagPunctuation ":") ^^ tauL - prettyTyparInst, resL - | MemberKind.PropertyGetSet -> - emptyTyparInst, stat - | MemberKind.PropertyGet -> - if isNil argInfos then - // use error recovery because intellisense on an incomplete file will show this - errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(), v.Id.idRange)) - let nameL = mkNameL [] tagProperty v.CoreDisplayName - let resL = stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordGet) - emptyTyparInst, resL - else - let argInfos = - match argInfos with - | [[(ty, _)]] when isUnitTy denv.g ty -> [] - | _ -> argInfos - - let prettyTyparInst, niceMethodTypars, tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty - let nameL = mkNameL niceMethodTypars tagProperty v.CoreDisplayName - let resL = stat --- (nameL ^^ WordL.colon ^^ (if isNil argInfos then tauL else tauL --- (WordL.keywordWith ^^ WordL.keywordGet))) + if short then + for argInfo in argInfos do + for _,info in argInfo do + info.Attribs <- [] + info.Name <- None + + let prettyTyparInst, memberL = + match membInfo.MemberFlags.MemberKind with + | SynMemberKind.Member -> + let prettyTyparInst, niceMethodTypars,tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty + let resL = + if short then tauL + else + let nameL = layoutMemberName denv v niceMethodTypars tagMember v.DisplayNameCoreMangled + let nameL = if short then nameL else mkInlineL denv v.Deref nameL + stat --- ((nameL |> addColonL) ^^ tauL) prettyTyparInst, resL - | MemberKind.PropertySet -> - if argInfos.Length <> 1 || isNil argInfos.Head then - // use error recovery because intellisense on an incomplete file will show this - errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(), v.Id.idRange)) - let nameL = mkNameL [] tagProperty v.CoreDisplayName - let resL = stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordSet) - emptyTyparInst, resL - else - let argInfos, valueInfo = List.frontAndBack argInfos.Head - let prettyTyparInst, niceMethodTypars, tauL = prettyLayoutOfMemberType denv v typarInst (if isNil argInfos then [] else [argInfos]) (fst valueInfo) - let nameL = mkNameL niceMethodTypars tagProperty v.CoreDisplayName - let resL = stat --- (nameL ^^ wordL (tagPunctuation ":") ^^ (tauL --- (WordL.keywordWith ^^ WordL.keywordSet))) + + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor -> + let prettyTyparInst, _, tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty + let resL = + if short then tauL + else + let newL = layoutAccessibility denv v.Accessibility WordL.keywordNew + stat ++ (newL |> addColonL) ^^ tauL prettyTyparInst, resL - let private layoutNonMemberVal denv (tps, v: Val, tau, cxs) = + | SynMemberKind.PropertyGetSet -> + emptyTyparInst, stat + + | SynMemberKind.PropertyGet -> + if isNil argInfos then + // use error recovery because intellisense on an incomplete file will show this + errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(), v.Id.idRange)) + let nameL = layoutMemberName denv v [] tagProperty v.DisplayNameCoreMangled + let resL = + if short then nameL --- (WordL.keywordWith ^^ WordL.keywordGet) + else stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordGet) + emptyTyparInst, resL + else + let argInfos = + match argInfos with + | [[(ty, _)]] when isUnitTy denv.g ty -> [] + | _ -> argInfos + let prettyTyparInst, niceMethodTypars,tauL = prettyLayoutOfMemberType denv v typarInst argInfos rty + let resL = + if short then + if isNil argInfos then tauL + else tauL --- (WordL.keywordWith ^^ WordL.keywordGet) + else + let nameL = layoutMemberName denv v niceMethodTypars tagProperty v.DisplayNameCoreMangled + stat --- ((nameL |> addColonL) ^^ (if isNil argInfos then tauL else tauL --- (WordL.keywordWith ^^ WordL.keywordGet))) + prettyTyparInst, resL + + | SynMemberKind.PropertySet -> + if argInfos.Length <> 1 || isNil argInfos.Head then + // use error recovery because intellisense on an incomplete file will show this + errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(), v.Id.idRange)) + let nameL = layoutMemberName denv v [] tagProperty v.DisplayNameCoreMangled + let resL = stat --- nameL --- (WordL.keywordWith ^^ WordL.keywordSet) + emptyTyparInst, resL + else + let argInfos, valueInfo = List.frontAndBack argInfos.Head + let prettyTyparInst, niceMethodTypars, tauL = prettyLayoutOfMemberType denv v typarInst (if isNil argInfos then [] else [argInfos]) (fst valueInfo) + let resL = + if short then + (tauL --- (WordL.keywordWith ^^ WordL.keywordSet)) + else + let nameL = layoutMemberName denv v niceMethodTypars tagProperty v.DisplayNameCoreMangled + stat --- ((nameL |> addColonL) ^^ (tauL --- (WordL.keywordWith ^^ WordL.keywordSet))) + prettyTyparInst, resL + + prettyTyparInst, memberL + + let prettyLayoutOfMember denv typarInst (v:Val) = prettyLayoutOfMemberShortOption denv typarInst v false + + let prettyLayoutOfMemberNoInstShort denv v = + prettyLayoutOfMemberShortOption denv emptyTyparInst v true |> snd + + let layoutOfLiteralValue literalValue = + let literalValue = + match literalValue with + | Const.Bool value -> if value then WordL.keywordTrue else WordL.keywordFalse + | Const.SByte _ + | Const.Byte _ + | Const.Int16 _ + | Const.UInt16 _ + | Const.Int32 _ + | Const.UInt32 _ + | Const.Int64 _ + | Const.UInt64 _ + | Const.IntPtr _ + | Const.UIntPtr _ + | Const.Single _ + | Const.Double _ + | Const.Decimal _ -> literalValue.ToString() |> tagNumericLiteral |> wordL + | Const.Char _ + | Const.String _ -> literalValue.ToString() |> tagStringLiteral |> wordL + | Const.Unit + | Const.Zero -> literalValue.ToString() |> tagText |> wordL + WordL.equals ++ literalValue + + let layoutNonMemberVal denv (tps, v: Val, tau, cxs) = let env = SimplifyTypes.CollectInfo true [tau] cxs let cxs = env.postfixConstraints let argInfos, rty = GetTopTauTypeInFSharpForm denv.g (arityOfVal v).ArgInfos tau v.Range let nameL = - (if v.IsModuleBinding then tagModuleBinding else tagUnknownEntity) v.DisplayName + + let tagF = + if isForallFunctionTy denv.g v.Type && not (isDiscard v.DisplayNameCore) then + if IsOperatorDisplayName v.DisplayName then + tagOperator + else + tagFunction + elif not v.IsCompiledAsTopLevel && not(isDiscard v.DisplayNameCore) then + tagLocal + elif v.IsModuleBinding then + tagModuleBinding + else + tagUnknownEntity + + v.DisplayName + |> tagF |> mkNav v.DefinitionRange |> wordL let nameL = layoutAccessibility denv v.Accessibility nameL let nameL = if v.IsMutable && not denv.suppressMutableKeyword then wordL (tagKeyword "mutable") ++ nameL - else - nameL - let nameL = - if v.MustInline && not denv.suppressInlineKeyword then - wordL (tagKeyword "inline") ++ nameL - else - nameL + else + nameL + let nameL = mkInlineL denv v nameL let isOverGeneric = List.length (Zset.elements (freeInType CollectTyparsNoCaching tau).FreeTypars) < List.length tps // Bug: 1143 let isTyFunction = v.IsTypeFunction // Bug: 1143, and innerpoly tests @@ -1212,113 +1275,150 @@ module private PrintTastMemberOrVals = if isTyFunction || isOverGeneric || denv.showTyparBinding then layoutTyparDecls denv nameL true tps else nameL - let valAndTypeL = (WordL.keywordVal ^^ typarBindingsL --- wordL (tagPunctuation ":")) --- layoutTopType denv env argInfos rty cxs - match denv.generatedValueLayout v with - | None -> valAndTypeL - | Some rhsL -> (valAndTypeL ++ wordL (tagPunctuation"=")) --- rhsL - - let prettyLayoutOfValOrMember denv typarInst (v: Val) = - let prettyTyparInst, vL = - match v.MemberInfo with - | None -> - let tps, tau = v.TypeScheme + let valAndTypeL = (WordL.keywordVal ^^ (typarBindingsL |> addColonL)) --- layoutTopType denv env argInfos rty cxs + let valAndTypeL = + match denv.generatedValueLayout v with + | None -> valAndTypeL + | Some rhsL -> (valAndTypeL ++ WordL.equals) --- rhsL + match v.LiteralValue with + | Some literalValue -> valAndTypeL --- layoutOfLiteralValue literalValue + | None -> valAndTypeL + + let prettyLayoutOfValOrMember denv infoReader typarInst (vref: ValRef) = + let prettyTyparInst, valL = + match vref.MemberInfo with + | None -> + let tps, tau = vref.TypeScheme // adjust the type in case this is the 'this' pointer stored in a reference cell - let tau = StripSelfRefCell(denv.g, v.BaseOrThisInfo, tau) + let tau = StripSelfRefCell(denv.g, vref.BaseOrThisInfo, tau) let (prettyTyparInst, prettyTypars, prettyTauTy), cxs = PrettyTypes.PrettifyInstAndTyparsAndType denv.g (typarInst, tps, tau) - let resL = layoutNonMemberVal denv (prettyTypars, v, prettyTauTy, cxs) + let resL = layoutNonMemberVal denv (prettyTypars, vref.Deref, prettyTauTy, cxs) prettyTyparInst, resL | Some _ -> - prettyLayoutOfMember denv typarInst v - prettyTyparInst, layoutAttribs denv v.Type TyparKind.Type v.Attribs vL + prettyLayoutOfMember denv typarInst vref.Deref + + let valL = + valL + |> layoutAttribs denv None vref.LiteralValue.IsSome TyparKind.Type vref.Attribs + |> layoutXmlDocOfVal denv infoReader vref - let prettyLayoutOfValOrMemberNoInst denv v = - prettyLayoutOfValOrMember denv emptyTyparInst v |> snd + prettyTyparInst, valL + + let prettyLayoutOfValOrMemberNoInst denv infoReader v = + prettyLayoutOfValOrMember denv infoReader emptyTyparInst v |> snd let layoutTyparConstraint denv x = x |> PrintTypes.layoutTyparConstraint denv + let outputType denv os x = x |> PrintTypes.layoutType denv |> bufferL os + let layoutType denv x = x |> PrintTypes.layoutType denv + let outputTypars denv nm os x = x |> PrintTypes.layoutTyparDecls denv (wordL nm) true |> bufferL os + let outputTyconRef denv os x = x |> PrintTypes.layoutTyconRef denv |> bufferL os + let layoutTyconRef denv x = x |> PrintTypes.layoutTyconRef denv + let layoutConst g ty c = PrintTypes.layoutConst g ty c let prettyLayoutOfMemberSig denv x = x |> PrintTypes.prettyLayoutOfMemberSig denv + let prettyLayoutOfUncurriedSig denv argInfos tau = PrintTypes.prettyLayoutOfUncurriedSig denv argInfos tau +let prettyLayoutsOfUnresolvedOverloading denv argInfos retTy genericParameters = PrintTypes.prettyLayoutsOfUnresolvedOverloading denv argInfos retTy genericParameters + //------------------------------------------------------------------------- /// Printing info objects module InfoMemberPrinting = - /// Format the arguments of a method to a buffer. - /// - /// This uses somewhat "old fashioned" printf-style buffer printing. + /// Format the arguments of a method let layoutParamData denv (ParamData(isParamArray, _isInArg, _isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty)) = let isOptArg = optArgInfo.IsOptional - match isParamArray, nmOpt, isOptArg, tryDestOptionTy denv.g pty with + // detect parameter type, if ptyOpt is None - this is .NET style optional argument + let ptyOpt = tryDestOptionTy denv.g pty + + match isParamArray, nmOpt, isOptArg with // Layout an optional argument - | _, Some nm, true, ptyOpt -> - // detect parameter type, if ptyOpt is None - this is .NET style optional argument + | _, Some id, true -> + let idL = ConvertValNameToDisplayLayout false (tagParameter >> rightL) id.idText let pty = match ptyOpt with ValueSome x -> x | _ -> pty - SepL.questionMark ^^ - wordL (tagParameter nm.idText) ^^ - RightL.colon ^^ + LeftL.questionMark ^^ + (idL |> addColonL) ^^ PrintTypes.layoutType denv pty + // Layout an unnamed argument - | _, None, _, _ -> + | _, None, _ -> PrintTypes.layoutType denv pty - // Layout a named argument - | true, Some nm, _, _ -> + + // Layout a named ParamArray argument + | true, Some id, _ -> + let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute ^^ - wordL (tagParameter nm.idText) ^^ - RightL.colon ^^ + (idL |> addColonL) ^^ PrintTypes.layoutType denv pty - | false, Some nm, _, _ -> - wordL (tagParameter nm.idText) ^^ - RightL.colon ^^ + + // Layout a named normal argument + | false, Some id, _ -> + let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText + (idL |> addColonL) ^^ PrintTypes.layoutType denv pty - let formatParamDataToBuffer denv os pd = layoutParamData denv pd |> bufferL os + let formatParamDataToBuffer denv os pd = + layoutParamData denv pd |> bufferL os /// Format a method info using "F# style". // // That is, this style: - // new: argName1: argType1 * ... * argNameN: argTypeN -> retType - // Method: argName1: argType1 * ... * argNameN: argTypeN -> retType - let private layoutMethInfoFSharpStyleCore amap m denv (minfo: MethInfo) minst = - let layout = - if not minfo.IsConstructor && not minfo.IsInstance then WordL.keywordStatic - else emptyL - let layout = - layout ^^ - ( + // new: argName1: argType1 * ... * argNameN: argTypeN -> retType + // Method: argName1: argType1 * ... * argNameN: argTypeN -> retType + // + let layoutMethInfoFSharpStyleCore (infoReader: InfoReader) m denv (minfo: MethInfo) minst = + let amap = infoReader.amap + + match minfo.ArbitraryValRef with + | Some vref -> + PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader vref + | None -> + let layout = + if not minfo.IsConstructor && not minfo.IsInstance then WordL.keywordStatic + else emptyL + + let nameL = if minfo.IsConstructor then - wordL (tagKeyword "new") + WordL.keywordNew else + let idL = ConvertValNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName WordL.keywordMember ^^ - PrintTypes.layoutTyparDecls denv (wordL (tagMethod minfo.LogicalName)) true minfo.FormalMethodTypars - ) ^^ - WordL.colon - let paramDatas = minfo.GetParamDatas(amap, m, minst) - let layout = - layout ^^ + PrintTypes.layoutTyparDecls denv idL true minfo.FormalMethodTypars + + let layout = layout ^^ (nameL |> addColonL) + let layout = layoutXmlDocOfMethInfo denv infoReader minfo layout + + let paramsL = + let paramDatas = minfo.GetParamDatas(amap, m, minst) if List.forall isNil paramDatas then WordL.structUnit else sepListL WordL.arrow (List.map ((List.map (layoutParamData denv)) >> sepListL WordL.star) paramDatas) - let retTy = minfo.GetFSharpReturnTy(amap, m, minst) - layout ^^ - WordL.arrow ^^ - PrintTypes.layoutType denv retTy + + let layout = layout ^^ paramsL + + let retL = + let retTy = minfo.GetFSharpReturnTy(amap, m, minst) + WordL.arrow ^^ + PrintTypes.layoutType denv retTy + + layout ^^ retL /// Format a method info using "half C# style". // // That is, this style: // Container(argName1: argType1, ..., argNameN: argTypeN) : retType // Container.Method(argName1: argType1, ..., argNameN: argTypeN) : retType - let private layoutMethInfoCSharpStyle amap m denv (minfo: MethInfo) minst = + let layoutMethInfoCSharpStyle amap m denv (minfo: MethInfo) minst = let retTy = if minfo.IsConstructor then minfo.ApparentEnclosingType else minfo.GetFSharpReturnTy(amap, m, minst) let layout = if minfo.IsExtensionMember then @@ -1336,26 +1436,27 @@ module InfoMemberPrinting = if minfo.IsConstructor then SepL.leftParen else + let idL = ConvertValNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName SepL.dot ^^ - PrintTypes.layoutTyparDecls denv (wordL (tagMethod minfo.LogicalName)) true minfo.FormalMethodTypars ^^ + PrintTypes.layoutTyparDecls denv idL true minfo.FormalMethodTypars ^^ SepL.leftParen let paramDatas = minfo.GetParamDatas (amap, m, minst) let layout = layout ^^ sepListL RightL.comma ((List.concat >> List.map (layoutParamData denv)) paramDatas) layout ^^ RightL.rightParen ^^ WordL.colon ^^ PrintTypes.layoutType denv retTy - - // Prettify this baby + // Prettify an ILMethInfo let prettifyILMethInfo (amap: Import.ImportMap) m (minfo: MethInfo) typarInst ilMethInfo = let (ILMethInfo(_, apparentTy, dty, mdef, _)) = ilMethInfo let (prettyTyparInst, prettyTys), _ = PrettyTypes.PrettifyInstAndTypes amap.g (typarInst, (apparentTy :: minfo.FormalMethodInst)) - let prettyApparentTy, prettyFormalMethInst = List.headAndTail prettyTys - let prettyMethInfo = - match dty with - | None -> MethInfo.CreateILMeth (amap, m, prettyApparentTy, mdef) - | Some declaringTyconRef -> MethInfo.CreateILExtensionMeth(amap, m, prettyApparentTy, declaringTyconRef, minfo.ExtensionMemberPriorityOption, mdef) - prettyTyparInst, prettyMethInfo, prettyFormalMethInst - + match prettyTys with + | prettyApparentTy :: prettyFormalMethInst -> + let prettyMethInfo = + match dty with + | None -> MethInfo.CreateILMeth (amap, m, prettyApparentTy, mdef) + | Some declaringTyconRef -> MethInfo.CreateILExtensionMeth(amap, m, prettyApparentTy, declaringTyconRef, minfo.ExtensionMemberPriorityOption, mdef) + prettyTyparInst, prettyMethInfo, prettyFormalMethInst + | _ -> failwith "prettifyILMethInfo - prettyTys empty" /// Format a method to a buffer using "standalone" display style. /// For example, these are the formats used when printing signatures of methods that have not been overridden, @@ -1378,13 +1479,16 @@ module InfoMemberPrinting = // // For C# extension members: // ApparentContainer.Method(argName1: argType1, ..., argNameN: argTypeN) : retType - let prettyLayoutOfMethInfoFreeStyle (amap: Import.ImportMap) m denv typarInst methInfo = + let prettyLayoutOfMethInfoFreeStyle (infoReader: InfoReader) m denv typarInst methInfo = + let amap = infoReader.amap + match methInfo with | DefaultStructCtor _ -> let prettyTyparInst, _ = PrettyTypes.PrettifyInst amap.g typarInst - prettyTyparInst, PrintTypes.layoutTyconRef denv methInfo.ApparentEnclosingTyconRef ^^ wordL (tagPunctuation "()") + let resL = PrintTypes.layoutTyconRef denv methInfo.ApparentEnclosingTyconRef ^^ wordL (tagPunctuation "()") + prettyTyparInst, resL | FSMeth(_, _, vref, _) -> - let prettyTyparInst, resL = PrintTastMemberOrVals.prettyLayoutOfValOrMember { denv with showMemberContainers=true } typarInst vref.Deref + let prettyTyparInst, resL = PrintTastMemberOrVals.prettyLayoutOfValOrMember { denv with showMemberContainers=true } infoReader typarInst vref prettyTyparInst, resL | ILMeth(_, ilminfo, _) -> let prettyTyparInst, prettyMethInfo, minst = prettifyILMethInfo amap m methInfo typarInst ilminfo @@ -1400,27 +1504,22 @@ module InfoMemberPrinting = let rty = pinfo.GetPropertyType(amap, m) let rty = if pinfo.IsIndexer then mkRefTupledTy g (pinfo.GetParamTypes(amap, m)) --> rty else rty let rty, _ = PrettyTypes.PrettifyType g rty - let tagProp = - match pinfo.ArbitraryValRef with - | None -> tagProperty - | Some vref -> tagProperty >> mkNav vref.DefinitionRange - let nameL = DemangleOperatorNameAsLayout tagProp pinfo.PropertyName + let nameL = ConvertValNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName let getterSetter = match pinfo.HasGetter, pinfo.HasSetter with - | (true, false) -> + | true, false -> wordL (tagKeyword "with") ^^ wordL (tagText "get") - | (false, true) -> + | false, true -> wordL (tagKeyword "with") ^^ wordL (tagText "set") - | (true, true) -> + | true, true -> wordL (tagKeyword "with") ^^ wordL (tagText "get, set") - | (false, false) -> + | false, false -> emptyL wordL (tagText (FSComp.SR.typeInfoProperty())) ^^ layoutTyconRef denv pinfo.ApparentEnclosingTyconRef ^^ SepL.dot ^^ - nameL ^^ - RightL.colon ^^ + (nameL |> addColonL) ^^ layoutType denv rty ^^ getterSetter @@ -1435,127 +1534,172 @@ module InfoMemberPrinting = //------------------------------------------------------------------------- /// Printing TAST objects -module private TastDefinitionPrinting = +module TastDefinitionPrinting = open PrintTypes - let layoutExtensionMember denv (v: Val) = - let tycon = v.MemberApparentEntity.Deref - let nameL = tagMethod tycon.DisplayName |> mkNav v.DefinitionRange |> wordL + let layoutExtensionMember denv infoReader (vref: ValRef) = + let (@@*) = if denv.printVerboseSignatures then (@@----) else (@@--) + let tycon = vref.MemberApparentEntity.Deref + let nameL = ConvertNameToDisplayLayout (tagMethod >> mkNav vref.DefinitionRange >> wordL) tycon.DisplayNameCore let nameL = layoutAccessibility denv tycon.Accessibility nameL // "type-accessibility" let tps = - match PartitionValTyparsForApparentEnclosingType denv.g v with + match PartitionValTyparsForApparentEnclosingType denv.g vref.Deref with | Some(_, memberParentTypars, _, _, _) -> memberParentTypars | None -> [] let lhsL = WordL.keywordType ^^ layoutTyparDecls denv nameL tycon.IsPrefixDisplay tps - let memberL = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv v - (lhsL ^^ WordL.keywordWith) @@-- memberL - - let layoutExtensionMembers denv vs = - aboveListL (List.map (layoutExtensionMember denv) vs) - - let layoutRecdField addAccess denv (fld: RecdField) = - let lhs = - tagRecordField fld.Name - |> mkNav fld.DefinitionRange - |> wordL - let lhs = (if addAccess then layoutAccessibility denv fld.Accessibility lhs else lhs) + let memberL = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader vref + (lhsL ^^ WordL.keywordWith) @@* memberL + + let layoutExtensionMembers denv infoReader vs = + aboveListL (List.map (layoutExtensionMember denv infoReader) vs) + + let layoutRecdField prefix isClassDecl denv infoReader (enclosingTcref: TyconRef) (fld: RecdField) = + let lhs = ConvertNameToDisplayLayout (tagRecordField >> mkNav fld.DefinitionRange >> wordL) fld.DisplayNameCore + let lhs = (if isClassDecl then layoutAccessibility denv fld.Accessibility lhs else lhs) let lhs = if fld.IsMutable then wordL (tagKeyword "mutable") --- lhs else lhs - (lhs ^^ RightL.colon) --- layoutType denv fld.FormalType + let fieldL = (lhs |> addColonL) --- layoutType denv fld.FormalType + let fieldL = prefix fieldL + let fieldL = fieldL |> layoutAttribs denv None false TyparKind.Type (fld.FieldAttribs @ fld.PropertyAttribs) - let layoutUnionOrExceptionField denv isGenerated i (fld: RecdField) = - if isGenerated i fld then layoutTypeWithInfoAndPrec denv SimplifyTypes.typeSimplificationInfo0 2 fld.FormalType - else layoutRecdField false denv fld + // The enclosing TyconRef might be a union and we can only get fields from union cases, so we need ignore unions here. + if not enclosingTcref.IsUnionTycon then + layoutXmlDocOfRecdField denv infoReader isClassDecl (RecdFieldRef(enclosingTcref, fld.Id.idText)) fieldL + else + fieldL + + let layoutUnionOrExceptionField denv infoReader isGenerated enclosingTcref i (fld: RecdField) = + if isGenerated i fld then + layoutTypeWithInfoAndPrec denv SimplifyTypes.typeSimplificationInfo0 2 fld.FormalType + else + layoutRecdField id false denv infoReader enclosingTcref fld let isGeneratedUnionCaseField pos (f: RecdField) = - if pos < 0 then f.Name = "Item" - else f.Name = "Item" + string (pos + 1) + if pos < 0 then f.LogicalName = "Item" + else f.LogicalName = "Item" + string (pos + 1) let isGeneratedExceptionField pos (f: RecdField) = - f.Name = "Data" + (string pos) + f.LogicalName = "Data" + (string pos) - let layoutUnionCaseFields denv isUnionCase fields = + let layoutUnionCaseFields denv infoReader isUnionCase enclosingTcref fields = match fields with - | [f] when isUnionCase -> layoutUnionOrExceptionField denv isGeneratedUnionCaseField -1 f + | [f] when isUnionCase -> + layoutUnionOrExceptionField denv infoReader isGeneratedUnionCaseField enclosingTcref -1 f | _ -> let isGenerated = if isUnionCase then isGeneratedUnionCaseField else isGeneratedExceptionField - sepListL (wordL (tagPunctuation "*")) (List.mapi (layoutUnionOrExceptionField denv isGenerated) fields) + sepListL WordL.star (List.mapi (layoutUnionOrExceptionField denv infoReader isGenerated enclosingTcref) fields) - let layoutUnionCase denv prefixL (ucase: UnionCase) = - let nmL = DemangleOperatorNameAsLayout (tagUnionCase >> mkNav ucase.DefinitionRange) ucase.Id.idText + let layoutUnionCase denv infoReader prefixL enclosingTcref (ucase: UnionCase) = + let nmL = ConvertNameToDisplayLayout (tagUnionCase >> mkNav ucase.DefinitionRange >> wordL) ucase.Id.idText //let nmL = layoutAccessibility denv ucase.Accessibility nmL - match ucase.RecdFields with - | [] -> (prefixL ^^ nmL) - | fields -> (prefixL ^^ nmL ^^ WordL.keywordOf) --- layoutUnionCaseFields denv true fields + let caseL = + match ucase.RecdFields with + | [] -> (prefixL ^^ nmL) + | fields -> (prefixL ^^ nmL ^^ WordL.keywordOf) --- layoutUnionCaseFields denv infoReader true enclosingTcref fields + layoutXmlDocOfUnionCase denv infoReader (UnionCaseRef(enclosingTcref, ucase.Id.idText)) caseL - let layoutUnionCases denv ucases = + let layoutUnionCases denv infoReader enclosingTcref ucases = let prefixL = WordL.bar // See bug://2964 - always prefix in case preceded by accessibility modifier - List.map (layoutUnionCase denv prefixL) ucases + List.map (layoutUnionCase denv infoReader prefixL enclosingTcref) ucases /// When to force a break? "type tyname = repn" /// When repn is class or datatype constructors (not single one). let breakTypeDefnEqn repr = match repr with + | TILObjectRepr _ -> true | TFSharpObjectRepr _ -> true - | TUnionRepr r -> not (isNilOrSingleton r.CasesTable.UnionCasesAsList) - | TRecdRepr _ -> true + | TFSharpRecdRepr _ -> true + | TFSharpUnionRepr r -> + not (isNilOrSingleton r.CasesTable.UnionCasesAsList) || + r.CasesTable.UnionCasesAsList |> List.exists (fun uc -> not uc.XmlDoc.IsEmpty) | TAsmRepr _ - | TILObjectRepr _ | TMeasureableRepr _ #if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint _ - | TProvidedNamespaceExtensionPoint _ + | TProvidedTypeRepr _ + | TProvidedNamespaceRepr _ #endif | TNoRepr -> false + + let layoutILFieldInfo denv (infoReader: InfoReader) m (finfo: ILFieldInfo) = + let staticL = if finfo.IsStatic then WordL.keywordStatic else emptyL + let nameL = ConvertNameToDisplayLayout (tagField >> wordL) finfo.FieldName + let typL = layoutType denv (finfo.FieldType(infoReader.amap, m)) + let fieldL = staticL ^^ WordL.keywordVal ^^ (nameL |> addColonL) ^^ typL + layoutXmlDocOfILFieldInfo denv infoReader finfo fieldL + + let layoutEventInfo denv (infoReader: InfoReader) m (einfo: EventInfo) = + let amap = infoReader.amap + let staticL = if einfo.IsStatic then WordL.keywordStatic else emptyL + let nameL = ConvertValNameToDisplayLayout false (tagEvent >> tagNavArbValRef einfo.ArbitraryValRef >> wordL) einfo.EventName + let typL = layoutType denv (einfo.GetDelegateType(amap, m)) + let overallL = staticL ^^ WordL.keywordMember ^^ (nameL |> addColonL) ^^ typL + layoutXmlDocOfEventInfo denv infoReader einfo overallL + let layoutPropInfo denv (infoReader: InfoReader) m (pinfo: PropInfo) = + let amap = infoReader.amap - -#if !NO_EXTENSIONTYPING - let private layoutILFieldInfo denv amap m (e: ILFieldInfo) = - let staticL = if e.IsStatic then WordL.keywordStatic else emptyL - let nameL = wordL (tagField (adjustILName e.FieldName)) - let typL = layoutType denv (e.FieldType(amap, m)) - staticL ^^ WordL.keywordVal ^^ nameL ^^ WordL.colon ^^ typL - - let private layoutEventInfo denv amap m (e: EventInfo) = - let staticL = if e.IsStatic then WordL.keywordStatic else emptyL - let nameL = wordL (tagEvent (adjustILName e.EventName)) - let typL = layoutType denv (e.GetDelegateType(amap, m)) - staticL ^^ WordL.keywordEvent ^^ nameL ^^ WordL.colon ^^ typL - - let private layoutPropInfo denv amap m (p: PropInfo) = - let staticL = if p.IsStatic then WordL.keywordStatic else emptyL - let nameL = wordL (tagProperty (adjustILName p.PropertyName)) - - let typL = layoutType denv (p.GetPropertyType(amap, m)) // shouldn't happen - - let specGetSetL = - match p.HasGetter, p.HasSetter with - | false, false | true, false -> emptyL - | false, true -> WordL.keywordWith ^^ WordL.keywordSet - | true, true -> WordL.keywordWith ^^ WordL.keywordGet^^ SepL.comma ^^ WordL.keywordSet - - staticL ^^ WordL.keywordMember ^^ nameL ^^ WordL.colon ^^ typL ^^ specGetSetL - - /// Another re-implementation of type printing, this time based off provided info objects. - let layoutProvidedTycon (denv: DisplayEnv) (infoReader: InfoReader) ad m start lhsL ty = - let g = denv.g - let tcref = tcrefOfAppTy g ty - - if isEnumTy g ty then - let fieldLs = - infoReader.GetILFieldInfosOfType (None, ad, m, ty) - |> List.filter (fun x -> x.FieldName <> "value__") - |> List.map (fun x -> PrintIL.layoutILEnumDefParts x.FieldName x.LiteralValue) - |> aboveListL - (lhsL ^^ WordL.equals) @@-- fieldLs - else + match pinfo.ArbitraryValRef with + | Some vref -> + PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader vref + | None -> + + let modifierAndMember = + if pinfo.IsStatic then + WordL.keywordStatic ^^ WordL.keywordMember + else + WordL.keywordMember + + let nameL = ConvertValNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName + let typL = layoutType denv (pinfo.GetPropertyType(amap, m)) + let overallL = modifierAndMember ^^ (nameL |> addColonL) ^^ typL + layoutXmlDocOfPropInfo denv infoReader pinfo overallL + + let layoutTyconDefn (denv: DisplayEnv) (infoReader: InfoReader) ad m simplified typewordL (tcref: TyconRef) = + let g = denv.g + // use 4-indent + let (-*) = if denv.printVerboseSignatures then (-----) else (---) + let (@@*) = if denv.printVerboseSignatures then (@@----) else (@@--) let amap = infoReader.amap + let tycon = tcref.Deref + let repr = tycon.TypeReprInfo + let isMeasure = (tycon.TypeOrMeasureKind = TyparKind.Measure) + let _, ty = generalizeTyconRef tcref + + let start, tagger = + if isStructTy g ty then + // Always show [] whether verbose or not + Some "struct", tagStruct + elif isInterfaceTy g ty then + if denv.printVerboseSignatures then + Some "interface", tagInterface + else + None, tagInterface + elif isMeasure then + None, tagClass + elif isClassTy g ty then + if denv.printVerboseSignatures then + (if simplified then None else Some "class"), tagClass + else + None, tagClass + else + None, tagUnknownType + + let nameL = ConvertNameToDisplayLayout (tagger >> mkNav tycon.DefinitionRange >> wordL) tycon.DisplayNameCore + + let nameL = layoutAccessibility denv tycon.Accessibility nameL + let denv = denv.AddAccessibility tycon.Accessibility + + let lhsL = + let tps = tycon.TyparsNoRange + let tpsL = layoutTyparDecls denv nameL tycon.IsPrefixDisplay tps + typewordL ^^ tpsL + + let sortKey (v: MethInfo) = (not v.IsConstructor, - not v.IsInstance, // instance first - v.DisplayName, // sort by name - List.sum v.NumArgs, // sort by #curried - v.NumArgs.Length) // sort by arity + not v.IsInstance, // instance first + v.DisplayNameCore, // sort by name + List.sum v.NumArgs, // sort by #curried + v.NumArgs.Length) // sort by arity let shouldShow (valRef: ValRef option) = match valRef with @@ -1563,314 +1707,480 @@ module private TastDefinitionPrinting = | Some(vr) -> (denv.showObsoleteMembers || not (CheckFSharpAttributesForObsolete denv.g vr.Attribs)) && (denv.showHiddenMembers || not (CheckFSharpAttributesForHidden denv.g vr.Attribs)) - + let ctors = GetIntrinsicConstructorInfosOfType infoReader m ty - |> List.filter (fun v -> shouldShow v.ArbitraryValRef) + |> List.filter (fun v -> IsMethInfoAccessible amap m ad v && not v.IsClassConstructor && shouldShow v.ArbitraryValRef) - let meths = - GetImmediateIntrinsicMethInfosOfType (None, ad) g amap m ty - |> List.filter (fun v -> shouldShow v.ArbitraryValRef) - - let iimplsLs = + let iimpls = if suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty then [] + elif isRecdTy g ty || isUnionTy g ty || tycon.IsStructOrEnumTycon then + tycon.ImmediateInterfacesOfFSharpTycon + |> List.filter (fun (_, compgen, _) -> not compgen) + |> List.map p13 else - GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty |> List.map (fun ity -> wordL (tagKeyword (if isInterfaceTy g ty then "inherit" else "interface")) --- layoutType denv ity) + GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty - let props = - GetIntrinsicPropInfosOfType infoReader None ad AllowMultiIntfInstantiations.Yes PreferOverrides m ty + let iimplsLs = + iimpls + |> List.map (fun ity -> wordL (tagKeyword (if isInterfaceTy g ty then "inherit" else "interface")) -* layoutType denv ity) + + let props = + GetImmediateIntrinsicPropInfosOfType (None, ad) g amap m ty |> List.filter (fun v -> shouldShow v.ArbitraryValRef) let events = infoReader.GetEventInfosOfType(None, ad, m, ty) - |> List.filter (fun v -> shouldShow v.ArbitraryValRef) + |> List.filter (fun v -> shouldShow v.ArbitraryValRef && typeEquiv g ty v.ApparentEnclosingType) let impliedNames = try - Set.ofList [ for p in props do - if p.HasGetter then yield p.GetterMethod.DisplayName - if p.HasSetter then yield p.SetterMethod.DisplayName - for e in events do - yield e.AddMethod.DisplayName - yield e.RemoveMethod.DisplayName ] - with _ -> Set.empty - - let ctorLs = - ctors - |> shrinkOverloads (InfoMemberPrinting.layoutMethInfoFSharpStyle amap m denv) (fun _ xL -> xL) + [ for p in props do + if p.HasGetter then p.GetterMethod.DisplayName + if p.HasSetter then p.SetterMethod.DisplayName + for e in events do + e.AddMethod.DisplayName + e.RemoveMethod.DisplayName ] + |> Set.ofList + with _ -> + Set.empty + + let meths = + GetImmediateIntrinsicMethInfosOfType (None, ad) g amap m ty + |> List.filter (fun minfo -> + not minfo.IsClassConstructor && + not minfo.IsConstructor && + shouldShow minfo.ArbitraryValRef && + not (impliedNames.Contains minfo.DisplayName) && + IsMethInfoAccessible amap m ad minfo && + // Discard method impls such as System.IConvertible.ToBoolean + not (minfo.IsILMethod && minfo.DisplayName.Contains(".")) && + not (minfo.DisplayName.Split('.') |> Array.exists (fun part -> isDiscard part))) + + let ilFields = + infoReader.GetILFieldInfosOfType (None, ad, m, ty) + |> List.filter (fun fld -> + IsILFieldInfoAccessible g amap m ad fld && + not (isDiscard fld.FieldName) && + typeEquiv g ty fld.ApparentEnclosingType) + + let ctorLs = + if denv.shrinkOverloads then + ctors + |> shrinkOverloads (InfoMemberPrinting.layoutMethInfoFSharpStyle infoReader m denv) (fun _ xL -> xL) + else + ctors + |> List.map (fun ctor -> InfoMemberPrinting.layoutMethInfoFSharpStyle infoReader m denv ctor) let methLs = - meths - |> List.filter (fun md -> not (impliedNames.Contains md.DisplayName)) - |> List.groupBy (fun md -> md.DisplayName) - |> List.collect (fun (_, group) -> shrinkOverloads (InfoMemberPrinting.layoutMethInfoFSharpStyle amap m denv) (fun x xL -> (sortKey x, xL)) group) + meths + |> List.groupBy (fun md -> md.DisplayNameCore) + |> List.collect (fun (_, group) -> + if denv.shrinkOverloads then + shrinkOverloads (InfoMemberPrinting.layoutMethInfoFSharpStyle infoReader m denv) (fun x xL -> (sortKey x, xL)) group + else + group + |> List.sortBy sortKey + |> List.map (fun methinfo -> ((not methinfo.IsConstructor, methinfo.IsInstance, methinfo.DisplayName, List.sum methinfo.NumArgs, methinfo.NumArgs.Length), InfoMemberPrinting.layoutMethInfoFSharpStyle infoReader m denv methinfo))) + |> List.sortBy fst + |> List.map snd + + let ilFieldsL = + ilFields + |> List.map (fun x -> (true, x.IsStatic, x.FieldName, 0, 0), layoutILFieldInfo denv infoReader m x) + |> List.sortBy fst + |> List.map snd + + let staticVals = + if isRecdTy g ty then + [] + else + tycon.TrueFieldsAsList + |> List.filter (fun f -> IsAccessible ad f.Accessibility && f.IsStatic && not (isDiscard f.DisplayNameCore)) + + let staticValLs = + staticVals + |> List.map (fun f -> layoutRecdField (fun l -> WordL.keywordStatic ^^ WordL.keywordVal ^^ l) true denv infoReader tcref f) - let fieldLs = - infoReader.GetILFieldInfosOfType (None, ad, m, ty) - |> List.map (fun x -> (true, x.IsStatic, x.FieldName, 0, 0), layoutILFieldInfo denv amap m x) + let instanceVals = + if isRecdTy g ty then + [] + else + tycon.TrueInstanceFieldsAsList + |> List.filter (fun f -> IsAccessible ad f.Accessibility && not (isDiscard f.DisplayNameCore)) + let instanceValLs = + instanceVals + |> List.map (fun f -> layoutRecdField (fun l -> WordL.keywordVal ^^ l) true denv infoReader tcref f) - let propLs = + let propLs = props - |> List.map (fun x -> (true, x.IsStatic, x.PropertyName, 0, 0), layoutPropInfo denv amap m x) + |> List.map (fun x -> (true, x.IsStatic, x.PropertyName, 0, 0), layoutPropInfo denv infoReader m x) + |> List.sortBy fst + |> List.map snd let eventLs = events - |> List.map (fun x -> (true, x.IsStatic, x.EventName, 0, 0), layoutEventInfo denv amap m x) - - let membLs = (methLs @ fieldLs @ propLs @ eventLs) |> List.sortBy fst |> List.map snd - - let nestedTypeLs = - match tcref.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> - [ - for nestedType in info.ProvidedType.PApplyArray((fun sty -> sty.GetNestedTypes()), "GetNestedTypes", m) do - yield nestedType.PUntaint((fun t -> t.IsClass, t.Name), m) - ] - |> List.sortBy snd - |> List.map (fun (isClass, t) -> WordL.keywordNested ^^ WordL.keywordType ^^ wordL ((if isClass then tagClass else tagStruct) t)) - | _ -> - [] + |> List.map (fun x -> (true, x.IsStatic, x.EventName, 0, 0), layoutEventInfo denv infoReader m x) + |> List.sortBy fst + |> List.map snd - let inherits = - if suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty then + let nestedTypeLs = +#if !NO_EXTENSIONTYPING + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + match tcref.TypeReprInfo with + | TProvidedTypeRepr info -> + [ + for nestedType in info.ProvidedType.PApplyArray((fun sty -> sty.GetNestedTypes() |> Array.filter (fun t -> t.IsPublic || t.IsNestedPublic)), "GetNestedTypes", m) do + yield nestedType.PUntaint((fun t -> t.IsClass, t.Name), m) + ] + |> List.sortBy snd + |> List.map (fun (isClass, t) -> WordL.keywordNested ^^ WordL.keywordType ^^ wordL ((if isClass then tagClass else tagStruct) t)) + | _ -> + [] + | ValueNone -> +#endif [] - else + + let inherits = + [ if not (suppressInheritanceAndInterfacesForTyInSimplifiedDisplays g amap m ty) then match GetSuperTypeOfType g amap m ty with - | Some super when not (isObjTy g super) -> [wordL (tagKeyword "inherit") ^^ (layoutType denv super)] - | _ -> [] + | Some super when not (isObjTy g super) && not (isValueTypeTy g super) -> + super + | _ -> () + ] + + let inheritsL = + inherits + |> List.map (fun super -> wordL (tagKeyword "inherit") ^^ (layoutType denv super)) + + let allDecls = inheritsL @ iimplsLs @ ctorLs @ instanceValLs @ methLs @ ilFieldsL @ propLs @ eventLs @ staticValLs @ nestedTypeLs + + let needsStartEnd = + match start with + | Some "class" -> + // 'inherits' is not enough for F# type kind inference to infer a class + // inherits.IsEmpty && + ilFields.IsEmpty && + // 'abstract' is not enough for F# type kind inference to infer a class by default in signatures + // 'static member' is surprisingly not enough for F# type kind inference to infer a class by default in signatures + // 'overrides' is surprisingly not enough for F# type kind inference to infer a class by default in signatures + //(meths |> List.forall (fun m -> m.IsAbstract || m.IsDefiniteFSharpOverride || not m.IsInstance)) && + //(props |> List.forall (fun m -> (not m.HasGetter || m.GetterMethod.IsAbstract))) && + //(props |> List.forall (fun m -> (not m.HasSetter || m.SetterMethod.IsAbstract))) && + ctors.IsEmpty && + instanceVals.IsEmpty && + staticVals.IsEmpty + | Some "struct" -> + true + | Some "interface" -> + meths.IsEmpty && + props.IsEmpty + | _ -> + false + + let start = if needsStartEnd then start else None + + let addMaxMembers reprL = + if isNil allDecls then + reprL + else + let memberLs = applyMaxMembers denv.maxMembers allDecls + reprL @@ aboveListL memberLs + + let addReprAccessL l = + layoutAccessibility denv tycon.TypeReprAccessibility l - let erasedL = -#if SHOW_ERASURE - if tcref.IsProvidedErasedTycon then - [ wordL ""; wordL (FSComp.SR.erasedTo()) ^^ PrintIL.layoutILTypeRef { denv with shortTypeNames = false } tcref.CompiledRepresentationForNamedType; wordL "" ] + let addLhs rhsL = + let brk = not (isNil allDecls) || breakTypeDefnEqn repr + if brk then + (lhsL ^^ WordL.equals) @@* rhsL else -#endif - [] - let decls = inherits @ iimplsLs @ ctorLs @ membLs @ nestedTypeLs @ erasedL - if isNil decls then - lhsL - else - let declsL = (inherits @ iimplsLs @ ctorLs @ membLs @ nestedTypeLs @ erasedL) |> applyMaxMembers denv.maxMembers |> aboveListL - let rhsL = match start with Some s -> (wordL s @@-- declsL) @@ WordL.keywordEnd | None -> declsL - (lhsL ^^ WordL.equals) @@-- rhsL -#endif + (lhsL ^^ WordL.equals) -* rhsL + + let typeDeclL = + + match repr with + | TFSharpRecdRepr _ -> + let denv = denv.AddAccessibility tycon.TypeReprAccessibility + + // For records, use multi-line layout as soon as there is XML doc + // type R = + // { + // /// ABC + // Field1: int + // + // /// ABC + // Field2: int + // } + // + // For records, use multi-line layout as soon as there is more than one field + // type R = + // { + // Field1: int + // Field2: int + // } + let useMultiLine = + let members = + match denv.maxMembers with + | None -> tycon.TrueFieldsAsList + | Some n -> tycon.TrueFieldsAsList |> List.truncate n + members.Length > 1 || + members |> List.exists (fun m -> not m.XmlDoc.IsEmpty) + + tycon.TrueFieldsAsList + |> List.map (layoutRecdField id false denv infoReader tcref) + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> (if useMultiLine then braceMultiLineL else braceL) + |> addReprAccessL + |> addMaxMembers + |> addLhs + + | TFSharpUnionRepr _ -> + let denv = denv.AddAccessibility tycon.TypeReprAccessibility + tycon.UnionCasesAsList + |> layoutUnionCases denv infoReader tcref + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> addReprAccessL + |> addMaxMembers + |> addLhs + + | TFSharpObjectRepr { fsobjmodel_kind = TFSharpDelegate slotSig } -> + let (TSlotSig(_, _, _, _, paraml, rty)) = slotSig + let rty = GetFSharpViewOfReturnType denv.g rty + let delegateL = WordL.keywordDelegate ^^ WordL.keywordOf -* layoutTopType denv SimplifyTypes.typeSimplificationInfo0 (paraml |> List.mapSquared (fun sp -> (sp.Type, ValReprInfo.unnamedTopArg1))) rty [] + delegateL + |> addLhs + + // Measure declarations are '[] type kg' unless abbreviations + | TFSharpObjectRepr _ when isMeasure -> + lhsL + + | TFSharpObjectRepr { fsobjmodel_kind = TFSharpEnum } -> + tycon.TrueFieldsAsList + |> List.map (fun f -> + match f.LiteralValue with + | None -> emptyL + | Some c -> + WordL.bar ^^ + wordL (tagField f.DisplayName) ^^ + WordL.equals ^^ + layoutConst denv.g ty c) + |> aboveListL + |> addLhs + + | TFSharpObjectRepr _ when isNil allDecls -> + lhsL + + | TFSharpObjectRepr _ -> + allDecls + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> addLhs + + | TAsmRepr _ -> + let asmL = wordL (tagText "(# \"\" #)") + asmL + |> addLhs + + | TMeasureableRepr ty -> + layoutType denv ty + |> addLhs + + | TILObjectRepr _ when tycon.ILTyconRawMetadata.IsEnum -> + infoReader.GetILFieldInfosOfType (None, ad, m, ty) + |> List.filter (fun x -> x.FieldName <> "value__") + |> List.map (fun x -> PrintIL.layoutILEnumCase x.FieldName x.LiteralValue) + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> addLhs - let layoutTycon (denv: DisplayEnv) (infoReader: InfoReader) ad m simplified typewordL (tycon: Tycon) = - let g = denv.g - let _, ty = generalizeTyconRef (mkLocalTyconRef tycon) - let start, name = - let n = tycon.DisplayName - if isStructTy g ty then Some "struct", tagStruct n - elif isInterfaceTy g ty then Some "interface", tagInterface n - elif isClassTy g ty then (if simplified then None else Some "class" ), tagClass n - else None, tagUnknownType n - let name = mkNav tycon.DefinitionRange name - let nameL = layoutAccessibility denv tycon.Accessibility (wordL name) - let denv = denv.AddAccessibility tycon.Accessibility - let lhsL = - let tps = tycon.TyparsNoRange - let tpsL = layoutTyparDecls denv nameL tycon.IsPrefixDisplay tps - typewordL ^^ tpsL - let start = Option.map tagKeyword start -#if !NO_EXTENSIONTYPING - match tycon.IsProvided with - | true -> - layoutProvidedTycon denv infoReader ad m start lhsL ty - | false -> -#else - ignore (infoReader, ad, m) -#endif - let memberImplementLs, memberCtorLs, memberInstanceLs, memberStaticLs = - let adhoc = - tycon.MembersOfFSharpTyconSorted - |> List.filter (fun v -> not v.IsDispatchSlot) - |> List.filter (fun v -> not v.Deref.IsClassConstructor) - |> List.filter (fun v -> - match v.MemberInfo.Value.ImplementedSlotSigs with - | TSlotSig(_, oty, _, _, _, _) :: _ -> - // Don't print overrides in HTML docs - denv.showOverrides && - // Don't print individual methods forming interface implementations - these are currently never exported - not (isInterfaceTy denv.g oty) - | [] -> true) - |> List.filter (fun v -> denv.showObsoleteMembers || not (CheckFSharpAttributesForObsolete denv.g v.Attribs)) - |> List.filter (fun v -> denv.showHiddenMembers || not (CheckFSharpAttributesForHidden denv.g v.Attribs)) - // sort - let sortKey (v: ValRef) = - (not v.IsConstructor, // constructors before others - v.Id.idText, // sort by name - (if v.IsCompiledAsTopLevel then v.ValReprInfo.Value.NumCurriedArgs else 0), // sort by #curried - (if v.IsCompiledAsTopLevel then v.ValReprInfo.Value.AritiesOfArgs else [])) // sort by arity - let adhoc = adhoc |> List.sortBy sortKey - let iimpls = - match tycon.TypeReprInfo with - | TFSharpObjectRepr r when (match r.fsobjmodel_kind with TTyconInterface -> true | _ -> false) -> [] - | _ -> tycon.ImmediateInterfacesOfFSharpTycon - let iimpls = iimpls |> List.filter (fun (_, compgen, _) -> not compgen) - // if TTyconInterface, the iimpls should be printed as inherited interfaces - let iimplsLs = iimpls |> List.map (fun (ty, _, _) -> wordL (tagKeyword "interface") --- layoutType denv ty) - let adhocCtorsLs = adhoc |> List.filter (fun v -> v.IsConstructor) |> List.map (fun vref -> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv vref.Deref) - let adhocInstanceLs = adhoc |> List.filter (fun v -> not v.IsConstructor && v.IsInstanceMember) |> List.map (fun vref -> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv vref.Deref) - let adhocStaticLs = adhoc |> List.filter (fun v -> not v.IsConstructor && not v.IsInstanceMember) |> List.map (fun vref -> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv vref.Deref) - iimplsLs, adhocCtorsLs, adhocInstanceLs, adhocStaticLs - let memberLs = memberImplementLs @ memberCtorLs @ memberInstanceLs @ memberStaticLs - let addMembersAsWithEnd reprL = - if isNil memberLs then reprL - else - let memberLs = applyMaxMembers denv.maxMembers memberLs - if simplified then reprL @@-- aboveListL memberLs - else reprL @@ (WordL.keywordWith @@-- aboveListL memberLs) @@ WordL.keywordEnd - - let reprL = - let repr = tycon.TypeReprInfo - match repr with - | TRecdRepr _ - | TUnionRepr _ - | TFSharpObjectRepr _ - | TAsmRepr _ - | TMeasureableRepr _ - | TILObjectRepr _ -> - let brk = not (isNil memberLs) || breakTypeDefnEqn repr - let rhsL = - let addReprAccessL l = layoutAccessibility denv tycon.TypeReprAccessibility l - let denv = denv.AddAccessibility tycon.TypeReprAccessibility - match repr with - | TRecdRepr _ -> - let recdFieldRefL fld = layoutRecdField false denv fld - - let recdL = - tycon.TrueFieldsAsList - |> List.map recdFieldRefL - |> applyMaxMembers denv.maxMembers - |> aboveListL - |> braceL - - Some (addMembersAsWithEnd (addReprAccessL recdL)) - - | TFSharpObjectRepr r -> - match r.fsobjmodel_kind with - | TTyconDelegate (TSlotSig(_, _, _, _, paraml, rty)) -> - let rty = GetFSharpViewOfReturnType denv.g rty - Some (WordL.keywordDelegate ^^ WordL.keywordOf --- layoutTopType denv SimplifyTypes.typeSimplificationInfo0 (paraml |> List.mapSquared (fun sp -> (sp.Type, ValReprInfo.unnamedTopArg1))) rty []) - | _ -> - match r.fsobjmodel_kind with - | TTyconEnum -> - tycon.TrueFieldsAsList - |> List.map (fun f -> - match f.LiteralValue with - | None -> emptyL - | Some c -> WordL.bar ^^ - wordL (tagField f.Name) ^^ - WordL.equals ^^ - layoutConst denv.g ty c) - |> aboveListL - |> Some - | _ -> - let inherits = - match r.fsobjmodel_kind, tycon.TypeContents.tcaug_super with - | TTyconClass, Some super -> [wordL (tagKeyword "inherit") ^^ (layoutType denv super)] - | TTyconInterface, _ -> - tycon.ImmediateInterfacesOfFSharpTycon - |> List.filter (fun (_, compgen, _) -> not compgen) - |> List.map (fun (ity, _, _) -> wordL (tagKeyword "inherit") ^^ (layoutType denv ity)) - | _ -> [] - let vsprs = - tycon.MembersOfFSharpTyconSorted - |> List.filter (fun v -> isNil (Option.get v.MemberInfo).ImplementedSlotSigs && v.IsDispatchSlot) - |> List.map (fun vref -> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv vref.Deref) - let staticValsLs = - tycon.TrueFieldsAsList - |> List.filter (fun f -> f.IsStatic) - |> List.map (fun f -> WordL.keywordStatic ^^ WordL.keywordVal ^^ layoutRecdField true denv f) - let instanceValsLs = - tycon.TrueFieldsAsList - |> List.filter (fun f -> not f.IsStatic) - |> List.map (fun f -> WordL.keywordVal ^^ layoutRecdField true denv f) - let allDecls = inherits @ memberImplementLs @ memberCtorLs @ instanceValsLs @ vsprs @ memberInstanceLs @ staticValsLs @ memberStaticLs - if isNil allDecls then - None - else - let allDecls = applyMaxMembers denv.maxMembers allDecls - let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil allDecls | _ -> false - if emptyMeasure then None else - let declsL = aboveListL allDecls - let declsL = match start with Some s -> (wordL s @@-- declsL) @@ wordL (tagKeyword "end") | None -> declsL - Some declsL - | TUnionRepr _ -> - let layoutUnionCases = tycon.UnionCasesAsList |> layoutUnionCases denv |> applyMaxMembers denv.maxMembers |> aboveListL - Some (addMembersAsWithEnd (addReprAccessL layoutUnionCases)) - | TAsmRepr _ -> - Some (wordL (tagText "(# \"\" #)")) - | TMeasureableRepr ty -> - Some (layoutType denv ty) - | TILObjectRepr _ -> - let td = tycon.ILTyconRawMetadata - Some (PrintIL.layoutILTypeDef denv td) - | _ -> None - - let brk = match tycon.TypeReprInfo with | TILObjectRepr _ -> true | _ -> brk - match rhsL with - | None -> lhsL - | Some rhsL -> - if brk then - (lhsL ^^ WordL.equals) @@-- rhsL - else - (lhsL ^^ WordL.equals) --- rhsL - - | _ -> - match tycon.TypeAbbrev with - | None -> - addMembersAsWithEnd (lhsL ^^ WordL.equals) - | Some a -> - (lhsL ^^ WordL.equals) --- (layoutType { denv with shortTypeNames = false } a) - layoutAttribs denv ty tycon.TypeOrMeasureKind tycon.Attribs reprL + | TILObjectRepr _ -> + allDecls + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> addLhs + + | TNoRepr when tycon.TypeAbbrev.IsSome -> + let abbreviatedType = tycon.TypeAbbrev.Value + (lhsL ^^ WordL.equals) -* (layoutType { denv with shortTypeNames = false } abbreviatedType) + + | _ when isNil allDecls -> + lhsL + + | TProvidedNamespaceRepr _ + | TProvidedTypeRepr _ + | TNoRepr -> + allDecls + |> applyMaxMembers denv.maxMembers + |> aboveListL + |> addLhs + + typeDeclL + |> layoutAttribs denv start false tycon.TypeOrMeasureKind tycon.Attribs + |> layoutXmlDocOfEntity denv infoReader tcref // Layout: exception definition - let layoutExnDefn denv (exnc: Entity) = - let nm = exnc.LogicalName - let nmL = wordL (tagClass nm) - let nmL = layoutAccessibility denv exnc.TypeReprAccessibility nmL - let exnL = wordL (tagKeyword "exception") ^^ nmL // need to tack on the Exception at the right of the name for goto definition + let layoutExnDefn denv infoReader (exncref: EntityRef) = + let (-*) = if denv.printVerboseSignatures then (-----) else (---) + let exnc = exncref.Deref + let nameL = ConvertNameToDisplayLayout (tagClass >> mkNav exncref.DefinitionRange >> wordL) exnc.DisplayNameCore + let nameL = layoutAccessibility denv exnc.TypeReprAccessibility nameL + let exnL = wordL (tagKeyword "exception") ^^ nameL // need to tack on the Exception at the right of the name for goto definition let reprL = match exnc.ExceptionInfo with - | TExnAbbrevRepr ecref -> WordL.equals --- layoutTyconRef denv ecref - | TExnAsmRepr _ -> WordL.equals --- wordL (tagText "(# ... #)") + | TExnAbbrevRepr ecref -> WordL.equals -* layoutTyconRef denv ecref + | TExnAsmRepr _ -> WordL.equals -* wordL (tagText "(# ... #)") | TExnNone -> emptyL | TExnFresh r -> match r.TrueFieldsAsList with | [] -> emptyL - | r -> WordL.keywordOf --- layoutUnionCaseFields denv false r + | r -> WordL.keywordOf -* layoutUnionCaseFields denv infoReader false exncref r - exnL ^^ reprL + let overallL = exnL ^^ reprL + layoutXmlDocOfEntity denv infoReader exncref overallL // Layout: module spec let layoutTyconDefns denv infoReader ad m (tycons: Tycon list) = match tycons with | [] -> emptyL - | [h] when h.IsExceptionDecl -> layoutExnDefn denv h + | [h] when h.IsExceptionDecl -> layoutExnDefn denv infoReader (mkLocalEntityRef h) | h :: t -> - let x = layoutTycon denv infoReader ad m false WordL.keywordType h - let xs = List.map (layoutTycon denv infoReader ad m false (wordL (tagKeyword "and"))) t + let x = layoutTyconDefn denv infoReader ad m false WordL.keywordType (mkLocalEntityRef h) + let xs = List.map (mkLocalEntityRef >> layoutTyconDefn denv infoReader ad m false (wordL (tagKeyword "and"))) t aboveListL (x :: xs) + let rec fullPath (mspec: ModuleOrNamespace) acc = + if mspec.IsNamespace then + match mspec.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions |> List.tryHead with + | Some next when next.IsNamespace -> + fullPath next (acc @ [next.DisplayNameCore]) + | _ -> + acc, mspec + else + acc, mspec + + let rec layoutModuleOrNamespace (denv: DisplayEnv) (infoReader: InfoReader) ad m isFirstTopLevel (mspec: ModuleOrNamespace) = + let (@@*) = if denv.printVerboseSignatures then (@@----) else (@@--) + + let outerPath = mspec.CompilationPath.AccessPath + + let path, mspec = fullPath mspec [mspec.DisplayNameCore] + + let denv = + let outerPath = outerPath |> List.map fst + denv.AddOpenPath (outerPath @ path) + + let headerL = + if mspec.IsNamespace then + // This is a container namespace. We print the header when we get to the first concrete module. + let pathL = path |> List.map (ConvertNameToDisplayLayout (tagNamespace >> wordL)) + wordL (tagKeyword "namespace") ^^ sepListL SepL.dot pathL + else + // This is a module + let name = path |> List.last + let nameL = ConvertNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) name + let nameL = + match path with + | [_] -> + nameL + | _ -> + let innerPath = path.[..path.Length - 2] + let innerPathL = innerPath |> List.map (ConvertNameToDisplayLayout (tagNamespace >> wordL)) + sepListL SepL.dot innerPathL ^^ SepL.dot ^^ nameL + + let modNameL = wordL (tagKeyword "module") ^^ nameL + let modNameEqualsL = modNameL ^^ WordL.equals + let modIsEmpty = + mspec.ModuleOrNamespaceType.AllEntities |> Seq.isEmpty && + mspec.ModuleOrNamespaceType.AllValsAndMembers |> Seq.isEmpty + + // Check if its an outer module or a nested module + if (outerPath |> List.forall (fun (_, istype) -> istype = Namespace)) && isNil outerPath then + // If so print a "module" declaration + modNameL + elif modIsEmpty then + modNameEqualsL ^^ wordL (tagKeyword "begin") ^^ WordL.keywordEnd + else + // Otherwise this is an outer module contained immediately in a namespace + // We already printed the namespace declaration earlier. So just print the + // module now. + modNameEqualsL + + let headerL = + layoutAttribs denv None false mspec.TypeOrMeasureKind mspec.Attribs headerL + + let shouldShow (v: Val) = + (denv.showObsoleteMembers || not (CheckFSharpAttributesForObsolete denv.g v.Attribs)) && + (denv.showHiddenMembers || not (CheckFSharpAttributesForHidden denv.g v.Attribs)) + + let entityLs = + if mspec.IsNamespace then [] + else + mspec.ModuleOrNamespaceType.AllEntities + |> QueueList.toList + |> List.map (fun entity -> layoutEntityDefn denv infoReader ad m (mkLocalEntityRef entity)) + + let valLs = + if mspec.IsNamespace then [] + else + mspec.ModuleOrNamespaceType.AllValsAndMembers + |> QueueList.toList + |> List.filter shouldShow + |> List.sortBy (fun v -> v.DisplayNameCore) + |> List.map (mkLocalValRef >> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader) + + if List.isEmpty entityLs && List.isEmpty valLs then + headerL + else + let entitiesL = + entityLs + |> aboveListL + + let valsL = + valLs + |> aboveListL + + if isFirstTopLevel then + aboveListL + [ + headerL + entitiesL + valsL + ] + else + headerL @@* entitiesL @@ valsL + + and layoutEntityDefn (denv: DisplayEnv) (infoReader: InfoReader) ad m (eref: EntityRef) = + if eref.IsModuleOrNamespace then + layoutModuleOrNamespace denv infoReader ad m false eref.Deref + |> layoutXmlDocOfEntity denv infoReader eref + elif eref.IsExceptionDecl then + layoutExnDefn denv infoReader eref + else + layoutTyconDefn denv infoReader ad m true WordL.keywordType eref //-------------------------------------------------------------------------- -module private InferredSigPrinting = +module InferredSigPrinting = open PrintTypes /// Layout the inferred signature of a compilation unit let layoutInferredSigOfModuleExpr showHeader denv infoReader ad m expr = + let (@@*) = if denv.printVerboseSignatures then (@@----) else (@@--) let rec isConcreteNamespace x = match x with - | TMDefRec(_, tycons, mbinds, _) -> + | TMDefRec(_, _opens, tycons, mbinds, _) -> not (isNil tycons) || (mbinds |> List.exists (function ModuleOrNamespaceBinding.Binding _ -> true | ModuleOrNamespaceBinding.Module(x, _) -> not x.IsNamespace)) | TMDefLet _ -> true | TMDefDo _ -> true + | TMDefOpens _ -> false | TMDefs defs -> defs |> List.exists isConcreteNamespace | TMAbstract(ModuleOrNamespaceExprWithSig(_, def, _)) -> isConcreteNamespace def @@ -1885,19 +2195,21 @@ module private InferredSigPrinting = let filterExtMem (v: Val) = v.IsExtensionMember match x with - | TMDefRec(_, tycons, mbinds, _) -> + | TMDefRec(_, _opens, tycons, mbinds, _) -> TastDefinitionPrinting.layoutTyconDefns denv infoReader ad m tycons @@ (mbinds |> List.choose (function ModuleOrNamespaceBinding.Binding bind -> Some bind | _ -> None) |> valsOfBinds |> List.filter filterExtMem - |> TastDefinitionPrinting.layoutExtensionMembers denv) @@ + |> List.map mkLocalValRef + |> TastDefinitionPrinting.layoutExtensionMembers denv infoReader) @@ (mbinds |> List.choose (function ModuleOrNamespaceBinding.Binding bind -> Some bind | _ -> None) |> valsOfBinds |> List.filter filterVal - |> List.map (PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv) + |> List.map mkLocalValRef + |> List.map (PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader) |> aboveListL) @@ (mbinds @@ -1908,9 +2220,12 @@ module private InferredSigPrinting = | TMDefLet(bind, _) -> ([bind.Var] |> List.filter filterVal - |> List.map (PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv) + |> List.map mkLocalValRef + |> List.map (PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader) |> aboveListL) + | TMDefOpens _ -> emptyL + | TMDefs defs -> imdefsL denv defs | TMDefDo _ -> emptyL @@ -1918,58 +2233,75 @@ module private InferredSigPrinting = | TMAbstract mexpr -> imexprLP denv mexpr and imbindL denv (mspec, def) = - let nm = mspec.DemangledModuleOrNamespaceName let innerPath = (fullCompPathOfModuleOrNamespace mspec).AccessPath let outerPath = mspec.CompilationPath.AccessPath let denv = denv.AddOpenPath (List.map fst innerPath) if mspec.IsNamespace then let basic = imdefL denv def - // Check if this namespace contains anything interesting - if isConcreteNamespace def then - // This is a container namespace. We print the header when we get to the first concrete module. - let headerL = - wordL (tagKeyword "namespace") ^^ sepListL SepL.dot (List.map (fst >> tagNamespace >> wordL) innerPath) - headerL @@-- basic - else - // This is a namespace that only contains namespaces. Skip the header - basic + let basicL = + // Check if this namespace contains anything interesting + if isConcreteNamespace def then + let pathL = innerPath |> List.map (fst >> ConvertNameToDisplayLayout (tagNamespace >> wordL)) + // This is a container namespace. We print the header when we get to the first concrete module. + let headerL = + wordL (tagKeyword "namespace") ^^ sepListL SepL.dot pathL + headerL @@* basic + else + // This is a namespace that only contains namespaces. Skip the header + basic + // NOTE: explicitly not calling `layoutXmlDoc` here, because even though + // `ModuleOrNamespace` has a field for XmlDoc, it is never present at the parser + // level for namespaces. This should be changed if the parser/spec changes. + basicL else // This is a module - let nmL = layoutAccessibility denv mspec.Accessibility (wordL (tagModule nm)) - let denv = denv.AddAccessibility mspec.Accessibility + let nmL = ConvertNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) mspec.DisplayNameCore + let nmL = layoutAccessibility denv mspec.Accessibility nmL + let denv = denv.AddAccessibility mspec.Accessibility let basic = imdefL denv def - // Check if its an outer module or a nested module - if (outerPath |> List.forall (fun (_, istype) -> istype = Namespace) ) then - // OK, this is an outer module - if showHeader then - // OK, we're not in F# Interactive - // Check if this is an outer module with no namespace - if isNil outerPath then - // If so print a "module" declaration - (wordL (tagKeyword "module") ^^ nmL) @@ basic - else - // Otherwise this is an outer module contained immediately in a namespace - // We already printed the namespace declaration earlier. So just print the - // module now. - ((wordL (tagKeyword"module") ^^ nmL ^^ WordL.equals ^^ wordL (tagKeyword "begin")) @@-- basic) @@ WordL.keywordEnd + let modNameL = wordL (tagKeyword "module") ^^ nmL + let modNameEqualsL = modNameL ^^ WordL.equals + let modIsOuter = (outerPath |> List.forall (fun (_, istype) -> istype = Namespace) ) + let basicL = + // Check if its an outer module or a nested module + if modIsOuter then + // OK, this is an outer module + if showHeader then + // OK, we're not in F# Interactive + // Check if this is an outer module with no namespace + if isNil outerPath then + // If so print a "module" declaration, no indentation + modNameL @@ basic + else + // Otherwise this is an outer module contained immediately in a namespace + // We already printed the namespace declaration earlier. So just print the + // module now. + if isEmptyL basic then + modNameEqualsL ^^ WordL.keywordBegin ^^ WordL.keywordEnd + else + modNameEqualsL @@* basic + else + // OK, we're in F# Interactive, presumably the implicit module for each interaction. + basic else - // OK, we're in F# Interactive, presumably the implicit module for each interaction. - basic - else - // OK, this is a nested module - ((wordL (tagKeyword "module") ^^ nmL ^^ WordL.equals ^^ wordL (tagKeyword"begin")) @@-- basic) @@ WordL.keywordEnd + // OK, this is a nested module, with indentation + if isEmptyL basic then + ((modNameEqualsL ^^ wordL (tagKeyword"begin")) @@* basic) @@ WordL.keywordEnd + else + modNameEqualsL @@* basic + layoutXmlDoc denv true mspec.XmlDoc basicL imexprL denv expr //-------------------------------------------------------------------------- -module private PrintData = +module PrintData = open PrintTypes /// Nice printing of a subset of expressions, e.g. for refutations in pattern matching let rec dataExprL denv expr = dataExprWrapL denv false expr - and private dataExprWrapL denv isAtomic expr = + and dataExprWrapL denv isAtomic expr = match expr with | Expr.Const (c, _, ty) -> if isEnumTy denv.g ty then @@ -1977,29 +2309,43 @@ module private PrintData = else layoutConst denv.g ty c - | Expr.Val (v, _, _) -> wordL (tagLocal v.DisplayName) - | Expr.Link rX -> dataExprWrapL denv isAtomic (!rX) - | Expr.Op (TOp.UnionCase (c), _, args, _) -> + | Expr.Val (v, _, _) -> + wordL (tagLocal v.DisplayName) + + | Expr.Link rX -> + dataExprWrapL denv isAtomic rX.Value + + | Expr.Op (TOp.UnionCase c, _, args, _) -> if denv.g.unionCaseRefEq c denv.g.nil_ucref then wordL (tagPunctuation "[]") elif denv.g.unionCaseRefEq c denv.g.cons_ucref then - let rec strip = function (Expr.Op (TOp.UnionCase _, _, [h;t], _)) -> h :: strip t | _ -> [] + let rec strip = function Expr.Op (TOp.UnionCase _, _, [h;t], _) -> h :: strip t | _ -> [] listL (dataExprL denv) (strip expr) elif isNil args then wordL (tagUnionCase c.CaseName) else (wordL (tagUnionCase c.CaseName) ++ bracketL (commaListL (dataExprsL denv args))) - | Expr.Op (TOp.ExnConstr (c), _, args, _) -> (wordL (tagMethod c.LogicalName) ++ bracketL (commaListL (dataExprsL denv args))) - | Expr.Op (TOp.Tuple _, _, xs, _) -> tupleL (dataExprsL denv xs) + | Expr.Op (TOp.ExnConstr c, _, args, _) -> + (wordL (tagMethod c.LogicalName) ++ bracketL (commaListL (dataExprsL denv args))) + + | Expr.Op (TOp.Tuple _, _, xs, _) -> + tupleL (dataExprsL denv xs) + | Expr.Op (TOp.Recd (_, tc), _, xs, _) -> let fields = tc.TrueInstanceFieldsAsList let lay fs x = (wordL (tagRecordField fs.rfield_id.idText) ^^ sepL (tagPunctuation "=")) --- (dataExprL denv x) - leftL (tagPunctuation "{") ^^ semiListL (List.map2 lay fields xs) ^^ rightL (tagPunctuation "}") - | Expr.Op (TOp.ValFieldGet (RecdFieldRef.RFRef (tcref, name)), _, _, _) -> + braceL (semiListL (List.map2 lay fields xs)) + + | Expr.Op (TOp.ValFieldGet (RecdFieldRef.RecdFieldRef (tcref, name)), _, _, _) -> (layoutTyconRef denv tcref) ^^ sepL (tagPunctuation ".") ^^ wordL (tagField name) - | Expr.Op (TOp.Array, [_], xs, _) -> leftL (tagPunctuation "[|") ^^ semiListL (dataExprsL denv xs) ^^ RightL.rightBracketBar - | _ -> wordL (tagPunctuation "?") - and private dataExprsL denv xs = List.map (dataExprL denv) xs + + | Expr.Op (TOp.Array, [_], xs, _) -> + leftL (tagPunctuation "[|") ^^ semiListL (dataExprsL denv xs) ^^ RightL.rightBracketBar + + | _ -> + wordL (tagPunctuation "?") + + and dataExprsL denv xs = List.map (dataExprL denv) xs let dataExprL denv expr = PrintData.dataExprL denv expr @@ -2007,56 +2353,88 @@ let dataExprL denv expr = PrintData.dataExprL denv expr // Print Signatures/Types - output functions //-------------------------------------------------------------------------- +let outputValOrMember denv infoReader os x = x |> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader |> bufferL os + +let stringValOrMember denv infoReader x = x |> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader |> showL -let outputValOrMember denv os x = x |> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv |> bufferL os -let stringValOrMember denv x = x |> PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv |> showL /// Print members with a qualification showing the type they are contained in -let layoutQualifiedValOrMember denv typarInst v = PrintTastMemberOrVals.prettyLayoutOfValOrMember { denv with showMemberContainers=true; } typarInst v -let outputQualifiedValOrMember denv os v = outputValOrMember { denv with showMemberContainers=true; } os v -let outputQualifiedValSpec denv os v = outputQualifiedValOrMember denv os v -let stringOfQualifiedValOrMember denv v = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst { denv with showMemberContainers=true; } v |> showL +let layoutQualifiedValOrMember denv infoReader typarInst v = PrintTastMemberOrVals.prettyLayoutOfValOrMember { denv with showMemberContainers=true; } infoReader typarInst v + +let outputQualifiedValOrMember denv infoReader os v = outputValOrMember { denv with showMemberContainers=true; } infoReader os v + +let outputQualifiedValSpec denv infoReader os v = outputQualifiedValOrMember denv infoReader os v + +let stringOfQualifiedValOrMember denv infoReader v = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst { denv with showMemberContainers=true; } infoReader v |> showL /// Convert a MethInfo to a string -let formatMethInfoToBufferFreeStyle amap m denv buf d = InfoMemberPrinting.formatMethInfoToBufferFreeStyle amap m denv buf d -let prettyLayoutOfMethInfoFreeStyle amap m denv typarInst minfo = InfoMemberPrinting.prettyLayoutOfMethInfoFreeStyle amap m denv typarInst minfo +let formatMethInfoToBufferFreeStyle infoReader m denv buf d = InfoMemberPrinting.formatMethInfoToBufferFreeStyle infoReader m denv buf d + +let prettyLayoutOfMethInfoFreeStyle infoReader m denv typarInst minfo = InfoMemberPrinting.prettyLayoutOfMethInfoFreeStyle infoReader m denv typarInst minfo /// Convert a PropInfo to a string let prettyLayoutOfPropInfoFreeStyle g amap m denv d = InfoMemberPrinting.prettyLayoutOfPropInfoFreeStyle g amap m denv d /// Convert a MethInfo to a string -let stringOfMethInfo amap m denv d = bufs (fun buf -> InfoMemberPrinting.formatMethInfoToBufferFreeStyle amap m denv buf d) +let stringOfMethInfo infoReader m denv minfo = + bufs (fun buf -> InfoMemberPrinting.formatMethInfoToBufferFreeStyle infoReader m denv buf minfo) + +/// Convert MethInfos to lines separated by newline including a newline as the first character +let multiLineStringOfMethInfos infoReader m denv minfos = + minfos + |> List.map (stringOfMethInfo infoReader m denv) + |> List.map (sprintf "%s %s" Environment.NewLine) + |> String.concat "" /// Convert a ParamData to a string let stringOfParamData denv paramData = bufs (fun buf -> InfoMemberPrinting.formatParamDataToBuffer denv buf paramData) + let layoutOfParamData denv paramData = InfoMemberPrinting.layoutParamData denv paramData -let outputILTypeRef denv os x = x |> PrintIL.layoutILTypeRef denv |> bufferL os -let layoutILTypeRef denv x = x |> PrintIL.layoutILTypeRef denv -let outputExnDef denv os x = x |> TastDefinitionPrinting.layoutExnDefn denv |> bufferL os -let layoutExnDef denv x = x |> TastDefinitionPrinting.layoutExnDefn denv + +let layoutExnDef denv infoReader x = x |> TastDefinitionPrinting.layoutExnDefn denv infoReader + let stringOfTyparConstraints denv x = x |> PrintTypes.layoutConstraintsWithInfo denv SimplifyTypes.typeSimplificationInfo0 |> showL -let outputTycon denv infoReader ad m (* width *) os x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Layout.squashTo width *) |> bufferL os -let layoutTycon denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTycon denv infoReader ad m true WordL.keywordType x (* |> Layout.squashTo width *) -let layoutUnionCases denv x = x |> TastDefinitionPrinting.layoutUnionCaseFields denv true -let outputUnionCases denv os x = x |> TastDefinitionPrinting.layoutUnionCaseFields denv true |> bufferL os + +let layoutTyconDefn denv infoReader ad m (* width *) x = TastDefinitionPrinting.layoutTyconDefn denv infoReader ad m true WordL.keywordType (mkLocalEntityRef x) (* |> Display.squashTo width *) + +let layoutEntityDefn denv infoReader ad m x = TastDefinitionPrinting.layoutEntityDefn denv infoReader ad m x + +let layoutUnionCases denv infoReader enclosingTcref x = x |> TastDefinitionPrinting.layoutUnionCaseFields denv infoReader true enclosingTcref + /// Pass negative number as pos in case of single cased discriminated unions let isGeneratedUnionCaseField pos f = TastDefinitionPrinting.isGeneratedUnionCaseField pos f + let isGeneratedExceptionField pos f = TastDefinitionPrinting.isGeneratedExceptionField pos f + let stringOfTyparConstraint denv tpc = stringOfTyparConstraints denv [tpc] + let stringOfTy denv x = x |> PrintTypes.layoutType denv |> showL + let prettyLayoutOfType denv x = x |> PrintTypes.prettyLayoutOfType denv + let prettyLayoutOfTypeNoCx denv x = x |> PrintTypes.prettyLayoutOfTypeNoConstraints denv + let prettyStringOfTy denv x = x |> PrintTypes.prettyLayoutOfType denv |> showL + let prettyStringOfTyNoCx denv x = x |> PrintTypes.prettyLayoutOfTypeNoConstraints denv |> showL -let stringOfRecdField denv x = x |> TastDefinitionPrinting.layoutRecdField false denv |> showL -let stringOfUnionCase denv x = x |> TastDefinitionPrinting.layoutUnionCase denv WordL.bar |> showL -let stringOfExnDef denv x = x |> TastDefinitionPrinting.layoutExnDefn denv |> showL + +let stringOfRecdField denv infoReader enclosingTcref x = x |> TastDefinitionPrinting.layoutRecdField id false denv infoReader enclosingTcref |> showL + +let stringOfUnionCase denv infoReader enclosingTcref x = x |> TastDefinitionPrinting.layoutUnionCase denv infoReader WordL.bar enclosingTcref |> showL + +let stringOfExnDef denv infoReader x = x |> TastDefinitionPrinting.layoutExnDefn denv infoReader |> showL let stringOfFSAttrib denv x = x |> PrintTypes.layoutAttrib denv |> squareAngleL |> showL + let stringOfILAttrib denv x = x |> PrintTypes.layoutILAttrib denv |> squareAngleL |> showL let layoutInferredSigOfModuleExpr showHeader denv infoReader ad m expr = InferredSigPrinting.layoutInferredSigOfModuleExpr showHeader denv infoReader ad m expr -let prettyLayoutOfValOrMember denv typarInst v = PrintTastMemberOrVals.prettyLayoutOfValOrMember denv typarInst v -let prettyLayoutOfValOrMemberNoInst denv v = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv v + +let prettyLayoutOfValOrMember denv infoReader typarInst v = PrintTastMemberOrVals.prettyLayoutOfValOrMember denv infoReader typarInst v + +let prettyLayoutOfValOrMemberNoInst denv infoReader v = PrintTastMemberOrVals.prettyLayoutOfValOrMemberNoInst denv infoReader v + +let prettyLayoutOfMemberNoInstShort denv v = PrintTastMemberOrVals.prettyLayoutOfMemberNoInstShort denv v + let prettyLayoutOfInstAndSig denv x = PrintTypes.prettyLayoutOfInstAndSig denv x /// Generate text for comparing two types. @@ -2111,18 +2489,17 @@ let minimalStringsOfTwoTypes denv t1 t2= (makeName t1, makeName t2, stringOfTyparConstraints denv tpcs) - // Note: Always show imperative annotations when comparing value signatures -let minimalStringsOfTwoValues denv v1 v2= +let minimalStringsOfTwoValues denv infoReader v1 v2= let denvMin = { denv with showImperativeTyparAnnotations=true; showConstraintTyparAnnotations=false } - let min1 = bufs (fun buf -> outputQualifiedValOrMember denvMin buf v1) - let min2 = bufs (fun buf -> outputQualifiedValOrMember denvMin buf v2) + let min1 = bufs (fun buf -> outputQualifiedValOrMember denvMin infoReader buf v1) + let min2 = bufs (fun buf -> outputQualifiedValOrMember denvMin infoReader buf v2) if min1 <> min2 then (min1, min2) else let denvMax = { denv with showImperativeTyparAnnotations=true; showConstraintTyparAnnotations=true } - let max1 = bufs (fun buf -> outputQualifiedValOrMember denvMax buf v1) - let max2 = bufs (fun buf -> outputQualifiedValOrMember denvMax buf v2) + let max1 = bufs (fun buf -> outputQualifiedValOrMember denvMax infoReader buf v1) + let max2 = bufs (fun buf -> outputQualifiedValOrMember denvMax infoReader buf v2) max1, max2 let minimalStringOfType denv ty = @@ -2130,58 +2507,3 @@ let minimalStringOfType denv ty = let denvMin = { denv with showImperativeTyparAnnotations=false; showConstraintTyparAnnotations=false } showL (PrintTypes.layoutTypeWithInfoAndPrec denvMin SimplifyTypes.typeSimplificationInfo0 2 ty) - -#if ASSEMBLY_AND_MODULE_SIGNATURE_PRINTING -type DeclSpec = - | DVal of Val - | DTycon of Tycon - | DException of Tycon - | DModul of ModuleOrNamespace - -let rangeOfDeclSpec = function - | DVal v -> v.Range - | DTycon t -> t.Range - | DException t -> t.Range - | DModul m -> m.Range - -/// modul - provides (valspec)* - and also types, exns and submodules. -/// Each defines a decl block on a given range. -/// Can sort on the ranges to recover the original declaration order. -let rec moduleOrNamespaceTypeLP (topLevel: bool) (denv: DisplayEnv) (mtype: ModuleOrNamespaceType) = - // REVIEW: consider a better way to keep decls in order. - let declSpecs: DeclSpec list = - List.concat - [ mtype.AllValsAndMembers |> Seq.toList |> List.filter (fun v -> not v.IsCompilerGenerated && v.MemberInfo.IsNone) |> List.map DVal - mtype.TypeDefinitions |> List.map DTycon - mtype.ExceptionDefinitions |> List.map DException - mtype.ModuleAndNamespaceDefinitions |> List.map DModul - ] - - let declSpecs = List.sortWithOrder (Order.orderOn rangeOfDeclSpec rangeOrder) declSpecs - let declSpecL = - function // only show namespaces / modules at the top level; this is because we've no global namespace - | DVal vspec when not topLevel -> prettyLayoutOfValOrMember denv vspec - | DTycon tycon when not topLevel -> tyconL denv (wordL "type") tycon - | DException tycon when not topLevel -> layoutExnDefn denv tycon - | DModul mspec -> moduleOrNamespaceLP false denv mspec - | _ -> emptyL // this catches non-namespace / modules at the top-level - - aboveListL (List.map declSpecL declSpecs) - -and moduleOrNamespaceLP (topLevel: bool) (denv: DisplayEnv) (mspec: ModuleOrNamespace) = - let istype = mspec.ModuleOrNamespaceType.ModuleOrNamespaceKind - let nm = mspec.DemangledModuleOrNamespaceName - let denv = denv.AddOpenModuleOrNamespace (mkLocalModRef mspec) - let nmL = layoutAccessibility denv mspec.Accessibility (wordL nm) - let denv = denv.AddAccessibility mspec.Accessibility - let path = path.Add nm // tack on the current module to be used in calls to linearise all subterms - let body = moduleOrNamespaceTypeLP topLevel denv path mspec.ModuleOrNamespaceType - if istype = Namespace - then (wordL "namespace" ^^ nmL) @@-- body - else (wordL "module" ^^ nmL ^^ wordL "= begin") @@-- body @@ wordL "end" - -let moduleOrNamespaceTypeL (denv: DisplayEnv) (mtype: ModuleOrNamespaceType) = moduleOrNamespaceTypeLP false denv Path.Empty mtype -let moduleOrNamespaceL denv mspec = moduleOrNamespaceLP false denv Path.Empty mspec -let assemblyL denv (mspec: ModuleOrNamespace) = moduleOrNamespaceTypeLP true denv Path.Empty mspec.ModuleOrNamespaceType // we seem to get the *assembly* name as an outer module, this strips this off -#endif - diff --git a/src/fsharp/NicePrint.fsi b/src/fsharp/NicePrint.fsi new file mode 100644 index 00000000000..5726a7f229b --- /dev/null +++ b/src/fsharp/NicePrint.fsi @@ -0,0 +1,118 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Print Signatures/Types, for signatures, intellisense, quick info, FSI responses +module internal FSharp.Compiler.NicePrint + +open System.Text +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Import +open FSharp.Compiler.Infos +open FSharp.Compiler.InfoReader +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +module PrintUtilities = + val layoutBuiltinAttribute: denv:DisplayEnv -> attrib:BuiltinAttribInfo -> Layout + +val layoutTyparConstraint: denv:DisplayEnv -> Typar * TyparConstraint -> Layout + +val outputType: denv:DisplayEnv -> os:StringBuilder -> x:TType -> unit + +val layoutType: denv:DisplayEnv -> x:TType -> Layout + +val outputTypars: denv:DisplayEnv -> nm:TaggedText -> os:StringBuilder -> x:Typars -> unit + +val outputTyconRef: denv:DisplayEnv -> os:StringBuilder -> x:TyconRef -> unit + +val layoutTyconRef: denv:DisplayEnv -> x:TyconRef -> Layout + +val layoutConst: g:TcGlobals -> ty:TType -> c:Const -> Layout + +val prettyLayoutOfMemberSig: denv:DisplayEnv -> (Typar * TType) list * string * Typars * (TType * ArgReprInfo) list list * TType -> Layout + +val prettyLayoutOfUncurriedSig: denv:DisplayEnv -> argInfos:TyparInst -> tau:UncurriedArgInfos -> (TType -> TyparInst * Layout) + +val prettyLayoutsOfUnresolvedOverloading: denv:DisplayEnv -> argInfos:(TType * ArgReprInfo) list -> retTy:TType -> genericParameters:seq -> Layout * Layout * Layout + +val dataExprL: denv:DisplayEnv -> expr:Expr -> Layout + +val outputValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> os:StringBuilder -> x:ValRef -> unit + +val stringValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> x:ValRef -> string + +val layoutQualifiedValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> typarInst:TyparInst -> v:ValRef -> TyparInst * Layout + +val outputQualifiedValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> os:StringBuilder -> v:ValRef -> unit + +val outputQualifiedValSpec: denv:DisplayEnv -> infoReader:InfoReader -> os:StringBuilder -> v:ValRef -> unit + +val stringOfQualifiedValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> v:ValRef -> string + +val formatMethInfoToBufferFreeStyle: infoReader:InfoReader -> m:range -> denv:DisplayEnv -> buf:StringBuilder -> d:MethInfo -> unit + +val prettyLayoutOfMethInfoFreeStyle: infoReader:InfoReader -> m:range -> denv:DisplayEnv -> typarInst:TyparInst -> minfo:MethInfo -> TyparInst * Layout + +val prettyLayoutOfPropInfoFreeStyle: g:TcGlobals -> amap:ImportMap -> m:range -> denv:DisplayEnv -> d:PropInfo -> Layout + +val stringOfMethInfo: infoReader:InfoReader -> m:range -> denv:DisplayEnv -> minfo:MethInfo -> string + +val multiLineStringOfMethInfos: infoReader:InfoReader -> m:range -> denv:DisplayEnv -> minfos:MethInfo list -> string + +val stringOfParamData: denv:DisplayEnv -> paramData:ParamData -> string + +val layoutOfParamData: denv:DisplayEnv -> paramData:ParamData -> Layout + +val layoutExnDef: denv:DisplayEnv -> infoReader:InfoReader -> x:EntityRef -> Layout + +val stringOfTyparConstraints: denv:DisplayEnv -> x:(Typar * TyparConstraint) list -> string + +val layoutTyconDefn: denv:DisplayEnv -> infoReader:InfoReader -> ad:AccessorDomain -> m:range -> x:Tycon -> Layout + +val layoutEntityDefn: denv:DisplayEnv -> infoReader:InfoReader -> ad:AccessorDomain -> m:range -> x:EntityRef -> Layout + +val layoutUnionCases: denv:DisplayEnv -> infoReader:InfoReader -> enclosingTcref:TyconRef -> x:RecdField list -> Layout + +val isGeneratedUnionCaseField: pos:int -> f:RecdField -> bool + +val isGeneratedExceptionField: pos:'a -> f:RecdField -> bool + +val stringOfTyparConstraint: denv:DisplayEnv -> Typar * TyparConstraint -> string + +val stringOfTy: denv:DisplayEnv -> x:TType -> string + +val prettyLayoutOfType: denv:DisplayEnv -> x:TType -> Layout + +val prettyLayoutOfTypeNoCx: denv:DisplayEnv -> x:TType -> Layout + +val prettyStringOfTy: denv:DisplayEnv -> x:TType -> string + +val prettyStringOfTyNoCx: denv:DisplayEnv -> x:TType -> string + +val stringOfRecdField: denv:DisplayEnv -> infoReader:InfoReader -> enclosingTcref:TyconRef -> x:RecdField -> string + +val stringOfUnionCase: denv:DisplayEnv -> infoReader:InfoReader -> enclosingTcref:TyconRef -> x:UnionCase -> string + +val stringOfExnDef: denv:DisplayEnv -> infoReader:InfoReader -> x:EntityRef -> string + +val stringOfFSAttrib: denv:DisplayEnv -> x:Attrib -> string + +val stringOfILAttrib: denv:DisplayEnv -> ILType * ILAttribElem list -> string + +val layoutInferredSigOfModuleExpr: showHeader:bool -> denv:DisplayEnv -> infoReader:InfoReader -> ad:AccessorDomain -> m:range -> expr:ModuleOrNamespaceExprWithSig -> Layout + +val prettyLayoutOfValOrMember: denv:DisplayEnv -> infoReader:InfoReader -> typarInst:TyparInst -> v:ValRef -> TyparInst * Layout + +val prettyLayoutOfValOrMemberNoInst: denv:DisplayEnv -> infoReader:InfoReader -> v:ValRef -> Layout + +val prettyLayoutOfMemberNoInstShort: denv:DisplayEnv -> v:Val -> Layout + +val prettyLayoutOfInstAndSig: denv:DisplayEnv -> TyparInst * TTypes * TType -> TyparInst * (TTypes * TType) * (Layout list * Layout) * Layout + +val minimalStringsOfTwoTypes: denv:DisplayEnv -> t1:TType -> t2:TType -> string * string * string + +val minimalStringsOfTwoValues: denv:DisplayEnv -> infoReader:InfoReader -> v1:ValRef -> v2:ValRef -> string * string + +val minimalStringOfType: denv:DisplayEnv -> ty:TType -> string diff --git a/src/fsharp/OptimizeInputs.fs b/src/fsharp/OptimizeInputs.fs new file mode 100644 index 00000000000..3cccaeef042 --- /dev/null +++ b/src/fsharp/OptimizeInputs.fs @@ -0,0 +1,206 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// # FSComp.SR.opts + +module internal FSharp.Compiler.OptimizeInputs + +open System.IO +open Internal.Utilities.Library +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.IlxGen +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.IO +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +let mutable showTermFileCount = 0 + +let PrintWholeAssemblyImplementation g (tcConfig:TcConfig) outfile header expr = + if tcConfig.showTerms then + if tcConfig.writeTermsToFiles then + let filename = outfile + ".terms" + use f = FileSystem.OpenFileForWriteShim(filename + "-" + string showTermFileCount + "-" + header, FileMode.Create).GetWriter() + showTermFileCount <- showTermFileCount + 1 + LayoutRender.outL f (Display.squashTo 192 (DebugPrint.implFilesL g expr)) + else + dprintf "\n------------------\nshowTerm: %s:\n" header + LayoutRender.outL stderr (Display.squashTo 192 (DebugPrint.implFilesL g expr)) + dprintf "\n------------------\n" + +let AddExternalCcuToOptimizationEnv tcGlobals optEnv (ccuinfo: ImportedAssembly) = + match ccuinfo.FSharpOptimizationData.Force() with + | None -> optEnv + | Some data -> Optimizer.BindCcu ccuinfo.FSharpViewOfMetadata data optEnv tcGlobals + +let GetInitialOptimizationEnv (tcImports:TcImports, tcGlobals:TcGlobals) = + let ccuinfos = tcImports.GetImportedAssemblies() + let optEnv = Optimizer.IncrementalOptimizationEnv.Empty + let optEnv = List.fold (AddExternalCcuToOptimizationEnv tcGlobals) optEnv ccuinfos + optEnv + +let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importMap, isIncrementalFragment, optEnv, ccu:CcuThunk, implFiles) = + // NOTE: optEnv - threads through + // + // Always optimize once - the results of this step give the x-module optimization + // info. Subsequent optimization steps choose representations etc. which we don't + // want to save in the x-module info (i.e. x-module info is currently "high level"). + PrintWholeAssemblyImplementation tcGlobals tcConfig outfile "pass-start" implFiles +#if DEBUG + if tcConfig.showOptimizationData then + dprintf "Expression prior to optimization:\n%s\n" (LayoutRender.showL (Display.squashTo 192 (DebugPrint.implFilesL tcGlobals implFiles))) + + if tcConfig.showOptimizationData then + dprintf "CCU prior to optimization:\n%s\n" (LayoutRender.showL (Display.squashTo 192 (DebugPrint.entityL tcGlobals ccu.Contents))) +#endif + + let optEnv0 = optEnv + ReportTime tcConfig "Optimizations" + + // Only do abstract_big_targets on the first pass! Only do it when TLR is on! + let optSettings = tcConfig.optSettings + let optSettings = { optSettings with abstractBigTargets = tcConfig.doTLR } + let optSettings = { optSettings with reportingPhase = true } + + let results, (optEnvFirstLoop, _, _, _) = + ((optEnv0, optEnv0, optEnv0, SignatureHidingInfo.Empty), implFiles) + + ||> List.mapFold (fun (optEnvFirstLoop, optEnvExtraLoop, optEnvFinalSimplify, hidden) implFile -> + + //ReportTime tcConfig ("Initial simplify") + let (optEnvFirstLoop, implFile, implFileOptData, hidden), optimizeDuringCodeGen = + Optimizer.OptimizeImplFile + (optSettings, ccu, tcGlobals, tcVal, importMap, + optEnvFirstLoop, isIncrementalFragment, + tcConfig.emitTailcalls, hidden, implFile) + + let implFile = AutoBox.TransformImplFile tcGlobals importMap implFile + + // Only do this on the first pass! + let optSettings = { optSettings with abstractBigTargets = false; reportingPhase = false } +#if DEBUG + if tcConfig.showOptimizationData then + dprintf "Optimization implFileOptData:\n%s\n" (LayoutRender.showL (Display.squashTo 192 (Optimizer.moduleInfoL tcGlobals implFileOptData))) +#endif + + let implFile, optEnvExtraLoop = + if tcConfig.extraOptimizationIterations > 0 then + + //ReportTime tcConfig ("Extra simplification loop") + let (optEnvExtraLoop, implFile, _, _), _ = + Optimizer.OptimizeImplFile + (optSettings, ccu, tcGlobals, tcVal, importMap, + optEnvExtraLoop, isIncrementalFragment, + tcConfig.emitTailcalls, hidden, implFile) + + //PrintWholeAssemblyImplementation tcConfig outfile (sprintf "extra-loop-%d" n) implFile + implFile, optEnvExtraLoop + else + implFile, optEnvExtraLoop + + let implFile = + if tcConfig.doDetuple then + //ReportTime tcConfig ("Detupled optimization") + let implFile = implFile |> Detuple.DetupleImplFile ccu tcGlobals + //PrintWholeAssemblyImplementation tcConfig outfile "post-detuple" implFile + implFile + else implFile + + let implFile = + if tcConfig.doTLR then + implFile |> InnerLambdasToTopLevelFuncs.MakeTopLevelRepresentationDecisions ccu tcGlobals + else implFile + + let implFile = + LowerCallsAndSeqs.LowerImplFile tcGlobals implFile + + let implFile, optEnvFinalSimplify = + if tcConfig.doFinalSimplify then + + //ReportTime tcConfig ("Final simplify pass") + let (optEnvFinalSimplify, implFile, _, _), _ = + Optimizer.OptimizeImplFile + (optSettings, ccu, tcGlobals, tcVal, importMap, optEnvFinalSimplify, + isIncrementalFragment, tcConfig.emitTailcalls, hidden, implFile) + + //PrintWholeAssemblyImplementation tcConfig outfile "post-rec-opt" implFile + implFile, optEnvFinalSimplify + else + implFile, optEnvFinalSimplify + + let implFile = + { ImplFile = implFile + OptimizeDuringCodeGen = optimizeDuringCodeGen } + + (implFile, implFileOptData), (optEnvFirstLoop, optEnvExtraLoop, optEnvFinalSimplify, hidden)) + + let implFiles, implFileOptDatas = List.unzip results + let assemblyOptData = Optimizer.UnionOptimizationInfos implFileOptDatas + let tassembly = TypedAssemblyAfterOptimization implFiles + PrintWholeAssemblyImplementation tcGlobals tcConfig outfile "pass-end" (implFiles |> List.map (fun implFile -> implFile.ImplFile)) + ReportTime tcConfig "Ending Optimizations" + tassembly, assemblyOptData, optEnvFirstLoop + +//---------------------------------------------------------------------------- +// ILX generation +//---------------------------------------------------------------------------- + +let CreateIlxAssemblyGenerator (_tcConfig:TcConfig, tcImports:TcImports, tcGlobals, tcVal, generatedCcu) = + let ilxGenerator = IlxAssemblyGenerator(tcImports.GetImportMap(), tcGlobals, tcVal, generatedCcu) + let ccus = tcImports.GetCcusInDeclOrder() + ilxGenerator.AddExternalCcus ccus + ilxGenerator + +let GenerateIlxCode + (ilxBackend, isInteractiveItExpr, isInteractiveOnMono, + tcConfig:TcConfig, topAttrs: TopAttribs, optimizedImpls, + fragName, ilxGenerator: IlxAssemblyGenerator) = + + let mainMethodInfo = + if (tcConfig.target = CompilerTarget.Dll) || (tcConfig.target = CompilerTarget.Module) then + None + else Some topAttrs.mainMethodAttrs + + let ilxGenOpts: IlxGenOptions = + { generateFilterBlocks = tcConfig.generateFilterBlocks + emitConstantArraysUsingStaticDataBlobs = not isInteractiveOnMono + workAroundReflectionEmitBugs=tcConfig.isInteractive // REVIEW: is this still required? + generateDebugSymbols= tcConfig.debuginfo + fragName = fragName + localOptimizationsEnabled= tcConfig.optSettings.LocalOptimizationsEnabled + testFlagEmitFeeFeeAs100001 = tcConfig.testFlagEmitFeeFeeAs100001 + mainMethodInfo= mainMethodInfo + ilxBackend = ilxBackend + isInteractive = tcConfig.isInteractive + isInteractiveItExpr = isInteractiveItExpr + alwaysCallVirt = tcConfig.alwaysCallVirt } + + ilxGenerator.GenerateCode (ilxGenOpts, optimizedImpls, topAttrs.assemblyAttrs, topAttrs.netModuleAttrs) + +//---------------------------------------------------------------------------- +// Assembly ref normalization: make sure all assemblies are referred to +// by the same references. Only used for static linking. +//---------------------------------------------------------------------------- + +let NormalizeAssemblyRefs (ctok, ilGlobals: ILGlobals, tcImports:TcImports) scoref = + let normalizeAssemblyRefByName nm = + match tcImports.TryFindDllInfo (ctok, Range.rangeStartup, nm, lookupOnly=false) with + | Some dllInfo -> dllInfo.ILScopeRef + | None -> scoref + + match scoref with + | ILScopeRef.Local + | ILScopeRef.Module _ -> scoref + | ILScopeRef.PrimaryAssembly -> normalizeAssemblyRefByName ilGlobals.primaryAssemblyName + | ILScopeRef.Assembly aref -> normalizeAssemblyRefByName aref.Name + +let GetGeneratedILModuleName (t:CompilerTarget) (s:string) = + // return the name of the file as a module name + let ext = match t with CompilerTarget.Dll -> "dll" | CompilerTarget.Module -> "netmodule" | _ -> "exe" + s + "." + ext diff --git a/src/fsharp/OptimizeInputs.fsi b/src/fsharp/OptimizeInputs.fsi new file mode 100644 index 00000000000..2c64a648ffd --- /dev/null +++ b/src/fsharp/OptimizeInputs.fsi @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.OptimizeInputs + +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.IlxGen +open FSharp.Compiler.Import +open FSharp.Compiler.Optimizer +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree + +val GetGeneratedILModuleName : CompilerTarget -> string -> string + +val GetInitialOptimizationEnv : TcImports * TcGlobals -> IncrementalOptimizationEnv + +val AddExternalCcuToOptimizationEnv : TcGlobals -> IncrementalOptimizationEnv -> ImportedAssembly -> IncrementalOptimizationEnv + +val ApplyAllOptimizations : TcConfig * TcGlobals * ConstraintSolver.TcValF * string * ImportMap * bool * IncrementalOptimizationEnv * CcuThunk * TypedImplFile list -> TypedAssemblyAfterOptimization * LazyModuleInfo * IncrementalOptimizationEnv + +val CreateIlxAssemblyGenerator : TcConfig * TcImports * TcGlobals * ConstraintSolver.TcValF * CcuThunk -> IlxAssemblyGenerator + +val GenerateIlxCode : IlxGenBackend * isInteractiveItExpr:bool * isInteractiveOnMono:bool * TcConfig * TopAttribs * TypedAssemblyAfterOptimization * fragName:string * IlxAssemblyGenerator -> IlxGenResults + +// Used during static linking +val NormalizeAssemblyRefs : CompilationThreadToken * ILGlobals * TcImports -> (ILScopeRef -> ILScopeRef) + +val GetGeneratedILModuleName : CompilerTarget -> string -> string diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 37d121cad43..c051e137939 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1,37 +1,38 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//------------------------------------------------------------------------- -// The F# expression simplifier. The main aim is to inline simple, known functions -// and constant values, and to eliminate non-side-affecting bindings that -// are never used. -//------------------------------------------------------------------------- - - +/// The F# expression simplifier. The main aim is to inline simple, known functions +/// and constant values, and to eliminate non-side-affecting bindings that +/// are never used. module internal FSharp.Compiler.Optimizer -open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library - -open FSharp.Compiler -open FSharp.Compiler.Lib -open FSharp.Compiler.Range -open FSharp.Compiler.Ast open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Infos -open FSharp.Compiler.Tast -open FSharp.Compiler.TastPickle -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Text.TaggedText +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint +open FSharp.Compiler.TypedTreePickle open FSharp.Compiler.TypeRelations open System.Collections.Generic +open System.Collections.ObjectModel #if DEBUG let verboseOptimizationInfo = @@ -51,8 +52,8 @@ let [] callSize = 1 /// size of a for/while loop let [] forAndWhileLoopSize = 5 -/// size of a try/catch -let [] tryCatchSize = 5 +/// size of a try/with +let [] tryWithSize = 5 /// size of a try/finally let [] tryFinallySize = 5 @@ -76,7 +77,7 @@ type ExprValueInfo = /// SizeValue(size, value) /// /// Records size info (maxDepth) for an ExprValueInfo - | SizeValue of int * ExprValueInfo + | SizeValue of size: int * ExprValueInfo /// ValValue(vref, value) /// @@ -101,10 +102,10 @@ type ExprValueInfo = /// the number of args in each bunch. NOTE: This include type arguments. /// expr: The value, a lambda term. /// ty: The type of lambda term - | CurriedLambdaValue of Unique * int * int * Expr * TType + | CurriedLambdaValue of id: Unique * arity: int * size: int * lambdaExpr: Expr * lambdaExprTy: TType /// ConstExprValue(size, value) - | ConstExprValue of int * Expr + | ConstExprValue of size: int * value: Expr type ValInfo = { ValMakesNoCriticalTailcalls: bool @@ -132,20 +133,37 @@ type ValInfos(entries) = let valInfoTable = lazy (let t = ValHash.Create () - for (vref: ValRef, x) in entries do + for vref: ValRef, x in entries do t.Add (vref.Deref, (vref, x)) t) - // The compiler ValRef's into fslib stored in env.fs break certain invariants that hold elsewhere, + // The compiler's ValRef's in TcGlobals.fs that refer to things in FSharp.Core break certain invariants that hold elsewhere, // because they dereference to point to Val's from signatures rather than Val's from implementations. - // Thus a backup alternative resolution technique is needed for these. + // Thus a backup alternative resolution technique is needed for these when processing the FSharp.Core implementation files + // holding these items. This resolution must be able to distinguish between overloaded methods, so we use + // XmlDocSigOfVal as a cheap hack to get a unique item of data for a value. let valInfosForFslib = - lazy ( - let dict = Dictionary<_, _>() - for (vref, _x) as p in entries do - let vkey = vref.Deref.GetLinkagePartialKey() - dict.Add(vkey, p) |> ignore - dict) + LazyWithContext<_, TcGlobals>.Create ((fun g -> + let dict = + Dictionary + (HashIdentity.FromFunctions + (fun (_: ValRef, k: ValLinkageFullKey) -> hash k.PartialKey) + (fun (v1, k1) (v2, k2) -> + k1.PartialKey = k2.PartialKey && + // dismbiguate overloads, somewhat low-perf but only use for a handful of overloads in FSharp.Core + match k1.TypeForLinkage, k2.TypeForLinkage with + | Some _, Some _ -> + let sig1 = XmlDocSigOfVal g true "" v1.Deref + let sig2 = XmlDocSigOfVal g true "" v2.Deref + (sig1 = sig2) + | None, None -> true + | _ -> false)) + for vref, _x as p in entries do + let vkey = (vref, vref.Deref.GetLinkageFullKey()) + if dict.ContainsKey vkey then + failwithf "dictionary already contains key %A" vkey + dict.Add(vkey, p) + ReadOnlyDictionary dict), id) member x.Entries = valInfoTable.Force().Values @@ -155,7 +173,8 @@ type ValInfos(entries) = member x.TryFind (v: ValRef) = valInfoTable.Force().TryFind v.Deref - member x.TryFindForFslib (v: ValRef) = valInfosForFslib.Force().TryGetValue(v.Deref.GetLinkagePartialKey()) + member x.TryFindForFslib (g, vref: ValRef) = + valInfosForFslib.Force(g).TryGetValue((vref, vref.Deref.GetLinkageFullKey())) type ModuleInfo = { ValInfos: ValInfos @@ -208,7 +227,7 @@ type Summary<'Info> = /// Meaning: could mutate, could non-terminate, could raise exception /// One use: an effect expr can not be eliminated as dead code (e.g. sequencing) - /// One use: an effect=false expr can not throw an exception? so try-catch is removed. + /// One use: an effect=false expr can not throw an exception? so try-with is removed. HasEffect: bool /// Indicates that a function may make a useful tailcall, hence when called should itself be tailcalled @@ -232,7 +251,7 @@ and SizeOfValueInfo x = | TupleValue vinfos | RecdValue (_, vinfos) | UnionCaseValue (_, vinfos) -> 1 + SizeOfValueInfos vinfos - | CurriedLambdaValue(_lambdaId, _arities, _bsize, _expr, _ety) -> 1 + | CurriedLambdaValue _ -> 1 | ConstExprValue (_size, _) -> 1 let [] minDepthForASizeNode = 5 // for small vinfos do not record size info, save space @@ -259,7 +278,7 @@ let BoundValueInfoBySize vinfo = | UnionCaseValue (ucr, vinfos) -> UnionCaseValue (ucr, Array.map (bound (depth-1)) vinfos) | ConstValue _ -> x | UnknownValue -> x - | CurriedLambdaValue(_lambdaId, _arities, _bsize, _expr, _ety) -> x + | CurriedLambdaValue _ -> x | ConstExprValue (_size, _) -> x let maxDepth = 6 (* beware huge constants! *) let trimDepth = 3 @@ -276,16 +295,21 @@ let [] jitOptDefault = true let [] localOptDefault = true -let [] crossModuleOptDefault = true +let [] crossAssemblyOptimizationDefault = true + +let [] debugPointsForPipeRightDefault = true type OptimizationSettings = - { abstractBigTargets : bool + { + abstractBigTargets : bool jitOptUser : bool option localOptUser : bool option - crossModuleOptUser : bool option + debugPointsForPipeRight: bool option + + crossAssemblyOptimizationUser : bool option /// size after which we start chopping methods in two, though only at match targets bigTargetSize : int @@ -312,9 +336,10 @@ type OptimizationSettings = { abstractBigTargets = false jitOptUser = None localOptUser = None + debugPointsForPipeRight = None bigTargetSize = 100 veryBigExprSize = 3000 - crossModuleOptUser = None + crossAssemblyOptimizationUser = None lambdaInlineThreshold = 6 reportingPhase = false reportNoNeedToTailcall = false @@ -323,41 +348,65 @@ type OptimizationSettings = reportTotalSizes = false } - member x.jitOpt() = match x.jitOptUser with Some f -> f | None -> jitOptDefault + /// Determines if JIT optimizations are enabled + member x.JitOptimizationsEnabled = match x.jitOptUser with Some f -> f | None -> jitOptDefault - member x.localOpt () = match x.localOptUser with Some f -> f | None -> localOptDefault + /// Determines if intra-assembly optimization is enabled + member x.LocalOptimizationsEnabled = match x.localOptUser with Some f -> f | None -> localOptDefault - member x.crossModuleOpt () = x.localOpt () && (match x.crossModuleOptUser with Some f -> f | None -> crossModuleOptDefault) + /// Determines if cross-assembly optimization is enabled + member x.crossAssemblyOpt () = + x.LocalOptimizationsEnabled && + x.crossAssemblyOptimizationUser |> Option.defaultValue crossAssemblyOptimizationDefault - member x.KeepOptimizationValues() = x.crossModuleOpt () + /// Determines if we should keep optimization values + member x.KeepOptimizationValues = x.crossAssemblyOpt () - /// inline calls? - member x.InlineLambdas () = x.localOpt () + /// Determines if we should inline calls + member x.InlineLambdas = x.LocalOptimizationsEnabled - /// eliminate unused bindings with no effect - member x.EliminateUnusedBindings () = x.localOpt () + /// Determines if we should eliminate unused bindings with no effect + member x.EliminateUnusedBindings = x.LocalOptimizationsEnabled - /// eliminate try around expr with no effect - member x.EliminateTryCatchAndTryFinally () = false // deemed too risky, given tiny overhead of including try/catch. See https://github.com/Microsoft/visualfsharp/pull/376 + /// Determines if we should arrange things so we debug points for pipelines x |> f1 |> f2 + /// including locals "", "" and so on. + /// On by default for debug code. + member x.DebugPointsForPipeRight = + not x.LocalOptimizationsEnabled && + x.debugPointsForPipeRight |> Option.defaultValue debugPointsForPipeRightDefault - /// eliminate first part of seq if no effect - member x.EliminateSequential () = x.localOpt () + /// Determines if we should eliminate for-loops around an expr if it has no effect + /// + /// This optimization is off by default, given tiny overhead of including try/with. See https://github.com/Microsoft/visualfsharp/pull/376 + member x.EliminateForLoop = x.LocalOptimizationsEnabled - /// determine branches in pattern matching - member x.EliminateSwitch () = x.localOpt () + /// Determines if we should eliminate try/with or try/finally around an expr if it has no effect + /// + /// This optimization is off by default, given tiny overhead of including try/with. See https://github.com/Microsoft/visualfsharp/pull/376 + member _.EliminateTryWithAndTryFinally = false - member x.EliminateRecdFieldGet () = x.localOpt () + /// Determines if we should eliminate first part of sequential expression if it has no effect + member x.EliminateSequential = x.LocalOptimizationsEnabled - member x.EliminateTupleFieldGet () = x.localOpt () + /// Determines if we should determine branches in pattern matching based on known information, e.g. + /// eliminate a "if true then .. else ... " + member x.EliminateSwitch = x.LocalOptimizationsEnabled - member x.EliminateUnionCaseFieldGet () = x.localOpt () + /// Determines if we should eliminate gets on a record if the value is known to be a record with known info and the field is not mutable + member x.EliminateRecdFieldGet = x.LocalOptimizationsEnabled - /// eliminate non-compiler generated immediate bindings - member x.EliminateImmediatelyConsumedLocals() = x.localOpt () + /// Determines if we should eliminate gets on a tuple if the value is known to be a tuple with known info + member x.EliminateTupleFieldGet = x.LocalOptimizationsEnabled - /// expand "let x = (exp1, exp2, ...)" bindings as prior tmps - /// expand "let x = Some exp1" bindings as prior tmps - member x.ExpandStructuralValues() = x.localOpt () + /// Determines if we should eliminate gets on a union if the value is known to be that union case and the particular field has known info + member x.EliminateUnionCaseFieldGet () = x.LocalOptimizationsEnabled + + /// Determines if we should eliminate non-compiler generated immediate bindings + member x.EliminateImmediatelyConsumedLocals() = x.LocalOptimizationsEnabled + + /// Determines if we should expand "let x = (exp1, exp2, ...)" bindings as prior tmps + /// Also if we should expand "let x = Some exp1" bindings as prior tmps + member x.ExpandStructuralValues() = x.LocalOptimizationsEnabled type cenv = { g: TcGlobals @@ -370,18 +419,25 @@ type cenv = scope: CcuThunk - localInternalVals: System.Collections.Generic.Dictionary + localInternalVals: Dictionary settings: OptimizationSettings emitTailcalls: bool /// cache methods with SecurityAttribute applied to them, to prevent unnecessary calls to ExistsInEntireHierarchyOfType - casApplied : Dictionary + casApplied: Dictionary + } override x.ToString() = "" +// environment for a method +type MethodEnv = + { mutable pipelineCount: int } + + override x.ToString() = "" + type IncrementalOptimizationEnv = { /// An identifier to help with name generation latestBoundId: Ident option @@ -395,15 +451,17 @@ type IncrementalOptimizationEnv = dontSplitVars: ValMap /// Disable method splitting in loops - inLoop: bool + disableMethodSplitting: bool /// The Val for the function binding being generated, if any. - functionVal: (Val * Tast.ValReprInfo) option + functionVal: (Val * ValReprInfo) option typarInfos: (Typar * TypeValueInfo) list localExternalVals: LayeredMap + methEnv: MethodEnv + globalModuleInfos: LayeredMap } @@ -413,9 +471,10 @@ type IncrementalOptimizationEnv = typarInfos = [] functionVal = None dontSplitVars = ValMap.Empty - inLoop = false + disableMethodSplitting = false localExternalVals = LayeredMap.Empty - globalModuleInfos = LayeredMap.Empty } + globalModuleInfos = LayeredMap.Empty + methEnv = { pipelineCount = 0 } } override x.ToString() = "" @@ -493,28 +552,19 @@ let mkValInfo info (v: Val) = { ValExprInfo=info.Info; ValMakesNoCriticalTailcal (* Bind a value *) let BindInternalLocalVal cenv (v: Val) vval env = let vval = if v.IsMutable then UnknownValInfo else vval -#if CHECKED -#else + match vval.ValExprInfo with | UnknownValue -> env - | _ -> -#endif + | _ -> cenv.localInternalVals.[v.Stamp] <- vval env let BindExternalLocalVal cenv (v: Val) vval env = -#if CHECKED - CheckInlineValueIsComplete v vval -#endif - let vval = if v.IsMutable then {vval with ValExprInfo=UnknownValue } else vval - let env = -#if CHECKED -#else + let env = match vval.ValExprInfo with | UnknownValue -> env - | _ -> -#endif + | _ -> { env with localExternalVals=env.localExternalVals.Add (v.Stamp, vval) } // If we're compiling fslib then also bind the value as a non-local path to // allow us to resolve the compiler-non-local-references that arise from env.fs @@ -541,21 +591,14 @@ let rec BindValsInModuleOrNamespace cenv (mval: LazyModuleInfo) env = env let inline BindInternalValToUnknown cenv v env = -#if CHECKED - BindInternalLocalVal cenv v UnknownValue env -#else ignore cenv ignore v env -#endif + let inline BindInternalValsToUnknown cenv vs env = -#if CHECKED - List.foldBack (BindInternalValToUnknown cenv) vs env -#else ignore cenv ignore vs env -#endif let BindTypeVar tyv typeinfo env = { env with typarInfos= (tyv, typeinfo) :: env.typarInfos } @@ -570,7 +613,7 @@ let BindTypeVarsToUnknown (tps: Typar list) env = tp.typar_id <- ident (nm, tp.Range)) List.fold (fun sofar arg -> BindTypeVar arg UnknownTypeValue sofar) env tps -let BindCcu (ccu: Tast.CcuThunk) mval env (_g: TcGlobals) = +let BindCcu (ccu: CcuThunk) mval env (_g: TcGlobals) = { env with globalModuleInfos=env.globalModuleInfos.Add(ccu.AssemblyName, mval) } /// Lookup information about values @@ -586,9 +629,6 @@ let GetInfoForLocalValue cenv env (v: Val) m = | None -> if v.MustInline then errorR(Error(FSComp.SR.optValueMarkedInlineButWasNotBoundInTheOptEnv(fullDisplayTextOfValRef (mkLocalValRef v)), m)) -#if CHECKED - warning(Error(FSComp.SR.optLocalValueNotFoundDuringOptimization(v.DisplayName), m)) -#endif UnknownValInfo let TryGetInfoForCcu env (ccu: CcuThunk) = env.globalModuleInfos.TryFind(ccu.AssemblyName) @@ -613,7 +653,7 @@ let GetInfoForNonLocalVal cenv env (vref: ValRef) = if vref.IsDispatchSlot then UnknownValInfo // REVIEW: optionally turn x-module on/off on per-module basis or - elif cenv.settings.crossModuleOpt () || vref.MustInline then + elif cenv.settings.crossAssemblyOpt () || vref.MustInline then match TryGetInfoForNonLocalEntityRef env vref.nlr.EnclosingEntity.nlr with | Some structInfo -> match structInfo.ValInfos.TryFind vref with @@ -622,7 +662,7 @@ let GetInfoForNonLocalVal cenv env (vref: ValRef) = //dprintn ("\n\n*** Optimization info for value "+n+" from module "+(full_name_of_nlpath smv)+" not found, module contains values: "+String.concat ", " (NameMap.domainL structInfo.ValInfos)) //System.Diagnostics.Debug.Assert(false, sprintf "Break for module %s, value %s" (full_name_of_nlpath smv) n) if cenv.g.compilingFslib then - match structInfo.ValInfos.TryFindForFslib vref with + match structInfo.ValInfos.TryFindForFslib (cenv.g, vref) with | true, ninfo -> snd ninfo | _ -> UnknownValInfo else @@ -756,15 +796,15 @@ let inline IntegerBinaryOp g f8 f16 f32 f64 fu8 fu16 fu32 fu64 a b = match a, b with | StripConstValue c1, StripConstValue c2 -> match c1, c2 with - | (Const.Bool a), (Const.Bool b) -> Some(mkBoolVal g (f32 (if a then 1 else 0) (if b then 1 else 0) <> 0)) - | (Const.Int32 a), (Const.Int32 b) -> Some(mkInt32Val g (f32 a b)) - | (Const.Int64 a), (Const.Int64 b) -> Some(mkInt64Val g (f64 a b)) - | (Const.Int16 a), (Const.Int16 b) -> Some(mkInt16Val g (f16 a b)) - | (Const.SByte a), (Const.SByte b) -> Some(mkInt8Val g (f8 a b)) - | (Const.Byte a), (Const.Byte b) -> Some(mkUInt8Val g (fu8 a b)) - | (Const.UInt16 a), (Const.UInt16 b) -> Some(mkUInt16Val g (fu16 a b)) - | (Const.UInt32 a), (Const.UInt32 b) -> Some(mkUInt32Val g (fu32 a b)) - | (Const.UInt64 a), (Const.UInt64 b) -> Some(mkUInt64Val g (fu64 a b)) + | Const.Bool a, Const.Bool b -> Some(mkBoolVal g (f32 (if a then 1 else 0) (if b then 1 else 0) <> 0)) + | Const.Int32 a, Const.Int32 b -> Some(mkInt32Val g (f32 a b)) + | Const.Int64 a, Const.Int64 b -> Some(mkInt64Val g (f64 a b)) + | Const.Int16 a, Const.Int16 b -> Some(mkInt16Val g (f16 a b)) + | Const.SByte a, Const.SByte b -> Some(mkInt8Val g (f8 a b)) + | Const.Byte a, Const.Byte b -> Some(mkUInt8Val g (fu8 a b)) + | Const.UInt16 a, Const.UInt16 b -> Some(mkUInt16Val g (fu16 a b)) + | Const.UInt32 a, Const.UInt32 b -> Some(mkUInt32Val g (fu32 a b)) + | Const.UInt64 a, Const.UInt64 b -> Some(mkUInt64Val g (fu64 a b)) | _ -> None | _ -> None @@ -1023,7 +1063,7 @@ let OrTailcalls l = List.exists (fun x -> x.MightMakeCriticalTailcall) l let OptimizeList f l = l |> List.map f |> List.unzip -let NoExprs : (Expr list * list>) = [], [] +let NoExprs : Expr list * list> = [], [] /// Common ways of building new value infos let CombineValueInfos einfos res = @@ -1161,7 +1201,7 @@ let AbstractExprInfoByVars (boundVars: Val list, boundTyVars) ivalue = (let fvs = freeInExpr (if isNil boundTyVars then CollectLocals else CollectTyparsAndLocals) expr (not (isNil boundVars) && List.exists (Zset.memberOf fvs.FreeLocals) boundVars) || (not (isNil boundTyVars) && List.exists (Zset.memberOf fvs.FreeTyvars.FreeTypars) boundTyVars) || - (fvs.UsesMethodLocalConstructs )) -> + fvs.UsesMethodLocalConstructs) -> // Trimming lambda UnknownValue @@ -1233,17 +1273,17 @@ let RemapOptimizationInfo g tmenv = let AbstractAndRemapModulInfo msg g m (repackage, hidden) info = let mrpi = mkRepackageRemapping repackage #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data prior to trim: \n%s\n" msg outputRange m (showL (Display.squashTo 192 (moduleInfoL g info))) #else ignore (msg, m) #endif let info = info |> AbstractLazyModulInfoByHiding false hidden #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after trim:\n%s\n" msg outputRange m (showL (Display.squashTo 192 (moduleInfoL g info))) #endif let info = info |> RemapOptimizationInfo g mrpi #if DEBUG - if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (Layout.showL (Layout.squashTo 192 (moduleInfoL g info))) + if verboseOptimizationInfo then dprintf "%s - %a - Optimization data after remap:\n%s\n" msg outputRange m (showL (Display.squashTo 192 (moduleInfoL g info))) #endif info @@ -1251,9 +1291,6 @@ let AbstractAndRemapModulInfo msg g m (repackage, hidden) info = // Misc helpers //------------------------------------------------------------------------- -// Mark some variables (the ones we introduce via abstractBigTargets) as don't-eliminate -let [] suffixForVariablesThatMayNotBeEliminated = "$cont" - /// Type applications of F# "type functions" may cause side effects, e.g. /// let x<'a> = printfn "hello"; typeof<'a> /// In this case do not treat them as constants. @@ -1274,6 +1311,18 @@ let ValueOfExpr expr = ConstExprValue(0, expr) else UnknownValue +let IsMutableStructuralBindingForTupleElement (vref: ValRef) = + vref.IsCompilerGenerated && + vref.LogicalName.EndsWith suffixForTupleElementAssignmentTarget + +let IsMutableForOutArg (vref: ValRef) = + vref.IsCompilerGenerated && + vref.LogicalName.StartsWith(outArgCompilerGeneratedName) + +let IsKnownOnlyMutableBeforeUse (vref: ValRef) = + IsMutableStructuralBindingForTupleElement vref || + IsMutableForOutArg vref + //------------------------------------------------------------------------- // Dead binding elimination //------------------------------------------------------------------------- @@ -1308,10 +1357,15 @@ let IsDiscardableEffectExpr expr = /// Checks is a value binding is non-discardable let ValueIsUsedOrHasEffect cenv fvs (b: Binding, binfo) = let v = b.Var - not (cenv.settings.EliminateUnusedBindings()) || + // No discarding for debug code, except InlineIfLambda + (not cenv.settings.EliminateUnusedBindings && not v.InlineIfLambda) || + // No discarding for members Option.isSome v.MemberInfo || + // No discarding for bindings that have an effect (binfo.HasEffect && not (IsDiscardableEffectExpr b.Expr)) || + // No discarding for 'fixed' v.IsFixed || + // No discarding for things that are used Zset.contains v (fvs()) let rec SplitValuesByIsUsedOrHasEffect cenv fvs x = @@ -1329,7 +1383,7 @@ let IlAssemblyCodeHasEffect instrs = List.exists IlAssemblyCodeInstrHasEffect in let rec ExprHasEffect g expr = match expr with - | Expr.Val (vref, _, _) -> vref.IsTypeFunction || (vref.IsMutable) + | Expr.Val (vref, _, _) -> vref.IsTypeFunction || vref.IsMutable | Expr.Quote _ | Expr.Lambda _ | Expr.TyLambda _ @@ -1363,11 +1417,11 @@ and OpHasEffect g m op = | TOp.UnionCaseProof _ -> false | TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n | TOp.ILAsm (instrs, _) -> IlAssemblyCodeHasEffect instrs - | TOp.TupleFieldGet (_) -> false + | TOp.TupleFieldGet _ -> false | TOp.ExnFieldGet (ecref, n) -> isExnFieldMutable ecref n | TOp.RefAddrGet _ -> false | TOp.AnonRecdGet _ -> true // conservative - | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true) + | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true) | TOp.ValFieldGetAddr (rfref, _readonly) -> rfref.RecdField.IsMutable | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable | TOp.LValueOp (LAddrOf _, _) -> false // addresses of values are always constants @@ -1377,7 +1431,7 @@ and OpHasEffect g m op = | TOp.Reraise | TOp.For _ | TOp.While _ - | TOp.TryCatch _ (* conservative *) + | TOp.TryWith _ (* conservative *) | TOp.TryFinally _ (* conservative *) | TOp.TraitCall _ | TOp.Goto _ @@ -1394,14 +1448,16 @@ let TryEliminateBinding cenv _env (TBind(vspec1, e1, spBind)) e2 _m = not vspec1.IsCompilerGenerated then None elif vspec1.IsFixed then None + elif vspec1.LogicalName.StartsWith stackVarPrefix || + vspec1.LogicalName.Contains suffixForVariablesThatMayNotBeEliminated then None else + // Peephole on immediate consumption of single bindings, e.g. "let x = e in x" --> "e" // REVIEW: enhance this by general elimination of bindings to // non-side-effecting expressions that are used only once. // But note the cases below cover some instances of side-effecting expressions as well.... let IsUniqueUse vspec2 args = valEq vspec1 vspec2 - && (not (vspec2.LogicalName.Contains suffixForVariablesThatMayNotBeEliminated)) // REVIEW: this looks slow. Look only for one variable instead && (let fvs = accFreeInExprs CollectLocals args emptyFreeVars not (Zset.contains vspec1 fvs.FreeLocals)) @@ -1409,7 +1465,7 @@ let TryEliminateBinding cenv _env (TBind(vspec1, e1, spBind)) e2 _m = // Immediate consumption of value as 2nd or subsequent argument to a construction or projection operation let rec GetImmediateUseContext rargsl argsr = match argsr with - | (Expr.Val (VRefLocal vspec2, _, _)) :: argsr2 + | Expr.Val (VRefLocal vspec2, _, _) :: argsr2 when valEq vspec1 vspec2 && IsUniqueUse vspec2 (List.rev rargsl@argsr2) -> Some(List.rev rargsl, argsr2) | argsrh :: argsrt when not (ExprHasEffect cenv.g argsrh) -> GetImmediateUseContext (argsrh :: rargsl) argsrt | _ -> None @@ -1421,20 +1477,32 @@ let TryEliminateBinding cenv _env (TBind(vspec1, e1, spBind)) e2 _m = when IsUniqueUse vspec2 [] -> Some e1 + // Immediate consumption of function in an application in a sequential, e.g. 'let part1 = e in part1 arg; rest' + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + | Expr.Sequential(Expr.App(Expr.Val (VRefLocal vspec2, _, _), f0ty, c, args, d), rest, NormalSeq, sp, m) + when IsUniqueUse vspec2 (rest :: args) -> + Some (Expr.Sequential(Expr.App(e1, f0ty, c, args, d), rest, NormalSeq, sp, m)) + + // Immediate consumption of delegate via an application in a sequential, e.g. 'let part1 = e in part1.Invoke(args); rest' + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + | Expr.Sequential(DelegateInvokeExpr cenv.g (invokeRef, f0ty, tyargs, Expr.Val (VRefLocal vspec2, _, _), args, _), rest, NormalSeq, sp, m) + when IsUniqueUse vspec2 (rest :: args) -> + let invoke = MakeFSharpDelegateInvokeAndTryBetaReduce cenv.g (invokeRef, e1, f0ty, tyargs, args, m) + Some (Expr.Sequential(invoke, rest, NormalSeq, sp, m)) + // Immediate consumption of value by a pattern match 'let x = e in match x with ...' - | Expr.Match (spMatch, _exprm, TDSwitch(Expr.Val (VRefLocal vspec2, _, _), cases, dflt, _), targets, m, ty2) - when (valEq vspec1 vspec2 && + | Expr.Match (spMatch, _exprm, TDSwitch(sp, Expr.Val (VRefLocal vspec2, _, _), cases, dflt, _), targets, m, ty2) + when (valEq vspec1 vspec2 && let fvs = accFreeInTargets CollectLocals targets (accFreeInSwitchCases CollectLocals cases dflt emptyFreeVars) not (Zset.contains vspec1 fvs.FreeLocals)) -> let spMatch = spBind.Combine spMatch - Some (Expr.Match (spMatch, e1.Range, TDSwitch(e1, cases, dflt, m), targets, m, ty2)) + Some (Expr.Match (spMatch, e1.Range, TDSwitch(sp, e1, cases, dflt, m), targets, m, ty2)) - // Immediate consumption of value as a function 'let f = e in f ...' and 'let x = e in f ... x ...' + // Immediate use of value as part of an application. 'let f = e in f ...' and 'let x = e in f ... x ...' // Note functions are evaluated before args // Note: do not include functions with a single arg of unit type, introduced by abstractBigTargets - | Expr.App (f, f0ty, tyargs, args, m) - when not (vspec1.LogicalName.Contains suffixForVariablesThatMayNotBeEliminated) -> + | Expr.App (f, f0ty, tyargs, args, m) -> match GetImmediateUseContext [] (f :: args) with | Some([], rargs) -> Some (MakeApplicationAndBetaReduce cenv.g (e1, f0ty, [tyargs], rargs, m)) | Some(f :: largs, rargs) -> Some (MakeApplicationAndBetaReduce cenv.g (f, f0ty, [tyargs], largs @ (e1 :: rargs), m)) @@ -1478,45 +1546,45 @@ let rec (|KnownValApp|_|) expr = /// check single case with bool const. let (|TDBoolSwitch|_|) dtree = match dtree with - | TDSwitch( expr, [TCase (DecisionTreeTest.Const(Const.Bool testBool), caseTree )], Some defaultTree, range) -> - Some (expr, testBool, caseTree, defaultTree, range) + | TDSwitch(sp, expr, [TCase (DecisionTreeTest.Const(Const.Bool testBool), caseTree )], Some defaultTree, range) -> + Some (sp, expr, testBool, caseTree, defaultTree, range) | _ -> None /// Check target that have a constant bool value let (|ConstantBoolTarget|_|) target = match target with - | TTarget([], Expr.Const (Const.Bool b,_,_),_) -> Some b + | TTarget([], Expr.Const (Const.Bool b, _, _), _, _) -> Some b | _ -> None /// Is this a tree, where each decision is a two-way switch (to prevent later duplication of trees), and each branch returns or true/false, /// apart from one branch which defers to another expression -let rec CountBoolLogicTree ((targets: DecisionTreeTarget[], costOuterCaseTree, costOuterDefaultTree, testBool) as data) tree = +let rec CountBoolLogicTree (targets: DecisionTreeTarget[], costOuterCaseTree, costOuterDefaultTree, testBool as data) tree = match tree with - | TDSwitch (_expr, [case], Some defaultTree, _range) -> + | TDSwitch (_sp, _expr, [case], Some defaultTree, _range) -> let tc1,ec1 = CountBoolLogicTree data case.CaseTree let tc2, ec2 = CountBoolLogicTree data defaultTree tc1 + tc2, ec1 + ec2 | TDSuccess([], idx) -> match targets.[idx] with | ConstantBoolTarget result -> (if result = testBool then costOuterCaseTree else costOuterDefaultTree), 0 - | TTarget([], _exp, _) -> costOuterCaseTree + costOuterDefaultTree, 10 + | TTarget([], _exp, _, _) -> costOuterCaseTree + costOuterDefaultTree, 10 | _ -> 100, 100 | _ -> 100, 100 /// Rewrite a decision tree for which CountBoolLogicTree returned a low number (see below). Produce a new decision /// tree where at each ConstantBoolSuccessTree tip we replace with either outerCaseTree or outerDefaultTree /// depending on whether the target result was true/false -let rec RewriteBoolLogicTree ((targets: DecisionTreeTarget[], outerCaseTree, outerDefaultTree, testBool) as data) tree = +let rec RewriteBoolLogicTree (targets: DecisionTreeTarget[], outerCaseTree, outerDefaultTree, testBool as data) tree = match tree with - | TDSwitch (expr, cases, defaultTree, range) -> + | TDSwitch (sp, expr, cases, defaultTree, range) -> let cases2 = cases |> List.map (RewriteBoolLogicCase data) let defaultTree2 = defaultTree |> Option.map (RewriteBoolLogicTree data) - TDSwitch (expr, cases2, defaultTree2, range) + TDSwitch (sp, expr, cases2, defaultTree2, range) | TDSuccess([], idx) -> match targets.[idx] with | ConstantBoolTarget result -> if result = testBool then outerCaseTree else outerDefaultTree - | TTarget([], exp, _) -> mkBoolSwitch exp.Range exp (if testBool then outerCaseTree else outerDefaultTree) (if testBool then outerDefaultTree else outerCaseTree) + | TTarget([], exp, _, _) -> mkBoolSwitch DebugPointAtSwitch.No exp.Range exp (if testBool then outerCaseTree else outerDefaultTree) (if testBool then outerDefaultTree else outerCaseTree) | _ -> failwith "CountBoolLogicTree should exclude this case" | _ -> failwith "CountBoolLogicTree should exclude this case" @@ -1531,7 +1599,7 @@ let rec CombineBoolLogic expr = // try to find nested boolean switch match expr with | Expr.Match (outerSP, outerMatchRange, - TDBoolSwitch(Expr.Match (_innerSP, _innerMatchRange, innerTree, innerTargets, _innerDefaultRange, _innerMatchTy), + TDBoolSwitch(_switchSP, Expr.Match (_innerSP, _innerMatchRange, innerTree, innerTargets, _innerDefaultRange, _innerMatchTy), outerTestBool, outerCaseTree, outerDefaultTree, _outerSwitchRange ), outerTargets, outerDefaultRange, outerMatchTy) -> @@ -1574,7 +1642,12 @@ let MakeStructuralBindingTemp (v: Val) i (arg: Expr) argTy = let name = v.LogicalName + "_" + string i let v, ve = mkCompGenLocal arg.Range name argTy ve, mkCompGenBind v arg - + +let MakeMutableStructuralBindingForTupleElement (v: Val) i (arg: Expr) argTy = + let name = sprintf "%s_%d%s" v.LogicalName i suffixForTupleElementAssignmentTarget + let v, ve = mkMutableCompGenLocal arg.Range name argTy + ve, mkCompGenBind v arg + let ExpandStructuralBindingRaw cenv expr = assert cenv.settings.ExpandStructuralValues() match expr with @@ -1608,6 +1681,86 @@ let rec RearrangeTupleBindings expr fin = | Some b -> Some (mkLetBind m bind b) | None -> None | Expr.Op (TOp.Tuple tupInfo, _, _, _) when not (evalTupInfoIsStruct tupInfo) -> Some (fin expr) + | Expr.Sequential (e1, e2, kind, sp, m) -> + match RearrangeTupleBindings e2 fin with + | Some b -> Some (Expr.Sequential (e1, b, kind, sp, m)) + | None -> None + | _ -> None + +// Attempts to rewrite tuple bindings containing ifs/matches by introducing a mutable local for each tuple element. +// These are assigned to exactly once from each branch in order to eliminate tuple allocations. The tuple binding +// is also rearranged such that OptimizeTupleFieldGet may kick in (see RearrangeTupleBindings comment above). +// First class use of a tuple at the end of any branch prevents this rewrite. +// +// Roughly speaking, the following expression: +// +// let a, b = +// if cond () then +// 1, 2 +// elif cond2 () then +// 3, 4 +// else +// 5, 6 +// in ... +// +// becomes +// +// let mutable a = Unchecked.defaultof<_> +// let mutable b = Unchecked.defaultof<_> +// +// if cond () then +// a <- 1 +// b <- 2 +// elif cond2 () then +// a <- 3 +// b <- 4 +// else +// a <- 5 +// b <- 6 +// in ... +let TryRewriteBranchingTupleBinding g (v: Val) rhs tgtSeqPtOpt body m = + let rec dive g m (requisites: Lazy<_>) expr = + match expr with + | Expr.Match (sp, inputRange, decision, targets, fullRange, ty) -> + // Recurse down every if/match branch + let rewrittenTargets = targets |> Array.choose (fun (TTarget (vals, targetExpr, sp, flags)) -> + match dive g m requisites targetExpr with + | Some rewritten -> TTarget (vals, rewritten, sp, flags) |> Some + | _ -> None) + + // If not all branches can be rewritten, keep the original expression as it is + if rewrittenTargets.Length <> targets.Length then + None + else + Expr.Match (sp, inputRange, decision, rewrittenTargets, fullRange, ty) |> Some + | Expr.Op (TOp.Tuple tupInfo, _, tupleElements, m) when not (evalTupInfoIsStruct tupInfo) -> + // Replace tuple allocation with mutations of locals + let _, _, _, vrefs = requisites.Value + List.map2 (mkValSet m) vrefs tupleElements + |> mkSequentials DebugPointAtSequential.SuppressStmt g m + |> Some + | Expr.Sequential (e1, e2, kind, sp, m) -> + match dive g m requisites e2 with + | Some rewritten -> Expr.Sequential (e1, rewritten, kind, sp, m) |> Some + | _ -> None + | Expr.Let (bind, body, m, _) -> + match dive g m requisites body with + | Some rewritten -> mkLetBind m bind rewritten |> Some + | _ -> None + | _ -> None + + let requisites = lazy ( + let argTys = destRefTupleTy g v.Type + let inits = argTys |> List.map (mkNull m) + let ves, binds = List.mapi2 (MakeMutableStructuralBindingForTupleElement v) inits argTys |> List.unzip + let vrefs = binds |> List.map (fun (TBind (v, _, _)) -> mkLocalValRef v) + argTys, ves, binds, vrefs) + + match dive g m requisites rhs with + | Some rewrittenRhs -> + let argTys, ves, binds, _ = requisites.Value + let rhsAndTupleBinding = mkCompGenSequential m rewrittenRhs (mkLet tgtSeqPtOpt m v (mkRefTupled g m ves argTys) body) + mkLetsBind m binds rhsAndTupleBinding |> Some | _ -> None let ExpandStructuralBinding cenv expr = @@ -1619,7 +1772,9 @@ let ExpandStructuralBinding cenv expr = CanExpandStructuralBinding v) -> match RearrangeTupleBindings rhs (fun top -> mkLet tgtSeqPtOpt m v top body) with | Some e -> ExpandStructuralBindingRaw cenv e - | None -> expr + | None -> + // RearrangeTupleBindings could have failed because the rhs branches + TryRewriteBranchingTupleBinding cenv.g v rhs tgtSeqPtOpt body m |> Option.defaultValue expr // Expand 'let v = Some arg in ...' to 'let tmp = arg in let v = Some tp in ...' // Used to give names to values of optional arguments prior as we inline. @@ -1689,7 +1844,7 @@ let (|AnyRefTupleTrans|) e = /// Look for any QueryBuilder.* operation and transform let (|AnyQueryBuilderOpTrans|_|) g = function - | Expr.App ((Expr.Val (vref, _, _) as v), vty, tyargs, [builder; AnyRefTupleTrans( (src :: rest), replaceArgs) ], m) when + | Expr.App (Expr.Val (vref, _, _) as v, vty, tyargs, [builder; AnyRefTupleTrans( src :: rest, replaceArgs) ], m) when (match vref.ApparentEnclosingEntity with Parent tcref -> tyconRefEq g tcref g.query_builder_tcref | ParentNone -> false) -> Some (src, (fun newSource -> Expr.App (v, vty, tyargs, [builder; replaceArgs(newSource :: rest)], m))) | _ -> None @@ -1746,10 +1901,10 @@ let rec tryRewriteToSeqCombinators g (e: Expr) = // match --> match | Expr.Match (spBind, exprm, pt, targets, m, _ty) -> - let targets = targets |> Array.map (fun (TTarget(vs, e, spTarget)) -> match tryRewriteToSeqCombinators g e with None -> None | Some e -> Some(TTarget(vs, e, spTarget))) + let targets = targets |> Array.map (fun (TTarget(vs, e, spTarget, flags)) -> match tryRewriteToSeqCombinators g e with None -> None | Some e -> Some(TTarget(vs, e, spTarget, flags))) if targets |> Array.forall Option.isSome then let targets = targets |> Array.map Option.get - let ty = targets |> Array.pick (fun (TTarget(_, e, _)) -> Some(tyOfExpr g e)) + let ty = targets |> Array.pick (fun (TTarget(_, e, _, _)) -> Some(tyOfExpr g e)) Some (Expr.Match (spBind, exprm, pt, targets, m, ty)) else None @@ -1867,7 +2022,7 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = | LinearMatchExpr _ | Expr.Sequential _ | Expr.Let _ -> - OptimizeLinearExpr cenv env expr (fun x -> x) + OptimizeLinearExpr cenv env expr id | Expr.Const (c, m, ty) -> OptimizeConst cenv env expr (c, m, ty) @@ -1876,8 +2031,12 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = OptimizeVal cenv env expr (v, m) | Expr.Quote (ast, splices, isFromQueryExpression, m, ty) -> - let splices = ref (splices.Value |> Option.map (map3Of4 (List.map (OptimizeExpr cenv env >> fst)))) - Expr.Quote (ast, splices, isFromQueryExpression, m, ty), + let doData data = map3Of4 (List.map (OptimizeExpr cenv env >> fst)) data + let splices = + match splices.Value with + | Some (data1, data2opt) -> Some (doData data1, doData data2opt) + | None -> None + Expr.Quote (ast, ref splices, isFromQueryExpression, m, ty), { TotalSize = 10 FunctionSize = 1 HasEffect = false @@ -1885,12 +2044,31 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = Info=UnknownValue } | Expr.Obj (_, ty, basev, createExpr, overrides, iimpls, m) -> - OptimizeObjectExpr cenv env (ty, basev, createExpr, overrides, iimpls, m) + match expr with + | NewDelegateExpr cenv.g (lambdaId, vsl, body, _, remake) -> + OptimizeNewDelegateExpr cenv env (lambdaId, vsl, body, remake) + | _ -> + OptimizeObjectExpr cenv env (ty, basev, createExpr, overrides, iimpls, m) | Expr.Op (op, tyargs, args, m) -> OptimizeExprOp cenv env (op, tyargs, args, m) | Expr.App (f, fty, tyargs, argsl, m) -> + match expr with + | DelegateInvokeExpr cenv.g (iref, fty, tyargs, delegatef, args, m) -> + OptimizeFSharpDelegateInvoke cenv env (iref, delegatef, fty, tyargs, args, m) + | _ -> + let attempt = + if cenv.settings.DebugPointsForPipeRight then + match expr with + | OpPipeRight cenv.g _ + | OpPipeRight2 cenv.g _ + | OpPipeRight3 cenv.g _ -> Some (OptimizeDebugPipeRights cenv env expr) + | _ -> None + else None + match attempt with + | Some res -> res + | None -> // eliminate uses of query match TryDetectQueryQuoteAndRun cenv expr with | Some newExpr -> OptimizeExpr cenv env newExpr @@ -1907,7 +2085,7 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = OptimizeLambdas None cenv env topValInfo expr ty | Expr.TyChoose _ -> - OptimizeExpr cenv env (TypeRelations.ChooseTyparSolutionsForFreeChoiceTypars cenv.g cenv.amap expr) + OptimizeExpr cenv env (ChooseTyparSolutionsForFreeChoiceTypars cenv.g cenv.amap expr) | Expr.Match (spMatch, exprm, dtree, targets, m, ty) -> OptimizeMatch cenv env (spMatch, exprm, dtree, targets, m, ty) @@ -1929,12 +2107,20 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = assert ("unexpected reclink" = "") failwith "Unexpected reclink" + | Expr.WitnessArg _ -> + expr, + { TotalSize = 10 + FunctionSize = 1 + HasEffect = false + MightMakeCriticalTailcall=false + Info=UnknownValue } + /// Optimize/analyze an object expression and OptimizeObjectExpr cenv env (ty, baseValOpt, basecall, overrides, iimpls, m) = let basecallR, basecallinfo = OptimizeExpr cenv env basecall let overridesR, overrideinfos = OptimizeMethods cenv env baseValOpt overrides let iimplsR, iimplsinfos = OptimizeInterfaceImpls cenv env baseValOpt iimpls - let exprR=mkObjExpr(ty, baseValOpt, basecallR, overridesR, iimplsR, m) + let exprR = mkObjExpr (ty, baseValOpt, basecallR, overridesR, iimplsR, m) exprR, { TotalSize=closureTotalSize + basecallinfo.TotalSize + AddTotalSizes overrideinfos + AddTotalSizes iimplsinfos FunctionSize=1 (* a newobj *) HasEffect=true @@ -1977,17 +2163,20 @@ and OptimizeInterfaceImpl cenv env baseValOpt (ty, overrides) = and MakeOptimizedSystemStringConcatCall cenv env m args = let rec optimizeArg argExpr accArgs = match argExpr, accArgs with - | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ], _), _ - when IsILMethodRefSystemStringConcatArray mref -> + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, ilMethRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ], _), _ + when IsILMethodRefSystemStringConcatArray ilMethRef -> optimizeArgs args accArgs - | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, args, _), _ - when IsILMethodRefSystemStringConcat mref -> + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, ilMethRef, _, _, _), _, args, _), _ + when IsILMethodRefSystemStringConcat ilMethRef -> optimizeArgs args accArgs +// String constant folding requires a bit more work as we cannot quadratically concat strings at compile time. +#if STRING_CONSTANT_FOLDING // Optimize string constants, e.g. "1" + "2" will turn into "12" | Expr.Const (Const.String str1, _, _), Expr.Const (Const.String str2, _, _) :: accArgs -> mkString cenv.g m (str1 + str2) :: accArgs +#endif | arg, _ -> arg :: accArgs @@ -2012,8 +2201,8 @@ and MakeOptimizedSystemStringConcatCall cenv env m args = mkStaticCall_String_Concat_Array cenv.g m arg match expr with - | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _) as op, tyargs, args, m) - when IsILMethodRefSystemStringConcat mref || IsILMethodRefSystemStringConcatArray mref -> + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, ilMethRef, _, _, _) as op, tyargs, args, m) + when IsILMethodRefSystemStringConcat ilMethRef || IsILMethodRefSystemStringConcatArray ilMethRef -> OptimizeExprOpReductions cenv env (op, tyargs, args, m) | _ -> OptimizeExpr cenv env expr @@ -2035,7 +2224,7 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = Info=UnknownValue } // Handle address-of - | TOp.LValueOp ((LAddrOf _ as lop), lv), _, _ -> + | TOp.LValueOp (LAddrOf _ as lop, lv), _, _ -> let newVal, _ = OptimizeExpr cenv env (exprForValRef m lv) let newOp = match newVal with @@ -2052,16 +2241,16 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = // Handle these as special cases since mutables are allowed inside their bodies | TOp.While (spWhile, marker), _, [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _)] -> - OptimizeWhileLoop cenv { env with inLoop=true } (spWhile, marker, e1, e2, m) + OptimizeWhileLoop cenv { env with disableMethodSplitting=true } (spWhile, marker, e1, e2, m) | TOp.For (spStart, dir), _, [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [v], e3, _, _)] -> - OptimizeFastIntegerForLoop cenv { env with inLoop=true } (spStart, v, e1, dir, e2, e3, m) + OptimizeFastIntegerForLoop cenv { env with disableMethodSplitting=true } (spStart, v, e1, dir, e2, e3, m) | TOp.TryFinally (spTry, spFinally), [resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)] -> OptimizeTryFinally cenv env (spTry, spFinally, e1, e2, m, resty) - | TOp.TryCatch (spTry, spWith), [resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> - OptimizeTryCatch cenv env (e1, vf, ef, vh, eh, m, resty, spTry, spWith) + | TOp.TryWith (spTry, spWith), [resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> + OptimizeTryWith cenv env (e1, vf, ef, vh, eh, m, resty, spTry, spWith) | TOp.TraitCall traitInfo, [], args -> OptimizeTraitCall cenv env (traitInfo, args, m) @@ -2069,9 +2258,9 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = // This code hooks arr.Length. The idea is to ensure loops end up in the "same shape"as the forms of loops that the .NET JIT // guarantees to optimize. - | TOp.ILCall (_, _, _, _, _, _, _, mref, _enclTypeArgs, _methTypeArgs, _tys), _, [arg] - when (mref.DeclaringTypeRef.Name = cenv.g.ilg.typ_Array.TypeRef.Name && - mref.Name = "get_Length" && + | TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, _, _, _), _, [arg] + when (ilMethRef.DeclaringTypeRef.Name = cenv.g.ilg.typ_Array.TypeRef.Name && + ilMethRef.Name = "get_Length" && isArray1DTy cenv.g (tyOfExpr cenv.g arg)) -> OptimizeExpr cenv env (Expr.Op (TOp.ILAsm (i_ldlen, [cenv.g.int_ty]), [], [arg], m)) @@ -2080,11 +2269,11 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = | TOp.ILAsm ([], [ty]), _, [a] when typeEquiv cenv.g (tyOfExpr cenv.g a) ty -> OptimizeExpr cenv env a // Optimize calls when concatenating strings, e.g. "1" + "2" + "3" + "4" .. etc. - | TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ] - when IsILMethodRefSystemStringConcatArray mref -> + | TOp.ILCall(_, _, _, _, _, _, _, ilMethRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ] + when IsILMethodRefSystemStringConcatArray ilMethRef -> MakeOptimizedSystemStringConcatCall cenv env m args - | TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, args - when IsILMethodRefSystemStringConcat mref -> + | TOp.ILCall(_, _, _, _, _, _, _, ilMethRef, _, _, _), _, args + when IsILMethodRefSystemStringConcat ilMethRef -> MakeOptimizedSystemStringConcatCall cenv env m args | _ -> @@ -2104,7 +2293,7 @@ and OptimizeExprOpReductionsAfter cenv env (op, tyargs, argsR, arginfos, m) = | _ -> None match knownValue with | Some valu -> - match TryOptimizeVal cenv env (false, valu, m) with + match TryOptimizeVal cenv env (None, false, false, valu, m) with | Some res -> OptimizeExpr cenv env res (* discard e1 since guard ensures it has no effects *) | None -> OptimizeExprOpFallback cenv env (op, tyargs, argsR, m) arginfos valu | None -> OptimizeExprOpFallback cenv env (op, tyargs, argsR, m) arginfos UnknownValue @@ -2144,13 +2333,13 @@ and OptimizeExprOpFallback cenv env (op, tyargs, argsR, m) arginfos valu = | StripUnionCaseValue (uc, info) -> UnionCaseValue(uc, info) | _ -> valu 0, valu - | TOp.ILAsm (instrs, tys) -> + | TOp.ILAsm (instrs, retTypes) -> min instrs.Length 1, - mkAssemblyCodeValueInfo cenv.g instrs argValues tys + mkAssemblyCodeValueInfo cenv.g instrs argValues retTypes | TOp.Bytes bytes -> bytes.Length/10, valu | TOp.UInt16s bytes -> bytes.Length/10, valu | TOp.ValFieldGetAddr _ - | TOp.Array | TOp.For _ | TOp.While _ | TOp.TryCatch _ | TOp.TryFinally _ + | TOp.Array | TOp.For _ | TOp.While _ | TOp.TryWith _ | TOp.TryFinally _ | TOp.ILCall _ | TOp.TraitCall _ | TOp.LValueOp _ | TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.RefAddrGet _ | TOp.Coerce | TOp.Reraise | TOp.UnionCaseFieldGetAddr _ @@ -2171,7 +2360,7 @@ and OptimizeExprOpFallback cenv env (op, tyargs, argsR, m) arginfos valu = // Indirect calls to IL code are always taken as tailcalls let mayBeCriticalTailcall = match op with - | TOp.ILCall (virt, _, newobj, _, _, _, _, _, _, _, _) -> not newobj && virt + | TOp.ILCall (isVirtual, _, isCtor, _, _, _, _, _, _, _, _) -> not isCtor && isVirtual | _ -> false let vinfo = { TotalSize=argsTSize + cost @@ -2206,9 +2395,9 @@ and OptimizeConst cenv env expr (c, m, ty) = Info=MakeValueInfoForConst c ty} /// Optimize/analyze a record lookup. -and TryOptimizeRecordFieldGet cenv _env (e1info, (RFRef (rtcref, _) as r), _tinst, m) = +and TryOptimizeRecordFieldGet cenv _env (e1info, (RecdFieldRef (rtcref, _) as r), _tinst, m) = match destRecdValue e1info.Info with - | Some finfos when cenv.settings.EliminateRecdFieldGet() && not e1info.HasEffect -> + | Some finfos when cenv.settings.EliminateRecdFieldGet && not e1info.HasEffect -> match TryFindFSharpAttribute cenv.g cenv.g.attrib_CLIMutableAttribute rtcref.Attribs with | Some _ -> None | None -> @@ -2219,7 +2408,7 @@ and TryOptimizeRecordFieldGet cenv _env (e1info, (RFRef (rtcref, _) as r), _tins and TryOptimizeTupleFieldGet cenv _env (_tupInfo, e1info, tys, n, m) = match destTupleValue e1info.Info with - | Some tups when cenv.settings.EliminateTupleFieldGet() && not e1info.HasEffect -> + | Some tups when cenv.settings.EliminateTupleFieldGet && not e1info.HasEffect -> let len = tups.Length if len <> tys.Length then errorR(InternalError("error: tuple lengths don't match", m)) if n >= len then errorR(InternalError("TryOptimizeTupleFieldGet: tuple index out of range", m)) @@ -2248,12 +2437,20 @@ and OptimizeFastIntegerForLoop cenv env (spStart, v, e1, dir, e2, e3, m) = | FSharpForLoopUp, Expr.Op (TOp.ILAsm ([ (AI_sub | AI_sub_ovf)], _), _, [Expr.Op (TOp.ILAsm ([ I_ldlen; (AI_conv DT_I4)], _), _, [arre], _); Expr.Const (Const.Int32 1, _, _)], _) when not (snd(OptimizeExpr cenv env arre)).HasEffect -> - mkLdlen cenv.g (e2R.Range) arre, CSharpForLoopUp + mkLdlen cenv.g e2R.Range arre, CSharpForLoopUp + + | FSharpForLoopUp, Expr.Op (TOp.ILAsm ([ (AI_sub | AI_sub_ovf)], _), _, [Expr.Op (TOp.ILCall(_,_,_,_,_,_,_, mth, _,_,_), _, [arre], _) as lenOp; Expr.Const (Const.Int32 1, _, _)], _) + when + mth.Name = "get_Length" && (mth.DeclaringTypeRef.FullName = "System.Span`1" || mth.DeclaringTypeRef.FullName = "System.ReadOnlySpan`1") + && not (snd(OptimizeExpr cenv env arre)).HasEffect -> + + lenOp, CSharpForLoopUp + // detect upwards for loops with constant bounds, but not MaxValue! | FSharpForLoopUp, Expr.Const (Const.Int32 n, _, _) when n < System.Int32.MaxValue -> - mkIncr cenv.g (e2R.Range) e2R, CSharpForLoopUp + mkIncr cenv.g e2R.Range e2R, CSharpForLoopUp | _ -> e2R, dir @@ -2261,7 +2458,7 @@ and OptimizeFastIntegerForLoop cenv env (spStart, v, e1, dir, e2, e3, m) = let einfos = [e1info;e2info;e3info] let eff = OrEffects einfos (* neither bounds nor body has an effect, and loops always terminate, hence eliminate the loop *) - if not eff then + if cenv.settings.EliminateForLoop && not eff then mkUnit cenv.g m, { TotalSize=0; FunctionSize=0; HasEffect=false; MightMakeCriticalTailcall=false; Info=UnknownValue } else let exprR = mkFor cenv.g (spStart, v, e1R, dir, e2R, e3R, m) @@ -2286,7 +2483,7 @@ and OptimizeLetRec cenv env (binds, bodyExpr, m) = // Trim out any optimization info that involves escaping values let evalueR = AbstractExprInfoByVars (vs, []) einfo.Info // REVIEW: size of constructing new closures - should probably add #freevars + #recfixups here - let bodyExprR = Expr.LetRec (bindsRR, bodyExprR, m, NewFreeVarsCache()) + let bodyExprR = Expr.LetRec (bindsRR, bodyExprR, m, Construct.NewFreeVarsCache()) let info = CombineValueInfos (einfo :: bindinfos) evalueR bodyExprR, info @@ -2299,6 +2496,24 @@ and OptimizeLinearExpr cenv env expr contf = let expr = if cenv.settings.ExpandStructuralValues() then ExpandStructuralBinding cenv expr else expr let expr = stripExpr expr + // Matching on 'match __resumableEntry() with ...` is really a first-class language construct which we + // don't optimize separately + match expr with + | ResumableEntryMatchExpr cenv.g (noneBranchExpr, someVar, someBranchExpr, rebuild) -> + let noneBranchExprR, e1info = OptimizeExpr cenv env noneBranchExpr + let env = BindInternalValToUnknown cenv someVar env + let someBranchExprR, e2info = OptimizeExpr cenv env someBranchExpr + let exprR = rebuild (noneBranchExprR, someBranchExprR) + let infoR = + { TotalSize = e1info.TotalSize + e2info.TotalSize + FunctionSize = e1info.FunctionSize + e2info.FunctionSize + HasEffect = true + MightMakeCriticalTailcall = false + Info = UnknownValue } + contf (exprR, infoR) + + | _ -> + match expr with | Expr.Sequential (e1, e2, flag, spSeq, m) -> let e1R, e1info = OptimizeExpr cenv env e1 @@ -2306,7 +2521,7 @@ and OptimizeLinearExpr cenv env expr contf = if (flag = NormalSeq) && // Always eliminate '(); expr' sequences, even in debug code, to ensure that // conditional method calls don't leave a dangling breakpoint (see FSharp 1.0 bug 6034) - (cenv.settings.EliminateSequential () || (match e1R with Expr.Const (Const.Unit, _, _) -> true | _ -> false)) && + (cenv.settings.EliminateSequential || (match e1R with Expr.Const (Const.Unit, _, _) -> true | _ -> false)) && not e1info.HasEffect then e2R, e2info else @@ -2352,7 +2567,7 @@ and OptimizeLinearExpr cenv env expr contf = // This ConsiderSplitToMethod is performed because it is present in OptimizeDecisionTreeTarget let e2, e2info = ConsiderSplitToMethod cenv.settings.abstractBigTargets cenv.settings.bigTargetSize cenv env (e2, e2info) let tinfos = [tg1info; e2info] - let targetsR = [tg1; TTarget([], e2, spTarget2)] + let targetsR = [tg1; TTarget([], e2, spTarget2, None)] OptimizeMatchPart2 cenv (spMatch, exprm, dtreeR, targetsR, dinfo, tinfos, m, ty))) | LinearOpExpr (op, tyargs, argsHead, argLast, m) -> @@ -2374,30 +2589,30 @@ and OptimizeTryFinally cenv env (spTry, spFinally, e1, e2, m, ty) = MightMakeCriticalTailcall = false // no tailcalls from inside in try/finally Info = UnknownValue } // try-finally, so no effect means no exception can be raised, so just sequence the finally - if cenv.settings.EliminateTryCatchAndTryFinally () && not e1info.HasEffect then + if cenv.settings.EliminateTryWithAndTryFinally && not e1info.HasEffect then let sp = match spTry with - | SequencePointAtTry _ -> SequencePointsAtSeq - | SequencePointInBodyOfTry -> SequencePointsAtSeq - | NoSequencePointAtTry -> SuppressSequencePointOnExprOfSequential + | DebugPointAtTry.Yes _ -> DebugPointAtSequential.SuppressNeither + | DebugPointAtTry.Body -> DebugPointAtSequential.SuppressNeither + | DebugPointAtTry.No -> DebugPointAtSequential.SuppressStmt Expr.Sequential (e1R, e2R, ThenDoSeq, sp, m), info else mkTryFinally cenv.g (e1R, e2R, m, ty, spTry, spFinally), info -/// Optimize/analyze a try/catch construct. -and OptimizeTryCatch cenv env (e1, vf, ef, vh, eh, m, ty, spTry, spWith) = +/// Optimize/analyze a try/with construct. +and OptimizeTryWith cenv env (e1, vf, ef, vh, eh, m, ty, spTry, spWith) = let e1R, e1info = OptimizeExpr cenv env e1 - // try-catch, so no effect means no exception can be raised, so discard the catch - if cenv.settings.EliminateTryCatchAndTryFinally () && not e1info.HasEffect then + // try-with, so no effect means no exception can be raised, so discard the with + if cenv.settings.EliminateTryWithAndTryFinally && not e1info.HasEffect then e1R, e1info else let envinner = BindInternalValToUnknown cenv vf (BindInternalValToUnknown cenv vh env) let efR, efinfo = OptimizeExpr cenv envinner ef let ehR, ehinfo = OptimizeExpr cenv envinner eh let info = - { TotalSize = e1info.TotalSize + efinfo.TotalSize+ ehinfo.TotalSize + tryCatchSize - FunctionSize = e1info.FunctionSize + efinfo.FunctionSize+ ehinfo.FunctionSize + tryCatchSize + { TotalSize = e1info.TotalSize + efinfo.TotalSize+ ehinfo.TotalSize + tryWithSize + FunctionSize = e1info.FunctionSize + efinfo.FunctionSize+ ehinfo.FunctionSize + tryWithSize HasEffect = e1info.HasEffect || efinfo.HasEffect || ehinfo.HasEffect MightMakeCriticalTailcall = false Info = UnknownValue } @@ -2422,7 +2637,7 @@ and OptimizeWhileLoop cenv env (spWhile, marker, e1, e2, m) = and OptimizeTraitCall cenv env (traitInfo, args, m) = // Resolve the static overloading early (during the compulsory rewrite phase) so we can inline. - match ConstraintSolver.CodegenWitnessThatTypeSupportsTraitConstraint cenv.TcVal cenv.g cenv.amap m traitInfo args with + match ConstraintSolver.CodegenWitnessExprForTraitConstraint cenv.TcVal cenv.g cenv.amap m traitInfo args with | OkResult (_, Some expr) -> OptimizeExpr cenv env expr @@ -2431,9 +2646,21 @@ and OptimizeTraitCall cenv env (traitInfo, args, m) = let argsR, arginfos = OptimizeExprsThenConsiderSplits cenv env args OptimizeExprOpFallback cenv env (TOp.TraitCall traitInfo, [], argsR, m) arginfos UnknownValue +and CopyExprForInlining cenv isInlineIfLambda expr m = + // 'InlineIfLambda' doesn't erase ranges, e.g. if the lambda is user code. + if isInlineIfLambda then + expr + |> copyExpr cenv.g CloneAll + else + // Debug points are erased when doing inlining + // Locals are marked compiler generated when doing inlining + expr + |> copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated + |> remarkExpr m + /// Make optimization decisions once we know the optimization information /// for a value -and TryOptimizeVal cenv env (mustInline, valInfoForVal, m) = +and TryOptimizeVal cenv env (vOpt: ValRef option, mustInline, inlineIfLambda, valInfoForVal, m) = match valInfoForVal with // Inline all constants immediately @@ -2441,21 +2668,33 @@ and TryOptimizeVal cenv env (mustInline, valInfoForVal, m) = Some (Expr.Const (c, m, ty)) | SizeValue (_, detail) -> - TryOptimizeVal cenv env (mustInline, detail, m) + TryOptimizeVal cenv env (vOpt, mustInline, inlineIfLambda, detail, m) | ValValue (vR, detail) -> // Inline values bound to other values immediately // Prefer to inline using the more specific info if possible // If the more specific info didn't reveal an inline then use the value - match TryOptimizeVal cenv env (mustInline, detail, m) with + match TryOptimizeVal cenv env (vOpt, mustInline, inlineIfLambda, detail, m) with | Some e -> Some e - | None -> Some(exprForValRef m vR) + | None -> + // If we have proven 'v = compilerGeneratedValue' + // and 'v' is being eliminated in favour of 'compilerGeneratedValue' + // then replace the name of 'compilerGeneratedValue' + // by 'v' and mark it not compiler generated so we preserve good debugging and names. + // Don't do this for things represented statically as it may publish multiple values with the same name. + match vOpt with + | Some v when not v.IsCompilerGenerated && vR.IsCompilerGenerated && not vR.IsCompiledAsTopLevel && not v.IsCompiledAsTopLevel -> + vR.Deref.SetIsCompilerGenerated(false) + vR.Deref.SetLogicalName(v.LogicalName) + | _ -> () + Some(exprForValRef m vR) | ConstExprValue(_size, expr) -> Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr)) - | CurriedLambdaValue (_, _, _, expr, _) when mustInline -> - Some (remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated expr)) + | CurriedLambdaValue (_, _, _, expr, _) when mustInline || inlineIfLambda -> + let exprCopy = CopyExprForInlining cenv inlineIfLambda expr m + Some exprCopy | TupleValue _ | UnionCaseValue _ | RecdValue _ when mustInline -> failwith "tuple, union and record values cannot be marked 'inline'" @@ -2468,24 +2707,26 @@ and TryOptimizeVal cenv env (mustInline, valInfoForVal, m) = | _ -> None and TryOptimizeValInfo cenv env m vinfo = - if vinfo.HasEffect then None else TryOptimizeVal cenv env (false, vinfo.Info, m) + if vinfo.HasEffect then None else TryOptimizeVal cenv env (None, false, false, vinfo.Info, m) /// Add 'v1 = v2' information into the information stored about a value and AddValEqualityInfo g m (v: ValRef) info = // ValValue is information that v = v2, where v2 does not change // So we can't record this information for mutable values. An exception can be made // for "outArg" values arising from method calls since they are only temporarily mutable - // when their address is passed to the method call. - if v.IsMutable && not (v.IsCompilerGenerated && v.DisplayName.StartsWith(PrettyNaming.outArgCompilerGeneratedName)) then + // when their address is passed to the method call. Another exception are mutable variables + // created for tuple elimination in branching tuple bindings because they are assigned to + // exactly once. + if not v.IsMutable || IsKnownOnlyMutableBeforeUse v then + { info with Info = MakeValueInfoForValue g m v info.Info } + else info - else - {info with Info= MakeValueInfoForValue g m v info.Info} /// Optimize/analyze a use of a value and OptimizeVal cenv env expr (v: ValRef, m) = let valInfoForVal = GetInfoForVal cenv env m v - match TryOptimizeVal cenv env (v.MustInline, valInfoForVal.ValExprInfo, m) with + match TryOptimizeVal cenv env (Some v, v.MustInline, v.InlineIfLambda, valInfoForVal.ValExprInfo, m) with | Some e -> // don't reoptimize inlined lambdas until they get applied to something match e with @@ -2502,7 +2743,10 @@ and OptimizeVal cenv env expr (v: ValRef, m) = e, AddValEqualityInfo cenv.g m v einfo | None -> - if v.MustInline then error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m)) + if v.MustInline then + error(Error(FSComp.SR.optFailedToInlineValue(v.DisplayName), m)) + if v.InlineIfLambda then + warning(Error(FSComp.SR.optFailedToInlineSuggestedValue(v.DisplayName), m)) expr, (AddValEqualityInfo cenv.g m v { Info=valInfoForVal.ValExprInfo HasEffect=false @@ -2752,21 +2996,20 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) | StripLambdaValue (lambdaId, arities, size, f2, f2ty) when (// Considering inlining lambda cenv.optimizing && - cenv.settings.InlineLambdas () && + cenv.settings.InlineLambdas && not finfo.HasEffect && // Don't inline recursively! not (Zset.contains lambdaId env.dontInline) && (// Check the number of argument groups is enough to saturate the lambdas of the target. (if tyargs |> List.exists (fun t -> match t with TType_measure _ -> false | _ -> true) then 1 else 0) + args.Length = arities && - (// Enough args - (if size > cenv.settings.lambdaInlineThreshold + args.Length then - // Not inlining lambda near, size too big - false - else true)))) -> + (if size > cenv.settings.lambdaInlineThreshold + args.Length then + // Not inlining lambda near, size too big + false + else true))) -> let isBaseCall = not (List.isEmpty args) && match args.[0] with - | Expr.Val (vref, _, _) when vref.BaseOrThisInfo = BaseVal -> true + | Expr.Val (vref, _, _) when vref.IsBaseVal -> true | _ -> false if isBaseCall then None else @@ -2809,13 +3052,14 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) if isGetHashCode then None else // Inlining lambda - (* ---------- printf "Inlining lambda near %a = %s\n" outputRange m (showL (exprL f2)) (* JAMES: *) ----------*) - let f2R = remarkExpr m (copyExpr cenv.g CloneAllAndMarkExprValsAsCompilerGenerated f2) + let f2R = CopyExprForInlining cenv false f2 m + // Optimizing arguments after inlining // REVIEW: this is a cheapshot way of optimizing the arg expressions as well without the restriction of recursive // inlining kicking into effect let argsR = args |> List.map (fun e -> let eR, _einfo = OptimizeExpr cenv env e in eR) + // Beta reduce. MakeApplicationAndBetaReduce cenv.g does all the hard work. // Inlining: beta reducing let exprR = MakeApplicationAndBetaReduce cenv.g (f2R, f2ty, [tyargs], argsR, m) @@ -2824,19 +3068,118 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) | _ -> None +// Optimize the application of computed functions. +// See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md +// +// Always lift 'let', 'letrec', sequentials and 'match' off computed functions so +// (let x = 1 in fexpr) arg ---> let x = 1 in fexpr arg +// (let rec binds in fexpr) arg ---> let rec binds in fexpr arg +// (e; fexpr) arg ---> e; fexpr arg +// (match e with pat1 -> func1 | pat2 -> func2) args --> (match e with pat1 -> func1 args | pat2 -> func2 args) +// +// This is always valid because functions are computed before arguments. +// We do this even in debug code as it doesn't change debugging properties. +// This is useful in DSLs that compute functions and weave them together with user code, e.g. +// inline F# computation expressions. +// +// The case of 'match' is particularly awkward because we are cloning 'args' on the right. We want to avoid +// this in the common case, so we first collect up all the "function holes" +// (let x = 1 in ) +// (let rec binds in ) +// (e; ) +// (match e with pat1 -> | pat2 -> ) +// then work out if we only have one of them. While collecting up the holes we build up a function to rebuild the +// overall expression given new expressions ("func" --> "func args" and its optimization). +// +// If there a multiple holes, we had a "match" somewhere, and we abandon OptimizeApplication and simply apply the +// function to the arguments at each hole (copying the arguments), then reoptimize the whole result. +// +// If there is a single hole, we proceed with OptimizeApplication +and StripPreComputationsFromComputedFunction g f0 args mkApp = + + // Identify sub-expressions that are the lambda functions to apply. + // There may be more than one because of multiple 'match' branches. + let rec strip (f: Expr) : Expr list * (Expr list -> Expr) = + match stripExpr f with + | Expr.Let (bind, bodyExpr, m, _) -> + let fs, remake = strip bodyExpr + fs, (remake >> mkLetBind m bind) + | Expr.LetRec (binds, bodyExpr, m, _) -> + let fs, remake = strip bodyExpr + fs, (remake >> mkLetRecBinds m binds) + | Expr.Sequential (x1, bodyExpr, NormalSeq, sp, m) -> + let fs, remake = strip bodyExpr + fs, (remake >> (fun bodyExpr2 -> Expr.Sequential (x1, bodyExpr2, NormalSeq, sp, m))) + + // Matches which compute a different function on each branch are awkward, see above. + | Expr.Match (spMatch, exprm, dtree, targets, dflt, _ty) when targets.Length <= 2 -> + let fsl, targetRemakes = + targets + |> Array.map (fun (TTarget(vs, bodyExpr, spTarget, flags)) -> + let fs, remake = strip bodyExpr + fs, (fun holes -> TTarget(vs, remake holes, spTarget, flags))) + |> Array.unzip + + let fs = List.concat fsl + let chunkSizes = Array.map List.length fsl + let remake (newExprs: Expr list) = + let newExprsInChunks, _ = + ((newExprs,0), chunkSizes) ||> Array.mapFold (fun (acc,i) chunkSize -> + let chunk = acc.[0..chunkSize-1] + let acc = acc.[chunkSize..] + chunk, (acc, i+chunkSize)) + let targetsR = (newExprsInChunks, targetRemakes) ||> Array.map2 (fun newExprsChunk targetRemake -> targetRemake newExprsChunk) + let tyR = tyOfExpr g targetsR.[0].TargetExpression + Expr.Match (spMatch, exprm, dtree, targetsR, dflt, tyR) + fs, remake + + | _ -> + [f], (fun newExprs -> (assert (newExprs.Length = 1)); List.head newExprs) + + match strip f0 with + | [f], remake -> + // If the computed function has only one interesting function result expression then progress as normal + Choice2Of2 (f, (fun x -> remake [x])) + | fs, remake -> + // If there is a match with multiple branches then apply each function to a copy of the arguments, + // remake the whole expression and return an indicator to reoptimize that. + let applied = + fs |> List.mapi (fun i f -> + let argsR = if i = 0 then args else List.map (copyExpr g CloneAll) args + mkApp f argsR) + let remade = remake applied + Choice1Of2 remade + +/// When optimizing a function in an application, use the whole range including arguments for the range +/// to apply to 'inline' code +and OptimizeFuncInApplication cenv env f0 mWithArgs = + let f0 = stripExpr f0 + match f0 with + | Expr.Val (v, _vFlags, _) -> + OptimizeVal cenv env f0 (v, mWithArgs) + | _ -> + OptimizeExpr cenv env f0 + /// Optimize/analyze an application of a function to type and term arguments and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) = + let g = cenv.g // trying to devirtualize match TryDevirtualizeApplication cenv env (f0, tyargs, args, m) with | Some res -> // devirtualized res | None -> - let newf0, finfo = OptimizeExpr cenv env f0 + let optf0, finfo = OptimizeFuncInApplication cenv env f0 m + + match StripPreComputationsFromComputedFunction g optf0 args (fun f argsR -> MakeApplicationAndBetaReduce g (f, tyOfExpr g f, [tyargs], argsR, f.Range)) with + | Choice1Of2 remade -> + OptimizeExpr cenv env remade + | Choice2Of2 (newf0, remake) -> + match TryInlineApplication cenv env finfo (tyargs, args, m) with - | Some res -> + | Some (res, info) -> // inlined - res + (res |> remake), info | None -> let shapes = @@ -2859,9 +3202,10 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) = let newArgs, arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env shapes // beta reducing - let newExpr = MakeApplicationAndBetaReduce cenv.g (newf0, f0ty, [tyargs], newArgs, m) + let reducedExpr = MakeApplicationAndBetaReduce g (newf0, f0ty, [tyargs], newArgs, m) + let newExpr = reducedExpr |> remake - match newf0, newExpr with + match newf0, reducedExpr with | (Expr.Lambda _ | Expr.TyLambda _), Expr.Let _ -> // we beta-reduced, hence reoptimize OptimizeExpr cenv env newExpr @@ -2900,19 +3244,139 @@ and OptimizeApplication cenv env (f0, f0ty, tyargs, args, m) = HasEffect=true MightMakeCriticalTailcall = mayBeCriticalTailcall Info=ValueOfExpr newExpr } + +/// Extract a sequence of pipe-right operations (note the pipe-right operator is left-associative +/// so we start with the full thing and descend down taking apps off the end first) +/// The pipeline begins with a |>, ||> or |||> +and getPipes g expr acc = + match expr with + | OpPipeRight g (resType, xExpr, fExpr, m) -> + getPipes g xExpr (([xExpr.Range], resType, fExpr, m) :: acc) + | OpPipeRight2 g (resType, x1Expr, x2Expr, fExpr, m) -> + [x1Expr; x2Expr], (([x1Expr.Range; x2Expr.Range], resType, fExpr, m) :: acc) + | OpPipeRight3 g (resType, x1Expr, x2Expr, x3Expr, fExpr, m) -> + [x1Expr; x2Expr; x3Expr], (([x1Expr.Range; x2Expr.Range; x3Expr.Range], resType, fExpr, m) :: acc) + | _ -> + [expr], acc + +/// In debug code, process a pipe-right manually to lay down the debug point for the application of the function after +/// the evaluation of the argument, all the way down the chain. +and OptimizeDebugPipeRights cenv env expr = + let g = cenv.g + + env.methEnv.pipelineCount <- env.methEnv.pipelineCount + 1 + let xs0, pipes = getPipes g expr [] + + let xs0R, xs0Infos = OptimizeExprsThenConsiderSplits cenv env xs0 + let xs0Info = CombineValueInfosUnknown xs0Infos + + assert (pipes.Length > 0) + let pipesFront, pipeLast = List.frontAndBack pipes + + // The last pipe in the chain + // ... |> fLast + // turns into a then-do sequential, so + // fLast thendo () + // with a breakpoint on the first expression + let binderLast (prevInputs, prevInputInfo) = + let (_, _, fExpr: Expr, _) = pipeLast + let fRange = fExpr.Range + let fType = tyOfExpr g fExpr + let fR, finfo = OptimizeExpr cenv env fExpr + let app = mkApps g ((fR, fType), [], prevInputs, fRange) + let expr = mkDebugPoint g fRange app + let info = CombineValueInfosUnknown [finfo; prevInputInfo] + expr, info + + // Mid points in the chain + // ... |> fMid |> rest + // turn into let-binding on an intermediate pipe stage + // let pipe-stage-n = fMid + // rest + // with a breakpoint on the binding + // + let pipesBinder = + List.foldBack + (fun (i, (xsRange, resType, fExpr: Expr, _)) binder -> + let fRange = fExpr.Range + let fType = tyOfExpr g fExpr + let name = $"Pipe #%d{env.methEnv.pipelineCount} stage #%d{i+1} at line %d{fRange.StartLine}" + let stageVal, stageValExpr = mkLocal (List.reduce unionRanges xsRange) name resType + let fR, finfo = OptimizeExpr cenv env fExpr + let restExpr, restInfo = binder ([stageValExpr], finfo) + let newBinder (ves, info) = + // The range used for the 'let' expression is only the 'f' in x |> f + let app = mkApps g ((fR, fType), [], ves, fRange) + let appDebugPoint = DebugPointAtBinding.Yes fRange + let expr = mkLet appDebugPoint fRange stageVal app restExpr + let info = CombineValueInfosUnknown [info; restInfo] + expr, info + newBinder + ) + (List.indexed pipesFront) + binderLast + + // The first point in the chain is similar + // let = x + // rest + // with a breakpoint on the pipe-input binding + let nxs0R = xs0R.Length + let inputVals, inputValExprs = + xs0R + |> List.mapi (fun i x0R -> + let nm = $"Pipe #%d{env.methEnv.pipelineCount} input" + (if nxs0R > 1 then " #" + string (i+1) else "") + $" at line %d{x0R.Range.StartLine}" + mkLocal x0R.Range nm (tyOfExpr g x0R)) + |> List.unzip + let pipesExprR, pipesInfo = pipesBinder (inputValExprs, xs0Info) + + // Build up the chain of 'let' related to the first input + let expr = + List.foldBack2 + (fun (x0R: Expr) inputVal e -> + let xRange0 = x0R.Range + mkLet (DebugPointAtBinding.Yes xRange0) expr.Range inputVal x0R e) + xs0R + inputVals + pipesExprR + expr, { pipesInfo with HasEffect=true} + +and OptimizeFSharpDelegateInvoke cenv env (invokeRef, f0, f0ty, tyargs, args, m) = + let g = cenv.g + let optf0, finfo = OptimizeExpr cenv env f0 + + match StripPreComputationsFromComputedFunction g optf0 args (fun f argsR -> MakeFSharpDelegateInvokeAndTryBetaReduce g (invokeRef, f, f0ty, tyargs, argsR, m)) with + | Choice1Of2 remade -> + OptimizeExpr cenv env remade + | Choice2Of2 (newf0, remake) -> + + let newArgs, arginfos = OptimizeExprsThenConsiderSplits cenv env args + let reducedExpr = MakeFSharpDelegateInvokeAndTryBetaReduce g (invokeRef, newf0, f0ty, tyargs, newArgs, m) + let newExpr = reducedExpr |> remake + match newf0, reducedExpr with + | Expr.Obj _, Expr.Let _ -> + // we beta-reduced, hence reoptimize + OptimizeExpr cenv env newExpr + | _ -> + // no reduction, return + newExpr, { TotalSize=finfo.TotalSize + AddTotalSizes arginfos + FunctionSize=finfo.FunctionSize + AddFunctionSizes arginfos + HasEffect=true + MightMakeCriticalTailcall = true + Info=ValueOfExpr newExpr } + /// Optimize/analyze a lambda expression and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = match e with | Expr.Lambda (lambdaId, _, _, _, _, m, _) | Expr.TyLambda (lambdaId, _, _, m, _) -> + let env = { env with methEnv = { pipelineCount = 0 }} let tps, ctorThisValOpt, baseValOpt, vsl, body, bodyty = IteratedAdjustArityOfLambda cenv.g cenv.amap topValInfo e let env = { env with functionVal = (match vspec with None -> None | Some v -> Some (v, topValInfo)) } let env = Option.foldBack (BindInternalValToUnknown cenv) ctorThisValOpt env let env = Option.foldBack (BindInternalValToUnknown cenv) baseValOpt env let env = BindTypeVarsToUnknown tps env let env = List.foldBack (BindInternalValsToUnknown cenv) vsl env - let env = BindInternalValsToUnknown cenv (Option.toList baseValOpt) env let bodyR, bodyinfo = OptimizeExpr cenv env body let exprR = mkMemberLambdas m tps ctorThisValOpt baseValOpt vsl (bodyR, bodyty) let arities = vsl.Length @@ -2958,7 +3422,6 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = let expr2 = mkMemberLambdas m tps ctorThisValOpt None vsl (bodyR, bodyty) CurriedLambdaValue (lambdaId, arities, bsize, expr2, ety) - let estimatedSize = match vspec with | Some v when v.IsCompiledAsTopLevel -> methodDefnTotalSize @@ -2969,8 +3432,23 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = HasEffect=false MightMakeCriticalTailcall = false Info= valu } + | _ -> OptimizeExpr cenv env e +and OptimizeNewDelegateExpr cenv env (lambdaId, vsl, body, remake) = + let env = List.foldBack (BindInternalValsToUnknown cenv) vsl env + let bodyR, bodyinfo = OptimizeExpr cenv env body + let arities = vsl.Length + let bsize = bodyinfo.TotalSize + let exprR = remake bodyR + let valu = CurriedLambdaValue (lambdaId, arities, bsize, exprR, tyOfExpr cenv.g exprR) + + exprR, { TotalSize=bsize + closureTotalSize (* estimate size of new syntactic closure - expensive, in contrast to a method *) + FunctionSize=1 + HasEffect=false + MightMakeCriticalTailcall = false + Info= valu } + /// Recursive calls that first try to make an expression "fit" the a shape /// where it is about to be consumed. and OptimizeExprsThenReshapeAndConsiderSplits cenv env exprs = @@ -3006,11 +3484,9 @@ and OptimizeExprThenConsiderSplit cenv env e = /// Decide whether to List.unzip a sub-expression into a new method and ComputeSplitToMethodCondition flag threshold cenv env (e: Expr, einfo) = flag && - // REVIEW: The method splitting optimization is completely disabled if we are not taking tailcalls. - // REVIEW: This should only apply to methods that actually make self-tailcalls (tested further below). - // Old comment "don't mess with taking guaranteed tailcalls if used with --no-tailcalls!" + // NOTE: The method splitting optimization is completely disabled if we are not taking tailcalls. cenv.emitTailcalls && - not env.inLoop && + not env.disableMethodSplitting && einfo.FunctionSize >= threshold && // We can only split an expression out as a method if certain conditions are met. @@ -3035,7 +3511,7 @@ and ComputeSplitToMethodCondition flag threshold cenv env (e: Expr, einfo) = and ConsiderSplitToMethod flag threshold cenv env (e, einfo) = if ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) then - let m = (e.Range) + let m = e.Range let uv, _ue = mkCompGenLocal m "unitVar" cenv.g.unit_ty let ty = tyOfExpr cenv.g e let nm = @@ -3058,7 +3534,7 @@ and OptimizeMatch cenv env (spMatch, exprm, dtree, targets, m, ty) = and OptimizeMatchPart2 cenv (spMatch, exprm, dtreeR, targetsR, dinfo, tinfos, m, ty) = let newExpr, newInfo = RebuildOptimizedMatch (spMatch, exprm, m, ty, dtreeR, targetsR, dinfo, tinfos) - let newExpr2 = if not (cenv.settings.localOpt()) then newExpr else CombineBoolLogic newExpr + let newExpr2 = if not cenv.settings.LocalOptimizationsEnabled then newExpr else CombineBoolLogic newExpr newExpr2, newInfo and CombineMatchInfos dinfo tinfo = @@ -3075,12 +3551,12 @@ and RebuildOptimizedMatch (spMatch, exprm, m, ty, dtree, tgs, dinfo, tinfos) = expr, einfo /// Optimize/analyze a target of a decision tree -and OptimizeDecisionTreeTarget cenv env _m (TTarget(vs, expr, spTarget)) = +and OptimizeDecisionTreeTarget cenv env _m (TTarget(vs, expr, spTarget, flags)) = let env = BindInternalValsToUnknown cenv vs env let exprR, einfo = OptimizeExpr cenv env expr let exprR, einfo = ConsiderSplitToMethod cenv.settings.abstractBigTargets cenv.settings.bigTargetSize cenv env (exprR, einfo) let evalueR = AbstractExprInfoByVars (vs, []) einfo.Info - TTarget(vs, exprR, spTarget), + TTarget(vs, exprR, spTarget, flags), { TotalSize=einfo.TotalSize FunctionSize=einfo.FunctionSize HasEffect=einfo.HasEffect @@ -3111,7 +3587,7 @@ and OptimizeDecisionTree cenv env m x = else rest, rinfo - | TDSwitch (e, cases, dflt, m) -> + | TDSwitch (sp, e, cases, dflt, m) -> // We always duplicate boolean-typed guards prior to optimizing. This is work which really should be done in patcompile.fs // where we must duplicate "when" expressions to ensure uniqueness of bound variables. // @@ -3119,40 +3595,40 @@ and OptimizeDecisionTree cenv env m x = // Hence we do it here. There is no doubt a better way to do this. let e = if typeEquiv cenv.g (tyOfExpr cenv.g e) cenv.g.bool_ty then copyExpr cenv.g CloneAll e else e - OptimizeSwitch cenv env (e, cases, dflt, m) + OptimizeSwitch cenv env (sp, e, cases, dflt, m) and TryOptimizeDecisionTreeTest cenv test vinfo = match test, vinfo with | DecisionTreeTest.UnionCase (c1, _), StripUnionCaseValue(c2, _) -> Some(cenv.g.unionCaseRefEq c1 c2) - | DecisionTreeTest.ArrayLength (_, _), _ -> None + | DecisionTreeTest.ArrayLength _, _ -> None | DecisionTreeTest.Const c1, StripConstValue c2 -> if c1 = Const.Zero || c2 = Const.Zero then None else Some(c1=c2) | DecisionTreeTest.IsNull, StripConstValue c2 -> Some(c2=Const.Zero) | DecisionTreeTest.IsInst (_srcty1, _tgty1), _ -> None // These should not occur in optimization - | DecisionTreeTest.ActivePatternCase (_, _, _vrefOpt1, _, _), _ -> None + | DecisionTreeTest.ActivePatternCase _, _ -> None | _ -> None /// Optimize/analyze a switch construct from pattern matching -and OptimizeSwitch cenv env (e, cases, dflt, m) = +and OptimizeSwitch cenv env (sp, e, cases, dflt, m) = let eR, einfo = OptimizeExpr cenv env e let cases, dflt = - if cenv.settings.EliminateSwitch() && not einfo.HasEffect then + if cenv.settings.EliminateSwitch && not einfo.HasEffect then // Attempt to find a definite success, i.e. the first case where there is definite success - match (List.tryFind (function (TCase(d2, _)) when TryOptimizeDecisionTreeTest cenv d2 einfo.Info = Some true -> true | _ -> false) cases) with + match (List.tryFind (function TCase(d2, _) when TryOptimizeDecisionTreeTest cenv d2 einfo.Info = Some true -> true | _ -> false) cases) with | Some(TCase(_, case)) -> [], Some case | _ -> // Filter definite failures - cases |> List.filter (function (TCase(d2, _)) when TryOptimizeDecisionTreeTest cenv d2 einfo.Info = Some false -> false | _ -> true), + cases |> List.filter (function TCase(d2, _) when TryOptimizeDecisionTreeTest cenv d2 einfo.Info = Some false -> false | _ -> true), dflt else cases, dflt // OK, see what weRre left with and continue match cases, dflt with | [], Some case -> OptimizeDecisionTree cenv env m case - | _ -> OptimizeSwitchFallback cenv env (eR, einfo, cases, dflt, m) + | _ -> OptimizeSwitchFallback cenv env (sp, eR, einfo, cases, dflt, m) -and OptimizeSwitchFallback cenv env (eR, einfo, cases, dflt, m) = +and OptimizeSwitchFallback cenv env (sp, eR, einfo, cases, dflt, m) = let casesR, cinfos = cases |> List.map (fun (TCase(discrim, e)) -> let eR, einfo = OptimizeDecisionTree cenv env m e in TCase(discrim, eR), einfo) @@ -3164,7 +3640,7 @@ and OptimizeSwitchFallback cenv env (eR, einfo, cases, dflt, m) = let size = (dinfos.Length + cinfos.Length) * 2 let info = CombineValueInfosUnknown (einfo :: cinfos @ dinfos) let info = { info with TotalSize = info.TotalSize + size; FunctionSize = info.FunctionSize + size; } - TDSwitch (eR, casesR, dfltR, m), info + TDSwitch (sp, eR, casesR, dfltR, m), info and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = try @@ -3179,7 +3655,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = let exprOptimized, einfo = let env = if vref.IsCompilerGenerated && Option.isSome env.latestBoundId then env else {env with latestBoundId=Some vref.Id} - let cenv = if vref.InlineInfo = ValInline.PseudoVal then { cenv with optimizing=false} else cenv + let cenv = if vref.InlineInfo.MustInline then { cenv with optimizing=false} else cenv let arityInfo = InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.No vref expr let exprOptimized, einfo = OptimizeLambdas (Some vref) cenv env arityInfo expr vref.Type let size = localVarSize @@ -3208,10 +3684,10 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = | UnknownValue | ConstValue _ | ConstExprValue _ -> ivalue | SizeValue(_, a) -> MakeSizedValueInfo (cut a) - let einfo = if vref.MustInline then einfo else {einfo with Info = cut einfo.Info } + let einfo = if vref.MustInline || vref.InlineIfLambda then einfo else {einfo with Info = cut einfo.Info } let einfo = - if (not vref.MustInline && not (cenv.settings.KeepOptimizationValues())) || + if (not vref.MustInline && not vref.InlineIfLambda && not cenv.settings.KeepOptimizationValues) || // Bug 4916: do not record inline data for initialization trigger expressions // Note: we can't eliminate these value infos at the file boundaries because that would change initialization @@ -3228,7 +3704,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = // Check we can deref system_MarshalByRefObject_tcref. When compiling against the Silverlight mscorlib we can't if mbrTyconRef.TryDeref.IsSome then // Check if this is a subtype of MarshalByRefObject - assert (cenv.g.system_MarshalByRefObject_ty.IsSome) + assert cenv.g.system_MarshalByRefObject_ty.IsSome ExistsSameHeadTypeInHierarchy cenv.g cenv.amap vref.Range (generalizedTyconRef tcref) cenv.g.system_MarshalByRefObject_ty.Value else false @@ -3281,9 +3757,9 @@ and OptimizeModuleExpr cenv env x = // the application of the signature. If it contains extra elements we'll accidentally eliminate // bindings. - let (_renaming, hidden) as rpi = ComputeRemappingFromImplementationToSignature cenv.g def mty + let _renaming, hidden as rpi = ComputeRemappingFromImplementationToSignature cenv.g def mty let def = - if not (cenv.settings.localOpt()) then def else + if not cenv.settings.LocalOptimizationsEnabled then def else let fvs = freeInModuleOrNamespace CollectLocals def let dead = @@ -3311,7 +3787,7 @@ and OptimizeModuleExpr cenv env x = // probably more costly than copying specs anyway. let rec elimModTy (mtyp: ModuleOrNamespaceType) = let mty = - new ModuleOrNamespaceType(kind=mtyp.ModuleOrNamespaceKind, + ModuleOrNamespaceType(kind=mtyp.ModuleOrNamespaceKind, vals= (mtyp.AllValsAndMembers |> QueueList.filter (Zset.memberOf deadSet >> not)), entities= mtyp.AllEntities) mtyp.ModuleAndNamespaceDefinitions |> List.iter elimModSpec @@ -3323,11 +3799,12 @@ and OptimizeModuleExpr cenv env x = let rec elimModDef x = match x with - | TMDefRec(isRec, tycons, mbinds, m) -> + | TMDefRec(isRec, opens, tycons, mbinds, m) -> let mbinds = mbinds |> List.choose elimModuleBinding - TMDefRec(isRec, tycons, mbinds, m) + TMDefRec(isRec, opens, tycons, mbinds, m) | TMDefLet(bind, m) -> - if Zset.contains bind.Var deadSet then TMDefRec(false, [], [], m) else x + if Zset.contains bind.Var deadSet then TMDefRec(false, [], [], [], m) else x + | TMDefOpens _ -> x | TMDefDo _ -> x | TMDefs defs -> TMDefs(List.map elimModDef defs) | TMAbstract _ -> x @@ -3351,17 +3828,17 @@ and OptimizeModuleExpr cenv env x = and mkValBind (bind: Binding) info = (mkLocalValRef bind.Var, info) -and OptimizeModuleDef cenv (env, bindInfosColl) x = - match x with - | TMDefRec(isRec, tycons, mbinds, m) -> - let env = if isRec then BindInternalValsToUnknown cenv (allValsOfModDef x) env else env +and OptimizeModuleDef cenv (env, bindInfosColl) input = + match input with + | TMDefRec(isRec, opens, tycons, mbinds, m) -> + let env = if isRec then BindInternalValsToUnknown cenv (allValsOfModDef input) env else env let mbindInfos, (env, bindInfosColl) = OptimizeModuleBindings cenv (env, bindInfosColl) mbinds let mbinds, minfos = List.unzip mbindInfos let binds = minfos |> List.choose (function Choice1Of2 (x, _) -> Some x | _ -> None) let binfos = minfos |> List.choose (function Choice1Of2 (_, x) -> Some x | _ -> None) let minfos = minfos |> List.choose (function Choice2Of2 x -> Some x | _ -> None) - (TMDefRec(isRec, tycons, mbinds, m), + (TMDefRec(isRec, opens, tycons, mbinds, m), notlazy { ValInfos = ValInfos(List.map2 (fun bind binfo -> mkValBind bind (mkValInfo binfo bind.Var)) binds binfos) ModuleOrNamespaceInfos = NameMap.ofList minfos}), (env, bindInfosColl) @@ -3371,15 +3848,18 @@ and OptimizeModuleDef cenv (env, bindInfosColl) x = let env = BindValsInModuleOrNamespace cenv info env (TMAbstract mexpr, info), (env, bindInfosColl) + | TMDefOpens _openDecls -> + (input, EmptyModuleInfo), (env, bindInfosColl) + | TMDefLet(bind, m) -> - let ((bindR, binfo) as bindInfo), env = OptimizeBinding cenv false env bind + let bindR, binfo as bindInfo, env = OptimizeBinding cenv false env bind (TMDefLet(bindR, m), notlazy { ValInfos=ValInfos [mkValBind bind (mkValInfo binfo bind.Var)] ModuleOrNamespaceInfos = NameMap.empty }), (env, ([bindInfo] :: bindInfosColl)) | TMDefDo(e, m) -> - let (e, _einfo) = OptimizeExpr cenv env e + let e, _einfo = OptimizeExpr cenv env e (TMDefDo(e, m), EmptyModuleInfo), (env, bindInfosColl) @@ -3392,7 +3872,7 @@ and OptimizeModuleBindings cenv (env, bindInfosColl) xs = List.mapFold (Optimize and OptimizeModuleBinding cenv (env, bindInfosColl) x = match x with | ModuleOrNamespaceBinding.Binding bind -> - let ((bindR, binfo) as bindInfo), env = OptimizeBinding cenv true env bind + let bindR, binfo as bindInfo, env = OptimizeBinding cenv true env bind (ModuleOrNamespaceBinding.Binding bindR, Choice1Of2 (bindR, binfo)), (env, [ bindInfo ] :: bindInfosColl) | ModuleOrNamespaceBinding.Module(mspec, def) -> let id = mspec.Id @@ -3438,9 +3918,15 @@ let OptimizeImplFile (settings, ccu, tcGlobals, tcVal, importMap, optEnv, isIncr optimizing=true localInternalVals=Dictionary(10000) emitTailcalls=emitTailcalls - casApplied=new Dictionary() } - let (optEnvNew, _, _, _ as results) = OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls - let optimizeDuringCodeGen expr = OptimizeExpr cenv optEnvNew expr |> fst + casApplied=Dictionary() + } + + let env, _, _, _ as results = OptimizeImplFileInternal cenv optEnv isIncrementalFragment hidden mimpls + + let optimizeDuringCodeGen disableMethodSplitting expr = + let env = { env with disableMethodSplitting = env.disableMethodSplitting || disableMethodSplitting } + OptimizeExpr cenv env expr |> fst + results, optimizeDuringCodeGen @@ -3500,7 +3986,8 @@ let rec u_ExprInfo st = | 6 -> u_tup2 u_int u_expr st |> (fun (a, b) -> ConstExprValue (a, b)) | 7 -> u_tup2 u_tcref (u_array loop) st |> (fun (a, b) -> RecdValue (a, b)) | _ -> failwith "loop" - MakeSizedValueInfo (loop st) (* calc size of unpicked ExprValueInfo *) + // calc size of unpicked ExprValueInfo + MakeSizedValueInfo (loop st) and u_ValInfo st = let a, b = u_tup2 u_ExprInfo u_bool st diff --git a/src/fsharp/Optimizer.fsi b/src/fsharp/Optimizer.fsi index bd656614bf4..2f58475338a 100644 --- a/src/fsharp/Optimizer.fsi +++ b/src/fsharp/Optimizer.fsi @@ -3,57 +3,95 @@ module internal FSharp.Compiler.Optimizer open FSharp.Compiler -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreePickle type OptimizationSettings = - { abstractBigTargets : bool + { + abstractBigTargets : bool + jitOptUser : bool option + localOptUser : bool option - crossModuleOptUser : bool option - bigTargetSize : int + + debugPointsForPipeRight: bool option + + crossAssemblyOptimizationUser : bool option + + /// size after which we start chopping methods in two, though only at match targets + bigTargetSize : int + + /// size after which we start enforcing splitting sub-expressions to new methods, to avoid hitting .NET IL limitations veryBigExprSize : int - lambdaInlineThreshold : int - reportingPhase : bool; + + /// The size after which we don't inline + lambdaInlineThreshold : int + + /// For unit testing + reportingPhase : bool + reportNoNeedToTailcall: bool - reportFunctionSizes : bool - reportHasEffect : bool - reportTotalSizes : bool } + + reportFunctionSizes : bool + + reportHasEffect : bool + + reportTotalSizes : bool + } - member jitOpt : unit -> bool - member localOpt : unit -> bool - static member Defaults : OptimizationSettings + + member JitOptimizationsEnabled: bool + + member LocalOptimizationsEnabled: bool + + static member Defaults: OptimizationSettings /// Optimization information type ModuleInfo + type LazyModuleInfo = Lazy + type ImplFileOptimizationInfo = LazyModuleInfo + type CcuOptimizationInfo = LazyModuleInfo [] type IncrementalOptimizationEnv = - static member Empty : IncrementalOptimizationEnv + static member Empty: IncrementalOptimizationEnv /// For building optimization environments incrementally -val internal BindCcu : CcuThunk -> CcuOptimizationInfo -> IncrementalOptimizationEnv -> TcGlobals -> IncrementalOptimizationEnv +val internal BindCcu: CcuThunk -> CcuOptimizationInfo -> IncrementalOptimizationEnv -> TcGlobals -> IncrementalOptimizationEnv /// Optimize one implementation file in the given environment -val internal OptimizeImplFile : OptimizationSettings * CcuThunk * TcGlobals * ConstraintSolver.TcValF * Import.ImportMap * IncrementalOptimizationEnv * isIncrementalFragment: bool * emitTaicalls: bool * SignatureHidingInfo * TypedImplFile -> (IncrementalOptimizationEnv * TypedImplFile * ImplFileOptimizationInfo * SignatureHidingInfo) * (Expr -> Expr) +val internal OptimizeImplFile: + OptimizationSettings * + CcuThunk * + TcGlobals * + ConstraintSolver.TcValF * + Import.ImportMap * + IncrementalOptimizationEnv * + isIncrementalFragment: bool * + emitTailcalls: bool * + SignatureHidingInfo * + TypedImplFile + -> (IncrementalOptimizationEnv * TypedImplFile * ImplFileOptimizationInfo * SignatureHidingInfo) * (bool -> Expr -> Expr) #if DEBUG /// Displaying optimization data -val internal moduleInfoL : TcGlobals -> LazyModuleInfo -> Layout.layout +val internal moduleInfoL: TcGlobals -> LazyModuleInfo -> Layout #endif /// Saving and re-reading optimization information -val p_CcuOptimizationInfo : CcuOptimizationInfo -> TastPickle.WriterState -> unit +val p_CcuOptimizationInfo: CcuOptimizationInfo -> WriterState -> unit /// Rewrite the module info using the export remapping -val RemapOptimizationInfo : TcGlobals -> Tastops.Remap -> (CcuOptimizationInfo -> CcuOptimizationInfo) +val RemapOptimizationInfo: TcGlobals -> Remap -> (CcuOptimizationInfo -> CcuOptimizationInfo) /// Ensure that 'internal' items are not exported in the optimization info -val AbstractOptimizationInfoToEssentials : (CcuOptimizationInfo -> CcuOptimizationInfo) +val AbstractOptimizationInfoToEssentials: (CcuOptimizationInfo -> CcuOptimizationInfo) /// Combine optimization infos val UnionOptimizationInfos: seq -> CcuOptimizationInfo @@ -61,4 +99,8 @@ val UnionOptimizationInfos: seq -> CcuOptimizationInfo /// Check if an expression has an effect val ExprHasEffect: TcGlobals -> Expr -> bool -val internal u_CcuOptimizationInfo : TastPickle.ReaderState -> CcuOptimizationInfo \ No newline at end of file +val internal u_CcuOptimizationInfo: ReaderState -> CcuOptimizationInfo + +/// Indicates the value is only mutable during its initialization and before any access or capture +val IsKnownOnlyMutableBeforeUse: ValRef -> bool + diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs new file mode 100644 index 00000000000..7d9a952b39f --- /dev/null +++ b/src/fsharp/ParseAndCheckInputs.fs @@ -0,0 +1,959 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to coordinate the parsing and checking of one or a group of files +module internal FSharp.Compiler.ParseAndCheckInputs + +open System +open System.IO + +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Text.Lexing + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.IO +open FSharp.Compiler.Lexhelp +open FSharp.Compiler.NameResolution +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals + +let CanonicalizeFilename filename = + let basic = FileSystemUtils.fileNameOfPath filename + String.capitalize (try FileSystemUtils.chopExtension basic with _ -> basic) + +let IsScript filename = + let lower = String.lowercase filename + FSharpScriptFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) + +// Give a unique name to the different kinds of inputs. Used to correlate signature and implementation files +// QualFileNameOfModuleName - files with a single module declaration or an anonymous module +let QualFileNameOfModuleName m filename modname = + QualifiedNameOfFile(mkSynId m (textOfLid modname + (if IsScript filename then "$fsx" else ""))) + +let QualFileNameOfFilename m filename = + QualifiedNameOfFile(mkSynId m (CanonicalizeFilename filename + (if IsScript filename then "$fsx" else ""))) + +// Interactive fragments +let ComputeQualifiedNameOfFileFromUniquePath (m, p: string list) = + QualifiedNameOfFile(mkSynId m (String.concat "_" p)) + +let QualFileNameOfSpecs filename specs = + match specs with + | [SynModuleOrNamespaceSig(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname + | [SynModuleOrNamespaceSig(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename + | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename + +let QualFileNameOfImpls filename specs = + match specs with + | [SynModuleOrNamespace(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname + | [SynModuleOrNamespace(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename + | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename + +let PrependPathToQualFileName x (QualifiedNameOfFile q) = + ComputeQualifiedNameOfFileFromUniquePath (q.idRange, pathOfLid x@[q.idText]) + +let PrependPathToImpl x (SynModuleOrNamespace(p, b, c, d, e, f, g, h)) = + SynModuleOrNamespace(x@p, b, c, d, e, f, g, h) + +let PrependPathToSpec x (SynModuleOrNamespaceSig(p, b, c, d, e, f, g, h)) = + SynModuleOrNamespaceSig(x@p, b, c, d, e, f, g, h) + +let PrependPathToInput x inp = + match inp with + | ParsedInput.ImplFile (ParsedImplFileInput (b, c, q, d, hd, impls, e)) -> + ParsedInput.ImplFile (ParsedImplFileInput (b, c, PrependPathToQualFileName x q, d, hd, List.map (PrependPathToImpl x) impls, e)) + + | ParsedInput.SigFile (ParsedSigFileInput (b, q, d, hd, specs)) -> + ParsedInput.SigFile (ParsedSigFileInput (b, PrependPathToQualFileName x q, d, hd, List.map (PrependPathToSpec x) specs)) + +let ComputeAnonModuleName check defaultNamespace filename (m: range) = + let modname = CanonicalizeFilename filename + if check && not (modname |> String.forall (fun c -> Char.IsLetterOrDigit c || c = '_')) then + if not (filename.EndsWith("fsx", StringComparison.OrdinalIgnoreCase) || filename.EndsWith("fsscript", StringComparison.OrdinalIgnoreCase)) then + warning(Error(FSComp.SR.buildImplicitModuleIsNotLegalIdentifier(modname, (FileSystemUtils.fileNameOfPath filename)), m)) + let combined = + match defaultNamespace with + | None -> modname + | Some ns -> textOfPath [ns;modname] + + let anonymousModuleNameRange = + let filename = m.FileName + mkRange filename pos0 pos0 + pathToSynLid anonymousModuleNameRange (splitNamespace combined) + +let PostParseModuleImpl (_i, defaultNamespace, isLastCompiland, filename, impl) = + match impl with + | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> + let lid = + match lid with + | [id] when kind.IsModule && id.idText = MangledGlobalName -> + error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) + | id :: rest when id.idText = MangledGlobalName -> rest + | _ -> lid + SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m) + + | ParsedImplFileFragment.AnonModule (defs, m)-> + let isLast, isExe = isLastCompiland + let lower = String.lowercase filename + if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)) then + match defs with + | SynModuleDecl.NestedModule _ :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), trimRangeToLine m)) + | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), trimRangeToLine m)) + + let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) + SynModuleOrNamespace(modname, false, SynModuleOrNamespaceKind.AnonModule, defs, PreXmlDoc.Empty, [], None, m) + + | ParsedImplFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> + let lid, kind = + match lid with + | id :: rest when id.idText = MangledGlobalName -> + rest, if List.isEmpty rest then SynModuleOrNamespaceKind.GlobalNamespace else kind + | _ -> lid, kind + SynModuleOrNamespace(lid, a, kind, c, d, e, None, m) + +let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, filename, intf) = + match intf with + | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> + let lid = + match lid with + | [id] when kind.IsModule && id.idText = MangledGlobalName -> + error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) + | id :: rest when id.idText = MangledGlobalName -> rest + | _ -> lid + SynModuleOrNamespaceSig(lid, isRec, SynModuleOrNamespaceKind.NamedModule, decls, xmlDoc, attribs, access, m) + + | ParsedSigFileFragment.AnonModule (defs, m) -> + let isLast, isExe = isLastCompiland + let lower = String.lowercase filename + if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)) then + match defs with + | SynModuleSigDecl.NestedModule _ :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), m)) + | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), m)) + + let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) + SynModuleOrNamespaceSig(modname, false, SynModuleOrNamespaceKind.AnonModule, defs, PreXmlDoc.Empty, [], None, m) + + | ParsedSigFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> + let lid, kind = + match lid with + | id :: rest when id.idText = MangledGlobalName -> + rest, if List.isEmpty rest then SynModuleOrNamespaceKind.GlobalNamespace else kind + | _ -> lid, kind + SynModuleOrNamespaceSig(lid, a, kind, c, d, e, None, m) + +let GetScopedPragmasForInput input = + match input with + | ParsedInput.SigFile (ParsedSigFileInput (scopedPragmas=pragmas)) -> pragmas + | ParsedInput.ImplFile (ParsedImplFileInput (scopedPragmas=pragmas)) -> pragmas + +let GetScopedPragmasForHashDirective hd = + [ match hd with + | ParsedHashDirective("nowarn", numbers, m) -> + for s in numbers do + match s with + | ParsedHashDirectiveArgument.SourceIdentifier _ -> () + | ParsedHashDirectiveArgument.String (s, _, _) -> + match GetWarningNumber(m, s) with + | None -> () + | Some n -> yield ScopedPragma.WarningOff(m, n) + | _ -> () ] + +let PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, ParsedImplFile (hashDirectives, impls)) = + match impls |> List.rev |> List.tryPick (function ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, _, _, _, _, _, _, _)) -> Some lid | _ -> None) with + | Some lid when impls.Length > 1 -> + errorR(Error(FSComp.SR.buildMultipleToplevelModules(), rangeOfLid lid)) + | _ -> + () + let impls = impls |> List.mapi (fun i x -> PostParseModuleImpl (i, defaultNamespace, isLastCompiland, filename, x)) + let qualName = QualFileNameOfImpls filename impls + let isScript = IsScript filename + + let scopedPragmas = + [ for SynModuleOrNamespace(_, _, _, decls, _, _, _, _) in impls do + for d in decls do + match d with + | SynModuleDecl.HashDirective (hd, _) -> yield! GetScopedPragmasForHashDirective hd + | _ -> () + for hd in hashDirectives do + yield! GetScopedPragmasForHashDirective hd ] + + ParsedInput.ImplFile (ParsedImplFileInput (filename, isScript, qualName, scopedPragmas, hashDirectives, impls, isLastCompiland)) + +let PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, ParsedSigFile (hashDirectives, specs)) = + match specs |> List.rev |> List.tryPick (function ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, _, _, _, _, _, _, _)) -> Some lid | _ -> None) with + | Some lid when specs.Length > 1 -> + errorR(Error(FSComp.SR.buildMultipleToplevelModules(), rangeOfLid lid)) + | _ -> + () + + let specs = specs |> List.mapi (fun i x -> PostParseModuleSpec(i, defaultNamespace, isLastCompiland, filename, x)) + let qualName = QualFileNameOfSpecs filename specs + let scopedPragmas = + [ for SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _) in specs do + for d in decls do + match d with + | SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd + | _ -> () + for hd in hashDirectives do + yield! GetScopedPragmasForHashDirective hd ] + + ParsedInput.SigFile (ParsedSigFileInput (filename, qualName, scopedPragmas, hashDirectives, specs)) + +type ModuleNamesDict = Map> + +/// Checks if a module name is already given and deduplicates the name if needed. +let DeduplicateModuleName (moduleNamesDict: ModuleNamesDict) fileName (qualNameOfFile: QualifiedNameOfFile) = + let path = Path.GetDirectoryName fileName + let path = if FileSystem.IsPathRootedShim path then try FileSystem.GetFullPathShim path with _ -> path else path + match moduleNamesDict.TryGetValue qualNameOfFile.Text with + | true, paths -> + if paths.ContainsKey path then + paths.[path], moduleNamesDict + else + let count = paths.Count + 1 + let id = qualNameOfFile.Id + let qualNameOfFileT = if count = 1 then qualNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange)) + let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, paths.Add(path, qualNameOfFileT)) + qualNameOfFileT, moduleNamesDictT + | _ -> + let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, Map.empty.Add(path, qualNameOfFile)) + qualNameOfFile, moduleNamesDictT + +/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. +let DeduplicateParsedInputModuleName (moduleNamesDict: ModuleNamesDict) input = + match input with + | ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput (fileName, isScript, qualNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) -> + let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile + let inputT = ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput (fileName, isScript, qualNameOfFileT, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) + inputT, moduleNamesDictT + | ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput (fileName, qualNameOfFile, scopedPragmas, hashDirectives, modules)) -> + let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile + let inputT = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput (fileName, qualNameOfFileT, scopedPragmas, hashDirectives, modules)) + inputT, moduleNamesDictT + +let ParseInput (lexer, errorLogger: ErrorLogger, lexbuf: UnicodeLexing.Lexbuf, defaultNamespace, filename, isLastCompiland) = + // The assert below is almost ok, but it fires in two cases: + // - fsi.exe sometimes passes "stdin" as a dummy filename + // - if you have a #line directive, e.g. + // # 1000 "Line01.fs" + // then it also asserts. But these are edge cases that can be fixed later, e.g. in bug 4651. + //System.Diagnostics.Debug.Assert(System.IO.Path.IsPathRooted filename, sprintf "should be absolute: '%s'" filename) + let lower = String.lowercase filename + + // Delay sending errors and warnings until after the file is parsed. This gives us a chance to scrape the + // #nowarn declarations for the file + let delayLogger = CapturingErrorLogger("Parsing") + use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayLogger) + use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + + let mutable scopedPragmas = [] + try + let input = + if mlCompatSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + errorR(Error(FSComp.SR.buildInvalidSourceFileExtensionML filename, rangeStartup)) + else + mlCompatWarning (FSComp.SR.buildCompilingExtensionIsForML()) rangeStartup + + // Call the appropriate parser - for signature files or implementation files + if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + let impl = Parser.implementationFile lexer lexbuf + PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, impl) + elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + let intfs = Parser.signatureFile lexer lexbuf + PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, intfs) + else + if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + error(Error(FSComp.SR.buildInvalidSourceFileExtensionUpdated filename, rangeStartup)) + else + error(Error(FSComp.SR.buildInvalidSourceFileExtension filename, rangeStartup)) + + + scopedPragmas <- GetScopedPragmasForInput input + input + finally + // OK, now commit the errors, since the ScopedPragmas will (hopefully) have been scraped + let filteringErrorLogger = GetErrorLoggerFilteringByScopedPragmas(false, scopedPragmas, errorLogger) + delayLogger.CommitDelayedDiagnostics filteringErrorLogger + +type Tokenizer = unit -> Parser.token + +// Show all tokens in the stream, for testing purposes +let ShowAllTokensAndExit (shortFilename, tokenizer: Tokenizer, lexbuf: LexBuffer) = + while true do + printf "tokenize - getting one token from %s\n" shortFilename + let t = tokenizer () + printf "tokenize - got %s @ %a\n" (Parser.token_to_string t) outputRange lexbuf.LexemeRange + match t with + | Parser.EOF _ -> exit 0 + | _ -> () + if lexbuf.IsPastEndOfStream then printf "!!! at end of stream\n" + +// Test one of the parser entry points, just for testing purposes +let TestInteractionParserAndExit (tokenizer: Tokenizer, lexbuf: LexBuffer) = + while true do + match (Parser.interaction (fun _ -> tokenizer ()) lexbuf) with + | ParsedScriptInteraction.Definitions(l, m) -> printfn "Parsed OK, got %d defs @ %a" l.Length outputRange m + | ParsedScriptInteraction.HashDirective(_, m) -> printfn "Parsed OK, got hash @ %a" outputRange m + exit 0 + +// Report the statistics for testing purposes +let ReportParsingStatistics res = + let rec flattenSpecs specs = + specs |> List.collect (function SynModuleSigDecl.NestedModule (_, _, subDecls, _) -> flattenSpecs subDecls | spec -> [spec]) + let rec flattenDefns specs = + specs |> List.collect (function SynModuleDecl.NestedModule (_, _, subDecls, _, _) -> flattenDefns subDecls | defn -> [defn]) + + let flattenModSpec (SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _)) = flattenSpecs decls + let flattenModImpl (SynModuleOrNamespace(_, _, _, decls, _, _, _, _)) = flattenDefns decls + match res with + | ParsedInput.SigFile (ParsedSigFileInput (_, _, _, _, specs)) -> + printfn "parsing yielded %d specs" (List.collect flattenModSpec specs).Length + | ParsedInput.ImplFile (ParsedImplFileInput (modules = impls)) -> + printfn "parsing yielded %d definitions" (List.collect flattenModImpl impls).Length + +let EmptyParsedInput(filename, isLastCompiland) = + let lower = String.lowercase filename + if FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + ParsedInput.SigFile( + ParsedSigFileInput( + filename, + QualFileNameOfImpls filename [], + [], + [], + [] + ) + ) + else + ParsedInput.ImplFile( + ParsedImplFileInput( + filename, + false, + QualFileNameOfImpls filename [], + [], + [], + [], + isLastCompiland + ) + ) + +/// Parse an input, drawing tokens from the LexBuffer +let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) = + use unwindbuildphase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + try + + // Don't report whitespace from lexer + let skipWhitespaceTokens = true + + // Set up the initial status for indentation-aware processing + let lightStatus = LightSyntaxStatus (tcConfig.ComputeLightSyntaxInitialStatus filename, true) + + // Set up the initial lexer arguments + let lexargs = mkLexargs (conditionalCompilationDefines@tcConfig.conditionalCompilationDefines, lightStatus, lexResourceManager, [], errorLogger, tcConfig.pathMap) + + // Set up the initial lexer arguments + let shortFilename = SanitizeFileName filename tcConfig.implicitIncludeDir + + let input = + usingLexbufForParsing (lexbuf, filename) (fun lexbuf -> + + // Set up the LexFilter over the token stream + let tokenizer,tokenizeOnly = + match tcConfig.tokenize with + | Unfiltered -> (fun () -> Lexer.token lexargs skipWhitespaceTokens lexbuf), true + | Only -> LexFilter.LexFilter(lightStatus, tcConfig.compilingFslib, Lexer.token lexargs skipWhitespaceTokens, lexbuf).GetToken, true + | _ -> LexFilter.LexFilter(lightStatus, tcConfig.compilingFslib, Lexer.token lexargs skipWhitespaceTokens, lexbuf).GetToken, false + + // If '--tokenize' then show the tokens now and exit + if tokenizeOnly then + ShowAllTokensAndExit(shortFilename, tokenizer, lexbuf) + + // Test hook for one of the parser entry points + if tcConfig.testInteractionParser then + TestInteractionParserAndExit (tokenizer, lexbuf) + + // Parse the input + let res = ParseInput((fun _ -> tokenizer ()), errorLogger, lexbuf, None, filename, isLastCompiland) + + // Report the statistics for testing purposes + if tcConfig.reportNumDecls then + ReportParsingStatistics res + + res + ) + input + + with e -> + errorRecovery e rangeStartup + EmptyParsedInput(filename, isLastCompiland) + +let ValidSuffixes = FSharpSigFileSuffixes@FSharpImplFileSuffixes + +let checkInputFile (tcConfig: TcConfig) filename = + let lower = String.lowercase filename + + if List.exists (FileSystemUtils.checkSuffix lower) ValidSuffixes then + if not(FileSystem.FileExistsShim filename) then + error(Error(FSComp.SR.buildCouldNotFindSourceFile filename, rangeStartup)) + else + error(Error(FSComp.SR.buildInvalidSourceFileExtension(SanitizeFileName filename tcConfig.implicitIncludeDir), rangeStartup)) + +let parseInputFileAux (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) = + // Get a stream reader for the file + use fileStream = FileSystem.OpenFileForReadShim(filename) + use reader = fileStream.GetReader(tcConfig.inputCodePage, retryLocked) + + // Set up the LexBuffer for the file + let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(not tcConfig.compilingFslib, tcConfig.langVersion, reader) + + // Parse the file drawing tokens from the lexbuf + ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger) + +/// Parse an input from disk +let ParseOneInputFile (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) = + try + checkInputFile tcConfig filename + parseInputFileAux(tcConfig, lexResourceManager, conditionalCompilationDefines, filename, isLastCompiland, errorLogger, retryLocked) + with e -> + errorRecovery e rangeStartup + EmptyParsedInput(filename, isLastCompiland) + +/// Parse multiple input files from disk +let ParseInputFiles (tcConfig: TcConfig, lexResourceManager, conditionalCompilationDefines, sourceFiles, errorLogger: ErrorLogger, exiter: Exiter, createErrorLogger: Exiter -> CapturingErrorLogger, retryLocked) = + try + let isLastCompiland, isExe = sourceFiles |> tcConfig.ComputeCanContainEntryPoint + let sourceFiles = isLastCompiland |> List.zip sourceFiles |> Array.ofList + + if tcConfig.concurrentBuild then + let mutable exitCode = 0 + let delayedExiter = + { new Exiter with + member this.Exit n = exitCode <- n; raise StopProcessing } + + // Check input files and create delayed error loggers before we try to parallel parse. + let delayedErrorLoggers = + sourceFiles + |> Array.map (fun (filename, _) -> + checkInputFile tcConfig filename + createErrorLogger(delayedExiter) + ) + + let results = + try + try + sourceFiles + |> ArrayParallel.mapi (fun i (filename, isLastCompiland) -> + let delayedErrorLogger = delayedErrorLoggers.[i] + + let directoryName = Path.GetDirectoryName filename + let input = parseInputFileAux(tcConfig, lexResourceManager, conditionalCompilationDefines, filename, (isLastCompiland, isExe), delayedErrorLogger, retryLocked) + (input, directoryName) + ) + finally + delayedErrorLoggers + |> Array.iter (fun delayedErrorLogger -> + delayedErrorLogger.CommitDelayedDiagnostics errorLogger + ) + with + | StopProcessing -> + exiter.Exit exitCode + + results + |> List.ofArray + else + sourceFiles + |> Array.map (fun (filename, isLastCompiland) -> + let directoryName = Path.GetDirectoryName filename + let input = ParseOneInputFile(tcConfig, lexResourceManager, conditionalCompilationDefines, filename, (isLastCompiland, isExe), errorLogger, retryLocked) + (input, directoryName)) + |> List.ofArray + + with e -> + errorRecoveryNoRange e + exiter.Exit 1 + +let ProcessMetaCommandsFromInput + (nowarnF: 'state -> range * string -> 'state, + hashReferenceF: 'state -> range * string * Directive -> 'state, + loadSourceF: 'state -> range * string -> unit) + (tcConfig:TcConfigBuilder, + inp: ParsedInput, + pathOfMetaCommandSource, + state0) = + + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + + let canHaveScriptMetaCommands = + match inp with + | ParsedInput.SigFile _ -> false + | ParsedInput.ImplFile (ParsedImplFileInput (isScript = isScript)) -> isScript + + let ProcessDependencyManagerDirective directive args m state = + if not canHaveScriptMetaCommands then + errorR(HashReferenceNotAllowedInNonScript m) + + match args with + | [path] -> + let p = + if String.IsNullOrWhiteSpace(path) then "" + else path + + hashReferenceF state (m, p, directive) + + | _ -> + errorR(Error(FSComp.SR.buildInvalidHashrDirective(), m)) + state + + let ProcessMetaCommand state hash = + let mutable matchedm = range0 + try + match hash with + | ParsedHashDirective("I", ParsedHashDirectiveArguments args, m) -> + if not canHaveScriptMetaCommands then + errorR(HashIncludeNotAllowedInNonScript m) + match args with + | [path] -> + matchedm <- m + tcConfig.AddIncludePath(m, path, pathOfMetaCommandSource) + state + | _ -> + errorR(Error(FSComp.SR.buildInvalidHashIDirective(), m)) + state + | ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers,m) -> + List.fold (fun state d -> nowarnF state (m,d)) state numbers + + | ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments args, m) -> + matchedm<-m + ProcessDependencyManagerDirective Directive.Resolution args m state + + | ParsedHashDirective("i", ParsedHashDirectiveArguments args, m) -> + matchedm<-m + ProcessDependencyManagerDirective Directive.Include args m state + + | ParsedHashDirective("load", ParsedHashDirectiveArguments args, m) -> + if not canHaveScriptMetaCommands then + errorR(HashDirectiveNotAllowedInNonScript m) + match args with + | _ :: _ -> + matchedm<-m + args |> List.iter (fun path -> loadSourceF state (m, path)) + | _ -> + errorR(Error(FSComp.SR.buildInvalidHashloadDirective(), m)) + state + | ParsedHashDirective("time", ParsedHashDirectiveArguments args, m) -> + if not canHaveScriptMetaCommands then + errorR(HashDirectiveNotAllowedInNonScript m) + match args with + | [] -> + () + | ["on" | "off"] -> + () + | _ -> + errorR(Error(FSComp.SR.buildInvalidHashtimeDirective(), m)) + state + + | _ -> + + (* warning(Error("This meta-command has been ignored", m)) *) + state + with e -> errorRecovery e matchedm; state + + let rec WarnOnIgnoredSpecDecls decls = + decls |> List.iter (fun d -> + match d with + | SynModuleSigDecl.HashDirective (_, m) -> warning(Error(FSComp.SR.buildDirectivesInModulesAreIgnored(), m)) + | SynModuleSigDecl.NestedModule (_, _, subDecls, _) -> WarnOnIgnoredSpecDecls subDecls + | _ -> ()) + + let rec WarnOnIgnoredImplDecls decls = + decls |> List.iter (fun d -> + match d with + | SynModuleDecl.HashDirective (_, m) -> warning(Error(FSComp.SR.buildDirectivesInModulesAreIgnored(), m)) + | SynModuleDecl.NestedModule (_, _, subDecls, _, _) -> WarnOnIgnoredImplDecls subDecls + | _ -> ()) + + let ProcessMetaCommandsFromModuleSpec state (SynModuleOrNamespaceSig(_, _, _, decls, _, _, _, _)) = + List.fold (fun s d -> + match d with + | SynModuleSigDecl.HashDirective (h, _) -> ProcessMetaCommand s h + | SynModuleSigDecl.NestedModule (_, _, subDecls, _) -> WarnOnIgnoredSpecDecls subDecls; s + | _ -> s) + state + decls + + let ProcessMetaCommandsFromModuleImpl state (SynModuleOrNamespace(_, _, _, decls, _, _, _, _)) = + List.fold (fun s d -> + match d with + | SynModuleDecl.HashDirective (h, _) -> ProcessMetaCommand s h + | SynModuleDecl.NestedModule (_, _, subDecls, _, _) -> WarnOnIgnoredImplDecls subDecls; s + | _ -> s) + state + decls + + match inp with + | ParsedInput.SigFile (ParsedSigFileInput (_, _, _, hashDirectives, specs)) -> + let state = List.fold ProcessMetaCommand state0 hashDirectives + let state = List.fold ProcessMetaCommandsFromModuleSpec state specs + state + | ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, hashDirectives, impls, _)) -> + let state = List.fold ProcessMetaCommand state0 hashDirectives + let state = List.fold ProcessMetaCommandsFromModuleImpl state impls + state + +let ApplyNoWarnsToTcConfig (tcConfig: TcConfig, inp: ParsedInput, pathOfMetaCommandSource) = + // Clone + let tcConfigB = tcConfig.CloneToBuilder() + let addNoWarn = fun () (m,s) -> tcConfigB.TurnWarningOff(m, s) + let addReference = fun () (_m, _s, _) -> () + let addLoadedSource = fun () (_m, _s) -> () + ProcessMetaCommandsFromInput + (addNoWarn, addReference, addLoadedSource) + (tcConfigB, inp, pathOfMetaCommandSource, ()) + TcConfig.Create(tcConfigB, validate=false) + +let ApplyMetaCommandsFromInputToTcConfig (tcConfig: TcConfig, inp: ParsedInput, pathOfMetaCommandSource, dependencyProvider) = + // Clone + let tcConfigB = tcConfig.CloneToBuilder() + let getWarningNumber = fun () _ -> () + let addReferenceDirective = fun () (m, path, directive) -> tcConfigB.AddReferenceDirective(dependencyProvider, m, path, directive) + let addLoadedSource = fun () (m,s) -> tcConfigB.AddLoadedSource(m,s,pathOfMetaCommandSource) + ProcessMetaCommandsFromInput + (getWarningNumber, addReferenceDirective, addLoadedSource) + (tcConfigB, inp, pathOfMetaCommandSource, ()) + TcConfig.Create(tcConfigB, validate=false) + +/// Build the initial type checking environment +let GetInitialTcEnv (assemblyName: string, initm: range, tcConfig: TcConfig, tcImports: TcImports, tcGlobals) = + let initm = initm.StartRange + + let ccus = + tcImports.GetImportedAssemblies() + |> List.map (fun asm -> asm.FSharpViewOfMetadata, asm.AssemblyAutoOpenAttributes, asm.AssemblyInternalsVisibleToAttributes) + + let amap = tcImports.GetImportMap() + + let openDecls0, tcEnv = CreateInitialTcEnv(tcGlobals, amap, initm, assemblyName, ccus) + + if tcConfig.checkOverflow then + try + let checkOperatorsModule = pathToSynLid initm (splitNamespace CoreOperatorsCheckedName) + let tcEnv, openDecls1 = TcOpenModuleOrNamespaceDecl TcResultsSink.NoSink tcGlobals amap initm tcEnv (checkOperatorsModule, initm) + tcEnv, openDecls0 @ openDecls1 + with e -> + errorRecovery e initm + tcEnv, openDecls0 + else + tcEnv, openDecls0 + +/// Inject faults into checking +let CheckSimulateException(tcConfig: TcConfig) = + match tcConfig.simulateException with + | Some("tc-oom") -> raise(OutOfMemoryException()) + | Some("tc-an") -> raise(ArgumentNullException("simulated")) + | Some("tc-invop") -> raise(InvalidOperationException()) + | Some("tc-av") -> raise(AccessViolationException()) + | Some("tc-nfn") -> raise(NotFiniteNumberException()) + | Some("tc-aor") -> raise(ArgumentOutOfRangeException()) + | Some("tc-dv0") -> raise(DivideByZeroException()) + | Some("tc-oe") -> raise(OverflowException()) + | Some("tc-atmm") -> raise(ArrayTypeMismatchException()) + | Some("tc-bif") -> raise(BadImageFormatException()) + | Some("tc-knf") -> raise(System.Collections.Generic.KeyNotFoundException()) + | Some("tc-ior") -> raise(IndexOutOfRangeException()) + | Some("tc-ic") -> raise(InvalidCastException()) + | Some("tc-ip") -> raise(InvalidProgramException()) + | Some("tc-ma") -> raise(MemberAccessException()) + | Some("tc-ni") -> raise(NotImplementedException()) + | Some("tc-nr") -> raise(NullReferenceException()) + | Some("tc-oc") -> raise(OperationCanceledException()) + | Some("tc-fail") -> failwith "simulated" + | _ -> () + +//---------------------------------------------------------------------------- +// Type-check sets of files +//-------------------------------------------------------------------------- + +type RootSigs = Zmap + +type RootImpls = Zset + +let qnameOrder = Order.orderBy (fun (q: QualifiedNameOfFile) -> q.Text) + +type TcState = + { + tcsCcu: CcuThunk + tcsCcuType: ModuleOrNamespace + tcsNiceNameGen: NiceNameGenerator + tcsTcSigEnv: TcEnv + tcsTcImplEnv: TcEnv + tcsCreatesGeneratedProvidedTypes: bool + tcsRootSigs: RootSigs + tcsRootImpls: RootImpls + tcsCcuSig: ModuleOrNamespaceType + + /// The collected open declarations implied by '/checked' flag and processing F# interactive fragments that have an implied module. + tcsImplicitOpenDeclarations: OpenDeclaration list + } + + member x.NiceNameGenerator = x.tcsNiceNameGen + + member x.TcEnvFromSignatures = x.tcsTcSigEnv + + member x.TcEnvFromImpls = x.tcsTcImplEnv + + member x.Ccu = x.tcsCcu + + member x.CreatesGeneratedProvidedTypes = x.tcsCreatesGeneratedProvidedTypes + + // Assem(a.fsi + b.fsi + c.fsi) (after checking implementation file ) + member x.CcuType = x.tcsCcuType + + // a.fsi + b.fsi + c.fsi (after checking implementation file for c.fs) + member x.CcuSig = x.tcsCcuSig + + member x.NextStateAfterIncrementalFragment tcEnvAtEndOfLastInput = + { x with tcsTcSigEnv = tcEnvAtEndOfLastInput + tcsTcImplEnv = tcEnvAtEndOfLastInput } + + +/// Create the initial type checking state for compiling an assembly +let GetInitialTcState(m, ccuName, tcConfig: TcConfig, tcGlobals, tcImports: TcImports, niceNameGen, tcEnv0, openDecls0) = + ignore tcImports + + // Create a ccu to hold all the results of compilation + let ccuContents = Construct.NewCcuContents ILScopeRef.Local m ccuName (Construct.NewEmptyModuleOrNamespaceType Namespace) + + let ccuData: CcuData = + { IsFSharp=true + UsesFSharp20PlusQuotations=false +#if !NO_EXTENSIONTYPING + InvalidateEvent=(Event<_>()).Publish + IsProviderGenerated = false + ImportProvidedType = (fun ty -> Import.ImportProvidedType (tcImports.GetImportMap()) m ty) +#endif + TryGetILModuleDef = (fun () -> None) + FileName=None + Stamp = newStamp() + QualifiedName= None + SourceCodeDirectory = tcConfig.implicitIncludeDir + ILScopeRef=ILScopeRef.Local + Contents=ccuContents + MemberSignatureEquality= typeEquivAux EraseAll tcGlobals + TypeForwarders=Map.empty + XmlDocumentationInfo = None } + + let ccu = CcuThunk.Create(ccuName, ccuData) + + // OK, is this is the FSharp.Core CCU then fix it up. + if tcConfig.compilingFslib then + tcGlobals.fslibCcu.Fixup ccu + + { tcsCcu= ccu + tcsCcuType=ccuContents + tcsNiceNameGen=niceNameGen + tcsTcSigEnv=tcEnv0 + tcsTcImplEnv=tcEnv0 + tcsCreatesGeneratedProvidedTypes=false + tcsRootSigs = Zmap.empty qnameOrder + tcsRootImpls = Zset.empty qnameOrder + tcsCcuSig = Construct.NewEmptyModuleOrNamespaceType Namespace + tcsImplicitOpenDeclarations = openDecls0 + } + +/// Typecheck a single file (or interactive entry into F# Interactive) +let TypeCheckOneInput(checkForErrors, + tcConfig: TcConfig, + tcImports: TcImports, + tcGlobals, + prefixPathOpt, + tcSink, + tcState: TcState, + inp: ParsedInput, + skipImplIfSigExists: bool) = + + cancellable { + try + CheckSimulateException tcConfig + + let m = inp.Range + let amap = tcImports.GetImportMap() + match inp with + | ParsedInput.SigFile (ParsedSigFileInput (_, qualNameOfFile, _, _, _) as file) -> + + // Check if we've seen this top module signature before. + if Zmap.mem qualNameOfFile tcState.tcsRootSigs then + errorR(Error(FSComp.SR.buildSignatureAlreadySpecified(qualNameOfFile.Text), m.StartRange)) + + // Check if the implementation came first in compilation order + if Zset.contains qualNameOfFile tcState.tcsRootImpls then + errorR(Error(FSComp.SR.buildImplementationAlreadyGivenDetail(qualNameOfFile.Text), m)) + + let conditionalDefines = + if tcConfig.noConditionalErasure then None else Some tcConfig.conditionalCompilationDefines + + // Typecheck the signature file + let! tcEnv, sigFileType, createsGeneratedProvidedTypes = + TypeCheckOneSigFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcState.tcsTcSigEnv file + + let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs + + // Add the signature to the signature env (unless it had an explicit signature) + let ccuSigForFile = CombineCcuContentFragments m [sigFileType; tcState.tcsCcuSig] + + // Open the prefixPath for fsi.exe + let tcEnv, _openDecls1 = + match prefixPathOpt with + | None -> tcEnv, [] + | Some prefixPath -> + let m = qualNameOfFile.Range + TcOpenModuleOrNamespaceDecl tcSink tcGlobals amap m tcEnv (prefixPath, m) + + let tcState = + { tcState with + tcsTcSigEnv=tcEnv + tcsTcImplEnv=tcState.tcsTcImplEnv + tcsRootSigs=rootSigs + tcsCreatesGeneratedProvidedTypes=tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes} + + return (tcEnv, EmptyTopAttrs, None, ccuSigForFile), tcState + + | ParsedInput.ImplFile (ParsedImplFileInput (_, _, qualNameOfFile, _, _, _, _) as file) -> + + // Check if we've got an interface for this fragment + let rootSigOpt = tcState.tcsRootSigs.TryFind qualNameOfFile + + // Check if we've already seen an implementation for this fragment + if Zset.contains qualNameOfFile tcState.tcsRootImpls then + errorR(Error(FSComp.SR.buildImplementationAlreadyGiven(qualNameOfFile.Text), m)) + + let tcImplEnv = tcState.tcsTcImplEnv + + let conditionalDefines = + if tcConfig.noConditionalErasure then None else Some tcConfig.conditionalCompilationDefines + + let hadSig = rootSigOpt.IsSome + + // Typecheck the implementation file + let typeCheckOne = + if skipImplIfSigExists && hadSig then + let dummyExpr = ModuleOrNamespaceExprWithSig.ModuleOrNamespaceExprWithSig(rootSigOpt.Value, ModuleOrNamespaceExpr.TMDefs [], range.Zero) + let dummyImplFile = TypedImplFile.TImplFile(qualNameOfFile, [], dummyExpr, false, false, StampMap []) + + (EmptyTopAttrs, dummyImplFile, Unchecked.defaultof<_>, tcImplEnv, false) + |> Cancellable.ret + else + TypeCheckOneImplFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, tcState.tcsImplicitOpenDeclarations, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring, tcImplEnv, rootSigOpt, file) + + let! topAttrs, implFile, _implFileHiddenType, tcEnvAtEnd, createsGeneratedProvidedTypes = typeCheckOne + + let implFileSigType = SigTypeOfImplFile implFile + + let rootImpls = Zset.add qualNameOfFile tcState.tcsRootImpls + + // Only add it to the environment if it didn't have a signature + let m = qualNameOfFile.Range + + // Add the implementation as to the implementation env + let tcImplEnv = AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcImplEnv implFileSigType + + // Add the implementation as to the signature env (unless it had an explicit signature) + let tcSigEnv = + if hadSig then tcState.tcsTcSigEnv + else AddLocalRootModuleOrNamespace TcResultsSink.NoSink tcGlobals amap m tcState.tcsTcSigEnv implFileSigType + + // Open the prefixPath for fsi.exe (tcImplEnv) + let tcImplEnv, openDecls = + match prefixPathOpt with + | Some prefixPath -> TcOpenModuleOrNamespaceDecl tcSink tcGlobals amap m tcImplEnv (prefixPath, m) + | _ -> tcImplEnv, [] + + // Open the prefixPath for fsi.exe (tcSigEnv) + let tcSigEnv, _ = + match prefixPathOpt with + | Some prefixPath when not hadSig -> TcOpenModuleOrNamespaceDecl tcSink tcGlobals amap m tcSigEnv (prefixPath, m) + | _ -> tcSigEnv, [] + + let ccuSigForFile = CombineCcuContentFragments m [implFileSigType; tcState.tcsCcuSig] + + let tcState = + { tcState with + tcsTcSigEnv=tcSigEnv + tcsTcImplEnv=tcImplEnv + tcsRootImpls=rootImpls + tcsCcuSig=ccuSigForFile + tcsCreatesGeneratedProvidedTypes=tcState.tcsCreatesGeneratedProvidedTypes || createsGeneratedProvidedTypes + tcsImplicitOpenDeclarations = tcState.tcsImplicitOpenDeclarations @ openDecls + } + return (tcEnvAtEnd, topAttrs, Some implFile, ccuSigForFile), tcState + + with e -> + errorRecovery e range0 + return (tcState.TcEnvFromSignatures, EmptyTopAttrs, None, tcState.tcsCcuSig), tcState + } + +/// Typecheck a single file (or interactive entry into F# Interactive) +let TypeCheckOneInputEntry (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt) tcState inp = + // 'use' ensures that the warning handler is restored at the end + use unwindEL = PushErrorLoggerPhaseUntilUnwind(fun oldLogger -> GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput inp, oldLogger) ) + use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck + + RequireCompilationThread ctok + TypeCheckOneInput (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, TcResultsSink.NoSink, tcState, inp, false) + |> Cancellable.runWithoutCancellation + +/// Finish checking multiple files (or one interactive entry into F# Interactive) +let TypeCheckMultipleInputsFinish(results, tcState: TcState) = + let tcEnvsAtEndFile, topAttrs, implFiles, ccuSigsForFiles = List.unzip4 results + let topAttrs = List.foldBack CombineTopAttrs topAttrs EmptyTopAttrs + let implFiles = List.choose id implFiles + // This is the environment required by fsi.exe when incrementally adding definitions + let tcEnvAtEndOfLastFile = (match tcEnvsAtEndFile with h :: _ -> h | _ -> tcState.TcEnvFromSignatures) + (tcEnvAtEndOfLastFile, topAttrs, implFiles, ccuSigsForFiles), tcState + +let TypeCheckOneInputAndFinish(checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) = + cancellable { + Logger.LogBlockStart LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually + let! results, tcState = TypeCheckOneInput(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input, false) + let result = TypeCheckMultipleInputsFinish([results], tcState) + Logger.LogBlockStop LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually + return result + } + +let TypeCheckClosedInputSetFinish (declaredImpls: TypedImplFile list, tcState) = + // Latest contents to the CCU + let ccuContents = Construct.NewCcuContents ILScopeRef.Local range0 tcState.tcsCcu.AssemblyName tcState.tcsCcuSig + + // Check all interfaces have implementations + tcState.tcsRootSigs |> Zmap.iter (fun qualNameOfFile _ -> + if not (Zset.contains qualNameOfFile tcState.tcsRootImpls) then + errorR(Error(FSComp.SR.buildSignatureWithoutImplementation(qualNameOfFile.Text), qualNameOfFile.Range))) + + tcState, declaredImpls, ccuContents + +let TypeCheckClosedInputSet (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcState, inputs) = + // tcEnvAtEndOfLastFile is the environment required by fsi.exe when incrementally adding definitions + let results, tcState = (tcState, inputs) ||> List.mapFold (TypeCheckOneInputEntry (ctok, checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt)) + let (tcEnvAtEndOfLastFile, topAttrs, implFiles, _), tcState = TypeCheckMultipleInputsFinish(results, tcState) + let tcState, declaredImpls, ccuContents = TypeCheckClosedInputSetFinish (implFiles, tcState) + tcState.Ccu.Deref.Contents <- ccuContents + tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile diff --git a/src/fsharp/ParseAndCheckInputs.fsi b/src/fsharp/ParseAndCheckInputs.fsi new file mode 100644 index 00000000000..dce7ab03f95 --- /dev/null +++ b/src/fsharp/ParseAndCheckInputs.fsi @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Contains logic to coordinate the parsing and checking of one or a group of files +module internal FSharp.Compiler.ParseAndCheckInputs + +open Internal.Utilities.Library +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.UnicodeLexing + +val IsScript: string -> bool + +val ComputeQualifiedNameOfFileFromUniquePath: range * string list -> QualifiedNameOfFile + +val PrependPathToInput: Ident list -> ParsedInput -> ParsedInput + +/// State used to de-deduplicate module names along a list of file names +type ModuleNamesDict = Map> + +/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. +val DeduplicateParsedInputModuleName: ModuleNamesDict -> ParsedInput -> ParsedInput * ModuleNamesDict + +/// Parse a single input (A signature file or implementation file) +val ParseInput: (Lexbuf -> Parser.token) * ErrorLogger * Lexbuf * string option * string * isLastCompiland:(bool * bool) -> ParsedInput + +/// A general routine to process hash directives +val ProcessMetaCommandsFromInput : + ('T -> range * string -> 'T) * + ('T -> range * string * Directive -> 'T) * + ('T -> range * string -> unit) + -> TcConfigBuilder * ParsedInput * string * 'T + -> 'T + +/// Process all the #r, #I etc. in an input. For non-scripts report warnings about ignored directives. +val ApplyMetaCommandsFromInputToTcConfig: TcConfig * ParsedInput * string * DependencyProvider -> TcConfig + +/// Process the #nowarn in an input and integrate them into the TcConfig +val ApplyNoWarnsToTcConfig: TcConfig * ParsedInput * string -> TcConfig + +/// Parse one input file +val ParseOneInputFile: TcConfig * Lexhelp.LexResourceManager * conditionalCompilationDefines: string list * string * isLastCompiland: (bool * bool) * ErrorLogger * retryLocked: bool -> ParsedInput + +/// Parse multiple input files from disk +val ParseInputFiles: TcConfig * Lexhelp.LexResourceManager * conditionalCompilationDefines: string list * string list * ErrorLogger * Exiter * createErrorLogger: (Exiter -> CapturingErrorLogger) * retryLocked: bool -> (ParsedInput * string) list + +/// Get the initial type checking environment including the loading of mscorlib/System.Core, FSharp.Core +/// applying the InternalsVisibleTo in referenced assemblies and opening 'Checked' if requested. +val GetInitialTcEnv: assemblyName: string * range * TcConfig * TcImports * TcGlobals -> TcEnv * OpenDeclaration list + +[] +/// Represents the incremental type checking state for a set of inputs +type TcState = + member NiceNameGenerator: NiceNameGenerator + + /// The CcuThunk for the current assembly being checked + member Ccu: CcuThunk + + /// Get the typing environment implied by the set of signature files and/or inferred signatures of implementation files checked so far + member TcEnvFromSignatures: TcEnv + + /// Get the typing environment implied by the set of implementation files checked so far + member TcEnvFromImpls: TcEnv + + /// The inferred contents of the assembly, containing the signatures of all files. + // a.fsi + b.fsi + c.fsi (after checking implementation file for c.fs) + member CcuSig: ModuleOrNamespaceType + + member NextStateAfterIncrementalFragment: TcEnv -> TcState + + member CreatesGeneratedProvidedTypes: bool + +/// Get the initial type checking state for a set of inputs +val GetInitialTcState: + range * + string * + TcConfig * + TcGlobals * + TcImports * + NiceNameGenerator * + TcEnv * + OpenDeclaration list + -> TcState + +/// Check one input, returned as an Eventually computation +val TypeCheckOneInput: + checkForErrors:(unit -> bool) * + TcConfig * + TcImports * + TcGlobals * + LongIdent option * + NameResolution.TcResultsSink * + TcState * + ParsedInput * + skipImplIfSigExists: bool + -> Cancellable<(TcEnv * TopAttribs * TypedImplFile option * ModuleOrNamespaceType) * TcState> + +/// Finish the checking of multiple inputs +val TypeCheckMultipleInputsFinish: (TcEnv * TopAttribs * 'T option * 'U) list * TcState -> (TcEnv * TopAttribs * 'T list * 'U list) * TcState + +/// Finish the checking of a closed set of inputs +val TypeCheckClosedInputSetFinish: + TypedImplFile list * + TcState + -> TcState * TypedImplFile list * ModuleOrNamespace + +/// Check a closed set of inputs +val TypeCheckClosedInputSet: + CompilationThreadToken * + checkForErrors: (unit -> bool) * + TcConfig * + TcImports * + TcGlobals * + LongIdent option * + TcState * + ParsedInput list + -> TcState * TopAttribs * TypedImplFile list * TcEnv + +/// Check a single input and finish the checking +val TypeCheckOneInputAndFinish : + checkForErrors: (unit -> bool) * + TcConfig * + TcImports * + TcGlobals * + LongIdent option * + NameResolution.TcResultsSink * + TcState * + ParsedInput + -> Cancellable<(TcEnv * TopAttribs * TypedImplFile list * ModuleOrNamespaceType list) * TcState> + +val GetScopedPragmasForInput: input: ParsedInput -> ScopedPragma list + +val ParseOneInputLexbuf: + tcConfig: TcConfig * + lexResourceManager: Lexhelp.LexResourceManager * + conditionalCompilationDefines: string list * + lexbuf: Lexbuf * + filename: string * + isLastCompiland: (bool * bool) * + errorLogger: ErrorLogger + -> ParsedInput + +val EmptyParsedInput: + filename: string * + isLastCompiland: (bool * bool) + -> ParsedInput diff --git a/src/fsharp/ParseHelpers.fs b/src/fsharp/ParseHelpers.fs new file mode 100644 index 00000000000..d6563d78ea2 --- /dev/null +++ b/src/fsharp/ParseHelpers.fs @@ -0,0 +1,254 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module FSharp.Compiler.ParseHelpers + +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.UnicodeLexing +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open Internal.Utilities.Text.Lexing +open Internal.Utilities.Text.Parsing + +//------------------------------------------------------------------------ +// Parsing: Error recovery exception for fsyacc +//------------------------------------------------------------------------ + +/// The error raised by the parse_error_rich function, which is called by the parser engine +/// when a syntax error occurs. The first object is the ParseErrorContext which contains a dump of +/// information about the grammar at the point where the error occurred, e.g. what tokens +/// are valid to shift next at that point in the grammar. This information is processed in CompileOps.fs. +[] +exception SyntaxError of obj (* ParseErrorContext<_> *) * range: range + +exception IndentationProblem of string * range + +let warningStringOfCoords line column = + sprintf "(%d:%d)" line (column + 1) + +let warningStringOfPos (p: pos) = + warningStringOfCoords p.Line p.Column + +//------------------------------------------------------------------------ +// Parsing: getting positions from the lexer +//------------------------------------------------------------------------ + +/// Get an F# compiler position from a lexer position +let posOfLexPosition (p: Position) = + mkPos p.Line p.Column + +/// Get an F# compiler range from a lexer range +let mkSynRange (p1: Position) (p2: Position) = + mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2) + +type LexBuffer<'Char> with + member lexbuf.LexemeRange = mkSynRange lexbuf.StartPos lexbuf.EndPos + +/// Get the range corresponding to the result of a grammar rule while it is being reduced +let lhs (parseState: IParseState) = + let p1 = parseState.ResultStartPosition + let p2 = parseState.ResultEndPosition + mkSynRange p1 p2 + +/// Get the range covering two of the r.h.s. symbols of a grammar rule while it is being reduced +let rhs2 (parseState: IParseState) i j = + let p1 = parseState.InputStartPosition i + let p2 = parseState.InputEndPosition j + mkSynRange p1 p2 + +/// Get the range corresponding to one of the r.h.s. symbols of a grammar rule while it is being reduced +let rhs parseState i = rhs2 parseState i i + +type IParseState with + + /// Get the generator used for compiler-generated argument names. + member x.SynArgNameGenerator = + let key = "SynArgNameGenerator" + let bls = x.LexBuffer.BufferLocalStore + let gen = + match bls.TryGetValue key with + | true, gen -> gen + | _ -> + let gen = box (SynArgNameGenerator()) + bls.[key] <- gen + gen + gen :?> SynArgNameGenerator + + /// Reset the generator used for compiler-generated argument names. + member x.ResetSynArgNameGenerator() = x.SynArgNameGenerator.Reset() + +//------------------------------------------------------------------------ +// Parsing: grabbing XmlDoc +//------------------------------------------------------------------------ + +/// XmlDoc F# lexer/parser state, held in the BufferLocalStore for the lexer. +/// This is the only use of the lexer BufferLocalStore in the codebase. +module LexbufLocalXmlDocStore = + // The key into the BufferLocalStore used to hold the current accumulated XmlDoc lines + let private xmlDocKey = "XmlDoc" + + let ClearXmlDoc (lexbuf: Lexbuf) = + lexbuf.BufferLocalStore.[xmlDocKey] <- box (XmlDocCollector()) + + /// Called from the lexer to save a single line of XML doc comment. + let SaveXmlDocLine (lexbuf: Lexbuf, lineText, range: range) = + let collector = + match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with + | true, collector -> collector + | _ -> + let collector = box (XmlDocCollector()) + lexbuf.BufferLocalStore.[xmlDocKey] <- collector + collector + let collector = unbox(collector) + collector.AddXmlDocLine(lineText, range) + + /// Called from the parser each time we parse a construct that marks the end of an XML doc comment range, + /// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct. + let GrabXmlDocBeforeMarker (lexbuf: Lexbuf, markerRange: range) = + match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with + | true, collector -> + let collector = unbox(collector) + PreXmlDoc.CreateFromGrabPoint(collector, markerRange.End) + | _ -> + PreXmlDoc.Empty + + +//------------------------------------------------------------------------ +// Parsing/lexing: status of #if/#endif processing in lexing, used for continutations +// for whitespace tokens in parser specification. +//------------------------------------------------------------------------ + +type LexerIfdefStackEntry = + | IfDefIf + | IfDefElse + +/// Represents the active #if/#else blocks +type LexerIfdefStackEntries = (LexerIfdefStackEntry * range) list + +type LexerIfdefStack = LexerIfdefStackEntries + +/// Specifies how the 'endline' function in the lexer should continue after +/// it reaches end of line or eof. The options are to continue with 'token' function +/// or to continue with 'skip' function. +type LexerEndlineContinuation = + | Token + | Skip of int * range: range + +type LexerIfdefExpression = + | IfdefAnd of LexerIfdefExpression*LexerIfdefExpression + | IfdefOr of LexerIfdefExpression*LexerIfdefExpression + | IfdefNot of LexerIfdefExpression + | IfdefId of string + +let rec LexerIfdefEval (lookup: string -> bool) = function + | IfdefAnd (l, r) -> (LexerIfdefEval lookup l) && (LexerIfdefEval lookup r) + | IfdefOr (l, r) -> (LexerIfdefEval lookup l) || (LexerIfdefEval lookup r) + | IfdefNot e -> not (LexerIfdefEval lookup e) + | IfdefId id -> lookup id + +//------------------------------------------------------------------------ +// Parsing: continuations for whitespace tokens +//------------------------------------------------------------------------ + +[] +type LexerStringStyle = + | Verbatim + | TripleQuote + | SingleQuote + +[] +type LexerStringKind = + { IsByteString: bool + IsInterpolated: bool + IsInterpolatedFirst: bool } + static member String = { IsByteString = false; IsInterpolated = false; IsInterpolatedFirst=false } + static member ByteString = { IsByteString = true; IsInterpolated = false; IsInterpolatedFirst=false } + static member InterpolatedStringFirst = { IsByteString = false; IsInterpolated = true; IsInterpolatedFirst=true } + static member InterpolatedStringPart = { IsByteString = false; IsInterpolated = true; IsInterpolatedFirst=false } + +/// Represents the degree of nesting of '{..}' and the style of the string to continue afterwards, in an interpolation fill. +/// Nesting counters and styles of outer interpolating strings are pushed on this stack. +type LexerInterpolatedStringNesting = (int * LexerStringStyle * range) list + +/// The parser defines a number of tokens for whitespace and +/// comments eliminated by the lexer. These carry a specification of +/// a continuation for the lexer for continued processing after we've dealt with +/// the whitespace. +[] +[] +type LexerContinuation = + | Token of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting + | IfDefSkip of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | String of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * style: LexerStringStyle * kind: LexerStringKind * range: range + | Comment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | SingleLineComment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | StringInComment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * style: LexerStringStyle * int * range: range + | MLOnly of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * range: range + | EndLine of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * LexerEndlineContinuation + + static member Default = LexCont.Token([],[]) + + member x.LexerIfdefStack = + match x with + | LexCont.Token (ifdef=ifd) + | LexCont.IfDefSkip (ifdef=ifd) + | LexCont.String (ifdef=ifd) + | LexCont.Comment (ifdef=ifd) + | LexCont.SingleLineComment (ifdef=ifd) + | LexCont.StringInComment (ifdef=ifd) + | LexCont.EndLine (ifdef=ifd) + | LexCont.MLOnly (ifdef=ifd) -> ifd + + member x.LexerInterpStringNesting = + match x with + | LexCont.Token (nesting=nesting) + | LexCont.IfDefSkip (nesting=nesting) + | LexCont.String (nesting=nesting) + | LexCont.Comment (nesting=nesting) + | LexCont.SingleLineComment (nesting=nesting) + | LexCont.StringInComment (nesting=nesting) + | LexCont.EndLine (nesting=nesting) + | LexCont.MLOnly (nesting=nesting) -> nesting + +and LexCont = LexerContinuation + +//------------------------------------------------------------------------ +// Parse IL assembly code +//------------------------------------------------------------------------ + +let ParseAssemblyCodeInstructions s reportLibraryOnlyFeatures langVersion m : IL.ILInstr[] = +#if NO_INLINE_IL_PARSER + ignore s + ignore isFeatureSupported + + errorR(Error((193, "Inline IL not valid in a hosted environment"), m)) + [| |] +#else + try + AsciiParser.ilInstrs + AsciiLexer.token + (StringAsLexbuf(reportLibraryOnlyFeatures, langVersion, s)) + with _ -> + errorR(Error(FSComp.SR.astParseEmbeddedILError(), m)); [||] +#endif + +let ParseAssemblyCodeType s reportLibraryOnlyFeatures langVersion m = + ignore s + +#if NO_INLINE_IL_PARSER + errorR(Error((193, "Inline IL not valid in a hosted environment"), m)) + IL.PrimaryAssemblyILGlobals.typ_Object +#else + try + AsciiParser.ilType + AsciiLexer.token + (StringAsLexbuf(reportLibraryOnlyFeatures, langVersion, s)) + with RecoverableParseError -> + errorR(Error(FSComp.SR.astParseEmbeddedILTypeError(), m)); + IL.PrimaryAssemblyILGlobals.typ_Object +#endif + diff --git a/src/fsharp/ParseHelpers.fsi b/src/fsharp/ParseHelpers.fsi new file mode 100644 index 00000000000..0e28f8d193c --- /dev/null +++ b/src/fsharp/ParseHelpers.fsi @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.ParseHelpers + +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Features +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open Internal.Utilities.Text.Lexing +open Internal.Utilities.Text.Parsing + +/// The error raised by the parse_error_rich function, which is called by the parser engine +/// when a syntax error occurs. The first object is the ParseErrorContext which contains a dump of +/// information about the grammar at the point where the error occurred, e.g. what tokens +/// are valid to shift next at that point in the grammar. This information is processed in CompileOps.fs. +[] +exception SyntaxError of obj * range: range + +exception IndentationProblem of string * range + +val warningStringOfCoords: line:int -> column:int -> string + +val warningStringOfPos: p:pos -> string + +val posOfLexPosition: p:Position -> pos + +val mkSynRange: p1:Position -> p2:Position -> range + +type LexBuffer<'Char> with + member LexemeRange: range + +val lhs: parseState:IParseState -> range + +val rhs2: parseState:IParseState -> i:int -> j:int -> range + +val rhs: parseState:IParseState -> i:int -> range + +type IParseState with + member SynArgNameGenerator: SyntaxTreeOps.SynArgNameGenerator + member ResetSynArgNameGenerator: unit -> unit + +module LexbufLocalXmlDocStore = + + val ClearXmlDoc: lexbuf:UnicodeLexing.Lexbuf -> unit + + val SaveXmlDocLine: lexbuf:UnicodeLexing.Lexbuf * lineText:string * range:range -> unit + + val GrabXmlDocBeforeMarker: lexbuf:UnicodeLexing.Lexbuf * markerRange:range -> PreXmlDoc + +type LexerIfdefStackEntry = + | IfDefIf + | IfDefElse + +type LexerIfdefStackEntries = (LexerIfdefStackEntry * range) list + +type LexerIfdefStack = LexerIfdefStackEntries + +type LexerEndlineContinuation = + | Token + | Skip of int * range: range + +type LexerIfdefExpression = + | IfdefAnd of LexerIfdefExpression * LexerIfdefExpression + | IfdefOr of LexerIfdefExpression * LexerIfdefExpression + | IfdefNot of LexerIfdefExpression + | IfdefId of string + +val LexerIfdefEval: lookup:(string -> bool) -> _arg1:LexerIfdefExpression -> bool + +[] +type LexerStringStyle = + | Verbatim + | TripleQuote + | SingleQuote + +[] +type LexerStringKind = + { IsByteString: bool + IsInterpolated: bool + IsInterpolatedFirst: bool } + + static member ByteString: LexerStringKind + + static member InterpolatedStringFirst: LexerStringKind + + static member InterpolatedStringPart: LexerStringKind + + static member String: LexerStringKind + +type LexerInterpolatedStringNesting = + (int * LexerStringStyle * range) list + +[] +type LexerContinuation = + | Token of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting + | IfDefSkip of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | String of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * style: LexerStringStyle * kind: LexerStringKind * range: range + | Comment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | SingleLineComment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * int * range: range + | StringInComment of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * style: LexerStringStyle * int * range: range + | MLOnly of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * range: range + | EndLine of ifdef: LexerIfdefStackEntries * nesting: LexerInterpolatedStringNesting * LexerEndlineContinuation + + member LexerIfdefStack: LexerIfdefStackEntries + + member LexerInterpStringNesting: LexerInterpolatedStringNesting + + static member Default: LexerContinuation + +and LexCont = LexerContinuation + +val ParseAssemblyCodeInstructions: s:string -> reportLibraryOnlyFeatures: bool -> langVersion: LanguageVersion -> m:range -> ILInstr[] + +val ParseAssemblyCodeType: s:string -> reportLibraryOnlyFeatures: bool -> langVersion: LanguageVersion -> m:range -> ILType diff --git a/src/fsharp/PatternMatchCompilation.fs b/src/fsharp/PatternMatchCompilation.fs index 6c5cc67e5ac..bf33354f082 100644 --- a/src/fsharp/PatternMatchCompilation.fs +++ b/src/fsharp/PatternMatchCompilation.fs @@ -3,20 +3,26 @@ module internal FSharp.Compiler.PatternMatchCompilation open System.Collections.Generic +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.TypeRelations +open FSharp.Compiler.InfoReader +open FSharp.Compiler.MethodCalls +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint +open FSharp.Compiler.TypeRelations exception MatchIncomplete of bool * (string * bool) option * range exception RuleNeverMatched of range @@ -36,7 +42,7 @@ type Pattern = | TPat_as of Pattern * PatternValBinding * range (* note: can be replaced by TPat_var, i.e. equals TPat_conjs([TPat_var; pat]) *) | TPat_disjs of Pattern list * range | TPat_conjs of Pattern list * range - | TPat_query of (Expr * TType list * (ValRef * TypeInst) option * int * ActivePatternInfo) * Pattern * range + | TPat_query of (Expr * TType list * bool * (ValRef * TypeInst) option * int * ActivePatternInfo) * Pattern * range | TPat_unioncase of UnionCaseRef * TypeInst * Pattern list * range | TPat_exnconstr of TyconRef * Pattern list * range | TPat_tuple of TupInfo * Pattern list * TType list * range @@ -44,7 +50,9 @@ type Pattern = | TPat_recd of TyconRef * TypeInst * Pattern list * range | TPat_range of char * char * range | TPat_null of range - | TPat_isinst of TType * TType * PatternValBinding option * range + | TPat_isinst of TType * TType * Pattern option * range + | TPat_error of range + member this.Range = match this with | TPat_const(_, m) -> m @@ -61,6 +69,7 @@ type Pattern = | TPat_range(_, _, m) -> m | TPat_null m -> m | TPat_isinst(_, _, _, m) -> m + | TPat_error m -> m and PatternValBinding = PBind of Val * TypeScheme @@ -70,7 +79,7 @@ and TypedMatchClause = member c.Pattern = let (TClause(p, _, _, _)) = c in p member c.Range = let (TClause(_, _, _, m)) = c in m member c.Target = let (TClause(_, _, tg, _)) = c in tg - member c.BoundVals = let (TClause(_p, _whenOpt, TTarget(vs, _, _), _m)) = c in vs + member c.BoundVals = let (TClause(_p, _whenOpt, TTarget(vs, _, _, _), _m)) = c in vs let debug = false @@ -109,11 +118,11 @@ let BindSubExprOfInput g amap gtps (PBind(v, tyscheme)) m (SubExpr(accessf, (ve2 mkTyparTy gtp else someSolved <- true - TypeRelations.ChooseTyparSolution g amap gtp + ChooseTyparSolution g amap gtp let solutions = List.map freezeVar gtps if someSolved then - TypeRelations.IterativelySubstituteTyparSolutions g gtps solutions + IterativelySubstituteTyparSolutions g gtps solutions else solutions @@ -170,7 +179,7 @@ let notNullText = "some-non-null-value" let otherSubtypeText = "some-other-subtype" /// Create a TAST const value from an IL-initialized field read from .NET metadata -// (Originally moved from TcFieldInit in TypeChecker.fs -- feel free to move this somewhere more appropriate) +// (Originally moved from TcFieldInit in CheckExpressions.fs -- feel free to move this somewhere more appropriate) let ilFieldToTastConst lit = match lit with | ILFieldInit.String s -> Const.String s @@ -226,9 +235,9 @@ let RefuteDiscrimSet g m path discrims = match discrims with | [DecisionTreeTest.IsNull] -> snd(mkCompGenLocal m notNullText ty), false - | [DecisionTreeTest.IsInst (_, _)] -> + | [DecisionTreeTest.IsInst _] -> snd(mkCompGenLocal m otherSubtypeText ty), false - | (DecisionTreeTest.Const c :: rest) -> + | DecisionTreeTest.Const c :: rest -> let consts = Set.ofList (c :: List.choose (function DecisionTreeTest.Const c -> Some c | _ -> None) rest) let c' = Seq.tryFind (fun c -> not (consts.Contains c)) @@ -247,7 +256,7 @@ let RefuteDiscrimSet g m path discrims = | Const.Double _ -> seq { 0 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Double(float v)) | Const.Single _ -> seq { 0 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Single(float32 v)) | Const.Char _ -> seq { 32us .. System.UInt16.MaxValue } |> Seq.map (fun v -> Const.Char(char v)) - | Const.String _ -> seq { 1 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.String(new System.String('a', v))) + | Const.String _ -> seq { 1 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.String(System.String('a', v))) | Const.Decimal _ -> seq { 1 .. System.Int32.MaxValue } |> Seq.map (fun v -> Const.Decimal(decimal v)) | _ -> raise CannotRefute) @@ -255,7 +264,7 @@ let RefuteDiscrimSet g m path discrims = match c' with | None -> raise CannotRefute | Some c -> - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref when tcref.IsEnumTycon -> // We must distinguish between F#-defined enums and other .NET enums, as they are represented differently in the TAST let enumValues = @@ -278,11 +287,11 @@ let RefuteDiscrimSet g m path discrims = match nonCoveredEnumValues with | None -> Expr.Const (c, m, ty), true | Some (fldName, _) -> - let v = RecdFieldRef.RFRef(tcref, fldName) + let v = RecdFieldRef.RecdFieldRef(tcref, fldName) Expr.Op (TOp.ValFieldGet v, [ty], [], m), false | _ -> Expr.Const (c, m, ty), false - | (DecisionTreeTest.UnionCase (ucref1, tinst) :: rest) -> + | DecisionTreeTest.UnionCase (ucref1, tinst) :: rest -> let ucrefs = ucref1 :: List.choose (function DecisionTreeTest.UnionCase(ucref, _) -> Some ucref | _ -> None) rest let tcref = ucref1.TyconRef (* Choose the first ucref based on ordering of names *) @@ -309,10 +318,10 @@ let rec CombineRefutations g r1 r2 = | Expr.Val (vref, _, _), other | other, Expr.Val (vref, _, _) when vref.LogicalName = notNullText -> other | Expr.Val (vref, _, _), other | other, Expr.Val (vref, _, _) when vref.LogicalName = otherSubtypeText -> other - | Expr.Op ((TOp.ExnConstr ecref1 as op1), tinst1, flds1, m1), Expr.Op (TOp.ExnConstr ecref2, _, flds2, _) when tyconRefEq g ecref1 ecref2 -> + | Expr.Op (TOp.ExnConstr ecref1 as op1, tinst1, flds1, m1), Expr.Op (TOp.ExnConstr ecref2, _, flds2, _) when tyconRefEq g ecref1 ecref2 -> Expr.Op (op1, tinst1, List.map2 (CombineRefutations g) flds1 flds2, m1) - | Expr.Op ((TOp.UnionCase ucref1 as op1), tinst1, flds1, m1), Expr.Op (TOp.UnionCase ucref2, _, flds2, _) -> + | Expr.Op (TOp.UnionCase ucref1 as op1, tinst1, flds1, m1), Expr.Op (TOp.UnionCase ucref2, _, flds2, _) -> if g.unionCaseRefEq ucref1 ucref2 then Expr.Op (op1, tinst1, List.map2 (CombineRefutations g) flds1 flds2, m1) (* Choose the greater of the two ucrefs based on name ordering *) @@ -348,15 +357,15 @@ let rec CombineRefutations g r1 r2 = let ShowCounterExample g denv m refuted = try let exprL expr = exprL g expr - let refutations = refuted |> List.collect (function RefutedWhenClause -> [] | (RefutedInvestigation(path, discrim)) -> [RefuteDiscrimSet g m path discrim]) + let refutations = refuted |> List.collect (function RefutedWhenClause -> [] | RefutedInvestigation(path, discrim) -> [RefuteDiscrimSet g m path discrim]) let counterExample, enumCoversKnown = match refutations with | [] -> raise CannotRefute | (r, eck) :: t -> - if verbose then dprintf "r = %s (enumCoversKnownValue = %b)\n" (Layout.showL (exprL r)) eck + if verbose then dprintf "r = %s (enumCoversKnownValue = %b)\n" (LayoutRender.showL (exprL r)) eck List.fold (fun (rAcc, eckAcc) (r, eck) -> CombineRefutations g rAcc r, eckAcc || eck) (r, eck) t - let text = Layout.showL (NicePrint.dataExprL denv counterExample) + let text = LayoutRender.showL (NicePrint.dataExprL denv counterExample) let failingWhenClause = refuted |> List.exists (function RefutedWhenClause -> true | _ -> false) Some(text, failingWhenClause, enumCoversKnown) @@ -387,17 +396,17 @@ type InvestigationPoint = Investigation of RuleNumber * DecisionTreeTest * Path let rec isMemOfActives p1 actives = match actives with | [] -> false - | (Active(p2, _, _)) :: rest -> pathEq p1 p2 || isMemOfActives p1 rest + | Active(p2, _, _) :: rest -> pathEq p1 p2 || isMemOfActives p1 rest let rec lookupActive x l = match l with | [] -> raise (KeyNotFoundException()) - | (Active(h, r1, r2) :: t) -> if pathEq x h then (r1, r2) else lookupActive x t + | Active(h, r1, r2) :: t -> if pathEq x h then (r1, r2) else lookupActive x t let rec removeActive x l = match l with | [] -> [] - | ((Active(h, _, _) as p) :: t) -> if pathEq x h then t else p :: removeActive x t + | Active(h, _, _) as p :: t -> if pathEq x h then t else p :: removeActive x t //--------------------------------------------------------------------------- // Utilities @@ -418,8 +427,12 @@ let getDiscrimOfPattern (g: TcGlobals) tpinst t = Some(DecisionTreeTest.UnionCase (c, instTypes tpinst tyargs')) | TPat_array (args, ty, _m) -> Some(DecisionTreeTest.ArrayLength (args.Length, ty)) - | TPat_query ((activePatExpr, resTys, apatVrefOpt, idx, apinfo), _, _m) -> - Some(DecisionTreeTest.ActivePatternCase (activePatExpr, instTypes tpinst resTys, apatVrefOpt, idx, apinfo)) + | TPat_query ((activePatExpr, resTys, isStructRetTy, apatVrefOpt, idx, apinfo), _, _m) -> + Some (DecisionTreeTest.ActivePatternCase (activePatExpr, instTypes tpinst resTys, isStructRetTy, apatVrefOpt, idx, apinfo)) + + | TPat_error range -> + Some (DecisionTreeTest.Error range) + | _ -> None let constOfDiscrim discrim = @@ -437,7 +450,7 @@ let discrimsEq (g: TcGlobals) d1 d2 = | DecisionTreeTest.Const c1, DecisionTreeTest.Const c2 -> (c1=c2) | DecisionTreeTest.IsNull, DecisionTreeTest.IsNull -> true | DecisionTreeTest.IsInst (srcty1, tgty1), DecisionTreeTest.IsInst (srcty2, tgty2) -> typeEquiv g srcty1 srcty2 && typeEquiv g tgty1 tgty2 - | DecisionTreeTest.ActivePatternCase (_, _, vrefOpt1, n1, _), DecisionTreeTest.ActivePatternCase (_, _, vrefOpt2, n2, _) -> + | DecisionTreeTest.ActivePatternCase (_, _, _, vrefOpt1, n1, _), DecisionTreeTest.ActivePatternCase (_, _, _, vrefOpt2, n2, _) -> match vrefOpt1, vrefOpt2 with | Some (vref1, tinst1), Some (vref2, tinst2) -> valRefEq g vref1 vref2 && n1 = n2 && not (doesActivePatternHaveFreeTypars g vref1) && List.lengthsEqAndForall2 (typeEquiv g) tinst1 tinst2 | _ -> false (* for equality purposes these are considered unequal! This is because adhoc computed patterns have no identity. *) @@ -459,10 +472,10 @@ let rec chooseSimultaneousEdgeSet prevOpt f l = | [] -> [], [] | h :: t -> match f prevOpt h with - | Some x, _ -> + | Some x -> let l, r = chooseSimultaneousEdgeSet (Some x) f t x :: l, r - | None, _cont -> + | None -> let l, r = chooseSimultaneousEdgeSet prevOpt f t l, h :: r @@ -477,19 +490,23 @@ let canCompactConstantClass c = /// Can two discriminators in a 'column' be decided simultaneously? let discrimsHaveSameSimultaneousClass g d1 d2 = match d1, d2 with - | DecisionTreeTest.Const _, DecisionTreeTest.Const _ - | DecisionTreeTest.IsNull, DecisionTreeTest.IsNull - | DecisionTreeTest.ArrayLength _, DecisionTreeTest.ArrayLength _ - | DecisionTreeTest.UnionCase _, DecisionTreeTest.UnionCase _ -> true - + | DecisionTreeTest.Const _, DecisionTreeTest.Const _ + | DecisionTreeTest.IsNull, DecisionTreeTest.IsNull + | DecisionTreeTest.ArrayLength _, DecisionTreeTest.ArrayLength _ + | DecisionTreeTest.UnionCase _, DecisionTreeTest.UnionCase _ -> true | DecisionTreeTest.IsInst _, DecisionTreeTest.IsInst _ -> false - | DecisionTreeTest.ActivePatternCase (_, _, apatVrefOpt1, _, _), DecisionTreeTest.ActivePatternCase (_, _, apatVrefOpt2, _, _) -> + | DecisionTreeTest.ActivePatternCase (_, _, _, apatVrefOpt1, _, _), DecisionTreeTest.ActivePatternCase (_, _, _, apatVrefOpt2, _, _) -> match apatVrefOpt1, apatVrefOpt2 with | Some (vref1, tinst1), Some (vref2, tinst2) -> valRefEq g vref1 vref2 && not (doesActivePatternHaveFreeTypars g vref1) && List.lengthsEqAndForall2 (typeEquiv g) tinst1 tinst2 | _ -> false (* for equality purposes these are considered different classes of discriminators! This is because adhoc computed patterns have no identity! *) | _ -> false +let canInvestigate (pat: Pattern) = + match pat with + | TPat_null _ | TPat_isinst _ | TPat_exnconstr _ | TPat_unioncase _ + | TPat_array _ | TPat_const _ | TPat_query _ | TPat_range _ | TPat_error _ -> true + | _ -> false /// Decide the next pattern to investigate let ChooseInvestigationPointLeftToRight frontiers = @@ -498,8 +515,7 @@ let ChooseInvestigationPointLeftToRight frontiers = let rec choose l = match l with | [] -> failwith "ChooseInvestigationPointLeftToRight: no non-immediate patterns in first rule" - | (Active(_, _, (TPat_null _ | TPat_isinst _ | TPat_exnconstr _ | TPat_unioncase _ | TPat_array _ | TPat_const _ | TPat_query _ | TPat_range _)) as active) - :: _ -> active + | Active (_, _, pat) as active :: _ when canInvestigate pat -> active | _ :: t -> choose t choose actives | [] -> failwith "ChooseInvestigationPointLeftToRight: no frontiers!" @@ -566,12 +582,12 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = // 'isinst' tests where we have stored the result of the 'isinst' in a variable // In this case the 'expr' already holds the result of the 'isinst' test. - | (TCase(DecisionTreeTest.IsInst _, success)) :: edges, dflt when Option.isSome inpExprOpt -> - TDSwitch(expr, [TCase(DecisionTreeTest.IsNull, BuildSwitch None g expr edges dflt m)], Some success, m) + | TCase(DecisionTreeTest.IsInst _, success) :: edges, dflt when Option.isSome inpExprOpt -> + TDSwitch(DebugPointAtSwitch.No, expr, [TCase(DecisionTreeTest.IsNull, BuildSwitch None g expr edges dflt m)], Some success, m) // isnull and isinst tests - | (TCase((DecisionTreeTest.IsNull | DecisionTreeTest.IsInst _), _) as edge) :: edges, dflt -> - TDSwitch(expr, [edge], Some (BuildSwitch inpExprOpt g expr edges dflt m), m) + | TCase((DecisionTreeTest.IsNull | DecisionTreeTest.IsInst _), _) as edge :: edges, dflt -> + TDSwitch(DebugPointAtSwitch.No, expr, [edge], Some (BuildSwitch inpExprOpt g expr edges dflt m), m) #if OPTIMIZE_LIST_MATCHING // 'cons/nil' tests where we have stored the result of the cons test in an 'isinst' in a variable @@ -581,11 +597,11 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = | [TCase(ListEmptyDiscrim g _, emptyCase); TCase(ListConsDiscrim g tinst, consCase)], None | [TCase(ListConsDiscrim g tinst, consCase); TCase(ListEmptyDiscrim g _, emptyCase)], None when Option.isSome inpExprOpt -> - TDSwitch(expr, [TCase(DecisionTreeTest.IsNull, emptyCase)], Some consCase, m) + TDSwitch(DebugPointAtSwitch.No, expr, [TCase(DecisionTreeTest.IsNull, emptyCase)], Some consCase, m) #endif // All these should also always have default cases - | (TCase(DecisionTreeTest.Const ConstNeedsDefaultCase, _) :: _), None -> + | TCase(DecisionTreeTest.Const ConstNeedsDefaultCase, _) :: _, None -> error(InternalError("inexhaustive match - need a default case!", m)) // Split string, float, uint64, int64, unativeint, nativeint matches into serial equality tests @@ -602,10 +618,10 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = mkCallEqualsOperator g m g.string_ty testexpr (Expr.Const (c, m, g.string_ty)) | DecisionTreeTest.Const (Const.Decimal _ as c) -> mkCallEqualsOperator g m g.decimal_ty testexpr (Expr.Const (c, m, g.decimal_ty)) - | DecisionTreeTest.Const ((Const.Double _ | Const.Single _ | Const.Int64 _ | Const.UInt64 _ | Const.IntPtr _ | Const.UIntPtr _) as c) -> + | DecisionTreeTest.Const (Const.Double _ | Const.Single _ | Const.Int64 _ | Const.UInt64 _ | Const.IntPtr _ | Const.UIntPtr _ as c) -> mkILAsmCeq g m testexpr (Expr.Const (c, m, tyOfExpr g testexpr)) | _ -> error(InternalError("strange switch", m)) - mkBoolSwitch m testexpr tree sofar) + mkBoolSwitch DebugPointAtSwitch.No m testexpr tree sofar) edges dflt @@ -613,13 +629,13 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = | TCase(DecisionTreeTest.Const c, _) :: _, Some dflt when canCompactConstantClass c -> let edgeCompare c1 c2 = match constOfCase c1, constOfCase c2 with - | (Const.SByte i1), (Const.SByte i2) -> compare i1 i2 - | (Const.Int16 i1), (Const.Int16 i2) -> compare i1 i2 - | (Const.Int32 i1), (Const.Int32 i2) -> compare i1 i2 - | (Const.Byte i1), (Const.Byte i2) -> compare i1 i2 - | (Const.UInt16 i1), (Const.UInt16 i2) -> compare i1 i2 - | (Const.UInt32 i1), (Const.UInt32 i2) -> compare i1 i2 - | (Const.Char c1), (Const.Char c2) -> compare c1 c2 + | Const.SByte i1, Const.SByte i2 -> compare i1 i2 + | Const.Int16 i1, Const.Int16 i2 -> compare i1 i2 + | Const.Int32 i1, Const.Int32 i2 -> compare i1 i2 + | Const.Byte i1, Const.Byte i2 -> compare i1 i2 + | Const.UInt16 i1, Const.UInt16 i2 -> compare i1 i2 + | Const.UInt32 i1, Const.UInt32 i2 -> compare i1 i2 + | Const.Char c1, Const.Char c2 -> compare c1 c2 | _ -> failwith "illtyped term during pattern compilation" let edges' = List.sortWith edgeCompare edges let rec compactify curr edges = @@ -647,36 +663,36 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = | _ -> failwith "internal error: compactify" let edgeGroups = compactify None edges' - (edgeGroups, dflt) ||> List.foldBack (fun edgeGroup sofar -> TDSwitch(expr, edgeGroup, Some sofar, m)) + (edgeGroups, dflt) ||> List.foldBack (fun edgeGroup sofar -> TDSwitch(DebugPointAtSwitch.No, expr, edgeGroup, Some sofar, m)) // For a total pattern match, run the active pattern, bind the result and // recursively build a switch in the choice type - | (TCase(DecisionTreeTest.ActivePatternCase _, _) :: _), _ -> + | TCase(DecisionTreeTest.ActivePatternCase _, _) :: _, _ -> error(InternalError("DecisionTreeTest.ActivePatternCase should have been eliminated", m)) // For a complete match, optimize one test to be the default - | (TCase(_, tree) :: rest), None -> TDSwitch (expr, rest, Some tree, m) + | TCase(_, tree) :: rest, None -> TDSwitch (DebugPointAtSwitch.No, expr, rest, Some tree, m) // Otherwise let codegen make the choices - | _ -> TDSwitch (expr, edges, dflt, m) + | _ -> TDSwitch (DebugPointAtSwitch.No, expr, edges, dflt, m) #if DEBUG let rec layoutPat pat = match pat with - | TPat_query (_, pat, _) -> Layout.(--) (Layout.wordL (Layout.TaggedTextOps.tagText "query")) (layoutPat pat) - | TPat_wild _ -> Layout.wordL (Layout.TaggedTextOps.tagText "wild") - | TPat_as _ -> Layout.wordL (Layout.TaggedTextOps.tagText "var") + | TPat_query (_, pat, _) -> Layout.(--) (Layout.wordL (TaggedText.tagText "query")) (layoutPat pat) + | TPat_wild _ -> Layout.wordL (TaggedText.tagText "wild") + | TPat_as _ -> Layout.wordL (TaggedText.tagText "var") | TPat_tuple (_, pats, _, _) | TPat_array (pats, _, _) -> Layout.bracketL (Layout.tupleL (List.map layoutPat pats)) - | _ -> Layout.wordL (Layout.TaggedTextOps.tagText "?") + | _ -> Layout.wordL (TaggedText.tagText "?") -let layoutPath _p = Layout.wordL (Layout.TaggedTextOps.tagText "") +let layoutPath _p = Layout.wordL (TaggedText.tagText "") let layoutActive (Active (path, _subexpr, pat)) = - Layout.(--) (Layout.wordL (Layout.TaggedTextOps.tagText "Active")) (Layout.tupleL [layoutPath path; layoutPat pat]) + Layout.(--) (Layout.wordL (TaggedText.tagText "Active")) (Layout.tupleL [layoutPath path; layoutPat pat]) let layoutFrontier (Frontier (i, actives, _)) = - Layout.(--) (Layout.wordL (Layout.TaggedTextOps.tagText "Frontier ")) (Layout.tupleL [intL i; Layout.listL layoutActive actives]) + Layout.(--) (Layout.wordL (TaggedText.tagText "Frontier ")) (Layout.tupleL [intL i; Layout.listL layoutActive actives]) #endif let mkFrontiers investigations i = @@ -687,7 +703,7 @@ let getRuleIndex (Frontier (i, _active, _valMap)) = i /// Is a pattern a partial pattern? let rec isPatternPartial p = match p with - | TPat_query ((_, _, _, _, apinfo), p, _m) -> not apinfo.IsTotal || isPatternPartial p + | TPat_query ((_, _, _, _, _, apinfo), p, _m) -> not apinfo.IsTotal || isPatternPartial p | TPat_const _ -> false | TPat_wild _ -> false | TPat_as (p, _, _) -> isPatternPartial p @@ -698,11 +714,12 @@ let rec isPatternPartial p = | TPat_range _ -> false | TPat_null _ -> false | TPat_isinst _ -> false + | TPat_error _ -> false let rec erasePartialPatterns inpp = match inpp with - | TPat_query ((expr, resTys, apatVrefOpt, idx, apinfo), p, m) -> - if apinfo.IsTotal then TPat_query ((expr, resTys, apatVrefOpt, idx, apinfo), erasePartialPatterns p, m) + | TPat_query ((expr, resTys, isStructRetTy, apatVrefOpt, idx, apinfo), p, m) -> + if apinfo.IsTotal then TPat_query ((expr, resTys, isStructRetTy, apatVrefOpt, idx, apinfo), erasePartialPatterns p, m) else TPat_disjs ([], m) (* always fail *) | TPat_as (p, x, m) -> TPat_as (erasePartialPatterns p, x, m) | TPat_disjs (ps, m) -> TPat_disjs(erasePartials ps, m) @@ -716,7 +733,8 @@ let rec erasePartialPatterns inpp = | TPat_wild _ | TPat_range _ | TPat_null _ - | TPat_isinst _ -> inpp + | TPat_isinst _ + | TPat_error _ -> inpp and erasePartials inps = List.map erasePartialPatterns inps @@ -731,19 +749,19 @@ let getDiscrim (EdgeDiscrim(_, discrim, _)) = discrim let CompilePatternBasic - g denv amap exprm matchm + (g: TcGlobals) denv amap tcVal infoReader exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, _origInputExprOpt: Expr option) - (clausesL: TypedMatchClause list) + (typedClauses: TypedMatchClause list) inputTy resultTy = // Add the targets to a match builder. // Note the input expression has already been evaluated and saved into a variable, // hence no need for a new sequence point. - let matchBuilder = MatchBuilder (NoSequencePointAtInvisibleBinding, exprm) - clausesL |> List.iter (fun c -> matchBuilder.AddTarget c.Target |> ignore) + let matchBuilder = MatchBuilder (DebugPointAtBinding.NoneAtInvisible, exprm) + typedClauses |> List.iter (fun c -> matchBuilder.AddTarget c.Target |> ignore) // Add the incomplete or rethrow match clause on demand, // printing a warning if necessary (only if it is ever exercised). @@ -774,14 +792,51 @@ let CompilePatternBasic mkInt g matchm 0 | Rethrow -> - // Rethrow unmatched try-catch exn. No sequence point at the target since its not real code. + // Rethrow unmatched try-with exn. No sequence point at the target since its not real code. mkReraise matchm resultTy | Throw -> - // We throw instead of rethrow on unmatched try-catch in a computation expression. But why? - // Because this isn't a real .NET exception filter/handler but just a function we're passing + let findMethInfo ty isInstance name (sigTys: TType list) = + TryFindIntrinsicMethInfo infoReader matchm AccessorDomain.AccessibleFromEverywhere name ty + |> List.tryFind (fun methInfo -> + methInfo.IsInstance = isInstance && + ( + match methInfo.GetParamTypes(amap, matchm, []) with + | [] -> false + | argTysList -> + let argTys = (argTysList |> List.reduce (@)) @ [ methInfo.GetFSharpReturnTy (amap, matchm, []) ] + if argTys.Length <> sigTys.Length then + false + else + (argTys, sigTys) + ||> List.forall2 (typeEquiv g) + ) + ) + + // We use throw, or EDI.Capture(exn).Throw() when EDI is supported, instead of rethrow on unmatched try-with in a computation expression. + // But why? Because this isn't a real .NET exception filter/handler but just a function we're passing // to a computation expression builder to simulate one. - mkThrow matchm resultTy (exprForVal matchm origInputVal) + let ediCaptureMethInfo, ediThrowMethInfo = + // EDI.Capture: exn -> EDI + g.system_ExceptionDispatchInfo_ty + |> Option.bind (fun ty -> findMethInfo ty false "Capture" [ g.exn_ty; ty ]), + // edi.Throw: unit -> unit + g.system_ExceptionDispatchInfo_ty + |> Option.bind (fun ty -> findMethInfo ty true "Throw" [ g.unit_ty ]) + + match Option.map2 (fun x y -> x,y) ediCaptureMethInfo ediThrowMethInfo with + | None -> + mkThrow matchm resultTy (exprForVal matchm origInputVal) + | Some (ediCaptureMethInfo, ediThrowMethInfo) -> + let edi, _ = + BuildMethodCall tcVal g amap NeverMutates matchm false + ediCaptureMethInfo ValUseFlag.NormalValUse [] [] [ (exprForVal matchm origInputVal) ] + + let e, _ = + BuildMethodCall tcVal g amap NeverMutates matchm false + ediThrowMethInfo ValUseFlag.NormalValUse [] [edi] [ ] + + mkCompGenSequential matchm e (mkDefault (matchm, resultTy)) | ThrowIncompleteMatchException -> mkThrow matchm resultTy @@ -798,7 +853,7 @@ let CompilePatternBasic // Note we don't emit sequence points at either the succeeding or failing targets of filters since if // the exception is filtered successfully then we will run the handler and hit the sequence point there. // That sequence point will have the pattern variables bound, which is exactly what we want. - let tg = TTarget(List.empty, throwExpr, SuppressSequencePointAtTarget) + let tg = TTarget([], throwExpr, DebugPointAtTarget.No, None) let _ = matchBuilder.AddTarget tg let clause = TClause(TPat_wild matchm, None, tg, matchm) incompleteMatchClauseOnce <- Some clause @@ -807,15 +862,17 @@ let CompilePatternBasic | Some c -> c // Helpers to get the variables bound at a target. - // We conceptually add a dummy clause that will always succeed with a "throw" - let clausesA = Array.ofList clausesL + // We conceptually add a dummy clause that will always succeed with a "throw". + let clausesA = Array.ofList typedClauses let nClauses = clausesA.Length let GetClause i refuted = if i < nClauses then clausesA.[i] elif i = nClauses then getIncompleteMatchClause refuted else failwith "GetClause" + let GetValsBoundByClause i refuted = (GetClause i refuted).BoundVals + let GetWhenGuardOfClause i refuted = (GetClause i refuted).GuardExpr // Different uses of parameterized active patterns have different identities as far as paths are concerned. @@ -842,14 +899,10 @@ let CompilePatternBasic | _ -> // Otherwise choose a point (i.e. a path) to investigate. let (Active(path, subexpr, pat)) = ChooseInvestigationPointLeftToRight frontiers - match pat with - // All these constructs should have been eliminated in BindProjectionPattern - | TPat_as _ | TPat_tuple _ | TPat_wild _ | TPat_disjs _ | TPat_conjs _ | TPat_recd _ -> + if not (canInvestigate pat) then + // All these constructs should have been eliminated in BindProjectionPattern failwith "Unexpected pattern" - - // Leaving the ones where we have real work to do. - | _ -> - + else let simulSetOfEdgeDiscrims, fallthroughPathFrontiers = ChooseSimultaneousEdges frontiers path let inpExprOpt, bindOpt = ChoosePreBinder simulSetOfEdgeDiscrims subexpr @@ -861,8 +914,7 @@ let CompilePatternBasic // Work out what the default/fall-through tree looks like, is any // Check if match is complete, if so optimize the default case away. - - let defaultTreeOpt : DecisionTree option = CompileFallThroughTree fallthroughPathFrontiers path refuted simulSetOfCases + let defaultTreeOpt = CompileFallThroughTree fallthroughPathFrontiers path refuted simulSetOfCases // OK, build the whole tree and whack on the binding if any let finalDecisionTree = @@ -879,28 +931,17 @@ let CompilePatternBasic let es2 = vs2 |> List.map (fun v -> match valMap.TryFind v with - | None -> error(Error(FSComp.SR.patcMissingVariable(v.DisplayName), v.Range)) + | None -> mkUnit g v.Range | Some res -> res) - let rhs' = TDSuccess(es2, i) + let successTree = TDSuccess(es2, i) match GetWhenGuardOfClause i refuted with | Some whenExpr -> - let m = whenExpr.Range + let whenExprWithBindings = mkLetsFromBindings m (mkInvisibleBinds vs2 es2) whenExpr + let failureTree = (InvestigateFrontiers (RefutedWhenClause :: refuted) rest) + mkBoolSwitch (DebugPointAtSwitch.Yes m) m whenExprWithBindings successTree failureTree - // SEQUENCE POINTS: REVIEW: Build a sequence point at 'when' - let whenExpr = mkLetsFromBindings m (mkInvisibleBinds vs2 es2) whenExpr - - // We must duplicate both the bindings and the guard expression to ensure uniqueness of bound variables. - // This is because guards and bindings can end up being compiled multiple times when "or" patterns are used. - // - // let whenExpr = copyExpr g CloneAll whenExpr - // - // However, we are not allowed to copy expressions until type checking is complete, because this - // would lose recursive fixup points within the expressions (see FSharp 1.0 bug 4821). - - mkBoolSwitch m whenExpr rhs' (InvestigateFrontiers (RefutedWhenClause :: refuted) rest) - - | None -> rhs' + | None -> successTree /// Select the set of discriminators which we can handle in one test, or as a series of iterated tests, /// e.g. in the case of TPat_isinst. Ensure we only take at most one class of `TPat_query` at a time. @@ -913,14 +954,14 @@ let CompilePatternBasic match getDiscrimOfPattern p with | Some discrim -> if (match prevOpt with None -> true | Some (EdgeDiscrim(_, discrimPrev, _)) -> discrimsHaveSameSimultaneousClass g discrim discrimPrev) then - Some (EdgeDiscrim(i', discrim, p.Range)), true + Some (EdgeDiscrim(i', discrim, p.Range)) else - None, false + None | None -> - None, true + None else - None, true) + None) and IsCopyableInputExpr origInputExpr = match origInputExpr with @@ -940,7 +981,7 @@ let CompilePatternBasic // if we flowed a bit of information through - | EdgeDiscrim(_i', (DecisionTreeTest.IsInst (_srcty, tgty)), m) :: _rest + | EdgeDiscrim(_i', DecisionTreeTest.IsInst (_srcty, tgty), m) :: _rest (* check we can use a simple 'isinst' instruction *) when canUseTypeTestFast g tgty && isNil origInputValTypars -> @@ -953,7 +994,7 @@ let CompilePatternBasic // Any match on a struct union must take the address of its input. // We can shortcut the addrOf when the original input is a deref of a byref value. - | EdgeDiscrim(_i', (DecisionTreeTest.UnionCase (ucref, _)), _) :: _rest + | EdgeDiscrim(_i', DecisionTreeTest.UnionCase (ucref, _), _) :: _rest when isNil origInputValTypars && ucref.Tycon.IsStructRecordOrUnionTycon -> let argExpr = GetSubExprOfInput subexpr @@ -989,17 +1030,27 @@ let CompilePatternBasic #endif // Active pattern matches: create a variable to hold the results of executing the active pattern. - | (EdgeDiscrim(_, (DecisionTreeTest.ActivePatternCase(activePatExpr, resTys, _, _, apinfo)), m) :: _) -> + // If a struct return we continue with an expression for taking the address of that location. + | EdgeDiscrim(_, DecisionTreeTest.ActivePatternCase(activePatExpr, resTys, isStructRetTy, _apatVrefOpt, _, apinfo), m) :: _ -> if not (isNil origInputValTypars) then error(InternalError("Unexpected generalized type variables when compiling an active pattern", m)) - let resTy = apinfo.ResultType g m resTys - let v, vExpr = mkCompGenLocal m ("activePatternResult" + string (newUnique())) resTy - if origInputVal.IsMemberOrModuleBinding then - AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + + let resTy = apinfo.ResultType g m resTys isStructRetTy let argExpr = GetSubExprOfInput subexpr let appExpr = mkApps g ((activePatExpr, tyOfExpr g activePatExpr), [], [argExpr], m) - Some vExpr, Some(mkInvisibleBind v appExpr) + let vOpt, addrExp, _readonly, _writeonly = mkExprAddrOfExprAux g isStructRetTy false NeverMutates appExpr None matchm + match vOpt with + | None -> + let v, vExpr = mkCompGenLocal m ("activePatternResult" + string (newUnique())) resTy + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + Some vExpr, Some(mkInvisibleBind v addrExp) + | Some (v, e) -> + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + Some addrExp, Some (mkInvisibleBind v e) + | _ -> None, None @@ -1044,13 +1095,13 @@ let CompilePatternBasic // Convert active pattern edges to tests on results data let discrim' = match discrim with - | DecisionTreeTest.ActivePatternCase(_pexp, resTys, _apatVrefOpt, idx, apinfo) -> + | DecisionTreeTest.ActivePatternCase(_pexp, resTys, isStructRetTy, _apatVrefOpt, idx, apinfo) -> let aparity = apinfo.Names.Length let total = apinfo.IsTotal if not total && aparity > 1 then error(Error(FSComp.SR.patcPartialActivePatternsGenerateOneResult(), m)) - if not total then DecisionTreeTest.UnionCase(mkSomeCase g, resTys) + if not total then DecisionTreeTest.UnionCase(mkAnySomeCase g isStructRetTy, resTys) elif aparity <= 1 then DecisionTreeTest.Const(Const.Unit) else DecisionTreeTest.UnionCase(mkChoiceCaseRef g m aparity idx, resTys) | _ -> discrim @@ -1084,7 +1135,7 @@ let CompilePatternBasic | DecisionTreeTest.Const (Const.Bool _b) :: _ when simulSetOfCases.Length = 2 -> None | DecisionTreeTest.Const (Const.Byte _) :: _ when simulSetOfCases.Length = 256 -> None | DecisionTreeTest.Const (Const.SByte _) :: _ when simulSetOfCases.Length = 256 -> None - | DecisionTreeTest.Const (Const.Unit) :: _ -> None + | DecisionTreeTest.Const Const.Unit :: _ -> None | DecisionTreeTest.UnionCase (ucref, _) :: _ when simulSetOfCases.Length = ucref.TyconRef.UnionCasesArray.Length -> None | DecisionTreeTest.ActivePatternCase _ :: _ -> error(InternalError("DecisionTreeTest.ActivePatternCase should have been eliminated", matchm)) | _ -> @@ -1104,7 +1155,7 @@ let CompilePatternBasic and GenerateNewFrontiersAfterSuccessfulInvestigation inpExprOpt resPostBindOpt (Investigation(i', discrim, path)) (Frontier (i, active, valMap) as frontier) = if (isMemOfActives path active) then - let (SubExpr(accessf, ve)), pat = lookupActive path active + let SubExpr(accessf, ve), pat = lookupActive path active let mkSubFrontiers path accessf' active' argpats pathBuilder = let mkSubActive j p = @@ -1118,9 +1169,9 @@ let CompilePatternBasic let active' = removeActive path active match pat with | TPat_wild _ | TPat_as _ | TPat_tuple _ | TPat_disjs _ | TPat_conjs _ | TPat_recd _ -> failwith "Unexpected projection pattern" - | TPat_query ((_, resTys, apatVrefOpt, idx, apinfo), p, m) -> - + | TPat_query ((_, resTys, isStructRetTy, apatVrefOpt, idx, apinfo), p, m) -> if apinfo.IsTotal then + // Total active patterns always return choice values let hasParam = (match apatVrefOpt with None -> true | Some (vref, _) -> doesActivePatternHaveFreeTypars g vref) if (hasParam && i = i') || (discrimsEq g discrim (Option.get (getDiscrimOfPattern pat))) then let aparity = apinfo.Names.Length @@ -1142,12 +1193,16 @@ let CompilePatternBasic else [] else + // Partial active patterns always return options or value-options if i = i' then - let accessf' _j tpinst _ = - // TODO: In the future we will want active patterns to be able to return struct-unions - // In that eventuality, we need to check we are taking the address correctly - mkUnionCaseFieldGetUnprovenViaExprAddr (Option.get inpExprOpt, mkSomeCase g, instTypes tpinst resTys, 0, exprm) - mkSubFrontiers path accessf' active' [p] (fun path j -> PathQuery(path, int64 j)) + let accessf' _j tpinst _ = + let expr = Option.get inpExprOpt + if isStructRetTy then + // In this case, the inpExprOpt is already an address-of expression + mkUnionCaseFieldGetProvenViaExprAddr (expr, mkValueSomeCase g, instTypes tpinst resTys, 0, exprm) + else + mkUnionCaseFieldGetUnprovenViaExprAddr (expr, mkSomeCase g, instTypes tpinst resTys, 0, exprm) + mkSubFrontiers path accessf' active' [p] (fun path j -> PathQuery(path, int64 j)) else // Successful active patterns don't refute other patterns [frontier] @@ -1206,9 +1261,8 @@ let CompilePatternBasic | _ -> // Otherwise call the helper mkCallUnboxFast g exprm (instType tpinst tgtTy1) (accessf tpinst exprIn) - - let (v, exprIn) = BindSubExprOfInput g amap origInputValTypars pbind exprm (SubExpr(accessf', ve)) - [Frontier (i, active', valMap.Add v exprIn )] + BindProjectionPattern (Active(path, SubExpr(accessf', ve), pbind)) (active', valMap) + |> mkFrontiers <| i | None -> [Frontier (i, active', valMap)] @@ -1235,10 +1289,19 @@ let CompilePatternBasic | _ -> [frontier] + | TPat_error range -> + match discrim with + | DecisionTreeTest.Error testRange when range = testRange -> + [Frontier (i, active', valMap)] + | _ -> + [frontier] + | _ -> failwith "pattern compilation: GenerateNewFrontiersAfterSuccessfulInvestigation" - else [frontier] - and BindProjectionPattern (Active(path, subExpr, p) as inp) ((accActive, accValMap) as s) = + else + [frontier] + + and BindProjectionPattern (Active(path, subExpr, p) as inp) (accActive, accValMap as s) = let (SubExpr(accessf, ve)) = subExpr let mkSubActive pathBuilder accessf' j p' = Active(pathBuilder path j, SubExpr(accessf' j, ve), p') @@ -1247,7 +1310,7 @@ let CompilePatternBasic | TPat_wild _ -> BindProjectionPatterns [] s | TPat_as(p', pbind, m) -> - let (v, subExpr') = BindSubExprOfInput g amap origInputValTypars pbind m subExpr + let v, subExpr' = BindSubExprOfInput g amap origInputValTypars pbind m subExpr BindProjectionPattern (Active(path, subExpr, p')) (accActive, accValMap.Add v subExpr' ) | TPat_tuple(tupInfo, ps, tyargs, _m) -> let accessf' j tpinst subExpr' = mkTupleFieldGet g (tupInfo, accessf tpinst subExpr', instTypes tpinst tyargs, j, exprm) @@ -1273,7 +1336,7 @@ let CompilePatternBasic res <- BindProjectionPattern (Active(path, subExpr, TPat_const(Const.Char(char i), m))) s @ res res // Assign an identifier to each TPat_query based on our knowledge of the 'identity' of the active pattern, if any - | TPat_query ((_, _, apatVrefOpt, _, _), _, _) -> + | TPat_query ((_, _, _, apatVrefOpt, _, _), _, _) -> let uniqId = match apatVrefOpt with | Some (vref, _) when not (doesActivePatternHaveFreeTypars g vref) -> vref.Stamp @@ -1286,11 +1349,11 @@ let CompilePatternBasic and BindProjectionPatterns ps s = List.foldBack (fun p sofar -> List.collect (BindProjectionPattern p) sofar) ps [s] - (* The setup routine of the match compiler *) + // The setup routine of the match compiler. let frontiers = - ((clausesL + ((typedClauses |> List.mapi (fun i c -> - let initialSubExpr = SubExpr((fun _tpinst x -> x), (exprForVal origInputVal.Range origInputVal, origInputVal)) + let initialSubExpr = SubExpr((fun _ x -> x), (exprForVal origInputVal.Range origInputVal, origInputVal)) let investigations = BindProjectionPattern (Active(PathEmpty inputTy, initialSubExpr, c.Pattern)) ([], ValMap<_>.Empty) mkFrontiers investigations i) |> List.concat) @@ -1308,33 +1371,32 @@ let CompilePatternBasic if warnOnUnused then let used = HashSet<_>(accTargetsOfDecisionTree dtree [], HashIdentity.Structural) - clausesL |> List.iteri (fun i c -> + typedClauses |> List.iteri (fun i c -> if not (used.Contains i) then warning (RuleNeverMatched c.Range)) dtree, targets let isPartialOrWhenClause (c: TypedMatchClause) = isPatternPartial c.Pattern || c.GuardExpr.IsSome - -let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (clausesL: TypedMatchClause list) inputTy resultTy = +let rec CompilePattern g denv amap tcVal infoReader exprm matchm warnOnUnused actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (clausesL: TypedMatchClause list) inputTy resultTy = match clausesL with | _ when List.exists isPartialOrWhenClause clausesL -> - // Partial clauses cause major code explosion if treated naively - // Hence treat any pattern matches with any partial clauses clause-by-clause // First make sure we generate at least some of the obvious incomplete match warnings. let warnOnUnused = false // we can't turn this on since we're pretending all partials fail in order to control the complexity of this. let warnOnIncomplete = true - let clausesPretendAllPartialFail = List.collect (fun (TClause(p, whenOpt, tg, m)) -> [TClause(erasePartialPatterns p, whenOpt, tg, m)]) clausesL - let _ = CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesPretendAllPartialFail inputTy resultTy + let clausesPretendAllPartialFail = clausesL |> List.collect (fun (TClause(p, whenOpt, tg, m)) -> [TClause(erasePartialPatterns p, whenOpt, tg, m)]) + let _ = CompilePatternBasic g denv amap tcVal infoReader exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesPretendAllPartialFail inputTy resultTy let warnOnIncomplete = false + // Partial and when clauses cause major code explosion if treated naively + // Hence treat any pattern matches with any partial clauses clause-by-clause let rec atMostOnePartialAtATime clauses = match List.takeUntil isPartialOrWhenClause clauses with | l, [] -> - CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) l inputTy resultTy - | l, (h :: t) -> - // Add the partial clause. + CompilePatternBasic g denv amap tcVal infoReader exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) l inputTy resultTy + | l, h :: t -> + // Add the partial or when clause. doGroupWithAtMostOnePartial (l @ [h]) t and doGroupWithAtMostOnePartial group rest = @@ -1342,21 +1404,21 @@ let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (o let decisionTree, targets = atMostOnePartialAtATime rest // Make the expression that represents the remaining cases of the pattern match. - let expr = mkAndSimplifyMatch NoSequencePointAtInvisibleBinding exprm matchm resultTy decisionTree targets + let expr = mkAndSimplifyMatch DebugPointAtBinding.NoneAtInvisible exprm matchm resultTy decisionTree targets // If the remainder of the match boiled away to nothing interesting. // We measure this simply by seeing if the range of the resulting expression is identical to matchm. let spTarget = - if Range.equals expr.Range matchm then SuppressSequencePointAtTarget - else SequencePointAtTarget + if equals expr.Range matchm then DebugPointAtTarget.No + else DebugPointAtTarget.Yes // Make the clause that represents the remaining cases of the pattern match - let clauseForRestOfMatch = TClause(TPat_wild matchm, None, TTarget(List.empty, expr, spTarget), matchm) + let clauseForRestOfMatch = TClause(TPat_wild matchm, None, TTarget(List.empty, expr, spTarget, None), matchm) - CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (group @ [clauseForRestOfMatch]) inputTy resultTy + CompilePatternBasic g denv amap tcVal infoReader exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (group @ [clauseForRestOfMatch]) inputTy resultTy atMostOnePartialAtATime clausesL | _ -> - CompilePatternBasic g denv amap exprm matchm warnOnUnused true actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesL inputTy resultTy + CompilePatternBasic g denv amap tcVal infoReader exprm matchm warnOnUnused true actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesL inputTy resultTy diff --git a/src/fsharp/PatternMatchCompilation.fsi b/src/fsharp/PatternMatchCompilation.fsi index b35b5f42b27..98e195637c1 100644 --- a/src/fsharp/PatternMatchCompilation.fsi +++ b/src/fsharp/PatternMatchCompilation.fsi @@ -2,12 +2,14 @@ module internal FSharp.Compiler.PatternMatchCompilation -open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Range +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps /// What should the decision tree contain for any incomplete match? type ActionOnFailure = @@ -17,15 +19,15 @@ type ActionOnFailure = | Rethrow | FailFilter -[] /// Represents the typechecked, elaborated form of a pattern, prior to pattern-match compilation. +[] type Pattern = | TPat_const of Const * range | TPat_wild of range | TPat_as of Pattern * PatternValBinding * range | TPat_disjs of Pattern list * range | TPat_conjs of Pattern list * range - | TPat_query of (Expr * TType list * (ValRef * TypeInst) option * int * PrettyNaming.ActivePatternInfo) * Pattern * range + | TPat_query of (Expr * TType list * bool * (ValRef * TypeInst) option * int * ActivePatternInfo) * Pattern * range | TPat_unioncase of UnionCaseRef * TypeInst * Pattern list * range | TPat_exnconstr of TyconRef * Pattern list * range | TPat_tuple of TupInfo * Pattern list * TType list * range @@ -33,7 +35,8 @@ type Pattern = | TPat_recd of TyconRef * TypeInst * Pattern list * range | TPat_range of char * char * range | TPat_null of range - | TPat_isinst of TType * TType * PatternValBinding option * range + | TPat_isinst of TType * TType * Pattern option * range + | TPat_error of range member Range: range @@ -43,13 +46,16 @@ and PatternValBinding = and TypedMatchClause = | TClause of Pattern * Expr option * DecisionTreeTarget * range -val ilFieldToTastConst: ILFieldInit -> Tast.Const +val ilFieldToTastConst: ILFieldInit -> Const /// Compile a pattern into a decision tree and a set of targets. val internal CompilePattern: TcGlobals -> DisplayEnv -> - Import.ImportMap -> + Import.ImportMap -> + // tcVal + (ValRef -> ValUseFlag -> TTypes -> range -> Expr * TType) -> + InfoReader -> // range of the expression we are matching on range -> // range to report "incomplete match" on @@ -70,5 +76,7 @@ val internal CompilePattern: DecisionTree * DecisionTreeTarget list exception internal MatchIncomplete of bool * (string * bool) option * range + exception internal RuleNeverMatched of range + exception internal EnumMatchIncomplete of bool * (string * bool) option * range \ No newline at end of file diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 2420e636d24..ad226c2b510 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -7,22 +7,25 @@ module internal FSharp.Compiler.PostTypeCheckSemanticChecks open System open System.Collections.Generic +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib +open FSharp.Compiler.Features open FSharp.Compiler.Infos -open FSharp.Compiler.PrettyNaming open FSharp.Compiler.InfoReader +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeRelations //-------------------------------------------------------------------------- @@ -63,6 +66,15 @@ open FSharp.Compiler.TypeRelations // check environment //-------------------------------------------------------------------------- +[] +type Resumable = + | None + /// Indicates we are expecting resumable code (the body of a ResumableCode delegate or + /// the body of the MoveNextMethod for a state machine) + /// -- allowed: are we inside the 'then' branch of an 'if __useResumableCode then ...' + /// for a ResumableCode delegate. + | ResumableExpr of allowed: bool + type env = { /// The bound type parameter names in scope @@ -94,9 +106,12 @@ type env = /// Are we in an app expression (Expr.App)? isInAppExpr: bool + + /// Are we expecting a resumable code block etc + resumableCode: Resumable } - override __.ToString() = "" + override _.ToString() = "" let BindTypar env (tp: Typar) = { env with @@ -213,9 +228,12 @@ type cenv = isInternalTestSpanStackReferring: bool // outputs - mutable usesQuotations : bool + mutable usesQuotations: bool - mutable entryPointGiven: bool } + mutable entryPointGiven: bool + + /// Callback required for quotation generation + tcVal: ConstraintSolver.TcValF } override x.ToString() = "" @@ -297,10 +315,9 @@ let BindVal cenv env (v: Val) = not (v.DisplayName.StartsWithOrdinal("_")) && not v.IsCompilerGenerated then - match v.BaseOrThisInfo with - | ValBaseOrThisInfo.CtorThisVal -> + if v.IsCtorThisVal then warning (Error(FSComp.SR.chkUnusedThisVariable v.DisplayName, v.Range)) - | _ -> + else warning (Error(FSComp.SR.chkUnusedValue v.DisplayName, v.Range)) let BindVals cenv env vs = List.iter (BindVal cenv env) vs @@ -313,7 +330,7 @@ let RecordAnonRecdInfo cenv (anonInfo: AnonRecdTypeInfo) = // approx walk of type //-------------------------------------------------------------------------- -let rec CheckTypeDeep (cenv: cenv) ((visitTy, visitTyconRefOpt, visitAppTyOpt, visitTraitSolutionOpt, visitTyparOpt) as f) (g: TcGlobals) env isInner ty = +let rec CheckTypeDeep (cenv: cenv) (visitTy, visitTyconRefOpt, visitAppTyOpt, visitTraitSolutionOpt, visitTyparOpt as f) (g: TcGlobals) env isInner ty = // We iterate the _solved_ constraints as well, to pick up any record of trait constraint solutions // This means we walk _all_ the constraints _everywhere_ in a type, including // those attached to _solved_ type variables. This is used by PostTypeCheckSemanticChecks to detect uses of @@ -325,7 +342,7 @@ let rec CheckTypeDeep (cenv: cenv) ((visitTy, visitTyconRefOpt, visitAppTyOpt, v | TType_var tp when tp.Solution.IsSome -> for cx in tp.Constraints do match cx with - | TyparConstraint.MayResolveMember((TTrait(_, _, _, _, _, soln)), _) -> + | TyparConstraint.MayResolveMember(TTrait(_, _, _, _, _, soln), _) -> match visitTraitSolutionOpt, !soln with | Some visitTraitSolution, Some sln -> visitTraitSolution sln | _ -> () @@ -402,7 +419,7 @@ and CheckTypeConstraintDeep cenv f g env x = | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> () -and CheckTraitInfoDeep cenv ((_, _, _, visitTraitSolutionOpt, _) as f) g env (TTrait(tys, _, _, argtys, rty, soln)) = +and CheckTraitInfoDeep cenv (_, _, _, visitTraitSolutionOpt, _ as f) g env (TTrait(tys, _, _, argtys, rty, soln)) = CheckTypesDeep cenv f g env tys CheckTypesDeep cenv f g env argtys Option.iter (CheckTypeDeep cenv f g env true ) rty @@ -433,7 +450,7 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit // Note that: Local mutables can be free, as they will be boxed later. // These checks must correspond to the tests governing the error messages below. - ((v.BaseOrThisInfo = BaseVal) || (isByrefLikeTy cenv.g m v.Type)) && + (v.IsBaseVal || isByrefLikeTy cenv.g m v.Type) && not (ListSet.contains valEq v syntacticArgs) let frees = freeInExpr CollectLocals body @@ -451,11 +468,11 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit // For safety, such functions are assumed to have no known arity, and so can not accept byrefs. errorR(Error(FSComp.SR.chkByrefUsedInInvalidWay(v.DisplayName), m)) - elif v.BaseOrThisInfo = BaseVal then + elif v.IsBaseVal then errorR(Error(FSComp.SR.chkBaseUsedInInvalidWay(), m)) else - (* Should be dead code, unless governing tests change *) + // Should be dead code, unless governing tests change errorR(InternalError(FSComp.SR.chkVariableUsedInInvalidWay(v.DisplayName), m)) Some frees else @@ -477,7 +494,7 @@ let CheckTypeForAccess (cenv: cenv) env objName valAcc m ty = let visitType ty = // We deliberately only check the fully stripped type for accessibility, // because references to private type abbreviations are permitted - match tryDestAppTy cenv.g ty with + match tryTcrefOfAppTy cenv.g ty with | ValueNone -> () | ValueSome tcref -> let thisCompPath = compPathOfCcu cenv.viewCcu @@ -493,14 +510,14 @@ let WarnOnWrongTypeForAccess (cenv: cenv) env objName valAcc m ty = let visitType ty = // We deliberately only check the fully stripped type for accessibility, // because references to private type abbreviations are permitted - match tryDestAppTy cenv.g ty with + match tryTcrefOfAppTy cenv.g ty with | ValueNone -> () | ValueSome tcref -> let thisCompPath = compPathOfCcu cenv.viewCcu let tyconAcc = tcref.Accessibility |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths if isLessAccessible tyconAcc valAcc then let errorText = FSComp.SR.chkTypeLessAccessibleThanType(tcref.DisplayName, (objName())) |> snd - let warningText = errorText + System.Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime() + let warningText = errorText + Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime() warning(AttributeChecking.ObsoleteWarning(warningText, m)) CheckTypeDeep cenv (visitType, None, None, None, None) cenv.g env false ty @@ -618,7 +635,7 @@ let CheckTypeAux permitByRefLike (cenv: cenv) env m ty onInnerByrefError = let visitAppTy (tcref, tinst) = if isByrefLikeTyconRef cenv.g m tcref then let visitType ty0 = - match tryDestAppTy cenv.g ty0 with + match tryTcrefOfAppTy cenv.g ty0 with | ValueNone -> () | ValueSome tcref2 -> if isByrefTyconRef cenv.g tcref2 then @@ -677,23 +694,62 @@ let CheckNoReraise cenv freesOpt (body: Expr) = /// Check if a function is a quotation splice operator let isSpliceOperator g v = valRefEq g v g.splice_expr_vref || valRefEq g v g.splice_raw_expr_vref -/// Check conditions associated with implementing multiple instantiations of a generic interface -let CheckMultipleInterfaceInstantiations cenv interfaces m = + +/// Examples: +/// I & I => ExactlyEqual. +/// I & I => NotEqual. +/// I & I<'T> => FeasiblyEqual. +/// with '[] type kg': I< int > & I => FeasiblyEqual. +/// with 'type MyInt = int': I & I => FeasiblyEqual. +/// +/// The differences could also be nested, example: +/// I> vs I> => FeasiblyEqual. +type TTypeEquality = + | ExactlyEqual + | FeasiblyEqual + | NotEqual + +let compareTypesWithRegardToTypeVariablesAndMeasures g amap m typ1 typ2 = + + if (typeEquiv g typ1 typ2) then + ExactlyEqual + else + if (typeEquiv g typ1 typ2 || TypesFeasiblyEquivStripMeasures g amap m typ1 typ2) then + FeasiblyEqual + else + NotEqual + +let CheckMultipleInterfaceInstantiations cenv (typ:TType) (interfaces:TType list) isObjectExpression m = let keyf ty = assert isAppTy cenv.g ty; (tcrefOfAppTy cenv.g ty).Stamp - let table = interfaces |> MultiMap.initBy keyf - let firstInterfaceWithMultipleGenericInstantiations = - interfaces |> List.tryPick (fun typ1 -> - table |> MultiMap.find (keyf typ1) |> List.tryPick (fun typ2 -> - if // same nominal type - tyconRefEq cenv.g (tcrefOfAppTy cenv.g typ1) (tcrefOfAppTy cenv.g typ2) && - // different instantiations - not (typeEquivAux EraseNone cenv.g typ1 typ2) - then Some (typ1, typ2) - else None)) - match firstInterfaceWithMultipleGenericInstantiations with + let groups = interfaces |> List.groupBy keyf + let errors = seq { + for _, items in groups do + for i1 in 0 .. items.Length - 1 do + for i2 in i1 + 1 .. items.Length - 1 do + let typ1 = items.[i1] + let typ2 = items.[i2] + let tcRef1 = tcrefOfAppTy cenv.g typ1 + match compareTypesWithRegardToTypeVariablesAndMeasures cenv.g cenv.amap m typ1 typ2 with + | ExactlyEqual -> () + | FeasiblyEqual -> + match tryLanguageFeatureErrorOption cenv.g.langVersion LanguageFeature.InterfacesWithMultipleGenericInstantiation m with + | None -> () + | Some e -> yield e + let typ1Str = NicePrint.minimalStringOfType cenv.denv typ1 + let typ2Str = NicePrint.minimalStringOfType cenv.denv typ2 + if isObjectExpression then + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariableObjectExpression(tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + else + let typStr = NicePrint.minimalStringOfType cenv.denv typ + yield (Error(FSComp.SR.typrelInterfaceWithConcreteAndVariable(typStr, tcRef1.DisplayNameWithStaticParametersAndUnderscoreTypars, typ1Str, typ2Str),m)) + | NotEqual -> + match tryLanguageFeatureErrorOption cenv.g.langVersion LanguageFeature.InterfacesWithMultipleGenericInstantiation m with + | None -> () + | Some e -> yield e + } + match Seq.tryHead errors with | None -> () - | Some (typ1, typ2) -> - errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)), m)) + | Some e -> errorR(e) /// Check an expression, where the expression is in a position where byrefs can be generated let rec CheckExprNoByrefs cenv env expr = @@ -708,6 +764,11 @@ and CheckValRef (cenv: cenv) (env: env) v m (context: PermitByRefExpr) = if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m)) if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m)) if valRefEq cenv.g v cenv.g.nameof_vref then errorR(Error(FSComp.SR.chkNoFirstClassNameOf(), m)) + if cenv.g.langVersion.SupportsFeature LanguageFeature.RefCellNotationInformationals then + if valRefEq cenv.g v cenv.g.refcell_deref_vref then informationalWarning(Error(FSComp.SR.chkInfoRefcellDeref(), m)) + if valRefEq cenv.g v cenv.g.refcell_assign_vref then informationalWarning(Error(FSComp.SR.chkInfoRefcellAssign(), m)) + if valRefEq cenv.g v cenv.g.refcell_incr_vref then informationalWarning(Error(FSComp.SR.chkInfoRefcellIncr(), m)) + if valRefEq cenv.g v cenv.g.refcell_decr_vref then informationalWarning(Error(FSComp.SR.chkInfoRefcellDecr(), m)) // ByRefLike-typed values can only occur in permitting contexts if context.Disallow && isByrefLikeTy cenv.g m v.Type then @@ -727,7 +788,7 @@ and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: Perm if cenv.reportErrors then - if vref.BaseOrThisInfo = BaseVal then + if vref.IsBaseVal then errorR(Error(FSComp.SR.chkLimitationsOfBaseKeyword(), m)) let isCallOfConstructorOfAbstractType = @@ -759,7 +820,7 @@ and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: Perm let isReturnOfStructThis = context.PermitOnlyReturnable && isByrefTy g vref.Type && - (vref.BaseOrThisInfo = MemberThisVal) + (vref.IsMemberThisVal) if isReturnOfStructThis then errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) @@ -798,7 +859,7 @@ and CheckForOverAppliedExceptionRaisingPrimitive (cenv: cenv) expr = | OptionalCoerce(Expr.Val (failwithfFunc, _, funcRange)) when valRefEq g failwithfFunc g.failwithf_vref -> match argsl with | Expr.App (Expr.Val (newFormat, _, _), _, [_; typB; typC; _; _], [Expr.Const (Const.String formatString, formatRange, _)], _) :: xs when valRefEq g newFormat g.new_format_vref -> - match CheckFormatStrings.TryCountFormatStringArguments formatRange g formatString typB typC with + match CheckFormatStrings.TryCountFormatStringArguments formatRange g false formatString typB typC with | Some n -> let expected = n + 1 let actual = List.length xs + 1 @@ -903,7 +964,7 @@ and CheckExprLinear (cenv: cenv) (env: env) expr (context: PermitByRefExpr) (con // tailcall CheckExprLinear cenv env e2 context contf - | Expr.Let ((TBind(v, _bindRhs, _) as bind), body, _, _) -> + | Expr.Let (TBind(v, _bindRhs, _) as bind, body, _, _) -> let isByRef = isByrefTy cenv.g v.Type let bindingContext = @@ -935,6 +996,99 @@ and CheckExprLinear (cenv: cenv) (env: env) expr (context: PermitByRefExpr) (con // not a linear expression contf (CheckExpr cenv env expr context) +/// Check a resumable code expression (the body of a ResumableCode delegate or +/// the body of the MoveNextMethod for a state machine) +and TryCheckResumableCodeConstructs cenv env expr : bool = + let g = cenv.g + + match env.resumableCode with + | Resumable.None -> + CheckNoResumableStmtConstructs cenv env expr + false + | Resumable.ResumableExpr allowed -> + match expr with + | IfUseResumableStateMachinesExpr g (thenExpr, elseExpr) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.ResumableExpr true } thenExpr + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } elseExpr + true + + | ResumableEntryMatchExpr g (noneBranchExpr, someVar, someBranchExpr, _rebuild) -> + if not allowed then + errorR(Error(FSComp.SR.tcInvalidResumableConstruct("__resumableEntry"), expr.Range)) + CheckExprNoByrefs cenv env noneBranchExpr + BindVal cenv env someVar + CheckExprNoByrefs cenv env someBranchExpr + true + + | ResumeAtExpr g pcExpr -> + if not allowed then + errorR(Error(FSComp.SR.tcInvalidResumableConstruct("__resumeAt"), expr.Range)) + CheckExprNoByrefs cenv env pcExpr + true + + | ResumableCodeInvoke g (_, f, args, _, _) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } f + for arg in args do + CheckExprPermitByRefLike cenv { env with resumableCode = Resumable.None } arg |> ignore + true + + | SequentialResumableCode g (e1, e2, _m, _recreate) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.ResumableExpr allowed }e1 + CheckExprNoByrefs cenv env e2 + true + + | WhileExpr (_sp1, _sp2, guardExpr, bodyExpr, _m) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } guardExpr + CheckExprNoByrefs cenv env bodyExpr + true + + // Integer for-loops are allowed but their bodies are not currently resumable + | ForLoopExpr (_sp1, _sp2, e1, e2, v, e3, _m) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } e1 + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } e2 + BindVal cenv env v + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } e3 + true + + | TryWithExpr (_spTry, _spWith, _resTy, bodyExpr, _filterVar, filterExpr, _handlerVar, handlerExpr, _m) -> + CheckExprNoByrefs cenv env bodyExpr + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } handlerExpr + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } filterExpr + true + + | TryFinallyExpr (_sp1, _sp2, _ty, e1, e2, _m) -> + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } e1 + CheckExprNoByrefs cenv { env with resumableCode = Resumable.None } e2 + true + + | Expr.Match (_spBind, _exprm, dtree, targets, _m, _ty) -> + targets |> Array.iter(fun (TTarget(vs, targetExpr, _spTarget, _)) -> + BindVals cenv env vs + CheckExprNoByrefs cenv env targetExpr) + CheckDecisionTree cenv { env with resumableCode = Resumable.None } dtree + true + + | Expr.Let (bind, bodyExpr, _m, _) + // Restriction: resumable code can't contain local constrained generic functions + when bind.Var.IsCompiledAsTopLevel || not (IsGenericValWithGenericConstraints g bind.Var) -> + CheckBinding cenv { env with resumableCode = Resumable.None } false PermitByRefExpr.Yes bind |> ignore + BindVal cenv env bind.Var + CheckExprNoByrefs cenv env bodyExpr + true + + // LetRec bindings may not appear as part of resumable code (more careful work is needed to make them compilable) + | Expr.LetRec(_bindings, bodyExpr, _range, _frees) when allowed -> + errorR(Error(FSComp.SR.tcResumableCodeContainsLetRec(), expr.Range)) + CheckExprNoByrefs cenv env bodyExpr + true + + // This construct arises from the 'mkDefault' in the 'Throw' case of an incomplete pattern match + | Expr.Const (Const.Zero, _, _) -> + true + + | _ -> + false + /// Check an expression, given information about the position of the expression and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limit = let g = cenv.g @@ -946,6 +1100,15 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi let expr = NormalizeAndAdjustPossibleSubsumptionExprs g origExpr let expr = stripExpr expr + match TryCheckResumableCodeConstructs cenv env expr with + | true -> + // we've handled the special cases of resumable code and don't do other checks. + NoLimit + | false -> + + // Handle ResumableExpr --> other expression + let env = { env with resumableCode = Resumable.None } + match expr with | LinearOpExpr _ | LinearMatchExpr _ @@ -970,13 +1133,18 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi if cenv.reportErrors then cenv.usesQuotations <- true - // Translate to quotation data + // Translate the quotation to quotation data try - let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) - let qdata = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast - let typeDefs, spliceTypes, spliceExprs = qscope.Close() + let doData suppressWitnesses = + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, cenv.tcVal, QuotationTranslator.IsReflectedDefinition.No) + let qdata = QuotationTranslator.ConvExprPublic qscope suppressWitnesses ast + let typeDefs, spliceTypes, spliceExprs = qscope.Close() + typeDefs, List.map fst spliceTypes, List.map fst spliceExprs, qdata + + let data1 = doData true + let data2 = doData false match savedConv.Value with - | None -> savedConv:= Some (typeDefs, List.map fst spliceTypes, List.map fst spliceExprs, qdata) + | None -> savedConv:= Some (data1, data2) | Some _ -> () with QuotationTranslator.InvalidQuotedTerm e -> errorRecovery e m @@ -984,26 +1152,39 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi CheckTypeNoByrefs cenv env m ty NoLimit + | StructStateMachineExpr g (_dataTy, + (moveNextThisVar, moveNextExpr), + (setStateMachineThisVar, setStateMachineStateVar, setStateMachineBody), + (afterCodeThisVar, afterCodeBody)) -> + if not (g.langVersion.SupportsFeature LanguageFeature.ResumableStateMachines) then + error(Error(FSComp.SR.tcResumableCodeNotSupported(), expr.Range)) + + BindVals cenv env [moveNextThisVar; setStateMachineThisVar; setStateMachineStateVar; afterCodeThisVar] + CheckExprNoByrefs cenv { env with resumableCode = Resumable.ResumableExpr true } moveNextExpr + CheckExprNoByrefs cenv env setStateMachineBody + CheckExprNoByrefs cenv env afterCodeBody + NoLimit + | Expr.Obj (_, ty, basev, superInitCall, overrides, iimpls, m) -> CheckExprNoByrefs cenv env superInitCall - CheckMethods cenv env basev overrides + CheckMethods cenv env basev (ty, overrides) CheckInterfaceImpls cenv env basev iimpls CheckTypeNoByrefs cenv env m ty let interfaces = [ if isInterfaceTy g ty then yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty - for (ty, _) in iimpls do + for ty, _ in iimpls do yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] |> List.filter (isInterfaceTy g) - CheckMultipleInterfaceInstantiations cenv interfaces m + CheckMultipleInterfaceInstantiations cenv ty interfaces true m NoLimit // Allow base calls to F# methods - | Expr.App ((InnerExprPat(ExprValWithPossibleTypeInst(v, vFlags, _, _) as f)), _fty, tyargs, (Expr.Val (baseVal, _, _) :: rest), m) + | Expr.App (InnerExprPat(ExprValWithPossibleTypeInst(v, vFlags, _, _) as f), _fty, tyargs, Expr.Val (baseVal, _, _) :: rest, m) when ((match vFlags with VSlotDirectCall -> true | _ -> false) && - baseVal.BaseOrThisInfo = BaseVal) -> + baseVal.IsBaseVal) -> let memberInfo = Option.get v.MemberInfo if memberInfo.MemberFlags.IsDispatchSlot then @@ -1020,27 +1201,27 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi CheckExprs cenv env rest (mkArgsForAppliedExpr true rest f) // Allow base calls to IL methods - | Expr.Op (TOp.ILCall (virt, _, _, _, _, _, _, mref, enclTypeArgs, methTypeArgs, tys), tyargs, (Expr.Val (baseVal, _, _) :: rest), m) - when not virt && baseVal.BaseOrThisInfo = BaseVal -> + | Expr.Op (TOp.ILCall (isVirtual, _, _, _, _, _, _, ilMethRef, enclTypeInst, methInst, retTypes), tyargs, Expr.Val (baseVal, _, _) :: rest, m) + when not isVirtual && baseVal.IsBaseVal -> // Disallow calls to abstract base methods on IL types. - match tryDestAppTy g baseVal.Type with + match tryTcrefOfAppTy g baseVal.Type with | ValueSome tcref when tcref.IsILTycon -> try // This is awkward - we have to explicitly re-resolve back to the IL metadata to determine if the method is abstract. // We believe this may be fragile in some situations, since we are using the Abstract IL code to compare // type equality, and it would be much better to remove any F# dependency on that implementation of IL type // equality. It would be better to make this check in tc.fs when we have the Abstract IL metadata for the method to hand. - let mdef = resolveILMethodRef tcref.ILTyconRawMetadata mref + let mdef = resolveILMethodRef tcref.ILTyconRawMetadata ilMethRef if mdef.IsAbstract then errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(mdef.Name), m)) with _ -> () // defensive coding | _ -> () CheckTypeInstNoByrefs cenv env m tyargs - CheckTypeInstNoByrefs cenv env m enclTypeArgs - CheckTypeInstNoByrefs cenv env m methTypeArgs - CheckTypeInstNoByrefs cenv env m tys + CheckTypeInstNoByrefs cenv env m enclTypeInst + CheckTypeInstNoByrefs cenv env m methInst + CheckTypeInstNoByrefs cenv env m retTypes CheckValRef cenv env baseVal m PermitByRefExpr.No CheckExprsPermitByRefLike cenv env rest @@ -1063,6 +1244,11 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi // Check an application | Expr.App (f, _fty, tyargs, argsl, m) -> + match expr with + | ResumableCodeInvoke g _ -> + warning(Error(FSComp.SR.tcResumableCodeInvocation(), m)) + | _ -> () + let returnTy = tyOfExpr g expr // This is to handle recursive cases. Don't check 'returnTy' again if we are still inside a app expression. @@ -1122,16 +1308,27 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi CheckTypeNoByrefs cenv env m ty1) NoLimit + | Expr.WitnessArg _ -> + NoLimit + | Expr.Link _ -> failwith "Unexpected reclink" -and CheckMethods cenv env baseValOpt methods = - methods |> List.iter (CheckMethod cenv env baseValOpt) +and CheckMethods cenv env baseValOpt (ty, methods) = + methods |> List.iter (CheckMethod cenv env baseValOpt ty) -and CheckMethod cenv env baseValOpt (TObjExprMethod(_, attribs, tps, vs, body, m)) = +and CheckMethod cenv env baseValOpt ty (TObjExprMethod(_, attribs, tps, vs, body, m)) = let env = BindTypars cenv.g env tps let vs = List.concat vs let env = BindArgVals env vs + let env = + // Body of ResumableCode delegate + if isResumableCodeTy cenv.g ty then + if not (cenv.g.langVersion.SupportsFeature LanguageFeature.ResumableStateMachines) then + error(Error(FSComp.SR.tcResumableCodeNotSupported(), m)) + { env with resumableCode = Resumable.ResumableExpr false } + else + { env with resumableCode = Resumable.None } CheckAttribs cenv env attribs CheckNoReraise cenv None body CheckEscapes cenv true m (match baseValOpt with Some x -> x :: vs | None -> vs) body |> ignore @@ -1140,11 +1337,22 @@ and CheckMethod cenv env baseValOpt (TObjExprMethod(_, attribs, tps, vs, body, m and CheckInterfaceImpls cenv env baseValOpt l = l |> List.iter (CheckInterfaceImpl cenv env baseValOpt) -and CheckInterfaceImpl cenv env baseValOpt (_ty, overrides) = +and CheckInterfaceImpl cenv env baseValOpt overrides = CheckMethods cenv env baseValOpt overrides +and CheckNoResumableStmtConstructs cenv _env expr = + let g = cenv.g + match expr with + | Expr.Val (v, _, m) + when valRefEq g v g.cgh__resumeAt_vref || + valRefEq g v g.cgh__resumableEntry_vref || + valRefEq g v g.cgh__stateMachine_vref -> + errorR(Error(FSComp.SR.tcInvalidResumableConstruct(v.DisplayName), m)) + | _ -> () + and CheckExprOp cenv env (op, tyargs, args, m) context expr = let g = cenv.g + let ctorLimitedZoneCheck() = if env.ctorLimitedZone then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) @@ -1173,7 +1381,7 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByRefLike cenv env [e1;e2;e3] - | TOp.TryCatch _, [_], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], _e2, _, _); Expr.Lambda (_, _, _, [_], e3, _, _)] -> + | TOp.TryWith _, [_], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], _e2, _, _); Expr.Lambda (_, _, _, [_], e3, _, _)] -> CheckTypeInstNoInnerByrefs cenv env m tyargs // result of a try/catch can be a byref ctorLimitedZoneCheck() let limit1 = CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref @@ -1181,21 +1389,21 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = let limit2 = CheckExpr cenv env e3 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref CombineTwoLimits limit1 limit2 - | TOp.ILCall (_, _, _, _, _, _, _, methRef, enclTypeArgs, methTypeArgs, tys), _, _ -> + | TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, enclTypeInst, methInst, retTypes), _, _ -> CheckTypeInstNoByrefs cenv env m tyargs - CheckTypeInstNoByrefs cenv env m enclTypeArgs - CheckTypeInstNoByrefs cenv env m methTypeArgs - CheckTypeInstNoInnerByrefs cenv env m tys // permit byref returns + CheckTypeInstNoByrefs cenv env m enclTypeInst + CheckTypeInstNoByrefs cenv env m methInst + CheckTypeInstNoInnerByrefs cenv env m retTypes // permit byref returns let hasReceiver = - (methRef.CallingConv.IsInstance || methRef.CallingConv.IsInstanceExplicit) && + (ilMethRef.CallingConv.IsInstance || ilMethRef.CallingConv.IsInstanceExplicit) && not args.IsEmpty let returnTy = tyOfExpr g expr let argContexts = List.init args.Length (fun _ -> PermitByRefExpr.Yes) - match tys with + match retTypes with | [ty] when context.PermitOnlyReturnable && isByrefLikeTy g m ty -> if hasReceiver then CheckCallWithReceiver cenv env m returnTy args argContexts context @@ -1299,7 +1507,7 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = NoLimit | TOp.Coerce, [tgty;srcty], [x] -> - if TypeRelations.TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgty srcty then + if TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgty srcty then CheckExpr cenv env x context else CheckTypeInstNoByrefs cenv env m tyargs @@ -1328,7 +1536,7 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = // C# applies a rule where the APIs to struct types can't return the addresses of fields in that struct. // There seems no particular reason for this given that other protections in the language, though allowing // it would mean "readonly" on a struct doesn't imply immutability-of-contents - it only implies - if context.PermitOnlyReturnable && (match obj with Expr.Val (vref, _, _) -> vref.BaseOrThisInfo = MemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then + if context.PermitOnlyReturnable && (match obj with Expr.Val (vref, _, _) -> vref.IsMemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then @@ -1353,7 +1561,7 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) - if context.PermitOnlyReturnable && (match obj with Expr.Val (vref, _, _) -> vref.BaseOrThisInfo = MemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then + if context.PermitOnlyReturnable && (match obj with Expr.Val (vref, _, _) -> vref.IsMemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) CheckTypeInstNoByrefs cenv env m tyargs @@ -1361,8 +1569,8 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = // Recursively check in same context, e.g. if at PermitOnlyReturnable the obj arg must also be returnable CheckExpr cenv env obj context - | TOp.ILAsm (instrs, tys), _, _ -> - CheckTypeInstNoInnerByrefs cenv env m tys + | TOp.ILAsm (instrs, retTypes), _, _ -> + CheckTypeInstNoInnerByrefs cenv env m retTypes CheckTypeInstNoByrefs cenv env m tyargs match instrs, args with // Write a .NET instance field @@ -1414,7 +1622,7 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = // allow args to be byref here CheckExprsPermitByRefLike cenv env args - | TOp.Recd (_, _), _, _ -> + | TOp.Recd _, _, _ -> CheckTypeInstNoByrefs cenv env m tyargs CheckExprsPermitByRefLike cenv env args @@ -1422,18 +1630,20 @@ and CheckExprOp cenv env (op, tyargs, args, m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByRefLike cenv env args -and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e mOrig ety context = +and CheckLambdas isTop (memberVal: Val option) cenv env inlined topValInfo alwaysCheckNoReraise expr mOrig ety context = let g = cenv.g + let memInfo = memberVal |> Option.bind (fun v -> v.MemberInfo) + // The topValInfo here says we are _guaranteeing_ to compile a function value // as a .NET method with precisely the corresponding argument counts. - match e with + match expr with | Expr.TyChoose (tps, e1, m) -> let env = BindTypars g env tps - CheckLambdas isTop memInfo cenv env inlined topValInfo alwaysCheckNoReraise e1 m ety context + CheckLambdas isTop memberVal cenv env inlined topValInfo alwaysCheckNoReraise e1 m ety context | Expr.Lambda (_, _, _, _, _, m, _) | Expr.TyLambda (_, _, _, m, _) -> - let tps, ctorThisValOpt, baseValOpt, vsl, body, bodyty = destTopLambda g cenv.amap topValInfo (e, ety) in + let tps, ctorThisValOpt, baseValOpt, vsl, body, bodyty = destTopLambda g cenv.amap topValInfo (expr, ety) let env = BindTypars g env tps let thisAndBase = Option.toList ctorThisValOpt @ Option.toList baseValOpt let restArgs = List.concat vsl @@ -1461,6 +1671,9 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check argument types syntacticArgs |> List.iter (fun arg -> + if arg.InlineIfLambda && (not inlined || not (isFunTy g arg.Type || isFSharpDelegateTy g arg.Type)) then + errorR(Error(FSComp.SR.tcInlineIfLambdaUsedOnNonInlineFunctionOrMethod(), arg.Range)) + CheckValSpecAux permitByRefType cenv env arg (fun () -> if arg.IsCompilerGenerated then errorR(Error(FSComp.SR.chkErrorUseOfByref(), arg.Range)) @@ -1515,13 +1728,13 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn let limit = if not inlined && (isByrefLikeTy g m ety || isNativePtrTy g ety) then // allow byref to occur as RHS of byref binding. - CheckExpr cenv env e context + CheckExpr cenv env expr context else - CheckExprNoByrefs cenv env e + CheckExprNoByrefs cenv env expr NoLimit if alwaysCheckNoReraise then - CheckNoReraise cenv None e + CheckNoReraise cenv None expr limit and CheckExprs cenv env exprs contexts : Limit = @@ -1535,7 +1748,7 @@ and CheckExprsNoByRefLike cenv env exprs : Limit = exprs |> List.iter (CheckExprNoByrefs cenv env) NoLimit -and CheckExprsPermitByRefLike cenv env exprs = +and CheckExprsPermitByRefLike cenv env exprs : Limit = exprs |> List.map (CheckExprPermitByRefLike cenv env) |> CombineLimits @@ -1556,7 +1769,7 @@ and CheckDecisionTreeTargets cenv env targets context = |> Array.map (CheckDecisionTreeTarget cenv env context) |> (CombineLimits << List.ofArray) -and CheckDecisionTreeTarget cenv env context (TTarget(vs, e, _)) = +and CheckDecisionTreeTarget cenv env context (TTarget(vs, e, _, _)) = BindVals cenv env vs vs |> List.iter (CheckValSpec PermitByRefType.All cenv env) CheckExpr cenv env e context @@ -1568,7 +1781,7 @@ and CheckDecisionTree cenv env x = | TDBind(bind, rest) -> CheckBinding cenv env false PermitByRefExpr.Yes bind |> ignore CheckDecisionTree cenv env rest - | TDSwitch (e, cases, dflt, m) -> + | TDSwitch (_, e, cases, dflt, m) -> CheckDecisionTreeSwitch cenv env (e, cases, dflt, m) and CheckDecisionTreeSwitch cenv env (e, cases, dflt, m) = @@ -1583,9 +1796,12 @@ and CheckDecisionTreeTest cenv env m discrim = | DecisionTreeTest.Const _ -> () | DecisionTreeTest.IsNull -> () | DecisionTreeTest.IsInst (srcTy, tgtTy) -> CheckTypeNoInnerByrefs cenv env m srcTy; CheckTypeNoInnerByrefs cenv env m tgtTy - | DecisionTreeTest.ActivePatternCase (exp, _, _, _, _) -> CheckExprNoByrefs cenv env exp + | DecisionTreeTest.ActivePatternCase (exp, _, _, _, _, _) -> CheckExprNoByrefs cenv env exp + | DecisionTreeTest.Error _ -> () -and CheckAttrib cenv env (Attrib(_, _, args, props, _, _, _)) = +and CheckAttrib cenv env (Attrib(tcref, _, args, props, _, _, m)) = + if List.exists (tyconRefEq cenv.g tcref) cenv.g.attribs_Unsupported then + warning(Error(FSComp.SR.unsupportedAttribute(), m)) props |> List.iter (fun (AttribNamedArg(_, _, _, expr)) -> CheckAttribExpr cenv env expr) args |> List.iter (CheckAttribExpr cenv env) @@ -1640,21 +1856,24 @@ and CheckAttribArgExpr cenv env expr = and CheckAttribs cenv env (attribs: Attribs) = if isNil attribs then () else - let tcrefs = [ for (Attrib(tcref, _, _, _, _, _, m)) in attribs -> (tcref, m) ] + let tcrefs = [ for Attrib(tcref, _, _, _, gs, _, m) in attribs -> (tcref, gs, m) ] // Check for violations of allowMultiple = false let duplicates = tcrefs - |> Seq.groupBy (fun (tcref, _) -> tcref.Stamp) + |> Seq.groupBy (fun (tcref, gs, _) -> + // Don't allow CompiledNameAttribute on both a property and its getter/setter (see E_CompiledName test) + if tyconRefEq cenv.g cenv.g.attrib_CompiledNameAttribute.TyconRef tcref then (tcref.Stamp, false) else + (tcref.Stamp, gs)) |> Seq.map (fun (_, elems) -> List.last (List.ofSeq elems), Seq.length elems) |> Seq.filter (fun (_, count) -> count > 1) |> Seq.map fst |> Seq.toList // Filter for allowMultiple = false - |> List.filter (fun (tcref, m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> Some true) + |> List.filter (fun (tcref, _, m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> Some true) if cenv.reportErrors then - for (tcref, m) in duplicates do + for tcref, _, m in duplicates do errorR(Error(FSComp.SR.chkAttrHasAllowMultiFalse(tcref.DisplayName), m)) attribs |> List.iter (CheckAttrib cenv env) @@ -1684,6 +1903,7 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = access and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as bind) : Limit = + let vref = mkLocalValRef v let g = cenv.g let isTop = Option.isSome bind.Var.ValReprInfo //printfn "visiting %s..." v.DisplayName @@ -1691,9 +1911,9 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as let env = { env with external = env.external || g.attrib_DllImportAttribute |> Option.exists (fun attr -> HasFSharpAttribute g attr v.Attribs) } // Check that active patterns don't have free type variables in their result - match TryGetActivePatternInfo (mkLocalValRef v) with + match TryGetActivePatternInfo vref with | Some _apinfo when _apinfo.ActiveTags.Length > 1 -> - if doesActivePatternHaveFreeTypars g (mkLocalValRef v) then + if doesActivePatternHaveFreeTypars g vref then errorR(Error(FSComp.SR.activePatternChoiceHasFreeTypars(v.LogicalName), v.Range)) | _ -> () @@ -1710,7 +1930,7 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as // Check accessibility if (v.IsMemberOrModuleBinding || v.IsMember) && not v.IsIncrClassGeneratedMember then let access = AdjustAccess (IsHiddenVal env.sigToImplRemapInfo v) (fun () -> v.TopValDeclaringEntity.CompilationPath) v.Accessibility - CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access v.Range v.Type + CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv cenv.infoReader vref) access v.Range v.Type let env = if v.IsConstructor && not v.IsIncrClassConstructor then { env with ctorLimitedZone=true } else env @@ -1747,23 +1967,19 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as match v.ReflectedDefinition with | None -> v.SetValDefn bindRhs | Some _ -> () + // Run the conversion process over the reflected definition to report any errors in the // front end rather than the back end. We currently re-run this during ilxgen.fs but there's // no real need for that except that it helps us to bundle all reflected definitions up into // one blob for pickling to the binary format try - let ety = tyOfExpr g bindRhs - let tps, taue, _ = - match bindRhs with - | Expr.TyLambda (_, tps, b, _, _) -> tps, b, applyForallTy g ety (List.map mkTyparTy tps) - | _ -> [], bindRhs, ety - let env = QuotationTranslator.QuotationTranslationEnv.Empty.BindTypars tps - let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes) - QuotationTranslator.ConvExprPublic qscope env taue |> ignore - let _, _, argExprs = qscope.Close() - if not (isNil argExprs) then + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, cenv.tcVal, QuotationTranslator.IsReflectedDefinition.Yes) + let methName = v.CompiledName g.CompilerGlobalState + QuotationTranslator.ConvReflectedDefinition qscope methName v bindRhs |> ignore + + let _, _, exprSplices = qscope.Close() + if not (isNil exprSplices) then errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), v.Range)) - QuotationTranslator.ConvMethodBase qscope env (v.CompiledName g.CompilerGlobalState, v) |> ignore with | QuotationTranslator.InvalidQuotedTerm e -> errorR e @@ -1771,7 +1987,7 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as match v.MemberInfo with | Some memberInfo when not v.IsIncrClassGeneratedMember -> match memberInfo.MemberFlags.MemberKind with - | (MemberKind.PropertySet | MemberKind.PropertyGet) -> + | SynMemberKind.PropertySet | SynMemberKind.PropertyGet -> // These routines raise errors for ill-formed properties v |> ReturnTypeOfPropertyVal g |> ignore v |> ArgInfosOfPropertyVal g |> ignore @@ -1782,7 +1998,23 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as let topValInfo = match bind.Var.ValReprInfo with Some info -> info | _ -> ValReprInfo.emptyValData - CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs v.Range v.Type context + // If the method has ResumableCode argument or return type it must be inline + // unless warning is suppressed (user must know what they're doing). + // + // If the method has ResumableCode return attribute we check the body w.r.t. that + let env = + if cenv.reportErrors && isReturnsResumableCodeTy g v.TauType then + if not (g.langVersion.SupportsFeature LanguageFeature.ResumableStateMachines) then + error(Error(FSComp.SR.tcResumableCodeNotSupported(), bind.Var.Range)) + if not v.MustInline then + warning(Error(FSComp.SR.tcResumableCodeFunctionMustBeInline(), v.Range)) + + if isReturnsResumableCodeTy g v.TauType then + { env with resumableCode = Resumable.ResumableExpr false } + else + env + + CheckLambdas isTop (Some v) cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs v.Range v.Type context and CheckBindings cenv env xs = xs |> List.iter (CheckBinding cenv env false PermitByRefExpr.Yes >> ignore) @@ -1863,7 +2095,8 @@ let CheckModuleBinding cenv env (TBind(v, e, _) as bind) = if tcref.UnionCasesArray.Length = 1 && hasNoArgs then let ucase1 = tcref.UnionCasesArray.[0] for f in ucase1.RecdFieldsArray do - if f.Name = nm then error(NameClash(nm, kind, v.DisplayName, v.Range, FSComp.SR.typeInfoGeneratedProperty(), f.Name, ucase1.Range)) + if f.LogicalName = nm then + error(NameClash(nm, kind, v.DisplayName, v.Range, FSComp.SR.typeInfoGeneratedProperty(), f.LogicalName, ucase1.Range)) // Default augmentation contains the nasty 'Case' etc. let prefix = "New" @@ -1880,10 +2113,10 @@ let CheckModuleBinding cenv env (TBind(v, e, _) as bind) = | None -> () match tcref.GetFieldByName nm with - | Some rf -> error(NameClash(nm, kind, v.DisplayName, v.Range, "field", rf.Name, rf.Range)) + | Some rf -> error(NameClash(nm, kind, v.DisplayName, v.Range, "field", rf.LogicalName, rf.Range)) | None -> () - check false v.CoreDisplayName + check false v.DisplayNameCoreMangled check false v.DisplayName check false (v.CompiledName cenv.g.CompilerGlobalState) @@ -1926,11 +2159,11 @@ let CheckRecdField isUnion cenv env (tycon: Tycon) (rfield: RecdField) = let m = rfield.Range let fieldTy = stripTyEqns cenv.g rfield.FormalType let isHidden = - IsHiddenTycon cenv.g env.sigToImplRemapInfo tycon || - IsHiddenTyconRepr cenv.g env.sigToImplRemapInfo tycon || + IsHiddenTycon env.sigToImplRemapInfo tycon || + IsHiddenTyconRepr env.sigToImplRemapInfo tycon || (not isUnion && IsHiddenRecdField env.sigToImplRemapInfo (tcref.MakeNestedRecdFieldRef rfield)) let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility - CheckTypeForAccess cenv env (fun () -> rfield.Name) access m fieldTy + CheckTypeForAccess cenv env (fun () -> rfield.LogicalName) access m fieldTy if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref then // Permit Span fields in IsByRefLike types @@ -1994,7 +2227,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = // precompute methods grouped by MethInfo.LogicalName let hashOfImmediateMeths = - let h = new Dictionary() + let h = Dictionary() for minfo in immediateMeths do match h.TryGetValue minfo.LogicalName with | true, methods -> @@ -2008,11 +2241,11 @@ let CheckEntityDefn cenv env (tycon: Entity) = let methods = hashOfImmediateMeths.[minfo.LogicalName] for m in methods do // use referential identity to filter out 'minfo' method - if not(System.Object.ReferenceEquals(m, minfo)) then + if not(Object.ReferenceEquals(m, minfo)) then yield m ] - let hashOfImmediateProps = new Dictionary() + let hashOfImmediateProps = Dictionary() for minfo in immediateMeths do let nm = minfo.LogicalName let m = (match minfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange) @@ -2102,8 +2335,8 @@ let CheckEntityDefn cenv env (tycon: Entity) = if ( (pinfo.HasGetter && pinfo.HasSetter && - let setterArgs = pinfo.DropGetter.GetParamTypes(cenv.amap, m) - let getterArgs = pinfo.DropSetter.GetParamTypes(cenv.amap, m) + let setterArgs = pinfo.DropGetter().GetParamTypes(cenv.amap, m) + let getterArgs = pinfo.DropSetter().GetParamTypes(cenv.amap, m) setterArgs.Length <> getterArgs.Length) || (let nargs = pinfo.GetParamTypes(cenv.amap, m).Length @@ -2114,15 +2347,15 @@ let CheckEntityDefn cenv env (tycon: Entity) = // Check to see if the signatures of the both getter and the setter imply the same property type if pinfo.HasGetter && pinfo.HasSetter && not pinfo.IsIndexer then - let ty1 = pinfo.DropSetter.GetPropertyType(cenv.amap, m) - let ty2 = pinfo.DropGetter.GetPropertyType(cenv.amap, m) + let ty1 = pinfo.DropSetter().GetPropertyType(cenv.amap, m) + let ty2 = pinfo.DropGetter().GetPropertyType(cenv.amap, m) if not (typeEquivAux EraseNone cenv.amap.g ty1 ty2) then errorR(Error(FSComp.SR.chkGetterAndSetterHaveSamePropertyType(pinfo.PropertyName, NicePrint.minimalStringOfType cenv.denv ty1, NicePrint.minimalStringOfType cenv.denv ty2), m)) hashOfImmediateProps.[nm] <- pinfo :: others if not (isInterfaceTy g ty) then - let hashOfAllVirtualMethsInParent = new Dictionary() + let hashOfAllVirtualMethsInParent = Dictionary() for minfo in allVirtualMethsInParent do let nm = minfo.LogicalName let others = getHash hashOfAllVirtualMethsInParent nm @@ -2136,7 +2369,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = match parentMethsOfSameName |> List.tryFind (checkForDup EraseAll) with | None -> () | Some minfo -> - let mtext = NicePrint.stringOfMethInfo cenv.amap m cenv.denv minfo + let mtext = NicePrint.stringOfMethInfo cenv.infoReader m cenv.denv minfo if parentMethsOfSameName |> List.exists (checkForDup EraseNone) then warning(Error(FSComp.SR.tcNewMemberHidesAbstractMember mtext, m)) else @@ -2161,7 +2394,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = if TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref && not tycon.IsStructOrEnumTycon then errorR(Error(FSComp.SR.tcIsReadOnlyNotStruct(), tycon.Range)) - // Considers TFSharpObjectRepr, TRecdRepr and TUnionRepr. + // Considers TFSharpObjectRepr, TFSharpRecdRepr and TFSharpUnionRepr. // [Review] are all cases covered: TILObjectRepr, TAsmRepr. [Yes - these are FSharp.Core.dll only] tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon) @@ -2172,10 +2405,9 @@ let CheckEntityDefn cenv env (tycon: Entity) = let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m let env = BindTypars g env tps for argtys in argtysl do - for (argty, _) in argtys do + for argty, _ in argtys do CheckTypeNoInnerByrefs cenv env vref.Range argty CheckTypeNoInnerByrefs cenv env vref.Range rty - | None -> () // Supported interface may not have byrefs @@ -2189,7 +2421,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = uc.RecdFieldsArray |> Array.iter (CheckRecdField true cenv env tycon)) // Access checks - let access = AdjustAccess (IsHiddenTycon g env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility + let access = AdjustAccess (IsHiddenTycon env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility let visitType ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType) @@ -2202,7 +2434,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = match tycon.TypeReprInfo with | TFSharpObjectRepr r -> match r.fsobjmodel_kind with - | TTyconDelegate ss -> + | TFSharpDelegate ss -> //ss.ClassTypars //ss.MethodTypars ss.FormalReturnType |> Option.iter visitType @@ -2223,11 +2455,11 @@ let CheckEntityDefn cenv env (tycon: Entity) = if cenv.reportErrors then if not tycon.IsTypeAbbrev then - let immediateInterfaces = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m ty - let interfaces = - [ for ty in immediateInterfaces do - yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] - CheckMultipleInterfaceInstantiations cenv interfaces m + let interfaces = + GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m ty + |> List.collect (AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes) + |> List.filter (isInterfaceTy g) + CheckMultipleInterfaceInstantiations cenv ty interfaces false m // Check struct fields. We check these late because we have to have first checked that the structs are // free of cycles @@ -2257,7 +2489,7 @@ let CheckEntityDefns cenv env tycons = let rec CheckModuleExpr cenv env x = match x with | ModuleOrNamespaceExprWithSig(mty, def, _) -> - let (rpi, mhi) = ComputeRemappingFromImplementationToSignature cenv.g def mty + let rpi, mhi = ComputeRemappingFromImplementationToSignature cenv.g def mty let env = { env with sigToImplRemapInfo = (mkRepackageRemapping rpi, mhi) :: env.sigToImplRemapInfo } CheckDefnInModule cenv env def @@ -2270,7 +2502,7 @@ and CheckNothingAfterEntryPoint cenv m = and CheckDefnInModule cenv env x = match x with - | TMDefRec(isRec, tycons, mspecs, m) -> + | TMDefRec(isRec, _opens, tycons, mspecs, m) -> CheckNothingAfterEntryPoint cenv m if isRec then BindVals cenv env (allValsOfModDef x |> Seq.toList) CheckEntityDefns cenv env tycons @@ -2279,6 +2511,8 @@ and CheckDefnInModule cenv env x = CheckNothingAfterEntryPoint cenv m CheckModuleBinding cenv env bind BindVal cenv env bind.Var + | TMDefOpens _ -> + () | TMDefDo(e, m) -> CheckNothingAfterEntryPoint cenv m CheckNoReraise cenv None e @@ -2296,12 +2530,12 @@ and CheckModuleSpec cenv env x = let env = { env with reflect = env.reflect || HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute mspec.Attribs } CheckDefnInModule cenv env rhs -let CheckTopImpl (g, amap, reportErrors, infoReader, internalsVisibleToPaths, viewCcu, denv, mexpr, extraAttribs, (isLastCompiland: bool*bool), isInternalTestSpanStackReferring) = +let CheckTopImpl (g, amap, reportErrors, infoReader, internalsVisibleToPaths, viewCcu, tcValF, denv, mexpr, extraAttribs, isLastCompiland: bool*bool, isInternalTestSpanStackReferring) = let cenv = { g =g reportErrors=reportErrors - boundVals= new Dictionary<_, _>(100, HashIdentity.Structural) - limitVals= new Dictionary<_, _>(100, HashIdentity.Structural) + boundVals = Dictionary<_, _>(100, HashIdentity.Structural) + limitVals = Dictionary<_, _>(100, HashIdentity.Structural) potentialUnboundUsesOfVals=Map.empty anonRecdTypes = StampMap.Empty usesQuotations=false @@ -2312,6 +2546,7 @@ let CheckTopImpl (g, amap, reportErrors, infoReader, internalsVisibleToPaths, vi viewCcu= viewCcu isLastCompiland=isLastCompiland isInternalTestSpanStackReferring = isInternalTestSpanStackReferring + tcVal = tcValF entryPointGiven=false} // Certain type equality checks go faster if these TyconRefs are pre-resolved. @@ -2335,10 +2570,11 @@ let CheckTopImpl (g, amap, reportErrors, infoReader, internalsVisibleToPaths, vi reflect=false external=false returnScope = 0 - isInAppExpr = false } + isInAppExpr = false + resumableCode = Resumable.None } CheckModuleExpr cenv env mexpr CheckAttribs cenv env extraAttribs - if cenv.usesQuotations && QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat g = QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus then + if cenv.usesQuotations && not (QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat(g).SupportsDeserializeEx) then viewCcu.UsesFSharp20PlusQuotations <- true cenv.entryPointGiven, cenv.anonRecdTypes diff --git a/src/fsharp/PostInferenceChecks.fsi b/src/fsharp/PostInferenceChecks.fsi index 25c6bf3ac35..95647603e56 100644 --- a/src/fsharp/PostInferenceChecks.fsi +++ b/src/fsharp/PostInferenceChecks.fsi @@ -6,9 +6,21 @@ module internal FSharp.Compiler.PostTypeCheckSemanticChecks open FSharp.Compiler.Import open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TcGlobals /// Perform the checks on the TAST for a file after type inference is complete. -val CheckTopImpl : TcGlobals * ImportMap * bool * InfoReader * CompilationPath list * CcuThunk * DisplayEnv * ModuleOrNamespaceExprWithSig * Attribs * (bool * bool) * isInternalTestSpanStackReferring: bool -> bool * StampMap +val CheckTopImpl: + g: TcGlobals * + amap: ImportMap * + reportErrors: bool * + infoReader: InfoReader * + internalsVisibleToPaths: CompilationPath list * + viewCcu: CcuThunk * + tcValF: ConstraintSolver.TcValF * + denv: DisplayEnv * + mexpr: ModuleOrNamespaceExprWithSig * + extraAttribs: Attribs * (bool * bool) * + isInternalTestSpanStackReferring: bool + -> bool * StampMap diff --git a/src/fsharp/PrettyNaming.fs b/src/fsharp/PrettyNaming.fs index 4c11b9054d3..a0c50c3d395 100755 --- a/src/fsharp/PrettyNaming.fs +++ b/src/fsharp/PrettyNaming.fs @@ -1,700 +1,951 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//---------------------------------------------------------------------------- -// Some general F# utilities for mangling / unmangling / manipulating names. -//-------------------------------------------------------------------------- - +/// Some general F# utilities for mangling / unmangling / manipulating names. /// Anything to do with special names of identifiers and other lexical rules -module public FSharp.Compiler.PrettyNaming - open System - open System.Collections.Generic - open System.Collections.Concurrent - open System.Globalization - open System.Text - - open FSharp.Compiler - open FSharp.Compiler.AbstractIL.Internal.Library - - open Internal.Utilities - open Internal.Utilities.StructuredFormat - open Internal.Utilities.StructuredFormat.LayoutOps - - //------------------------------------------------------------------------ - // Operator name compilation - //----------------------------------------------------------------------- - - let [] parenGet = ".()" - let [] parenSet = ".()<-" - let [] qmark = "?" - let [] qmarkSet = "?<-" - - /// Prefix for compiled (mangled) operator names. - let [] opNamePrefix = "op_" - - let private opNameTable = - [|("[]", "op_Nil") - ("::", "op_ColonColon") - ("+", "op_Addition") - ("~%", "op_Splice") - ("~%%", "op_SpliceUntyped") - ("~++", "op_Increment") - ("~--", "op_Decrement") - ("-", "op_Subtraction") - ("*", "op_Multiply") - ("**", "op_Exponentiation") - ("/", "op_Division") - ("@", "op_Append") - ("^", "op_Concatenate") - ("%", "op_Modulus") - ("&&&", "op_BitwiseAnd") - ("|||", "op_BitwiseOr") - ("^^^", "op_ExclusiveOr") - ("<<<", "op_LeftShift") - ("~~~", "op_LogicalNot") - (">>>", "op_RightShift") - ("~+", "op_UnaryPlus") - ("~-", "op_UnaryNegation") - ("~&", "op_AddressOf") - ("~&&", "op_IntegerAddressOf") - ("&&", "op_BooleanAnd") - ("||", "op_BooleanOr") - ("<=", "op_LessThanOrEqual") - ("=", "op_Equality") - ("<>", "op_Inequality") - (">=", "op_GreaterThanOrEqual") - ("<", "op_LessThan") - (">", "op_GreaterThan") - ("|>", "op_PipeRight") - ("||>", "op_PipeRight2") - ("|||>", "op_PipeRight3") - ("<|", "op_PipeLeft") - ("<||", "op_PipeLeft2") - ("<|||", "op_PipeLeft3") - ("!", "op_Dereference") - (">>", "op_ComposeRight") - ("<<", "op_ComposeLeft") - ("<< >>", "op_TypedQuotationUnicode") - ("<<| |>>", "op_ChevronsBar") - ("<@ @>", "op_Quotation") - ("<@@ @@>", "op_QuotationUntyped") - ("+=", "op_AdditionAssignment") - ("-=", "op_SubtractionAssignment") - ("*=", "op_MultiplyAssignment") - ("/=", "op_DivisionAssignment") - ("..", "op_Range") - (".. ..", "op_RangeStep") - (qmark, "op_Dynamic") - (qmarkSet, "op_DynamicAssignment") - (parenGet, "op_ArrayLookup") - (parenSet, "op_ArrayAssign") - |] - - let private opCharTranslateTable = - [|( '>', "Greater") - ( '<', "Less") - ( '+', "Plus") - ( '-', "Minus") - ( '*', "Multiply") - ( '=', "Equals") - ( '~', "Twiddle") - ( '%', "Percent") - ( '.', "Dot") - ( '$', "Dollar") - ( '&', "Amp") - ( '|', "Bar") - ( '@', "At") - ( '#', "Hash") - ( '^', "Hat") - ( '!', "Bang") - ( '?', "Qmark") - ( '/', "Divide") - ( ':', "Colon") - ( '(', "LParen") - ( ',', "Comma") - ( ')', "RParen") - ( ' ', "Space") - ( '[', "LBrack") - ( ']', "RBrack") |] - - /// The set of characters usable in custom operators. - let private opCharSet = - let t = new HashSet<_>() - for (c, _) in opCharTranslateTable do - t.Add(c) |> ignore - t +module public FSharp.Compiler.Syntax.PrettyNaming + +open System +open System.Collections.Generic +open System.Collections.Concurrent +open System.Globalization +open System.Text + +open FSharp.Compiler.AbstractIL +open Internal.Utilities.Library +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout + +//------------------------------------------------------------------------ +// Operator name compilation +//----------------------------------------------------------------------- + +let [] parenGet = ".()" +let [] parenSet = ".()<-" +let [] qmark = "?" +let [] qmarkSet = "?<-" + +/// Prefix for compiled (mangled) operator names. +let [] opNamePrefix = "op_" + +let opNameTable = + [|("[]", "op_Nil") + ("::", "op_ColonColon") + ("+", "op_Addition") + ("~%", "op_Splice") + ("~%%", "op_SpliceUntyped") + ("~++", "op_Increment") + ("~--", "op_Decrement") + ("-", "op_Subtraction") + ("*", "op_Multiply") + ("**", "op_Exponentiation") + ("/", "op_Division") + ("@", "op_Append") + ("^", "op_Concatenate") + ("%", "op_Modulus") + ("&&&", "op_BitwiseAnd") + ("|||", "op_BitwiseOr") + ("^^^", "op_ExclusiveOr") + ("<<<", "op_LeftShift") + ("~~~", "op_LogicalNot") + (">>>", "op_RightShift") + ("~+", "op_UnaryPlus") + ("~-", "op_UnaryNegation") + ("~&", "op_AddressOf") + ("~&&", "op_IntegerAddressOf") + ("&&", "op_BooleanAnd") + ("||", "op_BooleanOr") + ("<=", "op_LessThanOrEqual") + ("=", "op_Equality") + ("<>", "op_Inequality") + (">=", "op_GreaterThanOrEqual") + ("<", "op_LessThan") + (">", "op_GreaterThan") + ("|>", "op_PipeRight") + ("||>", "op_PipeRight2") + ("|||>", "op_PipeRight3") + ("<|", "op_PipeLeft") + ("<||", "op_PipeLeft2") + ("<|||", "op_PipeLeft3") + ("!", "op_Dereference") + (">>", "op_ComposeRight") + ("<<", "op_ComposeLeft") + ("<< >>", "op_TypedQuotationUnicode") + ("<<| |>>", "op_ChevronsBar") + ("<@ @>", "op_Quotation") + ("<@@ @@>", "op_QuotationUntyped") + ("+=", "op_AdditionAssignment") + ("-=", "op_SubtractionAssignment") + ("*=", "op_MultiplyAssignment") + ("/=", "op_DivisionAssignment") + ("..", "op_Range") + (".. ..", "op_RangeStep") + (qmark, "op_Dynamic") + (qmarkSet, "op_DynamicAssignment") + (parenGet, "op_ArrayLookup") + (parenSet, "op_ArrayAssign") + |] + +let opCharTranslateTable = + [|( '>', "Greater") + ( '<', "Less") + ( '+', "Plus") + ( '-', "Minus") + ( '*', "Multiply") + ( '=', "Equals") + ( '~', "Twiddle") + ( '%', "Percent") + ( '.', "Dot") + ( '$', "Dollar") + ( '&', "Amp") + ( '|', "Bar") + ( '@', "At") + ( '#', "Hash") + ( '^', "Hat") + ( '!', "Bang") + ( '?', "Qmark") + ( '/', "Divide") + ( ':', "Colon") + ( '(', "LParen") + ( ',', "Comma") + ( ')', "RParen") + ( ' ', "Space") + ( '[', "LBrack") + ( ']', "RBrack") |] + +/// The set of characters usable in custom operators. +let opCharSet = + let t = HashSet<_>() + for c, _ in opCharTranslateTable do + t.Add(c) |> ignore + t - /// Returns `true` if given string is an operator or double backticked name, e.g. ( |>> ) or ( long identifier ). - /// (where ( long identifier ) is the display name for ``long identifier``). - let IsOperatorOrBacktickedName (name: string) = - let nameLen = name.Length - let rec loop i = (i < nameLen && (opCharSet.Contains(name.[i]) || loop (i+1))) - loop 0 - - /// Returns `true` if given string is an operator display name, e.g. ( |>> ) - let IsOperatorName (name: string) = - let name = - if name.StartsWithOrdinal("( ") && name.EndsWithOrdinal(" )") then - name.[2 .. name.Length - 3] - else name - // there is single operator containing a space - range operator with step: `.. ..` - name = ".. .." || name |> Seq.forall (fun c -> c <> ' ' && opCharSet.Contains c) - - let IsMangledOpName (n: string) = - n.StartsWithOrdinal(opNamePrefix) - - /// Compiles a custom operator into a mangled operator name. - /// For example, "!%" becomes "op_DereferencePercent". - /// This function should only be used for custom operators - /// if an operator is or potentially may be a built-in operator, - /// use the 'CompileOpName' function instead. - let private compileCustomOpName = - let t2 = - let t2 = Dictionary<_, _> (opCharTranslateTable.Length) - for x, y in opCharTranslateTable do - t2.Add (x, y) - t2 - /// The maximum length of the name for a custom operator character. - /// This value is used when initializing StringBuilders to avoid resizing. - let maxOperatorNameLength = - opCharTranslateTable - |> Array.maxBy (snd >> String.length) - |> snd - |> String.length - - /// Memoize compilation of custom operators. - /// They're typically used more than once so this avoids some CPU and GC overhead. - let compiledOperators = ConcurrentDictionary<_, string> (StringComparer.Ordinal) - - fun opp -> - // Has this operator already been compiled? - compiledOperators.GetOrAdd(opp, fun (op: string) -> - let opLength = op.Length - let sb = new Text.StringBuilder (opNamePrefix, opNamePrefix.Length + (opLength * maxOperatorNameLength)) - for i = 0 to opLength - 1 do - let c = op.[i] - match t2.TryGetValue c with - | true, x -> - sb.Append(x) |> ignore - | false, _ -> - sb.Append(c) |> ignore - - /// The compiled (mangled) operator name. - let opName = sb.ToString () - - // Cache the compiled name so it can be reused. - opName) - - /// Compiles an operator into a mangled operator name. - /// For example, "!%" becomes "op_DereferencePercent". - /// This function accepts both built-in and custom operators. - let CompileOpName = - /// Maps the built-in F# operators to their mangled operator names. - let standardOpNames = - let opNames = Dictionary<_, _> (opNameTable.Length, StringComparer.Ordinal) - for x, y in opNameTable do - opNames.Add (x, y) - opNames - - fun op -> - match standardOpNames.TryGetValue op with - | true, x -> x - | false, _ -> - if IsOperatorOrBacktickedName op then - compileCustomOpName op - else op - - /// Decompiles the mangled name of a custom operator back into an operator. - /// For example, "op_DereferencePercent" becomes "!%". - /// This function should only be used for mangled names of custom operators - /// if a mangled name potentially represents a built-in operator, - /// use the 'DecompileOpName' function instead. - let private decompileCustomOpName = - // Memoize this operation. Custom operators are typically used more than once - // so this avoids repeating decompilation. - let decompiledOperators = ConcurrentDictionary<_, _> (StringComparer.Ordinal) - - /// The minimum length of the name for a custom operator character. - /// This value is used when initializing StringBuilders to avoid resizing. - let minOperatorNameLength = - opCharTranslateTable - |> Array.minBy (snd >> String.length) - |> snd - |> String.length - - fun opName -> - // Has this operator name already been decompiled? - match decompiledOperators.TryGetValue opName with - | true, op -> op - | false, _ -> - let opNameLen = opName.Length - - /// Function which decompiles the mangled operator name back into a string of operator characters. - /// Returns None if the name contains text which doesn't correspond to an operator - /// otherwise returns Some containing the original operator. - let rec decompile (sb : StringBuilder) idx = - // Have we reached the end of 'opName'? - if idx = opNameLen then - // Finished decompiling. - // Cache the decompiled operator before returning so it can be reused. - let decompiledOp = sb.ToString () - decompiledOperators.TryAdd (opName, decompiledOp) |> ignore - decompiledOp - else - let choice = - opCharTranslateTable - |> Array.tryFind (fun (_, opCharName) -> - // If this operator character name is longer than the remaining piece of 'opName', - // it's obviously not a match. - let opCharNameLen = opCharName.Length - if opNameLen - idx < opCharNameLen then false - else - // Does 'opCharName' match the current position in 'opName'? - String.Compare (opName, idx, opCharName, 0, opCharNameLen, StringComparison.Ordinal) = 0) - - match choice with - | None -> - // Couldn't decompile, so just return the original 'opName'. - opName - | Some (opChar, opCharName) -> - // 'opCharName' matched the current position in 'opName'. - // Append the corresponding operator character to the StringBuilder - // and continue decompiling at the index following this instance of 'opCharName'. - sb.Append opChar |> ignore - decompile sb (idx + opCharName.Length) - - let opNamePrefixLen = opNamePrefix.Length - let sb = - /// The maximum number of operator characters that could be contained in the - /// decompiled operator given the length of the mangled custom operator name. - let maxPossibleOpCharCount = (opNameLen - opNamePrefixLen) / minOperatorNameLength - StringBuilder (maxPossibleOpCharCount) - - // Start decompiling just after the operator prefix. - decompile sb opNamePrefixLen +/// The characters that are allowed to be the first character of an identifier. +let IsIdentifierFirstCharacter c = + if c = '_' then true + else + match Char.GetUnicodeCategory c with + // Letters + | UnicodeCategory.UppercaseLetter + | UnicodeCategory.LowercaseLetter + | UnicodeCategory.TitlecaseLetter + | UnicodeCategory.ModifierLetter + | UnicodeCategory.OtherLetter + | UnicodeCategory.LetterNumber -> true + | _ -> false - - /// Decompiles a mangled operator name back into an operator. - /// For example, "op_DereferencePercent" becomes "!%". - /// This function accepts mangled names for both built-in and custom operators. - let DecompileOpName = - /// Maps the mangled operator names of built-in F# operators back to the operators. - let standardOps = - let ops = Dictionary (opNameTable.Length, StringComparer.Ordinal) - for x, y in opNameTable do - ops.Add(y, x) - ops - - fun opName -> - match standardOps.TryGetValue opName with - | true, res -> res - | false, _ -> - if IsMangledOpName opName then - decompileCustomOpName opName +/// The characters that are allowed to be in an identifier. +let IsIdentifierPartCharacter c = + if c = '\'' then true // Tick + else + match Char.GetUnicodeCategory c with + // Letters + | UnicodeCategory.UppercaseLetter + | UnicodeCategory.LowercaseLetter + | UnicodeCategory.TitlecaseLetter + | UnicodeCategory.ModifierLetter + | UnicodeCategory.OtherLetter + | UnicodeCategory.LetterNumber + // Numbers + | UnicodeCategory.DecimalDigitNumber + // Connectors + | UnicodeCategory.ConnectorPunctuation + // Combiners + | UnicodeCategory.NonSpacingMark + | UnicodeCategory.SpacingCombiningMark -> true + | _ -> false + +/// Keywords paired with their descriptions. Used in completion and quick info. +let keywordsWithDescription : (string * string) list = + [ "abstract", FSComp.SR.keywordDescriptionAbstract() + "and", FSComp.SR.keyworkDescriptionAnd() + "as", FSComp.SR.keywordDescriptionAs() + "assert", FSComp.SR.keywordDescriptionAssert() + "base", FSComp.SR.keywordDescriptionBase() + "begin", FSComp.SR.keywordDescriptionBegin() + "class", FSComp.SR.keywordDescriptionClass() + "const", FSComp.SR.keywordDescriptionConst() + "default", FSComp.SR.keywordDescriptionDefault() + "delegate", FSComp.SR.keywordDescriptionDelegate() + "do", FSComp.SR.keywordDescriptionDo() + "done", FSComp.SR.keywordDescriptionDone() + "downcast", FSComp.SR.keywordDescriptionDowncast() + "downto", FSComp.SR.keywordDescriptionDownto() + "elif", FSComp.SR.keywordDescriptionElif() + "else", FSComp.SR.keywordDescriptionElse() + "end", FSComp.SR.keywordDescriptionEnd() + "exception", FSComp.SR.keywordDescriptionException() + "extern", FSComp.SR.keywordDescriptionExtern() + "false", FSComp.SR.keywordDescriptionTrueFalse() + "finally", FSComp.SR.keywordDescriptionFinally() + "for", FSComp.SR.keywordDescriptionFor() + "fun", FSComp.SR.keywordDescriptionFun() + "function", FSComp.SR.keywordDescriptionFunction() + "global", FSComp.SR.keywordDescriptionGlobal() + "if", FSComp.SR.keywordDescriptionIf() + "in", FSComp.SR.keywordDescriptionIn() + "inherit", FSComp.SR.keywordDescriptionInherit() + "inline", FSComp.SR.keywordDescriptionInline() + "interface", FSComp.SR.keywordDescriptionInterface() + "internal", FSComp.SR.keywordDescriptionInternal() + "lazy", FSComp.SR.keywordDescriptionLazy() + "let", FSComp.SR.keywordDescriptionLet() + "let!", FSComp.SR.keywordDescriptionLetBang() + "match", FSComp.SR.keywordDescriptionMatch() + "match!", FSComp.SR.keywordDescriptionMatchBang() + "member", FSComp.SR.keywordDescriptionMember() + "module", FSComp.SR.keywordDescriptionModule() + "mutable", FSComp.SR.keywordDescriptionMutable() + "namespace", FSComp.SR.keywordDescriptionNamespace() + "new", FSComp.SR.keywordDescriptionNew() + "not", FSComp.SR.keywordDescriptionNot() + "null", FSComp.SR.keywordDescriptionNull() + "of", FSComp.SR.keywordDescriptionOf() + "open", FSComp.SR.keywordDescriptionOpen() + "or", FSComp.SR.keywordDescriptionOr() + "override", FSComp.SR.keywordDescriptionOverride() + "private", FSComp.SR.keywordDescriptionPrivate() + "public", FSComp.SR.keywordDescriptionPublic() + "rec", FSComp.SR.keywordDescriptionRec() + "return", FSComp.SR.keywordDescriptionReturn() + "return!", FSComp.SR.keywordDescriptionReturnBang() + "static", FSComp.SR.keywordDescriptionStatic() + "struct", FSComp.SR.keywordDescriptionStruct() + "then", FSComp.SR.keywordDescriptionThen() + "to", FSComp.SR.keywordDescriptionTo() + "true", FSComp.SR.keywordDescriptionTrueFalse() + "try", FSComp.SR.keywordDescriptionTry() + "type", FSComp.SR.keywordDescriptionType() + "upcast", FSComp.SR.keywordDescriptionUpcast() + "use", FSComp.SR.keywordDescriptionUse() + "use!", FSComp.SR.keywordDescriptionUseBang() + "val", FSComp.SR.keywordDescriptionVal() + "void", FSComp.SR.keywordDescriptionVoid() + "when", FSComp.SR.keywordDescriptionWhen() + "while", FSComp.SR.keywordDescriptionWhile() + "with", FSComp.SR.keywordDescriptionWith() + "yield", FSComp.SR.keywordDescriptionYield() + "yield!", FSComp.SR.keywordDescriptionYieldBang() + "->", FSComp.SR.keywordDescriptionRightArrow() + "<-", FSComp.SR.keywordDescriptionLeftArrow() + ":>", FSComp.SR.keywordDescriptionCast() + ":?>", FSComp.SR.keywordDescriptionDynamicCast() + "<@", FSComp.SR.keywordDescriptionTypedQuotation() + "@>", FSComp.SR.keywordDescriptionTypedQuotation() + "<@@", FSComp.SR.keywordDescriptionUntypedQuotation() + "@@>", FSComp.SR.keywordDescriptionUntypedQuotation() ] + +let keywordLookup = set (List.map fst keywordsWithDescription) + +// Some legacy compat operator names are not encode using op_XYZ and this +// do not carry sufficient information to distinguish between +// let (or) x y = x || y +// let ``or`` x y = x || y +// let (land) x y = x || y +// let ``land`` x y = x || y +// All are deprecated except 'mod'. All except those two get double-backticks +let IsUnencodedOpName (name: string) = + match name with + | "mod" -> true + | _ -> false + +let IsUnencodedLegacyOpName (name: string) = + match name with + | "or" | "land" | "lor" | "lsl" + | "lsr" | "asr" | "lxor" -> true + | _ -> false + +let IsIdentifierName (name: string) = + not (keywordLookup.Contains name) && + not (IsUnencodedOpName name) && + not (IsUnencodedLegacyOpName name) && + let nameLen = name.Length + nameLen > 0 && + IsIdentifierFirstCharacter name.[0] && + let rec loop i = (i >= nameLen || (IsIdentifierPartCharacter(name.[i]) && loop (i+1))) + loop 1 + +let rec isCoreActivePatternName (name: string) idx seenNonOpChar = + if idx = name.Length - 1 then + seenNonOpChar + else + let c = name.[idx] + if opCharSet.Contains(c) && c <> '|' && c <> ' ' then + false + else + isCoreActivePatternName name (idx + 1) (seenNonOpChar || c <> '|') + +/// Determines if the specified name is a valid name for an active pattern. +let IsActivePatternName (name: string) = + // The name must contain at least one character between the starting and ending delimiters. + let nameLen = name.Length + if nameLen < 3 || name.[0] <> '|' || name.[nameLen - 1] <> '|' then + false + else + isCoreActivePatternName name 1 false + +/// Returns `true` if given string is an operator display name (DisplayName), e.g. +/// (::) +/// ([]) +/// (|>>) +/// (+) +/// ( * ) +/// Also returns true for core display names (DisplayNameCore) without the parens: +/// :: +/// [] +/// |>> +/// + +/// * +let IsOperatorDisplayName (name: string) = + let rec loop (name: string) idx endIndex = + if idx = endIndex then + true + else + let c = name.[idx] + if not (opCharSet.Contains(c)) || c = ' ' then + false + else + loop name (idx + 1) endIndex + + let skipParens2 = name.StartsWithOrdinal("( ") && name.EndsWithOrdinal(" )") + let skipParens1 = name.StartsWithOrdinal("(") && name.EndsWithOrdinal(")") + let skip = if skipParens2 then 2 elif skipParens1 then 1 else 0 + let startIndex = skip + let endIndex = name.Length - skip + (startIndex < endIndex && loop name startIndex endIndex) || + (name = ".. ..") || + (name = "(.. ..)") + +//IsOperatorDisplayName "+" +//IsOperatorDisplayName "(+)" +//IsOperatorDisplayName "(::)" +//IsOperatorDisplayName "::" +//IsOperatorDisplayName "([])" +//IsOperatorDisplayName "(*)" +//IsOperatorDisplayName "( ** )" +//IsOperatorDisplayName "( )" // false +//IsOperatorDisplayName "( +)" // false + +let IsMangledOpName (name: string) = + name.StartsWithOrdinal(opNamePrefix) + +/// Compiles a custom operator into a mangled operator name. +/// For example, "!%" becomes "op_DereferencePercent". +/// This function should only be used for custom operators +/// if an operator is or potentially may be a built-in operator, +/// use the 'CompileOpName' function instead. +let compileCustomOpName = + let t2 = + let t2 = Dictionary<_, _> opCharTranslateTable.Length + for x, y in opCharTranslateTable do + t2.Add (x, y) + t2 + + /// The maximum length of the name for a custom operator character. + /// This value is used when initializing StringBuilders to avoid resizing. + let maxOperatorNameLength = + opCharTranslateTable + |> Array.maxBy (snd >> String.length) + |> snd + |> String.length + + /// Memoize compilation of custom operators. + /// They're typically used more than once so this avoids some CPU and GC overhead. + let compiledOperators = ConcurrentDictionary<_, string> StringComparer.Ordinal + + fun opp -> + // Has this operator already been compiled? + compiledOperators.GetOrAdd(opp, fun (op: string) -> + let opLength = op.Length + let sb = StringBuilder(opNamePrefix, opNamePrefix.Length + (opLength * maxOperatorNameLength)) + for i = 0 to opLength - 1 do + let c = op.[i] + match t2.TryGetValue c with + | true, x -> + sb.Append(x) |> ignore + | false, _ -> + sb.Append(c) |> ignore + + /// The compiled (mangled) operator name. + let opName = sb.ToString () + + // Cache the compiled name so it can be reused. + opName) + +/// Maps the built-in F# operators to their mangled operator names. +let standardOpNames = + let opNames = Dictionary<_, _> (opNameTable.Length, StringComparer.Ordinal) + for x, y in opNameTable do + opNames.Add (x, y) + opNames + +let CompileOpName op = + match standardOpNames.TryGetValue op with + | true, x -> x + | false, _ -> + if IsUnencodedOpName op || IsUnencodedLegacyOpName op || IsIdentifierName op then + op + else + compileCustomOpName op + +/// Decompiles the mangled name of a custom operator back into an operator. +/// For example, "op_DereferencePercent" becomes "!%". +/// This function should only be used for mangled names of custom operators +/// if a mangled name potentially represents a built-in operator, +/// use the 'DecompileOpName' function instead. +let decompileCustomOpName = + // Memoize this operation. Custom operators are typically used more than once + // so this avoids repeating decompilation. + let decompiledOperators = ConcurrentDictionary<_, _> StringComparer.Ordinal + + /// The minimum length of the name for a custom operator character. + /// This value is used when initializing StringBuilders to avoid resizing. + let minOperatorNameLength = + opCharTranslateTable + |> Array.minBy (snd >> String.length) + |> snd + |> String.length + + fun opName -> + // Has this operator name already been decompiled? + match decompiledOperators.TryGetValue opName with + | true, op -> op + | false, _ -> + let opNameLen = opName.Length + + /// Function which decompiles the mangled operator name back into a string of operator characters. + /// Returns None if the name contains text which doesn't correspond to an operator + /// otherwise returns Some containing the original operator. + let rec decompile (sb : StringBuilder) idx = + // Have we reached the end of 'opName'? + if idx = opNameLen then + // Finished decompiling. + // Cache the decompiled operator before returning so it can be reused. + let decompiledOp = sb.ToString () + decompiledOperators.TryAdd (opName, decompiledOp) |> ignore + decompiledOp else - opName + let choice = + opCharTranslateTable + |> Array.tryFind (fun (_, opCharName) -> + // If this operator character name is longer than the remaining piece of 'opName', + // it's obviously not a match. + let opCharNameLen = opCharName.Length + if opNameLen - idx < opCharNameLen then false + else + // Does 'opCharName' match the current position in 'opName'? + String.Compare (opName, idx, opCharName, 0, opCharNameLen, StringComparison.Ordinal) = 0) + + match choice with + | None -> + // Couldn't decompile, so just return the original 'opName'. + opName + | Some (opChar, opCharName) -> + // 'opCharName' matched the current position in 'opName'. + // Append the corresponding operator character to the StringBuilder + // and continue decompiling at the index following this instance of 'opCharName'. + sb.Append opChar |> ignore + decompile sb (idx + opCharName.Length) + + let opNamePrefixLen = opNamePrefix.Length + let sb = + /// The maximum number of operator characters that could be contained in the + /// decompiled operator given the length of the mangled custom operator name. + let maxPossibleOpCharCount = (opNameLen - opNamePrefixLen) / minOperatorNameLength + StringBuilder maxPossibleOpCharCount + + // Start decompiling just after the operator prefix. + decompile sb opNamePrefixLen - let DemangleOperatorName nm = - let nm = DecompileOpName nm - if IsOperatorOrBacktickedName nm then "( " + nm + " )" - else nm - let DemangleOperatorNameAsLayout nonOpTagged nm = - let nm = DecompileOpName nm - if IsOperatorOrBacktickedName nm then wordL (TaggedTextOps.tagPunctuation "(") ^^ wordL (TaggedTextOps.tagOperator nm) ^^ wordL (TaggedTextOps.tagPunctuation ")") - else wordL (nonOpTagged nm) - - let opNameCons = CompileOpName "::" - - let opNameNil = CompileOpName "[]" - let opNameEquals = CompileOpName "=" - let opNameEqualsNullable = CompileOpName "=?" - let opNameNullableEquals = CompileOpName "?=" - let opNameNullableEqualsNullable = CompileOpName "?=?" - - /// The characters that are allowed to be the first character of an identifier. - let IsIdentifierFirstCharacter c = - if c = '_' then true +/// Maps the mangled operator names of built-in F# operators back to the operators. +let standardOpsDecompile = + let ops = Dictionary (opNameTable.Length, StringComparer.Ordinal) + for x, y in opNameTable do + ops.Add(y, x) + ops + +let DecompileOpName opName = + match standardOpsDecompile.TryGetValue opName with + | true, res -> res + | false, _ -> + if IsMangledOpName opName then + decompileCustomOpName opName else - match Char.GetUnicodeCategory c with - // Letters - | UnicodeCategory.UppercaseLetter - | UnicodeCategory.LowercaseLetter - | UnicodeCategory.TitlecaseLetter - | UnicodeCategory.ModifierLetter - | UnicodeCategory.OtherLetter - | UnicodeCategory.LetterNumber -> true - | _ -> false - - /// The characters that are allowed to be in an identifier. - let IsIdentifierPartCharacter c = - if c = '\'' then true // Tick + opName + +let DoesIdentifierNeedBackticks (name: string) : bool = + not (IsUnencodedOpName name) && + not (IsIdentifierName name) && + not (IsActivePatternName name) + +/// A utility to help determine if an identifier needs to be quoted +let AddBackticksToIdentifierIfNeeded (name: string) : string = + if DoesIdentifierNeedBackticks name && + not (name.StartsWithOrdinal("`")) && + not (name.EndsWithOrdinal("`")) then + "``" + name + "``" + else + name + +/// Quote identifier with double backticks if needed, remove unnecessary double backticks quotation. +let NormalizeIdentifierBackticks (name: string) : string = + let s = + if name.StartsWithOrdinal("``") && name.EndsWithOrdinal("``") then + name.[2..name.Length - 3] + else name + AddBackticksToIdentifierIfNeeded s + +let ConvertNameToDisplayName name = + AddBackticksToIdentifierIfNeeded name + +let ConvertValNameToDisplayName isBaseVal name = + if isBaseVal && name = "base" then + "base" + elif IsUnencodedOpName name || IsMangledOpName name || IsActivePatternName name then + let nm = DecompileOpName name + // Check for no decompilation, e.g. op_Implicit, op_NotAMangledOpName, op_A-B + if IsMangledOpName name && (nm = name) then + AddBackticksToIdentifierIfNeeded nm + // Add parentheses for multiply-like symbols, with spacing to avoid confusion with comments + elif nm <> "*" && (nm.StartsWithOrdinal "*" || nm.EndsWithOrdinal "*") then + "( " + nm + " )" + // Add parentheses for other symbols, no spacing else - match Char.GetUnicodeCategory c with - // Letters - | UnicodeCategory.UppercaseLetter - | UnicodeCategory.LowercaseLetter - | UnicodeCategory.TitlecaseLetter - | UnicodeCategory.ModifierLetter - | UnicodeCategory.OtherLetter - | UnicodeCategory.LetterNumber - // Numbers - | UnicodeCategory.DecimalDigitNumber - // Connectors - | UnicodeCategory.ConnectorPunctuation - // Combiners - | UnicodeCategory.NonSpacingMark - | UnicodeCategory.SpacingCombiningMark -> true - | _ -> false - - /// Is this character a part of a long identifier? - let IsLongIdentifierPartCharacter c = - c = '.' - || IsIdentifierPartCharacter c - - let IsValidPrefixOperatorUse s = - if String.IsNullOrEmpty s then false else - match s with - | "?+" | "?-" | "+" | "-" | "+." | "-." | "%" | "%%" | "&" | "&&" -> true - | _ -> - s.[0] = '!' - // The check for the first character here could be eliminated since it's covered - // by the call to String.forall; it is a fast check used to avoid the call if possible. - || (s.[0] = '~' && String.forall (fun c -> c = '~') s) + "(" + nm + ")" + else + ConvertNameToDisplayName name - let IsValidPrefixOperatorDefinitionName s = - if String.IsNullOrEmpty s then false else - match s with - | "~?+" | "~?-" | "~+" | "~-" | "~+." | "~-." | "~%" | "~%%" | "~&" | "~&&" -> true - | _ -> - (s.[0] = '!' && s <> "!=") - // The check for the first character here could be eliminated since it's covered - // by the call to String.forall; it is a fast check used to avoid the call if possible. - || (s.[0] = '~' && String.forall (fun c -> c = '~') s) - - let IsPrefixOperator s = - if String.IsNullOrEmpty s then false else - let s = DecompileOpName s - match s with - | "~?+" | "~?-" | "~+" | "~-" | "~+." | "~-." | "~%" | "~%%" | "~&" | "~&&" -> true - | _ -> - (s.[0] = '!' && s <> "!=") - // The check for the first character here could be eliminated since it's covered - // by the call to String.forall; it is a fast check used to avoid the call if possible. - || (s.[0] = '~' && String.forall (fun c -> c = '~') s) +let ConvertNameToDisplayLayout nonOpLayout name = + if DoesIdentifierNeedBackticks name then + leftL (TaggedText.tagPunctuation "``") ^^ wordL (TaggedText.tagOperator name) ^^ rightL (TaggedText.tagPunctuation "``") + else + nonOpLayout name + +let ConvertValNameToDisplayLayout isBaseVal nonOpLayout name = + if isBaseVal && name = "base" then + nonOpLayout "base" + elif IsUnencodedOpName name || IsMangledOpName name || IsActivePatternName name then + let nm = DecompileOpName name + // Check for no decompilation, e.g. op_Implicit, op_NotAMangledOpName, op_A-B + if IsMangledOpName name && (nm = name) then + ConvertNameToDisplayLayout nonOpLayout name + elif nm.StartsWithOrdinal "*" || nm.EndsWithOrdinal "*" then + wordL (TaggedText.tagPunctuation "(") ^^ wordL (TaggedText.tagOperator nm) ^^ wordL (TaggedText.tagPunctuation ")") + else + leftL (TaggedText.tagPunctuation "(") ^^ wordL (TaggedText.tagOperator nm) ^^ rightL (TaggedText.tagPunctuation ")") + else + ConvertNameToDisplayLayout nonOpLayout name - let IsPunctuation s = - if String.IsNullOrEmpty s then false else - match s with - | "," | ";" | "|" | ":" | "." | "*" - | "(" | ")" - | "[" | "]" - | "{" | "}" - | "<" | ">" - | "[|" | "|]" - | "[<" | ">]" - -> true - | _ -> false +let opNameCons = CompileOpName "::" - let IsTernaryOperator s = - (DecompileOpName s = qmarkSet) - - let IsInfixOperator = - - /// EQUALS, INFIX_COMPARE_OP, LESS, GREATER - let relational = [| "=";"!=";"<";">";"$"|] - - /// INFIX_AT_HAT_OP - let concat = [| "@";"^" |] - - /// PLUS_MINUS_OP, MINUS - let plusMinus = [| "+"; "-" |] - - /// PERCENT_OP, STAR, INFIX_STAR_DIV_MOD_OP - let otherMath = [| "*";"/";"%" |] - - /// Characters ignored at the start of the operator name - /// when determining whether an operator is an infix operator. - let ignoredChars = [| '.'; '?' |] - - fun s (* where s is assumed to be a compiled name *) -> - // Certain operator idents are parsed as infix expression operators. - // The parsing as infix operators is hardwired in the grammar [see declExpr productions] - // where certain operator tokens are accepted in infix forms, i.e. . - // The lexer defines the strings that lead to those tokens. - //------ - // This function recognises these "infix operator" names. - let s = DecompileOpName s - let skipIgnoredChars = s.TrimStart(ignoredChars) - let afterSkipStartsWith prefix = skipIgnoredChars.StartsWithOrdinal(prefix) - let afterSkipStarts prefixes = Array.exists afterSkipStartsWith prefixes - // The following conditions follow the declExpr infix clauses. - // The test corresponds to the lexer definition for the token. - s = ":=" || // COLON_EQUALS - afterSkipStartsWith "|" || // BAR_BAR, INFIX_BAR_OP - afterSkipStartsWith "&" || // AMP, AMP_AMP, INFIX_AMP_OP - afterSkipStarts relational || // EQUALS, INFIX_COMPARE_OP, LESS, GREATER - s = "$" || // DOLLAR - afterSkipStarts concat || // INFIX_AT_HAT_OP - s = "::" || // COLON_COLON - afterSkipStarts plusMinus || // PLUS_MINUS_OP, MINUS - afterSkipStarts otherMath || // PERCENT_OP, STAR, INFIX_STAR_DIV_MOD_OP - s = "**" // INFIX_STAR_STAR_OP - - let (|Control|Equality|Relational|Indexer|FixedTypes|Other|) opName = - match opName with - | "&" | "or" | "&&" | "||" -> - Control - | "<>" | "=" -> - Equality - | "<" | ">" | "<=" | ">=" -> - Relational - | "<<" | "<|" | "<||" | "<||" | "|>" | "||>" | "|||>" | ">>" | "^" | ":=" | "@" -> - FixedTypes - | ".[]" -> - Indexer - | _ -> - Other +let opNameNil = CompileOpName "[]" + +let opNameEquals = CompileOpName "=" + +let opNameEqualsNullable = CompileOpName "=?" - let [] private compilerGeneratedMarker = "@" +let opNameNullableEquals = CompileOpName "?=" - let [] private compilerGeneratedMarkerChar = '@' +let opNameNullableEqualsNullable = CompileOpName "?=?" + +/// Is this character a part of a long identifier? +let IsLongIdentifierPartCharacter c = + c = '.' + || IsIdentifierPartCharacter c + +let isTildeOnlyString (s: string) = + let rec loop (s: string) idx = + if idx >= s.Length then + true + elif s.[idx] <> '~' then + false + else + loop s (idx + 1) + loop s 0 + +let IsValidPrefixOperatorUse s = + if String.IsNullOrEmpty s then false else + match s with + | "?+" | "?-" | "+" | "-" | "+." | "-." | "%" | "%%" | "&" | "&&" -> true + | _ -> s.[0] = '!' || isTildeOnlyString s + +let IsValidPrefixOperatorDefinitionName s = + if String.IsNullOrEmpty s then false else + + match s.[0] with + | '~' -> + isTildeOnlyString s || + + match s with + | "~?+" | "~?-" | "~+" | "~-" | "~+." | "~-." | "~%" | "~%%" | "~&" | "~&&" -> true + | _ -> false + + | '!' -> s <> "!=" + | _ -> false + +let IsPrefixOperator s = + if String.IsNullOrEmpty s then false else + let s = DecompileOpName s + IsValidPrefixOperatorDefinitionName s + +let IsPunctuation s = + if String.IsNullOrEmpty s then false else + match s with + | "," | ";" | "|" | ":" | "." | "*" + | "(" | ")" + | "[" | "]" + | "{" | "}" + | "<" | ">" + | "[|" | "|]" + | "[<" | ">]" + -> true + | _ -> false + +let IsTernaryOperator s = + (DecompileOpName s = qmarkSet) + +/// EQUALS, INFIX_COMPARE_OP, LESS, GREATER +let relational = [| "=";"!=";"<";">";"$"|] + +/// INFIX_AT_HAT_OP +let concat = [| "@";"^" |] + +/// PLUS_MINUS_OP, MINUS +let plusMinus = [| "+"; "-" |] + +/// PERCENT_OP, STAR, INFIX_STAR_DIV_MOD_OP +let otherMath = [| "*";"/";"%" |] + +/// Characters ignored at the start of the operator name +/// when determining whether an operator is an infix operator. +let ignoredChars = [| '.'; '?' |] + +// Certain operator idents are parsed as infix expression operators. +// The parsing as infix operators is hardwired in the grammar [see declExpr productions] +// where certain operator tokens are accepted in infix forms, i.e. . +// The lexer defines the strings that lead to those tokens. +//------ +// This function recognises these "infix operator" names. +let IsInfixOperator s = (* where s is assumed to be a compiled name *) + let s = DecompileOpName s + let skipIgnoredChars = s.TrimStart(ignoredChars) + let afterSkipStartsWith prefix = skipIgnoredChars.StartsWithOrdinal(prefix) + let afterSkipStarts prefixes = Array.exists afterSkipStartsWith prefixes + // The following conditions follow the declExpr infix clauses. + // The test corresponds to the lexer definition for the token. + s = ":=" || // COLON_EQUALS + afterSkipStartsWith "|" || // BAR_BAR, INFIX_BAR_OP + afterSkipStartsWith "&" || // AMP, AMP_AMP, INFIX_AMP_OP + afterSkipStarts relational || // EQUALS, INFIX_COMPARE_OP, LESS, GREATER + s = "$" || // DOLLAR + afterSkipStarts concat || // INFIX_AT_HAT_OP + s = "::" || // COLON_COLON + afterSkipStarts plusMinus || // PLUS_MINUS_OP, MINUS + afterSkipStarts otherMath || // PERCENT_OP, STAR, INFIX_STAR_DIV_MOD_OP + s = "**" // INFIX_STAR_STAR_OP + +let (|Control|Equality|Relational|Indexer|FixedTypes|Other|) opName = + match opName with + | "&" | "or" | "&&" | "||" -> + Control + | "<>" | "=" -> + Equality + | "<" | ">" | "<=" | ">=" -> + Relational + | "<<" | "<|" | "<||" | "<||" | "|>" | "||>" | "|||>" | ">>" | "^" | ":=" | "@" -> + FixedTypes + | ".[]" -> + Indexer + | _ -> + Other + +let [] compilerGeneratedMarker = "@" + +let [] compilerGeneratedMarkerChar = '@' - let IsCompilerGeneratedName (nm: string) = - nm.IndexOf compilerGeneratedMarkerChar <> -1 +let IsCompilerGeneratedName (nm: string) = + nm.IndexOf compilerGeneratedMarkerChar <> -1 - let CompilerGeneratedName nm = - if IsCompilerGeneratedName nm then nm else nm+compilerGeneratedMarker - - let GetBasicNameOfPossibleCompilerGeneratedName (name: string) = - match name.IndexOf(compilerGeneratedMarker, StringComparison.Ordinal) with - | -1 | 0 -> name - | n -> name.[0..n-1] +let CompilerGeneratedName nm = + if IsCompilerGeneratedName nm then nm else nm+compilerGeneratedMarker - let CompilerGeneratedNameSuffix (basicName: string) suffix = - basicName+compilerGeneratedMarker+suffix +let GetBasicNameOfPossibleCompilerGeneratedName (name: string) = + match name.IndexOf(compilerGeneratedMarker, StringComparison.Ordinal) with + | -1 | 0 -> name + | n -> name.[0..n-1] +let CompilerGeneratedNameSuffix (basicName: string) suffix = + basicName+compilerGeneratedMarker+suffix - //------------------------------------------------------------------------- - // Handle mangled .NET generic type names - //------------------------------------------------------------------------- +//------------------------------------------------------------------------- +// Handle mangled .NET generic type names +//------------------------------------------------------------------------- - let [] private mangledGenericTypeNameSym = '`' - - let TryDemangleGenericNameAndPos (n: string) = - (* check what comes after the symbol is a number *) - let pos = n.LastIndexOf mangledGenericTypeNameSym - if pos = -1 then ValueNone else - let mutable res = pos < n.Length - 1 - let mutable i = pos + 1 - while res && i < n.Length do - let char = n.[i] - if not (char >= '0' && char <= '9') then - res <- false - i <- i + 1 - if res then - ValueSome pos - else - ValueNone - - type NameArityPair = NameArityPair of string * int - - let DecodeGenericTypeName pos (mangledName: string) = - let res = mangledName.Substring(0, pos) - let num = mangledName.Substring(pos+1, mangledName.Length - pos - 1) - NameArityPair(res, int32 num) - - let DemangleGenericTypeNameWithPos pos (mangledName: string) = - mangledName.Substring(0, pos) - - let DemangleGenericTypeName (mangledName: string) = - match TryDemangleGenericNameAndPos mangledName with - | ValueSome pos -> DemangleGenericTypeNameWithPos pos mangledName - | _ -> mangledName - - let private chopStringTo (s: string) (c: char) = - match s.IndexOf c with - | -1 -> s - | idx -> - let i = idx + 1 - s.Substring(i, s.Length - i) - - /// Try to chop "get_" or "set_" from a string - let TryChopPropertyName (s: string) = - // extract the logical name from any mangled name produced by MakeMemberDataAndMangledNameForMemberVal - if s.Length <= 4 then None else - if s.StartsWithOrdinal("get_") || - s.StartsWithOrdinal("set_") - then Some (s.Substring(4, s.Length - 4)) - else - let s = chopStringTo s '.' - if s.StartsWithOrdinal("get_") || - s.StartsWithOrdinal("set_") - then Some (s.Substring(4, s.Length - 4)) - else None - - /// Try to chop "get_" or "set_" from a string. - /// If the string does not start with "get_" or "set_", this function raises an exception. - let ChopPropertyName s = - match TryChopPropertyName s with - | None -> - failwithf "Invalid internal property name: '%s'" s - | Some res -> res - - let SplitNamesForILPath (s : string) : string list = - if s.StartsWithOrdinal("``") && s.EndsWithOrdinal("``") && s.Length > 4 then [s.Substring(2, s.Length-4)] // identifier is enclosed in `` .. ``, so it is only a single element (this is very approximate) - else s.Split [| '.' ; '`' |] |> Array.toList // '.' chops members / namespaces / modules; '`' chops generic parameters for .NET types +let [] mangledGenericTypeNameSym = '`' + +let TryDemangleGenericNameAndPos (n: string) = + // check what comes after the symbol is a number + let pos = n.LastIndexOf mangledGenericTypeNameSym + if pos = -1 then ValueNone else + let mutable res = pos < n.Length - 1 + let mutable i = pos + 1 + while res && i < n.Length do + let char = n.[i] + if not (char >= '0' && char <= '9') then + res <- false + i <- i + 1 + if res then + ValueSome pos + else + ValueNone + +type NameArityPair = NameArityPair of string * int + +let DemangleGenericTypeNameWithPos pos (mangledName: string) = + mangledName.Substring(0, pos) + +let DecodeGenericTypeNameWithPos pos (mangledName: string) = + let res = DemangleGenericTypeNameWithPos pos mangledName + let num = mangledName.Substring(pos+1, mangledName.Length - pos - 1) + NameArityPair(res, int32 num) + +let DemangleGenericTypeName (mangledName: string) = + match TryDemangleGenericNameAndPos mangledName with + | ValueSome pos -> DemangleGenericTypeNameWithPos pos mangledName + | _ -> mangledName + +let DecodeGenericTypeName (mangledName: string) = + match TryDemangleGenericNameAndPos mangledName with + | ValueSome pos -> DecodeGenericTypeNameWithPos pos mangledName + | _ -> NameArityPair(mangledName, 0) + +let chopStringTo (s: string) (c: char) = + match s.IndexOf c with + | -1 -> s + | idx -> + let i = idx + 1 + s.Substring(i, s.Length - i) + +/// Try to chop "get_" or "set_" from a string +let TryChopPropertyName (s: string) = + // extract the logical name from any mangled name produced by MakeMemberDataAndMangledNameForMemberVal + if s.Length <= 4 then None else + if s.StartsWithOrdinal("get_") || + s.StartsWithOrdinal("set_") + then Some (s.Substring(4, s.Length - 4)) + else + let s = chopStringTo s '.' + if s.StartsWithOrdinal("get_") || + s.StartsWithOrdinal("set_") + then Some (s.Substring(4, s.Length - 4)) + else None + +/// Try to chop "get_" or "set_" from a string. +/// If the string does not start with "get_" or "set_", this function raises an exception. +let ChopPropertyName s = + match TryChopPropertyName s with + | None -> + failwithf "Invalid internal property name: '%s'" s + | Some res -> res + +let SplitNamesForILPath (s : string) : string list = + if s.StartsWithOrdinal("``") && s.EndsWithOrdinal("``") && s.Length > 4 then [s.Substring(2, s.Length-4)] // identifier is enclosed in `` .. ``, so it is only a single element (this is very approximate) + else s.Split [| '.' ; '`' |] |> Array.toList // '.' chops members / namespaces / modules; '`' chops generic parameters for .NET types - /// Return a string array delimited by the given separator. - /// Note that a quoted string is not going to be mangled into pieces. - let inline private isNotQuotedQuotation (text: string) n = n > 0 && text.[n-1] <> '\\' - let private splitAroundQuotation (text: string) (separator: char) = - let length = text.Length - let result = ResizeArray() - let mutable insideQuotation = false - let mutable start = 0 - for i = 0 to length - 1 do - match text.[i], insideQuotation with - // split when seeing a separator - | c, false when c = separator -> - result.Add(text.Substring(start, i - start)) - insideQuotation <- false - start <- i + 1 - | _, _ when i = length - 1 -> - result.Add(text.Substring(start, i - start + 1)) - // keep reading if a separator is inside quotation - | c, true when c = separator -> - insideQuotation <- true - // open or close quotation - | '\"', _ when isNotQuotedQuotation text i -> - insideQuotation <- not insideQuotation - // keep reading - | _ -> () - - result.ToArray() - - /// Return a string array delimited by the given separator up to the maximum number. - /// Note that a quoted string is not going to be mangled into pieces. - let private splitAroundQuotationWithCount (text: string) (separator: char) (count: int)= - if count <= 1 then [| text |] else - let mangledText = splitAroundQuotation text separator - match mangledText.Length > count with - | true -> Array.append (mangledText.[0..(count-2)]) ([| mangledText.[(count-1)..] |> String.concat (Char.ToString separator) |]) - | false -> mangledText - - let [] FSharpModuleSuffix = "Module" - - let [] MangledGlobalName = "`global`" +/// Return a string array delimited by the given separator. +/// Note that a quoted string is not going to be mangled into pieces. +let inline isNotQuotedQuotation (text: string) n = n > 0 && text.[n-1] <> '\\' + +let splitAroundQuotation (text: string) (separator: char) = + let length = text.Length + let result = ResizeArray() + let mutable insideQuotation = false + let mutable start = 0 + for i = 0 to length - 1 do + match text.[i], insideQuotation with + // split when seeing a separator + | c, false when c = separator -> + result.Add(text.Substring(start, i - start)) + insideQuotation <- false + start <- i + 1 + | _, _ when i = length - 1 -> + result.Add(text.Substring(start, i - start + 1)) + // keep reading if a separator is inside quotation + | c, true when c = separator -> + insideQuotation <- true + // open or close quotation + | '\"', _ when isNotQuotedQuotation text i -> + insideQuotation <- not insideQuotation + // keep reading + | _ -> () + + result.ToArray() + +/// Return a string array delimited by the given separator up to the maximum number. +/// Note that a quoted string is not going to be mangled into pieces. +let splitAroundQuotationWithCount (text: string) (separator: char) (count: int)= + if count <= 1 then [| text |] else + let mangledText = splitAroundQuotation text separator + match mangledText.Length > count with + | true -> Array.append mangledText.[0..(count-2)] [| mangledText.[(count-1)..] |> String.concat (Char.ToString separator) |] + | false -> mangledText + +let [] FSharpModuleSuffix = "Module" + +let [] MangledGlobalName = "`global`" - let IllegalCharactersInTypeAndNamespaceNames = [| '.'; '+'; '$'; '&'; '['; ']'; '/'; '\\'; '*'; '\"'; '`' |] - - /// Determines if the specified name is a valid name for an active pattern. - let IsActivePatternName (nm: string) = - let nameLen = nm.Length - // The name must start and end with '|' - (nm.IndexOf '|' = 0) && - (nm.LastIndexOf '|' = nameLen - 1) && - // The name must contain at least one character between the starting and ending delimiters. - nameLen >= 3 && - ( - let core = nm.Substring(1, nameLen - 2) - // no operator characters except '|' and ' ' - core |> String.forall (fun c -> c = '|' || c = ' ' || not (opCharSet.Contains c)) && - // at least one non-operator or space character - core |> String.exists (fun c -> c = ' ' || not (opCharSet.Contains c)) - ) - - //IsActivePatternName "|+|" = false - //IsActivePatternName "|ABC|" = true - //IsActivePatternName "|ABC|DEF|" = true - //IsActivePatternName "|||" = false - //IsActivePatternName "||S|" = true - - type ActivePatternInfo = - | APInfo of bool * (string * Range.range) list * Range.range - - member x.IsTotal = let (APInfo(p, _, _)) = x in p - - member x.ActiveTags = let (APInfo(_, tags, _)) = x in List.map fst tags - - member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags - - member x.Range = let (APInfo(_, _, m)) = x in m - - let ActivePatternInfoOfValName nm (m: Range.range) = - // Note: The approximate range calculations in this code assume the name is of the form "(|A|B|)" not "(| A | B |)" - // The ranges are used for IDE refactoring support etc. If names of the second type are used, - // renaming may be inaccurate/buggy. However names of the first form are dominant in F# code. - let rec loop (nm: string) (mp: Range.range) = - let n = nm.IndexOf '|' - if n > 0 then - let m1 = Range.mkRange mp.FileName mp.Start (Range.mkPos mp.StartLine (mp.StartColumn + n)) - let m2 = Range.mkRange mp.FileName (Range.mkPos mp.StartLine (mp.StartColumn + n + 1)) mp.End - (nm.[0..n-1], m1) :: loop nm.[n+1..] m2 - else - let m1 = Range.mkRange mp.FileName mp.Start (Range.mkPos mp.StartLine (mp.StartColumn + nm.Length)) - [(nm, m1)] - let nm = DecompileOpName nm - if IsActivePatternName nm then - // Skip the '|' at each end when recovering ranges - let m0 = Range.mkRange m.FileName (Range.mkPos m.StartLine (m.StartColumn + 1)) (Range.mkPos m.EndLine (m.EndColumn - 1)) - let names = loop nm.[1..nm.Length-2] m0 - let resH, resT = List.frontAndBack names - Some(if fst resT = "_" then APInfo(false, resH, m) else APInfo(true, names, m)) - else - None +let IllegalCharactersInTypeAndNamespaceNames = [| '.'; '+'; '$'; '&'; '['; ']'; '/'; '\\'; '*'; '\"'; '`' |] + +type ActivePatternInfo = + | APInfo of bool * (string * range) list * range + + member x.IsTotal = let (APInfo(p, _, _)) = x in p + + member x.ActiveTags = let (APInfo(_, tags, _)) = x in List.map fst tags + + member x.ActiveTagsWithRanges = let (APInfo(_, tags, _)) = x in tags + + member x.Range = let (APInfo(_, _, m)) = x in m + +let ActivePatternInfoOfValName nm (m: range) = + // Note: The approximate range calculations in this code assume the name is of the form "(|A|B|)" not "(| A | B |)" + // The ranges are used for IDE refactoring support etc. If names of the second type are used, + // renaming may be inaccurate/buggy. However names of the first form are dominant in F# code. + let rec loop (nm: string) (mp: range) = + let n = nm.IndexOf '|' + if n > 0 then + let m1 = Range.mkRange mp.FileName mp.Start (Position.mkPos mp.StartLine (mp.StartColumn + n)) + let m2 = Range.mkRange mp.FileName (Position.mkPos mp.StartLine (mp.StartColumn + n + 1)) mp.End + (nm.[0..n-1], m1) :: loop nm.[n+1..] m2 + else + let m1 = Range.mkRange mp.FileName mp.Start (Position.mkPos mp.StartLine (mp.StartColumn + nm.Length)) + [(nm, m1)] + let nm = DecompileOpName nm + if IsActivePatternName nm then + // Skip the '|' at each end when recovering ranges + let m0 = Range.mkRange m.FileName (Position.mkPos m.StartLine (m.StartColumn + 1)) (Position.mkPos m.EndLine (m.EndColumn - 1)) + let names = loop nm.[1..nm.Length-2] m0 + let resH, resT = List.frontAndBack names + Some(if fst resT = "_" then APInfo(false, resH, m) else APInfo(true, names, m)) + else + None - let private mangleStaticStringArg (nm: string, v: string) = - nm + "=" + "\"" + v.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" - - let private tryDemangleStaticStringArg (mangledText: string) = - match splitAroundQuotationWithCount mangledText '=' 2 with - | [| nm; v |] -> - if v.Length >= 2 then - Some(nm, v.[1..v.Length-2].Replace("\\\\", "\\").Replace("\\\"", "\"")) - else - Some(nm, v) - | _ -> None - - exception InvalidMangledStaticArg of string - - /// Demangle the static parameters - let demangleProvidedTypeName (typeLogicalName: string) = - if typeLogicalName.Contains "," then - let pieces = splitAroundQuotation typeLogicalName ',' - match pieces with - | [| x; "" |] -> x, [| |] - | _ -> - let argNamesAndValues = pieces.[1..] |> Array.choose tryDemangleStaticStringArg - if argNamesAndValues.Length = (pieces.Length - 1) then - pieces.[0], argNamesAndValues - else - typeLogicalName, [| |] - else - typeLogicalName, [| |] - - /// Mangle the static parameters for a provided type or method - let mangleProvidedTypeName (typeLogicalName, nonDefaultArgs) = - let nonDefaultArgsText = - nonDefaultArgs - |> Array.map mangleStaticStringArg - |> String.concat "," - - if nonDefaultArgsText = "" then - typeLogicalName +let mangleStaticStringArg (nm: string, v: string) = + nm + "=" + "\"" + v.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" + +let tryDemangleStaticStringArg (mangledText: string) = + match splitAroundQuotationWithCount mangledText '=' 2 with + | [| nm; v |] -> + if v.Length >= 2 then + Some(nm, v.[1..v.Length-2].Replace("\\\\", "\\").Replace("\\\"", "\"")) else - typeLogicalName + "," + nonDefaultArgsText - - - /// Mangle the static parameters for a provided type or method - let computeMangledNameWithoutDefaultArgValues(nm, staticArgs, defaultArgValues) = - let nonDefaultArgs = - (staticArgs, defaultArgValues) - ||> Array.zip - |> Array.choose (fun (staticArg, (defaultArgName, defaultArgValue)) -> - let actualArgValue = string staticArg - match defaultArgValue with - | Some v when v = actualArgValue -> None - | _ -> Some (defaultArgName, actualArgValue)) - mangleProvidedTypeName (nm, nonDefaultArgs) - - let outArgCompilerGeneratedName = "outArg" \ No newline at end of file + Some(nm, v) + | _ -> None + +exception InvalidMangledStaticArg of string + +/// Demangle the static parameters +let demangleProvidedTypeName (typeLogicalName: string) = + if typeLogicalName.Contains "," then + let pieces = splitAroundQuotation typeLogicalName ',' + match pieces with + | [| x; "" |] -> x, [| |] + | _ -> + let argNamesAndValues = pieces.[1..] |> Array.choose tryDemangleStaticStringArg + if argNamesAndValues.Length = (pieces.Length - 1) then + pieces.[0], argNamesAndValues + else + typeLogicalName, [| |] + else + typeLogicalName, [| |] + +/// Mangle the static parameters for a provided type or method +let mangleProvidedTypeName (typeLogicalName, nonDefaultArgs) = + let nonDefaultArgsText = + nonDefaultArgs + |> Array.map mangleStaticStringArg + |> String.concat "," + + if nonDefaultArgsText = "" then + typeLogicalName + else + typeLogicalName + "," + nonDefaultArgsText + +/// Mangle the static parameters for a provided type or method +let computeMangledNameWithoutDefaultArgValues(nm, staticArgs, defaultArgValues) = + let nonDefaultArgs = + (staticArgs, defaultArgValues) + ||> Array.zip + |> Array.choose (fun (staticArg, (defaultArgName, defaultArgValue)) -> + let actualArgValue = string staticArg + match defaultArgValue with + | Some v when v = actualArgValue -> None + | _ -> Some (defaultArgName, actualArgValue)) + mangleProvidedTypeName (nm, nonDefaultArgs) + +let outArgCompilerGeneratedName = "outArg" + +let ExtraWitnessMethodName nm = nm + "$W" + +/// Reuses generated union case field name objects for common field numbers +let mkUnionCaseFieldName = + let names = + [| 1 .. 10 |] + |> Array.map (fun i -> "Item" + string i) + + fun nFields i -> + match nFields with + | 0 | 1 -> "Item" + | _ -> if i < 10 then names.[i] else "Item" + string (i + 1) + +/// Reuses generated exception field name objects for common field numbers +let mkExceptionFieldName = + let names = + [| 0 .. 9 |] + |> Array.map (fun i -> "Data" + string i) + + fun i -> + if i < 10 then names.[i] else "Data" + string i + +/// The prefix of the names used for the fake namespace path added to all dynamic code entries in FSI.EXE +let FsiDynamicModulePrefix = "FSI_" + +[] +module FSharpLib = + let Root = "Microsoft.FSharp" + let RootPath = IL.splitNamespace Root + let Core = Root + ".Core" + let CorePath = IL.splitNamespace Core + +[] +module CustomOperations = + [] + let Into = "into" + +let unassignedTyparName = "?" + +let FormatAndOtherOverloadsString remainingOverloads = FSComp.SR.typeInfoOtherOverloads(remainingOverloads) + +let GetLongNameFromString x = SplitNamesForILPath x + +//-------------------------------------------------------------------------- +// Resource format for pickled data +//-------------------------------------------------------------------------- + +let FSharpOptimizationDataResourceName = "FSharpOptimizationData." + +let FSharpSignatureDataResourceName = "FSharpSignatureData." + +// For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers +// don't complain when they see the resource. The prefix of these names must not be 'FSharpOptimizationData' +// or 'FSharpSignatureData' +let FSharpOptimizationDataResourceName2 = "FSharpOptimizationInfo." + +let FSharpSignatureDataResourceName2 = "FSharpSignatureInfo." + +let [] suffixForVariablesThatMayNotBeEliminated = "$cont" + +let [] suffixForTupleElementAssignmentTarget = "$tupleElem" + +let [] stackVarPrefix = "__stack_" + diff --git a/src/fsharp/PrettyNaming.fsi b/src/fsharp/PrettyNaming.fsi new file mode 100644 index 00000000000..53479e93468 --- /dev/null +++ b/src/fsharp/PrettyNaming.fsi @@ -0,0 +1,265 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Some general F# utilities for mangling / unmangling / manipulating names. +/// Anything to do with special names of identifiers and other lexical rules +module public FSharp.Compiler.Syntax.PrettyNaming + +open FSharp.Compiler.Text + +[] +val internal parenGet: string = ".()" + +[] +val internal parenSet: string = ".()<-" + +[] +val internal qmark: string = "?" + +[] +val internal qmarkSet: string = "?<-" + +/// Prefix for compiled (mangled) operator names. +[] +val internal opNamePrefix: string = "op_" + +/// Returns `true` if given string is an operator display name, e.g. +/// ( |>> ) +/// |>> +/// .. +val IsOperatorDisplayName: name:string -> bool + +/// Is the name a valid F# identifier +/// A --> true +/// A' --> true +/// _A --> true +/// A0 --> true +/// |A|B| --> false +/// op_Addition --> true +/// + --> false +val IsIdentifierName: name:string -> bool + +/// Determines if the specified name is a valid name for an active pattern. +/// |A|_| --> true +/// |A|B| --> true +/// |A| --> true +/// | --> false +/// || --> false +/// op_Addition --> false +val IsActivePatternName: name:string -> bool + +/// Returns `true` if given string requires double backticks to be a valid identifier, e.g. +/// + true, e.g. ``+`` (this is not op_Addition) +/// |>> true, e.g. ``|>>`` (this is not op_Addition) +/// A-B true, e.g. ``A-B`` +/// AB false, e.g. AB +/// |A|_| false // this is an active pattern name, needs parens not backticks +val DoesIdentifierNeedBackticks: name: string -> bool + +/// Adds double backticks if necessary to make a valid identifier, e.g. +/// op_Addition --> op_Addition +/// + --> ``+`` (this is not op_Addition) +/// |>> --> ``|>>`` (this is not an op_) +/// A-B --> ``A-B`` +/// AB --> AB +/// |A|_| --> |A|_| this is an active pattern name, needs parens not backticks +val AddBackticksToIdentifierIfNeeded: name: string -> string + +/// Removes double backticks if not necessary to make a valid identifier, e.g. +/// ``A`` --> A +/// ``A-B`` --> ``A-B`` +val NormalizeIdentifierBackticks: name: string -> string + +/// Is the name a mangled operator name (approximate) +/// op_Addition - yes +/// op_Quack - yes +val IsMangledOpName: name:string -> bool + +/// Compiles an operator into a mangled operator name. For example, +/// + --> op_Addition +/// !% --> op_DereferencePercent +/// Only used on actual operator names +val CompileOpName: string -> string + +/// Decompiles a potentially-mangled operator name back into a display name. For example: +/// Foo --> Foo +/// + --> + +/// op_Addition --> + +/// op_DereferencePercent --> !% +/// A-B --> A-B +/// |A|_| --> |A|_| +/// Used on names of all kinds +val DecompileOpName: string -> string + +/// Take a core display name (e.g. "List" or "Strange module name") and convert it to display text +/// by adding backticks if necessary. +/// Foo --> Foo +/// + --> ``+`` +/// A-B --> ``A-B`` +val internal ConvertNameToDisplayName: name: string -> string + +/// Take a core display name for a value (e.g. op_Addition or PropertyName) and convert it to display text +/// Foo --> Foo +/// + --> ``+`` +/// op_Addition --> (+) +/// op_Multiply --> ( * ) +/// op_DereferencePercent --> (!%) +/// A-B --> ``A-B`` +/// |A|_| --> (|A|_|) +/// base --> base +/// or --> or +/// mod --> mod +val internal ConvertValNameToDisplayName: isBaseVal: bool -> name: string -> string + +/// Like ConvertNameToDisplayName but produces a tagged layout +val internal ConvertNameToDisplayLayout: nonOpLayout: (string -> Layout) -> name: string -> Layout + +/// Like ConvertValNameToDisplayName but produces a tagged layout +val internal ConvertValNameToDisplayLayout: isBaseVal: bool -> nonOpLayout: (string -> Layout) -> name: string -> Layout + +val internal opNameCons: string + +val internal opNameNil: string + +val internal opNameEquals: string + +val internal opNameEqualsNullable: string + +val internal opNameNullableEquals: string + +val internal opNameNullableEqualsNullable: string + +/// The characters that are allowed to be the first character of an identifier. +val IsIdentifierFirstCharacter: c:char -> bool + +/// The characters that are allowed to be in an identifier. +val IsIdentifierPartCharacter: c:char -> bool + +/// Is this character a part of a long identifier? +val IsLongIdentifierPartCharacter: c:char -> bool + +val internal isTildeOnlyString: s:string -> bool + +val internal IsValidPrefixOperatorUse: s:string -> bool + +val internal IsValidPrefixOperatorDefinitionName: s:string -> bool + +val IsPrefixOperator: s:string -> bool + +val IsPunctuation: s:string -> bool + +val IsTernaryOperator: s:string -> bool + +val IsInfixOperator: string -> bool + +val internal ( |Control|Equality|Relational|Indexer|FixedTypes|Other| ): + opName:string -> Choice + +val IsCompilerGeneratedName: nm:string -> bool + +val internal CompilerGeneratedName: nm:string -> string + +val internal GetBasicNameOfPossibleCompilerGeneratedName: name:string -> string + +val internal CompilerGeneratedNameSuffix: basicName:string -> suffix:string -> string + +val internal TryDemangleGenericNameAndPos: n:string -> int voption + +type internal NameArityPair = | NameArityPair of string * int + +val internal DemangleGenericTypeNameWithPos: pos:int -> mangledName:string -> string + +val internal DecodeGenericTypeNameWithPos: pos:int -> mangledName:string -> NameArityPair + +val internal DemangleGenericTypeName: mangledName:string -> string + +val internal DecodeGenericTypeName: mangledName:string -> NameArityPair + +/// Try to chop "get_" or "set_" from a string +val TryChopPropertyName: s:string -> string option + +/// Try to chop "get_" or "set_" from a string. +/// If the string does not start with "get_" or "set_", this function raises an exception. +val internal ChopPropertyName: s:string -> string + +val internal SplitNamesForILPath: s:string -> string list + +[] +val internal FSharpModuleSuffix: string = "Module" + +[] +val internal MangledGlobalName: string = "`global`" + +val internal IllegalCharactersInTypeAndNamespaceNames: char [] + +type internal ActivePatternInfo = + | APInfo of bool * (string * range) list * range + member ActiveTags: string list + member ActiveTagsWithRanges: (string * range) list + member IsTotal: bool + member Range: range + +val internal ActivePatternInfoOfValName: nm:string -> m:range -> ActivePatternInfo option + +exception internal InvalidMangledStaticArg of string + +val internal demangleProvidedTypeName: typeLogicalName:string -> string * (string * string) [] + +/// Mangle the static parameters for a provided type or method +val internal mangleProvidedTypeName: typeLogicalName:string * nonDefaultArgs:(string * string) [] -> string + +/// Mangle the static parameters for a provided type or method +val internal computeMangledNameWithoutDefaultArgValues: nm:string * staticArgs:'a [] * defaultArgValues:(string * string option) [] -> string + +val internal outArgCompilerGeneratedName: string + +val internal ExtraWitnessMethodName: nm:string -> string + +/// Reuses generated union case field name objects for common field numbers +val internal mkUnionCaseFieldName: (int -> int -> string) + +/// Reuses generated exception field name objects for common field numbers +val internal mkExceptionFieldName: (int -> string) + +/// The prefix of the names used for the fake namespace path added to all dynamic code entries in FSI.EXE +val FsiDynamicModulePrefix: string + +module internal FSharpLib = + val Root: string + val RootPath: string list + val Core: string + val CorePath: string list + +module internal CustomOperations = + [] + val Into: string = "into" + +val internal unassignedTyparName: string + +val internal FSharpOptimizationDataResourceName: string + +val internal FSharpSignatureDataResourceName: string + +val internal FSharpOptimizationDataResourceName2: string + +val internal FSharpSignatureDataResourceName2: string + +val GetLongNameFromString: string -> string list + +val FormatAndOtherOverloadsString: int -> string + +val FSharpSignatureDataResourceName2: string + +/// Mark some variables (the ones we introduce via abstractBigTargets) as don't-eliminate +[] +val internal suffixForVariablesThatMayNotBeEliminated : string = "$cont" + +/// Indicates a ValRef generated to facilitate tuple eliminations +[] +val internal suffixForTupleElementAssignmentTarget : string = "$tupleElem" + +[] +val internal stackVarPrefix : string = "__stack_" + +/// Keywords paired with their descriptions. Used in completion and quick info. +val internal keywordsWithDescription: (string * string) list + diff --git a/src/fsharp/QueueList.fs b/src/fsharp/QueueList.fs index be38afa9ac0..49015631dfb 100644 --- a/src/fsharp/QueueList.fs +++ b/src/fsharp/QueueList.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace Internal.Utilities +namespace Internal.Utilities.Collections open System.Collections open System.Collections.Generic @@ -24,16 +24,20 @@ type internal QueueList<'T>(firstElementsIn:'T list, lastElementsRevIn: 'T list, let lastElements() = if push then [] else List.rev lastElementsRev static let empty = QueueList<'T>([], [], 0) + static member Empty : QueueList<'T> = empty + new (xs:'T list) = QueueList(xs,[],0) member x.ToList() = if push then firstElements else List.append firstElements (lastElements()) - member internal x.FirstElements = firstElements - member internal x.LastElements = lastElements() + member x.FirstElements = firstElements + + member x.LastElements = lastElements() /// This operation is O(1), unless a push happens, which is rare. member x.AppendOne(y) = QueueList(firstElements, y :: lastElementsRev, numLastElements+1) + member x.Append(ys:seq<_>) = let newElements = Seq.toList ys let newLength = List.length newElements @@ -43,33 +47,35 @@ type internal QueueList<'T>(firstElementsIn:'T list, lastElementsRevIn: 'T list, /// This operation is O(n) anyway, so executing ToList() here is OK interface IEnumerable<'T> with member x.GetEnumerator() : IEnumerator<'T> = (x.ToList() :> IEnumerable<_>).GetEnumerator() + interface IEnumerable with member x.GetEnumerator() : IEnumerator = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator) -[] module internal QueueList = let empty<'T> : QueueList<'T> = QueueList<'T>.Empty + let ofSeq (x:seq<_>) = QueueList(List.ofSeq x) + let rec iter f (x:QueueList<_>) = Seq.iter f x + let rec map f (x:QueueList<_>) = ofSeq (Seq.map f x) + let rec exists f (x:QueueList<_>) = Seq.exists f x + let rec filter f (x:QueueList<_>) = ofSeq (Seq.filter f x) + let rec foldBack f (x:QueueList<_>) acc = List.foldBack f x.FirstElements (List.foldBack f x.LastElements acc) + let forall f (x:QueueList<_>) = Seq.forall f x + let ofList (x:list<_>) = QueueList(x) + let toList (x:QueueList<_>) = Seq.toList x + let tryFind f (x:QueueList<_>) = Seq.tryFind f x - let one(x) = QueueList [x] - let appendOne (x:QueueList<_>) y = x.AppendOne(y) - let append (x:QueueList<_>) (ys:QueueList<_>) = x.Append(ys) -#if QUEUE_LIST_UNITTESTS -module internal Test = - let mutable q = QueueList.empty + let one x = QueueList [x] - for i = 0 to 100 do - if q |> QueueList.toList <> [0..i-1] then printfn "fail pre check, i = %d" i - q <- q.AppendOne(i) - if q |> QueueList.toList <> [0..i] then printfn "fail post check, i = %d" i *) -#endif + let appendOne (x:QueueList<_>) y = x.AppendOne(y) + let append (x:QueueList<_>) (ys:QueueList<_>) = x.Append(ys) diff --git a/src/fsharp/QueueList.fsi b/src/fsharp/QueueList.fsi new file mode 100644 index 00000000000..12c531ff17c --- /dev/null +++ b/src/fsharp/QueueList.fsi @@ -0,0 +1,58 @@ +namespace Internal.Utilities.Collections + +/// Iterable functional collection with O(1) append-1 time. Useful for data structures where elements get added at the +/// end but the collection must occasionally be iterated. Iteration is slower and may allocate because +/// a suffix of elements is stored in reverse order. +/// +/// The type doesn't support structural hashing or comparison. +type internal QueueList<'T> = + + interface System.Collections.IEnumerable + + interface System.Collections.Generic.IEnumerable<'T> + + new: xs:'T list -> QueueList<'T> + + new: firstElementsIn:'T list * lastElementsRevIn:'T list * numLastElementsIn:int -> QueueList<'T> + + member Append: ys:seq<'T> -> QueueList<'T> + + member AppendOne: y:'T -> QueueList<'T> + + member ToList: unit -> 'T list + + member FirstElements: 'T list + + member LastElements: 'T list + + static member Empty: QueueList<'T> + +module internal QueueList = + + val empty<'T> : QueueList<'T> + + val ofSeq: x:seq<'a> -> QueueList<'a> + + val iter: f:('a -> unit) -> x:QueueList<'a> -> unit + + val map: f:('a -> 'b) -> x:QueueList<'a> -> QueueList<'b> + + val exists: f:('a -> bool) -> x:QueueList<'a> -> bool + + val filter: f:('a -> bool) -> x:QueueList<'a> -> QueueList<'a> + + val foldBack: f:('a -> 'b -> 'b) -> x:QueueList<'a> -> acc:'b -> 'b + + val forall: f:('a -> bool) -> x:QueueList<'a> -> bool + + val ofList: x:'a list -> QueueList<'a> + + val toList: x:QueueList<'a> -> 'a list + + val tryFind: f:('a -> bool) -> x:QueueList<'a> -> 'a option + + val one: x:'a -> QueueList<'a> + + val appendOne: x:QueueList<'a> -> y:'a -> QueueList<'a> + + val append: x:QueueList<'a> -> ys:QueueList<'a> -> QueueList<'a> diff --git a/src/fsharp/QuotationPickler.fs b/src/fsharp/QuotationPickler.fs index 82273b01ab7..dd0ffda6906 100644 --- a/src/fsharp/QuotationPickler.fs +++ b/src/fsharp/QuotationPickler.fs @@ -2,206 +2,213 @@ module internal FSharp.Compiler.QuotationPickler +open System open System.Text +open FSharp.Compiler.IO open Internal.Utilities.Collections -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.Lib +open Internal.Utilities.Library.Extras -let mkRLinear mk (vs, body) = List.foldBack (fun v acc -> mk (v, acc)) vs body +let mkRLinear mk (vs, body) = List.foldBack (fun v acc -> mk (v, acc)) vs body -type TypeVarData = { tvName: string; } +type TypeVarData = { tvName: string } -type NamedTypeData = +type NamedTypeData = | Idx of int - | Named of (* tcName: *) string * (* tcAssembly: *) string + | Named of tcName: string * tcAssembly: string -type TypeCombOp = - | ArrayTyOp of int (* rank *) +type TypeCombOp = + | ArrayTyOp of int (* rank *) | FunTyOp | NamedTyOp of NamedTypeData type TypeData = - | VarType of int - | AppType of TypeCombOp * TypeData list + | VarType of int + | AppType of TypeCombOp * TypeData list -let mkVarTy v = VarType v -let mkFunTy (x1, x2) = AppType(FunTyOp, [x1; x2]) -let mkArrayTy (n, x) = AppType(ArrayTyOp n, [x]) -let mkILNamedTy (r, l) = AppType(NamedTyOp r, l) +let mkVarTy v = VarType v -type CtorData = +let mkFunTy (x1, x2) = AppType(FunTyOp, [x1; x2]) + +let mkArrayTy (n, x) = AppType(ArrayTyOp n, [x]) + +let mkILNamedTy (r, l) = AppType(NamedTyOp r, l) + +type CtorData = { ctorParent: NamedTypeData ctorArgTypes: TypeData list; } -type MethodData = +type MethodData = { methParent: NamedTypeData methName: string methArgTypes: TypeData list methRetType: TypeData numGenericArgs: int } - -type VarData = + +type VarData = { vText: string vType: TypeData - vMutable: bool } + vMutable: bool } -type FieldData = NamedTypeData * string -type RecdFieldData = NamedTypeData * string type PropInfoData = NamedTypeData * string * TypeData * TypeData list -type CombOp = +type CombOp = | AppOp - | CondOp + | CondOp | ModuleValueOp of NamedTypeData * string * bool - | LetRecOp - | LetRecCombOp - | LetOp - | RecdMkOp of NamedTypeData - | RecdGetOp of NamedTypeData * string - | RecdSetOp of NamedTypeData * string - | SumMkOp of NamedTypeData * string - | SumFieldGetOp of NamedTypeData * string * int + | ModuleValueWOp of NamedTypeData * string * bool * string * int + | LetRecOp + | LetRecCombOp + | LetOp + | RecdMkOp of NamedTypeData + | RecdGetOp of NamedTypeData * string + | RecdSetOp of NamedTypeData * string + | SumMkOp of NamedTypeData * string + | SumFieldGetOp of NamedTypeData * string * int | SumTagTestOp of NamedTypeData * string - | TupleMkOp + | TupleMkOp | TupleGetOp of int - | UnitOp - | BoolOp of bool - | StringOp of string - | SingleOp of float32 - | DoubleOp of float - | CharOp of char - | SByteOp of sbyte - | ByteOp of byte - | Int16Op of int16 - | UInt16Op of uint16 - | Int32Op of int32 - | UInt32Op of uint32 - | Int64Op of int64 - | UInt64Op of uint64 + | UnitOp + | BoolOp of bool + | StringOp of string + | SingleOp of float32 + | DoubleOp of float + | CharOp of char + | SByteOp of sbyte + | ByteOp of byte + | Int16Op of int16 + | UInt16Op of uint16 + | Int32Op of int32 + | UInt32Op of uint32 + | Int64Op of int64 + | UInt64Op of uint64 | PropGetOp of PropInfoData | FieldGetOp of NamedTypeData * string - | CtorCallOp of CtorData - | MethodCallOp of MethodData - | CoerceOp + | CtorCallOp of CtorData + | MethodCallOp of MethodData + | MethodCallWOp of MethodData * MethodData * int + | CoerceOp | NewArrayOp | DelegateOp - | SeqOp - | ForLoopOp - | WhileLoopOp - | NullOp - | DefaultValueOp + | SeqOp + | ForLoopOp + | WhileLoopOp + | NullOp + | DefaultValueOp | PropSetOp of PropInfoData - | FieldSetOp of NamedTypeData * string + | FieldSetOp of NamedTypeData * string | AddressOfOp | ExprSetOp | AddressSetOp - | TypeTestOp + | TypeTestOp | TryFinallyOp - | TryWithOp + | TryWithOp - -/// Represents specifications of a subset of F# expressions +/// Represents specifications of a subset of F# expressions type ExprData = - | AttrExpr of ExprData * ExprData list - | CombExpr of CombOp * TypeData list * ExprData list - | VarExpr of int - | QuoteExpr of ExprData + | AttrExpr of ExprData * ExprData list + | CombExpr of CombOp * TypeData list * ExprData list + | VarExpr of int + | QuoteExpr of ExprData | LambdaExpr of VarData * ExprData - | HoleExpr of TypeData * int - | ThisVarExpr of TypeData - | QuoteRawExpr of ExprData - -let mkVar v = VarExpr v + | HoleExpr of TypeData * int + | ThisVarExpr of TypeData + | QuoteRawExpr of ExprData + +let mkVar v = VarExpr v let mkHole (v, idx) = HoleExpr (v, idx) -let mkApp (a, b) = CombExpr(AppOp, [], [a; b]) +let mkApp (a, b) = CombExpr(AppOp, [], [a; b]) + +let mkLambda (a, b) = LambdaExpr (a, b) -let mkLambda (a, b) = LambdaExpr (a, b) +let mkQuote a = QuoteExpr a -let mkQuote (a) = QuoteExpr (a) +let mkQuoteRaw40 a = QuoteRawExpr a -let mkQuoteRaw40 (a) = QuoteRawExpr (a) +let mkCond (x1, x2, x3) = CombExpr(CondOp, [], [x1;x2;x3]) -let mkCond (x1, x2, x3) = CombExpr(CondOp, [], [x1;x2;x3]) +let mkModuleValueApp (tcref, nm, isProp, tyargs, args: ExprData list) = + CombExpr(ModuleValueOp(tcref, nm, isProp), tyargs, args) -let mkModuleValueApp (tcref, nm, isProp, tyargs, args: ExprData list list) = CombExpr(ModuleValueOp(tcref, nm, isProp), tyargs, List.concat args) +let mkModuleValueWApp (tcref, nm, isProp, nmW, nWitnesses, tyargs, args: ExprData list) = + CombExpr(ModuleValueWOp(tcref, nm, isProp, nmW, nWitnesses), tyargs, args) let mkTuple (ty, x) = CombExpr(TupleMkOp, [ty], x) let mkLet ((v, e), b) = CombExpr(LetOp, [], [e;mkLambda (v, b)]) (* nb. order preserves source order *) -let mkUnit () = CombExpr(UnitOp, [], []) +let mkUnit () = CombExpr(UnitOp, [], []) -let mkNull ty = CombExpr(NullOp, [ty], []) +let mkNull ty = CombExpr(NullOp, [ty], []) let mkLetRecRaw e1 = CombExpr(LetRecOp, [], [e1]) -let mkLetRecCombRaw args = CombExpr(LetRecCombOp, [], args) +let mkLetRecCombRaw args = CombExpr(LetRecCombOp, [], args) -let mkLetRec (ves, body) = - let vs, es = List.unzip ves +let mkLetRec (ves, body) = + let vs, es = List.unzip ves mkLetRecRaw(mkRLinear mkLambda (vs, mkLetRecCombRaw (body :: es))) - -let mkRecdMk (n, tys, args) = CombExpr(RecdMkOp n, tys, args) -let mkRecdGet ((d1, d2), tyargs, args) = CombExpr(RecdGetOp(d1, d2), tyargs, args) +let mkRecdMk (n, tys, args) = CombExpr(RecdMkOp n, tys, args) -let mkRecdSet ((d1, d2), tyargs, args) = CombExpr(RecdSetOp(d1, d2), tyargs, args) +let mkRecdGet (d1, d2, tyargs, args) = CombExpr(RecdGetOp(d1, d2), tyargs, args) -let mkUnion ((d1, d2), tyargs, args) = CombExpr(SumMkOp(d1, d2), tyargs, args) +let mkRecdSet (d1, d2, tyargs, args) = CombExpr(RecdSetOp(d1, d2), tyargs, args) -let mkUnionFieldGet ((d1, d2, d3), tyargs, arg) = CombExpr(SumFieldGetOp(d1, d2, d3), tyargs, [arg]) +let mkUnion (d1, d2, tyargs, args) = CombExpr(SumMkOp(d1, d2), tyargs, args) -let mkUnionCaseTagTest ((d1, d2), tyargs, arg) = CombExpr(SumTagTestOp(d1, d2), tyargs, [arg]) +let mkUnionFieldGet (d1, d2, d3, tyargs, arg) = CombExpr(SumFieldGetOp(d1, d2, d3), tyargs, [arg]) -let mkTupleGet (ty, n, e) = CombExpr(TupleGetOp n, [ty], [e]) +let mkUnionCaseTagTest (d1, d2, tyargs, arg) = CombExpr(SumTagTestOp(d1, d2), tyargs, [arg]) + +let mkTupleGet (ty, n, e) = CombExpr(TupleGetOp n, [ty], [e]) let mkCoerce (ty, arg) = CombExpr(CoerceOp, [ty], [arg]) let mkTypeTest (ty, arg) = CombExpr(TypeTestOp, [ty], [arg]) -let mkAddressOf (arg) = CombExpr(AddressOfOp, [], [arg]) +let mkAddressOf arg = CombExpr(AddressOfOp, [], [arg]) let mkAddressSet (arg1, arg2) = CombExpr(AddressSetOp, [], [arg1;arg2]) let mkVarSet (arg1, arg2) = CombExpr(ExprSetOp, [], [arg1;arg2]) -let mkDefaultValue (ty) = CombExpr(DefaultValueOp, [ty], []) +let mkDefaultValue ty = CombExpr(DefaultValueOp, [ty], []) -let mkThisVar (ty) = ThisVarExpr(ty) +let mkThisVar ty = ThisVarExpr(ty) let mkNewArray (ty, args) = CombExpr(NewArrayOp, [ty], args) -let mkBool (v, ty) = CombExpr(BoolOp v, [ty], []) +let mkBool (v, ty) = CombExpr(BoolOp v, [ty], []) -let mkString (v, ty) = CombExpr(StringOp v, [ty], []) +let mkString (v, ty) = CombExpr(StringOp v, [ty], []) -let mkSingle (v, ty) = CombExpr(SingleOp v, [ty], []) +let mkSingle (v, ty) = CombExpr(SingleOp v, [ty], []) -let mkDouble (v, ty) = CombExpr(DoubleOp v, [ty], []) +let mkDouble (v, ty) = CombExpr(DoubleOp v, [ty], []) -let mkChar (v, ty) = CombExpr(CharOp v, [ty], []) +let mkChar (v, ty) = CombExpr(CharOp v, [ty], []) -let mkSByte (v, ty) = CombExpr(SByteOp v, [ty], []) +let mkSByte (v, ty) = CombExpr(SByteOp v, [ty], []) -let mkByte (v, ty) = CombExpr(ByteOp v, [ty], []) +let mkByte (v, ty) = CombExpr(ByteOp v, [ty], []) -let mkInt16 (v, ty) = CombExpr(Int16Op v, [ty], []) +let mkInt16 (v, ty) = CombExpr(Int16Op v, [ty], []) -let mkUInt16 (v, ty) = CombExpr(UInt16Op v, [ty], []) +let mkUInt16 (v, ty) = CombExpr(UInt16Op v, [ty], []) -let mkInt32 (v, ty) = CombExpr(Int32Op v, [ty], []) +let mkInt32 (v, ty) = CombExpr(Int32Op v, [ty], []) -let mkUInt32 (v, ty) = CombExpr(UInt32Op v, [ty], []) +let mkUInt32 (v, ty) = CombExpr(UInt32Op v, [ty], []) -let mkInt64 (v, ty) = CombExpr(Int64Op v, [ty], []) +let mkInt64 (v, ty) = CombExpr(Int64Op v, [ty], []) -let mkUInt64 (v, ty) = CombExpr(UInt64Op v, [ty], []) +let mkUInt64 (v, ty) = CombExpr(UInt64Op v, [ty], []) let mkSequential (e1, e2) = CombExpr(SeqOp, [], [e1;e2]) -let mkForLoop (x1, x2, x3) = CombExpr(ForLoopOp, [], [x1;x2;x3]) +let mkForLoop (x1, x2, x3) = CombExpr(ForLoopOp, [], [x1;x2;x3]) let mkWhileLoop (e1, e2) = CombExpr(WhileLoopOp, [], [e1;e2]) @@ -215,30 +222,36 @@ let mkPropGet (d, tyargs, args) = CombExpr(PropGetOp(d), tyargs, args) let mkPropSet (d, tyargs, args) = CombExpr(PropSetOp(d), tyargs, args) -let mkFieldGet ((d1, d2), tyargs, args) = CombExpr(FieldGetOp(d1, d2), tyargs, args) +let mkFieldGet (d1, d2, tyargs, args) = CombExpr(FieldGetOp(d1, d2), tyargs, args) -let mkFieldSet ((d1, d2), tyargs, args) = CombExpr(FieldSetOp(d1, d2), tyargs, args) +let mkFieldSet (d1, d2, tyargs, args) = CombExpr(FieldSetOp(d1, d2), tyargs, args) let mkCtorCall (d, tyargs, args) = CombExpr(CtorCallOp(d), tyargs, args) let mkMethodCall (d, tyargs, args) = CombExpr(MethodCallOp(d), tyargs, args) +let mkMethodCallW (d1, d2, d3, tyargs, args) = CombExpr(MethodCallWOp(d1, d2, d3), tyargs, args) + let mkAttributedExpression(e, attr) = AttrExpr(e, [attr]) -let isAttributedExpression e = match e with AttrExpr(_, _) -> true | _ -> false +let isAttributedExpression e = match e with AttrExpr _ -> true | _ -> false //--------------------------------------------------------------------------- // Pickle/unpickle expression and type specifications in a stable format // compatible with those read by Microsoft.FSharp.Quotations -//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- let SerializedReflectedDefinitionsResourceNameBase = "ReflectedDefinitions" let freshVar (n, ty, mut) = { vText=n; vType=ty; vMutable=mut } -module SimplePickle = +/// Arbitrary value +[] +let PickleBufferCapacity = 100000 + +module SimplePickle = - type Table<'T> = + type Table<'T> = { tbl: HashMultiMap<'T, int> // This should be "Dictionary" mutable rows: 'T list mutable count: int } @@ -253,21 +266,21 @@ module SimplePickle = member tbl.Count = tbl.rows.Length member tbl.Add x = - let n = tbl.count + let n = tbl.count tbl.count <- tbl.count + 1 tbl.tbl.Add(x, n) tbl.rows <- x :: tbl.rows n member tbl.FindOrAdd x = - if tbl.tbl.ContainsKey x then tbl.tbl.[x] + if tbl.tbl.ContainsKey x then tbl.tbl.[x] else tbl.Add x - member tbl.Find x = tbl.tbl.[x] + member tbl.Find x = tbl.tbl.[x] - member tbl.ContainsKey x = tbl.tbl.ContainsKey x + member tbl.ContainsKey x = tbl.tbl.ContainsKey x - type QuotationPickleOutState = + type QuotationPickleOutState = { os: ByteBuffer ostrings: Table } @@ -279,33 +292,38 @@ module SimplePickle = let p_unit () (_os: QuotationPickleOutState) = () - let prim_pint32 i st = + let prim_pint32 i st = p_byte (Bits.b0 i) st p_byte (Bits.b1 i) st p_byte (Bits.b2 i) st p_byte (Bits.b3 i) st - // compress integers according to the same scheme used by CLR metadata - // This halves the size of pickled data - let p_int32 n st = - if n >= 0 && n <= 0x7F then + // compress integers according to the same scheme used by CLR metadata + // This halves the size of pickled data + let p_int32 n st = + if n >= 0 && n <= 0x7F then p_byte (Bits.b0 n) st - else if n >= 0x80 && n <= 0x3FFF then + else if n >= 0x80 && n <= 0x3FFF then p_byte (0x80 ||| (n >>> 8)) st - p_byte (n &&& 0xFF) st - else + p_byte (n &&& 0xFF) st + else p_byte 0xFF st prim_pint32 n st - let p_bytes (s:byte[]) st = + let p_bytes (s:byte[]) st = let len = s.Length - p_int32 (len) st + p_int32 len st st.os.EmitBytes s - let prim_pstring (s:string) st = - let bytes = Encoding.UTF8.GetBytes s - let len = bytes.Length - p_int32 (len) st + let p_memory (s:ReadOnlyMemory) st = + let len = s.Length + p_int32 len st + st.os.EmitMemory s + + let prim_pstring (s:string) st = + let bytes = Encoding.UTF8.GetBytes s + let len = bytes.Length + p_int32 len st st.os.EmitBytes bytes let p_int (c:int) st = p_int32 c st @@ -320,13 +338,13 @@ module SimplePickle = let puint32 (x:uint32) st = p_int32 (int32 x) st - let p_int64 i st = + let p_int64 i st = p_int32 (int32 (i &&& 0xFFFFFFFFL)) st p_int32 (int32 (i >>> 32)) st - let bits_of_float32 (x:float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x), 0) + let bits_of_float32 (x:float32) = BitConverter.ToInt32(BitConverter.GetBytes(x), 0) - let bits_of_float (x:float) = System.BitConverter.ToInt64(System.BitConverter.GetBytes(x), 0) + let bits_of_float (x:float) = BitConverter.ToInt64(BitConverter.GetBytes(x), 0) let p_uint64 x st = p_int64 (int64 x) st @@ -349,43 +367,49 @@ module SimplePickle = let p_string s st = puniq st.ostrings s st let rec p_list f x st = - match x with + match x with | [] -> p_byte 0 st | h :: t -> p_byte 1 st; f h st; p_list f t st - + let pickle_obj p x = + let st1 = + { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + ostrings=Table<_>.Create() } let stringTab, phase1bytes = - let st1 = - { os = ByteBuffer.Create 100000 - ostrings=Table<_>.Create() } p x st1 - st1.ostrings.AsList, st1.os.Close() - let phase2data = (stringTab, phase1bytes) - let phase2bytes = - let st2 = - { os = ByteBuffer.Create 100000 - ostrings=Table<_>.Create() } - p_tup2 (p_list prim_pstring) p_bytes phase2data st2 - st2.os.Close() - phase2bytes + st1.ostrings.AsList, st1.os.AsMemory() + + let phase2data = (stringTab, phase1bytes) + + let st2 = + { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + ostrings=Table<_>.Create() } + let phase2bytes = + p_tup2 (p_list prim_pstring) p_memory phase2data st2 + st2.os.AsMemory() + + let finalBytes = phase2bytes.ToArray() + (st1.os :> IDisposable).Dispose() + (st2.os :> IDisposable).Dispose() + finalBytes open SimplePickle let p_assemblyref x st = p_string x st -let p_NamedType x st = - match x with +let p_NamedType x st = + match x with | Idx n -> p_tup2 p_string p_assemblyref (string n, "") st | Named (nm, a) -> p_tup2 p_string p_assemblyref (nm, a) st -let p_tycon x st = +let p_tycon x st = match x with | FunTyOp -> p_byte 1 st | NamedTyOp a -> p_byte 2 st; p_NamedType a st | ArrayTyOp a -> p_byte 3 st; p_int a st let rec p_type x st = - match x with + match x with | VarType v -> p_byte 0 st; p_int v st | AppType(c, ts) -> p_byte 1 st; p_tup2 p_tycon p_types (c, ts) st @@ -397,19 +421,23 @@ let p_recdFieldSpec v st = p_tup2 p_NamedType p_string v st let p_ucaseSpec v st = p_tup2 p_NamedType p_string v st -let p_MethodData a st = +let p_MethodData a st = p_tup5 p_NamedType p_types p_type p_string p_int (a.methParent, a.methArgTypes, a.methRetType, a.methName, a.numGenericArgs) st -let p_CtorData a st = +let p_CtorData a st = p_tup2 p_NamedType p_types (a.ctorParent, a.ctorArgTypes) st -let p_PropInfoData a st = +let p_PropInfoData a st = p_tup4 p_NamedType p_string p_type p_types a st - -let p_CombOp x st = - match x with + +let p_CombOp x st = + match x with | CondOp -> p_byte 0 st - | ModuleValueOp (x, y, z) -> p_byte 1 st; p_tup3 p_NamedType p_string p_bool (x, y, z) st + | ModuleValueOp (x, y, z) -> + p_byte 1 st + p_NamedType x st + p_string y st + p_bool z st | LetRecOp -> p_byte 2 st | RecdMkOp a -> p_byte 3 st; p_NamedType a st | RecdGetOp (x, y) -> p_byte 4 st; p_recdFieldSpec (x, y) st @@ -456,9 +484,21 @@ let p_CombOp x st = | TryFinallyOp -> p_byte 47 st | TryWithOp -> p_byte 48 st | ExprSetOp -> p_byte 49 st + | MethodCallWOp (a, b, c) -> + p_byte 50 st + p_MethodData a st + p_MethodData b st + p_int c st + | ModuleValueWOp (x, y, z, nmW, nWitnesses) -> + p_byte 51 st + p_string nmW st + p_int nWitnesses st + p_NamedType x st + p_string y st + p_bool z st let rec p_expr x st = - match x with + match x with | CombExpr(c, ts, args) -> p_byte 0 st; p_tup3 p_CombOp p_types (p_list p_expr) (c, ts, args) st | VarExpr v -> p_byte 1 st; p_int v st | LambdaExpr(v, e) -> p_byte 2 st; p_tup2 p_varDecl p_expr (v, e) st @@ -467,30 +507,37 @@ let rec p_expr x st = | AttrExpr(e, attrs) -> p_byte 5 st; p_tup2 p_expr (p_list p_expr) (e, attrs) st | ThisVarExpr(ty) -> p_byte 6 st; p_type ty st | QuoteRawExpr(tm) -> p_byte 7 st; p_expr tm st - -type ModuleDefnData = + +type ModuleDefnData = { Module: NamedTypeData Name: string IsProperty: bool } -type MethodBaseData = - | ModuleDefn of ModuleDefnData - | Method of MethodData - | Ctor of CtorData +type MethodBaseData = + | ModuleDefn of ModuleDefnData * (string * int) option + | Method of MethodData + | Ctor of CtorData let pickle = pickle_obj p_expr -let p_MethodBase x st = - match x with - | ModuleDefn md -> +let p_MethodBase x st = + match x with + | ModuleDefn (md, None) -> p_byte 0 st p_NamedType md.Module st p_string md.Name st p_bool md.IsProperty st - | Method md -> + | ModuleDefn (md, Some (nmW, nWitnesses)) -> + p_byte 3 st + p_string nmW st + p_int nWitnesses st + p_NamedType md.Module st + p_string md.Name st + p_bool md.IsProperty st + | Method md -> p_byte 1 st p_MethodData md st - | Ctor md -> + | Ctor md -> p_byte 2 st p_CtorData md st diff --git a/src/fsharp/QuotationPickler.fsi b/src/fsharp/QuotationPickler.fsi index ffe23215886..d69e9ce2813 100644 --- a/src/fsharp/QuotationPickler.fsi +++ b/src/fsharp/QuotationPickler.fsi @@ -4,55 +4,49 @@ module internal FSharp.Compiler.QuotationPickler #nowarn "1178" // The struct, record or union type 'internal_instr_extension' is not structurally comparable because the type -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Bytes -open FSharp.Compiler -open FSharp.Compiler.Lib - type TypeData -type TypeVarData = { tvName: string } + +type TypeVarData = { tvName: string } type NamedTypeData = /// Indicates an F# 4.0+ reference into the supplied table of type definition references, ultimately resolved by TypeRef/TypeDef data | Idx of int /// Indicates an F# 3.0+ reference to a named type in an assembly loaded by name - | Named of (* tcName: *) string * (* tcAssembly: *) string - + | Named of tcName: string * tcAssembly: string val mkVarTy : int -> TypeData -val mkFunTy : (TypeData * TypeData) -> TypeData -val mkArrayTy : (int * TypeData ) -> TypeData -val mkILNamedTy : (NamedTypeData * TypeData list) -> TypeData + +val mkFunTy : TypeData * TypeData -> TypeData + +val mkArrayTy : int * TypeData -> TypeData + +val mkILNamedTy : NamedTypeData * TypeData list -> TypeData type ExprData type VarData type CtorData = - { ctorParent: NamedTypeData; - ctorArgTypes: TypeData list; } + { ctorParent: NamedTypeData + ctorArgTypes: TypeData list } type MethodData = - { methParent: NamedTypeData; - methName: string; - methArgTypes: TypeData list; - methRetType: TypeData; + { methParent: NamedTypeData + methName: string + methArgTypes: TypeData list + methRetType: TypeData numGenericArgs: int } type ModuleDefnData = - { Module: NamedTypeData; - Name: string; + { Module: NamedTypeData + Name: string IsProperty: bool } type MethodBaseData = - | ModuleDefn of ModuleDefnData + | ModuleDefn of ModuleDefnData * (string * int) option | Method of MethodData | Ctor of CtorData -type FieldData = NamedTypeData * string -type RecdFieldData = NamedTypeData * string type PropInfoData = NamedTypeData * string * TypeData * TypeData list val mkVar : int -> ExprData @@ -63,15 +57,16 @@ val mkLambda : VarData * ExprData -> ExprData val mkQuote : ExprData -> ExprData val mkQuoteRaw40 : ExprData -> ExprData // only available for FSharp.Core 4.4.0.0+ val mkCond : ExprData * ExprData * ExprData -> ExprData -val mkModuleValueApp : NamedTypeData * string * bool * TypeData list * ExprData list list -> ExprData +val mkModuleValueApp : NamedTypeData * string * bool * TypeData list * ExprData list -> ExprData +val mkModuleValueWApp : NamedTypeData * string * bool * string * int * TypeData list * ExprData list -> ExprData val mkLetRec : (VarData * ExprData) list * ExprData -> ExprData val mkLet : (VarData * ExprData) * ExprData -> ExprData val mkRecdMk : NamedTypeData * TypeData list * ExprData list -> ExprData -val mkRecdGet : RecdFieldData * TypeData list * ExprData list -> ExprData -val mkRecdSet : RecdFieldData * TypeData list * ExprData list -> ExprData -val mkUnion : (NamedTypeData * string) * TypeData list * ExprData list -> ExprData -val mkUnionFieldGet : (NamedTypeData * string * int) * TypeData list * ExprData -> ExprData -val mkUnionCaseTagTest : (NamedTypeData * string) * TypeData list * ExprData -> ExprData +val mkRecdGet : NamedTypeData * string * TypeData list * ExprData list -> ExprData +val mkRecdSet : NamedTypeData * string * TypeData list * ExprData list -> ExprData +val mkUnion : NamedTypeData * string * TypeData list * ExprData list -> ExprData +val mkUnionFieldGet : NamedTypeData * string * int * TypeData list * ExprData -> ExprData +val mkUnionCaseTagTest : NamedTypeData * string * TypeData list * ExprData -> ExprData val mkTuple : TypeData * ExprData list -> ExprData val mkTupleGet : TypeData * int * ExprData -> ExprData val mkCoerce : TypeData * ExprData -> ExprData @@ -104,10 +99,12 @@ val mkTryWith : ExprData * VarData * ExprData * VarData * ExprData -> ExprData val mkDelegate : TypeData * ExprData -> ExprData val mkPropGet : PropInfoData * TypeData list * ExprData list -> ExprData val mkPropSet : PropInfoData * TypeData list * ExprData list -> ExprData -val mkFieldGet : FieldData * TypeData list * ExprData list -> ExprData -val mkFieldSet : FieldData * TypeData list * ExprData list -> ExprData +val mkFieldGet : NamedTypeData * string * TypeData list * ExprData list -> ExprData +val mkFieldSet : NamedTypeData * string * TypeData list * ExprData list -> ExprData val mkCtorCall : CtorData * TypeData list * ExprData list -> ExprData val mkMethodCall : MethodData * TypeData list * ExprData list -> ExprData +val mkMethodCallW : MethodData * MethodData * int * TypeData list * ExprData list -> ExprData + val mkAttributedExpression : ExprData * ExprData -> ExprData val pickle : (ExprData -> byte[]) val isAttributedExpression : ExprData -> bool diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index 879130ab74e..c383eac6f74 100644 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -3,21 +3,23 @@ module internal FSharp.Compiler.QuotationTranslator open Internal.Utilities +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib -open FSharp.Compiler.Ast -open FSharp.Compiler.PrettyNaming +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Range +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open System.Collections.Generic -module QP = FSharp.Compiler.QuotationPickler +module QP = QuotationPickler let verboseCReflect = condition "VERBOSE_CREFLECT" @@ -28,33 +30,51 @@ type IsReflectedDefinition = [] type QuotationSerializationFormat = - /// Indicates that type references are emitted as integer indexes into a supplied table - | FSharp_40_Plus - | FSharp_20_Plus + { + /// Indicates that witness parameters are recorded + SupportsWitnesses: bool + + /// Indicates that type references are emitted as integer indexes into a supplied table + SupportsDeserializeEx: bool + } type QuotationGenerationScope = - { g: TcGlobals + { + g: TcGlobals + amap: Import.ImportMap + scope: CcuThunk + + tcVal : ConstraintSolver.TcValF + // Accumulate the references to type definitions referencedTypeDefs: ResizeArray + referencedTypeDefsTable: Dictionary - // Accumulate the type splices (i.e. captured type parameters) into here - typeSplices: ResizeArray - // Accumulate the expression splices into here + + /// Accumulate the type splices (i.e. captured type parameters) into here + typeSplices: ResizeArray + + /// Accumulate the expression splices into here exprSplices: ResizeArray + isReflectedDefinition : IsReflectedDefinition + quotationFormat : QuotationSerializationFormat - mutable emitDebugInfoInQuotations : bool } - static member Create (g: TcGlobals, amap, scope, isReflectedDefinition) = + mutable emitDebugInfoInQuotations : bool + } + + static member Create (g: TcGlobals, amap, scope, tcVal, isReflectedDefinition) = { g = g scope = scope amap = amap - referencedTypeDefs = new ResizeArray<_>() - referencedTypeDefsTable = new Dictionary<_, _>() - typeSplices = new ResizeArray<_>() - exprSplices = new ResizeArray<_>() + tcVal = tcVal + referencedTypeDefs = ResizeArray<_>() + referencedTypeDefsTable = Dictionary<_, _>() + typeSplices = ResizeArray<_>() + exprSplices = ResizeArray<_>() isReflectedDefinition = isReflectedDefinition quotationFormat = QuotationGenerationScope.ComputeQuotationFormat g emitDebugInfoInQuotations = g.emitDebugInfoInQuotations } @@ -65,22 +85,28 @@ type QuotationGenerationScope = cenv.exprSplices |> ResizeArray.toList static member ComputeQuotationFormat g = - let deserializeExValRef = ValRefForIntrinsic g.deserialize_quoted_FSharp_40_plus_info - if deserializeExValRef.TryDeref.IsSome then - QuotationSerializationFormat.FSharp_40_Plus - else - QuotationSerializationFormat.FSharp_20_Plus + { SupportsDeserializeEx = (ValRefForIntrinsic g.deserialize_quoted_FSharp_40_plus_info).TryDeref.IsSome + SupportsWitnesses = (ValRefForIntrinsic g.call_with_witnesses_info).TryDeref.IsSome } type QuotationTranslationEnv = { /// Map from Val to binding index vs: ValMap - nvs: int + numValsInScope: int /// Map from typar stamps to binding index tyvs: StampMap + /// Indicates that we disable generation of witnesses + suppressWitnesses: bool + + /// All witnesses in scope and their mapping to lambda variables. + // + // Note: this uses an immutable HashMap/Dictionary with an IEqualityComparer that captures TcGlobals, see + // the point where the empty initial object is created. + witnessesInScope: TraitWitnessInfoHashMap + // Map for values bound by the // 'let v = isinst e in .... if nonnull v then ...v .... ' // construct arising out the compilation of pattern matching. We decode these back to the form @@ -90,10 +116,12 @@ type QuotationTranslationEnv = substVals: ValMap } - static member Empty = + static member CreateEmpty g = { vs = ValMap<_>.Empty - nvs = 0 + numValsInScope = 0 tyvs = Map.empty + suppressWitnesses = false + witnessesInScope = EmptyTraitWitnessInfoHashMap g isinstVals = ValMap<_>.Empty substVals = ValMap<_>.Empty } @@ -101,16 +129,26 @@ type QuotationTranslationEnv = let idx = env.tyvs.Count { env with tyvs = env.tyvs.Add(v.Stamp, idx ) } + member env.BindWitnessInfo (witnessInfo: TraitWitnessInfo) = + let argIdx = env.numValsInScope + { env with + witnessesInScope = env.witnessesInScope.Add(witnessInfo, argIdx) + numValsInScope = env.numValsInScope + 1 } + member env.BindTypars vs = - (env, vs) ||> List.fold (fun env v -> env.BindTypar v) // fold left-to-right because indexes are left-to-right + (env, vs) ||> List.fold (fun env v -> env.BindTypar v) + + member env.BindWitnessInfos witnessInfos = + (env, witnessInfos) ||> List.fold (fun env v -> env.BindWitnessInfo v) let BindFormalTypars (env: QuotationTranslationEnv) vs = { env with tyvs = Map.empty }.BindTypars vs let BindVal env v = + let n = env.numValsInScope { env with - vs = env.vs.Add v env.nvs - nvs = env.nvs + 1 } + vs = env.vs.Add v n + numValsInScope = env.numValsInScope + 1 } let BindIsInstVal env v (ty, e) = { env with isinstVals = env.isinstVals.Add v (ty, e) } @@ -118,24 +156,24 @@ let BindIsInstVal env v (ty, e) = let BindSubstVal env v e = { env with substVals = env.substVals.Add v e } -let BindVals env vs = List.fold BindVal env vs // fold left-to-right because indexes are left-to-right +let BindVals env vs = List.fold BindVal env vs let BindFlatVals env vs = List.fold BindVal env vs // fold left-to-right because indexes are left-to-right exception InvalidQuotedTerm of exn -exception IgnoringPartOfQuotedTermWarning of string * Range.range +exception IgnoringPartOfQuotedTermWarning of string * range let wfail e = raise (InvalidQuotedTerm e) let (|ModuleValueOrMemberUse|_|) g expr = let rec loop expr args = match stripExpr expr with - | Expr.App ((InnerExprPat(Expr.Val (vref, vFlags, _) as f)), fty, tyargs, actualArgs, _m) when vref.IsMemberOrModuleBinding -> + | Expr.App (InnerExprPat(Expr.Val (vref, vFlags, _) as f), fty, tyargs, actualArgs, _m) when vref.IsMemberOrModuleBinding -> Some(vref, vFlags, f, fty, tyargs, actualArgs @ args) | Expr.App (f, _fty, [], actualArgs, _) -> loop f (actualArgs @ args) - | (Expr.Val (vref, vFlags, _m) as f) when (match vref.DeclaringEntity with ParentNone -> false | _ -> true) -> + | Expr.Val (vref, vFlags, _m) as f when (match vref.DeclaringEntity with ParentNone -> false | _ -> true) -> let fty = tyOfExpr g f Some(vref, vFlags, f, fty, [], args) | _ -> @@ -162,14 +200,14 @@ let (|ObjectInitializationCheck|_|) g expr = ( _, _, TDSwitch - ( - Expr.Op (TOp.ILAsm ([AI_clt], _), _, [Expr.Op (TOp.ValFieldGet ((RFRef(_, name))), _, [Expr.Val (selfRef, NormalValUse, _)], _); Expr.Const (Const.Int32 1, _, _)], _), _, _, _ + (_, + Expr.Op (TOp.ILAsm ([AI_clt], _), _, [Expr.Op (TOp.ValFieldGet (RecdFieldRef(_, name)), _, [Expr.Val (selfRef, NormalValUse, _)], _); Expr.Const (Const.Int32 1, _, _)], _), _, _, _ ), - [| TTarget([], Expr.App (Expr.Val (failInitRef, _, _), _, _, _, _), _); _ |], _, resultTy + [| TTarget([], Expr.App (Expr.Val (failInitRef, _, _), _, _, _, _), _, _); _ |], _, resultTy ) when IsCompilerGeneratedName name && name.StartsWithOrdinal("init") && - selfRef.BaseOrThisInfo = MemberThisVal && + selfRef.IsMemberThisVal && valRefEq g failInitRef (ValRefForIntrinsic g.fail_init_info) && isUnitTy g resultTy -> Some() | _ -> None @@ -206,13 +244,48 @@ let rec EmitDebugInfoIfNecessary cenv env m astExpr : QP.ExprData = and ConvExpr cenv env (expr : Expr) = EmitDebugInfoIfNecessary cenv env expr.Range (ConvExprCore cenv env expr) +and GetWitnessArgs cenv (env : QuotationTranslationEnv) m tps tyargs = + let g = cenv.g + if g.generateWitnesses && not env.suppressWitnesses then + let witnessExprs = + ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs + |> CommitOperationResult + let env = { env with suppressWitnesses = true } + witnessExprs |> List.map (fun arg -> + match arg with + | Choice1Of2 traitInfo -> + ConvWitnessInfo cenv env m traitInfo + | Choice2Of2 arg -> + ConvExpr cenv env arg) + else + [] + +and ConvWitnessInfo cenv env m traitInfo = + let g = cenv.g + let witnessInfo = traitInfo.TraitKey + let env = { env with suppressWitnesses = true } + // First check if this is a witness in ReflectedDefinition code + if env.witnessesInScope.ContainsKey witnessInfo then + let witnessArgIdx = env.witnessesInScope.[witnessInfo] + QP.mkVar witnessArgIdx + // Otherwise it is a witness in a quotation literal + else + let holeTy = GenWitnessTy g witnessInfo + let idx = cenv.exprSplices.Count + let fillExpr = Expr.WitnessArg(traitInfo, m) + let liftExpr = mkCallLiftValue cenv.g m holeTy fillExpr + cenv.exprSplices.Add((liftExpr, m)) + QP.mkHole(ConvType cenv env m holeTy, idx) + and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.ExprData = - let expr = DetectAndOptimizeForExpression cenv.g OptimizeIntRangesOnly expr + let g = cenv.g + + let expr = DetectAndOptimizeForExpression g OptimizeIntRangesOnly expr // Eliminate subsumption coercions for functions. This must be done post-typechecking because we need // complete inference types. - let expr = NormalizeAndAdjustPossibleSubsumptionExprs cenv.g expr + let expr = NormalizeAndAdjustPossibleSubsumptionExprs g expr // Remove TExpr_ref nodes let expr = stripExpr expr @@ -222,9 +295,9 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. match expr with // Detect expression tree exprSplices | Expr.App (InnerExprPat(Expr.Val (vf, _, _)), _, _, x0 :: rest, m) - when isSplice cenv.g vf -> + when isSplice g vf -> let idx = cenv.exprSplices.Count - let ty = tyOfExpr cenv.g expr + let ty = tyOfExpr g expr match (freeInExpr CollectTyparsAndLocalsNoCaching x0).FreeLocals |> Seq.tryPick (fun v -> if env.vs.ContainsVal v then Some v else None) with | Some v -> errorR(Error(FSComp.SR.crefBoundVarUsedInSplice(v.DisplayName), v.Range)) @@ -234,32 +307,33 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let hole = QP.mkHole(ConvType cenv env m ty, idx) (hole, rest) ||> List.fold (fun fR arg -> QP.mkApp (fR, ConvExpr cenv env arg)) - | ModuleValueOrMemberUse cenv.g (vref, vFlags, _f, _fty, tyargs, curriedArgs) - when not (isSplice cenv.g vref) -> + | ModuleValueOrMemberUse g (vref, vFlags, _f, _fty, tyargs, curriedArgs) + when not (isSplice g vref) -> let m = expr.Range - let (numEnclTypeArgs, _, isNewObj, valUseFlags, isSelfInit, takesInstanceArg, isPropGet, isPropSet) = - GetMemberCallInfo cenv.g (vref, vFlags) + let numEnclTypeArgs, _, isNewObj, valUseFlags, isSelfInit, takesInstanceArg, isPropGet, isPropSet = + GetMemberCallInfo g (vref, vFlags) - let isMember, tps, curriedArgInfos, retTy = + let isMember, tps, witnessInfos, curriedArgInfos, retTy = match vref.MemberInfo with | Some _ when not vref.IsExtensionMember -> // This is an application of a member method // We only count one argument block for these. - let tps, curriedArgInfos, retTy, _ = GetTypeOfIntrinsicMemberInCompiledForm cenv.g vref - true, tps, curriedArgInfos, retTy + let tps, witnessInfos, curriedArgInfos, retTy, _ = GetTypeOfIntrinsicMemberInCompiledForm g vref + true, tps, witnessInfos, curriedArgInfos, retTy | _ -> // This is an application of a module value or extension member let arities = arityOfVal vref.Deref - let tps, curriedArgInfos, retTy, _ = GetTopValTypeInCompiledForm cenv.g arities vref.Type m - false, tps, curriedArgInfos, retTy + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let tps, witnessInfos, curriedArgInfos, retTy, _ = GetTopValTypeInCompiledForm g arities numEnclosingTypars vref.Type m + false, tps, witnessInfos, curriedArgInfos, retTy // Compute the object arguments as they appear in a compiled call // Strip off the object argument, if any. The curriedArgInfos are already adjusted to compiled member form let objArgs, curriedArgs = match takesInstanceArg, curriedArgs with | false, curriedArgs -> [], curriedArgs - | true, (objArg :: curriedArgs) -> [objArg], curriedArgs + | true, objArg :: curriedArgs -> [objArg], curriedArgs | true, [] -> wfail(InternalError("warning: unexpected missing object argument when generating quotation for call to F# object member " + vref.LogicalName, m)) if verboseCReflect then @@ -281,8 +355,8 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | None -> error(InternalError("no arity information found for F# value " + vref.LogicalName, vref.Range)) | Some a -> a - let expr, exprty = AdjustValForExpectedArity cenv.g m vref vFlags topValInfo - ConvExpr cenv env (MakeApplicationAndBetaReduce cenv.g (expr, exprty, [tyargs], curriedArgs, m)) + let expr, exprty = AdjustValForExpectedArity g m vref vFlags topValInfo + ConvExpr cenv env (MakeApplicationAndBetaReduce g (expr, exprty, [tyargs], curriedArgs, m)) else // Too many arguments? Chop let (curriedArgs: Expr list ), laterArgs = List.splitAt nCurriedArgInfos curriedArgs @@ -300,26 +374,34 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. else tryDestRefTupleExpr arg)) if verboseCReflect then - dprintfn "vref.DisplayName = %A, after unit adjust, #untupledCurriedArgs = %A, #curriedArgInfos = %d" vref.DisplayName (List.map List.length untupledCurriedArgs) curriedArgInfos.Length + dprintfn "vref.DisplayName = %A , after unit adjust, #untupledCurriedArgs = %A, #curriedArgInfos = %d" vref.DisplayName (List.map List.length untupledCurriedArgs) curriedArgInfos.Length + + let witnessArgTys = + if g.generateWitnesses && not env.suppressWitnesses then + GenWitnessTys g witnessInfos + else + [] + + let witnessArgs = GetWitnessArgs cenv env m tps tyargs + let subCall = if isMember then - // This is an application of a member method - // We only count one argument block for these. - let callArgs = (objArgs :: untupledCurriedArgs) |> List.concat let parentTyconR = ConvTyconRef cenv vref.TopValDeclaringEntity m let isNewObj = isNewObj || valUseFlags || isSelfInit // The signature types are w.r.t. to the formal context let envinner = BindFormalTypars env tps let argTys = curriedArgInfos |> List.concat |> List.map fst + let witnessArgTypesR = ConvTypes cenv envinner m witnessArgTys let methArgTypesR = ConvTypes cenv envinner m argTys let methRetTypeR = ConvReturnType cenv envinner m retTy - let methName = vref.CompiledName cenv.g.CompilerGlobalState + let methName = vref.CompiledName g.CompilerGlobalState let numGenericArgs = tyargs.Length - numEnclTypeArgs - ConvObjectModelCall cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, methArgTypesR, methRetTypeR, methName, tyargs, numGenericArgs, callArgs) + ConvObjectModelCall cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, witnessArgTypesR, methArgTypesR, methRetTypeR, methName, tyargs, numGenericArgs, objArgs, witnessArgs, untupledCurriedArgs) else // This is an application of the module value. - ConvModuleValueApp cenv env m vref tyargs untupledCurriedArgs + ConvModuleValueApp cenv env m vref tyargs witnessArgs untupledCurriedArgs + match curriedArgs, curriedArgInfos with // static member and module value unit argument elimination | [arg: Expr], [[]] -> @@ -341,12 +423,12 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. // Blast type application nodes and expression application nodes apart so values are left with just their type arguments | Expr.App (f, fty, (_ :: _ as tyargs), (_ :: _ as args), m) -> - let rfty = applyForallTy cenv.g fty tyargs - ConvExpr cenv env (primMkApp (primMkApp (f, fty) tyargs [] m, rfty) [] args m) + let rfty = applyForallTy g fty tyargs + ConvExpr cenv env (primMkApp (primMkApp (f, fty) tyargs [] m, rfty) [] args m) // Uses of possibly-polymorphic values | Expr.App (InnerExprPat(Expr.Val (vref, _vFlags, m)), _fty, tyargs, [], _) -> - ConvValRef true cenv env m vref tyargs + ConvValRef true cenv env m vref tyargs // Simple applications | Expr.App (f, _fty, tyargs, args, m) -> @@ -375,16 +457,16 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. QP.mkLetRec(bindsR, bodyR) | Expr.Lambda (_, _, _, vs, b, _, _) -> - let v, b = MultiLambdaToTupledLambda cenv.g vs b + let v, b = MultiLambdaToTupledLambda g vs b let vR = ConvVal cenv env v let bR = ConvExpr cenv (BindVal env v) b QP.mkLambda(vR, bR) | Expr.Quote (ast, _, _, _, ety) -> // F# 2.0-3.1 had a bug with nested 'raw' quotations. F# 4.0 + FSharp.Core 4.4.0.0+ allows us to do the right thing. - if cenv.quotationFormat = QuotationSerializationFormat.FSharp_40_Plus && + if cenv.quotationFormat.SupportsDeserializeEx && // Look for a 'raw' quotation - tyconRefEq cenv.g (tcrefOfAppTy cenv.g ety) cenv.g.raw_expr_tcr + tyconRefEq g (tcrefOfAppTy g ety) g.raw_expr_tcr then QP.mkQuoteRaw40(ConvExpr cenv env ast) else @@ -397,33 +479,42 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let typR = ConvType cenv env m retTy ConvDecisionTree cenv env tgs typR dtree - // initialization check - | Expr.Sequential (ObjectInitializationCheck cenv.g, x1, NormalSeq, _, _) -> ConvExpr cenv env x1 - | Expr.Sequential (x0, x1, NormalSeq, _, _) -> QP.mkSequential(ConvExpr cenv env x0, ConvExpr cenv env x1) - | Expr.Obj (_, ty, _, _, [TObjExprMethod(TSlotSig(_, ctyp, _, _, _, _), _, tps, [tmvs], e, _) as tmethod], _, m) when isDelegateTy cenv.g ty -> - let f = mkLambdas m tps tmvs (e, GetFSharpViewOfReturnType cenv.g (returnTyOfMethod cenv.g tmethod)) - let fR = ConvExpr cenv env f - let tyargR = ConvType cenv env m ctyp - QP.mkDelegate(tyargR, fR) + | Expr.Sequential (ObjectInitializationCheck g, x1, NormalSeq, _, _) -> + ConvExpr cenv env x1 - | Expr.StaticOptimization (_, _, x, _) -> ConvExpr cenv env x - | Expr.TyChoose _ -> ConvExpr cenv env (TypeRelations.ChooseTyparSolutionsForFreeChoiceTypars cenv.g cenv.amap expr) - | Expr.Sequential (x0, x1, ThenDoSeq, _, _) -> QP.mkSequential(ConvExpr cenv env x0, ConvExpr cenv env x1) - | Expr.Obj (_lambdaId, _typ, _basev, _basecall, _overrides, _iimpls, m) -> wfail(Error(FSComp.SR.crefQuotationsCantContainObjExprs(), m)) + | Expr.Sequential (x0, x1, NormalSeq, _, _) -> + QP.mkSequential(ConvExpr cenv env x0, ConvExpr cenv env x1) + + | Expr.Obj (_, ty, _, _, [TObjExprMethod(TSlotSig(_, ctyp, _, _, _, _), _, tps, [tmvs], e, _) as tmethod], _, m) when isDelegateTy g ty -> + let f = mkLambdas m tps tmvs (e, GetFSharpViewOfReturnType g (returnTyOfMethod g tmethod)) + let fR = ConvExpr cenv env f + let tyargR = ConvType cenv env m ctyp + QP.mkDelegate(tyargR, fR) + + | Expr.StaticOptimization (_, _, x, _) -> + ConvExpr cenv env x + + | Expr.TyChoose _ -> + ConvExpr cenv env (TypeRelations.ChooseTyparSolutionsForFreeChoiceTypars g cenv.amap expr) + + | Expr.Sequential (x0, x1, ThenDoSeq, _, _) -> + QP.mkSequential(ConvExpr cenv env x0, ConvExpr cenv env x1) + + | Expr.Obj (_lambdaId, _typ, _basev, _basecall, _overrides, _iimpls, m) -> + wfail(Error(FSComp.SR.crefQuotationsCantContainObjExprs(), m)) | Expr.Op (op, tyargs, args, m) -> match op, tyargs, args with | TOp.UnionCase ucref, _, _ -> - let mkR = ConvUnionCaseRef cenv ucref m + let tcR, s = ConvUnionCaseRef cenv ucref m let tyargsR = ConvTypes cenv env m tyargs let argsR = ConvExprs cenv env args - QP.mkUnion(mkR, tyargsR, argsR) - + QP.mkUnion(tcR, s, tyargsR, argsR) | TOp.Tuple tupInfo, tyargs, _ -> - let tyR = ConvType cenv env m (mkAnyTupledTy cenv.g tupInfo tyargs) + let tyR = ConvType cenv env m (mkAnyTupledTy g tupInfo tyargs) let argsR = ConvExprs cenv env args - QP.mkTuple(tyR, argsR) // TODO: propagate to quotations + QP.mkTuple(tyR, argsR) | TOp.Recd (_, tcref), _, _ -> let rgtypR = ConvTyconRef cenv tcref m @@ -443,7 +534,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let rgtypR = ConvILTypeRef cenv tref let tyargsR = ConvTypes cenv env m tyargs let argsR = ConvExprs cenv env args - QP.mkRecdGet((rgtypR, anonInfo.SortedNames.[n]), tyargsR, argsR) + QP.mkRecdGet(rgtypR, anonInfo.SortedNames.[n], tyargsR, argsR) | TOp.UnionCaseFieldGet (ucref, n), tyargs, [e] -> ConvUnionFieldGet cenv env m ucref n tyargs e @@ -454,15 +545,15 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | TOp.UnionCaseFieldGetAddr _, _tyargs, _ -> wfail(Error(FSComp.SR.crefQuotationsCantContainAddressOf(), m)) - | TOp.ValFieldGet (_rfref), _tyargs, [] -> + | TOp.ValFieldGet _rfref, _tyargs, [] -> wfail(Error(FSComp.SR.crefQuotationsCantContainStaticFieldRef(), m)) - | TOp.ValFieldGet (rfref), tyargs, args -> + | TOp.ValFieldGet rfref, tyargs, args -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args | TOp.TupleFieldGet (tupInfo, n), tyargs, [e] -> let eR = ConvLValueExpr cenv env e - let tyR = ConvType cenv env m (mkAnyTupledTy cenv.g tupInfo tyargs) + let tyR = ConvType cenv env m (mkAnyTupledTy g tupInfo tyargs) QP.mkTupleGet(tyR, n, eR) | TOp.ILAsm (([ I_ldfld (_, _, fspec) ] @@ -475,18 +566,18 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let tyargsR = ConvTypes cenv env m enclTypeArgs let parentTyconR = ConvILTypeRefUnadjusted cenv m fspec.DeclaringTypeRef let argsR = ConvLValueArgs cenv env args - QP.mkFieldSet( (parentTyconR, fspec.Name), tyargsR, argsR) + QP.mkFieldSet(parentTyconR, fspec.Name, tyargsR, argsR) | TOp.ILAsm ([ AI_ceq ], _), _, [arg1;arg2] -> - let ty = tyOfExpr cenv.g arg1 - let eq = mkCallEqualsOperator cenv.g m ty arg1 arg2 + let ty = tyOfExpr g arg1 + let eq = mkCallEqualsOperator g m ty arg1 arg2 ConvExpr cenv env eq | TOp.ILAsm ([ I_throw ], _), _, [arg1] -> - let raiseExpr = mkCallRaise cenv.g m (tyOfExpr cenv.g expr) arg1 + let raiseExpr = mkCallRaise g m (tyOfExpr g expr) arg1 ConvExpr cenv env raiseExpr - | TOp.ILAsm (_il, _), _, _ -> + | TOp.ILAsm _, _, _ -> wfail(Error(FSComp.SR.crefQuotationsCantContainInlineIL(), m)) | TOp.ExnConstr tcref, _, args -> @@ -500,23 +591,23 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. QP.mkCtorCall( { ctorParent = parentTyconR ctorArgTypes = methArgTypesR }, [], argsR) - let exnTypeR = ConvType cenv env m cenv.g.exn_ty + let exnTypeR = ConvType cenv env m g.exn_ty QP.mkCoerce(exnTypeR, objR) | TOp.ValFieldSet rfref, _tinst, args -> let argsR = ConvLValueArgs cenv env args let tyargsR = ConvTypes cenv env m tyargs - let ((_parentTyconR, fldOrPropName) as projR) = ConvRecdFieldRef cenv rfref m + let parentTyconR, fldOrPropName = ConvRecdFieldRef cenv rfref m if rfref.TyconRef.IsRecordTycon then - QP.mkRecdSet(projR, tyargsR, argsR) + QP.mkRecdSet(parentTyconR, fldOrPropName, tyargsR, argsR) else let fspec = rfref.RecdField let tcref = rfref.TyconRef let parentTyconR = ConvTyconRef cenv tcref m if useGenuineField tcref.Deref fspec then - QP.mkFieldSet( projR, tyargsR, argsR) + QP.mkFieldSet(parentTyconR, fldOrPropName, tyargsR, argsR) else - let envinner = BindFormalTypars env (tcref.TyparsNoRange) + let envinner = BindFormalTypars env tcref.TyparsNoRange let propRetTypeR = ConvType cenv envinner m fspec.FormalType QP.mkPropSet( (parentTyconR, fldOrPropName, propRetTypeR, []), tyargsR, argsR) @@ -527,18 +618,18 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let propRetTypeR = ConvType cenv env m fspec.FormalType let callArgR = ConvExpr cenv env obj let exnTypeR = ConvType cenv env m (generalizedTyconRef tcref) - QP.mkPropGet( (parentTyconR, fspec.Name, propRetTypeR, []), [], [QP.mkCoerce (exnTypeR, callArgR)]) + QP.mkPropGet( (parentTyconR, fspec.LogicalName, propRetTypeR, []), [], [QP.mkCoerce (exnTypeR, callArgR)]) | TOp.Coerce, [tgtTy;srcTy], [x] -> let xR = ConvExpr cenv env x - if typeEquiv cenv.g tgtTy srcTy then + if typeEquiv g tgtTy srcTy then xR else QP.mkCoerce(ConvType cenv env m tgtTy, xR) | TOp.Reraise, [toTy], [] -> // rebuild reraise() and Convert - mkReraiseLibCall cenv.g toTy m |> ConvExpr cenv env + mkReraiseLibCall g toTy m |> ConvExpr cenv env | TOp.LValueOp (LAddrOf _, vref), [], [] -> QP.mkAddressOf(ConvValRef false cenv env m vref []) @@ -549,9 +640,9 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | TOp.LValueOp (LSet, vref), [], [e] -> // Sets of module values become property sets match vref.DeclaringEntity with - | Parent tcref when IsCompiledAsStaticProperty cenv.g vref.Deref -> + | Parent tcref when IsCompiledAsStaticProperty g vref.Deref -> let parentTyconR = ConvTyconRef cenv tcref m - let propName = vref.CompiledName cenv.g.CompilerGlobalState + let propName = vref.CompiledName g.CompilerGlobalState let propTy = ConvType cenv env m vref.Type QP.mkPropSet( (parentTyconR, propName, propTy, []), [], [ConvExpr cenv env e]) | _ -> @@ -566,10 +657,10 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | TOp.While _, [], [Expr.Lambda (_, _, _, [_], test, _, _);Expr.Lambda (_, _, _, [_], body, _, _)] -> QP.mkWhileLoop(ConvExpr cenv env test, ConvExpr cenv env body) - | TOp.For (_, FSharpForLoopUp), [], [Expr.Lambda (_, _, _, [_], lim0, _, _); Expr.Lambda (_, _, _, [_], SimpleArrayLoopUpperBound, lm, _); SimpleArrayLoopBody cenv.g (arr, elemTy, body)] -> + | TOp.For (_, FSharpForLoopUp), [], [Expr.Lambda (_, _, _, [_], lim0, _, _); Expr.Lambda (_, _, _, [_], SimpleArrayLoopUpperBound, lm, _); SimpleArrayLoopBody g (arr, elemTy, body)] -> let lim1 = - let len = mkCallArrayLength cenv.g lm elemTy arr // Array.length arr - mkCallSubtractionOperator cenv.g lm cenv.g.int32_ty len (Expr.Const (Const.Int32 1, m, cenv.g.int32_ty)) // len - 1 + let len = mkCallArrayLength g lm elemTy arr // Array.length arr + mkCallSubtractionOperator g lm g.int32_ty len (Expr.Const (Const.Int32 1, m, g.int32_ty)) // len - 1 QP.mkForLoop(ConvExpr cenv env lim0, ConvExpr cenv env lim1, ConvExpr cenv env body) | TOp.For (_, dir), [], [Expr.Lambda (_, _, _, [_], lim0, _, _);Expr.Lambda (_, _, _, [_], lim1, _, _);body] -> @@ -577,21 +668,21 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. | FSharpForLoopUp -> QP.mkForLoop(ConvExpr cenv env lim0, ConvExpr cenv env lim1, ConvExpr cenv env body) | _ -> wfail(Error(FSComp.SR.crefQuotationsCantContainDescendingForLoops(), m)) - | TOp.ILCall (_, _, _, isNewObj, valUseFlags, isProp, _, ilMethRef, enclTypeArgs, methTypeArgs, _tys), [], callArgs -> + | TOp.ILCall (_, _, _, isCtor, valUseFlag, isProperty, _, ilMethRef, enclTypeInst, methInst, _), [], callArgs -> let parentTyconR = ConvILTypeRefUnadjusted cenv m ilMethRef.DeclaringTypeRef - let isNewObj = isNewObj || (match valUseFlags with CtorValUsedAsSuperInit | CtorValUsedAsSelfInit -> true | _ -> false) + let isNewObj = isCtor || (match valUseFlag with CtorValUsedAsSuperInit | CtorValUsedAsSelfInit -> true | _ -> false) let methArgTypesR = List.map (ConvILType cenv env m) ilMethRef.ArgTypes let methRetTypeR = ConvILType cenv env m ilMethRef.ReturnType let methName = ilMethRef.Name - let isPropGet = isProp && methName.StartsWithOrdinal("get_") - let isPropSet = isProp && methName.StartsWithOrdinal("set_") - let tyargs = (enclTypeArgs@methTypeArgs) - ConvObjectModelCall cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, methArgTypesR, methRetTypeR, methName, tyargs, methTypeArgs.Length, callArgs) + let isPropGet = isProperty && methName.StartsWithOrdinal("get_") + let isPropSet = isProperty && methName.StartsWithOrdinal("set_") + let tyargs = (enclTypeInst@methInst) + ConvObjectModelCall cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, [], methArgTypesR, methRetTypeR, methName, tyargs, methInst.Length, [], [], [callArgs]) | TOp.TryFinally _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)] -> QP.mkTryFinally(ConvExpr cenv env e1, ConvExpr cenv env e2) - | TOp.TryCatch _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> + | TOp.TryWith _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> let vfR = ConvVal cenv env vf let envf = BindVal env vf let vhR = ConvVal cenv env vh @@ -599,20 +690,66 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. QP.mkTryWith(ConvExpr cenv env e1, vfR, ConvExpr cenv envf ef, vhR, ConvExpr cenv envh eh) | TOp.Bytes bytes, [], [] -> - ConvExpr cenv env (Expr.Op (TOp.Array, [cenv.g.byte_ty], List.ofArray (Array.map (mkByte cenv.g m) bytes), m)) + ConvExpr cenv env (Expr.Op (TOp.Array, [g.byte_ty], List.ofArray (Array.map (mkByte g m) bytes), m)) | TOp.UInt16s arr, [], [] -> - ConvExpr cenv env (Expr.Op (TOp.Array, [cenv.g.uint16_ty], List.ofArray (Array.map (mkUInt16 cenv.g m) arr), m)) - - | TOp.UnionCaseProof _, _, [e] -> ConvExpr cenv env e // Note: we erase the union case proof conversions when converting to quotations - | TOp.UnionCaseTagGet _tycr, _tinst, [_cx] -> wfail(Error(FSComp.SR.crefQuotationsCantFetchUnionIndexes(), m)) - | TOp.UnionCaseFieldSet (_c, _i), _tinst, [_cx;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetUnionFields(), m)) - | TOp.ExnFieldSet (_tcref, _i), [], [_ex;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetExceptionFields(), m)) - | TOp.RefAddrGet _, _, _ -> wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m)) - | TOp.TraitCall (_ss), _, _ -> wfail(Error(FSComp.SR.crefQuotationsCantCallTraitMembers(), m)) + ConvExpr cenv env (Expr.Op (TOp.Array, [g.uint16_ty], List.ofArray (Array.map (mkUInt16 g m) arr), m)) + + | TOp.UnionCaseProof _, _, [e] -> + ConvExpr cenv env e // Note: we erase the union case proof conversions when converting to quotations + + | TOp.UnionCaseTagGet _tycr, _tinst, [_cx] -> + wfail(Error(FSComp.SR.crefQuotationsCantFetchUnionIndexes(), m)) + + | TOp.UnionCaseFieldSet (_c, _i), _tinst, [_cx;_x] -> + wfail(Error(FSComp.SR.crefQuotationsCantSetUnionFields(), m)) + + | TOp.ExnFieldSet (_tcref, _i), [], [_ex;_x] -> + wfail(Error(FSComp.SR.crefQuotationsCantSetExceptionFields(), m)) + + | TOp.RefAddrGet _, _, _ -> + wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m)) + + | TOp.TraitCall traitInfo, _, args -> + let g = g + let inWitnessPassingScope = not env.witnessesInScope.IsEmpty + let witnessArgInfo = + if g.generateWitnesses && inWitnessPassingScope then + match env.witnessesInScope.TryGetValue traitInfo.TraitKey with + | true, storage -> Some storage + | _ -> None + else + None + + match witnessArgInfo with + | Some witnessArgIdx -> + + let witnessR = QP.mkVar witnessArgIdx + let args = if args.Length = 0 then [ mkUnit g m ] else args + let argsR = ConvExprs cenv env args + (witnessR, argsR) ||> List.fold (fun fR argR -> QP.mkApp (fR, argR)) + + | None -> + // If witnesses are available, we should now always find trait witnesses in scope + assert not inWitnessPassingScope + + let minfoOpt = + if g.generateWitnesses then + ConstraintSolver.CodegenWitnessExprForTraitConstraint cenv.tcVal g cenv.amap m traitInfo args |> CommitOperationResult + else + None + match minfoOpt with + | None -> + wfail(Error(FSComp.SR.crefQuotationsCantCallTraitMembers(), m)) + | Some expr -> + ConvExpr cenv env expr + | _ -> wfail(InternalError( "Unexpected expression shape", m)) + | Expr.WitnessArg (traitInfo, m) -> + ConvWitnessInfo cenv env m traitInfo + | _ -> wfail(InternalError(sprintf "unhandled construct in AST: %A" expr, expr.Range)) @@ -620,14 +757,13 @@ and ConvLdfld cenv env m (fspec: ILFieldSpec) enclTypeArgs args = let tyargsR = ConvTypes cenv env m enclTypeArgs let parentTyconR = ConvILTypeRefUnadjusted cenv m fspec.DeclaringTypeRef let argsR = ConvLValueArgs cenv env args - QP.mkFieldGet( (parentTyconR, fspec.Name), tyargsR, argsR) + QP.mkFieldGet(parentTyconR, fspec.Name, tyargsR, argsR) and ConvUnionFieldGet cenv env m ucref n tyargs e = let tyargsR = ConvTypes cenv env m tyargs let tcR, s = ConvUnionCaseRef cenv ucref m - let projR = (tcR, s, n) let eR = ConvLValueExpr cenv env e - QP.mkUnionFieldGet(projR, tyargsR, eR) + QP.mkUnionFieldGet(tcR, s, n, tyargsR, eR) and ConvClassOrRecdFieldGet cenv env m rfref tyargs args = EmitDebugInfoIfNecessary cenv env m (ConvClassOrRecdFieldGetCore cenv env m rfref tyargs args) @@ -635,14 +771,14 @@ and ConvClassOrRecdFieldGet cenv env m rfref tyargs args = and private ConvClassOrRecdFieldGetCore cenv env m rfref tyargs args = let tyargsR = ConvTypes cenv env m tyargs let argsR = ConvLValueArgs cenv env args - let ((parentTyconR, fldOrPropName) as projR) = ConvRecdFieldRef cenv rfref m + let parentTyconR, fldOrPropName = ConvRecdFieldRef cenv rfref m if rfref.TyconRef.IsRecordTycon then - QP.mkRecdGet(projR, tyargsR, argsR) + QP.mkRecdGet(parentTyconR, fldOrPropName, tyargsR, argsR) else let fspec = rfref.RecdField let tcref = rfref.TyconRef if useGenuineField tcref.Deref fspec then - QP.mkFieldGet(projR, tyargsR, argsR) + QP.mkFieldGet(parentTyconR, fldOrPropName, tyargsR, argsR) else let envinner = BindFormalTypars env tcref.TyparsNoRange let propRetTypeR = ConvType cenv envinner m fspec.FormalType @@ -679,7 +815,7 @@ and ConvLValueArgs cenv env args = | obj :: rest -> ConvLValueExpr cenv env obj :: ConvExprs cenv env rest | [] -> [] -and ConvLValueExpr cenv env expr = +and ConvLValueExpr cenv env (expr: Expr) = EmitDebugInfoIfNecessary cenv env expr.Range (ConvLValueExprCore cenv env expr) // This function has to undo the work of mkExprAddrOfExpr @@ -690,9 +826,9 @@ and ConvLValueExprCore cenv env expr = | TOp.LValueOp (LAddrOf _, vref), _, _ -> ConvValRef false cenv env m vref [] | TOp.ValFieldGetAddr (rfref, _), _, _ -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args | TOp.UnionCaseFieldGetAddr (ucref, n, _), [e], _ -> ConvUnionFieldGet cenv env m ucref n tyargs e - | TOp.ILAsm ([ I_ldflda(fspec) ], _rtys), _, _ -> ConvLdfld cenv env m fspec tyargs args - | TOp.ILAsm ([ I_ldsflda(fspec) ], _rtys), _, _ -> ConvLdfld cenv env m fspec tyargs args - | TOp.ILAsm (([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ] ), _), (arr :: idxs), [elemty] -> + | TOp.ILAsm ([ I_ldflda(fspec) ], _), _, _ -> ConvLdfld cenv env m fspec tyargs args + | TOp.ILAsm ([ I_ldsflda(fspec) ], _), _, _ -> ConvLdfld cenv env m fspec tyargs args + | TOp.ILAsm ([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ], _), arr :: idxs, [elemty] -> match shape.Rank, idxs with | 1, [idx1] -> ConvExpr cenv env (mkCallArrayGet cenv.g m elemty arr idx1) | 2, [idx1; idx2] -> ConvExpr cenv env (mkCallArray2DGet cenv.g m elemty arr idx1 idx2) @@ -705,46 +841,80 @@ and ConvLValueExprCore cenv env expr = and ConvObjectModelCall cenv env m callInfo = EmitDebugInfoIfNecessary cenv env m (ConvObjectModelCallCore cenv env m callInfo) -and ConvObjectModelCallCore cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, methArgTypesR, methRetTypeR, methName, tyargs, numGenericArgs, callArgs) = +and ConvObjectModelCallCore cenv env m (isPropGet, isPropSet, isNewObj, parentTyconR, witnessArgTypesR, methArgTypesR, methRetTypeR, methName, tyargs, numGenericArgs, objArgs, witnessArgsR, untupledCurriedArgs) = let tyargsR = ConvTypes cenv env m tyargs - let callArgsR = ConvLValueArgs cenv env callArgs + let tupledCurriedArgs = untupledCurriedArgs |> List.concat + let allArgsR = + match objArgs with + | [ obj ] -> ConvLValueExpr cenv env obj :: (witnessArgsR @ ConvExprs cenv env tupledCurriedArgs) + | [] -> witnessArgsR @ ConvLValueArgs cenv env tupledCurriedArgs + | _ -> failwith "unreachable" if isPropGet || isPropSet then + assert witnessArgTypesR.IsEmpty let propName = ChopPropertyName methName if isPropGet then - QP.mkPropGet( (parentTyconR, propName, methRetTypeR, methArgTypesR), tyargsR, callArgsR) + QP.mkPropGet( (parentTyconR, propName, methRetTypeR, methArgTypesR), tyargsR, allArgsR) else let args, propTy = List.frontAndBack methArgTypesR - QP.mkPropSet( (parentTyconR, propName, propTy, args), tyargsR, callArgsR) + QP.mkPropSet( (parentTyconR, propName, propTy, args), tyargsR, allArgsR) elif isNewObj then + assert witnessArgTypesR.IsEmpty let ctorR : QuotationPickler.CtorData = { ctorParent = parentTyconR ctorArgTypes = methArgTypesR } - QP.mkCtorCall(ctorR, tyargsR, callArgsR) + QP.mkCtorCall(ctorR, tyargsR, allArgsR) + + elif witnessArgTypesR.IsEmpty then - else let methR : QuotationPickler.MethodData = { methParent = parentTyconR methArgTypes = methArgTypesR methRetType = methRetTypeR methName = methName numGenericArgs = numGenericArgs } - QP.mkMethodCall(methR, tyargsR, callArgsR) -and ConvModuleValueApp cenv env m (vref: ValRef) tyargs (args: Expr list list) = - EmitDebugInfoIfNecessary cenv env m (ConvModuleValueAppCore cenv env m vref tyargs args) + QP.mkMethodCall(methR, tyargsR, allArgsR) -and ConvModuleValueAppCore cenv env m (vref: ValRef) tyargs (args: Expr list list) = + else + + // The old method entry point + let methR: QuotationPickler.MethodData = + { methParent = parentTyconR + methArgTypes = methArgTypesR + methRetType = methRetTypeR + methName = methName + numGenericArgs = numGenericArgs } + + // The witness-passing method entry point + let methWR: QuotationPickler.MethodData = + { methParent = parentTyconR + methArgTypes = witnessArgTypesR @ methArgTypesR + methRetType = methRetTypeR + methName = ExtraWitnessMethodName methName + numGenericArgs = numGenericArgs } + + QP.mkMethodCallW(methR, methWR, List.length witnessArgTypesR, tyargsR, allArgsR) + +and ConvModuleValueApp cenv env m (vref:ValRef) tyargs witnessArgs (args: Expr list list) = + EmitDebugInfoIfNecessary cenv env m (ConvModuleValueAppCore cenv env m vref tyargs witnessArgs args) + +and ConvModuleValueAppCore cenv env m (vref: ValRef) tyargs witnessArgsR (curriedArgs: Expr list list) = match vref.DeclaringEntity with - | ParentNone -> failwith "ConvModuleValueApp" + | ParentNone -> failwith "ConvModuleValueAppCore" | Parent(tcref) -> let isProperty = IsCompiledAsStaticProperty cenv.g vref.Deref let tcrefR = ConvTyconRef cenv tcref m let tyargsR = ConvTypes cenv env m tyargs let nm = vref.CompiledName cenv.g.CompilerGlobalState - let argsR = List.map (ConvExprs cenv env) args - QP.mkModuleValueApp(tcrefR, nm, isProperty, tyargsR, argsR) + let uncurriedArgsR = ConvExprs cenv env (List.concat curriedArgs) + let allArgsR = witnessArgsR @ uncurriedArgsR + let nWitnesses = witnessArgsR.Length + if nWitnesses = 0 then + QP.mkModuleValueApp(tcrefR, nm, isProperty, tyargsR, allArgsR) + else + QP.mkModuleValueWApp(tcrefR, nm, isProperty, ExtraWitnessMethodName nm, nWitnesses, tyargsR, allArgsR) and ConvExprs cenv env args = List.map (ConvExpr cenv env) args @@ -755,7 +925,7 @@ and ConvValRef holeOk cenv env m (vref: ValRef) tyargs = and private ConvValRefCore holeOk cenv env m (vref: ValRef) tyargs = let v = vref.Deref if env.isinstVals.ContainsVal v then - let (ty, e) = env.isinstVals.[v] + let ty, e = env.isinstVals.[v] ConvExpr cenv env (mkCallUnbox cenv.g m ty e) elif env.substVals.ContainsVal v then let e = env.substVals.[v] @@ -763,7 +933,7 @@ and private ConvValRefCore holeOk cenv env m (vref: ValRef) tyargs = elif env.vs.ContainsVal v then if not (List.isEmpty tyargs) then wfail(InternalError("ignoring generic application of local quoted variable", m)) QP.mkVar(env.vs.[v]) - elif v.BaseOrThisInfo = CtorThisVal && cenv.isReflectedDefinition = IsReflectedDefinition.Yes then + elif v.IsCtorThisVal && cenv.isReflectedDefinition = IsReflectedDefinition.Yes then QP.mkThisVar(ConvType cenv env m v.Type) else let vty = v.Type @@ -772,10 +942,14 @@ and private ConvValRefCore holeOk cenv env m (vref: ValRef) tyargs = // References to local values are embedded by value if not holeOk then wfail(Error(FSComp.SR.crefNoSetOfHole(), m)) let idx = cenv.exprSplices.Count - cenv.exprSplices.Add((mkCallLiftValueWithName cenv.g m vty v.LogicalName (exprForValRef m vref), m)) + let liftExpr = mkCallLiftValueWithName cenv.g m vty v.LogicalName (exprForValRef m vref) + cenv.exprSplices.Add((liftExpr, m)) QP.mkHole(ConvType cenv env m vty, idx) + | Parent _ -> - ConvModuleValueApp cenv env m vref tyargs [] + // First-class use or use of type function + let witnessArgs = GetWitnessArgs cenv env m vref.Typars tyargs + ConvModuleValueApp cenv env m vref tyargs witnessArgs [] and ConvUnionCaseRef cenv (ucref: UnionCaseRef) m = let ucgtypR = ConvTyconRef cenv ucref.TyconRef m @@ -817,7 +991,7 @@ and ConvType cenv env m ty = | TType_app(tcref, [tyarg]) when isArrayTyconRef cenv.g tcref -> QP.mkArrayTy(rankOfArrayTyconRef cenv.g tcref, ConvType cenv env m tyarg) - | TType_ucase(UCRef(tcref, _), tyargs) // Note: we erase union case 'types' when converting to quotations + | TType_ucase(UnionCaseRef(tcref, _), tyargs) // Note: we erase union case 'types' when converting to quotations | TType_app(tcref, tyargs) -> #if !NO_EXTENSIONTYPING match TryElimErasableTyconRef cenv m tcref with @@ -869,7 +1043,7 @@ and ConvConst cenv env m c ty = and ConvDecisionTree cenv env tgs typR x = match x with - | TDSwitch(e1, csl, dfltOpt, m) -> + | TDSwitch(_, e1, csl, dfltOpt, m) -> let acc = match dfltOpt with | Some d -> ConvDecisionTree cenv env tgs typR d @@ -881,9 +1055,9 @@ and ConvDecisionTree cenv env tgs typR x = match discrim with | DecisionTreeTest.UnionCase (ucref, tyargs) -> let e1R = ConvLValueExpr cenv env e1 - let ucR = ConvUnionCaseRef cenv ucref m + let tcR, s = ConvUnionCaseRef cenv ucref m let tyargsR = ConvTypes cenv env m tyargs - QP.mkCond (QP.mkUnionCaseTagTest (ucR, tyargsR, e1R), ConvDecisionTree cenv env tgs typR dtree, acc) + QP.mkCond (QP.mkUnionCaseTagTest (tcR, s, tyargsR, e1R), ConvDecisionTree cenv env tgs typR dtree, acc) | DecisionTreeTest.Const (Const.Bool true) -> let e1R = ConvExpr cenv env e1 @@ -904,7 +1078,7 @@ and ConvDecisionTree cenv env tgs typR x = // Decompile cached isinst tests match e1 with | Expr.Val (vref, _, _) when env.isinstVals.ContainsVal vref.Deref -> - let (ty, e) = env.isinstVals.[vref.Deref] + let ty, e = env.isinstVals.[vref.Deref] let tyR = ConvType cenv env m ty let eR = ConvExpr cenv env e // note: reverse the branches - a null test is a failure of an isinst test @@ -912,6 +1086,8 @@ and ConvDecisionTree cenv env tgs typR x = | _ -> let ty = tyOfExpr cenv.g e1 let eq = mkCallEqualsOperator cenv.g m ty e1 (Expr.Const (Const.Zero, m, ty)) + // no need to generate witnesses for generated equality operation calls, see https://github.com/dotnet/fsharp/issues/10389 + let env = { env with suppressWitnesses = true } let eqR = ConvExpr cenv env eq QP.mkCond (eqR, ConvDecisionTree cenv env tgs typR dtree, acc) @@ -922,11 +1098,13 @@ and ConvDecisionTree cenv env tgs typR x = | DecisionTreeTest.ActivePatternCase _ -> wfail(InternalError( "DecisionTreeTest.ActivePatternCase test in quoted expression", m)) | DecisionTreeTest.ArrayLength _ -> wfail(Error(FSComp.SR.crefQuotationsCantContainArrayPatternMatching(), m)) + + | DecisionTreeTest.Error m -> wfail(InternalError( "DecisionTreeTest.Error in quoted expression", m)) ) EmitDebugInfoIfNecessary cenv env m converted | TDSuccess (args, n) -> - let (TTarget(vars, rhs, _)) = tgs.[n] + let (TTarget(vars, rhs, _, _)) = tgs.[n] // TAST stores pattern bindings in reverse order for some reason // Reverse them here to give a good presentation to the user let args = List.rev args @@ -972,8 +1150,7 @@ and ConvILTypeRefUnadjusted cenv m (tr: ILTypeRef) = ConvILTypeRef cenv trefAdjusted and ConvILTypeRef cenv (tr: ILTypeRef) = - match cenv.quotationFormat with - | QuotationSerializationFormat.FSharp_40_Plus -> + if cenv.quotationFormat.SupportsDeserializeEx then let idx = match cenv.referencedTypeDefsTable.TryGetValue tr with | true, idx -> idx @@ -984,7 +1161,7 @@ and ConvILTypeRef cenv (tr: ILTypeRef) = idx QP.Idx idx - | QuotationSerializationFormat.FSharp_20_Plus -> + else let assemblyRef = match tr.Scope with | ILScopeRef.Local -> "." @@ -1011,7 +1188,7 @@ and ConvILType cenv env m ty = and TryElimErasableTyconRef cenv m (tcref: TyconRef) = match tcref.TypeReprInfo with // Get the base type - | TProvidedTypeExtensionPoint info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty)) + | TProvidedTypeRepr info when info.IsErased -> Some (info.BaseTypeForErased (m, cenv.g.obj_ty)) | _ -> None #endif @@ -1021,7 +1198,7 @@ and ConvTyconRef cenv (tcref: TyconRef) m = | Some baseTy -> ConvTyconRef cenv (tcrefOfAppTy cenv.g baseTy) m | None -> match tcref.TypeReprInfo with - | TProvidedTypeExtensionPoint info when not cenv.g.isInteractive && not info.IsErased -> + | TProvidedTypeRepr info when not cenv.g.isInteractive && not info.IsErased -> // Note, generated types are (currently) non-generic let tref = ExtensionTyping.GetILTypeRefOfProvidedType (info.ProvidedType, m) ConvILTypeRefUnadjusted cenv m tref @@ -1043,7 +1220,9 @@ and ConvReturnType cenv envinner m retTy = | None -> ConvVoidType cenv m | Some ty -> ConvType cenv envinner m ty -let ConvExprPublic cenv env e = +let ConvExprPublic cenv suppressWitnesses e = + let env = QuotationTranslationEnv.CreateEmpty(cenv.g) + let env = { env with suppressWitnesses = suppressWitnesses } let astExpr = let astExpr = ConvExpr cenv env e // always emit debug info for the top level expression @@ -1061,53 +1240,96 @@ let ConvMethodBase cenv env (methName, v: Val) = | Some vspr when not v.IsExtensionMember -> let vref = mkLocalValRef v - let tps, argInfos, retTy, _ = GetTypeOfMemberInMemberForm cenv.g vref + let tps, witnessInfos, argInfos, retTy, _ = GetTypeOfMemberInMemberForm cenv.g vref let numEnclTypeArgs = vref.MemberApparentEntity.TyparsNoRange.Length let argTys = argInfos |> List.concat |> List.map fst - let isNewObj = (vspr.MemberFlags.MemberKind = MemberKind.Constructor) + let isNewObj = (vspr.MemberFlags.MemberKind = SynMemberKind.Constructor) // The signature types are w.r.t. to the formal context let envinner = BindFormalTypars env tps + let witnessArgTysR = ConvTypes cenv envinner m (GenWitnessTys cenv.g witnessInfos) let methArgTypesR = ConvTypes cenv envinner m argTys let methRetTypeR = ConvReturnType cenv envinner m retTy let numGenericArgs = tps.Length-numEnclTypeArgs if isNewObj then - QP.MethodBaseData.Ctor - { ctorParent = parentTyconR - ctorArgTypes = methArgTypesR } + assert witnessArgTysR.IsEmpty + QP.MethodBaseData.Ctor + { ctorParent = parentTyconR + ctorArgTypes = methArgTypesR } else - QP.MethodBaseData.Method + QP.MethodBaseData.Method { methParent = parentTyconR - methArgTypes = methArgTypesR + methArgTypes = witnessArgTysR @ methArgTypesR methRetType = methRetTypeR methName = methName numGenericArgs=numGenericArgs } | _ when v.IsExtensionMember -> - let tps, argInfos, retTy, _ = GetTopValTypeInCompiledForm cenv.g v.ValReprInfo.Value v.Type v.Range + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let tps, witnessInfos, argInfos, retTy, _ = GetTopValTypeInCompiledForm cenv.g v.ValReprInfo.Value numEnclosingTypars v.Type v.Range let argTys = argInfos |> List.concat |> List.map fst let envinner = BindFormalTypars env tps + let witnessArgTysR = ConvTypes cenv envinner m (GenWitnessTys cenv.g witnessInfos) let methArgTypesR = ConvTypes cenv envinner m argTys let methRetTypeR = ConvReturnType cenv envinner m retTy let numGenericArgs = tps.Length QP.MethodBaseData.Method { methParent = parentTyconR - methArgTypes = methArgTypesR + methArgTypes = witnessArgTysR @ methArgTypesR methRetType = methRetTypeR methName = methName numGenericArgs=numGenericArgs } - | _ -> + | _ -> + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let tps, witnessInfos, _argInfos, _retTy, _ = GetTopValTypeInCompiledForm cenv.g v.ValReprInfo.Value numEnclosingTypars v.Type v.Range + let envinner = BindFormalTypars env tps + let witnessArgTysR = ConvTypes cenv envinner m (GenWitnessTys cenv.g witnessInfos) + let nWitnesses = witnessArgTysR.Length + let witnessData = (if nWitnesses = 0 then None else Some (ExtraWitnessMethodName methName, nWitnesses)) QP.MethodBaseData.ModuleDefn - { Name = methName - Module = parentTyconR - IsProperty = IsCompiledAsStaticProperty cenv.g v } - - -// FSComp.SR.crefQuotationsCantContainLiteralByteArrays + ({ Name = methName + Module = parentTyconR + IsProperty = IsCompiledAsStaticProperty cenv.g v }, witnessData) + +let ConvReflectedDefinition cenv methName v e = + let g = cenv.g + let ety = tyOfExpr g e + let tps, taue, _ = + match e with + | Expr.TyLambda (_, tps, body, _, _) -> tps, body, applyForallTy g ety (List.map mkTyparTy tps) + | _ -> [], e, ety + let env = QuotationTranslationEnv.CreateEmpty(g) + let env = env.BindTypars tps + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let witnessInfos = GetTraitWitnessInfosOfTypars g numEnclosingTypars tps + let astExpr = + let env = env.BindWitnessInfos witnessInfos + let astExpr = ConvExpr cenv env taue + // always emit debug info for ReflectedDefinition expression + let old = cenv.emitDebugInfoInQuotations + try + cenv.emitDebugInfoInQuotations <- true + EmitDebugInfoIfNecessary cenv env e.Range astExpr + finally + cenv.emitDebugInfoInQuotations <- old + + // Add on fake lambdas for implicit arguments for witnesses + let astExprWithWitnessLambdas = + List.foldBack + (fun witnessInfo e -> + let ty = GenWitnessTy g witnessInfo + let tyR = ConvType cenv env v.DefinitionRange ty + let vR = QuotationPickler.freshVar (witnessInfo.MemberName, tyR, false) + QuotationPickler.mkLambda (vR, e)) + witnessInfos + astExpr + + let mbaseR = ConvMethodBase cenv env (methName, v) + mbaseR, astExprWithWitnessLambdas diff --git a/src/fsharp/QuotationTranslator.fsi b/src/fsharp/QuotationTranslator.fsi index 184f1d3da4e..c6f3bcd48e5 100755 --- a/src/fsharp/QuotationTranslator.fsi +++ b/src/fsharp/QuotationTranslator.fsi @@ -1,23 +1,17 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// Convert quoted TAST data structures to structures ready for pickling - +/// Convert quoted TAST data structures to structures ready for pickling module internal FSharp.Compiler.QuotationTranslator open FSharp.Compiler -open FSharp.Compiler.Range +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.Import -open FSharp.Compiler.Tast +open FSharp.Compiler.Text open FSharp.Compiler.TcGlobals -open FSharp.Compiler.AbstractIL.IL - -[] -type QuotationTranslationEnv = - static member Empty : QuotationTranslationEnv - member BindTypars : Typars -> QuotationTranslationEnv +open FSharp.Compiler.TypedTree exception InvalidQuotedTerm of exn -exception IgnoringPartOfQuotedTermWarning of string * Range.range +exception IgnoringPartOfQuotedTermWarning of string * range [] type IsReflectedDefinition = @@ -26,19 +20,22 @@ type IsReflectedDefinition = [] type QuotationSerializationFormat = - /// Indicates that type references are emitted as integer indexes into a supplied table - | FSharp_40_Plus - | FSharp_20_Plus + { + /// Indicates that witness parameters are recorded + SupportsWitnesses: bool + + /// Indicates that type references are emitted as integer indexes into a supplied table + SupportsDeserializeEx: bool + } [] type QuotationGenerationScope = - static member Create: TcGlobals * ImportMap * CcuThunk * IsReflectedDefinition -> QuotationGenerationScope - member Close: unit -> ILTypeRef list * (TType * range) list * (Expr * range) list + static member Create: TcGlobals * ImportMap * CcuThunk * ConstraintSolver.TcValF * IsReflectedDefinition -> QuotationGenerationScope + member Close: unit -> ILTypeRef list * (TType * range) list * (Expr * range) list static member ComputeQuotationFormat : TcGlobals -> QuotationSerializationFormat -val ConvExprPublic : QuotationGenerationScope -> QuotationTranslationEnv -> Expr -> QuotationPickler.ExprData -val ConvMethodBase : QuotationGenerationScope -> QuotationTranslationEnv -> string * Val -> QuotationPickler.MethodBaseData - +val ConvExprPublic : QuotationGenerationScope -> suppressWitnesses: bool -> Expr -> QuotationPickler.ExprData +val ConvReflectedDefinition: QuotationGenerationScope -> string -> Val -> Expr -> QuotationPickler.MethodBaseData * QuotationPickler.ExprData val (|ModuleValueOrMemberUse|_|) : TcGlobals -> Expr -> (ValRef * ValUseFlag * Expr * TType * TypeInst * Expr list) option val (|SimpleArrayLoopUpperBound|_|) : Expr -> unit option diff --git a/src/fsharp/ReferenceResolver.fs b/src/fsharp/ReferenceResolver.fs index d9a23ecb2a1..67105cc6784 100644 --- a/src/fsharp/ReferenceResolver.fs +++ b/src/fsharp/ReferenceResolver.fs @@ -1,56 +1,63 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler - -module public ReferenceResolver = - - exception internal ResolutionFailure - - [] - type ResolutionEnvironment = - /// Indicates a script or source being edited or compiled. Uses reference assemblies (not implementation assemblies). - | EditingOrCompilation of isEditing: bool - /// Indicates a script or source being dynamically compiled and executed. Uses implementation assemblies. - | CompilationAndEvaluation - - type ResolvedFile = - { /// Item specification. - itemSpec:string - /// Prepare textual information about where the assembly was resolved from, used for tooltip output - prepareToolTip: string * string -> string - /// Round-tripped baggage - baggage:string - } - - override this.ToString() = sprintf "ResolvedFile(%s)" this.itemSpec - - [] - type Resolver = - /// Get the "v4.5.1"-style moniker for the highest installed .NET Framework version. - /// This is the value passed back to Resolve if no explicit "mscorlib" has been given. - /// - /// Note: If an explicit "mscorlib" is given, then --noframework is being used, and the whole ReferenceResolver logic is essentially - /// unused. However in the future an option may be added to allow an explicit specification of - /// a .NET Framework version to use for scripts. - abstract HighestInstalledNetFrameworkVersion : unit -> string +namespace FSharp.Compiler.CodeAnalysis + +exception internal LegacyResolutionFailure + +[] +type LegacyResolutionEnvironment = + /// Indicates a script or source being edited or compiled. Uses reference assemblies (not implementation assemblies). + | EditingOrCompilation of isEditing: bool + + /// Indicates a script or source being dynamically compiled and executed. Uses implementation assemblies. + | CompilationAndEvaluation + +type LegacyResolvedFile = + { + /// Item specification. + itemSpec:string + + /// Prepare textual information about where the assembly was resolved from, used for tooltip output + prepareToolTip: string * string -> string + + /// Round-tripped baggage + baggage:string + } + + override this.ToString() = sprintf "LegacyResolvedFile(%s)" this.itemSpec + +[] +type internal ILegacyReferenceResolver = + /// Get the "v4.5.1"-style moniker for the highest installed .NET Framework version. + /// This is the value passed back to Resolve if no explicit "mscorlib" has been given. + /// + /// Note: If an explicit "mscorlib" is given, then --noframework is being used, and the whole ReferenceResolver logic is essentially + /// unused. However in the future an option may be added to allow an explicit specification of + /// a .NET Framework version to use for scripts. + abstract HighestInstalledNetFrameworkVersion : unit -> string - /// Get the Reference Assemblies directory for the .NET Framework (on Windows) - /// This is added to the default resolution path for - /// design-time compilations. - abstract DotNetFrameworkReferenceAssembliesRootDirectory : string - - /// Perform assembly resolution on the given references under the given conditions - abstract Resolve : - resolutionEnvironment: ResolutionEnvironment * - // The actual reference paths or assembly name text, plus baggage - references:(string (* baggage *) * string)[] * - // e.g. v4.5.1 - targetFrameworkVersion:string * - targetFrameworkDirectories:string list * - targetProcessorArchitecture:string * - fsharpCoreDir:string * - explicitIncludeDirs:string list * - implicitIncludeDir:string * - logMessage:(string->unit) * - logDiagnostic:(bool -> string -> string -> unit) - -> ResolvedFile[] + /// Get the Reference Assemblies directory for the .NET Framework (on Windows) + /// This is added to the default resolution path for + /// design-time compilations. + abstract DotNetFrameworkReferenceAssembliesRootDirectory : string + + /// Perform assembly resolution on the given references under the given conditions + abstract Resolve : + resolutionEnvironment: LegacyResolutionEnvironment * + // The actual reference paths or assembly name text, plus baggage + references:(string (* baggage *) * string)[] * + // e.g. v4.5.1 + targetFrameworkVersion:string * + targetFrameworkDirectories:string list * + targetProcessorArchitecture:string * + fsharpCoreDir:string * + explicitIncludeDirs:string list * + implicitIncludeDir:string * + logMessage:(string->unit) * + logDiagnostic:(bool -> string -> string -> unit) + -> LegacyResolvedFile[] + +[] +type LegacyReferenceResolver(impl:ILegacyReferenceResolver) = + member internal _.Impl = impl + diff --git a/src/fsharp/ReferenceResolver.fsi b/src/fsharp/ReferenceResolver.fsi new file mode 100644 index 00000000000..8ef591de7f6 --- /dev/null +++ b/src/fsharp/ReferenceResolver.fsi @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System + +exception internal LegacyResolutionFailure + +[] +type internal LegacyResolutionEnvironment = + /// Indicates a script or source being edited or compiled. Uses reference assemblies (not implementation assemblies). + | EditingOrCompilation of isEditing: bool + + /// Indicates a script or source being dynamically compiled and executed. Uses implementation assemblies. + | CompilationAndEvaluation + +type internal LegacyResolvedFile = + { + /// Item specification. + itemSpec:string + + /// Prepare textual information about where the assembly was resolved from, used for tooltip output + prepareToolTip: string * string -> string + + /// Round-tripped baggage + baggage:string + } + +[] +type internal ILegacyReferenceResolver = + /// Get the "v4.5.1"-style moniker for the highest installed .NET Framework version. + /// This is the value passed back to Resolve if no explicit "mscorlib" has been given. + /// + /// Note: If an explicit "mscorlib" is given, then --noframework is being used, and the whole ReferenceResolver logic is essentially + /// unused. However in the future an option may be added to allow an explicit specification of + /// a .NET Framework version to use for scripts. + abstract HighestInstalledNetFrameworkVersion: unit -> string + + /// Perform assembly resolution on the given references under the given conditions + abstract Resolve: + resolutionEnvironment: LegacyResolutionEnvironment * + references:(string * string) [] * + targetFrameworkVersion:string * + targetFrameworkDirectories:string list * + targetProcessorArchitecture:string * + fsharpCoreDir:string * + explicitIncludeDirs:string list * + implicitIncludeDir:string * + logMessage:(string -> unit) * + logDiagnostic:(bool -> string -> string -> unit) -> + LegacyResolvedFile [] + + /// Get the Reference Assemblies directory for the .NET Framework (on Windows) + /// This is added to the default resolution path for + /// design-time compilations. + abstract DotNetFrameworkReferenceAssembliesRootDirectory: string + +// Note, two implementations of this are provided, and no further implementations can be added from +// outside FSharp.Compiler.Service +[] +type LegacyReferenceResolver = + internal new: impl: ILegacyReferenceResolver -> LegacyReferenceResolver + member internal Impl: ILegacyReferenceResolver + diff --git a/src/fsharp/ScriptClosure.fs b/src/fsharp/ScriptClosure.fs new file mode 100644 index 00000000000..dd06780ce3c --- /dev/null +++ b/src/fsharp/ScriptClosure.fs @@ -0,0 +1,496 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Compute the load closure of a set of script files +module internal FSharp.Compiler.ScriptClosure + +open System +open System.Collections.Generic +open System.IO +open System.Text +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range + +[] +type LoadClosureInput = + { FileName: string + SyntaxTree: ParsedInput option + ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + MetaCommandDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list } + +[] +type LoadClosure = + { /// The source files along with the ranges of the #load positions in each file. + SourceFiles: (string * range list) list + + /// The resolved references along with the ranges of the #r positions in each file. + References: (string * AssemblyResolution list) list + + /// The resolved pacakge references along with the ranges of the #r positions in each file. + PackageReferences: (range * string list)[] + + /// Whether we're decided to use .NET Framework analysis for this script + UseDesktopFramework: bool + + /// Was the SDK directory override given? + SdkDirOverride: string option + + /// The list of references that were not resolved during load closure. These may still be extension references. + UnresolvedReferences: UnresolvedAssemblyReference list + + /// The list of all sources in the closure with inputs when available + Inputs: LoadClosureInput list + + /// The #load, including those that didn't resolve + OriginalLoadReferences: (range * string * string) list + + /// The #nowarns + NoWarns: (string * range list) list + + /// Diagnostics seen while processing resolutions + ResolutionDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + /// Diagnostics seen while parsing root of closure + AllRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + /// Diagnostics seen while processing the compiler options implied root of closure + LoadClosureRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + } + + +[] +type CodeContext = + | CompilationAndEvaluation // in fsi.exe + | Compilation // in fsc.exe + | Editing // in VS + +module ScriptPreprocessClosure = + + /// Represents an input to the closure finding process + type ClosureSource = ClosureSource of filename: string * referenceRange: range * sourceText: ISourceText * parseRequired: bool + + /// Represents an output of the closure finding process + type ClosureFile = ClosureFile of string * range * ParsedInput option * (PhasedDiagnostic * FSharpDiagnosticSeverity) list * (PhasedDiagnostic * FSharpDiagnosticSeverity) list * (string * range) list // filename, range, errors, warnings, nowarns + + type Observed() = + let seen = Dictionary<_, bool>() + member ob.SetSeen check = + if not(seen.ContainsKey check) then + seen.Add(check, true) + + member ob.HaveSeen check = + seen.ContainsKey check + + /// Parse a script from source. + let ParseScriptText + (filename: string, sourceText: ISourceText, tcConfig: TcConfig, codeContext, + lexResourceManager: Lexhelp.LexResourceManager, errorLogger: ErrorLogger) = + + // fsc.exe -- COMPILED\!INTERACTIVE + // fsi.exe -- !COMPILED\INTERACTIVE + // Language service + // .fs -- EDITING + COMPILED\!INTERACTIVE + // .fsx -- EDITING + !COMPILED\INTERACTIVE + let defines = + match codeContext with + | CodeContext.CompilationAndEvaluation -> ["INTERACTIVE"] + | CodeContext.Compilation -> ["COMPILED"] + | CodeContext.Editing -> "EDITING" :: (if IsScript filename then ["INTERACTIVE"] else ["COMPILED"]) + + let lexbuf = UnicodeLexing.SourceTextAsLexbuf(true, tcConfig.langVersion, sourceText) + + let isLastCompiland = (IsScript filename), tcConfig.target.IsExe // The root compiland is last in the list of compilands. + ParseOneInputLexbuf (tcConfig, lexResourceManager, defines, lexbuf, filename, isLastCompiland, errorLogger) + + /// Create a TcConfig for load closure starting from a single .fsx file + let CreateScriptTextTcConfig + (legacyReferenceResolver, defaultFSharpBinariesDir, + filename: string, codeContext, + useSimpleResolution, useFsiAuxLib, + basicReferences, applyCommandLineArgs, + assumeDotNetFramework, useSdkRefs, sdkDirOverride, + tryGetMetadataSnapshot, reduceMemoryUsage) = + + let projectDir = Path.GetDirectoryName filename + let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation) + let isInvalidationSupported = (codeContext = CodeContext.Editing) + + let rangeForErrors = mkFirstLineOfFile filename + let tcConfigB = + TcConfigBuilder.CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir, + reduceMemoryUsage, + projectDir, + isInteractive, + isInvalidationSupported, + CopyFSharpCoreFlag.No, + tryGetMetadataSnapshot, + sdkDirOverride, + rangeForErrors) + tcConfigB.SetPrimaryAssembly (if assumeDotNetFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) + tcConfigB.SetUseSdkRefs useSdkRefs + + applyCommandLineArgs tcConfigB + + // Work out the references for the script in its location. This may produce diagnostics. + let scriptDefaultReferencesDiagnostics = + + match basicReferences with + | None -> + let errorLogger = CapturingErrorLogger("ScriptDefaultReferences") + use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + let references, useDotNetFramework = tcConfigB.FxResolver.GetDefaultReferences useFsiAuxLib + + // If the user requested .NET Core scripting but something went wrong and we reverted to + // .NET Framework scripting then we must adjust both the primaryAssembly and fxResolver + if useDotNetFramework <> assumeDotNetFramework then + tcConfigB.SetPrimaryAssembly (if useDotNetFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) + + // Add script references + for reference in references do + tcConfigB.AddReferencedAssemblyByPath(range0, reference) + + errorLogger.Diagnostics + + | Some (rs, diagnostics) -> + for m, reference in rs do + tcConfigB.AddReferencedAssemblyByPath(m, reference) + diagnostics + + tcConfigB.resolutionEnvironment <- + match codeContext with + | CodeContext.Editing -> LegacyResolutionEnvironment.EditingOrCompilation true + | CodeContext.Compilation -> LegacyResolutionEnvironment.EditingOrCompilation false + | CodeContext.CompilationAndEvaluation -> LegacyResolutionEnvironment.CompilationAndEvaluation + tcConfigB.framework <- false + tcConfigB.useSimpleResolution <- useSimpleResolution + // Indicates that there are some references not in basicReferencesForScriptLoadClosure which should + // be added conditionally once the relevant version of mscorlib.dll has been detected. + tcConfigB.implicitlyResolveAssemblies <- false + tcConfigB.SetUseSdkRefs useSdkRefs + + TcConfig.Create(tcConfigB, validate=true), scriptDefaultReferencesDiagnostics + + let ClosureSourceOfFilename(filename, m, inputCodePage, parseRequired) = + try + let filename = FileSystem.GetFullPathShim filename + use stream = FileSystem.OpenFileForReadShim(filename) + use reader = + match inputCodePage with + | None -> new StreamReader(stream, true) + | Some (n: int) -> new StreamReader(stream, Encoding.GetEncoding n) + let source = reader.ReadToEnd() + [ClosureSource(filename, m, SourceText.ofString source, parseRequired)] + with e -> + errorRecovery e m + [] + + let ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn + (tcConfig: TcConfig, inp: ParsedInput, + pathOfMetaCommandSource, dependencyProvider) = + + let tcConfigB = tcConfig.CloneToBuilder() + let mutable nowarns = [] + let getWarningNumber = fun () (m, s) -> nowarns <- (s, m) :: nowarns + let addReferenceDirective = fun () (m, s, directive) -> tcConfigB.AddReferenceDirective(dependencyProvider, m, s, directive) + let addLoadedSource = fun () (m, s) -> tcConfigB.AddLoadedSource(m, s, pathOfMetaCommandSource) + try + ProcessMetaCommandsFromInput (getWarningNumber, addReferenceDirective, addLoadedSource) (tcConfigB, inp, pathOfMetaCommandSource, ()) + with ReportedError _ -> + // Recover by using whatever did end up in the tcConfig + () + + try + TcConfig.Create(tcConfigB, validate=false), nowarns + with ReportedError _ -> + // Recover by using a default TcConfig. + let tcConfigB = tcConfig.CloneToBuilder() + TcConfig.Create(tcConfigB, validate=false), nowarns + + let FindClosureFiles + (mainFile, _m, closureSources, origTcConfig:TcConfig, + codeContext, lexResourceManager: Lexhelp.LexResourceManager, dependencyProvider: DependencyProvider) = + + let mutable tcConfig = origTcConfig + + let observedSources = Observed() + let loadScripts = HashSet<_>() + let packageReferences = Dictionary(HashIdentity.Structural) + + // Resolve the packages + let rec resolveDependencyManagerSources scriptName = + if not (loadScripts.Contains scriptName) then + [ for kv in tcConfig.packageManagerLines do + let packageManagerKey, packageManagerLines = kv.Key, kv.Value + match packageManagerLines with + | [] -> () + | { Directive=_; LineStatus=_; Line=_; Range=m } :: _ -> + let reportError = + ResolvingErrorReport (fun errorType err msg -> + let error = err, msg + match errorType with + | ErrorReportType.Warning -> warning(Error(error, m)) + | ErrorReportType.Error -> errorR(Error(error, m))) + + match origTcConfig.packageManagerLines |> Map.tryFind packageManagerKey with + | Some oldDependencyManagerLines when oldDependencyManagerLines = packageManagerLines -> () + | _ -> + let outputDir = tcConfig.outputDir |> Option.defaultValue "" + match dependencyProvider.TryFindDependencyManagerByKey(tcConfig.compilerToolPaths, outputDir, reportError, packageManagerKey) with + | null -> + errorR(Error(dependencyProvider.CreatePackageManagerUnknownError(tcConfig.compilerToolPaths, outputDir, packageManagerKey, reportError), m)) + + | dependencyManager -> + let directive d = + match d with + | Directive.Resolution -> "r" + | Directive.Include -> "i" + + let packageManagerTextLines = packageManagerLines |> List.map(fun l -> directive l.Directive, l.Line) + let tfm, rid = tcConfig.FxResolver.GetTfmAndRid() + let result = dependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError, tfm, rid, tcConfig.implicitIncludeDir, mainFile, scriptName) + if result.Success then + // Resolution produced no errors + //Write outputs in F# Interactive and compiler + if codeContext <> CodeContext.Editing then + for line in result.StdOut do Console.Out.WriteLine(line) + for line in result.StdError do Console.Error.WriteLine(line) + + packageReferences.[m] <- [ for script in result.SourceFiles do yield! FileSystem.OpenFileForReadShim(script).ReadLines() ] + if not (Seq.isEmpty result.Roots) then + let tcConfigB = tcConfig.CloneToBuilder() + for folder in result.Roots do + tcConfigB.AddIncludePath(m, folder, "") + tcConfigB.packageManagerLines <- PackageManagerLine.SetLinesAsProcessed packageManagerKey tcConfigB.packageManagerLines + tcConfig <- TcConfig.Create(tcConfigB, validate=false) + + if not (Seq.isEmpty result.Resolutions) then + let tcConfigB = tcConfig.CloneToBuilder() + for resolution in result.Resolutions do + tcConfigB.AddReferencedAssemblyByPath(m, resolution) + tcConfig <- TcConfig.Create(tcConfigB, validate = false) + + for script in result.SourceFiles do + use stream = FileSystem.OpenFileForReadShim(script) + let scriptText = stream.ReadAllText() + loadScripts.Add script |> ignore + let iSourceText = SourceText.ofString scriptText + yield! loop (ClosureSource(script, m, iSourceText, true)) + + else + // Send outputs via diagnostics + if (result.StdOut.Length > 0 || result.StdError.Length > 0) then + for line in Array.append result.StdOut result.StdError do + errorR(Error(FSComp.SR.packageManagerError(line), m)) + // Resolution produced errors update packagerManagerLines entries to note these failure + // failed resolutions will no longer be considered + let tcConfigB = tcConfig.CloneToBuilder() + tcConfigB.packageManagerLines <- PackageManagerLine.RemoveUnprocessedLines packageManagerKey tcConfigB.packageManagerLines + tcConfig <- TcConfig.Create(tcConfigB, validate=false)] + else [] + + and loop (ClosureSource(filename, m, sourceText, parseRequired)) = + [ if not (observedSources.HaveSeen(filename)) then + observedSources.SetSeen(filename) + //printfn "visiting %s" filename + if IsScript filename || parseRequired then + let parseResult, parseDiagnostics = + let errorLogger = CapturingErrorLogger("FindClosureParse") + use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + let result = ParseScriptText (filename, sourceText, tcConfig, codeContext, lexResourceManager, errorLogger) + result, errorLogger.Diagnostics + + let errorLogger = CapturingErrorLogger("FindClosureMetaCommands") + use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + let pathOfMetaCommandSource = Path.GetDirectoryName filename + let preSources = tcConfig.GetAvailableLoadedSources() + + let tcConfigResult, noWarns = ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn (tcConfig, parseResult, pathOfMetaCommandSource, dependencyProvider) + tcConfig <- tcConfigResult // We accumulate the tcConfig in order to collect assembly references + + yield! resolveDependencyManagerSources filename + + let postSources = tcConfig.GetAvailableLoadedSources() + let sources = if preSources.Length < postSources.Length then postSources.[preSources.Length..] else [] + + yield! resolveDependencyManagerSources filename + for m, subFile in sources do + if IsScript subFile then + for subSource in ClosureSourceOfFilename(subFile, m, tcConfigResult.inputCodePage, false) do + yield! loop subSource + else + yield ClosureFile(subFile, m, None, [], [], []) + yield ClosureFile(filename, m, Some parseResult, parseDiagnostics, errorLogger.Diagnostics, noWarns) + + else + // Don't traverse into .fs leafs. + printfn "yielding non-script source %s" filename + yield ClosureFile(filename, m, None, [], [], []) ] + + let sources = closureSources |> List.collect loop + let packageReferences = packageReferences |> Seq.map (fun kvp -> kvp.Key, kvp.Value) |> Seq.toArray + sources, tcConfig, packageReferences + + /// Reduce the full directive closure into LoadClosure + let GetLoadClosure(rootFilename, closureFiles, tcConfig: TcConfig, codeContext, packageReferences, earlierDiagnostics) = + + // Mark the last file as isLastCompiland. + let closureFiles = + if isNil closureFiles then + closureFiles + else + match List.frontAndBack closureFiles with + | rest, ClosureFile + (filename, m, + Some(ParsedInput.ImplFile (ParsedImplFileInput (name, isScript, qualNameOfFile, scopedPragmas, hashDirectives, implFileFlags, _))), + parseDiagnostics, metaDiagnostics, nowarns) -> + + let isLastCompiland = (true, tcConfig.target.IsExe) + rest @ [ClosureFile + (filename, m, + Some(ParsedInput.ImplFile (ParsedImplFileInput (name, isScript, qualNameOfFile, scopedPragmas, hashDirectives, implFileFlags, isLastCompiland))), + parseDiagnostics, metaDiagnostics, nowarns)] + + | _ -> closureFiles + + // Get all source files. + let sourceFiles = [ for ClosureFile(filename, m, _, _, _, _) in closureFiles -> (filename, m) ] + + let sourceInputs = + [ for ClosureFile(filename, _, input, parseDiagnostics, metaDiagnostics, _nowarns) in closureFiles -> + ({ FileName=filename + SyntaxTree=input + ParseDiagnostics=parseDiagnostics + MetaCommandDiagnostics=metaDiagnostics } : LoadClosureInput) ] + + let globalNoWarns = closureFiles |> List.collect (fun (ClosureFile(_, _, _, _, _, noWarns)) -> noWarns) + + // Resolve all references. + let references, unresolvedReferences, resolutionDiagnostics = + let errorLogger = CapturingErrorLogger("GetLoadClosure") + + use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + let references, unresolvedReferences = TcAssemblyResolutions.GetAssemblyResolutionInformation(tcConfig) + let references = references |> List.map (fun ar -> ar.resolvedPath, ar) + references, unresolvedReferences, errorLogger.Diagnostics + + // Root errors and warnings - look at the last item in the closureFiles list + let loadClosureRootDiagnostics, allRootDiagnostics = + match List.rev closureFiles with + | ClosureFile(_, _, _, parseDiagnostics, metaDiagnostics, _) :: _ -> + (earlierDiagnostics @ metaDiagnostics @ resolutionDiagnostics), + (parseDiagnostics @ earlierDiagnostics @ metaDiagnostics @ resolutionDiagnostics) + | _ -> [], [] // When no file existed. + + let isRootRange exn = + match GetRangeOfDiagnostic exn with + | Some m -> + // Return true if the error was *not* from a #load-ed file. + let isArgParameterWhileNotEditing = (codeContext <> CodeContext.Editing) && (equals m range0 || equals m rangeStartup || equals m rangeCmdArgs) + let isThisFileName = (0 = String.Compare(rootFilename, m.FileName, StringComparison.OrdinalIgnoreCase)) + isArgParameterWhileNotEditing || isThisFileName + | None -> true + + // Filter out non-root errors and warnings + let allRootDiagnostics = allRootDiagnostics |> List.filter (fst >> isRootRange) + + let result: LoadClosure = + { SourceFiles = List.groupBy fst sourceFiles |> List.map (map2Of2 (List.map snd)) + References = List.groupBy fst references |> List.map (map2Of2 (List.map snd)) + PackageReferences = packageReferences + UseDesktopFramework = (tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib) + SdkDirOverride = tcConfig.sdkDirOverride + UnresolvedReferences = unresolvedReferences + Inputs = sourceInputs + NoWarns = List.groupBy fst globalNoWarns |> List.map (map2Of2 (List.map snd)) + OriginalLoadReferences = tcConfig.loadedSources + ResolutionDiagnostics = resolutionDiagnostics + AllRootFileDiagnostics = allRootDiagnostics + LoadClosureRootFileDiagnostics = loadClosureRootDiagnostics } + + result + + /// Given source text, find the full load closure. Used from service.fs, when editing a script file + let GetFullClosureOfScriptText + (legacyReferenceResolver, defaultFSharpBinariesDir, + filename, sourceText, codeContext, + useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDirOverride, + lexResourceManager: Lexhelp.LexResourceManager, + applyCommandLineArgs, assumeDotNetFramework, + tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProvider) = + + // Resolve the basic references such as FSharp.Core.dll first, before processing any #I directives in the script + // + // This is tries to mimic the action of running the script in F# Interactive - the initial context for scripting is created + // first, then #I and other directives are processed. + let references0, assumeDotNetFramework, scriptDefaultReferencesDiagnostics = + let tcConfig, scriptDefaultReferencesDiagnostics = + CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, + filename, codeContext, useSimpleResolution, + useFsiAuxLib, None, applyCommandLineArgs, assumeDotNetFramework, + useSdkRefs, sdkDirOverride, tryGetMetadataSnapshot, reduceMemoryUsage) + + let resolutions0, _unresolvedReferences = TcAssemblyResolutions.GetAssemblyResolutionInformation(tcConfig) + let references0 = resolutions0 |> List.map (fun r->r.originalReference.Range, r.resolvedPath) |> Seq.distinct |> List.ofSeq + references0, tcConfig.assumeDotNetFramework, scriptDefaultReferencesDiagnostics + + let tcConfig, scriptDefaultReferencesDiagnostics = + CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename, + codeContext, useSimpleResolution, useFsiAuxLib, Some (references0, scriptDefaultReferencesDiagnostics), + applyCommandLineArgs, assumeDotNetFramework, useSdkRefs, sdkDirOverride, + tryGetMetadataSnapshot, reduceMemoryUsage) + + let closureSources = [ClosureSource(filename, range0, sourceText, true)] + let closureFiles, tcConfig, packageReferences = FindClosureFiles(filename, range0, closureSources, tcConfig, codeContext, lexResourceManager, dependencyProvider) + GetLoadClosure(filename, closureFiles, tcConfig, codeContext, packageReferences, scriptDefaultReferencesDiagnostics) + + /// Given source filename, find the full load closure + /// Used from fsi.fs and fsc.fs, for #load and command line + let GetFullClosureOfScriptFiles + (tcConfig:TcConfig, files:(string*range) list, codeContext, + lexResourceManager: Lexhelp.LexResourceManager, dependencyProvider) = + + let mainFile, mainFileRange = List.last files + let closureSources = files |> List.collect (fun (filename, m) -> ClosureSourceOfFilename(filename, m,tcConfig.inputCodePage,true)) + let closureFiles, tcConfig, packageReferences = FindClosureFiles(mainFile, mainFileRange, closureSources, tcConfig, codeContext, lexResourceManager, dependencyProvider) + GetLoadClosure(mainFile, closureFiles, tcConfig, codeContext, packageReferences, []) + +type LoadClosure with + /// Analyze a script text and find the closure of its references. + /// Used from FCS, when editing a script file. + // + /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the + /// same arguments as the rest of the application. + static member ComputeClosureOfScriptText + (legacyReferenceResolver, defaultFSharpBinariesDir, + filename: string, sourceText: ISourceText, implicitDefines, useSimpleResolution: bool, + useFsiAuxLib, useSdkRefs, sdkDir, lexResourceManager: Lexhelp.LexResourceManager, + applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot, + reduceMemoryUsage, dependencyProvider) = + + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + ScriptPreprocessClosure.GetFullClosureOfScriptText + (legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, + implicitDefines, useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDir, lexResourceManager, + applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProvider) + + /// Analyze a set of script files and find the closure of their references. + static member ComputeClosureOfScriptFiles + (tcConfig: TcConfig, files:(string*range) list, implicitDefines, + lexResourceManager: Lexhelp.LexResourceManager, dependencyProvider) = + + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + ScriptPreprocessClosure.GetFullClosureOfScriptFiles (tcConfig, files, implicitDefines, lexResourceManager, dependencyProvider) diff --git a/src/fsharp/ScriptClosure.fsi b/src/fsharp/ScriptClosure.fsi new file mode 100644 index 00000000000..8831b0f49ab --- /dev/null +++ b/src/fsharp/ScriptClosure.fsi @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Compute the load closure of a set of script files +module internal FSharp.Compiler.ScriptClosure + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +[] +type CodeContext = + | CompilationAndEvaluation + | Compilation + | Editing + +[] +type LoadClosureInput = + { + FileName: string + + SyntaxTree: ParsedInput option + + ParseDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + MetaCommandDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + } + +[] +type LoadClosure = + { /// The source files along with the ranges of the #load positions in each file. + SourceFiles: (string * range list) list + + /// The resolved references along with the ranges of the #r positions in each file. + References: (string * AssemblyResolution list) list + + /// The resolved pacakge references along with the ranges of the #r positions in each file. + PackageReferences: (range * string list)[] + + /// Whether we're decided to use .NET Framework analysis for this script + UseDesktopFramework: bool + + /// Was the SDK directory override given? + SdkDirOverride: string option + + /// The list of references that were not resolved during load closure. + UnresolvedReferences: UnresolvedAssemblyReference list + + /// The list of all sources in the closure with inputs when available, with associated parse errors and warnings + Inputs: LoadClosureInput list + + /// The original #load references, including those that didn't resolve + OriginalLoadReferences: (range * string * string) list + + /// The #nowarns + NoWarns: (string * range list) list + + /// Diagnostics seen while processing resolutions + ResolutionDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + /// Diagnostics to show for root of closure (used by fsc.fs) + AllRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list + + /// Diagnostics seen while processing the compiler options implied root of closure + LoadClosureRootFileDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity) list } + + /// Analyze a script text and find the closure of its references. + /// Used from FCS, when editing a script file. + // + /// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the + /// same arguments as the rest of the application. + static member ComputeClosureOfScriptText: + legacyReferenceResolver: LegacyReferenceResolver * + defaultFSharpBinariesDir: string * + filename: string * + sourceText: ISourceText * + implicitDefines:CodeContext * + useSimpleResolution: bool * + useFsiAuxLib: bool * + useSdkRefs: bool * + sdkDir: string option * + lexResourceManager: Lexhelp.LexResourceManager * + applyCompilerOptions: (TcConfigBuilder -> unit) * + assumeDotNetFramework: bool * + tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * + reduceMemoryUsage: ReduceMemoryFlag * + dependencyProvider: DependencyProvider + -> LoadClosure + + /// Analyze a set of script files and find the closure of their references. The resulting references are then added to the given TcConfig. + /// Used from fsi.fs and fsc.fs, for #load and command line. + static member ComputeClosureOfScriptFiles: + tcConfig:TcConfig * + (string * range) list * + implicitDefines:CodeContext * + lexResourceManager: Lexhelp.LexResourceManager * + dependencyProvider: DependencyProvider + -> LoadClosure + diff --git a/src/fsharp/SignatureConformance.fs b/src/fsharp/SignatureConformance.fs index 0a84d3af5f8..ab6d5bcced8 100644 --- a/src/fsharp/SignatureConformance.fs +++ b/src/fsharp/SignatureConformance.fs @@ -6,29 +6,35 @@ module internal FSharp.Compiler.SignatureConformance open System.Text +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Range -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib open FSharp.Compiler.Infos +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.InfoReader #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping #endif +exception RequiredButNotSpecified of DisplayEnv * ModuleOrNamespaceRef * string * (StringBuilder -> unit) * range -exception RequiredButNotSpecified of DisplayEnv * Tast.ModuleOrNamespaceRef * string * (StringBuilder -> unit) * range -exception ValueNotContained of DisplayEnv * Tast.ModuleOrNamespaceRef * Val * Val * (string * string * string -> string) -exception ConstrNotContained of DisplayEnv * UnionCase * UnionCase * (string * string -> string) -exception ExnconstrNotContained of DisplayEnv * Tycon * Tycon * (string * string -> string) -exception FieldNotContained of DisplayEnv * RecdField * RecdField * (string * string -> string) -exception InterfaceNotRevealed of DisplayEnv * TType * range +exception ValueNotContained of DisplayEnv * InfoReader * ModuleOrNamespaceRef * Val * Val * (string * string * string -> string) +exception ConstrNotContained of DisplayEnv * InfoReader * Tycon * UnionCase * UnionCase * (string * string -> string) + +exception ExnconstrNotContained of DisplayEnv * InfoReader * Tycon * Tycon * (string * string -> string) + +exception FieldNotContained of DisplayEnv * InfoReader * Tycon * RecdField * RecdField * (string * string -> string) + +exception InterfaceNotRevealed of DisplayEnv * TType * range // Use a type to capture the constant, common parameters type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = @@ -131,7 +137,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | TyparConstraint.DefaultsTo(_, _acty, _) -> true | _ -> if not (List.exists (typarConstraintsAEquiv g aenv implTyparCx) sigTypar.Constraints) - then (errorR(Error(FSComp.SR.typrelSigImplNotCompatibleConstraintsDiffer(sigTypar.Name, Layout.showL(NicePrint.layoutTyparConstraint denv (implTypar, implTyparCx))), m)); false) + then (errorR(Error(FSComp.SR.typrelSigImplNotCompatibleConstraintsDiffer(sigTypar.Name, LayoutRender.showL(NicePrint.layoutTyparConstraint denv (implTypar, implTyparCx))), m)); false) else true) && // Check the constraints in the signature are present in the implementation @@ -144,12 +150,12 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | TyparConstraint.SupportsEquality _ -> true | _ -> if not (List.exists (fun implTyparCx -> typarConstraintsAEquiv g aenv implTyparCx sigTyparCx) implTypar.Constraints) then - (errorR(Error(FSComp.SR.typrelSigImplNotCompatibleConstraintsDifferRemove(sigTypar.Name, Layout.showL(NicePrint.layoutTyparConstraint denv (sigTypar, sigTyparCx))), m)); false) + (errorR(Error(FSComp.SR.typrelSigImplNotCompatibleConstraintsDifferRemove(sigTypar.Name, LayoutRender.showL(NicePrint.layoutTyparConstraint denv (sigTypar, sigTyparCx))), m)); false) else true) && (not checkingSig || checkAttribs aenv implTypar.Attribs sigTypar.Attribs (fun attribs -> implTypar.SetAttribs attribs))) - and checkTypeDef (aenv: TypeEquivEnv) (implTycon: Tycon) (sigTycon: Tycon) = + and checkTypeDef (aenv: TypeEquivEnv) (infoReader: InfoReader) (implTycon: Tycon) (sigTycon: Tycon) = let m = implTycon.Range // Propagate defn location information from implementation to signature . @@ -166,7 +172,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = false else - checkExnInfo (fun f -> ExnconstrNotContained(denv, implTycon, sigTycon, f)) aenv implTycon.ExceptionInfo sigTycon.ExceptionInfo && + checkExnInfo (fun f -> ExnconstrNotContained(denv, infoReader, implTycon, sigTycon, f)) aenv infoReader implTycon implTycon.ExceptionInfo sigTycon.ExceptionInfo && let implTypars = implTycon.Typars m let sigTypars = sigTycon.Typars m @@ -247,10 +253,10 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = else checkTypars m aenv implTypars sigTypars && - checkTypeRepr m aenv implTycon sigTycon.TypeReprInfo && + checkTypeRepr m aenv infoReader implTycon sigTycon.TypeReprInfo && checkTypeAbbrev m aenv implTycon sigTycon && checkAttribs aenv implTycon.Attribs sigTycon.Attribs (fun attribs -> implTycon.entity_attribs <- attribs) && - checkModuleOrNamespaceContents implTycon.Range aenv (mkLocalEntityRef implTycon) sigTycon.ModuleOrNamespaceType + checkModuleOrNamespaceContents implTycon.Range aenv infoReader (mkLocalEntityRef implTycon) sigTycon.ModuleOrNamespaceType and checkValInfo aenv err (implVal : Val) (sigVal : Val) = let id = implVal.Id @@ -284,6 +290,15 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = warning(Error (FSComp.SR.ArgumentsInSigAndImplMismatch(sname.idText, iname.idText), iname.idRange)) | _ -> () + let sigHasInlineIfLambda = HasFSharpAttribute g g.attrib_InlineIfLambdaAttribute sigArgInfo.Attribs + let implHasInlineIfLambda = HasFSharpAttribute g g.attrib_InlineIfLambdaAttribute implArgInfo.Attribs + let m = + match implArgInfo.Name with + | Some iname-> iname.idRange + | None -> implVal.Range + if sigHasInlineIfLambda && not implHasInlineIfLambda then + errorR(Error (FSComp.SR.implMissingInlineIfLambda(), m)) + implArgInfo.Name <- sigArgInfo.Name implArgInfo.Attribs <- attribs))) && @@ -294,13 +309,13 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = implVal.SetValReprInfo (Some (ValReprInfo (sigTyparNames, implArgInfos, implRetInfo))) res - and checkVal implModRef (aenv: TypeEquivEnv) (implVal: Val) (sigVal: Val) = + and checkVal implModRef (aenv: TypeEquivEnv) (infoReader: InfoReader) (implVal: Val) (sigVal: Val) = // Propagate defn location information from implementation to signature . sigVal.SetOtherRange (implVal.Range, true) implVal.SetOtherRange (sigVal.Range, false) - let mk_err denv f = ValueNotContained(denv, implModRef, implVal, sigVal, f) + let mk_err denv f = ValueNotContained(denv, infoReader, implModRef, implVal, sigVal, f) let err denv f = errorR(mk_err denv f); false let m = implVal.Range if implVal.IsMutable <> sigVal.IsMutable then (err denv FSComp.SR.ValueNotContainedMutabilityAttributesDiffer) @@ -317,14 +332,14 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = if implTypars.Length <> sigTypars.Length then (err {denv with showTyparBinding=true} FSComp.SR.ValueNotContainedMutabilityParameterCountsDiffer) else let aenv = aenv.BindEquivTypars implTypars sigTypars checkTypars m aenv implTypars sigTypars && - if not (typeAEquiv g aenv atau ftau) then err denv (FSComp.SR.ValueNotContainedMutabilityTypesDiffer) + if not (typeAEquiv g aenv atau ftau) then err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer elif not (checkValInfo aenv (err denv) implVal sigVal) then false - elif not (implVal.IsExtensionMember = sigVal.IsExtensionMember) then err denv (FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer) + elif not (implVal.IsExtensionMember = sigVal.IsExtensionMember) then err denv FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer elif not (checkMemberDatasConform (err denv) (implVal.Attribs, implVal, implVal.MemberInfo) (sigVal.Attribs, sigVal, sigVal.MemberInfo)) then false else checkAttribs aenv implVal.Attribs sigVal.Attribs (fun attribs -> implVal.SetAttribs attribs) - and checkExnInfo err aenv implTypeRepr sigTypeRepr = + and checkExnInfo err aenv (infoReader: InfoReader) (enclosingTycon: Tycon) implTypeRepr sigTypeRepr = match implTypeRepr, sigTypeRepr with | TExnAsmRepr _, TExnFresh _ -> (errorR (err FSComp.SR.ExceptionDefsNotCompatibleHiddenBySignature); false) @@ -336,23 +351,23 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = if not (tcrefAEquiv g aenv ecr1 ecr2) then (errorR (err FSComp.SR.ExceptionDefsNotCompatibleSignaturesDiffer); false) else true - | TExnFresh r1, TExnFresh r2-> checkRecordFieldsForExn g denv err aenv r1 r2 + | TExnFresh r1, TExnFresh r2-> checkRecordFieldsForExn g denv err aenv infoReader enclosingTycon r1 r2 | TExnNone, TExnNone -> true | _ -> (errorR (err FSComp.SR.ExceptionDefsNotCompatibleExceptionDeclarationsDiffer); false) - and checkUnionCase aenv implUnionCase sigUnionCase = - let err f = errorR(ConstrNotContained(denv, implUnionCase, sigUnionCase, f));false + and checkUnionCase aenv infoReader (enclosingTycon: Tycon) implUnionCase sigUnionCase = + let err f = errorR(ConstrNotContained(denv, infoReader, enclosingTycon, implUnionCase, sigUnionCase, f));false sigUnionCase.OtherRangeOpt <- Some (implUnionCase.Range, true) implUnionCase.OtherRangeOpt <- Some (sigUnionCase.Range, false) if implUnionCase.Id.idText <> sigUnionCase.Id.idText then err FSComp.SR.ModuleContainsConstructorButNamesDiffer elif implUnionCase.RecdFieldsArray.Length <> sigUnionCase.RecdFieldsArray.Length then err FSComp.SR.ModuleContainsConstructorButDataFieldsDiffer - elif not (Array.forall2 (checkField aenv) implUnionCase.RecdFieldsArray sigUnionCase.RecdFieldsArray) then err FSComp.SR.ModuleContainsConstructorButTypesOfFieldsDiffer + elif not (Array.forall2 (checkField aenv infoReader enclosingTycon) implUnionCase.RecdFieldsArray sigUnionCase.RecdFieldsArray) then err FSComp.SR.ModuleContainsConstructorButTypesOfFieldsDiffer elif isLessAccessible implUnionCase.Accessibility sigUnionCase.Accessibility then err FSComp.SR.ModuleContainsConstructorButAccessibilityDiffers else checkAttribs aenv implUnionCase.Attribs sigUnionCase.Attribs (fun attribs -> implUnionCase.Attribs <- attribs) - and checkField aenv implField sigField = - let err f = errorR(FieldNotContained(denv, implField, sigField, f)); false + and checkField aenv infoReader (enclosingTycon: Tycon) implField sigField = + let err f = errorR(FieldNotContained(denv, infoReader, enclosingTycon, implField, sigField, f)); false sigField.rfield_other_range <- Some (implField.Range, true) implField.rfield_other_range <- Some (sigField.Range, false) if implField.rfield_id.idText <> sigField.rfield_id.idText then err FSComp.SR.FieldNotContainedNamesDiffer @@ -400,75 +415,67 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | _ -> false - // ------------------------------------------------------------------------------- - // WARNING!!!! - // checkRecordFields and checkRecordFieldsForExn are the EXACT SAME FUNCTION. - // The only difference is the signature for err - this is because err is a function - // that reports errors, and checkRecordFields is called with a different - // sig for err then checkRecordFieldsForExn. - // ------------------------------------------------------------------------------- - - and checkRecordFields m aenv (implTycon: Tycon) (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = + and checkRecordFields m aenv infoReader (implTycon: Tycon) (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = let implFields = implFields.TrueFieldsAsList let sigFields = sigFields.TrueFieldsAsList - let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) - let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) + let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) + let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) NameMap.suball2 (fun fieldName _ -> errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName, fieldName), m)); false) - (checkField aenv) m1 m2 && + (checkField aenv infoReader implTycon) m1 m2 && NameMap.suball2 (fun fieldName _ -> errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleFieldWasPresent(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName, fieldName), m)); false) - (fun x y -> checkField aenv y x) m2 m1 && + (fun x y -> checkField aenv infoReader implTycon y x) m2 m1 && // This check is required because constructors etc. are externally visible // and thus compiled representations do pick up dependencies on the field order - (if List.forall2 (checkField aenv) implFields sigFields + (if List.forall2 (checkField aenv infoReader implTycon) implFields sigFields then true else (errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false)) - and checkRecordFieldsForExn _g _denv err aenv (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = + and checkRecordFieldsForExn _g _denv err aenv (infoReader: InfoReader) (enclosingTycon: Tycon) (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = let implFields = implFields.TrueFieldsAsList let sigFields = sigFields.TrueFieldsAsList - let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) - let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) - NameMap.suball2 (fun s _ -> errorR(err (fun (x, y) -> FSComp.SR.ExceptionDefsNotCompatibleFieldInSigButNotImpl(s, x, y))); false) (checkField aenv) m1 m2 && - NameMap.suball2 (fun s _ -> errorR(err (fun (x, y) -> FSComp.SR.ExceptionDefsNotCompatibleFieldInImplButNotSig(s, x, y))); false) (fun x y -> checkField aenv y x) m2 m1 && + let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) + let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) + NameMap.suball2 (fun s _ -> errorR(err (fun (x, y) -> FSComp.SR.ExceptionDefsNotCompatibleFieldInSigButNotImpl(s, x, y))); false) (checkField aenv infoReader enclosingTycon) m1 m2 && + NameMap.suball2 (fun s _ -> errorR(err (fun (x, y) -> FSComp.SR.ExceptionDefsNotCompatibleFieldInImplButNotSig(s, x, y))); false) (fun x y -> checkField aenv infoReader enclosingTycon y x) m2 m1 && // This check is required because constructors etc. are externally visible // and thus compiled representations do pick up dependencies on the field order - (if List.forall2 (checkField aenv) implFields sigFields + (if List.forall2 (checkField aenv infoReader enclosingTycon) implFields sigFields then true - else (errorR(err (FSComp.SR.ExceptionDefsNotCompatibleFieldOrderDiffers)); false)) + else (errorR(err FSComp.SR.ExceptionDefsNotCompatibleFieldOrderDiffers); false)) - and checkVirtualSlots denv m (implTycon: Tycon) implAbstractSlots sigAbstractSlots = + and checkVirtualSlots denv infoReader m (implTycon: Tycon) implAbstractSlots sigAbstractSlots = let m1 = NameMap.ofKeyedList (fun (v: ValRef) -> v.DisplayName) implAbstractSlots let m2 = NameMap.ofKeyedList (fun (v: ValRef) -> v.DisplayName) sigAbstractSlots (m1, m2) ||> NameMap.suball2 (fun _s vref -> let kindText = implTycon.TypeOrMeasureKind.ToString() - let valText = NicePrint.stringValOrMember denv vref.Deref + let valText = NicePrint.stringValOrMember denv infoReader vref errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl(kindText, implTycon.DisplayName, valText), m)); false) (fun _x _y -> true) && (m2, m1) ||> NameMap.suball2 (fun _s vref -> let kindText = implTycon.TypeOrMeasureKind.ToString() - let valText = NicePrint.stringValOrMember denv vref.Deref + let valText = NicePrint.stringValOrMember denv infoReader vref errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig(kindText, implTycon.DisplayName, valText), m)); false) (fun _x _y -> true) - and checkClassFields isStruct m aenv (implTycon: Tycon) (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = + and checkClassFields isStruct m aenv infoReader (implTycon: Tycon) (implFields: TyconRecdFields) (sigFields: TyconRecdFields) = let implFields = implFields.TrueFieldsAsList let sigFields = sigFields.TrueFieldsAsList - let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) - let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.Name) + let m1 = implFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) + let m2 = sigFields |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) NameMap.suball2 (fun fieldName _ -> errorR(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName, fieldName), m)); false) - (checkField aenv) m1 m2 && + (checkField aenv infoReader implTycon) m1 m2 && (if isStruct then NameMap.suball2 (fun fieldName _ -> warning(Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName, fieldName), m)); true) - (fun x y -> checkField aenv y x) m2 m1 + (fun x y -> checkField aenv infoReader implTycon y x) m2 m1 else true) - and checkTypeRepr m aenv (implTycon: Tycon) sigTypeRepr = + and checkTypeRepr m aenv (infoReader: InfoReader) (implTycon: Tycon) sigTypeRepr = let reportNiceError k s1 s2 = let aset = NameSet.ofList s1 let fset = NameSet.ofList s2 @@ -480,41 +487,41 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | l -> (errorR (Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName, k, String.concat ";" l), m)); false) match implTycon.TypeReprInfo, sigTypeRepr with - | (TRecdRepr _ - | TUnionRepr _ + | (TFSharpRecdRepr _ + | TFSharpUnionRepr _ | TILObjectRepr _ #if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint _ - | TProvidedNamespaceExtensionPoint _ + | TProvidedTypeRepr _ + | TProvidedNamespaceRepr _ #endif ), TNoRepr -> true - | (TFSharpObjectRepr r), TNoRepr -> + | TFSharpObjectRepr r, TNoRepr -> match r.fsobjmodel_kind with - | TTyconStruct | TTyconEnum -> + | TFSharpStruct | TFSharpEnum -> (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplDefinesStruct(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) | _ -> true - | (TAsmRepr _), TNoRepr -> + | TAsmRepr _, TNoRepr -> (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) - | (TMeasureableRepr _), TNoRepr -> + | TMeasureableRepr _, TNoRepr -> (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleTypeIsHidden(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) - | (TUnionRepr r1), (TUnionRepr r2) -> + | TFSharpUnionRepr r1, TFSharpUnionRepr r2 -> let ucases1 = r1.UnionCasesAsList let ucases2 = r2.UnionCasesAsList if ucases1.Length <> ucases2.Length then let names (l: UnionCase list) = l |> List.map (fun c -> c.Id.idText) reportNiceError "union case" (names ucases1) (names ucases2) - else List.forall2 (checkUnionCase aenv) ucases1 ucases2 - | (TRecdRepr implFields), (TRecdRepr sigFields) -> - checkRecordFields m aenv implTycon implFields sigFields - | (TFSharpObjectRepr r1), (TFSharpObjectRepr r2) -> + else List.forall2 (checkUnionCase aenv infoReader implTycon) ucases1 ucases2 + | TFSharpRecdRepr implFields, TFSharpRecdRepr sigFields -> + checkRecordFields m aenv infoReader implTycon implFields sigFields + | TFSharpObjectRepr r1, TFSharpObjectRepr r2 -> if not (match r1.fsobjmodel_kind, r2.fsobjmodel_kind with - | TTyconClass, TTyconClass -> true - | TTyconInterface, TTyconInterface -> true - | TTyconStruct, TTyconStruct -> true - | TTyconEnum, TTyconEnum -> true - | TTyconDelegate (TSlotSig(_, typ1, ctps1, mtps1, ps1, rty1)), - TTyconDelegate (TSlotSig(_, typ2, ctps2, mtps2, ps2, rty2)) -> + | TFSharpClass, TFSharpClass -> true + | TFSharpInterface, TFSharpInterface -> true + | TFSharpStruct, TFSharpStruct -> true + | TFSharpEnum, TFSharpEnum -> true + | TFSharpDelegate (TSlotSig(_, typ1, ctps1, mtps1, ps1, rty1)), + TFSharpDelegate (TSlotSig(_, typ2, ctps2, mtps2, ps2, rty2)) -> (typeAEquiv g aenv typ1 typ2) && (ctps1.Length = ctps2.Length) && (let aenv = aenv.BindEquivTypars ctps1 ctps2 @@ -527,19 +534,19 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | _, _ -> false) then (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) else - let isStruct = (match r1.fsobjmodel_kind with TTyconStruct -> true | _ -> false) - checkClassFields isStruct m aenv implTycon r1.fsobjmodel_rfields r2.fsobjmodel_rfields && - checkVirtualSlots denv m implTycon r1.fsobjmodel_vslots r2.fsobjmodel_vslots - | (TAsmRepr tcr1), (TAsmRepr tcr2) -> + let isStruct = (match r1.fsobjmodel_kind with TFSharpStruct -> true | _ -> false) + checkClassFields isStruct m aenv infoReader implTycon r1.fsobjmodel_rfields r2.fsobjmodel_rfields && + checkVirtualSlots denv infoReader m implTycon r1.fsobjmodel_vslots r2.fsobjmodel_vslots + | TAsmRepr tcr1, TAsmRepr tcr2 -> if tcr1 <> tcr2 then (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleILDiffer(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) else true - | (TMeasureableRepr ty1), (TMeasureableRepr ty2) -> + | TMeasureableRepr ty1, TMeasureableRepr ty2 -> if typeAEquiv g aenv ty1 ty2 then true else (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) | TNoRepr, TNoRepr -> true #if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint info1, TProvidedTypeExtensionPoint info2 -> + | TProvidedTypeRepr info1, TProvidedTypeRepr info2 -> Tainted.EqTainted info1.ProvidedType.TypeProvider info2.ProvidedType.TypeProvider && ProvidedType.TaintedEquals(info1.ProvidedType, info2.ProvidedType) - | TProvidedNamespaceExtensionPoint _, TProvidedNamespaceExtensionPoint _ -> - System.Diagnostics.Debug.Assert(false, "unreachable: TProvidedNamespaceExtensionPoint only on namespaces, not types" ) + | TProvidedNamespaceRepr _, TProvidedNamespaceRepr _ -> + System.Diagnostics.Debug.Assert(false, "unreachable: TProvidedNamespaceRepr only on namespaces, not types" ) true #endif | TNoRepr, _ -> (errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) @@ -562,7 +569,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | Some _, None -> (errorR (Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) | None, Some _ -> (errorR (Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation(implTycon.TypeOrMeasureKind.ToString(), implTycon.DisplayName), m)); false) - and checkModuleOrNamespaceContents m aenv (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = + and checkModuleOrNamespaceContents m aenv (infoReader: InfoReader) (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = let implModType = implModRef.ModuleOrNamespaceType (if implModType.ModuleOrNamespaceKind <> signModType.ModuleOrNamespaceKind then errorR(Error(FSComp.SR.typrelModuleNamespaceAttributesDifferInSigAndImpl(), m))) @@ -570,19 +577,19 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = (implModType.TypesByMangledName, signModType.TypesByMangledName) ||> NameMap.suball2 (fun s _fx -> errorR(RequiredButNotSpecified(denv, implModRef, "type", (fun os -> Printf.bprintf os "%s" s), m)); false) - (checkTypeDef aenv) && + (checkTypeDef aenv infoReader) && (implModType.ModulesAndNamespacesByDemangledName, signModType.ModulesAndNamespacesByDemangledName ) ||> NameMap.suball2 (fun s fx -> errorR(RequiredButNotSpecified(denv, implModRef, (if fx.IsModule then "module" else "namespace"), (fun os -> Printf.bprintf os "%s" s), m)); false) - (fun x1 x2 -> checkModuleOrNamespace aenv (mkLocalModRef x1) x2) && + (fun x1 x2 -> checkModuleOrNamespace aenv infoReader (mkLocalModRef x1) x2) && let sigValHadNoMatchingImplementation (fx: Val) (_closeActualVal: Val option) = errorR(RequiredButNotSpecified(denv, implModRef, "value", (fun os -> (* In the case of missing members show the full required enclosing type and signature *) if fx.IsMember then - NicePrint.outputQualifiedValOrMember denv os fx + NicePrint.outputQualifiedValOrMember denv infoReader os (mkLocalValRef fx) else Printf.bprintf os "%s" fx.DisplayName), m)) @@ -601,7 +608,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | [], _ | _, [] -> failwith "unreachable" | [av], [fv] -> if valuesPartiallyMatch av fv then - checkVal implModRef aenv av fv + checkVal implModRef aenv infoReader av fv else sigValHadNoMatchingImplementation fv None false @@ -614,7 +621,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = | Some av -> Some(fv, av)) // Check the ones with matching linkage - let allPairsOk = matchingPairs |> List.map (fun (fv, av) -> checkVal implModRef aenv av fv) |> List.forall id + let allPairsOk = matchingPairs |> List.map (fun (fv, av) -> checkVal implModRef aenv infoReader av fv) |> List.forall id let someNotOk = matchingPairs.Length < fvs.Length // Report an error for those that don't. Try pairing up by enclosing-type/name if someNotOk then @@ -623,29 +630,29 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = match avs |> List.tryFind (fun av -> valuesPartiallyMatch av fv) with | None -> Choice1Of2 fv | Some av -> Choice2Of2(fv, av)) - for (fv, av) in partialMatchingPairs do - checkVal implModRef aenv av fv |> ignore + for fv, av in partialMatchingPairs do + checkVal implModRef aenv infoReader av fv |> ignore for fv in noMatches do sigValHadNoMatchingImplementation fv None allPairsOk && not someNotOk) - and checkModuleOrNamespace aenv implModRef sigModRef = + and checkModuleOrNamespace aenv (infoReader: InfoReader) implModRef sigModRef = // Propagate defn location information from implementation to signature . sigModRef.SetOtherRange (implModRef.Range, true) implModRef.Deref.SetOtherRange (sigModRef.Range, false) - checkModuleOrNamespaceContents implModRef.Range aenv implModRef sigModRef.ModuleOrNamespaceType && + checkModuleOrNamespaceContents implModRef.Range aenv infoReader implModRef sigModRef.ModuleOrNamespaceType && checkAttribs aenv implModRef.Attribs sigModRef.Attribs implModRef.Deref.SetAttribs - member __.CheckSignature aenv (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = - checkModuleOrNamespaceContents implModRef.Range aenv implModRef signModType + member _.CheckSignature aenv (infoReader: InfoReader) (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = + checkModuleOrNamespaceContents implModRef.Range aenv infoReader implModRef signModType - member __.CheckTypars m aenv (implTypars: Typars) (signTypars: Typars) = + member _.CheckTypars m aenv (implTypars: Typars) (signTypars: Typars) = checkTypars m aenv implTypars signTypars /// Check the names add up between a signature and its implementation. We check this first. -let rec CheckNamesOfModuleOrNamespaceContents denv (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = +let rec CheckNamesOfModuleOrNamespaceContents denv infoReader (implModRef: ModuleOrNamespaceRef) (signModType: ModuleOrNamespaceType) = let m = implModRef.Range let implModType = implModRef.ModuleOrNamespaceType NameMap.suball2 @@ -657,7 +664,7 @@ let rec CheckNamesOfModuleOrNamespaceContents denv (implModRef: ModuleOrNamespac (implModType.ModulesAndNamespacesByDemangledName, signModType.ModulesAndNamespacesByDemangledName ) ||> NameMap.suball2 (fun s fx -> errorR(RequiredButNotSpecified(denv, implModRef, (if fx.IsModule then "module" else "namespace"), (fun os -> Printf.bprintf os "%s" s), m)); false) - (fun x1 (x2: ModuleOrNamespace) -> CheckNamesOfModuleOrNamespace denv (mkLocalModRef x1) x2.ModuleOrNamespaceType) && + (fun x1 (x2: ModuleOrNamespace) -> CheckNamesOfModuleOrNamespace denv infoReader (mkLocalModRef x1) x2.ModuleOrNamespaceType) && (implModType.AllValsAndMembersByLogicalNameUncached, signModType.AllValsAndMembersByLogicalNameUncached) ||> NameMap.suball2 @@ -666,12 +673,12 @@ let rec CheckNamesOfModuleOrNamespaceContents denv (implModRef: ModuleOrNamespac errorR(RequiredButNotSpecified(denv, implModRef, "value", (fun os -> // In the case of missing members show the full required enclosing type and signature if Option.isSome fx.MemberInfo then - NicePrint.outputQualifiedValOrMember denv os fx + NicePrint.outputQualifiedValOrMember denv infoReader os (mkLocalValRef fx) else Printf.bprintf os "%s" fx.DisplayName), m)); false) (fun _ _ -> true) -and CheckNamesOfModuleOrNamespace denv (implModRef: ModuleOrNamespaceRef) signModType = - CheckNamesOfModuleOrNamespaceContents denv implModRef signModType +and CheckNamesOfModuleOrNamespace denv (infoReader: InfoReader) (implModRef: ModuleOrNamespaceRef) signModType = + CheckNamesOfModuleOrNamespaceContents denv infoReader implModRef signModType diff --git a/src/fsharp/SignatureConformance.fsi b/src/fsharp/SignatureConformance.fsi new file mode 100644 index 00000000000..673e6037d77 --- /dev/null +++ b/src/fsharp/SignatureConformance.fsi @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Primary relations on types and signatures, with the exception of +/// constraint solving and method overload resolution. +module internal FSharp.Compiler.SignatureConformance + +open System.Text + +open FSharp.Compiler +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.InfoReader + +exception RequiredButNotSpecified of DisplayEnv * ModuleOrNamespaceRef * string * (StringBuilder -> unit) * range + +exception ValueNotContained of DisplayEnv * InfoReader * ModuleOrNamespaceRef * Val * Val * (string * string * string -> string) + +exception ConstrNotContained of DisplayEnv * InfoReader * Tycon * UnionCase * UnionCase * (string * string -> string) + +exception ExnconstrNotContained of DisplayEnv * InfoReader * Tycon * Tycon * (string * string -> string) + +exception FieldNotContained of DisplayEnv * InfoReader * Tycon * RecdField * RecdField * (string * string -> string) + +exception InterfaceNotRevealed of DisplayEnv * TType * range + +type Checker = + + new: g:TcGlobals.TcGlobals * amap:Import.ImportMap * denv:DisplayEnv * remapInfo:SignatureRepackageInfo * checkingSig:bool -> Checker + + member CheckSignature: aenv:TypeEquivEnv -> infoReader:InfoReader -> implModRef:ModuleOrNamespaceRef -> signModType:ModuleOrNamespaceType -> bool + + member CheckTypars: m:range -> aenv:TypeEquivEnv -> implTypars:Typars -> signTypars:Typars -> bool + +/// Check the names add up between a signature and its implementation. We check this first. +val CheckNamesOfModuleOrNamespaceContents: denv:DisplayEnv -> infoReader:InfoReader -> implModRef:ModuleOrNamespaceRef -> signModType:ModuleOrNamespaceType -> bool + +val CheckNamesOfModuleOrNamespace: denv:DisplayEnv -> infoReader:InfoReader -> implModRef:ModuleOrNamespaceRef -> signModType:ModuleOrNamespaceType -> bool diff --git a/src/fsharp/SimulatedMSBuildReferenceResolver.fs b/src/fsharp/SimulatedMSBuildReferenceResolver.fs index bf5ffc092f0..f98e18288ca 100644 --- a/src/fsharp/SimulatedMSBuildReferenceResolver.fs +++ b/src/fsharp/SimulatedMSBuildReferenceResolver.fs @@ -1,52 +1,111 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -#if INTERACTIVE -#load "../utils/ResizeArray.fs" "../absil/illib.fs" "../fsharp/ReferenceResolver.fs" -#else -module internal FSharp.Compiler.SimulatedMSBuildReferenceResolver -#endif +module internal FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver open System open System.IO open System.Reflection +open Microsoft.Build.Utilities +open Internal.Utilities.Library +open FSharp.Compiler.IO + +#if !FX_NO_WIN_REGISTRY open Microsoft.Win32 -open FSharp.Compiler.ReferenceResolver -open FSharp.Compiler.AbstractIL.Internal.Library +#endif + +// ATTENTION!: the following code needs to be updated every time we are switching to the new MSBuild version because new .NET framework version was released +// 1. List of frameworks +// 2. DeriveTargetFrameworkDirectoriesFor45Plus +// 3. HighestInstalledRefAssembliesOrDotNETFramework +// 4. GetPathToDotNetFrameworkImlpementationAssemblies +[] +let private Net45 = "v4.5" + +[] +let private Net451 = "v4.5.1" + +[] +let private Net452 = "v4.5.2" // not available in Dev15 MSBuild version + +[] +let private Net46 = "v4.6" + +[] +let private Net461 = "v4.6.1" + +[] +let private Net462 = "v4.6.2" + +[] +let private Net47 = "v4.7" + +[] +let private Net471 = "v4.7.1" + +[] +let private Net472 = "v4.7.2" + +[] +let private Net48 = "v4.8" + +let SupportedDesktopFrameworkVersions = [ Net48; Net472; Net471; Net47; Net462; Net461; Net46; Net452; Net451; Net45 ] let private SimulatedMSBuildResolver = - let supportedFrameworks = [| - "v4.7.2" - "v4.7.1" - "v4.7" - "v4.6.2" - "v4.6.1" - "v4.6" - "v4.5.1" - "v4.5" - "v4.0" - |] - { new Resolver with + + /// Get the path to the .NET Framework implementation assemblies by using ToolLocationHelper.GetPathToDotNetFramework + /// This is only used to specify the "last resort" path for assembly resolution. + let GetPathToDotNetFrameworkImlpementationAssemblies v = + let v = + match v with + | Net45 -> Some TargetDotNetFrameworkVersion.Version45 + | Net451 -> Some TargetDotNetFrameworkVersion.Version451 + | Net452 -> Some TargetDotNetFrameworkVersion.Version452 + | Net46 -> Some TargetDotNetFrameworkVersion.Version46 + | Net461 -> Some TargetDotNetFrameworkVersion.Version461 + | Net462 -> Some TargetDotNetFrameworkVersion.Version462 + | Net47 -> Some TargetDotNetFrameworkVersion.Version47 + | Net471 -> Some TargetDotNetFrameworkVersion.Version471 + | Net472 -> Some TargetDotNetFrameworkVersion.Version472 + | Net48 -> Some TargetDotNetFrameworkVersion.Version48 + | _ -> assert false; None + match v with + | Some v -> + match ToolLocationHelper.GetPathToDotNetFramework v with + | null -> [] + | x -> [x] + | _ -> [] + + let GetPathToDotNetFrameworkReferenceAssemblies version = +#if NETSTANDARD + ignore version + let r : string list = [] + r +#else + match Microsoft.Build.Utilities.ToolLocationHelper.GetPathToStandardLibraries(".NETFramework",version,"") with + | null | "" -> [] + | x -> [x] +#endif + + { new ILegacyReferenceResolver with member x.HighestInstalledNetFrameworkVersion() = let root = x.DotNetFrameworkReferenceAssembliesRootDirectory - let fwOpt = supportedFrameworks |> Seq.tryFind(fun fw -> Directory.Exists(Path.Combine(root, fw) )) + let fwOpt = SupportedDesktopFrameworkVersions |> Seq.tryFind(fun fw -> FileSystem.DirectoryExistsShim(Path.Combine(root, fw) )) match fwOpt with | Some fw -> fw | None -> "v4.5" - member __.DotNetFrameworkReferenceAssembliesRootDirectory = -#if !FX_RESHAPED_MSBUILD - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then + member _.DotNetFrameworkReferenceAssembliesRootDirectory = + if Environment.OSVersion.Platform = PlatformID.Win32NT then let PF = match Environment.GetEnvironmentVariable("ProgramFiles(x86)") with | null -> Environment.GetEnvironmentVariable("ProgramFiles") // if PFx86 is null, then we are 32-bit and just get PF | s -> s PF + @"\Reference Assemblies\Microsoft\Framework\.NETFramework" else -#endif "" - member __.Resolve(resolutionEnvironment, references, targetFrameworkVersion, targetFrameworkDirectories, targetProcessorArchitecture, + member _.Resolve(resolutionEnvironment, references, targetFrameworkVersion, targetFrameworkDirectories, targetProcessorArchitecture, fsharpCoreDir, explicitIncludeDirs, implicitIncludeDir, logMessage, logWarningOrError) = #if !FX_NO_WIN_REGISTRY @@ -88,9 +147,11 @@ let private SimulatedMSBuildResolver = if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then yield! registrySearchPaths() #endif + yield! GetPathToDotNetFrameworkReferenceAssemblies targetFrameworkVersion + yield! GetPathToDotNetFrameworkImlpementationAssemblies targetFrameworkVersion ] - for (r, baggage) in references do + for r, baggage in references do //printfn "resolving %s" r let mutable found = false let success path = @@ -100,12 +161,11 @@ let private SimulatedMSBuildResolver = results.Add { itemSpec = path; prepareToolTip = snd; baggage=baggage } try - if not found && Path.IsPathRooted r then - if FileSystem.SafeExists r then + if not found && FileSystem.IsPathRootedShim r then + if FileSystem.FileExistsShim r then success r with e -> logWarningOrError false "SR001" (e.ToString()) -#if !FX_RESHAPED_MSBUILD // For this one we need to get the version search exactly right, without doing a load try if not found && r.StartsWithOrdinal("FSharp.Core, Version=") && Environment.OSVersion.Platform = PlatformID.Win32NT then @@ -117,10 +177,9 @@ let private SimulatedMSBuildResolver = | s -> s PF + @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\" + n.Version.ToString() let trialPath = Path.Combine(fscoreDir0, n.Name + ".dll") - if FileSystem.SafeExists trialPath then + if FileSystem.FileExistsShim trialPath then success trialPath with e -> logWarningOrError false "SR001" (e.ToString()) -#endif let isFileName = r.EndsWith("dll", StringComparison.OrdinalIgnoreCase) || @@ -132,11 +191,10 @@ let private SimulatedMSBuildResolver = try if not found then let trialPath = Path.Combine(searchPath, qual) - if FileSystem.SafeExists trialPath then + if FileSystem.FileExistsShim trialPath then success trialPath with e -> logWarningOrError false "SR001" (e.ToString()) -#if !FX_RESHAPED_MSBUILD try // Search the GAC on Windows if not found && not isFileName && Environment.OSVersion.Platform = PlatformID.Win32NT then @@ -146,13 +204,13 @@ let private SimulatedMSBuildResolver = match n.Version, n.GetPublicKeyToken() with | null, _ | _, null -> let options = - [ if Directory.Exists gac then - for gacDir in Directory.EnumerateDirectories gac do + [ if FileSystem.DirectoryExistsShim gac then + for gacDir in FileSystem.EnumerateDirectoriesShim gac do let assemblyDir = Path.Combine(gacDir, n.Name) - if Directory.Exists assemblyDir then - for tdir in Directory.EnumerateDirectories assemblyDir do + if FileSystem.DirectoryExistsShim assemblyDir then + for tdir in FileSystem.EnumerateDirectoriesShim assemblyDir do let trialPath = Path.Combine(tdir, qual) - if FileSystem.SafeExists trialPath then + if FileSystem.FileExistsShim trialPath then yield trialPath ] //printfn "sorting GAC paths: %A" options options @@ -161,26 +219,26 @@ let private SimulatedMSBuildResolver = |> function None -> () | Some p -> success p | v, tok -> - if Directory.Exists gac then + if FileSystem.DirectoryExistsShim gac then for gacDir in Directory.EnumerateDirectories gac do //printfn "searching GAC directory: %s" gacDir let assemblyDir = Path.Combine(gacDir, n.Name) - if Directory.Exists assemblyDir then + if FileSystem.DirectoryExistsShim assemblyDir then //printfn "searching GAC directory: %s" assemblyDir let tokText = String.concat "" [| for b in tok -> sprintf "%02x" b |] let verDir = Path.Combine(assemblyDir, "v4.0_"+v.ToString()+"__"+tokText) //printfn "searching GAC directory: %s" verDir - if Directory.Exists verDir then + if FileSystem.DirectoryExistsShim verDir then let trialPath = Path.Combine(verDir, qual) //printfn "searching GAC: %s" trialPath - if FileSystem.SafeExists trialPath then + if FileSystem.FileExistsShim trialPath then success trialPath with e -> logWarningOrError false "SR001" (e.ToString()) -#endif results.ToArray() } + |> LegacyReferenceResolver let internal getResolver () = SimulatedMSBuildResolver diff --git a/src/fsharp/SimulatedMSBuildReferenceResolver.fsi b/src/fsharp/SimulatedMSBuildReferenceResolver.fsi new file mode 100644 index 00000000000..0221673344c --- /dev/null +++ b/src/fsharp/SimulatedMSBuildReferenceResolver.fsi @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +[] +module internal FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver + +val getResolver: unit -> LegacyReferenceResolver + diff --git a/src/fsharp/StaticLinking.fs b/src/fsharp/StaticLinking.fs new file mode 100644 index 00000000000..c2a1e9c25ce --- /dev/null +++ b/src/fsharp/StaticLinking.fs @@ -0,0 +1,515 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Optional static linking of all DLLs that depend on the F# Library, plus other specified DLLs +module internal FSharp.Compiler.StaticLinking + +open System +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.OptimizeInputs +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +// Handles TypeForwarding for the generated IL model +type TypeForwarding (tcImports: TcImports) = + + // Make a dictionary of ccus passed to the compiler will be looked up by qualified assembly name + let ccuThunksQualifiedName = + tcImports.GetCcusInDeclOrder() + |> List.choose (fun ccuThunk -> ccuThunk.QualifiedName |> Option.map (fun v -> v, ccuThunk)) + |> dict + + // If we can't type forward using exact assembly match, we need to rely on the loader (Policy, Configuration or the coreclr load heuristics), so use try simple name + let ccuThunksSimpleName = + tcImports.GetCcusInDeclOrder() + |> List.choose (fun ccuThunk -> + if String.IsNullOrEmpty(ccuThunk.AssemblyName) then + None + else + Some (ccuThunk.AssemblyName, ccuThunk)) + |> dict + + let followTypeForwardForILTypeRef (tref:ILTypeRef) = + let typename = + let parts = tref.FullName.Split([|'.'|]) + match parts.Length with + | 0 -> None + | 1 -> Some (Array.empty, parts.[0]) + | n -> Some (parts.[0..n-2], parts.[n-1]) + + let scoref = tref.Scope + match scoref with + | ILScopeRef.Assembly scope -> + match ccuThunksQualifiedName.TryGetValue(scope.QualifiedName) with + | true, ccu -> + match typename with + | Some (parts, name) -> + let forwarded = ccu.TryForward(parts, name) + let result = + match forwarded with + | Some fwd -> fwd.CompilationPath.ILScopeRef + | None -> scoref + result + | None -> scoref + | false, _ -> + // Couldn't find an assembly with the version so try using a simple name + match ccuThunksSimpleName.TryGetValue(scope.Name) with + | true, ccu -> + match typename with + | Some (parts, name) -> + let forwarded = ccu.TryForward(parts, name) + let result = + match forwarded with + | Some fwd -> fwd.CompilationPath.ILScopeRef + | None -> scoref + result + | None -> scoref + | false, _ -> scoref + | _ -> scoref + + let typeForwardILTypeRef (tref: ILTypeRef) = + let scoref1 = tref.Scope + let scoref2 = followTypeForwardForILTypeRef tref + if scoref1 === scoref2 then tref + else ILTypeRef.Create (scoref2, tref.Enclosing, tref.Name) + + member _.TypeForwardILTypeRef tref = typeForwardILTypeRef tref + +let debugStaticLinking = condition "FSHARP_DEBUG_STATIC_LINKING" + +let StaticLinkILModules (tcConfig:TcConfig, ilGlobals, tcImports, ilxMainModule, dependentILModules: (CcuThunk option * ILModuleDef) list) = + if isNil dependentILModules then + ilxMainModule, id + else + let typeForwarding = TypeForwarding(tcImports) + + // Check no dependent assemblies use quotations + let dependentCcuUsingQuotations = dependentILModules |> List.tryPick (function Some ccu, _ when ccu.UsesFSharp20PlusQuotations -> Some ccu | _ -> None) + match dependentCcuUsingQuotations with + | Some ccu -> error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking(ccu.AssemblyName), rangeStartup)) + | None -> () + + // Check we're not static linking a .EXE + if dependentILModules |> List.exists (fun (_, x) -> not x.IsDLL) then + error(Error(FSComp.SR.fscStaticLinkingNoEXE(), rangeStartup)) + + // Check we're not static linking something that is not pure IL + if dependentILModules |> List.exists (fun (_, x) -> not x.IsILOnly) then + error(Error(FSComp.SR.fscStaticLinkingNoMixedDLL(), rangeStartup)) + + // The set of short names for the all dependent assemblies + let assems = + set [ for _, m in dependentILModules do + match m.Manifest with + | Some m -> yield m.Name + | _ -> () ] + + // A rewriter which rewrites scope references to things in dependent assemblies to be local references + let rewriteExternalRefsToLocalRefs x = + if assems.Contains (getNameOfScopeRef x) then ILScopeRef.Local else x + + let savedManifestAttrs = + [ for _, depILModule in dependentILModules do + match depILModule.Manifest with + | Some m -> + for ca in m.CustomAttrs.AsArray do + if ca.Method.MethodRef.DeclaringTypeRef.FullName = typeof.FullName then + yield ca + | _ -> () ] + + let savedResources = + let allResources = [ for ccu, m in dependentILModules do for r in m.Resources.AsList do yield (ccu, r) ] + // Don't save interface, optimization or resource definitions for provider-generated assemblies. + // These are "fake". + let isProvided (ccu: CcuThunk option) = +#if !NO_EXTENSIONTYPING + match ccu with + | Some c -> c.IsProviderGenerated + | None -> false +#else + ignore ccu + false +#endif + + // Save only the interface/optimization attributes of generated data + let intfDataResources, others = allResources |> List.partition (snd >> IsSignatureDataResource) + let intfDataResources = + [ for ccu, r in intfDataResources do + if tcConfig.GenerateSignatureData && not (isProvided ccu) then + yield r ] + + let optDataResources, others = others |> List.partition (snd >> IsOptimizationDataResource) + let optDataResources = + [ for ccu, r in optDataResources do + if tcConfig.GenerateOptimizationData && not (isProvided ccu) then + yield r ] + + let otherResources = others |> List.map snd + + let result = intfDataResources@optDataResources@otherResources + result + + let moduls = ilxMainModule :: (List.map snd dependentILModules) + + let savedNativeResources = + [ //yield! ilxMainModule.NativeResources + for m in moduls do + yield! m.NativeResources ] + + let topTypeDefs, normalTypeDefs = + moduls + |> List.map (fun m -> m.TypeDefs.AsList |> List.partition (fun td -> isTypeNameForGlobalFunctions td.Name)) + |> List.unzip + + let topTypeDef = + let topTypeDefs = List.concat topTypeDefs + mkILTypeDefForGlobalFunctions ilGlobals + (mkILMethods (topTypeDefs |> List.collect (fun td -> td.Methods.AsList)), + mkILFields (topTypeDefs |> List.collect (fun td -> td.Fields.AsList))) + + let ilxMainModule = + let main = + { ilxMainModule with + Manifest = (let m = ilxMainModule.ManifestOfAssembly in Some {m with CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (m.CustomAttrs.AsList @ savedManifestAttrs)) }) + CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs [ for m in moduls do yield! m.CustomAttrs.AsArray ]) + TypeDefs = mkILTypeDefs (topTypeDef :: List.concat normalTypeDefs) + Resources = mkILResources (savedResources @ ilxMainModule.Resources.AsList) + NativeResources = savedNativeResources } + Morphs.morphILTypeRefsInILModuleMemoized typeForwarding.TypeForwardILTypeRef main + + ilxMainModule, rewriteExternalRefsToLocalRefs + +[] +type Node = + { name: string + data: ILModuleDef + ccu: option + refs: ILReferences + mutable edges: list + mutable visited: bool } + +// Find all IL modules that are to be statically linked given the static linking roots. +let FindDependentILModulesForStaticLinking (ctok, tcConfig: TcConfig, tcImports: TcImports, ilGlobals: ILGlobals, ilxMainModule) = + if not tcConfig.standalone && tcConfig.extraStaticLinkRoots.IsEmpty then + [] + else + // Recursively find all referenced modules and add them to a module graph + let depModuleTable = HashMultiMap(0, HashIdentity.Structural) + let dummyEntry nm = + { refs = emptyILRefs + name=nm + ccu=None + data=ilxMainModule // any old module + edges = [] + visited = true } + let assumedIndependentSet = set [ "mscorlib"; "System"; "System.Core"; "System.Xml"; "Microsoft.Build.Framework"; "Microsoft.Build.Utilities"; "netstandard" ] + + begin + let mutable remaining = (computeILRefs ilGlobals ilxMainModule).AssemblyReferences + while not (isNil remaining) do + let ilAssemRef = List.head remaining + remaining <- List.tail remaining + if assumedIndependentSet.Contains ilAssemRef.Name || (ilAssemRef.PublicKey = Some ecmaPublicKey) then + depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name + else + if not (depModuleTable.ContainsKey ilAssemRef.Name) then + match tcImports.TryFindDllInfo(ctok, rangeStartup, ilAssemRef.Name, lookupOnly=false) with + | Some dllInfo -> + let ccu = + match tcImports.FindCcuFromAssemblyRef (ctok, rangeStartup, ilAssemRef) with + | ResolvedCcu ccu -> Some ccu + | UnresolvedCcu(_ccuName) -> None + + let fileName = dllInfo.FileName + let modul = + let pdbDirPathOption = + // We open the pdb file if one exists parallel to the binary we + // are reading, so that --standalone will preserve debug information. + if tcConfig.openDebugInformationForLaterStaticLinking then + let pdbDir = (try FileSystem.GetDirectoryNameShim fileName with _ -> ".") + let pdbFile = (try FileSystemUtils.chopExtension fileName with _ -> fileName)+".pdb" + if FileSystem.FileExistsShim pdbFile then + Some pdbDir + else + None + else + None + + let opts : ILReaderOptions = + { metadataOnly = MetadataOnlyFlag.No // turn this off here as we need the actual IL code + reduceMemoryUsage = tcConfig.reduceMemoryUsage + pdbDirPath = pdbDirPathOption + tryGetMetadataSnapshot = (fun _ -> None) } + + let reader = OpenILModuleReader dllInfo.FileName opts + reader.ILModuleDef + + let refs = + if ilAssemRef.Name = GetFSharpCoreLibraryName() then + emptyILRefs + elif not modul.IsILOnly then + warning(Error(FSComp.SR.fscIgnoringMixedWhenLinking ilAssemRef.Name, rangeStartup)) + emptyILRefs + else + { AssemblyReferences = dllInfo.ILAssemblyRefs + ModuleReferences = [] } + + depModuleTable.[ilAssemRef.Name] <- + { refs=refs + name=ilAssemRef.Name + ccu=ccu + data=modul + edges = [] + visited = false } + + // Push the new work items + remaining <- refs.AssemblyReferences @ remaining + + | None -> + warning(Error(FSComp.SR.fscAssumeStaticLinkContainsNoDependencies(ilAssemRef.Name), rangeStartup)) + depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name + done + end + + ReportTime tcConfig "Find dependencies" + + // Add edges from modules to the modules that depend on them + for KeyValue(_, n) in depModuleTable do + for aref in n.refs.AssemblyReferences do + let n2 = depModuleTable.[aref.Name] + n2.edges <- n :: n2.edges + + // Find everything that depends on FSharp.Core + let roots = + [ if tcConfig.standalone && depModuleTable.ContainsKey (GetFSharpCoreLibraryName()) then + yield depModuleTable.[GetFSharpCoreLibraryName()] + for n in tcConfig.extraStaticLinkRoots do + match depModuleTable.TryFind n with + | Some x -> yield x + | None -> error(Error(FSComp.SR.fscAssemblyNotFoundInDependencySet n, rangeStartup)) + ] + + let mutable remaining = roots + [ while not (isNil remaining) do + let n = List.head remaining + remaining <- List.tail remaining + if not n.visited then + n.visited <- true + remaining <- n.edges @ remaining + yield (n.ccu, n.data) ] + +// Add all provider-generated assemblies into the static linking set +let FindProviderGeneratedILModules (ctok, tcImports: TcImports, providerGeneratedAssemblies: (ImportedBinary * _) list) = + [ for importedBinary, provAssemStaticLinkInfo in providerGeneratedAssemblies do + let ilAssemRef = + match importedBinary.ILScopeRef with + | ILScopeRef.Assembly aref -> aref + | _ -> failwith "Invalid ILScopeRef, expected ILScopeRef.Assembly" + if debugStaticLinking then printfn "adding provider-generated assembly '%s' into static linking set" ilAssemRef.Name + match tcImports.TryFindDllInfo(ctok, rangeStartup, ilAssemRef.Name, lookupOnly=false) with + | Some dllInfo -> + let ccu = + match tcImports.FindCcuFromAssemblyRef (ctok, rangeStartup, ilAssemRef) with + | ResolvedCcu ccu -> Some ccu + | UnresolvedCcu(_ccuName) -> None + + let modul = dllInfo.RawMetadata.TryGetILModuleDef().Value + yield (ccu, dllInfo.ILScopeRef, modul), (ilAssemRef.Name, provAssemStaticLinkInfo) + | None -> () ] + +// Compute a static linker. This only captures tcImports (a large data structure) if +// static linking is enabled. Normally this is not the case, which lets us collect tcImports +// prior to this point. +let StaticLink (ctok, tcConfig: TcConfig, tcImports: TcImports, ilGlobals: ILGlobals) = + +#if !NO_EXTENSIONTYPING + let providerGeneratedAssemblies = + + [ // Add all EST-generated assemblies into the static linking set + for KeyValue(_, importedBinary: ImportedBinary) in tcImports.DllTable do + if importedBinary.IsProviderGenerated then + match importedBinary.ProviderGeneratedStaticLinkMap with + | None -> () + | Some provAssemStaticLinkInfo -> yield (importedBinary, provAssemStaticLinkInfo) ] +#endif + if not tcConfig.standalone && tcConfig.extraStaticLinkRoots.IsEmpty +#if !NO_EXTENSIONTYPING + && providerGeneratedAssemblies.IsEmpty +#endif + then + id + else + (fun ilxMainModule -> + ReportTime tcConfig "Find assembly references" + + let dependentILModules = FindDependentILModulesForStaticLinking (ctok, tcConfig, tcImports, ilGlobals, ilxMainModule) + + ReportTime tcConfig "Static link" + +#if !NO_EXTENSIONTYPING + Morphs.enableMorphCustomAttributeData() + let providerGeneratedILModules = FindProviderGeneratedILModules (ctok, tcImports, providerGeneratedAssemblies) + + // Transform the ILTypeRefs references in the IL of all provider-generated assemblies so that the references + // are now local. + let providerGeneratedILModules = + + providerGeneratedILModules |> List.map (fun ((ccu, ilOrigScopeRef, ilModule), (_, localProvAssemStaticLinkInfo)) -> + let ilAssemStaticLinkMap = + dict [ for _, (_, provAssemStaticLinkInfo) in providerGeneratedILModules do + for KeyValue(k, v) in provAssemStaticLinkInfo.ILTypeMap do + yield (k, v) + for KeyValue(k, v) in localProvAssemStaticLinkInfo.ILTypeMap do + yield (ILTypeRef.Create(ILScopeRef.Local, k.Enclosing, k.Name), v) ] + + let ilModule = + ilModule |> Morphs.morphILTypeRefsInILModuleMemoized (fun tref -> + if debugStaticLinking then printfn "deciding whether to rewrite type ref %A" tref.QualifiedName + let ok, v = ilAssemStaticLinkMap.TryGetValue tref + if ok then + if debugStaticLinking then printfn "rewriting type ref %A to %A" tref.QualifiedName v.QualifiedName + v + else + tref) + (ccu, ilOrigScopeRef, ilModule)) + + // Relocate provider generated type definitions into the expected shape for the [] declarations in an assembly + let providerGeneratedILModules, ilxMainModule = + // Build a dictionary of all remapped IL type defs + let ilOrigTyRefsForProviderGeneratedTypesToRelocate = + let rec walk acc (ProviderGeneratedType(ilOrigTyRef, _, xs) as node) = List.fold walk ((ilOrigTyRef, node) :: acc) xs + dict (Seq.fold walk [] tcImports.ProviderGeneratedTypeRoots) + + // Build a dictionary of all IL type defs, mapping ilOrigTyRef --> ilTypeDef + let allTypeDefsInProviderGeneratedAssemblies = + let rec loop ilOrigTyRef (ilTypeDef: ILTypeDef) = + seq { yield (ilOrigTyRef, ilTypeDef) + for ntdef in ilTypeDef.NestedTypes do + yield! loop (mkILTyRefInTyRef (ilOrigTyRef, ntdef.Name)) ntdef } + dict [ + for _ccu, ilOrigScopeRef, ilModule in providerGeneratedILModules do + for td in ilModule.TypeDefs do + yield! loop (mkILTyRef (ilOrigScopeRef, td.Name)) td ] + + + // Debugging output + if debugStaticLinking then + for ProviderGeneratedType(ilOrigTyRef, _, _) in tcImports.ProviderGeneratedTypeRoots do + printfn "Have [] root '%s'" ilOrigTyRef.QualifiedName + + // Build the ILTypeDefs for generated types, starting with the roots + let generatedILTypeDefs = + let rec buildRelocatedGeneratedType (ProviderGeneratedType(ilOrigTyRef, ilTgtTyRef, ch)) = + let isNested = not (isNil ilTgtTyRef.Enclosing) + match allTypeDefsInProviderGeneratedAssemblies.TryGetValue ilOrigTyRef with + | true, ilOrigTypeDef -> + if debugStaticLinking then printfn "Relocating %s to %s " ilOrigTyRef.QualifiedName ilTgtTyRef.QualifiedName + let ilOrigTypeDef = + if isNested then + ilOrigTypeDef + .WithAccess(match ilOrigTypeDef.Access with + | ILTypeDefAccess.Public -> ILTypeDefAccess.Nested ILMemberAccess.Public + | ILTypeDefAccess.Private -> ILTypeDefAccess.Nested ILMemberAccess.Private + | _ -> ilOrigTypeDef.Access) + else ilOrigTypeDef + ilOrigTypeDef.With(name = ilTgtTyRef.Name, + nestedTypes = mkILTypeDefs (List.map buildRelocatedGeneratedType ch)) + | _ -> + // If there is no matching IL type definition, then make a simple container class + if debugStaticLinking then + printfn "Generating simple class '%s' because we didn't find an original type '%s' in a provider generated assembly" + ilTgtTyRef.QualifiedName ilOrigTyRef.QualifiedName + + let access = (if isNested then ILTypeDefAccess.Nested ILMemberAccess.Public else ILTypeDefAccess.Public) + let tdefs = mkILTypeDefs (List.map buildRelocatedGeneratedType ch) + mkILSimpleClass ilGlobals (ilTgtTyRef.Name, access, emptyILMethods, emptyILFields, tdefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.OnAny) + + [ for ProviderGeneratedType(_, ilTgtTyRef, _) as node in tcImports.ProviderGeneratedTypeRoots do + yield (ilTgtTyRef, buildRelocatedGeneratedType node) ] + + // Implant all the generated type definitions into the ilxMainModule (generating a new ilxMainModule) + let ilxMainModule = + + /// Split the list into left, middle and right parts at the first element satisfying 'p'. If no element matches return + /// 'None' for the middle part. + let trySplitFind p xs = + let rec loop xs acc = + match xs with + | [] -> List.rev acc, None, [] + | h :: t -> if p h then List.rev acc, Some h, t else loop t (h :: acc) + loop xs [] + + /// Implant the (nested) type definition 'td' at path 'enc' in 'tdefs'. + let rec implantTypeDef isNested (tdefs: ILTypeDefs) (enc: string list) (td: ILTypeDef) = + match enc with + | [] -> addILTypeDef td tdefs + | h :: t -> + let tdefs = tdefs.AsList + let ltdefs, htd, rtdefs = + match tdefs |> trySplitFind (fun td -> td.Name = h) with + | ltdefs, None, rtdefs -> + let access = if isNested then ILTypeDefAccess.Nested ILMemberAccess.Public else ILTypeDefAccess.Public + let fresh = mkILSimpleClass ilGlobals (h, access, emptyILMethods, emptyILFields, emptyILTypeDefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.OnAny) + (ltdefs, fresh, rtdefs) + | ltdefs, Some htd, rtdefs -> + (ltdefs, htd, rtdefs) + let htd = htd.With(nestedTypes = implantTypeDef true htd.NestedTypes t td) + mkILTypeDefs (ltdefs @ [htd] @ rtdefs) + + let newTypeDefs = + (ilxMainModule.TypeDefs, generatedILTypeDefs) ||> List.fold (fun acc (ilTgtTyRef, td) -> + if debugStaticLinking then printfn "implanting '%s' at '%s'" td.Name ilTgtTyRef.QualifiedName + implantTypeDef false acc ilTgtTyRef.Enclosing td) + { ilxMainModule with TypeDefs = newTypeDefs } + + // Remove any ILTypeDefs from the provider generated modules if they have been relocated because of a [] declaration. + let providerGeneratedILModules = + providerGeneratedILModules |> List.map (fun (ccu, ilOrigScopeRef, ilModule) -> + let ilTypeDefsAfterRemovingRelocatedTypes = + let rec rw enc (tdefs: ILTypeDefs) = + mkILTypeDefs + [ for tdef in tdefs do + let ilOrigTyRef = mkILNestedTyRef (ilOrigScopeRef, enc, tdef.Name) + if not (ilOrigTyRefsForProviderGeneratedTypesToRelocate.ContainsKey ilOrigTyRef) then + if debugStaticLinking then printfn "Keep provided type %s in place because it wasn't relocated" ilOrigTyRef.QualifiedName + yield tdef.With(nestedTypes = rw (enc@[tdef.Name]) tdef.NestedTypes) ] + rw [] ilModule.TypeDefs + (ccu, { ilModule with TypeDefs = ilTypeDefsAfterRemovingRelocatedTypes })) + + providerGeneratedILModules, ilxMainModule + + Morphs.disableMorphCustomAttributeData() +#else + let providerGeneratedILModules = [] +#endif + + // Glue all this stuff into ilxMainModule + let ilxMainModule, rewriteExternalRefsToLocalRefs = + StaticLinkILModules (tcConfig, ilGlobals, tcImports, ilxMainModule, dependentILModules @ providerGeneratedILModules) + + // Rewrite type and assembly references + let ilxMainModule = + let isMscorlib = ilGlobals.primaryAssemblyName = PrimaryAssembly.Mscorlib.Name + let validateTargetPlatform (scopeRef : ILScopeRef) = + let name = getNameOfScopeRef scopeRef + if (not isMscorlib && name = PrimaryAssembly.Mscorlib.Name) then + error (Error(FSComp.SR.fscStaticLinkingNoProfileMismatches(), rangeCmdArgs)) + scopeRef + let rewriteAssemblyRefsToMatchLibraries = NormalizeAssemblyRefs (ctok, ilGlobals, tcImports) + Morphs.morphILTypeRefsInILModuleMemoized (Morphs.morphILScopeRefsInILTypeRef (validateTargetPlatform >> rewriteExternalRefsToLocalRefs >> rewriteAssemblyRefsToMatchLibraries)) ilxMainModule + + ilxMainModule) diff --git a/src/fsharp/StaticLinking.fsi b/src/fsharp/StaticLinking.fsi new file mode 100644 index 00000000000..d9f1c6b9a4e --- /dev/null +++ b/src/fsharp/StaticLinking.fsi @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Optional static linking of all DLLs that depend on the F# Library, plus other specified DLLs +module internal FSharp.Compiler.StaticLinking + +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports + +// Compute a static linker. This only captures tcImports (a large data structure) if +// static linking is enabled. Normally this is not the case, which lets us collect tcImports +// prior to this point. +val StaticLink: ctok: CompilationThreadToken * tcConfig: TcConfig * tcImports: TcImports * ilGlobals: ILGlobals -> (ILModuleDef -> ILModuleDef) diff --git a/src/fsharp/SyntaxTree.fs b/src/fsharp/SyntaxTree.fs new file mode 100644 index 00000000000..76bfd822d31 --- /dev/null +++ b/src/fsharp/SyntaxTree.fs @@ -0,0 +1,1967 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace rec FSharp.Compiler.Syntax + +open System.Diagnostics +open Internal.Utilities.Library +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml + +[] +type Ident (text: string, range: range) = + member _.idText = text + member _.idRange = range + override _.ToString() = text + +type LongIdent = Ident list + +type LongIdentWithDots = + | LongIdentWithDots of id: LongIdent * dotRanges: range list + + member this.Range = + match this with + | LongIdentWithDots([], _) -> failwith "rangeOfLidwd" + | LongIdentWithDots([id], []) -> id.idRange + | LongIdentWithDots([id], [m]) -> unionRanges id.idRange m + | LongIdentWithDots(h :: t, []) -> unionRanges h.idRange (List.last t).idRange + | LongIdentWithDots(h :: t, dotRanges) -> unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last dotRanges) + + member this.Lid = match this with LongIdentWithDots(lid, _) -> lid + + member this.ThereIsAnExtraDotAtTheEnd = match this with LongIdentWithDots(lid, dots) -> lid.Length = dots.Length + + member this.RangeWithoutAnyExtraDot = + match this with + | LongIdentWithDots([], _) -> failwith "rangeOfLidwd" + | LongIdentWithDots([id], _) -> id.idRange + | LongIdentWithDots(h :: t, dotRanges) -> + let nonExtraDots = if dotRanges.Length = t.Length then dotRanges else List.truncate t.Length dotRanges + unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last nonExtraDots) + +[] +type ParserDetail = + | Ok + + | ErrorRecovery + +[] +type TyparStaticReq = + | None + + | HeadType + +[] +type SynTypar = + | SynTypar of ident: Ident * staticReq: TyparStaticReq * isCompGen: bool + + member this.Range = + match this with + | SynTypar(id, _, _) -> + id.idRange + +[] +type SynStringKind = + | Regular + | Verbatim + | TripleQuote + +[] +type SynByteStringKind = + | Regular + | Verbatim + +[] +type SynConst = + + | Unit + + | Bool of bool + + | SByte of sbyte + + | Byte of byte + + | Int16 of int16 + + | UInt16 of uint16 + + | Int32 of int32 + + | UInt32 of uint32 + + | Int64 of int64 + + | UInt64 of uint64 + + | IntPtr of int64 + + | UIntPtr of uint64 + + | Single of single + + | Double of double + + | Char of char + + | Decimal of System.Decimal + + | UserNum of value: string * suffix: string + + | String of text: string * synStringKind :SynStringKind * range: range + + | Bytes of bytes: byte[] * synByteStringKind: SynByteStringKind * range: range + + | UInt16s of uint16[] + + | Measure of constant: SynConst * constantRange: Range * SynMeasure + + | SourceIdentifier of constant: string * value: string * range: Range + + member c.Range dflt = + match c with + | SynConst.String (_, _, m0) + | SynConst.Bytes (_, _, m0) + | SynConst.SourceIdentifier(_, _, m0) -> m0 + | _ -> dflt + +[] +type SynMeasure = + + | Named of longId: LongIdent * range: range + + | Product of measure1: SynMeasure * measure2: SynMeasure * range: range + + | Seq of measures: SynMeasure list * range: range + + | Divide of measure1: SynMeasure * measure2: SynMeasure * range: range + + | Power of measure: SynMeasure * power: SynRationalConst * range: range + + | One + + | Anon of range: range + + | Var of typar: SynTypar * range: range + +[] +type SynRationalConst = + + | Integer of value: int32 + + | Rational of numerator: int32 * denominator: int32 * range: range + + | Negate of SynRationalConst + +[] +type SynAccess = + | Public + + | Internal + + | Private + + override this.ToString () = + match this with + | Public -> "Public" + | Internal -> "Internal" + | Private -> "Private" + +[] +type DebugPointAtTarget = + | Yes + | No + +[] +type DebugPointAtSwitch = + | Yes of range + | No + +[] +type DebugPointAtSequential = + | SuppressNeither + | SuppressStmt + | SuppressBoth + | SuppressExpr + +[] +type DebugPointAtTry = + | Yes of range: range + | Body + | No + +[] +type DebugPointAtWith = + | Yes of range: range + | No + +[] +type DebugPointAtFinally = + | Yes of range: range + | Body + | No + +[] +type DebugPointAtFor = + | Yes of range: range + | No + +[] +type DebugPointAtWhile = + | Yes of range: range + | No + +[] +type DebugPointAtBinding = + | Yes of range: range + + | NoneAtDo + + | NoneAtLet + + | NoneAtSticky + + | NoneAtInvisible + + member x.Combine(y: DebugPointAtBinding) = + match x, y with + | DebugPointAtBinding.Yes _ as g, _ -> g + | _, (DebugPointAtBinding.Yes _ as g) -> g + | _ -> x + +type SeqExprOnly = + | SeqExprOnly of bool + +type BlockSeparator = range * pos option + +type RecordFieldName = LongIdentWithDots * bool + +type ExprAtomicFlag = + | Atomic = 0 + | NonAtomic = 1 + +[] +type SynBindingKind = + + | StandaloneExpression + + | Normal + + | Do + +[] +type SynTyparDecl = + | SynTyparDecl of attributes: SynAttributes * SynTypar + +[] +type SynTypeConstraint = + + | WhereTyparIsValueType of + typar: SynTypar * + range: range + + | WhereTyparIsReferenceType of + typar: SynTypar * + range: range + + | WhereTyparIsUnmanaged of + typar: SynTypar * + range: range + + | WhereTyparSupportsNull of + typar: SynTypar * + range: range + + | WhereTyparIsComparable of + typar: SynTypar * + range: range + + | WhereTyparIsEquatable of + typar: SynTypar * + range: range + + | WhereTyparDefaultsToType of + typar: SynTypar * + typeName: SynType * + range: range + + | WhereTyparSubtypeOfType of + typar: SynTypar * + typeName: SynType * + range: range + + | WhereTyparSupportsMember of + typars: SynType list * + memberSig: SynMemberSig * + range: range + + | WhereTyparIsEnum of + typar: SynTypar * + typeArgs: SynType list * + range: range + + | WhereTyparIsDelegate of + typar: SynTypar * + typeArgs: SynType list * + range: range + + member x.Range = + match x with + | WhereTyparIsValueType(range=range) + | WhereTyparIsReferenceType(range=range) + | WhereTyparIsUnmanaged(range=range) + | WhereTyparSupportsNull(range=range) + | WhereTyparIsComparable(range=range) + | WhereTyparIsEquatable(range=range) + | WhereTyparDefaultsToType(range=range) + | WhereTyparSubtypeOfType(range=range) + | WhereTyparSupportsMember(range=range) + | WhereTyparIsEnum(range=range) + | WhereTyparIsDelegate(range=range) -> range + +[] +type SynTyparDecls = + | PostfixList of decls: SynTyparDecl list * constraints: SynTypeConstraint list * range: range + | PrefixList of decls: SynTyparDecl list * range: range + | SinglePrefix of decl: SynTyparDecl * range: range + + member x.TyparDecls = + match x with + | PostfixList (decls=decls) + | PrefixList (decls=decls) -> decls + | SinglePrefix (decl, _) -> [decl] + + member x.Constraints = + match x with + | PostfixList (constraints=constraints) -> constraints + | _ -> [] + + member x.Range = + match x with + | PostfixList (range=range) + | PrefixList (range=range) -> range + | SinglePrefix (range=range) -> range + +[] +type SynType = + + | LongIdent of + longDotId: LongIdentWithDots + + | App of + typeName: SynType * + lessRange: range option * + typeArgs: SynType list * + commaRanges: range list * // interstitial commas + greaterRange: range option * + isPostfix: bool * + range: range + + | LongIdentApp of + typeName: SynType * + longDotId: LongIdentWithDots * + lessRange: range option * + typeArgs: SynType list * + commaRanges: range list * // interstitial commas + greaterRange: range option * + range: range + + | Tuple of + isStruct: bool * + elementTypes:(bool*SynType) list * + range: range + + | AnonRecd of + isStruct: bool * + fields:(Ident * SynType) list * + range: range + + | Array of + rank: int * + elementType: SynType * + range: range + + | Fun of + argType: SynType * + returnType: SynType * + range: range + + | Var of + typar: SynTypar * + range: range + + | Anon of range: range + + | WithGlobalConstraints of + typeName: SynType * + constraints: SynTypeConstraint list * + range: range + + | HashConstraint of + innerType: SynType * + range: range + + | MeasureDivide of + dividend: SynType * + divisor: SynType * + range: range + + | MeasurePower of + baseMeasure: SynType * + exponent: SynRationalConst * + range: range + + | StaticConstant of + constant: SynConst * + range: range + + | StaticConstantExpr of + expr: SynExpr * + range: range + + | StaticConstantNamed of + ident: SynType * + value: SynType * + range: range + + | Paren of + innerType: SynType * + range: range + + member x.Range = + match x with + | SynType.App (range=m) + | SynType.LongIdentApp (range=m) + | SynType.Tuple (range=m) + | SynType.Array (range=m) + | SynType.AnonRecd (range=m) + | SynType.Fun (range=m) + | SynType.Var (range=m) + | SynType.Anon (range=m) + | SynType.WithGlobalConstraints (range=m) + | SynType.StaticConstant (range=m) + | SynType.StaticConstantExpr (range=m) + | SynType.StaticConstantNamed (range=m) + | SynType.HashConstraint (range=m) + | SynType.MeasureDivide (range=m) + | SynType.MeasurePower (range=m) + | SynType.Paren (range=m) -> m + | SynType.LongIdent lidwd -> lidwd.Range + +[] +type SynExpr = + + | Paren of + expr: SynExpr * + leftParenRange: range * + rightParenRange: range option * + range: range + + | Quote of + operator: SynExpr * + isRaw: bool * + quotedExpr: SynExpr * + isFromQueryExpression: bool * + range: range + + | Const of + constant: SynConst * + range: range + + | Typed of + expr: SynExpr * + targetType: SynType * + range: range + + | Tuple of + isStruct: bool * + exprs: SynExpr list * + commaRanges: range list * // interstitial commas + range: range + + | AnonRecd of + isStruct: bool * + copyInfo:(SynExpr * BlockSeparator) option * + recordFields:(Ident * SynExpr) list * + range: range + + | ArrayOrList of + isArray: bool * + exprs: SynExpr list * + range: range + + | Record of + baseInfo:(SynType * SynExpr * range * BlockSeparator option * range) option * + copyInfo:(SynExpr * BlockSeparator) option * + recordFields:(RecordFieldName * SynExpr option * BlockSeparator option) list * + range: range + + | New of + isProtected: bool * + targetType: SynType * + expr: SynExpr * + range: range + + | ObjExpr of + objType: SynType * + argOptions:(SynExpr * Ident option) option * + bindings: SynBinding list * + extraImpls: SynInterfaceImpl list * + newExprRange: range * + range: range + + | While of + whileDebugPoint: DebugPointAtWhile * + whileExpr: SynExpr * + doExpr: SynExpr * + range: range + + | For of + forDebugPoint: DebugPointAtFor * + ident: Ident * + identBody: SynExpr * + direction: bool * + toBody: SynExpr * + doBody: SynExpr * + range: range + + | ForEach of + forDebugPoint: DebugPointAtFor * + seqExprOnly: SeqExprOnly * + isFromSource: bool * + pat: SynPat * + enumExpr: SynExpr * + bodyExpr: SynExpr * + range: range + + | ArrayOrListComputed of + isArray: bool * + expr: SynExpr * + range: range + + | IndexRange of + expr1: SynExpr option * + opm: range * + expr2: SynExpr option* + range1: range * + range2: range * + range: range + + | IndexFromEnd of + expr: SynExpr * + range: range + + | ComputationExpr of + hasSeqBuilder: bool * + expr: SynExpr * + range: range + + | Lambda of + fromMethod: bool * + inLambdaSeq: bool * + args: SynSimplePats * + arrow: Range option * + body: SynExpr * + parsedData: (SynPat list * SynExpr) option * + range: range + + | MatchLambda of + isExnMatch: bool * + keywordRange: range * + matchClauses: SynMatchClause list * + matchDebugPoint: DebugPointAtBinding * + range: range + + | Match of + matchDebugPoint: DebugPointAtBinding * + expr: SynExpr * + clauses: SynMatchClause list * + range: range + + | Do of + expr: SynExpr * + range: range + + | Assert of + expr: SynExpr * + range: range + + | App of + flag: ExprAtomicFlag * + isInfix: bool * + funcExpr: SynExpr * + argExpr: SynExpr * + range: range + + | TypeApp of + expr: SynExpr * + lessRange: range * + typeArgs: SynType list * + commaRanges: range list * + greaterRange: range option * + typeArgsRange: range * + range: range + + | LetOrUse of + isRecursive: bool * + isUse: bool * + bindings: SynBinding list * + body: SynExpr * + range: range + + | TryWith of + tryExpr: SynExpr * + tryRange: range * + withCases: SynMatchClause list * + withRange: range * + range: range * + tryDebugPoint: DebugPointAtTry * + withDebugPoint: DebugPointAtWith + + | TryFinally of + tryExpr: SynExpr * + finallyExpr: SynExpr * + range: range * + tryDebugPoint: DebugPointAtTry * + finallyDebugPoint: DebugPointAtFinally + + | Lazy of + expr: SynExpr * + range: range + + | Sequential of + debugPoint: DebugPointAtSequential * + isTrueSeq: bool * + expr1: SynExpr * + expr2: SynExpr * + range: range + + | IfThenElse of + ifKeyword: range * + isElif: bool * + ifExpr: SynExpr * + thenKeyword: range * + thenExpr: SynExpr * + elseKeyword: range option * + elseExpr: SynExpr option * + spIfToThen: DebugPointAtBinding * + isFromErrorRecovery: bool * + ifToThenRange: range * + range: range + + | Ident of + ident: Ident + + | LongIdent of + isOptional: bool * + longDotId: LongIdentWithDots * + altNameRefCell: SynSimplePatAlternativeIdInfo ref option * + range: range + + | LongIdentSet of + longDotId: LongIdentWithDots * + expr: SynExpr * + range: range + + | DotGet of + expr: SynExpr * + rangeOfDot: range * + longDotId: LongIdentWithDots * + range: range + + | DotSet of + targetExpr: SynExpr * + longDotId: LongIdentWithDots * + rhsExpr: SynExpr * + range: range + + | Set of + targetExpr: SynExpr * + rhsExpr: SynExpr * + range: range + + | DotIndexedGet of + objectExpr: SynExpr * + indexArgs: SynExpr * + dotRange: range * + range: range + + | DotIndexedSet of + objectExpr: SynExpr * + indexArgs: SynExpr * + valueExpr: SynExpr * + leftOfSetRange: range * + dotRange: range * + range: range + + | NamedIndexedPropertySet of + longDotId: LongIdentWithDots * + expr1: SynExpr * + expr2: SynExpr * + range: range + + | DotNamedIndexedPropertySet of + targetExpr: SynExpr * + longDotId: LongIdentWithDots * + argExpr: SynExpr * + rhsExpr: SynExpr * + range: range + + | TypeTest of + expr: SynExpr * + targetType: SynType * + range: range + + | Upcast of + expr: SynExpr * + targetType: SynType * + range: range + + | Downcast of + expr: SynExpr * + targetType: SynType * + range: range + + | InferredUpcast of + expr: SynExpr * + range: range + + | InferredDowncast of + expr: SynExpr * + range: range + + | Null of + range: range + + | AddressOf of + isByref: bool * + expr: SynExpr * + opRange: range * + range: range + + | TraitCall of + supportTys: SynTypar list * + traitSig: SynMemberSig * + argExpr: SynExpr * + range: range + + | JoinIn of + lhsExpr: SynExpr * + lhsRange: range * + rhsExpr: SynExpr * + range: range + + | ImplicitZero of + range: range + + | SequentialOrImplicitYield of + debugPoint:DebugPointAtSequential * + expr1:SynExpr * + expr2:SynExpr * + ifNotStmt:SynExpr * + range:range + + | YieldOrReturn of + flags: (bool * bool) * + expr: SynExpr * + range: range + + | YieldOrReturnFrom of + flags: (bool * bool) * + expr: SynExpr * + range: range + + | LetOrUseBang of + bindDebugPoint: DebugPointAtBinding * + isUse: bool * + isFromSource: bool * + pat: SynPat * + rhs: SynExpr * + andBangs:(DebugPointAtBinding * bool * bool * SynPat * SynExpr * range) list * + body:SynExpr * + range: range + + | MatchBang of + matchDebugPoint: DebugPointAtBinding * + expr: SynExpr * + clauses: SynMatchClause list * + range: range + + | DoBang of + expr: SynExpr * + range: range + + | LibraryOnlyILAssembly of + ilCode: obj * // this type is ILInstr[] but is hidden to avoid the representation of AbstractIL being public + typeArgs: SynType list * + args: SynExpr list * + retTy: SynType list * + range: range + + | LibraryOnlyStaticOptimization of + constraints: SynStaticOptimizationConstraint list * + expr: SynExpr * + optimizedExpr: SynExpr * + range: range + + | LibraryOnlyUnionCaseFieldGet of + expr: SynExpr * + longId: LongIdent * + fieldNum: int * + range: range + + | LibraryOnlyUnionCaseFieldSet of + expr: SynExpr * + longId: LongIdent * + fieldNum: int * + rhsExpr: SynExpr * + range: range + + | ArbitraryAfterError of + debugStr: string * + range: range + + | FromParseError of + expr: SynExpr * + range: range + + | DiscardAfterMissingQualificationAfterDot of + expr: SynExpr * + range: range + + | Fixed of + expr: SynExpr * + range: range + + | InterpolatedString of + contents: SynInterpolatedStringPart list * + synStringKind :SynStringKind * + range: range + + member e.Range = + match e with + | SynExpr.Paren (_, leftParenRange, rightParenRange, r) -> + match rightParenRange with + | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex -> leftParenRange + | _ -> r + | SynExpr.Quote (range=m) + | SynExpr.Const (range=m) + | SynExpr.Typed (range=m) + | SynExpr.Tuple (range=m) + | SynExpr.AnonRecd (range=m) + | SynExpr.ArrayOrList (range=m) + | SynExpr.Record (range=m) + | SynExpr.New (range=m) + | SynExpr.ObjExpr (range=m) + | SynExpr.While (range=m) + | SynExpr.For (range=m) + | SynExpr.ForEach (range=m) + | SynExpr.ComputationExpr (range=m) + | SynExpr.ArrayOrListComputed (range=m) + | SynExpr.Lambda (range=m) + | SynExpr.Match (range=m) + | SynExpr.MatchLambda (range=m) + | SynExpr.Do (range=m) + | SynExpr.Assert (range=m) + | SynExpr.App (range=m) + | SynExpr.TypeApp (range=m) + | SynExpr.LetOrUse (range=m) + | SynExpr.TryWith (range=m) + | SynExpr.TryFinally (range=m) + | SynExpr.Sequential (range=m) + | SynExpr.SequentialOrImplicitYield (range=m) + | SynExpr.ArbitraryAfterError (range=m) + | SynExpr.FromParseError (range=m) + | SynExpr.DiscardAfterMissingQualificationAfterDot (range=m) + | SynExpr.IfThenElse (range=m) + | SynExpr.LongIdent (range=m) + | SynExpr.LongIdentSet (range=m) + | SynExpr.NamedIndexedPropertySet (range=m) + | SynExpr.DotIndexedGet (range=m) + | SynExpr.DotIndexedSet (range=m) + | SynExpr.DotGet (range=m) + | SynExpr.DotSet (range=m) + | SynExpr.Set (range=m) + | SynExpr.DotNamedIndexedPropertySet (range=m) + | SynExpr.LibraryOnlyUnionCaseFieldGet (range=m) + | SynExpr.LibraryOnlyUnionCaseFieldSet (range=m) + | SynExpr.LibraryOnlyILAssembly (range=m) + | SynExpr.LibraryOnlyStaticOptimization (range=m) + | SynExpr.IndexRange (range=m) + | SynExpr.IndexFromEnd (range=m) + | SynExpr.TypeTest (range=m) + | SynExpr.Upcast (range=m) + | SynExpr.AddressOf (range=m) + | SynExpr.Downcast (range=m) + | SynExpr.JoinIn (range=m) + | SynExpr.InferredUpcast (range=m) + | SynExpr.InferredDowncast (range=m) + | SynExpr.Null (range=m) + | SynExpr.Lazy (range=m) + | SynExpr.TraitCall (range=m) + | SynExpr.ImplicitZero (range=m) + | SynExpr.YieldOrReturn (range=m) + | SynExpr.YieldOrReturnFrom (range=m) + | SynExpr.LetOrUseBang (range=m) + | SynExpr.MatchBang (range=m) + | SynExpr.DoBang (range=m) + | SynExpr.Fixed (range=m) + | SynExpr.InterpolatedString (range=m) -> m + | SynExpr.Ident id -> id.idRange + + member e.RangeWithoutAnyExtraDot = + match e with + | SynExpr.DotGet (expr, _, lidwd, m) -> + if lidwd.ThereIsAnExtraDotAtTheEnd then + unionRanges expr.Range lidwd.RangeWithoutAnyExtraDot + else + m + | SynExpr.LongIdent (_, lidwd, _, _) -> lidwd.RangeWithoutAnyExtraDot + | SynExpr.DiscardAfterMissingQualificationAfterDot (expr, _) -> expr.Range + | _ -> e.Range + + member e.RangeOfFirstPortion = + match e with + // these are better than just .Range, and also commonly applicable inside queries + | SynExpr.Paren (_, m, _, _) -> m + | SynExpr.Sequential (_, _, e1, _, _) + | SynExpr.SequentialOrImplicitYield (_, e1, _, _, _) + | SynExpr.App (_, _, e1, _, _) -> + e1.RangeOfFirstPortion + | SynExpr.ForEach (_, _, _, pat, _, _, r) -> + let start = r.Start + let e = (pat.Range: range).Start + mkRange r.FileName start e + | _ -> e.Range + + member this.IsArbExprAndThusAlreadyReportedError = + match this with + | SynExpr.ArbitraryAfterError _ -> true + | _ -> false + +[] +type SynInterpolatedStringPart = + | String of value: string * range: range + | FillExpr of fillExpr: SynExpr * qualifiers: Ident option + +[] +type SynSimplePat = + | Id of + ident: Ident * + altNameRefCell: SynSimplePatAlternativeIdInfo ref option * + isCompilerGenerated: bool * + isThisVal: bool * + isOptional: bool * + range: range + + | Typed of + pat: SynSimplePat * + targetType: SynType * + range: range + + | Attrib of + pat: SynSimplePat * + attributes: SynAttributes * + range: range + + member x.Range = + match x with + | SynSimplePat.Id(range=range) + | SynSimplePat.Typed(range=range) + | SynSimplePat.Attrib(range=range) -> range + +[] +type SynSimplePatAlternativeIdInfo = + + | Undecided of Ident + + | Decided of Ident + +[] +type SynStaticOptimizationConstraint = + + | WhenTyparTyconEqualsTycon of + typar: SynTypar * + rhsType: SynType * + range: range + + | WhenTyparIsStruct of + typar: SynTypar * + range: range + +[] +type SynSimplePats = + | SimplePats of + pats: SynSimplePat list * + range: range + + | Typed of + pats: SynSimplePats * + targetType: SynType * + range: range + + member x.Range = + match x with + | SynSimplePats.SimplePats(range=range) + | SynSimplePats.Typed(range=range) -> range + +[] +type SynArgPats = + | Pats of + pats: SynPat list + + | NamePatPairs of + pats: (Ident * SynPat) list * + range: range + + member x.Patterns = + match x with + | Pats pats -> pats + | NamePatPairs (pats, _) -> pats |> List.map snd + +[] +type SynPat = + + | Const of + constant: SynConst * + range: range + + | Wild of + range: range + + | Named of + ident: Ident * + isThisVal: bool * + accessibility: SynAccess option * + range: range + + | Typed of + pat: SynPat * + targetType: SynType * + range: range + + | Attrib of + pat: SynPat * + attributes: SynAttributes * + range: range + + | Or of + lhsPat: SynPat * + rhsPat: SynPat * + range: range + + | Ands of + pats: SynPat list * + range: range + + | As of + lhsPat: SynPat * + rhsPat: SynPat * + range: range + + | LongIdent of + longDotId: LongIdentWithDots * + extraId: Ident option * // holds additional ident for tooling + typarDecls: SynValTyparDecls option * // usually None: temporary used to parse "f<'a> x = x" + argPats: SynArgPats * + accessibility: SynAccess option * + range: range + + | Tuple of + isStruct: bool * + elementPats: SynPat list * + range: range + + | Paren of + pat: SynPat * + range: range + + | ArrayOrList of + isArray: bool * + elementPats: SynPat list * + range: range + + | Record of + fieldPats: ((LongIdent * Ident) * SynPat) list * + range: range + + | Null of + range: range + + | OptionalVal of + ident: Ident * + range: range + + | IsInst of + pat: SynType * + range: range + + | QuoteExpr of + expr: SynExpr * + range: range + + | DeprecatedCharRange of + startChar: char * + endChar: char * + range: range + + | InstanceMember of + thisId: Ident * + memberId: Ident * + toolingId: Ident option * // holds additional ident for tooling + accessibility: SynAccess option * + range: range + + | FromParseError of + pat: SynPat * + range: range + + member p.Range = + match p with + | SynPat.Const (range=m) + | SynPat.Wild (range=m) + | SynPat.Named (range=m) + | SynPat.Or (range=m) + | SynPat.Ands (range=m) + | SynPat.As (range=m) + | SynPat.LongIdent (range=m) + | SynPat.ArrayOrList (range=m) + | SynPat.Tuple (range=m) + | SynPat.Typed (range=m) + | SynPat.Attrib (range=m) + | SynPat.Record (range=m) + | SynPat.DeprecatedCharRange (range=m) + | SynPat.Null (range=m) + | SynPat.IsInst (range=m) + | SynPat.QuoteExpr (range=m) + | SynPat.InstanceMember (range=m) + | SynPat.OptionalVal (range=m) + | SynPat.Paren (range=m) + | SynPat.FromParseError (range=m) -> m + +[] +type SynInterfaceImpl = + | SynInterfaceImpl of + interfaceTy: SynType * + bindings: SynBinding list * + range: range + +[] +type SynMatchClause = + | SynMatchClause of + pat: SynPat * + whenExpr: SynExpr option * + arrow: Range option * + resultExpr: SynExpr * + range: range * + debugPoint: DebugPointAtTarget + + member this.RangeOfGuardAndRhs = + match this with + | SynMatchClause(_, eo, _, e, _, _) -> + match eo with + | None -> e.Range + | Some x -> unionRanges e.Range x.Range + + member this.Range = + match this with + | SynMatchClause(range = m) -> m + +[] +type SynAttribute = + { TypeName: LongIdentWithDots + + ArgExpr: SynExpr + + Target: Ident option + + AppliesToGetterAndSetter: bool + + Range: range + } + +[] +type SynAttributeList = + { + Attributes: SynAttribute list + + Range: range + } + +type SynAttributes = SynAttributeList list + +[] +type SynValData = + | SynValData of + memberFlags: SynMemberFlags option * + valInfo: SynValInfo * + thisIdOpt: Ident option + + member x.SynValInfo = (let (SynValData(_flags, synValInfo, _)) = x in synValInfo) + +[] +type SynBinding = + | SynBinding of + accessibility: SynAccess option * + kind: SynBindingKind * + isInline: bool * + isMutable: bool * + attributes: SynAttributes * + xmlDoc: PreXmlDoc * + valData: SynValData * + headPat: SynPat * + returnInfo: SynBindingReturnInfo option * + expr: SynExpr * + range: range * + debugPoint: DebugPointAtBinding + + // no member just named "Range", as that would be confusing: + // - for everything else, the 'range' member that appears last/second-to-last is the 'full range' of the whole tree construct + // - but for Binding, the 'range' is only the range of the left-hand-side, the right-hand-side range is in the SynExpr + // - so we use explicit names to avoid confusion + member x.RangeOfBindingWithoutRhs = let (SynBinding(range=m)) = x in m + + member x.RangeOfBindingWithRhs = let (SynBinding(expr=e; range=m)) = x in unionRanges e.Range m + + member x.RangeOfHeadPattern = let (SynBinding(headPat=headPat)) = x in headPat.Range + +[] +type SynBindingReturnInfo = + | SynBindingReturnInfo of + typeName: SynType * + range: range * + attributes: SynAttributes + +[] +type SynMemberFlags = + { + IsInstance: bool + + IsDispatchSlot: bool + + IsOverrideOrExplicitImpl: bool + + IsFinal: bool + + MemberKind: SynMemberKind + } + +[] +type SynMemberKind = + + | ClassConstructor + + | Constructor + + | Member + + | PropertyGet + + | PropertySet + + | PropertyGetSet + +[] +type SynMemberSig = + + | Member of + memberSig: SynValSig * + flags: SynMemberFlags * + range: range + + | Interface of + interfaceType: SynType * + range: range + + | Inherit of + inheritedType: SynType * + range: range + + | ValField of + field: SynField * + range: range + + | NestedType of + nestedType: SynTypeDefnSig * + range: range + + member d.Range = + match d with + | SynMemberSig.Member (range=m) + | SynMemberSig.Interface (range=m) + | SynMemberSig.Inherit (range=m) + | SynMemberSig.ValField (range=m) + | SynMemberSig.NestedType (range=m) -> m + +[] +type SynTypeDefnKind = + | Unspecified + | Class + | Interface + | Struct + | Record + | Union + | Abbrev + | Opaque + | Augmentation + | IL + | Delegate of signature: SynType * signatureInfo: SynValInfo + +[] +type SynTypeDefnSimpleRepr = + + | Union of + accessibility: SynAccess option * + unionCases: SynUnionCase list * + range: range + + | Enum of + cases: SynEnumCase list * + range: range + + | Record of + accessibility: SynAccess option * + recordFields: SynField list * + range: range + + | General of + kind: SynTypeDefnKind * + inherits: (SynType * range * Ident option) list * + slotsigs: (SynValSig * SynMemberFlags) list * + fields: SynField list * + isConcrete: bool * + isIncrClass: bool * + implicitCtorSynPats: SynSimplePats option * + range: range + + | LibraryOnlyILAssembly of + ilType: obj * // this type is ILType but is hidden to avoid the representation of AbstractIL being public + range: range + + | TypeAbbrev of + detail: ParserDetail * + rhsType: SynType * + range: range + + | None of + range: range + + | Exception of + exnRepr: SynExceptionDefnRepr + + member this.Range = + match this with + | Union (range=m) + | Enum (range=m) + | Record (range=m) + | General (range=m) + | LibraryOnlyILAssembly (range=m) + | TypeAbbrev (range=m) + | None (range=m) -> m + | Exception t -> t.Range + +[] +type SynEnumCase = + + | SynEnumCase of + attributes: SynAttributes * + ident: Ident * + value: SynConst * + valueRange: range * + xmlDoc: PreXmlDoc * + range: range + + member this.Range = + match this with + | SynEnumCase (range=m) -> m + +[] +type SynUnionCase = + + | SynUnionCase of + attributes: SynAttributes * + ident: Ident * + caseType: SynUnionCaseKind * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + + member this.Range = + match this with + | SynUnionCase (range=m) -> m + +[] +type SynUnionCaseKind = + + | Fields of + cases: SynField list + + | FullType of + fullType: SynType * + fullTypeInfo: SynValInfo + +[] +type SynTypeDefnSigRepr = + + | ObjectModel of + kind: SynTypeDefnKind * + memberSigs: SynMemberSig list * + range: range + + | Simple of + repr: SynTypeDefnSimpleRepr * + range: range + + | Exception of + repr: SynExceptionDefnRepr + + member this.Range = + match this with + | ObjectModel (range=m) + | Simple (range=m) -> m + | Exception e -> e.Range + +[] +type SynTypeDefnSig = + + | SynTypeDefnSig of + typeInfo: SynComponentInfo * + typeRepr: SynTypeDefnSigRepr * + members: SynMemberSig list * + range: range + + member this.Range = + match this with + | SynTypeDefnSig(range=m) -> m + +[] +type SynField = + | SynField of + attributes: SynAttributes * + isStatic: bool * + idOpt: Ident option * + fieldType: SynType * + isMutable: bool * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + +[] +type SynComponentInfo = + | SynComponentInfo of + attributes: SynAttributes * + typeParams: SynTyparDecls option * + constraints: SynTypeConstraint list * + longId: LongIdent * + xmlDoc: PreXmlDoc * + preferPostfix: bool * + accessibility: SynAccess option * + range: range + + member this.Range = + match this with + | SynComponentInfo (range=m) -> m + +[] +type SynValSig = + | SynValSig of + attributes: SynAttributes * + ident: Ident * + explicitValDecls: SynValTyparDecls * + synType: SynType * + arity: SynValInfo * + isInline: bool * + isMutable: bool * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + synExpr: SynExpr option * + range: range + + member x.RangeOfId = let (SynValSig(ident=id)) = x in id.idRange + + member x.SynInfo = let (SynValSig(arity=v)) = x in v + + member x.SynType = let (SynValSig(synType=ty)) = x in ty + +[] +type SynValInfo = + + | SynValInfo of curriedArgInfos: SynArgInfo list list * returnInfo: SynArgInfo + + member x.CurriedArgInfos = (let (SynValInfo(args, _)) = x in args) + + member x.ArgNames = + x.CurriedArgInfos + |> List.concat + |> List.map (fun info -> info.Ident) + |> List.choose id + |> List.map (fun id -> id.idText) + +[] +type SynArgInfo = + + | SynArgInfo of + attributes: SynAttributes * + optional: bool * + ident: Ident option + + member x.Ident : Ident option = let (SynArgInfo(_,_,id)) = x in id + + member x.Attributes : SynAttributes = let (SynArgInfo(attrs,_,_)) = x in attrs + +[] +type SynValTyparDecls = + | SynValTyparDecls of + typars: SynTyparDecls option * + canInfer: bool + +[] +type SynReturnInfo = + | SynReturnInfo of returnType: (SynType * SynArgInfo) * range: range + +[] +type SynExceptionDefnRepr = + + | SynExceptionDefnRepr of + attributes: SynAttributes * + caseName: SynUnionCase * + longId: LongIdent option * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + + member this.Range = match this with SynExceptionDefnRepr (range=m) -> m + +[] +type SynExceptionDefn = + + | SynExceptionDefn of + exnRepr: SynExceptionDefnRepr * + members: SynMemberDefns * + range: range + + member this.Range = + match this with + | SynExceptionDefn (range=m) -> m + +[] +type SynTypeDefnRepr = + + | ObjectModel of + kind: SynTypeDefnKind * + members: SynMemberDefns * + range: range + + | Simple of + simpleRepr: SynTypeDefnSimpleRepr * + range: range + + | Exception of + exnRepr: SynExceptionDefnRepr + + member this.Range = + match this with + | ObjectModel (range=m) + | Simple (range=m) -> m + | Exception t -> t.Range + +[] +type SynTypeDefn = + | SynTypeDefn of + typeInfo: SynComponentInfo * + typeRepr: SynTypeDefnRepr * + members: SynMemberDefns * + implicitConstructor: SynMemberDefn option * + range: range + + member this.Range = + match this with + | SynTypeDefn (range=m) -> m + +[] +type SynMemberDefn = + + | Open of + target: SynOpenDeclTarget * + range: range + + | Member of + memberDefn: SynBinding * + range: range + + | ImplicitCtor of + accessibility: SynAccess option * + attributes: SynAttributes * + ctorArgs: SynSimplePats * + selfIdentifier: Ident option * + xmlDoc: PreXmlDoc * + range: range + + | ImplicitInherit of + inheritType: SynType * + inheritArgs: SynExpr * + inheritAlias: Ident option * + range: range + + | LetBindings of + bindings: SynBinding list * + isStatic: bool * + isRecursive: bool * + range: range + + | AbstractSlot of + slotSig: SynValSig * + flags: SynMemberFlags * + range: range + + | Interface of + interfaceType: SynType * + members: SynMemberDefns option * + range: range + + | Inherit of + baseType: SynType * + asIdent: Ident option * + range: range + + | ValField of + fieldInfo: SynField * + range: range + + | NestedType of + typeDefn: SynTypeDefn * + accessibility: SynAccess option * + range: range + + | AutoProperty of + attributes: SynAttributes * + isStatic: bool * + ident: Ident * + typeOpt: SynType option * + propKind: SynMemberKind * + memberFlags:(SynMemberKind -> SynMemberFlags) * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + synExpr: SynExpr * + getSetRange: range option * + range: range + + member d.Range = + match d with + | SynMemberDefn.Member (range=m) + | SynMemberDefn.Interface (range=m) + | SynMemberDefn.Open (range=m) + | SynMemberDefn.LetBindings (range=m) + | SynMemberDefn.ImplicitCtor (range=m) + | SynMemberDefn.ImplicitInherit (range=m) + | SynMemberDefn.AbstractSlot (range=m) + | SynMemberDefn.Inherit (range=m) + | SynMemberDefn.ValField (range=m) + | SynMemberDefn.AutoProperty (range=m) + | SynMemberDefn.NestedType (range=m) -> m + +type SynMemberDefns = SynMemberDefn list + +[] +type SynModuleDecl = + + | ModuleAbbrev of + ident: Ident * + longId: LongIdent * + range: range + + | NestedModule of + moduleInfo: SynComponentInfo * + isRecursive: bool * + decls: SynModuleDecl list * + isContinuing: bool * + range: range + + | Let of + isRecursive: bool * + bindings: SynBinding list * + range: range + + | DoExpr of + debugPoint: DebugPointAtBinding * + expr: SynExpr * + range: range + + | Types of + typeDefns: SynTypeDefn list * + range: range + + | Exception of + exnDefn: SynExceptionDefn * + range: range + + | Open of + target: SynOpenDeclTarget * + range: range + + | Attributes of + attributes: SynAttributes * + range: range + + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + + | NamespaceFragment of + fragment: SynModuleOrNamespace + + member d.Range = + match d with + | SynModuleDecl.ModuleAbbrev (range=m) + | SynModuleDecl.NestedModule (range=m) + | SynModuleDecl.Let (range=m) + | SynModuleDecl.DoExpr (range=m) + | SynModuleDecl.Types (range=m) + | SynModuleDecl.Exception (range=m) + | SynModuleDecl.Open (range=m) + | SynModuleDecl.HashDirective (range=m) + | SynModuleDecl.NamespaceFragment (SynModuleOrNamespace (range=m)) + | SynModuleDecl.Attributes (range=m) -> m + +[] +type SynOpenDeclTarget = + + | ModuleOrNamespace of longId: LongIdent * range: range + + | Type of typeName: SynType * range: range + + member this.Range = + match this with + | ModuleOrNamespace (range=m) -> m + | Type (range=m) -> m + +[] +type SynExceptionSig = + | SynExceptionSig of + exnRepr: SynExceptionDefnRepr * + members: SynMemberSig list * + range: range + +[] +type SynModuleSigDecl = + + | ModuleAbbrev of + ident: Ident * + longId: LongIdent * + range: range + + | NestedModule of + moduleInfo: SynComponentInfo * + isRecursive: bool * + moduleDecls: SynModuleSigDecl list * + range: range + + | Val of + valSig: SynValSig * range: range + + | Types of + types: SynTypeDefnSig list * + range: range + + | Exception of + exnSig: SynExceptionSig * + range: range + + | Open of + target: SynOpenDeclTarget * + range: range + + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + + | NamespaceFragment of + SynModuleOrNamespaceSig + + member d.Range = + match d with + | SynModuleSigDecl.ModuleAbbrev (range=m) + | SynModuleSigDecl.NestedModule (range=m) + | SynModuleSigDecl.Val (range=m) + | SynModuleSigDecl.Types (range=m) + | SynModuleSigDecl.Exception (range=m) + | SynModuleSigDecl.Open (range=m) + | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig.SynModuleOrNamespaceSig(range=m)) + | SynModuleSigDecl.HashDirective (range=m) -> m + +[] +type SynModuleOrNamespaceKind = + | NamedModule + + | AnonModule + + | DeclaredNamespace + + | GlobalNamespace + + member x.IsModule = + match x with + | NamedModule | AnonModule -> true + | _ -> false + +[] +type SynModuleOrNamespace = + | SynModuleOrNamespace of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleDecl list * + xmlDoc: PreXmlDoc * + attribs: SynAttributes * + accessibility: SynAccess option * + range: range + + member this.Range = + match this with + | SynModuleOrNamespace (range=m) -> m + +[] +type SynModuleOrNamespaceSig = + | SynModuleOrNamespaceSig of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleSigDecl list * + xmlDoc: PreXmlDoc * + attribs: SynAttributes * + accessibility: SynAccess option * + range: range + + member this.Range = + match this with + | SynModuleOrNamespaceSig (range=m) -> m + +[] +type ParsedHashDirectiveArgument = + | String of value: string * stringKind: SynStringKind * range: Range + | SourceIdentifier of constant: string * value: string * range: Range + + member this.Range = + match this with + | ParsedHashDirectiveArgument.String (range=m) + | ParsedHashDirectiveArgument.SourceIdentifier (range=m) -> m + +[] +type ParsedHashDirective = + | ParsedHashDirective of + ident: string * + args: ParsedHashDirectiveArgument list * + range: range + +[] +type ParsedImplFileFragment = + + | AnonModule of + decls: SynModuleDecl list * + range: range + + | NamedModule of + namedModule: SynModuleOrNamespace + + | NamespaceFragment of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleDecl list * + xmlDoc: PreXmlDoc * + attributes: SynAttributes * + range: range + +[] +type ParsedSigFileFragment = + + | AnonModule of + decls: SynModuleSigDecl list * + range: range + + | NamedModule of + namedModule: SynModuleOrNamespaceSig + + | NamespaceFragment of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleSigDecl list * + xmlDoc: PreXmlDoc * + attributes: SynAttributes * + range: range + +[] +type ParsedScriptInteraction = + | Definitions of + defns: SynModuleDecl list * + range: range + + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + +[] +type ParsedImplFile = + | ParsedImplFile of + hashDirectives: ParsedHashDirective list * + fragments: ParsedImplFileFragment list + +[] +type ParsedSigFile = + | ParsedSigFile of + hashDirectives: ParsedHashDirective list * + fragments: ParsedSigFileFragment list + +[] +type ScopedPragma = + | WarningOff of range: range * warningNumber: int + +[] +type QualifiedNameOfFile = + | QualifiedNameOfFile of Ident + + member x.Text = (let (QualifiedNameOfFile t) = x in t.idText) + + member x.Id = (let (QualifiedNameOfFile t) = x in t) + + member x.Range = (let (QualifiedNameOfFile t) = x in t.idRange) + +[] +type ParsedImplFileInput = + | ParsedImplFileInput of + fileName: string * + isScript: bool * + qualifiedNameOfFile: QualifiedNameOfFile * + scopedPragmas: ScopedPragma list * + hashDirectives: ParsedHashDirective list * + modules: SynModuleOrNamespace list * + isLastCompiland: (bool * bool) + +[] +type ParsedSigFileInput = + | ParsedSigFileInput of + fileName: string * + qualifiedNameOfFile: QualifiedNameOfFile * + scopedPragmas: ScopedPragma list * + hashDirectives: ParsedHashDirective list * + modules: SynModuleOrNamespaceSig list + +[] +type ParsedInput = + | ImplFile of ParsedImplFileInput + + | SigFile of ParsedSigFileInput + + member inp.FileName = + match inp with + | ParsedInput.ImplFile (ParsedImplFileInput (fileName=filename)) + | ParsedInput.SigFile (ParsedSigFileInput (fileName=filename)) -> filename + + member inp.Range = + match inp with + | ParsedInput.ImplFile (ParsedImplFileInput (modules=SynModuleOrNamespace(range=m) :: _)) + | ParsedInput.SigFile (ParsedSigFileInput (modules=SynModuleOrNamespaceSig(range=m) :: _)) -> m + | ParsedInput.ImplFile (ParsedImplFileInput (fileName=filename)) + | ParsedInput.SigFile (ParsedSigFileInput (fileName=filename)) -> rangeN filename 0 diff --git a/src/fsharp/SyntaxTree.fsi b/src/fsharp/SyntaxTree.fsi new file mode 100644 index 00000000000..97a766b8ff5 --- /dev/null +++ b/src/fsharp/SyntaxTree.fsi @@ -0,0 +1,2174 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace rec FSharp.Compiler.Syntax + +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Xml + +/// Represents an identifier in F# code +[] +type Ident = + new: text: string * range: range -> Ident + member idText: string + member idRange: range + + +/// Represents a long identifier e.g. 'A.B.C' +type LongIdent = Ident list + + +/// Represents a long identifier with possible '.' at end. +/// +/// Typically dotRanges.Length = lid.Length-1, but they may be same if (incomplete) code ends in a dot, e.g. "Foo.Bar." +/// The dots mostly matter for parsing, and are typically ignored by the typechecker, but +/// if dotRanges.Length = lid.Length, then the parser must have reported an error, so the typechecker is allowed +/// more freedom about typechecking these expressions. +/// LongIdent can be empty list - it is used to denote that name of some AST element is absent (i.e. empty type name in inherit) +type LongIdentWithDots = + | //[] + LongIdentWithDots of id: LongIdent * dotRanges: range list + + /// Gets the syntax range of this construct + member Range: range + + /// Get the long ident for this construct + member Lid: LongIdent + + /// Indicates if the construct ends in '.' due to error recovery + member ThereIsAnExtraDotAtTheEnd: bool + + /// Gets the syntax range for part of this construct + member RangeWithoutAnyExtraDot: range + +/// Indicates if the construct arises from error recovery +[] +type ParserDetail = + /// The construct arises normally + | Ok + + /// The construct arises from error recovery + | ErrorRecovery + +/// Represents whether a type parameter has a static requirement or not (^T or 'T) +[] +type TyparStaticReq = + /// The construct is a normal type inference variable + | None + + /// The construct is a statically inferred type inference variable '^T' + | HeadType + +/// Represents a syntactic type parameter +[] +type SynTypar = + | SynTypar of ident: Ident * staticReq: TyparStaticReq * isCompGen: bool + + /// Gets the syntax range of this construct + member Range: range + +/// Indicate if the string had a special format +[] +type SynStringKind = + | Regular + | Verbatim + | TripleQuote + +/// Indicate if the byte string had a special format +[] +type SynByteStringKind = + | Regular + | Verbatim + +/// The unchecked abstract syntax tree of constants in F# types and expressions. +[] +type SynConst = + + /// F# syntax: () + | Unit + + /// F# syntax: true, false + | Bool of bool + + /// F# syntax: 13y, 0xFFy, 0o077y, 0b0111101y + | SByte of sbyte + + /// F# syntax: 13uy, 0x40uy, 0oFFuy, 0b0111101uy + | Byte of byte + + /// F# syntax: 13s, 0x4000s, 0o0777s, 0b0111101s + | Int16 of int16 + + /// F# syntax: 13us, 0x4000us, 0o0777us, 0b0111101us + | UInt16 of uint16 + + /// F# syntax: 13, 0x4000, 0o0777 + | Int32 of int32 + + /// F# syntax: 13u, 0x4000u, 0o0777u + | UInt32 of uint32 + + /// F# syntax: 13L + | Int64 of int64 + + /// F# syntax: 13UL + | UInt64 of uint64 + + /// F# syntax: 13n + | IntPtr of int64 + + /// F# syntax: 13un + | UIntPtr of uint64 + + /// F# syntax: 1.30f, 1.40e10f etc. + | Single of single + + /// F# syntax: 1.30, 1.40e10 etc. + | Double of double + + /// F# syntax: 'a' + | Char of char + + /// F# syntax: 23.4M + | Decimal of System.Decimal + + /// UserNum(value, suffix) + /// + /// F# syntax: 1Q, 1Z, 1R, 1N, 1G + | UserNum of value: string * suffix: string + + /// F# syntax: verbatim or regular string, e.g. "abc" + | String of text: string * synStringKind :SynStringKind * range: range + + /// F# syntax: verbatim or regular byte string, e.g. "abc"B. + /// + /// Also used internally in the typechecker once an array of unit16 constants + /// is detected, to allow more efficient processing of large arrays of uint16 constants. + | Bytes of bytes: byte[] * synByteStringKind: SynByteStringKind * range: range + + /// Used internally in the typechecker once an array of unit16 constants + /// is detected, to allow more efficient processing of large arrays of uint16 constants. + | UInt16s of uint16[] + + /// Old comment: "we never iterate, so the const here is not another SynConst.Measure" + | Measure of constant: SynConst * constantRange: range * SynMeasure + + /// Source Line, File, and Path Identifiers + /// Containing both the original value as the evaluated value. + | SourceIdentifier of constant: string * value: string * range: Range + + /// Gets the syntax range of this construct + member Range: dflt: range -> range + +/// Represents an unchecked syntax tree of F# unit of measure annotations. +[] +type SynMeasure = + + /// A named unit of measure + | Named of longId: LongIdent * range: range + + /// A product of two units of measure, e.g. 'kg * m' + | Product of measure1: SynMeasure * measure2: SynMeasure * range: range + + /// A sequence of several units of measure, e.g. 'kg m m' + | Seq of measures: SynMeasure list * range: range + + /// A division of two units of measure, e.g. 'kg / m' + | Divide of measure1: SynMeasure * measure2: SynMeasure * range: range + + /// A power of a unit of measure, e.g. 'kg ^ 2' + | Power of measure: SynMeasure * power: SynRationalConst * range: range + + /// The '1' unit of measure + | One + + /// An anonymous (inferred) unit of measure + | Anon of range: range + + /// A variable unit of measure + | Var of typar: SynTypar * range: range + +/// Represents an unchecked syntax tree of F# unit of measure exponents. +[] +type SynRationalConst = + + | Integer of value: int32 + + | Rational of numerator: int32 * denominator: int32 * range: range + + | Negate of SynRationalConst + +/// Represents an accessibility modifier in F# syntax +[] +type SynAccess = + /// A construct marked or assumed 'public' + | Public + + /// A construct marked or assumed 'internal' + | Internal + + /// A construct marked or assumed 'private' + | Private + +/// Represents whether a debug point should be present for the target +/// of a decision tree, that is whether the construct corresponds to a debug +/// point in the original source. +[] +type DebugPointAtTarget = + | Yes + | No + +/// Represents whether a debug point should be present at the switch +/// logic of a decision tree. These are introduced for 'when' expressions +/// and the encoding of 'a && b', 'a || b' +[] +type DebugPointAtSwitch = + | Yes of range + | No + +/// Represents whether a debug point should be suppressed for either the +/// first or second part of a sequential execution, that is whether the +/// construct corresponds to a debug point in the original source. +[] +type DebugPointAtSequential = + | SuppressNeither + + // This means "suppress a in 'a;b'" and "suppress b in 'a before b'" + | SuppressStmt + + // This means "suppress both" + | SuppressBoth + + // This means "suppress b in 'a;b'" and "suppress a in 'a before b'" + | SuppressExpr + +/// Represents whether a debug point should be present for a 'try', that is whether +/// the construct corresponds to a debug point in the original source. +[] +type DebugPointAtTry = + | Yes of range: range + | Body + | No + +/// Represents whether a debug point should be present for the 'with' in a 'try .. with', +/// that is whether the construct corresponds to a debug point in the original source. +[] +type DebugPointAtWith = + | Yes of range: range + | No + +/// Represents whether a debug point should be present for the 'finally' in a 'try .. finally', +/// that is whether the construct corresponds to a debug point in the original source. +[] +type DebugPointAtFinally = + | Yes of range: range + | Body + | No + +/// Represents whether a debug point should be present for the 'for' in a 'for...' loop, +/// that is whether the construct corresponds to a debug point in the original source. +[] +type DebugPointAtFor = + | Yes of range: range + | No + +/// Represents whether a debug point should be present for the 'while' in a 'while...' loop, +/// that is whether the construct corresponds to a debug point in the original source. +[] +type DebugPointAtWhile = + | Yes of range: range + | No + +/// Represents whether a debug point should be present for a 'let' binding, +/// that is whether the construct corresponds to a debug point in the original source. +[] +type DebugPointAtBinding = + // Indicates emit of a debug point prior to the 'let' + | Yes of range: range + + // Indicates the omission of a debug point for a binding for a 'do expr' + | NoneAtDo + + // Indicates the omission of a debug point for a binding for a 'let e = expr' where + // 'expr' has immediate control flow + | NoneAtLet + + // Indicates the omission of a debug point for a compiler generated binding + // where we've done a local expansion of some construct into something that involves + // a 'let'. e.g. we've inlined a function and bound its arguments using 'let' + // The let bindings are 'sticky' in that the inversion of the inlining would involve + // replacing the entire expression with the original and not just the let bindings alone. + | NoneAtSticky + + // Given 'let v = e1 in e2', where this is a compiler generated binding, + // we are sometimes forced to generate a debug point for the expression anyway based on its + // overall range. If the let binding is given the flag below then it is asserting that + // the binding has no interesting side effects and can be totally ignored and the range + // of the inner expression is used instead + | NoneAtInvisible + + // Don't drop debug points when combining debug points + member Combine: y: DebugPointAtBinding -> DebugPointAtBinding + +/// Indicates if a for loop is 'for x in e1 -> e2', only valid in sequence expressions +type SeqExprOnly = + /// Indicates if a for loop is 'for x in e1 -> e2', only valid in sequence expressions + | SeqExprOnly of bool + +/// Represents the location of the separator block + optional position +/// of the semicolon (used for tooling support) +type BlockSeparator = range * pos option + +/// Represents a record field name plus a flag indicating if given record field name is syntactically +/// correct and can be used in name resolution. +type RecordFieldName = LongIdentWithDots * bool + +/// Indicates if an expression is an atomic expression. +/// +/// An atomic expression has no whitespace unless enclosed in parentheses, e.g. +/// 1, "3", ident, ident.[expr] and (expr). If an atomic expression has type T, +/// then the largest expression ending at the same range as the atomic expression +/// also has type T. +type ExprAtomicFlag = + | Atomic = 0 + | NonAtomic = 1 + +/// The kind associated with a binding - "let", "do" or a standalone expression +[] +type SynBindingKind = + + /// A standalone expression in a module + | StandaloneExpression + + /// A normal 'let' binding in a module + | Normal + + /// A 'do' binding in a module. Must have type 'unit' + | Do + +/// Represents the explicit declaration of a type parameter +[] +type SynTyparDecl = + | SynTyparDecl of attributes: SynAttributes * SynTypar + +/// The unchecked abstract syntax tree of F# type constraints +[] +type SynTypeConstraint = + + /// F# syntax: is 'typar: struct + | WhereTyparIsValueType of + typar: SynTypar * + range: range + + /// F# syntax: is 'typar: not struct + | WhereTyparIsReferenceType of + typar: SynTypar * + range: range + + /// F# syntax is 'typar: unmanaged + | WhereTyparIsUnmanaged of + typar: SynTypar * + range: range + + /// F# syntax is 'typar: null + | WhereTyparSupportsNull of + typar: SynTypar * + range: range + + /// F# syntax is 'typar: comparison + | WhereTyparIsComparable of + typar: SynTypar * + range: range + + /// F# syntax is 'typar: equality + | WhereTyparIsEquatable of + typar: SynTypar * + range: range + + /// F# syntax is default ^T: type + | WhereTyparDefaultsToType of + typar: SynTypar * + typeName: SynType * + range: range + + /// F# syntax is 'typar :> type + | WhereTyparSubtypeOfType of + typar: SynTypar * + typeName: SynType * + range: range + + /// F# syntax is ^T: (static member MemberName: ^T * int -> ^T) + | WhereTyparSupportsMember of + typars: SynType list * + memberSig: SynMemberSig * + range: range + + /// F# syntax is 'typar: enum<'UnderlyingType> + | WhereTyparIsEnum of + typar: SynTypar * + typeArgs: SynType list * + range: range + + /// F# syntax is 'typar: delegate<'Args, unit> + | WhereTyparIsDelegate of + typar: SynTypar * + typeArgs: SynType list * + range: range + + member Range: range + +/// List of type parameter declarations with optional type constraints, +/// enclosed in `< ... >` (postfix) or `( ... )` (prefix), or a single prefix parameter. +[] +type SynTyparDecls = + | PostfixList of decls: SynTyparDecl list * constraints: SynTypeConstraint list * range: range + | PrefixList of decls: SynTyparDecl list * range: range + | SinglePrefix of decl: SynTyparDecl * range: range + + member TyparDecls: SynTyparDecl list + member Constraints: SynTypeConstraint list + member Range: range + +/// Represents a syntax tree for F# types +[] +type SynType = + + /// F# syntax: A.B.C + | LongIdent of + longDotId: LongIdentWithDots + + /// F# syntax: type or type type or (type, ..., type) type + /// isPostfix: indicates a postfix type application e.g. "int list" or "(int, string) dict" + | App of + typeName: SynType * + lessRange: range option * + typeArgs: SynType list * + commaRanges: range list * // interstitial commas + greaterRange: range option * + isPostfix: bool * + range: range + + /// F# syntax: type.A.B.C + | LongIdentApp of + typeName: SynType * + longDotId: LongIdentWithDots * + lessRange: range option * + typeArgs: SynType list * + commaRanges: range list * // interstitial commas + greaterRange: range option * + range: range + + /// F# syntax: type * ... * type + /// F# syntax: struct (type * ... * type) + // the bool is true if / rather than * follows the type + | Tuple of + isStruct: bool * + elementTypes:(bool*SynType) list * + range: range + + /// F# syntax: {| id: type; ...; id: type |} + /// F# syntax: struct {| id: type; ...; id: type |} + | AnonRecd of + isStruct: bool * + fields:(Ident * SynType) list * + range: range + + /// F# syntax: type[] + | Array of + rank: int * + elementType: SynType * + range: range + + /// F# syntax: type -> type + | Fun of + argType: SynType * + returnType: SynType * + range: range + + /// F# syntax: 'Var + | Var of + typar: SynTypar * + range: range + + /// F# syntax: _ + | Anon of range: range + + /// F# syntax: typ with constraints + | WithGlobalConstraints of + typeName: SynType * + constraints: SynTypeConstraint list * + range: range + + /// F# syntax: #type + | HashConstraint of + innerType: SynType * + range: range + + /// F# syntax: for units of measure e.g. m / s + | MeasureDivide of + dividend: SynType * + divisor: SynType * + range: range + + /// F# syntax: for units of measure e.g. m^3, kg^1/2 + | MeasurePower of + baseMeasure: SynType * + exponent: SynRationalConst * + range: range + + /// F# syntax: 1, "abc" etc, used in parameters to type providers + /// For the dimensionless units i.e. 1, and static parameters to provided types + | StaticConstant of + constant: SynConst * + range: range + + /// F# syntax: const expr, used in static parameters to type providers + | StaticConstantExpr of + expr: SynExpr * + range: range + + /// F# syntax: ident=1 etc., used in static parameters to type providers + | StaticConstantNamed of + ident: SynType * + value: SynType * + range: range + + | Paren of + innerType: SynType * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a syntax tree for F# expressions +[] +type SynExpr = + + /// F# syntax: (expr) + /// + /// Parenthesized expressions. Kept in AST to distinguish A.M((x, y)) + /// from A.M(x, y), among other things. + | Paren of + expr: SynExpr * + leftParenRange: range * + rightParenRange: range option * + range: range + + /// F# syntax: <@ expr @>, <@@ expr @@> + /// + /// Quote(operator, isRaw, quotedSynExpr, isFromQueryExpression, m) + | Quote of + operator: SynExpr * + isRaw: bool * + quotedExpr: SynExpr * + isFromQueryExpression: bool * + range: range + + /// F# syntax: 1, 1.3, () etc. + | Const of + constant: SynConst * + range: range + + /// F# syntax: expr: type + | Typed of + expr: SynExpr * + targetType: SynType * + range: range + + /// F# syntax: e1, ..., eN + | Tuple of + isStruct: bool * + exprs: SynExpr list * + commaRanges: range list * // interstitial commas + range: range + + /// F# syntax: {| id1=e1; ...; idN=eN |} + /// F# syntax: struct {| id1=e1; ...; idN=eN |} + | AnonRecd of + isStruct: bool * + copyInfo:(SynExpr * BlockSeparator) option * + recordFields:(Ident * SynExpr) list * + range: range + + /// F# syntax: [ e1; ...; en ], [| e1; ...; en |] + | ArrayOrList of + isArray: bool * + exprs: SynExpr list * + range: range + + /// F# syntax: { f1=e1; ...; fn=en } + /// inherit includes location of separator (for tooling) + /// copyOpt contains range of the following WITH part (for tooling) + /// every field includes range of separator after the field (for tooling) + | Record of + baseInfo:(SynType * SynExpr * range * BlockSeparator option * range) option * + copyInfo:(SynExpr * BlockSeparator) option * + recordFields:(RecordFieldName * SynExpr option * BlockSeparator option) list * + range: range + + /// F# syntax: new C(...) + /// The flag is true if known to be 'family' ('protected') scope + | New of + isProtected: bool * + targetType: SynType * + expr: SynExpr * + range: range + + /// F# syntax: { new ... with ... } + | ObjExpr of + objType: SynType * + argOptions:(SynExpr * Ident option) option * + bindings: SynBinding list * + extraImpls: SynInterfaceImpl list * + newExprRange: range * + range: range + + /// F# syntax: 'while ... do ...' + | While of + whileDebugPoint: DebugPointAtWhile * + whileExpr: SynExpr * + doExpr: SynExpr * + range: range + + /// F# syntax: 'for i = ... to ... do ...' + | For of + forDebugPoint: DebugPointAtFor * + ident: Ident * + identBody: SynExpr * + direction: bool * + toBody: SynExpr * + doBody: SynExpr * + range: range + + /// F# syntax: 'for ... in ... do ...' + | ForEach of + forDebugPoint: DebugPointAtFor * + seqExprOnly: SeqExprOnly * + isFromSource: bool * + pat: SynPat * + enumExpr: SynExpr * + bodyExpr: SynExpr * + range: range + + /// F# syntax: [ expr ], [| expr |] + | ArrayOrListComputed of + isArray: bool * + expr: SynExpr * + range: range + + /// F# syntax: expr.. + /// F# syntax: ..expr + /// F# syntax: expr..expr + /// F# syntax: * + /// A two-element range indexer argument a..b, a.., ..b. Also used to represent + /// a range in a list, array or sequence expression. + | IndexRange of + expr1: SynExpr option * + opm: range * + expr2: SynExpr option* + range1: range * + range2: range * + range: range + + /// F# syntax: ^expr + | IndexFromEnd of + expr: SynExpr * + range: range + + /// F# syntax: { expr } + | ComputationExpr of + hasSeqBuilder: bool * + expr: SynExpr * + range: range + + /// First bool indicates if lambda originates from a method. Patterns here are always "simple" + /// Second bool indicates if this is a "later" part of an iterated sequence of lambdas + /// parsedData keeps original parsed patterns and expression, + /// prior to transforming to "simple" patterns and iterated lambdas + /// + /// F# syntax: fun pat -> expr + | Lambda of + fromMethod: bool * + inLambdaSeq: bool * + args: SynSimplePats * + arrow: Range option * + body: SynExpr * + parsedData: (SynPat list * SynExpr) option * + range: range + + /// F# syntax: function pat1 -> expr | ... | patN -> exprN + | MatchLambda of + isExnMatch: bool * + keywordRange: range * + matchClauses: SynMatchClause list * + matchDebugPoint: DebugPointAtBinding * + range: range + + /// F# syntax: match expr with pat1 -> expr | ... | patN -> exprN + | Match of + matchDebugPoint: DebugPointAtBinding * + expr: SynExpr * + clauses: SynMatchClause list * + range: range + + /// F# syntax: do expr + | Do of + expr: SynExpr * + range: range + + /// F# syntax: assert expr + | Assert of + expr: SynExpr * + range: range + + /// F# syntax: f x + /// + /// flag: indicates if the application is syntactically atomic, e.g. f.[1] is atomic, but 'f x' is not + /// isInfix is true for the first app of an infix operator, e.g. 1+2 + /// becomes App(App(+, 1), 2), where the inner node is marked isInfix + | App of + flag: ExprAtomicFlag * + isInfix: bool * + funcExpr: SynExpr * + argExpr: SynExpr * + range: range + + /// F# syntax: expr + | TypeApp of + expr: SynExpr * + lessRange: range * + typeArgs: SynType list * + commaRanges: range list * + greaterRange: range option * + typeArgsRange: range * + range: range + + /// F# syntax: let pat = expr in expr + /// F# syntax: let f pat1 .. patN = expr in expr + /// F# syntax: let rec f pat1 .. patN = expr in expr + /// F# syntax: use pat = expr in expr + | LetOrUse of + isRecursive: bool * + isUse: bool * + bindings: SynBinding list * + body: SynExpr * + range: range + + /// F# syntax: try expr with pat -> expr + | TryWith of + tryExpr: SynExpr * + tryRange: range * + withCases: SynMatchClause list * + withRange: range * + range: range * + tryDebugPoint: DebugPointAtTry * + withDebugPoint: DebugPointAtWith + + /// F# syntax: try expr finally expr + | TryFinally of + tryExpr: SynExpr * + finallyExpr: SynExpr * + range: range * + tryDebugPoint: DebugPointAtTry * + finallyDebugPoint: DebugPointAtFinally + + /// F# syntax: lazy expr + | Lazy of + expr: SynExpr * + range: range + + /// F# syntax: expr; expr + /// + /// isTrueSeq: false indicates "let v = a in b; v" + | Sequential of + debugPoint: DebugPointAtSequential * + isTrueSeq: bool * + expr1: SynExpr * + expr2: SynExpr * + range: range + + /// F# syntax: if expr then expr + /// F# syntax: if expr then expr else expr + | IfThenElse of + ifKeyword: range * + isElif: bool * + ifExpr: SynExpr * + thenKeyword: range * + thenExpr: SynExpr * + elseKeyword: range option * + elseExpr: SynExpr option * + spIfToThen: DebugPointAtBinding * + isFromErrorRecovery: bool * + ifToThenRange: range * + range: range + + /// F# syntax: ident + /// Optimized representation for SynExpr.LongIdent (false, [id], id.idRange) + | Ident of + ident: Ident + + /// F# syntax: ident.ident...ident + /// + /// isOptional: true if preceded by a '?' for an optional named parameter + /// altNameRefCell: Normally 'None' except for some compiler-generated + /// variables in desugaring pattern matching. See SynSimplePat.Id + | LongIdent of + isOptional: bool * + longDotId: LongIdentWithDots * + altNameRefCell: SynSimplePatAlternativeIdInfo ref option * + range: range + + /// F# syntax: ident.ident...ident <- expr + | LongIdentSet of + longDotId: LongIdentWithDots * + expr: SynExpr * + range: range + + /// F# syntax: expr.ident.ident + | DotGet of + expr: SynExpr * + rangeOfDot: range * + longDotId: LongIdentWithDots * + range: range + + /// F# syntax: expr.ident...ident <- expr + | DotSet of + targetExpr: SynExpr * + longDotId: LongIdentWithDots * + rhsExpr: SynExpr * + range: range + + /// F# syntax: expr <- expr + | Set of + targetExpr: SynExpr * + rhsExpr: SynExpr * + range: range + + /// F# syntax: expr.[expr, ..., expr] + | DotIndexedGet of + objectExpr: SynExpr * + indexArgs: SynExpr * + dotRange: range * + range: range + + /// F# syntax: expr.[expr, ..., expr] <- expr + | DotIndexedSet of + objectExpr: SynExpr * + indexArgs: SynExpr * + valueExpr: SynExpr * + leftOfSetRange: range * + dotRange: range * + range: range + + /// F# syntax: Type.Items(e1) <- e2, rarely used named-property-setter notation, e.g. Foo.Bar.Chars(3) <- 'a' + | NamedIndexedPropertySet of + longDotId: LongIdentWithDots * + expr1: SynExpr * + expr2: SynExpr * + range: range + + /// F# syntax: expr.Items (e1) <- e2, rarely used named-property-setter notation, e.g. (stringExpr).Chars(3) <- 'a' + | DotNamedIndexedPropertySet of + targetExpr: SynExpr * + longDotId: LongIdentWithDots * + argExpr: SynExpr * + rhsExpr: SynExpr * + range: range + + /// F# syntax: expr :? type + | TypeTest of + expr: SynExpr * + targetType: SynType * + range: range + + /// F# syntax: expr :> type + | Upcast of + expr: SynExpr * + targetType: SynType * + range: range + + /// F# syntax: expr :?> type + | Downcast of + expr: SynExpr * + targetType: SynType * + range: range + + /// F# syntax: upcast expr + | InferredUpcast of + expr: SynExpr * + range: range + + /// F# syntax: downcast expr + | InferredDowncast of + expr: SynExpr * + range: range + + /// F# syntax: null + | Null of + range: range + + /// F# syntax: &expr, &&expr + | AddressOf of + isByref: bool * + expr: SynExpr * + opRange: range * + range: range + + /// F# syntax: ((typar1 or ... or typarN): (member-dig) expr) + | TraitCall of + supportTys: SynTypar list * + traitSig: SynMemberSig * + argExpr: SynExpr * + range: range + + /// F# syntax: ... in ... + /// Computation expressions only, based on JOIN_IN token from lex filter + | JoinIn of + lhsExpr: SynExpr * + lhsRange: range * + rhsExpr: SynExpr * + range: range + + /// Used in parser error recovery and internally during type checking for translating computation expressions. + | ImplicitZero of + range: range + + /// Used internally during type checking for translating computation expressions. + | SequentialOrImplicitYield of + debugPoint:DebugPointAtSequential * + expr1:SynExpr * + expr2:SynExpr * + ifNotStmt:SynExpr * + range:range + + /// F# syntax: yield expr + /// F# syntax: return expr + /// Computation expressions only + | YieldOrReturn of + flags: (bool * bool) * + expr: SynExpr * + range: range + + /// F# syntax: yield! expr + /// F# syntax: return! expr + /// Computation expressions only + | YieldOrReturnFrom of + flags: (bool * bool) * + expr: SynExpr * + range: range + + /// F# syntax: let! pat = expr in expr + /// F# syntax: use! pat = expr in expr + /// F# syntax: let! pat = expr and! ... and! ... and! pat = expr in expr + /// Computation expressions only + | LetOrUseBang of + bindDebugPoint: DebugPointAtBinding * + isUse: bool * + isFromSource: bool * + pat: SynPat * + rhs: SynExpr * + andBangs:(DebugPointAtBinding * bool * bool * SynPat * SynExpr * range) list * + body:SynExpr * + range: range + + /// F# syntax: match! expr with pat1 -> expr | ... | patN -> exprN + | MatchBang of + matchDebugPoint: DebugPointAtBinding * + expr: SynExpr * + clauses: SynMatchClause list * + range: range + + /// F# syntax: do! expr + /// Computation expressions only + | DoBang of + expr: SynExpr * + range: range + + /// Only used in FSharp.Core + | LibraryOnlyILAssembly of + ilCode: obj * // this type is ILInstr[] but is hidden to avoid the representation of AbstractIL being public + typeArgs: SynType list * + args: SynExpr list * + retTy: SynType list * + range: range + + /// Only used in FSharp.Core + | LibraryOnlyStaticOptimization of + constraints: SynStaticOptimizationConstraint list * + expr: SynExpr * + optimizedExpr: SynExpr * + range: range + + /// Only used in FSharp.Core + | LibraryOnlyUnionCaseFieldGet of + expr: SynExpr * + longId: LongIdent * + fieldNum: int * + range: range + + /// Only used in FSharp.Core + | LibraryOnlyUnionCaseFieldSet of + expr: SynExpr * + longId: LongIdent * + fieldNum: int * + rhsExpr: SynExpr * + range: range + + /// Inserted for error recovery + | ArbitraryAfterError of + debugStr: string * + range: range + + /// Inserted for error recovery + | FromParseError of + expr: SynExpr * + range: range + + /// Inserted for error recovery when there is "expr." and missing tokens or error recovery after the dot + | DiscardAfterMissingQualificationAfterDot of + expr: SynExpr * + range: range + + /// 'use x = fixed expr' + | Fixed of + expr: SynExpr * + range: range + + /// F# syntax: interpolated string, e.g. "abc{x}" or "abc{x,3}" or "abc{x:N4}" + /// Note the string ranges include the quotes, verbatim markers, dollar sign and braces + | InterpolatedString of + contents: SynInterpolatedStringPart list * + synStringKind :SynStringKind * + range: range + + /// Gets the syntax range of this construct + member Range: range + + member RangeWithoutAnyExtraDot: range + + /// Attempt to get the range of the first token or initial portion only - this + /// is ad-hoc, just a cheap way to improve a certain 'query custom operation' error range + member RangeOfFirstPortion: range + + /// Indicates if this expression arises from error recovery + member IsArbExprAndThusAlreadyReportedError: bool + +[] +type SynInterpolatedStringPart = + | String of value: string * range: range + | FillExpr of fillExpr: SynExpr * qualifiers: Ident option + +/// Represents a syntax tree for simple F# patterns +[] +type SynSimplePat = + + /// Indicates a simple pattern variable. + /// + /// altNameRefCell: + /// Normally 'None' except for some compiler-generated variables in desugaring pattern matching. + /// Pattern processing sets this reference for hidden variable introduced + /// by desugaring pattern matching in arguments. The info indicates an + /// alternative (compiler generated) identifier to be used because the + /// name of the identifier is already bound. + /// + /// isCompilerGenerated: true if a compiler generated name + /// isThisVal: true if 'this' variable in member + /// isOptional: true if a '?' is in front of the name + | Id of + ident: Ident * + altNameRefCell: SynSimplePatAlternativeIdInfo ref option * + isCompilerGenerated: bool * + isThisVal: bool * + isOptional: bool * + range: range + + /// A type annotated simple pattern + | Typed of + pat: SynSimplePat * + targetType: SynType * + range: range + + /// An attributed simple pattern + | Attrib of + pat: SynSimplePat * + attributes: SynAttributes * + range: range + + member Range: range + +/// Represents the alternative identifier for a simple pattern +[] +type SynSimplePatAlternativeIdInfo = + + /// We have not decided to use an alternative name in the pattern and related expression + | Undecided of Ident + + /// We have decided to use an alternative name in the pattern and related expression + | Decided of Ident + +/// Represents a syntax tree for a static optimization constraint in the F# core library +[] +type SynStaticOptimizationConstraint = + + /// A static optimization conditional that activates for a particular type instantiation + | WhenTyparTyconEqualsTycon of + typar: SynTypar * + rhsType: SynType * + range: range + + /// A static optimization conditional that activates for a struct + | WhenTyparIsStruct of + typar: SynTypar * + range: range + +/// Represents a simple set of variable bindings a, (a, b) or (a: Type, b: Type) at a lambda, +/// function definition or other binding point, after the elimination of pattern matching +/// from the construct, e.g. after changing a "function pat1 -> rule1 | ..." to a +/// "fun v -> match v with ..." +[] +type SynSimplePats = + | SimplePats of + pats: SynSimplePat list * + range: range + + | Typed of + pats: SynSimplePats * + targetType: SynType * + range: range + + member Range: range + +/// Represents a syntax tree for arguments patterns +[] +type SynArgPats = + | Pats of + pats: SynPat list + + | NamePatPairs of + pats: (Ident * SynPat) list * + range: range + + member Patterns: SynPat list + +/// Represents a syntax tree for an F# pattern +[] +type SynPat = + + /// A constant in a pattern + | Const of + constant: SynConst * + range: range + + /// A wildcard '_' in a pattern + | Wild of + range: range + + /// A name pattern 'ident' + | Named of + ident: Ident * + isThisVal: bool * + accessibility: SynAccess option * + range: range + + /// A typed pattern 'pat : type' + | Typed of + pat: SynPat * + targetType: SynType * + range: range + + /// An attributed pattern, used in argument or declaration position + | Attrib of + pat: SynPat * + attributes: SynAttributes * + range: range + + /// A disjunctive pattern 'pat1 | pat2' + | Or of + lhsPat: SynPat * + rhsPat: SynPat * + range: range + + /// A conjunctive pattern 'pat1 & pat2' + | Ands of + pats: SynPat list * + range: range + + /// A conjunctive pattern 'pat1 as pat2' + | As of + lhsPat: SynPat * + rhsPat: SynPat * + range: range + + /// A long identifier pattern possibly with argument patterns + | LongIdent of + longDotId: LongIdentWithDots * + extraId: Ident option * // holds additional ident for tooling + typarDecls: SynValTyparDecls option * // usually None: temporary used to parse "f<'a> x = x" + argPats: SynArgPats * + accessibility: SynAccess option * + range: range + + /// A tuple pattern + | Tuple of + isStruct: bool * + elementPats: SynPat list * + range: range + + /// A parenthesized pattern + | Paren of + pat: SynPat * + range: range + + /// An array or a list as a pattern + | ArrayOrList of + isArray: bool * + elementPats: SynPat list * + range: range + + /// A record pattern + | Record of + fieldPats: ((LongIdent * Ident) * SynPat) list * + range: range + + /// The 'null' pattern + | Null of + range: range + + /// '?id' -- for optional argument names + | OptionalVal of + ident: Ident * + range: range + + /// A type test pattern ':? type ' + | IsInst of + pat: SynType * + range: range + + /// <@ expr @>, used for active pattern arguments + | QuoteExpr of + expr: SynExpr * + range: range + + /// Deprecated character range: ranges + | DeprecatedCharRange of + startChar: char * + endChar: char * + range: range + + /// Used internally in the type checker + | InstanceMember of + thisId: Ident * + memberId: Ident * + toolingId: Ident option * // holds additional ident for tooling + accessibility: SynAccess option * + range: range + + /// A pattern arising from a parse error + | FromParseError of + pat: SynPat * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a set of bindings that implement an interface +[] +type SynInterfaceImpl = + | SynInterfaceImpl of + interfaceTy: SynType * + bindings: SynBinding list * + range: range + +/// Represents a clause in a 'match' expression +[] +type SynMatchClause = + | SynMatchClause of + pat: SynPat * + whenExpr: SynExpr option * + arrow: Range option * + resultExpr: SynExpr * + range: range * + debugPoint: DebugPointAtTarget + + /// Gets the syntax range of part of this construct + member RangeOfGuardAndRhs: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents an attribute +[] +type SynAttribute = + { /// The name of the type for the attribute + TypeName: LongIdentWithDots + + /// The argument of the attribute, perhaps a tuple + ArgExpr: SynExpr + + /// Target specifier, e.g. "assembly", "module", etc. + Target: Ident option + + /// Is this attribute being applied to a property getter or setter? + AppliesToGetterAndSetter: bool + + /// The syntax range of the attribute + Range: range + } + +/// List of attributes enclosed in [< ... >]. +[] +type SynAttributeList = + { + /// The list of attributes + Attributes: SynAttribute list + + /// The syntax range of the list of attributes + Range: range + } + +type SynAttributes = SynAttributeList list + +/// Represents extra information about the declaration of a value +[] +type SynValData = + | SynValData of + memberFlags: SynMemberFlags option * + valInfo: SynValInfo * + thisIdOpt: Ident option + + member SynValInfo: SynValInfo + +/// Represents a binding for a 'let' or 'member' declaration +[] +type SynBinding = + | SynBinding of + accessibility: SynAccess option * + kind: SynBindingKind * + isInline: bool * + isMutable: bool * + attributes: SynAttributes * + xmlDoc: PreXmlDoc * + valData: SynValData * + headPat: SynPat * + returnInfo: SynBindingReturnInfo option * + expr: SynExpr * + range: range * + debugPoint: DebugPointAtBinding + + // no member just named "Range", as that would be confusing: + // - for everything else, the 'range' member that appears last/second-to-last is the 'full range' of the whole tree construct + // - but for Binding, the 'range' is only the range of the left-hand-side, the right-hand-side range is in the SynExpr + // - so we use explicit names to avoid confusion + member RangeOfBindingWithoutRhs: range + + member RangeOfBindingWithRhs: range + + member RangeOfHeadPattern: range + +/// Represents the return information in a binding for a 'let' or 'member' declaration +[] +type SynBindingReturnInfo = + | SynBindingReturnInfo of + typeName: SynType * + range: range * + attributes: SynAttributes + +/// Represents the flags for a 'member' declaration +[] +type SynMemberFlags = + { + /// The member is an instance member (non-static) + IsInstance: bool + + /// The member is a dispatch slot + IsDispatchSlot: bool + + /// The member is an 'override' or explicit interface implementation + IsOverrideOrExplicitImpl: bool + + /// The member is 'final' + IsFinal: bool + + /// The kind of the member + MemberKind: SynMemberKind + } + +/// Note the member kind is actually computed partially by a syntax tree transformation in tc.fs +[] +type SynMemberKind = + + /// The member is a class initializer + | ClassConstructor + + /// The member is a object model constructor + | Constructor + + /// The member kind is not yet determined + | Member + + /// The member kind is property getter + | PropertyGet + + /// The member kind is property setter + | PropertySet + + /// An artificial member kind used prior to the point where a + /// get/set property is split into two distinct members. + | PropertyGetSet + +/// Represents the syntax tree for a member signature (used in signature files, abstract member declarations +/// and member constraints) +[] +type SynMemberSig = + + /// A member definition in a type in a signature file + | Member of + memberSig: SynValSig * + flags: SynMemberFlags * + range: range + + /// An interface definition in a type in a signature file + | Interface of + interfaceType: SynType * + range: range + + /// An 'inherit' definition in a type in a signature file + | Inherit of + inheritedType: SynType * + range: range + + /// A 'val' definition in a type in a signature file + | ValField of + field: SynField * + range: range + + /// A nested type definition in a signature file (an unimplemented feature) + | NestedType of + nestedType: SynTypeDefnSig * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the kind of a type definition whether explicit or inferred +[] +type SynTypeDefnKind = + | Unspecified + | Class + | Interface + | Struct + | Record + | Union + | Abbrev + | Opaque + | Augmentation + | IL + | Delegate of signature: SynType * signatureInfo: SynValInfo + +/// Represents the syntax tree for the core of a simple type definition, in either signature +/// or implementation. +[] +type SynTypeDefnSimpleRepr = + + /// A union type definition, type X = A | B + | Union of + accessibility: SynAccess option * + unionCases: SynUnionCase list * + range: range + + /// An enum type definition, type X = A = 1 | B = 2 + | Enum of + cases: SynEnumCase list * + range: range + + /// A record type definition, type X = { A: int; B: int } + | Record of + accessibility: SynAccess option * + recordFields: SynField list * + range: range + + /// An object oriented type definition. This is not a parse-tree form, but represents the core + /// type representation which the type checker splits out from the "ObjectModel" cases of type definitions. + | General of + kind: SynTypeDefnKind * + inherits: (SynType * range * Ident option) list * + slotsigs: (SynValSig * SynMemberFlags) list * + fields: SynField list * + isConcrete: bool * + isIncrClass: bool * + implicitCtorSynPats: SynSimplePats option * + range: range + + /// A type defined by using an IL assembly representation. Only used in FSharp.Core. + /// + /// F# syntax: "type X = (# "..."#) + | LibraryOnlyILAssembly of + ilType: obj * // this type is ILType but is hidden to avoid the representation of AbstractIL being public + range: range + + /// A type abbreviation, "type X = A.B.C" + | TypeAbbrev of + detail: ParserDetail * + rhsType: SynType * + range: range + + /// An abstract definition, "type X" + | None of + range: range + + /// An exception definition, "exception E = ..." + | Exception of + exnRepr: SynExceptionDefnRepr + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for one case in an enum definition. +[] +type SynEnumCase = + + | SynEnumCase of + attributes: SynAttributes * + ident: Ident * + value: SynConst * + valueRange: range * + xmlDoc: PreXmlDoc * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for one case in a union definition. +[] +type SynUnionCase = + + | SynUnionCase of + attributes: SynAttributes * + ident: Ident * + caseType: SynUnionCaseKind * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for the right-hand-side of union definition, excluding members, +/// in either a signature or implementation. +[] +type SynUnionCaseKind = + + /// Normal style declaration + | Fields of + cases: SynField list + + /// Full type spec given by 'UnionCase: ty1 * tyN -> rty'. Only used in FSharp.Core, otherwise a warning. + | FullType of + fullType: SynType * + fullTypeInfo: SynValInfo + +/// Represents the syntax tree for the right-hand-side of a type definition in a signature. +/// Note: in practice, using a discriminated union to make a distinction between +/// "simple" types and "object oriented" types is not particularly useful. +[] +type SynTypeDefnSigRepr = + + /// Indicates the right right-hand-side is a class, struct, interface or other object-model type + | ObjectModel of + kind: SynTypeDefnKind * + memberSigs: SynMemberSig list * + range: range + + /// Indicates the right right-hand-side is a record, union or other simple type. + | Simple of + repr: SynTypeDefnSimpleRepr * + range: range + + | Exception of + repr: SynExceptionDefnRepr + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for a type definition in a signature +[] +type SynTypeDefnSig = + + /// The information for a type definition in a signature + | SynTypeDefnSig of + typeInfo: SynComponentInfo * + typeRepr: SynTypeDefnSigRepr * + members: SynMemberSig list * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for a field declaration in a record or class +[] +type SynField = + | SynField of + attributes: SynAttributes * + isStatic: bool * + idOpt: Ident option * + fieldType: SynType * + isMutable: bool * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + +/// Represents the syntax tree associated with the name of a type definition or module +/// in signature or implementation. +/// +/// This includes the name, attributes, type parameters, constraints, documentation and accessibility +/// for a type definition or module. For modules, entries such as the type parameters are +/// always empty. +[] +type SynComponentInfo = + | SynComponentInfo of + attributes: SynAttributes * + typeParams: SynTyparDecls option * + constraints: SynTypeConstraint list * + longId: LongIdent * + xmlDoc: PreXmlDoc * + preferPostfix: bool * + accessibility: SynAccess option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the syntax tree for a 'val' definition in an abstract slot or a signature file +[] +type SynValSig = + | SynValSig of + attributes: SynAttributes * + ident: Ident * + explicitValDecls: SynValTyparDecls * + synType: SynType * + arity: SynValInfo * + isInline: bool * + isMutable: bool * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + synExpr: SynExpr option * + range: range + + member RangeOfId: range + + member SynInfo: SynValInfo + + member SynType: SynType + +/// The argument names and other metadata for a member or function +[] +type SynValInfo = + + /// SynValInfo(curriedArgInfos, returnInfo) + | SynValInfo of curriedArgInfos: SynArgInfo list list * returnInfo: SynArgInfo + + member CurriedArgInfos: SynArgInfo list list + + member ArgNames: string list + +/// Represents the argument names and other metadata for a parameter for a member or function +[] +type SynArgInfo = + + | SynArgInfo of + attributes: SynAttributes * + optional: bool * + ident: Ident option + + member Ident: Ident option + + member Attributes: SynAttributes + +/// Represents the names and other metadata for the type parameters for a member or function +[] +type SynValTyparDecls = + | SynValTyparDecls of + typars: SynTyparDecls option * + canInfer: bool + +/// Represents the syntactic elements associated with the "return" of a function or method. +[] +type SynReturnInfo = + | SynReturnInfo of returnType: (SynType * SynArgInfo) * range: range + +/// Represents the right hand side of an exception declaration 'exception E = ... ' +[] +type SynExceptionDefnRepr = + + | SynExceptionDefnRepr of + attributes: SynAttributes * + caseName: SynUnionCase * + longId: LongIdent option * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the right hand side of an exception declaration 'exception E = ... ' plus +/// any member definitions for the exception +[] +type SynExceptionDefn = + + | SynExceptionDefn of + exnRepr: SynExceptionDefnRepr * + members: SynMemberDefns * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the right hand side of a type or exception declaration 'type C = ... ' plus +/// any additional member definitions for the type +[] +type SynTypeDefnRepr = + + /// An object model type definition (class or interface) + | ObjectModel of + kind: SynTypeDefnKind * + members: SynMemberDefns * + range: range + + /// A simple type definition (record, union, abbreviation) + | Simple of + simpleRepr: SynTypeDefnSimpleRepr * + range: range + + /// An exception definition + | Exception of + exnRepr: SynExceptionDefnRepr + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a type or exception declaration 'type C = ... ' plus +/// any additional member definitions for the type +[] +type SynTypeDefn = + | SynTypeDefn of + typeInfo: SynComponentInfo * + typeRepr: SynTypeDefnRepr * + members: SynMemberDefns * + implicitConstructor: SynMemberDefn option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a definition element within a type definition, e.g. 'member ... ' +[] +type SynMemberDefn = + + /// An 'open' definition within a type + | Open of + target: SynOpenDeclTarget * + range: range + + /// A 'member' definition within a type + | Member of + memberDefn: SynBinding * + range: range + + /// An implicit constructor definition + | ImplicitCtor of + accessibility: SynAccess option * + attributes: SynAttributes * + ctorArgs: SynSimplePats * + selfIdentifier: Ident option * + xmlDoc: PreXmlDoc * + range: range + + /// An implicit inherit definition, 'inherit (args...) as base' + | ImplicitInherit of + inheritType: SynType * + inheritArgs: SynExpr * + inheritAlias: Ident option * + range: range + + /// A 'let' definition within a class + | LetBindings of + bindings: SynBinding list * + isStatic: bool * + isRecursive: bool * + range: range + + /// An abstract slot definition within a class or interface + | AbstractSlot of + slotSig: SynValSig * + flags: SynMemberFlags * + range: range + + /// An interface implementation definition within a class + | Interface of + interfaceType: SynType * + members: SynMemberDefns option * + range: range + + /// An 'inherit' definition within a class + | Inherit of + baseType: SynType * + asIdent: Ident option * + range: range + + /// A 'val' definition within a class + | ValField of + fieldInfo: SynField * + range: range + + /// A nested type definition, a feature that is not implemented + | NestedType of + typeDefn: SynTypeDefn * + accessibility: SynAccess option * + range: range + + /// An auto-property definition, F# syntax: 'member val X = expr' + | AutoProperty of + attributes: SynAttributes * + isStatic: bool * + ident: Ident * + typeOpt: SynType option * + propKind: SynMemberKind * + memberFlags:(SynMemberKind -> SynMemberFlags) * + xmlDoc: PreXmlDoc * + accessibility: SynAccess option * + synExpr: SynExpr * + getSetRange: range option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +type SynMemberDefns = SynMemberDefn list + +/// Represents a definition within a module +[] +type SynModuleDecl = + + /// A module abbreviation definition 'module X = A.B.C' + | ModuleAbbrev of + ident: Ident * + longId: LongIdent * + range: range + + /// A nested module definition 'module X = ...' + | NestedModule of + moduleInfo: SynComponentInfo * + isRecursive: bool * + decls: SynModuleDecl list * + isContinuing: bool * + range: range + + /// A 'let' definition within a module + | Let of + isRecursive: bool * + bindings: SynBinding list * + range: range + + /// A 'do expr' within a module + | DoExpr of + debugPoint: DebugPointAtBinding * + expr: SynExpr * + range: range + + /// One or more 'type' definitions within a module + | Types of + typeDefns: SynTypeDefn list * + range: range + + /// An 'exception' definition within a module + | Exception of + exnDefn: SynExceptionDefn * + range: range + + /// An 'open' definition within a module + | Open of + target: SynOpenDeclTarget * + range: range + + /// An attribute definition within a module, for assembly and .NET module attributes + | Attributes of + attributes: SynAttributes * + range: range + + /// A hash directive within a module + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + + /// A namespace fragment within a module + | NamespaceFragment of + fragment: SynModuleOrNamespace + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the target of the open declaration +[] +type SynOpenDeclTarget = + + /// A 'open' declaration + | ModuleOrNamespace of longId: LongIdent * range: range + + /// A 'open type' declaration + | Type of typeName: SynType * range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the right hand side of an exception definition in a signature file +[] +type SynExceptionSig = + | SynExceptionSig of + exnRepr: SynExceptionDefnRepr * + members: SynMemberSig list * + range: range + +/// Represents a definition within a module or namespace in a signature file +[] +type SynModuleSigDecl = + + /// A module abbreviation definition within a module or namespace in a signature file + | ModuleAbbrev of + ident: Ident * + longId: LongIdent * + range: range + + /// A nested module definition within a module or namespace in a signature file + | NestedModule of + moduleInfo: SynComponentInfo * + isRecursive: bool * + moduleDecls: SynModuleSigDecl list * + range: range + + /// A 'val' definition within a module or namespace in a signature file, corresponding + /// to a 'let' definition in the implementation + | Val of + valSig: SynValSig * range: range + + /// A set of one or more type definitions within a module or namespace in a signature file + | Types of + types: SynTypeDefnSig list * + range: range + + /// An exception definition within a module or namespace in a signature file + | Exception of + exnSig: SynExceptionSig * + range: range + + /// An 'open' definition within a module or namespace in a signature file + | Open of + target: SynOpenDeclTarget * + range: range + + /// A hash directive within a module or namespace in a signature file + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + + /// A namespace fragment within a namespace in a signature file + | NamespaceFragment of + SynModuleOrNamespaceSig + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the kind of a module or namespace definition +[] +type SynModuleOrNamespaceKind = + /// A module is explicitly named 'module N' + | NamedModule + + /// A module is anonymously named, e.g. a script + | AnonModule + + /// A namespace is explicitly declared + | DeclaredNamespace + + /// A namespace is declared 'global' + | GlobalNamespace + + /// Indicates if this is a module definition + member IsModule: bool + +/// Represents the definition of a module or namespace +[] +type SynModuleOrNamespace = + | SynModuleOrNamespace of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleDecl list * + xmlDoc: PreXmlDoc * + attribs: SynAttributes * + accessibility: SynAccess option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the definition of a module or namespace in a signature file +[] +type SynModuleOrNamespaceSig = + | SynModuleOrNamespaceSig of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleSigDecl list * + xmlDoc: PreXmlDoc * + attribs: SynAttributes * + accessibility: SynAccess option * + range: range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a parsed hash directive argument +[] +type ParsedHashDirectiveArgument = + | String of value: string * stringKind: SynStringKind * range: Range + | SourceIdentifier of constant: string * value: string * range: Range + + /// Gets the syntax range of this construct + member Range: range + +/// Represents a parsed hash directive +[] +type ParsedHashDirective = + | ParsedHashDirective of + ident: string * + args: ParsedHashDirectiveArgument list * + range: range + +/// Represents the syntax tree for the contents of a parsed implementation file +[] +type ParsedImplFileFragment = + + /// An implementation file which is an anonymous module definition, e.g. a script + | AnonModule of + decls: SynModuleDecl list * + range: range + + /// An implementation file is a named module definition, 'module N' + | NamedModule of + namedModule: SynModuleOrNamespace + + /// An implementation file fragment which declares a namespace fragment + | NamespaceFragment of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleDecl list * + xmlDoc: PreXmlDoc * + attributes: SynAttributes * + range: range + +/// Represents the syntax tree for the contents of a parsed signature file +[] +type ParsedSigFileFragment = + + /// A signature file which is an anonymous module, e.g. the signature file for the final file in an application + | AnonModule of + decls: SynModuleSigDecl list * + range: range + + /// A signature file which is a module, 'module N' + | NamedModule of + namedModule: SynModuleOrNamespaceSig + + /// A signature file namespace fragment + | NamespaceFragment of + longId: LongIdent * + isRecursive: bool * + kind: SynModuleOrNamespaceKind * + decls: SynModuleSigDecl list * + xmlDoc: PreXmlDoc * + attributes: SynAttributes * + range: range + +/// Represents a parsed syntax tree for an F# Interactive interaction +[] +type ParsedScriptInteraction = + | Definitions of + defns: SynModuleDecl list * + range: range + + | HashDirective of + hashDirective: ParsedHashDirective * + range: range + +/// Represents a parsed implementation file made up of fragments +[] +type ParsedImplFile = + | ParsedImplFile of + hashDirectives: ParsedHashDirective list * + fragments: ParsedImplFileFragment list + +/// Represents a parsed signature file made up of fragments +[] +type ParsedSigFile = + | ParsedSigFile of + hashDirectives: ParsedHashDirective list * + fragments: ParsedSigFileFragment list + +/// Represents a scoped pragma +[] +type ScopedPragma = + /// A pragma to turn a warning off + | WarningOff of range: range * warningNumber: int + +/// Represents a qualifying name for anonymous module specifications and implementations, +[] +type QualifiedNameOfFile = + | QualifiedNameOfFile of Ident + + /// The name of the file + member Text: string + + /// The identifier for the name of the file + member Id: Ident + + /// Gets the syntax range of this construct + member Range: range + +/// Represents the full syntax tree, file name and other parsing information for an implementation file +[] +type ParsedImplFileInput = + | ParsedImplFileInput of + fileName: string * + isScript: bool * + qualifiedNameOfFile: QualifiedNameOfFile * + scopedPragmas: ScopedPragma list * + hashDirectives: ParsedHashDirective list * + modules: SynModuleOrNamespace list * + isLastCompiland: (bool * bool) + +/// Represents the full syntax tree, file name and other parsing information for a signature file +[] +type ParsedSigFileInput = + | ParsedSigFileInput of + fileName: string * + qualifiedNameOfFile: QualifiedNameOfFile * + scopedPragmas: ScopedPragma list * + hashDirectives: ParsedHashDirective list * + modules: SynModuleOrNamespaceSig list + +/// Represents the syntax tree for a parsed implementation or signature file +[] +type ParsedInput = + /// A parsed implementation file + | ImplFile of ParsedImplFileInput + + /// A parsed signature file + | SigFile of ParsedSigFileInput + + /// Gets the file name for the parsed input + member FileName: string + + /// Gets the syntax range of this construct + member Range: range diff --git a/src/fsharp/SyntaxTreeOps.fs b/src/fsharp/SyntaxTreeOps.fs new file mode 100644 index 00000000000..207a122ed9c --- /dev/null +++ b/src/fsharp/SyntaxTreeOps.fs @@ -0,0 +1,791 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module FSharp.Compiler.SyntaxTreeOps + +open Internal.Utilities.Library +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml + +/// Generate implicit argument names in parsing +type SynArgNameGenerator() = + let mutable count = 0 + let generatedArgNamePrefix = "_arg" + + member _.New() : string = count <- count + 1; generatedArgNamePrefix + string count + member _.Reset() = count <- 0 + +let ident (s, r) = Ident(s, r) + +let textOfId (id: Ident) = id.idText + +let pathOfLid lid = List.map textOfId lid + +let arrPathOfLid lid = Array.ofList (pathOfLid lid) + +let textOfPath path = String.concat "." path + +let textOfLid lid = textOfPath (pathOfLid lid) + +let rangeOfLid (lid: Ident list) = + match lid with + | [] -> failwith "rangeOfLid" + | [id] -> id.idRange + | h :: t -> unionRanges h.idRange (List.last t).idRange + +let mkSynId m s = Ident(s, m) + +let pathToSynLid m p = List.map (mkSynId m) p + +let mkSynIdGet m n = SynExpr.Ident (mkSynId m n) + +let mkSynLidGet m path n = + let lid = pathToSynLid m path @ [mkSynId m n] + let dots = List.replicate (lid.Length - 1) m + SynExpr.LongIdent (false, LongIdentWithDots(lid, dots), None, m) + +let mkSynIdGetWithAlt m id altInfo = + match altInfo with + | None -> SynExpr.Ident id + | _ -> SynExpr.LongIdent (false, LongIdentWithDots([id], []), altInfo, m) + +let mkSynSimplePatVar isOpt id = SynSimplePat.Id (id, None, false, false, isOpt, id.idRange) + +let mkSynCompGenSimplePatVar id = SynSimplePat.Id (id, None, true, false, false, id.idRange) + +/// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree. +let (|LongOrSingleIdent|_|) inp = + match inp with + | SynExpr.LongIdent (isOpt, lidwd, altId, _m) -> Some (isOpt, lidwd, altId, lidwd.RangeWithoutAnyExtraDot) + | SynExpr.Ident id -> Some (false, LongIdentWithDots([id], []), None, id.idRange) + | _ -> None + +let (|SingleIdent|_|) inp = + match inp with + | SynExpr.LongIdent (false, LongIdentWithDots([id], _), None, _) -> Some id + | SynExpr.Ident id -> Some id + | _ -> None + +/// This affects placement of sequence points +let rec IsControlFlowExpression e = + match e with + | SynExpr.ObjExpr _ + | SynExpr.Lambda _ + | SynExpr.LetOrUse _ + | SynExpr.Sequential _ + // Treat "ident { ... }" as a control flow expression + | SynExpr.App (_, _, SynExpr.Ident _, SynExpr.ComputationExpr _, _) + | SynExpr.IfThenElse _ + | SynExpr.LetOrUseBang _ + | SynExpr.Match _ + | SynExpr.TryWith _ + | SynExpr.TryFinally _ + | SynExpr.For _ + | SynExpr.ForEach _ + | SynExpr.While _ -> true + | SynExpr.Typed (e, _, _) -> IsControlFlowExpression e + | _ -> false + +let mkSynAnonField (ty: SynType) = SynField([], false, None, ty, false, PreXmlDoc.Empty, None, ty.Range) + +let mkSynNamedField (ident, ty: SynType, m) = SynField([], false, Some ident, ty, false, PreXmlDoc.Empty, None, m) + +let mkSynPatVar vis (id: Ident) = SynPat.Named (id, false, vis, id.idRange) + +let mkSynThisPatVar (id: Ident) = SynPat.Named (id, true, None, id.idRange) + +let mkSynPatMaybeVar lidwd vis m = SynPat.LongIdent (lidwd, None, None, SynArgPats.Pats [], vis, m) + +/// Extract the argument for patterns corresponding to the declaration of 'new ... = ...' +let (|SynPatForConstructorDecl|_|) x = + match x with + | SynPat.LongIdent (LongIdentWithDots([_], _), _, _, SynArgPats.Pats [arg], _, _) -> Some arg + | _ -> None + +/// Recognize the '()' in 'new()' +let (|SynPatForNullaryArgs|_|) x = + match x with + | SynPat.Paren(SynPat.Const(SynConst.Unit, _), _) -> Some() + | _ -> None + +let (|SynExprErrorSkip|) (p: SynExpr) = + match p with + | SynExpr.FromParseError (p, _) -> p + | _ -> p + +let (|SynExprParen|_|) (e: SynExpr) = + match e with + | SynExpr.Paren (SynExprErrorSkip e, a, b, c) -> Some (e, a, b, c) + | _ -> None + +let (|SynPatErrorSkip|) (p: SynPat) = + match p with + | SynPat.FromParseError(p, _) -> p + | _ -> p + +/// Push non-simple parts of a patten match over onto the r.h.s. of a lambda. +/// Return a simple pattern and a function to build a match on the r.h.s. if the pattern is complex +let rec SimplePatOfPat (synArgNameGenerator: SynArgNameGenerator) p = + match p with + | SynPat.Typed(p', ty, m) -> + let p2, laterF = SimplePatOfPat synArgNameGenerator p' + SynSimplePat.Typed(p2, ty, m), + laterF + + | SynPat.Attrib(p', attribs, m) -> + let p2, laterF = SimplePatOfPat synArgNameGenerator p' + SynSimplePat.Attrib(p2, attribs, m), + laterF + + | SynPat.Named (v, thisV, _, m) -> + SynSimplePat.Id (v, None, false, thisV, false, m), + None + + | SynPat.OptionalVal (v, m) -> + SynSimplePat.Id (v, None, false, false, true, m), + None + + | SynPat.Paren (p, _) -> SimplePatOfPat synArgNameGenerator p + + | SynPat.FromParseError (p, _) -> SimplePatOfPat synArgNameGenerator p + + | _ -> + let m = p.Range + let isCompGen, altNameRefCell, id, item = + match p with + | SynPat.LongIdent(LongIdentWithDots([id], _), _, None, SynArgPats.Pats [], None, _) -> + // The pattern is 'V' or some other capitalized identifier. + // It may be a real variable, in which case we want to maintain its name. + // But it may also be a nullary union case or some other identifier. + // In this case, we want to use an alternate compiler generated name for the hidden variable. + let altNameRefCell = Some (ref (SynSimplePatAlternativeIdInfo.Undecided (mkSynId m (synArgNameGenerator.New())))) + let item = mkSynIdGetWithAlt m id altNameRefCell + false, altNameRefCell, id, item + | SynPat.Named(ident, _, _, _) + | SynPat.As(_, SynPat.Named(ident, _, _, _), _) -> + // named pats should be referred to as their name in docs, tooltips, etc. + let item = mkSynIdGet m ident.idText + false, None, ident, item + | _ -> + let nm = synArgNameGenerator.New() + let id = mkSynId m nm + let item = mkSynIdGet m nm + true, None, id, item + let fn = + match p with + | SynPat.Wild _ -> None + | _ -> + Some (fun e -> + let clause = SynMatchClause(p, None, None, e, m, DebugPointAtTarget.No) + let artificialMatchRange = (unionRanges m e.Range).MakeSynthetic() + SynExpr.Match (DebugPointAtBinding.NoneAtInvisible, item, [clause], artificialMatchRange)) + + SynSimplePat.Id (id, altNameRefCell, isCompGen, false, false, id.idRange), fn + +let appFunOpt funOpt x = match funOpt with None -> x | Some f -> f x + +let composeFunOpt funOpt1 funOpt2 = match funOpt2 with None -> funOpt1 | Some f -> Some (fun x -> appFunOpt funOpt1 (f x)) + +let rec SimplePatsOfPat synArgNameGenerator p = + match p with + | SynPat.FromParseError (p, _) -> SimplePatsOfPat synArgNameGenerator p + + | SynPat.Typed(p', ty, m) -> + let p2, laterF = SimplePatsOfPat synArgNameGenerator p' + SynSimplePats.Typed(p2, ty, m), + laterF + + | SynPat.Tuple (false, ps, m) + + | SynPat.Paren(SynPat.Tuple (false, ps, _), m) -> + let ps2, laterF = + List.foldBack + (fun (p', rhsf) (ps', rhsf') -> + p':: ps', + (composeFunOpt rhsf rhsf')) + (List.map (SimplePatOfPat synArgNameGenerator) ps) + ([], None) + SynSimplePats.SimplePats (ps2, m), + laterF + + | SynPat.Paren(SynPat.Const (SynConst.Unit, m), _) + + | SynPat.Const (SynConst.Unit, m) -> + SynSimplePats.SimplePats ([], m), + None + + | _ -> + let m = p.Range + let sp, laterF = SimplePatOfPat synArgNameGenerator p + SynSimplePats.SimplePats ([sp], m), laterF + +let PushPatternToExpr synArgNameGenerator isMember pat (rhs: SynExpr) = + let nowPats, laterF = SimplePatsOfPat synArgNameGenerator pat + nowPats, SynExpr.Lambda (isMember, false, nowPats, None, appFunOpt laterF rhs, None, rhs.Range) + +let private isSimplePattern pat = + let _nowPats, laterF = SimplePatsOfPat (SynArgNameGenerator()) pat + Option.isNone laterF + +/// "fun (UnionCase x) (UnionCase y) -> body" +/// ==> +/// "fun tmp1 tmp2 -> +/// let (UnionCase x) = tmp1 in +/// let (UnionCase y) = tmp2 in +/// body" +let PushCurriedPatternsToExpr synArgNameGenerator wholem isMember pats arrow rhs = + // Two phases + // First phase: Fold back, from right to left, pushing patterns into r.h.s. expr + let spatsl, rhs = + (pats, ([], rhs)) + ||> List.foldBack (fun arg (spatsl, body) -> + let spats, bodyf = SimplePatsOfPat synArgNameGenerator arg + // accumulate the body. This builds "let (UnionCase y) = tmp2 in body" + let body = appFunOpt bodyf body + // accumulate the patterns + let spatsl = spats :: spatsl + (spatsl, body)) + // Second phase: build lambdas. Mark subsequent ones with "true" indicating they are part of an iterated sequence of lambdas + let expr = + match spatsl with + | [] -> rhs + | h :: t -> + let expr = List.foldBack (fun spats e -> SynExpr.Lambda (isMember, true, spats, arrow, e, None, wholem)) t rhs + let expr = SynExpr.Lambda (isMember, false, h, arrow, expr, Some (pats, rhs), wholem) + expr + spatsl, expr + +let opNameParenGet = CompileOpName parenGet + +let opNameQMark = CompileOpName qmark + +let mkSynOperator opm oper = mkSynIdGet opm (CompileOpName oper) + +let mkSynInfix opm (l: SynExpr) oper (r: SynExpr) = + let firstTwoRange = unionRanges l.Range opm + let wholeRange = unionRanges l.Range r.Range + let app1 = SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator opm oper, l, firstTwoRange) + SynExpr.App (ExprAtomicFlag.NonAtomic, false, app1, r, wholeRange) + +let mkSynBifix m oper x1 x2 = + let app1 = SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator m oper, x1, m) + SynExpr.App (ExprAtomicFlag.NonAtomic, false, app1, x2, m) + +let mkSynTrifix m oper x1 x2 x3 = + let app1 = SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator m oper, x1, m) + let app2 = SynExpr.App (ExprAtomicFlag.NonAtomic, false, app1, x2, m) + SynExpr.App (ExprAtomicFlag.NonAtomic, false, app2, x3, m) + +let mkSynPrefixPrim opm m oper x = + SynExpr.App (ExprAtomicFlag.NonAtomic, false, mkSynOperator opm oper, x, m) + +let mkSynPrefix opm m oper x = + if oper = "~&" then + SynExpr.AddressOf (true, x, opm, m) + elif oper = "~&&" then + SynExpr.AddressOf (false, x, opm, m) + else + mkSynPrefixPrim opm m oper x + +let mkSynCaseName m n = [mkSynId m (CompileOpName n)] + +let mkSynApp1 f x1 m = SynExpr.App (ExprAtomicFlag.NonAtomic, false, f, x1, m) + +let mkSynApp2 f x1 x2 m = mkSynApp1 (mkSynApp1 f x1 m) x2 m + +let mkSynApp3 f x1 x2 x3 m = mkSynApp1 (mkSynApp2 f x1 x2 m) x3 m + +let mkSynApp4 f x1 x2 x3 x4 m = mkSynApp1 (mkSynApp3 f x1 x2 x3 m) x4 m + +let mkSynApp5 f x1 x2 x3 x4 x5 m = mkSynApp1 (mkSynApp4 f x1 x2 x3 x4 m) x5 m + +let mkSynDotParenSet m a b c = mkSynTrifix m parenSet a b c + +let mkSynDotBrackGet m mDot a b = SynExpr.DotIndexedGet (a, b, mDot, m) + +let mkSynQMarkSet m a b c = mkSynTrifix m qmarkSet a b c + +let mkSynDotParenGet lhsm dotm a b = + match b with + | SynExpr.Tuple (false, [_;_], _, _) -> + errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(), lhsm)) + SynExpr.Const (SynConst.Unit, lhsm) + + | SynExpr.Tuple (false, [_;_;_], _, _) -> + errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(), lhsm)) + SynExpr.Const (SynConst.Unit, lhsm) + + | _ -> mkSynInfix dotm a parenGet b + +let mkSynUnit m = SynExpr.Const (SynConst.Unit, m) + +let mkSynUnitPat m = SynPat.Const(SynConst.Unit, m) + +let mkSynDelay m e = + SynExpr.Lambda (false, false, SynSimplePats.SimplePats ([mkSynCompGenSimplePatVar (mkSynId m "unitVar")], m), None, e, None, m) + +let mkSynAssign (l: SynExpr) (r: SynExpr) = + let m = unionRanges l.Range r.Range + match l with + //| SynExpr.Paren (l2, m2) -> mkSynAssign m l2 r + | LongOrSingleIdent(false, v, None, _) -> SynExpr.LongIdentSet (v, r, m) + | SynExpr.DotGet (e, _, v, _) -> SynExpr.DotSet (e, v, r, m) + | SynExpr.DotIndexedGet (e1, e2, mDot, mLeft) -> SynExpr.DotIndexedSet (e1, e2, r, mLeft, mDot, m) + | SynExpr.LibraryOnlyUnionCaseFieldGet (x, y, z, _) -> SynExpr.LibraryOnlyUnionCaseFieldSet (x, y, z, r, m) + | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent nm, a, _), b, _) when nm.idText = opNameQMark -> + mkSynQMarkSet m a b r + | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent nm, a, _), b, _) when nm.idText = opNameParenGet -> + mkSynDotParenSet m a b r + | SynExpr.App (_, _, SynExpr.LongIdent (false, v, None, _), x, _) -> SynExpr.NamedIndexedPropertySet (v, x, r, m) + | SynExpr.App (_, _, SynExpr.DotGet (e, _, v, _), x, _) -> SynExpr.DotNamedIndexedPropertySet (e, v, x, r, m) + | l -> SynExpr.Set (l, r, m) + +let mkSynDot dotm m l r = + match l with + | SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots), None, _) -> + // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) + SynExpr.LongIdent (isOpt, LongIdentWithDots(lid@[r], dots@[dotm]), None, m) + | SynExpr.Ident id -> + SynExpr.LongIdent (false, LongIdentWithDots([id;r], [dotm]), None, m) + | SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots), _) -> + // REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) + SynExpr.DotGet (e, dm, LongIdentWithDots(lid@[r], dots@[dotm]), m) + | expr -> + SynExpr.DotGet (expr, dotm, LongIdentWithDots([r], []), m) + +let mkSynDotMissing dotm m l = + match l with + | SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots), None, _) -> + // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) + SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots@[dotm]), None, m) + | SynExpr.Ident id -> + SynExpr.LongIdent (false, LongIdentWithDots([id], [dotm]), None, m) + | SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots), _) -> + SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots@[dotm]), m)// REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) + | expr -> + SynExpr.DiscardAfterMissingQualificationAfterDot (expr, m) + +let mkSynFunMatchLambdas synArgNameGenerator isMember wholem ps arrow e = + let _, e = PushCurriedPatternsToExpr synArgNameGenerator wholem isMember ps arrow e + e + +let arbExpr (debugStr, range: range) = SynExpr.ArbitraryAfterError (debugStr, range.MakeSynthetic()) + +let unionRangeWithListBy projectRangeFromThing m listOfThing = + (m, listOfThing) ||> List.fold (fun m thing -> unionRanges m (projectRangeFromThing thing)) + +let mkAttributeList attrs range : SynAttributeList list = + [{ Attributes = attrs + Range = range }] + +let ConcatAttributesLists (attrsLists: SynAttributeList list) = + attrsLists + |> List.map (fun x -> x.Attributes) + |> List.concat + +let (|Attributes|) synAttributes = + ConcatAttributesLists synAttributes + +let (|TyparDecls|) (typarDecls: SynTyparDecls option) = + typarDecls + |> Option.map (fun x -> x.TyparDecls) + |> Option.defaultValue [] + +let (|TyparsAndConstraints|) (typarDecls: SynTyparDecls option) = + typarDecls + |> Option.map (fun x -> x.TyparDecls, x.Constraints) + |> Option.defaultValue ([], []) + +let (|ValTyparDecls|) (SynValTyparDecls(typarDecls, canInfer)) = + typarDecls + |> Option.map (fun x -> x.TyparDecls, x.Constraints, canInfer) + |> Option.defaultValue ([], [], canInfer) + +let rangeOfNonNilAttrs (attrs: SynAttributes) = + (attrs.Head.Range, attrs.Tail) ||> unionRangeWithListBy (fun a -> a.Range) + +let rec stripParenTypes synType = + match synType with + | SynType.Paren (innerType, _) -> stripParenTypes innerType + | _ -> synType + +let (|StripParenTypes|) synType = + stripParenTypes synType + +/// Operations related to the syntactic analysis of arguments of value, function and member definitions and signatures. +module SynInfo = + + /// The argument information for an argument without a name + let unnamedTopArg1 = SynArgInfo([], false, None) + + /// The argument information for a curried argument without a name + let unnamedTopArg = [unnamedTopArg1] + + /// The argument information for a '()' argument + let unitArgData = unnamedTopArg + + /// The 'argument' information for a return value where no attributes are given for the return value (the normal case) + let unnamedRetVal = SynArgInfo([], false, None) + + /// The 'argument' information for the 'this'/'self' parameter in the cases where it is not given explicitly + let selfMetadata = unnamedTopArg + + /// Determine if a syntactic information represents a member without arguments (which is implicitly a property getter) + let HasNoArgs (SynValInfo(args, _)) = isNil args + + /// Check if one particular argument is an optional argument. Used when adjusting the + /// types of optional arguments for function and member signatures. + let IsOptionalArg (SynArgInfo(_, isOpt, _)) = isOpt + + /// Check if there are any optional arguments in the syntactic argument information. Used when adjusting the + /// types of optional arguments for function and member signatures. + let HasOptionalArgs (SynValInfo(args, _)) = List.exists (List.exists IsOptionalArg) args + + /// Add a parameter entry to the syntactic value information to represent the '()' argument to a property getter. This is + /// used for the implicit '()' argument in property getter signature specifications. + let IncorporateEmptyTupledArgForPropertyGetter (SynValInfo(args, retInfo)) = SynValInfo([] :: args, retInfo) + + /// Add a parameter entry to the syntactic value information to represent the 'this' argument. This is + /// used for the implicit 'this' argument in member signature specifications. + let IncorporateSelfArg (SynValInfo(args, retInfo)) = SynValInfo(selfMetadata :: args, retInfo) + + /// Add a parameter entry to the syntactic value information to represent the value argument for a property setter. This is + /// used for the implicit value argument in property setter signature specifications. + let IncorporateSetterArg (SynValInfo(args, retInfo)) = + let args = + match args with + | [] -> [unnamedTopArg] + | [arg] -> [arg@[unnamedTopArg1]] + | _ -> failwith "invalid setter type" + SynValInfo(args, retInfo) + + /// Get the argument counts for each curried argument group. Used in some adhoc places in tc.fs. + let AritiesOfArgs (SynValInfo(args, _)) = List.map List.length args + + /// Get the argument attributes from the syntactic information for an argument. + let AttribsOfArgData (SynArgInfo(Attributes attribs, _, _)) = attribs + + /// Infer the syntactic argument info for a single argument from a simple pattern. + let rec InferSynArgInfoFromSimplePat attribs p = + match p with + | SynSimplePat.Id(nm, _, isCompGen, _, isOpt, _) -> + SynArgInfo(attribs, isOpt, (if isCompGen then None else Some nm)) + | SynSimplePat.Typed(a, _, _) -> InferSynArgInfoFromSimplePat attribs a + | SynSimplePat.Attrib(a, attribs2, _) -> InferSynArgInfoFromSimplePat (attribs @ attribs2) a + + /// Infer the syntactic argument info for one or more arguments one or more simple patterns. + let rec InferSynArgInfoFromSimplePats x = + match x with + | SynSimplePats.SimplePats(ps, _) -> List.map (InferSynArgInfoFromSimplePat []) ps + | SynSimplePats.Typed(ps, _, _) -> InferSynArgInfoFromSimplePats ps + + /// Infer the syntactic argument info for one or more arguments a pattern. + let InferSynArgInfoFromPat p = + // It is ok to use a fresh SynArgNameGenerator here, because compiler generated names are filtered from SynArgInfo, see InferSynArgInfoFromSimplePat above + let sp, _ = SimplePatsOfPat (SynArgNameGenerator()) p + InferSynArgInfoFromSimplePats sp + + /// Make sure only a solitary unit argument has unit elimination + let AdjustArgsForUnitElimination infosForArgs = + match infosForArgs with + | [[]] -> infosForArgs + | _ -> infosForArgs |> List.map (function [] -> unitArgData | x -> x) + + /// Transform a property declared using '[static] member P = expr' to a method taking a "unit" argument. + /// This is similar to IncorporateEmptyTupledArgForPropertyGetter, but applies to member definitions + /// rather than member signatures. + let AdjustMemberArgs memFlags infosForArgs = + match infosForArgs with + | [] when memFlags = SynMemberKind.Member -> [] :: infosForArgs + | _ -> infosForArgs + + /// For 'let' definitions, we infer syntactic argument information from the r.h.s. of a definition, if it + /// is an immediate 'fun ... -> ...' or 'function ...' expression. This is noted in the F# language specification. + /// This does not apply to member definitions nor to returns with attributes + let InferLambdaArgs (retInfo: SynArgInfo) origRhsExpr = + if retInfo.Attributes.Length > 0 then [] else + let rec loop e = + match e with + | SynExpr.Lambda (false, _, spats, _, rest, _, _) -> + InferSynArgInfoFromSimplePats spats :: loop rest + | _ -> [] + loop origRhsExpr + + let InferSynReturnData (retInfo: SynReturnInfo option) = + match retInfo with + | None -> unnamedRetVal + | Some(SynReturnInfo((_, retInfo), _)) -> retInfo + + let private emptySynValInfo = SynValInfo([], unnamedRetVal) + + let emptySynValData = SynValData(None, emptySynValInfo, None) + + /// Infer the syntactic information for a 'let' or 'member' definition, based on the argument pattern, + /// any declared return information (e.g. .NET attributes on the return element), and the r.h.s. expression + /// in the case of 'let' definitions. + let InferSynValData (memberFlagsOpt: SynMemberFlags option, pat, retInfo, origRhsExpr) = + + let infosForExplicitArgs = + match pat with + | Some(SynPat.LongIdent(_, _, _, SynArgPats.Pats curriedArgs, _, _)) -> List.map InferSynArgInfoFromPat curriedArgs + | _ -> [] + + let explicitArgsAreSimple = + match pat with + | Some(SynPat.LongIdent(_, _, _, SynArgPats.Pats curriedArgs, _, _)) -> List.forall isSimplePattern curriedArgs + | _ -> true + + let retInfo = InferSynReturnData retInfo + + match memberFlagsOpt with + | None -> + let infosForLambdaArgs = InferLambdaArgs retInfo origRhsExpr + let infosForArgs = infosForExplicitArgs @ (if explicitArgsAreSimple then infosForLambdaArgs else []) + let infosForArgs = AdjustArgsForUnitElimination infosForArgs + SynValData(None, SynValInfo(infosForArgs, retInfo), None) + + | Some memFlags -> + let infosForObjArgs = + if memFlags.IsInstance then [ selfMetadata ] else [] + + let infosForArgs = AdjustMemberArgs memFlags.MemberKind infosForExplicitArgs + let infosForArgs = AdjustArgsForUnitElimination infosForArgs + + let argInfos = infosForObjArgs @ infosForArgs + SynValData(Some memFlags, SynValInfo(argInfos, retInfo), None) + +let mkSynBindingRhs staticOptimizations rhsExpr mRhs retInfo = + let rhsExpr = List.foldBack (fun (c, e1) e2 -> SynExpr.LibraryOnlyStaticOptimization (c, e1, e2, mRhs)) staticOptimizations rhsExpr + let rhsExpr, retTyOpt = + match retInfo with + | Some (SynReturnInfo((ty, SynArgInfo(rAttribs, _, _)), tym)) -> + SynExpr.Typed (rhsExpr, ty, rhsExpr.Range), Some(SynBindingReturnInfo(ty, tym, rAttribs) ) + | None -> rhsExpr, None + rhsExpr, retTyOpt + +let mkSynBinding (xmlDoc, headPat) (vis, isInline, isMutable, mBind, spBind, retInfo, origRhsExpr, mRhs, staticOptimizations, attrs, memberFlagsOpt) = + let info = SynInfo.InferSynValData (memberFlagsOpt, Some headPat, retInfo, origRhsExpr) + let rhsExpr, retTyOpt = mkSynBindingRhs staticOptimizations origRhsExpr mRhs retInfo + SynBinding (vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDoc, info, headPat, retTyOpt, rhsExpr, mBind, spBind) + +let NonVirtualMemberFlags k : SynMemberFlags = + { MemberKind=k + IsInstance=true + IsDispatchSlot=false + IsOverrideOrExplicitImpl=false + IsFinal=false } + +let CtorMemberFlags : SynMemberFlags = + { MemberKind=SynMemberKind.Constructor + IsInstance=false + IsDispatchSlot=false + IsOverrideOrExplicitImpl=false + IsFinal=false } + +let ClassCtorMemberFlags : SynMemberFlags = + { MemberKind=SynMemberKind.ClassConstructor + IsInstance=false + IsDispatchSlot=false + IsOverrideOrExplicitImpl=false + IsFinal=false } + +let OverrideMemberFlags k : SynMemberFlags = + { MemberKind=k + IsInstance=true + IsDispatchSlot=false + IsOverrideOrExplicitImpl=true + IsFinal=false } + +let AbstractMemberFlags k : SynMemberFlags = + { MemberKind=k + IsInstance=true + IsDispatchSlot=true + IsOverrideOrExplicitImpl=false + IsFinal=false } + +let StaticMemberFlags k : SynMemberFlags = + { MemberKind=k + IsInstance=false + IsDispatchSlot=false + IsOverrideOrExplicitImpl=false + IsFinal=false } + +let inferredTyparDecls = SynValTyparDecls(None, true) + +let noInferredTypars = SynValTyparDecls(None, false) + +let rec synExprContainsError inpExpr = + let rec walkBind (SynBinding(_, _, _, _, _, _, _, _, _, synExpr, _, _)) = walkExpr synExpr + + and walkExprs es = es |> List.exists walkExpr + + and walkBinds es = es |> List.exists walkBind + + and walkMatchClauses cl = + cl |> List.exists (fun (SynMatchClause(_, whenExpr, _, e, _, _)) -> walkExprOpt whenExpr || walkExpr e) + + and walkExprOpt eOpt = eOpt |> Option.exists walkExpr + + and walkExpr e = + match e with + | SynExpr.FromParseError _ + | SynExpr.DiscardAfterMissingQualificationAfterDot _ + | SynExpr.ArbitraryAfterError _ -> true + + | SynExpr.LongIdent _ + | SynExpr.Quote _ + | SynExpr.LibraryOnlyILAssembly _ + | SynExpr.LibraryOnlyStaticOptimization _ + | SynExpr.Null _ + | SynExpr.Ident _ + | SynExpr.ImplicitZero _ + | SynExpr.Const _ -> false + + | SynExpr.TypeTest (e, _, _) + | SynExpr.Upcast (e, _, _) + | SynExpr.AddressOf (_, e, _, _) + | SynExpr.ComputationExpr (_, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) + | SynExpr.Typed (e, _, _) + | SynExpr.FromParseError (e, _) + | SynExpr.Do (e, _) + | SynExpr.Assert (e, _) + | SynExpr.DotGet (e, _, _, _) + | SynExpr.LongIdentSet (_, e, _) + | SynExpr.New (_, _, e, _) + | SynExpr.TypeApp (e, _, _, _, _, _, _) + | SynExpr.LibraryOnlyUnionCaseFieldGet (e, _, _, _) + | SynExpr.Downcast (e, _, _) + | SynExpr.InferredUpcast (e, _) + | SynExpr.InferredDowncast (e, _) + | SynExpr.Lazy (e, _) + | SynExpr.TraitCall (_, _, e, _) + | SynExpr.YieldOrReturn (_, e, _) + | SynExpr.YieldOrReturnFrom (_, e, _) + | SynExpr.DoBang (e, _) + | SynExpr.Fixed (e, _) + | SynExpr.Paren (e, _, _, _) -> + walkExpr e + + | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) + | SynExpr.DotSet (e1, _, e2, _) + | SynExpr.Set (e1, e2, _) + | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, _, _, e2, _) + | SynExpr.JoinIn (e1, _, e2, _) + | SynExpr.App (_, _, e1, e2, _) -> + walkExpr e1 || walkExpr e2 + + | SynExpr.ArrayOrList (_, es, _) + | SynExpr.Tuple (_, es, _, _) -> + walkExprs es + + | SynExpr.AnonRecd (_, origExpr, flds, _) -> + (match origExpr with Some (e, _) -> walkExpr e | None -> false) || + walkExprs (List.map snd flds) + + | SynExpr.Record (_, origExpr, fs, _) -> + (match origExpr with Some (e, _) -> walkExpr e | None -> false) || + let flds = fs |> List.choose (fun (_, v, _) -> v) + walkExprs flds + + | SynExpr.ObjExpr (_, _, bs, is, _, _) -> + walkBinds bs || walkBinds [ for SynInterfaceImpl(_, bs, _) in is do yield! bs ] + + | SynExpr.ForEach (_, _, _, _, e1, e2, _) + | SynExpr.While (_, e1, e2, _) -> + walkExpr e1 || walkExpr e2 + + | SynExpr.For (_, _, e1, _, e2, e3, _) -> + walkExpr e1 || walkExpr e2 || walkExpr e3 + + | SynExpr.MatchLambda (_, _, cl, _, _) -> + walkMatchClauses cl + + | SynExpr.Lambda (body = e) -> + walkExpr e + + | SynExpr.Match (_, e, cl, _) -> + walkExpr e || walkMatchClauses cl + + | SynExpr.LetOrUse (_, _, bs, e, _) -> + walkBinds bs || walkExpr e + + | SynExpr.TryWith (e, _, cl, _, _, _, _) -> + walkExpr e || walkMatchClauses cl + + | SynExpr.TryFinally (e1, e2, _, _, _) -> + walkExpr e1 || walkExpr e2 + + | SynExpr.Sequential (_, _, e1, e2, _) -> + walkExpr e1 || walkExpr e2 + + | SynExpr.SequentialOrImplicitYield (_, e1, e2, _, _) -> + walkExpr e1 || walkExpr e2 + + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3opt, _, _, _, _) -> + walkExpr e1 || walkExpr e2 || walkExprOpt e3opt + + | SynExpr.IndexRange (expr1, _, expr2, _, _, _) -> + (match expr1 with Some e -> walkExpr e | None -> false) || + (match expr2 with Some e -> walkExpr e | None -> false) + + | SynExpr.IndexFromEnd (e, _) -> + walkExpr e + + | SynExpr.DotIndexedGet (e1, indexArgs, _, _) -> + walkExpr e1 || walkExpr indexArgs + + | SynExpr.DotIndexedSet (e1, indexArgs, e2, _, _, _) -> + walkExpr e1 || walkExpr indexArgs || walkExpr e2 + + | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> + walkExpr e1 || walkExpr e2 || walkExpr e3 + + | SynExpr.MatchBang (_, e, cl, _) -> + walkExpr e || walkMatchClauses cl + + | SynExpr.LetOrUseBang (rhs=e1;body=e2;andBangs=es) -> + walkExpr e1 || walkExprs [ for _,_,_,_,e,_ in es do yield e ] || walkExpr e2 + + | SynExpr.InterpolatedString (parts, _, _m) -> + walkExprs + (parts |> List.choose (function + | SynInterpolatedStringPart.String _ -> None + | SynInterpolatedStringPart.FillExpr (x, _) -> Some x)) + + walkExpr inpExpr + +let (|ParsedHashDirectiveArguments|) (input: ParsedHashDirectiveArgument list) = + List.map + (function + | ParsedHashDirectiveArgument.String (s, _, _) -> s + | ParsedHashDirectiveArgument.SourceIdentifier (_, v, _) -> v) + input + +let (|SynBinOp|_|) input = + match input with + | SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident synId, x1, _m1), x2, _m2) -> + Some (synId, x1, x2) + | _ -> None + +let (|SynPipeRight|_|) input = + match input with + | SynBinOp (synId, x1, x2) when synId.idText = "op_PipeRight" -> Some (x1, x2) + | _ -> None + +let (|SynPipeRight2|_|) input = + match input with + | SynBinOp (synId, SynExpr.Paren(SynExpr.Tuple(false, [x1a; x1b], _, _), _, _, _), x2) + when synId.idText = "op_PipeRight2" -> + Some (x1a, x1b, x2) + | _ -> None + +let (|SynPipeRight3|_|) input = + match input with + | SynBinOp (synId, SynExpr.Paren(SynExpr.Tuple(false, [x1a; x1b; x1c], _, _), _, _, _), x2) + when synId.idText = "op_PipeRight3" -> + Some (x1a, x1b, x1c, x2) + | _ -> None diff --git a/src/fsharp/SyntaxTreeOps.fsi b/src/fsharp/SyntaxTreeOps.fsi new file mode 100644 index 00000000000..c4274fb9584 --- /dev/null +++ b/src/fsharp/SyntaxTreeOps.fsi @@ -0,0 +1,272 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.SyntaxTreeOps + +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.Syntax + +[] +type SynArgNameGenerator = + new: unit -> SynArgNameGenerator + member New: unit -> string + member Reset: unit -> unit + +val ident: s:string * r:range -> Ident + +val textOfId: id:Ident -> string + +val pathOfLid: lid:Ident list -> string list + +val arrPathOfLid: lid:Ident list -> string [] + +val textOfPath: path:seq -> string + +val textOfLid: lid:Ident list -> string + +val rangeOfLid: lid:Ident list -> range + +val mkSynId: m:range -> s:string -> Ident + +val pathToSynLid: m:range -> p:string list -> Ident list + +val mkSynIdGet: m:range -> n:string -> SynExpr + +val mkSynLidGet: m:range -> path:string list -> n:string -> SynExpr + +val mkSynIdGetWithAlt: m:range -> id:Ident -> altInfo:SynSimplePatAlternativeIdInfo ref option -> SynExpr + +val mkSynSimplePatVar: isOpt:bool -> id:Ident -> SynSimplePat + +val mkSynCompGenSimplePatVar: id:Ident -> SynSimplePat + +/// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree. +val (|LongOrSingleIdent|_|): inp:SynExpr -> (bool * LongIdentWithDots * SynSimplePatAlternativeIdInfo ref option * range) option + +val (|SingleIdent|_|): inp:SynExpr -> Ident option + +/// This affects placement of sequence points +val IsControlFlowExpression: e:SynExpr -> bool + +val mkSynAnonField: ty:SynType -> SynField + +val mkSynNamedField: ident:Ident * ty:SynType * m:range -> SynField + +val mkSynPatVar: vis:SynAccess option -> id:Ident -> SynPat + +val mkSynThisPatVar: id:Ident -> SynPat + +val mkSynPatMaybeVar: lidwd:LongIdentWithDots -> vis:SynAccess option -> m:range -> SynPat + +val ( |SynPatForConstructorDecl|_| ): x:SynPat -> SynPat option + +/// Recognize the '()' in 'new()' +val (|SynPatForNullaryArgs|_|): x:SynPat -> unit option + +val ( |SynExprErrorSkip| ): p:SynExpr -> SynExpr + +val ( |SynExprParen|_| ): e:SynExpr -> (SynExpr * range * range option * range) option + +val ( |SynPatErrorSkip| ): p:SynPat -> SynPat + +/// Push non-simple parts of a patten match over onto the r.h.s. of a lambda. +/// Return a simple pattern and a function to build a match on the r.h.s. if the pattern is complex +val SimplePatOfPat: synArgNameGenerator:SynArgNameGenerator -> p:SynPat -> SynSimplePat * (SynExpr -> SynExpr) option + +val appFunOpt: funOpt:('a -> 'a) option -> x:'a -> 'a + +val composeFunOpt: funOpt1:('a -> 'a) option -> funOpt2:('a -> 'a) option -> ('a -> 'a) option + +val SimplePatsOfPat: synArgNameGenerator:SynArgNameGenerator -> p:SynPat -> SynSimplePats * (SynExpr -> SynExpr) option + +val PushPatternToExpr: synArgNameGenerator:SynArgNameGenerator -> isMember:bool -> pat:SynPat -> rhs:SynExpr -> SynSimplePats * SynExpr + +/// "fun (UnionCase x) (UnionCase y) -> body" +/// ==> +/// "fun tmp1 tmp2 -> +/// let (UnionCase x) = tmp1 in +/// let (UnionCase y) = tmp2 in +/// body" +val PushCurriedPatternsToExpr: synArgNameGenerator:SynArgNameGenerator -> wholem:range -> isMember:bool -> pats:SynPat list -> arrow:Range option -> rhs:SynExpr -> SynSimplePats list * SynExpr + +val opNameParenGet: string + +val opNameQMark: string + +val mkSynOperator: opm:range -> oper:string -> SynExpr + +val mkSynInfix: opm:range -> l:SynExpr -> oper:string -> r:SynExpr -> SynExpr + +val mkSynBifix: m:range -> oper:string -> x1:SynExpr -> x2:SynExpr -> SynExpr + +val mkSynTrifix: m:range -> oper:string -> x1:SynExpr -> x2:SynExpr -> x3:SynExpr -> SynExpr + +val mkSynPrefixPrim: opm:range -> m:range -> oper:string -> x:SynExpr -> SynExpr + +val mkSynPrefix: opm:range -> m:range -> oper:string -> x:SynExpr -> SynExpr + +val mkSynCaseName: m:range -> n:string -> Ident list + +val mkSynApp1: f:SynExpr -> x1:SynExpr -> m:range -> SynExpr + +val mkSynApp2: f:SynExpr -> x1:SynExpr -> x2:SynExpr -> m:range -> SynExpr + +val mkSynApp3: f:SynExpr -> x1:SynExpr -> x2:SynExpr -> x3:SynExpr -> m:range -> SynExpr + +val mkSynApp4: f:SynExpr -> x1:SynExpr -> x2:SynExpr -> x3:SynExpr -> x4:SynExpr -> m:range -> SynExpr + +val mkSynApp5: f:SynExpr -> x1:SynExpr -> x2:SynExpr -> x3:SynExpr -> x4:SynExpr -> x5:SynExpr -> m:range -> SynExpr + +val mkSynDotParenSet: m:range -> a:SynExpr -> b:SynExpr -> c:SynExpr -> SynExpr + +val mkSynDotBrackGet: m:range -> mDot:range -> a:SynExpr -> b:SynExpr -> SynExpr + +val mkSynQMarkSet: m:range -> a:SynExpr -> b:SynExpr -> c:SynExpr -> SynExpr + +//val mkSynDotBrackSliceGet: m:range -> mDot:range -> arr:SynExpr -> sliceArg:SynIndexerArg -> SynExpr + +//val mkSynDotBrackSeqSliceGet: m:range -> mDot:range -> arr:SynExpr -> argsList:SynIndexerArg list -> SynExpr + +val mkSynDotParenGet: lhsm:range -> dotm:range -> a:SynExpr -> b:SynExpr -> SynExpr + +val mkSynUnit: m:range -> SynExpr + +val mkSynUnitPat: m:range -> SynPat + +val mkSynDelay: m:range -> e:SynExpr -> SynExpr + +val mkSynAssign: l:SynExpr -> r:SynExpr -> SynExpr + +val mkSynDot: dotm:range -> m:range -> l:SynExpr -> r:Ident -> SynExpr + +val mkSynDotMissing: dotm:range -> m:range -> l:SynExpr -> SynExpr + +val mkSynFunMatchLambdas: synArgNameGenerator:SynArgNameGenerator -> isMember:bool -> wholem:range -> ps:SynPat list -> arrow:Range option -> e:SynExpr -> SynExpr + +val arbExpr: debugStr:string * range:range -> SynExpr + +val unionRangeWithListBy: projectRangeFromThing:('a -> range) -> m:range -> listOfThing:'a list -> range + +val mkAttributeList: attrs:SynAttribute list -> range:range -> SynAttributeList list + +val ConcatAttributesLists: attrsLists:SynAttributeList list -> SynAttribute list + +val ( |Attributes| ): synAttributes:SynAttributeList list -> SynAttribute list + +val ( |TyparDecls| ): typarDecls: SynTyparDecls option -> SynTyparDecl list +val ( |TyparsAndConstraints| ): typarDecls: SynTyparDecls option -> SynTyparDecl list * SynTypeConstraint list +val ( |ValTyparDecls| ): valTyparDecls: SynValTyparDecls -> SynTyparDecl list * SynTypeConstraint list * bool + +val rangeOfNonNilAttrs: attrs:SynAttributes -> range + +val stripParenTypes: synType:SynType -> SynType + +val ( |StripParenTypes| ): synType:SynType -> SynType + +/// Operations related to the syntactic analysis of arguments of value, function and member definitions and signatures. +module SynInfo = + /// The argument information for an argument without a name + val unnamedTopArg1: SynArgInfo + + /// The argument information for a curried argument without a name + val unnamedTopArg: SynArgInfo list + + /// The argument information for a '()' argument + val unitArgData: SynArgInfo list + + /// The 'argument' information for a return value where no attributes are given for the return value (the normal case) + val unnamedRetVal: SynArgInfo + + /// The 'argument' information for the 'this'/'self' parameter in the cases where it is not given explicitly + val selfMetadata: SynArgInfo list + + /// Determine if a syntactic information represents a member without arguments (which is implicitly a property getter) + val HasNoArgs: SynValInfo -> bool + + /// Check if one particular argument is an optional argument. Used when adjusting the + /// types of optional arguments for function and member signatures. + val IsOptionalArg: SynArgInfo -> bool + + /// Check if there are any optional arguments in the syntactic argument information. Used when adjusting the + /// types of optional arguments for function and member signatures. + val HasOptionalArgs: SynValInfo -> bool + + /// Add a parameter entry to the syntactic value information to represent the '()' argument to a property getter. This is + /// used for the implicit '()' argument in property getter signature specifications. + val IncorporateEmptyTupledArgForPropertyGetter: SynValInfo -> SynValInfo + + /// Add a parameter entry to the syntactic value information to represent the 'this' argument. This is + /// used for the implicit 'this' argument in member signature specifications. + val IncorporateSelfArg: SynValInfo -> SynValInfo + + /// Add a parameter entry to the syntactic value information to represent the value argument for a property setter. This is + /// used for the implicit value argument in property setter signature specifications. + val IncorporateSetterArg: SynValInfo -> SynValInfo + + /// Get the argument counts for each curried argument group. Used in some adhoc places in tc.fs. + val AritiesOfArgs: SynValInfo -> int list + + /// Get the argument attributes from the syntactic information for an argument. + val AttribsOfArgData: SynArgInfo -> SynAttribute list + + /// Infer the syntactic argument info for a single argument from a simple pattern. + val InferSynArgInfoFromSimplePat: attribs:SynAttributes -> p:SynSimplePat -> SynArgInfo + + /// Infer the syntactic argument info for one or more arguments one or more simple patterns. + val InferSynArgInfoFromSimplePats: x:SynSimplePats -> SynArgInfo list + + /// Infer the syntactic argument info for one or more arguments a pattern. + val InferSynArgInfoFromPat: p:SynPat -> SynArgInfo list + + /// Make sure only a solitary unit argument has unit elimination + val AdjustArgsForUnitElimination: infosForArgs:SynArgInfo list list -> SynArgInfo list list + + /// Transform a property declared using '[static] member P = expr' to a method taking a "unit" argument. + /// This is similar to IncorporateEmptyTupledArgForPropertyGetter, but applies to member definitions + /// rather than member signatures. + val AdjustMemberArgs: memFlags:SynMemberKind -> infosForArgs:'a list list -> 'a list list + + val InferSynReturnData: retInfo:SynReturnInfo option -> SynArgInfo + + val emptySynValData: SynValData + + /// Infer the syntactic information for a 'let' or 'member' definition, based on the argument pattern, + /// any declared return information (e.g. .NET attributes on the return element), and the r.h.s. expression + /// in the case of 'let' definitions. + val InferSynValData: memberFlagsOpt:SynMemberFlags option * pat:SynPat option * retInfo:SynReturnInfo option * origRhsExpr:SynExpr -> SynValData + +val mkSynBindingRhs: staticOptimizations:(SynStaticOptimizationConstraint list * SynExpr) list -> rhsExpr:SynExpr -> mRhs:range -> retInfo:SynReturnInfo option -> SynExpr * SynBindingReturnInfo option + +val mkSynBinding: + xmlDoc:PreXmlDoc * headPat:SynPat -> + vis:SynAccess option * isInline:bool * isMutable:bool * mBind:range * + spBind:DebugPointAtBinding * retInfo:SynReturnInfo option * origRhsExpr:SynExpr * mRhs:range * + staticOptimizations:(SynStaticOptimizationConstraint list * SynExpr) list * attrs:SynAttributes * memberFlagsOpt:SynMemberFlags option + -> SynBinding + +val NonVirtualMemberFlags: k:SynMemberKind -> SynMemberFlags + +val CtorMemberFlags: SynMemberFlags + +val ClassCtorMemberFlags: SynMemberFlags + +val OverrideMemberFlags: k:SynMemberKind -> SynMemberFlags + +val AbstractMemberFlags: k:SynMemberKind -> SynMemberFlags + +val StaticMemberFlags: k:SynMemberKind -> SynMemberFlags + +val inferredTyparDecls: SynValTyparDecls + +val noInferredTypars: SynValTyparDecls + +val synExprContainsError: inpExpr:SynExpr -> bool + +val ( |ParsedHashDirectiveArguments| ) : ParsedHashDirectiveArgument list -> string list + +val (|SynPipeRight|_|): SynExpr -> (SynExpr * SynExpr) option + +val (|SynPipeRight2|_|): SynExpr -> (SynExpr * SynExpr * SynExpr) option + +val (|SynPipeRight3|_|): SynExpr -> (SynExpr * SynExpr * SynExpr * SynExpr) option + diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs deleted file mode 100644 index fe30b314d15..00000000000 --- a/src/fsharp/TastOps.fs +++ /dev/null @@ -1,9011 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Defines derived expression manipulation and construction functions. -module internal FSharp.Compiler.Tastops - -open System.Collections.Generic -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Rational -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Lib -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Features -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -#endif - -//--------------------------------------------------------------------------- -// Basic data structures -//--------------------------------------------------------------------------- - -[] -type TyparMap<'T> = - | TPMap of StampMap<'T> - - member tm.Item - with get (v: Typar) = - let (TPMap m) = tm - m.[v.Stamp] - - member tm.ContainsKey (v: Typar) = - let (TPMap m) = tm - m.ContainsKey(v.Stamp) - - member tm.TryFind (v: Typar) = - let (TPMap m) = tm - m.TryFind(v.Stamp) - - member tm.Add (v: Typar, x) = - let (TPMap m) = tm - TPMap (m.Add(v.Stamp, x)) - - static member Empty: TyparMap<'T> = TPMap Map.empty - -[] -type TyconRefMap<'T>(imap: StampMap<'T>) = - member m.Item with get (v: TyconRef) = imap.[v.Stamp] - member m.TryFind (v: TyconRef) = imap.TryFind v.Stamp - member m.ContainsKey (v: TyconRef) = imap.ContainsKey v.Stamp - member m.Add (v: TyconRef) x = TyconRefMap (imap.Add (v.Stamp, x)) - member m.Remove (v: TyconRef) = TyconRefMap (imap.Remove v.Stamp) - member m.IsEmpty = imap.IsEmpty - - static member Empty: TyconRefMap<'T> = TyconRefMap Map.empty - static member OfList vs = (vs, TyconRefMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add x y) - -[] -[] -type ValMap<'T>(imap: StampMap<'T>) = - - member m.Contents = imap - member m.Item with get (v: Val) = imap.[v.Stamp] - member m.TryFind (v: Val) = imap.TryFind v.Stamp - member m.ContainsVal (v: Val) = imap.ContainsKey v.Stamp - member m.Add (v: Val) x = ValMap (imap.Add(v.Stamp, x)) - member m.Remove (v: Val) = ValMap (imap.Remove(v.Stamp)) - static member Empty = ValMap<'T> Map.empty - member m.IsEmpty = imap.IsEmpty - static member OfList vs = (vs, ValMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add x y) - -//-------------------------------------------------------------------------- -// renamings -//-------------------------------------------------------------------------- - -type TyparInst = (Typar * TType) list - -type TyconRefRemap = TyconRefMap -type ValRemap = ValMap - -let emptyTyconRefRemap: TyconRefRemap = TyconRefMap<_>.Empty -let emptyTyparInst = ([]: TyparInst) - -[] -type Remap = - { tpinst: TyparInst - valRemap: ValRemap - tyconRefRemap: TyconRefRemap - removeTraitSolutions: bool } - -let emptyRemap = - { tpinst = emptyTyparInst - tyconRefRemap = emptyTyconRefRemap - valRemap = ValMap.Empty - removeTraitSolutions = false } - -type Remap with - static member Empty = emptyRemap - -//-------------------------------------------------------------------------- -// Substitute for type variables and remap type constructors -//-------------------------------------------------------------------------- - -let addTyconRefRemap tcref1 tcref2 tmenv = - { tmenv with tyconRefRemap = tmenv.tyconRefRemap.Add tcref1 tcref2 } - -let isRemapEmpty remap = - isNil remap.tpinst && - remap.tyconRefRemap.IsEmpty && - remap.valRemap.IsEmpty - -let rec instTyparRef tpinst ty tp = - match tpinst with - | [] -> ty - | (tp', ty') :: t -> - if typarEq tp tp' then ty' - else instTyparRef t ty tp - -let instMeasureTyparRef tpinst unt (tp: Typar) = - match tp.Kind with - | TyparKind.Measure -> - let rec loop tpinst = - match tpinst with - | [] -> unt - | (tp', ty') :: t -> - if typarEq tp tp' then - match ty' with - | TType_measure unt -> unt - | _ -> failwith "instMeasureTyparRef incorrect kind" - else - loop t - loop tpinst - | _ -> failwith "instMeasureTyparRef: kind=Type" - -let remapTyconRef (tcmap: TyconRefMap<_>) tcref = - match tcmap.TryFind tcref with - | Some tcref -> tcref - | None -> tcref - -let remapUnionCaseRef tcmap (UCRef(tcref, nm)) = UCRef(remapTyconRef tcmap tcref, nm) -let remapRecdFieldRef tcmap (RFRef(tcref, nm)) = RFRef(remapTyconRef tcmap tcref, nm) - -let mkTyparInst (typars: Typars) tyargs = -#if CHECKED - if List.length typars <> List.length tyargs then - failwith ("mkTyparInst: invalid type" + (sprintf " %d <> %d" (List.length typars) (List.length tyargs))) -#endif - (List.zip typars tyargs: TyparInst) - -let generalizeTypar tp = mkTyparTy tp -let generalizeTypars tps = List.map generalizeTypar tps - -let rec remapTypeAux (tyenv: Remap) (ty: TType) = - let ty = stripTyparEqns ty - match ty with - | TType_var tp as ty -> instTyparRef tyenv.tpinst ty tp - | TType_app (tcref, tinst) as ty -> - match tyenv.tyconRefRemap.TryFind tcref with - | Some tcref' -> TType_app (tcref', remapTypesAux tyenv tinst) - | None -> - match tinst with - | [] -> ty // optimization to avoid re-allocation of TType_app node in the common case - | _ -> - // avoid reallocation on idempotent - let tinst' = remapTypesAux tyenv tinst - if tinst === tinst' then ty else - TType_app (tcref, tinst') - - | TType_ucase (UCRef(tcref, n), tinst) -> - match tyenv.tyconRefRemap.TryFind tcref with - | Some tcref' -> TType_ucase (UCRef(tcref', n), remapTypesAux tyenv tinst) - | None -> TType_ucase (UCRef(tcref, n), remapTypesAux tyenv tinst) - - | TType_anon (anonInfo, l) as ty -> - let tupInfo' = remapTupInfoAux tyenv anonInfo.TupInfo - let l' = remapTypesAux tyenv l - if anonInfo.TupInfo === tupInfo' && l === l' then ty else - TType_anon (AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo', anonInfo.SortedIds), l') - - | TType_tuple (tupInfo, l) as ty -> - let tupInfo' = remapTupInfoAux tyenv tupInfo - let l' = remapTypesAux tyenv l - if tupInfo === tupInfo' && l === l' then ty else - TType_tuple (tupInfo', l') - - | TType_fun (d, r) as ty -> - let d' = remapTypeAux tyenv d - let r' = remapTypeAux tyenv r - if d === d' && r === r' then ty else - TType_fun (d', r') - - | TType_forall (tps, ty) -> - let tps', tyenv = copyAndRemapAndBindTypars tyenv tps - TType_forall (tps', remapTypeAux tyenv ty) - - | TType_measure unt -> - TType_measure (remapMeasureAux tyenv unt) - - -and remapMeasureAux tyenv unt = - match unt with - | Measure.One -> unt - | Measure.Con tcref -> - match tyenv.tyconRefRemap.TryFind tcref with - | Some tcref -> Measure.Con tcref - | None -> unt - | Measure.Prod(u1, u2) -> Measure.Prod(remapMeasureAux tyenv u1, remapMeasureAux tyenv u2) - | Measure.RationalPower(u, q) -> Measure.RationalPower(remapMeasureAux tyenv u, q) - | Measure.Inv u -> Measure.Inv(remapMeasureAux tyenv u) - | Measure.Var tp as unt -> - match tp.Solution with - | None -> - match ListAssoc.tryFind typarEq tp tyenv.tpinst with - | Some v -> - match v with - | TType_measure unt -> unt - | _ -> failwith "remapMeasureAux: incorrect kinds" - | None -> unt - | Some (TType_measure unt) -> remapMeasureAux tyenv unt - | Some ty -> failwithf "incorrect kinds: %A" ty - -and remapTupInfoAux _tyenv unt = - match unt with - | TupInfo.Const _ -> unt - -and remapTypesAux tyenv types = List.mapq (remapTypeAux tyenv) types -and remapTyparConstraintsAux tyenv cs = - cs |> List.choose (fun x -> - match x with - | TyparConstraint.CoercesTo(ty, m) -> - Some(TyparConstraint.CoercesTo (remapTypeAux tyenv ty, m)) - | TyparConstraint.MayResolveMember(traitInfo, m) -> - Some(TyparConstraint.MayResolveMember (remapTraitAux tyenv traitInfo, m)) - | TyparConstraint.DefaultsTo(priority, ty, m) -> Some(TyparConstraint.DefaultsTo(priority, remapTypeAux tyenv ty, m)) - | TyparConstraint.IsEnum(uty, m) -> - Some(TyparConstraint.IsEnum(remapTypeAux tyenv uty, m)) - | TyparConstraint.IsDelegate(uty1, uty2, m) -> - Some(TyparConstraint.IsDelegate(remapTypeAux tyenv uty1, remapTypeAux tyenv uty2, m)) - | TyparConstraint.SimpleChoice(tys, m) -> Some(TyparConstraint.SimpleChoice(remapTypesAux tyenv tys, m)) - | TyparConstraint.SupportsComparison _ - | TyparConstraint.SupportsEquality _ - | TyparConstraint.SupportsNull _ - | TyparConstraint.IsUnmanaged _ - | TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsReferenceType _ - | TyparConstraint.RequiresDefaultConstructor _ -> Some x) - -and remapTraitAux tyenv (TTrait(tys, nm, mf, argtys, rty, slnCell)) = - let slnCell = - match !slnCell with - | None -> None - | _ when tyenv.removeTraitSolutions -> None - | Some sln -> - let sln = - match sln with - | ILMethSln(ty, extOpt, ilMethRef, minst) -> - ILMethSln(remapTypeAux tyenv ty, extOpt, ilMethRef, remapTypesAux tyenv minst) - | FSMethSln(ty, vref, minst) -> - FSMethSln(remapTypeAux tyenv ty, remapValRef tyenv vref, remapTypesAux tyenv minst) - | FSRecdFieldSln(tinst, rfref, isSet) -> - FSRecdFieldSln(remapTypesAux tyenv tinst, remapRecdFieldRef tyenv.tyconRefRemap rfref, isSet) - | FSAnonRecdFieldSln(anonInfo, tinst, n) -> - FSAnonRecdFieldSln(anonInfo, remapTypesAux tyenv tinst, n) - | BuiltInSln -> - BuiltInSln - | ClosedExprSln e -> - ClosedExprSln e // no need to remap because it is a closed expression, referring only to external types - Some sln - // Note: we reallocate a new solution cell on every traversal of a trait constraint - // This feels incorrect for trait constraints that are quantified: it seems we should have - // formal binders for trait constraints when they are quantified, just as - // we have formal binders for type variables. - // - // The danger here is that a solution for one syntactic occurrence of a trait constraint won't - // be propagated to other, "linked" solutions. However trait constraints don't appear in any algebra - // in the same way as types - TTrait(remapTypesAux tyenv tys, nm, mf, remapTypesAux tyenv argtys, Option.map (remapTypeAux tyenv) rty, ref slnCell) - -and bindTypars tps tyargs tpinst = - match tps with - | [] -> tpinst - | _ -> List.map2 (fun tp tyarg -> (tp, tyarg)) tps tyargs @ tpinst - -// This version is used to remap most type parameters, e.g. ones bound at tycons, vals, records -// See notes below on remapTypeFull for why we have a function that accepts remapAttribs as an argument -and copyAndRemapAndBindTyparsFull remapAttrib tyenv tps = - match tps with - | [] -> tps, tyenv - | _ -> - let tps' = copyTypars tps - let tyenv = { tyenv with tpinst = bindTypars tps (generalizeTypars tps') tyenv.tpinst } - (tps, tps') ||> List.iter2 (fun tporig tp -> - tp.SetConstraints (remapTyparConstraintsAux tyenv tporig.Constraints) - tp.SetAttribs (tporig.Attribs |> remapAttrib)) - tps', tyenv - -// copies bound typars, extends tpinst -and copyAndRemapAndBindTypars tyenv tps = - copyAndRemapAndBindTyparsFull (fun _ -> []) tyenv tps - -and remapValLinkage tyenv (vlink: ValLinkageFullKey) = - let tyOpt = vlink.TypeForLinkage - let tyOpt' = - match tyOpt with - | None -> tyOpt - | Some ty -> - let ty' = remapTypeAux tyenv ty - if ty === ty' then tyOpt else - Some ty' - if tyOpt === tyOpt' then vlink else - ValLinkageFullKey(vlink.PartialKey, tyOpt') - -and remapNonLocalValRef tyenv (nlvref: NonLocalValOrMemberRef) = - let eref = nlvref.EnclosingEntity - let eref' = remapTyconRef tyenv.tyconRefRemap eref - let vlink = nlvref.ItemKey - let vlink' = remapValLinkage tyenv vlink - if eref === eref' && vlink === vlink' then nlvref else - { EnclosingEntity = eref' - ItemKey = vlink' } - -and remapValRef tmenv (vref: ValRef) = - match tmenv.valRemap.TryFind vref.Deref with - | None -> - if vref.IsLocalRef then vref else - let nlvref = vref.nlr - let nlvref' = remapNonLocalValRef tmenv nlvref - if nlvref === nlvref' then vref else - VRefNonLocal nlvref' - | Some res -> - res - -let remapType tyenv x = - if isRemapEmpty tyenv then x else - remapTypeAux tyenv x - -let remapTypes tyenv x = - if isRemapEmpty tyenv then x else - remapTypesAux tyenv x - -/// Use this one for any type that may be a forall type where the type variables may contain attributes -/// Logically speaking this is mutually recursive with remapAttrib defined much later in this file, -/// because types may contain forall types that contain attributes, which need to be remapped. -/// We currently break the recursion by passing in remapAttrib as a function parameter. -/// Use this one for any type that may be a forall type where the type variables may contain attributes -let remapTypeFull remapAttrib tyenv ty = - if isRemapEmpty tyenv then ty else - match stripTyparEqns ty with - | TType_forall(tps, tau) -> - let tps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenv tps - TType_forall(tps', remapType tyenvinner tau) - | _ -> - remapType tyenv ty - -let remapParam tyenv (TSlotParam(nm, ty, fl1, fl2, fl3, attribs) as x) = - if isRemapEmpty tyenv then x else - TSlotParam(nm, remapTypeAux tyenv ty, fl1, fl2, fl3, attribs) - -let remapSlotSig remapAttrib tyenv (TSlotSig(nm, ty, ctps, methTypars, paraml, rty) as x) = - if isRemapEmpty tyenv then x else - let ty' = remapTypeAux tyenv ty - let ctps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenv ctps - let methTypars', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenvinner methTypars - TSlotSig(nm, ty', ctps', methTypars', List.mapSquared (remapParam tyenvinner) paraml, Option.map (remapTypeAux tyenvinner) rty) - -let mkInstRemap tpinst = - { tyconRefRemap = emptyTyconRefRemap - tpinst = tpinst - valRemap = ValMap.Empty - removeTraitSolutions = false } - -// entry points for "typar -> TType" instantiation -let instType tpinst x = if isNil tpinst then x else remapTypeAux (mkInstRemap tpinst) x -let instTypes tpinst x = if isNil tpinst then x else remapTypesAux (mkInstRemap tpinst) x -let instTrait tpinst x = if isNil tpinst then x else remapTraitAux (mkInstRemap tpinst) x -let instTyparConstraints tpinst x = if isNil tpinst then x else remapTyparConstraintsAux (mkInstRemap tpinst) x -let instSlotSig tpinst ss = remapSlotSig (fun _ -> []) (mkInstRemap tpinst) ss -let copySlotSig ss = remapSlotSig (fun _ -> []) Remap.Empty ss - - -let mkTyparToTyparRenaming tpsOrig tps = - let tinst = generalizeTypars tps - mkTyparInst tpsOrig tinst, tinst - -let mkTyconInst (tycon: Tycon) tinst = mkTyparInst tycon.TyparsNoRange tinst -let mkTyconRefInst (tcref: TyconRef) tinst = mkTyconInst tcref.Deref tinst - -//--------------------------------------------------------------------------- -// Basic equalities -//--------------------------------------------------------------------------- - -let tyconRefEq (g: TcGlobals) tcref1 tcref2 = primEntityRefEq g.compilingFslib g.fslibCcu tcref1 tcref2 -let valRefEq (g: TcGlobals) vref1 vref2 = primValRefEq g.compilingFslib g.fslibCcu vref1 vref2 - -//--------------------------------------------------------------------------- -// Remove inference equations and abbreviations from units -//--------------------------------------------------------------------------- - -let reduceTyconRefAbbrevMeasureable (tcref: TyconRef) = - let abbrev = tcref.TypeAbbrev - match abbrev with - | Some (TType_measure ms) -> ms - | _ -> invalidArg "tcref" "not a measure abbreviation, or incorrect kind" - -let rec stripUnitEqnsFromMeasureAux canShortcut unt = - match stripUnitEqnsAux canShortcut unt with - | Measure.Con tcref when tcref.IsTypeAbbrev -> - stripUnitEqnsFromMeasureAux canShortcut (reduceTyconRefAbbrevMeasureable tcref) - | m -> m - -let stripUnitEqnsFromMeasure m = stripUnitEqnsFromMeasureAux false m - -//--------------------------------------------------------------------------- -// Basic unit stuff -//--------------------------------------------------------------------------- - -/// What is the contribution of unit-of-measure constant ucref to unit-of-measure expression measure? -let rec MeasureExprConExponent g abbrev ucref unt = - match (if abbrev then stripUnitEqnsFromMeasure unt else stripUnitEqns unt) with - | Measure.Con ucref' -> if tyconRefEq g ucref' ucref then OneRational else ZeroRational - | Measure.Inv unt' -> NegRational(MeasureExprConExponent g abbrev ucref unt') - | Measure.Prod(unt1, unt2) -> AddRational(MeasureExprConExponent g abbrev ucref unt1) (MeasureExprConExponent g abbrev ucref unt2) - | Measure.RationalPower(unt', q) -> MulRational (MeasureExprConExponent g abbrev ucref unt') q - | _ -> ZeroRational - -/// What is the contribution of unit-of-measure constant ucref to unit-of-measure expression measure -/// after remapping tycons? -let rec MeasureConExponentAfterRemapping g r ucref unt = - match stripUnitEqnsFromMeasure unt with - | Measure.Con ucref' -> if tyconRefEq g (r ucref') ucref then OneRational else ZeroRational - | Measure.Inv unt' -> NegRational(MeasureConExponentAfterRemapping g r ucref unt') - | Measure.Prod(unt1, unt2) -> AddRational(MeasureConExponentAfterRemapping g r ucref unt1) (MeasureConExponentAfterRemapping g r ucref unt2) - | Measure.RationalPower(unt', q) -> MulRational (MeasureConExponentAfterRemapping g r ucref unt') q - | _ -> ZeroRational - -/// What is the contribution of unit-of-measure variable tp to unit-of-measure expression unt? -let rec MeasureVarExponent tp unt = - match stripUnitEqnsFromMeasure unt with - | Measure.Var tp' -> if typarEq tp tp' then OneRational else ZeroRational - | Measure.Inv unt' -> NegRational(MeasureVarExponent tp unt') - | Measure.Prod(unt1, unt2) -> AddRational(MeasureVarExponent tp unt1) (MeasureVarExponent tp unt2) - | Measure.RationalPower(unt', q) -> MulRational (MeasureVarExponent tp unt') q - | _ -> ZeroRational - -/// List the *literal* occurrences of unit variables in a unit expression, without repeats -let ListMeasureVarOccs unt = - let rec gather acc unt = - match stripUnitEqnsFromMeasure unt with - | Measure.Var tp -> if List.exists (typarEq tp) acc then acc else tp :: acc - | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 - | Measure.RationalPower(unt', _) -> gather acc unt' - | Measure.Inv unt' -> gather acc unt' - | _ -> acc - gather [] unt - -/// List the *observable* occurrences of unit variables in a unit expression, without repeats, paired with their non-zero exponents -let ListMeasureVarOccsWithNonZeroExponents untexpr = - let rec gather acc unt = - match stripUnitEqnsFromMeasure unt with - | Measure.Var tp -> - if List.exists (fun (tp', _) -> typarEq tp tp') acc then acc - else - let e = MeasureVarExponent tp untexpr - if e = ZeroRational then acc else (tp, e) :: acc - | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 - | Measure.Inv unt' -> gather acc unt' - | Measure.RationalPower(unt', _) -> gather acc unt' - | _ -> acc - gather [] untexpr - -/// List the *observable* occurrences of unit constants in a unit expression, without repeats, paired with their non-zero exponents -let ListMeasureConOccsWithNonZeroExponents g eraseAbbrevs untexpr = - let rec gather acc unt = - match (if eraseAbbrevs then stripUnitEqnsFromMeasure unt else stripUnitEqns unt) with - | Measure.Con c -> - if List.exists (fun (c', _) -> tyconRefEq g c c') acc then acc else - let e = MeasureExprConExponent g eraseAbbrevs c untexpr - if e = ZeroRational then acc else (c, e) :: acc - | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 - | Measure.Inv unt' -> gather acc unt' - | Measure.RationalPower(unt', _) -> gather acc unt' - | _ -> acc - gather [] untexpr - -/// List the *literal* occurrences of unit constants in a unit expression, without repeats, -/// and after applying a remapping function r to tycons -let ListMeasureConOccsAfterRemapping g r unt = - let rec gather acc unt = - match stripUnitEqnsFromMeasure unt with - | Measure.Con c -> if List.exists (tyconRefEq g (r c)) acc then acc else r c :: acc - | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 - | Measure.RationalPower(unt', _) -> gather acc unt' - | Measure.Inv unt' -> gather acc unt' - | _ -> acc - - gather [] unt - -/// Construct a measure expression representing the n'th power of a measure -let MeasurePower u n = - if n = 1 then u - elif n = 0 then Measure.One - else Measure.RationalPower (u, intToRational n) - -let MeasureProdOpt m1 m2 = - match m1, m2 with - | Measure.One, _ -> m2 - | _, Measure.One -> m1 - | _, _ -> Measure.Prod (m1, m2) - -/// Construct a measure expression representing the product of a list of measures -let ProdMeasures ms = - match ms with - | [] -> Measure.One - | m :: ms -> List.foldBack MeasureProdOpt ms m - -let isDimensionless g tyarg = - match stripTyparEqns tyarg with - | TType_measure unt -> - isNil (ListMeasureVarOccsWithNonZeroExponents unt) && - isNil (ListMeasureConOccsWithNonZeroExponents g true unt) - | _ -> false - -let destUnitParMeasure g unt = - let vs = ListMeasureVarOccsWithNonZeroExponents unt - let cs = ListMeasureConOccsWithNonZeroExponents g true unt - - match vs, cs with - | [(v, e)], [] when e = OneRational -> v - | _, _ -> failwith "destUnitParMeasure: not a unit-of-measure parameter" - -let isUnitParMeasure g unt = - let vs = ListMeasureVarOccsWithNonZeroExponents unt - let cs = ListMeasureConOccsWithNonZeroExponents g true unt - - match vs, cs with - | [(_, e)], [] when e = OneRational -> true - | _, _ -> false - -let normalizeMeasure g ms = - let vs = ListMeasureVarOccsWithNonZeroExponents ms - let cs = ListMeasureConOccsWithNonZeroExponents g false ms - match vs, cs with - | [], [] -> Measure.One - | [(v, e)], [] when e = OneRational -> Measure.Var v - | vs, cs -> List.foldBack (fun (v, e) -> fun m -> Measure.Prod (Measure.RationalPower (Measure.Var v, e), m)) vs (List.foldBack (fun (c, e) -> fun m -> Measure.Prod (Measure.RationalPower (Measure.Con c, e), m)) cs Measure.One) - -let tryNormalizeMeasureInType g ty = - match ty with - | TType_measure (Measure.Var v) -> - match v.Solution with - | Some (TType_measure ms) -> - v.typar_solution <- Some (TType_measure (normalizeMeasure g ms)) - ty - | _ -> ty - | _ -> ty - -//--------------------------------------------------------------------------- -// Some basic type builders -//--------------------------------------------------------------------------- - -let mkNativePtrTy (g: TcGlobals) ty = - assert g.nativeptr_tcr.CanDeref // this should always be available, but check anyway - TType_app (g.nativeptr_tcr, [ty]) - -let mkByrefTy (g: TcGlobals) ty = - assert g.byref_tcr.CanDeref // this should always be available, but check anyway - TType_app (g.byref_tcr, [ty]) - -let mkInByrefTy (g: TcGlobals) ty = - if g.inref_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref = byref, see RFC FS-1053.md - TType_app (g.inref_tcr, [ty]) - else - mkByrefTy g ty - -let mkOutByrefTy (g: TcGlobals) ty = - if g.outref_tcr.CanDeref then // If not using sufficient FSharp.Core, then outref = byref, see RFC FS-1053.md - TType_app (g.outref_tcr, [ty]) - else - mkByrefTy g ty - -let mkByrefTyWithFlag g readonly ty = - if readonly then - mkInByrefTy g ty - else - mkByrefTy g ty - -let mkByref2Ty (g: TcGlobals) ty1 ty2 = - assert g.byref2_tcr.CanDeref // check we are using sufficient FSharp.Core, caller should check this - TType_app (g.byref2_tcr, [ty1; ty2]) - -let mkVoidPtrTy (g: TcGlobals) = - assert g.voidptr_tcr.CanDeref // check we are using sufficient FSharp.Core, caller should check this - TType_app (g.voidptr_tcr, []) - -let mkByrefTyWithInference (g: TcGlobals) ty1 ty2 = - if g.byref2_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref = byref, see RFC FS-1053.md - TType_app (g.byref2_tcr, [ty1; ty2]) - else - TType_app (g.byref_tcr, [ty1]) - -let mkArrayTy (g: TcGlobals) rank ty m = - if rank < 1 || rank > 32 then - errorR(Error(FSComp.SR.tastopsMaxArrayThirtyTwo rank, m)) - TType_app (g.il_arr_tcr_map.[3], [ty]) - else - TType_app (g.il_arr_tcr_map.[rank - 1], [ty]) - -//-------------------------------------------------------------------------- -// Tuple compilation (types) -//------------------------------------------------------------------------ - -let maxTuple = 8 -let goodTupleFields = maxTuple-1 - -let isCompiledTupleTyconRef g tcref = - tyconRefEq g g.ref_tuple1_tcr tcref || - tyconRefEq g g.ref_tuple2_tcr tcref || - tyconRefEq g g.ref_tuple3_tcr tcref || - tyconRefEq g g.ref_tuple4_tcr tcref || - tyconRefEq g g.ref_tuple5_tcr tcref || - tyconRefEq g g.ref_tuple6_tcr tcref || - tyconRefEq g g.ref_tuple7_tcr tcref || - tyconRefEq g g.ref_tuple8_tcr tcref || - tyconRefEq g g.struct_tuple1_tcr tcref || - tyconRefEq g g.struct_tuple2_tcr tcref || - tyconRefEq g g.struct_tuple3_tcr tcref || - tyconRefEq g g.struct_tuple4_tcr tcref || - tyconRefEq g g.struct_tuple5_tcr tcref || - tyconRefEq g g.struct_tuple6_tcr tcref || - tyconRefEq g g.struct_tuple7_tcr tcref || - tyconRefEq g g.struct_tuple8_tcr tcref - -let mkCompiledTupleTyconRef (g: TcGlobals) isStruct n = - if n = 1 then (if isStruct then g.struct_tuple1_tcr else g.ref_tuple1_tcr) - elif n = 2 then (if isStruct then g.struct_tuple2_tcr else g.ref_tuple2_tcr) - elif n = 3 then (if isStruct then g.struct_tuple3_tcr else g.ref_tuple3_tcr) - elif n = 4 then (if isStruct then g.struct_tuple4_tcr else g.ref_tuple4_tcr) - elif n = 5 then (if isStruct then g.struct_tuple5_tcr else g.ref_tuple5_tcr) - elif n = 6 then (if isStruct then g.struct_tuple6_tcr else g.ref_tuple6_tcr) - elif n = 7 then (if isStruct then g.struct_tuple7_tcr else g.ref_tuple7_tcr) - elif n = 8 then (if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr) - else failwithf "mkCompiledTupleTyconRef, n = %d" n - -/// Convert from F# tuple types to .NET tuple types -let rec mkCompiledTupleTy g isStruct tupElemTys = - let n = List.length tupElemTys - if n < maxTuple then - TType_app (mkCompiledTupleTyconRef g isStruct n, tupElemTys) - else - let tysA, tysB = List.splitAfter goodTupleFields tupElemTys - TType_app ((if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr), tysA@[mkCompiledTupleTy g isStruct tysB]) - -/// Convert from F# tuple types to .NET tuple types, but only the outermost level -let mkOuterCompiledTupleTy g isStruct tupElemTys = - let n = List.length tupElemTys - if n < maxTuple then - TType_app (mkCompiledTupleTyconRef g isStruct n, tupElemTys) - else - let tysA, tysB = List.splitAfter goodTupleFields tupElemTys - let tcref = (if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr) - // In the case of an 8-tuple we add the Tuple<_> marker. For other sizes we keep the type - // as a regular F# tuple type. - match tysB with - | [ tyB ] -> - let marker = TType_app (mkCompiledTupleTyconRef g isStruct 1, [tyB]) - TType_app (tcref, tysA@[marker]) - | _ -> - TType_app (tcref, tysA@[TType_tuple (mkTupInfo isStruct, tysB)]) - -//--------------------------------------------------------------------------- -// Remove inference equations and abbreviations from types -//--------------------------------------------------------------------------- - -let applyTyconAbbrev abbrevTy tycon tyargs = - if isNil tyargs then abbrevTy - else instType (mkTyconInst tycon tyargs) abbrevTy - -let reduceTyconAbbrev (tycon: Tycon) tyargs = - let abbrev = tycon.TypeAbbrev - match abbrev with - | None -> invalidArg "tycon" "this type definition is not an abbreviation" - | Some abbrevTy -> - applyTyconAbbrev abbrevTy tycon tyargs - -let reduceTyconRefAbbrev (tcref: TyconRef) tyargs = - reduceTyconAbbrev tcref.Deref tyargs - -let reduceTyconMeasureableOrProvided (g: TcGlobals) (tycon: Tycon) tyargs = -#if NO_EXTENSIONTYPING - ignore g // otherwise g would be unused -#endif - let repr = tycon.TypeReprInfo - match repr with - | TMeasureableRepr ty -> - if isNil tyargs then ty else instType (mkTyconInst tycon tyargs) ty -#if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint info when info.IsErased -> info.BaseTypeForErased (range0, g.obj_ty) -#endif - | _ -> invalidArg "tc" "this type definition is not a refinement" - -let reduceTyconRefMeasureableOrProvided (g: TcGlobals) (tcref: TyconRef) tyargs = - reduceTyconMeasureableOrProvided g tcref.Deref tyargs - -let rec stripTyEqnsA g canShortcut ty = - let ty = stripTyparEqnsAux canShortcut ty - match ty with - | TType_app (tcref, tinst) -> - let tycon = tcref.Deref - match tycon.TypeAbbrev with - | Some abbrevTy -> - stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) - | None -> - // This is the point where we get to add additional conditional normalizing equations - // into the type system. Such power! - // - // Add the equation byref<'T> = byref<'T, ByRefKinds.InOut> for when using sufficient FSharp.Core - // See RFC FS-1053.md - if tyconRefEq g tcref g.byref_tcr && g.byref2_tcr.CanDeref && g.byrefkind_InOut_tcr.CanDeref then - mkByref2Ty g tinst.[0] (TType_app(g.byrefkind_InOut_tcr, [])) - - // Add the equation double<1> = double for units of measure. - elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then - stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) - else - ty - | ty -> ty - -let stripTyEqns g ty = stripTyEqnsA g false ty - -let evalTupInfoIsStruct aexpr = - match aexpr with - | TupInfo.Const b -> b - -let evalAnonInfoIsStruct (anonInfo: AnonRecdTypeInfo) = - evalTupInfoIsStruct anonInfo.TupInfo - -/// This erases outermost occurrences of inference equations, type abbreviations, non-generated provided types -/// and measureable types (float<_>). -/// It also optionally erases all "compilation representations", i.e. function and -/// tuple types, and also "nativeptr<'T> --> System.IntPtr" -let rec stripTyEqnsAndErase eraseFuncAndTuple (g: TcGlobals) ty = - let ty = stripTyEqns g ty - match ty with - | TType_app (tcref, args) -> - let tycon = tcref.Deref - if tycon.IsErased then - stripTyEqnsAndErase eraseFuncAndTuple g (reduceTyconMeasureableOrProvided g tycon args) - elif tyconRefEq g tcref g.nativeptr_tcr && eraseFuncAndTuple then - stripTyEqnsAndErase eraseFuncAndTuple g g.nativeint_ty - else - ty - | TType_fun(a, b) when eraseFuncAndTuple -> TType_app(g.fastFunc_tcr, [ a; b]) - | TType_tuple(tupInfo, l) when eraseFuncAndTuple -> mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) l - | ty -> ty - -let stripTyEqnsAndMeasureEqns g ty = - stripTyEqnsAndErase false g ty - -type Erasure = EraseAll | EraseMeasures | EraseNone - -let stripTyEqnsWrtErasure erasureFlag g ty = - match erasureFlag with - | EraseAll -> stripTyEqnsAndErase true g ty - | EraseMeasures -> stripTyEqnsAndErase false g ty - | _ -> stripTyEqns g ty - -let rec stripExnEqns (eref: TyconRef) = - let exnc = eref.Deref - match exnc.ExceptionInfo with - | TExnAbbrevRepr eref -> stripExnEqns eref - | _ -> exnc - -let primDestForallTy g ty = ty |> stripTyEqns g |> (function TType_forall (tyvs, tau) -> (tyvs, tau) | _ -> failwith "primDestForallTy: not a forall type") -let destFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> (tyv, tau) | _ -> failwith "destFunTy: not a function type") -let destAnyTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) -> tupInfo, l | _ -> failwith "destAnyTupleTy: not a tuple type") -let destRefTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) when not (evalTupInfoIsStruct tupInfo) -> l | _ -> failwith "destRefTupleTy: not a reference tuple type") -let destStructTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) when evalTupInfoIsStruct tupInfo -> l | _ -> failwith "destStructTupleTy: not a struct tuple type") -let destTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> v | _ -> failwith "destTyparTy: not a typar type") -let destAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> v | TType_measure unt -> destUnitParMeasure g unt | _ -> failwith "destAnyParTy: not a typar or unpar type") -let destMeasureTy g ty = ty |> stripTyEqns g |> (function TType_measure m -> m | _ -> failwith "destMeasureTy: not a unit-of-measure type") -let isFunTy g ty = ty |> stripTyEqns g |> (function TType_fun _ -> true | _ -> false) -let isForallTy g ty = ty |> stripTyEqns g |> (function TType_forall _ -> true | _ -> false) -let isAnyTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple _ -> true | _ -> false) -let isRefTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> not (evalTupInfoIsStruct tupInfo) | _ -> false) -let isStructTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> evalTupInfoIsStruct tupInfo | _ -> false) -let isAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon _ -> true | _ -> false) -let isStructAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, _) -> evalAnonInfoIsStruct anonInfo | _ -> false) -let isUnionTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsUnionTycon | _ -> false) -let isReprHiddenTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsHiddenReprTycon | _ -> false) -let isFSharpObjModelTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpObjectModelTycon | _ -> false) -let isRecdTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsRecordTycon | _ -> false) -let isFSharpStructOrEnumTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpStructOrEnumTycon | _ -> false) -let isFSharpEnumTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpEnumTycon | _ -> false) -let isTyparTy g ty = ty |> stripTyEqns g |> (function TType_var _ -> true | _ -> false) -let isAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var _ -> true | TType_measure unt -> isUnitParMeasure g unt | _ -> false) -let isMeasureTy g ty = ty |> stripTyEqns g |> (function TType_measure _ -> true | _ -> false) - - -let isProvenUnionCaseTy ty = match ty with TType_ucase _ -> true | _ -> false - -let mkAppTy tcref tyargs = TType_app(tcref, tyargs) -let mkProvenUnionCaseTy ucref tyargs = TType_ucase(ucref, tyargs) -let isAppTy g ty = ty |> stripTyEqns g |> (function TType_app _ -> true | _ -> false) -let tryAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> ValueSome (tcref, tinst) | _ -> ValueNone) -let destAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> tcref, tinst | _ -> failwith "destAppTy") -let tcrefOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref | _ -> failwith "tcrefOfAppTy") -let argsOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(_, tinst) -> tinst | _ -> []) -let tryDestTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | _ -> ValueNone) -let tryDestFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> ValueSome(tyv, tau) | _ -> ValueNone) -let tryDestAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> ValueSome tcref | _ -> ValueNone) -let tryDestAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, tys) -> ValueSome (anonInfo, tys) | _ -> ValueNone) - -let tryAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | TType_measure unt when isUnitParMeasure g unt -> ValueSome(destUnitParMeasure g unt) | _ -> ValueNone) -let tryAnyParTyOption g ty = ty |> stripTyEqns g |> (function TType_var v -> Some v | TType_measure unt when isUnitParMeasure g unt -> Some(destUnitParMeasure g unt) | _ -> None) -let (|AppTy|_|) g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> Some (tcref, tinst) | _ -> None) -let (|RefTupleTy|_|) g ty = ty |> stripTyEqns g |> (function TType_tuple(tupInfo, tys) when not (evalTupInfoIsStruct tupInfo) -> Some tys | _ -> None) -let (|FunTy|_|) g ty = ty |> stripTyEqns g |> (function TType_fun(dty, rty) -> Some (dty, rty) | _ -> None) - -let tryNiceEntityRefOfTy ty = - let ty = stripTyparEqnsAux false ty - match ty with - | TType_app (tcref, _) -> ValueSome tcref - | TType_measure (Measure.Con tcref) -> ValueSome tcref - | _ -> ValueNone - -let tryNiceEntityRefOfTyOption ty = - let ty = stripTyparEqnsAux false ty - match ty with - | TType_app (tcref, _) -> Some tcref - | TType_measure (Measure.Con tcref) -> Some tcref - | _ -> None - -let mkInstForAppTy g ty = - match tryAppTy g ty with - | ValueSome (tcref, tinst) -> mkTyconRefInst tcref tinst - | _ -> [] - -let domainOfFunTy g ty = fst (destFunTy g ty) -let rangeOfFunTy g ty = snd (destFunTy g ty) - -let convertToTypeWithMetadataIfPossible g ty = - if isAnyTupleTy g ty then - let (tupInfo, tupElemTys) = destAnyTupleTy g ty - mkOuterCompiledTupleTy g (evalTupInfoIsStruct tupInfo) tupElemTys - elif isFunTy g ty then - let (a,b) = destFunTy g ty - mkAppTy g.fastFunc_tcr [a; b] - else ty - -//--------------------------------------------------------------------------- -// Equivalence of types up to alpha-equivalence -//--------------------------------------------------------------------------- - - -[] -type TypeEquivEnv = - { EquivTypars: TyparMap - EquivTycons: TyconRefRemap} - -// allocate a singleton -let typeEquivEnvEmpty = - { EquivTypars = TyparMap.Empty - EquivTycons = emptyTyconRefRemap } - -type TypeEquivEnv with - static member Empty = typeEquivEnvEmpty - - member aenv.BindTyparsToTypes tps1 tys2 = - { aenv with EquivTypars = (tps1, tys2, aenv.EquivTypars) |||> List.foldBack2 (fun tp ty tpmap -> tpmap.Add(tp, ty)) } - - member aenv.BindEquivTypars tps1 tps2 = - aenv.BindTyparsToTypes tps1 (List.map mkTyparTy tps2) - - static member FromTyparInst tpinst = - let tps, tys = List.unzip tpinst - TypeEquivEnv.Empty.BindTyparsToTypes tps tys - - static member FromEquivTypars tps1 tps2 = - TypeEquivEnv.Empty.BindEquivTypars tps1 tps2 - -let rec traitsAEquivAux erasureFlag g aenv (TTrait(tys1, nm, mf1, argtys, rty, _)) (TTrait(tys2, nm2, mf2, argtys2, rty2, _)) = - mf1 = mf2 && - nm = nm2 && - ListSet.equals (typeAEquivAux erasureFlag g aenv) tys1 tys2 && - returnTypesAEquivAux erasureFlag g aenv rty rty2 && - List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) argtys argtys2 - -and returnTypesAEquivAux erasureFlag g aenv rty rty2 = - match rty, rty2 with - | None, None -> true - | Some t1, Some t2 -> typeAEquivAux erasureFlag g aenv t1 t2 - | _ -> false - - -and typarConstraintsAEquivAux erasureFlag g aenv tpc1 tpc2 = - match tpc1, tpc2 with - | TyparConstraint.CoercesTo(acty, _), - TyparConstraint.CoercesTo(fcty, _) -> - typeAEquivAux erasureFlag g aenv acty fcty - - | TyparConstraint.MayResolveMember(trait1, _), - TyparConstraint.MayResolveMember(trait2, _) -> - traitsAEquivAux erasureFlag g aenv trait1 trait2 - - | TyparConstraint.DefaultsTo(_, acty, _), - TyparConstraint.DefaultsTo(_, fcty, _) -> - typeAEquivAux erasureFlag g aenv acty fcty - - | TyparConstraint.IsEnum(uty1, _), TyparConstraint.IsEnum(uty2, _) -> - typeAEquivAux erasureFlag g aenv uty1 uty2 - - | TyparConstraint.IsDelegate(aty1, bty1, _), TyparConstraint.IsDelegate(aty2, bty2, _) -> - typeAEquivAux erasureFlag g aenv aty1 aty2 && - typeAEquivAux erasureFlag g aenv bty1 bty2 - - | TyparConstraint.SimpleChoice (tys1, _), TyparConstraint.SimpleChoice(tys2, _) -> - ListSet.equals (typeAEquivAux erasureFlag g aenv) tys1 tys2 - - | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _ - | TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _ - | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ - | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ - | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ - | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true - | _ -> false - -and typarConstraintSetsAEquivAux erasureFlag g aenv (tp1: Typar) (tp2: Typar) = - tp1.StaticReq = tp2.StaticReq && - ListSet.equals (typarConstraintsAEquivAux erasureFlag g aenv) tp1.Constraints tp2.Constraints - -and typarsAEquivAux erasureFlag g (aenv: TypeEquivEnv) tps1 tps2 = - List.length tps1 = List.length tps2 && - let aenv = aenv.BindEquivTypars tps1 tps2 - List.forall2 (typarConstraintSetsAEquivAux erasureFlag g aenv) tps1 tps2 - -and tcrefAEquiv g aenv tc1 tc2 = - tyconRefEq g tc1 tc2 || - (match aenv.EquivTycons.TryFind tc1 with Some v -> tyconRefEq g v tc2 | None -> false) - -and typeAEquivAux erasureFlag g aenv ty1 ty2 = - let ty1 = stripTyEqnsWrtErasure erasureFlag g ty1 - let ty2 = stripTyEqnsWrtErasure erasureFlag g ty2 - match ty1, ty2 with - | TType_forall(tps1, rty1), TType_forall(tps2, rty2) -> - typarsAEquivAux erasureFlag g aenv tps1 tps2 && typeAEquivAux erasureFlag g (aenv.BindEquivTypars tps1 tps2) rty1 rty2 - | TType_var tp1, TType_var tp2 when typarEq tp1 tp2 -> - true - | TType_var tp1, _ -> - match aenv.EquivTypars.TryFind tp1 with - | Some v -> typeEquivAux erasureFlag g v ty2 - | None -> false - | TType_app (tc1, b1), TType_app (tc2, b2) -> - tcrefAEquiv g aenv tc1 tc2 && - typesAEquivAux erasureFlag g aenv b1 b2 - | TType_ucase (UCRef(tc1, n1), b1), TType_ucase (UCRef(tc2, n2), b2) -> - n1=n2 && - tcrefAEquiv g aenv tc1 tc2 && - typesAEquivAux erasureFlag g aenv b1 b2 - | TType_tuple (s1, l1), TType_tuple (s2, l2) -> - structnessAEquiv s1 s2 && typesAEquivAux erasureFlag g aenv l1 l2 - | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> - anonInfoEquiv anonInfo1 anonInfo2 && - typesAEquivAux erasureFlag g aenv l1 l2 - | TType_fun (dtys1, rty1), TType_fun (dtys2, rty2) -> - typeAEquivAux erasureFlag g aenv dtys1 dtys2 && typeAEquivAux erasureFlag g aenv rty1 rty2 - | TType_measure m1, TType_measure m2 -> - match erasureFlag with - | EraseNone -> measureAEquiv g aenv m1 m2 - | _ -> true - | _ -> false - - -and anonInfoEquiv (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = - ccuEq anonInfo1.Assembly anonInfo2.Assembly && - structnessAEquiv anonInfo1.TupInfo anonInfo2.TupInfo && - anonInfo1.SortedNames = anonInfo2.SortedNames - -and structnessAEquiv un1 un2 = - match un1, un2 with - | TupInfo.Const b1, TupInfo.Const b2 -> (b1 = b2) - -and measureAEquiv g aenv un1 un2 = - let vars1 = ListMeasureVarOccs un1 - let trans tp1 = if aenv.EquivTypars.ContainsKey tp1 then destAnyParTy g aenv.EquivTypars.[tp1] else tp1 - let remapTyconRef tc = if aenv.EquivTycons.ContainsKey tc then aenv.EquivTycons.[tc] else tc - let vars1' = List.map trans vars1 - let vars2 = ListSet.subtract typarEq (ListMeasureVarOccs un2) vars1' - let cons1 = ListMeasureConOccsAfterRemapping g remapTyconRef un1 - let cons2 = ListMeasureConOccsAfterRemapping g remapTyconRef un2 - - List.forall (fun v -> MeasureVarExponent v un1 = MeasureVarExponent (trans v) un2) vars1 && - List.forall (fun v -> MeasureVarExponent v un1 = MeasureVarExponent v un2) vars2 && - List.forall (fun c -> MeasureConExponentAfterRemapping g remapTyconRef c un1 = MeasureConExponentAfterRemapping g remapTyconRef c un2) (cons1@cons2) - - -and typesAEquivAux erasureFlag g aenv l1 l2 = List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) l1 l2 -and typeEquivAux erasureFlag g ty1 ty2 = typeAEquivAux erasureFlag g TypeEquivEnv.Empty ty1 ty2 - -let typeAEquiv g aenv ty1 ty2 = typeAEquivAux EraseNone g aenv ty1 ty2 -let typeEquiv g ty1 ty2 = typeEquivAux EraseNone g ty1 ty2 -let traitsAEquiv g aenv t1 t2 = traitsAEquivAux EraseNone g aenv t1 t2 -let typarConstraintsAEquiv g aenv c1 c2 = typarConstraintsAEquivAux EraseNone g aenv c1 c2 -let typarsAEquiv g aenv d1 d2 = typarsAEquivAux EraseNone g aenv d1 d2 -let returnTypesAEquiv g aenv t1 t2 = returnTypesAEquivAux EraseNone g aenv t1 t2 - -let measureEquiv g m1 m2 = measureAEquiv g TypeEquivEnv.Empty m1 m2 - -let isErasedType g ty = - match stripTyEqns g ty with -#if !NO_EXTENSIONTYPING - | TType_app (tcref, _) -> tcref.IsProvidedErasedTycon -#endif - | _ -> false - -// Return all components of this type expression that cannot be tested at runtime -let rec getErasedTypes g ty = - let ty = stripTyEqns g ty - if isErasedType g ty then [ty] else - match ty with - | TType_forall(_, rty) -> - getErasedTypes g rty - | TType_var tp -> - if tp.IsErased then [ty] else [] - | TType_app (_, b) | TType_ucase(_, b) | TType_anon (_, b) | TType_tuple (_, b) -> - List.foldBack (fun ty tys -> getErasedTypes g ty @ tys) b [] - | TType_fun (dty, rty) -> - getErasedTypes g dty @ getErasedTypes g rty - | TType_measure _ -> - [ty] - - -//--------------------------------------------------------------------------- -// Standard orderings, e.g. for order set/map keys -//--------------------------------------------------------------------------- - -let valOrder = { new IComparer with member __.Compare(v1, v2) = compare v1.Stamp v2.Stamp } -let tyconOrder = { new IComparer with member __.Compare(tc1, tc2) = compare tc1.Stamp tc2.Stamp } -let recdFieldRefOrder = - { new IComparer with - member __.Compare(RFRef(tcref1, nm1), RFRef(tcref2, nm2)) = - let c = tyconOrder.Compare (tcref1.Deref, tcref2.Deref) - if c <> 0 then c else - compare nm1 nm2 } - -let unionCaseRefOrder = - { new IComparer with - member __.Compare(UCRef(tcref1, nm1), UCRef(tcref2, nm2)) = - let c = tyconOrder.Compare (tcref1.Deref, tcref2.Deref) - if c <> 0 then c else - compare nm1 nm2 } - -//--------------------------------------------------------------------------- -// Make some common types -//--------------------------------------------------------------------------- - -let mkFunTy d r = TType_fun (d, r) - -let (-->) d r = mkFunTy d r - -let mkForallTy d r = TType_forall (d, r) - -let mkForallTyIfNeeded d r = if isNil d then r else mkForallTy d r - -let (+->) d r = mkForallTyIfNeeded d r - -let mkIteratedFunTy dl r = List.foldBack (-->) dl r - -let mkLambdaArgTy m tys = - match tys with - | [] -> error(InternalError("mkLambdaArgTy", m)) - | [h] -> h - | _ -> mkRawRefTupleTy tys - -let typeOfLambdaArg m vs = mkLambdaArgTy m (typesOfVals vs) -let mkMultiLambdaTy m vs rty = mkFunTy (typeOfLambdaArg m vs) rty -let mkLambdaTy tps tys rty = mkForallTyIfNeeded tps (mkIteratedFunTy tys rty) - -/// When compiling FSharp.Core.dll we have to deal with the non-local references into -/// the library arising from env.fs. Part of this means that we have to be able to resolve these -/// references. This function artificially forces the existence of a module or namespace at a -/// particular point in order to do this. -let ensureCcuHasModuleOrNamespaceAtPath (ccu: CcuThunk) path (CompPath(_, cpath)) xml = - let scoref = ccu.ILScopeRef - let rec loop prior_cpath (path: Ident list) cpath (modul: ModuleOrNamespace) = - let mtype = modul.ModuleOrNamespaceType - match path, cpath with - | (hpath :: tpath), ((_, mkind) :: tcpath) -> - let modName = hpath.idText - if not (Map.containsKey modName mtype.AllEntitiesByCompiledAndLogicalMangledNames) then - let smodul = NewModuleOrNamespace (Some(CompPath(scoref, prior_cpath))) taccessPublic hpath xml [] (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType mkind)) - mtype.AddModuleOrNamespaceByMutation smodul - let modul = Map.find modName mtype.AllEntitiesByCompiledAndLogicalMangledNames - loop (prior_cpath@[(modName, Namespace)]) tpath tcpath modul - - | _ -> () - - loop [] path cpath ccu.Contents - - -//--------------------------------------------------------------------------- -// Primitive destructors -//--------------------------------------------------------------------------- - -/// Look through the Expr.Link nodes arising from type inference -let rec stripExpr e = - match e with - | Expr.Link eref -> stripExpr !eref - | _ -> e - -let mkCase (a, b) = TCase(a, b) - -let isRefTupleExpr e = match e with Expr.Op (TOp.Tuple tupInfo, _, _, _) -> not (evalTupInfoIsStruct tupInfo) | _ -> false -let tryDestRefTupleExpr e = match e with Expr.Op (TOp.Tuple tupInfo, _, es, _) when not (evalTupInfoIsStruct tupInfo) -> es | _ -> [e] - -//--------------------------------------------------------------------------- -// Range info for expressions -//--------------------------------------------------------------------------- - -let rec rangeOfExpr x = - match x with - | Expr.Val (_, _, m) | Expr.Op (_, _, _, m) | Expr.Const (_, m, _) | Expr.Quote (_, _, _, m, _) - | Expr.Obj (_, _, _, _, _, _, m) | Expr.App (_, _, _, _, m) | Expr.Sequential (_, _, _, _, m) - | Expr.StaticOptimization (_, _, _, m) | Expr.Lambda (_, _, _, _, _, m, _) - | Expr.TyLambda (_, _, _, m, _)| Expr.TyChoose (_, _, m) | Expr.LetRec (_, _, m, _) | Expr.Let (_, _, m, _) | Expr.Match (_, _, _, _, m, _) -> m - | Expr.Link eref -> rangeOfExpr (!eref) - -type Expr with - member x.Range = rangeOfExpr x - -//--------------------------------------------------------------------------- -// Build nodes in decision graphs -//--------------------------------------------------------------------------- - - -let primMkMatch(spBind, exprm, tree, targets, matchm, ty) = Expr.Match (spBind, exprm, tree, targets, matchm, ty) - -type MatchBuilder(spBind, inpRange: Range.range) = - - let targets = new ResizeArray<_>(10) - member x.AddTarget tg = - let n = targets.Count - targets.Add tg - n - - member x.AddResultTarget(e, spTarget) = TDSuccess([], x.AddTarget(TTarget([], e, spTarget))) - - member x.CloseTargets() = targets |> ResizeArray.toList - - member x.Close(dtree, m, ty) = primMkMatch (spBind, inpRange, dtree, targets.ToArray(), m, ty) - -let mkBoolSwitch m g t e = TDSwitch(g, [TCase(DecisionTreeTest.Const(Const.Bool true), t)], Some e, m) - -let primMkCond spBind spTarget1 spTarget2 m ty e1 e2 e3 = - let mbuilder = new MatchBuilder(spBind, m) - let dtree = mkBoolSwitch m e1 (mbuilder.AddResultTarget(e2, spTarget1)) (mbuilder.AddResultTarget(e3, spTarget2)) - mbuilder.Close(dtree, m, ty) - -let mkCond spBind spTarget m ty e1 e2 e3 = primMkCond spBind spTarget spTarget m ty e1 e2 e3 - - -//--------------------------------------------------------------------------- -// Primitive constructors -//--------------------------------------------------------------------------- - -let exprForValRef m vref = Expr.Val (vref, NormalValUse, m) -let exprForVal m v = exprForValRef m (mkLocalValRef v) -let mkLocalAux m s ty mut compgen = - let thisv = NewVal(s, m, None, ty, mut, compgen, None, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) - thisv, exprForVal m thisv - -let mkLocal m s ty = mkLocalAux m s ty Immutable false -let mkCompGenLocal m s ty = mkLocalAux m s ty Immutable true -let mkMutableCompGenLocal m s ty = mkLocalAux m s ty Mutable true - - -// Type gives return type. For type-lambdas this is the formal return type. -let mkMultiLambda m vs (b, rty) = Expr.Lambda (newUnique(), None, None, vs, b, m, rty) -let rebuildLambda m ctorThisValOpt baseValOpt vs (b, rty) = Expr.Lambda (newUnique(), ctorThisValOpt, baseValOpt, vs, b, m, rty) -let mkLambda m v (b, rty) = mkMultiLambda m [v] (b, rty) -let mkTypeLambda m vs (b, tau_ty) = match vs with [] -> b | _ -> Expr.TyLambda (newUnique(), vs, b, m, tau_ty) -let mkTypeChoose m vs b = match vs with [] -> b | _ -> Expr.TyChoose (vs, b, m) - -let mkObjExpr (ty, basev, basecall, overrides, iimpls, m) = - Expr.Obj (newUnique(), ty, basev, basecall, overrides, iimpls, m) - -let mkLambdas m tps (vs: Val list) (b, rty) = - mkTypeLambda m tps (List.foldBack (fun v (e, ty) -> mkLambda m v (e, ty), v.Type --> ty) vs (b, rty)) - -let mkMultiLambdasCore m vsl (b, rty) = - List.foldBack (fun v (e, ty) -> mkMultiLambda m v (e, ty), typeOfLambdaArg m v --> ty) vsl (b, rty) - -let mkMultiLambdas m tps vsl (b, rty) = - mkTypeLambda m tps (mkMultiLambdasCore m vsl (b, rty) ) - -let mkMemberLambdas m tps ctorThisValOpt baseValOpt vsl (b, rty) = - let expr = - match ctorThisValOpt, baseValOpt with - | None, None -> mkMultiLambdasCore m vsl (b, rty) - | _ -> - match vsl with - | [] -> error(InternalError("mk_basev_multi_lambdas_core: can't attach a basev to a non-lambda expression", m)) - | h :: t -> - let b, rty = mkMultiLambdasCore m t (b, rty) - (rebuildLambda m ctorThisValOpt baseValOpt h (b, rty), (typeOfLambdaArg m h --> rty)) - mkTypeLambda m tps expr - -let mkMultiLambdaBind v letSeqPtOpt m tps vsl (b, rty) = - TBind(v, mkMultiLambdas m tps vsl (b, rty), letSeqPtOpt) - -let mkBind seqPtOpt v e = TBind(v, e, seqPtOpt) - -let mkLetBind m bind body = Expr.Let (bind, body, m, NewFreeVarsCache()) -let mkLetsBind m binds body = List.foldBack (mkLetBind m) binds body -let mkLetsFromBindings m binds body = List.foldBack (mkLetBind m) binds body -let mkLet seqPtOpt m v x body = mkLetBind m (mkBind seqPtOpt v x) body - -/// Make sticky bindings that are compiler generated (though the variables may not be - e.g. they may be lambda arguments in a beta reduction) -let mkCompGenBind v e = TBind(v, e, NoSequencePointAtStickyBinding) -let mkCompGenBinds (vs: Val list) (es: Expr list) = List.map2 mkCompGenBind vs es -let mkCompGenLet m v x body = mkLetBind m (mkCompGenBind v x) body -let mkCompGenLets m vs xs body = mkLetsBind m (mkCompGenBinds vs xs) body -let mkCompGenLetsFromBindings m vs xs body = mkLetsFromBindings m (mkCompGenBinds vs xs) body - -let mkInvisibleBind v e = TBind(v, e, NoSequencePointAtInvisibleBinding) -let mkInvisibleBinds (vs: Val list) (es: Expr list) = List.map2 mkInvisibleBind vs es -let mkInvisibleLet m v x body = mkLetBind m (mkInvisibleBind v x) body -let mkInvisibleLets m vs xs body = mkLetsBind m (mkInvisibleBinds vs xs) body -let mkInvisibleLetsFromBindings m vs xs body = mkLetsFromBindings m (mkInvisibleBinds vs xs) body - -let mkLetRecBinds m binds body = if isNil binds then body else Expr.LetRec (binds, body, m, NewFreeVarsCache()) - -//------------------------------------------------------------------------- -// Type schemes... -//------------------------------------------------------------------------- - -// Type parameters may be have been equated to other tps in equi-recursive type inference -// and unit type inference. Normalize them here -let NormalizeDeclaredTyparsForEquiRecursiveInference g tps = - match tps with - | [] -> [] - | tps -> - tps |> List.map (fun tp -> - let ty = mkTyparTy tp - match tryAnyParTy g ty with - | ValueSome anyParTy -> anyParTy - | ValueNone -> tp) - -type TypeScheme = TypeScheme of Typars * TType - -let mkGenericBindRhs g m generalizedTyparsForRecursiveBlock typeScheme bodyExpr = - let (TypeScheme(generalizedTypars, tauType)) = typeScheme - - // Normalize the generalized typars - let generalizedTypars = NormalizeDeclaredTyparsForEquiRecursiveInference g generalizedTypars - - // Some recursive bindings result in free type variables, e.g. - // let rec f (x:'a) = () - // and g() = f y |> ignore - // What is the type of y? Type inference equates it to 'a. - // But "g" is not polymorphic in 'a. Hence we get a free choice of "'a" - // in the scope of "g". Thus at each individual recursive binding we record all - // type variables for which we have a free choice, which is precisely the difference - // between the union of all sets of generalized type variables and the set generalized - // at each particular binding. - // - // We record an expression node that indicates that a free choice can be made - // for these. This expression node effectively binds the type variables. - let freeChoiceTypars = ListSet.subtract typarEq generalizedTyparsForRecursiveBlock generalizedTypars - mkTypeLambda m generalizedTypars (mkTypeChoose m freeChoiceTypars bodyExpr, tauType) - -let isBeingGeneralized tp typeScheme = - let (TypeScheme(generalizedTypars, _)) = typeScheme - ListSet.contains typarRefEq tp generalizedTypars - -//------------------------------------------------------------------------- -// Build conditional expressions... -//------------------------------------------------------------------------- - -let mkLazyAnd (g: TcGlobals) m e1 e2 = mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.bool_ty e1 e2 (Expr.Const (Const.Bool false, m, g.bool_ty)) -let mkLazyOr (g: TcGlobals) m e1 e2 = mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.bool_ty e1 (Expr.Const (Const.Bool true, m, g.bool_ty)) e2 - -let mkCoerceExpr(e, to_ty, m, from_ty) = Expr.Op (TOp.Coerce, [to_ty;from_ty], [e], m) - -let mkAsmExpr (code, tinst, args, rettys, m) = Expr.Op (TOp.ILAsm (code, rettys), tinst, args, m) -let mkUnionCaseExpr(uc, tinst, args, m) = Expr.Op (TOp.UnionCase uc, tinst, args, m) -let mkExnExpr(uc, args, m) = Expr.Op (TOp.ExnConstr uc, [], args, m) -let mkTupleFieldGetViaExprAddr(tupInfo, e, tinst, i, m) = Expr.Op (TOp.TupleFieldGet (tupInfo, i), tinst, [e], m) -let mkAnonRecdFieldGetViaExprAddr(anonInfo, e, tinst, i, m) = Expr.Op (TOp.AnonRecdGet (anonInfo, i), tinst, [e], m) - -let mkRecdFieldGetViaExprAddr (e, fref, tinst, m) = Expr.Op (TOp.ValFieldGet fref, tinst, [e], m) -let mkRecdFieldGetAddrViaExprAddr(readonly, e, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr (fref, readonly), tinst, [e], m) - -let mkStaticRecdFieldGetAddr(readonly, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr (fref, readonly), tinst, [], m) -let mkStaticRecdFieldGet (fref, tinst, m) = Expr.Op (TOp.ValFieldGet fref, tinst, [], m) -let mkStaticRecdFieldSet(fref, tinst, e, m) = Expr.Op (TOp.ValFieldSet fref, tinst, [e], m) - -let mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, exprs, m) = - Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTyWithFlag g readonly elemTy]), [elemTy], exprs, m) - -let mkRecdFieldSetViaExprAddr (e1, fref, tinst, e2, m) = Expr.Op (TOp.ValFieldSet fref, tinst, [e1;e2], m) - -let mkUnionCaseTagGetViaExprAddr (e1, cref, tinst, m) = Expr.Op (TOp.UnionCaseTagGet cref, tinst, [e1], m) - -/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) -let mkUnionCaseProof (e1, cref: UnionCaseRef, tinst, m) = if cref.Tycon.IsStructOrEnumTycon then e1 else Expr.Op (TOp.UnionCaseProof cref, tinst, [e1], m) - -/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions, -/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -let mkUnionCaseFieldGetProvenViaExprAddr (e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGet (cref, j), tinst, [e1], m) - -/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, -/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -let mkUnionCaseFieldGetAddrProvenViaExprAddr (readonly, e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGetAddr (cref, j, readonly), tinst, [e1], m) - -/// Build a 'get' expression for something we've already determined to be a particular union case, but where -/// the static type of the input is not yet proven to be that particular union case. This requires a type -/// cast to 'prove' the condition. -let mkUnionCaseFieldGetUnprovenViaExprAddr (e1, cref, tinst, j, m) = mkUnionCaseFieldGetProvenViaExprAddr (mkUnionCaseProof(e1, cref, tinst, m), cref, tinst, j, m) - -let mkUnionCaseFieldSet (e1, cref, tinst, j, e2, m) = Expr.Op (TOp.UnionCaseFieldSet (cref, j), tinst, [e1;e2], m) - -let mkExnCaseFieldGet (e1, ecref, j, m) = Expr.Op (TOp.ExnFieldGet (ecref, j), [], [e1], m) -let mkExnCaseFieldSet (e1, ecref, j, e2, m) = Expr.Op (TOp.ExnFieldSet (ecref, j), [], [e1;e2], m) - -let mkDummyLambda (g: TcGlobals) (e: Expr, ety) = - let m = e.Range - mkLambda m (fst (mkCompGenLocal m "unitVar" g.unit_ty)) (e, ety) - -let mkWhile (g: TcGlobals) (spWhile, marker, e1, e2, m) = - Expr.Op (TOp.While (spWhile, marker), [], [mkDummyLambda g (e1, g.bool_ty);mkDummyLambda g (e2, g.unit_ty)], m) - -let mkFor (g: TcGlobals) (spFor, v, e1, dir, e2, e3: Expr, m) = - Expr.Op (TOp.For (spFor, dir), [], [mkDummyLambda g (e1, g.int_ty) ;mkDummyLambda g (e2, g.int_ty);mkLambda e3.Range v (e3, g.unit_ty)], m) - -let mkTryWith g (e1, vf, ef: Expr, vh, eh: Expr, m, ty, spTry, spWith) = - Expr.Op (TOp.TryCatch (spTry, spWith), [ty], [mkDummyLambda g (e1, ty);mkLambda ef.Range vf (ef, ty);mkLambda eh.Range vh (eh, ty)], m) - -let mkTryFinally (g: TcGlobals) (e1, e2, m, ty, spTry, spFinally) = - Expr.Op (TOp.TryFinally (spTry, spFinally), [ty], [mkDummyLambda g (e1, ty);mkDummyLambda g (e2, g.unit_ty)], m) - -let mkDefault (m, ty) = Expr.Const (Const.Zero, m, ty) - -let mkValSet m v e = Expr.Op (TOp.LValueOp (LSet, v), [], [e], m) -let mkAddrSet m v e = Expr.Op (TOp.LValueOp (LByrefSet, v), [], [e], m) -let mkAddrGet m v = Expr.Op (TOp.LValueOp (LByrefGet, v), [], [], m) -let mkValAddr m readonly v = Expr.Op (TOp.LValueOp (LAddrOf readonly, v), [], [], m) - -//-------------------------------------------------------------------------- -// Maps tracking extra information for values -//-------------------------------------------------------------------------- - -[] -type ValHash<'T> = - | ValHash of Dictionary - - member ht.Values = - let (ValHash t) = ht - t.Values :> seq<'T> - - member ht.TryFind (v: Val) = - let (ValHash t) = ht - match t.TryGetValue v.Stamp with - | true, v -> Some v - | _ -> None - - member ht.Add (v: Val, x) = - let (ValHash t) = ht - t.[v.Stamp] <- x - - static member Create() = ValHash (new Dictionary<_, 'T>(11)) - -[] -type ValMultiMap<'T>(contents: StampMap<'T list>) = - - member m.ContainsKey (v: Val) = - contents.ContainsKey v.Stamp - - member m.Find (v: Val) = - match contents |> Map.tryFind v.Stamp with - | Some vals -> vals - | _ -> [] - - member m.Add (v: Val, x) = ValMultiMap<'T>(contents.Add (v.Stamp, x :: m.Find v)) - - member m.Remove (v: Val) = ValMultiMap<'T>(contents.Remove v.Stamp) - - member m.Contents = contents - - static member Empty = ValMultiMap<'T>(Map.empty) - -[] -type TyconRefMultiMap<'T>(contents: TyconRefMap<'T list>) = - member m.Find v = - match contents.TryFind v with - | Some vals -> vals - | _ -> [] - - member m.Add (v, x) = TyconRefMultiMap<'T>(contents.Add v (x :: m.Find v)) - static member Empty = TyconRefMultiMap<'T>(TyconRefMap<_>.Empty) - static member OfList vs = (vs, TyconRefMultiMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add (x, y)) - - -//-------------------------------------------------------------------------- -// From Ref_private to Ref_nonlocal when exporting data. -//-------------------------------------------------------------------------- - -/// Try to create a EntityRef suitable for accessing the given Entity from another assembly -let tryRescopeEntity viewedCcu (entity: Entity) : ValueOption = - match entity.PublicPath with - | Some pubpath -> ValueSome (ERefNonLocal (rescopePubPath viewedCcu pubpath)) - | None -> ValueNone - -/// Try to create a ValRef suitable for accessing the given Val from another assembly -let tryRescopeVal viewedCcu (entityRemap: Remap) (vspec: Val) : ValueOption = - match vspec.PublicPath with - | Some (ValPubPath(p, fullLinkageKey)) -> - // The type information in the val linkage doesn't need to keep any information to trait solutions. - let entityRemap = { entityRemap with removeTraitSolutions = true } - let fullLinkageKey = remapValLinkage entityRemap fullLinkageKey - let vref = - // This compensates for the somewhat poor design decision in the F# compiler and metadata where - // members are stored as values under the enclosing namespace/module rather than under the type. - // This stems from the days when types and namespace/modules were separated constructs in the - // compiler implementation. - if vspec.IsIntrinsicMember then - mkNonLocalValRef (rescopePubPathToParent viewedCcu p) fullLinkageKey - else - mkNonLocalValRef (rescopePubPath viewedCcu p) fullLinkageKey - ValueSome vref - | _ -> ValueNone - -//--------------------------------------------------------------------------- -// Type information about records, constructors etc. -//--------------------------------------------------------------------------- - -let actualTyOfRecdField inst (fspec: RecdField) = instType inst fspec.FormalType - -let actualTysOfRecdFields inst rfields = List.map (actualTyOfRecdField inst) rfields - -let actualTysOfInstanceRecdFields inst (tcref: TyconRef) = tcref.AllInstanceFieldsAsList |> actualTysOfRecdFields inst - -let actualTysOfUnionCaseFields inst (x: UnionCaseRef) = actualTysOfRecdFields inst x.AllFieldsAsList - -let actualResultTyOfUnionCase tinst (x: UnionCaseRef) = - instType (mkTyconRefInst x.TyconRef tinst) x.ReturnType - -let recdFieldsOfExnDefRef x = (stripExnEqns x).TrueInstanceFieldsAsList -let recdFieldOfExnDefRefByIdx x n = (stripExnEqns x).GetFieldByIndex n - -let recdFieldTysOfExnDefRef x = actualTysOfRecdFields [] (recdFieldsOfExnDefRef x) -let recdFieldTyOfExnDefRefByIdx x j = actualTyOfRecdField [] (recdFieldOfExnDefRefByIdx x j) - - -let actualTyOfRecdFieldForTycon tycon tinst (fspec: RecdField) = - instType (mkTyconInst tycon tinst) fspec.FormalType - -let actualTyOfRecdFieldRef (fref: RecdFieldRef) tinst = - actualTyOfRecdFieldForTycon fref.Tycon tinst fref.RecdField - -let actualTyOfUnionFieldRef (fref: UnionCaseRef) n tinst = - actualTyOfRecdFieldForTycon fref.Tycon tinst (fref.FieldByIndex n) - - -//--------------------------------------------------------------------------- -// Apply type functions to types -//--------------------------------------------------------------------------- - -let destForallTy g ty = - let tps, tau = primDestForallTy g ty - // tps may be have been equated to other tps in equi-recursive type inference - // and unit type inference. Normalize them here - let tps = NormalizeDeclaredTyparsForEquiRecursiveInference g tps - tps, tau - -let tryDestForallTy g ty = - if isForallTy g ty then destForallTy g ty else [], ty - -let rec stripFunTy g ty = - if isFunTy g ty then - let (d, r) = destFunTy g ty - let more, rty = stripFunTy g r - d :: more, rty - else [], ty - -let applyForallTy g ty tyargs = - let tps, tau = destForallTy g ty - instType (mkTyparInst tps tyargs) tau - -let reduceIteratedFunTy g ty args = - List.fold (fun ty _ -> - if not (isFunTy g ty) then failwith "reduceIteratedFunTy" - snd (destFunTy g ty)) ty args - -let applyTyArgs g functy tyargs = - if isForallTy g functy then applyForallTy g functy tyargs else functy - -let applyTys g functy (tyargs, argtys) = - let afterTyappTy = applyTyArgs g functy tyargs - reduceIteratedFunTy g afterTyappTy argtys - -let formalApplyTys g functy (tyargs, args) = - reduceIteratedFunTy g - (if isNil tyargs then functy else snd (destForallTy g functy)) - args - -let rec stripFunTyN g n ty = - assert (n >= 0) - if n > 0 && isFunTy g ty then - let (d, r) = destFunTy g ty - let more, rty = stripFunTyN g (n-1) r in d :: more, rty - else [], ty - - -let tryDestAnyTupleTy g ty = - if isAnyTupleTy g ty then destAnyTupleTy g ty else tupInfoRef, [ty] - -let tryDestRefTupleTy g ty = - if isRefTupleTy g ty then destRefTupleTy g ty else [ty] - -type UncurriedArgInfos = (TType * ArgReprInfo) list -type CurriedArgInfos = (TType * ArgReprInfo) list list - -// A 'tau' type is one with its type parameters stripped off -let GetTopTauTypeInFSharpForm g (curriedArgInfos: ArgReprInfo list list) tau m = - let nArgInfos = curriedArgInfos.Length - let argtys, rty = stripFunTyN g nArgInfos tau - if nArgInfos <> argtys.Length then - error(Error(FSComp.SR.tastInvalidMemberSignature(), m)) - let argtysl = - (curriedArgInfos, argtys) ||> List.map2 (fun argInfos argty -> - match argInfos with - | [] -> [ (g.unit_ty, ValReprInfo.unnamedTopArg1) ] - | [argInfo] -> [ (argty, argInfo) ] - | _ -> List.zip (destRefTupleTy g argty) argInfos) - argtysl, rty - -let destTopForallTy g (ValReprInfo (ntps, _, _)) ty = - let tps, tau = (if isNil ntps then [], ty else tryDestForallTy g ty) -#if CHECKED - if tps.Length <> kinds.Length then failwith (sprintf "destTopForallTy: internal error, #tps = %d, #ntps = %d" (List.length tps) ntps) -#endif - // tps may be have been equated to other tps in equi-recursive type inference. Normalize them here - let tps = NormalizeDeclaredTyparsForEquiRecursiveInference g tps - tps, tau - -let GetTopValTypeInFSharpForm g (ValReprInfo(_, argInfos, retInfo) as topValInfo) ty m = - let tps, tau = destTopForallTy g topValInfo ty - let curriedArgTys, returnTy = GetTopTauTypeInFSharpForm g argInfos tau m - tps, curriedArgTys, returnTy, retInfo - -let IsCompiledAsStaticProperty g (v: Val) = - match v.ValReprInfo with - | Some valReprInfoValue -> - match GetTopValTypeInFSharpForm g valReprInfoValue v.Type v.Range with - | [], [], _, _ when not v.IsMember -> true - | _ -> false - | _ -> false - -let IsCompiledAsStaticPropertyWithField g (v: Val) = - (not v.IsCompiledAsStaticPropertyWithoutField && IsCompiledAsStaticProperty g v) - -//------------------------------------------------------------------------- -// Multi-dimensional array types... -//------------------------------------------------------------------------- - -let isArrayTyconRef (g: TcGlobals) tcref = - g.il_arr_tcr_map - |> Array.exists (tyconRefEq g tcref) - -let rankOfArrayTyconRef (g: TcGlobals) tcref = - match g.il_arr_tcr_map |> Array.tryFindIndex (tyconRefEq g tcref) with - | Some idx -> - idx + 1 - | None -> - failwith "rankOfArrayTyconRef: unsupported array rank" - -//------------------------------------------------------------------------- -// Misc functions on F# types -//------------------------------------------------------------------------- - -let destArrayTy (g: TcGlobals) ty = - match tryAppTy g ty with - | ValueSome (tcref, [ty]) when isArrayTyconRef g tcref -> ty - | _ -> failwith "destArrayTy" - -let destListTy (g: TcGlobals) ty = - match tryAppTy g ty with - | ValueSome (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty - | _ -> failwith "destListTy" - -let tyconRefEqOpt g tcOpt tc = - match tcOpt with - | None -> false - | Some tc2 -> tyconRefEq g tc2 tc - -let isStringTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.system_String_tcref | _ -> false) -let isListTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.list_tcr_canon | _ -> false) -let isArrayTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isArrayTyconRef g tcref | _ -> false) -let isArray1DTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.il_arr_tcr_map.[0] | _ -> false) -let isUnitTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.unit_tcr_canon tcref | _ -> false) -let isObjTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Object_tcref tcref | _ -> false) -let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Void_tcref tcref | _ -> false) -let isILAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsILTycon | _ -> false) -let isNativePtrTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.nativeptr_tcr tcref | _ -> false) - -let isByrefTy g ty = - ty |> stripTyEqns g |> (function - | TType_app(tcref, _) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref - | TType_app(tcref, _) -> tyconRefEq g g.byref_tcr tcref - | _ -> false) - -let isInByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_In_tcr tcref | _ -> false) -let isInByrefTy g ty = - ty |> stripTyEqns g |> (function - | TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isInByrefTag g tag - | _ -> false) - -let isOutByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_Out_tcr tcref | _ -> false) -let isOutByrefTy g ty = - ty |> stripTyEqns g |> (function - | TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isOutByrefTag g tag - | _ -> false) - -#if !NO_EXTENSIONTYPING -let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr) -#endif - -type TypeDefMetadata = - | ILTypeMetadata of TILObjectReprData - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata of TProvidedTypeInfo -#endif - -let metadataOfTycon (tycon: Tycon) = -#if !NO_EXTENSIONTYPING - match tycon.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> ProvidedTypeMetadata info - | _ -> -#endif - if tycon.IsILTycon then - ILTypeMetadata tycon.ILTyconInfo - else - FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata - - -let metadataOfTy g ty = -#if !NO_EXTENSIONTYPING - match extensionInfoOfTy g ty with - | TProvidedTypeExtensionPoint info -> ProvidedTypeMetadata info - | _ -> -#endif - if isILAppTy g ty then - let tcref = tcrefOfAppTy g ty - ILTypeMetadata tcref.ILTyconInfo - else - FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata - - -let isILReferenceTy g ty = - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> not info.IsStructOrEnum -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> not td.IsStructOrEnum - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isArrayTy g ty - -let isILInterfaceTycon (tycon: Tycon) = - match metadataOfTycon tycon with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> info.IsInterface -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsInterface - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> false - -let rankOfArrayTy g ty = rankOfArrayTyconRef g (tcrefOfAppTy g ty) - -let isFSharpObjModelRefTy g ty = - isFSharpObjModelTy g ty && - let tcref = tcrefOfAppTy g ty - match tcref.FSharpObjectModelTypeInfo.fsobjmodel_kind with - | TTyconClass | TTyconInterface | TTyconDelegate _ -> true - | TTyconStruct | TTyconEnum -> false - -let isFSharpClassTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsFSharpClassTycon - | _ -> false - -let isFSharpStructTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsFSharpStructOrEnumTycon - | _ -> false - -let isFSharpInterfaceTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsFSharpInterfaceTycon - | _ -> false - -let isDelegateTy g ty = - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> info.IsDelegate () -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsDelegate - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsFSharpDelegateTycon - | _ -> false - -let isInterfaceTy g ty = - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> info.IsInterface -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsInterface - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isFSharpInterfaceTy g ty - -let isClassTy g ty = - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> info.IsClass -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsClass - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isFSharpClassTy g ty - -let isStructOrEnumTyconTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsStructOrEnumTycon - | _ -> false - -let isStructRecordOrUnionTyconTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tcref.Deref.IsStructRecordOrUnionTycon - | _ -> false - -let isStructTyconRef (tcref: TyconRef) = - let tycon = tcref.Deref - tycon.IsStructRecordOrUnionTycon || tycon.IsStructOrEnumTycon - -let isStructTy g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> - isStructTyconRef tcref - | _ -> - isStructAnonRecdTy g ty || isStructTupleTy g ty - -let isRefTy g ty = - not (isStructOrEnumTyconTy g ty) && - ( - isUnionTy g ty || - isRefTupleTy g ty || - isRecdTy g ty || - isILReferenceTy g ty || - isFunTy g ty || - isReprHiddenTy g ty || - isFSharpObjModelRefTy g ty || - isUnitTy g ty || - (isAnonRecdTy g ty && not (isStructAnonRecdTy g ty)) - ) - -// ECMA C# LANGUAGE SPECIFICATION, 27.2 -// An unmanaged-type is any type that isn't a reference-type, a type-parameter, or a generic struct-type and -// contains no fields whose type is not an unmanaged-type. In other words, an unmanaged-type is one of the -// following: -// - sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool. -// - Any enum-type. -// - Any pointer-type. -// - Any non-generic user-defined struct-type that contains fields of unmanaged-types only. -// [Note: Constructed types and type-parameters are never unmanaged-types. end note] -let rec isUnmanagedTy g ty = - let ty = stripTyEqnsAndMeasureEqns g ty - match tryDestAppTy g ty with - | ValueSome tcref -> - let isEq tcref2 = tyconRefEq g tcref tcref2 - if isEq g.nativeptr_tcr || isEq g.nativeint_tcr || - isEq g.sbyte_tcr || isEq g.byte_tcr || - isEq g.int16_tcr || isEq g.uint16_tcr || - isEq g.int32_tcr || isEq g.uint32_tcr || - isEq g.int64_tcr || isEq g.uint64_tcr || - isEq g.char_tcr || - isEq g.float32_tcr || - isEq g.float_tcr || - isEq g.decimal_tcr || - isEq g.bool_tcr then - true - else - let tycon = tcref.Deref - if tycon.IsEnumTycon then - true - elif tycon.IsStructOrEnumTycon then - match tycon.TyparsNoRange with - | [] -> tycon.AllInstanceFieldsAsList |> List.forall (fun r -> isUnmanagedTy g r.rfield_type) - | _ -> false // generic structs are never - else false - | ValueNone -> - false - -let isInterfaceTycon x = - isILInterfaceTycon x || x.IsFSharpInterfaceTycon - -let isInterfaceTyconRef (tcref: TyconRef) = isInterfaceTycon tcref.Deref - -let isEnumTy g ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> tcref.IsEnumTycon - -let actualReturnTyOfSlotSig parentTyInst methTyInst (TSlotSig(_, _, parentFormalTypars, methFormalTypars, _, formalRetTy)) = - let methTyInst = mkTyparInst methFormalTypars methTyInst - let parentTyInst = mkTyparInst parentFormalTypars parentTyInst - Option.map (instType (parentTyInst @ methTyInst)) formalRetTy - -let slotSigHasVoidReturnTy (TSlotSig(_, _, _, _, _, formalRetTy)) = - Option.isNone formalRetTy - -let returnTyOfMethod g (TObjExprMethod((TSlotSig(_, parentTy, _, _, _, _) as ss), _, methFormalTypars, _, _, _)) = - let tinst = argsOfAppTy g parentTy - let methTyInst = generalizeTypars methFormalTypars - actualReturnTyOfSlotSig tinst methTyInst ss - -/// Is the type 'abstract' in C#-speak -let isAbstractTycon (tycon: Tycon) = - if tycon.IsFSharpObjectModelTycon then - not tycon.IsFSharpDelegateTycon && - tycon.TypeContents.tcaug_abstract - else - tycon.IsILTycon && tycon.ILTyconRawMetadata.IsAbstract - -//--------------------------------------------------------------------------- -// Determine if a member/Val/ValRef is an explicit impl -//--------------------------------------------------------------------------- - -let MemberIsExplicitImpl g (membInfo: ValMemberInfo) = - membInfo.MemberFlags.IsOverrideOrExplicitImpl && - match membInfo.ImplementedSlotSigs with - | [] -> false - | slotsigs -> slotsigs |> List.forall (fun slotsig -> isInterfaceTy g slotsig.ImplementedType) - -let ValIsExplicitImpl g (v: Val) = - match v.MemberInfo with - | Some membInfo -> MemberIsExplicitImpl g membInfo - | _ -> false - -let ValRefIsExplicitImpl g (vref: ValRef) = ValIsExplicitImpl g vref.Deref - -//--------------------------------------------------------------------------- -// Find all type variables in a type, apart from those that have had -// an equation assigned by type inference. -//--------------------------------------------------------------------------- - -let emptyFreeLocals = Zset.empty valOrder -let unionFreeLocals s1 s2 = - if s1 === emptyFreeLocals then s2 - elif s2 === emptyFreeLocals then s1 - else Zset.union s1 s2 - -let emptyFreeRecdFields = Zset.empty recdFieldRefOrder -let unionFreeRecdFields s1 s2 = - if s1 === emptyFreeRecdFields then s2 - elif s2 === emptyFreeRecdFields then s1 - else Zset.union s1 s2 - -let emptyFreeUnionCases = Zset.empty unionCaseRefOrder -let unionFreeUnionCases s1 s2 = - if s1 === emptyFreeUnionCases then s2 - elif s2 === emptyFreeUnionCases then s1 - else Zset.union s1 s2 - -let emptyFreeTycons = Zset.empty tyconOrder -let unionFreeTycons s1 s2 = - if s1 === emptyFreeTycons then s2 - elif s2 === emptyFreeTycons then s1 - else Zset.union s1 s2 - -let typarOrder = - { new System.Collections.Generic.IComparer with - member x.Compare (v1: Typar, v2: Typar) = compare v1.Stamp v2.Stamp } - -let emptyFreeTypars = Zset.empty typarOrder -let unionFreeTypars s1 s2 = - if s1 === emptyFreeTypars then s2 - elif s2 === emptyFreeTypars then s1 - else Zset.union s1 s2 - -let emptyFreeTyvars = - { FreeTycons = emptyFreeTycons - /// The summary of values used as trait solutions - FreeTraitSolutions = emptyFreeLocals - FreeTypars = emptyFreeTypars} - -let isEmptyFreeTyvars ftyvs = - Zset.isEmpty ftyvs.FreeTypars && - Zset.isEmpty ftyvs.FreeTycons - -let unionFreeTyvars fvs1 fvs2 = - if fvs1 === emptyFreeTyvars then fvs2 else - if fvs2 === emptyFreeTyvars then fvs1 else - { FreeTycons = unionFreeTycons fvs1.FreeTycons fvs2.FreeTycons - FreeTraitSolutions = unionFreeLocals fvs1.FreeTraitSolutions fvs2.FreeTraitSolutions - FreeTypars = unionFreeTypars fvs1.FreeTypars fvs2.FreeTypars } - -type FreeVarOptions = - { canCache: bool - collectInTypes: bool - includeLocalTycons: bool - includeTypars: bool - includeLocalTyconReprs: bool - includeRecdFields: bool - includeUnionCases: bool - includeLocals: bool } - -let CollectAllNoCaching = - { canCache = false - collectInTypes = true - includeLocalTycons = true - includeLocalTyconReprs = true - includeRecdFields = true - includeUnionCases = true - includeTypars = true - includeLocals = true } - -let CollectTyparsNoCaching = - { canCache = false - collectInTypes = true - includeLocalTycons = false - includeTypars = true - includeLocalTyconReprs = false - includeRecdFields = false - includeUnionCases = false - includeLocals = false } - -let CollectLocalsNoCaching = - { canCache = false - collectInTypes = false - includeLocalTycons = false - includeTypars = false - includeLocalTyconReprs = false - includeRecdFields = false - includeUnionCases = false - includeLocals = true } - -let CollectTyparsAndLocalsNoCaching = - { canCache = false - collectInTypes = true - includeLocalTycons = false - includeLocalTyconReprs = false - includeRecdFields = false - includeUnionCases = false - includeTypars = true - includeLocals = true } - -let CollectAll = - { canCache = false - collectInTypes = true - includeLocalTycons = true - includeLocalTyconReprs = true - includeRecdFields = true - includeUnionCases = true - includeTypars = true - includeLocals = true } - -let CollectTyparsAndLocals = // CollectAll - { canCache = true // only cache for this one - collectInTypes = true - includeTypars = true - includeLocals = true - includeLocalTycons = false - includeLocalTyconReprs = false - includeRecdFields = false - includeUnionCases = false } - - -let CollectTypars = CollectTyparsAndLocals - -let CollectLocals = CollectTyparsAndLocals - - -let accFreeLocalTycon opts x acc = - if not opts.includeLocalTycons then acc else - if Zset.contains x acc.FreeTycons then acc else - { acc with FreeTycons = Zset.add x acc.FreeTycons } - -let accFreeTycon opts (tcref: TyconRef) acc = - if not opts.includeLocalTycons then acc - elif tcref.IsLocalRef then accFreeLocalTycon opts tcref.PrivateTarget acc - else acc - -let rec boundTypars opts tps acc = - // Bound type vars form a recursively-referential set due to constraints, e.g. A: I, B: I - // So collect up free vars in all constraints first, then bind all variables - let acc = List.foldBack (fun (tp: Typar) acc -> accFreeInTyparConstraints opts tp.Constraints acc) tps acc - List.foldBack (fun tp acc -> { acc with FreeTypars = Zset.remove tp acc.FreeTypars}) tps acc - -and accFreeInTyparConstraints opts cxs acc = - List.foldBack (accFreeInTyparConstraint opts) cxs acc - -and accFreeInTyparConstraint opts tpc acc = - match tpc with - | TyparConstraint.CoercesTo(ty, _) -> accFreeInType opts ty acc - | TyparConstraint.MayResolveMember (traitInfo, _) -> accFreeInTrait opts traitInfo acc - | TyparConstraint.DefaultsTo(_, rty, _) -> accFreeInType opts rty acc - | TyparConstraint.SimpleChoice(tys, _) -> accFreeInTypes opts tys acc - | TyparConstraint.IsEnum(uty, _) -> accFreeInType opts uty acc - | TyparConstraint.IsDelegate(aty, bty, _) -> accFreeInType opts aty (accFreeInType opts bty acc) - | TyparConstraint.SupportsComparison _ - | TyparConstraint.SupportsEquality _ - | TyparConstraint.SupportsNull _ - | TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsReferenceType _ - | TyparConstraint.IsUnmanaged _ - | TyparConstraint.RequiresDefaultConstructor _ -> acc - -and accFreeInTrait opts (TTrait(tys, _, _, argtys, rty, sln)) acc = - Option.foldBack (accFreeInTraitSln opts) sln.Value - (accFreeInTypes opts tys - (accFreeInTypes opts argtys - (Option.foldBack (accFreeInType opts) rty acc))) - -and accFreeInTraitSln opts sln acc = - match sln with - | ILMethSln(ty, _, _, minst) -> - accFreeInType opts ty - (accFreeInTypes opts minst acc) - | FSMethSln(ty, vref, minst) -> - accFreeInType opts ty - (accFreeValRefInTraitSln opts vref - (accFreeInTypes opts minst acc)) - | FSAnonRecdFieldSln(_anonInfo, tinst, _n) -> - accFreeInTypes opts tinst acc - | FSRecdFieldSln(tinst, _rfref, _isSet) -> - accFreeInTypes opts tinst acc - | BuiltInSln -> acc - | ClosedExprSln _ -> acc // nothing to accumulate because it's a closed expression referring only to erasure of provided method calls - -and accFreeLocalValInTraitSln _opts v fvs = - if Zset.contains v fvs.FreeTraitSolutions then fvs - else { fvs with FreeTraitSolutions = Zset.add v fvs.FreeTraitSolutions} - -and accFreeValRefInTraitSln opts (vref: ValRef) fvs = - if vref.IsLocalRef then - accFreeLocalValInTraitSln opts vref.PrivateTarget fvs - else - // non-local values do not contain free variables - fvs - -and accFreeTyparRef opts (tp: Typar) acc = - if not opts.includeTypars then acc else - if Zset.contains tp acc.FreeTypars then acc - else - accFreeInTyparConstraints opts tp.Constraints - { acc with FreeTypars = Zset.add tp acc.FreeTypars} - -and accFreeInType opts ty acc = - match stripTyparEqns ty with - | TType_tuple (tupInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts tupInfo acc) - | TType_anon (anonInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts anonInfo.TupInfo acc) - | TType_app (tc, tinst) -> - let acc = accFreeTycon opts tc acc - match tinst with - | [] -> acc // optimization to avoid unneeded call - | [h] -> accFreeInType opts h acc // optimization to avoid unneeded call - | _ -> accFreeInTypes opts tinst acc - | TType_ucase (UCRef(tc, _), tinst) -> accFreeInTypes opts tinst (accFreeTycon opts tc acc) - | TType_fun (d, r) -> accFreeInType opts d (accFreeInType opts r acc) - | TType_var r -> accFreeTyparRef opts r acc - | TType_forall (tps, r) -> unionFreeTyvars (boundTypars opts tps (freeInType opts r)) acc - | TType_measure unt -> accFreeInMeasure opts unt acc - -and accFreeInTupInfo _opts unt acc = - match unt with - | TupInfo.Const _ -> acc -and accFreeInMeasure opts unt acc = List.foldBack (fun (tp, _) acc -> accFreeTyparRef opts tp acc) (ListMeasureVarOccsWithNonZeroExponents unt) acc -and accFreeInTypes opts tys acc = - match tys with - | [] -> acc - | h :: t -> accFreeInTypes opts t (accFreeInType opts h acc) -and freeInType opts ty = accFreeInType opts ty emptyFreeTyvars - -and accFreeInVal opts (v: Val) acc = accFreeInType opts v.val_type acc - -let freeInTypes opts tys = accFreeInTypes opts tys emptyFreeTyvars -let freeInVal opts v = accFreeInVal opts v emptyFreeTyvars -let freeInTyparConstraints opts v = accFreeInTyparConstraints opts v emptyFreeTyvars -let accFreeInTypars opts tps acc = List.foldBack (accFreeTyparRef opts) tps acc - -let rec addFreeInModuleTy (mtyp: ModuleOrNamespaceType) acc = - QueueList.foldBack (typeOfVal >> accFreeInType CollectAllNoCaching) mtyp.AllValsAndMembers - (QueueList.foldBack (fun (mspec: ModuleOrNamespace) acc -> addFreeInModuleTy mspec.ModuleOrNamespaceType acc) mtyp.AllEntities acc) - -let freeInModuleTy mtyp = addFreeInModuleTy mtyp emptyFreeTyvars - - -//-------------------------------------------------------------------------- -// Free in type, left-to-right order preserved. This is used to determine the -// order of type variables for top-level definitions based on their signature, -// so be careful not to change the order. We accumulate in reverse -// order. -//-------------------------------------------------------------------------- - -let emptyFreeTyparsLeftToRight = [] -let unionFreeTyparsLeftToRight fvs1 fvs2 = ListSet.unionFavourRight typarEq fvs1 fvs2 - -let rec boundTyparsLeftToRight g cxFlag thruFlag acc tps = - // Bound type vars form a recursively-referential set due to constraints, e.g. A: I, B: I - // So collect up free vars in all constraints first, then bind all variables - List.fold (fun acc (tp: Typar) -> accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc tp.Constraints) tps acc - -and accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc cxs = - List.fold (accFreeInTyparConstraintLeftToRight g cxFlag thruFlag) acc cxs - -and accFreeInTyparConstraintLeftToRight g cxFlag thruFlag acc tpc = - match tpc with - | TyparConstraint.CoercesTo(ty, _) -> - accFreeInTypeLeftToRight g cxFlag thruFlag acc ty - | TyparConstraint.MayResolveMember (traitInfo, _) -> - accFreeInTraitLeftToRight g cxFlag thruFlag acc traitInfo - | TyparConstraint.DefaultsTo(_, rty, _) -> - accFreeInTypeLeftToRight g cxFlag thruFlag acc rty - | TyparConstraint.SimpleChoice(tys, _) -> - accFreeInTypesLeftToRight g cxFlag thruFlag acc tys - | TyparConstraint.IsEnum(uty, _) -> - accFreeInTypeLeftToRight g cxFlag thruFlag acc uty - | TyparConstraint.IsDelegate(aty, bty, _) -> - accFreeInTypeLeftToRight g cxFlag thruFlag (accFreeInTypeLeftToRight g cxFlag thruFlag acc aty) bty - | TyparConstraint.SupportsComparison _ - | TyparConstraint.SupportsEquality _ - | TyparConstraint.SupportsNull _ - | TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsUnmanaged _ - | TyparConstraint.IsReferenceType _ - | TyparConstraint.RequiresDefaultConstructor _ -> acc - -and accFreeInTraitLeftToRight g cxFlag thruFlag acc (TTrait(tys, _, _, argtys, rty, _)) = - let acc = accFreeInTypesLeftToRight g cxFlag thruFlag acc tys - let acc = accFreeInTypesLeftToRight g cxFlag thruFlag acc argtys - let acc = Option.fold (accFreeInTypeLeftToRight g cxFlag thruFlag) acc rty - acc - -and accFreeTyparRefLeftToRight g cxFlag thruFlag acc (tp: Typar) = - if ListSet.contains typarEq tp acc then - acc - else - let acc = ListSet.insert typarEq tp acc - if cxFlag then - accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc tp.Constraints - else - acc - -and accFreeInTypeLeftToRight g cxFlag thruFlag acc ty = - match (if thruFlag then stripTyEqns g ty else stripTyparEqns ty) with - | TType_anon (anonInfo, anonTys) -> - let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc anonInfo.TupInfo - accFreeInTypesLeftToRight g cxFlag thruFlag acc anonTys - | TType_tuple (tupInfo, tupTys) -> - let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc tupInfo - accFreeInTypesLeftToRight g cxFlag thruFlag acc tupTys - | TType_app (_, tinst) -> - accFreeInTypesLeftToRight g cxFlag thruFlag acc tinst - | TType_ucase (_, tinst) -> - accFreeInTypesLeftToRight g cxFlag thruFlag acc tinst - | TType_fun (d, r) -> - let dacc = accFreeInTypeLeftToRight g cxFlag thruFlag acc d - accFreeInTypeLeftToRight g cxFlag thruFlag dacc r - | TType_var r -> - accFreeTyparRefLeftToRight g cxFlag thruFlag acc r - | TType_forall (tps, r) -> - let racc = accFreeInTypeLeftToRight g cxFlag thruFlag emptyFreeTyparsLeftToRight r - unionFreeTyparsLeftToRight (boundTyparsLeftToRight g cxFlag thruFlag tps racc) acc - | TType_measure unt -> - let mvars = ListMeasureVarOccsWithNonZeroExponents unt - List.foldBack (fun (tp, _) acc -> accFreeTyparRefLeftToRight g cxFlag thruFlag acc tp) mvars acc - -and accFreeInTupInfoLeftToRight _g _cxFlag _thruFlag acc unt = - match unt with - | TupInfo.Const _ -> acc - -and accFreeInTypesLeftToRight g cxFlag thruFlag acc tys = - match tys with - | [] -> acc - | h :: t -> accFreeInTypesLeftToRight g cxFlag thruFlag (accFreeInTypeLeftToRight g cxFlag thruFlag acc h) t - -let freeInTypeLeftToRight g thruFlag ty = - accFreeInTypeLeftToRight g true thruFlag emptyFreeTyparsLeftToRight ty |> List.rev - -let freeInTypesLeftToRight g thruFlag ty = - accFreeInTypesLeftToRight g true thruFlag emptyFreeTyparsLeftToRight ty |> List.rev - -let freeInTypesLeftToRightSkippingConstraints g ty = - accFreeInTypesLeftToRight g false true emptyFreeTyparsLeftToRight ty |> List.rev - -let valOfBind (b: Binding) = b.Var - -let valsOfBinds (binds: Bindings) = binds |> List.map (fun b -> b.Var) - -//-------------------------------------------------------------------------- -// Values representing member functions on F# types -//-------------------------------------------------------------------------- - -// Pull apart the type for an F# value that represents an object model method. Do not strip off a 'unit' argument. -// Review: Should GetMemberTypeInFSharpForm have any other direct callers? -let GetMemberTypeInFSharpForm g memberFlags arities ty m = - let tps, argInfos, rty, retInfo = GetTopValTypeInFSharpForm g arities ty m - - let argInfos = - if memberFlags.IsInstance then - match argInfos with - | [] -> - errorR(InternalError("value does not have a valid member type", m)) - argInfos - | _ :: t -> t - else argInfos - tps, argInfos, rty, retInfo - -// Check that an F# value represents an object model method. -// It will also always have an arity (inferred from syntax). -let checkMemberVal membInfo arity m = - match membInfo, arity with - | None, _ -> error(InternalError("checkMemberVal - no membInfo", m)) - | _, None -> error(InternalError("checkMemberVal - no arity", m)) - | Some membInfo, Some arity -> (membInfo, arity) - -let checkMemberValRef (vref: ValRef) = - checkMemberVal vref.MemberInfo vref.ValReprInfo vref.Range - -let GetTopValTypeInCompiledForm g topValInfo ty m = - let tps, paramArgInfos, rty, retInfo = GetTopValTypeInFSharpForm g topValInfo ty m - // Eliminate lone single unit arguments - let paramArgInfos = - match paramArgInfos, topValInfo.ArgInfos with - // static member and module value unit argument elimination - | [[(_argType, _)]], [[]] -> - //assert isUnitTy g argType - [[]] - // instance member unit argument elimination - | [objInfo;[(_argType, _)]], [[_objArg];[]] -> - //assert isUnitTy g argType - [objInfo; []] - | _ -> - paramArgInfos - let rty = if isUnitTy g rty then None else Some rty - (tps, paramArgInfos, rty, retInfo) - -// Pull apart the type for an F# value that represents an object model method -// and see the "member" form for the type, i.e. -// detect methods with no arguments by (effectively) looking for single argument type of 'unit'. -// The analysis is driven of the inferred arity information for the value. -// -// This is used not only for the compiled form - it's also used for all type checking and object model -// logic such as determining if abstract methods have been implemented or not, and how -// many arguments the method takes etc. -let GetMemberTypeInMemberForm g memberFlags topValInfo ty m = - let tps, paramArgInfos, rty, retInfo = GetMemberTypeInFSharpForm g memberFlags topValInfo ty m - // Eliminate lone single unit arguments - let paramArgInfos = - match paramArgInfos, topValInfo.ArgInfos with - // static member and module value unit argument elimination - | [[(argType, _)]], [[]] -> - assert isUnitTy g argType - [[]] - // instance member unit argument elimination - | [[(argType, _)]], [[_objArg];[]] -> - assert isUnitTy g argType - [[]] - | _ -> - paramArgInfos - let rty = if isUnitTy g rty then None else Some rty - (tps, paramArgInfos, rty, retInfo) - -let GetTypeOfMemberInMemberForm g (vref: ValRef) = - //assert (not vref.IsExtensionMember) - let membInfo, topValInfo = checkMemberValRef vref - GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo vref.Type vref.Range - -let GetTypeOfMemberInFSharpForm g (vref: ValRef) = - let membInfo, topValInfo = checkMemberValRef vref - GetMemberTypeInFSharpForm g membInfo.MemberFlags topValInfo vref.Type vref.Range - -let PartitionValTyparsForApparentEnclosingType g (v: Val) = - match v.ValReprInfo with - | None -> error(InternalError("PartitionValTypars: not a top value", v.Range)) - | Some arities -> - let fullTypars, _ = destTopForallTy g arities v.Type - let parent = v.MemberApparentEntity - let parentTypars = parent.TyparsNoRange - let nparentTypars = parentTypars.Length - if nparentTypars <= fullTypars.Length then - let memberParentTypars, memberMethodTypars = List.splitAt nparentTypars fullTypars - let memberToParentInst, tinst = mkTyparToTyparRenaming memberParentTypars parentTypars - Some(parentTypars, memberParentTypars, memberMethodTypars, memberToParentInst, tinst) - else None - -/// Match up the type variables on an member value with the type -/// variables on the apparent enclosing type -let PartitionValTypars g (v: Val) = - match v.ValReprInfo with - | None -> error(InternalError("PartitionValTypars: not a top value", v.Range)) - | Some arities -> - if v.IsExtensionMember then - let fullTypars, _ = destTopForallTy g arities v.Type - Some([], [], fullTypars, emptyTyparInst, []) - else - PartitionValTyparsForApparentEnclosingType g v - -let PartitionValRefTypars g (vref: ValRef) = PartitionValTypars g vref.Deref - -/// Get the arguments for an F# value that represents an object model method -let ArgInfosOfMemberVal g (v: Val) = - let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range - let _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo v.Type v.Range - arginfos - -let ArgInfosOfMember g (vref: ValRef) = - ArgInfosOfMemberVal g vref.Deref - -let GetFSharpViewOfReturnType (g: TcGlobals) retTy = - match retTy with - | None -> g.unit_ty - | Some retTy -> retTy - - -/// Get the property "type" (getter return type) for an F# value that represents a getter or setter -/// of an object model property. -let ReturnTypeOfPropertyVal g (v: Val) = - let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range - match membInfo.MemberFlags.MemberKind with - | MemberKind.PropertySet -> - let _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo v.Type v.Range - if not arginfos.IsEmpty && not arginfos.Head.IsEmpty then - arginfos.Head |> List.last |> fst - else - error(Error(FSComp.SR.tastValueDoesNotHaveSetterType(), v.Range)) - | MemberKind.PropertyGet -> - let _, _, rty, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo v.Type v.Range - GetFSharpViewOfReturnType g rty - | _ -> error(InternalError("ReturnTypeOfPropertyVal", v.Range)) - - -/// Get the property arguments for an F# value that represents a getter or setter -/// of an object model property. -let ArgInfosOfPropertyVal g (v: Val) = - let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range - match membInfo.MemberFlags.MemberKind with - | MemberKind.PropertyGet -> - ArgInfosOfMemberVal g v |> List.concat - | MemberKind.PropertySet -> - let _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo v.Type v.Range - if not arginfos.IsEmpty && not arginfos.Head.IsEmpty then - arginfos.Head |> List.frontAndBack |> fst - else - error(Error(FSComp.SR.tastValueDoesNotHaveSetterType(), v.Range)) - | _ -> - error(InternalError("ArgInfosOfPropertyVal", v.Range)) - -//--------------------------------------------------------------------------- -// Generalize type constructors to types -//--------------------------------------------------------------------------- - -let generalTyconRefInst (tc: TyconRef) = generalizeTypars tc.TyparsNoRange - -let generalizeTyconRef tc = - let tinst = generalTyconRefInst tc - tinst, TType_app(tc, tinst) - -let generalizedTyconRef tc = TType_app(tc, generalTyconRefInst tc) - -let isTTyparSupportsStaticMethod = function TyparConstraint.MayResolveMember _ -> true | _ -> false -let isTTyparCoercesToType = function TyparConstraint.CoercesTo _ -> true | _ -> false - -//-------------------------------------------------------------------------- -// Print Signatures/Types - prelude -//-------------------------------------------------------------------------- - -let prefixOfStaticReq s = - match s with - | NoStaticReq -> "'" - | HeadTypeStaticReq -> " ^" - -let prefixOfRigidTypar (typar: Typar) = - if (typar.Rigidity <> TyparRigidity.Rigid) then "_" else "" - -//--------------------------------------------------------------------------- -// Prettify: PrettyTyparNames/PrettifyTypes - make typar names human friendly -//--------------------------------------------------------------------------- - -type TyparConstraintsWithTypars = (Typar * TyparConstraint) list - -module PrettyTypes = - let newPrettyTypar (tp: Typar) nm = - NewTypar (tp.Kind, tp.Rigidity, Typar(ident(nm, tp.Range), tp.StaticReq, false), false, TyparDynamicReq.Yes, [], false, false) - - let NewPrettyTypars renaming tps names = - let niceTypars = List.map2 newPrettyTypar tps names - let tl, _tt = mkTyparToTyparRenaming tps niceTypars in - let renaming = renaming @ tl - (tps, niceTypars) ||> List.iter2 (fun tp tpnice -> tpnice.SetConstraints (instTyparConstraints renaming tp.Constraints)) - niceTypars, renaming - - // We choose names for type parameters from 'a'..'t' - // We choose names for unit-of-measure from 'u'..'z' - // If we run off the end of these ranges, we use 'aX' for positive integer X or 'uX' for positive integer X - // Finally, we skip any names already in use - let NeedsPrettyTyparName (tp: Typar) = - tp.IsCompilerGenerated && - tp.ILName.IsNone && - (tp.typar_id.idText = unassignedTyparName) - - let PrettyTyparNames pred alreadyInUse tps = - let rec choose (tps: Typar list) (typeIndex, measureIndex) acc = - match tps with - | [] -> List.rev acc - | tp :: tps -> - - - // Use a particular name, possibly after incrementing indexes - let useThisName (nm, typeIndex, measureIndex) = - choose tps (typeIndex, measureIndex) (nm :: acc) - - // Give up, try again with incremented indexes - let tryAgain (typeIndex, measureIndex) = - choose (tp :: tps) (typeIndex, measureIndex) acc - - let tryName (nm, typeIndex, measureIndex) f = - if List.contains nm alreadyInUse then - f() - else - useThisName (nm, typeIndex, measureIndex) - - if pred tp then - if NeedsPrettyTyparName tp then - let (typeIndex, measureIndex, baseName, letters, i) = - match tp.Kind with - | TyparKind.Type -> (typeIndex+1, measureIndex, 'a', 20, typeIndex) - | TyparKind.Measure -> (typeIndex, measureIndex+1, 'u', 6, measureIndex) - let nm = - if i < letters then String.make 1 (char(int baseName + i)) - else String.make 1 baseName + string (i-letters+1) - tryName (nm, typeIndex, measureIndex) (fun () -> - tryAgain (typeIndex, measureIndex)) - - else - tryName (tp.Name, typeIndex, measureIndex) (fun () -> - // Use the next index and append it to the natural name - let (typeIndex, measureIndex, nm) = - match tp.Kind with - | TyparKind.Type -> (typeIndex+1, measureIndex, tp.Name+ string typeIndex) - | TyparKind.Measure -> (typeIndex, measureIndex+1, tp.Name+ string measureIndex) - tryName (nm, typeIndex, measureIndex) (fun () -> - tryAgain (typeIndex, measureIndex))) - else - useThisName (tp.Name, typeIndex, measureIndex) - - choose tps (0, 0) [] - - let PrettifyThings g foldTys mapTys things = - let ftps = foldTys (accFreeInTypeLeftToRight g true false) emptyFreeTyparsLeftToRight things - let ftps = List.rev ftps - let rec computeKeep (keep: Typars) change (tps: Typars) = - match tps with - | [] -> List.rev keep, List.rev change - | tp :: rest -> - if not (NeedsPrettyTyparName tp) && (not (keep |> List.exists (fun tp2 -> tp.Name = tp2.Name))) then - computeKeep (tp :: keep) change rest - else - computeKeep keep (tp :: change) rest - let keep, change = computeKeep [] [] ftps - - // change |> List.iter (fun tp -> dprintf "change typar: %s %s %d\n" tp.Name (tp.DisplayName) (stamp_of_typar tp)) - // keep |> List.iter (fun tp -> dprintf "keep typar: %s %s %d\n" tp.Name (tp.DisplayName) (stamp_of_typar tp)) - let alreadyInUse = keep |> List.map (fun x -> x.Name) - let names = PrettyTyparNames (fun x -> List.memq x change) alreadyInUse ftps - - let niceTypars, renaming = NewPrettyTypars [] ftps names - - // strip universal types for printing - let getTauStayTau t = - match t with - | TType_forall (_, tau) -> tau - | _ -> t - let tauThings = mapTys getTauStayTau things - - let prettyThings = mapTys (instType renaming) tauThings - // niceTypars |> List.iter (fun tp -> dprintf "nice typar: %d\n" (stamp_of_typar tp)); * - let tpconstraints = niceTypars |> List.collect (fun tpnice -> List.map (fun tpc -> tpnice, tpc) tpnice.Constraints) - - prettyThings, tpconstraints - - let PrettifyType g x = PrettifyThings g id id x - let PrettifyTypePair g x = PrettifyThings g (fun f -> foldPair (f, f)) (fun f -> mapPair (f, f)) x - let PrettifyTypes g x = PrettifyThings g List.fold List.map x - let PrettifyCurriedTypes g x = PrettifyThings g (fun f -> List.fold (List.fold f)) List.mapSquared x - let PrettifyCurriedSigTypes g x = PrettifyThings g (fun f -> foldPair (List.fold (List.fold f), f)) (fun f -> mapPair (List.mapSquared f, f)) x - - // Badly formed code may instantiate rigid declared typars to types. - // Hence we double check here that the thing is really a type variable - let safeDestAnyParTy orig g ty = match tryAnyParTy g ty with ValueNone -> orig | ValueSome x -> x - let tee f x = f x x - - let foldUnurriedArgInfos f z (x: UncurriedArgInfos) = List.fold (fold1Of2 f) z x - let mapUnurriedArgInfos f (x: UncurriedArgInfos) = List.map (map1Of2 f) x - - let foldTypar f z (x: Typar) = foldOn mkTyparTy f z x - let mapTypar g f (x: Typar) : Typar = (mkTyparTy >> f >> safeDestAnyParTy x g) x - - let foldTypars f z (x: Typars) = List.fold (foldTypar f) z x - let mapTypars g f (x: Typars) : Typars = List.map (mapTypar g f) x - - let foldTyparInst f z (x: TyparInst) = List.fold (foldPair (foldTypar f, f)) z x - let mapTyparInst g f (x: TyparInst) : TyparInst = List.map (mapPair (mapTypar g f, f)) x - - let PrettifyInstAndTyparsAndType g x = - PrettifyThings g - (fun f -> foldTriple (foldTyparInst f, foldTypars f, f)) - (fun f-> mapTriple (mapTyparInst g f, mapTypars g f, f)) - x - - let PrettifyInstAndUncurriedSig g (x: TyparInst * UncurriedArgInfos * TType) = - PrettifyThings g - (fun f -> foldTriple (foldTyparInst f, foldUnurriedArgInfos f, f)) - (fun f -> mapTriple (mapTyparInst g f, List.map (map1Of2 f), f)) - x - - let PrettifyInstAndCurriedSig g (x: TyparInst * TTypes * CurriedArgInfos * TType) = - PrettifyThings g - (fun f -> foldQuadruple (foldTyparInst f, List.fold f, List.fold (List.fold (fold1Of2 f)), f)) - (fun f -> mapQuadruple (mapTyparInst g f, List.map f, List.mapSquared (map1Of2 f), f)) - x - - let PrettifyInstAndSig g x = - PrettifyThings g - (fun f -> foldTriple (foldTyparInst f, List.fold f, f)) - (fun f -> mapTriple (mapTyparInst g f, List.map f, f) ) - x - - let PrettifyInstAndTypes g x = - PrettifyThings g - (fun f -> foldPair (foldTyparInst f, List.fold f)) - (fun f -> mapPair (mapTyparInst g f, List.map f)) - x - - let PrettifyInstAndType g x = - PrettifyThings g - (fun f -> foldPair (foldTyparInst f, f)) - (fun f -> mapPair (mapTyparInst g f, f)) - x - - let PrettifyInst g x = - PrettifyThings g - (fun f -> foldTyparInst f) - (fun f -> mapTyparInst g f) - x - -module SimplifyTypes = - - // CAREFUL! This function does NOT walk constraints - let rec foldTypeButNotConstraints f z ty = - let ty = stripTyparEqns ty - let z = f z ty - match ty with - | TType_forall (_, body) -> foldTypeButNotConstraints f z body - | TType_app (_, tys) - | TType_ucase (_, tys) - | TType_anon (_, tys) - | TType_tuple (_, tys) -> List.fold (foldTypeButNotConstraints f) z tys - | TType_fun (s, t) -> foldTypeButNotConstraints f (foldTypeButNotConstraints f z s) t - | TType_var _ -> z - | TType_measure _ -> z - - let incM x m = - if Zmap.mem x m then Zmap.add x (1 + Zmap.find x m) m - else Zmap.add x 1 m - - let accTyparCounts z ty = - // Walk type to determine typars and their counts (for pprinting decisions) - foldTypeButNotConstraints (fun z ty -> match ty with | TType_var tp when tp.Rigidity = TyparRigidity.Rigid -> incM tp z | _ -> z) z ty - - let emptyTyparCounts = Zmap.empty typarOrder - - // print multiple fragments of the same type using consistent naming and formatting - let accTyparCountsMulti acc l = List.fold accTyparCounts acc l - - type TypeSimplificationInfo = - { singletons: Typar Zset - inplaceConstraints: Zmap - postfixConstraints: (Typar * TyparConstraint) list } - - let typeSimplificationInfo0 = - { singletons = Zset.empty typarOrder - inplaceConstraints = Zmap.empty typarOrder - postfixConstraints = [] } - - let categorizeConstraints simplify m cxs = - let singletons = if simplify then Zmap.chooseL (fun tp n -> if n = 1 then Some tp else None) m else [] - let singletons = Zset.addList singletons (Zset.empty typarOrder) - // Here, singletons are typars that occur once in the type. - // However, they may also occur in a type constraint. - // If they do, they are really multiple occurrence - so we should remove them. - let constraintTypars = (freeInTyparConstraints CollectTyparsNoCaching (List.map snd cxs)).FreeTypars - let usedInTypeConstraint typar = Zset.contains typar constraintTypars - let singletons = singletons |> Zset.filter (usedInTypeConstraint >> not) - // Here, singletons should really be used once - let inplace, postfix = - cxs |> List.partition (fun (tp, tpc) -> - simplify && - isTTyparCoercesToType tpc && - Zset.contains tp singletons && - tp.Constraints.Length = 1) - let inplace = inplace |> List.map (function (tp, TyparConstraint.CoercesTo(ty, _)) -> tp, ty | _ -> failwith "not isTTyparCoercesToType") - - { singletons = singletons - inplaceConstraints = Zmap.ofList typarOrder inplace - postfixConstraints = postfix } - let CollectInfo simplify tys cxs = - categorizeConstraints simplify (accTyparCountsMulti emptyTyparCounts tys) cxs - -//-------------------------------------------------------------------------- -// Print Signatures/Types -//-------------------------------------------------------------------------- - -[] -type DisplayEnv = - { includeStaticParametersInTypeNames: bool - openTopPathsSorted: Lazy - openTopPathsRaw: string list list - shortTypeNames: bool - suppressNestedTypes: bool - maxMembers: int option - showObsoleteMembers: bool - showHiddenMembers: bool - showTyparBinding: bool - showImperativeTyparAnnotations: bool - suppressInlineKeyword: bool - suppressMutableKeyword: bool - showMemberContainers: bool - shortConstraints: bool - useColonForReturnType: bool - showAttributes: bool - showOverrides: bool - showConstraintTyparAnnotations: bool - abbreviateAdditionalConstraints: bool - showTyparDefaultConstraints: bool - g: TcGlobals - contextAccessibility: Accessibility - generatedValueLayout : (Val -> layout option) } - - member x.SetOpenPaths paths = - { x with - openTopPathsSorted = (lazy (paths |> List.sortWith (fun p1 p2 -> -(compare p1 p2)))) - openTopPathsRaw = paths - } - - static member Empty tcGlobals = - { includeStaticParametersInTypeNames = false - openTopPathsRaw = [] - openTopPathsSorted = notlazy [] - shortTypeNames = false - suppressNestedTypes = false - maxMembers = None - showObsoleteMembers = false - showHiddenMembers = false - showTyparBinding = false - showImperativeTyparAnnotations = false - suppressInlineKeyword = false - suppressMutableKeyword = false - showMemberContainers = false - showAttributes = false - showOverrides = true - showConstraintTyparAnnotations = true - abbreviateAdditionalConstraints = false - showTyparDefaultConstraints = false - shortConstraints = false - useColonForReturnType = false - g = tcGlobals - contextAccessibility = taccessPublic - generatedValueLayout = (fun _ -> None) } - - - member denv.AddOpenPath path = - denv.SetOpenPaths (path :: denv.openTopPathsRaw) - - member denv.AddOpenModuleOrNamespace (modref: ModuleOrNamespaceRef) = - denv.AddOpenPath (fullCompPathOfModuleOrNamespace modref.Deref).DemangledPath - - member denv.AddAccessibility access = - { denv with contextAccessibility = combineAccess denv.contextAccessibility access } - -let (+.+) s1 s2 = if s1 = "" then s2 else s1+"."+s2 - -let layoutOfPath p = - sepListL SepL.dot (List.map (tagNamespace >> wordL) p) - -let fullNameOfParentOfPubPath pp = - match pp with - | PubPath([| _ |]) -> ValueNone - | pp -> ValueSome(textOfPath pp.EnclosingPath) - -let fullNameOfParentOfPubPathAsLayout pp = - match pp with - | PubPath([| _ |]) -> ValueNone - | pp -> ValueSome(layoutOfPath (Array.toList pp.EnclosingPath)) - -let fullNameOfPubPath (PubPath p) = textOfPath p -let fullNameOfPubPathAsLayout (PubPath p) = layoutOfPath (Array.toList p) - -let fullNameOfParentOfNonLocalEntityRef (nlr: NonLocalEntityRef) = - if nlr.Path.Length < 2 then ValueNone - else ValueSome (textOfPath nlr.EnclosingMangledPath) - -let fullNameOfParentOfNonLocalEntityRefAsLayout (nlr: NonLocalEntityRef) = - if nlr.Path.Length < 2 then ValueNone - else ValueSome (layoutOfPath (List.ofArray nlr.EnclosingMangledPath)) - -let fullNameOfParentOfEntityRef eref = - match eref with - | ERefLocal x -> - match x.PublicPath with - | None -> ValueNone - | Some ppath -> fullNameOfParentOfPubPath ppath - | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRef nlr - -let fullNameOfParentOfEntityRefAsLayout eref = - match eref with - | ERefLocal x -> - match x.PublicPath with - | None -> ValueNone - | Some ppath -> fullNameOfParentOfPubPathAsLayout ppath - | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRefAsLayout nlr - -let fullNameOfEntityRef nmF xref = - match fullNameOfParentOfEntityRef xref with - | ValueNone -> nmF xref - | ValueSome pathText -> pathText +.+ nmF xref - -let tagEntityRefName (xref: EntityRef) name = - if xref.IsNamespace then tagNamespace name - elif xref.IsModule then tagModule name - elif xref.IsTypeAbbrev then tagAlias name - elif xref.IsFSharpDelegateTycon then tagDelegate name - elif xref.IsILEnumTycon || xref.IsFSharpEnumTycon then tagEnum name - elif xref.IsStructOrEnumTycon then tagStruct name - elif xref.IsFSharpInterfaceTycon then tagInterface name - elif xref.IsUnionTycon then tagUnion name - elif xref.IsRecordTycon then tagRecord name - else tagClass name - -let fullDisplayTextOfTyconRef (tc: TyconRef) = - fullNameOfEntityRef (fun tc -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) tc - -let fullNameOfEntityRefAsLayout nmF (xref: EntityRef) = - let navigableText = - tagEntityRefName xref (nmF xref) - |> mkNav xref.DefinitionRange - |> wordL - match fullNameOfParentOfEntityRefAsLayout xref with - | ValueNone -> navigableText - | ValueSome pathText -> pathText ^^ SepL.dot ^^ navigableText - -let fullNameOfParentOfValRef vref = - match vref with - | VRefLocal x -> - match x.PublicPath with - | None -> ValueNone - | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPath pp) - | VRefNonLocal nlr -> - ValueSome (fullNameOfEntityRef (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) - -let fullNameOfParentOfValRefAsLayout vref = - match vref with - | VRefLocal x -> - match x.PublicPath with - | None -> ValueNone - | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPathAsLayout pp) - | VRefNonLocal nlr -> - ValueSome (fullNameOfEntityRefAsLayout (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) - - -let fullDisplayTextOfParentOfModRef r = fullNameOfParentOfEntityRef r - -let fullDisplayTextOfModRef r = fullNameOfEntityRef (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) r -let fullDisplayTextOfTyconRefAsLayout r = fullNameOfEntityRefAsLayout (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r -let fullDisplayTextOfExnRef r = fullNameOfEntityRef (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r -let fullDisplayTextOfExnRefAsLayout r = fullNameOfEntityRefAsLayout (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r - -let fullDisplayTextOfUnionCaseRef (ucref: UnionCaseRef) = fullDisplayTextOfTyconRef ucref.TyconRef +.+ ucref.CaseName -let fullDisplayTextOfRecdFieldRef (rfref: RecdFieldRef) = fullDisplayTextOfTyconRef rfref.TyconRef +.+ rfref.FieldName - -let fullDisplayTextOfValRef (vref: ValRef) = - match fullNameOfParentOfValRef vref with - | ValueNone -> vref.DisplayName - | ValueSome pathText -> pathText +.+ vref.DisplayName - -let fullDisplayTextOfValRefAsLayout (vref: ValRef) = - let n = - match vref.MemberInfo with - | None -> - if vref.IsModuleBinding then tagModuleBinding vref.DisplayName - else tagUnknownEntity vref.DisplayName - | Some memberInfo -> - match memberInfo.MemberFlags.MemberKind with - | MemberKind.PropertyGet - | MemberKind.PropertySet - | MemberKind.PropertyGetSet -> tagProperty vref.DisplayName - | MemberKind.ClassConstructor - | MemberKind.Constructor -> tagMethod vref.DisplayName - | MemberKind.Member -> tagMember vref.DisplayName - match fullNameOfParentOfValRefAsLayout vref with - | ValueNone -> wordL n - | ValueSome pathText -> - pathText ^^ SepL.dot ^^ wordL n - //pathText +.+ vref.DisplayName - - -let fullMangledPathToTyconRef (tcref: TyconRef) = - match tcref with - | ERefLocal _ -> (match tcref.PublicPath with None -> [| |] | Some pp -> pp.EnclosingPath) - | ERefNonLocal nlr -> nlr.EnclosingMangledPath - -let qualifiedMangledNameOfTyconRef tcref nm = - String.concat "-" (Array.toList (fullMangledPathToTyconRef tcref) @ [ tcref.LogicalName + "-" + nm ]) - -let rec firstEq p1 p2 = - match p1 with - | [] -> true - | h1 :: t1 -> - match p2 with - | h2 :: t2 -> h1 = h2 && firstEq t1 t2 - | _ -> false - -let rec firstRem p1 p2 = - match p1 with [] -> p2 | _ :: t1 -> firstRem t1 (List.tail p2) - -let trimPathByDisplayEnv denv path = - let findOpenedNamespace openedPath = - if firstEq openedPath path then - let t2 = firstRem openedPath path - if t2 <> [] then Some(textOfPath t2 + ".") - else Some("") - else None - - match List.tryPick findOpenedNamespace (denv.openTopPathsSorted.Force()) with - | Some s -> s - | None -> if isNil path then "" else textOfPath path + "." - - -let superOfTycon (g: TcGlobals) (tycon: Tycon) = - match tycon.TypeContents.tcaug_super with - | None -> g.obj_ty - | Some ty -> ty - -//---------------------------------------------------------------------------- -// Detect attributes -//---------------------------------------------------------------------------- - -// AbsIL view of attributes (we read these from .NET binaries) -let isILAttribByName (tencl: string list, tname: string) (attr: ILAttribute) = - (attr.Method.DeclaringType.TypeSpec.Name = tname) && - (attr.Method.DeclaringType.TypeSpec.Enclosing = tencl) - -// AbsIL view of attributes (we read these from .NET binaries). The comparison is done by name. -let isILAttrib (tref: ILTypeRef) (attr: ILAttribute) = - isILAttribByName (tref.Enclosing, tref.Name) attr - -// REVIEW: consider supporting querying on Abstract IL custom attributes. -// These linear iterations cost us a fair bit when there are lots of attributes -// on imported types. However this is fairly rare and can also be solved by caching the -// results of attribute lookups in the TAST -let HasILAttribute tref (attrs: ILAttributes) = - attrs.AsArray |> Array.exists (isILAttrib tref) - -let TryDecodeILAttribute (g: TcGlobals) tref (attrs: ILAttributes) = - attrs.AsArray |> Array.tryPick (fun x -> if isILAttrib tref x then Some(decodeILAttribData g.ilg x) else None) - -// F# view of attributes (these get converted to AbsIL attributes in ilxgen) -let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2 -let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs -let findAttrib g tref attrs = List.find (IsMatchingFSharpAttribute g tref) attrs -let TryFindFSharpAttribute g tref attrs = List.tryFind (IsMatchingFSharpAttribute g tref) attrs -let TryFindFSharpAttributeOpt g tref attrs = match tref with None -> None | Some tref -> List.tryFind (IsMatchingFSharpAttribute g tref) attrs - -let HasFSharpAttributeOpt g trefOpt attrs = match trefOpt with Some tref -> List.exists (IsMatchingFSharpAttribute g tref) attrs | _ -> false -let IsMatchingFSharpAttributeOpt g attrOpt (Attrib(tcref2, _, _, _, _, _, _)) = match attrOpt with Some ((AttribInfo(_, tcref))) -> tyconRefEq g tcref tcref2 | _ -> false - -let (|ExtractAttribNamedArg|_|) nm args = - args |> List.tryPick (function (AttribNamedArg(nm2, _, _, v)) when nm = nm2 -> Some v | _ -> None) - -let (|AttribInt32Arg|_|) = function AttribExpr(_, Expr.Const (Const.Int32 n, _, _)) -> Some n | _ -> None -let (|AttribInt16Arg|_|) = function AttribExpr(_, Expr.Const (Const.Int16 n, _, _)) -> Some n | _ -> None -let (|AttribBoolArg|_|) = function AttribExpr(_, Expr.Const (Const.Bool n, _, _)) -> Some n | _ -> None -let (|AttribStringArg|_|) = function AttribExpr(_, Expr.Const (Const.String n, _, _)) -> Some n | _ -> None - -let TryFindFSharpBoolAttributeWithDefault dflt g nm attrs = - match TryFindFSharpAttribute g nm attrs with - | Some(Attrib(_, _, [ ], _, _, _, _)) -> Some dflt - | Some(Attrib(_, _, [ AttribBoolArg b ], _, _, _, _)) -> Some b - | _ -> None - -let TryFindFSharpBoolAttribute g nm attrs = TryFindFSharpBoolAttributeWithDefault true g nm attrs -let TryFindFSharpBoolAttributeAssumeFalse g nm attrs = TryFindFSharpBoolAttributeWithDefault false g nm attrs - -let TryFindFSharpInt32Attribute g nm attrs = - match TryFindFSharpAttribute g nm attrs with - | Some(Attrib(_, _, [ AttribInt32Arg b ], _, _, _, _)) -> Some b - | _ -> None - -let TryFindFSharpStringAttribute g nm attrs = - match TryFindFSharpAttribute g nm attrs with - | Some(Attrib(_, _, [ AttribStringArg b ], _, _, _, _)) -> Some b - | _ -> None - -let TryFindILAttribute (AttribInfo (atref, _)) attrs = - HasILAttribute atref attrs - -let TryFindILAttributeOpt attr attrs = - match attr with - | Some (AttribInfo (atref, _)) -> HasILAttribute atref attrs - | _ -> false - -/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and -/// provided attributes. -// -// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types) -let TryBindTyconRefAttribute g (m: range) (AttribInfo (atref, _) as args) (tcref: TyconRef) f1 f2 f3 = - ignore m; ignore f3 - match metadataOfTycon tcref.Deref with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> - let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)), m) - match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure id, atref.FullName)), m) with - | Some args -> f3 args - | None -> None -#endif - | ILTypeMetadata (TILObjectReprData(_, _, tdef)) -> - match TryDecodeILAttribute g atref tdef.CustomAttrs with - | Some attr -> f1 attr - | _ -> None - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - match TryFindFSharpAttribute g args tcref.Attribs with - | Some attr -> f2 attr - | _ -> None - -let TryFindTyconRefBoolAttribute g m attribSpec tcref = - TryBindTyconRefAttribute g m attribSpec tcref - (function - | ([ ], _) -> Some true - | ([ILAttribElem.Bool v ], _) -> Some v - | _ -> None) - (function - | (Attrib(_, _, [ ], _, _, _, _)) -> Some true - | (Attrib(_, _, [ AttribBoolArg v ], _, _, _, _)) -> Some v - | _ -> None) - (function - | ([ ], _) -> Some true - | ([ Some ((:? bool as v) : obj) ], _) -> Some v - | _ -> None) - -let TryFindAttributeUsageAttribute g m tcref = - TryBindTyconRefAttribute g m g.attrib_AttributeUsageAttribute tcref - (fun (_, named) -> named |> List.tryPick (function ("AllowMultiple", _, _, ILAttribElem.Bool res) -> Some res | _ -> None)) - (fun (Attrib(_, _, _, named, _, _, _)) -> named |> List.tryPick (function AttribNamedArg("AllowMultiple", _, _, AttribBoolArg res ) -> Some res | _ -> None)) - (fun (_, named) -> named |> List.tryPick (function ("AllowMultiple", Some ((:? bool as res) : obj)) -> Some res | _ -> None)) - - -/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. -/// -/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions) -let TryFindTyconRefStringAttribute g m attribSpec tcref = - TryBindTyconRefAttribute g m attribSpec tcref - (function ([ILAttribElem.String (Some msg) ], _) -> Some msg | _ -> None) - (function (Attrib(_, _, [ AttribStringArg msg ], _, _, _, _)) -> Some msg | _ -> None) - (function ([ Some ((:? string as msg) : obj) ], _) -> Some msg | _ -> None) - -/// Check if a type definition has a specific attribute -let TyconRefHasAttribute g m attribSpec tcref = - TryBindTyconRefAttribute g m attribSpec tcref - (fun _ -> Some ()) - (fun _ -> Some ()) - (fun _ -> Some ()) - |> Option.isSome - -let isByrefTyconRef (g: TcGlobals) (tcref: TyconRef) = - (g.byref_tcr.CanDeref && tyconRefEq g g.byref_tcr tcref) || - (g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) || - (g.inref_tcr.CanDeref && tyconRefEq g g.inref_tcr tcref) || - (g.outref_tcr.CanDeref && tyconRefEq g g.outref_tcr tcref) || - tyconRefEqOpt g g.system_TypedReference_tcref tcref || - tyconRefEqOpt g g.system_ArgIterator_tcref tcref || - tyconRefEqOpt g g.system_RuntimeArgumentHandle_tcref tcref - -// See RFC FS-1053.md -let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) = - tcref.CanDeref && - match tcref.TryIsByRefLike with - | ValueSome res -> res - | _ -> - let res = - isByrefTyconRef g tcref || - (isStructTyconRef tcref && TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref) - tcref.SetIsByRefLike res - res - -let isSpanLikeTyconRef g m tcref = - isByrefLikeTyconRef g m tcref && - not (isByrefTyconRef g tcref) - -let isByrefLikeTy g m ty = - ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isByrefLikeTyconRef g m tcref | _ -> false) - -let isSpanLikeTy g m ty = - isByrefLikeTy g m ty && - not (isByrefTy g ty) - -let isSpanTyconRef g m tcref = - isByrefLikeTyconRef g m tcref && - tcref.CompiledRepresentationForNamedType.BasicQualifiedName = "System.Span`1" - -let isSpanTy g m ty = - ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isSpanTyconRef g m tcref | _ -> false) - -let rec tryDestSpanTy g m ty = - match tryAppTy g ty with - | ValueSome(tcref, [ty]) when isSpanTyconRef g m tcref -> ValueSome(struct(tcref, ty)) - | _ -> ValueNone - -let destSpanTy g m ty = - match tryDestSpanTy g m ty with - | ValueSome(struct(tcref, ty)) -> struct(tcref, ty) - | _ -> failwith "destSpanTy" - -let isReadOnlySpanTyconRef g m tcref = - isByrefLikeTyconRef g m tcref && - tcref.CompiledRepresentationForNamedType.BasicQualifiedName = "System.ReadOnlySpan`1" - -let isReadOnlySpanTy g m ty = - ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isReadOnlySpanTyconRef g m tcref | _ -> false) - -let tryDestReadOnlySpanTy g m ty = - match tryAppTy g ty with - | ValueSome(tcref, [ty]) when isReadOnlySpanTyconRef g m tcref -> ValueSome(struct(tcref, ty)) - | _ -> ValueNone - -let destReadOnlySpanTy g m ty = - match tryDestReadOnlySpanTy g m ty with - | ValueSome(struct(tcref, ty)) -> struct(tcref, ty) - | _ -> failwith "destReadOnlySpanTy" - -//------------------------------------------------------------------------- -// List and reference types... -//------------------------------------------------------------------------- - -let destByrefTy g ty = - match ty |> stripTyEqns g with - | TType_app(tcref, [x; _]) when g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref -> x // Check sufficient FSharp.Core - | TType_app(tcref, [x]) when tyconRefEq g g.byref_tcr tcref -> x // all others - | _ -> failwith "destByrefTy: not a byref type" - -let (|ByrefTy|_|) g ty = - // Because of byref = byref2 it is better to write this using is/dest - if isByrefTy g ty then Some (destByrefTy g ty) else None - -let destNativePtrTy g ty = - match ty |> stripTyEqns g with - | TType_app(tcref, [x]) when tyconRefEq g g.nativeptr_tcr tcref -> x - | _ -> failwith "destNativePtrTy: not a native ptr type" - -let isRefCellTy g ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> tyconRefEq g g.refcell_tcr_canon tcref - -let destRefCellTy g ty = - match ty |> stripTyEqns g with - | TType_app(tcref, [x]) when tyconRefEq g g.refcell_tcr_canon tcref -> x - | _ -> failwith "destRefCellTy: not a ref type" - -let StripSelfRefCell(g: TcGlobals, baseOrThisInfo: ValBaseOrThisInfo, tau: TType) : TType = - if baseOrThisInfo = CtorThisVal && isRefCellTy g tau - then destRefCellTy g tau - else tau - -let mkRefCellTy (g: TcGlobals) ty = TType_app(g.refcell_tcr_nice, [ty]) - -let mkLazyTy (g: TcGlobals) ty = TType_app(g.lazy_tcr_nice, [ty]) - -let mkPrintfFormatTy (g: TcGlobals) aty bty cty dty ety = TType_app(g.format_tcr, [aty;bty;cty;dty; ety]) - -let mkOptionTy (g: TcGlobals) ty = TType_app (g.option_tcr_nice, [ty]) - -let mkListTy (g: TcGlobals) ty = TType_app (g.list_tcr_nice, [ty]) - -let isOptionTy (g: TcGlobals) ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> tyconRefEq g g.option_tcr_canon tcref - -let tryDestOptionTy g ty = - match argsOfAppTy g ty with - | [ty1] when isOptionTy g ty -> ValueSome ty1 - | _ -> ValueNone - -let destOptionTy g ty = - match tryDestOptionTy g ty with - | ValueSome ty -> ty - | ValueNone -> failwith "destOptionTy: not an option type" - -let isNullableTy (g: TcGlobals) ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> tyconRefEq g g.system_Nullable_tcref tcref - -let tryDestNullableTy g ty = - match argsOfAppTy g ty with - | [ty1] when isNullableTy g ty -> ValueSome ty1 - | _ -> ValueNone - -let destNullableTy g ty = - match tryDestNullableTy g ty with - | ValueSome ty -> ty - | ValueNone -> failwith "destNullableTy: not a Nullable type" - -let (|NullableTy|_|) g ty = - match tryAppTy g ty with - | ValueSome (tcref, [tyarg]) when tyconRefEq g tcref g.system_Nullable_tcref -> Some tyarg - | _ -> None - -let (|StripNullableTy|) g ty = - match tryDestNullableTy g ty with - | ValueSome tyarg -> tyarg - | _ -> ty - -let isLinqExpressionTy g ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> tyconRefEq g g.system_LinqExpression_tcref tcref - -let tryDestLinqExpressionTy g ty = - match argsOfAppTy g ty with - | [ty1] when isLinqExpressionTy g ty -> Some ty1 - | _ -> None - -let destLinqExpressionTy g ty = - match tryDestLinqExpressionTy g ty with - | Some ty -> ty - | None -> failwith "destLinqExpressionTy: not an expression type" - -let mkNoneCase (g: TcGlobals) = mkUnionCaseRef g.option_tcr_canon "None" -let mkSomeCase (g: TcGlobals) = mkUnionCaseRef g.option_tcr_canon "Some" - -let mkSome g ty arg m = mkUnionCaseExpr(mkSomeCase g, [ty], [arg], m) - -let mkNone g ty m = mkUnionCaseExpr(mkNoneCase g, [ty], [], m) - -type ValRef with - member vref.IsDispatchSlot = - match vref.MemberInfo with - | Some membInfo -> membInfo.MemberFlags.IsDispatchSlot - | None -> false - -let (|UnopExpr|_|) _g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, _, [arg1], _) -> Some (vref, arg1) - | _ -> None - -let (|BinopExpr|_|) _g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, _, [arg1;arg2], _) -> Some (vref, arg1, arg2) - | _ -> None - -let (|SpecificUnopExpr|_|) g vrefReqd expr = - match expr with - | UnopExpr g (vref, arg1) when valRefEq g vref vrefReqd -> Some arg1 - | _ -> None - -let (|SpecificBinopExpr|_|) g vrefReqd expr = - match expr with - | BinopExpr g (vref, arg1, arg2) when valRefEq g vref vrefReqd -> Some (arg1, arg2) - | _ -> None - -let (|EnumExpr|_|) g expr = - match (|SpecificUnopExpr|_|) g g.enum_vref expr with - | None -> (|SpecificUnopExpr|_|) g g.enumOfValue_vref expr - | x -> x - -let (|BitwiseOrExpr|_|) g expr = (|SpecificBinopExpr|_|) g g.bitwise_or_vref expr - -let (|AttribBitwiseOrExpr|_|) g expr = - match expr with - | BitwiseOrExpr g (arg1, arg2) -> Some(arg1, arg2) - // Special workaround, only used when compiling FSharp.Core.dll. Uses of 'a ||| b' occur before the '|||' bitwise or operator - // is defined. These get through type checking because enums implicitly support the '|||' operator through - // the automatic resolution of undefined operators (see tc.fs, Item.ImplicitOp). This then compiles as an - // application of a lambda to two arguments. We recognize this pattern here - | Expr.App (Expr.Lambda _, _, _, [arg1;arg2], _) when g.compilingFslib -> - Some(arg1, arg2) - | _ -> None - -let isUncheckedDefaultOfValRef g vref = - valRefEq g vref g.unchecked_defaultof_vref - // There is an internal version of typeof defined in prim-types.fs that needs to be detected - || (g.compilingFslib && vref.LogicalName = "defaultof") - -let isTypeOfValRef g vref = - valRefEq g vref g.typeof_vref - // There is an internal version of typeof defined in prim-types.fs that needs to be detected - || (g.compilingFslib && vref.LogicalName = "typeof") - -let isSizeOfValRef g vref = - valRefEq g vref g.sizeof_vref - // There is an internal version of typeof defined in prim-types.fs that needs to be detected - || (g.compilingFslib && vref.LogicalName = "sizeof") - -let isNameOfValRef g vref = - valRefEq g vref g.nameof_vref - // There is an internal version of nameof defined in prim-types.fs that needs to be detected - || (g.compilingFslib && vref.LogicalName = "nameof") - -let isTypeDefOfValRef g vref = - valRefEq g vref g.typedefof_vref - // There is an internal version of typedefof defined in prim-types.fs that needs to be detected - || (g.compilingFslib && vref.LogicalName = "typedefof") - -let (|UncheckedDefaultOfExpr|_|) g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isUncheckedDefaultOfValRef g vref -> Some ty - | _ -> None - -let (|TypeOfExpr|_|) g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isTypeOfValRef g vref -> Some ty - | _ -> None - -let (|SizeOfExpr|_|) g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isSizeOfValRef g vref -> Some ty - | _ -> None - -let (|TypeDefOfExpr|_|) g expr = - match expr with - | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isTypeDefOfValRef g vref -> Some ty - | _ -> None - -let (|NameOfExpr|_|) g expr = - match expr with - | Expr.App(Expr.Val(vref,_,_),_,[ty],[],_) when isNameOfValRef g vref -> Some ty - | _ -> None - -let (|SeqExpr|_|) g expr = - match expr with - | Expr.App(Expr.Val(vref,_,_),_,_,_,_) when valRefEq g vref g.seq_vref -> Some() - | _ -> None - -//-------------------------------------------------------------------------- -// DEBUG layout -//--------------------------------------------------------------------------- -module DebugPrint = - let layoutRanges = ref false - - let squareAngleL x = LeftL.leftBracketAngle ^^ x ^^ RightL.rightBracketAngle - - let angleL x = sepL Literals.leftAngle ^^ x ^^ rightL Literals.rightAngle - - let braceL x = leftL Literals.leftBrace ^^ x ^^ rightL Literals.rightBrace - - let braceBarL x = leftL Literals.leftBraceBar ^^ x ^^ rightL Literals.rightBraceBar - - let boolL = function true -> WordL.keywordTrue | false -> WordL.keywordFalse - - let intL (n: int) = wordL (tagNumericLiteral (string n )) - - let int64L (n: int64) = wordL (tagNumericLiteral (string n )) - - let jlistL xL xmap = QueueList.foldBack (fun x z -> z @@ xL x) xmap emptyL - - let bracketIfL x lyt = if x then bracketL lyt else lyt - - let lvalopL x = - match x with - | LAddrOf readonly -> wordL (tagText (sprintf "LAddrOf(%b)" readonly)) - | LByrefGet -> wordL (tagText "LByrefGet") - | LSet -> wordL (tagText "LSet") - | LByrefSet -> wordL (tagText "LByrefSet") - - let angleBracketL l = leftL (tagText "<") ^^ l ^^ rightL (tagText ">") - - let angleBracketListL l = angleBracketL (sepListL (sepL (tagText ",")) l) - - let layoutMemberFlags memFlags = - let stat = - if memFlags.IsInstance || (memFlags.MemberKind = MemberKind.Constructor) then emptyL - else wordL (tagText "static") - let stat = - if memFlags.IsDispatchSlot then stat ++ wordL (tagText "abstract") - elif memFlags.IsOverrideOrExplicitImpl then stat ++ wordL (tagText "override") - else stat - stat - - let stampL _n w = - w - - let layoutTyconRef (tc: TyconRef) = - wordL (tagText tc.DisplayNameWithStaticParameters) |> stampL tc.Stamp - - let rec auxTypeL env ty = auxTypeWrapL env false ty - - and auxTypeAtomL env ty = auxTypeWrapL env true ty - - and auxTyparsL env tcL prefix tinst = - match tinst with - | [] -> tcL - | [t] -> - let tL = auxTypeAtomL env t - if prefix then tcL ^^ angleBracketL tL - else tL ^^ tcL - | _ -> - let tinstL = List.map (auxTypeL env) tinst - if prefix then - tcL ^^ angleBracketListL tinstL - else - tupleL tinstL ^^ tcL - - and auxTypeWrapL env isAtomic ty = - let wrap x = bracketIfL isAtomic x in // wrap iff require atomic expr - match stripTyparEqns ty with - | TType_forall (typars, rty) -> - (leftL (tagText "!") ^^ layoutTyparDecls typars --- auxTypeL env rty) |> wrap - | TType_ucase (UCRef(tcref, _), tinst) - | TType_app (tcref, tinst) -> - let prefix = tcref.IsPrefixDisplay - let tcL = layoutTyconRef tcref - auxTyparsL env tcL prefix tinst - | TType_anon (anonInfo, tys) -> braceBarL (sepListL (wordL (tagText ";")) (List.map2 (fun nm ty -> wordL (tagField nm) --- auxTypeAtomL env ty) (Array.toList anonInfo.SortedNames) tys)) - | TType_tuple (_tupInfo, tys) -> sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) tys) |> wrap - | TType_fun (f, x) -> ((auxTypeAtomL env f ^^ wordL (tagText "->")) --- auxTypeL env x) |> wrap - | TType_var typar -> auxTyparWrapL env isAtomic typar - | TType_measure unt -> -#if DEBUG - leftL (tagText "{") ^^ - (match global_g with - | None -> wordL (tagText "") - | Some g -> - let sortVars (vs:(Typar * Rational) list) = vs |> List.sortBy (fun (v, _) -> v.DisplayName) - let sortCons (cs:(TyconRef * Rational) list) = cs |> List.sortBy (fun (c, _) -> c.DisplayName) - let negvs, posvs = ListMeasureVarOccsWithNonZeroExponents unt |> sortVars |> List.partition (fun (_, e) -> SignRational e < 0) - let negcs, poscs = ListMeasureConOccsWithNonZeroExponents g false unt |> sortCons |> List.partition (fun (_, e) -> SignRational e < 0) - let unparL (uv: Typar) = wordL (tagText ("'" + uv.DisplayName)) - let unconL tc = layoutTyconRef tc - let rationalL e = wordL (tagText(RationalToString e)) - let measureToPowerL x e = if e = OneRational then x else x -- wordL (tagText "^") -- rationalL e - let prefix = - spaceListL - (List.map (fun (v, e) -> measureToPowerL (unparL v) e) posvs @ - List.map (fun (c, e) -> measureToPowerL (unconL c) e) poscs) - let postfix = - spaceListL - (List.map (fun (v, e) -> measureToPowerL (unparL v) (NegRational e)) negvs @ - List.map (fun (c, e) -> measureToPowerL (unconL c) (NegRational e)) negcs) - match (negvs, negcs) with - | [], [] -> prefix - | _ -> prefix ^^ sepL (tagText "/") ^^ postfix) ^^ - rightL (tagText "}") -#else - unt |> ignore - wordL(tagText "") -#endif - - and auxTyparWrapL (env: SimplifyTypes.TypeSimplificationInfo) isAtomic (typar: Typar) = - let wrap x = bracketIfL isAtomic x in // wrap iff require atomic expr - // There are several cases for pprinting of typar. - // - // 'a - is multiple occurrence. - // #Type - inplace coercion constraint and singleton - // ('a :> Type) - inplace coercion constraint not singleton - // ('a.opM: S->T) - inplace operator constraint - let tpL = - wordL (tagText (prefixOfStaticReq typar.StaticReq - + prefixOfRigidTypar typar - + typar.DisplayName)) - let varL = tpL |> stampL typar.Stamp - - match Zmap.tryFind typar env.inplaceConstraints with - | Some typarConstraintTy -> - if Zset.contains typar env.singletons then - leftL (tagText "#") ^^ auxTyparConstraintTypL env typarConstraintTy - else - (varL ^^ sepL (tagText ":>") ^^ auxTyparConstraintTypL env typarConstraintTy) |> wrap - | _ -> varL - - and auxTypar2L env typar = auxTyparWrapL env false typar - - and auxTyparAtomL env typar = auxTyparWrapL env true typar - - and auxTyparConstraintTypL env ty = auxTypeL env ty - - and auxTraitL env (ttrait: TraitConstraintInfo) = -#if DEBUG - let (TTrait(tys, nm, memFlags, argtys, rty, _)) = ttrait - match global_g with - | None -> wordL (tagText "") - | Some g -> - let rty = GetFSharpViewOfReturnType g rty - let stat = layoutMemberFlags memFlags - let argsL = sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) argtys) - let resL = auxTypeL env rty - let methodTypeL = (argsL ^^ wordL (tagText "->")) ++ resL - bracketL (stat ++ bracketL (sepListL (wordL (tagText "or")) (List.map (auxTypeAtomL env) tys)) ++ wordL (tagText "member") --- (wordL (tagText nm) ^^ wordL (tagText ":") -- methodTypeL)) -#else - ignore (env, ttrait) - wordL(tagText "trait") -#endif - - and auxTyparConstraintL env (tp, tpc) = - let constraintPrefix l = auxTypar2L env tp ^^ wordL (tagText ":") ^^ l - match tpc with - | TyparConstraint.CoercesTo(typarConstraintTy, _) -> - auxTypar2L env tp ^^ wordL (tagText ":>") --- auxTyparConstraintTypL env typarConstraintTy - | TyparConstraint.MayResolveMember(traitInfo, _) -> - auxTypar2L env tp ^^ wordL (tagText ":") --- auxTraitL env traitInfo - | TyparConstraint.DefaultsTo(_, ty, _) -> - wordL (tagText "default") ^^ auxTypar2L env tp ^^ wordL (tagText ":") ^^ auxTypeL env ty - | TyparConstraint.IsEnum(ty, _) -> - auxTyparsL env (wordL (tagText "enum")) true [ty] |> constraintPrefix - | TyparConstraint.IsDelegate(aty, bty, _) -> - auxTyparsL env (wordL (tagText "delegate")) true [aty; bty] |> constraintPrefix - | TyparConstraint.SupportsNull _ -> - wordL (tagText "null") |> constraintPrefix - | TyparConstraint.SupportsComparison _ -> - wordL (tagText "comparison") |> constraintPrefix - | TyparConstraint.SupportsEquality _ -> - wordL (tagText "equality") |> constraintPrefix - | TyparConstraint.IsNonNullableStruct _ -> - wordL (tagText "struct") |> constraintPrefix - | TyparConstraint.IsReferenceType _ -> - wordL (tagText "not struct") |> constraintPrefix - | TyparConstraint.IsUnmanaged _ -> - wordL (tagText "unmanaged") |> constraintPrefix - | TyparConstraint.SimpleChoice(tys, _) -> - bracketL (sepListL (sepL (tagText "|")) (List.map (auxTypeL env) tys)) |> constraintPrefix - | TyparConstraint.RequiresDefaultConstructor _ -> - bracketL (wordL (tagText "new : unit -> ") ^^ (auxTypar2L env tp)) |> constraintPrefix - - and auxTyparConstraintsL env x = - match x with - | [] -> emptyL - | cxs -> wordL (tagText "when") --- aboveListL (List.map (auxTyparConstraintL env) cxs) - - and typarL tp = auxTypar2L SimplifyTypes.typeSimplificationInfo0 tp - - and typarAtomL tp = auxTyparAtomL SimplifyTypes.typeSimplificationInfo0 tp - - and typeAtomL tau = - let tau, cxs = tau, [] - let env = SimplifyTypes.CollectInfo false [tau] cxs - match env.postfixConstraints with - | [] -> auxTypeAtomL env tau - | _ -> bracketL (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) - - and typeL tau = - let tau, cxs = tau, [] - let env = SimplifyTypes.CollectInfo false [tau] cxs - match env.postfixConstraints with - | [] -> auxTypeL env tau - | _ -> (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) - - and typarDeclL tp = - let tau, cxs = mkTyparTy tp, (List.map (fun x -> (tp, x)) tp.Constraints) - let env = SimplifyTypes.CollectInfo false [tau] cxs - match env.postfixConstraints with - | [] -> auxTypeL env tau - | _ -> (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) - and layoutTyparDecls tps = angleBracketListL (List.map typarDeclL tps) - - let rangeL m = wordL (tagText (stringOfRange m)) - - let instL tyL tys = - match tys with - | [] -> emptyL - | tys -> sepL (tagText "@[") ^^ commaListL (List.map tyL tys) ^^ rightL (tagText "]") - - let valRefL (vr: ValRef) = - wordL (tagText vr.LogicalName) |> stampL vr.Stamp - - let layoutAttrib (Attrib(_, k, _, _, _, _, _)) = - leftL (tagText "[<") ^^ - (match k with - | ILAttrib ilmeth -> wordL (tagText ilmeth.Name) - | FSAttrib vref -> valRefL vref) ^^ - rightL (tagText ">]") - - let layoutAttribs attribs = aboveListL (List.map layoutAttrib attribs) - - let arityInfoL (ValReprInfo (tpNames, _, _) as tvd) = - let ns = tvd.AritiesOfArgs in - leftL (tagText "arity<") ^^ intL tpNames.Length ^^ sepL (tagText ">[") ^^ commaListL (List.map intL ns) ^^ rightL (tagText "]") - - let valL (v: Val) = - let vsL = wordL (tagText (DecompileOpName v.LogicalName)) |> stampL v.Stamp - let vsL = vsL -- layoutAttribs (v.Attribs) - vsL - - let typeOfValL (v: Val) = - (valL v - ^^ (if v.MustInline then wordL (tagText "inline ") else emptyL) - ^^ (if v.IsMutable then wordL(tagText "mutable ") else emptyL) - ^^ wordL (tagText ":")) -- typeL v.Type - - let tslotparamL (TSlotParam(nmOpt, ty, inFlag, outFlag, _, _)) = - (optionL (tagText >> wordL) nmOpt) ^^ - wordL(tagText ":") ^^ - typeL ty ^^ - (if inFlag then wordL(tagText "[in]") else emptyL) ^^ - (if outFlag then wordL(tagText "[out]") else emptyL) ^^ - (if inFlag then wordL(tagText "[opt]") else emptyL) - - let slotSigL (slotsig: SlotSig) = -#if DEBUG - let (TSlotSig(nm, ty, tps1, tps2, pms, rty)) = slotsig - match global_g with - | None -> wordL(tagText "") - | Some g -> - let rty = GetFSharpViewOfReturnType g rty - (wordL(tagText "slot") --- (wordL (tagText nm)) ^^ wordL(tagText "@") ^^ typeL ty) -- - (wordL(tagText "LAM") --- spaceListL (List.map typarL tps1) ^^ rightL(tagText ".")) --- - (wordL(tagText "LAM") --- spaceListL (List.map typarL tps2) ^^ rightL(tagText ".")) --- - (commaListL (List.map (List.map tslotparamL >> tupleL) pms)) ^^ (wordL(tagText "-> ")) --- (typeL rty) -#else - ignore slotsig - wordL(tagText "slotsig") -#endif - - let rec memberL (g:TcGlobals) (v: Val) (membInfo: ValMemberInfo) = - aboveListL - [ wordL(tagText "compiled_name! = ") ^^ wordL (tagText (v.CompiledName g.CompilerGlobalState)) - wordL(tagText "membInfo-slotsig! = ") ^^ listL slotSigL membInfo.ImplementedSlotSigs ] - - and valAtBindL g v = - let vL = valL v - let mutL = (if v.IsMutable then wordL(tagText "mutable") ++ vL else vL) - mutL --- - aboveListL - [ yield wordL(tagText ":") ^^ typeL v.Type - match v.MemberInfo with None -> () | Some mem_info -> yield wordL(tagText "!") ^^ memberL g v mem_info - match v.ValReprInfo with None -> () | Some arity_info -> yield wordL(tagText "#") ^^ arityInfoL arity_info] - - let unionCaseRefL (ucr: UnionCaseRef) = wordL (tagText ucr.CaseName) - - let recdFieldRefL (rfref: RecdFieldRef) = wordL (tagText rfref.FieldName) - - let identL (id: Ident) = wordL (tagText id.idText) - - // Note: We need nice printing of constants in order to print literals and attributes - let constL c = - let str = - match c with - | Const.Bool x -> if x then "true" else "false" - | Const.SByte x -> (x |> string)+"y" - | Const.Byte x -> (x |> string)+"uy" - | Const.Int16 x -> (x |> string)+"s" - | Const.UInt16 x -> (x |> string)+"us" - | Const.Int32 x -> (x |> string) - | Const.UInt32 x -> (x |> string)+"u" - | Const.Int64 x -> (x |> string)+"L" - | Const.UInt64 x -> (x |> string)+"UL" - | Const.IntPtr x -> (x |> string)+"n" - | Const.UIntPtr x -> (x |> string)+"un" - | Const.Single d -> - (let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s - then s + ".0" - else s) + "f" - | Const.Double d -> - let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) - if String.forall (fun c -> System.Char.IsDigit c || c = '-') s - then s + ".0" - else s - | Const.Char c -> "'" + c.ToString() + "'" - | Const.String bs -> "\"" + bs + "\"" - | Const.Unit -> "()" - | Const.Decimal bs -> string bs + "M" - | Const.Zero -> "default" - wordL (tagText str) - - let rec tyconL g (tycon: Tycon) = - if tycon.IsModuleOrNamespace then entityL g tycon else - - let lhsL = wordL (tagText (match tycon.TypeOrMeasureKind with TyparKind.Measure -> "[] type" | TyparKind.Type -> "type")) ^^ wordL (tagText tycon.DisplayName) ^^ layoutTyparDecls tycon.TyparsNoRange - let lhsL = lhsL --- layoutAttribs tycon.Attribs - let memberLs = - let adhoc = - tycon.MembersOfFSharpTyconSorted - |> List.filter (fun v -> not v.IsDispatchSlot) - |> List.filter (fun v -> not v.Deref.IsClassConstructor) - // Don't print individual methods forming interface implementations - these are currently never exported - |> List.filter (fun v -> isNil (Option.get v.MemberInfo).ImplementedSlotSigs) - let iimpls = - match tycon.TypeReprInfo with - | TFSharpObjectRepr r when (match r.fsobjmodel_kind with TTyconInterface -> true | _ -> false) -> [] - | _ -> tycon.ImmediateInterfacesOfFSharpTycon - let iimpls = iimpls |> List.filter (fun (_, compgen, _) -> not compgen) - // if TTyconInterface, the iimpls should be printed as inherited interfaces - if isNil adhoc && isNil iimpls then - emptyL - else - let iimplsLs = iimpls |> List.map (fun (ty, _, _) -> wordL(tagText "interface") --- typeL ty) - let adhocLs = adhoc |> List.map (fun vref -> valAtBindL g vref.Deref) - (wordL(tagText "with") @@-- aboveListL (iimplsLs @ adhocLs)) @@ wordL(tagText "end") - - let layoutUnionCaseArgTypes argtys = sepListL (wordL(tagText "*")) (List.map typeL argtys) - - let ucaseL prefixL (ucase: UnionCase) = - let nmL = wordL (tagText (DemangleOperatorName ucase.Id.idText)) - match ucase.RecdFields |> List.map (fun rfld -> rfld.FormalType) with - | [] -> (prefixL ^^ nmL) - | argtys -> (prefixL ^^ nmL ^^ wordL(tagText "of")) --- layoutUnionCaseArgTypes argtys - - let layoutUnionCases ucases = - let prefixL = if not (isNilOrSingleton ucases) then wordL(tagText "|") else emptyL - List.map (ucaseL prefixL) ucases - - let layoutRecdField (fld: RecdField) = - let lhs = wordL (tagText fld.Name) - let lhs = if fld.IsMutable then wordL(tagText "mutable") --- lhs else lhs - (lhs ^^ rightL(tagText ":")) --- typeL fld.FormalType - - let tyconReprL (repr, tycon: Tycon) = - match repr with - | TRecdRepr _ -> - tycon.TrueFieldsAsList |> List.map (fun fld -> layoutRecdField fld ^^ rightL(tagText ";")) |> aboveListL - | TFSharpObjectRepr r -> - match r.fsobjmodel_kind with - | TTyconDelegate _ -> - wordL(tagText "delegate ...") - | _ -> - let start = - match r.fsobjmodel_kind with - | TTyconClass -> "class" - | TTyconInterface -> "interface" - | TTyconStruct -> "struct" - | TTyconEnum -> "enum" - | _ -> failwith "???" - let inherits = - match r.fsobjmodel_kind, tycon.TypeContents.tcaug_super with - | TTyconClass, Some super -> [wordL(tagText "inherit") ^^ (typeL super)] - | TTyconInterface, _ -> - tycon.ImmediateInterfacesOfFSharpTycon - |> List.filter (fun (_, compgen, _) -> not compgen) - |> List.map (fun (ity, _, _) -> wordL(tagText "inherit") ^^ (typeL ity)) - | _ -> [] - let vsprs = - tycon.MembersOfFSharpTyconSorted - |> List.filter (fun v -> v.IsDispatchSlot) - |> List.map (fun vref -> valAtBindL g vref.Deref) - let vals = tycon.TrueFieldsAsList |> List.map (fun f -> (if f.IsStatic then wordL(tagText "static") else emptyL) ^^ wordL(tagText "val") ^^ layoutRecdField f) - let alldecls = inherits @ vsprs @ vals - let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil alldecls | _ -> false - if emptyMeasure then emptyL else (wordL (tagText start) @@-- aboveListL alldecls) @@ wordL(tagText "end") - | TUnionRepr _ -> tycon.UnionCasesAsList |> layoutUnionCases |> aboveListL - | TAsmRepr _ -> wordL(tagText "(# ... #)") - | TMeasureableRepr ty -> typeL ty - | TILObjectRepr (TILObjectReprData(_, _, td)) -> wordL (tagText td.Name) - | _ -> failwith "unreachable" - - let reprL = - match tycon.TypeReprInfo with -#if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint _ - | TProvidedNamespaceExtensionPoint _ -#endif - | TNoRepr -> - match tycon.TypeAbbrev with - | None -> lhsL @@-- memberLs - | Some a -> (lhsL ^^ wordL(tagText "=")) --- (typeL a @@ memberLs) - | a -> - let rhsL = tyconReprL (a, tycon) @@ memberLs - (lhsL ^^ wordL(tagText "=")) @@-- rhsL - reprL - - and bindingL g (TBind(v, repr, _)) = - valAtBindL g v --- (wordL(tagText "=") ^^ exprL g repr) - - and exprL g expr = exprWrapL g false expr - - and atomL g expr = exprWrapL g true expr // true means bracket if needed to be atomic expr - - and letRecL g binds bodyL = - let eqnsL = - binds - |> List.mapHeadTail (fun bind -> wordL(tagText "rec") ^^ bindingL g bind ^^ wordL(tagText "in")) - (fun bind -> wordL(tagText "and") ^^ bindingL g bind ^^ wordL(tagText "in")) - (aboveListL eqnsL @@ bodyL) - - and letL g bind bodyL = - let eqnL = wordL(tagText "let") ^^ bindingL g bind ^^ wordL(tagText "in") - (eqnL @@ bodyL) - - and exprWrapL g isAtomic expr = - let atomL args = atomL g args - let exprL expr = exprL g expr - let iimplL iimpls = iimplL g iimpls - let valAtBindL v = valAtBindL g v - let overrideL tmeth = overrideL g tmeth - let targetL targets = targetL g targets - let wrap = bracketIfL isAtomic // wrap iff require atomic expr - let lay = - match expr with - | Expr.Const (c, _, _) -> constL c - | Expr.Val (v, flags, _) -> - let xL = valL v.Deref - let xL = - match flags with - | PossibleConstrainedCall _ -> xL ^^ rightL(tagText "") - | CtorValUsedAsSelfInit -> xL ^^ rightL(tagText "") - | CtorValUsedAsSuperInit -> xL ^^ rightL(tagText "") - | VSlotDirectCall -> xL ^^ rightL(tagText "") - | NormalValUse -> xL - xL - | Expr.Sequential (expr1, expr2, flag, _, _) -> - let flag = - match flag with - | NormalSeq -> "; (*Seq*)" - | ThenDoSeq -> "; (*ThenDo*)" - ((exprL expr1 ^^ rightL (tagText flag)) @@ exprL expr2) |> wrap - | Expr.Lambda (_, _, baseValOpt, argvs, body, _, _) -> - let formalsL = spaceListL (List.map valAtBindL argvs) in - let bindingL = - match baseValOpt with - | None -> wordL(tagText "lam") ^^ formalsL ^^ rightL(tagText ".") - | Some basev -> wordL(tagText "lam") ^^ (leftL(tagText "base=") ^^ valAtBindL basev) --- formalsL ^^ rightL(tagText ".") in - (bindingL ++ exprL body) |> wrap - | Expr.TyLambda (_, argtyvs, body, _, _) -> - ((wordL(tagText "LAM") ^^ spaceListL (List.map typarL argtyvs) ^^ rightL(tagText ".")) ++ exprL body) |> wrap - | Expr.TyChoose (argtyvs, body, _) -> - ((wordL(tagText "CHOOSE") ^^ spaceListL (List.map typarL argtyvs) ^^ rightL(tagText ".")) ++ exprL body) |> wrap - | Expr.App (f, _, tys, argtys, _) -> - let flayout = atomL f - appL g flayout tys argtys |> wrap - | Expr.LetRec (binds, body, _, _) -> - letRecL g binds (exprL body) |> wrap - | Expr.Let (bind, body, _, _) -> - letL g bind (exprL body) |> wrap - | Expr.Link rX -> - (wordL(tagText "RecLink") --- atomL (!rX)) |> wrap - | Expr.Match (_, _, dtree, targets, _, _) -> - leftL(tagText "[") ^^ (decisionTreeL g dtree @@ aboveListL (List.mapi targetL (targets |> Array.toList)) ^^ rightL(tagText "]")) - | Expr.Op (TOp.UnionCase c, _, args, _) -> - (unionCaseRefL c ++ spaceListL (List.map atomL args)) |> wrap - | Expr.Op (TOp.ExnConstr ecref, _, args, _) -> - wordL (tagText ecref.LogicalName) ^^ bracketL (commaListL (List.map atomL args)) - | Expr.Op (TOp.Tuple _, _, xs, _) -> - tupleL (List.map exprL xs) - | Expr.Op (TOp.Recd (ctor, tc), _, xs, _) -> - let fields = tc.TrueInstanceFieldsAsList - let lay fs x = (wordL (tagText fs.rfield_id.idText) ^^ sepL(tagText "=")) --- (exprL x) - let ctorL = - match ctor with - | RecdExpr -> emptyL - | RecdExprIsObjInit-> wordL(tagText "(new)") - leftL(tagText "{") ^^ semiListL (List.map2 lay fields xs) ^^ rightL(tagText "}") ^^ ctorL - | Expr.Op (TOp.ValFieldSet rf, _, [rx;x], _) -> - (atomL rx --- wordL(tagText ".")) ^^ (recdFieldRefL rf ^^ wordL(tagText "<-") --- exprL x) - | Expr.Op (TOp.ValFieldSet rf, _, [x], _) -> - (recdFieldRefL rf ^^ wordL(tagText "<-") --- exprL x) - | Expr.Op (TOp.ValFieldGet rf, _, [rx], _) -> - (atomL rx ^^ rightL(tagText ".#") ^^ recdFieldRefL rf) - | Expr.Op (TOp.ValFieldGet rf, _, [], _) -> - recdFieldRefL rf - | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [rx], _) -> - leftL(tagText "&") ^^ bracketL (atomL rx ^^ rightL(tagText ".!") ^^ recdFieldRefL rf) - | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [], _) -> - leftL(tagText "&") ^^ (recdFieldRefL rf) - | Expr.Op (TOp.UnionCaseTagGet tycr, _, [x], _) -> - wordL (tagText ("#" + tycr.LogicalName + ".tag")) ^^ atomL x - | Expr.Op (TOp.UnionCaseProof c, _, [x], _) -> - wordL (tagText ("#" + c.CaseName + ".cast")) ^^ atomL x - | Expr.Op (TOp.UnionCaseFieldGet (c, i), _, [x], _) -> - wordL (tagText ("#" + c.CaseName + "." + string i)) --- atomL x - | Expr.Op (TOp.UnionCaseFieldSet (c, i), _, [x;y], _) -> - ((atomL x --- (rightL (tagText ("#" + c.CaseName + "." + string i)))) ^^ wordL(tagText ":=")) --- exprL y - | Expr.Op (TOp.TupleFieldGet (_, i), _, [x], _) -> - wordL (tagText ("#" + string i)) --- atomL x - | Expr.Op (TOp.Coerce, [ty;_], [x], _) -> - atomL x --- (wordL(tagText ":>") ^^ typeL ty) - | Expr.Op (TOp.Reraise, [_], [], _) -> - wordL(tagText "Rethrow!") - | Expr.Op (TOp.ILAsm (a, tys), tyargs, args, _) -> - let instrs = a |> List.map (sprintf "%+A" >> tagText >> wordL) |> spaceListL // %+A has + since instrs are from an "internal" type - let instrs = leftL(tagText "(#") ^^ instrs ^^ rightL(tagText "#)") - (appL g instrs tyargs args --- - wordL(tagText ":") ^^ spaceListL (List.map typeAtomL tys)) |> wrap - | Expr.Op (TOp.LValueOp (lvop, vr), _, args, _) -> - (lvalopL lvop ^^ valRefL vr --- bracketL (commaListL (List.map atomL args))) |> wrap - | Expr.Op (TOp.ILCall (_isVirtCall, _isProtectedCall, _valu, _isNewObjCall, _valUseFlags, _isProperty, _noTailCall, ilMethRef, tinst, minst, _tys), tyargs, args, _) -> - let meth = ilMethRef.Name - wordL(tagText "ILCall") ^^ - aboveListL - [ wordL(tagText "meth ") --- wordL (tagText ilMethRef.DeclaringTypeRef.FullName) ^^ sepL(tagText ".") ^^ wordL (tagText meth) - wordL(tagText "tinst ") --- listL typeL tinst - wordL(tagText "minst ") --- listL typeL minst - wordL(tagText "tyargs") --- listL typeL tyargs - wordL(tagText "args ") --- listL exprL args ] - |> wrap - | Expr.Op (TOp.Array, [_], xs, _) -> - leftL(tagText "[|") ^^ commaListL (List.map exprL xs) ^^ rightL(tagText "|]") - | Expr.Op (TOp.While _, [], [x1;x2], _) -> - wordL(tagText "while") ^^ exprL x1 ^^ wordL(tagText "do") ^^ exprL x2 ^^ rightL(tagText "}") - | Expr.Op (TOp.For _, [], [x1;x2;x3], _) -> - wordL(tagText "for") ^^ aboveListL [(exprL x1 ^^ wordL(tagText "to") ^^ exprL x2 ^^ wordL(tagText "do")); exprL x3 ] ^^ rightL(tagText "done") - | Expr.Op (TOp.TryCatch _, [_], [x1;x2], _) -> - wordL(tagText "try") ^^ exprL x1 ^^ wordL(tagText "with") ^^ exprL x2 ^^ rightL(tagText "}") - | Expr.Op (TOp.TryFinally _, [_], [x1;x2], _) -> - wordL(tagText "try") ^^ exprL x1 ^^ wordL(tagText "finally") ^^ exprL x2 ^^ rightL(tagText "}") - | Expr.Op (TOp.Bytes _, _, _, _) -> - wordL(tagText "bytes++") - | Expr.Op (TOp.UInt16s _, _, _, _) -> wordL(tagText "uint16++") - | Expr.Op (TOp.RefAddrGet _, _tyargs, _args, _) -> wordL(tagText "GetRefLVal...") - | Expr.Op (TOp.TraitCall _, _tyargs, _args, _) -> wordL(tagText "traitcall...") - | Expr.Op (TOp.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...") - | Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...") - | Expr.Op (TOp.TryFinally _, _tyargs, _args, _) -> wordL(tagText "TOp.TryFinally...") - | Expr.Op (TOp.TryCatch _, _tyargs, _args, _) -> wordL(tagText "TOp.TryCatch...") - | Expr.Op (_, _tys, args, _) -> wordL(tagText "Expr.Op ...") ^^ bracketL (commaListL (List.map atomL args)) - | Expr.Quote (a, _, _, _, _) -> leftL(tagText "<@") ^^ atomL a ^^ rightL(tagText "@>") - | Expr.Obj (_lambdaId, ty, basev, ccall, overrides, iimpls, _) -> - wordL(tagText "OBJ:") ^^ - aboveListL [typeL ty - exprL ccall - optionL valAtBindL basev - aboveListL (List.map overrideL overrides) - aboveListL (List.map iimplL iimpls)] - - | Expr.StaticOptimization (_tcs, csx, x, _) -> - (wordL(tagText "opt") @@- (exprL x)) @@-- - (wordL(tagText "|") ^^ exprL csx --- (wordL(tagText "when...") )) - - // For tracking ranges through expr rewrites - if !layoutRanges - then leftL(tagText "{") ^^ (rangeL expr.Range ^^ rightL(tagText ":")) ++ lay ^^ rightL(tagText "}") - else lay - - and implFilesL g implFiles = - let implFileL implFiles = implFileL g implFiles - aboveListL (List.map implFileL implFiles) - - and appL g flayout tys args = - let atomL args = atomL g args - let z = flayout - let z = z ^^ instL typeL tys - let z = z --- sepL(tagText "`") --- (spaceListL (List.map atomL args)) - z - - and implFileL g (TImplFile (_, _, mexpr, _, _, _)) = - aboveListL [(wordL(tagText "top implementation ")) @@-- mexprL g mexpr] - - and mexprL g x = - match x with - | ModuleOrNamespaceExprWithSig(mtyp, defs, _) -> mdefL g defs @@- (wordL(tagText ":") @@- entityTypeL g mtyp) - - and mdefsL g defs = - let mdefL x = mdefL g x - wordL(tagText "Module Defs") @@-- aboveListL(List.map mdefL defs) - - and mdefL g x = - let tyconL tycon = tyconL g tycon - let mbindL x = mbindL g x - match x with - | TMDefRec(_, tycons, mbinds, _) -> aboveListL ((tycons |> List.map tyconL) @ List.map mbindL mbinds) - | TMDefLet(bind, _) -> letL g bind emptyL - | TMDefDo(e, _) -> exprL g e - | TMDefs defs -> mdefsL g defs - | TMAbstract mexpr -> mexprL g mexpr - - and mbindL g x = - match x with - | ModuleOrNamespaceBinding.Binding bind -> letL g bind emptyL - | ModuleOrNamespaceBinding.Module(mspec, rhs) -> - (wordL (tagText (if mspec.IsNamespace then "namespace" else "module")) ^^ (wordL (tagText mspec.DemangledModuleOrNamespaceName) |> stampL mspec.Stamp)) @@-- mdefL g rhs - - and entityTypeL g (mtyp: ModuleOrNamespaceType) = - let tyconL tycon = tyconL g tycon - aboveListL [jlistL typeOfValL mtyp.AllValsAndMembers - jlistL tyconL mtyp.AllEntities] - - and entityL g (ms: ModuleOrNamespace) = - let header = wordL(tagText "module") ^^ (wordL (tagText ms.DemangledModuleOrNamespaceName) |> stampL ms.Stamp) ^^ wordL(tagText ":") - let footer = wordL(tagText "end") - let body = entityTypeL g ms.ModuleOrNamespaceType - (header @@-- body) @@ footer - - and ccuL g (ccu: CcuThunk) = entityL g ccu.Contents - - and decisionTreeL g x = - let exprL expr = exprL g expr - let dcaseL dcases = dcaseL g dcases - match x with - | TDBind (bind, body) -> - let bind = wordL(tagText "let") ^^ bindingL g bind ^^ wordL(tagText "in") - (bind @@ decisionTreeL g body) - | TDSuccess (args, n) -> - wordL(tagText "Success") ^^ leftL(tagText "T") ^^ intL n ^^ tupleL (args |> List.map exprL) - | TDSwitch (test, dcases, dflt, _) -> - (wordL(tagText "Switch") --- exprL test) @@-- - (aboveListL (List.map dcaseL dcases) @@ - match dflt with - | None -> emptyL - | Some dtree -> wordL(tagText "dflt:") --- decisionTreeL g dtree) - - and dcaseL g (TCase (test, dtree)) = (dtestL g test ^^ wordL(tagText "//")) --- decisionTreeL g dtree - - and dtestL g x = - match x with - | (DecisionTreeTest.UnionCase (c, tinst)) -> wordL(tagText "is") ^^ unionCaseRefL c ^^ instL typeL tinst - | (DecisionTreeTest.ArrayLength (n, ty)) -> wordL(tagText "length") ^^ intL n ^^ typeL ty - | (DecisionTreeTest.Const c) -> wordL(tagText "is") ^^ constL c - | (DecisionTreeTest.IsNull ) -> wordL(tagText "isnull") - | (DecisionTreeTest.IsInst (_, ty)) -> wordL(tagText "isinst") ^^ typeL ty - | (DecisionTreeTest.ActivePatternCase (exp, _, _, _, _)) -> wordL(tagText "query") ^^ exprL g exp - - and targetL g i (TTarget (argvs, body, _)) = leftL(tagText "T") ^^ intL i ^^ tupleL (flatValsL argvs) ^^ rightL(tagText ":") --- exprL g body - - and flatValsL vs = vs |> List.map valL - - and tmethodL g (TObjExprMethod(TSlotSig(nm, _, _, _, _, _), _, tps, vs, e, _)) = - let valAtBindL v = valAtBindL g v - (wordL(tagText "TObjExprMethod") --- (wordL (tagText nm)) ^^ wordL(tagText "=")) -- - (wordL(tagText "METH-LAM") --- angleBracketListL (List.map typarL tps) ^^ rightL(tagText ".")) --- - (wordL(tagText "meth-lam") --- tupleL (List.map (List.map valAtBindL >> tupleL) vs) ^^ rightL(tagText ".")) --- - (atomL g e) - - and overrideL g tmeth = wordL(tagText "with") ^^ tmethodL g tmeth - - and iimplL g (ty, tmeths) = - let tmethodL p = tmethodL g p - wordL(tagText "impl") ^^ aboveListL (typeL ty :: List.map tmethodL tmeths) - - let showType x = Layout.showL (typeL x) - - let showExpr g x = Layout.showL (exprL g x) - - let traitL x = auxTraitL SimplifyTypes.typeSimplificationInfo0 x - - let typarsL x = layoutTyparDecls x - -//-------------------------------------------------------------------------- -// Helpers related to type checking modules & namespaces -//-------------------------------------------------------------------------- - -let wrapModuleOrNamespaceType id cpath mtyp = - NewModuleOrNamespace (Some cpath) taccessPublic id XmlDoc.Empty [] (MaybeLazy.Strict mtyp) - -let wrapModuleOrNamespaceTypeInNamespace id cpath mtyp = - let mspec = wrapModuleOrNamespaceType id cpath mtyp - NewModuleOrNamespaceType Namespace [ mspec ] [], mspec - -let wrapModuleOrNamespaceExprInNamespace (id: Ident) cpath mexpr = - let mspec = wrapModuleOrNamespaceType id cpath (NewEmptyModuleOrNamespaceType Namespace) - TMDefRec (false, [], [ModuleOrNamespaceBinding.Module(mspec, mexpr)], id.idRange) - -// cleanup: make this a property -let SigTypeOfImplFile (TImplFile (_, _, mexpr, _, _, _)) = mexpr.Type - -//-------------------------------------------------------------------------- -// Data structures representing what gets hidden and what gets remapped (i.e. renamed or alpha-converted) -// when a module signature is applied to a module. -//-------------------------------------------------------------------------- - -type SignatureRepackageInfo = - { RepackagedVals: (ValRef * ValRef) list - RepackagedEntities: (TyconRef * TyconRef) list } - - member remapInfo.ImplToSigMapping = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } - static member Empty = { RepackagedVals = []; RepackagedEntities= [] } - -type SignatureHidingInfo = - { HiddenTycons: Zset - HiddenTyconReprs: Zset - HiddenVals: Zset - HiddenRecdFields: Zset - HiddenUnionCases: Zset } - - static member Empty = - { HiddenTycons = Zset.empty tyconOrder - HiddenTyconReprs = Zset.empty tyconOrder - HiddenVals = Zset.empty valOrder - HiddenRecdFields = Zset.empty recdFieldRefOrder - HiddenUnionCases = Zset.empty unionCaseRefOrder } - -let addValRemap v vNew tmenv = - { tmenv with valRemap= tmenv.valRemap.Add v (mkLocalValRef vNew) } - -let mkRepackageRemapping mrpi = - { valRemap = ValMap.OfList (mrpi.RepackagedVals |> List.map (fun (vref, x) -> vref.Deref, x)) - tpinst = emptyTyparInst - tyconRefRemap = TyconRefMap.OfList mrpi.RepackagedEntities - removeTraitSolutions = false } - -//-------------------------------------------------------------------------- -// Compute instances of the above for mty -> mty -//-------------------------------------------------------------------------- - -let accEntityRemap (msigty: ModuleOrNamespaceType) (entity: Entity) (mrpi, mhi) = - let sigtyconOpt = (NameMap.tryFind entity.LogicalName msigty.AllEntitiesByCompiledAndLogicalMangledNames) - match sigtyconOpt with - | None -> - // The type constructor is not present in the signature. Hence it is hidden. - let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } - (mrpi, mhi) - | Some sigtycon -> - // The type constructor is in the signature. Hence record the repackage entry - let sigtcref = mkLocalTyconRef sigtycon - let tcref = mkLocalTyconRef entity - let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } - // OK, now look for hidden things - let mhi = - if (match entity.TypeReprInfo with TNoRepr -> false | _ -> true) && (match sigtycon.TypeReprInfo with TNoRepr -> true | _ -> false) then - // The type representation is absent in the signature, hence it is hidden - { mhi with HiddenTyconReprs = Zset.add entity mhi.HiddenTyconReprs } - else - // The type representation is present in the signature. - // Find the fields that have been hidden or which were non-public anyway. - let mhi = - (entity.AllFieldsArray, mhi) ||> Array.foldBack (fun rfield mhi -> - match sigtycon.GetFieldByName(rfield.Name) with - | Some _ -> - // The field is in the signature. Hence it is not hidden. - mhi - | _ -> - // The field is not in the signature. Hence it is regarded as hidden. - let rfref = tcref.MakeNestedRecdFieldRef rfield - { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields }) - - let mhi = - (entity.UnionCasesAsList, mhi) ||> List.foldBack (fun ucase mhi -> - match sigtycon.GetUnionCaseByName ucase.DisplayName with - | Some _ -> - // The constructor is in the signature. Hence it is not hidden. - mhi - | _ -> - // The constructor is not in the signature. Hence it is regarded as hidden. - let ucref = tcref.MakeNestedUnionCaseRef ucase - { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases }) - mhi - (mrpi, mhi) - -let accSubEntityRemap (msigty: ModuleOrNamespaceType) (entity: Entity) (mrpi, mhi) = - let sigtyconOpt = (NameMap.tryFind entity.LogicalName msigty.AllEntitiesByCompiledAndLogicalMangledNames) - match sigtyconOpt with - | None -> - // The type constructor is not present in the signature. Hence it is hidden. - let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } - (mrpi, mhi) - | Some sigtycon -> - // The type constructor is in the signature. Hence record the repackage entry - let sigtcref = mkLocalTyconRef sigtycon - let tcref = mkLocalTyconRef entity - let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } - (mrpi, mhi) - -let valLinkageAEquiv g aenv (v1: Val) (v2: Val) = - (v1.GetLinkagePartialKey() = v2.GetLinkagePartialKey()) && - (if v1.IsMember && v2.IsMember then typeAEquivAux EraseAll g aenv v1.Type v2.Type else true) - -let accValRemap g aenv (msigty: ModuleOrNamespaceType) (implVal: Val) (mrpi, mhi) = - let implValKey = implVal.GetLinkagePartialKey() - let sigValOpt = - msigty.AllValsAndMembersByPartialLinkageKey - |> MultiMap.find implValKey - |> List.tryFind (fun sigVal -> valLinkageAEquiv g aenv implVal sigVal) - - let vref = mkLocalValRef implVal - match sigValOpt with - | None -> - if verbose then dprintf "accValRemap, hide = %s#%d\n" implVal.LogicalName implVal.Stamp - let mhi = { mhi with HiddenVals = Zset.add implVal mhi.HiddenVals } - (mrpi, mhi) - | Some (sigVal: Val) -> - // The value is in the signature. Add the repackage entry. - let mrpi = { mrpi with RepackagedVals = (vref, mkLocalValRef sigVal) :: mrpi.RepackagedVals } - (mrpi, mhi) - -let getCorrespondingSigTy nm (msigty: ModuleOrNamespaceType) = - match NameMap.tryFind nm msigty.AllEntitiesByCompiledAndLogicalMangledNames with - | None -> NewEmptyModuleOrNamespaceType ModuleOrType - | Some sigsubmodul -> sigsubmodul.ModuleOrNamespaceType - -let rec accEntityRemapFromModuleOrNamespaceType (mty: ModuleOrNamespaceType) (msigty: ModuleOrNamespaceType) acc = - let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (fun e acc -> accEntityRemapFromModuleOrNamespaceType e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) - let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (accEntityRemap msigty) - acc - -let rec accValRemapFromModuleOrNamespaceType g aenv (mty: ModuleOrNamespaceType) msigty acc = - let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (fun e acc -> accValRemapFromModuleOrNamespaceType g aenv e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) - let acc = (mty.AllValsAndMembers, acc) ||> QueueList.foldBack (accValRemap g aenv msigty) - acc - -let ComputeRemappingFromInferredSignatureToExplicitSignature g mty msigty = - // dprintf "ComputeRemappingFromInferredSignatureToExplicitSignature, \nmty = %s\nmmsigty=%s\n" (showL(entityTypeL mty)) (showL(entityTypeL msigty)) - let ((mrpi, _) as entityRemap) = accEntityRemapFromModuleOrNamespaceType mty msigty (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) - let aenv = mrpi.ImplToSigMapping - let valAndEntityRemap = accValRemapFromModuleOrNamespaceType g aenv mty msigty entityRemap - valAndEntityRemap - -//-------------------------------------------------------------------------- -// Compute instances of the above for mexpr -> mty -//-------------------------------------------------------------------------- - -/// At TMDefRec nodes abstract (virtual) vslots are effectively binders, even -/// though they are tucked away inside the tycon. This helper function extracts the -/// virtual slots to aid with finding this babies. -let abstractSlotValsOfTycons (tycons: Tycon list) = - tycons - |> List.collect (fun tycon -> if tycon.IsFSharpObjectModelTycon then tycon.FSharpObjectModelTypeInfo.fsobjmodel_vslots else []) - |> List.map (fun v -> v.Deref) - -let rec accEntityRemapFromModuleOrNamespace msigty x acc = - match x with - | TMDefRec(_, tycons, mbinds, _) -> - let acc = (mbinds, acc) ||> List.foldBack (accEntityRemapFromModuleOrNamespaceBind msigty) - let acc = (tycons, acc) ||> List.foldBack (accEntityRemap msigty) - let acc = (tycons, acc) ||> List.foldBack (fun e acc -> accEntityRemapFromModuleOrNamespaceType e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) - acc - | TMDefLet _ -> acc - | TMDefDo _ -> acc - | TMDefs defs -> accEntityRemapFromModuleOrNamespaceDefs msigty defs acc - | TMAbstract mexpr -> accEntityRemapFromModuleOrNamespaceType mexpr.Type msigty acc - -and accEntityRemapFromModuleOrNamespaceDefs msigty mdefs acc = - List.foldBack (accEntityRemapFromModuleOrNamespace msigty) mdefs acc - -and accEntityRemapFromModuleOrNamespaceBind msigty x acc = - match x with - | ModuleOrNamespaceBinding.Binding _ -> acc - | ModuleOrNamespaceBinding.Module(mspec, def) -> - accSubEntityRemap msigty mspec (accEntityRemapFromModuleOrNamespace (getCorrespondingSigTy mspec.LogicalName msigty) def acc) - -let rec accValRemapFromModuleOrNamespace g aenv msigty x acc = - match x with - | TMDefRec(_, tycons, mbinds, _) -> - let acc = (mbinds, acc) ||> List.foldBack (accValRemapFromModuleOrNamespaceBind g aenv msigty) - // Abstract (virtual) vslots in the tycons at TMDefRec nodes are binders. They also need to be added to the remapping. - let vslotvs = abstractSlotValsOfTycons tycons - let acc = (vslotvs, acc) ||> List.foldBack (accValRemap g aenv msigty) - acc - | TMDefLet(bind, _) -> accValRemap g aenv msigty bind.Var acc - | TMDefDo _ -> acc - | TMDefs defs -> accValRemapFromModuleOrNamespaceDefs g aenv msigty defs acc - | TMAbstract mexpr -> accValRemapFromModuleOrNamespaceType g aenv mexpr.Type msigty acc - -and accValRemapFromModuleOrNamespaceBind g aenv msigty x acc = - match x with - | ModuleOrNamespaceBinding.Binding bind -> accValRemap g aenv msigty bind.Var acc - | ModuleOrNamespaceBinding.Module(mspec, def) -> - accSubEntityRemap msigty mspec (accValRemapFromModuleOrNamespace g aenv (getCorrespondingSigTy mspec.LogicalName msigty) def acc) - -and accValRemapFromModuleOrNamespaceDefs g aenv msigty mdefs acc = List.foldBack (accValRemapFromModuleOrNamespace g aenv msigty) mdefs acc - -let ComputeRemappingFromImplementationToSignature g mdef msigty = - //if verbose then dprintf "ComputeRemappingFromImplementationToSignature, \nmdefs = %s\nmsigty=%s\n" (showL(DebugPrint.mdefL mdef)) (showL(DebugPrint.entityTypeL msigty)) - let ((mrpi, _) as entityRemap) = accEntityRemapFromModuleOrNamespace msigty mdef (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) - let aenv = mrpi.ImplToSigMapping - - let valAndEntityRemap = accValRemapFromModuleOrNamespace g aenv msigty mdef entityRemap - valAndEntityRemap - -//-------------------------------------------------------------------------- -// Compute instances of the above for the assembly boundary -//-------------------------------------------------------------------------- - -let accTyconHidingInfoAtAssemblyBoundary (tycon: Tycon) mhi = - if not (canAccessFromEverywhere tycon.Accessibility) then - // The type constructor is not public, hence hidden at the assembly boundary. - { mhi with HiddenTycons = Zset.add tycon mhi.HiddenTycons } - elif not (canAccessFromEverywhere tycon.TypeReprAccessibility) then - { mhi with HiddenTyconReprs = Zset.add tycon mhi.HiddenTyconReprs } - else - let mhi = - (tycon.AllFieldsArray, mhi) ||> Array.foldBack (fun rfield mhi -> - if not (canAccessFromEverywhere rfield.Accessibility) then - let tcref = mkLocalTyconRef tycon - let rfref = tcref.MakeNestedRecdFieldRef rfield - { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields } - else mhi) - let mhi = - (tycon.UnionCasesAsList, mhi) ||> List.foldBack (fun ucase mhi -> - if not (canAccessFromEverywhere ucase.Accessibility) then - let tcref = mkLocalTyconRef tycon - let ucref = tcref.MakeNestedUnionCaseRef ucase - { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases } - else mhi) - mhi - -// Collect up the values hidden at the assembly boundary. This is used by IsHiddenVal to -// determine if something is considered hidden. This is used in turn to eliminate optimization -// information at the assembly boundary and to decide to label things as "internal". -let accValHidingInfoAtAssemblyBoundary (vspec: Val) mhi = - if // anything labelled "internal" or more restrictive is considered to be hidden at the assembly boundary - not (canAccessFromEverywhere vspec.Accessibility) || - // compiler generated members for class function 'let' bindings are considered to be hidden at the assembly boundary - vspec.IsIncrClassGeneratedMember || - // anything that's not a module or member binding gets assembly visibility - not vspec.IsMemberOrModuleBinding then - // The value is not public, hence hidden at the assembly boundary. - { mhi with HiddenVals = Zset.add vspec mhi.HiddenVals } - else - mhi - -let rec accModuleOrNamespaceHidingInfoAtAssemblyBoundary mty acc = - let acc = QueueList.foldBack (fun (e: Entity) acc -> accModuleOrNamespaceHidingInfoAtAssemblyBoundary e.ModuleOrNamespaceType acc) mty.AllEntities acc - let acc = QueueList.foldBack accTyconHidingInfoAtAssemblyBoundary mty.AllEntities acc - let acc = QueueList.foldBack accValHidingInfoAtAssemblyBoundary mty.AllValsAndMembers acc - acc - -let ComputeHidingInfoAtAssemblyBoundary mty acc = -// dprintf "ComputeRemappingFromInferredSignatureToExplicitSignature, \nmty = %s\nmmsigty=%s\n" (showL(entityTypeL mty)) (showL(entityTypeL msigty)) - accModuleOrNamespaceHidingInfoAtAssemblyBoundary mty acc - -//-------------------------------------------------------------------------- -// Compute instances of the above for mexpr -> mty -//-------------------------------------------------------------------------- - -let IsHidden setF accessF remapF debugF = - let rec check mrmi x = - if verbose then dprintf "IsHidden %s ??\n" (showL (debugF x)) - // Internal/private? - not (canAccessFromEverywhere (accessF x)) || - (match mrmi with - | [] -> false // Ah! we escaped to freedom! - | (rpi, mhi) :: rest -> - // Explicitly hidden? - Zset.contains x (setF mhi) || - // Recurse... - check rest (remapF rpi x)) - fun mrmi x -> - let res = check mrmi x - if verbose then dprintf "IsHidden, #mrmi = %d, %s = %b\n" mrmi.Length (showL (debugF x)) res - res - -let IsHiddenTycon g mrmi x = - let debugPrint x = DebugPrint.tyconL g x - IsHidden (fun mhi -> mhi.HiddenTycons) (fun tc -> tc.Accessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) debugPrint mrmi x -let IsHiddenTyconRepr g mrmi x = - let debugPrint x = DebugPrint.tyconL g x - IsHidden (fun mhi -> mhi.HiddenTyconReprs) (fun v -> v.TypeReprAccessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) debugPrint mrmi x -let IsHiddenVal mrmi x = IsHidden (fun mhi -> mhi.HiddenVals) (fun v -> v.Accessibility) (fun rpi x -> (remapValRef rpi (mkLocalValRef x)).Deref) DebugPrint.valL mrmi x -let IsHiddenRecdField mrmi x = IsHidden (fun mhi -> mhi.HiddenRecdFields) (fun rfref -> rfref.RecdField.Accessibility) (fun rpi x -> remapRecdFieldRef rpi.tyconRefRemap x) DebugPrint.recdFieldRefL mrmi x - -//-------------------------------------------------------------------------- -// Generic operations on module types -//-------------------------------------------------------------------------- - -let foldModuleOrNamespaceTy ft fv mty acc = - let rec go mty acc = - let acc = QueueList.foldBack (fun (e: Entity) acc -> go e.ModuleOrNamespaceType acc) mty.AllEntities acc - let acc = QueueList.foldBack ft mty.AllEntities acc - let acc = QueueList.foldBack fv mty.AllValsAndMembers acc - acc - go mty acc - -let allValsOfModuleOrNamespaceTy m = foldModuleOrNamespaceTy (fun _ acc -> acc) (fun v acc -> v :: acc) m [] -let allEntitiesOfModuleOrNamespaceTy m = foldModuleOrNamespaceTy (fun ft acc -> ft :: acc) (fun _ acc -> acc) m [] - -//--------------------------------------------------------------------------- -// Free variables in terms. Are all constructs public accessible? -//--------------------------------------------------------------------------- - -let isPublicVal (lv: Val) = (lv.Accessibility = taccessPublic) -let isPublicUnionCase (ucr: UnionCaseRef) = (ucr.UnionCase.Accessibility = taccessPublic) -let isPublicRecdField (rfr: RecdFieldRef) = (rfr.RecdField.Accessibility = taccessPublic) -let isPublicTycon (tcref: Tycon) = (tcref.Accessibility = taccessPublic) - -let freeVarsAllPublic fvs = - // Are any non-public items used in the expr (which corresponded to the fvs)? - // Recall, taccess occurs in: - // EntityData has ReprAccessibility and Accessibility - // UnionCase has Accessibility - // RecdField has Accessibility - // ValData has Accessibility - // The freevars and FreeTyvars collect local constructs. - // Here, we test that all those constructs are public. - // - // CODE REVIEW: - // What about non-local vals. This fix assumes non-local vals must be public. OK? - Zset.forall isPublicVal fvs.FreeLocals && - Zset.forall isPublicUnionCase fvs.FreeUnionCases && - Zset.forall isPublicRecdField fvs.FreeRecdFields && - Zset.forall isPublicTycon fvs.FreeTyvars.FreeTycons - -let freeTyvarsAllPublic tyvars = - Zset.forall isPublicTycon tyvars.FreeTycons - -/// Detect the subset of match expressions we process in a linear way (i.e. using tailcalls, rather than -/// unbounded stack) -/// -- if then else -/// -- match e with pat[vs] -> e1[vs] | _ -> e2 - -let (|LinearMatchExpr|_|) expr = - match expr with - | Expr.Match (sp, m, dtree, [|tg1;(TTarget([], e2, sp2))|], m2, ty) -> Some(sp, m, dtree, tg1, e2, sp2, m2, ty) - | _ -> None - -let rebuildLinearMatchExpr (sp, m, dtree, tg1, e2, sp2, m2, ty) = - primMkMatch (sp, m, dtree, [|tg1;(TTarget([], e2, sp2))|], m2, ty) - -/// Detect a subset of 'Expr.Op' expressions we process in a linear way (i.e. using tailcalls, rather than -/// unbounded stack). Only covers Cons(args,Cons(args,Cons(args,Cons(args,...._)))). -let (|LinearOpExpr|_|) expr = - match expr with - | Expr.Op ((TOp.UnionCase _ as op), tinst, args, m) when not args.IsEmpty -> - let argsFront, argLast = List.frontAndBack args - Some (op, tinst, argsFront, argLast, m) - | _ -> None - -let rebuildLinearOpExpr (op, tinst, argsFront, argLast, m) = - Expr.Op (op, tinst, argsFront@[argLast], m) - -//--------------------------------------------------------------------------- -// Free variables in terms. All binders are distinct. -//--------------------------------------------------------------------------- - -let emptyFreeVars = - { UsesMethodLocalConstructs=false - UsesUnboundRethrow=false - FreeLocalTyconReprs=emptyFreeTycons - FreeLocals=emptyFreeLocals - FreeTyvars=emptyFreeTyvars - FreeRecdFields = emptyFreeRecdFields - FreeUnionCases = emptyFreeUnionCases} - -let unionFreeVars fvs1 fvs2 = - if fvs1 === emptyFreeVars then fvs2 else - if fvs2 === emptyFreeVars then fvs1 else - { FreeLocals = unionFreeLocals fvs1.FreeLocals fvs2.FreeLocals - FreeTyvars = unionFreeTyvars fvs1.FreeTyvars fvs2.FreeTyvars - UsesMethodLocalConstructs = fvs1.UsesMethodLocalConstructs || fvs2.UsesMethodLocalConstructs - UsesUnboundRethrow = fvs1.UsesUnboundRethrow || fvs2.UsesUnboundRethrow - FreeLocalTyconReprs = unionFreeTycons fvs1.FreeLocalTyconReprs fvs2.FreeLocalTyconReprs - FreeRecdFields = unionFreeRecdFields fvs1.FreeRecdFields fvs2.FreeRecdFields - FreeUnionCases = unionFreeUnionCases fvs1.FreeUnionCases fvs2.FreeUnionCases } - -let inline accFreeTyvars (opts: FreeVarOptions) f v acc = - if not opts.collectInTypes then acc else - let ftyvs = acc.FreeTyvars - let ftyvs' = f opts v ftyvs - if ftyvs === ftyvs' then acc else - { acc with FreeTyvars = ftyvs' } - -let accFreeVarsInTy opts ty acc = accFreeTyvars opts accFreeInType ty acc -let accFreeVarsInTys opts tys acc = if isNil tys then acc else accFreeTyvars opts accFreeInTypes tys acc -let accFreevarsInTycon opts tcref acc = accFreeTyvars opts accFreeTycon tcref acc -let accFreevarsInVal opts v acc = accFreeTyvars opts accFreeInVal v acc - -let accFreeVarsInTraitSln opts tys acc = accFreeTyvars opts accFreeInTraitSln tys acc - -let boundLocalVal opts v fvs = - if not opts.includeLocals then fvs else - let fvs = accFreevarsInVal opts v fvs - if not (Zset.contains v fvs.FreeLocals) then fvs - else {fvs with FreeLocals= Zset.remove v fvs.FreeLocals} - -let boundProtect fvs = - if fvs.UsesMethodLocalConstructs then {fvs with UsesMethodLocalConstructs = false} else fvs - -let accUsesFunctionLocalConstructs flg fvs = - if flg && not fvs.UsesMethodLocalConstructs then {fvs with UsesMethodLocalConstructs = true} - else fvs - -let bound_rethrow fvs = - if fvs.UsesUnboundRethrow then {fvs with UsesUnboundRethrow = false} else fvs - -let accUsesRethrow flg fvs = - if flg && not fvs.UsesUnboundRethrow then {fvs with UsesUnboundRethrow = true} - else fvs - -let boundLocalVals opts vs fvs = List.foldBack (boundLocalVal opts) vs fvs - -let bindLhs opts (bind: Binding) fvs = boundLocalVal opts bind.Var fvs - -let freeVarsCacheCompute opts cache f = if opts.canCache then cached cache f else f() - -let tryGetFreeVarsCacheValue opts cache = - if opts.canCache then tryGetCacheValue cache - else ValueNone - -let rec accBindRhs opts (TBind(_, repr, _)) acc = accFreeInExpr opts repr acc - -and accFreeInSwitchCases opts csl dflt (acc: FreeVars) = - Option.foldBack (accFreeInDecisionTree opts) dflt (List.foldBack (accFreeInSwitchCase opts) csl acc) - -and accFreeInSwitchCase opts (TCase(discrim, dtree)) acc = - accFreeInDecisionTree opts dtree (accFreeInTest opts discrim acc) - -and accFreeInTest (opts: FreeVarOptions) discrim acc = - match discrim with - | DecisionTreeTest.UnionCase(ucref, tinst) -> accFreeUnionCaseRef opts ucref (accFreeVarsInTys opts tinst acc) - | DecisionTreeTest.ArrayLength(_, ty) -> accFreeVarsInTy opts ty acc - | DecisionTreeTest.Const _ - | DecisionTreeTest.IsNull -> acc - | DecisionTreeTest.IsInst (srcty, tgty) -> accFreeVarsInTy opts srcty (accFreeVarsInTy opts tgty acc) - | DecisionTreeTest.ActivePatternCase (exp, tys, activePatIdentity, _, _) -> - accFreeInExpr opts exp - (accFreeVarsInTys opts tys - (Option.foldBack (fun (vref, tinst) acc -> accFreeValRef opts vref (accFreeVarsInTys opts tinst acc)) activePatIdentity acc)) - -and accFreeInDecisionTree opts x (acc: FreeVars) = - match x with - | TDSwitch(e1, csl, dflt, _) -> accFreeInExpr opts e1 (accFreeInSwitchCases opts csl dflt acc) - | TDSuccess (es, _) -> accFreeInFlatExprs opts es acc - | TDBind (bind, body) -> unionFreeVars (bindLhs opts bind (accBindRhs opts bind (freeInDecisionTree opts body))) acc - -and accFreeInValFlags opts flag acc = - let isMethLocal = - match flag with - | VSlotDirectCall - | CtorValUsedAsSelfInit - | CtorValUsedAsSuperInit -> true - | PossibleConstrainedCall _ - | NormalValUse -> false - let acc = accUsesFunctionLocalConstructs isMethLocal acc - match flag with - | PossibleConstrainedCall ty -> accFreeTyvars opts accFreeInType ty acc - | _ -> acc - -and accFreeLocalVal opts v fvs = - if not opts.includeLocals then fvs else - if Zset.contains v fvs.FreeLocals then fvs - else - let fvs = accFreevarsInVal opts v fvs - {fvs with FreeLocals=Zset.add v fvs.FreeLocals} - -and accLocalTyconRepr opts b fvs = - if not opts.includeLocalTyconReprs then fvs else - if Zset.contains b fvs.FreeLocalTyconReprs then fvs - else { fvs with FreeLocalTyconReprs = Zset.add b fvs.FreeLocalTyconReprs } - -and accUsedRecdOrUnionTyconRepr opts (tc: Tycon) fvs = - if match tc.TypeReprInfo with TFSharpObjectRepr _ | TRecdRepr _ | TUnionRepr _ -> true | _ -> false - then accLocalTyconRepr opts tc fvs - else fvs - -and accFreeUnionCaseRef opts ucref fvs = - if not opts.includeUnionCases then fvs else - if Zset.contains ucref fvs.FreeUnionCases then fvs - else - let fvs = fvs |> accUsedRecdOrUnionTyconRepr opts ucref.Tycon - let fvs = fvs |> accFreevarsInTycon opts ucref.TyconRef - { fvs with FreeUnionCases = Zset.add ucref fvs.FreeUnionCases } - -and accFreeRecdFieldRef opts rfref fvs = - if not opts.includeRecdFields then fvs else - if Zset.contains rfref fvs.FreeRecdFields then fvs - else - let fvs = fvs |> accUsedRecdOrUnionTyconRepr opts rfref.Tycon - let fvs = fvs |> accFreevarsInTycon opts rfref.TyconRef - { fvs with FreeRecdFields = Zset.add rfref fvs.FreeRecdFields } - -and accFreeExnRef _exnc fvs = fvs // Note: this exnc (TyconRef) should be collected the surround types, e.g. tinst of Expr.Op -and accFreeValRef opts (vref: ValRef) fvs = - match vref.IsLocalRef with - | true -> accFreeLocalVal opts vref.PrivateTarget fvs - // non-local values do not contain free variables - | _ -> fvs - -and accFreeInMethod opts (TObjExprMethod(slotsig, _attribs, tps, tmvs, e, _)) acc = - accFreeInSlotSig opts slotsig - (unionFreeVars (accFreeTyvars opts boundTypars tps (List.foldBack (boundLocalVals opts) tmvs (freeInExpr opts e))) acc) - -and accFreeInMethods opts methods acc = - List.foldBack (accFreeInMethod opts) methods acc - -and accFreeInInterfaceImpl opts (ty, overrides) acc = - accFreeVarsInTy opts ty (accFreeInMethods opts overrides acc) - -and accFreeInExpr (opts: FreeVarOptions) x acc = - match x with - | Expr.Let _ -> accFreeInExprLinear opts x acc (fun e -> e) - | _ -> accFreeInExprNonLinear opts x acc - -and accFreeInExprLinear (opts: FreeVarOptions) x acc contf = - // for nested let-bindings, we need to continue after the whole let-binding is processed - match x with - | Expr.Let (bind, e, _, cache) -> - match tryGetFreeVarsCacheValue opts cache with - | ValueSome free -> contf (unionFreeVars free acc) - | _ -> - accFreeInExprLinear opts e emptyFreeVars (contf << (fun free -> - unionFreeVars (freeVarsCacheCompute opts cache (fun () -> bindLhs opts bind (accBindRhs opts bind free))) acc - )) - | _ -> - // No longer linear expr - contf (accFreeInExpr opts x acc) - -and accFreeInExprNonLinear opts x acc = - match x with - - // BINDING CONSTRUCTS - | Expr.Lambda (_, ctorThisValOpt, baseValOpt, vs, bodyExpr, _, rty) -> - unionFreeVars - (Option.foldBack (boundLocalVal opts) ctorThisValOpt - (Option.foldBack (boundLocalVal opts) baseValOpt - (boundLocalVals opts vs - (accFreeVarsInTy opts rty - (freeInExpr opts bodyExpr))))) - acc - - | Expr.TyLambda (_, vs, bodyExpr, _, rty) -> - unionFreeVars (accFreeTyvars opts boundTypars vs (accFreeVarsInTy opts rty (freeInExpr opts bodyExpr))) acc - - | Expr.TyChoose (vs, bodyExpr, _) -> - unionFreeVars (accFreeTyvars opts boundTypars vs (freeInExpr opts bodyExpr)) acc - - | Expr.LetRec (binds, bodyExpr, _, cache) -> - unionFreeVars (freeVarsCacheCompute opts cache (fun () -> List.foldBack (bindLhs opts) binds (List.foldBack (accBindRhs opts) binds (freeInExpr opts bodyExpr)))) acc - - | Expr.Let _ -> - failwith "unreachable - linear expr" - - | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, _) -> - unionFreeVars - (boundProtect - (Option.foldBack (boundLocalVal opts) basev - (accFreeVarsInTy opts ty - (accFreeInExpr opts basecall - (accFreeInMethods opts overrides - (List.foldBack (accFreeInInterfaceImpl opts) iimpls emptyFreeVars)))))) - acc - - // NON-BINDING CONSTRUCTS - | Expr.Const _ -> acc - - | Expr.Val (lvr, flags, _) -> - accFreeInValFlags opts flags (accFreeValRef opts lvr acc) - - | Expr.Quote (ast, {contents=Some(_, argTypes, argExprs, _data)}, _, _, ty) -> - accFreeInExpr opts ast - (accFreeInExprs opts argExprs - (accFreeVarsInTys opts argTypes - (accFreeVarsInTy opts ty acc))) - - | Expr.Quote (ast, {contents=None}, _, _, ty) -> - accFreeInExpr opts ast (accFreeVarsInTy opts ty acc) - - | Expr.App (f0, f0ty, tyargs, args, _) -> - accFreeVarsInTy opts f0ty - (accFreeInExpr opts f0 - (accFreeVarsInTys opts tyargs - (accFreeInExprs opts args acc))) - - | Expr.Link eref -> accFreeInExpr opts !eref acc - - | Expr.Sequential (expr1, expr2, _, _, _) -> - let acc = accFreeInExpr opts expr1 acc - // tail-call - linear expression - accFreeInExpr opts expr2 acc - - | Expr.StaticOptimization (_, expr2, expr3, _) -> - accFreeInExpr opts expr2 (accFreeInExpr opts expr3 acc) - - | Expr.Match (_, _, dtree, targets, _, _) -> - match x with - // Handle if-then-else - | LinearMatchExpr(_, _, dtree, target, bodyExpr, _, _, _) -> - let acc = accFreeInDecisionTree opts dtree acc - let acc = accFreeInTarget opts target acc - accFreeInExpr opts bodyExpr acc // tailcall - - | _ -> - let acc = accFreeInDecisionTree opts dtree acc - accFreeInTargets opts targets acc - - | Expr.Op (TOp.TryCatch _, tinst, [expr1; expr2; expr3], _) -> - unionFreeVars - (accFreeVarsInTys opts tinst - (accFreeInExprs opts [expr1; expr2] acc)) - (bound_rethrow (accFreeInExpr opts expr3 emptyFreeVars)) - - | Expr.Op (op, tinst, args, _) -> - let acc = accFreeInOp opts op acc - let acc = accFreeVarsInTys opts tinst acc - accFreeInExprs opts args acc - -and accFreeInOp opts op acc = - match op with - - // Things containing no references - | TOp.Bytes _ - | TOp.UInt16s _ - | TOp.TryCatch _ - | TOp.TryFinally _ - | TOp.For _ - | TOp.Coerce - | TOp.RefAddrGet _ - | TOp.Array - | TOp.While _ - | TOp.Goto _ | TOp.Label _ | TOp.Return - | TOp.TupleFieldGet _ -> acc - - | TOp.Tuple tupInfo -> - accFreeTyvars opts accFreeInTupInfo tupInfo acc - - | TOp.AnonRecd anonInfo - | TOp.AnonRecdGet (anonInfo, _) -> - accFreeTyvars opts accFreeInTupInfo anonInfo.TupInfo acc - - | TOp.UnionCaseTagGet tcref -> - accUsedRecdOrUnionTyconRepr opts tcref.Deref acc - - // Things containing just a union case reference - | TOp.UnionCaseProof ucref - | TOp.UnionCase ucref - | TOp.UnionCaseFieldGetAddr (ucref, _, _) - | TOp.UnionCaseFieldGet (ucref, _) - | TOp.UnionCaseFieldSet (ucref, _) -> - accFreeUnionCaseRef opts ucref acc - - // Things containing just an exception reference - | TOp.ExnConstr ecref - | TOp.ExnFieldGet (ecref, _) - | TOp.ExnFieldSet (ecref, _) -> - accFreeExnRef ecref acc - - | TOp.ValFieldGet fref - | TOp.ValFieldGetAddr (fref, _) - | TOp.ValFieldSet fref -> - accFreeRecdFieldRef opts fref acc - - | TOp.Recd (kind, tcref) -> - let acc = accUsesFunctionLocalConstructs (kind = RecdExprIsObjInit) acc - (accUsedRecdOrUnionTyconRepr opts tcref.Deref (accFreeTyvars opts accFreeTycon tcref acc)) - - | TOp.ILAsm (_, tys) -> - accFreeVarsInTys opts tys acc - - | TOp.Reraise -> - accUsesRethrow true acc - - | TOp.TraitCall (TTrait(tys, _, _, argtys, rty, sln)) -> - Option.foldBack (accFreeVarsInTraitSln opts) sln.Value - (accFreeVarsInTys opts tys - (accFreeVarsInTys opts argtys - (Option.foldBack (accFreeVarsInTy opts) rty acc))) - - | TOp.LValueOp (_, vref) -> - accFreeValRef opts vref acc - - | TOp.ILCall (_, isProtectedCall, _, _, valUseFlags, _, _, _, enclTypeArgs, methTypeArgs, tys) -> - accFreeVarsInTys opts enclTypeArgs - (accFreeVarsInTys opts methTypeArgs - (accFreeInValFlags opts valUseFlags - (accFreeVarsInTys opts tys - (accUsesFunctionLocalConstructs isProtectedCall acc)))) - -and accFreeInTargets opts targets acc = - Array.foldBack (accFreeInTarget opts) targets acc - -and accFreeInTarget opts (TTarget(vs, expr, _)) acc = - List.foldBack (boundLocalVal opts) vs (accFreeInExpr opts expr acc) - -and accFreeInFlatExprs opts (exprs: Exprs) acc = List.foldBack (accFreeInExpr opts) exprs acc - -and accFreeInExprs opts (exprs: Exprs) acc = - match exprs with - | [] -> acc - | [h]-> - // tailcall - e.g. Cons(x, Cons(x2, .......Cons(x1000000, Nil))) and [| x1; .... ; x1000000 |] - accFreeInExpr opts h acc - | h :: t -> - let acc = accFreeInExpr opts h acc - accFreeInExprs opts t acc - -and accFreeInSlotSig opts (TSlotSig(_, ty, _, _, _, _)) acc = - accFreeVarsInTy opts ty acc - -and freeInDecisionTree opts dtree = - accFreeInDecisionTree opts dtree emptyFreeVars - -and freeInExpr opts expr = - accFreeInExpr opts expr emptyFreeVars - -// Note: these are only an approximation - they are currently used only by the optimizer -let rec accFreeInModuleOrNamespace opts mexpr acc = - match mexpr with - | TMDefRec(_, _, mbinds, _) -> List.foldBack (accFreeInModuleOrNamespaceBind opts) mbinds acc - | TMDefLet(bind, _) -> accBindRhs opts bind acc - | TMDefDo(e, _) -> accFreeInExpr opts e acc - | TMDefs defs -> accFreeInModuleOrNamespaces opts defs acc - | TMAbstract(ModuleOrNamespaceExprWithSig(_, mdef, _)) -> accFreeInModuleOrNamespace opts mdef acc // not really right, but sufficient for how this is used in optimization - -and accFreeInModuleOrNamespaceBind opts mbind acc = - match mbind with - | ModuleOrNamespaceBinding.Binding bind -> accBindRhs opts bind acc - | ModuleOrNamespaceBinding.Module (_, def) -> accFreeInModuleOrNamespace opts def acc - -and accFreeInModuleOrNamespaces opts mexprs acc = - List.foldBack (accFreeInModuleOrNamespace opts) mexprs acc - -let freeInBindingRhs opts bind = - accBindRhs opts bind emptyFreeVars - -let freeInModuleOrNamespace opts mdef = - accFreeInModuleOrNamespace opts mdef emptyFreeVars - -//--------------------------------------------------------------------------- -// Destruct - rarely needed -//--------------------------------------------------------------------------- - -let rec stripLambda (expr, ty) = - match expr with - | Expr.Lambda (_, ctorThisValOpt, baseValOpt, v, bodyExpr, _, rty) -> - if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", expr.Range)) - if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", expr.Range)) - let (vs', bodyExpr', rty') = stripLambda (bodyExpr, rty) - (v :: vs', bodyExpr', rty') - | _ -> ([], expr, ty) - -let rec stripLambdaN n expr = - assert (n >= 0) - match expr with - | Expr.Lambda (_, ctorThisValOpt, baseValOpt, v, bodyExpr, _, _) when n > 0 -> - if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", expr.Range)) - if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", expr.Range)) - let (vs, bodyExpr', remaining) = stripLambdaN (n-1) bodyExpr - (v :: vs, bodyExpr', remaining) - | _ -> ([], expr, n) - -let tryStripLambdaN n expr = - match expr with - | Expr.Lambda (_, None, None, _, _, _, _) -> - let argvsl, bodyExpr, remaining = stripLambdaN n expr - if remaining = 0 then Some (argvsl, bodyExpr) - else None - | _ -> None - -let stripTopLambda (expr, ty) = - let tps, taue, tauty = match expr with Expr.TyLambda (_, tps, b, _, rty) -> tps, b, rty | _ -> [], expr, ty - let vs, body, rty = stripLambda (taue, tauty) - tps, vs, body, rty - -[] -type AllowTypeDirectedDetupling = Yes | No - -// This is used to infer arities of expressions -// i.e. base the chosen arity on the syntactic expression shape and type of arguments -let InferArityOfExpr g allowTypeDirectedDetupling ty partialArgAttribsL retAttribs expr = - let rec stripLambda_notypes e = - match e with - | Expr.Lambda (_, _, _, vs, b, _, _) -> - let (vs', b') = stripLambda_notypes b - (vs :: vs', b') - | Expr.TyChoose (_, b, _) -> stripLambda_notypes b - | _ -> ([], e) - - let stripTopLambdaNoTypes e = - let tps, taue = match e with Expr.TyLambda (_, tps, b, _, _) -> tps, b | _ -> [], e - let vs, body = stripLambda_notypes taue - tps, vs, body - - let tps, vsl, _ = stripTopLambdaNoTypes expr - let fun_arity = vsl.Length - let dtys, _ = stripFunTyN g fun_arity (snd (tryDestForallTy g ty)) - let partialArgAttribsL = Array.ofList partialArgAttribsL - assert (List.length vsl = List.length dtys) - - let curriedArgInfos = - (List.zip vsl dtys) |> List.mapi (fun i (vs, ty) -> - let partialAttribs = if i < partialArgAttribsL.Length then partialArgAttribsL.[i] else [] - let tys = - match allowTypeDirectedDetupling with - | AllowTypeDirectedDetupling.No -> [ty] - | AllowTypeDirectedDetupling.Yes -> - if (i = 0 && isUnitTy g ty) then [] - else tryDestRefTupleTy g ty - let ids = - if vs.Length = tys.Length then vs |> List.map (fun v -> Some v.Id) - else tys |> List.map (fun _ -> None) - let attribs = - if partialAttribs.Length = tys.Length then partialAttribs - else tys |> List.map (fun _ -> []) - (ids, attribs) ||> List.map2 (fun id attribs -> { Name = id; Attribs = attribs }: ArgReprInfo )) - let retInfo: ArgReprInfo = { Attribs = retAttribs; Name = None } - ValReprInfo (ValReprInfo.InferTyparInfo tps, curriedArgInfos, retInfo) - -let InferArityOfExprBinding g allowTypeDirectedDetupling (v: Val) expr = - match v.ValReprInfo with - | Some info -> info - | None -> InferArityOfExpr g allowTypeDirectedDetupling v.Type [] [] expr - -//------------------------------------------------------------------------- -// Check if constraints are satisfied that allow us to use more optimized -// implementations -//------------------------------------------------------------------------- - -let underlyingTypeOfEnumTy (g: TcGlobals) ty = - assert(isEnumTy g ty) - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> info.UnderlyingTypeOfEnum() -#endif - | ILTypeMetadata (TILObjectReprData(_, _, tdef)) -> - - let info = computeILEnumInfo (tdef.Name, tdef.Fields) - let ilTy = getTyOfILEnumInfo info - match ilTy.TypeSpec.Name with - | "System.Byte" -> g.byte_ty - | "System.SByte" -> g.sbyte_ty - | "System.Int16" -> g.int16_ty - | "System.Int32" -> g.int32_ty - | "System.Int64" -> g.int64_ty - | "System.UInt16" -> g.uint16_ty - | "System.UInt32" -> g.uint32_ty - | "System.UInt64" -> g.uint64_ty - | "System.Single" -> g.float32_ty - | "System.Double" -> g.float_ty - | "System.Char" -> g.char_ty - | "System.Boolean" -> g.bool_ty - | _ -> g.int32_ty - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - let tycon = (tcrefOfAppTy g ty).Deref - match tycon.GetFieldByName "value__" with - | Some rf -> rf.FormalType - | None -> error(InternalError("no 'value__' field found for enumeration type " + tycon.LogicalName, tycon.Range)) - -// CLEANUP NOTE: Get rid of this mutation. -let setValHasNoArity (f: Val) = - f.SetValReprInfo None; f - -//-------------------------------------------------------------------------- -// Resolve static optimization constraints -//-------------------------------------------------------------------------- - -let normalizeEnumTy g ty = (if isEnumTy g ty then underlyingTypeOfEnumTy g ty else ty) - -type StaticOptimizationAnswer = - | Yes = 1y - | No = -1y - | Unknown = 0y - -let decideStaticOptimizationConstraint g c = - match c with - | TTyconEqualsTycon (a, b) -> - // Both types must be nominal for a definite result - let rec checkTypes a b = - let a = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g a) - match a with - | AppTy g (tcref1, _) -> - let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) - match b with - | AppTy g (tcref2, _) -> - if tyconRefEq g tcref1 tcref2 then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No - | RefTupleTy g _ | FunTy g _ -> StaticOptimizationAnswer.No - | _ -> StaticOptimizationAnswer.Unknown - - | FunTy g _ -> - let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) - match b with - | FunTy g _ -> StaticOptimizationAnswer.Yes - | AppTy g _ | RefTupleTy g _ -> StaticOptimizationAnswer.No - | _ -> StaticOptimizationAnswer.Unknown - | RefTupleTy g ts1 -> - let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) - match b with - | RefTupleTy g ts2 -> - if ts1.Length = ts2.Length then StaticOptimizationAnswer.Yes - else StaticOptimizationAnswer.No - | AppTy g _ | FunTy g _ -> StaticOptimizationAnswer.No - | _ -> StaticOptimizationAnswer.Unknown - | _ -> StaticOptimizationAnswer.Unknown - checkTypes a b - | TTyconIsStruct a -> - let a = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g a) - match tryDestAppTy g a with - | ValueSome tcref1 -> if tcref1.IsStructOrEnumTycon then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No - | ValueNone -> StaticOptimizationAnswer.Unknown - -let rec DecideStaticOptimizations g cs = - match cs with - | [] -> StaticOptimizationAnswer.Yes - | h :: t -> - let d = decideStaticOptimizationConstraint g h - if d = StaticOptimizationAnswer.No then StaticOptimizationAnswer.No - elif d = StaticOptimizationAnswer.Yes then DecideStaticOptimizations g t - else StaticOptimizationAnswer.Unknown - -let mkStaticOptimizationExpr g (cs, e1, e2, m) = - let d = DecideStaticOptimizations g cs in - if d = StaticOptimizationAnswer.No then e2 - elif d = StaticOptimizationAnswer.Yes then e1 - else Expr.StaticOptimization (cs, e1, e2, m) - -//-------------------------------------------------------------------------- -// Copy expressions, including new names for locally bound values. -// Used to inline expressions. -//-------------------------------------------------------------------------- - -type ValCopyFlag = - | CloneAll - | CloneAllAndMarkExprValsAsCompilerGenerated - | OnlyCloneExprVals - -// for quotations we do no want to avoid marking values as compiler generated since this may affect the shape of quotation (compiler generated values can be inlined) -let fixValCopyFlagForQuotations = function CloneAllAndMarkExprValsAsCompilerGenerated -> CloneAll | x -> x - -let markAsCompGen compgen d = - let compgen = - match compgen with - | CloneAllAndMarkExprValsAsCompilerGenerated -> true - | _ -> false - { d with val_flags= d.val_flags.SetIsCompilerGenerated(d.val_flags.IsCompilerGenerated || compgen) } - -let bindLocalVal (v: Val) (v': Val) tmenv = - { tmenv with valRemap=tmenv.valRemap.Add v (mkLocalValRef v') } - -let bindLocalVals vs vs' tmenv = - { tmenv with valRemap= (vs, vs', tmenv.valRemap) |||> List.foldBack2 (fun v v' acc -> acc.Add v (mkLocalValRef v') ) } - -let bindTycon (tc: Tycon) (tc': Tycon) tyenv = - { tyenv with tyconRefRemap=tyenv.tyconRefRemap.Add (mkLocalTyconRef tc) (mkLocalTyconRef tc') } - -let bindTycons tcs tcs' tyenv = - { tyenv with tyconRefRemap= (tcs, tcs', tyenv.tyconRefRemap) |||> List.foldBack2 (fun tc tc' acc -> acc.Add (mkLocalTyconRef tc) (mkLocalTyconRef tc')) } - -let remapAttribKind tmenv k = - match k with - | ILAttrib _ as x -> x - | FSAttrib vref -> FSAttrib(remapValRef tmenv vref) - -let tmenvCopyRemapAndBindTypars remapAttrib tmenv tps = - let tps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tmenv tps - let tmenvinner = tyenvinner - tps', tmenvinner - -let rec remapAttrib g tmenv (Attrib (tcref, kind, args, props, isGetOrSetAttr, targets, m)) = - Attrib(remapTyconRef tmenv.tyconRefRemap tcref, - remapAttribKind tmenv kind, - args |> List.map (remapAttribExpr g tmenv), - props |> List.map (fun (AttribNamedArg(nm, ty, flg, expr)) -> AttribNamedArg(nm, remapType tmenv ty, flg, remapAttribExpr g tmenv expr)), - isGetOrSetAttr, - targets, - m) - -and remapAttribExpr g tmenv (AttribExpr(e1, e2)) = - AttribExpr(remapExpr g CloneAll tmenv e1, remapExpr g CloneAll tmenv e2) - -and remapAttribs g tmenv xs = List.map (remapAttrib g tmenv) xs - -and remapPossibleForallTy g tmenv ty = remapTypeFull (remapAttribs g tmenv) tmenv ty - -and remapArgData g tmenv (argInfo: ArgReprInfo) : ArgReprInfo = - { Attribs = remapAttribs g tmenv argInfo.Attribs; Name = argInfo.Name } - -and remapValReprInfo g tmenv (ValReprInfo(tpNames, arginfosl, retInfo)) = - ValReprInfo(tpNames, List.mapSquared (remapArgData g tmenv) arginfosl, remapArgData g tmenv retInfo) - -and remapValData g tmenv (d: ValData) = - let ty = d.val_type - let topValInfo = d.ValReprInfo - let tyR = ty |> remapPossibleForallTy g tmenv - let declaringEntityR = d.DeclaringEntity |> remapParentRef tmenv - let reprInfoR = d.ValReprInfo |> Option.map (remapValReprInfo g tmenv) - let memberInfoR = d.MemberInfo |> Option.map (remapMemberInfo g d.val_range topValInfo ty tyR tmenv) - let attribsR = d.Attribs |> remapAttribs g tmenv - { d with - val_type = tyR - val_opt_data = - match d.val_opt_data with - | Some dd -> - Some { dd with - val_declaring_entity = declaringEntityR - val_repr_info = reprInfoR - val_member_info = memberInfoR - val_attribs = attribsR } - | None -> None } - -and remapParentRef tyenv p = - match p with - | ParentNone -> ParentNone - | Parent x -> Parent (x |> remapTyconRef tyenv.tyconRefRemap) - -and mapImmediateValsAndTycons ft fv (x: ModuleOrNamespaceType) = - let vals = x.AllValsAndMembers |> QueueList.map fv - let tycons = x.AllEntities |> QueueList.map ft - new ModuleOrNamespaceType(x.ModuleOrNamespaceKind, vals, tycons) - -and copyVal compgen (v: Val) = - match compgen with - | OnlyCloneExprVals when v.IsMemberOrModuleBinding -> v - | _ -> v |> NewModifiedVal id - -and fixupValData g compgen tmenv (v2: Val) = - // only fixup if we copy the value - match compgen with - | OnlyCloneExprVals when v2.IsMemberOrModuleBinding -> () - | _ -> - let newData = remapValData g tmenv v2 |> markAsCompGen compgen - // uses the same stamp - v2.SetData newData - -and copyAndRemapAndBindVals g compgen tmenv vs = - let vs2 = vs |> List.map (copyVal compgen) - let tmenvinner = bindLocalVals vs vs2 tmenv - vs2 |> List.iter (fixupValData g compgen tmenvinner) - vs2, tmenvinner - -and copyAndRemapAndBindVal g compgen tmenv v = - let v2 = v |> copyVal compgen - let tmenvinner = bindLocalVal v v2 tmenv - fixupValData g compgen tmenvinner v2 - v2, tmenvinner - -and remapExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) expr = - match expr with - - // Handle the linear cases for arbitrary-sized inputs - | LinearOpExpr _ - | LinearMatchExpr _ - | Expr.Sequential _ - | Expr.Let _ -> - remapLinearExpr g compgen tmenv expr (fun x -> x) - - // Binding constructs - see also dtrees below - | Expr.Lambda (_, ctorThisValOpt, baseValOpt, vs, b, m, rty) -> - let ctorThisValOpt, tmenv = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv ctorThisValOpt - let baseValOpt, tmenv = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv baseValOpt - let vs, tmenv = copyAndRemapAndBindVals g compgen tmenv vs - let b = remapExpr g compgen tmenv b - let rty = remapType tmenv rty - Expr.Lambda (newUnique(), ctorThisValOpt, baseValOpt, vs, b, m, rty) - - | Expr.TyLambda (_, tps, b, m, rty) -> - let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps - mkTypeLambda m tps' (remapExpr g compgen tmenvinner b, remapType tmenvinner rty) - - | Expr.TyChoose (tps, b, m) -> - let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps - Expr.TyChoose (tps', remapExpr g compgen tmenvinner b, m) - - | Expr.LetRec (binds, e, m, _) -> - let binds', tmenvinner = copyAndRemapAndBindBindings g compgen tmenv binds - Expr.LetRec (binds', remapExpr g compgen tmenvinner e, m, NewFreeVarsCache()) - - | Expr.Match (spBind, exprm, pt, targets, m, ty) -> - primMkMatch (spBind, exprm, remapDecisionTree g compgen tmenv pt, - targets |> Array.map (remapTarget g compgen tmenv), - m, remapType tmenv ty) - - | Expr.Val (vr, vf, m) -> - let vr' = remapValRef tmenv vr - let vf' = remapValFlags tmenv vf - if vr === vr' && vf === vf' then expr - else Expr.Val (vr', vf', m) - - | Expr.Quote (a, {contents=Some(typeDefs, argTypes, argExprs, data)}, isFromQueryExpression, m, ty) -> - // fix value of compgen for both original expression and pickled AST - let compgen = fixValCopyFlagForQuotations compgen - Expr.Quote (remapExpr g compgen tmenv a, {contents=Some(typeDefs, remapTypesAux tmenv argTypes, remapExprs g compgen tmenv argExprs, data)}, isFromQueryExpression, m, remapType tmenv ty) - - | Expr.Quote (a, {contents=None}, isFromQueryExpression, m, ty) -> - Expr.Quote (remapExpr g (fixValCopyFlagForQuotations compgen) tmenv a, {contents=None}, isFromQueryExpression, m, remapType tmenv ty) - - | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, m) -> - let basev', tmenvinner = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv basev - mkObjExpr (remapType tmenv ty, basev', - remapExpr g compgen tmenv basecall, - List.map (remapMethod g compgen tmenvinner) overrides, - List.map (remapInterfaceImpl g compgen tmenvinner) iimpls, m) - - // Addresses of immutable field may "leak" across assembly boundaries - see CanTakeAddressOfRecdFieldRef below. - // This is "ok", in the sense that it is always valid to fix these up to be uses - // of a temporary local, e.g. - // &(E.RF) --> let mutable v = E.RF in &v - - | Expr.Op (TOp.ValFieldGetAddr (rfref, readonly), tinst, [arg], m) when - not rfref.RecdField.IsMutable && - not (entityRefInThisAssembly g.compilingFslib rfref.TyconRef) -> - - let tinst = remapTypes tmenv tinst - let arg = remapExpr g compgen tmenv arg - let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfRecdFieldRef rfref tinst) - mkCompGenLet m tmp (mkRecdFieldGetViaExprAddr (arg, rfref, tinst, m)) (mkValAddr m readonly (mkLocalValRef tmp)) - - | Expr.Op (TOp.UnionCaseFieldGetAddr (uref, cidx, readonly), tinst, [arg], m) when - not (uref.FieldByIndex(cidx).IsMutable) && - not (entityRefInThisAssembly g.compilingFslib uref.TyconRef) -> - - let tinst = remapTypes tmenv tinst - let arg = remapExpr g compgen tmenv arg - let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfUnionFieldRef uref cidx tinst) - mkCompGenLet m tmp (mkUnionCaseFieldGetProvenViaExprAddr (arg, uref, tinst, cidx, m)) (mkValAddr m readonly (mkLocalValRef tmp)) - - | Expr.Op (op, tinst, args, m) -> - let op' = remapOp tmenv op - let tinst' = remapTypes tmenv tinst - let args' = remapExprs g compgen tmenv args - if op === op' && tinst === tinst' && args === args' then expr - else Expr.Op (op', tinst', args', m) - - | Expr.App (e1, e1ty, tyargs, args, m) -> - let e1' = remapExpr g compgen tmenv e1 - let e1ty' = remapPossibleForallTy g tmenv e1ty - let tyargs' = remapTypes tmenv tyargs - let args' = remapExprs g compgen tmenv args - if e1 === e1' && e1ty === e1ty' && tyargs === tyargs' && args === args' then expr - else Expr.App (e1', e1ty', tyargs', args', m) - - | Expr.Link eref -> - remapExpr g compgen tmenv !eref - - | Expr.StaticOptimization (cs, e2, e3, m) -> - // note that type instantiation typically resolve the static constraints here - mkStaticOptimizationExpr g (List.map (remapConstraint tmenv) cs, remapExpr g compgen tmenv e2, remapExpr g compgen tmenv e3, m) - - | Expr.Const (c, m, ty) -> - let ty' = remapType tmenv ty - if ty === ty' then expr else Expr.Const (c, m, ty') - -and remapTarget g compgen tmenv (TTarget(vs, e, spTarget)) = - let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenv vs - TTarget(vs', remapExpr g compgen tmenvinner e, spTarget) - -and remapLinearExpr g compgen tmenv expr contf = - - match expr with - - | Expr.Let (bind, bodyExpr, m, _) -> - let bind', tmenvinner = copyAndRemapAndBindBinding g compgen tmenv bind - // tailcall for the linear position - remapLinearExpr g compgen tmenvinner bodyExpr (contf << mkLetBind m bind') - - | Expr.Sequential (expr1, expr2, dir, spSeq, m) -> - let expr1' = remapExpr g compgen tmenv expr1 - // tailcall for the linear position - remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> - if expr1 === expr1' && expr2 === expr2' then expr - else Expr.Sequential (expr1', expr2', dir, spSeq, m))) - - | LinearMatchExpr (spBind, exprm, dtree, tg1, expr2, sp2, m2, ty) -> - let dtree' = remapDecisionTree g compgen tmenv dtree - let tg1' = remapTarget g compgen tmenv tg1 - let ty' = remapType tmenv ty - // tailcall for the linear position - remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> - rebuildLinearMatchExpr (spBind, exprm, dtree', tg1', expr2', sp2, m2, ty'))) - - | LinearOpExpr (op, tyargs, argsFront, argLast, m) -> - let op' = remapOp tmenv op - let tinst' = remapTypes tmenv tyargs - let argsFront' = remapExprs g compgen tmenv argsFront - // tailcall for the linear position - remapLinearExpr g compgen tmenv argLast (contf << (fun argLast' -> - if op === op' && tyargs === tinst' && argsFront === argsFront' && argLast === argLast' then expr - else rebuildLinearOpExpr (op', tinst', argsFront', argLast', m))) - - | _ -> - contf (remapExpr g compgen tmenv expr) - -and remapConstraint tyenv c = - match c with - | TTyconEqualsTycon(ty1, ty2) -> TTyconEqualsTycon(remapType tyenv ty1, remapType tyenv ty2) - | TTyconIsStruct ty1 -> TTyconIsStruct(remapType tyenv ty1) - -and remapOp tmenv op = - match op with - | TOp.Recd (ctor, tcref) -> TOp.Recd (ctor, remapTyconRef tmenv.tyconRefRemap tcref) - | TOp.UnionCaseTagGet tcref -> TOp.UnionCaseTagGet (remapTyconRef tmenv.tyconRefRemap tcref) - | TOp.UnionCase ucref -> TOp.UnionCase (remapUnionCaseRef tmenv.tyconRefRemap ucref) - | TOp.UnionCaseProof ucref -> TOp.UnionCaseProof (remapUnionCaseRef tmenv.tyconRefRemap ucref) - | TOp.ExnConstr ec -> TOp.ExnConstr (remapTyconRef tmenv.tyconRefRemap ec) - | TOp.ExnFieldGet (ec, n) -> TOp.ExnFieldGet (remapTyconRef tmenv.tyconRefRemap ec, n) - | TOp.ExnFieldSet (ec, n) -> TOp.ExnFieldSet (remapTyconRef tmenv.tyconRefRemap ec, n) - | TOp.ValFieldSet rfref -> TOp.ValFieldSet (remapRecdFieldRef tmenv.tyconRefRemap rfref) - | TOp.ValFieldGet rfref -> TOp.ValFieldGet (remapRecdFieldRef tmenv.tyconRefRemap rfref) - | TOp.ValFieldGetAddr (rfref, readonly) -> TOp.ValFieldGetAddr (remapRecdFieldRef tmenv.tyconRefRemap rfref, readonly) - | TOp.UnionCaseFieldGet (ucref, n) -> TOp.UnionCaseFieldGet (remapUnionCaseRef tmenv.tyconRefRemap ucref, n) - | TOp.UnionCaseFieldGetAddr (ucref, n, readonly) -> TOp.UnionCaseFieldGetAddr (remapUnionCaseRef tmenv.tyconRefRemap ucref, n, readonly) - | TOp.UnionCaseFieldSet (ucref, n) -> TOp.UnionCaseFieldSet (remapUnionCaseRef tmenv.tyconRefRemap ucref, n) - | TOp.ILAsm (instrs, tys) -> - let tys2 = remapTypes tmenv tys - if tys === tys2 then op else - TOp.ILAsm (instrs, tys2) - | TOp.TraitCall traitInfo -> TOp.TraitCall (remapTraitAux tmenv traitInfo) - | TOp.LValueOp (kind, lvr) -> TOp.LValueOp (kind, remapValRef tmenv lvr) - | TOp.ILCall (isVirtCall, isProtectedCall, valu, isNewObjCall, valUseFlags, isProperty, noTailCall, ilMethRef, enclTypeArgs, methTypeArgs, tys) -> - TOp.ILCall (isVirtCall, isProtectedCall, valu, isNewObjCall, remapValFlags tmenv valUseFlags, - isProperty, noTailCall, ilMethRef, remapTypes tmenv enclTypeArgs, - remapTypes tmenv methTypeArgs, remapTypes tmenv tys) - | _ -> op - -and remapValFlags tmenv x = - match x with - | PossibleConstrainedCall ty -> PossibleConstrainedCall (remapType tmenv ty) - | _ -> x - -and remapExprs g compgen tmenv es = List.mapq (remapExpr g compgen tmenv) es - -and remapFlatExprs g compgen tmenv es = List.mapq (remapExpr g compgen tmenv) es - -and remapDecisionTree g compgen tmenv x = - match x with - | TDSwitch(e1, csl, dflt, m) -> - TDSwitch(remapExpr g compgen tmenv e1, - List.map (fun (TCase(test, y)) -> - let test' = - match test with - | DecisionTreeTest.UnionCase (uc, tinst) -> DecisionTreeTest.UnionCase(remapUnionCaseRef tmenv.tyconRefRemap uc, remapTypes tmenv tinst) - | DecisionTreeTest.ArrayLength (n, ty) -> DecisionTreeTest.ArrayLength(n, remapType tmenv ty) - | DecisionTreeTest.Const _ -> test - | DecisionTreeTest.IsInst (srcty, tgty) -> DecisionTreeTest.IsInst (remapType tmenv srcty, remapType tmenv tgty) - | DecisionTreeTest.IsNull -> DecisionTreeTest.IsNull - | DecisionTreeTest.ActivePatternCase _ -> failwith "DecisionTreeTest.ActivePatternCase should only be used during pattern match compilation" - TCase(test', remapDecisionTree g compgen tmenv y)) csl, - Option.map (remapDecisionTree g compgen tmenv) dflt, - m) - | TDSuccess (es, n) -> - TDSuccess (remapFlatExprs g compgen tmenv es, n) - | TDBind (bind, rest) -> - let bind', tmenvinner = copyAndRemapAndBindBinding g compgen tmenv bind - TDBind (bind', remapDecisionTree g compgen tmenvinner rest) - -and copyAndRemapAndBindBinding g compgen tmenv (bind: Binding) = - let v = bind.Var - let v', tmenv = copyAndRemapAndBindVal g compgen tmenv v - remapAndRenameBind g compgen tmenv bind v', tmenv - -and copyAndRemapAndBindBindings g compgen tmenv binds = - let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenv (valsOfBinds binds) - remapAndRenameBinds g compgen tmenvinner binds vs', tmenvinner - -and remapAndRenameBinds g compgen tmenvinner binds vs' = List.map2 (remapAndRenameBind g compgen tmenvinner) binds vs' -and remapAndRenameBind g compgen tmenvinner (TBind(_, repr, letSeqPtOpt)) v' = TBind(v', remapExpr g compgen tmenvinner repr, letSeqPtOpt) - -and remapMethod g compgen tmenv (TObjExprMethod(slotsig, attribs, tps, vs, e, m)) = - let attribs2 = attribs |> remapAttribs g tmenv - let slotsig2 = remapSlotSig (remapAttribs g tmenv) tmenv slotsig - let tps2, tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps - let vs2, tmenvinner2 = List.mapFold (copyAndRemapAndBindVals g compgen) tmenvinner vs - let e2 = remapExpr g compgen tmenvinner2 e - TObjExprMethod(slotsig2, attribs2, tps2, vs2, e2, m) - -and remapInterfaceImpl g compgen tmenv (ty, overrides) = - (remapType tmenv ty, List.map (remapMethod g compgen tmenv) overrides) - -and remapRecdField g tmenv x = - { x with - rfield_type = x.rfield_type |> remapPossibleForallTy g tmenv - rfield_pattribs = x.rfield_pattribs |> remapAttribs g tmenv - rfield_fattribs = x.rfield_fattribs |> remapAttribs g tmenv } - -and remapRecdFields g tmenv (x: TyconRecdFields) = - x.AllFieldsAsList |> List.map (remapRecdField g tmenv) |> MakeRecdFieldsTable - -and remapUnionCase g tmenv (x: UnionCase) = - { x with - FieldTable = x.FieldTable |> remapRecdFields g tmenv - ReturnType = x.ReturnType |> remapType tmenv - Attribs = x.Attribs |> remapAttribs g tmenv } - -and remapUnionCases g tmenv (x: TyconUnionData) = - x.UnionCasesAsList |> List.map (remapUnionCase g tmenv) |> MakeUnionCases - -and remapFsObjData g tmenv x = - { x with - fsobjmodel_kind = - (match x.fsobjmodel_kind with - | TTyconDelegate slotsig -> TTyconDelegate (remapSlotSig (remapAttribs g tmenv) tmenv slotsig) - | TTyconClass | TTyconInterface | TTyconStruct | TTyconEnum -> x.fsobjmodel_kind) - fsobjmodel_vslots = x.fsobjmodel_vslots |> List.map (remapValRef tmenv) - fsobjmodel_rfields = x.fsobjmodel_rfields |> remapRecdFields g tmenv } - - -and remapTyconRepr g tmenv repr = - match repr with - | TFSharpObjectRepr x -> TFSharpObjectRepr (remapFsObjData g tmenv x) - | TRecdRepr x -> TRecdRepr (remapRecdFields g tmenv x) - | TUnionRepr x -> TUnionRepr (remapUnionCases g tmenv x) - | TILObjectRepr _ -> failwith "cannot remap IL type definitions" -#if !NO_EXTENSIONTYPING - | TProvidedNamespaceExtensionPoint _ -> repr - | TProvidedTypeExtensionPoint info -> - TProvidedTypeExtensionPoint - { info with - LazyBaseType = info.LazyBaseType.Force (range0, g.obj_ty) |> remapType tmenv |> LazyWithContext.NotLazy - // The load context for the provided type contains TyconRef objects. We must remap these. - // This is actually done on-demand (see the implementation of ProvidedTypeContext) - ProvidedType = - info.ProvidedType.PApplyNoFailure (fun st -> - let ctxt = st.Context.RemapTyconRefs(unbox >> remapTyconRef tmenv.tyconRefRemap >> box) - ProvidedType.ApplyContext (st, ctxt)) } -#endif - | TNoRepr _ -> repr - | TAsmRepr _ -> repr - | TMeasureableRepr x -> TMeasureableRepr (remapType tmenv x) - -and remapTyconAug tmenv (x: TyconAugmentation) = - { x with - tcaug_equals = x.tcaug_equals |> Option.map (mapPair (remapValRef tmenv, remapValRef tmenv)) - tcaug_compare = x.tcaug_compare |> Option.map (mapPair (remapValRef tmenv, remapValRef tmenv)) - tcaug_compare_withc = x.tcaug_compare_withc |> Option.map(remapValRef tmenv) - tcaug_hash_and_equals_withc = x.tcaug_hash_and_equals_withc |> Option.map (mapTriple (remapValRef tmenv, remapValRef tmenv, remapValRef tmenv)) - tcaug_adhoc = x.tcaug_adhoc |> NameMap.map (List.map (remapValRef tmenv)) - tcaug_adhoc_list = x.tcaug_adhoc_list |> ResizeArray.map (fun (flag, vref) -> (flag, remapValRef tmenv vref)) - tcaug_super = x.tcaug_super |> Option.map (remapType tmenv) - tcaug_interfaces = x.tcaug_interfaces |> List.map (map1Of3 (remapType tmenv)) } - -and remapTyconExnInfo g tmenv inp = - match inp with - | TExnAbbrevRepr x -> TExnAbbrevRepr (remapTyconRef tmenv.tyconRefRemap x) - | TExnFresh x -> TExnFresh (remapRecdFields g tmenv x) - | TExnAsmRepr _ | TExnNone -> inp - -and remapMemberInfo g m topValInfo ty ty' tmenv x = - // The slotsig in the ImplementedSlotSigs is w.r.t. the type variables in the value's type. - // REVIEW: this is a bit gross. It would be nice if the slotsig was standalone - assert (Option.isSome topValInfo) - let tpsOrig, _, _, _ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty m - let tps, _, _, _ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty' m - let renaming, _ = mkTyparToTyparRenaming tpsOrig tps - let tmenv = { tmenv with tpinst = tmenv.tpinst @ renaming } - { x with - ApparentEnclosingEntity = x.ApparentEnclosingEntity |> remapTyconRef tmenv.tyconRefRemap - ImplementedSlotSigs = x.ImplementedSlotSigs |> List.map (remapSlotSig (remapAttribs g tmenv) tmenv) - } - -and copyAndRemapAndBindModTy g compgen tmenv mty = - let tycons = allEntitiesOfModuleOrNamespaceTy mty - let vs = allValsOfModuleOrNamespaceTy mty - let _, _, tmenvinner = copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs - remapModTy g compgen tmenvinner mty, tmenvinner - -and remapModTy g _compgen tmenv mty = - mapImmediateValsAndTycons (renameTycon g tmenv) (renameVal tmenv) mty - -and renameTycon g tyenv x = - let tcref = - try - let res = tyenv.tyconRefRemap.[mkLocalTyconRef x] - res - with :? KeyNotFoundException -> - errorR(InternalError("couldn't remap internal tycon " + showL(DebugPrint.tyconL g x), x.Range)) - mkLocalTyconRef x - tcref.Deref - -and renameVal tmenv x = - match tmenv.valRemap.TryFind x with - | Some v -> v.Deref - | None -> x - -and copyTycon compgen (tycon: Tycon) = - match compgen with - | OnlyCloneExprVals -> tycon - | _ -> NewClonedTycon tycon - -/// This operates over a whole nested collection of tycons and vals simultaneously *) -and copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs = - let tycons' = tycons |> List.map (copyTycon compgen) - - let tmenvinner = bindTycons tycons tycons' tmenv - - // Values need to be copied and renamed. - let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenvinner vs - - // "if a type constructor is hidden then all its inner values and inner type constructors must also be hidden" - // Hence we can just lookup the inner tycon/value mappings in the tables. - - let lookupVal (v: Val) = - let vref = - try - let res = tmenvinner.valRemap.[v] - res - with :? KeyNotFoundException -> - errorR(InternalError(sprintf "couldn't remap internal value '%s'" v.LogicalName, v.Range)) - mkLocalValRef v - vref.Deref - - let lookupTycon g tycon = - let tcref = - try - let res = tmenvinner.tyconRefRemap.[mkLocalTyconRef tycon] - res - with :? KeyNotFoundException -> - errorR(InternalError("couldn't remap internal tycon " + showL(DebugPrint.tyconL g tycon), tycon.Range)) - mkLocalTyconRef tycon - tcref.Deref - (tycons, tycons') ||> List.iter2 (fun tcd tcd' -> - let lookupTycon tycon = lookupTycon g tycon - let tps', tmenvinner2 = tmenvCopyRemapAndBindTypars (remapAttribs g tmenvinner) tmenvinner (tcd.entity_typars.Force(tcd.entity_range)) - tcd'.entity_typars <- LazyWithContext.NotLazy tps' - tcd'.entity_attribs <- tcd.entity_attribs |> remapAttribs g tmenvinner2 - tcd'.entity_tycon_repr <- tcd.entity_tycon_repr |> remapTyconRepr g tmenvinner2 - let typeAbbrevR = tcd.TypeAbbrev |> Option.map (remapType tmenvinner2) - tcd'.entity_tycon_tcaug <- tcd.entity_tycon_tcaug |> remapTyconAug tmenvinner2 - tcd'.entity_modul_contents <- MaybeLazy.Strict (tcd.entity_modul_contents.Value - |> mapImmediateValsAndTycons lookupTycon lookupVal) - let exnInfoR = tcd.ExceptionInfo |> remapTyconExnInfo g tmenvinner2 - match tcd'.entity_opt_data with - | Some optData -> tcd'.entity_opt_data <- Some { optData with entity_tycon_abbrev = typeAbbrevR; entity_exn_info = exnInfoR } - | _ -> - tcd'.SetTypeAbbrev typeAbbrevR - tcd'.SetExceptionInfo exnInfoR) - tycons', vs', tmenvinner - - -and allTyconsOfTycon (tycon: Tycon) = - seq { yield tycon - for nestedTycon in tycon.ModuleOrNamespaceType.AllEntities do - yield! allTyconsOfTycon nestedTycon } - -and allEntitiesOfModDef mdef = - seq { match mdef with - | TMDefRec(_, tycons, mbinds, _) -> - for tycon in tycons do - yield! allTyconsOfTycon tycon - for mbind in mbinds do - match mbind with - | ModuleOrNamespaceBinding.Binding _ -> () - | ModuleOrNamespaceBinding.Module(mspec, def) -> - yield mspec - yield! allEntitiesOfModDef def - | TMDefLet _ -> () - | TMDefDo _ -> () - | TMDefs defs -> - for def in defs do - yield! allEntitiesOfModDef def - | TMAbstract(ModuleOrNamespaceExprWithSig(mty, _, _)) -> - yield! allEntitiesOfModuleOrNamespaceTy mty } - -and allValsOfModDef mdef = - seq { match mdef with - | TMDefRec(_, tycons, mbinds, _) -> - yield! abstractSlotValsOfTycons tycons - for mbind in mbinds do - match mbind with - | ModuleOrNamespaceBinding.Binding bind -> yield bind.Var - | ModuleOrNamespaceBinding.Module(_, def) -> yield! allValsOfModDef def - | TMDefLet(bind, _) -> - yield bind.Var - | TMDefDo _ -> () - | TMDefs defs -> - for def in defs do - yield! allValsOfModDef def - | TMAbstract(ModuleOrNamespaceExprWithSig(mty, _, _)) -> - yield! allValsOfModuleOrNamespaceTy mty } - -and remapAndBindModuleOrNamespaceExprWithSig g compgen tmenv (ModuleOrNamespaceExprWithSig(mty, mdef, m)) = - let mdef = copyAndRemapModDef g compgen tmenv mdef - let mty, tmenv = copyAndRemapAndBindModTy g compgen tmenv mty - ModuleOrNamespaceExprWithSig(mty, mdef, m), tmenv - -and remapModuleOrNamespaceExprWithSig g compgen tmenv (ModuleOrNamespaceExprWithSig(mty, mdef, m)) = - let mdef = copyAndRemapModDef g compgen tmenv mdef - let mty = remapModTy g compgen tmenv mty - ModuleOrNamespaceExprWithSig(mty, mdef, m) - -and copyAndRemapModDef g compgen tmenv mdef = - let tycons = allEntitiesOfModDef mdef |> List.ofSeq - let vs = allValsOfModDef mdef |> List.ofSeq - let _, _, tmenvinner = copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs - remapAndRenameModDef g compgen tmenvinner mdef - -and remapAndRenameModDefs g compgen tmenv x = - List.map (remapAndRenameModDef g compgen tmenv) x - -and remapAndRenameModDef g compgen tmenv mdef = - match mdef with - | TMDefRec(isRec, tycons, mbinds, m) -> - // Abstract (virtual) vslots in the tycons at TMDefRec nodes are binders. They also need to be copied and renamed. - let tycons = tycons |> List.map (renameTycon g tmenv) - let mbinds = mbinds |> List.map (remapAndRenameModBind g compgen tmenv) - TMDefRec(isRec, tycons, mbinds, m) - | TMDefLet(bind, m) -> - let v = bind.Var - let bind = remapAndRenameBind g compgen tmenv bind (renameVal tmenv v) - TMDefLet(bind, m) - | TMDefDo(e, m) -> - let e = remapExpr g compgen tmenv e - TMDefDo(e, m) - | TMDefs defs -> - let defs = remapAndRenameModDefs g compgen tmenv defs - TMDefs defs - | TMAbstract mexpr -> - let mexpr = remapModuleOrNamespaceExprWithSig g compgen tmenv mexpr - TMAbstract mexpr - -and remapAndRenameModBind g compgen tmenv x = - match x with - | ModuleOrNamespaceBinding.Binding bind -> - let v2 = bind |> valOfBind |> renameVal tmenv - let bind2 = remapAndRenameBind g compgen tmenv bind v2 - ModuleOrNamespaceBinding.Binding bind2 - | ModuleOrNamespaceBinding.Module(mspec, def) -> - let mspec = renameTycon g tmenv mspec - let def = remapAndRenameModDef g compgen tmenv def - ModuleOrNamespaceBinding.Module(mspec, def) - -and remapImplFile g compgen tmenv mv = - mapAccImplFile (remapAndBindModuleOrNamespaceExprWithSig g compgen) tmenv mv - -let copyModuleOrNamespaceType g compgen mtyp = copyAndRemapAndBindModTy g compgen Remap.Empty mtyp |> fst - -let copyExpr g compgen e = remapExpr g compgen Remap.Empty e - -let copyImplFile g compgen e = remapImplFile g compgen Remap.Empty e |> fst - -let instExpr g tpinst e = remapExpr g CloneAll (mkInstRemap tpinst) e - -//-------------------------------------------------------------------------- -// Replace Marks - adjust debugging marks when a lambda gets -// eliminated (i.e. an expression gets inlined) -//-------------------------------------------------------------------------- - -let rec remarkExpr m x = - match x with - | Expr.Lambda (uniq, ctorThisValOpt, baseValOpt, vs, b, _, rty) -> - Expr.Lambda (uniq, ctorThisValOpt, baseValOpt, vs, remarkExpr m b, m, rty) - - | Expr.TyLambda (uniq, tps, b, _, rty) -> - Expr.TyLambda (uniq, tps, remarkExpr m b, m, rty) - - | Expr.TyChoose (tps, b, _) -> - Expr.TyChoose (tps, remarkExpr m b, m) - - | Expr.LetRec (binds, e, _, fvs) -> - Expr.LetRec (remarkBinds m binds, remarkExpr m e, m, fvs) - - | Expr.Let (bind, e, _, fvs) -> - Expr.Let (remarkBind m bind, remarkExpr m e, m, fvs) - - | Expr.Match (_, _, pt, targets, _, ty) -> - let targetsR = targets |> Array.map (fun (TTarget(vs, e, _)) -> TTarget(vs, remarkExpr m e, SuppressSequencePointAtTarget)) - primMkMatch (NoSequencePointAtInvisibleBinding, m, remarkDecisionTree m pt, targetsR, m, ty) - - | Expr.Val (x, valUseFlags, _) -> - Expr.Val (x, valUseFlags, m) - - | Expr.Quote (a, conv, isFromQueryExpression, _, ty) -> - Expr.Quote (remarkExpr m a, conv, isFromQueryExpression, m, ty) - - | Expr.Obj (n, ty, basev, basecall, overrides, iimpls, _) -> - Expr.Obj (n, ty, basev, remarkExpr m basecall, - List.map (remarkObjExprMethod m) overrides, - List.map (remarkInterfaceImpl m) iimpls, m) - - | Expr.Op (op, tinst, args, _) -> - let op = - match op with - | TOp.TryFinally (_, _) -> TOp.TryFinally (NoSequencePointAtTry, NoSequencePointAtFinally) - | TOp.TryCatch (_, _) -> TOp.TryCatch (NoSequencePointAtTry, NoSequencePointAtWith) - | _ -> op - Expr.Op (op, tinst, remarkExprs m args, m) - - | Expr.Link eref -> - // Preserve identity of fixup nodes during remarkExpr - eref := remarkExpr m !eref - x - - | Expr.App (e1, e1ty, tyargs, args, _) -> - Expr.App (remarkExpr m e1, e1ty, tyargs, remarkExprs m args, m) - - | Expr.Sequential (e1, e2, dir, _, _) -> - Expr.Sequential (remarkExpr m e1, remarkExpr m e2, dir, SuppressSequencePointOnExprOfSequential, m) - - | Expr.StaticOptimization (eqns, e2, e3, _) -> - Expr.StaticOptimization (eqns, remarkExpr m e2, remarkExpr m e3, m) - - | Expr.Const (c, _, ty) -> Expr.Const (c, m, ty) - -and remarkObjExprMethod m (TObjExprMethod(slotsig, attribs, tps, vs, e, _)) = - TObjExprMethod(slotsig, attribs, tps, vs, remarkExpr m e, m) - -and remarkInterfaceImpl m (ty, overrides) = - (ty, List.map (remarkObjExprMethod m) overrides) - -and remarkExprs m es = es |> List.map (remarkExpr m) - -and remarkFlatExprs m es = es |> List.map (remarkExpr m) - -and remarkDecisionTree m x = - match x with - | TDSwitch(e1, csl, dflt, _) -> - let cslR = csl |> List.map (fun (TCase(test, y)) -> TCase(test, remarkDecisionTree m y)) - TDSwitch(remarkExpr m e1, cslR, Option.map (remarkDecisionTree m) dflt, m) - | TDSuccess (es, n) -> - TDSuccess (remarkFlatExprs m es, n) - | TDBind (bind, rest) -> - TDBind(remarkBind m bind, remarkDecisionTree m rest) - -and remarkBinds m binds = List.map (remarkBind m) binds - -// This very deliberately drops the sequence points since this is used when adjusting the marks for inlined expressions -and remarkBind m (TBind(v, repr, _)) = - TBind(v, remarkExpr m repr, NoSequencePointAtStickyBinding) - -//-------------------------------------------------------------------------- -// Mutability analysis -//-------------------------------------------------------------------------- - -let isRecdOrStructFieldDefinitelyMutable (f: RecdField) = not f.IsStatic && f.IsMutable - -let isUnionCaseDefinitelyMutable (uc: UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldDefinitelyMutable - -let isUnionCaseRefDefinitelyMutable (uc: UnionCaseRef) = uc.UnionCase |> isUnionCaseDefinitelyMutable - -/// This is an incomplete check for .NET struct types. Returning 'false' doesn't mean the thing is immutable. -let isRecdOrUnionOrStructTyconRefDefinitelyMutable (tcref: TyconRef) = - let tycon = tcref.Deref - if tycon.IsUnionTycon then - tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable - elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then - // Note: This only looks at the F# fields, causing oddities. - // See https://github.com/Microsoft/visualfsharp/pull/4576 - tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldDefinitelyMutable - else - false - -// Although from the pure F# perspective exception values cannot be changed, the .NET -// implementation of exception objects attaches a whole bunch of stack information to -// each raised object. Hence we treat exception objects as if they have identity -let isExnDefinitelyMutable (_ecref: TyconRef) = true - -// Some of the implementations of library functions on lists use mutation on the tail -// of the cons cell. These cells are always private, i.e. not accessible by any other -// code until the construction of the entire return list has been completed. -// However, within the implementation code reads of the tail cell must in theory be treated -// with caution. Hence we are conservative and within FSharp.Core we don't treat list -// reads as if they were pure. -let isUnionCaseFieldMutable (g: TcGlobals) (ucref: UnionCaseRef) n = - (g.compilingFslib && tyconRefEq g ucref.TyconRef g.list_tcr_canon && n = 1) || - (ucref.FieldByIndex n).IsMutable - -let isExnFieldMutable ecref n = - if n < 0 || n >= List.length (recdFieldsOfExnDefRef ecref) then errorR(InternalError(sprintf "isExnFieldMutable, exnc = %s, n = %d" ecref.LogicalName n, ecref.Range)) - (recdFieldOfExnDefRefByIdx ecref n).IsMutable - -let useGenuineField (tycon: Tycon) (f: RecdField) = - Option.isSome f.LiteralValue || tycon.IsEnumTycon || f.rfield_secret || (not f.IsStatic && f.rfield_mutable && not tycon.IsRecordTycon) - -let ComputeFieldName tycon f = - if useGenuineField tycon f then f.rfield_id.idText - else CompilerGeneratedName f.rfield_id.idText - -//------------------------------------------------------------------------- -// Helpers for building code contained in the initial environment -//------------------------------------------------------------------------- - -let isQuotedExprTy g ty = match tryAppTy g ty with ValueSome (tcref, _) -> tyconRefEq g tcref g.expr_tcr | _ -> false - -let destQuotedExprTy g ty = match tryAppTy g ty with ValueSome (_, [ty]) -> ty | _ -> failwith "destQuotedExprTy" - -let mkQuotedExprTy (g: TcGlobals) ty = TType_app(g.expr_tcr, [ty]) - -let mkRawQuotedExprTy (g: TcGlobals) = TType_app(g.raw_expr_tcr, []) - -let mkAnyTupledTy (g: TcGlobals) tupInfo tys = - match tys with - | [] -> g.unit_ty - | [h] -> h - | _ -> TType_tuple(tupInfo, tys) - -let mkAnyAnonRecdTy (_g: TcGlobals) anonInfo tys = - TType_anon(anonInfo, tys) - -let mkRefTupledTy g tys = mkAnyTupledTy g tupInfoRef tys - -let mkRefTupledVarsTy g vs = mkRefTupledTy g (typesOfVals vs) - -let mkMethodTy g argtys rty = mkIteratedFunTy (List.map (mkRefTupledTy g) argtys) rty - -let mkArrayType (g: TcGlobals) ty = TType_app (g.array_tcr_nice, [ty]) - -let mkByteArrayTy (g: TcGlobals) = mkArrayType g g.byte_ty - -//-------------------------------------------------------------------------- -// tyOfExpr -//-------------------------------------------------------------------------- - -let rec tyOfExpr g e = - match e with - | Expr.App (_, fty, tyargs, args, _) -> applyTys g fty (tyargs, args) - | Expr.Obj (_, ty, _, _, _, _, _) - | Expr.Match (_, _, _, _, _, ty) - | Expr.Quote (_, _, _, _, ty) - | Expr.Const (_, _, ty) -> (ty) - | Expr.Val (vref, _, _) -> vref.Type - | Expr.Sequential (a, b, k, _, _) -> tyOfExpr g (match k with NormalSeq -> b | ThenDoSeq -> a) - | Expr.Lambda (_, _, _, vs, _, _, rty) -> (mkRefTupledVarsTy g vs --> rty) - | Expr.TyLambda (_, tyvs, _, _, rty) -> (tyvs +-> rty) - | Expr.Let (_, e, _, _) - | Expr.TyChoose (_, e, _) - | Expr.Link { contents=e} - | Expr.StaticOptimization (_, _, e, _) - | Expr.LetRec (_, e, _, _) -> tyOfExpr g e - | Expr.Op (op, tinst, _, _) -> - match op with - | TOp.Coerce -> (match tinst with [to_ty;_fromTy] -> to_ty | _ -> failwith "bad TOp.Coerce node") - | (TOp.ILCall (_, _, _, _, _, _, _, _, _, _, rtys) | TOp.ILAsm (_, rtys)) -> (match rtys with [h] -> h | _ -> g.unit_ty) - | TOp.UnionCase uc -> actualResultTyOfUnionCase tinst uc - | TOp.UnionCaseProof uc -> mkProvenUnionCaseTy uc tinst - | TOp.Recd (_, tcref) -> mkAppTy tcref tinst - | TOp.ExnConstr _ -> g.exn_ty - | TOp.Bytes _ -> mkByteArrayTy g - | TOp.UInt16s _ -> mkArrayType g g.uint16_ty - | TOp.AnonRecdGet (_, i) -> List.item i tinst - | TOp.TupleFieldGet (_, i) -> List.item i tinst - | TOp.Tuple tupInfo -> mkAnyTupledTy g tupInfo tinst - | TOp.AnonRecd anonInfo -> mkAnyAnonRecdTy g anonInfo tinst - | (TOp.For _ | TOp.While _) -> g.unit_ty - | TOp.Array -> (match tinst with [ty] -> mkArrayType g ty | _ -> failwith "bad TOp.Array node") - | (TOp.TryCatch _ | TOp.TryFinally _) -> (match tinst with [ty] -> ty | _ -> failwith "bad TOp_try node") - | TOp.ValFieldGetAddr (fref, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdFieldRef fref tinst) - | TOp.ValFieldGet fref -> actualTyOfRecdFieldRef fref tinst - | (TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet), _)) ->g.unit_ty - | TOp.UnionCaseTagGet _ -> g.int_ty - | TOp.UnionCaseFieldGetAddr (cref, j, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j)) - | TOp.UnionCaseFieldGet (cref, j) -> actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j) - | TOp.ExnFieldGet (ecref, j) -> recdFieldTyOfExnDefRefByIdx ecref j - | TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type - | TOp.LValueOp (LAddrOf readonly, v) -> mkByrefTyWithFlag g readonly v.Type - | TOp.RefAddrGet readonly -> (match tinst with [ty] -> mkByrefTyWithFlag g readonly ty | _ -> failwith "bad TOp.RefAddrGet node") - | TOp.TraitCall (TTrait(_, _, _, _, ty, _)) -> GetFSharpViewOfReturnType g ty - | TOp.Reraise -> (match tinst with [rtn_ty] -> rtn_ty | _ -> failwith "bad TOp.Reraise node") - | TOp.Goto _ | TOp.Label _ | TOp.Return -> - //assert false - //errorR(InternalError("unexpected goto/label/return in tyOfExpr", m)) - // It doesn't matter what type we return here. This is only used in free variable analysis in the code generator - g.unit_ty - -//-------------------------------------------------------------------------- -// Make applications -//--------------------------------------------------------------------------- - -let primMkApp (f, fty) tyargs argsl m = - Expr.App (f, fty, tyargs, argsl, m) - -// Check for the funky where a generic type instantiation at function type causes a generic function -// to appear to accept more arguments than it really does, e.g. "id id 1", where the first "id" is -// instantiated with "int -> int". -// -// In this case, apply the arguments one at a time. -let isExpansiveUnderInstantiation g fty0 tyargs pargs argsl = - isForallTy g fty0 && - let fty1 = formalApplyTys g fty0 (tyargs, pargs) - (not (isFunTy g fty1) || - let rec loop fty xs = - match xs with - | [] -> false - | _ :: t -> not (isFunTy g fty) || loop (rangeOfFunTy g fty) t - loop fty1 argsl) - -let rec mkExprAppAux g f fty argsl m = - match argsl with - | [] -> f - | _ -> - // Always combine the term application with a type application - // - // Combine the term application with a term application, but only when f' is an under-applied value of known arity - match f with - | Expr.App (f', fty', tyargs, pargs, m2) - when - (isNil pargs || - (match stripExpr f' with - | Expr.Val (v, _, _) -> - match v.ValReprInfo with - | Some info -> info.NumCurriedArgs > pargs.Length - | None -> false - | _ -> false)) && - not (isExpansiveUnderInstantiation g fty' tyargs pargs argsl) -> - primMkApp (f', fty') tyargs (pargs@argsl) (unionRanges m2 m) - - | _ -> - // Don't combine. 'f' is not an application - if not (isFunTy g fty) then error(InternalError("expected a function type", m)) - primMkApp (f, fty) [] argsl m - - -let rec mkAppsAux g f fty tyargsl argsl m = - match tyargsl with - | tyargs :: rest -> - match tyargs with - | [] -> mkAppsAux g f fty rest argsl m - | _ -> - let arfty = applyForallTy g fty tyargs - mkAppsAux g (primMkApp (f, fty) tyargs [] m) arfty rest argsl m - | [] -> - mkExprAppAux g f fty argsl m - -let mkApps g ((f, fty), tyargsl, argl, m) = mkAppsAux g f fty tyargsl argl m - -let mkTyAppExpr m (f, fty) tyargs = match tyargs with [] -> f | _ -> primMkApp (f, fty) tyargs [] m - -//-------------------------------------------------------------------------- -// Decision tree reduction -//-------------------------------------------------------------------------- - -let rec accTargetsOfDecisionTree tree acc = - match tree with - | TDSwitch (_, cases, dflt, _) -> - List.foldBack (fun (c: DecisionTreeCase) -> accTargetsOfDecisionTree c.CaseTree) cases - (Option.foldBack accTargetsOfDecisionTree dflt acc) - | TDSuccess (_, i) -> i :: acc - | TDBind (_, rest) -> accTargetsOfDecisionTree rest acc - -let rec mapTargetsOfDecisionTree f tree = - match tree with - | TDSwitch (e, cases, dflt, m) -> TDSwitch (e, List.map (mapTargetsOfDecisionTreeCase f) cases, Option.map (mapTargetsOfDecisionTree f) dflt, m) - | TDSuccess (es, i) -> TDSuccess(es, f i) - | TDBind (bind, rest) -> TDBind(bind, mapTargetsOfDecisionTree f rest) - -and mapTargetsOfDecisionTreeCase f (TCase(x, t)) = - TCase(x, mapTargetsOfDecisionTree f t) - -// Dead target elimination -let eliminateDeadTargetsFromMatch tree (targets:_[]) = - let used = accTargetsOfDecisionTree tree [] |> ListSet.setify (=) |> Array.ofList - if used.Length < targets.Length then - Array.sortInPlace used - let ntargets = targets.Length - let tree' = - let remap = Array.create ntargets (-1) - Array.iteri (fun i tgn -> remap.[tgn] <- i) used - tree |> mapTargetsOfDecisionTree (fun tgn -> - if remap.[tgn] = -1 then failwith "eliminateDeadTargetsFromMatch: failure while eliminating unused targets" - remap.[tgn]) - let targets' = Array.map (Array.get targets) used - tree', targets' - else - tree, targets - -let rec targetOfSuccessDecisionTree tree = - match tree with - | TDSwitch _ -> None - | TDSuccess (_, i) -> Some i - | TDBind(_, t) -> targetOfSuccessDecisionTree t - -/// Check a decision tree only has bindings that immediately cover a 'Success' -let rec decisionTreeHasNonTrivialBindings tree = - match tree with - | TDSwitch (_, cases, dflt, _) -> - cases |> List.exists (fun c -> decisionTreeHasNonTrivialBindings c.CaseTree) || - dflt |> Option.exists decisionTreeHasNonTrivialBindings - | TDSuccess _ -> false - | TDBind (_, t) -> Option.isNone (targetOfSuccessDecisionTree t) - -// If a target has assignments and can only be reached through one -// branch (i.e. is "linear"), then transfer the assignments to the r.h.s. to be a "let". -let foldLinearBindingTargetsOfMatch tree (targets: _[]) = - - // Don't do this when there are any bindings in the tree except where those bindings immediately cover a success node - // since the variables would be extruded from their scope. - if decisionTreeHasNonTrivialBindings tree then - tree, targets - - else - let branchesToTargets = Array.create targets.Length [] - // Build a map showing how each target might be reached - let rec accumulateTipsOfDecisionTree accBinds tree = - match tree with - | TDSwitch (_, cases, dflt, _) -> - assert (isNil accBinds) // No switches under bindings - for edge in cases do accumulateTipsOfDecisionTree accBinds edge.CaseTree - match dflt with - | None -> () - | Some tree -> accumulateTipsOfDecisionTree accBinds tree - | TDSuccess (es, i) -> - branchesToTargets.[i] <- (List.rev accBinds, es) :: branchesToTargets.[i] - | TDBind (bind, rest) -> - accumulateTipsOfDecisionTree (bind :: accBinds) rest - - // Compute the targets that can only be reached one way - accumulateTipsOfDecisionTree [] tree - let isLinearTarget bs = match bs with [_] -> true | _ -> false - let isLinearTgtIdx i = isLinearTarget branchesToTargets.[i] - let getLinearTgtIdx i = branchesToTargets.[i].Head - let hasLinearTgtIdx = branchesToTargets |> Array.exists isLinearTarget - - if not hasLinearTgtIdx then - - tree, targets - - else - - /// rebuild the decision tree, replacing 'bind-then-success' decision trees by TDSuccess nodes that just go to the target - let rec rebuildDecisionTree tree = - - // Check if this is a bind-then-success tree - match targetOfSuccessDecisionTree tree with - | Some i when isLinearTgtIdx i -> TDSuccess([], i) - | _ -> - match tree with - | TDSwitch (e, cases, dflt, m) -> TDSwitch (e, List.map rebuildDecisionTreeEdge cases, Option.map rebuildDecisionTree dflt, m) - | TDSuccess _ -> tree - | TDBind _ -> tree - - and rebuildDecisionTreeEdge (TCase(x, t)) = - TCase(x, rebuildDecisionTree t) - - let tree' = rebuildDecisionTree tree - - /// rebuild the targets, replacing linear targets by ones that include all the 'let' bindings from the source - let targets' = - targets |> Array.mapi (fun i (TTarget(vs, exprTarget, spTarget) as tg) -> - if isLinearTgtIdx i then - let (binds, es) = getLinearTgtIdx i - // The value bindings are moved to become part of the target. - // Hence the expressions in the value bindings can be remarked with the range of the target. - let mTarget = exprTarget.Range - let es = es |> List.map (remarkExpr mTarget) - // These are non-sticky - any sequence point for 'exprTarget' goes on 'exprTarget' _after_ the bindings have been evaluated - TTarget(List.empty, mkLetsBind mTarget binds (mkInvisibleLetsFromBindings mTarget vs es exprTarget), spTarget) - else tg ) - - tree', targets' - -// Simplify a little as we go, including dead target elimination -let rec simplifyTrivialMatch spBind exprm matchm ty tree (targets : _[]) = - match tree with - | TDSuccess(es, n) -> - if n >= targets.Length then failwith "simplifyTrivialMatch: target out of range" - // REVIEW: should we use _spTarget here? - let (TTarget(vs, rhs, _spTarget)) = targets.[n] - if vs.Length <> es.Length then failwith ("simplifyTrivialMatch: invalid argument, n = " + string n + ", List.length targets = " + string targets.Length) - // These are non-sticky - any sequence point for 'rhs' goes on 'rhs' _after_ the bindings have been made - mkInvisibleLetsFromBindings rhs.Range vs es rhs - | _ -> - primMkMatch (spBind, exprm, tree, targets, matchm, ty) - -// Simplify a little as we go, including dead target elimination -let mkAndSimplifyMatch spBind exprm matchm ty tree targets = - let targets = Array.ofList targets - match tree with - | TDSuccess _ -> - simplifyTrivialMatch spBind exprm matchm ty tree targets - | _ -> - let tree, targets = eliminateDeadTargetsFromMatch tree targets - let tree, targets = foldLinearBindingTargetsOfMatch tree targets - simplifyTrivialMatch spBind exprm matchm ty tree targets - -//------------------------------------------------------------------------- -// mkExprAddrOfExprAux -//------------------------------------------------------------------------- - -type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates -exception DefensiveCopyWarning of string * range - -let isRecdOrStructTyconRefAssumedImmutable (g: TcGlobals) (tcref: TyconRef) = - tcref.CanDeref && - not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) || - tyconRefEq g tcref g.decimal_tcr || - tyconRefEq g tcref g.date_tcr - -let isTyconRefReadOnly g m (tcref: TyconRef) = - tcref.CanDeref && - if - match tcref.TryIsReadOnly with - | ValueSome res -> res - | _ -> - let res = TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref - tcref.SetIsReadOnly res - res - then true - else tcref.IsEnumTycon - -let isTyconRefAssumedReadOnly g (tcref: TyconRef) = - tcref.CanDeref && - match tcref.TryIsAssumedReadOnly with - | ValueSome res -> res - | _ -> - let res = isRecdOrStructTyconRefAssumedImmutable g tcref - tcref.SetIsAssumedReadOnly res - res - -let isRecdOrStructTyconRefReadOnlyAux g m isInref (tcref: TyconRef) = - if isInref && tcref.IsILStructOrEnumTycon then - isTyconRefReadOnly g m tcref - else - isTyconRefReadOnly g m tcref || isTyconRefAssumedReadOnly g tcref - -let isRecdOrStructTyconRefReadOnly g m tcref = - isRecdOrStructTyconRefReadOnlyAux g m false tcref - -let isRecdOrStructTyReadOnlyAux (g: TcGlobals) m isInref ty = - match tryDestAppTy g ty with - | ValueNone -> false - | ValueSome tcref -> isRecdOrStructTyconRefReadOnlyAux g m isInref tcref - -let isRecdOrStructTyReadOnly g m ty = - isRecdOrStructTyReadOnlyAux g m false ty - -let CanTakeAddressOf g m isInref ty mut = - match mut with - | NeverMutates -> true - | PossiblyMutates -> isRecdOrStructTyReadOnlyAux g m isInref ty - | DefinitelyMutates -> false - | AddressOfOp -> true // you can take the address but you might get a (readonly) inref as a result - -// We can take the address of values of struct type even if the value is immutable -// under certain conditions -// - all instances of the type are known to be immutable; OR -// - the operation is known not to mutate -// -// Note this may be taking the address of a closure field, i.e. a copy -// of the original struct, e.g. for -// let f () = -// let g1 = A.G(1) -// (fun () -> g1.x1) -// -// Note: isRecdOrStructTyReadOnly implies PossiblyMutates or NeverMutates -// -// We only do this for true local or closure fields because we can't take addresses of immutable static -// fields across assemblies. -let CanTakeAddressOfImmutableVal (g: TcGlobals) m (vref: ValRef) mut = - // We can take the address of values of struct type if the operation doesn't mutate - // and the value is a true local or closure field. - not vref.IsMutable && - not vref.IsMemberOrModuleBinding && - // Note: We can't add this: - // || valRefInThisAssembly g.compilingFslib vref - // This is because we don't actually guarantee to generate static backing fields for all values like these, e.g. simple constants "let x = 1". - // We always generate a static property but there is no field to take an address of - CanTakeAddressOf g m false vref.Type mut - -let MustTakeAddressOfVal (g: TcGlobals) (vref: ValRef) = - vref.IsMutable && - // We can only take the address of mutable values in the same assembly - valRefInThisAssembly g.compilingFslib vref - -let MustTakeAddressOfByrefGet (g: TcGlobals) (vref: ValRef) = - isByrefTy g vref.Type && not (isInByrefTy g vref.Type) - -let CanTakeAddressOfByrefGet (g: TcGlobals) (vref: ValRef) mut = - isInByrefTy g vref.Type && - CanTakeAddressOf g vref.Range true (destByrefTy g vref.Type) mut - -let MustTakeAddressOfRecdField (rfref: RecdField) = - // Static mutable fields must be private, hence we don't have to take their address - not rfref.IsStatic && - rfref.IsMutable - -let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField - -let CanTakeAddressOfRecdFieldRef (g: TcGlobals) m (rfref: RecdFieldRef) tinst mut = - // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields - entityRefInThisAssembly g.compilingFslib rfref.TyconRef && - not rfref.RecdField.IsMutable && - CanTakeAddressOf g m false (actualTyOfRecdFieldRef rfref tinst) mut - -let CanTakeAddressOfUnionFieldRef (g: TcGlobals) m (uref: UnionCaseRef) cidx tinst mut = - // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields - entityRefInThisAssembly g.compilingFslib uref.TyconRef && - let rfref = uref.FieldByIndex cidx - not rfref.IsMutable && - CanTakeAddressOf g m false (actualTyOfUnionFieldRef uref cidx tinst) mut - -let mkDerefAddrExpr mAddrGet expr mExpr exprTy = - let v, _ = mkCompGenLocal mAddrGet "byrefReturn" exprTy - mkCompGenLet mExpr v expr (mkAddrGet mAddrGet (mkLocalValRef v)) - -/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope. -/// Also return a flag that indicates if the resulting pointer is a not a pointer where writing is allowed and will -/// have intended effect (i.e. is a readonly pointer and/or a defensive copy). -let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut expr addrExprVal m = - if mustTakeAddress then - match expr with - // LVALUE of "*x" where "x" is byref is just the byref itself - | Expr.Op (TOp.LValueOp (LByrefGet, vref), _, [], m) when MustTakeAddressOfByrefGet g vref || CanTakeAddressOfByrefGet g vref mut -> - let readonly = not (MustTakeAddressOfByrefGet g vref) - let writeonly = isOutByrefTy g vref.Type - None, exprForValRef m vref, readonly, writeonly - - // LVALUE of "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate. - // Note: we can always take the address of mutable intra-assembly values - | Expr.Val (vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut -> - let readonly = not (MustTakeAddressOfVal g vref) - let writeonly = false - None, mkValAddr m readonly vref, readonly, writeonly - - // LVALUE of "e.f" where "f" is an instance F# field or record field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [objExpr], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut -> - let objTy = tyOfExpr g objExpr - let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken - let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m - let readonly = readonly || isInByrefTy g objTy || not (MustTakeAddressOfRecdFieldRef rfref) - let writeonly = writeonly || isOutByrefTy g objTy - wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly, writeonly - - // LVALUE of "f" where "f" is a static F# field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut -> - let readonly = not (MustTakeAddressOfRecdFieldRef rfref) - let writeonly = false - None, mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m), readonly, writeonly - - // LVALUE of "e.f" where "f" is an F# union field. - | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [objExpr], m) when MustTakeAddressOfRecdField (uref.FieldByIndex cidx) || CanTakeAddressOfUnionFieldRef g m uref cidx tinst mut -> - let objTy = tyOfExpr g objExpr - let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken - let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m - let readonly = readonly || isInByrefTy g objTy || not (MustTakeAddressOfRecdField (uref.FieldByIndex cidx)) - let writeonly = writeonly || isOutByrefTy g objTy - wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly, writeonly - - // LVALUE of "f" where "f" is a .NET static field. - | Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) -> - let readonly = false // we never consider taking the address of a .NET static field to give an inref pointer - let writeonly = false - None, Expr.Op (TOp.ILAsm ([IL.I_ldsflda fspec], [mkByrefTy g ty2]), tinst, [], m), readonly, writeonly - - // LVALUE of "e.f" where "f" is a .NET instance field. - | Expr.Op (TOp.ILAsm ([IL.I_ldfld (_align, _vol, fspec)], [ty2]), tinst, [objExpr], m) -> - let objTy = tyOfExpr g objExpr - let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken - // we never consider taking the address of an .NET instance field to give an inref pointer, unless the object pointer is an inref pointer - let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m - let readonly = readonly || isInByrefTy g objTy - let writeonly = writeonly || isOutByrefTy g objTy - wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda fspec], [mkByrefTyWithFlag g readonly ty2]), tinst, [expra], m), readonly, writeonly - - // LVALUE of "e.[n]" where e is an array of structs - | Expr.App (Expr.Val (vf, _, _), _, [elemTy], [aexpr;nexpr], _) when (valRefEq g vf g.array_get_vref) -> - - let readonly = false // array address is never forced to be readonly - let writeonly = false - let shape = ILArrayShape.SingleDimensional - let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress - let isNativePtr = - match addrExprVal with - | Some vf -> valRefEq g vf g.addrof2_vref - | _ -> false - None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [aexpr; nexpr], m), readonly, writeonly - - // LVALUE of "e.[n1, n2]", "e.[n1, n2, n3]", "e.[n1, n2, n3, n4]" where e is an array of structs - | Expr.App (Expr.Val (vref, _, _), _, [elemTy], (aexpr :: args), _) - when (valRefEq g vref g.array2D_get_vref || valRefEq g vref g.array3D_get_vref || valRefEq g vref g.array4D_get_vref) -> - - let readonly = false // array address is never forced to be readonly - let writeonly = false - let shape = ILArrayShape.FromRank args.Length - let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress - let isNativePtr = - match addrExprVal with - | Some vf -> valRefEq g vf g.addrof2_vref - | _ -> false - - None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr :: args), m), readonly, writeonly - - // LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]". - | Expr.Let (TBind(vref, e, _), Expr.Op (TOp.LValueOp (LByrefGet, vref2), _, _, _), _, _) - when (valRefEq g (mkLocalValRef vref) vref2) && - (MustTakeAddressOfByrefGet g vref2 || CanTakeAddressOfByrefGet g vref2 mut) -> - let ty = tyOfExpr g e - let readonly = isInByrefTy g ty - let writeonly = isOutByrefTy g ty - None, e, readonly, writeonly - - // Give a nice error message for address-of-byref - | Expr.Val (vref, _, m) when isByrefTy g vref.Type -> - error(Error(FSComp.SR.tastUnexpectedByRef(), m)) - - // Give a nice error message for DefinitelyMutates of address-of on mutable values in other assemblies - | Expr.Val (vref, _, m) when (mut = DefinitelyMutates || mut = AddressOfOp) && vref.IsMutable -> - error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m)) - - // Give a nice error message for AddressOfOp on immutable values - | Expr.Val _ when mut = AddressOfOp -> - error(Error(FSComp.SR.tastValueMustBeLocal(), m)) - - // Give a nice error message for mutating a value we can't take the address of - | Expr.Val _ when mut = DefinitelyMutates -> - error(Error(FSComp.SR.tastValueMustBeMutable(), m)) - - | _ -> - let ty = tyOfExpr g expr - if isStructTy g ty then - match mut with - | NeverMutates - | AddressOfOp -> () - | DefinitelyMutates -> - // Give a nice error message for mutating something we can't take the address of - errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)) - | PossiblyMutates -> - // Warn on defensive copy of something we can't take the address of - warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)) - - match mut with - | NeverMutates - | DefinitelyMutates - | PossiblyMutates -> () - | AddressOfOp -> - // we get an inref - errorR(Error(FSComp.SR.tastCantTakeAddressOfExpression(), m)) - - // Take a defensive copy - let tmp, _ = - match mut with - | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty - | _ -> mkMutableCompGenLocal m "copyOfStruct" ty - - // This local is special in that it ignore byref scoping rules. - tmp.SetIgnoresByrefScope() - - let readonly = true - let writeonly = false - Some (tmp, expr), (mkValAddr m readonly (mkLocalValRef tmp)), readonly, writeonly - else - None, expr, false, false - -let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = - let optBind, addre, readonly, writeonly = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m - match optBind with - | None -> (fun x -> x), addre, readonly, writeonly - | Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre, readonly, writeonly - -let mkTupleFieldGet g (tupInfo, e, tinst, i, m) = - let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalTupInfoIsStruct tupInfo) false NeverMutates e None m - wrap (mkTupleFieldGetViaExprAddr(tupInfo, e', tinst, i, m)) - -let mkAnonRecdFieldGet g (anonInfo: AnonRecdTypeInfo, e, tinst, i, m) = - let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalAnonInfoIsStruct anonInfo) false NeverMutates e None m - wrap (mkAnonRecdFieldGetViaExprAddr(anonInfo, e', tinst, i, m)) - -let mkRecdFieldGet g (e, fref: RecdFieldRef, tinst, m) = - assert (not (isByrefTy g (tyOfExpr g e))) - let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m - wrap (mkRecdFieldGetViaExprAddr (e', fref, tinst, m)) - -let mkUnionCaseFieldGetUnproven g (e, cref: UnionCaseRef, tinst, j, m) = - assert (not (isByrefTy g (tyOfExpr g e))) - let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g cref.Tycon.IsStructOrEnumTycon false NeverMutates e None m - wrap (mkUnionCaseFieldGetUnprovenViaExprAddr (e', cref, tinst, j, m)) - -let mkArray (argty, args, m) = Expr.Op (TOp.Array, [argty], args, m) - -//--------------------------------------------------------------------------- -// Compute fixups for letrec's. -// -// Generate an assignment expression that will fixup the recursion -// amongst the vals on the r.h.s. of a letrec. The returned expressions -// include disorderly constructs such as expressions/statements -// to set closure environments and non-mutable fields. These are only ever -// generated by the backend code-generator when processing a "letrec" -// construct. -// -// [self] is the top level value that is being fixed -// [exprToFix] is the r.h.s. expression -// [rvs] is the set of recursive vals being bound. -// [acc] accumulates the expression right-to-left. -// -// Traversal of the r.h.s. term must happen back-to-front to get the -// uniq's for the lambdas correct in the very rare case where the same lambda -// somehow appears twice on the right. -//--------------------------------------------------------------------------- - -let rec IterateRecursiveFixups g (selfv: Val option) rvs ((access: Expr), set) exprToFix = - let exprToFix = stripExpr exprToFix - match exprToFix with - | Expr.Const _ -> () - | Expr.Op (TOp.Tuple tupInfo, argtys, args, m) when not (evalTupInfoIsStruct tupInfo) -> - args |> List.iteri (fun n -> - IterateRecursiveFixups g None rvs - (mkTupleFieldGet g (tupInfo, access, argtys, n, m), - (fun e -> - // NICE: it would be better to do this check in the type checker - errorR(Error(FSComp.SR.tastRecursiveValuesMayNotBeInConstructionOfTuple(), m)) - e))) - - | Expr.Op (TOp.UnionCase c, tinst, args, m) -> - args |> List.iteri (fun n -> - IterateRecursiveFixups g None rvs - (mkUnionCaseFieldGetUnprovenViaExprAddr (access, c, tinst, n, m), - (fun e -> - // NICE: it would be better to do this check in the type checker - let tcref = c.TyconRef - if not (c.FieldByIndex n).IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then - errorR(Error(FSComp.SR.tastRecursiveValuesMayNotAppearInConstructionOfType(tcref.LogicalName), m)) - mkUnionCaseFieldSet (access, c, tinst, n, e, m)))) - - | Expr.Op (TOp.Recd (_, tcref), tinst, args, m) -> - (tcref.TrueInstanceFieldsAsRefList, args) ||> List.iter2 (fun fref arg -> - let fspec = fref.RecdField - IterateRecursiveFixups g None rvs - (mkRecdFieldGetViaExprAddr (access, fref, tinst, m), - (fun e -> - // NICE: it would be better to do this check in the type checker - if not fspec.IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then - errorR(Error(FSComp.SR.tastRecursiveValuesMayNotBeAssignedToNonMutableField(fspec.rfield_id.idText, tcref.LogicalName), m)) - mkRecdFieldSetViaExprAddr (access, fref, tinst, e, m))) arg ) - | Expr.Val _ - | Expr.Lambda _ - | Expr.Obj _ - | Expr.TyChoose _ - | Expr.TyLambda _ -> - rvs selfv access set exprToFix - | _ -> () - -//-------------------------------------------------------------------------- -// computations on constraints -//-------------------------------------------------------------------------- - -let JoinTyparStaticReq r1 r2 = - match r1, r2 with - | NoStaticReq, r | r, NoStaticReq -> r - | HeadTypeStaticReq, r | r, HeadTypeStaticReq -> r - -//------------------------------------------------------------------------- -// ExprFolder - fold steps -//------------------------------------------------------------------------- - -type ExprFolder<'State> = - { exprIntercept : (* recurseF *) ('State -> Expr -> 'State) -> (* noInterceptF *) ('State -> Expr -> 'State) -> 'State -> Expr -> 'State - // the bool is 'bound in dtree' - valBindingSiteIntercept : 'State -> bool * Val -> 'State - // these values are always bound to these expressions. bool indicates 'recursively' - nonRecBindingsIntercept : 'State -> Binding -> 'State - recBindingsIntercept : 'State -> Bindings -> 'State - dtreeIntercept : 'State -> DecisionTree -> 'State - targetIntercept : (* recurseF *) ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option - tmethodIntercept : (* recurseF *) ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option - } - -let ExprFolder0 = - { exprIntercept = (fun _recurseF noInterceptF z x -> noInterceptF z x) - valBindingSiteIntercept = (fun z _b -> z) - nonRecBindingsIntercept = (fun z _bs -> z) - recBindingsIntercept = (fun z _bs -> z) - dtreeIntercept = (fun z _dt -> z) - targetIntercept = (fun _exprF _z _x -> None) - tmethodIntercept = (fun _exprF _z _x -> None) } - -//------------------------------------------------------------------------- -// FoldExpr -//------------------------------------------------------------------------- - -/// Adapted from usage info folding. -/// Collecting from exprs at moment. -/// To collect ids etc some additional folding needed, over formals etc. -type ExprFolders<'State> (folders: ExprFolder<'State>) = - let mutable exprFClosure = Unchecked.defaultof<'State -> Expr -> 'State> // prevent reallocation of closure - let mutable exprNoInterceptFClosure = Unchecked.defaultof<'State -> Expr -> 'State> // prevent reallocation of closure - - let rec exprsF z xs = - List.fold exprFClosure z xs - - and exprF (z: 'State) (x: Expr) = - folders.exprIntercept exprFClosure exprNoInterceptFClosure z x - - and exprNoInterceptF (z: 'State) (x: Expr) = - match x with - - | Expr.Const _ -> z - - | Expr.Val _ -> z - - | LinearOpExpr (_op, _tyargs, argsHead, argLast, _m) -> - let z = exprsF z argsHead - // tailcall - exprF z argLast - - | Expr.Op (_c, _tyargs, args, _) -> - exprsF z args - - | Expr.Sequential (x0, x1, _dir, _, _) -> - let z = exprF z x0 - exprF z x1 - - | Expr.Lambda (_lambdaId, _ctorThisValOpt, _baseValOpt, _argvs, body, _m, _rty) -> - exprF z body - - | Expr.TyLambda (_lambdaId, _argtyvs, body, _m, _rty) -> - exprF z body - - | Expr.TyChoose (_, body, _) -> - exprF z body - - | Expr.App (f, _fty, _tys, argtys, _) -> - let z = exprF z f - exprsF z argtys - - | Expr.LetRec (binds, body, _, _) -> - let z = valBindsF false z binds - exprF z body - - | Expr.Let (bind, body, _, _) -> - let z = valBindF false z bind - exprF z body - - | Expr.Link rX -> exprF z (!rX) - - | Expr.Match (_spBind, _exprm, dtree, targets, _m, _ty) -> - let z = dtreeF z dtree - let z = Array.fold targetF z targets.[0..targets.Length - 2] - // tailcall - targetF z targets.[targets.Length - 1] - - | Expr.Quote (e, {contents=Some(_typeDefs, _argTypes, argExprs, _)}, _, _, _) -> - let z = exprF z e - exprsF z argExprs - - | Expr.Quote (e, {contents=None}, _, _m, _) -> - exprF z e - - | Expr.Obj (_n, _typ, _basev, basecall, overrides, iimpls, _m) -> - let z = exprF z basecall - let z = List.fold tmethodF z overrides - List.fold (foldOn snd (List.fold tmethodF)) z iimpls - - | Expr.StaticOptimization (_tcs, csx, x, _) -> - exprsF z [csx;x] - - and valBindF dtree z bind = - let z = folders.nonRecBindingsIntercept z bind - bindF dtree z bind - - and valBindsF dtree z binds = - let z = folders.recBindingsIntercept z binds - List.fold (bindF dtree) z binds - - and bindF dtree z (bind: Binding) = - let z = folders.valBindingSiteIntercept z (dtree, bind.Var) - exprF z bind.Expr - - and dtreeF z dtree = - let z = folders.dtreeIntercept z dtree - match dtree with - | TDBind (bind, rest) -> - let z = valBindF true z bind - dtreeF z rest - | TDSuccess (args, _) -> exprsF z args - | TDSwitch (test, dcases, dflt, _) -> - let z = exprF z test - let z = List.fold dcaseF z dcases - let z = Option.fold dtreeF z dflt - z - - and dcaseF z = function - TCase (_, dtree) -> dtreeF z dtree (* not collecting from test *) - - and targetF z x = - match folders.targetIntercept exprFClosure z x with - | Some z -> z // intercepted - | None -> // structurally recurse - let (TTarget (_, body, _)) = x - exprF z body - - and tmethodF z x = - match folders.tmethodIntercept exprFClosure z x with - | Some z -> z // intercepted - | None -> // structurally recurse - let (TObjExprMethod(_, _, _, _, e, _)) = x - exprF z e - - and mexprF z x = - match x with - | ModuleOrNamespaceExprWithSig(_, def, _) -> mdefF z def - - and mdefF z x = - match x with - | TMDefRec(_, _, mbinds, _) -> - // REVIEW: also iterate the abstract slot vspecs hidden in the _vslots field in the tycons - let z = List.fold mbindF z mbinds - z - | TMDefLet(bind, _) -> valBindF false z bind - | TMDefDo(e, _) -> exprF z e - | TMDefs defs -> List.fold mdefF z defs - | TMAbstract x -> mexprF z x - - and mbindF z x = - match x with - | ModuleOrNamespaceBinding.Binding b -> valBindF false z b - | ModuleOrNamespaceBinding.Module(_, def) -> mdefF z def - - and implF z x = foldTImplFile mexprF z x - - do exprFClosure <- exprF // allocate one instance of this closure - do exprNoInterceptFClosure <- exprNoInterceptF // allocate one instance of this closure - - member x.FoldExpr = exprF - - member x.FoldImplFile = implF - -let FoldExpr folders state expr = ExprFolders(folders).FoldExpr state expr - -let FoldImplFile folders state implFile = ExprFolders(folders).FoldImplFile state implFile - -#if DEBUG -//------------------------------------------------------------------------- -// ExprStats -//------------------------------------------------------------------------- - -let ExprStats x = - let mutable count = 0 - let folders = {ExprFolder0 with exprIntercept = (fun _ noInterceptF z x -> (count <- count + 1; noInterceptF z x))} - let () = FoldExpr folders () x - string count + " TExpr nodes" -#endif - -//------------------------------------------------------------------------- -// Make expressions -//------------------------------------------------------------------------- - -let mkString (g: TcGlobals) m n = Expr.Const (Const.String n, m, g.string_ty) - -let mkBool (g: TcGlobals) m b = Expr.Const (Const.Bool b, m, g.bool_ty) - -let mkByte (g: TcGlobals) m b = Expr.Const (Const.Byte b, m, g.byte_ty) - -let mkUInt16 (g: TcGlobals) m b = Expr.Const (Const.UInt16 b, m, g.uint16_ty) - -let mkTrue g m = mkBool g m true - -let mkFalse g m = mkBool g m false - -let mkUnit (g: TcGlobals) m = Expr.Const (Const.Unit, m, g.unit_ty) - -let mkInt32 (g: TcGlobals) m n = Expr.Const (Const.Int32 n, m, g.int32_ty) - -let mkInt g m n = mkInt32 g m n - -let mkZero g m = mkInt g m 0 - -let mkOne g m = mkInt g m 1 - -let mkTwo g m = mkInt g m 2 - -let mkMinusOne g m = mkInt g m (-1) - -let destInt32 = function Expr.Const (Const.Int32 n, _, _) -> Some n | _ -> None - -let isIDelegateEventType g ty = - match tryDestAppTy g ty with - | ValueSome tcref -> tyconRefEq g g.fslib_IDelegateEvent_tcr tcref - | _ -> false - -let destIDelegateEventType g ty = - if isIDelegateEventType g ty then - match argsOfAppTy g ty with - | [ty1] -> ty1 - | _ -> failwith "destIDelegateEventType: internal error" - else failwith "destIDelegateEventType: not an IDelegateEvent type" - -let mkIEventType (g: TcGlobals) ty1 ty2 = TType_app (g.fslib_IEvent2_tcr, [ty1;ty2]) - -let mkIObservableType (g: TcGlobals) ty1 = TType_app (g.tcref_IObservable, [ty1]) - -let mkIObserverType (g: TcGlobals) ty1 = TType_app (g.tcref_IObserver, [ty1]) - -let mkRefCellContentsRef (g: TcGlobals) = mkRecdFieldRef g.refcell_tcr_canon "contents" - -let mkSequential spSeq m e1 e2 = Expr.Sequential (e1, e2, NormalSeq, spSeq, m) - -let mkCompGenSequential m e1 e2 = mkSequential SuppressSequencePointOnExprOfSequential m e1 e2 - -let rec mkSequentials spSeq g m es = - match es with - | [e] -> e - | e :: es -> mkSequential spSeq m e (mkSequentials spSeq g m es) - | [] -> mkUnit g m - -let mkGetArg0 m ty = mkAsmExpr ( [ mkLdarg0 ], [], [], [ty], m) - -//------------------------------------------------------------------------- -// Tuples... -//------------------------------------------------------------------------- - -let mkAnyTupled g m tupInfo es tys = - match es with - | [] -> mkUnit g m - | [e] -> e - | _ -> Expr.Op (TOp.Tuple tupInfo, tys, es, m) - -let mkRefTupled g m es tys = mkAnyTupled g m tupInfoRef es tys - -let mkRefTupledNoTypes g m args = mkRefTupled g m args (List.map (tyOfExpr g) args) - -let mkRefTupledVars g m vs = mkRefTupled g m (List.map (exprForVal m) vs) (typesOfVals vs) - -//-------------------------------------------------------------------------- -// Permute expressions -//-------------------------------------------------------------------------- - -let inversePerm (sigma: int array) = - let n = sigma.Length - let invSigma = Array.create n -1 - for i = 0 to n-1 do - let sigma_i = sigma.[i] - // assert( invSigma.[sigma_i] = -1 ) - invSigma.[sigma_i] <- i - invSigma - -let permute (sigma: int[]) (data:'T[]) = - let n = sigma.Length - let invSigma = inversePerm sigma - Array.init n (fun i -> data.[invSigma.[i]]) - -let rec existsR a b pred = if a<=b then pred a || existsR (a+1) b pred else false - -// Given a permutation for record fields, work out the highest entry that we must lift out -// of a record initialization. Lift out xi if xi goes to position that will be preceded by an expr with an effect -// that originally followed xi. If one entry gets lifted then everything before it also gets lifted. -let liftAllBefore sigma = - let invSigma = inversePerm sigma - - let lifted = - [ for i in 0 .. sigma.Length - 1 do - let i' = sigma.[i] - if existsR 0 (i' - 1) (fun j' -> invSigma.[j'] > i) then - yield i ] - - if lifted.IsEmpty then 0 else List.max lifted + 1 - - -/// Put record field assignments in order. -// -let permuteExprList (sigma: int[]) (exprs: Expr list) (ty: TType list) (names: string list) = - let ty, names = (Array.ofList ty, Array.ofList names) - - let liftLim = liftAllBefore sigma - - let rewrite rbinds (i, expri: Expr) = - if i < liftLim then - let tmpvi, tmpei = mkCompGenLocal expri.Range names.[i] ty.[i] - let bindi = mkCompGenBind tmpvi expri - tmpei, bindi :: rbinds - else - expri, rbinds - - let newExprs, reversedBinds = List.mapFold rewrite [] (exprs |> List.indexed) - let binds = List.rev reversedBinds - let reorderedExprs = permute sigma (Array.ofList newExprs) - binds, Array.toList reorderedExprs - -/// Evaluate the expressions in the original order, but build a record with the results in field order -/// Note some fields may be static. If this were not the case we could just use -/// let sigma = Array.map #Index () -/// However the presence of static fields means .Index may index into a non-compact set of instance field indexes. -/// We still need to sort by index. -let mkRecordExpr g (lnk, tcref, tinst, unsortedRecdFields: RecdFieldRef list, unsortedFieldExprs, m) = - // Remove any abbreviations - let tcref, tinst = destAppTy g (mkAppTy tcref tinst) - - let sortedRecdFields = unsortedRecdFields |> List.indexed |> Array.ofList |> Array.sortBy (fun (_, r) -> r.Index) - let sigma = Array.create sortedRecdFields.Length -1 - sortedRecdFields |> Array.iteri (fun sortedIdx (unsortedIdx, _) -> - if sigma.[unsortedIdx] <> -1 then error(InternalError("bad permutation", m)) - sigma.[unsortedIdx] <- sortedIdx) - - let unsortedArgTys = unsortedRecdFields |> List.map (fun rfref -> actualTyOfRecdFieldRef rfref tinst) - let unsortedArgNames = unsortedRecdFields |> List.map (fun rfref -> rfref.FieldName) - let unsortedArgBinds, sortedArgExprs = permuteExprList sigma unsortedFieldExprs unsortedArgTys unsortedArgNames - let core = Expr.Op (TOp.Recd (lnk, tcref), tinst, sortedArgExprs, m) - mkLetsBind m unsortedArgBinds core - -let mkAnonRecd (_g: TcGlobals) m (anonInfo: AnonRecdTypeInfo) (unsortedIds: Ident[]) (unsortedFieldExprs: Expr list) unsortedArgTys = - let sortedRecdFields = unsortedFieldExprs |> List.indexed |> Array.ofList |> Array.sortBy (fun (i,_) -> unsortedIds.[i].idText) - let sortedArgTys = unsortedArgTys |> List.indexed |> List.sortBy (fun (i,_) -> unsortedIds.[i].idText) |> List.map snd - - let sigma = Array.create sortedRecdFields.Length -1 - sortedRecdFields |> Array.iteri (fun sortedIdx (unsortedIdx, _) -> - if sigma.[unsortedIdx] <> -1 then error(InternalError("bad permutation", m)) - sigma.[unsortedIdx] <- sortedIdx) - - let unsortedArgNames = unsortedIds |> Array.toList |> List.map (fun id -> id.idText) - let unsortedArgBinds, sortedArgExprs = permuteExprList sigma unsortedFieldExprs unsortedArgTys unsortedArgNames - let core = Expr.Op (TOp.AnonRecd anonInfo, sortedArgTys, sortedArgExprs, m) - mkLetsBind m unsortedArgBinds core - -//------------------------------------------------------------------------- -// List builders -//------------------------------------------------------------------------- - -let mkRefCell g m ty e = mkRecordExpr g (RecdExpr, g.refcell_tcr_canon, [ty], [mkRefCellContentsRef g], [e], m) - -let mkRefCellGet g m ty e = mkRecdFieldGetViaExprAddr (e, mkRefCellContentsRef g, [ty], m) - -let mkRefCellSet g m ty e1 e2 = mkRecdFieldSetViaExprAddr (e1, mkRefCellContentsRef g, [ty], e2, m) - -let mkNil (g: TcGlobals) m ty = mkUnionCaseExpr (g.nil_ucref, [ty], [], m) - -let mkCons (g: TcGlobals) ty h t = mkUnionCaseExpr (g.cons_ucref, [ty], [h;t], unionRanges h.Range t.Range) - -let mkCompGenLocalAndInvisibleBind g nm m e = - let locv, loce = mkCompGenLocal m nm (tyOfExpr g e) - locv, loce, mkInvisibleBind locv e - -//---------------------------------------------------------------------------- -// Make some fragments of code -//---------------------------------------------------------------------------- - -let box = IL.I_box (mkILTyvarTy 0us) - -let isinst = IL.I_isinst (mkILTyvarTy 0us) - -let unbox = IL.I_unbox_any (mkILTyvarTy 0us) - -let mkUnbox ty e m = mkAsmExpr ([ unbox ], [ty], [e], [ ty ], m) - -let mkBox ty e m = mkAsmExpr ([box], [], [e], [ty], m) - -let mkIsInst ty e m = mkAsmExpr ([ isinst ], [ty], [e], [ ty ], m) - -let mspec_Type_GetTypeFromHandle (g: TcGlobals) = IL.mkILNonGenericStaticMethSpecInTy(g.ilg.typ_Type, "GetTypeFromHandle", [g.iltyp_RuntimeTypeHandle], g.ilg.typ_Type) - -let mspec_String_Length (g: TcGlobals) = mkILNonGenericInstanceMethSpecInTy (g.ilg.typ_String, "get_Length", [], g.ilg.typ_Int32) - -let mspec_String_Concat2 (g: TcGlobals) = - mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) - -let mspec_String_Concat3 (g: TcGlobals) = - mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) - -let mspec_String_Concat4 (g: TcGlobals) = - mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) - -let mspec_String_Concat_Array (g: TcGlobals) = - mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ mkILArr1DTy g.ilg.typ_String ], g.ilg.typ_String) - -let fspec_Missing_Value (g: TcGlobals) = IL.mkILFieldSpecInTy(g.iltyp_Missing, "Value", g.iltyp_Missing) - -let mkInitializeArrayMethSpec (g: TcGlobals) = - let tref = g.FindSysILTypeRef "System.Runtime.CompilerServices.RuntimeHelpers" - mkILNonGenericStaticMethSpecInTy(mkILNonGenericBoxedTy tref, "InitializeArray", [g.ilg.typ_Array;g.iltyp_RuntimeFieldHandle], ILType.Void) - -let mkInvalidCastExnNewobj (g: TcGlobals) = - mkNormalNewobj (mkILCtorMethSpecForTy (mkILNonGenericBoxedTy (g.FindSysILTypeRef "System.InvalidCastException"), [])) - - -let typedExprForIntrinsic _g m (IntrinsicValRef(_, _, _, ty, _) as i) = - let vref = ValRefForIntrinsic i - exprForValRef m vref, ty - -let mkCallGetGenericComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_comparer_info |> fst - -let mkCallGetGenericEREqualityComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_er_equality_comparer_info |> fst - -let mkCallGetGenericPEREqualityComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_per_equality_comparer_info |> fst - -let mkCallUnbox (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unbox_info, [[ty]], [ e1 ], m) - -let mkCallUnboxFast (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unbox_fast_info, [[ty]], [ e1 ], m) - -let mkCallTypeTest (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.istype_info, [[ty]], [ e1 ], m) - -let mkCallTypeOf (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.typeof_info, [[ty]], [ ], m) - -let mkCallTypeDefOf (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.typedefof_info, [[ty]], [ ], m) - -let mkCallDispose (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.dispose_info, [[ty]], [ e1 ], m) - -let mkCallSeq (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.seq_info, [[ty]], [ e1 ], m) - -let mkCallCreateInstance (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.create_instance_info, [[ty]], [ mkUnit g m ], m) - -let mkCallGetQuerySourceAsEnumerable (g: TcGlobals) m ty1 ty2 e1 = mkApps g (typedExprForIntrinsic g m g.query_source_as_enum_info, [[ty1;ty2]], [ e1; mkUnit g m ], m) - -let mkCallNewQuerySource (g: TcGlobals) m ty1 ty2 e1 = mkApps g (typedExprForIntrinsic g m g.new_query_source_info, [[ty1;ty2]], [ e1 ], m) - -let mkCallCreateEvent (g: TcGlobals) m ty1 ty2 e1 e2 e3 = mkApps g (typedExprForIntrinsic g m g.create_event_info, [[ty1;ty2]], [ e1;e2;e3 ], m) - -let mkCallGenericComparisonWithComparerOuter (g: TcGlobals) m ty comp e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_comparison_withc_outer_info, [[ty]], [ comp;e1;e2 ], m) - -let mkCallGenericEqualityEROuter (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_equality_er_outer_info, [[ty]], [ e1;e2 ], m) - -let mkCallGenericEqualityWithComparerOuter (g: TcGlobals) m ty comp e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_equality_withc_outer_info, [[ty]], [comp;e1;e2], m) - -let mkCallGenericHashWithComparerOuter (g: TcGlobals) m ty comp e1 = mkApps g (typedExprForIntrinsic g m g.generic_hash_withc_outer_info, [[ty]], [comp;e1], m) - -let mkCallEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.equals_operator_info, [[ty]], [ e1;e2 ], m) - -let mkCallNotEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.not_equals_operator, [[ty]], [ e1;e2 ], m) - -let mkCallLessThanOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.less_than_operator, [[ty]], [ e1;e2 ], m) - -let mkCallLessThanOrEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.less_than_or_equals_operator, [[ty]], [ e1;e2 ], m) - -let mkCallGreaterThanOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.greater_than_operator, [[ty]], [ e1;e2 ], m) - -let mkCallGreaterThanOrEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.greater_than_or_equals_operator, [[ty]], [ e1;e2 ], m) - -let mkCallAdditionOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_addition_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallSubtractionOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_subtraction_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallMultiplyOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_multiply_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallDivisionOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_division_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallModulusOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_modulus_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallBitwiseAndOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_and_info, [[ty]], [e1;e2], m) - -let mkCallBitwiseOrOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_or_info, [[ty]], [e1;e2], m) - -let mkCallBitwiseXorOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_xor_info, [[ty]], [e1;e2], m) - -let mkCallShiftLeftOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_shift_left_info, [[ty]], [e1;e2], m) - -let mkCallShiftRightOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_shift_right_info, [[ty]], [e1;e2], m) - -let mkCallUnaryNegOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unchecked_unary_minus_info, [[ty]], [e1], m) - -let mkCallUnaryNotOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.bitwise_unary_not_info, [[ty]], [e1], m) - -let mkCallAdditionChecked (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_addition_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallSubtractionChecked (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_subtraction_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallMultiplyChecked (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_multiply_info, [[ty; ty; ty]], [e1;e2], m) - -let mkCallUnaryNegChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.checked_unary_minus_info, [[ty]], [e1], m) - -let mkCallToByteChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.byte_checked_info, [[ty]], [e1], m) - -let mkCallToSByteChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.sbyte_checked_info, [[ty]], [e1], m) - -let mkCallToInt16Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int16_checked_info, [[ty]], [e1], m) - -let mkCallToUInt16Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint16_checked_info, [[ty]], [e1], m) - -let mkCallToIntChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int_checked_info, [[ty]], [e1], m) - -let mkCallToInt32Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int32_checked_info, [[ty]], [e1], m) - -let mkCallToUInt32Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint32_checked_info, [[ty]], [e1], m) - -let mkCallToInt64Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int64_checked_info, [[ty]], [e1], m) - -let mkCallToUInt64Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint64_checked_info, [[ty]], [e1], m) - -let mkCallToIntPtrChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.nativeint_checked_info, [[ty]], [e1], m) - -let mkCallToUIntPtrChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unativeint_checked_info, [[ty]], [e1], m) - -let mkCallToByteOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.byte_operator_info, [[ty]], [e1], m) - -let mkCallToSByteOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.sbyte_operator_info, [[ty]], [e1], m) - -let mkCallToInt16Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int16_operator_info, [[ty]], [e1], m) - -let mkCallToUInt16Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint16_operator_info, [[ty]], [e1], m) - -let mkCallToIntOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int_operator_info, [[ty]], [e1], m) - -let mkCallToInt32Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int32_operator_info, [[ty]], [e1], m) - -let mkCallToUInt32Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint32_operator_info, [[ty]], [e1], m) - -let mkCallToInt64Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int64_operator_info, [[ty]], [e1], m) - -let mkCallToUInt64Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint64_operator_info, [[ty]], [e1], m) - -let mkCallToSingleOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.float32_operator_info, [[ty]], [e1], m) - -let mkCallToDoubleOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.float_operator_info, [[ty]], [e1], m) - -let mkCallToIntPtrOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.nativeint_operator_info, [[ty]], [e1], m) - -let mkCallToUIntPtrOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unativeint_operator_info, [[ty]], [e1], m) - -let mkCallToCharOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.char_operator_info, [[ty]], [e1], m) - -let mkCallToEnumOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.enum_operator_info, [[ty]], [e1], m) - -let mkCallArrayLength (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.array_length_info, [[ty]], [e1], m) - -let mkCallArrayGet (g: TcGlobals) m ty e1 idx1 = mkApps g (typedExprForIntrinsic g m g.array_get_info, [[ty]], [ e1 ; idx1 ], m) - -let mkCallArray2DGet (g: TcGlobals) m ty e1 idx1 idx2 = mkApps g (typedExprForIntrinsic g m g.array2D_get_info, [[ty]], [ e1 ; idx1; idx2 ], m) - -let mkCallArray3DGet (g: TcGlobals) m ty e1 idx1 idx2 idx3 = mkApps g (typedExprForIntrinsic g m g.array3D_get_info, [[ty]], [ e1 ; idx1; idx2; idx3 ], m) - -let mkCallArray4DGet (g: TcGlobals) m ty e1 idx1 idx2 idx3 idx4 = mkApps g (typedExprForIntrinsic g m g.array4D_get_info, [[ty]], [ e1 ; idx1; idx2; idx3; idx4 ], m) - -let mkCallArraySet (g: TcGlobals) m ty e1 idx1 v = mkApps g (typedExprForIntrinsic g m g.array_set_info, [[ty]], [ e1 ; idx1; v ], m) - -let mkCallArray2DSet (g: TcGlobals) m ty e1 idx1 idx2 v = mkApps g (typedExprForIntrinsic g m g.array2D_set_info, [[ty]], [ e1 ; idx1; idx2; v ], m) - -let mkCallArray3DSet (g: TcGlobals) m ty e1 idx1 idx2 idx3 v = mkApps g (typedExprForIntrinsic g m g.array3D_set_info, [[ty]], [ e1 ; idx1; idx2; idx3; v ], m) - -let mkCallArray4DSet (g: TcGlobals) m ty e1 idx1 idx2 idx3 idx4 v = mkApps g (typedExprForIntrinsic g m g.array4D_set_info, [[ty]], [ e1 ; idx1; idx2; idx3; idx4; v ], m) - -let mkCallHash (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.hash_info, [[ty]], [ e1 ], m) - -let mkCallBox (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.box_info, [[ty]], [ e1 ], m) - -let mkCallIsNull (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.isnull_info, [[ty]], [ e1 ], m) - -let mkCallIsNotNull (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.isnotnull_info, [[ty]], [ e1 ], m) - -let mkCallRaise (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.raise_info, [[ty]], [ e1 ], m) - -let mkCallNewDecimal (g: TcGlobals) m (e1, e2, e3, e4, e5) = mkApps g (typedExprForIntrinsic g m g.new_decimal_info, [], [ e1;e2;e3;e4;e5 ], m) - -let mkCallNewFormat (g: TcGlobals) m aty bty cty dty ety e1 = mkApps g (typedExprForIntrinsic g m g.new_format_info, [[aty;bty;cty;dty;ety]], [ e1 ], m) - -let TryEliminateDesugaredConstants g m c = - match c with - | Const.Decimal d -> - match System.Decimal.GetBits d with - | [| lo;med;hi; signExp |] -> - let scale = (min (((signExp &&& 0xFF0000) >>> 16) &&& 0xFF) 28) |> byte - let isNegative = (signExp &&& 0x80000000) <> 0 - Some(mkCallNewDecimal g m (mkInt g m lo, mkInt g m med, mkInt g m hi, mkBool g m isNegative, mkByte g m scale) ) - | _ -> failwith "unreachable" - | _ -> - None - -let mkSeqTy (g: TcGlobals) ty = mkAppTy g.seq_tcr [ty] - -let mkIEnumeratorTy (g: TcGlobals) ty = mkAppTy g.tcref_System_Collections_Generic_IEnumerator [ty] - -let mkCallSeqCollect g m alphaTy betaTy arg1 arg2 = - let enumty2 = try rangeOfFunTy g (tyOfExpr g arg1) with _ -> (* defensive programming *) (mkSeqTy g betaTy) - mkApps g (typedExprForIntrinsic g m g.seq_collect_info, [[alphaTy;enumty2;betaTy]], [ arg1; arg2 ], m) - -let mkCallSeqUsing g m resourceTy elemTy arg1 arg2 = - // We're instantiating val using : 'a -> ('a -> 'sb) -> seq<'b> when 'sb :> seq<'b> and 'a :> IDisposable - // We set 'sb -> range(typeof(arg2)) - let enumty = try rangeOfFunTy g (tyOfExpr g arg2) with _ -> (* defensive programming *) (mkSeqTy g elemTy) - mkApps g (typedExprForIntrinsic g m g.seq_using_info, [[resourceTy;enumty;elemTy]], [ arg1; arg2 ], m) - -let mkCallSeqDelay g m elemTy arg1 = - mkApps g (typedExprForIntrinsic g m g.seq_delay_info, [[elemTy]], [ arg1 ], m) - -let mkCallSeqAppend g m elemTy arg1 arg2 = - mkApps g (typedExprForIntrinsic g m g.seq_append_info, [[elemTy]], [ arg1; arg2 ], m) - -let mkCallSeqGenerated g m elemTy arg1 arg2 = - mkApps g (typedExprForIntrinsic g m g.seq_generated_info, [[elemTy]], [ arg1; arg2 ], m) - -let mkCallSeqFinally g m elemTy arg1 arg2 = - mkApps g (typedExprForIntrinsic g m g.seq_finally_info, [[elemTy]], [ arg1; arg2 ], m) - -let mkCallSeqOfFunctions g m ty1 ty2 arg1 arg2 arg3 = - mkApps g (typedExprForIntrinsic g m g.seq_of_functions_info, [[ty1;ty2]], [ arg1; arg2; arg3 ], m) - -let mkCallSeqToArray g m elemTy arg1 = - mkApps g (typedExprForIntrinsic g m g.seq_to_array_info, [[elemTy]], [ arg1 ], m) - -let mkCallSeqToList g m elemTy arg1 = - mkApps g (typedExprForIntrinsic g m g.seq_to_list_info, [[elemTy]], [ arg1 ], m) - -let mkCallSeqMap g m inpElemTy genElemTy arg1 arg2 = - mkApps g (typedExprForIntrinsic g m g.seq_map_info, [[inpElemTy;genElemTy]], [ arg1; arg2 ], m) - -let mkCallSeqSingleton g m ty1 arg1 = - mkApps g (typedExprForIntrinsic g m g.seq_singleton_info, [[ty1]], [ arg1 ], m) - -let mkCallSeqEmpty g m ty1 = - mkApps g (typedExprForIntrinsic g m g.seq_empty_info, [[ty1]], [ ], m) - -let mkCallDeserializeQuotationFSharp20Plus g m e1 e2 e3 e4 = - let args = [ e1; e2; e3; e4 ] - mkApps g (typedExprForIntrinsic g m g.deserialize_quoted_FSharp_20_plus_info, [], [ mkRefTupledNoTypes g m args ], m) - -let mkCallDeserializeQuotationFSharp40Plus g m e1 e2 e3 e4 e5 = - let args = [ e1; e2; e3; e4; e5 ] - mkApps g (typedExprForIntrinsic g m g.deserialize_quoted_FSharp_40_plus_info, [], [ mkRefTupledNoTypes g m args ], m) - -let mkCallCastQuotation g m ty e1 = - mkApps g (typedExprForIntrinsic g m g.cast_quotation_info, [[ty]], [ e1 ], m) - -let mkCallLiftValueWithName (g: TcGlobals) m ty nm e1 = - let vref = ValRefForIntrinsic g.lift_value_with_name_info - // Use "Expr.ValueWithName" if it exists in FSharp.Core - match vref.TryDeref with - | ValueSome _ -> - mkApps g (typedExprForIntrinsic g m g.lift_value_with_name_info, [[ty]], [mkRefTupledNoTypes g m [e1; mkString g m nm]], m) - | ValueNone -> - mkApps g (typedExprForIntrinsic g m g.lift_value_info, [[ty]], [e1], m) - -let mkCallLiftValueWithDefn g m qty e1 = - assert isQuotedExprTy g qty - let ty = destQuotedExprTy g qty - let vref = ValRefForIntrinsic g.lift_value_with_defn_info - // Use "Expr.WithValue" if it exists in FSharp.Core - match vref.TryDeref with - | ValueSome _ -> - let copyOfExpr = copyExpr g ValCopyFlag.CloneAll e1 - let quoteOfCopyOfExpr = Expr.Quote (copyOfExpr, ref None, false, m, qty) - mkApps g (typedExprForIntrinsic g m g.lift_value_with_defn_info, [[ty]], [mkRefTupledNoTypes g m [e1; quoteOfCopyOfExpr]], m) - | ValueNone -> - Expr.Quote (e1, ref None, false, m, qty) - -let mkCallCheckThis g m ty e1 = - mkApps g (typedExprForIntrinsic g m g.check_this_info, [[ty]], [e1], m) - -let mkCallFailInit g m = - mkApps g (typedExprForIntrinsic g m g.fail_init_info, [], [mkUnit g m], m) - -let mkCallFailStaticInit g m = - mkApps g (typedExprForIntrinsic g m g.fail_static_init_info, [], [mkUnit g m], m) - -let mkCallQuoteToLinqLambdaExpression g m ty e1 = - mkApps g (typedExprForIntrinsic g m g.quote_to_linq_lambda_info, [[ty]], [e1], m) - -let mkLazyDelayed g m ty f = mkApps g (typedExprForIntrinsic g m g.lazy_create_info, [[ty]], [ f ], m) - -let mkLazyForce g m ty e = mkApps g (typedExprForIntrinsic g m g.lazy_force_info, [[ty]], [ e; mkUnit g m ], m) - -let mkGetString g m e1 e2 = mkApps g (typedExprForIntrinsic g m g.getstring_info, [], [e1;e2], m) - -let mkGetStringChar = mkGetString - -let mkGetStringLength g m e = - let mspec = mspec_String_Length g - /// ILCall(useCallvirt, isProtected, valu, newobj, valUseFlags, isProp, noTailCall, mref, actualTypeInst, actualMethInst, retTy) - Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, true, false, mspec.MethodRef, [], [], [g.int32_ty]), [], [e], m) - -let mkStaticCall_String_Concat2 g m arg1 arg2 = - let mspec = mspec_String_Concat2 g - Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2], m) - -let mkStaticCall_String_Concat3 g m arg1 arg2 arg3 = - let mspec = mspec_String_Concat3 g - Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3], m) - -let mkStaticCall_String_Concat4 g m arg1 arg2 arg3 arg4 = - let mspec = mspec_String_Concat4 g - Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3; arg4], m) - -let mkStaticCall_String_Concat_Array g m arg = - let mspec = mspec_String_Concat_Array g - Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg], m) - -// Quotations can't contain any IL. -// As a result, we aim to get rid of all IL generation in the typechecker and pattern match -// compiler, or else train the quotation generator to understand the generated IL. -// Hence each of the following are marked with places where they are generated. - -// Generated by the optimizer and the encoding of 'for' loops -let mkDecr (g: TcGlobals) m e = mkAsmExpr ([ IL.AI_sub ], [], [e; mkOne g m], [g.int_ty], m) - -let mkIncr (g: TcGlobals) m e = mkAsmExpr ([ IL.AI_add ], [], [mkOne g m; e], [g.int_ty], m) - -// Generated by the pattern match compiler and the optimizer for -// 1. array patterns -// 2. optimizations associated with getting 'for' loops into the shape expected by the JIT. -// -// NOTE: The conv.i4 assumes that int_ty is int32. Note: ldlen returns native UNSIGNED int -let mkLdlen (g: TcGlobals) m arre = mkAsmExpr ([ IL.I_ldlen; (IL.AI_conv IL.DT_I4) ], [], [ arre ], [ g.int_ty ], m) - -let mkLdelem (_g: TcGlobals) m ty arre idxe = mkAsmExpr ([ IL.I_ldelem_any (ILArrayShape.SingleDimensional, mkILTyvarTy 0us) ], [ty], [ arre;idxe ], [ ty ], m) - -// This is generated in equality/compare/hash augmentations and in the pattern match compiler. -// It is understood by the quotation processor and turned into "Equality" nodes. -// -// Note: this is IL assembly code, don't go inserting this in expressions which will be exposed via quotations -let mkILAsmCeq (g: TcGlobals) m e1 e2 = mkAsmExpr ([ IL.AI_ceq ], [], [e1; e2], [g.bool_ty], m) - -let mkILAsmClt (g: TcGlobals) m e1 e2 = mkAsmExpr ([ IL.AI_clt ], [], [e1; e2], [g.bool_ty], m) - -// This is generated in the initialization of the "ctorv" field in the typechecker's compilation of -// an implicit class construction. -let mkNull m ty = Expr.Const (Const.Zero, m, ty) - -let mkThrow m ty e = mkAsmExpr ([ IL.I_throw ], [], [e], [ty], m) - -let destThrow = function - | Expr.Op (TOp.ILAsm ([IL.I_throw], [ty2]), [], [e], m) -> Some (m, ty2, e) - | _ -> None - -let isThrow x = Option.isSome (destThrow x) - -// reraise - parsed as library call - internally represented as op form. -let mkReraiseLibCall (g: TcGlobals) ty m = let ve, vt = typedExprForIntrinsic g m g.reraise_info in Expr.App (ve, vt, [ty], [mkUnit g m], m) - -let mkReraise m returnTy = Expr.Op (TOp.Reraise, [returnTy], [], m) (* could suppress unitArg *) - -//---------------------------------------------------------------------------- -// CompilationMappingAttribute, SourceConstructFlags -//---------------------------------------------------------------------------- - -let tnameCompilationSourceNameAttr = FSharpLib.Core + ".CompilationSourceNameAttribute" -let tnameCompilationArgumentCountsAttr = FSharpLib.Core + ".CompilationArgumentCountsAttribute" -let tnameCompilationMappingAttr = FSharpLib.Core + ".CompilationMappingAttribute" -let tnameSourceConstructFlags = FSharpLib.Core + ".SourceConstructFlags" - -let tref_CompilationArgumentCountsAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationArgumentCountsAttr) -let tref_CompilationMappingAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationMappingAttr) -let tref_CompilationSourceNameAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationSourceNameAttr) -let tref_SourceConstructFlags (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameSourceConstructFlags) - -let mkCompilationMappingAttrPrim (g: TcGlobals) k nums = - mkILCustomAttribute g.ilg (tref_CompilationMappingAttr g, - ((mkILNonGenericValueTy (tref_SourceConstructFlags g)) :: (nums |> List.map (fun _ -> g.ilg.typ_Int32))), - ((k :: nums) |> List.map (fun n -> ILAttribElem.Int32 n)), - []) - -let mkCompilationMappingAttr g kind = mkCompilationMappingAttrPrim g kind [] - -let mkCompilationMappingAttrWithSeqNum g kind seqNum = mkCompilationMappingAttrPrim g kind [seqNum] - -let mkCompilationMappingAttrWithVariantNumAndSeqNum g kind varNum seqNum = mkCompilationMappingAttrPrim g kind [varNum;seqNum] - -let mkCompilationArgumentCountsAttr (g: TcGlobals) nums = - mkILCustomAttribute g.ilg (tref_CompilationArgumentCountsAttr g, [ mkILArr1DTy g.ilg.typ_Int32 ], - [ILAttribElem.Array (g.ilg.typ_Int32, List.map (fun n -> ILAttribElem.Int32 n) nums)], - []) - -let mkCompilationSourceNameAttr (g: TcGlobals) n = - mkILCustomAttribute g.ilg (tref_CompilationSourceNameAttr g, [ g.ilg.typ_String ], - [ILAttribElem.String(Some n)], - []) - -let mkCompilationMappingAttrForQuotationResource (g: TcGlobals) (nm, tys: ILTypeRef list) = - mkILCustomAttribute g.ilg (tref_CompilationMappingAttr g, - [ g.ilg.typ_String; mkILArr1DTy g.ilg.typ_Type ], - [ ILAttribElem.String (Some nm); ILAttribElem.Array (g.ilg.typ_Type, [ for ty in tys -> ILAttribElem.TypeRef (Some ty) ]) ], - []) - -//---------------------------------------------------------------------------- -// Decode extensible typing attributes -//---------------------------------------------------------------------------- - -#if !NO_EXTENSIONTYPING - -let isTypeProviderAssemblyAttr (cattr: ILAttribute) = - cattr.Method.DeclaringType.BasicQualifiedName = typeof.FullName - -let TryDecodeTypeProviderAssemblyAttr ilg (cattr: ILAttribute) = - if isTypeProviderAssemblyAttr cattr then - let parms, _args = decodeILAttribData ilg cattr - match parms with // The first parameter to the attribute is the name of the assembly with the compiler extensions. - | (ILAttribElem.String (Some assemblyName)) :: _ -> Some assemblyName - | (ILAttribElem.String None) :: _ -> Some null - | [] -> Some null - | _ -> None - else - None - -#endif - -//---------------------------------------------------------------------------- -// FSharpInterfaceDataVersionAttribute -//---------------------------------------------------------------------------- - -let tname_SignatureDataVersionAttr = FSharpLib.Core + ".FSharpInterfaceDataVersionAttribute" - -let tnames_SignatureDataVersionAttr = splitILTypeName tname_SignatureDataVersionAttr - -let tref_SignatureDataVersionAttr () = mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), tname_SignatureDataVersionAttr) - -let mkSignatureDataVersionAttr (g: TcGlobals) (version: ILVersionInfo) = - mkILCustomAttribute g.ilg - (tref_SignatureDataVersionAttr(), - [g.ilg.typ_Int32;g.ilg.typ_Int32;g.ilg.typ_Int32], - [ILAttribElem.Int32 (int32 version.Major) - ILAttribElem.Int32 (int32 version.Minor) - ILAttribElem.Int32 (int32 version.Build)], []) - -let tname_AutoOpenAttr = FSharpLib.Core + ".AutoOpenAttribute" - -let IsSignatureDataVersionAttr cattr = isILAttribByName ([], tname_SignatureDataVersionAttr) cattr - -let TryFindAutoOpenAttr (ilg: IL.ILGlobals) cattr = - if isILAttribByName ([], tname_AutoOpenAttr) cattr then - match decodeILAttribData ilg cattr with - | [ILAttribElem.String s], _ -> s - | [], _ -> None - | _ -> - warning(Failure(FSComp.SR.tastUnexpectedDecodeOfAutoOpenAttribute())) - None - else - None - -let tname_InternalsVisibleToAttr = "System.Runtime.CompilerServices.InternalsVisibleToAttribute" - -let TryFindInternalsVisibleToAttr ilg cattr = - if isILAttribByName ([], tname_InternalsVisibleToAttr) cattr then - match decodeILAttribData ilg cattr with - | [ILAttribElem.String s], _ -> s - | [], _ -> None - | _ -> - warning(Failure(FSComp.SR.tastUnexpectedDecodeOfInternalsVisibleToAttribute())) - None - else - None - -let IsMatchingSignatureDataVersionAttr ilg (version: ILVersionInfo) cattr = - IsSignatureDataVersionAttr cattr && - match decodeILAttribData ilg cattr with - | [ILAttribElem.Int32 u1; ILAttribElem.Int32 u2;ILAttribElem.Int32 u3 ], _ -> - (version.Major = uint16 u1) && (version.Minor = uint16 u2) && (version.Build = uint16 u3) - | _ -> - warning(Failure(FSComp.SR.tastUnexpectedDecodeOfInterfaceDataVersionAttribute())) - false - -let mkCompilerGeneratedAttr (g: TcGlobals) n = - mkILCustomAttribute g.ilg (tref_CompilationMappingAttr g, [mkILNonGenericValueTy (tref_SourceConstructFlags g)], [ILAttribElem.Int32 n], []) - -//-------------------------------------------------------------------------- -// tupled lambda --> method/function with a given topValInfo specification. -// -// AdjustArityOfLambdaBody: "(vs, body)" represents a lambda "fun (vs) -> body". The -// aim is to produce a "static method" represented by a pair -// "(mvs, body)" where mvs has the List.length "arity". -//-------------------------------------------------------------------------- - -let untupledToRefTupled g vs = - let untupledTys = typesOfVals vs - let m = (List.head vs).Range - let tupledv, tuplede = mkCompGenLocal m "tupledArg" (mkRefTupledTy g untupledTys) - let untupling_es = List.mapi (fun i _ -> mkTupleFieldGet g (tupInfoRef, tuplede, untupledTys, i, m)) untupledTys - // These are non-sticky - at the caller,any sequence point for 'body' goes on 'body' _after_ the binding has been made - tupledv, mkInvisibleLets m vs untupling_es - -// The required tupled-arity (arity) can either be 1 -// or N, and likewise for the tuple-arity of the input lambda, i.e. either 1 or N -// where the N's will be identical. -let AdjustArityOfLambdaBody g arity (vs: Val list) body = - let nvs = vs.Length - if not (nvs = arity || nvs = 1 || arity = 1) then failwith ("lengths don't add up") - if arity = 0 then - vs, body - elif nvs = arity then - vs, body - elif nvs = 1 then - let v = vs.Head - let untupledTys = destRefTupleTy g v.Type - if (untupledTys.Length <> arity) then failwith "length untupledTys <> arity" - let dummyvs, dummyes = - untupledTys - |> List.mapi (fun i ty -> mkCompGenLocal v.Range (v.LogicalName + "_" + string i) ty) - |> List.unzip - // These are non-sticky - any sequence point for 'body' goes on 'body' _after_ the binding has been made - let body = mkInvisibleLet v.Range v (mkRefTupled g v.Range dummyes untupledTys) body - dummyvs, body - else - let tupledv, untupler = untupledToRefTupled g vs - [tupledv], untupler body - -let MultiLambdaToTupledLambda g vs body = - match vs with - | [] -> failwith "MultiLambdaToTupledLambda: expected some arguments" - | [v] -> v, body - | vs -> - let tupledv, untupler = untupledToRefTupled g vs - tupledv, untupler body - -let (|RefTuple|_|) expr = - match expr with - | Expr.Op (TOp.Tuple (TupInfo.Const false), _, args, _) -> Some args - | _ -> None - -let MultiLambdaToTupledLambdaIfNeeded g (vs, arg) body = - match vs, arg with - | [], _ -> failwith "MultiLambdaToTupledLambda: expected some arguments" - | [v], _ -> [(v, arg)], body - | vs, RefTuple args when args.Length = vs.Length -> List.zip vs args, body - | vs, _ -> - let tupledv, untupler = untupledToRefTupled g vs - [(tupledv, arg)], untupler body - -//-------------------------------------------------------------------------- -// Beta reduction via let-bindings. Reduce immediate apps. of lambdas to let bindings. -// Includes binding the immediate application of generic -// functions. Input type is the type of the function. Makes use of the invariant -// that any two expressions have distinct local variables (because we explicitly copy -// expressions). -//------------------------------------------------------------------------ - -let rec MakeApplicationAndBetaReduceAux g (f, fty, tyargsl: TType list list, argsl: Expr list, m) = - match f with - | Expr.Let (bind, body, mlet, _) -> - // Lift bindings out, i.e. (let x = e in f) y --> let x = e in f y - // This increases the scope of 'x', which I don't like as it mucks with debugging - // scopes of variables, but this is an important optimization, especially when the '|>' - // notation is used a lot. - mkLetBind mlet bind (MakeApplicationAndBetaReduceAux g (body, fty, tyargsl, argsl, m)) - | _ -> - match tyargsl with - | [] :: rest -> - MakeApplicationAndBetaReduceAux g (f, fty, rest, argsl, m) - - | tyargs :: rest -> - // Bind type parameters by immediate substitution - match f with - | Expr.TyLambda (_, tyvs, body, _, bodyty) when tyvs.Length = List.length tyargs -> - let tpenv = bindTypars tyvs tyargs emptyTyparInst - let body = remarkExpr m (instExpr g tpenv body) - let bodyty' = instType tpenv bodyty - MakeApplicationAndBetaReduceAux g (body, bodyty', rest, argsl, m) - - | _ -> - let f = mkAppsAux g f fty [tyargs] [] m - let fty = applyTyArgs g fty tyargs - MakeApplicationAndBetaReduceAux g (f, fty, rest, argsl, m) - | [] -> - match argsl with - | _ :: _ -> - // Bind term parameters by "let" explicit substitutions - // - // Only do this if there are enough lambdas for the number of arguments supplied. This is because - // all arguments get evaluated before application. - // - // VALID: - // (fun a b -> E[a, b]) t1 t2 ---> let a = t1 in let b = t2 in E[t1, t2] - // INVALID: - // (fun a -> E[a]) t1 t2 ---> let a = t1 in E[a] t2 UNLESS: E[a] has no effects OR t2 has no effects - - match tryStripLambdaN argsl.Length f with - | Some (argvsl, body) -> - assert (argvsl.Length = argsl.Length) - let pairs, body = List.mapFoldBack (MultiLambdaToTupledLambdaIfNeeded g) (List.zip argvsl argsl) body - let argvs2, args2 = List.unzip (List.concat pairs) - mkLetsBind m (mkCompGenBinds argvs2 args2) body - | _ -> - mkExprAppAux g f fty argsl m - - | [] -> - f - -let MakeApplicationAndBetaReduce g (f, fty, tyargsl, argl, m) = - MakeApplicationAndBetaReduceAux g (f, fty, tyargsl, argl, m) - -//--------------------------------------------------------------------------- -// Adjust for expected usage -// Convert a use of a value to saturate to the given arity. -//--------------------------------------------------------------------------- - -let MakeArgsForTopArgs _g m argtysl tpenv = - argtysl |> List.mapi (fun i argtys -> - argtys |> List.mapi (fun j (argty, argInfo: ArgReprInfo) -> - let ty = instType tpenv argty - let nm = - match argInfo.Name with - | None -> CompilerGeneratedName ("arg" + string i + string j) - | Some id -> id.idText - fst (mkCompGenLocal m nm ty))) - -let AdjustValForExpectedArity g m (vref: ValRef) flags topValInfo = - - let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m - let tps' = copyTypars tps - let tyargs' = List.map mkTyparTy tps' - let tpenv = bindTypars tps tyargs' emptyTyparInst - let rty' = instType tpenv rty - let vsl = MakeArgsForTopArgs g m argtysl tpenv - let call = MakeApplicationAndBetaReduce g (Expr.Val (vref, flags, m), vref.Type, [tyargs'], (List.map (mkRefTupledVars g m) vsl), m) - let tauexpr, tauty = - List.foldBack - (fun vs (e, ty) -> mkMultiLambda m vs (e, ty), (mkRefTupledVarsTy g vs --> ty)) - vsl - (call, rty') - // Build a type-lambda expression for the toplevel value if needed... - mkTypeLambda m tps' (tauexpr, tauty), tps' +-> tauty - -let IsSubsumptionExpr g expr = - match expr with - | Expr.Op (TOp.Coerce, [inputTy;actualTy], [_], _) -> - isFunTy g actualTy && isFunTy g inputTy - | _ -> - false - -let stripTupledFunTy g ty = - let argTys, retTy = stripFunTy g ty - let curriedArgTys = argTys |> List.map (tryDestRefTupleTy g) - curriedArgTys, retTy - -let (|ExprValWithPossibleTypeInst|_|) expr = - match expr with - | Expr.App (Expr.Val (vref, flags, m), _fty, tyargs, [], _) -> - Some (vref, flags, tyargs, m) - | Expr.Val (vref, flags, m) -> - Some (vref, flags, [], m) - | _ -> - None - -let mkCoerceIfNeeded g tgtTy srcTy expr = - if typeEquiv g tgtTy srcTy then - expr - else - mkCoerceExpr(expr, tgtTy, expr.Range, srcTy) - -let mkCompGenLetIn m nm ty e f = - let v, ve = mkCompGenLocal m nm ty - mkCompGenLet m v e (f (v, ve)) - -/// Take a node representing a coercion from one function type to another, e.g. -/// A -> A * A -> int -/// to -/// B -> B * A -> int -/// and return an expression of the correct type that doesn't use a coercion type. For example -/// return -/// (fun b1 b2 -> E (b1 :> A) (b2 :> A)) -/// -/// - Use good names for the closure arguments if available -/// - Create lambda variables if needed, or use the supplied arguments if available. -/// -/// Return the new expression and any unused suffix of supplied arguments -/// -/// If E is a value with TopInfo then use the arity to help create a better closure. -/// In particular we can create a closure like this: -/// (fun b1 b2 -> E (b1 :> A) (b2 :> A)) -/// rather than -/// (fun b1 -> let clo = E (b1 :> A) in (fun b2 -> clo (b2 :> A))) -/// The latter closures are needed to carefully preserve side effect order -/// -/// Note that the results of this translation are visible to quotations - -let AdjustPossibleSubsumptionExpr g (expr: Expr) (suppliedArgs: Expr list) : (Expr* Expr list) option = - - match expr with - | Expr.Op (TOp.Coerce, [inputTy;actualTy], [exprWithActualTy], m) when - isFunTy g actualTy && isFunTy g inputTy -> - - if typeEquiv g actualTy inputTy then - Some(exprWithActualTy, suppliedArgs) - else - - let curriedActualArgTys, retTy = stripTupledFunTy g actualTy - - let curriedInputTys, _ = stripFunTy g inputTy - - assert (curriedActualArgTys.Length = curriedInputTys.Length) - - let argTys = (curriedInputTys, curriedActualArgTys) ||> List.mapi2 (fun i x y -> (i, x, y)) - - - // Use the nice names for a function of known arity and name. Note that 'nice' here also - // carries a semantic meaning. For a function with top-info, - // let f (x: A) (y: A) (z: A) = ... - // we know there are no side effects on the application of 'f' to 1, 2 args. This greatly simplifies - // the closure built for - // f b1 b2 - // and indeed for - // f b1 b2 b3 - // we don't build any closure at all, and just return - // f (b1 :> A) (b2 :> A) (b3 :> A) - - let curriedNiceNames = - match stripExpr exprWithActualTy with - | ExprValWithPossibleTypeInst(vref, _, _, _) when vref.ValReprInfo.IsSome -> - - let _, argtysl, _, _ = GetTopValTypeInFSharpForm g vref.ValReprInfo.Value vref.Type expr.Range - argtysl |> List.mapi (fun i argtys -> - argtys |> List.mapi (fun j (_, argInfo) -> - match argInfo.Name with - | None -> CompilerGeneratedName ("arg" + string i + string j) - | Some id -> id.idText)) - | _ -> - [] - - let nCurriedNiceNames = curriedNiceNames.Length - assert (curriedActualArgTys.Length >= nCurriedNiceNames) - - let argTysWithNiceNames, argTysWithoutNiceNames = - List.splitAt nCurriedNiceNames argTys - - /// Only consume 'suppliedArgs' up to at most the number of nice arguments - let nSuppliedArgs = min suppliedArgs.Length nCurriedNiceNames - let suppliedArgs, droppedSuppliedArgs = - List.splitAt nSuppliedArgs suppliedArgs - - /// The relevant range for any expressions and applications includes the arguments - let appm = (m, suppliedArgs) ||> List.fold (fun m e -> unionRanges m (e.Range)) - - // See if we have 'enough' suppliedArgs. If not, we have to build some lambdas, and, - // we have to 'let' bind all arguments that we consume, e.g. - // Seq.take (effect;4) : int list -> int list - // is a classic case. Here we generate - // let tmp = (effect;4) in - // (fun v -> Seq.take tmp (v :> seq<_>)) - let buildingLambdas = nSuppliedArgs <> nCurriedNiceNames - - /// Given a tuple of argument variables that has a tuple type that satisfies the input argument types, - /// coerce it to a tuple that satisfies the matching coerced argument type(s). - let CoerceDetupled (argTys: TType list) (detupledArgs: Expr list) (actualTys: TType list) = - assert (actualTys.Length = argTys.Length) - assert (actualTys.Length = detupledArgs.Length) - // Inject the coercions into the user-supplied explicit tuple - let argm = List.reduce unionRanges (detupledArgs |> List.map (fun e -> e.Range)) - mkRefTupled g argm (List.map3 (mkCoerceIfNeeded g) actualTys argTys detupledArgs) actualTys - - /// Given an argument variable of tuple type that has been evaluated and stored in the - /// given variable, where the tuple type that satisfies the input argument types, - /// coerce it to a tuple that satisfies the matching coerced argument type(s). - let CoerceBoundTuple tupleVar argTys (actualTys: TType list) = - assert (actualTys.Length > 1) - - mkRefTupled g appm - ((actualTys, argTys) ||> List.mapi2 (fun i actualTy dummyTy -> - let argExprElement = mkTupleFieldGet g (tupInfoRef, tupleVar, argTys, i, appm) - mkCoerceIfNeeded g actualTy dummyTy argExprElement)) - actualTys - - /// Given an argument that has a tuple type that satisfies the input argument types, - /// coerce it to a tuple that satisfies the matching coerced argument type. Try to detuple the argument if possible. - let CoerceTupled niceNames (argExpr: Expr) (actualTys: TType list) = - let argExprTy = (tyOfExpr g argExpr) - - let argTys = - match actualTys with - | [_] -> - [tyOfExpr g argExpr] - | _ -> - tryDestRefTupleTy g argExprTy - - assert (actualTys.Length = argTys.Length) - let nm = match niceNames with [nm] -> nm | _ -> "arg" - if buildingLambdas then - // Evaluate the user-supplied tuple-valued argument expression, inject the coercions and build an explicit tuple - // Assign the argument to make sure it is only run once - // f ~~>: B -> int - // f ~~> : (B * B) -> int - // - // for - // let f a = 1 - // let f (a, a) = 1 - let v, ve = mkCompGenLocal appm nm argExprTy - let binderBuilder = (fun tm -> mkCompGenLet appm v argExpr tm) - let expr = - match actualTys, argTys with - | [actualTy], [argTy] -> mkCoerceIfNeeded g actualTy argTy ve - | _ -> CoerceBoundTuple ve argTys actualTys - - binderBuilder, expr - else - if typeEquiv g (mkRefTupledTy g actualTys) argExprTy then - (fun tm -> tm), argExpr - else - - let detupledArgs, argTys = - match actualTys with - | [_actualType] -> - [argExpr], [tyOfExpr g argExpr] - | _ -> - tryDestRefTupleExpr argExpr, tryDestRefTupleTy g argExprTy - - // OK, the tuples match, or there is no de-tupling, - // f x - // f (x, y) - // - // for - // let f (x, y) = 1 - // and we're not building lambdas, just coerce the arguments in place - if detupledArgs.Length = actualTys.Length then - (fun tm -> tm), CoerceDetupled argTys detupledArgs actualTys - else - // In this case there is a tuple mismatch. - // f p - // - // - // for - // let f (x, y) = 1 - // Assign the argument to make sure it is only run once - let v, ve = mkCompGenLocal appm nm argExprTy - let binderBuilder = (fun tm -> mkCompGenLet appm v argExpr tm) - let expr = CoerceBoundTuple ve argTys actualTys - binderBuilder, expr - - - // This variable is really a dummy to make the code below more regular. - // In the i = N - 1 cases we skip the introduction of the 'let' for - // this variable. - let resVar, resVarAsExpr = mkCompGenLocal appm "result" retTy - let N = argTys.Length - let (cloVar, exprForOtherArgs, _) = - List.foldBack - (fun (i, inpArgTy, actualArgTys) (cloVar: Val, res, resTy) -> - - let inpArgTys = - match actualArgTys with - | [_] -> [inpArgTy] - | _ -> destRefTupleTy g inpArgTy - - assert (inpArgTys.Length = actualArgTys.Length) - - let inpsAsVars, inpsAsExprs = inpArgTys |> List.mapi (fun j ty -> mkCompGenLocal appm ("arg" + string i + string j) ty) |> List.unzip - let inpsAsActualArg = CoerceDetupled inpArgTys inpsAsExprs actualArgTys - let inpCloVarType = (mkFunTy (mkRefTupledTy g actualArgTys) cloVar.Type) - let newResTy = mkFunTy inpArgTy resTy - let inpCloVar, inpCloVarAsExpr = mkCompGenLocal appm ("clo" + string i) inpCloVarType - let newRes = - // For the final arg we can skip introducing the dummy variable - if i = N - 1 then - mkMultiLambda appm inpsAsVars - (mkApps g ((inpCloVarAsExpr, inpCloVarType), [], [inpsAsActualArg], appm), resTy) - else - mkMultiLambda appm inpsAsVars - (mkCompGenLet appm cloVar - (mkApps g ((inpCloVarAsExpr, inpCloVarType), [], [inpsAsActualArg], appm)) - res, - resTy) - - inpCloVar, newRes, newResTy) - argTysWithoutNiceNames - (resVar, resVarAsExpr, retTy) - - let exprForAllArgs = - if isNil argTysWithNiceNames then - mkCompGenLet appm cloVar exprWithActualTy exprForOtherArgs - else - // Mark the up as Some/None - let suppliedArgs = List.map Some suppliedArgs @ List.replicate (nCurriedNiceNames - nSuppliedArgs) None - - assert (suppliedArgs.Length = nCurriedNiceNames) - - let lambdaBuilders, binderBuilders, inpsAsArgs = - - (argTysWithNiceNames, curriedNiceNames, suppliedArgs) |||> List.map3 (fun (_, inpArgTy, actualArgTys) niceNames suppliedArg -> - - let inpArgTys = - match actualArgTys with - | [_] -> [inpArgTy] - | _ -> destRefTupleTy g inpArgTy - - - /// Note: there might not be enough nice names, and they might not match in arity - let niceNames = - match niceNames with - | nms when nms.Length = inpArgTys.Length -> nms - | [nm] -> inpArgTys |> List.mapi (fun i _ -> (nm + string i)) - | nms -> nms - match suppliedArg with - | Some arg -> - let binderBuilder, inpsAsActualArg = CoerceTupled niceNames arg actualArgTys - let lambdaBuilder = (fun tm -> tm) - lambdaBuilder, binderBuilder, inpsAsActualArg - | None -> - let inpsAsVars, inpsAsExprs = (niceNames, inpArgTys) ||> List.map2 (fun nm ty -> mkCompGenLocal appm nm ty) |> List.unzip - let inpsAsActualArg = CoerceDetupled inpArgTys inpsAsExprs actualArgTys - let lambdaBuilder = (fun tm -> mkMultiLambda appm inpsAsVars (tm, tyOfExpr g tm)) - let binderBuilder = (fun tm -> tm) - lambdaBuilder, binderBuilder, inpsAsActualArg) - |> List.unzip3 - - // If no trailing args then we can skip introducing the dummy variable - // This corresponds to - // let f (x: A) = 1 - // - // f ~~> type B -> int - // - // giving - // (fun b -> f (b :> A)) - // rather than - // (fun b -> let clo = f (b :> A) in clo) - let exprApp = - if isNil argTysWithoutNiceNames then - mkApps g ((exprWithActualTy, actualTy), [], inpsAsArgs, appm) - else - mkCompGenLet appm - cloVar (mkApps g ((exprWithActualTy, actualTy), [], inpsAsArgs, appm)) - exprForOtherArgs - - List.foldBack (fun f acc -> f acc) binderBuilders - (List.foldBack (fun f acc -> f acc) lambdaBuilders exprApp) - - Some(exprForAllArgs, droppedSuppliedArgs) - | _ -> - None - -/// Find and make all subsumption eliminations -let NormalizeAndAdjustPossibleSubsumptionExprs g inputExpr = - let expr, args = - // AdjustPossibleSubsumptionExpr can take into account an application - match stripExpr inputExpr with - | Expr.App (f, _fty, [], args, _) -> - f, args - - | _ -> - inputExpr, [] - - match AdjustPossibleSubsumptionExpr g expr args with - | None -> - inputExpr - | Some (expr', []) -> - expr' - | Some (expr', args') -> - //printfn "adjusted...." - Expr.App (expr', tyOfExpr g expr', [], args', inputExpr.Range) - - -//--------------------------------------------------------------------------- -// LinearizeTopMatch - when only one non-failing target, make linear. The full -// complexity of this is only used for spectacularly rare bindings such as -// type ('a, 'b) either = This of 'a | That of 'b -// let this_f1 = This (fun x -> x) -// let This fA | That fA = this_f1 -// -// Here a polymorphic top level binding "fA" is _computed_ by a pattern match!!! -// The TAST coming out of type checking must, however, define fA as a type function, -// since it is marked with an arity that indicates it's r.h.s. is a type function] -// without side effects and so can be compiled as a generic method (for example). - -// polymorphic things bound in complex matches at top level require eta expansion of the -// type function to ensure the r.h.s. of the binding is indeed a type function -let etaExpandTypeLambda g m tps (tm, ty) = - if isNil tps then tm else mkTypeLambda m tps (mkApps g ((tm, ty), [(List.map mkTyparTy tps)], [], m), ty) - -let AdjustValToTopVal (tmp: Val) parent valData = - tmp.SetValReprInfo (Some valData) - tmp.SetDeclaringEntity parent - tmp.SetIsMemberOrModuleBinding() - -/// For match with only one non-failing target T0, the other targets, T1... failing (say, raise exception). -/// tree, T0(v0, .., vN) => rhs ; T1() => fail ; ... -/// Convert it to bind T0's variables, then continue with T0's rhs: -/// let tmp = switch tree, TO(fv0, ..., fvN) => Tup (fv0, ..., fvN) ; T1() => fail; ... -/// let v1 = #1 tmp in ... -/// and vN = #N tmp -/// rhs -/// Motivation: -/// - For top-level let bindings with possibly failing matches, -/// this makes clear that subsequent bindings (if reached) are top-level ones. -let LinearizeTopMatchAux g parent (spBind, m, tree, targets, m2, ty) = - let targetsL = Array.toList targets - (* items* package up 0, 1, more items *) - let itemsProj tys i x = - match tys with - | [] -> failwith "itemsProj: no items?" - | [_] -> x (* no projection needed *) - | tys -> Expr.Op (TOp.TupleFieldGet (tupInfoRef, i), tys, [x], m) - let isThrowingTarget = function TTarget(_, x, _) -> isThrow x - if 1 + List.count isThrowingTarget targetsL = targetsL.Length then - (* Have failing targets and ONE successful one, so linearize *) - let (TTarget (vs, rhs, spTarget)) = Option.get (List.tryFind (isThrowingTarget >> not) targetsL) - (* note - old code here used copy value to generate locals - this was not right *) - let fvs = vs |> List.map (fun v -> fst(mkLocal v.Range v.LogicalName v.Type)) (* fresh *) - let vtys = vs |> List.map (fun v -> v.Type) - let tmpTy = mkRefTupledVarsTy g vs - let tmp, tmpe = mkCompGenLocal m "matchResultHolder" tmpTy - - AdjustValToTopVal tmp parent ValReprInfo.emptyValData - - let newTg = TTarget (fvs, mkRefTupledVars g m fvs, spTarget) - let fixup (TTarget (tvs, tx, spTarget)) = - match destThrow tx with - | Some (m, _, e) -> - let tx = mkThrow m tmpTy e - TTarget(tvs, tx, spTarget) (* Throwing targets, recast it's "return type" *) - | None -> newTg (* Non-throwing target, replaced [new/old] *) - - let targets = Array.map fixup targets - let binds = - vs |> List.mapi (fun i v -> - let ty = v.Type - let rhs = etaExpandTypeLambda g m v.Typars (itemsProj vtys i tmpe, ty) - // update the arity of the value - v.SetValReprInfo (Some (InferArityOfExpr g AllowTypeDirectedDetupling.Yes ty [] [] rhs)) - // This binding is deliberately non-sticky - any sequence point for 'rhs' goes on 'rhs' _after_ the binding has been evaluated - mkInvisibleBind v rhs) in (* vi = proj tmp *) - mkCompGenLet m - tmp (primMkMatch (spBind, m, tree, targets, m2, tmpTy)) (* note, probably retyped match, but note, result still has same type *) - (mkLetsFromBindings m binds rhs) - else - (* no change *) - primMkMatch (spBind, m, tree, targets, m2, ty) - -let LinearizeTopMatch g parent = function - | Expr.Match (spBind, m, tree, targets, m2, ty) -> LinearizeTopMatchAux g parent (spBind, m, tree, targets, m2, ty) - | x -> x - - -//--------------------------------------------------------------------------- -// XmlDoc signatures -//--------------------------------------------------------------------------- - - -let commaEncs strs = String.concat "," strs -let angleEnc str = "{" + str + "}" -let ticksAndArgCountTextOfTyconRef (tcref: TyconRef) = - // Generic type names are (name + "`" + digits) where name does not contain "`". - let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName] - textOfPath path - -let typarEnc _g (gtpsType, gtpsMethod) typar = - match List.tryFindIndex (typarEq typar) gtpsType with - | Some idx -> "`" + string idx // single-tick-index for typar from type - | None -> - match List.tryFindIndex (typarEq typar) gtpsMethod with - | Some idx -> - "``" + string idx // double-tick-index for typar from method - | None -> - warning(InternalError("Typar not found during XmlDoc generation", typar.Range)) - "``0" - -let rec typeEnc g (gtpsType, gtpsMethod) ty = - if verbose then dprintf "--> typeEnc" - let stripped = stripTyEqnsAndMeasureEqns g ty - match stripped with - | TType_forall _ -> - "Microsoft.FSharp.Core.FSharpTypeFunc" - - | _ when isArrayTy g ty -> - let tcref, tinst = destAppTy g ty - let arraySuffix = - match rankOfArrayTyconRef g tcref with - | 1 -> "[]" - | 2 -> "[0:, 0:]" - | 3 -> "[0:, 0:, 0:]" - | 4 -> "[0:, 0:, 0:, 0:]" - | _ -> failwith "impossible: rankOfArrayTyconRef: unsupported array rank" - typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix - - | TType_ucase (UCRef(tcref, _), tinst) - | TType_app (tcref, tinst) -> - if tyconRefEq g g.byref_tcr tcref then - typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + "@" - elif tyconRefEq g tcref g.nativeptr_tcr then - typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + "*" - else - let tyName = - let ty = stripTyEqnsAndMeasureEqns g ty - match ty with - | TType_app (tcref, _tinst) -> - // Generic type names are (name + "`" + digits) where name does not contain "`". - // In XML doc, when used in type instances, these do not use the ticks. - let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName] - textOfPath (List.map DemangleGenericTypeName path) - | _ -> - assert false - failwith "impossible" - tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst - - | TType_anon (anonInfo, tinst) -> - sprintf "%s%s" anonInfo.ILTypeRef.FullName (tyargsEnc g (gtpsType, gtpsMethod) tinst) - - | TType_tuple (tupInfo, tys) -> - if evalTupInfoIsStruct tupInfo then - sprintf "System.ValueTuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) - else - sprintf "System.Tuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) - - | TType_fun (f, x) -> - "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [f;x] - - | TType_var typar -> - typarEnc g (gtpsType, gtpsMethod) typar - - | TType_measure _ -> "?" - -and tyargsEnc g (gtpsType, gtpsMethod) args = - match args with - | [] -> "" - | [a] when (match (stripTyEqns g a) with TType_measure _ -> true | _ -> false) -> "" // float should appear as just "float" in the generated .XML xmldoc file - | _ -> angleEnc (commaEncs (List.map (typeEnc g (gtpsType, gtpsMethod)) args)) - -let XmlDocArgsEnc g (gtpsType, gtpsMethod) argTs = - if isNil argTs then "" - else "(" + String.concat "," (List.map (typeEnc g (gtpsType, gtpsMethod)) argTs) + ")" - -let buildAccessPath (cp: CompilationPath option) = - match cp with - | Some cp -> - let ap = cp.AccessPath |> List.map fst |> List.toArray - System.String.Join(".", ap) - | None -> "Extension Type" -let prependPath path name = if path = "" then name else path + "." + name - -let XmlDocSigOfVal g path (v: Val) = - let parentTypars, methTypars, argInfos, prefix, path, name = - - // CLEANUP: this is one of several code paths that treat module values and members - // separately when really it would be cleaner to make sure GetTopValTypeInFSharpForm, GetMemberTypeInFSharpForm etc. - // were lined up so code paths like this could be uniform - - match v.MemberInfo with - | Some membInfo when not v.IsExtensionMember -> - (* Methods, Properties etc. *) - let tps, argInfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags (Option.get v.ValReprInfo) v.Type v.Range - let prefix, name = - match membInfo.MemberFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor -> "M:", "#ctor" - | MemberKind.Member -> "M:", v.CompiledName g.CompilerGlobalState - | MemberKind.PropertyGetSet - | MemberKind.PropertySet - | MemberKind.PropertyGet -> "P:", v.PropertyName - let path = if v.HasDeclaringEntity then prependPath path v.TopValDeclaringEntity.CompiledName else path - let parentTypars, methTypars = - match PartitionValTypars g v with - | Some(_, memberParentTypars, memberMethodTypars, _, _) -> memberParentTypars, memberMethodTypars - | None -> [], tps - parentTypars, methTypars, argInfos, prefix, path, name - | _ -> - // Regular F# values and extension members - let w = arityOfVal v - let tps, argInfos, _, _ = GetTopValTypeInCompiledForm g w v.Type v.Range - let name = v.CompiledName g.CompilerGlobalState - let prefix = - if w.NumCurriedArgs = 0 && isNil tps then "P:" - else "M:" - [], tps, argInfos, prefix, path, name - let argTs = argInfos |> List.concat |> List.map fst - let args = XmlDocArgsEnc g (parentTypars, methTypars) argTs - let arity = List.length methTypars in (* C# XML doc adds `` to *generic* member names *) - let genArity = if arity=0 then "" else sprintf "``%d" arity - prefix + prependPath path name + genArity + args - -let BuildXmlDocSig prefix paths = prefix + List.fold prependPath "" paths - -let XmlDocSigOfUnionCase = BuildXmlDocSig "T:" // Would like to use "U:", but ParseMemberSignature only accepts C# signatures - -let XmlDocSigOfField = BuildXmlDocSig "F:" - -let XmlDocSigOfProperty = BuildXmlDocSig "P:" - -let XmlDocSigOfTycon = BuildXmlDocSig "T:" - -let XmlDocSigOfSubModul = BuildXmlDocSig "T:" - -let XmlDocSigOfEntity (eref: EntityRef) = - XmlDocSigOfTycon [(buildAccessPath eref.CompilationPathOpt); eref.Deref.CompiledName] - -//-------------------------------------------------------------------------- -// Some unions have null as representations -//-------------------------------------------------------------------------- - - -let enum_CompilationRepresentationAttribute_Static = 0b0000000000000001 -let enum_CompilationRepresentationAttribute_Instance = 0b0000000000000010 -let enum_CompilationRepresentationAttribute_StaticInstanceMask = 0b0000000000000011 -let enum_CompilationRepresentationAttribute_ModuleSuffix = 0b0000000000000100 -let enum_CompilationRepresentationAttribute_PermitNull = 0b0000000000001000 - -let HasUseNullAsTrueValueAttribute g attribs = - match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attribs with - | Some flags -> ((flags &&& enum_CompilationRepresentationAttribute_PermitNull) <> 0) - | _ -> false - -let TyconHasUseNullAsTrueValueAttribute g (tycon: Tycon) = HasUseNullAsTrueValueAttribute g tycon.Attribs - -// WARNING: this must match optimizeAlternativeToNull in ilx/cu_erase.fs -let CanHaveUseNullAsTrueValueAttribute (_g: TcGlobals) (tycon: Tycon) = - (tycon.IsUnionTycon && - let ucs = tycon.UnionCasesArray - (ucs.Length = 0 || - (ucs |> Array.existsOne (fun uc -> uc.IsNullary) && - ucs |> Array.exists (fun uc -> not uc.IsNullary)))) - -// WARNING: this must match optimizeAlternativeToNull in ilx/cu_erase.fs -let IsUnionTypeWithNullAsTrueValue (g: TcGlobals) (tycon: Tycon) = - (tycon.IsUnionTycon && - let ucs = tycon.UnionCasesArray - (ucs.Length = 0 || - (TyconHasUseNullAsTrueValueAttribute g tycon && - ucs |> Array.existsOne (fun uc -> uc.IsNullary) && - ucs |> Array.exists (fun uc -> not uc.IsNullary)))) - -let TyconCompilesInstanceMembersAsStatic g tycon = IsUnionTypeWithNullAsTrueValue g tycon -let TcrefCompilesInstanceMembersAsStatic g (tcref: TyconRef) = TyconCompilesInstanceMembersAsStatic g tcref.Deref - -let TypeNullNever g ty = - let underlyingTy = stripTyEqnsAndMeasureEqns g ty - (isStructTy g underlyingTy) || - (isByrefTy g underlyingTy) - - - -/// Indicates if the type admits the use of 'null' as a value -let TypeNullIsExtraValue g m ty = - if isILReferenceTy g ty || isDelegateTy g ty then - // Putting AllowNullLiteralAttribute(false) on an IL or provided type means 'null' can't be used with that type - not (match tryDestAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some false | _ -> false) - elif TypeNullNever g ty then - false - else - // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type - match tryDestAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some true | _ -> false - -let TypeNullIsTrueValue g ty = - (match tryDestAppTy g ty with - | ValueSome tcref -> IsUnionTypeWithNullAsTrueValue g tcref.Deref - | _ -> false) || (isUnitTy g ty) - -let TypeNullNotLiked g m ty = - not (TypeNullIsExtraValue g m ty) - && not (TypeNullIsTrueValue g ty) - && not (TypeNullNever g ty) - -let TypeSatisfiesNullConstraint g m ty = - TypeNullIsExtraValue g m ty - -let rec TypeHasDefaultValue g m ty = - let ty = stripTyEqnsAndMeasureEqns g ty - TypeSatisfiesNullConstraint g m ty - || (isStructTy g ty && - // Is it an F# struct type? - (if isFSharpStructTy g ty then - let tcref, tinst = destAppTy g ty - let flds = - // Note this includes fields implied by the use of the implicit class construction syntax - tcref.AllInstanceFieldsAsList - // We can ignore fields with the DefaultValue(false) attribute - |> List.filter (fun fld -> not (TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute fld.FieldAttribs = Some false)) - - flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g m) - elif isStructTupleTy g ty then - destStructTupleTy g ty |> List.forall (TypeHasDefaultValue g m) - elif isStructAnonRecdTy g ty then - match tryDestAnonRecdTy g ty with - | ValueNone -> true - | ValueSome (_, ptys) -> ptys |> List.forall (TypeHasDefaultValue g m) - else - // All struct types defined in other .NET languages have a DefaultValue regardless of their - // instantiation - true)) - - -/// Determines types that are potentially known to satisfy the 'comparable' constraint and returns -/// a set of residual types that must also satisfy the constraint -let (|SpecialComparableHeadType|_|) g ty = - if isAnyTupleTy g ty then - let _tupInfo, elemTys = destAnyTupleTy g ty - Some elemTys - elif isAnonRecdTy g ty then - match tryDestAnonRecdTy g ty with - | ValueNone -> Some [] - | ValueSome (_anonInfo, elemTys) -> Some elemTys - else - match tryAppTy g ty with - | ValueSome (tcref, tinst) -> - if isArrayTyconRef g tcref || - tyconRefEq g tcref g.system_UIntPtr_tcref || - tyconRefEq g tcref g.system_IntPtr_tcref then - Some tinst - else - None - | _ -> - None - -let (|SpecialEquatableHeadType|_|) g ty = (|SpecialComparableHeadType|_|) g ty -let (|SpecialNotEquatableHeadType|_|) g ty = - if isFunTy g ty then Some() else None - - - -// Can we use the fast helper for the 'LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric'? -let canUseTypeTestFast g ty = - not (isTyparTy g ty) && - not (TypeNullIsTrueValue g ty) && - not (TypeNullNever g ty) - -// Can we use the fast helper for the 'LanguagePrimitives.IntrinsicFunctions.UnboxGeneric'? -let canUseUnboxFast g m ty = - not (isTyparTy g ty) && - not (TypeNullNotLiked g m ty) - - -//-------------------------------------------------------------------------- -// Nullness tests and pokes -//-------------------------------------------------------------------------- - -(* match inp with :? ty as v -> e2[v] | _ -> e3 *) -let mkIsInstConditional g m tgty vinpe v e2 e3 = - // No sequence point for this compiler generated expression form - - if canUseTypeTestFast g tgty then - - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m) - let tg2 = mbuilder.AddResultTarget(e2, SuppressSequencePointAtTarget) - let tg3 = mbuilder.AddResultTarget(e3, SuppressSequencePointAtTarget) - let dtree = TDSwitch(exprForVal m v, [TCase(DecisionTreeTest.IsNull, tg3)], Some tg2, m) - let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) - mkCompGenLet m v (mkIsInst tgty vinpe m) expr - - else - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m) - let tg2 = TDSuccess([mkCallUnbox g m tgty vinpe], mbuilder.AddTarget(TTarget([v], e2, SuppressSequencePointAtTarget))) - let tg3 = mbuilder.AddResultTarget(e3, SuppressSequencePointAtTarget) - let dtree = TDSwitch(vinpe, [TCase(DecisionTreeTest.IsInst(tyOfExpr g vinpe, tgty), tg2)], Some tg3, m) - let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) - expr - - - -// Null tests are generated by -// 1. The compilation of array patterns in the pattern match compiler -// 2. The compilation of string patterns in the pattern match compiler -let mkNullTest g m e1 e2 e3 = - let mbuilder = new MatchBuilder(NoSequencePointAtInvisibleBinding, m) - let tg2 = mbuilder.AddResultTarget(e2, SuppressSequencePointAtTarget) - let tg3 = mbuilder.AddResultTarget(e3, SuppressSequencePointAtTarget) - let dtree = TDSwitch(e1, [TCase(DecisionTreeTest.IsNull, tg3)], Some tg2, m) - let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) - expr -let mkNonNullTest (g: TcGlobals) m e = mkAsmExpr ([ IL.AI_ldnull ; IL.AI_cgt_un ], [], [e], [g.bool_ty], m) -let mkNonNullCond g m ty e1 e2 e3 = mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m ty (mkNonNullTest g m e1) e2 e3 -let mkIfThen (g: TcGlobals) m e1 e2 = mkCond NoSequencePointAtStickyBinding SuppressSequencePointAtTarget m g.unit_ty e1 e2 (mkUnit g m) - - -let ModuleNameIsMangled g attrs = - match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attrs with - | Some flags -> ((flags &&& enum_CompilationRepresentationAttribute_ModuleSuffix) <> 0) - | _ -> false - -let CompileAsEvent g attrs = HasFSharpAttribute g g.attrib_CLIEventAttribute attrs - - -let MemberIsCompiledAsInstance g parent isExtensionMember (membInfo: ValMemberInfo) attrs = - // All extension members are compiled as static members - if isExtensionMember then false - // Anything implementing a dispatch slot is compiled as an instance member - elif membInfo.MemberFlags.IsOverrideOrExplicitImpl then true - elif not (isNil membInfo.ImplementedSlotSigs) then true - else - // Otherwise check attributes to see if there is an explicit instance or explicit static flag - let explicitInstance, explicitStatic = - match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attrs with - | Some flags -> - ((flags &&& enum_CompilationRepresentationAttribute_Instance) <> 0), - ((flags &&& enum_CompilationRepresentationAttribute_Static) <> 0) - | _ -> false, false - explicitInstance || - (membInfo.MemberFlags.IsInstance && - not explicitStatic && - not (TcrefCompilesInstanceMembersAsStatic g parent)) - - -let isSealedTy g ty = - let ty = stripTyEqnsAndMeasureEqns g ty - not (isRefTy g ty) || - isUnitTy g ty || - isArrayTy g ty || - - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata st -> st.IsSealed -#endif - | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsSealed - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - if (isFSharpInterfaceTy g ty || isFSharpClassTy g ty) then - let tcref = tcrefOfAppTy g ty - TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some true - else - // All other F# types, array, byref, tuple types are sealed - true - -let isComInteropTy g ty = - let tcref = tcrefOfAppTy g ty - match g.attrib_ComImportAttribute with - | None -> false - | Some attr -> TryFindFSharpBoolAttribute g attr tcref.Attribs = Some true - -let ValSpecIsCompiledAsInstance g (v: Val) = - match v.MemberInfo with - | Some membInfo -> - // Note it doesn't matter if we pass 'v.TopValDeclaringEntity' or 'v.MemberApparentEntity' here. - // These only differ if the value is an extension member, and in that case MemberIsCompiledAsInstance always returns - // false anyway - MemberIsCompiledAsInstance g v.MemberApparentEntity v.IsExtensionMember membInfo v.Attribs - | _ -> false - -let ValRefIsCompiledAsInstanceMember g (vref: ValRef) = ValSpecIsCompiledAsInstance g vref.Deref - - -//--------------------------------------------------------------------------- -// Crack information about an F# object model call -//--------------------------------------------------------------------------- - -let GetMemberCallInfo g (vref: ValRef, vFlags) = - match vref.MemberInfo with - | Some membInfo when not vref.IsExtensionMember -> - let numEnclTypeArgs = vref.MemberApparentEntity.TyparsNoRange.Length - let virtualCall = - (membInfo.MemberFlags.IsOverrideOrExplicitImpl || - membInfo.MemberFlags.IsDispatchSlot) && - not membInfo.MemberFlags.IsFinal && - (match vFlags with VSlotDirectCall -> false | _ -> true) - let isNewObj = (membInfo.MemberFlags.MemberKind = MemberKind.Constructor) && (match vFlags with NormalValUse -> true | _ -> false) - let isSuperInit = (membInfo.MemberFlags.MemberKind = MemberKind.Constructor) && (match vFlags with CtorValUsedAsSuperInit -> true | _ -> false) - let isSelfInit = (membInfo.MemberFlags.MemberKind = MemberKind.Constructor) && (match vFlags with CtorValUsedAsSelfInit -> true | _ -> false) - let isCompiledAsInstance = ValRefIsCompiledAsInstanceMember g vref - let takesInstanceArg = isCompiledAsInstance && not isNewObj - let isPropGet = (membInfo.MemberFlags.MemberKind = MemberKind.PropertyGet) && (membInfo.MemberFlags.IsInstance = isCompiledAsInstance) - let isPropSet = (membInfo.MemberFlags.MemberKind = MemberKind.PropertySet) && (membInfo.MemberFlags.IsInstance = isCompiledAsInstance) - numEnclTypeArgs, virtualCall, isNewObj, isSuperInit, isSelfInit, takesInstanceArg, isPropGet, isPropSet - | _ -> - 0, false, false, false, false, false, false, false - -//--------------------------------------------------------------------------- -// Active pattern name helpers -//--------------------------------------------------------------------------- - - -let TryGetActivePatternInfo (vref: ValRef) = - // First is an optimization to prevent calls to CoreDisplayName, which calls DemangleOperatorName - let logicalName = vref.LogicalName - if logicalName.Length = 0 || logicalName.[0] <> '|' then - None - else - ActivePatternInfoOfValName vref.CoreDisplayName vref.Range - -type ActivePatternElemRef with - member x.Name = - let (APElemRef(_, vref, n)) = x - match TryGetActivePatternInfo vref with - | None -> error(InternalError("not an active pattern name", vref.Range)) - | Some apinfo -> - let nms = apinfo.ActiveTags - if n < 0 || n >= List.length nms then error(InternalError("name_of_apref: index out of range for active pattern reference", vref.Range)) - List.item n nms - -let mkChoiceTyconRef (g: TcGlobals) m n = - match n with - | 0 | 1 -> error(InternalError("mkChoiceTyconRef", m)) - | 2 -> g.choice2_tcr - | 3 -> g.choice3_tcr - | 4 -> g.choice4_tcr - | 5 -> g.choice5_tcr - | 6 -> g.choice6_tcr - | 7 -> g.choice7_tcr - | _ -> error(Error(FSComp.SR.tastActivePatternsLimitedToSeven(), m)) - -let mkChoiceTy (g: TcGlobals) m tinst = - match List.length tinst with - | 0 -> g.unit_ty - | 1 -> List.head tinst - | length -> mkAppTy (mkChoiceTyconRef g m length) tinst - -let mkChoiceCaseRef g m n i = - mkUnionCaseRef (mkChoiceTyconRef g m n) ("Choice"+string (i+1)+"Of"+string n) - -type PrettyNaming.ActivePatternInfo with - member x.Names = x.ActiveTags - - member apinfo.ResultType g m rtys = - let choicety = mkChoiceTy g m rtys - if apinfo.IsTotal then choicety else mkOptionTy g choicety - - member apinfo.OverallType g m dty rtys = - mkFunTy dty (apinfo.ResultType g m rtys) - -//--------------------------------------------------------------------------- -// Active pattern validation -//--------------------------------------------------------------------------- - -// check if an active pattern takes type parameters only bound by the return types, -// not by their argument types. -let doesActivePatternHaveFreeTypars g (v: ValRef) = - let vty = v.TauType - let vtps = v.Typars |> Zset.ofList typarOrder - if not (isFunTy g v.TauType) then - errorR(Error(FSComp.SR.activePatternIdentIsNotFunctionTyped(v.LogicalName), v.Range)) - let argtys, resty = stripFunTy g vty - let argtps, restps= (freeInTypes CollectTypars argtys).FreeTypars, (freeInType CollectTypars resty).FreeTypars - // Error if an active pattern is generic in type variables that only occur in the result Choice<_, ...>. - // Note: The test restricts to v.Typars since typars from the closure are considered fixed. - not (Zset.isEmpty (Zset.inter (Zset.diff restps argtps) vtps)) - -//--------------------------------------------------------------------------- -// RewriteExpr: rewrite bottom up with interceptors -//--------------------------------------------------------------------------- - -[] -type ExprRewritingEnv = - { PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option - PostTransform: Expr -> Expr option - PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option - IsUnderQuotations: bool } - -let rec rewriteBind env bind = - match env.PreInterceptBinding with - | Some f -> - match f (RewriteExpr env) bind with - | Some res -> res - | None -> rewriteBindStructure env bind - | None -> rewriteBindStructure env bind - -and rewriteBindStructure env (TBind(v, e, letSeqPtOpt)) = - TBind(v, RewriteExpr env e, letSeqPtOpt) - -and rewriteBinds env binds = List.map (rewriteBind env) binds - -and RewriteExpr env expr = - match expr with - | LinearOpExpr _ - | LinearMatchExpr _ - | Expr.Let _ - | Expr.Sequential _ -> - rewriteLinearExpr env expr (fun e -> e) - | _ -> - let expr = - match preRewriteExpr env expr with - | Some expr -> expr - | None -> rewriteExprStructure env expr - postRewriteExpr env expr - -and preRewriteExpr env expr = - match env.PreIntercept with - | Some f -> f (RewriteExpr env) expr - | None -> None - -and postRewriteExpr env expr = - match env.PostTransform expr with - | None -> expr - | Some expr -> expr - -and rewriteExprStructure env expr = - match expr with - | Expr.Const _ - | Expr.Val _ -> expr - - | Expr.App (f0, f0ty, tyargs, args, m) -> - let f0' = RewriteExpr env f0 - let args' = rewriteExprs env args - if f0 === f0' && args === args' then expr - else Expr.App (f0', f0ty, tyargs, args', m) - - | Expr.Quote (ast, {contents=Some(typeDefs, argTypes, argExprs, data)}, isFromQueryExpression, m, ty) -> - Expr.Quote ((if env.IsUnderQuotations then RewriteExpr env ast else ast), {contents=Some(typeDefs, argTypes, rewriteExprs env argExprs, data)}, isFromQueryExpression, m, ty) - - | Expr.Quote (ast, {contents=None}, isFromQueryExpression, m, ty) -> - Expr.Quote ((if env.IsUnderQuotations then RewriteExpr env ast else ast), {contents=None}, isFromQueryExpression, m, ty) - - | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, m) -> - mkObjExpr(ty, basev, RewriteExpr env basecall, List.map (rewriteObjExprOverride env) overrides, - List.map (rewriteObjExprInterfaceImpl env) iimpls, m) - | Expr.Link eref -> - RewriteExpr env !eref - - | Expr.Op (c, tyargs, args, m) -> - let args' = rewriteExprs env args - if args === args' then expr - else Expr.Op (c, tyargs, args', m) - - | Expr.Lambda (_lambdaId, ctorThisValOpt, baseValOpt, argvs, body, m, rty) -> - let body = RewriteExpr env body - rebuildLambda m ctorThisValOpt baseValOpt argvs (body, rty) - - | Expr.TyLambda (_lambdaId, argtyvs, body, m, rty) -> - let body = RewriteExpr env body - mkTypeLambda m argtyvs (body, rty) - - | Expr.Match (spBind, exprm, dtree, targets, m, ty) -> - let dtree' = rewriteDecisionTree env dtree - let targets' = rewriteTargets env targets - mkAndSimplifyMatch spBind exprm m ty dtree' targets' - - | Expr.LetRec (binds, e, m, _) -> - let binds = rewriteBinds env binds - let e' = RewriteExpr env e - Expr.LetRec (binds, e', m, NewFreeVarsCache()) - - | Expr.Let _ -> failwith "unreachable - linear let" - - | Expr.Sequential _ -> failwith "unreachable - linear seq" - - | Expr.StaticOptimization (constraints, e2, e3, m) -> - let e2' = RewriteExpr env e2 - let e3' = RewriteExpr env e3 - Expr.StaticOptimization (constraints, e2', e3', m) - - | Expr.TyChoose (a, b, m) -> - Expr.TyChoose (a, RewriteExpr env b, m) - -and rewriteLinearExpr env expr contf = - // schedule a rewrite on the way back up by adding to the continuation - let contf = contf << postRewriteExpr env - match preRewriteExpr env expr with - | Some expr -> contf expr - | None -> - match expr with - | Expr.Let (bind, bodyExpr, m, _) -> - let bind = rewriteBind env bind - // tailcall - rewriteLinearExpr env bodyExpr (contf << (fun bodyExpr' -> - mkLetBind m bind bodyExpr')) - - | Expr.Sequential (expr1, expr2, dir, spSeq, m) -> - let expr1' = RewriteExpr env expr1 - // tailcall - rewriteLinearExpr env expr2 (contf << (fun expr2' -> - if expr1 === expr1' && expr2 === expr2' then expr - else Expr.Sequential (expr1', expr2', dir, spSeq, m))) - - | LinearOpExpr (op, tyargs, argsFront, argLast, m) -> - let argsFront' = rewriteExprs env argsFront - // tailcall - rewriteLinearExpr env argLast (contf << (fun argLast' -> - if argsFront === argsFront' && argLast === argLast' then expr - else rebuildLinearOpExpr (op, tyargs, argsFront', argLast', m))) - - | LinearMatchExpr (spBind, exprm, dtree, tg1, expr2, sp2, m2, ty) -> - let dtree = rewriteDecisionTree env dtree - let tg1' = rewriteTarget env tg1 - // tailcall - rewriteLinearExpr env expr2 (contf << (fun expr2' -> - rebuildLinearMatchExpr (spBind, exprm, dtree, tg1', expr2', sp2, m2, ty))) - | _ -> - // no longer linear, no tailcall - contf (RewriteExpr env expr) - -and rewriteExprs env exprs = List.mapq (RewriteExpr env) exprs - -and rewriteFlatExprs env exprs = List.mapq (RewriteExpr env) exprs - -and rewriteDecisionTree env x = - match x with - | TDSuccess (es, n) -> - let es' = rewriteFlatExprs env es - if LanguagePrimitives.PhysicalEquality es es' then x - else TDSuccess(es', n) - - | TDSwitch (e, cases, dflt, m) -> - let e' = RewriteExpr env e - let cases' = List.map (fun (TCase(discrim, e)) -> TCase(discrim, rewriteDecisionTree env e)) cases - let dflt' = Option.map (rewriteDecisionTree env) dflt - TDSwitch (e', cases', dflt', m) - - | TDBind (bind, body) -> - let bind' = rewriteBind env bind - let body = rewriteDecisionTree env body - TDBind (bind', body) - -and rewriteTarget env (TTarget(vs, e, spTarget)) = TTarget(vs, RewriteExpr env e, spTarget) - -and rewriteTargets env targets = List.map (rewriteTarget env) (Array.toList targets) - -and rewriteObjExprOverride env (TObjExprMethod(slotsig, attribs, tps, vs, e, m)) = - TObjExprMethod(slotsig, attribs, tps, vs, RewriteExpr env e, m) - -and rewriteObjExprInterfaceImpl env (ty, overrides) = - (ty, List.map (rewriteObjExprOverride env) overrides) - -and rewriteModuleOrNamespaceExpr env x = - match x with - | ModuleOrNamespaceExprWithSig(mty, def, m) -> ModuleOrNamespaceExprWithSig(mty, rewriteModuleOrNamespaceDef env def, m) - -and rewriteModuleOrNamespaceDefs env x = List.map (rewriteModuleOrNamespaceDef env) x - -and rewriteModuleOrNamespaceDef env x = - match x with - | TMDefRec(isRec, tycons, mbinds, m) -> TMDefRec(isRec, tycons, rewriteModuleOrNamespaceBindings env mbinds, m) - | TMDefLet(bind, m) -> TMDefLet(rewriteBind env bind, m) - | TMDefDo(e, m) -> TMDefDo(RewriteExpr env e, m) - | TMDefs defs -> TMDefs(rewriteModuleOrNamespaceDefs env defs) - | TMAbstract mexpr -> TMAbstract(rewriteModuleOrNamespaceExpr env mexpr) - -and rewriteModuleOrNamespaceBinding env x = - match x with - | ModuleOrNamespaceBinding.Binding bind -> ModuleOrNamespaceBinding.Binding (rewriteBind env bind) - | ModuleOrNamespaceBinding.Module(nm, rhs) -> ModuleOrNamespaceBinding.Module(nm, rewriteModuleOrNamespaceDef env rhs) - -and rewriteModuleOrNamespaceBindings env mbinds = List.map (rewriteModuleOrNamespaceBinding env) mbinds - -and RewriteImplFile env mv = mapTImplFile (rewriteModuleOrNamespaceExpr env) mv - - - -//-------------------------------------------------------------------------- -// Build a Remap that converts all "local" references to "public" things -// accessed via non local references. -//-------------------------------------------------------------------------- - -let MakeExportRemapping viewedCcu (mspec: ModuleOrNamespace) = - - let accEntityRemap (entity: Entity) acc = - match tryRescopeEntity viewedCcu entity with - | ValueSome eref -> - addTyconRefRemap (mkLocalTyconRef entity) eref acc - | _ -> - if entity.IsNamespace then - acc - else - error(InternalError("Unexpected entity without a pubpath when remapping assembly data", entity.Range)) - - let accValRemap (vspec: Val) acc = - // The acc contains the entity remappings - match tryRescopeVal viewedCcu acc vspec with - | ValueSome vref -> - {acc with valRemap=acc.valRemap.Add vspec vref } - | _ -> - error(InternalError("Unexpected value without a pubpath when remapping assembly data", vspec.Range)) - - let mty = mspec.ModuleOrNamespaceType - let entities = allEntitiesOfModuleOrNamespaceTy mty - let vs = allValsOfModuleOrNamespaceTy mty - // Remap the entities first so we can correctly remap the types in the signatures of the ValLinkageFullKey's in the value references - let acc = List.foldBack accEntityRemap entities Remap.Empty - let allRemap = List.foldBack accValRemap vs acc - allRemap - -//-------------------------------------------------------------------------- -// Apply a "local to nonlocal" renaming to a module type. This can't use -// remap_mspec since the remapping we want isn't to newly created nodes -// but rather to remap to the nonlocal references. This is deliberately -// "breaking" the binding structure implicit in the module type, which is -// the whole point - one things are rewritten to use non local references then -// the elements can be copied at will, e.g. when inlining during optimization. -//------------------------------------------------------------------------ - - -let rec remapEntityDataToNonLocal g tmenv (d: Entity) = - let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv (d.entity_typars.Force(d.entity_range)) - let typarsR = LazyWithContext.NotLazy tps' - let attribsR = d.entity_attribs |> remapAttribs g tmenvinner - let tyconReprR = d.entity_tycon_repr |> remapTyconRepr g tmenvinner - let tyconAbbrevR = d.TypeAbbrev |> Option.map (remapType tmenvinner) - let tyconTcaugR = d.entity_tycon_tcaug |> remapTyconAug tmenvinner - let modulContentsR = - MaybeLazy.Strict (d.entity_modul_contents.Value - |> mapImmediateValsAndTycons (remapTyconToNonLocal g tmenv) (remapValToNonLocal g tmenv)) - let exnInfoR = d.ExceptionInfo |> remapTyconExnInfo g tmenvinner - { d with - entity_typars = typarsR - entity_attribs = attribsR - entity_tycon_repr = tyconReprR - entity_tycon_tcaug = tyconTcaugR - entity_modul_contents = modulContentsR - entity_opt_data = - match d.entity_opt_data with - | Some dd -> - Some { dd with entity_tycon_abbrev = tyconAbbrevR; entity_exn_info = exnInfoR } - | _ -> None } - -and remapTyconToNonLocal g tmenv x = - x |> NewModifiedTycon (remapEntityDataToNonLocal g tmenv) - -and remapValToNonLocal g tmenv inp = - // creates a new stamp - inp |> NewModifiedVal (remapValData g tmenv) - -let ApplyExportRemappingToEntity g tmenv x = remapTyconToNonLocal g tmenv x - -(* Which constraints actually get compiled to .NET constraints? *) -let isCompiledConstraint cx = - match cx with - | TyparConstraint.SupportsNull _ // this implies the 'class' constraint - | TyparConstraint.IsReferenceType _ // this is the 'class' constraint - | TyparConstraint.IsNonNullableStruct _ - | TyparConstraint.IsReferenceType _ - | TyparConstraint.RequiresDefaultConstructor _ - | TyparConstraint.CoercesTo _ -> true - | _ -> false - -// Is a value a first-class polymorphic value with .NET constraints? -// Used to turn off TLR and method splitting -let IsGenericValWithGenericConstraints g (v: Val) = - isForallTy g v.Type && - v.Type |> destForallTy g |> fst |> List.exists (fun tp -> List.exists isCompiledConstraint tp.Constraints) - -// Does a type support a given interface? -type Entity with - member tycon.HasInterface g ty = - tycon.TypeContents.tcaug_interfaces |> List.exists (fun (x, _, _) -> typeEquiv g ty x) - - // Does a type have an override matching the given name and argument types? - // Used to detect the presence of 'Equals' and 'GetHashCode' in type checking - member tycon.HasOverride g nm argtys = - tycon.TypeContents.tcaug_adhoc - |> NameMultiMap.find nm - |> List.exists (fun vref -> - match vref.MemberInfo with - | None -> false - | Some membInfo -> - let argInfos = ArgInfosOfMember g vref - argInfos.Length = 1 && - List.lengthsEqAndForall2 (typeEquiv g) (List.map fst (List.head argInfos)) argtys && - membInfo.MemberFlags.IsOverrideOrExplicitImpl) - - member tycon.HasMember g nm argtys = - tycon.TypeContents.tcaug_adhoc - |> NameMultiMap.find nm - |> List.exists (fun vref -> - match vref.MemberInfo with - | None -> false - | _ -> let argInfos = ArgInfosOfMember g vref - argInfos.Length = 1 && - List.lengthsEqAndForall2 (typeEquiv g) (List.map fst (List.head argInfos)) argtys) - - -type EntityRef with - member tcref.HasInterface g ty = tcref.Deref.HasInterface g ty - member tcref.HasOverride g nm argtys = tcref.Deref.HasOverride g nm argtys - member tcref.HasMember g nm argtys = tcref.Deref.HasMember g nm argtys - -let mkFastForLoop g (spLet, m, idv: Val, start, dir, finish, body) = - let dir = if dir then FSharpForLoopUp else FSharpForLoopDown - mkFor g (spLet, idv, start, dir, finish, body, m) - - -/// Accessing a binding of the form "let x = 1" or "let x = e" for any "e" satisfying the predicate -/// below does not cause an initialization trigger, i.e. does not get compiled as a static field. -let IsSimpleSyntacticConstantExpr g inputExpr = - let rec checkExpr (vrefs: Set) x = - match stripExpr x with - | Expr.Op (TOp.Coerce, _, [arg], _) - -> checkExpr vrefs arg - | UnopExpr g (vref, arg) - when (valRefEq g vref g.unchecked_unary_minus_vref || - valRefEq g vref g.unchecked_unary_plus_vref || - valRefEq g vref g.unchecked_unary_not_vref || - valRefEq g vref g.bitwise_unary_not_vref || - valRefEq g vref g.enum_vref) - -> checkExpr vrefs arg - // compare, =, <>, +, -, <, >, <=, >=, <<<, >>>, &&& - | BinopExpr g (vref, arg1, arg2) - when (valRefEq g vref g.equals_operator_vref || - valRefEq g vref g.compare_operator_vref || - valRefEq g vref g.unchecked_addition_vref || - valRefEq g vref g.less_than_operator_vref || - valRefEq g vref g.less_than_or_equals_operator_vref || - valRefEq g vref g.greater_than_operator_vref || - valRefEq g vref g.greater_than_or_equals_operator_vref || - valRefEq g vref g.not_equals_operator_vref || - valRefEq g vref g.unchecked_addition_vref || - valRefEq g vref g.unchecked_multiply_vref || - valRefEq g vref g.unchecked_subtraction_vref || - // Note: division and modulus can raise exceptions, so are not included - valRefEq g vref g.bitwise_shift_left_vref || - valRefEq g vref g.bitwise_shift_right_vref || - valRefEq g vref g.bitwise_xor_vref || - valRefEq g vref g.bitwise_and_vref || - valRefEq g vref g.bitwise_or_vref) && - (not (typeEquiv g (tyOfExpr g arg1) g.string_ty) && not (typeEquiv g (tyOfExpr g arg1) g.decimal_ty) ) - -> checkExpr vrefs arg1 && checkExpr vrefs arg2 - | Expr.Val (vref, _, _) -> vref.Deref.IsCompiledAsStaticPropertyWithoutField || vrefs.Contains vref.Stamp - | Expr.Match (_, _, dtree, targets, _, _) -> checkDecisionTree vrefs dtree && targets |> Array.forall (checkDecisionTreeTarget vrefs) - | Expr.Let (b, e, _, _) -> checkExpr vrefs b.Expr && checkExpr (vrefs.Add b.Var.Stamp) e - // Detect standard constants - | Expr.TyChoose (_, b, _) -> checkExpr vrefs b - | Expr.Const _ - | Expr.Op (TOp.UnionCase _, _, [], _) // Nullary union cases - | UncheckedDefaultOfExpr g _ - | SizeOfExpr g _ - | TypeOfExpr g _ -> true - | NameOfExpr g _ when g.langVersion.SupportsFeature LanguageFeature.NameOf -> true - // All others are not simple constant expressions - | _ -> false - - and checkDecisionTree vrefs x = - match x with - | TDSuccess (es, _n) -> es |> List.forall (checkExpr vrefs) - | TDSwitch (e, cases, dflt, _m) -> checkExpr vrefs e && cases |> List.forall (checkDecisionTreeCase vrefs) && dflt |> Option.forall (checkDecisionTree vrefs) - | TDBind (bind, body) -> checkExpr vrefs bind.Expr && checkDecisionTree (vrefs.Add bind.Var.Stamp) body - and checkDecisionTreeCase vrefs (TCase(discrim, dtree)) = - (match discrim with DecisionTreeTest.Const _c -> true | _ -> false) && checkDecisionTree vrefs dtree - and checkDecisionTreeTarget vrefs (TTarget(vs, e, _)) = - let vrefs = ((vrefs, vs) ||> List.fold (fun s v -> s.Add v.Stamp)) - checkExpr vrefs e - - checkExpr Set.empty inputExpr - -let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64) (arg1: Expr) (arg2: Expr) = - // At compile-time we check arithmetic - let m = unionRanges arg1.Range arg2.Range - try - match arg1, arg2 with - | Expr.Const (Const.Int32 x1, _, ty), Expr.Const (Const.Int32 x2, _, _) -> Expr.Const (Const.Int32 (opInt32 x1 x2), m, ty) - | Expr.Const (Const.SByte x1, _, ty), Expr.Const (Const.SByte x2, _, _) -> Expr.Const (Const.SByte (opInt8 x1 x2), m, ty) - | Expr.Const (Const.Int16 x1, _, ty), Expr.Const (Const.Int16 x2, _, _) -> Expr.Const (Const.Int16 (opInt16 x1 x2), m, ty) - | Expr.Const (Const.Int64 x1, _, ty), Expr.Const (Const.Int64 x2, _, _) -> Expr.Const (Const.Int64 (opInt64 x1 x2), m, ty) - | Expr.Const (Const.Byte x1, _, ty), Expr.Const (Const.Byte x2, _, _) -> Expr.Const (Const.Byte (opUInt8 x1 x2), m, ty) - | Expr.Const (Const.UInt16 x1, _, ty), Expr.Const (Const.UInt16 x2, _, _) -> Expr.Const (Const.UInt16 (opUInt16 x1 x2), m, ty) - | Expr.Const (Const.UInt32 x1, _, ty), Expr.Const (Const.UInt32 x2, _, _) -> Expr.Const (Const.UInt32 (opUInt32 x1 x2), m, ty) - | Expr.Const (Const.UInt64 x1, _, ty), Expr.Const (Const.UInt64 x2, _, _) -> Expr.Const (Const.UInt64 (opUInt64 x1 x2), m, ty) - | _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m)) - with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m)) - -// See also PostTypeCheckSemanticChecks.CheckAttribArgExpr, which must match this precisely -let rec EvalAttribArgExpr g x = - match x with - - // Detect standard constants - | Expr.Const (c, m, _) -> - match c with - | Const.Bool _ - | Const.Int32 _ - | Const.SByte _ - | Const.Int16 _ - | Const.Int32 _ - | Const.Int64 _ - | Const.Byte _ - | Const.UInt16 _ - | Const.UInt32 _ - | Const.UInt64 _ - | Const.Double _ - | Const.Single _ - | Const.Char _ - | Const.Zero _ - | Const.String _ -> - x - | Const.Decimal _ | Const.IntPtr _ | Const.UIntPtr _ | Const.Unit _ -> - errorR (Error ( FSComp.SR.tastNotAConstantExpression(), m)) - x - - | TypeOfExpr g _ -> x - | TypeDefOfExpr g _ -> x - | Expr.Op (TOp.Coerce, _, [arg], _) -> - EvalAttribArgExpr g arg - | EnumExpr g arg1 -> - EvalAttribArgExpr g arg1 - // Detect bitwise or of attribute flags - | AttribBitwiseOrExpr g (arg1, arg2) -> - EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.unchecked_addition_vref (arg1, arg2) -> - // At compile-time we check arithmetic - let v1, v2 = EvalAttribArgExpr g arg1, EvalAttribArgExpr g arg2 - match v1, v2 with - | Expr.Const (Const.String x1, m, ty), Expr.Const (Const.String x2, _, _) -> Expr.Const (Const.String (x1 + x2), m, ty) - | _ -> -#if ALLOW_ARITHMETIC_OPS_IN_LITERAL_EXPRESSIONS_AND_ATTRIBUTE_ARGS - EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) g v1 v2 -#else - errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) - x -#endif -#if ALLOW_ARITHMETIC_OPS_IN_LITERAL_EXPRESSIONS_AND_ATTRIBUTE_ARGS - | SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) -> - EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) g (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) -> - EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) g (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) -#endif - | _ -> - errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) - x - - -and EvaledAttribExprEquality g e1 e2 = - match e1, e2 with - | Expr.Const (c1, _, _), Expr.Const (c2, _, _) -> c1 = c2 - | TypeOfExpr g ty1, TypeOfExpr g ty2 -> typeEquiv g ty1 ty2 - | TypeDefOfExpr g ty1, TypeDefOfExpr g ty2 -> typeEquiv g ty1 ty2 - | _ -> false - -let (|ConstToILFieldInit|_|) c = - match c with - | Const.SByte n -> Some (ILFieldInit.Int8 n) - | Const.Int16 n -> Some (ILFieldInit.Int16 n) - | Const.Int32 n -> Some (ILFieldInit.Int32 n) - | Const.Int64 n -> Some (ILFieldInit.Int64 n) - | Const.Byte n -> Some (ILFieldInit.UInt8 n) - | Const.UInt16 n -> Some (ILFieldInit.UInt16 n) - | Const.UInt32 n -> Some (ILFieldInit.UInt32 n) - | Const.UInt64 n -> Some (ILFieldInit.UInt64 n) - | Const.Bool n -> Some (ILFieldInit.Bool n) - | Const.Char n -> Some (ILFieldInit.Char (uint16 n)) - | Const.Single n -> Some (ILFieldInit.Single n) - | Const.Double n -> Some (ILFieldInit.Double n) - | Const.String s -> Some (ILFieldInit.String s) - | Const.Zero -> Some (ILFieldInit.Null) - | _ -> None - -let EvalLiteralExprOrAttribArg g x = - match x with - | Expr.Op (TOp.Coerce, _, [Expr.Op (TOp.Array, [elemTy], args, m)], _) - | Expr.Op (TOp.Array, [elemTy], args, m) -> - let args = args |> List.map (EvalAttribArgExpr g) - Expr.Op (TOp.Array, [elemTy], args, m) - | _ -> - EvalAttribArgExpr g x - -// Take into account the fact that some "instance" members are compiled as static -// members when using CompilationRepresentation.Static, or any non-virtual instance members -// in a type that supports "null" as a true value. This is all members -// where ValRefIsCompiledAsInstanceMember is false but membInfo.MemberFlags.IsInstance -// is true. -// -// This is the right abstraction for viewing member types, but the implementation -// below is a little ugly. -let GetTypeOfIntrinsicMemberInCompiledForm g (vref: ValRef) = - assert (not vref.IsExtensionMember) - let membInfo, topValInfo = checkMemberValRef vref - let tps, argInfos, rty, retInfo = GetTypeOfMemberInMemberForm g vref - let argInfos = - // Check if the thing is really an instance member compiled as a static member - // If so, the object argument counts as a normal argument in the compiled form - if membInfo.MemberFlags.IsInstance && not (ValRefIsCompiledAsInstanceMember g vref) then - let _, origArgInfos, _, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type vref.Range - match origArgInfos with - | [] -> - errorR(InternalError("value does not have a valid member type", vref.Range)) - argInfos - | h :: _ -> h :: argInfos - else argInfos - tps, argInfos, rty, retInfo - - -//-------------------------------------------------------------------------- -// Tuple compilation (expressions) -//------------------------------------------------------------------------ - - -let rec mkCompiledTuple g isStruct (argtys, args, m) = - let n = List.length argtys - if n <= 0 then failwith "mkCompiledTuple" - elif n < maxTuple then (mkCompiledTupleTyconRef g isStruct n, argtys, args, m) - else - let argtysA, argtysB = List.splitAfter goodTupleFields argtys - let argsA, argsB = List.splitAfter goodTupleFields args - let ty8, v8 = - match argtysB, argsB with - | [ty8], [arg8] -> - match ty8 with - // if it's already been nested or ended, pass it through - | TType_app(tn, _) when (isCompiledTupleTyconRef g tn) -> - ty8, arg8 - | _ -> - let ty8enc = TType_app((if isStruct then g.struct_tuple1_tcr else g.ref_tuple1_tcr), [ty8]) - let v8enc = Expr.Op (TOp.Tuple (mkTupInfo isStruct), [ty8], [arg8], m) - ty8enc, v8enc - | _ -> - let a, b, c, d = mkCompiledTuple g isStruct (argtysB, argsB, m) - let ty8plus = TType_app(a, b) - let v8plus = Expr.Op (TOp.Tuple (mkTupInfo isStruct), b, c, d) - ty8plus, v8plus - let argtysAB = argtysA @ [ty8] - (mkCompiledTupleTyconRef g isStruct (List.length argtysAB), argtysAB, argsA @ [v8], m) - -let mkILMethodSpecForTupleItem (_g: TcGlobals) (ty: ILType) n = - mkILNonGenericInstanceMethSpecInTy(ty, (if n < goodTupleFields then "get_Item"+(n+1).ToString() else "get_Rest"), [], mkILTyvarTy (uint16 n)) - -let mkILFieldSpecForTupleItem (ty: ILType) n = - mkILFieldSpecInTy (ty, (if n < goodTupleFields then "Item"+(n+1).ToString() else "Rest"), mkILTyvarTy (uint16 n)) - -let mkGetTupleItemN g m n (ty: ILType) isStruct te retty = - if isStruct then - mkAsmExpr ([mkNormalLdfld (mkILFieldSpecForTupleItem ty n) ], [], [te], [retty], m) - else - mkAsmExpr ([IL.mkNormalCall(mkILMethodSpecForTupleItem g ty n)], [], [te], [retty], m) -/// Match an Int32 constant expression -let (|Int32Expr|_|) expr = - match expr with - | Expr.Const (Const.Int32 n, _, _) -> Some n - | _ -> None - -/// Match a try-finally expression -let (|TryFinally|_|) expr = - match expr with - | Expr.Op (TOp.TryFinally _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], _) -> Some(e1, e2) - | _ -> None - -// detect ONLY the while loops that result from compiling 'for ... in ... do ...' -let (|WhileLoopForCompiledForEachExpr|_|) expr = - match expr with - | Expr.Op (TOp.While (_, WhileLoopForCompiledForEachExprMarker), _, [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], m) -> Some(e1, e2, m) - | _ -> None - -let (|Let|_|) expr = - match expr with - | Expr.Let (TBind(v, e1, sp), e2, _, _) -> Some(v, e1, sp, e2) - | _ -> None - -let (|RangeInt32Step|_|) g expr = - match expr with - // detect 'n .. m' - | Expr.App (Expr.Val (vf, _, _), _, [tyarg], [startExpr;finishExpr], _) - when valRefEq g vf g.range_op_vref && typeEquiv g tyarg g.int_ty -> Some(startExpr, 1, finishExpr) - - // detect (RangeInt32 startExpr N finishExpr), the inlined/compiled form of 'n .. m' and 'n .. N .. m' - | Expr.App (Expr.Val (vf, _, _), _, [], [startExpr; Int32Expr n; finishExpr], _) - when valRefEq g vf g.range_int32_op_vref -> Some(startExpr, n, finishExpr) - - | _ -> None - -let (|GetEnumeratorCall|_|) expr = - match expr with - | Expr.Op (TOp.ILCall ( _, _, _, _, _, _, _, iLMethodRef, _, _, _), _, [Expr.Val (vref, _, _) | Expr.Op (_, _, [Expr.Val (vref, ValUseFlag.NormalValUse, _)], _) ], _) -> - if iLMethodRef.Name = "GetEnumerator" then Some vref - else None - | _ -> None - -let (|CompiledForEachExpr|_|) g expr = - match expr with - | Let (enumerableVar, enumerableExpr, _, - Let (enumeratorVar, GetEnumeratorCall enumerableVar2, enumeratorBind, - TryFinally (WhileLoopForCompiledForEachExpr (_, Let (elemVar, _, _, bodyExpr), _), _))) - // Apply correctness conditions to ensure this really is a compiled for-each expression. - when valRefEq g (mkLocalValRef enumerableVar) enumerableVar2 && - enumerableVar.IsCompilerGenerated && - enumeratorVar.IsCompilerGenerated && - (let fvs = (freeInExpr CollectLocals bodyExpr) - not (Zset.contains enumerableVar fvs.FreeLocals) && - not (Zset.contains enumeratorVar fvs.FreeLocals)) -> - - // Extract useful ranges - let mEnumExpr = enumerableExpr.Range - let mBody = bodyExpr.Range - let mWholeExpr = expr.Range - - let spForLoop, mForLoop = match enumeratorBind with SequencePointAtBinding spStart -> SequencePointAtForLoop spStart, spStart | _ -> NoSequencePointAtForLoop, mEnumExpr - let spWhileLoop = match enumeratorBind with SequencePointAtBinding spStart -> SequencePointAtWhileLoop spStart| _ -> NoSequencePointAtWhileLoop - let enumerableTy = tyOfExpr g enumerableExpr - - Some (enumerableTy, enumerableExpr, elemVar, bodyExpr, (mEnumExpr, mBody, spForLoop, mForLoop, spWhileLoop, mWholeExpr)) - | _ -> None - - -let (|CompiledInt32RangeForEachExpr|_|) g expr = - match expr with - | CompiledForEachExpr g (_, RangeInt32Step g (startExpr, step, finishExpr), elemVar, bodyExpr, ranges) -> - Some (startExpr, step, finishExpr, elemVar, bodyExpr, ranges) - | _ -> None - | _ -> None - - -type OptimizeForExpressionOptions = OptimizeIntRangesOnly | OptimizeAllForExpressions - -let DetectAndOptimizeForExpression g option expr = - match option, expr with - | _, CompiledInt32RangeForEachExpr g (startExpr, (1 | -1 as step), finishExpr, elemVar, bodyExpr, ranges) -> - - let (_mEnumExpr, _mBody, spForLoop, _mForLoop, _spWhileLoop, mWholeExpr) = ranges - mkFastForLoop g (spForLoop, mWholeExpr, elemVar, startExpr, (step = 1), finishExpr, bodyExpr) - - | OptimizeAllForExpressions, CompiledForEachExpr g (enumerableTy, enumerableExpr, elemVar, bodyExpr, ranges) -> - - let (mEnumExpr, mBody, spForLoop, mForLoop, spWhileLoop, mWholeExpr) = ranges - - if isStringTy g enumerableTy then - // type is string, optimize for expression as: - // let $str = enumerable - // for $idx in 0..(str.Length - 1) do - // let elem = str.[idx] - // body elem - - let strVar, strExpr = mkCompGenLocal mEnumExpr "str" enumerableTy - let idxVar, idxExpr = mkCompGenLocal elemVar.Range "idx" g.int32_ty - - let lengthExpr = mkGetStringLength g mForLoop strExpr - let charExpr = mkGetStringChar g mForLoop strExpr idxExpr - - let startExpr = mkZero g mForLoop - let finishExpr = mkDecr g mForLoop lengthExpr - // for compat reasons, loop item over string is sometimes object, not char - let loopItemExpr = mkCoerceIfNeeded g elemVar.Type g.char_ty charExpr - let bodyExpr = mkCompGenLet mForLoop elemVar loopItemExpr bodyExpr - let forExpr = mkFastForLoop g (spForLoop, mWholeExpr, idxVar, startExpr, true, finishExpr, bodyExpr) - let expr = mkCompGenLet mEnumExpr strVar enumerableExpr forExpr - - expr - - elif isListTy g enumerableTy then - // type is list, optimize for expression as: - // let mutable $currentVar = listExpr - // let mutable $nextVar = $tailOrNull - // while $guardExpr do - // let i = $headExpr - // bodyExpr () - // $current <- $next - // $next <- $tailOrNull - - let IndexHead = 0 - let IndexTail = 1 - - let currentVar, currentExpr = mkMutableCompGenLocal mEnumExpr "current" enumerableTy - let nextVar, nextExpr = mkMutableCompGenLocal mEnumExpr "next" enumerableTy - let elemTy = destListTy g enumerableTy - - let guardExpr = mkNonNullTest g mForLoop nextExpr - let headOrDefaultExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [elemTy], IndexHead, mForLoop) - let tailOrNullExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [elemTy], IndexTail, mForLoop) - let bodyExpr = - mkCompGenLet mForLoop elemVar headOrDefaultExpr - (mkCompGenSequential mForLoop - bodyExpr - (mkCompGenSequential mForLoop - (mkValSet mForLoop (mkLocalValRef currentVar) nextExpr) - (mkValSet mForLoop (mkLocalValRef nextVar) tailOrNullExpr))) - - let expr = - // let mutable current = enumerableExpr - let spBind = (match spForLoop with SequencePointAtForLoop spStart -> SequencePointAtBinding spStart | NoSequencePointAtForLoop -> NoSequencePointAtStickyBinding) - mkLet spBind mEnumExpr currentVar enumerableExpr - // let mutable next = current.TailOrNull - (mkCompGenLet mForLoop nextVar tailOrNullExpr - // while nonNull next dp - (mkWhile g (spWhileLoop, WhileLoopForCompiledForEachExprMarker, guardExpr, bodyExpr, mBody))) - - expr - - else - expr - - | _ -> expr - -// Used to remove Expr.Link for inner expressions in pattern matches -let (|InnerExprPat|) expr = stripExpr expr - -/// One of the transformations performed by the compiler -/// is to eliminate variables of static type "unit". These is a -/// utility function related to this. - -let BindUnitVars g (mvs: Val list, paramInfos: ArgReprInfo list, body) = - match mvs, paramInfos with - | [v], [] -> - assert isUnitTy g v.Type - [], mkLet NoSequencePointAtInvisibleBinding v.Range v (mkUnit g v.Range) body - | _ -> mvs, body - -let isThreadOrContextStatic g attrs = - HasFSharpAttributeOpt g g.attrib_ThreadStaticAttribute attrs || - HasFSharpAttributeOpt g g.attrib_ContextStaticAttribute attrs - -let mkUnitDelayLambda (g: TcGlobals) m e = - let uv, _ = mkCompGenLocal m "unitVar" g.unit_ty - mkLambda m uv (e, tyOfExpr g e) - - -let isStaticClass (g:TcGlobals) (x: EntityRef) = - not x.IsModuleOrNamespace && - x.TyparsNoRange.IsEmpty && - ((x.IsILTycon && - x.ILTyconRawMetadata.IsSealed && - x.ILTyconRawMetadata.IsAbstract) -#if !NO_EXTENSIONTYPING - || (x.IsProvided && - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.IsSealed && info.IsAbstract - | _ -> false) -#endif - || (not x.IsILTycon && not x.IsProvided && HasFSharpAttribute g g.attrib_AbstractClassAttribute x.Attribs)) && - not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute x.Attribs) diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi deleted file mode 100755 index 5179b85239e..00000000000 --- a/src/fsharp/TastOps.fsi +++ /dev/null @@ -1,2310 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Defines derived expression manipulation and construction functions. -module internal FSharp.Compiler.Tastops - -open System.Collections.Generic -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Rational -open FSharp.Compiler.Ast -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Layout - -//------------------------------------------------------------------------- -// Type equivalence -//------------------------------------------------------------------------- - -type Erasure = EraseAll | EraseMeasures | EraseNone - -/// Check the equivalence of two types up to an erasure flag -val typeEquivAux : Erasure -> TcGlobals -> TType -> TType -> bool - -/// Check the equivalence of two types -val typeEquiv : TcGlobals -> TType -> TType -> bool - -/// Check the equivalence of two units-of-measure -val measureEquiv : TcGlobals -> Measure -> Measure -> bool - -/// Reduce a type to its more canonical form subject to an erasure flag, inference equations and abbreviations -val stripTyEqnsWrtErasure: Erasure -> TcGlobals -> TType -> TType - -/// Build a function type -val mkFunTy : TType -> TType -> TType - -/// Build a function type -val ( --> ) : TType -> TType -> TType - -/// Build a type-forall anonymous generic type if necessary -val mkForallTyIfNeeded : Typars -> TType -> TType - -val ( +-> ) : Typars -> TType -> TType - -/// Build a curried function type -val mkIteratedFunTy : TTypes -> TType -> TType - -/// Get the natural type of a single argument amongst a set of curried arguments -val typeOfLambdaArg : range -> Val list -> TType - -/// Get the curried type corresponding to a lambda -val mkMultiLambdaTy : range -> Val list -> TType -> TType - -/// Get the curried type corresponding to a lambda -val mkLambdaTy : Typars -> TTypes -> TType -> TType - -/// Module publication, used while compiling fslib. -val ensureCcuHasModuleOrNamespaceAtPath : CcuThunk -> Ident list -> CompilationPath -> XmlDoc -> unit - -/// Ignore 'Expr.Link' in an expression -val stripExpr : Expr -> Expr - -/// Get the values for a set of bindings -val valsOfBinds : Bindings -> Vals - -/// Look for a use of an F# value, possibly including application of a generic thing to a set of type arguments -val (|ExprValWithPossibleTypeInst|_|) : Expr -> (ValRef * ValUseFlag * TType list * range) option - -/// Build decision trees imperatively -type MatchBuilder = - - /// Create a new builder - new : SequencePointInfoForBinding * range -> MatchBuilder - - /// Add a new destination target - member AddTarget : DecisionTreeTarget -> int - - /// Add a new destination target that is an expression result - member AddResultTarget : Expr * SequencePointInfoForTarget -> DecisionTree - - /// Finish the targets - member CloseTargets : unit -> DecisionTreeTarget list - - /// Build the overall expression - member Close : DecisionTree * range * TType -> Expr - -/// Add an if-then-else boolean conditional node into a decision tree -val mkBoolSwitch : range -> Expr -> DecisionTree -> DecisionTree -> DecisionTree - -/// Build a conditional expression -val primMkCond : SequencePointInfoForBinding -> SequencePointInfoForTarget -> SequencePointInfoForTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr - -/// Build a conditional expression -val mkCond : SequencePointInfoForBinding -> SequencePointInfoForTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr - -/// Build a conditional expression that checks for non-nullness -val mkNonNullCond : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr - -/// Build an if-then statement -val mkIfThen : TcGlobals -> range -> Expr -> Expr -> Expr - -/// Build an expression corresponding to the use of a value -/// Note: try to use exprForValRef or the expression returned from mkLocal instead of this. -val exprForVal : range -> Val -> Expr - -/// Build an expression corresponding to the use of a reference to a value -val exprForValRef : range -> ValRef -> Expr - -/// Make a new local value and build an expression to reference it -val mkLocal : range -> string -> TType -> Val * Expr - -/// Make a new compiler-generated local value and build an expression to reference it -val mkCompGenLocal : range -> string -> TType -> Val * Expr - -/// Make a new mutable compiler-generated local value and build an expression to reference it -val mkMutableCompGenLocal : range -> string -> TType -> Val * Expr - -/// Make a new mutable compiler-generated local value, 'let' bind it to an expression -/// 'invisibly' (no sequence point etc.), and build an expression to reference it -val mkCompGenLocalAndInvisibleBind : TcGlobals -> string -> range -> Expr -> Val * Expr * Binding - -/// Build a lambda expression taking multiple values -val mkMultiLambda : range -> Val list -> Expr * TType -> Expr - -/// Rebuild a lambda during an expression tree traversal -val rebuildLambda : range -> Val option -> Val option -> Val list -> Expr * TType -> Expr - -/// Build a lambda expression taking a single value -val mkLambda : range -> Val -> Expr * TType -> Expr - -/// Build a generic lambda expression (type abstraction) -val mkTypeLambda : range -> Typars -> Expr * TType -> Expr - -/// Build an object expression -val mkObjExpr : TType * Val option * Expr * ObjExprMethod list * (TType * ObjExprMethod list) list * Range.range -> Expr - -/// Build an type-chose expression, indicating that a local free choice of a type variable -val mkTypeChoose : range -> Typars -> Expr -> Expr - -/// Build an iterated (curried) lambda expression -val mkLambdas : range -> Typars -> Val list -> Expr * TType -> Expr - -/// Build an iterated (tupled+curried) lambda expression -val mkMultiLambdasCore : range -> Val list list -> Expr * TType -> Expr * TType - -/// Build an iterated generic (type abstraction + tupled+curried) lambda expression -val mkMultiLambdas : range -> Typars -> Val list list -> Expr * TType -> Expr - -/// Build a lambda expression that corresponds to the implementation of a member -val mkMemberLambdas : range -> Typars -> Val option -> Val option -> Val list list -> Expr * TType -> Expr - -/// Build a 'while' loop expression -val mkWhile : TcGlobals -> SequencePointInfoForWhileLoop * SpecialWhileLoopMarker * Expr * Expr * range -> Expr - -/// Build a 'for' loop expression -val mkFor : TcGlobals -> SequencePointInfoForForLoop * Val * Expr * ForLoopStyle * Expr * Expr * range -> Expr - -/// Build a 'try/with' expression -val mkTryWith : TcGlobals -> Expr * (* filter val *) Val * (* filter expr *) Expr * (* handler val *) Val * (* handler expr *) Expr * range * TType * SequencePointInfoForTry * SequencePointInfoForWith -> Expr - -/// Build a 'try/finally' expression -val mkTryFinally: TcGlobals -> Expr * Expr * range * TType * SequencePointInfoForTry * SequencePointInfoForFinally -> Expr - -/// Build a user-level value binding -val mkBind : SequencePointInfoForBinding -> Val -> Expr -> Binding - -/// Build a user-level let-binding -val mkLetBind : range -> Binding -> Expr -> Expr - -/// Build a user-level value sequence of let bindings -val mkLetsBind : range -> Binding list -> Expr -> Expr - -/// Build a user-level value sequence of let bindings -val mkLetsFromBindings : range -> Bindings -> Expr -> Expr - -/// Build a user-level let expression -val mkLet : SequencePointInfoForBinding -> range -> Val -> Expr -> Expr -> Expr - -/// Make a binding that binds a function value to a lambda taking multiple arguments -val mkMultiLambdaBind : Val -> SequencePointInfoForBinding -> range -> Typars -> Val list list -> Expr * TType -> Binding - -// Compiler generated bindings may involve a user variable. -// Compiler generated bindings may give rise to a sequence point if they are part of -// an SPAlways expression. Compiler generated bindings can arise from for example, inlining. -val mkCompGenBind : Val -> Expr -> Binding - -/// Make a set of bindings that bind compiler generated values to corresponding expressions. -/// Compiler-generated bindings do not give rise to a sequence point in debugging. -val mkCompGenBinds : Val list -> Exprs -> Bindings - -/// Make a let-expression that locally binds a compiler-generated value to an expression. -/// Compiler-generated bindings do not give rise to a sequence point in debugging. -val mkCompGenLet : range -> Val -> Expr -> Expr -> Expr - -/// Make a let-expression that locally binds a compiler-generated value to an expression, where the expression -/// is returned by the given continuation. Compiler-generated bindings do not give rise to a sequence point in debugging. -val mkCompGenLetIn: range -> string -> TType -> Expr -> (Val * Expr -> Expr) -> Expr - -/// Make a let-expression that locally binds a value to an expression in an "invisible" way. -/// Invisible bindings are not given a sequence point and should not have side effects. -val mkInvisibleLet : range -> Val -> Expr -> Expr -> Expr - -/// Make a binding that binds a value to an expression in an "invisible" way. -/// Invisible bindings are not given a sequence point and should not have side effects. -val mkInvisibleBind : Val -> Expr -> Binding - -/// Make a set of bindings that bind values to expressions in an "invisible" way. -/// Invisible bindings are not given a sequence point and should not have side effects. -val mkInvisibleBinds : Vals -> Exprs -> Bindings - -/// Make a let-rec expression that locally binds values to expressions where self-reference back to the values is possible. -val mkLetRecBinds : range -> Bindings -> Expr -> Expr - -/// TypeScheme (generalizedTypars, tauTy) -/// -/// generalizedTypars -- the truly generalized type parameters -/// tauTy -- the body of the generalized type. A 'tau' type is one with its type parameters stripped off. -type TypeScheme = TypeScheme of Typars * TType - -/// Make the right-hand side of a generalized binding, incorporating the generalized generic parameters from the type -/// scheme into the right-hand side as type generalizations. -val mkGenericBindRhs : TcGlobals -> range -> Typars -> TypeScheme -> Expr -> Expr - -/// Test if the type parameter is one of those being generalized by a type scheme. -val isBeingGeneralized : Typar -> TypeScheme -> bool - -/// Make the expression corresponding to 'expr1 && expr2' -val mkLazyAnd : TcGlobals -> range -> Expr -> Expr -> Expr - -/// Make the expression corresponding to 'expr1 || expr2' -val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr - -/// Make a byref type -val mkByrefTy : TcGlobals -> TType -> TType - -/// Make a byref type with a in/out kind inference parameter -val mkByrefTyWithInference : TcGlobals -> TType -> TType -> TType - -/// Make a in-byref type with a in kind parameter -val mkInByrefTy : TcGlobals -> TType -> TType - -/// Make an out-byref type with an out kind parameter -val mkOutByrefTy : TcGlobals -> TType -> TType - -/// Make an expression that constructs a union case, e.g. 'Some(expr)' -val mkUnionCaseExpr : UnionCaseRef * TypeInst * Exprs * range -> Expr - -/// Make an expression that constructs an exception value -val mkExnExpr : TyconRef * Exprs * range -> Expr - -/// Make an expression that is IL assembly code -val mkAsmExpr : ILInstr list * TypeInst * Exprs * TTypes * range -> Expr - -/// Make an expression that coerces one expression to another type -val mkCoerceExpr : Expr * TType * range * TType -> Expr - -/// Make an expression that re-raises an exception -val mkReraise : range -> TType -> Expr - -/// Make an expression that re-raises an exception via a library call -val mkReraiseLibCall : TcGlobals -> TType -> range -> Expr - -/// Make an expression that gets an item from a tuple -val mkTupleFieldGet : TcGlobals -> TupInfo * Expr * TypeInst * int * range -> Expr - -/// Make an expression that gets an item from an anonymous record -val mkAnonRecdFieldGet : TcGlobals -> AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr - -/// Make an expression that gets an item from an anonymous record (via the address of the value if it is a struct) -val mkAnonRecdFieldGetViaExprAddr : AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr - -/// Make an expression that gets an instance field from a record or class (via the address of the value if it is a struct) -val mkRecdFieldGetViaExprAddr : Expr * RecdFieldRef * TypeInst * range -> Expr - -/// Make an expression that gets the address of an instance field from a record or class (via the address of the value if it is a struct) -val mkRecdFieldGetAddrViaExprAddr : readonly: bool * Expr * RecdFieldRef * TypeInst * range -> Expr - -/// Make an expression that gets a static field from a record or class -val mkStaticRecdFieldGet : RecdFieldRef * TypeInst * range -> Expr - -/// Make an expression that sets a static field in a record or class -val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr - -/// Make an expression that gets the address of a static field in a record or class -val mkStaticRecdFieldGetAddr : readonly: bool * RecdFieldRef * TypeInst * range -> Expr - -/// Make an expression that sets an instance the field of a record or class (via the address of the value if it is a struct) -val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr - -/// Make an expression that gets the tag of a union value (via the address of the value if it is a struct) -val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr - -/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) -val mkUnionCaseProof : Expr * UnionCaseRef * TypeInst * range -> Expr - -/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions, -/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -val mkUnionCaseFieldGetProvenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr - -/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, -/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -val mkUnionCaseFieldGetAddrProvenViaExprAddr : readonly: bool * Expr * UnionCaseRef * TypeInst * int * range -> Expr - -/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, -/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -val mkUnionCaseFieldGetUnprovenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr - -/// Build a 'TOp.UnionCaseFieldSet' expression. For ref-unions, the input expression has 'TType_ucase', which is -/// an F# compiler internal "type" corresponding to the union case. For struct-unions, -/// the input should be the address of the expression. -val mkUnionCaseFieldSet : Expr * UnionCaseRef * TypeInst * int * Expr * range -> Expr - -/// Like mkUnionCaseFieldGetUnprovenViaExprAddr, but for struct-unions, the input should be a copy of the expression. -val mkUnionCaseFieldGetUnproven : TcGlobals -> Expr * UnionCaseRef * TypeInst * int * range -> Expr - -/// Make an expression that gets an instance field from an F# exception value -val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr - -/// Make an expression that sets an instance field in an F# exception value -val mkExnCaseFieldSet : Expr * TyconRef * int * Expr * range -> Expr - -/// Make an expression that gets the address of an element in an array -val mkArrayElemAddress : TcGlobals -> readonly: bool * ILReadonly * bool * ILArrayShape * TType * Expr list * range -> Expr - -//------------------------------------------------------------------------- -// Compiled view of tuples -//------------------------------------------------------------------------- - -/// The largest tuple before we start encoding, i.e. 7 -val maxTuple : int - -/// The number of fields in the largest tuple before we start encoding, i.e. 7 -val goodTupleFields : int - -/// Check if a TyconRef is for a .NET tuple type. Currently this includes Tuple`1 even though -/// that' not really part of the target set of TyconRef used to represent F# tuples. -val isCompiledTupleTyconRef : TcGlobals -> TyconRef -> bool - -/// Get a TyconRef for a .NET tuple type -val mkCompiledTupleTyconRef : TcGlobals -> bool -> int -> TyconRef - -/// Convert from F# tuple types to .NET tuple types. -val mkCompiledTupleTy : TcGlobals -> bool -> TTypes -> TType - -/// Convert from F# tuple creation expression to .NET tuple creation expressions -val mkCompiledTuple : TcGlobals -> bool -> TTypes * Exprs * range -> TyconRef * TTypes * Exprs * range - -/// Make a TAST expression representing getting an item fromm a tuple -val mkGetTupleItemN : TcGlobals -> range -> int -> ILType -> bool -> Expr -> TType -> Expr - -/// Evaluate the TupInfo to work out if it is a struct or a ref. Currently this is very simple -/// but TupInfo may later be used carry variables that infer structness. -val evalTupInfoIsStruct : TupInfo -> bool - -/// Evaluate the AnonRecdTypeInfo to work out if it is a struct or a ref. -val evalAnonInfoIsStruct : AnonRecdTypeInfo -> bool - -/// If it is a tuple type, ensure it's outermost type is a .NET tuple type, otherwise leave unchanged -val convertToTypeWithMetadataIfPossible : TcGlobals -> TType -> TType - -/// An exception representing a warning for a defensive copy of an immutable struct -exception DefensiveCopyWarning of string * range - -type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates - -/// Helper to create an expression that dereferences an address. -val mkDerefAddrExpr: mAddrGet: range -> expr: Expr -> mExpr: range -> exprTy: TType -> Expr - -/// Helper to take the address of an expression -val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr * bool * bool - -/// Take the address of an expression, or force it into a mutable local. Any allocated -/// mutable local may need to be kept alive over a larger expression, hence we return -/// a wrapping function that wraps "let mutable loc = Expr in ..." around a larger -/// expression. -val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr * bool * bool - -/// Maps Val to T, based on stamps -[] -type ValMap<'T> = - - member Contents : StampMap<'T> - - member Item : Val -> 'T with get - - member TryFind : Val -> 'T option - - member ContainsVal : Val -> bool - - member Add : Val -> 'T -> ValMap<'T> - - member Remove : Val -> ValMap<'T> - - member IsEmpty : bool - - static member Empty : ValMap<'T> - - static member OfList : (Val * 'T) list -> ValMap<'T> - -/// Mutable data structure mapping Val's to T based on stamp keys -[] -type ValHash<'T> = - - member Values : seq<'T> - - member TryFind : Val -> 'T option - - member Add : Val * 'T -> unit - - static member Create : unit -> ValHash<'T> - -/// Maps Val's to list of T based on stamp keys -[] -type ValMultiMap<'T> = - - member ContainsKey : Val -> bool - - member Find : Val -> 'T list - - member Add : Val * 'T -> ValMultiMap<'T> - - member Remove : Val -> ValMultiMap<'T> - - member Contents : StampMap<'T list> - - static member Empty : ValMultiMap<'T> - -/// Maps type parameters to entries based on stamp keys -[] -type TyparMap<'T> = - - /// Get the entry for the given type parameter - member Item : Typar -> 'T with get - - /// Determine is the map contains an entry for the given type parameter - member ContainsKey : Typar -> bool - - /// Try to find the entry for the given type parameter - member TryFind : Typar -> 'T option - - /// Make a new map, containing a new entry for the given type parameter - member Add : Typar * 'T -> TyparMap<'T> - - /// The empty map - static member Empty : TyparMap<'T> - -/// Maps TyconRef to T based on stamp keys -[] -type TyconRefMap<'T> = - - /// Get the entry for the given type definition - member Item : TyconRef -> 'T with get - - /// Try to find the entry for the given type definition - member TryFind : TyconRef -> 'T option - - /// Determine is the map contains an entry for the given type definition - member ContainsKey : TyconRef -> bool - - /// Make a new map, containing a new entry for the given type definition - member Add : TyconRef -> 'T -> TyconRefMap<'T> - - /// Remove the entry for the given type definition, if any - member Remove : TyconRef -> TyconRefMap<'T> - - /// Determine if the map is empty - member IsEmpty : bool - - /// The empty map - static member Empty : TyconRefMap<'T> - - /// Make a new map, containing entries for the given type definitions - static member OfList : (TyconRef * 'T) list -> TyconRefMap<'T> - -/// Maps TyconRef to list of T based on stamp keys -[] -type TyconRefMultiMap<'T> = - - /// Fetch the entries for the given type definition - member Find : TyconRef -> 'T list - - /// Make a new map, containing a new entry for the given type definition - member Add : TyconRef * 'T -> TyconRefMultiMap<'T> - - /// The empty map - static member Empty : TyconRefMultiMap<'T> - - /// Make a new map, containing a entries for the given type definitions - static member OfList : (TyconRef * 'T) list -> TyconRefMultiMap<'T> - -/// An ordering for value definitions, based on stamp -val valOrder: IComparer - -/// An ordering for type definitions, based on stamp -val tyconOrder: IComparer - -/// An ordering for record fields, based on stamp -val recdFieldRefOrder: IComparer - -/// An ordering for type parameters, based on stamp -val typarOrder: IComparer - -/// Equality for type definition references -val tyconRefEq : TcGlobals -> TyconRef -> TyconRef -> bool - -/// Equality for value references -val valRefEq : TcGlobals -> ValRef -> ValRef -> bool - -//------------------------------------------------------------------------- -// Operations on types: substitution -//------------------------------------------------------------------------- - -/// Represents an instantiation where types replace type parameters -type TyparInst = (Typar * TType) list - -/// Represents an instantiation where type definition references replace other type definition references -type TyconRefRemap = TyconRefMap - -/// Represents an instantiation where value references replace other value references -type ValRemap = ValMap - -/// Represents a combination of substitutions/instantiations where things replace other things during remapping -[] -type Remap = - { tpinst : TyparInst - valRemap: ValRemap - tyconRefRemap : TyconRefRemap - removeTraitSolutions: bool } - - static member Empty : Remap - -val addTyconRefRemap : TyconRef -> TyconRef -> Remap -> Remap - -val addValRemap : Val -> Val -> Remap -> Remap - -val mkTyparInst : Typars -> TTypes -> TyparInst - -val mkTyconRefInst : TyconRef -> TypeInst -> TyparInst - -val emptyTyparInst : TyparInst - -val instType : TyparInst -> TType -> TType - -val instTypes : TyparInst -> TypeInst -> TypeInst - -val instTyparConstraints : TyparInst -> TyparConstraint list -> TyparConstraint list - -val instTrait : TyparInst -> TraitConstraintInfo -> TraitConstraintInfo - -//------------------------------------------------------------------------- -// From typars to types -//------------------------------------------------------------------------- - -val generalizeTypars : Typars -> TypeInst - -val generalizeTyconRef : TyconRef -> TTypes * TType - -val generalizedTyconRef : TyconRef -> TType - -val mkTyparToTyparRenaming : Typars -> Typars -> TyparInst * TTypes - -//------------------------------------------------------------------------- -// See through typar equations from inference and/or type abbreviation equations. -//------------------------------------------------------------------------- - -val reduceTyconRefAbbrev : TyconRef -> TypeInst -> TType - -val reduceTyconRefMeasureableOrProvided : TcGlobals -> TyconRef -> TypeInst -> TType - -val reduceTyconRefAbbrevMeasureable : TyconRef -> Measure - -/// set bool to 'true' to allow shortcutting of type parameter equation chains during stripping -val stripTyEqnsA : TcGlobals -> bool -> TType -> TType - -val stripTyEqns : TcGlobals -> TType -> TType - -val stripTyEqnsAndMeasureEqns : TcGlobals -> TType -> TType - -val tryNormalizeMeasureInType : TcGlobals -> TType -> TType - -//------------------------------------------------------------------------- -// -//------------------------------------------------------------------------- - -/// See through F# exception abbreviations -val stripExnEqns : TyconRef -> Tycon - -val recdFieldsOfExnDefRef : TyconRef -> RecdField list - -val recdFieldTysOfExnDefRef : TyconRef -> TType list - -//------------------------------------------------------------------------- -// Analyze types. These all look through type abbreviations and -// inference equations, i.e. are "stripped" -//------------------------------------------------------------------------- - -val destForallTy : TcGlobals -> TType -> Typars * TType - -val destFunTy : TcGlobals -> TType -> TType * TType - -val destAnyTupleTy : TcGlobals -> TType -> TupInfo * TTypes - -val destRefTupleTy : TcGlobals -> TType -> TTypes - -val destStructTupleTy : TcGlobals -> TType -> TTypes - -val destTyparTy : TcGlobals -> TType -> Typar - -val destAnyParTy : TcGlobals -> TType -> Typar - -val destMeasureTy : TcGlobals -> TType -> Measure - -val tryDestForallTy : TcGlobals -> TType -> Typars * TType - -val isFunTy : TcGlobals -> TType -> bool - -val isForallTy : TcGlobals -> TType -> bool - -val isAnyTupleTy : TcGlobals -> TType -> bool - -val isRefTupleTy : TcGlobals -> TType -> bool - -val isStructTupleTy : TcGlobals -> TType -> bool - -val isStructAnonRecdTy : TcGlobals -> TType -> bool - -val isAnonRecdTy : TcGlobals -> TType -> bool - -val isUnionTy : TcGlobals -> TType -> bool - -val isReprHiddenTy : TcGlobals -> TType -> bool - -val isFSharpObjModelTy : TcGlobals -> TType -> bool - -val isRecdTy : TcGlobals -> TType -> bool - -val isFSharpStructOrEnumTy : TcGlobals -> TType -> bool - -val isFSharpEnumTy : TcGlobals -> TType -> bool - -val isTyparTy : TcGlobals -> TType -> bool - -val isAnyParTy : TcGlobals -> TType -> bool - -val tryAnyParTy : TcGlobals -> TType -> ValueOption - -val tryAnyParTyOption : TcGlobals -> TType -> Typar option - -val isMeasureTy : TcGlobals -> TType -> bool - -val mkAppTy : TyconRef -> TypeInst -> TType - -val mkProvenUnionCaseTy : UnionCaseRef -> TypeInst -> TType - -val isProvenUnionCaseTy : TType -> bool - -val isAppTy : TcGlobals -> TType -> bool - -val tryAppTy : TcGlobals -> TType -> ValueOption - -val destAppTy : TcGlobals -> TType -> TyconRef * TypeInst - -val tcrefOfAppTy : TcGlobals -> TType -> TyconRef - -val tryDestAppTy : TcGlobals -> TType -> ValueOption - -val tryDestTyparTy : TcGlobals -> TType -> ValueOption - -val tryDestFunTy : TcGlobals -> TType -> ValueOption<(TType * TType)> - -val tryDestAnonRecdTy : TcGlobals -> TType -> ValueOption - -val argsOfAppTy : TcGlobals -> TType -> TypeInst - -val mkInstForAppTy : TcGlobals -> TType -> TyparInst - -/// Try to get a TyconRef for a type without erasing type abbreviations -val tryNiceEntityRefOfTy : TType -> ValueOption - -val tryNiceEntityRefOfTyOption : TType -> TyconRef option - -val domainOfFunTy : TcGlobals -> TType -> TType - -val rangeOfFunTy : TcGlobals -> TType -> TType - -val stripFunTy : TcGlobals -> TType -> TType list * TType - -val stripFunTyN : TcGlobals -> int -> TType -> TType list * TType - -val applyForallTy : TcGlobals -> TType -> TypeInst -> TType - -val tryDestAnyTupleTy : TcGlobals -> TType -> TupInfo * TType list - -val tryDestRefTupleTy : TcGlobals -> TType -> TType list - -//------------------------------------------------------------------------- -// Compute actual types of union cases and fields given an instantiation -// of the generic type parameters of the enclosing type. -//------------------------------------------------------------------------- - -val actualResultTyOfUnionCase : TypeInst -> UnionCaseRef -> TType - -val actualTysOfUnionCaseFields : TyparInst -> UnionCaseRef -> TType list - -val actualTysOfInstanceRecdFields : TyparInst -> TyconRef -> TType list - -val actualTyOfRecdField : TyparInst -> RecdField -> TType - -val actualTyOfRecdFieldRef : RecdFieldRef -> TypeInst -> TType - -val actualTyOfRecdFieldForTycon : Tycon -> TypeInst -> RecdField -> TType - -//------------------------------------------------------------------------- -// Top types: guaranteed to be compiled to .NET methods, and must be able to -// have user-specified argument names (for stability w.r.t. reflection) -// and user-specified argument and return attributes. -//------------------------------------------------------------------------- - -type UncurriedArgInfos = (TType * ArgReprInfo) list - -type CurriedArgInfos = UncurriedArgInfos list - -val destTopForallTy : TcGlobals -> ValReprInfo -> TType -> Typars * TType - -val GetTopTauTypeInFSharpForm : TcGlobals -> ArgReprInfo list list -> TType -> range -> CurriedArgInfos * TType - -val GetTopValTypeInFSharpForm : TcGlobals -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType * ArgReprInfo - -val IsCompiledAsStaticProperty : TcGlobals -> Val -> bool - -val IsCompiledAsStaticPropertyWithField : TcGlobals -> Val -> bool - -val GetTopValTypeInCompiledForm : TcGlobals -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType option * ArgReprInfo - -val GetFSharpViewOfReturnType : TcGlobals -> TType option -> TType - -val NormalizeDeclaredTyparsForEquiRecursiveInference : TcGlobals -> Typars -> Typars - -//------------------------------------------------------------------------- -// Compute the return type after an application -//------------------------------------------------------------------------- - -val applyTys : TcGlobals -> TType -> TType list * 'T list -> TType - -//------------------------------------------------------------------------- -// Compute free variables in types -//------------------------------------------------------------------------- - -val emptyFreeTypars : FreeTypars - -val unionFreeTypars : FreeTypars -> FreeTypars -> FreeTypars - -val emptyFreeTycons : FreeTycons - -val unionFreeTycons : FreeTycons -> FreeTycons -> FreeTycons - -val emptyFreeTyvars : FreeTyvars - -val isEmptyFreeTyvars : FreeTyvars -> bool - -val unionFreeTyvars : FreeTyvars -> FreeTyvars -> FreeTyvars - -val emptyFreeLocals : FreeLocals - -val unionFreeLocals : FreeLocals -> FreeLocals -> FreeLocals - -type FreeVarOptions - -val CollectLocalsNoCaching : FreeVarOptions - -val CollectTyparsNoCaching : FreeVarOptions - -val CollectTyparsAndLocalsNoCaching : FreeVarOptions - -val CollectTyparsAndLocals : FreeVarOptions - -val CollectLocals : FreeVarOptions - -val CollectTypars : FreeVarOptions - -val CollectAllNoCaching : FreeVarOptions - -val CollectAll : FreeVarOptions - -val accFreeInTypes : FreeVarOptions -> TType list -> FreeTyvars -> FreeTyvars - -val accFreeInType : FreeVarOptions -> TType -> FreeTyvars -> FreeTyvars - -val accFreeInTypars : FreeVarOptions -> Typars -> FreeTyvars -> FreeTyvars - -val freeInType : FreeVarOptions -> TType -> FreeTyvars - -val freeInTypes : FreeVarOptions -> TType list -> FreeTyvars - -val freeInVal : FreeVarOptions -> Val -> FreeTyvars - -// This one puts free variables in canonical left-to-right order. -val freeInTypeLeftToRight : TcGlobals -> bool -> TType -> Typars - -val freeInTypesLeftToRight : TcGlobals -> bool -> TType list -> Typars - -val freeInTypesLeftToRightSkippingConstraints : TcGlobals -> TType list -> Typars - -val freeInModuleTy: ModuleOrNamespaceType -> FreeTyvars - -val isDimensionless : TcGlobals -> TType -> bool - -//------------------------------------------------------------------------- -// Equivalence of types (up to substitution of type variables in the left-hand type) -//------------------------------------------------------------------------- - -[] -type TypeEquivEnv = - { EquivTypars: TyparMap - EquivTycons: TyconRefRemap } - - static member Empty : TypeEquivEnv - - member BindEquivTypars : Typars -> Typars -> TypeEquivEnv - - static member FromTyparInst : TyparInst -> TypeEquivEnv - - static member FromEquivTypars : Typars -> Typars -> TypeEquivEnv - -val traitsAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool - -val traitsAEquiv : TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool - -val typarConstraintsAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool - -val typarConstraintsAEquiv : TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool - -val typarsAEquiv : TcGlobals -> TypeEquivEnv -> Typars -> Typars -> bool - -val typeAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool - -val typeAEquiv : TcGlobals -> TypeEquivEnv -> TType -> TType -> bool - -val returnTypesAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool - -val returnTypesAEquiv : TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool - -val tcrefAEquiv : TcGlobals -> TypeEquivEnv -> TyconRef -> TyconRef -> bool - -val valLinkageAEquiv : TcGlobals -> TypeEquivEnv -> Val -> Val -> bool - -val anonInfoEquiv : AnonRecdTypeInfo -> AnonRecdTypeInfo -> bool - -//------------------------------------------------------------------------- -// Erasure of types wrt units-of-measure and type providers -//------------------------------------------------------------------------- - -// Return true if this type is a nominal type that is an erased provided type -val isErasedType : TcGlobals -> TType -> bool - -// Return all components (units-of-measure, and types) of this type that would be erased -val getErasedTypes : TcGlobals -> TType -> TType list - -//------------------------------------------------------------------------- -// Unit operations -//------------------------------------------------------------------------- - -val MeasurePower : Measure -> int -> Measure - -val ListMeasureVarOccsWithNonZeroExponents : Measure -> (Typar * Rational) list - -val ListMeasureConOccsWithNonZeroExponents : TcGlobals -> bool -> Measure -> (TyconRef * Rational) list - -val ProdMeasures : Measure list -> Measure - -val MeasureVarExponent : Typar -> Measure -> Rational - -val MeasureExprConExponent : TcGlobals -> bool -> TyconRef -> Measure -> Rational - -val normalizeMeasure : TcGlobals -> Measure -> Measure - - -//------------------------------------------------------------------------- -// Members -//------------------------------------------------------------------------- - -val GetTypeOfMemberInFSharpForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType * ArgReprInfo - -val GetTypeOfMemberInMemberForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType option * ArgReprInfo - -val GetTypeOfIntrinsicMemberInCompiledForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType option * ArgReprInfo - -val GetMemberTypeInMemberForm : TcGlobals -> MemberFlags -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType option * ArgReprInfo - -/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) -val PartitionValTyparsForApparentEnclosingType : TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option - -/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) -val PartitionValTypars : TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option - -/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) -val PartitionValRefTypars : TcGlobals -> ValRef -> (Typars * Typars * Typars * TyparInst * TType list) option - -val ReturnTypeOfPropertyVal : TcGlobals -> Val -> TType - -val ArgInfosOfPropertyVal : TcGlobals -> Val -> UncurriedArgInfos - -val ArgInfosOfMember: TcGlobals -> ValRef -> CurriedArgInfos - -val GetMemberCallInfo : TcGlobals -> ValRef * ValUseFlag -> int * bool * bool * bool * bool * bool * bool * bool - -//------------------------------------------------------------------------- -// Printing -//------------------------------------------------------------------------- - -type TyparConstraintsWithTypars = (Typar * TyparConstraint) list - -module PrettyTypes = - - val NeedsPrettyTyparName : Typar -> bool - - val NewPrettyTypars : TyparInst -> Typars -> string list -> Typars * TyparInst - - val PrettyTyparNames : (Typar -> bool) -> string list -> Typars -> string list - - val PrettifyType : TcGlobals -> TType -> TType * TyparConstraintsWithTypars - - val PrettifyInstAndTyparsAndType : TcGlobals -> TyparInst * Typars * TType -> (TyparInst * Typars * TType) * TyparConstraintsWithTypars - - val PrettifyTypePair : TcGlobals -> TType * TType -> (TType * TType) * TyparConstraintsWithTypars - - val PrettifyTypes : TcGlobals -> TTypes -> TTypes * TyparConstraintsWithTypars - - val PrettifyInst : TcGlobals -> TyparInst -> TyparInst * TyparConstraintsWithTypars - - val PrettifyInstAndType : TcGlobals -> TyparInst * TType -> (TyparInst * TType) * TyparConstraintsWithTypars - - val PrettifyInstAndTypes : TcGlobals -> TyparInst * TTypes -> (TyparInst * TTypes) * TyparConstraintsWithTypars - - val PrettifyInstAndSig : TcGlobals -> TyparInst * TTypes * TType -> (TyparInst * TTypes * TType) * TyparConstraintsWithTypars - - val PrettifyCurriedTypes : TcGlobals -> TType list list -> TType list list * TyparConstraintsWithTypars - - val PrettifyCurriedSigTypes : TcGlobals -> TType list list * TType -> (TType list list * TType) * TyparConstraintsWithTypars - - val PrettifyInstAndUncurriedSig : TcGlobals -> TyparInst * UncurriedArgInfos * TType -> (TyparInst * UncurriedArgInfos * TType) * TyparConstraintsWithTypars - - val PrettifyInstAndCurriedSig : TcGlobals -> TyparInst * TTypes * CurriedArgInfos * TType -> (TyparInst * TTypes * CurriedArgInfos * TType) * TyparConstraintsWithTypars - -[] -type DisplayEnv = - { includeStaticParametersInTypeNames : bool - openTopPathsSorted: Lazy - openTopPathsRaw: string list list - shortTypeNames: bool - suppressNestedTypes: bool - maxMembers : int option - showObsoleteMembers: bool - showHiddenMembers: bool - showTyparBinding: bool - showImperativeTyparAnnotations: bool - suppressInlineKeyword:bool - suppressMutableKeyword:bool - showMemberContainers: bool - shortConstraints:bool - useColonForReturnType:bool - showAttributes: bool - showOverrides:bool - showConstraintTyparAnnotations:bool - abbreviateAdditionalConstraints: bool - showTyparDefaultConstraints: bool - g: TcGlobals - contextAccessibility: Accessibility - generatedValueLayout:(Val -> layout option) } - - member SetOpenPaths: string list list -> DisplayEnv - - static member Empty: TcGlobals -> DisplayEnv - - member AddAccessibility : Accessibility -> DisplayEnv - - member AddOpenPath : string list -> DisplayEnv - - member AddOpenModuleOrNamespace : ModuleOrNamespaceRef -> DisplayEnv - -val tagEntityRefName: xref: EntityRef -> name: string -> StructuredFormat.TaggedText - -/// Return the full text for an item as we want it displayed to the user as a fully qualified entity -val fullDisplayTextOfModRef : ModuleOrNamespaceRef -> string - -val fullDisplayTextOfParentOfModRef : ModuleOrNamespaceRef -> ValueOption - -val fullDisplayTextOfValRef : ValRef -> string - -val fullDisplayTextOfValRefAsLayout : ValRef -> StructuredFormat.Layout - -val fullDisplayTextOfTyconRef : TyconRef -> string - -val fullDisplayTextOfTyconRefAsLayout : TyconRef -> StructuredFormat.Layout - -val fullDisplayTextOfExnRef : TyconRef -> string - -val fullDisplayTextOfExnRefAsLayout : TyconRef -> StructuredFormat.Layout - -val fullDisplayTextOfUnionCaseRef : UnionCaseRef -> string - -val fullDisplayTextOfRecdFieldRef : RecdFieldRef -> string - -val ticksAndArgCountTextOfTyconRef : TyconRef -> string - -/// A unique qualified name for each type definition, used to qualify the names of interface implementation methods -val qualifiedMangledNameOfTyconRef : TyconRef -> string -> string - -val trimPathByDisplayEnv : DisplayEnv -> string list -> string - -val prefixOfStaticReq : TyparStaticReq -> string - -val prefixOfRigidTypar : Typar -> string - -/// Utilities used in simplifying types for visual presentation -module SimplifyTypes = - - type TypeSimplificationInfo = - { singletons : Typar Zset - inplaceConstraints : Zmap - postfixConstraints : TyparConstraintsWithTypars } - - val typeSimplificationInfo0 : TypeSimplificationInfo - - val CollectInfo : bool -> TType list -> TyparConstraintsWithTypars -> TypeSimplificationInfo - -val superOfTycon : TcGlobals -> Tycon -> TType - -val abstractSlotValsOfTycons : Tycon list -> Val list - -//------------------------------------------------------------------------- -// Free variables in expressions etc. -//------------------------------------------------------------------------- - -val emptyFreeVars : FreeVars - -val unionFreeVars : FreeVars -> FreeVars -> FreeVars - -val accFreeInTargets : FreeVarOptions -> DecisionTreeTarget array -> FreeVars -> FreeVars - -val accFreeInExprs : FreeVarOptions -> Exprs -> FreeVars -> FreeVars - -val accFreeInSwitchCases : FreeVarOptions -> DecisionTreeCase list -> DecisionTree option -> FreeVars -> FreeVars - -val accFreeInDecisionTree : FreeVarOptions -> DecisionTree -> FreeVars -> FreeVars - -/// Get the free variables in a module definition. -val freeInModuleOrNamespace : FreeVarOptions -> ModuleOrNamespaceExpr -> FreeVars - -/// Get the free variables in an expression. -val freeInExpr : FreeVarOptions -> Expr -> FreeVars - -/// Get the free variables in the right hand side of a binding. -val freeInBindingRhs : FreeVarOptions -> Binding -> FreeVars - -/// Check if a set of free type variables are all public -val freeTyvarsAllPublic : FreeTyvars -> bool - -/// Check if a set of free variables are all public -val freeVarsAllPublic : FreeVars -> bool - -/// Get the mark/range/position information from an expression -type Expr with - member Range : range - -/// Compute the type of an expression from the expression itself -val tyOfExpr : TcGlobals -> Expr -> TType - -/// A flag to govern whether arity inference should be type-directed or syntax-directed when -/// inferring an arity from a lambda expression. -[] -type AllowTypeDirectedDetupling = - | Yes - | No - -/// Given a (curried) lambda expression, pull off its arguments -val stripTopLambda : Expr * TType -> Typars * Val list list * Expr * TType - -/// Given a lambda expression, extract the ValReprInfo for its arguments and other details -val InferArityOfExpr : TcGlobals -> AllowTypeDirectedDetupling -> TType -> Attribs list list -> Attribs -> Expr -> ValReprInfo - -/// Given a lambda binding, extract the ValReprInfo for its arguments and other details -val InferArityOfExprBinding : TcGlobals -> AllowTypeDirectedDetupling -> Val -> Expr -> ValReprInfo - -/// Mutate a value to indicate it should be considered a local rather than a module-bound definition -// REVIEW: this mutation should not be needed -val setValHasNoArity : Val -> Val - -/// Indicate what should happen to value definitions when copying expressions -type ValCopyFlag = - | CloneAll - | CloneAllAndMarkExprValsAsCompilerGenerated - - /// OnlyCloneExprVals is a nasty setting to reuse the cloning logic in a mode where all - /// Tycon and "module/member" Val objects keep their identity, but the Val objects for all Expr bindings - /// are cloned. This is used to 'fixup' the TAST created by tlr.fs - /// - /// This is a fragile mode of use. It's not really clear why TLR needs to create a "bad" expression tree that - /// reuses Val objects as multiple value bindings, and its been the cause of several subtle bugs. - | OnlyCloneExprVals - -/// Remap a reference to a type definition using the given remapping substitution -val remapTyconRef : TyconRefRemap -> TyconRef -> TyconRef - -/// Remap a reference to a union case using the given remapping substitution -val remapUnionCaseRef : TyconRefRemap -> UnionCaseRef -> UnionCaseRef - -/// Remap a reference to a record field using the given remapping substitution -val remapRecdFieldRef : TyconRefRemap -> RecdFieldRef -> RecdFieldRef - -/// Remap a reference to a value using the given remapping substitution -val remapValRef : Remap -> ValRef -> ValRef - -/// Remap an expression using the given remapping substitution -val remapExpr : TcGlobals -> ValCopyFlag -> Remap -> Expr -> Expr - -/// Remap an attribute using the given remapping substitution -val remapAttrib : TcGlobals -> Remap -> Attrib -> Attrib - -/// Remap a (possible generic) type using the given remapping substitution -val remapPossibleForallTy : TcGlobals -> Remap -> TType -> TType - -/// Copy an entire module or namespace type using the given copying flags -val copyModuleOrNamespaceType : TcGlobals -> ValCopyFlag -> ModuleOrNamespaceType -> ModuleOrNamespaceType - -/// Copy an entire expression using the given copying flags -val copyExpr : TcGlobals -> ValCopyFlag -> Expr -> Expr - -/// Copy an entire implementation file using the given copying flags -val copyImplFile : TcGlobals -> ValCopyFlag -> TypedImplFile -> TypedImplFile - -/// Copy a method slot signature, including new generic type parameters if the slot signature represents a generic method -val copySlotSig : SlotSig -> SlotSig - -/// Instantiate the generic type parameters in a method slot signature, building a new one -val instSlotSig : TyparInst -> SlotSig -> SlotSig - -/// Instantiate the generic type parameters in an expression, building a new one -val instExpr : TcGlobals -> TyparInst -> Expr -> Expr - -/// The remapping that corresponds to a module meeting its signature -/// and also report the set of tycons, tycon representations and values hidden in the process. -type SignatureRepackageInfo = - { /// The list of corresponding values - RepackagedVals: (ValRef * ValRef) list - - /// The list of corresponding modules, namespaces and type definitions - RepackagedEntities: (TyconRef * TyconRef) list } - - /// The empty table - static member Empty : SignatureRepackageInfo - -/// A set of tables summarizing the items hidden by a signature -type SignatureHidingInfo = - { HiddenTycons: Zset - HiddenTyconReprs: Zset - HiddenVals: Zset - HiddenRecdFields: Zset - HiddenUnionCases: Zset } - - /// The empty table representing no hiding - static member Empty : SignatureHidingInfo - -/// Compute the remapping information implied by a signature being inferred for a particular implementation -val ComputeRemappingFromImplementationToSignature : TcGlobals -> ModuleOrNamespaceExpr -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo - -/// Compute the remapping information implied by an explicit signature being given for an inferred signature -val ComputeRemappingFromInferredSignatureToExplicitSignature : TcGlobals -> ModuleOrNamespaceType -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo - -/// Compute the hiding information that corresponds to the hiding applied at an assembly boundary -val ComputeHidingInfoAtAssemblyBoundary : ModuleOrNamespaceType -> SignatureHidingInfo -> SignatureHidingInfo - -val mkRepackageRemapping : SignatureRepackageInfo -> Remap - -/// Wrap one module or namespace implementation in a 'namespace N' outer wrapper -val wrapModuleOrNamespaceExprInNamespace : Ident -> CompilationPath -> ModuleOrNamespaceExpr -> ModuleOrNamespaceExpr - -/// Wrap one module or namespace definition in a 'namespace N' outer wrapper -val wrapModuleOrNamespaceTypeInNamespace : Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespaceType * ModuleOrNamespace - -/// Wrap one module or namespace definition in a 'module M = ..' outer wrapper -val wrapModuleOrNamespaceType : Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespace - -/// Given an implementation, fetch its recorded signature -val SigTypeOfImplFile : TypedImplFile -> ModuleOrNamespaceType - -/// Given a namespace, module or type definition, try to produce a reference to that entity. -val tryRescopeEntity : CcuThunk -> Entity -> ValueOption - -/// Given a value definition, try to produce a reference to that value. Fails for local values. -val tryRescopeVal : CcuThunk -> Remap -> Val -> ValueOption - -/// Make the substitution (remapping) table for viewing a module or namespace 'from the outside' -/// -/// Given the top-most signatures constrains the public compilation units -/// of an assembly, compute a remapping that converts local references to non-local references. -/// This remapping must be applied to all pickled expressions and types -/// exported from the assembly. -val MakeExportRemapping : CcuThunk -> ModuleOrNamespace -> Remap - -/// Make a remapping table for viewing a module or namespace 'from the outside' -val ApplyExportRemappingToEntity : TcGlobals -> Remap -> ModuleOrNamespace -> ModuleOrNamespace - -/// Determine if a type definition is hidden by a signature -val IsHiddenTycon : TcGlobals -> (Remap * SignatureHidingInfo) list -> Tycon -> bool - -/// Determine if the representation of a type definition is hidden by a signature -val IsHiddenTyconRepr : TcGlobals -> (Remap * SignatureHidingInfo) list -> Tycon -> bool - -/// Determine if a member, function or value is hidden by a signature -val IsHiddenVal : (Remap * SignatureHidingInfo) list -> Val -> bool - -/// Determine if a record field is hidden by a signature -val IsHiddenRecdField : (Remap * SignatureHidingInfo) list -> RecdFieldRef -> bool - -/// Adjust marks in expressions, replacing all marks by the given mark. -/// Used when inlining. -val remarkExpr : range -> Expr -> Expr - -/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments -val primMkApp : (Expr * TType) -> TypeInst -> Exprs -> range -> Expr - -/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments. -/// Reduce the application via let-bindings if the function value is a lambda expression. -val mkApps : TcGlobals -> (Expr * TType) * TType list list * Exprs * range -> Expr - -/// Build the application of a generic construct to a set of type arguments. -/// Reduce the application via substitution if the function value is a typed lambda expression. -val mkTyAppExpr : range -> Expr * TType -> TType list -> Expr - -/// Build an expression to mutate a local -/// localv <- e -val mkValSet : range -> ValRef -> Expr -> Expr - -/// Build an expression to mutate the contents of a local pointer -/// *localv_ptr = e -val mkAddrSet : range -> ValRef -> Expr -> Expr - -/// Build an expression to dereference a local pointer -/// *localv_ptr -val mkAddrGet : range -> ValRef -> Expr - -/// Build an expression to take the address of a local -/// &localv -val mkValAddr : range -> readonly: bool -> ValRef -> Expr - -/// Build an expression representing the read of an instance class or record field. -/// First take the address of the record expression if it is a struct. -val mkRecdFieldGet : TcGlobals -> Expr * RecdFieldRef * TypeInst * range -> Expr - -/// Accumulate the targets actually used in a decision graph (for reporting warnings) -val accTargetsOfDecisionTree : DecisionTree -> int list -> int list - -/// Make a 'match' expression applying some peep-hole optimizations along the way, e.g to -/// pre-decide the branch taken at compile-time. -val mkAndSimplifyMatch : SequencePointInfoForBinding -> range -> range -> TType -> DecisionTree -> DecisionTreeTarget list -> Expr - -/// Make a 'match' expression without applying any peep-hole optimizations. -val primMkMatch : SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget array * range * TType -> Expr - -/// Work out what things on the right-han-side of a 'let rec' recursive binding need to be fixed up -val IterateRecursiveFixups : - TcGlobals -> Val option -> - (Val option -> Expr -> (Expr -> Expr) -> Expr -> unit) -> - Expr * (Expr -> Expr) -> Expr -> unit - -/// Given a lambda expression taking multiple variables, build a corresponding lambda taking a tuple -val MultiLambdaToTupledLambda : TcGlobals -> Val list -> Expr -> Val * Expr - -/// Given a lambda expression, adjust it to have be one or two lambda expressions (fun a -> (fun b -> ...)) -/// where the first has the given arity. -val AdjustArityOfLambdaBody : TcGlobals -> int -> Val list -> Expr -> Val list * Expr - -/// Make an application expression, doing beta reduction by introducing let-bindings -val MakeApplicationAndBetaReduce : TcGlobals -> Expr * TType * TypeInst list * Exprs * range -> Expr - -/// Combine two static-resolution requirements on a type parameter -val JoinTyparStaticReq : TyparStaticReq -> TyparStaticReq -> TyparStaticReq - -/// Layout for internal compiler debugging purposes -module DebugPrint = - - /// A global flag indicating whether debug output should include ranges - val layoutRanges : bool ref - - /// Convert a type to a string for debugging purposes - val showType : TType -> string - - /// Convert an expression to a string for debugging purposes - val showExpr : TcGlobals -> Expr -> string - - /// Debug layout for a reference to a value - val valRefL : ValRef -> layout - - /// Debug layout for a reference to a union case - val unionCaseRefL : UnionCaseRef -> layout - - /// Debug layout for an value definition at its binding site - val valAtBindL : TcGlobals -> Val -> layout - - /// Debug layout for an integer - val intL : int -> layout - - /// Debug layout for a value definition - val valL : Val -> layout - - /// Debug layout for a type parameter definition - val typarDeclL : Typar -> layout - - /// Debug layout for a trait constraint - val traitL : TraitConstraintInfo -> layout - - /// Debug layout for a type parameter - val typarL : Typar -> layout - - /// Debug layout for a set of type parameters - val typarsL : Typars -> layout - - /// Debug layout for a type - val typeL : TType -> layout - - /// Debug layout for a method slot signature - val slotSigL : SlotSig -> layout - - /// Debug layout for the type signature of a module or namespace definition - val entityTypeL : TcGlobals -> ModuleOrNamespaceType -> layout - - /// Debug layout for a module or namespace definition - val entityL : TcGlobals -> ModuleOrNamespace -> layout - - /// Debug layout for the type of a value - val typeOfValL : Val -> layout - - /// Debug layout for a binding of an expression to a value - val bindingL : TcGlobals -> Binding -> layout - - /// Debug layout for an expression - val exprL : TcGlobals -> Expr -> layout - - /// Debug layout for a type definition - val tyconL : TcGlobals -> Tycon -> layout - - /// Debug layout for a decision tree - val decisionTreeL : TcGlobals -> DecisionTree -> layout - - /// Debug layout for an implementation file - val implFileL : TcGlobals -> TypedImplFile -> layout - - /// Debug layout for a list of implementation files - val implFilesL : TcGlobals -> TypedImplFile list -> layout - - /// Debug layout for class and record fields - val recdFieldRefL : RecdFieldRef -> layout - -/// A set of function parameters (visitor) for folding over expressions -type ExprFolder<'State> = - { exprIntercept : (* recurseF *) ('State -> Expr -> 'State) -> (* noInterceptF *) ('State -> Expr -> 'State) -> 'State -> Expr -> 'State - valBindingSiteIntercept : 'State -> bool * Val -> 'State - nonRecBindingsIntercept : 'State -> Binding -> 'State - recBindingsIntercept : 'State -> Bindings -> 'State - dtreeIntercept : 'State -> DecisionTree -> 'State - targetIntercept : ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option - tmethodIntercept : ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option} - -/// The empty set of actions for folding over expressions -val ExprFolder0 : ExprFolder<'State> - -/// Fold over all the expressions in an implementation file -val FoldImplFile: ExprFolder<'State> -> ('State -> TypedImplFile -> 'State) - -/// Fold over all the expressions in an expression -val FoldExpr : ExprFolder<'State> -> ('State -> Expr -> 'State) - -#if DEBUG -/// Extract some statistics from an expression -val ExprStats : Expr -> string -#endif - -/// Build a nativeptr type -val mkNativePtrTy : TcGlobals -> TType -> TType - -/// Build a 'voidptr' type -val mkVoidPtrTy : TcGlobals -> TType - -/// Build a single-dimensional array type -val mkArrayType : TcGlobals -> TType -> TType - -/// Determine if a type is an option type -val isOptionTy : TcGlobals -> TType -> bool - -/// Take apart an option type -val destOptionTy : TcGlobals -> TType -> TType - -/// Try to take apart an option type -val tryDestOptionTy : TcGlobals -> TType -> ValueOption - -/// Determine is a type is a System.Nullable type -val isNullableTy : TcGlobals -> TType -> bool - -/// Try to take apart a System.Nullable type -val tryDestNullableTy: TcGlobals -> TType -> ValueOption - -/// Take apart a System.Nullable type -val destNullableTy: TcGlobals -> TType -> TType - -/// Determine if a type is a System.Linq.Expression type -val isLinqExpressionTy : TcGlobals -> TType -> bool - -/// Take apart a System.Linq.Expression type -val destLinqExpressionTy : TcGlobals -> TType -> TType - -/// Try to take apart a System.Linq.Expression type -val tryDestLinqExpressionTy : TcGlobals -> TType -> TType option - -/// Determine if a type is an IDelegateEvent type -val isIDelegateEventType : TcGlobals -> TType -> bool - -/// Take apart an IDelegateEvent type -val destIDelegateEventType : TcGlobals -> TType -> TType - -/// Build an IEvent type -val mkIEventType : TcGlobals -> TType -> TType -> TType - -/// Build an IObservable type -val mkIObservableType : TcGlobals -> TType -> TType - -/// Build an IObserver type -val mkIObserverType : TcGlobals -> TType -> TType - -/// Build an Lazy type -val mkLazyTy : TcGlobals -> TType -> TType - -/// Build an PrintFormat type -val mkPrintfFormatTy : TcGlobals -> TType -> TType -> TType -> TType -> TType -> TType - -//------------------------------------------------------------------------- -// Classify types -//------------------------------------------------------------------------- - -/// Represents metadata extracted from a nominal type -type TypeDefMetadata = - | ILTypeMetadata of TILObjectReprData - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata of TProvidedTypeInfo -#endif - -/// Extract metadata from a type definition -val metadataOfTycon : Tycon -> TypeDefMetadata - -/// Extract metadata from a type -val metadataOfTy : TcGlobals -> TType -> TypeDefMetadata - -/// Determine if a type is the System.String type -val isStringTy : TcGlobals -> TType -> bool - -/// Determine if a type is an F# list type -val isListTy : TcGlobals -> TType -> bool - -/// Determine if a type is a nominal .NET type -val isILAppTy : TcGlobals -> TType -> bool - -/// Determine if a type is any kind of array type -val isArrayTy : TcGlobals -> TType -> bool - -/// Determine if a type is a single-dimensional array type -val isArray1DTy : TcGlobals -> TType -> bool - -/// Get the element type of an array type -val destArrayTy : TcGlobals -> TType -> TType - -/// Get the element type of an F# list type -val destListTy : TcGlobals -> TType -> TType - -/// Build an array type of the given rank -val mkArrayTy : TcGlobals -> int -> TType -> range -> TType - -/// Check if a type definition is one of the artificial type definitions used for array types of different ranks -val isArrayTyconRef : TcGlobals -> TyconRef -> bool - -/// Determine the rank of one of the artificial type definitions used for array types -val rankOfArrayTyconRef : TcGlobals -> TyconRef -> int - -/// Determine if a type is the F# unit type -val isUnitTy : TcGlobals -> TType -> bool - -/// Determine if a type is the System.Object type -val isObjTy : TcGlobals -> TType -> bool - -/// Determine if a type is the System.Void type -val isVoidTy : TcGlobals -> TType -> bool - -/// Get the element type of an array type -val destArrayTy : TcGlobals -> TType -> TType - -/// Get the rank of an array type -val rankOfArrayTy : TcGlobals -> TType -> int - -/// Determine if a reference to a type definition is an interface type -val isInterfaceTyconRef : TyconRef -> bool - -/// Determine if a type is a delegate type -val isDelegateTy : TcGlobals -> TType -> bool - -/// Determine if a type is an interface type -val isInterfaceTy : TcGlobals -> TType -> bool - -/// Determine if a type is a FSharpRef type -val isRefTy : TcGlobals -> TType -> bool - -/// Determine if a type is a sealed type -val isSealedTy : TcGlobals -> TType -> bool - -/// Determine if a type is a ComInterop type -val isComInteropTy : TcGlobals -> TType -> bool - -/// Determine the underlying type of an enum type (normally int32) -val underlyingTypeOfEnumTy : TcGlobals -> TType -> TType - -/// If the input type is an enum type, then convert to its underlying type, otherwise return the input type -val normalizeEnumTy : TcGlobals -> TType -> TType - -/// Determine if a type is a struct type -val isStructTy : TcGlobals -> TType -> bool - -/// Determine if a type is an unmanaged type -val isUnmanagedTy : TcGlobals -> TType -> bool - -/// Determine if a type is a class type -val isClassTy : TcGlobals -> TType -> bool - -/// Determine if a type is an enum type -val isEnumTy : TcGlobals -> TType -> bool - -/// Determine if a type is a struct, record or union type -val isStructRecordOrUnionTyconTy : TcGlobals -> TType -> bool - -/// For "type Class as self", 'self' is fixed up after initialization. To support this, -/// it is converted behind the scenes to a ref. This function strips off the ref and -/// returns the underlying type. -val StripSelfRefCell : TcGlobals * ValBaseOrThisInfo * TType -> TType - -/// An active pattern to determine if a type is a nominal type, possibly instantiated -val (|AppTy|_|) : TcGlobals -> TType -> (TyconRef * TType list) option - -/// An active pattern to match System.Nullable types -val (|NullableTy|_|) : TcGlobals -> TType -> TType option - -/// An active pattern to transform System.Nullable types to their input, otherwise leave the input unchanged -val (|StripNullableTy|) : TcGlobals -> TType -> TType - -/// Matches any byref type, yielding the target type -val (|ByrefTy|_|) : TcGlobals -> TType -> TType option - -//------------------------------------------------------------------------- -// Special semantic constraints -//------------------------------------------------------------------------- - -val IsUnionTypeWithNullAsTrueValue: TcGlobals -> Tycon -> bool - -val TyconHasUseNullAsTrueValueAttribute : TcGlobals -> Tycon -> bool - -val CanHaveUseNullAsTrueValueAttribute : TcGlobals -> Tycon -> bool - -val MemberIsCompiledAsInstance : TcGlobals -> TyconRef -> bool -> ValMemberInfo -> Attribs -> bool - -val ValSpecIsCompiledAsInstance : TcGlobals -> Val -> bool - -val ValRefIsCompiledAsInstanceMember : TcGlobals -> ValRef -> bool - -val ModuleNameIsMangled : TcGlobals -> Attribs -> bool - -val CompileAsEvent : TcGlobals -> Attribs -> bool - -val TypeNullIsExtraValue : TcGlobals -> range -> TType -> bool - -val TypeNullIsTrueValue : TcGlobals -> TType -> bool - -val TypeNullNotLiked : TcGlobals -> range -> TType -> bool - -val TypeNullNever : TcGlobals -> TType -> bool - -val TypeSatisfiesNullConstraint : TcGlobals -> range -> TType -> bool - -val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool - -val isAbstractTycon : Tycon -> bool - -val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> bool - -val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TyconRef -> bool - -val isExnDefinitelyMutable : TyconRef -> bool - -val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool - -val isExnFieldMutable : TyconRef -> int -> bool - -val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool - -val isRecdOrStructTyconRefAssumedImmutable: TcGlobals -> TyconRef -> bool - -val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool - -val useGenuineField : Tycon -> RecdField -> bool - -val ComputeFieldName : Tycon -> RecdField -> string - -//------------------------------------------------------------------------- -// Destruct slotsigs etc. -//------------------------------------------------------------------------- - -val slotSigHasVoidReturnTy : SlotSig -> bool - -val actualReturnTyOfSlotSig : TypeInst -> TypeInst -> SlotSig -> TType option - -val returnTyOfMethod : TcGlobals -> ObjExprMethod -> TType option - -//------------------------------------------------------------------------- -// Primitives associated with initialization graphs -//------------------------------------------------------------------------- - -val mkRefCell : TcGlobals -> range -> TType -> Expr -> Expr - -val mkRefCellGet : TcGlobals -> range -> TType -> Expr -> Expr - -val mkRefCellSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkLazyDelayed : TcGlobals -> range -> TType -> Expr -> Expr - -val mkLazyForce : TcGlobals -> range -> TType -> Expr -> Expr - -val mkRefCellContentsRef : TcGlobals -> RecdFieldRef - -val isRefCellTy : TcGlobals -> TType -> bool - -val destRefCellTy : TcGlobals -> TType -> TType - -val mkRefCellTy : TcGlobals -> TType -> TType - -val mkSeqTy : TcGlobals -> TType -> TType - -val mkIEnumeratorTy : TcGlobals -> TType -> TType - -val mkListTy : TcGlobals -> TType -> TType - -val mkOptionTy : TcGlobals -> TType -> TType - -val mkNoneCase : TcGlobals -> UnionCaseRef - -val mkSomeCase : TcGlobals -> UnionCaseRef - -val mkNil : TcGlobals -> range -> TType -> Expr - -val mkCons : TcGlobals -> TType -> Expr -> Expr -> Expr - -val mkSome : TcGlobals -> TType -> Expr -> range -> Expr - -val mkNone: TcGlobals -> TType -> range -> Expr - -//------------------------------------------------------------------------- -// Make a few more expressions -//------------------------------------------------------------------------- - -val mkSequential : SequencePointInfoForSeq -> range -> Expr -> Expr -> Expr - -val mkCompGenSequential : range -> Expr -> Expr -> Expr - -val mkSequentials : SequencePointInfoForSeq -> TcGlobals -> range -> Exprs -> Expr - -val mkRecordExpr : TcGlobals -> RecordConstructionInfo * TyconRef * TypeInst * RecdFieldRef list * Exprs * range -> Expr - -val mkUnbox : TType -> Expr -> range -> Expr - -val mkBox : TType -> Expr -> range -> Expr - -val mkIsInst : TType -> Expr -> range -> Expr - -val mkNull : range -> TType -> Expr - -val mkNullTest : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr - -val mkNonNullTest : TcGlobals -> range -> Expr -> Expr - -val mkIsInstConditional : TcGlobals -> range -> TType -> Expr -> Val -> Expr -> Expr -> Expr - -val mkThrow : range -> TType -> Expr -> Expr - -val mkGetArg0 : range -> TType -> Expr - -val mkDefault : range * TType -> Expr - -val isThrow : Expr -> bool - -val mkString : TcGlobals -> range -> string -> Expr - -val mkBool : TcGlobals -> range -> bool -> Expr - -val mkByte : TcGlobals -> range -> byte -> Expr - -val mkUInt16 : TcGlobals -> range -> uint16 -> Expr - -val mkTrue : TcGlobals -> range -> Expr - -val mkFalse : TcGlobals -> range -> Expr - -val mkUnit : TcGlobals -> range -> Expr - -val mkInt32 : TcGlobals -> range -> int32 -> Expr - -val mkInt : TcGlobals -> range -> int -> Expr - -val mkZero : TcGlobals -> range -> Expr - -val mkOne : TcGlobals -> range -> Expr - -val mkTwo : TcGlobals -> range -> Expr - -val mkMinusOne : TcGlobals -> range -> Expr - -val destInt32 : Expr -> int32 option - -//------------------------------------------------------------------------- -// Primitives associated with quotations -//------------------------------------------------------------------------- - -val isQuotedExprTy : TcGlobals -> TType -> bool - -val destQuotedExprTy : TcGlobals -> TType -> TType - -val mkQuotedExprTy : TcGlobals -> TType -> TType - -val mkRawQuotedExprTy : TcGlobals -> TType - -//------------------------------------------------------------------------- -// Primitives associated with IL code gen -//------------------------------------------------------------------------- - -val mspec_Type_GetTypeFromHandle : TcGlobals -> ILMethodSpec - -val fspec_Missing_Value : TcGlobals -> ILFieldSpec - -val mkInitializeArrayMethSpec: TcGlobals -> ILMethodSpec - -val mkByteArrayTy : TcGlobals -> TType - -val mkInvalidCastExnNewobj: TcGlobals -> ILInstr - - -//------------------------------------------------------------------------- -// Construct calls to some intrinsic functions -//------------------------------------------------------------------------- - -val mkCallNewFormat : TcGlobals -> range -> TType -> TType -> TType -> TType -> TType -> Expr -> Expr - -val mkCallUnbox : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallGetGenericComparer : TcGlobals -> range -> Expr - -val mkCallGetGenericEREqualityComparer : TcGlobals -> range -> Expr - -val mkCallGetGenericPEREqualityComparer : TcGlobals -> range -> Expr - -val mkCallUnboxFast : TcGlobals -> range -> TType -> Expr -> Expr - -val canUseUnboxFast : TcGlobals -> range -> TType -> bool - -val mkCallDispose : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeq : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallTypeTest : TcGlobals -> range -> TType -> Expr -> Expr - -val canUseTypeTestFast : TcGlobals -> TType -> bool - -val mkCallTypeOf : TcGlobals -> range -> TType -> Expr - -val mkCallTypeDefOf : TcGlobals -> range -> TType -> Expr - -val mkCallCreateInstance : TcGlobals -> range -> TType -> Expr - -val mkCallCreateEvent : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallArrayLength : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallArrayGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallArray2DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallArray3DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallArray4DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallArraySet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallArray2DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallArray3DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallArray4DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallHash : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallBox : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallIsNull : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallIsNotNull : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallRaise : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallGenericComparisonWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallGenericEqualityEROuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallGenericEqualityWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallGenericHashWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallNotEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallLessThanOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallLessThanOrEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallGreaterThanOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallGreaterThanOrEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallAdditionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallSubtractionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallMultiplyOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallDivisionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallModulusOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallBitwiseAndOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallBitwiseOrOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallBitwiseXorOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallShiftLeftOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallShiftRightOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallUnaryNegOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallUnaryNotOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallAdditionChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallSubtractionChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallMultiplyChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallUnaryNegChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToByteChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToSByteChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt16Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt16Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToIntChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt32Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt32Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt64Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt64Checked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToIntPtrChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUIntPtrChecked : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToByteOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToSByteOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt16Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt16Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToIntOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt32Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt32Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToInt64Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUInt64Operator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToSingleOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToDoubleOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToIntPtrOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToUIntPtrOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToCharOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallToEnumOperator : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallDeserializeQuotationFSharp20Plus : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallDeserializeQuotationFSharp40Plus : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkCallCastQuotation : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallLiftValueWithName : TcGlobals -> range -> TType -> string -> Expr -> Expr - -val mkCallLiftValueWithDefn : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeqCollect : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr - -val mkCallSeqUsing : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr - -val mkCallSeqDelay : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeqAppend : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallSeqFinally : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallSeqGenerated : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -val mkCallSeqOfFunctions : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr - -val mkCallSeqToArray : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeqToList : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeqMap : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr - -val mkCallSeqSingleton : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallSeqEmpty : TcGlobals -> range -> TType -> Expr - -val mkILAsmCeq : TcGlobals -> range -> Expr -> Expr -> Expr - -val mkILAsmClt : TcGlobals -> range -> Expr -> Expr -> Expr - -val mkCallFailInit : TcGlobals -> range -> Expr - -val mkCallFailStaticInit : TcGlobals -> range -> Expr - -val mkCallCheckThis : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCase : DecisionTreeTest * DecisionTree -> DecisionTreeCase - -val mkCallQuoteToLinqLambdaExpression : TcGlobals -> range -> TType -> Expr -> Expr - -val mkCallGetQuerySourceAsEnumerable : TcGlobals -> range -> TType -> TType -> Expr -> Expr - -val mkCallNewQuerySource : TcGlobals -> range -> TType -> TType -> Expr -> Expr - -val mkArray : TType * Exprs * range -> Expr - -val mkStaticCall_String_Concat2 : TcGlobals -> range -> Expr -> Expr -> Expr - -val mkStaticCall_String_Concat3 : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr - -val mkStaticCall_String_Concat4 : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr - -val mkStaticCall_String_Concat_Array : TcGlobals -> range -> Expr -> Expr - -//------------------------------------------------------------------------- -// operations primarily associated with the optimization to fix -// up loops to generate .NET code that does not include array bound checks -//------------------------------------------------------------------------- - -val mkDecr : TcGlobals -> range -> Expr -> Expr - -val mkIncr : TcGlobals -> range -> Expr -> Expr - -val mkLdlen : TcGlobals -> range -> Expr -> Expr - -val mkLdelem : TcGlobals -> range -> TType -> Expr -> Expr -> Expr - -//------------------------------------------------------------------------- -// Analyze attribute sets -//------------------------------------------------------------------------- - -val TryDecodeILAttribute : TcGlobals -> ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option - -val TryFindILAttribute : BuiltinAttribInfo -> ILAttributes -> bool - -val TryFindILAttributeOpt : BuiltinAttribInfo option -> ILAttributes -> bool - -val IsMatchingFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attrib -> bool - -val IsMatchingFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attrib -> bool - -val HasFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool - -val HasFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attribs -> bool - -val TryFindFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> Attrib option - -val TryFindFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attribs -> Attrib option - -val TryFindFSharpBoolAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option - -val TryFindFSharpBoolAttributeAssumeFalse : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option - -val TryFindFSharpStringAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> string option - -val TryFindFSharpInt32Attribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> int32 option - -/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. -/// -/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions) -val TryFindTyconRefStringAttribute : TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> string option - -/// Try to find a specific attribute on a type definition, where the attribute accepts a bool argument. -val TryFindTyconRefBoolAttribute : TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> bool option - -/// Try to find a specific attribute on a type definition -val TyconRefHasAttribute : TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> bool - -/// Try to find the AttributeUsage attribute, looking for the value of the AllowMultiple named parameter -val TryFindAttributeUsageAttribute : TcGlobals -> range -> TyconRef -> bool option - -#if !NO_EXTENSIONTYPING -/// returns Some(assemblyName) for success -val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option -#endif - -val IsSignatureDataVersionAttr : ILAttribute -> bool - -val TryFindAutoOpenAttr : IL.ILGlobals -> ILAttribute -> string option - -val TryFindInternalsVisibleToAttr : IL.ILGlobals -> ILAttribute -> string option - -val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool - -val mkCompilationMappingAttr : TcGlobals -> int -> ILAttribute -val mkCompilationMappingAttrWithSeqNum : TcGlobals -> int -> int -> ILAttribute - - -val mkCompilationMappingAttrWithVariantNumAndSeqNum : TcGlobals -> int -> int -> int -> ILAttribute - -val mkCompilationMappingAttrForQuotationResource : TcGlobals -> string * ILTypeRef list -> ILAttribute - -val mkCompilationArgumentCountsAttr : TcGlobals -> int list -> ILAttribute - -val mkCompilationSourceNameAttr : TcGlobals -> string -> ILAttribute - -val mkSignatureDataVersionAttr : TcGlobals -> ILVersionInfo -> ILAttribute - -val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAttribute - -//------------------------------------------------------------------------- -// More common type construction -//------------------------------------------------------------------------- - -val isInByrefTy : TcGlobals -> TType -> bool - -val isOutByrefTy : TcGlobals -> TType -> bool - -val isByrefTy : TcGlobals -> TType -> bool - -val isNativePtrTy : TcGlobals -> TType -> bool - -val destByrefTy : TcGlobals -> TType -> TType - -val destNativePtrTy : TcGlobals -> TType -> TType - -val isByrefTyconRef : TcGlobals -> TyconRef -> bool - -val isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool - -val isSpanLikeTyconRef : TcGlobals -> range -> TyconRef -> bool - -val isByrefLikeTy : TcGlobals -> range -> TType -> bool - -/// Check if the type is a byref-like but not a byref. -val isSpanLikeTy : TcGlobals -> range -> TType -> bool - -val isSpanTy : TcGlobals -> range -> TType -> bool - -val tryDestSpanTy : TcGlobals -> range -> TType -> struct(TyconRef * TType) voption - -val destSpanTy : TcGlobals -> range -> TType -> struct(TyconRef * TType) - -val isReadOnlySpanTy : TcGlobals -> range -> TType -> bool - -val tryDestReadOnlySpanTy : TcGlobals -> range -> TType -> struct(TyconRef * TType) voption - -val destReadOnlySpanTy : TcGlobals -> range -> TType -> struct(TyconRef * TType) - -//------------------------------------------------------------------------- -// Tuple constructors/destructors -//------------------------------------------------------------------------- - -val isRefTupleExpr : Expr -> bool - -val tryDestRefTupleExpr : Expr -> Exprs - -val mkAnyTupledTy : TcGlobals -> TupInfo -> TType list -> TType - -val mkAnyTupled : TcGlobals -> range -> TupInfo -> Exprs -> TType list -> Expr - -val mkRefTupled : TcGlobals -> range -> Exprs -> TType list -> Expr - -val mkRefTupledNoTypes : TcGlobals -> range -> Exprs -> Expr - -val mkRefTupledTy : TcGlobals -> TType list -> TType - -val mkRefTupledVarsTy : TcGlobals -> Val list -> TType - -val mkRefTupledVars : TcGlobals -> range -> Val list -> Expr - -val mkMethodTy : TcGlobals -> TType list list -> TType -> TType - -val mkAnyAnonRecdTy : TcGlobals -> AnonRecdTypeInfo -> TType list -> TType - -val mkAnonRecd : TcGlobals -> range -> AnonRecdTypeInfo -> Ident[] -> Exprs -> TType list -> Expr - -val AdjustValForExpectedArity : TcGlobals -> range -> ValRef -> ValUseFlag -> ValReprInfo -> Expr * TType - -val AdjustValToTopVal : Val -> ParentRef -> ValReprInfo -> unit - -val LinearizeTopMatch : TcGlobals -> ParentRef -> Expr -> Expr - -val AdjustPossibleSubsumptionExpr : TcGlobals -> Expr -> Exprs -> (Expr * Exprs) option - -val NormalizeAndAdjustPossibleSubsumptionExprs : TcGlobals -> Expr -> Expr - -//------------------------------------------------------------------------- -// XmlDoc signatures, used by both VS mode and XML-help emit -//------------------------------------------------------------------------- - -val buildAccessPath : CompilationPath option -> string - -val XmlDocArgsEnc : TcGlobals -> Typars * Typars -> TType list -> string - -val XmlDocSigOfVal : TcGlobals -> string -> Val -> string - -val XmlDocSigOfUnionCase : (string list -> string) - -val XmlDocSigOfField : (string list -> string) - -val XmlDocSigOfProperty : (string list -> string) - -val XmlDocSigOfTycon : (string list -> string) - -val XmlDocSigOfSubModul : (string list -> string) - -val XmlDocSigOfEntity : EntityRef -> string - -//--------------------------------------------------------------------------- -// Resolve static optimizations -//------------------------------------------------------------------------- - -type StaticOptimizationAnswer = - | Yes = 1y - | No = -1y - | Unknown = 0y - -val DecideStaticOptimizations : TcGlobals -> StaticOptimization list -> StaticOptimizationAnswer - -val mkStaticOptimizationExpr : TcGlobals -> StaticOptimization list * Expr * Expr * range -> Expr - -/// Build for loops -val mkFastForLoop : TcGlobals -> SequencePointInfoForForLoop * range * Val * Expr * bool * Expr * Expr -> Expr - -//--------------------------------------------------------------------------- -// Active pattern helpers -//------------------------------------------------------------------------- - -type ActivePatternElemRef with - member Name : string - -val TryGetActivePatternInfo : ValRef -> PrettyNaming.ActivePatternInfo option - -val mkChoiceCaseRef : TcGlobals -> range -> int -> int -> UnionCaseRef - -type PrettyNaming.ActivePatternInfo with - - member Names : string list - - member ResultType : TcGlobals -> range -> TType list -> TType - - member OverallType : TcGlobals -> range -> TType -> TType list -> TType - -val doesActivePatternHaveFreeTypars : TcGlobals -> ValRef -> bool - -//--------------------------------------------------------------------------- -// Structural rewrites -//------------------------------------------------------------------------- - -[] -type ExprRewritingEnv = - { PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option - PostTransform: Expr -> Expr option - PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option - IsUnderQuotations: bool } - -val RewriteExpr : ExprRewritingEnv -> Expr -> Expr - -val RewriteImplFile : ExprRewritingEnv -> TypedImplFile -> TypedImplFile - -val IsGenericValWithGenericConstraints: TcGlobals -> Val -> bool - -type Entity with - - member HasInterface : TcGlobals -> TType -> bool - - member HasOverride : TcGlobals -> string -> TType list -> bool - - member HasMember : TcGlobals -> string -> TType list -> bool - -type EntityRef with - - member HasInterface : TcGlobals -> TType -> bool - - member HasOverride : TcGlobals -> string -> TType list -> bool - - member HasMember : TcGlobals -> string -> TType list -> bool - -val (|AttribBitwiseOrExpr|_|) : TcGlobals -> Expr -> (Expr * Expr) option - -val (|EnumExpr|_|) : TcGlobals -> Expr -> Expr option - -val (|TypeOfExpr|_|) : TcGlobals -> Expr -> TType option - -val (|TypeDefOfExpr|_|) : TcGlobals -> Expr -> TType option -val (|NameOfExpr|_|) : TcGlobals -> Expr -> TType option -val (|SeqExpr|_|) : TcGlobals -> Expr -> unit option - -val EvalLiteralExprOrAttribArg: TcGlobals -> Expr -> Expr - -val EvaledAttribExprEquality : TcGlobals -> Expr -> Expr -> bool - -val IsSimpleSyntacticConstantExpr: TcGlobals -> Expr -> bool - -val (|ConstToILFieldInit|_|): Const -> ILFieldInit option - -val (|ExtractAttribNamedArg|_|) : string -> AttribNamedArg list -> AttribExpr option - -val (|AttribInt32Arg|_|) : AttribExpr -> int32 option - -val (|AttribInt16Arg|_|) : AttribExpr -> int16 option - -val (|AttribBoolArg|_|) : AttribExpr -> bool option - -val (|AttribStringArg|_|) : AttribExpr -> string option - -val (|Int32Expr|_|) : Expr -> int32 option - - -/// Determines types that are potentially known to satisfy the 'comparable' constraint and returns -/// a set of residual types that must also satisfy the constraint -val (|SpecialComparableHeadType|_|) : TcGlobals -> TType -> TType list option - -val (|SpecialEquatableHeadType|_|) : TcGlobals -> TType -> TType list option - -val (|SpecialNotEquatableHeadType|_|) : TcGlobals -> TType -> unit option - -type OptimizeForExpressionOptions = OptimizeIntRangesOnly | OptimizeAllForExpressions - -val DetectAndOptimizeForExpression : TcGlobals -> OptimizeForExpressionOptions -> Expr -> Expr - -val TryEliminateDesugaredConstants : TcGlobals -> range -> Const -> Expr option - -val MemberIsExplicitImpl : TcGlobals -> ValMemberInfo -> bool - -val ValIsExplicitImpl : TcGlobals -> Val -> bool - -val ValRefIsExplicitImpl : TcGlobals -> ValRef -> bool - -val (|LinearMatchExpr|_|) : Expr -> (SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget * Expr * SequencePointInfoForTarget * range * TType) option - -val rebuildLinearMatchExpr : (SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget * Expr * SequencePointInfoForTarget * range * TType) -> Expr - -val (|LinearOpExpr|_|) : Expr -> (TOp * TypeInst * Expr list * Expr * range) option - -val rebuildLinearOpExpr : (TOp * TypeInst * Expr list * Expr * range) -> Expr - -val mkCoerceIfNeeded : TcGlobals -> tgtTy: TType -> srcTy: TType -> Expr -> Expr - -val (|InnerExprPat|) : Expr -> Expr - -val allValsOfModDef : ModuleOrNamespaceExpr -> seq - -val BindUnitVars : TcGlobals -> (Val list * ArgReprInfo list * Expr) -> Val list * Expr - -val isThreadOrContextStatic: TcGlobals -> Attrib list -> bool - -val mkUnitDelayLambda: TcGlobals -> range -> Expr -> Expr - -val isStaticClass: g: TcGlobals -> tcref: TyconRef -> bool \ No newline at end of file diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs deleted file mode 100644 index ffdf31efbdf..00000000000 --- a/src/fsharp/TastPickle.fs +++ /dev/null @@ -1,2725 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.TastPickle - -open System.Collections.Generic -open System.Text -open Internal.Utilities -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib -open FSharp.Compiler.Lib.Bits -open FSharp.Compiler.Range -open FSharp.Compiler.Rational -open FSharp.Compiler.Ast -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.ErrorLogger - - -let verbose = false - -let ffailwith fileName str = - let msg = FSComp.SR.pickleErrorReadingWritingMetadata(fileName, str) - System.Diagnostics.Debug.Assert(false, msg) - failwith msg - - -// Fixup pickled data w.r.t. a set of CCU thunks indexed by name -[] -type PickledDataWithReferences<'rawData> = - { /// The data that uses a collection of CcuThunks internally - RawData: 'rawData - /// The assumptions that need to be fixed up - FixupThunks: CcuThunk [] } - - member x.Fixup loader = - x.FixupThunks |> Array.iter (fun reqd -> reqd.Fixup(loader reqd.AssemblyName)) - x.RawData - - /// Like Fixup but loader may return None, in which case there is no fixup. - member x.OptionalFixup loader = - x.FixupThunks - |> Array.iter(fun reqd-> - match loader reqd.AssemblyName with - | Some loaded -> reqd.Fixup loaded - | None -> reqd.FixupOrphaned() ) - x.RawData - - -//--------------------------------------------------------------------------- -// Basic pickle/unpickle state -//--------------------------------------------------------------------------- - -[] -type Table<'T> = - { name: string - tbl: Dictionary<'T, int> - mutable rows: ResizeArray<'T> - mutable count: int } - member tbl.AsArray = Seq.toArray tbl.rows - member tbl.Size = tbl.rows.Count - member tbl.Add x = - let n = tbl.count - tbl.count <- tbl.count + 1 - tbl.tbl.[x] <- n - tbl.rows.Add x - n - member tbl.FindOrAdd x = - match tbl.tbl.TryGetValue x with - | true, res -> res - | _ -> tbl.Add x - - - static member Create n = - { name = n - tbl = new System.Collections.Generic.Dictionary<_, _>(1000, HashIdentity.Structural) - rows= new ResizeArray<_>(1000) - count=0 } - -[] -type InputTable<'T> = - { itbl_name: string - itbl_rows: 'T array } - -let new_itbl n r = { itbl_name=n; itbl_rows=r } - -[] -type NodeOutTable<'Data, 'Node> = - { NodeStamp : ('Node -> Stamp) - NodeName : ('Node -> string) - GetRange : ('Node -> range) - Deref: ('Node -> 'Data) - Name: string - Table: Table } - member x.Size = x.Table.Size - - // inline this to get known-type-information through to the HashMultiMap constructor - static member inline Create (stampF, nameF, rangeF, derefF, nm) = - { NodeStamp = stampF - NodeName = nameF - GetRange = rangeF - Deref = derefF - Name = nm - Table = Table<_>.Create nm } - -[] -type WriterState = - { os: ByteBuffer - oscope: CcuThunk - occus: Table - oentities: NodeOutTable - otypars: NodeOutTable - ovals: NodeOutTable - oanoninfos: NodeOutTable - ostrings: Table - opubpaths: Table - onlerefs: Table - osimpletys: Table - oglobals : TcGlobals - mutable isStructThisArgPos : bool - ofile : string - /// Indicates if we are using in-memory format, where we store XML docs as well - oInMem : bool - } -let pfailwith st str = ffailwith st.ofile str - -[] -type NodeInTable<'Data, 'Node> = - { LinkNode : ('Node -> 'Data -> unit) - IsLinked : ('Node -> bool) - Name : string - Nodes : 'Node[] } - member x.Get n = x.Nodes.[n] - member x.Count = x.Nodes.Length - - static member Create (mkEmpty, lnk, isLinked, nm, n) = - { LinkNode = lnk; IsLinked = isLinked; Name = nm; Nodes = Array.init n (fun _i -> mkEmpty() ) } - -[] -type ReaderState = - { is: ByteStream - iilscope: ILScopeRef - iccus: InputTable - ientities: NodeInTable - itypars: NodeInTable - ivals: NodeInTable - ianoninfos: NodeInTable - istrings: InputTable - ipubpaths: InputTable - inlerefs: InputTable - isimpletys: InputTable - ifile: string - iILModule : ILModuleDef option // the Abstract IL metadata for the DLL being read - } - -let ufailwith st str = ffailwith st.ifile str - -//--------------------------------------------------------------------------- -// Basic pickle/unpickle operations -//--------------------------------------------------------------------------- - -type 'T pickler = 'T -> WriterState -> unit - -let p_byte b st = st.os.EmitIntAsByte b -let p_bool b st = p_byte (if b then 1 else 0) st -let prim_p_int32 i st = - p_byte (b0 i) st - p_byte (b1 i) st - p_byte (b2 i) st - p_byte (b3 i) st - -/// Compress integers according to the same scheme used by CLR metadata -/// This halves the size of pickled data -let p_int32 n st = - if n >= 0 && n <= 0x7F then - p_byte (b0 n) st - else if n >= 0x80 && n <= 0x3FFF then - p_byte ( (0x80 ||| (n >>> 8))) st - p_byte ( (n &&& 0xFF)) st - else - p_byte 0xFF st - prim_p_int32 n st - -let space = () -let p_space n () st = - for i = 0 to n - 1 do - p_byte 0 st - -/// Represents space that was reserved but is now possibly used -let p_used_space1 f st = - p_byte 1 st - f st - // leave more space - p_space 1 space st - -let p_bytes (s: byte[]) st = - let len = s.Length - p_int32 len st - st.os.EmitBytes s - -let p_prim_string (s: string) st = - let bytes = Encoding.UTF8.GetBytes s - let len = bytes.Length - p_int32 len st - st.os.EmitBytes bytes - -let p_int c st = p_int32 c st -let p_int8 (i: sbyte) st = p_int32 (int32 i) st -let p_uint8 (i: byte) st = p_byte (int i) st -let p_int16 (i: int16) st = p_int32 (int32 i) st -let p_uint16 (x: uint16) st = p_int32 (int32 x) st -let p_uint32 (x: uint32) st = p_int32 (int32 x) st -let p_int64 (i: int64) st = - p_int32 (int32 (i &&& 0xFFFFFFFFL)) st - p_int32 (int32 (i >>> 32)) st - -let p_uint64 (x: uint64) st = p_int64 (int64 x) st - -let bits_of_float32 (x: float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes x, 0) -let bits_of_float (x: float) = System.BitConverter.DoubleToInt64Bits x - -let p_single i st = p_int32 (bits_of_float32 i) st -let p_double i st = p_int64 (bits_of_float i) st -let p_ieee64 i st = p_int64 (bits_of_float i) st -let p_char i st = p_uint16 (uint16 (int32 i)) st - -let inline p_tup2 p1 p2 (a, b) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit) - -let inline p_tup3 p1 p2 p3 (a, b, c) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit) - -let inline p_tup4 p1 p2 p3 p4 (a, b, c, d) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit) - -let inline p_tup5 p1 p2 p3 p4 p5 (a, b, c, d, e) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit) - -let inline p_tup6 p1 p2 p3 p4 p5 p6 (a, b, c, d, e, f) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit) - -let inline p_tup7 p1 p2 p3 p4 p5 p6 p7 (a, b, c, d, e, f, x7) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit) - -let inline p_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (a, b, c, d, e, f, x7, x8) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit) - -let inline p_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (a, b, c, d, e, f, x7, x8, x9) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit) - -let inline p_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (a, b, c, d, e, f, x7, x8, x9, x10) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit); (p10 x10 st : unit) - -let inline p_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (a, b, c, d, e, f, x7, x8, x9, x10, x11) (st: WriterState) = - (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit); (p10 x10 st : unit); (p11 x11 st : unit) - -let u_byte st = int (st.is.ReadByte()) - -type unpickler<'T> = ReaderState -> 'T - -let u_bool st = let b = u_byte st in (b = 1) - - - -let prim_u_int32 st = - let b0 = (u_byte st) - let b1 = (u_byte st) - let b2 = (u_byte st) - let b3 = (u_byte st) - b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24) - -let u_int32 st = - let b0 = u_byte st - if b0 <= 0x7F then b0 - else if b0 <= 0xbf then - let b0 = b0 &&& 0x7F - let b1 = (u_byte st) - (b0 <<< 8) ||| b1 - else - assert(b0 = 0xFF) - prim_u_int32 st - -let u_byte_memory st = - let n = (u_int32 st) - st.is.ReadBytes n - -let u_bytes st = - (u_byte_memory st).ToArray() - -let u_prim_string st = - let len = (u_int32 st) - st.is.ReadUtf8String len - -let u_int st = u_int32 st -let u_int8 st = sbyte (u_int32 st) -let u_uint8 st = byte (u_byte st) -let u_int16 st = int16 (u_int32 st) -let u_uint16 st = uint16 (u_int32 st) -let u_uint32 st = uint32 (u_int32 st) -let u_int64 st = - let b1 = (int64 (u_int32 st)) &&& 0xFFFFFFFFL - let b2 = int64 (u_int32 st) - b1 ||| (b2 <<< 32) - -let u_uint64 st = uint64 (u_int64 st) -let float32_of_bits (x: int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes x, 0) -let float_of_bits (x: int64) = System.BitConverter.Int64BitsToDouble x - -let u_single st = float32_of_bits (u_int32 st) -let u_double st = float_of_bits (u_int64 st) - -let u_ieee64 st = float_of_bits (u_int64 st) - -let u_char st = char (int32 (u_uint16 st)) -let u_space n st = - for i = 0 to n - 1 do - let b = u_byte st - if b <> 0 then - warning(Error(FSComp.SR.pickleUnexpectedNonZero st.ifile, range0)) - -/// Represents space that was reserved but is now possibly used -let u_used_space1 f st = - let b = u_byte st - match b with - | 0 -> None - | 1 -> - let x = f st - u_space 1 st - Some x - | _ -> - warning(Error(FSComp.SR.pickleUnexpectedNonZero st.ifile, range0)); None - - -let inline u_tup2 p1 p2 (st: ReaderState) = let a = p1 st in let b = p2 st in (a, b) - -let inline u_tup3 p1 p2 p3 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in (a, b, c) - -let inline u_tup4 p1 p2 p3 p4 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in (a, b, c, d) - -let inline u_tup5 p1 p2 p3 p4 p5 (st: ReaderState) = - let a = p1 st - let b = p2 st - let c = p3 st - let d = p4 st - let e = p5 st - (a, b, c, d, e) - -let inline u_tup6 p1 p2 p3 p4 p5 p6 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in (a, b, c, d, e, f) - -let inline u_tup7 p1 p2 p3 p4 p5 p6 p7 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in (a, b, c, d, e, f, x7) - -let inline u_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in (a, b, c, d, e, f, x7, x8) - -let inline u_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in (a, b, c, d, e, f, x7, x8, x9) - -let inline u_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in (a, b, c, d, e, f, x7, x8, x9, x10) - -let inline u_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11) - -let inline u_tup12 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12) - -let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13) - -let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - let x14 = p14 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14) -let inline u_tup15 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - let x14 = p14 st in let x15 = p15 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15) - -let inline u_tup16 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) - -let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (st: ReaderState) = - let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in - let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in - let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in - let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in - (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) - - -//--------------------------------------------------------------------------- -// Pickle/unpickle operations for observably shared graph nodes -//--------------------------------------------------------------------------- - -// exception Nope - -// ctxt is for debugging -let p_osgn_ref (_ctxt: string) (outMap : NodeOutTable<_, _>) x st = - let idx = outMap.Table.FindOrAdd (outMap.NodeStamp x) - //if ((idx = 0) && outMap.Name = "oentities") then - // let msg = - // sprintf "idx %d#%d in table %s has name '%s', was defined at '%s' and is referenced from context %s\n" - // idx (outMap.NodeStamp x) - // outMap.Name (outMap.NodeName x) - // (stringOfRange (outMap.GetRange x)) - // _ctxt - // System.Diagnostics.Debug.Assert(false, msg ) - p_int idx st - -let p_osgn_decl (outMap : NodeOutTable<_, _>) p x st = - let stamp = outMap.NodeStamp x - let idx = outMap.Table.FindOrAdd stamp - //dprintf "decl %d#%d in table %s has name %s\n" idx (outMap.NodeStamp x) outMap.Name (outMap.NodeName x) - p_tup2 p_int p (idx, outMap.Deref x) st - -let u_osgn_ref (inMap: NodeInTable<_, _>) st = - let n = u_int st - if n < 0 || n >= inMap.Count then ufailwith st ("u_osgn_ref: out of range, table = "+inMap.Name+", n = "+string n) - inMap.Get n - -let u_osgn_decl (inMap: NodeInTable<_, _>) u st = - let idx, data = u_tup2 u_int u st - // dprintf "unpickling osgn %d in table %s\n" idx nm - let res = inMap.Get idx - inMap.LinkNode res data - res - -//--------------------------------------------------------------------------- -// Pickle/unpickle operations for interned nodes -//--------------------------------------------------------------------------- - -let encode_uniq (tbl: Table<_>) key = tbl.FindOrAdd key -let lookup_uniq st tbl n = - let arr = tbl.itbl_rows - if n < 0 || n >= arr.Length then ufailwith st ("lookup_uniq in table "+tbl.itbl_name+" out of range, n = "+string n+ ", sizeof(tab) = " + string (Array.length arr)) - arr.[n] - -//--------------------------------------------------------------------------- -// Pickle/unpickle arrays and lists. For lists use the same binary format as arrays so we can switch -// between internal representations relatively easily -//------------------------------------------------------------------------- - -let p_array_core f (x: 'T[]) st = - for i = 0 to x.Length-1 do - f x.[i] st - -let p_array f (x: 'T[]) st = - p_int x.Length st - p_array_core f x st - -// Optionally encode an extra item using a marker bit. -// When extraf is None, the marker bit is not set, and this is identical to p_array. -let p_array_ext extraf f (x: 'T[]) st = - let n = x.Length - let n = if Option.isSome extraf then n ||| 0x80000000 else n - p_int n st - match extraf with - | None -> () - | Some f -> f st - p_array_core f x st - -let p_list_core f (xs: 'T list) st = - for x in xs do - f x st - -let p_list f x st = - p_int (List.length x) st - p_list_core f x st -let p_list_ext extraf f x st = - let n = List.length x - let n = if Option.isSome extraf then n ||| 0x80000000 else n - p_int n st - match extraf with - | None -> () - | Some f -> f st - p_list_core f x st - -let p_List f (x: 'T list) st = p_list f x st - -let p_wrap (f: 'T -> 'U) (p : 'U pickler) : 'T pickler = (fun x st -> p (f x) st) -let p_option f x st = - match x with - | None -> p_byte 0 st - | Some h -> p_byte 1 st; f h st - -// Pickle lazy values in such a way that they can, in some future F# compiler version, be read back -// lazily. However, a lazy reader is not used in this version because the value may contain the definitions of some -// OSGN nodes. -let private p_lazy_impl p v st = - let fixupPos1 = st.os.Position - // We fix these up after - prim_p_int32 0 st - let fixupPos2 = st.os.Position - prim_p_int32 0 st - let fixupPos3 = st.os.Position - prim_p_int32 0 st - let fixupPos4 = st.os.Position - prim_p_int32 0 st - let fixupPos5 = st.os.Position - prim_p_int32 0 st - let fixupPos6 = st.os.Position - prim_p_int32 0 st - let fixupPos7 = st.os.Position - prim_p_int32 0 st - let idx1 = st.os.Position - let otyconsIdx1 = st.oentities.Size - let otyparsIdx1 = st.otypars.Size - let ovalsIdx1 = st.ovals.Size - // Run the pickler - p v st - // Determine and fixup the length of the pickled data - let idx2 = st.os.Position - st.os.FixupInt32 fixupPos1 (idx2-idx1) - // Determine and fixup the ranges of OSGN nodes defined within the lazy portion - let otyconsIdx2 = st.oentities.Size - let otyparsIdx2 = st.otypars.Size - let ovalsIdx2 = st.ovals.Size - st.os.FixupInt32 fixupPos2 otyconsIdx1 - st.os.FixupInt32 fixupPos3 otyconsIdx2 - st.os.FixupInt32 fixupPos4 otyparsIdx1 - st.os.FixupInt32 fixupPos5 otyparsIdx2 - st.os.FixupInt32 fixupPos6 ovalsIdx1 - st.os.FixupInt32 fixupPos7 ovalsIdx2 - -let p_lazy p x st = - p_lazy_impl p (Lazy.force x) st - -let p_maybe_lazy p (x: MaybeLazy<_>) st = - p_lazy_impl p x.Value st - -let p_hole () = - let mutable h = None - (fun f -> h <- Some f), (fun x st -> match h with Some f -> f x st | None -> pfailwith st "p_hole: unfilled hole") - -let p_hole2 () = - let mutable h = None - (fun f -> h <- Some f), (fun arg x st -> match h with Some f -> f arg x st | None -> pfailwith st "p_hole2: unfilled hole") - -let u_array_core f n st = - let res = Array.zeroCreate n - for i = 0 to n-1 do - res.[i] <- f st - res - -let u_array f st = - let n = u_int st - u_array_core f n st - -// Optionally decode an extra item if a marker bit is present. -// When the marker bit is not set this is identical to u_array, and extraf is not called -let u_array_ext extraf f st = - let n = u_int st - let extraItem = - if n &&& 0x80000000 = 0x80000000 then - Some (extraf st) - else - None - let arr = u_array_core f (n &&& 0x7FFFFFFF) st - extraItem, arr - -let u_list_core f n st = - List.init n (fun _ -> f st) - -let u_list f st = - let n = u_int st - u_list_core f n st -let u_list_ext extra f st = - let n = u_int st - let extraItem = - if n &&& 0x80000000 = 0x80000000 then - Some (extra st) - else - None - let list = u_list_core f (n &&& 0x7FFFFFFF) st - extraItem, list - -#if FLAT_LIST_AS_LIST -#else -let u_List f st = u_list f st // new List<_> (u_array f st) -#endif -#if FLAT_LIST_AS_ARRAY_STRUCT -//#else -let u_List f st = List(u_array f st) -#endif -#if FLAT_LIST_AS_ARRAY -//#else -let u_List f st = u_array f st -#endif - -let u_array_revi f st = - let n = u_int st - let res = Array.zeroCreate n - for i = 0 to n-1 do - res.[i] <- f st (n-1-i) - res - -// Mark up default constraints with a priority in reverse order: last gets 0 etc. See comment on TyparConstraint.DefaultsTo -let u_list_revi f st = - let n = u_int st - [ for i = 0 to n-1 do - yield f st (n-1-i) ] - - -let u_wrap (f: 'U -> 'T) (u : 'U unpickler) : 'T unpickler = (fun st -> f (u st)) - -let u_option f st = - let tag = u_byte st - match tag with - | 0 -> None - | 1 -> Some (f st) - | n -> ufailwith st ("u_option: found number " + string n) - -// Boobytrap an OSGN node with a force of a lazy load of a bunch of pickled data -#if LAZY_UNPICKLE -let wire (x: osgn<_>) (res: Lazy<_>) = - x.osgnTripWire <- Some(fun () -> res.Force() |> ignore) -#endif - -let u_lazy u st = - - // Read the number of bytes in the record - let len = prim_u_int32 st // fixupPos1 - // These are the ranges of OSGN nodes defined within the lazily read portion of the graph - let otyconsIdx1 = prim_u_int32 st // fixupPos2 - let otyconsIdx2 = prim_u_int32 st // fixupPos3 - let otyparsIdx1 = prim_u_int32 st // fixupPos4 - let otyparsIdx2 = prim_u_int32 st // fixupPos5 - let ovalsIdx1 = prim_u_int32 st // fixupPos6 - let ovalsIdx2 = prim_u_int32 st // fixupPos7 - -#if LAZY_UNPICKLE - // Record the position in the bytestream to use when forcing the read of the data - let idx1 = st.is.Position - // Skip the length of data - st.is.Skip len - // This is the lazy computation that wil force the unpickling of the term. - // This term must contain OSGN definitions of the given nodes. - let res = - lazy (let st = { st with is = st.is.CloneAndSeek idx1 } - u st) - /// Force the reading of the data as a "tripwire" for each of the OSGN thunks - for i = otyconsIdx1 to otyconsIdx2-1 do wire (st.ientities.Get i) res done - for i = ovalsIdx1 to ovalsIdx2-1 do wire (st.ivals.Get i) res done - for i = otyparsIdx1 to otyparsIdx2-1 do wire (st.itypars.Get i) res done - res -#else - ignore (len, otyconsIdx1, otyconsIdx2, otyparsIdx1, otyparsIdx2, ovalsIdx1, ovalsIdx2) - Lazy.CreateFromValue(u st) -#endif - - -let u_hole () = - let mutable h = None - (fun f -> h <- Some f), (fun st -> match h with Some f -> f st | None -> ufailwith st "u_hole: unfilled hole") - -//--------------------------------------------------------------------------- -// Pickle/unpickle F# interface data -//--------------------------------------------------------------------------- - -// Strings -// A huge number of these occur in pickled F# data, so make them unique -let encode_string stringTab x = encode_uniq stringTab x -let decode_string x = x -let lookup_string st stringTab x = lookup_uniq st stringTab x -let u_encoded_string = u_prim_string -let u_string st = lookup_uniq st st.istrings (u_int st) -let u_strings = u_list u_string -let u_ints = u_list u_int - - -let p_encoded_string = p_prim_string -let p_string s st = p_int (encode_string st.ostrings s) st -let p_strings = p_list p_string -let p_ints = p_list p_int - -// CCU References -// A huge number of these occur in pickled F# data, so make them unique -let encode_ccuref ccuTab (x: CcuThunk) = encode_uniq ccuTab x.AssemblyName -let decode_ccuref x = x -let lookup_ccuref st ccuTab x = lookup_uniq st ccuTab x -let u_encoded_ccuref st = - match u_byte st with - | 0 -> u_prim_string st - | n -> ufailwith st ("u_encoded_ccuref: found number " + string n) -let u_ccuref st = lookup_uniq st st.iccus (u_int st) - -let p_encoded_ccuref x st = - p_byte 0 st // leave a dummy tag to make room for future encodings of ccurefs - p_prim_string x st - -let p_ccuref s st = p_int (encode_ccuref st.occus s) st - -// References to public items in this module -// A huge number of these occur in pickled F# data, so make them unique -let decode_pubpath st stringTab a = PubPath(Array.map (lookup_string st stringTab) a) -let lookup_pubpath st pubpathTab x = lookup_uniq st pubpathTab x -let u_encoded_pubpath = u_array u_int -let u_pubpath st = lookup_uniq st st.ipubpaths (u_int st) - -let encode_pubpath stringTab pubpathTab (PubPath a) = encode_uniq pubpathTab (Array.map (encode_string stringTab) a) -let p_encoded_pubpath = p_array p_int -let p_pubpath x st = p_int (encode_pubpath st.ostrings st.opubpaths x) st - -// References to other modules -// A huge number of these occur in pickled F# data, so make them unique -let decode_nleref st ccuTab stringTab (a, b) = mkNonLocalEntityRef (lookup_ccuref st ccuTab a) (Array.map (lookup_string st stringTab) b) -let lookup_nleref st nlerefTab x = lookup_uniq st nlerefTab x -let u_encoded_nleref = u_tup2 u_int (u_array u_int) -let u_nleref st = lookup_uniq st st.inlerefs (u_int st) - -let encode_nleref ccuTab stringTab nlerefTab thisCcu (nleref: NonLocalEntityRef) = -#if !NO_EXTENSIONTYPING - // Remap references to statically-linked Entity nodes in provider-generated entities to point to the current assembly. - // References to these nodes _do_ appear in F# assembly metadata, because they may be public. - let nleref = - match nleref.Deref.PublicPath with - | Some pubpath when nleref.Deref.IsProvidedGeneratedTycon -> - if verbose then dprintfn "remapping pickled reference to provider-generated type %s" nleref.Deref.DisplayNameWithStaticParameters - rescopePubPath thisCcu pubpath - | _ -> nleref -#else - ignore thisCcu -#endif - - let (NonLocalEntityRef(a, b)) = nleref - encode_uniq nlerefTab (encode_ccuref ccuTab a, Array.map (encode_string stringTab) b) -let p_encoded_nleref = p_tup2 p_int (p_array p_int) -let p_nleref x st = p_int (encode_nleref st.occus st.ostrings st.onlerefs st.oscope x) st - -// Simple types are types like "int", represented as TType(Ref_nonlocal(..., "int"), []). -// A huge number of these occur in pickled F# data, so make them unique. -let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERefNonLocal (lookup_nleref st nlerefTab a), []) -let lookup_simpletyp st simpleTyTab x = lookup_uniq st simpleTyTab x -let u_encoded_simpletyp st = u_int st -let u_encoded_anoninfo st = u_int st -let u_simpletyp st = lookup_uniq st st.isimpletys (u_int st) -let encode_simpletyp ccuTab stringTab nlerefTab simpleTyTab thisCcu a = encode_uniq simpleTyTab (encode_nleref ccuTab stringTab nlerefTab thisCcu a) -let p_encoded_simpletyp x st = p_int x st -let p_encoded_anoninfo x st = p_int x st -let p_simpletyp x st = p_int (encode_simpletyp st.occus st.ostrings st.onlerefs st.osimpletys st.oscope x) st - -let pickleObjWithDanglingCcus inMem file g scope p x = - let ccuNameTab, (ntycons, ntypars, nvals, nanoninfos), stringTab, pubpathTab, nlerefTab, simpleTyTab, phase1bytes = - let st1 = - { os = ByteBuffer.Create 100000 - oscope=scope - occus= Table<_>.Create "occus" - oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), (fun osgn -> osgn), "otycons") - otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), (fun osgn -> osgn), "otypars") - ovals=NodeOutTable<_, _>.Create((fun (v: Val) -> v.Stamp), (fun v -> v.LogicalName), (fun v -> v.Range), (fun osgn -> osgn), "ovals") - oanoninfos=NodeOutTable<_, _>.Create((fun (v: AnonRecdTypeInfo) -> v.Stamp), (fun v -> string v.Stamp), (fun _ -> range0), id, "oanoninfos") - ostrings=Table<_>.Create "ostrings" - onlerefs=Table<_>.Create "onlerefs" - opubpaths=Table<_>.Create "opubpaths" - osimpletys=Table<_>.Create "osimpletys" - oglobals=g - ofile=file - oInMem=inMem - isStructThisArgPos = false} - p x st1 - let sizes = - st1.oentities.Size, - st1.otypars.Size, - st1.ovals.Size, - st1.oanoninfos.Size - st1.occus, sizes, st1.ostrings, st1.opubpaths, st1.onlerefs, st1.osimpletys, st1.os.Close() - - let phase2bytes = - let st2 = - { os = ByteBuffer.Create 100000 - oscope=scope - occus= Table<_>.Create "occus (fake)" - oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), (fun osgn -> osgn), "otycons") - otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), (fun osgn -> osgn), "otypars") - ovals=NodeOutTable<_, _>.Create((fun (v: Val) -> v.Stamp), (fun v -> v.LogicalName), (fun v -> v.Range), (fun osgn -> osgn), "ovals") - oanoninfos=NodeOutTable<_, _>.Create((fun (v: AnonRecdTypeInfo) -> v.Stamp), (fun v -> string v.Stamp), (fun _ -> range0), id, "oanoninfos") - ostrings=Table<_>.Create "ostrings (fake)" - opubpaths=Table<_>.Create "opubpaths (fake)" - onlerefs=Table<_>.Create "onlerefs (fake)" - osimpletys=Table<_>.Create "osimpletys (fake)" - oglobals=g - ofile=file - oInMem=inMem - isStructThisArgPos = false } - p_array p_encoded_ccuref ccuNameTab.AsArray st2 - // Add a 4th integer indicated by a negative 1st integer - let z1 = if nanoninfos > 0 then -ntycons-1 else ntycons - p_int z1 st2 - p_tup2 p_int p_int (ntypars, nvals) st2 - if nanoninfos > 0 then - p_int nanoninfos st2 - p_tup5 - (p_array p_encoded_string) - (p_array p_encoded_pubpath) - (p_array p_encoded_nleref) - (p_array p_encoded_simpletyp) - p_bytes - (stringTab.AsArray, pubpathTab.AsArray, nlerefTab.AsArray, simpleTyTab.AsArray, phase1bytes) - st2 - st2.os.Close() - phase2bytes - -let check (ilscope: ILScopeRef) (inMap : NodeInTable<_, _>) = - for i = 0 to inMap.Count - 1 do - let n = inMap.Get i - if not (inMap.IsLinked n) then - warning(Error(FSComp.SR.pickleMissingDefinition (i, inMap.Name, ilscope.QualifiedName), range0)) - // Note for compiler developers: to get information about which item this index relates to, - // enable the conditional in Pickle.p_osgn_ref to refer to the given index number and recompile - // an identical copy of the source for the DLL containing the data being unpickled. A message will - // then be printed indicating the name of the item. - -let unpickleObjWithDanglingCcus file ilscope (iILModule: ILModuleDef option) u (phase2bytes: ReadOnlyByteMemory) = - let st2 = - { is = ByteStream.FromBytes (phase2bytes, 0, phase2bytes.Length) - iilscope= ilscope - iccus= new_itbl "iccus (fake)" [| |] - ientities= NodeInTable<_, _>.Create (Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", 0) - itypars= NodeInTable<_, _>.Create (Typar.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itypars", 0) - ivals = NodeInTable<_, _>.Create (Val.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ivals", 0) - ianoninfos=NodeInTable<_, _>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ianoninfos", 0) - istrings = new_itbl "istrings (fake)" [| |] - inlerefs = new_itbl "inlerefs (fake)" [| |] - ipubpaths = new_itbl "ipubpaths (fake)" [| |] - isimpletys = new_itbl "isimpletys (fake)" [| |] - ifile=file - iILModule = iILModule } - let ccuNameTab = u_array u_encoded_ccuref st2 - let z1 = u_int st2 - let ntycons = if z1 < 0 then -z1-1 else z1 - let ntypars, nvals = u_tup2 u_int u_int st2 - let nanoninfos = if z1 < 0 then u_int st2 else 0 - let stringTab, pubpathTab, nlerefTab, simpleTyTab, phase1bytes = - u_tup5 - (u_array u_encoded_string) - (u_array u_encoded_pubpath) - (u_array u_encoded_nleref) - (u_array u_encoded_simpletyp) - u_byte_memory - st2 - let ccuTab = new_itbl "iccus" (Array.map (CcuThunk.CreateDelayed) ccuNameTab) - let stringTab = new_itbl "istrings" (Array.map decode_string stringTab) - let pubpathTab = new_itbl "ipubpaths" (Array.map (decode_pubpath st2 stringTab) pubpathTab) - let nlerefTab = new_itbl "inlerefs" (Array.map (decode_nleref st2 ccuTab stringTab) nlerefTab) - let simpletypTab = new_itbl "simpleTyTab" (Array.map (decode_simpletyp st2 ccuTab stringTab nlerefTab) simpleTyTab) - let data = - let st1 = - { is = ByteStream.FromBytes (phase1bytes, 0, phase1bytes.Length) - iccus= ccuTab - iilscope= ilscope - ientities= NodeInTable<_, _>.Create(Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", ntycons) - itypars= NodeInTable<_, _>.Create(Typar.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itypars", ntypars) - ivals= NodeInTable<_, _>.Create(Val.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ivals", nvals) - ianoninfos=NodeInTable<_, _>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ianoninfos", nanoninfos) - istrings = stringTab - ipubpaths = pubpathTab - inlerefs = nlerefTab - isimpletys = simpletypTab - ifile=file - iILModule = iILModule } - let res = u st1 -#if !LAZY_UNPICKLE - check ilscope st1.ientities - check ilscope st1.ivals - check ilscope st1.itypars -#endif - res - - {RawData=data; FixupThunks=ccuTab.itbl_rows } - - -//========================================================================= -// PART II -//========================================================================= - -//--------------------------------------------------------------------------- -// Pickle/unpickle for Abstract IL data, up to IL instructions -//--------------------------------------------------------------------------- - -let p_ILPublicKey x st = - match x with - | PublicKey b -> p_byte 0 st; p_bytes b st - | PublicKeyToken b -> p_byte 1 st; p_bytes b st - -let p_ILVersion (x: ILVersionInfo) st = p_tup4 p_uint16 p_uint16 p_uint16 p_uint16 (x.Major, x.Minor, x.Build, x.Revision) st - -let p_ILModuleRef (x: ILModuleRef) st = - p_tup3 p_string p_bool (p_option p_bytes) (x.Name, x.HasMetadata, x.Hash) st - -let p_ILAssemblyRef (x: ILAssemblyRef) st = - p_byte 0 st // leave a dummy tag to make room for future encodings of assembly refs - p_tup6 p_string (p_option p_bytes) (p_option p_ILPublicKey) p_bool (p_option p_ILVersion) (p_option p_string) - ( x.Name, x.Hash, x.PublicKey, x.Retargetable, x.Version, x.Locale) st - -let p_ILScopeRef x st = - match x with - | ILScopeRef.Local -> p_byte 0 st - | ILScopeRef.Module mref -> p_byte 1 st; p_ILModuleRef mref st - | ILScopeRef.Assembly aref -> p_byte 2 st; p_ILAssemblyRef aref st - // Encode primary assembly as a normal assembly ref - | ILScopeRef.PrimaryAssembly -> p_byte 2 st; p_ILAssemblyRef st.oglobals.ilg.primaryAssemblyRef st - -let u_ILPublicKey st = - let tag = u_byte st - match tag with - | 0 -> u_bytes st |> PublicKey - | 1 -> u_bytes st |> PublicKeyToken - | _ -> ufailwith st "u_ILPublicKey" - -let u_ILVersion st = - let (major, minor, build, revision) = u_tup4 u_uint16 u_uint16 u_uint16 u_uint16 st - ILVersionInfo(major, minor, build, revision) - -let u_ILModuleRef st = - let (a, b, c) = u_tup3 u_string u_bool (u_option u_bytes) st - ILModuleRef.Create(a, b, c) - -let u_ILAssemblyRef st = - let tag = u_byte st - match tag with - | 0 -> - let a, b, c, d, e, f = u_tup6 u_string (u_option u_bytes) (u_option u_ILPublicKey) u_bool (u_option u_ILVersion) (u_option u_string) st - ILAssemblyRef.Create(a, b, c, d, e, f) - | _ -> ufailwith st "u_ILAssemblyRef" - -// IL scope references are rescoped as they are unpickled. This means -// the pickler accepts IL fragments containing ILScopeRef.Local and adjusts them -// to be absolute scope references. -let u_ILScopeRef st = - let res = - let tag = u_byte st - match tag with - | 0 -> ILScopeRef.Local - | 1 -> u_ILModuleRef st |> ILScopeRef.Module - | 2 -> u_ILAssemblyRef st |> ILScopeRef.Assembly - | _ -> ufailwith st "u_ILScopeRef" - let res = rescopeILScopeRef st.iilscope res - res - -let p_ILHasThis x st = - p_byte (match x with - | ILThisConvention.Instance -> 0 - | ILThisConvention.InstanceExplicit -> 1 - | ILThisConvention.Static -> 2) st - -let p_ILArrayShape = p_wrap (fun (ILArrayShape x) -> x) (p_list (p_tup2 (p_option p_int32) (p_option p_int32))) - -let rec p_ILType ty st = - match ty with - | ILType.Void -> p_byte 0 st - | ILType.Array (shape, ty) -> p_byte 1 st; p_tup2 p_ILArrayShape p_ILType (shape, ty) st - | ILType.Value tspec -> p_byte 2 st; p_ILTypeSpec tspec st - | ILType.Boxed tspec -> p_byte 3 st; p_ILTypeSpec tspec st - | ILType.Ptr ty -> p_byte 4 st; p_ILType ty st - | ILType.Byref ty -> p_byte 5 st; p_ILType ty st - | ILType.FunctionPointer csig -> p_byte 6 st; p_ILCallSig csig st - | ILType.TypeVar n -> p_byte 7 st; p_uint16 n st - | ILType.Modified (req, tref, ty) -> p_byte 8 st; p_tup3 p_bool p_ILTypeRef p_ILType (req, tref, ty) st - -and p_ILTypes tys = p_list p_ILType tys - -and p_ILBasicCallConv x st = - p_byte (match x with - | ILArgConvention.Default -> 0 - | ILArgConvention.CDecl -> 1 - | ILArgConvention.StdCall -> 2 - | ILArgConvention.ThisCall -> 3 - | ILArgConvention.FastCall -> 4 - | ILArgConvention.VarArg -> 5) st - -and p_ILCallConv (Callconv(x, y)) st = p_tup2 p_ILHasThis p_ILBasicCallConv (x, y) st - -and p_ILCallSig x st = p_tup3 p_ILCallConv p_ILTypes p_ILType (x.CallingConv, x.ArgTypes, x.ReturnType) st - -and p_ILTypeRef (x: ILTypeRef) st = p_tup3 p_ILScopeRef p_strings p_string (x.Scope, x.Enclosing, x.Name) st - -and p_ILTypeSpec (a: ILTypeSpec) st = p_tup2 p_ILTypeRef p_ILTypes (a.TypeRef, a.GenericArgs) st - -let u_ILBasicCallConv st = - match u_byte st with - | 0 -> ILArgConvention.Default - | 1 -> ILArgConvention.CDecl - | 2 -> ILArgConvention.StdCall - | 3 -> ILArgConvention.ThisCall - | 4 -> ILArgConvention.FastCall - | 5 -> ILArgConvention.VarArg - | _ -> ufailwith st "u_ILBasicCallConv" - -let u_ILHasThis st = - match u_byte st with - | 0 -> ILThisConvention.Instance - | 1 -> ILThisConvention.InstanceExplicit - | 2 -> ILThisConvention.Static - | _ -> ufailwith st "u_ILHasThis" - -let u_ILCallConv st = let a, b = u_tup2 u_ILHasThis u_ILBasicCallConv st in Callconv(a, b) -let u_ILTypeRef st = let a, b, c = u_tup3 u_ILScopeRef u_strings u_string st in ILTypeRef.Create(a, b, c) -let u_ILArrayShape = u_wrap (fun x -> ILArrayShape x) (u_list (u_tup2 (u_option u_int32) (u_option u_int32))) - - -let rec u_ILType st = - let tag = u_byte st - match tag with - | 0 -> ILType.Void - | 1 -> u_tup2 u_ILArrayShape u_ILType st |> ILType.Array - | 2 -> u_ILTypeSpec st |> ILType.Value - | 3 -> u_ILTypeSpec st |> mkILBoxedType - | 4 -> u_ILType st |> ILType.Ptr - | 5 -> u_ILType st |> ILType.Byref - | 6 -> u_ILCallSig st |> ILType.FunctionPointer - | 7 -> u_uint16 st |> mkILTyvarTy - | 8 -> u_tup3 u_bool u_ILTypeRef u_ILType st |> ILType.Modified - | _ -> ufailwith st "u_ILType" - -and u_ILTypes st = u_list u_ILType st - -and u_ILCallSig = u_wrap (fun (a, b, c) -> {CallingConv=a; ArgTypes=b; ReturnType=c}) (u_tup3 u_ILCallConv u_ILTypes u_ILType) - -and u_ILTypeSpec st = let a, b = u_tup2 u_ILTypeRef u_ILTypes st in ILTypeSpec.Create(a, b) - - -let p_ILMethodRef (x: ILMethodRef) st = p_tup6 p_ILTypeRef p_ILCallConv p_int p_string p_ILTypes p_ILType (x.DeclaringTypeRef, x.CallingConv, x.GenericArity, x.Name, x.ArgTypes, x.ReturnType) st - -let p_ILFieldRef (x: ILFieldRef) st = p_tup3 p_ILTypeRef p_string p_ILType (x.DeclaringTypeRef, x.Name, x.Type) st - -let p_ILMethodSpec (x: ILMethodSpec) st = p_tup3 p_ILMethodRef p_ILType p_ILTypes (x.MethodRef, x.DeclaringType, x.GenericArgs) st - -let p_ILFieldSpec (x : ILFieldSpec) st = p_tup2 p_ILFieldRef p_ILType (x.FieldRef, x.DeclaringType) st - -let p_ILBasicType x st = - p_int (match x with - | DT_R -> 0 - | DT_I1 -> 1 - | DT_U1 -> 2 - | DT_I2 -> 3 - | DT_U2 -> 4 - | DT_I4 -> 5 - | DT_U4 -> 6 - | DT_I8 -> 7 - | DT_U8 -> 8 - | DT_R4 -> 9 - | DT_R8 -> 10 - | DT_I -> 11 - | DT_U -> 12 - | DT_REF -> 13) st - -let p_ILVolatility x st = p_int (match x with Volatile -> 0 | Nonvolatile -> 1) st -let p_ILReadonly x st = p_int (match x with ReadonlyAddress -> 0 | NormalAddress -> 1) st - -let u_ILMethodRef st = - let x1, x2, x3, x4, x5, x6 = u_tup6 u_ILTypeRef u_ILCallConv u_int u_string u_ILTypes u_ILType st - ILMethodRef.Create(x1, x2, x4, x3, x5, x6) - -let u_ILFieldRef st = - let x1, x2, x3 = u_tup3 u_ILTypeRef u_string u_ILType st - {DeclaringTypeRef=x1;Name=x2;Type=x3} - -let u_ILMethodSpec st = - let x1, x2, x3 = u_tup3 u_ILMethodRef u_ILType u_ILTypes st - ILMethodSpec.Create(x2, x1, x3) - -let u_ILFieldSpec st = - let x1, x2 = u_tup2 u_ILFieldRef u_ILType st - {FieldRef=x1;DeclaringType=x2} - -let u_ILBasicType st = - match u_int st with - | 0 -> DT_R - | 1 -> DT_I1 - | 2 -> DT_U1 - | 3 -> DT_I2 - | 4 -> DT_U2 - | 5 -> DT_I4 - | 6 -> DT_U4 - | 7 -> DT_I8 - | 8 -> DT_U8 - | 9 -> DT_R4 - | 10 -> DT_R8 - | 11 -> DT_I - | 12 -> DT_U - | 13 -> DT_REF - | _ -> ufailwith st "u_ILBasicType" - -let u_ILVolatility st = (match u_int st with 0 -> Volatile | 1 -> Nonvolatile | _ -> ufailwith st "u_ILVolatility" ) -let u_ILReadonly st = (match u_int st with 0 -> ReadonlyAddress | 1 -> NormalAddress | _ -> ufailwith st "u_ILReadonly" ) - -let [] itag_nop = 0 -let [] itag_ldarg = 1 -let [] itag_ldnull = 2 -let [] itag_ilzero = 3 -let [] itag_call = 4 -let [] itag_add = 5 -let [] itag_sub = 6 -let [] itag_mul = 7 -let [] itag_div = 8 -let [] itag_div_un = 9 -let [] itag_rem = 10 -let [] itag_rem_un = 11 -let [] itag_and = 12 -let [] itag_or = 13 -let [] itag_xor = 14 -let [] itag_shl = 15 -let [] itag_shr = 16 -let [] itag_shr_un = 17 -let [] itag_neg = 18 -let [] itag_not = 19 -let [] itag_conv = 20 -let [] itag_conv_un = 21 -let [] itag_conv_ovf = 22 -let [] itag_conv_ovf_un = 23 -let [] itag_callvirt = 24 -let [] itag_ldobj = 25 -let [] itag_ldstr = 26 -let [] itag_castclass = 27 -let [] itag_isinst = 28 -let [] itag_unbox = 29 -let [] itag_throw = 30 -let [] itag_ldfld = 31 -let [] itag_ldflda = 32 -let [] itag_stfld = 33 -let [] itag_ldsfld = 34 -let [] itag_ldsflda = 35 -let [] itag_stsfld = 36 -let [] itag_stobj = 37 -let [] itag_box = 38 -let [] itag_newarr = 39 -let [] itag_ldlen = 40 -let [] itag_ldelema = 41 -let [] itag_ckfinite = 42 -let [] itag_ldtoken = 43 -let [] itag_add_ovf = 44 -let [] itag_add_ovf_un = 45 -let [] itag_mul_ovf = 46 -let [] itag_mul_ovf_un = 47 -let [] itag_sub_ovf = 48 -let [] itag_sub_ovf_un = 49 -let [] itag_ceq = 50 -let [] itag_cgt = 51 -let [] itag_cgt_un = 52 -let [] itag_clt = 53 -let [] itag_clt_un = 54 -let [] itag_ldvirtftn = 55 -let [] itag_localloc = 56 -let [] itag_rethrow = 57 -let [] itag_sizeof = 58 -let [] itag_ldelem_any = 59 -let [] itag_stelem_any = 60 -let [] itag_unbox_any = 61 -let [] itag_ldlen_multi = 62 -let [] itag_initobj = 63 // currently unused, added for forward compat, see https://visualfsharp.codeplex.com/SourceControl/network/forks/jackpappas/fsharpcontrib/contribution/7134 -let [] itag_initblk = 64 // currently unused, added for forward compat -let [] itag_cpobj = 65 // currently unused, added for forward compat -let [] itag_cpblk = 66 // currently unused, added for forward compat - -let simple_instrs = - [ itag_add, AI_add - itag_add_ovf, AI_add_ovf - itag_add_ovf_un, AI_add_ovf_un - itag_and, AI_and - itag_div, AI_div - itag_div_un, AI_div_un - itag_ceq, AI_ceq - itag_cgt, AI_cgt - itag_cgt_un, AI_cgt_un - itag_clt, AI_clt - itag_clt_un, AI_clt_un - itag_mul, AI_mul - itag_mul_ovf, AI_mul_ovf - itag_mul_ovf_un, AI_mul_ovf_un - itag_rem, AI_rem - itag_rem_un, AI_rem_un - itag_shl, AI_shl - itag_shr, AI_shr - itag_shr_un, AI_shr_un - itag_sub, AI_sub - itag_sub_ovf, AI_sub_ovf - itag_sub_ovf_un, AI_sub_ovf_un - itag_xor, AI_xor - itag_or, AI_or - itag_neg, AI_neg - itag_not, AI_not - itag_ldnull, AI_ldnull - itag_ckfinite, AI_ckfinite - itag_nop, AI_nop - itag_localloc, I_localloc - itag_throw, I_throw - itag_ldlen, I_ldlen - itag_rethrow, I_rethrow - itag_rethrow, I_rethrow - itag_initblk, I_initblk (Aligned, Nonvolatile) - itag_cpblk, I_cpblk (Aligned, Nonvolatile) - ] - -let encode_table = Dictionary<_, _>(300, HashIdentity.Structural) -let _ = List.iter (fun (icode, i) -> encode_table.[i] <- icode) simple_instrs -let encode_instr si = encode_table.[si] -let isNoArgInstr s = encode_table.ContainsKey s - -let decoders = - [ itag_ldarg, u_uint16 >> mkLdarg - itag_call, u_ILMethodSpec >> (fun a -> I_call (Normalcall, a, None)) - itag_callvirt, u_ILMethodSpec >> (fun a -> I_callvirt (Normalcall, a, None)) - itag_ldvirtftn, u_ILMethodSpec >> I_ldvirtftn - itag_conv, u_ILBasicType >> (fun a -> (AI_conv a)) - itag_conv_ovf, u_ILBasicType >> (fun a -> (AI_conv_ovf a)) - itag_conv_ovf_un, u_ILBasicType >> (fun a -> (AI_conv_ovf_un a)) - itag_ldfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b, c) -> I_ldfld (Aligned, b, c)) - itag_ldflda, u_ILFieldSpec >> I_ldflda - itag_ldsfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a, b) -> I_ldsfld (a, b)) - itag_ldsflda, u_ILFieldSpec >> I_ldsflda - itag_stfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b, c) -> I_stfld (Aligned, b, c)) - itag_stsfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a, b) -> I_stsfld (a, b)) - itag_ldtoken, u_ILType >> (fun a -> I_ldtoken (ILToken.ILType a)) - itag_ldstr, u_string >> I_ldstr - itag_box, u_ILType >> I_box - itag_unbox, u_ILType >> I_unbox - itag_unbox_any, u_ILType >> I_unbox_any - itag_newarr, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_newarr(a, b)) - itag_stelem_any, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_stelem_any(a, b)) - itag_ldelem_any, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_ldelem_any(a, b)) - itag_ldelema, u_tup3 u_ILReadonly u_ILArrayShape u_ILType >> (fun (a, b, c) -> I_ldelema(a, false, b, c)) - itag_castclass, u_ILType >> I_castclass - itag_isinst, u_ILType >> I_isinst - itag_ldobj, u_ILType >> (fun c -> I_ldobj (Aligned, Nonvolatile, c)) - itag_stobj, u_ILType >> (fun c -> I_stobj (Aligned, Nonvolatile, c)) - itag_sizeof, u_ILType >> I_sizeof - itag_ldlen_multi, u_tup2 u_int32 u_int32 >> (fun (a, b) -> EI_ldlen_multi (a, b)) - itag_ilzero, u_ILType >> EI_ilzero - itag_ilzero, u_ILType >> EI_ilzero - itag_initobj, u_ILType >> I_initobj - itag_cpobj, u_ILType >> I_cpobj - ] - -let decode_tab = - let tab = Array.init 256 (fun n -> (fun st -> ufailwith st ("no decoder for instruction "+string n))) - let add_instr (icode, f) = tab.[icode] <- f - List.iter add_instr decoders - List.iter (fun (icode, mk) -> add_instr (icode, (fun _ -> mk))) simple_instrs - tab - -let p_ILInstr x st = - match x with - | si when isNoArgInstr si -> p_byte (encode_instr si) st - | I_call(Normalcall, mspec, None) -> p_byte itag_call st; p_ILMethodSpec mspec st - | I_callvirt(Normalcall, mspec, None) -> p_byte itag_callvirt st; p_ILMethodSpec mspec st - | I_ldvirtftn mspec -> p_byte itag_ldvirtftn st; p_ILMethodSpec mspec st - | I_ldarg x -> p_byte itag_ldarg st; p_uint16 x st - | AI_conv a -> p_byte itag_conv st; p_ILBasicType a st - | AI_conv_ovf a -> p_byte itag_conv_ovf st; p_ILBasicType a st - | AI_conv_ovf_un a -> p_byte itag_conv_ovf_un st; p_ILBasicType a st - | I_ldfld (Aligned, b, c) -> p_byte itag_ldfld st; p_tup2 p_ILVolatility p_ILFieldSpec (b, c) st - | I_ldsfld (a, b) -> p_byte itag_ldsfld st; p_tup2 p_ILVolatility p_ILFieldSpec (a, b) st - | I_stfld (Aligned, b, c) -> p_byte itag_stfld st; p_tup2 p_ILVolatility p_ILFieldSpec (b, c) st - | I_stsfld (a, b) -> p_byte itag_stsfld st; p_tup2 p_ILVolatility p_ILFieldSpec (a, b) st - | I_ldflda c -> p_byte itag_ldflda st; p_ILFieldSpec c st - | I_ldsflda a -> p_byte itag_ldsflda st; p_ILFieldSpec a st - | I_ldtoken (ILToken.ILType ty) -> p_byte itag_ldtoken st; p_ILType ty st - | I_ldstr s -> p_byte itag_ldstr st; p_string s st - | I_box ty -> p_byte itag_box st; p_ILType ty st - | I_unbox ty -> p_byte itag_unbox st; p_ILType ty st - | I_unbox_any ty -> p_byte itag_unbox_any st; p_ILType ty st - | I_newarr (a, b) -> p_byte itag_newarr st; p_tup2 p_ILArrayShape p_ILType (a, b) st - | I_stelem_any (a, b) -> p_byte itag_stelem_any st; p_tup2 p_ILArrayShape p_ILType (a, b) st - | I_ldelem_any (a, b) -> p_byte itag_ldelem_any st; p_tup2 p_ILArrayShape p_ILType (a, b) st - | I_ldelema (a, _, b, c) -> p_byte itag_ldelema st; p_tup3 p_ILReadonly p_ILArrayShape p_ILType (a, b, c) st - | I_castclass ty -> p_byte itag_castclass st; p_ILType ty st - | I_isinst ty -> p_byte itag_isinst st; p_ILType ty st - | I_ldobj (Aligned, Nonvolatile, c) -> p_byte itag_ldobj st; p_ILType c st - | I_stobj (Aligned, Nonvolatile, c) -> p_byte itag_stobj st; p_ILType c st - | I_sizeof ty -> p_byte itag_sizeof st; p_ILType ty st - | EI_ldlen_multi (n, m) -> p_byte itag_ldlen_multi st; p_tup2 p_int32 p_int32 (n, m) st - | EI_ilzero a -> p_byte itag_ilzero st; p_ILType a st - | I_initobj c -> p_byte itag_initobj st; p_ILType c st - | I_cpobj c -> p_byte itag_cpobj st; p_ILType c st - | i -> pfailwith st (sprintf "the IL instruction '%+A' cannot be emitted" i) - -let u_ILInstr st = - let n = u_byte st - decode_tab.[n] st - - - -//--------------------------------------------------------------------------- -// Pickle/unpickle for F# types and module signatures -//--------------------------------------------------------------------------- - -let p_Map_core pk pv xs st = - xs |> Map.iter (fun k v -> pk k st; pv v st) - -let p_Map pk pv x st = - p_int (Map.count x) st - p_Map_core pk pv x st - -let p_qlist pv = p_wrap QueueList.toList (p_list pv) -let p_namemap p = p_Map p_string p - -let u_Map_core uk uv n st = - Map.ofSeq (seq { for _ in 1..n -> (uk st, uv st) }) - -let u_Map uk uv st = - let n = u_int st - u_Map_core uk uv n st - -let u_qlist uv = u_wrap QueueList.ofList (u_list uv) -let u_namemap u = u_Map u_string u - -let p_pos (x: pos) st = p_tup2 p_int p_int (x.Line, x.Column) st - -let p_range (x: range) st = - let fileName = PathMap.apply st.oglobals.pathMap x.FileName - p_tup3 p_string p_pos p_pos (fileName, x.Start, x.End) st - -let p_dummy_range : range pickler = fun _x _st -> () -let p_ident (x: Ident) st = p_tup2 p_string p_range (x.idText, x.idRange) st -let p_xmldoc (XmlDoc x) st = p_array p_string x st - -let u_pos st = let a = u_int st in let b = u_int st in mkPos a b -let u_range st = let a = u_string st in let b = u_pos st in let c = u_pos st in mkRange a b c - -// Most ranges (e.g. on optimization expressions) can be elided from stored data -let u_dummy_range : range unpickler = fun _st -> range0 -let u_ident st = let a = u_string st in let b = u_range st in ident(a, b) -let u_xmldoc st = XmlDoc (u_array u_string st) - - -let p_local_item_ref ctxt tab st = p_osgn_ref ctxt tab st - -let p_tcref ctxt (x: EntityRef) st = - match x with - | ERefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.oentities x st - | ERefNonLocal x -> p_byte 1 st; p_nleref x st - -let p_ucref (UCRef(a, b)) st = p_tup2 (p_tcref "ucref") p_string (a, b) st -let p_rfref (RFRef(a, b)) st = p_tup2 (p_tcref "rfref") p_string (a, b) st -let p_tpref x st = p_local_item_ref "typar" st.otypars x st - -let u_local_item_ref tab st = u_osgn_ref tab st - -let u_tcref st = - let tag = u_byte st - match tag with - | 0 -> u_local_item_ref st.ientities st |> ERefLocal - | 1 -> u_nleref st |> ERefNonLocal - | _ -> ufailwith st "u_item_ref" - -let u_ucref st = let a, b = u_tup2 u_tcref u_string st in UCRef(a, b) - -let u_rfref st = let a, b = u_tup2 u_tcref u_string st in RFRef(a, b) - -let u_tpref st = u_local_item_ref st.itypars st - -// forward reference -let fill_p_ty2, p_ty2 = p_hole2() - -let p_ty = p_ty2 false -let p_tys = (p_list p_ty) - -let fill_p_attribs, p_attribs = p_hole() - -// In F# 4.5, the type of the "this" pointer for structs is considered to be inref for the purposes of checking the implementation -// of the struct. However for backwards compat reasons we can't serialize this as the type. -let checkForInRefStructThisArg st ty = - let g = st.oglobals - let _, tauTy = tryDestForallTy g ty - isFunTy g tauTy && isFunTy g (rangeOfFunTy g tauTy) && isInByrefTy g (domainOfFunTy g tauTy) - -let p_nonlocal_val_ref (nlv: NonLocalValOrMemberRef) st = - let a = nlv.EnclosingEntity - let key = nlv.ItemKey - let pkey = key.PartialKey - p_tcref "nlvref" a st - p_option p_string pkey.MemberParentMangledName st - p_bool pkey.MemberIsOverride st - p_string pkey.LogicalName st - p_int pkey.TotalArgCount st - let isStructThisArgPos = - match key.TypeForLinkage with - | None -> false - | Some ty -> checkForInRefStructThisArg st ty - p_option (p_ty2 isStructThisArgPos) key.TypeForLinkage st - -let rec p_vref ctxt x st = - match x with - | VRefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.ovals x st - | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref x st - -let p_vrefs ctxt = p_list (p_vref ctxt) - -let fill_u_ty, u_ty = u_hole() -let u_tys = (u_list u_ty) -let fill_u_attribs, u_attribs = u_hole() - -let u_nonlocal_val_ref st : NonLocalValOrMemberRef = - let a = u_tcref st - let b1 = u_option u_string st - let b2 = u_bool st - let b3 = u_string st - let c = u_int st - let d = u_option u_ty st - { EnclosingEntity = a - ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } - -let u_vref st = - let tag = u_byte st - match tag with - | 0 -> u_local_item_ref st.ivals st |> (fun x -> VRefLocal x) - | 1 -> u_nonlocal_val_ref st |> (fun x -> VRefNonLocal x) - | _ -> ufailwith st "u_item_ref" - -let u_vrefs = u_list u_vref - -let p_kind x st = - p_byte (match x with - | TyparKind.Type -> 0 - | TyparKind.Measure -> 1) st - -let p_member_kind x st = - p_byte (match x with - | MemberKind.Member -> 0 - | MemberKind.PropertyGet -> 1 - | MemberKind.PropertySet -> 2 - | MemberKind.Constructor -> 3 - | MemberKind.ClassConstructor -> 4 - | MemberKind.PropertyGetSet -> pfailwith st "pickling: MemberKind.PropertyGetSet only expected in parse trees") st - -let u_kind st = - match u_byte st with - | 0 -> TyparKind.Type - | 1 -> TyparKind.Measure - | _ -> ufailwith st "u_kind" - -let u_member_kind st = - match u_byte st with - | 0 -> MemberKind.Member - | 1 -> MemberKind.PropertyGet - | 2 -> MemberKind.PropertySet - | 3 -> MemberKind.Constructor - | 4 -> MemberKind.ClassConstructor - | _ -> ufailwith st "u_member_kind" - -let p_MemberFlags x st = - p_tup6 p_bool p_bool p_bool p_bool p_bool p_member_kind - (x.IsInstance, - false (* _x3UnusedBoolInFormat *), - x.IsDispatchSlot, - x.IsOverrideOrExplicitImpl, - x.IsFinal, - x.MemberKind) st -let u_MemberFlags st = - let x2, _x3UnusedBoolInFormat, x4, x5, x6, x7 = u_tup6 u_bool u_bool u_bool u_bool u_bool u_member_kind st - { IsInstance=x2 - IsDispatchSlot=x4 - IsOverrideOrExplicitImpl=x5 - IsFinal=x6 - MemberKind=x7} - -let fill_u_Expr_hole, u_expr_fwd = u_hole() -let fill_p_Expr_hole, p_expr_fwd = p_hole() - -let p_anonInfo_data (anonInfo: AnonRecdTypeInfo) st = - p_tup3 p_ccuref p_bool (p_array p_ident) (anonInfo.Assembly, evalTupInfoIsStruct anonInfo.TupInfo, anonInfo.SortedIds) st - -let p_anonInfo x st = - p_osgn_decl st.oanoninfos p_anonInfo_data x st - -let p_trait_sln sln st = - match sln with - | ILMethSln(a, b, c, d) -> - p_byte 0 st; p_tup4 p_ty (p_option p_ILTypeRef) p_ILMethodRef p_tys (a, b, c, d) st - | FSMethSln(a, b, c) -> - p_byte 1 st; p_tup3 p_ty (p_vref "trait") p_tys (a, b, c) st - | BuiltInSln -> - p_byte 2 st - | ClosedExprSln expr -> - p_byte 3 st; p_expr_fwd expr st - | FSRecdFieldSln(a, b, c) -> - p_byte 4 st; p_tup3 p_tys p_rfref p_bool (a, b, c) st - | FSAnonRecdFieldSln(a, b, c) -> - p_byte 5 st; p_tup3 p_anonInfo p_tys p_int (a, b, c) st - - -let p_trait (TTrait(a, b, c, d, e, f)) st = - p_tup6 p_tys p_string p_MemberFlags p_tys (p_option p_ty) (p_option p_trait_sln) (a, b, c, d, e, !f) st - -let u_anonInfo_data st = - let (ccu, info, nms) = u_tup3 u_ccuref u_bool (u_array u_ident) st - AnonRecdTypeInfo.Create (ccu, mkTupInfo info, nms) - -let u_anonInfo st = - u_osgn_decl st.ianoninfos u_anonInfo_data st - -// We have to store trait solutions since they can occur in optimization data -let u_trait_sln st = - let tag = u_byte st - match tag with - | 0 -> - let (a, b, c, d) = u_tup4 u_ty (u_option u_ILTypeRef) u_ILMethodRef u_tys st - ILMethSln(a, b, c, d) - | 1 -> - let (a, b, c) = u_tup3 u_ty u_vref u_tys st - FSMethSln(a, b, c) - | 2 -> - BuiltInSln - | 3 -> - ClosedExprSln (u_expr_fwd st) - | 4 -> - let (a, b, c) = u_tup3 u_tys u_rfref u_bool st - FSRecdFieldSln(a, b, c) - | 5 -> - let (a, b, c) = u_tup3 u_anonInfo u_tys u_int st - FSAnonRecdFieldSln(a, b, c) - | _ -> ufailwith st "u_trait_sln" - -let u_trait st = - let a, b, c, d, e, f = u_tup6 u_tys u_string u_MemberFlags u_tys (u_option u_ty) (u_option u_trait_sln) st - TTrait (a, b, c, d, e, ref f) - - -let p_rational q st = p_int32 (GetNumerator q) st; p_int32 (GetDenominator q) st - -let p_measure_con tcref st = p_byte 0 st; p_tcref "measure" tcref st - -let p_measure_var v st = p_byte 3 st; p_tpref v st - -let p_measure_one = p_byte 4 - -// Pickle a unit-of-measure variable or constructor -let p_measure_varcon unt st = - match unt with - | Measure.Con tcref -> p_measure_con tcref st - | Measure.Var v -> p_measure_var v st - | _ -> pfailwith st ("p_measure_varcon: expected measure variable or constructor") - -// Pickle a positive integer power of a unit-of-measure variable or constructor -let rec p_measure_pospower unt n st = - if n = 1 - then p_measure_varcon unt st - else p_byte 2 st; p_measure_varcon unt st; p_measure_pospower unt (n-1) st - -// Pickle a non-zero integer power of a unit-of-measure variable or constructor -let p_measure_intpower unt n st = - if n < 0 - then p_byte 1 st; p_measure_pospower unt (-n) st - else p_measure_pospower unt n st - -// Pickle a rational power of a unit-of-measure variable or constructor -let rec p_measure_power unt q st = - if q = ZeroRational then p_measure_one st - elif GetDenominator q = 1 - then p_measure_intpower unt (GetNumerator q) st - else p_byte 5 st; p_measure_varcon unt st; p_rational q st - -// Pickle a normalized unit-of-measure expression -// Normalized means of the form cv1 ^ q1 * ... * cvn ^ qn -// where q1, ..., qn are non-zero, and cv1, ..., cvn are distinct unit-of-measure variables or constructors -let rec p_normalized_measure unt st = - let unt = stripUnitEqnsAux false unt - match unt with - | Measure.Con tcref -> p_measure_con tcref st - | Measure.Inv x -> p_byte 1 st; p_normalized_measure x st - | Measure.Prod(x1, x2) -> p_byte 2 st; p_normalized_measure x1 st; p_normalized_measure x2 st - | Measure.Var v -> p_measure_var v st - | Measure.One -> p_measure_one st - | Measure.RationalPower(x, q) -> p_measure_power x q st - -// By normalizing the unit-of-measure and treating integer powers as a special case, -// we ensure that the pickle format for rational powers of units (byte 5 followed by -// numerator and denominator) is used only when absolutely necessary, maintaining -// compatibility of formats with versions prior to F# 4.0. -// -// See https://github.com/Microsoft/visualfsharp/issues/69 -let p_measure_expr unt st = p_normalized_measure (normalizeMeasure st.oglobals unt) st - -let u_rational st = - let a, b = u_tup2 u_int32 u_int32 st in DivRational (intToRational a) (intToRational b) - -let rec u_measure_expr st = - let tag = u_byte st - match tag with - | 0 -> let a = u_tcref st in Measure.Con a - | 1 -> let a = u_measure_expr st in Measure.Inv a - | 2 -> let a, b = u_tup2 u_measure_expr u_measure_expr st in Measure.Prod (a, b) - | 3 -> let a = u_tpref st in Measure.Var a - | 4 -> Measure.One - | 5 -> let a = u_measure_expr st in let b = u_rational st in Measure.RationalPower (a, b) - | _ -> ufailwith st "u_measure_expr" - -let p_tyar_constraint x st = - match x with - | TyparConstraint.CoercesTo (a, _) -> p_byte 0 st; p_ty a st - | TyparConstraint.MayResolveMember(traitInfo, _) -> p_byte 1 st; p_trait traitInfo st - | TyparConstraint.DefaultsTo(_, rty, _) -> p_byte 2 st; p_ty rty st - | TyparConstraint.SupportsNull _ -> p_byte 3 st - | TyparConstraint.IsNonNullableStruct _ -> p_byte 4 st - | TyparConstraint.IsReferenceType _ -> p_byte 5 st - | TyparConstraint.RequiresDefaultConstructor _ -> p_byte 6 st - | TyparConstraint.SimpleChoice(tys, _) -> p_byte 7 st; p_tys tys st - | TyparConstraint.IsEnum(ty, _) -> p_byte 8 st; p_ty ty st - | TyparConstraint.IsDelegate(aty, bty, _) -> p_byte 9 st; p_ty aty st; p_ty bty st - | TyparConstraint.SupportsComparison _ -> p_byte 10 st - | TyparConstraint.SupportsEquality _ -> p_byte 11 st - | TyparConstraint.IsUnmanaged _ -> p_byte 12 st -let p_tyar_constraints = (p_list p_tyar_constraint) - -let u_tyar_constraint st = - let tag = u_byte st - match tag with - | 0 -> u_ty st |> (fun a _ -> TyparConstraint.CoercesTo (a, range0) ) - | 1 -> u_trait st |> (fun a _ -> TyparConstraint.MayResolveMember(a, range0)) - | 2 -> u_ty st |> (fun a ridx -> TyparConstraint.DefaultsTo(ridx, a, range0)) - | 3 -> (fun _ -> TyparConstraint.SupportsNull range0) - | 4 -> (fun _ -> TyparConstraint.IsNonNullableStruct range0) - | 5 -> (fun _ -> TyparConstraint.IsReferenceType range0) - | 6 -> (fun _ -> TyparConstraint.RequiresDefaultConstructor range0) - | 7 -> u_tys st |> (fun a _ -> TyparConstraint.SimpleChoice(a, range0)) - | 8 -> u_ty st |> (fun a _ -> TyparConstraint.IsEnum(a, range0)) - | 9 -> u_tup2 u_ty u_ty st |> (fun (a, b) _ -> TyparConstraint.IsDelegate(a, b, range0)) - | 10 -> (fun _ -> TyparConstraint.SupportsComparison range0) - | 11 -> (fun _ -> TyparConstraint.SupportsEquality range0) - | 12 -> (fun _ -> TyparConstraint.IsUnmanaged range0) - | _ -> ufailwith st "u_tyar_constraint" - - -let u_tyar_constraints = (u_list_revi u_tyar_constraint) - - -let p_tyar_spec_data (x: Typar) st = - p_tup5 - p_ident - p_attribs - p_int64 - p_tyar_constraints - p_xmldoc - (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc) st - -let p_tyar_spec (x: Typar) st = - //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) - if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) - p_osgn_decl st.otypars p_tyar_spec_data x st - -let p_tyar_specs = (p_list p_tyar_spec) - -let u_tyar_spec_data st = - let a, c, d, e, g = u_tup5 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc st - { typar_id=a - typar_stamp=newStamp() - typar_flags=TyparFlags(int32 d) - typar_solution=None - typar_astype= Unchecked.defaultof<_> - typar_opt_data= - match g, e, c with - | XmlDoc [||], [], [] -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c } } - -let u_tyar_spec st = - u_osgn_decl st.itypars u_tyar_spec_data st - -let u_tyar_specs = (u_list u_tyar_spec) - -let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> - let ty = stripTyparEqns ty - - // See comment on 'checkForInRefStructThisArg' - let ty = - if isInByrefTy st.oglobals ty && isStructThisArgPos then - // Convert the inref to a byref - mkByrefTy st.oglobals (destByrefTy st.oglobals ty) - else - ty - - match ty with - | TType_tuple (tupInfo, l) -> - if evalTupInfoIsStruct tupInfo then - p_byte 8 st; p_tys l st - else - p_byte 0 st; p_tys l st - | TType_app(ERefNonLocal nleref, []) -> p_byte 1 st; p_simpletyp nleref st - | TType_app (tc, tinst) -> p_byte 2 st; p_tup2 (p_tcref "typ") p_tys (tc, tinst) st - | TType_fun (d, r) -> - p_byte 3 st - // Note, the "this" argument may be found in the domain position of a function type, so propagate the isStructThisArgPos value - p_ty2 isStructThisArgPos d st - p_ty r st - | TType_var r -> p_byte 4 st; p_tpref r st - | TType_forall (tps, r) -> - p_byte 5 st - p_tyar_specs tps st - // Note, the "this" argument may be found in the body of a generic forall type, so propagate the isStructThisArgPos value - p_ty2 isStructThisArgPos r st - | TType_measure unt -> p_byte 6 st; p_measure_expr unt st - | TType_ucase (uc, tinst) -> p_byte 7 st; p_tup2 p_ucref p_tys (uc, tinst) st - // p_byte 8 taken by TType_tuple above - | TType_anon (anonInfo, l) -> - p_byte 9 st - p_anonInfo anonInfo st - p_tys l st) - -let _ = fill_u_ty (fun st -> - let tag = u_byte st - match tag with - | 0 -> let l = u_tys st in TType_tuple (tupInfoRef, l) - | 1 -> u_simpletyp st - | 2 -> let tc = u_tcref st in let tinst = u_tys st in TType_app (tc, tinst) - | 3 -> let d = u_ty st in let r = u_ty st in TType_fun (d, r) - | 4 -> let r = u_tpref st in r.AsType - | 5 -> let tps = u_tyar_specs st in let r = u_ty st in TType_forall (tps, r) - | 6 -> let unt = u_measure_expr st in TType_measure unt - | 7 -> let uc = u_ucref st in let tinst = u_tys st in TType_ucase (uc, tinst) - | 8 -> let l = u_tys st in TType_tuple (tupInfoStruct, l) - | 9 -> let anonInfo = u_anonInfo st in let l = u_tys st in TType_anon (anonInfo, l) - | _ -> ufailwith st "u_typ") - - -let fill_p_binds, p_binds = p_hole() -let fill_p_targets, p_targets = p_hole() -let fill_p_Exprs, p_Exprs = p_hole() -let fill_p_constraints, p_constraints = p_hole() -let fill_p_Vals, p_Vals = p_hole() - -let fill_u_binds, u_binds = u_hole() -let fill_u_targets, u_targets = u_hole() -let fill_u_Exprs, u_Exprs = u_hole() -let fill_u_constraints, u_constraints = u_hole() -let fill_u_Vals, u_Vals = u_hole() - -let p_ArgReprInfo (x: ArgReprInfo) st = - p_attribs x.Attribs st - p_option p_ident x.Name st - -let p_TyparReprInfo (TyparReprInfo(a, b)) st = - p_ident a st - p_kind b st - -let p_ValReprInfo (ValReprInfo (a, args, ret)) st = - p_list p_TyparReprInfo a st - p_list (p_list p_ArgReprInfo) args st - p_ArgReprInfo ret st - -let u_ArgReprInfo st = - let a = u_attribs st - let b = u_option u_ident st - match a, b with - | [], None -> ValReprInfo.unnamedTopArg1 - | _ -> { Attribs = a; Name = b } - -let u_TyparReprInfo st = - let a = u_ident st - let b = u_kind st - TyparReprInfo(a, b) - -let u_ValReprInfo st = - let a = u_list u_TyparReprInfo st - let b = u_list (u_list u_ArgReprInfo) st - let c = u_ArgReprInfo st - ValReprInfo (a, b, c) - -let p_ranges x st = - p_option (p_tup2 p_range p_range) x st - -let p_istype x st = - match x with - | FSharpModuleWithSuffix -> p_byte 0 st - | ModuleOrType -> p_byte 1 st - | Namespace -> p_byte 2 st - -let p_cpath (CompPath(a, b)) st = - p_tup2 p_ILScopeRef (p_list (p_tup2 p_string p_istype)) (a, b) st - -let u_ranges st = u_option (u_tup2 u_range u_range) st - -let u_istype st = - let tag = u_byte st - match tag with - | 0 -> FSharpModuleWithSuffix - | 1 -> ModuleOrType - | 2 -> Namespace - | _ -> ufailwith st "u_istype" - -let u_cpath st = let a, b = u_tup2 u_ILScopeRef (u_list (u_tup2 u_string u_istype)) st in (CompPath(a, b)) - - -let rec dummy x = x -and p_tycon_repr x st = - // The leading "p_byte 1" and "p_byte 0" come from the F# 2.0 format, which used an option value at this point. - match x with - | TRecdRepr fs -> p_byte 1 st; p_byte 0 st; p_rfield_table fs st; false - | TUnionRepr x -> p_byte 1 st; p_byte 1 st; p_array p_unioncase_spec (x.CasesTable.CasesByIndex) st; false - | TAsmRepr ilty -> p_byte 1 st; p_byte 2 st; p_ILType ilty st; false - | TFSharpObjectRepr r -> p_byte 1 st; p_byte 3 st; p_tycon_objmodel_data r st; false - | TMeasureableRepr ty -> p_byte 1 st; p_byte 4 st; p_ty ty st; false - | TNoRepr -> p_byte 0 st; false -#if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint info -> - if info.IsErased then - // Pickle erased type definitions as a NoRepr - p_byte 0 st; false - else - // Pickle generated type definitions as a TAsmRepr - p_byte 1 st; p_byte 2 st; p_ILType (mkILBoxedType(ILTypeSpec.Create(ExtensionTyping.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st; true - | TProvidedNamespaceExtensionPoint _ -> p_byte 0 st; false -#endif - | TILObjectRepr (TILObjectReprData (_, _, td)) -> error (Failure("Unexpected IL type definition"+td.Name)) - -and p_tycon_objmodel_data x st = - p_tup3 p_tycon_objmodel_kind (p_vrefs "vslots") p_rfield_table - (x.fsobjmodel_kind, x.fsobjmodel_vslots, x.fsobjmodel_rfields) st - -and p_attribs_ext f x st = p_list_ext f p_attrib x st - -and p_unioncase_spec x st = - p_rfield_table x.FieldTable st - p_ty x.ReturnType st - p_string x.CompiledName st - p_ident x.Id st - // The XmlDoc are only written for the extended in-memory format. We encode their presence using a marker bit here - p_attribs_ext (if st.oInMem then Some (p_xmldoc x.XmlDoc) else None) x.Attribs st - p_string x.XmlDocSig st - p_access x.Accessibility st - -and p_exnc_spec_data x st = p_entity_spec_data x st - -and p_exnc_repr x st = - match x with - | TExnAbbrevRepr x -> p_byte 0 st; (p_tcref "exn abbrev") x st - | TExnAsmRepr x -> p_byte 1 st; p_ILTypeRef x st - | TExnFresh x -> p_byte 2 st; p_rfield_table x st - | TExnNone -> p_byte 3 st - -and p_exnc_spec x st = p_entity_spec x st - -and p_access (TAccess n) st = p_list p_cpath n st - -and p_recdfield_spec x st = - p_bool x.rfield_mutable st - p_bool x.rfield_volatile st - p_ty x.rfield_type st - p_bool x.rfield_static st - p_bool x.rfield_secret st - p_option p_const x.rfield_const st - p_ident x.rfield_id st - p_attribs_ext (if st.oInMem then Some (p_xmldoc x.XmlDoc) else None) x.rfield_pattribs st - p_attribs x.rfield_fattribs st - p_string x.rfield_xmldocsig st - p_access x.rfield_access st - -and p_rfield_table x st = - p_array p_recdfield_spec (x.FieldsByIndex) st - -and p_entity_spec_data (x: Entity) st = - p_tyar_specs (x.entity_typars.Force(x.entity_range)) st - p_string x.entity_logical_name st - p_option p_string x.EntityCompiledName st - p_range x.entity_range st - p_option p_pubpath x.entity_pubpath st - p_access x.Accessibility st - p_access x.TypeReprAccessibility st - p_attribs x.entity_attribs st - let flagBit = p_tycon_repr x.entity_tycon_repr st - p_option p_ty x.TypeAbbrev st - p_tcaug x.entity_tycon_tcaug st - p_string System.String.Empty st - p_kind x.TypeOrMeasureKind st - p_int64 (x.entity_flags.PickledBits ||| (if flagBit then EntityFlags.ReservedBitForPickleFormatTyconReprFlag else 0L)) st - p_option p_cpath x.entity_cpath st - p_maybe_lazy p_modul_typ x.entity_modul_contents st - p_exnc_repr x.ExceptionInfo st - if st.oInMem then - p_used_space1 (p_xmldoc x.XmlDoc) st - else - p_space 1 () st - - -and p_tcaug p st = - p_tup9 - (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) - (p_option (p_vref "compare_withc")) - (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) - (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) - (p_list (p_tup2 p_string (p_vref "adhoc"))) - (p_list (p_tup3 p_ty p_bool p_dummy_range)) - (p_option p_ty) - p_bool - (p_space 1) - (p.tcaug_compare, - p.tcaug_compare_withc, - p.tcaug_hash_and_equals_withc, - p.tcaug_equals, - (p.tcaug_adhoc_list - |> ResizeArray.toList - // Explicit impls of interfaces only get kept in the adhoc list - // in order to get check the well-formedness of an interface. - // Keeping them across assembly boundaries is not valid, because relinking their ValRefs - // does not work correctly (they may get incorrectly relinked to a default member) - |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) - |> List.map (fun (_, vref) -> vref.LogicalName, vref)), - p.tcaug_interfaces, - p.tcaug_super, - p.tcaug_abstract, - space) st - -and p_entity_spec x st = p_osgn_decl st.oentities p_entity_spec_data x st - -and p_parentref x st = - match x with - | ParentNone -> p_byte 0 st - | Parent x -> p_byte 1 st; p_tcref "parent tycon" x st - -and p_attribkind x st = - match x with - | ILAttrib x -> p_byte 0 st; p_ILMethodRef x st - | FSAttrib x -> p_byte 1 st; p_vref "attrib" x st - -and p_attrib (Attrib (a, b, c, d, e, _targets, f)) st = // AttributeTargets are not preserved - p_tup6 (p_tcref "attrib") p_attribkind (p_list p_attrib_expr) (p_list p_attrib_arg) p_bool p_dummy_range (a, b, c, d, e, f) st - -and p_attrib_expr (AttribExpr(e1, e2)) st = - p_tup2 p_expr p_expr (e1, e2) st - -and p_attrib_arg (AttribNamedArg(a, b, c, d)) st = - p_tup4 p_string p_ty p_bool p_attrib_expr (a, b, c, d) st - -and p_member_info (x: ValMemberInfo) st = - p_tup4 (p_tcref "member_info") p_MemberFlags (p_list p_slotsig) p_bool - (x.ApparentEnclosingEntity, x.MemberFlags, x.ImplementedSlotSigs, x.IsImplemented) st - -and p_tycon_objmodel_kind x st = - match x with - | TTyconClass -> p_byte 0 st - | TTyconInterface -> p_byte 1 st - | TTyconStruct -> p_byte 2 st - | TTyconDelegate ss -> p_byte 3 st; p_slotsig ss st - | TTyconEnum -> p_byte 4 st - -and p_mustinline x st = - p_byte (match x with - | ValInline.PseudoVal -> 0 - | ValInline.Always -> 1 - | ValInline.Optional -> 2 - | ValInline.Never -> 3) st - -and p_basethis x st = - p_byte (match x with - | BaseVal -> 0 - | CtorThisVal -> 1 - | NormalVal -> 2 - | MemberThisVal -> 3) st - -and p_vrefFlags x st = - match x with - | NormalValUse -> p_byte 0 st - | CtorValUsedAsSuperInit -> p_byte 1 st - | CtorValUsedAsSelfInit -> p_byte 2 st - | PossibleConstrainedCall ty -> p_byte 3 st; p_ty ty st - | VSlotDirectCall -> p_byte 4 st - -and p_ValData x st = - p_string x.val_logical_name st - p_option p_string x.ValCompiledName st - // only keep range information on published values, not on optimization data - p_ranges (x.ValReprInfo |> Option.map (fun _ -> x.val_range, x.DefinitionRange)) st - - let isStructThisArgPos = x.IsMember && checkForInRefStructThisArg st x.Type - p_ty2 isStructThisArgPos x.val_type st - - p_int64 x.val_flags.PickledBits st - p_option p_member_info x.MemberInfo st - p_attribs x.Attribs st - p_option p_ValReprInfo x.ValReprInfo st - p_string x.XmlDocSig st - p_access x.Accessibility st - p_parentref x.DeclaringEntity st - p_option p_const x.LiteralValue st - if st.oInMem then - p_used_space1 (p_xmldoc x.XmlDoc) st - else - p_space 1 () st - -and p_Val x st = - p_osgn_decl st.ovals p_ValData x st - -and p_modul_typ (x: ModuleOrNamespaceType) st = - p_tup3 - p_istype - (p_qlist p_Val) - (p_qlist p_entity_spec) - (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) - st - -and u_tycon_repr st = - let tag1 = u_byte st - match tag1 with - | 0 -> (fun _flagBit -> TNoRepr) - | 1 -> - let tag2 = u_byte st - match tag2 with - | 0 -> - let v = u_rfield_table st - (fun _flagBit -> TRecdRepr v) - | 1 -> - let v = u_list u_unioncase_spec st - (fun _flagBit -> MakeUnionRepr v) - | 2 -> - let v = u_ILType st - // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format - // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will - // interpret provider-generated types as TAsmRepr. - (fun flagBit -> - if flagBit then - let iltref = v.TypeRef - match st.iILModule with - | None -> TNoRepr - | Some iILModule -> - try - let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = - match enclosingTypeNames with - | [] -> List.rev acc, tdefs.FindByName iltref.Name - | h :: t -> - let nestedTypeDef = tdefs.FindByName h - find (tdefs.FindByName h :: acc) t nestedTypeDef.NestedTypes - let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs - TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) - with _ -> - System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) - TNoRepr - else - TAsmRepr v) - | 3 -> - let v = u_tycon_objmodel_data st - (fun _flagBit -> TFSharpObjectRepr v) - | 4 -> - let v = u_ty st - (fun _flagBit -> TMeasureableRepr v) - | _ -> ufailwith st "u_tycon_repr" - | _ -> ufailwith st "u_tycon_repr" - -and u_tycon_objmodel_data st = - let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st - {fsobjmodel_kind=x1; fsobjmodel_vslots=x2; fsobjmodel_rfields=x3 } - -and u_attribs_ext extraf st = u_list_ext extraf u_attrib st -and u_unioncase_spec st = - let a = u_rfield_table st - let b = u_ty st - - // The union case compiled name is now computed from Id field when needed and is not stored in UnionCase record. - let _c = u_string st - let d = u_ident st - // The XmlDoc is only present in the extended in-memory format. We detect its presence using a marker bit here - let xmldoc, e = u_attribs_ext u_xmldoc st - let f = u_string st - let i = u_access st - { FieldTable=a - ReturnType=b - Id=d - Attribs=e - XmlDoc= defaultArg xmldoc XmlDoc.Empty - XmlDocSig=f - Accessibility=i - OtherRangeOpt=None } - -and u_exnc_spec_data st = u_entity_spec_data st - -and u_exnc_repr st = - let tag = u_byte st - match tag with - | 0 -> u_tcref st |> TExnAbbrevRepr - | 1 -> u_ILTypeRef st |> TExnAsmRepr - | 2 -> u_rfield_table st |> TExnFresh - | 3 -> TExnNone - | _ -> ufailwith st "u_exnc_repr" - -and u_exnc_spec st = u_entity_spec st - -and u_access st = - match u_list u_cpath st with - | [] -> taccessPublic // save unnecessary allocations - | res -> TAccess res - -and u_recdfield_spec st = - let a = u_bool st - let b = u_bool st - let c1 = u_ty st - let c2 = u_bool st - let c2b = u_bool st - let c3 = u_option u_const st - let d = u_ident st - // The XmlDoc is only present in the extended in-memory format. We detect its presence using a marker bit here - let xmldoc, e1 = u_attribs_ext u_xmldoc st - let e2 = u_attribs st - let f = u_string st - let g = u_access st - { rfield_mutable=a - rfield_volatile=b - rfield_type=c1 - rfield_static=c2 - rfield_secret=c2b - rfield_const=c3 - rfield_id=d - rfield_pattribs=e1 - rfield_fattribs=e2 - rfield_xmldoc= defaultArg xmldoc XmlDoc.Empty - rfield_xmldocsig=f - rfield_access=g - rfield_name_generated = false - rfield_other_range = None } - -and u_rfield_table st = MakeRecdFieldsTable (u_list u_recdfield_spec st) - -and u_entity_spec_data st : Entity = - let x1, x2a, x2b, x2c, x3, (x4a, x4b), x6, x7f, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = - u_tup17 - u_tyar_specs - u_string - (u_option u_string) - u_range - (u_option u_pubpath) - (u_tup2 u_access u_access) - u_attribs - u_tycon_repr - (u_option u_ty) - u_tcaug - u_string - u_kind - u_int64 - (u_option u_cpath ) - (u_lazy u_modul_typ) - u_exnc_repr - (u_used_space1 u_xmldoc) - st - // We use a bit that was unused in the F# 2.0 format to indicate two possible representations in the F# 3.0 tycon_repr format - let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) - let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag - - { entity_typars=LazyWithContext.NotLazy x1 - entity_stamp=newStamp() - entity_logical_name=x2a - entity_range=x2c - entity_pubpath=x3 - entity_attribs=x6 - entity_tycon_repr=x7 - entity_tycon_tcaug=x9 - entity_flags=EntityFlags x11 - entity_cpath=x12 - entity_modul_contents=MaybeLazy.Lazy x13 - entity_il_repr_cache=newCache() - entity_opt_data= - match x2b, x10b, x15, x8, x4a, x4b, x14 with - | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None - | _ -> - Some { Entity.NewEmptyEntityOptData() with - entity_compiled_name = x2b - entity_kind = x10b - entity_xmldoc= defaultArg x15 XmlDoc.Empty - entity_xmldocsig = System.String.Empty - entity_tycon_abbrev = x8 - entity_accessibility = x4a - entity_tycon_repr_accessibility = x4b - entity_exn_info = x14 } - } - -and u_tcaug st = - let a1, a2, a3, b2, c, d, e, g, _space = - u_tup9 - (u_option (u_tup2 u_vref u_vref)) - (u_option u_vref) - (u_option (u_tup3 u_vref u_vref u_vref)) - (u_option (u_tup2 u_vref u_vref)) - (u_list (u_tup2 u_string u_vref)) - (u_list (u_tup3 u_ty u_bool u_dummy_range)) - (u_option u_ty) - u_bool - (u_space 1) - st - {tcaug_compare=a1 - tcaug_compare_withc=a2 - tcaug_hash_and_equals_withc=a3 - tcaug_equals=b2 - // only used for code generation and checking - hence don't care about the values when reading back in - tcaug_hasObjectGetHashCode=false - tcaug_adhoc_list= new ResizeArray<_> (c |> List.map (fun (_, vref) -> (false, vref))) - tcaug_adhoc=NameMultiMap.ofList c - tcaug_interfaces=d - tcaug_super=e - // pickled type definitions are always closed (i.e. no more intrinsic members allowed) - tcaug_closed=true - tcaug_abstract=g} - -and u_entity_spec st = - u_osgn_decl st.ientities u_entity_spec_data st - -and u_parentref st = - let tag = u_byte st - match tag with - | 0 -> ParentNone - | 1 -> u_tcref st |> Parent - | _ -> ufailwith st "u_attribkind" - -and u_attribkind st = - let tag = u_byte st - match tag with - | 0 -> u_ILMethodRef st |> ILAttrib - | 1 -> u_vref st |> FSAttrib - | _ -> ufailwith st "u_attribkind" - -and u_attrib st : Attrib = - let a, b, c, d, e, f = u_tup6 u_tcref u_attribkind (u_list u_attrib_expr) (u_list u_attrib_arg) u_bool u_dummy_range st - Attrib(a, b, c, d, e, None, f) // AttributeTargets are not preserved - -and u_attrib_expr st = - let a, b = u_tup2 u_expr u_expr st - AttribExpr(a, b) - -and u_attrib_arg st = - let a, b, c, d = u_tup4 u_string u_ty u_bool u_attrib_expr st - AttribNamedArg(a, b, c, d) - -and u_member_info st : ValMemberInfo = - let x2, x3, x4, x5 = u_tup4 u_tcref u_MemberFlags (u_list u_slotsig) u_bool st - { ApparentEnclosingEntity=x2 - MemberFlags=x3 - ImplementedSlotSigs=x4 - IsImplemented=x5 } - -and u_tycon_objmodel_kind st = - let tag = u_byte st - match tag with - | 0 -> TTyconClass - | 1 -> TTyconInterface - | 2 -> TTyconStruct - | 3 -> u_slotsig st |> TTyconDelegate - | 4 -> TTyconEnum - | _ -> ufailwith st "u_tycon_objmodel_kind" - -and u_mustinline st = - match u_byte st with - | 0 -> ValInline.PseudoVal - | 1 -> ValInline.Always - | 2 -> ValInline.Optional - | 3 -> ValInline.Never - | _ -> ufailwith st "u_mustinline" - -and u_basethis st = - match u_byte st with - | 0 -> BaseVal - | 1 -> CtorThisVal - | 2 -> NormalVal - | 3 -> MemberThisVal - | _ -> ufailwith st "u_basethis" - -and u_vrefFlags st = - match u_byte st with - | 0 -> NormalValUse - | 1 -> CtorValUsedAsSuperInit - | 2 -> CtorValUsedAsSelfInit - | 3 -> PossibleConstrainedCall (u_ty st) - | 4 -> VSlotDirectCall - | _ -> ufailwith st "u_vrefFlags" - -and u_ValData st = - let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = - u_tup13 - u_string - (u_option u_string) - u_ranges - u_ty - u_int64 - (u_option u_member_info) - u_attribs - (u_option u_ValReprInfo) - u_string - u_access - u_parentref - (u_option u_const) - (u_used_space1 u_xmldoc) - st - - { val_logical_name = x1 - val_range = (match x1a with None -> range0 | Some(a, _) -> a) - val_type = x2 - val_stamp = newStamp() - val_flags = ValFlags x4 - val_opt_data = - match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with - | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None - | _ -> - Some { val_compiled_name = x1z - val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) - val_defn = None - val_repr_info = x10 - val_const = x14 - val_access = x13 - val_xmldoc = defaultArg x15 XmlDoc.Empty - val_member_info = x8 - val_declaring_entity = x13b - val_xmldocsig = x12 - val_attribs = x9 } - } - -and u_Val st = u_osgn_decl st.ivals u_ValData st - - -and u_modul_typ st = - let x1, x3, x5 = - u_tup3 - u_istype - (u_qlist u_Val) - (u_qlist u_entity_spec) st - ModuleOrNamespaceType(x1, x3, x5) - - -//--------------------------------------------------------------------------- -// Pickle/unpickle for F# expressions (for optimization data) -//--------------------------------------------------------------------------- - -and p_const x st = - match x with - | Const.Bool x -> p_byte 0 st; p_bool x st - | Const.SByte x -> p_byte 1 st; p_int8 x st - | Const.Byte x -> p_byte 2 st; p_uint8 x st - | Const.Int16 x -> p_byte 3 st; p_int16 x st - | Const.UInt16 x -> p_byte 4 st; p_uint16 x st - | Const.Int32 x -> p_byte 5 st; p_int32 x st - | Const.UInt32 x -> p_byte 6 st; p_uint32 x st - | Const.Int64 x -> p_byte 7 st; p_int64 x st - | Const.UInt64 x -> p_byte 8 st; p_uint64 x st - | Const.IntPtr x -> p_byte 9 st; p_int64 x st - | Const.UIntPtr x -> p_byte 10 st; p_uint64 x st - | Const.Single x -> p_byte 11 st; p_single x st - | Const.Double x -> p_byte 12 st; p_int64 (bits_of_float x) st - | Const.Char c -> p_byte 13 st; p_char c st - | Const.String s -> p_byte 14 st; p_string s st - | Const.Unit -> p_byte 15 st - | Const.Zero -> p_byte 16 st - | Const.Decimal s -> p_byte 17 st; p_array p_int32 (System.Decimal.GetBits s) st - -and u_const st = - let tag = u_byte st - match tag with - | 0 -> u_bool st |> Const.Bool - | 1 -> u_int8 st |> Const.SByte - | 2 -> u_uint8 st |> Const.Byte - | 3 -> u_int16 st |> Const.Int16 - | 4 -> u_uint16 st |> Const.UInt16 - | 5 -> u_int32 st |> Const.Int32 - | 6 -> u_uint32 st |> Const.UInt32 - | 7 -> u_int64 st |> Const.Int64 - | 8 -> u_uint64 st |> Const.UInt64 - | 9 -> u_int64 st |> Const.IntPtr - | 10 -> u_uint64 st |> Const.UIntPtr - | 11 -> u_single st |> Const.Single - | 12 -> u_int64 st |> float_of_bits |> Const.Double - | 13 -> u_char st |> Const.Char - | 14 -> u_string st |> Const.String - | 15 -> Const.Unit - | 16 -> Const.Zero - | 17 -> u_array u_int32 st |> (fun bits -> Const.Decimal (System.Decimal bits)) - | _ -> ufailwith st "u_const" - - -and p_dtree x st = - match x with - | TDSwitch (a, b, c, d) -> p_byte 0 st; p_tup4 p_expr (p_list p_dtree_case) (p_option p_dtree) p_dummy_range (a, b, c, d) st - | TDSuccess (a, b) -> p_byte 1 st; p_tup2 p_Exprs p_int (a, b) st - | TDBind (a, b) -> p_byte 2 st; p_tup2 p_bind p_dtree (a, b) st - -and p_dtree_case (TCase(a, b)) st = p_tup2 p_dtree_discrim p_dtree (a, b) st - -and p_dtree_discrim x st = - match x with - | DecisionTreeTest.UnionCase (ucref, tinst) -> p_byte 0 st; p_tup2 p_ucref p_tys (ucref, tinst) st - | DecisionTreeTest.Const c -> p_byte 1 st; p_const c st - | DecisionTreeTest.IsNull -> p_byte 2 st - | DecisionTreeTest.IsInst (srcty, tgty) -> p_byte 3 st; p_ty srcty st; p_ty tgty st - | DecisionTreeTest.ArrayLength (n, ty) -> p_byte 4 st; p_tup2 p_int p_ty (n, ty) st - | DecisionTreeTest.ActivePatternCase _ -> pfailwith st "DecisionTreeTest.ActivePatternCase: only used during pattern match compilation" - -and p_target (TTarget(a, b, _)) st = p_tup2 p_Vals p_expr (a, b) st -and p_bind (TBind(a, b, _)) st = p_tup2 p_Val p_expr (a, b) st - -and p_lval_op_kind x st = - p_byte (match x with LAddrOf _ -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st - -and p_recdInfo x st = - match x with - | RecdExpr -> () - | RecdExprIsObjInit -> pfailwith st "explicit object constructors can't be inlined and should not have optimization information" - -and u_dtree st = - let tag = u_byte st - match tag with - | 0 -> u_tup4 u_expr (u_list u_dtree_case) (u_option u_dtree) u_dummy_range st |> TDSwitch - | 1 -> u_tup2 u_Exprs u_int st |> TDSuccess - | 2 -> u_tup2 u_bind u_dtree st |> TDBind - | _ -> ufailwith st "u_dtree" - -and u_dtree_case st = let a, b = u_tup2 u_dtree_discrim u_dtree st in (TCase(a, b)) - -and u_dtree_discrim st = - let tag = u_byte st - match tag with - | 0 -> u_tup2 u_ucref u_tys st |> DecisionTreeTest.UnionCase - | 1 -> u_const st |> DecisionTreeTest.Const - | 2 -> DecisionTreeTest.IsNull - | 3 -> u_tup2 u_ty u_ty st |> DecisionTreeTest.IsInst - | 4 -> u_tup2 u_int u_ty st |> DecisionTreeTest.ArrayLength - | _ -> ufailwith st "u_dtree_discrim" - -and u_target st = let a, b = u_tup2 u_Vals u_expr st in (TTarget(a, b, SuppressSequencePointAtTarget)) - -and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a, b, NoSequencePointAtStickyBinding) - -and u_lval_op_kind st = - match u_byte st with - | 0 -> LAddrOf false - | 1 -> LByrefGet - | 2 -> LSet - | 3 -> LByrefSet - | _ -> ufailwith st "uval_op_kind" - - -and p_op x st = - match x with - | TOp.UnionCase c -> p_byte 0 st; p_ucref c st - | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st - | TOp.Tuple tupInfo -> - if evalTupInfoIsStruct tupInfo then - p_byte 29 st - else - p_byte 2 st - | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st - | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st - | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st - | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st - | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st - | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st - | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st - | TOp.TupleFieldGet (tupInfo, a) -> - if evalTupInfoIsStruct tupInfo then - p_byte 30 st; p_int a st - else - p_byte 11 st; p_int a st - | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st - | TOp.RefAddrGet _ -> p_byte 13 st - | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st - | TOp.Coerce -> p_byte 15 st - | TOp.TraitCall b -> p_byte 16 st; p_trait b st - | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st - | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) - -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st - | TOp.Array -> p_byte 19 st - | TOp.While _ -> p_byte 20 st - | TOp.For (_, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st - | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st - | TOp.TryCatch _ -> p_byte 23 st - | TOp.TryFinally _ -> p_byte 24 st - | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st - | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st - | TOp.Reraise -> p_byte 27 st - | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st - // Note tag byte 29 is taken for struct tuples, see above - // Note tag byte 30 is taken for struct tuples, see above - (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) - (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) - | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st - | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st - | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" - -and u_op st = - let tag = u_byte st - match tag with - | 0 -> let a = u_ucref st - TOp.UnionCase a - | 1 -> let a = u_tcref st - TOp.ExnConstr a - | 2 -> TOp.Tuple tupInfoRef - | 3 -> let b = u_tcref st - TOp.Recd (RecdExpr, b) - | 4 -> let a = u_rfref st - TOp.ValFieldSet a - | 5 -> let a = u_rfref st - TOp.ValFieldGet a - | 6 -> let a = u_tcref st - TOp.UnionCaseTagGet a - | 7 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGet (a, b) - | 8 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldSet (a, b) - | 9 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldGet (a, b) - | 10 -> let a = u_tcref st - let b = u_int st - TOp.ExnFieldSet (a, b) - | 11 -> let a = u_int st - TOp.TupleFieldGet (tupInfoRef, a) - | 12 -> let a = (u_list u_ILInstr) st - let b = u_tys st - TOp.ILAsm (a, b) - | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes - | 14 -> let a = u_ucref st - TOp.UnionCaseProof a - | 15 -> TOp.Coerce - | 16 -> let a = u_trait st - TOp.TraitCall a - | 17 -> let a = u_lval_op_kind st - let b = u_vref st - TOp.LValueOp (a, b) - | 18 -> let (a1, a2, a3, a4, a5, a7, a8, a9) = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st - let b = u_tys st - let c = u_tys st - let d = u_tys st - TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) - | 19 -> TOp.Array - | 20 -> TOp.While (NoSequencePointAtWhileLoop, NoSpecialWhileLoopMarker) - | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" - TOp.For (NoSequencePointAtForLoop, dir) - | 22 -> TOp.Bytes (u_bytes st) - | 23 -> TOp.TryCatch (NoSequencePointAtTry, NoSequencePointAtWith) - | 24 -> TOp.TryFinally (NoSequencePointAtTry, NoSequencePointAtFinally) - | 25 -> let a = u_rfref st - TOp.ValFieldGetAddr (a, false) - | 26 -> TOp.UInt16s (u_array u_uint16 st) - | 27 -> TOp.Reraise - | 28 -> let a = u_ucref st - let b = u_int st - TOp.UnionCaseFieldGetAddr (a, b, false) - | 29 -> TOp.Tuple tupInfoStruct - | 30 -> let a = u_int st - TOp.TupleFieldGet (tupInfoStruct, a) - | 31 -> let info = u_anonInfo st - TOp.AnonRecd info - | 32 -> let info = u_anonInfo st - let n = u_int st - TOp.AnonRecdGet (info, n) - | _ -> ufailwith st "u_op" - -and p_expr expr st = - match expr with - | Expr.Link e -> p_expr !e st - | Expr.Const (x, m, ty) -> p_byte 0 st; p_tup3 p_const p_dummy_range p_ty (x, m, ty) st - | Expr.Val (a, b, m) -> p_byte 1 st; p_tup3 (p_vref "val") p_vrefFlags p_dummy_range (a, b, m) st - | Expr.Op (a, b, c, d) -> p_byte 2 st; p_tup4 p_op p_tys p_Exprs p_dummy_range (a, b, c, d) st - | Expr.Sequential (a, b, c, _, d) -> p_byte 3 st; p_tup4 p_expr p_expr p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st - | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 4 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr p_dummy_range p_ty (a1, b0, b1, c, d, e) st - | Expr.TyLambda (_, b, c, d, e) -> p_byte 5 st; p_tup4 p_tyar_specs p_expr p_dummy_range p_ty (b, c, d, e) st - | Expr.App (a1, a2, b, c, d) -> p_byte 6 st; p_tup5 p_expr p_ty p_tys p_Exprs p_dummy_range (a1, a2, b, c, d) st - | Expr.LetRec (a, b, c, _) -> p_byte 7 st; p_tup3 p_binds p_expr p_dummy_range (a, b, c) st - | Expr.Let (a, b, c, _) -> p_byte 8 st; p_tup3 p_bind p_expr p_dummy_range (a, b, c) st - | Expr.Match (_, a, b, c, d, e) -> p_byte 9 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty (a, b, c, d, e) st - | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 10 st; p_tup6 p_ty (p_option p_Val) p_expr p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st - | Expr.StaticOptimization (a, b, c, d) -> p_byte 11 st; p_tup4 p_constraints p_expr p_expr p_dummy_range (a, b, c, d) st - | Expr.TyChoose (a, b, c) -> p_byte 12 st; p_tup3 p_tyar_specs p_expr p_dummy_range (a, b, c) st - | Expr.Quote (ast, _, _, m, ty) -> p_byte 13 st; p_tup3 p_expr p_dummy_range p_ty (ast, m, ty) st - -and u_expr st = - let tag = u_byte st - match tag with - | 0 -> let a = u_const st - let b = u_dummy_range st - let c = u_ty st - Expr.Const (a, b, c) - | 1 -> let a = u_vref st - let b = u_vrefFlags st - let c = u_dummy_range st - Expr.Val (a, b, c) - | 2 -> let a = u_op st - let b = u_tys st - let c = u_Exprs st - let d = u_dummy_range st - Expr.Op (a, b, c, d) - | 3 -> let a = u_expr st - let b = u_expr st - let c = u_int st - let d = u_dummy_range st - Expr.Sequential (a, b, (match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag"), SuppressSequencePointOnExprOfSequential, d) - | 4 -> let a0 = u_option u_Val st - let b0 = u_option u_Val st - let b1 = u_Vals st - let c = u_expr st - let d = u_dummy_range st - let e = u_ty st - Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) - | 5 -> let b = u_tyar_specs st - let c = u_expr st - let d = u_dummy_range st - let e = u_ty st - Expr.TyLambda (newUnique(), b, c, d, e) - | 6 -> let a1 = u_expr st - let a2 = u_ty st - let b = u_tys st - let c = u_Exprs st - let d = u_dummy_range st - Expr.App (a1, a2, b, c, d) - | 7 -> let a = u_binds st - let b = u_expr st - let c = u_dummy_range st - Expr.LetRec (a, b, c, NewFreeVarsCache()) - | 8 -> let a = u_bind st - let b = u_expr st - let c = u_dummy_range st - Expr.Let (a, b, c, NewFreeVarsCache()) - | 9 -> let a = u_dummy_range st - let b = u_dtree st - let c = u_targets st - let d = u_dummy_range st - let e = u_ty st - Expr.Match (NoSequencePointAtStickyBinding, a, b, c, d, e) - | 10 -> let b = u_ty st - let c = (u_option u_Val) st - let d = u_expr st - let e = u_methods st - let f = u_intfs st - let g = u_dummy_range st - Expr.Obj (newUnique(), b, c, d, e, f, g) - | 11 -> let a = u_constraints st - let b = u_expr st - let c = u_expr st - let d = u_dummy_range st - Expr.StaticOptimization (a, b, c, d) - | 12 -> let a = u_tyar_specs st - let b = u_expr st - let c = u_dummy_range st - Expr.TyChoose (a, b, c) - | 13 -> let b = u_expr st - let c = u_dummy_range st - let d = u_ty st - Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false - | _ -> ufailwith st "u_expr" - -and p_static_optimization_constraint x st = - match x with - | TTyconEqualsTycon (a, b) -> p_byte 0 st; p_tup2 p_ty p_ty (a, b) st - | TTyconIsStruct a -> p_byte 1 st; p_ty a st - -and p_slotparam (TSlotParam (a, b, c, d, e, f)) st = p_tup6 (p_option p_string) p_ty p_bool p_bool p_bool p_attribs (a, b, c, d, e, f) st -and p_slotsig (TSlotSig (a, b, c, d, e, f)) st = p_tup6 p_string p_ty p_tyar_specs p_tyar_specs (p_list (p_list p_slotparam)) (p_option p_ty) (a, b, c, d, e, f) st -and p_method (TObjExprMethod (a, b, c, d, e, f)) st = p_tup6 p_slotsig p_attribs p_tyar_specs (p_list p_Vals) p_expr p_dummy_range (a, b, c, d, e, f) st -and p_methods x st = p_list p_method x st -and p_intf x st = p_tup2 p_ty p_methods x st -and p_intfs x st = p_list p_intf x st - -and u_static_optimization_constraint st = - let tag = u_byte st - match tag with - | 0 -> u_tup2 u_ty u_ty st |> TTyconEqualsTycon - | 1 -> u_ty st |> TTyconIsStruct - | _ -> ufailwith st "u_static_optimization_constraint" - -and u_slotparam st = - let a, b, c, d, e, f = u_tup6 (u_option u_string) u_ty u_bool u_bool u_bool u_attribs st - TSlotParam(a, b, c, d, e, f) - -and u_slotsig st = - let a, b, c, d, e, f = u_tup6 u_string u_ty u_tyar_specs u_tyar_specs (u_list (u_list u_slotparam)) (u_option u_ty) st - TSlotSig(a, b, c, d, e, f) - -and u_method st = - let a, b, c, d, e, f = u_tup6 u_slotsig u_attribs u_tyar_specs (u_list u_Vals) u_expr u_dummy_range st - TObjExprMethod(a, b, c, d, e, f) - -and u_methods st = u_list u_method st - -and u_intf st = u_tup2 u_ty u_methods st - -and u_intfs st = u_list u_intf st - -let _ = fill_p_binds (p_List p_bind) -let _ = fill_p_targets (p_array p_target) -let _ = fill_p_constraints (p_list p_static_optimization_constraint) -let _ = fill_p_Exprs (p_list p_expr) -let _ = fill_p_Expr_hole p_expr -let _ = fill_p_Exprs (p_List p_expr) -let _ = fill_p_attribs (p_list p_attrib) -let _ = fill_p_Vals (p_list p_Val) - -let _ = fill_u_binds (u_List u_bind) -let _ = fill_u_targets (u_array u_target) -let _ = fill_u_constraints (u_list u_static_optimization_constraint) -let _ = fill_u_Exprs (u_list u_expr) -let _ = fill_u_Expr_hole u_expr -let _ = fill_u_attribs (u_list u_attrib) -let _ = fill_u_Vals (u_list u_Val) - -//--------------------------------------------------------------------------- -// Pickle/unpickle F# interface data -//--------------------------------------------------------------------------- - -let pickleModuleOrNamespace mspec st = p_entity_spec mspec st - -let pickleCcuInfo (minfo: PickledCcuInfo) st = - p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations, ()) st - -let unpickleModuleOrNamespace st = u_entity_spec st - -let unpickleCcuInfo st = - let a, b, c, _space = u_tup4 unpickleModuleOrNamespace u_string u_bool (u_space 3) st - { mspec=a; compileTimeWorkingDir=b; usesQuotations=c } diff --git a/src/fsharp/TastPickle.fsi b/src/fsharp/TastPickle.fsi deleted file mode 100644 index e3d9379c07d..00000000000 --- a/src/fsharp/TastPickle.fsi +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// Defines the framework for serializing and de-serializing TAST data structures as binary blobs for the F# metadata format. -module internal FSharp.Compiler.TastPickle - -open Internal.Utilities -open FSharp.Compiler -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals - -/// Represents deserialized data with a dangling set of CCU fixup thunks indexed by name -[] -type PickledDataWithReferences<'RawData> = - { /// The data that uses a collection of CcuThunks internally - RawData: 'RawData - /// The assumptions that need to be fixed up - FixupThunks: CcuThunk [] } - - member Fixup : (CcuReference -> CcuThunk) -> 'RawData - /// Like Fixup but loader may return None, in which case there is no fixup. - member OptionalFixup: (CcuReference -> CcuThunk option) -> 'RawData - -/// The type of state written to by picklers -type WriterState - -/// A function to pickle a value into a given stateful writer -type pickler<'T> = 'T -> WriterState -> unit - -/// Serialize a byte -val internal p_byte : int -> WriterState -> unit - -/// Serialize a boolean value -val internal p_bool : bool -> WriterState -> unit - -/// Serialize an integer -val internal p_int : int -> WriterState -> unit - -/// Serialize a string -val internal p_string : string -> WriterState -> unit - -/// Serialize a lazy value (eagerly) -val internal p_lazy : pickler<'T> -> Lazy<'T> pickler - -/// Serialize a tuple of data -val inline internal p_tup2 : pickler<'T1> -> pickler<'T2> -> pickler<'T1 * 'T2> - -/// Serialize a tuple of data -val inline internal p_tup3 : pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T1 * 'T2 * 'T3> - -/// Serialize a tuple of data -val inline internal p_tup4 : pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T4> -> pickler<'T1 * 'T2 * 'T3 * 'T4> - -/// Serialize an array of data -val internal p_array : pickler<'T> -> pickler<'T[]> - -/// Serialize a namemap of data -val internal p_namemap : pickler<'T> -> pickler> - -/// Serialize a TAST constant -val internal p_const : pickler - -/// Serialize a TAST value reference -val internal p_vref : string -> pickler - -/// Serialize a TAST type or entity reference -val internal p_tcref : string -> pickler - -/// Serialize a TAST union case reference -val internal p_ucref : pickler - -/// Serialize a TAST expression -val internal p_expr : pickler - -/// Serialize a TAST type -val internal p_ty : pickler - -/// Serialize a TAST description of a compilation unit -val internal pickleCcuInfo : pickler - -/// Serialize an arbitrary object using the given pickler -val pickleObjWithDanglingCcus : inMem: bool -> file: string -> TcGlobals -> scope:CcuThunk -> pickler<'T> -> 'T -> byte[] - -/// The type of state unpicklers read from -type ReaderState - -/// A function to read a value from a given state -type unpickler<'T> = ReaderState -> 'T - -/// Deserialize a byte -val internal u_byte : ReaderState -> int - -/// Deserialize a bool -val internal u_bool : ReaderState -> bool - -/// Deserialize an integer -val internal u_int : ReaderState -> int - -/// Deserialize a string -val internal u_string : ReaderState -> string - -/// Deserialize a lazy value (eagerly) -val internal u_lazy : unpickler<'T> -> unpickler> - -/// Deserialize a tuple -val inline internal u_tup2 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T2 * 'T3> - -/// Deserialize a tuple -val inline internal u_tup3 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T2 * 'T3 * 'T4> - -/// Deserialize a tuple -val inline internal u_tup4 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T5> -> unpickler<'T2 * 'T3 * 'T4 * 'T5> - -/// Deserialize an array of values -val internal u_array : unpickler<'T> -> unpickler<'T[]> - -/// Deserialize a namemap -val internal u_namemap : unpickler<'T> -> unpickler> - -/// Deserialize a TAST constant -val internal u_const : unpickler - -/// Deserialize a TAST value reference -val internal u_vref : unpickler - -/// Deserialize a TAST type reference -val internal u_tcref : unpickler - -/// Deserialize a TAST union case reference -val internal u_ucref : unpickler - -/// Deserialize a TAST expression -val internal u_expr : unpickler - -/// Deserialize a TAST type -val internal u_ty : unpickler - -/// Deserialize a TAST description of a compilation unit -val internal unpickleCcuInfo : ReaderState -> PickledCcuInfo - -/// Deserialize an arbitrary object which may have holes referring to other compilation units -val internal unpickleObjWithDanglingCcus : file:string -> viewedScope:ILScopeRef -> ilModule:ILModuleDef option -> ('T unpickler) -> ReadOnlyByteMemory -> PickledDataWithReferences<'T> - - - diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index c70a378f6f2..fa82099c85a 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -2,27 +2,26 @@ /// Defines the global environment for all type checking. /// -/// The environment (TcGlobals) are well-known types and values are hard-wired +/// The environment (TcGlobals) are well-known types and values are hard-wired /// into the compiler. This lets the compiler perform particular optimizations /// for these types and values, for example emitting optimized calls for -/// comparison and hashing functions. +/// comparison and hashing functions. module internal FSharp.Compiler.TcGlobals -open System.Collections.Generic +open System.Collections.Concurrent open System.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Internal.Library - -open FSharp.Compiler.Tast -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILX +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.Features +open FSharp.Compiler.IO +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text.FileIndex +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics open Internal.Utilities @@ -31,7 +30,7 @@ let private envRange = rangeN DummyFileNameForRangesWithoutASpecificLocation 0 /// Represents an intrinsic value from FSharp.Core known to the compiler [] -type IntrinsicValRef = +type IntrinsicValRef = | IntrinsicValRef of NonLocalEntityRef * string * bool * TType * ValLinkageFullKey member x.Name = (let (IntrinsicValRef(_, nm, _, _, _)) = x in nm) @@ -42,15 +41,15 @@ type IntrinsicValRef = /// For debugging override x.ToString() = x.Name - + let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef mvr key //------------------------------------------------------------------------- // Access the initial environment: names -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- [] -module FSharpLib = +module FSharpLib = let CoreOperatorsCheckedName = FSharpLib.Root + ".Core.Operators.Checked" let ControlName = FSharpLib.Root + ".Control" @@ -60,19 +59,19 @@ module FSharpLib = let CompilerServicesName = FSharpLib.Root + ".Core.CompilerServices" let LinqRuntimeHelpersName = FSharpLib.Root + ".Linq.RuntimeHelpers" let RuntimeHelpersName = FSharpLib.Root + ".Core.CompilerServices.RuntimeHelpers" - let ExtraTopLevelOperatorsName = FSharpLib.Root + ".Core.ExtraTopLevelOperators" + let ExtraTopLevelOperatorsName = FSharpLib.Root + ".Core.ExtraTopLevelOperators" let NativeInteropName = FSharpLib.Root + ".NativeInterop" let QuotationsName = FSharpLib.Root + ".Quotations" - let ControlPath = IL.splitNamespace ControlName - let LinqPath = IL.splitNamespace LinqName - let CollectionsPath = IL.splitNamespace CollectionsName - let NativeInteropPath = IL.splitNamespace NativeInteropName |> Array.ofList - let CompilerServicesPath = IL.splitNamespace CompilerServicesName |> Array.ofList - let LinqRuntimeHelpersPath = IL.splitNamespace LinqRuntimeHelpersName |> Array.ofList - let RuntimeHelpersPath = IL.splitNamespace RuntimeHelpersName |> Array.ofList - let QuotationsPath = IL.splitNamespace QuotationsName |> Array.ofList + let ControlPath = splitNamespace ControlName + let LinqPath = splitNamespace LinqName + let CollectionsPath = splitNamespace CollectionsName + let NativeInteropPath = splitNamespace NativeInteropName |> Array.ofList + let CompilerServicesPath = splitNamespace CompilerServicesName |> Array.ofList + let LinqRuntimeHelpersPath = splitNamespace LinqRuntimeHelpersName |> Array.ofList + let RuntimeHelpersPath = splitNamespace RuntimeHelpersName |> Array.ofList + let QuotationsPath = splitNamespace QuotationsName |> Array.ofList let RootPathArray = FSharpLib.RootPath |> Array.ofList let CorePathArray = FSharpLib.CorePath |> Array.ofList @@ -86,21 +85,21 @@ module FSharpLib = let private mkNonGenericTy tcref = TType_app(tcref, []) -let mkNonLocalTyconRef2 ccu path n = mkNonLocalTyconRef (mkNonLocalEntityRef ccu path) n +let mkNonLocalTyconRef2 ccu path n = mkNonLocalTyconRef (mkNonLocalEntityRef ccu path) n -let mk_MFCore_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CorePathArray n -let mk_MFQuotations_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.QuotationsPath n -let mk_MFLinq_tcref ccu n = mkNonLocalTyconRef2 ccu LinqPathArray n -let mk_MFCollections_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CollectionsPathArray n -let mk_MFCompilerServices_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CompilerServicesPath n -let mk_MFRuntimeHelpers_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.RuntimeHelpersPath n -let mk_MFControl_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.ControlPathArray n +let mk_MFCore_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CorePathArray n +let mk_MFQuotations_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.QuotationsPath n +let mk_MFLinq_tcref ccu n = mkNonLocalTyconRef2 ccu LinqPathArray n +let mk_MFCollections_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CollectionsPathArray n +let mk_MFCompilerServices_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.CompilerServicesPath n +let mk_MFRuntimeHelpers_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.RuntimeHelpersPath n +let mk_MFControl_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.ControlPathArray n -type +type [] BuiltinAttribInfo = - | AttribInfo of ILTypeRef * TyconRef + | AttribInfo of ILTypeRef * TyconRef member this.TyconRef = let (AttribInfo(_, tcref)) = this in tcref @@ -111,8 +110,8 @@ type member x.DebugText = x.ToString() /// For debugging - override x.ToString() = x.TyconRef.ToString() - + override x.ToString() = x.TyconRef.ToString() + [] let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute" @@ -140,7 +139,7 @@ let tname_Exception = "System.Exception" [] let tname_Missing = "System.Reflection.Missing" [] -let tname_Activator = "System.Activator" +let tname_FormattableString = "System.FormattableString" [] let tname_SerializationInfo = "System.Runtime.Serialization.SerializationInfo" [] @@ -174,23 +173,23 @@ let tname_IAsyncResult = "System.IAsyncResult" //------------------------------------------------------------------------- // Table of all these "globals" -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- -type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, directoryToResolveRelativePaths, - mlCompatibility: bool, isInteractive:bool, +type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, directoryToResolveRelativePaths, + mlCompatibility: bool, isInteractive:bool, // The helper to find system types amongst referenced DLLs - tryFindSysTypeCcu, + tryFindSysTypeCcu, emitDebugInfoInQuotations: bool, noDebugData: bool, pathMap: PathMap, langVersion: LanguageVersion) = - let vara = NewRigidTypar "a" envRange - let varb = NewRigidTypar "b" envRange - let varc = NewRigidTypar "c" envRange - let vard = NewRigidTypar "d" envRange - let vare = NewRigidTypar "e" envRange + let vara = Construct.NewRigidTypar "a" envRange + let varb = Construct.NewRigidTypar "b" envRange + let varc = Construct.NewRigidTypar "c" envRange + let vard = Construct.NewRigidTypar "d" envRange + let vare = Construct.NewRigidTypar "e" envRange - let varaTy = mkTyparTy vara - let varbTy = mkTyparTy varb + let varaTy = mkTyparTy vara + let varbTy = mkTyparTy varb let varcTy = mkTyparTy varc let vardTy = mkTyparTy vard let vareTy = mkTyparTy vare @@ -215,14 +214,20 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_unit_tcr_nice = mk_MFCore_tcref fslibCcu "unit" let v_exn_tcr = mk_MFCore_tcref fslibCcu "exn" let v_char_tcr = mk_MFCore_tcref fslibCcu "char" - let v_float_tcr = mk_MFCore_tcref fslibCcu "float" + let v_float_tcr = mk_MFCore_tcref fslibCcu "float" let v_float32_tcr = mk_MFCore_tcref fslibCcu "float32" - let v_pfloat_tcr = mk_MFCore_tcref fslibCcu "float`1" - let v_pfloat32_tcr = mk_MFCore_tcref fslibCcu "float32`1" - let v_pint_tcr = mk_MFCore_tcref fslibCcu "int`1" - let v_pint8_tcr = mk_MFCore_tcref fslibCcu "sbyte`1" - let v_pint16_tcr = mk_MFCore_tcref fslibCcu "int16`1" - let v_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`1" + let v_pfloat_tcr = mk_MFCore_tcref fslibCcu "float`1" + let v_pfloat32_tcr = mk_MFCore_tcref fslibCcu "float32`1" + let v_pint_tcr = mk_MFCore_tcref fslibCcu "int`1" + let v_pint8_tcr = mk_MFCore_tcref fslibCcu "sbyte`1" + let v_pint16_tcr = mk_MFCore_tcref fslibCcu "int16`1" + let v_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`1" + let v_pnativeint_tcr = mk_MFCore_tcref fslibCcu "nativeint`1" + let v_puint_tcr = mk_MFCore_tcref fslibCcu "uint`1" + let v_puint8_tcr = mk_MFCore_tcref fslibCcu "byte`1" + let v_puint16_tcr = mk_MFCore_tcref fslibCcu "uint16`1" + let v_puint64_tcr = mk_MFCore_tcref fslibCcu "uint64`1" + let v_punativeint_tcr = mk_MFCore_tcref fslibCcu "unativeint`1" let v_byref_tcr = mk_MFCore_tcref fslibCcu "byref`1" let v_byref2_tcr = mk_MFCore_tcref fslibCcu "byref`2" let v_outref_tcr = mk_MFCore_tcref fslibCcu "outref`1" @@ -234,7 +239,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_refcell_tcr_canon = mk_MFCore_tcref fslibCcu "Ref`1" let v_refcell_tcr_nice = mk_MFCore_tcref fslibCcu "ref`1" - let dummyAssemblyNameCarryingUsefulErrorInformation path typeName = + let dummyAssemblyNameCarryingUsefulErrorInformation path typeName = FSComp.SR.tcGlobalsSystemTypeNotFound (String.concat "." path + "." + typeName) // Search for a type. If it is not found, leave a dangling CCU reference with some useful diagnostic information should @@ -244,35 +249,35 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d | None -> CcuThunk.CreateDelayed(dummyAssemblyNameCarryingUsefulErrorInformation path typeName) | Some ccu -> ccu - let tryFindSysTyconRef path nm = - match tryFindSysTypeCcu path nm with + let tryFindSysTyconRef path nm = + match tryFindSysTypeCcu path nm with | Some ccu -> Some (mkNonLocalTyconRef2 ccu (Array.ofList path) nm) | None -> None - let findSysTyconRef path nm = - let ccu = findSysTypeCcu path nm + let findSysTyconRef path nm = + let ccu = findSysTypeCcu path nm mkNonLocalTyconRef2 ccu (Array.ofList path) nm - let findSysILTypeRef (nm:string) = + let findSysILTypeRef (nm:string) = let path, typeName = splitILTypeName nm - let scoref = - match tryFindSysTypeCcu path typeName with + let scoref = + match tryFindSysTypeCcu path typeName with | None -> ILScopeRef.Assembly (mkSimpleAssemblyRef (dummyAssemblyNameCarryingUsefulErrorInformation path typeName)) | Some ccu -> ccu.ILScopeRef mkILTyRef (scoref, nm) - let tryFindSysILTypeRef (nm:string) = + let tryFindSysILTypeRef (nm:string) = let path, typeName = splitILTypeName nm tryFindSysTypeCcu path typeName |> Option.map (fun ccu -> mkILTyRef (ccu.ILScopeRef, nm)) - let findSysAttrib (nm:string) = + let findSysAttrib (nm:string) = let tref = findSysILTypeRef nm let path, typeName = splitILTypeName nm AttribInfo(tref, findSysTyconRef path typeName) - let tryFindSysAttrib nm = + let tryFindSysAttrib nm = let path, typeName = splitILTypeName nm - match tryFindSysTypeCcu path typeName with + match tryFindSysTypeCcu path typeName with | Some _ -> Some (findSysAttrib nm) | None -> None @@ -293,20 +298,21 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_fslib_IDelegateEvent_tcr = mk_MFControl_tcref fslibCcu "IDelegateEvent`1" let v_option_tcr_nice = mk_MFCore_tcref fslibCcu "option`1" + let v_valueoption_tcr_nice = mk_MFCore_tcref fslibCcu "voption`1" let v_list_tcr_canon = mk_MFCollections_tcref fslibCcu "List`1" let v_list_tcr_nice = mk_MFCollections_tcref fslibCcu "list`1" let v_lazy_tcr_nice = mk_MFControl_tcref fslibCcu "Lazy`1" let v_seq_tcr = mk_MFCollections_tcref fslibCcu "seq`1" - let v_format_tcr = mk_MFCore_tcref fslibCcu "PrintfFormat`5" - let v_format4_tcr = mk_MFCore_tcref fslibCcu "PrintfFormat`4" + let v_format_tcr = mk_MFCore_tcref fslibCcu "PrintfFormat`5" + let v_format4_tcr = mk_MFCore_tcref fslibCcu "PrintfFormat`4" let v_date_tcr = findSysTyconRef sys "DateTime" let v_IEnumerable_tcr = findSysTyconRef sysGenerics "IEnumerable`1" let v_IEnumerator_tcr = findSysTyconRef sysGenerics "IEnumerator`1" let v_System_Attribute_tcr = findSysTyconRef sys "Attribute" - let v_expr_tcr = mk_MFQuotations_tcref fslibCcu "Expr`1" - let v_raw_expr_tcr = mk_MFQuotations_tcref fslibCcu "Expr" - let v_query_builder_tcref = mk_MFLinq_tcref fslibCcu "QueryBuilder" - let v_querySource_tcr = mk_MFLinq_tcref fslibCcu "QuerySource`2" + let v_expr_tcr = mk_MFQuotations_tcref fslibCcu "Expr`1" + let v_raw_expr_tcr = mk_MFQuotations_tcref fslibCcu "Expr" + let v_query_builder_tcref = mk_MFLinq_tcref fslibCcu "QueryBuilder" + let v_querySource_tcr = mk_MFLinq_tcref fslibCcu "QuerySource`2" let v_linqExpression_tcr = findSysTyconRef ["System";"Linq";"Expressions"] "Expression`1" let v_il_arr_tcr_map = @@ -316,7 +322,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d if rank = 1 then "[]`1" else "[" + (String.replicate (rank - 1) ",") + "]`1" mk_MFCore_tcref fslibCcu type_sig) - + let v_byte_ty = mkNonGenericTy v_byte_tcr let v_sbyte_ty = mkNonGenericTy v_sbyte_tcr let v_int16_ty = mkNonGenericTy v_int16_tcr @@ -332,32 +338,38 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_unativeint_ty = mkNonGenericTy v_unativeint_tcr let v_enum_ty = mkNonGenericTy v_int_tcr - let v_bool_ty = mkNonGenericTy v_bool_tcr + let v_bool_ty = mkNonGenericTy v_bool_tcr let v_char_ty = mkNonGenericTy v_char_tcr - let v_obj_ty = mkNonGenericTy v_obj_tcr + let v_obj_ty = mkNonGenericTy v_obj_tcr + let v_IFormattable_tcref = findSysTyconRef sys "IFormattable" + let v_FormattableString_tcref = findSysTyconRef sys "FormattableString" + let v_IFormattable_ty = mkNonGenericTy v_IFormattable_tcref + let v_FormattableString_ty = mkNonGenericTy v_FormattableString_tcref + let v_FormattableStringFactory_tcref = findSysTyconRef sysCompilerServices "FormattableStringFactory" + let v_FormattableStringFactory_ty = mkNonGenericTy v_FormattableStringFactory_tcref let v_string_ty = mkNonGenericTy v_string_tcr let v_decimal_ty = mkSysNonGenericTy sys "Decimal" let v_unit_ty = mkNonGenericTy v_unit_tcr_nice let v_system_Type_ty = mkSysNonGenericTy sys "Type" + let v_Array_tcref = findSysTyconRef sys "Array" - let v_system_Reflection_MethodInfo_ty = mkSysNonGenericTy ["System";"Reflection"] "MethodInfo" let v_nullable_tcr = findSysTyconRef sys "Nullable`1" (* local helpers to build value infos *) - let mkNullableTy ty = TType_app(v_nullable_tcr, [ty]) - let mkByrefTy ty = TType_app(v_byref_tcr, [ty]) - let mkNativePtrTy ty = TType_app(v_nativeptr_tcr, [ty]) - let mkFunTy d r = TType_fun (d, r) + let mkNullableTy ty = TType_app(v_nullable_tcr, [ty]) + let mkByrefTy ty = TType_app(v_byref_tcr, [ty]) + let mkNativePtrTy ty = TType_app(v_nativeptr_tcr, [ty]) + let mkFunTy d r = TType_fun (d, r) let (-->) d r = mkFunTy d r let mkIteratedFunTy dl r = List.foldBack mkFunTy dl r let mkSmallRefTupledTy l = match l with [] -> v_unit_ty | [h] -> h | tys -> mkRawRefTupleTy tys let mkForallTyIfNeeded d r = match d with [] -> r | tps -> TType_forall(tps, r) // A table of all intrinsics that the compiler cares about - let v_knownIntrinsics = Dictionary<(string*string), ValRef>(HashIdentity.Structural) + let v_knownIntrinsics = ConcurrentDictionary(HashIdentity.Structural) - let makeIntrinsicValRef (enclosingEntity, logicalName, memberParentName, compiledNameOpt, typars, (argtys, rty)) = + let makeIntrinsicValRefGeneral isKnown (enclosingEntity, logicalName, memberParentName, compiledNameOpt, typars, (argtys, rty)) = let ty = mkForallTyIfNeeded typars (mkIteratedFunTy (List.map mkSmallRefTupledTy argtys) rty) let isMember = Option.isSome memberParentName let argCount = if isMember then List.sum (List.map List.length argtys) else 0 @@ -365,9 +377,15 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let key = ValLinkageFullKey({ MemberParentMangledName=memberParentName; MemberIsOverride=false; LogicalName=logicalName; TotalArgCount= argCount }, linkageType) let vref = IntrinsicValRef(enclosingEntity, logicalName, isMember, ty, key) let compiledName = defaultArg compiledNameOpt logicalName - v_knownIntrinsics.Add((enclosingEntity.LastItemMangledName, compiledName), ValRefForIntrinsic vref) + + let key = (enclosingEntity.LastItemMangledName, memberParentName, compiledName, argCount) + assert not (v_knownIntrinsics.ContainsKey(key)) + if isKnown && not (v_knownIntrinsics.ContainsKey(key)) then + v_knownIntrinsics.[key] <- ValRefForIntrinsic vref vref + let makeIntrinsicValRef info = makeIntrinsicValRefGeneral true info + let makeOtherIntrinsicValRef info = makeIntrinsicValRefGeneral false info let v_IComparer_ty = mkSysNonGenericTy sysCollections "IComparer" let v_IEqualityComparer_ty = mkSysNonGenericTy sysCollections "IEqualityComparer" @@ -387,35 +405,36 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let mkListTy ty = TType_app(v_list_tcr_nice, [ty]) let mkSeqTy ty1 = TType_app(v_seq_tcr, [ty1]) let mkRefCellTy ty = TType_app(v_refcell_tcr_canon, [ty]) + let mkOptionTy ty = TType_app(v_option_tcr_nice, [ty]) let mkQuerySourceTy ty1 ty2 = TType_app(v_querySource_tcr, [ty1; ty2]) let v_tcref_System_Collections_IEnumerable = findSysTyconRef sysCollections "IEnumerable"; let mkArrayType rank (ty : TType) : TType = assert (rank >= 1 && rank <= 32) TType_app(v_il_arr_tcr_map.[rank - 1], [ty]) let mkLazyTy ty = TType_app(lazy_tcr, [ty]) - - let mkPrintfFormatTy aty bty cty dty ety = TType_app(v_format_tcr, [aty;bty;cty;dty; ety]) - let mk_format4_ty aty bty cty dty = TType_app(v_format4_tcr, [aty;bty;cty;dty]) - let mkQuotedExprTy aty = TType_app(v_expr_tcr, [aty]) - let mkRawQuotedExprTy = TType_app(v_raw_expr_tcr, []) - let mkQueryBuilderTy = TType_app(v_query_builder_tcref, []) - let mkLinqExpressionTy aty = TType_app(v_linqExpression_tcr, [aty]) - let v_cons_ucref = mkUnionCaseRef v_list_tcr_canon "op_ColonColon" - let v_nil_ucref = mkUnionCaseRef v_list_tcr_canon "op_Nil" - - + + let mkPrintfFormatTy aty bty cty dty ety = TType_app(v_format_tcr, [aty;bty;cty;dty; ety]) + let mk_format4_ty aty bty cty dty = TType_app(v_format4_tcr, [aty;bty;cty;dty]) + let mkQuotedExprTy aty = TType_app(v_expr_tcr, [aty]) + let mkRawQuotedExprTy = TType_app(v_raw_expr_tcr, []) + let mkQueryBuilderTy = TType_app(v_query_builder_tcref, []) + let mkLinqExpressionTy aty = TType_app(v_linqExpression_tcr, [aty]) + let v_cons_ucref = mkUnionCaseRef v_list_tcr_canon "op_ColonColon" + let v_nil_ucref = mkUnionCaseRef v_list_tcr_canon "op_Nil" + + let fslib_MF_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.RootPathArray - let fslib_MFCore_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CorePathArray - let fslib_MFLinq_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqPathArray - let fslib_MFCollections_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CollectionsPathArray + let fslib_MFCore_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CorePathArray + let fslib_MFLinq_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqPathArray + let fslib_MFCollections_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CollectionsPathArray let fslib_MFCompilerServices_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CompilerServicesPath let fslib_MFLinqRuntimeHelpers_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqRuntimeHelpersPath let fslib_MFControl_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.ControlPathArray let fslib_MFNativeInterop_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.NativeInteropPath let fslib_MFLanguagePrimitives_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "LanguagePrimitives" - let fslib_MFIntrinsicOperators_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators" - let fslib_MFIntrinsicFunctions_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions" + let fslib_MFIntrinsicOperators_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators" + let fslib_MFIntrinsicFunctions_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions" let fslib_MFHashCompare_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "HashCompare" let fslib_MFOperators_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "Operators" let fslib_MFByRefKinds_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "ByRefKinds" @@ -427,7 +446,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let fslib_MFQueryRunExtensions_nleref = mkNestedNonLocalEntityRef fslib_MFLinq_nleref "QueryRunExtensions" let fslib_MFQueryRunExtensionsLowPriority_nleref = mkNestedNonLocalEntityRef fslib_MFQueryRunExtensions_nleref "LowPriority" let fslib_MFQueryRunExtensionsHighPriority_nleref = mkNestedNonLocalEntityRef fslib_MFQueryRunExtensions_nleref "HighPriority" - + + let fslib_MFPrintfModule_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "PrintfModule" let fslib_MFSeqModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "SeqModule" let fslib_MFListModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "ListModule" let fslib_MFArrayModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "ArrayModule" @@ -439,60 +459,62 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let fslib_MFStringModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "StringModule" let fslib_MFNativePtrModule_nleref = mkNestedNonLocalEntityRef fslib_MFNativeInterop_nleref "NativePtrModule" let fslib_MFOptionModule_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "OptionModule" + let fslib_MFStateMachineHelpers_nleref = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "StateMachineHelpers" let fslib_MFRuntimeHelpers_nleref = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "RuntimeHelpers" let fslib_MFQuotations_nleref = mkNestedNonLocalEntityRef fslib_MF_nleref "Quotations" - + let fslib_MFLinqRuntimeHelpersQuotationConverter_nleref = mkNestedNonLocalEntityRef fslib_MFLinqRuntimeHelpers_nleref "LeafExpressionConverter" - let fslib_MFLazyExtensions_nleref = mkNestedNonLocalEntityRef fslib_MFControl_nleref "LazyExtensions" - - let v_ref_tuple1_tcr = findSysTyconRef sys "Tuple`1" - let v_ref_tuple2_tcr = findSysTyconRef sys "Tuple`2" - let v_ref_tuple3_tcr = findSysTyconRef sys "Tuple`3" - let v_ref_tuple4_tcr = findSysTyconRef sys "Tuple`4" - let v_ref_tuple5_tcr = findSysTyconRef sys "Tuple`5" - let v_ref_tuple6_tcr = findSysTyconRef sys "Tuple`6" - let v_ref_tuple7_tcr = findSysTyconRef sys "Tuple`7" - let v_ref_tuple8_tcr = findSysTyconRef sys "Tuple`8" - let v_struct_tuple1_tcr = findSysTyconRef sys "ValueTuple`1" - let v_struct_tuple2_tcr = findSysTyconRef sys "ValueTuple`2" - let v_struct_tuple3_tcr = findSysTyconRef sys "ValueTuple`3" - let v_struct_tuple4_tcr = findSysTyconRef sys "ValueTuple`4" - let v_struct_tuple5_tcr = findSysTyconRef sys "ValueTuple`5" - let v_struct_tuple6_tcr = findSysTyconRef sys "ValueTuple`6" - let v_struct_tuple7_tcr = findSysTyconRef sys "ValueTuple`7" + let fslib_MFLazyExtensions_nleref = mkNestedNonLocalEntityRef fslib_MFControl_nleref "LazyExtensions" + + let v_ref_tuple1_tcr = findSysTyconRef sys "Tuple`1" + let v_ref_tuple2_tcr = findSysTyconRef sys "Tuple`2" + let v_ref_tuple3_tcr = findSysTyconRef sys "Tuple`3" + let v_ref_tuple4_tcr = findSysTyconRef sys "Tuple`4" + let v_ref_tuple5_tcr = findSysTyconRef sys "Tuple`5" + let v_ref_tuple6_tcr = findSysTyconRef sys "Tuple`6" + let v_ref_tuple7_tcr = findSysTyconRef sys "Tuple`7" + let v_ref_tuple8_tcr = findSysTyconRef sys "Tuple`8" + let v_struct_tuple1_tcr = findSysTyconRef sys "ValueTuple`1" + let v_struct_tuple2_tcr = findSysTyconRef sys "ValueTuple`2" + let v_struct_tuple3_tcr = findSysTyconRef sys "ValueTuple`3" + let v_struct_tuple4_tcr = findSysTyconRef sys "ValueTuple`4" + let v_struct_tuple5_tcr = findSysTyconRef sys "ValueTuple`5" + let v_struct_tuple6_tcr = findSysTyconRef sys "ValueTuple`6" + let v_struct_tuple7_tcr = findSysTyconRef sys "ValueTuple`7" let v_struct_tuple8_tcr = findSysTyconRef sys "ValueTuple`8" - - let v_choice2_tcr = mk_MFCore_tcref fslibCcu "Choice`2" - let v_choice3_tcr = mk_MFCore_tcref fslibCcu "Choice`3" - let v_choice4_tcr = mk_MFCore_tcref fslibCcu "Choice`4" - let v_choice5_tcr = mk_MFCore_tcref fslibCcu "Choice`5" - let v_choice6_tcr = mk_MFCore_tcref fslibCcu "Choice`6" - let v_choice7_tcr = mk_MFCore_tcref fslibCcu "Choice`7" + + let v_choice2_tcr = mk_MFCore_tcref fslibCcu "Choice`2" + let v_choice3_tcr = mk_MFCore_tcref fslibCcu "Choice`3" + let v_choice4_tcr = mk_MFCore_tcref fslibCcu "Choice`4" + let v_choice5_tcr = mk_MFCore_tcref fslibCcu "Choice`5" + let v_choice6_tcr = mk_MFCore_tcref fslibCcu "Choice`6" + let v_choice7_tcr = mk_MFCore_tcref fslibCcu "Choice`7" let tyconRefEq x y = primEntityRefEq compilingFslib fslibCcu x y - let v_suppressed_types = + let v_suppressed_types = [ mk_MFCore_tcref fslibCcu "Option`1"; - mk_MFCore_tcref fslibCcu "Ref`1"; + mk_MFCore_tcref fslibCcu "Ref`1"; mk_MFCore_tcref fslibCcu "FSharpTypeFunc"; - mk_MFCore_tcref fslibCcu "FSharpFunc`2"; - mk_MFCore_tcref fslibCcu "Unit" ] + mk_MFCore_tcref fslibCcu "FSharpFunc`2"; + mk_MFCore_tcref fslibCcu "Unit" ] - let v_knownFSharpCoreModules = - dict [ for nleref in [ fslib_MFLanguagePrimitives_nleref + let v_knownFSharpCoreModules = + dict [ for nleref in [ fslib_MFLanguagePrimitives_nleref fslib_MFIntrinsicOperators_nleref fslib_MFIntrinsicFunctions_nleref fslib_MFHashCompare_nleref - fslib_MFOperators_nleref + fslib_MFOperators_nleref fslib_MFOperatorIntrinsics_nleref fslib_MFOperatorsUnchecked_nleref fslib_MFOperatorsChecked_nleref fslib_MFExtraTopLevelOperators_nleref fslib_MFNullableOperators_nleref - fslib_MFQueryRunExtensions_nleref - fslib_MFQueryRunExtensionsLowPriority_nleref - fslib_MFQueryRunExtensionsHighPriority_nleref + fslib_MFQueryRunExtensions_nleref + fslib_MFQueryRunExtensionsLowPriority_nleref + fslib_MFQueryRunExtensionsHighPriority_nleref - fslib_MFSeqModule_nleref + fslib_MFPrintfModule_nleref + fslib_MFSeqModule_nleref fslib_MFListModule_nleref fslib_MFArrayModule_nleref fslib_MFArray2DModule_nleref @@ -503,14 +525,15 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d fslib_MFStringModule_nleref fslib_MFNativePtrModule_nleref fslib_MFOptionModule_nleref + fslib_MFStateMachineHelpers_nleref fslib_MFRuntimeHelpers_nleref ] do yield nleref.LastItemMangledName, ERefNonLocal nleref ] - - let tryDecodeTupleTy tupInfo l = - match l with - | [t1;t2;t3;t4;t5;t6;t7;marker] -> - match marker with + + let tryDecodeTupleTy tupInfo l = + match l with + | [t1;t2;t3;t4;t5;t6;t7;marker] -> + match marker with | TType_app(tcref, [t8]) when tyconRefEq tcref v_ref_tuple1_tcr -> mkRawRefTupleTy [t1;t2;t3;t4;t5;t6;t7;t8] |> Some | TType_app(tcref, [t8]) when tyconRefEq tcref v_struct_tuple1_tcr -> mkRawStructTupleTy [t1;t2;t3;t4;t5;t6;t7;t8] |> Some | TType_tuple (_structness2, t8plus) -> TType_tuple (tupInfo, [t1;t2;t3;t4;t5;t6;t7] @ t8plus) |> Some @@ -518,64 +541,64 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d | [] -> None | [_] -> None | _ -> TType_tuple (tupInfo, l) |> Some - - let decodeTupleTy tupInfo l = - match tryDecodeTupleTy tupInfo l with + + let decodeTupleTy tupInfo l = + match tryDecodeTupleTy tupInfo l with | Some ty -> ty | None -> failwith "couldn't decode tuple ty" - let decodeTupleTyIfPossible tcref tupInfo l = - match tryDecodeTupleTy tupInfo l with + let decodeTupleTyIfPossible tcref tupInfo l = + match tryDecodeTupleTy tupInfo l with | Some ty -> ty | None -> TType_app(tcref, l) - let mk_MFCore_attrib nm : BuiltinAttribInfo = - AttribInfo(mkILTyRef(IlxSettings.ilxFsharpCoreLibScopeRef (), FSharpLib.Core + "." + nm), mk_MFCore_tcref fslibCcu nm) - + let mk_MFCore_attrib nm : BuiltinAttribInfo = + AttribInfo(mkILTyRef(ilg.fsharpCoreAssemblyScopeRef, FSharpLib.Core + "." + nm), mk_MFCore_tcref fslibCcu nm) + let mk_doc filename = ILSourceDocument.Create(language=None, vendor=None, documentType=None, file=filename) // Build the memoization table for files - let v_memoize_file = new MemoizationTable ((fileOfFileIndex >> Filename.fullpath directoryToResolveRelativePaths >> mk_doc), keyComparer=HashIdentity.Structural) + let v_memoize_file = MemoizationTable((fileOfFileIndex >> FileSystem.GetFullFilePathInDirectoryShim directoryToResolveRelativePaths >> mk_doc), keyComparer=HashIdentity.Structural) - let v_and_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&" , None , None , [], mk_rel_sig v_bool_ty) - let v_addrof_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&" , None , None , [vara], ([[varaTy]], mkByrefTy varaTy)) + let v_and_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&" , None , None , [], mk_rel_sig v_bool_ty) + let v_addrof_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&" , None , None , [vara], ([[varaTy]], mkByrefTy varaTy)) let v_addrof2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "~&&" , None , None , [vara], ([[varaTy]], mkNativePtrTy varaTy)) - let v_and2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&&" , None , None , [], mk_rel_sig v_bool_ty) - let v_or_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, "or" , None , Some "Or" , [], mk_rel_sig v_bool_ty) - let v_or2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "||" , None , None , [], mk_rel_sig v_bool_ty) - let v_compare_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "compare" , None , Some "Compare", [vara], mk_compare_sig varaTy) - let v_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "=" , None , None , [vara], mk_rel_sig varaTy) - let v_equals_nullable_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "=?" , None , None , [vara], ([[varaTy];[mkNullableTy varaTy]], v_bool_ty)) - let v_nullable_equals_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "?=" , None , None , [vara], ([[mkNullableTy varaTy];[varaTy]], v_bool_ty)) - let v_nullable_equals_nullable_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "?=?" , None , None , [vara], ([[mkNullableTy varaTy];[mkNullableTy varaTy]], v_bool_ty)) - let v_not_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<>" , None , None , [vara], mk_rel_sig varaTy) - let v_less_than_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<" , None , None , [vara], mk_rel_sig varaTy) - let v_less_than_or_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<=" , None , None , [vara], mk_rel_sig varaTy) - let v_greater_than_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName ">" , None , None , [vara], mk_rel_sig varaTy) - let v_greater_than_or_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName ">=" , None , None , [vara], mk_rel_sig varaTy) - - let v_enumOfValue_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "EnumOfValue" , None , None , [vara; varb], ([[varaTy]], varbTy)) - - let v_generic_comparison_withc_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericComparisonWithComparer" , None , None , [vara], mk_compare_withc_sig varaTy) - let v_generic_hash_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple2" , None , None , [vara;varb], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) - let v_generic_hash_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple3" , None , None , [vara;varb;varc], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) - let v_generic_hash_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple4" , None , None , [vara;varb;varc;vard], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) - let v_generic_hash_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple5" , None , None , [vara;varb;varc;vard;vare], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) - let v_generic_equals_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple2" , None , None , [vara;varb], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) - let v_generic_equals_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple3" , None , None , [vara;varb;varc], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) - let v_generic_equals_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple4" , None , None , [vara;varb;varc;vard], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) - let v_generic_equals_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple5" , None , None , [vara;varb;varc;vard;vare], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) - - let v_generic_compare_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple2" , None , None , [vara;varb], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) - let v_generic_compare_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple3" , None , None , [vara;varb;varc], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) - let v_generic_compare_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple4" , None , None , [vara;varb;varc;vard], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) - let v_generic_compare_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple5" , None , None , [vara;varb;varc;vard;vare], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) - - - let v_generic_equality_er_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityER" , None , None , [vara], mk_rel_sig varaTy) - let v_get_generic_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericComparer" , None , None , [], ([], v_IComparer_ty)) - let v_get_generic_er_equality_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityERComparer" , None , None , [], ([], v_IEqualityComparer_ty)) - let v_get_generic_per_equality_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityComparer" , None , None , [], ([], v_IEqualityComparer_ty)) + let v_and2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "&&" , None , None , [], mk_rel_sig v_bool_ty) + let v_or_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, "or" , None , Some "Or" , [], mk_rel_sig v_bool_ty) + let v_or2_info = makeIntrinsicValRef(fslib_MFIntrinsicOperators_nleref, CompileOpName "||" , None , None , [], mk_rel_sig v_bool_ty) + let v_compare_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "compare" , None , Some "Compare", [vara], mk_compare_sig varaTy) + let v_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "=" , None , None , [vara], mk_rel_sig varaTy) + let v_equals_nullable_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "=?" , None , None , [vara], ([[varaTy];[mkNullableTy varaTy]], v_bool_ty)) + let v_nullable_equals_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "?=" , None , None , [vara], ([[mkNullableTy varaTy];[varaTy]], v_bool_ty)) + let v_nullable_equals_nullable_operator_info = makeIntrinsicValRef(fslib_MFNullableOperators_nleref, CompileOpName "?=?" , None , None , [vara], ([[mkNullableTy varaTy];[mkNullableTy varaTy]], v_bool_ty)) + let v_not_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<>" , None , None , [vara], mk_rel_sig varaTy) + let v_less_than_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<" , None , None , [vara], mk_rel_sig varaTy) + let v_less_than_or_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName "<=" , None , None , [vara], mk_rel_sig varaTy) + let v_greater_than_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName ">" , None , None , [vara], mk_rel_sig varaTy) + let v_greater_than_or_equals_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, CompileOpName ">=" , None , None , [vara], mk_rel_sig varaTy) + + let v_enumOfValue_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "EnumOfValue" , None , None , [vara; varb], ([[varaTy]], varbTy)) + + let v_generic_comparison_withc_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericComparisonWithComparer" , None , None , [vara], mk_compare_withc_sig varaTy) + let v_generic_hash_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple2" , None , None , [vara;varb], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) + let v_generic_hash_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple3" , None , None , [vara;varb;varc], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) + let v_generic_hash_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple4" , None , None , [vara;varb;varc;vard], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) + let v_generic_hash_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastHashTuple5" , None , None , [vara;varb;varc;vard;vare], mk_hash_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) + let v_generic_equals_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple2" , None , None , [vara;varb], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) + let v_generic_equals_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple3" , None , None , [vara;varb;varc], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) + let v_generic_equals_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple4" , None , None , [vara;varb;varc;vard], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) + let v_generic_equals_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastEqualsTuple5" , None , None , [vara;varb;varc;vard;vare], mk_equality_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) + + let v_generic_compare_withc_tuple2_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple2" , None , None , [vara;varb], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy])) + let v_generic_compare_withc_tuple3_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple3" , None , None , [vara;varb;varc], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy])) + let v_generic_compare_withc_tuple4_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple4" , None , None , [vara;varb;varc;vard], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy])) + let v_generic_compare_withc_tuple5_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "FastCompareTuple5" , None , None , [vara;varb;varc;vard;vare], mk_compare_withc_sig (decodeTupleTy tupInfoRef [varaTy; varbTy; varcTy; vardTy; vareTy])) + + + let v_generic_equality_er_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityER" , None , None , [vara], mk_rel_sig varaTy) + let v_get_generic_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericComparer" , None , None , [], ([], v_IComparer_ty)) + let v_get_generic_er_equality_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityERComparer" , None , None , [], ([], v_IEqualityComparer_ty)) + let v_get_generic_per_equality_comparer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityComparer" , None , None , [], ([], v_IEqualityComparer_ty)) let v_generic_equality_withc_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericEqualityWithComparer" , None , None , [vara], mk_equality_withc_sig varaTy) let v_generic_hash_withc_outer_info = makeIntrinsicValRef(fslib_MFLanguagePrimitives_nleref, "GenericHashWithComparer" , None , None , [vara], mk_hash_withc_sig varaTy) @@ -587,95 +610,102 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_generic_hash_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "GenericHashIntrinsic" , None , None , [vara], mk_hash_sig varaTy) let v_generic_hash_withc_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "GenericHashWithComparerIntrinsic" , None , None , [vara], mk_hash_withc_sig varaTy) - + let v_create_instance_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "CreateInstance" , None , None , [vara], ([[v_unit_ty]], varaTy)) let v_unbox_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxGeneric" , None , None , [vara], ([[v_obj_ty]], varaTy)) let v_unbox_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "UnboxFast" , None , None , [vara], ([[v_obj_ty]], varaTy)) - let v_istype_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestGeneric" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) - let v_istype_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestFast" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) + let v_istype_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestGeneric" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) + let v_istype_fast_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "TypeTestFast" , None , None , [vara], ([[v_obj_ty]], v_bool_ty)) let v_dispose_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "Dispose" , None , None , [vara], ([[varaTy]], v_unit_ty)) let v_getstring_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetString" , None , None , [], ([[v_string_ty];[v_int_ty]], v_char_ty)) - let v_reference_equality_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "PhysicalEqualityIntrinsic" , None , None , [vara], mk_rel_sig varaTy) - - let v_bitwise_or_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseOr" , None , None , [vara], mk_binop_ty varaTy) - let v_bitwise_and_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseAnd" , None , None , [vara], mk_binop_ty varaTy) - let v_bitwise_xor_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_ExclusiveOr" , None , None , [vara], mk_binop_ty varaTy) - let v_bitwise_unary_not_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_LogicalNot" , None , None , [vara], mk_unop_ty varaTy) - let v_bitwise_shift_left_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_LeftShift" , None , None , [vara], mk_shiftop_ty varaTy) - let v_bitwise_shift_right_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_RightShift" , None , None , [vara], mk_shiftop_ty varaTy) - let v_unchecked_addition_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Addition" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_unchecked_subtraction_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Subtraction" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_unchecked_multiply_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Multiply" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_unchecked_division_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Division" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_unchecked_modulus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Modulus" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_unchecked_unary_plus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_UnaryPlus" , None , None , [vara], mk_unop_ty varaTy) - let v_unchecked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_UnaryNegation" , None , None , [vara], mk_unop_ty varaTy) - let v_unchecked_unary_not_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "not" , None , Some "Not" , [], mk_unop_ty v_bool_ty) - - let v_checked_addition_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Addition" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_checked_subtraction_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Subtraction" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_checked_multiply_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Multiply" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) - let v_checked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_UnaryNegation" , None , None , [vara], mk_unop_ty varaTy) - - let v_byte_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "byte" , None , Some "ToByte", [vara], ([[varaTy]], v_byte_ty)) - let v_sbyte_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "sbyte" , None , Some "ToSByte", [vara], ([[varaTy]], v_sbyte_ty)) - let v_int16_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int16" , None , Some "ToInt16", [vara], ([[varaTy]], v_int16_ty)) - let v_uint16_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint16" , None , Some "ToUInt16", [vara], ([[varaTy]], v_uint16_ty)) - let v_int_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int" , None , Some "ToInt", [vara], ([[varaTy]], v_int_ty)) - let v_int32_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int32" , None , Some "ToInt32", [vara], ([[varaTy]], v_int32_ty)) - let v_uint32_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint32" , None , Some "ToUInt32", [vara], ([[varaTy]], v_uint32_ty)) - let v_int64_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int64" , None , Some "ToInt64", [vara], ([[varaTy]], v_int64_ty)) - let v_uint64_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint64" , None , Some "ToUInt64", [vara], ([[varaTy]], v_uint64_ty)) - let v_nativeint_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "nativeint" , None , Some "ToIntPtr", [vara], ([[varaTy]], v_nativeint_ty)) + let v_reference_equality_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "PhysicalEqualityIntrinsic" , None , None , [vara], mk_rel_sig varaTy) + + let v_piperight_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight" , None , None , [vara; varb],([[varaTy];[varaTy --> varbTy]], varbTy)) + let v_piperight2_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight2" , None , None , [vara; varb; varc],([[varaTy; varbTy];[varaTy --> (varbTy --> varcTy)]], varcTy)) + let v_piperight3_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight3" , None , None , [vara; varb; varc; vard],([[varaTy; varbTy; varcTy];[varaTy --> (varbTy --> (varcTy --> vardTy))]], vardTy)) + let v_bitwise_or_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseOr" , None , None , [vara], mk_binop_ty varaTy) + let v_bitwise_and_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseAnd" , None , None , [vara], mk_binop_ty varaTy) + let v_bitwise_xor_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_ExclusiveOr" , None , None , [vara], mk_binop_ty varaTy) + let v_bitwise_unary_not_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_LogicalNot" , None , None , [vara], mk_unop_ty varaTy) + let v_bitwise_shift_left_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_LeftShift" , None , None , [vara], mk_shiftop_ty varaTy) + let v_bitwise_shift_right_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_RightShift" , None , None , [vara], mk_shiftop_ty varaTy) + let v_unchecked_addition_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Addition" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_unchecked_subtraction_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Subtraction" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_unchecked_multiply_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Multiply" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_unchecked_division_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Division" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_unchecked_modulus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Modulus" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_unchecked_unary_plus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_UnaryPlus" , None , None , [vara], mk_unop_ty varaTy) + let v_unchecked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_UnaryNegation" , None , None , [vara], mk_unop_ty varaTy) + let v_unchecked_unary_not_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "not" , None , Some "Not" , [], mk_unop_ty v_bool_ty) + let v_refcell_deref_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Dereference" , None , None , [vara], ([[mkRefCellTy varaTy]], varaTy)) + let v_refcell_assign_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_ColonEquals" , None , None , [vara], ([[mkRefCellTy varaTy]; [varaTy]], v_unit_ty)) + let v_refcell_incr_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "incr" , None , Some "Increment" , [], ([[mkRefCellTy v_int_ty]], v_unit_ty)) + let v_refcell_decr_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "decr" , None , Some "Decrement" , [], ([[mkRefCellTy v_int_ty]], v_unit_ty)) + + let v_checked_addition_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Addition" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_checked_subtraction_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Subtraction" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_checked_multiply_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_Multiply" , None , None , [vara;varb;varc], mk_binop_ty3 varaTy varbTy varcTy) + let v_checked_unary_minus_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "op_UnaryNegation" , None , None , [vara], mk_unop_ty varaTy) + + let v_byte_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "byte" , None , Some "ToByte", [vara], ([[varaTy]], v_byte_ty)) + let v_sbyte_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "sbyte" , None , Some "ToSByte", [vara], ([[varaTy]], v_sbyte_ty)) + let v_int16_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int16" , None , Some "ToInt16", [vara], ([[varaTy]], v_int16_ty)) + let v_uint16_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint16" , None , Some "ToUInt16", [vara], ([[varaTy]], v_uint16_ty)) + let v_int_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int" , None , Some "ToInt", [vara], ([[varaTy]], v_int_ty)) + let v_int32_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int32" , None , Some "ToInt32", [vara], ([[varaTy]], v_int32_ty)) + let v_uint32_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint32" , None , Some "ToUInt32", [vara], ([[varaTy]], v_uint32_ty)) + let v_int64_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "int64" , None , Some "ToInt64", [vara], ([[varaTy]], v_int64_ty)) + let v_uint64_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "uint64" , None , Some "ToUInt64", [vara], ([[varaTy]], v_uint64_ty)) + let v_nativeint_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "nativeint" , None , Some "ToIntPtr", [vara], ([[varaTy]], v_nativeint_ty)) let v_unativeint_checked_info = makeIntrinsicValRef(fslib_MFOperatorsChecked_nleref, "unativeint" , None , Some "ToUIntPtr", [vara], ([[varaTy]], v_unativeint_ty)) - let v_byte_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "byte" , None , Some "ToByte", [vara], ([[varaTy]], v_byte_ty)) - let v_sbyte_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "sbyte" , None , Some "ToSByte", [vara], ([[varaTy]], v_sbyte_ty)) - let v_int16_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int16" , None , Some "ToInt16", [vara], ([[varaTy]], v_int16_ty)) - let v_uint16_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint16" , None , Some "ToUInt16", [vara], ([[varaTy]], v_uint16_ty)) - let v_int_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int" , None , Some "ToInt", [vara], ([[varaTy]], v_int_ty)) - let v_int32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int32" , None , Some "ToInt32", [vara], ([[varaTy]], v_int32_ty)) - let v_uint32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint32" , None , Some "ToUInt32", [vara], ([[varaTy]], v_uint32_ty)) - let v_int64_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int64" , None , Some "ToInt64", [vara], ([[varaTy]], v_int64_ty)) - let v_uint64_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint64" , None , Some "ToUInt64", [vara], ([[varaTy]], v_uint64_ty)) - let v_float32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "float32" , None , Some "ToSingle", [vara], ([[varaTy]], v_float32_ty)) - let v_float_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "float" , None , Some "ToDouble", [vara], ([[varaTy]], v_float_ty)) - let v_nativeint_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nativeint" , None , Some "ToIntPtr", [vara], ([[varaTy]], v_nativeint_ty)) + let v_byte_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "byte" , None , Some "ToByte", [vara], ([[varaTy]], v_byte_ty)) + let v_sbyte_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "sbyte" , None , Some "ToSByte", [vara], ([[varaTy]], v_sbyte_ty)) + let v_int16_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int16" , None , Some "ToInt16", [vara], ([[varaTy]], v_int16_ty)) + let v_uint16_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint16" , None , Some "ToUInt16", [vara], ([[varaTy]], v_uint16_ty)) + let v_int_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int" , None , Some "ToInt", [vara], ([[varaTy]], v_int_ty)) + let v_int32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int32" , None , Some "ToInt32", [vara], ([[varaTy]], v_int32_ty)) + let v_uint32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint32" , None , Some "ToUInt32", [vara], ([[varaTy]], v_uint32_ty)) + let v_int64_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "int64" , None , Some "ToInt64", [vara], ([[varaTy]], v_int64_ty)) + let v_uint64_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "uint64" , None , Some "ToUInt64", [vara], ([[varaTy]], v_uint64_ty)) + let v_float32_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "float32" , None , Some "ToSingle", [vara], ([[varaTy]], v_float32_ty)) + let v_float_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "float" , None , Some "ToDouble", [vara], ([[varaTy]], v_float_ty)) + let v_nativeint_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nativeint" , None , Some "ToIntPtr", [vara], ([[varaTy]], v_nativeint_ty)) let v_unativeint_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "unativeint" , None , Some "ToUIntPtr", [vara], ([[varaTy]], v_unativeint_ty)) - let v_char_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "char" , None , Some "ToChar", [vara], ([[varaTy]], v_char_ty)) - let v_enum_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "enum" , None , Some "ToEnum", [vara], ([[varaTy]], v_enum_ty)) + let v_char_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "char" , None , Some "ToChar", [vara], ([[varaTy]], v_char_ty)) + let v_enum_operator_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "enum" , None , Some "ToEnum", [vara], ([[varaTy]], v_enum_ty)) let v_hash_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "hash" , None , Some "Hash" , [vara], ([[varaTy]], v_int_ty)) let v_box_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "box" , None , Some "Box" , [vara], ([[varaTy]], v_obj_ty)) let v_isnull_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "isNull" , None , Some "IsNull" , [vara], ([[varaTy]], v_bool_ty)) let v_isnotnull_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "isNotNull" , None , Some "IsNotNull" , [vara], ([[varaTy]], v_bool_ty)) - let v_raise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "raise" , None , Some "Raise" , [vara], ([[mkSysNonGenericTy sys "Exception"]], varaTy)) - let v_failwith_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "failwith" , None , Some "FailWith" , [vara], ([[v_string_ty]], varaTy)) - let v_invalid_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidArg" , None , Some "InvalidArg" , [vara], ([[v_string_ty]; [v_string_ty]], varaTy)) - let v_null_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nullArg" , None , Some "NullArg" , [vara], ([[v_string_ty]], varaTy)) - let v_invalid_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidOp" , None , Some "InvalidOp" , [vara], ([[v_string_ty]], varaTy)) - let v_failwithf_info = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref, "failwithf" , None , Some "PrintFormatToStringThenFail" , [vara;varb], ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy)) - + let v_raise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "raise" , None , Some "Raise" , [vara], ([[mkSysNonGenericTy sys "Exception"]], varaTy)) + let v_failwith_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "failwith" , None , Some "FailWith" , [vara], ([[v_string_ty]], varaTy)) + let v_invalid_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidArg" , None , Some "InvalidArg" , [vara], ([[v_string_ty]; [v_string_ty]], varaTy)) + let v_null_arg_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nullArg" , None , Some "NullArg" , [vara], ([[v_string_ty]], varaTy)) + let v_invalid_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "invalidOp" , None , Some "InvalidOp" , [vara], ([[v_string_ty]], varaTy)) + let v_failwithf_info = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref, "failwithf" , None , Some "PrintFormatToStringThenFail" , [vara;varb], ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy)) + let v_reraise_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "reraise" , None , Some "Reraise", [vara], ([[v_unit_ty]], varaTy)) - let v_typeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typeof" , None , Some "TypeOf" , [vara], ([], v_system_Type_ty)) + let v_typeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typeof" , None , Some "TypeOf" , [vara], ([], v_system_Type_ty)) let v_methodhandleof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "methodhandleof" , None , Some "MethodHandleOf", [vara;varb], ([[varaTy --> varbTy]], v_system_RuntimeMethodHandle_ty)) - let v_sizeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "sizeof" , None , Some "SizeOf" , [vara], ([], v_int_ty)) + let v_sizeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "sizeof" , None , Some "SizeOf" , [vara], ([], v_int_ty)) let v_nameof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nameof" , None , Some "NameOf" , [vara], ([[varaTy]], v_string_ty)) - let v_unchecked_defaultof_info = makeIntrinsicValRef(fslib_MFOperatorsUnchecked_nleref, "defaultof" , None , Some "DefaultOf", [vara], ([], varaTy)) - let v_typedefof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typedefof" , None , Some "TypeDefOf", [vara], ([], v_system_Type_ty)) + let v_unchecked_defaultof_info = makeIntrinsicValRef(fslib_MFOperatorsUnchecked_nleref, "defaultof" , None , Some "DefaultOf", [vara], ([], varaTy)) + let v_typedefof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typedefof" , None , Some "TypeDefOf", [vara], ([], v_system_Type_ty)) let v_range_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Range" , None , None , [vara], ([[varaTy];[varaTy]], mkSeqTy varaTy)) let v_range_step_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_RangeStep" , None , None , [vara;varb], ([[varaTy];[varbTy];[varaTy]], mkSeqTy varaTy)) let v_range_int32_op_info = makeIntrinsicValRef(fslib_MFOperatorIntrinsics_nleref, "RangeInt32" , None , None , [], ([[v_int_ty];[v_int_ty];[v_int_ty]], mkSeqTy v_int_ty)) let v_array_length_info = makeIntrinsicValRef(fslib_MFArrayModule_nleref, "length" , None , Some "Length" , [vara], ([[mkArrayType 1 varaTy]], v_int_ty)) let v_array_get_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetArray" , None , None , [vara], ([[mkArrayType 1 varaTy]; [v_int_ty]], varaTy)) - let v_array2D_get_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetArray2D" , None , None , [vara], ([[mkArrayType 2 varaTy];[v_int_ty]; [v_int_ty]], varaTy)) + let v_array2D_get_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetArray2D" , None , None , [vara], ([[mkArrayType 2 varaTy];[v_int_ty]; [v_int_ty]], varaTy)) let v_array3D_get_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetArray3D" , None , None , [vara], ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]], varaTy)) let v_array4D_get_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "GetArray4D" , None , None , [vara], ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]], varaTy)) let v_array_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray" , None , None , [vara], ([[mkArrayType 1 varaTy]; [v_int_ty]; [varaTy]], v_unit_ty)) @@ -683,23 +713,30 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_array3D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray3D" , None , None , [vara], ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty)) let v_array4D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray4D" , None , None , [vara], ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty)) - let v_nativeptr_tobyref_info = makeIntrinsicValRef(fslib_MFNativePtrModule_nleref, "toByRef" , None , Some "ToByRefInlined", [vara], ([[mkNativePtrTy varaTy]], mkByrefTy varaTy)) + let v_option_toNullable_info = makeIntrinsicValRef(fslib_MFOptionModule_nleref, "toNullable" , None , Some "ToNullable" , [vara], ([[mkOptionTy varaTy]], mkNullableTy varaTy)) + let v_option_defaultValue_info = makeIntrinsicValRef(fslib_MFOptionModule_nleref, "defaultValue" , None , Some "DefaultValue" , [vara], ([[varaTy]; [mkOptionTy varaTy]], varaTy)) - let v_seq_collect_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "collect" , None , Some "Collect", [vara;varb;varc], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varcTy)) - let v_seq_delay_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "delay" , None , Some "Delay" , [varb], ([[v_unit_ty --> mkSeqTy varbTy]], mkSeqTy varbTy)) - let v_seq_append_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "append" , None , Some "Append" , [varb], ([[mkSeqTy varbTy]; [mkSeqTy varbTy]], mkSeqTy varbTy)) + let v_nativeptr_tobyref_info = makeIntrinsicValRef(fslib_MFNativePtrModule_nleref, "toByRef" , None , Some "ToByRefInlined", [vara], ([[mkNativePtrTy varaTy]], mkByrefTy varaTy)) + + let v_seq_collect_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "collect" , None , Some "Collect", [vara;varb;varc], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varcTy)) + let v_seq_delay_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "delay" , None , Some "Delay" , [varb], ([[v_unit_ty --> mkSeqTy varbTy]], mkSeqTy varbTy)) + let v_seq_append_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "append" , None , Some "Append" , [varb], ([[mkSeqTy varbTy]; [mkSeqTy varbTy]], mkSeqTy varbTy)) let v_seq_using_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateUsing" , None , None , [vara;varb;varc], ([[varaTy];[(varaTy --> varbTy)]], mkSeqTy varcTy)) let v_seq_generated_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateWhile" , None , None , [varb], ([[v_unit_ty --> v_bool_ty]; [mkSeqTy varbTy]], mkSeqTy varbTy)) let v_seq_finally_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateThenFinally" , None , None , [varb], ([[mkSeqTy varbTy]; [v_unit_ty --> v_unit_ty]], mkSeqTy varbTy)) - let v_seq_of_functions_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateFromFunctions" , None , None , [vara;varb], ([[v_unit_ty --> varaTy]; [varaTy --> v_bool_ty]; [varaTy --> varbTy]], mkSeqTy varbTy)) + let v_seq_of_functions_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "EnumerateFromFunctions" , None , None , [vara;varb], ([[v_unit_ty --> varaTy]; [varaTy --> v_bool_ty]; [varaTy --> varbTy]], mkSeqTy varbTy)) let v_create_event_info = makeIntrinsicValRef(fslib_MFRuntimeHelpers_nleref, "CreateEvent" , None , None , [vara;varb], ([[varaTy --> v_unit_ty]; [varaTy --> v_unit_ty]; [(v_obj_ty --> (varbTy --> v_unit_ty)) --> varaTy]], TType_app (v_fslib_IEvent2_tcr, [varaTy;varbTy]))) + let v_cgh__useResumableCode_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__useResumableCode" , None , None , [vara], ([[]], v_bool_ty)) + let v_cgh__resumeAt_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__resumeAt" , None , None , [vara], ([[v_int_ty]; [varaTy]], varaTy)) + let v_cgh__stateMachine_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__stateMachine" , None , None , [vara; varb], ([[varaTy]], varbTy)) // inaccurate type but it doesn't matter for linking + let v_cgh__resumableEntry_info = makeIntrinsicValRef(fslib_MFStateMachineHelpers_nleref, "__resumableEntry" , None , None , [vara], ([[v_int_ty --> varaTy]; [v_unit_ty --> varaTy]], varaTy)) let v_seq_to_array_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "toArray" , None , Some "ToArray", [varb], ([[mkSeqTy varbTy]], mkArrayType 1 varbTy)) let v_seq_to_list_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "toList" , None , Some "ToList" , [varb], ([[mkSeqTy varbTy]], mkListTy varbTy)) let v_seq_map_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "map" , None , Some "Map" , [vara;varb], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varbTy)) let v_seq_singleton_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "singleton" , None , Some "Singleton" , [vara], ([[varaTy]], mkSeqTy varaTy)) let v_seq_empty_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "empty" , None , Some "Empty" , [vara], ([], mkSeqTy varaTy)) - let v_new_format_info = makeIntrinsicValRef(fslib_MFCore_nleref, ".ctor" , Some "PrintfFormat`5", None , [vara;varb;varc;vard;vare], ([[v_string_ty]], mkPrintfFormatTy varaTy varbTy varcTy vardTy vareTy)) - let v_sprintf_info = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref, "sprintf" , None , Some "PrintFormatToStringThen", [vara], ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy)) + let v_new_format_info = makeIntrinsicValRef(fslib_MFCore_nleref, ".ctor" , Some "PrintfFormat`5", None , [vara;varb;varc;vard;vare], ([[v_string_ty]], mkPrintfFormatTy varaTy varbTy varcTy vardTy vareTy)) + let v_sprintf_info = makeIntrinsicValRef(fslib_MFExtraTopLevelOperators_nleref, "sprintf" , None , Some "PrintFormatToStringThen", [vara], ([[mk_format4_ty varaTy v_unit_ty v_string_ty v_string_ty]], varaTy)) let v_lazy_force_info = makeIntrinsicValRef(fslib_MFLazyExtensions_nleref, "Force" , Some "Lazy`1" , None , [vara], ([[mkLazyTy varaTy]; []], varaTy)) let v_lazy_create_info = makeIntrinsicValRef(fslib_MFLazyExtensions_nleref, "Create" , Some "Lazy`1" , None , [vara], ([[v_unit_ty --> varaTy]], mkLazyTy varaTy)) @@ -710,6 +747,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_new_decimal_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "MakeDecimal" , None , None , [], ([[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_bool_ty]; [v_byte_ty]], v_decimal_ty)) let v_deserialize_quoted_FSharp_20_plus_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "Deserialize" , Some "Expr" , None , [], ([[v_system_Type_ty ;mkListTy v_system_Type_ty ;mkListTy mkRawQuotedExprTy ; mkArrayType 1 v_byte_ty]], mkRawQuotedExprTy )) let v_deserialize_quoted_FSharp_40_plus_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "Deserialize40" , Some "Expr" , None , [], ([[v_system_Type_ty ;mkArrayType 1 v_system_Type_ty; mkArrayType 1 v_system_Type_ty; mkArrayType 1 mkRawQuotedExprTy; mkArrayType 1 v_byte_ty]], mkRawQuotedExprTy )) + let v_call_with_witnesses_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "CallWithWitnesses" , Some "Expr" , None , [], ([[v_system_Reflection_MethodInfo_ty; v_system_Reflection_MethodInfo_ty; mkListTy mkRawQuotedExprTy; mkListTy mkRawQuotedExprTy]], mkRawQuotedExprTy)) let v_cast_quotation_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "Cast" , Some "Expr" , None , [vara], ([[mkRawQuotedExprTy]], mkQuotedExprTy varaTy)) let v_lift_value_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "Value" , Some "Expr" , None , [vara], ([[varaTy]], mkRawQuotedExprTy)) let v_lift_value_with_name_info = makeIntrinsicValRef(fslib_MFQuotations_nleref, "ValueWithName" , Some "Expr" , None , [vara], ([[varaTy; v_string_ty]], mkRawQuotedExprTy)) @@ -734,17 +772,17 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let tref_DebuggableAttribute = findSysILTypeRef tname_DebuggableAttribute let tref_CompilerGeneratedAttribute = findSysILTypeRef tname_CompilerGeneratedAttribute - let mutable generatedAttribsCache = [] - let mutable debuggerBrowsableNeverAttributeCache = None - let mkDebuggerNonUserCodeAttribute() = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerNonUserCodeAttribute, [], [], []) - let mkCompilerGeneratedAttribute () = mkILCustomAttribute ilg (tref_CompilerGeneratedAttribute, [], [], []) + let mutable generatedAttribsCache = [] + let mutable debuggerBrowsableNeverAttributeCache = None + let mkDebuggerNonUserCodeAttribute() = mkILCustomAttribute (findSysILTypeRef tname_DebuggerNonUserCodeAttribute, [], [], []) + let mkCompilerGeneratedAttribute () = mkILCustomAttribute (tref_CompilerGeneratedAttribute, [], [], []) let compilerGlobalState = CompilerGlobalState() // Requests attributes to be added to compiler generated methods. - let addGeneratedAttrs (attrs: ILAttributes) = - let attribs = - match generatedAttribsCache with - | [] -> + let addGeneratedAttrs (attrs: ILAttributes) = + let attribs = + match generatedAttribsCache with + | [] -> let res = [ if not noDebugData then yield mkCompilerGeneratedAttribute() yield mkDebuggerNonUserCodeAttribute()] @@ -757,13 +795,13 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let addPropertyGeneratedAttrs (pdef:ILPropertyDef) = pdef.With(customAttrs = addGeneratedAttrs pdef.CustomAttrs) let addFieldGeneratedAttrs (fdef:ILFieldDef) = fdef.With(customAttrs = addGeneratedAttrs fdef.CustomAttrs) - let tref_DebuggerBrowsableAttribute n = - let typ_DebuggerBrowsableState = + let tref_DebuggerBrowsableAttribute n = + let typ_DebuggerBrowsableState = let tref = findSysILTypeRef tname_DebuggerBrowsableState ILType.Value (mkILNonGenericTySpec tref) - mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerBrowsableAttribute, [typ_DebuggerBrowsableState], [ILAttribElem.Int32 n], []) + mkILCustomAttribute (findSysILTypeRef tname_DebuggerBrowsableAttribute, [typ_DebuggerBrowsableState], [ILAttribElem.Int32 n], []) - let mkDebuggerBrowsableNeverAttribute() = + let mkDebuggerBrowsableNeverAttribute() = match debuggerBrowsableNeverAttributeCache with | None -> let res = tref_DebuggerBrowsableAttribute 0 @@ -774,14 +812,14 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let addNeverAttrs (attrs: ILAttributes) = mkILCustomAttrs (attrs.AsList @ [mkDebuggerBrowsableNeverAttribute()]) let addPropertyNeverAttrs (pdef:ILPropertyDef) = pdef.With(customAttrs = addNeverAttrs pdef.CustomAttrs) let addFieldNeverAttrs (fdef:ILFieldDef) = fdef.With(customAttrs = addNeverAttrs fdef.CustomAttrs) - let mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerTypeProxyAttribute, [ilg.typ_Type], [ILAttribElem.TypeRef (Some ty.TypeRef)], []) + let mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute (findSysILTypeRef tname_DebuggerTypeProxyAttribute, [ilg.typ_Type], [ILAttribElem.TypeRef (Some ty.TypeRef)], []) - let betterTyconEntries = - [| "Int32" , v_int_tcr - "IntPtr" , v_nativeint_tcr + let betterTyconEntries = + [| "Int32" , v_int_tcr + "IntPtr" , v_nativeint_tcr "UIntPtr" , v_unativeint_tcr - "Int16" , v_int16_tcr - "Int64" , v_int64_tcr + "Int16" , v_int16_tcr + "Int64" , v_int64_tcr "UInt16" , v_uint16_tcr "UInt32" , v_uint32_tcr "UInt64" , v_uint64_tcr @@ -794,13 +832,13 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d "Exception", v_exn_tcr "Char" , v_char_tcr "Double" , v_float_tcr - "Single" , v_float32_tcr |] - |> Array.map (fun (nm, tcr) -> - let ty = mkNonGenericTy tcr - nm, findSysTyconRef sys nm, (fun _ -> ty)) + "Single" , v_float32_tcr |] + |> Array.map (fun (nm, tcr) -> + let ty = mkNonGenericTy tcr + nm, findSysTyconRef sys nm, (fun _ -> ty)) let decompileTyconEntries = - [| + [| "FSharpFunc`2" , v_fastFunc_tcr , (fun tinst -> mkFunTy (List.item 0 tinst) (List.item 1 tinst)) "Tuple`2" , v_ref_tuple2_tcr , decodeTupleTy tupInfoRef "Tuple`3" , v_ref_tuple3_tcr , decodeTupleTy tupInfoRef @@ -815,7 +853,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d "ValueTuple`5" , v_struct_tuple5_tcr , decodeTupleTy tupInfoStruct "ValueTuple`6" , v_struct_tuple6_tcr , decodeTupleTy tupInfoStruct "ValueTuple`7" , v_struct_tuple7_tcr , decodeTupleTy tupInfoStruct - "ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTyIfPossible v_struct_tuple8_tcr tupInfoStruct |] + "ValueTuple`8" , v_struct_tuple8_tcr , decodeTupleTyIfPossible v_struct_tuple8_tcr tupInfoStruct |] let betterEntries = Array.append betterTyconEntries decompileTyconEntries @@ -823,10 +861,10 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let mutable betterTypeDict1 = null let mutable betterTypeDict2 = null - /// This map is indexed by stamps and lazy to avoid dereferencing while setting up the base imports. - let getDecompileTypeDict () = - match decompileTypeDict with - | null -> + /// This map is indexed by stamps and lazy to avoid dereferencing while setting up the base imports. + let getDecompileTypeDict () = + match decompileTypeDict with + | null -> let entries = decompileTyconEntries let t = Dictionary.newWithSize entries.Length for _, tcref, builder in entries do @@ -838,10 +876,10 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d /// This map is for use when building FSharp.Core.dll. The backing Tycon's may not yet exist for /// the TyconRef's we have in our hands, hence we can't dereference them to find their stamps. - /// So this dictionary is indexed by names. Make it lazy to avoid dereferencing while setting up the base imports. - let getBetterTypeDict1 () = - match betterTypeDict1 with - | null -> + /// So this dictionary is indexed by names. Make it lazy to avoid dereferencing while setting up the base imports. + let getBetterTypeDict1 () = + match betterTypeDict1 with + | null -> let entries = betterEntries let t = Dictionary.newWithSize entries.Length for nm, tcref, builder in entries do @@ -851,10 +889,10 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d | t -> t /// This map is for use in normal times (not building FSharp.Core.dll). It is indexed by stamps - /// and lazy to avoid dereferencing while setting up the base imports. - let getBetterTypeDict2 () = - match betterTypeDict2 with - | null -> + /// and lazy to avoid dereferencing while setting up the base imports. + let getBetterTypeDict2 () = + match betterTypeDict2 with + | null -> let entries = betterEntries let t = Dictionary.newWithSize entries.Length for _, tcref, builder in entries do @@ -867,8 +905,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d /// For logical purposes equate some F# types with .NET types, e.g. TType_tuple == System.Tuple/ValueTuple. /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs). - let decompileTy (tcref: EntityRef) tinst = - if compilingFslib then + let decompileTy (tcref: EntityRef) tinst = + if compilingFslib then // No need to decompile when compiling FSharp.Core.dll TType_app (tcref, tinst) else @@ -877,11 +915,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d | true, builder -> builder tinst | _ -> TType_app (tcref, tinst) - /// For cosmetic purposes "improve" some .NET types, e.g. Int32 --> int32. + /// For cosmetic purposes "improve" some .NET types, e.g. Int32 --> int32. /// Doing this normalization is a fairly performance critical piece of code as it is frequently invoked /// in the process of converting .NET metadata to F# internal compiler data structures (see import.fs). - let improveTy (tcref: EntityRef) tinst = - if compilingFslib then + let improveTy (tcref: EntityRef) tinst = + if compilingFslib then let dict = getBetterTypeDict1() match dict.TryGetValue tcref.LogicalName with | true, builder -> builder tcref tinst @@ -894,106 +932,125 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d override x.ToString() = "" - member __.ilg=ilg + member _.ilg=ilg // A table of all intrinsics that the compiler cares about - member __.knownIntrinsics = v_knownIntrinsics + member _.knownIntrinsics = v_knownIntrinsics // A table of known modules in FSharp.Core. Not all modules are necessarily listed, but the more we list the // better the job we do of mapping from provided expressions back to FSharp.Core F# functions and values. - member __.knownFSharpCoreModules = v_knownFSharpCoreModules - member __.compilingFslib = compilingFslib - member __.mlCompatibility = mlCompatibility - member __.emitDebugInfoInQuotations = emitDebugInfoInQuotations - member __.directoryToResolveRelativePaths= directoryToResolveRelativePaths - member __.pathMap = pathMap - member __.langVersion = langVersion - member __.unionCaseRefEq x y = primUnionCaseRefEq compilingFslib fslibCcu x y - member __.valRefEq x y = primValRefEq compilingFslib fslibCcu x y - member __.fslibCcu = fslibCcu + member _.knownFSharpCoreModules = v_knownFSharpCoreModules + member _.compilingFslib = compilingFslib + member _.mlCompatibility = mlCompatibility + member _.emitDebugInfoInQuotations = emitDebugInfoInQuotations + member _.directoryToResolveRelativePaths= directoryToResolveRelativePaths + member _.pathMap = pathMap + member _.langVersion = langVersion + member _.unionCaseRefEq x y = primUnionCaseRefEq compilingFslib fslibCcu x y + member _.valRefEq x y = primValRefEq compilingFslib fslibCcu x y + member _.fslibCcu = fslibCcu member val refcell_tcr_canon = v_refcell_tcr_canon member val option_tcr_canon = mk_MFCore_tcref fslibCcu "Option`1" - member __.list_tcr_canon = v_list_tcr_canon + member val valueoption_tcr_canon = mk_MFCore_tcref fslibCcu "ValueOption`1" + member _.list_tcr_canon = v_list_tcr_canon member val set_tcr_canon = mk_MFCollections_tcref fslibCcu "Set`1" member val map_tcr_canon = mk_MFCollections_tcref fslibCcu "Map`2" - member __.lazy_tcr_canon = lazy_tcr + member _.lazy_tcr_canon = lazy_tcr member val refcell_tcr_nice = v_refcell_tcr_nice member val array_tcr_nice = v_il_arr_tcr_map.[0] - member __.option_tcr_nice = v_option_tcr_nice - member __.list_tcr_nice = v_list_tcr_nice - member __.lazy_tcr_nice = v_lazy_tcr_nice - member __.format_tcr = v_format_tcr - member __.expr_tcr = v_expr_tcr - member __.raw_expr_tcr = v_raw_expr_tcr - member __.nativeint_tcr = v_nativeint_tcr - member __.unativeint_tcr = v_unativeint_tcr - member __.int_tcr = v_int_tcr - member __.int32_tcr = v_int32_tcr - member __.int16_tcr = v_int16_tcr - member __.int64_tcr = v_int64_tcr - member __.uint16_tcr = v_uint16_tcr - member __.uint32_tcr = v_uint32_tcr - member __.uint64_tcr = v_uint64_tcr - member __.sbyte_tcr = v_sbyte_tcr - member __.decimal_tcr = v_decimal_tcr - member __.date_tcr = v_date_tcr - member __.pdecimal_tcr = v_pdecimal_tcr - member __.byte_tcr = v_byte_tcr - member __.bool_tcr = v_bool_tcr - member __.unit_tcr_canon = v_unit_tcr_canon - member __.unit_tcr_nice = v_unit_tcr_nice - member __.exn_tcr = v_exn_tcr - member __.char_tcr = v_char_tcr - member __.float_tcr = v_float_tcr - member __.float32_tcr = v_float32_tcr - member __.pfloat_tcr = v_pfloat_tcr - member __.pfloat32_tcr = v_pfloat32_tcr - member __.pint_tcr = v_pint_tcr - member __.pint8_tcr = v_pint8_tcr - member __.pint16_tcr = v_pint16_tcr - member __.pint64_tcr = v_pint64_tcr - member __.byref_tcr = v_byref_tcr - member __.byref2_tcr = v_byref2_tcr - member __.outref_tcr = v_outref_tcr - member __.inref_tcr = v_inref_tcr - member __.nativeptr_tcr = v_nativeptr_tcr - member __.voidptr_tcr = v_voidptr_tcr - member __.ilsigptr_tcr = v_ilsigptr_tcr - member __.fastFunc_tcr = v_fastFunc_tcr - member __.tcref_IQueryable = v_tcref_IQueryable - member __.tcref_IObservable = v_tcref_IObservable - member __.tcref_IObserver = v_tcref_IObserver - member __.fslib_IEvent2_tcr = v_fslib_IEvent2_tcr - member __.fslib_IDelegateEvent_tcr = v_fslib_IDelegateEvent_tcr - member __.seq_tcr = v_seq_tcr + member _.option_tcr_nice = v_option_tcr_nice + member _.valueoption_tcr_nice = v_valueoption_tcr_nice + member _.list_tcr_nice = v_list_tcr_nice + member _.lazy_tcr_nice = v_lazy_tcr_nice + member _.format_tcr = v_format_tcr + member _.expr_tcr = v_expr_tcr + member _.raw_expr_tcr = v_raw_expr_tcr + member _.nativeint_tcr = v_nativeint_tcr + member _.unativeint_tcr = v_unativeint_tcr + member _.int_tcr = v_int_tcr + member _.int32_tcr = v_int32_tcr + member _.int16_tcr = v_int16_tcr + member _.int64_tcr = v_int64_tcr + member _.uint16_tcr = v_uint16_tcr + member _.uint32_tcr = v_uint32_tcr + member _.uint64_tcr = v_uint64_tcr + member _.sbyte_tcr = v_sbyte_tcr + member _.decimal_tcr = v_decimal_tcr + member _.date_tcr = v_date_tcr + member _.pdecimal_tcr = v_pdecimal_tcr + member _.byte_tcr = v_byte_tcr + member _.bool_tcr = v_bool_tcr + member _.unit_tcr_canon = v_unit_tcr_canon + member _.unit_tcr_nice = v_unit_tcr_nice + member _.exn_tcr = v_exn_tcr + member _.char_tcr = v_char_tcr + member _.float_tcr = v_float_tcr + member _.float32_tcr = v_float32_tcr + member _.pfloat_tcr = v_pfloat_tcr + member _.pfloat32_tcr = v_pfloat32_tcr + member _.pint_tcr = v_pint_tcr + member _.pint8_tcr = v_pint8_tcr + member _.pint16_tcr = v_pint16_tcr + member _.pint64_tcr = v_pint64_tcr + member _.pnativeint_tcr = v_pnativeint_tcr + member _.puint_tcr = v_puint_tcr + member _.puint8_tcr = v_puint8_tcr + member _.puint16_tcr = v_puint16_tcr + member _.puint64_tcr = v_puint64_tcr + member _.punativeint_tcr = v_punativeint_tcr + member _.byref_tcr = v_byref_tcr + member _.byref2_tcr = v_byref2_tcr + member _.outref_tcr = v_outref_tcr + member _.inref_tcr = v_inref_tcr + member _.nativeptr_tcr = v_nativeptr_tcr + member _.voidptr_tcr = v_voidptr_tcr + member _.ilsigptr_tcr = v_ilsigptr_tcr + member _.fastFunc_tcr = v_fastFunc_tcr + member _.tcref_IQueryable = v_tcref_IQueryable + member _.tcref_IObservable = v_tcref_IObservable + member _.tcref_IObserver = v_tcref_IObserver + member _.fslib_IEvent2_tcr = v_fslib_IEvent2_tcr + member _.fslib_IDelegateEvent_tcr = v_fslib_IDelegateEvent_tcr + member _.seq_tcr = v_seq_tcr member val seq_base_tcr = mk_MFCompilerServices_tcref fslibCcu "GeneratedSequenceBase`1" + member val ListCollector_tcr = mk_MFCompilerServices_tcref fslibCcu "ListCollector`1" + member val ArrayCollector_tcr = mk_MFCompilerServices_tcref fslibCcu "ArrayCollector`1" + member g.mk_GeneratedSequenceBase_ty seqElemTy = TType_app(g.seq_base_tcr,[seqElemTy]) + member val ResumableStateMachine_tcr = mk_MFCompilerServices_tcref fslibCcu "ResumableStateMachine`1" + member g.mk_ResumableStateMachine_ty dataTy = TType_app(g.ResumableStateMachine_tcr,[dataTy]) + member val IResumableStateMachine_tcr = mk_MFCompilerServices_tcref fslibCcu "IResumableStateMachine`1" + member g.mk_IResumableStateMachine_ty dataTy = TType_app(g.IResumableStateMachine_tcr,[dataTy]) + member g.mk_ListCollector_ty seqElemTy = TType_app(g.ListCollector_tcr,[seqElemTy]) + member g.mk_ArrayCollector_ty seqElemTy = TType_app(g.ArrayCollector_tcr,[seqElemTy]) member val byrefkind_In_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "In" member val byrefkind_Out_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "Out" member val byrefkind_InOut_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "InOut" member val measureproduct_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureProduct`2" member val measureinverse_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureInverse`1" member val measureone_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureOne" - member __.il_arr_tcr_map = v_il_arr_tcr_map - member __.ref_tuple1_tcr = v_ref_tuple1_tcr - member __.ref_tuple2_tcr = v_ref_tuple2_tcr - member __.ref_tuple3_tcr = v_ref_tuple3_tcr - member __.ref_tuple4_tcr = v_ref_tuple4_tcr - member __.ref_tuple5_tcr = v_ref_tuple5_tcr - member __.ref_tuple6_tcr = v_ref_tuple6_tcr - member __.ref_tuple7_tcr = v_ref_tuple7_tcr - member __.ref_tuple8_tcr = v_ref_tuple8_tcr - member __.struct_tuple1_tcr = v_struct_tuple1_tcr - member __.struct_tuple2_tcr = v_struct_tuple2_tcr - member __.struct_tuple3_tcr = v_struct_tuple3_tcr - member __.struct_tuple4_tcr = v_struct_tuple4_tcr - member __.struct_tuple5_tcr = v_struct_tuple5_tcr - member __.struct_tuple6_tcr = v_struct_tuple6_tcr - member __.struct_tuple7_tcr = v_struct_tuple7_tcr - member __.struct_tuple8_tcr = v_struct_tuple8_tcr - member __.choice2_tcr = v_choice2_tcr - member __.choice3_tcr = v_choice3_tcr - member __.choice4_tcr = v_choice4_tcr - member __.choice5_tcr = v_choice5_tcr - member __.choice6_tcr = v_choice6_tcr - member __.choice7_tcr = v_choice7_tcr + member val ResumableCode_tcr = mk_MFCompilerServices_tcref fslibCcu "ResumableCode`2" + + member _.il_arr_tcr_map = v_il_arr_tcr_map + member _.ref_tuple1_tcr = v_ref_tuple1_tcr + member _.ref_tuple2_tcr = v_ref_tuple2_tcr + member _.ref_tuple3_tcr = v_ref_tuple3_tcr + member _.ref_tuple4_tcr = v_ref_tuple4_tcr + member _.ref_tuple5_tcr = v_ref_tuple5_tcr + member _.ref_tuple6_tcr = v_ref_tuple6_tcr + member _.ref_tuple7_tcr = v_ref_tuple7_tcr + member _.ref_tuple8_tcr = v_ref_tuple8_tcr + member _.struct_tuple1_tcr = v_struct_tuple1_tcr + member _.struct_tuple2_tcr = v_struct_tuple2_tcr + member _.struct_tuple3_tcr = v_struct_tuple3_tcr + member _.struct_tuple4_tcr = v_struct_tuple4_tcr + member _.struct_tuple5_tcr = v_struct_tuple5_tcr + member _.struct_tuple6_tcr = v_struct_tuple6_tcr + member _.struct_tuple7_tcr = v_struct_tuple7_tcr + member _.struct_tuple8_tcr = v_struct_tuple8_tcr + member _.choice2_tcr = v_choice2_tcr + member _.choice3_tcr = v_choice3_tcr + member _.choice4_tcr = v_choice4_tcr + member _.choice5_tcr = v_choice5_tcr + member _.choice6_tcr = v_choice6_tcr + member _.choice7_tcr = v_choice7_tcr member val nativeint_ty = v_nativeint_ty member val unativeint_ty = v_unativeint_ty member val int32_ty = v_int32_ty @@ -1003,20 +1060,26 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val uint32_ty = v_uint32_ty member val uint64_ty = v_uint64_ty member val sbyte_ty = v_sbyte_ty - member __.byte_ty = v_byte_ty - member __.bool_ty = v_bool_ty - member __.int_ty = v_int_ty - member __.string_ty = v_string_ty - member __.unit_ty = v_unit_ty - member __.obj_ty = v_obj_ty - member __.char_ty = v_char_ty - member __.decimal_ty = v_decimal_ty + member _.byte_ty = v_byte_ty + member _.bool_ty = v_bool_ty + member _.int_ty = v_int_ty + member _.string_ty = v_string_ty + member _.system_IFormattable_tcref = v_IFormattable_tcref + member _.system_FormattableString_tcref = v_FormattableString_tcref + member _.system_FormattableStringFactory_tcref = v_FormattableStringFactory_tcref + member _.system_IFormattable_ty = v_IFormattable_ty + member _.system_FormattableString_ty = v_FormattableString_ty + member _.system_FormattableStringFactory_ty = v_FormattableStringFactory_ty + member _.unit_ty = v_unit_ty + member _.obj_ty = v_obj_ty + member _.char_ty = v_char_ty + member _.decimal_ty = v_decimal_ty member val exn_ty = mkNonGenericTy v_exn_tcr member val float_ty = v_float_ty member val float32_ty = v_float32_ty /// Memoization table to help minimize the number of ILSourceDocument objects we create - member __.memoize_file x = v_memoize_file.Apply x + member _.memoize_file x = v_memoize_file.Apply x member val system_Array_ty = mkSysNonGenericTy sys "Array" member val system_Object_ty = mkSysNonGenericTy sys "Object" @@ -1030,7 +1093,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val system_String_typ = mkSysNonGenericTy sys "String" member val system_String_tcref = findSysTyconRef sys "String" member val system_Int32_ty = mkSysNonGenericTy sys "Int32" - member __.system_Type_ty = v_system_Type_ty + member _.system_Type_ty = v_system_Type_ty member val system_TypedReference_tcref = tryFindSysTyconRef sys "TypedReference" member val system_ArgIterator_tcref = tryFindSysTyconRef sys "ArgIterator" member val system_RuntimeArgumentHandle_tcref = tryFindSysTyconRef sys "RuntimeArgumentHandle" @@ -1040,7 +1103,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val system_Int32_tcref = findSysTyconRef sys "Int32" member val system_Int64_tcref = findSysTyconRef sys "Int64" member val system_IntPtr_tcref = findSysTyconRef sys "IntPtr" - member val system_Bool_tcref = findSysTyconRef sys "Boolean" + member val system_Bool_tcref = findSysTyconRef sys "Boolean" member val system_Byte_tcref = findSysTyconRef sys "Byte" member val system_UInt16_tcref = findSysTyconRef sys "UInt16" member val system_Char_tcref = findSysTyconRef sys "Char" @@ -1050,15 +1113,20 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val system_Single_tcref = findSysTyconRef sys "Single" member val system_Double_tcref = findSysTyconRef sys "Double" member val system_RuntimeTypeHandle_ty = mkSysNonGenericTy sys "RuntimeTypeHandle" - member __.system_RuntimeMethodHandle_ty = v_system_RuntimeMethodHandle_ty - + member _.system_RuntimeMethodHandle_ty = v_system_RuntimeMethodHandle_ty + member val system_MarshalByRefObject_tcref = tryFindSysTyconRef sys "MarshalByRefObject" member val system_MarshalByRefObject_ty = tryMkSysNonGenericTy sys "MarshalByRefObject" - member __.system_Reflection_MethodInfo_ty = v_system_Reflection_MethodInfo_ty + member val system_ExceptionDispatchInfo_ty = + tryMkSysNonGenericTy ["System"; "Runtime"; "ExceptionServices"] "ExceptionDispatchInfo" + + member _.system_Reflection_MethodInfo_ty = v_system_Reflection_MethodInfo_ty + member _.mk_IAsyncStateMachine_ty = mkSysNonGenericTy sysCompilerServices "IAsyncStateMachine" - member val system_Array_tcref = findSysTyconRef sys "Array" + member val system_Array_tcref = v_Array_tcref member val system_Object_tcref = findSysTyconRef sys "Object" + member val system_Value_tcref = findSysTyconRef sys "ValueType" member val system_Void_tcref = findSysTyconRef sys "Void" member val system_IndexOutOfRangeException_tcref = findSysTyconRef sys "IndexOutOfRangeException" member val system_Nullable_tcref = v_nullable_tcr @@ -1068,22 +1136,22 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val system_LinqExpression_tcref = v_linqExpression_tcr member val mk_IStructuralComparable_ty = mkSysNonGenericTy sysCollections "IStructuralComparable" - + member val mk_IStructuralEquatable_ty = mkSysNonGenericTy sysCollections "IStructuralEquatable" - member __.IComparer_ty = v_IComparer_ty - member __.IEqualityComparer_ty = v_IEqualityComparer_ty + member _.IComparer_ty = v_IComparer_ty + member _.IEqualityComparer_ty = v_IEqualityComparer_ty member val tcref_System_Collections_IComparer = findSysTyconRef sysCollections "IComparer" member val tcref_System_Collections_IEqualityComparer = findSysTyconRef sysCollections "IEqualityComparer" member val tcref_System_Collections_Generic_IEqualityComparer = findSysTyconRef sysGenerics "IEqualityComparer`1" member val tcref_System_Collections_Generic_Dictionary = findSysTyconRef sysGenerics "Dictionary`2" member val tcref_System_Collections_Generic_IDictionary = findSysTyconRef sysGenerics "IDictionary`2" - + member val tcref_System_IComparable = findSysTyconRef sys "IComparable" member val tcref_System_IStructuralComparable = findSysTyconRef sysCollections "IStructuralComparable" member val tcref_System_IStructuralEquatable = findSysTyconRef sysCollections "IStructuralEquatable" member val tcref_System_IDisposable = findSysTyconRef sys "IDisposable" - + member val tcref_LanguagePrimitives = mk_MFCore_tcref fslibCcu "LanguagePrimitives" member val tcref_System_Collections_Generic_List = findSysTyconRef sysGenerics "List`1" @@ -1091,12 +1159,15 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val tcref_System_Collections_Generic_IReadOnlyList = findSysTyconRef sysGenerics "IReadOnlyList`1" member val tcref_System_Collections_Generic_ICollection = findSysTyconRef sysGenerics "ICollection`1" member val tcref_System_Collections_Generic_IReadOnlyCollection = findSysTyconRef sysGenerics "IReadOnlyCollection`1" - member __.tcref_System_Collections_IEnumerable = v_tcref_System_Collections_IEnumerable + member _.tcref_System_Collections_IEnumerable = v_tcref_System_Collections_IEnumerable - member __.tcref_System_Collections_Generic_IEnumerable = v_IEnumerable_tcr - member __.tcref_System_Collections_Generic_IEnumerator = v_IEnumerator_tcr - - member __.tcref_System_Attribute = v_System_Attribute_tcr + member _.tcref_System_Collections_Generic_IEnumerable = v_IEnumerable_tcr + member _.tcref_System_Collections_Generic_IEnumerator = v_IEnumerator_tcr + + member _.tcref_System_Attribute = v_System_Attribute_tcr + + // Review: Does this need to be an option type? + member val System_Runtime_CompilerServices_RuntimeFeature_ty = tryFindSysTyconRef sysCompilerServices "RuntimeFeature" |> Option.map mkNonGenericTy member val iltyp_TypedReference = tryFindSysILTypeRef "System.TypedReference" |> Option.map mkILNonGenericValueTy member val iltyp_StreamingContext = tryFindSysILTypeRef tname_StreamingContext |> Option.map mkILNonGenericValueTy @@ -1116,24 +1187,24 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute" member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute" member val attrib_IUnknownConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IUnknownConstantAttribute" - + // We use 'findSysAttrib' here because lookup on attribute is done by name comparison, and can proceed // even if the type is not found in a system assembly. member val attrib_IsByRefLikeAttribute = findSysAttrib "System.Runtime.CompilerServices.IsByRefLikeAttribute" member val attrib_IsReadOnlyAttribute = findSysAttrib "System.Runtime.CompilerServices.IsReadOnlyAttribute" - + member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute" member val attrib_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute" member val attrib_StructLayoutAttribute = findSysAttrib "System.Runtime.InteropServices.StructLayoutAttribute" member val attrib_TypeForwardedToAttribute = findSysAttrib "System.Runtime.CompilerServices.TypeForwardedToAttribute" member val attrib_ComVisibleAttribute = findSysAttrib "System.Runtime.InteropServices.ComVisibleAttribute" member val attrib_ComImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.ComImportAttribute" - member val attrib_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute" + member val attrib_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute" member val attrib_MarshalAsAttribute = tryFindSysAttrib "System.Runtime.InteropServices.MarshalAsAttribute" - member val attrib_InAttribute = findSysAttrib "System.Runtime.InteropServices.InAttribute" - member val attrib_OutAttribute = findSysAttrib "System.Runtime.InteropServices.OutAttribute" - member val attrib_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute" - member val attrib_DefaultParameterValueAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DefaultParameterValueAttribute" + member val attrib_InAttribute = findSysAttrib "System.Runtime.InteropServices.InAttribute" + member val attrib_OutAttribute = findSysAttrib "System.Runtime.InteropServices.OutAttribute" + member val attrib_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute" + member val attrib_DefaultParameterValueAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DefaultParameterValueAttribute" member val attrib_ThreadStaticAttribute = tryFindSysAttrib "System.ThreadStaticAttribute" member val attrib_SpecialNameAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.SpecialNameAttribute" member val attrib_VolatileFieldAttribute = mk_MFCore_attrib "VolatileFieldAttribute" @@ -1148,11 +1219,16 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val attrib_CallerLineNumberAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerLineNumberAttribute" member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute" member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute" + member val attrib_SkipLocalsInitAttribute = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute" + member val attribs_Unsupported = [ + tryFindSysAttrib "System.Runtime.CompilerServices.ModuleInitializerAttribute" + tryFindSysAttrib "System.Runtime.CompilerServices.CallerArgumentExpressionAttribute" + ] |> List.choose (Option.map (fun x -> x.TyconRef)) member val attrib_ProjectionParameterAttribute = mk_MFCore_attrib "ProjectionParameterAttribute" member val attrib_CustomOperationAttribute = mk_MFCore_attrib "CustomOperationAttribute" member val attrib_NonSerializedAttribute = tryFindSysAttrib "System.NonSerializedAttribute" - + member val attrib_AutoSerializableAttribute = mk_MFCore_attrib "AutoSerializableAttribute" member val attrib_RequireQualifiedAccessAttribute = mk_MFCore_attrib "RequireQualifiedAccessAttribute" member val attrib_EntryPointAttribute = mk_MFCore_attrib "EntryPointAttribute" @@ -1176,6 +1252,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val attrib_CompilationArgumentCountsAttribute = mk_MFCore_attrib "CompilationArgumentCountsAttribute" member val attrib_CompilationMappingAttribute = mk_MFCore_attrib "CompilationMappingAttribute" member val attrib_CLIEventAttribute = mk_MFCore_attrib "CLIEventAttribute" + member val attrib_InlineIfLambdaAttribute = mk_MFCore_attrib "InlineIfLambdaAttribute" member val attrib_CLIMutableAttribute = mk_MFCore_attrib "CLIMutableAttribute" member val attrib_AllowNullLiteralAttribute = mk_MFCore_attrib "AllowNullLiteralAttribute" member val attrib_NoEqualityAttribute = mk_MFCore_attrib "NoEqualityAttribute" @@ -1202,32 +1279,35 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member g.decompileType tcref tinst = decompileTy tcref tinst - member __.new_decimal_info = v_new_decimal_info - member __.seq_info = v_seq_info - member val seq_vref = (ValRefForIntrinsic v_seq_info) + member _.new_decimal_info = v_new_decimal_info + member _.seq_info = v_seq_info + member val seq_vref = (ValRefForIntrinsic v_seq_info) member val fsharpref_vref = (ValRefForIntrinsic v_refcell_info) - member val and_vref = (ValRefForIntrinsic v_and_info) + member val and_vref = (ValRefForIntrinsic v_and_info) member val and2_vref = (ValRefForIntrinsic v_and2_info) member val addrof_vref = (ValRefForIntrinsic v_addrof_info) member val addrof2_vref = (ValRefForIntrinsic v_addrof2_info) member val or_vref = (ValRefForIntrinsic v_or_info) member val splice_expr_vref = (ValRefForIntrinsic v_splice_expr_info) member val splice_raw_expr_vref = (ValRefForIntrinsic v_splice_raw_expr_info) - member val or2_vref = (ValRefForIntrinsic v_or2_info) + member val or2_vref = (ValRefForIntrinsic v_or2_info) member val generic_equality_er_inner_vref = ValRefForIntrinsic v_generic_equality_er_inner_info member val generic_equality_per_inner_vref = ValRefForIntrinsic v_generic_equality_per_inner_info member val generic_equality_withc_inner_vref = ValRefForIntrinsic v_generic_equality_withc_inner_info member val generic_comparison_inner_vref = ValRefForIntrinsic v_generic_comparison_inner_info member val generic_comparison_withc_inner_vref = ValRefForIntrinsic v_generic_comparison_withc_inner_info - member __.generic_comparison_withc_outer_info = v_generic_comparison_withc_outer_info - member __.generic_equality_er_outer_info = v_generic_equality_er_outer_info - member __.generic_equality_withc_outer_info = v_generic_equality_withc_outer_info - member __.generic_hash_withc_outer_info = v_generic_hash_withc_outer_info + member _.generic_comparison_withc_outer_info = v_generic_comparison_withc_outer_info + member _.generic_equality_er_outer_info = v_generic_equality_er_outer_info + member _.generic_equality_withc_outer_info = v_generic_equality_withc_outer_info + member _.generic_hash_withc_outer_info = v_generic_hash_withc_outer_info member val generic_hash_inner_vref = ValRefForIntrinsic v_generic_hash_inner_info member val generic_hash_withc_inner_vref = ValRefForIntrinsic v_generic_hash_withc_inner_info member val reference_equality_inner_vref = ValRefForIntrinsic v_reference_equality_inner_info + member val piperight_vref = ValRefForIntrinsic v_piperight_info + member val piperight2_vref = ValRefForIntrinsic v_piperight2_info + member val piperight3_vref = ValRefForIntrinsic v_piperight3_info member val bitwise_or_vref = ValRefForIntrinsic v_bitwise_or_info member val bitwise_and_vref = ValRefForIntrinsic v_bitwise_and_info member val bitwise_xor_vref = ValRefForIntrinsic v_bitwise_xor_info @@ -1241,55 +1321,60 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val unchecked_subtraction_vref = ValRefForIntrinsic v_unchecked_subtraction_info member val unchecked_multiply_vref = ValRefForIntrinsic v_unchecked_multiply_info member val unchecked_defaultof_vref = ValRefForIntrinsic v_unchecked_defaultof_info - - member __.bitwise_or_info = v_bitwise_or_info - member __.bitwise_and_info = v_bitwise_and_info - member __.bitwise_xor_info = v_bitwise_xor_info - member __.bitwise_unary_not_info = v_bitwise_unary_not_info - member __.bitwise_shift_left_info = v_bitwise_shift_left_info - member __.bitwise_shift_right_info = v_bitwise_shift_right_info - member __.unchecked_addition_info = v_unchecked_addition_info - member __.unchecked_subtraction_info = v_unchecked_subtraction_info - member __.unchecked_multiply_info = v_unchecked_multiply_info - member __.unchecked_division_info = v_unchecked_division_info - member __.unchecked_modulus_info = v_unchecked_modulus_info - member __.unchecked_unary_plus_info = v_unchecked_unary_plus_info - member __.unchecked_unary_minus_info = v_unchecked_unary_minus_info - member __.unchecked_unary_not_info = v_unchecked_unary_not_info - - member __.checked_addition_info = v_checked_addition_info - member __.checked_subtraction_info = v_checked_subtraction_info - member __.checked_multiply_info = v_checked_multiply_info - member __.checked_unary_minus_info = v_checked_unary_minus_info - - member __.byte_checked_info = v_byte_checked_info - member __.sbyte_checked_info = v_sbyte_checked_info - member __.int16_checked_info = v_int16_checked_info - member __.uint16_checked_info = v_uint16_checked_info - member __.int_checked_info = v_int_checked_info - member __.int32_checked_info = v_int32_checked_info - member __.uint32_checked_info = v_uint32_checked_info - member __.int64_checked_info = v_int64_checked_info - member __.uint64_checked_info = v_uint64_checked_info - member __.nativeint_checked_info = v_nativeint_checked_info - member __.unativeint_checked_info = v_unativeint_checked_info - - member __.byte_operator_info = v_byte_operator_info - member __.sbyte_operator_info = v_sbyte_operator_info - member __.int16_operator_info = v_int16_operator_info - member __.uint16_operator_info = v_uint16_operator_info - member __.int_operator_info = v_int_operator_info - member __.int32_operator_info = v_int32_operator_info - member __.uint32_operator_info = v_uint32_operator_info - member __.int64_operator_info = v_int64_operator_info - member __.uint64_operator_info = v_uint64_operator_info - member __.float32_operator_info = v_float32_operator_info - member __.float_operator_info = v_float_operator_info - member __.nativeint_operator_info = v_nativeint_operator_info - member __.unativeint_operator_info = v_unativeint_operator_info - - member __.char_operator_info = v_char_operator_info - member __.enum_operator_info = v_enum_operator_info + member val refcell_deref_vref = ValRefForIntrinsic v_refcell_deref_info + member val refcell_assign_vref = ValRefForIntrinsic v_refcell_assign_info + member val refcell_incr_vref = ValRefForIntrinsic v_refcell_incr_info + member val refcell_decr_vref = ValRefForIntrinsic v_refcell_decr_info + + member _.bitwise_or_info = v_bitwise_or_info + member _.bitwise_and_info = v_bitwise_and_info + member _.bitwise_xor_info = v_bitwise_xor_info + member _.bitwise_unary_not_info = v_bitwise_unary_not_info + member _.bitwise_shift_left_info = v_bitwise_shift_left_info + member _.bitwise_shift_right_info = v_bitwise_shift_right_info + member _.unchecked_addition_info = v_unchecked_addition_info + member _.unchecked_subtraction_info = v_unchecked_subtraction_info + member _.unchecked_multiply_info = v_unchecked_multiply_info + member _.unchecked_division_info = v_unchecked_division_info + member _.unchecked_modulus_info = v_unchecked_modulus_info + member _.unchecked_unary_plus_info = v_unchecked_unary_plus_info + member _.unchecked_unary_minus_info = v_unchecked_unary_minus_info + member _.unchecked_unary_not_info = v_unchecked_unary_not_info + member _.unchecked_defaultof_info = v_unchecked_defaultof_info + + member _.checked_addition_info = v_checked_addition_info + member _.checked_subtraction_info = v_checked_subtraction_info + member _.checked_multiply_info = v_checked_multiply_info + member _.checked_unary_minus_info = v_checked_unary_minus_info + + member _.byte_checked_info = v_byte_checked_info + member _.sbyte_checked_info = v_sbyte_checked_info + member _.int16_checked_info = v_int16_checked_info + member _.uint16_checked_info = v_uint16_checked_info + member _.int_checked_info = v_int_checked_info + member _.int32_checked_info = v_int32_checked_info + member _.uint32_checked_info = v_uint32_checked_info + member _.int64_checked_info = v_int64_checked_info + member _.uint64_checked_info = v_uint64_checked_info + member _.nativeint_checked_info = v_nativeint_checked_info + member _.unativeint_checked_info = v_unativeint_checked_info + + member _.byte_operator_info = v_byte_operator_info + member _.sbyte_operator_info = v_sbyte_operator_info + member _.int16_operator_info = v_int16_operator_info + member _.uint16_operator_info = v_uint16_operator_info + member _.int_operator_info = v_int_operator_info + member _.int32_operator_info = v_int32_operator_info + member _.uint32_operator_info = v_uint32_operator_info + member _.int64_operator_info = v_int64_operator_info + member _.uint64_operator_info = v_uint64_operator_info + member _.float32_operator_info = v_float32_operator_info + member _.float_operator_info = v_float_operator_info + member _.nativeint_operator_info = v_nativeint_operator_info + member _.unativeint_operator_info = v_unativeint_operator_info + + member _.char_operator_info = v_char_operator_info + member _.enum_operator_info = v_enum_operator_info member val compare_operator_vref = ValRefForIntrinsic v_compare_operator_info member val equals_operator_vref = ValRefForIntrinsic v_equals_operator_info @@ -1309,27 +1394,27 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val invalid_op_vref = ValRefForIntrinsic v_invalid_op_info member val failwithf_vref = ValRefForIntrinsic v_failwithf_info - member __.equals_operator_info = v_equals_operator_info - member __.not_equals_operator = v_not_equals_operator_info - member __.less_than_operator = v_less_than_operator_info - member __.less_than_or_equals_operator = v_less_than_or_equals_operator_info - member __.greater_than_operator = v_greater_than_operator_info - member __.greater_than_or_equals_operator = v_greater_than_or_equals_operator_info - - member __.hash_info = v_hash_info - member __.box_info = v_box_info - member __.isnull_info = v_isnull_info - member __.isnotnull_info = v_isnotnull_info - member __.raise_info = v_raise_info - member __.failwith_info = v_failwith_info - member __.invalid_arg_info = v_invalid_arg_info - member __.null_arg_info = v_null_arg_info - member __.invalid_op_info = v_invalid_op_info - member __.failwithf_info = v_failwithf_info - member __.reraise_info = v_reraise_info - member __.methodhandleof_info = v_methodhandleof_info - member __.typeof_info = v_typeof_info - member __.typedefof_info = v_typedefof_info + member _.equals_operator_info = v_equals_operator_info + member _.not_equals_operator = v_not_equals_operator_info + member _.less_than_operator = v_less_than_operator_info + member _.less_than_or_equals_operator = v_less_than_or_equals_operator_info + member _.greater_than_operator = v_greater_than_operator_info + member _.greater_than_or_equals_operator = v_greater_than_or_equals_operator_info + + member _.hash_info = v_hash_info + member _.box_info = v_box_info + member _.isnull_info = v_isnull_info + member _.isnotnull_info = v_isnotnull_info + member _.raise_info = v_raise_info + member _.failwith_info = v_failwith_info + member _.invalid_arg_info = v_invalid_arg_info + member _.null_arg_info = v_null_arg_info + member _.invalid_op_info = v_invalid_op_info + member _.failwithf_info = v_failwithf_info + member _.reraise_info = v_reraise_info + member _.methodhandleof_info = v_methodhandleof_info + member _.typeof_info = v_typeof_info + member _.typedefof_info = v_typedefof_info member val reraise_vref = ValRefForIntrinsic v_reraise_info member val methodhandleof_vref = ValRefForIntrinsic v_methodhandleof_info @@ -1373,58 +1458,70 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val query_select_vref = ValRefForIntrinsic v_query_select_value_info member val query_where_vref = ValRefForIntrinsic v_query_where_value_info member val query_zero_vref = ValRefForIntrinsic v_query_zero_value_info - - member __.seq_collect_info = v_seq_collect_info - member __.seq_using_info = v_seq_using_info - member __.seq_delay_info = v_seq_delay_info - member __.seq_append_info = v_seq_append_info - member __.seq_generated_info = v_seq_generated_info - member __.seq_finally_info = v_seq_finally_info - member __.seq_of_functions_info = v_seq_of_functions_info - member __.seq_map_info = v_seq_map_info - member __.seq_singleton_info = v_seq_singleton_info - member __.seq_empty_info = v_seq_empty_info - member __.new_format_info = v_new_format_info - member __.unbox_info = v_unbox_info - member __.get_generic_comparer_info = v_get_generic_comparer_info - member __.get_generic_er_equality_comparer_info = v_get_generic_er_equality_comparer_info - member __.get_generic_per_equality_comparer_info = v_get_generic_per_equality_comparer_info - member __.dispose_info = v_dispose_info - member __.getstring_info = v_getstring_info - member __.unbox_fast_info = v_unbox_fast_info - member __.istype_info = v_istype_info - member __.istype_fast_info = v_istype_fast_info - member __.lazy_force_info = v_lazy_force_info - member __.lazy_create_info = v_lazy_create_info - member __.create_instance_info = v_create_instance_info - member __.create_event_info = v_create_event_info - member __.seq_to_list_info = v_seq_to_list_info - member __.seq_to_array_info = v_seq_to_array_info - - member __.array_length_info = v_array_length_info - member __.array_get_info = v_array_get_info - member __.array2D_get_info = v_array2D_get_info - member __.array3D_get_info = v_array3D_get_info - member __.array4D_get_info = v_array4D_get_info - member __.array_set_info = v_array_set_info - member __.array2D_set_info = v_array2D_set_info - member __.array3D_set_info = v_array3D_set_info - member __.array4D_set_info = v_array4D_set_info - - member __.deserialize_quoted_FSharp_20_plus_info = v_deserialize_quoted_FSharp_20_plus_info - member __.deserialize_quoted_FSharp_40_plus_info = v_deserialize_quoted_FSharp_40_plus_info - member __.cast_quotation_info = v_cast_quotation_info - member __.lift_value_info = v_lift_value_info - member __.lift_value_with_name_info = v_lift_value_with_name_info - member __.lift_value_with_defn_info = v_lift_value_with_defn_info - member __.query_source_as_enum_info = v_query_source_as_enum_info - member __.new_query_source_info = v_new_query_source_info - member __.query_builder_tcref = v_query_builder_tcref - member __.fail_init_info = v_fail_init_info - member __.fail_static_init_info = v_fail_static_init_info - member __.check_this_info = v_check_this_info - member __.quote_to_linq_lambda_info = v_quote_to_linq_lambda_info - + member val seq_to_list_vref = ValRefForIntrinsic v_seq_to_list_info + member val seq_to_array_vref = ValRefForIntrinsic v_seq_to_array_info + + member _.seq_collect_info = v_seq_collect_info + member _.seq_using_info = v_seq_using_info + member _.seq_delay_info = v_seq_delay_info + member _.seq_append_info = v_seq_append_info + member _.seq_generated_info = v_seq_generated_info + member _.seq_finally_info = v_seq_finally_info + member _.seq_of_functions_info = v_seq_of_functions_info + member _.seq_map_info = v_seq_map_info + member _.seq_singleton_info = v_seq_singleton_info + member _.seq_empty_info = v_seq_empty_info + member _.sprintf_info = v_sprintf_info + member _.new_format_info = v_new_format_info + member _.unbox_info = v_unbox_info + member _.get_generic_comparer_info = v_get_generic_comparer_info + member _.get_generic_er_equality_comparer_info = v_get_generic_er_equality_comparer_info + member _.get_generic_per_equality_comparer_info = v_get_generic_per_equality_comparer_info + member _.dispose_info = v_dispose_info + member _.getstring_info = v_getstring_info + member _.unbox_fast_info = v_unbox_fast_info + member _.istype_info = v_istype_info + member _.istype_fast_info = v_istype_fast_info + member _.lazy_force_info = v_lazy_force_info + member _.lazy_create_info = v_lazy_create_info + member _.create_instance_info = v_create_instance_info + member _.create_event_info = v_create_event_info + member _.seq_to_list_info = v_seq_to_list_info + member _.seq_to_array_info = v_seq_to_array_info + + member _.array_length_info = v_array_length_info + member _.array_get_info = v_array_get_info + member _.array2D_get_info = v_array2D_get_info + member _.array3D_get_info = v_array3D_get_info + member _.array4D_get_info = v_array4D_get_info + member _.array_set_info = v_array_set_info + member _.array2D_set_info = v_array2D_set_info + member _.array3D_set_info = v_array3D_set_info + member _.array4D_set_info = v_array4D_set_info + + member val option_toNullable_info = v_option_toNullable_info + member val option_defaultValue_info = v_option_defaultValue_info + + member _.deserialize_quoted_FSharp_20_plus_info = v_deserialize_quoted_FSharp_20_plus_info + member _.deserialize_quoted_FSharp_40_plus_info = v_deserialize_quoted_FSharp_40_plus_info + member _.call_with_witnesses_info = v_call_with_witnesses_info + member _.cast_quotation_info = v_cast_quotation_info + member _.lift_value_info = v_lift_value_info + member _.lift_value_with_name_info = v_lift_value_with_name_info + member _.lift_value_with_defn_info = v_lift_value_with_defn_info + member _.query_source_as_enum_info = v_query_source_as_enum_info + member _.new_query_source_info = v_new_query_source_info + member _.query_builder_tcref = v_query_builder_tcref + member _.fail_init_info = v_fail_init_info + member _.fail_static_init_info = v_fail_static_init_info + member _.check_this_info = v_check_this_info + member _.quote_to_linq_lambda_info = v_quote_to_linq_lambda_info + + + member val cgh__stateMachine_vref = ValRefForIntrinsic v_cgh__stateMachine_info + member val cgh__useResumableCode_vref = ValRefForIntrinsic v_cgh__useResumableCode_info + member val cgh__resumeAt_vref = ValRefForIntrinsic v_cgh__resumeAt_info + member val cgh__resumableEntry_vref = ValRefForIntrinsic v_cgh__resumableEntry_info member val generic_hash_withc_tuple2_vref = ValRefForIntrinsic v_generic_hash_withc_tuple2_info member val generic_hash_withc_tuple3_vref = ValRefForIntrinsic v_generic_hash_withc_tuple3_info @@ -1441,55 +1538,163 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val generic_equality_withc_outer_vref = ValRefForIntrinsic v_generic_equality_withc_outer_info - member __.cons_ucref = v_cons_ucref - member __.nil_ucref = v_nil_ucref - - // A list of types that are explicitly suppressed from the F# intellisense + member _.cons_ucref = v_cons_ucref + member _.nil_ucref = v_nil_ucref + + // A list of types that are explicitly suppressed from the F# intellisense // Note that the suppression checks for the precise name of the type // so the lowercase versions are visible - member __.suppressed_types = v_suppressed_types - /// Are we assuming all code gen is for F# interactive, with no static linking - member __.isInteractive=isInteractive - - member __.FindSysTyconRef path nm = findSysTyconRef path nm - member __.TryFindSysTyconRef path nm = tryFindSysTyconRef path nm - member __.FindSysILTypeRef nm = findSysILTypeRef nm - member __.TryFindSysILTypeRef nm = tryFindSysILTypeRef nm - member __.FindSysAttrib nm = findSysAttrib nm - member __.TryFindSysAttrib nm = tryFindSysAttrib nm - - member val ilxPubCloEnv=EraseClosures.newIlxPubCloEnv(ilg, addMethodGeneratedAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs) - member __.AddMethodGeneratedAttributes mdef = addMethodGeneratedAttrs mdef - member __.AddFieldGeneratedAttrs mdef = addFieldGeneratedAttrs mdef - member __.AddFieldNeverAttrs mdef = addFieldNeverAttrs mdef - member __.mkDebuggerHiddenAttribute() = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerHiddenAttribute, [], [], []) - member __.mkDebuggerDisplayAttribute s = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerDisplayAttribute, [ilg.typ_String], [ILAttribElem.String (Some s)], []) - member __.DebuggerBrowsableNeverAttribute = mkDebuggerBrowsableNeverAttribute() - - member __.mkDebuggerStepThroughAttribute() = mkILCustomAttribute ilg (findSysILTypeRef tname_DebuggerStepThroughAttribute, [], [], []) - member __.mkDebuggableAttribute (jitOptimizerDisabled) = - mkILCustomAttribute ilg (tref_DebuggableAttribute, [ilg.typ_Bool; ilg.typ_Bool], [ILAttribElem.Bool false; ILAttribElem.Bool jitOptimizerDisabled], []) - - - member __.mkDebuggableAttributeV2(jitTracking, ignoreSymbolStoreSequencePoints, jitOptimizerDisabled, enableEnC) = - let debuggingMode = + member _.suppressed_types = v_suppressed_types + + /// Are we assuming all code gen is for F# interactive, with no static linking + member _.isInteractive=isInteractive + + /// Indicates if we are generating witness arguments for SRTP constraints. Only done if the FSharp.Core + /// supports witness arguments. + member g.generateWitnesses = + compilingFslib || + ((ValRefForIntrinsic g.call_with_witnesses_info).TryDeref.IsSome && langVersion.SupportsFeature LanguageFeature.WitnessPassing) + + /// Indicates if we can use System.Array.Empty when emitting IL for empty array literals + member val isArrayEmptyAvailable = v_Array_tcref.ILTyconRawMetadata.Methods.FindByName "Empty" |> List.isEmpty |> not + + member _.FindSysTyconRef path nm = findSysTyconRef path nm + + member _.TryFindSysTyconRef path nm = tryFindSysTyconRef path nm + + member _.FindSysILTypeRef nm = findSysILTypeRef nm + + member _.TryFindSysILTypeRef nm = tryFindSysILTypeRef nm + + member _.FindSysAttrib nm = findSysAttrib nm + + member _.TryFindSysAttrib nm = tryFindSysAttrib nm + + member val ilxPubCloEnv = + EraseClosures.newIlxPubCloEnv(ilg, addMethodGeneratedAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs) + + member _.AddMethodGeneratedAttributes mdef = addMethodGeneratedAttrs mdef + + member _.AddFieldGeneratedAttrs mdef = addFieldGeneratedAttrs mdef + + member _.AddFieldNeverAttrs mdef = addFieldNeverAttrs mdef + + member _.mkDebuggerHiddenAttribute() = mkILCustomAttribute (findSysILTypeRef tname_DebuggerHiddenAttribute, [], [], []) + + member _.mkDebuggerDisplayAttribute s = mkILCustomAttribute (findSysILTypeRef tname_DebuggerDisplayAttribute, [ilg.typ_String], [ILAttribElem.String (Some s)], []) + + member _.DebuggerBrowsableNeverAttribute = mkDebuggerBrowsableNeverAttribute() + + member _.mkDebuggerStepThroughAttribute() = + mkILCustomAttribute (findSysILTypeRef tname_DebuggerStepThroughAttribute, [], [], []) + + member _.mkDebuggableAttribute jitOptimizerDisabled = + mkILCustomAttribute (tref_DebuggableAttribute, [ilg.typ_Bool; ilg.typ_Bool], [ILAttribElem.Bool false; ILAttribElem.Bool jitOptimizerDisabled], []) + + member _.mkDebuggableAttributeV2(jitTracking, ignoreSymbolStoreSequencePoints, jitOptimizerDisabled, enableEnC) = + let debuggingMode = (if jitTracking then 1 else 0) ||| - (if jitOptimizerDisabled then 256 else 0) ||| + (if jitOptimizerDisabled then 256 else 0) ||| (if ignoreSymbolStoreSequencePoints then 2 else 0) ||| (if enableEnC then 4 else 0) let tref_DebuggableAttribute_DebuggingModes = mkILTyRefInTyRef (tref_DebuggableAttribute, tname_DebuggableAttribute_DebuggingModes) - mkILCustomAttribute ilg + mkILCustomAttribute (tref_DebuggableAttribute, [mkILNonGenericValueTy tref_DebuggableAttribute_DebuggingModes], (* See System.Diagnostics.DebuggableAttribute.DebuggingModes *) [ILAttribElem.Int32( debuggingMode )], []) - member internal __.CompilerGlobalState = Some compilerGlobalState - - member __.CompilerGeneratedAttribute = mkCompilerGeneratedAttribute () - - member __.eraseClassUnionDef = EraseUnions.mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs, mkDebuggerTypeProxyAttribute) ilg + member internal _.CompilerGlobalState = Some compilerGlobalState + + member _.CompilerGeneratedAttribute = mkCompilerGeneratedAttribute () + + /// Find an FSharp.Core LaguagePrimitives dynamic function that corresponds to a trait witness, e.g. + /// AdditionDynamic for op_Addition. Also work out the type instantiation of the dynamic function. + member _.MakeBuiltInWitnessInfo (t: TraitConstraintInfo) = + let memberName = + let nm = t.MemberName + let coreName = + if nm.StartsWith "op_" then nm.[3..] + elif nm = "get_Zero" then "GenericZero" + elif nm = "get_One" then "GenericOne" + else nm + coreName + "Dynamic" + let gtps, argTys, retTy, tinst = + match memberName, t.ArgumentTypes, t.ReturnType with + | ("AdditionDynamic" | "MultiplyDynamic" | "SubtractionDynamic"| "DivisionDynamic" | "ModulusDynamic" | "CheckedAdditionDynamic" | "CheckedMultiplyDynamic" | "CheckedSubtractionDynamic" | "LeftShiftDynamic" | "RightShiftDynamic" | "BitwiseAndDynamic" | "BitwiseOrDynamic" | "ExclusiveOrDynamic" | "LessThanDynamic" | "GreaterThanDynamic" | "LessThanOrEqualDynamic" | "GreaterThanOrEqualDynamic" | "EqualityDynamic" | "InequalityDynamic"), + [ arg0Ty; arg1Ty ], + Some retTy -> + [vara; varb; varc], [ varaTy; varbTy ], varcTy, [ arg0Ty; arg1Ty; retTy ] + | ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic"), + [ arg0Ty ], + Some retTy -> + [vara; varb ], [ varaTy ], varbTy, [ arg0Ty; retTy ] + | "DivideByIntDynamic", [arg0Ty; _], _ -> + [vara], [ varaTy; v_int32_ty ], varaTy, [ arg0Ty ] + | ("GenericZeroDynamic" | "GenericOneDynamic"), [], Some retTy -> + [vara], [ ], varaTy, [ retTy ] + | _ -> failwithf "unknown builtin witness '%s'" memberName + let vref = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, memberName, None, None, gtps, (List.map List.singleton argTys, retTy)) + vref, tinst + + /// Find an FSharp.Core operator that corresponds to a trait witness + member g.TryMakeOperatorAsBuiltInWitnessInfo isStringTy isArrayTy (t: TraitConstraintInfo) argExprs = + + match t.MemberName, t.ArgumentTypes, t.ReturnType, argExprs with + | "get_Sign", [aty], _, objExpr :: _ -> + // Call Operators.sign + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "sign", None, Some "Sign", [vara], ([[varaTy]], v_int32_ty)) + let tyargs = [aty] + Some (info, tyargs, [objExpr]) + | "Sqrt", [aty], Some bty, [_] -> + // Call Operators.sqrt + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "sqrt", None, Some "Sqrt", [vara; varb], ([[varaTy]], varbTy)) + let tyargs = [aty; bty] + Some (info, tyargs, argExprs) + | "Pow", [aty;bty], _, [_;_] -> + // Call Operators.(**) + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "op_Exponentiation", None, None, [vara; varb], ([[varaTy]; [varbTy]], varaTy)) + let tyargs = [aty;bty] + Some (info, tyargs, argExprs) + | "Atan2", [aty;_], Some bty, [_;_] -> + // Call Operators.atan2 + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "atan2", None, Some "Atan2", [vara; varb], ([[varaTy]; [varaTy]], varbTy)) + let tyargs = [aty;bty] + Some (info, tyargs, argExprs) + | "get_Zero", _, Some aty, [_] -> + // Call LanguagePrimitives.GenericZero + let info = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, "GenericZero", None, None, [vara], ([], varaTy)) + let tyargs = [aty] + Some (info, tyargs, []) + | "get_One", _, Some aty, [_] -> + // Call LanguagePrimitives.GenericOne + let info = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, "GenericOne", None, None, [vara], ([], varaTy)) + let tyargs = [aty] + Some (info, tyargs, []) + | ("Abs" | "Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10"| "Log"), [aty], _, [_] -> + // Call corresponding Operators.* + let nm = t.MemberName + let lower = if nm = "Ceiling" then "ceil" else nm.ToLowerInvariant() + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, lower, None, Some nm, [vara], ([[varaTy]], varaTy)) + let tyargs = [aty] + Some (info, tyargs, argExprs) + | "get_Item", [arrTy; _], Some rty, [_; _] when isArrayTy g arrTy -> + Some (g.array_get_info, [rty], argExprs) + | "set_Item", [arrTy; _; ety], _, [_; _; _] when isArrayTy g arrTy -> + Some (g.array_set_info, [ety], argExprs) + | "get_Item", [sty; _; _], _, [_; _] when isStringTy g sty -> + Some (g.getstring_info, [], argExprs) + | "op_UnaryPlus", [aty], _, [_] -> + // Call Operators.id + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "id", None, None, [vara], ([[varaTy]], varaTy)) + let tyargs = [aty] + Some (info, tyargs, argExprs) + | _ -> + None + + member _.EraseClassUnionDef cud = + EraseUnions.mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs, mkDebuggerTypeProxyAttribute) ilg cud #if DEBUG -// This global is only used during debug output +// This global is only used during debug output let mutable global_g = None : TcGlobals option #endif diff --git a/src/fsharp/TextLayoutRender.fs b/src/fsharp/TextLayoutRender.fs new file mode 100644 index 00000000000..f042b1fdc64 --- /dev/null +++ b/src/fsharp/TextLayoutRender.fs @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.Text + +open System +open System.IO +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Core.Printf + +#nowarn "62" // This construct is for ML compatibility. + +type NavigableTaggedText(taggedText: TaggedText, range: range) = + inherit TaggedText(taggedText.Tag, taggedText.Text) + member val Range = range + +module SepL = + let dot = sepL TaggedText.dot + let star = sepL TaggedText.star + let colon = sepL TaggedText.colon + let questionMark = sepL TaggedText.questionMark + let leftParen = sepL TaggedText.leftParen + let comma = sepL TaggedText.comma + let space = sepL TaggedText.space + let leftBracket = sepL TaggedText.leftBracket + let leftAngle = sepL TaggedText.leftAngle + let lineBreak = sepL TaggedText.lineBreak + let rightParen = sepL TaggedText.rightParen + +module WordL = + let arrow = wordL TaggedText.arrow + let star = wordL TaggedText.star + let colon = wordL TaggedText.colon + let equals = wordL TaggedText.equals + let keywordNew = wordL TaggedText.keywordNew + let structUnit = wordL TaggedText.structUnit + let keywordStatic = wordL TaggedText.keywordStatic + let keywordMember = wordL TaggedText.keywordMember + let keywordVal = wordL TaggedText.keywordVal + let keywordEvent = wordL TaggedText.keywordEvent + let keywordWith = wordL TaggedText.keywordWith + let keywordSet = wordL TaggedText.keywordSet + let keywordGet = wordL TaggedText.keywordGet + let keywordTrue = wordL TaggedText.keywordTrue + let keywordFalse = wordL TaggedText.keywordFalse + let bar = wordL TaggedText.bar + let keywordStruct = wordL TaggedText.keywordStruct + let keywordInherit = wordL TaggedText.keywordInherit + let keywordBegin = wordL TaggedText.keywordBegin + let keywordEnd = wordL TaggedText.keywordEnd + let keywordNested = wordL TaggedText.keywordNested + let keywordType = wordL TaggedText.keywordType + let keywordDelegate = wordL TaggedText.keywordDelegate + let keywordOf = wordL TaggedText.keywordOf + let keywordInternal = wordL TaggedText.keywordInternal + let keywordPrivate = wordL TaggedText.keywordPrivate + let keywordAbstract = wordL TaggedText.keywordAbstract + let keywordOverride = wordL TaggedText.keywordOverride + let keywordEnum = wordL TaggedText.keywordEnum + +module LeftL = + let leftParen = leftL TaggedText.leftParen + let questionMark = leftL TaggedText.questionMark + let colon = leftL TaggedText.colon + let leftBracketAngle = leftL TaggedText.leftBracketAngle + let leftBracketBar = leftL TaggedText.leftBracketBar + let keywordTypeof = leftL TaggedText.keywordTypeof + let keywordTypedefof = leftL TaggedText.keywordTypedefof + +module RightL = + let comma = rightL TaggedText.comma + let rightParen = rightL TaggedText.rightParen + let colon = rightL TaggedText.colon + let rightBracket = rightL TaggedText.rightBracket + let rightAngle = rightL TaggedText.rightAngle + let rightBracketAngle = rightL TaggedText.rightBracketAngle + let rightBracketBar = rightL TaggedText.rightBracketBar + +type LayoutRenderer<'a, 'b> = + abstract Start : unit -> 'b + abstract AddText : 'b -> TaggedText -> 'b + abstract AddBreak : 'b -> int -> 'b + abstract AddTag : 'b -> string * (string * string) list * bool -> 'b + abstract Finish : 'b -> 'a + +type NoState = NoState +type NoResult = NoResult + +[] +module LayoutRender = + let mkNav r t = NavigableTaggedText(t, r) :> TaggedText + + let spaces n = String(' ', n) + + let renderL (rr: LayoutRenderer<_, _>) layout = + let rec addL z pos i layout k = + match layout with + | ObjLeaf _ -> failwith "ObjLeaf should never appear here" + (* pos is tab level *) + | Leaf (_, text, _) -> + k(rr.AddText z text, i + text.Text.Length) + | Node (l, r, Broken indent) -> + addL z pos i l <| + fun (z, _i) -> + let z, i = rr.AddBreak z (pos+indent), (pos+indent) + addL z (pos+indent) i r k + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) + addL z pos i l <| + fun (z, i) -> + let z, i = if jm then z, i else rr.AddText z TaggedText.space, i+1 + let pos = i + addL z pos i r k + | Attr (tag, attrs, l) -> + let z = rr.AddTag z (tag, attrs, true) + addL z pos i l <| + fun (z, i) -> + let z = rr.AddTag z (tag, attrs, false) + k(z, i) + let pos = 0 + let z, i = rr.Start(), 0 + let z, _i = addL z pos i layout id + rr.Finish z + + /// string render + let stringR = + { new LayoutRenderer with + member _.Start () = [] + member _.AddText rstrs taggedText = taggedText.Text :: rstrs + member _.AddBreak rstrs n = (spaces n) :: "\n" :: rstrs + member _.AddTag z (_, _, _) = z + member _.Finish rstrs = String.Join("", Array.ofList (List.rev rstrs)) } + + /// string render + let taggedTextListR collector = + { new LayoutRenderer with + member _.Start () = NoState + member _.AddText z text = collector text; z + member _.AddBreak rstrs n = collector TaggedText.lineBreak; collector (TaggedText.tagSpace(spaces n)); rstrs + member _.AddTag z (_, _, _) = z + member _.Finish rstrs = NoResult } + + /// channel LayoutRenderer + let channelR (chan:TextWriter) = + { new LayoutRenderer with + member r.Start () = NoState + member r.AddText z s = chan.Write s.Text; z + member r.AddBreak z n = chan.WriteLine(); chan.Write (spaces n); z + member r.AddTag z (tag, attrs, start) = z + member r.Finish z = NoResult } + + /// buffer render + let bufferR os = + { new LayoutRenderer with + member r.Start () = NoState + member r.AddText z s = bprintf os "%s" s.Text; z + member r.AddBreak z n = bprintf os "\n"; bprintf os "%s" (spaces n); z + member r.AddTag z (tag, attrs, start) = z + member r.Finish z = NoResult } + + let showL layout = renderL stringR layout + + let outL (chan:TextWriter) layout = renderL (channelR chan) layout |> ignore + + let bufferL os layout = renderL (bufferR os) layout |> ignore + + let emitL f layout = renderL (taggedTextListR f) layout |> ignore + + let toArray layout = + let output = ResizeArray() + renderL (taggedTextListR (fun tt -> output.Add(tt))) layout |> ignore + output.ToArray() diff --git a/src/fsharp/TextLayoutRender.fsi b/src/fsharp/TextLayoutRender.fsi new file mode 100644 index 00000000000..f2d71063e8a --- /dev/null +++ b/src/fsharp/TextLayoutRender.fsi @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// DSL to create structured layout objects with optional breaks and render them +namespace FSharp.Compiler.Text + +open System.Text +open System.IO +open FSharp.Compiler.Text + +/// An enhancement to TaggedText in the TaggedText layouts generated by FSharp.Compiler.Service +type public NavigableTaggedText = + internal new: TaggedText * range -> NavigableTaggedText + member Range: range + inherit TaggedText + +/// Render a Layout yielding an 'a using a 'b (hidden state) type +type internal LayoutRenderer<'a,'b> = + abstract Start: unit -> 'b + abstract AddText: 'b -> TaggedText -> 'b + abstract AddBreak: 'b -> int -> 'b + abstract AddTag: 'b -> string * (string * string) list * bool -> 'b + abstract Finish: 'b -> 'a + +type internal NoState = NoState +type internal NoResult = NoResult + +module internal LayoutRender = + + val internal toArray: Layout -> TaggedText[] + + val internal emitL: (TaggedText -> unit) -> Layout -> unit + + val internal mkNav: range -> TaggedText -> TaggedText + + val internal showL: Layout -> string + + val internal outL: TextWriter -> Layout -> unit + + val internal bufferL: StringBuilder -> Layout -> unit + + /// Run a render on a Layout + val internal renderL: LayoutRenderer<'b,'a> -> Layout -> 'b + + /// Render layout to string + val internal stringR: LayoutRenderer + + /// Render layout to channel + val internal channelR: TextWriter -> LayoutRenderer + + /// Render layout to StringBuilder + val internal bufferR: StringBuilder -> LayoutRenderer + + /// Render layout to collector of TaggedText + val internal taggedTextListR: collector: (TaggedText -> unit) -> LayoutRenderer + +module internal SepL = + val dot: Layout + val star: Layout + val colon: Layout + val questionMark: Layout + val leftParen: Layout + val comma: Layout + val space: Layout + val leftBracket: Layout + val leftAngle: Layout + val lineBreak: Layout + val rightParen: Layout + +module internal WordL = + val arrow: Layout + val star: Layout + val colon: Layout + val equals: Layout + val keywordNew: Layout + val structUnit: Layout + val keywordStatic: Layout + val keywordMember: Layout + val keywordVal: Layout + val keywordEvent: Layout + val keywordWith: Layout + val keywordSet: Layout + val keywordGet: Layout + val keywordTrue: Layout + val keywordFalse: Layout + val bar: Layout + val keywordStruct: Layout + val keywordInherit: Layout + val keywordBegin: Layout + val keywordEnd: Layout + val keywordNested: Layout + val keywordType: Layout + val keywordDelegate: Layout + val keywordOf: Layout + val keywordInternal: Layout + val keywordPrivate: Layout + val keywordAbstract: Layout + val keywordOverride: Layout + val keywordEnum: Layout + +module internal LeftL = + val leftParen: Layout + val questionMark: Layout + val colon: Layout + val leftBracketAngle: Layout + val leftBracketBar: Layout + val keywordTypeof: Layout + val keywordTypedefof: Layout + +module internal RightL = + val comma: Layout + val rightParen: Layout + val colon: Layout + val rightBracket: Layout + val rightAngle: Layout + val rightBracketAngle: Layout + val rightBracketBar: Layout + diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs deleted file mode 100644 index 5d7a170c2c8..00000000000 --- a/src/fsharp/TypeChecker.fs +++ /dev/null @@ -1,17747 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -/// The typechecker. Left-to-right constrained type checking -/// with generalization at appropriate points. -module internal FSharp.Compiler.TypeChecker - -open System -open System.Collections.Generic - -open Internal.Utilities - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Internal.Library.ResultOrException -open FSharp.Compiler.AbstractIL.Diagnostics - -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Rational -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.PatternMatchCompilation -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib -open FSharp.Compiler.Infos -open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.AttributeChecking -open FSharp.Compiler.TypeRelations -open FSharp.Compiler.MethodCalls -open FSharp.Compiler.MethodOverrides -open FSharp.Compiler.ConstraintSolver -open FSharp.Compiler.NameResolution -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.InfoReader -open FSharp.Compiler.Features - -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -#endif - -//------------------------------------------------------------------------- -// Helpers that should be elsewhere -//------------------------------------------------------------------------- - -let mkNilListPat (g: TcGlobals) m ty = TPat_unioncase(g.nil_ucref, [ty], [], m) -let mkConsListPat (g: TcGlobals) ty ph pt = TPat_unioncase(g.cons_ucref, [ty], [ph;pt], unionRanges ph.Range pt.Range) - -//------------------------------------------------------------------------- -// Errors. -//------------------------------------------------------------------------- - -exception BakedInMemberConstraintName of string * range -exception FunctionExpected of DisplayEnv * TType * range -exception NotAFunction of DisplayEnv * TType * range * range -exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range -exception Recursion of DisplayEnv * Ident * TType * TType * range -exception RecursiveUseCheckedAtRuntime of DisplayEnv * ValRef * range -exception LetRecEvaluatedOutOfOrder of DisplayEnv * ValRef * ValRef * range -exception LetRecCheckedAtRuntime of range -exception LetRecUnsound of DisplayEnv * ValRef list * range -exception TyconBadArgs of DisplayEnv * TyconRef * int * range -exception UnionCaseWrongArguments of DisplayEnv * int * int * range -exception UnionCaseWrongNumberOfArgs of DisplayEnv * int * int * range -exception FieldsFromDifferentTypes of DisplayEnv * RecdFieldRef * RecdFieldRef * range -exception FieldGivenTwice of DisplayEnv * Tast.RecdFieldRef * range -exception MissingFields of string list * range -exception FunctionValueUnexpected of DisplayEnv * TType * range -exception UnitTypeExpected of DisplayEnv * TType * range -exception UnitTypeExpectedWithEquality of DisplayEnv * TType * range -exception UnitTypeExpectedWithPossibleAssignment of DisplayEnv * TType * bool * string * range -exception UnitTypeExpectedWithPossiblePropertySetter of DisplayEnv * TType * string * string * range -exception UnionPatternsBindDifferentNames of range -exception VarBoundTwice of Ident -exception ValueRestriction of DisplayEnv * bool * Val * Typar * range -exception ValNotMutable of DisplayEnv * ValRef * range -exception ValNotLocal of DisplayEnv * ValRef * range -exception InvalidRuntimeCoercion of DisplayEnv * TType * TType * range -exception IndeterminateRuntimeCoercion of DisplayEnv * TType * TType * range -exception IndeterminateStaticCoercion of DisplayEnv * TType * TType * range -exception RuntimeCoercionSourceSealed of DisplayEnv * TType * range -exception CoercionTargetSealed of DisplayEnv * TType * range -exception UpcastUnnecessary of range -exception TypeTestUnnecessary of range -exception StaticCoercionShouldUseBox of DisplayEnv * TType * TType * range -exception SelfRefObjCtor of bool * range -exception VirtualAugmentationOnNullValuedType of range -exception NonVirtualAugmentationOnNullValuedType of range -exception UseOfAddressOfOperator of range -exception DeprecatedThreadStaticBindingWarning of range -exception IntfImplInIntrinsicAugmentation of range -exception IntfImplInExtrinsicAugmentation of range -exception OverrideInIntrinsicAugmentation of range -exception OverrideInExtrinsicAugmentation of range -exception NonUniqueInferredAbstractSlot of TcGlobals * DisplayEnv * string * MethInfo * MethInfo * range -exception StandardOperatorRedefinitionWarning of string * range -exception InvalidInternalsVisibleToAssemblyName of (*badName*)string * (*fileName option*) string option - -/// Represents information about the initialization field used to check that object constructors -/// have completed before fields are accessed. -type SafeInitData = - | SafeInitField of RecdFieldRef * RecdField - | NoSafeInitInfo - -/// Represents information about object constructors -type CtorInfo = - { /// Object model constructors have a very specific form to satisfy .NET limitations. - /// For "new = \arg. { new C with ... }" - /// ctor = 3 indicates about to type check "\arg. (body)", - /// ctor = 2 indicates about to type check "body" - /// ctor = 1 indicates actually type checking the body expression - /// 0 indicates everywhere else, including auxiliary expressions such e1 in "let x = e1 in { new ... }" - /// REVIEW: clean up this rather odd approach ... - ctorShapeCounter: int - - /// A handle to the ref cell to hold results of 'this' for 'type X() as x = ...' and 'new() as x = ...' constructs - /// in case 'x' is used in the arguments to the 'inherits' call. - safeThisValOpt: Val option - - /// A handle to the boolean ref cell to hold success of initialized 'this' for 'type X() as x = ...' constructs - safeInitInfo: SafeInitData - - /// Is the an implicit constructor or an explicit one? - ctorIsImplicit: bool - } - -/// Represents an item in the environment that may restrict the automatic generalization of later -/// declarations because it refers to type inference variables. As type inference progresses -/// these type inference variables may get solved. -[] -type UngeneralizableItem(computeFreeTyvars: (unit -> FreeTyvars)) = - - // Flag is for: have we determined that this item definitely has - // no free type inference variables? This implies that - // (a) it will _never_ have any free type inference variables as further constraints are added to the system. - // (b) its set of FreeTycons will not change as further constraints are added to the system - let mutable willNeverHaveFreeTypars = false - - // If WillNeverHaveFreeTypars then we can cache the computation of FreeTycons, since they are invariant. - let mutable cachedFreeLocalTycons = emptyFreeTycons - - // If WillNeverHaveFreeTypars then we can cache the computation of FreeTraitSolutions, since they are invariant. - let mutable cachedFreeTraitSolutions = emptyFreeLocals - - member item.GetFreeTyvars() = - let fvs = computeFreeTyvars() - if fvs.FreeTypars.IsEmpty then - willNeverHaveFreeTypars <- true - cachedFreeLocalTycons <- fvs.FreeTycons - cachedFreeTraitSolutions <- fvs.FreeTraitSolutions - fvs - - member item.WillNeverHaveFreeTypars = willNeverHaveFreeTypars - - member item.CachedFreeLocalTycons = cachedFreeLocalTycons - - member item.CachedFreeTraitSolutions = cachedFreeTraitSolutions - -/// Represents the type environment at a particular scope. Includes the name -/// resolution environment, the ungeneralizable items from earlier in the scope -/// and other information about the scope. -[] -type TcEnv = - { /// Name resolution information - eNameResEnv: NameResolutionEnv - - /// The list of items in the environment that may contain free inference - /// variables (which may not be generalized). The relevant types may - /// change as a result of inference equations being asserted, hence may need to - /// be recomputed. - eUngeneralizableItems: UngeneralizableItem list - - // Two (!) versions of the current module path - // These are used to: - // - Look up the appropriate point in the corresponding signature - // see if an item is public or not - // - Change fslib canonical module type to allow compiler references to these items - // - Record the cpath for concrete modul_specs, tycon_specs and excon_specs so they can cache their generated IL representation where necessary - // - Record the pubpath of public, concrete {val, tycon, modul, excon}_specs. - // This information is used mainly when building non-local references - // to public items. - // - // Of the two, 'ePath' is the one that's barely used. It's only - // used by UpdateAccModuleOrNamespaceType to modify the CCU while compiling FSharp.Core - ePath: Ident list - - eCompPath: CompilationPath - - eAccessPath: CompilationPath - - /// This field is computed from other fields, but we amortize the cost of computing it. - eAccessRights: AccessorDomain - - /// Internals under these should be accessible - eInternalsVisibleCompPaths: CompilationPath list - - /// Mutable accumulator for the current module type - eModuleOrNamespaceTypeAccumulator: ModuleOrNamespaceType ref - - /// Context information for type checker - eContextInfo: ContextInfo - - /// Here Some tcref indicates we can access protected members in all super types - eFamilyType: TyconRef option - - // Information to enforce special restrictions on valid expressions - // for .NET constructors. - eCtorInfo: CtorInfo option - - eCallerMemberName: string option - } - - member tenv.DisplayEnv = tenv.eNameResEnv.DisplayEnv - - member tenv.NameEnv = tenv.eNameResEnv - - member tenv.AccessRights = tenv.eAccessRights - - override tenv.ToString() = "TcEnv(...)" - -/// Compute the value of this computed, cached field -let computeAccessRights eAccessPath eInternalsVisibleCompPaths eFamilyType = - AccessibleFrom (eAccessPath :: eInternalsVisibleCompPaths, eFamilyType) // env.eAccessRights - -let emptyTcEnv g = - let cpath = compPathInternal // allow internal access initially - { eNameResEnv = NameResolutionEnv.Empty g - eUngeneralizableItems = [] - ePath = [] - eCompPath = cpath // dummy - eAccessPath = cpath // dummy - eAccessRights = computeAccessRights cpath [] None // compute this field - eInternalsVisibleCompPaths = [] - eContextInfo = ContextInfo.NoContext - eModuleOrNamespaceTypeAccumulator = ref (NewEmptyModuleOrNamespaceType Namespace) - eFamilyType = None - eCtorInfo = None - eCallerMemberName = None } - -//------------------------------------------------------------------------- -// Helpers related to determining if we're in a constructor and/or a class -// that may be able to access "protected" members. -//------------------------------------------------------------------------- - -let InitialExplicitCtorInfo (safeThisValOpt, safeInitInfo) = - { ctorShapeCounter = 3 - safeThisValOpt = safeThisValOpt - safeInitInfo = safeInitInfo - ctorIsImplicit = false} - -let InitialImplicitCtorInfo () = - { ctorShapeCounter = 0 - safeThisValOpt = None - safeInitInfo = NoSafeInitInfo - ctorIsImplicit = true } - -let EnterFamilyRegion tcref env = - let eFamilyType = Some tcref - { env with - eAccessRights = computeAccessRights env.eAccessPath env.eInternalsVisibleCompPaths eFamilyType // update this computed field - eFamilyType = eFamilyType } - -let ExitFamilyRegion env = - let eFamilyType = None - match env.eFamilyType with - | None -> env // optimization to avoid reallocation - | _ -> - { env with - eAccessRights = computeAccessRights env.eAccessPath env.eInternalsVisibleCompPaths eFamilyType // update this computed field - eFamilyType = eFamilyType } - -let AreWithinCtorShape env = match env.eCtorInfo with None -> false | Some ctorInfo -> ctorInfo.ctorShapeCounter > 0 -let AreWithinImplicitCtor env = match env.eCtorInfo with None -> false | Some ctorInfo -> ctorInfo.ctorIsImplicit -let GetCtorShapeCounter env = match env.eCtorInfo with None -> 0 | Some ctorInfo -> ctorInfo.ctorShapeCounter -let GetRecdInfo env = match env.eCtorInfo with None -> RecdExpr | Some ctorInfo -> if ctorInfo.ctorShapeCounter = 1 then RecdExprIsObjInit else RecdExpr - -let AdjustCtorShapeCounter f env = {env with eCtorInfo = Option.map (fun ctorInfo -> { ctorInfo with ctorShapeCounter = f ctorInfo.ctorShapeCounter }) env.eCtorInfo } -let ExitCtorShapeRegion env = AdjustCtorShapeCounter (fun _ -> 0) env - -/// Add a type to the TcEnv, i.e. register it as ungeneralizable. -let addFreeItemOfTy ty eUngeneralizableItems = - let fvs = freeInType CollectAllNoCaching ty - if isEmptyFreeTyvars fvs then eUngeneralizableItems - else UngeneralizableItem(fun () -> freeInType CollectAllNoCaching ty) :: eUngeneralizableItems - -/// Add the contents of a module type to the TcEnv, i.e. register the contents as ungeneralizable. -/// Add a module type to the TcEnv, i.e. register it as ungeneralizable. -let addFreeItemOfModuleTy mtyp eUngeneralizableItems = - let fvs = freeInModuleTy mtyp - if isEmptyFreeTyvars fvs then eUngeneralizableItems - else UngeneralizableItem(fun () -> freeInModuleTy mtyp) :: eUngeneralizableItems - -/// Add a table of values to the name resolution environment. -let AddValMapToNameEnv vs nenv = - NameMap.foldBackRange (fun v nenv -> AddValRefToNameEnv nenv (mkLocalValRef v)) vs nenv - -/// Add a list of values to the name resolution environment. -let AddValListToNameEnv vs nenv = - List.foldBack (fun v nenv -> AddValRefToNameEnv nenv (mkLocalValRef v)) vs nenv - -/// Adjust the TcEnv to make more things 'InternalsVisibleTo' -let addInternalsAccessibility env (ccu: CcuThunk) = - let compPath = CompPath (ccu.ILScopeRef, []) - let eInternalsVisibleCompPaths = compPath :: env.eInternalsVisibleCompPaths - { env with - eAccessRights = computeAccessRights env.eAccessPath eInternalsVisibleCompPaths env.eFamilyType // update this computed field - eInternalsVisibleCompPaths = compPath :: env.eInternalsVisibleCompPaths } - -/// Add a local value to TcEnv -let AddLocalValPrimitive (v: Val) env = - { env with - eNameResEnv = AddValRefToNameEnv env.eNameResEnv (mkLocalValRef v) - eUngeneralizableItems = addFreeItemOfTy v.Type env.eUngeneralizableItems } - -/// Add a table of local values to TcEnv -let AddLocalValMap tcSink scopem (vals: Val NameMap) env = - let env = - if vals.IsEmpty then - env - else - { env with - eNameResEnv = AddValMapToNameEnv vals env.eNameResEnv - eUngeneralizableItems = NameMap.foldBackRange (typeOfVal >> addFreeItemOfTy) vals env.eUngeneralizableItems } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add a list of local values to TcEnv and report them to the sink -let AddLocalVals tcSink scopem (vals: Val list) env = - let env = - if isNil vals then - env - else - { env with - eNameResEnv = AddValListToNameEnv vals env.eNameResEnv - eUngeneralizableItems = List.foldBack (typeOfVal >> addFreeItemOfTy) vals env.eUngeneralizableItems } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add a local value to TcEnv and report it to the sink -let AddLocalVal tcSink scopem v env = - let env = { env with - eNameResEnv = AddValRefToNameEnv env.eNameResEnv (mkLocalValRef v) - eUngeneralizableItems = addFreeItemOfTy v.Type env.eUngeneralizableItems } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add an exception definition to TcEnv and report it to the sink -let AddLocalExnDefnAndReport tcSink scopem env (exnc: Tycon) = - let env = { env with eNameResEnv = AddExceptionDeclsToNameEnv BulkAdd.No env.eNameResEnv (mkLocalEntityRef exnc) } - // Also make VisualStudio think there is an identifier in scope at the range of the identifier text of its binding location - CallEnvSink tcSink (exnc.Range, env.NameEnv, env.eAccessRights) - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add a list of type definitions to TcEnv -let AddLocalTyconRefs ownDefinition g amap m tcrefs env = - if isNil tcrefs then env else - { env with eNameResEnv = AddTyconRefsToNameEnv BulkAdd.No ownDefinition g amap env.eAccessRights m false env.eNameResEnv tcrefs } - -/// Add a list of type definitions to TcEnv -let AddLocalTycons g amap m (tycons: Tycon list) env = - if isNil tycons then env else - env |> AddLocalTyconRefs false g amap m (List.map mkLocalTyconRef tycons) - -/// Add a list of type definitions to TcEnv and report them to the sink -let AddLocalTyconsAndReport tcSink scopem g amap m tycons env = - let env = AddLocalTycons g amap m tycons env - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Adjust the TcEnv to account for opening the set of modules, namespaces or static classes implied by an `open` declaration -let OpenEntities tcSink g amap scopem root env mvvs openDeclaration = - let env = - if isNil mvvs then env else - { env with eNameResEnv = AddEntitiesContentsToNameEnv g amap env.eAccessRights scopem root env.eNameResEnv mvvs } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - CallOpenDeclarationSink tcSink openDeclaration - env - -/// Adjust the TcEnv to account for a new root Ccu being available, e.g. a referenced assembly -let AddRootModuleOrNamespaceRefs g amap m env modrefs = - if isNil modrefs then env else - { env with eNameResEnv = AddModuleOrNamespaceRefsToNameEnv g amap m true env.eAccessRights env.eNameResEnv modrefs } - -/// Adjust the TcEnv to account for a new referenced assembly -let AddNonLocalCcu g amap scopem env assemblyName (ccu: CcuThunk, internalsVisibleToAttributes) = - - let internalsVisible = - internalsVisibleToAttributes - |> List.exists (fun visibleTo -> - try - System.Reflection.AssemblyName(visibleTo).Name = assemblyName - with e -> - warning(InvalidInternalsVisibleToAssemblyName(visibleTo, ccu.FileName)) - false) - - let env = if internalsVisible then addInternalsAccessibility env ccu else env - - // Compute the top-rooted module or namespace references - let modrefs = ccu.RootModulesAndNamespaces |> List.map (mkNonLocalCcuRootEntityRef ccu) - - // Compute the top-rooted type definitions - let tcrefs = ccu.RootTypeAndExceptionDefinitions |> List.map (mkNonLocalCcuRootEntityRef ccu) - let env = AddRootModuleOrNamespaceRefs g amap scopem env modrefs - let env = - if isNil tcrefs then env else - { env with eNameResEnv = AddTyconRefsToNameEnv BulkAdd.Yes false g amap env.eAccessRights scopem true env.eNameResEnv tcrefs } - env - -/// Adjust the TcEnv to account for a fully processed "namespace" declaration in this file -let AddLocalRootModuleOrNamespace tcSink g amap scopem env (mtyp: ModuleOrNamespaceType) = - // Compute the top-rooted module or namespace references - let modrefs = mtyp.ModuleAndNamespaceDefinitions |> List.map mkLocalModRef - // Compute the top-rooted type definitions - let tcrefs = mtyp.TypeAndExceptionDefinitions |> List.map mkLocalTyconRef - let env = AddRootModuleOrNamespaceRefs g amap scopem env modrefs - let env = { env with - eNameResEnv = if isNil tcrefs then env.eNameResEnv else AddTyconRefsToNameEnv BulkAdd.No false g amap env.eAccessRights scopem true env.eNameResEnv tcrefs - eUngeneralizableItems = addFreeItemOfModuleTy mtyp env.eUngeneralizableItems } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add a "module X = Y" local module abbreviation to the TcEnv -let AddModuleAbbreviationAndReport tcSink scopem id modrefs env = - let env = - if isNil modrefs then env else - { env with eNameResEnv = AddModuleAbbrevToNameEnv id env.eNameResEnv modrefs } - - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - let item = Item.ModuleOrNamespaces modrefs - CallNameResolutionSink tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - env - -/// Add a "module X = ..." definition to the TcEnv -let AddLocalSubModule g amap m env (modul: ModuleOrNamespace) = - let env = { env with - eNameResEnv = AddModuleOrNamespaceRefToNameEnv g amap m false env.eAccessRights env.eNameResEnv (mkLocalModRef modul) - eUngeneralizableItems = addFreeItemOfModuleTy modul.ModuleOrNamespaceType env.eUngeneralizableItems } - env - -/// Add a "module X = ..." definition to the TcEnv and report it to the sink -let AddLocalSubModuleAndReport tcSink scopem g amap m env (modul: ModuleOrNamespace) = - let env = AddLocalSubModule g amap m env modul - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - env - -/// Add a set of explicitly declared type parameters as being available in the TcEnv -let AddDeclaredTypars check typars env = - if isNil typars then env else - let env = { env with eNameResEnv = AddDeclaredTyparsToNameEnv check env.eNameResEnv typars } - { env with eUngeneralizableItems = List.foldBack (mkTyparTy >> addFreeItemOfTy) typars env.eUngeneralizableItems } - -/// Represents the compilation environment for typechecking a single file in an assembly. -[] -type cenv = - { g: TcGlobals - - /// Push an entry every time a recursive value binding is used, - /// in order to be able to fix up recursive type applications as - /// we infer type parameters - mutable recUses: ValMultiMap<(Expr ref * range * bool)> - - /// Checks to run after all inference is complete. - mutable postInferenceChecks: ResizeArray unit> - - /// Set to true if this file causes the creation of generated provided types. - mutable createsGeneratedProvidedTypes: bool - - /// Are we in a script? if so relax the reporting of discarded-expression warnings at the top level - isScript: bool - - /// Environment needed to convert IL types to F# types in the importer. - amap: Import.ImportMap - - /// Used to generate new syntactic argument names in post-parse syntactic processing - synArgNameGenerator: SynArgNameGenerator - - tcSink: TcResultsSink - - /// Holds a reference to the component being compiled. - /// This field is very rarely used (mainly when fixing up forward references to fslib. - topCcu: CcuThunk - - /// Holds the current inference constraints - css: ConstraintSolverState - - /// Are we compiling the signature of a module from fslib? - compilingCanonicalFslibModuleType: bool - - /// Is this a .fsi file? - isSig: bool - - /// Does this .fs file have a .fsi file? - haveSig: bool - - /// Used to generate names - niceNameGen: NiceNameGenerator - - /// Used to read and cache information about types and members - infoReader: InfoReader - - /// Used to resolve names - nameResolver: NameResolver - - /// The set of active conditional defines. The value is None when conditional erasure is disabled in tooling. - conditionalDefines: string list option - - isInternalTestSpanStackReferring: bool - } - - /// Create a new compilation environment - static member Create (g, isScript, niceNameGen, amap, topCcu, isSig, haveSig, conditionalDefines, tcSink, tcVal, isInternalTestSpanStackReferring) = - let infoReader = new InfoReader(g, amap) - let instantiationGenerator m tpsorig = ConstraintSolver.FreshenTypars m tpsorig - let nameResolver = new NameResolver(g, amap, infoReader, instantiationGenerator) - { g = g - amap = amap - recUses = ValMultiMap<_>.Empty - postInferenceChecks = ResizeArray() - createsGeneratedProvidedTypes = false - topCcu = topCcu - isScript = isScript - css = ConstraintSolverState.New(g, amap, infoReader, tcVal) - infoReader = infoReader - tcSink = tcSink - nameResolver = nameResolver - niceNameGen = niceNameGen - synArgNameGenerator = SynArgNameGenerator() - isSig = isSig - haveSig = haveSig - compilingCanonicalFslibModuleType = (isSig || not haveSig) && g.compilingFslib - conditionalDefines = conditionalDefines - isInternalTestSpanStackReferring = isInternalTestSpanStackReferring } - - override __.ToString() = "" - -let CopyAndFixupTypars m rigid tpsorig = - ConstraintSolver.FreshenAndFixupTypars m rigid [] [] tpsorig - -let UnifyTypes cenv (env: TcEnv) m actualTy expectedTy = - ConstraintSolver.AddCxTypeEqualsType env.eContextInfo env.DisplayEnv cenv.css m (tryNormalizeMeasureInType cenv.g actualTy) (tryNormalizeMeasureInType cenv.g expectedTy) - -/// Make the initial type checking environment for a single file with an empty accumulator for the overall contents for the file -let MakeInitialEnv env = - // Note: here we allocate a new module type accumulator - let mtypeAcc = ref (NewEmptyModuleOrNamespaceType Namespace) - { env with eModuleOrNamespaceTypeAccumulator = mtypeAcc }, mtypeAcc - -/// Make an environment suitable for a module or namespace. Does not create a new accumulator but uses one we already have/ -let MakeInnerEnvWithAcc env nm mtypeAcc modKind = - let path = env.ePath @ [nm] - let cpath = env.eCompPath.NestedCompPath nm.idText modKind - { env with - ePath = path - eCompPath = cpath - eAccessPath = cpath - eAccessRights = computeAccessRights cpath env.eInternalsVisibleCompPaths env.eFamilyType // update this computed field - eNameResEnv = { env.eNameResEnv with eDisplayEnv = env.DisplayEnv.AddOpenPath (pathOfLid path) } - eModuleOrNamespaceTypeAccumulator = mtypeAcc } - -/// Make an environment suitable for a module or namespace, creating a new accumulator. -let MakeInnerEnv env nm modKind = - // Note: here we allocate a new module type accumulator - let mtypeAcc = ref (NewEmptyModuleOrNamespaceType modKind) - MakeInnerEnvWithAcc env nm mtypeAcc modKind, mtypeAcc - -/// Make an environment suitable for processing inside a type definition -let MakeInnerEnvForTyconRef env tcref isExtrinsicExtension = - if isExtrinsicExtension then - // Extension members don't get access to protected stuff - env - else - // Regular members get access to protected stuff - let env = EnterFamilyRegion tcref env - // Note: assumes no nesting - let eAccessPath = env.eCompPath.NestedCompPath tcref.LogicalName ModuleOrType - { env with - eAccessRights = computeAccessRights eAccessPath env.eInternalsVisibleCompPaths env.eFamilyType // update this computed field - eAccessPath = eAccessPath } - -/// Make an environment suitable for processing inside a member definition -let MakeInnerEnvForMember env (v: Val) = - match v.MemberInfo with - | None -> env - | Some _ -> MakeInnerEnvForTyconRef env v.MemberApparentEntity v.IsExtensionMember - -/// Get the current accumulator for the namespace/module we're in -let GetCurrAccumulatedModuleOrNamespaceType env = !(env.eModuleOrNamespaceTypeAccumulator) - -/// Set the current accumulator for the namespace/module we're in, updating the inferred contents -let SetCurrAccumulatedModuleOrNamespaceType env x = env.eModuleOrNamespaceTypeAccumulator := x - -/// Set up the initial environment accounting for the enclosing "namespace X.Y.Z" definition -let LocateEnv ccu env enclosingNamespacePath = - let cpath = compPathOfCcu ccu - let env = - {env with - ePath = [] - eCompPath = cpath - eAccessPath = cpath - // update this computed field - eAccessRights = computeAccessRights cpath env.eInternalsVisibleCompPaths env.eFamilyType } - let env = List.fold (fun env id -> MakeInnerEnv env id Namespace |> fst) env enclosingNamespacePath - env - -/// Given an inferred module type, place that inside a namespace path implied by a "namespace X.Y.Z" definition -let BuildRootModuleType enclosingNamespacePath (cpath: CompilationPath) mtyp = - (enclosingNamespacePath, (cpath, (mtyp, []))) - ||> List.foldBack (fun id (cpath, (mtyp, mspecs)) -> - let a, b = wrapModuleOrNamespaceTypeInNamespace id cpath.ParentCompPath mtyp - cpath.ParentCompPath, (a, b :: mspecs)) - |> fun (_, (mtyp, mspecs)) -> mtyp, List.rev mspecs - -/// Given a resulting module expression, place that inside a namespace path implied by a "namespace X.Y.Z" definition -let BuildRootModuleExpr enclosingNamespacePath (cpath: CompilationPath) mexpr = - (enclosingNamespacePath, (cpath, mexpr)) - ||> List.foldBack (fun id (cpath, mexpr) -> (cpath.ParentCompPath, wrapModuleOrNamespaceExprInNamespace id cpath.ParentCompPath mexpr)) - |> snd - -/// Try to take the "FSINNN" prefix off a namespace path -let TryStripPrefixPath (g: TcGlobals) (enclosingNamespacePath: Ident list) = - match enclosingNamespacePath with - | p :: rest when - g.isInteractive && - not (isNil rest) && - p.idText.StartsWithOrdinal FsiDynamicModulePrefix && - p.idText.[FsiDynamicModulePrefix.Length..] |> String.forall System.Char.IsDigit - -> Some(p, rest) - | _ -> None - -/// Inside "namespace X.Y.Z" there is an implicit open of "X.Y.Z" -let ImplicitlyOpenOwnNamespace tcSink g amap scopem enclosingNamespacePath env = - if isNil enclosingNamespacePath then - env - else - // For F# interactive, skip "FSI_0002" prefixes when determining the path to open implicitly - let enclosingNamespacePathToOpen = - match TryStripPrefixPath g enclosingNamespacePath with - | Some(_, rest) -> rest - | None -> enclosingNamespacePath - - match enclosingNamespacePathToOpen with - | id :: rest -> - let ad = env.eAccessRights - match ResolveLongIndentAsModuleOrNamespaceOrStaticClass tcSink ResultCollectionSettings.AllResults amap scopem true true OpenQualified env.eNameResEnv ad id rest true with - | Result modrefs -> - let modrefs = List.map p23 modrefs - let openDecl = OpenDeclaration.Create (enclosingNamespacePathToOpen, modrefs, scopem, true) - OpenEntities tcSink g amap scopem false env modrefs openDecl - | Exception _ -> env - | _ -> env - - -//------------------------------------------------------------------------- -// Helpers for unification -//------------------------------------------------------------------------- - -/// When the context is matching the oldRange then this function shrinks it to newRange. -/// This can be used to change context over no-op expressions like parens. -let ShrinkContext env oldRange newRange = - match env.eContextInfo with - | ContextInfo.NoContext - | ContextInfo.RecordFields - | ContextInfo.TupleInRecordFields - | ContextInfo.ReturnInComputationExpression - | ContextInfo.YieldInComputationExpression - | ContextInfo.RuntimeTypeTest _ - | ContextInfo.DowncastUsedInsteadOfUpcast _ - | ContextInfo.SequenceExpression _ -> - env - | ContextInfo.CollectionElement (b,m) -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.CollectionElement(b,newRange) } - | ContextInfo.FollowingPatternMatchClause m -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.FollowingPatternMatchClause newRange } - | ContextInfo.PatternMatchGuard m -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.PatternMatchGuard newRange } - | ContextInfo.IfExpression m -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.IfExpression newRange } - | ContextInfo.OmittedElseBranch m -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.OmittedElseBranch newRange } - | ContextInfo.ElseBranchResult m -> - if not (Range.equals m oldRange) then env else - { env with eContextInfo = ContextInfo.ElseBranchResult newRange } - -/// Optimized unification routine that avoids creating new inference -/// variables unnecessarily -let UnifyRefTupleType contextInfo cenv denv m ty ps = - let ptys = - if isRefTupleTy cenv.g ty then - let ptys = destRefTupleTy cenv.g ty - if List.length ps = List.length ptys then ptys - else NewInferenceTypes ps - else NewInferenceTypes ps - - let contextInfo = - match contextInfo with - | ContextInfo.RecordFields -> ContextInfo.TupleInRecordFields - | _ -> contextInfo - - AddCxTypeEqualsType contextInfo denv cenv.css m ty (TType_tuple (tupInfoRef, ptys)) - ptys - -/// Allow the inference of structness from the known type, e.g. -/// let (x: struct (int * int)) = (3,4) -let UnifyTupleTypeAndInferCharacteristics contextInfo cenv denv m knownTy isExplicitStruct ps = - let tupInfo, ptys = - if isAnyTupleTy cenv.g knownTy then - let tupInfo, ptys = destAnyTupleTy cenv.g knownTy - let tupInfo = (if isExplicitStruct then tupInfoStruct else tupInfo) - let ptys = - if List.length ps = List.length ptys then ptys - else NewInferenceTypes ps - tupInfo, ptys - else - mkTupInfo isExplicitStruct, NewInferenceTypes ps - - let contextInfo = - match contextInfo with - | ContextInfo.RecordFields -> ContextInfo.TupleInRecordFields - | _ -> contextInfo - - let ty2 = TType_tuple (tupInfo, ptys) - AddCxTypeEqualsType contextInfo denv cenv.css m knownTy ty2 - tupInfo, ptys - -// Allow inference of assembly-affinity and structness from the known type - even from another assembly. This is a rule of -// the language design and allows effective cross-assembly use of anonymous types in some limited circumstances. -let UnifyAnonRecdTypeAndInferCharacteristics contextInfo cenv denv m ty isExplicitStruct unsortedNames = - let anonInfo, ptys = - match tryDestAnonRecdTy cenv.g ty with - | ValueSome (anonInfo, ptys) -> - // Note: use the assembly of the known type, not the current assembly - // Note: use the structness of the known type, unless explicit - // Note: use the names of our type, since they are always explicit - let tupInfo = (if isExplicitStruct then tupInfoStruct else anonInfo.TupInfo) - let anonInfo = AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo, unsortedNames) - let ptys = - if List.length ptys = Array.length unsortedNames then ptys - else NewInferenceTypes (Array.toList anonInfo.SortedNames) - anonInfo, ptys - | ValueNone -> - // Note: no known anonymous record type - use our assembly - let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, mkTupInfo isExplicitStruct, unsortedNames) - anonInfo, NewInferenceTypes (Array.toList anonInfo.SortedNames) - let ty2 = TType_anon (anonInfo, ptys) - AddCxTypeEqualsType contextInfo denv cenv.css m ty ty2 - anonInfo, ptys - - -/// Optimized unification routine that avoids creating new inference -/// variables unnecessarily -let UnifyFunctionTypeUndoIfFailed cenv denv m ty = - match tryDestFunTy cenv.g ty with - | ValueNone -> - let domainTy = NewInferenceType () - let resultTy = NewInferenceType () - if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty (domainTy --> resultTy) then - ValueSome(domainTy, resultTy) - else - ValueNone - | r -> r - -/// Optimized unification routine that avoids creating new inference -/// variables unnecessarily -let UnifyFunctionType extraInfo cenv denv mFunExpr ty = - match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr ty with - | ValueSome res -> res - | ValueNone -> - match extraInfo with - | Some argm -> error (NotAFunction(denv, ty, mFunExpr, argm)) - | None -> error (FunctionExpected(denv, ty, mFunExpr)) - -let ReportImplicitlyIgnoredBoolExpression denv m ty expr = - let checkExpr m expr = - match expr with - | Expr.App (Expr.Val (vf, _, _), _, _, exprs, _) when vf.LogicalName = opNameEquals -> - match exprs with - | Expr.App (Expr.Val (propRef, _, _), _, _, Expr.Val (vf, _, _) :: _, _) :: _ -> - if propRef.IsPropertyGetterMethod then - let propertyName = propRef.PropertyName - let hasCorrespondingSetter = - match propRef.DeclaringEntity with - | Parent entityRef -> - entityRef.MembersOfFSharpTyconSorted - |> List.exists (fun valRef -> valRef.IsPropertySetterMethod && valRef.PropertyName = propertyName) - | _ -> false - - if hasCorrespondingSetter then - UnitTypeExpectedWithPossiblePropertySetter (denv, ty, vf.DisplayName, propertyName, m) - else - UnitTypeExpectedWithEquality (denv, ty, m) - else - UnitTypeExpectedWithEquality (denv, ty, m) - | Expr.Op (TOp.ILCall (_, _, _, _, _, _, _, methodRef, _, _, _), _, Expr.Val (vf, _, _) :: _, _) :: _ when methodRef.Name.StartsWithOrdinal("get_") -> - UnitTypeExpectedWithPossiblePropertySetter (denv, ty, vf.DisplayName, PrettyNaming.ChopPropertyName(methodRef.Name), m) - | Expr.Val (vf, _, _) :: _ -> - UnitTypeExpectedWithPossibleAssignment (denv, ty, vf.IsMutable, vf.DisplayName, m) - | _ -> UnitTypeExpectedWithEquality (denv, ty, m) - | _ -> UnitTypeExpected (denv, ty, m) - - match expr with - | Expr.Let (_, Expr.Sequential (_, inner, _, _, _), _, _) - | Expr.Sequential (_, inner, _, _, _) -> - let rec extractNext expr = - match expr with - | Expr.Sequential (_, inner, _, _, _) -> extractNext inner - | _ -> checkExpr expr.Range expr - extractNext inner - | expr -> checkExpr m expr - -let UnifyUnitType cenv (env: TcEnv) m ty expr = - let denv = env.DisplayEnv - if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty cenv.g.unit_ty then - true - else - let domainTy = NewInferenceType () - let resultTy = NewInferenceType () - if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty (domainTy --> resultTy) then - warning (FunctionValueUnexpected(denv, ty, m)) - else - let reportImplicitlyDiscardError() = - if typeEquiv cenv.g cenv.g.bool_ty ty then - warning (ReportImplicitlyIgnoredBoolExpression denv m ty expr) - else - warning (UnitTypeExpected (denv, ty, m)) - - match env.eContextInfo with - | ContextInfo.SequenceExpression seqTy -> - let lifted = mkSeqTy cenv.g ty - if typeEquiv cenv.g seqTy lifted then - warning (Error (FSComp.SR.implicitlyDiscardedInSequenceExpression(NicePrint.prettyStringOfTy denv ty), m)) - else - if isListTy cenv.g ty || isArrayTy cenv.g ty || typeEquiv cenv.g seqTy ty then - warning (Error (FSComp.SR.implicitlyDiscardedSequenceInSequenceExpression(NicePrint.prettyStringOfTy denv ty), m)) - else - reportImplicitlyDiscardError() - | _ -> - reportImplicitlyDiscardError() - - false - -let TryUnifyUnitTypeWithoutWarning cenv (env:TcEnv) m ty = - let denv = env.DisplayEnv - AddCxTypeEqualsTypeUndoIfFailedOrWarnings denv cenv.css m ty cenv.g.unit_ty - -// Logically extends System.AttributeTargets -module AttributeTargets = - let FieldDecl = AttributeTargets.Field ||| AttributeTargets.Property - let FieldDeclRestricted = AttributeTargets.Field - let UnionCaseDecl = AttributeTargets.Method ||| AttributeTargets.Property - let TyconDecl = AttributeTargets.Class ||| AttributeTargets.Interface ||| AttributeTargets.Delegate ||| AttributeTargets.Struct ||| AttributeTargets.Enum - let ExnDecl = AttributeTargets.Class - let ModuleDecl = AttributeTargets.Class - let Top = AttributeTargets.Assembly ||| AttributeTargets.Module ||| AttributeTargets.Method - -let ForNewConstructors tcSink (env: TcEnv) mObjTy methodName meths = - let origItem = Item.CtorGroup(methodName, meths) - let callSink (item, minst) = CallNameResolutionSink tcSink (mObjTy, env.NameEnv, item, origItem, minst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - let sendToSink minst refinedMeths = callSink (Item.CtorGroup(methodName, refinedMeths), minst) - match meths with - | [] -> - AfterResolution.DoNothing - | [_] -> - sendToSink emptyTyparInst meths - AfterResolution.DoNothing - | _ -> - AfterResolution.RecordResolution (None, (fun tpinst -> callSink (origItem, tpinst)), (fun (minfo, _, minst) -> sendToSink minst [minfo]), (fun () -> callSink (origItem, emptyTyparInst))) - - -/// Typecheck rational constant terms in units-of-measure exponents -let rec TcSynRationalConst c = - match c with - | SynRationalConst.Integer i -> intToRational i - | SynRationalConst.Negate c' -> NegRational (TcSynRationalConst c') - | SynRationalConst.Rational(p, q, _) -> DivRational (intToRational p) (intToRational q) - -/// Typecheck constant terms in expressions and patterns -let TcConst cenv ty m env c = - let rec tcMeasure ms = - match ms with - | SynMeasure.One -> Measure.One - | SynMeasure.Named(tc, m) -> - let ad = env.eAccessRights - let tcref = ForceRaise(ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Use OpenQualified env.eNameResEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No) - match tcref.TypeOrMeasureKind with - | TyparKind.Type -> error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) - | TyparKind.Measure -> Measure.Con tcref - - | SynMeasure.Power(ms, exponent, _) -> Measure.RationalPower (tcMeasure ms, TcSynRationalConst exponent) - | SynMeasure.Product(ms1, ms2, _) -> Measure.Prod(tcMeasure ms1, tcMeasure ms2) - | SynMeasure.Divide(ms1, ((SynMeasure.Seq (_ :: (_ :: _), _)) as ms2), m) -> - warning(Error(FSComp.SR.tcImplicitMeasureFollowingSlash(), m)) - Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2)) - | SynMeasure.Divide(ms1, ms2, _) -> - Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2)) - | SynMeasure.Seq(mss, _) -> ProdMeasures (List.map tcMeasure mss) - | SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), m)) - | SynMeasure.Var(_, m) -> error(Error(FSComp.SR.tcNonZeroConstantCannotHaveGenericUnit(), m)) - - let unif expected = UnifyTypes cenv env m ty expected - - let unifyMeasureArg iszero tcr c = - let measureTy = - match c with - | SynConst.Measure(_, SynMeasure.Anon _) -> - (mkAppTy tcr [TType_measure (Measure.Var (NewAnonTypar (TyparKind.Measure, m, TyparRigidity.Anon, (if iszero then NoStaticReq else HeadTypeStaticReq), TyparDynamicReq.No)))]) - - | SynConst.Measure(_, ms) -> mkAppTy tcr [TType_measure (tcMeasure ms)] - | _ -> mkAppTy tcr [TType_measure Measure.One] - unif measureTy - - match c with - | SynConst.Unit -> unif cenv.g.unit_ty; Const.Unit - | SynConst.Bool i -> unif cenv.g.bool_ty; Const.Bool i - | SynConst.SByte i -> unif cenv.g.sbyte_ty; Const.SByte i - | SynConst.Int16 i -> unif cenv.g.int16_ty; Const.Int16 i - | SynConst.Int32 i -> unif cenv.g.int_ty; Const.Int32 i - | SynConst.Int64 i -> unif cenv.g.int64_ty; Const.Int64 i - | SynConst.IntPtr i -> unif cenv.g.nativeint_ty; Const.IntPtr i - | SynConst.Byte i -> unif cenv.g.byte_ty; Const.Byte i - | SynConst.UInt16 i -> unif cenv.g.uint16_ty; Const.UInt16 i - | SynConst.UInt32 i -> unif cenv.g.uint32_ty; Const.UInt32 i - | SynConst.UInt64 i -> unif cenv.g.uint64_ty; Const.UInt64 i - | SynConst.UIntPtr i -> unif cenv.g.unativeint_ty; Const.UIntPtr i - | SynConst.Measure(SynConst.Single f, _) | SynConst.Single f -> unifyMeasureArg (f=0.0f) cenv.g.pfloat32_tcr c; Const.Single f - | SynConst.Measure(SynConst.Double f, _) | SynConst.Double f -> unifyMeasureArg (f=0.0) cenv.g.pfloat_tcr c; Const.Double f - | SynConst.Measure(SynConst.Decimal s, _) | SynConst.Decimal s -> unifyMeasureArg false cenv.g.pdecimal_tcr c; Const.Decimal s - | SynConst.Measure(SynConst.SByte i, _) | SynConst.SByte i -> unifyMeasureArg (i=0y) cenv.g.pint8_tcr c; Const.SByte i - | SynConst.Measure(SynConst.Int16 i, _) | SynConst.Int16 i -> unifyMeasureArg (i=0s) cenv.g.pint16_tcr c; Const.Int16 i - | SynConst.Measure(SynConst.Int32 i, _) | SynConst.Int32 i -> unifyMeasureArg (i=0) cenv.g.pint_tcr c; Const.Int32 i - | SynConst.Measure(SynConst.Int64 i, _) | SynConst.Int64 i -> unifyMeasureArg (i=0L) cenv.g.pint64_tcr c; Const.Int64 i - | SynConst.Char c -> unif cenv.g.char_ty; Const.Char c - | SynConst.String (s, _) -> unif cenv.g.string_ty; Const.String s - | SynConst.UserNum _ -> error (InternalError(FSComp.SR.tcUnexpectedBigRationalConstant(), m)) - | SynConst.Measure _ -> error (Error(FSComp.SR.tcInvalidTypeForUnitsOfMeasure(), m)) - - | SynConst.UInt16s _ -> error (InternalError(FSComp.SR.tcUnexpectedConstUint16Array(), m)) - | SynConst.Bytes _ -> error (InternalError(FSComp.SR.tcUnexpectedConstByteArray(), m)) - -/// Convert an Abstract IL ILFieldInit value read from .NET metadata to a TAST constant -let TcFieldInit (_m: range) lit = PatternMatchCompilation.ilFieldToTastConst lit - -//------------------------------------------------------------------------- -// Arities. These serve two roles in the system: -// 1. syntactic arities come from the syntactic forms found -// signature files and the syntactic forms of function and member definitions. -// 2. compiled arities representing representation choices w.r.t. internal representations of -// functions and members. -//------------------------------------------------------------------------- - -// Adjust the arities that came from the parsing of the toptyp (arities) to be a valSynData. -// This means replacing the "[unitArg]" arising from a "unit -> ty" with a "[]". -let AdjustValSynInfoInSignature g ty (SynValInfo(argsData, retData) as sigMD) = - if argsData.Length = 1 && argsData.Head.Length = 1 && isFunTy g ty && typeEquiv g g.unit_ty (domainOfFunTy g ty) then - SynValInfo(argsData.Head.Tail :: argsData.Tail, retData) - else - sigMD - -/// The ValReprInfo for a value, except the number of typars is not yet inferred -type PartialValReprInfo = PartialValReprInfo of ArgReprInfo list list * ArgReprInfo - -let TranslateTopArgSynInfo isArg m tcAttributes (SynArgInfo(Attributes attrs, isOpt, nm)) = - // Synthesize an artificial "OptionalArgument" attribute for the parameter - let optAttrs = - if isOpt then - [ ( { TypeName=LongIdentWithDots(pathToSynLid m ["Microsoft";"FSharp";"Core";"OptionalArgument"], []) - ArgExpr=mkSynUnit m - Target=None - AppliesToGetterAndSetter=false - Range=m} : SynAttribute) ] - else - [] - - if isArg && not (isNil attrs) && Option.isNone nm then - errorR(Error(FSComp.SR.tcParameterRequiresName(), m)) - - if not isArg && Option.isSome nm then - errorR(Error(FSComp.SR.tcReturnValuesCannotHaveNames(), m)) - - // Call the attribute checking function - let attribs = tcAttributes (optAttrs@attrs) - ({ Attribs = attribs; Name = nm } : ArgReprInfo) - -/// Members have an arity inferred from their syntax. This "valSynData" is not quite the same as the arities -/// used in the middle and backends of the compiler ("topValInfo"). -/// "0" in a valSynData (see Ast.arity_of_pat) means a "unit" arg in a topValInfo -/// Hence remove all "zeros" from arity and replace them with 1 here. -/// Note we currently use the compiled form for choosing unique names, to distinguish overloads because this must match up -/// between signature and implementation, and the signature just has "unit". -let TranslateTopValSynInfo m tcAttributes (SynValInfo(argsData, retData)) = - PartialValReprInfo (argsData |> List.mapSquared (TranslateTopArgSynInfo true m (tcAttributes AttributeTargets.Parameter)), - retData |> TranslateTopArgSynInfo false m (tcAttributes AttributeTargets.ReturnValue)) - -let TranslatePartialArity tps (PartialValReprInfo (argsData, retData)) = - ValReprInfo(ValReprInfo.InferTyparInfo tps, argsData, retData) - - -//------------------------------------------------------------------------- -// Members -//------------------------------------------------------------------------- - -let ComputeLogicalName (id: Ident) memberFlags = - match memberFlags.MemberKind with - | MemberKind.ClassConstructor -> ".cctor" - | MemberKind.Constructor -> ".ctor" - | MemberKind.Member -> - match id.idText with - | (".ctor" | ".cctor") as r -> errorR(Error(FSComp.SR.tcInvalidMemberNameCtor(), id.idRange)); r - | r -> r - | MemberKind.PropertyGetSet -> error(InternalError(FSComp.SR.tcMemberKindPropertyGetSetNotExpected(), id.idRange)) - | MemberKind.PropertyGet -> "get_" + id.idText - | MemberKind.PropertySet -> "set_" + id.idText - -/// ValMemberInfoTransient(memberInfo, logicalName, compiledName) -type ValMemberInfoTransient = ValMemberInfoTransient of ValMemberInfo * string * string - -/// Make the unique "name" for a member. -// -// optImplSlotTy = None (for classes) or Some ty (when implementing interface type ty) -let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, optImplSlotTys, memberFlags, valSynData, id, isCompGen) = - let logicalName = ComputeLogicalName id memberFlags - let optIntfSlotTys = if optImplSlotTys |> List.forall (isInterfaceTy g) then optImplSlotTys else [] - let memberInfo: ValMemberInfo = - { ApparentEnclosingEntity=tcref - MemberFlags=memberFlags - IsImplemented=false - // NOTE: This value is initially only set for interface implementations and those overrides - // where we manage to pre-infer which abstract is overridden by the method. It is filled in - // properly when we check the allImplemented implementation checks at the end of the inference scope. - ImplementedSlotSigs=optImplSlotTys |> List.map (fun ity -> TSlotSig(logicalName, ity, [], [], [], None)) } - let isInstance = MemberIsCompiledAsInstance g tcref isExtrinsic memberInfo attrs - if (memberFlags.IsDispatchSlot || not (isNil optIntfSlotTys)) then - if not isInstance then - errorR(VirtualAugmentationOnNullValuedType(id.idRange)) - elif not memberFlags.IsOverrideOrExplicitImpl && memberFlags.IsInstance then - if not isExtrinsic && not isInstance then - warning(NonVirtualAugmentationOnNullValuedType(id.idRange)) - - let compiledName = - if isExtrinsic then - let tname = tcref.LogicalName - let text = tname + "." + logicalName - let text = if memberFlags.MemberKind <> MemberKind.Constructor && memberFlags.MemberKind <> MemberKind.ClassConstructor && not memberFlags.IsInstance then text + ".Static" else text - let text = if memberFlags.IsOverrideOrExplicitImpl then text + ".Override" else text - text - else - List.foldBack (tcrefOfAppTy g >> qualifiedMangledNameOfTyconRef) optIntfSlotTys logicalName - - if not isCompGen && IsMangledOpName id.idText && IsInfixOperator id.idText then - let m = id.idRange - let name = DecompileOpName id.idText - // Check symbolic members. Expect valSynData implied arity to be [[2]]. - match SynInfo.AritiesOfArgs valSynData with - | [] | [0] -> warning(Error(FSComp.SR.memberOperatorDefinitionWithNoArguments name, m)) - | n :: otherArgs -> - let opTakesThreeArgs = PrettyNaming.IsTernaryOperator name - if n<>2 && not opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonPairArgument(name, n), m)) - if n<>3 && opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonTripleArgument(name, n), m)) - if not (isNil otherArgs) then warning(Error(FSComp.SR.memberOperatorDefinitionWithCurriedArguments name, m)) - - if isExtrinsic && IsMangledOpName id.idText then - warning(Error(FSComp.SR.tcMemberOperatorDefinitionInExtrinsic(), id.idRange)) - - ValMemberInfoTransient(memberInfo, logicalName, compiledName) - -type OverridesOK = - | OverridesOK - | WarnOnOverrides - | ErrorOnOverrides - -/// A type to represent information associated with values to indicate what explicit (declared) type parameters -/// are given and what additional type parameters can be inferred, if any. -/// -/// The declared type parameters, e.g. let f<'a> (x:'a) = x, plus an indication -/// of whether additional polymorphism may be inferred, e.g. let f<'a, ..> (x:'a) y = x -type ExplicitTyparInfo = ExplicitTyparInfo of Typars * Typars * bool - -let permitInferTypars = ExplicitTyparInfo ([], [], true) -let dontInferTypars = ExplicitTyparInfo ([], [], false) - -type ArgAndRetAttribs = ArgAndRetAttribs of Attribs list list * Attribs -let noArgOrRetAttribs = ArgAndRetAttribs ([], []) - -/// A flag to represent the sort of bindings are we processing. -/// Processing "declaration" and "class" bindings that make up a module (such as "let x = 1 let y = 2") -/// shares the same code paths (e.g. TcLetBinding and TcLetrec) as processing expression bindings (such as "let x = 1 in ...") -/// Member bindings also use this path. -// -/// However there are differences in how different bindings get processed, -/// i.e. module bindings get published to the implicitly accumulated module type, but expression 'let' bindings don't. -type DeclKind = - | ModuleOrMemberBinding - - /// Extensions to a type within the same assembly - | IntrinsicExtensionBinding - - /// Extensions to a type in a different assembly - | ExtrinsicExtensionBinding - - | ClassLetBinding of (* isStatic *) bool - - | ObjectExpressionOverrideBinding - - | ExpressionBinding - - static member IsModuleOrMemberOrExtensionBinding x = - match x with - | ModuleOrMemberBinding -> true - | IntrinsicExtensionBinding -> true - | ExtrinsicExtensionBinding -> true - | ClassLetBinding _ -> false - | ObjectExpressionOverrideBinding -> false - | ExpressionBinding -> false - - static member MustHaveArity x = DeclKind.IsModuleOrMemberOrExtensionBinding x - - member x.CanBeDllImport = - match x with - | ModuleOrMemberBinding -> true - | IntrinsicExtensionBinding -> true - | ExtrinsicExtensionBinding -> true - | ClassLetBinding _ -> true - | ObjectExpressionOverrideBinding -> false - | ExpressionBinding -> false - - static member IsAccessModifierPermitted x = DeclKind.IsModuleOrMemberOrExtensionBinding x - - static member ImplicitlyStatic x = DeclKind.IsModuleOrMemberOrExtensionBinding x - - static member AllowedAttribTargets memberFlagsOpt x = - match x with - | ModuleOrMemberBinding | ObjectExpressionOverrideBinding -> - match memberFlagsOpt with - | Some flags when flags.MemberKind = MemberKind.Constructor -> AttributeTargets.Constructor - | Some flags when flags.MemberKind = MemberKind.PropertyGetSet -> AttributeTargets.Event ||| AttributeTargets.Property - | Some flags when flags.MemberKind = MemberKind.PropertyGet -> AttributeTargets.Event ||| AttributeTargets.Property - | Some flags when flags.MemberKind = MemberKind.PropertySet -> AttributeTargets.Property - | Some _ -> AttributeTargets.Method - | None -> AttributeTargets.Field ||| AttributeTargets.Method ||| AttributeTargets.Property - | IntrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property - | ExtrinsicExtensionBinding -> AttributeTargets.Method ||| AttributeTargets.Property - | ClassLetBinding _ -> AttributeTargets.Field ||| AttributeTargets.Method - | ExpressionBinding -> enum 0 // indicates attributes not allowed on expression 'let' bindings - - // Note: now always true - static member CanGeneralizeConstrainedTypars x = - match x with - | ModuleOrMemberBinding -> true - | IntrinsicExtensionBinding -> true - | ExtrinsicExtensionBinding -> true - | ClassLetBinding _ -> true - | ObjectExpressionOverrideBinding -> true - | ExpressionBinding -> true - - static member ConvertToLinearBindings x = - match x with - | ModuleOrMemberBinding -> true - | IntrinsicExtensionBinding -> true - | ExtrinsicExtensionBinding -> true - | ClassLetBinding _ -> true - | ObjectExpressionOverrideBinding -> true - | ExpressionBinding -> false - - static member CanOverrideOrImplement x = - match x with - | ModuleOrMemberBinding -> OverridesOK - | IntrinsicExtensionBinding -> WarnOnOverrides - | ExtrinsicExtensionBinding -> ErrorOnOverrides - | ClassLetBinding _ -> ErrorOnOverrides - | ObjectExpressionOverrideBinding -> OverridesOK - | ExpressionBinding -> ErrorOnOverrides - -//------------------------------------------------------------------------- -// Data structures that track the gradual accumulation of information -// about values and members during inference. -//------------------------------------------------------------------------- - -/// The results of preliminary pass over patterns to extract variables being declared. -// We should make this a record for cleaner code -type PrelimValScheme1 = - | PrelimValScheme1 of - Ident * - ExplicitTyparInfo * - TType * - PartialValReprInfo option * - ValMemberInfoTransient option * - bool * - ValInline * - ValBaseOrThisInfo * - ArgAndRetAttribs * - SynAccess option * - bool - - member x.Type = let (PrelimValScheme1(_, _, ty, _, _, _, _, _, _, _, _)) = x in ty - - member x.Ident = let (PrelimValScheme1(id, _, _, _, _, _, _, _, _, _, _)) = x in id - -/// The results of applying let-style generalization after type checking. -// We should make this a record for cleaner code -type PrelimValScheme2 = - PrelimValScheme2 of - Ident * - TypeScheme * - PartialValReprInfo option * - ValMemberInfoTransient option * - bool * - ValInline * - ValBaseOrThisInfo * - ArgAndRetAttribs * - SynAccess option * - bool * - bool (* hasDeclaredTypars *) - - -/// The results of applying arity inference to PrelimValScheme2 -// We should make this a record for cleaner code -type ValScheme = - | ValScheme of - Ident * - TypeScheme * - ValReprInfo option * - ValMemberInfoTransient option * - bool * // isMutable - ValInline * - ValBaseOrThisInfo * - SynAccess option * - bool * // compgen * - bool * // isIncrClass - bool * // isTyFunc - bool // hasDeclaredTypars - - member x.GeneralizedTypars = let (ValScheme(_, TypeScheme(gtps, _), _, _, _, _, _, _, _, _, _, _)) = x in gtps - - member x.TypeScheme = let (ValScheme(_, ts, _, _, _, _, _, _, _, _, _, _)) = x in ts - -/// Translation of patterns is split into three phases. The first collects names. -/// The second is run after val_specs have been created for those names and inference -/// has been resolved. The second phase is run by applying a function returned by the -/// first phase. The input to the second phase is a List.map that gives the Val and type scheme -/// for each value bound by the pattern. -type TcPatPhase2Input = - | TcPatPhase2Input of (Val * TypeScheme) NameMap * bool - // Get an input indicating we are no longer on the left-most path through a disjunctive "or" pattern - member x.RightPath = (let (TcPatPhase2Input(a, _)) = x in TcPatPhase2Input(a, false)) - -/// The first phase of checking and elaborating a binding leaves a goop of information. -/// This is a bit of a mess: much of this information is also carried on a per-value basis by the -/// "NameMap". -type CheckedBindingInfo = - | CheckedBindingInfo of - ValInline * - Tast.Attribs * - XmlDoc * - (TcPatPhase2Input -> PatternMatchCompilation.Pattern) * - ExplicitTyparInfo * - NameMap * - Expr * - ArgAndRetAttribs * - TType * - range * - SequencePointInfoForBinding * - bool * // compiler generated? - Const option * // literal value? - bool // fixed? - member x.Expr = let (CheckedBindingInfo(_, _, _, _, _, _, expr, _, _, _, _, _, _, _)) = x in expr - member x.SeqPoint = let (CheckedBindingInfo(_, _, _, _, _, _, _, _, _, _, spBind, _, _, _)) = x in spBind - -/// Return the generalized type for a type scheme -let GeneralizedTypeForTypeScheme typeScheme = - let (TypeScheme(generalizedTypars, tau)) = typeScheme - mkForallTyIfNeeded generalizedTypars tau - -/// Create a type scheme for something that is not generic -let NonGenericTypeScheme ty = TypeScheme([], ty) - -//------------------------------------------------------------------------- -// Helpers related to publishing values, types and members into the -// elaborated representation. -//------------------------------------------------------------------------- - -let UpdateAccModuleOrNamespaceType cenv env f = - // When compiling FSharp.Core, modify the fslib CCU to ensure forward stable references used by - // the compiler can be resolved ASAP. Not at all pretty but it's hard to - // find good ways to do references from the compiler into a term graph. - if cenv.compilingCanonicalFslibModuleType then - let nleref = mkNonLocalEntityRef cenv.topCcu (arrPathOfLid env.ePath) - let modul = nleref.Deref - modul.entity_modul_contents <- MaybeLazy.Strict (f true modul.ModuleOrNamespaceType) - SetCurrAccumulatedModuleOrNamespaceType env (f false (GetCurrAccumulatedModuleOrNamespaceType env)) - -let PublishModuleDefn cenv env mspec = - UpdateAccModuleOrNamespaceType cenv env (fun intoFslibCcu mty -> - if intoFslibCcu then mty - else mty.AddEntity mspec) - let item = Item.ModuleOrNamespaces([mkLocalModRef mspec]) - CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights) - -let PublishTypeDefn cenv env tycon = - UpdateAccModuleOrNamespaceType cenv env (fun _ mty -> - mty.AddEntity tycon) - -let PublishValueDefnPrim cenv env (vspec: Val) = - UpdateAccModuleOrNamespaceType cenv env (fun _ mty -> - mty.AddVal vspec) - -let PublishValueDefn cenv env declKind (vspec: Val) = - if (declKind = ModuleOrMemberBinding) && - ((GetCurrAccumulatedModuleOrNamespaceType env).ModuleOrNamespaceKind = Namespace) && - (Option.isNone vspec.MemberInfo) then - errorR(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(), vspec.Range)) - - if (declKind = ExtrinsicExtensionBinding) && - ((GetCurrAccumulatedModuleOrNamespaceType env).ModuleOrNamespaceKind = Namespace) then - errorR(Error(FSComp.SR.tcNamespaceCannotContainExtensionMembers(), vspec.Range)) - - // Publish the value to the module type being generated. - match declKind with - | ModuleOrMemberBinding - | ExtrinsicExtensionBinding - | IntrinsicExtensionBinding -> PublishValueDefnPrim cenv env vspec - | _ -> () - - match vspec.MemberInfo with - | Some _ when - (not vspec.IsCompilerGenerated && - // Extrinsic extensions don't get added to the tcaug - not (declKind = ExtrinsicExtensionBinding)) -> - // // Static initializers don't get published to the tcaug - // not (memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor)) -> - - let tcaug = vspec.MemberApparentEntity.TypeContents - let vref = mkLocalValRef vspec - tcaug.tcaug_adhoc <- NameMultiMap.add vspec.LogicalName vref tcaug.tcaug_adhoc - tcaug.tcaug_adhoc_list.Add (ValRefIsExplicitImpl cenv.g vref, vref) - | _ -> () - -let CombineVisibilityAttribs vis1 vis2 m = - match vis1 with - | Some _ -> - if Option.isSome vis2 then - errorR(Error(FSComp.SR.tcMultipleVisibilityAttributes(), m)) - vis1 - | _ -> vis2 - -let ComputeAccessAndCompPath env declKindOpt m vis overrideVis actualParent = - let accessPath = env.eAccessPath - let accessModPermitted = - match declKindOpt with - | None -> true - | Some declKind -> DeclKind.IsAccessModifierPermitted declKind - - if Option.isSome vis && not accessModPermitted then - errorR(Error(FSComp.SR.tcMultipleVisibilityAttributesWithLet(), m)) - - let vis = - match overrideVis, vis with - | Some v, _ -> v - | _, None -> taccessPublic (* a module or member binding defaults to "public" *) - | _, Some SynAccess.Public -> taccessPublic - | _, Some SynAccess.Private -> taccessPrivate accessPath - | _, Some SynAccess.Internal -> taccessInternal - - let vis = - match actualParent with - | ParentNone -> vis - | Parent tcref -> combineAccess vis tcref.Accessibility - - let cpath = if accessModPermitted then Some env.eCompPath else None - vis, cpath - -let CheckForAbnormalOperatorNames cenv (idRange: range) coreDisplayName (memberInfoOpt: ValMemberInfo option) = - if (idRange.EndColumn - idRange.StartColumn <= 5) && - not cenv.g.compilingFslib - then - let opName = DecompileOpName coreDisplayName - let isMember = memberInfoOpt.IsSome - match opName with - | PrettyNaming.Relational -> - if isMember then - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMethodNameForRelationalOperator(opName, coreDisplayName), idRange)) - else - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinitionRelational opName, idRange)) - | PrettyNaming.Equality -> - if isMember then - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMethodNameForEquality(opName, coreDisplayName), idRange)) - else - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinitionEquality opName, idRange)) - | PrettyNaming.Control -> - if isMember then - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMemberName(opName, coreDisplayName), idRange)) - else - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidOperatorDefinition opName, idRange)) - | PrettyNaming.Indexer -> - if not isMember then - error(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidIndexOperatorDefinition opName, idRange)) - | PrettyNaming.FixedTypes -> - if isMember then - warning(StandardOperatorRedefinitionWarning(FSComp.SR.tcInvalidMemberNameFixedTypes opName, idRange)) - | PrettyNaming.Other -> () - -let MakeAndPublishVal cenv env (altActualParent, inSig, declKind, vrec, vscheme, attrs, doc, konst, isGeneratedEventVal) = - - let (ValScheme(id, typeScheme, topValData, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars)) = vscheme - - let ty = GeneralizedTypeForTypeScheme typeScheme - - let m = id.idRange - - let isTopBinding = - match declKind with - | ModuleOrMemberBinding -> true - | ExtrinsicExtensionBinding -> true - | IntrinsicExtensionBinding -> true - | _ -> false - - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - - let actualParent, overrideVis = - // Use the parent of the member if it's available - // If it's an extrinsic extension member or not a member then use the containing module. - match memberInfoOpt with - | Some (ValMemberInfoTransient(memberInfo, _, _)) when not isExtrinsic -> - if memberInfo.ApparentEnclosingEntity.IsModuleOrNamespace then - errorR(InternalError(FSComp.SR.tcExpectModuleOrNamespaceParent(id.idText), m)) - - // Members of interface implementations have the accessibility of the interface - // they are implementing. - let vis = - if Tastops.MemberIsExplicitImpl cenv.g memberInfo then - let slotSig = List.head memberInfo.ImplementedSlotSigs - match slotSig.ImplementedType with - | TType_app (tyconref, _) -> Some tyconref.Accessibility - | _ -> None - else - None - Parent(memberInfo.ApparentEnclosingEntity), vis - | _ -> altActualParent, None - - let vis, _ = ComputeAccessAndCompPath env (Some declKind) id.idRange vis overrideVis actualParent - - let inlineFlag = - if HasFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute attrs then - if inlineFlag = ValInline.PseudoVal || inlineFlag = ValInline.Always then - errorR(Error(FSComp.SR.tcDllImportStubsCannotBeInlined(), m)) - ValInline.Never - else - let implflags = - match TryFindFSharpAttribute cenv.g cenv.g.attrib_MethodImplAttribute attrs with - | Some (Attrib(_, _, [ AttribInt32Arg flags ], _, _, _, _)) -> flags - | _ -> 0x0 - // MethodImplOptions.NoInlining = 0x8 - let NO_INLINING = 0x8 - if (implflags &&& NO_INLINING) <> 0x0 then - ValInline.Never - else - inlineFlag - - // CompiledName not allowed on virtual/abstract/override members - let compiledNameAttrib = TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs - if Option.isSome compiledNameAttrib then - match memberInfoOpt with - | Some (ValMemberInfoTransient(memberInfo, _, _)) -> - if memberInfo.MemberFlags.IsDispatchSlot || memberInfo.MemberFlags.IsOverrideOrExplicitImpl then - errorR(Error(FSComp.SR.tcCompiledNameAttributeMisused(), m)) - | None -> - match altActualParent with - | ParentNone -> errorR(Error(FSComp.SR.tcCompiledNameAttributeMisused(), m)) - | _ -> () - - let compiledNameIsOnProp = - match memberInfoOpt with - | Some (ValMemberInfoTransient(memberInfo, _, _)) -> - memberInfo.MemberFlags.MemberKind = MemberKind.PropertyGet || - memberInfo.MemberFlags.MemberKind = MemberKind.PropertySet || - memberInfo.MemberFlags.MemberKind = MemberKind.PropertyGetSet - | _ -> false - - let compiledName = - match compiledNameAttrib with - // We fix up CompiledName on properties during codegen - | Some _ when not compiledNameIsOnProp -> compiledNameAttrib - | _ -> - match memberInfoOpt with - | Some (ValMemberInfoTransient(_, _, compiledName)) -> - Some compiledName - | None -> - None - - let logicalName = - match memberInfoOpt with - | Some (ValMemberInfoTransient(_, logicalName, _)) -> - logicalName - | None -> - id.idText - - let memberInfoOpt = - match memberInfoOpt with - | Some (ValMemberInfoTransient(memberInfo, _, _)) -> - Some memberInfo - | None -> - None - - let vspec = - NewVal (logicalName, id.idRange, compiledName, ty, - (if ((* (isByrefTy cenv.g ty) || *) isMutable) then Mutable else Immutable), - compgen, topValData, vis, vrec, memberInfoOpt, baseOrThis, attrs, inlineFlag, doc, isTopBinding, isExtrinsic, isIncrClass, isTyFunc, - (hasDeclaredTypars || inSig), isGeneratedEventVal, konst, actualParent) - - - CheckForAbnormalOperatorNames cenv id.idRange vspec.CoreDisplayName memberInfoOpt - - PublishValueDefn cenv env declKind vspec - - let shouldNotifySink (vspec: Val) = - match vspec.MemberInfo with - // `this` reference named `__`. It's either: - // * generated by compiler for auto properties or - // * provided by source code (i.e. `member __.Method = ...`) - // We don't notify sink about it to prevent generating `FSharpSymbol` for it and appearing in completion list. - | None when - let baseOrThisInfo = vspec.BaseOrThisInfo - baseOrThisInfo = ValBaseOrThisInfo.BaseVal || // visualfsharp#3699 - baseOrThisInfo = ValBaseOrThisInfo.MemberThisVal && vspec.LogicalName = "__" -> false - | _ -> true - - match cenv.tcSink.CurrentSink with - | Some _ when not vspec.IsCompilerGenerated && shouldNotifySink vspec -> - let nenv = AddFakeNamedValRefToNameEnv vspec.DisplayName env.NameEnv (mkLocalValRef vspec) - CallEnvSink cenv.tcSink (vspec.Range, nenv, env.eAccessRights) - let item = Item.Value(mkLocalValRef vspec) - CallNameResolutionSink cenv.tcSink (vspec.Range, nenv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights) - | _ -> () - - vspec - -let MakeAndPublishVals cenv env (altActualParent, inSig, declKind, vrec, valSchemes, attrs, doc, konst) = - Map.foldBack - (fun name (valscheme: ValScheme) values -> - Map.add name (MakeAndPublishVal cenv env (altActualParent, inSig, declKind, vrec, valscheme, attrs, doc, konst, false), valscheme.TypeScheme) values) - valSchemes - Map.empty - -let MakeAndPublishBaseVal cenv env baseIdOpt ty = - baseIdOpt - |> Option.map (fun (id: Ident) -> - let valscheme = ValScheme(id, NonGenericTypeScheme ty, None, None, false, ValInline.Never, BaseVal, None, false, false, false, false) - MakeAndPublishVal cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valscheme, [], XmlDoc.Empty, None, false)) - -let InstanceMembersNeedSafeInitCheck cenv m thisTy = - ExistsInEntireHierarchyOfType - (fun ty -> not (isStructTy cenv.g ty) && (match tryDestAppTy cenv.g ty with ValueSome tcref when tcref.HasSelfReferentialConstructor -> true | _ -> false)) - cenv.g - cenv.amap - m - AllowMultiIntfInstantiations.Yes - thisTy - -let MakeSafeInitField (g: TcGlobals) env m isStatic = - let id = - // Ensure that we have an g.CompilerGlobalState - assert(g.CompilerGlobalState |> Option.isSome) - ident(g.CompilerGlobalState.Value.NiceNameGenerator.FreshCompilerGeneratedName("init", m), m) - let taccess = TAccess [env.eAccessPath] - NewRecdField isStatic None id false g.int_ty true true [] [] XmlDoc.Empty taccess true - -// Make the "delayed reference" boolean value recording the safe initialization of a type in a hierarchy where there is a HasSelfReferentialConstructor -let ComputeInstanceSafeInitInfo cenv env m thisTy = - if InstanceMembersNeedSafeInitCheck cenv m thisTy then - let rfield = MakeSafeInitField cenv.g env m false - let tcref = tcrefOfAppTy cenv.g thisTy - SafeInitField (mkRecdFieldRef tcref rfield.Name, rfield) - else - NoSafeInitInfo - -// Make the "delayed reference" value where the this pointer will reside after calling the base class constructor -// Make the value for the 'this' pointer for use within a constructor -let MakeAndPublishSafeThisVal cenv env (thisIdOpt: Ident option) thisTy = - match thisIdOpt with - | Some thisId -> - // for structs, thisTy is a byref - if not (isFSharpObjModelTy cenv.g thisTy) then - errorR(Error(FSComp.SR.tcStructsCanOnlyBindThisAtMemberDeclaration(), thisId.idRange)) - - let valScheme = ValScheme(thisId, NonGenericTypeScheme(mkRefCellTy cenv.g thisTy), None, None, false, ValInline.Never, CtorThisVal, None, false, false, false, false) - Some(MakeAndPublishVal cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valScheme, [], XmlDoc.Empty, None, false)) - - | None -> - None - - -//------------------------------------------------------------------------- -// Helpers for type inference for recursive bindings -//------------------------------------------------------------------------- - -/// Fixup the type instantiation at recursive references. Used after the bindings have been -/// checked. The fixups are applied by using mutation. -let AdjustAndForgetUsesOfRecValue cenv (vrefTgt: ValRef) (valScheme: ValScheme) = - let (TypeScheme(generalizedTypars, _)) = valScheme.TypeScheme - let fty = GeneralizedTypeForTypeScheme valScheme.TypeScheme - let lvrefTgt = vrefTgt.Deref - if not (isNil generalizedTypars) then - // Find all the uses of this recursive binding and use mutation to adjust the expressions - // at those points in order to record the inferred type parameters. - let recUses = cenv.recUses.Find lvrefTgt - recUses - |> List.iter (fun (fixupPoint, m, isComplete) -> - if not isComplete then - // Keep any values for explicit type arguments - let fixedUpExpr = - let vrefFlags, tyargs0 = - match fixupPoint.Value with - | Expr.App (Expr.Val (_, vrefFlags, _), _, tyargs0, [], _) -> vrefFlags, tyargs0 - | Expr.Val (_, vrefFlags, _) -> vrefFlags, [] - | _ -> - errorR(Error(FSComp.SR.tcUnexpectedExprAtRecInfPoint(), m)) - NormalValUse, [] - - let ityargs = generalizeTypars (List.drop (List.length tyargs0) generalizedTypars) - primMkApp (Expr.Val (vrefTgt, vrefFlags, m), fty) (tyargs0 @ ityargs) [] m - fixupPoint.Value <- fixedUpExpr) - - vrefTgt.Deref.SetValRec ValNotInRecScope - cenv.recUses <- cenv.recUses.Remove vrefTgt.Deref - - -/// Set the properties of recursive values that are only fully known after inference is complete -let AdjustRecType _cenv (vspec: Val) (ValScheme(_, typeScheme, topValData, _, _, _, _, _, _, _, _, _)) = - let fty = GeneralizedTypeForTypeScheme typeScheme - vspec.SetType fty - vspec.SetValReprInfo topValData - vspec.SetValRec (ValInRecScope true) - -/// Record the generated value expression as a place where we will have to -/// adjust using AdjustAndForgetUsesOfRecValue at a letrec point. Every use of a value -/// under a letrec gets used at the _same_ type instantiation. -let RecordUseOfRecValue cenv vrec (vrefTgt: ValRef) vexp m = - match vrec with - | ValInRecScope isComplete -> - let fixupPoint = ref vexp - cenv.recUses <- cenv.recUses.Add (vrefTgt.Deref, (fixupPoint, m, isComplete)) - Expr.Link fixupPoint - | ValNotInRecScope -> - vexp - -type RecursiveUseFixupPoints = RecursiveUseFixupPoints of (Expr ref * range) list - -/// Get all recursive references, for fixing up delayed recursion using laziness -let GetAllUsesOfRecValue cenv vrefTgt = - RecursiveUseFixupPoints (cenv.recUses.Find vrefTgt |> List.map (fun (fixupPoint, m, _) -> (fixupPoint, m))) - - -//------------------------------------------------------------------------- -// Helpers for Generalization -//------------------------------------------------------------------------- - -let ChooseCanonicalDeclaredTyparsAfterInference g denv declaredTypars m = - declaredTypars |> List.iter (fun tp -> - let ty = mkTyparTy tp - if not (isAnyParTy g ty) then - error(Error(FSComp.SR.tcLessGenericBecauseOfAnnotation(tp.Name, NicePrint.prettyStringOfTy denv ty), tp.Range))) - - let declaredTypars = NormalizeDeclaredTyparsForEquiRecursiveInference g declaredTypars - - if ListSet.hasDuplicates typarEq declaredTypars then - errorR(Error(FSComp.SR.tcConstrainedTypeVariableCannotBeGeneralized(), m)) - - declaredTypars - -let ChooseCanonicalValSchemeAfterInference g denv valscheme m = - let (ValScheme(id, typeScheme, arityInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars)) = valscheme - let (TypeScheme(generalizedTypars, ty)) = typeScheme - let generalizedTypars = ChooseCanonicalDeclaredTyparsAfterInference g denv generalizedTypars m - let typeScheme = TypeScheme(generalizedTypars, ty) - let valscheme = ValScheme(id, typeScheme, arityInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, isIncrClass, isTyFunc, hasDeclaredTypars) - valscheme - -let PlaceTyparsInDeclarationOrder declaredTypars generalizedTypars = - declaredTypars @ (generalizedTypars |> List.filter (fun tp -> not (ListSet.contains typarEq tp declaredTypars))) - -let SetTyparRigid _g denv m (tp: Typar) = - match tp.Solution with - | None -> () - | Some ty -> - if tp.IsCompilerGenerated then - errorR(Error(FSComp.SR.tcGenericParameterHasBeenConstrained(NicePrint.prettyStringOfTy denv ty), m)) - else - errorR(Error(FSComp.SR.tcTypeParameterHasBeenConstrained(NicePrint.prettyStringOfTy denv ty), tp.Range)) - tp.SetRigidity TyparRigidity.Rigid - -let GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTyparsForThisBinding - (PrelimValScheme1(id, iflex, ty, partialValReprInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) = - - let (ExplicitTyparInfo(_rigidCopyOfDeclaredTypars, declaredTypars, _)) = iflex - - let m = id.idRange - - let allDeclaredTypars = enclosingDeclaredTypars@declaredTypars - let allDeclaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g denv allDeclaredTypars m - - // Trim out anything not in type of the value (as opposed to the type of the r.h.s) - // This is important when a single declaration binds - // multiple generic items, where each item does not use all the polymorphism - // of the r.h.s., e.g. let x, y = None, [] - let computeRelevantTypars thruFlag = - let ftps = freeInTypeLeftToRight cenv.g thruFlag ty - let generalizedTypars = generalizedTyparsForThisBinding |> List.filter (fun tp -> ListSet.contains typarEq tp ftps) - // Put declared typars first - let generalizedTypars = PlaceTyparsInDeclarationOrder allDeclaredTypars generalizedTypars - generalizedTypars - - let generalizedTypars = computeRelevantTypars false - - // Check stability of existence and ordering of type parameters under erasure of type abbreviations - let generalizedTyparsLookingThroughTypeAbbreviations = computeRelevantTypars true - if not (generalizedTypars.Length = generalizedTyparsLookingThroughTypeAbbreviations.Length && - List.forall2 typarEq generalizedTypars generalizedTyparsLookingThroughTypeAbbreviations) - then - warning(Error(FSComp.SR.tcTypeParametersInferredAreNotStable(), m)) - - let hasDeclaredTypars = not (isNil declaredTypars) - // This is just about the only place we form a TypeScheme - let tyScheme = TypeScheme(generalizedTypars, ty) - PrelimValScheme2(id, tyScheme, partialValReprInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen, hasDeclaredTypars) - -let GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars types = - NameMap.map (GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars) types - -let DontGeneralizeVals types = - let dontGeneralizeVal (PrelimValScheme1(id, _, ty, partialValReprInfoOpt, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) = - PrelimValScheme2(id, NonGenericTypeScheme ty, partialValReprInfoOpt, memberInfoOpt, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen, false) - NameMap.map dontGeneralizeVal types - -let InferGenericArityFromTyScheme (TypeScheme(generalizedTypars, _)) partialValReprInfo = - TranslatePartialArity generalizedTypars partialValReprInfo - -let ComputeIsTyFunc(id: Ident, hasDeclaredTypars, arityInfo: ValReprInfo option) = - hasDeclaredTypars && - (match arityInfo with - | None -> error(Error(FSComp.SR.tcExplicitTypeParameterInvalid(), id.idRange)) - | Some info -> info.NumCurriedArgs = 0) - -let UseSyntacticArity declKind typeScheme partialValReprInfo = - if DeclKind.MustHaveArity declKind then - Some(InferGenericArityFromTyScheme typeScheme partialValReprInfo) - else - None - -/// Combine the results of InferSynValData and InferArityOfExpr. -// -// The F# spec says that we infer arities from declaration forms and types. -// -// For example -// let f (a, b) c = 1 // gets arity [2;1] -// let f (a: int*int) = 1 // gets arity [2], based on type -// let f () = 1 // gets arity [0] -// let f = (fun (x: int) (y: int) -> 1) // gets arity [1;1] -// let f = (fun (x: int*int) y -> 1) // gets arity [2;1] -// -// Some of this arity inference is purely syntax directed and done in InferSynValData in ast.fs -// Some is done by InferArityOfExpr. -// -// However, there are some corner cases in this specification. In particular, consider -// let f () () = 1 // [0;1] or [0;0]? Answer: [0;1] -// let f (a: unit) = 1 // [0] or [1]? Answer: [1] -// let f = (fun () -> 1) // [0] or [1]? Answer: [0] -// let f = (fun (a: unit) -> 1) // [0] or [1]? Answer: [1] -// -// The particular choice of [1] for -// let f (a: unit) = 1 -// is intended to give a disambiguating form for members that override methods taking a single argument -// instantiated to type "unit", e.g. -// type Base<'a> = -// abstract M: 'a -> unit -// -// { new Base with -// member x.M(v: int) = () } -// -// { new Base with -// member x.M(v: unit) = () } -// -let CombineSyntacticAndInferredArities g declKind rhsExpr prelimScheme = - let (PrelimValScheme2(_, typeScheme, partialValReprInfoOpt, memberInfoOpt, isMutable, _, _, ArgAndRetAttribs(argAttribs, retAttribs), _, _, _)) = prelimScheme - match partialValReprInfoOpt, DeclKind.MustHaveArity declKind with - | _, false -> None - | None, true -> Some(PartialValReprInfo([], ValReprInfo.unnamedRetVal)) - // Don't use any expression information for members, where syntax dictates the arity completely - | _ when memberInfoOpt.IsSome -> - partialValReprInfoOpt - | Some partialValReprInfoFromSyntax, true -> - let (PartialValReprInfo(curriedArgInfosFromSyntax, retInfoFromSyntax)) = partialValReprInfoFromSyntax - let partialArityInfo = - if isMutable then - PartialValReprInfo ([], retInfoFromSyntax) - else - - let (ValReprInfo (_, curriedArgInfosFromExpression, _)) = - InferArityOfExpr g AllowTypeDirectedDetupling.Yes (GeneralizedTypeForTypeScheme typeScheme) argAttribs retAttribs rhsExpr - - // Choose between the syntactic arity and the expression-inferred arity - // If the syntax specifies an eliminated unit arg, then use that - let choose ai1 ai2 = - match ai1, ai2 with - | [], _ -> [] - // Dont infer eliminated unit args from the expression if they don't occur syntactically. - | ai, [] -> ai - // If we infer a tupled argument from the expression and/or type then use that - | _ when ai1.Length < ai2.Length -> ai2 - | _ -> ai1 - let rec loop ais1 ais2 = - match ais1, ais2 with - // If the expression infers additional arguments then use those (this shouldn't happen, since the - // arity inference done on the syntactic form should give identical results) - | [], ais | ais, [] -> ais - | (h1 :: t1), (h2 :: t2) -> choose h1 h2 :: loop t1 t2 - let curriedArgInfos = loop curriedArgInfosFromSyntax curriedArgInfosFromExpression - PartialValReprInfo (curriedArgInfos, retInfoFromSyntax) - - Some partialArityInfo - -let BuildValScheme declKind partialArityInfoOpt prelimScheme = - let (PrelimValScheme2(id, typeScheme, _, memberInfoOpt, isMutable, inlineFlag, baseOrThis, _, vis, compgen, hasDeclaredTypars)) = prelimScheme - let topValInfo = - if DeclKind.MustHaveArity declKind then - Option.map (InferGenericArityFromTyScheme typeScheme) partialArityInfoOpt - else - None - let isTyFunc = ComputeIsTyFunc(id, hasDeclaredTypars, topValInfo) - ValScheme(id, typeScheme, topValInfo, memberInfoOpt, isMutable, inlineFlag, baseOrThis, vis, compgen, false, isTyFunc, hasDeclaredTypars) - -let UseCombinedArity g declKind rhsExpr prelimScheme = - let partialArityInfoOpt = CombineSyntacticAndInferredArities g declKind rhsExpr prelimScheme - BuildValScheme declKind partialArityInfoOpt prelimScheme - -let UseNoArity prelimScheme = - BuildValScheme ExpressionBinding None prelimScheme - -let MakeSimpleVals cenv env names = - let tyschemes = DontGeneralizeVals names - let valSchemes = NameMap.map UseNoArity tyschemes - let values = MakeAndPublishVals cenv env (ParentNone, false, ExpressionBinding, ValNotInRecScope, valSchemes, [], XmlDoc.Empty, None) - let vspecMap = NameMap.map fst values - values, vspecMap - -let MakeAndPublishSimpleVals cenv env m names mergeNamesInOneNameresEnv = - - let values, vspecMap = - if not mergeNamesInOneNameresEnv then MakeSimpleVals cenv env names - else - // reason: now during typecheck we create new name resolution environment for all components of tupled arguments in lambda. - // When trying to find best environment for the given position first we pick the most deeply nested scope that contains given position - // (and that will be lambda body - correct one), then we look for the better subtree on the left hand side - // (and that will be name resolution environment containing second parameter parameter - without the first one). - // fix: I've tried to make fix as local as possible to reduce overall impact on the source code. - // Idea of the fix: replace existing typecheck results sink and capture all reported name resolutions (this will be all parameters in lambda). - // After that - we restore the sink back, generate new name resolution environment that contains all captured names and report generated environment - // to the old sink. - - - // default behavior - send EnvWithScope notification for every resolved name - // what we do here is override this default behavior and capture only all name resolution notifications - // later we'll process them and create one name resolution env that will contain names from all notifications - let nameResolutions = ResizeArray() - let values, vspecMap = - let sink = - { new ITypecheckResultsSink with - member this.NotifyEnvWithScope(_, _, _) = () // ignore EnvWithScope reports - member this.NotifyNameResolution(pos, item, itemGroup, itemTyparInst, occurence, denv, nenv, ad, m, replacing) = - if not m.IsSynthetic then - nameResolutions.Add(pos, item, itemGroup, itemTyparInst, occurence, denv, nenv, ad, m, replacing) - member this.NotifyExprHasType(_, _, _, _, _, _) = assert false // no expr typings in MakeSimpleVals - member this.NotifyFormatSpecifierLocation(_, _) = () - member this.NotifyOpenDeclaration(_) = () - member this.CurrentSourceText = None - member this.FormatStringCheckContext = None } - - use _h = WithNewTypecheckResultsSink(sink, cenv.tcSink) - MakeSimpleVals cenv env names - - if nameResolutions.Count <> 0 then - let (_, _, _, _, _, _, _, ad, m1, _replacing) = nameResolutions.[0] - // mergedNameEnv - name resolution env that contains all names - // mergedRange - union of ranges of names - let mergedNameEnv, mergedRange = - ((env.NameEnv, m1), nameResolutions) ||> Seq.fold (fun (nenv, merged) (_, item, _, _, _, _, _, _, m, _) -> - // MakeAndPublishVal creates only Item.Value - let item = match item with Item.Value item -> item | _ -> failwith "impossible" - (AddFakeNamedValRefToNameEnv item.DisplayName nenv item), (unionRanges m merged) - ) - // send notification about mergedNameEnv - CallEnvSink cenv.tcSink (mergedRange, mergedNameEnv, ad) - // call CallNameResolutionSink for all captured name resolutions using mergedNameEnv - for (_, item, itemGroup, itemTyparInst, occurence, denv, _nenv, ad, m, _replacing) in nameResolutions do - CallNameResolutionSink cenv.tcSink (m, mergedNameEnv, item, itemGroup, itemTyparInst, occurence, denv, ad) - - values, vspecMap - - let envinner = AddLocalValMap cenv.tcSink m vspecMap env - envinner, values, vspecMap - - - -//------------------------------------------------------------------------- -// Helpers to freshen existing types and values, i.e. when a reference -// to C<_> occurs then generate C for a fresh type inference variable ?ty. -//------------------------------------------------------------------------- - -let FreshenTyconRef m rigid (tcref: TyconRef) declaredTyconTypars = - let tpsorig = declaredTyconTypars - let tps = copyTypars tpsorig - if rigid <> TyparRigidity.Rigid then - tps |> List.iter (fun tp -> tp.SetRigidity rigid) - - let renaming, tinst = FixupNewTypars m [] [] tpsorig tps - (TType_app(tcref, List.map mkTyparTy tpsorig), tps, renaming, TType_app(tcref, tinst)) - -let FreshenPossibleForallTy g m rigid ty = - let tpsorig, tau = tryDestForallTy g ty - if isNil tpsorig then - [], [], [], tau - else - // tps may be have been equated to other tps in equi-recursive type inference and units-of-measure type inference. Normalize them here - let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference g tpsorig - let tps, renaming, tinst = CopyAndFixupTypars m rigid tpsorig - tpsorig, tps, tinst, instType renaming tau - -let infoOfTyconRef m (tcref: TyconRef) = - let tps, renaming, tinst = FreshenTypeInst m (tcref.Typars m) - tps, renaming, tinst, TType_app (tcref, tinst) - - -/// Given a abstract method, which may be a generic method, freshen the type in preparation -/// to apply it as a constraint to the method that implements the abstract slot -let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = - - // Work out if an explicit instantiation has been given. If so then the explicit type - // parameters will be made rigid and checked for generalization. If not then auto-generalize - // by making the copy of the type parameters on the virtual being overridden rigid. - - let typarsFromAbsSlotAreRigid = - - match synTyparDecls with - | SynValTyparDecls(synTypars, infer, _) -> - if infer && not (isNil synTypars) then - errorR(Error(FSComp.SR.tcOverridingMethodRequiresAllOrNoTypeParameters(), m)) - - isNil synTypars - - let (CompiledSig (argTys, retTy, fmtps, _)) = CompiledSigOfMeth g amap m absMethInfo - - // If the virtual method is a generic method then copy its type parameters - let typarsFromAbsSlot, typarInstFromAbsSlot, _ = - let ttps = absMethInfo.GetFormalTyparsOfDeclaringType m - let ttinst = argsOfAppTy g absMethInfo.ApparentEnclosingType - let rigid = if typarsFromAbsSlotAreRigid then TyparRigidity.Rigid else TyparRigidity.Flexible - ConstraintSolver.FreshenAndFixupTypars m rigid ttps ttinst fmtps - - // Work out the required type of the member - let argTysFromAbsSlot = argTys |> List.mapSquared (instType typarInstFromAbsSlot) - let retTyFromAbsSlot = retTy |> GetFSharpViewOfReturnType g |> instType typarInstFromAbsSlot - typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot - - -//------------------------------------------------------------------------- -// Helpers to typecheck expressions and patterns -//------------------------------------------------------------------------- - -let BuildFieldMap cenv env isPartial ty flds m = - let ad = env.eAccessRights - if isNil flds then invalidArg "flds" "BuildFieldMap" - let fldCount = flds.Length - - let frefSets = - let allFields = flds |> List.map (fun ((_, ident), _) -> ident) - flds - |> List.map (fun (fld, fldExpr) -> - let frefSet = ResolveField cenv.tcSink cenv.nameResolver env.eNameResEnv ad ty fld allFields - fld, frefSet, fldExpr) - - let relevantTypeSets = - frefSets |> List.map (fun (_, frefSet, _) -> frefSet |> List.map (fun (FieldResolution(rfref, _)) -> rfref.TyconRef)) - - let tcref = - match List.fold (ListSet.intersect (tyconRefEq cenv.g)) (List.head relevantTypeSets) (List.tail relevantTypeSets) with - | [tcref] -> tcref - | tcrefs -> - if isPartial then - warning (Error(FSComp.SR.tcFieldsDoNotDetermineUniqueRecordType(), m)) - - // try finding a record type with the same number of fields as the ones that are given. - match tcrefs |> List.tryFind (fun tc -> tc.TrueFieldsAsList.Length = fldCount) with - | Some tcref -> tcref - | _ -> - // OK, there isn't a unique, good type dictated by the intersection for the field refs. - // We're going to get an error of some kind below. - // Just choose one field ref and let the error come later - let (_, frefSet1, _) = List.head frefSets - let (FieldResolution(fref1, _)) = List.head frefSet1 - fref1.TyconRef - - let fldsmap, rfldsList = - ((Map.empty, []), frefSets) ||> List.fold (fun (fs, rfldsList) (fld, frefs, fldExpr) -> - match frefs |> List.filter (fun (FieldResolution(fref2, _)) -> tyconRefEq cenv.g tcref fref2.TyconRef) with - | [FieldResolution(fref2, showDeprecated)] -> - - // Record the precise resolution of the field for intellisense - let item = FreshenRecdFieldRef cenv.nameResolver m fref2 - CallNameResolutionSink cenv.tcSink ((snd fld).idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) - - CheckRecdFieldAccessible cenv.amap m env.eAccessRights fref2 |> ignore - CheckFSharpAttributes cenv.g fref2.PropertyAttribs m |> CommitOperationResult - if Map.containsKey fref2.FieldName fs then - errorR (Error(FSComp.SR.tcFieldAppearsTwiceInRecord(fref2.FieldName), m)) - if showDeprecated then - warning(Deprecated(FSComp.SR.nrRecordTypeNeedsQualifiedAccess(fref2.FieldName, fref2.Tycon.DisplayName) |> snd, m)) - - if not (tyconRefEq cenv.g tcref fref2.TyconRef) then - let (_, frefSet1, _) = List.head frefSets - let (FieldResolution(fref1, _)) = List.head frefSet1 - errorR (FieldsFromDifferentTypes(env.DisplayEnv, fref1, fref2, m)) - fs, rfldsList - else - Map.add fref2.FieldName fldExpr fs, (fref2.FieldName, fldExpr) :: rfldsList - - | _ -> error(Error(FSComp.SR.tcRecordFieldInconsistentTypes(), m))) - tcref, fldsmap, List.rev rfldsList - -let rec ApplyUnionCaseOrExn (makerForUnionCase, makerForExnTag) m cenv env overallTy item = - let ad = env.eAccessRights - match item with - | Item.ExnCase ecref -> - CheckEntityAttributes cenv.g ecref m |> CommitOperationResult - UnifyTypes cenv env m overallTy cenv.g.exn_ty - CheckTyconAccessible cenv.amap m ad ecref |> ignore - let mkf = makerForExnTag ecref - mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f.Id ] - - | Item.UnionCase(ucinfo, showDeprecated) -> - if showDeprecated then - warning(Deprecated(FSComp.SR.nrUnionTypeNeedsQualifiedAccess(ucinfo.Name, ucinfo.Tycon.DisplayName) |> snd, m)) - - let ucref = ucinfo.UnionCaseRef - CheckUnionCaseAttributes cenv.g ucref m |> CommitOperationResult - CheckUnionCaseAccessible cenv.amap m ad ucref |> ignore - let gtyp2 = actualResultTyOfUnionCase ucinfo.TypeInst ucref - let inst = mkTyparInst ucref.TyconRef.TyparsNoRange ucinfo.TypeInst - UnifyTypes cenv env m overallTy gtyp2 - let mkf = makerForUnionCase(ucref, ucinfo.TypeInst) - mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f.Id ] - | _ -> invalidArg "item" "not a union case or exception reference" - -let ApplyUnionCaseOrExnTypes m cenv env overallTy c = - ApplyUnionCaseOrExn ((fun (a, b) mArgs args -> mkUnionCaseExpr(a, b, args, unionRanges m mArgs)), - (fun a mArgs args -> mkExnExpr (a, args, unionRanges m mArgs))) m cenv env overallTy c - -let ApplyUnionCaseOrExnTypesForPat m cenv env overallTy c = - ApplyUnionCaseOrExn ((fun (a, b) mArgs args -> TPat_unioncase(a, b, args, unionRanges m mArgs)), - (fun a mArgs args -> TPat_exnconstr(a, args, unionRanges m mArgs))) m cenv env overallTy c - -let UnionCaseOrExnCheck (env: TcEnv) numArgTys numArgs m = - if numArgs <> numArgTys then error (UnionCaseWrongArguments(env.DisplayEnv, numArgTys, numArgs, m)) - -let TcUnionCaseOrExnField cenv (env: TcEnv) ty1 m c n funcs = - let ad = env.eAccessRights - let mkf, argTys, _argNames = - match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false m ad env.eNameResEnv TypeNameResolutionInfo.Default c with - | (Item.UnionCase _ | Item.ExnCase _) as item -> - ApplyUnionCaseOrExn funcs m cenv env ty1 item - | _ -> error(Error(FSComp.SR.tcUnknownUnion(), m)) - let argstysLength = List.length argTys - if n >= argstysLength then - error (UnionCaseWrongNumberOfArgs(env.DisplayEnv, argstysLength, n, m)) - let ty2 = List.item n argTys - mkf, ty2 - -//------------------------------------------------------------------------- -// Environment of explicit type parameters, e.g. 'a in "(x: 'a)" -//------------------------------------------------------------------------- - -type SyntacticUnscopedTyparEnv = UnscopedTyparEnv of NameMap - -let emptyUnscopedTyparEnv: SyntacticUnscopedTyparEnv = UnscopedTyparEnv Map.empty - -let AddUnscopedTypar n p (UnscopedTyparEnv tab) = UnscopedTyparEnv (Map.add n p tab) - -let TryFindUnscopedTypar n (UnscopedTyparEnv tab) = Map.tryFind n tab - -let HideUnscopedTypars typars (UnscopedTyparEnv tab) = - UnscopedTyparEnv (List.fold (fun acc (tp: Typar) -> Map.remove tp.Name acc) tab typars) - -//------------------------------------------------------------------------- -// Helpers for generalizing type variables -//------------------------------------------------------------------------- - -type GeneralizeConstrainedTyparOptions = - | CanGeneralizeConstrainedTypars - | DoNotGeneralizeConstrainedTypars - - -module GeneralizationHelpers = - let ComputeUngeneralizableTypars env = - - let acc = Collections.Generic.List() - for item in env.eUngeneralizableItems do - if not item.WillNeverHaveFreeTypars then - let ftps = item.GetFreeTyvars().FreeTypars - if not ftps.IsEmpty then - for ftp in ftps do - acc.Add ftp - - Zset.Create(typarOrder, acc) - - - let ComputeUnabstractableTycons env = - let acc_in_free_item acc (item: UngeneralizableItem) = - let ftycs = - if item.WillNeverHaveFreeTypars then item.CachedFreeLocalTycons else - let ftyvs = item.GetFreeTyvars() - ftyvs.FreeTycons - if ftycs.IsEmpty then acc else unionFreeTycons ftycs acc - - List.fold acc_in_free_item emptyFreeTycons env.eUngeneralizableItems - - let ComputeUnabstractableTraitSolutions env = - let acc_in_free_item acc (item: UngeneralizableItem) = - let ftycs = - if item.WillNeverHaveFreeTypars then item.CachedFreeTraitSolutions else - let ftyvs = item.GetFreeTyvars() - ftyvs.FreeTraitSolutions - if ftycs.IsEmpty then acc else unionFreeLocals ftycs acc - - List.fold acc_in_free_item emptyFreeLocals env.eUngeneralizableItems - - let rec IsGeneralizableValue g t = - match t with - | Expr.Lambda _ | Expr.TyLambda _ | Expr.Const _ -> true - - // let f(x: byref) = let v = &x in ... shouldn't generalize "v" - | Expr.Val (vref, _, m) -> not (isByrefLikeTy g m vref.Type) - - // Look through coercion nodes corresponding to introduction of subsumption - | Expr.Op (TOp.Coerce, [inputTy;actualTy], [e1], _) when isFunTy g actualTy && isFunTy g inputTy -> - IsGeneralizableValue g e1 - - | Expr.Op (op, _, args, _) -> - - let canGeneralizeOp = - match op with - | TOp.Tuple _ -> true - | TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc) - | TOp.Recd (ctorInfo, tcref) -> - match ctorInfo with - | RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) - | RecdExprIsObjInit -> false - | TOp.Array -> isNil args - | TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec) - | TOp.ILAsm ([], _) -> true - | _ -> false - - canGeneralizeOp && List.forall (IsGeneralizableValue g) args - - | Expr.LetRec (binds, body, _, _) -> - binds |> List.forall (fun b -> not b.Var.IsMutable) && - binds |> List.forall (fun b -> IsGeneralizableValue g b.Expr) && - IsGeneralizableValue g body - - | Expr.Let (bind, body, _, _) -> - not bind.Var.IsMutable && - IsGeneralizableValue g bind.Expr && - IsGeneralizableValue g body - - // Applications of type functions are _not_ normally generalizable unless explicitly marked so - | Expr.App (Expr.Val (vref, _, _), _, _, [], _) when vref.IsTypeFunction -> - HasFSharpAttribute g g.attrib_GeneralizableValueAttribute vref.Attribs - - | Expr.App (e1, _, _, [], _) -> IsGeneralizableValue g e1 - | Expr.TyChoose (_, b, _) -> IsGeneralizableValue g b - | Expr.Obj (_, ty, _, _, _, _, _) -> isInterfaceTy g ty || isDelegateTy g ty - | Expr.Link eref -> IsGeneralizableValue g !eref - - | _ -> false - - let CanGeneralizeConstrainedTyparsForDecl declKind = - if DeclKind.CanGeneralizeConstrainedTypars declKind - then CanGeneralizeConstrainedTypars - else DoNotGeneralizeConstrainedTypars - - /// Recursively knock out typars we can't generalize. - /// For non-generalized type variables be careful to iteratively knock out - /// both the typars and any typars free in the constraints of the typars - /// into the set that are considered free in the environment. - let rec TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag (generalizedTypars: Typar list) freeInEnv = - // Do not generalize type variables with a static requirement unless function is marked 'inline' - let generalizedTypars, ungeneralizableTypars1 = - if inlineFlag = ValInline.PseudoVal then generalizedTypars, [] - else generalizedTypars |> List.partition (fun tp -> tp.StaticReq = NoStaticReq) - - // Do not generalize type variables which would escape their scope - // because they are free in the environment - let generalizedTypars, ungeneralizableTypars2 = - List.partition (fun x -> not (Zset.contains x freeInEnv)) generalizedTypars - - // Some situations, e.g. implicit class constructions that represent functions as fields, - // do not allow generalisation over constrained typars. (since they can not be represented as fields) - // - // Don't generalize IsCompatFlex type parameters to avoid changing inferred types. - let generalizedTypars, ungeneralizableTypars3 = - generalizedTypars - |> List.partition (fun tp -> - (genConstrainedTyparFlag = CanGeneralizeConstrainedTypars || tp.Constraints.IsEmpty) && - not tp.IsCompatFlex) - - if isNil ungeneralizableTypars1 && isNil ungeneralizableTypars2 && isNil ungeneralizableTypars3 then - generalizedTypars, freeInEnv - else - let freeInEnv = - unionFreeTypars - (accFreeInTypars CollectAllNoCaching ungeneralizableTypars1 - (accFreeInTypars CollectAllNoCaching ungeneralizableTypars2 - (accFreeInTypars CollectAllNoCaching ungeneralizableTypars3 emptyFreeTyvars))).FreeTypars - freeInEnv - TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag generalizedTypars freeInEnv - - /// Condense type variables in positive position - let CondenseTypars (cenv, denv: DisplayEnv, generalizedTypars: Typars, tauTy, m) = - - // The type of the value is ty11 * ... * ty1N -> ... -> tyM1 * ... * tyMM -> retTy - // This is computed REGARDLESS of the arity of the expression. - let curriedArgTys, retTy = stripFunTy cenv.g tauTy - let allUntupledArgTys = curriedArgTys |> List.collect (tryDestRefTupleTy cenv.g) - - // Compute the type variables in 'retTy' - let returnTypeFreeTypars = freeInTypeLeftToRight cenv.g false retTy - let allUntupledArgTysWithFreeVars = allUntupledArgTys |> List.map (fun ty -> (ty, freeInTypeLeftToRight cenv.g false ty)) - - let relevantUniqueSubtypeConstraint (tp: Typar) = - // Find a single subtype constraint - match tp.Constraints |> List.partition (function (TyparConstraint.CoercesTo _) -> true | _ -> false) with - | [TyparConstraint.CoercesTo(cxty, _)], others -> - // Throw away null constraints if they are implied - if others |> List.exists (function (TyparConstraint.SupportsNull(_)) -> not (TypeSatisfiesNullConstraint cenv.g m cxty) | _ -> true) - then None - else Some cxty - | _ -> None - - - // Condensation typars can't be used in the constraints of any candidate condensation typars. So compute all the - // typars free in the constraints of tyIJ - - let lhsConstraintTypars = - allUntupledArgTys |> List.collect (fun ty -> - match tryDestTyparTy cenv.g ty with - | ValueSome tp -> - match relevantUniqueSubtypeConstraint tp with - | Some cxty -> freeInTypeLeftToRight cenv.g false cxty - | None -> [] - | _ -> []) - - let IsCondensationTypar (tp: Typar) = - // A condensation typar may not a user-generated type variable nor has it been unified with any user type variable - (tp.DynamicReq = TyparDynamicReq.No) && - // A condensation typar must have a single constraint "'a :> A" - (Option.isSome (relevantUniqueSubtypeConstraint tp)) && - // This is type variable is not used on the r.h.s. of the type - not (ListSet.contains typarEq tp returnTypeFreeTypars) && - // A condensation typar can't be used in the constraints of any candidate condensation typars - not (ListSet.contains typarEq tp lhsConstraintTypars) && - // A condensation typar must occur precisely once in tyIJ, and must not occur free in any other tyIJ - (match allUntupledArgTysWithFreeVars |> List.partition (fun (ty, _) -> match tryDestTyparTy cenv.g ty with ValueSome destTypar -> typarEq destTypar tp | _ -> false) with - | [_], rest -> not (rest |> List.exists (fun (_, fvs) -> ListSet.contains typarEq tp fvs)) - | _ -> false) - - let condensationTypars, generalizedTypars = generalizedTypars |> List.partition IsCondensationTypar - - // Condensation solves type variables eagerly and removes them from the generalization set - condensationTypars |> List.iter (fun tp -> - ConstraintSolver.ChooseTyparSolutionAndSolve cenv.css denv tp) - generalizedTypars - - let CanonicalizePartialInferenceProblem (cenv, denv, m) tps = - // Canonicalize constraints prior to generalization - let csenv = (MakeConstraintSolverEnv ContextInfo.NoContext cenv.css m denv) - TryD (fun () -> ConstraintSolver.CanonicalizeRelevantMemberConstraints csenv 0 NoTrace tps) - (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) - |> RaiseOperationResult - - let ComputeAndGeneralizeGenericTypars (cenv, - denv: DisplayEnv, - m, - freeInEnv: FreeTypars, - canInferTypars, - genConstrainedTyparFlag, - inlineFlag, - exprOpt, - allDeclaredTypars: Typars, - maxInferredTypars: Typars, - tauTy, - resultFirst) = - - let allDeclaredTypars = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g allDeclaredTypars - let typarsToAttemptToGeneralize = - if (match exprOpt with None -> true | Some e -> IsGeneralizableValue cenv.g e) - then (ListSet.unionFavourLeft typarEq allDeclaredTypars maxInferredTypars) - else allDeclaredTypars - - let generalizedTypars, freeInEnv = - TrimUngeneralizableTypars genConstrainedTyparFlag inlineFlag typarsToAttemptToGeneralize freeInEnv - - allDeclaredTypars - |> List.iter (fun tp -> - if Zset.memberOf freeInEnv tp then - let ty = mkTyparTy tp - error(Error(FSComp.SR.tcNotSufficientlyGenericBecauseOfScope(NicePrint.prettyStringOfTy denv ty), m))) - - let generalizedTypars = CondenseTypars(cenv, denv, generalizedTypars, tauTy, m) - - let generalizedTypars = - if canInferTypars then generalizedTypars - else generalizedTypars |> List.filter (fun tp -> ListSet.contains typarEq tp allDeclaredTypars) - - let allConstraints = List.collect (fun (tp: Typar) -> tp.Constraints) generalizedTypars - let generalizedTypars = ConstraintSolver.SimplifyMeasuresInTypeScheme cenv.g resultFirst generalizedTypars tauTy allConstraints - - // Generalization turns inference type variables into rigid, quantified type variables, - // (they may be rigid already) - generalizedTypars |> List.iter (SetTyparRigid cenv.g denv m) - - // Generalization removes constraints related to generalized type variables - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext cenv.css m denv - EliminateConstraintsForGeneralizedTypars csenv NoTrace generalizedTypars - - generalizedTypars - - //------------------------------------------------------------------------- - // Helpers to freshen existing types and values, i.e. when a reference - // to C<_> occurs then generate C for a fresh type inference variable ?ty. - //------------------------------------------------------------------------- - - - - let CheckDeclaredTyparsPermitted (memFlagsOpt, declaredTypars, m) = - match memFlagsOpt with - | None -> () - | Some memberFlags -> - match memberFlags.MemberKind with - // can't infer extra polymorphism for properties - | MemberKind.PropertyGet - | MemberKind.PropertySet -> - if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcPropertyRequiresExplicitTypeParameters(), m)) - | MemberKind.Constructor -> - if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcConstructorCannotHaveTypeParameters(), m)) - | _ -> () - - /// Properties and Constructors may only generalize the variables associated with the containing class (retrieved from the 'this' pointer) - /// Also check they don't declare explicit typars. - let ComputeCanInferExtraGeneralizableTypars (parentRef, canInferTypars, memFlagsOpt) = - canInferTypars && - (match memFlagsOpt with - | None -> true - | Some memberFlags -> - match memberFlags.MemberKind with - // can't infer extra polymorphism for properties - | MemberKind.PropertyGet | MemberKind.PropertySet -> false - // can't infer extra polymorphism for class constructors - | MemberKind.ClassConstructor -> false - // can't infer extra polymorphism for constructors - | MemberKind.Constructor -> false - // feasible to infer extra polymorphism - | _ -> true) && - (match parentRef with - | Parent tcref -> not tcref.IsFSharpDelegateTycon - | _ -> true) // no generic parameters inferred for 'Invoke' method - - - -//------------------------------------------------------------------------- -// ComputeInlineFlag -//------------------------------------------------------------------------- - -let ComputeInlineFlag memFlagsOption isInline isMutable m = - let inlineFlag = - // Mutable values may never be inlined - // Constructors may never be inlined - // Calls to virtual/abstract slots may never be inlined - if isMutable || - (match memFlagsOption with - | None -> false - | Some x -> (x.MemberKind = MemberKind.Constructor) || x.IsDispatchSlot || x.IsOverrideOrExplicitImpl) - then ValInline.Never - elif isInline then ValInline.PseudoVal - else ValInline.Optional - if isInline && (inlineFlag <> ValInline.PseudoVal) then - errorR(Error(FSComp.SR.tcThisValueMayNotBeInlined(), m)) - inlineFlag - - -//------------------------------------------------------------------------- -// Binding normalization. -// -// Determine what sort of value is being bound (normal value, instance -// member, normal function, static member etc.) and make some -// name-resolution-sensitive adjustments to the syntax tree. -// -// One part of this "normalization" ensures: -// "let SynPat.LongIdent(f) = e" when f not a datatype constructor --> let Pat_var(f) = e" -// "let SynPat.LongIdent(f) pat = e" when f not a datatype constructor --> let Pat_var(f) = \pat. e" -// "let (SynPat.LongIdent(f) : ty) = e" when f not a datatype constructor --> let (Pat_var(f) : ty) = e" -// "let (SynPat.LongIdent(f) : ty) pat = e" when f not a datatype constructor --> let (Pat_var(f) : ty) = \pat. e" -// -// This is because the first lambda in a function definition "let F x = e" -// now looks like a constructor application, i.e. let (F x) = e ... -// also let A.F x = e ... -// also let f x = e ... -// -// The other parts turn property definitions into method definitions. -//------------------------------------------------------------------------- - - -// NormalizedBindingRhs records the r.h.s. of a binding after some munging just before type checking. -// NOTE: This is a bit of a mess. In the early implementation of F# we decided -// to have the parser convert "let f x = e" into -// "let f = fun x -> e". This is called "pushing" a pattern across to the right hand side. Complex -// patterns (e.g. non-tuple patterns) result in a computation on the right. -// However, this approach really isn't that great - especially since -// the language is now considerably more complex, e.g. we use -// type information from the first (but not the second) form in -// type inference for recursive bindings, and the first form -// may specify .NET attributes for arguments. There are still many -// relics of this approach around, e.g. the expression in BindingRhs -// below is of the second form. However, to extract relevant information -// we keep a record of the pats and optional explicit return type already pushed -// into expression so we can use any user-given type information from these -type NormalizedBindingRhs = - | NormalizedBindingRhs of SynSimplePats list * SynBindingReturnInfo option * SynExpr - -let PushOnePatternToRhs (cenv: cenv) isMember p (NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr)) = - let spats, rhsExpr = PushPatternToExpr cenv.synArgNameGenerator isMember p rhsExpr - NormalizedBindingRhs(spats :: spatsL, rtyOpt, rhsExpr) - -type NormalizedBindingPatternInfo = - NormalizedBindingPat of SynPat * NormalizedBindingRhs * SynValData * SynValTyparDecls - - -/// Represents a syntactic, unchecked binding after the resolution of the name resolution status of pattern -/// constructors and after "pushing" all complex patterns to the right hand side. -type NormalizedBinding = - | NormalizedBinding of - SynAccess option * - SynBindingKind * - bool * (* pseudo/mustinline value? *) - bool * (* mutable *) - SynAttribute list * - XmlDoc * - SynValTyparDecls * - SynValData * - SynPat * - NormalizedBindingRhs * - range * - SequencePointInfoForBinding - - -type IsObjExprBinding = - | ObjExprBinding - | ValOrMemberBinding - - - -module BindingNormalization = - /// Push a bunch of pats at once. They may contain patterns, e.g. let f (A x) (B y) = ... - /// In this case the semantics is let f a b = let A x = a in let B y = b - let private PushMultiplePatternsToRhs (cenv: cenv) isMember ps (NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr)) = - let spatsL2, rhsExpr = PushCurriedPatternsToExpr cenv.synArgNameGenerator rhsExpr.Range isMember ps rhsExpr - NormalizedBindingRhs(spatsL2@spatsL, rtyOpt, rhsExpr) - - - let private MakeNormalizedStaticOrValBinding cenv isObjExprBinding id vis typars args rhsExpr valSynData = - let (SynValData(memberFlagsOpt, _, _)) = valSynData - NormalizedBindingPat(mkSynPatVar vis id, PushMultiplePatternsToRhs cenv ((isObjExprBinding = ObjExprBinding) || Option.isSome memberFlagsOpt) args rhsExpr, valSynData, typars) - - let private MakeNormalizedInstanceMemberBinding cenv thisId memberId toolId vis m typars args rhsExpr valSynData = - NormalizedBindingPat(SynPat.InstanceMember(thisId, memberId, toolId, vis, m), PushMultiplePatternsToRhs cenv true args rhsExpr, valSynData, typars) - - let private NormalizeStaticMemberBinding cenv memberFlags valSynData id vis typars args m rhsExpr = - let (SynValData(_, valSynInfo, thisIdOpt)) = valSynData - if memberFlags.IsInstance then - // instance method without adhoc "this" argument - error(Error(FSComp.SR.tcInstanceMemberRequiresTarget(), m)) - match args, memberFlags.MemberKind with - | _, MemberKind.PropertyGetSet -> error(Error(FSComp.SR.tcUnexpectedPropertyInSyntaxTree(), m)) - | [], MemberKind.ClassConstructor -> error(Error(FSComp.SR.tcStaticInitializerRequiresArgument(), m)) - | [], MemberKind.Constructor -> error(Error(FSComp.SR.tcObjectConstructorRequiresArgument(), m)) - | [_], MemberKind.ClassConstructor - | [_], MemberKind.Constructor -> MakeNormalizedStaticOrValBinding cenv ValOrMemberBinding id vis typars args rhsExpr valSynData - // Static property declared using 'static member P = expr': transformed to a method taking a "unit" argument - // static property: these transformed into methods taking one "unit" argument - | [], MemberKind.Member -> - let memberFlags = {memberFlags with MemberKind = MemberKind.PropertyGet} - let valSynData = SynValData(Some memberFlags, valSynInfo, thisIdOpt) - NormalizedBindingPat(mkSynPatVar vis id, - PushOnePatternToRhs cenv true (SynPat.Const(SynConst.Unit, m)) rhsExpr, - valSynData, - typars) - | _ -> MakeNormalizedStaticOrValBinding cenv ValOrMemberBinding id vis typars args rhsExpr valSynData - - let private NormalizeInstanceMemberBinding cenv memberFlags valSynData thisId memberId (toolId: Ident option) vis typars args m rhsExpr = - let (SynValData(_, valSynInfo, thisIdOpt)) = valSynData - if not memberFlags.IsInstance then - // static method with adhoc "this" argument - error(Error(FSComp.SR.tcStaticMemberShouldNotHaveThis(), m)) - match args, memberFlags.MemberKind with - | _, MemberKind.ClassConstructor -> error(Error(FSComp.SR.tcExplicitStaticInitializerSyntax(), m)) - | _, MemberKind.Constructor -> error(Error(FSComp.SR.tcExplicitObjectConstructorSyntax(), m)) - | _, MemberKind.PropertyGetSet -> error(Error(FSComp.SR.tcUnexpectedPropertySpec(), m)) - // Instance property declared using 'x.Member': transformed to methods taking a "this" and a "unit" argument - // We push across the 'this' arg in mk_rec_binds - | [], MemberKind.Member -> - let memberFlags = {memberFlags with MemberKind = MemberKind.PropertyGet} - NormalizedBindingPat - (SynPat.InstanceMember(thisId, memberId, toolId, vis, m), - PushOnePatternToRhs cenv true (SynPat.Const(SynConst.Unit, m)) rhsExpr, - // Update the member info to record that this is a MemberKind.PropertyGet - SynValData(Some memberFlags, valSynInfo, thisIdOpt), - typars) - - | _ -> MakeNormalizedInstanceMemberBinding cenv thisId memberId toolId vis m typars args rhsExpr valSynData - - let private NormalizeBindingPattern cenv nameResolver isObjExprBinding (env: TcEnv) valSynData pat rhsExpr = - let ad = env.eAccessRights - let (SynValData(memberFlagsOpt, _, _)) = valSynData - let rec normPattern pat = - // One major problem with versions of F# prior to 1.9.x was that data constructors easily 'pollute' the namespace - // of available items, to the point that you can't even define a function with the same name as an existing union case. - match pat with - | SynPat.FromParseError(p, _) -> normPattern p - | SynPat.LongIdent (LongIdentWithDots(longId, _), toolId, tyargs, SynConstructorArgs.Pats args, vis, m) -> - let typars = match tyargs with None -> inferredTyparDecls | Some typars -> typars - match memberFlagsOpt with - | None -> - match ResolvePatternLongIdent cenv.tcSink nameResolver AllIdsOK true m ad env.eNameResEnv TypeNameResolutionInfo.Default longId with - | Item.NewDef id -> - if id.idText = opNameCons then - NormalizedBindingPat(pat, rhsExpr, valSynData, typars) - else - if isObjExprBinding = ObjExprBinding then - errorR(Deprecated(FSComp.SR.tcObjectExpressionFormDeprecated(), m)) - MakeNormalizedStaticOrValBinding cenv isObjExprBinding id vis typars args rhsExpr valSynData - | _ -> - error(Error(FSComp.SR.tcInvalidDeclaration(), m)) - - | Some memberFlags -> - match longId with - // x.Member in member binding patterns. - | [thisId;memberId] -> NormalizeInstanceMemberBinding cenv memberFlags valSynData thisId memberId toolId vis typars args m rhsExpr - | [memberId] -> NormalizeStaticMemberBinding cenv memberFlags valSynData memberId vis typars args m rhsExpr - | _ -> NormalizedBindingPat(pat, rhsExpr, valSynData, typars) - - // Object constructors are normalized in TcLetrec - // Here we are normalizing member definitions with simple (not long) ids, - // e.g. "static member x = 3" and "member x = 3" (instance with missing "this." comes through here. It is trapped and generates a warning) - | SynPat.Named (SynPat.Wild _, id, false, vis, m) - when - (match memberFlagsOpt with - | None -> false - | Some memberFlags -> - memberFlags.MemberKind <> MemberKind.Constructor && - memberFlags.MemberKind <> MemberKind.ClassConstructor) -> - NormalizeStaticMemberBinding cenv (Option.get memberFlagsOpt) valSynData id vis inferredTyparDecls [] m rhsExpr - - | SynPat.Typed(pat', x, y) -> - let (NormalizedBindingPat(pat'', e'', valSynData, typars)) = normPattern pat' - NormalizedBindingPat(SynPat.Typed(pat'', x, y), e'', valSynData, typars) - - | SynPat.Attrib(_, _, m) -> - error(Error(FSComp.SR.tcAttributesInvalidInPatterns(), m)) - - | _ -> - NormalizedBindingPat(pat, rhsExpr, valSynData, inferredTyparDecls) - normPattern pat - - let NormalizeBinding isObjExprBinding cenv (env: TcEnv) b = - match b with - | Binding (vis, bkind, isInline, isMutable, Attributes attrs, doc, valSynData, p, retInfo, rhsExpr, mBinding, spBind) -> - let (NormalizedBindingPat(pat, rhsExpr, valSynData, typars)) = - NormalizeBindingPattern cenv cenv.nameResolver isObjExprBinding env valSynData p (NormalizedBindingRhs ([], retInfo, rhsExpr)) - NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc.ToXmlDoc(), typars, valSynData, pat, rhsExpr, mBinding, spBind) - -//------------------------------------------------------------------------- -// input is: -// [] -// member x.P with get = fun () -> e -// --> -// member x.add_P< >(argName) = (e).AddHandler(argName) -// member x.remove_P< >(argName) = (e).RemoveHandler(argName) - -module EventDeclarationNormalization = - let ConvertSynInfo m (SynValInfo(argInfos, retInfo)) = - // reconstitute valSynInfo by adding the argument - let argInfos = - match argInfos with - | [[thisArgInfo];[]] -> [[thisArgInfo];SynInfo.unnamedTopArg] // instance property getter - | [[]] -> [SynInfo.unnamedTopArg] // static property getter - | _ -> error(BadEventTransformation m) - - // reconstitute valSynInfo - SynValInfo(argInfos, retInfo) - - // The property x.P becomes methods x.add_P and x.remove_P - let ConvertMemberFlags memberFlags = { memberFlags with MemberKind = MemberKind.Member } - - let private ConvertMemberFlagsOpt m memberFlagsOpt = - match memberFlagsOpt with - | Some memberFlags -> Some (ConvertMemberFlags memberFlags) - | _ -> error(BadEventTransformation m) - - let private ConvertSynData m valSynData = - let (SynValData(memberFlagsOpt, valSynInfo, thisIdOpt)) = valSynData - let memberFlagsOpt = ConvertMemberFlagsOpt m memberFlagsOpt - let valSynInfo = ConvertSynInfo m valSynInfo - SynValData(memberFlagsOpt, valSynInfo, thisIdOpt) - - let rec private RenameBindingPattern f declPattern = - match declPattern with - | SynPat.FromParseError(p, _) -> RenameBindingPattern f p - | SynPat.Typed(pat', _, _) -> RenameBindingPattern f pat' - | SynPat.Named (SynPat.Wild m1, id, x2, vis2, m) -> SynPat.Named (SynPat.Wild m1, ident(f id.idText, id.idRange), x2, vis2, m) - | SynPat.InstanceMember(thisId, id, toolId, vis2, m) -> SynPat.InstanceMember(thisId, ident(f id.idText, id.idRange), toolId, vis2, m) - | _ -> error(Error(FSComp.SR.tcOnlySimplePatternsInLetRec(), declPattern.Range)) - - /// Some F# bindings syntactically imply additional bindings, notably properties - /// annotated with [] - let GenerateExtraBindings cenv (bindingAttribs, binding) = - let (NormalizedBinding(vis1, bindingKind, isInline, isMutable, _, bindingXmlDoc, _synTyparDecls, valSynData, declPattern, bindingRhs, mBinding, spBind)) = binding - if CompileAsEvent cenv.g bindingAttribs then - - let MakeOne (prefix, target) = - let declPattern = RenameBindingPattern (fun s -> prefix + s) declPattern - let argName = "handler" - // modify the rhs and argument data - let bindingRhs, valSynData = - let (NormalizedBindingRhs(_, _, rhsExpr)) = bindingRhs - let m = rhsExpr.Range - // reconstitute valSynInfo by adding the argument - let valSynData = ConvertSynData m valSynData - - match rhsExpr with - // Detect 'fun () -> e' which results from the compilation of a property getter - | SynExpr.Lambda (_, _, SynSimplePats.SimplePats([], _), trueRhsExpr, m) -> - let rhsExpr = mkSynApp1 (SynExpr.DotGet (SynExpr.Paren (trueRhsExpr, range0, None, m), range0, LongIdentWithDots([ident(target, m)], []), m)) (SynExpr.Ident (ident(argName, m))) m - - // reconstitute rhsExpr - let bindingRhs = NormalizedBindingRhs([], None, rhsExpr) - - // add the argument to the expression - let bindingRhs = PushOnePatternToRhs cenv true (mkSynPatVar None (ident (argName, mBinding))) bindingRhs - - bindingRhs, valSynData - | _ -> - error(BadEventTransformation m) - - // reconstitute the binding - NormalizedBinding(vis1, bindingKind, isInline, isMutable, [], bindingXmlDoc, noInferredTypars, valSynData, declPattern, bindingRhs, mBinding, spBind) - - [ MakeOne ("add_", "AddHandler"); MakeOne ("remove_", "RemoveHandler") ] - else - [] - - - -/// Make a copy of the "this" type for a generic object type, e.g. List<'T> --> List<'?> for a fresh inference variable. -/// Also adjust the "this" type to take into account whether the type is a struct. -let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars = -#if EXTENDED_EXTENSION_MEMBERS // indicates if extension members can add additional constraints to type parameters - let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy = FreshenTyconRef m (if isExtrinsic then TyparRigidity.Flexible else rigid) tcref declaredTyconTypars -#else - let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy = FreshenTyconRef m rigid tcref declaredTyconTypars -#endif - // Struct members have a byref 'this' type (unless they are extrinsic extension members) - let thisTy = - if not isExtrinsic && tcref.IsStructOrEnumTycon then - if isRecdOrStructTyReadOnly cenv.g m objTy then - mkInByrefTy cenv.g objTy - else - mkByrefTy cenv.g objTy - else - objTy - tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy - - -// The early generalization rule of F# 2.0 can be unsound for members in generic types (Bug DevDiv2 10649). -// It gives rise to types like "Forall T. ?X -> ?Y" where ?X and ?Y are later discovered to involve T. -// -// For example: -// type C<'T>() = -// let mutable x = Unchecked.defaultof<_> // unknown inference variable ?X -// static member A() = x -// // At this point A is generalized early to "Forall T. unit -> ?X" -// static member B1() = C.A() -// // At this point during type inference, the return type of C.A() is '?X' -// // After type inference, the return type of C.A() is 'string' -// static member B2() = C.A() -// // At this point during type inference, the return type of C.A() is '?X' -// // After type inference, the return type of C.A() is 'int' -// member this.C() = (x: 'T) -// // At this point during type inference the type of 'x' is inferred to be 'T' -// -// Here "A" is generalized too early. -// -// Ideally we would simply generalize "A" later, when it is known to be -// sound. However, that can lead to other problems (e.g. some programs that typecheck today would no longer -// be accepted). As a result, we deal with this unsoundness by an adhoc post-type-checking -// consistency check for recursive uses of "A" with explicit instantiations within the recursive -// scope of "A". -let TcValEarlyGeneralizationConsistencyCheck cenv (env: TcEnv) (v: Val, vrec, tinst, vty, tau, m) = - match vrec with - | ValInRecScope isComplete when isComplete && not (isNil tinst) -> - //printfn "pushing post-inference check for '%s', vty = '%s'" v.DisplayName (DebugPrint.showType vty) - cenv.postInferenceChecks.Add (fun () -> - //printfn "running post-inference check for '%s'" v.DisplayName - //printfn "tau = '%s'" (DebugPrint.showType tau) - //printfn "vty = '%s'" (DebugPrint.showType vty) - let tpsorig, tau2 = tryDestForallTy cenv.g vty - //printfn "tau2 = '%s'" (DebugPrint.showType tau2) - if not (isNil tpsorig) then - let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g tpsorig - let tau3 = instType (mkTyparInst tpsorig tinst) tau2 - //printfn "tau3 = '%s'" (DebugPrint.showType tau3) - if not (AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m tau tau3) then - let txt = bufs (fun buf -> NicePrint.outputQualifiedValSpec env.DisplayEnv buf v) - error(Error(FSComp.SR.tcInferredGenericTypeGivesRiseToInconsistency(v.DisplayName, txt), m))) - | _ -> () - - -/// TcVal. "Use" a value, normally at a fresh type instance (unless optInst is -/// given). optInst is set when an explicit type instantiation is given, e.g. -/// Seq.empty -/// In this case the vrefFlags inside optInst are just NormalValUse. -/// -/// optInst is is also set when building the final call for a reference to an -/// F# object model member, in which case the optInst is the type instantiation -/// inferred by member overload resolution, and vrefFlags indicate if the -/// member is being used in a special way, i.e. may be one of: -/// | CtorValUsedAsSuperInit "inherit Panel()" -/// | CtorValUsedAsSelfInit "new() = new OwnType(3)" -/// | VSlotDirectCall "base.OnClick(eventArgs)" -let TcVal checkAttributes cenv env tpenv (vref: ValRef) optInst optAfterResolution m = - let (tpsorig, _, _, _, tinst, _) as res = - let v = vref.Deref - let vrec = v.RecursiveValInfo - v.SetHasBeenReferenced() - CheckValAccessible m env.eAccessRights vref - if checkAttributes then - CheckValAttributes cenv.g vref m |> CommitOperationResult - let vty = vref.Type - // byref-typed values get dereferenced - if isByrefTy cenv.g vty then - let isSpecial = true - [], mkAddrGet m vref, isSpecial, destByrefTy cenv.g vty, [], tpenv - else - match v.LiteralValue with - | Some c -> - // Literal values go to constants - let isSpecial = true - // The value may still be generic, e.g. - // [] - // let Null = null - let tpsorig, _, tinst, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty - tpsorig, Expr.Const (c, m, tau), isSpecial, tau, tinst, tpenv - - | None -> - // References to 'this' in classes get dereferenced from their implicit reference cell and poked - if v.BaseOrThisInfo = CtorThisVal && isRefCellTy cenv.g vty then - let exprForVal = exprForValRef m vref - //if AreWithinCtorPreConstruct env then - // warning(SelfRefObjCtor(AreWithinImplicitCtor env, m)) - - let ty = destRefCellTy cenv.g vty - let isSpecial = true - [], mkCallCheckThis cenv.g m ty (mkRefCellGet cenv.g m ty exprForVal), isSpecial, ty, [], tpenv - else - // Instantiate the value - let tpsorig, vrefFlags, tinst, tau, tpenv = - // Have we got an explicit instantiation? - match optInst with - // No explicit instantiation (the normal case) - | None -> - if HasFSharpAttribute cenv.g cenv.g.attrib_RequiresExplicitTypeArgumentsAttribute v.Attribs then - errorR(Error(FSComp.SR.tcFunctionRequiresExplicitTypeArguments(v.DisplayName), m)) - - match vrec with - | ValInRecScope false -> - let tpsorig, tau = vref.TypeScheme - let tinst = tpsorig |> List.map mkTyparTy - tpsorig, NormalValUse, tinst, tau, tpenv - | ValInRecScope true - | ValNotInRecScope -> - let tpsorig, _, tinst, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty - tpsorig, NormalValUse, tinst, tau, tpenv - - // If we have got an explicit instantiation then use that - | Some(vrefFlags, checkTys) -> - let checkInst (tinst: TypeInst) = - if not v.IsMember && not v.PermitsExplicitTypeInstantiation && not (List.isEmpty tinst) && not (List.isEmpty v.Typars) then - warning(Error(FSComp.SR.tcDoesNotAllowExplicitTypeArguments(v.DisplayName), m)) - match vrec with - | ValInRecScope false -> - let tpsorig, tau = vref.TypeScheme - let (tinst: TypeInst), tpenv = checkTys tpenv (tpsorig |> List.map (fun tp -> tp.Kind)) - checkInst tinst - if tpsorig.Length <> tinst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tpsorig.Length, tinst.Length), m)) - let tau2 = instType (mkTyparInst tpsorig tinst) tau - (tpsorig, tinst) ||> List.iter2 (fun tp ty -> - try UnifyTypes cenv env m (mkTyparTy tp) ty - with _ -> error (Recursion(env.DisplayEnv, v.Id, tau2, tau, m))) - tpsorig, vrefFlags, tinst, tau2, tpenv - | ValInRecScope true - | ValNotInRecScope -> - let tpsorig, tps, tptys, tau = FreshenPossibleForallTy cenv.g m TyparRigidity.Flexible vty - //dprintfn "After Freshen: tau = %s" (Layout.showL (typeL tau)) - let (tinst: TypeInst), tpenv = checkTys tpenv (tps |> List.map (fun tp -> tp.Kind)) - checkInst tinst - //dprintfn "After Check: tau = %s" (Layout.showL (typeL tau)) - if tptys.Length <> tinst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tps.Length, tinst.Length), m)) - List.iter2 (UnifyTypes cenv env m) tptys tinst - TcValEarlyGeneralizationConsistencyCheck cenv env (v, vrec, tinst, vty, tau, m) - - //dprintfn "After Unify: tau = %s" (Layout.showL (typeL tau)) - tpsorig, vrefFlags, tinst, tau, tpenv - - let exprForVal = Expr.Val (vref, vrefFlags, m) - let exprForVal = mkTyAppExpr m (exprForVal, vty) tinst - let isSpecial = - (match vrefFlags with NormalValUse | PossibleConstrainedCall _ -> false | _ -> true) || - valRefEq cenv.g vref cenv.g.splice_expr_vref || - valRefEq cenv.g vref cenv.g.splice_raw_expr_vref - - let exprForVal = RecordUseOfRecValue cenv vrec vref exprForVal m - - tpsorig, exprForVal, isSpecial, tau, tinst, tpenv - - match optAfterResolution with - | Some (AfterResolution.RecordResolution(_, callSink, _, _)) -> callSink (mkTyparInst tpsorig tinst) - | Some AfterResolution.DoNothing | None -> () - res - -/// simplified version of TcVal used in calls to BuildMethodCall (typrelns.fs) -/// this function is used on typechecking step for making calls to provided methods and on optimization step (for the same purpose). -let LightweightTcValForUsingInBuildMethodCall g (vref: ValRef) vrefFlags (vrefTypeInst: TTypes) m = - let v = vref.Deref - let vty = vref.Type - // byref-typed values get dereferenced - if isByrefTy g vty then - mkAddrGet m vref, destByrefTy g vty - else - match v.LiteralValue with - | Some c -> - let _, _, _, tau = FreshenPossibleForallTy g m TyparRigidity.Flexible vty - Expr.Const (c, m, tau), tau - | None -> - // Instantiate the value - let tau = - // If we have got an explicit instantiation then use that - let _, tps, tptys, tau = FreshenPossibleForallTy g m TyparRigidity.Flexible vty - if tptys.Length <> vrefTypeInst.Length then error(Error(FSComp.SR.tcTypeParameterArityMismatch(tps.Length, vrefTypeInst.Length), m)) - instType (mkTyparInst tps vrefTypeInst) tau - - let exprForVal = Expr.Val (vref, vrefFlags, m) - let exprForVal = mkTyAppExpr m (exprForVal, vty) vrefTypeInst - exprForVal, tau - -/// Mark points where we decide whether an expression will support automatic -/// decondensation or not. This is somewhat a relic of a previous implementation of decondensation and could -/// be removed - -type ApplicableExpr = - | ApplicableExpr of - // context - cenv * - // the function-valued expression - Expr * - // is this the first in an application series - bool - - member x.Range = - match x with - | ApplicableExpr (_, e, _) -> e.Range - - member x.Type = - match x with - | ApplicableExpr (cenv, e, _) -> tyOfExpr cenv.g e - - member x.SupplyArgument(e2, m) = - let (ApplicableExpr (cenv, fe, first)) = x - let combinedExpr = - match fe with - | Expr.App (e1, e1ty, tyargs1, args1, e1m) when - (not first || isNil args1) && - (not (isForallTy cenv.g e1ty) || isFunTy cenv.g (applyTys cenv.g e1ty (tyargs1, args1))) -> - Expr.App (e1, e1ty, tyargs1, args1@[e2], unionRanges e1m m) - | _ -> - Expr.App (fe, tyOfExpr cenv.g fe, [], [e2], m) - ApplicableExpr(cenv, combinedExpr, false) - - member x.Expr = - match x with - | ApplicableExpr(_, e, _) -> e - -let MakeApplicableExprNoFlex cenv expr = - ApplicableExpr (cenv, expr, true) - -/// This function reverses the effect of condensation for a named function value (indeed it can -/// work for any expression, though we only invoke it immediately after a call to TcVal). -/// -/// De-condensation is determined BEFORE any arguments are checked. Thus -/// let f (x:'a) (y:'a) = () -/// -/// f (new obj()) "string" -/// -/// does not type check (the argument instantiates 'a to "obj" but there is no flexibility on the -/// second argument position. -/// -/// De-condensation is applied AFTER taking into account an explicit type instantiation. This -/// let f<'a> (x:'a) = () -/// -/// f("string)" -/// -/// will type check but -/// -/// Sealed types and 'obj' do not introduce generic flexibility when functions are used as first class -/// values. -/// -/// For 'obj' this is because introducing this flexibility would NOT be the reverse of condensation, -/// since we don't condense -/// f: 'a -> unit -/// to -/// f: obj -> unit -/// -/// We represent the flexibility in the TAST by leaving a function-to-function coercion node in the tree -/// This "special" node is immediately eliminated by the use of IteratedFlexibleAdjustArityOfLambdaBody as soon as we -/// first transform the tree (currently in optimization) - -let MakeApplicableExprWithFlex cenv (env: TcEnv) expr = - let g = cenv.g - let exprTy = tyOfExpr g expr - let m = expr.Range - - let isNonFlexibleType ty = isSealedTy g ty - - let argTys, retTy = stripFunTy g exprTy - let curriedActualTypes = argTys |> List.map (tryDestRefTupleTy g) - if (curriedActualTypes.IsEmpty || - curriedActualTypes |> List.exists (List.exists (isByrefTy g)) || - curriedActualTypes |> List.forall (List.forall isNonFlexibleType)) then - - ApplicableExpr (cenv, expr, true) - else - let curriedFlexibleTypes = - curriedActualTypes |> List.mapSquared (fun actualType -> - if isNonFlexibleType actualType - then actualType - else - let flexibleType = NewInferenceType () - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace actualType flexibleType - flexibleType) - - // Create a coercion to represent the expansion of the application - let expr = mkCoerceExpr (expr, mkIteratedFunTy (List.map (mkRefTupledTy g) curriedFlexibleTypes) retTy, m, exprTy) - ApplicableExpr (cenv, expr, true) - - -/// Checks, warnings and constraint assertions for downcasts -let TcRuntimeTypeTest isCast isOperator cenv denv m tgtTy srcTy = - let g = cenv.g - if TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgtTy srcTy then - warning(TypeTestUnnecessary m) - - if isTyparTy g srcTy && not (destTyparTy g srcTy).IsCompatFlex then - error(IndeterminateRuntimeCoercion(denv, srcTy, tgtTy, m)) - - if isSealedTy g srcTy then - error(RuntimeCoercionSourceSealed(denv, srcTy, m)) - - if isSealedTy g tgtTy || isTyparTy g tgtTy || not (isInterfaceTy g srcTy) then - if isCast then - AddCxTypeMustSubsumeType (ContextInfo.RuntimeTypeTest isOperator) denv cenv.css m NoTrace srcTy tgtTy - else - AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace srcTy tgtTy - - if isErasedType g tgtTy then - if isCast then - warning(Error(FSComp.SR.tcTypeCastErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g tgtTy)), m)) - else - error(Error(FSComp.SR.tcTypeTestErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g tgtTy)), m)) - else - getErasedTypes g tgtTy |> - List.iter (fun ety -> if isMeasureTy g ety - then warning(Error(FSComp.SR.tcTypeTestLosesMeasures(NicePrint.minimalStringOfType denv ety), m)) - else warning(Error(FSComp.SR.tcTypeTestLossy(NicePrint.minimalStringOfType denv ety, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll g ety)), m))) - -/// Checks, warnings and constraint assertions for upcasts -let TcStaticUpcast cenv denv m tgtTy srcTy = - if isTyparTy cenv.g tgtTy then - if not (destTyparTy cenv.g tgtTy).IsCompatFlex then - error(IndeterminateStaticCoercion(denv, srcTy, tgtTy, m)) - //else warning(UpcastUnnecessary m) - - if isSealedTy cenv.g tgtTy && not (isTyparTy cenv.g tgtTy) then - warning(CoercionTargetSealed(denv, tgtTy, m)) - - if typeEquiv cenv.g srcTy tgtTy then - warning(UpcastUnnecessary m) - - AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace tgtTy srcTy - -let BuildPossiblyConditionalMethodCall cenv env isMutable m isProp minfo valUseFlags minst objArgs args = - - let conditionalCallDefineOpt = TryFindMethInfoStringAttribute cenv.g m cenv.g.attrib_ConditionalAttribute minfo - - match conditionalCallDefineOpt, cenv.conditionalDefines with - | Some d, Some defines when not (List.contains d defines) -> - - // Methods marked with 'Conditional' must return 'unit' - UnifyTypes cenv env m cenv.g.unit_ty (minfo.GetFSharpReturnTy(cenv.amap, m, minst)) - mkUnit cenv.g m, cenv.g.unit_ty - - | _ -> -#if !NO_EXTENSIONTYPING - match minfo with - | ProvidedMeth(_, mi, _, _) -> - // BuildInvokerExpressionForProvidedMethodCall converts references to F# intrinsics back to values - // and uses TcVal to do this. However we don't want to check attributes again for provided references to values, - // so we pass 'false' for 'checkAttributes'. - let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g - let _, retExpt, retTy = ProvidedMethodCalls.BuildInvokerExpressionForProvidedMethodCall tcVal (cenv.g, cenv.amap, mi, objArgs, isMutable, isProp, valUseFlags, args, m) - retExpt, retTy - - | _ -> -#endif - let tcVal valref valUse ttypes m = - let _, a, _, b, _, _ = TcVal true cenv env emptyUnscopedTyparEnv valref (Some (valUse, (fun x _ -> ttypes, x))) None m - a, b - BuildMethodCall tcVal cenv.g cenv.amap isMutable m isProp minfo valUseFlags minst objArgs args - - -let TryFindIntrinsicOrExtensionMethInfo collectionSettings (cenv: cenv) (env: TcEnv) m ad nm ty = - AllMethInfosOfTypeInScope collectionSettings cenv.infoReader env.NameEnv (Some nm) ad IgnoreOverrides m ty - -let TryFindFSharpSignatureInstanceGetterProperty (cenv: cenv) (env: TcEnv) m nm ty (sigTys: TType list) = - TryFindPropInfo cenv.infoReader m env.AccessRights nm ty - |> List.tryFind (fun propInfo -> - not propInfo.IsStatic && propInfo.HasGetter && - ( - match propInfo.GetterMethod.GetParamTypes(cenv.amap, m, []) with - | [] -> false - | argTysList -> - - let argTys = (argTysList |> List.reduce (@)) @ [ propInfo.GetterMethod.GetFSharpReturnTy(cenv.amap, m, []) ] in - if argTys.Length <> sigTys.Length then - false - else - (argTys, sigTys) - ||> List.forall2 (typeEquiv cenv.g) - ) - ) - -/// Build the 'test and dispose' part of a 'use' statement -let BuildDisposableCleanup cenv env m (v: Val) = - v.SetHasBeenReferenced() - let ad = env.eAccessRights - let disposeMethod = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Dispose" cenv.g.system_IDisposable_ty with - | [x] -> x - | _ -> error(InternalError(FSComp.SR.tcCouldNotFindIDisposable(), m)) - - - // For struct types the test is simpler: we can determine if IDisposable is supported, and even when it is, we can avoid doing the type test - // Note this affects the elaborated form seen by quotations etc. - if isStructTy cenv.g v.Type then - if TypeFeasiblySubsumesType 0 cenv.g cenv.amap m cenv.g.system_IDisposable_ty CanCoerce v.Type then - // We can use NeverMutates here because the variable is going out of scope, there is no need to take a defensive - // copy of it. - let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false disposeMethod NormalValUse [] [exprForVal v.Range v] [] - disposeExpr - else - mkUnit cenv.g m - else - let disposeObjVar, disposeObjExpr = Tastops.mkCompGenLocal m "objectToDispose" cenv.g.system_IDisposable_ty - let disposeExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false disposeMethod NormalValUse [] [disposeObjExpr] [] - let inpe = mkCoerceExpr(exprForVal v.Range v, cenv.g.obj_ty, m, v.Type) - mkIsInstConditional cenv.g m cenv.g.system_IDisposable_ty inpe disposeObjVar disposeExpr (mkUnit cenv.g m) - -/// Build call to get_OffsetToStringData as part of 'fixed' -let BuildOffsetToStringData cenv env m = - let ad = env.eAccessRights - let offsetToStringDataMethod = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_OffsetToStringData" cenv.g.system_RuntimeHelpers_ty with - | [x] -> x - | _ -> error(Error(FSComp.SR.tcCouldNotFindOffsetToStringData(), m)) - - let offsetExpr, _ = BuildPossiblyConditionalMethodCall cenv env NeverMutates m false offsetToStringDataMethod NormalValUse [] [] [] - offsetExpr - -let BuildILFieldGet g amap m objExpr (finfo: ILFieldInfo) = - let fref = finfo.ILFieldRef - let isValueType = finfo.IsValueType - let valu = if isValueType then AsValue else AsObject - let tinst = finfo.TypeInst - let fieldType = finfo.FieldType (amap, m) -#if !NO_EXTENSIONTYPING - let ty = tyOfExpr g objExpr - match finfo with - | ProvidedField _ when (isErasedType g ty) -> - // we know it's accessible, and there are no attributes to check for now... - match finfo.LiteralValue with - | None -> - error (Error(FSComp.SR.tcTPFieldMustBeLiteral(), m)) - | Some lit -> - Expr.Const (TcFieldInit m lit, m, fieldType) - | _ -> -#endif - let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g isValueType false NeverMutates objExpr None m - // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm - // This ensures we always get the type instantiation right when doing this from - // polymorphic code, after inlining etc. * - let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) - // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. - wrap (mkAsmExpr (([ mkNormalLdfld fspec ] @ (if finfo.IsInitOnly then [ AI_nop ] else [])), tinst, [objExpr], [fieldType], m)) - -let BuildILFieldSet g m objExpr (finfo: ILFieldInfo) argExpr = - let fref = finfo.ILFieldRef - let isValueType = finfo.IsValueType - let valu = if isValueType then AsValue else AsObject - let tinst = finfo.TypeInst - // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm - // This ensures we always get the type instantiation right when doing this from - // polymorphic code, after inlining etc. * - let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) - if finfo.IsInitOnly then error (Error (FSComp.SR.tcFieldIsReadonly(), m)) - let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g isValueType false DefinitelyMutates objExpr None m - wrap (mkAsmExpr ([ mkNormalStfld fspec ], tinst, [objExpr; argExpr], [], m)) - -let BuildILStaticFieldSet m (finfo: ILFieldInfo) argExpr = - let fref = finfo.ILFieldRef - let isValueType = finfo.IsValueType - let valu = if isValueType then AsValue else AsObject - let tinst = finfo.TypeInst - // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm - // This ensures we always get the type instantiation right when doing this from - // polymorphic code, after inlining etc. - let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) - if finfo.IsInitOnly then error (Error (FSComp.SR.tcFieldIsReadonly(), m)) - mkAsmExpr ([ mkNormalStsfld fspec ], tinst, [argExpr], [], m) - -let BuildRecdFieldSet g m objExpr (rfinfo: RecdFieldInfo) argExpr = - let tgtTy = rfinfo.DeclaringType - let valu = isStructTy g tgtTy - let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, m, tyOfExpr g objExpr) - let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m - wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) ) - -//------------------------------------------------------------------------- -// Helpers dealing with named and optional args at callsites -//------------------------------------------------------------------------- - -let (|BinOpExpr|_|) e = - match e with - | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent opId, a, _), b, _) -> Some (opId, a, b) - | _ -> None - -let (|SimpleEqualsExpr|_|) e = - match e with - | BinOpExpr(opId, a, b) when opId.idText = opNameEquals -> Some (a, b) - | _ -> None - -// For join clauses that join on nullable, we syntactically insert the creation of nullable values on the appropriate side of the condition, -// then pull the syntax apart again -let (|JoinRelation|_|) cenv env (e: SynExpr) = - let m = e.Range - let ad = env.eAccessRights - - let isOpName opName vref s = - (s = opName) && - match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.eNameResEnv TypeNameResolutionInfo.Default [ident(opName, m)] with - | Item.Value vref2, [] -> valRefEq cenv.g vref vref2 - | _ -> false - - match e with - | BinOpExpr(opId, a, b) when isOpName opNameEquals cenv.g.equals_operator_vref opId.idText -> Some (a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameEqualsNullable cenv.g.equals_nullable_operator_vref opId.idText -> - - let a = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet a.Range [MangledGlobalName;"System"] "Nullable", a, a.Range) - Some (a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameNullableEquals cenv.g.nullable_equals_operator_vref opId.idText -> - - let b = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet b.Range [MangledGlobalName;"System"] "Nullable", b, b.Range) - Some (a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameNullableEqualsNullable cenv.g.nullable_equals_nullable_operator_vref opId.idText -> - - Some (a, b) - - | _ -> None - - -/// Detect a named argument at a callsite -let TryGetNamedArg e = - match e with - | SimpleEqualsExpr(LongOrSingleIdent(isOpt, LongIdentWithDots([a], _), None, _), b) -> Some(isOpt, a, b) - | _ -> None - -let inline IsNamedArg e = - match e with - | SimpleEqualsExpr(LongOrSingleIdent(_, LongIdentWithDots([_], _), None, _), _) -> true - | _ -> false - -/// Get the method arguments at a callsite, taking into account named and optional arguments -let GetMethodArgs arg = - let args = - match arg with - | SynExpr.Const (SynConst.Unit, _) -> [] - | SynExprParen(SynExpr.Tuple (false, args, _, _), _, _, _) | SynExpr.Tuple (false, args, _, _) -> args - | SynExprParen(arg, _, _, _) | arg -> [arg] - let unnamedCallerArgs, namedCallerArgs = - args |> List.takeUntil IsNamedArg - let namedCallerArgs = - namedCallerArgs - |> List.choose (fun e -> - match TryGetNamedArg e with - | None -> - // ignore errors to avoid confusing error messages in cases like foo(a = 1, ) - // do not abort overload resolution in case if named arguments are mixed with errors - match e with - | SynExpr.ArbitraryAfterError _ -> None - | _ -> error(Error(FSComp.SR.tcNameArgumentsMustAppearLast(), e.Range)) - | namedArg -> namedArg) - unnamedCallerArgs, namedCallerArgs - - -//------------------------------------------------------------------------- -// Helpers dealing with pattern match compilation -//------------------------------------------------------------------------- - -let CompilePatternForMatch cenv (env: TcEnv) mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy = - let dtree, targets = CompilePattern cenv.g env.DisplayEnv cenv.amap mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy - mkAndSimplifyMatch NoSequencePointAtInvisibleBinding mExpr matchm resultTy dtree targets - -/// Compile a pattern -let CompilePatternForMatchClauses cenv env mExpr matchm warnOnUnused actionOnFailure inputExprOpt inputTy resultTy tclauses = - // Avoid creating a dummy in the common cases where we are about to bind a name for the expression - // CLEANUP: avoid code duplication with code further below, i.e.all callers should call CompilePatternForMatch - match tclauses with - | [TClause(TPat_as (pat1, PBind (asVal, TypeScheme(generalizedTypars, _)), _), None, TTarget(vs, e, spTarget), m2)] -> - let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (asVal, generalizedTypars, None) [TClause(pat1, None, TTarget(ListSet.remove valEq asVal vs, e, spTarget), m2)] inputTy resultTy - asVal, expr - | _ -> - let matchValueTmp, _ = Tastops.mkCompGenLocal mExpr "matchValue" inputTy - let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (matchValueTmp, [], inputExprOpt) tclauses inputTy resultTy - matchValueTmp, expr - -//------------------------------------------------------------------------- -// Helpers dealing with sequence expressions -//------------------------------------------------------------------------- - - -/// Get the fragmentary expressions resulting from turning -/// an expression into an enumerable value, e.g. at 'for' loops - -// localAlloc is relevant if the enumerator is a mutable struct and indicates -// if the enumerator can be allocated as a mutable local variable -let AnalyzeArbitraryExprAsEnumerable cenv (env: TcEnv) localAlloc m exprty expr = - let ad = env.eAccessRights - - let err k ty = - let txt = NicePrint.minimalStringOfType env.DisplayEnv ty - let msg = if k then FSComp.SR.tcTypeCannotBeEnumerated txt else FSComp.SR.tcEnumTypeCannotBeEnumerated txt - Exception(Error(msg, m)) - - let findMethInfo k m nm ty = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad nm ty with - | [] -> err k ty - | res :: _ -> Result res - - // Ensure there are no curried arguments, and indeed no arguments at all - let hasArgs (minfo: MethInfo) minst = - match minfo.GetParamTypes(cenv.amap, m, minst) with - | [[]] -> false - | _ -> true - - let tryType (exprToSearchForGetEnumeratorAndItem, tyToSearchForGetEnumeratorAndItem) = - match findMethInfo true m "GetEnumerator" tyToSearchForGetEnumeratorAndItem with - | Exception e -> Exception e - | Result getEnumerator_minfo -> - - let getEnumerator_minst = FreshenMethInfo m getEnumerator_minfo - let retTypeOfGetEnumerator = getEnumerator_minfo.GetFSharpReturnTy(cenv.amap, m, getEnumerator_minst) - if hasArgs getEnumerator_minfo getEnumerator_minst then err true tyToSearchForGetEnumeratorAndItem else - - match findMethInfo false m "MoveNext" retTypeOfGetEnumerator with - | Exception e -> Exception e - | Result moveNext_minfo -> - - let moveNext_minst = FreshenMethInfo m moveNext_minfo - let retTypeOfMoveNext = moveNext_minfo.GetFSharpReturnTy(cenv.amap, m, moveNext_minst) - if not (typeEquiv cenv.g cenv.g.bool_ty retTypeOfMoveNext) then err false retTypeOfGetEnumerator else - if hasArgs moveNext_minfo moveNext_minst then err false retTypeOfGetEnumerator else - - match findMethInfo false m "get_Current" retTypeOfGetEnumerator with - | Exception e -> Exception e - | Result get_Current_minfo -> - - let get_Current_minst = FreshenMethInfo m get_Current_minfo - if hasArgs get_Current_minfo get_Current_minst then err false retTypeOfGetEnumerator else - let enumElemTy = get_Current_minfo.GetFSharpReturnTy(cenv.amap, m, get_Current_minst) - - // Compute the element type of the strongly typed enumerator - // - // Like C#, we detect the 'GetEnumerator' pattern for .NET version 1.x abstractions that don't - // support the correct generic interface. However unlike C# we also go looking for a 'get_Item' or 'Item' method - // with a single integer indexer argument to try to get a strong type for the enumeration should the Enumerator - // not provide anything useful. To enable interop with some legacy COM APIs, - // the single integer indexer argument is allowed to have type 'object'. - - let enumElemTy = - - if isObjTy cenv.g enumElemTy then - // Look for an 'Item' property, or a set of these with consistent return types - let allEquivReturnTypes (minfo: MethInfo) (others: MethInfo list) = - let returnTy = minfo.GetFSharpReturnTy(cenv.amap, m, []) - others |> List.forall (fun other -> typeEquiv cenv.g (other.GetFSharpReturnTy(cenv.amap, m, [])) returnTy) - - let isInt32OrObjectIndexer (minfo: MethInfo) = - match minfo.GetParamTypes(cenv.amap, m, []) with - | [[ty]] -> - // e.g. MatchCollection - typeEquiv cenv.g cenv.g.int32_ty ty || - // e.g. EnvDTE.Documents.Item - typeEquiv cenv.g cenv.g.obj_ty ty - | _ -> false - - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "get_Item" tyToSearchForGetEnumeratorAndItem with - | (minfo :: others) when (allEquivReturnTypes minfo others && - List.exists isInt32OrObjectIndexer (minfo :: others)) -> - minfo.GetFSharpReturnTy(cenv.amap, m, []) - - | _ -> - - // Some types such as XmlNodeList have only an Item method - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Item" tyToSearchForGetEnumeratorAndItem with - | (minfo :: others) when (allEquivReturnTypes minfo others && - List.exists isInt32OrObjectIndexer (minfo :: others)) -> - minfo.GetFSharpReturnTy(cenv.amap, m, []) - - | _ -> enumElemTy - else - enumElemTy - - let isEnumeratorTypeStruct = isStructTy cenv.g retTypeOfGetEnumerator - let originalRetTypeOfGetEnumerator = retTypeOfGetEnumerator - - let (enumeratorVar, enumeratorExpr), retTypeOfGetEnumerator = - if isEnumeratorTypeStruct then - if localAlloc then - Tastops.mkMutableCompGenLocal m "enumerator" retTypeOfGetEnumerator, retTypeOfGetEnumerator - else - let refCellTyForRetTypeOfGetEnumerator = mkRefCellTy cenv.g retTypeOfGetEnumerator - let v, e = Tastops.mkMutableCompGenLocal m "enumerator" refCellTyForRetTypeOfGetEnumerator - (v, mkRefCellGet cenv.g m retTypeOfGetEnumerator e), refCellTyForRetTypeOfGetEnumerator - - else - Tastops.mkCompGenLocal m "enumerator" retTypeOfGetEnumerator, retTypeOfGetEnumerator - - let getEnumExpr, getEnumTy = - let (getEnumExpr, getEnumTy) as res = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates m false getEnumerator_minfo NormalValUse getEnumerator_minst [exprToSearchForGetEnumeratorAndItem] [] - if not isEnumeratorTypeStruct || localAlloc then res - else - // wrap enumerators that are represented as mutable structs into ref cells - let getEnumExpr = mkRefCell cenv.g m originalRetTypeOfGetEnumerator getEnumExpr - let getEnumTy = mkRefCellTy cenv.g getEnumTy - getEnumExpr, getEnumTy - - let guardExpr, guardTy = BuildPossiblyConditionalMethodCall cenv env DefinitelyMutates m false moveNext_minfo NormalValUse moveNext_minst [enumeratorExpr] [] - let currentExpr, currentTy = BuildPossiblyConditionalMethodCall cenv env DefinitelyMutates m true get_Current_minfo NormalValUse get_Current_minst [enumeratorExpr] [] - let currentExpr = mkCoerceExpr(currentExpr, enumElemTy, currentExpr.Range, currentTy) - let currentExpr, enumElemTy = - // Implicitly dereference byref for expr 'for x in ...' - if isByrefTy cenv.g enumElemTy then - let expr = mkDerefAddrExpr m currentExpr currentExpr.Range enumElemTy - expr, destByrefTy cenv.g enumElemTy - else - currentExpr, enumElemTy - - Result(enumeratorVar, enumeratorExpr, retTypeOfGetEnumerator, enumElemTy, getEnumExpr, getEnumTy, guardExpr, guardTy, currentExpr) - - // First try the original known static type - match (if isArray1DTy cenv.g exprty then Exception (Failure "") else tryType (expr, exprty)) with - | Result res -> res - | Exception e -> - - let probe ty = - if (AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m ty exprty) then - match tryType (mkCoerceExpr(expr, ty, expr.Range, exprty), ty) with - | Result res -> Some res - | Exception e -> - PreserveStackTrace e - raise e - else None - - // Next try to typecheck the thing as a sequence - let enumElemTy = NewInferenceType () - let exprTyAsSeq = mkSeqTy cenv.g enumElemTy - - match probe exprTyAsSeq with - | Some res -> res - | None -> - let ienumerable = mkAppTy cenv.g.tcref_System_Collections_IEnumerable [] - match probe ienumerable with - | Some res -> res - | None -> - PreserveStackTrace e - raise e - - -// Used inside sequence expressions -let ConvertArbitraryExprToEnumerable cenv ty (env: TcEnv) (expr: Expr) = - let m = expr.Range - let enumElemTy = NewInferenceType () - if AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m ( mkSeqTy cenv.g enumElemTy) ty then - expr, enumElemTy - else - let enumerableVar, enumerableExpr = mkCompGenLocal m "inputSequence" ty - let enumeratorVar, _, retTypeOfGetEnumerator, enumElemTy, getEnumExpr, _, guardExpr, guardTy, betterCurrentExpr = - AnalyzeArbitraryExprAsEnumerable cenv env false m ty enumerableExpr - - let expr = - mkCompGenLet m enumerableVar expr - (mkCallSeqOfFunctions cenv.g m retTypeOfGetEnumerator enumElemTy - (mkUnitDelayLambda cenv.g m getEnumExpr) - (mkLambda m enumeratorVar (guardExpr, guardTy)) - (mkLambda m enumeratorVar (betterCurrentExpr, enumElemTy))) - expr, enumElemTy - -let mkSeqEmpty cenv env m genTy = - // We must discover the 'zero' of the monadic algebra being generated in order to compile failing matches. - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - mkCallSeqEmpty cenv.g m genResultTy - -let mkSeqCollect cenv env m enumElemTy genTy lam enumExpr = - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr - mkCallSeqCollect cenv.g m enumElemTy genResultTy lam enumExpr - -let mkSeqUsing cenv (env: TcEnv) m resourceTy genTy resourceExpr lam = - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace cenv.g.system_IDisposable_ty resourceTy - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - mkCallSeqUsing cenv.g m resourceTy genResultTy resourceExpr lam - -let mkSeqDelay cenv env m genTy lam = - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - mkCallSeqDelay cenv.g m genResultTy (mkUnitDelayLambda cenv.g m lam) - - -let mkSeqAppend cenv env m genTy e1 e2 = - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - let e1 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e1) e1 - let e2 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e2) e2 - mkCallSeqAppend cenv.g m genResultTy e1 e2 - -let mkSeqFromFunctions cenv env m genTy e1 e2 = - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - let e2 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e2) e2 - mkCallSeqGenerated cenv.g m genResultTy e1 e2 - -let mkSeqFinally cenv env m genTy e1 e2 = - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genTy (mkSeqTy cenv.g genResultTy) - let e1 = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g genResultTy) (tyOfExpr cenv.g e1) e1 - mkCallSeqFinally cenv.g m genResultTy e1 e2 - -let mkSeqExprMatchClauses (pat', vspecs) innerExpr = - [TClause(pat', None, TTarget(vspecs, innerExpr, SequencePointAtTarget), pat'.Range) ] - -let compileSeqExprMatchClauses cenv env inputExprMark (pat: Pattern, vspecs) innerExpr inputExprOpt bindPatTy genInnerTy = - let patMark = pat.Range - let tclauses = mkSeqExprMatchClauses (pat, vspecs) innerExpr - CompilePatternForMatchClauses cenv env inputExprMark patMark false ThrowIncompleteMatchException inputExprOpt bindPatTy genInnerTy tclauses - -let elimFastIntegerForLoop (spBind, id, start, dir, finish, innerExpr, m) = - let pseudoEnumExpr = - if dir then mkSynInfix m start ".." finish - else mkSynTrifix m ".. .." start (SynExpr.Const (SynConst.Int32 -1, start.Range)) finish - SynExpr.ForEach (spBind, SeqExprOnly false, true, mkSynPatVar None id, pseudoEnumExpr, innerExpr, m) - -let (|ExprAsPat|_|) (f: SynExpr) = - match f with - | SingleIdent v1 | SynExprParen(SingleIdent v1, _, _, _) -> Some (mkSynPatVar None v1) - | SynExprParen(SynExpr.Tuple (false, elems, _, _), _, _, _) -> - let elems = elems |> List.map (|SingleIdent|_|) - if elems |> List.forall (fun x -> x.IsSome) then - Some (SynPat.Tuple(false, (elems |> List.map (fun x -> mkSynPatVar None x.Value)), f.Range)) - else - None - | _ -> None - -/// Check if a computation or sequence expression is syntactically free of 'yield' (though not yield!) -let YieldFree cenv expr = - if cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield then - - // Implement yield free logic for F# Language including the LanguageFeature.ImplicitYield - let rec YieldFree expr = - match expr with - | SynExpr.Sequential (_, _, e1, e2, _) -> - YieldFree e1 && YieldFree e2 - - | SynExpr.IfThenElse (_, e2, e3opt, _, _, _, _) -> - YieldFree e2 && Option.forall YieldFree e3opt - - | SynExpr.TryWith (e1, _, clauses, _, _, _, _) -> - YieldFree e1 && clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) - - | (SynExpr.Match (_, _, clauses, _) | SynExpr.MatchBang (_, _, clauses, _)) -> - clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) - - | SynExpr.For (_, _, _, _, _, body, _) - | SynExpr.TryFinally (body, _, _, _, _) - | SynExpr.LetOrUse (_, _, _, body, _) - | SynExpr.While (_, _, body, _) - | SynExpr.ForEach (_, _, _, _, _, body, _) -> - YieldFree body - - | SynExpr.LetOrUseBang(_, _, _, _, _, body, _) -> - YieldFree body - - | SynExpr.YieldOrReturn((true, _), _, _) -> false - - | _ -> true - - YieldFree expr - else - // Implement yield free logic for F# Language without the LanguageFeature.ImplicitYield - let rec YieldFree expr = - match expr with - | SynExpr.Sequential (_, _, e1, e2, _) -> - YieldFree e1 && YieldFree e2 - - | SynExpr.IfThenElse (_, e2, e3opt, _, _, _, _) -> - YieldFree e2 && Option.forall YieldFree e3opt - - | SynExpr.TryWith (e1, _, clauses, _, _, _, _) -> - YieldFree e1 && clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) - - | (SynExpr.Match (_, _, clauses, _) | SynExpr.MatchBang (_, _, clauses, _)) -> - clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) - - | SynExpr.For (_, _, _, _, _, body, _) - | SynExpr.TryFinally (body, _, _, _, _) - | SynExpr.LetOrUse (_, _, _, body, _) - | SynExpr.While (_, _, body, _) - | SynExpr.ForEach (_, _, _, _, _, body, _) -> - YieldFree body - - | SynExpr.LetOrUseBang _ - | SynExpr.YieldOrReturnFrom _ - | SynExpr.YieldOrReturn _ - | SynExpr.ImplicitZero _ - | SynExpr.Do _ -> false - - | _ -> true - - YieldFree expr - - -/// Determine if a syntactic expression inside 'seq { ... }' or '[...]' counts as a "simple sequence -/// of semicolon separated values". For example [1;2;3]. -/// 'acceptDeprecated' is true for the '[ ... ]' case, where we allow the syntax '[ if g then t else e ]' but ask it to be parenthesized -/// -let (|SimpleSemicolonSequence|_|) cenv acceptDeprecated cexpr = - - let IsSimpleSemicolonSequenceElement expr = - match expr with - | SynExpr.IfThenElse _ when acceptDeprecated && YieldFree cenv expr -> true - | SynExpr.IfThenElse _ - | SynExpr.TryWith _ - | SynExpr.Match _ - | SynExpr.For _ - | SynExpr.ForEach _ - | SynExpr.TryFinally _ - | SynExpr.YieldOrReturnFrom _ - | SynExpr.YieldOrReturn _ - | SynExpr.LetOrUse _ - | SynExpr.Do _ - | SynExpr.MatchBang _ - | SynExpr.LetOrUseBang _ - | SynExpr.While _ -> false - | _ -> true - - let rec TryGetSimpleSemicolonSequenceOfComprehension expr acc = - match expr with - | SynExpr.Sequential (_, true, e1, e2, _) -> - if IsSimpleSemicolonSequenceElement e1 then - TryGetSimpleSemicolonSequenceOfComprehension e2 (e1 :: acc) - else - None - | e -> - if IsSimpleSemicolonSequenceElement e then - Some(List.rev (e :: acc)) - else - None - - TryGetSimpleSemicolonSequenceOfComprehension cexpr [] - -//------------------------------------------------------------------------- -// Mutually recursive shapes -//------------------------------------------------------------------------- - -/// Represents the shape of a mutually recursive group of declarations including nested modules -[] -type MutRecShape<'TypeData, 'LetsData, 'ModuleData, 'ModuleAbbrevData, 'OpenData> = - | Tycon of 'TypeData - | Lets of 'LetsData - | Module of 'ModuleData * MutRecShapes<'TypeData, 'LetsData, 'ModuleData, 'ModuleAbbrevData, 'OpenData> - | ModuleAbbrev of 'ModuleAbbrevData - | Open of 'OpenData - -and MutRecShapes<'TypeData, 'LetsData, 'ModuleData, 'ModuleAbbrevData, 'OpenData> = MutRecShape<'TypeData, 'LetsData, 'ModuleData, 'ModuleAbbrevData, 'OpenData> list - -module MutRecShapes = - let rec map f1 f2 f3 x = - x |> List.map (function - | MutRecShape.Open a -> MutRecShape.Open a - | MutRecShape.ModuleAbbrev b -> MutRecShape.ModuleAbbrev b - | MutRecShape.Tycon a -> MutRecShape.Tycon (f1 a) - | MutRecShape.Lets b -> MutRecShape.Lets (f2 b) - | MutRecShape.Module (c, d) -> MutRecShape.Module (f3 c, map f1 f2 f3 d)) - - - let mapTycons f1 xs = map f1 id id xs - let mapTyconsAndLets f1 f2 xs = map f1 f2 id xs - let mapLets f2 xs = map id f2 id xs - let mapModules f1 xs = map id id f1 xs - - let rec mapWithEnv fTycon fLets (env: 'Env) x = - x |> List.map (function - | MutRecShape.Open a -> MutRecShape.Open a - | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a - | MutRecShape.Tycon a -> MutRecShape.Tycon (fTycon env a) - | MutRecShape.Lets b -> MutRecShape.Lets (fLets env b) - | MutRecShape.Module ((c, env2), d) -> MutRecShape.Module ((c, env2), mapWithEnv fTycon fLets env2 d)) - - let mapTyconsWithEnv f1 env xs = mapWithEnv f1 (fun _env x -> x) env xs - - let rec mapWithParent parent f1 f2 f3 xs = - xs |> List.map (function - | MutRecShape.Open a -> MutRecShape.Open a - | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a - | MutRecShape.Tycon a -> MutRecShape.Tycon (f2 parent a) - | MutRecShape.Lets b -> MutRecShape.Lets (f3 parent b) - | MutRecShape.Module (c, d) -> - let c2, parent2 = f1 parent c d - MutRecShape.Module (c2, mapWithParent parent2 f1 f2 f3 d)) - - let rec computeEnvs f1 f2 (env: 'Env) xs = - let env = f2 env xs - env, - xs |> List.map (function - | MutRecShape.Open a -> MutRecShape.Open a - | MutRecShape.ModuleAbbrev a -> MutRecShape.ModuleAbbrev a - | MutRecShape.Tycon a -> MutRecShape.Tycon a - | MutRecShape.Lets b -> MutRecShape.Lets b - | MutRecShape.Module (c, ds) -> - let env2 = f1 env c - let env3, ds2 = computeEnvs f1 f2 env2 ds - MutRecShape.Module ((c, env3), ds2)) - - let rec extendEnvs f1 (env: 'Env) xs = - let env = f1 env xs - env, - xs |> List.map (function - | MutRecShape.Module ((c, env), ds) -> - let env2, ds2 = extendEnvs f1 env ds - MutRecShape.Module ((c, env2), ds2) - | x -> x) - - let dropEnvs xs = xs |> mapModules fst - - let rec expandTyconsWithEnv f1 env xs = - let preBinds, postBinds = - xs |> List.map (fun elem -> - match elem with - | MutRecShape.Tycon a -> f1 env a - | _ -> [], []) - |> List.unzip - [MutRecShape.Lets (List.concat preBinds)] @ - (xs |> List.map (fun elem -> - match elem with - | MutRecShape.Module ((c, env2), d) -> MutRecShape.Module ((c, env2), expandTyconsWithEnv f1 env2 d) - | _ -> elem)) @ - [MutRecShape.Lets (List.concat postBinds)] - - let rec mapFoldWithEnv f1 z env xs = - (z, xs) ||> List.mapFold (fun z x -> - match x with - | MutRecShape.Module ((c, env2), ds) -> let ds2, z = mapFoldWithEnv f1 z env2 ds in MutRecShape.Module ((c, env2), ds2), z - | _ -> let x2, z = f1 z env x in x2, z) - - - let rec collectTycons x = - x |> List.collect (function - | MutRecShape.Tycon a -> [a] - | MutRecShape.Module (_, d) -> collectTycons d - | _ -> []) - - let topTycons x = - x |> List.choose (function MutRecShape.Tycon a -> Some a | _ -> None) - - let rec iter f1 f2 f3 f4 f5 x = - x |> List.iter (function - | MutRecShape.Tycon a -> f1 a - | MutRecShape.Lets b -> f2 b - | MutRecShape.Module (c, d) -> f3 c; iter f1 f2 f3 f4 f5 d - | MutRecShape.Open a -> f4 a - | MutRecShape.ModuleAbbrev a -> f5 a) - - let iterTycons f1 x = iter f1 ignore ignore ignore ignore x - let iterTyconsAndLets f1 f2 x = iter f1 f2 ignore ignore ignore x - let iterModules f1 x = iter ignore ignore f1 ignore ignore x - - let rec iterWithEnv f1 f2 f3 f4 env x = - x |> List.iter (function - | MutRecShape.Tycon a -> f1 env a - | MutRecShape.Lets b -> f2 env b - | MutRecShape.Module ((_, env), d) -> iterWithEnv f1 f2 f3 f4 env d - | MutRecShape.Open a -> f3 env a - | MutRecShape.ModuleAbbrev a -> f4 env a) - - let iterTyconsWithEnv f1 env xs = iterWithEnv f1 (fun _env _x -> ()) (fun _env _x -> ()) (fun _env _x -> ()) env xs - -//------------------------------------------------------------------------- -// Post-transform initialization graphs using the 'lazy' interpretation. -// See ML workshop paper. -//------------------------------------------------------------------------- - -type InitializationGraphAnalysisState = - | Top - | InnerTop - | DefinitelyStrict - | MaybeLazy - | DefinitelyLazy - -type PreInitializationGraphEliminationBinding = - { FixupPoints: RecursiveUseFixupPoints - Binding: Tast.Binding } - - -/// Check for safety and determine if we need to insert lazy thunks -let EliminateInitializationGraphs - (getTyconBinds: 'TyconDataIn -> PreInitializationGraphEliminationBinding list) - (morphTyconBinds: (PreInitializationGraphEliminationBinding list -> Binding list) -> 'TyconDataIn -> 'TyconDataOut) - (getLetBinds: 'LetDataIn list -> PreInitializationGraphEliminationBinding list) - (morphLetBinds: (PreInitializationGraphEliminationBinding list -> Binding list) -> 'LetDataIn list -> Binding list) - g mustHaveArity denv - (fixupsAndBindingsWithoutLaziness: MutRecShape<_, _, _, _, _> list) bindsm = - - let recursiveVals = - let hash = ValHash.Create() - let add (pgrbind: PreInitializationGraphEliminationBinding) = let c = pgrbind.Binding.Var in hash.Add(c, c) - fixupsAndBindingsWithoutLaziness |> MutRecShapes.iterTyconsAndLets (getTyconBinds >> List.iter add) (getLetBinds >> List.iter add) - hash - - // The output of the analysis - let mutable outOfOrder = false - let mutable runtimeChecks = false - let mutable directRecursiveData = false - let mutable reportedEager = false - let mutable definiteDependencies = [] - - let rec stripChooseAndExpr e = - match stripExpr e with - | Expr.TyChoose (_, b, _) -> stripChooseAndExpr b - | e -> e - - let availIfInOrder = ValHash<_>.Create() - let check boundv expr = - let strict = function - | MaybeLazy -> MaybeLazy - | DefinitelyLazy -> DefinitelyLazy - | Top | DefinitelyStrict | InnerTop -> DefinitelyStrict - let lzy = function - | Top | InnerTop | DefinitelyLazy -> DefinitelyLazy - | MaybeLazy | DefinitelyStrict -> MaybeLazy - let fixable = function - | Top | InnerTop -> InnerTop - | DefinitelyStrict -> DefinitelyStrict - | MaybeLazy -> MaybeLazy - | DefinitelyLazy -> DefinitelyLazy - - let rec CheckExpr st e = - match stripChooseAndExpr e with - // Expressions with some lazy parts - | Expr.Lambda (_, _, _, _, b, _, _) -> checkDelayed st b - - // Type-lambdas are analyzed as if they are strict. - // - // This is a design decision (See bug 6496), so that generalized recursive bindings such as - // let rec x = x - // are analyzed. Although we give type "x: 'T" to these, from the users point of view - // any use of "x" will result in an infinite recursion. Type instantiation is implicit in F# - // because of type inference, which makes it reasonable to check generic bindings strictly. - | Expr.TyLambda (_, _, b, _, _) -> CheckExpr st b - - | Expr.Obj (_, ty, _, e, overrides, extraImpls, _) -> - // NOTE: we can't fixup recursive references inside delegates since the closure delegee of a delegate is not accessible - // from outside. Object expressions implementing interfaces can, on the other hand, be fixed up. See FSharp 1.0 bug 1469 - if isInterfaceTy g ty then - List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> checkDelayed st e) overrides - List.iter (snd >> List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> checkDelayed st e)) extraImpls - else - CheckExpr (strict st) e - List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> CheckExpr (lzy (strict st)) e) overrides - List.iter (snd >> List.iter (fun (TObjExprMethod(_, _, _, _, e, _)) -> CheckExpr (lzy (strict st)) e)) extraImpls - - // Expressions where fixups may be needed - | Expr.Val (v, _, m) -> CheckValRef st v m - - // Expressions where subparts may be fixable - | Expr.Op ((TOp.Tuple _ | TOp.UnionCase _ | TOp.Recd _), _, args, _) -> - List.iter (CheckExpr (fixable st)) args - - // Composite expressions - | Expr.Const _ -> () - | Expr.LetRec (binds, e, _, _) -> - binds |> List.iter (CheckBinding (strict st)) - CheckExpr (strict st) e - | Expr.Let (bind, e, _, _) -> - CheckBinding (strict st) bind - CheckExpr (strict st) e - | Expr.Match (_, _, pt, targets, _, _) -> - CheckDecisionTree (strict st) pt - Array.iter (CheckDecisionTreeTarget (strict st)) targets - | Expr.App (e1, _, _, args, _) -> - CheckExpr (strict st) e1 - List.iter (CheckExpr (strict st)) args - // Binary expressions - | Expr.Sequential (e1, e2, _, _, _) - | Expr.StaticOptimization (_, e1, e2, _) -> - CheckExpr (strict st) e1; CheckExpr (strict st) e2 - // n-ary expressions - | Expr.Op (op, _, args, m) -> CheckExprOp st op m; List.iter (CheckExpr (strict st)) args - // misc - | Expr.Link eref -> CheckExpr st !eref - | Expr.TyChoose (_, b, _) -> CheckExpr st b - | Expr.Quote _ -> () - - and CheckBinding st (TBind(_, e, _)) = CheckExpr st e - and CheckDecisionTree st = function - | TDSwitch(e1, csl, dflt, _) -> CheckExpr st e1; List.iter (fun (TCase(_, d)) -> CheckDecisionTree st d) csl; Option.iter (CheckDecisionTree st) dflt - | TDSuccess (es, _) -> es |> List.iter (CheckExpr st) - | TDBind(bind, e) -> CheckBinding st bind; CheckDecisionTree st e - and CheckDecisionTreeTarget st (TTarget(_, e, _)) = CheckExpr st e - - and CheckExprOp st op m = - match op with - | TOp.LValueOp (_, lvr) -> CheckValRef (strict st) lvr m - | _ -> () - - and CheckValRef st (v: ValRef) m = - match st with - | MaybeLazy -> - if recursiveVals.TryFind v.Deref |> Option.isSome then - warning (RecursiveUseCheckedAtRuntime (denv, v, m)) - if not reportedEager then - (warning (LetRecCheckedAtRuntime m); reportedEager <- true) - runtimeChecks <- true - - | Top | DefinitelyStrict -> - if recursiveVals.TryFind v.Deref |> Option.isSome then - if availIfInOrder.TryFind v.Deref |> Option.isNone then - warning (LetRecEvaluatedOutOfOrder (denv, boundv, v, m)) - outOfOrder <- true - if not reportedEager then - (warning (LetRecCheckedAtRuntime m); reportedEager <- true) - definiteDependencies <- (boundv, v) :: definiteDependencies - | InnerTop -> - if recursiveVals.TryFind v.Deref |> Option.isSome then - directRecursiveData <- true - | DefinitelyLazy -> () - and checkDelayed st b = - match st with - | MaybeLazy | DefinitelyStrict -> CheckExpr MaybeLazy b - | DefinitelyLazy | Top | InnerTop -> () - - - CheckExpr Top expr - - - // Check the bindings one by one, each w.r.t. the previously available set of binding - begin - let checkBind (pgrbind: PreInitializationGraphEliminationBinding) = - let (TBind(v, e, _)) = pgrbind.Binding - check (mkLocalValRef v) e - availIfInOrder.Add(v, 1) - fixupsAndBindingsWithoutLaziness |> MutRecShapes.iterTyconsAndLets (getTyconBinds >> List.iter checkBind) (getLetBinds >> List.iter checkBind) - end - - // ddg = definiteDependencyGraph - let ddgNodes = recursiveVals.Values |> Seq.toList |> List.map mkLocalValRef - let ddg = Graph((fun v -> v.Stamp), ddgNodes, definiteDependencies ) - ddg.IterateCycles (fun path -> error (LetRecUnsound (denv, path, path.Head.Range))) - - let requiresLazyBindings = runtimeChecks || outOfOrder - if directRecursiveData && requiresLazyBindings then - error(Error(FSComp.SR.tcInvalidMixtureOfRecursiveForms(), bindsm)) - - if requiresLazyBindings then - let morphBinding (pgrbind: PreInitializationGraphEliminationBinding) = - let (RecursiveUseFixupPoints fixupPoints) = pgrbind.FixupPoints - let (TBind(v, e, seqPtOpt)) = pgrbind.Binding - match stripChooseAndExpr e with - | Expr.Lambda _ | Expr.TyLambda _ -> - [], [mkInvisibleBind v e] - | _ -> - let ty = v.Type - let m = v.Range - let vty = (mkLazyTy g ty) - - let fty = (g.unit_ty --> ty) - let flazy, felazy = Tastops.mkCompGenLocal m v.LogicalName fty - let frhs = mkUnitDelayLambda g m e - if mustHaveArity then flazy.SetValReprInfo (Some(InferArityOfExpr g AllowTypeDirectedDetupling.Yes fty [] [] frhs)) - - let vlazy, velazy = Tastops.mkCompGenLocal m v.LogicalName vty - let vrhs = (mkLazyDelayed g m ty felazy) - - if mustHaveArity then vlazy.SetValReprInfo (Some(InferArityOfExpr g AllowTypeDirectedDetupling.Yes vty [] [] vrhs)) - fixupPoints |> List.iter (fun (fp, _) -> fp := mkLazyForce g (!fp).Range ty velazy) - - [mkInvisibleBind flazy frhs; mkInvisibleBind vlazy vrhs], - [mkBind seqPtOpt v (mkLazyForce g m ty velazy)] - - let newTopBinds = ResizeArray<_>() - let morphBindings pgrbinds = pgrbinds |> List.map morphBinding |> List.unzip |> (fun (a, b) -> newTopBinds.Add (List.concat a); List.concat b) - - let res = fixupsAndBindingsWithoutLaziness |> MutRecShapes.map (morphTyconBinds morphBindings) (morphLetBinds morphBindings) id - if newTopBinds.Count = 0 then res - else MutRecShape.Lets (List.concat newTopBinds) :: res - else - let noMorph (pgrbinds: PreInitializationGraphEliminationBinding list) = pgrbinds |> List.map (fun pgrbind -> pgrbind.Binding) - fixupsAndBindingsWithoutLaziness |> MutRecShapes.map (morphTyconBinds noMorph) (morphLetBinds noMorph) id - -//------------------------------------------------------------------------- -// Check the shape of an object constructor and rewrite calls -//------------------------------------------------------------------------- - -let CheckAndRewriteObjectCtor g env (ctorLambdaExpr: Expr) = - - let m = ctorLambdaExpr.Range - let tps, vsl, body, returnTy = stripTopLambda (ctorLambdaExpr, tyOfExpr g ctorLambdaExpr) - - // Rewrite legitimate self-construction calls to CtorValUsedAsSelfInit - let error (expr: Expr) = - errorR(Error(FSComp.SR.tcInvalidObjectConstructionExpression(), expr.Range)) - expr - - // Build an assignment into the safeThisValOpt mutable reference cell that holds recursive references to 'this' - // Build an assignment into the safeInitInfo mutable field that indicates that partial initialization is successful - let rewriteConstruction recdExpr = - match env.eCtorInfo with - | None -> recdExpr - | Some ctorInfo -> - let recdExpr = - match ctorInfo.safeThisValOpt with - | None -> recdExpr - | Some safeInitVal -> - let ty = tyOfExpr g recdExpr - let thisExpr = mkGetArg0 m ty - let setExpr = mkRefCellSet g m ty (exprForValRef m (mkLocalValRef safeInitVal)) thisExpr - Expr.Sequential (recdExpr, setExpr, ThenDoSeq, SuppressSequencePointOnExprOfSequential, m) - let recdExpr = - match ctorInfo.safeInitInfo with - | NoSafeInitInfo -> recdExpr - | SafeInitField (rfref, _) -> - let thisTy = tyOfExpr g recdExpr - let thisExpr = mkGetArg0 m thisTy - let thisTyInst = argsOfAppTy g thisTy - let setExpr = mkRecdFieldSetViaExprAddr (thisExpr, rfref, thisTyInst, mkOne g m, m) - Expr.Sequential (recdExpr, setExpr, ThenDoSeq, SuppressSequencePointOnExprOfSequential, m) - recdExpr - - - let rec checkAndRewrite (expr: Expr) = - match expr with - // = { fields } - // The constructor ends in an object initialization expression - good - | Expr.Op (TOp.Recd (RecdExprIsObjInit, _), _, _, _) -> rewriteConstruction expr - - // = "a; " - | Expr.Sequential (a, body, NormalSeq, spSeq, b) -> Expr.Sequential (a, checkAndRewrite body, NormalSeq, spSeq, b) - - // = " then " - | Expr.Sequential (body, a, ThenDoSeq, spSeq, b) -> Expr.Sequential (checkAndRewrite body, a, ThenDoSeq, spSeq, b) - - // = "let pat = expr in " - | Expr.Let (bind, body, m, _) -> mkLetBind m bind (checkAndRewrite body) - - // The constructor is a sequence "let pat = expr in " - | Expr.Match (spBind, a, b, targets, c, d) -> Expr.Match (spBind, a, b, (targets |> Array.map (fun (TTarget(vs, body, spTarget)) -> TTarget(vs, checkAndRewrite body, spTarget))), c, d) - - // = "let rec binds in " - | Expr.LetRec (a, body, _, _) -> Expr.LetRec (a, checkAndRewrite body, m, NewFreeVarsCache()) - - // = "new C(...)" - | Expr.App (f, b, c, d, m) -> - // The application had better be an application of a ctor - let f = checkAndRewriteCtorUsage f - let expr = Expr.App (f, b, c, d, m) - rewriteConstruction expr - - | _ -> - error expr - - and checkAndRewriteCtorUsage expr = - match expr with - | Expr.Link eref -> - let e = checkAndRewriteCtorUsage !eref - eref := e - expr - - // Type applications are ok, e.g. - // type C<'a>(x: int) = - // new() = C<'a>(3) - | Expr.App (f, fty, tyargs, [], m) -> - let f = checkAndRewriteCtorUsage f - Expr.App (f, fty, tyargs, [], m) - - // Self-calls are OK and get rewritten. - | Expr.Val (vref, NormalValUse, a) -> - let isCtor = - match vref.MemberInfo with - | None -> false - | Some memberInfo -> memberInfo.MemberFlags.MemberKind = MemberKind.Constructor - - if not isCtor then - error expr - else - Expr.Val (vref, CtorValUsedAsSelfInit, a) - | _ -> - error expr - - let body = checkAndRewrite body - mkMultiLambdas m tps vsl (body, returnTy) - - - -/// Post-typechecking normalizations to enforce semantic constraints -/// lazy and, lazy or, rethrow, address-of -let buildApp cenv expr resultTy arg m = - let g = cenv.g - match expr, arg with - - // Special rule for building applications of the 'x && y' operator - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [x0], _), _), _ - when valRefEq g vf g.and_vref - || valRefEq g vf g.and2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyAnd g m x0 arg), resultTy - - // Special rule for building applications of the 'x || y' operator - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [x0], _), _), _ - when valRefEq g vf g.or_vref - || valRefEq g vf g.or2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyOr g m x0 arg ), resultTy - - // Special rule for building applications of the 'reraise' operator - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ - when valRefEq g vf g.reraise_vref -> - - // exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type. - MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy - - // Special rules for NativePtr.ofByRef to generalize result. - // See RFC FS-1053.md - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ - when (valRefEq g vf g.nativeptr_tobyref_vref) -> - - let argty = NewInferenceType() - let resultTy = mkByrefTyWithInference g argty (NewByRefKindInferenceType g m) - expr.SupplyArgument (arg, m), resultTy - - // Special rules for building applications of the '&expr' operator, which gets the - // address of an expression. - // - // See also RFC FS-1053.md - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ - when valRefEq g vf g.addrof_vref -> - - let wrap, e1a', readonly, _writeonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some vf) m - // Assert the result type to be readonly if we couldn't take the address - let resultTy = - let argTy = tyOfExpr g arg - if readonly then - mkInByrefTy g argTy - - // "`outref<'T>` types are never introduced implicitly by F#.", see rationale in RFC FS-1053 - // - // We do _not_ introduce outref here, e.g. '&x' where 'x' is outref<_> is _not_ outref. - // This effectively makes 'outref<_>' documentation-only. There is frequently a need to pass outref - // pointers to .NET library functions whose signatures are not tagged with [] - //elif writeonly then - // mkOutByrefTy g argTy - - else - mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) - - MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy - - // Special rules for building applications of the &&expr' operators, which gets the - // address of an expression. - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _), _ - when valRefEq g vf g.addrof2_vref -> - - warning(UseOfAddressOfOperator m) - let wrap, e1a', _readonly, _writeonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some vf) m - MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy - - | _ when isByrefTy g resultTy -> - // Handle byref returns, byref-typed returns get implicitly dereferenced - let expr = expr.SupplyArgument (arg, m) - let expr = mkDerefAddrExpr m expr.Expr m resultTy - let resultTy = destByrefTy g resultTy - MakeApplicableExprNoFlex cenv expr, resultTy - - | _ -> - expr.SupplyArgument (arg, m), resultTy - -//------------------------------------------------------------------------- -// Additional data structures used by type checking -//------------------------------------------------------------------------- - -type DelayedItem = - /// DelayedTypeApp (typeArgs, mTypeArgs, mExprAndTypeArgs) - /// - /// Represents the in "item" - | DelayedTypeApp of Ast.SynType list * range * range - - /// DelayedApp (isAtomic, argExpr, mFuncAndArg) - /// - /// Represents the args in "item args", or "item.[args]". - | DelayedApp of ExprAtomicFlag * Ast.SynExpr * range - - /// Represents the long identifiers in "item.Ident1", or "item.Ident1.Ident2" etc. - | DelayedDotLookup of Ast.Ident list * range - - /// Represents an incomplete "item." - | DelayedDot - - /// Represents the valueExpr in "item <- valueExpr", also "item.[indexerArgs] <- valueExpr" etc. - | DelayedSet of Ast.SynExpr * range - -let MakeDelayedSet(e: SynExpr, m) = - // We have longId <- e. Wrap 'e' in another pair of parentheses to ensure it's never interpreted as - // a named argument, e.g. for "el.Checked <- (el = el2)" - DelayedSet (SynExpr.Paren (e, range0, None, e.Range), m) - -type NewSlotsOK = - | NewSlotsOK - | NoNewSlots - - -type ImplicitlyBoundTyparsAllowed = - | NewTyparsOKButWarnIfNotRigid - | NewTyparsOK - | NoNewTypars - -type CheckConstraints = - | CheckCxs - | NoCheckCxs - -type TypeRealizationPass = - | FirstPass - | SecondPass - -type MemberOrValContainerInfo = - | MemberOrValContainerInfo of - TyconRef * // tcref: The logical apparent parent of a value/member, either a module, type or exception - (TType * SlotImplSet) option * // optIntfSlotTy - Val option * // baseValOpt - SafeInitData * // safeInitInfo - Typars // declaredTyconTypars - -/// Provides information about the context for a value or member definition -type ContainerInfo = - | ContainerInfo of - // The nearest containing module. Used as the 'actual' parent for extension members and values - ParentRef * - // For members: - MemberOrValContainerInfo option - member x.ParentRef = - let (ContainerInfo(v, _)) = x - v - -/// Indicates a declaration is contained in an expression -let ExprContainerInfo = ContainerInfo(ParentNone, None) -/// Indicates a declaration is contained in the given module -let ModuleOrNamespaceContainerInfo modref = ContainerInfo(Parent modref, Some(MemberOrValContainerInfo(modref, None, None, NoSafeInitInfo, []))) -/// Indicates a declaration is contained in the given type definition in the given module -let TyconContainerInfo (parent, tcref, declaredTyconTypars, safeInitInfo) = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, None, None, safeInitInfo, declaredTyconTypars))) - -type NormalizedRecBindingDefn = NormalizedRecBindingDefn of ContainerInfo * NewSlotsOK * DeclKind * NormalizedBinding - -type TyconBindingDefn = TyconBindingDefn of ContainerInfo * NewSlotsOK * DeclKind * SynMemberDefn * range - -type ValSpecResult = ValSpecResult of ParentRef * ValMemberInfoTransient option * Ident * Typars * Typars * TType * PartialValReprInfo * DeclKind - -//------------------------------------------------------------------------- -// Additional data structures used by checking recursive bindings -//------------------------------------------------------------------------- - - -type RecDefnBindingInfo = RecDefnBindingInfo of ContainerInfo * NewSlotsOK * DeclKind * SynBinding - -type MutRecDataForOpen = MutRecDataForOpen of LongIdent * range * appliedScope: range -type MutRecDataForModuleAbbrev = MutRecDataForModuleAbbrev of Ident * LongIdent * range - -type MutRecSigsInitialData = MutRecShape list -type MutRecDefnsInitialData = MutRecShape list - -type MutRecDefnsPhase1DataForTycon = MutRecDefnsPhase1DataForTycon of SynComponentInfo * SynTypeDefnSimpleRepr * (SynType * range) list * preEstablishedHasDefaultCtor: bool * hasSelfReferentialCtor: bool * isAtOriginalTyconDefn: bool -type MutRecDefnsPhase1Data = MutRecShape list - -type MutRecDefnsPhase2DataForTycon = MutRecDefnsPhase2DataForTycon of Tycon option * ParentRef * DeclKind * TyconRef * Val option * SafeInitData * Typars * SynMemberDefn list * range * NewSlotsOK * fixupFinalAttribs: (unit -> unit) -type MutRecDefnsPhase2DataForModule = MutRecDefnsPhase2DataForModule of ModuleOrNamespaceType ref * ModuleOrNamespace -type MutRecDefnsPhase2Data = MutRecShape list - -type MutRecDefnsPhase2InfoForTycon = MutRecDefnsPhase2InfoForTycon of Tycon option * TyconRef * Typars * DeclKind * TyconBindingDefn list * fixupFinalAttrs: (unit -> unit) -type MutRecDefnsPhase2Info = MutRecShape list - - -/// RecursiveBindingInfo - flows through initial steps of TcLetrec -type RecursiveBindingInfo = - | RBInfo of - int * // index of the binding in the recursive group - ContainerInfo * - Typars * - ValInline * - Val * - ExplicitTyparInfo * - PartialValReprInfo * - ValMemberInfoTransient option * - Val option * - Val option * - SafeInitData * - SynAccess option * - TType * - DeclKind - - member x.EnclosingDeclaredTypars = let (RBInfo(_, _, enclosingDeclaredTypars, _, _, _, _, _, _, _, _, _, _, _)) = x in enclosingDeclaredTypars - member x.Val = let (RBInfo(_, _, _, _, vspec, _, _, _, _, _, _, _, _, _)) = x in vspec - member x.ExplicitTyparInfo = let (RBInfo(_, _, _, _, _, flex, _, _, _, _, _, _, _, _)) = x in flex - member x.DeclaredTypars = let (ExplicitTyparInfo(_, declaredTypars, _)) = x.ExplicitTyparInfo in declaredTypars - member x.Index = let (RBInfo(i, _, _, _, _, _, _, _, _, _, _, _, _, _)) = x in i - member x.ContainerInfo = let (RBInfo(_, c, _, _, _, _, _, _, _, _, _, _, _, _)) = x in c - member x.DeclKind = let (RBInfo(_, _, _, _, _, _, _, _, _, _, _, _, _, declKind)) = x in declKind - -type PreCheckingRecursiveBinding = - { SyntacticBinding: NormalizedBinding - RecBindingInfo: RecursiveBindingInfo } - - -type PreGeneralizationRecursiveBinding = - { ExtraGeneralizableTypars: Typars - CheckedBinding: CheckedBindingInfo - RecBindingInfo: RecursiveBindingInfo } - -type PostGeneralizationRecursiveBinding = - { ValScheme: ValScheme - CheckedBinding: CheckedBindingInfo - RecBindingInfo: RecursiveBindingInfo } - member x.GeneralizedTypars = x.ValScheme.GeneralizedTypars - -type PostBindCtorThisVarRefCellRecursiveBinding = - { ValScheme: ValScheme - Binding: Tast.Binding } - - -let CanInferExtraGeneralizedTyparsForRecBinding (pgrbind: PreGeneralizationRecursiveBinding) = - let flex = pgrbind.RecBindingInfo.ExplicitTyparInfo - let (ExplicitTyparInfo(_, _, canInferTypars)) = flex - let memFlagsOpt = pgrbind.RecBindingInfo.Val.MemberInfo |> Option.map (fun memInfo -> memInfo.MemberFlags) - let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (pgrbind.RecBindingInfo.ContainerInfo.ParentRef, canInferTypars, memFlagsOpt) - canInferTypars - - -/// Get the "this" variable from an instance member binding -let GetInstanceMemberThisVariable (v: Val, x) = - // Skip over LAM tps. Choose 'a. - if v.IsInstanceMember then - let rec firstArg e = - match e with - | Expr.TyLambda (_, _, b, _, _) -> firstArg b - | Expr.TyChoose (_, b, _) -> firstArg b - | Expr.Lambda (_, _, _, [v], _, _, _) -> Some v - | _ -> failwith "GetInstanceMemberThisVariable: instance member did not have expected internal form" - - firstArg x - else - None - -//------------------------------------------------------------------------- -// Checking types and type constraints -//------------------------------------------------------------------------- -/// Check specifications of constraints on type parameters -let rec TcTyparConstraint ridx cenv newOk checkCxs occ (env: TcEnv) tpenv c = - let checkSimpleConstraint tp m constraintAdder = - let tp', tpenv = TcTypar cenv env newOk tpenv tp - constraintAdder env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') - tpenv - - match c with - | WhereTyparDefaultsToType(tp, ty, m) -> - let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty - let tp', tpenv = TcTypar cenv env newOk tpenv tp - let csenv = MakeConstraintSolverEnv env.eContextInfo cenv.css m env.DisplayEnv - AddConstraint csenv 0 m NoTrace tp' (TyparConstraint.DefaultsTo(ridx, ty', m)) |> CommitOperationResult - tpenv - - | WhereTyparSubtypeOfType(tp, ty, m) -> - let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType env tpenv ty - let tp', tpenv = TcTypar cenv env newOk tpenv tp - if newOk = NoNewTypars && isSealedTy cenv.g ty' then - errorR(Error(FSComp.SR.tcInvalidConstraintTypeSealed(), m)) - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty' (mkTyparTy tp') - tpenv - - | WhereTyparSupportsNull(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportNull - - | WhereTyparIsComparable(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportComparison - - | WhereTyparIsEquatable(tp, m) -> checkSimpleConstraint tp m AddCxTypeMustSupportEquality - - | WhereTyparIsReferenceType(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsReferenceType - - | WhereTyparIsValueType(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsValueType - - | WhereTyparIsUnmanaged(tp, m) -> checkSimpleConstraint tp m AddCxTypeIsUnmanaged - - | WhereTyparIsEnum(tp, tyargs, m) -> - let tp', tpenv = TcTypar cenv env newOk tpenv tp - let tpenv = - match tyargs with - | [underlying] -> - let underlying', tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType env tpenv underlying - AddCxTypeIsEnum env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') underlying' - tpenv - | _ -> - errorR(Error(FSComp.SR.tcInvalidEnumConstraint(), m)) - tpenv - tpenv - - | WhereTyparIsDelegate(tp, tyargs, m) -> - let tp', tpenv = TcTypar cenv env newOk tpenv tp - match tyargs with - | [a;b] -> - let a', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv a - let b', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv b - AddCxTypeIsDelegate env.DisplayEnv cenv.css m NoTrace (mkTyparTy tp') a' b' - tpenv - | _ -> - errorR(Error(FSComp.SR.tcInvalidEnumConstraint(), m)) - tpenv - - | WhereTyparSupportsMember(tps, memSpfn, m) -> - let traitInfo, tpenv = TcPseudoMemberSpec cenv newOk env tps tpenv memSpfn m - match traitInfo with - | TTrait(objtys, ".ctor", memberFlags, argTys, returnTy, _) when memberFlags.MemberKind = MemberKind.Constructor -> - match objtys, argTys with - | [ty], [] when typeEquiv cenv.g ty (GetFSharpViewOfReturnType cenv.g returnTy) -> - AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css m NoTrace ty - tpenv - | _ -> - errorR(Error(FSComp.SR.tcInvalidNewConstraint(), m)) - tpenv - | _ -> - AddCxMethodConstraint env.DisplayEnv cenv.css m NoTrace traitInfo - tpenv - -and TcPseudoMemberSpec cenv newOk env synTypes tpenv memSpfn m = -#if ALLOW_MEMBER_CONSTRAINTS_ON_MEASURES - let tps, tpenv = List.mapFold (TcTyparOrMeasurePar None cenv env newOk) tpenv synTypars -#else - let tys, tpenv = List.mapFold (TcTypeAndRecover cenv newOk CheckCxs ItemOccurence.UseInType env) tpenv synTypes -#endif - match memSpfn with - | SynMemberSig.Member (valSpfn, memberFlags, m) -> - // REVIEW: Test pseudo constraints cannot refer to polymorphic methods. - // REVIEW: Test pseudo constraints cannot be curried. - let members, tpenv = TcValSpec cenv env ModuleOrMemberBinding newOk ExprContainerInfo (Some memberFlags) (Some (List.head tys)) tpenv valSpfn [] - match members with - | [ValSpecResult(_, _, id, _, _, memberConstraintTy, partialValReprInfo, _)] -> - let memberConstraintTypars, _ = tryDestForallTy cenv.g memberConstraintTy - let topValInfo = TranslatePartialArity memberConstraintTypars partialValReprInfo - let _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm cenv.g topValInfo memberConstraintTy m - //if curriedArgInfos.Length > 1 then error(Error(FSComp.SR.tcInvalidConstraint(), m)) - let argTys = List.concat curriedArgInfos - let argTys = List.map fst argTys - let logicalCompiledName = ComputeLogicalName id memberFlags - - let item = Item.ArgName (id, memberConstraintTy, None) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv - | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) - | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) - - -/// Check a value specification, e.g. in a signature, interface declaration or a constraint -and TcValSpec cenv env declKind newOk containerInfo memFlagsOpt thisTyOpt tpenv valSpfn attrs = - let (ValSpfn(_, id, SynValTyparDecls(synTypars, _, synTyparConstraints), ty, valSynInfo, _, _, _, _, _, m)) = valSpfn - let declaredTypars = TcTyparDecls cenv env synTypars - let (ContainerInfo(altActualParent, tcrefContainerInfo)) = containerInfo - let enclosingDeclaredTypars, memberContainerInfo, thisTyOpt, declKind = - match tcrefContainerInfo with - | Some(MemberOrValContainerInfo(tcref, _, _, _, declaredTyconTypars)) -> - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let _, enclosingDeclaredTypars, _, _, thisTy = FreshenObjectArgType cenv m TyparRigidity.Rigid tcref isExtrinsic declaredTyconTypars - // An implemented interface type is in terms of the type's type parameters. - // We need a signature in terms of the values' type parameters. - // let optIntfSlotTy = Option.map (instType renaming) optIntfSlotTy in - enclosingDeclaredTypars, Some tcref, Some thisTy, declKind - | None -> - [], None, thisTyOpt, ModuleOrMemberBinding - let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars - let envinner = AddDeclaredTypars NoCheckForDuplicateTypars allDeclaredTypars env - let checkCxs = CheckCxs - let tpenv = TcTyparConstraints cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv synTyparConstraints - - // Treat constraints at the "end" of the type as if they are declared. - // This is by far the most convenient place to locate the constraints. - // e.g. - // val FastGenericComparer<'T>: IComparer<'T> when 'T: comparison - let tpenv = - match ty with - | SynType.WithGlobalConstraints(_, wcs, _) -> - TcTyparConstraints cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv wcs - | _ -> - tpenv - - // Enforce "no undeclared constraints allowed on declared typars" - allDeclaredTypars |> List.iter (SetTyparRigid cenv.g env.DisplayEnv m) - // Process the type, including any constraints - let declaredTy, tpenv = TcTypeAndRecover cenv newOk checkCxs ItemOccurence.UseInType envinner tpenv ty - - match memFlagsOpt, thisTyOpt with - | Some memberFlags, Some thisTy -> - let generateOneMember memberFlags = - - // Decode members in the signature - let ty', valSynInfo = - match memberFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.Member -> - declaredTy, valSynInfo - | MemberKind.PropertyGet - | MemberKind.PropertySet -> - let fakeArgReprInfos = [ for n in SynInfo.AritiesOfArgs valSynInfo do yield [ for _ in 1 .. n do yield ValReprInfo.unnamedTopArg1 ] ] - let arginfos, returnTy = GetTopTauTypeInFSharpForm cenv.g fakeArgReprInfos declaredTy m - if arginfos.Length > 1 then error(Error(FSComp.SR.tcInvalidPropertyType(), m)) - match memberFlags.MemberKind with - | MemberKind.PropertyGet -> - if SynInfo.HasNoArgs valSynInfo then - (cenv.g.unit_ty --> declaredTy), (SynInfo.IncorporateEmptyTupledArgForPropertyGetter valSynInfo) - else - declaredTy, valSynInfo - | _ -> - let setterTy = (mkRefTupledTy cenv.g (List.map fst (List.concat arginfos) @ [returnTy]) --> cenv.g.unit_ty) - let synInfo = SynInfo.IncorporateSetterArg valSynInfo - setterTy, synInfo - | MemberKind.PropertyGetSet -> - error(InternalError("Unexpected MemberKind.PropertyGetSet from signature parsing", m)) - - // Take "unit" into account in the signature - let valSynInfo = AdjustValSynInfoInSignature cenv.g ty' valSynInfo - - let ty', valSynInfo = - if memberFlags.IsInstance then - (thisTy --> ty'), (SynInfo.IncorporateSelfArg valSynInfo) - else - ty', valSynInfo - - let reallyGenerateOneMember(id: Ident, valSynInfo, ty', memberFlags) = - let (PartialValReprInfo(argsData, _)) as partialValReprInfo = - TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynInfo - - - // Fold in the optional argument information - // Resort to using the syntactic argument information since that is what tells us - // what is optional and what is not. - let ty' = - - if SynInfo.HasOptionalArgs valSynInfo then - let curriedArgTys, returnTy = GetTopTauTypeInFSharpForm cenv.g argsData ty' m - let curriedArgTys = - (List.zip (List.mapSquared fst curriedArgTys) valSynInfo.ArgInfos) - |> List.map (fun (argTys, argInfos) -> - (List.zip argTys argInfos) - |> List.map (fun (argty, argInfo) -> - if SynInfo.IsOptionalArg argInfo then mkOptionTy cenv.g argty - else argty)) - mkIteratedFunTy (List.map (mkRefTupledTy cenv.g) curriedArgTys) returnTy - else ty' - - let memberInfoOpt = - match memberContainerInfo with - | Some tcref -> - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let memberInfoTransient = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, attrs, [], memberFlags, valSynInfo, id, false) - Some memberInfoTransient - | None -> - None - - ValSpecResult(altActualParent, memberInfoOpt, id, enclosingDeclaredTypars, declaredTypars, ty', partialValReprInfo, declKind) - - [ yield reallyGenerateOneMember(id, valSynInfo, ty', memberFlags) - if CompileAsEvent cenv.g attrs then - let valSynInfo = EventDeclarationNormalization.ConvertSynInfo id.idRange valSynInfo - let memberFlags = EventDeclarationNormalization.ConvertMemberFlags memberFlags - let delTy = FindDelegateTypeOfPropertyEvent cenv.g cenv.amap id.idText id.idRange declaredTy - let ty = - if memberFlags.IsInstance then - thisTy --> (delTy --> cenv.g.unit_ty) - else - (delTy --> cenv.g.unit_ty) - yield reallyGenerateOneMember(ident("add_" + id.idText, id.idRange), valSynInfo, ty, memberFlags) - yield reallyGenerateOneMember(ident("remove_" + id.idText, id.idRange), valSynInfo, ty, memberFlags) ] - - - - match memberFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.Member - | MemberKind.PropertyGet - | MemberKind.PropertySet -> - generateOneMember memberFlags, tpenv - | MemberKind.PropertyGetSet -> - [ yield! generateOneMember({memberFlags with MemberKind=MemberKind.PropertyGet}) - yield! generateOneMember({memberFlags with MemberKind=MemberKind.PropertySet}) ], tpenv - | _ -> - let valSynInfo = AdjustValSynInfoInSignature cenv.g declaredTy valSynInfo - let partialValReprInfo = TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynInfo - [ ValSpecResult(altActualParent, None, id, enclosingDeclaredTypars, declaredTypars, declaredTy, partialValReprInfo, declKind) ], tpenv - - -//------------------------------------------------------------------------- -// Bind types -//------------------------------------------------------------------------- - -/// Check and elaborate a type or measure parameter occurrence -/// If optKind=Some kind, then this is the kind we're expecting (we're in *analysis* mode) -/// If optKind=None, we need to determine the kind (we're in *synthesis* mode) -/// -and TcTyparOrMeasurePar optKind cenv (env: TcEnv) newOk tpenv (Typar(id, _, _) as tp) = - let checkRes (res: Typar) = - match optKind, res.Kind with - | Some TyparKind.Measure, TyparKind.Type -> error (Error(FSComp.SR.tcExpectedUnitOfMeasureMarkWithAttribute(), id.idRange)); res, tpenv - | Some TyparKind.Type, TyparKind.Measure -> error (Error(FSComp.SR.tcExpectedTypeParameter(), id.idRange)); res, tpenv - | _, _ -> - let item = Item.TypeVar(id.idText, res) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights) - // record the ' as well for tokenization - // CallNameResolutionSink cenv.tcSink (tp.Range.StartRange, env.NameEnv, item, item, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights) - res, tpenv - let key = id.idText - match env.eNameResEnv.eTypars.TryGetValue key with - | true, res -> checkRes res - | _ -> - match TryFindUnscopedTypar key tpenv with - | Some res -> checkRes res - | None -> - if newOk = NoNewTypars then - let suggestTypeParameters (addToBuffer: string -> unit) = - for p in env.eNameResEnv.eTypars do - addToBuffer ("'" + p.Key) - - match tpenv with - | UnscopedTyparEnv elements -> - for p in elements do - addToBuffer ("'" + p.Key) - - let reportedId = Ident("'" + id.idText, id.idRange) - error (UndefinedName(0, FSComp.SR.undefinedNameTypeParameter, reportedId, suggestTypeParameters)) - - // OK, this is an implicit declaration of a type parameter - // The kind defaults to Type - let tp' = NewTypar ((match optKind with None -> TyparKind.Type | Some kind -> kind), TyparRigidity.WarnIfNotRigid, tp, false, TyparDynamicReq.Yes, [], false, false) - let item = Item.TypeVar(id.idText, tp') - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights) - tp', AddUnscopedTypar key tp' tpenv - -and TcTypar cenv env newOk tpenv tp = - TcTyparOrMeasurePar (Some TyparKind.Type) cenv env newOk tpenv tp - -and TcTyparDecl cenv env (TyparDecl(Attributes synAttrs, (Typar(id, _, _) as stp))) = - let attrs = TcAttributes cenv env AttributeTargets.GenericParameter synAttrs - let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs - let hasEqDepAttr = HasFSharpAttribute cenv.g cenv.g.attrib_EqualityConditionalOnAttribute attrs - let hasCompDepAttr = HasFSharpAttribute cenv.g cenv.g.attrib_ComparisonConditionalOnAttribute attrs - let attrs = attrs |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute >> not) - let tp = NewTypar ((if hasMeasureAttr then TyparKind.Measure else TyparKind.Type), TyparRigidity.WarnIfNotRigid, stp, false, TyparDynamicReq.Yes, attrs, hasEqDepAttr, hasCompDepAttr) - match TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs with - | Some compiledName -> - tp.SetILName (Some compiledName) - | None -> - () - let item = Item.TypeVar(id.idText, tp) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights) - tp - - -and TcTyparDecls cenv env synTypars = List.map (TcTyparDecl cenv env) synTypars - -/// Check and elaborate a syntactic type or measure -/// If optKind=Some kind, then this is the kind we're expecting (we're in *analysis* mode) -/// If optKind=None, we need to determine the kind (we're in *synthesis* mode) -/// -and TcTypeOrMeasure optKind cenv newOk checkCxs occ env (tpenv: SyntacticUnscopedTyparEnv) ty = - let g = cenv.g - - match ty with - | SynType.LongIdent(LongIdentWithDots([], _)) -> - // special case when type name is absent - i.e. empty inherit part in type declaration - g.obj_ty, tpenv - - | SynType.LongIdent(LongIdentWithDots(tc, _) as lidwd) -> - let m = lidwd.Range - let ad = env.eAccessRights - let tcref = ForceRaise(ResolveTypeLongIdent cenv.tcSink cenv.nameResolver occ OpenQualified env.eNameResEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No) - match optKind, tcref.TypeOrMeasureKind with - | Some TyparKind.Type, TyparKind.Measure -> - error(Error(FSComp.SR.tcExpectedTypeNotUnitOfMeasure(), m)) - NewErrorType (), tpenv - | Some TyparKind.Measure, TyparKind.Type -> - error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) - TType_measure (NewErrorMeasure ()), tpenv - | _, TyparKind.Measure -> - TType_measure (Measure.Con tcref), tpenv - | _, TyparKind.Type -> - TcTypeApp cenv newOk checkCxs occ env tpenv m tcref [] [] - - | SynType.App (SynType.LongIdent(LongIdentWithDots(tc, _)), _, args, _commas, _, postfix, m) -> - let ad = env.eAccessRights - - let tcref = - let tyResInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs args.Length - ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInType OpenQualified env.eNameResEnv ad tc tyResInfo PermitDirectReferenceToGeneratedType.No - |> ForceRaise - - match optKind, tcref.TypeOrMeasureKind with - | Some TyparKind.Type, TyparKind.Measure -> - error(Error(FSComp.SR.tcExpectedTypeNotUnitOfMeasure(), m)) - NewErrorType (), tpenv - - | Some TyparKind.Measure, TyparKind.Type -> - error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) - TType_measure (NewErrorMeasure ()), tpenv - - | _, TyparKind.Type -> - if postfix && tcref.Typars m |> List.exists (fun tp -> match tp.Kind with TyparKind.Measure -> true | _ -> false) - then error(Error(FSComp.SR.tcInvalidUnitsOfMeasurePrefix(), m)) - TcTypeApp cenv newOk checkCxs occ env tpenv m tcref [] args - | _, TyparKind.Measure -> - match args, postfix with - | [arg], true -> - let ms, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg m - TType_measure (Measure.Prod(Measure.Con tcref, ms)), tpenv - - | _, _ -> - errorR(Error(FSComp.SR.tcUnitsOfMeasureInvalidInTypeConstructor(), m)) - NewErrorType (), tpenv - - | SynType.LongIdentApp (ltyp, LongIdentWithDots(longId, _), _, args, _commas, _, m) -> - let ad = env.eAccessRights - let ltyp, tpenv = TcType cenv newOk checkCxs occ env tpenv ltyp - match ltyp with - | AppTy g (tcref, tinst) -> - let tcref = ResolveTypeLongIdentInTyconRef cenv.tcSink cenv.nameResolver env.eNameResEnv (TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.FromTyArgs args.Length)) ad m tcref longId - TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinst args - | _ -> error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), m)) - - | SynType.Tuple(isStruct, args, m) -> - let tupInfo = mkTupInfo isStruct - if isStruct then - let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m - TType_tuple(tupInfo,args'),tpenv - else - let isMeasure = match optKind with Some TyparKind.Measure -> true | None -> List.exists (fun (isquot,_) -> isquot) args | _ -> false - if isMeasure then - let ms,tpenv = TcMeasuresAsTuple cenv newOk checkCxs occ env tpenv args m - TType_measure ms,tpenv - else - let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m - TType_tuple(tupInfo,args'),tpenv - - | SynType.AnonRecd(isStruct, args,m) -> - let tupInfo = mkTupInfo isStruct - let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv (args |> List.map snd |> List.map (fun x -> (false,x))) m - let unsortedFieldIds = args |> List.map fst |> List.toArray - let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, tupInfo, unsortedFieldIds) - // Sort into canonical order - let sortedFieldTys, sortedCheckedArgTys = List.zip args args' |> List.indexed |> List.sortBy (fun (i,_) -> unsortedFieldIds.[i].idText) |> List.map snd |> List.unzip - sortedFieldTys |> List.iteri (fun i (x,_) -> - let item = Item.AnonRecdField(anonInfo, sortedCheckedArgTys, i, x.idRange) - CallNameResolutionSink cenv.tcSink (x.idRange,env.NameEnv,item,item,emptyTyparInst,ItemOccurence.UseInType,env.DisplayEnv,env.eAccessRights)) - TType_anon(anonInfo, sortedCheckedArgTys),tpenv - - | SynType.Fun(domainTy, resultTy, _) -> - let domainTy', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv domainTy - let resultTy', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv resultTy - (domainTy' --> resultTy'), tpenv - - | SynType.Array (n, elemTy, m) -> - let elemTy, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv elemTy - mkArrayTy g n elemTy m, tpenv - - | SynType.Var (tp, _) -> - let tp', tpenv = TcTyparOrMeasurePar optKind cenv env newOk tpenv tp - match tp'.Kind with - | TyparKind.Measure -> TType_measure (Measure.Var tp'), tpenv - | TyparKind.Type -> mkTyparTy tp', tpenv - - // _ types - | SynType.Anon m -> - let tp: Typar = TcAnonTypeOrMeasure optKind cenv TyparRigidity.Anon TyparDynamicReq.No newOk m - match tp.Kind with - | TyparKind.Measure -> TType_measure (Measure.Var tp), tpenv - | TyparKind.Type -> mkTyparTy tp, tpenv - - | SynType.WithGlobalConstraints(ty, wcs, _) -> - let cty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty - let tpenv = TcTyparConstraints cenv newOk checkCxs occ env tpenv wcs - cty, tpenv - - // #typ - | SynType.HashConstraint(ty, m) -> - let tp = TcAnonTypeOrMeasure (Some TyparKind.Type) cenv TyparRigidity.WarnIfNotRigid TyparDynamicReq.Yes newOk m - let ty', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace ty' (mkTyparTy tp) - tp.AsType, tpenv - - | SynType.StaticConstant (c, m) -> - match c, optKind with - | _, Some TyparKind.Type -> - errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) - NewErrorType (), tpenv - | SynConst.Int32 1, _ -> - TType_measure Measure.One, tpenv - | _ -> - errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) - NewErrorType (), tpenv - - | SynType.StaticConstantNamed (_, _, m) - - | SynType.StaticConstantExpr (_, m) -> - errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m)) - NewErrorType (), tpenv - - | SynType.MeasurePower(ty, exponent, m) -> - match optKind with - | Some TyparKind.Type -> - errorR(Error(FSComp.SR.tcUnexpectedSymbolInTypeExpression("^"), m)) - NewErrorType (), tpenv - | _ -> - let ms, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv ty m - TType_measure (Measure.RationalPower (ms, TcSynRationalConst exponent)), tpenv - - | SynType.MeasureDivide(typ1, typ2, m) -> - match optKind with - | Some TyparKind.Type -> - errorR(Error(FSComp.SR.tcUnexpectedSymbolInTypeExpression("/"), m)) - NewErrorType (), tpenv - | _ -> - let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv typ1 m - let ms2, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv typ2 m - TType_measure (Measure.Prod(ms1, Measure.Inv ms2)), tpenv - - | SynType.App((SynType.Var(_, m1) | SynType.MeasurePower(_, _, m1)) as arg1, _, args, _commas, _, postfix, m) -> - match optKind, args, postfix with - | (None | Some TyparKind.Measure), [arg2], true -> - let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg1 m1 - let ms2, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv arg2 m - TType_measure (Measure.Prod(ms1, ms2)), tpenv - - | _ -> - errorR(Error(FSComp.SR.tcTypeParameterInvalidAsTypeConstructor(), m)) - NewErrorType (), tpenv - - | SynType.App(_, _, _, _, _, _, m) -> - errorR(Error(FSComp.SR.tcIllegalSyntaxInTypeExpression(), m)) - NewErrorType (), tpenv - -and TcType cenv newOk checkCxs occ env (tpenv: SyntacticUnscopedTyparEnv) ty = - TcTypeOrMeasure (Some TyparKind.Type) cenv newOk checkCxs occ env tpenv ty - -and TcMeasure cenv newOk checkCxs occ env (tpenv: SyntacticUnscopedTyparEnv) ty m = - match ty with - | SynType.Anon m -> - error(Error(FSComp.SR.tcAnonymousUnitsOfMeasureCannotBeNested(), m)) - NewErrorMeasure (), tpenv - | _ -> - match TcTypeOrMeasure (Some TyparKind.Measure) cenv newOk checkCxs occ env tpenv ty with - | TType_measure ms, tpenv -> ms, tpenv - | _ -> - error(Error(FSComp.SR.tcExpectedUnitOfMeasureNotType(), m)) - NewErrorMeasure (), tpenv - -and TcAnonTypeOrMeasure optKind _cenv rigid dyn newOk m = - if newOk = NoNewTypars then errorR (Error(FSComp.SR.tcAnonymousTypeInvalidInDeclaration(), m)) - let rigid = (if rigid = TyparRigidity.Anon && newOk = NewTyparsOKButWarnIfNotRigid then TyparRigidity.WarnIfNotRigid else rigid) - let kind = match optKind with Some TyparKind.Measure -> TyparKind.Measure | _ -> TyparKind.Type - NewAnonTypar (kind, m, rigid, NoStaticReq, dyn) - -and TcTypes cenv newOk checkCxs occ env tpenv args = - List.mapFold (TcTypeAndRecover cenv newOk checkCxs occ env) tpenv args - -and TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m = - match args with - | [] -> error(InternalError("empty tuple type", m)) - | [(_, ty)] -> let ty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty in [ty], tpenv - | (isquot, ty) :: args -> - let ty, tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty - let tys, tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m - if isquot then errorR(Error(FSComp.SR.tcUnexpectedSlashInType(), m)) - ty :: tys, tpenv - -// Type-check a list of measures separated by juxtaposition, * or / -and TcMeasuresAsTuple cenv newOk checkCxs occ env (tpenv: SyntacticUnscopedTyparEnv) args m = - let rec gather args tpenv isquot acc = - match args with - | [] -> acc, tpenv - | (nextisquot, ty) :: args -> - let ms1, tpenv = TcMeasure cenv newOk checkCxs occ env tpenv ty m - gather args tpenv nextisquot (if isquot then Measure.Prod(acc, Measure.Inv ms1) else Measure.Prod(acc, ms1)) - gather args tpenv false Measure.One - -and TcTypesOrMeasures optKinds cenv newOk checkCxs occ env tpenv args m = - match optKinds with - | None -> - List.mapFold (TcTypeOrMeasure None cenv newOk checkCxs occ env) tpenv args - | Some kinds -> - if List.length kinds = List.length args then - List.mapFold (fun tpenv (arg, kind) -> TcTypeOrMeasure (Some kind) cenv newOk checkCxs occ env tpenv arg) tpenv (List.zip args kinds) - elif isNil kinds then error(Error(FSComp.SR.tcUnexpectedTypeArguments(), m)) - else error(Error(FSComp.SR.tcTypeParameterArityMismatch((List.length kinds), (List.length args)), m)) - -and TcTyparConstraints cenv newOk checkCxs occ env tpenv wcs = - // Mark up default constraints with a priority in reverse order: last gets 0, second - // last gets 1 etc. See comment on TyparConstraint.DefaultsTo - let _, tpenv = List.fold (fun (ridx, tpenv) tc -> ridx - 1, TcTyparConstraint ridx cenv newOk checkCxs occ env tpenv tc) (List.length wcs - 1, tpenv) wcs - tpenv - -#if !NO_EXTENSIONTYPING -and TcStaticConstantParameter cenv (env: TcEnv) tpenv kind (v: SynType) idOpt container = - let g = cenv.g - let fail() = error(Error(FSComp.SR.etInvalidStaticArgument(NicePrint.minimalStringOfType env.DisplayEnv kind), v.Range)) - let record ttype = - match idOpt with - | Some id -> - let item = Item.ArgName (id, ttype, Some container) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - | _ -> () - - match v with - | SynType.StaticConstant(sc, _) -> - let v = - match sc with - | SynConst.Byte n when typeEquiv g g.byte_ty kind -> record(g.byte_ty); box (n: byte) - | SynConst.Int16 n when typeEquiv g g.int16_ty kind -> record(g.int16_ty); box (n: int16) - | SynConst.Int32 n when typeEquiv g g.int32_ty kind -> record(g.int32_ty); box (n: int) - | SynConst.Int64 n when typeEquiv g g.int64_ty kind -> record(g.int64_ty); box (n: int64) - | SynConst.SByte n when typeEquiv g g.sbyte_ty kind -> record(g.sbyte_ty); box (n: sbyte) - | SynConst.UInt16 n when typeEquiv g g.uint16_ty kind -> record(g.uint16_ty); box (n: uint16) - | SynConst.UInt32 n when typeEquiv g g.uint32_ty kind -> record(g.uint32_ty); box (n: uint32) - | SynConst.UInt64 n when typeEquiv g g.uint64_ty kind -> record(g.uint64_ty); box (n: uint64) - | SynConst.Decimal n when typeEquiv g g.decimal_ty kind -> record(g.decimal_ty); box (n: decimal) - | SynConst.Single n when typeEquiv g g.float32_ty kind -> record(g.float32_ty); box (n: single) - | SynConst.Double n when typeEquiv g g.float_ty kind -> record(g.float_ty); box (n: double) - | SynConst.Char n when typeEquiv g g.char_ty kind -> record(g.char_ty); box (n: char) - | SynConst.String (s, _) when s <> null && typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string) - | SynConst.Bool b when typeEquiv g g.bool_ty kind -> record(g.bool_ty); box (b: bool) - | _ -> fail() - v, tpenv - | SynType.StaticConstantExpr(e, _ ) -> - - // If an error occurs, don't try to recover, since the constant expression will be nothing like what we need - let te, tpenv' = TcExprNoRecover cenv kind env tpenv e - - // Evaluate the constant expression using static attribute argument rules - let te = EvalLiteralExprOrAttribArg g te - let v = - match stripExpr te with - // Check we have a residue constant. We know the type was correct because we checked the expression with this type. - | Expr.Const (c, _, _) -> - match c with - | Const.Byte n -> record(g.byte_ty); box (n: byte) - | Const.Int16 n -> record(g.int16_ty); box (n: int16) - | Const.Int32 n -> record(g.int32_ty); box (n: int) - | Const.Int64 n -> record(g.int64_ty); box (n: int64) - | Const.SByte n -> record(g.sbyte_ty); box (n: sbyte) - | Const.UInt16 n -> record(g.uint16_ty); box (n: uint16) - | Const.UInt32 n -> record(g.uint32_ty); box (n: uint32) - | Const.UInt64 n -> record(g.uint64_ty); box (n: uint64) - | Const.Decimal n -> record(g.decimal_ty); box (n: decimal) - | Const.Single n -> record(g.float32_ty); box (n: single) - | Const.Double n -> record(g.float_ty); box (n: double) - | Const.Char n -> record(g.char_ty); box (n: char) - | Const.String null -> fail() - | Const.String s -> record(g.string_ty); box (s: string) - | Const.Bool b -> record(g.bool_ty); box (b: bool) - | _ -> fail() - | _ -> error(Error(FSComp.SR.tcInvalidConstantExpression(), v.Range)) - v, tpenv' - | SynType.LongIdent lidwd -> - let m = lidwd.Range - TcStaticConstantParameter cenv env tpenv kind (SynType.StaticConstantExpr(SynExpr.LongIdent (false, lidwd, None, m), m)) idOpt container - | _ -> - fail() - -and CrackStaticConstantArgs cenv env tpenv (staticParameters: Tainted[], args: SynType list, container, containerName, m) = - let args = - args |> List.map (function - | SynType.StaticConstantNamed(SynType.LongIdent(LongIdentWithDots([id], _)), v, _) -> Some id, v - | v -> None, v) - - let unnamedArgs = args |> Seq.takeWhile (fst >> Option.isNone) |> Seq.toArray |> Array.map snd - let otherArgs = args |> List.skipWhile (fst >> Option.isNone) - let namedArgs = otherArgs |> List.takeWhile (fst >> Option.isSome) |> List.map (map1Of2 Option.get) - let otherArgs = otherArgs |> List.skipWhile (fst >> Option.isSome) - if not otherArgs.IsEmpty then - error (Error(FSComp.SR.etBadUnnamedStaticArgs(), m)) - - let indexedStaticParameters = staticParameters |> Array.toList |> List.indexed - for (n, _) in namedArgs do - match indexedStaticParameters |> List.filter (fun (j, sp) -> j >= unnamedArgs.Length && n.idText = sp.PUntaint((fun sp -> sp.Name), m)) with - | [] -> - if staticParameters |> Array.exists (fun sp -> n.idText = sp.PUntaint((fun sp -> sp.Name), n.idRange)) then - error (Error(FSComp.SR.etStaticParameterAlreadyHasValue n.idText, n.idRange)) - else - error (Error(FSComp.SR.etNoStaticParameterWithName n.idText, n.idRange)) - | [_] -> () - | _ -> error (Error(FSComp.SR.etMultipleStaticParameterWithName n.idText, n.idRange)) - - if staticParameters.Length < namedArgs.Length + unnamedArgs.Length then - error (Error(FSComp.SR.etTooManyStaticParameters(staticParameters.Length, unnamedArgs.Length, namedArgs.Length), m)) - - let argsInStaticParameterOrderIncludingDefaults = - staticParameters |> Array.mapi (fun i sp -> - let spKind = Import.ImportProvidedType cenv.amap m (sp.PApply((fun x -> x.ParameterType), m)) - let spName = sp.PUntaint((fun sp -> sp.Name), m) - if i < unnamedArgs.Length then - let v = unnamedArgs.[i] - let v, _tpenv = TcStaticConstantParameter cenv env tpenv spKind v None container - v - else - match namedArgs |> List.filter (fun (n, _) -> n.idText = spName) with - | [(n, v)] -> - let v, _tpenv = TcStaticConstantParameter cenv env tpenv spKind v (Some n) container - v - | [] -> - if sp.PUntaint((fun sp -> sp.IsOptional), m) then - match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with - | null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, containerName, containerName, spName), m)) - | v -> v - else - error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, containerName, containerName, spName), m)) - | ps -> - error (Error(FSComp.SR.etMultipleStaticParameterWithName spName, (fst (List.last ps)).idRange))) - - argsInStaticParameterOrderIncludingDefaults - -and TcProvidedTypeAppToStaticConstantArgs cenv env optGeneratedTypePath tpenv (tcref: TyconRef) (args: SynType list) m = - let typeBeforeArguments = - match tcref.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.ProvidedType - | _ -> failwith "unreachable" - - let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.GetStaticParameters provider), range=m) - let staticParameters = staticParameters.PApplyArray(id, "GetStaticParameters", m) - - let argsInStaticParameterOrderIncludingDefaults = CrackStaticConstantArgs cenv env tpenv (staticParameters, args, ArgumentContainer.Type tcref, tcref.DisplayName, m) - - // Take the static arguments (as SynType's) and convert them to objects of the appropriate type, based on the expected kind. - let providedTypeAfterStaticArguments, checkTypeName = - match ExtensionTyping.TryApplyProvidedType(typeBeforeArguments, optGeneratedTypePath, argsInStaticParameterOrderIncludingDefaults, m) with - | None -> error(Error(FSComp.SR.etErrorApplyingStaticArgumentsToType(), m)) - | Some (ty, checkTypeName) -> (ty, checkTypeName) - - let hasNoArgs = (argsInStaticParameterOrderIncludingDefaults.Length = 0) - hasNoArgs, providedTypeAfterStaticArguments, checkTypeName - - -and TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos: MethInfo list, argsOpt, mExprAndArg, mItem) = - match minfos, argsOpt with - | [minfo], Some (args, _) -> - match minfo.ProvidedStaticParameterInfo with - | Some (methBeforeArguments, staticParams) -> - let providedMethAfterStaticArguments = TcProvidedMethodAppToStaticConstantArgs cenv env tpenv (minfo, methBeforeArguments, staticParams, args, mExprAndArg) - let minfoAfterStaticArguments = ProvidedMeth(cenv.amap, providedMethAfterStaticArguments, minfo.ExtensionMemberPriorityOption, mItem) - Some minfoAfterStaticArguments - | _ -> None - | _ -> None - -and TcProvidedMethodAppToStaticConstantArgs cenv env tpenv (minfo, methBeforeArguments, staticParams, args, m) = - - let argsInStaticParameterOrderIncludingDefaults = CrackStaticConstantArgs cenv env tpenv (staticParams, args, ArgumentContainer.Method minfo, minfo.DisplayName, m) - - let providedMethAfterStaticArguments = - match ExtensionTyping.TryApplyProvidedMethod(methBeforeArguments, argsInStaticParameterOrderIncludingDefaults, m) with - | None -> error(Error(FSComp.SR.etErrorApplyingStaticArgumentsToMethod(), m)) - | Some meth -> meth - - providedMethAfterStaticArguments - -and TcProvidedTypeApp cenv env tpenv tcref args m = - let hasNoArgs, providedTypeAfterStaticArguments, checkTypeName = TcProvidedTypeAppToStaticConstantArgs cenv env None tpenv tcref args m - - let isGenerated = providedTypeAfterStaticArguments.PUntaint((fun st -> not st.IsErased), m) - - //printfn "adding entity for provided type '%s', isDirectReferenceToGenerated = %b, isGenerated = %b" (st.PUntaint((fun st -> st.Name), m)) isDirectReferenceToGenerated isGenerated - let isDirectReferenceToGenerated = isGenerated && ExtensionTyping.IsGeneratedTypeDirectReference (providedTypeAfterStaticArguments, m) - if isDirectReferenceToGenerated then - error(Error(FSComp.SR.etDirectReferenceToGeneratedTypeNotAllowed(tcref.DisplayName), m)) - - // We put the type name check after the 'isDirectReferenceToGenerated' check because we need the 'isDirectReferenceToGenerated' error to be shown for generated types - checkTypeName() - if hasNoArgs then - mkAppTy tcref [], tpenv - else - let ty = Import.ImportProvidedType cenv.amap m providedTypeAfterStaticArguments - ty, tpenv -#endif - -/// Typecheck an application of a generic type to type arguments. -/// -/// Note that the generic type may be a nested generic type List.ListEnumerator. -/// In this case, 'args' is only the instantiation of the suffix type arguments, and pathTypeArgs gives -/// the prefix of type arguments. -and TcTypeApp cenv newOk checkCxs occ env tpenv m tcref pathTypeArgs (synArgTys: SynType list) = - let g = cenv.g - CheckTyconAccessible cenv.amap m env.eAccessRights tcref |> ignore - CheckEntityAttributes g tcref m |> CommitOperationResult - -#if !NO_EXTENSIONTYPING - // Provided types are (currently) always non-generic. Their names may include mangled - // static parameters, which are passed by the provider. - if tcref.Deref.IsProvided then TcProvidedTypeApp cenv env tpenv tcref synArgTys m else -#endif - - let tps, _, tinst, _ = infoOfTyconRef m tcref - - // If we're not checking constraints, i.e. when we first assert the super/interfaces of a type definition, then just - // clear the constraint lists of the freshly generated type variables. A little ugly but fairly localized. - if checkCxs = NoCheckCxs then tps |> List.iter (fun tp -> tp.SetConstraints []) - if tinst.Length <> pathTypeArgs.Length + synArgTys.Length then - error (TyconBadArgs(env.DisplayEnv, tcref, pathTypeArgs.Length + synArgTys.Length, m)) - - let argTys, tpenv = - // Get the suffix of typars - let tpsForArgs = List.drop (tps.Length - synArgTys.Length) tps - let kindsForArgs = tpsForArgs |> List.map (fun tp -> tp.Kind) - TcTypesOrMeasures (Some kindsForArgs) cenv newOk checkCxs occ env tpenv synArgTys m - - // Add the types of the enclosing class for a nested type - let actualArgTys = pathTypeArgs @ argTys - - if checkCxs = CheckCxs then - List.iter2 (UnifyTypes cenv env m) tinst actualArgTys - - // Try to decode System.Tuple --> F~ tuple types etc. - let ty = g.decompileType tcref actualArgTys - - ty, tpenv - -and TcTypeOrMeasureAndRecover optKind cenv newOk checkCxs occ env tpenv ty = - try TcTypeOrMeasure optKind cenv newOk checkCxs occ env tpenv ty - with e -> - errorRecovery e ty.Range - let rty = - match optKind, newOk with - | Some TyparKind.Measure, NoNewTypars -> TType_measure Measure.One - | Some TyparKind.Measure, _ -> TType_measure (NewErrorMeasure ()) - | _, NoNewTypars -> cenv.g.obj_ty - | _ -> NewErrorType () - rty, tpenv - - -and TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty = - TcTypeOrMeasureAndRecover (Some TyparKind.Type) cenv newOk checkCxs occ env tpenv ty - -and TcNestedTypeApplication cenv newOk checkCxs occ env tpenv mWholeTypeApp ty tyargs = - let ty = convertToTypeWithMetadataIfPossible cenv.g ty - if not (isAppTy cenv.g ty) then error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), mWholeTypeApp)) - match ty with - | TType_app(tcref, tinst) -> - let pathTypeArgs = List.truncate (max (tinst.Length - tcref.Typars(mWholeTypeApp).Length) 0) tinst - TcTypeApp cenv newOk checkCxs occ env tpenv mWholeTypeApp tcref pathTypeArgs tyargs - | _ -> error(InternalError("TcNestedTypeApplication: expected type application", mWholeTypeApp)) - - -and TryAdjustHiddenVarNameToCompGenName cenv env (id: Ident) altNameRefCellOpt = - match altNameRefCellOpt with - | Some ({contents = Undecided altId } as altNameRefCell) -> - match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false id.idRange env.eAccessRights env.eNameResEnv TypeNameResolutionInfo.Default [id] with - | Item.NewDef _ -> None // the name is not in scope as a pattern identifier (e.g. union case), so do not use the alternate ID - | _ -> altNameRefCell := Decided altId; Some altId // the name is in scope as a pattern identifier, so use the alternate ID - | Some ({contents = Decided altId }) -> Some altId - | None -> None - -/// Bind the patterns used in a lambda. Not clear why we don't use TcPat. -and TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p = - match p with - | SynSimplePat.Id (id, altNameRefCellOpt, compgen, isMemberThis, isOpt, m) -> - // Check to see if pattern translation decides to use an alternative identifier. - match TryAdjustHiddenVarNameToCompGenName cenv env id altNameRefCellOpt with - | Some altId -> TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) (SynSimplePat.Id (altId, None, compgen, isMemberThis, isOpt, m) ) - | None -> - if isOpt then - if not optArgsOK then - errorR(Error(FSComp.SR.tcOptionalArgsOnlyOnMembers(), m)) - - let tyarg = NewInferenceType () - UnifyTypes cenv env m ty (mkOptionTy cenv.g tyarg) - - let _, names, takenNames = TcPatBindingName cenv env id ty isMemberThis None None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, compgen) (names, takenNames) - id.idText, - (tpenv, names, takenNames) - - | SynSimplePat.Typed (p, cty, m) -> - let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK checkCxs ItemOccurence.UseInType env tpenv cty - match p with - // Optional arguments on members - | SynSimplePat.Id(_, _, _, _, true, _) -> UnifyTypes cenv env m ty (mkOptionTy cenv.g cty') - | _ -> UnifyTypes cenv env m ty cty' - - TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p - - | SynSimplePat.Attrib (p, _, _) -> - TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p - -// raise an error if any optional args precede any non-optional args -and ValidateOptArgOrder (spats: SynSimplePats) = - - let rec getPats spats = - match spats with - | SynSimplePats.SimplePats(p, m) -> p, m - | SynSimplePats.Typed(p, _, _) -> getPats p - - let rec isOptArg pat = - match pat with - | SynSimplePat.Id (_, _, _, _, isOpt, _) -> isOpt - | SynSimplePat.Typed (p, _, _) -> isOptArg p - | SynSimplePat.Attrib (p, _, _) -> isOptArg p - - let pats, m = getPats spats - - let mutable hitOptArg = false - - List.iter (fun pat -> if isOptArg pat then hitOptArg <- true elif hitOptArg then error(Error(FSComp.SR.tcOptionalArgsMustComeAfterNonOptionalArgs(), m))) pats - - -/// Bind the patterns used in argument position for a function, method or lambda. -and TcSimplePats cenv optArgsOK checkCxs ty env (tpenv, names, takenNames: Set<_>) p = - - // validate optional argument declaration - ValidateOptArgOrder p - - match p with - | SynSimplePats.SimplePats ([], m) -> - // Unit "()" patterns in argument position become SynSimplePats.SimplePats([], _) in the - // syntactic translation when building bindings. This is done because the - // use of "()" has special significance for arity analysis and argument counting. - // - // Here we give a name to the single argument implied by those patterns. - // This is a little awkward since it would be nice if this was - // uniform with the process where we give names to other (more complex) - // patterns used in argument position, e.g. "let f (D(x)) = ..." - let id = ident("unitVar" + string takenNames.Count, m) - UnifyTypes cenv env m ty cenv.g.unit_ty - let _, names, takenNames = TcPatBindingName cenv env id ty false None None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, true) (names, takenNames) - [id.idText], (tpenv, names, takenNames) - - | SynSimplePats.SimplePats ([p], _) -> - let v, (tpenv, names, takenNames) = TcSimplePat optArgsOK checkCxs cenv ty env (tpenv, names, takenNames) p - [v], (tpenv, names, takenNames) - - | SynSimplePats.SimplePats (ps, m) -> - let ptys = UnifyRefTupleType env.eContextInfo cenv env.DisplayEnv m ty ps - let ps', (tpenv, names, takenNames) = List.mapFold (fun tpenv (ty, e) -> TcSimplePat optArgsOK checkCxs cenv ty env tpenv e) (tpenv, names, takenNames) (List.zip ptys ps) - ps', (tpenv, names, takenNames) - - | SynSimplePats.Typed (p, cty, m) -> - let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty - - match p with - // Solitary optional arguments on members - | SynSimplePats.SimplePats([SynSimplePat.Id(_, _, _, _, true, _)], _) -> UnifyTypes cenv env m ty (mkOptionTy cenv.g cty') - | _ -> UnifyTypes cenv env m ty cty' - - TcSimplePats cenv optArgsOK checkCxs ty env (tpenv, names, takenNames) p - -and TcSimplePatsOfUnknownType cenv optArgsOK checkCxs env tpenv spats = - let argty = NewInferenceType () - TcSimplePats cenv optArgsOK checkCxs argty env (tpenv, NameMap.empty, Set.empty) spats - -and TcPatBindingName cenv env id ty isMemberThis vis1 topValData (inlineFlag, declaredTypars, argAttribs, isMutable, vis2, compgen) (names, takenNames: Set) = - let vis = if Option.isSome vis1 then vis1 else vis2 - if takenNames.Contains id.idText then errorR (VarBoundTwice id) - let compgen = compgen || IsCompilerGeneratedName id.idText - let baseOrThis = if isMemberThis then MemberThisVal else NormalVal - let names = Map.add id.idText (PrelimValScheme1(id, declaredTypars, ty, topValData, None, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) names - let takenNames = Set.add id.idText takenNames - (fun (TcPatPhase2Input (values, isLeftMost)) -> - let (vspec, typeScheme) = - let name = id.idText - match values.TryGetValue name with - | true, value -> - if not (String.IsNullOrEmpty name) && Char.IsLower(name.[0]) then - match env.eNameResEnv.ePatItems.TryGetValue name with - | true, Item.Value vref when vref.LiteralValue.IsSome -> - warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern name, id.idRange)) - | _ -> () - value - | _ -> error(Error(FSComp.SR.tcNameNotBoundInPattern name, id.idRange)) - - // isLeftMost indicates we are processing the left-most path through a disjunctive or pattern. - // For those binding locations, CallNameResolutionSink is called in MakeAndPublishValue, like all other bindings - // For non-left-most paths, we register the name resolutions here - if not isLeftMost && not vspec.IsCompilerGenerated && not (vspec.LogicalName.StartsWithOrdinal("_")) then - let item = Item.Value(mkLocalValRef vspec) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights) - - PBind(vspec, typeScheme)), - names, takenNames - -and TcPatAndRecover warnOnUpper cenv (env: TcEnv) topValInfo vFlags (tpenv, names, takenNames) ty (pat: SynPat) = - try - TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty pat - with e -> - // Error recovery - return some rubbish expression, but replace/annotate - // the type of the current expression with a type variable that indicates an error - let m = pat.Range - errorRecovery e m - //solveTypAsError cenv env.DisplayEnv m ty - (fun _ -> TPat_wild m), (tpenv, names, takenNames) - -/// Typecheck a pattern. Patterns are type-checked in three phases: -/// 1. TcPat builds a List.map from simple variable names to inferred types for -/// those variables. It also returns a function to perform the second phase. -/// 2. The second phase assumes the caller has built the actual value_spec's -/// for the values being defined, and has decided if the types of these -/// variables are to be generalized. The caller hands this information to -/// the second-phase function in terms of a List.map from names to actual -/// value specifications. -and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty pat = - let ad = env.eAccessRights - match pat with - | SynPat.Const (c, m) -> - match c with - | SynConst.Bytes (bytes, m) -> - UnifyTypes cenv env m ty (mkByteArrayTy cenv.g) - TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty (SynPat.ArrayOrList (true, [ for b in bytes -> SynPat.Const(SynConst.Byte b, m) ], m)) - | SynConst.UserNum _ -> - error(Error(FSComp.SR.tcInvalidNonPrimitiveLiteralInPatternMatch(), m)) - | _ -> - let c' = TcConst cenv ty m env c - (fun (_: TcPatPhase2Input) -> TPat_const(c', m)), (tpenv, names, takenNames) - - | SynPat.Wild m -> - (fun _ -> TPat_wild m), (tpenv, names, takenNames) - - | SynPat.IsInst(cty, m) - | SynPat.Named (SynPat.IsInst(cty, m), _, _, _, _) -> - let srcTy = ty - let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOKButWarnIfNotRigid CheckCxs ItemOccurence.UseInType env tpenv cty - TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy - match pat with - | SynPat.IsInst(_, m) -> - (fun _ -> TPat_isinst (srcTy, tgtTy, None, m)), (tpenv, names, takenNames) - | SynPat.Named (SynPat.IsInst _, id, isMemberThis, vis, m) -> - let bindf, names, takenNames = TcPatBindingName cenv env id tgtTy isMemberThis vis None vFlags (names, takenNames) - (fun values -> TPat_isinst (srcTy, tgtTy, Some(bindf values), m)), - (tpenv, names, takenNames) - | _ -> failwith "TcPat" - - | SynPat.OptionalVal (_, m) -> - error(Error(FSComp.SR.tcOptionalArgsOnlyOnMembers(), m)) - - | SynPat.Named (p, id, isMemberThis, vis, m) -> - let bindf, names, takenNames = TcPatBindingName cenv env id ty isMemberThis vis topValInfo vFlags (names, takenNames) - let pat', acc = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p - (fun values -> TPat_as (pat' values, bindf values, m)), - acc - - | SynPat.Typed (p, cty, m) -> - let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty - UnifyTypes cenv env m ty cty' - TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p - - | SynPat.Attrib (_, _, m) -> - error(Error(FSComp.SR.tcAttributesInvalidInPatterns(), m)) - - | SynPat.Or (pat1, pat2, m) -> - let pat1', (tpenv, names1, takenNames1) = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty pat1 - let pat2', (tpenv, names2, takenNames2) = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty pat2 - if not (takenNames1 = takenNames2) then - // We don't try to recover from this error since we get later bad internal errors during pattern - // matching - error (UnionPatternsBindDifferentNames m) - names1 |> Map.iter (fun _ (PrelimValScheme1(id1, _, ty1, _, _, _, _, _, _, _, _)) -> - match names2.TryGetValue id1.idText with - | true, PrelimValScheme1(_, _, ty2, _, _, _, _, _, _, _, _) -> - UnifyTypes cenv env m ty1 ty2 - | _ -> ()) - (fun values -> TPat_disjs ([pat1' values;pat2' values.RightPath], m)), (tpenv, names1, takenNames1) - - | SynPat.Ands (pats, m) -> - let pats', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (List.map (fun _ -> ty) pats) pats - (fun values -> TPat_conjs(List.map (fun f -> f values) pats', m)), acc - - | SynPat.LongIdent (LongIdentWithDots(longId, _), _, tyargs, args, vis, m) -> - if Option.isSome tyargs then errorR(Error(FSComp.SR.tcInvalidTypeArgumentUsage(), m)) - let warnOnUpperForId = - match args with - | SynConstructorArgs.Pats [] -> warnOnUpper - | _ -> AllIdsOK - - let checkNoArgsForLiteral() = - let numArgs = - match args with - | SynConstructorArgs.Pats args -> args.Length - | SynConstructorArgs.NamePatPairs (pairs, _) -> pairs.Length - if numArgs <> 0 then error(Error(FSComp.SR.tcLiteralDoesNotTakeArguments(), m)) - - match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver warnOnUpperForId false m ad env.eNameResEnv TypeNameResolutionInfo.Default longId with - | Item.NewDef id -> - match args with - | SynConstructorArgs.Pats [] - | SynConstructorArgs.NamePatPairs ([], _)-> TcPat warnOnUpperForId cenv env topValInfo vFlags (tpenv, names, takenNames) ty (mkSynPatVar vis id) - | _ -> error (UndefinedName(0, FSComp.SR.undefinedNamePatternDiscriminator, id, NoSuggestions)) - - | Item.ActivePatternCase(APElemRef(apinfo, vref, idx)) as item -> - let args = match args with SynConstructorArgs.Pats args -> args | _ -> error(Error(FSComp.SR.tcNamedActivePattern(apinfo.ActiveTags.[idx]), m)) - // TOTAL/PARTIAL ACTIVE PATTERNS - let _, vexp, _, _, tinst, _ = TcVal true cenv env tpenv vref None None m - let vexp = MakeApplicableExprWithFlex cenv env vexp - let vexpty = vexp.Type - - let activePatArgsAsSynPats, patarg = - match args with - | [] -> [], SynPat.Const(SynConst.Unit, m) - | _ -> - // This bit of type-directed analysis ensures that parameterized partial active patterns returning unit do not need to take an argument - // See FSharp 1.0 3502 - let dtys, rty = stripFunTy cenv.g vexpty - - if dtys.Length = args.Length + 1 && isOptionTy cenv.g rty && isUnitTy cenv.g (destOptionTy cenv.g rty) then - args, SynPat.Const(SynConst.Unit, m) - else - List.frontAndBack args - - if not (isNil activePatArgsAsSynPats) && apinfo.ActiveTags.Length <> 1 then - error(Error(FSComp.SR.tcRequireActivePatternWithOneResult(), m)) - - // Parse the arguments to an active pattern - // Note we parse arguments to parameterized pattern labels as patterns, not expressions. - // This means the range of syntactic expression forms that can be used here is limited. - let rec convSynPatToSynExpr x = - match x with - | SynPat.FromParseError(p, _) -> convSynPatToSynExpr p - | SynPat.Const (c, m) -> SynExpr.Const (c, m) - | SynPat.Named (SynPat.Wild _, id, _, None, _) -> SynExpr.Ident id - | SynPat.Typed (p, cty, m) -> SynExpr.Typed (convSynPatToSynExpr p, cty, m) - | SynPat.LongIdent (LongIdentWithDots(longId, dotms) as lidwd, _, _tyargs, args, None, m) -> - let args = match args with SynConstructorArgs.Pats args -> args | _ -> failwith "impossible: active patterns can be used only with SynConstructorArgs.Pats" - let e = - if dotms.Length = longId.Length then - let e = SynExpr.LongIdent (false, LongIdentWithDots(longId, List.truncate (dotms.Length - 1) dotms), None, m) - SynExpr.DiscardAfterMissingQualificationAfterDot (e, unionRanges e.Range (List.last dotms)) - else SynExpr.LongIdent (false, lidwd, None, m) - List.fold (fun f x -> mkSynApp1 f (convSynPatToSynExpr x) m) e args - | SynPat.Tuple (isStruct, args, m) -> SynExpr.Tuple (isStruct, List.map convSynPatToSynExpr args, [], m) - | SynPat.Paren (p, _) -> convSynPatToSynExpr p - | SynPat.ArrayOrList (isArray, args, m) -> SynExpr.ArrayOrList (isArray,List.map convSynPatToSynExpr args, m) - | SynPat.QuoteExpr (e,_) -> e - | SynPat.Null m -> SynExpr.Null m - | _ -> error(Error(FSComp.SR.tcInvalidArgForParameterizedPattern(), x.Range)) - let activePatArgsAsSynExprs = List.map convSynPatToSynExpr activePatArgsAsSynPats - - let activePatResTys = NewInferenceTypes apinfo.Names - let activePatType = apinfo.OverallType cenv.g m ty activePatResTys - - let delayed = activePatArgsAsSynExprs |> List.map (fun arg -> DelayedApp(ExprAtomicFlag.NonAtomic, arg, unionRanges (rangeOfLid longId) arg.Range)) - let activePatExpr, tpenv = PropagateThenTcDelayed cenv activePatType env tpenv m vexp vexpty ExprAtomicFlag.NonAtomic delayed - - if idx >= activePatResTys.Length then error(Error(FSComp.SR.tcInvalidIndexIntoActivePatternArray(), m)) - let argty = List.item idx activePatResTys - - let arg', (tpenv, names, takenNames) = TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) argty patarg - - // The identity of an active pattern consists of its value and the types it is applied to. - // If there are any expression args then we've lost identity. - let activePatIdentity = if isNil activePatArgsAsSynExprs then Some (vref, tinst) else None - (fun values -> - // Report information about the 'active recognizer' occurrence to IDE - CallNameResolutionSink cenv.tcSink (rangeOfLid longId, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.eAccessRights) - TPat_query((activePatExpr, activePatResTys, activePatIdentity, idx, apinfo), arg' values, m)), - (tpenv, names, takenNames) - - | (Item.UnionCase _ | Item.ExnCase _) as item -> - // DATA MATCH CONSTRUCTORS - let mkf, argTys, argNames = ApplyUnionCaseOrExnTypesForPat m cenv env ty item - let numArgTys = argTys.Length - - let args = - match args with - | SynConstructorArgs.Pats args -> args - | SynConstructorArgs.NamePatPairs (pairs, m) -> - // rewrite patterns from the form (name-N = pat-N...) to (..._, pat-N, _...) - // so type T = Case of name: int * value: int - // | Case(value = v) - // will become - // | Case(_, v) - let result = Array.zeroCreate numArgTys - for (id, pat) in pairs do - match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with - | None -> - match item with - | Item.UnionCase(uci, _) -> - error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(uci.Name, id.idText), id.idRange)) - | Item.ExnCase tcref -> - error(Error(FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName(tcref.DisplayName, id.idText), id.idRange)) - | _ -> - error(Error(FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName(id.idText), id.idRange)) - - | Some idx -> - match box result.[idx] with - | null -> - result.[idx] <- pat - let argContainerOpt = match item with - | Item.UnionCase(uci, _) -> Some(ArgumentContainer.UnionCase uci) - | Item.ExnCase tref -> Some(ArgumentContainer.Type tref) - | _ -> None - let argItem = Item.ArgName (argNames.[idx], argTys.[idx], argContainerOpt) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, argItem, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, ad) - | _ -> - error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) - for i = 0 to numArgTys - 1 do - if isNull (box result.[i]) then - result.[i] <- SynPat.Wild(m.MakeSynthetic()) - - let args = List.ofArray result - if result.Length = 1 then args - else [ SynPat.Tuple(false, args, m) ] - - let args = - match args with - | []-> [] - // note: the next will always be parenthesized - | [SynPatErrorSkip(SynPat.Tuple (false, args, _)) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Tuple (false, args, _)), _))] when numArgTys > 1 -> args - - // note: we allow both 'C _' and 'C (_)' regardless of number of argument of the pattern - | [SynPatErrorSkip(SynPat.Wild _ as e) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Wild _ as e), _))] -> Array.toList (Array.create numArgTys e) - | [arg] -> [arg] - | _ when numArgTys = 0 -> error(Error(FSComp.SR.tcUnionCaseDoesNotTakeArguments(), m)) - | _ when numArgTys = 1 -> error(Error(FSComp.SR.tcUnionCaseRequiresOneArgument(), m)) - | _ -> error(Error(FSComp.SR.tcUnionCaseExpectsTupledArguments numArgTys, m)) - UnionCaseOrExnCheck env numArgTys args.Length m - - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args - (fun values -> - // Report information about the case occurrence to IDE - CallNameResolutionSink cenv.tcSink (rangeOfLid longId, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.eAccessRights) - mkf m (List.map (fun f -> f values) args')), acc - - | Item.ILField finfo -> - // LITERAL .NET FIELDS - CheckILFieldInfoAccessible cenv.g cenv.amap m env.eAccessRights finfo - if not finfo.IsStatic then errorR (Error (FSComp.SR.tcFieldIsNotStatic(finfo.FieldName), m)) - CheckILFieldAttributes cenv.g finfo m - match finfo.LiteralValue with - | None -> error (Error(FSComp.SR.tcFieldNotLiteralCannotBeUsedInPattern(), m)) - | Some lit -> - checkNoArgsForLiteral() - UnifyTypes cenv env m ty (finfo.FieldType(cenv.amap, m)) - let c' = TcFieldInit m lit - let item = Item.ILField finfo - CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.AccessRights) - (fun _ -> TPat_const (c', m)), (tpenv, names, takenNames) - - | Item.RecdField rfinfo -> - // LITERAL F# FIELDS - CheckRecdFieldInfoAccessible cenv.amap m env.eAccessRights rfinfo - if not rfinfo.IsStatic then errorR (Error (FSComp.SR.tcFieldIsNotStatic(rfinfo.Name), m)) - CheckRecdFieldInfoAttributes cenv.g rfinfo m |> CommitOperationResult - match rfinfo.LiteralValue with - | None -> error (Error(FSComp.SR.tcFieldNotLiteralCannotBeUsedInPattern(), m)) - | Some lit -> - checkNoArgsForLiteral() - UnifyTypes cenv env m ty rfinfo.FieldType - let item = Item.RecdField rfinfo - // FUTURE: can we do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE. - CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.AccessRights) - (fun _ -> TPat_const (lit, m)), (tpenv, names, takenNames) - - | Item.Value vref -> - match vref.LiteralValue with - | None -> error (Error(FSComp.SR.tcNonLiteralCannotBeUsedInPattern(), m)) - | Some lit -> - let _, _, _, vexpty, _, _ = TcVal true cenv env tpenv vref None None m - CheckValAccessible m env.eAccessRights vref - CheckFSharpAttributes cenv.g vref.Attribs m |> CommitOperationResult - checkNoArgsForLiteral() - UnifyTypes cenv env m ty vexpty - let item = Item.Value vref - CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.AccessRights) - (fun _ -> TPat_const (lit, m)), (tpenv, names, takenNames) - - | _ -> error (Error(FSComp.SR.tcRequireVarConstRecogOrLiteral(), m)) - - | SynPat.QuoteExpr(_, m) -> error (Error(FSComp.SR.tcInvalidPattern(), m)) - - | SynPat.Tuple (isExplicitStruct, args, m) -> - let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m ty isExplicitStruct args - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args - (fun values -> TPat_tuple(tupInfo, List.map (fun f -> f values) args', argTys, m)), acc - - | SynPat.Paren (p, _) -> - TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p - - | SynPat.ArrayOrList (isArray, args, m) -> - let argty = NewInferenceType () - UnifyTypes cenv env m ty (if isArray then mkArrayType cenv.g argty else Tastops.mkListTy cenv.g argty) - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) (List.map (fun _ -> argty) args) args - (fun values -> - let args' = List.map (fun f -> f values) args' - if isArray then TPat_array(args', argty, m) - else List.foldBack (mkConsListPat cenv.g argty) args' (mkNilListPat cenv.g m argty)), acc - - | SynPat.Record (flds, m) -> - let tcref, fldsmap, _fldsList = BuildFieldMap cenv env true ty flds m - // REVIEW: use _fldsList to type check pattern in code order not field defn order - let _, inst, tinst, gtyp = infoOfTyconRef m tcref - UnifyTypes cenv env m ty gtyp - let fields = tcref.TrueInstanceFieldsAsList - let ftys = fields |> List.map (fun fsp -> actualTyOfRecdField inst fsp, fsp) - let fldsmap', acc = - ((tpenv, names, takenNames), ftys) ||> List.mapFold (fun s (ty, fsp) -> - match fldsmap.TryGetValue fsp.rfield_id.idText with - | true, v -> TcPat warnOnUpper cenv env None vFlags s ty v - | _ -> (fun _ -> TPat_wild m), s) - (fun values -> TPat_recd (tcref, tinst, List.map (fun f -> f values) fldsmap', m)), - acc - - | SynPat.DeprecatedCharRange (c1, c2, m) -> - errorR(Deprecated(FSComp.SR.tcUseWhenPatternGuard(), m)) - UnifyTypes cenv env m ty (cenv.g.char_ty) - (fun _ -> TPat_range(c1, c2, m)), (tpenv, names, takenNames) - - | SynPat.Null m -> - AddCxTypeMustSupportNull env.DisplayEnv cenv.css m NoTrace ty - (fun _ -> TPat_null m), (tpenv, names, takenNames) - - | SynPat.InstanceMember (_, _, _, _, m) -> - errorR(Error(FSComp.SR.tcIllegalPattern(), pat.Range)) - (fun _ -> TPat_wild m), (tpenv, names, takenNames) - | SynPat.FromParseError (pat, _) -> - suppressErrorReporting (fun () -> TcPatAndRecover warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) (NewErrorType()) pat) - -and TcPatterns warnOnUpper cenv env vFlags s argTys args = - assert (List.length args = List.length argTys) - List.mapFold (fun s (ty, pat) -> TcPat warnOnUpper cenv env None vFlags s ty pat) s (List.zip argTys args) - - -and solveTypAsError cenv denv m ty = - let ty2 = NewErrorType () - assert((destTyparTy cenv.g ty2).IsFromError) - SolveTypeEqualsTypeKeepAbbrevs (MakeConstraintSolverEnv ContextInfo.NoContext cenv.css m denv) 0 m NoTrace ty ty2 |> ignore - -and RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv expr = - // This function is motivated by cases like - // query { for ... join(for x in f(). } - // where there is incomplete code in a query, and we are current just dropping a piece of the AST on the floor (above, the bit inside the 'join'). - // - // The problem with dropping the AST on the floor is that we get no captured resolutions, which means no Intellisense/QuickInfo/ParamHelp. - // - // The idea behind the fix is to semi-typecheck this AST-fragment, just to get resolutions captured. - // - // The tricky bit is to not also have any other effects from typechecking, namely producing error diagnostics (which may be spurious) or having - // side-effects on the typecheck environment. - // - // REVIEW: We are yet to deal with the tricky bit. As it stands, we turn off error logging, but still have typechecking environment effects. As a result, - // at the very least, you cannot call this function unless you're already reported a typechecking error (the 'worst' possible outcome would be - // to incorrectly solve typecheck constraints as a result of effects in this function, and then have the code compile successfully and behave - // in some weird way; so ensure the code can't possibly compile before calling this function as an expedient way to get better IntelliSense). - suppressErrorReporting (fun () -> - try ignore(TcExprOfUnknownType cenv env tpenv expr) - with e -> ()) - -and RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed = - - let rec dummyCheckedDelayed delayed = - match delayed with - | DelayedApp (_hpa, arg, _mExprAndArg) :: otherDelayed -> - RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv arg - dummyCheckedDelayed otherDelayed - | _ -> () - dummyCheckedDelayed delayed - -// Calls UnifyTypes, but upon error only does the minimal error recovery -// so that IntelliSense information can continue to be collected. -and UnifyTypesAndRecover cenv env m expectedTy actualTy = - try - UnifyTypes cenv env m expectedTy actualTy - with e -> - errorRecovery e m - -and TcExprOfUnknownType cenv env tpenv expr = - let exprty = NewInferenceType () - let expr', tpenv = TcExpr cenv exprty env tpenv expr - expr', exprty, tpenv - -and TcExprFlex cenv flex compat ty (env: TcEnv) tpenv (e: SynExpr) = - if flex then - let argty = NewInferenceType () - if compat then - (destTyparTy cenv.g argty).SetIsCompatFlex(true) - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css e.Range NoTrace ty argty - let e', tpenv = TcExpr cenv argty env tpenv e - let e' = mkCoerceIfNeeded cenv.g ty argty e' - e', tpenv - else - TcExpr cenv ty env tpenv e - - -and TcExpr cenv ty (env: TcEnv) tpenv (expr: SynExpr) = - // Start an error recovery handler - // Note the try/catch can lead to tail-recursion problems for iterated constructs, e.g. let... in... - // So be careful! - try - TcExprNoRecover cenv ty env tpenv expr - with e -> - let m = expr.Range - // Error recovery - return some rubbish expression, but replace/annotate - // the type of the current expression with a type variable that indicates an error - errorRecovery e m - solveTypAsError cenv env.DisplayEnv m ty - mkThrow m ty (mkOne cenv.g m), tpenv - -and TcExprNoRecover cenv ty (env: TcEnv) tpenv (expr: SynExpr) = - - // Count our way through the expression shape that makes up an object constructor - // See notes at definition of "ctor" re. object model constructors. - let env = - if GetCtorShapeCounter env > 0 then AdjustCtorShapeCounter (fun x -> x - 1) env - else env - - TcExprThen cenv ty env tpenv expr [] - - -// This recursive entry is only used from one callsite (DiscardAfterMissingQualificationAfterDot) -// and has been added relatively late in F# 4.0 to preserve the structure of previous code. It pushes a 'delayed' parameter -// through TcExprOfUnknownType, TcExpr and TcExprNoRecover -and TcExprOfUnknownTypeThen cenv env tpenv expr delayed = - let exprty = NewInferenceType () - let expr', tpenv = - try - TcExprThen cenv exprty env tpenv expr delayed - with e -> - let m = expr.Range - errorRecovery e m - solveTypAsError cenv env.DisplayEnv m exprty - mkThrow m exprty (mkOne cenv.g m), tpenv - expr', exprty, tpenv - -/// This is used to typecheck legitimate 'main body of constructor' expressions -and TcExprThatIsCtorBody safeInitInfo cenv overallTy env tpenv expr = - let env = {env with eCtorInfo = Some (InitialExplicitCtorInfo safeInitInfo) } - let expr, tpenv = TcExpr cenv overallTy env tpenv expr - let expr = CheckAndRewriteObjectCtor cenv.g env expr - expr, tpenv - -/// This is used to typecheck all ordinary expressions including constituent -/// parts of ctor. -and TcExprThatCanBeCtorBody cenv overallTy env tpenv expr = - let env = if AreWithinCtorShape env then AdjustCtorShapeCounter (fun x -> x + 1) env else env - TcExpr cenv overallTy env tpenv expr - -/// This is used to typecheck legitimate 'non-main body of object constructor' expressions -and TcExprThatCantBeCtorBody cenv overallTy env tpenv expr = - let env = if AreWithinCtorShape env then ExitCtorShapeRegion env else env - TcExpr cenv overallTy env tpenv expr - -/// This is used to typecheck legitimate 'non-main body of object constructor' expressions -and TcStmtThatCantBeCtorBody cenv env tpenv expr = - let env = if AreWithinCtorShape env then ExitCtorShapeRegion env else env - TcStmt cenv env tpenv expr - -and TcStmt cenv env tpenv synExpr = - let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr - let m = synExpr.Range - let wasUnit = UnifyUnitType cenv env m ty expr - if wasUnit then - expr, tpenv - else - mkCompGenSequential m expr (mkUnit cenv.g m), tpenv - -and TryTcStmt cenv env tpenv synExpr = - let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr - let m = synExpr.Range - let hasTypeUnit = TryUnifyUnitTypeWithoutWarning cenv env m ty - hasTypeUnit, expr, tpenv - -/// During checking of expressions of the form (x(y)).z(w1, w2) -/// keep a stack of things on the right. This lets us recognize -/// method applications and other item-based syntax. -and TcExprThen cenv overallTy env tpenv synExpr delayed = - match synExpr with - - | LongOrSingleIdent (isOpt, longId, altNameRefCellOpt, mLongId) -> - if isOpt then errorR(Error(FSComp.SR.tcSyntaxErrorUnexpectedQMark(), mLongId)) - // Check to see if pattern translation decided to use an alternative identifier. - match altNameRefCellOpt with - | Some {contents = Decided altId} -> TcExprThen cenv overallTy env tpenv (SynExpr.LongIdent (isOpt, LongIdentWithDots([altId], []), None, mLongId)) delayed - | _ -> TcLongIdentThen cenv overallTy env tpenv longId delayed - - // f x - | SynExpr.App (hpa, _, func, arg, mFuncAndArg) -> - TcExprThen cenv overallTy env tpenv func ((DelayedApp (hpa, arg, mFuncAndArg)) :: delayed) - - // e - | SynExpr.TypeApp (func, _, typeArgs, _, _, mTypeArgs, mFuncAndTypeArgs) -> - TcExprThen cenv overallTy env tpenv func ((DelayedTypeApp (typeArgs, mTypeArgs, mFuncAndTypeArgs)) :: delayed) - - // e1.id1 - // e1.id1.id2 - // etc. - | SynExpr.DotGet (e1, _, LongIdentWithDots(longId, _), _) -> - TcExprThen cenv overallTy env tpenv e1 ((DelayedDotLookup (longId, synExpr.RangeSansAnyExtraDot)) :: delayed) - - // e1.[e2] - // e1.[e21, ..., e2n] - // etc. - | SynExpr.DotIndexedGet (e1, e2, mDot, mWholeExpr) -> - TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv synExpr e1 e2 delayed - - // e1.[e2] <- e3 - // e1.[e21, ..., e2n] <- e3 - // etc. - | SynExpr.DotIndexedSet (e1, e2, _, _, mDot, mWholeExpr) -> - TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv synExpr e1 e2 delayed - - | _ -> - match delayed with - | [] -> TcExprUndelayed cenv overallTy env tpenv synExpr - | _ -> - let expr, exprty, tpenv = TcExprUndelayedNoType cenv env tpenv synExpr - PropagateThenTcDelayed cenv overallTy env tpenv synExpr.Range (MakeApplicableExprNoFlex cenv expr) exprty ExprAtomicFlag.NonAtomic delayed - -and TcExprs cenv env m tpenv flexes argTys args = - if List.length args <> List.length argTys then error(Error(FSComp.SR.tcExpressionCountMisMatch((List.length argTys), (List.length args)), m)) - (tpenv, List.zip3 flexes argTys args) ||> List.mapFold (fun tpenv (flex, ty, e) -> - TcExprFlex cenv flex false ty env tpenv e) - -and CheckSuperInit cenv objTy m = - // Check the type is not abstract - match tryDestAppTy cenv.g objTy with - | ValueSome tcref when isAbstractTycon tcref.Deref -> - errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(), m)) - | _ -> () - -//------------------------------------------------------------------------- -// TcExprUndelayed -//------------------------------------------------------------------------- - -and TcExprUndelayedNoType cenv env tpenv synExpr: Expr * TType * _ = - let overallTy = NewInferenceType () - let expr, tpenv = TcExprUndelayed cenv overallTy env tpenv synExpr - expr, overallTy, tpenv - -and TcExprUndelayed cenv overallTy env tpenv (synExpr: SynExpr) = - - // LanguageFeatures.ImplicitYield do not require this validation - let implicitYieldEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield - let validateObjectSequenceOrRecordExpression = not implicitYieldEnabled - let validateExpressionWithIfRequiresParenthesis = not implicitYieldEnabled - let acceptDeprecatedIfThenExpression = not implicitYieldEnabled - - match synExpr with - | SynExpr.Paren (expr2, _, _, mWholeExprIncludingParentheses) -> - // We invoke CallExprHasTypeSink for every construct which is atomic in the syntax, i.e. where a '.' immediately following the - // construct is a dot-lookup for the result of the construct. - CallExprHasTypeSink cenv.tcSink (mWholeExprIncludingParentheses, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - let env = ShrinkContext env mWholeExprIncludingParentheses expr2.Range - TcExpr cenv overallTy env tpenv expr2 - - | SynExpr.DotIndexedGet _ | SynExpr.DotIndexedSet _ - | SynExpr.TypeApp _ | SynExpr.Ident _ | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) - - | SynExpr.Const (SynConst.String (s, m), _) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcConstStringExpr cenv overallTy env m tpenv s - - | SynExpr.Const (synConst, m) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcConstExpr cenv overallTy env m tpenv synConst - - | SynExpr.Lambda _ -> - TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr - - | SynExpr.Match (spMatch, synInputExpr, synClauses, _m) -> - - let inputExpr, inputTy, tpenv = TcExprOfUnknownType cenv env tpenv synInputExpr - let mInputExpr = inputExpr.Range - let matchVal, matchExpr, tpenv = TcAndPatternCompileMatchClauses mInputExpr mInputExpr ThrowIncompleteMatchException cenv (Some inputExpr) inputTy overallTy env tpenv synClauses - let overallExpr = mkLet spMatch mInputExpr matchVal inputExpr matchExpr - overallExpr, tpenv - - // (function[spMatch] pat1 -> expr1 ... | patN -> exprN) - // - // --> - // (fun anonArg -> let[spMatch] anonVal = anonArg in pat1 -> expr1 ... | patN -> exprN) - // - // Note the presence of the "let" is visible in quotations regardless of the presence of sequence points, so - // <@ function x -> (x: int) @> - // is - // Lambda (_arg2, Let (x, _arg2, x)) - - | SynExpr.MatchLambda (isExnMatch, mArg, clauses, spMatch, m) -> - - let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy - let idv1, idve1 = mkCompGenLocal mArg (cenv.synArgNameGenerator.New()) domainTy - let envinner = ExitFamilyRegion env - let idv2, matchExpr, tpenv = TcAndPatternCompileMatchClauses m mArg (if isExnMatch then Throw else ThrowIncompleteMatchException) cenv None domainTy resultTy envinner tpenv clauses - let overallExpr = mkMultiLambda m [idv1] ((mkLet spMatch m idv2 idve1 matchExpr), resultTy) - overallExpr, tpenv - - | SynExpr.Assert (x, m) -> - TcAssertExpr cenv overallTy env m tpenv x - - | SynExpr.Fixed (_, m) -> - error(Error(FSComp.SR.tcFixedNotAllowed(), m)) - - // e: ty - | SynExpr.Typed (synBodyExpr, synType, m) -> - let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType - UnifyTypes cenv env m overallTy tgtTy - let expr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr - expr, tpenv - - // e :? ty - | SynExpr.TypeTest (synInnerExpr, tgtTy, m) -> - let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr - UnifyTypes cenv env m overallTy cenv.g.bool_ty - let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy - TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy - let expr = mkCallTypeTest cenv.g m tgtTy innerExpr - expr, tpenv - - // SynExpr.AddressOf is noted in the syntax ast in order to recognize it as concrete type information - // during type checking, in particular prior to resolving overloads. This helps distinguish - // its use at method calls from the use of the conflicting 'ref' mechanism for passing byref parameters - | SynExpr.AddressOf (byref, synInnerExpr, opm, m) -> - TcExpr cenv overallTy env tpenv (mkSynPrefixPrim opm m (if byref then "~&" else "~&&") synInnerExpr) - - | SynExpr.Upcast (synInnerExpr, _, m) | SynExpr.InferredUpcast (synInnerExpr, m) -> - let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr - let tgtTy, tpenv = - match synExpr with - | SynExpr.Upcast (_, tgtTy, m) -> - let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy - UnifyTypes cenv env m tgtTy overallTy - tgtTy, tpenv - | SynExpr.InferredUpcast _ -> - overallTy, tpenv - | _ -> failwith "upcast" - TcStaticUpcast cenv env.DisplayEnv m tgtTy srcTy - let expr = mkCoerceExpr(innerExpr, tgtTy, m, srcTy) - expr, tpenv - - | SynExpr.Downcast (synInnerExpr, _, m) | SynExpr.InferredDowncast (synInnerExpr, m) -> - let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr - let tgtTy, tpenv, isOperator = - match synExpr with - | SynExpr.Downcast (_, tgtTy, m) -> - let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy - UnifyTypes cenv env m tgtTy overallTy - tgtTy, tpenv, true - | SynExpr.InferredDowncast _ -> overallTy, tpenv, false - | _ -> failwith "downcast" - TcRuntimeTypeTest (*isCast*)true isOperator cenv env.DisplayEnv m tgtTy srcTy - - // TcRuntimeTypeTest ensures tgtTy is a nominal type. Hence we can insert a check here - // based on the nullness semantics of the nominal type. - let expr = mkCallUnbox cenv.g m tgtTy innerExpr - expr, tpenv - - | SynExpr.Null m -> - AddCxTypeMustSupportNull env.DisplayEnv cenv.css m NoTrace overallTy - mkNull m overallTy, tpenv - - | SynExpr.Lazy (synInnerExpr, m) -> - let innerTy = NewInferenceType () - UnifyTypes cenv env m overallTy (mkLazyTy cenv.g innerTy) - let innerExpr, tpenv = TcExpr cenv innerTy env tpenv synInnerExpr - let expr = mkLazyDelayed cenv.g m innerTy (mkUnitDelayLambda cenv.g m innerExpr) - expr, tpenv - - | SynExpr.Tuple (isExplicitStruct, args, _, m) -> - let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m overallTy isExplicitStruct args - // No subsumption at tuple construction - let flexes = argTys |> List.map (fun _ -> false) - let args', tpenv = TcExprs cenv env m tpenv flexes argTys args - let expr = mkAnyTupled cenv.g m tupInfo args' argTys - expr, tpenv - - | SynExpr.AnonRecd (isStruct, optOrigExpr, unsortedFieldExprs, mWholeExpr) -> - TcAnonRecdExpr cenv overallTy env tpenv (isStruct, optOrigExpr, unsortedFieldExprs, mWholeExpr) - - | SynExpr.ArrayOrList (isArray, args, m) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - - let argty = NewInferenceType () - UnifyTypes cenv env m overallTy (if isArray then mkArrayType cenv.g argty else Tastops.mkListTy cenv.g argty) - - // Always allow subsumption if a nominal type is known prior to type checking any arguments - let flex = not (isTyparTy cenv.g argty) - let mutable first = true - let getInitEnv m = - if first then - first <- false - env - else - { env with eContextInfo = ContextInfo.CollectionElement (isArray, m) } - - let args', tpenv = List.mapFold (fun tpenv (x: SynExpr) -> TcExprFlex cenv flex false argty (getInitEnv x.Range) tpenv x) tpenv args - - let expr = - if isArray then Expr.Op (TOp.Array, [argty], args', m) - else List.foldBack (mkCons cenv.g argty) args' (mkNil cenv.g m argty) - expr, tpenv - - | SynExpr.New (superInit, synObjTy, arg, mNewExpr) -> - let objTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.Use env tpenv synObjTy - UnifyTypes cenv env mNewExpr overallTy objTy - TcNewExpr cenv env tpenv objTy (Some synObjTy.Range) superInit arg mNewExpr - - | SynExpr.ObjExpr (objTy, argopt, binds, extraImpls, mNewExpr, m) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcObjectExpr cenv overallTy env tpenv (objTy, argopt, binds, extraImpls, mNewExpr, m) - - | SynExpr.Record (inherits, optOrigExpr, flds, mWholeExpr) -> - CallExprHasTypeSink cenv.tcSink (mWholeExpr, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) - - | SynExpr.While (spWhile, synGuardExpr, synBodyExpr, m) -> - UnifyTypes cenv env m overallTy cenv.g.unit_ty - let guardExpr, tpenv = TcExpr cenv cenv.g.bool_ty env tpenv synGuardExpr - let bodyExpr, tpenv = TcStmt cenv env tpenv synBodyExpr - mkWhile cenv.g (spWhile, NoSpecialWhileLoopMarker, guardExpr, bodyExpr, m), tpenv - - | SynExpr.For (spBind, id, start, dir, finish, body, m) -> - UnifyTypes cenv env m overallTy cenv.g.unit_ty - let startExpr, tpenv = TcExpr cenv cenv.g.int_ty env tpenv start - let finishExpr, tpenv = TcExpr cenv cenv.g.int_ty env tpenv finish - let idv, _ = mkLocal id.idRange id.idText cenv.g.int_ty - let envinner = AddLocalVal cenv.tcSink m idv env - - // notify name resolution sink about loop variable - let item = Item.Value(mkLocalValRef idv) - CallNameResolutionSink cenv.tcSink (idv.Range, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights) - - let bodyExpr, tpenv = TcStmt cenv envinner tpenv body - mkFastForLoop cenv.g (spBind, m, idv, startExpr, dir, finishExpr, bodyExpr), tpenv - - | SynExpr.ForEach (spForLoop, SeqExprOnly seqExprOnly, isFromSource, pat, enumSynExpr, bodySynExpr, m) -> - assert isFromSource - if seqExprOnly then warning (Error(FSComp.SR.tcExpressionRequiresSequence(), m)) - TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, m, spForLoop) - - | SynExpr.CompExpr (isArrayOrList, isNotNakedRefCell, comp, m) -> - let env = ExitFamilyRegion env - if not isArrayOrList then - match comp with - | SynExpr.New _ -> - errorR(Error(FSComp.SR.tcInvalidObjectExpressionSyntaxForm(), m)) - | SimpleSemicolonSequence cenv false _ when validateObjectSequenceOrRecordExpression -> - errorR(Error(FSComp.SR.tcInvalidObjectSequenceOrRecordExpression(), m)) - | _ -> - () - if not !isNotNakedRefCell && not cenv.g.compilingFslib then - error(Error(FSComp.SR.tcInvalidSequenceExpressionSyntaxForm(), m)) - - TcSequenceExpression cenv env tpenv comp overallTy m - - | SynExpr.ArrayOrListOfSeqExpr (isArray, comp, m) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - match comp with - | SynExpr.CompExpr (_, _, (SimpleSemicolonSequence cenv acceptDeprecatedIfThenExpression elems as body), _) -> - match body with - | SimpleSemicolonSequence cenv false _ -> () - | _ when validateExpressionWithIfRequiresParenthesis -> errorR(Deprecated(FSComp.SR.tcExpressionWithIfRequiresParenthesis(), m)) - | _ -> () - - let replacementExpr = - if isArray then - // This are to improve parsing/processing speed for parser tables by converting to an array blob ASAP - let nelems = elems.Length - if nelems > 0 && List.forall (function SynExpr.Const (SynConst.UInt16 _, _) -> true | _ -> false) elems - then SynExpr.Const (SynConst.UInt16s (Array.ofList (List.map (function SynExpr.Const (SynConst.UInt16 x, _) -> x | _ -> failwith "unreachable") elems)), m) - elif nelems > 0 && List.forall (function SynExpr.Const (SynConst.Byte _, _) -> true | _ -> false) elems - then SynExpr.Const (SynConst.Bytes (Array.ofList (List.map (function SynExpr.Const (SynConst.Byte x, _) -> x | _ -> failwith "unreachable") elems), m), m) - else SynExpr.ArrayOrList (isArray, elems, m) - else - if elems.Length > 500 then - error(Error(FSComp.SR.tcListLiteralMaxSize(), m)) - SynExpr.ArrayOrList (isArray, elems, m) - - TcExprUndelayed cenv overallTy env tpenv replacementExpr - | _ -> - - let genCollElemTy = NewInferenceType () - - let genCollTy = (if isArray then mkArrayType else mkListTy) cenv.g genCollElemTy - - UnifyTypes cenv env m overallTy genCollTy - - let exprty = mkSeqTy cenv.g genCollElemTy - - // Check the comprehension - let expr, tpenv = TcExpr cenv exprty env tpenv comp - - let expr = mkCoerceIfNeeded cenv.g exprty (tyOfExpr cenv.g expr) expr - - let expr = - if cenv.g.compilingFslib then - expr - else - // We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the - // comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined. - mkCallSeq cenv.g m genCollElemTy expr - - let expr = mkCoerceExpr(expr, exprty, expr.Range, overallTy) - - let expr = - if isArray then - mkCallSeqToArray cenv.g m genCollElemTy expr - else - mkCallSeqToList cenv.g m genCollElemTy expr - - expr, tpenv - - | SynExpr.LetOrUse _ -> - TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) - - | SynExpr.TryWith (synBodyExpr, _mTryToWith, synWithClauses, mWithToLast, mTryToLast, spTry, spWith) -> - let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr - // Compile the pattern twice, once as a List.filter with all succeeding targets returning "1", and once as a proper catch block. - let filterClauses = synWithClauses |> List.map (function (Clause(pat, optWhenExpr, _, m, _)) -> Clause(pat, optWhenExpr, (SynExpr.Const (SynConst.Int32 1, m)), m, SuppressSequencePointAtTarget)) - let checkedFilterClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty cenv.g.int_ty env tpenv filterClauses - let checkedHandlerClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty overallTy env tpenv synWithClauses - let v1, filterExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true FailFilter None cenv.g.exn_ty cenv.g.int_ty checkedFilterClauses - let v2, handlerExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true Rethrow None cenv.g.exn_ty overallTy checkedHandlerClauses - mkTryWith cenv.g (bodyExpr, v1, filterExpr, v2, handlerExpr, mTryToLast, overallTy, spTry, spWith), tpenv - - | SynExpr.TryFinally (synBodyExpr, synFinallyExpr, mTryToLast, spTry, spFinally) -> - let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr - let finallyExpr, tpenv = TcStmt cenv env tpenv synFinallyExpr - mkTryFinally cenv.g (bodyExpr, finallyExpr, mTryToLast, overallTy, spTry, spFinally), tpenv - - | SynExpr.JoinIn (e1, mInToken, e2, mAll) -> - errorR(Error(FSComp.SR.parsUnfinishedExpression("in"), mInToken)) - let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv e1) - let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv e2) - mkDefault(mAll, overallTy), tpenv - - | SynExpr.ArbitraryAfterError (_debugStr, m) -> - //solveTypAsError cenv env.DisplayEnv m overallTy - mkDefault(m, overallTy), tpenv - - // expr. (already reported as an error) - | SynExpr.DiscardAfterMissingQualificationAfterDot (e1, m) -> - let _, _, tpenv = suppressErrorReporting (fun () -> TcExprOfUnknownTypeThen cenv env tpenv e1 [DelayedDot]) - mkDefault(m, overallTy), tpenv - - | SynExpr.FromParseError (e1, m) -> - //solveTypAsError cenv env.DisplayEnv m overallTy - let _, tpenv = suppressErrorReporting (fun () -> TcExpr cenv overallTy env tpenv e1) - mkDefault(m, overallTy), tpenv - - | SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m) -> - if dir then - TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) - else - // Constructors using "new (...) = then " - let expr1, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synExpr1 - if (GetCtorShapeCounter env) <> 1 then - errorR(Error(FSComp.SR.tcExpressionFormRequiresObjectConstructor(), m)) - let expr2, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv synExpr2 - Expr.Sequential (expr1, expr2, ThenDoSeq, sp, m), tpenv - - // Used to implement the type-directed 'implicit yield' rule for computation expressions - | SynExpr.SequentialOrImplicitYield (sp, synExpr1, synExpr2, otherExpr, m) -> - let isStmt, expr1, tpenv = TryTcStmt cenv env tpenv synExpr1 - if isStmt then - let env = ShrinkContext env m synExpr2.Range - let expr2, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synExpr2 - Expr.Sequential(expr1, expr2, NormalSeq, sp, m), tpenv - else - // The first expression wasn't unit-typed, so proceed to the alternative interpretation - // Note a copy of the first expression is embedded in 'otherExpr' and thus - // this will type-check the first expression over again. - TcExpr cenv overallTy env tpenv otherExpr - - | SynExpr.Do (synInnerExpr, m) -> - UnifyTypes cenv env m overallTy cenv.g.unit_ty - TcStmtThatCantBeCtorBody cenv env tpenv synInnerExpr - - | SynExpr.IfThenElse _ -> - TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) - - // This is for internal use in the libraries only - | SynExpr.LibraryOnlyStaticOptimization (constraints, e2, e3, m) -> - let constraints', tpenv = List.mapFold (TcStaticOptimizationConstraint cenv env) tpenv constraints - // Do not force the types of the two expressions to be equal - // This means uses of this construct have to be very carefully written - let e2', _, tpenv = TcExprOfUnknownType cenv env tpenv e2 - let e3', tpenv = TcExpr cenv overallTy env tpenv e3 - Expr.StaticOptimization (constraints', e2', e3', m), tpenv - - /// e1.longId <- e2 - | SynExpr.DotSet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, mStmt) -> - if lidwd.ThereIsAnExtraDotAtTheEnd then - // just drop rhs on the floor - let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) - TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup)] - else - let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) - TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup); MakeDelayedSet(e2, mStmt)] - - /// e1 <- e2 - | SynExpr.Set (e1, e2, mStmt) -> - TcExprThen cenv overallTy env tpenv e1 [MakeDelayedSet(e2, mStmt)] - - /// e1.longId(e2) <- e3, very rarely used named property setters - | SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) -> - if lidwd.ThereIsAnExtraDotAtTheEnd then - // just drop rhs on the floor - let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) - TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup)] - else - let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) - TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup); DelayedApp(ExprAtomicFlag.Atomic, e2, mStmt); MakeDelayedSet(e3, mStmt)] - - | SynExpr.LongIdentSet (lidwd, e2, m) -> - if lidwd.ThereIsAnExtraDotAtTheEnd then - // just drop rhs on the floor - TcLongIdentThen cenv overallTy env tpenv lidwd [ ] - else - TcLongIdentThen cenv overallTy env tpenv lidwd [ MakeDelayedSet(e2, m) ] - - // Type.Items(e1) <- e2 - | SynExpr.NamedIndexedPropertySet (lidwd, e1, e2, mStmt) -> - if lidwd.ThereIsAnExtraDotAtTheEnd then - // just drop rhs on the floor - TcLongIdentThen cenv overallTy env tpenv lidwd [ ] - else - TcLongIdentThen cenv overallTy env tpenv lidwd [ DelayedApp(ExprAtomicFlag.Atomic, e1, mStmt); MakeDelayedSet(e2, mStmt) ] - - | SynExpr.TraitCall (tps, memSpfn, arg, m) -> - let synTypes = tps |> List.map (fun tp -> SynType.Var(tp, m)) - let (TTrait(_, logicalCompiledName, _, argTys, returnTy, _) as traitInfo), tpenv = TcPseudoMemberSpec cenv NewTyparsOK env synTypes tpenv memSpfn m - if BakedInTraitConstraintNames.Contains logicalCompiledName then - warning(BakedInMemberConstraintName(logicalCompiledName, m)) - - let returnTy = GetFSharpViewOfReturnType cenv.g returnTy - let args, namedCallerArgs = GetMethodArgs arg - if not (isNil namedCallerArgs) then errorR(Error(FSComp.SR.tcNamedArgumentsCannotBeUsedInMemberTraits(), m)) - // Subsumption at trait calls if arguments have nominal type prior to unification of any arguments or return type - let flexes = argTys |> List.map (isTyparTy cenv.g >> not) - let args', tpenv = TcExprs cenv env m tpenv flexes argTys args - AddCxMethodConstraint env.DisplayEnv cenv.css m NoTrace traitInfo - UnifyTypes cenv env m overallTy returnTy - Expr.Op (TOp.TraitCall traitInfo, [], args', m), tpenv - - | SynExpr.LibraryOnlyUnionCaseFieldGet (e1, c, n, m) -> - let e1', ty1, tpenv = TcExprOfUnknownType cenv env tpenv e1 - let mkf, ty2 = TcUnionCaseOrExnField cenv env ty1 m c n - ((fun (a, b) n -> mkUnionCaseFieldGetUnproven cenv.g (e1', a, b, n, m)), - (fun a n -> mkExnCaseFieldGet(e1', a, n, m))) - UnifyTypes cenv env m overallTy ty2 - mkf n, tpenv - - | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, c, n, e2, m) -> - UnifyTypes cenv env m overallTy cenv.g.unit_ty - let e1', ty1, tpenv = TcExprOfUnknownType cenv env tpenv e1 - let mkf, ty2 = TcUnionCaseOrExnField cenv env ty1 m c n - ((fun (a, b) n e2' -> - if not (isUnionCaseFieldMutable cenv.g a n) then errorR(Error(FSComp.SR.tcFieldIsNotMutable(), m)) - mkUnionCaseFieldSet(e1', a, b, n, e2', m)), - (fun a n e2' -> - if not (isExnFieldMutable a n) then errorR(Error(FSComp.SR.tcFieldIsNotMutable(), m)) - mkExnCaseFieldSet(e1', a, n, e2', m))) - let e2', tpenv = TcExpr cenv ty2 env tpenv e2 - mkf n e2', tpenv - - | SynExpr.LibraryOnlyILAssembly (s, tyargs, args, rtys, m) -> - let argTys = NewInferenceTypes args - let tyargs', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tyargs - // No subsumption at uses of IL assembly code - let flexes = argTys |> List.map (fun _ -> false) - let args', tpenv = TcExprs cenv env m tpenv flexes argTys args - let rtys', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv rtys - let returnTy = - match rtys' with - | [] -> cenv.g.unit_ty - | [ returnTy ] -> returnTy - | _ -> error(InternalError("Only zero or one pushed items are permitted in IL assembly code", m)) - UnifyTypes cenv env m overallTy returnTy - mkAsmExpr (Array.toList s, tyargs', args', rtys', m), tpenv - - | SynExpr.Quote (oper, raw, ast, isFromQueryExpression, m) -> - CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcQuotationExpr cenv overallTy env tpenv (oper, raw, ast, isFromQueryExpression, m) - - | SynExpr.YieldOrReturn ((isTrueYield, _), _, m) - | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, m) when isTrueYield -> - error(Error(FSComp.SR.tcConstructRequiresListArrayOrSequence(), m)) - - | SynExpr.YieldOrReturn ((_, isTrueReturn), _, m) - | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, m) when isTrueReturn -> - error(Error(FSComp.SR.tcConstructRequiresComputationExpressions(), m)) - - | SynExpr.YieldOrReturn (_, _, m) - | SynExpr.YieldOrReturnFrom (_, _, m) - | SynExpr.ImplicitZero m -> - error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m)) - - | SynExpr.DoBang (_, m) - | SynExpr.LetOrUseBang (_, _, _, _, _, _, m) -> - error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) - - | SynExpr.MatchBang (_, _, _, m) -> - error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) - -/// Check lambdas as a group, to catch duplicate names in patterns -and TcIteratedLambdas cenv isFirst (env: TcEnv) overallTy takenNames tpenv e = - match e with - | SynExpr.Lambda (isMember, isSubsequent, spats, bodyExpr, m) when isMember || isFirst || isSubsequent -> - let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy - let vs, (tpenv, names, takenNames) = TcSimplePats cenv isMember CheckCxs domainTy env (tpenv, Map.empty, takenNames) spats - let envinner, _, vspecMap = MakeAndPublishSimpleVals cenv env m names true - let byrefs = vspecMap |> Map.map (fun _ v -> isByrefTy cenv.g v.Type, v) - let envinner = if isMember then envinner else ExitFamilyRegion envinner - let bodyExpr, tpenv = TcIteratedLambdas cenv false envinner resultTy takenNames tpenv bodyExpr - // See bug 5758: Non-monotonicity in inference: need to ensure that parameters are never inferred to have byref type, instead it is always declared - byrefs |> Map.iter (fun _ (orig, v) -> - if not orig && isByrefTy cenv.g v.Type then errorR(Error(FSComp.SR.tcParameterInferredByref v.DisplayName, v.Range))) - mkMultiLambda m (List.map (fun nm -> NameMap.find nm vspecMap) vs) (bodyExpr, resultTy), tpenv - | e -> - // Dive into the expression to check for syntax errors and suppress them if they show. - conditionallySuppressErrorReporting (not isFirst && synExprContainsError e) (fun () -> - //TcExprFlex cenv true true overallTy env tpenv e) - TcExpr cenv overallTy env tpenv e) - - -// Check expr.[idx] -// This is a little over complicated for my liking. Basically we want to interpret e1.[idx] as e1.Item(idx). -// However it's not so simple as all that. First "Item" can have a different name according to an attribute in -// .NET metadata. This means we manually typecheck 'e1' and look to see if it has a nominal type. We then -// do the right thing in each case. -and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArgs delayed = - let ad = env.eAccessRights - let e1', e1ty, tpenv = TcExprOfUnknownType cenv env tpenv e1 - - // Find the first type in the effective hierarchy that either has a DefaultMember attribute OR - // has a member called 'Item' - let isIndex = indexArgs |> List.forall( fun x -> match x with SynIndexerArg.One _ -> true | _ -> false) - let propName = - if isIndex then - FoldPrimaryHierarchyOfType (fun ty acc -> - match acc with - | None -> - match tryDestAppTy cenv.g ty with - | ValueSome tcref -> - TryFindTyconRefStringAttribute cenv.g mWholeExpr cenv.g.attrib_DefaultMemberAttribute tcref - | _ -> - let item = Some "Item" - match AllPropInfosOfTypeInScope ResultCollectionSettings.AtMostOneResult cenv.infoReader env.NameEnv item ad IgnoreOverrides mWholeExpr ty with - | [] -> None - | _ -> item - | _ -> acc) - cenv.g - cenv.amap - mWholeExpr - AllowMultiIntfInstantiations.Yes - e1ty - None - else Some "GetSlice" - - let isNominal = isAppTy cenv.g e1ty - - let isArray = isArrayTy cenv.g e1ty - let isString = typeEquiv cenv.g cenv.g.string_ty e1ty - - let idxRange = indexArgs |> List.map (fun e -> e.Range) |> List.reduce unionRanges - - // xs.GetReverseIndex rank offset - 1 - let rewriteReverseExpr (rank: int) (offset: SynExpr) (range: range) = - let rankExpr = SynExpr.Const(SynConst.Int32(rank), range) - let sliceArgs = SynExpr.Paren(SynExpr.Tuple(false, [rankExpr; offset], [], range), range, Some range, range) - let xsId = e1 - - mkSynApp1 - (mkSynDot range range xsId (mkSynId range "GetReverseIndex")) - sliceArgs - range - - let rewriteReverseOption (app: SynExpr) (rank: int) (range: range) = - match app with - | SynExpr.App(atomicFlag, isInfix, funcExpr, e1, outerRange) -> SynExpr.App(atomicFlag, isInfix, funcExpr, rewriteReverseExpr rank e1 range, outerRange) - | _ -> app - - let expandedIndexArgs = - indexArgs - |> List.mapi ( fun pos indexerArg -> - match indexerArg with - | SynIndexerArg.One(expr, fromEnd, range) -> - [ if fromEnd then rewriteReverseExpr pos expr range else expr ] - | SynIndexerArg.Two - ( - a1, - fromEnd1, - a2, - fromEnd2, - range1, - range2) -> - [ - if fromEnd1 then rewriteReverseOption a1 pos range1 else a1 ; - if fromEnd2 then rewriteReverseOption a2 pos range2 else a2 - ] - ) - |> List.collect (id) - - let MakeIndexParam setSliceArrayOption = - match indexArgs with - | [] -> failwith "unexpected empty index list" - | [SynIndexerArg.One _] -> SynExpr.Paren (expandedIndexArgs.Head, range0, None, idxRange) - | _ -> SynExpr.Paren (SynExpr.Tuple (false, expandedIndexArgs @ Option.toList setSliceArrayOption, [], idxRange), range0, None, idxRange) - - let attemptArrayString = - let indexOpPath = ["Microsoft";"FSharp";"Core";"LanguagePrimitives";"IntrinsicFunctions"] - let sliceOpPath = ["Microsoft";"FSharp";"Core";"Operators";"OperatorIntrinsics"] - - let info = - if isArray then - let fixedIndex3d4dEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.FixedIndexSlice3d4d - match wholeExpr with - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _; SynIndexerArg.One _], _, _) -> Some (indexOpPath, "GetArray2D", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _;], _, _) -> Some (indexOpPath, "GetArray3D", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _], _, _) -> Some (indexOpPath, "GetArray4D", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _], _, _) -> Some (indexOpPath, "GetArray", expandedIndexArgs) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _; SynIndexerArg.One _], e3, _, _, _) -> Some (indexOpPath, "SetArray2D", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _;], e3, _, _, _) -> Some (indexOpPath, "SetArray3D", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _; SynIndexerArg.One _], e3, _, _, _) -> Some (indexOpPath, "SetArray4D", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _], e3, _, _, _) -> Some (indexOpPath, "SetArray", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice2DFixed1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice2DFixed2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice2D", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice3D", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4D", expandedIndexArgs) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice2D", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice2DFixed1", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice2DFixed2", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3D", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4D", (expandedIndexArgs @ [e3])) - | _ when fixedIndex3d4dEnabled -> - match wholeExpr with - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedSingle1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedSingle2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedSingle3", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedDouble1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedDouble2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice3DFixedDouble3", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedSingle1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedSingle2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedSingle3", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedSingle4", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble3", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble4", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble5", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedDouble6", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedTriple1", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedTriple2", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedTriple3", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetArraySlice4DFixedTriple4", expandedIndexArgs) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle1", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle2", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedSingle3", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble1", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble2", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice3DFixedDouble3", (expandedIndexArgs @ [e3])) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle1", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle2", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle3", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedSingle4", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble1", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble2", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble3", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble4", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble5", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedDouble6", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple1", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple2", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _;SynIndexerArg.One _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple3", expandedIndexArgs @ [e3]) - | SynExpr.DotIndexedSet (_, [SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.One _;SynIndexerArg.Two _], e3, _, _, _) -> Some (sliceOpPath, "SetArraySlice4DFixedTriple4", expandedIndexArgs @ [e3]) - | _ -> None - | _ -> None - - elif isString then - match wholeExpr with - | SynExpr.DotIndexedGet (_, [SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetStringSlice", expandedIndexArgs) - | SynExpr.DotIndexedGet (_, [SynIndexerArg.One _], _, _) -> Some (indexOpPath, "GetString", expandedIndexArgs) - | _ -> None - - else None - - match info with - | None -> None - | Some (path, functionName, indexArgs) -> - let operPath = mkSynLidGet mDot path (CompileOpName functionName) - let f, fty, tpenv = TcExprOfUnknownType cenv env tpenv operPath - let domainTy, resultTy = UnifyFunctionType (Some mWholeExpr) cenv env.DisplayEnv mWholeExpr fty - UnifyTypes cenv env mWholeExpr domainTy e1ty - let f', resultTy = buildApp cenv (MakeApplicableExprNoFlex cenv f) resultTy e1' mWholeExpr - let delayed = List.foldBack (fun idx acc -> DelayedApp(ExprAtomicFlag.Atomic, idx, mWholeExpr) :: acc) indexArgs delayed // atomic, otherwise no ar.[1] <- xyz - Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed ) - - match attemptArrayString with - | Some res -> res - | None -> - if isNominal || Option.isSome propName then - let nm = - match propName with - | None -> "Item" - | Some nm -> nm - let delayed = - match wholeExpr with - // e1.[e2] - | SynExpr.DotIndexedGet _ -> - DelayedDotLookup([ident(nm, mWholeExpr)], mWholeExpr) :: DelayedApp(ExprAtomicFlag.Atomic, MakeIndexParam None, mWholeExpr) :: delayed - // e1.[e2] <- e3 - | SynExpr.DotIndexedSet (_, _, e3, mOfLeftOfSet, _, _) -> - match isIndex with - | true -> DelayedDotLookup([ident(nm, mOfLeftOfSet)], mOfLeftOfSet) :: DelayedApp(ExprAtomicFlag.Atomic, MakeIndexParam None, mOfLeftOfSet) :: MakeDelayedSet(e3, mWholeExpr) :: delayed - | false -> DelayedDotLookup([ident("SetSlice", mOfLeftOfSet)], mOfLeftOfSet) :: DelayedApp(ExprAtomicFlag.Atomic, MakeIndexParam (Some e3), mWholeExpr) :: delayed - - | _ -> error(InternalError("unreachable", mWholeExpr)) - PropagateThenTcDelayed cenv overallTy env tpenv mDot (MakeApplicableExprNoFlex cenv e1') e1ty ExprAtomicFlag.Atomic delayed - - else - // deprecated constrained lookup - error(Error(FSComp.SR.tcObjectOfIndeterminateTypeUsedRequireTypeConstraint(), mWholeExpr)) - - -/// Check a 'new Type(args)' expression, also an 'inheritedTys declaration in an implicit or explicit class -/// For 'new Type(args)', mWholeExprOrObjTy is the whole expression -/// For 'inherit Type(args)', mWholeExprOrObjTy is the whole expression -/// For an implicit inherit from System.Object or a default constructor, mWholeExprOrObjTy is the type name of the type being defined -and TcNewExpr cenv env tpenv objTy mObjTyOpt superInit arg mWholeExprOrObjTy = - let ad = env.eAccessRights - // Handle the case 'new 'a()' - if (isTyparTy cenv.g objTy) then - if superInit then error(Error(FSComp.SR.tcCannotInheritFromVariableType(), mWholeExprOrObjTy)) - AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css mWholeExprOrObjTy NoTrace objTy - - match arg with - | SynExpr.Const (SynConst.Unit, _) -> () - | _ -> errorR(Error(FSComp.SR.tcObjectConstructorsOnTypeParametersCannotTakeArguments(), mWholeExprOrObjTy)) - - mkCallCreateInstance cenv.g mWholeExprOrObjTy objTy, tpenv - else - if not (isAppTy cenv.g objTy) && not (isAnyTupleTy cenv.g objTy) then error(Error(FSComp.SR.tcNamedTypeRequired(if superInit then "inherit" else "new"), mWholeExprOrObjTy)) - let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mWholeExprOrObjTy ad objTy) - - TcCtorCall false cenv env tpenv objTy objTy mObjTyOpt item superInit [arg] mWholeExprOrObjTy [] None - -/// Check an 'inheritedTys declaration in an implicit or explicit class -and TcCtorCall isNaked cenv env tpenv overallTy objTy mObjTyOpt item superInit args mWholeCall delayed afterTcOverloadResolutionOpt = - let ad = env.eAccessRights - let isSuperInit = (if superInit then CtorValUsedAsSuperInit else NormalValUse) - let mItem = match mObjTyOpt with Some m -> m | None -> mWholeCall - - if isInterfaceTy cenv.g objTy then - error(Error((if superInit then FSComp.SR.tcInheritCannotBeUsedOnInterfaceType() else FSComp.SR.tcNewCannotBeUsedOnInterfaceType()), mWholeCall)) - - match item, args with - | Item.CtorGroup(methodName, minfos), _ -> - let meths = List.map (fun minfo -> minfo, None) minfos - if isNaked && TypeFeasiblySubsumesType 0 cenv.g cenv.amap mWholeCall cenv.g.system_IDisposable_ty NoCoerce objTy then - warning(Error(FSComp.SR.tcIDisposableTypeShouldUseNew(), mWholeCall)) - - // Check the type is not abstract - // skip this check if this ctor call is either 'inherit(...)' or call is located within constructor shape - if not (superInit || AreWithinCtorShape env) - then CheckSuperInit cenv objTy mWholeCall - - let afterResolution = - match mObjTyOpt, afterTcOverloadResolutionOpt with - | _, Some action -> action - | Some mObjTy, None -> ForNewConstructors cenv.tcSink env mObjTy methodName minfos - | None, _ -> AfterResolution.DoNothing - - TcMethodApplicationThen cenv env overallTy (Some objTy) tpenv None [] mWholeCall mItem methodName ad PossiblyMutates false meths afterResolution isSuperInit args ExprAtomicFlag.NonAtomic delayed - - | Item.DelegateCtor ty, [arg] -> - // Re-record the name resolution since we now know it's a constructor call - match mObjTyOpt with - | Some mObjTy -> CallNameResolutionSink cenv.tcSink (mObjTy, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - | None -> () - TcNewDelegateThen cenv objTy env tpenv mItem mWholeCall ty arg ExprAtomicFlag.NonAtomic delayed - - | _ -> - error(Error(FSComp.SR.tcSyntaxCanOnlyBeUsedToCreateObjectTypes(if superInit then "inherit" else "new"), mWholeCall)) - - -// Check a record construction expression -and TcRecordConstruction cenv overallTy env tpenv optOrigExprInfo objTy fldsList m = - let tcref, tinst = destAppTy cenv.g objTy - let tycon = tcref.Deref - UnifyTypes cenv env m overallTy objTy - - // Types with implicit constructors can't use record or object syntax: all constructions must go through the implicit constructor - if tycon.MembersOfFSharpTyconByName |> NameMultiMap.existsInRange (fun v -> v.IsIncrClassConstructor) then - errorR(Error(FSComp.SR.tcConstructorRequiresCall(tycon.DisplayName), m)) - - let fspecs = tycon.TrueInstanceFieldsAsList - // Freshen types and work out their subtype flexibility - let fldsList = - [ for (fname, fexpr) in fldsList do - let fspec = - try - fspecs |> List.find (fun fspec -> fspec.Name = fname) - with :? KeyNotFoundException -> - error (Error(FSComp.SR.tcUndefinedField(fname, NicePrint.minimalStringOfType env.DisplayEnv objTy), m)) - let fty = actualTyOfRecdFieldForTycon tycon tinst fspec - let flex = not (isTyparTy cenv.g fty) - yield (fname, fexpr, fty, flex) ] - - // Type check and generalize the supplied bindings - let fldsList, tpenv = - let env = { env with eContextInfo = ContextInfo.RecordFields } - (tpenv, fldsList) ||> List.mapFold (fun tpenv (fname, fexpr, fty, flex) -> - let fieldExpr, tpenv = TcExprFlex cenv flex false fty env tpenv fexpr - (fname, fieldExpr), tpenv) - - // Add rebindings for unbound field when an "old value" is available - // Effect order: mutable fields may get modified by other bindings... - let oldFldsList = - match optOrigExprInfo with - | None -> [] - | Some (_, _, oldvaddre) -> - let fieldNameUnbound nom = List.forall (fun (name, _) -> name <> nom) fldsList - let flds = - fspecs |> List.choose (fun rfld -> - if fieldNameUnbound rfld.Name && not rfld.IsZeroInit - then Some(rfld.Name, mkRecdFieldGetViaExprAddr (oldvaddre, tcref.MakeNestedRecdFieldRef rfld, tinst, m)) - else None) - flds - - let fldsList = fldsList @ oldFldsList - - // From now on only interested in fspecs that truly need values. - let fspecs = fspecs |> List.filter (fun f -> not f.IsZeroInit) - - // Check all fields are bound - fspecs |> List.iter (fun fspec -> - if not (fldsList |> List.exists (fun (fname, _) -> fname = fspec.Name)) then - error(Error(FSComp.SR.tcFieldRequiresAssignment(fspec.rfield_id.idText, fullDisplayTextOfTyconRef tcref), m))) - - // Other checks (overlap with above check now clear) - let ns1 = NameSet.ofList (List.map fst fldsList) - let ns2 = NameSet.ofList (List.map (fun x -> x.rfield_id.idText) fspecs) - - if optOrigExprInfo.IsNone && not (Zset.subset ns2 ns1) then - error (MissingFields(Zset.elements (Zset.diff ns2 ns1), m)) - - if not (Zset.subset ns1 ns2) then - error (Error(FSComp.SR.tcExtraneousFieldsGivenValues(), m)) - - // Build record - let rfrefs = List.map (fst >> mkRecdFieldRef tcref) fldsList - - // Check accessibility: this is also done in BuildFieldMap, but also need to check - // for fields in { new R with a=1 and b=2 } constructions and { r with a=1 } copy-and-update expressions - rfrefs |> List.iter (fun rfref -> - CheckRecdFieldAccessible cenv.amap m env.eAccessRights rfref |> ignore - CheckFSharpAttributes cenv.g rfref.PropertyAttribs m |> CommitOperationResult) - - let args = List.map snd fldsList - - let expr = mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m) - - let expr = - match optOrigExprInfo with - | None -> - // '{ recd fields }'. // - expr - - | Some (old, oldvaddr, _) -> - // '{ recd with fields }'. - // Assign the first object to a tmp and then construct - let wrap, oldaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates old None m - wrap (mkCompGenLet m oldvaddr oldaddr expr) - - expr, tpenv - -//------------------------------------------------------------------------- -// TcObjectExpr -//------------------------------------------------------------------------- - -and GetNameAndArityOfObjExprBinding _cenv _env b = - let (NormalizedBinding (_, _, _, _, _, _, _, valSynData, pat, rhsExpr, mBinding, _)) = b - let (SynValData(memberFlagsOpt, valSynInfo, _)) = valSynData - match pat, memberFlagsOpt with - - // This is the normal case for F# 'with member x.M(...) = ...' - | SynPat.InstanceMember(_thisId, memberId, _, None, _), Some memberFlags -> - let logicalMethId = ident (ComputeLogicalName memberId memberFlags, memberId.idRange) - logicalMethId.idText, valSynInfo - - | _ -> - // This is for the deprecated form 'with M(...) = ...' - let rec lookPat pat = - match pat with - | SynPat.Typed(pat, _, _) -> lookPat pat - | SynPat.FromParseError(pat, _) -> lookPat pat - | SynPat.Named (SynPat.Wild _, id, _, None, _) -> - let (NormalizedBindingRhs(pushedPats, _, _)) = rhsExpr - let infosForExplicitArgs = pushedPats |> List.map SynInfo.InferSynArgInfoFromSimplePats - let infosForExplicitArgs = SynInfo.AdjustMemberArgs MemberKind.Member infosForExplicitArgs - let infosForExplicitArgs = SynInfo.AdjustArgsForUnitElimination infosForExplicitArgs - let argInfos = [SynInfo.selfMetadata] @ infosForExplicitArgs - let retInfo = SynInfo.unnamedRetVal //SynInfo.InferSynReturnData pushedRetInfoOpt - let valSynData = SynValInfo(argInfos, retInfo) - (id.idText, valSynData) - | _ -> error(Error(FSComp.SR.tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual(), mBinding)) - - lookPat pat - - -and FreshenObjExprAbstractSlot cenv (env: TcEnv) (implty: TType) virtNameAndArityPairs (bind, bindAttribs, bindName, absSlots:(_ * MethInfo) list) = - let (NormalizedBinding (_, _, _, _, _, _, synTyparDecls, _, _, _, mBinding, _)) = bind - match absSlots with - | [] when not (CompileAsEvent cenv.g bindAttribs) -> - let absSlotsByName = List.filter (fst >> fst >> (=) bindName) virtNameAndArityPairs - let getSignature absSlot = (NicePrint.stringOfMethInfo cenv.amap mBinding env.DisplayEnv absSlot).Replace("abstract ", "") - let getDetails (absSlot: MethInfo) = - if absSlot.GetParamTypes(cenv.amap, mBinding, []) |> List.existsSquared (isAnyTupleTy cenv.g) then - FSComp.SR.tupleRequiredInAbstractMethod() - else "" - - // Compute the argument counts of the member arguments - let _, synValInfo = GetNameAndArityOfObjExprBinding cenv env bind - let arity = - match SynInfo.AritiesOfArgs synValInfo with - | _ :: x :: _ -> x - | _ -> 0 - - match absSlotsByName with - | [] -> - let tcref = tcrefOfAppTy cenv.g implty - let containsNonAbstractMemberWithSameName = - tcref.MembersOfFSharpTyconByName - |> Seq.exists (fun kv -> kv.Value |> List.exists (fun valRef -> valRef.DisplayName = bindName)) - - let suggestVirtualMembers (addToBuffer: string -> unit) = - for ((x,_),_) in virtNameAndArityPairs do - addToBuffer x - - if containsNonAbstractMemberWithSameName then - errorR(ErrorWithSuggestions(FSComp.SR.tcMemberFoundIsNotAbstractOrVirtual(tcref.DisplayName, bindName), mBinding, bindName, suggestVirtualMembers)) - else - errorR(ErrorWithSuggestions(FSComp.SR.tcNoAbstractOrVirtualMemberFound bindName, mBinding, bindName, suggestVirtualMembers)) - | [(_, absSlot: MethInfo)] -> - errorR(Error(FSComp.SR.tcArgumentArityMismatch(bindName, List.sum absSlot.NumArgs, arity, getSignature absSlot, getDetails absSlot), mBinding)) - | (_, absSlot: MethInfo) :: _ -> - errorR(Error(FSComp.SR.tcArgumentArityMismatchOneOverload(bindName, List.sum absSlot.NumArgs, arity, getSignature absSlot, getDetails absSlot), mBinding)) - - None - - | [(_, absSlot)] -> - - let typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot - = FreshenAbstractSlot cenv.g cenv.amap mBinding synTyparDecls absSlot - - // Work out the required type of the member - let bindingTy = implty --> (mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot) - - Some(typarsFromAbsSlotAreRigid, typarsFromAbsSlot, bindingTy) - - | _ -> - None - - -and TcObjectExprBinding cenv (env: TcEnv) implty tpenv (absSlotInfo, bind) = - // 4a1. normalize the binding (note: needlessly repeating what we've done above) - let (NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc, synTyparDecls, valSynData, p, bindingRhs, mBinding, spBind)) = bind - let (SynValData(memberFlagsOpt, _, _)) = valSynData - // 4a2. adjust the binding, especially in the "member" case, a subset of the logic of AnalyzeAndMakeAndPublishRecursiveValue - let bindingRhs, logicalMethId, memberFlags = - let rec lookPat p = - match p, memberFlagsOpt with - | SynPat.FromParseError(pat, _), _ -> lookPat pat - | SynPat.Named (SynPat.Wild _, id, _, _, _), None -> - let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar (ident (CompilerGeneratedName "this", id.idRange))) bindingRhs - let logicalMethId = id - let memberFlags = OverrideMemberFlags MemberKind.Member - bindingRhs, logicalMethId, memberFlags - - | SynPat.InstanceMember(thisId, memberId, _, _, _), Some memberFlags -> - CheckMemberFlags None NewSlotsOK OverridesOK memberFlags mBinding - let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar thisId) bindingRhs - let logicalMethId = ident (ComputeLogicalName memberId memberFlags, memberId.idRange) - bindingRhs, logicalMethId, memberFlags - | _ -> - error(InternalError("unexpected member binding", mBinding)) - lookPat p - let bind = NormalizedBinding (vis, bkind, isInline, isMutable, attrs, doc, synTyparDecls, valSynData, mkSynPatVar vis logicalMethId, bindingRhs, mBinding, spBind) - - // 4b. typecheck the binding - let bindingTy = - match absSlotInfo with - | Some(_, _, memberTyFromAbsSlot) -> - memberTyFromAbsSlot - | _ -> - implty --> NewInferenceType () - - let (CheckedBindingInfo(inlineFlag, bindingAttribs, _, _, ExplicitTyparInfo(_, declaredTypars, _), nameToPrelimValSchemeMap, rhsExpr, _, _, m, _, _, _, _), tpenv) = - let flex, tpenv = TcNonrecBindingTyparDecls cenv env tpenv bind - TcNormalizedBinding ObjectExpressionOverrideBinding cenv env tpenv bindingTy None NoSafeInitInfo ([], flex) bind - - // 4c. generalize the binding - only relevant when implementing a generic virtual method - - match NameMap.range nameToPrelimValSchemeMap with - | [PrelimValScheme1(id, _, _, _, _, _, _, _, _, _, _)] -> - let denv = env.DisplayEnv - - let declaredTypars = - match absSlotInfo with - | Some(typarsFromAbsSlotAreRigid, typarsFromAbsSlot, _) -> - if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars - | _ -> - declaredTypars - // Canonicalize constraints prior to generalization - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, m) declaredTypars - - let freeInEnv = GeneralizationHelpers.ComputeUngeneralizableTypars env - - let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv, denv, m, freeInEnv, false, CanGeneralizeConstrainedTypars, inlineFlag, Some rhsExpr, declaredTypars, [], bindingTy, false) - let declaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g env.DisplayEnv declaredTypars m - - let generalizedTypars = PlaceTyparsInDeclarationOrder declaredTypars generalizedTypars - - (id, memberFlags, (generalizedTypars +-> bindingTy), bindingAttribs, rhsExpr), tpenv - | _ -> - error(Error(FSComp.SR.tcSimpleMethodNameRequired(), m)) - -and ComputeObjectExprOverrides cenv (env: TcEnv) tpenv impls = - - // Compute the method sets each implemented type needs to implement - let slotImplSets = DispatchSlotChecking.GetSlotImplSets cenv.infoReader env.DisplayEnv true (impls |> List.map (fun (m, ty, _) -> ty, m)) - - let allImpls = - (impls, slotImplSets) ||> List.map2 (fun (m, ty, binds) implTySet -> - let binds = binds |> List.map (BindingNormalization.NormalizeBinding ObjExprBinding cenv env) - m, ty, binds, implTySet) - - let overridesAndVirts, tpenv = - (tpenv, allImpls) ||> List.mapFold (fun tpenv (m, implty, binds, SlotImplSet(reqdSlots, dispatchSlotsKeyed, availPriorOverrides, _) ) -> - - // Generate extra bindings fo object expressions with bindings using the CLIEvent attribute - let binds, bindsAttributes = - [ for binding in binds do - let (NormalizedBinding(_, _, _, _, bindingSynAttribs, _, _, valSynData, _, _, _, _)) = binding - let (SynValData(memberFlagsOpt, _, _)) = valSynData - let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt ObjectExpressionOverrideBinding - let bindingAttribs = TcAttributes cenv env attrTgt bindingSynAttribs - yield binding, bindingAttribs - for extraBinding in EventDeclarationNormalization.GenerateExtraBindings cenv (bindingAttribs, binding) do - yield extraBinding, [] ] - |> List.unzip - - // 2. collect all name/arity of all overrides - let dispatchSlots = reqdSlots |> List.map (fun (RequiredSlot(dispatchSlot, _)) -> dispatchSlot) - let virtNameAndArityPairs = dispatchSlots |> List.map (fun virt -> - let vkey = (virt.LogicalName, virt.NumArgs) - //dprintfn "vkey = %A" vkey - (vkey, virt)) - let bindNameAndSynInfoPairs = binds |> List.map (GetNameAndArityOfObjExprBinding cenv env) - let bindNames = bindNameAndSynInfoPairs |> List.map fst - let bindKeys = - bindNameAndSynInfoPairs |> List.map (fun (name, valSynData) -> - // Compute the argument counts of the member arguments - let argCounts = (SynInfo.AritiesOfArgs valSynData).Tail - //dprintfn "name = %A, argCounts = %A" name argCounts - (name, argCounts)) - - // 3. infer must-have types by name/arity - let preAssignedVirtsPerBinding = - bindKeys |> List.map (fun bkey -> List.filter (fst >> (=) bkey) virtNameAndArityPairs) - - let absSlotInfo = - (List.zip4 binds bindsAttributes bindNames preAssignedVirtsPerBinding) - |> List.map (FreshenObjExprAbstractSlot cenv env implty virtNameAndArityPairs) - - // 4. typecheck/typeinfer/generalizer overrides using this information - let overrides, tpenv = (tpenv, List.zip absSlotInfo binds) ||> List.mapFold (TcObjectExprBinding cenv env implty) - - // Convert the syntactic info to actual info - let overrides = - (overrides, bindNameAndSynInfoPairs) ||> List.map2 (fun (id: Ident, memberFlags, ty, bindingAttribs, bindingBody) (_, valSynData) -> - let partialValInfo = TranslateTopValSynInfo id.idRange (TcAttributes cenv env) valSynData - let tps, _ = tryDestForallTy cenv.g ty - let valInfo = TranslatePartialArity tps partialValInfo - DispatchSlotChecking.GetObjectExprOverrideInfo cenv.g cenv.amap (implty, id, memberFlags, ty, valInfo, bindingAttribs, bindingBody)) - - (m, implty, reqdSlots, dispatchSlotsKeyed, availPriorOverrides, overrides), tpenv) - - overridesAndVirts, tpenv - -and CheckSuperType cenv ty m = - if typeEquiv cenv.g ty cenv.g.system_Value_ty || - typeEquiv cenv.g ty cenv.g.system_Enum_ty || - typeEquiv cenv.g ty cenv.g.system_Array_ty || - typeEquiv cenv.g ty cenv.g.system_MulticastDelegate_ty || - typeEquiv cenv.g ty cenv.g.system_Delegate_ty then - error(Error(FSComp.SR.tcPredefinedTypeCannotBeUsedAsSuperType(), m)) - if isErasedType cenv.g ty then - errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) - - -and TcObjectExpr cenv overallTy env tpenv (synObjTy, argopt, binds, extraImpls, mNewExpr, mWholeExpr) = - let mObjTy = synObjTy.Range - - let objTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synObjTy - match tryDestAppTy cenv.g objTy with - | ValueNone -> error(Error(FSComp.SR.tcNewMustBeUsedWithNamedType(), mNewExpr)) - | ValueSome tcref -> - let isRecordTy = isRecdTy cenv.g objTy - if not isRecordTy && not (isInterfaceTy cenv.g objTy) && isSealedTy cenv.g objTy then errorR(Error(FSComp.SR.tcCannotCreateExtensionOfSealedType(), mNewExpr)) - - CheckSuperType cenv objTy synObjTy.Range - - // Add the object type to the ungeneralizable items - let env = {env with eUngeneralizableItems = addFreeItemOfTy objTy env.eUngeneralizableItems } - - // Object expression members can access protected members of the implemented type - let env = EnterFamilyRegion tcref env - let ad = env.eAccessRights - - if // record construction ? - isRecordTy || - // object construction? - (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && argopt.IsNone) then - - if argopt.IsSome then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(), mWholeExpr)) - if not (isNil extraImpls) then error(Error(FSComp.SR.tcNoInterfaceImplementationForConstructionExpression(), mNewExpr)) - if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env <> 1 then - error(Error(FSComp.SR.tcObjectConstructionCanOnlyBeUsedInClassTypes(), mNewExpr)) - let fldsList = - binds |> List.map (fun b -> - match BindingNormalization.NormalizeBinding ObjExprBinding cenv env b with - | NormalizedBinding (_, _, _, _, [], _, _, _, SynPat.Named(SynPat.Wild _, id, _, _, _), NormalizedBindingRhs(_, _, rhsExpr), _, _) -> id.idText, rhsExpr - | _ -> error(Error(FSComp.SR.tcOnlySimpleBindingsCanBeUsedInConstructionExpressions(), b.RangeOfBindingSansRhs))) - - TcRecordConstruction cenv overallTy env tpenv None objTy fldsList mWholeExpr - else - let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy) - - if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env = 1 then - error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr)) - - // Work out the type of any interfaces to implement - let extraImpls, tpenv = - (tpenv, extraImpls) ||> List.mapFold (fun tpenv (InterfaceImpl(synIntfTy, overrides, m)) -> - let intfTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synIntfTy - if not (isInterfaceTy cenv.g intfTy) then - error(Error(FSComp.SR.tcExpectedInterfaceType(), m)) - if isErasedType cenv.g intfTy then - errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) - (m, intfTy, overrides), tpenv) - - let realObjTy = if isObjTy cenv.g objTy && not (isNil extraImpls) then (p23 (List.head extraImpls)) else objTy - UnifyTypes cenv env mWholeExpr overallTy realObjTy - - let ctorCall, baseIdOpt, tpenv = - match item, argopt with - | Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) -> - let meths = minfos |> List.map (fun minfo -> minfo, None) - let afterResolution = ForNewConstructors cenv.tcSink env synObjTy.Range methodName minfos - let ad = env.eAccessRights - - let expr, tpenv = TcMethodApplicationThen cenv env objTy None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic [] - // The 'base' value is always bound - let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id) - expr, baseIdOpt, tpenv - | Item.FakeInterfaceCtor intfTy, None -> - UnifyTypes cenv env mWholeExpr objTy intfTy - let expr = BuildObjCtorCall cenv.g mWholeExpr - expr, None, tpenv - | Item.FakeInterfaceCtor _, Some _ -> - error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr)) - | Item.CtorGroup _, None -> - error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr)) - | _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr)) - - let baseValOpt = MakeAndPublishBaseVal cenv env baseIdOpt objTy - let env = Option.foldBack (AddLocalVal cenv.tcSink mNewExpr) baseValOpt env - - - let impls = (mWholeExpr, objTy, binds) :: extraImpls - - - // 1. collect all the relevant abstract slots for each type we have to implement - - let overridesAndVirts, tpenv = ComputeObjectExprOverrides cenv env tpenv impls - - - overridesAndVirts |> List.iter (fun (m, implty, dispatchSlots, dispatchSlotsKeyed, availPriorOverrides, overrides) -> - let overrideSpecs = overrides |> List.map fst - - DispatchSlotChecking.CheckOverridesAreAllUsedOnce (env.DisplayEnv, cenv.g, cenv.amap, true, implty, dispatchSlotsKeyed, availPriorOverrides, overrideSpecs) - - DispatchSlotChecking.CheckDispatchSlotsAreImplemented (env.DisplayEnv, cenv.g, cenv.amap, m, env.NameEnv, cenv.tcSink, false, implty, dispatchSlots, availPriorOverrides, overrideSpecs) |> ignore) - - // 6c. create the specs of overrides - let allTypeImpls = - overridesAndVirts |> List.map (fun (m, implty, _, dispatchSlotsKeyed, _, overrides) -> - let overrides' = - [ for overrideMeth in overrides do - let (Override(_, _, id, (mtps, _), _, _, isFakeEventProperty, _) as ovinfo), (_, thisVal, methodVars, bindingAttribs, bindingBody) = overrideMeth - if not isFakeEventProperty then - let searchForOverride = - dispatchSlotsKeyed - |> NameMultiMap.find id.idText - |> List.tryPick (fun (RequiredSlot(virt, _)) -> - if DispatchSlotChecking.IsExactMatch cenv.g cenv.amap m virt ovinfo then - Some virt - else - None) - - let overridden = - match searchForOverride with - | Some x -> x - | None -> error(Error(FSComp.SR.tcAtLeastOneOverrideIsInvalid(), synObjTy.Range)) - - yield TObjExprMethod(overridden.GetSlotSig(cenv.amap, m), bindingAttribs, mtps, [thisVal] :: methodVars, bindingBody, id.idRange) ] - (implty, overrides')) - - let (objTy', overrides') = allTypeImpls.Head - let extraImpls = allTypeImpls.Tail - - // 7. Build the implementation - let expr = mkObjExpr(objTy', baseValOpt, ctorCall, overrides', extraImpls, mWholeExpr) - let expr = mkCoerceIfNeeded cenv.g realObjTy objTy' expr - expr, tpenv - - - -//------------------------------------------------------------------------- -// TcConstStringExpr -//------------------------------------------------------------------------- - -/// Check a constant string expression. It might be a 'printf' format string -and TcConstStringExpr cenv overallTy env m tpenv s = - - if (AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy cenv.g.string_ty) then - mkString cenv.g m s, tpenv - else - let aty = NewInferenceType () - let bty = NewInferenceType () - let cty = NewInferenceType () - let dty = NewInferenceType () - let ety = NewInferenceType () - let ty' = mkPrintfFormatTy cenv.g aty bty cty dty ety - if (not (isObjTy cenv.g overallTy) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy ty') then - // Parse the format string to work out the phantom types - let formatStringCheckContext = match cenv.tcSink.CurrentSink with None -> None | Some sink -> sink.FormatStringCheckContext - let normalizedString = (s.Replace("\r\n", "\n").Replace("\r", "\n")) - - let (aty', ety'), specifierLocations = (try CheckFormatStrings.ParseFormatString m cenv.g formatStringCheckContext normalizedString bty cty dty with Failure s -> error (Error(FSComp.SR.tcUnableToParseFormatString s, m))) - - match cenv.tcSink.CurrentSink with - | None -> () - | Some sink -> - for specifierLocation, numArgs in specifierLocations do - sink.NotifyFormatSpecifierLocation(specifierLocation, numArgs) - - UnifyTypes cenv env m aty aty' - UnifyTypes cenv env m ety ety' - mkCallNewFormat cenv.g m aty bty cty dty ety (mkString cenv.g m s), tpenv - else - UnifyTypes cenv env m overallTy cenv.g.string_ty - mkString cenv.g m s, tpenv - -//------------------------------------------------------------------------- -// TcConstExpr -//------------------------------------------------------------------------- - -/// Check a constant expression. -and TcConstExpr cenv overallTy env m tpenv c = - match c with - - // NOTE: these aren't "really" constants - | SynConst.Bytes (bytes, m) -> - UnifyTypes cenv env m overallTy (mkByteArrayTy cenv.g) - Expr.Op (TOp.Bytes bytes, [], [], m), tpenv - - | SynConst.UInt16s arr -> - UnifyTypes cenv env m overallTy (mkArrayType cenv.g cenv.g.uint16_ty); Expr.Op (TOp.UInt16s arr, [], [], m), tpenv - - | SynConst.UserNum (s, suffix) -> - let expr = - let modName = "NumericLiteral" + suffix - let ad = env.eAccessRights - match ResolveLongIndentAsModuleOrNamespaceOrStaticClass cenv.tcSink ResultCollectionSettings.AtMostOneResult cenv.amap m true true OpenQualified env.eNameResEnv ad (ident (modName, m)) [] false with - | Result [] - | Exception _ -> error(Error(FSComp.SR.tcNumericLiteralRequiresModule modName, m)) - | Result ((_, mref, _) :: _) -> - let expr = - try - match int32 s with - | 0 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromZero", SynExpr.Const (SynConst.Unit, m), m) - | 1 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromOne", SynExpr.Const (SynConst.Unit, m), m) - | i32 -> SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromInt32", SynExpr.Const (SynConst.Int32 i32, m), m) - with _ -> - try - let i64 = int64 s - SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromInt64", SynExpr.Const (SynConst.Int64 i64, m), m) - with _ -> - SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromString", SynExpr.Const (SynConst.String (s, m), m), m) - - if suffix <> "I" then - expr - else - match ccuOfTyconRef mref with - | Some ccu when ccuEq ccu cenv.g.fslibCcu -> - SynExpr.Typed (expr, SynType.LongIdent(LongIdentWithDots(pathToSynLid m ["System";"Numerics";"BigInteger"], [])), m) - | _ -> - expr - - TcExpr cenv overallTy env tpenv expr - - | _ -> - let c' = TcConst cenv overallTy m env c - Expr.Const (c', m, overallTy), tpenv - - -//------------------------------------------------------------------------- -// TcAssertExpr -//------------------------------------------------------------------------- - -// Check an 'assert x' expression. -and TcAssertExpr cenv overallTy env (m: range) tpenv x = - let synm = m.MakeSynthetic() // Mark as synthetic so the language service won't pick it up. - let callDiagnosticsExpr = SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet synm ["System";"Diagnostics";"Debug"] "Assert", - // wrap an extra parentheses so 'assert(x=1) isn't considered a named argument to a method call - SynExpr.Paren (x, range0, None, synm), synm) - - TcExpr cenv overallTy env tpenv callDiagnosticsExpr - - -and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) = - - let requiresCtor = (GetCtorShapeCounter env = 1) // Get special expression forms for constructors - let haveCtor = Option.isSome inherits - - let optOrigExpr, tpenv = - match optOrigExpr with - | None -> None, tpenv - | Some (origExpr, _) -> - match inherits with - | Some (_, _, mInherits, _, _) -> error(Error(FSComp.SR.tcInvalidRecordConstruction(), mInherits)) - | None -> - let olde, tpenv = TcExpr cenv overallTy env tpenv origExpr - Some (olde), tpenv - - let hasOrigExpr = optOrigExpr.IsSome - - let fldsList = - let flds = - [ - // if we met at least one field that is not syntactically correct - raise ReportedError to transfer control to the recovery routine - for ((lidwd, isOk), v, _) in flds do - if not isOk then - // raising ReportedError None transfers control to the closest errorRecovery point but do not make any records into log - // we assume that parse errors were already reported - raise (ReportedError None) - - yield (List.frontAndBack lidwd.Lid, v) - ] - - match flds with - | [] -> [] - | _ -> - let tcref, _, fldsList = BuildFieldMap cenv env hasOrigExpr overallTy flds mWholeExpr - let _, _, _, gtyp = infoOfTyconRef mWholeExpr tcref - UnifyTypes cenv env mWholeExpr overallTy gtyp - - [ for n, v in fldsList do - match v with - | Some v -> yield n, v - | None -> () ] - - let optOrigExprInfo = - match optOrigExpr with - | None -> None - | Some(olde) -> - let oldvaddr, oldvaddre = mkCompGenLocal mWholeExpr "inputRecord" (if isStructTy cenv.g overallTy then mkByrefTy cenv.g overallTy else overallTy) - Some(olde, oldvaddr, oldvaddre) - - if hasOrigExpr && not (isRecdTy cenv.g overallTy) then - errorR(Error(FSComp.SR.tcExpressionFormRequiresRecordTypes(), mWholeExpr)) - - if requiresCtor || haveCtor then - if not (isFSharpObjModelTy cenv.g overallTy) then - // Deliberate no-recovery failure here to prevent cascading internal errors - error(Error(FSComp.SR.tcInheritedTypeIsNotObjectModelType(), mWholeExpr)) - if not requiresCtor then - errorR(Error(FSComp.SR.tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes(), mWholeExpr)) - else - if isNil flds then - let errorInfo = if hasOrigExpr then FSComp.SR.tcEmptyCopyAndUpdateRecordInvalid() else FSComp.SR.tcEmptyRecordInvalid() - error(Error(errorInfo, mWholeExpr)) - - if isFSharpObjModelTy cenv.g overallTy then errorR(Error(FSComp.SR.tcTypeIsNotARecordTypeNeedConstructor(), mWholeExpr)) - elif not (isRecdTy cenv.g overallTy) then errorR(Error(FSComp.SR.tcTypeIsNotARecordType(), mWholeExpr)) - - let superTy, tpenv = - match inherits, GetSuperTypeOfType cenv.g cenv.amap mWholeExpr overallTy with - | Some (superTy, arg, m, _, _), Some realSuperTy -> - // Constructor expression, with an explicit 'inheritedTys clause. Check the inherits clause. - let e, tpenv = TcExpr cenv realSuperTy env tpenv (SynExpr.New (true, superTy, arg, m)) - Some e, tpenv - | None, Some realSuperTy when requiresCtor -> - // Constructor expression, No 'inherited' clause, hence look for a default constructor - let e, tpenv = TcNewExpr cenv env tpenv realSuperTy None true (SynExpr.Const (SynConst.Unit, mWholeExpr)) mWholeExpr - Some e, tpenv - | None, _ -> - None, tpenv - | _, None -> - errorR(InternalError("Unexpected failure in getting super type", mWholeExpr)) - None, tpenv - - let expr, tpenv = TcRecordConstruction cenv overallTy env tpenv optOrigExprInfo overallTy fldsList mWholeExpr - - let expr = - match superTy with - | _ when isStructTy cenv.g overallTy -> expr - | Some e -> mkCompGenSequential mWholeExpr e expr - | None -> expr - expr, tpenv - - -// Check '{| .... |}' -and TcAnonRecdExpr cenv overallTy env tpenv (isStruct, optOrigSynExpr, unsortedFieldIdsAndSynExprsGiven, mWholeExpr) = - let unsortedFieldSynExprsGiven = List.map snd unsortedFieldIdsAndSynExprsGiven - - match optOrigSynExpr with - | None -> - let unsortedFieldIds = unsortedFieldIdsAndSynExprsGiven |> List.map fst |> List.toArray - let anonInfo, sortedFieldTys = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedFieldIds - - // Sort into canonical order - let sortedIndexedArgs = - unsortedFieldIdsAndSynExprsGiven - |> List.indexed - |> List.sortBy (fun (i,_) -> unsortedFieldIds.[i].idText) - - // Map from sorted indexes to unsorted indexes - let sigma = List.map fst sortedIndexedArgs |> List.toArray - let sortedFieldExprs = List.map snd sortedIndexedArgs - - sortedFieldExprs |> List.iteri (fun j (x, _) -> - let item = Item.AnonRecdField(anonInfo, sortedFieldTys, j, x.idRange) - CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights)) - - let unsortedFieldTys = - sortedFieldTys - |> List.indexed - |> List.sortBy (fun (sortedIdx, _) -> sigma.[sortedIdx]) - |> List.map snd - - let flexes = unsortedFieldTys |> List.map (fun _ -> true) - - let unsortedCheckedArgs, tpenv = TcExprs cenv env mWholeExpr tpenv flexes unsortedFieldTys unsortedFieldSynExprsGiven - - mkAnonRecd cenv.g mWholeExpr anonInfo unsortedFieldIds unsortedCheckedArgs unsortedFieldTys, tpenv - - | Some (origExpr, _) -> - // The fairly complex case '{| origExpr with X = 1; Y = 2 |}' - // The origExpr may be either a record or anonymous record. - // The origExpr may be either a struct or not. - // All the properties of origExpr are copied across except where they are overridden. - // The result is a field-sorted anonymous record. - // - // Unlike in the case of record type copy-and-update we do _not_ assume that the origExpr has the same type as the overall expression. - // Unlike in the case of record type copy-and-update {| a with X = 1 |} does not force a.X to exist or have had type 'int' - - let origExprTy = NewInferenceType() - let origExprChecked, tpenv = TcExpr cenv origExprTy env tpenv origExpr - let oldv, oldve = mkCompGenLocal mWholeExpr "inputRecord" origExprTy - let mOrigExpr = origExpr.Range - - if not (isAppTy cenv.g origExprTy || isAnonRecdTy cenv.g origExprTy) then - error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) - - let origExprIsStruct = - match tryDestAnonRecdTy cenv.g origExprTy with - | ValueSome (anonInfo, _) -> evalTupInfoIsStruct anonInfo.TupInfo - | ValueNone -> - let tcref, _ = destAppTy cenv.g origExprTy - tcref.IsStructOrEnumTycon - - let wrap, oldveaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g origExprIsStruct false NeverMutates oldve None mOrigExpr - - // Put all the expressions in unsorted order. The new bindings come first. The origin of each is tracked using - /// - Choice1Of2 for a new binding - /// - Choice2Of2 for a binding coming from the original expression - let unsortedIdAndExprsAll = - [| for (id, e) in unsortedFieldIdsAndSynExprsGiven do - yield (id, Choice1Of2 e) - match tryDestAnonRecdTy cenv.g origExprTy with - | ValueSome (anonInfo, tinst) -> - for (i, id) in Array.indexed anonInfo.SortedIds do - yield id, Choice2Of2 (mkAnonRecdFieldGetViaExprAddr (anonInfo, oldveaddr, tinst, i, mOrigExpr)) - | ValueNone -> - if isRecdTy cenv.g origExprTy then - let tcref, tinst = destAppTy cenv.g origExprTy - let fspecs = tcref.Deref.TrueInstanceFieldsAsList - for fspec in fspecs do - yield fspec.Id, Choice2Of2 (mkRecdFieldGetViaExprAddr (oldveaddr, tcref.MakeNestedRecdFieldRef fspec, tinst, mOrigExpr)) - else - error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) |] - |> Array.distinctBy (fst >> textOfId) - - let unsortedFieldIdsAll = Array.map fst unsortedIdAndExprsAll - - let anonInfo, sortedFieldTysAll = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedFieldIdsAll - - let sortedIndexedFieldsAll = unsortedIdAndExprsAll |> Array.indexed |> Array.sortBy (snd >> fst >> textOfId) - - // map from sorted indexes to unsorted indexes - let sigma = Array.map fst sortedIndexedFieldsAll - - let sortedFieldsAll = Array.map snd sortedIndexedFieldsAll - - // Report _all_ identifiers to name resolution. We should likely just report the ones - // that are explicit in source code. - sortedFieldsAll |> Array.iteri (fun j (x, expr) -> - match expr with - | Choice1Of2 _ -> - let item = Item.AnonRecdField(anonInfo, sortedFieldTysAll, j, x.idRange) - CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - | Choice2Of2 _ -> ()) - - let unsortedFieldTysAll = - sortedFieldTysAll - |> List.indexed - |> List.sortBy (fun (sortedIdx, _) -> sigma.[sortedIdx]) - |> List.map snd - - let unsortedFieldTysGiven = - unsortedFieldTysAll - |> List.take unsortedFieldIdsAndSynExprsGiven.Length - - let flexes = unsortedFieldTysGiven |> List.map (fun _ -> true) - - // Check the expressions in unsorted order - let unsortedFieldExprsGiven, tpenv = - TcExprs cenv env mWholeExpr tpenv flexes unsortedFieldTysGiven unsortedFieldSynExprsGiven - - let unsortedFieldExprsGiven = unsortedFieldExprsGiven |> List.toArray - - let unsortedFieldIds = - unsortedIdAndExprsAll - |> Array.map fst - - let unsortedFieldExprs = - unsortedIdAndExprsAll - |> Array.mapi (fun unsortedIdx (_, expr) -> - match expr with - | Choice1Of2 _ -> unsortedFieldExprsGiven.[unsortedIdx] - | Choice2Of2 subExpr -> UnifyTypes cenv env mOrigExpr (tyOfExpr cenv.g subExpr) unsortedFieldTysAll.[unsortedIdx]; subExpr) - |> List.ofArray - - // Permute the expressions to sorted order in the TAST - let expr = mkAnonRecd cenv.g mWholeExpr anonInfo unsortedFieldIds unsortedFieldExprs unsortedFieldTysAll - let expr = wrap expr - - // Bind the original expression - let expr = mkCompGenLet mOrigExpr oldv origExprChecked expr - expr, tpenv - - -and TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, mWholeExpr, spForLoop) = - let tryGetOptimizeSpanMethodsAux g m ty isReadOnlySpan = - match (if isReadOnlySpan then tryDestReadOnlySpanTy g m ty else tryDestSpanTy g m ty) with - | ValueSome(struct(_, destTy)) -> - match TryFindFSharpSignatureInstanceGetterProperty cenv env m "Item" ty [ g.int32_ty; (if isReadOnlySpan then mkInByrefTy g destTy else mkByrefTy g destTy) ], - TryFindFSharpSignatureInstanceGetterProperty cenv env m "Length" ty [ g.int32_ty ] with - | Some(itemPropInfo), Some(lengthPropInfo) -> - ValueSome(struct(itemPropInfo.GetterMethod, lengthPropInfo.GetterMethod, isReadOnlySpan)) - | _ -> - ValueNone - | _ -> - ValueNone - - let tryGetOptimizeSpanMethods g m ty = - let result = tryGetOptimizeSpanMethodsAux g m ty false - if result.IsSome then - result - else - tryGetOptimizeSpanMethodsAux g m ty true - - UnifyTypes cenv env mWholeExpr overallTy cenv.g.unit_ty - - let mPat = pat.Range - //let mBodyExpr = bodySynExpr.Range - let mEnumExpr = enumSynExpr.Range - let mForLoopStart = match spForLoop with SequencePointAtForLoop mStart -> mStart | NoSequencePointAtForLoop -> mEnumExpr - - // Check the expression being enumerated - let enumExpr, enumExprTy, tpenv = TcExprOfUnknownType cenv env tpenv enumSynExpr - - // Depending on its type we compile it in different ways - let enumElemTy, bodyExprFixup, overallExprFixup, iterationTechnique = - match enumExpr with - - // optimize 'for i in n .. m do' - | Expr.App (Expr.Val (vf, _, _), _, [tyarg], [startExpr;finishExpr], _) - when valRefEq cenv.g vf cenv.g.range_op_vref && typeEquiv cenv.g tyarg cenv.g.int_ty -> - (cenv.g.int32_ty, (fun _ x -> x), id, Choice1Of3 (startExpr, finishExpr)) - - // optimize 'for i in arr do' - | _ when isArray1DTy cenv.g enumExprTy -> - let arrVar, arrExpr = mkCompGenLocal mEnumExpr "arr" enumExprTy - let idxVar, idxExpr = mkCompGenLocal mPat "idx" cenv.g.int32_ty - let elemTy = destArrayTy cenv.g enumExprTy - - // Evaluate the array index lookup - let bodyExprFixup elemVar bodyExpr = mkCompGenLet mForLoopStart elemVar (mkLdelem cenv.g mForLoopStart elemTy arrExpr idxExpr) bodyExpr - - // Evaluate the array expression once and put it in arrVar - let overallExprFixup overallExpr = mkCompGenLet mForLoopStart arrVar enumExpr overallExpr - - // Ask for a loop over integers for the given range - (elemTy, bodyExprFixup, overallExprFixup, Choice2Of3 (idxVar, mkZero cenv.g mForLoopStart, mkDecr cenv.g mForLoopStart (mkLdlen cenv.g mForLoopStart arrExpr))) - - | _ -> - // try optimize 'for i in span do' for span or readonlyspan - match tryGetOptimizeSpanMethods cenv.g mWholeExpr enumExprTy with - | ValueSome(struct(getItemMethInfo, getLengthMethInfo, isReadOnlySpan)) -> - let tcVal = LightweightTcValForUsingInBuildMethodCall cenv.g - let spanVar, spanExpr = mkCompGenLocal mEnumExpr "span" enumExprTy - let idxVar, idxExpr = mkCompGenLocal mPat "idx" cenv.g.int32_ty - let struct(_, elemTy) = if isReadOnlySpan then destReadOnlySpanTy cenv.g mWholeExpr enumExprTy else destSpanTy cenv.g mWholeExpr enumExprTy - let elemAddrTy = if isReadOnlySpan then mkInByrefTy cenv.g elemTy else mkByrefTy cenv.g elemTy - - // Evaluate the span index lookup - let bodyExprFixup elemVar bodyExpr = - let elemAddrVar, _ = mkCompGenLocal mForLoopStart "addr" elemAddrTy - let e = mkCompGenLet mForLoopStart elemVar (mkAddrGet mForLoopStart (mkLocalValRef elemAddrVar)) bodyExpr - let getItemCallExpr, _ = BuildMethodCall tcVal cenv.g cenv.amap PossiblyMutates mWholeExpr true getItemMethInfo ValUseFlag.NormalValUse [] [ spanExpr ] [ idxExpr ] - mkCompGenLet mForLoopStart elemAddrVar getItemCallExpr e - - // Evaluate the span expression once and put it in spanVar - let overallExprFixup overallExpr = mkCompGenLet mForLoopStart spanVar enumExpr overallExpr - - let getLengthCallExpr, _ = BuildMethodCall tcVal cenv.g cenv.amap PossiblyMutates mWholeExpr true getLengthMethInfo ValUseFlag.NormalValUse [] [ spanExpr ] [] - - // Ask for a loop over integers for the given range - (elemTy, bodyExprFixup, overallExprFixup, Choice2Of3 (idxVar, mkZero cenv.g mForLoopStart, mkDecr cenv.g mForLoopStart getLengthCallExpr)) - - | _ -> - let enumerableVar, enumerableExprInVar = mkCompGenLocal mEnumExpr "inputSequence" enumExprTy - let enumeratorVar, enumeratorExpr, _, enumElemTy, getEnumExpr, getEnumTy, guardExpr, _, currentExpr = - AnalyzeArbitraryExprAsEnumerable cenv env true mEnumExpr enumExprTy enumerableExprInVar - (enumElemTy, (fun _ x -> x), id, Choice3Of3(enumerableVar, enumeratorVar, enumeratorExpr, getEnumExpr, getEnumTy, guardExpr, currentExpr)) - - let pat, _, vspecs, envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) - let elemVar, pat = - // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to - match pat with - | TPat_as (pat1, PBind(v, TypeScheme([], _)), _) -> - v, pat1 - | _ -> - let tmp, _ = mkCompGenLocal pat.Range "forLoopVar" enumElemTy - tmp, pat - - // Check the body of the loop - let bodyExpr, tpenv = TcStmt cenv envinner tpenv bodySynExpr - - // Add the pattern match compilation - let bodyExpr = - let valsDefinedByMatching = ListSet.remove valEq elemVar vspecs - CompilePatternForMatch - cenv env enumSynExpr.Range pat.Range false IgnoreWithWarning (elemVar, [], None) - [TClause(pat, None, TTarget(valsDefinedByMatching, bodyExpr, SequencePointAtTarget), mForLoopStart)] - enumElemTy - overallTy - - // Apply the fixup to bind the elemVar if needed - let bodyExpr = bodyExprFixup elemVar bodyExpr - - // Build the overall loop - let overallExpr = - - match iterationTechnique with - - // Build iteration as a for loop - | Choice1Of3(startExpr, finishExpr) -> - mkFastForLoop cenv.g (spForLoop, mWholeExpr, elemVar, startExpr, true, finishExpr, bodyExpr) - - // Build iteration as a for loop with a specific index variable that is not the same as the elemVar - | Choice2Of3(idxVar, startExpr, finishExpr) -> - mkFastForLoop cenv.g (spForLoop, mWholeExpr, idxVar, startExpr, true, finishExpr, bodyExpr) - - // Build iteration as a while loop with a try/finally disposal - | Choice3Of3(enumerableVar, enumeratorVar, _, getEnumExpr, _, guardExpr, currentExpr) -> - - // This compiled for must be matched EXACTLY by CompiledForEachExpr in opt.fs and creflect.fs - mkCompGenLet mForLoopStart enumerableVar enumExpr - (let cleanupE = BuildDisposableCleanup cenv env mWholeExpr enumeratorVar - let spBind = match spForLoop with SequencePointAtForLoop spStart -> SequencePointAtBinding spStart | NoSequencePointAtForLoop -> NoSequencePointAtStickyBinding - (mkLet spBind mForLoopStart enumeratorVar getEnumExpr - (mkTryFinally cenv.g - (mkWhile cenv.g - (NoSequencePointAtWhileLoop, - WhileLoopForCompiledForEachExprMarker, guardExpr, - mkCompGenLet mForLoopStart elemVar currentExpr bodyExpr, - mForLoopStart), - cleanupE, mForLoopStart, cenv.g.unit_ty, NoSequencePointAtTry, NoSequencePointAtFinally)))) - - let overallExpr = overallExprFixup overallExpr - overallExpr, tpenv - -//------------------------------------------------------------------------- -// TcQuotationExpr -//------------------------------------------------------------------------- - -and TcQuotationExpr cenv overallTy env tpenv (_oper, raw, ast, isFromQueryExpression, m) = - let astTy = NewInferenceType () - - // Assert the overall type for the domain of the quotation template - UnifyTypes cenv env m overallTy (if raw then mkRawQuotedExprTy cenv.g else mkQuotedExprTy cenv.g astTy) - - // Check the expression - let expr, tpenv = TcExpr cenv astTy env tpenv ast - - // Wrap the expression - let expr = Expr.Quote (expr, ref None, isFromQueryExpression, m, overallTy) - - // Coerce it if needed - let expr = if raw then mkCoerceExpr(expr, (mkRawQuotedExprTy cenv.g), m, (tyOfExpr cenv.g expr)) else expr - - // We serialize the quoted expression to bytes in IlxGen after type inference etc. is complete. - expr, tpenv - -/// Ignores an attribute -and IgnoreAttribute _ = None - -/// Used for all computation expressions except sequence expressions -and TcComputationExpression cenv env overallTy mWhole (interpExpr: Expr) builderTy tpenv (comp: SynExpr) = - - //dprintfn "TcComputationExpression, comp = \n%A\n-------------------\n" comp - let ad = env.eAccessRights - - let mkSynDelay2 (e: SynExpr) = mkSynDelay (e.Range.MakeSynthetic()) e - - let builderValName = CompilerGeneratedName "builder" - let mBuilderVal = interpExpr.Range - - // Give bespoke error messages for the FSharp.Core "query" builder - let isQuery = - match interpExpr with - | Expr.Val (vf, _, m) -> - let item = Item.CustomBuilder (vf.DisplayName, vf) - CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - valRefEq cenv.g vf cenv.g.query_value_vref - | _ -> false - - /// Make a builder.Method(...) call - let mkSynCall nm (m: range) args = - let m = m.MakeSynthetic() // Mark as synthetic so the language service won't pick it up. - let args = - match args with - | [] -> SynExpr.Const (SynConst.Unit, m) - | [arg] -> SynExpr.Paren (SynExpr.Paren (arg, range0, None, m), range0, None, m) - | args -> SynExpr.Paren (SynExpr.Tuple (false, args, [], m), range0, None, m) - - let builderVal = mkSynIdGet m builderValName - mkSynApp1 (SynExpr.DotGet (builderVal, range0, LongIdentWithDots([mkSynId m nm], []), m)) args m - - let hasMethInfo nm = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad nm builderTy |> isNil |> not - - let sourceMethInfo = TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Source" builderTy - - // Optionally wrap sources of "let!", "yield!", "use!" in "query.Source" - let mkSourceExpr callExpr = - match sourceMethInfo with - | [] -> callExpr - | _ -> mkSynCall "Source" callExpr.Range [callExpr] - - /// Decide if the builder is an auto-quote builder - let isAutoQuote = hasMethInfo "Quote" - - let customOperationMethods = - AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults cenv.infoReader env.NameEnv None ad IgnoreOverrides mBuilderVal builderTy - |> List.choose (fun methInfo -> - if not (IsMethInfoAccessible cenv.amap mBuilderVal ad methInfo) then None else - let nameSearch = - TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo - IgnoreAttribute // We do not respect this attribute for IL methods - (function (Attrib(_, _, [ AttribStringArg msg ], _, _, _, _)) -> Some msg | _ -> None) - IgnoreAttribute // We do not respect this attribute for provided methods - - match nameSearch with - | None -> None - | Some nm -> - let joinConditionWord = - TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo - IgnoreAttribute // We do not respect this attribute for IL methods - (function (Attrib(_, _, _, ExtractAttribNamedArg "JoinConditionWord" (AttribStringArg s), _, _, _)) -> Some s | _ -> None) - IgnoreAttribute // We do not respect this attribute for provided methods - - let flagSearch (propName: string) = - TryBindMethInfoAttribute cenv.g mBuilderVal cenv.g.attrib_CustomOperationAttribute methInfo - IgnoreAttribute // We do not respect this attribute for IL methods - (function (Attrib(_, _, _, ExtractAttribNamedArg propName (AttribBoolArg b), _, _, _)) -> Some b | _ -> None) - IgnoreAttribute // We do not respect this attribute for provided methods - - let maintainsVarSpaceUsingBind = defaultArg (flagSearch "MaintainsVariableSpaceUsingBind") false - let maintainsVarSpace = defaultArg (flagSearch "MaintainsVariableSpace") false - let allowInto = defaultArg (flagSearch "AllowIntoPattern") false - let isLikeZip = defaultArg (flagSearch "IsLikeZip") false - let isLikeJoin = defaultArg (flagSearch "IsLikeJoin") false - let isLikeGroupJoin = defaultArg (flagSearch "IsLikeGroupJoin") false - - Some (nm, maintainsVarSpaceUsingBind, maintainsVarSpace, allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, joinConditionWord, methInfo)) - - let customOperationMethodsIndexedByKeyword = - customOperationMethods - |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) - |> dict - - // Check for duplicates by method name (keywords and method names must be 1:1) - let customOperationMethodsIndexedByMethodName = - customOperationMethods - |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) - |> dict - - - /// Decide if the identifier represents a use of a custom query operator - let tryGetDataForCustomOperation (nm: Ident) = - match customOperationMethodsIndexedByKeyword.TryGetValue nm.idText with - | true, [opData] -> - let (opName, maintainsVarSpaceUsingBind, maintainsVarSpace, _allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, _joinConditionWord, methInfo) = opData - if (maintainsVarSpaceUsingBind && maintainsVarSpace) || (isLikeZip && isLikeJoin) || (isLikeZip && isLikeGroupJoin) || (isLikeJoin && isLikeGroupJoin) then - errorR(Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) - match customOperationMethodsIndexedByMethodName.TryGetValue methInfo.LogicalName with - | true, [_] -> () - | _ -> errorR(Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) - Some opData - | true, opData :: _ -> errorR(Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)); Some opData - | _ -> None - - /// Decide if the identifier represents a use of a custom query operator - let hasCustomOperations () = not (isNil customOperationMethods) - - let isCustomOperation nm = tryGetDataForCustomOperation nm |> Option.isSome - - // Check for the MaintainsVariableSpace on custom operation - let customOperationMaintainsVarSpace (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, _maintainsVarSpaceUsingBind, maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> maintainsVarSpace - - let customOperationMaintainsVarSpaceUsingBind (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> maintainsVarSpaceUsingBind - - let customOperationIsLikeZip (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeZip - - let customOperationIsLikeJoin (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeJoin - - let customOperationIsLikeGroupJoin (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, isLikeGroupJoin, _joinConditionWord, _methInfo) -> isLikeGroupJoin - - let customOperationJoinConditionWord (nm: Ident) = - match tryGetDataForCustomOperation nm with - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, Some joinConditionWord, _methInfo) -> joinConditionWord - | _ -> "on" - - let customOperationAllowsInto (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, _methInfo) -> allowInto - - let customOpUsageText nm = - match tryGetDataForCustomOperation nm with - | None -> None - | Some (_nm, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, _joinConditionWord, _methInfo) -> - if isLikeGroupJoin then - Some (FSComp.SR.customOperationTextLikeGroupJoin(nm.idText, customOperationJoinConditionWord nm, customOperationJoinConditionWord nm)) - elif isLikeJoin then - Some (FSComp.SR.customOperationTextLikeJoin(nm.idText, customOperationJoinConditionWord nm, customOperationJoinConditionWord nm)) - elif isLikeZip then - Some (FSComp.SR.customOperationTextLikeZip(nm.idText)) - else - None - - /// Inside the 'query { ... }' use a modified name environment that contains fake 'CustomOperation' entries - /// for all custom operations. This adds them to the completion lists and prevents them being used as values inside - /// the query. - let env = - if List.isEmpty customOperationMethods then env else - { env with - eNameResEnv = - (env.eNameResEnv, customOperationMethods) - ||> Seq.fold (fun nenv (nm, _, _, _, _, _, _, _, methInfo) -> - AddFakeNameToNameEnv nm nenv (Item.CustomOperation (nm, (fun () -> customOpUsageText (ident (nm, mBuilderVal))), Some methInfo))) } - - // Environment is needed for completions - CallEnvSink cenv.tcSink (comp.Range, env.NameEnv, ad) - - // Check for the [] attribute on an argument position - let tryGetArgInfosForCustomOperator (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> None - | Some (_nm, __maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, _isLikeZip, _isLikeJoin, _isLikeGroupJoin, _joinConditionWord, methInfo) -> - match methInfo with - | FSMeth(_, _, vref, _) -> - match ArgInfosOfMember cenv.g vref with - | [curriedArgInfo] -> Some curriedArgInfo // one for the actual argument group - | _ -> None - | _ -> None - - let expectedArgCountForCustomOperator (nm: Ident) = - match tryGetArgInfosForCustomOperator nm with - | None -> 0 - | Some argInfos -> max (argInfos.Length - 1) 0 // drop the computation context argument - - // Check for the [] attribute on an argument position - let isCustomOperationProjectionParameter i (nm: Ident) = - match tryGetArgInfosForCustomOperator nm with - | None -> false - | Some argInfos -> - i < argInfos.Length && - let (_, argInfo) = List.item i argInfos - HasFSharpAttribute cenv.g cenv.g.attrib_ProjectionParameterAttribute argInfo.Attribs - - let (|ForEachThen|_|) e = - match e with - | SynExpr.ForEach (_spBind, SeqExprOnly false, isFromSource, pat1, expr1, SynExpr.Sequential (_, true, clause, rest, _), _) -> Some (isFromSource, pat1, expr1, clause, rest) - | _ -> None - - let (|CustomOpId|_|) predicate e = - match e with - | SingleIdent nm when isCustomOperation nm && predicate nm -> Some nm - | _ -> None - - // e1 in e2 ('in' is parsed as 'JOIN_IN') - let (|InExpr|_|) (e: SynExpr) = - match e with - | SynExpr.JoinIn (e1, _, e2, mApp) -> Some (e1, e2, mApp) - | _ -> None - - // e1 on e2 (note: 'on' is the 'JoinConditionWord') - let (|OnExpr|_|) nm (e: SynExpr) = - match tryGetDataForCustomOperation nm with - | None -> None - | Some _ -> - match e with - | SynExpr.App (_, _, SynExpr.App (_, _, e1, SingleIdent opName, _), e2, _) when opName.idText = customOperationJoinConditionWord nm -> - let item = Item.CustomOperation (opName.idText, (fun () -> None), None) - CallNameResolutionSink cenv.tcSink (opName.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - Some (e1, e2) - | _ -> None - - // e1 into e2 - let (|IntoSuffix|_|) (e: SynExpr) = - match e with - | SynExpr.App (_, _, SynExpr.App (_, _, x, SingleIdent nm2, _), ExprAsPat intoPat, _) when nm2.idText = CustomOperations.Into -> - Some (x, nm2.idRange, intoPat) - | _ -> - None - - let arbPat (m: range) = mkSynPatVar None (mkSynId (m.MakeSynthetic()) "_missingVar") - - let MatchIntoSuffixOrRecover alreadyGivenError (nm: Ident) (e: SynExpr) = - match e with - | IntoSuffix (x, intoWordRange, intoPat) -> - // record the "into" as a custom operation for colorization - let item = Item.CustomOperation ("into", (fun () -> None), None) - CallNameResolutionSink cenv.tcSink (intoWordRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - (x, intoPat, alreadyGivenError) - | _ -> - if not alreadyGivenError then - errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - (e, arbPat e.Range, true) - - let MatchOnExprOrRecover alreadyGivenError nm (onExpr: SynExpr) = - match onExpr with - | OnExpr nm (innerSource, SynExprParen(keySelectors, _, _, _)) -> - (innerSource, keySelectors) - | _ -> - if not alreadyGivenError then - suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv onExpr) |> ignore - errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - (arbExpr("_innerSource", onExpr.Range), mkSynBifix onExpr.Range "=" (arbExpr("_keySelectors", onExpr.Range)) (arbExpr("_keySelector2", onExpr.Range))) - - let JoinOrGroupJoinOp detector e = - match e with - | SynExpr.App (_, _, CustomOpId detector nm, ExprAsPat innerSourcePat, mJoinCore) -> - Some(nm, innerSourcePat, mJoinCore, false) - // join with bad pattern (gives error on "join" and continues) - | SynExpr.App (_, _, CustomOpId detector nm, _innerSourcePatExpr, mJoinCore) -> - errorR(Error(FSComp.SR.tcBinaryOperatorRequiresVariable(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat mJoinCore, mJoinCore, true) - // join (without anything after - gives error on "join" and continues) - | CustomOpId detector nm -> - errorR(Error(FSComp.SR.tcBinaryOperatorRequiresVariable(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat e.Range, e.Range, true) - | _ -> - None - // JoinOrGroupJoinOp customOperationIsLikeJoin - - let (|JoinOp|_|) (e: SynExpr) = JoinOrGroupJoinOp customOperationIsLikeJoin e - let (|GroupJoinOp|_|) (e: SynExpr) = JoinOrGroupJoinOp customOperationIsLikeGroupJoin e - - let arbKeySelectors m = mkSynBifix m "=" (arbExpr("_keySelectors", m)) (arbExpr("_keySelector2", m)) - - let (|JoinExpr|_|) (e: SynExpr) = - match e with - | InExpr (JoinOp(nm, innerSourcePat, _, alreadyGivenError), onExpr, mJoinCore) -> - let (innerSource, keySelectors) = MatchOnExprOrRecover alreadyGivenError nm onExpr - Some(nm, innerSourcePat, innerSource, keySelectors, mJoinCore) - | JoinOp (nm, innerSourcePat, mJoinCore, alreadyGivenError) -> - if alreadyGivenError then - errorR(Error(FSComp.SR.tcOperatorRequiresIn(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some (nm, innerSourcePat, arbExpr("_innerSource", e.Range), arbKeySelectors e.Range, mJoinCore) - | _ -> None - - let (|GroupJoinExpr|_|) (e: SynExpr) = - match e with - | InExpr (GroupJoinOp (nm, innerSourcePat, _, alreadyGivenError), intoExpr, mGroupJoinCore) -> - let onExpr, intoPat, alreadyGivenError = MatchIntoSuffixOrRecover alreadyGivenError nm intoExpr - let innerSource, keySelectors = MatchOnExprOrRecover alreadyGivenError nm onExpr - Some (nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) - | GroupJoinOp (nm, innerSourcePat, mGroupJoinCore, alreadyGivenError) -> - if alreadyGivenError then - errorR(Error(FSComp.SR.tcOperatorRequiresIn(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some (nm, innerSourcePat, arbExpr("_innerSource", e.Range), arbKeySelectors e.Range, arbPat e.Range, mGroupJoinCore) - | _ -> - None - - - let (|JoinOrGroupJoinOrZipClause|_|) (e: SynExpr) = - match e with - - // join innerSourcePat in innerSource on (keySelector1 = keySelector2) - | JoinExpr (nm, innerSourcePat, innerSource, keySelectors, mJoinCore) -> - Some(nm, innerSourcePat, innerSource, Some keySelectors, None, mJoinCore) - - // groupJoin innerSourcePat in innerSource on (keySelector1 = keySelector2) into intoPat - | GroupJoinExpr (nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) -> - Some(nm, innerSourcePat, innerSource, Some keySelectors, Some intoPat, mGroupJoinCore) - - // zip intoPat in secondSource - | InExpr (SynExpr.App (_, _, CustomOpId customOperationIsLikeZip nm, ExprAsPat secondSourcePat, _), secondSource, mZipCore) -> - Some(nm, secondSourcePat, secondSource, None, None, mZipCore) - - // zip (without secondSource or in - gives error) - | CustomOpId customOperationIsLikeZip nm -> - errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat e.Range, arbExpr("_secondSource", e.Range), None, None, e.Range) - - // zip secondSource (without in - gives error) - | SynExpr.App (_, _, CustomOpId customOperationIsLikeZip nm, ExprAsPat secondSourcePat, mZipCore) -> - errorR(Error(FSComp.SR.tcOperatorIncorrectSyntax(nm.idText, Option.get (customOpUsageText nm)), mZipCore)) - Some(nm, secondSourcePat, arbExpr("_innerSource", e.Range), None, None, mZipCore) - - | _ -> - None - - let (|ForEachThenJoinOrGroupJoinOrZipClause|_|) e = - match e with - | ForEachThen (isFromSource, firstSourcePat, firstSource, JoinOrGroupJoinOrZipClause(nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), innerComp) - when - (let _firstSourceSimplePats, later1 = - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - Option.isNone later1) - - -> Some (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore, innerComp) - - | JoinOrGroupJoinOrZipClause(nm, pat2, expr2, expr3, pat3opt, mOpCore) -> - errorR(Error(FSComp.SR.tcBinaryOperatorRequiresBody(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some (true, arbPat e.Range, arbExpr("_outerSource", e.Range), nm, pat2, expr2, expr3, pat3opt, mOpCore, arbExpr("_innerComp", e.Range)) - - | _ -> - None - - let (|StripApps|) e = - let rec strip e = - match e with - | SynExpr.FromParseError (SynExpr.App (_, _, f, arg, _), _) - | SynExpr.App (_, _, f, arg, _) -> - let g, acc = strip f - g, (arg :: acc) - | _ -> e, [] - let g, acc = strip e - g, List.rev acc - - let (|OptionalIntoSuffix|) e = - match e with - | IntoSuffix (body, intoWordRange, optInfo) -> (body, Some (intoWordRange, optInfo)) - | body -> (body, None) - - let (|CustomOperationClause|_|) e = - match e with - | OptionalIntoSuffix(StripApps(SingleIdent nm, _) as core, optInto) when isCustomOperation nm -> - // Now we know we have a custom operation, commit the name resolution - let optIntoInfo = - match optInto with - | Some (intoWordRange, optInfo) -> - let item = Item.CustomOperation ("into", (fun () -> None), None) - CallNameResolutionSink cenv.tcSink (intoWordRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - Some optInfo - | None -> None - - Some (nm, Option.get (tryGetDataForCustomOperation nm), core, core.Range, optIntoInfo) - | _ -> None - - let mkSynLambda p e m = SynExpr.Lambda (false, false, p, e, m) - - let mkExprForVarSpace m (patvs: Val list) = - match patvs with - | [] -> SynExpr.Const (SynConst.Unit, m) - | [v] -> SynExpr.Ident v.Id - | vs -> SynExpr.Tuple (false, (vs |> List.map (fun v -> SynExpr.Ident v.Id)), [], m) - - let mkSimplePatForVarSpace m (patvs: Val list) = - let spats = - match patvs with - | [] -> [] - | [v] -> [mkSynSimplePatVar false v.Id] - | vs -> vs |> List.map (fun v -> mkSynSimplePatVar false v.Id) - SynSimplePats.SimplePats (spats, m) - - let mkPatForVarSpace m (patvs: Val list) = - match patvs with - | [] -> SynPat.Const (SynConst.Unit, m) - | [v] -> mkSynPatVar None v.Id - | vs -> SynPat.Tuple(false, (vs |> List.map (fun x -> mkSynPatVar None x.Id)), m) - - let (|OptionalSequential|) e = - match e with - | SynExpr.Sequential (_sp, true, dataComp1, dataComp2, _) -> (dataComp1, Some dataComp2) - | _ -> (e, None) - - // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) - // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay - // NOTE: we should probably suppress these sequence points altogether - let rangeForCombine innerComp1 = - match innerComp1 with - | SynExpr.IfThenElse (_, _, _, _, _, mIfToThen, _m) -> mIfToThen - | SynExpr.Match (SequencePointAtBinding mMatch, _, _, _) -> mMatch - | SynExpr.TryWith (_, _, _, _, _, SequencePointAtTry mTry, _) -> mTry - | SynExpr.TryFinally (_, _, _, SequencePointAtTry mTry, _) -> mTry - | SynExpr.For (SequencePointAtForLoop mBind, _, _, _, _, _, _) -> mBind - | SynExpr.ForEach (SequencePointAtForLoop mBind, _, _, _, _, _, _) -> mBind - | SynExpr.While (SequencePointAtWhileLoop mWhile, _, _, _) -> mWhile - | _ -> innerComp1.Range - - // Check for 'where x > y', 'select x, y' and other mis-applications of infix operators, give a good error message, and return a flag - let checkForBinaryApp comp = - match comp with - | StripApps(SingleIdent nm, [StripApps(SingleIdent nm2, args); arg2]) when - PrettyNaming.IsInfixOperator nm.idText && - expectedArgCountForCustomOperator nm2 > 0 && - not (List.isEmpty args) -> - let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range arg2.Range - errorR(Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator(), estimatedRangeOfIntendedLeftAndRightArguments)) - true - | SynExpr.Tuple (false, (StripApps(SingleIdent nm2, args) :: _), _, m) when - expectedArgCountForCustomOperator nm2 > 0 && - not (List.isEmpty args) -> - let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range m.EndRange - errorR(Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator(), estimatedRangeOfIntendedLeftAndRightArguments)) - true - | _ -> - false - - let addVarsToVarSpace (varSpace: LazyWithContext) f = - LazyWithContext.Create - ((fun m -> - let (patvs: Val list, env) = varSpace.Force m - let vs, envinner = f m env - let patvs = List.append patvs (vs |> List.filter (fun v -> not (patvs |> List.exists (fun v2 -> v.LogicalName = v2.LogicalName)))) - patvs, envinner), - id) - - let emptyVarSpace = LazyWithContext.NotLazy ([], env) - - // If there are no 'yield' in the computation expression, and the builder supports 'Yield', - // then allow the type-directed rule interpreting non-unit-typed expressions in statement - // positions as 'yield'. 'yield!' may be present in the computation expression. - let enableImplicitYield = - cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield - && (hasMethInfo "Yield" && hasMethInfo "Combine" && hasMethInfo "Delay" && YieldFree cenv comp) - - // q - a flag indicating if custom operators are allowed. They are not allowed inside try/with, try/finally, if/then/else etc. - // varSpace - a lazy data structure indicating the variables bound so far in the overall computation - // comp - the computation expression being analyzed - // translatedCtxt - represents the translation of the context in which the computation expression 'comp' occurs, up to a - // hole to be filled by (part of) the results of translating 'comp'. - let rec tryTrans firstTry q varSpace comp translatedCtxt = - - match comp with - - // for firstSourcePat in firstSource do - // join secondSourcePat in expr2 on (expr3 = expr4) - // ... - // --> - // join expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat secondSourcePat -> ...) - - // for firstSourcePat in firstSource do - // groupJoin secondSourcePat in expr2 on (expr3 = expr4) into groupPat - // ... - // --> - // groupJoin expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat groupPat -> ...) - - // for firstSourcePat in firstSource do - // zip secondSource into secondSourcePat - // ... - // --> - // zip expr1 expr2 (fun pat1 pat3 -> ...) - | ForEachThenJoinOrGroupJoinOrZipClause (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, secondResultPatOpt, mOpCore, innerComp) -> - - - if not q then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), nm.idRange)) - let firstSource = if isFromSource then mkSourceExpr firstSource else firstSource - let secondSource = mkSourceExpr secondSource - - // Add the variables to the variable space, on demand - let varSpaceWithFirstVars = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (firstSourcePat, None) - vspecs, envinner) - - let varSpaceWithSecondVars = - addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (secondSourcePat, None) - vspecs, envinner) - - let varSpaceWithGroupJoinVars = - match secondResultPatOpt with - | Some pat3 -> - addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat3, None) - vspecs, envinner) - | None -> varSpace - - let firstSourceSimplePats, later1 = SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - let secondSourceSimplePats, later2 = SimplePatsOfPat cenv.synArgNameGenerator secondSourcePat - - if Option.isSome later1 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), firstSourcePat.Range)) - if Option.isSome later2 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondSourcePat.Range)) - - // check 'join' or 'groupJoin' or 'zip' is permitted for this builder - match tryGetDataForCustomOperation nm with - | None -> error(Error(FSComp.SR.tcMissingCustomOperation(nm.idText), nm.idRange)) - | Some (opName, _, _, _, _, _, _, _, methInfo) -> - - // Record the resolution of the custom operation for posterity - let item = Item.CustomOperation (opName, (fun () -> customOpUsageText nm), Some methInfo) - - // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE. - CallNameResolutionSink cenv.tcSink (nm.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - let mkJoinExpr keySelector1 keySelector2 innerPat e = - let mSynthetic = mOpCore.MakeSynthetic() - mkSynCall methInfo.DisplayName mOpCore - [ firstSource - secondSource - (mkSynLambda firstSourceSimplePats keySelector1 mSynthetic) - (mkSynLambda secondSourceSimplePats keySelector2 mSynthetic) - (mkSynLambda firstSourceSimplePats (mkSynLambda innerPat e mSynthetic) mSynthetic) ] - - let mkZipExpr e = - let mSynthetic = mOpCore.MakeSynthetic() - mkSynCall methInfo.DisplayName mOpCore - [ firstSource - secondSource - (mkSynLambda firstSourceSimplePats (mkSynLambda secondSourceSimplePats e mSynthetic) mSynthetic) ] - - // wraps given expression into sequence with result produced by arbExpr so result will look like: - // l; SynExpr.ArbitraryAfterError (...) - // this allows to handle cases like 'on (a > b)' // '>' is not permitted as correct join relation - // after wrapping a and b can still be typechecked (so we'll have correct completion inside 'on' part) - // but presence of SynExpr.ArbitraryAfterError allows to avoid errors about incompatible types in cases like - // query { - // for a in [1] do - // join b in [""] on (a > b) - // } - // if we typecheck raw 'a' and 'b' then we'll end up with 2 errors: - // 1. incorrect join relation - // 2. incompatible types: int and string - // with SynExpr.ArbitraryAfterError we have only first one - let wrapInArbErrSequence l caption = - SynExpr.Sequential (SequencePointInfoForSeq.SequencePointsAtSeq, true, l, (arbExpr(caption, l.Range.EndRange)), l.Range) - - let mkOverallExprGivenVarSpaceExpr, varSpaceInner = - let isNullableOp opId = - match DecompileOpName opId with "?=" | "=?" | "?=?" -> true | _ -> false - match secondResultPatOpt, keySelectorsOpt with - // groupJoin - | Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin nm -> - let secondResultSimplePats, later3 = SimplePatsOfPat cenv.synArgNameGenerator secondResultPat - if Option.isSome later3 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondResultPat.Range)) - match relExpr with - | JoinRelation cenv env (keySelector1, keySelector2) -> - mkJoinExpr keySelector1 keySelector2 secondResultSimplePats, varSpaceWithGroupJoinVars - | BinOpExpr (opId, l, r) -> - if isNullableOp opId.idText then - // When we cannot resolve NullableOps, recommend the relevant namespace to be added - errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range)) - else - errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) - let l = wrapInArbErrSequence l "_keySelector1" - let r = wrapInArbErrSequence r "_keySelector2" - // this is not correct JoinRelation but it is still binary operation - // we've already reported error now we can use operands of binary operation as join components - mkJoinExpr l r secondResultSimplePats, varSpaceWithGroupJoinVars - | _ -> - errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) - // since the shape of relExpr doesn't match our expectations (JoinRelation) - // then we assume that this is l.h.s. of the join relation - // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in GroupJoin method - mkJoinExpr relExpr (arbExpr("_keySelector2", relExpr.Range)) secondResultSimplePats, varSpaceWithGroupJoinVars - - | None, Some relExpr when customOperationIsLikeJoin nm -> - match relExpr with - | JoinRelation cenv env (keySelector1, keySelector2) -> - mkJoinExpr keySelector1 keySelector2 secondSourceSimplePats, varSpaceWithSecondVars - | BinOpExpr (opId, l, r) -> - if isNullableOp opId.idText then - // When we cannot resolve NullableOps, recommend the relevant namespace to be added - errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range)) - else - errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) - // this is not correct JoinRelation but it is still binary operation - // we've already reported error now we can use operands of binary operation as join components - let l = wrapInArbErrSequence l "_keySelector1" - let r = wrapInArbErrSequence r "_keySelector2" - mkJoinExpr l r secondSourceSimplePats, varSpaceWithGroupJoinVars - | _ -> - errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range)) - // since the shape of relExpr doesn't match our expectations (JoinRelation) - // then we assume that this is l.h.s. of the join relation - // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in Join method - mkJoinExpr relExpr (arbExpr("_keySelector2", relExpr.Range)) secondSourceSimplePats, varSpaceWithGroupJoinVars - - | None, None when customOperationIsLikeZip nm -> - mkZipExpr, varSpaceWithSecondVars - - | _ -> - assert false - failwith "unreachable" - - - // Case from C# spec: A query expression with a join clause with an into followed by something other than a select clause - // Case from C# spec: A query expression with a join clause without an into followed by something other than a select clause - let valsInner, _env = varSpaceInner.Force mOpCore - let varSpaceExpr = mkExprForVarSpace mOpCore valsInner - let varSpacePat = mkPatForVarSpace mOpCore valsInner - let joinExpr = mkOverallExprGivenVarSpaceExpr varSpaceExpr - Some (trans true q varSpaceInner (SynExpr.ForEach (NoSequencePointAtForLoop, SeqExprOnly false, false, varSpacePat, joinExpr, innerComp, mOpCore)) translatedCtxt) - - - | SynExpr.ForEach (spForLoop, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _) -> - let wrappedSourceExpr = if isFromSource then mkSourceExpr sourceExpr else sourceExpr - let mFor = match spForLoop with SequencePointAtForLoop m -> m | _ -> pat.Range - let mPat = pat.Range - let spBind = match spForLoop with SequencePointAtForLoop m -> SequencePointAtBinding m | NoSequencePointAtForLoop -> NoSequencePointAtStickyBinding - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mFor ad "For" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("For"), mFor)) - - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) - vspecs, envinner) - - Some (trans true q varSpace innerComp - (fun holeFill -> - translatedCtxt (mkSynCall "For" mFor [wrappedSourceExpr; SynExpr.MatchLambda (false, sourceExpr.Range, [Clause(pat, None, holeFill, mPat, SequencePointAtTarget)], spBind, mFor) ])) ) - - | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> - let mFor = match spBind with SequencePointAtForLoop m -> m | _ -> m - if isQuery then errorR(Error(FSComp.SR.tcNoIntegerForLoopInQuery(), mFor)) - Some (trans true q varSpace (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m)) translatedCtxt ) - - | SynExpr.While (spWhile, guardExpr, innerComp, _) -> - let mGuard = guardExpr.Range - let mWhile = match spWhile with SequencePointAtWhileLoop m -> m | _ -> mGuard - if isQuery then error(Error(FSComp.SR.tcNoWhileInQuery(), mWhile)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "While" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("While"), mWhile)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mWhile)) - Some(trans true q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "While" mWhile [mkSynDelay2 guardExpr; mkSynCall "Delay" mWhile [mkSynDelay innerComp.Range holeFill]])) ) - - | SynExpr.TryFinally (innerComp, unwindExpr, mTryToLast, spTry, _spFinally) -> - - let mTry = match spTry with SequencePointAtTry m -> m | _ -> mTryToLast - if isQuery then error(Error(FSComp.SR.tcNoTryFinallyInQuery(), mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryFinally" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryFinally"), mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mTry)) - Some (translatedCtxt (mkSynCall "TryFinally" mTry [mkSynCall "Delay" mTry [mkSynDelay innerComp.Range (transNoQueryOps innerComp)]; mkSynDelay2 unwindExpr])) - - | SynExpr.Paren (_, _, _, m) -> - error(Error(FSComp.SR.tcConstructIsAmbiguousInComputationExpression(), m)) - - | SynExpr.ImplicitZero m -> - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"), m)) - Some (translatedCtxt (mkSynCall "Zero" m [])) - - | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _) - when firstTry -> - - // 'join' clauses preceded by 'let' and other constructs get processed by repackaging with a 'for' loop. - let patvs, _env = varSpace.Force comp.Range - let varSpaceExpr = mkExprForVarSpace mClause patvs - let varSpacePat = mkPatForVarSpace mClause patvs - - let dataCompPrior = - translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn ((true, false), varSpaceExpr, mClause))) - - // Rebind using for ... - let rebind = - SynExpr.ForEach (NoSequencePointAtForLoop, SeqExprOnly false, false, varSpacePat, dataCompPrior, comp, comp.Range) - - // Retry with the 'for' loop packaging. Set firstTry=false just in case 'join' processing fails - tryTrans false q varSpace rebind id - - - | OptionalSequential (CustomOperationClause (nm, _, opExpr, mClause, _), _) -> - - if not q then error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere(), opExpr.Range)) - - let patvs, _env = varSpace.Force comp.Range - let varSpaceExpr = mkExprForVarSpace mClause patvs - - let dataCompPriorToOp = - let isYield = not (customOperationMaintainsVarSpaceUsingBind nm) - translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn ((isYield, false), varSpaceExpr, mClause))) - - let rec consumeClauses (varSpace: LazyWithContext<_, _>) dataCompPrior compClausesExpr lastUsesBind = - - // Substitute 'yield ' into the context - - let patvs, _env = varSpace.Force comp.Range - let varSpaceSimplePat = mkSimplePatForVarSpace mClause patvs - let varSpacePat = mkPatForVarSpace mClause patvs - - match compClausesExpr with - - // Detect one custom operation... This clause will always match at least once... - | OptionalSequential (CustomOperationClause (nm, (opName, _maintainsVarSpaceUsingBind, _maintainsVarSpace, _allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, _, methInfo), opExpr, mClause, optionalIntoPat), optionalCont) -> - - // Record the resolution of the custom operation for posterity - let item = Item.CustomOperation (opName, (fun () -> customOpUsageText nm), Some methInfo) - - // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE. - CallNameResolutionSink cenv.tcSink (nm.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - if isLikeZip || isLikeJoin || isLikeGroupJoin then - errorR(Error(FSComp.SR.tcBinaryOperatorRequiresBody(nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - match optionalCont with - | None -> - // we are about to drop the 'opExpr' AST on the floor. we've already reported an error. attempt to get name resolutions before dropping it - RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects cenv env tpenv opExpr - dataCompPrior - | Some contExpr -> consumeClauses varSpace dataCompPrior contExpr lastUsesBind - else - - let maintainsVarSpace = customOperationMaintainsVarSpace nm - let maintainsVarSpaceUsingBind = customOperationMaintainsVarSpaceUsingBind nm - - let expectedArgCount = expectedArgCountForCustomOperator nm - - let dataCompAfterOp = - match opExpr with - | StripApps(SingleIdent nm, args) -> - if args.Length = expectedArgCount then - // Check for the [] attribute on each argument position - let args = args |> List.mapi (fun i arg -> if isCustomOperationProjectionParameter (i+1) nm then SynExpr.Lambda (false, false, varSpaceSimplePat, arg, arg.Range.MakeSynthetic()) else arg) - mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) - else - errorR(Error(FSComp.SR.tcCustomOperationHasIncorrectArgCount(nm.idText, expectedArgCount, args.Length), nm.idRange)) - mkSynCall methInfo.DisplayName mClause ([ dataCompPrior ] @ List.init expectedArgCount (fun i -> arbExpr("_arg" + string i, mClause))) - | _ -> failwith "unreachable" - - match optionalCont with - | None -> - match optionalIntoPat with - | Some intoPat -> errorR(Error(FSComp.SR.tcIntoNeedsRestOfQuery(), intoPat.Range)) - | None -> () - dataCompAfterOp - - | Some contExpr -> - - // select a.Name into name; ... - // distinct into d; ... - // - // Rebind the into pattern and process the rest of the clauses - match optionalIntoPat with - | Some intoPat -> - if not (customOperationAllowsInto nm) then - error(Error(FSComp.SR.tcOperatorDoesntAcceptInto(nm.idText), intoPat.Range)) - - // Rebind using either for ... or let!.... - let rebind = - if maintainsVarSpaceUsingBind then - SynExpr.LetOrUseBang (NoSequencePointAtLetBinding, false, false, intoPat, dataCompAfterOp, contExpr, intoPat.Range) - else - SynExpr.ForEach (NoSequencePointAtForLoop, SeqExprOnly false, false, intoPat, dataCompAfterOp, contExpr, intoPat.Range) - - trans true q emptyVarSpace rebind id - - // select a.Name; ... - // distinct; ... - // - // Process the rest of the clauses - | None -> - if maintainsVarSpace || maintainsVarSpaceUsingBind then - consumeClauses varSpace dataCompAfterOp contExpr maintainsVarSpaceUsingBind - else - consumeClauses emptyVarSpace dataCompAfterOp contExpr false - - // No more custom operator clauses in compClausesExpr, but there may be clauses like join, yield etc. - // Bind/iterate the dataCompPrior and use compClausesExpr as the body. - | _ -> - // Rebind using either for ... or let!.... - let rebind = - if lastUsesBind then - SynExpr.LetOrUseBang (NoSequencePointAtLetBinding, false, false, varSpacePat, dataCompPrior, compClausesExpr, compClausesExpr.Range) - else - SynExpr.ForEach (NoSequencePointAtForLoop, SeqExprOnly false, false, varSpacePat, dataCompPrior, compClausesExpr, compClausesExpr.Range) - - trans true q varSpace rebind id - - // Now run the consumeClauses - Some (consumeClauses varSpace dataCompPriorToOp comp false) - - | SynExpr.Sequential (sp, true, innerComp1, innerComp2, m) -> - - // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1 - if isQuery && checkForBinaryApp innerComp1 then - Some (trans true q varSpace innerComp2 translatedCtxt) - - else - - if isQuery && not(innerComp1.IsArbExprAndThusAlreadyReportedError) then - match innerComp1 with - | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential - | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), innerComp1.RangeOfFirstPortion)) - - match tryTrans true false varSpace innerComp1 id with - | Some c -> - // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) - // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay - // NOTE: we should probably suppress these sequence points altogether - let m1 = rangeForCombine innerComp1 - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Combine" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Combine"), m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), m)) - Some (translatedCtxt (mkSynCall "Combine" m1 [c; mkSynCall "Delay" m1 [mkSynDelay innerComp2.Range (transNoQueryOps innerComp2)]])) - | None -> - // "do! expr; cexpr" is treated as { let! () = expr in cexpr } - match innerComp1 with - | SynExpr.DoBang (rhsExpr, m) -> - let sp = - match sp with - | SuppressSequencePointOnStmtOfSequential -> SequencePointAtBinding m - | SuppressSequencePointOnExprOfSequential -> NoSequencePointAtDoBinding - | SequencePointsAtSeq -> SequencePointAtBinding m - Some(trans true q varSpace (SynExpr.LetOrUseBang (sp, false, true, SynPat.Const(SynConst.Unit, rhsExpr.Range), rhsExpr, innerComp2, m)) translatedCtxt) - // "expr; cexpr" is treated as sequential execution - | _ -> - Some (trans true q varSpace innerComp2 (fun holeFill -> - let fillExpr = - if enableImplicitYield then - // When implicit yields are enabled, then if the 'innerComp1' checks as type - // 'unit' we interpret the expression as a sequential, and when it doesn't - // have type 'unit' we interpret it as a 'Yield + Combine'. - let combineExpr = - let m1 = rangeForCombine innerComp1 - let implicitYieldExpr = mkSynCall "Yield" comp.Range [innerComp1] - mkSynCall "Combine" m1 [implicitYieldExpr; mkSynCall "Delay" m1 [mkSynDelay holeFill.Range holeFill]] - SynExpr.SequentialOrImplicitYield(sp, innerComp1, holeFill, combineExpr, m) - else - SynExpr.Sequential(sp, true, innerComp1, holeFill, m) - translatedCtxt fillExpr)) - - | SynExpr.IfThenElse (guardExpr, thenComp, elseCompOpt, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch) -> - match elseCompOpt with - | Some elseComp -> - if isQuery then error(Error(FSComp.SR.tcIfThenElseMayNotBeUsedWithinQueries(), mIfToThen)) - Some (translatedCtxt (SynExpr.IfThenElse (guardExpr, transNoQueryOps thenComp, Some(transNoQueryOps elseComp), spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch))) - | None -> - let elseComp = - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mIfToThen ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"), mIfToThen)) - mkSynCall "Zero" mIfToThen [] - Some (trans true q varSpace thenComp (fun holeFill -> translatedCtxt (SynExpr.IfThenElse (guardExpr, holeFill, Some elseComp, spIfToThen, isRecovery, mIfToThen, mIfToEndOfElseBranch)))) - - // 'let binds in expr' - | SynExpr.LetOrUse (isRec, false, binds, innerComp, m) -> - - // For 'query' check immediately - if isQuery then - match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with - | [NormalizedBinding(_, NormalBinding, (*inline*)false, (*mutable*)false, _, _, _, _, _, _, _, _)] when not isRec -> - () - | normalizedBindings -> - let failAt m = error(Error(FSComp.SR.tcNonSimpleLetBindingInQuery(), m)) - match normalizedBindings with - | NormalizedBinding(_, _, _, _, _, _, _, _, _, _, mBinding, _) :: _ -> failAt mBinding - | _ -> failAt m - - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun mQueryOp env -> - // Normalize the bindings before detecting the bound variables - match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with - | [NormalizedBinding(_vis, NormalBinding, false, false, _, _, _, _, pat, _, _, _)] -> - // successful case - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) - vspecs, envinner - | _ -> - // error case - error(Error(FSComp.SR.tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings(), mQueryOp))) - - - Some (trans true q varSpace innerComp (fun holeFill -> translatedCtxt (SynExpr.LetOrUse (isRec, false, binds, holeFill, m)))) - - // 'use x = expr in expr' - | SynExpr.LetOrUse (_, true, [Binding (_, NormalBinding, _, _, _, _, _, pat, _, rhsExpr, _, spBind)], innerComp, _) -> - let bindRange = match spBind with SequencePointAtBinding m -> m | _ -> rhsExpr.Range - if isQuery then error(Error(FSComp.SR.tcUseMayNotBeUsedInQueries(), bindRange)) - let innerCompRange = innerComp.Range - let consumeExpr = SynExpr.MatchLambda(false, innerCompRange, [Clause(pat, None, transNoQueryOps innerComp, innerCompRange, SequencePointAtTarget)], spBind, innerCompRange) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"), bindRange)) - Some (translatedCtxt (mkSynCall "Using" bindRange [rhsExpr; consumeExpr ])) - - // 'let! pat = expr in expr' --> build.Bind(e1, (function _argN -> match _argN with pat -> expr)) - | SynExpr.LetOrUseBang (spBind, false, isFromSource, pat, rhsExpr, innerComp, _) -> - - let bindRange = match spBind with SequencePointAtBinding m -> m | _ -> rhsExpr.Range - if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), bindRange)) - let innerRange = innerComp.Range - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), bindRange)) - - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let _, _, vspecs, envinner, _ = TcMatchPattern cenv (NewInferenceType()) env tpenv (pat, None) - vspecs, envinner) - - let rhsExpr = if isFromSource then mkSourceExpr rhsExpr else rhsExpr - Some (trans true q varSpace innerComp (fun holeFill -> - let consumeExpr = SynExpr.MatchLambda (false, pat.Range, [Clause(pat, None, holeFill, innerRange, SequencePointAtTarget)], spBind, innerRange) - translatedCtxt (mkSynCall "Bind" bindRange [rhsExpr; consumeExpr]))) - - // 'use! pat = e1 in e2' --> build.Bind(e1, (function _argN -> match _argN with pat -> build.Using(x, (fun _argN -> match _argN with pat -> e2)))) - | SynExpr.LetOrUseBang (spBind, true, isFromSource, (SynPat.Named (SynPat.Wild _, id, false, _, _) as pat), rhsExpr, innerComp, _) - | SynExpr.LetOrUseBang (spBind, true, isFromSource, (SynPat.LongIdent (LongIdentWithDots([id], _), _, _, _, _, _) as pat), rhsExpr, innerComp, _) -> - - let bindRange = match spBind with SequencePointAtBinding m -> m | _ -> rhsExpr.Range - if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), bindRange)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"), bindRange)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), bindRange)) - let consumeExpr = SynExpr.MatchLambda(false, bindRange, [Clause(pat, None, transNoQueryOps innerComp, innerComp.Range, SequencePointAtTarget)], spBind, bindRange) - let consumeExpr = mkSynCall "Using" bindRange [SynExpr.Ident(id); consumeExpr ] - let consumeExpr = SynExpr.MatchLambda(false, bindRange, [Clause(pat, None, consumeExpr, id.idRange, SequencePointAtTarget)], spBind, bindRange) - let rhsExpr = if isFromSource then mkSourceExpr rhsExpr else rhsExpr - Some(translatedCtxt (mkSynCall "Bind" bindRange [rhsExpr; consumeExpr])) - - // 'use! pat = e1 in e2' where 'pat' is not a simple name --> error - | SynExpr.LetOrUseBang (_spBind, true, _isFromSource, pat, _rhsExpr, _innerComp, _) -> - error(Error(FSComp.SR.tcInvalidUseBangBinding(), pat.Range)) - - | SynExpr.Match (spMatch, expr, clauses, m) -> - let mMatch = match spMatch with SequencePointAtBinding mMatch -> mMatch | _ -> m - if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) - let clauses = clauses |> List.map (fun (Clause(pat, cond, innerComp, patm, sp)) -> Clause(pat, cond, transNoQueryOps innerComp, patm, sp)) - Some(translatedCtxt (SynExpr.Match (spMatch, expr, clauses, m))) - - // 'match! expr with pats ...' --> build.Bind(e1, (function pats ...)) - | SynExpr.MatchBang (spMatch, expr, clauses, m) -> - let mMatch = match spMatch with SequencePointAtBinding mMatch -> mMatch | _ -> m - if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mMatch ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), mMatch)) - let clauses = clauses |> List.map (fun (Clause(pat, cond, innerComp, patm, sp)) -> Clause(pat, cond, transNoQueryOps innerComp, patm, sp)) - let consumeExpr = SynExpr.MatchLambda (false, mMatch, clauses, spMatch, mMatch) - Some(translatedCtxt (mkSynCall "Bind" mMatch [expr; consumeExpr])) - - | SynExpr.TryWith (innerComp, _mTryToWith, clauses, _mWithToLast, mTryToLast, spTry, _spWith) -> - let mTry = match spTry with SequencePointAtTry m -> m | _ -> mTryToLast - - if isQuery then error(Error(FSComp.SR.tcTryWithMayNotBeUsedInQueries(), mTry)) - let clauses = clauses |> List.map (fun (Clause(pat, cond, clauseComp, patm, sp)) -> Clause(pat, cond, transNoQueryOps clauseComp, patm, sp)) - let consumeExpr = SynExpr.MatchLambda(true, mTryToLast, clauses, NoSequencePointAtStickyBinding, mTryToLast) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryWith" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryWith"), mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"), mTry)) - Some(translatedCtxt (mkSynCall "TryWith" mTry [mkSynCall "Delay" mTry [mkSynDelay2 (transNoQueryOps innerComp)]; consumeExpr])) - - | SynExpr.YieldOrReturnFrom ((isYield, _), yieldExpr, m) -> - let yieldExpr = mkSourceExpr yieldExpr - if isYield then - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "YieldFrom" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("YieldFrom"), m)) - Some (translatedCtxt (mkSynCall "YieldFrom" m [yieldExpr])) - - else - if isQuery then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(), m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "ReturnFrom" builderTy) then - errorR(Error(FSComp.SR.tcRequireBuilderMethod("ReturnFrom"), m)) - Some (translatedCtxt yieldExpr) - else - Some (translatedCtxt (mkSynCall "ReturnFrom" m [yieldExpr])) - - | SynExpr.YieldOrReturn ((isYield, _), yieldExpr, m) -> - let methName = (if isYield then "Yield" else "Return") - if isQuery && not isYield then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(), m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad methName builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod(methName), m)) - Some(translatedCtxt (mkSynCall methName m [yieldExpr])) - - | _ -> None - - and transNoQueryOps comp = - trans true false emptyVarSpace comp id - - and trans firstTry q varSpace comp translatedCtxt = - match tryTrans firstTry q varSpace comp translatedCtxt with - | Some e -> e - | None -> - // This only occurs in final position in a sequence - match comp with - // "do! expr;" in final position is treated as { let! () = expr in return () } when Return is provided or as { let! () = expr in zero } otherwise - | SynExpr.DoBang (rhsExpr, m) -> - let mUnit = rhsExpr.Range - let rhsExpr = mkSourceExpr rhsExpr - if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(), m)) - let bodyExpr = - if isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Return" builderTy) then - SynExpr.ImplicitZero m - else - SynExpr.YieldOrReturn((false, true), SynExpr.Const (SynConst.Unit, m), m) - trans true q varSpace (SynExpr.LetOrUseBang(NoSequencePointAtDoBinding, false, false, SynPat.Const(SynConst.Unit, mUnit), rhsExpr, bodyExpr, m)) translatedCtxt - - // "expr;" in final position is treated as { expr; zero } - // Suppress the sequence point on the "zero" - | _ -> - // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore comp - if isQuery && checkForBinaryApp comp then - trans true q varSpace (SynExpr.ImplicitZero comp.Range) translatedCtxt - else - if isQuery && not comp.IsArbExprAndThusAlreadyReportedError then - match comp with - | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential - | _ -> errorR(Error(FSComp.SR.tcUnrecognizedQueryOperator(), comp.RangeOfFirstPortion)) - trans true q varSpace (SynExpr.ImplicitZero comp.Range) (fun holeFill -> - let fillExpr = - if enableImplicitYield then - let implicitYieldExpr = mkSynCall "Yield" comp.Range [comp] - SynExpr.SequentialOrImplicitYield(SuppressSequencePointOnStmtOfSequential, comp, holeFill, implicitYieldExpr, comp.Range) - else - SynExpr.Sequential(SuppressSequencePointOnStmtOfSequential, true, comp, holeFill, comp.Range) - translatedCtxt fillExpr) - - let basicSynExpr = - trans true (hasCustomOperations ()) (LazyWithContext.NotLazy ([], env)) comp (fun holeFill -> holeFill) - - let delayedExpr = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Delay" builderTy with - | [] -> basicSynExpr - | _ -> mkSynCall "Delay" mBuilderVal [(mkSynDelay2 basicSynExpr)] - - let quotedSynExpr = - if isAutoQuote then - SynExpr.Quote (mkSynIdGet (mBuilderVal.MakeSynthetic()) (CompileOpName "<@ @>"), (*isRaw=*)false, delayedExpr, (*isFromQueryExpression=*)true, mWhole) - else delayedExpr - - let runExpr = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Run" builderTy with - | [] -> quotedSynExpr - | _ -> mkSynCall "Run" mBuilderVal [quotedSynExpr] - - let lambdaExpr = - let mBuilderVal = mBuilderVal.MakeSynthetic() - SynExpr.Lambda (false, false, SynSimplePats.SimplePats ([mkSynSimplePatVar false (mkSynId mBuilderVal builderValName)], mBuilderVal), runExpr, mBuilderVal) - - let env = - match comp with - | SynExpr.YieldOrReturn ((true, _), _, _) -> { env with eContextInfo = ContextInfo.YieldInComputationExpression } - | SynExpr.YieldOrReturn ((_, true), _, _) -> { env with eContextInfo = ContextInfo.ReturnInComputationExpression } - | _ -> env - - let lambdaExpr, tpenv= TcExpr cenv (builderTy --> overallTy) env tpenv lambdaExpr - // beta-var-reduce to bind the builder using a 'let' binding - let coreExpr = mkApps cenv.g ((lambdaExpr, tyOfExpr cenv.g lambdaExpr), [], [interpExpr], mBuilderVal) - - coreExpr, tpenv - - -/// This case is used for computation expressions which are sequence expressions. Technically the code path is different because it -/// typechecks rather than doing a shallow syntactic translation, and generates calls into the Seq.* library -/// and helpers rather than to the builder methods (there is actually no builder for 'seq' in the library). -/// These are later detected by state machine compilation. -/// -/// Also "ienumerable extraction" is performed on arguments to "for". -and TcSequenceExpression cenv env tpenv comp overallTy m = - - let genEnumElemTy = NewInferenceType () - UnifyTypes cenv env m overallTy (mkSeqTy cenv.g genEnumElemTy) - - // Allow subsumption at 'yield' if the element type is nominal prior to the analysis of the body of the sequence expression - let flex = not (isTyparTy cenv.g genEnumElemTy) - - // If there are no 'yield' in the computation expression then allow the type-directed rule - // interpreting non-unit-typed expressions in statement positions as 'yield'. 'yield!' may be - // present in the computation expression. - let enableImplicitYield = - cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield - && (YieldFree cenv comp) - - let mkDelayedExpr (coreExpr: Expr) = - let m = coreExpr.Range - let overallTy = tyOfExpr cenv.g coreExpr - mkSeqDelay cenv env m overallTy coreExpr - - let rec tryTcSequenceExprBody env genOuterTy tpenv comp = - match comp with - | SynExpr.ForEach (_spBind, SeqExprOnly _seqExprOnly, _isFromSource, pat, pseudoEnumExpr, innerComp, m) -> - // This expression is not checked with the knowledge it is an IEnumerable, since we permit other enumerable types with GetEnumerator/MoveNext methods, as does C# - let pseudoEnumExpr, arb_ty, tpenv = TcExprOfUnknownType cenv env tpenv pseudoEnumExpr - let enumExpr, enumElemTy = ConvertArbitraryExprToEnumerable cenv arb_ty env pseudoEnumExpr - let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - - match pat', vspecs, innerExpr with - // peephole optimization: "for x in e1 -> e2" == "e1 |> List.map (fun x -> e2)" *) - | (TPat_as (TPat_wild _, PBind (v, _), _), - vs, - Expr.App (Expr.Val (vf, _, _), _, [genEnumElemTy], [yexpr], _)) - when vs.Length = 1 && valRefEq cenv.g vf cenv.g.seq_singleton_vref -> - - let enumExprMark = enumExpr.Range - let lam = mkLambda enumExprMark v (yexpr, genEnumElemTy) - - // SEQUENCE POINTS: need to build a let here consuming spBind - let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr - Some(mkCallSeqMap cenv.g m enumElemTy genEnumElemTy lam enumExpr, tpenv) - - | _ -> - let enumExprMark = enumExpr.Range - - // SEQUENCE POINTS: need to build a let here consuming spBind - - let matchv, matchExpr = compileSeqExprMatchClauses cenv env enumExprMark (pat', vspecs) innerExpr None enumElemTy genOuterTy - let lam = mkLambda enumExprMark matchv (matchExpr, tyOfExpr cenv.g matchExpr) - Some(mkSeqCollect cenv env m enumElemTy genOuterTy lam enumExpr, tpenv) - - | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> - Some(tcSequenceExprBody env genOuterTy tpenv (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m))) - - | SynExpr.While (_spWhile, guardExpr, innerComp, _m) -> - let guardExpr, tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr - let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp - - let guardExprMark = guardExpr.Range - let guardExpr = mkUnitDelayLambda cenv.g guardExprMark guardExpr - let innerExpr = mkDelayedExpr innerExpr - Some(mkSeqFromFunctions cenv env guardExprMark genOuterTy guardExpr innerExpr, tpenv) - - | SynExpr.TryFinally (innerComp, unwindExpr, _mTryToLast, _spTry, _spFinally) -> - let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp - let unwindExpr, tpenv = TcExpr cenv cenv.g.unit_ty env tpenv unwindExpr - - let unwindExprMark = unwindExpr.Range - let unwindExpr = mkUnitDelayLambda cenv.g unwindExprMark unwindExpr - let innerExpr = mkDelayedExpr innerExpr - let innerExprMark = innerExpr.Range - - Some(mkSeqFinally cenv env innerExprMark genOuterTy innerExpr unwindExpr, tpenv) - - | SynExpr.Paren (_, _, _, m) when not (cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield)-> - error(Error(FSComp.SR.tcConstructIsAmbiguousInSequenceExpression(), m)) - - | SynExpr.ImplicitZero m -> - Some(mkSeqEmpty cenv env m genOuterTy, tpenv ) - - | SynExpr.DoBang (_rhsExpr, m) -> - error(Error(FSComp.SR.tcDoBangIllegalInSequenceExpression(), m)) - - | SynExpr.Sequential (sp, true, innerComp1, innerComp2, m) -> - // "expr; cexpr" is treated as sequential execution - // "cexpr; cexpr" is treated as append - let res, tpenv = tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv innerComp1 - match res with - | Choice1Of2 innerExpr1 -> - let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 - let innerExpr2 = mkDelayedExpr innerExpr2 - Some(mkSeqAppend cenv env innerComp1.Range genOuterTy innerExpr1 innerExpr2, tpenv) - | Choice2Of2 stmt1 -> - let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 - Some(Expr.Sequential(stmt1, innerExpr2, NormalSeq, sp, m), tpenv) - - | SynExpr.IfThenElse (guardExpr, thenComp, elseCompOpt, spIfToThen, _isRecovery, mIfToThen, mIfToEndOfElseBranch) -> - let guardExpr', tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr - let thenExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv thenComp - let elseComp = (match elseCompOpt with Some c -> c | None -> SynExpr.ImplicitZero mIfToThen) - let elseExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv elseComp - Some(mkCond spIfToThen SequencePointAtTarget mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv) - - // 'let x = expr in expr' - | SynExpr.LetOrUse (_, false (* not a 'use' binding *), _, _, _) -> - TcLinearExprs - (fun ty envinner tpenv e -> tcSequenceExprBody envinner ty tpenv e) - cenv env overallTy - tpenv - true - comp - (fun x -> x) |> Some - - // 'use x = expr in expr' - | SynExpr.LetOrUse (_isRec, true, [Binding (_vis, NormalBinding, _, _, _, _, _, pat, _, rhsExpr, _, _spBind)], innerComp, wholeExprMark) -> - - let bindPatTy = NewInferenceType () - let inputExprTy = NewInferenceType () - let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv bindPatTy env tpenv (pat, None) - UnifyTypes cenv env m inputExprTy bindPatTy - let inputExpr, tpenv = TcExpr cenv inputExprTy env tpenv rhsExpr - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - let inputExprMark = inputExpr.Range - let matchv, matchExpr = compileSeqExprMatchClauses cenv env inputExprMark (pat', vspecs) innerExpr (Some inputExpr) bindPatTy genOuterTy - let consumeExpr = mkLambda wholeExprMark matchv (matchExpr, genOuterTy) - //SEQPOINT NEEDED - we must consume spBind on this path - Some(mkSeqUsing cenv env wholeExprMark bindPatTy genOuterTy inputExpr consumeExpr, tpenv) - - | SynExpr.LetOrUseBang (_, _, _, _, _, _, m) -> - error(Error(FSComp.SR.tcUseForInSequenceExpression(), m)) - - | SynExpr.Match (spMatch, expr, clauses, _) -> - let inputExpr, matchty, tpenv = TcExprOfUnknownType cenv env tpenv expr - let tclauses, tpenv = - List.mapFold - (fun tpenv (Clause(pat, cond, innerComp, _, sp)) -> - let pat', cond', vspecs, envinner, tpenv = TcMatchPattern cenv matchty env tpenv (pat, cond) - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - TClause(pat', cond', TTarget(vspecs, innerExpr, sp), pat'.Range), tpenv) - tpenv - clauses - let inputExprTy = tyOfExpr cenv.g inputExpr - let inputExprMark = inputExpr.Range - let matchv, matchExpr = CompilePatternForMatchClauses cenv env inputExprMark inputExprMark true ThrowIncompleteMatchException (Some inputExpr) inputExprTy genOuterTy tclauses - Some(mkLet spMatch inputExprMark matchv inputExpr matchExpr, tpenv) - - | SynExpr.TryWith (_, mTryToWith, _, _, _, _, _) -> - error(Error(FSComp.SR.tcTryIllegalInSequenceExpression(), mTryToWith)) - - | SynExpr.YieldOrReturnFrom ((isYield, _), yieldExpr, m) -> - let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv yieldExpr - - if not isYield then errorR(Error(FSComp.SR.tcUseYieldBangForMultipleResults(), m)) - - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy - Some(mkCoerceExpr(resultExpr, genOuterTy, m, genExprTy), tpenv) - - | SynExpr.YieldOrReturn ((isYield, _), yieldExpr, m) -> - let genResultTy = NewInferenceType () - if not isYield then errorR(Error(FSComp.SR.tcSeqResultsUseYield(), m)) - UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) - - let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv yieldExpr - Some(mkCallSeqSingleton cenv.g m genResultTy resultExpr, tpenv ) - - | _ -> None - - and tcSequenceExprBody env genOuterTy tpenv comp = - let res, tpenv = tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv comp - match res with - | Choice1Of2 expr -> - expr, tpenv - | Choice2Of2 stmt -> - let m = comp.Range - let resExpr = Expr.Sequential(stmt, mkSeqEmpty cenv env m genOuterTy, NormalSeq, SuppressSequencePointOnStmtOfSequential, m) - resExpr, tpenv - - and tcSequenceExprBodyAsSequenceOrStatement env genOuterTy tpenv comp = - match tryTcSequenceExprBody env genOuterTy tpenv comp with - | Some (expr, tpenv) -> Choice1Of2 expr, tpenv - | None -> - let env = { env with eContextInfo = ContextInfo.SequenceExpression genOuterTy } - if enableImplicitYield then - let hasTypeUnit, expr, tpenv = TryTcStmt cenv env tpenv comp - if hasTypeUnit then - Choice2Of2 expr, tpenv - else - let genResultTy = NewInferenceType () - UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) - let exprTy = tyOfExpr cenv.g expr - AddCxTypeMustSubsumeType env.eContextInfo env.DisplayEnv cenv.css m NoTrace genResultTy exprTy - let resExpr = mkCallSeqSingleton cenv.g m genResultTy (mkCoerceExpr(expr, genResultTy, m, exprTy)) - Choice1Of2 resExpr, tpenv - else - let stmt, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv comp - Choice2Of2 stmt, tpenv - - let coreExpr, tpenv = tcSequenceExprBody env overallTy tpenv comp - let delayedExpr = mkDelayedExpr coreExpr - delayedExpr, tpenv - -/// When checking sequence of function applications, -/// type applications and dot-notation projections, first extract known -/// type information from the applications. -/// -/// 'overallTy' is the type expected for the entire chain of expr + lookups. -/// 'exprty' is the type of the expression on the left of the lookup chain. -/// -/// We propagate information from the expected overall type 'overallTy'. The use -/// of function application syntax unambiguously implies that 'overallTy' is a function type. -and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = - - let rec propagate isAddrOf delayedList mExpr exprty = - match delayedList with - | [] -> - - if not (isNil delayed) then - - // We generate a tag inference parameter to the return type for "&x" and 'NativePtr.toByRef' - // See RFC FS-1053.md - let exprty = - if isAddrOf && isByrefTy cenv.g exprty then - mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewByRefKindInferenceType cenv.g mExpr) - elif isByrefTy cenv.g exprty then - // Implicit dereference on byref on return - if isByrefTy cenv.g overallTy then - errorR(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), mExpr)) - destByrefTy cenv.g exprty - else - exprty - - UnifyTypesAndRecover cenv env mExpr overallTy exprty - - | DelayedDot :: _ - | DelayedSet _ :: _ - | DelayedDotLookup _ :: _ -> () - | DelayedTypeApp (_, _mTypeArgs, mExprAndTypeArgs) :: delayedList' -> - // Note this case should not occur: would eventually give an "Unexpected type application" error in TcDelayed - propagate isAddrOf delayedList' mExprAndTypeArgs exprty - - | DelayedApp (_, arg, mExprAndArg) :: delayedList' -> - let denv = env.DisplayEnv - match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with - | ValueSome (_, resultTy) -> - - // We add tag parameter to the return type for "&x" and 'NativePtr.toByRef' - // See RFC FS-1053.md - let isAddrOf = - match expr with - | ApplicableExpr(_, Expr.App (Expr.Val (vf, _, _), _, _, [], _), _) - when (valRefEq cenv.g vf cenv.g.addrof_vref || - valRefEq cenv.g vf cenv.g.nativeptr_tobyref_vref) -> true - | _ -> false - - propagate isAddrOf delayedList' mExprAndArg resultTy - - | _ -> - let mArg = arg.Range - match arg with - | SynExpr.CompExpr _ -> () - | SynExpr.ArrayOrListOfSeqExpr (false, _, _) -> - // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body - RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed - if IsIndexerType cenv.g cenv.amap expr.Type then - match expr.Expr with - | Expr.Val (d, _, _) -> - error (NotAFunctionButIndexer(denv, overallTy, Some d.DisplayName, mExpr, mArg)) - | _ -> - error (NotAFunctionButIndexer(denv, overallTy, None, mExpr, mArg)) - else - error (NotAFunction(denv, overallTy, mExpr, mArg)) - | _ -> - // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body - RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed - error (NotAFunction(denv, overallTy, mExpr, mArg)) - - propagate false delayed expr.Range exprty - -and PropagateThenTcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag: ExprAtomicFlag) delayed = - Propagate cenv overallTy env tpenv expr exprty delayed - TcDelayed cenv overallTy env tpenv mExpr expr exprty atomicFlag delayed - - -/// Typecheck "expr ... " constructs where "..." is a sequence of applications, -/// type applications and dot-notation projections. -and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag: ExprAtomicFlag) delayed = - - // OK, we've typechecked the thing on the left of the delayed lookup chain. - // We can now record for posterity the type of this expression and the location of the expression. - if (atomicFlag = ExprAtomicFlag.Atomic) then - CallExprHasTypeSink cenv.tcSink (mExpr, env.NameEnv, exprty, env.DisplayEnv, env.eAccessRights) - - match delayed with - | [] - | DelayedDot :: _ -> - UnifyTypes cenv env mExpr overallTy exprty - expr.Expr, tpenv - // Expr.M (args) where x.M is a .NET method or index property - // expr.M(args) where x.M is a .NET method or index property - // expr.M where x.M is a .NET method or index property - | DelayedDotLookup (longId, mDotLookup) :: otherDelayed -> - TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup - // f x - | DelayedApp (hpa, arg, mExprAndArg) :: otherDelayed -> - TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty arg hpa otherDelayed - // f - | DelayedTypeApp (_, mTypeArgs, _mExprAndTypeArgs) :: _ -> - error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs)) - | DelayedSet (synExpr2, mStmt) :: otherDelayed -> - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mExpr)) - UnifyTypes cenv env mExpr overallTy cenv.g.unit_ty - let expr = expr.Expr - let _wrap, exprAddress, _readonly, _writeonly = mkExprAddrOfExpr cenv.g true false DefinitelyMutates expr None mExpr - let vty = tyOfExpr cenv.g expr - // Always allow subsumption on assignment to fields - let expr2, tpenv = TcExprFlex cenv true false vty env tpenv synExpr2 - let v, _ve = mkCompGenLocal mExpr "addr" (mkByrefTy cenv.g vty) - mkCompGenLet mStmt v exprAddress (mkAddrSet mStmt (mkLocalValRef v) expr2), tpenv - - -/// Convert the delayed identifiers to a dot-lookup. -/// -/// TcItemThen: For StaticItem [.Lookup], mPrior is the range of StaticItem -/// TcLookupThen: For expr.InstanceItem [.Lookup], mPrior is the range of expr.InstanceItem -and delayRest rest mPrior delayed = - match rest with - | [] -> delayed - | longId -> - let mPriorAndLongId = unionRanges mPrior (rangeOfLid longId) - DelayedDotLookup (rest, mPriorAndLongId) :: delayed - -/// Typecheck "nameof" expressions -and TcNameOfExpr cenv env tpenv (synArg: SynExpr) = - - let rec stripParens expr = - match expr with - | SynExpr.Paren(expr, _, _, _) -> stripParens expr - | _ -> expr - - let cleanSynArg = stripParens synArg - let m = cleanSynArg.Range - let rec check overallTyOpt expr (delayed: DelayedItem list) = - match expr with - | LongOrSingleIdent (false, (LongIdentWithDots(longId, _) as lidd), _, _) when longId.Length > 0 -> - let ad = env.eAccessRights - let id, rest = List.headAndTail longId - match ResolveLongIndentAsModuleOrNamespaceOrStaticClass cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m false true OpenQualified env.eNameResEnv ad id rest true with - | Result modref when delayed.IsEmpty && modref |> List.exists (p23 >> IsEntityAccessible cenv.amap m ad) -> - () // resolved to a module or namespace, done with checks - | _ -> - let (TypeNameResolutionInfo(_, staticArgsInfo)) = GetLongIdentTypeNameInfo delayed - match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad longId staticArgsInfo PermitDirectReferenceToGeneratedType.No with - | Result tcref when IsEntityAccessible cenv.amap m ad tcref -> - () // resolved to a type name, done with checks - | _ -> - let overallTy = match overallTyOpt with None -> NewInferenceType() | Some t -> t - let _, _ = TcLongIdentThen cenv overallTy env tpenv lidd delayed - () // checked as an expression, done with checks - List.last longId - - | SynExpr.TypeApp (hd, _, types, _, _, _, m) -> - check overallTyOpt hd (DelayedTypeApp(types, m, m) :: delayed) - - | SynExpr.Paren(expr, _, _, _) when overallTyOpt.IsNone && delayed.IsEmpty -> - check overallTyOpt expr [] - - | SynExpr.Typed (synBodyExpr, synType, _m) when delayed.IsEmpty && overallTyOpt.IsNone -> - let tgtTy, _tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType - check (Some tgtTy) synBodyExpr [] - - | _ -> - error (Error(FSComp.SR.expressionHasNoName(), m)) - - let lastIdent = check None cleanSynArg [] - let constRange = mkRange m.FileName m.Start (mkPos m.StartLine (m.StartColumn + lastIdent.idText.Length + 2)) // `2` are for quotes - Expr.Const(Const.String(lastIdent.idText), constRange, cenv.g.string_ty) - -//------------------------------------------------------------------------- -// TcFunctionApplicationThen: Typecheck "expr x" + projections -//------------------------------------------------------------------------- - -and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty (synArg: SynExpr) atomicFlag delayed = - let denv = env.DisplayEnv - let mArg = synArg.Range - let mFunExpr = expr.Range - - // If the type of 'synArg' unifies as a function type, then this is a function application, otherwise - // it is an error or a computation expression - match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr exprty with - | ValueSome (domainTy, resultTy) -> - match expr with - | ApplicableExpr(_, NameOfExpr cenv.g _, _) when cenv.g.langVersion.SupportsFeature LanguageFeature.NameOf -> - let replacementExpr = TcNameOfExpr cenv env tpenv synArg - TcDelayed cenv overallTy env tpenv mExprAndArg (ApplicableExpr(cenv, replacementExpr, true)) cenv.g.string_ty ExprAtomicFlag.Atomic delayed - | _ -> - // Notice the special case 'seq { ... }'. In this case 'seq' is actually a function in the F# library. - // Set a flag in the syntax tree to say we noticed a leading 'seq' - match synArg with - | SynExpr.CompExpr (false, isNotNakedRefCell, _comp, _m) -> - isNotNakedRefCell := - !isNotNakedRefCell - || - (match expr with - | ApplicableExpr(_, Expr.Op(TOp.Coerce, _, [SeqExpr cenv.g], _), _) -> true - | _ -> false) - | _ -> () - - let arg, tpenv = TcExpr cenv domainTy env tpenv synArg - let exprAndArg, resultTy = buildApp cenv expr resultTy arg mExprAndArg - TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed - - | ValueNone -> - // OK, 'expr' doesn't have function type, but perhaps 'expr' is a computation expression builder, and 'arg' is '{ ... }' - match synArg with - | SynExpr.CompExpr (false, _isNotNakedRefCell, comp, _m) -> - let bodyOfCompExpr, tpenv = TcComputationExpression cenv env overallTy mFunExpr expr.Expr exprty tpenv comp - TcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv bodyOfCompExpr) (tyOfExpr cenv.g bodyOfCompExpr) ExprAtomicFlag.NonAtomic delayed - | _ -> - error (NotAFunction(denv, overallTy, mFunExpr, mArg)) - -//------------------------------------------------------------------------- -// TcLongIdentThen: Typecheck "A.B.C.E.F ... " constructs -//------------------------------------------------------------------------- - -and GetLongIdentTypeNameInfo delayed = - // Given 'MyOverloadedType.MySubType...' use the number of given type arguments to help - // resolve type name lookup of 'MyOverloadedType' - // Also determine if type names should resolve to Item.Types or Item.CtorGroup - match delayed with - | DelayedTypeApp (tyargs, _, _) :: (DelayedDot | DelayedDotLookup _) :: _ -> - // cases like 'MyType.Sth' - TypeNameResolutionInfo(ResolveTypeNamesToTypeRefs, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) - - | DelayedTypeApp (tyargs, _, _) :: _ -> - // Note, this also covers the case 'MyType.' (without LValue_get), which is needed for VS (when typing) - TypeNameResolutionInfo(ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) - - | _ -> - TypeNameResolutionInfo.Default - -and TcLongIdentThen cenv overallTy env tpenv (LongIdentWithDots(longId, _)) delayed = - - let ad = env.eAccessRights - let typeNameResInfo = GetLongIdentTypeNameInfo delayed - let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId - TcItemThen cenv overallTy env tpenv nameResolutionResult delayed - -//------------------------------------------------------------------------- -// Typecheck "item+projections" -//------------------------------------------------------------------------- *) -// mItem is the textual range covered by the long identifiers that make up the item -and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) delayed = - let g = cenv.g - let delayed = delayRest rest mItem delayed - let ad = env.eAccessRights - match item with - // x where x is a union case or active pattern result tag. - | (Item.UnionCase _ | Item.ExnCase _ | Item.ActivePatternResult _) as item -> - // ucaseAppTy is the type of the union constructor applied to its (optional) argument - let ucaseAppTy = NewInferenceType () - let mkConstrApp, argTys, argNames = - match item with - | Item.ActivePatternResult(apinfo, _, n, _) -> - let aparity = apinfo.Names.Length - match aparity with - | 0 | 1 -> - let mkConstrApp _mArgs = function [arg] -> arg | _ -> error(InternalError("ApplyUnionCaseOrExn", mItem)) - mkConstrApp, [ucaseAppTy], [ for (s, m) in apinfo.ActiveTagsWithRanges -> mkSynId m s ] - | _ -> - let ucref = mkChoiceCaseRef g mItem aparity n - let _, _, tinst, _ = infoOfTyconRef mItem ucref.TyconRef - let ucinfo = UnionCaseInfo(tinst, ucref) - ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy (Item.UnionCase(ucinfo, false)) - | _ -> - ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy item - let numArgTys = List.length argTys - // Subsumption at data constructions if argument type is nominal prior to equations for any arguments or return types - let flexes = argTys |> List.map (isTyparTy g >> not) - - let (|FittedArgs|_|) arg = - match arg with - | SynExprParen(SynExpr.Tuple (false, args, _, _), _, _, _) - | SynExpr.Tuple (false, args, _, _) when numArgTys > 1 -> Some args - | SynExprParen(arg, _, _, _) - | arg when numArgTys = 1 -> Some [arg] - | _ -> None - - match delayed with - // This is where the constructor is applied to an argument - | ((DelayedApp (atomicFlag, (FittedArgs args as origArg), mExprAndArg)) :: otherDelayed) -> - // assert the overall result type if possible - if isNil otherDelayed then - UnifyTypes cenv env mExprAndArg overallTy ucaseAppTy - - let numArgs = List.length args - UnionCaseOrExnCheck env numArgTys numArgs mExprAndArg - - // if we manage to get here - number of formal arguments = number of actual arguments - // apply named parameters - let args = - // GetMethodArgs checks that no named parameters are located before positional - let unnamedArgs, namedCallerArgs = GetMethodArgs origArg - match namedCallerArgs with - | [] -> - args - | _ -> - let fittedArgs = Array.zeroCreate numArgTys - - // first: put all positional arguments - let mutable currentIndex = 0 - for arg in unnamedArgs do - fittedArgs.[currentIndex] <- arg - currentIndex <- currentIndex + 1 - - let SEEN_NAMED_ARGUMENT = -1 - - // dealing with named arguments is a bit tricky since prior to these changes we have an ambiguous situation: - // regular notation for named parameters Some(Value = 5) can mean either 1) create option with value - result of equality operation or 2) create option using named arg syntax. - // so far we've used 1) so we cannot immediately switch to 2) since it will be a definite breaking change. - - for (_, id, arg) in namedCallerArgs do - match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with - | Some i -> - if isNull(box fittedArgs.[i]) then - fittedArgs.[i] <- arg - let argContainerOpt = match item with - | Item.UnionCase(uci, _) -> Some(ArgumentContainer.UnionCase uci) - | Item.ExnCase tref -> Some(ArgumentContainer.Type tref) - | _ -> None - let argItem = Item.ArgName (argNames.[i], argTys.[i], argContainerOpt) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, argItem, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) - else error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) - currentIndex <- SEEN_NAMED_ARGUMENT - | None -> - // ambiguity may appear only when if argument is boolean\generic. - // if - // - we didn't find argument with specified name AND - // - we have not seen any named arguments so far AND - // - type of current argument is bool\generic - // then we'll favor old behavior and treat current argument as positional. - let isSpecialCaseForBackwardCompatibility = - (currentIndex <> SEEN_NAMED_ARGUMENT) && - (currentIndex < numArgTys) && - match stripTyEqns g argTys.[currentIndex] with - | TType_app(tcref, _) -> tyconRefEq g g.bool_tcr tcref || tyconRefEq g g.system_Bool_tcref tcref - | TType_var(_) -> true - | _ -> false - - if isSpecialCaseForBackwardCompatibility then - assert (isNull(box fittedArgs.[currentIndex])) - fittedArgs.[currentIndex] <- List.item currentIndex args // grab original argument, not item from the list of named parameters - currentIndex <- currentIndex + 1 - else - match item with - | Item.UnionCase(uci, _) -> - error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(uci.Name, id.idText), id.idRange)) - | Item.ExnCase tcref -> - error(Error(FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName(tcref.DisplayName, id.idText), id.idRange)) - | Item.ActivePatternResult(_,_,_,_) -> - error(Error(FSComp.SR.tcActivePatternsDoNotHaveFields(), id.idRange)) - | _ -> - error(Error(FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName(id.idText), id.idRange)) - - assert (Seq.forall (box >> ((<>) null) ) fittedArgs) - List.ofArray fittedArgs - - let args', tpenv = TcExprs cenv env mExprAndArg tpenv flexes argTys args - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv (mkConstrApp mExprAndArg args')) ucaseAppTy atomicFlag otherDelayed - - | DelayedTypeApp (_x, mTypeArgs, _mExprAndTypeArgs) :: _delayed' -> - error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs)) - | _ -> - // Work out how many syntactic arguments we really expect. Also return a function that builds the overall - // expression, but don't apply this function until after we've checked that the number of arguments is OK - // (or else we would be building an invalid expression) - - // Unit-taking active pattern result can be applied to no args - let numArgs, mkExpr = - // This is where the constructor is an active pattern result applied to no argument - // Unit-taking active pattern result can be applied to no args - if (numArgTys = 1 && match item with Item.ActivePatternResult _ -> true | _ -> false) then - UnifyTypes cenv env mItem (List.head argTys) g.unit_ty - 1, (fun () -> mkConstrApp mItem [mkUnit g mItem]) - - // This is where the constructor expects no arguments and is applied to no argument - elif numArgTys = 0 then - 0, (fun () -> mkConstrApp mItem []) - else - // This is where the constructor expects arguments but is not applied to arguments, hence build a lambda - numArgTys, - (fun () -> - let vs, args = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip - let constrApp = mkConstrApp mItem args - let lam = mkMultiLambda mItem vs (constrApp, tyOfExpr g constrApp) - lam) - UnionCaseOrExnCheck env numArgTys numArgs mItem - let expr = mkExpr() - let exprTy = tyOfExpr g expr - PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprNoFlex cenv expr) exprTy ExprAtomicFlag.Atomic delayed - - | Item.Types(nm, (ty :: _)) -> - - match delayed with - | ((DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs)) :: (DelayedDotLookup (longId, mLongId)) :: otherDelayed) -> - - // If Item.Types is returned then the ty will be of the form TType_app(tcref, genericTyargs) where tyargs - // is a fresh instantiation for tcref. TcNestedTypeApplication will chop off precisely #genericTyargs args - // and replace them by 'tyargs' - let ty, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs ty tyargs - - // Report information about the whole expression including type arguments to VS - let item = Item.Types(nm, [ty]) - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - TcItemThen cenv overallTy env tpenv (ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver (unionRanges mExprAndTypeArgs mLongId) ad env.eNameResEnv ty longId IgnoreOverrides true) otherDelayed - - | ((DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs)) :: _delayed') -> - // A case where we have an incomplete name e.g. 'Foo.' - we still want to report it to VS! - let ty, _ = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs ty tyargs - let item = Item.Types(nm, [ty]) - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - // Same error as in the following case - error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) - - | _ -> - // In this case the type is not generic, and indeed we should never have returned Item.Types. - // That's because ResolveTypeNamesToCtors should have been set at the original - // call to ResolveLongIdentAsExprAndComputeRange - error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem)) - - | Item.MethodGroup (methodName, minfos, _) -> - // Static method calls Type.Foo(arg1, ..., argn) - let meths = List.map (fun minfo -> minfo, None) minfos - match delayed with - | (DelayedApp (atomicFlag, arg, mExprAndArg) :: otherDelayed) -> - TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndArg mItem methodName ad NeverMutates false meths afterResolution NormalValUse [arg] atomicFlag otherDelayed - - | (DelayedTypeApp(tys, mTypeArgs, mExprAndTypeArgs) :: otherDelayed) -> - -#if !NO_EXTENSIONTYPING - match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, Some (tys, mTypeArgs), mExprAndTypeArgs, mItem) with - | Some minfoAfterStaticArguments -> - - // Replace the resolution including the static parameters, plus the extra information about the original method info - let item = Item.MethodGroup(methodName, [minfoAfterStaticArguments], Some minfos.[0]) - CallNameResolutionSinkReplacing cenv.tcSink (mItem, env.NameEnv, item, item, [], ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - match otherDelayed with - | DelayedApp(atomicFlag, arg, mExprAndArg) :: otherDelayed -> - TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndArg mItem methodName ad NeverMutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse [arg] atomicFlag otherDelayed - | _ -> - TcMethodApplicationThen cenv env overallTy None tpenv None [] mExprAndTypeArgs mItem methodName ad NeverMutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse [] ExprAtomicFlag.Atomic otherDelayed - - | None -> -#endif - - let tyargs, tpenv = TcTypesOrMeasures None cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tys mTypeArgs - - // FUTURE: can we do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE? But note we haven't yet even checked if the - // number of type arguments is correct... - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - match otherDelayed with - | DelayedApp(atomicFlag, arg, mExprAndArg) :: otherDelayed -> - TcMethodApplicationThen cenv env overallTy None tpenv (Some tyargs) [] mExprAndArg mItem methodName ad NeverMutates false meths afterResolution NormalValUse [arg] atomicFlag otherDelayed - | _ -> - TcMethodApplicationThen cenv env overallTy None tpenv (Some tyargs) [] mExprAndTypeArgs mItem methodName ad NeverMutates false meths afterResolution NormalValUse [] ExprAtomicFlag.Atomic otherDelayed - - | _ -> -#if !NO_EXTENSIONTYPING - if not minfos.IsEmpty && minfos.[0].ProvidedStaticParameterInfo.IsSome then - error(Error(FSComp.SR.etMissingStaticArgumentsToMethod(), mItem)) -#endif - TcMethodApplicationThen cenv env overallTy None tpenv None [] mItem mItem methodName ad NeverMutates false meths afterResolution NormalValUse [] ExprAtomicFlag.Atomic delayed - - | Item.CtorGroup(nm, minfos) -> - let objTy = - match minfos with - | (minfo :: _) -> minfo.ApparentEnclosingType - | [] -> error(Error(FSComp.SR.tcTypeHasNoAccessibleConstructor(), mItem)) - match delayed with - | ((DelayedApp (_, arg, mExprAndArg)) :: otherDelayed) -> - - CallExprHasTypeSink cenv.tcSink (mExprAndArg, env.NameEnv, objTy, env.DisplayEnv, env.eAccessRights) - TcCtorCall true cenv env tpenv overallTy objTy (Some mItem) item false [arg] mExprAndArg otherDelayed (Some afterResolution) - - | ((DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs)) :: (DelayedApp (_, arg, mExprAndArg)) :: otherDelayed) -> - - let objTyAfterTyArgs, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs objTy tyargs - CallExprHasTypeSink cenv.tcSink (mExprAndArg, env.NameEnv, objTyAfterTyArgs, env.DisplayEnv, env.eAccessRights) - let itemAfterTyArgs, minfosAfterTyArgs = -#if !NO_EXTENSIONTYPING - // If the type is provided and took static arguments then the constructor will have changed - // to a provided constructor on the statically instantiated type. Re-resolve that constructor. - match objTyAfterTyArgs with - | AppTy g (tcref, _) when tcref.Deref.IsProvided -> - let newItem = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mExprAndArg ad objTyAfterTyArgs) - match newItem with - | Item.CtorGroup(_, newMinfos) -> newItem, newMinfos - | _ -> item, minfos - | _ -> -#endif - item, minfos - - minfosAfterTyArgs |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTyAfterTyArgs) - TcCtorCall true cenv env tpenv overallTy objTyAfterTyArgs (Some mExprAndTypeArgs) itemAfterTyArgs false [arg] mExprAndArg otherDelayed (Some afterResolution) - - | ((DelayedTypeApp(tyargs, _mTypeArgs, mExprAndTypeArgs)) :: otherDelayed) -> - - let objTy, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mExprAndTypeArgs objTy tyargs - - // A case where we have an incomplete name e.g. 'Foo.' - we still want to report it to VS! - let resolvedItem = Item.Types(nm, [objTy]) - CallNameResolutionSink cenv.tcSink (mExprAndTypeArgs, env.NameEnv, resolvedItem, resolvedItem, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - minfos |> List.iter (fun minfo -> UnifyTypes cenv env mExprAndTypeArgs minfo.ApparentEnclosingType objTy) - TcCtorCall true cenv env tpenv overallTy objTy (Some mExprAndTypeArgs) item false [] mExprAndTypeArgs otherDelayed (Some afterResolution) - - | _ -> - - TcCtorCall true cenv env tpenv overallTy objTy (Some mItem) item false [] mItem delayed (Some afterResolution) - - | Item.FakeInterfaceCtor _ -> - error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem)) - | Item.ImplicitOp(id, sln) -> - - let isPrefix = PrettyNaming.IsPrefixOperator id.idText - let isTernary = PrettyNaming.IsTernaryOperator id.idText - - let argData = - if isPrefix then - [ Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) ] - elif isTernary then - [ Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) - Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) - Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) ] - else - [ Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) - Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) ] - - let retTyData = Typar(mkSynId mItem (cenv.synArgNameGenerator.New()), HeadTypeStaticReq, true) - let argTypars = argData |> List.map (fun d -> NewTypar (TyparKind.Type, TyparRigidity.Flexible, d, false, TyparDynamicReq.Yes, [], false, false)) - let retTypar = NewTypar (TyparKind.Type, TyparRigidity.Flexible, retTyData, false, TyparDynamicReq.Yes, [], false, false) - let argTys = argTypars |> List.map mkTyparTy - let retTy = mkTyparTy retTypar - - let vs, ves = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip - - let memberFlags = StaticMemberFlags MemberKind.Member - let logicalCompiledName = ComputeLogicalName id memberFlags - let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, sln) - - let expr = Expr.Op (TOp.TraitCall traitInfo, [], ves, mItem) - let expr = mkLambdas mItem [] vs (expr, retTy) - - let rec isSimpleArgument e = - match e with - | SynExpr.New (_, _, synExpr, _) - | SynExpr.Paren (synExpr, _, _, _) - | SynExpr.Typed (synExpr, _, _) - | SynExpr.TypeApp (synExpr, _, _, _, _, _, _) - | SynExpr.TypeTest (synExpr, _, _) - | SynExpr.Upcast (synExpr, _, _) - | SynExpr.DotGet (synExpr, _, _, _) - | SynExpr.Downcast (synExpr, _, _) - | SynExpr.InferredUpcast (synExpr, _) - | SynExpr.InferredDowncast (synExpr, _) - | SynExpr.AddressOf (_, synExpr, _, _) - | SynExpr.Quote (_, _, synExpr, _, _) -> isSimpleArgument synExpr - - | SynExpr.Null _ - | SynExpr.Ident _ - | SynExpr.Const _ - | SynExpr.LongIdent _ -> true - - | SynExpr.Tuple (_, synExprs, _, _) - | SynExpr.ArrayOrList (_, synExprs, _) -> synExprs |> List.forall isSimpleArgument - | SynExpr.Record (_, copyOpt, fields, _) -> copyOpt |> Option.forall (fst >> isSimpleArgument) && fields |> List.forall (p23 >> Option.forall isSimpleArgument) - | SynExpr.App (_, _, synExpr, synExpr2, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 - | SynExpr.IfThenElse (synExpr, synExpr2, synExprOpt, _, _, _, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 && Option.forall isSimpleArgument synExprOpt - | SynExpr.DotIndexedGet (synExpr, _, _, _) -> isSimpleArgument synExpr - | SynExpr.ObjExpr _ - | SynExpr.AnonRecd _ - | SynExpr.While _ - | SynExpr.For _ - | SynExpr.ForEach _ - | SynExpr.ArrayOrListOfSeqExpr _ - | SynExpr.CompExpr _ - | SynExpr.Lambda _ - | SynExpr.MatchLambda _ - | SynExpr.Match _ - | SynExpr.Do _ - | SynExpr.Assert _ - | SynExpr.Fixed _ - | SynExpr.TryWith _ - | SynExpr.TryFinally _ - | SynExpr.Lazy _ - | SynExpr.Sequential _ - | SynExpr.SequentialOrImplicitYield _ - | SynExpr.LetOrUse _ - | SynExpr.DotSet _ - | SynExpr.DotIndexedSet _ - | SynExpr.LongIdentSet _ - | SynExpr.Set _ - | SynExpr.JoinIn _ - | SynExpr.NamedIndexedPropertySet _ - | SynExpr.DotNamedIndexedPropertySet _ - | SynExpr.LibraryOnlyILAssembly _ - | SynExpr.LibraryOnlyStaticOptimization _ - | SynExpr.LibraryOnlyUnionCaseFieldGet _ - | SynExpr.LibraryOnlyUnionCaseFieldSet _ - | SynExpr.ArbitraryAfterError (_, _) - | SynExpr.FromParseError (_, _) - | SynExpr.DiscardAfterMissingQualificationAfterDot (_, _) - | SynExpr.ImplicitZero _ - | SynExpr.YieldOrReturn _ - | SynExpr.YieldOrReturnFrom _ - | SynExpr.MatchBang _ - | SynExpr.LetOrUseBang _ - | SynExpr.DoBang _ - | SynExpr.TraitCall _ - -> false - - - // Propagate the known application structure into function types - Propagate cenv overallTy env tpenv (MakeApplicableExprNoFlex cenv expr) (tyOfExpr g expr) delayed - - // Take all simple arguments and process them before applying the constraint. - let delayed1, delayed2 = - let pred = (function (DelayedApp (_, arg, _)) -> isSimpleArgument arg | _ -> false) - List.takeWhile pred delayed, List.skipWhile pred delayed - let intermediateTy = if isNil delayed2 then overallTy else NewInferenceType () - - let resultExpr, tpenv = TcDelayed cenv intermediateTy env tpenv mItem (MakeApplicableExprNoFlex cenv expr) (tyOfExpr g expr) ExprAtomicFlag.NonAtomic delayed1 - - // Add the constraint after the application arguments have been checked to allow annotations to kick in on rigid type parameters - AddCxMethodConstraint env.DisplayEnv cenv.css mItem NoTrace traitInfo - - // Process all remaining arguments after the constraint is asserted - let resultExpr2, tpenv2 = TcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprNoFlex cenv resultExpr) intermediateTy ExprAtomicFlag.NonAtomic delayed2 - resultExpr2, tpenv2 - - - | Item.DelegateCtor ty -> - match delayed with - | ((DelayedApp (atomicFlag, arg, mItemAndArg)) :: otherDelayed) -> - TcNewDelegateThen cenv overallTy env tpenv mItem mItemAndArg ty arg atomicFlag otherDelayed - | ((DelayedTypeApp(tyargs, _mTypeArgs, mItemAndTypeArgs)) :: (DelayedApp (atomicFlag, arg, mItemAndArg)) :: otherDelayed) -> - let ty, tpenv = TcNestedTypeApplication cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv mItemAndTypeArgs ty tyargs - - // Report information about the whole expression including type arguments to VS - let item = Item.DelegateCtor ty - CallNameResolutionSink cenv.tcSink (mItemAndTypeArgs, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - TcNewDelegateThen cenv overallTy env tpenv mItem mItemAndArg ty arg atomicFlag otherDelayed - | _ -> - error(Error(FSComp.SR.tcInvalidUseOfDelegate(), mItem)) - - | Item.Value vref -> - - match delayed with - // Mutable value set: 'v <- e' - | DelayedSet(e2, mStmt) :: otherDelayed -> - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) - UnifyTypes cenv env mStmt overallTy g.unit_ty - vref.Deref.SetHasBeenReferenced() - CheckValAccessible mItem env.eAccessRights vref - CheckValAttributes g vref mItem |> CommitOperationResult - let vty = vref.Type - let vty2 = - if isByrefTy g vty then - destByrefTy g vty - else - if not vref.IsMutable then - errorR (ValNotMutable (env.DisplayEnv, vref, mStmt)) - vty - // Always allow subsumption on assignment to fields - let e2', tpenv = TcExprFlex cenv true false vty2 env tpenv e2 - let vexp = - if isInByrefTy g vty then - errorR(Error(FSComp.SR.writeToReadOnlyByref(), mStmt)) - mkAddrSet mStmt vref e2' - elif isByrefTy g vty then - mkAddrSet mStmt vref e2' - else - mkValSet mStmt vref e2' - - PropagateThenTcDelayed cenv overallTy env tpenv mStmt (MakeApplicableExprNoFlex cenv vexp) (tyOfExpr g vexp) ExprAtomicFlag.NonAtomic otherDelayed - - // Value instantiation: v ... - | (DelayedTypeApp(tys, _mTypeArgs, mExprAndTypeArgs) :: otherDelayed) -> - // Note: we know this is a NormalValUse or PossibleConstrainedCall because: - // - it isn't a CtorValUsedAsSuperInit - // - it isn't a CtorValUsedAsSelfInit - // - it isn't a VSlotDirectCall (uses of base values do not take type arguments - let checkTys tpenv kinds = TcTypesOrMeasures (Some kinds) cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tys mItem - let _, vexp, isSpecial, _, _, tpenv = TcVal true cenv env tpenv vref (Some (NormalValUse, checkTys)) (Some afterResolution) mItem - let vexpFlex = (if isSpecial then MakeApplicableExprNoFlex cenv vexp else MakeApplicableExprWithFlex cenv env vexp) - // We need to eventually record the type resolution for an expression, but this is done - // inside PropagateThenTcDelayed, so we don't have to explicitly call 'CallExprHasTypeSink' here - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndTypeArgs vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic otherDelayed - - // Value get - | _ -> - let _, vexp, isSpecial, _, _, tpenv = TcVal true cenv env tpenv vref None (Some afterResolution) mItem - let vexpFlex = (if isSpecial then MakeApplicableExprNoFlex cenv vexp else MakeApplicableExprWithFlex cenv env vexp) - PropagateThenTcDelayed cenv overallTy env tpenv mItem vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic delayed - - | Item.Property (nm, pinfos) -> - if isNil pinfos then error (InternalError ("Unexpected error: empty property list", mItem)) - // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. - // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed - let pinfo = List.head pinfos - let _, tyargsOpt, args, delayed, tpenv = - if pinfo.IsIndexer - then GetMemberApplicationArgs delayed cenv env tpenv - else ExprAtomicFlag.Atomic, None, [mkSynUnit mItem], delayed, tpenv - if not pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsNotStatic nm, mItem)) - match delayed with - | DelayedSet(e2, mStmt) :: otherDelayed -> - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) - // Static Property Set (possibly indexer) - UnifyTypes cenv env mStmt overallTy g.unit_ty - let meths = pinfos |> SettersOfPropInfos - if meths.IsEmpty then - let meths = pinfos |> GettersOfPropInfos - let isByrefMethReturnSetter = meths |> List.exists (function (_,Some pinfo) -> isByrefTy g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false) - if not isByrefMethReturnSetter then - errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) - // x.P <- ... byref setter - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterResolution NormalValUse args ExprAtomicFlag.Atomic delayed - else - let args = if pinfo.IsIndexer then args else [] - if isNil meths then - errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) - // Note: static calls never mutate a struct object argument - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mStmt mItem nm ad NeverMutates true meths afterResolution NormalValUse (args@[e2]) ExprAtomicFlag.NonAtomic otherDelayed - | _ -> - // Static Property Get (possibly indexer) - let meths = pinfos |> GettersOfPropInfos - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) - // Note: static calls never mutate a struct object argument - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterResolution NormalValUse args ExprAtomicFlag.Atomic delayed - - | Item.ILField finfo -> - - CheckILFieldInfoAccessible g cenv.amap mItem ad finfo - if not finfo.IsStatic then error (Error (FSComp.SR.tcFieldIsNotStatic(finfo.FieldName), mItem)) - CheckILFieldAttributes g finfo mItem - let fref = finfo.ILFieldRef - let exprty = finfo.FieldType(cenv.amap, mItem) - match delayed with - | DelayedSet(e2, mStmt) :: _delayed' -> - UnifyTypes cenv env mStmt overallTy g.unit_ty - // Always allow subsumption on assignment to fields - let e2', tpenv = TcExprFlex cenv true false exprty env tpenv e2 - let expr = BuildILStaticFieldSet mStmt finfo e2' - expr, tpenv - | _ -> - // Get static IL field - let expr = - match finfo.LiteralValue with - | Some lit -> - Expr.Const (TcFieldInit mItem lit, mItem, exprty) - | None -> - let isValueType = finfo.IsValueType - let valu = if isValueType then AsValue else AsObject - - // The empty instantiation on the fspec is OK, since we make the correct fspec in IlxGen.GenAsm - // This ensures we always get the type instantiation right when doing this from - // polymorphic code, after inlining etc. - let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) - - // Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr. - mkAsmExpr ([ mkNormalLdsfld fspec ] @ (if finfo.IsInitOnly then [ AI_nop ] else []), finfo.TypeInst, [], [exprty], mItem) - PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed - - | Item.RecdField rfinfo -> - // Get static F# field or literal - CheckRecdFieldInfoAccessible cenv.amap mItem ad rfinfo - if not rfinfo.IsStatic then error (Error (FSComp.SR.tcFieldIsNotStatic(rfinfo.Name), mItem)) - CheckRecdFieldInfoAttributes g rfinfo mItem |> CommitOperationResult - let fref = rfinfo.RecdFieldRef - let fieldTy = rfinfo.FieldType - match delayed with - | DelayedSet(e2, mStmt) :: otherDelayed -> - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) - - // Set static F# field - CheckRecdFieldMutation mItem env.DisplayEnv rfinfo - UnifyTypes cenv env mStmt overallTy g.unit_ty - let fieldTy = rfinfo.FieldType - // Always allow subsumption on assignment to fields - let e2', tpenv = TcExprFlex cenv true false fieldTy env tpenv e2 - let expr = mkStaticRecdFieldSet (rfinfo.RecdFieldRef, rfinfo.TypeInst, e2', mStmt) - expr, tpenv - | _ -> - let exprty = fieldTy - let expr = - match rfinfo.LiteralValue with - // Get literal F# field - | Some lit -> Expr.Const (lit, mItem, exprty) - // Get static F# field - | None -> mkStaticRecdFieldGet (fref, rfinfo.TypeInst, mItem) - PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed - - | Item.Event einfo -> - // Instance IL event (fake up event-as-value) - TcEventValueThen cenv overallTy env tpenv mItem mItem None einfo delayed - - | Item.CustomOperation (nm, usageTextOpt, _) -> - // 'delayed' is about to be dropped on the floor, first do rudimentary checking to get name resolutions in its body - RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed - match usageTextOpt() with - | None -> error(Error(FSComp.SR.tcCustomOperationNotUsedCorrectly nm, mItem)) - | Some usageText -> error(Error(FSComp.SR.tcCustomOperationNotUsedCorrectly2(nm, usageText), mItem)) - | _ -> error(Error(FSComp.SR.tcLookupMayNotBeUsedHere(), mItem)) - - -//------------------------------------------------------------------------- -// Typecheck "expr.A.B.C ... " constructs -//------------------------------------------------------------------------- - -and GetSynMemberApplicationArgs delayed tpenv = - match delayed with - | DelayedApp (atomicFlag, arg, _) :: otherDelayed -> - atomicFlag, None, [arg], otherDelayed, tpenv - | DelayedTypeApp(tyargs, mTypeArgs, _) :: DelayedApp (atomicFlag, arg, _mExprAndArg) :: otherDelayed -> - (atomicFlag, Some (tyargs, mTypeArgs), [arg], otherDelayed, tpenv) - | DelayedTypeApp(tyargs, mTypeArgs, _) :: otherDelayed -> - (ExprAtomicFlag.Atomic, Some (tyargs, mTypeArgs), [], otherDelayed, tpenv) - | otherDelayed -> - (ExprAtomicFlag.NonAtomic, None, [], otherDelayed, tpenv) - - -and TcMemberTyArgsOpt cenv env tpenv tyargsOpt = - match tyargsOpt with - | None -> None, tpenv - | Some (tyargs, mTypeArgs) -> - let tyargsChecked, tpenv = TcTypesOrMeasures None cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tyargs mTypeArgs - Some tyargsChecked, tpenv - -and GetMemberApplicationArgs delayed cenv env tpenv = - let atomicFlag, tyargsOpt, args, delayed, tpenv = GetSynMemberApplicationArgs delayed tpenv - let tyArgsOptChecked, tpenv = TcMemberTyArgsOpt cenv env tpenv tyargsOpt - atomicFlag, tyArgsOptChecked, args, delayed, tpenv - -and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId delayed mExprAndLongId = - let objArgs = [objExpr] - let ad = env.eAccessRights - - // 'base' calls use a different resolution strategy when finding methods. - let findFlag = - let baseCall = IsBaseCall objArgs - (if baseCall then PreferOverrides else IgnoreOverrides) - - // Canonicalize inference problem prior to '.' lookup on variable types - if isTyparTy cenv.g objExprTy then - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, env.DisplayEnv, mExprAndLongId) (freeInTypeLeftToRight cenv.g false objExprTy) - - let item, mItem, rest, afterResolution = ResolveExprDotLongIdentAndComputeRange cenv.tcSink cenv.nameResolver mExprAndLongId ad env.eNameResEnv objExprTy longId findFlag false - let mExprAndItem = unionRanges mObjExpr mItem - let delayed = delayRest rest mExprAndItem delayed - - match item with - | Item.MethodGroup (methodName, minfos, _) -> - let atomicFlag, tyargsOpt, args, delayed, tpenv = GetSynMemberApplicationArgs delayed tpenv - // We pass PossiblyMutates here because these may actually mutate a value type object - // To get better warnings we special case some of the few known mutate-a-struct method names - let mutates = (if methodName = "MoveNext" || methodName = "GetNextArg" then DefinitelyMutates else PossiblyMutates) - -#if !NO_EXTENSIONTYPING - match TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos, tyargsOpt, mExprAndItem, mItem) with - | Some minfoAfterStaticArguments -> - // Replace the resolution including the static parameters, plus the extra information about the original method info - let item = Item.MethodGroup(methodName, [minfoAfterStaticArguments], Some minfos.[0]) - CallNameResolutionSinkReplacing cenv.tcSink (mExprAndItem, env.NameEnv, item, item, [], ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - - TcMethodApplicationThen cenv env overallTy None tpenv None objArgs mExprAndItem mItem methodName ad mutates false [(minfoAfterStaticArguments, None)] afterResolution NormalValUse args atomicFlag delayed - | None -> - if not minfos.IsEmpty && minfos.[0].ProvidedStaticParameterInfo.IsSome then - error(Error(FSComp.SR.etMissingStaticArgumentsToMethod(), mItem)) -#endif - - let tyargsOpt, tpenv = TcMemberTyArgsOpt cenv env tpenv tyargsOpt - let meths = minfos |> List.map (fun minfo -> minfo, None) - - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem methodName ad mutates false meths afterResolution NormalValUse args atomicFlag delayed - - | Item.Property (nm, pinfos) -> - // Instance property - if isNil pinfos then error (InternalError ("Unexpected error: empty property list", mItem)) - // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. - // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed - let pinfo = List.head pinfos - let atomicFlag, tyargsOpt, args, delayed, tpenv = - if pinfo.IsIndexer - then GetMemberApplicationArgs delayed cenv env tpenv - else ExprAtomicFlag.Atomic, None, [mkSynUnit mItem], delayed, tpenv - if pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsStatic nm, mItem)) - - - match delayed with - | DelayedSet(e2, mStmt) :: otherDelayed -> - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) - // Instance property setter - UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty - let meths = SettersOfPropInfos pinfos - if meths.IsEmpty then - let meths = pinfos |> GettersOfPropInfos - let isByrefMethReturnSetter = meths |> List.exists (function (_,Some pinfo) -> isByrefTy cenv.g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false) - if not isByrefMethReturnSetter then - errorR (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) - // x.P <- ... byref setter - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed - else - let args = if pinfo.IsIndexer then args else [] - let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mStmt mItem nm ad mut true meths afterResolution NormalValUse (args @ [e2]) atomicFlag [] - | _ -> - // Instance property getter - let meths = GettersOfPropInfos pinfos - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable nm, mItem)) - TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed - - | Item.RecdField rfinfo -> - // Get or set instance F# field or literal - RecdFieldInstanceChecks cenv.g cenv.amap ad mItem rfinfo - let tgtTy = rfinfo.DeclaringType - let valu = isStructTy cenv.g tgtTy - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgtTy objExprTy - let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, mExprAndItem, objExprTy) - let fieldTy = rfinfo.FieldType - match delayed with - | DelayedSet(e2, mStmt) :: otherDelayed -> - // Mutable value set: 'v <- e' - if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mItem)) - CheckRecdFieldMutation mItem env.DisplayEnv rfinfo - UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty - // Always allow subsumption on assignment to fields - let e2', tpenv = TcExprFlex cenv true false fieldTy env tpenv e2 - BuildRecdFieldSet cenv.g mStmt objExpr rfinfo e2', tpenv - - | _ -> - - // Instance F# Record or Class field - let objExpr' = mkRecdFieldGet cenv.g (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, mExprAndItem) - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed - - | Item.AnonRecdField (anonInfo, tinst, n, _) -> - let tgty = TType_anon (anonInfo, tinst) - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgty objExprTy - let fieldTy = List.item n tinst - match delayed with - | DelayedSet _ :: _otherDelayed -> - error(Error(FSComp.SR.tcInvalidAssignment(),mItem)) - | _ -> - // Instance F# Anonymous Record - let objExpr' = mkAnonRecdFieldGet cenv.g (anonInfo,objExpr,tinst,n,mExprAndItem) - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed - - | Item.ILField finfo -> - // Get or set instance IL field - ILFieldInstanceChecks cenv.g cenv.amap ad mItem finfo - let exprty = finfo.FieldType(cenv.amap, mItem) - - match delayed with - // Set instance IL field - | DelayedSet(e2, mStmt) :: _delayed' -> - UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty - // Always allow subsumption on assignment to fields - let e2', tpenv = TcExprFlex cenv true false exprty env tpenv e2 - let expr = BuildILFieldSet cenv.g mStmt objExpr finfo e2' - expr, tpenv - | _ -> - let expr = BuildILFieldGet cenv.g cenv.amap mExprAndItem objExpr finfo - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env expr) exprty ExprAtomicFlag.Atomic delayed - - | Item.Event einfo -> - // Instance IL event (fake up event-as-value) - TcEventValueThen cenv overallTy env tpenv mItem mExprAndItem (Some(objExpr, objExprTy)) einfo delayed - - | (Item.FakeInterfaceCtor _ | Item.DelegateCtor _) -> error (Error (FSComp.SR.tcConstructorsCannotBeFirstClassValues(), mItem)) - | _ -> error (Error (FSComp.SR.tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields(), mItem)) - -and TcEventValueThen cenv overallTy env tpenv mItem mExprAndItem objDetails (einfo: EventInfo) delayed = - // Instance IL event (fake up event-as-value) - let nm = einfo.EventName - let ad = env.eAccessRights - match objDetails, einfo.IsStatic with - | Some _, true -> error (Error (FSComp.SR.tcEventIsStatic nm, mItem)) - | None, false -> error (Error (FSComp.SR.tcEventIsNotStatic nm, mItem)) - | _ -> () - - let delegateType = einfo.GetDelegateType(cenv.amap, mItem) - let (SigOfFunctionForDelegate(invokeMethInfo, compiledViewOfDelArgTys, _, _)) = GetSigOfFunctionForDelegate cenv.infoReader delegateType mItem ad - let objArgs = Option.toList (Option.map fst objDetails) - MethInfoChecks cenv.g cenv.amap true None objArgs env.eAccessRights mItem invokeMethInfo - - // This checks for and drops the 'object' sender - let argsTy = ArgsTypOfEventInfo cenv.infoReader mItem ad einfo - if not (slotSigHasVoidReturnTy (invokeMethInfo.GetSlotSig(cenv.amap, mItem))) then errorR (nonStandardEventError einfo.EventName mItem) - let delEventTy = mkIEventType cenv.g delegateType argsTy - - let bindObjArgs f = - match objDetails with - | None -> f [] - | Some (objExpr, objExprTy) -> mkCompGenLetIn mItem "eventTarget" objExprTy objExpr (fun (_, ve) -> f [ve]) - - // Bind the object target expression to make sure we only run its side effects once, and to make - // sure if it's a mutable reference then we dereference it - see FSharp 1.0 bug 942 - let expr = - bindObjArgs (fun objVars -> - // EventHelper ((fun d -> e.add_X(d)), (fun d -> e.remove_X(d)), (fun f -> new 'Delegate(f))) - mkCallCreateEvent cenv.g mItem delegateType argsTy - (let dv, de = mkCompGenLocal mItem "eventDelegate" delegateType - let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.AddMethod NormalValUse [] objVars [de] - mkLambda mItem dv (callExpr, cenv.g.unit_ty)) - (let dv, de = mkCompGenLocal mItem "eventDelegate" delegateType - let callExpr, _ = BuildPossiblyConditionalMethodCall cenv env PossiblyMutates mItem false einfo.RemoveMethod NormalValUse [] objVars [de] - mkLambda mItem dv (callExpr, cenv.g.unit_ty)) - (let fvty = (cenv.g.obj_ty --> (argsTy --> cenv.g.unit_ty)) - let fv, fe = mkCompGenLocal mItem "callback" fvty - let createExpr = BuildNewDelegateExpr (Some einfo, cenv.g, cenv.amap, delegateType, invokeMethInfo, compiledViewOfDelArgTys, fe, fvty, mItem) - mkLambda mItem fv (createExpr, delegateType))) - - let exprty = delEventTy - PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprNoFlex cenv expr) exprty ExprAtomicFlag.Atomic delayed - - -//------------------------------------------------------------------------- -// Method uses can calls -//------------------------------------------------------------------------- - -/// Typecheck method/member calls and uses of members as first-class values. -and TcMethodApplicationThen - cenv - env - overallTy // The type of the overall expression including "delayed". The method "application" may actually be a use of a member as - // a first-class function value, when this would be a function type. - objTyOpt // methodType - tpenv - callerTyArgs // The return type of the overall expression including "delayed" - objArgs // The 'obj' arguments in obj.M(...) and obj.M, if any - m // The range of the object argument or whole application. We immediately union this with the range of the arguments - mItem // The range of the item that resolved to the method name - methodName // string, name of the method - ad // accessibility rights of the caller - mut // what do we know/assume about whether this method will mutate or not? - isProp // is this a property call? Used for better error messages and passed to BuildMethodCall - meths // the set of methods we may be calling - afterResolution // do we need to notify sink after overload resolution - isSuperInit // is this a special invocation, e.g. a super-class constructor call. Passed through to BuildMethodCall - args // the _syntactic_ method arguments, not yet type checked. - atomicFlag // is the expression atomic or not? - delayed // further lookups and applications that follow this - = - - // Nb. args is always of List.length <= 1 except for indexed setters, when it is 2 - let mWholeExpr = (m, args) ||> List.fold (fun m arg -> unionRanges m arg.Range) - - // Work out if we know anything about the return type of the overall expression. If there are any delayed - // lookups then we don't know anything. - let exprTy = if isNil delayed then overallTy else NewInferenceType () - - // Call the helper below to do the real checking - let (expr, attributeAssignedNamedItems, delayed), tpenv = - TcMethodApplication false cenv env tpenv callerTyArgs objArgs mWholeExpr mItem methodName objTyOpt ad mut isProp meths afterResolution isSuperInit args exprTy delayed - - // Give errors if some things couldn't be assigned - if not (isNil attributeAssignedNamedItems) then - let (CallerNamedArg(id, _)) = List.head attributeAssignedNamedItems - errorR(Error(FSComp.SR.tcNamedArgumentDidNotMatch(id.idText), id.idRange)) - - - // Resolve the "delayed" lookups - let exprty = (tyOfExpr cenv.g expr) - - PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr (MakeApplicableExprNoFlex cenv expr) exprty atomicFlag delayed - -/// Infer initial type information at the callsite from the syntax of an argument, prior to overload resolution. -and GetNewInferenceTypeForMethodArg cenv env tpenv x = - match x with - | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a - | SynExpr.AddressOf (true, a, _, m) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewByRefKindInferenceType cenv.g m) - | SynExpr.Lambda (_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) - | SynExpr.Quote (_, raw, a, _, _) -> - if raw then mkRawQuotedExprTy cenv.g - else mkQuotedExprTy cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) - | _ -> NewInferenceType () - -/// Method calls, property lookups, attribute constructions etc. get checked through here -and TcMethodApplication - isCheckingAttributeCall - cenv - env - tpenv - tyargsOpt - objArgs - mMethExpr // range of the entire method expression - mItem - methodName - (objTyOpt: TType option) - ad - mut - isProp - calledMethsAndProps - afterResolution - isSuperInit - curriedCallerArgs - exprTy - delayed - = - - let denv = env.DisplayEnv - - let isSimpleFormalArg (isParamArrayArg, _isInArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfo: CallerInfo, _reflArgInfo: ReflectedArgInfo) = - not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfo = NoCallerInfo - - let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g) - - let calledMeths = calledMethsAndProps |> List.map fst - - // Uses of curried members are ALWAYS treated as if they are first class uses of members. - // Curried members may not be overloaded (checked at use-site for curried members brought into scope through extension members) - let curriedCallerArgs, exprTy, delayed = - match calledMeths with - | [calledMeth] when not isProp && calledMeth.NumArgs.Length > 1 -> - [], NewInferenceType (), [ for x in curriedCallerArgs -> DelayedApp(ExprAtomicFlag.NonAtomic, x, x.Range) ] @ delayed - | _ when not isProp && calledMeths |> List.exists (fun calledMeth -> calledMeth.NumArgs.Length > 1) -> - // This condition should only apply when multiple conflicting curried extension members are brought into scope - error(Error(FSComp.SR.tcOverloadsCannotHaveCurriedArguments(), mMethExpr)) - | _ -> - curriedCallerArgs, exprTy, delayed - - let candidateMethsAndProps = - match calledMethsAndProps |> List.filter (fun (meth, _prop) -> IsMethInfoAccessible cenv.amap mItem ad meth) with - | [] -> calledMethsAndProps - | accessibleMeths -> accessibleMeths - - let candidates = candidateMethsAndProps |> List.map fst - - - // Split the syntactic arguments (if any) into named and unnamed parameters - // - // In one case (the second "single named item" rule) we delay the application of a - // argument until we've produced a lambda that detuples an input tuple - let curriedCallerArgsOpt, unnamedDelayedCallerArgExprOpt, exprTy = - match curriedCallerArgs with - | [] -> - None, None, exprTy - | _ -> - let unnamedCurriedCallerArgs, namedCurriedCallerArgs = curriedCallerArgs |> List.map GetMethodArgs |> List.unzip - - // There is an mismatch when _uses_ of indexed property setters in the tc.fs code that calls this function. - // The arguments are passed as if they are curried with arity [numberOfIndexParameters;1], however in the TAST, indexed property setters - // are uncurried and have arity [numberOfIndexParameters+1]. - // - // Here we work around this mismatch by crunching all property argument lists to uncurried form. - // Ideally the problem needs to be solved at its root cause at the callsites to this function - let unnamedCurriedCallerArgs, namedCurriedCallerArgs = - if isProp then - [List.concat unnamedCurriedCallerArgs], [List.concat namedCurriedCallerArgs] - else - unnamedCurriedCallerArgs, namedCurriedCallerArgs - - let MakeUnnamedCallerArgInfo x = (x, GetNewInferenceTypeForMethodArg cenv env tpenv x, x.Range) - - // "single named item" rule. This is where we have a single accessible method - // member x.M(arg1) - // being used with - // x.M (x, y) - // Without this rule this requires - // x.M ((x, y)) - match candidates with - | [calledMeth] - when (namedCurriedCallerArgs |> List.forall isNil && - let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) - curriedCalledArgs.Length = 1 && - curriedCalledArgs.Head.Length = 1 && - curriedCalledArgs.Head.Head |> isSimpleFormalArg) -> - let unnamedCurriedCallerArgs = curriedCallerArgs |> List.map (MakeUnnamedCallerArgInfo >> List.singleton) - let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.map (fun _ -> []) - (Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy) - - // "single named item" rule. This is where we have a single accessible method - // member x.M(arg1, arg2) - // being used with - // x.M p - // We typecheck this as if it has been written "(fun (v1, v2) -> x.M(v1, v2)) p" - // Without this rule this requires - // x.M (fst p, snd p) - | [calledMeth] - when (namedCurriedCallerArgs |> List.forall isNil && - unnamedCurriedCallerArgs.Length = 1 && - unnamedCurriedCallerArgs.Head.Length = 1 && - let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) - curriedCalledArgs.Length = 1 && - curriedCalledArgs.Head.Length > 1 && - curriedCalledArgs.Head |> List.forall isSimpleFormalArg) -> - - // The call lambda has function type - let exprTy = mkFunTy (NewInferenceType ()) exprTy - - (None, Some unnamedCurriedCallerArgs.Head.Head, exprTy) - - | _ -> - let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared MakeUnnamedCallerArgInfo - let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (isOpt, nm, x) -> - let ty = GetNewInferenceTypeForMethodArg cenv env tpenv x - // #435263: compiler crash with .net optional parameters and F# optional syntax - // named optional arguments should always have option type - let ty = if isOpt then mkOptionTy denv.g ty else ty - nm, isOpt, x, ty, x.Range) - - (Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy) - - - let CalledMethHasSingleArgumentGroupOfThisLength n (calledMeth: MethInfo) = - let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem) - curriedMethodArgAttribs.Length = 1 && - curriedMethodArgAttribs.Head.Length = n - - let GenerateMatchingSimpleArgumentTypes (calledMeth: MethInfo) = - let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem) - curriedMethodArgAttribs - |> List.map (List.filter isSimpleFormalArg >> NewInferenceTypes) - - let UnifyMatchingSimpleArgumentTypes exprTy (calledMeth: MethInfo) = - let curriedArgTys = GenerateMatchingSimpleArgumentTypes calledMeth - let returnTy = - (exprTy, curriedArgTys) ||> List.fold (fun exprTy argTys -> - let domainTy, resultTy = UnifyFunctionType None cenv denv mMethExpr exprTy - UnifyTypes cenv env mMethExpr domainTy (mkRefTupledTy cenv.g argTys) - resultTy) - curriedArgTys, returnTy - - if isProp && Option.isNone curriedCallerArgsOpt then - error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(), mItem)) - - // STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments. - // Extract what we know about the caller arguments, either type-directed if - // no arguments are given or else based on the syntax of the arguments. - let uniquelyResolved, preArgumentTypeCheckingCalledMethGroup = - let dummyExpr = mkSynUnit mItem - - // Build the CallerArg values for the caller's arguments. - // Fake up some arguments if this is the use of a method as a first class function - let unnamedCurriedCallerArgs, namedCurriedCallerArgs, returnTy = - - match curriedCallerArgsOpt, candidates with - // "single named item" rule. This is where we have a single accessible method - // member x.M(arg1, ..., argN) - // being used in a first-class way, i.e. - // x.M - // Because there is only one accessible method info available based on the name of the item - // being accessed we know the number of arguments the first class use of this - // method will take. Optional and out args are _not_ included, which means they will be resolved - // to their default values (for optionals) and be part of the return tuple (for out args). - | None, [calledMeth] -> - let curriedArgTys, returnTy = UnifyMatchingSimpleArgumentTypes exprTy calledMeth - let unnamedCurriedCallerArgs = curriedArgTys |> List.mapSquared (fun ty -> CallerArg(ty, mMethExpr, false, dummyExpr)) - let namedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.map (fun _ -> []) - unnamedCurriedCallerArgs, namedCurriedCallerArgs, returnTy - - // "type directed" rule for first-class uses of ambiguous methods. - // By context we know a type for the input argument. If it's a tuple - // this gives us the a potential number of arguments expected. Indeed even if it's a variable - // type we assume the number of arguments is just "1". - | None, _ -> - - let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy - let argTys = if isUnitTy cenv.g domainTy then [] else tryDestRefTupleTy cenv.g domainTy - // Only apply this rule if a candidate method exists with this number of arguments - let argTys = - if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then - argTys - else - [domainTy] - let unnamedCurriedCallerArgs = [argTys |> List.map (fun ty -> CallerArg(ty, mMethExpr, false, dummyExpr)) ] - let namedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.map (fun _ -> []) - unnamedCurriedCallerArgs, namedCurriedCallerArgs, returnTy - - | Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), _ -> - let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared (fun (argExpr, argTy, mArg) -> CallerArg(argTy, mArg, false, argExpr)) - let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (id, isOpt, argExpr, argTy, mArg) -> CallerNamedArg(id, CallerArg(argTy, mArg, isOpt, argExpr))) - unnamedCurriedCallerArgs, namedCurriedCallerArgs, exprTy - - let callerArgCounts = (List.sumBy List.length unnamedCurriedCallerArgs, List.sumBy List.length namedCurriedCallerArgs) - - let callerArgs = List.zip unnamedCurriedCallerArgs namedCurriedCallerArgs - - let makeOneCalledMeth (minfo, pinfoOpt, usesParamArrayConversion) = - let minst = FreshenMethInfo mItem minfo - let callerTyArgs = - match tyargsOpt with - | Some tyargs -> minfo.AdjustUserTypeInstForFSharpStyleIndexedExtensionMembers tyargs - | None -> minst - CalledMeth(cenv.infoReader, Some(env.NameEnv), isCheckingAttributeCall, FreshenMethInfo, mMethExpr, ad, minfo, minst, callerTyArgs, pinfoOpt, callerObjArgTys, callerArgs, usesParamArrayConversion, true, objTyOpt) - - let preArgumentTypeCheckingCalledMethGroup = - [ for (minfo, pinfoOpt) in candidateMethsAndProps do - let meth = makeOneCalledMeth (minfo, pinfoOpt, true) - yield meth - if meth.UsesParamArrayConversion then - yield makeOneCalledMeth (minfo, pinfoOpt, false) ] - - let uniquelyResolved = - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext cenv.css mMethExpr denv - UnifyUniqueOverloading csenv callerArgCounts methodName ad preArgumentTypeCheckingCalledMethGroup returnTy - - uniquelyResolved, preArgumentTypeCheckingCalledMethGroup - - // STEP 2. Type check arguments - let unnamedCurriedCallerArgs, namedCurriedCallerArgs, lambdaVars, returnTy, tpenv = - - // STEP 2a. First extract what we know about the caller arguments, either type-directed if - // no arguments are given or else based on the syntax of the arguments. - match curriedCallerArgsOpt with - | None -> - let curriedArgTys, returnTy = - match candidates with - // "single named item" rule. This is where we have a single accessible method - // member x.M(arg1, ..., argN) - // being used in a first-class way, i.e. - // x.M - // Because there is only one accessible method info available based on the name of the item - // being accessed we know the number of arguments the first class use of this - // method will take. Optional and out args are _not_ included, which means they will be resolved - // to their default values (for optionals) and be part of the return tuple (for out args). - | [calledMeth] -> - UnifyMatchingSimpleArgumentTypes exprTy calledMeth - | _ -> - let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy - let argTys = if isUnitTy cenv.g domainTy then [] else tryDestRefTupleTy cenv.g domainTy - // Only apply this rule if a candidate method exists with this number of arguments - let argTys = - if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then - argTys - else - [domainTy] - [argTys], returnTy - - let lambdaVarsAndExprs = curriedArgTys |> List.mapiSquared (fun i j ty -> mkCompGenLocal mMethExpr ("arg"+string i+string j) ty) - let unnamedCurriedCallerArgs = lambdaVarsAndExprs |> List.mapSquared (fun (_, e) -> CallerArg(tyOfExpr cenv.g e, e.Range, false, e)) - let namedCurriedCallerArgs = lambdaVarsAndExprs |> List.map (fun _ -> []) - let lambdaVars = List.mapSquared fst lambdaVarsAndExprs - unnamedCurriedCallerArgs, namedCurriedCallerArgs, Some lambdaVars, returnTy, tpenv - - | Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs) -> - // This is the case where some explicit arguments have been given. - - let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared (fun (argExpr, argTy, mArg) -> CallerArg(argTy, mArg, false, argExpr)) - let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (id, isOpt, argExpr, argTy, mArg) -> CallerNamedArg(id, CallerArg(argTy, mArg, isOpt, argExpr))) - - // Collect the information for F# 3.1 lambda propagation rule, and apply the caller's object type to the method's object type if the rule is relevant. - let lambdaPropagationInfo = - if preArgumentTypeCheckingCalledMethGroup.Length > 1 then - [| for meth in preArgumentTypeCheckingCalledMethGroup do - match ExamineMethodForLambdaPropagation meth with - | Some (unnamedInfo, namedInfo) -> - let calledObjArgTys = meth.CalledObjArgTys mMethExpr - if (calledObjArgTys, callerObjArgTys) ||> Seq.forall2 (fun calledTy callerTy -> AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed denv cenv.css mMethExpr calledTy callerTy) then - yield (List.toArraySquared unnamedInfo, List.toArraySquared namedInfo) - | None -> () |] - else - [| |] - - // Now typecheck the argument expressions - let unnamedCurriedCallerArgs, (lambdaPropagationInfo, tpenv) = TcUnnamedMethodArgs cenv env lambdaPropagationInfo tpenv unnamedCurriedCallerArgs - let namedCurriedCallerArgs, (_, tpenv) = TcMethodNamedArgs cenv env lambdaPropagationInfo tpenv namedCurriedCallerArgs - unnamedCurriedCallerArgs, namedCurriedCallerArgs, None, exprTy, tpenv - - let preArgumentTypeCheckingCalledMethGroup = - preArgumentTypeCheckingCalledMethGroup |> List.map (fun cmeth -> (cmeth.Method, cmeth.CalledTyArgs, cmeth.AssociatedPropertyInfo, cmeth.UsesParamArrayConversion)) - - let uniquelyResolved = - match uniquelyResolved with - | ErrorResult _ -> - match afterResolution with - | AfterResolution.DoNothing -> () - | AfterResolution.RecordResolution(_, _, _, onFailure) -> onFailure() - | _ -> () - - uniquelyResolved |> CommitOperationResult - - // STEP 3. Resolve overloading - /// Select the called method that's the result of overload resolution - let finalCalledMeth = - - let callerArgs = List.zip unnamedCurriedCallerArgs namedCurriedCallerArgs - - let postArgumentTypeCheckingCalledMethGroup = - preArgumentTypeCheckingCalledMethGroup |> List.map (fun (minfo: MethInfo, minst, pinfoOpt, usesParamArrayConversion) -> - let callerTyArgs = - match tyargsOpt with - | Some tyargs -> minfo.AdjustUserTypeInstForFSharpStyleIndexedExtensionMembers tyargs - | None -> minst - CalledMeth(cenv.infoReader, Some(env.NameEnv), isCheckingAttributeCall, FreshenMethInfo, mMethExpr, ad, minfo, minst, callerTyArgs, pinfoOpt, callerObjArgTys, callerArgs, usesParamArrayConversion, true, objTyOpt)) - - let callerArgCounts = (unnamedCurriedCallerArgs.Length, namedCurriedCallerArgs.Length) - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext cenv.css mMethExpr denv - - // Commit unassociated constraints prior to member overload resolution where there is ambiguity - // about the possible target of the call. - if not uniquelyResolved then - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, mItem) - (//freeInTypeLeftToRight cenv.g false returnTy @ - (unnamedCurriedCallerArgs |> List.collectSquared (fun callerArg -> freeInTypeLeftToRight cenv.g false callerArg.Type))) - - let result, errors = - ResolveOverloading csenv NoTrace methodName 0 None callerArgCounts ad postArgumentTypeCheckingCalledMethGroup true (Some returnTy) - - match afterResolution, result with - | AfterResolution.DoNothing, _ -> () - - // Record the precise override resolution - | AfterResolution.RecordResolution(Some unrefinedItem, _, callSink, _), Some result - when result.Method.IsVirtual -> - - let overriding = - match unrefinedItem with - | Item.MethodGroup(_, overridenMeths, _) -> overridenMeths |> List.map (fun minfo -> minfo, None) - | Item.Property(_, pinfos) -> - if result.Method.LogicalName.StartsWithOrdinal("set_") then - SettersOfPropInfos pinfos - else - GettersOfPropInfos pinfos - | _ -> [] - - let overridingInfo = - overriding - |> List.tryFind (fun (minfo, _) -> minfo.IsVirtual && MethInfosEquivByNameAndSig EraseNone true cenv.g cenv.amap range0 result.Method minfo) - - match overridingInfo with - | Some (minfo, pinfoOpt) -> - let tps = minfo.FormalMethodTypars - let tyargs = result.CalledTyArgs - let tpinst = if tps.Length = tyargs.Length then mkTyparInst tps tyargs else [] - (minfo, pinfoOpt, tpinst) |> callSink - | None -> - (result.Method, result.AssociatedPropertyInfo, result.CalledTyparInst) |> callSink - - // Record the precise overload resolution and the type instantiation - | AfterResolution.RecordResolution(_, _, callSink, _), Some result -> - (result.Method, result.AssociatedPropertyInfo, result.CalledTyparInst) |> callSink - - | AfterResolution.RecordResolution(_, _, _, onFailure), None -> - onFailure() - - - // Raise the errors from the constraint solving - RaiseOperationResult errors - match result with - | None -> error(InternalError("at least one error should be returned by failed method overloading", mItem)) - | Some res -> res - - let finalCalledMethInfo = finalCalledMeth.Method - let finalCalledMethInst = finalCalledMeth.CalledTyArgs - let finalAssignedItemSetters = finalCalledMeth.AssignedItemSetters - let finalAttributeAssignedNamedItems = finalCalledMeth.AttributeAssignedNamedArgs - - // STEP 4. Check the attributes on the method and the corresponding event/property, if any - - finalCalledMeth.AssociatedPropertyInfo |> Option.iter (fun pinfo -> CheckPropInfoAttributes pinfo mItem |> CommitOperationResult) - - let isInstance = not (isNil objArgs) - MethInfoChecks cenv.g cenv.amap isInstance tyargsOpt objArgs ad mItem finalCalledMethInfo - - // Adhoc constraints on use of .NET methods - begin - // Uses of Object.GetHashCode and Object.Equals imply an equality constraint on the object argument - // - if (isInstance && - finalCalledMethInfo.IsInstance && - typeEquiv cenv.g finalCalledMethInfo.ApparentEnclosingType cenv.g.obj_ty && - (finalCalledMethInfo.LogicalName = "GetHashCode" || finalCalledMethInfo.LogicalName = "Equals")) then - - objArgs |> List.iter (fun expr -> ConstraintSolver.AddCxTypeMustSupportEquality env.DisplayEnv cenv.css mMethExpr NoTrace (tyOfExpr cenv.g expr)) - - // Uses of a Dictionary() constructor without an IEqualityComparer argument imply an equality constraint - // on the first type argument. - if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType && - finalCalledMethInfo.IsConstructor && - not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CalledTyArgs) - |> List.existsSquared (fun (ParamData(_, _, _, _, _, _, _, ty)) -> - HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_IEqualityComparer ty)) then - - match argsOfAppTy cenv.g finalCalledMethInfo.ApparentEnclosingType with - | [dty; _] -> ConstraintSolver.AddCxTypeMustSupportEquality env.DisplayEnv cenv.css mMethExpr NoTrace dty - | _ -> () - end - - if (finalCalledMeth.ArgSets |> List.existsi (fun i argSet -> argSet.UnnamedCalledArgs |> List.existsi (fun j ca -> ca.Position <> (i, j)))) then - errorR(Deprecated(FSComp.SR.tcUnnamedArgumentsDoNotFormPrefix(), mMethExpr)) - - /// STEP 5. Build the argument list. Adjust for optional arguments, byref arguments and coercions. - - let objArgPreBinder, objArgs, allArgsPreBinders, allArgs, allArgsCoerced, optArgPreBinder, paramArrayPreBinders, outArgExprs, outArgTmpBinds = - AdjustCallerArgExprs TcFieldInit env.eCallerMemberName cenv.g cenv.amap cenv.infoReader ad finalCalledMeth objArgs lambdaVars mItem mMethExpr - - // Record the resolution of the named argument for the Language Service - allArgs |> List.iter (fun assignedArg -> - match assignedArg.NamedArgIdOpt with - | None -> () - | Some id -> - let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method finalCalledMethInfo)) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad)) - - - /// STEP 6. Build the call expression, then adjust for byref-returns, out-parameters-as-tuples, post-hoc property assignments, methods-as-first-class-value, - /// - - let callExpr0, exprty = - BuildPossiblyConditionalMethodCall cenv env mut mMethExpr isProp finalCalledMethInfo isSuperInit finalCalledMethInst objArgs allArgsCoerced - - // Handle byref returns - let callExpr1 = - // byref-typed returns get implicitly dereferenced - let vty = tyOfExpr cenv.g callExpr0 - if isByrefTy cenv.g vty then - mkDerefAddrExpr mMethExpr callExpr0 mMethExpr vty - else - callExpr0 - - // Bind "out" parameters as part of the result tuple - let callExpr2, exprty = - let expr = callExpr1 - if isNil outArgTmpBinds then expr, exprty - else - let outArgTys = outArgExprs |> List.map (tyOfExpr cenv.g) - let expr = - if isUnitTy cenv.g exprty then - mkCompGenSequential mMethExpr expr (mkRefTupled cenv.g mMethExpr outArgExprs outArgTys) - else - mkRefTupled cenv.g mMethExpr (expr :: outArgExprs) (exprty :: outArgTys) - let expr = mkLetsBind mMethExpr outArgTmpBinds expr - expr, tyOfExpr cenv.g expr - - // Handle post-hoc property assignments - let setterExprPrebinders, callExpr3 = - let expr = callExpr2 - if isCheckingAttributeCall then - [], expr - elif isNil finalAssignedItemSetters then - [], expr - else - // This holds the result of the call - let objv, objExpr = mkMutableCompGenLocal mMethExpr "returnVal" exprty // mutable in case it's a struct - - // Build the expression that mutates the properties on the result of the call - let setterExprPrebinders, propSetExpr = - (mkUnit cenv.g mMethExpr, finalAssignedItemSetters) ||> List.mapFold (fun acc assignedItemSetter -> - let argExprPrebinder, action, m = TcSetterArgExpr cenv env denv objExpr ad assignedItemSetter - argExprPrebinder, mkCompGenSequential m acc action) - - // now put them together - let expr = mkCompGenLet mMethExpr objv expr (mkCompGenSequential mMethExpr propSetExpr objExpr) - setterExprPrebinders, expr - - // Build the lambda expression if any, if the method is used as a first-class value - let callExpr4 = - let expr = callExpr3 - match lambdaVars with - | None -> expr - | Some curriedLambdaVars -> - let mkLambda vs expr = - match vs with - | [] -> mkUnitDelayLambda cenv.g mMethExpr expr - | _ -> mkMultiLambda mMethExpr vs (expr, tyOfExpr cenv.g expr) - List.foldBack mkLambda curriedLambdaVars expr - - let callExpr5, tpenv = - let expr = callExpr4 - match unnamedDelayedCallerArgExprOpt with - | Some synArgExpr -> - match lambdaVars with - | Some [lambdaVars] -> - let argExpr, tpenv = TcExpr cenv (mkRefTupledVarsTy cenv.g lambdaVars) env tpenv synArgExpr - mkApps cenv.g ((expr, tyOfExpr cenv.g expr), [], [argExpr], mMethExpr), tpenv - | _ -> - error(InternalError("unreachable - expected some lambda vars for a tuple mismatch", mItem)) - | None -> - expr, tpenv - - // Apply the PreBinders, if any - let callExpr6 = - let expr = callExpr5 - let expr = (expr, setterExprPrebinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) - let expr = (expr, paramArrayPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) - let expr = (expr, allArgsPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr) - - let expr = optArgPreBinder expr - let expr = objArgPreBinder expr - expr - - (callExpr6, finalAttributeAssignedNamedItems, delayed), tpenv - -and TcSetterArgExpr cenv env denv objExpr ad (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) = - if isOptCallerArg then error(Error(FSComp.SR.tcInvalidOptionalAssignmentToPropertyOrField(), m)) - - let argExprPrebinder, action, defnItem = - match setter with - | AssignedPropSetter (pinfo, pminfo, pminst) -> - MethInfoChecks cenv.g cenv.amap true None [objExpr] ad m pminfo - let calledArgTy = List.head (List.head (pminfo.GetParamTypes(cenv.amap, m, pminst))) - let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExprForCoercions cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr - let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) - let action = BuildPossiblyConditionalMethodCall cenv env mut m true pminfo NormalValUse pminst [objExpr] [argExpr] |> fst - argExprPrebinder, action, Item.Property (pinfo.PropertyName, [pinfo]) - - | AssignedILFieldSetter finfo -> - // Get or set instance IL field - ILFieldInstanceChecks cenv.g cenv.amap ad m finfo - let calledArgTy = finfo.FieldType (cenv.amap, m) - let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExprForCoercions cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr - let action = BuildILFieldSet cenv.g m objExpr finfo argExpr - argExprPrebinder, action, Item.ILField finfo - - | AssignedRecdFieldSetter rfinfo -> - RecdFieldInstanceChecks cenv.g cenv.amap ad m rfinfo - let calledArgTy = rfinfo.FieldType - CheckRecdFieldMutation m denv rfinfo - let argExprPrebinder, argExpr = MethodCalls.AdjustCallerArgExprForCoercions cenv.g cenv.amap cenv.infoReader ad false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr - let action = BuildRecdFieldSet cenv.g m objExpr rfinfo argExpr - argExprPrebinder, action, Item.RecdField rfinfo - - // Record the resolution for the Language Service - let item = Item.SetterArg (id, defnItem) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) - - argExprPrebinder, action, m - -and TcUnnamedMethodArgs cenv env lambdaPropagationInfo tpenv args = - List.mapiFoldSquared (TcUnnamedMethodArg cenv env) (lambdaPropagationInfo, tpenv) args - -and TcUnnamedMethodArg cenv env (lambdaPropagationInfo, tpenv) (i, j, CallerArg(argTy, mArg, isOpt, argExpr)) = - // Try to find the lambda propagation info for the corresponding unnamed argument at this position - let lambdaPropagationInfoForArg = - [| for (unnamedInfo, _) in lambdaPropagationInfo -> - if i < unnamedInfo.Length && j < unnamedInfo.[i].Length then unnamedInfo.[i].[j] else NoInfo |] - TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, CallerArg(argTy, mArg, isOpt, argExpr)) - -and TcMethodNamedArgs cenv env lambdaPropagationInfo tpenv args = - List.mapFoldSquared (TcMethodNamedArg cenv env) (lambdaPropagationInfo, tpenv) args - -and TcMethodNamedArg cenv env (lambdaPropagationInfo, tpenv) (CallerNamedArg(id, arg)) = - // Try to find the lambda propagation info for the corresponding named argument - let lambdaPropagationInfoForArg = - [| for (_, namedInfo) in lambdaPropagationInfo -> - namedInfo |> Array.tryPick (fun namedInfoForArgSet -> - namedInfoForArgSet |> Array.tryPick (fun (nm, info) -> - if nm.idText = id.idText then Some info else None)) |] - |> Array.map (fun x -> defaultArg x NoInfo) - - let arg', (lambdaPropagationInfo, tpenv) = TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, arg) - CallerNamedArg(id, arg'), (lambdaPropagationInfo, tpenv) - -and TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfoForArg, CallerArg(argTy, mArg, isOpt, argExpr)) = - - // Apply the F# 3.1 rule for extracting information for lambdas - // - // Before we check the argument, check to see if we can propagate info from a called lambda expression into the arguments of a received lambda - if lambdaPropagationInfoForArg.Length > 0 then - let allOverloadsAreNotCalledArgMatchesForThisArg = - lambdaPropagationInfoForArg - |> Array.forall (function ArgDoesNotMatch | CallerLambdaHasArgTypes _ | NoInfo -> true | CalledArgMatchesType _ -> false) - - if allOverloadsAreNotCalledArgMatchesForThisArg then - let overloadsWhichAreFuncAtThisPosition = lambdaPropagationInfoForArg |> Array.choose (function CallerLambdaHasArgTypes r -> Some (List.toArray r) | _ -> None) - if overloadsWhichAreFuncAtThisPosition.Length > 0 then - let minFuncArity = overloadsWhichAreFuncAtThisPosition |> Array.minBy Array.length |> Array.length - let prefixOfLambdaArgsForEachOverload = overloadsWhichAreFuncAtThisPosition |> Array.map (Array.take minFuncArity) - - if prefixOfLambdaArgsForEachOverload.Length > 0 then - let numLambdaVars = prefixOfLambdaArgsForEachOverload.[0].Length - // Fold across the lambda var positions checking if all method overloads imply the same argument type for a lambda variable. - // If so, force the caller to have a function type that looks like the calledLambdaArgTy. - // The loop variable callerLambdaTyOpt becomes None if something failed. - let rec loop callerLambdaTy lambdaVarNum = - if lambdaVarNum < numLambdaVars then - let calledLambdaArgTy = prefixOfLambdaArgsForEachOverload.[0].[lambdaVarNum] - let allRowsGiveSameArgumentType = - prefixOfLambdaArgsForEachOverload - |> Array.forall (fun row -> typeEquiv cenv.g calledLambdaArgTy row.[lambdaVarNum]) - - if allRowsGiveSameArgumentType then - // Force the caller to be a function type. - match UnifyFunctionTypeUndoIfFailed cenv env.DisplayEnv mArg callerLambdaTy with - | ValueSome (callerLambdaDomainTy, callerLambdaRangeTy) -> - if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css mArg calledLambdaArgTy callerLambdaDomainTy then - loop callerLambdaRangeTy (lambdaVarNum + 1) - | _ -> () - loop argTy 0 - - let e', tpenv = TcExpr cenv argTy env tpenv argExpr - - // After we have checked, propagate the info from argument into the overloads that receive it. - // - // Filter out methods where an argument doesn't match. This just filters them from lambda propagation but not from - // later method overload resolution. - let lambdaPropagationInfo = - [| for (info, argInfo) in Array.zip lambdaPropagationInfo lambdaPropagationInfoForArg do - match argInfo with - | ArgDoesNotMatch _ -> () - | NoInfo | CallerLambdaHasArgTypes _ -> - yield info - | CalledArgMatchesType adjustedCalledTy -> - if AddCxTypeMustSubsumeTypeMatchingOnlyUndoIfFailed env.DisplayEnv cenv.css mArg adjustedCalledTy argTy then - yield info |] - - CallerArg(argTy, mArg, isOpt, e'), (lambdaPropagationInfo, tpenv) - -/// Typecheck "new Delegate(fun x y z -> ...)" constructs -and TcNewDelegateThen cenv overallTy env tpenv mDelTy mExprAndArg delegateTy arg atomicFlag delayed = - let ad = env.eAccessRights - UnifyTypes cenv env mExprAndArg overallTy delegateTy - let (SigOfFunctionForDelegate(invokeMethInfo, delArgTys, _, fty)) = GetSigOfFunctionForDelegate cenv.infoReader delegateTy mDelTy ad - // We pass isInstance = true here because we're checking the rights to access the "Invoke" method - MethInfoChecks cenv.g cenv.amap true None [] env.eAccessRights mExprAndArg invokeMethInfo - let args = GetMethodArgs arg - match args with - | [farg], [] -> - let m = arg.Range - let callerArg, (_, tpenv) = TcMethodArg cenv env (Array.empty, tpenv) (Array.empty, CallerArg(fty, m, false, farg)) - let expr = BuildNewDelegateExpr (None, cenv.g, cenv.amap, delegateTy, invokeMethInfo, delArgTys, callerArg.Expr, fty, m) - PropagateThenTcDelayed cenv overallTy env tpenv m (MakeApplicableExprNoFlex cenv expr) delegateTy atomicFlag delayed - | _ -> - error(Error(FSComp.SR.tcDelegateConstructorMustBePassed(), mExprAndArg)) - - -and bindLetRec (binds: Bindings) m e = - if isNil binds then - e - else - Expr.LetRec (binds, e, m, NewFreeVarsCache()) - -/// Check for duplicate bindings in simple recursive patterns -and CheckRecursiveBindingIds binds = - let hashOfBinds = new HashSet() - - for (SynBinding.Binding(_, _, _, _, _, _, _, b, _, _, m, _)) in binds do - let nm = - match b with - | SynPat.Named(_, id, _, _, _) -> id.idText - | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) -> id.idText - | _ -> "" - if nm <> "" && not (hashOfBinds.Add nm) then - error(Duplicate("value", nm, m)) - -/// Process a sequence of sequentials mixed with iterated lets "let ... in let ... in ..." in a tail recursive way -/// This avoids stack overflow on really large "let" and "letrec" lists -and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont = - match expr with - | SynExpr.Sequential (sp, true, e1, e2, m) when not isCompExpr -> - let e1', _ = TcStmtThatCantBeCtorBody cenv env tpenv e1 - // tailcall - let env = ShrinkContext env m e2.Range - // tailcall - TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr e2 (fun (e2', tpenv) -> - cont (Expr.Sequential (e1', e2', NormalSeq, sp, m), tpenv)) - - | SynExpr.LetOrUse (isRec, isUse, binds, body, m) when not (isUse && isCompExpr) -> - if isRec then - // TcLinearExprs processes at most one recursive binding, this is not tailcalling - CheckRecursiveBindingIds binds - let binds = List.map (fun x -> RecDefnBindingInfo(ExprContainerInfo, NoNewSlots, ExpressionBinding, x)) binds - if isUse then errorR(Error(FSComp.SR.tcBindingCannotBeUseAndRec(), m)) - let binds, envinner, tpenv = TcLetrec ErrorOnOverrides cenv env tpenv (binds, m, m) - let bodyExpr, tpenv = bodyChecker overallTy envinner tpenv body - let bodyExpr = bindLetRec binds m bodyExpr - cont (bodyExpr, tpenv) - else - // TcLinearExprs processes multiple 'let' bindings in a tail recursive way - let mkf, envinner, tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds, m, body.Range) - let envinner = ShrinkContext envinner m body.Range - // tailcall - TcLinearExprs bodyChecker cenv envinner overallTy tpenv isCompExpr body (fun (x, tpenv) -> - cont (fst (mkf (x, overallTy)), tpenv)) - - | SynExpr.IfThenElse (synBoolExpr, synThenExpr, synElseExprOpt, spIfToThen, isRecovery, mIfToThen, m) when not isCompExpr -> - let boolExpr, tpenv = TcExprThatCantBeCtorBody cenv cenv.g.bool_ty env tpenv synBoolExpr - let thenExpr, tpenv = - let env = - match env.eContextInfo with - | ContextInfo.ElseBranchResult _ -> { env with eContextInfo = ContextInfo.ElseBranchResult synThenExpr.Range } - | _ -> - match synElseExprOpt with - | None -> { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range } - | _ -> { env with eContextInfo = ContextInfo.IfExpression synThenExpr.Range } - - if not isRecovery && Option.isNone synElseExprOpt then - UnifyTypes cenv env m cenv.g.unit_ty overallTy - - TcExprThatCanBeCtorBody cenv overallTy env tpenv synThenExpr - - match synElseExprOpt with - | None -> - let elseExpr = mkUnit cenv.g mIfToThen - let spElse = SuppressSequencePointAtTarget // the fake 'unit' value gets exactly the same range as spIfToThen - let overallExpr = primMkCond spIfToThen SequencePointAtTarget spElse m overallTy boolExpr thenExpr elseExpr - cont (overallExpr, tpenv) - - | Some synElseExpr -> - let env = { env with eContextInfo = ContextInfo.ElseBranchResult synElseExpr.Range } - // tailcall - TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr synElseExpr (fun (elseExpr, tpenv) -> - let resExpr = primMkCond spIfToThen SequencePointAtTarget SequencePointAtTarget m overallTy boolExpr thenExpr elseExpr - cont (resExpr, tpenv)) - - | _ -> - cont (bodyChecker overallTy env tpenv expr) - -/// Typecheck and compile pattern-matching constructs -and TcAndPatternCompileMatchClauses mExpr matchm actionOnFailure cenv inputExprOpt inputTy resultTy env tpenv synClauses = - let clauses, tpenv = TcMatchClauses cenv inputTy resultTy env tpenv synClauses - let matchVal, expr = CompilePatternForMatchClauses cenv env mExpr matchm true actionOnFailure inputExprOpt inputTy resultTy clauses - matchVal, expr, tpenv - -and TcMatchPattern cenv inputTy env tpenv (pat: SynPat, optWhenExpr) = - let m = pat.Range - let patf', (tpenv, names, _) = TcPat WarnOnUpperCase cenv env None (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, false) (tpenv, Map.empty, Set.empty) inputTy pat - let envinner, values, vspecMap = MakeAndPublishSimpleVals cenv env m names false - let optWhenExpr', tpenv = - match optWhenExpr with - | Some whenExpr -> - let guardEnv = { envinner with eContextInfo = ContextInfo.PatternMatchGuard whenExpr.Range } - let whenExpr', tpenv = TcExpr cenv cenv.g.bool_ty guardEnv tpenv whenExpr - Some whenExpr', tpenv - | None -> None, tpenv - patf' (TcPatPhase2Input (values, true)), optWhenExpr', NameMap.range vspecMap, envinner, tpenv - -and TcMatchClauses cenv inputTy resultTy env tpenv clauses = - let mutable first = true - let isFirst() = if first then first <- false; true else false - List.mapFold (fun clause -> TcMatchClause cenv inputTy resultTy env (isFirst()) clause) tpenv clauses - -and TcMatchClause cenv inputTy resultTy env isFirst tpenv (Clause(pat, optWhenExpr, e, patm, spTgt)) = - let pat', optWhenExpr', vspecs, envinner, tpenv = TcMatchPattern cenv inputTy env tpenv (pat, optWhenExpr) - let resultEnv = if isFirst then envinner else { envinner with eContextInfo = ContextInfo.FollowingPatternMatchClause e.Range } - let e', tpenv = TcExprThatCanBeCtorBody cenv resultTy resultEnv tpenv e - TClause(pat', optWhenExpr', TTarget(vspecs, e', spTgt), patm), tpenv - -and TcStaticOptimizationConstraint cenv env tpenv c = - match c with - | WhenTyparTyconEqualsTycon(tp, ty, m) -> - if not cenv.g.compilingFslib then - errorR(Error(FSComp.SR.tcStaticOptimizationConditionalsOnlyForFSharpLibrary(), m)) - let ty', tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv ty - let tp', tpenv = TcTypar cenv env NewTyparsOK tpenv tp - TTyconEqualsTycon(mkTyparTy tp', ty'), tpenv - | WhenTyparIsStruct(tp, m) -> - if not cenv.g.compilingFslib then - errorR(Error(FSComp.SR.tcStaticOptimizationConditionalsOnlyForFSharpLibrary(), m)) - let tp', tpenv = TcTypar cenv env NewTyparsOK tpenv tp - TTyconIsStruct(mkTyparTy tp'), tpenv - -/// Emit a conv.i instruction -and mkConvToNativeInt (g: TcGlobals) e m = Expr.Op (TOp.ILAsm ([ AI_conv ILBasicType.DT_I], [ g.nativeint_ty ]), [], [e], m) - -/// Fix up the r.h.s. of a 'use x = fixed expr' -and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBinding) = - warning(PossibleUnverifiableCode mBinding) - match overallExprTy with - | ty when isByrefTy cenv.g ty -> - let okByRef = - match stripExpr fixedExpr with - | Expr.Op (op, tyargs, args, _) -> - match op, tyargs, args with - | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon - | TOp.ILAsm ([ I_ldflda fspec], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject - | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true - | TOp.RefAddrGet _, _, _ -> true - | _ -> false - | _ -> false - if not okByRef then - error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - - let elemTy = destByrefTy cenv.g overallExprTy - UnifyTypes cenv env mBinding (mkNativePtrTy cenv.g elemTy) overallPatTy - mkCompGenLetIn mBinding "pinnedByref" ty fixedExpr (fun (v, ve) -> - v.SetIsFixed() - mkConvToNativeInt cenv.g ve mBinding) - - | ty when isStringTy cenv.g ty -> - let charPtrTy = mkNativePtrTy cenv.g cenv.g.char_ty - UnifyTypes cenv env mBinding charPtrTy overallPatTy - // - // let ptr: nativeptr = - // let pinned s = str - // (nativeptr)s + get_OffsettoStringData() - - mkCompGenLetIn mBinding "pinnedString" cenv.g.string_ty fixedExpr (fun (v, ve) -> - v.SetIsFixed() - let addrOffset = BuildOffsetToStringData cenv env mBinding - let stringAsNativeInt = mkConvToNativeInt cenv.g ve mBinding - let plusOffset = Expr.Op (TOp.ILAsm ([ AI_add ], [ cenv.g.nativeint_ty ]), [], [stringAsNativeInt; addrOffset], mBinding) - // check for non-null - mkNullTest cenv.g mBinding ve plusOffset ve) - - | ty when isArray1DTy cenv.g ty -> - let elemTy = destArrayTy cenv.g overallExprTy - let elemPtrTy = mkNativePtrTy cenv.g elemTy - UnifyTypes cenv env mBinding elemPtrTy overallPatTy - - // let ptr: nativeptr = - // let tmpArray: elem[] = arr - // if nonNull tmpArray then - // if tmpArray.Length <> 0 then - // let pinned tmpArrayByref: byref = &arr.[0] - // (nativeint) tmpArrayByref - // else - // (nativeint) 0 - // else - // (nativeint) 0 - // - mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_, ve) -> - // This is &arr.[0] - let elemZeroAddress = mkArrayElemAddress cenv.g (false, ILReadonly.NormalAddress, false, ILArrayShape.SingleDimensional, elemTy, [ve; mkInt32 cenv.g mBinding 0], mBinding) - // check for non-null and non-empty - let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding - // This is arr.Length - let arrayLengthExpr = mkCallArrayLength cenv.g mBinding elemTy ve - mkNullTest cenv.g mBinding ve - (mkNullTest cenv.g mBinding arrayLengthExpr - (mkCompGenLetIn mBinding "pinnedByref" (mkByrefTy cenv.g elemTy) elemZeroAddress (fun (v, ve) -> - v.SetIsFixed() - (mkConvToNativeInt cenv.g ve mBinding))) - zero) - zero) - - | _ -> error(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - - -/// Binding checking code, for all bindings including let bindings, let-rec bindings, member bindings and object-expression bindings and -and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt safeInitInfo (enclosingDeclaredTypars, (ExplicitTyparInfo(_, declaredTypars, _) as flex)) bind = - let envinner = AddDeclaredTypars NoCheckForDuplicateTypars (enclosingDeclaredTypars@declaredTypars) env - - match bind with - - | NormalizedBinding(vis, bkind, isInline, isMutable, attrs, doc, _, valSynData, pat, NormalizedBindingRhs(spatsL, rtyOpt, rhsExpr), mBinding, spBind) -> - let (SynValData(memberFlagsOpt, valSynInfo, _)) = valSynData - - let callerName = - match declKind, bkind, pat with - | ExpressionBinding, _, _ -> envinner.eCallerMemberName - | _, _, SynPat.Named(_, name, _, _, _) -> - match memberFlagsOpt with - | Some memberFlags -> - match memberFlags.MemberKind with - | MemberKind.PropertyGet | MemberKind.PropertySet | MemberKind.PropertyGetSet -> Some(name.idText.Substring 4) - | MemberKind.ClassConstructor -> Some(".ctor") - | MemberKind.Constructor -> Some(".ctor") - | _ -> Some(name.idText) - | _ -> Some(name.idText) - | ClassLetBinding false, DoBinding, _ -> Some(".ctor") - | ClassLetBinding true, DoBinding, _ -> Some(".cctor") - | ModuleOrMemberBinding, StandaloneExpression, _ -> Some(".cctor") - | _, _, _ -> envinner.eCallerMemberName - - let envinner = {envinner with eCallerMemberName = callerName } - - let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt declKind - - let isFixed, rhsExpr, overallPatTy, overallExprTy = - match rhsExpr with - | SynExpr.Fixed (e, _) -> true, e, NewInferenceType(), overallTy - | e -> false, e, overallTy, overallTy - - // Check the attributes of the binding, parameters or return value - let TcAttrs tgt attrs = - let attrs = TcAttributes cenv envinner tgt attrs - if attrTgt = enum 0 && not (isNil attrs) then - errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(), mBinding)) - attrs - - let valAttribs = TcAttrs attrTgt attrs - let isVolatile = HasFSharpAttribute cenv.g cenv.g.attrib_VolatileFieldAttribute valAttribs - - let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable mBinding - - let argAttribs = - spatsL |> List.map (SynInfo.InferSynArgInfoFromSimplePats >> List.map (SynInfo.AttribsOfArgData >> TcAttrs AttributeTargets.Parameter)) - let retAttribs = - match rtyOpt with - | Some (SynBindingReturnInfo(_, _, Attributes retAttrs)) -> TcAttrs AttributeTargets.ReturnValue retAttrs - | None -> [] - - let argAndRetAttribs = ArgAndRetAttribs(argAttribs, retAttribs) - - if HasFSharpAttribute cenv.g cenv.g.attrib_DefaultValueAttribute valAttribs then - errorR(Error(FSComp.SR.tcDefaultValueAttributeRequiresVal(), mBinding)) - - let isThreadStatic = isThreadOrContextStatic cenv.g valAttribs - if isThreadStatic then errorR(DeprecatedThreadStaticBindingWarning mBinding) - - if isVolatile then - match declKind with - | ClassLetBinding(_) -> () - | _ -> errorR(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), mBinding)) - - if (not isMutable || isThreadStatic) then - errorR(Error(FSComp.SR.tcVolatileFieldsMustBeMutable(), mBinding)) - - if isFixed && (declKind <> ExpressionBinding || isInline || isMutable) then - errorR(Error(FSComp.SR.tcFixedNotAllowed(), mBinding)) - - if (not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false)) && - HasFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute valAttribs - then - errorR(Error(FSComp.SR.tcDllImportNotAllowed(), mBinding)) - - if Option.isNone memberFlagsOpt && HasFSharpAttribute cenv.g cenv.g.attrib_ConditionalAttribute valAttribs then - errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(), mBinding)) - - if HasFSharpAttribute cenv.g cenv.g.attrib_EntryPointAttribute valAttribs then - if Option.isSome memberFlagsOpt then - errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(), mBinding)) - else - UnifyTypes cenv env mBinding overallPatTy (mkArrayType cenv.g cenv.g.string_ty --> cenv.g.int_ty) - - if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(), mBinding)) - - if isMutable && not (isNil declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(), mBinding)) - - let flex = if isMutable then dontInferTypars else flex - - if isMutable && not (isNil spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(), mBinding)) - - let isInline = - if isInline && isNil spatsL && isNil declaredTypars then - errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(), mBinding)) - false - else - isInline - - let compgen = false - - // Use the syntactic arity if we're defining a function - let partialValReprInfo = TranslateTopValSynInfo mBinding (TcAttributes cenv env) valSynInfo - - // Check the pattern of the l.h.s. of the binding - let tcPatPhase2, (tpenv, nameToPrelimValSchemeMap, _) = - TcPat AllIdsOK cenv envinner (Some partialValReprInfo) (inlineFlag, flex, argAndRetAttribs, isMutable, vis, compgen) (tpenv, NameMap.empty, Set.empty) overallPatTy pat - - - // Add active pattern result names to the environment - let apinfoOpt = - match NameMap.range nameToPrelimValSchemeMap with - | [PrelimValScheme1(id, _, ty, _, _, _, _, _, _, _, _) ] -> - match ActivePatternInfoOfValName id.idText id.idRange with - | Some apinfo -> Some (apinfo, ty, id.idRange) - | None -> None - | _ -> None - - // Add active pattern result names to the environment - let envinner = - match apinfoOpt with - | Some (apinfo, ty, m) -> - if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then - error(Error(FSComp.SR.tcInvalidActivePatternName(), mBinding)) - - apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag, tagRange) -> - let item = Item.ActivePatternResult(apinfo, cenv.g.unit_ty, i, tagRange) - CallNameResolutionSink cenv.tcSink (tagRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights)) - - { envinner with eNameResEnv = AddActivePatternResultTagsToNameEnv apinfo envinner.eNameResEnv ty m } - | None -> - envinner - - // Now tc the r.h.s. - // If binding a ctor then set the ugly counter that permits us to write ctor expressions on the r.h.s. - let isCtor = (match memberFlagsOpt with Some memberFlags -> memberFlags.MemberKind = MemberKind.Constructor | _ -> false) - - // At each module binding, dive into the expression to check for syntax errors and suppress them if they show. - // Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas - let rhsExprChecked, tpenv = - let atTopNonLambdaDefn = - DeclKind.IsModuleOrMemberOrExtensionBinding declKind && - (match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) && - synExprContainsError rhsExpr - - conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () -> - - if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv overallExprTy envinner tpenv rhsExpr - else TcExprThatCantBeCtorBody cenv overallExprTy envinner tpenv rhsExpr) - - if bkind = StandaloneExpression && not cenv.isScript then - UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore - - // Fix up the r.h.s. expression for 'fixed' - let rhsExprChecked = - if isFixed then TcAndBuildFixedExpr cenv env (overallPatTy, rhsExprChecked, overallExprTy, mBinding) - else rhsExprChecked - - // Assert the return type of an active pattern - match apinfoOpt with - | Some (apinfo, ty, _) -> - let activePatResTys = NewInferenceTypes apinfo.ActiveTags - let _, rty = stripFunTy cenv.g ty - UnifyTypes cenv env mBinding (apinfo.ResultType cenv.g rhsExpr.Range activePatResTys) rty - | None -> - () - - // Check other attributes - let hasLiteralAttr, konst = TcLiteral cenv overallExprTy env tpenv (valAttribs, rhsExpr) - - if hasLiteralAttr then - if isThreadStatic then - errorR(Error(FSComp.SR.tcIllegalAttributesForLiteral(), mBinding)) - if isMutable then - errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(), mBinding)) - if isInline then - errorR(Error(FSComp.SR.tcLiteralCannotBeInline(), mBinding)) - if not (isNil declaredTypars) then - errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(), mBinding)) - - CheckedBindingInfo(inlineFlag, valAttribs, doc, tcPatPhase2, flex, nameToPrelimValSchemeMap, rhsExprChecked, argAndRetAttribs, overallPatTy, mBinding, spBind, compgen, konst, isFixed), tpenv - -and TcLiteral cenv overallTy env tpenv (attrs, synLiteralValExpr) = - let hasLiteralAttr = HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs - if hasLiteralAttr then - let literalValExpr, _ = TcExpr cenv overallTy env tpenv synLiteralValExpr - match EvalLiteralExprOrAttribArg cenv.g literalValExpr with - | Expr.Const (c, _, ty) -> - if c = Const.Zero && isStructTy cenv.g ty then - warning(Error(FSComp.SR.tcIllegalStructTypeForConstantExpression(), synLiteralValExpr.Range)) - false, None - else - true, Some c - | _ -> - errorR(Error(FSComp.SR.tcInvalidConstantExpression(), synLiteralValExpr.Range)) - true, Some Const.Unit - - else hasLiteralAttr, None - -and TcBindingTyparDecls alwaysRigid cenv env tpenv (SynValTyparDecls(synTypars, infer, synTyparConstraints)) = - let declaredTypars = TcTyparDecls cenv env synTypars - let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTypars env - let tpenv = TcTyparConstraints cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv synTyparConstraints - - let rigidCopyOfDeclaredTypars = - if alwaysRigid then - declaredTypars |> List.iter (fun tp -> SetTyparRigid cenv.g env.DisplayEnv tp.Range tp) - declaredTypars - else - let rigidCopyOfDeclaredTypars = copyTypars declaredTypars - // The type parameters used to check rigidity after inference are marked rigid straight away - rigidCopyOfDeclaredTypars |> List.iter (fun tp -> SetTyparRigid cenv.g env.DisplayEnv tp.Range tp) - // The type parameters using during inference will be marked rigid after inference - declaredTypars |> List.iter (fun tp -> tp.SetRigidity TyparRigidity.WillBeRigid) - rigidCopyOfDeclaredTypars - - ExplicitTyparInfo(rigidCopyOfDeclaredTypars, declaredTypars, infer), tpenv - -and TcNonrecBindingTyparDecls cenv env tpenv bind = - let (NormalizedBinding(_, _, _, _, _, _, synTyparDecls, _, _, _, _, _)) = bind - TcBindingTyparDecls true cenv env tpenv synTyparDecls - -and TcNonRecursiveBinding declKind cenv env tpenv ty b = - let b = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env b - let flex, tpenv = TcNonrecBindingTyparDecls cenv env tpenv b - TcNormalizedBinding declKind cenv env tpenv ty None NoSafeInitInfo ([], flex) b - -//------------------------------------------------------------------------- -// TcAttribute* -//------------------------------------------------------------------------ - -and TcAttribute canFail cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) = - let (LongIdentWithDots(tycon, _)) = synAttr.TypeName - let arg = synAttr.ArgExpr - let targetIndicator = synAttr.Target - let isAppliedToGetterOrSetter = synAttr.AppliesToGetterAndSetter - let mAttr = synAttr.Range - let (typath, tyid) = List.frontAndBack tycon - let tpenv = emptyUnscopedTyparEnv - - // if we're checking an attribute that was applied directly to a getter or a setter, then - // what we're really checking against is a method, not a property - let attrTgt = if isAppliedToGetterOrSetter then ((attrTgt ^^^ AttributeTargets.Property) ||| AttributeTargets.Method) else attrTgt - let ty, tpenv = - let try1 n = - let tyid = mkSynId tyid.idRange n - let tycon = (typath @ [tyid]) - let ad = env.eAccessRights - match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad tycon TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No with - | Exception err -> raze err - | _ -> success(TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInAttribute env tpenv (SynType.App(SynType.LongIdent(LongIdentWithDots(tycon, [])), None, [], [], None, false, mAttr)) ) - ForceRaise ((try1 (tyid.idText + "Attribute")) |> ResultOrException.otherwise (fun () -> (try1 tyid.idText))) - - let ad = env.eAccessRights - - if not (IsTypeAccessible cenv.g cenv.amap mAttr ad ty) then errorR(Error(FSComp.SR.tcTypeIsInaccessible(), mAttr)) - - let tcref = tcrefOfAppTy cenv.g ty - - let conditionalCallDefineOpt = TryFindTyconRefStringAttribute cenv.g mAttr cenv.g.attrib_ConditionalAttribute tcref - - match conditionalCallDefineOpt, cenv.conditionalDefines with - | Some d, Some defines when not (List.contains d defines) -> - [], false - | _ -> - // REVIEW: take notice of inherited? - let validOn, _inherited = - let validOnDefault = 0x7fff - let inheritedDefault = true - if tcref.IsILTycon then - let tdef = tcref.ILTyconRawMetadata - let tref = cenv.g.attrib_AttributeUsageAttribute.TypeRef - - match TryDecodeILAttribute cenv.g tref tdef.CustomAttrs with - | Some ([ILAttribElem.Int32 validOn ], named) -> - let inherited = - match List.tryPick (function ("Inherited", _, _, ILAttribElem.Bool res) -> Some res | _ -> None) named with - | None -> inheritedDefault - | Some x -> x - (validOn, inherited) - | Some ([ILAttribElem.Int32 validOn; ILAttribElem.Bool _allowMultiple; ILAttribElem.Bool inherited ], _) -> - (validOn, inherited) - | _ -> - (validOnDefault, inheritedDefault) - else - match (TryFindFSharpAttribute cenv.g cenv.g.attrib_AttributeUsageAttribute tcref.Attribs) with - | Some(Attrib(_, _, [ AttribInt32Arg validOn ], _, _, _, _)) -> - (validOn, inheritedDefault) - | Some(Attrib(_, _, [ AttribInt32Arg validOn - AttribBoolArg(_allowMultiple) - AttribBoolArg inherited], _, _, _, _)) -> - (validOn, inherited) - | Some _ -> - warning(Error(FSComp.SR.tcUnexpectedConditionInImportedAssembly(), mAttr)) - (validOnDefault, inheritedDefault) - | _ -> - (validOnDefault, inheritedDefault) - let possibleTgts = enum validOn &&& attrTgt - let directedTgts = - match targetIndicator with - | Some id when id.idText = "assembly" -> AttributeTargets.Assembly - | Some id when id.idText = "module" -> AttributeTargets.Module - | Some id when id.idText = "return" -> AttributeTargets.ReturnValue - | Some id when id.idText = "field" -> AttributeTargets.Field - | Some id when id.idText = "property" -> AttributeTargets.Property - | Some id when id.idText = "method" -> AttributeTargets.Method - | Some id when id.idText = "param" -> AttributeTargets.Parameter - | Some id when id.idText = "type" -> AttributeTargets.TyconDecl - | Some id when id.idText = "constructor" -> AttributeTargets.Constructor - | Some id when id.idText = "event" -> AttributeTargets.Event - | Some id -> - errorR(Error(FSComp.SR.tcUnrecognizedAttributeTarget(), id.idRange)) - possibleTgts - | _ -> possibleTgts - let constrainedTgts = possibleTgts &&& directedTgts - if constrainedTgts = enum 0 then - if (directedTgts = AttributeTargets.Assembly || directedTgts = AttributeTargets.Module) then - error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElementUseDo(), mAttr)) - else - error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr)) - - match ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mAttr ad ty with - | Exception _ when canFail -> [ ], true - | res -> - let item = ForceRaise res - if not (ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap mAttr ty cenv.g.tcref_System_Attribute) then warning(Error(FSComp.SR.tcTypeDoesNotInheritAttribute(), mAttr)) - let attrib = - match item with - | Item.CtorGroup(methodName, minfos) -> - let meths = minfos |> List.map (fun minfo -> minfo, None) - let afterResolution = ForNewConstructors cenv.tcSink env tyid.idRange methodName minfos - let (expr, attributeAssignedNamedItems, _), _ = - TcMethodApplication true cenv env tpenv None [] mAttr mAttr methodName None ad PossiblyMutates false meths afterResolution NormalValUse [arg] (NewInferenceType ()) [] - - UnifyTypes cenv env mAttr ty (tyOfExpr cenv.g expr) - - let mkAttribExpr e = - AttribExpr(e, EvalLiteralExprOrAttribArg cenv.g e) - - let namedAttribArgMap = - attributeAssignedNamedItems |> List.map (fun (CallerNamedArg(id, CallerArg(argtyv, m, isOpt, callerArgExpr))) -> - if isOpt then error(Error(FSComp.SR.tcOptionalArgumentsCannotBeUsedInCustomAttribute(), m)) - let m = callerArgExpr.Range - let setterItem, _ = ResolveLongIdentInType cenv.tcSink cenv.nameResolver env.NameEnv LookupKind.Expr m ad id IgnoreOverrides TypeNameResolutionInfo.Default ty - let nm, isProp, argty = - match setterItem with - | Item.Property (_, [pinfo]) -> - if not pinfo.HasSetter then - errorR(Error(FSComp.SR.tcPropertyCannotBeSet0(), m)) - id.idText, true, pinfo.GetPropertyType(cenv.amap, m) - | Item.ILField finfo -> - CheckILFieldInfoAccessible cenv.g cenv.amap m ad finfo - CheckILFieldAttributes cenv.g finfo m - id.idText, false, finfo.FieldType(cenv.amap, m) - | Item.RecdField rfinfo when not rfinfo.IsStatic -> - CheckRecdFieldInfoAttributes cenv.g rfinfo m |> CommitOperationResult - CheckRecdFieldInfoAccessible cenv.amap m ad rfinfo - // This uses the F# backend name mangling of fields.... - let nm = ComputeFieldName rfinfo.Tycon rfinfo.RecdField - nm, false, rfinfo.FieldType - | _ -> - errorR(Error(FSComp.SR.tcPropertyOrFieldNotFoundInAttribute(), m)) - id.idText, false, cenv.g.unit_ty - let propNameItem = Item.SetterArg(id, setterItem) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, propNameItem, propNameItem, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) - - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace argty argtyv - - AttribNamedArg(nm, argty, isProp, mkAttribExpr callerArgExpr)) - - match expr with - | Expr.Op (TOp.ILCall (_, _, valu, _, _, _, _, ilMethRef, [], [], _rtys), [], args, m) -> - if valu then error (Error(FSComp.SR.tcCustomAttributeMustBeReferenceType(), m)) - if args.Length <> ilMethRef.ArgTypes.Length then error (Error(FSComp.SR.tcCustomAttributeArgumentMismatch(), m)) - let args = args |> List.map mkAttribExpr - Attrib(tcref, ILAttrib ilMethRef, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, m) - - | Expr.App ((InnerExprPat(ExprValWithPossibleTypeInst(vref, _, _, _))), _, _, args, _) -> - let args = args |> List.collect (function Expr.Const (Const.Unit, _, _) -> [] | expr -> tryDestRefTupleExpr expr) |> List.map mkAttribExpr - Attrib(tcref, FSAttrib vref, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, mAttr) - - | _ -> - error (Error(FSComp.SR.tcCustomAttributeMustInvokeConstructor(), mAttr)) - - | _ -> - error(Error(FSComp.SR.tcAttributeExpressionsMustBeConstructorCalls(), mAttr)) - - [ (constrainedTgts, attrib) ], false - -and TcAttributesWithPossibleTargets canFail cenv env attrTgt synAttribs = - - (false, synAttribs) ||> List.collectFold (fun didFail synAttrib -> - try - let attribsAndTargets, didFail2 = TcAttribute canFail cenv env attrTgt synAttrib - - // This is where we place any checks that completely exclude the use of some particular - // attributes from F#. - let attribs = List.map snd attribsAndTargets - if HasFSharpAttribute cenv.g cenv.g.attrib_TypeForwardedToAttribute attribs || - HasFSharpAttribute cenv.g cenv.g.attrib_CompilationArgumentCountsAttribute attribs || - HasFSharpAttribute cenv.g cenv.g.attrib_CompilationMappingAttribute attribs then - errorR(Error(FSComp.SR.tcUnsupportedAttribute(), synAttrib.Range)) - - attribsAndTargets, didFail || didFail2 - - with e -> - errorRecovery e synAttrib.Range - [], false) - -and TcAttributesMaybeFail canFail cenv env attrTgt synAttribs = - let attribsAndTargets, didFail = TcAttributesWithPossibleTargets canFail cenv env attrTgt synAttribs - attribsAndTargets |> List.map snd, didFail - -and TcAttributesCanFail cenv env attrTgt synAttribs = - let attrs, didFail = TcAttributesMaybeFail true cenv env attrTgt synAttribs - attrs, (fun () -> if didFail then TcAttributes cenv env attrTgt synAttribs else attrs) - -and TcAttributes cenv env attrTgt synAttribs = - TcAttributesMaybeFail false cenv env attrTgt synAttribs |> fst - -//------------------------------------------------------------------------- -// TcLetBinding -//------------------------------------------------------------------------ - -and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBindsRange, scopem) = - - // Typecheck all the bindings... - let checkedBinds, tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv (NewInferenceType ()) b) tpenv synBinds - let (ContainerInfo(altActualParent, _)) = containerInfo - - // Canonicalize constraints prior to generalization - let denv = env.DisplayEnv - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, synBindsRange) - (checkedBinds |> List.collect (fun tbinfo -> - let (CheckedBindingInfo(_, _, _, _, flex, _, _, _, tauTy, _, _, _, _, _)) = tbinfo - let (ExplicitTyparInfo(_, declaredTypars, _)) = flex - let maxInferredTypars = (freeInTypeLeftToRight cenv.g false tauTy) - declaredTypars @ maxInferredTypars)) - - let lazyFreeInEnv = lazy (GeneralizationHelpers.ComputeUngeneralizableTypars env) - - // Generalize the bindings... - (((fun x -> x), env, tpenv), checkedBinds) ||> List.fold (fun (buildExpr, env, tpenv) tbinfo -> - let (CheckedBindingInfo(inlineFlag, attrs, doc, tcPatPhase2, flex, nameToPrelimValSchemeMap, rhsExpr, _, tauTy, m, spBind, _, konst, isFixed)) = tbinfo - let enclosingDeclaredTypars = [] - let (ExplicitTyparInfo(_, declaredTypars, canInferTypars)) = flex - let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars - let generalizedTypars, prelimValSchemes2 = - let canInferTypars = GeneralizationHelpers. ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, canInferTypars, None) - - let maxInferredTypars = freeInTypeLeftToRight cenv.g false tauTy - - let generalizedTypars = - if isNil maxInferredTypars && isNil allDeclaredTypars then - [] - else - let freeInEnv = lazyFreeInEnv.Force() - let canConstrain = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl declKind - GeneralizationHelpers.ComputeAndGeneralizeGenericTypars - (cenv, denv, m, freeInEnv, canInferTypars, canConstrain, inlineFlag, Some rhsExpr, allDeclaredTypars, maxInferredTypars, tauTy, false) - - let prelimValSchemes2 = GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars nameToPrelimValSchemeMap - - generalizedTypars, prelimValSchemes2 - - // REVIEW: this scopes generalized type variables. Ensure this is handled properly - // on all other paths. - let tpenv = HideUnscopedTypars generalizedTypars tpenv - let valSchemes = NameMap.map (UseCombinedArity cenv.g declKind rhsExpr) prelimValSchemes2 - let values = MakeAndPublishVals cenv env (altActualParent, false, declKind, ValNotInRecScope, valSchemes, attrs, doc, konst) - let checkedPat = tcPatPhase2 (TcPatPhase2Input (values, true)) - let prelimRecValues = NameMap.map fst values - - // Now bind the r.h.s. to the l.h.s. - let rhsExpr = mkTypeLambda m generalizedTypars (rhsExpr, tauTy) - - match checkedPat with - // Don't introduce temporary or 'let' for 'match against wild' or 'match against unit' - - | (TPat_wild _ | TPat_const (Const.Unit, _)) when not isUse && not isFixed && isNil generalizedTypars -> - let mkSequentialBind (tm, tmty) = (mkSequential SequencePointsAtSeq m rhsExpr tm, tmty) - (buildExpr >> mkSequentialBind, env, tpenv) - | _ -> - - // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to - let patternInputTmp, checkedPat2 = - match checkedPat with - // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to - | TPat_as (pat, PBind(v, TypeScheme(generalizedTypars', _)), _) - when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' -> - - v, pat - //Op (LValueOp (LByrefGet,x),[],[],C:\GitHub\dsyme\visualfsharp\a.fs (15,42--15,43) IsSynthetic=false) - - | _ when inlineFlag.MustInline -> - error(Error(FSComp.SR.tcInvalidInlineSpecification(), m)) - - | _ -> - - let tmp, _ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy) - - if isUse || isFixed then - errorR(Error(FSComp.SR.tcInvalidUseBinding(), m)) - - // If the overall declaration is declaring statics or a module value, then force the patternInputTmp to also - // have representation as module value. - if (DeclKind.MustHaveArity declKind) then - AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes tmp rhsExpr) - - tmp, checkedPat - - // Add the bind "let patternInputTmp = rhsExpr" to the bodyExpr we get from mkPatBind - let mkRhsBind (bodyExpr, bodyExprTy) = - let letExpr = mkLet spBind m patternInputTmp rhsExpr bodyExpr - letExpr, bodyExprTy - - let allValsDefinedByPattern = NameMap.range prelimRecValues - - // Add the compilation of the pattern to the bodyExpr we get from mkCleanup - let mkPatBind (bodyExpr, bodyExprTy) = - let valsDefinedByMatching = ListSet.remove valEq patternInputTmp allValsDefinedByPattern - let clauses = [TClause(checkedPat2, None, TTarget(valsDefinedByMatching, bodyExpr, SuppressSequencePointAtTarget), m)] - let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (patternInputTmp, generalizedTypars, Some rhsExpr) clauses tauTy bodyExprTy - let matchx = if (DeclKind.ConvertToLinearBindings declKind) then LinearizeTopMatch cenv.g altActualParent matchx else matchx - matchx, bodyExprTy - - // Add the dispose of any "use x = ..." to bodyExpr - let mkCleanup (bodyExpr, bodyExprTy) = - if isUse && not isFixed then - (allValsDefinedByPattern, (bodyExpr, bodyExprTy)) ||> List.foldBack (fun v (bodyExpr, bodyExprTy) -> - AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css v.Range NoTrace cenv.g.system_IDisposable_ty v.Type - let cleanupE = BuildDisposableCleanup cenv env m v - mkTryFinally cenv.g (bodyExpr, cleanupE, m, bodyExprTy, SequencePointInBodyOfTry, NoSequencePointAtFinally), bodyExprTy) - else - (bodyExpr, bodyExprTy) - - let envInner = AddLocalValMap cenv.tcSink scopem prelimRecValues env - - ((buildExpr >> mkCleanup >> mkPatBind >> mkRhsBind), envInner, tpenv)) - -/// Return binds corresponding to the linearised let-bindings. -/// This reveals the bound items, e.g. when the lets occur in incremental object defns. -/// RECAP: -/// The LHS of let-bindings are patterns. -/// These patterns could fail, e.g. "let Some x = ...". -/// So let bindings could contain a fork at a match construct, with one branch being the match failure. -/// If bindings are linearised, then this fork is pushed to the RHS. -/// In this case, the let bindings type check to a sequence of bindings. -and TcLetBindings cenv env containerInfo declKind tpenv (binds, bindsm, scopem) = - assert(DeclKind.ConvertToLinearBindings declKind) - let mkf, env, tpenv = TcLetBinding cenv false env containerInfo declKind tpenv (binds, bindsm, scopem) - let unite = mkUnit cenv.g bindsm - let expr, _ = mkf (unite, cenv.g.unit_ty) - let rec stripLets acc = function - | Expr.Let (bind, body, m, _) -> stripLets (TMDefLet(bind, m) :: acc) body - | Expr.Sequential (e1, e2, NormalSeq, _, m) -> stripLets (TMDefDo(e1, m) :: acc) e2 - | Expr.Const (Const.Unit, _, _) -> List.rev acc - | _ -> failwith "TcLetBindings: let sequence is non linear. Maybe a LHS pattern was not linearised?" - let binds = stripLets [] expr - binds, env, tpenv - -and CheckMemberFlags optIntfSlotTy newslotsOK overridesOK memberFlags m = - if newslotsOK = NoNewSlots && memberFlags.IsDispatchSlot then - errorR(Error(FSComp.SR.tcAbstractMembersIllegalInAugmentation(), m)) - if overridesOK = ErrorOnOverrides && memberFlags.MemberKind = MemberKind.Constructor then - errorR(Error(FSComp.SR.tcConstructorsIllegalInAugmentation(), m)) - if overridesOK = WarnOnOverrides && memberFlags.IsOverrideOrExplicitImpl && Option.isNone optIntfSlotTy then - warning(OverrideInIntrinsicAugmentation m) - if overridesOK = ErrorOnOverrides && memberFlags.IsOverrideOrExplicitImpl then - error(Error(FSComp.SR.tcMethodOverridesIllegalHere(), m)) - -/// Apply the pre-assumed knowledge available to type inference prior to looking at -/// the _body_ of the binding. For example, in a letrec we may assume this knowledge -/// for each binding in the letrec prior to any type inference. This might, for example, -/// tell us the type of the arguments to a recursive function. -and ApplyTypesFromArgumentPatterns (cenv, env, optArgsOK, ty, m, tpenv, NormalizedBindingRhs (pushedPats, retInfoOpt, e), memberFlagsOpt: MemberFlags option) = - match pushedPats with - | [] -> - match retInfoOpt with - | None -> () - | Some (SynBindingReturnInfo (retInfoTy, m, _)) -> - let retInfoTy, _ = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv retInfoTy - UnifyTypes cenv env m ty retInfoTy - // Property setters always have "unit" return type - match memberFlagsOpt with - | Some memFlags when memFlags.MemberKind = MemberKind.PropertySet -> - UnifyTypes cenv env m ty cenv.g.unit_ty - | _ -> () - - | pushedPat :: morePushedPats -> - let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m ty - // We apply the type information from the patterns by type checking the - // "simple" patterns against 'domainTy'. They get re-typechecked later. - ignore (TcSimplePats cenv optArgsOK CheckCxs domainTy env (tpenv, Map.empty, Set.empty) pushedPat) - ApplyTypesFromArgumentPatterns (cenv, env, optArgsOK, resultTy, m, tpenv, NormalizedBindingRhs (morePushedPats, retInfoOpt, e), memberFlagsOpt) - - -/// Do the type annotations give the full and complete generic type? If so, enable generic recursion -and ComputeIsComplete enclosingDeclaredTypars declaredTypars ty = - Zset.isEmpty (List.fold (fun acc v -> Zset.remove v acc) - (freeInType CollectAllNoCaching ty).FreeTypars - (enclosingDeclaredTypars@declaredTypars)) - - -/// Determine if a uniquely-identified-abstract-slot exists for an override member (or interface member implementation) based on the information available -/// at the syntactic definition of the member (i.e. prior to type inference). If so, we know the expected signature of the override, and the full slotsig -/// it implements. Apply the inferred slotsig. -and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (bindingTy, m, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, _objTy, optIntfSlotTy, valSynData, memberFlags, attribs) = - - let ad = envinner.eAccessRights - let typToSearchForAbstractMembers = - match optIntfSlotTy with - | Some (ty, abstractSlots) -> - // The interface type is in terms of the type's type parameters. - // We need a signature in terms of the values' type parameters. - ty, Some abstractSlots - | None -> - tcrefObjTy, None - - // Determine if a uniquely-identified-override exists based on the information - // at the member signature. If so, we know the type of this member, and the full slotsig - // it implements. Apply the inferred slotsig. - if memberFlags.IsOverrideOrExplicitImpl then - - // for error detection, we want to compare finality when testing for equivalence - let methInfosEquivByNameAndSig meths = - match meths with - | [] -> false - | head :: tail -> - tail |> List.forall (MethInfosEquivByNameAndSig EraseNone false cenv.g cenv.amap m head) - - match memberFlags.MemberKind with - | MemberKind.Member -> - let dispatchSlots, dispatchSlotsArityMatch = - GetAbstractMethInfosForSynMethodDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, valSynData) - - let uniqueAbstractMethSigs = - match dispatchSlots with - | [] -> - errorR(Error(FSComp.SR.tcNoMemberFoundForOverride(), memberId.idRange)) - [] - - | slots -> - match dispatchSlotsArityMatch with - | meths when methInfosEquivByNameAndSig meths -> meths - | [] -> - let details = - slots - |> Seq.map (NicePrint.stringOfMethInfo cenv.amap m envinner.DisplayEnv) - |> Seq.map (sprintf "%s %s" System.Environment.NewLine) - |> String.concat "" - - errorR(Error(FSComp.SR.tcOverrideArityMismatch details, memberId.idRange)) - [] - | _ -> [] // check that method to override is sealed is located at CheckOverridesAreAllUsedOnce (typrelns.fs) - // We hit this case when it is ambiguous which abstract method is being implemented. - - - - // If we determined a unique member then utilize the type information from the slotsig - let declaredTypars = - match uniqueAbstractMethSigs with - | uniqueAbstractMeth :: _ -> - - let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming) - - let typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot = - FreshenAbstractSlot cenv.g cenv.amap m synTyparDecls uniqueAbstractMeth - - let declaredTypars = (if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars) - - let absSlotTy = mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot - - UnifyTypes cenv envinner m bindingTy absSlotTy - declaredTypars - | _ -> declaredTypars - - // Retained to ensure use of an FSComp.txt entry, can be removed at a later date: errorR(Error(FSComp.SR.tcDefaultAmbiguous(), memberId.idRange)) - - // What's the type containing the abstract slot we're implementing? Used later on in MakeMemberDataAndMangledNameForMemberVal. - // This type must be in terms of the enclosing type's formal type parameters, hence the application of revRenaming - - let optInferredImplSlotTys = - match optIntfSlotTy with - | Some (x, _) -> [x] - | None -> uniqueAbstractMethSigs |> List.map (fun x -> x.ApparentEnclosingType) - - optInferredImplSlotTys, declaredTypars - - | MemberKind.PropertyGet - | MemberKind.PropertySet as k -> - let dispatchSlots = GetAbstractPropInfosForSynPropertyDecl(cenv.infoReader, ad, memberId, m, typToSearchForAbstractMembers, k, valSynData) - - // Only consider those abstract slots where the get/set flags match the value we're defining - let dispatchSlots = - dispatchSlots - |> List.filter (fun pinfo -> - (pinfo.HasGetter && k=MemberKind.PropertyGet) || - (pinfo.HasSetter && k=MemberKind.PropertySet)) - - // Find the unique abstract slot if it exists - let uniqueAbstractPropSigs = - match dispatchSlots with - | [] when not (CompileAsEvent cenv.g attribs) -> - errorR(Error(FSComp.SR.tcNoPropertyFoundForOverride(), memberId.idRange)) - [] - | [uniqueAbstractProp] -> [uniqueAbstractProp] - | _ -> - // We hit this case when it is ambiguous which abstract property is being implemented. - [] - - // If we determined a unique member then utilize the type information from the slotsig - uniqueAbstractPropSigs |> List.iter (fun uniqueAbstractProp -> - - let kIsGet = (k = MemberKind.PropertyGet) - - if not (if kIsGet then uniqueAbstractProp.HasGetter else uniqueAbstractProp.HasSetter) then - error(Error(FSComp.SR.tcAbstractPropertyMissingGetOrSet(if kIsGet then "getter" else "setter"), memberId.idRange)) - - let uniqueAbstractMeth = if kIsGet then uniqueAbstractProp.GetterMethod else uniqueAbstractProp.SetterMethod - - let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming) - - let _, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot = - FreshenAbstractSlot cenv.g cenv.amap m synTyparDecls uniqueAbstractMeth - - if not (isNil typarsFromAbsSlot) then - errorR(InternalError("Unexpected generic property", memberId.idRange)) - - let absSlotTy = - if (memberFlags.MemberKind = MemberKind.PropertyGet) - then mkMethodTy cenv.g argTysFromAbsSlot retTyFromAbsSlot - else - match argTysFromAbsSlot with - | [argTysFromAbsSlot] -> mkRefTupledTy cenv.g argTysFromAbsSlot --> cenv.g.unit_ty - | _ -> - error(Error(FSComp.SR.tcInvalidSignatureForSet(), memberId.idRange)) - retTyFromAbsSlot --> cenv.g.unit_ty - - UnifyTypes cenv envinner m bindingTy absSlotTy) - - // What's the type containing the abstract slot we're implementing? Used later on in MakeMemberDataAndMangledNameForMemberVal. - // This type must be in terms of the enclosing type's formal type parameters, hence the application of revRenaming. - - let optInferredImplSlotTys = - match optIntfSlotTy with - | Some (x, _) -> [ x ] - | None -> uniqueAbstractPropSigs |> List.map (fun pinfo -> pinfo.ApparentEnclosingType) - - optInferredImplSlotTys, declaredTypars - - | _ -> - match optIntfSlotTy with - | Some (x, _) -> [x], declaredTypars - | None -> [], declaredTypars - - else - - [], declaredTypars - -and CheckForNonAbstractInterface declKind tcref memberFlags m = - if isInterfaceTyconRef tcref then - if memberFlags.MemberKind = MemberKind.ClassConstructor then - error(Error(FSComp.SR.tcStaticInitializersIllegalInInterface(), m)) - elif memberFlags.MemberKind = MemberKind.Constructor then - error(Error(FSComp.SR.tcObjectConstructorsIllegalInInterface(), m)) - elif memberFlags.IsOverrideOrExplicitImpl then - error(Error(FSComp.SR.tcMemberOverridesIllegalInInterface(), m)) - elif not (declKind=ExtrinsicExtensionBinding || memberFlags.IsDispatchSlot ) then - error(Error(FSComp.SR.tcConcreteMembersIllegalInInterface(), m)) - -//------------------------------------------------------------------------- -// TcLetrec - AnalyzeAndMakeAndPublishRecursiveValue s -//------------------------------------------------------------------------ - -and AnalyzeRecursiveStaticMemberOrValDecl - (cenv, envinner: TcEnv, - tpenv, declKind, - newslotsOK, overridesOK, - tcrefContainerInfo, vis1, - id: Ident, vis2, declaredTypars, - memberFlagsOpt, thisIdOpt, - bindingAttribs, valSynInfo, ty, - bindingRhs, mBinding, flex) = - - let vis = CombineVisibilityAttribs vis1 vis2 mBinding - - // Check if we're defining a member, in which case generate the internal unique - // name for the member and the information about which type it is augmenting - - match tcrefContainerInfo, memberFlagsOpt with - | (Some(MemberOrValContainerInfo(tcref, optIntfSlotTy, baseValOpt, _safeInitInfo, declaredTyconTypars)), Some memberFlags) -> - assert (Option.isNone optIntfSlotTy) - - CheckMemberFlags None newslotsOK overridesOK memberFlags id.idRange - CheckForNonAbstractInterface declKind tcref memberFlags id.idRange - - if memberFlags.MemberKind = MemberKind.Constructor && tcref.Deref.IsExceptionDecl then - error(Error(FSComp.SR.tcConstructorsDisallowedInExceptionAugmentation(), id.idRange)) - - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let _, enclosingDeclaredTypars, _, objTy, thisTy = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars - let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner - let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic - - let safeThisValOpt, baseValOpt = - match memberFlags.MemberKind with - - // Explicit struct or class constructor - | MemberKind.Constructor -> - // A fairly adhoc place to put this check - if tcref.IsStructOrEnumTycon && (match valSynInfo with SynValInfo([[]], _) -> true | _ -> false) then - errorR(Error(FSComp.SR.tcStructsCannotHaveConstructorWithNoArguments(), mBinding)) - - if not tcref.IsFSharpObjectModelTycon then - errorR(Error(FSComp.SR.tcConstructorsIllegalForThisType(), id.idRange)) - - let safeThisValOpt = MakeAndPublishSafeThisVal cenv envinner thisIdOpt thisTy - - // baseValOpt is the 'base' variable associated with the inherited portion of a class - // It is declared once on the 'inheritedTys clause, but a fresh binding is made for - // each member that may use it. - let baseValOpt = - match GetSuperTypeOfType cenv.g cenv.amap mBinding objTy with - | Some superTy -> MakeAndPublishBaseVal cenv envinner (match baseValOpt with None -> None | Some v -> Some v.Id) superTy - | None -> None - - let domainTy = NewInferenceType () - - // This is the type we pretend a constructor has, because its implementation must ultimately appear to return a value of the given type - // This is somewhat awkward later in codegen etc. - UnifyTypes cenv envinner mBinding ty (domainTy --> objTy) - - safeThisValOpt, baseValOpt - - | _ -> - None, None - - let memberInfo = - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, bindingAttribs, [], memberFlags, valSynInfo, id, false) - - envinner, tpenv, id, None, Some memberInfo, vis, vis2, safeThisValOpt, enclosingDeclaredTypars, baseValOpt, flex, bindingRhs, declaredTypars - - // non-member bindings. How easy. - | _ -> - envinner, tpenv, id, None, None, vis, vis2, None, [], None, flex, bindingRhs, declaredTypars - - -and AnalyzeRecursiveInstanceMemberDecl - (cenv, envinner: TcEnv, tpenv, declKind, synTyparDecls, valSynInfo, - flex: ExplicitTyparInfo, newslotsOK, overridesOK, vis1, thisId, - memberId: Ident, toolId: Ident option, bindingAttribs, vis2, - tcrefContainerInfo, memberFlagsOpt, ty, bindingRhs, mBinding) = - - let vis = CombineVisibilityAttribs vis1 vis2 mBinding - let (ExplicitTyparInfo(_, declaredTypars, infer)) = flex - match tcrefContainerInfo, memberFlagsOpt with - // Normal instance members. - | Some(MemberOrValContainerInfo(tcref, optIntfSlotTy, baseValOpt, _safeInitInfo, declaredTyconTypars)), Some memberFlags -> - - CheckMemberFlags optIntfSlotTy newslotsOK overridesOK memberFlags mBinding - - if Option.isSome vis && memberFlags.IsOverrideOrExplicitImpl then - errorR(Error(FSComp.SR.tcOverridesCannotHaveVisibilityDeclarations(), memberId.idRange)) - - // Syntactically push the "this" variable across to be a lambda on the right - let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar thisId) bindingRhs - - // The type being augmented tells us the type of 'this' - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy = FreshenObjectArgType cenv mBinding TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars - - let envinner = AddDeclaredTypars CheckForDuplicateTypars enclosingDeclaredTypars envinner - - // If private, the member's accessibility is related to 'tcref' - let envinner = MakeInnerEnvForTyconRef envinner tcref isExtrinsic - - let baseValOpt = if tcref.IsFSharpObjectModelTycon then baseValOpt else None - - // Apply the known type of 'this' - let bindingTy = NewInferenceType () - UnifyTypes cenv envinner mBinding ty (thisTy --> bindingTy) - - CheckForNonAbstractInterface declKind tcref memberFlags memberId.idRange - - // Determine if a uniquely-identified-override List.exists based on the information - // at the member signature. If so, we know the type of this member, and the full slotsig - // it implements. Apply the inferred slotsig. - let optInferredImplSlotTys, declaredTypars = - ApplyAbstractSlotInference cenv envinner (bindingTy, mBinding, synTyparDecls, declaredTypars, memberId, tcrefObjTy, renaming, objTy, optIntfSlotTy, valSynInfo, memberFlags, bindingAttribs) - - // Update the ExplicitTyparInfo to reflect the declaredTypars inferred from the abstract slot - let flex = ExplicitTyparInfo(declaredTypars, declaredTypars, infer) - - // baseValOpt is the 'base' variable associated with the inherited portion of a class - // It is declared once on the 'inheritedTys clause, but a fresh binding is made for - // each member that may use it. - let baseValOpt = - match GetSuperTypeOfType cenv.g cenv.amap mBinding objTy with - | Some superTy -> MakeAndPublishBaseVal cenv envinner (match baseValOpt with None -> None | Some v -> Some v.Id) superTy - | None -> None - - let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, isExtrinsic, bindingAttribs, optInferredImplSlotTys, memberFlags, valSynInfo, memberId, false) - // This line factored in the 'get' or 'set' as the identifier for a property declaration using "with get () = ... and set v = ..." - // It has been removed from FSharp.Compiler.Service because we want the property name to be the location of - // the definition of these symbols. - // - // See https://github.com/fsharp/FSharp.Compiler.Service/issues/79. - //let memberId = match toolId with Some tid -> ident(memberId.idText, tid.idRange) | None -> memberId - //ignore toolId - - envinner, tpenv, memberId, toolId, Some memberInfo, vis, vis2, None, enclosingDeclaredTypars, baseValOpt, flex, bindingRhs, declaredTypars - | _ -> - error(Error(FSComp.SR.tcRecursiveBindingsWithMembersMustBeDirectAugmentation(), mBinding)) - -and AnalyzeRecursiveDecl (cenv, envinner, tpenv, declKind, synTyparDecls, declaredTypars, thisIdOpt, valSynInfo, flex, newslotsOK, overridesOK, vis1, declPattern, bindingAttribs, tcrefContainerInfo, memberFlagsOpt, ty, bindingRhs, mBinding) = - let rec analyzeRecursiveDeclPat tpenv p = - match p with - | SynPat.FromParseError(pat', _) -> analyzeRecursiveDeclPat tpenv pat' - | SynPat.Typed(pat', cty, _) -> - let cty', tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType envinner tpenv cty - UnifyTypes cenv envinner mBinding ty cty' - analyzeRecursiveDeclPat tpenv pat' - | SynPat.Attrib(_pat', _attribs, m) -> - error(Error(FSComp.SR.tcAttributesInvalidInPatterns(), m)) - //analyzeRecursiveDeclPat pat' - - // This is for the construct 'let rec x = ... and do ... and y = ...' (DEPRECATED IN pars.mly ) - // - // Also for - // module rec M = - // printfn "hello" // side effects in recursive modules - // let x = 1 - | SynPat.Const (SynConst.Unit, m) | SynPat.Wild m -> - let id = ident (cenv.niceNameGen.FreshCompilerGeneratedName("doval", m), m) - analyzeRecursiveDeclPat tpenv (SynPat.Named (SynPat.Wild m, id, false, None, m)) - - | SynPat.Named (SynPat.Wild _, id, _, vis2, _) -> - AnalyzeRecursiveStaticMemberOrValDecl - (cenv, envinner, tpenv, declKind, - newslotsOK, overridesOK, tcrefContainerInfo, - vis1, id, vis2, declaredTypars, - memberFlagsOpt, thisIdOpt, bindingAttribs, - valSynInfo, ty, bindingRhs, mBinding, flex) - - | SynPat.InstanceMember(thisId, memberId, toolId, vis2, _) -> - AnalyzeRecursiveInstanceMemberDecl - (cenv, envinner, tpenv, declKind, - synTyparDecls, valSynInfo, flex, newslotsOK, - overridesOK, vis1, thisId, memberId, toolId, - bindingAttribs, vis2, tcrefContainerInfo, - memberFlagsOpt, ty, bindingRhs, mBinding) - - | _ -> error(Error(FSComp.SR.tcOnlySimplePatternsInLetRec(), mBinding)) - - analyzeRecursiveDeclPat tpenv declPattern - - -/// This is a major routine that generates the Val for a recursive binding -/// prior to the analysis of the definition of the binding. This includes -/// members of all flavours (including properties, implicit class constructors -/// and overrides). At this point we perform override inference, to infer -/// which method we are overriding, in order to add constraints to the -/// implementation of the method. -and AnalyzeAndMakeAndPublishRecursiveValue overridesOK isGeneratedEventVal cenv (env: TcEnv) (tpenv, recBindIdx) (NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, binding)) = - - // Pull apart the inputs - let (NormalizedBinding(vis1, bindingKind, isInline, isMutable, bindingSynAttribs, bindingXmlDoc, synTyparDecls, valSynData, declPattern, bindingRhs, mBinding, spBind)) = binding - let (NormalizedBindingRhs(_, _, bindingExpr)) = bindingRhs - let (SynValData(memberFlagsOpt, valSynInfo, thisIdOpt)) = valSynData - let (ContainerInfo(altActualParent, tcrefContainerInfo)) = containerInfo - - let attrTgt = DeclKind.AllowedAttribTargets memberFlagsOpt declKind - - // Check the attributes on the declaration - let bindingAttribs = TcAttributes cenv env attrTgt bindingSynAttribs - - // Allocate the type inference variable for the inferred type - let ty = NewInferenceType () - - - let inlineFlag = ComputeInlineFlag memberFlagsOpt isInline isMutable mBinding - if isMutable then errorR(Error(FSComp.SR.tcOnlyRecordFieldsAndSimpleLetCanBeMutable(), mBinding)) - - - // Typecheck the typar decls, if any - let flex, tpenv = TcBindingTyparDecls false cenv env tpenv synTyparDecls - let (ExplicitTyparInfo(_, declaredTypars, _)) = flex - let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTypars env - - // OK, analyze the declaration and return lots of information about it - let envinner, tpenv, bindingId, toolIdOpt, memberInfoOpt, vis, vis2, safeThisValOpt, enclosingDeclaredTypars, baseValOpt, flex, bindingRhs, declaredTypars = - - AnalyzeRecursiveDecl (cenv, envinner, tpenv, declKind, synTyparDecls, declaredTypars, thisIdOpt, valSynInfo, flex, - newslotsOK, overridesOK, vis1, declPattern, bindingAttribs, tcrefContainerInfo, - memberFlagsOpt, ty, bindingRhs, mBinding) - - let optArgsOK = Option.isSome memberFlagsOpt - - // Assert the types given in the argument patterns - ApplyTypesFromArgumentPatterns(cenv, envinner, optArgsOK, ty, mBinding, tpenv, bindingRhs, memberFlagsOpt) - - // Do the type annotations give the full and complete generic type? - // If so, generic recursion can be used when using this type. - let isComplete = ComputeIsComplete enclosingDeclaredTypars declaredTypars ty - - // NOTE: The type scheme here is normally not 'complete'!!!! The type is more or less just a type variable at this point. - // NOTE: top arity, type and typars get fixed-up after inference - let prelimTyscheme = TypeScheme(enclosingDeclaredTypars@declaredTypars, ty) - let partialValReprInfo = TranslateTopValSynInfo mBinding (TcAttributes cenv envinner) valSynInfo - let topValInfo = UseSyntacticArity declKind prelimTyscheme partialValReprInfo - let hasDeclaredTypars = not (List.isEmpty declaredTypars) - let prelimValScheme = ValScheme(bindingId, prelimTyscheme, topValInfo, memberInfoOpt, false, inlineFlag, NormalVal, vis, false, false, false, hasDeclaredTypars) - - // Check the literal r.h.s., if any - let _, konst = TcLiteral cenv ty env tpenv (bindingAttribs, bindingExpr) - - let extraBindings, extraValues, tpenv, recBindIdx = - let extraBindings = - [ for extraBinding in EventDeclarationNormalization.GenerateExtraBindings cenv (bindingAttribs, binding) do - yield (NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, extraBinding)) ] - let res, (tpenv, recBindIdx) = List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue overridesOK true cenv env) (tpenv, recBindIdx) extraBindings - let extraBindings, extraValues = List.unzip res - List.concat extraBindings, List.concat extraValues, tpenv, recBindIdx - - // Create the value - let vspec = MakeAndPublishVal cenv envinner (altActualParent, false, declKind, ValInRecScope isComplete, prelimValScheme, bindingAttribs, bindingXmlDoc, konst, isGeneratedEventVal) - - // Suppress hover tip for "get" and "set" at property definitions, where toolId <> bindingId - match toolIdOpt with - | Some tid when not tid.idRange.IsSynthetic && not (Range.equals tid.idRange bindingId.idRange) -> - let item = Item.Value (mkLocalValRef vspec) - CallNameResolutionSink cenv.tcSink (tid.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.RelatedText, env.DisplayEnv, env.eAccessRights) - | _ -> () - - - let mangledId = ident(vspec.LogicalName, vspec.Range) - // Reconstitute the binding with the unique name - let revisedBinding = NormalizedBinding (vis1, bindingKind, isInline, isMutable, bindingSynAttribs, bindingXmlDoc, synTyparDecls, valSynData, mkSynPatVar vis2 mangledId, bindingRhs, mBinding, spBind) - - // Create the RBInfo to use in later phases - let rbinfo = - let safeInitInfo = - match tcrefContainerInfo with - | Some(MemberOrValContainerInfo(_, _, _, safeInitInfo, _)) -> safeInitInfo - | _ -> NoSafeInitInfo - - RBInfo(recBindIdx, containerInfo, enclosingDeclaredTypars, inlineFlag, vspec, flex, partialValReprInfo, memberInfoOpt, baseValOpt, safeThisValOpt, safeInitInfo, vis, ty, declKind) - - let recBindIdx = recBindIdx + 1 - - // Done - add the declared name to the List.map and return the bundle for use by TcLetrec - let primaryBinding: PreCheckingRecursiveBinding = - { SyntacticBinding = revisedBinding - RecBindingInfo = rbinfo } - - ((primaryBinding :: extraBindings), (vspec :: extraValues)), (tpenv, recBindIdx) - - -and AnalyzeAndMakeAndPublishRecursiveValues overridesOK cenv env tpenv binds = - let recBindIdx = 0 - let res, tpenv = List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv env) (tpenv, recBindIdx) binds - let bindings, values = List.unzip res - List.concat bindings, List.concat values, tpenv - - -//------------------------------------------------------------------------- -// TcLetrecBinding -//------------------------------------------------------------------------- - -and TcLetrecBinding - (cenv, envRec: TcEnv, scopem, extraGeneralizableTypars: Typars, reqdThisValTyOpt: TType option) - - // The state of the left-to-right iteration through the bindings - (envNonRec: TcEnv, - generalizedRecBinds: PostGeneralizationRecursiveBinding list, - preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, - tpenv, - uncheckedRecBindsTable: Map) - - // This is the actual binding to check - (rbind: PreCheckingRecursiveBinding) = - - let (RBInfo(_, _, enclosingDeclaredTypars, _, vspec, flex, _, _, baseValOpt, safeThisValOpt, safeInitInfo, _, tau, declKind)) = rbind.RecBindingInfo - - let allDeclaredTypars = enclosingDeclaredTypars @ rbind.RecBindingInfo.DeclaredTypars - - // Notes on FSharp 1.0, 3187: - // - Progressively collect the "eligible for early generalization" set of bindings -- DONE - // - After checking each binding, check this set to find generalizable bindings - // - The only reason we can't generalize is if a binding refers to type variables to which - // additional constraints may be applied as part of checking a later binding - // - Compute the set by iteratively knocking out bindings that refer to type variables free in later bindings - // - Implementation notes: - // - Generalize by remap/substitution - // - Pass in "free in later bindings" by passing in the set of inference variables for the bindings, i.e. the binding types - // - For classes the bindings will include all members in a recursive group of types - // - - // Example 1: - // let f() = g() f: unit -> ?b - // and g() = 1 f: unit -> int, can generalize (though now monomorphic) - - // Example 2: - // let f() = g() f: unit -> ?b - // and g() = [] f: unit -> ?c list, can generalize - - // Example 3: - // let f() = [] f: unit -> ?b, can generalize immediately - // and g() = [] - let envRec = Option.foldBack (AddLocalVal cenv.tcSink scopem) baseValOpt envRec - let envRec = Option.foldBack (AddLocalVal cenv.tcSink scopem) safeThisValOpt envRec - - // Members can access protected members of parents of the type, and private members in the type - let envRec = MakeInnerEnvForMember envRec vspec - - let checkedBind, tpenv = - TcNormalizedBinding declKind cenv envRec tpenv tau safeThisValOpt safeInitInfo (enclosingDeclaredTypars, flex) rbind.SyntacticBinding - - (try UnifyTypes cenv envRec vspec.Range (allDeclaredTypars +-> tau) vspec.Type - with e -> error (Recursion(envRec.DisplayEnv, vspec.Id, tau, vspec.Type, vspec.Range))) - - // Inside the incremental class syntax we assert the type of the 'this' variable to be precisely the same type as the - // this variable for the implicit class constructor. For static members, we assert the type variables associated - // for the class to be identical to those used for the implicit class constructor and the static class constructor. - match reqdThisValTyOpt with - | None -> () - | Some reqdThisValTy -> - let reqdThisValTy, actualThisValTy, rangeForCheck = - match GetInstanceMemberThisVariable (vspec, checkedBind.Expr) with - | None -> - let reqdThisValTy = if isByrefTy cenv.g reqdThisValTy then destByrefTy cenv.g reqdThisValTy else reqdThisValTy - let enclosingTyconRef = tcrefOfAppTy cenv.g reqdThisValTy - reqdThisValTy, (mkAppTy enclosingTyconRef (List.map mkTyparTy enclosingDeclaredTypars)), vspec.Range - | Some thisVal -> - reqdThisValTy, thisVal.Type, thisVal.Range - if not (AddCxTypeEqualsTypeUndoIfFailed envRec.DisplayEnv cenv.css rangeForCheck actualThisValTy reqdThisValTy) then - errorR (Error(FSComp.SR.tcNonUniformMemberUse vspec.DisplayName, vspec.Range)) - - let preGeneralizationRecBind = - { RecBindingInfo = rbind.RecBindingInfo - CheckedBinding= checkedBind - ExtraGeneralizableTypars= extraGeneralizableTypars } - - // Remove one binding from the unchecked list - let uncheckedRecBindsTable = - assert (uncheckedRecBindsTable.ContainsKey rbind.RecBindingInfo.Val.Stamp) - uncheckedRecBindsTable.Remove rbind.RecBindingInfo.Val.Stamp - - // Add one binding to the candidates eligible for generalization - let preGeneralizationRecBinds = (preGeneralizationRecBind :: preGeneralizationRecBinds) - - // Incrementally generalize as many bindings as we can - TcIncrementalLetRecGeneralization cenv scopem (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) - -and TcIncrementalLetRecGeneralization cenv scopem - // The state of the left-to-right iteration through the bindings - (envNonRec: TcEnv, - generalizedRecBinds: PostGeneralizationRecursiveBinding list, - preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, - tpenv, - uncheckedRecBindsTable: Map) = - - let denv = envNonRec.DisplayEnv - // recompute the free-in-environment in case any type variables have been instantiated - let freeInEnv = GeneralizationHelpers.ComputeUngeneralizableTypars envNonRec - - // Attempt to actually generalize some of the candidates eligible for generalization. - // Compute which bindings are now eligible for early generalization. - // Do this by computing a greatest fixed point by iteratively knocking out bindings that refer - // to type variables free in later bindings. Look for ones whose type doesn't involve any of the other types - let newGeneralizedRecBinds, preGeneralizationRecBinds, tpenv = - - //printfn "\n---------------------\nConsidering early generalization after type checking binding %s" vspec.DisplayName - - // Get the type variables free in bindings that have not yet been checked. - // - // The naive implementation of this is to iterate all the forward bindings, but this is quadratic. - // - // It turns out we can remove the quadratic behaviour as follows. - // - During type checking we already keep a table of recursive uses of values, indexed by target value. - // - This table is usually much smaller than the number of remaining forward declarations ? e.g. in the pathological case you mentioned below this table is size 1. - // - If a forward declaration does not have an entry in this table then its type can't involve any inference variables from the declarations we have already checked. - // - So by scanning the domain of this table we can reduce the complexity down to something like O(n * average-number-of-forward-calls). - // - For a fully connected programs or programs where every forward declaration is subject to a forward call, this would be quadratic. However we do not expect call graphs to be like this in practice - // - // Hence we use the recursive-uses table to guide the process of scraping forward references for frozen types - // If the is no entry in the recursive use table then a forward binding has never been used and - // the type of a binding will not contain any inference variables. - // - // We do this lazily in case it is "obvious" that a binding can be generalized (e.g. its type doesn't - // involve any type inference variables) - // - // The forward uses table will always be smaller than the number of potential forward bindings except in extremely - // pathological situations - let freeInUncheckedRecBinds = - lazy ((emptyFreeTyvars, cenv.recUses.Contents) ||> Map.fold (fun acc vStamp _ -> - match uncheckedRecBindsTable.TryGetValue vStamp with - | true, fwdBind -> - accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc - | _ -> - acc)) - - let rec loop (preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, - frozenBindings: PreGeneralizationRecursiveBinding list) = - - let frozenBindingTypes = frozenBindings |> List.map (fun pgrbind -> pgrbind.RecBindingInfo.Val.Type) - - let freeInFrozenAndLaterBindings = - if frozenBindingTypes.IsEmpty then - freeInUncheckedRecBinds - else - lazy (accFreeInTypes CollectAllNoCaching frozenBindingTypes (freeInUncheckedRecBinds.Force())) - - let preGeneralizationRecBinds, newFrozenBindings = - - preGeneralizationRecBinds |> List.partition (fun pgrbind -> - - //printfn "(testing binding %s)" pgrbind.RecBindingInfo.Val.DisplayName - - // Get the free type variables in the binding - // - // We use the TauType here because the binding may already have been pre-generalized because it has - // a fully type-annotated type signature. We effectively want to generalize the binding - // again here, properly - for example this means adjusting the expression for the binding to include - // a Expr_tlambda. If we use Val.Type then the type will appear closed. - let freeInBinding = (freeInType CollectAllNoCaching pgrbind.RecBindingInfo.Val.TauType).FreeTypars - - // Is the binding free of type inference variables? If so, it can be generalized immediately - if freeInBinding.IsEmpty then true else - - //printfn "(failed generalization test 1 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName - // Any declared type parameters in an type are always generalizable - let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) - - if freeInBinding.IsEmpty then true else - - //printfn "(failed generalization test 2 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName - - // Any declared method parameters can always be generalized - let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.RecBindingInfo.DeclaredTypars)) - - if freeInBinding.IsEmpty then true else - - //printfn "(failed generalization test 3 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName - - // Type variables free in the non-recursive environment do not stop us generalizing the binding, - // since they can't be generalized anyway - let freeInBinding = Zset.diff freeInBinding freeInEnv - - if freeInBinding.IsEmpty then true else - - //printfn "(failed generalization test 4 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName - - // Type variables free in unchecked bindings do stop us generalizing - let freeInBinding = Zset.inter (freeInFrozenAndLaterBindings.Force().FreeTypars) freeInBinding - - if freeInBinding.IsEmpty then true else - - //printfn "(failed generalization test 5 for binding for %s)" pgrbind.RecBindingInfo.Val.DisplayName - - false) - //if canGeneralize then - // printfn "YES: binding for %s can be generalized early" pgrbind.RecBindingInfo.Val.DisplayName - //else - // printfn "NO: binding for %s can't be generalized early" pgrbind.RecBindingInfo.Val.DisplayName - - // Have we reached a fixed point? - if newFrozenBindings.IsEmpty then - preGeneralizationRecBinds, frozenBindings - else - // if not, then repeat - loop(preGeneralizationRecBinds, newFrozenBindings@frozenBindings) - - // start with no frozen bindings - let newGeneralizableBindings, preGeneralizationRecBinds = loop(preGeneralizationRecBinds, []) - - // Some of the bindings may now have been marked as 'generalizable' (which means they now transition - // from PreGeneralization --> PostGeneralization, since we won't get any more information on - // these bindings by processing later bindings). But this doesn't mean we - // actually generalize all the individual type variables occuring in these bindings - for example, some - // type variables may be free in the environment, and some definitions - // may be value definitions which can't be generalized, e.g. - // let rec f x = g x - // and g = id f - // Here the type variables in 'g' can't be generalized because it's a computation on the right. - // - // Note that in the normal case each binding passes IsGeneralizableValue. Properties and - // constructors do not pass CanInferExtraGeneralizedTyparsForRecBinding. - - let freeInEnv = - (freeInEnv, newGeneralizableBindings) ||> List.fold (fun freeInEnv pgrbind -> - if GeneralizationHelpers.IsGeneralizableValue cenv.g pgrbind.CheckedBinding.Expr then - freeInEnv - else - let freeInBinding = (freeInType CollectAllNoCaching pgrbind.RecBindingInfo.Val.TauType).FreeTypars - let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) - let freeInBinding = Zset.diff freeInBinding (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.RecBindingInfo.DeclaredTypars)) - Zset.union freeInBinding freeInEnv) - - // Process the bindings marked for transition from PreGeneralization --> PostGeneralization - let newGeneralizedRecBinds, tpenv = - if newGeneralizableBindings.IsEmpty then - [], tpenv - else - - let supportForBindings = newGeneralizableBindings |> List.collect (TcLetrecComputeSupportForBinding cenv) - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, scopem) supportForBindings - - let generalizedTyparsL = newGeneralizableBindings |> List.map (TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv) - - // Generalize the bindings. - let newGeneralizedRecBinds = (generalizedTyparsL, newGeneralizableBindings) ||> List.map2 (TcLetrecGeneralizeBinding cenv denv ) - let tpenv = HideUnscopedTypars (List.concat generalizedTyparsL) tpenv - newGeneralizedRecBinds, tpenv - - - newGeneralizedRecBinds, preGeneralizationRecBinds, tpenv - - let envNonRec = envNonRec |> AddLocalVals cenv.tcSink scopem (newGeneralizedRecBinds |> List.map (fun b -> b.RecBindingInfo.Val)) - let generalizedRecBinds = newGeneralizedRecBinds @ generalizedRecBinds - - (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) - -//------------------------------------------------------------------------- -// TcLetrecComputeAndGeneralizeGenericTyparsForBinding -//------------------------------------------------------------------------- - -/// Compute the type variables which may be generalized and perform the generalization -and TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv (pgrbind: PreGeneralizationRecursiveBinding) = - - let freeInEnv = Zset.diff freeInEnv (Zset.ofList typarOrder (NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g pgrbind.ExtraGeneralizableTypars)) - - let rbinfo = pgrbind.RecBindingInfo - let vspec = rbinfo.Val - let (CheckedBindingInfo(inlineFlag, _, _, _, _, _, expr, _, _, m, _, _, _, _)) = pgrbind.CheckedBinding - let (ExplicitTyparInfo(rigidCopyOfDeclaredTypars, declaredTypars, _)) = rbinfo.ExplicitTyparInfo - let allDeclaredTypars = rbinfo.EnclosingDeclaredTypars @ declaredTypars - - - // The declared typars were not marked rigid to allow equi-recursive type inference to unify - // two declared type variables. So we now check that, for each binding, the declared - // type variables can be unified with a rigid version of the same and undo the results - // of this unification. - ConstraintSolver.CheckDeclaredTypars denv cenv.css m rigidCopyOfDeclaredTypars declaredTypars - - let memFlagsOpt = vspec.MemberInfo |> Option.map (fun memInfo -> memInfo.MemberFlags) - let isCtor = (match memFlagsOpt with None -> false | Some memberFlags -> memberFlags.MemberKind = MemberKind.Constructor) - - GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, declaredTypars, m) - let canInferTypars = CanInferExtraGeneralizedTyparsForRecBinding pgrbind - - let tau = vspec.TauType - let maxInferredTypars = freeInTypeLeftToRight cenv.g false tau - - let canGeneralizeConstrained = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl rbinfo.DeclKind - let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars (cenv, denv, m, freeInEnv, canInferTypars, canGeneralizeConstrained, inlineFlag, Some expr, allDeclaredTypars, maxInferredTypars, tau, isCtor) - generalizedTypars - -/// Compute the type variables which may have member constraints that need to be canonicalized prior to generalization -and TcLetrecComputeSupportForBinding cenv (pgrbind: PreGeneralizationRecursiveBinding) = - let rbinfo = pgrbind.RecBindingInfo - let allDeclaredTypars = rbinfo.EnclosingDeclaredTypars @ rbinfo.DeclaredTypars - let maxInferredTypars = freeInTypeLeftToRight cenv.g false rbinfo.Val.TauType - allDeclaredTypars @ maxInferredTypars - -//------------------------------------------------------------------------- -// TcLetrecGeneralizeBinding -//------------------------------------------------------------------------ - -// Generalise generalizedTypars from checkedBind. -and TcLetrecGeneralizeBinding cenv denv generalizedTypars (pgrbind: PreGeneralizationRecursiveBinding) : PostGeneralizationRecursiveBinding = - - let (RBInfo(_, _, enclosingDeclaredTypars, _, vspec, flex, partialValReprInfo, memberInfoOpt, _, _, _, vis, _, declKind)) = pgrbind.RecBindingInfo - let (CheckedBindingInfo(inlineFlag, _, _, _, _, _, expr, argAttribs, _, _, _, compgen, _, isFixed)) = pgrbind.CheckedBinding - - if isFixed then - errorR(Error(FSComp.SR.tcFixedNotAllowed(), expr.Range)) - - let _, tau = vspec.TypeScheme - - let pvalscheme1 = PrelimValScheme1(vspec.Id, flex, tau, Some partialValReprInfo, memberInfoOpt, false, inlineFlag, NormalVal, argAttribs, vis, compgen) - let pvalscheme2 = GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars pvalscheme1 - - let valscheme = UseCombinedArity cenv.g declKind expr pvalscheme2 - AdjustRecType cenv vspec valscheme - - { ValScheme = valscheme - CheckedBinding = pgrbind.CheckedBinding - RecBindingInfo = pgrbind.RecBindingInfo } - - -and TcLetrecComputeCtorSafeThisValBind cenv safeThisValOpt = - match safeThisValOpt with - | None -> None - | Some (v: Val) -> - let m = v.Range - let ty = destRefCellTy cenv.g v.Type - Some (mkCompGenBind v (mkRefCell cenv.g m ty (mkNull m ty))) - -and MakeCheckSafeInitField g tinst thisValOpt rfref reqExpr (expr: Expr) = - let m = expr.Range - let availExpr = - match thisValOpt with - | None -> mkStaticRecdFieldGet (rfref, tinst, m) - | Some thisVar -> - // This is an instance method, it must have a 'this' var - mkRecdFieldGetViaExprAddr (exprForVal m thisVar, rfref, tinst, m) - let failureExpr = match thisValOpt with None -> mkCallFailStaticInit g m | Some _ -> mkCallFailInit g m - mkCompGenSequential m (mkIfThen g m (mkILAsmClt g m availExpr reqExpr) failureExpr) expr - -and MakeCheckSafeInit g tinst safeInitInfo reqExpr expr = - match safeInitInfo with - | SafeInitField (rfref, _) -> MakeCheckSafeInitField g tinst None rfref reqExpr expr - | NoSafeInitInfo -> expr - -// Given a method binding (after generalization) -// -// method M = (fun -> ) -// -// wrap the following around it if needed -// -// method M = (fun baseVal -> -// check ctorSafeInitInfo -// let ctorSafeThisVal = ref null -// ) -// -// The "check ctorSafeInitInfo" is only added for non-constructor instance members in a class where at least one type in the -// hierarchy has HasSelfReferentialConstructor -// -// The "let ctorSafeThisVal = ref null" is only added for explicit constructors with a self-reference parameter (Note: check later code for exact conditions) -// For implicit constructors the binding is added to the bindings of the implicit constructor - -and TcLetrecAdjustMemberForSpecialVals cenv (pgrbind: PostGeneralizationRecursiveBinding) : PostBindCtorThisVarRefCellRecursiveBinding = - - let (RBInfo(_, _, _, _, vspec, _, _, _, baseValOpt, safeThisValOpt, safeInitInfo, _, _, _)) = pgrbind.RecBindingInfo - let expr = pgrbind.CheckedBinding.Expr - let spBind = pgrbind.CheckedBinding.SeqPoint - - let expr = - match TcLetrecComputeCtorSafeThisValBind cenv safeThisValOpt with - | None -> expr - | Some bind -> - let m = expr.Range - let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) - mkMultiLambdas m tps vsl (mkLetBind m bind body, returnTy) - - // Add a call to CheckInit if necessary for instance members - let expr = - if vspec.IsInstanceMember && not vspec.IsExtensionMember && not vspec.IsConstructor then - match safeInitInfo with - | SafeInitField (rfref, _) -> - let m = expr.Range - let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) - // This is an instance member, it must have a 'this' - let thisVar = vsl.Head.Head - let thisTypeInst = argsOfAppTy cenv.g thisVar.Type - let newBody = MakeCheckSafeInitField cenv.g thisTypeInst (Some thisVar) rfref (mkOne cenv.g m) body - mkMultiLambdas m tps vsl (newBody, returnTy) - | NoSafeInitInfo -> - expr - - else - expr - - let expr = - match baseValOpt with - | None -> expr - | _ -> - let m = expr.Range - let tps, vsl, body, returnTy = stripTopLambda (expr, vspec.Type) - mkMemberLambdas m tps None baseValOpt vsl (body, returnTy) - - { ValScheme = pgrbind.ValScheme - Binding = TBind(vspec, expr, spBind) } - -and FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock (bind: PostBindCtorThisVarRefCellRecursiveBinding) = - let (TBind(vspec, expr, spBind)) = bind.Binding - - // Check coherence of generalization of variables for memberInfo members in generic classes - match vspec.MemberInfo with -#if EXTENDED_EXTENSION_MEMBERS // indicates if extension members can add additional constraints to type parameters - | Some _ when not vspec.IsExtensionMember -> -#else - | Some _ -> -#endif - match PartitionValTyparsForApparentEnclosingType cenv.g vspec with - | Some(parentTypars, memberParentTypars, _, _, _) -> - ignore(SignatureConformance.Checker(cenv.g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.Empty memberParentTypars parentTypars) - | None -> - errorR(Error(FSComp.SR.tcMemberIsNotSufficientlyGeneric(), vspec.Range)) - | _ -> () - - // Fixup recursive references... - let fixupPoints = GetAllUsesOfRecValue cenv vspec - - AdjustAndForgetUsesOfRecValue cenv (mkLocalValRef vspec) bind.ValScheme - - let expr = mkGenericBindRhs cenv.g vspec.Range generalizedTyparsForRecursiveBlock bind.ValScheme.TypeScheme expr - - { FixupPoints = fixupPoints - Binding = TBind(vspec, expr, spBind) } - -//------------------------------------------------------------------------- -// TcLetrec -//------------------------------------------------------------------------ - -and unionGeneralizedTypars typarSets = List.foldBack (ListSet.unionFavourRight typarEq) typarSets [] - - -and TcLetrec overridesOK cenv env tpenv (binds, bindsm, scopem) = - - // Create prelimRecValues for the recursive items (includes type info from LHS of bindings) *) - let binds = binds |> List.map (fun (RecDefnBindingInfo(a, b, c, bind)) -> NormalizedRecBindingDefn(a, b, c, BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env bind)) - let uncheckedRecBinds, prelimRecValues, (tpenv, _) = AnalyzeAndMakeAndPublishRecursiveValues overridesOK cenv env tpenv binds - - let envRec = AddLocalVals cenv.tcSink scopem prelimRecValues env - - // Typecheck bindings - let uncheckedRecBindsTable = uncheckedRecBinds |> List.map (fun rbind -> rbind.RecBindingInfo.Val.Stamp, rbind) |> Map.ofList - - let (_, generalizedRecBinds, preGeneralizationRecBinds, tpenv, _) = - ((env, [], [], tpenv, uncheckedRecBindsTable), uncheckedRecBinds) ||> List.fold (TcLetrecBinding (cenv, envRec, scopem, [], None)) - - // There should be no bindings that have not been generalized since checking the vary last binding always - // results in the generalization of all remaining ungeneralized bindings, since there are no remaining unchecked bindings - // to prevent the generalization - assert preGeneralizationRecBinds.IsEmpty - - let generalizedRecBinds = generalizedRecBinds |> List.sortBy (fun pgrbind -> pgrbind.RecBindingInfo.Index) - let generalizedTyparsForRecursiveBlock = - generalizedRecBinds - |> List.map (fun pgrbind -> pgrbind.GeneralizedTypars) - |> unionGeneralizedTypars - - - let vxbinds = generalizedRecBinds |> List.map (TcLetrecAdjustMemberForSpecialVals cenv) - - // Now that we know what we've generalized we can adjust the recursive references - let vxbinds = vxbinds |> List.map (FixupLetrecBind cenv env.DisplayEnv generalizedTyparsForRecursiveBlock) - - // Now eliminate any initialization graphs - let binds = - let bindsWithoutLaziness = vxbinds - let mustHaveArity = - match uncheckedRecBinds with - | [] -> false - | (rbind :: _) -> DeclKind.MustHaveArity rbind.RecBindingInfo.DeclKind - - let results = - EliminateInitializationGraphs - (fun _ -> failwith "unreachable 2 - no type definitions in recursive group") - (fun _ _ -> failwith "unreachable 3 - no type definitions in recursive group") - id - (fun morpher oldBinds -> morpher oldBinds) - cenv.g mustHaveArity env.DisplayEnv [MutRecShape.Lets bindsWithoutLaziness] bindsm - match results with - | [MutRecShape.Lets newBinds; MutRecShape.Lets newBinds2] -> newBinds @ newBinds2 - | [MutRecShape.Lets newBinds] -> newBinds - | _ -> failwith "unreachable 4 - gave a Lets shape, expected at most one pre-lets shape back" - - // Post letrec env - let envbody = AddLocalVals cenv.tcSink scopem prelimRecValues env - binds, envbody, tpenv - - - -//------------------------------------------------------------------------- -// Bind specifications of values -//------------------------------------------------------------------------- - -let TcAndPublishValSpec (cenv, env, containerInfo: ContainerInfo, declKind, memFlagsOpt, tpenv, valSpfn) = - - let (ValSpfn (Attributes synAttrs, _, SynValTyparDecls (synTypars, synCanInferTypars, _), _, _, isInline, mutableFlag, doc, vis, literalExprOpt, m)) = valSpfn - - GeneralizationHelpers.CheckDeclaredTyparsPermitted(memFlagsOpt, synTypars, m) - let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, synCanInferTypars, memFlagsOpt) - - let attrTgt = DeclKind.AllowedAttribTargets memFlagsOpt declKind - - let attrs = TcAttributes cenv env attrTgt synAttrs - let newOk = if canInferTypars then NewTyparsOK else NoNewTypars - - let valinfos, tpenv = TcValSpec cenv env declKind newOk containerInfo memFlagsOpt None tpenv valSpfn attrs - let denv = env.DisplayEnv - - (tpenv, valinfos) ||> List.mapFold (fun tpenv valSpecResult -> - - let (ValSpecResult (altActualParent, memberInfoOpt, id, enclosingDeclaredTypars, declaredTypars, ty, partialValReprInfo, declKind)) = valSpecResult - - let inlineFlag = ComputeInlineFlag (memberInfoOpt |> Option.map (fun (ValMemberInfoTransient(memberInfo, _, _)) -> memberInfo.MemberFlags)) isInline mutableFlag m - - let freeInType = freeInTypeLeftToRight cenv.g false ty - - let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars - - let flex = ExplicitTyparInfo(declaredTypars, declaredTypars, synCanInferTypars) - - let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars(cenv, denv, id.idRange, emptyFreeTypars, canInferTypars, CanGeneralizeConstrainedTypars, inlineFlag, None, allDeclaredTypars, freeInType, ty, false) - - let valscheme1 = PrelimValScheme1(id, flex, ty, Some partialValReprInfo, memberInfoOpt, mutableFlag, inlineFlag, NormalVal, noArgOrRetAttribs, vis, false) - - let valscheme2 = GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTypars valscheme1 - - let tpenv = HideUnscopedTypars generalizedTypars tpenv - - let valscheme = BuildValScheme declKind (Some partialValReprInfo) valscheme2 - - let konst = - match literalExprOpt with - | None -> - let hasLiteralAttr = HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute attrs - if hasLiteralAttr then - errorR(Error(FSComp.SR.tcLiteralAttributeRequiresConstantValue(), m)) - None - - | Some e -> - let hasLiteralAttr, konst = TcLiteral cenv ty env tpenv (attrs, e) - if not hasLiteralAttr then - errorR(Error(FSComp.SR.tcValueInSignatureRequiresLiteralAttribute(), e.Range)) - konst - - let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, doc.ToXmlDoc(), konst, false) - assert(vspec.InlineInfo = inlineFlag) - - vspec, tpenv) - - -//------------------------------------------------------------------------- -// Bind elements of data definitions for exceptions and types (fields, etc.) -//------------------------------------------------------------------------- - -exception NotUpperCaseConstructor of range - -let CheckNamespaceModuleOrTypeName (g: TcGlobals) (id: Ident) = - // type names '[]' etc. are used in fslib - if not g.compilingFslib && id.idText.IndexOfAny IllegalCharactersInTypeAndNamespaceNames <> -1 then - errorR(Error(FSComp.SR.tcInvalidNamespaceModuleTypeUnionName(), id.idRange)) - -let CheckDuplicates (idf: _ -> Ident) k elems = - elems |> List.iteri (fun i uc1 -> - elems |> List.iteri (fun j uc2 -> - let id1 = (idf uc1) - let id2 = (idf uc2) - if j > i && id1.idText = id2.idText then - errorR (Duplicate(k, id1.idText, id1.idRange)))) - elems - - -module TcRecdUnionAndEnumDeclarations = begin - - let CombineReprAccess parent vis = - match parent with - | ParentNone -> vis - | Parent tcref -> combineAccess vis tcref.TypeReprAccessibility - - let MakeRecdFieldSpec _cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, vol, xmldoc, vis, m) = - let vis, _ = ComputeAccessAndCompPath env None m vis None parent - let vis = CombineReprAccess parent vis - NewRecdField isStatic konst id nameGenerated ty' isMutable vol attrsForProperty attrsForField xmldoc vis false - - let TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, synAttrs, id, nameGenerated, ty, isMutable, xmldoc, vis, m) = - let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDecl synAttrs - let attrsForProperty, attrsForField = attrs |> List.partition (fun (attrTargets, _) -> (attrTargets &&& AttributeTargets.Property) <> enum 0) - let attrsForProperty = (List.map snd attrsForProperty) - let attrsForField = (List.map snd attrsForField) - let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType env tpenv ty - let zeroInit = HasFSharpAttribute cenv.g cenv.g.attrib_DefaultValueAttribute attrsForField - let isVolatile = HasFSharpAttribute cenv.g cenv.g.attrib_VolatileFieldAttribute attrsForField - - let isThreadStatic = isThreadOrContextStatic cenv.g attrsForField - if isThreadStatic && (not zeroInit || not isStatic) then - error(Error(FSComp.SR.tcThreadStaticAndContextStaticMustBeStatic(), m)) - - if isVolatile then - error(Error(FSComp.SR.tcVolatileOnlyOnClassLetBindings(), m)) - - if isIncrClass && (not zeroInit || not isMutable) then errorR(Error(FSComp.SR.tcUninitializedValFieldsMustBeMutable(), m)) - if isStatic && (not zeroInit || not isMutable || vis <> Some SynAccess.Private ) then errorR(Error(FSComp.SR.tcStaticValFieldsMustBeMutableAndPrivate(), m)) - let konst = if zeroInit then Some Const.Zero else None - let rfspec = MakeRecdFieldSpec cenv env parent (isStatic, konst, ty', attrsForProperty, attrsForField, id, nameGenerated, isMutable, isVolatile, xmldoc, vis, m) - match parent with - | Parent tcref when useGenuineField tcref.Deref rfspec -> - // Recheck the attributes for errors if the definition only generates a field - TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore - | _ -> () - rfspec - - - let TcAnonFieldDecl cenv env parent tpenv nm (Field(Attributes attribs, isStatic, idOpt, ty, isMutable, xmldoc, vis, m)) = - let id = (match idOpt with None -> mkSynId m nm | Some id -> id) - let f = TcFieldDecl cenv env parent false tpenv (isStatic, attribs, id, idOpt.IsNone, ty, isMutable, xmldoc.ToXmlDoc(), vis, m) - match idOpt with - | None -> () - | Some id -> - let item = Item.ArgName(id, f.FormalType, None) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.AccessRights) - f - - - let TcNamedFieldDecl cenv env parent isIncrClass tpenv (Field(Attributes attribs, isStatic, id, ty, isMutable, xmldoc, vis, m)) = - match id with - | None -> error (Error(FSComp.SR.tcFieldRequiresName(), m)) - | Some id -> TcFieldDecl cenv env parent isIncrClass tpenv (isStatic, attribs, id, false, ty, isMutable, xmldoc.ToXmlDoc(), vis, m) - - let TcNamedFieldDecls cenv env parent isIncrClass tpenv fields = - fields |> List.map (TcNamedFieldDecl cenv env parent isIncrClass tpenv) - - - //------------------------------------------------------------------------- - // Bind other elements of type definitions (constructors etc.) - //------------------------------------------------------------------------- - - let CheckUnionCaseName cenv (id: Ident) = - let name = id.idText - if name = "Tags" then - errorR(Error(FSComp.SR.tcUnionCaseNameConflictsWithGeneratedType(name, "Tags"), id.idRange)) - - CheckNamespaceModuleOrTypeName cenv.g id - if not (String.isUpper name) && name <> opNameCons && name <> opNameNil then - errorR(NotUpperCaseConstructor(id.idRange)) - - let ValidateFieldNames (synFields: SynField list, tastFields: RecdField list) = - let seen = Dictionary() - for (sf, f) in List.zip synFields tastFields do - match seen.TryGetValue f.Name with - | true, synField -> - match sf, synField with - | Field(_, _, Some id, _, _, _, _, _), Field(_, _, Some(_), _, _, _, _, _) -> - error(Error(FSComp.SR.tcFieldNameIsUsedModeThanOnce(id.idText), id.idRange)) - | Field(_, _, Some id, _, _, _, _, _), Field(_, _, None, _, _, _, _, _) - | Field(_, _, None, _, _, _, _, _), Field(_, _, Some id, _, _, _, _, _) -> - error(Error(FSComp.SR.tcFieldNameConflictsWithGeneratedNameForAnonymousField(id.idText), id.idRange)) - | _ -> assert false - | _ -> - seen.Add(f.Name, sf) - - let TcUnionCaseDecl cenv env parent thisTy tpenv (UnionCase(Attributes synAttrs, id, args, xmldoc, vis, m)) = - let attrs = TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs // the attributes of a union case decl get attached to the generated "static factory" method - let vis, _ = ComputeAccessAndCompPath env None m vis None parent - let vis = CombineReprAccess parent vis - - CheckUnionCaseName cenv id - - let mkName nFields i = if nFields <= 1 then "Item" else "Item"+string (i+1) - let rfields, recordTy = - match args with - | UnionCaseFields flds -> - let nFields = flds.Length - let rfields = flds |> List.mapi (fun i fld -> TcAnonFieldDecl cenv env parent tpenv (mkName nFields i) fld) - ValidateFieldNames(flds, rfields) - - rfields, thisTy - | UnionCaseFullType (ty, arity) -> - let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType env tpenv ty - let curriedArgTys, recordTy = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m - if curriedArgTys.Length > 1 then - errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) - let argTys = curriedArgTys |> List.concat - let nFields = argTys.Length - let rfields = - argTys |> List.mapi (fun i (argty, argInfo) -> - let id = (match argInfo.Name with Some id -> id | None -> mkSynId m (mkName nFields i)) - MakeRecdFieldSpec cenv env parent (false, None, argty, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m)) - if not (typeEquiv cenv.g recordTy thisTy) then - error(Error(FSComp.SR.tcReturnTypesForUnionMustBeSameAsType(), m)) - rfields, recordTy - NewUnionCase id rfields recordTy attrs (xmldoc.ToXmlDoc()) vis - - - let TcUnionCaseDecls cenv env parent (thisTy: TType) tpenv unionCases = - let unionCases' = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy tpenv) - unionCases' |> CheckDuplicates (fun uc -> uc.Id) "union case" - - let TcEnumDecl cenv env parent thisTy fieldTy (EnumCase(Attributes synAttrs, id, v, xmldoc, m)) = - let attrs = TcAttributes cenv env AttributeTargets.Field synAttrs - match v with - | SynConst.Bytes _ - | SynConst.UInt16s _ - | SynConst.UserNum _ -> error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), m)) - | _ -> - let v = TcConst cenv fieldTy m env v - let vis, _ = ComputeAccessAndCompPath env None m None None parent - let vis = CombineReprAccess parent vis - if id.idText = "value__" then errorR(Error(FSComp.SR.tcNotValidEnumCaseName(), id.idRange)) - NewRecdField true (Some v) id false thisTy false false [] attrs (xmldoc.ToXmlDoc()) vis false - - let TcEnumDecls cenv env parent thisTy enumCases = - let fieldTy = NewInferenceType () - let enumCases' = enumCases |> List.map (TcEnumDecl cenv env parent thisTy fieldTy) |> CheckDuplicates (fun f -> f.Id) "enum element" - fieldTy, enumCases' - -end - -//------------------------------------------------------------------------- -// Bind elements of classes -//------------------------------------------------------------------------- - -let PublishInterface cenv denv (tcref: TyconRef) m compgen ty' = - if not (isInterfaceTy cenv.g ty') then errorR(Error(FSComp.SR.tcTypeIsNotInterfaceType1(NicePrint.minimalStringOfType denv ty'), m)) - let tcaug = tcref.TypeContents - if tcref.HasInterface cenv.g ty' then - errorR(Error(FSComp.SR.tcDuplicateSpecOfInterface(), m)) - tcaug.tcaug_interfaces <- (ty', compgen, m) :: tcaug.tcaug_interfaces - -let TcAndPublishMemberSpec cenv env containerInfo declKind tpenv memb = - match memb with - | SynMemberSig.ValField(_, m) -> error(Error(FSComp.SR.tcFieldValIllegalHere(), m)) - | SynMemberSig.Inherit(_, m) -> error(Error(FSComp.SR.tcInheritIllegalHere(), m)) - | SynMemberSig.NestedType(_, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)) - | SynMemberSig.Member(valSpfn, memberFlags, _) -> - TcAndPublishValSpec (cenv, env, containerInfo, declKind, Some memberFlags, tpenv, valSpfn) - | SynMemberSig.Interface _ -> - // These are done in TcMutRecDefns_Phase1 - [], tpenv - - -let TcTyconMemberSpecs cenv env containerInfo declKind tpenv (augSpfn: SynMemberSigs) = - let members, tpenv = List.mapFold (TcAndPublishMemberSpec cenv env containerInfo declKind) tpenv augSpfn - List.concat members, tpenv - - -//------------------------------------------------------------------------- -// Bind 'open' declarations -//------------------------------------------------------------------------- - -let TcOpenLidAndPermitAutoResolve tcSink env amap (longId : Ident list) = - let ad = env.eAccessRights - match longId with - | [] -> [] - | id :: rest -> - let m = longId |> List.map (fun id -> id.idRange) |> List.reduce unionRanges - match ResolveLongIndentAsModuleOrNamespaceOrStaticClass tcSink ResultCollectionSettings.AllResults amap m true true OpenQualified env.eNameResEnv ad id rest true with - | Result res -> res - | Exception err -> - errorR(err); [] - -let TcOpenDecl tcSink (g: TcGlobals) amap m scopem env (longId: Ident list) = - match TcOpenLidAndPermitAutoResolve tcSink env amap longId with - | [] -> env - | modrefs -> - - // validate opened namespace names - for id in longId do - if id.idText <> MangledGlobalName then - CheckNamespaceModuleOrTypeName g id - - let IsPartiallyQualifiedNamespace (modref: ModuleOrNamespaceRef) = - let (CompPath(_, p)) = modref.CompilationPath - // Bug FSharp 1.0 3274: FSI paths don't count when determining this warning - let p = - match p with - | [] -> [] - | (h, _) :: t -> if h.StartsWithOrdinal FsiDynamicModulePrefix then t else p - - // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f - let isFSharpCoreSpecialCase = - match ccuOfTyconRef modref with - | None -> false - | Some ccu -> - ccuEq ccu g.fslibCcu && - // Check if we're using a reference one string shorter than what we expect. - // - // "p" is the fully qualified path _containing_ the thing we're opening, e.g. "Microsoft.FSharp" when opening "Microsoft.FSharp.Data" - // "longId" is the text being used, e.g. "FSharp.Data" - // Length of thing being opened = p.Length + 1 - // Length of reference = longId.Length - // So the reference is a "shortened" reference if (p.Length + 1) - 1 = longId.Length - (p.Length + 1) - 1 = longId.Length && - fst p.[0] = "Microsoft" - - modref.IsNamespace && - p.Length >= longId.Length && - not isFSharpCoreSpecialCase - // Allow "open Foo" for "Microsoft.Foo" from FSharp.Core - - modrefs |> List.iter (fun (_, modref, _) -> - if modref.IsModule && HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs then - errorR(Error(FSComp.SR.tcModuleRequiresQualifiedAccess(fullDisplayTextOfModRef modref), m))) - - // Bug FSharp 1.0 3133: 'open Lexing'. Skip this warning if we successfully resolved to at least a module name - if not (modrefs |> List.exists (fun (_, modref, _) -> modref.IsModule && not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs))) then - modrefs |> List.iter (fun (_, modref, _) -> - if IsPartiallyQualifiedNamespace modref then - errorR(Error(FSComp.SR.tcOpenUsedWithPartiallyQualifiedPath(fullDisplayTextOfModRef modref), m))) - - let modrefs = List.map p23 modrefs - modrefs |> List.iter (fun modref -> CheckEntityAttributes g modref m |> CommitOperationResult) - - let openDecl = OpenDeclaration.Create (longId, modrefs, scopem, false) - let env = OpenEntities tcSink g amap scopem false env modrefs openDecl - env - - -exception ParameterlessStructCtor of range - -/// Incremental class definitions -module IncrClassChecking = - - /// Represents a single group of bindings in a class with an implicit constructor - type IncrClassBindingGroup = - | IncrClassBindingGroup of Tast.Binding list * (*isStatic:*) bool* (*recursive:*) bool - | IncrClassDo of Expr * (*isStatic:*) bool - - /// Typechecked info for implicit constructor and it's arguments - type IncrClassCtorLhs = - { - /// The TyconRef for the type being defined - TyconRef: TyconRef - - /// The type parameters allocated for the implicit instance constructor. - /// These may be equated with other (WillBeRigid) type parameters through equi-recursive inference, and so - /// should always be renormalized/canonicalized when used. - InstanceCtorDeclaredTypars: Typars - - /// The value representing the static implicit constructor. - /// Lazy to ensure the static ctor value is only published if needed. - StaticCtorValInfo: Lazy<(Val list * Val * ValScheme)> - - /// The value representing the implicit constructor. - InstanceCtorVal: Val - - /// The type of the implicit constructor, representing as a ValScheme. - InstanceCtorValScheme: ValScheme - - /// The values representing the arguments to the implicit constructor. - InstanceCtorArgs: Val list - - /// The reference cell holding the 'this' parameter within the implicit constructor so it can be referenced in the - /// arguments passed to the base constructor - InstanceCtorSafeThisValOpt: Val option - - /// Data indicating if safe-initialization checks need to be inserted for this type. - InstanceCtorSafeInitInfo: SafeInitData - - /// The value representing the 'base' variable within the implicit instance constructor. - InstanceCtorBaseValOpt: Val option - - /// The value representing the 'this' variable within the implicit instance constructor. - InstanceCtorThisVal: Val - - /// The name generator used to generate the names of fields etc. within the type. - NameGenerator: NiceNameGenerator - } - - /// Get the type parameters of the implicit constructor, after taking equi-recursive inference into account. - member ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv denv m = - let ctorDeclaredTypars = ctorInfo.InstanceCtorDeclaredTypars - let ctorDeclaredTypars = ChooseCanonicalDeclaredTyparsAfterInference cenv.g denv ctorDeclaredTypars m - ctorDeclaredTypars - - /// Check and elaborate the "left hand side" of the implicit class construction - /// syntax. - let TcImplicitCtorLhs_Phase2A(cenv, env, tpenv, tcref: TyconRef, vis, attrs, spats, thisIdOpt, baseValOpt: Val option, safeInitInfo, m, copyOfTyconTypars, objTy, thisTy) = - - let baseValOpt = - match GetSuperTypeOfType cenv.g cenv.amap m objTy with - | Some superTy -> MakeAndPublishBaseVal cenv env (match baseValOpt with None -> None | Some v -> Some v.Id) superTy - | None -> None - - // Add class typars to env - let env = AddDeclaredTypars CheckForDuplicateTypars copyOfTyconTypars env - - // Type check arguments by processing them as 'simple' patterns - // NOTE: if we allow richer patterns here this is where we'd process those patterns - let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true CheckCxs env tpenv (SynSimplePats.SimplePats (spats, m)) - - // Create the values with the given names - let _, vspecs = MakeSimpleVals cenv env names - - if tcref.IsStructOrEnumTycon && isNil spats then - errorR (ParameterlessStructCtor(tcref.Range)) - - // Put them in order - let ctorArgs = List.map (fun v -> NameMap.find v vspecs) ctorArgNames - let safeThisValOpt = MakeAndPublishSafeThisVal cenv env thisIdOpt thisTy - - // NOTE: the type scheme here is not complete!!! The ctorTy is more or less - // just a type variable. The type and typars get fixed-up after inference - let ctorValScheme, ctorVal = - let argty = mkRefTupledTy cenv.g (typesOfVals ctorArgs) - // Initial type has known information - let ctorTy = mkFunTy argty objTy - // REVIEW: no attributes can currently be specified for the implicit constructor - let attribs = TcAttributes cenv env (AttributeTargets.Constructor ||| AttributeTargets.Method) attrs - let memberFlags = CtorMemberFlags - - let synArgInfos = List.map (SynInfo.InferSynArgInfoFromSimplePat []) spats - let valSynData = SynValInfo([synArgInfos], SynInfo.unnamedRetVal) - let id = ident ("new", m) - - CheckForNonAbstractInterface ModuleOrMemberBinding tcref memberFlags id.idRange - let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, false, attribs, [], memberFlags, valSynData, id, false) - let partialValReprInfo = TranslateTopValSynInfo m (TcAttributes cenv env) valSynData - let prelimTyschemeG = TypeScheme(copyOfTyconTypars, ctorTy) - let isComplete = ComputeIsComplete copyOfTyconTypars [] ctorTy - let topValInfo = InferGenericArityFromTyScheme prelimTyschemeG partialValReprInfo - let ctorValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, vis, false, true, false, false) - let ctorVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValInRecScope isComplete, ctorValScheme, attribs, XmlDoc.Empty, None, false) - ctorValScheme, ctorVal - - // We only generate the cctor on demand, because we don't need it if there are no cctor actions. - // The code below has a side-effect (MakeAndPublishVal), so we only want to run it once if at all. - // The .cctor is never referenced by any other code. - let cctorValInfo = - lazy - (let cctorArgs = [ fst(mkCompGenLocal m "unitVar" cenv.g.unit_ty) ] - - let cctorTy = mkFunTy cenv.g.unit_ty cenv.g.unit_ty - let valSynData = SynValInfo([[]], SynInfo.unnamedRetVal) - let id = ident ("cctor", m) - CheckForNonAbstractInterface ModuleOrMemberBinding tcref ClassCtorMemberFlags id.idRange - let memberInfo = MakeMemberDataAndMangledNameForMemberVal(cenv.g, tcref, false, [(*no attributes*)], [], ClassCtorMemberFlags, valSynData, id, false) - let partialValReprInfo = TranslateTopValSynInfo m (TcAttributes cenv env) valSynData - let prelimTyschemeG = TypeScheme(copyOfTyconTypars, cctorTy) - let topValInfo = InferGenericArityFromTyScheme prelimTyschemeG partialValReprInfo - let cctorValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, Some SynAccess.Private, false, true, false, false) - - let cctorVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValNotInRecScope, cctorValScheme, [(* no attributes*)], XmlDoc.Empty, None, false) - cctorArgs, cctorVal, cctorValScheme) - - let thisVal = - // --- Create this for use inside constructor - let thisId = ident ("this", m) - let thisValScheme = ValScheme(thisId, NonGenericTypeScheme thisTy, None, None, false, ValInline.Never, CtorThisVal, None, true, false, false, false) - let thisVal = MakeAndPublishVal cenv env (ParentNone, false, ClassLetBinding false, ValNotInRecScope, thisValScheme, [], XmlDoc.Empty, None, false) - thisVal - - {TyconRef = tcref - InstanceCtorDeclaredTypars = copyOfTyconTypars - StaticCtorValInfo = cctorValInfo - InstanceCtorArgs = ctorArgs - InstanceCtorVal = ctorVal - InstanceCtorValScheme = ctorValScheme - InstanceCtorBaseValOpt = baseValOpt - InstanceCtorSafeThisValOpt = safeThisValOpt - InstanceCtorSafeInitInfo = safeInitInfo - InstanceCtorThisVal = thisVal - // For generating names of local fields - NameGenerator = NiceNameGenerator() - - } - - - // Partial class defns - local val mapping to fields - - /// Create the field for a "let" binding in a type definition. - /// - /// The "v" is the local typed w.r.t. tyvars of the implicit ctor. - /// The formalTyparInst does the formal-typars/implicit-ctor-typars subst. - /// Field specifications added to a tcref must be in terms of the tcrefs formal typars. - let private MakeIncrClassField(g, cpath, formalTyparInst: TyparInst, v: Val, isStatic, rfref: RecdFieldRef) = - let name = rfref.FieldName - let id = ident (name, v.Range) - let ty = v.Type |> instType formalTyparInst - let taccess = TAccess [cpath] - let isVolatile = HasFSharpAttribute g g.attrib_VolatileFieldAttribute v.Attribs - - NewRecdField isStatic None id false ty v.IsMutable isVolatile [(*no property attributes*)] v.Attribs v.XmlDoc taccess (*compiler generated:*)true - - /// Indicates how is a 'let' bound value in a class with implicit construction is represented in - /// the TAST ultimately produced by type checking. - type IncrClassValRepr = - // e.g representation for 'let v = 3' if it is not used in anything given a method representation - | InVar of (* isArg: *) bool - // e.g representation for 'let v = 3' - | InField of (*isStatic:*)bool * (*staticCountForSafeInit:*) int * RecdFieldRef - // e.g representation for 'let f x = 3' - | InMethod of (*isStatic:*)bool * Val * ValReprInfo - - /// IncrClassReprInfo represents the decisions we make about the representation of 'let' and 'do' bindings in a - /// type defined with implicit class construction. - type IncrClassReprInfo = - { /// Indicates the set of field names taken within one incremental class - TakenFieldNames: Set - RepInfoTcGlobals: TcGlobals - /// vals mapped to representations - ValReprs: Zmap - /// vals represented as fields or members from this point on - ValsWithRepresentation: Zset } - - static member Empty(g, names) = - { TakenFieldNames=Set.ofList names - RepInfoTcGlobals=g - ValReprs = Zmap.empty valOrder - ValsWithRepresentation = Zset.empty valOrder } - - /// Find the representation of a value - member localRep.LookupRepr (v: Val) = - match Zmap.tryFind v localRep.ValReprs with - | None -> error(InternalError("LookupRepr: failed to find representation for value", v.Range)) - | Some res -> res - - static member IsMethodRepr cenv (bind: Binding) = - let v = bind.Var - // unit fields are not stored, just run rhs for effects - if isUnitTy cenv.g v.Type then - false - else - let arity = InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes v bind.Expr - not arity.HasNoArgs && not v.IsMutable - - - /// Choose how a binding is represented - member localRep.ChooseRepresentation (cenv, env: TcEnv, isStatic, isCtorArg, - ctorInfo: IncrClassCtorLhs, - /// The vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings - staticForcedFieldVars: FreeLocals, - /// The vars forced to be fields due to instance member bindings - instanceForcedFieldVars: FreeLocals, - takenFieldNames: Set, - bind: Binding) = - let g = cenv.g - let v = bind.Var - let relevantForcedFieldVars = (if isStatic then staticForcedFieldVars else instanceForcedFieldVars) - - let tcref = ctorInfo.TyconRef - let name, takenFieldNames = - - let isNameTaken = - // Check if a implicit field already exists with this name - takenFieldNames.Contains(v.LogicalName) || - // Check if a user-defined field already exists with this name. Struct fields have already been created - see bug FSharp 1.0 5304 - (tcref.GetFieldByName(v.LogicalName).IsSome && (isStatic || not tcref.IsFSharpStructOrEnumTycon)) - - let nm = - if isNameTaken then - ctorInfo.NameGenerator.FreshCompilerGeneratedName (v.LogicalName, v.Range) - else - v.LogicalName - nm, takenFieldNames.Add nm - - let reportIfUnused() = - if not v.HasBeenReferenced && not v.IsCompiledAsTopLevel && not (v.DisplayName.StartsWithOrdinal("_")) && not v.IsCompilerGenerated then - warning (Error(FSComp.SR.chkUnusedValue(v.DisplayName), v.Range)) - - let repr = - match InferArityOfExprBinding g AllowTypeDirectedDetupling.Yes v bind.Expr with - | arity when arity.HasNoArgs || v.IsMutable -> - // all mutable variables are forced into fields, since they may escape into closures within the implicit constructor - // e.g. - // type C() = - // let mutable m = 1 - // let n = ... (fun () -> m) .... - // - // All struct variables are forced into fields. Structs may not contain "let" bindings, so no new variables can be - // introduced. - - if v.IsMutable || relevantForcedFieldVars.Contains v || tcref.IsStructOrEnumTycon then - //dprintfn "Representing %s as a field %s" v.LogicalName name - let rfref = RFRef(tcref, name) - reportIfUnused() - InField (isStatic, localRep.ValReprs.Count, rfref) - else - //if not v.Attribs.IsEmpty then - // warning(Error(FSComp.SR.tcAttributesIgnoredOnLetBinding(), v.Range)) - //dprintfn - // "Representing %s as a local variable %s, staticForcedFieldVars = %s, instanceForcedFieldVars = %s" - // v.LogicalName name - // (staticForcedFieldVars |> Seq.map (fun v -> v.LogicalName) |> String.concat ",") - // (instanceForcedFieldVars |> Seq.map (fun v -> v.LogicalName) |> String.concat ",") - InVar isCtorArg - | topValInfo -> - //dprintfn "Representing %s as a method %s" v.LogicalName name - let tps, argInfos, _, _ = GetTopValTypeInCompiledForm g topValInfo v.Type v.Range - - let valSynInfo = SynValInfo(argInfos |> List.mapSquared (fun (_, argInfo) -> SynArgInfo([], false, argInfo.Name)), SynInfo.unnamedRetVal) - let memberFlags = (if isStatic then StaticMemberFlags else NonVirtualMemberFlags) MemberKind.Member - let id = mkSynId v.Range name - let memberInfo = MakeMemberDataAndMangledNameForMemberVal(g, tcref, false, [], [], memberFlags, valSynInfo, mkSynId v.Range name, true) - - let copyOfTyconTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv env.DisplayEnv ctorInfo.TyconRef.Range - // Add the 'this' pointer on to the function - let memberTauTy, topValInfo = - let tauTy = v.TauType - if isStatic then - tauTy, topValInfo - else - let tauTy = ctorInfo.InstanceCtorThisVal.Type --> v.TauType - let (ValReprInfo(tpNames, args, ret)) = topValInfo - let topValInfo = ValReprInfo(tpNames, ValReprInfo.selfMetadata :: args, ret) - tauTy, topValInfo - // Add the enclosing type parameters on to the function - let topValInfo = - let (ValReprInfo(tpNames, args, ret)) = topValInfo - ValReprInfo(tpNames@ValReprInfo.InferTyparInfo copyOfTyconTypars, args, ret) - - let prelimTyschemeG = TypeScheme(copyOfTyconTypars@tps, memberTauTy) - let memberValScheme = ValScheme(id, prelimTyschemeG, Some topValInfo, Some memberInfo, false, ValInline.Never, NormalVal, None, true (* isCompilerGenerated *), true (* isIncrClass *), false, false) - let methodVal = MakeAndPublishVal cenv env (Parent tcref, false, ModuleOrMemberBinding, ValNotInRecScope, memberValScheme, v.Attribs, XmlDoc.Empty, None, false) - reportIfUnused() - InMethod(isStatic, methodVal, topValInfo) - - repr, takenFieldNames - - /// Extend the known local representations by choosing a representation for a binding - member localRep.ChooseAndAddRepresentation(cenv, env: TcEnv, isStatic, isCtorArg, ctorInfo: IncrClassCtorLhs, staticForcedFieldVars: FreeLocals, instanceForcedFieldVars: FreeLocals, bind: Binding) = - let v = bind.Var - let repr, takenFieldNames = localRep.ChooseRepresentation (cenv, env, isStatic, isCtorArg, ctorInfo, staticForcedFieldVars, instanceForcedFieldVars, localRep.TakenFieldNames, bind ) - // OK, representation chosen, now add it - {localRep with - TakenFieldNames=takenFieldNames - ValReprs = Zmap.add v repr localRep.ValReprs} - - member localRep.ValNowWithRepresentation (v: Val) = - {localRep with ValsWithRepresentation = Zset.add v localRep.ValsWithRepresentation} - - member localRep.IsValWithRepresentation (v: Val) = - localRep.ValsWithRepresentation.Contains v - - member localRep.IsValRepresentedAsLocalVar (v: Val) = - match localRep.LookupRepr v with - | InVar false -> true - | _ -> false - - member localRep.IsValRepresentedAsMethod (v: Val) = - localRep.IsValWithRepresentation v && - match localRep.LookupRepr v with - | InMethod _ -> true - | _ -> false - - /// Make the elaborated expression that represents a use of a - /// a "let v = ..." class binding - member localRep.MakeValueLookup thisValOpt tinst safeStaticInitInfo v tyargs m = - let g = localRep.RepInfoTcGlobals - match localRep.LookupRepr v, thisValOpt with - | InVar _, _ -> - exprForVal m v - | InField(false, _idx, rfref), Some thisVal -> - let thise = exprForVal m thisVal - mkRecdFieldGetViaExprAddr (thise, rfref, tinst, m) - | InField(false, _idx, _rfref), None -> - error(InternalError("Unexpected missing 'this' variable in MakeValueLookup", m)) - | InField(true, idx, rfref), _ -> - let expr = mkStaticRecdFieldGet (rfref, tinst, m) - MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr - - | InMethod(isStatic, methodVal, topValInfo), _ -> - //dprintfn "Rewriting application of %s to be call to method %s" v.LogicalName methodVal.LogicalName - let expr, exprty = AdjustValForExpectedArity g m (mkLocalValRef methodVal) NormalValUse topValInfo - // Prepend the the type arguments for the class - let tyargs = tinst @ tyargs - let thisArgs = - if isStatic then [] - else Option.toList (Option.map (exprForVal m) thisValOpt) - - MakeApplicationAndBetaReduce g (expr, exprty, [tyargs], thisArgs, m) - - /// Make the elaborated expression that represents an assignment - /// to a "let mutable v = ..." class binding - member localRep.MakeValueAssign thisValOpt tinst safeStaticInitInfo v expr m = - let g = localRep.RepInfoTcGlobals - match localRep.LookupRepr v, thisValOpt with - | InField(false, _, rfref), Some thisVal -> - let thise = exprForVal m thisVal - mkRecdFieldSetViaExprAddr(thise, rfref, tinst, expr, m) - | InField(false, _, _rfref), None -> - error(InternalError("Unexpected missing 'this' variable in MakeValueAssign", m)) - | InVar _, _ -> - mkValSet m (mkLocalValRef v) expr - | InField (true, idx, rfref), _ -> - let expr = mkStaticRecdFieldSet(rfref, tinst, expr, m) - MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr - | InMethod _, _ -> - error(InternalError("Local was given method storage, yet later it's been assigned to", m)) - - member localRep.MakeValueGetAddress readonly thisValOpt tinst safeStaticInitInfo v m = - let g = localRep.RepInfoTcGlobals - match localRep.LookupRepr v, thisValOpt with - | InField(false, _, rfref), Some thisVal -> - let thise = exprForVal m thisVal - mkRecdFieldGetAddrViaExprAddr(readonly, thise, rfref, tinst, m) - | InField(false, _, _rfref), None -> - error(InternalError("Unexpected missing 'this' variable in MakeValueGetAddress", m)) - | InField(true, idx, rfref), _ -> - let expr = mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m) - MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr - | InVar _, _ -> - mkValAddr m readonly (mkLocalValRef v) - | InMethod _, _ -> - error(InternalError("Local was given method storage, yet later it's address was required", m)) - - /// Mutate a type definition by adding fields - /// Used as part of processing "let" bindings in a type definition. - member localRep.PublishIncrClassFields (cenv, denv, cpath, ctorInfo: IncrClassCtorLhs, safeStaticInitInfo) = - let tcref = ctorInfo.TyconRef - let rfspecs = - [ for KeyValue(v, repr) in localRep.ValReprs do - match repr with - | InField(isStatic, _, rfref) -> - // Instance fields for structs are published earlier because the full set of fields is determined syntactically from the implicit - // constructor arguments. This is important for the "default value" and "does it have an implicit default constructor" - // semantic conditions for structs - see bug FSharp 1.0 5304. - if isStatic || not tcref.IsFSharpStructOrEnumTycon then - let ctorDeclaredTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv denv ctorInfo.TyconRef.Range - - // Note: tcrefObjTy contains the original "formal" typars, thisTy is the "fresh" one... f<>fresh. - let revTypeInst = List.zip ctorDeclaredTypars (tcref.TyparsNoRange |> List.map mkTyparTy) - - yield MakeIncrClassField(localRep.RepInfoTcGlobals, cpath, revTypeInst, v, isStatic, rfref) - | _ -> - () - match safeStaticInitInfo with - | SafeInitField (_, fld) -> yield fld - | NoSafeInitInfo -> () ] - - let recdFields = MakeRecdFieldsTable (rfspecs @ tcref.AllFieldsAsList) - - // Mutate the entity_tycon_repr to publish the fields - tcref.Deref.entity_tycon_repr <- TFSharpObjectRepr { tcref.FSharpObjectModelTypeInfo with fsobjmodel_rfields = recdFields} - - - /// Given localRep saying how locals have been represented, e.g. as fields. - /// Given an expr under a given thisVal context. - // - /// Fix up the references to the locals, e.g. - /// v -> this.fieldv - /// f x -> this.method x - member localRep.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo (thisTyInst: TypeInst) expr = - // fixup: intercept and expr rewrite - let FixupExprNode rw e = - //dprintfn "Fixup %s" (showL (exprL e)) - let g = localRep.RepInfoTcGlobals - let e = NormalizeAndAdjustPossibleSubsumptionExprs g e - match e with - // Rewrite references to applied let-bound-functions-compiled-as-methods - // Rewrite references to applied recursive let-bound-functions-compiled-as-methods - // Rewrite references to applied recursive generic let-bound-functions-compiled-as-methods - | Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, args, m) - | Expr.App (Expr.Link {contents = Expr.Val (ValDeref v, _, _) }, _, tyargs, args, m) - | Expr.App (Expr.Link {contents = Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, [], _) }, _, [], args, m) - when localRep.IsValRepresentedAsMethod v && not (cenv.recUses.ContainsKey v) -> - - let expr = localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v tyargs m - let args = args |> List.map rw - Some (MakeApplicationAndBetaReduce g (expr, (tyOfExpr g expr), [], args, m)) - - // Rewrite references to values stored as fields and first class uses of method values - | Expr.Val (ValDeref v, _, m) - when localRep.IsValWithRepresentation v -> - - //dprintfn "Found use of %s" v.LogicalName - Some (localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v [] m) - - // Rewrite assignments to mutable values stored as fields - | Expr.Op (TOp.LValueOp (LSet, ValDeref v), [], [arg], m) - when localRep.IsValWithRepresentation v -> - let arg = rw arg - Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m) - - // Rewrite taking the address of mutable values stored as fields - | Expr.Op (TOp.LValueOp (LAddrOf readonly, ValDeref v), [], [], m) - when localRep.IsValWithRepresentation v -> - Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m) - - | _ -> None - Tastops.RewriteExpr { PreIntercept = Some FixupExprNode - PostTransform = (fun _ -> None) - PreInterceptBinding = None - IsUnderQuotations=true } expr - - - type IncrClassConstructionBindingsPhase2C = - | Phase2CBindings of IncrClassBindingGroup list - | Phase2CCtorJustAfterSuperInit - | Phase2CCtorJustAfterLastLet - - /// Given a set of 'let' bindings (static or not, recursive or not) that make up a class, - /// generate their initialization expression(s). - let MakeCtorForIncrClassConstructionPhase2C - (cenv, - env: TcEnv, - /// The lhs information about the implicit constructor - ctorInfo: IncrClassCtorLhs, - /// The call to the super class constructor - inheritsExpr, - /// Should we place a sequence point at the 'inheritedTys call? - inheritsIsVisible, - /// The declarations - decs: IncrClassConstructionBindingsPhase2C list, - memberBinds: Binding list, - /// Record any unconstrained type parameters generalized for the outer members as "free choices" in the let bindings - generalizedTyparsForRecursiveBlock, - safeStaticInitInfo: SafeInitData) = - - - let denv = env.DisplayEnv - let g = cenv.g - let thisVal = ctorInfo.InstanceCtorThisVal - - let m = thisVal.Range - let ctorDeclaredTypars = ctorInfo.GetNormalizedInstanceCtorDeclaredTypars cenv denv m - - ctorDeclaredTypars |> List.iter (SetTyparRigid g env.DisplayEnv m) - - // Reconstitute the type with the correct quantified type variables. - ctorInfo.InstanceCtorVal.SetType (mkForallTyIfNeeded ctorDeclaredTypars ctorInfo.InstanceCtorVal.TauType) - - let freeChoiceTypars = ListSet.subtract typarEq generalizedTyparsForRecursiveBlock ctorDeclaredTypars - - let thisTyInst = List.map mkTyparTy ctorDeclaredTypars - - let accFreeInExpr acc expr = - unionFreeVars acc (freeInExpr CollectLocalsNoCaching expr) - - let accFreeInBinding acc (bind: Binding) = - accFreeInExpr acc bind.Expr - - let accFreeInBindings acc (binds: Binding list) = - (acc, binds) ||> List.fold accFreeInBinding - - // Find all the variables used in any method. These become fields. - // staticForcedFieldVars: FreeLocals: the vars forced to be fields due to static member bindings, instance initialization expressions or instance member bindings - // instanceForcedFieldVars: FreeLocals: the vars forced to be fields due to instance member bindings - - let staticForcedFieldVars, instanceForcedFieldVars = - let (staticForcedFieldVars, instanceForcedFieldVars) = - ((emptyFreeVars, emptyFreeVars), decs) ||> List.fold (fun (staticForcedFieldVars, instanceForcedFieldVars) dec -> - match dec with - | Phase2CCtorJustAfterLastLet - | Phase2CCtorJustAfterSuperInit -> - (staticForcedFieldVars, instanceForcedFieldVars) - | Phase2CBindings decs -> - ((staticForcedFieldVars, instanceForcedFieldVars), decs) ||> List.fold (fun (staticForcedFieldVars, instanceForcedFieldVars) dec -> - match dec with - | IncrClassBindingGroup(binds, isStatic, _) -> - let methodBinds = binds |> List.filter (IncrClassReprInfo.IsMethodRepr cenv) - let staticForcedFieldVars = - if isStatic then - // Any references to static variables in any static method force the variable to be represented as a field - (staticForcedFieldVars, methodBinds) ||> accFreeInBindings - else - // Any references to static variables in any instance bindings force the variable to be represented as a field - (staticForcedFieldVars, binds) ||> accFreeInBindings - - let instanceForcedFieldVars = - // Any references to instance variables in any methods force the variable to be represented as a field - (instanceForcedFieldVars, methodBinds) ||> accFreeInBindings - - (staticForcedFieldVars, instanceForcedFieldVars) - | IncrClassDo (e, isStatic) -> - let staticForcedFieldVars = - if isStatic then - staticForcedFieldVars - else - unionFreeVars staticForcedFieldVars (freeInExpr CollectLocalsNoCaching e) - (staticForcedFieldVars, instanceForcedFieldVars))) - let staticForcedFieldVars = (staticForcedFieldVars, memberBinds) ||> accFreeInBindings - let instanceForcedFieldVars = (instanceForcedFieldVars, memberBinds) ||> accFreeInBindings - - // Any references to static variables in the 'inherits' expression force those static variables to be represented as fields - let staticForcedFieldVars = (staticForcedFieldVars, inheritsExpr) ||> accFreeInExpr - - (staticForcedFieldVars.FreeLocals, instanceForcedFieldVars.FreeLocals) - - - // Compute the implicit construction side effects of single - // 'let' or 'let rec' binding in the implicit class construction sequence - let TransBind (reps: IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) = - if v.MustInline then - error(Error(FSComp.SR.tcLocalClassBindingsCannotBeInline(), v.Range)) - let rhsExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst rhsExpr - - // The initialization of the 'ref cell' variable for 'this' is the only binding which comes prior to the super init - let isPriorToSuperInit = - match ctorInfo.InstanceCtorSafeThisValOpt with - | None -> false - | Some v2 -> valEq v v2 - - match reps.LookupRepr v with - | InMethod(isStatic, methodVal, _) -> - let _, chooseTps, tauExpr, tauTy, m = - match rhsExpr with - | Expr.TyChoose (chooseTps, b, _) -> [], chooseTps, b, (tyOfExpr g b), m - | Expr.TyLambda (_, tps, Expr.TyChoose (chooseTps, b, _), m, returnTy) -> tps, chooseTps, b, returnTy, m - | Expr.TyLambda (_, tps, b, m, returnTy) -> tps, [], b, returnTy, m - | e -> [], [], e, (tyOfExpr g e), e.Range - - let chooseTps = chooseTps @ (ListSet.subtract typarEq freeChoiceTypars methodVal.Typars) - - // Add the 'this' variable as an argument - let tauExpr, tauTy = - if isStatic then - tauExpr, tauTy - else - let e = mkLambda m thisVal (tauExpr, tauTy) - e, tyOfExpr g e - - // Replace the type parameters that used to be on the rhs with - // the full set of type parameters including the type parameters of the enclosing class - let rhsExpr = mkTypeLambda m methodVal.Typars (mkTypeChoose m chooseTps tauExpr, tauTy) - (isPriorToSuperInit, (fun e -> e)), [TBind (methodVal, rhsExpr, spBind)] - - // If it's represented as a non-escaping local variable then just bind it to its value - // If it's represented as a non-escaping local arg then no binding necessary (ctor args are already bound) - - | InVar isArg -> - (isPriorToSuperInit, (fun e -> if isArg then e else mkLetBind m (TBind(v, rhsExpr, spBind)) e)), [] - - | InField (isStatic, idx, _) -> - // Use spBind if it available as the span for the assignment into the field - let m = - match spBind, rhsExpr with - // Don't generate big sequence points for functions in classes - | _, (Expr.Lambda _ | Expr.TyLambda _) -> v.Range - | SequencePointAtBinding m, _ -> m - | _ -> v.Range - let assignExpr = reps.MakeValueAssign (Some thisVal) thisTyInst NoSafeInitInfo v rhsExpr m - let adjustSafeInitFieldExprOpt = - if isStatic then - match safeStaticInitInfo with - | SafeInitField (rfref, _) -> - let setExpr = mkStaticRecdFieldSet (rfref, thisTyInst, mkInt g m idx, m) - let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) NoSafeInitInfo thisTyInst setExpr - Some setExpr - | NoSafeInitInfo -> - None - else - None - - (isPriorToSuperInit, (fun e -> - let e = match adjustSafeInitFieldExprOpt with None -> e | Some ae -> mkCompGenSequential m ae e - mkSequential SequencePointsAtSeq m assignExpr e)), [] - - /// Work out the implicit construction side effects of a 'let', 'let rec' or 'do' - /// binding in the implicit class construction sequence - let TransTrueDec isCtorArg (reps: IncrClassReprInfo) dec = - match dec with - | (IncrClassBindingGroup(binds, isStatic, isRec)) -> - let actions, reps, methodBinds = - let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ChooseAndAddRepresentation(cenv, env, isStatic, isCtorArg, ctorInfo, staticForcedFieldVars, instanceForcedFieldVars, bind)) // extend - if isRec then - // Note: the recursive calls are made via members on the object - // or via access to fields. This means the recursive loop is "broken", - // and we can collapse to sequential bindings - let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ValNowWithRepresentation bind.Var) // in scope before - let actions, methodBinds = binds |> List.map (TransBind reps) |> List.unzip // since can occur in RHS of own defns - actions, reps, methodBinds - else - let actions, methodBinds = binds |> List.map (TransBind reps) |> List.unzip - let reps = (reps, binds) ||> List.fold (fun rep bind -> rep.ValNowWithRepresentation bind.Var) // in scope after - actions, reps, methodBinds - let methodBinds = List.concat methodBinds - if isStatic then - (actions, [], methodBinds), reps - else - ([], actions, methodBinds), reps - - | IncrClassDo (doExpr, isStatic) -> - let doExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst doExpr - let binder = (fun e -> mkSequential SequencePointsAtSeq doExpr.Range doExpr e) - let isPriorToSuperInit = false - if isStatic then - ([(isPriorToSuperInit, binder)], [], []), reps - else - ([], [(isPriorToSuperInit, binder)], []), reps - - - /// Work out the implicit construction side effects of each declaration - /// in the implicit class construction sequence - let TransDec (reps: IncrClassReprInfo) dec = - match dec with - // The call to the base class constructor is done so we can set the ref cell - | Phase2CCtorJustAfterSuperInit -> - let binders = - [ match ctorInfo.InstanceCtorSafeThisValOpt with - | None -> () - | Some v -> - let setExpr = mkRefCellSet g m ctorInfo.InstanceCtorThisVal.Type (exprForVal m v) (exprForVal m ctorInfo.InstanceCtorThisVal) - let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst setExpr - let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e) - let isPriorToSuperInit = false - yield (isPriorToSuperInit, binder) ] - - ([], binders, []), reps - - // The last 'let' binding is done so we can set the initialization condition for the collection of object fields - // which now allows members to be called. - | Phase2CCtorJustAfterLastLet -> - let binders = - [ match ctorInfo.InstanceCtorSafeInitInfo with - | SafeInitField (rfref, _) -> - let setExpr = mkRecdFieldSetViaExprAddr (exprForVal m thisVal, rfref, thisTyInst, mkOne g m, m) - let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst setExpr - let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e) - let isPriorToSuperInit = false - yield (isPriorToSuperInit, binder) - | NoSafeInitInfo -> - () ] - - ([], binders, []), reps - - | Phase2CBindings decs -> - let initActions, reps = List.mapFold (TransTrueDec false) reps decs - let cctorInitActions, ctorInitActions, methodBinds = List.unzip3 initActions - (List.concat cctorInitActions, List.concat ctorInitActions, List.concat methodBinds), reps - - - - let takenFieldNames = - [ for b in memberBinds do - yield b.Var.CompiledName cenv.g.CompilerGlobalState - yield b.Var.DisplayName - yield b.Var.CoreDisplayName - yield b.Var.LogicalName ] - let reps = IncrClassReprInfo.Empty(g, takenFieldNames) - - // Bind the IsArg(true) representations of the object constructor arguments and assign them to fields - // if they escape to the members. We do this by running the instance bindings 'let x = x' through TransTrueDec - // for each constructor argument 'x', but with the special flag 'isCtorArg', which helps TransBind know that - // the value is already available as an argument, and that nothing special needs to be done unless the - // value is being stored into a field. - let (cctorInitActions1, ctorInitActions1, methodBinds1), reps = - let binds = ctorInfo.InstanceCtorArgs |> List.map (fun v -> mkInvisibleBind v (exprForVal v.Range v)) - TransTrueDec true reps (IncrClassBindingGroup(binds, false, false)) - - // We expect that only ctorInitActions1 will be non-empty here, and even then only if some elements are stored in the field - assert (isNil cctorInitActions1) - assert (isNil methodBinds1) - - // Now deal with all the 'let' and 'member' declarations - let initActions, reps = List.mapFold TransDec reps decs - let cctorInitActions2, ctorInitActions2, methodBinds2 = List.unzip3 initActions - let cctorInitActions = cctorInitActions1 @ List.concat cctorInitActions2 - let ctorInitActions = ctorInitActions1 @ List.concat ctorInitActions2 - let methodBinds = methodBinds1 @ List.concat methodBinds2 - - let ctorBody = - // Build the elements of the implicit constructor body, starting from the bottom - // - // - // - // return () - let ctorInitActionsPre, ctorInitActionsPost = ctorInitActions |> List.partition (fun (isPriorToSuperInit, _) -> isPriorToSuperInit) - - // This is the return result - let ctorBody = mkUnit g m - - // Add . - // That is, add any that come prior to the super init constructor call, - // This is only ever at most the init of the InstanceCtorSafeThisValOpt and InstanceCtorSafeInitInfo var/field - let ctorBody = List.foldBack (fun (_, binder) acc -> binder acc) ctorInitActionsPost ctorBody - - // Add the - let ctorBody = - // The inheritsExpr may refer to the this variable or to incoming arguments, e.g. in closure fields. - // References to the this variable go via the ref cell that gets created to help ensure coherent initialization. - // This ref cell itself may be stored in a field of the object and accessed via arg0. - // Likewise the incoming arguments will eventually be stored in fields and accessed via arg0. - // - // As a result, the most natural way to implement this would be to simply capture arg0 if needed - // and access all variables via that. This would be done by rewriting the inheritsExpr as follows: - // let inheritsExpr = reps.FixupIncrClassExprPhase2C (Some thisVal) thisTyInst inheritsExpr - // However, the rules of IL mean we are not actually allowed to capture arg0 - // and store it as a closure field before the base class constructor is called. - // - // As a result we do not rewrite the inheritsExpr and instead - // (a) wrap a let binding for the ref cell around the inheritsExpr if needed - // (b) rely on the fact that the input arguments are in scope and can be accessed from as argument variables - // (c) rely on the fact that there are no 'let' bindings prior to the inherits expr. - let inheritsExpr = - match ctorInfo.InstanceCtorSafeThisValOpt with - | Some v when not (reps.IsValRepresentedAsLocalVar v) -> - // Rewrite the expression to convert it to a load of a field if needed. - // We are allowed to load fields from our own object even though we haven't called - // the super class constructor yet. - let ldexpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst (exprForVal m v) - mkInvisibleLet m v ldexpr inheritsExpr - | _ -> - inheritsExpr - - let spAtSuperInit = (if inheritsIsVisible then SequencePointsAtSeq else SuppressSequencePointOnExprOfSequential) - mkSequential spAtSuperInit m inheritsExpr ctorBody - - // Add the normal - let ctorBody = List.foldBack (fun (_, binder) acc -> binder acc) ctorInitActionsPre ctorBody - - // Add the final wrapping to make this into a method - let ctorBody = mkMemberLambdas m [] (Some thisVal) ctorInfo.InstanceCtorBaseValOpt [ctorInfo.InstanceCtorArgs] (ctorBody, g.unit_ty) - - ctorBody - - let cctorBodyOpt = - /// Omit the .cctor if it's empty - match cctorInitActions with - | [] -> None - | _ -> - let cctorInitAction = List.foldBack (fun (_, binder) acc -> binder acc) cctorInitActions (mkUnit g m) - let m = thisVal.Range - let cctorArgs, cctorVal, _ = ctorInfo.StaticCtorValInfo.Force() - // Reconstitute the type of the implicit class constructor with the correct quantified type variables. - cctorVal.SetType (mkForallTyIfNeeded ctorDeclaredTypars cctorVal.TauType) - let cctorBody = mkMemberLambdas m [] None None [cctorArgs] (cctorInitAction, g.unit_ty) - Some cctorBody - - ctorBody, cctorBodyOpt, methodBinds, reps - - - - -// Checking of mutually recursive types, members and 'let' bindings in classes -// -// Technique: multiple passes. -// Phase1: create and establish type definitions and core representation information -// Phase2A: create Vals for recursive items given names and args -// Phase2B-D: type check AST to TAST collecting (sufficient) type constraints, -// generalize definitions, fix up recursive instances, build ctor binding -module MutRecBindingChecking = - - open IncrClassChecking - - /// Represents one element in a type definition, after the first phase - type TyconBindingPhase2A = - /// An entry corresponding to the definition of the implicit constructor for a class - | Phase2AIncrClassCtor of IncrClassCtorLhs - /// An 'inherit' declaration in an incremental class - /// - /// Phase2AInherit (ty, arg, baseValOpt, m) - | Phase2AInherit of SynType * SynExpr * Val option * range - /// A set of value or function definitions in an incremental class - /// - /// Phase2AIncrClassBindings (tcref, letBinds, isStatic, isRec, m) - | Phase2AIncrClassBindings of TyconRef * Ast.SynBinding list * bool * bool * range - /// A 'member' definition in a class - | Phase2AMember of PreCheckingRecursiveBinding -#if OPEN_IN_TYPE_DECLARATIONS - /// A dummy declaration, should we ever support 'open' in type definitions - | Phase2AOpen of LongIdent * range -#endif - /// Indicates the super init has just been called, 'this' may now be published - | Phase2AIncrClassCtorJustAfterSuperInit - /// Indicates the last 'field' has been initialized, only 'do' comes after - | Phase2AIncrClassCtorJustAfterLastLet - - /// The collected syntactic input definitions for a single type or type-extension definition - type TyconBindingsPhase2A = - | TyconBindingsPhase2A of Tycon option * DeclKind * Val list * TyconRef * Typar list * TType * TyconBindingPhase2A list - - /// The collected syntactic input definitions for a recursive group of type or type-extension definitions - type MutRecDefnsPhase2AData = MutRecShape list - - /// Represents one element in a type definition, after the second phase - type TyconBindingPhase2B = - | Phase2BIncrClassCtor of IncrClassCtorLhs * Tast.Binding option - | Phase2BInherit of Expr * Val option - /// A set of value of function definitions in a class definition with an implicit constructor. - | Phase2BIncrClassBindings of IncrClassBindingGroup list - | Phase2BMember of int - /// An intermediate definition that represent the point in an implicit class definition where - /// the super type has been initialized. - | Phase2BIncrClassCtorJustAfterSuperInit - /// An intermediate definition that represent the point in an implicit class definition where - /// the last 'field' has been initialized, i.e. only 'do' and 'member' definitions come after - /// this point. - | Phase2BIncrClassCtorJustAfterLastLet - - type TyconBindingsPhase2B = TyconBindingsPhase2B of Tycon option * TyconRef * TyconBindingPhase2B list - - type MutRecDefnsPhase2BData = MutRecShape list - - /// Represents one element in a type definition, after the third phase - type TyconBindingPhase2C = - | Phase2CIncrClassCtor of IncrClassCtorLhs * Tast.Binding option - | Phase2CInherit of Expr * Val option - | Phase2CIncrClassBindings of IncrClassBindingGroup list - | Phase2CMember of PreInitializationGraphEliminationBinding - // Indicates the last 'field' has been initialized, only 'do' comes after - | Phase2CIncrClassCtorJustAfterSuperInit - | Phase2CIncrClassCtorJustAfterLastLet - - type TyconBindingsPhase2C = TyconBindingsPhase2C of Tycon option * TyconRef * TyconBindingPhase2C list - - type MutRecDefnsPhase2CData = MutRecShape list - - - - // Phase2A: create member prelimRecValues for "recursive" items, i.e. ctor val and member vals - // Phase2A: also processes their arg patterns - collecting type assertions - let TcMutRecBindings_Phase2A_CreateRecursiveValuesAndCheckArgumentPatterns cenv tpenv (envMutRec, mutRecDefns: MutRecDefnsPhase2Info) = - let g = cenv.g - - // The basic iteration over the declarations in a single type definition - // State: - // tpenv: floating type parameter environment - // recBindIdx: index of the recursive binding - // prelimRecValuesRev: accumulation of prelim value entries - // uncheckedBindsRev: accumulation of unchecked bindings - let (defnsAs: MutRecDefnsPhase2AData), (tpenv, _, uncheckedBindsRev) = - let initialOuterState = (tpenv, 0, ([]: PreCheckingRecursiveBinding list)) - (initialOuterState, envMutRec, mutRecDefns) |||> MutRecShapes.mapFoldWithEnv (fun outerState envForDecls defn -> - let (tpenv, recBindIdx, uncheckedBindsRev) = outerState - match defn with - | MutRecShape.Module _ -> failwith "unreachable" - | MutRecShape.Open x -> MutRecShape.Open x, outerState - | MutRecShape.ModuleAbbrev x -> MutRecShape.ModuleAbbrev x, outerState - | MutRecShape.Lets recBinds -> - let normRecDefns = - [ for (RecDefnBindingInfo(a, b, c, bind)) in recBinds do - yield NormalizedRecBindingDefn(a, b, c, BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForDecls bind) ] - let bindsAndValues, (tpenv, recBindIdx) = ((tpenv, recBindIdx), normRecDefns) ||> List.mapFold (AnalyzeAndMakeAndPublishRecursiveValue ErrorOnOverrides false cenv envForDecls) - let binds = bindsAndValues |> List.collect fst - - let defnAs = MutRecShape.Lets binds - defnAs, (tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev) - - | MutRecShape.Tycon (MutRecDefnsPhase2InfoForTycon(tyconOpt, tcref, declaredTyconTypars, declKind, binds, _)) -> - - // Class members can access protected members of the implemented type - // Class members can access private members in the ty - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let initialEnvForTycon = MakeInnerEnvForTyconRef envForDecls tcref isExtrinsic - - // Re-add the type constructor to make it take precedence for record label field resolutions - // This does not apply to extension members: in those cases the relationship between the record labels - // and the type is too extruded - let envForTycon = - if isExtrinsic then - initialEnvForTycon - else - AddLocalTyconRefs true g cenv.amap tcref.Range [tcref] initialEnvForTycon - - // Make fresh version of the class type for type checking the members and lets * - let _, copyOfTyconTypars, _, objTy, thisTy = FreshenObjectArgType cenv tcref.Range TyparRigidity.WillBeRigid tcref isExtrinsic declaredTyconTypars - - - // The basic iteration over the declarations in a single type definition - let initialInnerState = (None, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) - let defnAs, (_, _envForTycon, tpenv, recBindIdx, uncheckedBindsRev) = - - (initialInnerState, binds) ||> List.collectFold (fun innerState defn -> - - let (TyconBindingDefn(containerInfo, newslotsOK, declKind, classMemberDef, m)) = defn - let (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) = innerState - - if tcref.IsTypeAbbrev then - // ideally we'd have the 'm' of the type declaration stored here, to avoid needing to trim to line to approx - error(Error(FSComp.SR.tcTypeAbbreviationsMayNotHaveMembers(), (trimRangeToLine m))) - - if tcref.IsEnumTycon && (declKind <> ExtrinsicExtensionBinding) then - // ideally we'd have the 'm' of the type declaration stored here, to avoid needing to trim to line to approx - error(Error(FSComp.SR.tcEnumerationsMayNotHaveMembers(), (trimRangeToLine m))) - - match classMemberDef, containerInfo with - | SynMemberDefn.ImplicitCtor (vis, Attributes attrs, SynSimplePats.SimplePats(spats, _), thisIdOpt, m), ContainerInfo(_, Some(MemberOrValContainerInfo(tcref, _, baseValOpt, safeInitInfo, _))) -> - if tcref.TypeOrMeasureKind = TyparKind.Measure then - error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) - - // Phase2A: make incrClassCtorLhs - ctorv, thisVal etc, type depends on argty(s) - let incrClassCtorLhs = TcImplicitCtorLhs_Phase2A(cenv, envForTycon, tpenv, tcref, vis, attrs, spats, thisIdOpt, baseValOpt, safeInitInfo, m, copyOfTyconTypars, objTy, thisTy) - // Phase2A: Add copyOfTyconTypars from incrClassCtorLhs - or from tcref - let envForTycon = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envForTycon - let innerState = (Some incrClassCtorLhs, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) - - [Phase2AIncrClassCtor incrClassCtorLhs], innerState - - | SynMemberDefn.ImplicitInherit (ty, arg, _baseIdOpt, m), _ -> - if tcref.TypeOrMeasureKind = TyparKind.Measure then - error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) - - // Phase2A: inherit ty(arg) as base - pass through - // Phase2A: pick up baseValOpt! - let baseValOpt = incrClassCtorLhsOpt |> Option.bind (fun x -> x.InstanceCtorBaseValOpt) - let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) - [Phase2AInherit (ty, arg, baseValOpt, m); Phase2AIncrClassCtorJustAfterSuperInit], innerState - - | SynMemberDefn.LetBindings (letBinds, isStatic, isRec, m), _ -> - match tcref.TypeOrMeasureKind, isStatic with - | TyparKind.Measure, false -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) - | _ -> () - - if not isStatic && tcref.IsStructOrEnumTycon then - let allDo = letBinds |> List.forall (function (Binding(_, DoBinding, _, _, _, _, _, _, _, _, _, _)) -> true | _ -> false) - // Code for potential future design change to allow functions-compiled-as-members in structs - if allDo then - errorR(Deprecated(FSComp.SR.tcStructsMayNotContainDoBindings(), (trimRangeToLine m))) - else - // Code for potential future design change to allow functions-compiled-as-members in structs - errorR(Error(FSComp.SR.tcStructsMayNotContainLetBindings(), (trimRangeToLine m))) - - if isStatic && Option.isNone incrClassCtorLhsOpt then - errorR(Error(FSComp.SR.tcStaticLetBindingsRequireClassesWithImplicitConstructors(), m)) - - // Phase2A: let-bindings - pass through - let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, uncheckedBindsRev) - [Phase2AIncrClassBindings (tcref, letBinds, isStatic, isRec, m)], innerState - - | SynMemberDefn.Member (bind, m), _ -> - // Phase2A: member binding - create prelim valspec (for recursive reference) and RecursiveBindingInfo - let (NormalizedBinding(_, _, _, _, _, _, _, valSynData, _, _, _, _)) as bind = BindingNormalization.NormalizeBinding ValOrMemberBinding cenv envForTycon bind - let (SynValData(memberFlagsOpt, _, _)) = valSynData - match tcref.TypeOrMeasureKind with - | TyparKind.Type -> () - | TyparKind.Measure -> - match memberFlagsOpt with - | None -> () - | Some memberFlags -> - if memberFlags.IsInstance then error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembers(), m)) - match memberFlags.MemberKind with - | MemberKind.Constructor -> error(Error(FSComp.SR.tcMeasureDeclarationsRequireStaticMembersNotConstructors(), m)) - | _ -> () - let rbind = NormalizedRecBindingDefn(containerInfo, newslotsOK, declKind, bind) - let overridesOK = DeclKind.CanOverrideOrImplement declKind - let (binds, _values), (tpenv, recBindIdx) = AnalyzeAndMakeAndPublishRecursiveValue overridesOK false cenv envForTycon (tpenv, recBindIdx) rbind - let cbinds = [ for rbind in binds -> Phase2AMember rbind ] - - let innerState = (incrClassCtorLhsOpt, envForTycon, tpenv, recBindIdx, List.rev binds @ uncheckedBindsRev) - cbinds, innerState - -#if OPEN_IN_TYPE_DECLARATIONS - | SynMemberDefn.Open (mp, m), _ -> - let innerState = (incrClassCtorLhsOpt, env, tpenv, recBindIdx, prelimRecValuesRev, uncheckedBindsRev) - [ Phase2AOpen (mp, m) ], innerState -#endif - - | definition -> - error(InternalError(sprintf "Unexpected definition %A" definition, m))) - - // If no constructor call, insert Phase2AIncrClassCtorJustAfterSuperInit at start - let defnAs = - match defnAs with - | (Phase2AIncrClassCtor _ as b1) :: rest -> - let rest = - if rest |> List.exists (function Phase2AIncrClassCtorJustAfterSuperInit -> true | _ -> false) then - rest - else - Phase2AIncrClassCtorJustAfterSuperInit :: rest - // Insert Phase2AIncrClassCtorJustAfterLastLet at the point where local construction is known to have been finished - let rest = - let isAfter b = - match b with -#if OPEN_IN_TYPE_DECLARATIONS - | Phase2AOpen _ -#endif - | Phase2AIncrClassCtor _ | Phase2AInherit _ | Phase2AIncrClassCtorJustAfterSuperInit -> false - | Phase2AIncrClassBindings (_, binds, _, _, _) -> binds |> List.exists (function (Binding (_, DoBinding, _, _, _, _, _, _, _, _, _, _)) -> true | _ -> false) - | Phase2AIncrClassCtorJustAfterLastLet - | Phase2AMember _ -> true - let restRev = List.rev rest - let afterRev = restRev |> List.takeWhile isAfter - let beforeRev = restRev |> List.skipWhile isAfter - - [ yield! List.rev beforeRev - yield Phase2AIncrClassCtorJustAfterLastLet - yield! List.rev afterRev ] - b1 :: rest - - // Cover the case where this is not a type with an implicit constructor. - | rest -> rest - - let prelimRecValues = [ for x in defnAs do match x with Phase2AMember bind -> yield bind.RecBindingInfo.Val | _ -> () ] - let defnAs = MutRecShape.Tycon(TyconBindingsPhase2A(tyconOpt, declKind, prelimRecValues, tcref, copyOfTyconTypars, thisTy, defnAs)) - defnAs, (tpenv, recBindIdx, uncheckedBindsRev)) - - let uncheckedRecBinds = List.rev uncheckedBindsRev - - (defnsAs, uncheckedRecBinds, tpenv) - - /// Phase2B: check each of the bindings, convert from ast to tast and collects type assertions. - /// Also generalize incrementally. - let TcMutRecBindings_Phase2B_TypeCheckAndIncrementalGeneralization cenv tpenv envInitial (envMutRec, defnsAs: MutRecDefnsPhase2AData, uncheckedRecBinds: PreCheckingRecursiveBinding list, scopem) : MutRecDefnsPhase2BData * _ * _ = - let g = cenv.g - - let (defnsBs: MutRecDefnsPhase2BData), (tpenv, generalizedRecBinds, preGeneralizationRecBinds, _, _) = - - let uncheckedRecBindsTable = uncheckedRecBinds |> List.map (fun rbind -> rbind.RecBindingInfo.Val.Stamp, rbind) |> Map.ofList - - // Loop through the types being defined... - // - // The envNonRec is the environment used to limit generalization to prevent leakage of type - // variables into the types of 'let' bindings. It gets accumulated across type definitions, e.g. - // consider - // - // type A<'T>() = - // let someFuncValue: 'A = A<'T>.Meth2() - // static member Meth2() = A<'T>.Meth2() - // and B<'T>() = - // static member Meth1() = A<'T>.Meth2() - // - // Here 'A can't be generalized, even at 'Meth1'. - // - // The envForTycon is the environment used for name resolution within the let and member bindings - // of the type definition. This becomes 'envStatic' and 'envInstance' for the two - - let initialOuterState = (tpenv, ([]: PostGeneralizationRecursiveBinding list), ([]: PreGeneralizationRecursiveBinding list), uncheckedRecBindsTable, envInitial) - - (initialOuterState, envMutRec, defnsAs) |||> MutRecShapes.mapFoldWithEnv (fun outerState envForDecls defnsA -> - - let (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec) = outerState - - match defnsA with - | MutRecShape.Module _ -> failwith "unreachable" - | MutRecShape.Open x -> MutRecShape.Open x, outerState - | MutRecShape.ModuleAbbrev x -> MutRecShape.ModuleAbbrev x, outerState - | MutRecShape.Lets binds -> - - let defnBs, (tpenv, _, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = - - let initialInnerState = (tpenv, envForDecls, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - (initialInnerState, binds) ||> List.mapFold (fun innerState rbind -> - - let (tpenv, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = innerState - - let (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, _, uncheckedRecBindsTable) = - TcLetrecBinding (cenv, envStatic, scopem, [], None) (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) rbind - - let innerState = (tpenv, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - rbind.RecBindingInfo.Index, innerState) - - let outerState = (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec) - MutRecShape.Lets defnBs, outerState - - | MutRecShape.Tycon (TyconBindingsPhase2A(tyconOpt, declKind, _, tcref, copyOfTyconTypars, thisTy, defnAs)) -> - - let isExtrinsic = (declKind = ExtrinsicExtensionBinding) - let envForTycon = MakeInnerEnvForTyconRef envForDecls tcref isExtrinsic - let envForTycon = if isExtrinsic then envForTycon else AddLocalTyconRefs true g cenv.amap tcref.Range [tcref] envForTycon - // Set up the environment so use-before-definition warnings are given, at least - // until we reach a Phase2AIncrClassCtorJustAfterSuperInit. - let envForTycon = { envForTycon with eCtorInfo = Some (InitialImplicitCtorInfo()) } - - let reqdThisValTyOpt = Some thisTy - - // Loop through the definition elements in a type... - // State: - // envInstance: the environment in scope in instance members - // envStatic: the environment in scope in static members - // envNonRec: the environment relevant to generalization - // generalizedRecBinds: part of the incremental generalization state - // preGeneralizationRecBinds: part of the incremental generalization state - // uncheckedRecBindsTable: part of the incremental generalization state - let defnBs, (tpenv, _, _, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = - - let initialInnerState = (tpenv, envForTycon, envForTycon, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - (initialInnerState, defnAs) ||> List.mapFold (fun innerState defnA -> - - let (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) = innerState - - match defnA with - // Phase2B for the definition of an implicit constructor. Enrich the instance environments - // with the implicit ctor args. - | Phase2AIncrClassCtor incrClassCtorLhs -> - - let envInstance = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envInstance - let envStatic = AddDeclaredTypars CheckForDuplicateTypars incrClassCtorLhs.InstanceCtorDeclaredTypars envStatic - let envInstance = match incrClassCtorLhs.InstanceCtorSafeThisValOpt with Some v -> AddLocalVal cenv.tcSink scopem v envInstance | None -> envInstance - let envInstance = List.foldBack AddLocalValPrimitive incrClassCtorLhs.InstanceCtorArgs envInstance - let envNonRec = match incrClassCtorLhs.InstanceCtorSafeThisValOpt with Some v -> AddLocalVal cenv.tcSink scopem v envNonRec | None -> envNonRec - let envNonRec = List.foldBack AddLocalValPrimitive incrClassCtorLhs.InstanceCtorArgs envNonRec - let safeThisValBindOpt = TcLetrecComputeCtorSafeThisValBind cenv incrClassCtorLhs.InstanceCtorSafeThisValOpt - - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt), innerState - - // Phase2B: typecheck the argument to an 'inherits' call and build the new object expr for the inherit-call - | Phase2AInherit (synBaseTy, arg, baseValOpt, m) -> - let baseTy, tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.Use envInstance tpenv synBaseTy - let baseTy = baseTy |> convertToTypeWithMetadataIfPossible g - let inheritsExpr, tpenv = TcNewExpr cenv envInstance tpenv baseTy (Some synBaseTy.Range) true arg m - let envInstance = match baseValOpt with Some baseVal -> AddLocalVal cenv.tcSink scopem baseVal envInstance | None -> envInstance - let envNonRec = match baseValOpt with Some baseVal -> AddLocalVal cenv.tcSink scopem baseVal envNonRec | None -> envNonRec - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BInherit (inheritsExpr, baseValOpt), innerState - - // Phase2B: let and let rec value and function definitions - | Phase2AIncrClassBindings (tcref, binds, isStatic, isRec, bindsm) -> - let envForBinding = if isStatic then envStatic else envInstance - let binds, bindRs, env, tpenv = - if isRec then - - // Type check local recursive binding - let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(ExprContainerInfo, NoNewSlots, ClassLetBinding isStatic, bind)) - let binds, env, tpenv = TcLetrec ErrorOnOverrides cenv envForBinding tpenv (binds, scopem(*bindsm*), scopem) - let bindRs = [IncrClassBindingGroup(binds, isStatic, true)] - binds, bindRs, env, tpenv - else - - // Type check local binding - let binds, env, tpenv = TcLetBindings cenv envForBinding ExprContainerInfo (ClassLetBinding isStatic) tpenv (binds, bindsm, scopem) - let binds, bindRs = - binds - |> List.map (function - | TMDefLet(bind, _) -> [bind], IncrClassBindingGroup([bind], isStatic, false) - | TMDefDo(e, _) -> [], IncrClassDo(e, isStatic) - | _ -> error(InternalError("unexpected definition kind", tcref.Range))) - |> List.unzip - List.concat binds, bindRs, env, tpenv - - let envNonRec = (envNonRec, binds) ||> List.fold (fun acc bind -> AddLocalValPrimitive bind.Var acc) - - // Check to see that local bindings and members don't have the same name and check some other adhoc conditions - for bind in binds do - if not isStatic && HasFSharpAttributeOpt g g.attrib_DllImportAttribute bind.Var.Attribs then - errorR(Error(FSComp.SR.tcDllImportNotAllowed(), bind.Var.Range)) - - let nm = bind.Var.DisplayName - let ty = generalizedTyconRef tcref - let ad = envNonRec.eAccessRights - match TryFindIntrinsicMethInfo cenv.infoReader bind.Var.Range ad nm ty, - TryFindPropInfo cenv.infoReader bind.Var.Range ad nm ty with - | [], [] -> () - | _ -> errorR (Error(FSComp.SR.tcMemberAndLocalClassBindingHaveSameName nm, bind.Var.Range)) - - // Also add static entries to the envInstance if necessary - let envInstance = (if isStatic then (binds, envInstance) ||> List.foldBack (fun b e -> AddLocalVal cenv.tcSink scopem b.Var e) else env) - let envStatic = (if isStatic then env else envStatic) - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BIncrClassBindings bindRs, innerState - - | Phase2AIncrClassCtorJustAfterSuperInit -> - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BIncrClassCtorJustAfterSuperInit, innerState - - | Phase2AIncrClassCtorJustAfterLastLet -> - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BIncrClassCtorJustAfterLastLet, innerState - - -#if OPEN_IN_TYPE_DECLARATIONS - | Phase2AOpen(mp, m) -> - let envInstance = TcOpenDecl cenv.tcSink g cenv.amap m scopem envInstance mp - let envStatic = TcOpenDecl cenv.tcSink g cenv.amap m scopem envStatic mp - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BOpen, innerState -#endif - - - // Note: this path doesn't add anything the environment, because the member is already available off via its type - - | Phase2AMember rbind -> - - // Phase2B: Typecheck member binding, generalize them later, when all type constraints are known - // static members are checked under envStatic. - // envStatic contains class typars and the (ungeneralized) members on the class(es). - // envStatic has no instance-variables (local let-bindings or ctor args). - - let v = rbind.RecBindingInfo .Val - let envForBinding = if v.IsInstanceMember then envInstance else envStatic - - // Type variables derived from the type definition (or implicit constructor) are always generalizable (we check their generalizability later). - // Note they may be solved to be equi-recursive. - let extraGeneralizableTypars = copyOfTyconTypars - - // Inside the incremental class syntax we assert the type of the 'this' variable to be precisely the same type as the - // this variable for the implicit class constructor. For static members, we assert the type variables associated - // for the class to be identical to those used for the implicit class constructor and the static class constructor. - // - // See TcLetrecBinding where this information is consumed. - - // Type check the member and apply early generalization. - // We ignore the tpenv returned by checking each member. Each member gets checked in a fresh, clean tpenv - let (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, _, uncheckedRecBindsTable) = - TcLetrecBinding (cenv, envForBinding, scopem, extraGeneralizableTypars, reqdThisValTyOpt) (envNonRec, generalizedRecBinds, preGeneralizationRecBinds, tpenv, uncheckedRecBindsTable) rbind - - let innerState = (tpenv, envInstance, envStatic, envNonRec, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable) - Phase2BMember rbind.RecBindingInfo.Index, innerState) - - let defnBs = MutRecShape.Tycon (TyconBindingsPhase2B(tyconOpt, tcref, defnBs)) - let outerState = (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec) - defnBs, outerState) - - // There should be no bindings that have not been generalized since checking the vary last binding always - // results in the generalization of all remaining ungeneralized bindings, since there are no remaining unchecked bindings - // to prevent the generalization - assert preGeneralizationRecBinds.IsEmpty - - defnsBs, generalizedRecBinds, tpenv - - - // Choose type scheme implicit constructors and adjust their recursive types. - // Fixup recursive references to members. - let TcMutRecBindings_Phase2C_FixupRecursiveReferences cenv (denv, defnsBs: MutRecDefnsPhase2BData, generalizedTyparsForRecursiveBlock: Typar list, generalizedRecBinds: PostGeneralizationRecursiveBinding list, scopem) = - let g = cenv.g - - // Build an index ---> binding map - let generalizedBindingsMap = generalizedRecBinds |> List.map (fun pgrbind -> (pgrbind.RecBindingInfo.Index, pgrbind)) |> Map.ofList - - defnsBs |> MutRecShapes.mapTyconsAndLets - - // Phase2C: Fixup member bindings - (fun (TyconBindingsPhase2B(tyconOpt, tcref, defnBs)) -> - - let defnCs = - defnBs |> List.map (fun defnB -> - - // Phase2C: Generalise implicit ctor val - match defnB with - | Phase2BIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) -> - let valscheme = incrClassCtorLhs.InstanceCtorValScheme - let valscheme = ChooseCanonicalValSchemeAfterInference g denv valscheme scopem - AdjustRecType cenv incrClassCtorLhs.InstanceCtorVal valscheme - Phase2CIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) - - | Phase2BInherit (inheritsExpr, basevOpt) -> - Phase2CInherit (inheritsExpr, basevOpt) - - | Phase2BIncrClassBindings bindRs -> - Phase2CIncrClassBindings bindRs - - | Phase2BIncrClassCtorJustAfterSuperInit -> - Phase2CIncrClassCtorJustAfterSuperInit - - | Phase2BIncrClassCtorJustAfterLastLet -> - Phase2CIncrClassCtorJustAfterLastLet - - | Phase2BMember idx -> - // Phase2C: Fixup member bindings - let generalizedBinding = generalizedBindingsMap.[idx] - let vxbind = TcLetrecAdjustMemberForSpecialVals cenv generalizedBinding - let pgbrind = FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock vxbind - Phase2CMember pgbrind) - TyconBindingsPhase2C(tyconOpt, tcref, defnCs)) - - // Phase2C: Fixup let bindings - (fun bindIdxs -> - [ for idx in bindIdxs do - let generalizedBinding = generalizedBindingsMap.[idx] - let vxbind = TcLetrecAdjustMemberForSpecialVals cenv generalizedBinding - yield FixupLetrecBind cenv denv generalizedTyparsForRecursiveBlock vxbind ]) - - - // --- Extract field bindings from let-bindings - // --- Extract method bindings from let-bindings - // --- Extract bindings for implicit constructors - let TcMutRecBindings_Phase2D_ExtractImplicitFieldAndMethodBindings cenv envMutRec tpenv (denv, generalizedTyparsForRecursiveBlock, defnsCs: MutRecDefnsPhase2CData) = - let g = cenv.g - - // let (fixupValueExprBinds, methodBinds) = - (envMutRec, defnsCs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (TyconBindingsPhase2C(tyconOpt, tcref, defnCs)) -> - match defnCs with - | Phase2CIncrClassCtor (incrClassCtorLhs, safeThisValBindOpt) :: defnCs -> - - // Determine is static fields in this type need to be "protected" against invalid recursive initialization - let safeStaticInitInfo = - // Safe static init checks are not added to FSharp.Core. The FailInit helper is not defined in some places, and - // there are some minor concerns about performance w.r.t. these static bindings: - // - // set.fs (also map.fs) - // static let empty: Set<'T> = - // let comparer = LanguagePrimitives.FastGenericComparer<'T> - // new Set<'T>(comparer, SetEmpty) - // - // prim-types.fs: - // type TypeInfo<'T>() = - // static let info = - // let ty = typeof<'T> - // ... - // and some others in prim-types.fs - // - // REVIEW: consider allowing an optimization switch to turn off these checks - - let needsSafeStaticInit = not g.compilingFslib - - // We only need safe static init checks if there are some static field bindings (actually, we look for non-method bindings) - let hasStaticBindings = - defnCs |> List.exists (function - | Phase2CIncrClassBindings groups -> - groups |> List.exists (function - | IncrClassBindingGroup(binds, isStatic, _) -> - isStatic && (binds |> List.exists (IncrClassReprInfo.IsMethodRepr cenv >> not)) - | _ -> false) - | _ -> false) - - if needsSafeStaticInit && hasStaticBindings then - let rfield = MakeSafeInitField g envForDecls tcref.Range true - SafeInitField(mkRecdFieldRef tcref rfield.Name, rfield) - else - NoSafeInitInfo - - - // This is the type definition we're processing - let tcref = incrClassCtorLhs.TyconRef - - // Assumes inherit call immediately follows implicit ctor. Checked by CheckMembersForm - let inheritsExpr, inheritsIsVisible, _, defnCs = - match defnCs |> List.partition (function Phase2CInherit _ -> true | _ -> false) with - | [Phase2CInherit (inheritsExpr, baseValOpt)], defnCs -> - inheritsExpr, true, baseValOpt, defnCs - - | _ -> - if tcref.IsStructOrEnumTycon then - mkUnit g tcref.Range, false, None, defnCs - else - let inheritsExpr, _ = TcNewExpr cenv envForDecls tpenv g.obj_ty None true (SynExpr.Const (SynConst.Unit, tcref.Range)) tcref.Range - inheritsExpr, false, None, defnCs - - let envForTycon = MakeInnerEnvForTyconRef envForDecls tcref false - - // Compute the cpath used when creating the hidden fields - let cpath = envForTycon.eAccessPath - - let localDecs = - defnCs |> List.filter (function - | Phase2CIncrClassBindings _ - | Phase2CIncrClassCtorJustAfterSuperInit - | Phase2CIncrClassCtorJustAfterLastLet -> true - | _ -> false) - let memberBindsWithFixups = defnCs |> List.choose (function Phase2CMember pgrbind -> Some pgrbind | _ -> None) - - // Extend localDecs with "let safeThisVal = ref null" if there is a safeThisVal - let localDecs = - match safeThisValBindOpt with - | None -> localDecs - | Some bind -> Phase2CIncrClassBindings [IncrClassBindingGroup([bind], false, false)] :: localDecs - - // Carve out the initialization sequence and decide on the localRep - let ctorBodyLambdaExpr, cctorBodyLambdaExprOpt, methodBinds, localReps = - - let localDecs = - [ for localDec in localDecs do - match localDec with - | Phase2CIncrClassBindings binds -> yield Phase2CBindings binds - | Phase2CIncrClassCtorJustAfterSuperInit -> yield Phase2CCtorJustAfterSuperInit - | Phase2CIncrClassCtorJustAfterLastLet -> yield Phase2CCtorJustAfterLastLet - | _ -> () ] - let memberBinds = memberBindsWithFixups |> List.map (fun x -> x.Binding) - MakeCtorForIncrClassConstructionPhase2C(cenv, envForTycon, incrClassCtorLhs, inheritsExpr, inheritsIsVisible, localDecs, memberBinds, generalizedTyparsForRecursiveBlock, safeStaticInitInfo) - - // Generate the (value, expr) pairs for the implicit - // object constructor and implicit static initializer - let ctorValueExprBindings = - [ (let ctorValueExprBinding = TBind(incrClassCtorLhs.InstanceCtorVal, ctorBodyLambdaExpr, NoSequencePointAtStickyBinding) - let rbind = { ValScheme = incrClassCtorLhs.InstanceCtorValScheme ; Binding = ctorValueExprBinding } - FixupLetrecBind cenv envForDecls.DisplayEnv generalizedTyparsForRecursiveBlock rbind) ] - @ - ( match cctorBodyLambdaExprOpt with - | None -> [] - | Some cctorBodyLambdaExpr -> - [ (let _, cctorVal, cctorValScheme = incrClassCtorLhs.StaticCtorValInfo.Force() - let cctorValueExprBinding = TBind(cctorVal, cctorBodyLambdaExpr, NoSequencePointAtStickyBinding) - let rbind = { ValScheme = cctorValScheme; Binding = cctorValueExprBinding } - FixupLetrecBind cenv envForDecls.DisplayEnv generalizedTyparsForRecursiveBlock rbind) ] ) - - // Publish the fields of the representation to the type - localReps.PublishIncrClassFields (cenv, denv, cpath, incrClassCtorLhs, safeStaticInitInfo) (* mutation *) - - // Fixup members - let memberBindsWithFixups = - memberBindsWithFixups |> List.map (fun pgrbind -> - let (TBind(v, x, spBind)) = pgrbind.Binding - - // Work out the 'this' variable and type instantiation for field fixups. - // We use the instantiation from the instance member if any. Note: It is likely this is not strictly needed - // since we unify the types of the 'this' variables with those of the ctor declared typars. - let thisValOpt = GetInstanceMemberThisVariable (v, x) - - // Members have at least as many type parameters as the enclosing class. Just grab the type variables for the type. - let thisTyInst = List.map mkTyparTy (List.truncate (tcref.Typars(v.Range).Length) v.Typars) - - let x = localReps.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo thisTyInst x - - { pgrbind with Binding = TBind(v, x, spBind) } ) - - tyconOpt, ctorValueExprBindings @ memberBindsWithFixups, methodBinds - - // Cover the case where this is not a class with an implicit constructor - | defnCs -> - let memberBindsWithFixups = defnCs |> List.choose (function Phase2CMember pgrbind -> Some pgrbind | _ -> None) - tyconOpt, memberBindsWithFixups, []) - - /// Check a "module X = A.B.C" module abbreviation declaration - let TcModuleAbbrevDecl (cenv: cenv) scopem env (id, p, m) = - let ad = env.eAccessRights - let resolved = - match p with - | [] -> Result [] - | id :: rest -> ResolveLongIndentAsModuleOrNamespaceOrStaticClass cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m false true OpenQualified env.eNameResEnv ad id rest false - let mvvs = ForceRaise resolved - if isNil mvvs then env else - let modrefs = mvvs |> List.map p23 - if not (isNil modrefs) && modrefs |> List.forall (fun modref -> modref.IsNamespace) then - errorR(Error(FSComp.SR.tcModuleAbbreviationForNamespace(fullDisplayTextOfModRef (List.head modrefs)), m)) - let modrefs = modrefs |> List.filter (fun mvv -> not mvv.IsNamespace) - if isNil modrefs then env else - modrefs |> List.iter (fun modref -> CheckEntityAttributes cenv.g modref m |> CommitOperationResult) - let env = AddModuleAbbreviationAndReport cenv.tcSink scopem id modrefs env - env - - /// Update the contents accessible via the recursive namespace declaration, if any - let TcMutRecDefns_UpdateNSContents mutRecNSInfo = - match mutRecNSInfo with - | Some (Some (mspecNS: ModuleOrNamespace), mtypeAcc) -> - mspecNS.entity_modul_contents <- MaybeLazy.Strict !mtypeAcc - | _ -> () - - /// Updates the types of the modules to contain the contents so far - let TcMutRecDefns_UpdateModuleContents mutRecNSInfo defns = - defns |> MutRecShapes.iterModules (fun (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), _) -> - mspec.entity_modul_contents <- MaybeLazy.Strict !mtypeAcc) - - TcMutRecDefns_UpdateNSContents mutRecNSInfo - - /// Compute the active environments within each nested module. - let TcMutRecDefns_ComputeEnvs getTyconOpt getVals (cenv: cenv) report scopem m envInitial mutRecShape = - (envInitial, mutRecShape) ||> MutRecShapes.computeEnvs - (fun envAbove (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec)) -> MakeInnerEnvWithAcc envAbove mspec.Id mtypeAcc mspec.ModuleOrNamespaceType.ModuleOrNamespaceKind) - (fun envAbove decls -> - - // Collect the type definitions, exception definitions, modules and "open" declarations - let tycons = decls |> List.choose (function MutRecShape.Tycon d -> getTyconOpt d | _ -> None) - let mspecs = decls |> List.choose (function MutRecShape.Module (MutRecDefnsPhase2DataForModule (_, mspec), _) -> Some mspec | _ -> None) - let moduleAbbrevs = decls |> List.choose (function MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev (id, mp, m)) -> Some (id, mp, m) | _ -> None) - let opens = decls |> List.choose (function MutRecShape.Open (MutRecDataForOpen (mp, m, moduleRange)) -> Some (mp, m, moduleRange) | _ -> None) - let lets = decls |> List.collect (function MutRecShape.Lets binds -> getVals binds | _ -> []) - let exns = tycons |> List.filter (fun (tycon: Tycon) -> tycon.IsExceptionDecl) - - // Add the type definitions, exceptions, modules and "open" declarations. - // The order here is sensitive. The things added first will be resolved in an environment - // where not everything has been added. The things added last will be preferred in name - // resolution. - // - // 'open' declarations ('open M') may refer to modules being defined ('M') and so must be - // processed in an environment where 'M' is present. However, in later processing the names of - // modules being defined ('M') take precedence over those coming from 'open' declarations. - // So add the names of the modules being defined to the environment twice - once to allow - // the processing of 'open M', and once to allow the correct name resolution of 'M'. - // - // Module abbreviations being defined ('module M = A.B.C') are not available for use in 'open' - // declarations. So - // namespace rec N = - // open M - // module M = FSharp.Core.Operators - // is not allowed. - - let envForDecls = envAbove - // Add the modules being defined - let envForDecls = (envForDecls, mspecs) ||> List.fold ((if report then AddLocalSubModuleAndReport cenv.tcSink scopem else AddLocalSubModule) cenv.g cenv.amap m) - // Process the 'open' declarations - let envForDecls = (envForDecls, opens) ||> List.fold (fun env (mp, m, moduleRange) -> TcOpenDecl cenv.tcSink cenv.g cenv.amap m moduleRange env mp) - // Add the type definitions being defined - let envForDecls = (if report then AddLocalTyconsAndReport cenv.tcSink scopem else AddLocalTycons) cenv.g cenv.amap m tycons envForDecls - // Add the exception definitions being defined - let envForDecls = (envForDecls, exns) ||> List.fold (AddLocalExnDefnAndReport cenv.tcSink scopem) - // Add the modules again (but don't report them a second time) - let envForDecls = (envForDecls, mspecs) ||> List.fold (AddLocalSubModule cenv.g cenv.amap m) - // Add the module abbreviations - let envForDecls = (envForDecls, moduleAbbrevs) ||> List.fold (TcModuleAbbrevDecl cenv scopem) - // Add the values and members - let envForDecls = AddLocalVals cenv.tcSink scopem lets envForDecls - envForDecls) - - /// Phase 2: Check the members and 'let' definitions in a mutually recursive group of definitions. - let TcMutRecDefns_Phase2_Bindings cenv envInitial tpenv bindsm scopem mutRecNSInfo (envMutRecPrelimWithReprs: TcEnv) (mutRecDefns: MutRecDefnsPhase2Info) = - let g = cenv.g - let denv = envMutRecPrelimWithReprs.DisplayEnv - - // Phase2A: create member prelimRecValues for "recursive" items, i.e. ctor val and member vals - // Phase2A: also processes their arg patterns - collecting type assertions - let (defnsAs, uncheckedRecBinds, tpenv) = TcMutRecBindings_Phase2A_CreateRecursiveValuesAndCheckArgumentPatterns cenv tpenv (envMutRecPrelimWithReprs, mutRecDefns) - - // Now basic member values are created we can compute the final attributes (i.e. in the case where attributes refer to constructors being defined) - mutRecDefns |> MutRecShapes.iterTycons (fun (MutRecDefnsPhase2InfoForTycon(_, _, _, _, _, fixupFinalAttrs)) -> - fixupFinalAttrs()) - - // Updates the types of the modules to contain the contents so far, which now includes values and members - TcMutRecDefns_UpdateModuleContents mutRecNSInfo defnsAs - - // Updates the environments to include the values - // We must open all modules from scratch again because there may be extension methods and/or AutoOpen - let envMutRec, defnsAs = - (envInitial, MutRecShapes.dropEnvs defnsAs) - ||> TcMutRecDefns_ComputeEnvs - (fun (TyconBindingsPhase2A(tyconOpt, _, _, _, _, _, _)) -> tyconOpt) - (fun binds -> [ for bind in binds -> bind.RecBindingInfo.Val ]) - cenv false scopem scopem - ||> MutRecShapes.extendEnvs (fun envForDecls decls -> - - let prelimRecValues = - decls |> List.collect (function - | MutRecShape.Tycon (TyconBindingsPhase2A(_, _, prelimRecValues, _, _, _, _)) -> prelimRecValues - | MutRecShape.Lets binds -> [ for bind in binds -> bind.RecBindingInfo.Val ] - | _ -> []) - - let ctorVals = - decls |> MutRecShapes.topTycons |> List.collect (fun (TyconBindingsPhase2A(_, _, _, _, _, _, defnAs)) -> - [ for defnB in defnAs do - match defnB with - | Phase2AIncrClassCtor incrClassCtorLhs -> yield incrClassCtorLhs.InstanceCtorVal - | _ -> () ]) - - let envForDeclsUpdated = - envForDecls - |> AddLocalVals cenv.tcSink scopem prelimRecValues - |> AddLocalVals cenv.tcSink scopem ctorVals - - envForDeclsUpdated) - - // Phase2B: type check pass, convert from ast to tast and collects type assertions, and generalize - let defnsBs, generalizedRecBinds, tpenv = TcMutRecBindings_Phase2B_TypeCheckAndIncrementalGeneralization cenv tpenv envInitial (envMutRec, defnsAs, uncheckedRecBinds, scopem) - - - let generalizedTyparsForRecursiveBlock = - generalizedRecBinds - |> List.map (fun pgrbind -> pgrbind.GeneralizedTypars) - |> unionGeneralizedTypars - - // Check the escape condition for all extraGeneralizableTypars. - // First collect up all the extraGeneralizableTypars. - let allExtraGeneralizableTypars = - defnsAs |> MutRecShapes.collectTycons |> List.collect (fun (TyconBindingsPhase2A(_, _, _, _, copyOfTyconTypars, _, defnAs)) -> - [ yield! copyOfTyconTypars - for defnA in defnAs do - match defnA with - | Phase2AMember rbind -> yield! rbind.RecBindingInfo.EnclosingDeclaredTypars - | _ -> () ]) - - // Now check they don't escape the overall scope of the recursive set of types - if not (isNil allExtraGeneralizableTypars) then - let freeInInitialEnv = GeneralizationHelpers.ComputeUngeneralizableTypars envInitial - for extraTypar in allExtraGeneralizableTypars do - if Zset.memberOf freeInInitialEnv extraTypar then - let ty = mkTyparTy extraTypar - error(Error(FSComp.SR.tcNotSufficientlyGenericBecauseOfScope(NicePrint.prettyStringOfTy denv ty), extraTypar.Range)) - - // Solve any type variables in any part of the overall type signature of the class whose - // constraints involve generalized type variables. - // - // This includes property, member and constructor argument types that couldn't be fully generalized because they - // involve generalized copies of class type variables. - let unsolvedTyparsForRecursiveBlockInvolvingGeneralizedVariables = - let genSet = (freeInTypes CollectAllNoCaching [ for tp in generalizedTyparsForRecursiveBlock -> mkTyparTy tp ]).FreeTypars - //printfn "genSet.Count = %d" genSet.Count - let allTypes = - [ for pgrbind in generalizedRecBinds do - yield pgrbind.RecBindingInfo.Val.Type - for (TyconBindingsPhase2B(_tyconOpt, _tcref, defnBs)) in MutRecShapes.collectTycons defnsBs do - for defnB in defnBs do - match defnB with - | Phase2BIncrClassCtor (incrClassCtorLhs, _) -> - yield incrClassCtorLhs.InstanceCtorVal.Type - | _ -> - () - ] - //printfn "allTypes.Length = %d" allTypes.Length - let unsolvedTypars = freeInTypesLeftToRight g true allTypes - //printfn "unsolvedTypars.Length = %d" unsolvedTypars.Length - //for x in unsolvedTypars do - // printfn "unsolvedTypar: %s #%d" x.DisplayName x.Stamp - let unsolvedTyparsInvolvingGeneralizedVariables = - unsolvedTypars |> List.filter (fun tp -> - let freeInTypar = (freeInType CollectAllNoCaching (mkTyparTy tp)).FreeTypars - // Check it is not one of the generalized variables... - not (genSet.Contains tp) && - // Check it involves a generalized variable in one of its constraints... - freeInTypar.Exists(fun otherTypar -> genSet.Contains otherTypar)) - //printfn "unsolvedTyparsInvolvingGeneralizedVariables.Length = %d" unsolvedTyparsInvolvingGeneralizedVariables.Length - //for x in unsolvedTypars do - // printfn "unsolvedTyparsInvolvingGeneralizedVariable: %s #%d" x.DisplayName x.Stamp - unsolvedTyparsInvolvingGeneralizedVariables - - for tp in unsolvedTyparsForRecursiveBlockInvolvingGeneralizedVariables do - //printfn "solving unsolvedTyparsInvolvingGeneralizedVariable: %s #%d" tp.DisplayName tp.Stamp - if (tp.Rigidity <> TyparRigidity.Rigid) && not tp.IsSolved then - ConstraintSolver.ChooseTyparSolutionAndSolve cenv.css denv tp - - // Now that we know what we've generalized we can adjust the recursive references - let defnsCs = TcMutRecBindings_Phase2C_FixupRecursiveReferences cenv (denv, defnsBs, generalizedTyparsForRecursiveBlock, generalizedRecBinds, scopem) - - // --- Extract field bindings from let-bindings - // --- Extract method bindings from let-bindings - // --- Extract bindings for implicit constructors - let defnsDs = TcMutRecBindings_Phase2D_ExtractImplicitFieldAndMethodBindings cenv envMutRec tpenv (denv, generalizedTyparsForRecursiveBlock, defnsCs) - - // Phase2E - rewrite values to initialization graphs - let defnsEs = - EliminateInitializationGraphs - p23 - (fun morpher (tyconOpt, fixupValueExprBinds, methodBinds) -> (tyconOpt, morpher fixupValueExprBinds @ methodBinds)) - id - (fun morpher oldBinds -> morpher oldBinds) - g true denv defnsDs bindsm - - defnsEs, envMutRec - -/// Check and generalize the interface implementations, members, 'let' definitions in a mutually recursive group of definitions. -let TcMutRecDefns_Phase2 cenv envInitial bindsm scopem mutRecNSInfo (envMutRec: TcEnv) (mutRecDefns: MutRecDefnsPhase2Data) = - let g = cenv.g - let interfacesFromTypeDefn envForTycon tyconMembersData = - let (MutRecDefnsPhase2DataForTycon(_, _, declKind, tcref, _, _, declaredTyconTypars, members, _, _, _)) = tyconMembersData - let overridesOK = DeclKind.CanOverrideOrImplement declKind - members |> List.collect (function - | SynMemberDefn.Interface(ity, defnOpt, _) -> - let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref - let m = ity.Range - if tcref.IsTypeAbbrev then error(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveInterfaceDeclaration(), m)) - if tcref.IsEnumTycon then error(Error(FSComp.SR.tcEnumerationsCannotHaveInterfaceDeclaration(), m)) - - let ity' = - let envinner = AddDeclaredTypars CheckForDuplicateTypars declaredTyconTypars envForTycon - TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner emptyUnscopedTyparEnv ity |> fst - if not (isInterfaceTy g ity') then errorR(Error(FSComp.SR.tcTypeIsNotInterfaceType0(), ity.Range)) - - if not (tcref.HasInterface g ity') then - error(Error(FSComp.SR.tcAllImplementedInterfacesShouldBeDeclared(), ity.Range)) - if (typeEquiv g ity' g.mk_IComparable_ty && Option.isSome tcref.GeneratedCompareToValues) || - (typeEquiv g ity' g.mk_IStructuralComparable_ty && Option.isSome tcref.GeneratedCompareToWithComparerValues) || - (typeEquiv g ity' ((mkAppTy g.system_GenericIComparable_tcref [ty])) && Option.isSome tcref.GeneratedCompareToValues) || - (typeEquiv g ity' ((mkAppTy g.system_GenericIEquatable_tcref [ty])) && Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues) || - (typeEquiv g ity' g.mk_IStructuralEquatable_ty && Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues) then - errorR(Error(FSComp.SR.tcDefaultImplementationForInterfaceHasAlreadyBeenAdded(), ity.Range)) - if overridesOK = WarnOnOverrides then - warning(IntfImplInIntrinsicAugmentation(ity.Range)) - if overridesOK = ErrorOnOverrides then - errorR(IntfImplInExtrinsicAugmentation(ity.Range)) - match defnOpt with - | Some defn -> [ (ity', defn, m) ] - | _-> [] - - | _ -> []) - - let interfaceMembersFromTypeDefn tyconMembersData (ity', defn, _) implTySet = - let (MutRecDefnsPhase2DataForTycon(_, parent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, _, _, newslotsOK, _)) = tyconMembersData - let containerInfo = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, Some(ity', implTySet), baseValOpt, safeInitInfo, declaredTyconTypars))) - defn |> List.choose (fun mem -> - match mem with - | SynMemberDefn.Member(_, m) -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, mem, m)) - | SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, _, _, m) -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, mem, m)) - | _ -> errorR(Error(FSComp.SR.tcMemberNotPermittedInInterfaceImplementation(), mem.Range)); None) - - let tyconBindingsOfTypeDefn (MutRecDefnsPhase2DataForTycon(_, parent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, _, newslotsOK, _)) = - let containerInfo = ContainerInfo(parent, Some(MemberOrValContainerInfo(tcref, None, baseValOpt, safeInitInfo, declaredTyconTypars))) - members - |> List.choose (fun memb -> - match memb with - | SynMemberDefn.ImplicitCtor _ - | SynMemberDefn.ImplicitInherit _ - | SynMemberDefn.LetBindings _ - | SynMemberDefn.AutoProperty _ - | SynMemberDefn.Member _ - | SynMemberDefn.Open _ - -> Some(TyconBindingDefn(containerInfo, newslotsOK, declKind, memb, memb.Range)) - - // Interfaces exist in the member list - handled above in interfaceMembersFromTypeDefn - | SynMemberDefn.Interface _ -> None - - // The following should have been List.unzip out already in SplitTyconDefn - | SynMemberDefn.AbstractSlot _ - | SynMemberDefn.ValField _ - | SynMemberDefn.Inherit _ -> error(InternalError("Unexpected declaration element", memb.Range)) - | SynMemberDefn.NestedType _ -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), memb.Range))) - - let tpenv = emptyUnscopedTyparEnv - - try - // Some preliminary checks - mutRecDefns |> MutRecShapes.iterTycons (fun tyconData -> - let (MutRecDefnsPhase2DataForTycon(_, _, declKind, tcref, _, _, _, members, m, newslotsOK, _)) = tyconData - let tcaug = tcref.TypeContents - if tcaug.tcaug_closed && declKind <> ExtrinsicExtensionBinding then - error(InternalError("Intrinsic augmentations of types are only permitted in the same file as the definition of the type", m)) - members |> List.iter (fun mem -> - match mem with - | SynMemberDefn.Member _ -> () - | SynMemberDefn.Interface _ -> () - | SynMemberDefn.Open _ - | SynMemberDefn.AutoProperty _ - | SynMemberDefn.LetBindings _ // accept local definitions - | SynMemberDefn.ImplicitCtor _ // accept implicit ctor pattern, should be first! - | SynMemberDefn.ImplicitInherit _ when newslotsOK = NewSlotsOK -> () // accept implicit ctor pattern, should be first! - // The rest should have been removed by splitting, they belong to "core" (they are "shape" of type, not implementation) - | _ -> error(Error(FSComp.SR.tcDeclarationElementNotPermittedInAugmentation(), mem.Range)))) - - - let binds: MutRecDefnsPhase2Info = - (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls tyconData -> - let (MutRecDefnsPhase2DataForTycon(tyconOpt, _, declKind, tcref, _, _, declaredTyconTypars, _, _, _, fixupFinalAttrs)) = tyconData - let obinds = tyconBindingsOfTypeDefn tyconData - let ibinds = - let intfTypes = interfacesFromTypeDefn envForDecls tyconData - let slotImplSets = DispatchSlotChecking.GetSlotImplSets cenv.infoReader envForDecls.DisplayEnv false (List.map (fun (ity, _, m) -> (ity, m)) intfTypes) - (intfTypes, slotImplSets) ||> List.map2 (interfaceMembersFromTypeDefn tyconData) |> List.concat - MutRecDefnsPhase2InfoForTycon(tyconOpt, tcref, declaredTyconTypars, declKind, obinds @ ibinds, fixupFinalAttrs)) - - MutRecBindingChecking.TcMutRecDefns_Phase2_Bindings cenv envInitial tpenv bindsm scopem mutRecNSInfo envMutRec binds - - with e -> errorRecovery e scopem; [], envMutRec - -//------------------------------------------------------------------------- -// Build augmentation declarations -//------------------------------------------------------------------------- - -module AddAugmentationDeclarations = - let tcaugHasNominalInterface g (tcaug: TyconAugmentation) tcref = - tcaug.tcaug_interfaces |> List.exists (fun (x, _, _) -> - match tryDestAppTy g x with - | ValueSome tcref2 when tyconRefEq g tcref2 tcref -> true - | _ -> false) - - let AddGenericCompareDeclarations cenv (env: TcEnv) (scSet: Set) (tycon: Tycon) = - let g = cenv.g - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare g tycon && scSet.Contains tycon.Stamp then - let tcref = mkLocalTyconRef tycon - let tcaug = tycon.TypeContents - let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref - let m = tycon.Range - let genericIComparableTy = mkAppTy g.system_GenericIComparable_tcref [ty] - - - let hasExplicitIComparable = tycon.HasInterface g g.mk_IComparable_ty - let hasExplicitGenericIComparable = tcaugHasNominalInterface g tcaug g.system_GenericIComparable_tcref - let hasExplicitIStructuralComparable = tycon.HasInterface g g.mk_IStructuralComparable_ty - - if hasExplicitIComparable then - errorR(Error(FSComp.SR.tcImplementsIComparableExplicitly(tycon.DisplayName), m)) - - elif hasExplicitGenericIComparable then - errorR(Error(FSComp.SR.tcImplementsGenericIComparableExplicitly(tycon.DisplayName), m)) - elif hasExplicitIStructuralComparable then - errorR(Error(FSComp.SR.tcImplementsIStructuralComparableExplicitly(tycon.DisplayName), m)) - else - let hasExplicitGenericIComparable = tycon.HasInterface g genericIComparableTy - let cvspec1, cvspec2 = AugmentWithHashCompare.MakeValsForCompareAugmentation g tcref - let cvspec3 = AugmentWithHashCompare.MakeValsForCompareWithComparerAugmentation g tcref - - PublishInterface cenv env.DisplayEnv tcref m true g.mk_IStructuralComparable_ty - PublishInterface cenv env.DisplayEnv tcref m true g.mk_IComparable_ty - if not tycon.IsExceptionDecl && not hasExplicitGenericIComparable then - PublishInterface cenv env.DisplayEnv tcref m true genericIComparableTy - tcaug.SetCompare (mkLocalValRef cvspec1, mkLocalValRef cvspec2) - tcaug.SetCompareWith (mkLocalValRef cvspec3) - PublishValueDefn cenv env ModuleOrMemberBinding cvspec1 - PublishValueDefn cenv env ModuleOrMemberBinding cvspec2 - PublishValueDefn cenv env ModuleOrMemberBinding cvspec3 - - - - let AddGenericEqualityWithComparerDeclarations cenv (env: TcEnv) (seSet: Set) (tycon: Tycon) = - let g = cenv.g - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tycon && seSet.Contains tycon.Stamp then - let tcref = mkLocalTyconRef tycon - let tcaug = tycon.TypeContents - let m = tycon.Range - - let hasExplicitIStructuralEquatable = tycon.HasInterface g g.mk_IStructuralEquatable_ty - - if hasExplicitIStructuralEquatable then - errorR(Error(FSComp.SR.tcImplementsIStructuralEquatableExplicitly(tycon.DisplayName), m)) - else - let evspec1, evspec2, evspec3 = AugmentWithHashCompare.MakeValsForEqualityWithComparerAugmentation g tcref - PublishInterface cenv env.DisplayEnv tcref m true g.mk_IStructuralEquatable_ty - tcaug.SetHashAndEqualsWith (mkLocalValRef evspec1, mkLocalValRef evspec2, mkLocalValRef evspec3) - PublishValueDefn cenv env ModuleOrMemberBinding evspec1 - PublishValueDefn cenv env ModuleOrMemberBinding evspec2 - PublishValueDefn cenv env ModuleOrMemberBinding evspec3 - - - let AddGenericCompareBindings cenv (tycon: Tycon) = - if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToValues then - AugmentWithHashCompare.MakeBindingsForCompareAugmentation cenv.g tycon - else - [] - - let AddGenericCompareWithComparerBindings cenv (tycon: Tycon) = - if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToWithComparerValues then - (AugmentWithHashCompare.MakeBindingsForCompareWithComparerAugmentation cenv.g tycon) - else - [] - - let AddGenericEqualityWithComparerBindings cenv (tycon: Tycon) = - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then - (AugmentWithHashCompare.MakeBindingsForEqualityWithComparerAugmentation cenv.g tycon) - else - [] - - let AddGenericHashAndComparisonDeclarations cenv env scSet seSet tycon = - AddGenericCompareDeclarations cenv env scSet tycon - AddGenericEqualityWithComparerDeclarations cenv env seSet tycon - - - let AddGenericHashAndComparisonBindings cenv tycon = - AddGenericCompareBindings cenv tycon @ AddGenericCompareWithComparerBindings cenv tycon @ AddGenericEqualityWithComparerBindings cenv tycon - - - // We can only add the Equals override after we've done the augmentation because we have to wait until - // tycon.HasOverride can give correct results - let AddGenericEqualityBindings cenv (env: TcEnv) tycon = - let g = cenv.g - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tycon then - let tcref = mkLocalTyconRef tycon - let tcaug = tycon.TypeContents - let _, ty = if tcref.Deref.IsExceptionDecl then [], g.exn_ty else generalizeTyconRef tcref - let m = tycon.Range - - // Note: tycon.HasOverride only gives correct results after we've done the type augmentation - let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty] - let hasExplicitGenericIEquatable = tcaugHasNominalInterface g tcaug g.system_GenericIEquatable_tcref - - if hasExplicitGenericIEquatable then - errorR(Error(FSComp.SR.tcImplementsIEquatableExplicitly(tycon.DisplayName), m)) - - // Note: only provide the equals method if Equals is not implemented explicitly, and - // we're actually generating Hash/Equals for this type - if not hasExplicitObjectEqualsOverride && - Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then - - let vspec1, vspec2 = AugmentWithHashCompare.MakeValsForEqualsAugmentation g tcref - tcaug.SetEquals (mkLocalValRef vspec1, mkLocalValRef vspec2) - if not tycon.IsExceptionDecl then - PublishInterface cenv env.DisplayEnv tcref m true (mkAppTy g.system_GenericIEquatable_tcref [ty]) - PublishValueDefn cenv env ModuleOrMemberBinding vspec1 - PublishValueDefn cenv env ModuleOrMemberBinding vspec2 - AugmentWithHashCompare.MakeBindingsForEqualsAugmentation g tycon - else [] - else [] - - - -/// Infer 'comparison' and 'equality' constraints from type definitions -module TyconConstraintInference = - - /// Infer 'comparison' constraints from type definitions - let InferSetOfTyconsSupportingComparable cenv (denv: DisplayEnv) tyconsWithStructuralTypes = - - let g = cenv.g - let tab = tyconsWithStructuralTypes |> List.map (fun (tycon: Tycon, structuralTypes) -> tycon.Stamp, (tycon, structuralTypes)) |> Map.ofList - - // Initially, assume the equality relation is available for all structural type definitions - let initialAssumedTycons = - set [ for (tycon, _) in tyconsWithStructuralTypes do - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon then - yield tycon.Stamp ] - - // Initially, don't assume that the equality relation is dependent on any type variables - let initialAssumedTypars = Set.empty - - // Repeatedly eliminate structural type definitions whose structural component types no longer support - // comparison. On the way record type variables which are support the comparison relation. - let rec loop (assumedTycons: Set) (assumedTypars: Set) = - let mutable assumedTyparsAcc = assumedTypars - - // Checks if a field type supports the 'comparison' constraint based on the assumptions about the type constructors - // and type parameters. - let rec checkIfFieldTypeSupportsComparison (tycon: Tycon) (ty: TType) = - - // Is the field type a type parameter? - match tryDestTyparTy cenv.g ty with - | ValueSome tp -> - // Look for an explicit 'comparison' constraint - if tp.Constraints |> List.exists (function TyparConstraint.SupportsComparison _ -> true | _ -> false) then - true - - // Within structural types, type parameters can be optimistically assumed to have comparison - // We record the ones for which we have made this assumption. - elif tycon.TyparsNoRange |> List.exists (fun tp2 -> typarRefEq tp tp2) then - assumedTyparsAcc <- assumedTyparsAcc.Add(tp.Stamp) - true - - else - false - | _ -> - match ty with - // Look for array, UIntPtr and IntPtr types - | SpecialComparableHeadType g tinst -> - tinst |> List.forall (checkIfFieldTypeSupportsComparison tycon) - - // Otherwise it's a nominal type - | _ -> - - match ty with - | AppTy g (tcref, tinst) -> - // Check the basic requirement - IComparable/IStructuralComparable or assumed-comparable - (if initialAssumedTycons.Contains tcref.Stamp then - assumedTycons.Contains tcref.Stamp - else - ExistsSameHeadTypeInHierarchy g cenv.amap range0 ty g.mk_IComparable_ty || - ExistsSameHeadTypeInHierarchy g cenv.amap range0 ty g.mk_IStructuralComparable_ty) - && - // Check it isn't ruled out by the user - not (HasFSharpAttribute g g.attrib_NoComparisonAttribute tcref.Attribs) - && - // Check the structural dependencies - (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> - if tp.ComparisonConditionalOn || assumedTypars.Contains tp.Stamp then - checkIfFieldTypeSupportsComparison tycon ty - else - true) - | _ -> - false - - let newSet = - assumedTycons |> Set.filter (fun tyconStamp -> - let (tycon, structuralTypes) = tab.[tyconStamp] - - if cenv.g.compilingFslib && - AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && - not (HasFSharpAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs) && - not (HasFSharpAttribute g g.attrib_NoComparisonAttribute tycon.Attribs) then - errorR(Error(FSComp.SR.tcFSharpCoreRequiresExplicit(), tycon.Range)) - - let res = (structuralTypes |> List.forall (fst >> checkIfFieldTypeSupportsComparison tycon)) - - // If the type was excluded, say why - if not res then - match TryFindFSharpBoolAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs with - | Some true -> - match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with - | None -> - assert false - failwith "unreachable" - | Some (ty, _) -> - if isTyparTy g ty then - errorR(Error(FSComp.SR.tcStructuralComparisonNotSatisfied1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) - else - errorR(Error(FSComp.SR.tcStructuralComparisonNotSatisfied2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) - | Some false -> - () - - | None -> - match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with - | None -> - assert false - failwith "unreachable" - | Some (ty, _) -> - // NOTE: these warnings are off by default - they are level 4 informational warnings - // PERF: this call to prettyStringOfTy is always being executed, even when the warning - // is not being reported (the normal case). - if isTyparTy g ty then - warning(Error(FSComp.SR.tcNoComparisonNeeded1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) - else - warning(Error(FSComp.SR.tcNoComparisonNeeded2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) - - - res) - - if newSet = assumedTycons && assumedTypars = assumedTyparsAcc then - newSet, assumedTyparsAcc - else - loop newSet assumedTyparsAcc - - let uneliminatedTycons, assumedTyparsActual = loop initialAssumedTycons initialAssumedTypars - - // OK, we're done, Record the results for the type variable which provide the support - for tyconStamp in uneliminatedTycons do - let (tycon, _) = tab.[tyconStamp] - for tp in tycon.Typars(tycon.Range) do - if assumedTyparsActual.Contains(tp.Stamp) then - tp.SetComparisonDependsOn true - - // Return the set of structural type definitions which support the relation - uneliminatedTycons - - /// Infer 'equality' constraints from type definitions - let InferSetOfTyconsSupportingEquatable cenv (denv: DisplayEnv) (tyconsWithStructuralTypes:(Tycon * _) list) = - - let g = cenv.g - let tab = tyconsWithStructuralTypes |> List.map (fun (tycon, c) -> tycon.Stamp, (tycon, c)) |> Map.ofList - - // Initially, assume the equality relation is available for all structural type definitions - let initialAssumedTycons = - set [ for (tycon, _) in tyconsWithStructuralTypes do - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then - yield tycon.Stamp ] - - // Initially, don't assume that the equality relation is dependent on any type variables - let initialAssumedTypars = Set.empty - - // Repeatedly eliminate structural type definitions whose structural component types no longer support - // equality. On the way add type variables which are support the equality relation - let rec loop (assumedTycons: Set) (assumedTypars: Set) = - let mutable assumedTyparsAcc = assumedTypars - - // Checks if a field type supports the 'equality' constraint based on the assumptions about the type constructors - // and type parameters. - let rec checkIfFieldTypeSupportsEquality (tycon: Tycon) (ty: TType) = - match tryDestTyparTy cenv.g ty with - | ValueSome tp -> - // Look for an explicit 'equality' constraint - if tp.Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then - true - - // Within structural types, type parameters can be optimistically assumed to have equality - // We record the ones for which we have made this assumption. - elif tycon.Typars(tycon.Range) |> List.exists (fun tp2 -> typarRefEq tp tp2) then - assumedTyparsAcc <- assumedTyparsAcc.Add(tp.Stamp) - true - else - false - | _ -> - match ty with - | SpecialEquatableHeadType g tinst -> - tinst |> List.forall (checkIfFieldTypeSupportsEquality tycon) - | SpecialNotEquatableHeadType g -> - false - | _ -> - // Check the basic requirement - any types except those eliminated - match ty with - | AppTy g (tcref, tinst) -> - (if initialAssumedTycons.Contains tcref.Stamp then - assumedTycons.Contains tcref.Stamp - elif AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tcref.Deref then - Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues - else - true) - && - // Check it isn't ruled out by the user - not (HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs) - && - // Check the structural dependencies - (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> - if tp.EqualityConditionalOn || assumedTypars.Contains tp.Stamp then - checkIfFieldTypeSupportsEquality tycon ty - else - true) - | _ -> - false - - let newSet = - assumedTycons |> Set.filter (fun tyconStamp -> - - let (tycon, structuralTypes) = tab.[tyconStamp] - - if cenv.g.compilingFslib && - AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && - not (HasFSharpAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs) && - not (HasFSharpAttribute g g.attrib_NoEqualityAttribute tycon.Attribs) then - errorR(Error(FSComp.SR.tcFSharpCoreRequiresExplicit(), tycon.Range)) - - // Remove structural types with incomparable elements from the assumedTycons - let res = (structuralTypes |> List.forall (fst >> checkIfFieldTypeSupportsEquality tycon)) - - // If the type was excluded, say why - if not res then - match TryFindFSharpBoolAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs with - | Some true -> - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then - match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with - | None -> - assert false - failwith "unreachable" - | Some (ty, _) -> - if isTyparTy g ty then - errorR(Error(FSComp.SR.tcStructuralEqualityNotSatisfied1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) - else - errorR(Error(FSComp.SR.tcStructuralEqualityNotSatisfied2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty), tycon.Range)) - else - () - | Some false -> - () - | None -> - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then - match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with - | None -> - assert false - failwith "unreachable" - | Some (ty, _) -> - if isTyparTy g ty then - warning(Error(FSComp.SR.tcNoEqualityNeeded1(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) - else - warning(Error(FSComp.SR.tcNoEqualityNeeded2(tycon.DisplayName, NicePrint.prettyStringOfTy denv ty, tycon.DisplayName), tycon.Range)) - - - res) - - if newSet = assumedTycons && assumedTypars = assumedTyparsAcc then - newSet, assumedTyparsAcc - else - loop newSet assumedTyparsAcc - - let uneliminatedTycons, assumedTyparsActual = loop initialAssumedTycons initialAssumedTypars - - // OK, we're done, Record the results for the type variable which provide the support - for tyconStamp in uneliminatedTycons do - let (tycon, _) = tab.[tyconStamp] - for tp in tycon.Typars(tycon.Range) do - if assumedTyparsActual.Contains(tp.Stamp) then - tp.SetEqualityDependsOn true - - // Return the set of structural type definitions which support the relation - uneliminatedTycons - - -//------------------------------------------------------------------------- -// Helpers for modules, types and exception declarations -//------------------------------------------------------------------------- - -let ComputeModuleName (longPath: Ident list) = - if longPath.Length <> 1 then error(Error(FSComp.SR.tcInvalidModuleName(), (List.head longPath).idRange)) - longPath.Head - -let CheckForDuplicateConcreteType env nm m = - let curr = GetCurrAccumulatedModuleOrNamespaceType env - if Map.containsKey nm curr.AllEntitiesByCompiledAndLogicalMangledNames then - // Use 'error' instead of 'errorR' here to avoid cascading errors - see bug 1177 in FSharp 1.0 - error (Duplicate(FSComp.SR.tcTypeExceptionOrModule(), nm, m)) - -let CheckForDuplicateModule env nm m = - let curr = GetCurrAccumulatedModuleOrNamespaceType env - if curr.ModulesAndNamespacesByDemangledName.ContainsKey nm then - errorR (Duplicate(FSComp.SR.tcTypeOrModule(), nm, m)) - - -//------------------------------------------------------------------------- -// Bind exception definitions -//------------------------------------------------------------------------- - -/// Check 'exception' declarations in implementations and signatures -module TcExceptionDeclarations = - - let TcExnDefnCore_Phase1A cenv env parent (SynExceptionDefnRepr(Attributes synAttrs, UnionCase(_, id, _, _, _, _), _, doc, vis, m)) = - let attrs = TcAttributes cenv env AttributeTargets.ExnDecl synAttrs - if not (String.isUpper id.idText) then errorR(NotUpperCaseConstructor m) - let vis, cpath = ComputeAccessAndCompPath env None m vis None parent - let vis = TcRecdUnionAndEnumDeclarations.CombineReprAccess parent vis - CheckForDuplicateConcreteType env (id.idText + "Exception") id.idRange - CheckForDuplicateConcreteType env id.idText id.idRange - NewExn cpath id vis (TExnFresh (MakeRecdFieldsTable [])) attrs (doc.ToXmlDoc()) - - let TcExnDefnCore_Phase1G_EstablishRepresentation cenv env parent (exnc: Entity) (SynExceptionDefnRepr(_, UnionCase(_, _, args, _, _, _), reprIdOpt, _, _, m)) = - let g = cenv.g - let args = match args with (UnionCaseFields args) -> args | _ -> error(Error(FSComp.SR.tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors(), m)) - let ad = env.eAccessRights - let id = exnc.Id - - let args' = List.mapi (fun i fdef -> TcRecdUnionAndEnumDeclarations.TcAnonFieldDecl cenv env parent emptyUnscopedTyparEnv ("Data" + string i) fdef) args - TcRecdUnionAndEnumDeclarations.ValidateFieldNames(args, args') - let repr = - match reprIdOpt with - | Some longId -> - match ResolveExprLongIdent cenv.tcSink cenv.nameResolver m ad env.eNameResEnv TypeNameResolutionInfo.Default longId with - | Item.ExnCase exnc, [] -> - CheckTyconAccessible cenv.amap m env.eAccessRights exnc |> ignore - if not (isNil args') then - errorR (Error(FSComp.SR.tcExceptionAbbreviationsShouldNotHaveArgumentList(), m)) - TExnAbbrevRepr exnc - | Item.CtorGroup(_, meths), [] -> - // REVIEW: check this really is an exception type - match args' with - | [] -> () - | _ -> error (Error(FSComp.SR.tcAbbreviationsFordotNetExceptionsCannotTakeArguments(), m)) - let candidates = - meths |> List.filter (fun minfo -> - minfo.NumArgs = [args'.Length] && - minfo.GenericArity = 0) - match candidates with - | [minfo] -> - match minfo.ApparentEnclosingType with - | AppTy g (tcref, _) as ety when (TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m g.exn_ty ety) -> - let tref = tcref.CompiledRepresentationForNamedType - TExnAsmRepr tref - | _ -> - error(Error(FSComp.SR.tcExceptionAbbreviationsMustReferToValidExceptions(), m)) - | _ -> - error (Error(FSComp.SR.tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor(), m)) - | _ -> - error (Error(FSComp.SR.tcNotAnException(), m)) - | None -> - TExnFresh (MakeRecdFieldsTable args') - - exnc.SetExceptionInfo repr - - let item = Item.ExnCase(mkLocalTyconRef exnc) - CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights) - args' - - let private TcExnDefnCore cenv env parent synExnDefnRepr = - let exnc = TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr - let args' = TcExnDefnCore_Phase1G_EstablishRepresentation cenv env parent exnc synExnDefnRepr - exnc.TypeContents.tcaug_super <- Some cenv.g.exn_ty - - PublishTypeDefn cenv env exnc - - let structuralTypes = args' |> List.map (fun rf -> (rf.FormalType, rf.Range)) - let scSet = TyconConstraintInference.InferSetOfTyconsSupportingComparable cenv env.DisplayEnv [(exnc, structuralTypes)] - let seSet = TyconConstraintInference.InferSetOfTyconsSupportingEquatable cenv env.DisplayEnv [(exnc, structuralTypes)] - - // Augment the exception constructor with comparison and hash methods if needed - let binds = - match exnc.ExceptionInfo with - | TExnAbbrevRepr _ | TExnNone | TExnAsmRepr _ -> [] - | TExnFresh _ -> - AddAugmentationDeclarations.AddGenericHashAndComparisonDeclarations cenv env scSet seSet exnc - AddAugmentationDeclarations.AddGenericHashAndComparisonBindings cenv exnc - - binds, exnc - - - let TcExnDefn cenv envInitial parent (SynExceptionDefn(core, aug, m), scopem) = - let binds1, exnc = TcExnDefnCore cenv envInitial parent core - let envMutRec = AddLocalExnDefnAndReport cenv.tcSink scopem (AddLocalTycons cenv.g cenv.amap scopem [exnc] envInitial) exnc - - let defns = [MutRecShape.Tycon(MutRecDefnsPhase2DataForTycon(Some exnc, parent, ModuleOrMemberBinding, mkLocalEntityRef exnc, None, NoSafeInitInfo, [], aug, m, NoNewSlots, (fun () -> ())))] - let binds2, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem None envMutRec defns - let binds2flat = binds2 |> MutRecShapes.collectTycons |> List.collect snd - // Augment types with references to values that implement the pre-baked semantics of the type - let binds3 = AddAugmentationDeclarations.AddGenericEqualityBindings cenv envFinal exnc - binds1 @ binds2flat @ binds3, exnc, envFinal - - let TcExnSignature cenv envInitial parent tpenv (SynExceptionSig(core, aug, _), scopem) = - let binds, exnc = TcExnDefnCore cenv envInitial parent core - let envMutRec = AddLocalExnDefnAndReport cenv.tcSink scopem (AddLocalTycons cenv.g cenv.amap scopem [exnc] envInitial) exnc - let ecref = mkLocalEntityRef exnc - let vals, _ = TcTyconMemberSpecs cenv envMutRec (ContainerInfo(parent, Some(MemberOrValContainerInfo(ecref, None, None, NoSafeInitInfo, [])))) ModuleOrMemberBinding tpenv aug - binds, vals, ecref, envMutRec - - - -/// Bind type definitions -/// -/// We first establish the cores of a set of type definitions (i.e. everything -/// about the type definitions that doesn't involve values or expressions) -/// -/// This is a non-trivial multi-phase algorithm. The technique used -/// is to gradually "fill in" the fields of the type constructors. -/// -/// This use of mutation is very problematic. This has many dangers, -/// since the process of filling in the fields -/// involves creating, traversing and analyzing types that may recursively -/// refer to the types being defined. However a functional version of this -/// would need to re-implement certain type relations to work over a -/// partial representation of types. -module EstablishTypeDefinitionCores = - - /// Compute the mangled name of a type definition. 'doErase' is true for all type definitions except type abbreviations. - let private ComputeTyconName (longPath: Ident list, doErase: bool, typars: Typars) = - if longPath.Length <> 1 then error(Error(FSComp.SR.tcInvalidTypeExtension(), longPath.Head.idRange)) - let id = longPath.Head - let erasedArity = - if doErase then typars |> Seq.sumBy (fun tp -> if tp.IsErased then 0 else 1) - else typars.Length - mkSynId id.idRange (if erasedArity = 0 then id.idText else id.idText + "`" + string erasedArity) - - let private GetTyconAttribs g attrs = - let hasClassAttr = HasFSharpAttribute g g.attrib_ClassAttribute attrs - let hasAbstractClassAttr = HasFSharpAttribute g g.attrib_AbstractClassAttribute attrs - let hasInterfaceAttr = HasFSharpAttribute g g.attrib_InterfaceAttribute attrs - let hasStructAttr = HasFSharpAttribute g g.attrib_StructAttribute attrs - let hasMeasureAttr = HasFSharpAttribute g g.attrib_MeasureAttribute attrs - (hasClassAttr, hasAbstractClassAttr, hasInterfaceAttr, hasStructAttr, hasMeasureAttr) - - //------------------------------------------------------------------------- - // Type kind inference - //------------------------------------------------------------------------- - - let private InferTyconKind g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) = - let (hasClassAttr, hasAbstractClassAttr, hasInterfaceAttr, hasStructAttr, hasMeasureAttr) = GetTyconAttribs g attrs - let bi b = (if b then 1 else 0) - if (bi hasClassAttr + bi hasInterfaceAttr + bi hasStructAttr + bi hasMeasureAttr) > 1 || - (bi hasAbstractClassAttr + bi hasInterfaceAttr + bi hasStructAttr + bi hasMeasureAttr) > 1 then - error(Error(FSComp.SR.tcAttributesOfTypeSpecifyMultipleKindsForType(), m)) - - match kind with - | TyconUnspecified -> - if hasClassAttr || hasAbstractClassAttr || hasMeasureAttr then TyconClass - elif hasInterfaceAttr then TyconInterface - elif hasStructAttr then TyconStruct - elif isConcrete || not (isNil fields) then TyconClass - elif isNil slotsigs && inSig then TyconHiddenRepr - else TyconInterface - | k -> - if hasClassAttr && not (match k with TyconClass -> true | _ -> false) || - hasMeasureAttr && not (match k with TyconClass | TyconAbbrev | TyconHiddenRepr -> true | _ -> false) || - hasInterfaceAttr && not (match k with TyconInterface -> true | _ -> false) || - hasStructAttr && not (match k with TyconStruct | TyconRecord | TyconUnion -> true | _ -> false) then - error(Error(FSComp.SR.tcKindOfTypeSpecifiedDoesNotMatchDefinition(), m)) - k - - - let private (|TyconCoreAbbrevThatIsReallyAUnion|_|) (hasMeasureAttr, envinner, id: Ident) synTyconRepr = - match synTyconRepr with - | SynTypeDefnSimpleRepr.TypeAbbrev(_, SynType.LongIdent(LongIdentWithDots([unionCaseName], _)), m) - when - (not hasMeasureAttr && - (isNil (LookupTypeNameInEnvNoArity OpenQualified unionCaseName.idText envinner.eNameResEnv) || - id.idText = unionCaseName.idText)) -> - Some(unionCaseName, m) - | _ -> - None - - /// Get the component types that make a record, union or struct type. - /// - /// Used when determining if a structural type supports structural comparison. - let private GetStructuralElementsOfTyconDefn cenv env tpenv (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) tycon = - let thisTyconRef = mkLocalTyconRef tycon - let m = tycon.Range - let env = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) env - let env = MakeInnerEnvForTyconRef env thisTyconRef false - [ match synTyconRepr with - | SynTypeDefnSimpleRepr.None _ -> () - | SynTypeDefnSimpleRepr.Union (_, unionCases, _) -> - - for (UnionCase (_, _, args, _, _, m)) in unionCases do - match args with - | UnionCaseFields flds -> - for (Field(_, _, _, ty, _, _, _, m)) in flds do - let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty - yield (ty', m) - | UnionCaseFullType (ty, arity) -> - let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty - let curriedArgTys, _ = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m - if curriedArgTys.Length > 1 then - errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) - for argTys in curriedArgTys do - for (argty, _) in argTys do - yield (argty, m) - - | SynTypeDefnSimpleRepr.General (_, _, _, fields, _, _, implicitCtorSynPats, _) when tycon.IsFSharpStructOrEnumTycon -> // for structs - for (Field(_, isStatic, _, ty, _, _, _, m)) in fields do - if not isStatic then - let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty - yield (ty', m) - - match implicitCtorSynPats with - | None -> () - | Some spats -> - let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true NoCheckCxs env tpenv spats - for arg in ctorArgNames do - let ty = names.[arg].Type - let m = names.[arg].Ident.idRange - if not (isNil (ListSet.subtract typarEq (freeInTypeLeftToRight cenv.g false ty) tycon.TyparsNoRange)) then - errorR(Error(FSComp.SR.tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly(), m)) - yield (ty, m) - - | SynTypeDefnSimpleRepr.Record (_, fields, _) -> - for (Field(_, _, _, ty, _, _, _, m)) in fields do - let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty - yield (ty', m) - - | _ -> - () ] - - let ComputeModuleOrNamespaceKind g isModule typeNames attribs nm = - if not isModule then Namespace - elif ModuleNameIsMangled g attribs || Set.contains nm typeNames then FSharpModuleWithSuffix - else ModuleOrType - - let AdjustModuleName modKind nm = (match modKind with FSharpModuleWithSuffix -> nm+FSharpModuleSuffix | _ -> nm) - - - let TypeNamesInMutRecDecls cenv env (compDecls: MutRecShapes) = - [ for d in compDecls do - match d with - | MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(ComponentInfo(_, typars, _, ids, _, _, _, _), _, _, _, _, isAtOriginalTyconDefn), _) -> - if isAtOriginalTyconDefn && (TcTyparDecls cenv env typars |> List.forall (fun p -> p.Kind = TyparKind.Measure)) then - yield (List.last ids).idText - | _ -> () ] - |> set - - let TypeNamesInNonMutRecDecls defs = - [ for def in defs do - match def with - | SynModuleDecl.Types (typeSpecs, _) -> - for (TypeDefn(ComponentInfo(_, typars, _, ids, _, _, _, _), trepr, _, _)) in typeSpecs do - if isNil typars then - match trepr with - | SynTypeDefnRepr.ObjectModel(TyconAugmentation, _, _) -> () - | _ -> yield (List.last ids).idText - | _ -> () ] - |> set - - // Collect the type names so we can implicitly add the compilation suffix to module names - let TypeNamesInNonMutRecSigDecls defs = - [ for def in defs do - match def with - | SynModuleSigDecl.Types (typeSpecs, _) -> - for (TypeDefnSig(ComponentInfo(_, typars, _, ids, _, _, _, _), trepr, extraMembers, _)) in typeSpecs do - if isNil typars then - match trepr with - | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _), _) when not (isNil extraMembers) -> () - | _ -> yield (List.last ids).idText - | _ -> () ] - |> set - - let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo decls = - let (ComponentInfo(Attributes attribs, _parms, _constraints, longPath, xml, _, vis, im)) = compInfo - let id = ComputeModuleName longPath - let modAttrs = TcAttributes cenv envInitial AttributeTargets.ModuleDecl attribs - let modKind = ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText - let modName = AdjustModuleName modKind id.idText - - let vis, _ = ComputeAccessAndCompPath envInitial None id.idRange vis None parent - - CheckForDuplicateModule envInitial id.idText id.idRange - let id = ident (modName, id.idRange) - CheckForDuplicateConcreteType envInitial id.idText im - CheckNamespaceModuleOrTypeName cenv.g id - - let envForDecls, mtypeAcc = MakeInnerEnv envInitial id modKind - let mspec = NewModuleOrNamespace (Some envInitial.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType modKind)) - let innerParent = Parent (mkLocalModRef mspec) - let innerTypeNames = TypeNamesInMutRecDecls cenv envForDecls decls - MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, innerTypeNames, envForDecls) - - /// Establish 'type C < T1... TN > = ...' including - /// - computing the mangled name for C - /// but - /// - we don't yet 'properly' establish constraints on type parameters - let private TcTyconDefnCore_Phase1A_BuildInitialTycon cenv env parent (MutRecDefnsPhase1DataForTycon(synTyconInfo, synTyconRepr, _, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, _)) = - let (ComponentInfo (_, synTypars, _, id, doc, preferPostfix, synVis, _)) = synTyconInfo - let checkedTypars = TcTyparDecls cenv env synTypars - id |> List.iter (CheckNamespaceModuleOrTypeName cenv.g) - match synTyconRepr with - | SynTypeDefnSimpleRepr.Exception synExnDefnRepr -> - TcExceptionDeclarations.TcExnDefnCore_Phase1A cenv env parent synExnDefnRepr - | _ -> - let id = ComputeTyconName (id, (match synTyconRepr with SynTypeDefnSimpleRepr.TypeAbbrev _ -> false | _ -> true), checkedTypars) - - // Augmentations of type definitions are allowed within the same file as long as no new type representation or abbreviation is given - CheckForDuplicateConcreteType env id.idText id.idRange - let vis, cpath = ComputeAccessAndCompPath env None id.idRange synVis None parent - - // Establish the visibility of the representation, e.g. - // type R = - // private { f: int } - // member x.P = x.f + x.f - let synVisOfRepr = - match synTyconRepr with - | SynTypeDefnSimpleRepr.None _ -> None - | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None - | SynTypeDefnSimpleRepr.Union (vis, _, _) -> vis - | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None - | SynTypeDefnSimpleRepr.Record (vis, _, _) -> vis - | SynTypeDefnSimpleRepr.General _ -> None - | SynTypeDefnSimpleRepr.Enum _ -> None - | SynTypeDefnSimpleRepr.Exception _ -> None - - let visOfRepr, _ = ComputeAccessAndCompPath env None id.idRange synVisOfRepr None parent - let visOfRepr = combineAccess vis visOfRepr - // If we supported nested types and modules then additions would be needed here - let lmtyp = MaybeLazy.Strict (NewEmptyModuleOrNamespaceType ModuleOrType) - - NewTycon(cpath, id.idText, id.idRange, vis, visOfRepr, TyparKind.Type, LazyWithContext.NotLazy checkedTypars, doc.ToXmlDoc(), preferPostfix, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, lmtyp) - - //------------------------------------------------------------------------- - /// Establishing type definitions: early phase: work out the basic kind of the type definition - /// - /// On entry: the Tycon for the type definition has been created but many of its fields are not - /// yet filled in. - /// On exit: the entity_tycon_repr field of the tycon has been filled in with a dummy value that - /// indicates the kind of the type constructor - /// Also, some adhoc checks are made. - /// - /// synTyconInfo: Syntactic AST for the name, attributes etc. of the type constructor - /// synTyconRepr: Syntactic AST for the RHS of the type definition - let private TcTyconDefnCore_Phase1B_EstablishBasicKind cenv inSig envinner (MutRecDefnsPhase1DataForTycon(synTyconInfo, synTyconRepr, _, _, _, _)) (tycon: Tycon) = - let (ComponentInfo(Attributes synAttrs, typars, _, _, _, _, _, _)) = synTyconInfo - let m = tycon.Range - let id = tycon.Id - - // 'Check' the attributes. We return the results to avoid having to re-check them in all other phases. - // Allow failure of constructor resolution because Vals for members in the same recursive group are not yet available - let attrs, getFinalAttrs = TcAttributesCanFail cenv envinner AttributeTargets.TyconDecl synAttrs - let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs - - let isStructRecordOrUnionType = - match synTyconRepr with - | SynTypeDefnSimpleRepr.Record _ - | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) _ - | SynTypeDefnSimpleRepr.Union _ -> - HasFSharpAttribute cenv.g cenv.g.attrib_StructAttribute attrs - | _ -> - false - - tycon.SetIsStructRecordOrUnion isStructRecordOrUnionType - - // Set the compiled name, if any - tycon.SetCompiledName (TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs) - - if hasMeasureAttr then - tycon.SetTypeOrMeasureKind TyparKind.Measure - if not (isNil typars) then error(Error(FSComp.SR.tcMeasureDefinitionsCannotHaveTypeParameters(), m)) - - let repr = - match synTyconRepr with - | SynTypeDefnSimpleRepr.Exception _ -> TNoRepr - | SynTypeDefnSimpleRepr.None m -> - // Run InferTyconKind to raise errors on inconsistent attribute sets - InferTyconKind cenv.g (TyconHiddenRepr, attrs, [], [], inSig, true, m) |> ignore - if not inSig && not hasMeasureAttr then - errorR(Error(FSComp.SR.tcTypeRequiresDefinition(), m)) - if hasMeasureAttr then - TFSharpObjectRepr { fsobjmodel_kind=TTyconClass - fsobjmodel_vslots=[] - fsobjmodel_rfields=MakeRecdFieldsTable [] } - else - TNoRepr - - | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (_, m) - | SynTypeDefnSimpleRepr.Union (_, _, m) -> - // Run InferTyconKind to raise errors on inconsistent attribute sets - InferTyconKind cenv.g (TyconUnion, attrs, [], [], inSig, true, m) |> ignore - // Note: the table of union cases is initially empty - MakeUnionRepr [] - - | SynTypeDefnSimpleRepr.TypeAbbrev _ -> - // Run InferTyconKind to raise errors on inconsistent attribute sets - InferTyconKind cenv.g (TyconAbbrev, attrs, [], [], inSig, true, m) |> ignore - TNoRepr - - | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (s, m) -> - // Run InferTyconKind to raise errors on inconsistent attribute sets - InferTyconKind cenv.g (TyconILAssemblyCode, attrs, [], [], inSig, true, m) |> ignore - TAsmRepr s - - | SynTypeDefnSimpleRepr.Record (_, _, m) -> - // Run InferTyconKind to raise errors on inconsistent attribute sets - InferTyconKind cenv.g (TyconRecord, attrs, [], [], inSig, true, m) |> ignore - // Note: the table of record fields is initially empty - TRecdRepr (MakeRecdFieldsTable []) - - | SynTypeDefnSimpleRepr.General (kind, _, slotsigs, fields, isConcrete, _, _, _) -> - let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) - match kind with - | TyconHiddenRepr -> - TNoRepr - | _ -> - let kind = - match kind with - | TyconClass -> TTyconClass - | TyconInterface -> TTyconInterface - | TyconDelegate _ -> TTyconDelegate (MakeSlotSig("Invoke", cenv.g.unit_ty, [], [], [], None)) - | TyconStruct -> TTyconStruct - | _ -> error(InternalError("should have inferred tycon kind", m)) - - let repr = { fsobjmodel_kind=kind - fsobjmodel_vslots=[] - fsobjmodel_rfields=MakeRecdFieldsTable [] } - TFSharpObjectRepr repr - - | SynTypeDefnSimpleRepr.Enum _ -> - let kind = TTyconEnum - let repr = { fsobjmodel_kind=kind - fsobjmodel_vslots=[] - fsobjmodel_rfields=MakeRecdFieldsTable [] } - TFSharpObjectRepr repr - - // OK, now fill in the (partially computed) type representation - tycon.entity_tycon_repr <- repr - attrs, getFinalAttrs - -#if !NO_EXTENSIONTYPING - /// Get the items on the r.h.s. of a 'type X = ABC<...>' definition - let private TcTyconDefnCore_GetGenerateDeclaration_Rhs rhsType = - match rhsType with - | SynType.App (SynType.LongIdent(LongIdentWithDots(tc, _)), _, args, _commas, _, _postfix, m) -> Some(tc, args, m) - | SynType.LongIdent (LongIdentWithDots(tc, _) as lidwd) -> Some(tc, [], lidwd.Range) - | SynType.LongIdentApp (SynType.LongIdent (LongIdentWithDots(tc, _)), LongIdentWithDots(longId, _), _, args, _commas, _, m) -> Some(tc@longId, args, m) - | _ -> None - - /// Check whether 'type X = ABC<...>' is a generative provided type definition - let private TcTyconDefnCore_TryAsGenerateDeclaration cenv envinner tpenv (tycon: Tycon, rhsType) = - - let tcref = mkLocalTyconRef tycon - match TcTyconDefnCore_GetGenerateDeclaration_Rhs rhsType with - | None -> None - | Some (tc, args, m) -> - let ad = envinner.eAccessRights - match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInType OpenQualified envinner.eNameResEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.Yes with - | Result tcrefBeforeStaticArguments when - tcrefBeforeStaticArguments.IsProvided && - not tcrefBeforeStaticArguments.IsErased -> - - let typeBeforeArguments = - match tcrefBeforeStaticArguments.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.ProvidedType - | _ -> failwith "unreachable" - - if ExtensionTyping.IsGeneratedTypeDirectReference (typeBeforeArguments, m) then - let optGeneratedTypePath = Some (tcref.CompilationPath.MangledPath @ [ tcref.LogicalName ]) - let _hasNoArgs, providedTypeAfterStaticArguments, checkTypeName = TcProvidedTypeAppToStaticConstantArgs cenv envinner optGeneratedTypePath tpenv tcrefBeforeStaticArguments args m - let isGenerated = providedTypeAfterStaticArguments.PUntaint((fun st -> not st.IsErased), m) - if isGenerated then - Some (tcrefBeforeStaticArguments, providedTypeAfterStaticArguments, checkTypeName, args, m) - else - None // The provided type (after ApplyStaticArguments) must also be marked 'IsErased=false' - else - // This must be a direct reference to a generated type, otherwise it is a type abbreviation - None - | _ -> - None - - - /// Check and establish a 'type X = ABC<...>' provided type definition - let private TcTyconDefnCore_Phase1C_EstablishDeclarationForGeneratedSetOfTypes cenv inSig (tycon: Tycon, rhsType: SynType, tcrefForContainer: TyconRef, theRootType: Tainted, checkTypeName, args, m) = - // Explanation: We are definitely on the compilation thread here, we just have not propagated the token this far. - let ctok = AssumeCompilationThreadWithoutEvidence() - - let tcref = mkLocalTyconRef tycon - try - let resolutionEnvironment = - if not (isNil args) then - checkTypeName() - let resolutionEnvironment = - match tcrefForContainer.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.ResolutionEnvironment - | _ -> failwith "unreachable" - resolutionEnvironment - - // Build up a mapping from System.Type --> TyconRef/ILTypeRef, to allow reverse-mapping - // of types - - let previousContext = (theRootType.PApply ((fun x -> x.Context), m)).PUntaint ((fun x -> x), m) - let lookupILTypeRef, lookupTyconRef = previousContext.GetDictionaries() - - let ctxt = ProvidedTypeContext.Create(lookupILTypeRef, lookupTyconRef) - - // Create a new provided type which captures the reverse-remapping tables. - let theRootTypeWithRemapping = theRootType.PApply ((fun x -> ProvidedType.ApplyContext(x, ctxt)), m) - - let isRootGenerated, rootProvAssemStaticLinkInfoOpt = - let stRootAssembly = theRootTypeWithRemapping.PApply((fun st -> st.Assembly), m) - - cenv.amap.assemblyLoader.GetProvidedAssemblyInfo (ctok, m, stRootAssembly) - - let isRootGenerated = isRootGenerated || theRootTypeWithRemapping.PUntaint((fun st -> not st.IsErased), m) - - if not isRootGenerated then - let desig = theRootTypeWithRemapping.TypeProviderDesignation - let nm = theRootTypeWithRemapping.PUntaint((fun st -> st.FullName), m) - error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) - - cenv.createsGeneratedProvidedTypes <- true - - // In compiled code, all types in the set of generated types end up being both generated and relocated, unless relocation is suppressed - let isForcedSuppressRelocate = theRootTypeWithRemapping.PUntaint((fun st -> st.IsSuppressRelocate), m) - if isForcedSuppressRelocate && canAccessFromEverywhere tycon.Accessibility && not cenv.isScript then - errorR(Error(FSComp.SR.tcGeneratedTypesShouldBeInternalOrPrivate(), tcref.Range)) - - let isSuppressRelocate = cenv.g.isInteractive || isForcedSuppressRelocate - - // Adjust the representation of the container type - let repr = Construct.NewProvidedTyconRepr(resolutionEnvironment, theRootTypeWithRemapping, - Import.ImportProvidedType cenv.amap m, - isSuppressRelocate, - m=m) - tycon.entity_tycon_repr <- repr - // Record the details so we can map System.Type --> TyconRef - let ilOrigRootTypeRef = GetOriginalILTypeRefOfProvidedType (theRootTypeWithRemapping, m) - theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st.RawSystemType)) ; lookupTyconRef.Add(st.RawSystemType, tcref)), m) - - // Record the details so we can map System.Type --> ILTypeRef, including the relocation if any - if not isSuppressRelocate then - let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType - theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st.RawSystemType)) ; lookupILTypeRef.Add(st.RawSystemType, ilTgtRootTyRef)), m) - - // Iterate all nested types and force their embedding, to populate the mapping from System.Type --> TyconRef/ILTypeRef. - // This is only needed for generated types, because for other types the System.Type objects self-describe - // their corresponding F# type. - let rec doNestedType (eref: EntityRef) (st: Tainted) = - - // Check the type is a generated type - let isGenerated, provAssemStaticLinkInfoOpt = - let stAssembly = st.PApply((fun st -> st.Assembly), m) - cenv.amap.assemblyLoader.GetProvidedAssemblyInfo (ctok, m, stAssembly) - - let isGenerated = isGenerated || st.PUntaint((fun st -> not st.IsErased), m) - - if not isGenerated then - let desig = st.TypeProviderDesignation - let nm = st.PUntaint((fun st -> st.FullName), m) - error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) - - // Embed the type into the module we're compiling - let cpath = eref.CompilationPath.NestedCompPath eref.LogicalName ModuleOrNamespaceKind.ModuleOrType - let access = combineAccess tycon.Accessibility (if st.PUntaint((fun st -> st.IsPublic || st.IsNestedPublic), m) then taccessPublic else taccessPrivate cpath) - - let nestedTycon = Construct.NewProvidedTycon(resolutionEnvironment, st, - Import.ImportProvidedType cenv.amap m, - isSuppressRelocate, - m=m, cpath=cpath, access = access) - eref.ModuleOrNamespaceType.AddProvidedTypeEntity nestedTycon - - let nestedTyRef = eref.NestedTyconRef nestedTycon - let ilOrigTypeRef = GetOriginalILTypeRefOfProvidedType (st, m) - - // Record the details so we can map System.Type --> TyconRef - st.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st.RawSystemType)) ; lookupTyconRef.Add(st.RawSystemType, nestedTyRef)), m) - - if isGenerated then - let ilTgtTyRef = nestedTycon.CompiledRepresentationForNamedType - // Record the details so we can map System.Type --> ILTypeRef - st.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st.RawSystemType)) ; lookupILTypeRef.Add(st.RawSystemType, ilTgtTyRef)), m) - - // Record the details so we can build correct ILTypeDefs during static linking rewriting - if not isSuppressRelocate then - match provAssemStaticLinkInfoOpt with - | Some provAssemStaticLinkInfo -> provAssemStaticLinkInfo.ILTypeMap.[ilOrigTypeRef] <- ilTgtTyRef - | None -> () - - ProviderGeneratedType(ilOrigTypeRef, ilTgtTyRef, doNestedTypes nestedTyRef st) - else - ProviderGeneratedType(ilOrigTypeRef, ilOrigTypeRef, doNestedTypes nestedTyRef st) - - - //System.Diagnostics.Debug.Assert eref.TryDeref.IsSome - - and doNestedTypes (eref: EntityRef) (st: Tainted) = - st.PApplyArray((fun st -> st.GetAllNestedTypes()), "GetAllNestedTypes", m) - |> Array.map (doNestedType eref) - |> Array.toList - - let nested = doNestedTypes tcref theRootTypeWithRemapping - if not isSuppressRelocate then - - let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType - match rootProvAssemStaticLinkInfoOpt with - | Some provAssemStaticLinkInfo -> provAssemStaticLinkInfo.ILTypeMap.[ilOrigRootTypeRef] <- ilTgtRootTyRef - | None -> () - - if not inSig then - cenv.amap.assemblyLoader.RecordGeneratedTypeRoot (ProviderGeneratedType(ilOrigRootTypeRef, ilTgtRootTyRef, nested)) - - with e -> - errorRecovery e rhsType.Range -#endif - - /// Establish any type abbreviations - /// - /// e.g. for - /// type B<'a when 'a: C> = DDD of C - /// and C = B - /// - /// we establish - /// - /// Entity('B) - /// TypeAbbrev = TType_app(Entity('int'), []) - /// - /// and for - /// - /// type C = B - /// - /// we establish - /// TypeAbbrev = TType_app(Entity('B'), []) - /// - /// Note that for - /// type PairOfInts = int * int - /// then after running this phase and checking for cycles, operations - // such as 'isRefTupleTy' will return reliable results, e.g. isRefTupleTy on the - /// TAST type for 'PairOfInts' will report 'true' - // - let private TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations cenv envinner inSig tpenv pass (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) (tycon: Tycon) (attrs: Attribs) = - let m = tycon.Range - let checkCxs = if (pass = SecondPass) then CheckCxs else NoCheckCxs - let firstPass = (pass = FirstPass) - try - let id = tycon.Id - let thisTyconRef = mkLocalTyconRef tycon - - let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs - let hasMeasureableAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureableAttribute attrs - let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner - let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false - - match synTyconRepr with - - // This unfortunate case deals with "type x = A" - // In F# this only defines a new type if A is not in scope - // as a type constructor, or if the form type A = A is used. - // "type x = | A" can always be used instead. - | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) _ -> () - - | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, m) -> - -#if !NO_EXTENSIONTYPING - // Check we have not already decided that this is a generative provided type definition. If we have already done this (i.e. this is the second pass - // for a generative provided type definition, then there is no more work to do). - if (match tycon.entity_tycon_repr with TNoRepr -> true | _ -> false) then - - // Determine if this is a generative type definition. - match TcTyconDefnCore_TryAsGenerateDeclaration cenv envinner tpenv (tycon, rhsType) with - | Some (tcrefForContainer, providedTypeAfterStaticArguments, checkTypeName, args, m) -> - // If this is a generative provided type definition then establish the provided type and all its nested types. Only do this on the first pass. - if firstPass then - TcTyconDefnCore_Phase1C_EstablishDeclarationForGeneratedSetOfTypes cenv inSig (tycon, rhsType, tcrefForContainer, providedTypeAfterStaticArguments, checkTypeName, args, m) - | None -> -#else - ignore inSig -#endif - - // This case deals with ordinary type and measure abbreviations - if not hasMeasureableAttr then - let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type - let ty, _ = TcTypeOrMeasureAndRecover (Some kind) cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner tpenv rhsType - - if not firstPass then - let ftyvs = freeInTypeLeftToRight cenv.g false ty - let typars = tycon.Typars m - if ftyvs.Length <> typars.Length then - errorR(Deprecated(FSComp.SR.tcTypeAbbreviationHasTypeParametersMissingOnType(), tycon.Range)) - - if firstPass then - tycon.SetTypeAbbrev (Some ty) - - | _ -> () - - with e -> - errorRecovery e m - - // Third phase: check and publish the super types. Run twice, once before constraints are established - // and once after - let private TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig pass (envMutRec, mutRecDefns: MutRecShape<(_ * (Tycon * (Attribs * _)) option), _, _, _, _> list) = - let checkCxs = if (pass = SecondPass) then CheckCxs else NoCheckCxs - let firstPass = (pass = FirstPass) - - // Publish the immediately declared interfaces. - let tyconWithImplementsL = - (envMutRec, mutRecDefns) ||> MutRecShapes.mapTyconsWithEnv (fun envinner (origInfo, tyconAndAttrsOpt) -> - match origInfo, tyconAndAttrsOpt with - | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> - let (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, explicitImplements, _, _, _)) = typeDefCore - let m = tycon.Range - let tcref = mkLocalTyconRef tycon - let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner - let envinner = MakeInnerEnvForTyconRef envinner tcref false - - let implementedTys, _ = List.mapFold (mapFoldFst (TcTypeAndRecover cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner)) tpenv explicitImplements - - if firstPass then - tycon.entity_attribs <- attrs - - let implementedTys, inheritedTys = - match synTyconRepr with - | SynTypeDefnSimpleRepr.Exception _ -> [], [] - | SynTypeDefnSimpleRepr.General (kind, inherits, slotsigs, fields, isConcrete, _, _, m) -> - let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) - - let inherits = inherits |> List.map (fun (ty, m, _) -> (ty, m)) - let inheritedTys = fst (List.mapFold (mapFoldFst (TcTypeAndRecover cenv NoNewTypars checkCxs ItemOccurence.UseInType envinner)) tpenv inherits) - let implementedTys, inheritedTys = - match kind with - | TyconInterface -> - explicitImplements |> List.iter (fun (_, m) -> errorR(Error(FSComp.SR.tcInterfacesShouldUseInheritNotInterface(), m))) - (implementedTys @ inheritedTys), [] - | _ -> implementedTys, inheritedTys - implementedTys, inheritedTys - | SynTypeDefnSimpleRepr.Enum _ | SynTypeDefnSimpleRepr.None _ | SynTypeDefnSimpleRepr.TypeAbbrev _ - - | SynTypeDefnSimpleRepr.Union _ | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ | SynTypeDefnSimpleRepr.Record _ -> - // REVIEW: we could do the IComparable/IStructuralHash interface analysis here. - // This would let the type satisfy more recursive IComparable/IStructuralHash constraints - implementedTys, [] - - for (implementedTy, m) in implementedTys do - if firstPass && isErasedType cenv.g implementedTy then - errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) - - // Publish interfaces, but only on the first pass, to avoid a duplicate interface check - if firstPass then - implementedTys |> List.iter (fun (ty, m) -> PublishInterface cenv envinner.DisplayEnv tcref m false ty) - - Some (attrs, inheritedTys, synTyconRepr, tycon) - | _ -> None) - - // Publish the attributes and supertype - tyconWithImplementsL |> MutRecShapes.iterTycons (Option.iter (fun (attrs, inheritedTys, synTyconRepr, tycon) -> - let m = tycon.Range - try - let super = - match synTyconRepr with - | SynTypeDefnSimpleRepr.Exception _ -> Some cenv.g.exn_ty - | SynTypeDefnSimpleRepr.None _ -> None - | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None - | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None - | SynTypeDefnSimpleRepr.Union _ - | SynTypeDefnSimpleRepr.Record _ -> - if tycon.IsStructRecordOrUnionTycon then Some(cenv.g.system_Value_ty) - else None - | SynTypeDefnSimpleRepr.General (kind, _, slotsigs, fields, isConcrete, _, _, _) -> - let kind = InferTyconKind cenv.g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) - - match inheritedTys with - | [] -> - match kind with - | TyconStruct -> Some(cenv.g.system_Value_ty) - | TyconDelegate _ -> Some(cenv.g.system_MulticastDelegate_ty ) - | TyconHiddenRepr | TyconClass | TyconInterface -> None - | _ -> error(InternalError("should have inferred tycon kind", m)) - - | [(ty, m)] -> - if not firstPass && not (match kind with TyconClass -> true | _ -> false) then - errorR (Error(FSComp.SR.tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes(), m)) - CheckSuperType cenv ty m - if isTyparTy cenv.g ty then - if firstPass then - errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), m)) - Some cenv.g.obj_ty // a "super" that is a variable type causes grief later - else - Some ty - | _ -> - error(Error(FSComp.SR.tcTypesCannotInheritFromMultipleConcreteTypes(), m)) - - | SynTypeDefnSimpleRepr.Enum _ -> - Some(cenv.g.system_Enum_ty) - - // Allow super type to be a function type but convert back to FSharpFunc to make sure it has metadata - // (We don't apply the same rule to tuple types, i.e. no F#-declared inheritors of those are permitted) - let super = - super |> Option.map (fun ty -> - if isFunTy cenv.g ty then - let (a,b) = destFunTy cenv.g ty - mkAppTy cenv.g.fastFunc_tcr [a; b] - else ty) - - // Publish the super type - tycon.TypeContents.tcaug_super <- super - - with e -> errorRecovery e m)) - - /// Establish the fields, dispatch slots and union cases of a type - let private TcTyconDefnCore_Phase1G_EstablishRepresentation cenv envinner tpenv inSig (MutRecDefnsPhase1DataForTycon(_, synTyconRepr, _, _, _, _)) (tycon: Tycon) (attrs: Attribs) = - let g = cenv.g - let m = tycon.Range - try - let id = tycon.Id - let thisTyconRef = mkLocalTyconRef tycon - let innerParent = Parent thisTyconRef - let thisTyInst, thisTy = generalizeTyconRef thisTyconRef - - let hasAbstractAttr = HasFSharpAttribute g g.attrib_AbstractClassAttribute attrs - let hasSealedAttr = - // The special case is needed for 'unit' because the 'Sealed' attribute is not yet available when this type is defined. - if g.compilingFslib && id.idText = "Unit" then - Some true - else - TryFindFSharpBoolAttribute g g.attrib_SealedAttribute attrs - let hasMeasureAttr = HasFSharpAttribute g g.attrib_MeasureAttribute attrs - - // REVIEW: for hasMeasureableAttr we need to be stricter about checking these - // are only used on exactly the right kinds of type definitions and not in conjunction with other attributes. - let hasMeasureableAttr = HasFSharpAttribute g g.attrib_MeasureableAttribute attrs - let hasCLIMutable = HasFSharpAttribute g g.attrib_CLIMutableAttribute attrs - - let structLayoutAttr = TryFindFSharpInt32Attribute g g.attrib_StructLayoutAttribute attrs - let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute g g.attrib_AllowNullLiteralAttribute attrs = Some true - - if hasAbstractAttr then - tycon.TypeContents.tcaug_abstract <- true - - tycon.entity_attribs <- attrs - let noAbstractClassAttributeCheck() = - if hasAbstractAttr then errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) - - let noAllowNullLiteralAttributeCheck() = - if hasAllowNullLiteralAttr then errorR (Error(FSComp.SR.tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute(), m)) - - - let allowNullLiteralAttributeCheck() = - if hasAllowNullLiteralAttr then - tycon.TypeContents.tcaug_super |> Option.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) - tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (fun ty -> if not (TypeNullIsExtraValue g m ty) then errorR (Error(FSComp.SR.tcAllowNullTypesMayOnlyInheritFromAllowNullTypes(), m))) - - - let structLayoutAttributeCheck allowed = - let explicitKind = int32 System.Runtime.InteropServices.LayoutKind.Explicit - match structLayoutAttr with - | Some kind -> - if allowed then - if kind = explicitKind then - warning(PossibleUnverifiableCode m) - elif List.isEmpty (thisTyconRef.Typars m) then - errorR (Error(FSComp.SR.tcOnlyStructsCanHaveStructLayout(), m)) - else - errorR (Error(FSComp.SR.tcGenericTypesCannotHaveStructLayout(), m)) - | None -> () - - let hiddenReprChecks hasRepr = - structLayoutAttributeCheck false - if hasSealedAttr = Some false || (hasRepr && hasSealedAttr <> Some true && not (id.idText = "Unit" && g.compilingFslib) ) then - errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) - if hasAbstractAttr then - errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) - - let noMeasureAttributeCheck() = - if hasMeasureAttr then errorR (Error(FSComp.SR.tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure(), m)) - - let noCLIMutableAttributeCheck() = - if hasCLIMutable then errorR (Error(FSComp.SR.tcThisTypeMayNotHaveACLIMutableAttribute(), m)) - - let noSealedAttributeCheck k = - if hasSealedAttr = Some true then errorR (Error(k(), m)) - - let noFieldsCheck(fields': RecdField list) = - match fields' with - | (rf :: _) -> errorR (Error(FSComp.SR.tcInterfaceTypesAndDelegatesCannotContainFields(), rf.Range)) - | _ -> () - - - let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner - let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false - - - // Notify the Language Service about field names in record/class declaration - let ad = envinner.eAccessRights - let writeFakeRecordFieldsToSink (fields: RecdField list) = - let nenv = envinner.NameEnv - // Record fields should be visible from IntelliSense, so add fake names for them (similarly to "let a = ..") - for fspec in fields do - if not fspec.IsCompilerGenerated then - let info = RecdFieldInfo(thisTyInst, thisTyconRef.MakeNestedRecdFieldRef fspec) - let nenv' = AddFakeNameToNameEnv fspec.Name nenv (Item.RecdField info) - // Name resolution gives better info for tooltips - let item = FreshenRecdFieldRef cenv.nameResolver m (thisTyconRef.MakeNestedRecdFieldRef fspec) - CallNameResolutionSink cenv.tcSink (fspec.Range, nenv, item, item, emptyTyparInst, ItemOccurence.Binding, envinner.DisplayEnv, ad) - // Environment is needed for completions - CallEnvSink cenv.tcSink (fspec.Range, nenv', ad) - - // Notify the Language Service about constructors in discriminated union declaration - let writeFakeUnionCtorsToSink (unionCases: UnionCase list) = - let nenv = envinner.NameEnv - // Constructors should be visible from IntelliSense, so add fake names for them - for unionCase in unionCases do - let info = UnionCaseInfo(thisTyInst, mkUnionCaseRef thisTyconRef unionCase.Id.idText) - let nenv' = AddFakeNameToNameEnv unionCase.Id.idText nenv (Item.UnionCase(info, false)) - // Report to both - as in previous function - let item = Item.UnionCase(info, false) - CallNameResolutionSink cenv.tcSink (unionCase.Range, nenv, item, item, emptyTyparInst, ItemOccurence.Binding, envinner.DisplayEnv, ad) - CallEnvSink cenv.tcSink (unionCase.Id.idRange, nenv', ad) - - let typeRepr, baseValOpt, safeInitInfo = - match synTyconRepr with - - | SynTypeDefnSimpleRepr.Exception synExnDefnRepr -> - let parent = Parent (mkLocalTyconRef tycon) - TcExceptionDeclarations.TcExnDefnCore_Phase1G_EstablishRepresentation cenv envinner parent tycon synExnDefnRepr |> ignore - TNoRepr, None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.None _ -> - hiddenReprChecks false - noAllowNullLiteralAttributeCheck() - if hasMeasureAttr then - let repr = TFSharpObjectRepr { fsobjmodel_kind=TTyconClass - fsobjmodel_vslots=[] - fsobjmodel_rfields= MakeRecdFieldsTable [] } - repr, None, NoSafeInitInfo - else - TNoRepr, None, NoSafeInitInfo - - // This unfortunate case deals with "type x = A" - // In F# this only defines a new type if A is not in scope - // as a type constructor, or if the form type A = A is used. - // "type x = | A" can always be used instead. - | TyconCoreAbbrevThatIsReallyAUnion (hasMeasureAttr, envinner, id) (unionCaseName, _) -> - - structLayoutAttributeCheck false - noAllowNullLiteralAttributeCheck() - TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName - let unionCase = NewUnionCase unionCaseName [] thisTy [] XmlDoc.Empty tycon.Accessibility - writeFakeUnionCtorsToSink [ unionCase ] - MakeUnionRepr [ unionCase ], None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ThereWereSignificantParseErrorsSoDoNotTypecheckThisNode, _rhsType, _) -> - TNoRepr, None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, _) -> - if hasSealedAttr = Some true then - errorR (Error(FSComp.SR.tcAbbreviatedTypesCannotBeSealed(), m)) - noAbstractClassAttributeCheck() - noAllowNullLiteralAttributeCheck() - if hasMeasureableAttr then - let kind = if hasMeasureAttr then TyparKind.Measure else TyparKind.Type - let theTypeAbbrev, _ = TcTypeOrMeasureAndRecover (Some kind) cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv rhsType - - TMeasureableRepr theTypeAbbrev, None, NoSafeInitInfo - // If we already computed a representation, e.g. for a generative type definition, then don't change it here. - elif (match tycon.TypeReprInfo with TNoRepr -> false | _ -> true) then - tycon.TypeReprInfo, None, NoSafeInitInfo - else - TNoRepr, None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.Union (_, unionCases, _) -> - noCLIMutableAttributeCheck() - noMeasureAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedDU - noAbstractClassAttributeCheck() - noAllowNullLiteralAttributeCheck() - structLayoutAttributeCheck false - let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy tpenv unionCases - - if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then - let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft.Name ] - if fieldNames |> List.distinct |> List.length <> fieldNames.Length then - errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) - - writeFakeUnionCtorsToSink unionCases - MakeUnionRepr unionCases, None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.Record (_, fields, _) -> - noMeasureAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedRecord - noAbstractClassAttributeCheck() - noAllowNullLiteralAttributeCheck() - structLayoutAttributeCheck true // these are allowed for records - let recdFields = TcRecdUnionAndEnumDeclarations.TcNamedFieldDecls cenv envinner innerParent false tpenv fields - recdFields |> CheckDuplicates (fun f -> f.Id) "field" |> ignore - writeFakeRecordFieldsToSink recdFields - TRecdRepr (MakeRecdFieldsTable recdFields), None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (s, _) -> - noCLIMutableAttributeCheck() - noMeasureAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedAssemblyCode - noAllowNullLiteralAttributeCheck() - structLayoutAttributeCheck false - noAbstractClassAttributeCheck() - TAsmRepr s, None, NoSafeInitInfo - - | SynTypeDefnSimpleRepr.General (kind, inherits, slotsigs, fields, isConcrete, isIncrClass, implicitCtorSynPats, _) -> - let userFields = TcRecdUnionAndEnumDeclarations.TcNamedFieldDecls cenv envinner innerParent isIncrClass tpenv fields - let implicitStructFields = - [ // For structs with an implicit ctor, determine the fields immediately based on the arguments - match implicitCtorSynPats with - | None -> - () - | Some spats -> - if tycon.IsFSharpStructOrEnumTycon then - let ctorArgNames, (_, names, _) = TcSimplePatsOfUnknownType cenv true CheckCxs envinner tpenv spats - for arg in ctorArgNames do - let ty = names.[arg].Type - let id = names.[arg].Ident - let taccess = TAccess [envinner.eAccessPath] - yield NewRecdField false None id false ty false false [(*no property attributes*)] [(*no field attributes *)] XmlDoc.Empty taccess (*compiler generated:*)true ] - - (userFields @ implicitStructFields) |> CheckDuplicates (fun f -> f.Id) "field" |> ignore - writeFakeRecordFieldsToSink userFields - - let superTy = tycon.TypeContents.tcaug_super - let containerInfo = TyconContainerInfo(innerParent, thisTyconRef, thisTyconRef.Typars m, NoSafeInitInfo) - let kind = InferTyconKind g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) - match kind with - | TyconHiddenRepr -> - hiddenReprChecks true - noAllowNullLiteralAttributeCheck() - TNoRepr, None, NoSafeInitInfo - | _ -> - - // Note: for a mutually recursive set we can't check this condition - // until "isSealedTy" and "isClassTy" give reliable results. - superTy |> Option.iter (fun ty -> - let m = match inherits with | [] -> m | ((_, m, _) :: _) -> m - if isSealedTy g ty then - errorR(Error(FSComp.SR.tcCannotInheritFromSealedType(), m)) - elif not (isClassTy g ty) then - errorR(Error(FSComp.SR.tcCannotInheritFromInterfaceType(), m))) - - let kind = - match kind with - | TyconStruct -> - noCLIMutableAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedStruct - noAbstractClassAttributeCheck() - noAllowNullLiteralAttributeCheck() - if not (isNil slotsigs) then - errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(), m)) - structLayoutAttributeCheck true - - TTyconStruct - | TyconInterface -> - if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) - noCLIMutableAttributeCheck() - structLayoutAttributeCheck false - noAbstractClassAttributeCheck() - allowNullLiteralAttributeCheck() - noFieldsCheck userFields - TTyconInterface - | TyconClass -> - noCLIMutableAttributeCheck() - structLayoutAttributeCheck(not isIncrClass) - allowNullLiteralAttributeCheck() - TTyconClass - | TyconDelegate (ty, arity) -> - noCLIMutableAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedDelegate - structLayoutAttributeCheck false - noAllowNullLiteralAttributeCheck() - noAbstractClassAttributeCheck() - noFieldsCheck userFields - let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType envinner tpenv ty - let _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm g (arity |> TranslateTopValSynInfo m (TcAttributes cenv envinner) |> TranslatePartialArity []) ty' m - if curriedArgInfos.Length < 1 then error(Error(FSComp.SR.tcInvalidDelegateSpecification(), m)) - if curriedArgInfos.Length > 1 then error(Error(FSComp.SR.tcDelegatesCannotBeCurried(), m)) - let ttps = thisTyconRef.Typars m - let fparams = curriedArgInfos.Head |> List.map MakeSlotParam - TTyconDelegate (MakeSlotSig("Invoke", thisTy, ttps, [], [fparams], returnTy)) - | _ -> - error(InternalError("should have inferred tycon kind", m)) - - let baseIdOpt = - match synTyconRepr with - | SynTypeDefnSimpleRepr.None _ -> None - | SynTypeDefnSimpleRepr.Exception _ -> None - | SynTypeDefnSimpleRepr.TypeAbbrev _ -> None - | SynTypeDefnSimpleRepr.Union _ -> None - | SynTypeDefnSimpleRepr.LibraryOnlyILAssembly _ -> None - | SynTypeDefnSimpleRepr.Record _ -> None - | SynTypeDefnSimpleRepr.Enum _ -> None - | SynTypeDefnSimpleRepr.General (_, inherits, _, _, _, _, _, _) -> - match inherits with - | [] -> None - | ((_, m, baseIdOpt) :: _) -> - match baseIdOpt with - | None -> Some(ident("base", m)) - | Some id -> Some id - - let abstractSlots = - [ for (valSpfn, memberFlags) in slotsigs do - - let (ValSpfn(_, _, _, _, _valSynData, _, _, _, _, _, m)) = valSpfn - - CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m - - let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, valSpfn)) - // Multiple slots may be returned, e.g. for - // abstract P: int with get, set - - for slot in slots do - yield mkLocalValRef slot ] - - let baseValOpt = MakeAndPublishBaseVal cenv envinner baseIdOpt (superOfTycon g tycon) - let safeInitInfo = ComputeInstanceSafeInitInfo cenv envinner thisTyconRef.Range thisTy - let safeInitFields = match safeInitInfo with SafeInitField (_, fld) -> [fld] | NoSafeInitInfo -> [] - - let repr = - TFSharpObjectRepr - { fsobjmodel_kind=kind - fsobjmodel_vslots= abstractSlots - fsobjmodel_rfields=MakeRecdFieldsTable (userFields @ implicitStructFields @ safeInitFields) } - repr, baseValOpt, safeInitInfo - - | SynTypeDefnSimpleRepr.Enum (decls, m) -> - let fieldTy, fields' = TcRecdUnionAndEnumDeclarations.TcEnumDecls cenv envinner innerParent thisTy decls - let kind = TTyconEnum - structLayoutAttributeCheck false - noCLIMutableAttributeCheck() - noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedEnum - noAllowNullLiteralAttributeCheck() - let vfld = NewRecdField false None (ident("value__", m)) false fieldTy false false [] [] XmlDoc.Empty taccessPublic true - - let legitEnumTypes = [ g.int32_ty; g.int16_ty; g.sbyte_ty; g.int64_ty; g.char_ty; g.bool_ty; g.uint32_ty; g.uint16_ty; g.byte_ty; g.uint64_ty ] - if not (ListSet.contains (typeEquiv g) fieldTy legitEnumTypes) then - errorR(Error(FSComp.SR.tcInvalidTypeForLiteralEnumeration(), m)) - - writeFakeRecordFieldsToSink fields' - let repr = - TFSharpObjectRepr - { fsobjmodel_kind=kind - fsobjmodel_vslots=[] - fsobjmodel_rfields= MakeRecdFieldsTable (vfld :: fields') } - repr, None, NoSafeInitInfo - - tycon.entity_tycon_repr <- typeRepr - // We check this just after establishing the representation - if TyconHasUseNullAsTrueValueAttribute g tycon && not (CanHaveUseNullAsTrueValueAttribute g tycon) then - errorR(Error(FSComp.SR.tcInvalidUseNullAsTrueValue(), m)) - - // validate ConditionalAttribute, should it be applied (it's only valid on a type if the type is an attribute type) - match attrs |> List.tryFind (IsMatchingFSharpAttribute g g.attrib_ConditionalAttribute) with - | Some _ -> - if not(ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy g.tcref_System_Attribute [])) g cenv.amap m AllowMultiIntfInstantiations.Yes thisTy) then - errorR(Error(FSComp.SR.tcConditionalAttributeUsage(), m)) - | _ -> () - - (baseValOpt, safeInitInfo) - with e -> - errorRecovery e m - None, NoSafeInitInfo - - /// Check that a set of type definitions is free of cycles in abbreviations - let private TcTyconDefnCore_CheckForCyclicAbbreviations tycons = - - let edgesFrom (tycon: Tycon) = - - let rec accInAbbrevType ty acc = - match stripTyparEqns ty with - | TType_anon (_,l) - | TType_tuple (_, l) -> accInAbbrevTypes l acc - | TType_ucase (UCRef(tc, _), tinst) - | TType_app (tc, tinst) -> - let tycon2 = tc.Deref - let acc = accInAbbrevTypes tinst acc - // Record immediate recursive references - if ListSet.contains (===) tycon2 tycons then - (tycon, tycon2) :: acc - // Expand the representation of abbreviations - elif tc.IsTypeAbbrev then - accInAbbrevType (reduceTyconRefAbbrev tc tinst) acc - // Otherwise H - explore the instantiation. - else - acc - - | TType_fun (d, r) -> - accInAbbrevType d (accInAbbrevType r acc) - - | TType_var _ -> acc - - | TType_forall (_, r) -> accInAbbrevType r acc - - | TType_measure ms -> accInMeasure ms acc - - and accInMeasure ms acc = - match stripUnitEqns ms with - | Measure.Con tc when ListSet.contains (===) tc.Deref tycons -> - (tycon, tc.Deref) :: acc - | Measure.Con tc when tc.IsTypeAbbrev -> - accInMeasure (reduceTyconRefAbbrevMeasureable tc) acc - | Measure.Prod (ms1, ms2) -> accInMeasure ms1 (accInMeasure ms2 acc) - | Measure.Inv ms -> accInMeasure ms acc - | _ -> acc - - and accInAbbrevTypes tys acc = - List.foldBack accInAbbrevType tys acc - - match tycon.TypeAbbrev with - | None -> [] - | Some ty -> accInAbbrevType ty [] - - let edges = List.collect edgesFrom tycons - let graph = Graph ((fun tc -> tc.Stamp), tycons, edges) - graph.IterateCycles (fun path -> - let tycon = path.Head - // The thing is cyclic. Set the abbreviation and representation to be "None" to stop later VS crashes - tycon.SetTypeAbbrev None - tycon.entity_tycon_repr <- TNoRepr - errorR(Error(FSComp.SR.tcTypeDefinitionIsCyclic(), tycon.Range))) - - - /// Check that a set of type definitions is free of inheritance cycles - let TcTyconDefnCore_CheckForCyclicStructsAndInheritance cenv tycons = - let g = cenv.g - // Overview: - // Given several tycons now being defined (the "initial" tycons). - // Look for cycles in inheritance and struct-field-containment. - // - // The graph is on the (initial) type constructors (not types (e.g. tycon instantiations)). - // Closing under edges: - // 1. (tycon, superTycon) -- tycon (initial) to the tycon of its super type. - // 2. (tycon, interfaceTycon) -- tycon (initial) to the tycon of an interface it implements. - // 3. (tycon, T) -- tycon (initial) is a struct with a field (static or instance) that would store a T<_> - // where storing T<_> means is T<_> - // or is a struct with an instance field that stores T<_>. - // The implementation only stores edges between (initial) tycons. - // - // The special case "S<'a> static field on S<'a>" is allowed, so no #3 edge is collected for this. - // Only static fields for current tycons need to be followed. Previous tycons are assumed (previously checked) OK. - // - // BEGIN: EARLIER COMMENT - // Of course structs are not allowed to contain instance fields of their own type: - // type S = struct { field x: S } - // - // In addition, see bug 3429. In the .NET IL structs are allowed to contain - // static fields of their exact generic type, e.g. - // type S = struct { static field x: S } - // type S = struct { static field x: S } - // but not - // type S = struct { static field x: S } - // type S = struct { static field x: S } - // etc. - // - // Ideally structs would allow static fields of any type. However - // this is a restriction and exemption that originally stems from - // the way the Microsoft desktop CLR class loader works. - // END: EARLIER COMMENT - - // edgesFrom tycon collects (tycon, tycon2) edges, for edges as described above. - let edgesFrom (tycon: Tycon) = - // Record edge (tycon, tycon2), only when tycon2 is an "initial" tycon. - let insertEdgeToTycon tycon2 acc = - if ListSet.contains (===) tycon2 tycons && // note: only add if tycon2 is initial - not (List.exists (fun (tc, tc2) -> tc === tycon && tc2 === tycon2) acc) // note: only add if (tycon, tycon2) not already an edge - then - (tycon, tycon2) :: acc - else acc // note: all edges added are (tycon, _) - let insertEdgeToType ty acc = - match tryDestAppTy g ty with - | ValueSome tcref -> - insertEdgeToTycon tcref.Deref acc - | _ -> - acc - - // collect edges from an a struct field (which is struct-contained in tycon) - let rec accStructField (structTycon: Tycon) structTyInst (fspec: RecdField) (doneTypes, acc) = - let fieldTy = actualTyOfRecdFieldForTycon structTycon structTyInst fspec - accStructFieldType structTycon structTyInst fspec fieldTy (doneTypes, acc) - - // collect edges from an a struct field (given the field type, which may be expanded if it is a type abbreviation) - and accStructFieldType structTycon structTyInst fspec fieldTy (doneTypes, acc) = - let fieldTy = stripTyparEqns fieldTy - match fieldTy with - | TType_app (tcref2, tinst2) when tcref2.IsStructOrEnumTycon -> - // The field is a struct. - // An edge (tycon, tycon2) should be recorded, unless it is the "static self-typed field" case. - let tycon2 = tcref2.Deref - let specialCaseStaticField = - // The special case of "static field S<'a> in struct S<'a>" is permitted. (so no (S, S) edge to be collected). - fspec.IsStatic && - (structTycon === tycon2) && - (structTyInst, tinst2) ||> List.lengthsEqAndForall2 (fun ty1 ty2 -> - match tryDestTyparTy g ty1 with - | ValueSome destTypar1 -> - match tryDestTyparTy g ty2 with - | ValueSome destTypar2 -> typarEq destTypar1 destTypar2 - | _ -> false - | _ -> false) - if specialCaseStaticField then - doneTypes, acc // no edge collected, no recursion. - else - let acc = insertEdgeToTycon tycon2 acc // collect edge (tycon, tycon2), if tycon2 is initial. - accStructInstanceFields fieldTy tycon2 tinst2 (doneTypes, acc) // recurse through struct field looking for more edges - | TType_app (tcref2, tinst2) when tcref2.IsTypeAbbrev -> - // The field is a type abbreviation. Expand and repeat. - accStructFieldType structTycon structTyInst fspec (reduceTyconRefAbbrev tcref2 tinst2) (doneTypes, acc) - | _ -> - doneTypes, acc - - // collect edges from the fields of a given struct type. - and accStructFields includeStaticFields ty (structTycon: Tycon) tinst (doneTypes, acc) = - if List.exists (typeEquiv g ty) doneTypes then - // This type (type instance) has been seen before, so no need to collect the same edges again (and avoid loops!) - doneTypes, acc - else - // Only collect once from each type instance. - let doneTypes = ty :: doneTypes - let fspecs = - if structTycon.IsUnionTycon then - [ for uc in structTycon.UnionCasesArray do - for c in uc.FieldTable.FieldsByIndex do - yield c] - else - structTycon.AllFieldsAsList - let fspecs = fspecs |> List.filter (fun fspec -> includeStaticFields || not fspec.IsStatic) - let doneTypes, acc = List.foldBack (accStructField structTycon tinst) fspecs (doneTypes, acc) - doneTypes, acc - and accStructInstanceFields ty structTycon tinst (doneTypes, acc) = accStructFields false ty structTycon tinst (doneTypes, acc) - and accStructAllFields ty (structTycon: Tycon) tinst (doneTypes, acc) = accStructFields true ty structTycon tinst (doneTypes, acc) - - let acc = [] - let acc = - if tycon.IsStructOrEnumTycon then - let tinst, ty = generalizeTyconRef (mkLocalTyconRef tycon) - let _, acc = accStructAllFields ty tycon tinst ([], acc) - acc - else - acc - - let acc = - // Note: only the nominal type counts - let super = superOfTycon g tycon - insertEdgeToType super acc - let acc = - // Note: only the nominal type counts - List.foldBack insertEdgeToType tycon.ImmediateInterfaceTypesOfFSharpTycon acc - acc - let edges = (List.collect edgesFrom tycons) - let graph = Graph ((fun tc -> tc.Stamp), tycons, edges) - graph.IterateCycles (fun path -> - let tycon = path.Head - // The thing is cyclic. Set the abbreviation and representation to be "None" to stop later VS crashes - tycon.SetTypeAbbrev None - tycon.entity_tycon_repr <- TNoRepr - errorR(Error(FSComp.SR.tcTypeDefinitionIsCyclicThroughInheritance(), tycon.Range))) - - - // Interlude between Phase1D and Phase1E - Check and publish the explicit constraints. - let TcMutRecDefns_CheckExplicitConstraints cenv tpenv m checkCxs envMutRecPrelim withEnvs = - (envMutRecPrelim, withEnvs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> - match origInfo, tyconOpt with - | (typeDefCore, _, _), Some (tycon: Tycon) -> - let (MutRecDefnsPhase1DataForTycon(synTyconInfo, _, _, _, _, _)) = typeDefCore - let (ComponentInfo(_, _, synTyconConstraints, _, _, _, _, _)) = synTyconInfo - let envForTycon = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envForDecls - let thisTyconRef = mkLocalTyconRef tycon - let envForTycon = MakeInnerEnvForTyconRef envForTycon thisTyconRef false - try TcTyparConstraints cenv NoNewTypars checkCxs ItemOccurence.UseInType envForTycon tpenv synTyconConstraints |> ignore - with e -> errorRecovery e m - | _ -> ()) - - - let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent typeNames inSig tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecShapes) = - let g = cenv.g - // Phase1A - build Entity for type definitions, exception definitions and module definitions. - // Also for abbreviations of any of these. Augmentations are skipped in this phase. - let withEntities = - mutRecDefns - |> MutRecShapes.mapWithParent - (parent, typeNames, envInitial) - // Build the initial entity for each module definition - (fun (innerParent, typeNames, envForDecls) compInfo decls -> - TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent typeNames compInfo decls) - - // Build the initial Tycon for each type definition - (fun (innerParent, _, envForDecls) (typeDefCore, tyconMemberInfo) -> - let (MutRecDefnsPhase1DataForTycon(_, _, _, _, _, isAtOriginalTyconDefn)) = typeDefCore - let tyconOpt = - if isAtOriginalTyconDefn then - Some (TcTyconDefnCore_Phase1A_BuildInitialTycon cenv envForDecls innerParent typeDefCore) - else - None - (typeDefCore, tyconMemberInfo, innerParent), tyconOpt) - - // Bundle up the data for each 'val', 'member' or 'let' definition (just package up the data, no processing yet) - (fun (innerParent, _, _) synBinds -> - let containerInfo = ModuleOrNamespaceContainerInfo(match innerParent with Parent p -> p | _ -> failwith "unreachable") - mkLetInfo containerInfo synBinds) - - // Phase1AB - Publish modules - let envTmp, withEnvs = - (envInitial, withEntities) ||> MutRecShapes.computeEnvs - (fun envAbove (MutRecDefnsPhase2DataForModule (mtypeAcc, mspec)) -> - PublishModuleDefn cenv envAbove mspec - MakeInnerEnvWithAcc envAbove mspec.Id mtypeAcc mspec.ModuleOrNamespaceType.ModuleOrNamespaceKind) - (fun envAbove _ -> envAbove) - - // Updates the types of the modules to contain the contents so far, which now includes the nested modules and types - MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo withEnvs - - // Publish tycons - (envTmp, withEnvs) ||> MutRecShapes.iterTyconsWithEnv - (fun envAbove (_, tyconOpt) -> - tyconOpt |> Option.iter (fun tycon -> - // recheck these in case type is a duplicate in a mutually recursive set - CheckForDuplicateConcreteType envAbove tycon.LogicalName tycon.Range - PublishTypeDefn cenv envAbove tycon)) - - // Updates the types of the modules to contain the contents so far - MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo withEnvs - - // Phase1AB - Compute the active environments within each nested module. - // - // Add the types to the environment. This does not add the fields and union cases (because we haven't established them yet). - // We re-add them to the original environment later on. We don't report them to the Language Service yet as we don't know if - // they are well-formed (e.g. free of abbreviation cycles) - let envMutRecPrelim, withEnvs = (envInitial, withEntities) ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs snd (fun _ -> []) cenv false scopem m - - // Phase 1B. Establish the kind of each type constructor - // Here we run InferTyconKind and record partial information about the kind of the type constructor. - // This means TyconObjModelKind is set, which means isSealedTy, isInterfaceTy etc. give accurate results. - let withAttrs = - (envMutRecPrelim, withEnvs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> - let res = - match origInfo, tyconOpt with - | (typeDefCore, _, _), Some tycon -> Some (tycon, TcTyconDefnCore_Phase1B_EstablishBasicKind cenv inSig envForDecls typeDefCore tycon) - | _ -> None - origInfo, res) - - // Phase 1C. Establish the abbreviations (no constraint checking, because constraints not yet established) - (envMutRecPrelim, withAttrs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> - match origInfo, tyconAndAttrsOpt with - | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations cenv envForDecls inSig tpenv FirstPass typeDefCore tycon attrs - | _ -> ()) - - // Check for cyclic abbreviations. If this succeeds we can start reducing abbreviations safely. - let tycons = withEntities |> MutRecShapes.collectTycons |> List.choose snd - - TcTyconDefnCore_CheckForCyclicAbbreviations tycons - - // Phase 1D. Establish the super type and interfaces (no constraint checking, because constraints not yet established) - (envMutRecPrelim, withAttrs) |> TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig FirstPass - - // Interlude between Phase1D and Phase1E - Add the interface and member declarations for - // hash/compare. Because this adds interfaces, this may let constraints - // be satisfied, so we have to do this prior to checking any constraints. - // - // First find all the field types in all the structural types - let tyconsWithStructuralTypes = - (envMutRecPrelim, withEnvs) - ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) -> - match origInfo, tyconOpt with - | (typeDefCore, _, _), Some tycon -> Some (tycon, GetStructuralElementsOfTyconDefn cenv envForDecls tpenv typeDefCore tycon) - | _ -> None) - |> MutRecShapes.collectTycons - |> List.choose id - - let scSet = TyconConstraintInference.InferSetOfTyconsSupportingComparable cenv envMutRecPrelim.DisplayEnv tyconsWithStructuralTypes - let seSet = TyconConstraintInference.InferSetOfTyconsSupportingEquatable cenv envMutRecPrelim.DisplayEnv tyconsWithStructuralTypes - - (envMutRecPrelim, withEnvs) - ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (_, tyconOpt) -> - tyconOpt |> Option.iter (AddAugmentationDeclarations.AddGenericHashAndComparisonDeclarations cenv envForDecls scSet seSet)) - - TcMutRecDefns_CheckExplicitConstraints cenv tpenv m NoCheckCxs envMutRecPrelim withEnvs - - // No inferred constraints allowed on declared typars - (envMutRecPrelim, withEnvs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (_, tyconOpt) -> - tyconOpt |> Option.iter (fun tycon -> tycon.Typars m |> List.iter (SetTyparRigid g envForDecls.DisplayEnv m))) - - // Phase1E. OK, now recheck the abbreviations, super/interface and explicit constraints types (this time checking constraints) - (envMutRecPrelim, withAttrs) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> - match origInfo, tyconAndAttrsOpt with - | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1C_Phase1E_EstablishAbbreviations cenv envForDecls inSig tpenv SecondPass typeDefCore tycon attrs - | _ -> ()) - - // Phase1F. Establish inheritance hierarchy - (envMutRecPrelim, withAttrs) |> TcTyconDefnCore_Phase1D_Phase1F_EstablishSuperTypesAndInterfaceTypes cenv tpenv inSig SecondPass - - TcMutRecDefns_CheckExplicitConstraints cenv tpenv m CheckCxs envMutRecPrelim withEnvs - - // Add exception definitions to the environments, which are used for checking exception abbreviations in representations - let envMutRecPrelim, withAttrs = - (envMutRecPrelim, withAttrs) - ||> MutRecShapes.extendEnvs (fun envForDecls decls -> - let tycons = decls |> List.choose (function MutRecShape.Tycon (_, Some (tycon, _)) -> Some tycon | _ -> None) - let exns = tycons |> List.filter (fun tycon -> tycon.IsExceptionDecl) - let envForDecls = (envForDecls, exns) ||> List.fold (AddLocalExnDefnAndReport cenv.tcSink scopem) - envForDecls) - - // Phase1G. Establish inheritance hierarchy - // Now all the type parameters, abbreviations, constraints and kind information is established. - // Now do the representations. Each baseValOpt is a residue from the representation which is potentially available when - // checking the members. - let withBaseValsAndSafeInitInfos = - (envMutRecPrelim, withAttrs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconAndAttrsOpt) -> - let info = - match origInfo, tyconAndAttrsOpt with - | (typeDefCore, _, _), Some (tycon, (attrs, _)) -> TcTyconDefnCore_Phase1G_EstablishRepresentation cenv envForDecls tpenv inSig typeDefCore tycon attrs - | _ -> None, NoSafeInitInfo - let tyconOpt, fixupFinalAttrs = - match tyconAndAttrsOpt with - | None -> None, (fun () -> ()) - | Some (tycon, (_prelimAttrs, getFinalAttrs)) -> Some tycon, (fun () -> tycon.entity_attribs <- getFinalAttrs()) - - (origInfo, tyconOpt, fixupFinalAttrs, info)) - - // Now check for cyclic structs and inheritance. It's possible these should be checked as separate conditions. - // REVIEW: checking for cyclic inheritance is happening too late. See note above. - TcTyconDefnCore_CheckForCyclicStructsAndInheritance cenv tycons - - - (tycons, envMutRecPrelim, withBaseValsAndSafeInitInfos) - - -/// Bind declarations in implementation and signature files -module TcDeclarations = - - /// Given a type definition, compute whether its members form an extension of an existing type, and if so if it is an - /// intrinsic or extrinsic extension - let private ComputeTyconDeclKind cenv envForDecls tyconOpt isAtOriginalTyconDefn inSig m (synTypars: SynTyparDecl list) synTyparCxs longPath = - let g = cenv.g - let ad = envForDecls.eAccessRights - - let tcref = - match tyconOpt with - | Some tycon when isAtOriginalTyconDefn -> - - // This records a name resolution of the type at the location - let resInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs synTypars.Length - ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Binding OpenQualified envForDecls.eNameResEnv ad longPath resInfo PermitDirectReferenceToGeneratedType.No - |> ignore - - mkLocalTyconRef tycon - - | _ -> - let resInfo = TypeNameResolutionStaticArgsInfo.FromTyArgs synTypars.Length - match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Binding OpenQualified envForDecls.eNameResEnv ad longPath resInfo PermitDirectReferenceToGeneratedType.No with - | Result res -> res - | res when inSig && longPath.Length = 1 -> - errorR(Deprecated(FSComp.SR.tcReservedSyntaxForAugmentation(), m)) - ForceRaise res - | res -> ForceRaise res - - let isInterfaceOrDelegateOrEnum = - tcref.Deref.IsFSharpInterfaceTycon || - tcref.Deref.IsFSharpDelegateTycon || - tcref.Deref.IsFSharpEnumTycon - - let reqTypars = tcref.Typars m - - // Member definitions are intrinsic (added directly to the type) if: - // a) For interfaces, only if it is in the original defn. - // Augmentations to interfaces via partial type defns will always be extensions, e.g. extension members on interfaces. - // b) For other types, if the type is isInSameModuleOrNamespace - let declKind, typars = - if isAtOriginalTyconDefn then - ModuleOrMemberBinding, reqTypars - - else - let isInSameModuleOrNamespace = - match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryGetValue tcref.LogicalName with - | true, tycon -> tyconOrder.Compare(tcref.Deref, tycon) = 0 - | _ -> - //false - // There is a special case we allow when compiling FSharp.Core.dll which permits interface implementations across namespace fragments - g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`") - - let nReqTypars = reqTypars.Length - - let declaredTypars = TcTyparDecls cenv envForDecls synTypars - let envForTycon = AddDeclaredTypars CheckForDuplicateTypars declaredTypars envForDecls - let _tpenv = TcTyparConstraints cenv NoNewTypars CheckCxs ItemOccurence.UseInType envForTycon emptyUnscopedTyparEnv synTyparCxs - declaredTypars |> List.iter (SetTyparRigid g envForDecls.DisplayEnv m) - - if isInSameModuleOrNamespace && not isInterfaceOrDelegateOrEnum then - // For historical reasons we only give a warning for incorrect type parameters on intrinsic extensions - if nReqTypars <> synTypars.Length then - warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then - warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - // Note we return 'reqTypars' for intrinsic extensions since we may only have given warnings - IntrinsicExtensionBinding, reqTypars - else - if isInSameModuleOrNamespace && isInterfaceOrDelegateOrEnum then - errorR(Error(FSComp.SR.tcMembersThatExtendInterfaceMustBePlacedInSeparateModule(), tcref.Range)) - if nReqTypars <> synTypars.Length then - error(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then - errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - ExtrinsicExtensionBinding, declaredTypars - - - declKind, tcref, typars - - - let private isAugmentationTyconDefnRepr = function (SynTypeDefnSimpleRepr.General(TyconAugmentation, _, _, _, _, _, _, _)) -> true | _ -> false - let private isAutoProperty = function SynMemberDefn.AutoProperty _ -> true | _ -> false - let private isMember = function SynMemberDefn.Member _ -> true | _ -> false - let private isImplicitCtor = function SynMemberDefn.ImplicitCtor _ -> true | _ -> false - let private isImplicitInherit = function SynMemberDefn.ImplicitInherit _ -> true | _ -> false - let private isAbstractSlot = function SynMemberDefn.AbstractSlot _ -> true | _ -> false - let private isInterface = function SynMemberDefn.Interface _ -> true | _ -> false - let private isInherit = function SynMemberDefn.Inherit _ -> true | _ -> false - let private isField = function SynMemberDefn.ValField (_, _) -> true | _ -> false - let private isTycon = function SynMemberDefn.NestedType _ -> true | _ -> false - - let private allFalse ps x = List.forall (fun p -> not (p x)) ps - - /// Check the ordering on the bindings and members in a class construction - // Accepted forms: - // - // Implicit Construction: - // implicit_ctor - // optional implicit_inherit - // multiple bindings - // multiple member-binding(includes-overrides) or abstract-slot-declaration or interface-bindings - // - // Classic construction: - // multiple (binding or slotsig or field or interface or inherit). - // i.e. not local-bindings, implicit ctor or implicit inherit (or tycon?). - // atMostOne inherit. - let private CheckMembersForm ds = - match ds with - | d :: ds when isImplicitCtor d -> - // Implicit construction - let ds = - match ds with - | d :: ds when isImplicitInherit d -> ds // skip inherit call if it comes next - | _ -> ds - - // Skip over 'let' and 'do' bindings - let _, ds = ds |> List.takeUntil (function SynMemberDefn.LetBindings _ -> false | _ -> true) - - // Skip over 'let' and 'do' bindings - let _, ds = ds |> List.takeUntil (allFalse [isMember;isAbstractSlot;isInterface;isAutoProperty]) - - match ds with - | SynMemberDefn.Member (_, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have binding", m)) - | SynMemberDefn.AbstractSlot (_, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have slotsig", m)) - | SynMemberDefn.Interface (_, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have interface", m)) - | SynMemberDefn.ImplicitCtor (_, _, _, _, m) :: _ -> errorR(InternalError("implicit class construction with two implicit constructions", m)) - | SynMemberDefn.AutoProperty (_, _, _, _, _, _, _, _, _, _, m) :: _ -> errorR(InternalError("List.takeUntil is wrong, have auto property", m)) - | SynMemberDefn.ImplicitInherit (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit(), m)) - | SynMemberDefn.LetBindings (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers(), m)) - | SynMemberDefn.Inherit (_, _, m) :: _ -> errorR(Error(FSComp.SR.tcInheritDeclarationMissingArguments(), m)) - | SynMemberDefn.NestedType (_, _, m) :: _ -> errorR(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)) - | _ -> () - | ds -> - // Classic class construction - let _, ds = List.takeUntil (allFalse [isMember;isAbstractSlot;isInterface;isInherit;isField;isTycon]) ds - match ds with - | SynMemberDefn.Member (_, m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m)) - | SynMemberDefn.ImplicitCtor (_, _, _, _, m) :: _ -> errorR(InternalError("CheckMembersForm: implicit ctor line should be first", m)) - | SynMemberDefn.ImplicitInherit (_, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcInheritConstructionCallNotPartOfImplicitSequence(), m)) - | SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, _, _, m) :: _ -> errorR(Error(FSComp.SR.tcAutoPropertyRequiresImplicitConstructionSequence(), m)) - | SynMemberDefn.LetBindings (_, false, _, m) :: _ -> errorR(Error(FSComp.SR.tcLetAndDoRequiresImplicitConstructionSequence(), m)) - | SynMemberDefn.AbstractSlot (_, _, m) :: _ - | SynMemberDefn.Interface (_, _, m) :: _ - | SynMemberDefn.Inherit (_, _, m) :: _ - | SynMemberDefn.ValField (_, m) :: _ - | SynMemberDefn.NestedType (_, _, m) :: _ -> errorR(InternalError("CheckMembersForm: List.takeUntil is wrong", m)) - | _ -> () - - - /// Separates the definition into core (shape) and body. - /// - /// core = synTyconInfo, simpleRepr, interfaceTypes - /// where simpleRepr can contain inherit type, declared fields and virtual slots. - /// body = members - /// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions. - let rec private SplitTyconDefn (TypeDefn(synTyconInfo, trepr, extraMembers, _)) = - let implements1 = List.choose (function SynMemberDefn.Interface (ty, _, _) -> Some(ty, ty.Range) | _ -> None) extraMembers - match trepr with - | SynTypeDefnRepr.ObjectModel(kind, cspec, m) -> - CheckMembersForm cspec - let fields = cspec |> List.choose (function SynMemberDefn.ValField (f, _) -> Some f | _ -> None) - let implements2 = cspec |> List.choose (function SynMemberDefn.Interface (ty, _, _) -> Some(ty, ty.Range) | _ -> None) - let inherits = cspec |> List.choose (function - | SynMemberDefn.Inherit (ty, idOpt, m) -> Some(ty, m, idOpt) - | SynMemberDefn.ImplicitInherit (ty, _, idOpt, m) -> Some(ty, m, idOpt) - | _ -> None) - //let nestedTycons = cspec |> List.choose (function SynMemberDefn.NestedType (x, _, _) -> Some x | _ -> None) - let slotsigs = cspec |> List.choose (function SynMemberDefn.AbstractSlot (x, y, _) -> Some(x, y) | _ -> None) - - let members = - let membersIncludingAutoProps = - cspec |> List.filter (fun memb -> - match memb with - | SynMemberDefn.Interface _ - | SynMemberDefn.Member _ - | SynMemberDefn.LetBindings _ - | SynMemberDefn.ImplicitCtor _ - | SynMemberDefn.AutoProperty _ - | SynMemberDefn.Open _ - | SynMemberDefn.ImplicitInherit _ -> true - | SynMemberDefn.NestedType (_, _, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)); false - // covered above - | SynMemberDefn.ValField _ - | SynMemberDefn.Inherit _ - | SynMemberDefn.AbstractSlot _ -> false) - - // Convert auto properties to let bindings in the pre-list - let rec preAutoProps memb = - match memb with - | SynMemberDefn.AutoProperty(Attributes attribs, isStatic, id, tyOpt, propKind, _, xmlDoc, _access, synExpr, _mGetSet, mWholeAutoProp) -> - // Only the keep the field-targeted attributes - let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> true | _ -> false) - let mLetPortion = synExpr.Range - let fldId = ident (CompilerGeneratedName id.idText, mLetPortion) - let headPat = SynPat.LongIdent (LongIdentWithDots([fldId], []), None, Some noInferredTypars, SynConstructorArgs.Pats [], None, mLetPortion) - let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) - let isMutable = - match propKind with - | MemberKind.PropertySet - | MemberKind.PropertyGetSet -> true - | _ -> false - let attribs = mkAttributeList attribs mWholeAutoProp - let binding = mkSynBinding (xmlDoc, headPat) (None, false, isMutable, mLetPortion, NoSequencePointAtInvisibleBinding, retInfo, synExpr, synExpr.Range, [], attribs, None) - - [(SynMemberDefn.LetBindings ([binding], isStatic, false, mWholeAutoProp))] - - | SynMemberDefn.Interface (_, Some membs, _) -> membs |> List.collect preAutoProps - | SynMemberDefn.LetBindings _ - | SynMemberDefn.ImplicitCtor _ - | SynMemberDefn.Open _ - | SynMemberDefn.ImplicitInherit _ -> [memb] - | _ -> [] - - // Convert auto properties to member bindings in the post-list - let rec postAutoProps memb = - match memb with - | SynMemberDefn.AutoProperty(Attributes attribs, isStatic, id, tyOpt, propKind, memberFlags, xmlDoc, access, _synExpr, mGetSetOpt, _mWholeAutoProp) -> - let mMemberPortion = id.idRange - // Only the keep the non-field-targeted attributes - let attribs = attribs |> List.filter (fun a -> match a.Target with Some t when t.idText = "field" -> false | _ -> true) - let fldId = ident (CompilerGeneratedName id.idText, mMemberPortion) - let headPatIds = if isStatic then [id] else [ident ("__", mMemberPortion);id] - let headPat = SynPat.LongIdent (LongIdentWithDots(headPatIds, []), None, Some noInferredTypars, SynConstructorArgs.Pats [], None, mMemberPortion) - - match propKind, mGetSetOpt with - | MemberKind.PropertySet, Some m -> errorR(Error(FSComp.SR.parsMutableOnAutoPropertyShouldBeGetSetNotJustSet(), m)) - | _ -> () - - [ - match propKind with - | MemberKind.Member - | MemberKind.PropertyGet - | MemberKind.PropertyGetSet -> - let getter = - let rhsExpr = SynExpr.Ident fldId - let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) - let attribs = mkAttributeList attribs mMemberPortion - let binding = mkSynBinding (xmlDoc, headPat) (access, false, false, mMemberPortion, NoSequencePointAtInvisibleBinding, retInfo, rhsExpr, rhsExpr.Range, [], attribs, Some (memberFlags MemberKind.Member)) - SynMemberDefn.Member (binding, mMemberPortion) - yield getter - | _ -> () - - match propKind with - | MemberKind.PropertySet - | MemberKind.PropertyGetSet -> - let setter = - let vId = ident("v", mMemberPortion) - let headPat = SynPat.LongIdent (LongIdentWithDots(headPatIds, []), None, Some noInferredTypars, SynConstructorArgs.Pats [mkSynPatVar None vId], None, mMemberPortion) - let rhsExpr = mkSynAssign (SynExpr.Ident fldId) (SynExpr.Ident vId) - //let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range)) - let binding = mkSynBinding (xmlDoc, headPat) (access, false, false, mMemberPortion, NoSequencePointAtInvisibleBinding, None, rhsExpr, rhsExpr.Range, [], [], Some (memberFlags MemberKind.PropertySet)) - SynMemberDefn.Member (binding, mMemberPortion) - yield setter - | _ -> ()] - | SynMemberDefn.Interface (ty, Some membs, m) -> - let membs' = membs |> List.collect postAutoProps - [SynMemberDefn.Interface (ty, Some membs', m)] - | SynMemberDefn.LetBindings _ - | SynMemberDefn.ImplicitCtor _ - | SynMemberDefn.Open _ - | SynMemberDefn.ImplicitInherit _ -> [] - | _ -> [memb] - - let preMembers = membersIncludingAutoProps |> List.collect preAutoProps - let postMembers = membersIncludingAutoProps |> List.collect postAutoProps - - preMembers @ postMembers - - let isConcrete = - members |> List.exists (function - | SynMemberDefn.Member(Binding(_, _, _, _, _, _, SynValData(Some memberFlags, _, _), _, _, _, _, _), _) -> not memberFlags.IsDispatchSlot - | SynMemberDefn.Interface (_, defOpt, _) -> Option.isSome defOpt - | SynMemberDefn.LetBindings _ -> true - | SynMemberDefn.ImplicitCtor _ -> true - | SynMemberDefn.ImplicitInherit _ -> true - | _ -> false) - - let isIncrClass = - members |> List.exists (function - | SynMemberDefn.ImplicitCtor _ -> true - | _ -> false) - - let hasSelfReferentialCtor = - members |> List.exists (function - | SynMemberDefn.ImplicitCtor (_, _, _, thisIdOpt, _) - | SynMemberDefn.Member(Binding(_, _, _, _, _, _, SynValData(_, _, thisIdOpt), _, _, _, _, _), _) -> thisIdOpt.IsSome - | _ -> false) - - let implicitCtorSynPats = - members |> List.tryPick (function - | SynMemberDefn.ImplicitCtor (_, _, (SynSimplePats.SimplePats _ as spats), _, _) -> Some spats - | _ -> None) - - // An ugly bit of code to pre-determine if a type has a nullary constructor, prior to establishing the - // members of the type - let preEstablishedHasDefaultCtor = - members |> List.exists (function - | SynMemberDefn.Member(Binding(_, _, _, _, _, _, SynValData(Some memberFlags, _, _), SynPatForConstructorDecl SynPatForNullaryArgs, _, _, _, _), _) -> - memberFlags.MemberKind=MemberKind.Constructor - | SynMemberDefn.ImplicitCtor (_, _, SynSimplePats.SimplePats(spats, _), _, _) -> isNil spats - | _ -> false) - let repr = SynTypeDefnSimpleRepr.General(kind, inherits, slotsigs, fields, isConcrete, isIncrClass, implicitCtorSynPats, m) - let isAtOriginalTyconDefn = not (isAugmentationTyconDefnRepr repr) - let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements2@implements1, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isAtOriginalTyconDefn) - - core, members @ extraMembers - - | SynTypeDefnRepr.Simple(repr, _) -> - let members = [] - let isAtOriginalTyconDefn = true - let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements1, false, false, isAtOriginalTyconDefn) - core, members @ extraMembers - - | SynTypeDefnRepr.Exception r -> - let isAtOriginalTyconDefn = true - let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) - core, extraMembers - - //------------------------------------------------------------------------- - - /// Bind a collection of mutually recursive definitions in an implementation file - let TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) = - - // Split the definitions into "core representations" and "members". The code to process core representations - // is shared between processing of signature files and implementation files. - let mutRecDefnsAfterSplit = mutRecDefns |> MutRecShapes.mapTycons SplitTyconDefn - - // Create the entities for each module and type definition, and process the core representation of each type definition. - let tycons, envMutRecPrelim, mutRecDefnsAfterCore = - EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 - (fun containerInfo synBinds -> [ for synBind in synBinds -> RecDefnBindingInfo(containerInfo, NoNewSlots, ModuleOrMemberBinding, synBind) ]) - cenv envInitial parent typeNames false tpenv m scopem mutRecNSInfo mutRecDefnsAfterSplit - - // Package up the phase two information for processing members. - let mutRecDefnsAfterPrep = - (envMutRecPrelim, mutRecDefnsAfterCore) - ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls ((typeDefnCore, members, innerParent), tyconOpt, fixupFinalAttrs, (baseValOpt, safeInitInfo)) -> - let (MutRecDefnsPhase1DataForTycon(synTyconInfo, _, _, _, _, isAtOriginalTyconDefn)) = typeDefnCore - let tyDeclRange = synTyconInfo.Range - let (ComponentInfo(_, typars, cs, longPath, _, _, _, _)) = synTyconInfo - let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind cenv envForDecls tyconOpt isAtOriginalTyconDefn false tyDeclRange typars cs longPath - let newslotsOK = (if isAtOriginalTyconDefn && tcref.IsFSharpObjectModelTycon then NewSlotsOK else NoNewSlots) - - if (declKind = ExtrinsicExtensionBinding) && isByrefTyconRef cenv.g tcref then - error(Error(FSComp.SR.tcByrefsMayNotHaveTypeExtensions(), tyDeclRange)) - - if not (isNil members) && tcref.IsTypeAbbrev then - errorR(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveAugmentations(), tyDeclRange)) - - let (ComponentInfo (attributes, _, _, _, _, _, _, _)) = synTyconInfo - if not (List.isEmpty attributes) && (declKind = ExtrinsicExtensionBinding || declKind = IntrinsicExtensionBinding) then - let attributeRange = (List.head attributes).Range - error(Error(FSComp.SR.tcAugmentationsCannotHaveAttributes(), attributeRange)) - - MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) - - // By now we've established the full contents of type definitions apart from their - // members and any fields determined by implicit construction. We know the kinds and - // representations of types and have established them as valid. - // - // We now reconstruct the active environments all over again - this will add the union cases and fields. - // - // Note: This environment reconstruction doesn't seem necessary. We're about to create Val's for all members, - // which does require type checking, but no more information than is already available. - let envMutRecPrelimWithReprs, withEnvs = - (envInitial, MutRecShapes.dropEnvs mutRecDefnsAfterPrep) - ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs - (fun (MutRecDefnsPhase2DataForTycon(tyconOpt, _, _, _, _, _, _, _, _, _, _)) -> tyconOpt) - (fun _binds -> [ (* no values are available yet *) ]) - cenv true scopem m - - // Check the members and decide on representations for types with implicit constructors. - let withBindings, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem mutRecNSInfo envMutRecPrelimWithReprs withEnvs - - // Generate the hash/compare/equality bindings for all tycons. - // - // Note: generating these bindings must come after generating the members, since some in the case of structs some fields - // may be added by generating the implicit construction syntax - let withExtraBindings = - (envFinal, withBindings) ||> MutRecShapes.expandTyconsWithEnv (fun envForDecls (tyconOpt, _) -> - match tyconOpt with - | None -> [], [] - | Some tycon -> - // We put the hash/compare bindings before the type definitions and the - // equality bindings after because tha is the order they've always been generated - // in, and there are code generation tests to check that. - let binds = AddAugmentationDeclarations.AddGenericHashAndComparisonBindings cenv tycon - let binds3 = AddAugmentationDeclarations.AddGenericEqualityBindings cenv envForDecls tycon - binds, binds3) - - // Check for cyclic structs and inheritance all over again, since we may have added some fields to the struct when generating the implicit construction syntax - EstablishTypeDefinitionCores.TcTyconDefnCore_CheckForCyclicStructsAndInheritance cenv tycons - - withExtraBindings, envFinal - - - //------------------------------------------------------------------------- - - /// Separates the signature declaration into core (shape) and body. - let rec private SplitTyconSignature (TypeDefnSig(synTyconInfo, trepr, extraMembers, _)) = - - let implements1 = - extraMembers |> List.choose (function SynMemberSig.Interface (f, m) -> Some(f, m) | _ -> None) - - match trepr with - | SynTypeDefnSigRepr.ObjectModel(kind, cspec, m) -> - let fields = cspec |> List.choose (function SynMemberSig.ValField (f, _) -> Some f | _ -> None) - let implements2 = cspec |> List.choose (function SynMemberSig.Interface (ty, m) -> Some(ty, m) | _ -> None) - let inherits = cspec |> List.choose (function SynMemberSig.Inherit (ty, _) -> Some(ty, m, None) | _ -> None) - //let nestedTycons = cspec |> List.choose (function SynMemberSig.NestedType (x, _) -> Some x | _ -> None) - let slotsigs = cspec |> List.choose (function SynMemberSig.Member (v, fl, _) when fl.IsDispatchSlot -> Some(v, fl) | _ -> None) - let members = cspec |> List.filter (function - | SynMemberSig.Interface _ -> true - | SynMemberSig.Member (_, memberFlags, _) when not memberFlags.IsDispatchSlot -> true - | SynMemberSig.NestedType (_, m) -> error(Error(FSComp.SR.tcTypesCannotContainNestedTypes(), m)); false - | _ -> false) - let isConcrete = - members |> List.exists (function - | SynMemberSig.Member (_, memberFlags, _) -> memberFlags.MemberKind=MemberKind.Constructor - | _ -> false) - - // An ugly bit of code to pre-determine if a type has a nullary constructor, prior to establishing the - // members of the type - let preEstablishedHasDefaultCtor = - members |> List.exists (function - | SynMemberSig.Member (valSpfn, memberFlags, _) -> - memberFlags.MemberKind=MemberKind.Constructor && - // REVIEW: This is a syntactic approximation - (match valSpfn.SynType, valSpfn.SynInfo.ArgInfos with - | SynType.Fun (SynType.LongIdent (LongIdentWithDots([id], _)), _, _), [[_]] when id.idText = "unit" -> true - | _ -> false) - | _ -> false) - - let hasSelfReferentialCtor = false - - let repr = SynTypeDefnSimpleRepr.General(kind, inherits, slotsigs, fields, isConcrete, false, None, m) - let isAtOriginalTyconDefn = true - let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, repr, implements2@implements1, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isAtOriginalTyconDefn) - - tyconCore, (synTyconInfo, members@extraMembers) - - // 'type X with ...' in a signature is always interpreted as an extrinsic extension. - // Representation-hidden types with members and interfaces are written 'type X = ...' - | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _ as r), _) when not (isNil extraMembers) -> - let isAtOriginalTyconDefn = false - let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, r, implements1, false, false, isAtOriginalTyconDefn) - tyconCore, (synTyconInfo, extraMembers) - - | SynTypeDefnSigRepr.Exception r -> - let isAtOriginalTyconDefn = true - let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, SynTypeDefnSimpleRepr.Exception r, implements1, false, false, isAtOriginalTyconDefn) - core, (synTyconInfo, extraMembers) - - | SynTypeDefnSigRepr.Simple(r, _) -> - let isAtOriginalTyconDefn = true - let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, r, implements1, false, false, isAtOriginalTyconDefn) - tyconCore, (synTyconInfo, extraMembers) - - - let private TcMutRecSignatureDecls_Phase2 cenv scopem envMutRec mutRecDefns = - (envMutRec, mutRecDefns) ||> MutRecShapes.mapWithEnv - // Do this for the members in each 'type' declaration - (fun envForDecls ((tyconCore, (synTyconInfo, members), innerParent), tyconOpt, _fixupFinalAttrs, _) -> - let tpenv = emptyUnscopedTyparEnv - let (MutRecDefnsPhase1DataForTycon (_, _, _, _, _, isAtOriginalTyconDefn)) = tyconCore - let (ComponentInfo(_, typars, cs, longPath, _, _, _, m)) = synTyconInfo - let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind cenv envForDecls tyconOpt isAtOriginalTyconDefn true m typars cs longPath - - let envForTycon = AddDeclaredTypars CheckForDuplicateTypars declaredTyconTypars envForDecls - let envForTycon = MakeInnerEnvForTyconRef envForTycon tcref (declKind = ExtrinsicExtensionBinding) - - TcTyconMemberSpecs cenv envForTycon (TyconContainerInfo(innerParent, tcref, declaredTyconTypars, NoSafeInitInfo)) declKind tpenv members) - - // Do this for each 'val' declaration in a module - (fun envForDecls (containerInfo, valSpec) -> - let tpenv = emptyUnscopedTyparEnv - let idvs, _ = TcAndPublishValSpec (cenv, envForDecls, containerInfo, ModuleOrMemberBinding, None, tpenv, valSpec) - let env = List.foldBack (AddLocalVal cenv.tcSink scopem) idvs envForDecls - env) - - - /// Bind a collection of mutually recursive declarations in a signature file - let TcMutRecSignatureDecls cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecSigs: MutRecSigsInitialData) = - let mutRecSigsAfterSplit = mutRecSigs |> MutRecShapes.mapTycons SplitTyconSignature - let _tycons, envMutRec, mutRecDefnsAfterCore = EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 (fun containerInfo valDecl -> (containerInfo, valDecl)) cenv envInitial parent typeNames true tpenv m scopem mutRecNSInfo mutRecSigsAfterSplit - - // Updates the types of the modules to contain the contents so far, which now includes values and members - MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterCore - - // By now we've established the full contents of type definitions apart from their - // members and any fields determined by implicit construction. We know the kinds and - // representations of types and have established them as valid. - // - // We now reconstruct the active environments all over again - this will add the union cases and fields. - // - // Note: This environment reconstruction doesn't seem necessary. We're about to create Val's for all members, - // which does require type checking, but no more information than is already available. - let envMutRecPrelimWithReprs, withEnvs = - (envInitial, MutRecShapes.dropEnvs mutRecDefnsAfterCore) - ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs - (fun (_, tyconOpt, _, _) -> tyconOpt) - (fun _binds -> [ (* no values are available yet *) ]) - cenv true scopem m - - let mutRecDefnsAfterVals = TcMutRecSignatureDecls_Phase2 cenv scopem envMutRecPrelimWithReprs withEnvs - - // Updates the types of the modules to contain the contents so far, which now includes values and members - MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterVals - - envMutRec - -//------------------------------------------------------------------------- -// Bind module types -//------------------------------------------------------------------------- - -let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synSigDecl: Eventually = - eventually { - try - match synSigDecl with - | SynModuleSigDecl.Exception (edef, m) -> - let scopem = unionRanges m.EndRange endm - let _, _, _, env = TcExceptionDeclarations.TcExnSignature cenv env parent emptyUnscopedTyparEnv (edef, scopem) - return env - - | SynModuleSigDecl.Types (typeSpecs, m) -> - let scopem = unionRanges m endm - let mutRecDefns = typeSpecs |> List.map MutRecShape.Tycon - let env = TcDeclarations.TcMutRecSignatureDecls cenv env parent typeNames emptyUnscopedTyparEnv m scopem None mutRecDefns - return env - - | SynModuleSigDecl.Open (mp, m) -> - let scopem = unionRanges m.EndRange endm - let env = TcOpenDecl cenv.tcSink cenv.g cenv.amap m scopem env mp - return env - - | SynModuleSigDecl.Val (vspec, m) -> - let parentModule = - match parent with - | ParentNone -> error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(), vspec.RangeOfId)) - | Parent p -> p - let containerInfo = ModuleOrNamespaceContainerInfo parentModule - let idvs, _ = TcAndPublishValSpec (cenv, env, containerInfo, ModuleOrMemberBinding, None, emptyUnscopedTyparEnv, vspec) - let scopem = unionRanges m endm - let env = List.foldBack (AddLocalVal cenv.tcSink scopem) idvs env - return env - - | SynModuleSigDecl.NestedModule(ComponentInfo(Attributes attribs, _parms, _constraints, longPath, xml, _, vis, im) as compInfo, isRec, mdefs, m) -> - if isRec then - // Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...' - let modDecl = SynModuleSigDecl.NestedModule(compInfo, false, mdefs, m) - - return! TcSignatureElementsMutRec cenv parent typeNames endm None env [modDecl] - else - let id = ComputeModuleName longPath - let vis, _ = ComputeAccessAndCompPath env None im vis None parent - let attribs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs - CheckNamespaceModuleOrTypeName cenv.g id - let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames attribs id.idText - let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText - CheckForDuplicateConcreteType env modName id.idRange - - // Now typecheck the signature, accumulating and then recording the submodule description. - let id = ident (modName, id.idRange) - - let mspec = NewModuleOrNamespace (Some env.eCompPath) vis id (xml.ToXmlDoc()) attribs (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType modKind)) - - let! (mtyp, _) = TcModuleOrNamespaceSignatureElementsNonMutRec cenv (Parent (mkLocalModRef mspec)) env (id, modKind, mdefs, m, xml) - - mspec.entity_modul_contents <- MaybeLazy.Strict mtyp - let scopem = unionRanges m endm - PublishModuleDefn cenv env mspec - let env = AddLocalSubModuleAndReport cenv.tcSink scopem cenv.g cenv.amap m env mspec - return env - - | SynModuleSigDecl.ModuleAbbrev (id, p, m) -> - let ad = env.eAccessRights - let resolved = - match p with - | [] -> Result [] - | id :: rest -> ResolveLongIndentAsModuleOrNamespaceOrStaticClass cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m false true OpenQualified env.eNameResEnv ad id rest false - let mvvs = ForceRaise resolved - let scopem = unionRanges m endm - let unfilteredModrefs = mvvs |> List.map p23 - - let modrefs = unfilteredModrefs |> List.filter (fun modref -> not modref.IsNamespace) - - if not (List.isEmpty unfilteredModrefs) && List.isEmpty modrefs then - errorR(Error(FSComp.SR.tcModuleAbbreviationForNamespace(fullDisplayTextOfModRef (List.head unfilteredModrefs)), m)) - - if List.isEmpty modrefs then return env else - modrefs |> List.iter (fun modref -> CheckEntityAttributes cenv.g modref m |> CommitOperationResult) - - let env = AddModuleAbbreviationAndReport cenv.tcSink scopem id modrefs env - return env - - | SynModuleSigDecl.HashDirective _ -> - return env - - - | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig(longId, isRec, kind, defs, xml, attribs, vis, m)) -> - - do for id in longId do - CheckNamespaceModuleOrTypeName cenv.g id - - // Logically speaking, this changes - // module [rec] A.B.M - // ... - // to - // namespace [rec] A.B - // module M = ... - let enclosingNamespacePath, defs = - if kind.IsModule then - let nsp, modName = List.frontAndBack longId - let modDecl = [SynModuleSigDecl.NestedModule(ComponentInfo(attribs, [], [], [modName], xml, false, vis, m), false, defs, m)] - nsp, modDecl - else - longId, defs - - let envNS = LocateEnv cenv.topCcu env enclosingNamespacePath - let envNS = ImplicitlyOpenOwnNamespace cenv.tcSink cenv.g cenv.amap m enclosingNamespacePath envNS - - // For 'namespace rec' and 'module rec' we add the thing being defined - let mtypNS = !(envNS.eModuleOrNamespaceTypeAccumulator) - let mtypRoot, mspecNSs = BuildRootModuleType enclosingNamespacePath envNS.eCompPath mtypNS - let mspecNSOpt = List.tryHead mspecNSs - - mspecNSs |> List.iter (fun mspec -> - let modref = mkLocalModRef mspec - let item = Item.ModuleOrNamespaces [modref] - CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights)) - - // For 'namespace rec' and 'module rec' we add the thing being defined - let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m envNS mtypRoot else envNS - let nsInfo = Some (mspecNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) - let mutRecNSInfo = if isRec then nsInfo else None - - let! envAtEnd = TcSignatureElements cenv ParentNone m.EndRange envNS xml mutRecNSInfo defs - - MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo - - let env = - if isNil enclosingNamespacePath then - envAtEnd - else - let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot - - // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment. - let env = - match TryStripPrefixPath cenv.g enclosingNamespacePath with - | Some(p, _) -> TcOpenDecl cenv.tcSink cenv.g cenv.amap m.EndRange m.EndRange env [p] - | None -> env - - // Publish the combined module type - env.eModuleOrNamespaceTypeAccumulator := CombineCcuContentFragments m [!(env.eModuleOrNamespaceTypeAccumulator); mtypRoot] - env - - return env - - with e -> - errorRecovery e endm - return env - } - - -and TcSignatureElements cenv parent endm env xml mutRecNSInfo defs = - eventually { - // Ensure the .Deref call in UpdateAccModuleOrNamespaceType succeeds - if cenv.compilingCanonicalFslibModuleType then - ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath (xml.ToXmlDoc()) - - let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecSigDecls defs - match mutRecNSInfo with - | Some _ -> - return! TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo env defs - | None -> - return! TcSignatureElementsNonMutRec cenv parent typeNames endm env defs - } - -and TcSignatureElementsNonMutRec cenv parent typeNames endm env defs = - eventually { - - return! Eventually.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs - } - -and TcSignatureElementsMutRec cenv parent typeNames m mutRecNSInfo envInitial (defs: SynModuleSigDecl list) = - eventually { - let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges - let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m) - - let mutRecDefns = - let rec loop isNamespace moduleRange defs: MutRecSigsInitialData = - ((true, true), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk) def -> - match def with - | SynModuleSigDecl.Types (typeSpecs, _) -> - let decls = typeSpecs |> List.map MutRecShape.Tycon - decls, (false, false) - - | SynModuleSigDecl.Open (lid, m) -> - if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m)) - let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m, moduleRange)) ] - decls, (openOk, moduleAbbrevOk) - - | SynModuleSigDecl.Exception (SynExceptionSig(exnRepr, members, _), _) -> - let ( SynExceptionDefnRepr(synAttrs, UnionCase(_, id, _args, _, _, _), _, doc, vis, m)) = exnRepr - let compInfo = ComponentInfo(synAttrs, [], [], [id], doc, false, vis, id.idRange) - let decls = [ MutRecShape.Tycon(SynTypeDefnSig.TypeDefnSig(compInfo, SynTypeDefnSigRepr.Exception exnRepr, members, m)) ] - decls, (false, false) - - | SynModuleSigDecl.Val (vspec, _) -> - if isNamespace then error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(), vspec.RangeOfId)) - let decls = [ MutRecShape.Lets vspec ] - decls, (false, false) - - | SynModuleSigDecl.NestedModule(compInfo, isRec, synDefs, moduleRange) -> - if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range)) - let mutRecDefs = loop false moduleRange synDefs - let decls = [MutRecShape.Module (compInfo, mutRecDefs)] - decls, (false, false) - - | SynModuleSigDecl.HashDirective _ -> - [], (openOk, moduleAbbrevOk) - - | SynModuleSigDecl.ModuleAbbrev (id, p, m) -> - if not moduleAbbrevOk then errorR(Error(FSComp.SR.tcModuleAbbrevFirstInMutRec(), m)) - let decls = [ MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev(id, p, m)) ] - decls, (false, moduleAbbrevOk) - - | SynModuleSigDecl.NamespaceFragment _ -> - error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), def.Range))) - - |> fst - loop (match parent with ParentNone -> true | Parent _ -> false) m defs - return TcDeclarations.TcMutRecSignatureDecls cenv envInitial parent typeNames emptyUnscopedTyparEnv m scopem mutRecNSInfo mutRecDefns - } - - - -and TcModuleOrNamespaceSignatureElementsNonMutRec cenv parent env (id, modKind, defs, m: range, xml) = - - eventually { - let endm = m.EndRange // use end of range for errors - - // Create the module type that will hold the results of type checking.... - let envForModule, mtypeAcc = MakeInnerEnv env id modKind - - // Now typecheck the signature, using mutation to fill in the submodule description. - let! envAtEnd = TcSignatureElements cenv parent endm envForModule xml None defs - - // mtypeAcc has now accumulated the module type - return !mtypeAcc, envAtEnd - } - -//------------------------------------------------------------------------- -// Bind definitions within modules -//------------------------------------------------------------------------- - - -let ElimModuleDoBinding bind = - match bind with - | SynModuleDecl.DoExpr (spExpr, expr, m) -> - let bind2 = Binding (None, StandaloneExpression, false, false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, SynPat.Wild m, None, expr, m, spExpr) - SynModuleDecl.Let(false, [bind2], m) - | _ -> bind - -let TcMutRecDefnsEscapeCheck (binds: MutRecShapes<_, _, _, _, _>) env = - let freeInEnv = GeneralizationHelpers.ComputeUnabstractableTycons env - let checkTycon (tycon: Tycon) = - if not tycon.IsTypeAbbrev && Zset.contains tycon freeInEnv then - let nm = tycon.DisplayName - errorR(Error(FSComp.SR.tcTypeUsedInInvalidWay(nm, nm, nm), tycon.Range)) - - binds |> MutRecShapes.iterTycons (fst >> Option.iter checkTycon) - - let freeInEnv = GeneralizationHelpers.ComputeUnabstractableTraitSolutions env - let checkBinds (binds: Binding list) = - for bind in binds do - if Zset.contains bind.Var freeInEnv then - let nm = bind.Var.DisplayName - errorR(Error(FSComp.SR.tcMemberUsedInInvalidWay(nm, nm, nm), bind.Var.Range)) - - binds |> MutRecShapes.iterTyconsAndLets (snd >> checkBinds) checkBinds - -// ignore solitary '()' expressions and 'do ()' bindings, since these are allowed in namespaces -// for the purposes of attaching attributes to an assembly, e.g. -// namespace A.B.C -// [] -// do() - -let CheckLetOrDoInNamespace binds m = - match binds with - | [ Binding (None, (StandaloneExpression | DoBinding), false, false, [], _, _, _, None, (SynExpr.Do (SynExpr.Const (SynConst.Unit, _), _) | SynExpr.Const (SynConst.Unit, _)), _, _) ] -> - () - | [] -> - error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(), m)) - | _ -> - error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(), binds.Head.RangeOfHeadPat)) - -/// The non-mutually recursive case for a declaration -let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem env synDecl = - eventually { - cenv.synArgNameGenerator.Reset() - let tpenv = emptyUnscopedTyparEnv - - //printfn "----------\nCHECKING, e = %+A\n------------------\n" e - try - match ElimModuleDoBinding synDecl with - - | SynModuleDecl.ModuleAbbrev (id, p, m) -> - let env = MutRecBindingChecking.TcModuleAbbrevDecl cenv scopem env (id, p, m) - return ((fun e -> e), []), env, env - - | SynModuleDecl.Exception (edef, m) -> - let binds, decl, env = TcExceptionDeclarations.TcExnDefn cenv env parent (edef, scopem) - return ((fun e -> TMDefRec(true, [decl], binds |> List.map ModuleOrNamespaceBinding.Binding, m) :: e), []), env, env - - | SynModuleDecl.Types (typeDefs, m) -> - let scopem = unionRanges m scopem - let mutRecDefns = typeDefs |> List.map MutRecShape.Tycon - let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent typeNames tpenv m scopem None mutRecDefns - // Check the non-escaping condition as we build the expression on the way back up - let exprfWithEscapeCheck e = - TcMutRecDefnsEscapeCheck mutRecDefnsChecked env - TcMutRecDefsFinish cenv mutRecDefnsChecked m :: e - - return (exprfWithEscapeCheck, []), envAfter, envAfter - - | SynModuleDecl.Open (LongIdentWithDots(mp, _), m) -> - let scopem = unionRanges m.EndRange scopem - let env = TcOpenDecl cenv.tcSink cenv.g cenv.amap m scopem env mp - return ((fun e -> e), []), env, env - - | SynModuleDecl.Let (letrec, binds, m) -> - - match parent with - | ParentNone -> - CheckLetOrDoInNamespace binds m - return (id, []), env, env - - | Parent parentModule -> - let containerInfo = ModuleOrNamespaceContainerInfo parentModule - if letrec then - let scopem = unionRanges m scopem - let binds = binds |> List.map (fun bind -> RecDefnBindingInfo(containerInfo, NoNewSlots, ModuleOrMemberBinding, bind)) - let binds, env, _ = TcLetrec WarnOnOverrides cenv env tpenv (binds, m, scopem) - return ((fun e -> TMDefRec(true, [], binds |> List.map ModuleOrNamespaceBinding.Binding, m) :: e), []), env, env - else - let binds, env, _ = TcLetBindings cenv env containerInfo ModuleOrMemberBinding tpenv (binds, m, scopem) - return ((fun e -> binds@e), []), env, env - - | SynModuleDecl.DoExpr _ -> return! failwith "unreachable" - - | SynModuleDecl.Attributes (Attributes synAttrs, _) -> - let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.Top synAttrs - return ((fun e -> e), attrs), env, env - - | SynModuleDecl.HashDirective _ -> - return ((fun e -> e), []), env, env - - | SynModuleDecl.NestedModule(compInfo, isRec, mdefs, isContinuingModule, m) -> - - // Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...' - if isRec then - assert (not isContinuingModule) - let modDecl = SynModuleDecl.NestedModule(compInfo, false, mdefs, isContinuingModule, m) - return! TcModuleOrNamespaceElementsMutRec cenv parent typeNames m env None [modDecl] - else - let (ComponentInfo(Attributes attribs, _parms, _constraints, longPath, xml, _, vis, im)) = compInfo - let id = ComputeModuleName longPath - - let modAttrs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs - let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText - let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText - CheckForDuplicateConcreteType env modName im - CheckForDuplicateModule env id.idText id.idRange - let vis, _ = ComputeAccessAndCompPath env None id.idRange vis None parent - - let endm = m.EndRange - let id = ident (modName, id.idRange) - - CheckNamespaceModuleOrTypeName cenv.g id - - let envForModule, mtypeAcc = MakeInnerEnv env id modKind - - // Create the new module specification to hold the accumulated results of the type of the module - // Also record this in the environment as the accumulator - let mspec = NewModuleOrNamespace (Some env.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType modKind)) - - // Now typecheck. - let! mexpr, topAttrsNew, envAtEnd = TcModuleOrNamespaceElements cenv (Parent (mkLocalModRef mspec)) endm envForModule xml None mdefs - - // Get the inferred type of the decls and record it in the mspec. - mspec.entity_modul_contents <- MaybeLazy.Strict !mtypeAcc - let modDefn = TMDefRec(false, [], [ModuleOrNamespaceBinding.Module(mspec, mexpr)], m) - PublishModuleDefn cenv env mspec - let env = AddLocalSubModuleAndReport cenv.tcSink scopem cenv.g cenv.amap m env mspec - - // isContinuingModule is true for all of the following - // - the implicit module of a script - // - the major 'module' declaration for a file stating with 'module X.Y' - // - an interactive entry for F# Interactive - // - // In this case the envAtEnd is the environment at the end of this module, which doesn't contain the module definition itself - // but does contain the results of all the 'open' declarations and so on. - let envAtEnd = (if isContinuingModule then envAtEnd else env) - - return ((fun modDefs -> modDefn :: modDefs), topAttrsNew), env, envAtEnd - - - | SynModuleDecl.NamespaceFragment(SynModuleOrNamespace(longId, isRec, kind, defs, xml, attribs, vis, m)) -> - - if progress then dprintn ("Typecheck implementation " + textOfLid longId) - let endm = m.EndRange - - do for id in longId do - CheckNamespaceModuleOrTypeName cenv.g id - - // Logically speaking, this changes - // module [rec] A.B.M - // ... - // to - // namespace [rec] A.B - // module M = ... - let enclosingNamespacePath, defs = - if kind.IsModule then - let nsp, modName = List.frontAndBack longId - let modDecl = [SynModuleDecl.NestedModule(ComponentInfo(attribs, [], [], [modName], xml, false, vis, m), false, defs, true, m)] - nsp, modDecl - else - longId, defs - - let envNS = LocateEnv cenv.topCcu env enclosingNamespacePath - let envNS = ImplicitlyOpenOwnNamespace cenv.tcSink cenv.g cenv.amap m enclosingNamespacePath envNS - - let mtypNS = !(envNS.eModuleOrNamespaceTypeAccumulator) - let mtypRoot, mspecNSs = BuildRootModuleType enclosingNamespacePath envNS.eCompPath mtypNS - let mspecNSOpt = List.tryHead mspecNSs - - mspecNSs |> List.iter (fun mspec -> - let modref = mkLocalModRef mspec - let item = Item.ModuleOrNamespaces [modref] - CallNameResolutionSink cenv.tcSink (mspec.Range, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Binding, env.DisplayEnv, env.eAccessRights)) - - // For 'namespace rec' and 'module rec' we add the thing being defined - let envNS = if isRec then AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m envNS mtypRoot else envNS - let nsInfo = Some (mspecNSOpt, envNS.eModuleOrNamespaceTypeAccumulator) - let mutRecNSInfo = if isRec then nsInfo else None - - let! modExpr, topAttrs, envAtEnd = TcModuleOrNamespaceElements cenv parent endm envNS xml mutRecNSInfo defs - - MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo - - let env = - if isNil enclosingNamespacePath then - envAtEnd - else - let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot - - // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment - let env = - match TryStripPrefixPath cenv.g enclosingNamespacePath with - | Some(p, _) -> TcOpenDecl cenv.tcSink cenv.g cenv.amap m.EndRange m.EndRange env [p] - | None -> env - - // Publish the combined module type - env.eModuleOrNamespaceTypeAccumulator := CombineCcuContentFragments m [!(env.eModuleOrNamespaceTypeAccumulator); mtypRoot] - env - - let modExprRoot = BuildRootModuleExpr enclosingNamespacePath envNS.eCompPath modExpr - - return ((fun modExprs -> modExprRoot :: modExprs), topAttrs), env, envAtEnd - - with exn -> - errorRecovery exn synDecl.Range - return ((fun e -> e), []), env, env - } - -/// The non-mutually recursive case for a sequence of declarations -and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) = - eventually { - match moreDefs with - | (firstDef :: otherDefs) -> - // Lookahead one to find out the scope of the next declaration. - let scopem = - if isNil otherDefs then unionRanges firstDef.Range endm - else unionRanges (List.head otherDefs).Range endm - - // Possibly better: - //let scopem = unionRanges h1.Range.EndRange endm - - let! firstDef', env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef - // tail recursive - return! TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs - | [] -> - return List.rev defsSoFar, envAtEnd - } - -/// The mutually recursive case for a sequence of declarations (and nested modules) -and TcModuleOrNamespaceElementsMutRec cenv parent typeNames m envInitial mutRecNSInfo (defs: SynModuleDecl list) = - eventually { - - let m = match defs with [] -> m | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges - let scopem = (defs, m) ||> List.foldBack (fun h m -> unionRanges h.Range m) - - let (mutRecDefns, (_, _, Attributes synAttrs)) = - let rec loop isNamespace moduleRange attrs defs: (MutRecDefnsInitialData * _) = - ((true, true, attrs), defs) ||> List.collectFold (fun (openOk, moduleAbbrevOk, attrs) def -> - match ElimModuleDoBinding def with - - | SynModuleDecl.Types (typeDefs, _) -> - let decls = typeDefs |> List.map MutRecShape.Tycon - decls, (false, false, attrs) - - | SynModuleDecl.Let (letrec, binds, m) -> - let binds = - if isNamespace then - CheckLetOrDoInNamespace binds m; [] - else - if letrec then [MutRecShape.Lets binds] - else List.map (List.singleton >> MutRecShape.Lets) binds - binds, (false, false, attrs) - - | SynModuleDecl.NestedModule(compInfo, isRec, synDefs, _isContinuingModule, moduleRange) -> - if isRec then warning(Error(FSComp.SR.tcRecImplied(), compInfo.Range)) - let mutRecDefs, (_, _, attrs) = loop false moduleRange attrs synDefs - let decls = [MutRecShape.Module (compInfo, mutRecDefs)] - decls, (false, false, attrs) - - | SynModuleDecl.Open (LongIdentWithDots(lid, _), m) -> - if not openOk then errorR(Error(FSComp.SR.tcOpenFirstInMutRec(), m)) - let decls = [ MutRecShape.Open (MutRecDataForOpen(lid, m, moduleRange)) ] - decls, (openOk, moduleAbbrevOk, attrs) - - | SynModuleDecl.Exception (SynExceptionDefn(repr, members, _), _m) -> - let (SynExceptionDefnRepr(synAttrs, UnionCase(_, id, _args, _, _, _), _repr, doc, vis, m)) = repr - let compInfo = ComponentInfo(synAttrs, [], [], [id], doc, false, vis, id.idRange) - let decls = [ MutRecShape.Tycon(SynTypeDefn.TypeDefn(compInfo, SynTypeDefnRepr.Exception repr, members, m)) ] - decls, (false, false, attrs) - - | SynModuleDecl.HashDirective _ -> - [ ], (openOk, moduleAbbrevOk, attrs) - - | SynModuleDecl.Attributes (synAttrs, _) -> - [ ], (false, false, synAttrs) - - | SynModuleDecl.ModuleAbbrev (id, p, m) -> - if not moduleAbbrevOk then errorR(Error(FSComp.SR.tcModuleAbbrevFirstInMutRec(), m)) - let decls = [ MutRecShape.ModuleAbbrev (MutRecDataForModuleAbbrev(id, p, m)) ] - decls, (false, moduleAbbrevOk, attrs) - - | SynModuleDecl.DoExpr _ -> failwith "unreachable: SynModuleDecl.DoExpr - ElimModuleDoBinding" - - | (SynModuleDecl.NamespaceFragment _ as d) -> error(Error(FSComp.SR.tcUnsupportedMutRecDecl(), d.Range))) - - loop (match parent with ParentNone -> true | Parent _ -> false) m [] defs - - let tpenv = emptyUnscopedTyparEnv - let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns - - // Check the assembly attributes - let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs - - // Check the non-escaping condition as we build the list of module expressions on the way back up - let exprfWithEscapeCheck modExprs = - TcMutRecDefnsEscapeCheck mutRecDefnsChecked envInitial - let modExpr = TcMutRecDefsFinish cenv mutRecDefnsChecked m - modExpr :: modExprs - - return (exprfWithEscapeCheck, attrs), envAfter, envAfter - - } - -and TcMutRecDefsFinish cenv defs m = - let tycons = defs |> List.choose (function MutRecShape.Tycon (Some tycon, _) -> Some tycon | _ -> None) - let binds = - defs |> List.collect (function - | MutRecShape.Open _ -> [] - | MutRecShape.ModuleAbbrev _ -> [] - | MutRecShape.Tycon (_, binds) - | MutRecShape.Lets binds -> - binds |> List.map ModuleOrNamespaceBinding.Binding - | MutRecShape.Module ((MutRecDefnsPhase2DataForModule(mtypeAcc, mspec), _), mdefs) -> - let mexpr = TcMutRecDefsFinish cenv mdefs m - mspec.entity_modul_contents <- MaybeLazy.Strict !mtypeAcc - [ ModuleOrNamespaceBinding.Module(mspec, mexpr) ]) - - TMDefRec(true, tycons, binds, m) - -and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo defs = - eventually { - // Ensure the deref_nlpath call in UpdateAccModuleOrNamespaceType succeeds - if cenv.compilingCanonicalFslibModuleType then - ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath (xml.ToXmlDoc()) - - // Collect the type names so we can implicitly add the compilation suffix to module names - let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecDecls defs - - match mutRecNSInfo with - | Some _ -> - let! (exprf, topAttrsNew), _, envAtEnd = TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm env mutRecNSInfo defs - // Apply the functions for each declaration to build the overall expression-builder - let mexpr = TMDefs(exprf []) - return (mexpr, topAttrsNew, envAtEnd) - - | None -> - - let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) defs - - // Apply the functions for each declaration to build the overall expression-builder - let mexpr = TMDefs(List.foldBack (fun (f, _) x -> f x) compiledDefs []) - - // Collect up the attributes that are global to the file - let topAttrsNew = List.foldBack (fun (_, y) x -> y@x) compiledDefs [] - return (mexpr, topAttrsNew, envAtEnd) - } - - -//-------------------------------------------------------------------------- -// TypeCheckOneImplFile - Typecheck all the namespace fragments in a file. -//-------------------------------------------------------------------------- - - -let ApplyAssemblyLevelAutoOpenAttributeToTcEnv g amap (ccu: CcuThunk) scopem env (p, root) = - let warn() = - warning(Error(FSComp.SR.tcAttributeAutoOpenWasIgnored(p, ccu.AssemblyName), scopem)) - env - let p = splitNamespace p - if isNil p then warn() else - let h, t = List.frontAndBack p - let modref = mkNonLocalTyconRef (mkNonLocalEntityRef ccu (Array.ofList h)) t - match modref.TryDeref with - | ValueNone -> warn() - | ValueSome _ -> - let openDecl = OpenDeclaration.Create ([], [modref], scopem, false) - OpenEntities TcResultsSink.NoSink g amap scopem root env [modref] openDecl - -// Add the CCU and apply the "AutoOpen" attributes -let AddCcuToTcEnv(g, amap, scopem, env, assemblyName, ccu, autoOpens, internalsVisible) = - let env = AddNonLocalCcu g amap scopem env assemblyName (ccu, internalsVisible) - - // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f - // "Microsoft" is opened by default in FSharp.Core - let autoOpens = - let autoOpens = autoOpens |> List.map (fun p -> (p, false)) - if ccuEq ccu g.fslibCcu then - // Auto open 'Microsoft' in FSharp.Core.dll. Even when using old versions of FSharp.Core.dll that do - // not have this attribute. The 'true' means 'treat all namespaces so revealed as "roots" accessible via - // global, e.g. global.FSharp.Collections' - ("Microsoft", true) :: autoOpens - else - autoOpens - - let env = (env, autoOpens) ||> List.fold (ApplyAssemblyLevelAutoOpenAttributeToTcEnv g amap ccu scopem) - env - -let CreateInitialTcEnv(g, amap, scopem, assemblyName, ccus) = - (emptyTcEnv g, ccus) ||> List.fold (fun env (ccu, autoOpens, internalsVisible) -> - try - AddCcuToTcEnv(g, amap, scopem, env, assemblyName, ccu, autoOpens, internalsVisible) - with e -> - errorRecovery e scopem - env) - -type ConditionalDefines = - string list - - -/// The attributes that don't get attached to any declaration -type TopAttribs = - { mainMethodAttrs: Attribs - netModuleAttrs: Attribs - assemblyAttrs: Attribs } - -let EmptyTopAttrs = - { mainMethodAttrs=[] - netModuleAttrs=[] - assemblyAttrs =[] } - -let CombineTopAttrs topAttrs1 topAttrs2 = - { mainMethodAttrs = topAttrs1.mainMethodAttrs @ topAttrs2.mainMethodAttrs - netModuleAttrs = topAttrs1.netModuleAttrs @ topAttrs2.netModuleAttrs - assemblyAttrs = topAttrs1.assemblyAttrs @ topAttrs2.assemblyAttrs } - -let rec IterTyconsOfModuleOrNamespaceType f (mty: ModuleOrNamespaceType) = - mty.AllEntities |> QueueList.iter (fun tycon -> f tycon) - mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> - IterTyconsOfModuleOrNamespaceType f v.ModuleOrNamespaceType) - - -// Defaults get applied before the module signature is checked and before the implementation conditions on virtuals/overrides. -// Defaults get applied in priority order. Defaults listed last get priority 0 (lowest), 2nd last priority 1 etc. -let ApplyDefaults cenv g denvAtEnd m mexpr extraAttribs = - try - let unsolved = FSharp.Compiler.FindUnsolved.UnsolvedTyparsOfModuleDef g cenv.amap denvAtEnd (mexpr, extraAttribs) - - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denvAtEnd, m) unsolved - - let applyDefaults priority = - unsolved |> List.iter (fun tp -> - if not tp.IsSolved then - // Apply the first default. If we're defaulting one type variable to another then - // the defaults will be propagated to the new type variable. - tp.Constraints |> List.iter (fun tpc -> - match tpc with - | TyparConstraint.DefaultsTo(priority2, ty2, m) when priority2 = priority -> - let ty1 = mkTyparTy tp - if not tp.IsSolved && not (typeEquiv cenv.g ty1 ty2) then - let csenv = MakeConstraintSolverEnv ContextInfo.NoContext cenv.css m denvAtEnd - TryD (fun () -> ConstraintSolver.SolveTyparEqualsType csenv 0 m NoTrace ty1 ty2) - (fun e -> solveTypAsError cenv denvAtEnd m ty1 - ErrorD(ErrorFromApplyingDefault(g, denvAtEnd, tp, ty2, e, m))) - |> RaiseOperationResult - | _ -> ())) - - for priority = 10 downto 0 do - applyDefaults priority - - // OK, now apply defaults for any unsolved HeadTypeStaticReq - unsolved |> List.iter (fun tp -> - if not tp.IsSolved then - if (tp.StaticReq <> NoStaticReq) then - ConstraintSolver.ChooseTyparSolutionAndSolve cenv.css denvAtEnd tp) - with e -> errorRecovery e m - -let CheckValueRestriction denvAtEnd rootSigOpt implFileTypePriorToSig m = - if Option.isNone rootSigOpt then - let rec check (mty: ModuleOrNamespaceType) = - for v in mty.AllValsAndMembers do - let ftyvs = (freeInVal CollectTyparsNoCaching v).FreeTypars |> Zset.elements - if (not v.IsCompilerGenerated && - not (ftyvs |> List.exists (fun tp -> tp.IsFromError)) && - // Do not apply the value restriction to methods and functions - // Note, normally these completely generalize their argument types anyway. However, - // some methods (property getters/setters, constructors) can't be as generic - // as they might naturally be, and these can leave type variables unsolved. See - // for example FSharp 1.0 3661. - (match v.ValReprInfo with None -> true | Some tvi -> tvi.HasNoArgs)) then - match ftyvs with - | tp :: _ -> errorR (ValueRestriction(denvAtEnd, false, v, tp, v.Range)) - | _ -> () - mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> check v.ModuleOrNamespaceType) - try check implFileTypePriorToSig with e -> errorRecovery e m - - -let SolveInternalUnknowns g cenv denvAtEnd mexpr extraAttribs = - let unsolved = FSharp.Compiler.FindUnsolved.UnsolvedTyparsOfModuleDef g cenv.amap denvAtEnd (mexpr, extraAttribs) - - unsolved |> List.iter (fun tp -> - if (tp.Rigidity <> TyparRigidity.Rigid) && not tp.IsSolved then - ConstraintSolver.ChooseTyparSolutionAndSolve cenv.css denvAtEnd tp) - -let CheckModuleSignature g cenv m denvAtEnd rootSigOpt implFileTypePriorToSig implFileSpecPriorToSig mexpr = - match rootSigOpt with - | None -> - // Deep copy the inferred type of the module - let implFileTypePriorToSigCopied = copyModuleOrNamespaceType g CloneAll implFileTypePriorToSig - - ModuleOrNamespaceExprWithSig(implFileTypePriorToSigCopied, mexpr, m) - - | Some sigFileType -> - - // We want to show imperative type variables in any types in error messages at this late point - let denv = { denvAtEnd with showImperativeTyparAnnotations=true } - begin - try - - // As typechecked the signature and implementation use different tycons etc. - // Here we (a) check there are enough names, (b) match them up to build a renaming and - // (c) check signature conformance up to this renaming. - if not (SignatureConformance.CheckNamesOfModuleOrNamespace denv (mkLocalTyconRef implFileSpecPriorToSig) sigFileType) then - raise (ReportedError None) - - // Compute the remapping from implementation to signature - let remapInfo, _ = ComputeRemappingFromInferredSignatureToExplicitSignature cenv.g implFileTypePriorToSig sigFileType - - let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } - - if not (SignatureConformance.Checker(cenv.g, cenv.amap, denv, remapInfo, true).CheckSignature aenv (mkLocalModRef implFileSpecPriorToSig) sigFileType) then ( - // We can just raise 'ReportedError' since CheckModuleOrNamespace raises its own error - raise (ReportedError None) - ) - with e -> errorRecovery e m - end - - ModuleOrNamespaceExprWithSig(sigFileType, mexpr, m) - - -/// Check an entire implementation file -/// Typecheck, then close the inference scope and then check the file meets its signature (if any) -let TypeCheckOneImplFile - // checkForErrors: A function to help us stop reporting cascading errors - (g, niceNameGen, amap, topCcu, checkForErrors, conditionalDefines, tcSink, isInternalTestSpanStackReferring) - env - (rootSigOpt: ModuleOrNamespaceType option) - (ParsedImplFileInput (_, isScript, qualNameOfFile, scopedPragmas, _, implFileFrags, isLastCompiland)) = - - eventually { - let cenv = cenv.Create (g, isScript, niceNameGen, amap, topCcu, false, Option.isSome rootSigOpt, conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring) - - let envinner, mtypeAcc = MakeInitialEnv env - - let defs = [ for x in implFileFrags -> SynModuleDecl.NamespaceFragment x ] - let! mexpr, topAttrs, envAtEnd = TcModuleOrNamespaceElements cenv ParentNone qualNameOfFile.Range envinner PreXmlDocEmpty None defs - - let implFileTypePriorToSig = !mtypeAcc - - let topAttrs = - let mainMethodAttrs, others = topAttrs |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Method <> enum 0) - let assemblyAttrs, others = others |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Assembly <> enum 0) - // REVIEW: consider checking if '_others' is empty - let netModuleAttrs, _others = others |> List.partition (fun (possTargets, _) -> possTargets &&& AttributeTargets.Module <> enum 0) - { mainMethodAttrs = List.map snd mainMethodAttrs - netModuleAttrs = List.map snd netModuleAttrs - assemblyAttrs = List.map snd assemblyAttrs} - let denvAtEnd = envAtEnd.DisplayEnv - let m = qualNameOfFile.Range - - // This is a fake module spec - let implFileSpecPriorToSig = wrapModuleOrNamespaceType qualNameOfFile.Id (compPathOfCcu topCcu) implFileTypePriorToSig - - let extraAttribs = topAttrs.mainMethodAttrs@topAttrs.netModuleAttrs@topAttrs.assemblyAttrs - - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - ApplyDefaults cenv g denvAtEnd m mexpr extraAttribs) - - // Check completion of all classes defined across this file. - // NOTE: this is not a great technique if inner signatures are permitted to hide - // virtual dispatch slots. - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - try implFileTypePriorToSig |> IterTyconsOfModuleOrNamespaceType (FinalTypeDefinitionChecksAtEndOfInferenceScope (cenv.infoReader, envAtEnd.NameEnv, cenv.tcSink, true, denvAtEnd)) - with e -> errorRecovery e m) - - // Check the value restriction. Only checked if there is no signature. - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - CheckValueRestriction denvAtEnd rootSigOpt implFileTypePriorToSig m) - - // Solve unsolved internal type variables - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - SolveInternalUnknowns g cenv denvAtEnd mexpr extraAttribs) - - // Check the module matches the signature - let implFileExprAfterSig = - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - CheckModuleSignature g cenv m denvAtEnd rootSigOpt implFileTypePriorToSig implFileSpecPriorToSig mexpr) - - // Run any additional checks registered for post-type-inference - do - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - for check in cenv.postInferenceChecks do - try - check() - with e -> - errorRecovery e m) - - // We ALWAYS run the PostTypeCheckSemanticChecks phase, though we if we have already encountered some - // errors we turn off error reporting. This is because it performs various fixups over the TAST, e.g. - // assigning nice names for inference variables. - let hasExplicitEntryPoint, anonRecdTypes = - - conditionallySuppressErrorReporting (checkForErrors()) (fun () -> - - try - let reportErrors = not (checkForErrors()) - - PostTypeCheckSemanticChecks.CheckTopImpl - (g, cenv.amap, reportErrors, cenv.infoReader, - env.eInternalsVisibleCompPaths, cenv.topCcu, envAtEnd.DisplayEnv, - implFileExprAfterSig, extraAttribs, isLastCompiland, - isInternalTestSpanStackReferring) - - with e -> - errorRecovery e m - false, StampMap.Empty) - - // Warn on version attributes. - topAttrs.assemblyAttrs |> List.iter (function - | Attrib(tref, _, [ AttribExpr(Expr.Const (Const.String version, range, _), _) ], _, _, _, _) -> - let attrName = tref.CompiledRepresentationForNamedType.FullName - let isValid() = - try IL.parseILVersion version |> ignore; true - with _ -> false - match attrName with - | "System.Reflection.AssemblyFileVersionAttribute" //TODO compile error like c# compiler? - | "System.Reflection.AssemblyVersionAttribute" when not (isValid()) -> - warning(Error(FSComp.SR.fscBadAssemblyVersion(attrName, version), range)) - | _ -> () - | _ -> ()) - - let implFile = TImplFile (qualNameOfFile, scopedPragmas, implFileExprAfterSig, hasExplicitEntryPoint, isScript, anonRecdTypes) - - return (topAttrs, implFile, implFileTypePriorToSig, envAtEnd, cenv.createsGeneratedProvidedTypes) - } - - - -/// Check an entire signature file -let TypeCheckOneSigFile (g, niceNameGen, amap, topCcu, checkForErrors, conditionalDefines, tcSink, isInternalTestSpanStackReferring) tcEnv (ParsedSigFileInput (_, qualNameOfFile, _, _, sigFileFrags)) = - eventually { - let cenv = cenv.Create (g, false, niceNameGen, amap, topCcu, true, false, conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring) - let envinner, mtypeAcc = MakeInitialEnv tcEnv - - let specs = [ for x in sigFileFrags -> SynModuleSigDecl.NamespaceFragment x ] - let! tcEnv = TcSignatureElements cenv ParentNone qualNameOfFile.Range envinner PreXmlDocEmpty None specs - - let sigFileType = !mtypeAcc - - if not (checkForErrors()) then - try sigFileType |> IterTyconsOfModuleOrNamespaceType (FinalTypeDefinitionChecksAtEndOfInferenceScope(cenv.infoReader, tcEnv.NameEnv, cenv.tcSink, false, tcEnv.DisplayEnv)) - with e -> errorRecovery e qualNameOfFile.Range - - return (tcEnv, sigFileType, cenv.createsGeneratedProvidedTypes) - } diff --git a/src/fsharp/TypeChecker.fsi b/src/fsharp/TypeChecker.fsi deleted file mode 100644 index 09856e04895..00000000000 --- a/src/fsharp/TypeChecker.fsi +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.TypeChecker - -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Infos -open FSharp.Compiler.Import -open FSharp.Compiler.TcGlobals - -open System.Collections.Generic - -[] -type TcEnv = - member DisplayEnv : DisplayEnv - member NameEnv : NameResolution.NameResolutionEnv - member AccessRights : AccessorDomain - -val CreateInitialTcEnv : TcGlobals * ImportMap * range * assemblyName: string * (CcuThunk * string list * string list) list -> TcEnv -val AddCcuToTcEnv : TcGlobals * ImportMap * range * TcEnv * assemblyName: string * ccu: CcuThunk * autoOpens: string list * internalsVisibleToAttributes: string list -> TcEnv -val AddLocalRootModuleOrNamespace : NameResolution.TcResultsSink -> TcGlobals -> ImportMap -> range -> TcEnv -> ModuleOrNamespaceType -> TcEnv -val TcOpenDecl : NameResolution.TcResultsSink -> TcGlobals -> ImportMap -> range -> range -> TcEnv -> LongIdent -> TcEnv - -type TopAttribs = - { mainMethodAttrs : Attribs; - netModuleAttrs : Attribs; - assemblyAttrs : Attribs } - -type ConditionalDefines = - string list - -val EmptyTopAttrs : TopAttribs -val CombineTopAttrs : TopAttribs -> TopAttribs -> TopAttribs - -val TypeCheckOneImplFile : - TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines option * NameResolution.TcResultsSink * bool - -> TcEnv - -> Tast.ModuleOrNamespaceType option - -> ParsedImplFileInput - -> Eventually - -val TypeCheckOneSigFile : - TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines option * NameResolution.TcResultsSink * bool - -> TcEnv - -> ParsedSigFileInput - -> Eventually - -//------------------------------------------------------------------------- -// Some of the exceptions arising from type checking. These should be moved to -// use ErrorLogger. -//------------------------------------------------------------------------- - -exception BakedInMemberConstraintName of string * range -exception FunctionExpected of DisplayEnv * TType * range -exception NotAFunction of DisplayEnv * TType * range * range -exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range -exception Recursion of DisplayEnv * Ast.Ident * TType * TType * range -exception RecursiveUseCheckedAtRuntime of DisplayEnv * ValRef * range -exception LetRecEvaluatedOutOfOrder of DisplayEnv * ValRef * ValRef * range -exception LetRecCheckedAtRuntime of range -exception LetRecUnsound of DisplayEnv * ValRef list * range -exception TyconBadArgs of DisplayEnv * TyconRef * int * range -exception UnionCaseWrongArguments of DisplayEnv * int * int * range -exception UnionCaseWrongNumberOfArgs of DisplayEnv * int * int * range -exception FieldsFromDifferentTypes of DisplayEnv * RecdFieldRef * RecdFieldRef * range -exception FieldGivenTwice of DisplayEnv * RecdFieldRef * range -exception MissingFields of string list * range -exception UnitTypeExpected of DisplayEnv * TType * range -exception UnitTypeExpectedWithEquality of DisplayEnv * TType * range -exception UnitTypeExpectedWithPossiblePropertySetter of DisplayEnv * TType * string * string * range -exception UnitTypeExpectedWithPossibleAssignment of DisplayEnv * TType * bool * string * range -exception FunctionValueUnexpected of DisplayEnv * TType * range -exception UnionPatternsBindDifferentNames of range -exception VarBoundTwice of Ast.Ident -exception ValueRestriction of DisplayEnv * bool * Val * Typar * range -exception ValNotMutable of DisplayEnv * ValRef * range -exception ValNotLocal of DisplayEnv * ValRef * range -exception InvalidRuntimeCoercion of DisplayEnv * TType * TType * range -exception IndeterminateRuntimeCoercion of DisplayEnv * TType * TType * range -exception IndeterminateStaticCoercion of DisplayEnv * TType * TType * range -exception StaticCoercionShouldUseBox of DisplayEnv * TType * TType * range -exception RuntimeCoercionSourceSealed of DisplayEnv * TType * range -exception CoercionTargetSealed of DisplayEnv * TType * range -exception UpcastUnnecessary of range -exception TypeTestUnnecessary of range -exception SelfRefObjCtor of bool * range -exception VirtualAugmentationOnNullValuedType of range -exception NonVirtualAugmentationOnNullValuedType of range -exception UseOfAddressOfOperator of range -exception DeprecatedThreadStaticBindingWarning of range -exception NotUpperCaseConstructor of range -exception IntfImplInIntrinsicAugmentation of range -exception IntfImplInExtrinsicAugmentation of range -exception OverrideInIntrinsicAugmentation of range -exception OverrideInExtrinsicAugmentation of range -exception NonUniqueInferredAbstractSlot of TcGlobals * DisplayEnv * string * MethInfo * MethInfo * range -exception StandardOperatorRedefinitionWarning of string * range -exception ParameterlessStructCtor of range -exception InvalidInternalsVisibleToAssemblyName of (*badName*)string * (*fileName option*) string option - -val TcFieldInit : range -> ILFieldInit -> Tast.Const - -val LightweightTcValForUsingInBuildMethodCall : g : TcGlobals -> vref:ValRef -> vrefFlags : ValUseFlag -> vrefTypeInst : TTypes -> m : range -> Expr * TType \ No newline at end of file diff --git a/src/fsharp/TypeRelations.fs b/src/fsharp/TypeRelations.fs index dd32a6ee001..b52dfac4dda 100755 --- a/src/fsharp/TypeRelations.fs +++ b/src/fsharp/TypeRelations.fs @@ -4,13 +4,14 @@ /// constraint solving and method overload resolution. module internal FSharp.Compiler.TypeRelations -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Collections +open Internal.Utilities.Library open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals open FSharp.Compiler.Infos +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps /// Implements a :> b without coercion based on finalized (no type variable) types // Note: This relation is approximate and not part of the language specification. @@ -46,30 +47,37 @@ let rec TypeDefinitelySubsumesTypeNoCoercion ndeep g amap m ty1 ty2 = type CanCoerce = CanCoerce | NoCoerce /// The feasible equivalence relation. Part of the language spec. -let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = +let rec TypesFeasiblyEquivalent stripMeasures ndeep g amap m ty1 ty2 = if ndeep > 100 then error(InternalError("recursive class hierarchy (detected in TypeFeasiblySubsumesType), ty1 = " + (DebugPrint.showType ty1), m)); - let ty1 = stripTyEqns g ty1 - let ty2 = stripTyEqns g ty2 - match ty1, ty2 with + let stripAll ty = + if stripMeasures then + ty |> stripTyEqnsWrtErasure EraseAll g |> stripMeasuresFromTType g + else + ty |> stripTyEqns g + + let ty1str = stripAll ty1 + let ty2str = stripAll ty2 + + match ty1str, ty2str with | TType_var _, _ | _, TType_var _ -> true - | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) -> (evalTupInfoIsStruct anonInfo1.TupInfo = evalTupInfoIsStruct anonInfo2.TupInfo) && (match anonInfo1.Assembly, anonInfo2.Assembly with ccu1, ccu2 -> ccuEq ccu1 ccu2) && (anonInfo1.SortedNames = anonInfo2.SortedNames) && - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> evalTupInfoIsStruct tupInfo1 = evalTupInfoIsStruct tupInfo2 && - List.lengthsEqAndForall2 (TypesFeasiblyEquiv ndeep g amap m) l1 l2 + List.lengthsEqAndForall2 (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) l1 l2 | TType_fun (d1, r1), TType_fun (d2, r2) -> - (TypesFeasiblyEquiv ndeep g amap m) d1 d2 && (TypesFeasiblyEquiv ndeep g amap m) r1 r2 + (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) d1 d2 && (TypesFeasiblyEquivalent stripMeasures ndeep g amap m) r1 r2 | TType_measure _, TType_measure _ -> true @@ -77,8 +85,15 @@ let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = | _ -> false -/// The feasible coercion relation. Part of the language spec. +/// The feasible equivalence relation. Part of the language spec. +let rec TypesFeasiblyEquiv ndeep g amap m ty1 ty2 = + TypesFeasiblyEquivalent false ndeep g amap m ty1 ty2 +/// The feasible equivalence relation after stripping Measures. +let TypesFeasiblyEquivStripMeasures g amap m ty1 ty2 = + TypesFeasiblyEquivalent true 0 g amap m ty1 ty2 + +/// The feasible coercion relation. Part of the language spec. let rec TypeFeasiblySubsumesType ndeep g amap m ty1 canCoerce ty2 = if ndeep > 100 then error(InternalError("recursive class hierarchy (detected in TypeFeasiblySubsumesType), ty1 = " + (DebugPrint.showType ty1), m)) let ty1 = stripTyEqns g ty1 @@ -109,7 +124,6 @@ let rec TypeFeasiblySubsumesType ndeep g amap m ty1 canCoerce ty2 = ty2 |> GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m |> List.exists (TypeFeasiblySubsumesType (ndeep+1) g amap m ty1 NoCoerce)) - /// Choose solutions for Expr.TyChoose type "hidden" variables introduced /// by letrec nodes. Also used by the pattern match compiler to choose type /// variables when compiling patterns at generalized bindings. @@ -133,7 +147,7 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) = match tpc with | TyparConstraint.CoercesTo(x, m) -> join m x, m - | TyparConstraint.MayResolveMember(TTrait(_, _, _, _, _, _), m) -> + | TyparConstraint.MayResolveMember(_traitInfo, m) -> maxSoFar, m | TyparConstraint.SimpleChoice(_, m) -> errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInPrintf(), m)) @@ -210,7 +224,6 @@ let ChooseTyparSolutionsForFreeChoiceTypars g amap e = instExpr g tpenv e1 | _ -> e - /// Break apart lambdas. Needs ChooseTyparSolutionsForFreeChoiceTypars because it's used in /// PostTypeCheckSemanticChecks before we've eliminated these nodes. @@ -218,7 +231,7 @@ let tryDestTopLambda g amap (ValReprInfo (tpNames, _, _) as tvd) (e, ty) = let rec stripLambdaUpto n (e, ty) = match e with | Expr.Lambda (_, None, None, v, b, _, retTy) when n > 0 -> - let (vs', b', retTy') = stripLambdaUpto (n-1) (b, retTy) + let vs', b', retTy' = stripLambdaUpto (n-1) (b, retTy) (v :: vs', b', retTy') | _ -> ([], e, ty) @@ -226,7 +239,7 @@ let tryDestTopLambda g amap (ValReprInfo (tpNames, _, _) as tvd) (e, ty) = let rec startStripLambdaUpto n (e, ty) = match e with | Expr.Lambda (_, ctorThisValOpt, baseValOpt, v, b, _, retTy) when n > 0 -> - let (vs', b', retTy') = stripLambdaUpto (n-1) (b, retTy) + let vs', b', retTy' = stripLambdaUpto (n-1) (b, retTy) (ctorThisValOpt, baseValOpt, (v :: vs'), b', retTy') | Expr.TyChoose (_tps, _b, _) -> startStripLambdaUpto n (ChooseTyparSolutionsForFreeChoiceTypars g amap e, ty) @@ -266,11 +279,9 @@ let IteratedAdjustArityOfLambda g amap topValInfo e = let vsl, body = IteratedAdjustArityOfLambdaBody g arities vsl body tps, ctorThisValOpt, baseValOpt, vsl, body, bodyty - /// "Single Feasible Type" inference /// Look for the unique supertype of ty2 for which ty2 :> ty1 might feasibly hold let FindUniqueFeasibleSupertype g amap m ty1 ty2 = - if not (isAppTy g ty2) then None else let supertypes = Option.toList (GetSuperTypeOfType g amap m ty2) @ (GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty2) supertypes |> List.tryFind (TypeFeasiblySubsumesType 0 g amap m ty1 NoCoerce) diff --git a/src/fsharp/TypeRelations.fsi b/src/fsharp/TypeRelations.fsi new file mode 100644 index 00000000000..2138e0e57f8 --- /dev/null +++ b/src/fsharp/TypeRelations.fsi @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Primary relations on types and signatures, with the exception of +/// constraint solving and method overload resolution. +module internal FSharp.Compiler.TypeRelations + +open FSharp.Compiler.Import +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +type CanCoerce = + | CanCoerce + | NoCoerce + +/// Implements a :> b without coercion based on finalized (no type variable) types +val TypeDefinitelySubsumesTypeNoCoercion: ndeep:int -> g:TcGlobals -> amap:ImportMap -> m:range -> ty1:TType -> ty2:TType -> bool + +/// The feasible equivalence relation. Part of the language spec. +val TypesFeasiblyEquivalent: stripMeasures:bool -> ndeep:int -> g:TcGlobals -> amap:'a -> m:range -> ty1:TType -> ty2:TType -> bool + +/// The feasible equivalence relation. Part of the language spec. +val TypesFeasiblyEquiv: ndeep:int -> g:TcGlobals -> amap:'a -> m:range -> ty1:TType -> ty2:TType -> bool + +/// The feasible equivalence relation after stripping Measures. +val TypesFeasiblyEquivStripMeasures: g:TcGlobals -> amap:'a -> m:range -> ty1:TType -> ty2:TType -> bool + +/// The feasible coercion relation. Part of the language spec. +val TypeFeasiblySubsumesType: ndeep:int -> g:TcGlobals -> amap:ImportMap -> m:range -> ty1:TType -> canCoerce:CanCoerce -> ty2:TType -> bool + +/// Choose solutions for Expr.TyChoose type "hidden" variables introduced +/// by letrec nodes. Also used by the pattern match compiler to choose type +/// variables when compiling patterns at generalized bindings. +/// e.g. let ([], x) = ([], []) +/// Here x gets a generalized type "list<'T>". +val ChooseTyparSolutionAndRange: g:TcGlobals -> amap:ImportMap -> tp:Typar -> TType * range + +val ChooseTyparSolution: g:TcGlobals -> amap:ImportMap -> tp:Typar -> TType + +val IterativelySubstituteTyparSolutions: g:TcGlobals -> tps:Typars -> solutions:TTypes -> TypeInst + +val ChooseTyparSolutionsForFreeChoiceTypars: g:TcGlobals -> amap:ImportMap -> e:Expr -> Expr + +/// Break apart lambdas. Needs ChooseTyparSolutionsForFreeChoiceTypars because it's used in +/// PostTypeCheckSemanticChecks before we've eliminated these nodes. +val tryDestTopLambda: g:TcGlobals -> amap:ImportMap -> ValReprInfo -> e:Expr * ty:TType -> (Typars * Val option * Val option * Val list list * Expr * TType) option + +val destTopLambda: g:TcGlobals -> amap:ImportMap -> topValInfo:ValReprInfo -> e:Expr * ty:TType -> Typars * Val option * Val option * Val list list * Expr * TType + +/// Do AdjustArityOfLambdaBody for a series of iterated lambdas, producing one method. +/// The required iterated function arity (List.length topValInfo) must be identical +/// to the iterated function arity of the input lambda (List.length vsl) +val IteratedAdjustArityOfLambda: g:TcGlobals -> amap:ImportMap -> topValInfo:ValReprInfo -> e:Expr -> Typars * Val option * Val option * Val list list * Expr * TType + +/// "Single Feasible Type" inference +/// Look for the unique supertype of ty2 for which ty2 :> ty1 might feasibly hold +val FindUniqueFeasibleSupertype: g:TcGlobals -> amap:ImportMap -> m:range -> ty1:TType -> ty2:TType -> TType option diff --git a/src/fsharp/TypedTree.fs b/src/fsharp/TypedTree.fs new file mode 100644 index 00000000000..cc4545ee69c --- /dev/null +++ b/src/fsharp/TypedTree.fs @@ -0,0 +1,5842 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines the typed abstract syntax intermediate representation used throughout the F# compiler. +module internal rec FSharp.Compiler.TypedTree + +open System +open System.Collections.Generic +open System.Diagnostics +open System.Reflection + +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Rational + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILX.Types +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.QuotationPickler +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +open FSharp.Core.CompilerServices +#endif + +type Stamp = int64 + +type StampMap<'T> = Map + +[] +type ValInline = + + /// Indicates the value is inlined but the .NET IL code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined + | Always + + /// Indicates the value may optionally be inlined by the optimizer + | Optional + + /// Indicates the value must never be inlined by the optimizer + | Never + + /// Returns true if the implementation of a value must always be inlined + member x.MustInline = + match x with + | ValInline.Always -> true + | ValInline.Optional | ValInline.Never -> false + +/// A flag associated with values that indicates whether the recursive scope of the value is currently being processed, and +/// if the value has been generalized or not as yet. +type ValRecursiveScopeInfo = + + /// Set while the value is within its recursive scope. The flag indicates if the value has been eagerly generalized and accepts generic-recursive calls + | ValInRecScope of bool + + /// The normal value for this flag when the value is not within its recursive scope + | ValNotInRecScope + +type ValMutability = + | Immutable + | Mutable + +[] +/// Indicates if a type parameter is needed at runtime and may not be eliminated +type TyparDynamicReq = + + /// Indicates the type parameter is not needed at runtime and may be eliminated + | No + + /// Indicates the type parameter is needed at runtime and may not be eliminated + | Yes + +type ValBaseOrThisInfo = + + /// Indicates a ref-cell holding 'this' or the implicit 'this' used throughout an + /// implicit constructor to access and set values + | CtorThisVal + + /// Indicates the value called 'base' available for calling base class members + | BaseVal + + /// Indicates a normal value + | NormalVal + + /// Indicates the 'this' value specified in a memberm e.g. 'x' in 'member x.M() = 1' + | MemberThisVal + +[] +/// Flags on values +type ValFlags(flags: int64) = + + new (recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal) = + let flags = + (match baseOrThis with + | BaseVal -> 0b00000000000000000000L + | CtorThisVal -> 0b00000000000000000010L + | NormalVal -> 0b00000000000000000100L + | MemberThisVal -> 0b00000000000000000110L) ||| + (if isCompGen then 0b00000000000000001000L + else 0b000000000000000000000L) ||| + (match inlineInfo with + | ValInline.Always -> 0b00000000000000010000L + | ValInline.Optional -> 0b00000000000000100000L + | ValInline.Never -> 0b00000000000000110000L) ||| + (match isMutable with + | Immutable -> 0b00000000000000000000L + | Mutable -> 0b00000000000001000000L) ||| + + (match isModuleOrMemberBinding with + | false -> 0b00000000000000000000L + | true -> 0b00000000000010000000L) ||| + (match isExtensionMember with + | false -> 0b00000000000000000000L + | true -> 0b00000000000100000000L) ||| + (match isIncrClassSpecialMember with + | false -> 0b00000000000000000000L + | true -> 0b00000000001000000000L) ||| + (match isTyFunc with + | false -> 0b00000000000000000000L + | true -> 0b00000000010000000000L) ||| + + (match recValInfo with + | ValNotInRecScope -> 0b00000000000000000000L + | ValInRecScope true -> 0b00000000100000000000L + | ValInRecScope false -> 0b00000001000000000000L) ||| + + (match allowTypeInst with + | false -> 0b00000000000000000000L + | true -> 0b00000100000000000000L) ||| + + (match isGeneratedEventVal with + | false -> 0b00000000000000000000L + | true -> 0b00100000000000000000L) + + ValFlags flags + + member x.BaseOrThisInfo = + match (flags &&& 0b00000000000000000110L) with + | 0b00000000000000000000L -> BaseVal + | 0b00000000000000000010L -> CtorThisVal + | 0b00000000000000000100L -> NormalVal + | 0b00000000000000000110L -> MemberThisVal + | _ -> failwith "unreachable" + + + + member x.IsCompilerGenerated = (flags &&& 0b00000000000000001000L) <> 0x0L + + member x.WithIsCompilerGenerated isCompGen = + let flags = (flags &&& ~~~0b00000000000000001000L) ||| + (match isCompGen with + | false -> 0b00000000000000000000L + | true -> 0b00000000000000001000L) + ValFlags flags + + member x.InlineInfo = + match (flags &&& 0b00000000000000110000L) with + | 0b00000000000000000000L + | 0b00000000000000010000L -> ValInline.Always + | 0b00000000000000100000L -> ValInline.Optional + | 0b00000000000000110000L -> ValInline.Never + | _ -> failwith "unreachable" + + member x.MutabilityInfo = + match (flags &&& 0b00000000000001000000L) with + | 0b00000000000000000000L -> Immutable + | 0b00000000000001000000L -> Mutable + | _ -> failwith "unreachable" + + + member x.IsMemberOrModuleBinding = + match (flags &&& 0b00000000000010000000L) with + | 0b00000000000000000000L -> false + | 0b00000000000010000000L -> true + | _ -> failwith "unreachable" + + + member x.WithIsMemberOrModuleBinding = ValFlags(flags ||| 0b00000000000010000000L) + + + member x.IsExtensionMember = (flags &&& 0b00000000000100000000L) <> 0L + + member x.IsIncrClassSpecialMember = (flags &&& 0b00000000001000000000L) <> 0L + + member x.IsTypeFunction = (flags &&& 0b00000000010000000000L) <> 0L + + member x.RecursiveValInfo = match (flags &&& 0b00000001100000000000L) with + | 0b00000000000000000000L -> ValNotInRecScope + | 0b00000000100000000000L -> ValInRecScope true + | 0b00000001000000000000L -> ValInRecScope false + | _ -> failwith "unreachable" + + member x.WithRecursiveValInfo recValInfo = + let flags = + (flags &&& ~~~0b00000001100000000000L) ||| + (match recValInfo with + | ValNotInRecScope -> 0b00000000000000000000L + | ValInRecScope true -> 0b00000000100000000000L + | ValInRecScope false -> 0b00000001000000000000L) + ValFlags flags + + member x.MakesNoCriticalTailcalls = (flags &&& 0b00000010000000000000L) <> 0L + + member x.WithMakesNoCriticalTailcalls = ValFlags(flags ||| 0b00000010000000000000L) + + member x.PermitsExplicitTypeInstantiation = (flags &&& 0b00000100000000000000L) <> 0L + + member x.HasBeenReferenced = (flags &&& 0b00001000000000000000L) <> 0L + + member x.WithHasBeenReferenced = ValFlags(flags ||| 0b00001000000000000000L) + + member x.IsCompiledAsStaticPropertyWithoutField = (flags &&& 0b00010000000000000000L) <> 0L + + member x.WithIsCompiledAsStaticPropertyWithoutField = ValFlags(flags ||| 0b00010000000000000000L) + + member x.IsGeneratedEventVal = (flags &&& 0b00100000000000000000L) <> 0L + + member x.IsFixed = (flags &&& 0b01000000000000000000L) <> 0L + + member x.WithIsFixed = ValFlags(flags ||| 0b01000000000000000000L) + + member x.IgnoresByrefScope = (flags &&& 0b10000000000000000000L) <> 0L + + member x.WithIgnoresByrefScope = ValFlags(flags ||| 0b10000000000000000000L) + + member x.InlineIfLambda = (flags &&& 0b100000000000000000000L) <> 0L + + member x.WithInlineIfLambda = ValFlags(flags ||| 0b100000000000000000000L) + + /// Get the flags as included in the F# binary metadata + member x.PickledBits = + // Clear the RecursiveValInfo, only used during inference and irrelevant across assembly boundaries + // Clear the IsCompiledAsStaticPropertyWithoutField, only used to determine whether to use a true field for a value, and to eliminate the optimization info for observable bindings + // Clear the HasBeenReferenced, only used to report "unreferenced variable" warnings and to help collect 'it' values in FSI.EXE + // Clear the IsGeneratedEventVal, since there's no use in propagating specialname information for generated add/remove event vals + (flags &&& ~~~0b010011001100000000000L) + +/// Represents the kind of a type parameter +[] +type TyparKind = + + | Type + + | Measure + + member x.AttrName = + match x with + | TyparKind.Type -> ValueNone + | TyparKind.Measure -> ValueSome "Measure" + + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = + match x with + | TyparKind.Type -> "type" + | TyparKind.Measure -> "measure" + +/// Indicates if the type variable can be solved or given new constraints. The status of a type variable +/// evolves towards being either rigid or solved. +[] +type TyparRigidity = + + /// Indicates the type parameter can't be solved + | Rigid + + /// Indicates the type parameter can't be solved, but the variable is not set to "rigid" until after inference is complete + | WillBeRigid + + /// Indicates we give a warning if the type parameter is ever solved + | WarnIfNotRigid + + /// Indicates the type parameter is an inference variable may be solved + | Flexible + + /// Indicates the type parameter derives from an '_' anonymous type + /// For units-of-measure, we give a warning if this gets solved to '1' + | Anon + + member x.ErrorIfUnified = match x with TyparRigidity.Rigid -> true | _ -> false + + member x.WarnIfUnified = match x with TyparRigidity.WillBeRigid | TyparRigidity.WarnIfNotRigid -> true | _ -> false + + member x.WarnIfMissingConstraint = match x with TyparRigidity.WillBeRigid -> true | _ -> false + + +/// Encode typar flags into a bit field +[] +type TyparFlags(flags: int32) = + + new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool) = + TyparFlags((if isFromError then 0b00000000000000010 else 0) ||| + (if isCompGen then 0b00000000000000100 else 0) ||| + (match staticReq with + | TyparStaticReq.None -> 0b00000000000000000 + | TyparStaticReq.HeadType -> 0b00000000000001000) ||| + (match rigidity with + | TyparRigidity.Rigid -> 0b00000000000000000 + | TyparRigidity.WillBeRigid -> 0b00000000000100000 + | TyparRigidity.WarnIfNotRigid -> 0b00000000001000000 + | TyparRigidity.Flexible -> 0b00000000001100000 + | TyparRigidity.Anon -> 0b00000000010000000) ||| + (match kind with + | TyparKind.Type -> 0b00000000000000000 + | TyparKind.Measure -> 0b00000000100000000) ||| + (if comparisonDependsOn then + 0b00000001000000000 else 0) ||| + (match dynamicReq with + | TyparDynamicReq.No -> 0b00000000000000000 + | TyparDynamicReq.Yes -> 0b00000010000000000) ||| + (if equalityDependsOn then + 0b00000100000000000 else 0)) + + /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns + member x.IsFromError = (flags &&& 0b00000000000000010) <> 0x0 + + /// Indicates if the type variable is compiler generated, i.e. is an implicit type inference variable + member x.IsCompilerGenerated = (flags &&& 0b00000000000000100) <> 0x0 + + /// Indicates if the type variable has a static "head type" requirement, i.e. ^a variables used in FSharp.Core and member constraints. + member x.StaticReq = + match (flags &&& 0b00000000000001000) with + | 0b00000000000000000 -> TyparStaticReq.None + | 0b00000000000001000 -> TyparStaticReq.HeadType + | _ -> failwith "unreachable" + + /// Indicates if the type variable can be solved or given new constraints. The status of a type variable + /// generally always evolves towards being either rigid or solved. + member x.Rigidity = + match (flags &&& 0b00000000011100000) with + | 0b00000000000000000 -> TyparRigidity.Rigid + | 0b00000000000100000 -> TyparRigidity.WillBeRigid + | 0b00000000001000000 -> TyparRigidity.WarnIfNotRigid + | 0b00000000001100000 -> TyparRigidity.Flexible + | 0b00000000010000000 -> TyparRigidity.Anon + | _ -> failwith "unreachable" + + /// Indicates whether a type variable can be instantiated by types or units-of-measure. + member x.Kind = + match (flags &&& 0b00001000100000000) with + | 0b00000000000000000 -> TyparKind.Type + | 0b00000000100000000 -> TyparKind.Measure + | _ -> failwith "unreachable" + + + /// Indicates that whether or not a generic type definition satisfies the comparison constraint is dependent on whether this type variable satisfies the comparison constraint. + member x.ComparisonConditionalOn = + (flags &&& 0b00000001000000000) <> 0x0 + + /// Indicates if a type parameter is needed at runtime and may not be eliminated + member x.DynamicReq = + match (flags &&& 0b00000010000000000) with + | 0b00000000000000000 -> TyparDynamicReq.No + | 0b00000010000000000 -> TyparDynamicReq.Yes + | _ -> failwith "unreachable" + + /// Indicates that whether or not a generic type definition satisfies the equality constraint is dependent on whether this type variable satisfies the equality constraint. + member x.EqualityConditionalOn = + (flags &&& 0b00000100000000000) <> 0x0 + + /// Indicates that whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) + member x.IsCompatFlex = + (flags &&& 0b00010000000000000) <> 0x0 + + member x.WithCompatFlex b = + if b then + TyparFlags(flags ||| 0b00010000000000000) + else + TyparFlags(flags &&& ~~~0b00010000000000000) + + /// Get the flags as included in the F# binary metadata. We pickle this as int64 to allow for future expansion + member x.PickledBits = flags + +/// Encode entity flags into a bit field. We leave lots of space to allow for future expansion. +[] +type EntityFlags(flags: int64) = + + new (usesPrefixDisplay, isModuleOrNamespace, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isStructRecordOrUnionType) = + EntityFlags((if isModuleOrNamespace then 0b000000000000001L else 0L) ||| + (if usesPrefixDisplay then 0b000000000000010L else 0L) ||| + (if preEstablishedHasDefaultCtor then 0b000000000000100L else 0L) ||| + (if hasSelfReferentialCtor then 0b000000000001000L else 0L) ||| + (if isStructRecordOrUnionType then 0b000000000100000L else 0L)) + + /// Indicates the Entity is actually a module or namespace, not a type definition + member x.IsModuleOrNamespace = (flags &&& 0b000000000000001L) <> 0x0L + + /// Indicates the type prefers the "tycon" syntax for display etc. + member x.IsPrefixDisplay = (flags &&& 0b000000000000010L) <> 0x0L + + // This bit is not pickled, only used while establishing a type constructor. It is needed because the type constructor + // is known to satisfy the default constructor constraint even before any of its members have been established. + member x.PreEstablishedHasDefaultConstructor = (flags &&& 0b000000000000100L) <> 0x0L + + // This bit represents an F# specific condition where a type has at least one constructor that may access + // the 'this' pointer prior to successful initialization of the partial contents of the object. In this + // case sub-classes must protect themselves against early access to their contents. + member x.HasSelfReferentialConstructor = (flags &&& 0b000000000001000L) <> 0x0L + + /// This bit is reserved for us in the pickle format, see pickle.fs, it's being listed here to stop it ever being used for anything else + static member ReservedBitForPickleFormatTyconReprFlag = 0b000000000010000L + + /// This bit represents a F# record that is a value type, or a struct record. + member x.IsStructRecordOrUnionType = (flags &&& 0b000000000100000L) <> 0x0L + + /// These two bits represents the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = (flags &&& 0b000000011000000L) + |> function + | 0b000000011000000L -> ValueSome true + | 0b000000010000000L -> ValueSome false + | _ -> ValueNone + + /// Adjust the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.WithIsByRefLike flag = + let flags = + (flags &&& ~~~0b000000011000000L) ||| + (match flag with + | true -> 0b000000011000000L + | false -> 0b000000010000000L) + EntityFlags flags + + /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute + member x.TryIsReadOnly = (flags &&& 0b000001100000000L) + |> function + | 0b000001100000000L -> ValueSome true + | 0b000001000000000L -> ValueSome false + | _ -> ValueNone + + /// Adjust the on-demand analysis about whether the entity has the IsReadOnly attribute + member x.WithIsReadOnly flag = + let flags = + (flags &&& ~~~0b000001100000000L) ||| + (match flag with + | true -> 0b000001100000000L + | false -> 0b000001000000000L) + EntityFlags flags + + /// These two bits represents the on-demand analysis about whether the entity is assumed to be a readonly struct + member x.TryIsAssumedReadOnly = (flags &&& 0b000110000000000L) + |> function + | 0b000110000000000L -> ValueSome true + | 0b000100000000000L -> ValueSome false + | _ -> ValueNone + + /// Adjust the on-demand analysis about whether the entity is assumed to be a readonly struct + member x.WithIsAssumedReadOnly flag = + let flags = + (flags &&& ~~~0b000110000000000L) ||| + (match flag with + | true -> 0b000110000000000L + | false -> 0b000100000000000L) + EntityFlags flags + + /// Get the flags as included in the F# binary metadata + member x.PickledBits = (flags &&& ~~~0b000111111000100L) + + + +exception UndefinedName of + depth: int * + error: (string -> string) * + id: Ident * + suggestions: Suggestions + +exception InternalUndefinedItemRef of (string * string * string -> int * string) * string * string * string + +type ModuleOrNamespaceKind = + + /// Indicates that a module is compiled to a class with the "Module" suffix added. + | FSharpModuleWithSuffix + + /// Indicates that a module is compiled to a class with the same name as the original module + | ModuleOrType + + /// Indicates that a 'module' is really a namespace + | Namespace + +/// A public path records where a construct lives within the global namespace +/// of a CCU. +type PublicPath = + | PubPath of string[] + member x.EnclosingPath = + let (PubPath pp) = x + assert (pp.Length >= 1) + pp.[0..pp.Length-2] + + +/// The information ILXGEN needs about the location of an item +type CompilationPath = + | CompPath of ILScopeRef * (string * ModuleOrNamespaceKind) list + + member x.ILScopeRef = (let (CompPath(scoref, _)) = x in scoref) + + member x.AccessPath = (let (CompPath(_, p)) = x in p) + + member x.MangledPath = List.map fst x.AccessPath + + member x.NestedPublicPath (id: Ident) = PubPath(Array.append (Array.ofList x.MangledPath) [| id.idText |]) + + member x.ParentCompPath = + let a, _ = List.frontAndBack x.AccessPath + CompPath(x.ILScopeRef, a) + + member x.NestedCompPath n modKind = CompPath(x.ILScopeRef, x.AccessPath@[(n, modKind)]) + + member x.DemangledPath = + x.AccessPath |> List.map (fun (nm, k) -> CompilationPath.DemangleEntityName nm k) + + /// String 'Module' off an F# module name, if FSharpModuleWithSuffix is used + static member DemangleEntityName nm k = + match k with + | FSharpModuleWithSuffix -> String.dropSuffix nm FSharpModuleSuffix + | _ -> nm + +[] +type EntityOptionalData = + { + /// The name of the type, possibly with `n mangling + // MUTABILITY; used only when establishing tycons. + mutable entity_compiled_name: string option + + // MUTABILITY: the signature is adjusted when it is checked + /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is + /// the signature range for an item in an implementation + mutable entity_other_range: (range * bool) option + + // MUTABILITY; used only when establishing tycons. + mutable entity_kind: TyparKind + + /// The declared documentation for the type or module + // MUTABILITY: only for unpickle linkage + mutable entity_xmldoc: XmlDoc + + /// The XML document signature for this entity + mutable entity_xmldocsig: string + + /// If non-None, indicates the type is an abbreviation for another type. + // + // MUTABILITY; used only during creation and remapping of tycons + mutable entity_tycon_abbrev: TType option + + /// The declared accessibility of the representation, not taking signatures into account + mutable entity_tycon_repr_accessibility: Accessibility + + /// Indicates how visible is the entity is. + // MUTABILITY: only for unpickle linkage + mutable entity_accessibility: Accessibility + + /// Field used when the 'tycon' is really an exception definition + // + // MUTABILITY; used only during creation and remapping of tycons + mutable entity_exn_info: ExceptionInfo + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "EntityOptionalData(...)" + +/// Represents a type definition, exception definition, module definition or namespace definition. +[] +type Entity = + { + /// The declared type parameters of the type + // MUTABILITY; used only during creation and remapping of tycons + mutable entity_typars: LazyWithContext + + mutable entity_flags: EntityFlags + + /// The unique stamp of the "tycon blob". Note the same tycon in signature and implementation get different stamps + // MUTABILITY: only for unpickle linkage + mutable entity_stamp: Stamp + + /// The name of the type, possibly with `n mangling + // MUTABILITY: only for unpickle linkage + mutable entity_logical_name: string + + /// The declaration location for the type constructor + mutable entity_range: range + + /// The declared attributes for the type + // MUTABILITY; used during creation and remapping of tycons + // MUTABILITY; used when propagating signature attributes into the implementation. + mutable entity_attribs: Attribs + + /// The declared representation of the type, i.e. record, union, class etc. + // + // MUTABILITY; used only during creation and remapping of tycons + mutable entity_tycon_repr: TyconRepresentation + + /// The methods and properties of the type + // + // MUTABILITY; used only during creation and remapping of tycons + mutable entity_tycon_tcaug: TyconAugmentation + + /// This field is used when the 'tycon' is really a module definition. It holds statically nested type definitions and nested modules + // + // MUTABILITY: only used during creation and remapping of tycons and + // when compiling fslib to fixup compiler forward references to internal items + mutable entity_modul_contents: MaybeLazy + + /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 + // REVIEW: it looks like entity_cpath subsumes this + // MUTABILITY: only for unpickle linkage + mutable entity_pubpath: PublicPath option + + /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 + // MUTABILITY: only for unpickle linkage + mutable entity_cpath: CompilationPath option + + /// Used during codegen to hold the ILX representation indicating how to access the type + // MUTABILITY: only for unpickle linkage and caching + mutable entity_il_repr_cache: CompiledTypeRepr cache + + mutable entity_opt_data: EntityOptionalData option + } + + static member NewEmptyEntityOptData() = + { entity_compiled_name = None + entity_other_range = None + entity_kind = TyparKind.Type + entity_xmldoc = XmlDoc.Empty + entity_xmldocsig = "" + entity_tycon_abbrev = None + entity_tycon_repr_accessibility = TAccess [] + entity_accessibility = TAccess [] + entity_exn_info = TExnNone } + + /// The name of the namespace, module or type, possibly with mangling, e.g. List`1, List or FailureException + member x.LogicalName = x.entity_logical_name + + /// The compiled name of the namespace, module or type, e.g. FSharpList`1, ListModule or FailureException + member x.CompiledName = + match x.entity_opt_data with + | Some { entity_compiled_name = Some s } -> s + | _ -> x.LogicalName + + member x.EntityCompiledName = + match x.entity_opt_data with + | Some optData -> optData.entity_compiled_name + | _ -> None + + member x.SetCompiledName name = + match x.entity_opt_data with + | Some optData -> optData.entity_compiled_name <- name + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_compiled_name = name } + + /// The display name of the namespace, module or type, e.g. List instead of List`1, and no static parameters. + /// For modules the Module suffix is removed if FSharpModuleWithSuffix is used. + /// + /// No backticks are added for entities with non-identifier names + member x.DisplayNameCore = x.GetDisplayName(coreName=true) + + /// The display name of the namespace, module or type, e.g. List instead of List`1, and no static parameters + /// For modules the Module suffix is removed if FSharpModuleWithSuffix is used. + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayName = x.GetDisplayName(coreName=false) + + /// The display name of the namespace, module or type with <_, _, _> added for generic types, plus static parameters if any + /// For modules the Module suffix is removed if FSharpModuleWithSuffix is used. + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayNameWithStaticParametersAndUnderscoreTypars = + x.GetDisplayName(coreName=false, withStaticParameters=true, withUnderscoreTypars=true) + + /// The display name of the namespace, module or type, e.g. List instead of List`1, including static parameters if any + /// For modules the Module suffix is removed if FSharpModuleWithSuffix is used. + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayNameWithStaticParameters = + x.GetDisplayName(coreName=false, withStaticParameters=true, withUnderscoreTypars=false) + +#if !NO_EXTENSIONTYPING + member x.IsStaticInstantiationTycon = + x.IsProvidedErasedTycon && + let _nm, args = demangleProvidedTypeName x.LogicalName + args.Length > 0 +#endif + + member x.GetDisplayName(coreName, ?withStaticParameters, ?withUnderscoreTypars) = + let withStaticParameters = defaultArg withStaticParameters false + let withUnderscoreTypars = defaultArg withUnderscoreTypars false + let nm = x.LogicalName + if x.IsModuleOrNamespace then x.DemangledModuleOrNamespaceName +#if !NO_EXTENSIONTYPING + elif x.IsProvidedErasedTycon then + let nm, args = demangleProvidedTypeName nm + if withStaticParameters && args.Length > 0 then + nm + "<" + String.concat "," (Array.map snd args) + ">" + else + nm +#endif + else + ignore withStaticParameters + match x.TyparsNoRange with + | [] -> nm + | tps -> + let nm = DemangleGenericTypeName nm + let isArray = nm.StartsWithOrdinal("[") && nm.EndsWithOrdinal("]") + let nm = if coreName || isArray then nm else ConvertNameToDisplayName nm + if withUnderscoreTypars then + let typarNames = tps |> List.map (fun _ -> "_") + nm + "<" + String.concat "," typarNames + ">" + else + nm + + /// The code location where the module, namespace or type is defined. + member x.Range = +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + | TProvidedTypeRepr info -> + match Construct.ComputeDefinitionLocationOfProvidedItem info.ProvidedType with + | Some range -> range + | None -> x.entity_range + | _ -> +#endif + x.entity_range + + /// The range in the implementation, adjusted for an item in a signature + member x.DefinitionRange = + match x.entity_opt_data with + | Some { entity_other_range = Some (r, true) } -> r + | _ -> x.Range + + member x.SigRange = + match x.entity_opt_data with + | Some { entity_other_range = Some (r, false) } -> r + | _ -> x.Range + + member x.SetOtherRange m = + match x.entity_opt_data with + | Some optData -> optData.entity_other_range <- Some m + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_other_range = Some m } + + /// A unique stamp for this module, namespace or type definition within the context of this compilation. + /// Note that because of signatures, there are situations where in a single compilation the "same" + /// module, namespace or type may have two distinct Entity objects that have distinct stamps. + member x.Stamp = x.entity_stamp + + /// The F#-defined custom attributes of the entity, if any. If the entity is backed by Abstract IL or provided metadata + /// then this does not include any attributes from those sources. + member x.Attribs = x.entity_attribs + + /// The XML documentation of the entity, if any. If the entity is backed by provided metadata + /// then this _does_ include this documentation. If the entity is backed by Abstract IL metadata + /// or comes from another F# assembly then it does not (because the documentation will get read from + /// an XML file). + member x.XmlDoc = +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + | TProvidedTypeRepr info -> + let lines = info.ProvidedType.PUntaintNoFailure(fun st -> (st :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(info.ProvidedType.TypeProvider.PUntaintNoFailure id)) + XmlDoc (lines, x.DefinitionRange) + | _ -> +#endif + match x.entity_opt_data with + | Some optData -> optData.entity_xmldoc + | _ -> XmlDoc.Empty + + /// The XML documentation sig-string of the entity, if any, to use to lookup an .xml doc file. This also acts + /// as a cache for this sig-string computation. + member x.XmlDocSig + with get() = + match x.entity_opt_data with + | Some optData -> optData.entity_xmldocsig + | _ -> "" + and set v = + match x.entity_opt_data with + | Some optData -> optData.entity_xmldocsig <- v + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_xmldocsig = v } + + /// The logical contents of the entity when it is a module or namespace fragment. + member x.ModuleOrNamespaceType = x.entity_modul_contents.Force() + + /// The logical contents of the entity when it is a type definition. + member x.TypeContents = x.entity_tycon_tcaug + + /// The kind of the type definition - is it a measure definition or a type definition? + member x.TypeOrMeasureKind = + match x.entity_opt_data with + | Some optData -> optData.entity_kind + | _ -> TyparKind.Type + + member x.SetTypeOrMeasureKind kind = + match x.entity_opt_data with + | Some optData -> optData.entity_kind <- kind + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_kind = kind } + + /// The identifier at the point of declaration of the type definition. + member x.Id = ident(x.LogicalName, x.Range) + + /// The information about the r.h.s. of a type definition, if any. For example, the r.h.s. of a union or record type. + member x.TypeReprInfo = x.entity_tycon_repr + + /// The information about the r.h.s. of an F# exception definition, if any. + member x.ExceptionInfo = + match x.entity_opt_data with + | Some optData -> optData.entity_exn_info + | _ -> TExnNone + + member x.SetExceptionInfo exn_info = + match x.entity_opt_data with + | Some optData -> optData.entity_exn_info <- exn_info + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_exn_info = exn_info } + + /// Indicates if the entity represents an F# exception declaration. + member x.IsExceptionDecl = match x.ExceptionInfo with TExnNone -> false | _ -> true + + /// Demangle the module name, if FSharpModuleWithSuffix is used + member x.DemangledModuleOrNamespaceName = + CompilationPath.DemangleEntityName x.LogicalName x.ModuleOrNamespaceType.ModuleOrNamespaceKind + + /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. + /// + /// Lazy because it may read metadata, must provide a context "range" in case error occurs reading metadata. + member x.Typars m = x.entity_typars.Force m + + /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. + member x.TyparsNoRange: Typars = x.Typars x.Range + + /// Get the type abbreviated by this type definition, if it is an F# type abbreviation definition + member x.TypeAbbrev = + match x.entity_opt_data with + | Some optData -> optData.entity_tycon_abbrev + | _ -> None + + member x.SetTypeAbbrev tycon_abbrev = + match x.entity_opt_data with + | Some optData -> optData.entity_tycon_abbrev <- tycon_abbrev + | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_tycon_abbrev = tycon_abbrev } + + /// Indicates if this entity is an F# type abbreviation definition + member x.IsTypeAbbrev = x.TypeAbbrev.IsSome + + /// Get the value representing the accessibility of the r.h.s. of an F# type definition. + member x.TypeReprAccessibility = + match x.entity_opt_data with + | Some optData -> optData.entity_tycon_repr_accessibility + | _ -> TAccess [] + + /// Get the cache of the compiled ILTypeRef representation of this module or type. + member x.CompiledReprCache = x.entity_il_repr_cache + + /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. + member x.PublicPath = x.entity_pubpath + + /// Get the value representing the accessibility of an F# type definition or module. + member x.Accessibility = + match x.entity_opt_data with + | Some optData -> optData.entity_accessibility + | _ -> TAccess [] + + /// Indicates the type prefers the "tycon" syntax for display etc. + member x.IsPrefixDisplay = x.entity_flags.IsPrefixDisplay + + /// Indicates the Entity is actually a module or namespace, not a type definition + member x.IsModuleOrNamespace = x.entity_flags.IsModuleOrNamespace + + /// Indicates if the entity is a namespace + member x.IsNamespace = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> true | _ -> false) + + /// Indicates if the entity is an F# module definition + member x.IsModule = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> false | _ -> true) +#if !NO_EXTENSIONTYPING + + /// Indicates if the entity is a provided type or namespace definition + member x.IsProvided = + match x.TypeReprInfo with + | TProvidedTypeRepr _ -> true + | TProvidedNamespaceRepr _ -> true + | _ -> false + + /// Indicates if the entity is a provided namespace fragment + member x.IsProvidedNamespace = + match x.TypeReprInfo with + | TProvidedNamespaceRepr _ -> true + | _ -> false + + /// Indicates if the entity is an erased provided type definition + member x.IsProvidedErasedTycon = + match x.TypeReprInfo with + | TProvidedTypeRepr info -> info.IsErased + | _ -> false + + /// Indicates if the entity is a generated provided type definition, i.e. not erased. + member x.IsProvidedGeneratedTycon = + match x.TypeReprInfo with + | TProvidedTypeRepr info -> info.IsGenerated + | _ -> false +#endif + + /// Indicates if the entity is erased, either a measure definition, or an erased provided type definition + member x.IsErased = + x.IsMeasureableReprTycon +#if !NO_EXTENSIONTYPING + || x.IsProvidedErasedTycon +#endif + + /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. + member x.CompilationPathOpt = x.entity_cpath + + /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. + member x.CompilationPath = + match x.CompilationPathOpt with + | Some cpath -> cpath + | None -> error(Error(FSComp.SR.tastTypeOrModuleNotConcrete(x.LogicalName), x.Range)) + + /// Get a table of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldTable = + match x.TypeReprInfo with + | TFSharpRecdRepr x | TFSharpObjectRepr {fsobjmodel_rfields=x} -> x + | _ -> + match x.ExceptionInfo with + | TExnFresh x -> x + | _ -> + { FieldsByIndex = [| |] + FieldsByName = NameMap.empty } + + /// Get an array of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldsArray = x.AllFieldTable.FieldsByIndex + + /// Get a list of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldsAsList = x.AllFieldsArray |> Array.toList + + /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition. + /// including hidden fields from the compilation of implicit class constructions. + // NOTE: This method doesn't perform particularly well, and is over-used, but doesn't seem to appear on performance traces + member x.AllInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic) + + /// Get a list of all fields for F#-defined record, struct and class fields in this type definition, + /// including static fields, but excluding compiler-generate fields. + member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated) + + /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition, + /// excluding compiler-generate fields. + member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated) + + /// Get a field by index in definition order + member x.GetFieldByIndex n = x.AllFieldTable.FieldByIndex n + + /// Get a field by name. + member x.GetFieldByName n = x.AllFieldTable.FieldByName n + + /// Indicate if this is a type whose r.h.s. is known to be a union type definition. + member x.IsUnionTycon = match x.TypeReprInfo with | TFSharpUnionRepr _ -> true | _ -> false + + /// Get the union cases and other union-type information for a type, if any + member x.UnionTypeInfo = + match x.TypeReprInfo with + | TFSharpUnionRepr x -> ValueSome x + | _ -> ValueNone + + /// Get the union cases for a type, if any + member x.UnionCasesArray = + match x.UnionTypeInfo with + | ValueSome x -> x.CasesTable.CasesByIndex + | ValueNone -> [| |] + + /// Get the union cases for a type, if any, as a list + member x.UnionCasesAsList = x.UnionCasesArray |> Array.toList + + /// Get a union case of a type by name + member x.GetUnionCaseByName n = + match x.UnionTypeInfo with + | ValueSome x -> NameMap.tryFind n x.CasesTable.CasesByName + | ValueNone -> None + + + /// Create a new entity with empty, unlinked data. Only used during unpickling of F# metadata. + static member NewUnlinked() : Entity = + { entity_typars = Unchecked.defaultof<_> + entity_flags = Unchecked.defaultof<_> + entity_stamp = Unchecked.defaultof<_> + entity_logical_name = Unchecked.defaultof<_> + entity_range = Unchecked.defaultof<_> + entity_attribs = Unchecked.defaultof<_> + entity_tycon_repr= Unchecked.defaultof<_> + entity_tycon_tcaug= Unchecked.defaultof<_> + entity_modul_contents= Unchecked.defaultof<_> + entity_pubpath = Unchecked.defaultof<_> + entity_cpath = Unchecked.defaultof<_> + entity_il_repr_cache = Unchecked.defaultof<_> + entity_opt_data = Unchecked.defaultof<_>} + + /// Create a new entity with the given backing data. Only used during unpickling of F# metadata. + static member New _reason (data: Entity) : Entity = data + + /// Link an entity based on empty, unlinked data to the given data. Only used during unpickling of F# metadata. + member x.Link (tg: EntityData) = + x.entity_typars <- tg.entity_typars + x.entity_flags <- tg.entity_flags + x.entity_stamp <- tg.entity_stamp + x.entity_logical_name <- tg.entity_logical_name + x.entity_range <- tg.entity_range + x.entity_attribs <- tg.entity_attribs + x.entity_tycon_repr <- tg.entity_tycon_repr + x.entity_tycon_tcaug <- tg.entity_tycon_tcaug + x.entity_modul_contents <- tg.entity_modul_contents + x.entity_pubpath <- tg.entity_pubpath + x.entity_cpath <- tg.entity_cpath + x.entity_il_repr_cache <- tg.entity_il_repr_cache + match tg.entity_opt_data with + | Some tg -> + x.entity_opt_data <- + Some { entity_compiled_name = tg.entity_compiled_name + entity_other_range = tg.entity_other_range + entity_kind = tg.entity_kind + entity_xmldoc = tg.entity_xmldoc + entity_xmldocsig = tg.entity_xmldocsig + entity_tycon_abbrev = tg.entity_tycon_abbrev + entity_tycon_repr_accessibility = tg.entity_tycon_repr_accessibility + entity_accessibility = tg.entity_accessibility + entity_exn_info = tg.entity_exn_info } + | None -> () + + + /// Indicates if the entity is linked to backing data. Only used during unpickling of F# metadata. + member x.IsLinked = match box x.entity_attribs with null -> false | _ -> true + + /// Get the blob of information associated with an F# object-model type definition, i.e. class, interface, struct etc. + member x.FSharpObjectModelTypeInfo = + match x.TypeReprInfo with + | TFSharpObjectRepr x -> x + | _ -> failwith "not an F# object model type definition" + + /// Indicate if this is a type definition backed by Abstract IL metadata. + member x.IsILTycon = match x.TypeReprInfo with | TILObjectRepr _ -> true | _ -> false + + /// Get the Abstract IL scope, nesting and metadata for this + /// type definition, assuming it is backed by Abstract IL metadata. + member x.ILTyconInfo = match x.TypeReprInfo with | TILObjectRepr data -> data | _ -> failwith "not a .NET type definition" + + /// Get the Abstract IL metadata for this type definition, assuming it is backed by Abstract IL metadata. + member x.ILTyconRawMetadata = let (TILObjectReprData(_, _, td)) = x.ILTyconInfo in td + + /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition. + member x.IsRecordTycon = match x.TypeReprInfo with | TFSharpRecdRepr _ -> true | _ -> false + + /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition that is a value type. + member x.IsStructRecordOrUnionTycon = match x.TypeReprInfo with TFSharpRecdRepr _ | TFSharpUnionRepr _ -> x.entity_flags.IsStructRecordOrUnionType | _ -> false + + /// The on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = x.entity_flags.TryIsByRefLike + + /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.SetIsByRefLike b = x.entity_flags <- x.entity_flags.WithIsByRefLike b + + /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute + member x.TryIsReadOnly = x.entity_flags.TryIsReadOnly + + /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute + member x.SetIsReadOnly b = x.entity_flags <- x.entity_flags.WithIsReadOnly b + + /// These two bits represents the on-demand analysis about whether the entity is assumed to be a readonly struct + member x.TryIsAssumedReadOnly = x.entity_flags.TryIsAssumedReadOnly + + /// Set the on-demand analysis about whether the entity is assumed to be a readonly struct + member x.SetIsAssumedReadOnly b = x.entity_flags <- x.entity_flags.WithIsAssumedReadOnly b + + /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition + member x.IsFSharpObjectModelTycon = match x.TypeReprInfo with | TFSharpObjectRepr _ -> true | _ -> false + + /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll which uses + /// an assembly-code representation for the type, e.g. the primitive array type constructor. + member x.IsAsmReprTycon = match x.TypeReprInfo with | TAsmRepr _ -> true | _ -> false + + /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll like 'float<_>' which + /// defines a measure type with a relation to an existing non-measure type as a representation. + member x.IsMeasureableReprTycon = match x.TypeReprInfo with | TMeasureableRepr _ -> true | _ -> false + + /// Indicates if this is an F# type definition whose r.h.s. definition is unknown (i.e. a traditional ML 'abstract' type in a signature, + /// which in F# is called a 'unknown representation' type). + member x.IsHiddenReprTycon = match x.TypeAbbrev, x.TypeReprInfo with | None, TNoRepr -> true | _ -> false + + /// Indicates if this is an F#-defined interface type definition + member x.IsFSharpInterfaceTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TFSharpInterface -> true | _ -> false + + /// Indicates if this is an F#-defined delegate type definition + member x.IsFSharpDelegateTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TFSharpDelegate _ -> true | _ -> false + + /// Indicates if this is an F#-defined enum type definition + member x.IsFSharpEnumTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TFSharpEnum -> true | _ -> false + + /// Indicates if this is an F#-defined class type definition + member x.IsFSharpClassTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TFSharpClass -> true | _ -> false + + /// Indicates if this is a .NET-defined enum type definition + member x.IsILEnumTycon = x.IsILTycon && x.ILTyconRawMetadata.IsEnum + + /// Indicates if this is an enum type definition + member x.IsEnumTycon = +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + | TProvidedTypeRepr info -> info.IsEnum + | TProvidedNamespaceRepr _ -> false + | _ -> +#endif + x.IsILEnumTycon || x.IsFSharpEnumTycon + + + /// Indicates if this is an F#-defined struct or enum type definition, i.e. a value type definition + member x.IsFSharpStructOrEnumTycon = + match x.TypeReprInfo with + | TFSharpRecdRepr _ -> x.IsStructRecordOrUnionTycon + | TFSharpUnionRepr _ -> x.IsStructRecordOrUnionTycon + | TFSharpObjectRepr info -> + match info.fsobjmodel_kind with + | TFSharpClass | TFSharpInterface | TFSharpDelegate _ -> false + | TFSharpStruct | TFSharpEnum -> true + | _ -> false + + /// Indicates if this is a .NET-defined struct or enum type definition, i.e. a value type definition + member x.IsILStructOrEnumTycon = + x.IsILTycon && + x.ILTyconRawMetadata.IsStructOrEnum + + /// Indicates if this is a struct or enum type definition, i.e. a value type definition + member x.IsStructOrEnumTycon = +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + | TProvidedTypeRepr info -> info.IsStructOrEnum + | TProvidedNamespaceRepr _ -> false + | _ -> +#endif + x.IsILStructOrEnumTycon || x.IsFSharpStructOrEnumTycon + + /// Gets the immediate interface definitions of an F# type definition. Further interfaces may be supported through class and interface inheritance. + member x.ImmediateInterfacesOfFSharpTycon = + x.TypeContents.tcaug_interfaces + + /// Gets the immediate interface types of an F# type definition. Further interfaces may be supported through class and interface inheritance. + member x.ImmediateInterfaceTypesOfFSharpTycon = + x.ImmediateInterfacesOfFSharpTycon |> List.map (fun (x, _, _) -> x) + + /// Gets the immediate members of an F# type definition, excluding compiler-generated ones. + /// Note: result is alphabetically sorted, then for each name the results are in declaration order + member x.MembersOfFSharpTyconSorted = + x.TypeContents.tcaug_adhoc + |> NameMultiMap.rangeReversingEachBucket + |> List.filter (fun v -> not v.IsCompilerGenerated) + + /// Gets all immediate members of an F# type definition keyed by name, including compiler-generated ones. + /// Note: result is a indexed table, and for each name the results are in reverse declaration order + member x.MembersOfFSharpTyconByName = + x.TypeContents.tcaug_adhoc + + /// Gets any implicit hash/equals (with comparer argument) methods added to an F# record, union or struct type definition. + member x.GeneratedHashAndEqualsWithComparerValues = x.TypeContents.tcaug_hash_and_equals_withc + + /// Gets any implicit CompareTo (with comparer argument) methods added to an F# record, union or struct type definition. + member x.GeneratedCompareToWithComparerValues = x.TypeContents.tcaug_compare_withc + + /// Gets any implicit CompareTo methods added to an F# record, union or struct type definition. + member x.GeneratedCompareToValues = x.TypeContents.tcaug_compare + + /// Gets any implicit hash/equals methods added to an F# record, union or struct type definition. + member x.GeneratedHashAndEqualsValues = x.TypeContents.tcaug_equals + + /// Gets all implicit hash/equals/compare methods added to an F# record, union or struct type definition. + member x.AllGeneratedValues = + [ match x.GeneratedCompareToValues with + | None -> () + | Some (v1, v2) -> yield v1; yield v2 + match x.GeneratedCompareToWithComparerValues with + | None -> () + | Some v -> yield v + match x.GeneratedHashAndEqualsValues with + | None -> () + | Some (v1, v2) -> yield v1; yield v2 + match x.GeneratedHashAndEqualsWithComparerValues with + | None -> () + | Some (v1, v2, v3) -> yield v1; yield v2; yield v3 ] + + + /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. + member x.CompiledRepresentation = +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + // We should never be computing this property for erased types + | TProvidedTypeRepr info when info.IsErased -> + failwith "No compiled representation for provided erased type" + + // Generated types that are not relocated just point straight to the generated backing assembly, computed from "st". + // These are used when running F# Interactive, which does not use static linking of provider-generated assemblies, + // and also for types with relocation suppressed. + | TProvidedTypeRepr info when info.IsGenerated && info.IsSuppressRelocate -> + let st = info.ProvidedType + let tref = GetILTypeRefOfProvidedType (st, x.Range) + let boxity = if x.IsStructOrEnumTycon then AsValue else AsObject + CompiledTypeRepr.ILAsmNamed(tref, boxity, None) + | TProvidedNamespaceRepr _ -> failwith "No compiled representation for provided namespace" + | _ -> +#endif + let ilTypeRefForCompilationPath (CompPath(sref, p)) item = + let rec top racc p = + match p with + | [] -> ILTypeRef.Create(sref, [], textOfPath (List.rev (item :: racc))) + | (h, isType) :: t -> + match isType with + | FSharpModuleWithSuffix | ModuleOrType -> + let outerTypeName = (textOfPath (List.rev (h :: racc))) + ILTypeRef.Create(sref, (outerTypeName :: List.map fst t), item) + | _ -> + top (h :: racc) t + top [] p + + + cached x.CompiledReprCache (fun () -> + match x.ExceptionInfo with + | TExnAbbrevRepr ecref2 -> ecref2.CompiledRepresentation + | TExnAsmRepr tref -> CompiledTypeRepr.ILAsmNamed(tref, AsObject, Some (mkILTy AsObject (mkILTySpec (tref, [])))) + | _ -> + match x.TypeReprInfo with + | TAsmRepr ty -> CompiledTypeRepr.ILAsmOpen ty + | _ -> + let boxity = if x.IsStructOrEnumTycon then AsValue else AsObject + let ilTypeRef = + match x.TypeReprInfo with + | TILObjectRepr (TILObjectReprData(ilScopeRef, ilEnclosingTypeDefs, ilTypeDef)) -> mkRefForNestedILTypeDef ilScopeRef (ilEnclosingTypeDefs, ilTypeDef) + | _ -> ilTypeRefForCompilationPath x.CompilationPath x.CompiledName + // Pre-allocate a ILType for monomorphic types, to reduce memory usage from Abstract IL nodes + let ilTypeOpt = + match x.TyparsNoRange with + | [] -> Some (mkILTy boxity (mkILTySpec (ilTypeRef, []))) + | _ -> None + CompiledTypeRepr.ILAsmNamed (ilTypeRef, boxity, ilTypeOpt)) + + /// Gets the data indicating the compiled representation of a named type or module in terms of Abstract IL data structures. + member x.CompiledRepresentationForNamedType = + match x.CompiledRepresentation with + | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> tref + | CompiledTypeRepr.ILAsmOpen _ -> invalidOp (FSComp.SR.tastTypeHasAssemblyCodeRepresentation(x.DisplayNameWithStaticParametersAndUnderscoreTypars)) + + + /// Indicates if we have pre-determined that a type definition has a default constructor. + member x.PreEstablishedHasDefaultConstructor = x.entity_flags.PreEstablishedHasDefaultConstructor + + /// Indicates if we have pre-determined that a type definition has a self-referential constructor using 'as x' + member x.HasSelfReferentialConstructor = x.entity_flags.HasSelfReferentialConstructor + + /// Set the custom attributes on an F# type definition. + member x.SetAttribs attribs = x.entity_attribs <- attribs + + /// Sets the structness of a record or union type definition + member x.SetIsStructRecordOrUnion b = let flags = x.entity_flags in x.entity_flags <- EntityFlags(flags.IsPrefixDisplay, flags.IsModuleOrNamespace, flags.PreEstablishedHasDefaultConstructor, flags.HasSelfReferentialConstructor, b) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.LogicalName + +type EntityData = Entity + +/// Represents the parent entity of a type definition, if any +type ParentRef = + | Parent of parent: EntityRef + | ParentNone + +/// Specifies the compiled representations of type and exception definitions. Basically +/// just an ILTypeRef. Computed and cached by later phases. Stored in +/// type and exception definitions. Not pickled. Store an optional ILType object for +/// non-generic types. +[] +type CompiledTypeRepr = + + /// An AbstractIL type representation that is just the name of a type. + /// + /// CompiledTypeRepr.ILAsmNamed (ilTypeRef, ilBoxity, ilTypeOpt) + /// + /// The ilTypeOpt is present for non-generic types. It is an ILType corresponding to the first two elements of the case. This + /// prevents reallocation of the ILType each time we need to generate it. For generic types, it is None. + | ILAsmNamed of + ilTypeRef: ILTypeRef * + ilBoxity: ILBoxity * + ilTypeOpt: ILType option + + /// An AbstractIL type representation that may include type variables + // This case is only used for types defined in the F# library by their translation to ILASM types, e.g. + // type ``[]``<'T> = (# "!0[]" #) + // type ``[, ]``<'T> = (# "!0[0 ..., 0 ...]" #) + // type ``[, , ]``<'T> = (# "!0[0 ..., 0 ..., 0 ...]" #) + // type byref<'T> = (# "!0&" #) + // type nativeptr<'T when 'T: unmanaged> = (# "native int" #) + // type ilsigptr<'T> = (# "!0*" #) + | ILAsmOpen of ilType: ILType + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "CompiledTypeRepr(...)" + +[] +type TyconAugmentation = + { + /// This is the value implementing the auto-generated comparison + /// semantics if any. It is not present if the type defines its own implementation + /// of IComparable or if the type doesn't implement IComparable implicitly. + mutable tcaug_compare: (ValRef * ValRef) option + + /// This is the value implementing the auto-generated comparison + /// semantics if any. It is not present if the type defines its own implementation + /// of IStructuralComparable or if the type doesn't implement IComparable implicitly. + mutable tcaug_compare_withc: ValRef option + + /// This is the value implementing the auto-generated equality + /// semantics if any. It is not present if the type defines its own implementation + /// of Object.Equals or if the type doesn't override Object.Equals implicitly. + mutable tcaug_equals: (ValRef * ValRef) option + + /// This is the value implementing the auto-generated comparison + /// semantics if any. It is not present if the type defines its own implementation + /// of IStructuralEquatable or if the type doesn't implement IComparable implicitly. + mutable tcaug_hash_and_equals_withc: (ValRef * ValRef * ValRef) option + + /// True if the type defined an Object.GetHashCode method. In this + /// case we give a warning if we auto-generate a hash method since the semantics may not match up + mutable tcaug_hasObjectGetHashCode: bool + + /// Properties, methods etc. in declaration order. The boolean flag for each indicates if the + /// member is known to be an explicit interface implementation. This must be computed and + /// saved prior to remapping assembly information. + tcaug_adhoc_list: ResizeArray + + /// Properties, methods etc. as lookup table + mutable tcaug_adhoc: NameMultiMap + + /// Interface implementations - boolean indicates compiler-generated + mutable tcaug_interfaces: (TType * bool * range) list + + /// Super type, if any + mutable tcaug_super: TType option + + /// Set to true at the end of the scope where proper augmentations are allowed + mutable tcaug_closed: bool + + /// Set to true if the type is determined to be abstract + mutable tcaug_abstract: bool + } + + member tcaug.SetCompare x = tcaug.tcaug_compare <- Some x + + member tcaug.SetCompareWith x = tcaug.tcaug_compare_withc <- Some x + + member tcaug.SetEquals x = tcaug.tcaug_equals <- Some x + + member tcaug.SetHashAndEqualsWith x = tcaug.tcaug_hash_and_equals_withc <- Some x + + member tcaug.SetHasObjectGetHashCode b = tcaug.tcaug_hasObjectGetHashCode <- b + + static member Create() = + { tcaug_compare=None + tcaug_compare_withc=None + tcaug_equals=None + tcaug_hash_and_equals_withc=None + tcaug_hasObjectGetHashCode=false + tcaug_adhoc=NameMultiMap.empty + tcaug_adhoc_list=ResizeArray<_>() + tcaug_super=None + tcaug_interfaces=[] + tcaug_closed=false + tcaug_abstract=false } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "SynTypeDefnKind.Augmentation(...)" + +/// The information for the contents of a type. Also used for a provided namespace. +[] +type TyconRepresentation = + + /// Indicates the type is a class, struct, enum, delegate or interface + | TFSharpObjectRepr of TyconObjModelData + + /// Indicates the type is a record + | TFSharpRecdRepr of TyconRecdFields + + /// Indicates the type is a discriminated union + | TFSharpUnionRepr of TyconUnionData + + /// Indicates the type is a type from a .NET assembly without F# metadata. + | TILObjectRepr of TILObjectReprData + + /// Indicates the type is implemented as IL assembly code using the given closed Abstract IL type + | TAsmRepr of ILType + + /// Indicates the type is parameterized on a measure (e.g. float<_>) but erases to some other type (e.g. float) + | TMeasureableRepr of TType + +#if !NO_EXTENSIONTYPING + /// TProvidedTypeRepr + /// + /// Indicates the representation information for a provided type. + | TProvidedTypeRepr of TProvidedTypeInfo + + /// Indicates the representation information for a provided namespace. + // + // Note, the list could probably be a list of IProvidedNamespace rather than ITypeProvider + | TProvidedNamespaceRepr of ResolutionEnvironment * Tainted list +#endif + + /// The 'NoRepr' value here has four meanings: + /// (1) it indicates 'not yet known' during the first 2 phases of establishing type definitions + /// (2) it indicates 'no representation', i.e. 'type X' in signatures + /// (3) it is the setting used for exception definitions (!) + /// (4) it is the setting used for modules and namespaces. + /// + /// It would be better to separate the "not yet known" and other cases out. + /// The information for exception definitions should be folded into here. + | TNoRepr + + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +[] +type TILObjectReprData = + | TILObjectReprData of scope: ILScopeRef * nesting: ILTypeDef list * definition: ILTypeDef + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TILObjectReprData(...)" + + +#if !NO_EXTENSIONTYPING + +/// The information kept about a provided type +[] +type TProvidedTypeInfo = + { + /// The parameters given to the provider that provided to this type. + ResolutionEnvironment: ExtensionTyping.ResolutionEnvironment + + /// The underlying System.Type (wrapped as a ProvidedType to make sure we don't call random things on + /// System.Type, and wrapped as Tainted to make sure we track which provider this came from, for reporting + /// error messages) + ProvidedType: Tainted + + /// The base type of the type. We use it to compute the compiled representation of the type for erased types. + /// Reading is delayed, since it does an import on the underlying type + LazyBaseType: LazyWithContext + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsClass: bool + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsSealed: bool + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsAbstract: bool + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsInterface: bool + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsStructOrEnum: bool + + /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. + IsEnum: bool + + /// A type read from the provided type and used to compute basic properties of the type definition. + /// Reading is delayed, since it does an import on the underlying type + UnderlyingTypeOfEnum: unit -> TType + + /// A flag read from the provided type and used to compute basic properties of the type definition. + /// Reading is delayed, since it looks at the .BaseType + IsDelegate: unit -> bool + + /// Indicates the type is erased + IsErased: bool + + /// Indicates the type is generated, but type-relocation is suppressed + IsSuppressRelocate: bool + } + + /// Indicates if the provided type is generated, i.e. not erased + member info.IsGenerated = not info.IsErased + + /// Gets the base type of an erased provided type + member info.BaseTypeForErased (m, objTy) = + if info.IsErased then info.LazyBaseType.Force (m, objTy) + else failwith "expect erased type" + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "TProvidedTypeInfo(...)" + +#endif + +type TyconFSharpObjModelKind = + /// Indicates the type is an F#-declared class (also used for units-of-measure) + | TFSharpClass + + /// Indicates the type is an F#-declared interface + | TFSharpInterface + + /// Indicates the type is an F#-declared struct + | TFSharpStruct + + /// Indicates the type is an F#-declared delegate with the given Invoke signature + | TFSharpDelegate of slotSig: SlotSig + + /// Indicates the type is an F#-declared enumeration + | TFSharpEnum + + /// Indicates if the type definition is a value type + member x.IsValueType = + match x with + | TFSharpClass | TFSharpInterface | TFSharpDelegate _ -> false + | TFSharpStruct | TFSharpEnum -> true + +/// Represents member values and class fields relating to the F# object model +[] +type TyconObjModelData = + { + /// Indicates whether the type declaration is an F# class, interface, enum, delegate or struct + fsobjmodel_kind: TyconFSharpObjModelKind + + /// The declared abstract slots of the class, interface or struct + fsobjmodel_vslots: ValRef list + + /// The fields of the class, struct or enum + fsobjmodel_rfields: TyconRecdFields + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TyconObjModelData(...)" + +/// Represents record fields in an F# type definition +[] +type TyconRecdFields = + { + /// The fields of the record, in declaration order. + FieldsByIndex: RecdField[] + + /// The fields of the record, indexed by name. + FieldsByName: NameMap + } + + /// Get a field by index + member x.FieldByIndex n = + if n >= 0 && n < x.FieldsByIndex.Length then x.FieldsByIndex.[n] + else failwith "FieldByIndex" + + /// Get a field by name + member x.FieldByName nm = x.FieldsByName.TryFind nm + + /// Get all the fields as a list + member x.AllFieldsAsList = x.FieldsByIndex |> Array.toList + + /// Get all non-compiler-generated fields as a list + member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated) + + /// Get all non-compiler-generated instance fields as a list + member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TyconRecdFields(...)" + +/// Represents union cases in an F# type definition +[] +type TyconUnionCases = + { + /// The cases of the discriminated union, in declaration order. + CasesByIndex: UnionCase[] + + /// The cases of the discriminated union, indexed by name. + CasesByName: NameMap + } + + /// Get a union case by index + member x.GetUnionCaseByIndex n = + if n >= 0 && n < x.CasesByIndex.Length then x.CasesByIndex.[n] + else invalidArg "n" "GetUnionCaseByIndex" + + /// Get the union cases as a list + member x.UnionCasesAsList = x.CasesByIndex |> Array.toList + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TyconUnionCases(...)" + +/// Represents the union cases and related information in an F# type definition +[] +type TyconUnionData = + { + /// The cases contained in the discriminated union. + CasesTable: TyconUnionCases + + /// The ILX data structure representing the discriminated union. + CompiledRepresentation: IlxUnionRef cache + } + + /// Get the union cases as a list + member x.UnionCasesAsList = x.CasesTable.CasesByIndex |> Array.toList + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TyconUnionData(...)" + +/// Represents a union case in an F# type definition +[] +type UnionCase = + { + /// Data carried by the case. + FieldTable: TyconRecdFields + + /// Return type constructed by the case. Normally exactly the type of the enclosing type, sometimes an abbreviation of it + ReturnType: TType + + /// Documentation for the case + XmlDoc: XmlDoc + + /// XML documentation signature for the case + mutable XmlDocSig: string + + /// Name/range of the case + Id: Ident + + /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is + /// the signature range for an item in an implementation + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable OtherRangeOpt: (range * bool) option + + /// Indicates the declared visibility of the union constructor, not taking signatures into account + Accessibility: Accessibility + + /// Attributes, attached to the generated static method to make instances of the case + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable Attribs: Attribs + } + + /// Get the declaration location of the union case + member uc.Range = uc.Id.idRange + + /// Get the definition location of the union case + member uc.DefinitionRange = + match uc.OtherRangeOpt with + | Some (m, true) -> m + | _ -> uc.Range + + /// Get the signature location of the union case + member uc.SigRange = + match uc.OtherRangeOpt with + | Some (m, false) -> m + | _ -> uc.Range + + /// Get the logical name of the union case + member uc.LogicalName = uc.Id.idText + + /// Get the core of the display name of the union case + /// + /// Backticks and parens are not added for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become [] and :: respectively. + member uc.DisplayNameCore = uc.LogicalName |> DecompileOpName + + /// Get the display name of the union case + /// + /// Backticks and parens are added for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively. + member uc.DisplayName = uc.LogicalName |> ConvertValNameToDisplayName false + + /// Get the name of the case in generated IL code. + /// Note logical names `op_Nil` and `op_ConsCons` become `Empty` and `Cons` respectively. + /// This is because this is how ILX union code gen expects to see them. + member uc.CompiledName = + let idText = uc.Id.idText + if idText = opNameCons then "Cons" + elif idText = opNameNil then "Empty" + else idText + + /// Get the full array of fields of the union case + member uc.RecdFieldsArray = uc.FieldTable.FieldsByIndex + + /// Get the full list of fields of the union case + member uc.RecdFields = uc.FieldTable.FieldsByIndex |> Array.toList + + /// Get a field of the union case by name + member uc.GetFieldByName nm = uc.FieldTable.FieldByName nm + + /// Get a field of the union case by position + member uc.GetFieldByIndex n = uc.FieldTable.FieldByIndex n + + /// Indicates if the union case has no fields + member uc.IsNullary = (uc.FieldTable.FieldsByIndex.Length = 0) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "UnionCase(" + x.LogicalName + ")" + +/// Represents a class, struct or record field in an F# type definition. +/// This may represent a "field" in either a struct, class, record or union. +[] +type RecdField = + { + /// Is the field declared mutable in F#? + rfield_mutable: bool + + /// Documentation for the field + rfield_xmldoc: XmlDoc + + /// XML Documentation signature for the field + mutable rfield_xmldocsig: string + + /// The type of the field, w.r.t. the generic parameters of the enclosing type constructor + rfield_type: TType + + /// Indicates a static field + rfield_static: bool + + /// Indicates a volatile field + rfield_volatile: bool + + /// Indicates a compiler generated field, not visible to Intellisense or name resolution + rfield_secret: bool + + /// The default initialization info, for static literals + rfield_const: Const option + + /// Indicates the declared visibility of the field, not taking signatures into account + rfield_access: Accessibility + + /// Attributes attached to generated property + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable rfield_pattribs: Attribs + + /// Attributes attached to generated field + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable rfield_fattribs: Attribs + + /// Name/declaration-location of the field + rfield_id: Ident + + rfield_name_generated: bool + + /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is + /// the signature range for an item in an implementation + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable rfield_other_range: (range * bool) option } + + /// Indicates the declared visibility of the field, not taking signatures into account + member v.Accessibility = v.rfield_access + + /// Attributes attached to generated property + member v.PropertyAttribs = v.rfield_pattribs + + /// Attributes attached to generated field + member v.FieldAttribs = v.rfield_fattribs + + /// Get the declaration location of the field + member v.Range = v.rfield_id.idRange + + /// Get the definition location of the field + member v.DefinitionRange = + match v.rfield_other_range with + | Some (m, true) -> m + | _ -> v.Range + + /// Get the signature location of the field + member v.SigRange = + match v.rfield_other_range with + | Some (m, false) -> m + | _ -> v.Range + + /// Name/declaration-location of the field + member v.Id = v.rfield_id + + /// Name of the field + member v.LogicalName = v.rfield_id.idText + + /// Name of the field. For fields this is the same as the logical name. + member v.DisplayNameCore = v.LogicalName + + /// Name of the field + member v.DisplayName = v.DisplayNameCore |> ConvertNameToDisplayName + + /// Indicates a compiler generated field, not visible to Intellisense or name resolution + member v.IsCompilerGenerated = v.rfield_secret + + /// Is the field declared mutable in F#? + member v.IsMutable = v.rfield_mutable + + /// Indicates a static field + member v.IsStatic = v.rfield_static + + /// Indicates a volatile field + member v.IsVolatile = v.rfield_volatile + + /// The type of the field, w.r.t. the generic parameters of the enclosing type constructor + member v.FormalType = v.rfield_type + + /// XML Documentation signature for the field + member v.XmlDoc = v.rfield_xmldoc + + /// Get or set the XML documentation signature for the field + member v.XmlDocSig + with get() = v.rfield_xmldocsig + and set x = v.rfield_xmldocsig <- x + + /// The default initialization info, for static literals + member v.LiteralValue = + match v.rfield_const with + | None -> None + | Some Const.Zero -> None + | Some k -> Some k + + /// Indicates if the field is zero-initialized + member v.IsZeroInit = + match v.rfield_const with + | None -> false + | Some Const.Zero -> true + | _ -> false + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.LogicalName + +/// Represents the implementation of an F# exception definition. +[] +type ExceptionInfo = + + /// Indicates that an exception is an abbreviation for the given exception + | TExnAbbrevRepr of TyconRef + + /// Indicates that an exception is shorthand for the given .NET exception type + | TExnAsmRepr of ILTypeRef + + /// Indicates that an exception carries the given record of values + | TExnFresh of TyconRecdFields + + /// Indicates that an exception is abstract, i.e. is in a signature file, and we do not know the representation + | TExnNone + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// Represents the contents of of a module of namespace +[] +type ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, entities: QueueList) = + + /// Mutation used during compilation of FSharp.Core.dll + let mutable entities = entities + + // Lookup tables keyed the way various clients expect them to be keyed. + // We attach them here so we don't need to store lookup tables via any other technique. + // + // The type option ref is used because there are a few functions that treat these as first class values. + // We should probably change to 'mutable'. + // + // We do not need to lock this mutable state this it is only ever accessed from the compiler thread. + let activePatternElemRefCache: NameMap option ref = ref None + + let mutable modulesByDemangledNameCache: NameMap option = None + + let mutable exconsByDemangledNameCache: NameMap option = None + + let mutable tyconsByDemangledNameAndArityCache: LayeredMap option = None + + let mutable tyconsByAccessNamesCache: LayeredMultiMap option = None + + let mutable tyconsByMangledNameCache: NameMap option = None + + let mutable allEntitiesByMangledNameCache: NameMap option = None + + let mutable allValsAndMembersByPartialLinkageKeyCache: MultiMap option = None + + let mutable allValsByLogicalNameCache: NameMap option = None + + /// Namespace or module-compiled-as-type? + member _.ModuleOrNamespaceKind = kind + + /// Values, including members in F# types in this module-or-namespace-fragment. + member _.AllValsAndMembers = vals + + /// Type, mapping mangled name to Tycon, e.g. + //// "Dictionary`2" --> Tycon + //// "ListModule" --> Tycon with module info + //// "FooException" --> Tycon with exception info + member _.AllEntities = entities + + /// Mutation used during compilation of FSharp.Core.dll + member _.AddModuleOrNamespaceByMutation(modul: ModuleOrNamespace) = + entities <- QueueList.appendOne entities modul + modulesByDemangledNameCache <- None + allEntitiesByMangledNameCache <- None + +#if !NO_EXTENSIONTYPING + /// Mutation used in hosting scenarios to hold the hosted types in this module or namespace + member mtyp.AddProvidedTypeEntity(entity: Entity) = + entities <- QueueList.appendOne entities entity + tyconsByMangledNameCache <- None + tyconsByDemangledNameAndArityCache <- None + tyconsByAccessNamesCache <- None + allEntitiesByMangledNameCache <- None +#endif + + /// Return a new module or namespace type with an entity added. + member _.AddEntity(tycon: Tycon) = + ModuleOrNamespaceType(kind, vals, entities.AppendOne tycon) + + /// Return a new module or namespace type with a value added. + member _.AddVal(vspec: Val) = + ModuleOrNamespaceType(kind, vals.AppendOne vspec, entities) + + /// Get a table of the active patterns defined in this module. + member _.ActivePatternElemRefLookupTable = activePatternElemRefCache + + /// Get a list of types defined within this module, namespace or type. + member _.TypeDefinitions = entities |> Seq.filter (fun x -> not x.IsExceptionDecl && not x.IsModuleOrNamespace) |> Seq.toList + + /// Get a list of F# exception definitions defined within this module, namespace or type. + member _.ExceptionDefinitions = entities |> Seq.filter (fun x -> x.IsExceptionDecl) |> Seq.toList + + /// Get a list of module and namespace definitions defined within this module, namespace or type. + member _.ModuleAndNamespaceDefinitions = entities |> Seq.filter (fun x -> x.IsModuleOrNamespace) |> Seq.toList + + /// Get a list of type and exception definitions defined within this module, namespace or type. + member _.TypeAndExceptionDefinitions = entities |> Seq.filter (fun x -> not x.IsModuleOrNamespace) |> Seq.toList + + /// Get a table of types defined within this module, namespace or type. The + /// table is indexed by both name and generic arity. This means that for generic + /// types "List`1", the entry (List, 1) will be present. + member mtyp.TypesByDemangledNameAndArity = + cacheOptByref &tyconsByDemangledNameAndArityCache (fun () -> + LayeredMap.Empty.AddAndMarkAsCollapsible( mtyp.TypeAndExceptionDefinitions |> List.map (fun (tc: Tycon) -> Construct.KeyTyconByDecodedName tc.LogicalName tc) |> List.toArray)) + + /// Get a table of types defined within this module, namespace or type. The + /// table is indexed by both name and, for generic types, also by mangled name. + member mtyp.TypesByAccessNames = + cacheOptByref &tyconsByAccessNamesCache (fun () -> + LayeredMultiMap.Empty.AddAndMarkAsCollapsible (mtyp.TypeAndExceptionDefinitions |> List.toArray |> Array.collect (fun (tc: Tycon) -> Construct.KeyTyconByAccessNames tc.LogicalName tc))) + + // REVIEW: we can remove this lookup and use AllEntitiesByMangledName instead? + member mtyp.TypesByMangledName = + let addTyconByMangledName (x: Tycon) tab = NameMap.add x.LogicalName x tab + cacheOptByref &tyconsByMangledNameCache (fun () -> + List.foldBack addTyconByMangledName mtyp.TypeAndExceptionDefinitions Map.empty) + + /// Get a table of entities indexed by both logical and compiled names + member _.AllEntitiesByCompiledAndLogicalMangledNames: NameMap = + let addEntityByMangledName (x: Entity) tab = + let name1 = x.LogicalName + let name2 = x.CompiledName + let tab = NameMap.add name1 x tab + if name1 = name2 then tab + else NameMap.add name2 x tab + + cacheOptByref &allEntitiesByMangledNameCache (fun () -> + QueueList.foldBack addEntityByMangledName entities Map.empty) + + /// Get a table of entities indexed by both logical name + member _.AllEntitiesByLogicalMangledName: NameMap = + let addEntityByMangledName (x: Entity) tab = NameMap.add x.LogicalName x tab + QueueList.foldBack addEntityByMangledName entities Map.empty + + /// Get a table of values and members indexed by partial linkage key, which includes name, the mangled name of the parent type (if any), + /// and the method argument count (if any). + member _.AllValsAndMembersByPartialLinkageKey = + let addValByMangledName (x: Val) tab = + if x.IsCompiledAsTopLevel then + let key = x.GetLinkagePartialKey() + MultiMap.add key x tab + else + tab + cacheOptByref &allValsAndMembersByPartialLinkageKeyCache (fun () -> + QueueList.foldBack addValByMangledName vals MultiMap.empty) + + /// Try to find the member with the given linkage key in the given module. + member mtyp.TryLinkVal(ccu: CcuThunk, key: ValLinkageFullKey) = + mtyp.AllValsAndMembersByPartialLinkageKey + |> MultiMap.find key.PartialKey + |> List.tryFind (fun v -> match key.TypeForLinkage with + | None -> true + | Some keyTy -> ccu.MemberSignatureEquality(keyTy, v.Type)) + |> ValueOptionInternal.ofOption + + /// Get a table of values indexed by logical name + member _.AllValsByLogicalName = + let addValByName (x: Val) tab = + // Note: names may occur twice prior to raising errors about this in PostTypeCheckSemanticChecks + // Earlier ones take precedence since we report errors about the later ones + if not x.IsMember && not x.IsCompilerGenerated then + NameMap.add x.LogicalName x tab + else + tab + cacheOptByref &allValsByLogicalNameCache (fun () -> + QueueList.foldBack addValByName vals Map.empty) + + /// Compute a table of values and members indexed by logical name. + member _.AllValsAndMembersByLogicalNameUncached = + let addValByName (x: Val) tab = + if not x.IsCompilerGenerated then + MultiMap.add x.LogicalName x tab + else + tab + QueueList.foldBack addValByName vals MultiMap.empty + + /// Get a table of F# exception definitions indexed by demangled name, so 'FailureException' is indexed by 'Failure' + member mtyp.ExceptionDefinitionsByDemangledName = + let add (tycon: Tycon) acc = NameMap.add tycon.LogicalName tycon acc + cacheOptByref &exconsByDemangledNameCache (fun () -> + List.foldBack add mtyp.ExceptionDefinitions Map.empty) + + /// Get a table of nested module and namespace fragments indexed by demangled name (so 'ListModule' becomes 'List') + member _.ModulesAndNamespacesByDemangledName = + let add (entity: Entity) acc = + if entity.IsModuleOrNamespace then + NameMap.add entity.DemangledModuleOrNamespaceName entity acc + else acc + cacheOptByref &modulesByDemangledNameCache (fun () -> + QueueList.foldBack add entities Map.empty) + + [] + member mtyp.DebugText = mtyp.ToString() + + override _.ToString() = "ModuleOrNamespaceType(...)" + +/// Represents a module or namespace definition in the typed AST +type ModuleOrNamespace = Entity + +/// Represents a type or exception definition in the typed AST +type Tycon = Entity + +/// Represents the constraint on access for a construct +[] +type Accessibility = + + /// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope. + | TAccess of compilationPaths: CompilationPath list + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "Accessibility(...)" + +/// Represents less-frequently-required data about a type parameter of type inference variable +[] +type TyparOptionalData = + { + /// MUTABILITY: we set the names of generalized inference type parameters to make the look nice for IL code generation + /// The storage for the IL name for the type parameter. + mutable typar_il_name: string option + + /// The documentation for the type parameter. Empty for inference variables. + /// MUTABILITY: for linking when unpickling + mutable typar_xmldoc: XmlDoc + + /// The inferred constraints for the type parameter or inference variable. + mutable typar_constraints: TyparConstraint list + + /// The declared attributes of the type parameter. Empty for type inference variables. + mutable typar_attribs: Attribs + } + + [] + member x.DebugText = x.ToString() + + override _.ToString() = sprintf "TyparOptionalData(...)" + +type TyparData = Typar + +/// A declared generic type/measure parameter, or a type/measure inference variable. +[] +type Typar = + { + /// MUTABILITY: we set the names of generalized inference type parameters to make the look nice for IL code generation + /// The identifier for the type parameter + mutable typar_id: Ident + + /// The flag data for the type parameter + mutable typar_flags: TyparFlags + + /// The unique stamp of the type parameter + /// MUTABILITY: for linking when unpickling + mutable typar_stamp: Stamp + + /// An inferred equivalence for a type inference variable. + mutable typar_solution: TType option + + /// A cached TAST type used when this type variable is used as type. + mutable typar_astype: TType + + /// The optional data for the type parameter + mutable typar_opt_data: TyparOptionalData option + } + + /// The name of the type parameter + member x.Name = x.typar_id.idText + + /// The range of the identifier for the type parameter definition + member x.Range = x.typar_id.idRange + + /// The identifier for a type parameter definition + member x.Id = x.typar_id + + /// The unique stamp of the type parameter + member x.Stamp = x.typar_stamp + + /// The inferred equivalence for the type inference variable, if any. + member x.Solution = x.typar_solution + + /// The inferred constraints for the type inference variable, if any + member x.Constraints = + match x.typar_opt_data with + | Some optData -> optData.typar_constraints + | _ -> [] + + /// Indicates if the type variable is compiler generated, i.e. is an implicit type inference variable + member x.IsCompilerGenerated = x.typar_flags.IsCompilerGenerated + + /// Indicates if the type variable can be solved or given new constraints. The status of a type variable + /// generally always evolves towards being either rigid or solved. + member x.Rigidity = x.typar_flags.Rigidity + + /// Indicates if a type parameter is needed at runtime and may not be eliminated + member x.DynamicReq = x.typar_flags.DynamicReq + + /// Indicates that whether or not a generic type definition satisfies the equality constraint is dependent on whether this type variable satisfies the equality constraint. + member x.EqualityConditionalOn = x.typar_flags.EqualityConditionalOn + + /// Indicates that whether or not a generic type definition satisfies the comparison constraint is dependent on whether this type variable satisfies the comparison constraint. + member x.ComparisonConditionalOn = x.typar_flags.ComparisonConditionalOn + + /// Indicates if the type variable has a static "head type" requirement, i.e. ^a variables used in FSharp.Core and member constraints. + member x.StaticReq = x.typar_flags.StaticReq + + /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns + member x.IsFromError = x.typar_flags.IsFromError + + /// Indicates that whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) + member x.IsCompatFlex = x.typar_flags.IsCompatFlex + + /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) + member x.SetIsCompatFlex b = x.typar_flags <- x.typar_flags.WithCompatFlex b + + /// Indicates whether a type variable can be instantiated by types or units-of-measure. + member x.Kind = x.typar_flags.Kind + + /// Indicates whether a type variable is erased in compiled .NET IL code, i.e. whether it is a unit-of-measure variable + member x.IsErased = match x.Kind with TyparKind.Type -> false | _ -> true + + /// The declared attributes of the type parameter. Empty for type inference variables and parameters from .NET. + member x.Attribs = + match x.typar_opt_data with + | Some optData -> optData.typar_attribs + | _ -> [] + + /// Set the attributes on the type parameter + member x.SetAttribs attribs = + match attribs, x.typar_opt_data with + | [], None -> () + | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_constraints = [] } when doc.IsEmpty -> + x.typar_opt_data <- None + | _, Some optData -> optData.typar_attribs <- attribs + | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } + + /// Get the XML documetnation for the type parameter + member x.XmlDoc = + match x.typar_opt_data with + | Some optData -> optData.typar_xmldoc + | _ -> XmlDoc.Empty + + /// Get the IL name of the type parameter + member x.ILName = + match x.typar_opt_data with + | Some optData -> optData.typar_il_name + | _ -> None + + /// Set the IL name of the type parameter + member x.SetILName il_name = + match x.typar_opt_data with + | Some optData -> optData.typar_il_name <- il_name + | _ -> x.typar_opt_data <- Some { typar_il_name = il_name; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = [] } + + /// Indicates the display name of a type variable + member x.DisplayName = if x.Name = "?" then "?"+string x.Stamp else x.Name + + /// Adjusts the constraints associated with a type variable + member x.SetConstraints cs = + match cs, x.typar_opt_data with + | [], None -> () + | [], Some { typar_il_name = None; typar_xmldoc = doc; typar_attribs = [] } when doc.IsEmpty -> + x.typar_opt_data <- None + | _, Some optData -> optData.typar_constraints <- cs + | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = cs; typar_attribs = [] } + + /// Creates a type variable that contains empty data, and is not yet linked. Only used during unpickling of F# metadata. + static member NewUnlinked() : Typar = + { typar_id = Unchecked.defaultof<_> + typar_flags = Unchecked.defaultof<_> + typar_stamp = -1L + typar_solution = Unchecked.defaultof<_> + typar_astype = Unchecked.defaultof<_> + typar_opt_data = Unchecked.defaultof<_> } + + /// Creates a type variable based on the given data. Only used during unpickling of F# metadata. + static member New (data: TyparData) : Typar = data + + /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. + member x.Link (tg: TyparData) = + x.typar_id <- tg.typar_id + x.typar_flags <- tg.typar_flags + x.typar_stamp <- tg.typar_stamp + x.typar_solution <- tg.typar_solution + match tg.typar_opt_data with + | Some tg -> + let optData = { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs } + x.typar_opt_data <- Some optData + | None -> () + + /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. + member x.AsType = + let ty = x.typar_astype + match box ty with + | null -> + let ty2 = TType_var x + x.typar_astype <- ty2 + ty2 + | _ -> ty + + /// Indicates if a type variable has been linked. Only used during unpickling of F# metadata. + member x.IsLinked = x.typar_stamp <> -1L + + /// Indicates if a type variable has been solved. + member x.IsSolved = + match x.Solution with + | None -> false + | _ -> true + + /// Sets the identifier associated with a type variable + member x.SetIdent id = x.typar_id <- id + + /// Sets the rigidity of a type variable + member x.SetRigidity b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + + /// Sets whether a type variable is compiler generated + member x.SetCompilerGenerated b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + + /// Sets whether a type variable has a static requirement + member x.SetStaticReq b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, b, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + + /// Sets whether a type variable is required at runtime + member x.SetDynamicReq b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + + /// Sets whether the equality constraint of a type definition depends on this type variable + member x.SetEqualityDependsOn b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn) + + /// Sets whether the comparison constraint of a type definition depends on this type variable + member x.SetComparisonDependsOn b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.Name + +/// Represents a constraint on a type parameter or type +[] +type TyparConstraint = + + /// A constraint that a type is a subtype of the given type + | CoercesTo of ty: TType * range: range + + /// A constraint for a default value for an inference type variable should it be neither generalized nor solved + | DefaultsTo of priority: int * ty: TType * range: range + + /// A constraint that a type has a 'null' value + | SupportsNull of range: range + + /// A constraint that a type has a member with the given signature + | MayResolveMember of constraintInfo: TraitConstraintInfo * range: range + + /// A constraint that a type is a non-Nullable value type + /// These are part of .NET's model of generic constraints, and in order to + /// generate verifiable code we must attach them to F# generalized type variables as well. + | IsNonNullableStruct of range: range + + /// A constraint that a type is a reference type + | IsReferenceType of range: range + + /// A constraint that a type is a simple choice between one of the given ground types. Only arises from 'printf' format strings. See format.fs + | SimpleChoice of tys: TTypes * range: range + + /// A constraint that a type has a parameterless constructor + | RequiresDefaultConstructor of range: range + + /// A constraint that a type is an enum with the given underlying + | IsEnum of ty: TType * range: range + + /// A constraint that a type implements IComparable, with special rules for some known structural container types + | SupportsComparison of range: range + + /// A constraint that a type does not have the Equality(false) attribute, or is not a structural type with this attribute, with special rules for some known structural container types + | SupportsEquality of range: range + + /// A constraint that a type is a delegate from the given tuple of args to the given return type + | IsDelegate of aty: TType * bty: TType * range: range + + /// A constraint that a type is .NET unmanaged type + | IsUnmanaged of range: range + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +[] +type TraitWitnessInfo = + | TraitWitnessInfo of TTypes * string * SynMemberFlags * TTypes * TType option + + /// Get the member name associated with the member constraint. + member x.MemberName = (let (TraitWitnessInfo(_, b, _, _, _)) = x in b) + + /// Get the return type recorded in the member constraint. + member x.ReturnType = (let (TraitWitnessInfo(_, _, _, _, ty)) = x in ty) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TTrait(" + x.MemberName + ")" + +/// The specification of a member constraint that must be solved +[] +type TraitConstraintInfo = + + /// Indicates the signature of a member constraint. Contains a mutable solution cell + /// to store the inferred solution of the constraint. + | TTrait of tys: TTypes * memberName: string * _memFlags: SynMemberFlags * argTys: TTypes * returnTy: TType option * solution: TraitConstraintSln option ref + + /// Get the key associated with the member constraint. + member x.TraitKey = (let (TTrait(a, b, c, d, e, _)) = x in TraitWitnessInfo(a, b, c, d, e)) + + /// Get the member name associated with the member constraint. + member x.MemberName = (let (TTrait(_, nm, _, _, _, _)) = x in nm) + + /// Get the member flags associated with the member constraint. + member x.MemberFlags = (let (TTrait(_, _, flags, _, _, _)) = x in flags) + + /// Get the argument types recorded in the member constraint. This includes the object instance type for + /// instance members. + member x.ArgumentTypes = (let (TTrait(_, _, _, argtys, _, _)) = x in argtys) + + /// Get the return type recorded in the member constraint. + member x.ReturnType = (let (TTrait(_, _, _, _, ty, _)) = x in ty) + + /// Get or set the solution of the member constraint during inference + member x.Solution + with get() = (let (TTrait(_, _, _, _, _, sln)) = x in sln.Value) + and set v = (let (TTrait(_, _, _, _, _, sln)) = x in sln.Value <- v) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TTrait(" + x.MemberName + ")" + +/// Represents the solution of a member constraint during inference. +[] +type TraitConstraintSln = + + /// FSMethSln(ty, vref, minst) + /// + /// Indicates a trait is solved by an F# method. + /// ty -- the type and its instantiation + /// vref -- the method that solves the trait constraint + /// minst -- the generic method instantiation + | FSMethSln of ty: TType * vref: ValRef * minst: TypeInst + + /// FSRecdFieldSln(tinst, rfref, isSetProp) + /// + /// Indicates a trait is solved by an F# record field. + /// tinst -- the instantiation of the declaring type + /// rfref -- the reference to the record field + /// isSetProp -- indicates if this is a set of a record field + | FSRecdFieldSln of tinst: TypeInst * rfref: RecdFieldRef * isSetProp: bool + + /// Indicates a trait is solved by an F# anonymous record field. + | FSAnonRecdFieldSln of anonInfo: AnonRecdTypeInfo * tinst: TypeInst * index: int + + /// ILMethSln(ty, extOpt, ilMethodRef, minst) + /// + /// Indicates a trait is solved by a .NET method. + /// ty -- the type and its instantiation + /// extOpt -- information about an extension member, if any + /// ilMethodRef -- the method that solves the trait constraint + /// minst -- the generic method instantiation + | ILMethSln of ty: TType * extOpt: ILTypeRef option * ilMethodRef: ILMethodRef * minst: TypeInst + + /// ClosedExprSln expr + /// + /// Indicates a trait is solved by an erased provided expression + | ClosedExprSln of expr: Expr + + /// Indicates a trait is solved by a 'fake' instance of an operator, like '+' on integers + | BuiltInSln + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// The partial information used to index the methods of all those in a ModuleOrNamespace. +[] +type ValLinkagePartialKey = + { + /// The name of the type with which the member is associated. None for non-member values. + MemberParentMangledName: string option + + /// Indicates if the member is an override. + MemberIsOverride: bool + + /// Indicates the logical name of the member. + LogicalName: string + + /// Indicates the total argument count of the member. + TotalArgCount: int + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "ValLinkagePartialKey(" + x.LogicalName + ")" + +/// The full information used to identify a specific overloaded method +/// amongst all those in a ModuleOrNamespace. +[] +type ValLinkageFullKey(partialKey: ValLinkagePartialKey, typeForLinkage: TType option) = + + /// The partial information used to index the value in a ModuleOrNamespace. + member x.PartialKey = partialKey + + /// The full type of the value for the purposes of linking. May be None for non-members, since they can't be overloaded. + member x.TypeForLinkage = typeForLinkage + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "ValLinkageFullKey(" + partialKey.LogicalName + ")" + +[] +type ValOptionalData = + { + /// MUTABILITY: for unpickle linkage + mutable val_compiled_name: string option + + /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is + /// the signature range for an item in an implementation + mutable val_other_range: (range * bool) option + + mutable val_const: Const option + + /// What is the original, unoptimized, closed-term definition, if any? + /// Used to implement [] + mutable val_defn: Expr option + + // MUTABILITY CLEANUP: mutability of this field is used by + // -- adjustAllUsesOfRecValue + // -- TLR optimizations + // -- LinearizeTopMatch + // + // For example, we use mutability to replace the empty arity initially assumed with an arity garnered from the + // type-checked expression. + mutable val_repr_info: ValReprInfo option + + /// How visible is this? + /// MUTABILITY: for unpickle linkage + mutable val_access: Accessibility + + /// XML documentation attached to a value. + /// MUTABILITY: for unpickle linkage + mutable val_xmldoc: XmlDoc + + /// Is the value actually an instance method/property/event that augments + /// a type, and if so what name does it take in the IL? + /// MUTABILITY: for unpickle linkage + mutable val_member_info: ValMemberInfo option + + // MUTABILITY CLEANUP: mutability of this field is used by + // -- LinearizeTopMatch + // + // The fresh temporary should just be created with the right parent + mutable val_declaring_entity: ParentRef + + /// XML documentation signature for the value + mutable val_xmldocsig: string + + /// Custom attributes attached to the value. These contain references to other values (i.e. constructors in types). Mutable to fixup + /// these value references after copying a collection of values. + mutable val_attribs: Attribs + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "ValOptionalData(...)" + +type ValData = Val + +[] +type Val = + { + /// Mutable for unpickle linkage + mutable val_logical_name: string + + /// Mutable for unpickle linkage + mutable val_range: range + + mutable val_type: TType + + /// Mutable for unpickle linkage + mutable val_stamp: Stamp + + /// See vflags section further below for encoding/decodings here + mutable val_flags: ValFlags + + mutable val_opt_data: ValOptionalData option } + + static member NewEmptyValOptData() = + { val_compiled_name = None + val_other_range = None + val_const = None + val_defn = None + val_repr_info = None + val_access = TAccess [] + val_xmldoc = XmlDoc.Empty + val_member_info = None + val_declaring_entity = ParentNone + val_xmldocsig = String.Empty + val_attribs = [] } + + /// Range of the definition (implementation) of the value, used by Visual Studio + member x.DefinitionRange = + match x.val_opt_data with + | Some { val_other_range = Some(m, true) } -> m + | _ -> x.val_range + + /// Range of the definition (signature) of the value, used by Visual Studio + member x.SigRange = + match x.val_opt_data with + | Some { val_other_range = Some(m, false) } -> m + | _ -> x.val_range + + /// The place where the value was defined. + member x.Range = x.val_range + + /// A unique stamp within the context of this invocation of the compiler process + member x.Stamp = x.val_stamp + + /// The type of the value. + /// May be a TType_forall for a generic value. + /// May be a type variable or type containing type variables during type inference. + // + // Note: this data is mutated during inference by adjustAllUsesOfRecValue when we replace the inferred type with a schema. + member x.Type = x.val_type + + /// How visible is this value, function or member? + member x.Accessibility = + match x.val_opt_data with + | Some optData -> optData.val_access + | _ -> TAccess [] + + /// The value of a value or member marked with [] + member x.LiteralValue = + match x.val_opt_data with + | Some optData -> optData.val_const + | _ -> None + + /// Records the "extra information" for a value compiled as a method. + /// + /// This indicates the number of arguments in each position for a curried + /// functions, and relates to the F# spec for arity analysis. + /// For module-defined values, the currying is based + /// on the number of lambdas, and in each position the elements are + /// based on attempting to deconstruct the type of the argument as a + /// tuple-type. + /// + /// The field is mutable because arities for recursive + /// values are only inferred after the r.h.s. is analyzed, but the + /// value itself is created before the r.h.s. is analyzed. + /// + /// TLR also sets this for inner bindings that it wants to + /// represent as "top level" bindings. + member x.ValReprInfo: ValReprInfo option = + match x.val_opt_data with + | Some optData -> optData.val_repr_info + | _ -> None + + member x.Id = ident(x.LogicalName, x.Range) + + /// Is this represented as a "top level" static binding (i.e. a static field, static member, + /// instance member), rather than an "inner" binding that may result in a closure. + /// + /// This is implied by IsMemberOrModuleBinding, however not vice versa, for two reasons. + /// Some optimizations mutate this value when they decide to change the representation of a + /// binding to be IsCompiledAsTopLevel. Second, even immediately after type checking we expect + /// some non-module, non-member bindings to be marked IsCompiledAsTopLevel, e.g. 'y' in + /// 'let x = let y = 1 in y + y' (NOTE: check this, don't take it as gospel) + member x.IsCompiledAsTopLevel = x.ValReprInfo.IsSome + + /// The partial information used to index the methods of all those in a ModuleOrNamespace. + member x.GetLinkagePartialKey() : ValLinkagePartialKey = + assert x.IsCompiledAsTopLevel + { LogicalName = x.LogicalName + MemberParentMangledName = (if x.IsMember then Some x.MemberApparentEntity.LogicalName else None) + MemberIsOverride = x.IsOverrideOrExplicitImpl + TotalArgCount = if x.IsMember then x.ValReprInfo.Value.TotalArgCount else 0 } + + /// The full information used to identify a specific overloaded method amongst all those in a ModuleOrNamespace. + member x.GetLinkageFullKey() : ValLinkageFullKey = + assert x.IsCompiledAsTopLevel + let key = x.GetLinkagePartialKey() + ValLinkageFullKey(key, (if x.IsMember then Some x.Type else None)) + + /// Is this a member definition or module definition? + member x.IsMemberOrModuleBinding = x.val_flags.IsMemberOrModuleBinding + + /// Indicates if this is an F#-defined extension member + member x.IsExtensionMember = x.val_flags.IsExtensionMember + + /// The quotation expression associated with a value given the [] tag + member x.ReflectedDefinition = + match x.val_opt_data with + | Some optData -> optData.val_defn + | _ -> None + + /// Is this a member, if so some more data about the member. + /// + /// Note, the value may still be (a) an extension member or (b) and abstract slot without + /// a true body. These cases are often causes of bugs in the compiler. + member x.MemberInfo = + match x.val_opt_data with + | Some optData -> optData.val_member_info + | _ -> None + + /// Indicates if this is a member + member x.IsMember = x.MemberInfo.IsSome + + /// Indicates if this is a member, excluding extension members + member x.IsIntrinsicMember = x.IsMember && not x.IsExtensionMember + + /// Indicates if this is an F#-defined value in a module, or an extension member, but excluding compiler generated bindings from optimizations + member x.IsModuleBinding = x.IsMemberOrModuleBinding && not x.IsMember + + /// Indicates if this is something compiled into a module, i.e. a user-defined value, an extension member or a compiler-generated value + member x.IsCompiledIntoModule = x.IsExtensionMember || x.IsModuleBinding + + /// Indicates if this is an F#-defined instance member. + /// + /// Note, the value may still be (a) an extension member or (b) and abstract slot without + /// a true body. These cases are often causes of bugs in the compiler. + member x.IsInstanceMember = x.IsMember && x.MemberInfo.Value.MemberFlags.IsInstance + + /// Indicates if this is an F#-defined 'new' constructor member + member x.IsConstructor = + match x.MemberInfo with + | Some memberInfo when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) -> true + | _ -> false + + /// Indicates if this is a compiler-generated class constructor member + member x.IsClassConstructor = + match x.MemberInfo with + | Some memberInfo when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = SynMemberKind.ClassConstructor) -> true + | _ -> false + + /// Indicates if this value was a member declared 'override' or an implementation of an interface slot + member x.IsOverrideOrExplicitImpl = + match x.MemberInfo with + | Some memberInfo when memberInfo.MemberFlags.IsOverrideOrExplicitImpl -> true + | _ -> false + + /// Indicates if this is declared 'mutable' + member x.IsMutable = (match x.val_flags.MutabilityInfo with Immutable -> false | Mutable -> true) + + /// Indicates if this is inferred to be a method or function that definitely makes no critical tailcalls? + member x.MakesNoCriticalTailcalls = x.val_flags.MakesNoCriticalTailcalls + + /// Indicates if this is ever referenced? + member x.HasBeenReferenced = x.val_flags.HasBeenReferenced + + /// Indicates if the backing field for a static value is suppressed. + member x.IsCompiledAsStaticPropertyWithoutField = + let hasValueAsStaticProperty = x.Attribs |> List.exists(fun (Attrib(tc, _, _, _, _, _, _)) -> tc.CompiledName = "ValueAsStaticPropertyAttribute") + x.val_flags.IsCompiledAsStaticPropertyWithoutField || hasValueAsStaticProperty + + /// Indicates if the value is pinned/fixed + member x.IsFixed = x.val_flags.IsFixed + + /// Indicates if the value will ignore byref scoping rules + member x.IgnoresByrefScope = x.val_flags.IgnoresByrefScope + + /// Indicates if this value allows the use of an explicit type instantiation (i.e. does it itself have explicit type arguments, + /// or does it have a signature?) + member x.PermitsExplicitTypeInstantiation = x.val_flags.PermitsExplicitTypeInstantiation + + /// Indicates if this is a member generated from the de-sugaring of 'let' function bindings in the implicit class syntax? + member x.IsIncrClassGeneratedMember = x.IsCompilerGenerated && x.val_flags.IsIncrClassSpecialMember + + /// Indicates if this is a constructor member generated from the de-sugaring of implicit constructor for a class type? + member x.IsIncrClassConstructor = x.IsConstructor && x.val_flags.IsIncrClassSpecialMember + + /// Get the information about the value used during type inference + member x.RecursiveValInfo = x.val_flags.RecursiveValInfo + + /// Indicates if this is a 'base' or 'this' value? + member x.BaseOrThisInfo = x.val_flags.BaseOrThisInfo + + /// Indicates if this is a 'this' value for an implicit ctor? + member x.IsCtorThisVal = (x.BaseOrThisInfo = CtorThisVal) + + /// Indicates if this is a 'this' value for a member? + member x.IsMemberThisVal = (x.BaseOrThisInfo = MemberThisVal) + + /// Indicates if this is a 'base' value? + member x.IsBaseVal = (x.BaseOrThisInfo = BaseVal) + + // Indicates if this value was declared to be a type function, e.g. "let f<'a> = typeof<'a>" + member x.IsTypeFunction = x.val_flags.IsTypeFunction + + /// Get the inline declaration on the value + member x.InlineInfo = x.val_flags.InlineInfo + + /// Get the inline declaration on a parameter or other non-function-declaration value, used for optimization + member x.InlineIfLambda = x.val_flags.InlineIfLambda + + /// Indicates whether the inline declaration for the value indicate that the value must be inlined? + member x.MustInline = x.InlineInfo.MustInline + + /// Indicates whether this value was generated by the compiler. + /// + /// Note: this is true for the overrides generated by hash/compare augmentations + member x.IsCompilerGenerated = x.val_flags.IsCompilerGenerated + + /// Get the declared attributes for the value + member x.Attribs = + match x.val_opt_data with + | Some optData -> optData.val_attribs + | _ -> [] + + /// Get the declared documentation for the value + member x.XmlDoc = + match x.val_opt_data with + | Some optData -> optData.val_xmldoc + | _ -> XmlDoc.Empty + + ///Get the signature for the value's XML documentation + member x.XmlDocSig + with get() = + match x.val_opt_data with + | Some optData -> optData.val_xmldocsig + | _ -> String.Empty + and set v = + match x.val_opt_data with + | Some optData -> optData.val_xmldocsig <- v + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_xmldocsig = v } + + /// The parent type or module, if any (None for expression bindings and parameters) + member x.DeclaringEntity = + match x.val_opt_data with + | Some optData -> optData.val_declaring_entity + | _ -> ParentNone + + /// Get the actual parent entity for the value (a module or a type), i.e. the entity under which the + /// value will appear in compiled code. For extension members this is the module where the extension member + /// is declared. + member x.TopValDeclaringEntity = + match x.DeclaringEntity with + | Parent tcref -> tcref + | ParentNone -> error(InternalError("TopValDeclaringEntity: does not have a parent", x.Range)) + + member x.HasDeclaringEntity = + match x.DeclaringEntity with + | Parent _ -> true + | ParentNone -> false + + /// Get the apparent parent entity for a member + member x.MemberApparentEntity: TyconRef = + match x.MemberInfo with + | Some membInfo -> membInfo.ApparentEnclosingEntity + | None -> error(InternalError("MemberApparentEntity", x.Range)) + + /// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'. + member v.NumObjArgs = + match v.MemberInfo with + | Some membInfo -> if membInfo.MemberFlags.IsInstance then 1 else 0 + | None -> 0 + + /// Get the apparent parent entity for the value, i.e. the entity under with which the + /// value is associated. For extension members this is the nominal type the member extends. + /// For other values it is just the actual parent. + member x.ApparentEnclosingEntity = + match x.MemberInfo with + | Some membInfo -> Parent(membInfo.ApparentEnclosingEntity) + | None -> x.DeclaringEntity + + /// Get the public path to the value, if any? Should be set if and only if + /// IsMemberOrModuleBinding is set. + // + // We use it here: + // - in opt.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) + // - in ilxgen.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) + // - in opt.fs: (fullDebugTextOfValRef) for error reporting of non-inlinable values + // - in service.fs (boutput_item_description): to display the full text of a value's binding location + // - in check.fs: as a boolean to detect public values for saving quotations + // - in ilxgen.fs: as a boolean to detect public values for saving quotations + // - in MakeExportRemapping, to build non-local references for values + member x.PublicPath = + match x.DeclaringEntity with + | Parent eref -> + match eref.PublicPath with + | None -> None + | Some p -> Some(ValPubPath(p, x.GetLinkageFullKey())) + | ParentNone -> + None + + /// Indicates if this member is an F#-defined dispatch slot. + member x.IsDispatchSlot = + match x.MemberInfo with + | Some membInfo -> membInfo.MemberFlags.IsDispatchSlot + | _ -> false + + /// Get the type of the value including any generic type parameters + member x.TypeScheme = + match x.Type with + | TType_forall(tps, tau) -> tps, tau + | ty -> [], ty + + /// Get the type of the value after removing any generic type parameters + member x.TauType = + match x.Type with + | TType_forall(_, tau) -> tau + | ty -> ty + + /// Get the generic type parameters for the value + member x.Typars = + match x.Type with + | TType_forall(tps, _) -> tps + | _ -> [] + + /// The name of the method. + /// - If this is a property then this is 'get_Foo' or 'set_Foo' + /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot + /// - If this is an extension member then this will be the simple name + member x.LogicalName = + match x.MemberInfo with + | None -> x.val_logical_name + | Some membInfo -> + match membInfo.ImplementedSlotSigs with + | slotsig :: _ -> slotsig.Name + | _ -> x.val_logical_name + + // Set the logical name of the value + member x.SetLogicalName(nm) = + x.val_logical_name <- nm + + member x.ValCompiledName = + match x.val_opt_data with + | Some optData -> optData.val_compiled_name + | _ -> None + + /// The name of the method in compiled code (with some exceptions where ilxgen.fs decides not to use a method impl) + /// - If this is a property then this is 'get_Foo' or 'set_Foo' + /// - If this is an implementation of an abstract slot then this may be a mangled name + /// - If this is an extension member then this will be a mangled name + /// - If this is an operator then this is 'op_Addition' + member x.CompiledName (compilerGlobalState:CompilerGlobalState option) = + let givenName = + match x.val_opt_data with + | Some { val_compiled_name = Some n } -> n + | _ -> x.LogicalName + // These cases must get stable unique names for their static field & static property. This name + // must be stable across quotation generation and IL code generation (quotations can refer to the + // properties implicit in these) + // + // Variable 'x' here, which is compiled as a top level static: + // do let x = expr in ... // IsMemberOrModuleBinding = false, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=false + // + // The implicit 'patternInput' variable here: + // let [x] = expr in ... // IsMemberOrModuleBinding = true, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=true + // + // The implicit 'copyOfStruct' variables here: + // let dt = System.DateTime.Now - System.DateTime.Now // IsMemberOrModuleBinding = false, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=true + // + // However we don't need this for CompilerGenerated members such as the implementations of IComparable + match compilerGlobalState with + | Some state when x.IsCompiledAsTopLevel && not x.IsMember && (x.IsCompilerGenerated || not x.IsMemberOrModuleBinding) -> + state.StableNameGenerator.GetUniqueCompilerGeneratedName(givenName, x.Range, x.Stamp) + | _ -> givenName + + /// The name of the property. + /// - If this is a property then this is 'Foo' + member x.PropertyName = + let logicalName = x.LogicalName + ChopPropertyName logicalName + + /// The display name of the value or method but without operator names decompiled and without backticks etc. + /// This is very close to LogicalName except that properties have get_ removed. + /// + /// Note: here "Core" means "without added backticks or parens" + /// Note: here "Mangled" means "op_Addition" + /// + /// - If this is a property --> Foo + /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot + /// - If this is an active pattern --> |A|_| + /// - If this is an operator --> op_Addition + /// - If this is an identifier needing backticks --> A-B + member x.DisplayNameCoreMangled = + match x.MemberInfo with + | Some membInfo -> + match membInfo.MemberFlags.MemberKind with + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.Member -> x.LogicalName + | SynMemberKind.PropertyGetSet + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGet -> x.PropertyName + | None -> x.LogicalName + + /// The display name of the value or method with operator names decompiled but without backticks etc. + /// + /// Note: here "Core" means "without added backticks or parens" + member x.DisplayNameCore = + x.DisplayNameCoreMangled |> DecompileOpName + + /// The full text for the value to show in error messages and to use in code. + /// This includes backticks, parens etc. + /// + /// - If this is a property --> Foo + /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot + /// - If this is an active pattern --> (|A|_|) + /// - If this is an operator --> (+) + /// - If this is an identifier needing backticks --> ``A-B`` + /// - If this is a base value --> base + /// - If this is a value named ``base`` --> ``base`` + member x.DisplayName = + ConvertValNameToDisplayName x.IsBaseVal x.DisplayNameCoreMangled + + member x.SetValRec b = x.val_flags <- x.val_flags.WithRecursiveValInfo b + + member x.SetIsCompilerGenerated(v) = x.val_flags <- x.val_flags.WithIsCompilerGenerated(v) + + member x.SetIsMemberOrModuleBinding() = x.val_flags <- x.val_flags.WithIsMemberOrModuleBinding + + member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.WithMakesNoCriticalTailcalls + + member x.SetHasBeenReferenced() = x.val_flags <- x.val_flags.WithHasBeenReferenced + + member x.SetIsCompiledAsStaticPropertyWithoutField() = x.val_flags <- x.val_flags.WithIsCompiledAsStaticPropertyWithoutField + + member x.SetIsFixed() = x.val_flags <- x.val_flags.WithIsFixed + + member x.SetIgnoresByrefScope() = x.val_flags <- x.val_flags.WithIgnoresByrefScope + + member x.SetInlineIfLambda() = x.val_flags <- x.val_flags.WithInlineIfLambda + + member x.SetValReprInfo info = + match x.val_opt_data with + | Some optData -> optData.val_repr_info <- info + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_repr_info = info } + + member x.SetType ty = x.val_type <- ty + + member x.SetOtherRange m = + match x.val_opt_data with + | Some optData -> optData.val_other_range <- Some m + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_other_range = Some m } + + member x.SetDeclaringEntity parent = + match x.val_opt_data with + | Some optData -> optData.val_declaring_entity <- parent + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_declaring_entity = parent } + + member x.SetAttribs attribs = + match x.val_opt_data with + | Some optData -> optData.val_attribs <- attribs + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_attribs = attribs } + + member x.SetMemberInfo member_info = + match x.val_opt_data with + | Some optData -> optData.val_member_info <- Some member_info + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_member_info = Some member_info } + + member x.SetValDefn val_defn = + match x.val_opt_data with + | Some optData -> optData.val_defn <- Some val_defn + | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_defn = Some val_defn } + + /// Create a new value with empty, unlinked data. Only used during unpickling of F# metadata. + static member NewUnlinked() : Val = + { val_logical_name = Unchecked.defaultof<_> + val_range = Unchecked.defaultof<_> + val_type = Unchecked.defaultof<_> + val_stamp = Unchecked.defaultof<_> + val_flags = Unchecked.defaultof<_> + val_opt_data = Unchecked.defaultof<_> } + + + /// Create a new value with the given backing data. Only used during unpickling of F# metadata. + static member New data: Val = data + + /// Link a value based on empty, unlinked data to the given data. Only used during unpickling of F# metadata. + member x.Link (tg: ValData) = x.SetData tg + + /// Set all the data on a value + member x.SetData (tg: ValData) = + x.val_logical_name <- tg.val_logical_name + x.val_range <- tg.val_range + x.val_type <- tg.val_type + x.val_stamp <- tg.val_stamp + x.val_flags <- tg.val_flags + match tg.val_opt_data with + | Some tg -> + x.val_opt_data <- + Some { val_compiled_name = tg.val_compiled_name + val_other_range = tg.val_other_range + val_const = tg.val_const + val_defn = tg.val_defn + val_repr_info = tg.val_repr_info + val_access = tg.val_access + val_xmldoc = tg.val_xmldoc + val_member_info = tg.val_member_info + val_declaring_entity = tg.val_declaring_entity + val_xmldocsig = tg.val_xmldocsig + val_attribs = tg.val_attribs } + | None -> () + + /// Indicates if a value is linked to backing data yet. Only used during unpickling of F# metadata. + member x.IsLinked = match box x.val_logical_name with null -> false | _ -> true + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.LogicalName + + +/// Represents the extra information stored for a member +[] +type ValMemberInfo = + { + /// The parent type. For an extension member this is the type being extended + ApparentEnclosingEntity: TyconRef + + /// Updated with the full implemented slotsig after interface implementation relation is checked + mutable ImplementedSlotSigs: SlotSig list + + /// Gets updated with 'true' if an abstract slot is implemented in the file being typechecked. Internal only. + mutable IsImplemented: bool + + MemberFlags: SynMemberFlags + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "ValMemberInfo(...)" + +[] +type NonLocalValOrMemberRef = + { + /// A reference to the entity containing the value or member. This will always be a non-local reference + EnclosingEntity: EntityRef + + /// The name of the value, or the full signature of the member + ItemKey: ValLinkageFullKey + } + + /// Get the thunk for the assembly referred to + member x.Ccu = x.EnclosingEntity.nlr.Ccu + + /// Get the name of the assembly referred to + member x.AssemblyName = x.EnclosingEntity.nlr.AssemblyName + + /// For debugging + [] + member x.DebugText = x.ToString() + + /// For debugging + override x.ToString() = x.EnclosingEntity.nlr.ToString() + "::" + x.ItemKey.PartialKey.LogicalName + +/// Represents the path information for a reference to a value or member in another assembly, disassociated +/// from any particular reference. +[] +type ValPublicPath = + | ValPubPath of PublicPath * ValLinkageFullKey + + [] + member x.DebugText = x.ToString() + + override _.ToString() = sprintf "ValPubPath(...)" + +/// Represents an index into the namespace/module structure of an assembly +[] +type NonLocalEntityRef = + | NonLocalEntityRef of CcuThunk * string[] + + /// Try to find the entity corresponding to the given path in the given CCU + static member TryDerefEntityPath(ccu: CcuThunk, path: string[], i: int, entity: Entity) = + if i >= path.Length then ValueSome entity + else + match entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryGetValue path.[i] with + | true, res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res) +#if !NO_EXTENSIONTYPING + | _ -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity) +#else + | _ -> ValueNone +#endif + +#if !NO_EXTENSIONTYPING + /// Try to find the entity corresponding to the given path, using type-providers to link the data + static member TryDerefEntityPathViaProvidedType(ccu: CcuThunk, path: string[], i: int, entity: Entity) = + // Errors during linking are not necessarily given good ranges. This has always been the case in F# 2.0, but also applies to + // type provider type linking errors in F# 3.0. + let m = range0 + match entity.TypeReprInfo with + | TProvidedTypeRepr info -> + let resolutionEnvironment = info.ResolutionEnvironment + let st = info.ProvidedType + + // In this case, we're safely in the realm of types. Just iterate through the nested + // types until i = path.Length-1. Create the Tycon's as needed + let rec tryResolveNestedTypeOf(parentEntity: Entity, resolutionEnvironment, st: Tainted, i) = + match st.PApply((fun st -> st.GetNestedType path.[i]), m) with + | Tainted.Null -> ValueNone + | st -> + let newEntity = Construct.NewProvidedTycon(resolutionEnvironment, st, ccu.ImportProvidedType, false, m) + parentEntity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity + if i = path.Length-1 then ValueSome newEntity + else tryResolveNestedTypeOf(newEntity, resolutionEnvironment, st, i+1) + + tryResolveNestedTypeOf(entity, resolutionEnvironment, st, i) + + | TProvidedNamespaceRepr(resolutionEnvironment, resolvers) -> + + // In this case, we're still in the realm of extensible namespaces. + // <----entity--> + // 0 .........i-1..i .......... j ..... path.Length-1 + // + // <----entity--> <---resolver----> + // 0 .........i-1..i ............. j ..... path.Length-1 + // + // <----entity--> <---resolver----> <--loop---> + // 0 .........i-1..i ............. j ..... path.Length-1 + // + // We now query the resolvers with + // moduleOrNamespace = path.[0..j-1] + // typeName = path.[j] + // starting with j = i and then progressively increasing j + + // This function queries at 'j' + let tryResolvePrefix j = + assert (j >= 0) + assert (j <= path.Length - 1) + let matched = + [ for resolver in resolvers do + let moduleOrNamespace = if j = 0 then null else path.[0..j-1] + let typename = path.[j] + let resolution = TryLinkProvidedType(resolver, moduleOrNamespace, typename, m) + match resolution with + | None | Some Tainted.Null -> () + | Some st -> yield (resolver, st) ] + match matched with + | [(_, st)] -> + // 'entity' is at position i in the dereference chain. We resolved to position 'j'. + // Inject namespaces until we're an position j, and then inject the type. + // Note: this is similar to code in CompileOps.fs + let rec injectNamespacesFromIToJ (entity: Entity) k = + if k = j then + let newEntity = Construct.NewProvidedTycon(resolutionEnvironment, st, ccu.ImportProvidedType, false, m) + entity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity + newEntity + else + let cpath = entity.CompilationPath.NestedCompPath entity.LogicalName ModuleOrNamespaceKind.Namespace + let newEntity = + Construct.NewModuleOrNamespace + (Some cpath) + (TAccess []) (ident(path.[k], m)) XmlDoc.Empty [] + (MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType Namespace)) + entity.ModuleOrNamespaceType.AddModuleOrNamespaceByMutation newEntity + injectNamespacesFromIToJ newEntity (k+1) + let newEntity = injectNamespacesFromIToJ entity i + + // newEntity is at 'j' + NonLocalEntityRef.TryDerefEntityPath(ccu, path, (j+1), newEntity) + + | [] -> ValueNone + | _ -> failwith "Unexpected" + + let rec tryResolvePrefixes j = + if j >= path.Length then ValueNone + else match tryResolvePrefix j with + | ValueNone -> tryResolvePrefixes (j+1) + | ValueSome res -> ValueSome res + + tryResolvePrefixes i + + | _ -> ValueNone +#endif + + /// Try to link a non-local entity reference to an actual entity + member nleref.TryDeref canError = + let (NonLocalEntityRef(ccu, path)) = nleref + if canError then + ccu.EnsureDerefable path + + if ccu.IsUnresolvedReference then ValueNone else + + match NonLocalEntityRef.TryDerefEntityPath(ccu, path, 0, ccu.Contents) with + | ValueSome _ as r -> r + | ValueNone -> + // OK, the lookup failed. Check if we can redirect through a type forwarder on this assembly. + // Look for a forwarder for each prefix-path + let rec tryForwardPrefixPath i = + if i < path.Length then + match ccu.TryForward(path.[0..i-1], path.[i]) with + // OK, found a forwarder, now continue with the lookup to find the nested type + | Some tcref -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), tcref.Deref) + | None -> tryForwardPrefixPath (i+1) + else + ValueNone + tryForwardPrefixPath 0 + + /// Get the CCU referenced by the nonlocal reference. + member nleref.Ccu = + let (NonLocalEntityRef(ccu, _)) = nleref + ccu + + /// Get the path into the CCU referenced by the nonlocal reference. + member nleref.Path = + let (NonLocalEntityRef(_, p)) = nleref + p + + member nleref.DisplayName = + String.concat "." nleref.Path + + /// Get the mangled name of the last item in the path of the nonlocal reference. + member nleref.LastItemMangledName = + let p = nleref.Path + p.[p.Length-1] + + /// Get the all-but-last names of the path of the nonlocal reference. + member nleref.EnclosingMangledPath = + let p = nleref.Path + p.[0..p.Length-2] + + /// Get the name of the assembly referenced by the nonlocal reference. + member nleref.AssemblyName = nleref.Ccu.AssemblyName + + /// Dereference the nonlocal reference, and raise an error if this fails. + member nleref.Deref = + match nleref.TryDeref(canError=true) with + | ValueSome res -> res + | ValueNone -> + errorR (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespace, nleref.DisplayName, nleref.AssemblyName, "")) + raise (KeyNotFoundException()) + + /// Get the details of the module or namespace fragment for the entity referred to by this non-local reference. + member nleref.ModuleOrNamespaceType = + nleref.Deref.ModuleOrNamespaceType + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.DisplayName + +[] +type EntityRef = + { + /// Indicates a reference to something bound in this CCU + mutable binding: NonNullSlot + + /// Indicates a reference to something bound in another CCU + nlr: NonLocalEntityRef + } + + /// Indicates if the reference is a local reference + member x.IsLocalRef = match box x.nlr with null -> true | _ -> false + + /// Indicates if the reference has been resolved + member x.IsResolved = match box x.binding with null -> false | _ -> true + + /// The resolved target of the reference + member x.ResolvedTarget = x.binding + + /// Resolve the reference + member private tcr.Resolve canError = + let res = tcr.nlr.TryDeref canError + match res with + | ValueSome r -> + tcr.binding <- nullableSlotFull r + | ValueNone -> + () + + /// Dereference the TyconRef to a Tycon. Amortize the cost of doing this. + /// This path should not allocate in the amortized case + member tcr.Deref = + match box tcr.binding with + | null -> + tcr.Resolve(canError=true) + match box tcr.binding with + | null -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespaceType, String.concat "." tcr.nlr.EnclosingMangledPath, tcr.nlr.AssemblyName, tcr.nlr.LastItemMangledName)) + | _ -> tcr.binding + | _ -> + tcr.binding + + /// Dereference the TyconRef to a Tycon option. + member tcr.TryDeref = + match box tcr.binding with + | null -> + tcr.Resolve(canError=false) + match box tcr.binding with + | null -> ValueNone + | _ -> ValueSome tcr.binding + + | _ -> + ValueSome tcr.binding + + /// Is the destination assembly available? + member tcr.CanDeref = tcr.TryDeref.IsSome + + /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. + member x.CompiledRepresentation = x.Deref.CompiledRepresentation + + /// Gets the data indicating the compiled representation of a named type or module in terms of Abstract IL data structures. + member x.CompiledRepresentationForNamedType = x.Deref.CompiledRepresentationForNamedType + + /// The implementation definition location of the namespace, module or type + member x.DefinitionRange = x.Deref.DefinitionRange + + /// The signature definition location of the namespace, module or type + member x.SigRange = x.Deref.SigRange + + /// The name of the namespace, module or type, possibly with mangling, e.g. List`1, List or FailureException + member x.LogicalName = x.Deref.LogicalName + + /// The compiled name of the namespace, module or type, e.g. FSharpList`1, ListModule or FailureException + member x.CompiledName = x.Deref.CompiledName + + /// The display name of the namespace, module or type, e.g. List instead of List`1, not including static parameters + /// + /// No backticks are added for entities with non-identifier names + member x.DisplayNameCore = x.Deref.DisplayNameCore + + /// The display name of the namespace, module or type, e.g. List instead of List`1, not including static parameters + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayName = x.Deref.DisplayName + + /// The display name of the namespace, module or type with <_, _, _> added for generic types, including static parameters + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayNameWithStaticParametersAndUnderscoreTypars = x.Deref.DisplayNameWithStaticParametersAndUnderscoreTypars + + /// The display name of the namespace, module or type, e.g. List instead of List`1, including static parameters + /// + /// Backticks are added implicitly for entities with non-identifier names + member x.DisplayNameWithStaticParameters = x.Deref.DisplayNameWithStaticParameters + + /// The code location where the module, namespace or type is defined. + member x.Range = x.Deref.Range + + /// A unique stamp for this module, namespace or type definition within the context of this compilation. + /// Note that because of signatures, there are situations where in a single compilation the "same" + /// module, namespace or type may have two distinct Entity objects that have distinct stamps. + member x.Stamp = x.Deref.Stamp + + /// The F#-defined custom attributes of the entity, if any. If the entity is backed by Abstract IL or provided metadata + /// then this does not include any attributes from those sources. + member x.Attribs = x.Deref.Attribs + + /// The XML documentation of the entity, if any. If the entity is backed by provided metadata + /// then this _does_ include this documentation. If the entity is backed by Abstract IL metadata + /// or comes from another F# assembly then it does not (because the documentation will get read from + /// an XML file). + member x.XmlDoc = x.Deref.XmlDoc + + /// The XML documentation sig-string of the entity, if any, to use to lookup an .xml doc file. This also acts + /// as a cache for this sig-string computation. + member x.XmlDocSig = x.Deref.XmlDocSig + + /// The logical contents of the entity when it is a module or namespace fragment. + member x.ModuleOrNamespaceType = x.Deref.ModuleOrNamespaceType + + /// Demangle the module name, if FSharpModuleWithSuffix is used + member x.DemangledModuleOrNamespaceName = x.Deref.DemangledModuleOrNamespaceName + + /// The logical contents of the entity when it is a type definition. + member x.TypeContents = x.Deref.TypeContents + + /// The kind of the type definition - is it a measure definition or a type definition? + member x.TypeOrMeasureKind = x.Deref.TypeOrMeasureKind + + /// The identifier at the point of declaration of the type definition. + member x.Id = x.Deref.Id + + /// The information about the r.h.s. of a type definition, if any. For example, the r.h.s. of a union or record type. + member x.TypeReprInfo = x.Deref.TypeReprInfo + + /// The information about the r.h.s. of an F# exception definition, if any. + member x.ExceptionInfo = x.Deref.ExceptionInfo + + /// Indicates if the entity represents an F# exception declaration. + member x.IsExceptionDecl = x.Deref.IsExceptionDecl + + /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. + /// + /// Lazy because it may read metadata, must provide a context "range" in case error occurs reading metadata. + member x.Typars m = x.Deref.Typars m + + /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. + member x.TyparsNoRange = x.Deref.TyparsNoRange + + /// Indicates if this entity is an F# type abbreviation definition + member x.TypeAbbrev = x.Deref.TypeAbbrev + + /// Indicates if this entity is an F# type abbreviation definition + member x.IsTypeAbbrev = x.Deref.IsTypeAbbrev + + /// Get the value representing the accessibility of the r.h.s. of an F# type definition. + member x.TypeReprAccessibility = x.Deref.TypeReprAccessibility + + /// Get the cache of the compiled ILTypeRef representation of this module or type. + member x.CompiledReprCache = x.Deref.CompiledReprCache + + /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. + member x.PublicPath: PublicPath option = x.Deref.PublicPath + + /// Get the value representing the accessibility of an F# type definition or module. + member x.Accessibility = x.Deref.Accessibility + + /// Indicates the type prefers the "tycon" syntax for display etc. + member x.IsPrefixDisplay = x.Deref.IsPrefixDisplay + + /// Indicates the "tycon blob" is actually a module + member x.IsModuleOrNamespace = x.Deref.IsModuleOrNamespace + + /// Indicates if the entity is a namespace + member x.IsNamespace = x.Deref.IsNamespace + + /// Indicates if the entity is an F# module definition + member x.IsModule = x.Deref.IsModule + + /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. + member x.CompilationPathOpt = x.Deref.CompilationPathOpt + +#if !NO_EXTENSIONTYPING + /// Indicates if the entity is a provided namespace fragment + member x.IsProvided = x.Deref.IsProvided + + /// Indicates if the entity is a provided namespace fragment + member x.IsProvidedNamespace = x.Deref.IsProvidedNamespace + + /// Indicates if the entity is an erased provided type definition + member x.IsProvidedErasedTycon = x.Deref.IsProvidedErasedTycon + + /// Indicates if the entity is an erased provided type definition that incorporates a static instantiation (and therefore in some sense compiler generated) + member x.IsStaticInstantiationTycon = x.Deref.IsStaticInstantiationTycon + + /// Indicates if the entity is a generated provided type definition, i.e. not erased. + member x.IsProvidedGeneratedTycon = x.Deref.IsProvidedGeneratedTycon +#endif + + /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. + member x.CompilationPath = x.Deref.CompilationPath + + /// Get a table of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldTable = x.Deref.AllFieldTable + + /// Get an array of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldsArray = x.Deref.AllFieldsArray + + /// Get a list of fields for all the F#-defined record, struct and class fields in this type definition, including + /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. + member x.AllFieldsAsList = x.Deref.AllFieldsAsList + + /// Get a list of all fields for F#-defined record, struct and class fields in this type definition, + /// including static fields, but excluding compiler-generate fields. + member x.TrueFieldsAsList = x.Deref.TrueFieldsAsList + + /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition, + /// excluding compiler-generate fields. + member x.TrueInstanceFieldsAsList = x.Deref.TrueInstanceFieldsAsList + + /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition. + /// including hidden fields from the compilation of implicit class constructions. + member x.AllInstanceFieldsAsList = x.Deref.AllInstanceFieldsAsList + + /// Get a field by index in definition order + member x.GetFieldByIndex n = x.Deref.GetFieldByIndex n + + /// Get a field by name. + member x.GetFieldByName n = x.Deref.GetFieldByName n + + /// Get the union cases and other union-type information for a type, if any + member x.UnionTypeInfo = x.Deref.UnionTypeInfo + + /// Get the union cases for a type, if any + member x.UnionCasesArray = x.Deref.UnionCasesArray + + /// Get the union cases for a type, if any, as a list + member x.UnionCasesAsList = x.Deref.UnionCasesAsList + + /// Get a union case of a type by name + member x.GetUnionCaseByName n = x.Deref.GetUnionCaseByName n + + /// Get the blob of information associated with an F# object-model type definition, i.e. class, interface, struct etc. + member x.FSharpObjectModelTypeInfo = x.Deref.FSharpObjectModelTypeInfo + + /// Gets the immediate interface definitions of an F# type definition. Further interfaces may be supported through class and interface inheritance. + member x.ImmediateInterfacesOfFSharpTycon = x.Deref.ImmediateInterfacesOfFSharpTycon + + /// Gets the immediate interface types of an F# type definition. Further interfaces may be supported through class and interface inheritance. + member x.ImmediateInterfaceTypesOfFSharpTycon = x.Deref.ImmediateInterfaceTypesOfFSharpTycon + + /// Gets the immediate members of an F# type definition, excluding compiler-generated ones. + /// Note: result is alphabetically sorted, then for each name the results are in declaration order + member x.MembersOfFSharpTyconSorted = x.Deref.MembersOfFSharpTyconSorted + + /// Gets all immediate members of an F# type definition keyed by name, including compiler-generated ones. + /// Note: result is a indexed table, and for each name the results are in reverse declaration order + member x.MembersOfFSharpTyconByName = x.Deref.MembersOfFSharpTyconByName + + /// Indicates if this is a struct or enum type definition, i.e. a value type definition + member x.IsStructOrEnumTycon = x.Deref.IsStructOrEnumTycon + + /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll which uses + /// an assembly-code representation for the type, e.g. the primitive array type constructor. + member x.IsAsmReprTycon = x.Deref.IsAsmReprTycon + + /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll like 'float<_>' which + /// defines a measure type with a relation to an existing non-measure type as a representation. + member x.IsMeasureableReprTycon = x.Deref.IsMeasureableReprTycon + + /// Indicates if the entity is erased, either a measure definition, or an erased provided type definition + member x.IsErased = x.Deref.IsErased + + /// Gets any implicit hash/equals (with comparer argument) methods added to an F# record, union or struct type definition. + member x.GeneratedHashAndEqualsWithComparerValues = x.Deref.GeneratedHashAndEqualsWithComparerValues + + /// Gets any implicit CompareTo (with comparer argument) methods added to an F# record, union or struct type definition. + member x.GeneratedCompareToWithComparerValues = x.Deref.GeneratedCompareToWithComparerValues + + /// Gets any implicit CompareTo methods added to an F# record, union or struct type definition. + member x.GeneratedCompareToValues = x.Deref.GeneratedCompareToValues + + /// Gets any implicit hash/equals methods added to an F# record, union or struct type definition. + member x.GeneratedHashAndEqualsValues = x.Deref.GeneratedHashAndEqualsValues + + /// Indicate if this is a type definition backed by Abstract IL metadata. + member x.IsILTycon = x.Deref.IsILTycon + + /// Get the Abstract IL scope, nesting and metadata for this + /// type definition, assuming it is backed by Abstract IL metadata. + member x.ILTyconInfo = x.Deref.ILTyconInfo + + /// Get the Abstract IL metadata for this type definition, assuming it is backed by Abstract IL metadata. + member x.ILTyconRawMetadata = x.Deref.ILTyconRawMetadata + + /// Indicate if this is a type whose r.h.s. is known to be a union type definition. + member x.IsUnionTycon = x.Deref.IsUnionTycon + + /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition. + member x.IsRecordTycon = x.Deref.IsRecordTycon + + /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition + member x.IsFSharpObjectModelTycon = x.Deref.IsFSharpObjectModelTycon + + /// The on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = x.Deref.TryIsByRefLike + + /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.SetIsByRefLike b = x.Deref.SetIsByRefLike b + + /// The on-demand analysis about whether the entity has the IsReadOnly attribute + member x.TryIsReadOnly = x.Deref.TryIsReadOnly + + /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute + member x.SetIsReadOnly b = x.Deref.SetIsReadOnly b + + /// The on-demand analysis about whether the entity is assumed to be a readonly struct + member x.TryIsAssumedReadOnly = x.Deref.TryIsAssumedReadOnly + + /// Set the on-demand analysis about whether the entity is assumed to be a readonly struct + member x.SetIsAssumedReadOnly b = x.Deref.SetIsAssumedReadOnly b + + /// Indicates if this is an F# type definition whose r.h.s. definition is unknown (i.e. a traditional ML 'abstract' type in a signature, + /// which in F# is called a 'unknown representation' type). + member x.IsHiddenReprTycon = x.Deref.IsHiddenReprTycon + + /// Indicates if this is an F#-defined interface type definition + member x.IsFSharpInterfaceTycon = x.Deref.IsFSharpInterfaceTycon + + /// Indicates if this is an F#-defined delegate type definition + member x.IsFSharpDelegateTycon = x.Deref.IsFSharpDelegateTycon + + /// Indicates if this is an F#-defined enum type definition + member x.IsFSharpEnumTycon = x.Deref.IsFSharpEnumTycon + + /// Indicates if this is a .NET-defined enum type definition + member x.IsILEnumTycon = x.Deref.IsILEnumTycon + + /// Indicates if this is an enum type definition + member x.IsEnumTycon = x.Deref.IsEnumTycon + + /// Indicates if this is an F#-defined struct or enum type definition, i.e. a value type definition + member x.IsFSharpStructOrEnumTycon = x.Deref.IsFSharpStructOrEnumTycon + + /// Indicates if this is a .NET-defined struct or enum type definition, i.e. a value type definition + member x.IsILStructOrEnumTycon = x.Deref.IsILStructOrEnumTycon + + /// Indicates if we have pre-determined that a type definition has a default constructor. + member x.PreEstablishedHasDefaultConstructor = x.Deref.PreEstablishedHasDefaultConstructor + + /// Indicates if we have pre-determined that a type definition has a self-referential constructor using 'as x' + member x.HasSelfReferentialConstructor = x.Deref.HasSelfReferentialConstructor + + member x.UnionCasesAsRefList = x.UnionCasesAsList |> List.map x.MakeNestedUnionCaseRef + + member x.TrueInstanceFieldsAsRefList = x.TrueInstanceFieldsAsList |> List.map x.MakeNestedRecdFieldRef + + member x.AllFieldAsRefList = x.AllFieldsAsList |> List.map x.MakeNestedRecdFieldRef + + member x.MakeNestedRecdFieldRef (rf: RecdField) = RecdFieldRef (x, rf.LogicalName) + + member x.MakeNestedUnionCaseRef (uc: UnionCase) = UnionCaseRef (x, uc.Id.idText) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = + if x.IsLocalRef then + x.ResolvedTarget.DisplayName + else + x.nlr.DisplayName + +/// Represents a module-or-namespace reference in the typed abstract syntax. +type ModuleOrNamespaceRef = EntityRef + +/// Represents a type definition reference in the typed abstract syntax. +type TyconRef = EntityRef + +/// References are either local or nonlocal +[] +type ValRef = + { + /// Indicates a reference to something bound in this CCU + mutable binding: NonNullSlot + + /// Indicates a reference to something bound in another CCU + nlr: NonLocalValOrMemberRef + } + + member x.IsLocalRef = obj.ReferenceEquals(x.nlr, null) + + member x.IsResolved = not (obj.ReferenceEquals(x.binding, null)) + + member x.ResolvedTarget = x.binding + + /// Dereference the ValRef to a Val. + member vr.Deref = + if obj.ReferenceEquals(vr.binding, null) then + let res = + let nlr = vr.nlr + let e = nlr.EnclosingEntity.Deref + let possible = e.ModuleOrNamespaceType.TryLinkVal(nlr.EnclosingEntity.nlr.Ccu, nlr.ItemKey) + match possible with + | ValueNone -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefVal, e.DisplayNameWithStaticParameters, nlr.AssemblyName, sprintf "%+A" nlr.ItemKey.PartialKey)) + | ValueSome h -> h + vr.binding <- nullableSlotFull res + res + else vr.binding + + /// Dereference the ValRef to a Val option. + member vr.TryDeref = + if obj.ReferenceEquals(vr.binding, null) then + let resOpt = + match vr.nlr.EnclosingEntity.TryDeref with + | ValueNone -> ValueNone + | ValueSome e -> e.ModuleOrNamespaceType.TryLinkVal(vr.nlr.EnclosingEntity.nlr.Ccu, vr.nlr.ItemKey) + match resOpt with + | ValueNone -> () + | ValueSome res -> + vr.binding <- nullableSlotFull res + resOpt + else ValueSome vr.binding + + /// The type of the value. May be a TType_forall for a generic value. + /// May be a type variable or type containing type variables during type inference. + member x.Type = x.Deref.Type + + /// Get the type of the value including any generic type parameters + member x.TypeScheme = x.Deref.TypeScheme + + /// Get the type of the value after removing any generic type parameters + member x.TauType = x.Deref.TauType + + member x.Typars = x.Deref.Typars + + member x.LogicalName = x.Deref.LogicalName + + member x.DisplayNameCoreMangled = x.Deref.DisplayNameCoreMangled + + member x.DisplayNameCore = x.Deref.DisplayNameCore + + member x.DisplayName = x.Deref.DisplayName + + member x.Range = x.Deref.Range + + /// Get the value representing the accessibility of an F# type definition or module. + member x.Accessibility = x.Deref.Accessibility + + /// The parent type or module, if any (None for expression bindings and parameters) + member x.DeclaringEntity = x.Deref.DeclaringEntity + + /// Get the apparent parent entity for the value, i.e. the entity under with which the + /// value is associated. For extension members this is the nominal type the member extends. + /// For other values it is just the actual parent. + member x.ApparentEnclosingEntity = x.Deref.ApparentEnclosingEntity + + member x.DefinitionRange = x.Deref.DefinitionRange + + member x.SigRange = x.Deref.SigRange + + /// The value of a value or member marked with [] + member x.LiteralValue = x.Deref.LiteralValue + + member x.Id = x.Deref.Id + + /// Get the name of the value, assuming it is compiled as a property. + /// - If this is a property then this is 'Foo' + /// - If this is an implementation of an abstract slot then this is the name of the property implemented by the abstract slot + member x.PropertyName = x.Deref.PropertyName + + /// Indicates whether this value represents a property getter. + member x.IsPropertyGetterMethod = + match x.MemberInfo with + | None -> false + | Some (memInfo: ValMemberInfo) -> memInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGet || memInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet + + /// Indicates whether this value represents a property setter. + member x.IsPropertySetterMethod = + match x.MemberInfo with + | None -> false + | Some (memInfo: ValMemberInfo) -> memInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet || memInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGetSet + + /// A unique stamp within the context of this invocation of the compiler process + member x.Stamp = x.Deref.Stamp + + /// Is this represented as a "top level" static binding (i.e. a static field, static member, + /// instance member), rather than an "inner" binding that may result in a closure. + member x.IsCompiledAsTopLevel = x.Deref.IsCompiledAsTopLevel + + /// Indicates if this member is an F#-defined dispatch slot. + member x.IsDispatchSlot = x.Deref.IsDispatchSlot + + /// The name of the method in compiled code (with some exceptions where ilxgen.fs decides not to use a method impl) + member x.CompiledName = x.Deref.CompiledName + + /// Get the public path to the value, if any? Should be set if and only if + /// IsMemberOrModuleBinding is set. + member x.PublicPath = x.Deref.PublicPath + + /// The quotation expression associated with a value given the [] tag + member x.ReflectedDefinition = x.Deref.ReflectedDefinition + + /// Indicates if this is an F#-defined 'new' constructor member + member x.IsConstructor = x.Deref.IsConstructor + + /// Indicates if this value was a member declared 'override' or an implementation of an interface slot + member x.IsOverrideOrExplicitImpl = x.Deref.IsOverrideOrExplicitImpl + + /// Is this a member, if so some more data about the member. + member x.MemberInfo = x.Deref.MemberInfo + + /// Indicates if this is a member + member x.IsMember = x.Deref.IsMember + + /// Indicates if this is an F#-defined value in a module, or an extension member, but excluding compiler generated bindings from optimizations + member x.IsModuleBinding = x.Deref.IsModuleBinding + + /// Indicates if this is an F#-defined instance member. + /// + /// Note, the value may still be (a) an extension member or (b) and abstract slot without + /// a true body. These cases are often causes of bugs in the compiler. + member x.IsInstanceMember = x.Deref.IsInstanceMember + + /// Indicates if this value is declared 'mutable' + member x.IsMutable = x.Deref.IsMutable + + /// Indicates if this value allows the use of an explicit type instantiation (i.e. does it itself have explicit type arguments, + /// or does it have a signature?) + member x.PermitsExplicitTypeInstantiation = x.Deref.PermitsExplicitTypeInstantiation + + /// Indicates if this is inferred to be a method or function that definitely makes no critical tailcalls? + member x.MakesNoCriticalTailcalls = x.Deref.MakesNoCriticalTailcalls + + /// Is this a member definition or module definition? + member x.IsMemberOrModuleBinding = x.Deref.IsMemberOrModuleBinding + + /// Indicates if this is an F#-defined extension member + member x.IsExtensionMember = x.Deref.IsExtensionMember + + /// Indicates if this is a constructor member generated from the de-sugaring of implicit constructor for a class type? + member x.IsIncrClassConstructor = x.Deref.IsIncrClassConstructor + + /// Indicates if this is a member generated from the de-sugaring of 'let' function bindings in the implicit class syntax? + member x.IsIncrClassGeneratedMember = x.Deref.IsIncrClassGeneratedMember + + /// Get the information about a recursive value used during type inference + member x.RecursiveValInfo = x.Deref.RecursiveValInfo + + /// Indicates if this is a 'base' or 'this' value? + member x.BaseOrThisInfo = x.Deref.BaseOrThisInfo + + /// Indicates if this is a 'base' value? + member x.IsBaseVal = x.Deref.IsBaseVal + + /// Indicates if this is a 'this' value for an implicit ctor? + member x.IsCtorThisVal = x.Deref.IsCtorThisVal + + /// Indicates if this is a 'this' value for a member? + member x.IsMemberThisVal = x.Deref.IsMemberThisVal + + /// Indicates if this value was declared to be a type function, e.g. "let f<'a> = typeof<'a>" + member x.IsTypeFunction = x.Deref.IsTypeFunction + + /// Records the "extra information" for a value compiled as a method. + /// + /// This indicates the number of arguments in each position for a curried function. + member x.ValReprInfo = x.Deref.ValReprInfo + + /// Get the inline declaration on the value + member x.InlineInfo = x.Deref.InlineInfo + + /// Get the inline declaration on a parameter or other non-function-declaration value, used for optimization + member x.InlineIfLambda = x.Deref.InlineIfLambda + + /// Indicates whether the inline declaration for the value indicate that the value must be inlined? + member x.MustInline = x.Deref.MustInline + + /// Indicates whether this value was generated by the compiler. + /// + /// Note: this is true for the overrides generated by hash/compare augmentations + member x.IsCompilerGenerated = x.Deref.IsCompilerGenerated + + /// Get the declared attributes for the value + member x.Attribs = x.Deref.Attribs + + /// Get the declared documentation for the value + member x.XmlDoc = x.Deref.XmlDoc + + /// Get or set the signature for the value's XML documentation + member x.XmlDocSig = x.Deref.XmlDocSig + + /// Get the actual parent entity for the value (a module or a type), i.e. the entity under which the + /// value will appear in compiled code. For extension members this is the module where the extension member + /// is declared. + member x.TopValDeclaringEntity = x.Deref.TopValDeclaringEntity + + // Can be false for members after error recovery + member x.HasDeclaringEntity = x.Deref.HasDeclaringEntity + + /// Get the apparent parent entity for a member + member x.MemberApparentEntity = x.Deref.MemberApparentEntity + + /// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'. + member x.NumObjArgs = x.Deref.NumObjArgs + + [] + member x.DebugText = x.ToString() + + override x.ToString() = + if x.IsLocalRef then x.ResolvedTarget.DisplayName + else x.nlr.ToString() + +/// Represents a reference to a case of a union type +[] +type UnionCaseRef = + | UnionCaseRef of TyconRef * string + + /// Get a reference to the type containing this union case + member x.TyconRef = let (UnionCaseRef(tcref, _)) = x in tcref + + /// Get the name of this union case + member x.CaseName = let (UnionCaseRef(_, nm)) = x in nm + + /// Get the Entity for the type containing this union case + member x.Tycon = x.TyconRef.Deref + + /// Dereference the reference to the union case + member x.UnionCase = + match x.TyconRef.GetUnionCaseByName x.CaseName with + | Some res -> res + | None -> error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) + + /// Try to dereference the reference + member x.TryUnionCase = + x.TyconRef.TryDeref + |> ValueOptionInternal.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOptionInternal.ofOption) + + /// Get the attributes associated with the union case + member x.Attribs = x.UnionCase.Attribs + + /// Get the range of the union case + member x.Range = x.UnionCase.Range + + /// Get the definition range of the union case + member x.DefinitionRange = x.UnionCase.DefinitionRange + + /// Get the signature range of the union case + member x.SigRange = x.UnionCase.SigRange + + /// Get the index of the union case amongst the cases + member x.Index = + try + // REVIEW: this could be faster, e.g. by storing the index in the NameMap + x.TyconRef.UnionCasesArray |> Array.findIndex (fun uc -> uc.LogicalName = x.CaseName) + with :? KeyNotFoundException -> + error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) + + /// Get the fields of the union case + member x.AllFieldsAsList = x.UnionCase.FieldTable.AllFieldsAsList + + /// Get the resulting type of the union case + member x.ReturnType = x.UnionCase.ReturnType + + /// Get a field of the union case by index + member x.FieldByIndex n = x.UnionCase.FieldTable.FieldByIndex n + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.CaseName + +/// Represents a reference to a field in a record, class or struct +[] +type RecdFieldRef = + | RecdFieldRef of tcref: TyconRef * id: string + + /// Get a reference to the type containing this union case + member x.TyconRef = let (RecdFieldRef(tcref, _)) = x in tcref + + /// Get the name of the field + member x.FieldName = let (RecdFieldRef(_, id)) = x in id + + /// Get the name of the field, with backticks added for non-identifier names + member x.DisplayName = x.FieldName |> ConvertNameToDisplayName + + /// Get the Entity for the type containing this union case + member x.Tycon = x.TyconRef.Deref + + /// Dereference the reference + member x.RecdField = + let (RecdFieldRef(tcref, id)) = x + match tcref.GetFieldByName id with + | Some res -> res + | None -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) + + /// Try to dereference the reference + member x.TryRecdField = + x.TyconRef.TryDeref + |> ValueOptionInternal.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) + + /// Get the attributes associated with the compiled property of the record field + member x.PropertyAttribs = x.RecdField.PropertyAttribs + + /// Get the declaration range of the record field + member x.Range = x.RecdField.Range + + /// Get the definition range of the record field + member x.DefinitionRange = x.RecdField.DefinitionRange + + /// Get the signature range of the record field + member x.SigRange = x.RecdField.SigRange + + member x.Index = + let (RecdFieldRef(tcref, id)) = x + try + // REVIEW: this could be faster, e.g. by storing the index in the NameMap + tcref.AllFieldsArray |> Array.findIndex (fun rfspec -> rfspec.LogicalName = id) + with :? KeyNotFoundException -> + error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.FieldName + +/// Represents a type in the typed abstract syntax +[] +type TType = + + /// TType_forall(typars, bodyTy). + /// + /// Indicates the type is a universal type, only used for types of values and members + | TType_forall of typars: Typars * bodyTy: TType + + /// TType_app(tyconRef, typeInstantiation). + /// + /// Indicates the type is built from a named type and a number of type arguments + | TType_app of tyconRef: TyconRef * typeInstantiation: TypeInst + + /// TType_anon + /// + /// Indicates the type is an anonymous record type whose compiled representation is located in the given assembly + | TType_anon of anonInfo: AnonRecdTypeInfo * tys: TType list + + /// TType_tuple(elementTypes). + /// + /// Indicates the type is a tuple type. elementTypes must be of length 2 or greater. + | TType_tuple of tupInfo: TupInfo * elementTypes: TTypes + + /// TType_fun(domainType, rangeType). + /// + /// Indicates the type is a function type + | TType_fun of domainType: TType * rangeType: TType + + /// TType_ucase(unionCaseRef, typeInstantiation) + /// + /// Indicates the type is a non-F#-visible type representing a "proof" that a union value belongs to a particular union case + /// These types are not user-visible and will never appear as an inferred type. They are the types given to + /// the temporaries arising out of pattern matching on union values. + | TType_ucase of unionCaseRef: UnionCaseRef * typeInstantiation: TypeInst + + /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter + | TType_var of typar: Typar + + /// Indicates the type is a unit-of-measure expression being used as an argument to a type or member + | TType_measure of measure: Measure + + /// For now, used only as a discriminant in error message. + /// See https://github.com/Microsoft/visualfsharp/issues/2561 + member x.GetAssemblyName() = + match x with + | TType_forall (_tps, ty) -> ty.GetAssemblyName() + | TType_app (tcref, _tinst) -> tcref.CompilationPath.ILScopeRef.QualifiedName + | TType_tuple (_tupInfo, _tinst) -> "" + | TType_anon (anonInfo, _tinst) -> defaultArg anonInfo.Assembly.QualifiedName "" + | TType_fun (_d, _r) -> "" + | TType_measure _ms -> "" + | TType_var tp -> tp.Solution |> function Some sln -> sln.GetAssemblyName() | None -> "" + | TType_ucase (_uc, _tinst) -> + let (TILObjectReprData(scope, _nesting, _definition)) = _uc.Tycon.ILTyconInfo + scope.QualifiedName + + [] + member x.DebugText = x.ToString() + + override x.ToString() = + match x with + | TType_forall (_tps, ty) -> "forall ... " + ty.ToString() + | TType_app (tcref, tinst) -> tcref.DisplayName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") + | TType_tuple (tupInfo, tinst) -> + (match tupInfo with + | TupInfo.Const false -> "" + | TupInfo.Const true -> "struct ") + + String.concat "," (List.map string tinst) + | TType_anon (anonInfo, tinst) -> + (match anonInfo.TupInfo with + | TupInfo.Const false -> "" + | TupInfo.Const true -> "struct ") + + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + ")" + "|}" + | TType_fun (d, r) -> "(" + string d + " -> " + string r + ")" + | TType_ucase (uc, tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") + | TType_var tp -> + match tp.Solution with + | None -> tp.DisplayName + | Some _ -> tp.DisplayName + " (solved)" + | TType_measure ms -> ms.ToString() + +type TypeInst = TType list + +type TTypes = TType list + +/// Represents the information identifying an anonymous record +[] +type AnonRecdTypeInfo = + { + // Mutability for pickling/unpickling only + mutable Assembly: CcuThunk + + mutable TupInfo: TupInfo + + mutable SortedIds: Ident[] + + mutable Stamp: Stamp + + mutable SortedNames: string[] + } + + /// Create an AnonRecdTypeInfo from the basic data + static member Create(ccu: CcuThunk, tupInfo, ids: Ident[]) = + let sortedIds = ids |> Array.sortBy (fun id -> id.idText) + // Hash all the data to form a unique stamp + let stamp = + sha1HashInt64 + [| for c in ccu.AssemblyName do yield byte c; yield byte (int32 c >>> 8) + match tupInfo with + | TupInfo.Const b -> yield (if b then 0uy else 1uy) + for id in sortedIds do + for c in id.idText do yield byte c; yield byte (int32 c >>> 8) |] + let sortedNames = Array.map textOfId sortedIds + { Assembly = ccu; TupInfo = tupInfo; SortedIds = sortedIds; Stamp = stamp; SortedNames = sortedNames } + + /// Get the ILTypeRef for the generated type implied by the anonymous type + member x.ILTypeRef = + let ilTypeName = sprintf "<>f__AnonymousType%s%u`%d" (match x.TupInfo with TupInfo.Const b -> if b then "1000" else "") (uint32 x.Stamp) x.SortedIds.Length + mkILTyRef(x.Assembly.ILScopeRef, ilTypeName) + + static member NewUnlinked() : AnonRecdTypeInfo = + { Assembly = Unchecked.defaultof<_> + TupInfo = Unchecked.defaultof<_> + SortedIds = Unchecked.defaultof<_> + Stamp = Unchecked.defaultof<_> + SortedNames = Unchecked.defaultof<_> } + + member x.Link d = + let sortedNames = Array.map textOfId d.SortedIds + x.Assembly <- d.Assembly + x.TupInfo <- d.TupInfo + x.SortedIds <- d.SortedIds + x.Stamp <- d.Stamp + x.SortedNames <- sortedNames + + member x.IsLinked = (match x.SortedIds with null -> true | _ -> false) + +[] +type TupInfo = + /// Some constant, e.g. true or false for tupInfo + | Const of bool + +/// Represents a unit of measure in the typed AST +[] +type Measure = + + /// A variable unit-of-measure + | Var of typar: Typar + + /// A constant, leaf unit-of-measure such as 'kg' or 'm' + | Con of tyconRef: TyconRef + + /// A product of two units of measure + | Prod of measure1: Measure * measure2: Measure + + /// An inverse of a units of measure expression + | Inv of measure: Measure + + /// The unit of measure '1', e.g. float = float<1> + | One + + /// Raising a measure to a rational power + | RationalPower of measure: Measure * power: Rational + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +type Attribs = Attrib list + +[] +type AttribKind = + + /// Indicates an attribute refers to a type defined in an imported .NET assembly + | ILAttrib of ilMethodRef: ILMethodRef + + /// Indicates an attribute refers to a type defined in an imported F# assembly + | FSAttrib of valRef: ValRef + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// Attrib(tyconRef, kind, unnamedArgs, propVal, appliedToAGetterOrSetter, targetsOpt, range) +[] +type Attrib = + + | Attrib of + tyconRef: TyconRef * + kind: AttribKind * + unnamedArgs: AttribExpr list * + propVal: AttribNamedArg list * + appliedToAGetterOrSetter: bool * + targetsOpt: AttributeTargets option * + range: range + + [] + member x.DebugText = x.ToString() + + member x.TyconRef = (let (Attrib(tcref, _, _, _, _, _, _)) = x in tcref) + + member x.Range = (let (Attrib(_, _, _, _, _, _, m)) = x in m) + + override x.ToString() = "attrib" + x.TyconRef.ToString() + +/// We keep both source expression and evaluated expression around to help intellisense and signature printing +[] +type AttribExpr = + + /// AttribExpr(source, evaluated) + | AttribExpr of source: Expr * evaluated: Expr + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "AttribExpr(...)" + +/// AttribNamedArg(name, type, isField, value) +[] +type AttribNamedArg = + | AttribNamedArg of (string*TType*bool*AttribExpr) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "AttribNamedArg(...)" + +/// Constants in expressions +[] +type Const = + | Bool of bool + | SByte of sbyte + | Byte of byte + | Int16 of int16 + | UInt16 of uint16 + | Int32 of int32 + | UInt32 of uint32 + | Int64 of int64 + | UInt64 of uint64 + | IntPtr of int64 + | UIntPtr of uint64 + | Single of single + | Double of double + | Char of char + | String of string + | Decimal of Decimal + | Unit + | Zero // null/zero-bit-pattern + + [] + member x.DebugText = x.ToString() + + override c.ToString() = + match c with + | Bool b -> (if b then "true" else "false") + | SByte x -> string x + "y" + | Byte x -> string x + "uy" + | Int16 x -> string x + "s" + | UInt16 x -> string x + "us" + | Int32 x -> string x + | UInt32 x -> string x + "u" + | Int64 x -> string x + "L" + | UInt64 x -> string x + "UL" + | IntPtr x -> string x + "n" + | UIntPtr x -> string x + "un" + | Single x -> string x + "f" + | Double x -> string x + | Char x -> "'" + string x + "'" + | String x -> "\"" + x + "\"" + | Decimal x -> string x + "M" + | Unit -> "()" + | Zero -> "Const.Zero" + +/// Decision trees. Pattern matching has been compiled down to +/// a decision tree by this point. The right-hand-sides (actions) of +/// a decision tree by this point. The right-hand-sides (actions) of +/// the decision tree are labelled by integers that are unique for that +/// particular tree. +[] +type DecisionTree = + + /// TDSwitch(input, cases, default, range) + /// + /// Indicates a decision point in a decision tree. + /// input -- The expression being tested. If switching over a struct union this + /// must be the address of the expression being tested. + /// cases -- The list of tests and their subsequent decision trees + /// default -- The default decision tree, if any + /// range -- (precise documentation needed) + | TDSwitch of debugPoint: DebugPointAtSwitch * input: Expr * cases: DecisionTreeCase list * defaultOpt: DecisionTree option * range: range + + /// TDSuccess(results, targets) + /// + /// Indicates the decision tree has terminated with success, transferring control to the given target with the given parameters. + /// results -- the expressions to be bound to the variables at the target + /// target -- the target number for the continuation + | TDSuccess of results: Exprs * targetNum: int + + /// TDBind(binding, body) + /// + /// Bind the given value through the remaining cases of the dtree. + /// These arise from active patterns and some optimizations to prevent + /// repeated computations in decision trees. + /// binding -- the value and the expression it is bound to + /// body -- the rest of the decision tree + | TDBind of binding: Binding * body: DecisionTree + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// Represents a test and a subsequent decision tree +[] +type DecisionTreeCase = + | TCase of discriminator: DecisionTreeTest * caseTree: DecisionTree + + /// Get the discriminator associated with the case + member x.Discriminator = let (TCase(d, _)) = x in d + + /// Get the decision tree or a successful test + member x.CaseTree = let (TCase(_, d)) = x in d + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "DecisionTreeCase(...)" + +[] +type DecisionTreeTest = + /// Test if the input to a decision tree matches the given union case + | UnionCase of caseRef: UnionCaseRef * tinst: TypeInst + + /// Test if the input to a decision tree is an array of the given length + | ArrayLength of length: int * ty: TType + + /// Test if the input to a decision tree is the given constant value + | Const of value: Const + + /// Test if the input to a decision tree is null + | IsNull + + /// IsInst(source, target) + /// + /// Test if the input to a decision tree is an instance of the given type + | IsInst of source: TType * target: TType + + /// Test.ActivePatternCase(activePatExpr, activePatResTys, isStructRetTy, activePatIdentity, idx, activePatInfo) + /// + /// Run the active pattern and bind a successful result to a + /// variable in the remaining tree. + /// activePatExpr -- The active pattern function being called, perhaps applied to some active pattern parameters. + /// activePatResTys -- The result types (case types) of the active pattern. + /// isStructRetTy -- Is the active pattern a struct return + /// activePatIdentity -- The value and the types it is applied to. If there are any active pattern parameters then this is empty. + /// idx -- The case number of the active pattern which the test relates to. + /// activePatternInfo -- The extracted info for the active pattern. + | ActivePatternCase of + activePatExpr: Expr * + activePatResTys: TTypes * + isStructRetTy: bool * + activePatIdentity: (ValRef * TypeInst) option * + idx: int * + activePatternInfo: ActivePatternInfo + + /// Used in error recovery + | Error of range: range + + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. +/// -- boundVals - The values bound at the target, matching the valuesin the TDSuccess +/// -- targetExpr - The expression to evaluate if we branch to the target +/// -- debugPoint - The debug point for the target +/// -- isStateVarFlags - Indicates which, if any, of the values are repesents as state machine variables +[] +type DecisionTreeTarget = + | TTarget of + boundVals: Val list * + targetExpr: Expr * + debugPoint: DebugPointAtTarget * + isStateVarFlags: bool list option + + [] + member x.DebugText = x.ToString() + + member x.TargetExpression = (let (TTarget(_, expr, _, _)) = x in expr) + + override x.ToString() = sprintf "DecisionTreeTarget(...)" + +/// A collection of simultaneous bindings +type Bindings = Binding list + +/// A binding of a variable to an expression, as in a `let` binding or similar +/// -- val: The value being bound +/// -- expr: The expression to execute to get the value +/// -- debugPoint: The debug point for the binding +[] +type Binding = + | TBind of + var: Val * + expr: Expr * + debugPoint: DebugPointAtBinding + + /// The value being bound + member x.Var = (let (TBind(v, _, _)) = x in v) + + /// The expression the value is being bound to + member x.Expr = (let (TBind(_, e, _)) = x in e) + + /// The information about whether to emit a sequence point for the binding + member x.DebugPoint = (let (TBind(_, _, sp)) = x in sp) + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "TBind(%s, ...)" (x.Var.CompiledName None) + +/// Represents a reference to an active pattern element. The +/// integer indicates which choice in the target set is being selected by this item. +[] +type ActivePatternElemRef = + | APElemRef of + activePatternInfo: ActivePatternInfo * + activePatternVal: ValRef * + caseIndex: int * + isStructRetTy: bool + + /// Get the full information about the active pattern being referred to + member x.ActivePatternInfo = (let (APElemRef(info, _, _, _)) = x in info) + + /// Get a reference to the value for the active pattern being referred to + member x.ActivePatternVal = (let (APElemRef(_, vref, _, _)) = x in vref) + + /// Get a reference to the value for the active pattern being referred to + member x.IsStructReturn = (let (APElemRef(_, _, _, isStructRetTy)) = x in isStructRetTy) + + /// Get the index of the active pattern element within the overall active pattern + member x.CaseIndex = (let (APElemRef(_, _, n, _)) = x in n) + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "ActivePatternElemRef(...)" + +/// Records the "extra information" for a value compiled as a method (rather +/// than a closure or a local), including argument names, attributes etc. +[] +type ValReprInfo = + /// ValReprInfo (typars, args, result) + | ValReprInfo of + typars: TyparReprInfo list * + args: ArgReprInfo list list * + result: ArgReprInfo + + /// Get the extra information about the arguments for the value + member x.ArgInfos = (let (ValReprInfo(_, args, _)) = x in args) + + /// Get the number of curried arguments of the value + member x.NumCurriedArgs = (let (ValReprInfo(_, args, _)) = x in args.Length) + + /// Get the number of type parameters of the value + member x.NumTypars = (let (ValReprInfo(n, _, _)) = x in n.Length) + + /// Indicates if the value has no arguments - neither type parameters nor value arguments + member x.HasNoArgs = (let (ValReprInfo(n, args, _)) = x in n.IsEmpty && args.IsEmpty) + + /// Get the number of tupled arguments in each curried argument position + member x.AritiesOfArgs = (let (ValReprInfo(_, args, _)) = x in List.map List.length args) + + /// Get the kind of each type parameter + member x.KindsOfTypars = (let (ValReprInfo(n, _, _)) = x in n |> List.map (fun (TyparReprInfo(_, k)) -> k)) + + /// Get the total number of arguments + member x.TotalArgCount = + let (ValReprInfo(_, args, _)) = x + // This is List.sumBy List.length args + // We write this by hand as it can be a performance bottleneck in LinkagePartialKey + let rec loop (args: ArgReprInfo list list) acc = + match args with + | [] -> acc + | [] :: t -> loop t acc + | [_] :: t -> loop t (acc+1) + | (_ :: _ :: h) :: t -> loop t (acc + h.Length + 2) + loop args 0 + + member x.ArgNames = + Some [ for argtys in x.ArgInfos do for arginfo in argtys do match arginfo.Name with None -> () | Some nm -> nm.idText ] + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "ValReprInfo(...)" + +/// Records the "extra information" for an argument compiled as a real +/// method argument, specifically the argument name and attributes. +[] +type ArgReprInfo = + { + /// The attributes for the argument + // MUTABILITY: used when propagating signature attributes into the implementation. + mutable Attribs: Attribs + + /// The name for the argument at this position, if any + // MUTABILITY: used when propagating names of parameters from signature into the implementation. + mutable Name: Ident option + } + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "ArgReprInfo(...)" + +/// Records the extra metadata stored about typars for type parameters +/// compiled as "real" IL type parameters, specifically for values with +/// ValReprInfo. Any information here is propagated from signature through +/// to the compiled code. +type TyparReprInfo = TyparReprInfo of Ident * TyparKind + +type Typars = Typar list + +type Exprs = Expr list + +type Vals = Val list + +/// Represents an expression in the typed abstract syntax +[] +type Expr = + /// A constant expression. + | Const of + value: Const * + range: range * + constType: TType + + /// Reference a value. The flag is only relevant if the value is an object model member + /// and indicates base calls and special uses of object constructors. + | Val of + valRef: ValRef * + flags: ValUseFlag * + range: range + + /// Sequence expressions, used for "a;b", "let a = e in b;a" and "a then b" (the last an OO constructor). + | Sequential of + expr1: Expr * + expr2: Expr * + kind: SequentialOpKind * + debugPoint: DebugPointAtSequential * + range: range + + /// Lambda expressions. + + /// Why multiple vspecs? A Expr.Lambda taking multiple arguments really accepts a tuple. + /// But it is in a convenient form to be compile accepting multiple + /// arguments, e.g. if compiled as a toplevel static method. + | Lambda of + unique: Unique * + ctorThisValOpt: Val option * + baseValOpt: Val option * + valParams: Val list * + bodyExpr: Expr * + range: range * + overallType: TType + + /// Type lambdas. These are used for the r.h.s. of polymorphic 'let' bindings and + /// for expressions that implement first-class polymorphic values. + | TyLambda of + unique: Unique * + typeParams: Typars * + bodyExpr: Expr * + range: range * + overallType: TType + + /// Applications. + /// Applications combine type and term applications, and are normalized so + /// that sequential applications are combined, so "(f x y)" becomes "f [[x];[y]]". + /// The type attached to the function is the formal function type, used to ensure we don't build application + /// nodes that over-apply when instantiating at function types. + | App of + funcExpr: Expr * + formalType: TType * + typeArgs: TypeInst * + args: Exprs * + range: range + + /// Bind a recursive set of values. + | LetRec of + bindings: Bindings * + bodyExpr: Expr * + range: range * + frees: FreeVarsCache + + /// Bind a value. + | Let of + binding: Binding * + bodyExpr: Expr * + range: range * + frees: FreeVarsCache + + // Object expressions: A closure that implements an interface or a base type. + // The base object type might be a delegate type. + | Obj of + unique: Unique * + objTy: TType * (* <-- NOTE: specifies type parameters for base type *) + baseVal: Val option * + ctorCall: Expr * + overrides: ObjExprMethod list * + interfaceImpls: (TType * ObjExprMethod list) list * + range: range + + /// Matches are a more complicated form of "let" with multiple possible destinations + /// and possibly multiple ways to get to each destination. + /// The first range is that of the expression being matched, which is used + /// as the range for all the decision making and binding that happens during the decision tree + /// execution. + | Match of + debugPoint: DebugPointAtBinding * + inputRange: range * + decision: DecisionTree * + targets: DecisionTreeTarget array * + fullRange: range * + exprType: TType + + /// If we statically know some information then in many cases we can use a more optimized expression + /// This is primarily used by terms in the standard library, particularly those implementing overloaded + /// operators. + | StaticOptimization of + conditions: StaticOptimization list * + expr: Expr * + alternativeExpr: Expr * + range: range + + /// An intrinsic applied to some (strictly evaluated) arguments + /// A few of intrinsics (TOp_try, TOp.While, TOp.For) expect arguments kept in a normal form involving lambdas + | Op of + op: TOp * + typeArgs: TypeInst * + args: Exprs * + range: range + + /// Indicates the expression is a quoted expression tree. + /// + // MUTABILITY: this use of mutability is awkward and perhaps should be removed + | Quote of + quotedExpr: Expr * + quotationInfo: ((ILTypeRef list * TTypes * Exprs * ExprData) * (ILTypeRef list * TTypes * Exprs * ExprData)) option ref * + isFromQueryExpression: bool * + range: range * + quotedType: TType + + /// Used in quotation generation to indicate a witness argument, spliced into a quotation literal. + /// + /// For example: + /// + /// let inline f x = <@ sin x @> + /// + /// needs to pass a witness argument to `sin x`, captured from the surrounding context, for the witness-passing + /// version of the code. Thus the QuotationTranslation and IlxGen makes the generated code as follows: + /// + /// f(x) { return Deserialize(<@ sin _spliceHole @>, [| x |]) } + /// + /// f$W(witnessForSin, x) { return Deserialize(<@ sin$W _spliceHole1 _spliceHole2 @>, [| WitnessArg(witnessForSin), x |]) } + /// + /// where _spliceHole1 will be the location of the witness argument in the quotation data, and + /// witnessArg is the lambda for the witness + /// + | WitnessArg of + traitInfo: TraitConstraintInfo * + range: range + + /// Indicates a free choice of typars that arises due to + /// minimization of polymorphism at let-rec bindings. These are + /// resolved to a concrete instantiation on subsequent rewrites. + | TyChoose of + typeParams: Typars * + bodyExpr: Expr * + range: range + + /// An instance of a link node occurs for every use of a recursively bound variable. When type-checking + /// the recursive bindings a dummy expression is stored in the mutable reference cell. + /// After type checking the bindings this is replaced by a use of the variable, perhaps at an + /// appropriate type instantiation. These are immediately eliminated on subsequent rewrites. + | Link of Expr ref + + [] + member expr.DebugText = expr.ToDebugString(3) + + override expr.ToString() = expr.ToDebugString(3) + + member expr.ToDebugString(depth: int) = + if depth = 0 then ".." else + let depth = depth - 1 + match expr with + | Const (c, _, _) -> c.ToString() + | Val (v, _, _) -> v.LogicalName + | Sequential (e1, e2, _, _, _) -> "Sequential(" + e1.ToDebugString(depth) + ", " + e2.ToDebugString(depth) + ")" + | Lambda (_, _, _, vs, body, _, _) -> sprintf "Lambda(%+A, " vs + body.ToDebugString(depth) + ")" + | TyLambda (_, tps, body, _, _) -> sprintf "TyLambda(%+A, " tps + body.ToDebugString(depth) + ")" + | App (f, _, _, args, _) -> "App(" + f.ToDebugString(depth) + ", [" + String.concat ", " (args |> List.map (fun e -> e.ToDebugString(depth))) + "])" + | LetRec _ -> "LetRec(..)" + | Let (bind, body, _, _) -> "Let(" + bind.Var.DisplayName + ", " + bind.Expr.ToDebugString(depth) + ", " + body.ToDebugString(depth) + ")" + | Obj (_, _objTy, _, _, _, _, _) -> "Obj(..)" + | Match (_, _, _dt, _tgs, _, _) -> "Match(..)" + | StaticOptimization _ -> "StaticOptimization(..)" + | Op (op, _, args, _) -> "Op(" + op.ToString() + ", " + String.concat ", " (args |> List.map (fun e -> e.ToDebugString(depth))) + ")" + | Quote _ -> "Quote(..)" + | WitnessArg _ -> "WitnessArg(..)" + | TyChoose _ -> "TyChoose(..)" + | Link e -> "Link(" + e.Value.ToDebugString(depth) + ")" + +[] +type TOp = + + /// An operation representing the creation of a union value of the particular union case + | UnionCase of UnionCaseRef + + /// An operation representing the creation of an exception value using an F# exception declaration + | ExnConstr of TyconRef + + /// An operation representing the creation of a tuple value + | Tuple of TupInfo + + /// An operation representing the creation of an anonymous record + | AnonRecd of AnonRecdTypeInfo + + /// An operation representing the get of a property from an anonymous record + | AnonRecdGet of AnonRecdTypeInfo * int + + /// An operation representing the creation of an array value + | Array + + /// Constant byte arrays (used for parser tables and other embedded data) + | Bytes of byte[] + + /// Constant uint16 arrays (used for parser tables) + | UInt16s of uint16[] + + /// An operation representing a lambda-encoded while loop. The special while loop marker is used to mark compilations of 'foreach' expressions + | While of DebugPointAtWhile * SpecialWhileLoopMarker + + /// An operation representing a lambda-encoded for loop + | For of DebugPointAtFor * ForLoopStyle (* count up or down? *) + + /// An operation representing a lambda-encoded try/with + | TryWith of DebugPointAtTry * DebugPointAtWith + + /// An operation representing a lambda-encoded try/finally + | TryFinally of DebugPointAtTry * DebugPointAtFinally + + /// Construct a record or object-model value. The ValRef is for self-referential class constructors, otherwise + /// it indicates that we're in a constructor and the purpose of the expression is to + /// fill in the fields of a pre-created but uninitialized object, and to assign the initialized + /// version of the object into the optional mutable cell pointed to be the given value. + | Recd of RecordConstructionInfo * TyconRef + + /// An operation representing setting a record or class field + | ValFieldSet of RecdFieldRef + + /// An operation representing getting a record or class field + | ValFieldGet of RecdFieldRef + + /// An operation representing getting the address of a record field + | ValFieldGetAddr of RecdFieldRef * readonly: bool + + /// An operation representing getting an integer tag for a union value representing the union case number + | UnionCaseTagGet of TyconRef + + /// An operation representing a coercion that proves a union value is of a particular union case. This is not a test, its + /// simply added proof to enable us to generate verifiable code for field access on union types + | UnionCaseProof of UnionCaseRef + + /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case. + | UnionCaseFieldGet of UnionCaseRef * int + + /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case. + | UnionCaseFieldGetAddr of UnionCaseRef * int * readonly: bool + + /// An operation representing a field-get from a union value. The value is not assumed to have been proven to be of the corresponding union case. + | UnionCaseFieldSet of UnionCaseRef * int + + /// An operation representing a field-get from an F# exception value. + | ExnFieldGet of TyconRef * int + + /// An operation representing a field-set on an F# exception value. + | ExnFieldSet of TyconRef * int + + /// An operation representing a field-get from an F# tuple value. + | TupleFieldGet of TupInfo * int + + /// IL assembly code - type list are the types pushed on the stack + | ILAsm of + instrs: ILInstr list * + retTypes: TTypes + + /// Generate a ldflda on an 'a ref. + | RefAddrGet of bool + + /// Conversion node, compiled via type-directed translation or to box/unbox + | Coerce + + /// Represents a "rethrow" operation. May not be rebound, or used outside of try-finally, expecting a unit argument + | Reraise + + /// Used for state machine compilation + | Return + + /// Used for state machine compilation + | Goto of ILCodeLabel + + /// Used for state machine compilation + | Label of ILCodeLabel + + /// Pseudo method calls. This is used for overloaded operations like op_Addition. + | TraitCall of TraitConstraintInfo + + /// Operation nodes representing C-style operations on byrefs and mutable vals (l-values) + | LValueOp of LValueOperation * ValRef + + /// IL method calls. + /// isProperty -- used for quotation reflection, property getters & setters + /// noTailCall - DllImport? if so don't tailcall + /// retTypes -- the types of pushed values, if any + | ILCall of + isVirtual: bool * + isProtected: bool * + isStruct: bool * + isCtor: bool * + valUseFlag: ValUseFlag * + isProperty: bool * + noTailCall: bool * + ilMethRef: ILMethodRef * + enclTypeInst: TypeInst * + methInst: TypeInst * + retTypes: TTypes + + [] + member x.DebugText = x.ToString() + + override op.ToString() = + match op with + | UnionCase ucref -> "UnionCase(" + ucref.CaseName + ")" + | ExnConstr ecref -> "ExnConstr(" + ecref.LogicalName + ")" + | Tuple _tupinfo -> "Tuple" + | AnonRecd _anonInfo -> "AnonRecd(..)" + | AnonRecdGet _ -> "AnonRecdGet(..)" + | Array -> "NewArray" + | Bytes _ -> "Bytes(..)" + | UInt16s _ -> "UInt16s(..)" + | While _ -> "While" + | For _ -> "For" + | TryWith _ -> "TryWith" + | TryFinally _ -> "TryFinally" + | Recd (_, tcref) -> "Recd(" + tcref.LogicalName + ")" + | ValFieldSet rfref -> "ValFieldSet(" + rfref.FieldName + ")" + | ValFieldGet rfref -> "ValFieldGet(" + rfref.FieldName + ")" + | ValFieldGetAddr (rfref, _) -> "ValFieldGetAddr(" + rfref.FieldName + ",..)" + | UnionCaseTagGet tcref -> "UnionCaseTagGet(" + tcref.LogicalName + ")" + | UnionCaseProof ucref -> "UnionCaseProof(" + ucref.CaseName + ")" + | UnionCaseFieldGet (ucref, _) -> "UnionCaseFieldGet(" + ucref.CaseName + ",..)" + | UnionCaseFieldGetAddr (ucref, _, _) -> "UnionCaseFieldGetAddr(" + ucref.CaseName + ",..)" + | UnionCaseFieldSet (ucref, _) -> "UnionCaseFieldSet(" + ucref.CaseName + ",..)" + | ExnFieldGet (tcref, _) -> "ExnFieldGet(" + tcref.LogicalName + ",..)" + | ExnFieldSet (tcref, _) -> "ExnFieldSet(" + tcref.LogicalName + ",..)" + | TupleFieldGet _ -> "TupleFieldGet(..)" + | ILAsm _ -> "ILAsm(..)" + | RefAddrGet _ -> "RefAddrGet(..)" + | Coerce -> "Coerce" + | Reraise -> "Reraise" + | Return -> "Return" + | Goto n -> "Goto(" + string n + ")" + | Label n -> "Label(" + string n + ")" + | TraitCall info -> "TraitCall(" + info.MemberName + ")" + | LValueOp (op, vref) -> sprintf "%+A(%s)" op vref.LogicalName + | ILCall (_,_,_,_,_,_,_,ilMethRef,_,_,_) -> "ILCall(" + ilMethRef.ToString() + ",..)" + +/// Represents the kind of record construction operation. +type RecordConstructionInfo = + + /// We're in an explicit constructor. The purpose of the record expression is to + /// fill in the fields of a pre-created but uninitialized object + | RecdExprIsObjInit + + /// Normal record construction + | RecdExpr + +/// If this is Some ty then it indicates that a .NET 2.0 constrained call is required, with the given type as the +/// static type of the object argument. +type ConstrainedCallInfo = TType option + +/// Represents the kind of looping operation. +type SpecialWhileLoopMarker = + + | NoSpecialWhileLoopMarker + + /// Marks the compiled form of a 'for ... in ... do ' expression + | WhileLoopForCompiledForEachExprMarker + +/// Represents the kind of looping operation. +type ForLoopStyle = + /// Evaluate start and end once, loop up + | FSharpForLoopUp + + /// Evaluate start and end once, loop down + | FSharpForLoopDown + + /// Evaluate start once and end multiple times, loop up + | CSharpForLoopUp + +/// Indicates what kind of pointer operation this is. +type LValueOperation = + + /// In C syntax this is: &localv + | LAddrOf of readonly: bool + + /// In C syntax this is: *localv_ptr + | LByrefGet + + /// In C syntax this is: localv = e, note == *(&localv) = e == LAddrOf; LByrefSet + | LSet + + /// In C syntax this is: *localv_ptr = e + | LByrefSet + +/// Represents the kind of sequential operation, i.e. "normal" or "to a before returning b" +type SequentialOpKind = + /// a ; b + | NormalSeq + + /// let res = a in b;res + | ThenDoSeq + +/// Indicates how a value, function or member is being used at a particular usage point. +type ValUseFlag = + + /// Indicates a use of a value represents a call to a method that may require + /// a .NET 2.0 constrained call. A constrained call is only used for calls where + // the object argument is a value type or generic type, and the call is to a method + // on System.Object, System.ValueType, System.Enum or an interface methods. + | PossibleConstrainedCall of ty: TType + + /// A normal use of a value + | NormalValUse + + /// A call to a constructor, e.g. 'inherit C()' + | CtorValUsedAsSuperInit + + /// A call to a constructor, e.g. 'new C() = new C(3)' + | CtorValUsedAsSelfInit + + /// A call to a base method, e.g. 'base.OnPaint(args)' + | VSlotDirectCall + +/// Represents the kind of an F# core library static optimization construct +type StaticOptimization = + + /// Indicates the static optimization applies when a type equality holds + | TTyconEqualsTycon of ty1: TType * ty2: TType + + /// Indicates the static optimization applies when a type is a struct + | TTyconIsStruct of ty: TType + +/// A representation of a method in an object expression. +/// +/// TObjExprMethod(slotsig, attribs, methTyparsOfOverridingMethod, methodParams, methodBodyExpr, m) +[] +type ObjExprMethod = + + | TObjExprMethod of + slotSig: SlotSig * + attribs: Attribs * + methTyparsOfOverridingMethod: Typars * + methodParams: Val list list * + methodBodyExpr: Expr * + range: range + + member x.Id = let (TObjExprMethod(slotsig, _, _, _, _, m)) = x in mkSynId m slotsig.Name + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "TObjExprMethod(%s, ...)" x.Id.idText + +/// Represents an abstract method slot, or delegate signature. +/// +/// TSlotSig(methodName, declaringType, declaringTypeParameters, methodTypeParameters, slotParameters, returnTy) +[] +type SlotSig = + | TSlotSig of + methodName: string * + implementedType: TType * + classTypars: Typars * + methodTypars: Typars * + formalParams: SlotParam list list * + formalReturn: TType option + + /// The name of the method + member ss.Name = let (TSlotSig(nm, _, _, _, _, _)) = ss in nm + + /// The (instantiated) type which the slot is logically a part of + member ss.ImplementedType = let (TSlotSig(_, ty, _, _, _, _)) = ss in ty + + /// The class type parameters of the slot + member ss.ClassTypars = let (TSlotSig(_, _, ctps, _, _, _)) = ss in ctps + + /// The method type parameters of the slot + member ss.MethodTypars = let (TSlotSig(_, _, _, mtps, _, _)) = ss in mtps + + /// The formal parameters of the slot (regardless of the type or method instantiation) + member ss.FormalParams = let (TSlotSig(_, _, _, _, ps, _)) = ss in ps + + /// The formal return type of the slot (regardless of the type or method instantiation) + member ss.FormalReturnType = let (TSlotSig(_, _, _, _, _, rt)) = ss in rt + + [] + member x.DebugText = x.ToString() + + override ss.ToString() = sprintf "TSlotSig(%s, ...)" ss.Name + +/// Represents a parameter to an abstract method slot. +/// +/// TSlotParam(nm, ty, inFlag, outFlag, optionalFlag, attribs) +[] +type SlotParam = + | TSlotParam of + paramName: string option * + paramType: TType * + isIn: bool * + isOut: bool * + isOptional: bool * + attributes: Attribs + + member x.Type = let (TSlotParam(_, ty, _, _, _, _)) = x in ty + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TSlotParam(...)" + +/// A type for a module-or-namespace-fragment and the actual definition of the module-or-namespace-fragment +/// The first ModuleOrNamespaceType is the signature and is a binder. However the bindings are not used in the ModuleOrNamespaceExpr: it is only referenced from the 'outside' +/// is for use by FCS only to report the "hidden" contents of the assembly prior to applying the signature. +[] +type ModuleOrNamespaceExprWithSig = + | ModuleOrNamespaceExprWithSig of + moduleType: ModuleOrNamespaceType * + contents: ModuleOrNamespaceExpr * + range: range + + member x.Type = let (ModuleOrNamespaceExprWithSig(mtyp, _, _)) = x in mtyp + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "ModuleOrNamespaceExprWithSig(...)" + +/// Represents open declaration statement. +type OpenDeclaration = + { /// Syntax after 'open' as it's presented in source code. + Target: SynOpenDeclTarget + + /// Full range of the open declaration. + Range: range option + + /// Modules or namespaces which is opened with this declaration. + Modules: ModuleOrNamespaceRef list + + /// Types whose static content is opened with this declaration. + Types: TType list + + /// Scope in which open declaration is visible. + AppliedScope: range + + /// If it's `namespace Xxx.Yyy` declaration. + IsOwnNamespace: bool + } + + /// Create a new instance of OpenDeclaration. + static member Create(target: SynOpenDeclTarget, modules: ModuleOrNamespaceRef list, types: TType list, appliedScope: range, isOwnNamespace: bool) = + { Target = target + Range = + match target with + | SynOpenDeclTarget.ModuleOrNamespace (range=m) + | SynOpenDeclTarget.Type (range=m) -> Some m + Types = types + Modules = modules + AppliedScope = appliedScope + IsOwnNamespace = isOwnNamespace } + +/// The contents of a module-or-namespace-fragment definition +[] +type ModuleOrNamespaceExpr = + /// Indicates the module is a module with a signature + | TMAbstract of moduleOrNamespaceExprWithSig: ModuleOrNamespaceExprWithSig + + /// Indicates the module fragment is made of several module fragments in succession + | TMDefs of moduleOrNamespaceExprs: ModuleOrNamespaceExpr list + + /// Indicates the given 'open' declarations are active + | TMDefOpens of openDecls: OpenDeclaration list + + /// Indicates the module fragment is a 'let' definition + | TMDefLet of binding: Binding * range: range + + /// Indicates the module fragment is an evaluation of expression for side-effects + | TMDefDo of expr: Expr * range: range + + /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules + | TMDefRec of isRec: bool * opens: OpenDeclaration list * tycons: Tycon list * moduleOrNamespaceBindings: ModuleOrNamespaceBinding list * range: range + + // %+A formatting is used, so this is not needed + //[] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "%+A" x + +/// A named module-or-namespace-fragment definition +[] +type ModuleOrNamespaceBinding = + + | Binding of binding: Binding + + | Module of + /// This ModuleOrNamespace that represents the compilation of a module as a class. + /// The same set of tycons etc. are bound in the ModuleOrNamespace as in the ModuleOrNamespaceExpr + moduleOrNamespace: ModuleOrNamespace * + /// This is the body of the module/namespace + moduleOrNamespaceExpr: ModuleOrNamespaceExpr + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "ModuleOrNamespaceBinding(...)" + +/// Represents a complete typechecked implementation file, including its typechecked signature if any. +/// +/// TImplFile (qualifiedNameOfFile, pragmas, implementationExpressionWithSignature, hasExplicitEntryPoint, isScript, anonRecdTypeInfo) +[] +type TypedImplFile = + | TImplFile of + qualifiedNameOfFile: QualifiedNameOfFile * + pragmas: ScopedPragma list * + implementationExpressionWithSignature: ModuleOrNamespaceExprWithSig * + hasExplicitEntryPoint: bool * + isScript: bool * + anonRecdTypeInfo: StampMap + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TImplFile (...)" + +/// Represents a complete typechecked assembly, made up of multiple implementation files. +[] +type TypedImplFileAfterOptimization = + { ImplFile: TypedImplFile + OptimizeDuringCodeGen: bool -> Expr -> Expr } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TypedImplFileAfterOptimization(...)" + +/// Represents a complete typechecked assembly, made up of multiple implementation files. +[] +type TypedAssemblyAfterOptimization = + | TypedAssemblyAfterOptimization of TypedImplFileAfterOptimization list + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "TypedAssemblyAfterOptimization(...)" + +[] +type CcuData = + { + /// Holds the filename for the DLL, if any + FileName: string option + + /// Holds the data indicating how this assembly/module is referenced from the code being compiled. + ILScopeRef: ILScopeRef + + /// A unique stamp for this DLL + Stamp: Stamp + + /// The fully qualified assembly reference string to refer to this assembly. This is persisted in quotations + QualifiedName: string option + + /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) + SourceCodeDirectory: string + + /// Indicates that this DLL was compiled using the F# compiler and has F# metadata + IsFSharp: bool + +#if !NO_EXTENSIONTYPING + /// Is the CCu an assembly injected by a type provider + IsProviderGenerated: bool + + /// Triggered when the contents of the CCU are invalidated + InvalidateEvent: IEvent + + /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality + /// logic in tastops.fs + ImportProvidedType: Tainted -> TType + +#endif + /// Indicates that this DLL uses pre-F#-4.0 quotation literals somewhere. This is used to implement a restriction on static linking + mutable UsesFSharp20PlusQuotations: bool + + /// A handle to the full specification of the contents of the module contained in this ccu + // NOTE: may contain transient state during typechecking + mutable Contents: ModuleOrNamespace + + /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality + /// logic in tastops.fs + TryGetILModuleDef: unit -> ILModuleDef option + + /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality + /// logic in tastops.fs + MemberSignatureEquality: TType -> TType -> bool + + /// The table of .NET CLI type forwarders for this assembly + TypeForwarders: CcuTypeForwarderTable + + XmlDocumentationInfo: XmlDocumentationInfo option } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = sprintf "CcuData(%A)" x.FileName + +/// Represents a table of .NET CLI type forwarders for an assembly +type CcuTypeForwarderTable = Map> + +type CcuReference = string // ILAssemblyRef + +/// A relinkable handle to the contents of a compilation unit. Relinking is performed by mutation. +// +/// A compilation unit is, more or less, the new material created in one +/// invocation of the compiler. Due to static linking assemblies may hold more +/// than one compilation unit (i.e. when two assemblies are merged into a compilation +/// the resulting assembly will contain 3 CUs). Compilation units are also created for referenced +/// .NET assemblies. +/// +/// References to items such as type constructors are via +/// cross-compilation-unit thunks, which directly reference the data structures that define +/// these modules. Thus, when saving out values to disk we only wish +/// to save out the "current" part of the term graph. When reading values +/// back in we "fixup" the links to previously referenced modules. +/// +/// All non-local accesses to the data structures are mediated +/// by ccu-thunks. Ultimately, a ccu-thunk is either a (named) element of +/// the data structure, or it is a delayed fixup, i.e. an invalid dangling +/// reference that has not had an appropriate fixup applied. +[] +type CcuThunk = + { + /// ccu.target is null when a reference is missing in the transitive closure of static references that + /// may potentially be required for the metadata of referenced DLLs. + mutable target: CcuData + name: CcuReference + } + + /// Dereference the asssembly reference + member ccu.Deref = + if isNull (ccu.target :> obj) then + raise(UnresolvedReferenceNoRange ccu.name) + ccu.target + + /// Indicates if this assembly reference is unresolved + member ccu.IsUnresolvedReference = isNull (ccu.target :> obj) + + /// Ensure the ccu is derefable in advance. Supply a path to attach to any resulting error message. + member ccu.EnsureDerefable(requiringPath: string[]) = + if ccu.IsUnresolvedReference then + let path = String.Join(".", requiringPath) + raise(UnresolvedPathReferenceNoRange(ccu.name, path)) + + /// Indicates that this DLL uses F# 2.0+ quotation literals somewhere. This is used to implement a restriction on static linking. + member ccu.UsesFSharp20PlusQuotations + with get() = ccu.Deref.UsesFSharp20PlusQuotations + and set v = ccu.Deref.UsesFSharp20PlusQuotations <- v + + /// The short name of the asssembly being referenced + member ccu.AssemblyName = ccu.name + + /// Holds the data indicating how this assembly/module is referenced from the code being compiled. + member ccu.ILScopeRef = ccu.Deref.ILScopeRef + + /// A unique stamp for this assembly + member ccu.Stamp = ccu.Deref.Stamp + + /// Holds the filename for the assembly, if any + member ccu.FileName = ccu.Deref.FileName + + /// Try to get the .NET Assembly, if known. May not be present for `IsFSharp` for + /// in-memory cross-project references + member ccu.TryGetILModuleDef() = ccu.Deref.TryGetILModuleDef() + +#if !NO_EXTENSIONTYPING + /// Is this a provider-injected assembly + member ccu.IsProviderGenerated = ccu.Deref.IsProviderGenerated + + /// Used to make 'forward' calls into the loader during linking + member ccu.ImportProvidedType ty: TType = ccu.Deref.ImportProvidedType ty +#endif + + /// The fully qualified assembly reference string to refer to this assembly. This is persisted in quotations + member ccu.QualifiedName = ccu.Deref.QualifiedName + + /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) + member ccu.SourceCodeDirectory = ccu.Deref.SourceCodeDirectory + + /// Indicates that this DLL was compiled using the F# compiler and has F# metadata + member ccu.IsFSharp = ccu.Deref.IsFSharp + + /// A handle to the full specification of the contents of the module contained in this ccu + // NOTE: may contain transient state during typechecking + member ccu.Contents = ccu.Deref.Contents + + /// The table of type forwarders for this assembly + member ccu.TypeForwarders: Map> = ccu.Deref.TypeForwarders + + /// The table of modules and namespaces at the "root" of the assembly + member ccu.RootModulesAndNamespaces = ccu.Contents.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions + + /// The table of type definitions at the "root" of the assembly + member ccu.RootTypeAndExceptionDefinitions = ccu.Contents.ModuleOrNamespaceType.TypeAndExceptionDefinitions + + /// Create a CCU with the given name and contents + static member Create(nm, x) = + { target = x + name = nm } + + /// Create a CCU with the given name but where the contents have not yet been specified + static member CreateDelayed nm = + { target = Unchecked.defaultof<_> + name = nm } + + /// Fixup a CCU to have the given contents + member x.Fixup(avail: CcuThunk) = + + match box x.target with + | null -> () + | _ -> + // In the IDE we tolerate a double-fixup of FSHarp.Core when editing the FSharp.Core project itself + if x.AssemblyName <> "FSharp.Core" then + errorR(Failure("internal error: Fixup: the ccu thunk for assembly "+x.AssemblyName+" not delayed!")) + + assert (avail.AssemblyName = x.AssemblyName) + x.target <- + match box avail.target with + | null -> error(Failure("internal error: ccu thunk '"+avail.name+"' not fixed up!")) + | _ -> avail.target + + /// Try to resolve a path into the CCU by referencing the .NET/CLI type forwarder table of the CCU + member ccu.TryForward(nlpath: string[], item: string) : EntityRef option = + ccu.EnsureDerefable nlpath + let key = nlpath, item + match ccu.TypeForwarders.TryGetValue key with + | true, entity -> Some(entity.Force()) + | _ -> None + + /// Used to make forward calls into the type/assembly loader when comparing member signatures during linking + member ccu.MemberSignatureEquality(ty1: TType, ty2: TType) = + ccu.Deref.MemberSignatureEquality ty1 ty2 + + [] + member x.DebugText = x.ToString() + + /// Used at the end of comppiling an assembly to get a frozen, final stable CCU + /// for the compilation which we no longer mutate. + member x.CloneWithFinalizedContents(ccuContents) = + { x with target = { x.target with Contents = ccuContents } } + + override ccu.ToString() = ccu.AssemblyName + +/// The result of attempting to resolve an assembly name to a full ccu. +/// UnresolvedCcu will contain the name of the assembly that could not be resolved. +[] +type CcuResolutionResult = + + | ResolvedCcu of CcuThunk + + | UnresolvedCcu of string + + [] + member x.DebugText = x.ToString() + + override x.ToString() = match x with ResolvedCcu ccu -> ccu.ToString() | UnresolvedCcu s -> "unresolved " + s + +/// Represents the information saved in the assembly signature data resource for an F# assembly +[] +type PickledCcuInfo = + { + mspec: ModuleOrNamespace + + compileTimeWorkingDir: string + + usesQuotations: bool + } + + [] + member x.DebugText = x.ToString() + + override _.ToString() = "PickledCcuInfo(...)" + + +/// Represents a set of free local values. Computed and cached by later phases +/// (never cached type checking). Cached in expressions. Not pickled. +type FreeLocals = Zset + +/// Represents a set of free type parameters. Computed and cached by later phases +/// (never cached type checking). Cached in expressions. Not pickled. +type FreeTypars = Zset + +/// Represents a set of 'free' named type definitions. Used to collect the named type definitions referred to +/// from a type or expression. Computed and cached by later phases (never cached type checking). Cached +/// in expressions. Not pickled. +type FreeTycons = Zset + +/// Represents a set of 'free' record field definitions. Used to collect the record field definitions referred to +/// from an expression. +type FreeRecdFields = Zset + +/// Represents a set of 'free' union cases. Used to collect the union cases referred to from an expression. +type FreeUnionCases = Zset + +/// Represents a set of 'free' type-related elements, including named types, trait solutions, union cases and +/// record fields. +[] +type FreeTyvars = + { + /// The summary of locally defined type definitions used in the expression. These may be made private by a signature + /// and we have to check various conditions associated with that. + FreeTycons: FreeTycons + + /// The summary of values used as trait solutions + FreeTraitSolutions: FreeLocals + + /// The summary of type parameters used in the expression. These may not escape the enclosing generic construct + /// and we have to check various conditions associated with that. + FreeTypars: FreeTypars + } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "FreeTyvars(...)" + +/// Represents an amortized computation of the free variables in an expression +type FreeVarsCache = FreeVars cache + +/// Represents the set of free variables in an expression +[] +type FreeVars = + { + /// The summary of locally defined variables used in the expression. These may be hidden at let bindings etc. + /// or made private by a signature or marked 'internal' or 'private', and we have to check various conditions associated with that. + FreeLocals: FreeLocals + + /// Indicates if the expression contains a call to a protected member or a base call. + /// Calls to protected members and direct calls to super classes can't escape, also code can't be inlined + UsesMethodLocalConstructs: bool + + /// Indicates if the expression contains a call to rethrow that is not bound under a (try-)with branch. + /// Rethrow may only occur in such locations. + UsesUnboundRethrow: bool + + /// The summary of locally defined tycon representations used in the expression. These may be made private by a signature + /// or marked 'internal' or 'private' and we have to check various conditions associated with that. + FreeLocalTyconReprs: FreeTycons + + /// The summary of fields used in the expression. These may be made private by a signature + /// or marked 'internal' or 'private' and we have to check various conditions associated with that. + FreeRecdFields: FreeRecdFields + + /// The summary of union constructors used in the expression. These may be + /// marked 'internal' or 'private' and we have to check various conditions associated with that. + FreeUnionCases: FreeUnionCases + + /// See FreeTyvars above. + FreeTyvars: FreeTyvars } + + [] + member x.DebugText = x.ToString() + + override x.ToString() = "FreeVars(...)" + +/// A set of static methods for constructing types. +type Construct() = + + static let taccessPublic = TAccess [] + + /// Key a Tycon or TyconRef by decoded name + static member KeyTyconByDecodedName<'T> (nm: string) (x: 'T) : KeyValuePair = + KeyValuePair(DecodeGenericTypeName nm, x) + + /// Key a Tycon or TyconRef by both mangled and demangled name. + /// Generic types can be accessed either by 'List' or 'List`1'. + /// This lists both keys. + static member KeyTyconByAccessNames<'T> (nm: string) (x: 'T) : KeyValuePair[] = + match TryDemangleGenericNameAndPos nm with + | ValueSome pos -> + let dnm = DemangleGenericTypeNameWithPos pos nm + [| KeyValuePair(nm, x); KeyValuePair(dnm, x) |] + | _ -> + [| KeyValuePair(nm, x) |] + + /// Create a new node for the contents of a module or namespace + static member NewModuleOrNamespaceType mkind tycons vals = + ModuleOrNamespaceType(mkind, QueueList.ofList vals, QueueList.ofList tycons) + + /// Create a new node for an empty module or namespace contents + static member NewEmptyModuleOrNamespaceType mkind = + Construct.NewModuleOrNamespaceType mkind [] [] + +#if !NO_EXTENSIONTYPING + + /// Create a new node for the representation information for a provided type definition + static member NewProvidedTyconRepr(resolutionEnvironment, st: Tainted, importProvidedType, isSuppressRelocate, m) = + + let isErased = st.PUntaint((fun st -> st.IsErased), m) + + let lazyBaseTy = + LazyWithContext.Create + ((fun (m, objTy) -> + let baseSystemTy = st.PApplyOption((fun st -> match st.BaseType with null -> None | ty -> Some ty), m) + match baseSystemTy with + | None -> objTy + | Some t -> importProvidedType t), + findOriginalException) + + TProvidedTypeRepr + { ResolutionEnvironment=resolutionEnvironment + ProvidedType=st + LazyBaseType=lazyBaseTy + UnderlyingTypeOfEnum = (fun () -> importProvidedType (st.PApply((fun st -> st.GetEnumUnderlyingType()), m))) + IsDelegate = (fun () -> st.PUntaint((fun st -> + let baseType = st.BaseType + match baseType with + | null -> false + | x when x.IsGenericType -> false + | x when x.DeclaringType <> null -> false + | x -> x.FullName = "System.Delegate" || x.FullName = "System.MulticastDelegate"), m)) + IsEnum = st.PUntaint((fun st -> st.IsEnum), m) + IsStructOrEnum = st.PUntaint((fun st -> st.IsValueType || st.IsEnum), m) + IsInterface = st.PUntaint((fun st -> st.IsInterface), m) + IsSealed = st.PUntaint((fun st -> st.IsSealed), m) + IsAbstract = st.PUntaint((fun st -> st.IsAbstract), m) + IsClass = st.PUntaint((fun st -> st.IsClass), m) + IsErased = isErased + IsSuppressRelocate = isSuppressRelocate } + + /// Create a new entity node for a provided type definition + static member NewProvidedTycon(resolutionEnvironment, st: Tainted, importProvidedType, isSuppressRelocate, m, ?access, ?cpath) = + let stamp = newStamp() + let name = st.PUntaint((fun st -> st.Name), m) + let id = ident (name, m) + let kind = + let isMeasure = + st.PApplyWithProvider((fun (st, provider) -> + ignore provider + st.IsMeasure), m) + .PUntaintNoFailure(Operators.id) + if isMeasure then TyparKind.Measure else TyparKind.Type + + let access = + match access with + | Some a -> a + | None -> TAccess [] + let cpath = + match cpath with + | None -> + let ilScopeRef = st.TypeProviderAssemblyRef + let enclosingName = GetFSharpPathToProvidedType(st, m) + CompPath(ilScopeRef, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace)) + | Some p -> p + let pubpath = cpath.NestedPublicPath id + + let repr = Construct.NewProvidedTyconRepr(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) + + Tycon.New "tycon" + { entity_stamp=stamp + entity_logical_name=name + entity_range=m + entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) + entity_attribs=[] // fetched on demand via est.fs API + entity_typars= LazyWithContext.NotLazy [] + entity_tycon_repr = repr + entity_tycon_tcaug=TyconAugmentation.Create() + entity_modul_contents = MaybeLazy.Lazy (lazy ModuleOrNamespaceType(Namespace, QueueList.ofList [], QueueList.ofList [])) + // Generated types get internal accessibility + entity_pubpath = Some pubpath + entity_cpath = Some cpath + entity_il_repr_cache = newCache() + entity_opt_data = + match kind, access with + | TyparKind.Type, TAccess [] -> None + | _ -> Some { Entity.NewEmptyEntityOptData() with + entity_kind = kind + entity_accessibility = access } } +#endif + + /// Create a new entity node for a module or namespace + static member NewModuleOrNamespace cpath access (id: Ident) (xml: XmlDoc) attribs mtype = + let stamp = newStamp() + // Put the module suffix on if needed + Tycon.New "mspec" + { entity_logical_name=id.idText + entity_range = id.idRange + entity_stamp=stamp + entity_modul_contents = mtype + entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=true, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) + entity_typars=LazyWithContext.NotLazy [] + entity_tycon_repr = TNoRepr + entity_tycon_tcaug=TyconAugmentation.Create() + entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) + entity_cpath=cpath + entity_attribs=attribs + entity_il_repr_cache = newCache() + entity_opt_data = + match xml, access with + | doc, TAccess [] when doc.IsEmpty -> None + | _ -> Some { Entity.NewEmptyEntityOptData() with + entity_xmldoc = xml + entity_tycon_repr_accessibility = access + entity_accessibility = access } } + + /// Create a new unfilled cache for free variable calculations + static member NewFreeVarsCache() = newCache () + + /// Create the field tables for a record or class type + static member MakeRecdFieldsTable ucs: TyconRecdFields = + { FieldsByIndex = Array.ofList ucs + FieldsByName = ucs |> NameMap.ofKeyedList (fun rfld -> rfld.LogicalName) } + + /// Create the union case tables for a union type + static member MakeUnionCases ucs: TyconUnionData = + { CasesTable = + { CasesByIndex = Array.ofList ucs + CasesByName = NameMap.ofKeyedList (fun uc -> uc.LogicalName) ucs } + CompiledRepresentation=newCache() } + + /// Create a node for a union type + static member MakeUnionRepr ucs = TFSharpUnionRepr (Construct.MakeUnionCases ucs) + + /// Create a new type parameter node + static member NewTypar (kind, rigid, SynTypar(id, staticReq, isCompGen), isFromError, dynamicReq, attribs, eqDep, compDep) = + Typar.New + { typar_id = id + typar_stamp = newStamp() + typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep) + typar_solution = None + typar_astype = Unchecked.defaultof<_> + typar_opt_data = + match attribs with + | [] -> None + | _ -> Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } } + + /// Create a new type parameter node for a declared type parameter + static member NewRigidTypar nm m = + Construct.NewTypar (TyparKind.Type, TyparRigidity.Rigid, SynTypar(mkSynId m nm, TyparStaticReq.None, true), false, TyparDynamicReq.Yes, [], false, false) + + /// Create a new union case node + static member NewUnionCase id tys rty attribs docOption access: UnionCase = + { Id=id + XmlDoc=docOption + XmlDocSig="" + Accessibility=access + FieldTable = Construct.MakeRecdFieldsTable tys + ReturnType = rty + Attribs=attribs + OtherRangeOpt = None } + + /// Create a new TAST Entity node for an F# exception definition + static member NewExn cpath (id: Ident) access repr attribs (doc: XmlDoc) = + Tycon.New "exnc" + { entity_stamp=newStamp() + entity_attribs=attribs + entity_logical_name=id.idText + entity_range=id.idRange + entity_tycon_tcaug=TyconAugmentation.Create() + entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) + entity_modul_contents = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType) + entity_cpath= cpath + entity_typars=LazyWithContext.NotLazy [] + entity_tycon_repr = TNoRepr + entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) + entity_il_repr_cache= newCache() + entity_opt_data = + match doc, access, repr with + | doc, TAccess [], TExnNone when doc.IsEmpty -> None + | _ -> Some { Entity.NewEmptyEntityOptData() with entity_xmldoc = doc; entity_accessibility = access; entity_tycon_repr_accessibility = access; entity_exn_info = repr } } + + /// Create a new TAST RecdField node for an F# class, struct or record field + static member NewRecdField stat konst id nameGenerated ty isMutable isVolatile pattribs fattribs docOption access secret = + { rfield_mutable=isMutable + rfield_pattribs=pattribs + rfield_fattribs=fattribs + rfield_type=ty + rfield_static=stat + rfield_volatile=isVolatile + rfield_const=konst + rfield_access = access + rfield_secret = secret + rfield_xmldoc = docOption + rfield_xmldocsig = "" + rfield_id=id + rfield_name_generated = nameGenerated + rfield_other_range = None } + + + /// Create a new type definition node + static member NewTycon (cpath, nm, m, access, reprAccess, kind, typars, doc: XmlDoc, usesPrefixDisplay, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, mtyp) = + let stamp = newStamp() + Tycon.New "tycon" + { entity_stamp=stamp + entity_logical_name=nm + entity_range=m + entity_flags=EntityFlags(usesPrefixDisplay=usesPrefixDisplay, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=preEstablishedHasDefaultCtor, hasSelfReferentialCtor=hasSelfReferentialCtor, isStructRecordOrUnionType=false) + entity_attribs=[] // fixed up after + entity_typars=typars + entity_tycon_repr = TNoRepr + entity_tycon_tcaug=TyconAugmentation.Create() + entity_modul_contents = mtyp + entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath (mkSynId m nm)) + entity_cpath = cpath + entity_il_repr_cache = newCache() + entity_opt_data = + match kind, doc, reprAccess, access with + | TyparKind.Type, doc, TAccess [], TAccess [] when doc.IsEmpty -> None + | _ -> Some { Entity.NewEmptyEntityOptData() with entity_kind = kind; entity_xmldoc = doc; entity_tycon_repr_accessibility = reprAccess; entity_accessibility=access } } + + /// Create a new type definition node for a .NET type definition + static member NewILTycon nlpath (nm, m) tps (scoref: ILScopeRef, enc, tdef: ILTypeDef) mtyp = + let tycon = Construct.NewTycon(nlpath, nm, m, taccessPublic, taccessPublic, TyparKind.Type, tps, XmlDoc.Empty, true, false, false, mtyp) + + tycon.entity_tycon_repr <- TILObjectRepr (TILObjectReprData (scoref, enc, tdef)) + tycon.TypeContents.tcaug_closed <- true + tycon + + /// Create a new Val node + static member NewVal + (logicalName: string, m: range, compiledName, ty, isMutable, isCompGen, arity, access, + recValInfo, specialRepr, baseOrThis, attribs, inlineInfo, doc: XmlDoc, isModuleOrMemberBinding, + isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal, + konst, actualParent) : Val = + + let stamp = newStamp() + Val.New { + val_stamp = stamp + val_logical_name = logicalName + val_range = m + val_flags = ValFlags(recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal) + val_type = ty + val_opt_data = + match compiledName, arity, konst, access, doc, specialRepr, actualParent, attribs with + | None, None, None, TAccess [], doc, None, ParentNone, [] when doc.IsEmpty -> None + | _ -> + Some { Val.NewEmptyValOptData() with + val_compiled_name = (match compiledName with Some v when v <> logicalName -> compiledName | _ -> None) + val_repr_info = arity + val_const = konst + val_access = access + val_xmldoc = doc + val_member_info = specialRepr + val_declaring_entity = actualParent + val_attribs = attribs } + } + + /// Create the new contents of an overall assembly + static member NewCcuContents sref m nm mty = + Construct.NewModuleOrNamespace (Some(CompPath(sref, []))) taccessPublic (ident(nm, m)) XmlDoc.Empty [] (MaybeLazy.Strict mty) + + /// Create a tycon based on an existing one using the function 'f'. + /// We require that we be given the new parent for the new tycon. + /// We pass the new tycon to 'f' in case it needs to reparent the + /// contents of the tycon. + static member NewModifiedTycon f (orig: Tycon) = + let data = { orig with entity_stamp = newStamp() } + Tycon.New "NewModifiedTycon" (f data) + + /// Create a module Tycon based on an existing one using the function 'f'. + /// We require that we be given the parent for the new module. + /// We pass the new module to 'f' in case it needs to reparent the + /// contents of the module. + static member NewModifiedModuleOrNamespace f orig = + orig |> Construct.NewModifiedTycon (fun d -> + { d with entity_modul_contents = MaybeLazy.Strict (f (d.entity_modul_contents.Force())) }) + + /// Create a Val based on an existing one using the function 'f'. + /// We require that we be given the parent for the new Val. + static member NewModifiedVal f (orig: Val) = + let stamp = newStamp() + let data' = f { orig with val_stamp=stamp } + Val.New data' + + /// Create a new module or namespace node by cloning an existing one + static member NewClonedModuleOrNamespace orig = + Construct.NewModifiedModuleOrNamespace id orig + + /// Create a new type definition node by cloning an existing one + static member NewClonedTycon orig = + Construct.NewModifiedTycon id orig + +#if !NO_EXTENSIONTYPING + /// Compute the definition location of a provided item + static member ComputeDefinitionLocationOfProvidedItem<'T when 'T :> IProvidedCustomAttributeProvider> (p: Tainted<'T>) : range option = + let attrs = p.PUntaintNoFailure(fun x -> x.GetDefinitionLocationAttribute(p.TypeProvider.PUntaintNoFailure id)) + match attrs with + | None | Some (null, _, _) -> None + | Some (filePath, line, column) -> + // Coordinates from type provider are 1-based for lines and columns + // Coordinates internally in the F# compiler are 1-based for lines and 0-based for columns + let pos = Position.mkPos line (max 0 (column - 1)) + mkRange filePath pos pos |> Some +#endif + diff --git a/src/fsharp/TypedTreeBasics.fs b/src/fsharp/TypedTreeBasics.fs new file mode 100644 index 00000000000..fe730b9aeba --- /dev/null +++ b/src/fsharp/TypedTreeBasics.fs @@ -0,0 +1,466 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +//------------------------------------------------------------------------- +// Defines the typed abstract syntax trees used throughout the F# compiler. +//------------------------------------------------------------------------- + +module internal FSharp.Compiler.TypedTreeBasics + +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.Text +open FSharp.Compiler.Syntax +open FSharp.Compiler.TypedTree + +#if DEBUG +assert (sizeof = 8) +assert (sizeof = 8) +assert (sizeof = 4) +#endif + +let getNameOfScopeRef sref = + match sref with + | ILScopeRef.Local -> "" + | ILScopeRef.Module mref -> mref.Name + | ILScopeRef.Assembly aref -> aref.Name + | ILScopeRef.PrimaryAssembly -> "" + +/// Metadata on values (names of arguments etc. +module ValReprInfo = + + let unnamedTopArg1: ArgReprInfo = { Attribs=[]; Name=None } + + let unnamedTopArg = [unnamedTopArg1] + + let unitArgData: ArgReprInfo list list = [[]] + + let unnamedRetVal: ArgReprInfo = { Attribs = []; Name=None } + + let selfMetadata = unnamedTopArg + + let emptyValData = ValReprInfo([], [], unnamedRetVal) + + let InferTyparInfo (tps: Typar list) = tps |> List.map (fun tp -> TyparReprInfo(tp.Id, tp.Kind)) + + let InferArgReprInfo (v: Val) : ArgReprInfo = { Attribs = []; Name= Some v.Id } + + let InferArgReprInfos (vs: Val list list) = ValReprInfo([], List.mapSquared InferArgReprInfo vs, unnamedRetVal) + + let HasNoArgs (ValReprInfo(n, args, _)) = n.IsEmpty && args.IsEmpty + +//--------------------------------------------------------------------------- +// Basic properties via functions (old style) +//--------------------------------------------------------------------------- + +let typeOfVal (v: Val) = v.Type + +let typesOfVals (v: Val list) = v |> List.map (fun v -> v.Type) + +let nameOfVal (v: Val) = v.LogicalName + +let arityOfVal (v: Val) = (match v.ValReprInfo with None -> ValReprInfo.emptyValData | Some arities -> arities) + +let tupInfoRef = TupInfo.Const false + +let tupInfoStruct = TupInfo.Const true + +let mkTupInfo b = if b then tupInfoStruct else tupInfoRef + +let structnessDefault = false + +let mkRawRefTupleTy tys = TType_tuple (tupInfoRef, tys) + +let mkRawStructTupleTy tys = TType_tuple (tupInfoStruct, tys) + +//--------------------------------------------------------------------------- +// Aggregate operations to help transform the components that +// make up the entire compilation unit +//--------------------------------------------------------------------------- + +let mapTImplFile f (TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = + TImplFile (fragName, pragmas, f moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes) + +let mapAccImplFile f z (TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = + let moduleExpr, z = f z moduleExpr + TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes), z + +let foldTImplFile f z (TImplFile (_, _, moduleExpr, _, _, _)) = f z moduleExpr + +//--------------------------------------------------------------------------- +// Equality relations on locally defined things +//--------------------------------------------------------------------------- + +let typarEq (lv1: Typar) (lv2: Typar) = (lv1.Stamp = lv2.Stamp) + +/// Equality on type variables, implemented as reference equality. This should be equivalent to using typarEq. +let typarRefEq (tp1: Typar) (tp2: Typar) = (tp1 === tp2) + +/// Equality on value specs, implemented as reference equality +let valEq (lv1: Val) (lv2: Val) = (lv1 === lv2) + +/// Equality on CCU references, implemented as reference equality except when unresolved +let ccuEq (mv1: CcuThunk) (mv2: CcuThunk) = + (mv1 === mv2) || + (if mv1.IsUnresolvedReference || mv2.IsUnresolvedReference then + mv1.AssemblyName = mv2.AssemblyName + else + mv1.Contents === mv2.Contents) + +/// For dereferencing in the middle of a pattern +let (|ValDeref|) (vr: ValRef) = vr.Deref + +//-------------------------------------------------------------------------- +// Make references to TAST items +//-------------------------------------------------------------------------- + +let mkRecdFieldRef tcref f = RecdFieldRef(tcref, f) + +let mkUnionCaseRef tcref c = UnionCaseRef(tcref, c) + +let ERefLocal x: EntityRef = { binding=x; nlr=Unchecked.defaultof<_> } + +let ERefNonLocal x: EntityRef = { binding=Unchecked.defaultof<_>; nlr=x } + +let ERefNonLocalPreResolved x xref: EntityRef = { binding=x; nlr=xref } + +let (|ERefLocal|ERefNonLocal|) (x: EntityRef) = + match box x.nlr with + | null -> ERefLocal x.binding + | _ -> ERefNonLocal x.nlr + +//-------------------------------------------------------------------------- +// Construct local references +//-------------------------------------------------------------------------- + +let mkLocalTyconRef x = ERefLocal x + +let mkNonLocalEntityRef ccu mp = NonLocalEntityRef(ccu, mp) + +let mkNestedNonLocalEntityRef (nleref: NonLocalEntityRef) id = + mkNonLocalEntityRef nleref.Ccu (Array.append nleref.Path [| id |]) + +let mkNonLocalTyconRef nleref id = ERefNonLocal (mkNestedNonLocalEntityRef nleref id) + +let mkNonLocalTyconRefPreResolved x nleref id = + ERefNonLocalPreResolved x (mkNestedNonLocalEntityRef nleref id) + +type EntityRef with + + member tcref.NestedTyconRef (x: Entity) = + match tcref with + | ERefLocal _ -> mkLocalTyconRef x + | ERefNonLocal nlr -> mkNonLocalTyconRefPreResolved x nlr x.LogicalName + + member tcref.RecdFieldRefInNestedTycon tycon (id: Ident) = RecdFieldRef (tcref.NestedTyconRef tycon, id.idText) + +/// Make a reference to a union case for type in a module or namespace +let mkModuleUnionCaseRef (modref: ModuleOrNamespaceRef) tycon uc = + (modref.NestedTyconRef tycon).MakeNestedUnionCaseRef uc + +let VRefLocal x: ValRef = { binding=x; nlr=Unchecked.defaultof<_> } + +let VRefNonLocal x: ValRef = { binding=Unchecked.defaultof<_>; nlr=x } + +let VRefNonLocalPreResolved x xref: ValRef = { binding=x; nlr=xref } + +let (|VRefLocal|VRefNonLocal|) (x: ValRef) = + match box x.nlr with + | null -> VRefLocal x.binding + | _ -> VRefNonLocal x.nlr + +let mkNonLocalValRef mp id = VRefNonLocal {EnclosingEntity = ERefNonLocal mp; ItemKey=id } + +let mkNonLocalValRefPreResolved x mp id = VRefNonLocalPreResolved x {EnclosingEntity = ERefNonLocal mp; ItemKey=id } + +let ccuOfValRef vref = + match vref with + | VRefLocal _ -> None + | VRefNonLocal nlr -> Some nlr.Ccu + +let ccuOfTyconRef eref = + match eref with + | ERefLocal _ -> None + | ERefNonLocal nlr -> Some nlr.Ccu + +//-------------------------------------------------------------------------- +// Type parameters and inference unknowns +//------------------------------------------------------------------------- + +let mkTyparTy (tp: Typar) = + match tp.Kind with + | TyparKind.Type -> tp.AsType + | TyparKind.Measure -> TType_measure (Measure.Var tp) + +let copyTypar (tp: Typar) = + let optData = tp.typar_opt_data |> Option.map (fun tg -> { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs }) + Typar.New { typar_id = tp.typar_id + typar_flags = tp.typar_flags + typar_stamp = newStamp() + typar_solution = tp.typar_solution + typar_astype = Unchecked.defaultof<_> + // Be careful to clone the mutable optional data too + typar_opt_data = optData } + +let copyTypars tps = List.map copyTypar tps + +//-------------------------------------------------------------------------- +// Inference variables +//-------------------------------------------------------------------------- + +let tryShortcutSolvedUnitPar canShortcut (r: Typar) = + if r.Kind = TyparKind.Type then failwith "tryShortcutSolvedUnitPar: kind=type" + match r.Solution with + | Some (TType_measure unt) -> + if canShortcut then + match unt with + | Measure.Var r2 -> + match r2.Solution with + | None -> () + | Some _ as soln -> + r.typar_solution <- soln + | _ -> () + unt + | _ -> + failwith "tryShortcutSolvedUnitPar: unsolved" + +let rec stripUnitEqnsAux canShortcut unt = + match unt with + | Measure.Var r when r.IsSolved -> stripUnitEqnsAux canShortcut (tryShortcutSolvedUnitPar canShortcut r) + | _ -> unt + +let rec stripTyparEqnsAux canShortcut ty = + match ty with + | TType_var r -> + match r.Solution with + | Some soln -> + if canShortcut then + match soln with + // We avoid shortcutting when there are additional constraints on the type variable we're trying to cut out + // This is only because IterType likes to walk _all_ the constraints _everywhere_ in a type, including + // those attached to _solved_ type variables. In an ideal world this would never be needed - see the notes + // on IterType. + | TType_var r2 when r2.Constraints.IsEmpty -> + match r2.Solution with + | None -> () + | Some _ as soln2 -> + r.typar_solution <- soln2 + | _ -> () + stripTyparEqnsAux canShortcut soln + | None -> + ty + | TType_measure unt -> + TType_measure (stripUnitEqnsAux canShortcut unt) + | _ -> ty + +let stripTyparEqns ty = stripTyparEqnsAux false ty + +let stripUnitEqns unt = stripUnitEqnsAux false unt + +//--------------------------------------------------------------------------- +// These make local/non-local references to values according to whether +// the item is globally stable ("published") or not. +//--------------------------------------------------------------------------- + +let mkLocalValRef (v: Val) = VRefLocal v +let mkLocalModRef (v: ModuleOrNamespace) = ERefLocal v +let mkLocalEntityRef (v: Entity) = ERefLocal v + +let mkNonLocalCcuRootEntityRef ccu (x: Entity) = mkNonLocalTyconRefPreResolved x (mkNonLocalEntityRef ccu [| |]) x.LogicalName + +let mkNestedValRef (cref: EntityRef) (v: Val) : ValRef = + match cref with + | ERefLocal _ -> mkLocalValRef v + | ERefNonLocal nlr -> + let key = v.GetLinkageFullKey() + mkNonLocalValRefPreResolved v nlr key + +/// From Ref_private to Ref_nonlocal when exporting data. +let rescopePubPathToParent viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p.[0..p.Length-2]) + +/// From Ref_private to Ref_nonlocal when exporting data. +let rescopePubPath viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p) + +//--------------------------------------------------------------------------- +// Equality between TAST items. +//--------------------------------------------------------------------------- + +let valRefInThisAssembly compilingFslib (x: ValRef) = + match x with + | VRefLocal _ -> true + | VRefNonLocal _ -> compilingFslib + +let tyconRefUsesLocalXmlDoc compilingFslib (x: TyconRef) = + match x with + | ERefLocal _ -> true + | ERefNonLocal _ -> +#if !NO_EXTENSIONTYPING + match x.TypeReprInfo with + | TProvidedTypeRepr _ -> true + | _ -> +#endif + compilingFslib + +let entityRefInThisAssembly compilingFslib (x: EntityRef) = + match x with + | ERefLocal _ -> true + | ERefNonLocal _ -> compilingFslib + +let arrayPathEq (y1: string[]) (y2: string[]) = + let len1 = y1.Length + let len2 = y2.Length + (len1 = len2) && + (let rec loop i = (i >= len1) || (y1.[i] = y2.[i] && loop (i+1)) + loop 0) + +let nonLocalRefEq (NonLocalEntityRef(x1, y1) as smr1) (NonLocalEntityRef(x2, y2) as smr2) = + smr1 === smr2 || (ccuEq x1 x2 && arrayPathEq y1 y2) + +/// This predicate tests if non-local resolution paths are definitely known to resolve +/// to different entities. All references with different named paths always resolve to +/// different entities. Two references with the same named paths may resolve to the same +/// entities even if they reference through different CCUs, because one reference +/// may be forwarded to another via a .NET TypeForwarder. +let nonLocalRefDefinitelyNotEq (NonLocalEntityRef(_, y1)) (NonLocalEntityRef(_, y2)) = + not (arrayPathEq y1 y2) + +let pubPathEq (PubPath path1) (PubPath path2) = arrayPathEq path1 path2 + +let fslibRefEq (nlr1: NonLocalEntityRef) (PubPath path2) = + arrayPathEq nlr1.Path path2 + +// Compare two EntityRef's for equality when compiling fslib (FSharp.Core.dll) +// +// Compiler-internal references to items in fslib are Ref_nonlocals even when compiling fslib. +// This breaks certain invariants that hold elsewhere, because they dereference to point to +// Entity's from signatures rather than Entity's from implementations. This means backup, alternative +// equality comparison techniques are needed when compiling fslib itself. +let fslibEntityRefEq fslibCcu (eref1: EntityRef) (eref2: EntityRef) = + match eref1, eref2 with + | ERefNonLocal nlr1, ERefLocal x2 + | ERefLocal x2, ERefNonLocal nlr1 -> + ccuEq nlr1.Ccu fslibCcu && + match x2.PublicPath with + | Some pp2 -> fslibRefEq nlr1 pp2 + | None -> false + | ERefLocal e1, ERefLocal e2 -> + match e1.PublicPath, e2.PublicPath with + | Some pp1, Some pp2 -> pubPathEq pp1 pp2 + | _ -> false + | _ -> false + +// Compare two ValRef's for equality when compiling fslib (FSharp.Core.dll) +// +// Compiler-internal references to items in fslib are Ref_nonlocals even when compiling fslib. +// This breaks certain invariants that hold elsewhere, because they dereference to point to +// Val's from signatures rather than Val's from implementations. This means backup, alternative +// equality comparison techniques are needed when compiling fslib itself. +let fslibValRefEq fslibCcu vref1 vref2 = + match vref1, vref2 with + | VRefNonLocal nlr1, VRefLocal x2 + | VRefLocal x2, VRefNonLocal nlr1 -> + ccuEq nlr1.Ccu fslibCcu && + match x2.PublicPath with + | Some (ValPubPath(pp2, nm2)) -> + // Note: this next line is just comparing the values by name, and not even the partial linkage data + // This relies on the fact that the compiler doesn't use any references to + // entities in fslib that are overloaded, or, if they are overloaded, then value identity + // is not significant + nlr1.ItemKey.PartialKey = nm2.PartialKey && + fslibRefEq nlr1.EnclosingEntity.nlr pp2 + | _ -> + false + // Note: I suspect this private-to-private reference comparison is not needed + | VRefLocal e1, VRefLocal e2 -> + match e1.PublicPath, e2.PublicPath with + | Some (ValPubPath(pp1, nm1)), Some (ValPubPath(pp2, nm2)) -> + pubPathEq pp1 pp2 && + (nm1 = nm2) + | _ -> false + | _ -> false + +/// Primitive routine to compare two EntityRef's for equality +/// This takes into account the possibility that they may have type forwarders +let primEntityRefEq compilingFslib fslibCcu (x: EntityRef) (y: EntityRef) = + x === y || + + if x.IsResolved && y.IsResolved && not compilingFslib then + x.ResolvedTarget === y.ResolvedTarget + elif not x.IsLocalRef && not y.IsLocalRef && + (// Two tcrefs with identical paths are always equal + nonLocalRefEq x.nlr y.nlr || + // The tcrefs may have forwarders. If they may possibly be equal then resolve them to get their canonical references + // and compare those using pointer equality. + (not (nonLocalRefDefinitelyNotEq x.nlr y.nlr) && + match x.TryDeref with + | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false + | _ -> match y.TryDeref with ValueNone -> true | _ -> false)) then + true + else + compilingFslib && fslibEntityRefEq fslibCcu x y + +/// Primitive routine to compare two UnionCaseRef's for equality +let primUnionCaseRefEq compilingFslib fslibCcu (UnionCaseRef(tcr1, c1) as uc1) (UnionCaseRef(tcr2, c2) as uc2) = + uc1 === uc2 || (primEntityRefEq compilingFslib fslibCcu tcr1 tcr2 && c1 = c2) + +/// Primitive routine to compare two ValRef's for equality. On the whole value identity is not particularly +/// significant in F#. However it is significant for +/// (a) Active Patterns +/// (b) detecting uses of "special known values" from FSharp.Core.dll, such as 'seq' +/// and quotation splicing +/// +/// Note this routine doesn't take type forwarding into account +let primValRefEq compilingFslib fslibCcu (x: ValRef) (y: ValRef) = + x === y + || (x.IsResolved && y.IsResolved && x.ResolvedTarget === y.ResolvedTarget) + || (x.IsLocalRef && y.IsLocalRef && valEq x.ResolvedTarget y.ResolvedTarget) + || // Use TryDeref to guard against the platforms/times when certain F# language features aren't available + match x.TryDeref with + | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | ValueNone -> false + | ValueNone -> match y.TryDeref with ValueNone -> true | ValueSome _ -> false + || (compilingFslib && fslibValRefEq fslibCcu x y) + +//--------------------------------------------------------------------------- +// pubpath/cpath mess +//--------------------------------------------------------------------------- + +let fullCompPathOfModuleOrNamespace (m: ModuleOrNamespace) = + let (CompPath(scoref, cpath)) = m.CompilationPath + CompPath(scoref, cpath@[(m.LogicalName, m.ModuleOrNamespaceType.ModuleOrNamespaceKind)]) + +// Can cpath2 be accessed given a right to access cpath1. That is, is cpath2 a nested type or namespace of cpath1. Note order of arguments. +let inline canAccessCompPathFrom (CompPath(scoref1, cpath1)) (CompPath(scoref2, cpath2)) = + let rec loop p1 p2 = + match p1, p2 with + | (a1, k1) :: rest1, (a2, k2) :: rest2 -> (a1=a2) && (k1=k2) && loop rest1 rest2 + | [], _ -> true + | _ -> false // cpath1 is longer + loop cpath1 cpath2 && + (scoref1 = scoref2) + +let canAccessFromOneOf cpaths cpathTest = + cpaths |> List.exists (fun cpath -> canAccessCompPathFrom cpath cpathTest) + +let canAccessFrom (TAccess x) cpath = + x |> List.forall (fun cpath1 -> canAccessCompPathFrom cpath1 cpath) + +let canAccessFromEverywhere (TAccess x) = x.IsEmpty +let canAccessFromSomewhere (TAccess _) = true +let isLessAccessible (TAccess aa) (TAccess bb) = + not (aa |> List.forall(fun a -> bb |> List.exists (fun b -> canAccessCompPathFrom a b))) + +/// Given (newPath, oldPath) replace oldPath by newPath in the TAccess. +let accessSubstPaths (newPath, oldPath) (TAccess paths) = + let subst cpath = if cpath=oldPath then newPath else cpath + TAccess (List.map subst paths) + +let compPathOfCcu (ccu: CcuThunk) = CompPath(ccu.ILScopeRef, []) +let taccessPublic = TAccess [] +let taccessPrivate accessPath = TAccess [accessPath] +let compPathInternal = CompPath(ILScopeRef.Local, []) +let taccessInternal = TAccess [compPathInternal] +let combineAccess (TAccess a1) (TAccess a2) = TAccess(a1@a2) + +exception Duplicate of string * string * range +exception NameClash of string * string * string * range * string * string * range + diff --git a/src/fsharp/TypedTreeBasics.fsi b/src/fsharp/TypedTreeBasics.fsi new file mode 100644 index 00000000000..fd9fe751e9e --- /dev/null +++ b/src/fsharp/TypedTreeBasics.fsi @@ -0,0 +1,230 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +//------------------------------------------------------------------------- +// Defines the typed abstract syntax trees used throughout the F# compiler. +//------------------------------------------------------------------------- + +module internal FSharp.Compiler.TypedTreeBasics + +open Internal.Utilities.Library.Extras +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree + +val getNameOfScopeRef: sref:ILScopeRef -> string + +/// Metadata on values (names of arguments etc. +module ValReprInfo = + + val unnamedTopArg1: ArgReprInfo + + val unnamedTopArg: ArgReprInfo list + + val unitArgData: ArgReprInfo list list + + val unnamedRetVal: ArgReprInfo + + val selfMetadata: ArgReprInfo list + + val emptyValData: ValReprInfo + + val InferTyparInfo: tps:Typar list -> TyparReprInfo list + + val InferArgReprInfo: v:Val -> ArgReprInfo + + val InferArgReprInfos: vs:Val list list -> ValReprInfo + + val HasNoArgs: ValReprInfo -> bool + +val typeOfVal: v:Val -> TType + +val typesOfVals: v:Val list -> TType list + +val nameOfVal: v:Val -> string + +val arityOfVal: v:Val -> ValReprInfo + +val tupInfoRef: TupInfo + +val tupInfoStruct: TupInfo + +val mkTupInfo: b:bool -> TupInfo + +val structnessDefault: bool + +val mkRawRefTupleTy: tys:TTypes -> TType + +val mkRawStructTupleTy: tys:TTypes -> TType + +val mapTImplFile: f:(ModuleOrNamespaceExprWithSig -> ModuleOrNamespaceExprWithSig) -> TypedImplFile -> TypedImplFile + +val mapAccImplFile: f:('a -> ModuleOrNamespaceExprWithSig -> ModuleOrNamespaceExprWithSig * 'b) -> z:'a -> TypedImplFile -> TypedImplFile * 'b + +val foldTImplFile: f:('a -> ModuleOrNamespaceExprWithSig -> 'b) -> z:'a -> TypedImplFile -> 'b + +val typarEq: lv1:Typar -> lv2:Typar -> bool + +/// Equality on type variables, implemented as reference equality. This should be equivalent to using typarEq. +val typarRefEq: tp1:Typar -> tp2:Typar -> bool + +/// Equality on value specs, implemented as reference equality +val valEq: lv1:Val -> lv2:Val -> bool + +/// Equality on CCU references, implemented as reference equality except when unresolved +val ccuEq: mv1:CcuThunk -> mv2:CcuThunk -> bool + +/// For dereferencing in the middle of a pattern +val ( |ValDeref| ): vr:ValRef -> Val + +val mkRecdFieldRef: tcref:TyconRef -> f:string -> RecdFieldRef + +val mkUnionCaseRef: tcref:TyconRef -> c:string -> UnionCaseRef + +val ERefLocal: x:NonNullSlot -> EntityRef + +val ERefNonLocal: x:NonLocalEntityRef -> EntityRef + +val ERefNonLocalPreResolved: x:NonNullSlot -> xref:NonLocalEntityRef -> EntityRef + +val ( |ERefLocal|ERefNonLocal| ): x:EntityRef -> Choice,NonLocalEntityRef> + +val mkLocalTyconRef: x:NonNullSlot -> EntityRef + +val mkNonLocalEntityRef: ccu:CcuThunk -> mp:string [] -> NonLocalEntityRef + +val mkNestedNonLocalEntityRef: nleref:NonLocalEntityRef -> id:string -> NonLocalEntityRef + +val mkNonLocalTyconRef: nleref:NonLocalEntityRef -> id:string -> EntityRef + +val mkNonLocalTyconRefPreResolved: x:NonNullSlot -> nleref:NonLocalEntityRef -> id:string -> EntityRef + +type EntityRef with + member NestedTyconRef: x:Entity -> EntityRef + member RecdFieldRefInNestedTycon: tycon:Entity -> id:Ident -> RecdFieldRef + +/// Make a reference to a union case for type in a module or namespace +val mkModuleUnionCaseRef: modref:ModuleOrNamespaceRef -> tycon:Entity -> uc:UnionCase -> UnionCaseRef val VRefLocal: x:NonNullSlot -> ValRef + +val VRefNonLocal: x:NonLocalValOrMemberRef -> ValRef + +val VRefNonLocalPreResolved: x:NonNullSlot -> xref:NonLocalValOrMemberRef -> ValRef + +val ( |VRefLocal|VRefNonLocal| ): x:ValRef -> Choice,NonLocalValOrMemberRef> + +val mkNonLocalValRef: mp:NonLocalEntityRef -> id:ValLinkageFullKey -> ValRef + +val mkNonLocalValRefPreResolved: x:NonNullSlot -> mp:NonLocalEntityRef -> id:ValLinkageFullKey -> ValRef + +val ccuOfValRef: vref:ValRef -> CcuThunk option + +val ccuOfTyconRef: eref:EntityRef -> CcuThunk option + +val mkTyparTy: tp:Typar -> TType + +val copyTypar: tp:Typar -> Typar + +val copyTypars: tps:Typar list -> Typar list + +val tryShortcutSolvedUnitPar: canShortcut:bool -> r:Typar -> Measure + +val stripUnitEqnsAux: canShortcut:bool -> unt:Measure -> Measure + +val stripTyparEqnsAux: canShortcut:bool -> ty:TType -> TType + +val stripTyparEqns: ty:TType -> TType + +val stripUnitEqns: unt:Measure -> Measure + +val mkLocalValRef: v:Val -> ValRef + +val mkLocalModRef: v:ModuleOrNamespace -> EntityRef + +val mkLocalEntityRef: v:Entity -> EntityRef + +val mkNonLocalCcuRootEntityRef: ccu:CcuThunk -> x:Entity -> EntityRef + +val mkNestedValRef:cref:EntityRef -> v:Val -> ValRef + +/// From Ref_private to Ref_nonlocal when exporting data. +val rescopePubPathToParent:viewedCcu:CcuThunk -> PublicPath -> NonLocalEntityRef + +/// From Ref_private to Ref_nonlocal when exporting data. +val rescopePubPath: viewedCcu:CcuThunk -> PublicPath -> NonLocalEntityRef + +val valRefInThisAssembly: compilingFslib:bool -> x:ValRef -> bool + +val tyconRefUsesLocalXmlDoc: compilingFslib:bool -> x:TyconRef -> bool + +val entityRefInThisAssembly: compilingFslib:bool -> x:EntityRef -> bool + +val arrayPathEq: y1:string [] -> y2:string [] -> bool + +val nonLocalRefEq:NonLocalEntityRef -> NonLocalEntityRef -> bool + +/// This predicate tests if non-local resolution paths are definitely known to resolve +/// to different entities. All references with different named paths always resolve to +/// different entities. Two references with the same named paths may resolve to the same +/// entities even if they reference through different CCUs, because one reference +/// may be forwarded to another via a .NET TypeForwarder. +val nonLocalRefDefinitelyNotEq: NonLocalEntityRef -> NonLocalEntityRef -> bool + +val pubPathEq: PublicPath -> PublicPath -> bool + +val fslibRefEq: nlr1:NonLocalEntityRef -> PublicPath -> bool + +/// Compare two EntityRef's for equality when compiling fslib (FSharp.Core.dll) +val fslibEntityRefEq: fslibCcu:CcuThunk -> eref1:EntityRef -> eref2:EntityRef -> bool + +// Compare two ValRef's for equality when compiling fslib (FSharp.Core.dll) +val fslibValRefEq: fslibCcu:CcuThunk -> vref1:ValRef -> vref2:ValRef -> bool + +/// Primitive routine to compare two EntityRef's for equality +/// This takes into account the possibility that they may have type forwarders +val primEntityRefEq: compilingFslib:bool -> fslibCcu:CcuThunk -> x:EntityRef -> y:EntityRef -> bool + +/// Primitive routine to compare two UnionCaseRef's for equality +val primUnionCaseRefEq: compilingFslib:bool -> fslibCcu:CcuThunk -> UnionCaseRef -> UnionCaseRef -> bool + +/// Primitive routine to compare two ValRef's for equality. On the whole value identity is not particularly +/// significant in F#. However it is significant for +/// (a) Active Patterns +/// (b) detecting uses of "special known values" from FSharp.Core.dll, such as 'seq' +/// and quotation splicing +/// +/// Note this routine doesn't take type forwarding into account +val primValRefEq: compilingFslib:bool -> fslibCcu:CcuThunk -> x:ValRef -> y:ValRef -> bool + +val fullCompPathOfModuleOrNamespace: m:ModuleOrNamespace -> CompilationPath + +val inline canAccessCompPathFrom: CompilationPath -> CompilationPath -> bool + +val canAccessFromOneOf: cpaths:CompilationPath list -> cpathTest:CompilationPath -> bool + +val canAccessFrom: Accessibility -> cpath:CompilationPath -> bool + +val canAccessFromEverywhere: Accessibility -> bool + +val canAccessFromSomewhere: Accessibility -> bool + +val isLessAccessible: Accessibility -> Accessibility -> bool + +/// Given (newPath, oldPath) replace oldPath by newPath in the TAccess. +val accessSubstPaths: newPath:CompilationPath * oldPath:CompilationPath -> Accessibility -> Accessibility + +val compPathOfCcu: ccu:CcuThunk -> CompilationPath + +val taccessPublic: Accessibility + +val taccessPrivate: accessPath:CompilationPath -> Accessibility + +val compPathInternal: CompilationPath + +val taccessInternal: Accessibility + +val combineAccess: Accessibility -> Accessibility -> Accessibility + +exception Duplicate of string * string * range + +exception NameClash of string * string * string * range * string * string * range + diff --git a/src/fsharp/TypedTreeOps.fs b/src/fsharp/TypedTreeOps.fs new file mode 100644 index 00000000000..4996150ed88 --- /dev/null +++ b/src/fsharp/TypedTreeOps.fs @@ -0,0 +1,9721 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines derived expression manipulation and construction functions. +module internal FSharp.Compiler.TypedTreeOps + +open System.Collections.Generic +open System.Collections.Immutable +open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Rational + +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Features +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Text.TaggedText +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +//--------------------------------------------------------------------------- +// Basic data structures +//--------------------------------------------------------------------------- + +[] +type TyparMap<'T> = + | TPMap of StampMap<'T> + + member tm.Item + with get (v: Typar) = + let (TPMap m) = tm + m.[v.Stamp] + + member tm.ContainsKey (v: Typar) = + let (TPMap m) = tm + m.ContainsKey(v.Stamp) + + member tm.TryFind (v: Typar) = + let (TPMap m) = tm + m.TryFind(v.Stamp) + + member tm.Add (v: Typar, x) = + let (TPMap m) = tm + TPMap (m.Add(v.Stamp, x)) + + static member Empty: TyparMap<'T> = TPMap Map.empty + +[] +type TyconRefMap<'T>(imap: StampMap<'T>) = + member m.Item with get (v: TyconRef) = imap.[v.Stamp] + member m.TryFind (v: TyconRef) = imap.TryFind v.Stamp + member m.ContainsKey (v: TyconRef) = imap.ContainsKey v.Stamp + member m.Add (v: TyconRef) x = TyconRefMap (imap.Add (v.Stamp, x)) + member m.Remove (v: TyconRef) = TyconRefMap (imap.Remove v.Stamp) + member m.IsEmpty = imap.IsEmpty + + static member Empty: TyconRefMap<'T> = TyconRefMap Map.empty + static member OfList vs = (vs, TyconRefMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add x y) + +[] +[] +type ValMap<'T>(imap: StampMap<'T>) = + + member m.Contents = imap + member m.Item with get (v: Val) = imap.[v.Stamp] + member m.TryFind (v: Val) = imap.TryFind v.Stamp + member m.ContainsVal (v: Val) = imap.ContainsKey v.Stamp + member m.Add (v: Val) x = ValMap (imap.Add(v.Stamp, x)) + member m.Remove (v: Val) = ValMap (imap.Remove(v.Stamp)) + static member Empty = ValMap<'T> Map.empty + member m.IsEmpty = imap.IsEmpty + static member OfList vs = (vs, ValMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add x y) + +//-------------------------------------------------------------------------- +// renamings +//-------------------------------------------------------------------------- + +type TyparInst = (Typar * TType) list + +type TyconRefRemap = TyconRefMap +type ValRemap = ValMap + +let emptyTyconRefRemap: TyconRefRemap = TyconRefMap<_>.Empty +let emptyTyparInst = ([]: TyparInst) + +[] +type Remap = + { tpinst: TyparInst + + /// Values to remap + valRemap: ValRemap + + /// TyconRefs to remap + tyconRefRemap: TyconRefRemap + + /// Remove existing trait solutions? + removeTraitSolutions: bool } + +let emptyRemap = + { tpinst = emptyTyparInst + tyconRefRemap = emptyTyconRefRemap + valRemap = ValMap.Empty + removeTraitSolutions = false } + +type Remap with + static member Empty = emptyRemap + +//-------------------------------------------------------------------------- +// Substitute for type variables and remap type constructors +//-------------------------------------------------------------------------- + +let addTyconRefRemap tcref1 tcref2 tmenv = + { tmenv with tyconRefRemap = tmenv.tyconRefRemap.Add tcref1 tcref2 } + +let isRemapEmpty remap = + isNil remap.tpinst && + remap.tyconRefRemap.IsEmpty && + remap.valRemap.IsEmpty + +let rec instTyparRef tpinst ty tp = + match tpinst with + | [] -> ty + | (tp', ty') :: t -> + if typarEq tp tp' then ty' + else instTyparRef t ty tp + +let instMeasureTyparRef tpinst unt (tp: Typar) = + match tp.Kind with + | TyparKind.Measure -> + let rec loop tpinst = + match tpinst with + | [] -> unt + | (tp', ty') :: t -> + if typarEq tp tp' then + match ty' with + | TType_measure unt -> unt + | _ -> failwith "instMeasureTyparRef incorrect kind" + else + loop t + loop tpinst + | _ -> failwith "instMeasureTyparRef: kind=Type" + +let remapTyconRef (tcmap: TyconRefMap<_>) tcref = + match tcmap.TryFind tcref with + | Some tcref -> tcref + | None -> tcref + +let remapUnionCaseRef tcmap (UnionCaseRef(tcref, nm)) = UnionCaseRef(remapTyconRef tcmap tcref, nm) +let remapRecdFieldRef tcmap (RecdFieldRef(tcref, nm)) = RecdFieldRef(remapTyconRef tcmap tcref, nm) + +let mkTyparInst (typars: Typars) tyargs = + (List.zip typars tyargs: TyparInst) + +let generalizeTypar tp = mkTyparTy tp +let generalizeTypars tps = List.map generalizeTypar tps + +let rec remapTypeAux (tyenv: Remap) (ty: TType) = + let ty = stripTyparEqns ty + match ty with + | TType_var tp as ty -> instTyparRef tyenv.tpinst ty tp + | TType_app (tcref, tinst) as ty -> + match tyenv.tyconRefRemap.TryFind tcref with + | Some tcref' -> TType_app (tcref', remapTypesAux tyenv tinst) + | None -> + match tinst with + | [] -> ty // optimization to avoid re-allocation of TType_app node in the common case + | _ -> + // avoid reallocation on idempotent + let tinst' = remapTypesAux tyenv tinst + if tinst === tinst' then ty else + TType_app (tcref, tinst') + + | TType_ucase (UnionCaseRef(tcref, n), tinst) -> + match tyenv.tyconRefRemap.TryFind tcref with + | Some tcref' -> TType_ucase (UnionCaseRef(tcref', n), remapTypesAux tyenv tinst) + | None -> TType_ucase (UnionCaseRef(tcref, n), remapTypesAux tyenv tinst) + + | TType_anon (anonInfo, l) as ty -> + let tupInfo' = remapTupInfoAux tyenv anonInfo.TupInfo + let l' = remapTypesAux tyenv l + if anonInfo.TupInfo === tupInfo' && l === l' then ty else + TType_anon (AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo', anonInfo.SortedIds), l') + + | TType_tuple (tupInfo, l) as ty -> + let tupInfo' = remapTupInfoAux tyenv tupInfo + let l' = remapTypesAux tyenv l + if tupInfo === tupInfo' && l === l' then ty else + TType_tuple (tupInfo', l') + + | TType_fun (d, r) as ty -> + let d' = remapTypeAux tyenv d + let r' = remapTypeAux tyenv r + if d === d' && r === r' then ty else + TType_fun (d', r') + + | TType_forall (tps, ty) -> + let tps', tyenv = copyAndRemapAndBindTypars tyenv tps + TType_forall (tps', remapTypeAux tyenv ty) + + | TType_measure unt -> + TType_measure (remapMeasureAux tyenv unt) + + +and remapMeasureAux tyenv unt = + match unt with + | Measure.One -> unt + | Measure.Con tcref -> + match tyenv.tyconRefRemap.TryFind tcref with + | Some tcref -> Measure.Con tcref + | None -> unt + | Measure.Prod(u1, u2) -> Measure.Prod(remapMeasureAux tyenv u1, remapMeasureAux tyenv u2) + | Measure.RationalPower(u, q) -> Measure.RationalPower(remapMeasureAux tyenv u, q) + | Measure.Inv u -> Measure.Inv(remapMeasureAux tyenv u) + | Measure.Var tp as unt -> + match tp.Solution with + | None -> + match ListAssoc.tryFind typarEq tp tyenv.tpinst with + | Some v -> + match v with + | TType_measure unt -> unt + | _ -> failwith "remapMeasureAux: incorrect kinds" + | None -> unt + | Some (TType_measure unt) -> remapMeasureAux tyenv unt + | Some ty -> failwithf "incorrect kinds: %A" ty + +and remapTupInfoAux _tyenv unt = + match unt with + | TupInfo.Const _ -> unt + +and remapTypesAux tyenv types = List.mapq (remapTypeAux tyenv) types +and remapTyparConstraintsAux tyenv cs = + cs |> List.choose (fun x -> + match x with + | TyparConstraint.CoercesTo(ty, m) -> + Some(TyparConstraint.CoercesTo (remapTypeAux tyenv ty, m)) + | TyparConstraint.MayResolveMember(traitInfo, m) -> + Some(TyparConstraint.MayResolveMember (remapTraitInfo tyenv traitInfo, m)) + | TyparConstraint.DefaultsTo(priority, ty, m) -> + Some(TyparConstraint.DefaultsTo(priority, remapTypeAux tyenv ty, m)) + | TyparConstraint.IsEnum(uty, m) -> + Some(TyparConstraint.IsEnum(remapTypeAux tyenv uty, m)) + | TyparConstraint.IsDelegate(uty1, uty2, m) -> + Some(TyparConstraint.IsDelegate(remapTypeAux tyenv uty1, remapTypeAux tyenv uty2, m)) + | TyparConstraint.SimpleChoice(tys, m) -> + Some(TyparConstraint.SimpleChoice(remapTypesAux tyenv tys, m)) + | TyparConstraint.SupportsComparison _ + | TyparConstraint.SupportsEquality _ + | TyparConstraint.SupportsNull _ + | TyparConstraint.IsUnmanaged _ + | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsReferenceType _ + | TyparConstraint.RequiresDefaultConstructor _ -> Some x) + +and remapTraitWitnessInfo tyenv (TraitWitnessInfo(tys, nm, mf, argtys, rty)) = + let tysR = remapTypesAux tyenv tys + let argtysR = remapTypesAux tyenv argtys + let rtyR = Option.map (remapTypeAux tyenv) rty + TraitWitnessInfo(tysR, nm, mf, argtysR, rtyR) + +and remapTraitInfo tyenv (TTrait(tys, nm, mf, argtys, rty, slnCell)) = + let slnCell = + match !slnCell with + | None -> None + | _ when tyenv.removeTraitSolutions -> None + | Some sln -> + let sln = + match sln with + | ILMethSln(ty, extOpt, ilMethRef, minst) -> + ILMethSln(remapTypeAux tyenv ty, extOpt, ilMethRef, remapTypesAux tyenv minst) + | FSMethSln(ty, vref, minst) -> + FSMethSln(remapTypeAux tyenv ty, remapValRef tyenv vref, remapTypesAux tyenv minst) + | FSRecdFieldSln(tinst, rfref, isSet) -> + FSRecdFieldSln(remapTypesAux tyenv tinst, remapRecdFieldRef tyenv.tyconRefRemap rfref, isSet) + | FSAnonRecdFieldSln(anonInfo, tinst, n) -> + FSAnonRecdFieldSln(anonInfo, remapTypesAux tyenv tinst, n) + | BuiltInSln -> + BuiltInSln + | ClosedExprSln e -> + ClosedExprSln e // no need to remap because it is a closed expression, referring only to external types + Some sln + // Note: we reallocate a new solution cell on every traversal of a trait constraint + // This feels incorrect for trait constraints that are quantified: it seems we should have + // formal binders for trait constraints when they are quantified, just as + // we have formal binders for type variables. + // + // The danger here is that a solution for one syntactic occurrence of a trait constraint won't + // be propagated to other, "linked" solutions. However trait constraints don't appear in any algebra + // in the same way as types + TTrait(remapTypesAux tyenv tys, nm, mf, remapTypesAux tyenv argtys, Option.map (remapTypeAux tyenv) rty, ref slnCell) + +and bindTypars tps tyargs tpinst = + match tps with + | [] -> tpinst + | _ -> List.map2 (fun tp tyarg -> (tp, tyarg)) tps tyargs @ tpinst + +// This version is used to remap most type parameters, e.g. ones bound at tycons, vals, records +// See notes below on remapTypeFull for why we have a function that accepts remapAttribs as an argument +and copyAndRemapAndBindTyparsFull remapAttrib tyenv tps = + match tps with + | [] -> tps, tyenv + | _ -> + let tps' = copyTypars tps + let tyenv = { tyenv with tpinst = bindTypars tps (generalizeTypars tps') tyenv.tpinst } + (tps, tps') ||> List.iter2 (fun tporig tp -> + tp.SetConstraints (remapTyparConstraintsAux tyenv tporig.Constraints) + tp.SetAttribs (tporig.Attribs |> remapAttrib)) + tps', tyenv + +// copies bound typars, extends tpinst +and copyAndRemapAndBindTypars tyenv tps = + copyAndRemapAndBindTyparsFull (fun _ -> []) tyenv tps + +and remapValLinkage tyenv (vlink: ValLinkageFullKey) = + let tyOpt = vlink.TypeForLinkage + let tyOpt' = + match tyOpt with + | None -> tyOpt + | Some ty -> + let ty' = remapTypeAux tyenv ty + if ty === ty' then tyOpt else + Some ty' + if tyOpt === tyOpt' then vlink else + ValLinkageFullKey(vlink.PartialKey, tyOpt') + +and remapNonLocalValRef tyenv (nlvref: NonLocalValOrMemberRef) = + let eref = nlvref.EnclosingEntity + let eref' = remapTyconRef tyenv.tyconRefRemap eref + let vlink = nlvref.ItemKey + let vlink' = remapValLinkage tyenv vlink + if eref === eref' && vlink === vlink' then nlvref else + { EnclosingEntity = eref' + ItemKey = vlink' } + +and remapValRef tmenv (vref: ValRef) = + match tmenv.valRemap.TryFind vref.Deref with + | None -> + if vref.IsLocalRef then vref else + let nlvref = vref.nlr + let nlvref' = remapNonLocalValRef tmenv nlvref + if nlvref === nlvref' then vref else + VRefNonLocal nlvref' + | Some res -> + res + +let remapType tyenv x = + if isRemapEmpty tyenv then x else + remapTypeAux tyenv x + +let remapTypes tyenv x = + if isRemapEmpty tyenv then x else + remapTypesAux tyenv x + +/// Use this one for any type that may be a forall type where the type variables may contain attributes +/// Logically speaking this is mutually recursive with remapAttrib defined much later in this file, +/// because types may contain forall types that contain attributes, which need to be remapped. +/// We currently break the recursion by passing in remapAttrib as a function parameter. +/// Use this one for any type that may be a forall type where the type variables may contain attributes +let remapTypeFull remapAttrib tyenv ty = + if isRemapEmpty tyenv then ty else + match stripTyparEqns ty with + | TType_forall(tps, tau) -> + let tps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenv tps + TType_forall(tps', remapType tyenvinner tau) + | _ -> + remapType tyenv ty + +let remapParam tyenv (TSlotParam(nm, ty, fl1, fl2, fl3, attribs) as x) = + if isRemapEmpty tyenv then x else + TSlotParam(nm, remapTypeAux tyenv ty, fl1, fl2, fl3, attribs) + +let remapSlotSig remapAttrib tyenv (TSlotSig(nm, ty, ctps, methTypars, paraml, rty) as x) = + if isRemapEmpty tyenv then x else + let ty' = remapTypeAux tyenv ty + let ctps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenv ctps + let methTypars', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tyenvinner methTypars + TSlotSig(nm, ty', ctps', methTypars', List.mapSquared (remapParam tyenvinner) paraml, Option.map (remapTypeAux tyenvinner) rty) + +let mkInstRemap tpinst = + { tyconRefRemap = emptyTyconRefRemap + tpinst = tpinst + valRemap = ValMap.Empty + removeTraitSolutions = false } + +// entry points for "typar -> TType" instantiation +let instType tpinst x = if isNil tpinst then x else remapTypeAux (mkInstRemap tpinst) x +let instTypes tpinst x = if isNil tpinst then x else remapTypesAux (mkInstRemap tpinst) x +let instTrait tpinst x = if isNil tpinst then x else remapTraitInfo (mkInstRemap tpinst) x +let instTyparConstraints tpinst x = if isNil tpinst then x else remapTyparConstraintsAux (mkInstRemap tpinst) x +let instSlotSig tpinst ss = remapSlotSig (fun _ -> []) (mkInstRemap tpinst) ss +let copySlotSig ss = remapSlotSig (fun _ -> []) Remap.Empty ss + + +let mkTyparToTyparRenaming tpsOrig tps = + let tinst = generalizeTypars tps + mkTyparInst tpsOrig tinst, tinst + +let mkTyconInst (tycon: Tycon) tinst = mkTyparInst tycon.TyparsNoRange tinst +let mkTyconRefInst (tcref: TyconRef) tinst = mkTyconInst tcref.Deref tinst + +//--------------------------------------------------------------------------- +// Basic equalities +//--------------------------------------------------------------------------- + +let tyconRefEq (g: TcGlobals) tcref1 tcref2 = primEntityRefEq g.compilingFslib g.fslibCcu tcref1 tcref2 +let valRefEq (g: TcGlobals) vref1 vref2 = primValRefEq g.compilingFslib g.fslibCcu vref1 vref2 + +//--------------------------------------------------------------------------- +// Remove inference equations and abbreviations from units +//--------------------------------------------------------------------------- + +let reduceTyconRefAbbrevMeasureable (tcref: TyconRef) = + let abbrev = tcref.TypeAbbrev + match abbrev with + | Some (TType_measure ms) -> ms + | _ -> invalidArg "tcref" "not a measure abbreviation, or incorrect kind" + +let rec stripUnitEqnsFromMeasureAux canShortcut unt = + match stripUnitEqnsAux canShortcut unt with + | Measure.Con tcref when tcref.IsTypeAbbrev -> + stripUnitEqnsFromMeasureAux canShortcut (reduceTyconRefAbbrevMeasureable tcref) + | m -> m + +let stripUnitEqnsFromMeasure m = stripUnitEqnsFromMeasureAux false m + +//--------------------------------------------------------------------------- +// Basic unit stuff +//--------------------------------------------------------------------------- + +/// What is the contribution of unit-of-measure constant ucref to unit-of-measure expression measure? +let rec MeasureExprConExponent g abbrev ucref unt = + match (if abbrev then stripUnitEqnsFromMeasure unt else stripUnitEqns unt) with + | Measure.Con ucref' -> if tyconRefEq g ucref' ucref then OneRational else ZeroRational + | Measure.Inv unt' -> NegRational(MeasureExprConExponent g abbrev ucref unt') + | Measure.Prod(unt1, unt2) -> AddRational(MeasureExprConExponent g abbrev ucref unt1) (MeasureExprConExponent g abbrev ucref unt2) + | Measure.RationalPower(unt', q) -> MulRational (MeasureExprConExponent g abbrev ucref unt') q + | _ -> ZeroRational + +/// What is the contribution of unit-of-measure constant ucref to unit-of-measure expression measure +/// after remapping tycons? +let rec MeasureConExponentAfterRemapping g r ucref unt = + match stripUnitEqnsFromMeasure unt with + | Measure.Con ucref' -> if tyconRefEq g (r ucref') ucref then OneRational else ZeroRational + | Measure.Inv unt' -> NegRational(MeasureConExponentAfterRemapping g r ucref unt') + | Measure.Prod(unt1, unt2) -> AddRational(MeasureConExponentAfterRemapping g r ucref unt1) (MeasureConExponentAfterRemapping g r ucref unt2) + | Measure.RationalPower(unt', q) -> MulRational (MeasureConExponentAfterRemapping g r ucref unt') q + | _ -> ZeroRational + +/// What is the contribution of unit-of-measure variable tp to unit-of-measure expression unt? +let rec MeasureVarExponent tp unt = + match stripUnitEqnsFromMeasure unt with + | Measure.Var tp' -> if typarEq tp tp' then OneRational else ZeroRational + | Measure.Inv unt' -> NegRational(MeasureVarExponent tp unt') + | Measure.Prod(unt1, unt2) -> AddRational(MeasureVarExponent tp unt1) (MeasureVarExponent tp unt2) + | Measure.RationalPower(unt', q) -> MulRational (MeasureVarExponent tp unt') q + | _ -> ZeroRational + +/// List the *literal* occurrences of unit variables in a unit expression, without repeats +let ListMeasureVarOccs unt = + let rec gather acc unt = + match stripUnitEqnsFromMeasure unt with + | Measure.Var tp -> if List.exists (typarEq tp) acc then acc else tp :: acc + | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 + | Measure.RationalPower(unt', _) -> gather acc unt' + | Measure.Inv unt' -> gather acc unt' + | _ -> acc + gather [] unt + +/// List the *observable* occurrences of unit variables in a unit expression, without repeats, paired with their non-zero exponents +let ListMeasureVarOccsWithNonZeroExponents untexpr = + let rec gather acc unt = + match stripUnitEqnsFromMeasure unt with + | Measure.Var tp -> + if List.exists (fun (tp', _) -> typarEq tp tp') acc then acc + else + let e = MeasureVarExponent tp untexpr + if e = ZeroRational then acc else (tp, e) :: acc + | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 + | Measure.Inv unt' -> gather acc unt' + | Measure.RationalPower(unt', _) -> gather acc unt' + | _ -> acc + gather [] untexpr + +/// List the *observable* occurrences of unit constants in a unit expression, without repeats, paired with their non-zero exponents +let ListMeasureConOccsWithNonZeroExponents g eraseAbbrevs untexpr = + let rec gather acc unt = + match (if eraseAbbrevs then stripUnitEqnsFromMeasure unt else stripUnitEqns unt) with + | Measure.Con c -> + if List.exists (fun (c', _) -> tyconRefEq g c c') acc then acc else + let e = MeasureExprConExponent g eraseAbbrevs c untexpr + if e = ZeroRational then acc else (c, e) :: acc + | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 + | Measure.Inv unt' -> gather acc unt' + | Measure.RationalPower(unt', _) -> gather acc unt' + | _ -> acc + gather [] untexpr + +/// List the *literal* occurrences of unit constants in a unit expression, without repeats, +/// and after applying a remapping function r to tycons +let ListMeasureConOccsAfterRemapping g r unt = + let rec gather acc unt = + match stripUnitEqnsFromMeasure unt with + | Measure.Con c -> if List.exists (tyconRefEq g (r c)) acc then acc else r c :: acc + | Measure.Prod(unt1, unt2) -> gather (gather acc unt1) unt2 + | Measure.RationalPower(unt', _) -> gather acc unt' + | Measure.Inv unt' -> gather acc unt' + | _ -> acc + + gather [] unt + +/// Construct a measure expression representing the n'th power of a measure +let MeasurePower u n = + if n = 1 then u + elif n = 0 then Measure.One + else Measure.RationalPower (u, intToRational n) + +let MeasureProdOpt m1 m2 = + match m1, m2 with + | Measure.One, _ -> m2 + | _, Measure.One -> m1 + | _, _ -> Measure.Prod (m1, m2) + +/// Construct a measure expression representing the product of a list of measures +let ProdMeasures ms = + match ms with + | [] -> Measure.One + | m :: ms -> List.foldBack MeasureProdOpt ms m + +let isDimensionless g tyarg = + match stripTyparEqns tyarg with + | TType_measure unt -> + isNil (ListMeasureVarOccsWithNonZeroExponents unt) && + isNil (ListMeasureConOccsWithNonZeroExponents g true unt) + | _ -> false + +let destUnitParMeasure g unt = + let vs = ListMeasureVarOccsWithNonZeroExponents unt + let cs = ListMeasureConOccsWithNonZeroExponents g true unt + + match vs, cs with + | [(v, e)], [] when e = OneRational -> v + | _, _ -> failwith "destUnitParMeasure: not a unit-of-measure parameter" + +let isUnitParMeasure g unt = + let vs = ListMeasureVarOccsWithNonZeroExponents unt + let cs = ListMeasureConOccsWithNonZeroExponents g true unt + + match vs, cs with + | [(_, e)], [] when e = OneRational -> true + | _, _ -> false + +let normalizeMeasure g ms = + let vs = ListMeasureVarOccsWithNonZeroExponents ms + let cs = ListMeasureConOccsWithNonZeroExponents g false ms + match vs, cs with + | [], [] -> Measure.One + | [(v, e)], [] when e = OneRational -> Measure.Var v + | vs, cs -> List.foldBack (fun (v, e) -> fun m -> Measure.Prod (Measure.RationalPower (Measure.Var v, e), m)) vs (List.foldBack (fun (c, e) -> fun m -> Measure.Prod (Measure.RationalPower (Measure.Con c, e), m)) cs Measure.One) + +let tryNormalizeMeasureInType g ty = + match ty with + | TType_measure (Measure.Var v) -> + match v.Solution with + | Some (TType_measure ms) -> + v.typar_solution <- Some (TType_measure (normalizeMeasure g ms)) + ty + | _ -> ty + | _ -> ty + +//--------------------------------------------------------------------------- +// Some basic type builders +//--------------------------------------------------------------------------- + +let mkNativePtrTy (g: TcGlobals) ty = + assert g.nativeptr_tcr.CanDeref // this should always be available, but check anyway + TType_app (g.nativeptr_tcr, [ty]) + +let mkByrefTy (g: TcGlobals) ty = + assert g.byref_tcr.CanDeref // this should always be available, but check anyway + TType_app (g.byref_tcr, [ty]) + +let mkInByrefTy (g: TcGlobals) ty = + if g.inref_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref = byref, see RFC FS-1053.md + TType_app (g.inref_tcr, [ty]) + else + mkByrefTy g ty + +let mkOutByrefTy (g: TcGlobals) ty = + if g.outref_tcr.CanDeref then // If not using sufficient FSharp.Core, then outref = byref, see RFC FS-1053.md + TType_app (g.outref_tcr, [ty]) + else + mkByrefTy g ty + +let mkByrefTyWithFlag g readonly ty = + if readonly then + mkInByrefTy g ty + else + mkByrefTy g ty + +let mkByref2Ty (g: TcGlobals) ty1 ty2 = + assert g.byref2_tcr.CanDeref // check we are using sufficient FSharp.Core, caller should check this + TType_app (g.byref2_tcr, [ty1; ty2]) + +let mkVoidPtrTy (g: TcGlobals) = + assert g.voidptr_tcr.CanDeref // check we are using sufficient FSharp.Core, caller should check this + TType_app (g.voidptr_tcr, []) + +let mkByrefTyWithInference (g: TcGlobals) ty1 ty2 = + if g.byref2_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref = byref, see RFC FS-1053.md + TType_app (g.byref2_tcr, [ty1; ty2]) + else + TType_app (g.byref_tcr, [ty1]) + +let mkArrayTy (g: TcGlobals) rank ty m = + if rank < 1 || rank > 32 then + errorR(Error(FSComp.SR.tastopsMaxArrayThirtyTwo rank, m)) + TType_app (g.il_arr_tcr_map.[3], [ty]) + else + TType_app (g.il_arr_tcr_map.[rank - 1], [ty]) + +//-------------------------------------------------------------------------- +// Tuple compilation (types) +//------------------------------------------------------------------------ + +let maxTuple = 8 +let goodTupleFields = maxTuple-1 + +let isCompiledTupleTyconRef g tcref = + tyconRefEq g g.ref_tuple1_tcr tcref || + tyconRefEq g g.ref_tuple2_tcr tcref || + tyconRefEq g g.ref_tuple3_tcr tcref || + tyconRefEq g g.ref_tuple4_tcr tcref || + tyconRefEq g g.ref_tuple5_tcr tcref || + tyconRefEq g g.ref_tuple6_tcr tcref || + tyconRefEq g g.ref_tuple7_tcr tcref || + tyconRefEq g g.ref_tuple8_tcr tcref || + tyconRefEq g g.struct_tuple1_tcr tcref || + tyconRefEq g g.struct_tuple2_tcr tcref || + tyconRefEq g g.struct_tuple3_tcr tcref || + tyconRefEq g g.struct_tuple4_tcr tcref || + tyconRefEq g g.struct_tuple5_tcr tcref || + tyconRefEq g g.struct_tuple6_tcr tcref || + tyconRefEq g g.struct_tuple7_tcr tcref || + tyconRefEq g g.struct_tuple8_tcr tcref + +let mkCompiledTupleTyconRef (g: TcGlobals) isStruct n = + if n = 1 then (if isStruct then g.struct_tuple1_tcr else g.ref_tuple1_tcr) + elif n = 2 then (if isStruct then g.struct_tuple2_tcr else g.ref_tuple2_tcr) + elif n = 3 then (if isStruct then g.struct_tuple3_tcr else g.ref_tuple3_tcr) + elif n = 4 then (if isStruct then g.struct_tuple4_tcr else g.ref_tuple4_tcr) + elif n = 5 then (if isStruct then g.struct_tuple5_tcr else g.ref_tuple5_tcr) + elif n = 6 then (if isStruct then g.struct_tuple6_tcr else g.ref_tuple6_tcr) + elif n = 7 then (if isStruct then g.struct_tuple7_tcr else g.ref_tuple7_tcr) + elif n = 8 then (if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr) + else failwithf "mkCompiledTupleTyconRef, n = %d" n + +/// Convert from F# tuple types to .NET tuple types +let rec mkCompiledTupleTy g isStruct tupElemTys = + let n = List.length tupElemTys + if n < maxTuple then + TType_app (mkCompiledTupleTyconRef g isStruct n, tupElemTys) + else + let tysA, tysB = List.splitAfter goodTupleFields tupElemTys + TType_app ((if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr), tysA@[mkCompiledTupleTy g isStruct tysB]) + +/// Convert from F# tuple types to .NET tuple types, but only the outermost level +let mkOuterCompiledTupleTy g isStruct tupElemTys = + let n = List.length tupElemTys + if n < maxTuple then + TType_app (mkCompiledTupleTyconRef g isStruct n, tupElemTys) + else + let tysA, tysB = List.splitAfter goodTupleFields tupElemTys + let tcref = (if isStruct then g.struct_tuple8_tcr else g.ref_tuple8_tcr) + // In the case of an 8-tuple we add the Tuple<_> marker. For other sizes we keep the type + // as a regular F# tuple type. + match tysB with + | [ tyB ] -> + let marker = TType_app (mkCompiledTupleTyconRef g isStruct 1, [tyB]) + TType_app (tcref, tysA@[marker]) + | _ -> + TType_app (tcref, tysA@[TType_tuple (mkTupInfo isStruct, tysB)]) + +//--------------------------------------------------------------------------- +// Remove inference equations and abbreviations from types +//--------------------------------------------------------------------------- + +let applyTyconAbbrev abbrevTy tycon tyargs = + if isNil tyargs then abbrevTy + else instType (mkTyconInst tycon tyargs) abbrevTy + +let reduceTyconAbbrev (tycon: Tycon) tyargs = + let abbrev = tycon.TypeAbbrev + match abbrev with + | None -> invalidArg "tycon" "this type definition is not an abbreviation" + | Some abbrevTy -> + applyTyconAbbrev abbrevTy tycon tyargs + +let reduceTyconRefAbbrev (tcref: TyconRef) tyargs = + reduceTyconAbbrev tcref.Deref tyargs + +let reduceTyconMeasureableOrProvided (g: TcGlobals) (tycon: Tycon) tyargs = +#if NO_EXTENSIONTYPING + ignore g // otherwise g would be unused +#endif + let repr = tycon.TypeReprInfo + match repr with + | TMeasureableRepr ty -> + if isNil tyargs then ty else instType (mkTyconInst tycon tyargs) ty +#if !NO_EXTENSIONTYPING + | TProvidedTypeRepr info when info.IsErased -> info.BaseTypeForErased (range0, g.obj_ty) +#endif + | _ -> invalidArg "tc" "this type definition is not a refinement" + +let reduceTyconRefMeasureableOrProvided (g: TcGlobals) (tcref: TyconRef) tyargs = + reduceTyconMeasureableOrProvided g tcref.Deref tyargs + +let rec stripTyEqnsA g canShortcut ty = + let ty = stripTyparEqnsAux canShortcut ty + match ty with + | TType_app (tcref, tinst) -> + let tycon = tcref.Deref + match tycon.TypeAbbrev with + | Some abbrevTy -> + stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) + | None -> + // This is the point where we get to add additional conditional normalizing equations + // into the type system. Such power! + // + // Add the equation byref<'T> = byref<'T, ByRefKinds.InOut> for when using sufficient FSharp.Core + // See RFC FS-1053.md + if tyconRefEq g tcref g.byref_tcr && g.byref2_tcr.CanDeref && g.byrefkind_InOut_tcr.CanDeref then + mkByref2Ty g tinst.[0] (TType_app(g.byrefkind_InOut_tcr, [])) + + // Add the equation double<1> = double for units of measure. + elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then + stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) + else + ty + | ty -> ty + +let stripTyEqns g ty = stripTyEqnsA g false ty + +let evalTupInfoIsStruct aexpr = + match aexpr with + | TupInfo.Const b -> b + +let evalAnonInfoIsStruct (anonInfo: AnonRecdTypeInfo) = + evalTupInfoIsStruct anonInfo.TupInfo + +/// This erases outermost occurrences of inference equations, type abbreviations, non-generated provided types +/// and measureable types (float<_>). +/// It also optionally erases all "compilation representations", i.e. function and +/// tuple types, and also "nativeptr<'T> --> System.IntPtr" +let rec stripTyEqnsAndErase eraseFuncAndTuple (g: TcGlobals) ty = + let ty = stripTyEqns g ty + match ty with + | TType_app (tcref, args) -> + let tycon = tcref.Deref + if tycon.IsErased then + stripTyEqnsAndErase eraseFuncAndTuple g (reduceTyconMeasureableOrProvided g tycon args) + elif tyconRefEq g tcref g.nativeptr_tcr && eraseFuncAndTuple then + stripTyEqnsAndErase eraseFuncAndTuple g g.nativeint_ty + else + ty + | TType_fun(a, b) when eraseFuncAndTuple -> TType_app(g.fastFunc_tcr, [ a; b]) + | TType_tuple(tupInfo, l) when eraseFuncAndTuple -> mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) l + | ty -> ty + +let stripTyEqnsAndMeasureEqns g ty = + stripTyEqnsAndErase false g ty + +type Erasure = EraseAll | EraseMeasures | EraseNone + +let stripTyEqnsWrtErasure erasureFlag g ty = + match erasureFlag with + | EraseAll -> stripTyEqnsAndErase true g ty + | EraseMeasures -> stripTyEqnsAndErase false g ty + | _ -> stripTyEqns g ty + +let rec stripExnEqns (eref: TyconRef) = + let exnc = eref.Deref + match exnc.ExceptionInfo with + | TExnAbbrevRepr eref -> stripExnEqns eref + | _ -> exnc + +let primDestForallTy g ty = ty |> stripTyEqns g |> (function TType_forall (tyvs, tau) -> (tyvs, tau) | _ -> failwith "primDestForallTy: not a forall type") +let destFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> (tyv, tau) | _ -> failwith "destFunTy: not a function type") +let destAnyTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) -> tupInfo, l | _ -> failwith "destAnyTupleTy: not a tuple type") +let destRefTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) when not (evalTupInfoIsStruct tupInfo) -> l | _ -> failwith "destRefTupleTy: not a reference tuple type") +let destStructTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, l) when evalTupInfoIsStruct tupInfo -> l | _ -> failwith "destStructTupleTy: not a struct tuple type") +let destTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> v | _ -> failwith "destTyparTy: not a typar type") +let destAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> v | TType_measure unt -> destUnitParMeasure g unt | _ -> failwith "destAnyParTy: not a typar or unpar type") +let destMeasureTy g ty = ty |> stripTyEqns g |> (function TType_measure m -> m | _ -> failwith "destMeasureTy: not a unit-of-measure type") +let isFunTy g ty = ty |> stripTyEqns g |> (function TType_fun _ -> true | _ -> false) +let isForallTy g ty = ty |> stripTyEqns g |> (function TType_forall _ -> true | _ -> false) +let isAnyTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple _ -> true | _ -> false) +let isRefTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> not (evalTupInfoIsStruct tupInfo) | _ -> false) +let isStructTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> evalTupInfoIsStruct tupInfo | _ -> false) +let isAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon _ -> true | _ -> false) +let isStructAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, _) -> evalAnonInfoIsStruct anonInfo | _ -> false) +let isUnionTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsUnionTycon | _ -> false) +let isReprHiddenTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsHiddenReprTycon | _ -> false) +let isFSharpObjModelTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpObjectModelTycon | _ -> false) +let isRecdTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsRecordTycon | _ -> false) +let isFSharpStructOrEnumTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpStructOrEnumTycon | _ -> false) +let isFSharpEnumTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsFSharpEnumTycon | _ -> false) +let isTyparTy g ty = ty |> stripTyEqns g |> (function TType_var _ -> true | _ -> false) +let isAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var _ -> true | TType_measure unt -> isUnitParMeasure g unt | _ -> false) +let isMeasureTy g ty = ty |> stripTyEqns g |> (function TType_measure _ -> true | _ -> false) + + +let isProvenUnionCaseTy ty = match ty with TType_ucase _ -> true | _ -> false + +let mkAppTy tcref tyargs = TType_app(tcref, tyargs) +let mkProvenUnionCaseTy ucref tyargs = TType_ucase(ucref, tyargs) +let isAppTy g ty = ty |> stripTyEqns g |> (function TType_app _ -> true | _ -> false) +let tryAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> ValueSome (tcref, tinst) | _ -> ValueNone) +let destAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> tcref, tinst | _ -> failwith "destAppTy") +let tcrefOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref | _ -> failwith "tcrefOfAppTy") +let argsOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(_, tinst) -> tinst | _ -> []) +let tryDestTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | _ -> ValueNone) +let tryDestFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> ValueSome(tyv, tau) | _ -> ValueNone) +let tryTcrefOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> ValueSome tcref | _ -> ValueNone) +let tryDestAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, tys) -> ValueSome (anonInfo, tys) | _ -> ValueNone) + +let tryAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | TType_measure unt when isUnitParMeasure g unt -> ValueSome(destUnitParMeasure g unt) | _ -> ValueNone) +let tryAnyParTyOption g ty = ty |> stripTyEqns g |> (function TType_var v -> Some v | TType_measure unt when isUnitParMeasure g unt -> Some(destUnitParMeasure g unt) | _ -> None) +let (|AppTy|_|) g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> Some (tcref, tinst) | _ -> None) +let (|RefTupleTy|_|) g ty = ty |> stripTyEqns g |> (function TType_tuple(tupInfo, tys) when not (evalTupInfoIsStruct tupInfo) -> Some tys | _ -> None) +let (|FunTy|_|) g ty = ty |> stripTyEqns g |> (function TType_fun(dty, rty) -> Some (dty, rty) | _ -> None) + +let tryNiceEntityRefOfTy ty = + let ty = stripTyparEqnsAux false ty + match ty with + | TType_app (tcref, _) -> ValueSome tcref + | TType_measure (Measure.Con tcref) -> ValueSome tcref + | _ -> ValueNone + +let tryNiceEntityRefOfTyOption ty = + let ty = stripTyparEqnsAux false ty + match ty with + | TType_app (tcref, _) -> Some tcref + | TType_measure (Measure.Con tcref) -> Some tcref + | _ -> None + +let mkInstForAppTy g ty = + match tryAppTy g ty with + | ValueSome (tcref, tinst) -> mkTyconRefInst tcref tinst + | _ -> [] + +let domainOfFunTy g ty = fst (destFunTy g ty) +let rangeOfFunTy g ty = snd (destFunTy g ty) + +let convertToTypeWithMetadataIfPossible g ty = + if isAnyTupleTy g ty then + let tupInfo, tupElemTys = destAnyTupleTy g ty + mkOuterCompiledTupleTy g (evalTupInfoIsStruct tupInfo) tupElemTys + elif isFunTy g ty then + let a,b = destFunTy g ty + mkAppTy g.fastFunc_tcr [a; b] + else ty + +//--------------------------------------------------------------------------- +// TType modifications +//--------------------------------------------------------------------------- + +let stripMeasuresFromTType g tt = + match tt with + | TType_app(a,b) -> + let b' = b |> List.filter (isMeasureTy g >> not) + TType_app(a, b') + | _ -> tt + +//--------------------------------------------------------------------------- +// Equivalence of types up to alpha-equivalence +//--------------------------------------------------------------------------- + + +[] +type TypeEquivEnv = + { EquivTypars: TyparMap + EquivTycons: TyconRefRemap} + +// allocate a singleton +let typeEquivEnvEmpty = + { EquivTypars = TyparMap.Empty + EquivTycons = emptyTyconRefRemap } + +type TypeEquivEnv with + static member Empty = typeEquivEnvEmpty + + member aenv.BindTyparsToTypes tps1 tys2 = + { aenv with EquivTypars = (tps1, tys2, aenv.EquivTypars) |||> List.foldBack2 (fun tp ty tpmap -> tpmap.Add(tp, ty)) } + + member aenv.BindEquivTypars tps1 tps2 = + aenv.BindTyparsToTypes tps1 (List.map mkTyparTy tps2) + + static member FromTyparInst tpinst = + let tps, tys = List.unzip tpinst + TypeEquivEnv.Empty.BindTyparsToTypes tps tys + + static member FromEquivTypars tps1 tps2 = + TypeEquivEnv.Empty.BindEquivTypars tps1 tps2 + +let rec traitsAEquivAux erasureFlag g aenv traitInfo1 traitInfo2 = + let (TTrait(tys1, nm, mf1, argtys, rty, _)) = traitInfo1 + let (TTrait(tys2, nm2, mf2, argtys2, rty2, _)) = traitInfo2 + mf1 = mf2 && + nm = nm2 && + ListSet.equals (typeAEquivAux erasureFlag g aenv) tys1 tys2 && + returnTypesAEquivAux erasureFlag g aenv rty rty2 && + List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) argtys argtys2 + +and traitKeysAEquivAux erasureFlag g aenv (TraitWitnessInfo(tys1, nm, mf1, argtys, rty)) (TraitWitnessInfo(tys2, nm2, mf2, argtys2, rty2)) = + mf1 = mf2 && + nm = nm2 && + ListSet.equals (typeAEquivAux erasureFlag g aenv) tys1 tys2 && + returnTypesAEquivAux erasureFlag g aenv rty rty2 && + List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) argtys argtys2 + +and returnTypesAEquivAux erasureFlag g aenv rty rty2 = + match rty, rty2 with + | None, None -> true + | Some t1, Some t2 -> typeAEquivAux erasureFlag g aenv t1 t2 + | _ -> false + + +and typarConstraintsAEquivAux erasureFlag g aenv tpc1 tpc2 = + match tpc1, tpc2 with + | TyparConstraint.CoercesTo(acty, _), + TyparConstraint.CoercesTo(fcty, _) -> + typeAEquivAux erasureFlag g aenv acty fcty + + | TyparConstraint.MayResolveMember(trait1, _), + TyparConstraint.MayResolveMember(trait2, _) -> + traitsAEquivAux erasureFlag g aenv trait1 trait2 + + | TyparConstraint.DefaultsTo(_, acty, _), + TyparConstraint.DefaultsTo(_, fcty, _) -> + typeAEquivAux erasureFlag g aenv acty fcty + + | TyparConstraint.IsEnum(uty1, _), TyparConstraint.IsEnum(uty2, _) -> + typeAEquivAux erasureFlag g aenv uty1 uty2 + + | TyparConstraint.IsDelegate(aty1, bty1, _), TyparConstraint.IsDelegate(aty2, bty2, _) -> + typeAEquivAux erasureFlag g aenv aty1 aty2 && + typeAEquivAux erasureFlag g aenv bty1 bty2 + + | TyparConstraint.SimpleChoice (tys1, _), TyparConstraint.SimpleChoice(tys2, _) -> + ListSet.equals (typeAEquivAux erasureFlag g aenv) tys1 tys2 + + | TyparConstraint.SupportsComparison _, TyparConstraint.SupportsComparison _ + | TyparConstraint.SupportsEquality _, TyparConstraint.SupportsEquality _ + | TyparConstraint.SupportsNull _, TyparConstraint.SupportsNull _ + | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ + | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ + | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true + | _ -> false + +and typarConstraintSetsAEquivAux erasureFlag g aenv (tp1: Typar) (tp2: Typar) = + tp1.StaticReq = tp2.StaticReq && + ListSet.equals (typarConstraintsAEquivAux erasureFlag g aenv) tp1.Constraints tp2.Constraints + +and typarsAEquivAux erasureFlag g (aenv: TypeEquivEnv) tps1 tps2 = + List.length tps1 = List.length tps2 && + let aenv = aenv.BindEquivTypars tps1 tps2 + List.forall2 (typarConstraintSetsAEquivAux erasureFlag g aenv) tps1 tps2 + +and tcrefAEquiv g aenv tc1 tc2 = + tyconRefEq g tc1 tc2 || + (match aenv.EquivTycons.TryFind tc1 with Some v -> tyconRefEq g v tc2 | None -> false) + +and typeAEquivAux erasureFlag g aenv ty1 ty2 = + let ty1 = stripTyEqnsWrtErasure erasureFlag g ty1 + let ty2 = stripTyEqnsWrtErasure erasureFlag g ty2 + match ty1, ty2 with + | TType_forall(tps1, rty1), TType_forall(tps2, rty2) -> + typarsAEquivAux erasureFlag g aenv tps1 tps2 && typeAEquivAux erasureFlag g (aenv.BindEquivTypars tps1 tps2) rty1 rty2 + | TType_var tp1, TType_var tp2 when typarEq tp1 tp2 -> + true + | TType_var tp1, _ -> + match aenv.EquivTypars.TryFind tp1 with + | Some v -> typeEquivAux erasureFlag g v ty2 + | None -> false + | TType_app (tc1, b1), TType_app (tc2, b2) -> + tcrefAEquiv g aenv tc1 tc2 && + typesAEquivAux erasureFlag g aenv b1 b2 + | TType_ucase (UnionCaseRef(tc1, n1), b1), TType_ucase (UnionCaseRef(tc2, n2), b2) -> + n1=n2 && + tcrefAEquiv g aenv tc1 tc2 && + typesAEquivAux erasureFlag g aenv b1 b2 + | TType_tuple (s1, l1), TType_tuple (s2, l2) -> + structnessAEquiv s1 s2 && typesAEquivAux erasureFlag g aenv l1 l2 + | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> + anonInfoEquiv anonInfo1 anonInfo2 && + typesAEquivAux erasureFlag g aenv l1 l2 + | TType_fun (dtys1, rty1), TType_fun (dtys2, rty2) -> + typeAEquivAux erasureFlag g aenv dtys1 dtys2 && typeAEquivAux erasureFlag g aenv rty1 rty2 + | TType_measure m1, TType_measure m2 -> + match erasureFlag with + | EraseNone -> measureAEquiv g aenv m1 m2 + | _ -> true + | _ -> false + + +and anonInfoEquiv (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = + ccuEq anonInfo1.Assembly anonInfo2.Assembly && + structnessAEquiv anonInfo1.TupInfo anonInfo2.TupInfo && + anonInfo1.SortedNames = anonInfo2.SortedNames + +and structnessAEquiv un1 un2 = + match un1, un2 with + | TupInfo.Const b1, TupInfo.Const b2 -> (b1 = b2) + +and measureAEquiv g aenv un1 un2 = + let vars1 = ListMeasureVarOccs un1 + let trans tp1 = if aenv.EquivTypars.ContainsKey tp1 then destAnyParTy g aenv.EquivTypars.[tp1] else tp1 + let remapTyconRef tc = if aenv.EquivTycons.ContainsKey tc then aenv.EquivTycons.[tc] else tc + let vars1' = List.map trans vars1 + let vars2 = ListSet.subtract typarEq (ListMeasureVarOccs un2) vars1' + let cons1 = ListMeasureConOccsAfterRemapping g remapTyconRef un1 + let cons2 = ListMeasureConOccsAfterRemapping g remapTyconRef un2 + + List.forall (fun v -> MeasureVarExponent v un1 = MeasureVarExponent (trans v) un2) vars1 && + List.forall (fun v -> MeasureVarExponent v un1 = MeasureVarExponent v un2) vars2 && + List.forall (fun c -> MeasureConExponentAfterRemapping g remapTyconRef c un1 = MeasureConExponentAfterRemapping g remapTyconRef c un2) (cons1@cons2) + + +and typesAEquivAux erasureFlag g aenv l1 l2 = List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) l1 l2 +and typeEquivAux erasureFlag g ty1 ty2 = typeAEquivAux erasureFlag g TypeEquivEnv.Empty ty1 ty2 + +let typeAEquiv g aenv ty1 ty2 = typeAEquivAux EraseNone g aenv ty1 ty2 +let typeEquiv g ty1 ty2 = typeEquivAux EraseNone g ty1 ty2 +let traitsAEquiv g aenv t1 t2 = traitsAEquivAux EraseNone g aenv t1 t2 +let traitKeysAEquiv g aenv t1 t2 = traitKeysAEquivAux EraseNone g aenv t1 t2 +let typarConstraintsAEquiv g aenv c1 c2 = typarConstraintsAEquivAux EraseNone g aenv c1 c2 +let typarsAEquiv g aenv d1 d2 = typarsAEquivAux EraseNone g aenv d1 d2 +let returnTypesAEquiv g aenv t1 t2 = returnTypesAEquivAux EraseNone g aenv t1 t2 + +let measureEquiv g m1 m2 = measureAEquiv g TypeEquivEnv.Empty m1 m2 + +// Get measure of type, float<_> or float32<_> or decimal<_> but not float=float<1> or float32=float32<1> or decimal=decimal<1> +let getMeasureOfType g ty = + match ty with + | AppTy g (tcref, [tyarg]) -> + match stripTyEqns g tyarg with + | TType_measure ms when not (measureEquiv g ms Measure.One) -> Some (tcref, ms) + | _ -> None + | _ -> None + +let isErasedType g ty = + match stripTyEqns g ty with +#if !NO_EXTENSIONTYPING + | TType_app (tcref, _) -> tcref.IsProvidedErasedTycon +#endif + | _ -> false + +// Return all components of this type expression that cannot be tested at runtime +let rec getErasedTypes g ty = + let ty = stripTyEqns g ty + if isErasedType g ty then [ty] else + match ty with + | TType_forall(_, rty) -> + getErasedTypes g rty + | TType_var tp -> + if tp.IsErased then [ty] else [] + | TType_app (_, b) | TType_ucase(_, b) | TType_anon (_, b) | TType_tuple (_, b) -> + List.foldBack (fun ty tys -> getErasedTypes g ty @ tys) b [] + | TType_fun (dty, rty) -> + getErasedTypes g dty @ getErasedTypes g rty + | TType_measure _ -> + [ty] + + +//--------------------------------------------------------------------------- +// Standard orderings, e.g. for order set/map keys +//--------------------------------------------------------------------------- + +let valOrder = { new IComparer with member _.Compare(v1, v2) = compare v1.Stamp v2.Stamp } +let tyconOrder = { new IComparer with member _.Compare(tc1, tc2) = compare tc1.Stamp tc2.Stamp } +let recdFieldRefOrder = + { new IComparer with + member _.Compare(RecdFieldRef(tcref1, nm1), RecdFieldRef(tcref2, nm2)) = + let c = tyconOrder.Compare (tcref1.Deref, tcref2.Deref) + if c <> 0 then c else + compare nm1 nm2 } + +let unionCaseRefOrder = + { new IComparer with + member _.Compare(UnionCaseRef(tcref1, nm1), UnionCaseRef(tcref2, nm2)) = + let c = tyconOrder.Compare (tcref1.Deref, tcref2.Deref) + if c <> 0 then c else + compare nm1 nm2 } + +//--------------------------------------------------------------------------- +// Make some common types +//--------------------------------------------------------------------------- + +let mkFunTy d r = TType_fun (d, r) + +let (-->) d r = mkFunTy d r + +let mkForallTy d r = TType_forall (d, r) + +let mkForallTyIfNeeded d r = if isNil d then r else mkForallTy d r + +let (+->) d r = mkForallTyIfNeeded d r + +let mkIteratedFunTy dl r = List.foldBack (-->) dl r + +let mkLambdaArgTy m tys = + match tys with + | [] -> error(InternalError("mkLambdaArgTy", m)) + | [h] -> h + | _ -> mkRawRefTupleTy tys + +let typeOfLambdaArg m vs = mkLambdaArgTy m (typesOfVals vs) +let mkMultiLambdaTy m vs rty = mkFunTy (typeOfLambdaArg m vs) rty +let mkLambdaTy tps tys rty = mkForallTyIfNeeded tps (mkIteratedFunTy tys rty) + +/// When compiling FSharp.Core.dll we have to deal with the non-local references into +/// the library arising from env.fs. Part of this means that we have to be able to resolve these +/// references. This function artificially forces the existence of a module or namespace at a +/// particular point in order to do this. +let ensureCcuHasModuleOrNamespaceAtPath (ccu: CcuThunk) path (CompPath(_, cpath)) xml = + let scoref = ccu.ILScopeRef + let rec loop prior_cpath (path: Ident list) cpath (modul: ModuleOrNamespace) = + let mtype = modul.ModuleOrNamespaceType + match path, cpath with + | hpath :: tpath, (_, mkind) :: tcpath -> + let modName = hpath.idText + if not (Map.containsKey modName mtype.AllEntitiesByCompiledAndLogicalMangledNames) then + let mty = Construct.NewEmptyModuleOrNamespaceType mkind + let cpath = CompPath(scoref, prior_cpath) + let smodul = Construct.NewModuleOrNamespace (Some cpath) taccessPublic hpath xml [] (MaybeLazy.Strict mty) + mtype.AddModuleOrNamespaceByMutation smodul + let modul = Map.find modName mtype.AllEntitiesByCompiledAndLogicalMangledNames + loop (prior_cpath @ [(modName, Namespace)]) tpath tcpath modul + + | _ -> () + + loop [] path cpath ccu.Contents + + +//--------------------------------------------------------------------------- +// Primitive destructors +//--------------------------------------------------------------------------- + +/// Look through the Expr.Link nodes arising from type inference +let rec stripExpr e = + match e with + | Expr.Link eref -> stripExpr !eref + | _ -> e + +let mkCase (a, b) = TCase(a, b) + +let isRefTupleExpr e = match e with Expr.Op (TOp.Tuple tupInfo, _, _, _) -> not (evalTupInfoIsStruct tupInfo) | _ -> false +let tryDestRefTupleExpr e = match e with Expr.Op (TOp.Tuple tupInfo, _, es, _) when not (evalTupInfoIsStruct tupInfo) -> es | _ -> [e] + +//--------------------------------------------------------------------------- +// Range info for expressions +//--------------------------------------------------------------------------- + +let rec rangeOfExpr x = + match x with + | Expr.Val (_, _, m) | Expr.Op (_, _, _, m) | Expr.Const (_, m, _) | Expr.Quote (_, _, _, m, _) + | Expr.Obj (_, _, _, _, _, _, m) | Expr.App (_, _, _, _, m) | Expr.Sequential (_, _, _, _, m) + | Expr.StaticOptimization (_, _, _, m) | Expr.Lambda (_, _, _, _, _, m, _) + | Expr.WitnessArg (_, m) + | Expr.TyLambda (_, _, _, m, _)| Expr.TyChoose (_, _, m) | Expr.LetRec (_, _, m, _) | Expr.Let (_, _, m, _) | Expr.Match (_, _, _, _, m, _) -> m + | Expr.Link eref -> rangeOfExpr (!eref) + +type Expr with + member x.Range = rangeOfExpr x + +//--------------------------------------------------------------------------- +// Build nodes in decision graphs +//--------------------------------------------------------------------------- + + +let primMkMatch(spBind, exprm, tree, targets, matchm, ty) = Expr.Match (spBind, exprm, tree, targets, matchm, ty) + +type MatchBuilder(spBind, inpRange: range) = + + let targets = ResizeArray<_>(10) + member x.AddTarget tg = + let n = targets.Count + targets.Add tg + n + + member x.AddResultTarget(e, spTarget) = TDSuccess([], x.AddTarget(TTarget([], e, spTarget, None))) + + member x.CloseTargets() = targets |> ResizeArray.toList + + member x.Close(dtree, m, ty) = primMkMatch (spBind, inpRange, dtree, targets.ToArray(), m, ty) + +let mkBoolSwitch debugPoint m g t e = + TDSwitch(debugPoint, g, [TCase(DecisionTreeTest.Const(Const.Bool true), t)], Some e, m) + +let primMkCond spBind spTarget1 spTarget2 m ty e1 e2 e3 = + let mbuilder = MatchBuilder(spBind, m) + let dtree = mkBoolSwitch DebugPointAtSwitch.No m e1 (mbuilder.AddResultTarget(e2, spTarget1)) (mbuilder.AddResultTarget(e3, spTarget2)) + mbuilder.Close(dtree, m, ty) + +let mkCond spBind spTarget m ty e1 e2 e3 = + primMkCond spBind spTarget spTarget m ty e1 e2 e3 + +//--------------------------------------------------------------------------- +// Primitive constructors +//--------------------------------------------------------------------------- + +let exprForValRef m vref = Expr.Val (vref, NormalValUse, m) +let exprForVal m v = exprForValRef m (mkLocalValRef v) +let mkLocalAux m s ty mut compgen = + let thisv = Construct.NewVal(s, m, None, ty, mut, compgen, None, taccessPublic, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, XmlDoc.Empty, false, false, false, false, false, false, None, ParentNone) + thisv, exprForVal m thisv + +let mkLocal m s ty = mkLocalAux m s ty Immutable false +let mkCompGenLocal m s ty = mkLocalAux m s ty Immutable true +let mkMutableCompGenLocal m s ty = mkLocalAux m s ty Mutable true + + +// Type gives return type. For type-lambdas this is the formal return type. +let mkMultiLambda m vs (b, rty) = Expr.Lambda (newUnique(), None, None, vs, b, m, rty) +let rebuildLambda m ctorThisValOpt baseValOpt vs (b, rty) = Expr.Lambda (newUnique(), ctorThisValOpt, baseValOpt, vs, b, m, rty) +let mkLambda m v (b, rty) = mkMultiLambda m [v] (b, rty) +let mkTypeLambda m vs (b, tau_ty) = match vs with [] -> b | _ -> Expr.TyLambda (newUnique(), vs, b, m, tau_ty) +let mkTypeChoose m vs b = match vs with [] -> b | _ -> Expr.TyChoose (vs, b, m) + +let mkObjExpr (ty, basev, basecall, overrides, iimpls, m) = + Expr.Obj (newUnique(), ty, basev, basecall, overrides, iimpls, m) + +let mkLambdas m tps (vs: Val list) (b, rty) = + mkTypeLambda m tps (List.foldBack (fun v (e, ty) -> mkLambda m v (e, ty), v.Type --> ty) vs (b, rty)) + +let mkMultiLambdasCore m vsl (b, rty) = + List.foldBack (fun v (e, ty) -> mkMultiLambda m v (e, ty), typeOfLambdaArg m v --> ty) vsl (b, rty) + +let mkMultiLambdas m tps vsl (b, rty) = + mkTypeLambda m tps (mkMultiLambdasCore m vsl (b, rty) ) + +let mkMemberLambdas m tps ctorThisValOpt baseValOpt vsl (b, rty) = + let expr = + match ctorThisValOpt, baseValOpt with + | None, None -> mkMultiLambdasCore m vsl (b, rty) + | _ -> + match vsl with + | [] -> error(InternalError("mk_basev_multi_lambdas_core: can't attach a basev to a non-lambda expression", m)) + | h :: t -> + let b, rty = mkMultiLambdasCore m t (b, rty) + (rebuildLambda m ctorThisValOpt baseValOpt h (b, rty), (typeOfLambdaArg m h --> rty)) + mkTypeLambda m tps expr + +let mkMultiLambdaBind v letSeqPtOpt m tps vsl (b, rty) = + TBind(v, mkMultiLambdas m tps vsl (b, rty), letSeqPtOpt) + +let mkBind seqPtOpt v e = TBind(v, e, seqPtOpt) + +let mkLetBind m bind body = Expr.Let (bind, body, m, Construct.NewFreeVarsCache()) +let mkLetsBind m binds body = List.foldBack (mkLetBind m) binds body +let mkLetsFromBindings m binds body = List.foldBack (mkLetBind m) binds body +let mkLet seqPtOpt m v x body = mkLetBind m (mkBind seqPtOpt v x) body + +/// Make sticky bindings that are compiler generated (though the variables may not be - e.g. they may be lambda arguments in a beta reduction) +let mkCompGenBind v e = TBind(v, e, DebugPointAtBinding.NoneAtSticky) +let mkCompGenBinds (vs: Val list) (es: Expr list) = List.map2 mkCompGenBind vs es +let mkCompGenLet m v x body = mkLetBind m (mkCompGenBind v x) body +let mkCompGenLets m vs xs body = mkLetsBind m (mkCompGenBinds vs xs) body +let mkCompGenLetsFromBindings m vs xs body = mkLetsFromBindings m (mkCompGenBinds vs xs) body + +let mkInvisibleBind v e = TBind(v, e, DebugPointAtBinding.NoneAtInvisible) +let mkInvisibleBinds (vs: Val list) (es: Expr list) = List.map2 mkInvisibleBind vs es +let mkInvisibleLet m v x body = mkLetBind m (mkInvisibleBind v x) body +let mkInvisibleLets m vs xs body = mkLetsBind m (mkInvisibleBinds vs xs) body +let mkInvisibleLetsFromBindings m vs xs body = mkLetsFromBindings m (mkInvisibleBinds vs xs) body + +let mkLetRecBinds m binds body = + if isNil binds then + body + else + Expr.LetRec (binds, body, m, Construct.NewFreeVarsCache()) + +//------------------------------------------------------------------------- +// Type schemes... +//------------------------------------------------------------------------- + +// Type parameters may be have been equated to other tps in equi-recursive type inference +// and unit type inference. Normalize them here +let NormalizeDeclaredTyparsForEquiRecursiveInference g tps = + match tps with + | [] -> [] + | tps -> + tps |> List.map (fun tp -> + let ty = mkTyparTy tp + match tryAnyParTy g ty with + | ValueSome anyParTy -> anyParTy + | ValueNone -> tp) + +type TypeScheme = TypeScheme of Typars * TType + +let mkGenericBindRhs g m generalizedTyparsForRecursiveBlock typeScheme bodyExpr = + let (TypeScheme(generalizedTypars, tauType)) = typeScheme + + // Normalize the generalized typars + let generalizedTypars = NormalizeDeclaredTyparsForEquiRecursiveInference g generalizedTypars + + // Some recursive bindings result in free type variables, e.g. + // let rec f (x:'a) = () + // and g() = f y |> ignore + // What is the type of y? Type inference equates it to 'a. + // But "g" is not polymorphic in 'a. Hence we get a free choice of "'a" + // in the scope of "g". Thus at each individual recursive binding we record all + // type variables for which we have a free choice, which is precisely the difference + // between the union of all sets of generalized type variables and the set generalized + // at each particular binding. + // + // We record an expression node that indicates that a free choice can be made + // for these. This expression node effectively binds the type variables. + let freeChoiceTypars = ListSet.subtract typarEq generalizedTyparsForRecursiveBlock generalizedTypars + mkTypeLambda m generalizedTypars (mkTypeChoose m freeChoiceTypars bodyExpr, tauType) + +let isBeingGeneralized tp typeScheme = + let (TypeScheme(generalizedTypars, _)) = typeScheme + ListSet.contains typarRefEq tp generalizedTypars + +//------------------------------------------------------------------------- +// Build conditional expressions... +//------------------------------------------------------------------------- + +let mkBool (g: TcGlobals) m b = Expr.Const (Const.Bool b, m, g.bool_ty) + +let mkTrue g m = mkBool g m true + +let mkFalse g m = mkBool g m false + +let mkLazyOr (g: TcGlobals) m e1 e2 = + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.bool_ty e1 (mkTrue g m) e2 + +let mkLazyAnd (g: TcGlobals) m e1 e2 = + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.bool_ty e1 e2 (mkFalse g m) + +let mkCoerceExpr(e, to_ty, m, from_ty) = Expr.Op (TOp.Coerce, [to_ty;from_ty], [e], m) + +let mkAsmExpr (code, tinst, args, rettys, m) = Expr.Op (TOp.ILAsm (code, rettys), tinst, args, m) + +let mkUnionCaseExpr(uc, tinst, args, m) = Expr.Op (TOp.UnionCase uc, tinst, args, m) + +let mkExnExpr(uc, args, m) = Expr.Op (TOp.ExnConstr uc, [], args, m) + +let mkTupleFieldGetViaExprAddr(tupInfo, e, tinst, i, m) = Expr.Op (TOp.TupleFieldGet (tupInfo, i), tinst, [e], m) + +let mkAnonRecdFieldGetViaExprAddr(anonInfo, e, tinst, i, m) = Expr.Op (TOp.AnonRecdGet (anonInfo, i), tinst, [e], m) + +let mkRecdFieldGetViaExprAddr (e, fref, tinst, m) = Expr.Op (TOp.ValFieldGet fref, tinst, [e], m) + +let mkRecdFieldGetAddrViaExprAddr(readonly, e, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr (fref, readonly), tinst, [e], m) + +let mkStaticRecdFieldGetAddr(readonly, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr (fref, readonly), tinst, [], m) + +let mkStaticRecdFieldGet (fref, tinst, m) = Expr.Op (TOp.ValFieldGet fref, tinst, [], m) + +let mkStaticRecdFieldSet(fref, tinst, e, m) = Expr.Op (TOp.ValFieldSet fref, tinst, [e], m) + +let mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, exprs, m) = + Expr.Op (TOp.ILAsm ([I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTyWithFlag g readonly elemTy]), [elemTy], exprs, m) + +let mkRecdFieldSetViaExprAddr (e1, fref, tinst, e2, m) = Expr.Op (TOp.ValFieldSet fref, tinst, [e1;e2], m) + +let mkUnionCaseTagGetViaExprAddr (e1, cref, tinst, m) = Expr.Op (TOp.UnionCaseTagGet cref, tinst, [e1], m) + +/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) +let mkUnionCaseProof (e1, cref: UnionCaseRef, tinst, m) = if cref.Tycon.IsStructOrEnumTycon then e1 else Expr.Op (TOp.UnionCaseProof cref, tinst, [e1], m) + +/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions, +/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +let mkUnionCaseFieldGetProvenViaExprAddr (e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGet (cref, j), tinst, [e1], m) + +/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, +/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +let mkUnionCaseFieldGetAddrProvenViaExprAddr (readonly, e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGetAddr (cref, j, readonly), tinst, [e1], m) + +/// Build a 'get' expression for something we've already determined to be a particular union case, but where +/// the static type of the input is not yet proven to be that particular union case. This requires a type +/// cast to 'prove' the condition. +let mkUnionCaseFieldGetUnprovenViaExprAddr (e1, cref, tinst, j, m) = mkUnionCaseFieldGetProvenViaExprAddr (mkUnionCaseProof(e1, cref, tinst, m), cref, tinst, j, m) + +let mkUnionCaseFieldSet (e1, cref, tinst, j, e2, m) = Expr.Op (TOp.UnionCaseFieldSet (cref, j), tinst, [e1;e2], m) + +let mkExnCaseFieldGet (e1, ecref, j, m) = Expr.Op (TOp.ExnFieldGet (ecref, j), [], [e1], m) + +let mkExnCaseFieldSet (e1, ecref, j, e2, m) = Expr.Op (TOp.ExnFieldSet (ecref, j), [], [e1;e2], m) + +let mkDummyLambda (g: TcGlobals) (e: Expr, ety) = + let m = e.Range + mkLambda m (fst (mkCompGenLocal m "unitVar" g.unit_ty)) (e, ety) + +let mkWhile (g: TcGlobals) (spWhile, marker, e1, e2, m) = + Expr.Op (TOp.While (spWhile, marker), [], [mkDummyLambda g (e1, g.bool_ty);mkDummyLambda g (e2, g.unit_ty)], m) + +let mkFor (g: TcGlobals) (spFor, v, e1, dir, e2, e3: Expr, m) = + Expr.Op (TOp.For (spFor, dir), [], [mkDummyLambda g (e1, g.int_ty) ;mkDummyLambda g (e2, g.int_ty);mkLambda e3.Range v (e3, g.unit_ty)], m) + +let mkTryWith g (e1, vf, ef: Expr, vh, eh: Expr, m, ty, spTry, spWith) = + Expr.Op (TOp.TryWith (spTry, spWith), [ty], [mkDummyLambda g (e1, ty);mkLambda ef.Range vf (ef, ty);mkLambda eh.Range vh (eh, ty)], m) + +let mkTryFinally (g: TcGlobals) (e1, e2, m, ty, spTry, spFinally) = + Expr.Op (TOp.TryFinally (spTry, spFinally), [ty], [mkDummyLambda g (e1, ty);mkDummyLambda g (e2, g.unit_ty)], m) + +let mkDefault (m, ty) = Expr.Const (Const.Zero, m, ty) + +let mkValSet m v e = Expr.Op (TOp.LValueOp (LSet, v), [], [e], m) +let mkAddrSet m v e = Expr.Op (TOp.LValueOp (LByrefSet, v), [], [e], m) +let mkAddrGet m v = Expr.Op (TOp.LValueOp (LByrefGet, v), [], [], m) +let mkValAddr m readonly v = Expr.Op (TOp.LValueOp (LAddrOf readonly, v), [], [], m) + +//-------------------------------------------------------------------------- +// Maps tracking extra information for values +//-------------------------------------------------------------------------- + +[] +type ValHash<'T> = + | ValHash of Dictionary + + member ht.Values = + let (ValHash t) = ht + t.Values :> seq<'T> + + member ht.TryFind (v: Val) = + let (ValHash t) = ht + match t.TryGetValue v.Stamp with + | true, v -> Some v + | _ -> None + + member ht.Add (v: Val, x) = + let (ValHash t) = ht + t.[v.Stamp] <- x + + static member Create() = ValHash (new Dictionary<_, 'T>(11)) + +[] +type ValMultiMap<'T>(contents: StampMap<'T list>) = + + member m.ContainsKey (v: Val) = + contents.ContainsKey v.Stamp + + member m.Find (v: Val) = + match contents |> Map.tryFind v.Stamp with + | Some vals -> vals + | _ -> [] + + member m.Add (v: Val, x) = ValMultiMap<'T>(contents.Add (v.Stamp, x :: m.Find v)) + + member m.Remove (v: Val) = ValMultiMap<'T>(contents.Remove v.Stamp) + + member m.Contents = contents + + static member Empty = ValMultiMap<'T>(Map.empty) + +[] +type TyconRefMultiMap<'T>(contents: TyconRefMap<'T list>) = + member m.Find v = + match contents.TryFind v with + | Some vals -> vals + | _ -> [] + + member m.Add (v, x) = TyconRefMultiMap<'T>(contents.Add v (x :: m.Find v)) + static member Empty = TyconRefMultiMap<'T>(TyconRefMap<_>.Empty) + static member OfList vs = (vs, TyconRefMultiMap<'T>.Empty) ||> List.foldBack (fun (x, y) acc -> acc.Add (x, y)) + + +//-------------------------------------------------------------------------- +// From Ref_private to Ref_nonlocal when exporting data. +//-------------------------------------------------------------------------- + +/// Try to create a EntityRef suitable for accessing the given Entity from another assembly +let tryRescopeEntity viewedCcu (entity: Entity) : ValueOption = + match entity.PublicPath with + | Some pubpath -> ValueSome (ERefNonLocal (rescopePubPath viewedCcu pubpath)) + | None -> ValueNone + +/// Try to create a ValRef suitable for accessing the given Val from another assembly +let tryRescopeVal viewedCcu (entityRemap: Remap) (vspec: Val) : ValueOption = + match vspec.PublicPath with + | Some (ValPubPath(p, fullLinkageKey)) -> + // The type information in the val linkage doesn't need to keep any information to trait solutions. + let entityRemap = { entityRemap with removeTraitSolutions = true } + let fullLinkageKey = remapValLinkage entityRemap fullLinkageKey + let vref = + // This compensates for the somewhat poor design decision in the F# compiler and metadata where + // members are stored as values under the enclosing namespace/module rather than under the type. + // This stems from the days when types and namespace/modules were separated constructs in the + // compiler implementation. + if vspec.IsIntrinsicMember then + mkNonLocalValRef (rescopePubPathToParent viewedCcu p) fullLinkageKey + else + mkNonLocalValRef (rescopePubPath viewedCcu p) fullLinkageKey + ValueSome vref + | _ -> ValueNone + +//--------------------------------------------------------------------------- +// Type information about records, constructors etc. +//--------------------------------------------------------------------------- + +let actualTyOfRecdField inst (fspec: RecdField) = instType inst fspec.FormalType + +let actualTysOfRecdFields inst rfields = List.map (actualTyOfRecdField inst) rfields + +let actualTysOfInstanceRecdFields inst (tcref: TyconRef) = tcref.AllInstanceFieldsAsList |> actualTysOfRecdFields inst + +let actualTysOfUnionCaseFields inst (x: UnionCaseRef) = actualTysOfRecdFields inst x.AllFieldsAsList + +let actualResultTyOfUnionCase tinst (x: UnionCaseRef) = + instType (mkTyconRefInst x.TyconRef tinst) x.ReturnType + +let recdFieldsOfExnDefRef x = (stripExnEqns x).TrueInstanceFieldsAsList +let recdFieldOfExnDefRefByIdx x n = (stripExnEqns x).GetFieldByIndex n + +let recdFieldTysOfExnDefRef x = actualTysOfRecdFields [] (recdFieldsOfExnDefRef x) +let recdFieldTyOfExnDefRefByIdx x j = actualTyOfRecdField [] (recdFieldOfExnDefRefByIdx x j) + + +let actualTyOfRecdFieldForTycon tycon tinst (fspec: RecdField) = + instType (mkTyconInst tycon tinst) fspec.FormalType + +let actualTyOfRecdFieldRef (fref: RecdFieldRef) tinst = + actualTyOfRecdFieldForTycon fref.Tycon tinst fref.RecdField + +let actualTyOfUnionFieldRef (fref: UnionCaseRef) n tinst = + actualTyOfRecdFieldForTycon fref.Tycon tinst (fref.FieldByIndex n) + + +//--------------------------------------------------------------------------- +// Apply type functions to types +//--------------------------------------------------------------------------- + +let destForallTy g ty = + let tps, tau = primDestForallTy g ty + // tps may be have been equated to other tps in equi-recursive type inference + // and unit type inference. Normalize them here + let tps = NormalizeDeclaredTyparsForEquiRecursiveInference g tps + tps, tau + +let tryDestForallTy g ty = + if isForallTy g ty then destForallTy g ty else [], ty + +let rec stripFunTy g ty = + if isFunTy g ty then + let d, r = destFunTy g ty + let more, rty = stripFunTy g r + d :: more, rty + else [], ty + +let applyForallTy g ty tyargs = + let tps, tau = destForallTy g ty + instType (mkTyparInst tps tyargs) tau + +let reduceIteratedFunTy g ty args = + List.fold (fun ty _ -> + if not (isFunTy g ty) then failwith "reduceIteratedFunTy" + snd (destFunTy g ty)) ty args + +let applyTyArgs g functy tyargs = + if isForallTy g functy then applyForallTy g functy tyargs else functy + +let applyTys g functy (tyargs, argtys) = + let afterTyappTy = applyTyArgs g functy tyargs + reduceIteratedFunTy g afterTyappTy argtys + +let formalApplyTys g functy (tyargs, args) = + reduceIteratedFunTy g + (if isNil tyargs then functy else snd (destForallTy g functy)) + args + +let rec stripFunTyN g n ty = + assert (n >= 0) + if n > 0 && isFunTy g ty then + let d, r = destFunTy g ty + let more, rty = stripFunTyN g (n-1) r in d :: more, rty + else [], ty + + +let tryDestAnyTupleTy g ty = + if isAnyTupleTy g ty then destAnyTupleTy g ty else tupInfoRef, [ty] + +let tryDestRefTupleTy g ty = + if isRefTupleTy g ty then destRefTupleTy g ty else [ty] + +type UncurriedArgInfos = (TType * ArgReprInfo) list + +type CurriedArgInfos = (TType * ArgReprInfo) list list + +type TraitWitnessInfos = TraitWitnessInfo list + +// A 'tau' type is one with its type parameters stripped off +let GetTopTauTypeInFSharpForm g (curriedArgInfos: ArgReprInfo list list) tau m = + let nArgInfos = curriedArgInfos.Length + let argtys, rty = stripFunTyN g nArgInfos tau + if nArgInfos <> argtys.Length then + error(Error(FSComp.SR.tastInvalidMemberSignature(), m)) + let argtysl = + (curriedArgInfos, argtys) ||> List.map2 (fun argInfos argty -> + match argInfos with + | [] -> [ (g.unit_ty, ValReprInfo.unnamedTopArg1) ] + | [argInfo] -> [ (argty, argInfo) ] + | _ -> List.zip (destRefTupleTy g argty) argInfos) + argtysl, rty + +let destTopForallTy g (ValReprInfo (ntps, _, _)) ty = + let tps, tau = (if isNil ntps then [], ty else tryDestForallTy g ty) + // tps may be have been equated to other tps in equi-recursive type inference. Normalize them here + let tps = NormalizeDeclaredTyparsForEquiRecursiveInference g tps + tps, tau + +let GetTopValTypeInFSharpForm g (ValReprInfo(_, argInfos, retInfo) as topValInfo) ty m = + let tps, tau = destTopForallTy g topValInfo ty + let curriedArgTys, returnTy = GetTopTauTypeInFSharpForm g argInfos tau m + tps, curriedArgTys, returnTy, retInfo + +let IsCompiledAsStaticProperty g (v: Val) = + match v.ValReprInfo with + | Some valReprInfoValue -> + match GetTopValTypeInFSharpForm g valReprInfoValue v.Type v.Range with + | [], [], _, _ when not v.IsMember -> true + | _ -> false + | _ -> false + +let IsCompiledAsStaticPropertyWithField g (v: Val) = + (not v.IsCompiledAsStaticPropertyWithoutField && IsCompiledAsStaticProperty g v) + +//------------------------------------------------------------------------- +// Multi-dimensional array types... +//------------------------------------------------------------------------- + +let isArrayTyconRef (g: TcGlobals) tcref = + g.il_arr_tcr_map + |> Array.exists (tyconRefEq g tcref) + +let rankOfArrayTyconRef (g: TcGlobals) tcref = + match g.il_arr_tcr_map |> Array.tryFindIndex (tyconRefEq g tcref) with + | Some idx -> + idx + 1 + | None -> + failwith "rankOfArrayTyconRef: unsupported array rank" + +//------------------------------------------------------------------------- +// Misc functions on F# types +//------------------------------------------------------------------------- + +let destArrayTy (g: TcGlobals) ty = + match tryAppTy g ty with + | ValueSome (tcref, [ty]) when isArrayTyconRef g tcref -> ty + | _ -> failwith "destArrayTy" + +let destListTy (g: TcGlobals) ty = + match tryAppTy g ty with + | ValueSome (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty + | _ -> failwith "destListTy" + +let tyconRefEqOpt g tcOpt tc = + match tcOpt with + | None -> false + | Some tc2 -> tyconRefEq g tc2 tc + +let isStringTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.system_String_tcref | _ -> false) +let isListTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.list_tcr_canon | _ -> false) +let isArrayTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isArrayTyconRef g tcref | _ -> false) +let isArray1DTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.il_arr_tcr_map.[0] | _ -> false) +let isUnitTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.unit_tcr_canon tcref | _ -> false) +let isObjTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Object_tcref tcref | _ -> false) +let isValueTypeTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Value_tcref tcref | _ -> false) +let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Void_tcref tcref | _ -> false) +let isILAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsILTycon | _ -> false) +let isNativePtrTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.nativeptr_tcr tcref | _ -> false) + +let isByrefTy g ty = + ty |> stripTyEqns g |> (function + | TType_app(tcref, _) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref + | TType_app(tcref, _) -> tyconRefEq g g.byref_tcr tcref + | _ -> false) + +let isInByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_In_tcr tcref | _ -> false) +let isInByrefTy g ty = + ty |> stripTyEqns g |> (function + | TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isInByrefTag g tag + | _ -> false) + +let isOutByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_Out_tcr tcref | _ -> false) +let isOutByrefTy g ty = + ty |> stripTyEqns g |> (function + | TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isOutByrefTag g tag + | _ -> false) + +#if !NO_EXTENSIONTYPING +let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr) +#endif + +type TypeDefMetadata = + | ILTypeMetadata of TILObjectReprData + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata of TProvidedTypeInfo +#endif + +let metadataOfTycon (tycon: Tycon) = +#if !NO_EXTENSIONTYPING + match tycon.TypeReprInfo with + | TProvidedTypeRepr info -> ProvidedTypeMetadata info + | _ -> +#endif + if tycon.IsILTycon then + ILTypeMetadata tycon.ILTyconInfo + else + FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata + + +let metadataOfTy g ty = +#if !NO_EXTENSIONTYPING + match extensionInfoOfTy g ty with + | TProvidedTypeRepr info -> ProvidedTypeMetadata info + | _ -> +#endif + if isILAppTy g ty then + let tcref = tcrefOfAppTy g ty + ILTypeMetadata tcref.ILTyconInfo + else + FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata + + +let isILReferenceTy g ty = + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> not info.IsStructOrEnum +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> not td.IsStructOrEnum + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isArrayTy g ty + +let isILInterfaceTycon (tycon: Tycon) = + match metadataOfTycon tycon with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> info.IsInterface +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsInterface + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> false + +let rankOfArrayTy g ty = rankOfArrayTyconRef g (tcrefOfAppTy g ty) + +let isFSharpObjModelRefTy g ty = + isFSharpObjModelTy g ty && + let tcref = tcrefOfAppTy g ty + match tcref.FSharpObjectModelTypeInfo.fsobjmodel_kind with + | TFSharpClass | TFSharpInterface | TFSharpDelegate _ -> true + | TFSharpStruct | TFSharpEnum -> false + +let isFSharpClassTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsFSharpClassTycon + | _ -> false + +let isFSharpStructTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsFSharpStructOrEnumTycon + | _ -> false + +let isFSharpInterfaceTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsFSharpInterfaceTycon + | _ -> false + +let isDelegateTy g ty = + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> info.IsDelegate () +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsDelegate + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsFSharpDelegateTycon + | _ -> false + +let isInterfaceTy g ty = + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> info.IsInterface +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsInterface + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isFSharpInterfaceTy g ty + +let isFSharpDelegateTy g ty = isDelegateTy g ty && isFSharpObjModelTy g ty + +let isClassTy g ty = + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> info.IsClass +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsClass + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> isFSharpClassTy g ty + +let isStructOrEnumTyconTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsStructOrEnumTycon + | _ -> false + +let isStructRecordOrUnionTyconTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.Deref.IsStructRecordOrUnionTycon + | _ -> false + +let isStructTyconRef (tcref: TyconRef) = + let tycon = tcref.Deref + tycon.IsStructRecordOrUnionTycon || tycon.IsStructOrEnumTycon + +let isStructTy g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + isStructTyconRef tcref + | _ -> + isStructAnonRecdTy g ty || isStructTupleTy g ty + +let isRefTy g ty = + not (isStructOrEnumTyconTy g ty) && + ( + isUnionTy g ty || + isRefTupleTy g ty || + isRecdTy g ty || + isILReferenceTy g ty || + isFunTy g ty || + isReprHiddenTy g ty || + isFSharpObjModelRefTy g ty || + isUnitTy g ty || + (isAnonRecdTy g ty && not (isStructAnonRecdTy g ty)) + ) + +let isForallFunctionTy g ty = + let _, tau = tryDestForallTy g ty + isFunTy g tau + +// ECMA C# LANGUAGE SPECIFICATION, 27.2 +// An unmanaged-type is any type that isn't a reference-type, a type-parameter, or a generic struct-type and +// contains no fields whose type is not an unmanaged-type. In other words, an unmanaged-type is one of the +// following: +// - sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool. +// - Any enum-type. +// - Any pointer-type. +// - Any non-generic user-defined struct-type that contains fields of unmanaged-types only. +// [Note: Constructed types and type-parameters are never unmanaged-types. end note] +let rec isUnmanagedTy g ty = + let ty = stripTyEqnsAndMeasureEqns g ty + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + let isEq tcref2 = tyconRefEq g tcref tcref2 + if isEq g.nativeptr_tcr || isEq g.nativeint_tcr || + isEq g.sbyte_tcr || isEq g.byte_tcr || + isEq g.int16_tcr || isEq g.uint16_tcr || + isEq g.int32_tcr || isEq g.uint32_tcr || + isEq g.int64_tcr || isEq g.uint64_tcr || + isEq g.char_tcr || + isEq g.float32_tcr || + isEq g.float_tcr || + isEq g.decimal_tcr || + isEq g.bool_tcr then + true + else + let tycon = tcref.Deref + if tycon.IsEnumTycon then + true + elif tycon.IsStructOrEnumTycon then + match tycon.TyparsNoRange with + | [] -> tycon.AllInstanceFieldsAsList |> List.forall (fun r -> isUnmanagedTy g r.rfield_type) + | _ -> false // generic structs are never + else false + | ValueNone -> + false + +let isInterfaceTycon x = + isILInterfaceTycon x || x.IsFSharpInterfaceTycon + +let isInterfaceTyconRef (tcref: TyconRef) = isInterfaceTycon tcref.Deref + +let isEnumTy g ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tcref.IsEnumTycon + +let actualReturnTyOfSlotSig parentTyInst methTyInst (TSlotSig(_, _, parentFormalTypars, methFormalTypars, _, formalRetTy)) = + let methTyInst = mkTyparInst methFormalTypars methTyInst + let parentTyInst = mkTyparInst parentFormalTypars parentTyInst + Option.map (instType (parentTyInst @ methTyInst)) formalRetTy + +let slotSigHasVoidReturnTy (TSlotSig(_, _, _, _, _, formalRetTy)) = + Option.isNone formalRetTy + +let returnTyOfMethod g (TObjExprMethod(TSlotSig(_, parentTy, _, _, _, _) as ss, _, methFormalTypars, _, _, _)) = + let tinst = argsOfAppTy g parentTy + let methTyInst = generalizeTypars methFormalTypars + actualReturnTyOfSlotSig tinst methTyInst ss + +/// Is the type 'abstract' in C#-speak +let isAbstractTycon (tycon: Tycon) = + if tycon.IsFSharpObjectModelTycon then + not tycon.IsFSharpDelegateTycon && + tycon.TypeContents.tcaug_abstract + else + tycon.IsILTycon && tycon.ILTyconRawMetadata.IsAbstract + +//--------------------------------------------------------------------------- +// Determine if a member/Val/ValRef is an explicit impl +//--------------------------------------------------------------------------- + +let MemberIsExplicitImpl g (membInfo: ValMemberInfo) = + membInfo.MemberFlags.IsOverrideOrExplicitImpl && + match membInfo.ImplementedSlotSigs with + | [] -> false + | slotsigs -> slotsigs |> List.forall (fun slotsig -> isInterfaceTy g slotsig.ImplementedType) + +let ValIsExplicitImpl g (v: Val) = + match v.MemberInfo with + | Some membInfo -> MemberIsExplicitImpl g membInfo + | _ -> false + +let ValRefIsExplicitImpl g (vref: ValRef) = ValIsExplicitImpl g vref.Deref + +//--------------------------------------------------------------------------- +// Find all type variables in a type, apart from those that have had +// an equation assigned by type inference. +//--------------------------------------------------------------------------- + +let emptyFreeLocals = Zset.empty valOrder +let unionFreeLocals s1 s2 = + if s1 === emptyFreeLocals then s2 + elif s2 === emptyFreeLocals then s1 + else Zset.union s1 s2 + +let emptyFreeRecdFields = Zset.empty recdFieldRefOrder +let unionFreeRecdFields s1 s2 = + if s1 === emptyFreeRecdFields then s2 + elif s2 === emptyFreeRecdFields then s1 + else Zset.union s1 s2 + +let emptyFreeUnionCases = Zset.empty unionCaseRefOrder +let unionFreeUnionCases s1 s2 = + if s1 === emptyFreeUnionCases then s2 + elif s2 === emptyFreeUnionCases then s1 + else Zset.union s1 s2 + +let emptyFreeTycons = Zset.empty tyconOrder +let unionFreeTycons s1 s2 = + if s1 === emptyFreeTycons then s2 + elif s2 === emptyFreeTycons then s1 + else Zset.union s1 s2 + +let typarOrder = + { new IComparer with + member x.Compare (v1: Typar, v2: Typar) = compare v1.Stamp v2.Stamp } + +let emptyFreeTypars = Zset.empty typarOrder +let unionFreeTypars s1 s2 = + if s1 === emptyFreeTypars then s2 + elif s2 === emptyFreeTypars then s1 + else Zset.union s1 s2 + +let emptyFreeTyvars = + { FreeTycons = emptyFreeTycons + /// The summary of values used as trait solutions + FreeTraitSolutions = emptyFreeLocals + FreeTypars = emptyFreeTypars} + +let isEmptyFreeTyvars ftyvs = + Zset.isEmpty ftyvs.FreeTypars && + Zset.isEmpty ftyvs.FreeTycons + +let unionFreeTyvars fvs1 fvs2 = + if fvs1 === emptyFreeTyvars then fvs2 else + if fvs2 === emptyFreeTyvars then fvs1 else + { FreeTycons = unionFreeTycons fvs1.FreeTycons fvs2.FreeTycons + FreeTraitSolutions = unionFreeLocals fvs1.FreeTraitSolutions fvs2.FreeTraitSolutions + FreeTypars = unionFreeTypars fvs1.FreeTypars fvs2.FreeTypars } + +type FreeVarOptions = + { canCache: bool + collectInTypes: bool + includeLocalTycons: bool + includeTypars: bool + includeLocalTyconReprs: bool + includeRecdFields: bool + includeUnionCases: bool + includeLocals: bool } + +let CollectAllNoCaching = + { canCache = false + collectInTypes = true + includeLocalTycons = true + includeLocalTyconReprs = true + includeRecdFields = true + includeUnionCases = true + includeTypars = true + includeLocals = true } + +let CollectTyparsNoCaching = + { canCache = false + collectInTypes = true + includeLocalTycons = false + includeTypars = true + includeLocalTyconReprs = false + includeRecdFields = false + includeUnionCases = false + includeLocals = false } + +let CollectLocalsNoCaching = + { canCache = false + collectInTypes = false + includeLocalTycons = false + includeTypars = false + includeLocalTyconReprs = false + includeRecdFields = false + includeUnionCases = false + includeLocals = true } + +let CollectTyparsAndLocalsNoCaching = + { canCache = false + collectInTypes = true + includeLocalTycons = false + includeLocalTyconReprs = false + includeRecdFields = false + includeUnionCases = false + includeTypars = true + includeLocals = true } + +let CollectAll = + { canCache = false + collectInTypes = true + includeLocalTycons = true + includeLocalTyconReprs = true + includeRecdFields = true + includeUnionCases = true + includeTypars = true + includeLocals = true } + +let CollectTyparsAndLocals = // CollectAll + { canCache = true // only cache for this one + collectInTypes = true + includeTypars = true + includeLocals = true + includeLocalTycons = false + includeLocalTyconReprs = false + includeRecdFields = false + includeUnionCases = false } + + +let CollectTypars = CollectTyparsAndLocals + +let CollectLocals = CollectTyparsAndLocals + + +let accFreeLocalTycon opts x acc = + if not opts.includeLocalTycons then acc else + if Zset.contains x acc.FreeTycons then acc else + { acc with FreeTycons = Zset.add x acc.FreeTycons } + +let accFreeTycon opts (tcref: TyconRef) acc = + if not opts.includeLocalTycons then acc + elif tcref.IsLocalRef then accFreeLocalTycon opts tcref.ResolvedTarget acc + else acc + +let rec boundTypars opts tps acc = + // Bound type vars form a recursively-referential set due to constraints, e.g. A: I, B: I + // So collect up free vars in all constraints first, then bind all variables + let acc = List.foldBack (fun (tp: Typar) acc -> accFreeInTyparConstraints opts tp.Constraints acc) tps acc + List.foldBack (fun tp acc -> { acc with FreeTypars = Zset.remove tp acc.FreeTypars}) tps acc + +and accFreeInTyparConstraints opts cxs acc = + List.foldBack (accFreeInTyparConstraint opts) cxs acc + +and accFreeInTyparConstraint opts tpc acc = + match tpc with + | TyparConstraint.CoercesTo(ty, _) -> accFreeInType opts ty acc + | TyparConstraint.MayResolveMember (traitInfo, _) -> accFreeInTrait opts traitInfo acc + | TyparConstraint.DefaultsTo(_, rty, _) -> accFreeInType opts rty acc + | TyparConstraint.SimpleChoice(tys, _) -> accFreeInTypes opts tys acc + | TyparConstraint.IsEnum(uty, _) -> accFreeInType opts uty acc + | TyparConstraint.IsDelegate(aty, bty, _) -> accFreeInType opts aty (accFreeInType opts bty acc) + | TyparConstraint.SupportsComparison _ + | TyparConstraint.SupportsEquality _ + | TyparConstraint.SupportsNull _ + | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsReferenceType _ + | TyparConstraint.IsUnmanaged _ + | TyparConstraint.RequiresDefaultConstructor _ -> acc + +and accFreeInTrait opts (TTrait(tys, _, _, argtys, rty, sln)) acc = + Option.foldBack (accFreeInTraitSln opts) sln.Value + (accFreeInTypes opts tys + (accFreeInTypes opts argtys + (Option.foldBack (accFreeInType opts) rty acc))) + +and accFreeInWitnessArg opts (TraitWitnessInfo(tys, _nm, _mf, argtys, rty)) acc = + accFreeInTypes opts tys + (accFreeInTypes opts argtys + (Option.foldBack (accFreeInType opts) rty acc)) + +and accFreeInTraitSln opts sln acc = + match sln with + | ILMethSln(ty, _, _, minst) -> + accFreeInType opts ty + (accFreeInTypes opts minst acc) + | FSMethSln(ty, vref, minst) -> + accFreeInType opts ty + (accFreeValRefInTraitSln opts vref + (accFreeInTypes opts minst acc)) + | FSAnonRecdFieldSln(_anonInfo, tinst, _n) -> + accFreeInTypes opts tinst acc + | FSRecdFieldSln(tinst, _rfref, _isSet) -> + accFreeInTypes opts tinst acc + | BuiltInSln -> acc + | ClosedExprSln _ -> acc // nothing to accumulate because it's a closed expression referring only to erasure of provided method calls + +and accFreeLocalValInTraitSln _opts v fvs = + if Zset.contains v fvs.FreeTraitSolutions then fvs + else { fvs with FreeTraitSolutions = Zset.add v fvs.FreeTraitSolutions} + +and accFreeValRefInTraitSln opts (vref: ValRef) fvs = + if vref.IsLocalRef then + accFreeLocalValInTraitSln opts vref.ResolvedTarget fvs + else + // non-local values do not contain free variables + fvs + +and accFreeTyparRef opts (tp: Typar) acc = + if not opts.includeTypars then acc else + if Zset.contains tp acc.FreeTypars then acc + else + accFreeInTyparConstraints opts tp.Constraints + { acc with FreeTypars = Zset.add tp acc.FreeTypars} + +and accFreeInType opts ty acc = + match stripTyparEqns ty with + | TType_tuple (tupInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts tupInfo acc) + | TType_anon (anonInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts anonInfo.TupInfo acc) + | TType_app (tc, tinst) -> + let acc = accFreeTycon opts tc acc + match tinst with + | [] -> acc // optimization to avoid unneeded call + | [h] -> accFreeInType opts h acc // optimization to avoid unneeded call + | _ -> accFreeInTypes opts tinst acc + | TType_ucase (UnionCaseRef(tc, _), tinst) -> accFreeInTypes opts tinst (accFreeTycon opts tc acc) + | TType_fun (d, r) -> accFreeInType opts d (accFreeInType opts r acc) + | TType_var r -> accFreeTyparRef opts r acc + | TType_forall (tps, r) -> unionFreeTyvars (boundTypars opts tps (freeInType opts r)) acc + | TType_measure unt -> accFreeInMeasure opts unt acc + +and accFreeInTupInfo _opts unt acc = + match unt with + | TupInfo.Const _ -> acc +and accFreeInMeasure opts unt acc = List.foldBack (fun (tp, _) acc -> accFreeTyparRef opts tp acc) (ListMeasureVarOccsWithNonZeroExponents unt) acc +and accFreeInTypes opts tys acc = + match tys with + | [] -> acc + | h :: t -> accFreeInTypes opts t (accFreeInType opts h acc) +and freeInType opts ty = accFreeInType opts ty emptyFreeTyvars + +and accFreeInVal opts (v: Val) acc = accFreeInType opts v.val_type acc + +let freeInTypes opts tys = accFreeInTypes opts tys emptyFreeTyvars +let freeInVal opts v = accFreeInVal opts v emptyFreeTyvars +let freeInTyparConstraints opts v = accFreeInTyparConstraints opts v emptyFreeTyvars +let accFreeInTypars opts tps acc = List.foldBack (accFreeTyparRef opts) tps acc + +let rec addFreeInModuleTy (mtyp: ModuleOrNamespaceType) acc = + QueueList.foldBack (typeOfVal >> accFreeInType CollectAllNoCaching) mtyp.AllValsAndMembers + (QueueList.foldBack (fun (mspec: ModuleOrNamespace) acc -> addFreeInModuleTy mspec.ModuleOrNamespaceType acc) mtyp.AllEntities acc) + +let freeInModuleTy mtyp = addFreeInModuleTy mtyp emptyFreeTyvars + + +//-------------------------------------------------------------------------- +// Free in type, left-to-right order preserved. This is used to determine the +// order of type variables for top-level definitions based on their signature, +// so be careful not to change the order. We accumulate in reverse +// order. +//-------------------------------------------------------------------------- + +let emptyFreeTyparsLeftToRight = [] +let unionFreeTyparsLeftToRight fvs1 fvs2 = ListSet.unionFavourRight typarEq fvs1 fvs2 + +let rec boundTyparsLeftToRight g cxFlag thruFlag acc tps = + // Bound type vars form a recursively-referential set due to constraints, e.g. A: I, B: I + // So collect up free vars in all constraints first, then bind all variables + List.fold (fun acc (tp: Typar) -> accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc tp.Constraints) tps acc + +and accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc cxs = + List.fold (accFreeInTyparConstraintLeftToRight g cxFlag thruFlag) acc cxs + +and accFreeInTyparConstraintLeftToRight g cxFlag thruFlag acc tpc = + match tpc with + | TyparConstraint.CoercesTo(ty, _) -> + accFreeInTypeLeftToRight g cxFlag thruFlag acc ty + | TyparConstraint.MayResolveMember (traitInfo, _) -> + accFreeInTraitLeftToRight g cxFlag thruFlag acc traitInfo + | TyparConstraint.DefaultsTo(_, rty, _) -> + accFreeInTypeLeftToRight g cxFlag thruFlag acc rty + | TyparConstraint.SimpleChoice(tys, _) -> + accFreeInTypesLeftToRight g cxFlag thruFlag acc tys + | TyparConstraint.IsEnum(uty, _) -> + accFreeInTypeLeftToRight g cxFlag thruFlag acc uty + | TyparConstraint.IsDelegate(aty, bty, _) -> + accFreeInTypeLeftToRight g cxFlag thruFlag (accFreeInTypeLeftToRight g cxFlag thruFlag acc aty) bty + | TyparConstraint.SupportsComparison _ + | TyparConstraint.SupportsEquality _ + | TyparConstraint.SupportsNull _ + | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsUnmanaged _ + | TyparConstraint.IsReferenceType _ + | TyparConstraint.RequiresDefaultConstructor _ -> acc + +and accFreeInTraitLeftToRight g cxFlag thruFlag acc (TTrait(tys, _, _, argtys, rty, _)) = + let acc = accFreeInTypesLeftToRight g cxFlag thruFlag acc tys + let acc = accFreeInTypesLeftToRight g cxFlag thruFlag acc argtys + let acc = Option.fold (accFreeInTypeLeftToRight g cxFlag thruFlag) acc rty + acc + +and accFreeTyparRefLeftToRight g cxFlag thruFlag acc (tp: Typar) = + if ListSet.contains typarEq tp acc then + acc + else + let acc = ListSet.insert typarEq tp acc + if cxFlag then + accFreeInTyparConstraintsLeftToRight g cxFlag thruFlag acc tp.Constraints + else + acc + +and accFreeInTypeLeftToRight g cxFlag thruFlag acc ty = + match (if thruFlag then stripTyEqns g ty else stripTyparEqns ty) with + | TType_anon (anonInfo, anonTys) -> + let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc anonInfo.TupInfo + accFreeInTypesLeftToRight g cxFlag thruFlag acc anonTys + | TType_tuple (tupInfo, tupTys) -> + let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc tupInfo + accFreeInTypesLeftToRight g cxFlag thruFlag acc tupTys + | TType_app (_, tinst) -> + accFreeInTypesLeftToRight g cxFlag thruFlag acc tinst + | TType_ucase (_, tinst) -> + accFreeInTypesLeftToRight g cxFlag thruFlag acc tinst + | TType_fun (d, r) -> + let dacc = accFreeInTypeLeftToRight g cxFlag thruFlag acc d + accFreeInTypeLeftToRight g cxFlag thruFlag dacc r + | TType_var r -> + accFreeTyparRefLeftToRight g cxFlag thruFlag acc r + | TType_forall (tps, r) -> + let racc = accFreeInTypeLeftToRight g cxFlag thruFlag emptyFreeTyparsLeftToRight r + unionFreeTyparsLeftToRight (boundTyparsLeftToRight g cxFlag thruFlag tps racc) acc + | TType_measure unt -> + let mvars = ListMeasureVarOccsWithNonZeroExponents unt + List.foldBack (fun (tp, _) acc -> accFreeTyparRefLeftToRight g cxFlag thruFlag acc tp) mvars acc + +and accFreeInTupInfoLeftToRight _g _cxFlag _thruFlag acc unt = + match unt with + | TupInfo.Const _ -> acc + +and accFreeInTypesLeftToRight g cxFlag thruFlag acc tys = + match tys with + | [] -> acc + | h :: t -> accFreeInTypesLeftToRight g cxFlag thruFlag (accFreeInTypeLeftToRight g cxFlag thruFlag acc h) t + +let freeInTypeLeftToRight g thruFlag ty = + accFreeInTypeLeftToRight g true thruFlag emptyFreeTyparsLeftToRight ty |> List.rev + +let freeInTypesLeftToRight g thruFlag ty = + accFreeInTypesLeftToRight g true thruFlag emptyFreeTyparsLeftToRight ty |> List.rev + +let freeInTypesLeftToRightSkippingConstraints g ty = + accFreeInTypesLeftToRight g false true emptyFreeTyparsLeftToRight ty |> List.rev + +let valOfBind (b: Binding) = b.Var + +let valsOfBinds (binds: Bindings) = binds |> List.map (fun b -> b.Var) + +//-------------------------------------------------------------------------- +// Values representing member functions on F# types +//-------------------------------------------------------------------------- + +// Pull apart the type for an F# value that represents an object model method. Do not strip off a 'unit' argument. +// Review: Should GetMemberTypeInFSharpForm have any other direct callers? +let GetMemberTypeInFSharpForm g (memberFlags: SynMemberFlags) arities ty m = + let tps, argInfos, rty, retInfo = GetTopValTypeInFSharpForm g arities ty m + + let argInfos = + if memberFlags.IsInstance then + match argInfos with + | [] -> + errorR(InternalError("value does not have a valid member type", m)) + argInfos + | _ :: t -> t + else argInfos + tps, argInfos, rty, retInfo + +// Check that an F# value represents an object model method. +// It will also always have an arity (inferred from syntax). +let checkMemberVal membInfo arity m = + match membInfo, arity with + | None, _ -> error(InternalError("checkMemberVal - no membInfo", m)) + | _, None -> error(InternalError("checkMemberVal - no arity", m)) + | Some membInfo, Some arity -> (membInfo, arity) + +let checkMemberValRef (vref: ValRef) = + checkMemberVal vref.MemberInfo vref.ValReprInfo vref.Range + +/// Get information about the trait constraints for a set of typars. +/// Put these in canonical order. +let GetTraitConstraintInfosOfTypars g (tps: Typars) = + [ for tp in tps do + for cx in tp.Constraints do + match cx with + | TyparConstraint.MayResolveMember(traitInfo, _) -> yield traitInfo + | _ -> () ] + |> ListSet.setify (traitsAEquiv g TypeEquivEnv.Empty) + |> List.sortBy (fun traitInfo -> traitInfo.MemberName, traitInfo.ArgumentTypes.Length) + +/// Get information about the runtime witnesses needed for a set of generalized typars +let GetTraitWitnessInfosOfTypars g numParentTypars typars = + let typs = typars |> List.skip numParentTypars + let cxs = GetTraitConstraintInfosOfTypars g typs + cxs |> List.map (fun cx -> cx.TraitKey) + +/// Count the number of type parameters on the enclosing type +let CountEnclosingTyparsOfActualParentOfVal (v: Val) = + match v.ValReprInfo with + | None -> 0 + | Some _ -> + if v.IsExtensionMember then 0 + elif not v.IsMember then 0 + else v.MemberApparentEntity.TyparsNoRange.Length + +let GetTopValTypeInCompiledForm g topValInfo numEnclosingTypars ty m = + let tps, paramArgInfos, rty, retInfo = GetTopValTypeInFSharpForm g topValInfo ty m + let witnessInfos = GetTraitWitnessInfosOfTypars g numEnclosingTypars tps + // Eliminate lone single unit arguments + let paramArgInfos = + match paramArgInfos, topValInfo.ArgInfos with + // static member and module value unit argument elimination + | [[(_argType, _)]], [[]] -> + //assert isUnitTy g argType + [[]] + // instance member unit argument elimination + | [objInfo;[(_argType, _)]], [[_objArg];[]] -> + //assert isUnitTy g argType + [objInfo; []] + | _ -> + paramArgInfos + let rty = if isUnitTy g rty then None else Some rty + (tps, witnessInfos, paramArgInfos, rty, retInfo) + +// Pull apart the type for an F# value that represents an object model method +// and see the "member" form for the type, i.e. +// detect methods with no arguments by (effectively) looking for single argument type of 'unit'. +// The analysis is driven of the inferred arity information for the value. +// +// This is used not only for the compiled form - it's also used for all type checking and object model +// logic such as determining if abstract methods have been implemented or not, and how +// many arguments the method takes etc. +let GetMemberTypeInMemberForm g memberFlags topValInfo numEnclosingTypars ty m = + let tps, paramArgInfos, rty, retInfo = GetMemberTypeInFSharpForm g memberFlags topValInfo ty m + let witnessInfos = GetTraitWitnessInfosOfTypars g numEnclosingTypars tps + // Eliminate lone single unit arguments + let paramArgInfos = + match paramArgInfos, topValInfo.ArgInfos with + // static member and module value unit argument elimination + | [[(argType, _)]], [[]] -> + assert isUnitTy g argType + [[]] + // instance member unit argument elimination + | [[(argType, _)]], [[_objArg];[]] -> + assert isUnitTy g argType + [[]] + | _ -> + paramArgInfos + let rty = if isUnitTy g rty then None else Some rty + (tps, witnessInfos, paramArgInfos, rty, retInfo) + +let GetTypeOfMemberInMemberForm g (vref: ValRef) = + //assert (not vref.IsExtensionMember) + let membInfo, topValInfo = checkMemberValRef vref + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo numEnclosingTypars vref.Type vref.Range + +let GetTypeOfMemberInFSharpForm g (vref: ValRef) = + let membInfo, topValInfo = checkMemberValRef vref + GetMemberTypeInFSharpForm g membInfo.MemberFlags topValInfo vref.Type vref.Range + +let PartitionValTyparsForApparentEnclosingType g (v: Val) = + match v.ValReprInfo with + | None -> error(InternalError("PartitionValTypars: not a top value", v.Range)) + | Some arities -> + let fullTypars, _ = destTopForallTy g arities v.Type + let parent = v.MemberApparentEntity + let parentTypars = parent.TyparsNoRange + let nparentTypars = parentTypars.Length + if nparentTypars <= fullTypars.Length then + let memberParentTypars, memberMethodTypars = List.splitAt nparentTypars fullTypars + let memberToParentInst, tinst = mkTyparToTyparRenaming memberParentTypars parentTypars + Some(parentTypars, memberParentTypars, memberMethodTypars, memberToParentInst, tinst) + else None + +/// Match up the type variables on an member value with the type +/// variables on the apparent enclosing type +let PartitionValTypars g (v: Val) = + match v.ValReprInfo with + | None -> error(InternalError("PartitionValTypars: not a top value", v.Range)) + | Some arities -> + if v.IsExtensionMember then + let fullTypars, _ = destTopForallTy g arities v.Type + Some([], [], fullTypars, emptyTyparInst, []) + else + PartitionValTyparsForApparentEnclosingType g v + +let PartitionValRefTypars g (vref: ValRef) = PartitionValTypars g vref.Deref + +/// Get the arguments for an F# value that represents an object model method +let ArgInfosOfMemberVal g (v: Val) = + let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let _, _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo numEnclosingTypars v.Type v.Range + arginfos + +let ArgInfosOfMember g (vref: ValRef) = + ArgInfosOfMemberVal g vref.Deref + +let GetFSharpViewOfReturnType (g: TcGlobals) retTy = + match retTy with + | None -> g.unit_ty + | Some retTy -> retTy + + +/// Get the property "type" (getter return type) for an F# value that represents a getter or setter +/// of an object model property. +let ReturnTypeOfPropertyVal g (v: Val) = + let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range + match membInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertySet -> + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let _, _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo numEnclosingTypars v.Type v.Range + if not arginfos.IsEmpty && not arginfos.Head.IsEmpty then + arginfos.Head |> List.last |> fst + else + error(Error(FSComp.SR.tastValueDoesNotHaveSetterType(), v.Range)) + | SynMemberKind.PropertyGet -> + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let _, _, _, rty, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo numEnclosingTypars v.Type v.Range + GetFSharpViewOfReturnType g rty + | _ -> error(InternalError("ReturnTypeOfPropertyVal", v.Range)) + + +/// Get the property arguments for an F# value that represents a getter or setter +/// of an object model property. +let ArgInfosOfPropertyVal g (v: Val) = + let membInfo, topValInfo = checkMemberVal v.MemberInfo v.ValReprInfo v.Range + match membInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertyGet -> + ArgInfosOfMemberVal g v |> List.concat + | SynMemberKind.PropertySet -> + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let _, _, arginfos, _, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags topValInfo numEnclosingTypars v.Type v.Range + if not arginfos.IsEmpty && not arginfos.Head.IsEmpty then + arginfos.Head |> List.frontAndBack |> fst + else + error(Error(FSComp.SR.tastValueDoesNotHaveSetterType(), v.Range)) + | _ -> + error(InternalError("ArgInfosOfPropertyVal", v.Range)) + +//--------------------------------------------------------------------------- +// Generalize type constructors to types +//--------------------------------------------------------------------------- + +let generalTyconRefInst (tc: TyconRef) = generalizeTypars tc.TyparsNoRange + +let generalizeTyconRef tc = + let tinst = generalTyconRefInst tc + tinst, TType_app(tc, tinst) + +let generalizedTyconRef tc = TType_app(tc, generalTyconRefInst tc) + +let isTTyparSupportsStaticMethod = function TyparConstraint.MayResolveMember _ -> true | _ -> false +let isTTyparCoercesToType = function TyparConstraint.CoercesTo _ -> true | _ -> false + +//-------------------------------------------------------------------------- +// Print Signatures/Types - prelude +//-------------------------------------------------------------------------- + +let prefixOfStaticReq s = + match s with + | TyparStaticReq.None -> "'" + | TyparStaticReq.HeadType -> " ^" + +let prefixOfRigidTypar (typar: Typar) = + if (typar.Rigidity <> TyparRigidity.Rigid) then "_" else "" + +//--------------------------------------------------------------------------- +// Prettify: PrettyTyparNames/PrettifyTypes - make typar names human friendly +//--------------------------------------------------------------------------- + +type TyparConstraintsWithTypars = (Typar * TyparConstraint) list + +module PrettyTypes = + let newPrettyTypar (tp: Typar) nm = + Construct.NewTypar (tp.Kind, tp.Rigidity, SynTypar(ident(nm, tp.Range), tp.StaticReq, false), false, TyparDynamicReq.Yes, [], false, false) + + let NewPrettyTypars renaming tps names = + let niceTypars = List.map2 newPrettyTypar tps names + let tl, _tt = mkTyparToTyparRenaming tps niceTypars in + let renaming = renaming @ tl + (tps, niceTypars) ||> List.iter2 (fun tp tpnice -> tpnice.SetConstraints (instTyparConstraints renaming tp.Constraints)) + niceTypars, renaming + + // We choose names for type parameters from 'a'..'t' + // We choose names for unit-of-measure from 'u'..'z' + // If we run off the end of these ranges, we use 'aX' for positive integer X or 'uX' for positive integer X + // Finally, we skip any names already in use + let NeedsPrettyTyparName (tp: Typar) = + tp.IsCompilerGenerated && + tp.ILName.IsNone && + (tp.typar_id.idText = unassignedTyparName) + + let PrettyTyparNames pred alreadyInUse tps = + let rec choose (tps: Typar list) (typeIndex, measureIndex) acc = + match tps with + | [] -> List.rev acc + | tp :: tps -> + + + // Use a particular name, possibly after incrementing indexes + let useThisName (nm, typeIndex, measureIndex) = + choose tps (typeIndex, measureIndex) (nm :: acc) + + // Give up, try again with incremented indexes + let tryAgain (typeIndex, measureIndex) = + choose (tp :: tps) (typeIndex, measureIndex) acc + + let tryName (nm, typeIndex, measureIndex) f = + if List.contains nm alreadyInUse then + f() + else + useThisName (nm, typeIndex, measureIndex) + + if pred tp then + if NeedsPrettyTyparName tp then + let typeIndex, measureIndex, baseName, letters, i = + match tp.Kind with + | TyparKind.Type -> (typeIndex+1, measureIndex, 'a', 20, typeIndex) + | TyparKind.Measure -> (typeIndex, measureIndex+1, 'u', 6, measureIndex) + let nm = + if i < letters then String.make 1 (char(int baseName + i)) + else String.make 1 baseName + string (i-letters+1) + tryName (nm, typeIndex, measureIndex) (fun () -> + tryAgain (typeIndex, measureIndex)) + + else + tryName (tp.Name, typeIndex, measureIndex) (fun () -> + // Use the next index and append it to the natural name + let typeIndex, measureIndex, nm = + match tp.Kind with + | TyparKind.Type -> (typeIndex+1, measureIndex, tp.Name+ string typeIndex) + | TyparKind.Measure -> (typeIndex, measureIndex+1, tp.Name+ string measureIndex) + tryName (nm, typeIndex, measureIndex) (fun () -> + tryAgain (typeIndex, measureIndex))) + else + useThisName (tp.Name, typeIndex, measureIndex) + + choose tps (0, 0) [] + + let PrettifyThings g foldTys mapTys things = + let ftps = foldTys (accFreeInTypeLeftToRight g true false) emptyFreeTyparsLeftToRight things + let ftps = List.rev ftps + let rec computeKeep (keep: Typars) change (tps: Typars) = + match tps with + | [] -> List.rev keep, List.rev change + | tp :: rest -> + if not (NeedsPrettyTyparName tp) && (not (keep |> List.exists (fun tp2 -> tp.Name = tp2.Name))) then + computeKeep (tp :: keep) change rest + else + computeKeep keep (tp :: change) rest + let keep, change = computeKeep [] [] ftps + + let alreadyInUse = keep |> List.map (fun x -> x.Name) + let names = PrettyTyparNames (fun x -> List.memq x change) alreadyInUse ftps + + let niceTypars, renaming = NewPrettyTypars [] ftps names + + // strip universal types for printing + let getTauStayTau t = + match t with + | TType_forall (_, tau) -> tau + | _ -> t + let tauThings = mapTys getTauStayTau things + + let prettyThings = mapTys (instType renaming) tauThings + let tpconstraints = niceTypars |> List.collect (fun tpnice -> List.map (fun tpc -> tpnice, tpc) tpnice.Constraints) + + prettyThings, tpconstraints + + let PrettifyType g x = PrettifyThings g id id x + let PrettifyTypePair g x = PrettifyThings g (fun f -> foldPair (f, f)) (fun f -> mapPair (f, f)) x + let PrettifyTypes g x = PrettifyThings g List.fold List.map x + + let PrettifyDiscriminantAndTypePairs g x = + let tys, cxs = (PrettifyThings g List.fold List.map (x |> List.map snd)) + List.zip (List.map fst x) tys, cxs + + let PrettifyCurriedTypes g x = PrettifyThings g (fun f -> List.fold (List.fold f)) List.mapSquared x + let PrettifyCurriedSigTypes g x = PrettifyThings g (fun f -> foldPair (List.fold (List.fold f), f)) (fun f -> mapPair (List.mapSquared f, f)) x + + // Badly formed code may instantiate rigid declared typars to types. + // Hence we double check here that the thing is really a type variable + let safeDestAnyParTy orig g ty = match tryAnyParTy g ty with ValueNone -> orig | ValueSome x -> x + let tee f x = f x x + + let foldUnurriedArgInfos f z (x: UncurriedArgInfos) = List.fold (fold1Of2 f) z x + let mapUnurriedArgInfos f (x: UncurriedArgInfos) = List.map (map1Of2 f) x + + let foldTypar f z (x: Typar) = foldOn mkTyparTy f z x + let mapTypar g f (x: Typar) : Typar = (mkTyparTy >> f >> safeDestAnyParTy x g) x + + let foldTypars f z (x: Typars) = List.fold (foldTypar f) z x + let mapTypars g f (x: Typars) : Typars = List.map (mapTypar g f) x + + let foldTyparInst f z (x: TyparInst) = List.fold (foldPair (foldTypar f, f)) z x + let mapTyparInst g f (x: TyparInst) : TyparInst = List.map (mapPair (mapTypar g f, f)) x + + let PrettifyInstAndTyparsAndType g x = + PrettifyThings g + (fun f -> foldTriple (foldTyparInst f, foldTypars f, f)) + (fun f-> mapTriple (mapTyparInst g f, mapTypars g f, f)) + x + + let PrettifyInstAndUncurriedSig g (x: TyparInst * UncurriedArgInfos * TType) = + PrettifyThings g + (fun f -> foldTriple (foldTyparInst f, foldUnurriedArgInfos f, f)) + (fun f -> mapTriple (mapTyparInst g f, List.map (map1Of2 f), f)) + x + + let PrettifyInstAndCurriedSig g (x: TyparInst * TTypes * CurriedArgInfos * TType) = + PrettifyThings g + (fun f -> foldQuadruple (foldTyparInst f, List.fold f, List.fold (List.fold (fold1Of2 f)), f)) + (fun f -> mapQuadruple (mapTyparInst g f, List.map f, List.mapSquared (map1Of2 f), f)) + x + + let PrettifyInstAndSig g x = + PrettifyThings g + (fun f -> foldTriple (foldTyparInst f, List.fold f, f)) + (fun f -> mapTriple (mapTyparInst g f, List.map f, f) ) + x + + let PrettifyInstAndTypes g x = + PrettifyThings g + (fun f -> foldPair (foldTyparInst f, List.fold f)) + (fun f -> mapPair (mapTyparInst g f, List.map f)) + x + + let PrettifyInstAndType g x = + PrettifyThings g + (fun f -> foldPair (foldTyparInst f, f)) + (fun f -> mapPair (mapTyparInst g f, f)) + x + + let PrettifyInst g x = + PrettifyThings g + (fun f -> foldTyparInst f) + (fun f -> mapTyparInst g f) + x + +module SimplifyTypes = + + // CAREFUL! This function does NOT walk constraints + let rec foldTypeButNotConstraints f z ty = + let ty = stripTyparEqns ty + let z = f z ty + match ty with + | TType_forall (_, body) -> foldTypeButNotConstraints f z body + | TType_app (_, tys) + | TType_ucase (_, tys) + | TType_anon (_, tys) + | TType_tuple (_, tys) -> List.fold (foldTypeButNotConstraints f) z tys + | TType_fun (s, t) -> foldTypeButNotConstraints f (foldTypeButNotConstraints f z s) t + | TType_var _ -> z + | TType_measure _ -> z + + let incM x m = + if Zmap.mem x m then Zmap.add x (1 + Zmap.find x m) m + else Zmap.add x 1 m + + let accTyparCounts z ty = + // Walk type to determine typars and their counts (for pprinting decisions) + foldTypeButNotConstraints (fun z ty -> match ty with | TType_var tp when tp.Rigidity = TyparRigidity.Rigid -> incM tp z | _ -> z) z ty + + let emptyTyparCounts = Zmap.empty typarOrder + + // print multiple fragments of the same type using consistent naming and formatting + let accTyparCountsMulti acc l = List.fold accTyparCounts acc l + + type TypeSimplificationInfo = + { singletons: Typar Zset + inplaceConstraints: Zmap + postfixConstraints: (Typar * TyparConstraint) list } + + let typeSimplificationInfo0 = + { singletons = Zset.empty typarOrder + inplaceConstraints = Zmap.empty typarOrder + postfixConstraints = [] } + + let categorizeConstraints simplify m cxs = + let singletons = if simplify then Zmap.chooseL (fun tp n -> if n = 1 then Some tp else None) m else [] + let singletons = Zset.addList singletons (Zset.empty typarOrder) + // Here, singletons are typars that occur once in the type. + // However, they may also occur in a type constraint. + // If they do, they are really multiple occurrence - so we should remove them. + let constraintTypars = (freeInTyparConstraints CollectTyparsNoCaching (List.map snd cxs)).FreeTypars + let usedInTypeConstraint typar = Zset.contains typar constraintTypars + let singletons = singletons |> Zset.filter (usedInTypeConstraint >> not) + // Here, singletons should really be used once + let inplace, postfix = + cxs |> List.partition (fun (tp, tpc) -> + simplify && + isTTyparCoercesToType tpc && + Zset.contains tp singletons && + tp.Constraints.Length = 1) + let inplace = inplace |> List.map (function tp, TyparConstraint.CoercesTo(ty, _) -> tp, ty | _ -> failwith "not isTTyparCoercesToType") + + { singletons = singletons + inplaceConstraints = Zmap.ofList typarOrder inplace + postfixConstraints = postfix } + let CollectInfo simplify tys cxs = + categorizeConstraints simplify (accTyparCountsMulti emptyTyparCounts tys) cxs + +//-------------------------------------------------------------------------- +// Print Signatures/Types +//-------------------------------------------------------------------------- + +type GenericParameterStyle = + | Implicit + | Prefix + | Suffix + +[] +type DisplayEnv = + { includeStaticParametersInTypeNames: bool + openTopPathsSorted: Lazy + openTopPathsRaw: string list list + shortTypeNames: bool + suppressNestedTypes: bool + maxMembers: int option + showObsoleteMembers: bool + showHiddenMembers: bool + showTyparBinding: bool + showImperativeTyparAnnotations: bool + suppressInlineKeyword: bool + suppressMutableKeyword: bool + showMemberContainers: bool + shortConstraints: bool + useColonForReturnType: bool + showAttributes: bool + showOverrides: bool + showConstraintTyparAnnotations: bool + abbreviateAdditionalConstraints: bool + showTyparDefaultConstraints: bool + showDocumentation: bool + shrinkOverloads: bool + printVerboseSignatures: bool + escapeKeywordNames: bool + g: TcGlobals + contextAccessibility: Accessibility + generatedValueLayout : Val -> Layout option + genericParameterStyle: GenericParameterStyle } + + member x.SetOpenPaths paths = + { x with + openTopPathsSorted = (lazy (paths |> List.sortWith (fun p1 p2 -> -(compare p1 p2)))) + openTopPathsRaw = paths + } + + static member Empty tcGlobals = + { includeStaticParametersInTypeNames = false + openTopPathsRaw = [] + openTopPathsSorted = notlazy [] + shortTypeNames = false + suppressNestedTypes = false + maxMembers = None + showObsoleteMembers = false + showHiddenMembers = false + showTyparBinding = false + showImperativeTyparAnnotations = false + suppressInlineKeyword = true + suppressMutableKeyword = false + showMemberContainers = false + showAttributes = false + showOverrides = true + showConstraintTyparAnnotations = true + showDocumentation = false + abbreviateAdditionalConstraints = false + showTyparDefaultConstraints = false + shortConstraints = false + useColonForReturnType = false + shrinkOverloads = true + printVerboseSignatures = false + escapeKeywordNames = false + g = tcGlobals + contextAccessibility = taccessPublic + generatedValueLayout = (fun _ -> None) + genericParameterStyle = GenericParameterStyle.Implicit } + + + member denv.AddOpenPath path = + denv.SetOpenPaths (path :: denv.openTopPathsRaw) + + member denv.AddOpenModuleOrNamespace (modref: ModuleOrNamespaceRef) = + denv.AddOpenPath (fullCompPathOfModuleOrNamespace modref.Deref).DemangledPath + + member denv.AddAccessibility access = + { denv with contextAccessibility = combineAccess denv.contextAccessibility access } + + member denv.UseGenericParameterStyle style = + { denv with genericParameterStyle = style } + + static member InitialForSigFileGeneration g = + let denv = + { DisplayEnv.Empty g with + showImperativeTyparAnnotations = true + showHiddenMembers = true + showObsoleteMembers = true + showAttributes = true + suppressInlineKeyword = false + showDocumentation = true + shrinkOverloads = false + escapeKeywordNames = true } + denv.SetOpenPaths + [ FSharpLib.RootPath + FSharpLib.CorePath + CollectionsPath + ControlPath + (splitNamespace ExtraTopLevelOperatorsName) ] + +let (+.+) s1 s2 = if s1 = "" then s2 else s1+"."+s2 + +let layoutOfPath p = + sepListL SepL.dot (List.map (tagNamespace >> wordL) p) + +let fullNameOfParentOfPubPath pp = + match pp with + | PubPath([| _ |]) -> ValueNone + | pp -> ValueSome(textOfPath pp.EnclosingPath) + +let fullNameOfParentOfPubPathAsLayout pp = + match pp with + | PubPath([| _ |]) -> ValueNone + | pp -> ValueSome(layoutOfPath (Array.toList pp.EnclosingPath)) + +let fullNameOfPubPath (PubPath p) = textOfPath p +let fullNameOfPubPathAsLayout (PubPath p) = layoutOfPath (Array.toList p) + +let fullNameOfParentOfNonLocalEntityRef (nlr: NonLocalEntityRef) = + if nlr.Path.Length < 2 then ValueNone + else ValueSome (textOfPath nlr.EnclosingMangledPath) + +let fullNameOfParentOfNonLocalEntityRefAsLayout (nlr: NonLocalEntityRef) = + if nlr.Path.Length < 2 then ValueNone + else ValueSome (layoutOfPath (List.ofArray nlr.EnclosingMangledPath)) + +let fullNameOfParentOfEntityRef eref = + match eref with + | ERefLocal x -> + match x.PublicPath with + | None -> ValueNone + | Some ppath -> fullNameOfParentOfPubPath ppath + | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRef nlr + +let fullNameOfParentOfEntityRefAsLayout eref = + match eref with + | ERefLocal x -> + match x.PublicPath with + | None -> ValueNone + | Some ppath -> fullNameOfParentOfPubPathAsLayout ppath + | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRefAsLayout nlr + +let fullNameOfEntityRef nmF xref = + match fullNameOfParentOfEntityRef xref with + | ValueNone -> nmF xref + | ValueSome pathText -> pathText +.+ nmF xref + +let tagEntityRefName (xref: EntityRef) name = + if xref.IsNamespace then tagNamespace name + elif xref.IsModule then tagModule name + elif xref.IsTypeAbbrev then tagAlias name + elif xref.IsFSharpDelegateTycon then tagDelegate name + elif xref.IsILEnumTycon || xref.IsFSharpEnumTycon then tagEnum name + elif xref.IsStructOrEnumTycon then tagStruct name + elif isInterfaceTyconRef xref then tagInterface name + elif xref.IsUnionTycon then tagUnion name + elif xref.IsRecordTycon then tagRecord name + else tagClass name + +let fullDisplayTextOfTyconRef (tc: TyconRef) = + fullNameOfEntityRef (fun tc -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) tc + +let fullNameOfEntityRefAsLayout nmF (xref: EntityRef) = + let navigableText = + tagEntityRefName xref (nmF xref) + |> mkNav xref.DefinitionRange + |> wordL + match fullNameOfParentOfEntityRefAsLayout xref with + | ValueNone -> navigableText + | ValueSome pathText -> pathText ^^ SepL.dot ^^ navigableText + +let fullNameOfParentOfValRef vref = + match vref with + | VRefLocal x -> + match x.PublicPath with + | None -> ValueNone + | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPath pp) + | VRefNonLocal nlr -> + ValueSome (fullNameOfEntityRef (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) + +let fullNameOfParentOfValRefAsLayout vref = + match vref with + | VRefLocal x -> + match x.PublicPath with + | None -> ValueNone + | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPathAsLayout pp) + | VRefNonLocal nlr -> + ValueSome (fullNameOfEntityRefAsLayout (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) + + +let fullDisplayTextOfParentOfModRef r = fullNameOfParentOfEntityRef r + +let fullDisplayTextOfModRef r = fullNameOfEntityRef (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) r +let fullDisplayTextOfTyconRefAsLayout r = fullNameOfEntityRefAsLayout (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r +let fullDisplayTextOfExnRef r = fullNameOfEntityRef (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r +let fullDisplayTextOfExnRefAsLayout r = fullNameOfEntityRefAsLayout (fun (tc: TyconRef) -> tc.DisplayNameWithStaticParametersAndUnderscoreTypars) r + +let fullDisplayTextOfUnionCaseRef (ucref: UnionCaseRef) = fullDisplayTextOfTyconRef ucref.TyconRef +.+ ucref.CaseName +let fullDisplayTextOfRecdFieldRef (rfref: RecdFieldRef) = fullDisplayTextOfTyconRef rfref.TyconRef +.+ rfref.FieldName + +let fullDisplayTextOfValRef (vref: ValRef) = + match fullNameOfParentOfValRef vref with + | ValueNone -> vref.DisplayName + | ValueSome pathText -> pathText +.+ vref.DisplayName + +let fullDisplayTextOfValRefAsLayout (vref: ValRef) = + let n = + match vref.MemberInfo with + | None -> + if vref.IsModuleBinding then tagModuleBinding vref.DisplayName + else tagUnknownEntity vref.DisplayName + | Some memberInfo -> + match memberInfo.MemberFlags.MemberKind with + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGetSet -> tagProperty vref.DisplayName + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor -> tagMethod vref.DisplayName + | SynMemberKind.Member -> tagMember vref.DisplayName + match fullNameOfParentOfValRefAsLayout vref with + | ValueNone -> wordL n + | ValueSome pathText -> + pathText ^^ SepL.dot ^^ wordL n + //pathText +.+ vref.DisplayName + +let fullMangledPathToTyconRef (tcref:TyconRef) = + match tcref with + | ERefLocal _ -> (match tcref.PublicPath with None -> [| |] | Some pp -> pp.EnclosingPath) + | ERefNonLocal nlr -> nlr.EnclosingMangledPath + +/// generates a name like 'System.IComparable.Get' +let tyconRefToFullName (tc:TyconRef) = + let namespaceParts = + // we need to ensure there are no collisions between (for example) + // - ``IB`` (non-generic) + // - IB<'T> instantiated with 'T = GlobalType + // This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. + // So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. + match fullMangledPathToTyconRef tc with + | [||] -> [| "global`" |] + | ns -> ns + seq { yield! namespaceParts; yield tc.DisplayName } |> String.concat "." + +let rec qualifiedInterfaceImplementationNameAux g (x:TType) : string = + match stripMeasuresFromTType g (stripTyEqnsAndErase true g x) with + | TType_app (a,[]) -> tyconRefToFullName a + | TType_anon (a,b) -> + let genericParameters = b |> Seq.map (qualifiedInterfaceImplementationNameAux g) |> String.concat ", " + sprintf "%s<%s>" a.ILTypeRef.FullName genericParameters + | TType_app (a,b) -> + let genericParameters = b |> Seq.map (qualifiedInterfaceImplementationNameAux g) |> String.concat ", " + sprintf "%s<%s>" (tyconRefToFullName a) genericParameters + | TType_var v -> "'" + v.Name + | _ -> failwithf "unexpected: expected TType_app but got %O" (x.GetType()) + +/// for types in the global namespace, `global is prepended (note the backtick) +let qualifiedInterfaceImplementationName g (tt:TType) memberName = + let interfaceName = tt |> qualifiedInterfaceImplementationNameAux g + sprintf "%s.%s" interfaceName memberName + +let qualifiedMangledNameOfTyconRef tcref nm = + String.concat "-" (Array.toList (fullMangledPathToTyconRef tcref) @ [ tcref.LogicalName + "-" + nm ]) + +let rec firstEq p1 p2 = + match p1 with + | [] -> true + | h1 :: t1 -> + match p2 with + | h2 :: t2 -> h1 = h2 && firstEq t1 t2 + | _ -> false + +let rec firstRem p1 p2 = + match p1 with [] -> p2 | _ :: t1 -> firstRem t1 (List.tail p2) + +let trimPathByDisplayEnv denv path = + let findOpenedNamespace openedPath = + if firstEq openedPath path then + let t2 = firstRem openedPath path + if t2 <> [] then Some(textOfPath t2 + ".") + else Some("") + else None + + match List.tryPick findOpenedNamespace (denv.openTopPathsSorted.Force()) with + | Some s -> s + | None -> if isNil path then "" else textOfPath path + "." + + +let superOfTycon (g: TcGlobals) (tycon: Tycon) = + match tycon.TypeContents.tcaug_super with + | None -> g.obj_ty + | Some ty -> ty + +/// walk a TyconRef's inheritance tree, yielding any parent types as an array +let supersOfTyconRef (tcref: TyconRef) = + Array.unfold (fun (tcref: TyconRef) -> match tcref.TypeContents.tcaug_super with Some (TType_app(sup, _)) -> Some(sup, sup) | _ -> None) tcref + + +//---------------------------------------------------------------------------- +// Detect attributes +//---------------------------------------------------------------------------- + +// AbsIL view of attributes (we read these from .NET binaries) +let isILAttribByName (tencl: string list, tname: string) (attr: ILAttribute) = + (attr.Method.DeclaringType.TypeSpec.Name = tname) && + (attr.Method.DeclaringType.TypeSpec.Enclosing = tencl) + +// AbsIL view of attributes (we read these from .NET binaries). The comparison is done by name. +let isILAttrib (tref: ILTypeRef) (attr: ILAttribute) = + isILAttribByName (tref.Enclosing, tref.Name) attr + +// REVIEW: consider supporting querying on Abstract IL custom attributes. +// These linear iterations cost us a fair bit when there are lots of attributes +// on imported types. However this is fairly rare and can also be solved by caching the +// results of attribute lookups in the TAST +let HasILAttribute tref (attrs: ILAttributes) = + attrs.AsArray |> Array.exists (isILAttrib tref) + +let TryDecodeILAttribute tref (attrs: ILAttributes) = + attrs.AsArray |> Array.tryPick (fun x -> if isILAttrib tref x then Some(decodeILAttribData x) else None) + +// F# view of attributes (these get converted to AbsIL attributes in ilxgen) +let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2 +let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs +let findAttrib g tref attrs = List.find (IsMatchingFSharpAttribute g tref) attrs +let TryFindFSharpAttribute g tref attrs = List.tryFind (IsMatchingFSharpAttribute g tref) attrs +let TryFindFSharpAttributeOpt g tref attrs = match tref with None -> None | Some tref -> List.tryFind (IsMatchingFSharpAttribute g tref) attrs + +let HasFSharpAttributeOpt g trefOpt attrs = match trefOpt with Some tref -> List.exists (IsMatchingFSharpAttribute g tref) attrs | _ -> false +let IsMatchingFSharpAttributeOpt g attrOpt (Attrib(tcref2, _, _, _, _, _, _)) = match attrOpt with Some (AttribInfo(_, tcref)) -> tyconRefEq g tcref tcref2 | _ -> false + +let (|ExtractAttribNamedArg|_|) nm args = + args |> List.tryPick (function AttribNamedArg(nm2, _, _, v) when nm = nm2 -> Some v | _ -> None) + +let (|StringExpr|_|) = function Expr.Const (Const.String n, _, _) -> Some n | _ -> None +let (|AttribInt32Arg|_|) = function AttribExpr(_, Expr.Const (Const.Int32 n, _, _)) -> Some n | _ -> None +let (|AttribInt16Arg|_|) = function AttribExpr(_, Expr.Const (Const.Int16 n, _, _)) -> Some n | _ -> None +let (|AttribBoolArg|_|) = function AttribExpr(_, Expr.Const (Const.Bool n, _, _)) -> Some n | _ -> None +let (|AttribStringArg|_|) = function AttribExpr(_, Expr.Const (Const.String n, _, _)) -> Some n | _ -> None + +let TryFindFSharpBoolAttributeWithDefault dflt g nm attrs = + match TryFindFSharpAttribute g nm attrs with + | Some(Attrib(_, _, [ ], _, _, _, _)) -> Some dflt + | Some(Attrib(_, _, [ AttribBoolArg b ], _, _, _, _)) -> Some b + | _ -> None + +let TryFindFSharpBoolAttribute g nm attrs = TryFindFSharpBoolAttributeWithDefault true g nm attrs +let TryFindFSharpBoolAttributeAssumeFalse g nm attrs = TryFindFSharpBoolAttributeWithDefault false g nm attrs + +let TryFindFSharpInt32Attribute g nm attrs = + match TryFindFSharpAttribute g nm attrs with + | Some(Attrib(_, _, [ AttribInt32Arg b ], _, _, _, _)) -> Some b + | _ -> None + +let TryFindFSharpStringAttribute g nm attrs = + match TryFindFSharpAttribute g nm attrs with + | Some(Attrib(_, _, [ AttribStringArg b ], _, _, _, _)) -> Some b + | _ -> None + +let TryFindILAttribute (AttribInfo (atref, _)) attrs = + HasILAttribute atref attrs + +let TryFindILAttributeOpt attr attrs = + match attr with + | Some (AttribInfo (atref, _)) -> HasILAttribute atref attrs + | _ -> false + +/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and +/// provided attributes. +// +// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types) +let TryBindTyconRefAttribute g (m: range) (AttribInfo (atref, _) as args) (tcref: TyconRef) f1 f2 (f3: obj option list * (string * obj option) list -> 'a option) : 'a option = + ignore m; ignore f3 + match metadataOfTycon tcref.Deref with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> + let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)), m) + match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure id, atref.FullName)), m) with + | Some args -> f3 args + | None -> None +#endif + | ILTypeMetadata (TILObjectReprData(_, _, tdef)) -> + match TryDecodeILAttribute atref tdef.CustomAttrs with + | Some attr -> f1 attr + | _ -> None + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + match TryFindFSharpAttribute g args tcref.Attribs with + | Some attr -> f2 attr + | _ -> None + +let TryFindTyconRefBoolAttribute g m attribSpec tcref = + TryBindTyconRefAttribute g m attribSpec tcref + (function + | [ ], _ -> Some true + | [ILAttribElem.Bool v ], _ -> Some v + | _ -> None) + (function + | Attrib(_, _, [ ], _, _, _, _) -> Some true + | Attrib(_, _, [ AttribBoolArg v ], _, _, _, _) -> Some v + | _ -> None) + (function + | [ ], _ -> Some true + | [ Some (:? bool as v : obj) ], _ -> Some v + | _ -> None) + +/// Try to find the resolved attributeusage for an type by walking its inheritance tree and picking the correct attribute usage value +let TryFindAttributeUsageAttribute g m tcref = + [| yield tcref + yield! supersOfTyconRef tcref |] + |> Array.tryPick (fun tcref -> + TryBindTyconRefAttribute g m g.attrib_AttributeUsageAttribute tcref + (fun (_, named) -> named |> List.tryPick (function "AllowMultiple", _, _, ILAttribElem.Bool res -> Some res | _ -> None)) + (fun (Attrib(_, _, _, named, _, _, _)) -> named |> List.tryPick (function AttribNamedArg("AllowMultiple", _, _, AttribBoolArg res ) -> Some res | _ -> None)) + (fun (_, named) -> named |> List.tryPick (function "AllowMultiple", Some (:? bool as res : obj) -> Some res | _ -> None)) + ) + +/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. +/// +/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions) +let TryFindTyconRefStringAttribute g m attribSpec tcref = + TryBindTyconRefAttribute g m attribSpec tcref + (function [ILAttribElem.String (Some msg) ], _ -> Some msg | _ -> None) + (function Attrib(_, _, [ AttribStringArg msg ], _, _, _, _) -> Some msg | _ -> None) + (function [ Some (:? string as msg : obj) ], _ -> Some msg | _ -> None) + +/// Check if a type definition has a specific attribute +let TyconRefHasAttribute g m attribSpec tcref = + TryBindTyconRefAttribute g m attribSpec tcref + (fun _ -> Some ()) + (fun _ -> Some ()) + (fun _ -> Some ()) + |> Option.isSome + +let isByrefTyconRef (g: TcGlobals) (tcref: TyconRef) = + (g.byref_tcr.CanDeref && tyconRefEq g g.byref_tcr tcref) || + (g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) || + (g.inref_tcr.CanDeref && tyconRefEq g g.inref_tcr tcref) || + (g.outref_tcr.CanDeref && tyconRefEq g g.outref_tcr tcref) || + tyconRefEqOpt g g.system_TypedReference_tcref tcref || + tyconRefEqOpt g g.system_ArgIterator_tcref tcref || + tyconRefEqOpt g g.system_RuntimeArgumentHandle_tcref tcref + +// See RFC FS-1053.md +let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) = + tcref.CanDeref && + match tcref.TryIsByRefLike with + | ValueSome res -> res + | _ -> + let res = + isByrefTyconRef g tcref || + (isStructTyconRef tcref && TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref) + tcref.SetIsByRefLike res + res + +let isSpanLikeTyconRef g m tcref = + isByrefLikeTyconRef g m tcref && + not (isByrefTyconRef g tcref) + +let isByrefLikeTy g m ty = + ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isByrefLikeTyconRef g m tcref | _ -> false) + +let isSpanLikeTy g m ty = + isByrefLikeTy g m ty && + not (isByrefTy g ty) + +let isSpanTyconRef g m tcref = + isByrefLikeTyconRef g m tcref && + tcref.CompiledRepresentationForNamedType.BasicQualifiedName = "System.Span`1" + +let isSpanTy g m ty = + ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isSpanTyconRef g m tcref | _ -> false) + +let rec tryDestSpanTy g m ty = + match tryAppTy g ty with + | ValueSome(tcref, [ty]) when isSpanTyconRef g m tcref -> ValueSome(struct(tcref, ty)) + | _ -> ValueNone + +let destSpanTy g m ty = + match tryDestSpanTy g m ty with + | ValueSome(struct(tcref, ty)) -> struct(tcref, ty) + | _ -> failwith "destSpanTy" + +let isReadOnlySpanTyconRef g m tcref = + isByrefLikeTyconRef g m tcref && + tcref.CompiledRepresentationForNamedType.BasicQualifiedName = "System.ReadOnlySpan`1" + +let isReadOnlySpanTy g m ty = + ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isReadOnlySpanTyconRef g m tcref | _ -> false) + +let tryDestReadOnlySpanTy g m ty = + match tryAppTy g ty with + | ValueSome(tcref, [ty]) when isReadOnlySpanTyconRef g m tcref -> ValueSome(struct(tcref, ty)) + | _ -> ValueNone + +let destReadOnlySpanTy g m ty = + match tryDestReadOnlySpanTy g m ty with + | ValueSome(struct(tcref, ty)) -> struct(tcref, ty) + | _ -> failwith "destReadOnlySpanTy" + +//------------------------------------------------------------------------- +// List and reference types... +//------------------------------------------------------------------------- + +let destByrefTy g ty = + match ty |> stripTyEqns g with + | TType_app(tcref, [x; _]) when g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref -> x // Check sufficient FSharp.Core + | TType_app(tcref, [x]) when tyconRefEq g g.byref_tcr tcref -> x // all others + | _ -> failwith "destByrefTy: not a byref type" + +let (|ByrefTy|_|) g ty = + // Because of byref = byref2 it is better to write this using is/dest + if isByrefTy g ty then Some (destByrefTy g ty) else None + +let destNativePtrTy g ty = + match ty |> stripTyEqns g with + | TType_app(tcref, [x]) when tyconRefEq g g.nativeptr_tcr tcref -> x + | _ -> failwith "destNativePtrTy: not a native ptr type" + +let isRefCellTy g ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.refcell_tcr_canon tcref + +let destRefCellTy g ty = + match ty |> stripTyEqns g with + | TType_app(tcref, [x]) when tyconRefEq g g.refcell_tcr_canon tcref -> x + | _ -> failwith "destRefCellTy: not a ref type" + +let StripSelfRefCell(g: TcGlobals, baseOrThisInfo: ValBaseOrThisInfo, tau: TType) : TType = + if baseOrThisInfo = CtorThisVal && isRefCellTy g tau + then destRefCellTy g tau + else tau + +let mkRefCellTy (g: TcGlobals) ty = TType_app(g.refcell_tcr_nice, [ty]) + +let mkLazyTy (g: TcGlobals) ty = TType_app(g.lazy_tcr_nice, [ty]) + +let mkPrintfFormatTy (g: TcGlobals) aty bty cty dty ety = TType_app(g.format_tcr, [aty;bty;cty;dty; ety]) + +let mkOptionTy (g: TcGlobals) ty = TType_app (g.option_tcr_nice, [ty]) + +let mkValueOptionTy (g: TcGlobals) ty = TType_app (g.valueoption_tcr_nice, [ty]) + +let mkNullableTy (g: TcGlobals) ty = TType_app (g.system_Nullable_tcref, [ty]) + +let mkListTy (g: TcGlobals) ty = TType_app (g.list_tcr_nice, [ty]) + +let isValueOptionTy (g: TcGlobals) ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.valueoption_tcr_canon tcref + +let isOptionTy (g: TcGlobals) ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.option_tcr_canon tcref + +let tryDestOptionTy g ty = + match argsOfAppTy g ty with + | [ty1] when isOptionTy g ty -> ValueSome ty1 + | _ -> ValueNone + +let destOptionTy g ty = + match tryDestOptionTy g ty with + | ValueSome ty -> ty + | ValueNone -> failwith "destOptionTy: not an option type" + +let isNullableTy (g: TcGlobals) ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.system_Nullable_tcref tcref + +let tryDestNullableTy g ty = + match argsOfAppTy g ty with + | [ty1] when isNullableTy g ty -> ValueSome ty1 + | _ -> ValueNone + +let destNullableTy g ty = + match tryDestNullableTy g ty with + | ValueSome ty -> ty + | ValueNone -> failwith "destNullableTy: not a Nullable type" + +let (|NullableTy|_|) g ty = + match tryAppTy g ty with + | ValueSome (tcref, [tyarg]) when tyconRefEq g tcref g.system_Nullable_tcref -> Some tyarg + | _ -> None + +let (|StripNullableTy|) g ty = + match tryDestNullableTy g ty with + | ValueSome tyarg -> tyarg + | _ -> ty + +let isLinqExpressionTy g ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.system_LinqExpression_tcref tcref + +let tryDestLinqExpressionTy g ty = + match argsOfAppTy g ty with + | [ty1] when isLinqExpressionTy g ty -> Some ty1 + | _ -> None + +let destLinqExpressionTy g ty = + match tryDestLinqExpressionTy g ty with + | Some ty -> ty + | None -> failwith "destLinqExpressionTy: not an expression type" + +let mkNoneCase (g: TcGlobals) = mkUnionCaseRef g.option_tcr_canon "None" + +let mkSomeCase (g: TcGlobals) = mkUnionCaseRef g.option_tcr_canon "Some" + +let mkSome g ty arg m = mkUnionCaseExpr(mkSomeCase g, [ty], [arg], m) + +let mkNone g ty m = mkUnionCaseExpr(mkNoneCase g, [ty], [], m) + +let mkValueSomeCase (g: TcGlobals) = mkUnionCaseRef g.valueoption_tcr_canon "ValueSome" + +let mkAnySomeCase g isStruct = (if isStruct then mkValueSomeCase g else mkSomeCase g) + +type ValRef with + member vref.IsDispatchSlot = + match vref.MemberInfo with + | Some membInfo -> membInfo.MemberFlags.IsDispatchSlot + | None -> false + +let (|UnopExpr|_|) _g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, _, [arg1], _) -> Some (vref, arg1) + | _ -> None + +let (|BinopExpr|_|) _g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, _, [arg1;arg2], _) -> Some (vref, arg1, arg2) + | _ -> None + +let (|SpecificUnopExpr|_|) g vrefReqd expr = + match expr with + | UnopExpr g (vref, arg1) when valRefEq g vref vrefReqd -> Some arg1 + | _ -> None + +let (|SpecificBinopExpr|_|) g vrefReqd expr = + match expr with + | BinopExpr g (vref, arg1, arg2) when valRefEq g vref vrefReqd -> Some (arg1, arg2) + | _ -> None + +let (|EnumExpr|_|) g expr = + match (|SpecificUnopExpr|_|) g g.enum_vref expr with + | None -> (|SpecificUnopExpr|_|) g g.enumOfValue_vref expr + | x -> x + +let (|BitwiseOrExpr|_|) g expr = (|SpecificBinopExpr|_|) g g.bitwise_or_vref expr + +let (|AttribBitwiseOrExpr|_|) g expr = + match expr with + | BitwiseOrExpr g (arg1, arg2) -> Some(arg1, arg2) + // Special workaround, only used when compiling FSharp.Core.dll. Uses of 'a ||| b' occur before the '|||' bitwise or operator + // is defined. These get through type checking because enums implicitly support the '|||' operator through + // the automatic resolution of undefined operators (see tc.fs, Item.ImplicitOp). This then compiles as an + // application of a lambda to two arguments. We recognize this pattern here + | Expr.App (Expr.Lambda _, _, _, [arg1;arg2], _) when g.compilingFslib -> + Some(arg1, arg2) + | _ -> None + +let isUncheckedDefaultOfValRef g vref = + valRefEq g vref g.unchecked_defaultof_vref + // There is an internal version of typeof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "defaultof") + +let isTypeOfValRef g vref = + valRefEq g vref g.typeof_vref + // There is an internal version of typeof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "typeof") + +let isSizeOfValRef g vref = + valRefEq g vref g.sizeof_vref + // There is an internal version of typeof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "sizeof") + +let isNameOfValRef g vref = + valRefEq g vref g.nameof_vref + // There is an internal version of nameof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "nameof") + +let isTypeDefOfValRef g vref = + valRefEq g vref g.typedefof_vref + // There is an internal version of typedefof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "typedefof") + +let (|UncheckedDefaultOfExpr|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isUncheckedDefaultOfValRef g vref -> Some ty + | _ -> None + +let (|TypeOfExpr|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isTypeOfValRef g vref -> Some ty + | _ -> None + +let (|SizeOfExpr|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isSizeOfValRef g vref -> Some ty + | _ -> None + +let (|TypeDefOfExpr|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isTypeDefOfValRef g vref -> Some ty + | _ -> None + +let (|NameOfExpr|_|) g expr = + match expr with + | Expr.App(Expr.Val(vref,_,_),_,[ty],[],_) when isNameOfValRef g vref -> Some ty + | _ -> None + +let (|SeqExpr|_|) g expr = + match expr with + | Expr.App(Expr.Val(vref,_,_),_,_,_,_) when valRefEq g vref g.seq_vref -> Some() + | _ -> None + +//-------------------------------------------------------------------------- +// DEBUG layout +//--------------------------------------------------------------------------- +module DebugPrint = + let layoutRanges = ref false + + let squareAngleL x = LeftL.leftBracketAngle ^^ x ^^ RightL.rightBracketAngle + + let angleL x = sepL leftAngle ^^ x ^^ rightL rightAngle + + let braceL x = leftL leftBrace ^^ x ^^ rightL rightBrace + + let braceBarL x = leftL leftBraceBar ^^ x ^^ rightL rightBraceBar + + let boolL = function true -> WordL.keywordTrue | false -> WordL.keywordFalse + + let intL (n: int) = wordL (tagNumericLiteral (string n )) + + let int64L (n: int64) = wordL (tagNumericLiteral (string n )) + + let jlistL xL xmap = QueueList.foldBack (fun x z -> z @@ xL x) xmap emptyL + + let bracketIfL x lyt = if x then bracketL lyt else lyt + + let lvalopL x = + match x with + | LAddrOf readonly -> wordL (tagText (sprintf "LAddrOf(%b)" readonly)) + | LByrefGet -> wordL (tagText "LByrefGet") + | LSet -> wordL (tagText "LSet") + | LByrefSet -> wordL (tagText "LByrefSet") + + let angleBracketL l = leftL (tagText "<") ^^ l ^^ rightL (tagText ">") + + let angleBracketListL l = angleBracketL (sepListL (sepL (tagText ",")) l) + + let layoutMemberFlags (memFlags: SynMemberFlags) = + let stat = + if memFlags.IsInstance || (memFlags.MemberKind = SynMemberKind.Constructor) then emptyL + else wordL (tagText "static") + let stat = + if memFlags.IsDispatchSlot then stat ++ wordL (tagText "abstract") + elif memFlags.IsOverrideOrExplicitImpl then stat ++ wordL (tagText "override") + else stat + stat + + let stampL _n w = + w + + let layoutTyconRef (tc: TyconRef) = + wordL (tagText tc.DisplayNameWithStaticParameters) |> stampL tc.Stamp + + let rec auxTypeL env ty = auxTypeWrapL env false ty + + and auxTypeAtomL env ty = auxTypeWrapL env true ty + + and auxTyparsL env tcL prefix tinst = + match tinst with + | [] -> tcL + | [t] -> + let tL = auxTypeAtomL env t + if prefix then tcL ^^ angleBracketL tL + else tL ^^ tcL + | _ -> + let tinstL = List.map (auxTypeL env) tinst + if prefix then + tcL ^^ angleBracketListL tinstL + else + tupleL tinstL ^^ tcL + + and auxTypeWrapL env isAtomic ty = + let wrap x = bracketIfL isAtomic x in // wrap iff require atomic expr + match stripTyparEqns ty with + | TType_forall (typars, rty) -> + (leftL (tagText "!") ^^ layoutTyparDecls typars --- auxTypeL env rty) |> wrap + | TType_ucase (UnionCaseRef(tcref, _), tinst) + | TType_app (tcref, tinst) -> + let prefix = tcref.IsPrefixDisplay + let tcL = layoutTyconRef tcref + auxTyparsL env tcL prefix tinst + | TType_anon (anonInfo, tys) -> braceBarL (sepListL (wordL (tagText ";")) (List.map2 (fun nm ty -> wordL (tagField nm) --- auxTypeAtomL env ty) (Array.toList anonInfo.SortedNames) tys)) + | TType_tuple (_tupInfo, tys) -> sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) tys) |> wrap + | TType_fun (f, x) -> ((auxTypeAtomL env f ^^ wordL (tagText "->")) --- auxTypeL env x) |> wrap + | TType_var typar -> auxTyparWrapL env isAtomic typar + | TType_measure unt -> +#if DEBUG + leftL (tagText "{") ^^ + (match global_g with + | None -> wordL (tagText "") + | Some g -> + let sortVars (vs:(Typar * Rational) list) = vs |> List.sortBy (fun (v, _) -> v.DisplayName) + let sortCons (cs:(TyconRef * Rational) list) = cs |> List.sortBy (fun (c, _) -> c.DisplayName) + let negvs, posvs = ListMeasureVarOccsWithNonZeroExponents unt |> sortVars |> List.partition (fun (_, e) -> SignRational e < 0) + let negcs, poscs = ListMeasureConOccsWithNonZeroExponents g false unt |> sortCons |> List.partition (fun (_, e) -> SignRational e < 0) + let unparL (uv: Typar) = wordL (tagText ("'" + uv.DisplayName)) + let unconL tc = layoutTyconRef tc + let rationalL e = wordL (tagText(RationalToString e)) + let measureToPowerL x e = if e = OneRational then x else x -- wordL (tagText "^") -- rationalL e + let prefix = + spaceListL + (List.map (fun (v, e) -> measureToPowerL (unparL v) e) posvs @ + List.map (fun (c, e) -> measureToPowerL (unconL c) e) poscs) + let postfix = + spaceListL + (List.map (fun (v, e) -> measureToPowerL (unparL v) (NegRational e)) negvs @ + List.map (fun (c, e) -> measureToPowerL (unconL c) (NegRational e)) negcs) + match (negvs, negcs) with + | [], [] -> prefix + | _ -> prefix ^^ sepL (tagText "/") ^^ postfix) ^^ + rightL (tagText "}") +#else + unt |> ignore + wordL(tagText "") +#endif + + and auxTyparWrapL (env: SimplifyTypes.TypeSimplificationInfo) isAtomic (typar: Typar) = + let wrap x = bracketIfL isAtomic x in // wrap iff require atomic expr + // There are several cases for pprinting of typar. + // + // 'a - is multiple occurrence. + // #Type - inplace coercion constraint and singleton + // ('a :> Type) - inplace coercion constraint not singleton + // ('a.opM: S->T) - inplace operator constraint + let tpL = + wordL (tagText (prefixOfStaticReq typar.StaticReq + + prefixOfRigidTypar typar + + typar.DisplayName)) + let varL = tpL |> stampL typar.Stamp + + match Zmap.tryFind typar env.inplaceConstraints with + | Some typarConstraintTy -> + if Zset.contains typar env.singletons then + leftL (tagText "#") ^^ auxTyparConstraintTypL env typarConstraintTy + else + (varL ^^ sepL (tagText ":>") ^^ auxTyparConstraintTypL env typarConstraintTy) |> wrap + | _ -> varL + + and auxTypar2L env typar = auxTyparWrapL env false typar + + and auxTyparAtomL env typar = auxTyparWrapL env true typar + + and auxTyparConstraintTypL env ty = auxTypeL env ty + + and auxTraitL env (ttrait: TraitConstraintInfo) = +#if DEBUG + let (TTrait(tys, nm, memFlags, argtys, rty, _)) = ttrait + match global_g with + | None -> wordL (tagText "") + | Some g -> + let rty = GetFSharpViewOfReturnType g rty + let stat = layoutMemberFlags memFlags + let argsL = sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) argtys) + let resL = auxTypeL env rty + let methodTypeL = (argsL ^^ wordL (tagText "->")) ++ resL + bracketL (stat ++ bracketL (sepListL (wordL (tagText "or")) (List.map (auxTypeAtomL env) tys)) ++ wordL (tagText "member") --- (wordL (tagText nm) ^^ wordL (tagText ":") -- methodTypeL)) +#else + ignore (env, ttrait) + wordL(tagText "trait") +#endif + + and auxTyparConstraintL env (tp, tpc) = + let constraintPrefix l = auxTypar2L env tp ^^ wordL (tagText ":") ^^ l + match tpc with + | TyparConstraint.CoercesTo(typarConstraintTy, _) -> + auxTypar2L env tp ^^ wordL (tagText ":>") --- auxTyparConstraintTypL env typarConstraintTy + | TyparConstraint.MayResolveMember(traitInfo, _) -> + auxTypar2L env tp ^^ wordL (tagText ":") --- auxTraitL env traitInfo + | TyparConstraint.DefaultsTo(_, ty, _) -> + wordL (tagText "default") ^^ auxTypar2L env tp ^^ wordL (tagText ":") ^^ auxTypeL env ty + | TyparConstraint.IsEnum(ty, _) -> + auxTyparsL env (wordL (tagText "enum")) true [ty] |> constraintPrefix + | TyparConstraint.IsDelegate(aty, bty, _) -> + auxTyparsL env (wordL (tagText "delegate")) true [aty; bty] |> constraintPrefix + | TyparConstraint.SupportsNull _ -> + wordL (tagText "null") |> constraintPrefix + | TyparConstraint.SupportsComparison _ -> + wordL (tagText "comparison") |> constraintPrefix + | TyparConstraint.SupportsEquality _ -> + wordL (tagText "equality") |> constraintPrefix + | TyparConstraint.IsNonNullableStruct _ -> + wordL (tagText "struct") |> constraintPrefix + | TyparConstraint.IsReferenceType _ -> + wordL (tagText "not struct") |> constraintPrefix + | TyparConstraint.IsUnmanaged _ -> + wordL (tagText "unmanaged") |> constraintPrefix + | TyparConstraint.SimpleChoice(tys, _) -> + bracketL (sepListL (sepL (tagText "|")) (List.map (auxTypeL env) tys)) |> constraintPrefix + | TyparConstraint.RequiresDefaultConstructor _ -> + bracketL (wordL (tagText "new : unit -> ") ^^ (auxTypar2L env tp)) |> constraintPrefix + + and auxTyparConstraintsL env x = + match x with + | [] -> emptyL + | cxs -> wordL (tagText "when") --- aboveListL (List.map (auxTyparConstraintL env) cxs) + + and typarL tp = auxTypar2L SimplifyTypes.typeSimplificationInfo0 tp + + and typarAtomL tp = auxTyparAtomL SimplifyTypes.typeSimplificationInfo0 tp + + and typeAtomL tau = + let tau, cxs = tau, [] + let env = SimplifyTypes.CollectInfo false [tau] cxs + match env.postfixConstraints with + | [] -> auxTypeAtomL env tau + | _ -> bracketL (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) + + and typeL tau = + let tau, cxs = tau, [] + let env = SimplifyTypes.CollectInfo false [tau] cxs + match env.postfixConstraints with + | [] -> auxTypeL env tau + | _ -> (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) + + and typarDeclL tp = + let tau, cxs = mkTyparTy tp, (List.map (fun x -> (tp, x)) tp.Constraints) + let env = SimplifyTypes.CollectInfo false [tau] cxs + match env.postfixConstraints with + | [] -> auxTypeL env tau + | _ -> (auxTypeL env tau --- auxTyparConstraintsL env env.postfixConstraints) + and layoutTyparDecls tps = angleBracketListL (List.map typarDeclL tps) + + let rangeL m = wordL (tagText (stringOfRange m)) + + let instL tyL tys = + match tys with + | [] -> emptyL + | tys -> sepL (tagText "@[") ^^ commaListL (List.map tyL tys) ^^ rightL (tagText "]") + + let valRefL (vr: ValRef) = + wordL (tagText vr.LogicalName) |> stampL vr.Stamp + + let layoutAttrib (Attrib(_, k, _, _, _, _, _)) = + leftL (tagText "[<") ^^ + (match k with + | ILAttrib ilmeth -> wordL (tagText ilmeth.Name) + | FSAttrib vref -> valRefL vref) ^^ + rightL (tagText ">]") + + let layoutAttribs attribs = aboveListL (List.map layoutAttrib attribs) + + let arityInfoL (ValReprInfo (tpNames, _, _) as tvd) = + let ns = tvd.AritiesOfArgs in + leftL (tagText "arity<") ^^ intL tpNames.Length ^^ sepL (tagText ">[") ^^ commaListL (List.map intL ns) ^^ rightL (tagText "]") + + let valL (v: Val) = + let vsL = wordL (tagText (DecompileOpName v.LogicalName)) |> stampL v.Stamp + let vsL = vsL -- layoutAttribs v.Attribs + vsL + + let typeOfValL (v: Val) = + (valL v + ^^ (if v.MustInline then wordL (tagText "inline ") else emptyL) + ^^ (if v.IsMutable then wordL(tagText "mutable ") else emptyL) + ^^ wordL (tagText ":")) -- typeL v.Type + + let tslotparamL (TSlotParam(nmOpt, ty, inFlag, outFlag, _, _)) = + (optionL (tagText >> wordL) nmOpt) ^^ + wordL(tagText ":") ^^ + typeL ty ^^ + (if inFlag then wordL(tagText "[in]") else emptyL) ^^ + (if outFlag then wordL(tagText "[out]") else emptyL) ^^ + (if inFlag then wordL(tagText "[opt]") else emptyL) + + let slotSigL (slotsig: SlotSig) = +#if DEBUG + let (TSlotSig(nm, ty, tps1, tps2, pms, rty)) = slotsig + match global_g with + | None -> wordL(tagText "") + | Some g -> + let rty = GetFSharpViewOfReturnType g rty + (wordL(tagText "slot") --- (wordL (tagText nm)) ^^ wordL(tagText "@") ^^ typeL ty) -- + (wordL(tagText "LAM") --- spaceListL (List.map typarL tps1) ^^ rightL(tagText ".")) --- + (wordL(tagText "LAM") --- spaceListL (List.map typarL tps2) ^^ rightL(tagText ".")) --- + (commaListL (List.map (List.map tslotparamL >> tupleL) pms)) ^^ (wordL(tagText "-> ")) --- (typeL rty) +#else + ignore slotsig + wordL(tagText "slotsig") +#endif + + let rec memberL (g:TcGlobals) (v: Val) (membInfo: ValMemberInfo) = + aboveListL + [ wordL(tagText "compiled_name! = ") ^^ wordL (tagText (v.CompiledName g.CompilerGlobalState)) + wordL(tagText "membInfo-slotsig! = ") ^^ listL slotSigL membInfo.ImplementedSlotSigs ] + + and valAtBindL g v = + let vL = valL v + let mutL = (if v.IsMutable then wordL(tagText "mutable") ++ vL else vL) + mutL --- + aboveListL + [ yield wordL(tagText ":") ^^ typeL v.Type + match v.MemberInfo with None -> () | Some mem_info -> yield wordL(tagText "!") ^^ memberL g v mem_info + match v.ValReprInfo with None -> () | Some arity_info -> yield wordL(tagText "#") ^^ arityInfoL arity_info] + + let unionCaseRefL (ucr: UnionCaseRef) = wordL (tagText ucr.CaseName) + + let recdFieldRefL (rfref: RecdFieldRef) = wordL (tagText rfref.FieldName) + + let identL (id: Ident) = wordL (tagText id.idText) + + // Note: We need nice printing of constants in order to print literals and attributes + let constL c = + let str = + match c with + | Const.Bool x -> if x then "true" else "false" + | Const.SByte x -> (x |> string)+"y" + | Const.Byte x -> (x |> string)+"uy" + | Const.Int16 x -> (x |> string)+"s" + | Const.UInt16 x -> (x |> string)+"us" + | Const.Int32 x -> (x |> string) + | Const.UInt32 x -> (x |> string)+"u" + | Const.Int64 x -> (x |> string)+"L" + | Const.UInt64 x -> (x |> string)+"UL" + | Const.IntPtr x -> (x |> string)+"n" + | Const.UIntPtr x -> (x |> string)+"un" + | Const.Single d -> + (let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) + if String.forall (fun c -> System.Char.IsDigit c || c = '-') s + then s + ".0" + else s) + "f" + | Const.Double d -> + let s = d.ToString("g12", System.Globalization.CultureInfo.InvariantCulture) + if String.forall (fun c -> System.Char.IsDigit c || c = '-') s + then s + ".0" + else s + | Const.Char c -> "'" + c.ToString() + "'" + | Const.String bs -> "\"" + bs + "\"" + | Const.Unit -> "()" + | Const.Decimal bs -> string bs + "M" + | Const.Zero -> "default" + wordL (tagText str) + + let rec tyconL g (tycon: Tycon) = + if tycon.IsModuleOrNamespace then entityL g tycon else + + let lhsL = wordL (tagText (match tycon.TypeOrMeasureKind with TyparKind.Measure -> "[] type" | TyparKind.Type -> "type")) ^^ wordL (tagText tycon.DisplayName) ^^ layoutTyparDecls tycon.TyparsNoRange + let lhsL = lhsL --- layoutAttribs tycon.Attribs + let memberLs = + let adhoc = + tycon.MembersOfFSharpTyconSorted + |> List.filter (fun v -> not v.IsDispatchSlot) + |> List.filter (fun v -> not v.Deref.IsClassConstructor) + // Don't print individual methods forming interface implementations - these are currently never exported + |> List.filter (fun v -> isNil (Option.get v.MemberInfo).ImplementedSlotSigs) + let iimpls = + match tycon.TypeReprInfo with + | TFSharpObjectRepr r when (match r.fsobjmodel_kind with TFSharpInterface -> true | _ -> false) -> [] + | _ -> tycon.ImmediateInterfacesOfFSharpTycon + let iimpls = iimpls |> List.filter (fun (_, compgen, _) -> not compgen) + // if TFSharpInterface, the iimpls should be printed as inherited interfaces + if isNil adhoc && isNil iimpls then + emptyL + else + let iimplsLs = iimpls |> List.map (fun (ty, _, _) -> wordL(tagText "interface") --- typeL ty) + let adhocLs = adhoc |> List.map (fun vref -> valAtBindL g vref.Deref) + (wordL(tagText "with") @@-- aboveListL (iimplsLs @ adhocLs)) @@ wordL(tagText "end") + + let layoutUnionCaseArgTypes argtys = sepListL (wordL(tagText "*")) (List.map typeL argtys) + + let ucaseL prefixL (ucase: UnionCase) = + let nmL = wordL (tagText ucase.DisplayName) + match ucase.RecdFields |> List.map (fun rfld -> rfld.FormalType) with + | [] -> (prefixL ^^ nmL) + | argtys -> (prefixL ^^ nmL ^^ wordL(tagText "of")) --- layoutUnionCaseArgTypes argtys + + let layoutUnionCases ucases = + let prefixL = if not (isNilOrSingleton ucases) then wordL(tagText "|") else emptyL + List.map (ucaseL prefixL) ucases + + let layoutRecdField (fld: RecdField) = + let lhs = wordL (tagText fld.LogicalName) + let lhs = if fld.IsMutable then wordL(tagText "mutable") --- lhs else lhs + (lhs ^^ rightL(tagText ":")) --- typeL fld.FormalType + + let tyconReprL (repr, tycon: Tycon) = + match repr with + | TFSharpRecdRepr _ -> + tycon.TrueFieldsAsList |> List.map (fun fld -> layoutRecdField fld ^^ rightL(tagText ";")) |> aboveListL + | TFSharpObjectRepr r -> + match r.fsobjmodel_kind with + | TFSharpDelegate _ -> + wordL(tagText "delegate ...") + | _ -> + let start = + match r.fsobjmodel_kind with + | TFSharpClass -> "class" + | TFSharpInterface -> "interface" + | TFSharpStruct -> "struct" + | TFSharpEnum -> "enum" + | _ -> failwith "???" + let inherits = + match r.fsobjmodel_kind, tycon.TypeContents.tcaug_super with + | TFSharpClass, Some super -> [wordL(tagText "inherit") ^^ (typeL super)] + | TFSharpInterface, _ -> + tycon.ImmediateInterfacesOfFSharpTycon + |> List.filter (fun (_, compgen, _) -> not compgen) + |> List.map (fun (ity, _, _) -> wordL(tagText "inherit") ^^ (typeL ity)) + | _ -> [] + let vsprs = + tycon.MembersOfFSharpTyconSorted + |> List.filter (fun v -> v.IsDispatchSlot) + |> List.map (fun vref -> valAtBindL g vref.Deref) + let vals = tycon.TrueFieldsAsList |> List.map (fun f -> (if f.IsStatic then wordL(tagText "static") else emptyL) ^^ wordL(tagText "val") ^^ layoutRecdField f) + let alldecls = inherits @ vsprs @ vals + let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil alldecls | _ -> false + if emptyMeasure then emptyL else (wordL (tagText start) @@-- aboveListL alldecls) @@ wordL(tagText "end") + | TFSharpUnionRepr _ -> tycon.UnionCasesAsList |> layoutUnionCases |> aboveListL + | TAsmRepr _ -> wordL(tagText "(# ... #)") + | TMeasureableRepr ty -> typeL ty + | TILObjectRepr (TILObjectReprData(_, _, td)) -> wordL (tagText td.Name) + | _ -> failwith "unreachable" + + let reprL = + match tycon.TypeReprInfo with +#if !NO_EXTENSIONTYPING + | TProvidedTypeRepr _ + | TProvidedNamespaceRepr _ +#endif + | TNoRepr -> + match tycon.TypeAbbrev with + | None -> lhsL @@-- memberLs + | Some a -> (lhsL ^^ wordL(tagText "=")) --- (typeL a @@ memberLs) + | a -> + let rhsL = tyconReprL (a, tycon) @@ memberLs + (lhsL ^^ wordL(tagText "=")) @@-- rhsL + reprL + + and bindingL g (TBind(v, repr, _)) = + (valAtBindL g v ^^ wordL(tagText "=")) @@-- exprL g repr + + and exprL g expr = exprWrapL g false expr + + and atomL g expr = exprWrapL g true expr // true means bracket if needed to be atomic expr + + and letRecL g binds bodyL = + let eqnsL = + binds + |> List.mapHeadTail (fun bind -> wordL(tagText "rec") ^^ bindingL g bind ^^ wordL(tagText "in")) + (fun bind -> wordL(tagText "and") ^^ bindingL g bind ^^ wordL(tagText "in")) + (aboveListL eqnsL @@ bodyL) + + and letL g bind bodyL = + let eqnL = wordL(tagText "let") ^^ bindingL g bind + (eqnL @@ bodyL) + + and exprWrapL g isAtomic expr = + let atomL args = atomL g args + let exprL expr = exprL g expr + let valAtBindL v = valAtBindL g v + let targetL targets = targetL g targets + let wrap = bracketIfL isAtomic // wrap iff require atomic expr + let lay = + match expr with + | Expr.Const (c, _, _) -> constL c + | Expr.Val (v, flags, _) -> + let xL = valL v.Deref + let xL = + match flags with + | PossibleConstrainedCall _ -> xL ^^ rightL(tagText "") + | CtorValUsedAsSelfInit -> xL ^^ rightL(tagText "") + | CtorValUsedAsSuperInit -> xL ^^ rightL(tagText "") + | VSlotDirectCall -> xL ^^ rightL(tagText "") + | NormalValUse -> xL + xL + | Expr.Sequential (expr1, expr2, flag, _, _) -> + let flag = + match flag with + | NormalSeq -> ";" + | ThenDoSeq -> "; ThenDo" + ((exprL expr1 ^^ rightL (tagText flag)) @@ exprL expr2) |> wrap + | Expr.Lambda (_, _, baseValOpt, argvs, body, _, _) -> + let formalsL = spaceListL (List.map valAtBindL argvs) in + let bindingL = + match baseValOpt with + | None -> wordL(tagText "lam") ^^ formalsL ^^ rightL(tagText ".") + | Some basev -> wordL(tagText "lam") ^^ (leftL(tagText "base=") ^^ valAtBindL basev) --- formalsL ^^ rightL(tagText ".") in + (bindingL ++ exprL body) |> wrap + | Expr.TyLambda (_, argtyvs, body, _, _) -> + ((wordL(tagText "LAM") ^^ spaceListL (List.map typarL argtyvs) ^^ rightL(tagText ".")) ++ exprL body) |> wrap + | Expr.TyChoose (argtyvs, body, _) -> + ((wordL(tagText "CHOOSE") ^^ spaceListL (List.map typarL argtyvs) ^^ rightL(tagText ".")) ++ exprL body) |> wrap + | Expr.App (f, _, tys, argtys, _) -> + let flayout = atomL f + appL g flayout tys argtys |> wrap + | Expr.LetRec (binds, body, _, _) -> + letRecL g binds (exprL body) |> wrap + | Expr.Let (bind, body, _, _) -> + letL g bind (exprL body) |> wrap + | Expr.Link rX -> + (wordL(tagText "RecLink") --- atomL (!rX)) |> wrap + | Expr.Match (_, _, dtree, targets, _, _) -> + leftL(tagText "[") ^^ (decisionTreeL g dtree @@ aboveListL (List.mapi targetL (targets |> Array.toList)) ^^ rightL(tagText "]")) + | Expr.Op (TOp.UnionCase c, _, args, _) -> + (unionCaseRefL c ++ spaceListL (List.map atomL args)) |> wrap + | Expr.Op (TOp.ExnConstr ecref, _, args, _) -> + wordL (tagText ecref.LogicalName) ^^ bracketL (commaListL (List.map atomL args)) + | Expr.Op (TOp.Tuple _, _, xs, _) -> + tupleL (List.map exprL xs) + | Expr.Op (TOp.Recd (ctor, tc), _, xs, _) -> + let fields = tc.TrueInstanceFieldsAsList + let lay fs x = (wordL (tagText fs.rfield_id.idText) ^^ sepL(tagText "=")) --- (exprL x) + let ctorL = + match ctor with + | RecdExpr -> emptyL + | RecdExprIsObjInit-> wordL(tagText "(new)") + leftL(tagText "{") ^^ semiListL (List.map2 lay fields xs) ^^ rightL(tagText "}") ^^ ctorL + | Expr.Op (TOp.ValFieldSet rf, _, [rx;x], _) -> + (atomL rx --- wordL(tagText ".")) ^^ (recdFieldRefL rf ^^ wordL(tagText "<-") --- exprL x) + | Expr.Op (TOp.ValFieldSet rf, _, [x], _) -> + (recdFieldRefL rf ^^ wordL(tagText "<-") --- exprL x) + | Expr.Op (TOp.ValFieldGet rf, _, [rx], _) -> + (atomL rx ^^ rightL(tagText ".#") ^^ recdFieldRefL rf) + | Expr.Op (TOp.ValFieldGet rf, _, [], _) -> + recdFieldRefL rf + | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [rx], _) -> + leftL(tagText "&") ^^ bracketL (atomL rx ^^ rightL(tagText ".!") ^^ recdFieldRefL rf) + | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [], _) -> + leftL(tagText "&") ^^ (recdFieldRefL rf) + | Expr.Op (TOp.UnionCaseTagGet tycr, _, [x], _) -> + wordL (tagText ("#" + tycr.LogicalName + ".tag")) ^^ atomL x + | Expr.Op (TOp.UnionCaseProof c, _, [x], _) -> + wordL (tagText ("#" + c.CaseName + ".cast")) ^^ atomL x + | Expr.Op (TOp.UnionCaseFieldGet (c, i), _, [x], _) -> + wordL (tagText ("#" + c.CaseName + "." + string i)) --- atomL x + | Expr.Op (TOp.UnionCaseFieldSet (c, i), _, [x;y], _) -> + ((atomL x --- (rightL (tagText ("#" + c.CaseName + "." + string i)))) ^^ wordL(tagText ":=")) --- exprL y + | Expr.Op (TOp.TupleFieldGet (_, i), _, [x], _) -> + wordL (tagText ("#" + string i)) --- atomL x + | Expr.Op (TOp.Coerce, [ty;_], [x], _) -> + atomL x --- (wordL(tagText ":>") ^^ typeL ty) + | Expr.Op (TOp.Reraise, [_], [], _) -> + wordL(tagText "Rethrow!") + | Expr.Op (TOp.ILAsm (instrs, retTypes), tyargs, args, _) -> + let instrs = instrs |> List.map (sprintf "%+A" >> tagText >> wordL) |> spaceListL // %+A has + since instrs are from an "internal" type + let instrs = leftL(tagText "(#") ^^ instrs ^^ rightL(tagText "#)") + (appL g instrs tyargs args --- + wordL(tagText ":") ^^ spaceListL (List.map typeAtomL retTypes)) |> wrap + | Expr.Op (TOp.LValueOp (lvop, vr), _, args, _) -> + (lvalopL lvop ^^ valRefL vr --- bracketL (commaListL (List.map atomL args))) |> wrap + | Expr.Op (TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, enclTypeInst, methInst, _), tyargs, args, _) -> + let meth = ilMethRef.Name + wordL(tagText "ILCall") ^^ + aboveListL + [ yield wordL (tagText ilMethRef.DeclaringTypeRef.FullName) ^^ sepL(tagText ".") ^^ wordL (tagText meth) + if not enclTypeInst.IsEmpty then yield wordL(tagText "tinst ") --- listL typeL enclTypeInst + if not methInst.IsEmpty then yield wordL (tagText "minst ") --- listL typeL methInst + if not tyargs.IsEmpty then yield wordL (tagText "tyargs") --- listL typeL tyargs + if not args.IsEmpty then yield listL exprL args ] + |> wrap + | Expr.Op (TOp.Array, [_], xs, _) -> + leftL(tagText "[|") ^^ commaListL (List.map exprL xs) ^^ rightL(tagText "|]") + | Expr.Op (TOp.While _, [], [Expr.Lambda (_, _, _, [_], x1, _, _);Expr.Lambda (_, _, _, [_], x2, _, _)], _) -> + (wordL(tagText "while") ^^ exprL x1 ^^ wordL(tagText "do")) @@-- exprL x2 + | Expr.Op (TOp.For _, [], [Expr.Lambda (_, _, _, [_], x1, _, _);Expr.Lambda (_, _, _, [_], x2, _, _);Expr.Lambda (_, _, _, [_], x3, _, _)], _) -> + wordL(tagText "for") ^^ aboveListL [(exprL x1 ^^ wordL(tagText "to") ^^ exprL x2 ^^ wordL(tagText "do")); exprL x3 ] ^^ rightL(tagText "done") + | Expr.Op (TOp.TryWith _, [_], [Expr.Lambda (_, _, _, [_], x1, _, _);Expr.Lambda (_, _, _, [_], xf, _, _);Expr.Lambda (_, _, _, [_], xh, _, _)], _) -> + (wordL (tagText "try") @@-- exprL x1) @@ (wordL(tagText "with-filter") @@-- exprL xf) @@ (wordL(tagText "with") @@-- exprL xh) + | Expr.Op (TOp.TryFinally _, [_], [Expr.Lambda (_, _, _, [_], x1, _, _);Expr.Lambda (_, _, _, [_], x2, _, _)], _) -> + (wordL (tagText "try") @@-- exprL x1) @@ (wordL(tagText "finally") @@-- exprL x2) + | Expr.Op (TOp.Bytes _, _, _, _) -> + wordL(tagText "bytes++") + | Expr.Op (TOp.UInt16s _, _, _, _) -> wordL(tagText "uint16++") + | Expr.Op (TOp.RefAddrGet _, _tyargs, _args, _) -> wordL(tagText "GetRefLVal...") + | Expr.Op (TOp.TraitCall _, _tyargs, _args, _) -> wordL(tagText "traitcall...") + | Expr.Op (TOp.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...") + | Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...") + | Expr.Op (TOp.TryFinally _, _tyargs, _args, _) -> wordL(tagText "TOp.TryFinally...") + | Expr.Op (TOp.TryWith _, _tyargs, _args, _) -> wordL(tagText "TOp.TryWith...") + | Expr.Op (TOp.Goto l, _tys, args, _) -> wordL(tagText ("Expr.Goto " + string l)) ^^ bracketL (commaListL (List.map atomL args)) + | Expr.Op (TOp.Label l, _tys, args, _) -> wordL(tagText ("Expr.Label " + string l)) ^^ bracketL (commaListL (List.map atomL args)) + | Expr.Op (_, _tys, args, _) -> wordL(tagText "Expr.Op ...") ^^ bracketL (commaListL (List.map atomL args)) + | Expr.Quote (a, _, _, _, _) -> leftL(tagText "<@") ^^ atomL a ^^ rightL(tagText "@>") + | Expr.Obj (_lambdaId, ty, basev, ccall, overrides, iimpls, _) -> + (leftL (tagText "{") + @@-- + ((wordL(tagText "new ") ++ typeL ty) + @@-- + aboveListL [exprL ccall + optionL valAtBindL basev + aboveListL (List.map (tmethodL g) overrides) + aboveListL (List.map (iimplL g) iimpls)])) + @@ + rightL (tagText "}") + + | Expr.WitnessArg _ -> wordL (tagText "") + | Expr.StaticOptimization (_tcs, csx, x, _) -> + (wordL(tagText "opt") @@- (exprL x)) @@-- + (wordL(tagText "|") ^^ exprL csx --- (wordL(tagText "when...") )) + + // For tracking ranges through expr rewrites + if !layoutRanges + then leftL(tagText "{") ^^ (rangeL expr.Range ^^ rightL(tagText ":")) ++ lay ^^ rightL(tagText "}") + else lay + + and implFilesL g implFiles = + aboveListL (List.map (implFileL g) implFiles) + + and appL g flayout tys args = + let z = flayout + let z = if isNil tys then z else z ^^ instL typeL tys + let z = if isNil args then z else z --- spaceListL (List.map (atomL g) args) + z + + and implFileL g (TImplFile (_, _, mexpr, _, _, _)) = + aboveListL [(wordL(tagText "top implementation ")) @@-- mexprL g mexpr] + + and mexprL g x = + match x with + | ModuleOrNamespaceExprWithSig(mtyp, defs, _) -> mdefL g defs @@- (wordL(tagText ":") @@- entityTypeL g mtyp) + + and mdefsL g defs = + wordL(tagText "Module Defs") @@-- aboveListL(List.map (mdefL g) defs) + + and mdefL g x = + match x with + | TMDefRec(_, _, tycons, mbinds, _) -> aboveListL ((tycons |> List.map (tyconL g)) @ (mbinds |> List.map (mbindL g))) + | TMDefLet(bind, _) -> letL g bind emptyL + | TMDefDo(e, _) -> exprL g e + | TMDefOpens _ -> wordL (tagText "open ... ") + | TMDefs defs -> mdefsL g defs + | TMAbstract mexpr -> mexprL g mexpr + + and mbindL g x = + match x with + | ModuleOrNamespaceBinding.Binding bind -> letL g bind emptyL + | ModuleOrNamespaceBinding.Module(mspec, rhs) -> + (wordL (tagText (if mspec.IsNamespace then "namespace" else "module")) ^^ (wordL (tagText mspec.DemangledModuleOrNamespaceName) |> stampL mspec.Stamp)) @@-- mdefL g rhs + + and entityTypeL g (mtyp: ModuleOrNamespaceType) = + aboveListL [jlistL typeOfValL mtyp.AllValsAndMembers + jlistL (tyconL g) mtyp.AllEntities] + + and entityL g (ms: ModuleOrNamespace) = + let header = wordL(tagText "module") ^^ (wordL (tagText ms.DemangledModuleOrNamespaceName) |> stampL ms.Stamp) ^^ wordL(tagText ":") + let footer = wordL(tagText "end") + let body = entityTypeL g ms.ModuleOrNamespaceType + (header @@-- body) @@ footer + + and ccuL g (ccu: CcuThunk) = entityL g ccu.Contents + + and decisionTreeL g x = + match x with + | TDBind (bind, body) -> + let bind = wordL(tagText "let") ^^ bindingL g bind + (bind @@ decisionTreeL g body) + | TDSuccess (args, n) -> + wordL(tagText "Success") ^^ leftL(tagText "T") ^^ intL n ^^ tupleL (args |> List.map (exprL g)) + | TDSwitch (_, test, dcases, dflt, _) -> + (wordL(tagText "Switch") --- exprL g test) @@-- + (aboveListL (List.map (dcaseL g) dcases) @@ + match dflt with + | None -> emptyL + | Some dtree -> wordL(tagText "dflt:") --- decisionTreeL g dtree) + + and dcaseL g (TCase (test, dtree)) = (dtestL g test ^^ wordL(tagText "//")) --- decisionTreeL g dtree + + and dtestL g x = + match x with + | DecisionTreeTest.UnionCase (c, tinst) -> wordL(tagText "is") ^^ unionCaseRefL c ^^ instL typeL tinst + | DecisionTreeTest.ArrayLength (n, ty) -> wordL(tagText "length") ^^ intL n ^^ typeL ty + | DecisionTreeTest.Const c -> wordL(tagText "is") ^^ constL c + | DecisionTreeTest.IsNull -> wordL(tagText "isnull") + | DecisionTreeTest.IsInst (_, ty) -> wordL(tagText "isinst") ^^ typeL ty + | DecisionTreeTest.ActivePatternCase (exp, _, _, _, _, _) -> wordL(tagText "query") ^^ exprL g exp + | DecisionTreeTest.Error _ -> wordL (tagText "error recovery") + + and targetL g i (TTarget (argvs, body, _, _)) = + leftL(tagText "T") ^^ intL i ^^ tupleL (flatValsL argvs) ^^ rightL(tagText ":") --- exprL g body + + and flatValsL vs = vs |> List.map valL + + and tmethodL g (TObjExprMethod(TSlotSig(nm, _, _, _, _, _), _, tps, vs, e, _)) = + ((wordL(tagText "TObjExprMethod") --- (wordL (tagText nm)) ^^ wordL(tagText "=")) -- + (angleBracketListL (List.map typarL tps) ^^ rightL(tagText ".")) --- + (tupleL (List.map (List.map (valAtBindL g) >> tupleL) vs) ^^ rightL(tagText "."))) + @@-- + (atomL g e) + + and iimplL g (ty, tmeths) = wordL(tagText "impl") ^^ aboveListL (typeL ty :: List.map (tmethodL g) tmeths) + + let showType x = showL (typeL x) + + let showExpr g x = showL (exprL g x) + + let traitL x = auxTraitL SimplifyTypes.typeSimplificationInfo0 x + + let typarsL x = layoutTyparDecls x + +//-------------------------------------------------------------------------- +// Helpers related to type checking modules & namespaces +//-------------------------------------------------------------------------- + +let wrapModuleOrNamespaceType id cpath mtyp = + Construct.NewModuleOrNamespace (Some cpath) taccessPublic id XmlDoc.Empty [] (MaybeLazy.Strict mtyp) + +let wrapModuleOrNamespaceTypeInNamespace id cpath mtyp = + let mspec = wrapModuleOrNamespaceType id cpath mtyp + Construct.NewModuleOrNamespaceType Namespace [ mspec ] [], mspec + +let wrapModuleOrNamespaceExprInNamespace (id: Ident) cpath mexpr = + let mspec = wrapModuleOrNamespaceType id cpath (Construct.NewEmptyModuleOrNamespaceType Namespace) + TMDefRec (false, [], [], [ModuleOrNamespaceBinding.Module(mspec, mexpr)], id.idRange) + +// cleanup: make this a property +let SigTypeOfImplFile (TImplFile (_, _, mexpr, _, _, _)) = mexpr.Type + +//-------------------------------------------------------------------------- +// Data structures representing what gets hidden and what gets remapped (i.e. renamed or alpha-converted) +// when a module signature is applied to a module. +//-------------------------------------------------------------------------- + +type SignatureRepackageInfo = + { RepackagedVals: (ValRef * ValRef) list + RepackagedEntities: (TyconRef * TyconRef) list } + + member remapInfo.ImplToSigMapping = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } + static member Empty = { RepackagedVals = []; RepackagedEntities= [] } + +type SignatureHidingInfo = + { HiddenTycons: Zset + HiddenTyconReprs: Zset + HiddenVals: Zset + HiddenRecdFields: Zset + HiddenUnionCases: Zset } + + static member Empty = + { HiddenTycons = Zset.empty tyconOrder + HiddenTyconReprs = Zset.empty tyconOrder + HiddenVals = Zset.empty valOrder + HiddenRecdFields = Zset.empty recdFieldRefOrder + HiddenUnionCases = Zset.empty unionCaseRefOrder } + +let addValRemap v vNew tmenv = + { tmenv with valRemap= tmenv.valRemap.Add v (mkLocalValRef vNew) } + +let mkRepackageRemapping mrpi = + { valRemap = ValMap.OfList (mrpi.RepackagedVals |> List.map (fun (vref, x) -> vref.Deref, x)) + tpinst = emptyTyparInst + tyconRefRemap = TyconRefMap.OfList mrpi.RepackagedEntities + removeTraitSolutions = false } + +//-------------------------------------------------------------------------- +// Compute instances of the above for mty -> mty +//-------------------------------------------------------------------------- + +let accEntityRemap (msigty: ModuleOrNamespaceType) (entity: Entity) (mrpi, mhi) = + let sigtyconOpt = (NameMap.tryFind entity.LogicalName msigty.AllEntitiesByCompiledAndLogicalMangledNames) + match sigtyconOpt with + | None -> + // The type constructor is not present in the signature. Hence it is hidden. + let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } + (mrpi, mhi) + | Some sigtycon -> + // The type constructor is in the signature. Hence record the repackage entry + let sigtcref = mkLocalTyconRef sigtycon + let tcref = mkLocalTyconRef entity + let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } + // OK, now look for hidden things + let mhi = + if (match entity.TypeReprInfo with TNoRepr -> false | _ -> true) && (match sigtycon.TypeReprInfo with TNoRepr -> true | _ -> false) then + // The type representation is absent in the signature, hence it is hidden + { mhi with HiddenTyconReprs = Zset.add entity mhi.HiddenTyconReprs } + else + // The type representation is present in the signature. + // Find the fields that have been hidden or which were non-public anyway. + let mhi = + (entity.AllFieldsArray, mhi) ||> Array.foldBack (fun rfield mhi -> + match sigtycon.GetFieldByName(rfield.LogicalName) with + | Some _ -> + // The field is in the signature. Hence it is not hidden. + mhi + | _ -> + // The field is not in the signature. Hence it is regarded as hidden. + let rfref = tcref.MakeNestedRecdFieldRef rfield + { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields }) + + let mhi = + (entity.UnionCasesAsList, mhi) ||> List.foldBack (fun ucase mhi -> + match sigtycon.GetUnionCaseByName ucase.LogicalName with + | Some _ -> + // The constructor is in the signature. Hence it is not hidden. + mhi + | _ -> + // The constructor is not in the signature. Hence it is regarded as hidden. + let ucref = tcref.MakeNestedUnionCaseRef ucase + { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases }) + mhi + (mrpi, mhi) + +let accSubEntityRemap (msigty: ModuleOrNamespaceType) (entity: Entity) (mrpi, mhi) = + let sigtyconOpt = (NameMap.tryFind entity.LogicalName msigty.AllEntitiesByCompiledAndLogicalMangledNames) + match sigtyconOpt with + | None -> + // The type constructor is not present in the signature. Hence it is hidden. + let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } + (mrpi, mhi) + | Some sigtycon -> + // The type constructor is in the signature. Hence record the repackage entry + let sigtcref = mkLocalTyconRef sigtycon + let tcref = mkLocalTyconRef entity + let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } + (mrpi, mhi) + +let valLinkageAEquiv g aenv (v1: Val) (v2: Val) = + (v1.GetLinkagePartialKey() = v2.GetLinkagePartialKey()) && + (if v1.IsMember && v2.IsMember then typeAEquivAux EraseAll g aenv v1.Type v2.Type else true) + +let accValRemap g aenv (msigty: ModuleOrNamespaceType) (implVal: Val) (mrpi, mhi) = + let implValKey = implVal.GetLinkagePartialKey() + let sigValOpt = + msigty.AllValsAndMembersByPartialLinkageKey + |> MultiMap.find implValKey + |> List.tryFind (fun sigVal -> valLinkageAEquiv g aenv implVal sigVal) + + let vref = mkLocalValRef implVal + match sigValOpt with + | None -> + let mhi = { mhi with HiddenVals = Zset.add implVal mhi.HiddenVals } + (mrpi, mhi) + | Some (sigVal: Val) -> + // The value is in the signature. Add the repackage entry. + let mrpi = { mrpi with RepackagedVals = (vref, mkLocalValRef sigVal) :: mrpi.RepackagedVals } + (mrpi, mhi) + +let getCorrespondingSigTy nm (msigty: ModuleOrNamespaceType) = + match NameMap.tryFind nm msigty.AllEntitiesByCompiledAndLogicalMangledNames with + | None -> Construct.NewEmptyModuleOrNamespaceType ModuleOrType + | Some sigsubmodul -> sigsubmodul.ModuleOrNamespaceType + +let rec accEntityRemapFromModuleOrNamespaceType (mty: ModuleOrNamespaceType) (msigty: ModuleOrNamespaceType) acc = + let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (fun e acc -> accEntityRemapFromModuleOrNamespaceType e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) + let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (accEntityRemap msigty) + acc + +let rec accValRemapFromModuleOrNamespaceType g aenv (mty: ModuleOrNamespaceType) msigty acc = + let acc = (mty.AllEntities, acc) ||> QueueList.foldBack (fun e acc -> accValRemapFromModuleOrNamespaceType g aenv e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) + let acc = (mty.AllValsAndMembers, acc) ||> QueueList.foldBack (accValRemap g aenv msigty) + acc + +let ComputeRemappingFromInferredSignatureToExplicitSignature g mty msigty = + let mrpi, _ as entityRemap = accEntityRemapFromModuleOrNamespaceType mty msigty (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) + let aenv = mrpi.ImplToSigMapping + let valAndEntityRemap = accValRemapFromModuleOrNamespaceType g aenv mty msigty entityRemap + valAndEntityRemap + +//-------------------------------------------------------------------------- +// Compute instances of the above for mexpr -> mty +//-------------------------------------------------------------------------- + +/// At TMDefRec nodes abstract (virtual) vslots are effectively binders, even +/// though they are tucked away inside the tycon. This helper function extracts the +/// virtual slots to aid with finding this babies. +let abstractSlotValRefsOfTycons (tycons: Tycon list) = + tycons + |> List.collect (fun tycon -> if tycon.IsFSharpObjectModelTycon then tycon.FSharpObjectModelTypeInfo.fsobjmodel_vslots else []) + +let abstractSlotValsOfTycons (tycons: Tycon list) = + abstractSlotValRefsOfTycons tycons + |> List.map (fun v -> v.Deref) + +let rec accEntityRemapFromModuleOrNamespace msigty x acc = + match x with + | TMDefRec(_, _, tycons, mbinds, _) -> + let acc = (mbinds, acc) ||> List.foldBack (accEntityRemapFromModuleOrNamespaceBind msigty) + let acc = (tycons, acc) ||> List.foldBack (accEntityRemap msigty) + let acc = (tycons, acc) ||> List.foldBack (fun e acc -> accEntityRemapFromModuleOrNamespaceType e.ModuleOrNamespaceType (getCorrespondingSigTy e.LogicalName msigty) acc) + acc + | TMDefLet _ -> acc + | TMDefOpens _ -> acc + | TMDefDo _ -> acc + | TMDefs defs -> accEntityRemapFromModuleOrNamespaceDefs msigty defs acc + | TMAbstract mexpr -> accEntityRemapFromModuleOrNamespaceType mexpr.Type msigty acc + +and accEntityRemapFromModuleOrNamespaceDefs msigty mdefs acc = + List.foldBack (accEntityRemapFromModuleOrNamespace msigty) mdefs acc + +and accEntityRemapFromModuleOrNamespaceBind msigty x acc = + match x with + | ModuleOrNamespaceBinding.Binding _ -> acc + | ModuleOrNamespaceBinding.Module(mspec, def) -> + accSubEntityRemap msigty mspec (accEntityRemapFromModuleOrNamespace (getCorrespondingSigTy mspec.LogicalName msigty) def acc) + +let rec accValRemapFromModuleOrNamespace g aenv msigty x acc = + match x with + | TMDefRec(_, _, tycons, mbinds, _) -> + let acc = (mbinds, acc) ||> List.foldBack (accValRemapFromModuleOrNamespaceBind g aenv msigty) + // Abstract (virtual) vslots in the tycons at TMDefRec nodes are binders. They also need to be added to the remapping. + let vslotvs = abstractSlotValsOfTycons tycons + let acc = (vslotvs, acc) ||> List.foldBack (accValRemap g aenv msigty) + acc + | TMDefLet(bind, _) -> accValRemap g aenv msigty bind.Var acc + | TMDefOpens _ -> acc + | TMDefDo _ -> acc + | TMDefs defs -> accValRemapFromModuleOrNamespaceDefs g aenv msigty defs acc + | TMAbstract mexpr -> accValRemapFromModuleOrNamespaceType g aenv mexpr.Type msigty acc + +and accValRemapFromModuleOrNamespaceBind g aenv msigty x acc = + match x with + | ModuleOrNamespaceBinding.Binding bind -> accValRemap g aenv msigty bind.Var acc + | ModuleOrNamespaceBinding.Module(mspec, def) -> + accSubEntityRemap msigty mspec (accValRemapFromModuleOrNamespace g aenv (getCorrespondingSigTy mspec.LogicalName msigty) def acc) + +and accValRemapFromModuleOrNamespaceDefs g aenv msigty mdefs acc = List.foldBack (accValRemapFromModuleOrNamespace g aenv msigty) mdefs acc + +let ComputeRemappingFromImplementationToSignature g mdef msigty = + let mrpi, _ as entityRemap = accEntityRemapFromModuleOrNamespace msigty mdef (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) + let aenv = mrpi.ImplToSigMapping + + let valAndEntityRemap = accValRemapFromModuleOrNamespace g aenv msigty mdef entityRemap + valAndEntityRemap + +//-------------------------------------------------------------------------- +// Compute instances of the above for the assembly boundary +//-------------------------------------------------------------------------- + +let accTyconHidingInfoAtAssemblyBoundary (tycon: Tycon) mhi = + if not (canAccessFromEverywhere tycon.Accessibility) then + // The type constructor is not public, hence hidden at the assembly boundary. + { mhi with HiddenTycons = Zset.add tycon mhi.HiddenTycons } + elif not (canAccessFromEverywhere tycon.TypeReprAccessibility) then + { mhi with HiddenTyconReprs = Zset.add tycon mhi.HiddenTyconReprs } + else + let mhi = + (tycon.AllFieldsArray, mhi) ||> Array.foldBack (fun rfield mhi -> + if not (canAccessFromEverywhere rfield.Accessibility) then + let tcref = mkLocalTyconRef tycon + let rfref = tcref.MakeNestedRecdFieldRef rfield + { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields } + else mhi) + let mhi = + (tycon.UnionCasesAsList, mhi) ||> List.foldBack (fun ucase mhi -> + if not (canAccessFromEverywhere ucase.Accessibility) then + let tcref = mkLocalTyconRef tycon + let ucref = tcref.MakeNestedUnionCaseRef ucase + { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases } + else mhi) + mhi + +// Collect up the values hidden at the assembly boundary. This is used by IsHiddenVal to +// determine if something is considered hidden. This is used in turn to eliminate optimization +// information at the assembly boundary and to decide to label things as "internal". +let accValHidingInfoAtAssemblyBoundary (vspec: Val) mhi = + if // anything labelled "internal" or more restrictive is considered to be hidden at the assembly boundary + not (canAccessFromEverywhere vspec.Accessibility) || + // compiler generated members for class function 'let' bindings are considered to be hidden at the assembly boundary + vspec.IsIncrClassGeneratedMember || + // anything that's not a module or member binding gets assembly visibility + not vspec.IsMemberOrModuleBinding then + // The value is not public, hence hidden at the assembly boundary. + { mhi with HiddenVals = Zset.add vspec mhi.HiddenVals } + else + mhi + +let rec accModuleOrNamespaceHidingInfoAtAssemblyBoundary mty acc = + let acc = QueueList.foldBack (fun (e: Entity) acc -> accModuleOrNamespaceHidingInfoAtAssemblyBoundary e.ModuleOrNamespaceType acc) mty.AllEntities acc + let acc = QueueList.foldBack accTyconHidingInfoAtAssemblyBoundary mty.AllEntities acc + let acc = QueueList.foldBack accValHidingInfoAtAssemblyBoundary mty.AllValsAndMembers acc + acc + +let ComputeHidingInfoAtAssemblyBoundary mty acc = + accModuleOrNamespaceHidingInfoAtAssemblyBoundary mty acc + +//-------------------------------------------------------------------------- +// Compute instances of the above for mexpr -> mty +//-------------------------------------------------------------------------- + +let IsHidden setF accessF remapF = + let rec check mrmi x = + // Internal/private? + not (canAccessFromEverywhere (accessF x)) || + (match mrmi with + | [] -> false // Ah! we escaped to freedom! + | (rpi, mhi) :: rest -> + // Explicitly hidden? + Zset.contains x (setF mhi) || + // Recurse... + check rest (remapF rpi x)) + fun mrmi x -> + check mrmi x + +let IsHiddenTycon mrmi x = IsHidden (fun mhi -> mhi.HiddenTycons) (fun tc -> tc.Accessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) mrmi x + +let IsHiddenTyconRepr mrmi x = IsHidden (fun mhi -> mhi.HiddenTyconReprs) (fun v -> v.TypeReprAccessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) mrmi x + +let IsHiddenVal mrmi x = IsHidden (fun mhi -> mhi.HiddenVals) (fun v -> v.Accessibility) (fun rpi x -> (remapValRef rpi (mkLocalValRef x)).Deref) mrmi x + +let IsHiddenRecdField mrmi x = IsHidden (fun mhi -> mhi.HiddenRecdFields) (fun rfref -> rfref.RecdField.Accessibility) (fun rpi x -> remapRecdFieldRef rpi.tyconRefRemap x) mrmi x + +//-------------------------------------------------------------------------- +// Generic operations on module types +//-------------------------------------------------------------------------- + +let foldModuleOrNamespaceTy ft fv mty acc = + let rec go mty acc = + let acc = QueueList.foldBack (fun (e: Entity) acc -> go e.ModuleOrNamespaceType acc) mty.AllEntities acc + let acc = QueueList.foldBack ft mty.AllEntities acc + let acc = QueueList.foldBack fv mty.AllValsAndMembers acc + acc + go mty acc + +let allValsOfModuleOrNamespaceTy m = foldModuleOrNamespaceTy (fun _ acc -> acc) (fun v acc -> v :: acc) m [] +let allEntitiesOfModuleOrNamespaceTy m = foldModuleOrNamespaceTy (fun ft acc -> ft :: acc) (fun _ acc -> acc) m [] + +//--------------------------------------------------------------------------- +// Free variables in terms. Are all constructs public accessible? +//--------------------------------------------------------------------------- + +let isPublicVal (lv: Val) = (lv.Accessibility = taccessPublic) +let isPublicUnionCase (ucr: UnionCaseRef) = (ucr.UnionCase.Accessibility = taccessPublic) +let isPublicRecdField (rfr: RecdFieldRef) = (rfr.RecdField.Accessibility = taccessPublic) +let isPublicTycon (tcref: Tycon) = (tcref.Accessibility = taccessPublic) + +let freeVarsAllPublic fvs = + // Are any non-public items used in the expr (which corresponded to the fvs)? + // Recall, taccess occurs in: + // EntityData has ReprAccessibility and Accessibility + // UnionCase has Accessibility + // RecdField has Accessibility + // ValData has Accessibility + // The freevars and FreeTyvars collect local constructs. + // Here, we test that all those constructs are public. + // + // CODE REVIEW: + // What about non-local vals. This fix assumes non-local vals must be public. OK? + Zset.forall isPublicVal fvs.FreeLocals && + Zset.forall isPublicUnionCase fvs.FreeUnionCases && + Zset.forall isPublicRecdField fvs.FreeRecdFields && + Zset.forall isPublicTycon fvs.FreeTyvars.FreeTycons + +let freeTyvarsAllPublic tyvars = + Zset.forall isPublicTycon tyvars.FreeTycons + +/// Detect the subset of match expressions we process in a linear way (i.e. using tailcalls, rather than +/// unbounded stack) +/// -- if then else +/// -- match e with pat[vs] -> e1[vs] | _ -> e2 + +let (|LinearMatchExpr|_|) expr = + match expr with + | Expr.Match (sp, m, dtree, [|tg1;(TTarget([], e2, sp2, _))|], m2, ty) -> Some(sp, m, dtree, tg1, e2, sp2, m2, ty) + | _ -> None + +let rebuildLinearMatchExpr (sp, m, dtree, tg1, e2, sp2, m2, ty) = + primMkMatch (sp, m, dtree, [|tg1;(TTarget([], e2, sp2, None))|], m2, ty) + +/// Detect a subset of 'Expr.Op' expressions we process in a linear way (i.e. using tailcalls, rather than +/// unbounded stack). Only covers Cons(args,Cons(args,Cons(args,Cons(args,...._)))). +let (|LinearOpExpr|_|) expr = + match expr with + | Expr.Op (TOp.UnionCase _ as op, tinst, args, m) when not args.IsEmpty -> + let argsFront, argLast = List.frontAndBack args + Some (op, tinst, argsFront, argLast, m) + | _ -> None + +let rebuildLinearOpExpr (op, tinst, argsFront, argLast, m) = + Expr.Op (op, tinst, argsFront@[argLast], m) + +//--------------------------------------------------------------------------- +// Free variables in terms. All binders are distinct. +//--------------------------------------------------------------------------- + +let emptyFreeVars = + { UsesMethodLocalConstructs=false + UsesUnboundRethrow=false + FreeLocalTyconReprs=emptyFreeTycons + FreeLocals=emptyFreeLocals + FreeTyvars=emptyFreeTyvars + FreeRecdFields = emptyFreeRecdFields + FreeUnionCases = emptyFreeUnionCases} + +let unionFreeVars fvs1 fvs2 = + if fvs1 === emptyFreeVars then fvs2 else + if fvs2 === emptyFreeVars then fvs1 else + { FreeLocals = unionFreeLocals fvs1.FreeLocals fvs2.FreeLocals + FreeTyvars = unionFreeTyvars fvs1.FreeTyvars fvs2.FreeTyvars + UsesMethodLocalConstructs = fvs1.UsesMethodLocalConstructs || fvs2.UsesMethodLocalConstructs + UsesUnboundRethrow = fvs1.UsesUnboundRethrow || fvs2.UsesUnboundRethrow + FreeLocalTyconReprs = unionFreeTycons fvs1.FreeLocalTyconReprs fvs2.FreeLocalTyconReprs + FreeRecdFields = unionFreeRecdFields fvs1.FreeRecdFields fvs2.FreeRecdFields + FreeUnionCases = unionFreeUnionCases fvs1.FreeUnionCases fvs2.FreeUnionCases } + +let inline accFreeTyvars (opts: FreeVarOptions) f v acc = + if not opts.collectInTypes then acc else + let ftyvs = acc.FreeTyvars + let ftyvs' = f opts v ftyvs + if ftyvs === ftyvs' then acc else + { acc with FreeTyvars = ftyvs' } + +let accFreeVarsInTy opts ty acc = accFreeTyvars opts accFreeInType ty acc +let accFreeVarsInTys opts tys acc = if isNil tys then acc else accFreeTyvars opts accFreeInTypes tys acc +let accFreevarsInTycon opts tcref acc = accFreeTyvars opts accFreeTycon tcref acc +let accFreevarsInVal opts v acc = accFreeTyvars opts accFreeInVal v acc + +let accFreeVarsInTraitSln opts tys acc = accFreeTyvars opts accFreeInTraitSln tys acc + +let accFreeVarsInTraitInfo opts tys acc = accFreeTyvars opts accFreeInTrait tys acc + +let boundLocalVal opts v fvs = + if not opts.includeLocals then fvs else + let fvs = accFreevarsInVal opts v fvs + if not (Zset.contains v fvs.FreeLocals) then fvs + else {fvs with FreeLocals= Zset.remove v fvs.FreeLocals} + +let boundProtect fvs = + if fvs.UsesMethodLocalConstructs then {fvs with UsesMethodLocalConstructs = false} else fvs + +let accUsesFunctionLocalConstructs flg fvs = + if flg && not fvs.UsesMethodLocalConstructs then {fvs with UsesMethodLocalConstructs = true} + else fvs + +let bound_rethrow fvs = + if fvs.UsesUnboundRethrow then {fvs with UsesUnboundRethrow = false} else fvs + +let accUsesRethrow flg fvs = + if flg && not fvs.UsesUnboundRethrow then {fvs with UsesUnboundRethrow = true} + else fvs + +let boundLocalVals opts vs fvs = List.foldBack (boundLocalVal opts) vs fvs + +let bindLhs opts (bind: Binding) fvs = boundLocalVal opts bind.Var fvs + +let freeVarsCacheCompute opts cache f = if opts.canCache then cached cache f else f() + +let tryGetFreeVarsCacheValue opts cache = + if opts.canCache then tryGetCacheValue cache + else ValueNone + +let rec accBindRhs opts (TBind(_, repr, _)) acc = accFreeInExpr opts repr acc + +and accFreeInSwitchCases opts csl dflt (acc: FreeVars) = + Option.foldBack (accFreeInDecisionTree opts) dflt (List.foldBack (accFreeInSwitchCase opts) csl acc) + +and accFreeInSwitchCase opts (TCase(discrim, dtree)) acc = + accFreeInDecisionTree opts dtree (accFreeInTest opts discrim acc) + +and accFreeInTest (opts: FreeVarOptions) discrim acc = + match discrim with + | DecisionTreeTest.UnionCase(ucref, tinst) -> accFreeUnionCaseRef opts ucref (accFreeVarsInTys opts tinst acc) + | DecisionTreeTest.ArrayLength(_, ty) -> accFreeVarsInTy opts ty acc + | DecisionTreeTest.Const _ + | DecisionTreeTest.IsNull -> acc + | DecisionTreeTest.IsInst (srcty, tgty) -> accFreeVarsInTy opts srcty (accFreeVarsInTy opts tgty acc) + | DecisionTreeTest.ActivePatternCase (exp, tys, _, activePatIdentity, _, _) -> + accFreeInExpr opts exp + (accFreeVarsInTys opts tys + (Option.foldBack (fun (vref, tinst) acc -> accFreeValRef opts vref (accFreeVarsInTys opts tinst acc)) activePatIdentity acc)) + | DecisionTreeTest.Error _ -> acc + +and accFreeInDecisionTree opts x (acc: FreeVars) = + match x with + | TDSwitch(_, e1, csl, dflt, _) -> accFreeInExpr opts e1 (accFreeInSwitchCases opts csl dflt acc) + | TDSuccess (es, _) -> accFreeInFlatExprs opts es acc + | TDBind (bind, body) -> unionFreeVars (bindLhs opts bind (accBindRhs opts bind (freeInDecisionTree opts body))) acc + +and accFreeInValFlags opts flag acc = + let isMethLocal = + match flag with + | VSlotDirectCall + | CtorValUsedAsSelfInit + | CtorValUsedAsSuperInit -> true + | PossibleConstrainedCall _ + | NormalValUse -> false + let acc = accUsesFunctionLocalConstructs isMethLocal acc + match flag with + | PossibleConstrainedCall ty -> accFreeTyvars opts accFreeInType ty acc + | _ -> acc + +and accFreeLocalVal opts v fvs = + if not opts.includeLocals then fvs else + if Zset.contains v fvs.FreeLocals then fvs + else + let fvs = accFreevarsInVal opts v fvs + {fvs with FreeLocals=Zset.add v fvs.FreeLocals} + +and accLocalTyconRepr opts b fvs = + if not opts.includeLocalTyconReprs then fvs else + if Zset.contains b fvs.FreeLocalTyconReprs then fvs + else { fvs with FreeLocalTyconReprs = Zset.add b fvs.FreeLocalTyconReprs } + +and accUsedRecdOrUnionTyconRepr opts (tc: Tycon) fvs = + if match tc.TypeReprInfo with TFSharpObjectRepr _ | TFSharpRecdRepr _ | TFSharpUnionRepr _ -> true | _ -> false + then accLocalTyconRepr opts tc fvs + else fvs + +and accFreeUnionCaseRef opts ucref fvs = + if not opts.includeUnionCases then fvs else + if Zset.contains ucref fvs.FreeUnionCases then fvs + else + let fvs = fvs |> accUsedRecdOrUnionTyconRepr opts ucref.Tycon + let fvs = fvs |> accFreevarsInTycon opts ucref.TyconRef + { fvs with FreeUnionCases = Zset.add ucref fvs.FreeUnionCases } + +and accFreeRecdFieldRef opts rfref fvs = + if not opts.includeRecdFields then fvs else + if Zset.contains rfref fvs.FreeRecdFields then fvs + else + let fvs = fvs |> accUsedRecdOrUnionTyconRepr opts rfref.Tycon + let fvs = fvs |> accFreevarsInTycon opts rfref.TyconRef + { fvs with FreeRecdFields = Zset.add rfref fvs.FreeRecdFields } + +and accFreeExnRef _exnc fvs = fvs // Note: this exnc (TyconRef) should be collected the surround types, e.g. tinst of Expr.Op +and accFreeValRef opts (vref: ValRef) fvs = + match vref.IsLocalRef with + | true -> accFreeLocalVal opts vref.ResolvedTarget fvs + // non-local values do not contain free variables + | _ -> fvs + +and accFreeInMethod opts (TObjExprMethod(slotsig, _attribs, tps, tmvs, e, _)) acc = + accFreeInSlotSig opts slotsig + (unionFreeVars (accFreeTyvars opts boundTypars tps (List.foldBack (boundLocalVals opts) tmvs (freeInExpr opts e))) acc) + +and accFreeInMethods opts methods acc = + List.foldBack (accFreeInMethod opts) methods acc + +and accFreeInInterfaceImpl opts (ty, overrides) acc = + accFreeVarsInTy opts ty (accFreeInMethods opts overrides acc) + +and accFreeInExpr (opts: FreeVarOptions) x acc = + match x with + | Expr.Let _ -> accFreeInExprLinear opts x acc (fun e -> e) + | _ -> accFreeInExprNonLinear opts x acc + +and accFreeInExprLinear (opts: FreeVarOptions) x acc contf = + // for nested let-bindings, we need to continue after the whole let-binding is processed + match x with + | Expr.Let (bind, e, _, cache) -> + match tryGetFreeVarsCacheValue opts cache with + | ValueSome free -> contf (unionFreeVars free acc) + | _ -> + accFreeInExprLinear opts e emptyFreeVars (contf << (fun free -> + unionFreeVars (freeVarsCacheCompute opts cache (fun () -> bindLhs opts bind (accBindRhs opts bind free))) acc + )) + | _ -> + // No longer linear expr + contf (accFreeInExpr opts x acc) + +and accFreeInExprNonLinear opts x acc = + match x with + + // BINDING CONSTRUCTS + | Expr.Lambda (_, ctorThisValOpt, baseValOpt, vs, bodyExpr, _, rty) -> + unionFreeVars + (Option.foldBack (boundLocalVal opts) ctorThisValOpt + (Option.foldBack (boundLocalVal opts) baseValOpt + (boundLocalVals opts vs + (accFreeVarsInTy opts rty + (freeInExpr opts bodyExpr))))) + acc + + | Expr.TyLambda (_, vs, bodyExpr, _, rty) -> + unionFreeVars (accFreeTyvars opts boundTypars vs (accFreeVarsInTy opts rty (freeInExpr opts bodyExpr))) acc + + | Expr.TyChoose (vs, bodyExpr, _) -> + unionFreeVars (accFreeTyvars opts boundTypars vs (freeInExpr opts bodyExpr)) acc + + | Expr.LetRec (binds, bodyExpr, _, cache) -> + unionFreeVars (freeVarsCacheCompute opts cache (fun () -> List.foldBack (bindLhs opts) binds (List.foldBack (accBindRhs opts) binds (freeInExpr opts bodyExpr)))) acc + + | Expr.Let _ -> + failwith "unreachable - linear expr" + + | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, _) -> + unionFreeVars + (boundProtect + (Option.foldBack (boundLocalVal opts) basev + (accFreeVarsInTy opts ty + (accFreeInExpr opts basecall + (accFreeInMethods opts overrides + (List.foldBack (accFreeInInterfaceImpl opts) iimpls emptyFreeVars)))))) + acc + + // NON-BINDING CONSTRUCTS + | Expr.Const _ -> acc + + | Expr.Val (lvr, flags, _) -> + accFreeInValFlags opts flags (accFreeValRef opts lvr acc) + + | Expr.Quote (ast, dataCell, _, _, ty) -> + match dataCell.Value with + | Some (_, (_, argTypes, argExprs, _data)) -> + accFreeInExpr opts ast + (accFreeInExprs opts argExprs + (accFreeVarsInTys opts argTypes + (accFreeVarsInTy opts ty acc))) + + | None -> + accFreeInExpr opts ast (accFreeVarsInTy opts ty acc) + + | Expr.App (f0, f0ty, tyargs, args, _) -> + accFreeVarsInTy opts f0ty + (accFreeInExpr opts f0 + (accFreeVarsInTys opts tyargs + (accFreeInExprs opts args acc))) + + | Expr.Link eref -> accFreeInExpr opts !eref acc + + | Expr.Sequential (expr1, expr2, _, _, _) -> + let acc = accFreeInExpr opts expr1 acc + // tail-call - linear expression + accFreeInExpr opts expr2 acc + + | Expr.StaticOptimization (_, expr2, expr3, _) -> + accFreeInExpr opts expr2 (accFreeInExpr opts expr3 acc) + + | Expr.Match (_, _, dtree, targets, _, _) -> + match x with + // Handle if-then-else + | LinearMatchExpr(_, _, dtree, target, bodyExpr, _, _, _) -> + let acc = accFreeInDecisionTree opts dtree acc + let acc = accFreeInTarget opts target acc + accFreeInExpr opts bodyExpr acc // tailcall + + | _ -> + let acc = accFreeInDecisionTree opts dtree acc + accFreeInTargets opts targets acc + + | Expr.Op (TOp.TryWith _, tinst, [expr1; expr2; expr3], _) -> + unionFreeVars + (accFreeVarsInTys opts tinst + (accFreeInExprs opts [expr1; expr2] acc)) + (bound_rethrow (accFreeInExpr opts expr3 emptyFreeVars)) + + | Expr.Op (op, tinst, args, _) -> + let acc = accFreeInOp opts op acc + let acc = accFreeVarsInTys opts tinst acc + accFreeInExprs opts args acc + + | Expr.WitnessArg (traitInfo, _) -> + accFreeVarsInTraitInfo opts traitInfo acc + +and accFreeInOp opts op acc = + match op with + + // Things containing no references + | TOp.Bytes _ + | TOp.UInt16s _ + | TOp.TryWith _ + | TOp.TryFinally _ + | TOp.For _ + | TOp.Coerce + | TOp.RefAddrGet _ + | TOp.Array + | TOp.While _ + | TOp.Goto _ | TOp.Label _ | TOp.Return + | TOp.TupleFieldGet _ -> acc + + | TOp.Tuple tupInfo -> + accFreeTyvars opts accFreeInTupInfo tupInfo acc + + | TOp.AnonRecd anonInfo + | TOp.AnonRecdGet (anonInfo, _) -> + accFreeTyvars opts accFreeInTupInfo anonInfo.TupInfo acc + + | TOp.UnionCaseTagGet tcref -> + accUsedRecdOrUnionTyconRepr opts tcref.Deref acc + + // Things containing just a union case reference + | TOp.UnionCaseProof ucref + | TOp.UnionCase ucref + | TOp.UnionCaseFieldGetAddr (ucref, _, _) + | TOp.UnionCaseFieldGet (ucref, _) + | TOp.UnionCaseFieldSet (ucref, _) -> + accFreeUnionCaseRef opts ucref acc + + // Things containing just an exception reference + | TOp.ExnConstr ecref + | TOp.ExnFieldGet (ecref, _) + | TOp.ExnFieldSet (ecref, _) -> + accFreeExnRef ecref acc + + | TOp.ValFieldGet fref + | TOp.ValFieldGetAddr (fref, _) + | TOp.ValFieldSet fref -> + accFreeRecdFieldRef opts fref acc + + | TOp.Recd (kind, tcref) -> + let acc = accUsesFunctionLocalConstructs (kind = RecdExprIsObjInit) acc + (accUsedRecdOrUnionTyconRepr opts tcref.Deref (accFreeTyvars opts accFreeTycon tcref acc)) + + | TOp.ILAsm (_, retTypes) -> + accFreeVarsInTys opts retTypes acc + + | TOp.Reraise -> + accUsesRethrow true acc + + | TOp.TraitCall (TTrait(tys, _, _, argtys, rty, sln)) -> + Option.foldBack (accFreeVarsInTraitSln opts) sln.Value + (accFreeVarsInTys opts tys + (accFreeVarsInTys opts argtys + (Option.foldBack (accFreeVarsInTy opts) rty acc))) + + | TOp.LValueOp (_, vref) -> + accFreeValRef opts vref acc + + | TOp.ILCall (_, isProtected, _, _, valUseFlag, _, _, _, enclTypeInst, methInst, retTypes) -> + accFreeVarsInTys opts enclTypeInst + (accFreeVarsInTys opts methInst + (accFreeInValFlags opts valUseFlag + (accFreeVarsInTys opts retTypes + (accUsesFunctionLocalConstructs isProtected acc)))) + +and accFreeInTargets opts targets acc = + Array.foldBack (accFreeInTarget opts) targets acc + +and accFreeInTarget opts (TTarget(vs, expr, _, flags)) acc = + match flags with + | None -> List.foldBack (boundLocalVal opts) vs (accFreeInExpr opts expr acc) + | Some xs -> List.foldBack2 (fun v isStateVar acc -> if isStateVar then acc else boundLocalVal opts v acc) vs xs (accFreeInExpr opts expr acc) + +and accFreeInFlatExprs opts (exprs: Exprs) acc = List.foldBack (accFreeInExpr opts) exprs acc + +and accFreeInExprs opts (exprs: Exprs) acc = + match exprs with + | [] -> acc + | [h]-> + // tailcall - e.g. Cons(x, Cons(x2, .......Cons(x1000000, Nil))) and [| x1; .... ; x1000000 |] + accFreeInExpr opts h acc + | h :: t -> + let acc = accFreeInExpr opts h acc + accFreeInExprs opts t acc + +and accFreeInSlotSig opts (TSlotSig(_, ty, _, _, _, _)) acc = + accFreeVarsInTy opts ty acc + +and freeInDecisionTree opts dtree = + accFreeInDecisionTree opts dtree emptyFreeVars + +and freeInExpr opts expr = + accFreeInExpr opts expr emptyFreeVars + +// Note: these are only an approximation - they are currently used only by the optimizer +let rec accFreeInModuleOrNamespace opts mexpr acc = + match mexpr with + | TMDefRec(_, _, _, mbinds, _) -> List.foldBack (accFreeInModuleOrNamespaceBind opts) mbinds acc + | TMDefLet(bind, _) -> accBindRhs opts bind acc + | TMDefDo(e, _) -> accFreeInExpr opts e acc + | TMDefOpens _ -> acc + | TMDefs defs -> accFreeInModuleOrNamespaces opts defs acc + | TMAbstract(ModuleOrNamespaceExprWithSig(_, mdef, _)) -> accFreeInModuleOrNamespace opts mdef acc // not really right, but sufficient for how this is used in optimization + +and accFreeInModuleOrNamespaceBind opts mbind acc = + match mbind with + | ModuleOrNamespaceBinding.Binding bind -> accBindRhs opts bind acc + | ModuleOrNamespaceBinding.Module (_, def) -> accFreeInModuleOrNamespace opts def acc + +and accFreeInModuleOrNamespaces opts mexprs acc = + List.foldBack (accFreeInModuleOrNamespace opts) mexprs acc + +let freeInBindingRhs opts bind = + accBindRhs opts bind emptyFreeVars + +let freeInModuleOrNamespace opts mdef = + accFreeInModuleOrNamespace opts mdef emptyFreeVars + +//--------------------------------------------------------------------------- +// Destruct - rarely needed +//--------------------------------------------------------------------------- + +let rec stripLambda (expr, ty) = + match expr with + | Expr.Lambda (_, ctorThisValOpt, baseValOpt, v, bodyExpr, _, rty) -> + if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", expr.Range)) + if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", expr.Range)) + let vs', bodyExpr', rty' = stripLambda (bodyExpr, rty) + (v :: vs', bodyExpr', rty') + | _ -> ([], expr, ty) + +let rec stripLambdaN n expr = + assert (n >= 0) + match expr with + | Expr.Lambda (_, ctorThisValOpt, baseValOpt, v, bodyExpr, _, _) when n > 0 -> + if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", expr.Range)) + if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", expr.Range)) + let vs, bodyExpr', remaining = stripLambdaN (n-1) bodyExpr + (v :: vs, bodyExpr', remaining) + | _ -> ([], expr, n) + +let tryStripLambdaN n expr = + match expr with + | Expr.Lambda (_, None, None, _, _, _, _) -> + let argvsl, bodyExpr, remaining = stripLambdaN n expr + if remaining = 0 then Some (argvsl, bodyExpr) + else None + | _ -> None + +let stripTopLambda (expr, ty) = + let tps, taue, tauty = match expr with Expr.TyLambda (_, tps, b, _, rty) -> tps, b, rty | _ -> [], expr, ty + let vs, body, rty = stripLambda (taue, tauty) + tps, vs, body, rty + +[] +type AllowTypeDirectedDetupling = Yes | No + +// This is used to infer arities of expressions +// i.e. base the chosen arity on the syntactic expression shape and type of arguments +let InferArityOfExpr g allowTypeDirectedDetupling ty partialArgAttribsL retAttribs expr = + let rec stripLambda_notypes e = + match e with + | Expr.Lambda (_, _, _, vs, b, _, _) -> + let vs', b' = stripLambda_notypes b + (vs :: vs', b') + | Expr.TyChoose (_, b, _) -> stripLambda_notypes b + | _ -> ([], e) + + let stripTopLambdaNoTypes e = + let tps, taue = match e with Expr.TyLambda (_, tps, b, _, _) -> tps, b | _ -> [], e + let vs, body = stripLambda_notypes taue + tps, vs, body + + let tps, vsl, _ = stripTopLambdaNoTypes expr + let fun_arity = vsl.Length + let dtys, _ = stripFunTyN g fun_arity (snd (tryDestForallTy g ty)) + let partialArgAttribsL = Array.ofList partialArgAttribsL + assert (List.length vsl = List.length dtys) + + let curriedArgInfos = + (vsl, dtys) ||> List.mapi2 (fun i vs ty -> + let partialAttribs = if i < partialArgAttribsL.Length then partialArgAttribsL.[i] else [] + let tys = + match allowTypeDirectedDetupling with + | AllowTypeDirectedDetupling.No -> [ty] + | AllowTypeDirectedDetupling.Yes -> + if (i = 0 && isUnitTy g ty) then [] + else tryDestRefTupleTy g ty + let ids = + if vs.Length = tys.Length then vs |> List.map (fun v -> Some v.Id) + else tys |> List.map (fun _ -> None) + let attribs = + if partialAttribs.Length = tys.Length then partialAttribs + else tys |> List.map (fun _ -> []) + (ids, attribs) ||> List.map2 (fun id attribs -> { Name = id; Attribs = attribs }: ArgReprInfo )) + let retInfo: ArgReprInfo = { Attribs = retAttribs; Name = None } + ValReprInfo (ValReprInfo.InferTyparInfo tps, curriedArgInfos, retInfo) + +let InferArityOfExprBinding g allowTypeDirectedDetupling (v: Val) expr = + match v.ValReprInfo with + | Some info -> info + | None -> InferArityOfExpr g allowTypeDirectedDetupling v.Type [] [] expr + +//------------------------------------------------------------------------- +// Check if constraints are satisfied that allow us to use more optimized +// implementations +//------------------------------------------------------------------------- + +let underlyingTypeOfEnumTy (g: TcGlobals) ty = + assert(isEnumTy g ty) + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> info.UnderlyingTypeOfEnum() +#endif + | ILTypeMetadata (TILObjectReprData(_, _, tdef)) -> + + let info = computeILEnumInfo (tdef.Name, tdef.Fields) + let ilTy = getTyOfILEnumInfo info + match ilTy.TypeSpec.Name with + | "System.Byte" -> g.byte_ty + | "System.SByte" -> g.sbyte_ty + | "System.Int16" -> g.int16_ty + | "System.Int32" -> g.int32_ty + | "System.Int64" -> g.int64_ty + | "System.UInt16" -> g.uint16_ty + | "System.UInt32" -> g.uint32_ty + | "System.UInt64" -> g.uint64_ty + | "System.Single" -> g.float32_ty + | "System.Double" -> g.float_ty + | "System.Char" -> g.char_ty + | "System.Boolean" -> g.bool_ty + | _ -> g.int32_ty + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + let tycon = (tcrefOfAppTy g ty).Deref + match tycon.GetFieldByName "value__" with + | Some rf -> rf.FormalType + | None -> error(InternalError("no 'value__' field found for enumeration type " + tycon.LogicalName, tycon.Range)) + +// CLEANUP NOTE: Get rid of this mutation. +let setValHasNoArity (f: Val) = + f.SetValReprInfo None; f + +//-------------------------------------------------------------------------- +// Resolve static optimization constraints +//-------------------------------------------------------------------------- + +let normalizeEnumTy g ty = (if isEnumTy g ty then underlyingTypeOfEnumTy g ty else ty) + +type StaticOptimizationAnswer = + | Yes = 1y + | No = -1y + | Unknown = 0y + +let decideStaticOptimizationConstraint g c haveWitnesses = + match c with + // When witnesses are available in generic code during codegen, "when ^T : ^T" resolves StaticOptimizationAnswer.Yes + // This doesn't apply to "when 'T : 'T" use for "FastGenericEqualityComparer" and others. + | TTyconEqualsTycon (a, b) when haveWitnesses && typeEquiv g a b && (match tryDestTyparTy g a with ValueSome tp -> tp.StaticReq = TyparStaticReq.HeadType | _ -> false) -> + StaticOptimizationAnswer.Yes + | TTyconEqualsTycon (a, b) -> + // Both types must be nominal for a definite result + let rec checkTypes a b = + let a = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g a) + match a with + | AppTy g (tcref1, _) -> + let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) + match b with + | AppTy g (tcref2, _) -> + if tyconRefEq g tcref1 tcref2 then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No + | RefTupleTy g _ | FunTy g _ -> StaticOptimizationAnswer.No + | _ -> StaticOptimizationAnswer.Unknown + + | FunTy g _ -> + let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) + match b with + | FunTy g _ -> StaticOptimizationAnswer.Yes + | AppTy g _ | RefTupleTy g _ -> StaticOptimizationAnswer.No + | _ -> StaticOptimizationAnswer.Unknown + | RefTupleTy g ts1 -> + let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b) + match b with + | RefTupleTy g ts2 -> + if ts1.Length = ts2.Length then StaticOptimizationAnswer.Yes + else StaticOptimizationAnswer.No + | AppTy g _ | FunTy g _ -> StaticOptimizationAnswer.No + | _ -> StaticOptimizationAnswer.Unknown + | _ -> StaticOptimizationAnswer.Unknown + checkTypes a b + | TTyconIsStruct a -> + let a = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g a) + match tryTcrefOfAppTy g a with + | ValueSome tcref1 -> if tcref1.IsStructOrEnumTycon then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No + | ValueNone -> StaticOptimizationAnswer.Unknown + +let rec DecideStaticOptimizations g cs haveWitnesses = + match cs with + | [] -> StaticOptimizationAnswer.Yes + | h :: t -> + let d = decideStaticOptimizationConstraint g h haveWitnesses + if d = StaticOptimizationAnswer.No then StaticOptimizationAnswer.No + elif d = StaticOptimizationAnswer.Yes then DecideStaticOptimizations g t haveWitnesses + else StaticOptimizationAnswer.Unknown + +let mkStaticOptimizationExpr g (cs, e1, e2, m) = + let d = DecideStaticOptimizations g cs false + if d = StaticOptimizationAnswer.No then e2 + elif d = StaticOptimizationAnswer.Yes then e1 + else Expr.StaticOptimization (cs, e1, e2, m) + +//-------------------------------------------------------------------------- +// Copy expressions, including new names for locally bound values. +// Used to inline expressions. +//-------------------------------------------------------------------------- + +type ValCopyFlag = + | CloneAll + | CloneAllAndMarkExprValsAsCompilerGenerated + | OnlyCloneExprVals + +// for quotations we do no want to avoid marking values as compiler generated since this may affect the shape of quotation (compiler generated values can be inlined) +let fixValCopyFlagForQuotations = function CloneAllAndMarkExprValsAsCompilerGenerated -> CloneAll | x -> x + +let markAsCompGen compgen d = + let compgen = + match compgen with + | CloneAllAndMarkExprValsAsCompilerGenerated -> true + | _ -> false + { d with val_flags= d.val_flags.WithIsCompilerGenerated(d.val_flags.IsCompilerGenerated || compgen) } + +let bindLocalVal (v: Val) (v': Val) tmenv = + { tmenv with valRemap=tmenv.valRemap.Add v (mkLocalValRef v') } + +let bindLocalVals vs vs' tmenv = + { tmenv with valRemap= (vs, vs', tmenv.valRemap) |||> List.foldBack2 (fun v v' acc -> acc.Add v (mkLocalValRef v') ) } + +let bindTycon (tc: Tycon) (tc': Tycon) tyenv = + { tyenv with tyconRefRemap=tyenv.tyconRefRemap.Add (mkLocalTyconRef tc) (mkLocalTyconRef tc') } + +let bindTycons tcs tcs' tyenv = + { tyenv with tyconRefRemap= (tcs, tcs', tyenv.tyconRefRemap) |||> List.foldBack2 (fun tc tc' acc -> acc.Add (mkLocalTyconRef tc) (mkLocalTyconRef tc')) } + +let remapAttribKind tmenv k = + match k with + | ILAttrib _ as x -> x + | FSAttrib vref -> FSAttrib(remapValRef tmenv vref) + +let tmenvCopyRemapAndBindTypars remapAttrib tmenv tps = + let tps', tyenvinner = copyAndRemapAndBindTyparsFull remapAttrib tmenv tps + let tmenvinner = tyenvinner + tps', tmenvinner + +let rec remapAttrib g tmenv (Attrib (tcref, kind, args, props, isGetOrSetAttr, targets, m)) = + Attrib(remapTyconRef tmenv.tyconRefRemap tcref, + remapAttribKind tmenv kind, + args |> List.map (remapAttribExpr g tmenv), + props |> List.map (fun (AttribNamedArg(nm, ty, flg, expr)) -> AttribNamedArg(nm, remapType tmenv ty, flg, remapAttribExpr g tmenv expr)), + isGetOrSetAttr, + targets, + m) + +and remapAttribExpr g tmenv (AttribExpr(e1, e2)) = + AttribExpr(remapExpr g CloneAll tmenv e1, remapExpr g CloneAll tmenv e2) + +and remapAttribs g tmenv xs = List.map (remapAttrib g tmenv) xs + +and remapPossibleForallTy g tmenv ty = remapTypeFull (remapAttribs g tmenv) tmenv ty + +and remapArgData g tmenv (argInfo: ArgReprInfo) : ArgReprInfo = + { Attribs = remapAttribs g tmenv argInfo.Attribs; Name = argInfo.Name } + +and remapValReprInfo g tmenv (ValReprInfo(tpNames, arginfosl, retInfo)) = + ValReprInfo(tpNames, List.mapSquared (remapArgData g tmenv) arginfosl, remapArgData g tmenv retInfo) + +and remapValData g tmenv (d: ValData) = + let ty = d.val_type + let topValInfo = d.ValReprInfo + let tyR = ty |> remapPossibleForallTy g tmenv + let declaringEntityR = d.DeclaringEntity |> remapParentRef tmenv + let reprInfoR = d.ValReprInfo |> Option.map (remapValReprInfo g tmenv) + let memberInfoR = d.MemberInfo |> Option.map (remapMemberInfo g d.val_range topValInfo ty tyR tmenv) + let attribsR = d.Attribs |> remapAttribs g tmenv + { d with + val_type = tyR + val_opt_data = + match d.val_opt_data with + | Some dd -> + Some { dd with + val_declaring_entity = declaringEntityR + val_repr_info = reprInfoR + val_member_info = memberInfoR + val_attribs = attribsR } + | None -> None } + +and remapParentRef tyenv p = + match p with + | ParentNone -> ParentNone + | Parent x -> Parent (x |> remapTyconRef tyenv.tyconRefRemap) + +and mapImmediateValsAndTycons ft fv (x: ModuleOrNamespaceType) = + let vals = x.AllValsAndMembers |> QueueList.map fv + let tycons = x.AllEntities |> QueueList.map ft + ModuleOrNamespaceType(x.ModuleOrNamespaceKind, vals, tycons) + +and copyVal compgen (v: Val) = + match compgen with + | OnlyCloneExprVals when v.IsMemberOrModuleBinding -> v + | _ -> v |> Construct.NewModifiedVal id + +and fixupValData g compgen tmenv (v2: Val) = + // only fixup if we copy the value + match compgen with + | OnlyCloneExprVals when v2.IsMemberOrModuleBinding -> () + | _ -> + let newData = remapValData g tmenv v2 |> markAsCompGen compgen + // uses the same stamp + v2.SetData newData + +and copyAndRemapAndBindVals g compgen tmenv vs = + let vs2 = vs |> List.map (copyVal compgen) + let tmenvinner = bindLocalVals vs vs2 tmenv + vs2 |> List.iter (fixupValData g compgen tmenvinner) + vs2, tmenvinner + +and copyAndRemapAndBindVal g compgen tmenv v = + let v2 = v |> copyVal compgen + let tmenvinner = bindLocalVal v v2 tmenv + fixupValData g compgen tmenvinner v2 + v2, tmenvinner + +and remapExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) expr = + match expr with + + // Handle the linear cases for arbitrary-sized inputs + | LinearOpExpr _ + | LinearMatchExpr _ + | Expr.Sequential _ + | Expr.Let _ -> + remapLinearExpr g compgen tmenv expr (fun x -> x) + + // Binding constructs - see also dtrees below + | Expr.Lambda (_, ctorThisValOpt, baseValOpt, vs, b, m, rty) -> + remapLambaExpr g compgen tmenv (ctorThisValOpt, baseValOpt, vs, b, m, rty) + + | Expr.TyLambda (_, tps, b, m, rty) -> + let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps + mkTypeLambda m tps' (remapExpr g compgen tmenvinner b, remapType tmenvinner rty) + + | Expr.TyChoose (tps, b, m) -> + let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps + Expr.TyChoose (tps', remapExpr g compgen tmenvinner b, m) + + | Expr.LetRec (binds, e, m, _) -> + let binds', tmenvinner = copyAndRemapAndBindBindings g compgen tmenv binds + Expr.LetRec (binds', remapExpr g compgen tmenvinner e, m, Construct.NewFreeVarsCache()) + + | Expr.Match (spBind, exprm, pt, targets, m, ty) -> + primMkMatch (spBind, exprm, remapDecisionTree g compgen tmenv pt, + targets |> Array.map (remapTarget g compgen tmenv), + m, remapType tmenv ty) + + | Expr.Val (vr, vf, m) -> + let vr' = remapValRef tmenv vr + let vf' = remapValFlags tmenv vf + if vr === vr' && vf === vf' then expr + else Expr.Val (vr', vf', m) + + | Expr.Quote (a, dataCell, isFromQueryExpression, m, ty) -> + remapQuoteExpr g compgen tmenv (a, dataCell, isFromQueryExpression, m, ty) + + | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, m) -> + let basev', tmenvinner = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv basev + mkObjExpr (remapType tmenv ty, basev', + remapExpr g compgen tmenv basecall, + List.map (remapMethod g compgen tmenvinner) overrides, + List.map (remapInterfaceImpl g compgen tmenvinner) iimpls, m) + + // Addresses of immutable field may "leak" across assembly boundaries - see CanTakeAddressOfRecdFieldRef below. + // This is "ok", in the sense that it is always valid to fix these up to be uses + // of a temporary local, e.g. + // &(E.RF) --> let mutable v = E.RF in &v + + | Expr.Op (TOp.ValFieldGetAddr (rfref, readonly), tinst, [arg], m) when + not rfref.RecdField.IsMutable && + not (entityRefInThisAssembly g.compilingFslib rfref.TyconRef) -> + + let tinst = remapTypes tmenv tinst + let arg = remapExpr g compgen tmenv arg + let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfRecdFieldRef rfref tinst) + mkCompGenLet m tmp (mkRecdFieldGetViaExprAddr (arg, rfref, tinst, m)) (mkValAddr m readonly (mkLocalValRef tmp)) + + | Expr.Op (TOp.UnionCaseFieldGetAddr (uref, cidx, readonly), tinst, [arg], m) when + not (uref.FieldByIndex(cidx).IsMutable) && + not (entityRefInThisAssembly g.compilingFslib uref.TyconRef) -> + + let tinst = remapTypes tmenv tinst + let arg = remapExpr g compgen tmenv arg + let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfUnionFieldRef uref cidx tinst) + mkCompGenLet m tmp (mkUnionCaseFieldGetProvenViaExprAddr (arg, uref, tinst, cidx, m)) (mkValAddr m readonly (mkLocalValRef tmp)) + + | Expr.Op (op, tinst, args, m) -> + remapOpExpr g compgen tmenv (op, tinst, args, m) expr + + | Expr.App (e1, e1ty, tyargs, args, m) -> + remapAppExpr g compgen tmenv (e1, e1ty, tyargs, args, m) expr + + | Expr.Link eref -> + remapExpr g compgen tmenv !eref + + | Expr.StaticOptimization (cs, e2, e3, m) -> + // note that type instantiation typically resolve the static constraints here + mkStaticOptimizationExpr g (List.map (remapConstraint tmenv) cs, remapExpr g compgen tmenv e2, remapExpr g compgen tmenv e3, m) + + | Expr.Const (c, m, ty) -> + let ty' = remapType tmenv ty + if ty === ty' then expr else Expr.Const (c, m, ty') + + | Expr.WitnessArg (traitInfo, m) -> + let traitInfoR = remapTraitInfo tmenv traitInfo + Expr.WitnessArg (traitInfoR, m) + +and remapLambaExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) (ctorThisValOpt, baseValOpt, vs, b, m, rty) = + let ctorThisValOpt, tmenv = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv ctorThisValOpt + let baseValOpt, tmenv = Option.mapFold (copyAndRemapAndBindVal g compgen) tmenv baseValOpt + let vs, tmenv = copyAndRemapAndBindVals g compgen tmenv vs + let b = remapExpr g compgen tmenv b + let rty = remapType tmenv rty + Expr.Lambda (newUnique(), ctorThisValOpt, baseValOpt, vs, b, m, rty) + +and remapQuoteExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) (a, dataCell, isFromQueryExpression, m, ty) = + let doData (typeDefs, argTypes, argExprs, res) = (typeDefs, remapTypesAux tmenv argTypes, remapExprs g compgen tmenv argExprs, res) + let data' = + match dataCell.Value with + | None -> None + | Some (data1, data2) -> Some (doData data1, doData data2) + // fix value of compgen for both original expression and pickled AST + let compgen = fixValCopyFlagForQuotations compgen + Expr.Quote (remapExpr g compgen tmenv a, ref data', isFromQueryExpression, m, remapType tmenv ty) + +and remapOpExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) (op, tinst, args, m) origExpr = + let op' = remapOp tmenv op + let tinst' = remapTypes tmenv tinst + let args' = remapExprs g compgen tmenv args + if op === op' && tinst === tinst' && args === args' then origExpr + else Expr.Op (op', tinst', args', m) + +and remapAppExpr (g: TcGlobals) (compgen: ValCopyFlag) (tmenv: Remap) (e1, e1ty, tyargs, args, m) origExpr = + let e1' = remapExpr g compgen tmenv e1 + let e1ty' = remapPossibleForallTy g tmenv e1ty + let tyargs' = remapTypes tmenv tyargs + let args' = remapExprs g compgen tmenv args + if e1 === e1' && e1ty === e1ty' && tyargs === tyargs' && args === args' then origExpr + else Expr.App (e1', e1ty', tyargs', args', m) + +and remapTarget g compgen tmenv (TTarget(vs, e, spTarget, flags)) = + let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenv vs + TTarget(vs', remapExpr g compgen tmenvinner e, spTarget, flags) + +and remapLinearExpr g compgen tmenv expr contf = + + match expr with + + | Expr.Let (bind, bodyExpr, m, _) -> + let bind', tmenvinner = copyAndRemapAndBindBinding g compgen tmenv bind + // tailcall for the linear position + remapLinearExpr g compgen tmenvinner bodyExpr (contf << mkLetBind m bind') + + | Expr.Sequential (expr1, expr2, dir, spSeq, m) -> + let expr1' = remapExpr g compgen tmenv expr1 + // tailcall for the linear position + remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> + if expr1 === expr1' && expr2 === expr2' then expr + else Expr.Sequential (expr1', expr2', dir, spSeq, m))) + + | LinearMatchExpr (spBind, exprm, dtree, tg1, expr2, sp2, m2, ty) -> + let dtree' = remapDecisionTree g compgen tmenv dtree + let tg1' = remapTarget g compgen tmenv tg1 + let ty' = remapType tmenv ty + // tailcall for the linear position + remapLinearExpr g compgen tmenv expr2 (contf << (fun expr2' -> + rebuildLinearMatchExpr (spBind, exprm, dtree', tg1', expr2', sp2, m2, ty'))) + + | LinearOpExpr (op, tyargs, argsFront, argLast, m) -> + let op' = remapOp tmenv op + let tinst' = remapTypes tmenv tyargs + let argsFront' = remapExprs g compgen tmenv argsFront + // tailcall for the linear position + remapLinearExpr g compgen tmenv argLast (contf << (fun argLast' -> + if op === op' && tyargs === tinst' && argsFront === argsFront' && argLast === argLast' then expr + else rebuildLinearOpExpr (op', tinst', argsFront', argLast', m))) + + | _ -> + contf (remapExpr g compgen tmenv expr) + +and remapConstraint tyenv c = + match c with + | TTyconEqualsTycon(ty1, ty2) -> TTyconEqualsTycon(remapType tyenv ty1, remapType tyenv ty2) + | TTyconIsStruct ty1 -> TTyconIsStruct(remapType tyenv ty1) + +and remapOp tmenv op = + match op with + | TOp.Recd (ctor, tcref) -> TOp.Recd (ctor, remapTyconRef tmenv.tyconRefRemap tcref) + | TOp.UnionCaseTagGet tcref -> TOp.UnionCaseTagGet (remapTyconRef tmenv.tyconRefRemap tcref) + | TOp.UnionCase ucref -> TOp.UnionCase (remapUnionCaseRef tmenv.tyconRefRemap ucref) + | TOp.UnionCaseProof ucref -> TOp.UnionCaseProof (remapUnionCaseRef tmenv.tyconRefRemap ucref) + | TOp.ExnConstr ec -> TOp.ExnConstr (remapTyconRef tmenv.tyconRefRemap ec) + | TOp.ExnFieldGet (ec, n) -> TOp.ExnFieldGet (remapTyconRef tmenv.tyconRefRemap ec, n) + | TOp.ExnFieldSet (ec, n) -> TOp.ExnFieldSet (remapTyconRef tmenv.tyconRefRemap ec, n) + | TOp.ValFieldSet rfref -> TOp.ValFieldSet (remapRecdFieldRef tmenv.tyconRefRemap rfref) + | TOp.ValFieldGet rfref -> TOp.ValFieldGet (remapRecdFieldRef tmenv.tyconRefRemap rfref) + | TOp.ValFieldGetAddr (rfref, readonly) -> TOp.ValFieldGetAddr (remapRecdFieldRef tmenv.tyconRefRemap rfref, readonly) + | TOp.UnionCaseFieldGet (ucref, n) -> TOp.UnionCaseFieldGet (remapUnionCaseRef tmenv.tyconRefRemap ucref, n) + | TOp.UnionCaseFieldGetAddr (ucref, n, readonly) -> TOp.UnionCaseFieldGetAddr (remapUnionCaseRef tmenv.tyconRefRemap ucref, n, readonly) + | TOp.UnionCaseFieldSet (ucref, n) -> TOp.UnionCaseFieldSet (remapUnionCaseRef tmenv.tyconRefRemap ucref, n) + | TOp.ILAsm (instrs, retTypes) -> + let retTypes2 = remapTypes tmenv retTypes + if retTypes === retTypes2 then op else + TOp.ILAsm (instrs, retTypes2) + | TOp.TraitCall traitInfo -> TOp.TraitCall (remapTraitInfo tmenv traitInfo) + | TOp.LValueOp (kind, lvr) -> TOp.LValueOp (kind, remapValRef tmenv lvr) + | TOp.ILCall (isVirtual, isProtected, isStruct, isCtor, valUseFlag, isProperty, noTailCall, ilMethRef, enclTypeInst, methInst, retTypes) -> + TOp.ILCall (isVirtual, isProtected, isStruct, isCtor, remapValFlags tmenv valUseFlag, + isProperty, noTailCall, ilMethRef, remapTypes tmenv enclTypeInst, + remapTypes tmenv methInst, remapTypes tmenv retTypes) + | _ -> op + +and remapValFlags tmenv x = + match x with + | PossibleConstrainedCall ty -> PossibleConstrainedCall (remapType tmenv ty) + | _ -> x + +and remapExprs g compgen tmenv es = List.mapq (remapExpr g compgen tmenv) es + +and remapFlatExprs g compgen tmenv es = List.mapq (remapExpr g compgen tmenv) es + +and remapDecisionTree g compgen tmenv x = + match x with + | TDSwitch(sp, e1, cases, dflt, m) -> + let e1R = remapExpr g compgen tmenv e1 + let casesR = + cases |> List.map (fun (TCase(test, subTree)) -> + let testR = + match test with + | DecisionTreeTest.UnionCase (uc, tinst) -> DecisionTreeTest.UnionCase(remapUnionCaseRef tmenv.tyconRefRemap uc, remapTypes tmenv tinst) + | DecisionTreeTest.ArrayLength (n, ty) -> DecisionTreeTest.ArrayLength(n, remapType tmenv ty) + | DecisionTreeTest.Const _ -> test + | DecisionTreeTest.IsInst (srcty, tgty) -> DecisionTreeTest.IsInst (remapType tmenv srcty, remapType tmenv tgty) + | DecisionTreeTest.IsNull -> DecisionTreeTest.IsNull + | DecisionTreeTest.ActivePatternCase _ -> failwith "DecisionTreeTest.ActivePatternCase should only be used during pattern match compilation" + | DecisionTreeTest.Error(m) -> DecisionTreeTest.Error(m) + let subTreeR = remapDecisionTree g compgen tmenv subTree + TCase(testR, subTreeR)) + let dfltR = Option.map (remapDecisionTree g compgen tmenv) dflt + TDSwitch(sp, e1R, casesR, dfltR, m) + + | TDSuccess (es, n) -> + TDSuccess (remapFlatExprs g compgen tmenv es, n) + + | TDBind (bind, rest) -> + let bind', tmenvinner = copyAndRemapAndBindBinding g compgen tmenv bind + TDBind (bind', remapDecisionTree g compgen tmenvinner rest) + +and copyAndRemapAndBindBinding g compgen tmenv (bind: Binding) = + let v = bind.Var + let v', tmenv = copyAndRemapAndBindVal g compgen tmenv v + remapAndRenameBind g compgen tmenv bind v', tmenv + +and copyAndRemapAndBindBindings g compgen tmenv binds = + let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenv (valsOfBinds binds) + remapAndRenameBinds g compgen tmenvinner binds vs', tmenvinner + +and remapAndRenameBinds g compgen tmenvinner binds vs' = List.map2 (remapAndRenameBind g compgen tmenvinner) binds vs' +and remapAndRenameBind g compgen tmenvinner (TBind(_, repr, letSeqPtOpt)) v' = TBind(v', remapExpr g compgen tmenvinner repr, letSeqPtOpt) + +and remapMethod g compgen tmenv (TObjExprMethod(slotsig, attribs, tps, vs, e, m)) = + let attribs2 = attribs |> remapAttribs g tmenv + let slotsig2 = remapSlotSig (remapAttribs g tmenv) tmenv slotsig + let tps2, tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv tps + let vs2, tmenvinner2 = List.mapFold (copyAndRemapAndBindVals g compgen) tmenvinner vs + let e2 = remapExpr g compgen tmenvinner2 e + TObjExprMethod(slotsig2, attribs2, tps2, vs2, e2, m) + +and remapInterfaceImpl g compgen tmenv (ty, overrides) = + (remapType tmenv ty, List.map (remapMethod g compgen tmenv) overrides) + +and remapRecdField g tmenv x = + { x with + rfield_type = x.rfield_type |> remapPossibleForallTy g tmenv + rfield_pattribs = x.rfield_pattribs |> remapAttribs g tmenv + rfield_fattribs = x.rfield_fattribs |> remapAttribs g tmenv } + +and remapRecdFields g tmenv (x: TyconRecdFields) = + x.AllFieldsAsList |> List.map (remapRecdField g tmenv) |> Construct.MakeRecdFieldsTable + +and remapUnionCase g tmenv (x: UnionCase) = + { x with + FieldTable = x.FieldTable |> remapRecdFields g tmenv + ReturnType = x.ReturnType |> remapType tmenv + Attribs = x.Attribs |> remapAttribs g tmenv } + +and remapUnionCases g tmenv (x: TyconUnionData) = + x.UnionCasesAsList |> List.map (remapUnionCase g tmenv) |> Construct.MakeUnionCases + +and remapFsObjData g tmenv x = + { x with + fsobjmodel_kind = + (match x.fsobjmodel_kind with + | TFSharpDelegate slotsig -> TFSharpDelegate (remapSlotSig (remapAttribs g tmenv) tmenv slotsig) + | TFSharpClass | TFSharpInterface | TFSharpStruct | TFSharpEnum -> x.fsobjmodel_kind) + fsobjmodel_vslots = x.fsobjmodel_vslots |> List.map (remapValRef tmenv) + fsobjmodel_rfields = x.fsobjmodel_rfields |> remapRecdFields g tmenv } + + +and remapTyconRepr g tmenv repr = + match repr with + | TFSharpObjectRepr x -> TFSharpObjectRepr (remapFsObjData g tmenv x) + | TFSharpRecdRepr x -> TFSharpRecdRepr (remapRecdFields g tmenv x) + | TFSharpUnionRepr x -> TFSharpUnionRepr (remapUnionCases g tmenv x) + | TILObjectRepr _ -> failwith "cannot remap IL type definitions" +#if !NO_EXTENSIONTYPING + | TProvidedNamespaceRepr _ -> repr + | TProvidedTypeRepr info -> + TProvidedTypeRepr + { info with + LazyBaseType = info.LazyBaseType.Force (range0, g.obj_ty) |> remapType tmenv |> LazyWithContext.NotLazy + // The load context for the provided type contains TyconRef objects. We must remap these. + // This is actually done on-demand (see the implementation of ProvidedTypeContext) + ProvidedType = + info.ProvidedType.PApplyNoFailure (fun st -> + let ctxt = st.Context.RemapTyconRefs(unbox >> remapTyconRef tmenv.tyconRefRemap >> box) + ProvidedType.ApplyContext (st, ctxt)) } +#endif + | TNoRepr _ -> repr + | TAsmRepr _ -> repr + | TMeasureableRepr x -> TMeasureableRepr (remapType tmenv x) + +and remapTyconAug tmenv (x: TyconAugmentation) = + { x with + tcaug_equals = x.tcaug_equals |> Option.map (mapPair (remapValRef tmenv, remapValRef tmenv)) + tcaug_compare = x.tcaug_compare |> Option.map (mapPair (remapValRef tmenv, remapValRef tmenv)) + tcaug_compare_withc = x.tcaug_compare_withc |> Option.map(remapValRef tmenv) + tcaug_hash_and_equals_withc = x.tcaug_hash_and_equals_withc |> Option.map (mapTriple (remapValRef tmenv, remapValRef tmenv, remapValRef tmenv)) + tcaug_adhoc = x.tcaug_adhoc |> NameMap.map (List.map (remapValRef tmenv)) + tcaug_adhoc_list = x.tcaug_adhoc_list |> ResizeArray.map (fun (flag, vref) -> (flag, remapValRef tmenv vref)) + tcaug_super = x.tcaug_super |> Option.map (remapType tmenv) + tcaug_interfaces = x.tcaug_interfaces |> List.map (map1Of3 (remapType tmenv)) } + +and remapTyconExnInfo g tmenv inp = + match inp with + | TExnAbbrevRepr x -> TExnAbbrevRepr (remapTyconRef tmenv.tyconRefRemap x) + | TExnFresh x -> TExnFresh (remapRecdFields g tmenv x) + | TExnAsmRepr _ | TExnNone -> inp + +and remapMemberInfo g m topValInfo ty ty' tmenv x = + // The slotsig in the ImplementedSlotSigs is w.r.t. the type variables in the value's type. + // REVIEW: this is a bit gross. It would be nice if the slotsig was standalone + assert (Option.isSome topValInfo) + let tpsOrig, _, _, _ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty m + let tps, _, _, _ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty' m + let renaming, _ = mkTyparToTyparRenaming tpsOrig tps + let tmenv = { tmenv with tpinst = tmenv.tpinst @ renaming } + { x with + ApparentEnclosingEntity = x.ApparentEnclosingEntity |> remapTyconRef tmenv.tyconRefRemap + ImplementedSlotSigs = x.ImplementedSlotSigs |> List.map (remapSlotSig (remapAttribs g tmenv) tmenv) + } + +and copyAndRemapAndBindModTy g compgen tmenv mty = + let tycons = allEntitiesOfModuleOrNamespaceTy mty + let vs = allValsOfModuleOrNamespaceTy mty + let _, _, tmenvinner = copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs + remapModTy g compgen tmenvinner mty, tmenvinner + +and remapModTy g _compgen tmenv mty = + mapImmediateValsAndTycons (renameTycon g tmenv) (renameVal tmenv) mty + +and renameTycon g tyenv x = + let tcref = + try + let res = tyenv.tyconRefRemap.[mkLocalTyconRef x] + res + with :? KeyNotFoundException -> + errorR(InternalError("couldn't remap internal tycon " + showL(DebugPrint.tyconL g x), x.Range)) + mkLocalTyconRef x + tcref.Deref + +and renameVal tmenv x = + match tmenv.valRemap.TryFind x with + | Some v -> v.Deref + | None -> x + +and copyTycon compgen (tycon: Tycon) = + match compgen with + | OnlyCloneExprVals -> tycon + | _ -> Construct.NewClonedTycon tycon + +/// This operates over a whole nested collection of tycons and vals simultaneously *) +and copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs = + let tycons' = tycons |> List.map (copyTycon compgen) + + let tmenvinner = bindTycons tycons tycons' tmenv + + // Values need to be copied and renamed. + let vs', tmenvinner = copyAndRemapAndBindVals g compgen tmenvinner vs + + // "if a type constructor is hidden then all its inner values and inner type constructors must also be hidden" + // Hence we can just lookup the inner tycon/value mappings in the tables. + + let lookupVal (v: Val) = + let vref = + try + let res = tmenvinner.valRemap.[v] + res + with :? KeyNotFoundException -> + errorR(InternalError(sprintf "couldn't remap internal value '%s'" v.LogicalName, v.Range)) + mkLocalValRef v + vref.Deref + + let lookupTycon g tycon = + let tcref = + try + let res = tmenvinner.tyconRefRemap.[mkLocalTyconRef tycon] + res + with :? KeyNotFoundException -> + errorR(InternalError("couldn't remap internal tycon " + showL(DebugPrint.tyconL g tycon), tycon.Range)) + mkLocalTyconRef tycon + tcref.Deref + (tycons, tycons') ||> List.iter2 (fun tcd tcd' -> + let lookupTycon tycon = lookupTycon g tycon + let tps', tmenvinner2 = tmenvCopyRemapAndBindTypars (remapAttribs g tmenvinner) tmenvinner (tcd.entity_typars.Force(tcd.entity_range)) + tcd'.entity_typars <- LazyWithContext.NotLazy tps' + tcd'.entity_attribs <- tcd.entity_attribs |> remapAttribs g tmenvinner2 + tcd'.entity_tycon_repr <- tcd.entity_tycon_repr |> remapTyconRepr g tmenvinner2 + let typeAbbrevR = tcd.TypeAbbrev |> Option.map (remapType tmenvinner2) + tcd'.entity_tycon_tcaug <- tcd.entity_tycon_tcaug |> remapTyconAug tmenvinner2 + tcd'.entity_modul_contents <- MaybeLazy.Strict (tcd.entity_modul_contents.Value + |> mapImmediateValsAndTycons lookupTycon lookupVal) + let exnInfoR = tcd.ExceptionInfo |> remapTyconExnInfo g tmenvinner2 + match tcd'.entity_opt_data with + | Some optData -> tcd'.entity_opt_data <- Some { optData with entity_tycon_abbrev = typeAbbrevR; entity_exn_info = exnInfoR } + | _ -> + tcd'.SetTypeAbbrev typeAbbrevR + tcd'.SetExceptionInfo exnInfoR) + tycons', vs', tmenvinner + + +and allTyconsOfTycon (tycon: Tycon) = + seq { yield tycon + for nestedTycon in tycon.ModuleOrNamespaceType.AllEntities do + yield! allTyconsOfTycon nestedTycon } + +and allEntitiesOfModDef mdef = + seq { match mdef with + | TMDefRec(_, _, tycons, mbinds, _) -> + for tycon in tycons do + yield! allTyconsOfTycon tycon + for mbind in mbinds do + match mbind with + | ModuleOrNamespaceBinding.Binding _ -> () + | ModuleOrNamespaceBinding.Module(mspec, def) -> + yield mspec + yield! allEntitiesOfModDef def + | TMDefLet _ -> () + | TMDefDo _ -> () + | TMDefOpens _ -> () + | TMDefs defs -> + for def in defs do + yield! allEntitiesOfModDef def + | TMAbstract(ModuleOrNamespaceExprWithSig(mty, _, _)) -> + yield! allEntitiesOfModuleOrNamespaceTy mty } + +and allValsOfModDef mdef = + seq { match mdef with + | TMDefRec(_, _, tycons, mbinds, _) -> + yield! abstractSlotValsOfTycons tycons + for mbind in mbinds do + match mbind with + | ModuleOrNamespaceBinding.Binding bind -> yield bind.Var + | ModuleOrNamespaceBinding.Module(_, def) -> yield! allValsOfModDef def + | TMDefLet(bind, _) -> + yield bind.Var + | TMDefDo _ -> () + | TMDefOpens _ -> () + | TMDefs defs -> + for def in defs do + yield! allValsOfModDef def + | TMAbstract(ModuleOrNamespaceExprWithSig(mty, _, _)) -> + yield! allValsOfModuleOrNamespaceTy mty } + +and remapAndBindModuleOrNamespaceExprWithSig g compgen tmenv (ModuleOrNamespaceExprWithSig(mty, mdef, m)) = + let mdef = copyAndRemapModDef g compgen tmenv mdef + let mty, tmenv = copyAndRemapAndBindModTy g compgen tmenv mty + ModuleOrNamespaceExprWithSig(mty, mdef, m), tmenv + +and remapModuleOrNamespaceExprWithSig g compgen tmenv (ModuleOrNamespaceExprWithSig(mty, mdef, m)) = + let mdef = copyAndRemapModDef g compgen tmenv mdef + let mty = remapModTy g compgen tmenv mty + ModuleOrNamespaceExprWithSig(mty, mdef, m) + +and copyAndRemapModDef g compgen tmenv mdef = + let tycons = allEntitiesOfModDef mdef |> List.ofSeq + let vs = allValsOfModDef mdef |> List.ofSeq + let _, _, tmenvinner = copyAndRemapAndBindTyconsAndVals g compgen tmenv tycons vs + remapAndRenameModDef g compgen tmenvinner mdef + +and remapAndRenameModDefs g compgen tmenv x = + List.map (remapAndRenameModDef g compgen tmenv) x + +and remapOpenDeclarations tmenv opens = + opens |> List.map (fun od -> + { od with + Modules = od.Modules |> List.map (remapTyconRef tmenv.tyconRefRemap) + Types = od.Types |> List.map (remapType tmenv) + }) + +and remapAndRenameModDef g compgen tmenv mdef = + match mdef with + | TMDefRec(isRec, opens, tycons, mbinds, m) -> + // Abstract (virtual) vslots in the tycons at TMDefRec nodes are binders. They also need to be copied and renamed. + let opensR = remapOpenDeclarations tmenv opens + let tyconsR = tycons |> List.map (renameTycon g tmenv) + let mbindsR = mbinds |> List.map (remapAndRenameModBind g compgen tmenv) + TMDefRec(isRec, opensR, tyconsR, mbindsR, m) + | TMDefLet(bind, m) -> + let v = bind.Var + let bind = remapAndRenameBind g compgen tmenv bind (renameVal tmenv v) + TMDefLet(bind, m) + | TMDefDo(e, m) -> + let e = remapExpr g compgen tmenv e + TMDefDo(e, m) + | TMDefOpens opens -> + let opens = remapOpenDeclarations tmenv opens + TMDefOpens opens + | TMDefs defs -> + let defs = remapAndRenameModDefs g compgen tmenv defs + TMDefs defs + | TMAbstract mexpr -> + let mexpr = remapModuleOrNamespaceExprWithSig g compgen tmenv mexpr + TMAbstract mexpr + +and remapAndRenameModBind g compgen tmenv x = + match x with + | ModuleOrNamespaceBinding.Binding bind -> + let v2 = bind |> valOfBind |> renameVal tmenv + let bind2 = remapAndRenameBind g compgen tmenv bind v2 + ModuleOrNamespaceBinding.Binding bind2 + | ModuleOrNamespaceBinding.Module(mspec, def) -> + let mspec = renameTycon g tmenv mspec + let def = remapAndRenameModDef g compgen tmenv def + ModuleOrNamespaceBinding.Module(mspec, def) + +and remapImplFile g compgen tmenv mv = + mapAccImplFile (remapAndBindModuleOrNamespaceExprWithSig g compgen) tmenv mv + +let copyModuleOrNamespaceType g compgen mtyp = copyAndRemapAndBindModTy g compgen Remap.Empty mtyp |> fst + +let copyExpr g compgen e = remapExpr g compgen Remap.Empty e + +let copyImplFile g compgen e = remapImplFile g compgen Remap.Empty e |> fst + +let instExpr g tpinst e = remapExpr g CloneAll (mkInstRemap tpinst) e + +//-------------------------------------------------------------------------- +// Replace Marks - adjust debugging marks when a lambda gets +// eliminated (i.e. an expression gets inlined) +//-------------------------------------------------------------------------- + +let rec remarkExpr m x = + match x with + | Expr.Lambda (uniq, ctorThisValOpt, baseValOpt, vs, b, _, rty) -> + Expr.Lambda (uniq, ctorThisValOpt, baseValOpt, vs, remarkExpr m b, m, rty) + + | Expr.TyLambda (uniq, tps, b, _, rty) -> + Expr.TyLambda (uniq, tps, remarkExpr m b, m, rty) + + | Expr.TyChoose (tps, b, _) -> + Expr.TyChoose (tps, remarkExpr m b, m) + + | Expr.LetRec (binds, e, _, fvs) -> + Expr.LetRec (remarkBinds m binds, remarkExpr m e, m, fvs) + + | Expr.Let (bind, e, _, fvs) -> + Expr.Let (remarkBind m bind, remarkExpr m e, m, fvs) + + | Expr.Match (_, _, pt, targets, _, ty) -> + let targetsR = targets |> Array.map (fun (TTarget(vs, e, _, flags)) -> TTarget(vs, remarkExpr m e, DebugPointAtTarget.No, flags)) + primMkMatch (DebugPointAtBinding.NoneAtInvisible, m, remarkDecisionTree m pt, targetsR, m, ty) + + | Expr.Val (x, valUseFlags, _) -> + Expr.Val (x, valUseFlags, m) + + | Expr.Quote (a, conv, isFromQueryExpression, _, ty) -> + Expr.Quote (remarkExpr m a, conv, isFromQueryExpression, m, ty) + + | Expr.Obj (n, ty, basev, basecall, overrides, iimpls, _) -> + Expr.Obj (n, ty, basev, remarkExpr m basecall, + List.map (remarkObjExprMethod m) overrides, + List.map (remarkInterfaceImpl m) iimpls, m) + + | Expr.Op (op, tinst, args, _) -> + + // If this is ultimately being inlined as the implementation + // of a 'while'/'for' etc in a computation expression then lay down a + // debug point + let op = + match op with + | TOp.For (spFor, style) -> + let spFor2 = + match m.DebugPointKind with + | RangeDebugPointKind.For -> DebugPointAtFor.Yes m + | _ -> spFor + TOp.For(spFor2, style) + | TOp.While (spWhile, marker) -> + let spWhile2 = + match m.DebugPointKind with + | RangeDebugPointKind.While -> DebugPointAtWhile.Yes m + | _ -> spWhile + TOp.While(spWhile2, marker) + | TOp.TryFinally (spTry, _) -> + let spTry2 = + match m.DebugPointKind with + | RangeDebugPointKind.Try -> DebugPointAtTry.Yes m + | _ -> spTry + // The debug point for the 'finally' is not yet recoverable + TOp.TryFinally (spTry2, DebugPointAtFinally.No) + | TOp.TryWith (spTry, _) -> + let spTry2 = + match m.DebugPointKind with + | RangeDebugPointKind.Try -> DebugPointAtTry.Yes m + | _ -> spTry + // The debug point for the 'with' is not yet recoverable + TOp.TryWith (spTry2, DebugPointAtWith.No) + | _ -> op + Expr.Op (op, tinst, remarkExprs m args, m) + + | Expr.Link eref -> + // Preserve identity of fixup nodes during remarkExpr + eref := remarkExpr m !eref + x + + | Expr.App (e1, e1ty, tyargs, args, _) -> + Expr.App (remarkExpr m e1, e1ty, tyargs, remarkExprs m args, m) + + | Expr.Sequential (e1, e2, dir, sp, _) -> + let e1R = remarkExpr m e1 + let e2R = remarkExpr m e2 + + // This is to suppress false sequence points when inlining 'ResumableCode.TryWith' + // It is adhoc and may need to be improved if the library implementation changes + // + // For this specific code: + // + // __stack_caught <- true + // __stack_savedExn <- ... + // + // we suppress the sequence points on both the sequentials. + // + // Normally inlining associates all of the inlined code with the expression range of the overall construct, + // which for computation expression calls TryFinally and TryWith is the 'try' keyword. + // However this is broken when inlining sophisticated control flow as the 'with' and 'finally' + // parts of the code get the 'try' keyword as their sequence point range. + let sp = + match sp, e2R with + | DebugPointAtSequential.SuppressBoth, _ -> DebugPointAtSequential.SuppressBoth + | _, Expr.Op(TOp.LValueOp (LSet _, v), _, _, _) when v.DisplayName = "__stack_savedExn" -> DebugPointAtSequential.SuppressBoth + | _ -> DebugPointAtSequential.SuppressStmt + + Expr.Sequential (e1R, e2R, dir, sp, m) + + | Expr.StaticOptimization (eqns, e2, e3, _) -> + Expr.StaticOptimization (eqns, remarkExpr m e2, remarkExpr m e3, m) + + | Expr.Const (c, _, ty) -> + Expr.Const (c, m, ty) + + | Expr.WitnessArg (witnessInfo, _) -> + Expr.WitnessArg (witnessInfo, m) + +and remarkObjExprMethod m (TObjExprMethod(slotsig, attribs, tps, vs, e, _)) = + TObjExprMethod(slotsig, attribs, tps, vs, remarkExpr m e, m) + +and remarkInterfaceImpl m (ty, overrides) = + (ty, List.map (remarkObjExprMethod m) overrides) + +and remarkExprs m es = es |> List.map (remarkExpr m) + +and remarkFlatExprs m es = es |> List.map (remarkExpr m) + +and remarkDecisionTree m x = + match x with + | TDSwitch(sp, e1, cases, dflt, _) -> + let e1R = remarkExpr m e1 + let casesR = cases |> List.map (fun (TCase(test, y)) -> TCase(test, remarkDecisionTree m y)) + let dfltR = Option.map (remarkDecisionTree m) dflt + TDSwitch(sp, e1R, casesR, Option.map (remarkDecisionTree m) dfltR, m) + | TDSuccess (es, n) -> + TDSuccess (remarkFlatExprs m es, n) + | TDBind (bind, rest) -> + TDBind(remarkBind m bind, remarkDecisionTree m rest) + +and remarkBinds m binds = List.map (remarkBind m) binds + +// This very deliberately drops the sequence points since this is used when adjusting the marks for inlined expressions +and remarkBind m (TBind(v, repr, _)) = + TBind(v, remarkExpr m repr, DebugPointAtBinding.NoneAtSticky) + +//-------------------------------------------------------------------------- +// Mutability analysis +//-------------------------------------------------------------------------- + +let isRecdOrStructFieldDefinitelyMutable (f: RecdField) = not f.IsStatic && f.IsMutable + +let isUnionCaseDefinitelyMutable (uc: UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldDefinitelyMutable + +let isUnionCaseRefDefinitelyMutable (uc: UnionCaseRef) = uc.UnionCase |> isUnionCaseDefinitelyMutable + +/// This is an incomplete check for .NET struct types. Returning 'false' doesn't mean the thing is immutable. +let isRecdOrUnionOrStructTyconRefDefinitelyMutable (tcref: TyconRef) = + let tycon = tcref.Deref + if tycon.IsUnionTycon then + tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable + elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then + // Note: This only looks at the F# fields, causing oddities. + // See https://github.com/Microsoft/visualfsharp/pull/4576 + tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldDefinitelyMutable + else + false + +// Although from the pure F# perspective exception values cannot be changed, the .NET +// implementation of exception objects attaches a whole bunch of stack information to +// each raised object. Hence we treat exception objects as if they have identity +let isExnDefinitelyMutable (_ecref: TyconRef) = true + +// Some of the implementations of library functions on lists use mutation on the tail +// of the cons cell. These cells are always private, i.e. not accessible by any other +// code until the construction of the entire return list has been completed. +// However, within the implementation code reads of the tail cell must in theory be treated +// with caution. Hence we are conservative and within FSharp.Core we don't treat list +// reads as if they were pure. +let isUnionCaseFieldMutable (g: TcGlobals) (ucref: UnionCaseRef) n = + (g.compilingFslib && tyconRefEq g ucref.TyconRef g.list_tcr_canon && n = 1) || + (ucref.FieldByIndex n).IsMutable + +let isExnFieldMutable ecref n = + if n < 0 || n >= List.length (recdFieldsOfExnDefRef ecref) then errorR(InternalError(sprintf "isExnFieldMutable, exnc = %s, n = %d" ecref.LogicalName n, ecref.Range)) + (recdFieldOfExnDefRefByIdx ecref n).IsMutable + +let useGenuineField (tycon: Tycon) (f: RecdField) = + Option.isSome f.LiteralValue || tycon.IsEnumTycon || f.rfield_secret || (not f.IsStatic && f.rfield_mutable && not tycon.IsRecordTycon) + +let ComputeFieldName tycon f = + if useGenuineField tycon f then f.rfield_id.idText + else CompilerGeneratedName f.rfield_id.idText + +//------------------------------------------------------------------------- +// Helpers for building code contained in the initial environment +//------------------------------------------------------------------------- + +let isQuotedExprTy g ty = match tryAppTy g ty with ValueSome (tcref, _) -> tyconRefEq g tcref g.expr_tcr | _ -> false + +let destQuotedExprTy g ty = match tryAppTy g ty with ValueSome (_, [ty]) -> ty | _ -> failwith "destQuotedExprTy" + +let mkQuotedExprTy (g: TcGlobals) ty = TType_app(g.expr_tcr, [ty]) + +let mkRawQuotedExprTy (g: TcGlobals) = TType_app(g.raw_expr_tcr, []) + +let mkAnyTupledTy (g: TcGlobals) tupInfo tys = + match tys with + | [] -> g.unit_ty + | [h] -> h + | _ -> TType_tuple(tupInfo, tys) + +let mkAnyAnonRecdTy (_g: TcGlobals) anonInfo tys = + TType_anon(anonInfo, tys) + +let mkRefTupledTy g tys = mkAnyTupledTy g tupInfoRef tys + +let mkRefTupledVarsTy g vs = mkRefTupledTy g (typesOfVals vs) + +let mkMethodTy g argtys rty = mkIteratedFunTy (List.map (mkRefTupledTy g) argtys) rty + +let mkArrayType (g: TcGlobals) ty = TType_app (g.array_tcr_nice, [ty]) + +let mkByteArrayTy (g: TcGlobals) = mkArrayType g g.byte_ty + +//--------------------------------------------------------------------------- +// Witnesses +//--------------------------------------------------------------------------- + +let GenWitnessArgTys (g: TcGlobals) (traitInfo: TraitWitnessInfo) = + let (TraitWitnessInfo(_tys, _nm, _memFlags, argtys, _rty)) = traitInfo + let argtys = if argtys.IsEmpty then [g.unit_ty] else argtys + let argtysl = List.map List.singleton argtys + argtysl + +let GenWitnessTy (g: TcGlobals) (traitInfo: TraitWitnessInfo) = + let rty = match traitInfo.ReturnType with None -> g.unit_ty | Some ty -> ty + let argtysl = GenWitnessArgTys g traitInfo + mkMethodTy g argtysl rty + +let GenWitnessTys (g: TcGlobals) (cxs: TraitWitnessInfos) = + if g.generateWitnesses then + cxs |> List.map (GenWitnessTy g) + else + [] + +//-------------------------------------------------------------------------- +// tyOfExpr +//-------------------------------------------------------------------------- + +let rec tyOfExpr g e = + match e with + | Expr.App (_, fty, tyargs, args, _) -> applyTys g fty (tyargs, args) + | Expr.Obj (_, ty, _, _, _, _, _) + | Expr.Match (_, _, _, _, _, ty) + | Expr.Quote (_, _, _, _, ty) + | Expr.Const (_, _, ty) -> ty + | Expr.Val (vref, _, _) -> vref.Type + | Expr.Sequential (a, b, k, _, _) -> tyOfExpr g (match k with NormalSeq -> b | ThenDoSeq -> a) + | Expr.Lambda (_, _, _, vs, _, _, rty) -> (mkRefTupledVarsTy g vs --> rty) + | Expr.TyLambda (_, tyvs, _, _, rty) -> (tyvs +-> rty) + | Expr.Let (_, e, _, _) + | Expr.TyChoose (_, e, _) + | Expr.Link { contents=e} + | Expr.StaticOptimization (_, _, e, _) + | Expr.LetRec (_, e, _, _) -> tyOfExpr g e + | Expr.Op (op, tinst, _, _) -> + match op with + | TOp.Coerce -> (match tinst with [to_ty;_fromTy] -> to_ty | _ -> failwith "bad TOp.Coerce node") + | TOp.ILCall (_, _, _, _, _, _, _, _, _, _, retTypes) | TOp.ILAsm (_, retTypes) -> (match retTypes with [h] -> h | _ -> g.unit_ty) + | TOp.UnionCase uc -> actualResultTyOfUnionCase tinst uc + | TOp.UnionCaseProof uc -> mkProvenUnionCaseTy uc tinst + | TOp.Recd (_, tcref) -> mkAppTy tcref tinst + | TOp.ExnConstr _ -> g.exn_ty + | TOp.Bytes _ -> mkByteArrayTy g + | TOp.UInt16s _ -> mkArrayType g g.uint16_ty + | TOp.AnonRecdGet (_, i) -> List.item i tinst + | TOp.TupleFieldGet (_, i) -> List.item i tinst + | TOp.Tuple tupInfo -> mkAnyTupledTy g tupInfo tinst + | TOp.AnonRecd anonInfo -> mkAnyAnonRecdTy g anonInfo tinst + | TOp.For _ | TOp.While _ -> g.unit_ty + | TOp.Array -> (match tinst with [ty] -> mkArrayType g ty | _ -> failwith "bad TOp.Array node") + | TOp.TryWith _ | TOp.TryFinally _ -> (match tinst with [ty] -> ty | _ -> failwith "bad TOp_try node") + | TOp.ValFieldGetAddr (fref, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdFieldRef fref tinst) + | TOp.ValFieldGet fref -> actualTyOfRecdFieldRef fref tinst + | TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet), _) ->g.unit_ty + | TOp.UnionCaseTagGet _ -> g.int_ty + | TOp.UnionCaseFieldGetAddr (cref, j, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j)) + | TOp.UnionCaseFieldGet (cref, j) -> actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j) + | TOp.ExnFieldGet (ecref, j) -> recdFieldTyOfExnDefRefByIdx ecref j + | TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type + | TOp.LValueOp (LAddrOf readonly, v) -> mkByrefTyWithFlag g readonly v.Type + | TOp.RefAddrGet readonly -> (match tinst with [ty] -> mkByrefTyWithFlag g readonly ty | _ -> failwith "bad TOp.RefAddrGet node") + | TOp.TraitCall traitInfo -> GetFSharpViewOfReturnType g traitInfo.ReturnType + | TOp.Reraise -> (match tinst with [rtn_ty] -> rtn_ty | _ -> failwith "bad TOp.Reraise node") + | TOp.Goto _ | TOp.Label _ | TOp.Return -> + //assert false + //errorR(InternalError("unexpected goto/label/return in tyOfExpr", m)) + // It doesn't matter what type we return here. This is only used in free variable analysis in the code generator + g.unit_ty + | Expr.WitnessArg (traitInfo, _m) -> GenWitnessTy g traitInfo.TraitKey + +//-------------------------------------------------------------------------- +// Make applications +//--------------------------------------------------------------------------- + +let primMkApp (f, fty) tyargs argsl m = + Expr.App (f, fty, tyargs, argsl, m) + +// Check for the funky where a generic type instantiation at function type causes a generic function +// to appear to accept more arguments than it really does, e.g. "id id 1", where the first "id" is +// instantiated with "int -> int". +// +// In this case, apply the arguments one at a time. +let isExpansiveUnderInstantiation g fty0 tyargs pargs argsl = + isForallTy g fty0 && + let fty1 = formalApplyTys g fty0 (tyargs, pargs) + (not (isFunTy g fty1) || + let rec loop fty xs = + match xs with + | [] -> false + | _ :: t -> not (isFunTy g fty) || loop (rangeOfFunTy g fty) t + loop fty1 argsl) + +let rec mkExprAppAux g f fty argsl m = + match argsl with + | [] -> f + | _ -> + // Always combine the term application with a type application + // + // Combine the term application with a term application, but only when f' is an under-applied value of known arity + match f with + | Expr.App (f', fty', tyargs, pargs, m2) + when + (isNil pargs || + (match stripExpr f' with + | Expr.Val (v, _, _) -> + match v.ValReprInfo with + | Some info -> info.NumCurriedArgs > pargs.Length + | None -> false + | _ -> false)) && + not (isExpansiveUnderInstantiation g fty' tyargs pargs argsl) -> + primMkApp (f', fty') tyargs (pargs@argsl) (unionRanges m2 m) + + | _ -> + // Don't combine. 'f' is not an application + if not (isFunTy g fty) then error(InternalError("expected a function type", m)) + primMkApp (f, fty) [] argsl m + + +let rec mkAppsAux g f fty tyargsl argsl m = + match tyargsl with + | tyargs :: rest -> + match tyargs with + | [] -> mkAppsAux g f fty rest argsl m + | _ -> + let arfty = applyForallTy g fty tyargs + mkAppsAux g (primMkApp (f, fty) tyargs [] m) arfty rest argsl m + | [] -> + mkExprAppAux g f fty argsl m + +let mkApps g ((f, fty), tyargsl, argl, m) = mkAppsAux g f fty tyargsl argl m + +let mkTyAppExpr m (f, fty) tyargs = match tyargs with [] -> f | _ -> primMkApp (f, fty) tyargs [] m + +//-------------------------------------------------------------------------- +// Decision tree reduction +//-------------------------------------------------------------------------- + +let rec accTargetsOfDecisionTree tree acc = + match tree with + | TDSwitch (_, _, cases, dflt, _) -> + List.foldBack (fun (c: DecisionTreeCase) -> accTargetsOfDecisionTree c.CaseTree) cases + (Option.foldBack accTargetsOfDecisionTree dflt acc) + | TDSuccess (_, i) -> i :: acc + | TDBind (_, rest) -> accTargetsOfDecisionTree rest acc + +let rec mapTargetsOfDecisionTree f tree = + match tree with + | TDSwitch (sp, e, cases, dflt, m) -> + let casesR = cases |> List.map (mapTargetsOfDecisionTreeCase f) + let dfltR = Option.map (mapTargetsOfDecisionTree f) dflt + TDSwitch (sp, e, casesR, dfltR, m) + | TDSuccess (es, i) -> TDSuccess(es, f i) + | TDBind (bind, rest) -> TDBind(bind, mapTargetsOfDecisionTree f rest) + +and mapTargetsOfDecisionTreeCase f (TCase(x, t)) = + TCase(x, mapTargetsOfDecisionTree f t) + +// Dead target elimination +let eliminateDeadTargetsFromMatch tree (targets:_[]) = + let used = accTargetsOfDecisionTree tree [] |> ListSet.setify (=) |> Array.ofList + if used.Length < targets.Length then + Array.sortInPlace used + let ntargets = targets.Length + let tree' = + let remap = Array.create ntargets -1 + Array.iteri (fun i tgn -> remap.[tgn] <- i) used + tree |> mapTargetsOfDecisionTree (fun tgn -> + if remap.[tgn] = -1 then failwith "eliminateDeadTargetsFromMatch: failure while eliminating unused targets" + remap.[tgn]) + let targets' = Array.map (Array.get targets) used + tree', targets' + else + tree, targets + +let rec targetOfSuccessDecisionTree tree = + match tree with + | TDSwitch _ -> None + | TDSuccess (_, i) -> Some i + | TDBind(_, t) -> targetOfSuccessDecisionTree t + +/// Check a decision tree only has bindings that immediately cover a 'Success' +let rec decisionTreeHasNonTrivialBindings tree = + match tree with + | TDSwitch (_, _, cases, dflt, _) -> + cases |> List.exists (fun c -> decisionTreeHasNonTrivialBindings c.CaseTree) || + dflt |> Option.exists decisionTreeHasNonTrivialBindings + | TDSuccess _ -> false + | TDBind (_, t) -> Option.isNone (targetOfSuccessDecisionTree t) + +// If a target has assignments and can only be reached through one +// branch (i.e. is "linear"), then transfer the assignments to the r.h.s. to be a "let". +let foldLinearBindingTargetsOfMatch tree (targets: _[]) = + + // Don't do this when there are any bindings in the tree except where those bindings immediately cover a success node + // since the variables would be extruded from their scope. + if decisionTreeHasNonTrivialBindings tree then + tree, targets + + else + let branchesToTargets = Array.create targets.Length [] + // Build a map showing how each target might be reached + let rec accumulateTipsOfDecisionTree accBinds tree = + match tree with + | TDSwitch (_, _, cases, dflt, _) -> + assert (isNil accBinds) // No switches under bindings + for edge in cases do + accumulateTipsOfDecisionTree accBinds edge.CaseTree + match dflt with + | None -> () + | Some tree -> accumulateTipsOfDecisionTree accBinds tree + | TDSuccess (es, i) -> + branchesToTargets.[i] <- (List.rev accBinds, es) :: branchesToTargets.[i] + | TDBind (bind, rest) -> + accumulateTipsOfDecisionTree (bind :: accBinds) rest + + // Compute the targets that can only be reached one way + accumulateTipsOfDecisionTree [] tree + let isLinearTarget bs = match bs with [_] -> true | _ -> false + let isLinearTgtIdx i = isLinearTarget branchesToTargets.[i] + let getLinearTgtIdx i = branchesToTargets.[i].Head + let hasLinearTgtIdx = branchesToTargets |> Array.exists isLinearTarget + + if not hasLinearTgtIdx then + + tree, targets + + else + + /// rebuild the decision tree, replacing 'bind-then-success' decision trees by TDSuccess nodes that just go to the target + let rec rebuildDecisionTree tree = + + // Check if this is a bind-then-success tree + match targetOfSuccessDecisionTree tree with + | Some i when isLinearTgtIdx i -> TDSuccess([], i) + | _ -> + match tree with + | TDSwitch (sp, e, cases, dflt, m) -> + let casesR = List.map rebuildDecisionTreeEdge cases + let dfltR = Option.map rebuildDecisionTree dflt + TDSwitch (sp, e, casesR, dfltR, m) + | TDSuccess _ -> tree + | TDBind _ -> tree + + and rebuildDecisionTreeEdge (TCase(x, t)) = + TCase(x, rebuildDecisionTree t) + + let tree' = rebuildDecisionTree tree + + /// rebuild the targets, replacing linear targets by ones that include all the 'let' bindings from the source + let targets' = + targets |> Array.mapi (fun i (TTarget(vs, exprTarget, spTarget, _) as tg) -> + if isLinearTgtIdx i then + let binds, es = getLinearTgtIdx i + // The value bindings are moved to become part of the target. + // Hence the expressions in the value bindings can be remarked with the range of the target. + let mTarget = exprTarget.Range + let es = es |> List.map (remarkExpr mTarget) + // These are non-sticky - any sequence point for 'exprTarget' goes on 'exprTarget' _after_ the bindings have been evaluated + TTarget(List.empty, mkLetsBind mTarget binds (mkInvisibleLetsFromBindings mTarget vs es exprTarget), spTarget, None) + else tg ) + + tree', targets' + +// Simplify a little as we go, including dead target elimination +let rec simplifyTrivialMatch spBind exprm matchm ty tree (targets : _[]) = + match tree with + | TDSuccess(es, n) -> + if n >= targets.Length then failwith "simplifyTrivialMatch: target out of range" + // REVIEW: should we use _spTarget here? + let (TTarget(vs, rhs, _spTarget, _)) = targets.[n] + if vs.Length <> es.Length then failwith ("simplifyTrivialMatch: invalid argument, n = " + string n + ", List.length targets = " + string targets.Length) + // These are non-sticky - any sequence point for 'rhs' goes on 'rhs' _after_ the bindings have been made + mkInvisibleLetsFromBindings rhs.Range vs es rhs + | _ -> + primMkMatch (spBind, exprm, tree, targets, matchm, ty) + +// Simplify a little as we go, including dead target elimination +let mkAndSimplifyMatch spBind exprm matchm ty tree targets = + let targets = Array.ofList targets + match tree with + | TDSuccess _ -> + simplifyTrivialMatch spBind exprm matchm ty tree targets + | _ -> + let tree, targets = eliminateDeadTargetsFromMatch tree targets + let tree, targets = foldLinearBindingTargetsOfMatch tree targets + simplifyTrivialMatch spBind exprm matchm ty tree targets + +//------------------------------------------------------------------------- +// mkExprAddrOfExprAux +//------------------------------------------------------------------------- + +type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates +exception DefensiveCopyWarning of string * range + +let isRecdOrStructTyconRefAssumedImmutable (g: TcGlobals) (tcref: TyconRef) = + (tcref.CanDeref && not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref)) || + tyconRefEq g tcref g.decimal_tcr || + tyconRefEq g tcref g.date_tcr + +let isTyconRefReadOnly g m (tcref: TyconRef) = + tcref.CanDeref && + if + match tcref.TryIsReadOnly with + | ValueSome res -> res + | _ -> + let res = TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref + tcref.SetIsReadOnly res + res + then true + else tcref.IsEnumTycon + +let isTyconRefAssumedReadOnly g (tcref: TyconRef) = + tcref.CanDeref && + match tcref.TryIsAssumedReadOnly with + | ValueSome res -> res + | _ -> + let res = isRecdOrStructTyconRefAssumedImmutable g tcref + tcref.SetIsAssumedReadOnly res + res + +let isRecdOrStructTyconRefReadOnlyAux g m isInref (tcref: TyconRef) = + if isInref && tcref.IsILStructOrEnumTycon then + isTyconRefReadOnly g m tcref + else + isTyconRefReadOnly g m tcref || isTyconRefAssumedReadOnly g tcref + +let isRecdOrStructTyconRefReadOnly g m tcref = + isRecdOrStructTyconRefReadOnlyAux g m false tcref + +let isRecdOrStructTyReadOnlyAux (g: TcGlobals) m isInref ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> isRecdOrStructTyconRefReadOnlyAux g m isInref tcref + +let isRecdOrStructTyReadOnly g m ty = + isRecdOrStructTyReadOnlyAux g m false ty + +let CanTakeAddressOf g m isInref ty mut = + match mut with + | NeverMutates -> true + | PossiblyMutates -> isRecdOrStructTyReadOnlyAux g m isInref ty + | DefinitelyMutates -> false + | AddressOfOp -> true // you can take the address but you might get a (readonly) inref as a result + +// We can take the address of values of struct type even if the value is immutable +// under certain conditions +// - all instances of the type are known to be immutable; OR +// - the operation is known not to mutate +// +// Note this may be taking the address of a closure field, i.e. a copy +// of the original struct, e.g. for +// let f () = +// let g1 = A.G(1) +// (fun () -> g1.x1) +// +// Note: isRecdOrStructTyReadOnly implies PossiblyMutates or NeverMutates +// +// We only do this for true local or closure fields because we can't take addresses of immutable static +// fields across assemblies. +let CanTakeAddressOfImmutableVal (g: TcGlobals) m (vref: ValRef) mut = + // We can take the address of values of struct type if the operation doesn't mutate + // and the value is a true local or closure field. + not vref.IsMutable && + not vref.IsMemberOrModuleBinding && + // Note: We can't add this: + // || valRefInThisAssembly g.compilingFslib vref + // This is because we don't actually guarantee to generate static backing fields for all values like these, e.g. simple constants "let x = 1". + // We always generate a static property but there is no field to take an address of + CanTakeAddressOf g m false vref.Type mut + +let MustTakeAddressOfVal (g: TcGlobals) (vref: ValRef) = + vref.IsMutable && + // We can only take the address of mutable values in the same assembly + valRefInThisAssembly g.compilingFslib vref + +let MustTakeAddressOfByrefGet (g: TcGlobals) (vref: ValRef) = + isByrefTy g vref.Type && not (isInByrefTy g vref.Type) + +let CanTakeAddressOfByrefGet (g: TcGlobals) (vref: ValRef) mut = + isInByrefTy g vref.Type && + CanTakeAddressOf g vref.Range true (destByrefTy g vref.Type) mut + +let MustTakeAddressOfRecdField (rfref: RecdField) = + // Static mutable fields must be private, hence we don't have to take their address + not rfref.IsStatic && + rfref.IsMutable + +let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField + +let CanTakeAddressOfRecdFieldRef (g: TcGlobals) m (rfref: RecdFieldRef) tinst mut = + // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields + entityRefInThisAssembly g.compilingFslib rfref.TyconRef && + not rfref.RecdField.IsMutable && + CanTakeAddressOf g m false (actualTyOfRecdFieldRef rfref tinst) mut + +let CanTakeAddressOfUnionFieldRef (g: TcGlobals) m (uref: UnionCaseRef) cidx tinst mut = + // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields + entityRefInThisAssembly g.compilingFslib uref.TyconRef && + let rfref = uref.FieldByIndex cidx + not rfref.IsMutable && + CanTakeAddressOf g m false (actualTyOfUnionFieldRef uref cidx tinst) mut + +let mkDerefAddrExpr mAddrGet expr mExpr exprTy = + let v, _ = mkCompGenLocal mAddrGet "byrefReturn" exprTy + mkCompGenLet mExpr v expr (mkAddrGet mAddrGet (mkLocalValRef v)) + +/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope. +/// Also return a flag that indicates if the resulting pointer is a not a pointer where writing is allowed and will +/// have intended effect (i.e. is a readonly pointer and/or a defensive copy). +let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut expr addrExprVal m = + if mustTakeAddress then + let isNativePtr = + match addrExprVal with + | Some vf -> valRefEq g vf g.addrof2_vref + | _ -> false + + // If we are taking the native address using "&&" to get a nativeptr, disallow if it's readonly. + let checkTakeNativeAddress readonly = + if isNativePtr && readonly then + error(Error(FSComp.SR.tastValueMustBeMutable(), m)) + + match expr with + // LVALUE of "*x" where "x" is byref is just the byref itself + | Expr.Op (TOp.LValueOp (LByrefGet, vref), _, [], m) when MustTakeAddressOfByrefGet g vref || CanTakeAddressOfByrefGet g vref mut -> + let readonly = not (MustTakeAddressOfByrefGet g vref) + let writeonly = isOutByrefTy g vref.Type + None, exprForValRef m vref, readonly, writeonly + + // LVALUE of "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate. + // Note: we can always take the address of mutable intra-assembly values + | Expr.Val (vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut -> + let readonly = not (MustTakeAddressOfVal g vref) + let writeonly = false + checkTakeNativeAddress readonly + None, mkValAddr m readonly vref, readonly, writeonly + + // LVALUE of "e.f" where "f" is an instance F# field or record field. + | Expr.Op (TOp.ValFieldGet rfref, tinst, [objExpr], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut -> + let objTy = tyOfExpr g objExpr + let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken + let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m + let readonly = readonly || isInByrefTy g objTy || not (MustTakeAddressOfRecdFieldRef rfref) + let writeonly = writeonly || isOutByrefTy g objTy + wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly, writeonly + + // LVALUE of "f" where "f" is a static F# field. + | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut -> + let readonly = not (MustTakeAddressOfRecdFieldRef rfref) + let writeonly = false + None, mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m), readonly, writeonly + + // LVALUE of "e.f" where "f" is an F# union field. + | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [objExpr], m) when MustTakeAddressOfRecdField (uref.FieldByIndex cidx) || CanTakeAddressOfUnionFieldRef g m uref cidx tinst mut -> + let objTy = tyOfExpr g objExpr + let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken + let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m + let readonly = readonly || isInByrefTy g objTy || not (MustTakeAddressOfRecdField (uref.FieldByIndex cidx)) + let writeonly = writeonly || isOutByrefTy g objTy + wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly, writeonly + + // LVALUE of "f" where "f" is a .NET static field. + | Expr.Op (TOp.ILAsm ([I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) -> + let readonly = false // we never consider taking the address of a .NET static field to give an inref pointer + let writeonly = false + None, Expr.Op (TOp.ILAsm ([I_ldsflda fspec], [mkByrefTy g ty2]), tinst, [], m), readonly, writeonly + + // LVALUE of "e.f" where "f" is a .NET instance field. + | Expr.Op (TOp.ILAsm ([I_ldfld (_align, _vol, fspec)], [ty2]), tinst, [objExpr], m) -> + let objTy = tyOfExpr g objExpr + let takeAddrOfObjExpr = isStructTy g objTy // It seems this will always be false - the address will already have been taken + // we never consider taking the address of an .NET instance field to give an inref pointer, unless the object pointer is an inref pointer + let wrap, expra, readonly, writeonly = mkExprAddrOfExprAux g takeAddrOfObjExpr false mut objExpr None m + let readonly = readonly || isInByrefTy g objTy + let writeonly = writeonly || isOutByrefTy g objTy + wrap, Expr.Op (TOp.ILAsm ([I_ldflda fspec], [mkByrefTyWithFlag g readonly ty2]), tinst, [expra], m), readonly, writeonly + + // LVALUE of "e.[n]" where e is an array of structs + | Expr.App (Expr.Val (vf, _, _), _, [elemTy], [aexpr;nexpr], _) when (valRefEq g vf g.array_get_vref) -> + + let readonly = false // array address is never forced to be readonly + let writeonly = false + let shape = ILArrayShape.SingleDimensional + let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress + None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [aexpr; nexpr], m), readonly, writeonly + + // LVALUE of "e.[n1, n2]", "e.[n1, n2, n3]", "e.[n1, n2, n3, n4]" where e is an array of structs + | Expr.App (Expr.Val (vref, _, _), _, [elemTy], aexpr :: args, _) + when (valRefEq g vref g.array2D_get_vref || valRefEq g vref g.array3D_get_vref || valRefEq g vref g.array4D_get_vref) -> + + let readonly = false // array address is never forced to be readonly + let writeonly = false + let shape = ILArrayShape.FromRank args.Length + let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress + None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr :: args), m), readonly, writeonly + + // LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]". + | Expr.Let (TBind(vref, e, _), Expr.Op (TOp.LValueOp (LByrefGet, vref2), _, _, _), _, _) + when (valRefEq g (mkLocalValRef vref) vref2) && + (MustTakeAddressOfByrefGet g vref2 || CanTakeAddressOfByrefGet g vref2 mut) -> + let ty = tyOfExpr g e + let readonly = isInByrefTy g ty + let writeonly = isOutByrefTy g ty + None, e, readonly, writeonly + + // Give a nice error message for address-of-byref + | Expr.Val (vref, _, m) when isByrefTy g vref.Type -> + error(Error(FSComp.SR.tastUnexpectedByRef(), m)) + + // Give a nice error message for DefinitelyMutates of address-of on mutable values in other assemblies + | Expr.Val (vref, _, m) when (mut = DefinitelyMutates || mut = AddressOfOp) && vref.IsMutable -> + error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m)) + + // Give a nice error message for AddressOfOp on immutable values + | Expr.Val _ when mut = AddressOfOp -> + error(Error(FSComp.SR.tastValueMustBeLocal(), m)) + + // Give a nice error message for mutating a value we can't take the address of + | Expr.Val _ when mut = DefinitelyMutates -> + error(Error(FSComp.SR.tastValueMustBeMutable(), m)) + + | _ -> + let ty = tyOfExpr g expr + if isStructTy g ty then + match mut with + | NeverMutates + | AddressOfOp -> () + | DefinitelyMutates -> + // Give a nice error message for mutating something we can't take the address of + errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)) + | PossiblyMutates -> + // Warn on defensive copy of something we can't take the address of + warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)) + + match mut with + | NeverMutates + | DefinitelyMutates + | PossiblyMutates -> () + | AddressOfOp -> + // we get an inref + errorR(Error(FSComp.SR.tastCantTakeAddressOfExpression(), m)) + + // Take a defensive copy + let tmp, _ = + match mut with + | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty + | _ -> mkMutableCompGenLocal m "copyOfStruct" ty + + // This local is special in that it ignore byref scoping rules. + tmp.SetIgnoresByrefScope() + + let readonly = true + let writeonly = false + Some (tmp, expr), (mkValAddr m readonly (mkLocalValRef tmp)), readonly, writeonly + else + None, expr, false, false + +let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = + let optBind, addre, readonly, writeonly = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m + match optBind with + | None -> (fun x -> x), addre, readonly, writeonly + | Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre, readonly, writeonly + +let mkTupleFieldGet g (tupInfo, e, tinst, i, m) = + let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalTupInfoIsStruct tupInfo) false NeverMutates e None m + wrap (mkTupleFieldGetViaExprAddr(tupInfo, e', tinst, i, m)) + +let mkAnonRecdFieldGet g (anonInfo: AnonRecdTypeInfo, e, tinst, i, m) = + let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalAnonInfoIsStruct anonInfo) false NeverMutates e None m + wrap (mkAnonRecdFieldGetViaExprAddr(anonInfo, e', tinst, i, m)) + +let mkRecdFieldGet g (e, fref: RecdFieldRef, tinst, m) = + assert (not (isByrefTy g (tyOfExpr g e))) + let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m + wrap (mkRecdFieldGetViaExprAddr (e', fref, tinst, m)) + +let mkUnionCaseFieldGetUnproven g (e, cref: UnionCaseRef, tinst, j, m) = + assert (not (isByrefTy g (tyOfExpr g e))) + let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g cref.Tycon.IsStructOrEnumTycon false NeverMutates e None m + wrap (mkUnionCaseFieldGetUnprovenViaExprAddr (e', cref, tinst, j, m)) + +let mkArray (argty, args, m) = Expr.Op (TOp.Array, [argty], args, m) + +//--------------------------------------------------------------------------- +// Compute fixups for letrec's. +// +// Generate an assignment expression that will fixup the recursion +// amongst the vals on the r.h.s. of a letrec. The returned expressions +// include disorderly constructs such as expressions/statements +// to set closure environments and non-mutable fields. These are only ever +// generated by the backend code-generator when processing a "letrec" +// construct. +// +// [self] is the top level value that is being fixed +// [exprToFix] is the r.h.s. expression +// [rvs] is the set of recursive vals being bound. +// [acc] accumulates the expression right-to-left. +// +// Traversal of the r.h.s. term must happen back-to-front to get the +// uniq's for the lambdas correct in the very rare case where the same lambda +// somehow appears twice on the right. +//--------------------------------------------------------------------------- + +let rec IterateRecursiveFixups g (selfv: Val option) rvs (access: Expr, set) exprToFix = + let exprToFix = stripExpr exprToFix + match exprToFix with + | Expr.Const _ -> () + | Expr.Op (TOp.Tuple tupInfo, argtys, args, m) when not (evalTupInfoIsStruct tupInfo) -> + args |> List.iteri (fun n -> + IterateRecursiveFixups g None rvs + (mkTupleFieldGet g (tupInfo, access, argtys, n, m), + (fun e -> + // NICE: it would be better to do this check in the type checker + errorR(Error(FSComp.SR.tastRecursiveValuesMayNotBeInConstructionOfTuple(), m)) + e))) + + | Expr.Op (TOp.UnionCase c, tinst, args, m) -> + args |> List.iteri (fun n -> + IterateRecursiveFixups g None rvs + (mkUnionCaseFieldGetUnprovenViaExprAddr (access, c, tinst, n, m), + (fun e -> + // NICE: it would be better to do this check in the type checker + let tcref = c.TyconRef + if not (c.FieldByIndex n).IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then + errorR(Error(FSComp.SR.tastRecursiveValuesMayNotAppearInConstructionOfType(tcref.LogicalName), m)) + mkUnionCaseFieldSet (access, c, tinst, n, e, m)))) + + | Expr.Op (TOp.Recd (_, tcref), tinst, args, m) -> + (tcref.TrueInstanceFieldsAsRefList, args) ||> List.iter2 (fun fref arg -> + let fspec = fref.RecdField + IterateRecursiveFixups g None rvs + (mkRecdFieldGetViaExprAddr (access, fref, tinst, m), + (fun e -> + // NICE: it would be better to do this check in the type checker + if not fspec.IsMutable && not (entityRefInThisAssembly g.compilingFslib tcref) then + errorR(Error(FSComp.SR.tastRecursiveValuesMayNotBeAssignedToNonMutableField(fspec.rfield_id.idText, tcref.LogicalName), m)) + mkRecdFieldSetViaExprAddr (access, fref, tinst, e, m))) arg ) + | Expr.Val _ + | Expr.Lambda _ + | Expr.Obj _ + | Expr.TyChoose _ + | Expr.TyLambda _ -> + rvs selfv access set exprToFix + | _ -> () + +//-------------------------------------------------------------------------- +// computations on constraints +//-------------------------------------------------------------------------- + +let JoinTyparStaticReq r1 r2 = + match r1, r2 with + | TyparStaticReq.None, r | r, TyparStaticReq.None -> r + | TyparStaticReq.HeadType, r | r, TyparStaticReq.HeadType -> r + +//------------------------------------------------------------------------- +// ExprFolder - fold steps +//------------------------------------------------------------------------- + +type ExprFolder<'State> = + { exprIntercept : (* recurseF *) ('State -> Expr -> 'State) -> (* noInterceptF *) ('State -> Expr -> 'State) -> 'State -> Expr -> 'State + // the bool is 'bound in dtree' + valBindingSiteIntercept : 'State -> bool * Val -> 'State + // these values are always bound to these expressions. bool indicates 'recursively' + nonRecBindingsIntercept : 'State -> Binding -> 'State + recBindingsIntercept : 'State -> Bindings -> 'State + dtreeIntercept : 'State -> DecisionTree -> 'State + targetIntercept : (* recurseF *) ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option + tmethodIntercept : (* recurseF *) ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option + } + +let ExprFolder0 = + { exprIntercept = (fun _recurseF noInterceptF z x -> noInterceptF z x) + valBindingSiteIntercept = (fun z _b -> z) + nonRecBindingsIntercept = (fun z _bs -> z) + recBindingsIntercept = (fun z _bs -> z) + dtreeIntercept = (fun z _dt -> z) + targetIntercept = (fun _exprF _z _x -> None) + tmethodIntercept = (fun _exprF _z _x -> None) } + +//------------------------------------------------------------------------- +// FoldExpr +//------------------------------------------------------------------------- + +/// Adapted from usage info folding. +/// Collecting from exprs at moment. +/// To collect ids etc some additional folding needed, over formals etc. +type ExprFolders<'State> (folders: ExprFolder<'State>) = + let mutable exprFClosure = Unchecked.defaultof<'State -> Expr -> 'State> // prevent reallocation of closure + let mutable exprNoInterceptFClosure = Unchecked.defaultof<'State -> Expr -> 'State> // prevent reallocation of closure + + let rec exprsF z xs = + List.fold exprFClosure z xs + + and exprF (z: 'State) (x: Expr) = + folders.exprIntercept exprFClosure exprNoInterceptFClosure z x + + and exprNoInterceptF (z: 'State) (x: Expr) = + match x with + + | Expr.Const _ -> z + + | Expr.Val _ -> z + + | LinearOpExpr (_op, _tyargs, argsHead, argLast, _m) -> + let z = exprsF z argsHead + // tailcall + exprF z argLast + + | Expr.Op (_c, _tyargs, args, _) -> + exprsF z args + + | Expr.Sequential (x0, x1, _dir, _, _) -> + let z = exprF z x0 + exprF z x1 + + | Expr.Lambda (_lambdaId, _ctorThisValOpt, _baseValOpt, _argvs, body, _m, _rty) -> + exprF z body + + | Expr.TyLambda (_lambdaId, _argtyvs, body, _m, _rty) -> + exprF z body + + | Expr.TyChoose (_, body, _) -> + exprF z body + + | Expr.App (f, _fty, _tys, argtys, _) -> + let z = exprF z f + exprsF z argtys + + | Expr.LetRec (binds, body, _, _) -> + let z = valBindsF false z binds + exprF z body + + | Expr.Let (bind, body, _, _) -> + let z = valBindF false z bind + exprF z body + + | Expr.Link rX -> exprF z (!rX) + + | Expr.Match (_spBind, _exprm, dtree, targets, _m, _ty) -> + let z = dtreeF z dtree + let z = Array.fold targetF z targets.[0..targets.Length - 2] + // tailcall + targetF z targets.[targets.Length - 1] + + | Expr.Quote (e, dataCell, _, _, _) -> + let z = exprF z e + match dataCell.Value with + | None -> z + | Some ((_typeDefs, _argTypes, argExprs, _), _) -> exprsF z argExprs + + | Expr.Obj (_n, _typ, _basev, basecall, overrides, iimpls, _m) -> + let z = exprF z basecall + let z = List.fold tmethodF z overrides + List.fold (foldOn snd (List.fold tmethodF)) z iimpls + + | Expr.StaticOptimization (_tcs, csx, x, _) -> + exprsF z [csx;x] + + | Expr.WitnessArg (_witnessInfo, _m) -> + z + + and valBindF dtree z bind = + let z = folders.nonRecBindingsIntercept z bind + bindF dtree z bind + + and valBindsF dtree z binds = + let z = folders.recBindingsIntercept z binds + List.fold (bindF dtree) z binds + + and bindF dtree z (bind: Binding) = + let z = folders.valBindingSiteIntercept z (dtree, bind.Var) + exprF z bind.Expr + + and dtreeF z dtree = + let z = folders.dtreeIntercept z dtree + match dtree with + | TDBind (bind, rest) -> + let z = valBindF true z bind + dtreeF z rest + | TDSuccess (args, _) -> exprsF z args + | TDSwitch (_, test, dcases, dflt, _) -> + let z = exprF z test + let z = List.fold dcaseF z dcases + let z = Option.fold dtreeF z dflt + z + + and dcaseF z = function + TCase (_, dtree) -> dtreeF z dtree (* not collecting from test *) + + and targetF z x = + match folders.targetIntercept exprFClosure z x with + | Some z -> z // intercepted + | None -> // structurally recurse + let (TTarget (_, body, _, _)) = x + exprF z body + + and tmethodF z x = + match folders.tmethodIntercept exprFClosure z x with + | Some z -> z // intercepted + | None -> // structurally recurse + let (TObjExprMethod(_, _, _, _, e, _)) = x + exprF z e + + and mexprF z x = + match x with + | ModuleOrNamespaceExprWithSig(_, def, _) -> mdefF z def + + and mdefF z x = + match x with + | TMDefRec(_, _, _, mbinds, _) -> + // REVIEW: also iterate the abstract slot vspecs hidden in the _vslots field in the tycons + let z = List.fold mbindF z mbinds + z + | TMDefLet(bind, _) -> valBindF false z bind + | TMDefOpens _ -> z + | TMDefDo(e, _) -> exprF z e + | TMDefs defs -> List.fold mdefF z defs + | TMAbstract x -> mexprF z x + + and mbindF z x = + match x with + | ModuleOrNamespaceBinding.Binding b -> valBindF false z b + | ModuleOrNamespaceBinding.Module(_, def) -> mdefF z def + + and implF z x = foldTImplFile mexprF z x + + do exprFClosure <- exprF // allocate one instance of this closure + do exprNoInterceptFClosure <- exprNoInterceptF // allocate one instance of this closure + + member x.FoldExpr = exprF + + member x.FoldImplFile = implF + +let FoldExpr folders state expr = ExprFolders(folders).FoldExpr state expr + +let FoldImplFile folders state implFile = ExprFolders(folders).FoldImplFile state implFile + +#if DEBUG +//------------------------------------------------------------------------- +// ExprStats +//------------------------------------------------------------------------- + +let ExprStats x = + let mutable count = 0 + let folders = {ExprFolder0 with exprIntercept = (fun _ noInterceptF z x -> (count <- count + 1; noInterceptF z x))} + let () = FoldExpr folders () x + string count + " TExpr nodes" +#endif + +//------------------------------------------------------------------------- +// Make expressions +//------------------------------------------------------------------------- + +let mkString (g: TcGlobals) m n = Expr.Const (Const.String n, m, g.string_ty) + +let mkByte (g: TcGlobals) m b = Expr.Const (Const.Byte b, m, g.byte_ty) + +let mkUInt16 (g: TcGlobals) m b = Expr.Const (Const.UInt16 b, m, g.uint16_ty) + +let mkUnit (g: TcGlobals) m = Expr.Const (Const.Unit, m, g.unit_ty) + +let mkInt32 (g: TcGlobals) m n = Expr.Const (Const.Int32 n, m, g.int32_ty) + +let mkInt g m n = mkInt32 g m n + +let mkZero g m = mkInt g m 0 + +let mkOne g m = mkInt g m 1 + +let mkTwo g m = mkInt g m 2 + +let mkMinusOne g m = mkInt g m -1 + +let destInt32 = function Expr.Const (Const.Int32 n, _, _) -> Some n | _ -> None + +let isIDelegateEventType g ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tyconRefEq g g.fslib_IDelegateEvent_tcr tcref + | _ -> false + +let destIDelegateEventType g ty = + if isIDelegateEventType g ty then + match argsOfAppTy g ty with + | [ty1] -> ty1 + | _ -> failwith "destIDelegateEventType: internal error" + else failwith "destIDelegateEventType: not an IDelegateEvent type" + +let mkIEventType (g: TcGlobals) ty1 ty2 = TType_app (g.fslib_IEvent2_tcr, [ty1;ty2]) + +let mkIObservableType (g: TcGlobals) ty1 = TType_app (g.tcref_IObservable, [ty1]) + +let mkIObserverType (g: TcGlobals) ty1 = TType_app (g.tcref_IObserver, [ty1]) + +let mkRefCellContentsRef (g: TcGlobals) = mkRecdFieldRef g.refcell_tcr_canon "contents" + +let mkSequential spSeq m e1 e2 = Expr.Sequential (e1, e2, NormalSeq, spSeq, m) + +let mkCompGenSequential m stmt expr = mkSequential DebugPointAtSequential.SuppressStmt m stmt expr + +let mkThenDoSequential spSeq m expr stmt = Expr.Sequential (expr, stmt, ThenDoSeq, spSeq, m) + +let mkCompGenThenDoSequential m expr stmt = mkThenDoSequential DebugPointAtSequential.SuppressStmt m expr stmt + +let rec mkSequentials spSeq g m es = + match es with + | [e] -> e + | e :: es -> mkSequential spSeq m e (mkSequentials spSeq g m es) + | [] -> mkUnit g m + +let mkGetArg0 m ty = mkAsmExpr ( [ mkLdarg0 ], [], [], [ty], m) + +//------------------------------------------------------------------------- +// Tuples... +//------------------------------------------------------------------------- + +let mkAnyTupled g m tupInfo es tys = + match es with + | [] -> mkUnit g m + | [e] -> e + | _ -> Expr.Op (TOp.Tuple tupInfo, tys, es, m) + +let mkRefTupled g m es tys = mkAnyTupled g m tupInfoRef es tys + +let mkRefTupledNoTypes g m args = mkRefTupled g m args (List.map (tyOfExpr g) args) + +let mkRefTupledVars g m vs = mkRefTupled g m (List.map (exprForVal m) vs) (typesOfVals vs) + +//-------------------------------------------------------------------------- +// Permute expressions +//-------------------------------------------------------------------------- + +let inversePerm (sigma: int array) = + let n = sigma.Length + let invSigma = Array.create n -1 + for i = 0 to n-1 do + let sigma_i = sigma.[i] + // assert( invSigma.[sigma_i] = -1 ) + invSigma.[sigma_i] <- i + invSigma + +let permute (sigma: int[]) (data:'T[]) = + let n = sigma.Length + let invSigma = inversePerm sigma + Array.init n (fun i -> data.[invSigma.[i]]) + +let rec existsR a b pred = if a<=b then pred a || existsR (a+1) b pred else false + +// Given a permutation for record fields, work out the highest entry that we must lift out +// of a record initialization. Lift out xi if xi goes to position that will be preceded by an expr with an effect +// that originally followed xi. If one entry gets lifted then everything before it also gets lifted. +let liftAllBefore sigma = + let invSigma = inversePerm sigma + + let lifted = + [ for i in 0 .. sigma.Length - 1 do + let i' = sigma.[i] + if existsR 0 (i' - 1) (fun j' -> invSigma.[j'] > i) then + yield i ] + + if lifted.IsEmpty then 0 else List.max lifted + 1 + + +/// Put record field assignments in order. +// +let permuteExprList (sigma: int[]) (exprs: Expr list) (ty: TType list) (names: string list) = + let ty, names = (Array.ofList ty, Array.ofList names) + + let liftLim = liftAllBefore sigma + + let rewrite rbinds (i, expri: Expr) = + if i < liftLim then + let tmpvi, tmpei = mkCompGenLocal expri.Range names.[i] ty.[i] + let bindi = mkCompGenBind tmpvi expri + tmpei, bindi :: rbinds + else + expri, rbinds + + let newExprs, reversedBinds = List.mapFold rewrite [] (exprs |> List.indexed) + let binds = List.rev reversedBinds + let reorderedExprs = permute sigma (Array.ofList newExprs) + binds, Array.toList reorderedExprs + +/// Evaluate the expressions in the original order, but build a record with the results in field order +/// Note some fields may be static. If this were not the case we could just use +/// let sigma = Array.map #Index () +/// However the presence of static fields means .Index may index into a non-compact set of instance field indexes. +/// We still need to sort by index. +let mkRecordExpr g (lnk, tcref, tinst, unsortedRecdFields: RecdFieldRef list, unsortedFieldExprs, m) = + // Remove any abbreviations + let tcref, tinst = destAppTy g (mkAppTy tcref tinst) + + let sortedRecdFields = unsortedRecdFields |> List.indexed |> Array.ofList |> Array.sortBy (fun (_, r) -> r.Index) + let sigma = Array.create sortedRecdFields.Length -1 + sortedRecdFields |> Array.iteri (fun sortedIdx (unsortedIdx, _) -> + if sigma.[unsortedIdx] <> -1 then error(InternalError("bad permutation", m)) + sigma.[unsortedIdx] <- sortedIdx) + + let unsortedArgTys = unsortedRecdFields |> List.map (fun rfref -> actualTyOfRecdFieldRef rfref tinst) + let unsortedArgNames = unsortedRecdFields |> List.map (fun rfref -> rfref.FieldName) + let unsortedArgBinds, sortedArgExprs = permuteExprList sigma unsortedFieldExprs unsortedArgTys unsortedArgNames + let core = Expr.Op (TOp.Recd (lnk, tcref), tinst, sortedArgExprs, m) + mkLetsBind m unsortedArgBinds core + +let mkAnonRecd (_g: TcGlobals) m (anonInfo: AnonRecdTypeInfo) (unsortedIds: Ident[]) (unsortedFieldExprs: Expr list) unsortedArgTys = + let sortedRecdFields = unsortedFieldExprs |> List.indexed |> Array.ofList |> Array.sortBy (fun (i,_) -> unsortedIds.[i].idText) + let sortedArgTys = unsortedArgTys |> List.indexed |> List.sortBy (fun (i,_) -> unsortedIds.[i].idText) |> List.map snd + + let sigma = Array.create sortedRecdFields.Length -1 + sortedRecdFields |> Array.iteri (fun sortedIdx (unsortedIdx, _) -> + if sigma.[unsortedIdx] <> -1 then error(InternalError("bad permutation", m)) + sigma.[unsortedIdx] <- sortedIdx) + + let unsortedArgNames = unsortedIds |> Array.toList |> List.map (fun id -> id.idText) + let unsortedArgBinds, sortedArgExprs = permuteExprList sigma unsortedFieldExprs unsortedArgTys unsortedArgNames + let core = Expr.Op (TOp.AnonRecd anonInfo, sortedArgTys, sortedArgExprs, m) + mkLetsBind m unsortedArgBinds core + +//------------------------------------------------------------------------- +// List builders +//------------------------------------------------------------------------- + +let mkRefCell g m ty e = mkRecordExpr g (RecdExpr, g.refcell_tcr_canon, [ty], [mkRefCellContentsRef g], [e], m) + +let mkRefCellGet g m ty e = mkRecdFieldGetViaExprAddr (e, mkRefCellContentsRef g, [ty], m) + +let mkRefCellSet g m ty e1 e2 = mkRecdFieldSetViaExprAddr (e1, mkRefCellContentsRef g, [ty], e2, m) + +let mkNil (g: TcGlobals) m ty = mkUnionCaseExpr (g.nil_ucref, [ty], [], m) + +let mkCons (g: TcGlobals) ty h t = mkUnionCaseExpr (g.cons_ucref, [ty], [h;t], unionRanges h.Range t.Range) + +let mkCompGenLocalAndInvisibleBind g nm m e = + let locv, loce = mkCompGenLocal m nm (tyOfExpr g e) + locv, loce, mkInvisibleBind locv e + +//---------------------------------------------------------------------------- +// Make some fragments of code +//---------------------------------------------------------------------------- + +let box = I_box (mkILTyvarTy 0us) + +let isinst = I_isinst (mkILTyvarTy 0us) + +let unbox = I_unbox_any (mkILTyvarTy 0us) + +let mkUnbox ty e m = mkAsmExpr ([ unbox ], [ty], [e], [ ty ], m) + +let mkBox ty e m = mkAsmExpr ([box], [], [e], [ty], m) + +let mkIsInst ty e m = mkAsmExpr ([ isinst ], [ty], [e], [ ty ], m) + +let mspec_Type_GetTypeFromHandle (g: TcGlobals) = mkILNonGenericStaticMethSpecInTy(g.ilg.typ_Type, "GetTypeFromHandle", [g.iltyp_RuntimeTypeHandle], g.ilg.typ_Type) + +let mspec_String_Length (g: TcGlobals) = mkILNonGenericInstanceMethSpecInTy (g.ilg.typ_String, "get_Length", [], g.ilg.typ_Int32) + +let mspec_String_Concat2 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat3 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat4 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat_Array (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ mkILArr1DTy g.ilg.typ_String ], g.ilg.typ_String) + +let fspec_Missing_Value (g: TcGlobals) = mkILFieldSpecInTy(g.iltyp_Missing, "Value", g.iltyp_Missing) + +let mkInitializeArrayMethSpec (g: TcGlobals) = + let tref = g.FindSysILTypeRef "System.Runtime.CompilerServices.RuntimeHelpers" + mkILNonGenericStaticMethSpecInTy(mkILNonGenericBoxedTy tref, "InitializeArray", [g.ilg.typ_Array;g.iltyp_RuntimeFieldHandle], ILType.Void) + +let mkInvalidCastExnNewobj (g: TcGlobals) = + mkNormalNewobj (mkILCtorMethSpecForTy (mkILNonGenericBoxedTy (g.FindSysILTypeRef "System.InvalidCastException"), [])) + +let typedExprForIntrinsic _g m (IntrinsicValRef(_, _, _, ty, _) as i) = + let vref = ValRefForIntrinsic i + exprForValRef m vref, ty + +let mkCallGetGenericComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_comparer_info |> fst + +let mkCallGetGenericEREqualityComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_er_equality_comparer_info |> fst + +let mkCallGetGenericPEREqualityComparer (g: TcGlobals) m = typedExprForIntrinsic g m g.get_generic_per_equality_comparer_info |> fst + +let mkCallUnbox (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unbox_info, [[ty]], [ e1 ], m) + +let mkCallUnboxFast (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unbox_fast_info, [[ty]], [ e1 ], m) + +let mkCallTypeTest (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.istype_info, [[ty]], [ e1 ], m) + +let mkCallTypeOf (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.typeof_info, [[ty]], [ ], m) + +let mkCallTypeDefOf (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.typedefof_info, [[ty]], [ ], m) + +let mkCallDispose (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.dispose_info, [[ty]], [ e1 ], m) + +let mkCallSeq (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.seq_info, [[ty]], [ e1 ], m) + +let mkCallCreateInstance (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.create_instance_info, [[ty]], [ mkUnit g m ], m) + +let mkCallGetQuerySourceAsEnumerable (g: TcGlobals) m ty1 ty2 e1 = mkApps g (typedExprForIntrinsic g m g.query_source_as_enum_info, [[ty1;ty2]], [ e1; mkUnit g m ], m) + +let mkCallNewQuerySource (g: TcGlobals) m ty1 ty2 e1 = mkApps g (typedExprForIntrinsic g m g.new_query_source_info, [[ty1;ty2]], [ e1 ], m) + +let mkCallCreateEvent (g: TcGlobals) m ty1 ty2 e1 e2 e3 = mkApps g (typedExprForIntrinsic g m g.create_event_info, [[ty1;ty2]], [ e1;e2;e3 ], m) + +let mkCallGenericComparisonWithComparerOuter (g: TcGlobals) m ty comp e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_comparison_withc_outer_info, [[ty]], [ comp;e1;e2 ], m) + +let mkCallGenericEqualityEROuter (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_equality_er_outer_info, [[ty]], [ e1;e2 ], m) + +let mkCallGenericEqualityWithComparerOuter (g: TcGlobals) m ty comp e1 e2 = mkApps g (typedExprForIntrinsic g m g.generic_equality_withc_outer_info, [[ty]], [comp;e1;e2], m) + +let mkCallGenericHashWithComparerOuter (g: TcGlobals) m ty comp e1 = mkApps g (typedExprForIntrinsic g m g.generic_hash_withc_outer_info, [[ty]], [comp;e1], m) + +let mkCallEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.equals_operator_info, [[ty]], [ e1;e2 ], m) + +let mkCallNotEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.not_equals_operator, [[ty]], [ e1;e2 ], m) + +let mkCallLessThanOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.less_than_operator, [[ty]], [ e1;e2 ], m) + +let mkCallLessThanOrEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.less_than_or_equals_operator, [[ty]], [ e1;e2 ], m) + +let mkCallGreaterThanOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.greater_than_operator, [[ty]], [ e1;e2 ], m) + +let mkCallGreaterThanOrEqualsOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.greater_than_or_equals_operator, [[ty]], [ e1;e2 ], m) + +let mkCallAdditionOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_addition_info, [[ty; ty; ty]], [e1;e2], m) + +let mkCallSubtractionOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_subtraction_info, [[ty; ty; ty]], [e1;e2], m) + +let mkCallMultiplyOperator (g: TcGlobals) m ty1 ty2 rty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_multiply_info, [[ty1; ty2; rty]], [e1;e2], m) + +let mkCallDivisionOperator (g: TcGlobals) m ty1 ty2 rty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_division_info, [[ty1; ty2; rty]], [e1;e2], m) + +let mkCallModulusOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.unchecked_modulus_info, [[ty; ty; ty]], [e1;e2], m) + +let mkCallDefaultOf (g: TcGlobals) m ty = mkApps g (typedExprForIntrinsic g m g.unchecked_defaultof_info, [[ty]], [], m) + +let mkCallBitwiseAndOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_and_info, [[ty]], [e1;e2], m) + +let mkCallBitwiseOrOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_or_info, [[ty]], [e1;e2], m) + +let mkCallBitwiseXorOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_xor_info, [[ty]], [e1;e2], m) + +let mkCallShiftLeftOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_shift_left_info, [[ty]], [e1;e2], m) + +let mkCallShiftRightOperator (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.bitwise_shift_right_info, [[ty]], [e1;e2], m) + +let mkCallUnaryNegOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unchecked_unary_minus_info, [[ty]], [e1], m) + +let mkCallUnaryNotOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.bitwise_unary_not_info, [[ty]], [e1], m) + +let mkCallAdditionChecked (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_addition_info, [[ty; ty; ty]], [e1;e2], m) + +let mkCallSubtractionChecked (g: TcGlobals) m ty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_subtraction_info, [[ty; ty; ty]], [e1;e2], m) + +let mkCallMultiplyChecked (g: TcGlobals) m ty1 ty2 rty e1 e2 = mkApps g (typedExprForIntrinsic g m g.checked_multiply_info, [[ty1; ty2; rty]], [e1;e2], m) + +let mkCallUnaryNegChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.checked_unary_minus_info, [[ty]], [e1], m) + +let mkCallToByteChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.byte_checked_info, [[ty]], [e1], m) + +let mkCallToSByteChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.sbyte_checked_info, [[ty]], [e1], m) + +let mkCallToInt16Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int16_checked_info, [[ty]], [e1], m) + +let mkCallToUInt16Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint16_checked_info, [[ty]], [e1], m) + +let mkCallToIntChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int_checked_info, [[ty]], [e1], m) + +let mkCallToInt32Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int32_checked_info, [[ty]], [e1], m) + +let mkCallToUInt32Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint32_checked_info, [[ty]], [e1], m) + +let mkCallToInt64Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int64_checked_info, [[ty]], [e1], m) + +let mkCallToUInt64Checked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint64_checked_info, [[ty]], [e1], m) + +let mkCallToIntPtrChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.nativeint_checked_info, [[ty]], [e1], m) + +let mkCallToUIntPtrChecked (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unativeint_checked_info, [[ty]], [e1], m) + +let mkCallToByteOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.byte_operator_info, [[ty]], [e1], m) + +let mkCallToSByteOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.sbyte_operator_info, [[ty]], [e1], m) + +let mkCallToInt16Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int16_operator_info, [[ty]], [e1], m) + +let mkCallToUInt16Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint16_operator_info, [[ty]], [e1], m) + +let mkCallToIntOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int_operator_info, [[ty]], [e1], m) + +let mkCallToInt32Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int32_operator_info, [[ty]], [e1], m) + +let mkCallToUInt32Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint32_operator_info, [[ty]], [e1], m) + +let mkCallToInt64Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.int64_operator_info, [[ty]], [e1], m) + +let mkCallToUInt64Operator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.uint64_operator_info, [[ty]], [e1], m) + +let mkCallToSingleOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.float32_operator_info, [[ty]], [e1], m) + +let mkCallToDoubleOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.float_operator_info, [[ty]], [e1], m) + +let mkCallToIntPtrOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.nativeint_operator_info, [[ty]], [e1], m) + +let mkCallToUIntPtrOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.unativeint_operator_info, [[ty]], [e1], m) + +let mkCallToCharOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.char_operator_info, [[ty]], [e1], m) + +let mkCallToEnumOperator (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.enum_operator_info, [[ty]], [e1], m) + +let mkCallArrayLength (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.array_length_info, [[ty]], [e1], m) + +let mkCallArrayGet (g: TcGlobals) m ty e1 idx1 = mkApps g (typedExprForIntrinsic g m g.array_get_info, [[ty]], [ e1 ; idx1 ], m) + +let mkCallArray2DGet (g: TcGlobals) m ty e1 idx1 idx2 = mkApps g (typedExprForIntrinsic g m g.array2D_get_info, [[ty]], [ e1 ; idx1; idx2 ], m) + +let mkCallArray3DGet (g: TcGlobals) m ty e1 idx1 idx2 idx3 = mkApps g (typedExprForIntrinsic g m g.array3D_get_info, [[ty]], [ e1 ; idx1; idx2; idx3 ], m) + +let mkCallArray4DGet (g: TcGlobals) m ty e1 idx1 idx2 idx3 idx4 = mkApps g (typedExprForIntrinsic g m g.array4D_get_info, [[ty]], [ e1 ; idx1; idx2; idx3; idx4 ], m) + +let mkCallArraySet (g: TcGlobals) m ty e1 idx1 v = mkApps g (typedExprForIntrinsic g m g.array_set_info, [[ty]], [ e1 ; idx1; v ], m) + +let mkCallArray2DSet (g: TcGlobals) m ty e1 idx1 idx2 v = mkApps g (typedExprForIntrinsic g m g.array2D_set_info, [[ty]], [ e1 ; idx1; idx2; v ], m) + +let mkCallArray3DSet (g: TcGlobals) m ty e1 idx1 idx2 idx3 v = mkApps g (typedExprForIntrinsic g m g.array3D_set_info, [[ty]], [ e1 ; idx1; idx2; idx3; v ], m) + +let mkCallArray4DSet (g: TcGlobals) m ty e1 idx1 idx2 idx3 idx4 v = mkApps g (typedExprForIntrinsic g m g.array4D_set_info, [[ty]], [ e1 ; idx1; idx2; idx3; idx4; v ], m) + +let mkCallHash (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.hash_info, [[ty]], [ e1 ], m) + +let mkCallBox (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.box_info, [[ty]], [ e1 ], m) + +let mkCallIsNull (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.isnull_info, [[ty]], [ e1 ], m) + +let mkCallIsNotNull (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.isnotnull_info, [[ty]], [ e1 ], m) + +let mkCallRaise (g: TcGlobals) m ty e1 = mkApps g (typedExprForIntrinsic g m g.raise_info, [[ty]], [ e1 ], m) + +let mkCallNewDecimal (g: TcGlobals) m (e1, e2, e3, e4, e5) = mkApps g (typedExprForIntrinsic g m g.new_decimal_info, [], [ e1;e2;e3;e4;e5 ], m) + +let mkCallNewFormat (g: TcGlobals) m aty bty cty dty ety formatStringExpr = + mkApps g (typedExprForIntrinsic g m g.new_format_info, [[aty;bty;cty;dty;ety]], [ formatStringExpr ], m) + +let tryMkCallBuiltInWitness (g: TcGlobals) traitInfo argExprs m = + let info, tinst = g.MakeBuiltInWitnessInfo traitInfo + let vref = ValRefForIntrinsic info + match vref.TryDeref with + | ValueSome v -> + let f = exprForValRef m vref + mkApps g ((f, v.Type), [tinst], argExprs, m) |> Some + | ValueNone -> + None + +let tryMkCallCoreFunctionAsBuiltInWitness (g: TcGlobals) info tyargs argExprs m = + let vref = ValRefForIntrinsic info + match vref.TryDeref with + | ValueSome v -> + let f = exprForValRef m vref + mkApps g ((f, v.Type), [tyargs], argExprs, m) |> Some + | ValueNone -> + None + +let TryEliminateDesugaredConstants g m c = + match c with + | Const.Decimal d -> + match System.Decimal.GetBits d with + | [| lo;med;hi; signExp |] -> + let scale = (min (((signExp &&& 0xFF0000) >>> 16) &&& 0xFF) 28) |> byte + let isNegative = (signExp &&& 0x80000000) <> 0 + Some(mkCallNewDecimal g m (mkInt g m lo, mkInt g m med, mkInt g m hi, mkBool g m isNegative, mkByte g m scale) ) + | _ -> failwith "unreachable" + | _ -> + None + +let mkSeqTy (g: TcGlobals) ty = mkAppTy g.seq_tcr [ty] + +let mkIEnumeratorTy (g: TcGlobals) ty = mkAppTy g.tcref_System_Collections_Generic_IEnumerator [ty] + +let mkCallSeqCollect g m alphaTy betaTy arg1 arg2 = + let enumty2 = try rangeOfFunTy g (tyOfExpr g arg1) with _ -> (* defensive programming *) (mkSeqTy g betaTy) + mkApps g (typedExprForIntrinsic g m g.seq_collect_info, [[alphaTy;enumty2;betaTy]], [ arg1; arg2 ], m) + +let mkCallSeqUsing g m resourceTy elemTy arg1 arg2 = + // We're instantiating val using : 'a -> ('a -> 'sb) -> seq<'b> when 'sb :> seq<'b> and 'a :> IDisposable + // We set 'sb -> range(typeof(arg2)) + let enumty = try rangeOfFunTy g (tyOfExpr g arg2) with _ -> (* defensive programming *) (mkSeqTy g elemTy) + mkApps g (typedExprForIntrinsic g m g.seq_using_info, [[resourceTy;enumty;elemTy]], [ arg1; arg2 ], m) + +let mkCallSeqDelay g m elemTy arg1 = + mkApps g (typedExprForIntrinsic g m g.seq_delay_info, [[elemTy]], [ arg1 ], m) + +let mkCallSeqAppend g m elemTy arg1 arg2 = + mkApps g (typedExprForIntrinsic g m g.seq_append_info, [[elemTy]], [ arg1; arg2 ], m) + +let mkCallSeqGenerated g m elemTy arg1 arg2 = + mkApps g (typedExprForIntrinsic g m g.seq_generated_info, [[elemTy]], [ arg1; arg2 ], m) + +let mkCallSeqFinally g m elemTy arg1 arg2 = + mkApps g (typedExprForIntrinsic g m g.seq_finally_info, [[elemTy]], [ arg1; arg2 ], m) + +let mkCallSeqOfFunctions g m ty1 ty2 arg1 arg2 arg3 = + mkApps g (typedExprForIntrinsic g m g.seq_of_functions_info, [[ty1;ty2]], [ arg1; arg2; arg3 ], m) + +let mkCallSeqToArray g m elemTy arg1 = + mkApps g (typedExprForIntrinsic g m g.seq_to_array_info, [[elemTy]], [ arg1 ], m) + +let mkCallSeqToList g m elemTy arg1 = + mkApps g (typedExprForIntrinsic g m g.seq_to_list_info, [[elemTy]], [ arg1 ], m) + +let mkCallSeqMap g m inpElemTy genElemTy arg1 arg2 = + mkApps g (typedExprForIntrinsic g m g.seq_map_info, [[inpElemTy;genElemTy]], [ arg1; arg2 ], m) + +let mkCallSeqSingleton g m ty1 arg1 = + mkApps g (typedExprForIntrinsic g m g.seq_singleton_info, [[ty1]], [ arg1 ], m) + +let mkCallSeqEmpty g m ty1 = + mkApps g (typedExprForIntrinsic g m g.seq_empty_info, [[ty1]], [ ], m) + +let mkCall_sprintf (g: TcGlobals) m funcTy fmtExpr fillExprs = + mkApps g (typedExprForIntrinsic g m g.sprintf_info, [[funcTy]], fmtExpr::fillExprs , m) + +let mkCallDeserializeQuotationFSharp20Plus g m e1 e2 e3 e4 = + let args = [ e1; e2; e3; e4 ] + mkApps g (typedExprForIntrinsic g m g.deserialize_quoted_FSharp_20_plus_info, [], [ mkRefTupledNoTypes g m args ], m) + +let mkCallDeserializeQuotationFSharp40Plus g m e1 e2 e3 e4 e5 = + let args = [ e1; e2; e3; e4; e5 ] + mkApps g (typedExprForIntrinsic g m g.deserialize_quoted_FSharp_40_plus_info, [], [ mkRefTupledNoTypes g m args ], m) + +let mkCallCastQuotation g m ty e1 = + mkApps g (typedExprForIntrinsic g m g.cast_quotation_info, [[ty]], [ e1 ], m) + +let mkCallLiftValue (g: TcGlobals) m ty e1 = + mkApps g (typedExprForIntrinsic g m g.lift_value_info, [[ty]], [e1], m) + +let mkCallLiftValueWithName (g: TcGlobals) m ty nm e1 = + let vref = ValRefForIntrinsic g.lift_value_with_name_info + // Use "Expr.ValueWithName" if it exists in FSharp.Core + match vref.TryDeref with + | ValueSome _ -> + mkApps g (typedExprForIntrinsic g m g.lift_value_with_name_info, [[ty]], [mkRefTupledNoTypes g m [e1; mkString g m nm]], m) + | ValueNone -> + mkCallLiftValue g m ty e1 + +let mkCallLiftValueWithDefn g m qty e1 = + assert isQuotedExprTy g qty + let ty = destQuotedExprTy g qty + let vref = ValRefForIntrinsic g.lift_value_with_defn_info + // Use "Expr.WithValue" if it exists in FSharp.Core + match vref.TryDeref with + | ValueSome _ -> + let copyOfExpr = copyExpr g ValCopyFlag.CloneAll e1 + let quoteOfCopyOfExpr = Expr.Quote (copyOfExpr, ref None, false, m, qty) + mkApps g (typedExprForIntrinsic g m g.lift_value_with_defn_info, [[ty]], [mkRefTupledNoTypes g m [e1; quoteOfCopyOfExpr]], m) + | ValueNone -> + Expr.Quote (e1, ref None, false, m, qty) + +let mkCallCheckThis g m ty e1 = + mkApps g (typedExprForIntrinsic g m g.check_this_info, [[ty]], [e1], m) + +let mkCallFailInit g m = + mkApps g (typedExprForIntrinsic g m g.fail_init_info, [], [mkUnit g m], m) + +let mkCallFailStaticInit g m = + mkApps g (typedExprForIntrinsic g m g.fail_static_init_info, [], [mkUnit g m], m) + +let mkCallQuoteToLinqLambdaExpression g m ty e1 = + mkApps g (typedExprForIntrinsic g m g.quote_to_linq_lambda_info, [[ty]], [e1], m) + +let mkOptionToNullable g m ty e1 = + mkApps g (typedExprForIntrinsic g m g.option_toNullable_info, [[ty]], [e1], m) + +let mkOptionDefaultValue g m ty e1 e2 = + mkApps g (typedExprForIntrinsic g m g.option_defaultValue_info, [[ty]], [e1; e2], m) + +let mkLazyDelayed g m ty f = mkApps g (typedExprForIntrinsic g m g.lazy_create_info, [[ty]], [ f ], m) + +let mkLazyForce g m ty e = mkApps g (typedExprForIntrinsic g m g.lazy_force_info, [[ty]], [ e; mkUnit g m ], m) + +let mkGetString g m e1 e2 = mkApps g (typedExprForIntrinsic g m g.getstring_info, [], [e1;e2], m) + +let mkGetStringChar = mkGetString + +let mkGetStringLength g m e = + let mspec = mspec_String_Length g + Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, true, false, mspec.MethodRef, [], [], [g.int32_ty]), [], [e], m) + +let mkStaticCall_String_Concat2 g m arg1 arg2 = + let mspec = mspec_String_Concat2 g + Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2], m) + +let mkStaticCall_String_Concat3 g m arg1 arg2 arg3 = + let mspec = mspec_String_Concat3 g + Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3], m) + +let mkStaticCall_String_Concat4 g m arg1 arg2 arg3 arg4 = + let mspec = mspec_String_Concat4 g + Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3; arg4], m) + +let mkStaticCall_String_Concat_Array g m arg = + let mspec = mspec_String_Concat_Array g + Expr.Op (TOp.ILCall (false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg], m) + +// Quotations can't contain any IL. +// As a result, we aim to get rid of all IL generation in the typechecker and pattern match +// compiler, or else train the quotation generator to understand the generated IL. +// Hence each of the following are marked with places where they are generated. + +// Generated by the optimizer and the encoding of 'for' loops +let mkDecr (g: TcGlobals) m e = mkAsmExpr ([ AI_sub ], [], [e; mkOne g m], [g.int_ty], m) + +let mkIncr (g: TcGlobals) m e = mkAsmExpr ([ AI_add ], [], [mkOne g m; e], [g.int_ty], m) + +// Generated by the pattern match compiler and the optimizer for +// 1. array patterns +// 2. optimizations associated with getting 'for' loops into the shape expected by the JIT. +// +// NOTE: The conv.i4 assumes that int_ty is int32. Note: ldlen returns native UNSIGNED int +let mkLdlen (g: TcGlobals) m arre = mkAsmExpr ([ I_ldlen; (AI_conv DT_I4) ], [], [ arre ], [ g.int_ty ], m) + +let mkLdelem (_g: TcGlobals) m ty arre idxe = mkAsmExpr ([ I_ldelem_any (ILArrayShape.SingleDimensional, mkILTyvarTy 0us) ], [ty], [ arre;idxe ], [ ty ], m) + +// This is generated in equality/compare/hash augmentations and in the pattern match compiler. +// It is understood by the quotation processor and turned into "Equality" nodes. +// +// Note: this is IL assembly code, don't go inserting this in expressions which will be exposed via quotations +let mkILAsmCeq (g: TcGlobals) m e1 e2 = mkAsmExpr ([ AI_ceq ], [], [e1; e2], [g.bool_ty], m) + +let mkILAsmClt (g: TcGlobals) m e1 e2 = mkAsmExpr ([ AI_clt ], [], [e1; e2], [g.bool_ty], m) + +// This is generated in the initialization of the "ctorv" field in the typechecker's compilation of +// an implicit class construction. +let mkNull m ty = Expr.Const (Const.Zero, m, ty) + +let mkThrow m ty e = mkAsmExpr ([ I_throw ], [], [e], [ty], m) + +let destThrow = function + | Expr.Op (TOp.ILAsm ([I_throw], [ty2]), [], [e], m) -> Some (m, ty2, e) + | _ -> None + +let isThrow x = Option.isSome (destThrow x) + +// reraise - parsed as library call - internally represented as op form. +let mkReraiseLibCall (g: TcGlobals) ty m = + let ve, vt = typedExprForIntrinsic g m g.reraise_info + Expr.App (ve, vt, [ty], [mkUnit g m], m) + +let mkReraise m returnTy = Expr.Op (TOp.Reraise, [returnTy], [], m) (* could suppress unitArg *) + +//---------------------------------------------------------------------------- +// CompilationMappingAttribute, SourceConstructFlags +//---------------------------------------------------------------------------- + +let tnameCompilationSourceNameAttr = FSharpLib.Core + ".CompilationSourceNameAttribute" +let tnameCompilationArgumentCountsAttr = FSharpLib.Core + ".CompilationArgumentCountsAttribute" +let tnameCompilationMappingAttr = FSharpLib.Core + ".CompilationMappingAttribute" +let tnameSourceConstructFlags = FSharpLib.Core + ".SourceConstructFlags" + +let tref_CompilationArgumentCountsAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationArgumentCountsAttr) +let tref_CompilationMappingAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationMappingAttr) +let tref_CompilationSourceNameAttr (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameCompilationSourceNameAttr) +let tref_SourceConstructFlags (g: TcGlobals) = mkILTyRef (g.fslibCcu.ILScopeRef, tnameSourceConstructFlags) + +let mkCompilationMappingAttrPrim (g: TcGlobals) k nums = + mkILCustomAttribute (tref_CompilationMappingAttr g, + ((mkILNonGenericValueTy (tref_SourceConstructFlags g)) :: (nums |> List.map (fun _ -> g.ilg.typ_Int32))), + ((k :: nums) |> List.map (fun n -> ILAttribElem.Int32 n)), + []) + +let mkCompilationMappingAttr g kind = mkCompilationMappingAttrPrim g kind [] + +let mkCompilationMappingAttrWithSeqNum g kind seqNum = mkCompilationMappingAttrPrim g kind [seqNum] + +let mkCompilationMappingAttrWithVariantNumAndSeqNum g kind varNum seqNum = mkCompilationMappingAttrPrim g kind [varNum;seqNum] + +let mkCompilationArgumentCountsAttr (g: TcGlobals) nums = + mkILCustomAttribute (tref_CompilationArgumentCountsAttr g, [ mkILArr1DTy g.ilg.typ_Int32 ], + [ILAttribElem.Array (g.ilg.typ_Int32, List.map (fun n -> ILAttribElem.Int32 n) nums)], + []) + +let mkCompilationSourceNameAttr (g: TcGlobals) n = + mkILCustomAttribute (tref_CompilationSourceNameAttr g, [ g.ilg.typ_String ], + [ILAttribElem.String(Some n)], + []) + +let mkCompilationMappingAttrForQuotationResource (g: TcGlobals) (nm, tys: ILTypeRef list) = + mkILCustomAttribute (tref_CompilationMappingAttr g, + [ g.ilg.typ_String; mkILArr1DTy g.ilg.typ_Type ], + [ ILAttribElem.String (Some nm); ILAttribElem.Array (g.ilg.typ_Type, [ for ty in tys -> ILAttribElem.TypeRef (Some ty) ]) ], + []) + +//---------------------------------------------------------------------------- +// Decode extensible typing attributes +//---------------------------------------------------------------------------- + +#if !NO_EXTENSIONTYPING + +let isTypeProviderAssemblyAttr (cattr: ILAttribute) = + cattr.Method.DeclaringType.BasicQualifiedName = typeof.FullName + +let TryDecodeTypeProviderAssemblyAttr (cattr: ILAttribute) = + if isTypeProviderAssemblyAttr cattr then + let parms, _args = decodeILAttribData cattr + match parms with // The first parameter to the attribute is the name of the assembly with the compiler extensions. + | ILAttribElem.String (Some assemblyName) :: _ -> Some assemblyName + | ILAttribElem.String None :: _ -> Some null + | [] -> Some null + | _ -> None + else + None + +#endif + +//---------------------------------------------------------------------------- +// FSharpInterfaceDataVersionAttribute +//---------------------------------------------------------------------------- + +let tname_SignatureDataVersionAttr = FSharpLib.Core + ".FSharpInterfaceDataVersionAttribute" + +let tnames_SignatureDataVersionAttr = splitILTypeName tname_SignatureDataVersionAttr + +let tref_SignatureDataVersionAttr fsharpCoreAssemblyScopeRef = mkILTyRef(fsharpCoreAssemblyScopeRef, tname_SignatureDataVersionAttr) + +let mkSignatureDataVersionAttr (g: TcGlobals) (version: ILVersionInfo) = + mkILCustomAttribute + (tref_SignatureDataVersionAttr g.ilg.fsharpCoreAssemblyScopeRef, + [g.ilg.typ_Int32;g.ilg.typ_Int32;g.ilg.typ_Int32], + [ILAttribElem.Int32 (int32 version.Major) + ILAttribElem.Int32 (int32 version.Minor) + ILAttribElem.Int32 (int32 version.Build)], []) + +let tname_AutoOpenAttr = FSharpLib.Core + ".AutoOpenAttribute" + +let IsSignatureDataVersionAttr cattr = isILAttribByName ([], tname_SignatureDataVersionAttr) cattr + +let TryFindAutoOpenAttr cattr = + if isILAttribByName ([], tname_AutoOpenAttr) cattr then + match decodeILAttribData cattr with + | [ILAttribElem.String s], _ -> s + | [], _ -> None + | _ -> + warning(Failure(FSComp.SR.tastUnexpectedDecodeOfAutoOpenAttribute())) + None + else + None + +let tname_InternalsVisibleToAttr = "System.Runtime.CompilerServices.InternalsVisibleToAttribute" + +let TryFindInternalsVisibleToAttr cattr = + if isILAttribByName ([], tname_InternalsVisibleToAttr) cattr then + match decodeILAttribData cattr with + | [ILAttribElem.String s], _ -> s + | [], _ -> None + | _ -> + warning(Failure(FSComp.SR.tastUnexpectedDecodeOfInternalsVisibleToAttribute())) + None + else + None + +let IsMatchingSignatureDataVersionAttr (version: ILVersionInfo) cattr = + IsSignatureDataVersionAttr cattr && + match decodeILAttribData cattr with + | [ILAttribElem.Int32 u1; ILAttribElem.Int32 u2;ILAttribElem.Int32 u3 ], _ -> + (version.Major = uint16 u1) && (version.Minor = uint16 u2) && (version.Build = uint16 u3) + | _ -> + warning(Failure(FSComp.SR.tastUnexpectedDecodeOfInterfaceDataVersionAttribute())) + false + +let mkCompilerGeneratedAttr (g: TcGlobals) n = + mkILCustomAttribute (tref_CompilationMappingAttr g, [mkILNonGenericValueTy (tref_SourceConstructFlags g)], [ILAttribElem.Int32 n], []) + +//-------------------------------------------------------------------------- +// tupled lambda --> method/function with a given topValInfo specification. +// +// AdjustArityOfLambdaBody: "(vs, body)" represents a lambda "fun (vs) -> body". The +// aim is to produce a "static method" represented by a pair +// "(mvs, body)" where mvs has the List.length "arity". +//-------------------------------------------------------------------------- + +let untupledToRefTupled g vs = + let untupledTys = typesOfVals vs + let m = (List.head vs).Range + let tupledv, tuplede = mkCompGenLocal m "tupledArg" (mkRefTupledTy g untupledTys) + let untupling_es = List.mapi (fun i _ -> mkTupleFieldGet g (tupInfoRef, tuplede, untupledTys, i, m)) untupledTys + // These are non-sticky - at the caller,any sequence point for 'body' goes on 'body' _after_ the binding has been made + tupledv, mkInvisibleLets m vs untupling_es + +// The required tupled-arity (arity) can either be 1 +// or N, and likewise for the tuple-arity of the input lambda, i.e. either 1 or N +// where the N's will be identical. +let AdjustArityOfLambdaBody g arity (vs: Val list) body = + let nvs = vs.Length + if not (nvs = arity || nvs = 1 || arity = 1) then failwith "lengths don't add up" + if arity = 0 then + vs, body + elif nvs = arity then + vs, body + elif nvs = 1 then + let v = vs.Head + let untupledTys = destRefTupleTy g v.Type + if (untupledTys.Length <> arity) then failwith "length untupledTys <> arity" + let dummyvs, dummyes = + untupledTys + |> List.mapi (fun i ty -> mkCompGenLocal v.Range (v.LogicalName + "_" + string i) ty) + |> List.unzip + // These are non-sticky - any sequence point for 'body' goes on 'body' _after_ the binding has been made + let body = mkInvisibleLet v.Range v (mkRefTupled g v.Range dummyes untupledTys) body + dummyvs, body + else + let tupledv, untupler = untupledToRefTupled g vs + [tupledv], untupler body + +let MultiLambdaToTupledLambda g vs body = + match vs with + | [] -> failwith "MultiLambdaToTupledLambda: expected some arguments" + | [v] -> v, body + | vs -> + let tupledv, untupler = untupledToRefTupled g vs + tupledv, untupler body + +let (|RefTuple|_|) expr = + match expr with + | Expr.Op (TOp.Tuple (TupInfo.Const false), _, args, _) -> Some args + | _ -> None + +let MultiLambdaToTupledLambdaIfNeeded g (vs, arg) body = + match vs, arg with + | [], _ -> failwith "MultiLambdaToTupledLambda: expected some arguments" + | [v], _ -> [(v, arg)], body + | vs, RefTuple args when args.Length = vs.Length -> List.zip vs args, body + | vs, _ -> + let tupledv, untupler = untupledToRefTupled g vs + [(tupledv, arg)], untupler body + +//-------------------------------------------------------------------------- +// Beta reduction via let-bindings. Reduce immediate apps. of lambdas to let bindings. +// Includes binding the immediate application of generic +// functions. Input type is the type of the function. Makes use of the invariant +// that any two expressions have distinct local variables (because we explicitly copy +// expressions). +//------------------------------------------------------------------------ + +let rec MakeApplicationAndBetaReduceAux g (f, fty, tyargsl: TType list list, argsl: Expr list, m) = + match f with + | Expr.Let (bind, body, mlet, _) -> + // Lift bindings out, i.e. (let x = e in f) y --> let x = e in f y + // This increases the scope of 'x', which I don't like as it mucks with debugging + // scopes of variables, but this is an important optimization, especially when the '|>' + // notation is used a lot. + mkLetBind mlet bind (MakeApplicationAndBetaReduceAux g (body, fty, tyargsl, argsl, m)) + | _ -> + match tyargsl with + | [] :: rest -> + MakeApplicationAndBetaReduceAux g (f, fty, rest, argsl, m) + + | tyargs :: rest -> + // Bind type parameters by immediate substitution + match f with + | Expr.TyLambda (_, tyvs, body, _, bodyty) when tyvs.Length = List.length tyargs -> + let tpenv = bindTypars tyvs tyargs emptyTyparInst + let body = instExpr g tpenv body + let bodyty' = instType tpenv bodyty + MakeApplicationAndBetaReduceAux g (body, bodyty', rest, argsl, m) + + | _ -> + let f = mkAppsAux g f fty [tyargs] [] m + let fty = applyTyArgs g fty tyargs + MakeApplicationAndBetaReduceAux g (f, fty, rest, argsl, m) + | [] -> + match argsl with + | _ :: _ -> + // Bind term parameters by "let" explicit substitutions + // + // Only do this if there are enough lambdas for the number of arguments supplied. This is because + // all arguments get evaluated before application. + // + // VALID: + // (fun a b -> E[a, b]) t1 t2 ---> let a = t1 in let b = t2 in E[t1, t2] + // INVALID: + // (fun a -> E[a]) t1 t2 ---> let a = t1 in E[a] t2 UNLESS: E[a] has no effects OR t2 has no effects + + match tryStripLambdaN argsl.Length f with + | Some (argvsl, body) -> + assert (argvsl.Length = argsl.Length) + let pairs, body = List.mapFoldBack (MultiLambdaToTupledLambdaIfNeeded g) (List.zip argvsl argsl) body + let argvs2, args2 = List.unzip (List.concat pairs) + mkLetsBind m (mkCompGenBinds argvs2 args2) body + | _ -> + mkExprAppAux g f fty argsl m + + | [] -> + f + +let MakeApplicationAndBetaReduce g (f, fty, tyargsl, argl, m) = + MakeApplicationAndBetaReduceAux g (f, fty, tyargsl, argl, m) + +let (|NewDelegateExpr|_|) g expr = + match expr with + | Expr.Obj (lambdaId, ty, a, b, [TObjExprMethod(c, d, e, tmvs, body, f)], [], m) when isDelegateTy g ty -> + Some (lambdaId, tmvs, body, m, (fun bodyR -> Expr.Obj (lambdaId, ty, a, b, [TObjExprMethod(c, d, e, tmvs, bodyR, f)], [], m))) + | _ -> None + +let (|DelegateInvokeExpr|_|) g expr = + match expr with + | Expr.App ((Expr.Val (invokeRef, _, _)) as iref, fty, tyargs, (f :: args), m) + when invokeRef.LogicalName = "Invoke" && isFSharpDelegateTy g (tyOfExpr g f) -> + Some(iref, fty, tyargs, f, args, m) + | _ -> None + +let (|OpPipeRight|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [_; resType], [xExpr; fExpr], m) + when valRefEq g vref g.piperight_vref -> + Some(resType, xExpr, fExpr, m) + | _ -> None + +let (|OpPipeRight2|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [_; _; resType], [Expr.Op (TOp.Tuple _, _, [arg1; arg2], _); fExpr], m) + when valRefEq g vref g.piperight2_vref -> + Some(resType, arg1, arg2, fExpr, m) + | _ -> None + +let (|OpPipeRight3|_|) g expr = + match expr with + | Expr.App (Expr.Val (vref, _, _), _, [_; _; _; resType], [Expr.Op (TOp.Tuple _, _, [arg1; arg2; arg3], _); fExpr], m) + when valRefEq g vref g.piperight3_vref -> + Some(resType, arg1, arg2, arg3, fExpr, m) + | _ -> None + +let rec MakeFSharpDelegateInvokeAndTryBetaReduce g (invokeRef, f, fty, tyargs, argsl: Expr list, m) = + match f with + | Expr.Let (bind, body, mlet, _) -> + mkLetBind mlet bind (MakeFSharpDelegateInvokeAndTryBetaReduce g (invokeRef, body, fty, tyargs, argsl, m)) + | _ -> + match f with + | NewDelegateExpr g (_, argvsl, body, m, _) when argvsl.Length = argsl.Length -> + let pairs, body = List.mapFoldBack (MultiLambdaToTupledLambdaIfNeeded g) (List.zip argvsl argsl) body + let argvs2, args2 = List.unzip (List.concat pairs) + mkLetsBind m (mkCompGenBinds argvs2 args2) body + | _ -> + // Remake the delegate invoke + Expr.App (invokeRef, fty, tyargs, (f :: argsl), m) + +//--------------------------------------------------------------------------- +// Adjust for expected usage +// Convert a use of a value to saturate to the given arity. +//--------------------------------------------------------------------------- + +let MakeArgsForTopArgs _g m argtysl tpenv = + argtysl |> List.mapi (fun i argtys -> + argtys |> List.mapi (fun j (argty, argInfo: ArgReprInfo) -> + let ty = instType tpenv argty + let nm = + match argInfo.Name with + | None -> CompilerGeneratedName ("arg" + string i + string j) + | Some id -> id.idText + fst (mkCompGenLocal m nm ty))) + +let AdjustValForExpectedArity g m (vref: ValRef) flags topValInfo = + + let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m + let tps' = copyTypars tps + let tyargs' = List.map mkTyparTy tps' + let tpenv = bindTypars tps tyargs' emptyTyparInst + let rty' = instType tpenv rty + let vsl = MakeArgsForTopArgs g m argtysl tpenv + let call = MakeApplicationAndBetaReduce g (Expr.Val (vref, flags, m), vref.Type, [tyargs'], (List.map (mkRefTupledVars g m) vsl), m) + let tauexpr, tauty = + List.foldBack + (fun vs (e, ty) -> mkMultiLambda m vs (e, ty), (mkRefTupledVarsTy g vs --> ty)) + vsl + (call, rty') + // Build a type-lambda expression for the toplevel value if needed... + mkTypeLambda m tps' (tauexpr, tauty), tps' +-> tauty + +let IsSubsumptionExpr g expr = + match expr with + | Expr.Op (TOp.Coerce, [inputTy;actualTy], [_], _) -> + isFunTy g actualTy && isFunTy g inputTy + | _ -> + false + +let stripTupledFunTy g ty = + let argTys, retTy = stripFunTy g ty + let curriedArgTys = argTys |> List.map (tryDestRefTupleTy g) + curriedArgTys, retTy + +let (|ExprValWithPossibleTypeInst|_|) expr = + match expr with + | Expr.App (Expr.Val (vref, flags, m), _fty, tyargs, [], _) -> + Some (vref, flags, tyargs, m) + | Expr.Val (vref, flags, m) -> + Some (vref, flags, [], m) + | _ -> + None + +let mkCoerceIfNeeded g tgtTy srcTy expr = + if typeEquiv g tgtTy srcTy then + expr + else + mkCoerceExpr(expr, tgtTy, expr.Range, srcTy) + +let mkCompGenLetIn m nm ty e f = + let v, ve = mkCompGenLocal m nm ty + mkCompGenLet m v e (f (v, ve)) + +/// Take a node representing a coercion from one function type to another, e.g. +/// A -> A * A -> int +/// to +/// B -> B * A -> int +/// and return an expression of the correct type that doesn't use a coercion type. For example +/// return +/// (fun b1 b2 -> E (b1 :> A) (b2 :> A)) +/// +/// - Use good names for the closure arguments if available +/// - Create lambda variables if needed, or use the supplied arguments if available. +/// +/// Return the new expression and any unused suffix of supplied arguments +/// +/// If E is a value with TopInfo then use the arity to help create a better closure. +/// In particular we can create a closure like this: +/// (fun b1 b2 -> E (b1 :> A) (b2 :> A)) +/// rather than +/// (fun b1 -> let clo = E (b1 :> A) in (fun b2 -> clo (b2 :> A))) +/// The latter closures are needed to carefully preserve side effect order +/// +/// Note that the results of this translation are visible to quotations + +let AdjustPossibleSubsumptionExpr g (expr: Expr) (suppliedArgs: Expr list) : (Expr* Expr list) option = + + match expr with + | Expr.Op (TOp.Coerce, [inputTy;actualTy], [exprWithActualTy], m) when + isFunTy g actualTy && isFunTy g inputTy -> + + if typeEquiv g actualTy inputTy then + Some(exprWithActualTy, suppliedArgs) + else + + let curriedActualArgTys, retTy = stripTupledFunTy g actualTy + + let curriedInputTys, _ = stripFunTy g inputTy + + assert (curriedActualArgTys.Length = curriedInputTys.Length) + + let argTys = (curriedInputTys, curriedActualArgTys) ||> List.mapi2 (fun i x y -> (i, x, y)) + + + // Use the nice names for a function of known arity and name. Note that 'nice' here also + // carries a semantic meaning. For a function with top-info, + // let f (x: A) (y: A) (z: A) = ... + // we know there are no side effects on the application of 'f' to 1, 2 args. This greatly simplifies + // the closure built for + // f b1 b2 + // and indeed for + // f b1 b2 b3 + // we don't build any closure at all, and just return + // f (b1 :> A) (b2 :> A) (b3 :> A) + + let curriedNiceNames = + match stripExpr exprWithActualTy with + | ExprValWithPossibleTypeInst(vref, _, _, _) when vref.ValReprInfo.IsSome -> + + let _, argtysl, _, _ = GetTopValTypeInFSharpForm g vref.ValReprInfo.Value vref.Type expr.Range + argtysl |> List.mapi (fun i argtys -> + argtys |> List.mapi (fun j (_, argInfo) -> + match argInfo.Name with + | None -> CompilerGeneratedName ("arg" + string i + string j) + | Some id -> id.idText)) + | _ -> + [] + + let nCurriedNiceNames = curriedNiceNames.Length + assert (curriedActualArgTys.Length >= nCurriedNiceNames) + + let argTysWithNiceNames, argTysWithoutNiceNames = + List.splitAt nCurriedNiceNames argTys + + /// Only consume 'suppliedArgs' up to at most the number of nice arguments + let nSuppliedArgs = min suppliedArgs.Length nCurriedNiceNames + let suppliedArgs, droppedSuppliedArgs = + List.splitAt nSuppliedArgs suppliedArgs + + /// The relevant range for any expressions and applications includes the arguments + let appm = (m, suppliedArgs) ||> List.fold (fun m e -> unionRanges m e.Range) + + // See if we have 'enough' suppliedArgs. If not, we have to build some lambdas, and, + // we have to 'let' bind all arguments that we consume, e.g. + // Seq.take (effect;4) : int list -> int list + // is a classic case. Here we generate + // let tmp = (effect;4) in + // (fun v -> Seq.take tmp (v :> seq<_>)) + let buildingLambdas = nSuppliedArgs <> nCurriedNiceNames + + /// Given a tuple of argument variables that has a tuple type that satisfies the input argument types, + /// coerce it to a tuple that satisfies the matching coerced argument type(s). + let CoerceDetupled (argTys: TType list) (detupledArgs: Expr list) (actualTys: TType list) = + assert (actualTys.Length = argTys.Length) + assert (actualTys.Length = detupledArgs.Length) + // Inject the coercions into the user-supplied explicit tuple + let argm = List.reduce unionRanges (detupledArgs |> List.map (fun e -> e.Range)) + mkRefTupled g argm (List.map3 (mkCoerceIfNeeded g) actualTys argTys detupledArgs) actualTys + + /// Given an argument variable of tuple type that has been evaluated and stored in the + /// given variable, where the tuple type that satisfies the input argument types, + /// coerce it to a tuple that satisfies the matching coerced argument type(s). + let CoerceBoundTuple tupleVar argTys (actualTys: TType list) = + assert (actualTys.Length > 1) + + mkRefTupled g appm + ((actualTys, argTys) ||> List.mapi2 (fun i actualTy dummyTy -> + let argExprElement = mkTupleFieldGet g (tupInfoRef, tupleVar, argTys, i, appm) + mkCoerceIfNeeded g actualTy dummyTy argExprElement)) + actualTys + + /// Given an argument that has a tuple type that satisfies the input argument types, + /// coerce it to a tuple that satisfies the matching coerced argument type. Try to detuple the argument if possible. + let CoerceTupled niceNames (argExpr: Expr) (actualTys: TType list) = + let argExprTy = (tyOfExpr g argExpr) + + let argTys = + match actualTys with + | [_] -> + [tyOfExpr g argExpr] + | _ -> + tryDestRefTupleTy g argExprTy + + assert (actualTys.Length = argTys.Length) + let nm = match niceNames with [nm] -> nm | _ -> "arg" + if buildingLambdas then + // Evaluate the user-supplied tuple-valued argument expression, inject the coercions and build an explicit tuple + // Assign the argument to make sure it is only run once + // f ~~>: B -> int + // f ~~> : (B * B) -> int + // + // for + // let f a = 1 + // let f (a, a) = 1 + let v, ve = mkCompGenLocal appm nm argExprTy + let binderBuilder = (fun tm -> mkCompGenLet appm v argExpr tm) + let expr = + match actualTys, argTys with + | [actualTy], [argTy] -> mkCoerceIfNeeded g actualTy argTy ve + | _ -> CoerceBoundTuple ve argTys actualTys + + binderBuilder, expr + else + if typeEquiv g (mkRefTupledTy g actualTys) argExprTy then + (fun tm -> tm), argExpr + else + + let detupledArgs, argTys = + match actualTys with + | [_actualType] -> + [argExpr], [tyOfExpr g argExpr] + | _ -> + tryDestRefTupleExpr argExpr, tryDestRefTupleTy g argExprTy + + // OK, the tuples match, or there is no de-tupling, + // f x + // f (x, y) + // + // for + // let f (x, y) = 1 + // and we're not building lambdas, just coerce the arguments in place + if detupledArgs.Length = actualTys.Length then + (fun tm -> tm), CoerceDetupled argTys detupledArgs actualTys + else + // In this case there is a tuple mismatch. + // f p + // + // + // for + // let f (x, y) = 1 + // Assign the argument to make sure it is only run once + let v, ve = mkCompGenLocal appm nm argExprTy + let binderBuilder = (fun tm -> mkCompGenLet appm v argExpr tm) + let expr = CoerceBoundTuple ve argTys actualTys + binderBuilder, expr + + + // This variable is really a dummy to make the code below more regular. + // In the i = N - 1 cases we skip the introduction of the 'let' for + // this variable. + let resVar, resVarAsExpr = mkCompGenLocal appm "result" retTy + let N = argTys.Length + let cloVar, exprForOtherArgs, _ = + List.foldBack + (fun (i, inpArgTy, actualArgTys) (cloVar: Val, res, resTy) -> + + let inpArgTys = + match actualArgTys with + | [_] -> [inpArgTy] + | _ -> destRefTupleTy g inpArgTy + + assert (inpArgTys.Length = actualArgTys.Length) + + let inpsAsVars, inpsAsExprs = inpArgTys |> List.mapi (fun j ty -> mkCompGenLocal appm ("arg" + string i + string j) ty) |> List.unzip + let inpsAsActualArg = CoerceDetupled inpArgTys inpsAsExprs actualArgTys + let inpCloVarType = (mkFunTy (mkRefTupledTy g actualArgTys) cloVar.Type) + let newResTy = mkFunTy inpArgTy resTy + let inpCloVar, inpCloVarAsExpr = mkCompGenLocal appm ("clo" + string i) inpCloVarType + let newRes = + // For the final arg we can skip introducing the dummy variable + if i = N - 1 then + mkMultiLambda appm inpsAsVars + (mkApps g ((inpCloVarAsExpr, inpCloVarType), [], [inpsAsActualArg], appm), resTy) + else + mkMultiLambda appm inpsAsVars + (mkCompGenLet appm cloVar + (mkApps g ((inpCloVarAsExpr, inpCloVarType), [], [inpsAsActualArg], appm)) + res, + resTy) + + inpCloVar, newRes, newResTy) + argTysWithoutNiceNames + (resVar, resVarAsExpr, retTy) + + let exprForAllArgs = + if isNil argTysWithNiceNames then + mkCompGenLet appm cloVar exprWithActualTy exprForOtherArgs + else + // Mark the up as Some/None + let suppliedArgs = List.map Some suppliedArgs @ List.replicate (nCurriedNiceNames - nSuppliedArgs) None + + assert (suppliedArgs.Length = nCurriedNiceNames) + + let lambdaBuilders, binderBuilders, inpsAsArgs = + + (argTysWithNiceNames, curriedNiceNames, suppliedArgs) |||> List.map3 (fun (_, inpArgTy, actualArgTys) niceNames suppliedArg -> + + let inpArgTys = + match actualArgTys with + | [_] -> [inpArgTy] + | _ -> destRefTupleTy g inpArgTy + + + /// Note: there might not be enough nice names, and they might not match in arity + let niceNames = + match niceNames with + | nms when nms.Length = inpArgTys.Length -> nms + | [nm] -> inpArgTys |> List.mapi (fun i _ -> (nm + string i)) + | nms -> nms + match suppliedArg with + | Some arg -> + let binderBuilder, inpsAsActualArg = CoerceTupled niceNames arg actualArgTys + let lambdaBuilder = (fun tm -> tm) + lambdaBuilder, binderBuilder, inpsAsActualArg + | None -> + let inpsAsVars, inpsAsExprs = (niceNames, inpArgTys) ||> List.map2 (fun nm ty -> mkCompGenLocal appm nm ty) |> List.unzip + let inpsAsActualArg = CoerceDetupled inpArgTys inpsAsExprs actualArgTys + let lambdaBuilder = (fun tm -> mkMultiLambda appm inpsAsVars (tm, tyOfExpr g tm)) + let binderBuilder = (fun tm -> tm) + lambdaBuilder, binderBuilder, inpsAsActualArg) + |> List.unzip3 + + // If no trailing args then we can skip introducing the dummy variable + // This corresponds to + // let f (x: A) = 1 + // + // f ~~> type B -> int + // + // giving + // (fun b -> f (b :> A)) + // rather than + // (fun b -> let clo = f (b :> A) in clo) + let exprApp = + if isNil argTysWithoutNiceNames then + mkApps g ((exprWithActualTy, actualTy), [], inpsAsArgs, appm) + else + mkCompGenLet appm + cloVar (mkApps g ((exprWithActualTy, actualTy), [], inpsAsArgs, appm)) + exprForOtherArgs + + List.foldBack (fun f acc -> f acc) binderBuilders + (List.foldBack (fun f acc -> f acc) lambdaBuilders exprApp) + + Some(exprForAllArgs, droppedSuppliedArgs) + | _ -> + None + +/// Find and make all subsumption eliminations +let NormalizeAndAdjustPossibleSubsumptionExprs g inputExpr = + let expr, args = + // AdjustPossibleSubsumptionExpr can take into account an application + match stripExpr inputExpr with + | Expr.App (f, _fty, [], args, _) -> + f, args + + | _ -> + inputExpr, [] + + match AdjustPossibleSubsumptionExpr g expr args with + | None -> + inputExpr + | Some (expr', []) -> + expr' + | Some (expr', args') -> + //printfn "adjusted...." + Expr.App (expr', tyOfExpr g expr', [], args', inputExpr.Range) + + +//--------------------------------------------------------------------------- +// LinearizeTopMatch - when only one non-failing target, make linear. The full +// complexity of this is only used for spectacularly rare bindings such as +// type ('a, 'b) either = This of 'a | That of 'b +// let this_f1 = This (fun x -> x) +// let This fA | That fA = this_f1 +// +// Here a polymorphic top level binding "fA" is _computed_ by a pattern match!!! +// The TAST coming out of type checking must, however, define fA as a type function, +// since it is marked with an arity that indicates it's r.h.s. is a type function] +// without side effects and so can be compiled as a generic method (for example). + +// polymorphic things bound in complex matches at top level require eta expansion of the +// type function to ensure the r.h.s. of the binding is indeed a type function +let etaExpandTypeLambda g m tps (tm, ty) = + if isNil tps then tm else mkTypeLambda m tps (mkApps g ((tm, ty), [(List.map mkTyparTy tps)], [], m), ty) + +let AdjustValToTopVal (tmp: Val) parent valData = + tmp.SetValReprInfo (Some valData) + tmp.SetDeclaringEntity parent + tmp.SetIsMemberOrModuleBinding() + +/// For match with only one non-failing target T0, the other targets, T1... failing (say, raise exception). +/// tree, T0(v0, .., vN) => rhs ; T1() => fail ; ... +/// Convert it to bind T0's variables, then continue with T0's rhs: +/// let tmp = switch tree, TO(fv0, ..., fvN) => Tup (fv0, ..., fvN) ; T1() => fail; ... +/// let v1 = #1 tmp in ... +/// and vN = #N tmp +/// rhs +/// Motivation: +/// - For top-level let bindings with possibly failing matches, +/// this makes clear that subsequent bindings (if reached) are top-level ones. +let LinearizeTopMatchAux g parent (spBind, m, tree, targets, m2, ty) = + let targetsL = Array.toList targets + (* items* package up 0, 1, more items *) + let itemsProj tys i x = + match tys with + | [] -> failwith "itemsProj: no items?" + | [_] -> x (* no projection needed *) + | tys -> Expr.Op (TOp.TupleFieldGet (tupInfoRef, i), tys, [x], m) + let isThrowingTarget = function TTarget(_, x, _, _) -> isThrow x + if 1 + List.count isThrowingTarget targetsL = targetsL.Length then + // Have failing targets and ONE successful one, so linearize + let (TTarget (vs, rhs, spTarget, _)) = List.find (isThrowingTarget >> not) targetsL + let fvs = vs |> List.map (fun v -> fst(mkLocal v.Range v.LogicalName v.Type)) (* fresh *) + let vtys = vs |> List.map (fun v -> v.Type) + let tmpTy = mkRefTupledVarsTy g vs + let tmp, tmpe = mkCompGenLocal m "matchResultHolder" tmpTy + + AdjustValToTopVal tmp parent ValReprInfo.emptyValData + + let newTg = TTarget (fvs, mkRefTupledVars g m fvs, spTarget, None) + let fixup (TTarget (tvs, tx, spTarget, flags)) = + match destThrow tx with + | Some (m, _, e) -> + let tx = mkThrow m tmpTy e + TTarget(tvs, tx, spTarget, flags) (* Throwing targets, recast it's "return type" *) + | None -> newTg (* Non-throwing target, replaced [new/old] *) + + let targets = Array.map fixup targets + let binds = + vs |> List.mapi (fun i v -> + let ty = v.Type + let rhs = etaExpandTypeLambda g m v.Typars (itemsProj vtys i tmpe, ty) + // update the arity of the value + v.SetValReprInfo (Some (InferArityOfExpr g AllowTypeDirectedDetupling.Yes ty [] [] rhs)) + // This binding is deliberately non-sticky - any sequence point for 'rhs' goes on 'rhs' _after_ the binding has been evaluated + mkInvisibleBind v rhs) in (* vi = proj tmp *) + mkCompGenLet m + tmp (primMkMatch (spBind, m, tree, targets, m2, tmpTy)) (* note, probably retyped match, but note, result still has same type *) + (mkLetsFromBindings m binds rhs) + else + (* no change *) + primMkMatch (spBind, m, tree, targets, m2, ty) + +let LinearizeTopMatch g parent = function + | Expr.Match (spBind, m, tree, targets, m2, ty) -> LinearizeTopMatchAux g parent (spBind, m, tree, targets, m2, ty) + | x -> x + + +//--------------------------------------------------------------------------- +// XmlDoc signatures +//--------------------------------------------------------------------------- + +let commaEncs strs = String.concat "," strs +let angleEnc str = "{" + str + "}" +let ticksAndArgCountTextOfTyconRef (tcref: TyconRef) = + // Generic type names are (name + "`" + digits) where name does not contain "`". + let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName] + textOfPath path + +let typarEnc _g (gtpsType, gtpsMethod) typar = + match List.tryFindIndex (typarEq typar) gtpsType with + | Some idx -> "`" + string idx // single-tick-index for typar from type + | None -> + match List.tryFindIndex (typarEq typar) gtpsMethod with + | Some idx -> + "``" + string idx // double-tick-index for typar from method + | None -> + warning(InternalError("Typar not found during XmlDoc generation", typar.Range)) + "``0" + +let rec typeEnc g (gtpsType, gtpsMethod) ty = + let stripped = stripTyEqnsAndMeasureEqns g ty + match stripped with + | TType_forall _ -> + "Microsoft.FSharp.Core.FSharpTypeFunc" + + | _ when isByrefTy g ty -> + let ety = destByrefTy g ty + typeEnc g (gtpsType, gtpsMethod) ety + "@" + + | _ when isNativePtrTy g ty -> + let ety = destNativePtrTy g ty + typeEnc g (gtpsType, gtpsMethod) ety + "*" + + | _ when isArrayTy g ty -> + let tcref, tinst = destAppTy g ty + let rank = rankOfArrayTyconRef g tcref + let arraySuffix = "[" + String.concat ", " (List.replicate (rank-1) "0:") + "]" + typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix + + | TType_ucase (_, tinst) + | TType_app (_, tinst) -> + let tyName = + let ty = stripTyEqnsAndMeasureEqns g ty + match ty with + | TType_app (tcref, _tinst) -> + // Generic type names are (name + "`" + digits) where name does not contain "`". + // In XML doc, when used in type instances, these do not use the ticks. + let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName] + textOfPath (List.map DemangleGenericTypeName path) + | _ -> + assert false + failwith "impossible" + tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst + + | TType_anon (anonInfo, tinst) -> + sprintf "%s%s" anonInfo.ILTypeRef.FullName (tyargsEnc g (gtpsType, gtpsMethod) tinst) + + | TType_tuple (tupInfo, tys) -> + if evalTupInfoIsStruct tupInfo then + sprintf "System.ValueTuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) + else + sprintf "System.Tuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) + + | TType_fun (f, x) -> + "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [f;x] + + | TType_var typar -> + typarEnc g (gtpsType, gtpsMethod) typar + + | TType_measure _ -> "?" + +and tyargsEnc g (gtpsType, gtpsMethod) args = + match args with + | [] -> "" + | [a] when (match (stripTyEqns g a) with TType_measure _ -> true | _ -> false) -> "" // float should appear as just "float" in the generated .XML xmldoc file + | _ -> angleEnc (commaEncs (List.map (typeEnc g (gtpsType, gtpsMethod)) args)) + +let XmlDocArgsEnc g (gtpsType, gtpsMethod) argTys = + if isNil argTys then "" + else "(" + String.concat "," (List.map (typeEnc g (gtpsType, gtpsMethod)) argTys) + ")" + +let buildAccessPath (cp: CompilationPath option) = + match cp with + | Some cp -> + let ap = cp.AccessPath |> List.map fst |> List.toArray + System.String.Join(".", ap) + | None -> "Extension Type" +let prependPath path name = if path = "" then name else path + "." + name + +let XmlDocSigOfVal g full path (v: Val) = + let parentTypars, methTypars, cxs, argInfos, rty, prefix, path, name = + + // CLEANUP: this is one of several code paths that treat module values and members + // separately when really it would be cleaner to make sure GetTopValTypeInFSharpForm, GetMemberTypeInFSharpForm etc. + // were lined up so code paths like this could be uniform + + match v.MemberInfo with + | Some membInfo when not v.IsExtensionMember -> + // Methods, Properties etc. + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let tps, witnessInfos, argInfos, rty, _ = GetMemberTypeInMemberForm g membInfo.MemberFlags (Option.get v.ValReprInfo) numEnclosingTypars v.Type v.Range + let prefix, name = + match membInfo.MemberFlags.MemberKind with + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor -> "M:", "#ctor" + | SynMemberKind.Member -> "M:", v.CompiledName g.CompilerGlobalState + | SynMemberKind.PropertyGetSet + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGet -> "P:", v.PropertyName + let path = if v.HasDeclaringEntity then prependPath path v.TopValDeclaringEntity.CompiledName else path + let parentTypars, methTypars = + match PartitionValTypars g v with + | Some(_, memberParentTypars, memberMethodTypars, _, _) -> memberParentTypars, memberMethodTypars + | None -> [], tps + parentTypars, methTypars, witnessInfos, argInfos, rty, prefix, path, name + | _ -> + // Regular F# values and extension members + let w = arityOfVal v + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal v + let tps, witnessInfos, argInfos, rty, _ = GetTopValTypeInCompiledForm g w numEnclosingTypars v.Type v.Range + let name = v.CompiledName g.CompilerGlobalState + let prefix = + if w.NumCurriedArgs = 0 && isNil tps then "P:" + else "M:" + [], tps, witnessInfos, argInfos, rty, prefix, path, name + + let witnessArgTys = GenWitnessTys g cxs + let argTys = argInfos |> List.concat |> List.map fst + let argTys = witnessArgTys @ argTys @ (match rty with Some t when full -> [t] | _ -> []) + let args = XmlDocArgsEnc g (parentTypars, methTypars) argTys + let arity = List.length methTypars in (* C# XML doc adds `` to *generic* member names *) + let genArity = if arity=0 then "" else sprintf "``%d" arity + prefix + prependPath path name + genArity + args + +let BuildXmlDocSig prefix paths = prefix + List.fold prependPath "" paths + +let XmlDocSigOfUnionCase = BuildXmlDocSig "T:" // Would like to use "U:", but ParseMemberSignature only accepts C# signatures + +let XmlDocSigOfField = BuildXmlDocSig "F:" + +let XmlDocSigOfProperty = BuildXmlDocSig "P:" + +let XmlDocSigOfTycon = BuildXmlDocSig "T:" + +let XmlDocSigOfSubModul = BuildXmlDocSig "T:" + +let XmlDocSigOfEntity (eref: EntityRef) = + XmlDocSigOfTycon [(buildAccessPath eref.CompilationPathOpt); eref.Deref.CompiledName] + +//-------------------------------------------------------------------------- +// Some unions have null as representations +//-------------------------------------------------------------------------- + + +let enum_CompilationRepresentationAttribute_Static = 0b0000000000000001 +let enum_CompilationRepresentationAttribute_Instance = 0b0000000000000010 +let enum_CompilationRepresentationAttribute_StaticInstanceMask = 0b0000000000000011 +let enum_CompilationRepresentationAttribute_ModuleSuffix = 0b0000000000000100 +let enum_CompilationRepresentationAttribute_PermitNull = 0b0000000000001000 + +let HasUseNullAsTrueValueAttribute g attribs = + match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attribs with + | Some flags -> ((flags &&& enum_CompilationRepresentationAttribute_PermitNull) <> 0) + | _ -> false + +let TyconHasUseNullAsTrueValueAttribute g (tycon: Tycon) = HasUseNullAsTrueValueAttribute g tycon.Attribs + +// WARNING: this must match optimizeAlternativeToNull in ilx/cu_erase.fs +let CanHaveUseNullAsTrueValueAttribute (_g: TcGlobals) (tycon: Tycon) = + (tycon.IsUnionTycon && + let ucs = tycon.UnionCasesArray + (ucs.Length = 0 || + (ucs |> Array.existsOne (fun uc -> uc.IsNullary) && + ucs |> Array.exists (fun uc -> not uc.IsNullary)))) + +// WARNING: this must match optimizeAlternativeToNull in ilx/cu_erase.fs +let IsUnionTypeWithNullAsTrueValue (g: TcGlobals) (tycon: Tycon) = + (tycon.IsUnionTycon && + let ucs = tycon.UnionCasesArray + (ucs.Length = 0 || + (TyconHasUseNullAsTrueValueAttribute g tycon && + ucs |> Array.existsOne (fun uc -> uc.IsNullary) && + ucs |> Array.exists (fun uc -> not uc.IsNullary)))) + +let TyconCompilesInstanceMembersAsStatic g tycon = IsUnionTypeWithNullAsTrueValue g tycon +let TcrefCompilesInstanceMembersAsStatic g (tcref: TyconRef) = TyconCompilesInstanceMembersAsStatic g tcref.Deref + +// Note, isStructTy does not include type parameters with the ': struct' constraint +// This predicate is used to detect those type parameters. +let isNonNullableStructTyparTy g ty = + match tryDestTyparTy g ty with + | ValueSome tp -> + tp.Constraints |> List.exists (function TyparConstraint.IsNonNullableStruct _ -> true | _ -> false) + | ValueNone -> + false + +// Note, isRefTy does not include type parameters with the ': not struct' constraint +// This predicate is used to detect those type parameters. +let isReferenceTyparTy g ty = + match tryDestTyparTy g ty with + | ValueSome tp -> + tp.Constraints |> List.exists (function TyparConstraint.IsReferenceType _ -> true | _ -> false) + | ValueNone -> + false + +let TypeNullNever g ty = + let underlyingTy = stripTyEqnsAndMeasureEqns g ty + isStructTy g underlyingTy || + isByrefTy g underlyingTy || + isNonNullableStructTyparTy g ty + +/// Indicates if the type admits the use of 'null' as a value +let TypeNullIsExtraValue g m ty = + if isILReferenceTy g ty || isDelegateTy g ty then + // Putting AllowNullLiteralAttribute(false) on an IL or provided type means 'null' can't be used with that type + not (match tryTcrefOfAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some false | _ -> false) + elif TypeNullNever g ty then + false + else + // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some true + | ValueNone -> + + // Consider type parameters + if isReferenceTyparTy g ty then + (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) + else + false + +let TypeNullIsTrueValue g ty = + (match tryTcrefOfAppTy g ty with + | ValueSome tcref -> IsUnionTypeWithNullAsTrueValue g tcref.Deref + | _ -> false) + || isUnitTy g ty + +let TypeNullNotLiked g m ty = + not (TypeNullIsExtraValue g m ty) + && not (TypeNullIsTrueValue g ty) + && not (TypeNullNever g ty) + +// The non-inferring counter-part to SolveTypeSupportsNull +let TypeSatisfiesNullConstraint g m ty = + TypeNullIsExtraValue g m ty + +// The non-inferring counter-part to SolveTypeRequiresDefaultValue (and SolveTypeRequiresDefaultConstructor for struct types) +let rec TypeHasDefaultValue g m ty = + let ty = stripTyEqnsAndMeasureEqns g ty + // Check reference types - precisely the ones satisfying the ': null' constraint have default values + TypeSatisfiesNullConstraint g m ty + || + // Check nominal struct types + (isStructTy g ty && + // F# struct types have a DefaultValue if all their field types have a default value excluding those with DefaultValue(false) + (if isFSharpStructTy g ty then + let tcref, tinst = destAppTy g ty + let flds = + // Note this includes fields implied by the use of the implicit class construction syntax + tcref.AllInstanceFieldsAsList + // We can ignore fields with the DefaultValue(false) attribute + |> List.filter (fun fld -> not (TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute fld.FieldAttribs = Some false)) + + flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g m) + + // Struct tuple types have a DefaultValue if all their element types have a default value + elif isStructTupleTy g ty then + destStructTupleTy g ty |> List.forall (TypeHasDefaultValue g m) + + // Struct anonymous record types have a DefaultValue if all their element types have a default value + elif isStructAnonRecdTy g ty then + match tryDestAnonRecdTy g ty with + | ValueNone -> true + | ValueSome (_, ptys) -> ptys |> List.forall (TypeHasDefaultValue g m) + else + // All nominal struct types defined in other .NET languages have a DefaultValue regardless of their instantiation + true)) + || + // Check for type variables with the ":struct" and "(new : unit -> 'T)" constraints + (isNonNullableStructTyparTy g ty && + (destTyparTy g ty).Constraints |> List.exists (function TyparConstraint.RequiresDefaultConstructor _ -> true | _ -> false)) + +/// Determines types that are potentially known to satisfy the 'comparable' constraint and returns +/// a set of residual types that must also satisfy the constraint +let (|SpecialComparableHeadType|_|) g ty = + if isAnyTupleTy g ty then + let _tupInfo, elemTys = destAnyTupleTy g ty + Some elemTys + elif isAnonRecdTy g ty then + match tryDestAnonRecdTy g ty with + | ValueNone -> Some [] + | ValueSome (_anonInfo, elemTys) -> Some elemTys + else + match tryAppTy g ty with + | ValueSome (tcref, tinst) -> + if isArrayTyconRef g tcref || + tyconRefEq g tcref g.system_UIntPtr_tcref || + tyconRefEq g tcref g.system_IntPtr_tcref then + Some tinst + else + None + | _ -> + None + +let (|SpecialEquatableHeadType|_|) g ty = (|SpecialComparableHeadType|_|) g ty + +let (|SpecialNotEquatableHeadType|_|) g ty = + if isFunTy g ty then Some() else None + +// Can we use the fast helper for the 'LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric'? +let canUseTypeTestFast g ty = + not (isTyparTy g ty) && + not (TypeNullIsTrueValue g ty) && + not (TypeNullNever g ty) + +// Can we use the fast helper for the 'LanguagePrimitives.IntrinsicFunctions.UnboxGeneric'? +let canUseUnboxFast g m ty = + not (isTyparTy g ty) && + not (TypeNullNotLiked g m ty) + +//-------------------------------------------------------------------------- +// Nullness tests and pokes +//-------------------------------------------------------------------------- + +// Generates the logical equivalent of +// match inp with :? ty as v -> e2[v] | _ -> e3 +// +// No sequence point is generated for this expression form as this function is only +// used for compiler-generated code. +let mkIsInstConditional g m tgty vinpe v e2 e3 = + + if canUseTypeTestFast g tgty then + + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m) + let tg2 = mbuilder.AddResultTarget(e2, DebugPointAtTarget.No) + let tg3 = mbuilder.AddResultTarget(e3, DebugPointAtTarget.No) + let dtree = TDSwitch(DebugPointAtSwitch.No, exprForVal m v, [TCase(DecisionTreeTest.IsNull, tg3)], Some tg2, m) + let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) + mkCompGenLet m v (mkIsInst tgty vinpe m) expr + + else + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m) + let tg2 = TDSuccess([mkCallUnbox g m tgty vinpe], mbuilder.AddTarget(TTarget([v], e2, DebugPointAtTarget.No, None))) + let tg3 = mbuilder.AddResultTarget(e3, DebugPointAtTarget.No) + let dtree = TDSwitch(DebugPointAtSwitch.No, vinpe, [TCase(DecisionTreeTest.IsInst(tyOfExpr g vinpe, tgty), tg2)], Some tg3, m) + let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) + expr + +// Called for when creating compiled form of 'let fixed ...'. +// +// No sequence point is generated for this expression form as this function is only +// used for compiler-generated code. +let mkNullTest g m e1 e2 e3 = + let mbuilder = MatchBuilder(DebugPointAtBinding.NoneAtInvisible, m) + let tg2 = mbuilder.AddResultTarget(e2, DebugPointAtTarget.No) + let tg3 = mbuilder.AddResultTarget(e3, DebugPointAtTarget.No) + let dtree = TDSwitch(DebugPointAtSwitch.No, e1, [TCase(DecisionTreeTest.IsNull, tg3)], Some tg2, m) + let expr = mbuilder.Close(dtree, m, tyOfExpr g e2) + expr + +let mkNonNullTest (g: TcGlobals) m e = + mkAsmExpr ([ AI_ldnull ; AI_cgt_un ], [], [e], [g.bool_ty], m) + +// No sequence point is generated for this expression form as this function is only +// used for compiler-generated code. +let mkNonNullCond g m ty e1 e2 e3 = + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m ty (mkNonNullTest g m e1) e2 e3 + +// No sequence point is generated for this expression form as this function is only +// used for compiler-generated code. +let mkIfThen (g: TcGlobals) m e1 e2 = + mkCond DebugPointAtBinding.NoneAtSticky DebugPointAtTarget.No m g.unit_ty e1 e2 (mkUnit g m) + +let ModuleNameIsMangled g attrs = + match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attrs with + | Some flags -> ((flags &&& enum_CompilationRepresentationAttribute_ModuleSuffix) <> 0) + | _ -> false + +let CompileAsEvent g attrs = HasFSharpAttribute g g.attrib_CLIEventAttribute attrs + +let MemberIsCompiledAsInstance g parent isExtensionMember (membInfo: ValMemberInfo) attrs = + // All extension members are compiled as static members + if isExtensionMember then false + // Anything implementing a dispatch slot is compiled as an instance member + elif membInfo.MemberFlags.IsOverrideOrExplicitImpl then true + elif not (isNil membInfo.ImplementedSlotSigs) then true + else + // Otherwise check attributes to see if there is an explicit instance or explicit static flag + let explicitInstance, explicitStatic = + match TryFindFSharpInt32Attribute g g.attrib_CompilationRepresentationAttribute attrs with + | Some flags -> + ((flags &&& enum_CompilationRepresentationAttribute_Instance) <> 0), + ((flags &&& enum_CompilationRepresentationAttribute_Static) <> 0) + | _ -> false, false + explicitInstance || + (membInfo.MemberFlags.IsInstance && + not explicitStatic && + not (TcrefCompilesInstanceMembersAsStatic g parent)) + + +let isSealedTy g ty = + let ty = stripTyEqnsAndMeasureEqns g ty + not (isRefTy g ty) || + isUnitTy g ty || + isArrayTy g ty || + + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata st -> st.IsSealed +#endif + | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsSealed + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + if (isFSharpInterfaceTy g ty || isFSharpClassTy g ty) then + let tcref = tcrefOfAppTy g ty + TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some true + else + // All other F# types, array, byref, tuple types are sealed + true + +let isComInteropTy g ty = + let tcref = tcrefOfAppTy g ty + match g.attrib_ComImportAttribute with + | None -> false + | Some attr -> TryFindFSharpBoolAttribute g attr tcref.Attribs = Some true + +let ValSpecIsCompiledAsInstance g (v: Val) = + match v.MemberInfo with + | Some membInfo -> + // Note it doesn't matter if we pass 'v.TopValDeclaringEntity' or 'v.MemberApparentEntity' here. + // These only differ if the value is an extension member, and in that case MemberIsCompiledAsInstance always returns + // false anyway + MemberIsCompiledAsInstance g v.MemberApparentEntity v.IsExtensionMember membInfo v.Attribs + | _ -> false + +let ValRefIsCompiledAsInstanceMember g (vref: ValRef) = ValSpecIsCompiledAsInstance g vref.Deref + + +//--------------------------------------------------------------------------- +// Crack information about an F# object model call +//--------------------------------------------------------------------------- + +let GetMemberCallInfo g (vref: ValRef, vFlags) = + match vref.MemberInfo with + | Some membInfo when not vref.IsExtensionMember -> + let numEnclTypeArgs = vref.MemberApparentEntity.TyparsNoRange.Length + let virtualCall = + (membInfo.MemberFlags.IsOverrideOrExplicitImpl || + membInfo.MemberFlags.IsDispatchSlot) && + not membInfo.MemberFlags.IsFinal && + (match vFlags with VSlotDirectCall -> false | _ -> true) + let isNewObj = (membInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) && (match vFlags with NormalValUse -> true | _ -> false) + let isSuperInit = (membInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) && (match vFlags with CtorValUsedAsSuperInit -> true | _ -> false) + let isSelfInit = (membInfo.MemberFlags.MemberKind = SynMemberKind.Constructor) && (match vFlags with CtorValUsedAsSelfInit -> true | _ -> false) + let isCompiledAsInstance = ValRefIsCompiledAsInstanceMember g vref + let takesInstanceArg = isCompiledAsInstance && not isNewObj + let isPropGet = (membInfo.MemberFlags.MemberKind = SynMemberKind.PropertyGet) && (membInfo.MemberFlags.IsInstance = isCompiledAsInstance) + let isPropSet = (membInfo.MemberFlags.MemberKind = SynMemberKind.PropertySet) && (membInfo.MemberFlags.IsInstance = isCompiledAsInstance) + numEnclTypeArgs, virtualCall, isNewObj, isSuperInit, isSelfInit, takesInstanceArg, isPropGet, isPropSet + | _ -> + 0, false, false, false, false, false, false, false + +//--------------------------------------------------------------------------- +// Active pattern name helpers +//--------------------------------------------------------------------------- + +let TryGetActivePatternInfo (vref: ValRef) = + // First is an optimization to prevent calls to string routines + let logicalName = vref.LogicalName + if logicalName.Length = 0 || logicalName.[0] <> '|' then + None + else + ActivePatternInfoOfValName vref.DisplayNameCoreMangled vref.Range + +type ActivePatternElemRef with + member x.Name = + let (APElemRef(_, vref, n, _)) = x + match TryGetActivePatternInfo vref with + | None -> error(InternalError("not an active pattern name", vref.Range)) + | Some apinfo -> + let nms = apinfo.ActiveTags + if n < 0 || n >= List.length nms then error(InternalError("name_of_apref: index out of range for active pattern reference", vref.Range)) + List.item n nms + +let mkChoiceTyconRef (g: TcGlobals) m n = + match n with + | 0 | 1 -> error(InternalError("mkChoiceTyconRef", m)) + | 2 -> g.choice2_tcr + | 3 -> g.choice3_tcr + | 4 -> g.choice4_tcr + | 5 -> g.choice5_tcr + | 6 -> g.choice6_tcr + | 7 -> g.choice7_tcr + | _ -> error(Error(FSComp.SR.tastActivePatternsLimitedToSeven(), m)) + +let mkChoiceTy (g: TcGlobals) m tinst = + match List.length tinst with + | 0 -> g.unit_ty + | 1 -> List.head tinst + | length -> mkAppTy (mkChoiceTyconRef g m length) tinst + +let mkChoiceCaseRef g m n i = + mkUnionCaseRef (mkChoiceTyconRef g m n) ("Choice"+string (i+1)+"Of"+string n) + +type ActivePatternInfo with + member x.Names = x.ActiveTags + + member apinfo.ResultType g m rtys isStruct = + let choicety = mkChoiceTy g m rtys + if apinfo.IsTotal then choicety + elif isStruct then mkValueOptionTy g choicety + else mkOptionTy g choicety + + member apinfo.OverallType g m dty rtys isStruct = + mkFunTy dty (apinfo.ResultType g m rtys isStruct) + +//--------------------------------------------------------------------------- +// Active pattern validation +//--------------------------------------------------------------------------- + +// check if an active pattern takes type parameters only bound by the return types, +// not by their argument types. +let doesActivePatternHaveFreeTypars g (v: ValRef) = + let vty = v.TauType + let vtps = v.Typars |> Zset.ofList typarOrder + if not (isFunTy g v.TauType) then + errorR(Error(FSComp.SR.activePatternIdentIsNotFunctionTyped(v.LogicalName), v.Range)) + let argtys, resty = stripFunTy g vty + let argtps, restps= (freeInTypes CollectTypars argtys).FreeTypars, (freeInType CollectTypars resty).FreeTypars + // Error if an active pattern is generic in type variables that only occur in the result Choice<_, ...>. + // Note: The test restricts to v.Typars since typars from the closure are considered fixed. + not (Zset.isEmpty (Zset.inter (Zset.diff restps argtps) vtps)) + +//--------------------------------------------------------------------------- +// RewriteExpr: rewrite bottom up with interceptors +//--------------------------------------------------------------------------- + +[] +type ExprRewritingEnv = + { PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option + PostTransform: Expr -> Expr option + PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option + IsUnderQuotations: bool } + +let rec rewriteBind env bind = + match env.PreInterceptBinding with + | Some f -> + match f (RewriteExpr env) bind with + | Some res -> res + | None -> rewriteBindStructure env bind + | None -> rewriteBindStructure env bind + +and rewriteBindStructure env (TBind(v, e, letSeqPtOpt)) = + TBind(v, RewriteExpr env e, letSeqPtOpt) + +and rewriteBinds env binds = List.map (rewriteBind env) binds + +and RewriteExpr env expr = + match expr with + | LinearOpExpr _ + | LinearMatchExpr _ + | Expr.Let _ + | Expr.Sequential _ -> + rewriteLinearExpr env expr (fun e -> e) + | _ -> + let expr = + match preRewriteExpr env expr with + | Some expr -> expr + | None -> rewriteExprStructure env expr + postRewriteExpr env expr + +and preRewriteExpr env expr = + match env.PreIntercept with + | Some f -> f (RewriteExpr env) expr + | None -> None + +and postRewriteExpr env expr = + match env.PostTransform expr with + | None -> expr + | Some expr2 -> expr2 + +and rewriteExprStructure env expr = + match expr with + | Expr.Const _ + | Expr.Val _ -> expr + + | Expr.App (f0, f0ty, tyargs, args, m) -> + let f0' = RewriteExpr env f0 + let args' = rewriteExprs env args + if f0 === f0' && args === args' then expr + else Expr.App (f0', f0ty, tyargs, args', m) + + | Expr.Quote (ast, dataCell, isFromQueryExpression, m, ty) -> + let data = + match dataCell.Value with + | None -> None + | Some (data1, data2) -> Some(map3Of4 (rewriteExprs env) data1, map3Of4 (rewriteExprs env) data2) + Expr.Quote ((if env.IsUnderQuotations then RewriteExpr env ast else ast), ref data, isFromQueryExpression, m, ty) + + | Expr.Obj (_, ty, basev, basecall, overrides, iimpls, m) -> + mkObjExpr(ty, basev, RewriteExpr env basecall, List.map (rewriteObjExprOverride env) overrides, + List.map (rewriteObjExprInterfaceImpl env) iimpls, m) + | Expr.Link eref -> + RewriteExpr env !eref + + | Expr.Op (c, tyargs, args, m) -> + let args' = rewriteExprs env args + if args === args' then expr + else Expr.Op (c, tyargs, args', m) + + | Expr.Lambda (_lambdaId, ctorThisValOpt, baseValOpt, argvs, body, m, rty) -> + let body = RewriteExpr env body + rebuildLambda m ctorThisValOpt baseValOpt argvs (body, rty) + + | Expr.TyLambda (_lambdaId, argtyvs, body, m, rty) -> + let body = RewriteExpr env body + mkTypeLambda m argtyvs (body, rty) + + | Expr.Match (spBind, exprm, dtree, targets, m, ty) -> + let dtree' = RewriteDecisionTree env dtree + let targets' = rewriteTargets env targets + mkAndSimplifyMatch spBind exprm m ty dtree' targets' + + | Expr.LetRec (binds, e, m, _) -> + let binds = rewriteBinds env binds + let e' = RewriteExpr env e + Expr.LetRec (binds, e', m, Construct.NewFreeVarsCache()) + + | Expr.Let _ -> failwith "unreachable - linear let" + + | Expr.Sequential _ -> failwith "unreachable - linear seq" + + | Expr.StaticOptimization (constraints, e2, e3, m) -> + let e2' = RewriteExpr env e2 + let e3' = RewriteExpr env e3 + Expr.StaticOptimization (constraints, e2', e3', m) + + | Expr.TyChoose (a, b, m) -> + Expr.TyChoose (a, RewriteExpr env b, m) + + | Expr.WitnessArg (witnessInfo, m) -> + Expr.WitnessArg (witnessInfo, m) + +and rewriteLinearExpr env expr contf = + // schedule a rewrite on the way back up by adding to the continuation + let contf = contf << postRewriteExpr env + match preRewriteExpr env expr with + | Some expr -> contf expr + | None -> + match expr with + | Expr.Let (bind, bodyExpr, m, _) -> + let bind = rewriteBind env bind + // tailcall + rewriteLinearExpr env bodyExpr (contf << (fun bodyExpr' -> + mkLetBind m bind bodyExpr')) + + | Expr.Sequential (expr1, expr2, dir, spSeq, m) -> + let expr1' = RewriteExpr env expr1 + // tailcall + rewriteLinearExpr env expr2 (contf << (fun expr2' -> + if expr1 === expr1' && expr2 === expr2' then expr + else Expr.Sequential (expr1', expr2', dir, spSeq, m))) + + | LinearOpExpr (op, tyargs, argsFront, argLast, m) -> + let argsFront' = rewriteExprs env argsFront + // tailcall + rewriteLinearExpr env argLast (contf << (fun argLast' -> + if argsFront === argsFront' && argLast === argLast' then expr + else rebuildLinearOpExpr (op, tyargs, argsFront', argLast', m))) + + | LinearMatchExpr (spBind, exprm, dtree, tg1, expr2, sp2, m2, ty) -> + let dtree = RewriteDecisionTree env dtree + let tg1' = rewriteTarget env tg1 + // tailcall + rewriteLinearExpr env expr2 (contf << (fun expr2' -> + rebuildLinearMatchExpr (spBind, exprm, dtree, tg1', expr2', sp2, m2, ty))) + | _ -> + // no longer linear, no tailcall + contf (RewriteExpr env expr) + +and rewriteExprs env exprs = List.mapq (RewriteExpr env) exprs + +and rewriteFlatExprs env exprs = List.mapq (RewriteExpr env) exprs + +and RewriteDecisionTree env x = + match x with + | TDSuccess (es, n) -> + let esR = rewriteFlatExprs env es + if LanguagePrimitives.PhysicalEquality es esR then x + else TDSuccess(esR, n) + + | TDSwitch (sp, e, cases, dflt, m) -> + let eR = RewriteExpr env e + let casesR = List.map (fun (TCase(discrim, e)) -> TCase(discrim, RewriteDecisionTree env e)) cases + let dfltR = Option.map (RewriteDecisionTree env) dflt + TDSwitch (sp, eR, casesR, dfltR, m) + + | TDBind (bind, body) -> + let bindR = rewriteBind env bind + let bodyR = RewriteDecisionTree env body + TDBind (bindR, bodyR) + +and rewriteTarget env (TTarget(vs, e, spTarget, flags)) = + let eR = RewriteExpr env e + TTarget(vs, eR, spTarget, flags) + +and rewriteTargets env targets = + List.map (rewriteTarget env) (Array.toList targets) + +and rewriteObjExprOverride env (TObjExprMethod(slotsig, attribs, tps, vs, e, m)) = + TObjExprMethod(slotsig, attribs, tps, vs, RewriteExpr env e, m) + +and rewriteObjExprInterfaceImpl env (ty, overrides) = + (ty, List.map (rewriteObjExprOverride env) overrides) + +and rewriteModuleOrNamespaceExpr env x = + match x with + | ModuleOrNamespaceExprWithSig(mty, def, m) -> ModuleOrNamespaceExprWithSig(mty, rewriteModuleOrNamespaceDef env def, m) + +and rewriteModuleOrNamespaceDefs env x = List.map (rewriteModuleOrNamespaceDef env) x + +and rewriteModuleOrNamespaceDef env x = + match x with + | TMDefRec(isRec, opens, tycons, mbinds, m) -> TMDefRec(isRec, opens, tycons, rewriteModuleOrNamespaceBindings env mbinds, m) + | TMDefLet(bind, m) -> TMDefLet(rewriteBind env bind, m) + | TMDefDo(e, m) -> TMDefDo(RewriteExpr env e, m) + | TMDefOpens _ -> x + | TMDefs defs -> TMDefs(rewriteModuleOrNamespaceDefs env defs) + | TMAbstract mexpr -> TMAbstract(rewriteModuleOrNamespaceExpr env mexpr) + +and rewriteModuleOrNamespaceBinding env x = + match x with + | ModuleOrNamespaceBinding.Binding bind -> ModuleOrNamespaceBinding.Binding (rewriteBind env bind) + | ModuleOrNamespaceBinding.Module(nm, rhs) -> ModuleOrNamespaceBinding.Module(nm, rewriteModuleOrNamespaceDef env rhs) + +and rewriteModuleOrNamespaceBindings env mbinds = List.map (rewriteModuleOrNamespaceBinding env) mbinds + +and RewriteImplFile env mv = mapTImplFile (rewriteModuleOrNamespaceExpr env) mv + + + +//-------------------------------------------------------------------------- +// Build a Remap that converts all "local" references to "public" things +// accessed via non local references. +//-------------------------------------------------------------------------- + +let MakeExportRemapping viewedCcu (mspec: ModuleOrNamespace) = + + let accEntityRemap (entity: Entity) acc = + match tryRescopeEntity viewedCcu entity with + | ValueSome eref -> + addTyconRefRemap (mkLocalTyconRef entity) eref acc + | _ -> + if entity.IsNamespace then + acc + else + error(InternalError("Unexpected entity without a pubpath when remapping assembly data", entity.Range)) + + let accValRemap (vspec: Val) acc = + // The acc contains the entity remappings + match tryRescopeVal viewedCcu acc vspec with + | ValueSome vref -> + {acc with valRemap=acc.valRemap.Add vspec vref } + | _ -> + error(InternalError("Unexpected value without a pubpath when remapping assembly data", vspec.Range)) + + let mty = mspec.ModuleOrNamespaceType + let entities = allEntitiesOfModuleOrNamespaceTy mty + let vs = allValsOfModuleOrNamespaceTy mty + // Remap the entities first so we can correctly remap the types in the signatures of the ValLinkageFullKey's in the value references + let acc = List.foldBack accEntityRemap entities Remap.Empty + let allRemap = List.foldBack accValRemap vs acc + allRemap + +//-------------------------------------------------------------------------- +// Apply a "local to nonlocal" renaming to a module type. This can't use +// remap_mspec since the remapping we want isn't to newly created nodes +// but rather to remap to the nonlocal references. This is deliberately +// "breaking" the binding structure implicit in the module type, which is +// the whole point - one things are rewritten to use non local references then +// the elements can be copied at will, e.g. when inlining during optimization. +//------------------------------------------------------------------------ + + +let rec remapEntityDataToNonLocal g tmenv (d: Entity) = + let tps', tmenvinner = tmenvCopyRemapAndBindTypars (remapAttribs g tmenv) tmenv (d.entity_typars.Force(d.entity_range)) + let typarsR = LazyWithContext.NotLazy tps' + let attribsR = d.entity_attribs |> remapAttribs g tmenvinner + let tyconReprR = d.entity_tycon_repr |> remapTyconRepr g tmenvinner + let tyconAbbrevR = d.TypeAbbrev |> Option.map (remapType tmenvinner) + let tyconTcaugR = d.entity_tycon_tcaug |> remapTyconAug tmenvinner + let modulContentsR = + MaybeLazy.Strict (d.entity_modul_contents.Value + |> mapImmediateValsAndTycons (remapTyconToNonLocal g tmenv) (remapValToNonLocal g tmenv)) + let exnInfoR = d.ExceptionInfo |> remapTyconExnInfo g tmenvinner + { d with + entity_typars = typarsR + entity_attribs = attribsR + entity_tycon_repr = tyconReprR + entity_tycon_tcaug = tyconTcaugR + entity_modul_contents = modulContentsR + entity_opt_data = + match d.entity_opt_data with + | Some dd -> + Some { dd with entity_tycon_abbrev = tyconAbbrevR; entity_exn_info = exnInfoR } + | _ -> None } + +and remapTyconToNonLocal g tmenv x = + x |> Construct.NewModifiedTycon (remapEntityDataToNonLocal g tmenv) + +and remapValToNonLocal g tmenv inp = + // creates a new stamp + inp |> Construct.NewModifiedVal (remapValData g tmenv) + +let ApplyExportRemappingToEntity g tmenv x = remapTyconToNonLocal g tmenv x + +(* Which constraints actually get compiled to .NET constraints? *) +let isCompiledOrWitnessPassingConstraint (g: TcGlobals) cx = + match cx with + | TyparConstraint.SupportsNull _ // this implies the 'class' constraint + | TyparConstraint.IsReferenceType _ // this is the 'class' constraint + | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.IsReferenceType _ + | TyparConstraint.RequiresDefaultConstructor _ + | TyparConstraint.CoercesTo _ -> true + | TyparConstraint.MayResolveMember _ when g.langVersion.SupportsFeature LanguageFeature.WitnessPassing -> true + | _ -> false + +// Is a value a first-class polymorphic value with .NET constraints, or witness-passing constraints? +// Used to turn off TLR and method splitting and do not compile to +// FSharpTypeFunc, but rather bake a "local type function" for each TyLambda abstraction. +let IsGenericValWithGenericConstraints g (v: Val) = + isForallTy g v.Type && + v.Type |> destForallTy g |> fst |> List.exists (fun tp -> List.exists (isCompiledOrWitnessPassingConstraint g) tp.Constraints) + +// Does a type support a given interface? +type Entity with + member tycon.HasInterface g ty = + tycon.TypeContents.tcaug_interfaces |> List.exists (fun (x, _, _) -> typeEquiv g ty x) + + // Does a type have an override matching the given name and argument types? + // Used to detect the presence of 'Equals' and 'GetHashCode' in type checking + member tycon.HasOverride g nm argtys = + tycon.TypeContents.tcaug_adhoc + |> NameMultiMap.find nm + |> List.exists (fun vref -> + match vref.MemberInfo with + | None -> false + | Some membInfo -> + let argInfos = ArgInfosOfMember g vref + argInfos.Length = 1 && + List.lengthsEqAndForall2 (typeEquiv g) (List.map fst (List.head argInfos)) argtys && + membInfo.MemberFlags.IsOverrideOrExplicitImpl) + + member tycon.HasMember g nm argtys = + tycon.TypeContents.tcaug_adhoc + |> NameMultiMap.find nm + |> List.exists (fun vref -> + match vref.MemberInfo with + | None -> false + | _ -> let argInfos = ArgInfosOfMember g vref + argInfos.Length = 1 && + List.lengthsEqAndForall2 (typeEquiv g) (List.map fst (List.head argInfos)) argtys) + + +type EntityRef with + member tcref.HasInterface g ty = tcref.Deref.HasInterface g ty + member tcref.HasOverride g nm argtys = tcref.Deref.HasOverride g nm argtys + member tcref.HasMember g nm argtys = tcref.Deref.HasMember g nm argtys + +let mkFastForLoop g (spLet, m, idv: Val, start, dir, finish, body) = + let dir = if dir then FSharpForLoopUp else FSharpForLoopDown + mkFor g (spLet, idv, start, dir, finish, body, m) + + +/// Accessing a binding of the form "let x = 1" or "let x = e" for any "e" satisfying the predicate +/// below does not cause an initialization trigger, i.e. does not get compiled as a static field. +let IsSimpleSyntacticConstantExpr g inputExpr = + let rec checkExpr (vrefs: Set) x = + match stripExpr x with + | Expr.Op (TOp.Coerce, _, [arg], _) + -> checkExpr vrefs arg + | UnopExpr g (vref, arg) + when (valRefEq g vref g.unchecked_unary_minus_vref || + valRefEq g vref g.unchecked_unary_plus_vref || + valRefEq g vref g.unchecked_unary_not_vref || + valRefEq g vref g.bitwise_unary_not_vref || + valRefEq g vref g.enum_vref) + -> checkExpr vrefs arg + // compare, =, <>, +, -, <, >, <=, >=, <<<, >>>, &&& + | BinopExpr g (vref, arg1, arg2) + when (valRefEq g vref g.equals_operator_vref || + valRefEq g vref g.compare_operator_vref || + valRefEq g vref g.unchecked_addition_vref || + valRefEq g vref g.less_than_operator_vref || + valRefEq g vref g.less_than_or_equals_operator_vref || + valRefEq g vref g.greater_than_operator_vref || + valRefEq g vref g.greater_than_or_equals_operator_vref || + valRefEq g vref g.not_equals_operator_vref || + valRefEq g vref g.unchecked_addition_vref || + valRefEq g vref g.unchecked_multiply_vref || + valRefEq g vref g.unchecked_subtraction_vref || + // Note: division and modulus can raise exceptions, so are not included + valRefEq g vref g.bitwise_shift_left_vref || + valRefEq g vref g.bitwise_shift_right_vref || + valRefEq g vref g.bitwise_xor_vref || + valRefEq g vref g.bitwise_and_vref || + valRefEq g vref g.bitwise_or_vref) && + (not (typeEquiv g (tyOfExpr g arg1) g.string_ty) && not (typeEquiv g (tyOfExpr g arg1) g.decimal_ty) ) + -> checkExpr vrefs arg1 && checkExpr vrefs arg2 + | Expr.Val (vref, _, _) -> vref.Deref.IsCompiledAsStaticPropertyWithoutField || vrefs.Contains vref.Stamp + | Expr.Match (_, _, dtree, targets, _, _) -> checkDecisionTree vrefs dtree && targets |> Array.forall (checkDecisionTreeTarget vrefs) + | Expr.Let (b, e, _, _) -> checkExpr vrefs b.Expr && checkExpr (vrefs.Add b.Var.Stamp) e + // Detect standard constants + | Expr.TyChoose (_, b, _) -> checkExpr vrefs b + | Expr.Const _ + | Expr.Op (TOp.UnionCase _, _, [], _) // Nullary union cases + | UncheckedDefaultOfExpr g _ + | SizeOfExpr g _ + | TypeOfExpr g _ -> true + | NameOfExpr g _ when g.langVersion.SupportsFeature LanguageFeature.NameOf -> true + // All others are not simple constant expressions + | _ -> false + + and checkDecisionTree vrefs x = + match x with + | TDSuccess (es, _n) -> es |> List.forall (checkExpr vrefs) + | TDSwitch (_, e, cases, dflt, _m) -> + checkExpr vrefs e && + cases |> List.forall (checkDecisionTreeCase vrefs) && + dflt |> Option.forall (checkDecisionTree vrefs) + | TDBind (bind, body) -> + checkExpr vrefs bind.Expr && + checkDecisionTree (vrefs.Add bind.Var.Stamp) body + + and checkDecisionTreeCase vrefs (TCase(discrim, dtree)) = + (match discrim with + | DecisionTreeTest.Const _c -> true + | _ -> false) && + checkDecisionTree vrefs dtree + + and checkDecisionTreeTarget vrefs (TTarget(vs, e, _, _)) = + let vrefs = ((vrefs, vs) ||> List.fold (fun s v -> s.Add v.Stamp)) + checkExpr vrefs e + + checkExpr Set.empty inputExpr + +let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64) (arg1: Expr) (arg2: Expr) = + // At compile-time we check arithmetic + let m = unionRanges arg1.Range arg2.Range + try + match arg1, arg2 with + | Expr.Const (Const.Int32 x1, _, ty), Expr.Const (Const.Int32 x2, _, _) -> Expr.Const (Const.Int32 (opInt32 x1 x2), m, ty) + | Expr.Const (Const.SByte x1, _, ty), Expr.Const (Const.SByte x2, _, _) -> Expr.Const (Const.SByte (opInt8 x1 x2), m, ty) + | Expr.Const (Const.Int16 x1, _, ty), Expr.Const (Const.Int16 x2, _, _) -> Expr.Const (Const.Int16 (opInt16 x1 x2), m, ty) + | Expr.Const (Const.Int64 x1, _, ty), Expr.Const (Const.Int64 x2, _, _) -> Expr.Const (Const.Int64 (opInt64 x1 x2), m, ty) + | Expr.Const (Const.Byte x1, _, ty), Expr.Const (Const.Byte x2, _, _) -> Expr.Const (Const.Byte (opUInt8 x1 x2), m, ty) + | Expr.Const (Const.UInt16 x1, _, ty), Expr.Const (Const.UInt16 x2, _, _) -> Expr.Const (Const.UInt16 (opUInt16 x1 x2), m, ty) + | Expr.Const (Const.UInt32 x1, _, ty), Expr.Const (Const.UInt32 x2, _, _) -> Expr.Const (Const.UInt32 (opUInt32 x1 x2), m, ty) + | Expr.Const (Const.UInt64 x1, _, ty), Expr.Const (Const.UInt64 x2, _, _) -> Expr.Const (Const.UInt64 (opUInt64 x1 x2), m, ty) + | _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m)) + with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m)) + +// See also PostTypeCheckSemanticChecks.CheckAttribArgExpr, which must match this precisely +let rec EvalAttribArgExpr g x = + match x with + + // Detect standard constants + | Expr.Const (c, m, _) -> + match c with + | Const.Bool _ + | Const.Int32 _ + | Const.SByte _ + | Const.Int16 _ + | Const.Int32 _ + | Const.Int64 _ + | Const.Byte _ + | Const.UInt16 _ + | Const.UInt32 _ + | Const.UInt64 _ + | Const.Double _ + | Const.Single _ + | Const.Char _ + | Const.Zero _ + | Const.String _ -> + x + | Const.Decimal _ | Const.IntPtr _ | Const.UIntPtr _ | Const.Unit _ -> + errorR (Error ( FSComp.SR.tastNotAConstantExpression(), m)) + x + + | TypeOfExpr g _ -> x + | TypeDefOfExpr g _ -> x + | Expr.Op (TOp.Coerce, _, [arg], _) -> + EvalAttribArgExpr g arg + | EnumExpr g arg1 -> + EvalAttribArgExpr g arg1 + // Detect bitwise or of attribute flags + | AttribBitwiseOrExpr g (arg1, arg2) -> + EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) + | SpecificBinopExpr g g.unchecked_addition_vref (arg1, arg2) -> + // At compile-time we check arithmetic + let v1, v2 = EvalAttribArgExpr g arg1, EvalAttribArgExpr g arg2 + match v1, v2 with + | Expr.Const (Const.String x1, m, ty), Expr.Const (Const.String x2, _, _) -> Expr.Const (Const.String (x1 + x2), m, ty) + | _ -> +#if ALLOW_ARITHMETIC_OPS_IN_LITERAL_EXPRESSIONS_AND_ATTRIBUTE_ARGS + EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) g v1 v2 +#else + errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) + x +#endif +#if ALLOW_ARITHMETIC_OPS_IN_LITERAL_EXPRESSIONS_AND_ATTRIBUTE_ARGS + | SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) -> + EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) g (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) + | SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) -> + EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) g (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) +#endif + | _ -> + errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) + x + + +and EvaledAttribExprEquality g e1 e2 = + match e1, e2 with + | Expr.Const (c1, _, _), Expr.Const (c2, _, _) -> c1 = c2 + | TypeOfExpr g ty1, TypeOfExpr g ty2 -> typeEquiv g ty1 ty2 + | TypeDefOfExpr g ty1, TypeDefOfExpr g ty2 -> typeEquiv g ty1 ty2 + | _ -> false + +let (|ConstToILFieldInit|_|) c = + match c with + | Const.SByte n -> Some (ILFieldInit.Int8 n) + | Const.Int16 n -> Some (ILFieldInit.Int16 n) + | Const.Int32 n -> Some (ILFieldInit.Int32 n) + | Const.Int64 n -> Some (ILFieldInit.Int64 n) + | Const.Byte n -> Some (ILFieldInit.UInt8 n) + | Const.UInt16 n -> Some (ILFieldInit.UInt16 n) + | Const.UInt32 n -> Some (ILFieldInit.UInt32 n) + | Const.UInt64 n -> Some (ILFieldInit.UInt64 n) + | Const.Bool n -> Some (ILFieldInit.Bool n) + | Const.Char n -> Some (ILFieldInit.Char (uint16 n)) + | Const.Single n -> Some (ILFieldInit.Single n) + | Const.Double n -> Some (ILFieldInit.Double n) + | Const.String s -> Some (ILFieldInit.String s) + | Const.Zero -> Some ILFieldInit.Null + | _ -> None + +let EvalLiteralExprOrAttribArg g x = + match x with + | Expr.Op (TOp.Coerce, _, [Expr.Op (TOp.Array, [elemTy], args, m)], _) + | Expr.Op (TOp.Array, [elemTy], args, m) -> + let args = args |> List.map (EvalAttribArgExpr g) + Expr.Op (TOp.Array, [elemTy], args, m) + | _ -> + EvalAttribArgExpr g x + +// Take into account the fact that some "instance" members are compiled as static +// members when using CompilationRepresentation.Static, or any non-virtual instance members +// in a type that supports "null" as a true value. This is all members +// where ValRefIsCompiledAsInstanceMember is false but membInfo.MemberFlags.IsInstance +// is true. +// +// This is the right abstraction for viewing member types, but the implementation +// below is a little ugly. +let GetTypeOfIntrinsicMemberInCompiledForm g (vref: ValRef) = + assert (not vref.IsExtensionMember) + let membInfo, topValInfo = checkMemberValRef vref + let tps, cxs, argInfos, rty, retInfo = GetTypeOfMemberInMemberForm g vref + let argInfos = + // Check if the thing is really an instance member compiled as a static member + // If so, the object argument counts as a normal argument in the compiled form + if membInfo.MemberFlags.IsInstance && not (ValRefIsCompiledAsInstanceMember g vref) then + let _, origArgInfos, _, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type vref.Range + match origArgInfos with + | [] -> + errorR(InternalError("value does not have a valid member type", vref.Range)) + argInfos + | h :: _ -> h :: argInfos + else argInfos + tps, cxs, argInfos, rty, retInfo + + +//-------------------------------------------------------------------------- +// Tuple compilation (expressions) +//------------------------------------------------------------------------ + + +let rec mkCompiledTuple g isStruct (argtys, args, m) = + let n = List.length argtys + if n <= 0 then failwith "mkCompiledTuple" + elif n < maxTuple then (mkCompiledTupleTyconRef g isStruct n, argtys, args, m) + else + let argtysA, argtysB = List.splitAfter goodTupleFields argtys + let argsA, argsB = List.splitAfter goodTupleFields args + let ty8, v8 = + match argtysB, argsB with + | [ty8], [arg8] -> + match ty8 with + // if it's already been nested or ended, pass it through + | TType_app(tn, _) when (isCompiledTupleTyconRef g tn) -> + ty8, arg8 + | _ -> + let ty8enc = TType_app((if isStruct then g.struct_tuple1_tcr else g.ref_tuple1_tcr), [ty8]) + let v8enc = Expr.Op (TOp.Tuple (mkTupInfo isStruct), [ty8], [arg8], m) + ty8enc, v8enc + | _ -> + let a, b, c, d = mkCompiledTuple g isStruct (argtysB, argsB, m) + let ty8plus = TType_app(a, b) + let v8plus = Expr.Op (TOp.Tuple (mkTupInfo isStruct), b, c, d) + ty8plus, v8plus + let argtysAB = argtysA @ [ty8] + (mkCompiledTupleTyconRef g isStruct (List.length argtysAB), argtysAB, argsA @ [v8], m) + +let mkILMethodSpecForTupleItem (_g: TcGlobals) (ty: ILType) n = + mkILNonGenericInstanceMethSpecInTy(ty, (if n < goodTupleFields then "get_Item"+(n+1).ToString() else "get_Rest"), [], mkILTyvarTy (uint16 n)) + +let mkILFieldSpecForTupleItem (ty: ILType) n = + mkILFieldSpecInTy (ty, (if n < goodTupleFields then "Item"+(n+1).ToString() else "Rest"), mkILTyvarTy (uint16 n)) + +let mkGetTupleItemN g m n (ty: ILType) isStruct te retty = + if isStruct then + mkAsmExpr ([mkNormalLdfld (mkILFieldSpecForTupleItem ty n) ], [], [te], [retty], m) + else + mkAsmExpr ([mkNormalCall(mkILMethodSpecForTupleItem g ty n)], [], [te], [retty], m) + +/// Match an Int32 constant expression +let (|Int32Expr|_|) expr = + match expr with + | Expr.Const (Const.Int32 n, _, _) -> Some n + | _ -> None + +/// Match a try-finally expression +let (|TryFinally|_|) expr = + match expr with + | Expr.Op (TOp.TryFinally _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], _) -> Some(e1, e2) + | _ -> None + +// detect ONLY the while loops that result from compiling 'for ... in ... do ...' +let (|WhileLoopForCompiledForEachExpr|_|) expr = + match expr with + | Expr.Op (TOp.While (_, WhileLoopForCompiledForEachExprMarker), _, [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], m) -> Some(e1, e2, m) + | _ -> None + +let (|Let|_|) expr = + match expr with + | Expr.Let (TBind(v, e1, sp), e2, _, _) -> Some(v, e1, sp, e2) + | _ -> None + +let (|RangeInt32Step|_|) g expr = + match expr with + // detect 'n .. m' + | Expr.App (Expr.Val (vf, _, _), _, [tyarg], [startExpr;finishExpr], _) + when valRefEq g vf g.range_op_vref && typeEquiv g tyarg g.int_ty -> Some(startExpr, 1, finishExpr) + + // detect (RangeInt32 startExpr N finishExpr), the inlined/compiled form of 'n .. m' and 'n .. N .. m' + | Expr.App (Expr.Val (vf, _, _), _, [], [startExpr; Int32Expr n; finishExpr], _) + when valRefEq g vf g.range_int32_op_vref -> Some(startExpr, n, finishExpr) + + | _ -> None + +let (|GetEnumeratorCall|_|) expr = + match expr with + | Expr.Op (TOp.ILCall ( _, _, _, _, _, _, _, ilMethodRef, _, _, _), _, [Expr.Val (vref, _, _) | Expr.Op (_, _, [Expr.Val (vref, ValUseFlag.NormalValUse, _)], _) ], _) -> + if ilMethodRef.Name = "GetEnumerator" then Some vref + else None + | _ -> None + +let (|CompiledForEachExpr|_|) g expr = + match expr with + | Let (enumerableVar, enumerableExpr, _, + Let (enumeratorVar, GetEnumeratorCall enumerableVar2, enumeratorBind, + TryFinally (WhileLoopForCompiledForEachExpr (_, Let (elemVar, _, _, bodyExpr), _), _))) + // Apply correctness conditions to ensure this really is a compiled for-each expression. + when valRefEq g (mkLocalValRef enumerableVar) enumerableVar2 && + enumerableVar.IsCompilerGenerated && + enumeratorVar.IsCompilerGenerated && + (let fvs = (freeInExpr CollectLocals bodyExpr) + not (Zset.contains enumerableVar fvs.FreeLocals) && + not (Zset.contains enumeratorVar fvs.FreeLocals)) -> + + // Extract useful ranges + let mEnumExpr = enumerableExpr.Range + let mBody = bodyExpr.Range + let mWholeExpr = expr.Range + + let spForLoop, mForLoop = match enumeratorBind with DebugPointAtBinding.Yes spStart -> DebugPointAtFor.Yes spStart, spStart | _ -> DebugPointAtFor.No, mEnumExpr + let spWhileLoop = match enumeratorBind with DebugPointAtBinding.Yes spStart -> DebugPointAtWhile.Yes spStart| _ -> DebugPointAtWhile.No + let enumerableTy = tyOfExpr g enumerableExpr + + Some (enumerableTy, enumerableExpr, elemVar, bodyExpr, (mEnumExpr, mBody, spForLoop, mForLoop, spWhileLoop, mWholeExpr)) + | _ -> None + + +let (|CompiledInt32RangeForEachExpr|_|) g expr = + match expr with + | CompiledForEachExpr g (_, RangeInt32Step g (startExpr, step, finishExpr), elemVar, bodyExpr, ranges) -> + Some (startExpr, step, finishExpr, elemVar, bodyExpr, ranges) + | _ -> None + | _ -> None + + +type OptimizeForExpressionOptions = OptimizeIntRangesOnly | OptimizeAllForExpressions + +let DetectAndOptimizeForExpression g option expr = + match option, expr with + | _, CompiledInt32RangeForEachExpr g (startExpr, (1 | -1 as step), finishExpr, elemVar, bodyExpr, ranges) -> + + let _mEnumExpr, _mBody, spForLoop, _mForLoop, _spWhileLoop, mWholeExpr = ranges + mkFastForLoop g (spForLoop, mWholeExpr, elemVar, startExpr, (step = 1), finishExpr, bodyExpr) + + | OptimizeAllForExpressions, CompiledForEachExpr g (enumerableTy, enumerableExpr, elemVar, bodyExpr, ranges) -> + + let mEnumExpr, mBody, spForLoop, mForLoop, spWhileLoop, mWholeExpr = ranges + + if isStringTy g enumerableTy then + // type is string, optimize for expression as: + // let $str = enumerable + // for $idx in 0..(str.Length - 1) do + // let elem = str.[idx] + // body elem + + let strVar, strExpr = mkCompGenLocal mEnumExpr "str" enumerableTy + let idxVar, idxExpr = mkCompGenLocal elemVar.Range "idx" g.int32_ty + + let lengthExpr = mkGetStringLength g mForLoop strExpr + let charExpr = mkGetStringChar g mForLoop strExpr idxExpr + + let startExpr = mkZero g mForLoop + let finishExpr = mkDecr g mForLoop lengthExpr + // for compat reasons, loop item over string is sometimes object, not char + let loopItemExpr = mkCoerceIfNeeded g elemVar.Type g.char_ty charExpr + let bodyExpr = mkCompGenLet mForLoop elemVar loopItemExpr bodyExpr + let forExpr = mkFastForLoop g (spForLoop, mWholeExpr, idxVar, startExpr, true, finishExpr, bodyExpr) + let expr = mkCompGenLet mEnumExpr strVar enumerableExpr forExpr + + expr + + elif isListTy g enumerableTy then + // type is list, optimize for expression as: + // let mutable $currentVar = listExpr + // let mutable $nextVar = $tailOrNull + // while $guardExpr do + // let i = $headExpr + // bodyExpr () + // $current <- $next + // $next <- $tailOrNull + + let IndexHead = 0 + let IndexTail = 1 + + let currentVar, currentExpr = mkMutableCompGenLocal mEnumExpr "current" enumerableTy + let nextVar, nextExpr = mkMutableCompGenLocal mEnumExpr "next" enumerableTy + let elemTy = destListTy g enumerableTy + + let guardExpr = mkNonNullTest g mForLoop nextExpr + let headOrDefaultExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [elemTy], IndexHead, mForLoop) + let tailOrNullExpr = mkUnionCaseFieldGetUnprovenViaExprAddr (currentExpr, g.cons_ucref, [elemTy], IndexTail, mForLoop) + let bodyExpr = + mkCompGenLet mForLoop elemVar headOrDefaultExpr + (mkCompGenSequential mForLoop + bodyExpr + (mkCompGenSequential mForLoop + (mkValSet mForLoop (mkLocalValRef currentVar) nextExpr) + (mkValSet mForLoop (mkLocalValRef nextVar) tailOrNullExpr))) + + let expr = + // let mutable current = enumerableExpr + let spBind = (match spForLoop with DebugPointAtFor.Yes spStart -> DebugPointAtBinding.Yes spStart | DebugPointAtFor.No -> DebugPointAtBinding.NoneAtSticky) + mkLet spBind mEnumExpr currentVar enumerableExpr + // let mutable next = current.TailOrNull + (mkCompGenLet mForLoop nextVar tailOrNullExpr + // while nonNull next dp + (mkWhile g (spWhileLoop, WhileLoopForCompiledForEachExprMarker, guardExpr, bodyExpr, mBody))) + + expr + + else + expr + + | _ -> expr + +// Used to remove Expr.Link for inner expressions in pattern matches +let (|InnerExprPat|) expr = stripExpr expr + +/// One of the transformations performed by the compiler +/// is to eliminate variables of static type "unit". These is a +/// utility function related to this. + +let BindUnitVars g (mvs: Val list, paramInfos: ArgReprInfo list, body) = + match mvs, paramInfos with + | [v], [] -> + assert isUnitTy g v.Type + [], mkLet DebugPointAtBinding.NoneAtInvisible v.Range v (mkUnit g v.Range) body + | _ -> mvs, body + +let isThreadOrContextStatic g attrs = + HasFSharpAttributeOpt g g.attrib_ThreadStaticAttribute attrs || + HasFSharpAttributeOpt g g.attrib_ContextStaticAttribute attrs + +let mkUnitDelayLambda (g: TcGlobals) m e = + let uv, _ = mkCompGenLocal m "unitVar" g.unit_ty + mkLambda m uv (e, tyOfExpr g e) + + +let (|ValApp|_|) g vref expr = + match expr with + | Expr.App (Expr.Val (vref2, _, _), _f0ty, tyargs, args, m) when valRefEq g vref vref2 -> Some (tyargs, args, m) + | _ -> None + +let (|UseResumableStateMachinesExpr|_|) g expr = + match expr with + | ValApp g g.cgh__useResumableCode_vref (_, _, _m) -> Some () + | _ -> None + +/// Match +let (|IfThenElseExpr|_|) expr = + match expr with + | Expr.Match (_spBind, _exprm, TDSwitch(_spSwitch, cond, [ TCase( DecisionTreeTest.Const (Const.Bool true), TDSuccess ([], 0) )], Some (TDSuccess ([], 1)), _), + [| TTarget([], thenExpr, _, _); TTarget([], elseExpr, _, _) |], _m, _ty) -> + Some (cond, thenExpr, elseExpr) + | _ -> None + +/// if __useResumableCode then ... else ... +let (|IfUseResumableStateMachinesExpr|_|) g expr = + match expr with + | IfThenElseExpr(UseResumableStateMachinesExpr g (), thenExpr, elseExpr) -> Some (thenExpr, elseExpr) + | _ -> None + +/// Combine a list of ModuleOrNamespaceType's making up the description of a CCU. checking there are now +/// duplicate modules etc. +let CombineCcuContentFragments m l = + + /// Combine module types when multiple namespace fragments contribute to the + /// same namespace, making new module specs as we go. + let rec CombineModuleOrNamespaceTypes path m (mty1: ModuleOrNamespaceType) (mty2: ModuleOrNamespaceType) = + match mty1.ModuleOrNamespaceKind, mty2.ModuleOrNamespaceKind with + | Namespace, Namespace -> + let kind = mty1.ModuleOrNamespaceKind + let tab1 = mty1.AllEntitiesByLogicalMangledName + let tab2 = mty2.AllEntitiesByLogicalMangledName + let entities = + [ for e1 in mty1.AllEntities do + match tab2.TryGetValue e1.LogicalName with + | true, e2 -> yield CombineEntities path e1 e2 + | _ -> yield e1 + for e2 in mty2.AllEntities do + match tab1.TryGetValue e2.LogicalName with + | true, _ -> () + | _ -> yield e2 ] + + let vals = QueueList.append mty1.AllValsAndMembers mty2.AllValsAndMembers + + ModuleOrNamespaceType(kind, vals, QueueList.ofList entities) + + | Namespace, _ | _, Namespace -> + error(Error(FSComp.SR.tastNamespaceAndModuleWithSameNameInAssembly(textOfPath path), m)) + + | _-> + error(Error(FSComp.SR.tastTwoModulesWithSameNameInAssembly(textOfPath path), m)) + + and CombineEntities path (entity1: Entity) (entity2: Entity) = + + match entity1.IsModuleOrNamespace, entity2.IsModuleOrNamespace with + | true, true -> + entity1 |> Construct.NewModifiedTycon (fun data1 -> + let xml = XmlDoc.Merge entity1.XmlDoc entity2.XmlDoc + { data1 with + entity_attribs = entity1.Attribs @ entity2.Attribs + entity_modul_contents = MaybeLazy.Lazy (lazy (CombineModuleOrNamespaceTypes (path@[entity2.DemangledModuleOrNamespaceName]) entity2.Range entity1.ModuleOrNamespaceType entity2.ModuleOrNamespaceType)) + entity_opt_data = + match data1.entity_opt_data with + | Some optData -> Some { optData with entity_xmldoc = xml } + | _ -> Some { Entity.NewEmptyEntityOptData() with entity_xmldoc = xml } }) + | false, false -> + error(Error(FSComp.SR.tastDuplicateTypeDefinitionInAssembly(entity2.LogicalName, textOfPath path), entity2.Range)) + | _, _ -> + error(Error(FSComp.SR.tastConflictingModuleAndTypeDefinitionInAssembly(entity2.LogicalName, textOfPath path), entity2.Range)) + + and CombineModuleOrNamespaceTypeList path m l = + match l with + | h :: t -> List.fold (CombineModuleOrNamespaceTypes path m) h t + | _ -> failwith "CombineModuleOrNamespaceTypeList" + + CombineModuleOrNamespaceTypeList [] m l + +/// An immutable mappping from witnesses to some data. +/// +/// Note: this uses an immutable HashMap/Dictionary with an IEqualityComparer that captures TcGlobals, see EmptyTraitWitnessInfoHashMap +type TraitWitnessInfoHashMap<'T> = ImmutableDictionary + +/// Create an empty immutable mapping from witnesses to some data +let EmptyTraitWitnessInfoHashMap g : TraitWitnessInfoHashMap<'T> = + ImmutableDictionary.Create( + { new IEqualityComparer<_> with + member _.Equals(a, b) = traitKeysAEquiv g TypeEquivEnv.Empty a b + member _.GetHashCode(a) = hash a.MemberName + }) + +let (|WhileExpr|_|) expr = + match expr with + | Expr.Op (TOp.While (sp1, sp2), _, [Expr.Lambda (_, _, _, [_gv], guardExpr, _, _);Expr.Lambda (_, _, _, [_bv], bodyExpr, _, _)], m) -> + Some (sp1, sp2, guardExpr, bodyExpr, m) + | _ -> None + +let (|TryFinallyExpr|_|) expr = + match expr with + | Expr.Op (TOp.TryFinally (sp1, sp2), [ty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)], m) -> + Some (sp1, sp2, ty, e1, e2, m) + | _ -> None + +let (|ForLoopExpr|_|) expr = + match expr with + | Expr.Op (TOp.For (sp1, sp2), _, [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [v], e3, _, _)], m) -> + Some (sp1, sp2, e1, e2, v, e3, m) + | _ -> None + +let (|TryWithExpr|_|) expr = + match expr with + | Expr.Op (TOp.TryWith (spTry, spWith), [resTy], [Expr.Lambda (_, _, _, [_], bodyExpr, _, _); Expr.Lambda (_, _, _, [filterVar], filterExpr, _, _); Expr.Lambda (_, _, _, [handlerVar], handlerExpr, _, _)], m) -> + Some (spTry, spWith, resTy, bodyExpr, filterVar, filterExpr, handlerVar, handlerExpr, m) + | _ -> None + +let (|MatchTwoCasesExpr|_|) expr = + match expr with + | Expr.Match (spBind, exprm, TDSwitch(spSwitch, cond, [ TCase( DecisionTreeTest.UnionCase (ucref, a), TDSuccess ([], tg1) )], Some (TDSuccess ([], tg2)), b), tgs, m, ty) -> + + // How to rebuild this construct + let rebuild (cond, ucref, tg1, tg2, tgs) = + Expr.Match (spBind, exprm, TDSwitch(spSwitch, cond, [ TCase( DecisionTreeTest.UnionCase (ucref, a), TDSuccess ([], tg1) )], Some (TDSuccess ([], tg2)), b), tgs, m, ty) + + Some (cond, ucref, tg1, tg2, tgs, rebuild) + + | _ -> None + +/// match e with None -> ... | Some v -> ... or other variations of the same +let (|MatchOptionExpr|_|) expr = + match expr with + | MatchTwoCasesExpr(cond, ucref, tg1, tg2, tgs, rebuildTwoCases) -> + let tgNone, tgSome = if ucref.CaseName = "None" then tg1, tg2 else tg2, tg1 + match tgs.[tgNone], tgs.[tgSome] with + | TTarget([], noneBranchExpr, b1, b2), + TTarget([], Expr.Let(TBind(unionCaseVar, Expr.Op(TOp.UnionCaseProof a1, a2, a3, a4), a5), + Expr.Let(TBind(someVar, Expr.Op(TOp.UnionCaseFieldGet (a6a, a6b), a7, a8, a9), a10), someBranchExpr, a11, a12), a13, a14), a15, a16) + when unionCaseVar.LogicalName = "unionCase" -> + + // How to rebuild this construct + let rebuild (cond, noneBranchExpr, someVar, someBranchExpr) = + let tgs = Array.zeroCreate 2 + tgs.[tgNone] <- TTarget([], noneBranchExpr, b1, b2) + tgs.[tgSome] <- TTarget([], Expr.Let(TBind(unionCaseVar, Expr.Op(TOp.UnionCaseProof a1, a2, a3, a4), a5), + Expr.Let(TBind(someVar, Expr.Op(TOp.UnionCaseFieldGet (a6a, a6b), a7, a8, a9), a10), someBranchExpr, a11, a12), a13, a14), a15, a16) + rebuildTwoCases (cond, ucref, tg1, tg2, tgs) + + Some (cond, noneBranchExpr, someVar, someBranchExpr, rebuild) + | _ -> None + | _ -> None + +let (|ResumableEntryAppExpr|_|) g expr = + match expr with + | ValApp g g.cgh__resumableEntry_vref (_, _, _m) -> Some () + | _ -> None + +/// Match an (unoptimized) __resumableEntry expression +let (|ResumableEntryMatchExpr|_|) g expr = + match expr with + | Expr.Let(TBind(matchVar, matchExpr, sp1), MatchOptionExpr (Expr.Val(matchVar2, b, c), noneBranchExpr, someVar, someBranchExpr, rebuildMatch), d, e) -> + match matchExpr with + | ResumableEntryAppExpr g () -> + if valRefEq g (mkLocalValRef matchVar) matchVar2 then + + // How to rebuild this construct + let rebuild (noneBranchExpr, someBranchExpr) = + Expr.Let(TBind(matchVar, matchExpr, sp1), rebuildMatch (Expr.Val(matchVar2, b, c), noneBranchExpr, someVar, someBranchExpr), d, e) + + Some (noneBranchExpr, someVar, someBranchExpr, rebuild) + + else None + + | _ -> None + | _ -> None + +let (|PossiblyCompiledTypeOfExpr|_|) g expr = + match expr with + | TypeOfExpr g ty -> Some ty + | Expr.Op(TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, _, _, _), [],[Expr.Op (TOp.ILAsm ([ I_ldtoken (ILToken.ILType _) ], _), [ty], _, _)], _) + when ilMethRef.DeclaringTypeRef.Name = "System.Type" && ilMethRef.Name = "GetTypeFromHandle" -> + Some ty + | _ -> None + +let (|StructStateMachineExpr|_|) g expr = + match expr with + | ValApp g g.cgh__stateMachine_vref ([dataTy; _resultTy], [moveNext; setStateMachine; afterCode], _m) -> + match moveNext, setStateMachine, afterCode with + | NewDelegateExpr g (_, [[moveNextThisVar]], moveNextBody, _, _), + NewDelegateExpr g (_, [[setStateMachineThisVar;setStateMachineStateVar]], setStateMachineBody, _, _), + NewDelegateExpr g (_, [[afterCodeThisVar]], afterCodeBody, _, _) -> + Some (dataTy, + (moveNextThisVar, moveNextBody), + (setStateMachineThisVar, setStateMachineStateVar, setStateMachineBody), + (afterCodeThisVar, afterCodeBody)) + | _ -> None + | _ -> None + +let (|ResumeAtExpr|_|) g expr = + match expr with + | ValApp g g.cgh__resumeAt_vref (_, [pcExpr], _m) -> Some pcExpr + | _ -> None + +// Detect sequencing constructs in state machine code +let (|SequentialResumableCode|_|) (g: TcGlobals) expr = + match expr with + + // e1; e2 + | Expr.Sequential(e1, e2, NormalSeq, sp, m) -> + Some (e1, e2, m, (fun e1 e2 -> Expr.Sequential(e1, e2, NormalSeq, sp, m))) + + // let __stack_step = e1 in e2 + | Expr.Let(bind, e2, m, _) when bind.Var.CompiledName(g.CompilerGlobalState).StartsWith(stackVarPrefix) -> + Some (bind.Expr, e2, m, (fun e1 e2 -> mkLet bind.DebugPoint m bind.Var e1 e2)) + + | _ -> None + +let mkLabelled m l e = mkCompGenSequential m (Expr.Op (TOp.Label l, [], [], m)) e + +let isResumableCodeTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.ResumableCode_tcr | _ -> false) + +let rec isReturnsResumableCodeTy g ty = + if isFunTy g ty then isReturnsResumableCodeTy g (rangeOfFunTy g ty) + else isResumableCodeTy g ty + +let (|ResumableCodeInvoke|_|) g expr = + match expr with + // defn.Invoke x --> let arg = x in [defn][arg/x] + | Expr.App ((Expr.Val (invokeRef, _, _) as iref), a, b, (f :: args), m) + when invokeRef.LogicalName = "Invoke" && isReturnsResumableCodeTy g (tyOfExpr g f) -> + Some (iref, f, args, m, (fun (f2, args2) -> Expr.App ((iref, a, b, (f2 :: args2), m)))) + | _ -> None + +let mkDebugPoint g m expr = + mkThenDoSequential DebugPointAtSequential.SuppressStmt m expr (mkUnit g m) + diff --git a/src/fsharp/TypedTreeOps.fsi b/src/fsharp/TypedTreeOps.fsi new file mode 100755 index 00000000000..8963d7d9222 --- /dev/null +++ b/src/fsharp/TypedTreeOps.fsi @@ -0,0 +1,2528 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines derived expression manipulation and construction functions. +module internal FSharp.Compiler.TypedTreeOps + +open System.Collections.Generic +open System.Collections.Immutable +open Internal.Utilities.Collections +open Internal.Utilities.Rational +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TcGlobals + +type Erasure = EraseAll | EraseMeasures | EraseNone + +/// Check the equivalence of two types up to an erasure flag +val typeEquivAux: Erasure -> TcGlobals -> TType -> TType -> bool + +/// Check the equivalence of two types +val typeEquiv: TcGlobals -> TType -> TType -> bool + +/// Check the equivalence of two units-of-measure +val measureEquiv: TcGlobals -> Measure -> Measure -> bool + +/// Get the unit of measure for an annotated type +val getMeasureOfType: TcGlobals -> TType -> (TyconRef * Measure) option + +/// Reduce a type to its more canonical form subject to an erasure flag, inference equations and abbreviations +val stripTyEqnsWrtErasure: Erasure -> TcGlobals -> TType -> TType + +/// Build a function type +val mkFunTy: TType -> TType -> TType + +/// Build a function type +val ( --> ): TType -> TType -> TType + +/// Build a type-forall anonymous generic type if necessary +val mkForallTyIfNeeded: Typars -> TType -> TType + +val ( +-> ): Typars -> TType -> TType + +/// Build a curried function type +val mkIteratedFunTy: TTypes -> TType -> TType + +/// Get the natural type of a single argument amongst a set of curried arguments +val typeOfLambdaArg: range -> Val list -> TType + +/// Get the curried type corresponding to a lambda +val mkMultiLambdaTy: range -> Val list -> TType -> TType + +/// Get the curried type corresponding to a lambda +val mkLambdaTy: Typars -> TTypes -> TType -> TType + +/// Module publication, used while compiling fslib. +val ensureCcuHasModuleOrNamespaceAtPath: CcuThunk -> Ident list -> CompilationPath -> XmlDoc -> unit + +/// Ignore 'Expr.Link' in an expression +val stripExpr: Expr -> Expr + +/// Get the values for a set of bindings +val valsOfBinds: Bindings -> Vals + +/// Look for a use of an F# value, possibly including application of a generic thing to a set of type arguments +val (|ExprValWithPossibleTypeInst|_|): Expr -> (ValRef * ValUseFlag * TType list * range) option + +/// Build decision trees imperatively +type MatchBuilder = + + /// Create a new builder + new: DebugPointAtBinding * range -> MatchBuilder + + /// Add a new destination target + member AddTarget: DecisionTreeTarget -> int + + /// Add a new destination target that is an expression result + member AddResultTarget: Expr * DebugPointAtTarget -> DecisionTree + + /// Finish the targets + member CloseTargets: unit -> DecisionTreeTarget list + + /// Build the overall expression + member Close: DecisionTree * range * TType -> Expr + +/// Add an if-then-else boolean conditional node into a decision tree +val mkBoolSwitch: DebugPointAtSwitch -> range -> Expr -> DecisionTree -> DecisionTree -> DecisionTree + +/// Build a conditional expression +val primMkCond: DebugPointAtBinding -> DebugPointAtTarget -> DebugPointAtTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr + +/// Build a conditional expression +val mkCond: DebugPointAtBinding -> DebugPointAtTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr + +/// Build a conditional expression that checks for non-nullness +val mkNonNullCond: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + +/// Build an if-then statement +val mkIfThen: TcGlobals -> range -> Expr -> Expr -> Expr + +/// Build an expression corresponding to the use of a value +/// Note: try to use exprForValRef or the expression returned from mkLocal instead of this. +val exprForVal: range -> Val -> Expr + +/// Build an expression corresponding to the use of a reference to a value +val exprForValRef: range -> ValRef -> Expr + +/// Make a new local value and build an expression to reference it +val mkLocal: range -> string -> TType -> Val * Expr + +/// Make a new compiler-generated local value and build an expression to reference it +val mkCompGenLocal: range -> string -> TType -> Val * Expr + +/// Make a new mutable compiler-generated local value and build an expression to reference it +val mkMutableCompGenLocal: range -> string -> TType -> Val * Expr + +/// Make a new mutable compiler-generated local value, 'let' bind it to an expression +/// 'invisibly' (no sequence point etc.), and build an expression to reference it +val mkCompGenLocalAndInvisibleBind: TcGlobals -> string -> range -> Expr -> Val * Expr * Binding + +/// Build a lambda expression taking multiple values +val mkMultiLambda: range -> Val list -> Expr * TType -> Expr + +/// Rebuild a lambda during an expression tree traversal +val rebuildLambda: range -> Val option -> Val option -> Val list -> Expr * TType -> Expr + +/// Build a lambda expression taking a single value +val mkLambda: range -> Val -> Expr * TType -> Expr + +/// Build a generic lambda expression (type abstraction) +val mkTypeLambda: range -> Typars -> Expr * TType -> Expr + +/// Build an object expression +val mkObjExpr: TType * Val option * Expr * ObjExprMethod list * (TType * ObjExprMethod list) list * range -> Expr + +/// Build an type-chose expression, indicating that a local free choice of a type variable +val mkTypeChoose: range -> Typars -> Expr -> Expr + +/// Build an iterated (curried) lambda expression +val mkLambdas: range -> Typars -> Val list -> Expr * TType -> Expr + +/// Build an iterated (tupled+curried) lambda expression +val mkMultiLambdasCore: range -> Val list list -> Expr * TType -> Expr * TType + +/// Build an iterated generic (type abstraction + tupled+curried) lambda expression +val mkMultiLambdas: range -> Typars -> Val list list -> Expr * TType -> Expr + +/// Build a lambda expression that corresponds to the implementation of a member +val mkMemberLambdas: range -> Typars -> Val option -> Val option -> Val list list -> Expr * TType -> Expr + +/// Build a 'while' loop expression +val mkWhile: TcGlobals -> DebugPointAtWhile * SpecialWhileLoopMarker * Expr * Expr * range -> Expr + +/// Build a 'for' loop expression +val mkFor: TcGlobals -> DebugPointAtFor * Val * Expr * ForLoopStyle * Expr * Expr * range -> Expr + +/// Build a 'try/with' expression +val mkTryWith: TcGlobals -> Expr * (* filter val *) Val * (* filter expr *) Expr * (* handler val *) Val * (* handler expr *) Expr * range * TType * DebugPointAtTry * DebugPointAtWith -> Expr + +/// Build a 'try/finally' expression +val mkTryFinally: TcGlobals -> Expr * Expr * range * TType * DebugPointAtTry * DebugPointAtFinally -> Expr + +/// Build a user-level value binding +val mkBind: DebugPointAtBinding -> Val -> Expr -> Binding + +/// Build a user-level let-binding +val mkLetBind: range -> Binding -> Expr -> Expr + +/// Build a user-level value sequence of let bindings +val mkLetsBind: range -> Binding list -> Expr -> Expr + +/// Build a user-level value sequence of let bindings +val mkLetsFromBindings: range -> Bindings -> Expr -> Expr + +/// Build a user-level let expression +val mkLet: DebugPointAtBinding -> range -> Val -> Expr -> Expr -> Expr + +/// Make a binding that binds a function value to a lambda taking multiple arguments +val mkMultiLambdaBind: Val -> DebugPointAtBinding -> range -> Typars -> Val list list -> Expr * TType -> Binding + +// Compiler generated bindings may involve a user variable. +// Compiler generated bindings may give rise to a sequence point if they are part of +// an SPAlways expression. Compiler generated bindings can arise from for example, inlining. +val mkCompGenBind: Val -> Expr -> Binding + +/// Make a set of bindings that bind compiler generated values to corresponding expressions. +/// Compiler-generated bindings do not give rise to a sequence point in debugging. +val mkCompGenBinds: Val list -> Exprs -> Bindings + +/// Make a let-expression that locally binds a compiler-generated value to an expression. +/// Compiler-generated bindings do not give rise to a sequence point in debugging. +val mkCompGenLet: range -> Val -> Expr -> Expr -> Expr + +/// Make a let-expression that locally binds a compiler-generated value to an expression, where the expression +/// is returned by the given continuation. Compiler-generated bindings do not give rise to a sequence point in debugging. +val mkCompGenLetIn: range -> string -> TType -> Expr -> (Val * Expr -> Expr) -> Expr + +/// Make a let-expression that locally binds a value to an expression in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. +val mkInvisibleLet: range -> Val -> Expr -> Expr -> Expr + +/// Make a binding that binds a value to an expression in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. +val mkInvisibleBind: Val -> Expr -> Binding + +/// Make a set of bindings that bind values to expressions in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. +val mkInvisibleBinds: Vals -> Exprs -> Bindings + +/// Make a let-rec expression that locally binds values to expressions where self-reference back to the values is possible. +val mkLetRecBinds: range -> Bindings -> Expr -> Expr + +/// TypeScheme (generalizedTypars, tauTy) +/// +/// generalizedTypars -- the truly generalized type parameters +/// tauTy -- the body of the generalized type. A 'tau' type is one with its type parameters stripped off. +type TypeScheme = TypeScheme of Typars * TType + +/// Make the right-hand side of a generalized binding, incorporating the generalized generic parameters from the type +/// scheme into the right-hand side as type generalizations. +val mkGenericBindRhs: TcGlobals -> range -> Typars -> TypeScheme -> Expr -> Expr + +/// Test if the type parameter is one of those being generalized by a type scheme. +val isBeingGeneralized: Typar -> TypeScheme -> bool + +/// Make the expression corresponding to 'expr1 && expr2' +val mkLazyAnd: TcGlobals -> range -> Expr -> Expr -> Expr + +/// Make the expression corresponding to 'expr1 || expr2' +val mkLazyOr: TcGlobals -> range -> Expr -> Expr -> Expr + +/// Make a byref type +val mkByrefTy: TcGlobals -> TType -> TType + +/// Make a byref type with a in/out kind inference parameter +val mkByrefTyWithInference: TcGlobals -> TType -> TType -> TType + +/// Make a in-byref type with a in kind parameter +val mkInByrefTy: TcGlobals -> TType -> TType + +/// Make an out-byref type with an out kind parameter +val mkOutByrefTy: TcGlobals -> TType -> TType + +/// Make an expression that constructs a union case, e.g. 'Some(expr)' +val mkUnionCaseExpr: UnionCaseRef * TypeInst * Exprs * range -> Expr + +/// Make an expression that constructs an exception value +val mkExnExpr: TyconRef * Exprs * range -> Expr + +/// Make an expression that is IL assembly code +val mkAsmExpr: ILInstr list * TypeInst * Exprs * TTypes * range -> Expr + +/// Make an expression that coerces one expression to another type +val mkCoerceExpr: Expr * TType * range * TType -> Expr + +/// Make an expression that re-raises an exception +val mkReraise: range -> TType -> Expr + +/// Make an expression that re-raises an exception via a library call +val mkReraiseLibCall: TcGlobals -> TType -> range -> Expr + +/// Make an expression that gets an item from a tuple +val mkTupleFieldGet: TcGlobals -> TupInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an item from an anonymous record +val mkAnonRecdFieldGet: TcGlobals -> AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an item from an anonymous record (via the address of the value if it is a struct) +val mkAnonRecdFieldGetViaExprAddr: AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an instance field from a record or class (via the address of the value if it is a struct) +val mkRecdFieldGetViaExprAddr: Expr * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that gets the address of an instance field from a record or class (via the address of the value if it is a struct) +val mkRecdFieldGetAddrViaExprAddr: readonly: bool * Expr * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that gets a static field from a record or class +val mkStaticRecdFieldGet: RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that sets a static field in a record or class +val mkStaticRecdFieldSet: RecdFieldRef * TypeInst * Expr * range -> Expr + +/// Make an expression that gets the address of a static field in a record or class +val mkStaticRecdFieldGetAddr: readonly: bool * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that sets an instance the field of a record or class (via the address of the value if it is a struct) +val mkRecdFieldSetViaExprAddr: Expr * RecdFieldRef * TypeInst * Expr * range -> Expr + +/// Make an expression that gets the tag of a union value (via the address of the value if it is a struct) +val mkUnionCaseTagGetViaExprAddr: Expr * TyconRef * TypeInst * range -> Expr + +/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) +val mkUnionCaseProof: Expr * UnionCaseRef * TypeInst * range -> Expr + +/// Build a 'TOp.UnionCaseFieldGet' expression for something we've already determined to be a particular union case. For ref-unions, +/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +val mkUnionCaseFieldGetProvenViaExprAddr: Expr * UnionCaseRef * TypeInst * int * range -> Expr + +/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, +/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +val mkUnionCaseFieldGetAddrProvenViaExprAddr: readonly: bool * Expr * UnionCaseRef * TypeInst * int * range -> Expr + +/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, +/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +val mkUnionCaseFieldGetUnprovenViaExprAddr: Expr * UnionCaseRef * TypeInst * int * range -> Expr + +/// Build a 'TOp.UnionCaseFieldSet' expression. For ref-unions, the input expression has 'TType_ucase', which is +/// an F# compiler internal "type" corresponding to the union case. For struct-unions, +/// the input should be the address of the expression. +val mkUnionCaseFieldSet: Expr * UnionCaseRef * TypeInst * int * Expr * range -> Expr + +/// Like mkUnionCaseFieldGetUnprovenViaExprAddr, but for struct-unions, the input should be a copy of the expression. +val mkUnionCaseFieldGetUnproven: TcGlobals -> Expr * UnionCaseRef * TypeInst * int * range -> Expr + +/// Make an expression that gets an instance field from an F# exception value +val mkExnCaseFieldGet: Expr * TyconRef * int * range -> Expr + +/// Make an expression that sets an instance field in an F# exception value +val mkExnCaseFieldSet: Expr * TyconRef * int * Expr * range -> Expr + +/// Make an expression that gets the address of an element in an array +val mkArrayElemAddress: TcGlobals -> readonly: bool * ILReadonly * bool * ILArrayShape * TType * Expr list * range -> Expr + +/// The largest tuple before we start encoding, i.e. 7 +val maxTuple: int + +/// The number of fields in the largest tuple before we start encoding, i.e. 7 +val goodTupleFields: int + +/// Check if a TyconRef is for a .NET tuple type. Currently this includes Tuple`1 even though +/// that' not really part of the target set of TyconRef used to represent F# tuples. +val isCompiledTupleTyconRef: TcGlobals -> TyconRef -> bool + +/// Get a TyconRef for a .NET tuple type +val mkCompiledTupleTyconRef: TcGlobals -> bool -> int -> TyconRef + +/// Convert from F# tuple types to .NET tuple types. +val mkCompiledTupleTy: TcGlobals -> bool -> TTypes -> TType + +/// Convert from F# tuple creation expression to .NET tuple creation expressions +val mkCompiledTuple: TcGlobals -> bool -> TTypes * Exprs * range -> TyconRef * TTypes * Exprs * range + +/// Make a TAST expression representing getting an item fromm a tuple +val mkGetTupleItemN: TcGlobals -> range -> int -> ILType -> bool -> Expr -> TType -> Expr + +/// Evaluate the TupInfo to work out if it is a struct or a ref. Currently this is very simple +/// but TupInfo may later be used carry variables that infer structness. +val evalTupInfoIsStruct: TupInfo -> bool + +/// Evaluate the AnonRecdTypeInfo to work out if it is a struct or a ref. +val evalAnonInfoIsStruct: AnonRecdTypeInfo -> bool + +/// If it is a tuple type, ensure it's outermost type is a .NET tuple type, otherwise leave unchanged +val convertToTypeWithMetadataIfPossible: TcGlobals -> TType -> TType + +/// An exception representing a warning for a defensive copy of an immutable struct +exception DefensiveCopyWarning of string * range + +type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates + +/// Helper to create an expression that dereferences an address. +val mkDerefAddrExpr: mAddrGet: range -> expr: Expr -> mExpr: range -> exprTy: TType -> Expr + +/// Helper to take the address of an expression +val mkExprAddrOfExprAux: TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr * bool * bool + +/// Take the address of an expression, or force it into a mutable local. Any allocated +/// mutable local may need to be kept alive over a larger expression, hence we return +/// a wrapping function that wraps "let mutable loc = Expr in ..." around a larger +/// expression. +val mkExprAddrOfExpr: TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr * bool * bool + +/// Maps Val to T, based on stamps +[] +type ValMap<'T> = + + member Contents: StampMap<'T> + + member Item: Val -> 'T with get + + member TryFind: Val -> 'T option + + member ContainsVal: Val -> bool + + member Add: Val -> 'T -> ValMap<'T> + + member Remove: Val -> ValMap<'T> + + member IsEmpty: bool + + static member Empty: ValMap<'T> + + static member OfList: (Val * 'T) list -> ValMap<'T> + +/// Mutable data structure mapping Val's to T based on stamp keys +[] +type ValHash<'T> = + + member Values: seq<'T> + + member TryFind: Val -> 'T option + + member Add: Val * 'T -> unit + + static member Create: unit -> ValHash<'T> + +/// Maps Val's to list of T based on stamp keys +[] +type ValMultiMap<'T> = + + member ContainsKey: Val -> bool + + member Find: Val -> 'T list + + member Add: Val * 'T -> ValMultiMap<'T> + + member Remove: Val -> ValMultiMap<'T> + + member Contents: StampMap<'T list> + + static member Empty: ValMultiMap<'T> + +/// Maps type parameters to entries based on stamp keys +[] +type TyparMap<'T> = + + /// Get the entry for the given type parameter + member Item: Typar -> 'T with get + + /// Determine is the map contains an entry for the given type parameter + member ContainsKey: Typar -> bool + + /// Try to find the entry for the given type parameter + member TryFind: Typar -> 'T option + + /// Make a new map, containing a new entry for the given type parameter + member Add: Typar * 'T -> TyparMap<'T> + + /// The empty map + static member Empty: TyparMap<'T> + +/// Maps TyconRef to T based on stamp keys +[] +type TyconRefMap<'T> = + + /// Get the entry for the given type definition + member Item: TyconRef -> 'T with get + + /// Try to find the entry for the given type definition + member TryFind: TyconRef -> 'T option + + /// Determine is the map contains an entry for the given type definition + member ContainsKey: TyconRef -> bool + + /// Make a new map, containing a new entry for the given type definition + member Add: TyconRef -> 'T -> TyconRefMap<'T> + + /// Remove the entry for the given type definition, if any + member Remove: TyconRef -> TyconRefMap<'T> + + /// Determine if the map is empty + member IsEmpty: bool + + /// The empty map + static member Empty: TyconRefMap<'T> + + /// Make a new map, containing entries for the given type definitions + static member OfList: (TyconRef * 'T) list -> TyconRefMap<'T> + +/// Maps TyconRef to list of T based on stamp keys +[] +type TyconRefMultiMap<'T> = + + /// Fetch the entries for the given type definition + member Find: TyconRef -> 'T list + + /// Make a new map, containing a new entry for the given type definition + member Add: TyconRef * 'T -> TyconRefMultiMap<'T> + + /// The empty map + static member Empty: TyconRefMultiMap<'T> + + /// Make a new map, containing a entries for the given type definitions + static member OfList: (TyconRef * 'T) list -> TyconRefMultiMap<'T> + +/// An ordering for value definitions, based on stamp +val valOrder: IComparer + +/// An ordering for type definitions, based on stamp +val tyconOrder: IComparer + +/// An ordering for record fields, based on stamp +val recdFieldRefOrder: IComparer + +/// An ordering for type parameters, based on stamp +val typarOrder: IComparer + +/// Equality for type definition references +val tyconRefEq: TcGlobals -> TyconRef -> TyconRef -> bool + +/// Equality for value references +val valRefEq: TcGlobals -> ValRef -> ValRef -> bool + +//------------------------------------------------------------------------- +// Operations on types: substitution +//------------------------------------------------------------------------- + +/// Represents an instantiation where types replace type parameters +type TyparInst = (Typar * TType) list + +/// Represents an instantiation where type definition references replace other type definition references +type TyconRefRemap = TyconRefMap + +/// Represents an instantiation where value references replace other value references +type ValRemap = ValMap + +/// Represents a combination of substitutions/instantiations where things replace other things during remapping +[] +type Remap = + { tpinst: TyparInst + valRemap: ValRemap + tyconRefRemap: TyconRefRemap + removeTraitSolutions: bool } + + static member Empty: Remap + +val addTyconRefRemap: TyconRef -> TyconRef -> Remap -> Remap + +val addValRemap: Val -> Val -> Remap -> Remap + +val mkTyparInst: Typars -> TTypes -> TyparInst + +val mkTyconRefInst: TyconRef -> TypeInst -> TyparInst + +val emptyTyparInst: TyparInst + +val instType: TyparInst -> TType -> TType + +val instTypes: TyparInst -> TypeInst -> TypeInst + +val instTyparConstraints: TyparInst -> TyparConstraint list -> TyparConstraint list + +val instTrait: TyparInst -> TraitConstraintInfo -> TraitConstraintInfo + +/// From typars to types +val generalizeTypars: Typars -> TypeInst + +val generalizeTyconRef: TyconRef -> TTypes * TType + +val generalizedTyconRef: TyconRef -> TType + +val mkTyparToTyparRenaming: Typars -> Typars -> TyparInst * TTypes + +//------------------------------------------------------------------------- +// See through typar equations from inference and/or type abbreviation equations. +//------------------------------------------------------------------------- + +val reduceTyconRefAbbrev: TyconRef -> TypeInst -> TType + +val reduceTyconRefMeasureableOrProvided: TcGlobals -> TyconRef -> TypeInst -> TType + +val reduceTyconRefAbbrevMeasureable: TyconRef -> Measure + +/// set bool to 'true' to allow shortcutting of type parameter equation chains during stripping +val stripTyEqnsA: TcGlobals -> bool -> TType -> TType + +val stripTyEqns: TcGlobals -> TType -> TType + +val stripTyEqnsAndMeasureEqns: TcGlobals -> TType -> TType + +val tryNormalizeMeasureInType: TcGlobals -> TType -> TType + +/// See through F# exception abbreviations +val stripExnEqns: TyconRef -> Tycon + +val recdFieldsOfExnDefRef: TyconRef -> RecdField list + +val recdFieldTysOfExnDefRef: TyconRef -> TType list + +//------------------------------------------------------------------------- +// Analyze types. These all look through type abbreviations and +// inference equations, i.e. are "stripped" +//------------------------------------------------------------------------- + +val destForallTy: TcGlobals -> TType -> Typars * TType + +val destFunTy: TcGlobals -> TType -> TType * TType + +val destAnyTupleTy: TcGlobals -> TType -> TupInfo * TTypes + +val destRefTupleTy: TcGlobals -> TType -> TTypes + +val destStructTupleTy: TcGlobals -> TType -> TTypes + +val destTyparTy: TcGlobals -> TType -> Typar + +val destAnyParTy: TcGlobals -> TType -> Typar + +val destMeasureTy: TcGlobals -> TType -> Measure + +val tryDestForallTy: TcGlobals -> TType -> Typars * TType + +val isFunTy: TcGlobals -> TType -> bool + +val isForallTy: TcGlobals -> TType -> bool + +val isAnyTupleTy: TcGlobals -> TType -> bool + +val isRefTupleTy: TcGlobals -> TType -> bool + +val isStructTupleTy: TcGlobals -> TType -> bool + +val isStructAnonRecdTy: TcGlobals -> TType -> bool + +val isAnonRecdTy: TcGlobals -> TType -> bool + +val isUnionTy: TcGlobals -> TType -> bool + +val isReprHiddenTy: TcGlobals -> TType -> bool + +val isFSharpObjModelTy: TcGlobals -> TType -> bool + +val isRecdTy: TcGlobals -> TType -> bool + +val isFSharpStructOrEnumTy: TcGlobals -> TType -> bool + +val isFSharpEnumTy: TcGlobals -> TType -> bool + +val isTyparTy: TcGlobals -> TType -> bool + +val isAnyParTy: TcGlobals -> TType -> bool + +val tryAnyParTy: TcGlobals -> TType -> ValueOption + +val tryAnyParTyOption: TcGlobals -> TType -> Typar option + +val isMeasureTy: TcGlobals -> TType -> bool + +val mkAppTy: TyconRef -> TypeInst -> TType + +val mkProvenUnionCaseTy: UnionCaseRef -> TypeInst -> TType + +val isProvenUnionCaseTy: TType -> bool + +val isAppTy: TcGlobals -> TType -> bool + +val tryAppTy: TcGlobals -> TType -> ValueOption + +val destAppTy: TcGlobals -> TType -> TyconRef * TypeInst + +val tcrefOfAppTy: TcGlobals -> TType -> TyconRef + +val tryTcrefOfAppTy: TcGlobals -> TType -> ValueOption + +val tryDestTyparTy: TcGlobals -> TType -> ValueOption + +val tryDestFunTy: TcGlobals -> TType -> ValueOption + +val tryDestAnonRecdTy: TcGlobals -> TType -> ValueOption + +val argsOfAppTy: TcGlobals -> TType -> TypeInst + +val mkInstForAppTy: TcGlobals -> TType -> TyparInst + +/// Try to get a TyconRef for a type without erasing type abbreviations +val tryNiceEntityRefOfTy: TType -> ValueOption + +val tryNiceEntityRefOfTyOption: TType -> TyconRef option + +val domainOfFunTy: TcGlobals -> TType -> TType + +val rangeOfFunTy: TcGlobals -> TType -> TType + +val stripFunTy: TcGlobals -> TType -> TType list * TType + +val stripFunTyN: TcGlobals -> int -> TType -> TType list * TType + +val applyForallTy: TcGlobals -> TType -> TypeInst -> TType + +val tryDestAnyTupleTy: TcGlobals -> TType -> TupInfo * TType list + +val tryDestRefTupleTy: TcGlobals -> TType -> TType list + +//------------------------------------------------------------------------- +// Compute actual types of union cases and fields given an instantiation +// of the generic type parameters of the enclosing type. +//------------------------------------------------------------------------- + +val actualResultTyOfUnionCase: TypeInst -> UnionCaseRef -> TType + +val actualTysOfUnionCaseFields: TyparInst -> UnionCaseRef -> TType list + +val actualTysOfInstanceRecdFields: TyparInst -> TyconRef -> TType list + +val actualTyOfRecdField: TyparInst -> RecdField -> TType + +val actualTyOfRecdFieldRef: RecdFieldRef -> TypeInst -> TType + +val actualTyOfRecdFieldForTycon: Tycon -> TypeInst -> RecdField -> TType + +//------------------------------------------------------------------------- +// Top types: guaranteed to be compiled to .NET methods, and must be able to +// have user-specified argument names (for stability w.r.t. reflection) +// and user-specified argument and return attributes. +//------------------------------------------------------------------------- + +type UncurriedArgInfos = (TType * ArgReprInfo) list + +type CurriedArgInfos = UncurriedArgInfos list + +type TraitWitnessInfos = TraitWitnessInfo list + +val destTopForallTy: TcGlobals -> ValReprInfo -> TType -> Typars * TType + +val GetTopTauTypeInFSharpForm: TcGlobals -> ArgReprInfo list list -> TType -> range -> CurriedArgInfos * TType + +val GetTopValTypeInFSharpForm: TcGlobals -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType * ArgReprInfo + +val IsCompiledAsStaticProperty: TcGlobals -> Val -> bool + +val IsCompiledAsStaticPropertyWithField: TcGlobals -> Val -> bool + +val GetTopValTypeInCompiledForm: TcGlobals -> ValReprInfo -> int -> TType -> range -> Typars * TraitWitnessInfos * CurriedArgInfos * TType option * ArgReprInfo + +val GetFSharpViewOfReturnType: TcGlobals -> TType option -> TType + +val NormalizeDeclaredTyparsForEquiRecursiveInference: TcGlobals -> Typars -> Typars + +//------------------------------------------------------------------------- +// Compute the return type after an application +//------------------------------------------------------------------------- + +val applyTys: TcGlobals -> TType -> TType list * 'T list -> TType + +//------------------------------------------------------------------------- +// Compute free variables in types +//------------------------------------------------------------------------- + +val emptyFreeTypars: FreeTypars + +val unionFreeTypars: FreeTypars -> FreeTypars -> FreeTypars + +val emptyFreeTycons: FreeTycons + +val unionFreeTycons: FreeTycons -> FreeTycons -> FreeTycons + +val emptyFreeTyvars: FreeTyvars + +val isEmptyFreeTyvars: FreeTyvars -> bool + +val unionFreeTyvars: FreeTyvars -> FreeTyvars -> FreeTyvars + +val emptyFreeLocals: FreeLocals + +val unionFreeLocals: FreeLocals -> FreeLocals -> FreeLocals + +type FreeVarOptions + +val CollectLocalsNoCaching: FreeVarOptions + +val CollectTyparsNoCaching: FreeVarOptions + +val CollectTyparsAndLocalsNoCaching: FreeVarOptions + +val CollectTyparsAndLocals: FreeVarOptions + +val CollectLocals: FreeVarOptions + +val CollectTypars: FreeVarOptions + +val CollectAllNoCaching: FreeVarOptions + +val CollectAll: FreeVarOptions + +val accFreeInTypes: FreeVarOptions -> TType list -> FreeTyvars -> FreeTyvars + +val accFreeInType: FreeVarOptions -> TType -> FreeTyvars -> FreeTyvars + +val accFreeInTypars: FreeVarOptions -> Typars -> FreeTyvars -> FreeTyvars + +val freeInType: FreeVarOptions -> TType -> FreeTyvars + +val freeInTypes: FreeVarOptions -> TType list -> FreeTyvars + +val freeInVal: FreeVarOptions -> Val -> FreeTyvars + +// This one puts free variables in canonical left-to-right order. +val freeInTypeLeftToRight: TcGlobals -> bool -> TType -> Typars + +val freeInTypesLeftToRight: TcGlobals -> bool -> TType list -> Typars + +val freeInTypesLeftToRightSkippingConstraints: TcGlobals -> TType list -> Typars + +val freeInModuleTy: ModuleOrNamespaceType -> FreeTyvars + +val isDimensionless: TcGlobals -> TType -> bool + +//--------------------------------------------------------------------------- +// TType modifications and comparisons +//--------------------------------------------------------------------------- + +val stripMeasuresFromTType: TcGlobals -> TType -> TType + +//------------------------------------------------------------------------- +// Equivalence of types (up to substitution of type variables in the left-hand type) +//------------------------------------------------------------------------- + +[] +type TypeEquivEnv = + { EquivTypars: TyparMap + EquivTycons: TyconRefRemap } + + static member Empty: TypeEquivEnv + + member BindEquivTypars: Typars -> Typars -> TypeEquivEnv + + static member FromTyparInst: TyparInst -> TypeEquivEnv + + static member FromEquivTypars: Typars -> Typars -> TypeEquivEnv + +val traitsAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool + +val traitsAEquiv: TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool + +val traitKeysAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TraitWitnessInfo -> TraitWitnessInfo -> bool + +val traitKeysAEquiv: TcGlobals -> TypeEquivEnv -> TraitWitnessInfo -> TraitWitnessInfo -> bool + +val typarConstraintsAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool + +val typarConstraintsAEquiv: TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool + +val typarsAEquiv: TcGlobals -> TypeEquivEnv -> Typars -> Typars -> bool + +val typeAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool + +val typeAEquiv: TcGlobals -> TypeEquivEnv -> TType -> TType -> bool + +val returnTypesAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool + +val returnTypesAEquiv: TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool + +val tcrefAEquiv: TcGlobals -> TypeEquivEnv -> TyconRef -> TyconRef -> bool + +val valLinkageAEquiv: TcGlobals -> TypeEquivEnv -> Val -> Val -> bool + +val anonInfoEquiv: AnonRecdTypeInfo -> AnonRecdTypeInfo -> bool + +//------------------------------------------------------------------------- +// Erasure of types wrt units-of-measure and type providers +//------------------------------------------------------------------------- + +// Return true if this type is a nominal type that is an erased provided type +val isErasedType: TcGlobals -> TType -> bool + +// Return all components (units-of-measure, and types) of this type that would be erased +val getErasedTypes: TcGlobals -> TType -> TType list + +//------------------------------------------------------------------------- +// Unit operations +//------------------------------------------------------------------------- + +val MeasurePower: Measure -> int -> Measure + +val ListMeasureVarOccsWithNonZeroExponents: Measure -> (Typar * Rational) list + +val ListMeasureConOccsWithNonZeroExponents: TcGlobals -> bool -> Measure -> (TyconRef * Rational) list + +val ProdMeasures: Measure list -> Measure + +val MeasureVarExponent: Typar -> Measure -> Rational + +val MeasureExprConExponent: TcGlobals -> bool -> TyconRef -> Measure -> Rational + +val normalizeMeasure: TcGlobals -> Measure -> Measure + + +//------------------------------------------------------------------------- +// Members +//------------------------------------------------------------------------- + +val GetTypeOfMemberInFSharpForm: TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType * ArgReprInfo + +val GetTypeOfMemberInMemberForm: TcGlobals -> ValRef -> Typars * TraitWitnessInfos * CurriedArgInfos * TType option * ArgReprInfo + +val GetTypeOfIntrinsicMemberInCompiledForm: TcGlobals -> ValRef -> Typars * TraitWitnessInfos * CurriedArgInfos * TType option * ArgReprInfo + +val GetMemberTypeInMemberForm: TcGlobals -> SynMemberFlags -> ValReprInfo -> int -> TType -> range -> Typars * TraitWitnessInfos * CurriedArgInfos * TType option * ArgReprInfo + +/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) +val PartitionValTyparsForApparentEnclosingType: TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option + +/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) +val PartitionValTypars: TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option + +/// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) +val PartitionValRefTypars: TcGlobals -> ValRef -> (Typars * Typars * Typars * TyparInst * TType list) option + +/// Count the number of type parameters on the enclosing type +val CountEnclosingTyparsOfActualParentOfVal: Val -> int + +val ReturnTypeOfPropertyVal: TcGlobals -> Val -> TType + +val ArgInfosOfPropertyVal: TcGlobals -> Val -> UncurriedArgInfos + +val ArgInfosOfMember: TcGlobals -> ValRef -> CurriedArgInfos + +val GetMemberCallInfo: TcGlobals -> ValRef * ValUseFlag -> int * bool * bool * bool * bool * bool * bool * bool + +//------------------------------------------------------------------------- +// Printing +//------------------------------------------------------------------------- + +type TyparConstraintsWithTypars = (Typar * TyparConstraint) list + +module PrettyTypes = + + val NeedsPrettyTyparName: Typar -> bool + + val NewPrettyTypars: TyparInst -> Typars -> string list -> Typars * TyparInst + + val PrettyTyparNames: (Typar -> bool) -> string list -> Typars -> string list + + val PrettifyType: TcGlobals -> TType -> TType * TyparConstraintsWithTypars + + val PrettifyInstAndTyparsAndType: TcGlobals -> TyparInst * Typars * TType -> (TyparInst * Typars * TType) * TyparConstraintsWithTypars + + val PrettifyTypePair: TcGlobals -> TType * TType -> (TType * TType) * TyparConstraintsWithTypars + + val PrettifyTypes: TcGlobals -> TTypes -> TTypes * TyparConstraintsWithTypars + + /// same as PrettifyTypes, but allows passing the types along with a discriminant value + /// useful to prettify many types that need to be sorted out after prettifying operation + /// took place. + val PrettifyDiscriminantAndTypePairs: TcGlobals -> ('Discriminant * TType) list -> ('Discriminant * TType) list * TyparConstraintsWithTypars + + val PrettifyInst: TcGlobals -> TyparInst -> TyparInst * TyparConstraintsWithTypars + + val PrettifyInstAndType: TcGlobals -> TyparInst * TType -> (TyparInst * TType) * TyparConstraintsWithTypars + + val PrettifyInstAndTypes: TcGlobals -> TyparInst * TTypes -> (TyparInst * TTypes) * TyparConstraintsWithTypars + + val PrettifyInstAndSig: TcGlobals -> TyparInst * TTypes * TType -> (TyparInst * TTypes * TType) * TyparConstraintsWithTypars + + val PrettifyCurriedTypes: TcGlobals -> TType list list -> TType list list * TyparConstraintsWithTypars + + val PrettifyCurriedSigTypes: TcGlobals -> TType list list * TType -> (TType list list * TType) * TyparConstraintsWithTypars + + val PrettifyInstAndUncurriedSig: TcGlobals -> TyparInst * UncurriedArgInfos * TType -> (TyparInst * UncurriedArgInfos * TType) * TyparConstraintsWithTypars + + val PrettifyInstAndCurriedSig: TcGlobals -> TyparInst * TTypes * CurriedArgInfos * TType -> (TyparInst * TTypes * CurriedArgInfos * TType) * TyparConstraintsWithTypars + +/// Describes how generic type parameters in a type will be formatted during printing +type GenericParameterStyle = + /// Use the IsPrefixDisplay member of the TyCon to determine the style + | Implicit + /// Force the prefix style: List + | Prefix + /// Force the suffix style: int List + | Suffix + +[] +type DisplayEnv = + { includeStaticParametersInTypeNames: bool + openTopPathsSorted: Lazy + openTopPathsRaw: string list list + shortTypeNames: bool + suppressNestedTypes: bool + maxMembers: int option + showObsoleteMembers: bool + showHiddenMembers: bool + showTyparBinding: bool + showImperativeTyparAnnotations: bool + suppressInlineKeyword:bool + suppressMutableKeyword:bool + showMemberContainers: bool + shortConstraints:bool + useColonForReturnType:bool + showAttributes: bool + showOverrides:bool + showConstraintTyparAnnotations:bool + abbreviateAdditionalConstraints: bool + showTyparDefaultConstraints: bool + /// If set, signatures will be rendered with XML documentation comments for members if they exist + /// Defaults to false, expected use cases include things like signature file generation. + showDocumentation: bool + shrinkOverloads: bool + printVerboseSignatures: bool + escapeKeywordNames: bool + g: TcGlobals + contextAccessibility: Accessibility + generatedValueLayout: Val -> Layout option + genericParameterStyle: GenericParameterStyle } + + member SetOpenPaths: string list list -> DisplayEnv + + static member Empty: TcGlobals -> DisplayEnv + + member AddAccessibility: Accessibility -> DisplayEnv + + member AddOpenPath: string list -> DisplayEnv + + member AddOpenModuleOrNamespace: ModuleOrNamespaceRef -> DisplayEnv + + member UseGenericParameterStyle: GenericParameterStyle -> DisplayEnv + + static member InitialForSigFileGeneration: TcGlobals -> DisplayEnv + +val tagEntityRefName: xref: EntityRef -> name: string -> TaggedText + +/// Return the full text for an item as we want it displayed to the user as a fully qualified entity +val fullDisplayTextOfModRef: ModuleOrNamespaceRef -> string + +val fullDisplayTextOfParentOfModRef: ModuleOrNamespaceRef -> ValueOption + +val fullDisplayTextOfValRef: ValRef -> string + +val fullDisplayTextOfValRefAsLayout: ValRef -> Layout + +val fullDisplayTextOfTyconRef: TyconRef -> string + +val fullDisplayTextOfTyconRefAsLayout: TyconRef -> Layout + +val fullDisplayTextOfExnRef: TyconRef -> string + +val fullDisplayTextOfExnRefAsLayout: TyconRef -> Layout + +val fullDisplayTextOfUnionCaseRef: UnionCaseRef -> string + +val fullDisplayTextOfRecdFieldRef: RecdFieldRef -> string + +val ticksAndArgCountTextOfTyconRef: TyconRef -> string + +/// A unique qualified name for each type definition, used to qualify the names of interface implementation methods +val qualifiedMangledNameOfTyconRef: TyconRef -> string -> string + +val qualifiedInterfaceImplementationName: TcGlobals -> TType -> string -> string + +val trimPathByDisplayEnv: DisplayEnv -> string list -> string + +val prefixOfStaticReq: TyparStaticReq -> string + +val prefixOfRigidTypar: Typar -> string + +/// Utilities used in simplifying types for visual presentation +module SimplifyTypes = + + type TypeSimplificationInfo = + { singletons: Typar Zset + inplaceConstraints: Zmap + postfixConstraints: TyparConstraintsWithTypars } + + val typeSimplificationInfo0: TypeSimplificationInfo + + val CollectInfo: bool -> TType list -> TyparConstraintsWithTypars -> TypeSimplificationInfo + +val superOfTycon: TcGlobals -> Tycon -> TType + +val abstractSlotValRefsOfTycons: Tycon list -> ValRef list + +val abstractSlotValsOfTycons: Tycon list -> Val list + +//------------------------------------------------------------------------- +// Free variables in expressions etc. +//------------------------------------------------------------------------- + +val emptyFreeVars: FreeVars + +val unionFreeVars: FreeVars -> FreeVars -> FreeVars + +val accFreeInTargets: FreeVarOptions -> DecisionTreeTarget array -> FreeVars -> FreeVars + +val accFreeInExprs: FreeVarOptions -> Exprs -> FreeVars -> FreeVars + +val accFreeInSwitchCases: FreeVarOptions -> DecisionTreeCase list -> DecisionTree option -> FreeVars -> FreeVars + +val accFreeInDecisionTree: FreeVarOptions -> DecisionTree -> FreeVars -> FreeVars + +/// Get the free variables in a module definition. +val freeInModuleOrNamespace: FreeVarOptions -> ModuleOrNamespaceExpr -> FreeVars + +/// Get the free variables in an expression. +val freeInExpr: FreeVarOptions -> Expr -> FreeVars + +/// Get the free variables in the right hand side of a binding. +val freeInBindingRhs: FreeVarOptions -> Binding -> FreeVars + +/// Check if a set of free type variables are all public +val freeTyvarsAllPublic: FreeTyvars -> bool + +/// Check if a set of free variables are all public +val freeVarsAllPublic: FreeVars -> bool + +/// Get the mark/range/position information from an expression +type Expr with + member Range: range + +/// Compute the type of an expression from the expression itself +val tyOfExpr: TcGlobals -> Expr -> TType + +/// A flag to govern whether arity inference should be type-directed or syntax-directed when +/// inferring an arity from a lambda expression. +[] +type AllowTypeDirectedDetupling = + | Yes + | No + +/// Given a (curried) lambda expression, pull off its arguments +val stripTopLambda: Expr * TType -> Typars * Val list list * Expr * TType + +/// Given a lambda expression, extract the ValReprInfo for its arguments and other details +val InferArityOfExpr: TcGlobals -> AllowTypeDirectedDetupling -> TType -> Attribs list list -> Attribs -> Expr -> ValReprInfo + +/// Given a lambda binding, extract the ValReprInfo for its arguments and other details +val InferArityOfExprBinding: TcGlobals -> AllowTypeDirectedDetupling -> Val -> Expr -> ValReprInfo + +/// Mutate a value to indicate it should be considered a local rather than a module-bound definition +// REVIEW: this mutation should not be needed +val setValHasNoArity: Val -> Val + +/// Indicate what should happen to value definitions when copying expressions +type ValCopyFlag = + | CloneAll + | CloneAllAndMarkExprValsAsCompilerGenerated + + /// OnlyCloneExprVals is a nasty setting to reuse the cloning logic in a mode where all + /// Tycon and "module/member" Val objects keep their identity, but the Val objects for all Expr bindings + /// are cloned. This is used to 'fixup' the TAST created by tlr.fs + /// + /// This is a fragile mode of use. It's not really clear why TLR needs to create a "bad" expression tree that + /// reuses Val objects as multiple value bindings, and its been the cause of several subtle bugs. + | OnlyCloneExprVals + +/// Remap a reference to a type definition using the given remapping substitution +val remapTyconRef: TyconRefRemap -> TyconRef -> TyconRef + +/// Remap a reference to a union case using the given remapping substitution +val remapUnionCaseRef: TyconRefRemap -> UnionCaseRef -> UnionCaseRef + +/// Remap a reference to a record field using the given remapping substitution +val remapRecdFieldRef: TyconRefRemap -> RecdFieldRef -> RecdFieldRef + +/// Remap a reference to a value using the given remapping substitution +val remapValRef: Remap -> ValRef -> ValRef + +/// Remap an expression using the given remapping substitution +val remapExpr: TcGlobals -> ValCopyFlag -> Remap -> Expr -> Expr + +/// Remap an attribute using the given remapping substitution +val remapAttrib: TcGlobals -> Remap -> Attrib -> Attrib + +/// Remap a (possible generic) type using the given remapping substitution +val remapPossibleForallTy: TcGlobals -> Remap -> TType -> TType + +/// Copy an entire module or namespace type using the given copying flags +val copyModuleOrNamespaceType: TcGlobals -> ValCopyFlag -> ModuleOrNamespaceType -> ModuleOrNamespaceType + +/// Copy an entire expression using the given copying flags +val copyExpr: TcGlobals -> ValCopyFlag -> Expr -> Expr + +/// Copy an entire implementation file using the given copying flags +val copyImplFile: TcGlobals -> ValCopyFlag -> TypedImplFile -> TypedImplFile + +/// Copy a method slot signature, including new generic type parameters if the slot signature represents a generic method +val copySlotSig: SlotSig -> SlotSig + +/// Instantiate the generic type parameters in a method slot signature, building a new one +val instSlotSig: TyparInst -> SlotSig -> SlotSig + +/// Instantiate the generic type parameters in an expression, building a new one +val instExpr: TcGlobals -> TyparInst -> Expr -> Expr + +/// The remapping that corresponds to a module meeting its signature +/// and also report the set of tycons, tycon representations and values hidden in the process. +type SignatureRepackageInfo = + { /// The list of corresponding values + RepackagedVals: (ValRef * ValRef) list + + /// The list of corresponding modules, namespaces and type definitions + RepackagedEntities: (TyconRef * TyconRef) list } + + /// The empty table + static member Empty: SignatureRepackageInfo + +/// A set of tables summarizing the items hidden by a signature +type SignatureHidingInfo = + { HiddenTycons: Zset + HiddenTyconReprs: Zset + HiddenVals: Zset + HiddenRecdFields: Zset + HiddenUnionCases: Zset } + + /// The empty table representing no hiding + static member Empty: SignatureHidingInfo + +/// Compute the remapping information implied by a signature being inferred for a particular implementation +val ComputeRemappingFromImplementationToSignature: TcGlobals -> ModuleOrNamespaceExpr -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo + +/// Compute the remapping information implied by an explicit signature being given for an inferred signature +val ComputeRemappingFromInferredSignatureToExplicitSignature: TcGlobals -> ModuleOrNamespaceType -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo + +/// Compute the hiding information that corresponds to the hiding applied at an assembly boundary +val ComputeHidingInfoAtAssemblyBoundary: ModuleOrNamespaceType -> SignatureHidingInfo -> SignatureHidingInfo + +val mkRepackageRemapping: SignatureRepackageInfo -> Remap + +/// Wrap one module or namespace implementation in a 'namespace N' outer wrapper +val wrapModuleOrNamespaceExprInNamespace: Ident -> CompilationPath -> ModuleOrNamespaceExpr -> ModuleOrNamespaceExpr + +/// Wrap one module or namespace definition in a 'namespace N' outer wrapper +val wrapModuleOrNamespaceTypeInNamespace: Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespaceType * ModuleOrNamespace + +/// Wrap one module or namespace definition in a 'module M = ..' outer wrapper +val wrapModuleOrNamespaceType: Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespace + +/// Given an implementation, fetch its recorded signature +val SigTypeOfImplFile: TypedImplFile -> ModuleOrNamespaceType + +/// Given a namespace, module or type definition, try to produce a reference to that entity. +val tryRescopeEntity: CcuThunk -> Entity -> ValueOption + +/// Given a value definition, try to produce a reference to that value. Fails for local values. +val tryRescopeVal: CcuThunk -> Remap -> Val -> ValueOption + +/// Make the substitution (remapping) table for viewing a module or namespace 'from the outside' +/// +/// Given the top-most signatures constrains the public compilation units +/// of an assembly, compute a remapping that converts local references to non-local references. +/// This remapping must be applied to all pickled expressions and types +/// exported from the assembly. +val MakeExportRemapping: CcuThunk -> ModuleOrNamespace -> Remap + +/// Make a remapping table for viewing a module or namespace 'from the outside' +val ApplyExportRemappingToEntity: TcGlobals -> Remap -> ModuleOrNamespace -> ModuleOrNamespace + +/// Determine if a type definition is hidden by a signature +val IsHiddenTycon: (Remap * SignatureHidingInfo) list -> Tycon -> bool + +/// Determine if the representation of a type definition is hidden by a signature +val IsHiddenTyconRepr: (Remap * SignatureHidingInfo) list -> Tycon -> bool + +/// Determine if a member, function or value is hidden by a signature +val IsHiddenVal: (Remap * SignatureHidingInfo) list -> Val -> bool + +/// Determine if a record field is hidden by a signature +val IsHiddenRecdField: (Remap * SignatureHidingInfo) list -> RecdFieldRef -> bool + +/// Adjust marks in expressions, replacing all marks by the given mark. +/// Used when inlining. +val remarkExpr: range -> Expr -> Expr + +/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments +val primMkApp: Expr * TType -> TypeInst -> Exprs -> range -> Expr + +/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments. +/// Reduce the application via let-bindings if the function value is a lambda expression. +val mkApps: TcGlobals -> (Expr * TType) * TType list list * Exprs * range -> Expr + +/// Build the application of a generic construct to a set of type arguments. +/// Reduce the application via substitution if the function value is a typed lambda expression. +val mkTyAppExpr: range -> Expr * TType -> TType list -> Expr + +/// Build an expression to mutate a local +/// localv <- e +val mkValSet: range -> ValRef -> Expr -> Expr + +/// Build an expression to mutate the contents of a local pointer +/// *localv_ptr = e +val mkAddrSet: range -> ValRef -> Expr -> Expr + +/// Build an expression to dereference a local pointer +/// *localv_ptr +val mkAddrGet: range -> ValRef -> Expr + +/// Build an expression to take the address of a local +/// &localv +val mkValAddr: range -> readonly: bool -> ValRef -> Expr + +/// Build an expression representing the read of an instance class or record field. +/// First take the address of the record expression if it is a struct. +val mkRecdFieldGet: TcGlobals -> Expr * RecdFieldRef * TypeInst * range -> Expr + +/// Accumulate the targets actually used in a decision graph (for reporting warnings) +val accTargetsOfDecisionTree: DecisionTree -> int list -> int list + +/// Make a 'match' expression applying some peep-hole optimizations along the way, e.g to +/// pre-decide the branch taken at compile-time. +val mkAndSimplifyMatch: DebugPointAtBinding -> range -> range -> TType -> DecisionTree -> DecisionTreeTarget list -> Expr + +/// Make a 'match' expression without applying any peep-hole optimizations. +val primMkMatch: DebugPointAtBinding * range * DecisionTree * DecisionTreeTarget array * range * TType -> Expr + +/// Work out what things on the right-han-side of a 'let rec' recursive binding need to be fixed up +val IterateRecursiveFixups: + TcGlobals -> Val option -> + (Val option -> Expr -> (Expr -> Expr) -> Expr -> unit) -> + Expr * (Expr -> Expr) -> Expr -> unit + +/// Given a lambda expression taking multiple variables, build a corresponding lambda taking a tuple +val MultiLambdaToTupledLambda: TcGlobals -> Val list -> Expr -> Val * Expr + +/// Given a lambda expression, adjust it to have be one or two lambda expressions (fun a -> (fun b -> ...)) +/// where the first has the given arity. +val AdjustArityOfLambdaBody: TcGlobals -> int -> Val list -> Expr -> Val list * Expr + +/// Make an application expression, doing beta reduction by introducing let-bindings +/// if the function expression is a construction of a lambda +val MakeApplicationAndBetaReduce: TcGlobals -> Expr * TType * TypeInst list * Exprs * range -> Expr + +/// Make a delegate invoke expression for an F# delegate type, doing beta reduction by introducing let-bindings +/// if the delegate expression is a construction of a delegate. +val MakeFSharpDelegateInvokeAndTryBetaReduce: TcGlobals -> invokeRef: Expr * f: Expr * fty: TType * tyargs: TypeInst * argsl: Exprs * m: range -> Expr + +/// Combine two static-resolution requirements on a type parameter +val JoinTyparStaticReq: TyparStaticReq -> TyparStaticReq -> TyparStaticReq + +/// Layout for internal compiler debugging purposes +module DebugPrint = + + /// A global flag indicating whether debug output should include ranges + val layoutRanges: bool ref + + /// Convert a type to a string for debugging purposes + val showType: TType -> string + + /// Convert an expression to a string for debugging purposes + val showExpr: TcGlobals -> Expr -> string + + /// Debug layout for a reference to a value + val valRefL: ValRef -> Layout + + /// Debug layout for a reference to a union case + val unionCaseRefL: UnionCaseRef -> Layout + + /// Debug layout for an value definition at its binding site + val valAtBindL: TcGlobals -> Val -> Layout + + /// Debug layout for an integer + val intL: int -> Layout + + /// Debug layout for a value definition + val valL: Val -> Layout + + /// Debug layout for a type parameter definition + val typarDeclL: Typar -> Layout + + /// Debug layout for a trait constraint + val traitL: TraitConstraintInfo -> Layout + + /// Debug layout for a type parameter + val typarL: Typar -> Layout + + /// Debug layout for a set of type parameters + val typarsL: Typars -> Layout + + /// Debug layout for a type + val typeL: TType -> Layout + + /// Debug layout for a method slot signature + val slotSigL: SlotSig -> Layout + + /// Debug layout for the type signature of a module or namespace definition + val entityTypeL: TcGlobals -> ModuleOrNamespaceType -> Layout + + /// Debug layout for a module or namespace definition + val entityL: TcGlobals -> ModuleOrNamespace -> Layout + + /// Debug layout for the type of a value + val typeOfValL: Val -> Layout + + /// Debug layout for a binding of an expression to a value + val bindingL: TcGlobals -> Binding -> Layout + + /// Debug layout for an expression + val exprL: TcGlobals -> Expr -> Layout + + /// Debug layout for a type definition + val tyconL: TcGlobals -> Tycon -> Layout + + /// Debug layout for a decision tree + val decisionTreeL: TcGlobals -> DecisionTree -> Layout + + /// Debug layout for an implementation file + val implFileL: TcGlobals -> TypedImplFile -> Layout + + /// Debug layout for a list of implementation files + val implFilesL: TcGlobals -> TypedImplFile list -> Layout + + /// Debug layout for class and record fields + val recdFieldRefL: RecdFieldRef -> Layout + +/// A set of function parameters (visitor) for folding over expressions +type ExprFolder<'State> = + { exprIntercept: (* recurseF *) ('State -> Expr -> 'State) -> (* noInterceptF *) ('State -> Expr -> 'State) -> 'State -> Expr -> 'State + valBindingSiteIntercept: 'State -> bool * Val -> 'State + nonRecBindingsIntercept: 'State -> Binding -> 'State + recBindingsIntercept: 'State -> Bindings -> 'State + dtreeIntercept: 'State -> DecisionTree -> 'State + targetIntercept: ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option + tmethodIntercept: ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option} + +/// The empty set of actions for folding over expressions +val ExprFolder0: ExprFolder<'State> + +/// Fold over all the expressions in an implementation file +val FoldImplFile: ExprFolder<'State> -> ('State -> TypedImplFile -> 'State) + +/// Fold over all the expressions in an expression +val FoldExpr: ExprFolder<'State> -> ('State -> Expr -> 'State) + +#if DEBUG +/// Extract some statistics from an expression +val ExprStats: Expr -> string +#endif + +/// Build a nativeptr type +val mkNativePtrTy: TcGlobals -> TType -> TType + +/// Build a 'voidptr' type +val mkVoidPtrTy: TcGlobals -> TType + +/// Build a single-dimensional array type +val mkArrayType: TcGlobals -> TType -> TType + +/// Determine if a type is a value option type +val isValueOptionTy: TcGlobals -> TType -> bool + +/// Determine if a type is an option type +val isOptionTy: TcGlobals -> TType -> bool + +/// Take apart an option type +val destOptionTy: TcGlobals -> TType -> TType + +/// Try to take apart an option type +val tryDestOptionTy: TcGlobals -> TType -> ValueOption + +/// Determine is a type is a System.Nullable type +val isNullableTy: TcGlobals -> TType -> bool + +/// Try to take apart a System.Nullable type +val tryDestNullableTy: TcGlobals -> TType -> ValueOption + +/// Take apart a System.Nullable type +val destNullableTy: TcGlobals -> TType -> TType + +/// Determine if a type is a System.Linq.Expression type +val isLinqExpressionTy: TcGlobals -> TType -> bool + +/// Take apart a System.Linq.Expression type +val destLinqExpressionTy: TcGlobals -> TType -> TType + +/// Try to take apart a System.Linq.Expression type +val tryDestLinqExpressionTy: TcGlobals -> TType -> TType option + +/// Determine if a type is an IDelegateEvent type +val isIDelegateEventType: TcGlobals -> TType -> bool + +/// Take apart an IDelegateEvent type +val destIDelegateEventType: TcGlobals -> TType -> TType + +/// Build an IEvent type +val mkIEventType: TcGlobals -> TType -> TType -> TType + +/// Build an IObservable type +val mkIObservableType: TcGlobals -> TType -> TType + +/// Build an IObserver type +val mkIObserverType: TcGlobals -> TType -> TType + +/// Build an Lazy type +val mkLazyTy: TcGlobals -> TType -> TType + +/// Build an PrintFormat type +val mkPrintfFormatTy: TcGlobals -> TType -> TType -> TType -> TType -> TType -> TType + +//------------------------------------------------------------------------- +// Classify types +//------------------------------------------------------------------------- + +/// Represents metadata extracted from a nominal type +type TypeDefMetadata = + | ILTypeMetadata of TILObjectReprData + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata of TProvidedTypeInfo +#endif + +/// Extract metadata from a type definition +val metadataOfTycon: Tycon -> TypeDefMetadata + +/// Extract metadata from a type +val metadataOfTy: TcGlobals -> TType -> TypeDefMetadata + +/// Determine if a type is the System.String type +val isStringTy: TcGlobals -> TType -> bool + +/// Determine if a type is an F# list type +val isListTy: TcGlobals -> TType -> bool + +/// Determine if a type is a nominal .NET type +val isILAppTy: TcGlobals -> TType -> bool + +/// Determine if a type is any kind of array type +val isArrayTy: TcGlobals -> TType -> bool + +/// Determine if a type is a single-dimensional array type +val isArray1DTy: TcGlobals -> TType -> bool + +/// Get the element type of an array type +val destArrayTy: TcGlobals -> TType -> TType + +/// Get the element type of an F# list type +val destListTy: TcGlobals -> TType -> TType + +/// Build an array type of the given rank +val mkArrayTy: TcGlobals -> int -> TType -> range -> TType + +/// Check if a type definition is one of the artificial type definitions used for array types of different ranks +val isArrayTyconRef: TcGlobals -> TyconRef -> bool + +/// Determine the rank of one of the artificial type definitions used for array types +val rankOfArrayTyconRef: TcGlobals -> TyconRef -> int + +/// Determine if a type is the F# unit type +val isUnitTy: TcGlobals -> TType -> bool + +/// Determine if a type is the System.Object type +val isObjTy: TcGlobals -> TType -> bool + +/// Determine if a type is the System.ValueType type +val isValueTypeTy: TcGlobals -> TType -> bool + +/// Determine if a type is the System.Void type +val isVoidTy: TcGlobals -> TType -> bool + +/// Get the element type of an array type +val destArrayTy: TcGlobals -> TType -> TType + +/// Get the rank of an array type +val rankOfArrayTy: TcGlobals -> TType -> int + +/// Determine if a reference to a type definition is an interface type +val isInterfaceTyconRef: TyconRef -> bool + +/// Determine if a type is a delegate type +val isDelegateTy: TcGlobals -> TType -> bool + +/// Determine if a type is a delegate type defined in F# +val isFSharpDelegateTy: TcGlobals -> TType -> bool + +/// Determine if a type is an interface type +val isInterfaceTy: TcGlobals -> TType -> bool + +/// Determine if a type is a FSharpRef type +val isRefTy: TcGlobals -> TType -> bool + +/// Determine if a type is a function (including generic). Not the same as isFunTy. +val isForallFunctionTy: TcGlobals -> TType -> bool + +/// Determine if a type is a sealed type +val isSealedTy: TcGlobals -> TType -> bool + +/// Determine if a type is a ComInterop type +val isComInteropTy: TcGlobals -> TType -> bool + +/// Determine the underlying type of an enum type (normally int32) +val underlyingTypeOfEnumTy: TcGlobals -> TType -> TType + +/// If the input type is an enum type, then convert to its underlying type, otherwise return the input type +val normalizeEnumTy: TcGlobals -> TType -> TType + +/// Determine if a type is a struct type +val isStructTy: TcGlobals -> TType -> bool + +val isStructOrEnumTyconTy: TcGlobals -> TType -> bool + +/// Determine if a type is a variable type with the ': struct' constraint. +/// +/// Note, isStructTy does not include type parameters with the ': struct' constraint +/// This predicate is used to detect those type parameters. +val isNonNullableStructTyparTy: TcGlobals -> TType -> bool + +/// Determine if a type is a variable type with the ': not struct' constraint. +/// +/// Note, isRefTy does not include type parameters with the ': not struct' constraint +/// This predicate is used to detect those type parameters. +val isReferenceTyparTy: TcGlobals -> TType -> bool + +/// Determine if a type is an unmanaged type +val isUnmanagedTy: TcGlobals -> TType -> bool + +/// Determine if a type is a class type +val isClassTy: TcGlobals -> TType -> bool + +/// Determine if a type is an enum type +val isEnumTy: TcGlobals -> TType -> bool + +/// Determine if a type is a struct, record or union type +val isStructRecordOrUnionTyconTy: TcGlobals -> TType -> bool + +/// For "type Class as self", 'self' is fixed up after initialization. To support this, +/// it is converted behind the scenes to a ref. This function strips off the ref and +/// returns the underlying type. +val StripSelfRefCell: TcGlobals * ValBaseOrThisInfo * TType -> TType + +/// An active pattern to determine if a type is a nominal type, possibly instantiated +val (|AppTy|_|): TcGlobals -> TType -> (TyconRef * TType list) option + +/// An active pattern to match System.Nullable types +val (|NullableTy|_|): TcGlobals -> TType -> TType option + +/// An active pattern to transform System.Nullable types to their input, otherwise leave the input unchanged +val (|StripNullableTy|): TcGlobals -> TType -> TType + +/// Matches any byref type, yielding the target type +val (|ByrefTy|_|): TcGlobals -> TType -> TType option + +//------------------------------------------------------------------------- +// Special semantic constraints +//------------------------------------------------------------------------- + +val IsUnionTypeWithNullAsTrueValue: TcGlobals -> Tycon -> bool + +val TyconHasUseNullAsTrueValueAttribute: TcGlobals -> Tycon -> bool + +val CanHaveUseNullAsTrueValueAttribute: TcGlobals -> Tycon -> bool + +val MemberIsCompiledAsInstance: TcGlobals -> TyconRef -> bool -> ValMemberInfo -> Attribs -> bool + +val ValSpecIsCompiledAsInstance: TcGlobals -> Val -> bool + +val ValRefIsCompiledAsInstanceMember: TcGlobals -> ValRef -> bool + +val ModuleNameIsMangled: TcGlobals -> Attribs -> bool + +val CompileAsEvent: TcGlobals -> Attribs -> bool + +val TypeNullIsExtraValue: TcGlobals -> range -> TType -> bool + +val TypeNullIsTrueValue: TcGlobals -> TType -> bool + +val TypeNullNotLiked: TcGlobals -> range -> TType -> bool + +val TypeNullNever: TcGlobals -> TType -> bool + +val TypeSatisfiesNullConstraint: TcGlobals -> range -> TType -> bool + +val TypeHasDefaultValue: TcGlobals -> range -> TType -> bool + +val isAbstractTycon: Tycon -> bool + +val isUnionCaseRefDefinitelyMutable: UnionCaseRef -> bool + +val isRecdOrUnionOrStructTyconRefDefinitelyMutable: TyconRef -> bool + +val isExnDefinitelyMutable: TyconRef -> bool + +val isUnionCaseFieldMutable: TcGlobals -> UnionCaseRef -> int -> bool + +val isExnFieldMutable: TyconRef -> int -> bool + +val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool + +val isRecdOrStructTyconRefAssumedImmutable: TcGlobals -> TyconRef -> bool + +val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool + +val useGenuineField: Tycon -> RecdField -> bool + +val ComputeFieldName: Tycon -> RecdField -> string + +//------------------------------------------------------------------------- +// Destruct slotsigs etc. +//------------------------------------------------------------------------- + +val slotSigHasVoidReturnTy: SlotSig -> bool + +val actualReturnTyOfSlotSig: TypeInst -> TypeInst -> SlotSig -> TType option + +val returnTyOfMethod: TcGlobals -> ObjExprMethod -> TType option + +//------------------------------------------------------------------------- +// Primitives associated with initialization graphs +//------------------------------------------------------------------------- + +val mkRefCell: TcGlobals -> range -> TType -> Expr -> Expr + +val mkRefCellGet: TcGlobals -> range -> TType -> Expr -> Expr + +val mkRefCellSet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkLazyDelayed: TcGlobals -> range -> TType -> Expr -> Expr + +val mkLazyForce: TcGlobals -> range -> TType -> Expr -> Expr + +val mkRefCellContentsRef: TcGlobals -> RecdFieldRef + +/// Check if a type is an FSharpRef type +val isRefCellTy: TcGlobals -> TType -> bool + +/// Get the element type of an FSharpRef type +val destRefCellTy: TcGlobals -> TType -> TType + +/// Create the FSharpRef type for a given element type +val mkRefCellTy: TcGlobals -> TType -> TType + +/// Create the IEnumerable (seq) type for a given element type +val mkSeqTy: TcGlobals -> TType -> TType + +/// Create the IEnumerator type for a given element type +val mkIEnumeratorTy: TcGlobals -> TType -> TType + +/// Create the list type for a given element type +val mkListTy: TcGlobals -> TType -> TType + +/// Create the option type for a given element type +val mkOptionTy: TcGlobals -> TType -> TType + +/// Create the voption type for a given element type +val mkValueOptionTy : TcGlobals -> TType -> TType + +/// Create the Nullable type for a given element type +val mkNullableTy: TcGlobals -> TType -> TType + +/// Create the union case 'None' for an option type +val mkNoneCase: TcGlobals -> UnionCaseRef + +/// Create the union case 'Some(expr)' for an option type +val mkSomeCase: TcGlobals -> UnionCaseRef + +/// Create the struct union case 'ValueSome(expr)' for a voption type +val mkValueSomeCase: TcGlobals -> UnionCaseRef + +/// Create the struct union case 'Some' or 'ValueSome(expr)' for a voption type +val mkAnySomeCase: TcGlobals -> isStruct: bool -> UnionCaseRef + +/// Create the expression '[]' for a list type +val mkNil: TcGlobals -> range -> TType -> Expr + +/// Create the expression 'headExpr:: tailExpr' +val mkCons: TcGlobals -> TType -> Expr -> Expr -> Expr + +/// Create the expression 'Some(expr)' +val mkSome: TcGlobals -> TType -> Expr -> range -> Expr + +/// Create the expression 'None' for an option-type +val mkNone: TcGlobals -> TType -> range -> Expr + +val mkOptionToNullable: TcGlobals -> range -> TType -> Expr -> Expr + +val mkOptionDefaultValue: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +//------------------------------------------------------------------------- +// Make a few more expressions +//------------------------------------------------------------------------- + +val mkSequential: DebugPointAtSequential -> range -> Expr -> Expr -> Expr + +val mkThenDoSequential: DebugPointAtSequential -> range -> expr: Expr -> stmt: Expr -> Expr + +/// This is used for tacking on code _before_ the expression. The SuppressStmt +/// setting is used for debug points, suppressing the debug points for the statement if possible. +val mkCompGenSequential: range -> stmt: Expr -> expr: Expr -> Expr + +/// This is used for tacking on code _after_ the expression. The SuppressStmt +/// setting is used for debug points, suppressing the debug points for the statement if possible. +val mkCompGenThenDoSequential: range -> expr: Expr -> stmt: Expr -> Expr + +val mkSequentials: DebugPointAtSequential -> TcGlobals -> range -> Exprs -> Expr + +val mkRecordExpr: TcGlobals -> RecordConstructionInfo * TyconRef * TypeInst * RecdFieldRef list * Exprs * range -> Expr + +val mkUnbox: TType -> Expr -> range -> Expr + +val mkBox: TType -> Expr -> range -> Expr + +val mkIsInst: TType -> Expr -> range -> Expr + +val mkNull: range -> TType -> Expr + +val mkNullTest: TcGlobals -> range -> Expr -> Expr -> Expr -> Expr + +val mkNonNullTest: TcGlobals -> range -> Expr -> Expr + +val mkIsInstConditional: TcGlobals -> range -> TType -> Expr -> Val -> Expr -> Expr -> Expr + +val mkThrow: range -> TType -> Expr -> Expr + +val mkGetArg0: range -> TType -> Expr + +val mkDefault: range * TType -> Expr + +val isThrow: Expr -> bool + +val mkString: TcGlobals -> range -> string -> Expr + +val mkBool: TcGlobals -> range -> bool -> Expr + +val mkByte: TcGlobals -> range -> byte -> Expr + +val mkUInt16: TcGlobals -> range -> uint16 -> Expr + +val mkTrue: TcGlobals -> range -> Expr + +val mkFalse: TcGlobals -> range -> Expr + +val mkUnit: TcGlobals -> range -> Expr + +val mkInt32: TcGlobals -> range -> int32 -> Expr + +val mkInt: TcGlobals -> range -> int -> Expr + +val mkZero: TcGlobals -> range -> Expr + +val mkOne: TcGlobals -> range -> Expr + +val mkTwo: TcGlobals -> range -> Expr + +val mkMinusOne: TcGlobals -> range -> Expr + +val destInt32: Expr -> int32 option + +//------------------------------------------------------------------------- +// Primitives associated with quotations +//------------------------------------------------------------------------- + +val isQuotedExprTy: TcGlobals -> TType -> bool + +val destQuotedExprTy: TcGlobals -> TType -> TType + +val mkQuotedExprTy: TcGlobals -> TType -> TType + +val mkRawQuotedExprTy: TcGlobals -> TType + +//------------------------------------------------------------------------- +// Primitives associated with IL code gen +//------------------------------------------------------------------------- + +val mspec_Type_GetTypeFromHandle: TcGlobals -> ILMethodSpec + +val fspec_Missing_Value: TcGlobals -> ILFieldSpec + +val mkInitializeArrayMethSpec: TcGlobals -> ILMethodSpec + +val mkByteArrayTy: TcGlobals -> TType + +val mkInvalidCastExnNewobj: TcGlobals -> ILInstr + + +//------------------------------------------------------------------------- +// Construct calls to some intrinsic functions +//------------------------------------------------------------------------- + +val mkCallNewFormat: TcGlobals -> range -> TType -> TType -> TType -> TType -> TType -> formatStringExpr: Expr -> Expr + +val mkCallUnbox: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallGetGenericComparer: TcGlobals -> range -> Expr + +val mkCallGetGenericEREqualityComparer: TcGlobals -> range -> Expr + +val mkCallGetGenericPEREqualityComparer: TcGlobals -> range -> Expr + +val mkCallUnboxFast: TcGlobals -> range -> TType -> Expr -> Expr + +val canUseUnboxFast: TcGlobals -> range -> TType -> bool + +val mkCallDispose: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeq: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallTypeTest: TcGlobals -> range -> TType -> Expr -> Expr + +val canUseTypeTestFast: TcGlobals -> TType -> bool + +val mkCallTypeOf: TcGlobals -> range -> TType -> Expr + +val mkCallTypeDefOf: TcGlobals -> range -> TType -> Expr + +val mkCallCreateInstance: TcGlobals -> range -> TType -> Expr + +val mkCallCreateEvent: TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallArrayLength: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallArrayGet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallArray2DGet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallArray3DGet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallArray4DGet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallArraySet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallArray2DSet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallArray3DSet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallArray4DSet: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallHash: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallBox: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallIsNull: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallIsNotNull: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallRaise: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallGenericComparisonWithComparerOuter: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallGenericEqualityEROuter: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallGenericEqualityWithComparerOuter: TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallGenericHashWithComparerOuter: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallEqualsOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallNotEqualsOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallLessThanOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallLessThanOrEqualsOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallGreaterThanOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallGreaterThanOrEqualsOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallAdditionOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallSubtractionOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallMultiplyOperator: TcGlobals -> range -> ty1: TType -> ty2: TType -> rty: TType -> Expr -> Expr -> Expr + +val mkCallDivisionOperator: TcGlobals -> range -> ty1: TType -> ty2: TType -> rty: TType -> Expr -> Expr -> Expr + +val mkCallModulusOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallDefaultOf: TcGlobals -> range -> TType -> Expr + +val mkCallBitwiseAndOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallBitwiseOrOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallBitwiseXorOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallShiftLeftOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallShiftRightOperator: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallUnaryNegOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallUnaryNotOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallAdditionChecked: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallSubtractionChecked: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallMultiplyChecked: TcGlobals -> range -> ty1: TType -> ty2: TType -> rty: TType -> Expr -> Expr -> Expr + +val mkCallUnaryNegChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToByteChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToSByteChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt16Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt16Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToIntChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt32Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt32Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt64Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt64Checked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToIntPtrChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUIntPtrChecked: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToByteOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToSByteOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt16Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt16Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToIntOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt32Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt32Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToInt64Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUInt64Operator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToSingleOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToDoubleOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToIntPtrOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToUIntPtrOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToCharOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallToEnumOperator: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallDeserializeQuotationFSharp20Plus: TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallDeserializeQuotationFSharp40Plus: TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkCallCastQuotation: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallLiftValueWithName: TcGlobals -> range -> TType -> string -> Expr -> Expr + +val mkCallLiftValue: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallLiftValueWithDefn: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeqCollect: TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + +val mkCallSeqUsing: TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + +val mkCallSeqDelay: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeqAppend: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallSeqFinally: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallSeqGenerated: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +val mkCallSeqOfFunctions: TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr + +val mkCallSeqToArray: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeqToList: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeqMap: TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + +val mkCallSeqSingleton: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallSeqEmpty: TcGlobals -> range -> TType -> Expr + +/// Make a call to the 'isprintf' function for string interpolation +val mkCall_sprintf: g: TcGlobals -> m: range -> funcTy: TType -> fmtExpr: Expr -> fillExprs: Expr list -> Expr + +val mkILAsmCeq: TcGlobals -> range -> Expr -> Expr -> Expr + +val mkILAsmClt: TcGlobals -> range -> Expr -> Expr -> Expr + +val mkCallFailInit: TcGlobals -> range -> Expr + +val mkCallFailStaticInit: TcGlobals -> range -> Expr + +val mkCallCheckThis: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCase: DecisionTreeTest * DecisionTree -> DecisionTreeCase + +val mkCallQuoteToLinqLambdaExpression: TcGlobals -> range -> TType -> Expr -> Expr + +val mkCallGetQuerySourceAsEnumerable: TcGlobals -> range -> TType -> TType -> Expr -> Expr + +val mkCallNewQuerySource: TcGlobals -> range -> TType -> TType -> Expr -> Expr + +val mkArray: TType * Exprs * range -> Expr + +val mkStaticCall_String_Concat2: TcGlobals -> range -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat3: TcGlobals -> range -> Expr -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat4: TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat_Array: TcGlobals -> range -> Expr -> Expr + +/// Use a witness in BuiltInWitnesses +val tryMkCallBuiltInWitness: TcGlobals -> TraitConstraintInfo -> Expr list -> range -> Expr option + +/// Use an operator as a witness +val tryMkCallCoreFunctionAsBuiltInWitness: TcGlobals -> IntrinsicValRef -> TType list -> Expr list -> range -> Expr option + +//------------------------------------------------------------------------- +// operations primarily associated with the optimization to fix +// up loops to generate .NET code that does not include array bound checks +//------------------------------------------------------------------------- + +val mkDecr: TcGlobals -> range -> Expr -> Expr + +val mkIncr: TcGlobals -> range -> Expr -> Expr + +val mkLdlen: TcGlobals -> range -> Expr -> Expr + +val mkLdelem: TcGlobals -> range -> TType -> Expr -> Expr -> Expr + +//------------------------------------------------------------------------- +// Analyze attribute sets +//------------------------------------------------------------------------- + +val TryDecodeILAttribute: ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option + +val TryFindILAttribute: BuiltinAttribInfo -> ILAttributes -> bool + +val TryFindILAttributeOpt: BuiltinAttribInfo option -> ILAttributes -> bool + +val IsMatchingFSharpAttribute: TcGlobals -> BuiltinAttribInfo -> Attrib -> bool + +val IsMatchingFSharpAttributeOpt: TcGlobals -> BuiltinAttribInfo option -> Attrib -> bool + +val HasFSharpAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> bool + +val HasFSharpAttributeOpt: TcGlobals -> BuiltinAttribInfo option -> Attribs -> bool + +val TryFindFSharpAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> Attrib option + +val TryFindFSharpAttributeOpt: TcGlobals -> BuiltinAttribInfo option -> Attribs -> Attrib option + +val TryFindFSharpBoolAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option + +val TryFindFSharpBoolAttributeAssumeFalse: TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option + +val TryFindFSharpStringAttribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> string option + +val TryFindFSharpInt32Attribute: TcGlobals -> BuiltinAttribInfo -> Attribs -> int32 option + +/// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. +/// +/// This is used to detect the 'DefaultMemberAttribute' and 'ConditionalAttribute' attributes (on type definitions) +val TryFindTyconRefStringAttribute: TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> string option + +/// Try to find a specific attribute on a type definition, where the attribute accepts a bool argument. +val TryFindTyconRefBoolAttribute: TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> bool option + +/// Try to find a specific attribute on a type definition +val TyconRefHasAttribute: TcGlobals -> range -> BuiltinAttribInfo -> TyconRef -> bool + +/// Try to find the AttributeUsage attribute, looking for the value of the AllowMultiple named parameter +val TryFindAttributeUsageAttribute: TcGlobals -> range -> TyconRef -> bool option + +#if !NO_EXTENSIONTYPING +/// returns Some(assemblyName) for success +val TryDecodeTypeProviderAssemblyAttr: ILAttribute -> string option +#endif + +val IsSignatureDataVersionAttr: ILAttribute -> bool + +val TryFindAutoOpenAttr: ILAttribute -> string option + +val TryFindInternalsVisibleToAttr: ILAttribute -> string option + +val IsMatchingSignatureDataVersionAttr: ILVersionInfo -> ILAttribute -> bool + +val mkCompilationMappingAttr: TcGlobals -> int -> ILAttribute + +val mkCompilationMappingAttrWithSeqNum: TcGlobals -> int -> int -> ILAttribute + + +val mkCompilationMappingAttrWithVariantNumAndSeqNum: TcGlobals -> int -> int -> int -> ILAttribute + +val mkCompilationMappingAttrForQuotationResource: TcGlobals -> string * ILTypeRef list -> ILAttribute + +val mkCompilationArgumentCountsAttr: TcGlobals -> int list -> ILAttribute + +val mkCompilationSourceNameAttr: TcGlobals -> string -> ILAttribute + +val mkSignatureDataVersionAttr: TcGlobals -> ILVersionInfo -> ILAttribute + +val mkCompilerGeneratedAttr: TcGlobals -> int -> ILAttribute + +//------------------------------------------------------------------------- +// More common type construction +//------------------------------------------------------------------------- + +val isInByrefTy: TcGlobals -> TType -> bool + +val isOutByrefTy: TcGlobals -> TType -> bool + +val isByrefTy: TcGlobals -> TType -> bool + +val isNativePtrTy: TcGlobals -> TType -> bool + +val destByrefTy: TcGlobals -> TType -> TType + +val destNativePtrTy: TcGlobals -> TType -> TType + +val isByrefTyconRef: TcGlobals -> TyconRef -> bool + +val isByrefLikeTyconRef: TcGlobals -> range -> TyconRef -> bool + +val isSpanLikeTyconRef: TcGlobals -> range -> TyconRef -> bool + +val isByrefLikeTy: TcGlobals -> range -> TType -> bool + +/// Check if the type is a byref-like but not a byref. +val isSpanLikeTy: TcGlobals -> range -> TType -> bool + +val isSpanTy: TcGlobals -> range -> TType -> bool + +val tryDestSpanTy: TcGlobals -> range -> TType -> struct(TyconRef * TType) voption + +val destSpanTy: TcGlobals -> range -> TType -> struct(TyconRef * TType) + +val isReadOnlySpanTy: TcGlobals -> range -> TType -> bool + +val tryDestReadOnlySpanTy: TcGlobals -> range -> TType -> struct(TyconRef * TType) voption + +val destReadOnlySpanTy: TcGlobals -> range -> TType -> struct(TyconRef * TType) + +//------------------------------------------------------------------------- +// Tuple constructors/destructors +//------------------------------------------------------------------------- + +val isRefTupleExpr: Expr -> bool + +val tryDestRefTupleExpr: Expr -> Exprs + +val mkAnyTupledTy: TcGlobals -> TupInfo -> TType list -> TType + +val mkAnyTupled: TcGlobals -> range -> TupInfo -> Exprs -> TType list -> Expr + +val mkRefTupled: TcGlobals -> range -> Exprs -> TType list -> Expr + +val mkRefTupledNoTypes: TcGlobals -> range -> Exprs -> Expr + +val mkRefTupledTy: TcGlobals -> TType list -> TType + +val mkRefTupledVarsTy: TcGlobals -> Val list -> TType + +val mkRefTupledVars: TcGlobals -> range -> Val list -> Expr + +val mkMethodTy: TcGlobals -> TType list list -> TType -> TType + +val mkAnyAnonRecdTy: TcGlobals -> AnonRecdTypeInfo -> TType list -> TType + +val mkAnonRecd: TcGlobals -> range -> AnonRecdTypeInfo -> Ident[] -> Exprs -> TType list -> Expr + +val AdjustValForExpectedArity: TcGlobals -> range -> ValRef -> ValUseFlag -> ValReprInfo -> Expr * TType + +val AdjustValToTopVal: Val -> ParentRef -> ValReprInfo -> unit + +val LinearizeTopMatch: TcGlobals -> ParentRef -> Expr -> Expr + +val AdjustPossibleSubsumptionExpr: TcGlobals -> Expr -> Exprs -> (Expr * Exprs) option + +val NormalizeAndAdjustPossibleSubsumptionExprs: TcGlobals -> Expr -> Expr + +//------------------------------------------------------------------------- +// XmlDoc signatures, used by both VS mode and XML-help emit +//------------------------------------------------------------------------- + +val buildAccessPath: CompilationPath option -> string + +val XmlDocArgsEnc: TcGlobals -> Typars * Typars -> TType list -> string + +val XmlDocSigOfVal: TcGlobals -> full: bool -> string -> Val -> string + +val XmlDocSigOfUnionCase: (string list -> string) + +val XmlDocSigOfField: (string list -> string) + +val XmlDocSigOfProperty: (string list -> string) + +val XmlDocSigOfTycon: (string list -> string) + +val XmlDocSigOfSubModul: (string list -> string) + +val XmlDocSigOfEntity: EntityRef -> string + +//--------------------------------------------------------------------------- +// Resolve static optimizations +//------------------------------------------------------------------------- + +type StaticOptimizationAnswer = + | Yes = 1y + | No = -1y + | Unknown = 0y + +val DecideStaticOptimizations: TcGlobals -> StaticOptimization list -> haveWitnesses: bool -> StaticOptimizationAnswer + +val mkStaticOptimizationExpr: TcGlobals -> StaticOptimization list * Expr * Expr * range -> Expr + +/// Build for loops +val mkFastForLoop: TcGlobals -> DebugPointAtFor * range * Val * Expr * bool * Expr * Expr -> Expr + +//--------------------------------------------------------------------------- +// Active pattern helpers +//------------------------------------------------------------------------- + +type ActivePatternElemRef with + member Name: string + +val TryGetActivePatternInfo: ValRef -> PrettyNaming.ActivePatternInfo option + +val mkChoiceCaseRef: g: TcGlobals -> m: range -> n: int -> i: int -> UnionCaseRef + +type PrettyNaming.ActivePatternInfo with + + member Names: string list + + member ResultType: g: TcGlobals -> range -> TType list -> bool -> TType + + member OverallType: g: TcGlobals -> m: range -> dty: TType -> rtys: TType list -> isStruct: bool -> TType + +val doesActivePatternHaveFreeTypars: TcGlobals -> ValRef -> bool + +//--------------------------------------------------------------------------- +// Structural rewrites +//------------------------------------------------------------------------- + +[] +type ExprRewritingEnv = + { PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option + PostTransform: Expr -> Expr option + PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option + IsUnderQuotations: bool } + +val RewriteDecisionTree: ExprRewritingEnv -> DecisionTree -> DecisionTree + +val RewriteExpr: ExprRewritingEnv -> Expr -> Expr + +val RewriteImplFile: ExprRewritingEnv -> TypedImplFile -> TypedImplFile + +val IsGenericValWithGenericConstraints: TcGlobals -> Val -> bool + +type Entity with + + member HasInterface: TcGlobals -> TType -> bool + + member HasOverride: TcGlobals -> string -> TType list -> bool + + member HasMember: TcGlobals -> string -> TType list -> bool + +type EntityRef with + + member HasInterface: TcGlobals -> TType -> bool + + member HasOverride: TcGlobals -> string -> TType list -> bool + + member HasMember: TcGlobals -> string -> TType list -> bool + +val (|AttribBitwiseOrExpr|_|): TcGlobals -> Expr -> (Expr * Expr) option + +val (|EnumExpr|_|): TcGlobals -> Expr -> Expr option + +val (|TypeOfExpr|_|): TcGlobals -> Expr -> TType option + +val (|TypeDefOfExpr|_|): TcGlobals -> Expr -> TType option + +val isNameOfValRef: TcGlobals -> ValRef -> bool + +val (|NameOfExpr|_|): TcGlobals -> Expr -> TType option + +val (|SeqExpr|_|): TcGlobals -> Expr -> unit option + +val EvalLiteralExprOrAttribArg: TcGlobals -> Expr -> Expr + +val EvaledAttribExprEquality: TcGlobals -> Expr -> Expr -> bool + +val IsSimpleSyntacticConstantExpr: TcGlobals -> Expr -> bool + +val (|ConstToILFieldInit|_|): Const -> ILFieldInit option + +val (|ExtractAttribNamedArg|_|): string -> AttribNamedArg list -> AttribExpr option + +val (|AttribInt32Arg|_|): AttribExpr -> int32 option + +val (|AttribInt16Arg|_|): AttribExpr -> int16 option + +val (|AttribBoolArg|_|): AttribExpr -> bool option + +val (|AttribStringArg|_|): AttribExpr -> string option + +val (|Int32Expr|_|): Expr -> int32 option + +/// Determines types that are potentially known to satisfy the 'comparable' constraint and returns +/// a set of residual types that must also satisfy the constraint +val (|SpecialComparableHeadType|_|): TcGlobals -> TType -> TType list option + +val (|SpecialEquatableHeadType|_|): TcGlobals -> TType -> TType list option + +val (|SpecialNotEquatableHeadType|_|): TcGlobals -> TType -> unit option + +type OptimizeForExpressionOptions = OptimizeIntRangesOnly | OptimizeAllForExpressions + +val DetectAndOptimizeForExpression: TcGlobals -> OptimizeForExpressionOptions -> Expr -> Expr + +val TryEliminateDesugaredConstants: TcGlobals -> range -> Const -> Expr option + +val MemberIsExplicitImpl: TcGlobals -> ValMemberInfo -> bool + +val ValIsExplicitImpl: TcGlobals -> Val -> bool + +val ValRefIsExplicitImpl: TcGlobals -> ValRef -> bool + +val (|LinearMatchExpr|_|): Expr -> (DebugPointAtBinding * range * DecisionTree * DecisionTreeTarget * Expr * DebugPointAtTarget * range * TType) option + +val rebuildLinearMatchExpr: DebugPointAtBinding * range * DecisionTree * DecisionTreeTarget * Expr * DebugPointAtTarget * range * TType -> Expr + +val (|LinearOpExpr|_|): Expr -> (TOp * TypeInst * Expr list * Expr * range) option + +val rebuildLinearOpExpr: TOp * TypeInst * Expr list * Expr * range -> Expr + +val mkCoerceIfNeeded: TcGlobals -> tgtTy: TType -> srcTy: TType -> Expr -> Expr + +val (|InnerExprPat|): Expr -> Expr + +val allValsOfModDef: ModuleOrNamespaceExpr -> seq + +val BindUnitVars: TcGlobals -> Val list * ArgReprInfo list * Expr -> Val list * Expr + +val isThreadOrContextStatic: TcGlobals -> Attrib list -> bool + +val mkUnitDelayLambda: TcGlobals -> range -> Expr -> Expr + +val GenWitnessArgTys: TcGlobals -> TraitWitnessInfo -> TType list list + +val GenWitnessTys: TcGlobals -> TraitWitnessInfos -> TType list + +val GenWitnessTy: TcGlobals -> TraitWitnessInfo -> TType + +val GetTraitConstraintInfosOfTypars: TcGlobals -> Typars -> TraitConstraintInfo list + +val GetTraitWitnessInfosOfTypars: TcGlobals -> numParentTypars: int -> typars: Typars -> TraitWitnessInfos + +/// An immutable mappping from witnesses to some data. +/// +/// Note: this uses an immutable HashMap/Dictionary with an IEqualityComparer that captures TcGlobals, see EmptyTraitWitnessInfoHashMap +type TraitWitnessInfoHashMap<'T> = ImmutableDictionary + +/// Create an empty immutable mapping from witnesses to some data +val EmptyTraitWitnessInfoHashMap: TcGlobals -> TraitWitnessInfoHashMap<'T> + +/// Match expressions that are an application of a particular F# function value +val (|ValApp|_|): TcGlobals -> ValRef -> Expr -> (TypeInst * Exprs * range) option + +/// Match expressions that represent the creation of an instance of an F# delegate value +val (|NewDelegateExpr|_|): TcGlobals -> Expr -> (Unique * Val list list * Expr * range * (Expr -> Expr)) option + +/// Match a .Invoke on a delegate +val (|DelegateInvokeExpr|_|): TcGlobals -> Expr -> (Expr * TType * TypeInst * Expr * Exprs * range) option + +/// Match 'if __useResumableCode then ... else ...' expressions +val (|IfUseResumableStateMachinesExpr|_|) : TcGlobals -> Expr -> (Expr * Expr) option + +val CombineCcuContentFragments: range -> ModuleOrNamespaceType list -> ModuleOrNamespaceType + +/// Recognise a 'match __resumableEntry() with ...' expression +val (|ResumableEntryMatchExpr|_|): g: TcGlobals -> Expr -> (Expr * Val * Expr * (Expr * Expr -> Expr)) option + +/// Recognise a '__stateMachine' expression +val (|StructStateMachineExpr|_|): + g: TcGlobals -> + expr: Expr -> + (TType * (Val * Expr) * (Val * Val * Expr) * (Val * Expr)) option + +/// Recognise a sequential or binding construct in a resumable code +val (|SequentialResumableCode|_|): g: TcGlobals -> Expr -> (Expr * Expr * range * (Expr -> Expr -> Expr)) option + +/// Recognise a '__resumeAt' expression +val (|ResumeAtExpr|_|): g: TcGlobals -> Expr -> Expr option + +/// Recognise a while expression +val (|WhileExpr|_|): Expr -> (DebugPointAtWhile * SpecialWhileLoopMarker * Expr * Expr * range) option + +/// Recognise a for-loop expression +val (|ForLoopExpr|_|): Expr -> (DebugPointAtFor * ForLoopStyle * Expr * Expr * Val * Expr * range) option + +/// Recognise a try-with expression +val (|TryWithExpr|_|): Expr -> (DebugPointAtTry * DebugPointAtWith * TType * Expr * Val * Expr * Val * Expr * range) option + +/// Recognise a try-finally expression +val (|TryFinallyExpr|_|): Expr -> (DebugPointAtTry * DebugPointAtFinally * TType * Expr * Expr * range) option + +/// Add a label to use as the target for a goto +val mkLabelled: range -> ILCodeLabel -> Expr -> Expr + +/// Any delegate type with ResumableCode attribute, or any function returning such a delegate type +val isResumableCodeTy: TcGlobals -> TType -> bool + +/// The delegate type ResumableCode, or any function returning this a delegate type +val isReturnsResumableCodeTy: TcGlobals -> TType -> bool + +/// Shared helper for binding attributes +val TryBindTyconRefAttribute: + g:TcGlobals -> + m:range -> + BuiltinAttribInfo -> + tcref:TyconRef -> + f1:(ILAttribElem list * ILAttributeNamedArg list -> 'a option) -> + f2:(Attrib -> 'a option) -> + f3:(obj option list * (string * obj option) list -> 'a option) + -> 'a option + +val (|ResumableCodeInvoke|_|): + g:TcGlobals -> + expr: Expr -> + (Expr * Expr * Expr list * range * (Expr * Expr list -> Expr)) option + +val (|OpPipeRight|_|): + g:TcGlobals -> + expr: Expr -> + (TType * Expr * Expr * range) option + +val (|OpPipeRight2|_|): + g:TcGlobals -> + expr: Expr -> + (TType * Expr * Expr * Expr * range) option + +val (|OpPipeRight3|_|): + g:TcGlobals -> + expr: Expr -> + (TType * Expr * Expr * Expr * Expr * range) option + +/// This uses 'expr thendo ()' with a note that there should be a debug point on the 'expr' +val mkDebugPoint: g: TcGlobals -> m: range -> expr: Expr -> Expr diff --git a/src/fsharp/TypedTreePickle.fs b/src/fsharp/TypedTreePickle.fs new file mode 100644 index 00000000000..d8f9b0342b6 --- /dev/null +++ b/src/fsharp/TypedTreePickle.fs @@ -0,0 +1,2728 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.TypedTreePickle + +open System.Collections.Generic +open System.Text + +open FSharp.Compiler.IO +open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Library.Extras.Bits +open Internal.Utilities.Rational + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals + +let verbose = false + +let ffailwith fileName str = + let msg = FSComp.SR.pickleErrorReadingWritingMetadata(fileName, str) + System.Diagnostics.Debug.Assert(false, msg) + failwith msg + +// Fixup pickled data w.r.t. a set of CCU thunks indexed by name +[] +type PickledDataWithReferences<'rawData> = + { /// The data that uses a collection of CcuThunks internally + RawData: 'rawData + /// The assumptions that need to be fixed up + FixupThunks: CcuThunk [] } + + member x.Fixup loader = + x.FixupThunks |> Array.iter (fun reqd -> reqd.Fixup(loader reqd.AssemblyName)) + x.RawData + + /// Like Fixup but loader may return None, in which case there is no fixup. + member x.OptionalFixup loader = + x.FixupThunks + |> Array.iter(fun reqd-> + // Only fixup what needs fixing up + if reqd.IsUnresolvedReference then + match loader reqd.AssemblyName with + | Some loaded -> + if reqd.IsUnresolvedReference then reqd.Fixup loaded + | _ -> () ) + x.RawData + +//--------------------------------------------------------------------------- +// Basic pickle/unpickle state +//--------------------------------------------------------------------------- + +[] +type Table<'T> = + { name: string + tbl: Dictionary<'T, int> + mutable rows: ResizeArray<'T> + mutable count: int } + member tbl.AsArray = Seq.toArray tbl.rows + member tbl.Size = tbl.rows.Count + member tbl.Add x = + let n = tbl.count + tbl.count <- tbl.count + 1 + tbl.tbl.[x] <- n + tbl.rows.Add x + n + member tbl.FindOrAdd x = + match tbl.tbl.TryGetValue x with + | true, res -> res + | _ -> tbl.Add x + + + static member Create n = + { name = n + tbl = Dictionary<_, _>(1000, HashIdentity.Structural) + rows= ResizeArray<_>(1000) + count=0 } + +[] +type InputTable<'T> = + { itbl_name: string + itbl_rows: 'T array } + +let new_itbl n r = { itbl_name=n; itbl_rows=r } + +[] +type NodeOutTable<'Data, 'Node> = + { NodeStamp : 'Node -> Stamp + NodeName : 'Node -> string + GetRange : 'Node -> range + Deref: 'Node -> 'Data + Name: string + Table: Table } + member x.Size = x.Table.Size + + // inline this to get known-type-information through to the HashMultiMap constructor + static member inline Create (stampF, nameF, rangeF, derefF, nm) = + { NodeStamp = stampF + NodeName = nameF + GetRange = rangeF + Deref = derefF + Name = nm + Table = Table<_>.Create nm } + +[] +type WriterState = + { os: ByteBuffer + oscope: CcuThunk + occus: Table + oentities: NodeOutTable + otypars: NodeOutTable + ovals: NodeOutTable + oanoninfos: NodeOutTable + ostrings: Table + opubpaths: Table + onlerefs: Table + osimpletys: Table + oglobals : TcGlobals + mutable isStructThisArgPos : bool + ofile : string + /// Indicates if we are using in-memory format, where we store XML docs as well + oInMem : bool + } +let pfailwith st str = ffailwith st.ofile str + +[] +type NodeInTable<'Data, 'Node> = + { LinkNode : 'Node -> 'Data -> unit + IsLinked : 'Node -> bool + Name : string + Nodes : 'Node[] } + member x.Get n = x.Nodes.[n] + member x.Count = x.Nodes.Length + + static member Create (mkEmpty, lnk, isLinked, nm, n) = + { LinkNode = lnk; IsLinked = isLinked; Name = nm; Nodes = Array.init n (fun _i -> mkEmpty() ) } + +[] +type ReaderState = + { is: ByteStream + iilscope: ILScopeRef + iccus: InputTable + ientities: NodeInTable + itypars: NodeInTable + ivals: NodeInTable + ianoninfos: NodeInTable + istrings: InputTable + ipubpaths: InputTable + inlerefs: InputTable + isimpletys: InputTable + ifile: string + iILModule : ILModuleDef option // the Abstract IL metadata for the DLL being read + } + +let ufailwith st str = ffailwith st.ifile str + +//--------------------------------------------------------------------------- +// Basic pickle/unpickle operations +//--------------------------------------------------------------------------- + +type 'T pickler = 'T -> WriterState -> unit + +let p_byte b st = st.os.EmitIntAsByte b + +let p_bool b st = p_byte (if b then 1 else 0) st + +let prim_p_int32 i st = + p_byte (b0 i) st + p_byte (b1 i) st + p_byte (b2 i) st + p_byte (b3 i) st + +/// Compress integers according to the same scheme used by CLR metadata +/// This halves the size of pickled data +let p_int32 n st = + if n >= 0 && n <= 0x7F then + p_byte (b0 n) st + else if n >= 0x80 && n <= 0x3FFF then + p_byte (0x80 ||| (n >>> 8)) st + p_byte (n &&& 0xFF) st + else + p_byte 0xFF st + prim_p_int32 n st + +let space = () +let p_space n () st = + for i = 0 to n - 1 do + p_byte 0 st + +/// Represents space that was reserved but is now possibly used +let p_used_space1 f st = + p_byte 1 st + f st + // leave more space + p_space 1 space st + +let p_bytes (s: byte[]) st = + let len = s.Length + p_int32 len st + st.os.EmitBytes s + +let p_memory (s: System.ReadOnlyMemory) st = + let len = s.Length + p_int32 len st + st.os.EmitMemory s + +let p_prim_string (s: string) st = + let bytes = Encoding.UTF8.GetBytes s + let len = bytes.Length + p_int32 len st + st.os.EmitBytes bytes + +let p_int c st = p_int32 c st +let p_int8 (i: sbyte) st = p_int32 (int32 i) st +let p_uint8 (i: byte) st = p_byte (int i) st +let p_int16 (i: int16) st = p_int32 (int32 i) st +let p_uint16 (x: uint16) st = p_int32 (int32 x) st +let p_uint32 (x: uint32) st = p_int32 (int32 x) st +let p_int64 (i: int64) st = + p_int32 (int32 (i &&& 0xFFFFFFFFL)) st + p_int32 (int32 (i >>> 32)) st + +let p_uint64 (x: uint64) st = p_int64 (int64 x) st + +let bits_of_float32 (x: float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes x, 0) +let bits_of_float (x: float) = System.BitConverter.DoubleToInt64Bits x + +let p_single i st = p_int32 (bits_of_float32 i) st +let p_double i st = p_int64 (bits_of_float i) st +let p_ieee64 i st = p_int64 (bits_of_float i) st +let p_char i st = p_uint16 (uint16 (int32 i)) st + +let inline p_tup2 p1 p2 (a, b) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit) + +let inline p_tup3 p1 p2 p3 (a, b, c) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit) + +let inline p_tup4 p1 p2 p3 p4 (a, b, c, d) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit) + +let inline p_tup5 p1 p2 p3 p4 p5 (a, b, c, d, e) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit) + +let inline p_tup6 p1 p2 p3 p4 p5 p6 (a, b, c, d, e, f) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit) + +let inline p_tup7 p1 p2 p3 p4 p5 p6 p7 (a, b, c, d, e, f, x7) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit) + +let inline p_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (a, b, c, d, e, f, x7, x8) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit) + +let inline p_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (a, b, c, d, e, f, x7, x8, x9) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit) + +let inline p_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (a, b, c, d, e, f, x7, x8, x9, x10) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit); (p10 x10 st : unit) + +let inline p_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (a, b, c, d, e, f, x7, x8, x9, x10, x11) (st: WriterState) = + (p1 a st : unit); (p2 b st : unit); (p3 c st : unit); (p4 d st : unit); (p5 e st : unit); (p6 f st : unit); (p7 x7 st : unit); (p8 x8 st : unit); (p9 x9 st : unit); (p10 x10 st : unit); (p11 x11 st : unit) + +let u_byte st = int (st.is.ReadByte()) + +type unpickler<'T> = ReaderState -> 'T + +let u_bool st = let b = u_byte st in (b = 1) + + + +let prim_u_int32 st = + let b0 = (u_byte st) + let b1 = (u_byte st) + let b2 = (u_byte st) + let b3 = (u_byte st) + b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24) + +let u_int32 st = + let b0 = u_byte st + if b0 <= 0x7F then b0 + else if b0 <= 0xbf then + let b0 = b0 &&& 0x7F + let b1 = (u_byte st) + (b0 <<< 8) ||| b1 + else + assert(b0 = 0xFF) + prim_u_int32 st + +let u_byte_memory st = + let n = (u_int32 st) + st.is.ReadBytes n + +let u_bytes st = + (u_byte_memory st).ToArray() + +let u_prim_string st = + let len = (u_int32 st) + st.is.ReadUtf8String len + +let u_int st = u_int32 st +let u_int8 st = sbyte (u_int32 st) +let u_uint8 st = byte (u_byte st) +let u_int16 st = int16 (u_int32 st) +let u_uint16 st = uint16 (u_int32 st) +let u_uint32 st = uint32 (u_int32 st) +let u_int64 st = + let b1 = (int64 (u_int32 st)) &&& 0xFFFFFFFFL + let b2 = int64 (u_int32 st) + b1 ||| (b2 <<< 32) + +let u_uint64 st = uint64 (u_int64 st) +let float32_of_bits (x: int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes x, 0) +let float_of_bits (x: int64) = System.BitConverter.Int64BitsToDouble x + +let u_single st = float32_of_bits (u_int32 st) +let u_double st = float_of_bits (u_int64 st) + +let u_ieee64 st = float_of_bits (u_int64 st) + +let u_char st = char (int32 (u_uint16 st)) +let u_space n st = + for i = 0 to n - 1 do + let b = u_byte st + if b <> 0 then + warning(Error(FSComp.SR.pickleUnexpectedNonZero st.ifile, range0)) + +/// Represents space that was reserved but is now possibly used +let u_used_space1 f st = + let b = u_byte st + match b with + | 0 -> None + | 1 -> + let x = f st + u_space 1 st + Some x + | _ -> + warning(Error(FSComp.SR.pickleUnexpectedNonZero st.ifile, range0)); None + + +let inline u_tup2 p1 p2 (st: ReaderState) = let a = p1 st in let b = p2 st in (a, b) + +let inline u_tup3 p1 p2 p3 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in (a, b, c) + +let inline u_tup4 p1 p2 p3 p4 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in (a, b, c, d) + +let inline u_tup5 p1 p2 p3 p4 p5 (st: ReaderState) = + let a = p1 st + let b = p2 st + let c = p3 st + let d = p4 st + let e = p5 st + (a, b, c, d, e) + +let inline u_tup6 p1 p2 p3 p4 p5 p6 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in (a, b, c, d, e, f) + +let inline u_tup7 p1 p2 p3 p4 p5 p6 p7 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in (a, b, c, d, e, f, x7) + +let inline u_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in (a, b, c, d, e, f, x7, x8) + +let inline u_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in (a, b, c, d, e, f, x7, x8, x9) + +let inline u_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in (a, b, c, d, e, f, x7, x8, x9, x10) + +let inline u_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in (a, b, c, d, e, f, x7, x8, x9, x10, x11) + +let inline u_tup12 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12) + +let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13) + +let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + let x14 = p14 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14) +let inline u_tup15 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + let x14 = p14 st in let x15 = p15 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15) + +let inline u_tup16 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) + +let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (st: ReaderState) = + let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in + let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in + let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in + let x14 = p14 st in let x15 = p15 st in let x16 = p16 st in let x17 = p17 st in + (a, b, c, d, e, f, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) + + +//--------------------------------------------------------------------------- +// Pickle/unpickle operations for observably shared graph nodes +//--------------------------------------------------------------------------- + +// exception Nope + +// ctxt is for debugging +let p_osgn_ref (_ctxt: string) (outMap : NodeOutTable<_, _>) x st = + let idx = outMap.Table.FindOrAdd (outMap.NodeStamp x) + //if ((idx = 0) && outMap.Name = "oentities") then + // let msg = + // sprintf "idx %d#%d in table %s has name '%s', was defined at '%s' and is referenced from context %s\n" + // idx (outMap.NodeStamp x) + // outMap.Name (outMap.NodeName x) + // (stringOfRange (outMap.GetRange x)) + // _ctxt + // System.Diagnostics.Debug.Assert(false, msg ) + p_int idx st + +let p_osgn_decl (outMap : NodeOutTable<_, _>) p x st = + let stamp = outMap.NodeStamp x + let idx = outMap.Table.FindOrAdd stamp + //dprintf "decl %d#%d in table %s has name %s\n" idx (outMap.NodeStamp x) outMap.Name (outMap.NodeName x) + p_tup2 p_int p (idx, outMap.Deref x) st + +let u_osgn_ref (inMap: NodeInTable<_, _>) st = + let n = u_int st + if n < 0 || n >= inMap.Count then ufailwith st ("u_osgn_ref: out of range, table = "+inMap.Name+", n = "+string n) + inMap.Get n + +let u_osgn_decl (inMap: NodeInTable<_, _>) u st = + let idx, data = u_tup2 u_int u st + // dprintf "unpickling osgn %d in table %s\n" idx nm + let res = inMap.Get idx + inMap.LinkNode res data + res + +//--------------------------------------------------------------------------- +// Pickle/unpickle operations for interned nodes +//--------------------------------------------------------------------------- + +let encode_uniq (tbl: Table<_>) key = tbl.FindOrAdd key +let lookup_uniq st tbl n = + let arr = tbl.itbl_rows + if n < 0 || n >= arr.Length then ufailwith st ("lookup_uniq in table "+tbl.itbl_name+" out of range, n = "+string n+ ", sizeof(tab) = " + string (Array.length arr)) + arr.[n] + +//--------------------------------------------------------------------------- +// Pickle/unpickle arrays and lists. For lists use the same binary format as arrays so we can switch +// between internal representations relatively easily +//------------------------------------------------------------------------- + +let p_array_core f (x: 'T[]) st = + for i = 0 to x.Length-1 do + f x.[i] st + +let p_array f (x: 'T[]) st = + p_int x.Length st + p_array_core f x st + +// Optionally encode an extra item using a marker bit. +// When extraf is None, the marker bit is not set, and this is identical to p_array. +let p_array_ext extraf f (x: 'T[]) st = + let n = x.Length + let n = if Option.isSome extraf then n ||| 0x80000000 else n + p_int n st + match extraf with + | None -> () + | Some f -> f st + p_array_core f x st + +let p_list_core f (xs: 'T list) st = + for x in xs do + f x st + +let p_list f x st = + p_int (List.length x) st + p_list_core f x st +let p_list_ext extraf f x st = + let n = List.length x + let n = if Option.isSome extraf then n ||| 0x80000000 else n + p_int n st + match extraf with + | None -> () + | Some f -> f st + p_list_core f x st + +let p_List f (x: 'T list) st = p_list f x st + +let p_wrap (f: 'T -> 'U) (p : 'U pickler) : 'T pickler = (fun x st -> p (f x) st) +let p_option f x st = + match x with + | None -> p_byte 0 st + | Some h -> p_byte 1 st; f h st + +// Pickle lazy values in such a way that they can, in some future F# compiler version, be read back +// lazily. However, a lazy reader is not used in this version because the value may contain the definitions of some +// OSGN nodes. +let private p_lazy_impl p v st = + let fixupPos1 = st.os.Position + // We fix these up after + prim_p_int32 0 st + let fixupPos2 = st.os.Position + prim_p_int32 0 st + let fixupPos3 = st.os.Position + prim_p_int32 0 st + let fixupPos4 = st.os.Position + prim_p_int32 0 st + let fixupPos5 = st.os.Position + prim_p_int32 0 st + let fixupPos6 = st.os.Position + prim_p_int32 0 st + let fixupPos7 = st.os.Position + prim_p_int32 0 st + let idx1 = st.os.Position + let otyconsIdx1 = st.oentities.Size + let otyparsIdx1 = st.otypars.Size + let ovalsIdx1 = st.ovals.Size + // Run the pickler + p v st + // Determine and fixup the length of the pickled data + let idx2 = st.os.Position + st.os.FixupInt32 fixupPos1 (idx2-idx1) + // Determine and fixup the ranges of OSGN nodes defined within the lazy portion + let otyconsIdx2 = st.oentities.Size + let otyparsIdx2 = st.otypars.Size + let ovalsIdx2 = st.ovals.Size + st.os.FixupInt32 fixupPos2 otyconsIdx1 + st.os.FixupInt32 fixupPos3 otyconsIdx2 + st.os.FixupInt32 fixupPos4 otyparsIdx1 + st.os.FixupInt32 fixupPos5 otyparsIdx2 + st.os.FixupInt32 fixupPos6 ovalsIdx1 + st.os.FixupInt32 fixupPos7 ovalsIdx2 + +let p_lazy p x st = + p_lazy_impl p (Lazy.force x) st + +let p_maybe_lazy p (x: MaybeLazy<_>) st = + p_lazy_impl p x.Value st + +let p_hole () = + let mutable h = None + (fun f -> h <- Some f), (fun x st -> match h with Some f -> f x st | None -> pfailwith st "p_hole: unfilled hole") + +let p_hole2 () = + let mutable h = None + (fun f -> h <- Some f), (fun arg x st -> match h with Some f -> f arg x st | None -> pfailwith st "p_hole2: unfilled hole") + +let u_array_core f n st = + let res = Array.zeroCreate n + for i = 0 to n-1 do + res.[i] <- f st + res + +let u_array f st = + let n = u_int st + u_array_core f n st + +// Optionally decode an extra item if a marker bit is present. +// When the marker bit is not set this is identical to u_array, and extraf is not called +let u_array_ext extraf f st = + let n = u_int st + let extraItem = + if n &&& 0x80000000 = 0x80000000 then + Some (extraf st) + else + None + let arr = u_array_core f (n &&& 0x7FFFFFFF) st + extraItem, arr + +let u_list_core f n st = + List.init n (fun _ -> f st) + +let u_list f st = + let n = u_int st + u_list_core f n st +let u_list_ext extra f st = + let n = u_int st + let extraItem = + if n &&& 0x80000000 = 0x80000000 then + Some (extra st) + else + None + let list = u_list_core f (n &&& 0x7FFFFFFF) st + extraItem, list + +#if FLAT_LIST_AS_LIST +#else +let u_List f st = u_list f st // new List<_> (u_array f st) +#endif +#if FLAT_LIST_AS_ARRAY_STRUCT +//#else +let u_List f st = List(u_array f st) +#endif +#if FLAT_LIST_AS_ARRAY +//#else +let u_List f st = u_array f st +#endif + +let u_array_revi f st = + let n = u_int st + let res = Array.zeroCreate n + for i = 0 to n-1 do + res.[i] <- f st (n-1-i) + res + +// Mark up default constraints with a priority in reverse order: last gets 0 etc. See comment on TyparConstraint.DefaultsTo +let u_list_revi f st = + let n = u_int st + [ for i = 0 to n-1 do + yield f st (n-1-i) ] + + +let u_wrap (f: 'U -> 'T) (u : 'U unpickler) : 'T unpickler = (fun st -> f (u st)) + +let u_option f st = + let tag = u_byte st + match tag with + | 0 -> None + | 1 -> Some (f st) + | n -> ufailwith st ("u_option: found number " + string n) + +// Boobytrap an OSGN node with a force of a lazy load of a bunch of pickled data +#if LAZY_UNPICKLE +let wire (x: osgn<_>) (res: Lazy<_>) = + x.osgnTripWire <- Some(fun () -> res.Force() |> ignore) +#endif + +let u_lazy u st = + + // Read the number of bytes in the record + let len = prim_u_int32 st // fixupPos1 + // These are the ranges of OSGN nodes defined within the lazily read portion of the graph + let otyconsIdx1 = prim_u_int32 st // fixupPos2 + let otyconsIdx2 = prim_u_int32 st // fixupPos3 + let otyparsIdx1 = prim_u_int32 st // fixupPos4 + let otyparsIdx2 = prim_u_int32 st // fixupPos5 + let ovalsIdx1 = prim_u_int32 st // fixupPos6 + let ovalsIdx2 = prim_u_int32 st // fixupPos7 + +#if LAZY_UNPICKLE + // Record the position in the bytestream to use when forcing the read of the data + let idx1 = st.is.Position + // Skip the length of data + st.is.Skip len + // This is the lazy computation that wil force the unpickling of the term. + // This term must contain OSGN definitions of the given nodes. + let res = + lazy (let st = { st with is = st.is.CloneAndSeek idx1 } + u st) + /// Force the reading of the data as a "tripwire" for each of the OSGN thunks + for i = otyconsIdx1 to otyconsIdx2-1 do wire (st.ientities.Get i) res done + for i = ovalsIdx1 to ovalsIdx2-1 do wire (st.ivals.Get i) res done + for i = otyparsIdx1 to otyparsIdx2-1 do wire (st.itypars.Get i) res done + res +#else + ignore (len, otyconsIdx1, otyconsIdx2, otyparsIdx1, otyparsIdx2, ovalsIdx1, ovalsIdx2) + Lazy.CreateFromValue(u st) +#endif + + +let u_hole () = + let mutable h = None + (fun f -> h <- Some f), (fun st -> match h with Some f -> f st | None -> ufailwith st "u_hole: unfilled hole") + +//--------------------------------------------------------------------------- +// Pickle/unpickle F# interface data +//--------------------------------------------------------------------------- + +// Strings +// A huge number of these occur in pickled F# data, so make them unique +let encode_string stringTab x = encode_uniq stringTab x +let decode_string x = x +let lookup_string st stringTab x = lookup_uniq st stringTab x +let u_encoded_string = u_prim_string +let u_string st = lookup_uniq st st.istrings (u_int st) +let u_strings = u_list u_string +let u_ints = u_list u_int + + +let p_encoded_string = p_prim_string +let p_string s st = p_int (encode_string st.ostrings s) st +let p_strings = p_list p_string +let p_ints = p_list p_int + +// CCU References +// A huge number of these occur in pickled F# data, so make them unique +let encode_ccuref ccuTab (x: CcuThunk) = encode_uniq ccuTab x.AssemblyName +let decode_ccuref x = x +let lookup_ccuref st ccuTab x = lookup_uniq st ccuTab x +let u_encoded_ccuref st = + match u_byte st with + | 0 -> u_prim_string st + | n -> ufailwith st ("u_encoded_ccuref: found number " + string n) +let u_ccuref st = lookup_uniq st st.iccus (u_int st) + +let p_encoded_ccuref x st = + p_byte 0 st // leave a dummy tag to make room for future encodings of ccurefs + p_prim_string x st + +let p_ccuref s st = p_int (encode_ccuref st.occus s) st + +// References to public items in this module +// A huge number of these occur in pickled F# data, so make them unique +let decode_pubpath st stringTab a = PubPath(Array.map (lookup_string st stringTab) a) +let lookup_pubpath st pubpathTab x = lookup_uniq st pubpathTab x +let u_encoded_pubpath = u_array u_int +let u_pubpath st = lookup_uniq st st.ipubpaths (u_int st) + +let encode_pubpath stringTab pubpathTab (PubPath a) = encode_uniq pubpathTab (Array.map (encode_string stringTab) a) +let p_encoded_pubpath = p_array p_int +let p_pubpath x st = p_int (encode_pubpath st.ostrings st.opubpaths x) st + +// References to other modules +// A huge number of these occur in pickled F# data, so make them unique +let decode_nleref st ccuTab stringTab (a, b) = mkNonLocalEntityRef (lookup_ccuref st ccuTab a) (Array.map (lookup_string st stringTab) b) +let lookup_nleref st nlerefTab x = lookup_uniq st nlerefTab x +let u_encoded_nleref = u_tup2 u_int (u_array u_int) +let u_nleref st = lookup_uniq st st.inlerefs (u_int st) + +let encode_nleref ccuTab stringTab nlerefTab thisCcu (nleref: NonLocalEntityRef) = +#if !NO_EXTENSIONTYPING + // Remap references to statically-linked Entity nodes in provider-generated entities to point to the current assembly. + // References to these nodes _do_ appear in F# assembly metadata, because they may be public. + let nleref = + match nleref.Deref.PublicPath with + | Some pubpath when nleref.Deref.IsProvidedGeneratedTycon -> + if verbose then dprintfn "remapping pickled reference to provider-generated type %s" nleref.Deref.DisplayNameWithStaticParameters + rescopePubPath thisCcu pubpath + | _ -> nleref +#else + ignore thisCcu +#endif + + let (NonLocalEntityRef(a, b)) = nleref + encode_uniq nlerefTab (encode_ccuref ccuTab a, Array.map (encode_string stringTab) b) +let p_encoded_nleref = p_tup2 p_int (p_array p_int) +let p_nleref x st = p_int (encode_nleref st.occus st.ostrings st.onlerefs st.oscope x) st + +// Simple types are types like "int", represented as TType(Ref_nonlocal(..., "int"), []). +// A huge number of these occur in pickled F# data, so make them unique. +let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERefNonLocal (lookup_nleref st nlerefTab a), []) +let lookup_simpletyp st simpleTyTab x = lookup_uniq st simpleTyTab x +let u_encoded_simpletyp st = u_int st +let u_encoded_anoninfo st = u_int st +let u_simpletyp st = lookup_uniq st st.isimpletys (u_int st) +let encode_simpletyp ccuTab stringTab nlerefTab simpleTyTab thisCcu a = encode_uniq simpleTyTab (encode_nleref ccuTab stringTab nlerefTab thisCcu a) +let p_encoded_simpletyp x st = p_int x st +let p_encoded_anoninfo x st = p_int x st +let p_simpletyp x st = p_int (encode_simpletyp st.occus st.ostrings st.onlerefs st.osimpletys st.oscope x) st + +/// Arbitrary value +[] +let PickleBufferCapacity = 100000 + +let pickleObjWithDanglingCcus inMem file g scope p x = + let st1 = + { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + oscope=scope + occus= Table<_>.Create "occus" + oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), id , "otycons") + otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), id , "otypars") + ovals=NodeOutTable<_, _>.Create((fun (v: Val) -> v.Stamp), (fun v -> v.LogicalName), (fun v -> v.Range), id , "ovals") + oanoninfos=NodeOutTable<_, _>.Create((fun (v: AnonRecdTypeInfo) -> v.Stamp), (fun v -> string v.Stamp), (fun _ -> range0), id, "oanoninfos") + ostrings=Table<_>.Create "ostrings" + onlerefs=Table<_>.Create "onlerefs" + opubpaths=Table<_>.Create "opubpaths" + osimpletys=Table<_>.Create "osimpletys" + oglobals=g + ofile=file + oInMem=inMem + isStructThisArgPos = false} + let ccuNameTab, (ntycons, ntypars, nvals, nanoninfos), stringTab, pubpathTab, nlerefTab, simpleTyTab, phase1bytes = + p x st1 + let sizes = + st1.oentities.Size, + st1.otypars.Size, + st1.ovals.Size, + st1.oanoninfos.Size + st1.occus, sizes, st1.ostrings, st1.opubpaths, st1.onlerefs, st1.osimpletys, st1.os.AsMemory() + + let st2 = + { os = ByteBuffer.Create(PickleBufferCapacity, useArrayPool = true) + oscope=scope + occus= Table<_>.Create "occus (fake)" + oentities=NodeOutTable<_, _>.Create((fun (tc: Tycon) -> tc.Stamp), (fun tc -> tc.LogicalName), (fun tc -> tc.Range), id , "otycons") + otypars=NodeOutTable<_, _>.Create((fun (tp: Typar) -> tp.Stamp), (fun tp -> tp.DisplayName), (fun tp -> tp.Range), id , "otypars") + ovals=NodeOutTable<_, _>.Create((fun (v: Val) -> v.Stamp), (fun v -> v.LogicalName), (fun v -> v.Range), (fun osgn -> osgn), "ovals") + oanoninfos=NodeOutTable<_, _>.Create((fun (v: AnonRecdTypeInfo) -> v.Stamp), (fun v -> string v.Stamp), (fun _ -> range0), id, "oanoninfos") + ostrings=Table<_>.Create "ostrings (fake)" + opubpaths=Table<_>.Create "opubpaths (fake)" + onlerefs=Table<_>.Create "onlerefs (fake)" + osimpletys=Table<_>.Create "osimpletys (fake)" + oglobals=g + ofile=file + oInMem=inMem + isStructThisArgPos = false } + let phase2bytes = + p_array p_encoded_ccuref ccuNameTab.AsArray st2 + // Add a 4th integer indicated by a negative 1st integer + let z1 = if nanoninfos > 0 then -ntycons-1 else ntycons + p_int z1 st2 + p_tup2 p_int p_int (ntypars, nvals) st2 + if nanoninfos > 0 then + p_int nanoninfos st2 + p_tup5 + (p_array p_encoded_string) + (p_array p_encoded_pubpath) + (p_array p_encoded_nleref) + (p_array p_encoded_simpletyp) + p_memory + (stringTab.AsArray, pubpathTab.AsArray, nlerefTab.AsArray, simpleTyTab.AsArray, phase1bytes) + st2 + st2.os + + let finalBytes = phase2bytes + (st1.os :> System.IDisposable).Dispose() + finalBytes + +let check (ilscope: ILScopeRef) (inMap : NodeInTable<_, _>) = + for i = 0 to inMap.Count - 1 do + let n = inMap.Get i + if not (inMap.IsLinked n) then + warning(Error(FSComp.SR.pickleMissingDefinition (i, inMap.Name, ilscope.QualifiedName), range0)) + // Note for compiler developers: to get information about which item this index relates to, + // enable the conditional in Pickle.p_osgn_ref to refer to the given index number and recompile + // an identical copy of the source for the DLL containing the data being unpickled. A message will + // then be printed indicating the name of the item. + +let unpickleObjWithDanglingCcus file viewedScope (ilModule: ILModuleDef option) u (phase2bytes: ReadOnlyByteMemory) = + let st2 = + { is = ByteStream.FromBytes (phase2bytes, 0, phase2bytes.Length) + iilscope= viewedScope + iccus= new_itbl "iccus (fake)" [| |] + ientities= NodeInTable<_, _>.Create (Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", 0) + itypars= NodeInTable<_, _>.Create (Typar.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itypars", 0) + ivals = NodeInTable<_, _>.Create (Val.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ivals", 0) + ianoninfos=NodeInTable<_, _>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ianoninfos", 0) + istrings = new_itbl "istrings (fake)" [| |] + inlerefs = new_itbl "inlerefs (fake)" [| |] + ipubpaths = new_itbl "ipubpaths (fake)" [| |] + isimpletys = new_itbl "isimpletys (fake)" [| |] + ifile=file + iILModule = ilModule } + let ccuNameTab = u_array u_encoded_ccuref st2 + let z1 = u_int st2 + let ntycons = if z1 < 0 then -z1-1 else z1 + let ntypars, nvals = u_tup2 u_int u_int st2 + let nanoninfos = if z1 < 0 then u_int st2 else 0 + let stringTab, pubpathTab, nlerefTab, simpleTyTab, phase1bytes = + u_tup5 + (u_array u_encoded_string) + (u_array u_encoded_pubpath) + (u_array u_encoded_nleref) + (u_array u_encoded_simpletyp) + u_byte_memory + st2 + let ccuTab = new_itbl "iccus" (Array.map CcuThunk.CreateDelayed ccuNameTab) + let stringTab = new_itbl "istrings" (Array.map decode_string stringTab) + let pubpathTab = new_itbl "ipubpaths" (Array.map (decode_pubpath st2 stringTab) pubpathTab) + let nlerefTab = new_itbl "inlerefs" (Array.map (decode_nleref st2 ccuTab stringTab) nlerefTab) + let simpletypTab = new_itbl "simpleTyTab" (Array.map (decode_simpletyp st2 ccuTab stringTab nlerefTab) simpleTyTab) + let data = + let st1 = + { is = ByteStream.FromBytes (phase1bytes, 0, phase1bytes.Length) + iccus= ccuTab + iilscope= viewedScope + ientities= NodeInTable<_, _>.Create(Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itycons", ntycons) + itypars= NodeInTable<_, _>.Create(Typar.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "itypars", ntypars) + ivals= NodeInTable<_, _>.Create(Val.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ivals", nvals) + ianoninfos=NodeInTable<_, _>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg), (fun osgn -> osgn.IsLinked), "ianoninfos", nanoninfos) + istrings = stringTab + ipubpaths = pubpathTab + inlerefs = nlerefTab + isimpletys = simpletypTab + ifile=file + iILModule = ilModule } + let res = u st1 +#if !LAZY_UNPICKLE + check viewedScope st1.ientities + check viewedScope st1.ivals + check viewedScope st1.itypars +#endif + res + + {RawData=data; FixupThunks=ccuTab.itbl_rows } + + +//========================================================================= +// PART II +//========================================================================= + +//--------------------------------------------------------------------------- +// Pickle/unpickle for Abstract IL data, up to IL instructions +//--------------------------------------------------------------------------- + +let p_ILPublicKey x st = + match x with + | PublicKey b -> p_byte 0 st; p_bytes b st + | PublicKeyToken b -> p_byte 1 st; p_bytes b st + +let p_ILVersion (x: ILVersionInfo) st = p_tup4 p_uint16 p_uint16 p_uint16 p_uint16 (x.Major, x.Minor, x.Build, x.Revision) st + +let p_ILModuleRef (x: ILModuleRef) st = + p_tup3 p_string p_bool (p_option p_bytes) (x.Name, x.HasMetadata, x.Hash) st + +let p_ILAssemblyRef (x: ILAssemblyRef) st = + p_byte 0 st // leave a dummy tag to make room for future encodings of assembly refs + p_tup6 p_string (p_option p_bytes) (p_option p_ILPublicKey) p_bool (p_option p_ILVersion) (p_option p_string) + ( x.Name, x.Hash, x.PublicKey, x.Retargetable, x.Version, x.Locale) st + +let p_ILScopeRef x st = + match x with + | ILScopeRef.Local -> p_byte 0 st + | ILScopeRef.Module mref -> p_byte 1 st; p_ILModuleRef mref st + | ILScopeRef.Assembly aref -> p_byte 2 st; p_ILAssemblyRef aref st + // Encode primary assembly as a normal assembly ref + | ILScopeRef.PrimaryAssembly -> p_byte 2 st; p_ILAssemblyRef st.oglobals.ilg.primaryAssemblyRef st + +let u_ILPublicKey st = + let tag = u_byte st + match tag with + | 0 -> u_bytes st |> PublicKey + | 1 -> u_bytes st |> PublicKeyToken + | _ -> ufailwith st "u_ILPublicKey" + +let u_ILVersion st = + let major, minor, build, revision = u_tup4 u_uint16 u_uint16 u_uint16 u_uint16 st + ILVersionInfo(major, minor, build, revision) + +let u_ILModuleRef st = + let a, b, c = u_tup3 u_string u_bool (u_option u_bytes) st + ILModuleRef.Create(a, b, c) + +let u_ILAssemblyRef st = + let tag = u_byte st + match tag with + | 0 -> + let a, b, c, d, e, f = u_tup6 u_string (u_option u_bytes) (u_option u_ILPublicKey) u_bool (u_option u_ILVersion) (u_option u_string) st + ILAssemblyRef.Create(a, b, c, d, e, f) + | _ -> ufailwith st "u_ILAssemblyRef" + +// IL scope references are rescoped as they are unpickled. This means +// the pickler accepts IL fragments containing ILScopeRef.Local and adjusts them +// to be absolute scope references. +let u_ILScopeRef st = + let res = + let tag = u_byte st + match tag with + | 0 -> ILScopeRef.Local + | 1 -> u_ILModuleRef st |> ILScopeRef.Module + | 2 -> u_ILAssemblyRef st |> ILScopeRef.Assembly + | _ -> ufailwith st "u_ILScopeRef" + let res = rescopeILScopeRef st.iilscope res + res + +let p_ILHasThis x st = + p_byte (match x with + | ILThisConvention.Instance -> 0 + | ILThisConvention.InstanceExplicit -> 1 + | ILThisConvention.Static -> 2) st + +let p_ILArrayShape = p_wrap (fun (ILArrayShape x) -> x) (p_list (p_tup2 (p_option p_int32) (p_option p_int32))) + +let rec p_ILType ty st = + match ty with + | ILType.Void -> p_byte 0 st + | ILType.Array (shape, ty) -> p_byte 1 st; p_tup2 p_ILArrayShape p_ILType (shape, ty) st + | ILType.Value tspec -> p_byte 2 st; p_ILTypeSpec tspec st + | ILType.Boxed tspec -> p_byte 3 st; p_ILTypeSpec tspec st + | ILType.Ptr ty -> p_byte 4 st; p_ILType ty st + | ILType.Byref ty -> p_byte 5 st; p_ILType ty st + | ILType.FunctionPointer csig -> p_byte 6 st; p_ILCallSig csig st + | ILType.TypeVar n -> p_byte 7 st; p_uint16 n st + | ILType.Modified (req, tref, ty) -> p_byte 8 st; p_tup3 p_bool p_ILTypeRef p_ILType (req, tref, ty) st + +and p_ILTypes tys = p_list p_ILType tys + +and p_ILBasicCallConv x st = + p_byte (match x with + | ILArgConvention.Default -> 0 + | ILArgConvention.CDecl -> 1 + | ILArgConvention.StdCall -> 2 + | ILArgConvention.ThisCall -> 3 + | ILArgConvention.FastCall -> 4 + | ILArgConvention.VarArg -> 5) st + +and p_ILCallConv (Callconv(x, y)) st = p_tup2 p_ILHasThis p_ILBasicCallConv (x, y) st + +and p_ILCallSig x st = p_tup3 p_ILCallConv p_ILTypes p_ILType (x.CallingConv, x.ArgTypes, x.ReturnType) st + +and p_ILTypeRef (x: ILTypeRef) st = p_tup3 p_ILScopeRef p_strings p_string (x.Scope, x.Enclosing, x.Name) st + +and p_ILTypeSpec (a: ILTypeSpec) st = p_tup2 p_ILTypeRef p_ILTypes (a.TypeRef, a.GenericArgs) st + +let u_ILBasicCallConv st = + match u_byte st with + | 0 -> ILArgConvention.Default + | 1 -> ILArgConvention.CDecl + | 2 -> ILArgConvention.StdCall + | 3 -> ILArgConvention.ThisCall + | 4 -> ILArgConvention.FastCall + | 5 -> ILArgConvention.VarArg + | _ -> ufailwith st "u_ILBasicCallConv" + +let u_ILHasThis st = + match u_byte st with + | 0 -> ILThisConvention.Instance + | 1 -> ILThisConvention.InstanceExplicit + | 2 -> ILThisConvention.Static + | _ -> ufailwith st "u_ILHasThis" + +let u_ILCallConv st = let a, b = u_tup2 u_ILHasThis u_ILBasicCallConv st in Callconv(a, b) +let u_ILTypeRef st = let a, b, c = u_tup3 u_ILScopeRef u_strings u_string st in ILTypeRef.Create(a, b, c) +let u_ILArrayShape = u_wrap (fun x -> ILArrayShape x) (u_list (u_tup2 (u_option u_int32) (u_option u_int32))) + + +let rec u_ILType st = + let tag = u_byte st + match tag with + | 0 -> ILType.Void + | 1 -> u_tup2 u_ILArrayShape u_ILType st |> ILType.Array + | 2 -> u_ILTypeSpec st |> ILType.Value + | 3 -> u_ILTypeSpec st |> mkILBoxedType + | 4 -> u_ILType st |> ILType.Ptr + | 5 -> u_ILType st |> ILType.Byref + | 6 -> u_ILCallSig st |> ILType.FunctionPointer + | 7 -> u_uint16 st |> mkILTyvarTy + | 8 -> u_tup3 u_bool u_ILTypeRef u_ILType st |> ILType.Modified + | _ -> ufailwith st "u_ILType" + +and u_ILTypes st = u_list u_ILType st + +and u_ILCallSig = u_wrap (fun (a, b, c) -> {CallingConv=a; ArgTypes=b; ReturnType=c}) (u_tup3 u_ILCallConv u_ILTypes u_ILType) + +and u_ILTypeSpec st = let a, b = u_tup2 u_ILTypeRef u_ILTypes st in ILTypeSpec.Create(a, b) + + +let p_ILMethodRef (x: ILMethodRef) st = p_tup6 p_ILTypeRef p_ILCallConv p_int p_string p_ILTypes p_ILType (x.DeclaringTypeRef, x.CallingConv, x.GenericArity, x.Name, x.ArgTypes, x.ReturnType) st + +let p_ILFieldRef (x: ILFieldRef) st = p_tup3 p_ILTypeRef p_string p_ILType (x.DeclaringTypeRef, x.Name, x.Type) st + +let p_ILMethodSpec (x: ILMethodSpec) st = p_tup3 p_ILMethodRef p_ILType p_ILTypes (x.MethodRef, x.DeclaringType, x.GenericArgs) st + +let p_ILFieldSpec (x : ILFieldSpec) st = p_tup2 p_ILFieldRef p_ILType (x.FieldRef, x.DeclaringType) st + +let p_ILBasicType x st = + p_int (match x with + | DT_R -> 0 + | DT_I1 -> 1 + | DT_U1 -> 2 + | DT_I2 -> 3 + | DT_U2 -> 4 + | DT_I4 -> 5 + | DT_U4 -> 6 + | DT_I8 -> 7 + | DT_U8 -> 8 + | DT_R4 -> 9 + | DT_R8 -> 10 + | DT_I -> 11 + | DT_U -> 12 + | DT_REF -> 13) st + +let p_ILVolatility x st = p_int (match x with Volatile -> 0 | Nonvolatile -> 1) st +let p_ILReadonly x st = p_int (match x with ReadonlyAddress -> 0 | NormalAddress -> 1) st + +let u_ILMethodRef st = + let x1, x2, x3, x4, x5, x6 = u_tup6 u_ILTypeRef u_ILCallConv u_int u_string u_ILTypes u_ILType st + ILMethodRef.Create(x1, x2, x4, x3, x5, x6) + +let u_ILFieldRef st = + let x1, x2, x3 = u_tup3 u_ILTypeRef u_string u_ILType st + {DeclaringTypeRef=x1;Name=x2;Type=x3} + +let u_ILMethodSpec st = + let x1, x2, x3 = u_tup3 u_ILMethodRef u_ILType u_ILTypes st + ILMethodSpec.Create(x2, x1, x3) + +let u_ILFieldSpec st = + let x1, x2 = u_tup2 u_ILFieldRef u_ILType st + {FieldRef=x1;DeclaringType=x2} + +let u_ILBasicType st = + match u_int st with + | 0 -> DT_R + | 1 -> DT_I1 + | 2 -> DT_U1 + | 3 -> DT_I2 + | 4 -> DT_U2 + | 5 -> DT_I4 + | 6 -> DT_U4 + | 7 -> DT_I8 + | 8 -> DT_U8 + | 9 -> DT_R4 + | 10 -> DT_R8 + | 11 -> DT_I + | 12 -> DT_U + | 13 -> DT_REF + | _ -> ufailwith st "u_ILBasicType" + +let u_ILVolatility st = (match u_int st with 0 -> Volatile | 1 -> Nonvolatile | _ -> ufailwith st "u_ILVolatility" ) +let u_ILReadonly st = (match u_int st with 0 -> ReadonlyAddress | 1 -> NormalAddress | _ -> ufailwith st "u_ILReadonly" ) + +let [] itag_nop = 0 +let [] itag_ldarg = 1 +let [] itag_ldnull = 2 +let [] itag_ilzero = 3 +let [] itag_call = 4 +let [] itag_add = 5 +let [] itag_sub = 6 +let [] itag_mul = 7 +let [] itag_div = 8 +let [] itag_div_un = 9 +let [] itag_rem = 10 +let [] itag_rem_un = 11 +let [] itag_and = 12 +let [] itag_or = 13 +let [] itag_xor = 14 +let [] itag_shl = 15 +let [] itag_shr = 16 +let [] itag_shr_un = 17 +let [] itag_neg = 18 +let [] itag_not = 19 +let [] itag_conv = 20 +let [] itag_conv_un = 21 +let [] itag_conv_ovf = 22 +let [] itag_conv_ovf_un = 23 +let [] itag_callvirt = 24 +let [] itag_ldobj = 25 +let [] itag_ldstr = 26 +let [] itag_castclass = 27 +let [] itag_isinst = 28 +let [] itag_unbox = 29 +let [] itag_throw = 30 +let [] itag_ldfld = 31 +let [] itag_ldflda = 32 +let [] itag_stfld = 33 +let [] itag_ldsfld = 34 +let [] itag_ldsflda = 35 +let [] itag_stsfld = 36 +let [] itag_stobj = 37 +let [] itag_box = 38 +let [] itag_newarr = 39 +let [] itag_ldlen = 40 +let [] itag_ldelema = 41 +let [] itag_ckfinite = 42 +let [] itag_ldtoken = 43 +let [] itag_add_ovf = 44 +let [] itag_add_ovf_un = 45 +let [] itag_mul_ovf = 46 +let [] itag_mul_ovf_un = 47 +let [] itag_sub_ovf = 48 +let [] itag_sub_ovf_un = 49 +let [] itag_ceq = 50 +let [] itag_cgt = 51 +let [] itag_cgt_un = 52 +let [] itag_clt = 53 +let [] itag_clt_un = 54 +let [] itag_ldvirtftn = 55 +let [] itag_localloc = 56 +let [] itag_rethrow = 57 +let [] itag_sizeof = 58 +let [] itag_ldelem_any = 59 +let [] itag_stelem_any = 60 +let [] itag_unbox_any = 61 +let [] itag_ldlen_multi = 62 +let [] itag_initobj = 63 +let [] itag_initblk = 64 +let [] itag_cpobj = 65 +let [] itag_cpblk = 66 + +let simple_instrs = + [ itag_add, AI_add + itag_add_ovf, AI_add_ovf + itag_add_ovf_un, AI_add_ovf_un + itag_and, AI_and + itag_div, AI_div + itag_div_un, AI_div_un + itag_ceq, AI_ceq + itag_cgt, AI_cgt + itag_cgt_un, AI_cgt_un + itag_clt, AI_clt + itag_clt_un, AI_clt_un + itag_mul, AI_mul + itag_mul_ovf, AI_mul_ovf + itag_mul_ovf_un, AI_mul_ovf_un + itag_rem, AI_rem + itag_rem_un, AI_rem_un + itag_shl, AI_shl + itag_shr, AI_shr + itag_shr_un, AI_shr_un + itag_sub, AI_sub + itag_sub_ovf, AI_sub_ovf + itag_sub_ovf_un, AI_sub_ovf_un + itag_xor, AI_xor + itag_or, AI_or + itag_neg, AI_neg + itag_not, AI_not + itag_ldnull, AI_ldnull + itag_ckfinite, AI_ckfinite + itag_nop, AI_nop + itag_localloc, I_localloc + itag_throw, I_throw + itag_ldlen, I_ldlen + itag_rethrow, I_rethrow + itag_rethrow, I_rethrow + itag_initblk, I_initblk (Aligned, Nonvolatile) + itag_cpblk, I_cpblk (Aligned, Nonvolatile) + ] + +let encode_table = Dictionary<_, _>(300, HashIdentity.Structural) +let _ = List.iter (fun (icode, i) -> encode_table.[i] <- icode) simple_instrs +let encode_instr si = encode_table.[si] +let isNoArgInstr s = encode_table.ContainsKey s + +let decoders = + [ itag_ldarg, u_uint16 >> mkLdarg + itag_call, u_ILMethodSpec >> (fun a -> I_call (Normalcall, a, None)) + itag_callvirt, u_ILMethodSpec >> (fun a -> I_callvirt (Normalcall, a, None)) + itag_ldvirtftn, u_ILMethodSpec >> I_ldvirtftn + itag_conv, u_ILBasicType >> (fun a -> (AI_conv a)) + itag_conv_ovf, u_ILBasicType >> (fun a -> (AI_conv_ovf a)) + itag_conv_ovf_un, u_ILBasicType >> (fun a -> (AI_conv_ovf_un a)) + itag_ldfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b, c) -> I_ldfld (Aligned, b, c)) + itag_ldflda, u_ILFieldSpec >> I_ldflda + itag_ldsfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a, b) -> I_ldsfld (a, b)) + itag_ldsflda, u_ILFieldSpec >> I_ldsflda + itag_stfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (b, c) -> I_stfld (Aligned, b, c)) + itag_stsfld, u_tup2 u_ILVolatility u_ILFieldSpec >> (fun (a, b) -> I_stsfld (a, b)) + itag_ldtoken, u_ILType >> (fun a -> I_ldtoken (ILToken.ILType a)) + itag_ldstr, u_string >> I_ldstr + itag_box, u_ILType >> I_box + itag_unbox, u_ILType >> I_unbox + itag_unbox_any, u_ILType >> I_unbox_any + itag_newarr, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_newarr(a, b)) + itag_stelem_any, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_stelem_any(a, b)) + itag_ldelem_any, u_tup2 u_ILArrayShape u_ILType >> (fun (a, b) -> I_ldelem_any(a, b)) + itag_ldelema, u_tup3 u_ILReadonly u_ILArrayShape u_ILType >> (fun (a, b, c) -> I_ldelema(a, false, b, c)) + itag_castclass, u_ILType >> I_castclass + itag_isinst, u_ILType >> I_isinst + itag_ldobj, u_ILType >> (fun c -> I_ldobj (Aligned, Nonvolatile, c)) + itag_stobj, u_ILType >> (fun c -> I_stobj (Aligned, Nonvolatile, c)) + itag_sizeof, u_ILType >> I_sizeof + itag_ldlen_multi, u_tup2 u_int32 u_int32 >> (fun (a, b) -> EI_ldlen_multi (a, b)) + itag_ilzero, u_ILType >> EI_ilzero + itag_ilzero, u_ILType >> EI_ilzero + itag_initobj, u_ILType >> I_initobj + itag_cpobj, u_ILType >> I_cpobj + ] + +let decode_tab = + let tab = Array.init 256 (fun n -> (fun st -> ufailwith st ("no decoder for instruction "+string n))) + let add_instr (icode, f) = tab.[icode] <- f + List.iter add_instr decoders + List.iter (fun (icode, mk) -> add_instr (icode, (fun _ -> mk))) simple_instrs + tab + +let p_ILInstr x st = + match x with + | si when isNoArgInstr si -> p_byte (encode_instr si) st + | I_call(Normalcall, mspec, None) -> p_byte itag_call st; p_ILMethodSpec mspec st + | I_callvirt(Normalcall, mspec, None) -> p_byte itag_callvirt st; p_ILMethodSpec mspec st + | I_ldvirtftn mspec -> p_byte itag_ldvirtftn st; p_ILMethodSpec mspec st + | I_ldarg x -> p_byte itag_ldarg st; p_uint16 x st + | AI_conv a -> p_byte itag_conv st; p_ILBasicType a st + | AI_conv_ovf a -> p_byte itag_conv_ovf st; p_ILBasicType a st + | AI_conv_ovf_un a -> p_byte itag_conv_ovf_un st; p_ILBasicType a st + | I_ldfld (Aligned, b, c) -> p_byte itag_ldfld st; p_tup2 p_ILVolatility p_ILFieldSpec (b, c) st + | I_ldsfld (a, b) -> p_byte itag_ldsfld st; p_tup2 p_ILVolatility p_ILFieldSpec (a, b) st + | I_stfld (Aligned, b, c) -> p_byte itag_stfld st; p_tup2 p_ILVolatility p_ILFieldSpec (b, c) st + | I_stsfld (a, b) -> p_byte itag_stsfld st; p_tup2 p_ILVolatility p_ILFieldSpec (a, b) st + | I_ldflda c -> p_byte itag_ldflda st; p_ILFieldSpec c st + | I_ldsflda a -> p_byte itag_ldsflda st; p_ILFieldSpec a st + | I_ldtoken (ILToken.ILType ty) -> p_byte itag_ldtoken st; p_ILType ty st + | I_ldstr s -> p_byte itag_ldstr st; p_string s st + | I_box ty -> p_byte itag_box st; p_ILType ty st + | I_unbox ty -> p_byte itag_unbox st; p_ILType ty st + | I_unbox_any ty -> p_byte itag_unbox_any st; p_ILType ty st + | I_newarr (a, b) -> p_byte itag_newarr st; p_tup2 p_ILArrayShape p_ILType (a, b) st + | I_stelem_any (a, b) -> p_byte itag_stelem_any st; p_tup2 p_ILArrayShape p_ILType (a, b) st + | I_ldelem_any (a, b) -> p_byte itag_ldelem_any st; p_tup2 p_ILArrayShape p_ILType (a, b) st + | I_ldelema (a, _, b, c) -> p_byte itag_ldelema st; p_tup3 p_ILReadonly p_ILArrayShape p_ILType (a, b, c) st + | I_castclass ty -> p_byte itag_castclass st; p_ILType ty st + | I_isinst ty -> p_byte itag_isinst st; p_ILType ty st + | I_ldobj (Aligned, Nonvolatile, c) -> p_byte itag_ldobj st; p_ILType c st + | I_stobj (Aligned, Nonvolatile, c) -> p_byte itag_stobj st; p_ILType c st + | I_sizeof ty -> p_byte itag_sizeof st; p_ILType ty st + | EI_ldlen_multi (n, m) -> p_byte itag_ldlen_multi st; p_tup2 p_int32 p_int32 (n, m) st + | EI_ilzero a -> p_byte itag_ilzero st; p_ILType a st + | I_initobj c -> p_byte itag_initobj st; p_ILType c st + | I_cpobj c -> p_byte itag_cpobj st; p_ILType c st + | i -> pfailwith st (sprintf "the IL instruction '%+A' cannot be emitted" i) + +let u_ILInstr st = + let n = u_byte st + decode_tab.[n] st + + + +//--------------------------------------------------------------------------- +// Pickle/unpickle for F# types and module signatures +//--------------------------------------------------------------------------- + +let p_Map_core pk pv xs st = + xs |> Map.iter (fun k v -> pk k st; pv v st) + +let p_Map pk pv x st = + p_int (Map.count x) st + p_Map_core pk pv x st + +let p_qlist pv = p_wrap QueueList.toList (p_list pv) +let p_namemap p = p_Map p_string p + +let u_Map_core uk uv n st = + Map.ofSeq (seq { for _ in 1..n -> (uk st, uv st) }) + +let u_Map uk uv st = + let n = u_int st + u_Map_core uk uv n st + +let u_qlist uv = u_wrap QueueList.ofList (u_list uv) +let u_namemap u = u_Map u_string u + +let p_pos (x: pos) st = p_tup2 p_int p_int (x.Line, x.Column) st + +let p_range (x: range) st = + let fileName = PathMap.apply st.oglobals.pathMap x.FileName + p_tup3 p_string p_pos p_pos (fileName, x.Start, x.End) st + +let p_dummy_range : range pickler = fun _x _st -> () +let p_ident (x: Ident) st = p_tup2 p_string p_range (x.idText, x.idRange) st +let p_xmldoc (doc: XmlDoc) st = p_array p_string doc.UnprocessedLines st + +let u_pos st = let a = u_int st in let b = u_int st in mkPos a b +let u_range st = let a = u_string st in let b = u_pos st in let c = u_pos st in mkRange a b c + +// Most ranges (e.g. on optimization expressions) can be elided from stored data +let u_dummy_range : range unpickler = fun _st -> range0 +let u_ident st = let a = u_string st in let b = u_range st in ident(a, b) +let u_xmldoc st = XmlDoc (u_array u_string st, range0) + +let p_local_item_ref ctxt tab st = p_osgn_ref ctxt tab st + +let p_tcref ctxt (x: EntityRef) st = + match x with + | ERefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.oentities x st + | ERefNonLocal x -> p_byte 1 st; p_nleref x st + +let p_ucref (UnionCaseRef(a, b)) st = p_tup2 (p_tcref "ucref") p_string (a, b) st +let p_rfref (RecdFieldRef(a, b)) st = p_tup2 (p_tcref "rfref") p_string (a, b) st +let p_tpref x st = p_local_item_ref "typar" st.otypars x st + +let u_local_item_ref tab st = u_osgn_ref tab st + +let u_tcref st = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ientities st |> ERefLocal + | 1 -> u_nleref st |> ERefNonLocal + | _ -> ufailwith st "u_item_ref" + +let u_ucref st = let a, b = u_tup2 u_tcref u_string st in UnionCaseRef(a, b) + +let u_rfref st = let a, b = u_tup2 u_tcref u_string st in RecdFieldRef(a, b) + +let u_tpref st = u_local_item_ref st.itypars st + +// forward reference +let fill_p_ty2, p_ty2 = p_hole2() + +let p_ty = p_ty2 false +let p_tys = (p_list p_ty) + +let fill_p_attribs, p_attribs = p_hole() + +// In F# 4.5, the type of the "this" pointer for structs is considered to be inref for the purposes of checking the implementation +// of the struct. However for backwards compat reasons we can't serialize this as the type. +let checkForInRefStructThisArg st ty = + let g = st.oglobals + let _, tauTy = tryDestForallTy g ty + isFunTy g tauTy && isFunTy g (rangeOfFunTy g tauTy) && isInByrefTy g (domainOfFunTy g tauTy) + +let p_nonlocal_val_ref (nlv: NonLocalValOrMemberRef) st = + let a = nlv.EnclosingEntity + let key = nlv.ItemKey + let pkey = key.PartialKey + p_tcref "nlvref" a st + p_option p_string pkey.MemberParentMangledName st + p_bool pkey.MemberIsOverride st + p_string pkey.LogicalName st + p_int pkey.TotalArgCount st + let isStructThisArgPos = + match key.TypeForLinkage with + | None -> false + | Some ty -> checkForInRefStructThisArg st ty + p_option (p_ty2 isStructThisArgPos) key.TypeForLinkage st + +let rec p_vref ctxt x st = + match x with + | VRefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.ovals x st + | VRefNonLocal x -> p_byte 1 st; p_nonlocal_val_ref x st + +let p_vrefs ctxt = p_list (p_vref ctxt) + +let fill_u_ty, u_ty = u_hole() +let u_tys = (u_list u_ty) +let fill_u_attribs, u_attribs = u_hole() + +let u_nonlocal_val_ref st : NonLocalValOrMemberRef = + let a = u_tcref st + let b1 = u_option u_string st + let b2 = u_bool st + let b3 = u_string st + let c = u_int st + let d = u_option u_ty st + { EnclosingEntity = a + ItemKey=ValLinkageFullKey({ MemberParentMangledName=b1; MemberIsOverride=b2;LogicalName=b3; TotalArgCount=c }, d) } + +let u_vref st = + let tag = u_byte st + match tag with + | 0 -> u_local_item_ref st.ivals st |> (fun x -> VRefLocal x) + | 1 -> u_nonlocal_val_ref st |> (fun x -> VRefNonLocal x) + | _ -> ufailwith st "u_item_ref" + +let u_vrefs = u_list u_vref + +let p_kind x st = + p_byte (match x with + | TyparKind.Type -> 0 + | TyparKind.Measure -> 1) st + +let p_member_kind x st = + p_byte (match x with + | SynMemberKind.Member -> 0 + | SynMemberKind.PropertyGet -> 1 + | SynMemberKind.PropertySet -> 2 + | SynMemberKind.Constructor -> 3 + | SynMemberKind.ClassConstructor -> 4 + | SynMemberKind.PropertyGetSet -> pfailwith st "pickling: SynMemberKind.PropertyGetSet only expected in parse trees") st + +let u_kind st = + match u_byte st with + | 0 -> TyparKind.Type + | 1 -> TyparKind.Measure + | _ -> ufailwith st "u_kind" + +let u_member_kind st = + match u_byte st with + | 0 -> SynMemberKind.Member + | 1 -> SynMemberKind.PropertyGet + | 2 -> SynMemberKind.PropertySet + | 3 -> SynMemberKind.Constructor + | 4 -> SynMemberKind.ClassConstructor + | _ -> ufailwith st "u_member_kind" + +let p_MemberFlags (x: SynMemberFlags) st = + p_tup6 p_bool p_bool p_bool p_bool p_bool p_member_kind + (x.IsInstance, + false (* _x3UnusedBoolInFormat *), + x.IsDispatchSlot, + x.IsOverrideOrExplicitImpl, + x.IsFinal, + x.MemberKind) st +let u_MemberFlags st : SynMemberFlags= + let x2, _x3UnusedBoolInFormat, x4, x5, x6, x7 = u_tup6 u_bool u_bool u_bool u_bool u_bool u_member_kind st + { IsInstance=x2 + IsDispatchSlot=x4 + IsOverrideOrExplicitImpl=x5 + IsFinal=x6 + MemberKind=x7} + +let fill_u_Expr_hole, u_expr_fwd = u_hole() +let fill_p_Expr_hole, p_expr_fwd = p_hole() + +let p_anonInfo_data (anonInfo: AnonRecdTypeInfo) st = + p_tup3 p_ccuref p_bool (p_array p_ident) (anonInfo.Assembly, evalTupInfoIsStruct anonInfo.TupInfo, anonInfo.SortedIds) st + +let p_anonInfo x st = + p_osgn_decl st.oanoninfos p_anonInfo_data x st + +let p_trait_sln sln st = + match sln with + | ILMethSln(a, b, c, d) -> + p_byte 0 st; p_tup4 p_ty (p_option p_ILTypeRef) p_ILMethodRef p_tys (a, b, c, d) st + | FSMethSln(a, b, c) -> + p_byte 1 st; p_tup3 p_ty (p_vref "trait") p_tys (a, b, c) st + | BuiltInSln -> + p_byte 2 st + | ClosedExprSln expr -> + p_byte 3 st; p_expr_fwd expr st + | FSRecdFieldSln(a, b, c) -> + p_byte 4 st; p_tup3 p_tys p_rfref p_bool (a, b, c) st + | FSAnonRecdFieldSln(a, b, c) -> + p_byte 5 st; p_tup3 p_anonInfo p_tys p_int (a, b, c) st + + +let p_trait (TTrait(a, b, c, d, e, f)) st = + p_tup6 p_tys p_string p_MemberFlags p_tys (p_option p_ty) (p_option p_trait_sln) (a, b, c, d, e, !f) st + +let u_anonInfo_data st = + let ccu, info, nms = u_tup3 u_ccuref u_bool (u_array u_ident) st + AnonRecdTypeInfo.Create (ccu, mkTupInfo info, nms) + +let u_anonInfo st = + u_osgn_decl st.ianoninfos u_anonInfo_data st + +// We have to store trait solutions since they can occur in optimization data +let u_trait_sln st = + let tag = u_byte st + match tag with + | 0 -> + let a, b, c, d = u_tup4 u_ty (u_option u_ILTypeRef) u_ILMethodRef u_tys st + ILMethSln(a, b, c, d) + | 1 -> + let a, b, c = u_tup3 u_ty u_vref u_tys st + FSMethSln(a, b, c) + | 2 -> + BuiltInSln + | 3 -> + ClosedExprSln (u_expr_fwd st) + | 4 -> + let a, b, c = u_tup3 u_tys u_rfref u_bool st + FSRecdFieldSln(a, b, c) + | 5 -> + let a, b, c = u_tup3 u_anonInfo u_tys u_int st + FSAnonRecdFieldSln(a, b, c) + | _ -> ufailwith st "u_trait_sln" + +let u_trait st = + let a, b, c, d, e, f = u_tup6 u_tys u_string u_MemberFlags u_tys (u_option u_ty) (u_option u_trait_sln) st + TTrait (a, b, c, d, e, ref f) + + +let p_rational q st = p_int32 (GetNumerator q) st; p_int32 (GetDenominator q) st + +let p_measure_con tcref st = p_byte 0 st; p_tcref "measure" tcref st + +let p_measure_var v st = p_byte 3 st; p_tpref v st + +let p_measure_one = p_byte 4 + +// Pickle a unit-of-measure variable or constructor +let p_measure_varcon unt st = + match unt with + | Measure.Con tcref -> p_measure_con tcref st + | Measure.Var v -> p_measure_var v st + | _ -> pfailwith st "p_measure_varcon: expected measure variable or constructor" + +// Pickle a positive integer power of a unit-of-measure variable or constructor +let rec p_measure_pospower unt n st = + if n = 1 + then p_measure_varcon unt st + else p_byte 2 st; p_measure_varcon unt st; p_measure_pospower unt (n-1) st + +// Pickle a non-zero integer power of a unit-of-measure variable or constructor +let p_measure_intpower unt n st = + if n < 0 + then p_byte 1 st; p_measure_pospower unt (-n) st + else p_measure_pospower unt n st + +// Pickle a rational power of a unit-of-measure variable or constructor +let rec p_measure_power unt q st = + if q = ZeroRational then p_measure_one st + elif GetDenominator q = 1 + then p_measure_intpower unt (GetNumerator q) st + else p_byte 5 st; p_measure_varcon unt st; p_rational q st + +// Pickle a normalized unit-of-measure expression +// Normalized means of the form cv1 ^ q1 * ... * cvn ^ qn +// where q1, ..., qn are non-zero, and cv1, ..., cvn are distinct unit-of-measure variables or constructors +let rec p_normalized_measure unt st = + let unt = stripUnitEqnsAux false unt + match unt with + | Measure.Con tcref -> p_measure_con tcref st + | Measure.Inv x -> p_byte 1 st; p_normalized_measure x st + | Measure.Prod(x1, x2) -> p_byte 2 st; p_normalized_measure x1 st; p_normalized_measure x2 st + | Measure.Var v -> p_measure_var v st + | Measure.One -> p_measure_one st + | Measure.RationalPower(x, q) -> p_measure_power x q st + +// By normalizing the unit-of-measure and treating integer powers as a special case, +// we ensure that the pickle format for rational powers of units (byte 5 followed by +// numerator and denominator) is used only when absolutely necessary, maintaining +// compatibility of formats with versions prior to F# 4.0. +// +// See https://github.com/Microsoft/visualfsharp/issues/69 +let p_measure_expr unt st = p_normalized_measure (normalizeMeasure st.oglobals unt) st + +let u_rational st = + let a, b = u_tup2 u_int32 u_int32 st in DivRational (intToRational a) (intToRational b) + +let rec u_measure_expr st = + let tag = u_byte st + match tag with + | 0 -> let a = u_tcref st in Measure.Con a + | 1 -> let a = u_measure_expr st in Measure.Inv a + | 2 -> let a, b = u_tup2 u_measure_expr u_measure_expr st in Measure.Prod (a, b) + | 3 -> let a = u_tpref st in Measure.Var a + | 4 -> Measure.One + | 5 -> let a = u_measure_expr st in let b = u_rational st in Measure.RationalPower (a, b) + | _ -> ufailwith st "u_measure_expr" + +let p_tyar_constraint x st = + match x with + | TyparConstraint.CoercesTo (a, _) -> p_byte 0 st; p_ty a st + | TyparConstraint.MayResolveMember(traitInfo, _) -> p_byte 1 st; p_trait traitInfo st + | TyparConstraint.DefaultsTo(_, rty, _) -> p_byte 2 st; p_ty rty st + | TyparConstraint.SupportsNull _ -> p_byte 3 st + | TyparConstraint.IsNonNullableStruct _ -> p_byte 4 st + | TyparConstraint.IsReferenceType _ -> p_byte 5 st + | TyparConstraint.RequiresDefaultConstructor _ -> p_byte 6 st + | TyparConstraint.SimpleChoice(tys, _) -> p_byte 7 st; p_tys tys st + | TyparConstraint.IsEnum(ty, _) -> p_byte 8 st; p_ty ty st + | TyparConstraint.IsDelegate(aty, bty, _) -> p_byte 9 st; p_ty aty st; p_ty bty st + | TyparConstraint.SupportsComparison _ -> p_byte 10 st + | TyparConstraint.SupportsEquality _ -> p_byte 11 st + | TyparConstraint.IsUnmanaged _ -> p_byte 12 st +let p_tyar_constraints = (p_list p_tyar_constraint) + +let u_tyar_constraint st = + let tag = u_byte st + match tag with + | 0 -> u_ty st |> (fun a _ -> TyparConstraint.CoercesTo (a, range0) ) + | 1 -> u_trait st |> (fun a _ -> TyparConstraint.MayResolveMember(a, range0)) + | 2 -> u_ty st |> (fun a ridx -> TyparConstraint.DefaultsTo(ridx, a, range0)) + | 3 -> (fun _ -> TyparConstraint.SupportsNull range0) + | 4 -> (fun _ -> TyparConstraint.IsNonNullableStruct range0) + | 5 -> (fun _ -> TyparConstraint.IsReferenceType range0) + | 6 -> (fun _ -> TyparConstraint.RequiresDefaultConstructor range0) + | 7 -> u_tys st |> (fun a _ -> TyparConstraint.SimpleChoice(a, range0)) + | 8 -> u_ty st |> (fun a _ -> TyparConstraint.IsEnum(a, range0)) + | 9 -> u_tup2 u_ty u_ty st |> (fun (a, b) _ -> TyparConstraint.IsDelegate(a, b, range0)) + | 10 -> (fun _ -> TyparConstraint.SupportsComparison range0) + | 11 -> (fun _ -> TyparConstraint.SupportsEquality range0) + | 12 -> (fun _ -> TyparConstraint.IsUnmanaged range0) + | _ -> ufailwith st "u_tyar_constraint" + + +let u_tyar_constraints = (u_list_revi u_tyar_constraint) + + +let p_tyar_spec_data (x: Typar) st = + p_tup5 + p_ident + p_attribs + p_int64 + p_tyar_constraints + p_xmldoc + (x.typar_id, x.Attribs, int64 x.typar_flags.PickledBits, x.Constraints, x.XmlDoc) st + +let p_tyar_spec (x: Typar) st = + //Disabled, workaround for bug 2721: if x.Rigidity <> TyparRigidity.Rigid then warning(Error(sprintf "p_tyar_spec: typar#%d is not rigid" x.Stamp, x.Range)) + if x.IsFromError then warning(Error((0, "p_tyar_spec: from error"), x.Range)) + p_osgn_decl st.otypars p_tyar_spec_data x st + +let p_tyar_specs = (p_list p_tyar_spec) + +let u_tyar_spec_data st = + let a, c, d, e, g = u_tup5 u_ident u_attribs u_int64 u_tyar_constraints u_xmldoc st + { typar_id=a + typar_stamp=newStamp() + typar_flags=TyparFlags(int32 d) + typar_solution=None + typar_astype= Unchecked.defaultof<_> + typar_opt_data= + match g, e, c with + | doc, [], [] when doc.IsEmpty -> None + | _ -> Some { typar_il_name = None; typar_xmldoc = g; typar_constraints = e; typar_attribs = c } } + +let u_tyar_spec st = + u_osgn_decl st.itypars u_tyar_spec_data st + +let u_tyar_specs = (u_list u_tyar_spec) + +let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> + let ty = stripTyparEqns ty + + // See comment on 'checkForInRefStructThisArg' + let ty = + if isInByrefTy st.oglobals ty && isStructThisArgPos then + // Convert the inref to a byref + mkByrefTy st.oglobals (destByrefTy st.oglobals ty) + else + ty + + match ty with + | TType_tuple (tupInfo, l) -> + if evalTupInfoIsStruct tupInfo then + p_byte 8 st; p_tys l st + else + p_byte 0 st; p_tys l st + | TType_app(ERefNonLocal nleref, []) -> p_byte 1 st; p_simpletyp nleref st + | TType_app (tc, tinst) -> p_byte 2 st; p_tup2 (p_tcref "typ") p_tys (tc, tinst) st + | TType_fun (d, r) -> + p_byte 3 st + // Note, the "this" argument may be found in the domain position of a function type, so propagate the isStructThisArgPos value + p_ty2 isStructThisArgPos d st + p_ty r st + | TType_var r -> p_byte 4 st; p_tpref r st + | TType_forall (tps, r) -> + p_byte 5 st + p_tyar_specs tps st + // Note, the "this" argument may be found in the body of a generic forall type, so propagate the isStructThisArgPos value + p_ty2 isStructThisArgPos r st + | TType_measure unt -> p_byte 6 st; p_measure_expr unt st + | TType_ucase (uc, tinst) -> p_byte 7 st; p_tup2 p_ucref p_tys (uc, tinst) st + // p_byte 8 taken by TType_tuple above + | TType_anon (anonInfo, l) -> + p_byte 9 st + p_anonInfo anonInfo st + p_tys l st) + +let _ = fill_u_ty (fun st -> + let tag = u_byte st + match tag with + | 0 -> let l = u_tys st in TType_tuple (tupInfoRef, l) + | 1 -> u_simpletyp st + | 2 -> let tc = u_tcref st in let tinst = u_tys st in TType_app (tc, tinst) + | 3 -> let d = u_ty st in let r = u_ty st in TType_fun (d, r) + | 4 -> let r = u_tpref st in r.AsType + | 5 -> let tps = u_tyar_specs st in let r = u_ty st in TType_forall (tps, r) + | 6 -> let unt = u_measure_expr st in TType_measure unt + | 7 -> let uc = u_ucref st in let tinst = u_tys st in TType_ucase (uc, tinst) + | 8 -> let l = u_tys st in TType_tuple (tupInfoStruct, l) + | 9 -> let anonInfo = u_anonInfo st in let l = u_tys st in TType_anon (anonInfo, l) + | _ -> ufailwith st "u_typ") + + +let fill_p_binds, p_binds = p_hole() +let fill_p_targets, p_targets = p_hole() +let fill_p_Exprs, p_Exprs = p_hole() +let fill_p_constraints, p_constraints = p_hole() +let fill_p_Vals, p_Vals = p_hole() + +let fill_u_binds, u_binds = u_hole() +let fill_u_targets, u_targets = u_hole() +let fill_u_Exprs, u_Exprs = u_hole() +let fill_u_constraints, u_constraints = u_hole() +let fill_u_Vals, u_Vals = u_hole() + +let p_ArgReprInfo (x: ArgReprInfo) st = + p_attribs x.Attribs st + p_option p_ident x.Name st + +let p_TyparReprInfo (TyparReprInfo(a, b)) st = + p_ident a st + p_kind b st + +let p_ValReprInfo (ValReprInfo (a, args, ret)) st = + p_list p_TyparReprInfo a st + p_list (p_list p_ArgReprInfo) args st + p_ArgReprInfo ret st + +let u_ArgReprInfo st = + let a = u_attribs st + let b = u_option u_ident st + match a, b with + | [], None -> ValReprInfo.unnamedTopArg1 + | _ -> { Attribs = a; Name = b } + +let u_TyparReprInfo st = + let a = u_ident st + let b = u_kind st + TyparReprInfo(a, b) + +let u_ValReprInfo st = + let a = u_list u_TyparReprInfo st + let b = u_list (u_list u_ArgReprInfo) st + let c = u_ArgReprInfo st + ValReprInfo (a, b, c) + +let p_ranges x st = + p_option (p_tup2 p_range p_range) x st + +let p_istype x st = + match x with + | FSharpModuleWithSuffix -> p_byte 0 st + | ModuleOrType -> p_byte 1 st + | Namespace -> p_byte 2 st + +let p_cpath (CompPath(a, b)) st = + p_tup2 p_ILScopeRef (p_list (p_tup2 p_string p_istype)) (a, b) st + +let u_ranges st = u_option (u_tup2 u_range u_range) st + +let u_istype st = + let tag = u_byte st + match tag with + | 0 -> FSharpModuleWithSuffix + | 1 -> ModuleOrType + | 2 -> Namespace + | _ -> ufailwith st "u_istype" + +let u_cpath st = let a, b = u_tup2 u_ILScopeRef (u_list (u_tup2 u_string u_istype)) st in (CompPath(a, b)) + + +let rec dummy x = x +and p_tycon_repr x st = + // The leading "p_byte 1" and "p_byte 0" come from the F# 2.0 format, which used an option value at this point. + match x with + | TFSharpRecdRepr fs -> p_byte 1 st; p_byte 0 st; p_rfield_table fs st; false + | TFSharpUnionRepr x -> p_byte 1 st; p_byte 1 st; p_array p_unioncase_spec x.CasesTable.CasesByIndex st; false + | TAsmRepr ilty -> p_byte 1 st; p_byte 2 st; p_ILType ilty st; false + | TFSharpObjectRepr r -> p_byte 1 st; p_byte 3 st; p_tycon_objmodel_data r st; false + | TMeasureableRepr ty -> p_byte 1 st; p_byte 4 st; p_ty ty st; false + | TNoRepr -> p_byte 0 st; false +#if !NO_EXTENSIONTYPING + | TProvidedTypeRepr info -> + if info.IsErased then + // Pickle erased type definitions as a NoRepr + p_byte 0 st; false + else + // Pickle generated type definitions as a TAsmRepr + p_byte 1 st; p_byte 2 st; p_ILType (mkILBoxedType(ILTypeSpec.Create(ExtensionTyping.GetILTypeRefOfProvidedType(info.ProvidedType, range0), []))) st; true + | TProvidedNamespaceRepr _ -> p_byte 0 st; false +#endif + | TILObjectRepr (TILObjectReprData (_, _, td)) -> error (Failure("Unexpected IL type definition"+td.Name)) + +and p_tycon_objmodel_data x st = + p_tup3 p_tycon_objmodel_kind (p_vrefs "vslots") p_rfield_table + (x.fsobjmodel_kind, x.fsobjmodel_vslots, x.fsobjmodel_rfields) st + +and p_attribs_ext f x st = p_list_ext f p_attrib x st + +and p_unioncase_spec x st = + p_rfield_table x.FieldTable st + p_ty x.ReturnType st + // The union case compiled name is now computed from Id field when needed and is not stored in UnionCase record. + // So this field doesn't really need to be stored but it exists for legacy compat + p_string x.CompiledName st + p_ident x.Id st + // The XmlDoc are only written for the extended in-memory format. We encode their presence using a marker bit here + p_attribs_ext (if st.oInMem then Some (p_xmldoc x.XmlDoc) else None) x.Attribs st + p_string x.XmlDocSig st + p_access x.Accessibility st + +and p_exnc_spec_data x st = p_entity_spec_data x st + +and p_exnc_repr x st = + match x with + | TExnAbbrevRepr x -> p_byte 0 st; (p_tcref "exn abbrev") x st + | TExnAsmRepr x -> p_byte 1 st; p_ILTypeRef x st + | TExnFresh x -> p_byte 2 st; p_rfield_table x st + | TExnNone -> p_byte 3 st + +and p_exnc_spec x st = p_entity_spec x st + +and p_access (TAccess n) st = p_list p_cpath n st + +and p_recdfield_spec x st = + p_bool x.rfield_mutable st + p_bool x.rfield_volatile st + p_ty x.rfield_type st + p_bool x.rfield_static st + p_bool x.rfield_secret st + p_option p_const x.rfield_const st + p_ident x.rfield_id st + p_attribs_ext (if st.oInMem then Some (p_xmldoc x.XmlDoc) else None) x.rfield_pattribs st + p_attribs x.rfield_fattribs st + p_string x.rfield_xmldocsig st + p_access x.rfield_access st + +and p_rfield_table x st = + p_array p_recdfield_spec x.FieldsByIndex st + +and p_entity_spec_data (x: Entity) st = + p_tyar_specs (x.entity_typars.Force(x.entity_range)) st + p_string x.entity_logical_name st + p_option p_string x.EntityCompiledName st + p_range x.entity_range st + p_option p_pubpath x.entity_pubpath st + p_access x.Accessibility st + p_access x.TypeReprAccessibility st + p_attribs x.entity_attribs st + let flagBit = p_tycon_repr x.entity_tycon_repr st + p_option p_ty x.TypeAbbrev st + p_tcaug x.entity_tycon_tcaug st + p_string System.String.Empty st + p_kind x.TypeOrMeasureKind st + p_int64 (x.entity_flags.PickledBits ||| (if flagBit then EntityFlags.ReservedBitForPickleFormatTyconReprFlag else 0L)) st + p_option p_cpath x.entity_cpath st + p_maybe_lazy p_modul_typ x.entity_modul_contents st + p_exnc_repr x.ExceptionInfo st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st + + +and p_tcaug p st = + p_tup9 + (p_option (p_tup2 (p_vref "compare_obj") (p_vref "compare"))) + (p_option (p_vref "compare_withc")) + (p_option (p_tup3 (p_vref "hash_obj") (p_vref "hash_withc") (p_vref "equals_withc"))) + (p_option (p_tup2 (p_vref "hash") (p_vref "equals"))) + (p_list (p_tup2 p_string (p_vref "adhoc"))) + (p_list (p_tup3 p_ty p_bool p_dummy_range)) + (p_option p_ty) + p_bool + (p_space 1) + (p.tcaug_compare, + p.tcaug_compare_withc, + p.tcaug_hash_and_equals_withc, + p.tcaug_equals, + (p.tcaug_adhoc_list + |> ResizeArray.toList + // Explicit impls of interfaces only get kept in the adhoc list + // in order to get check the well-formedness of an interface. + // Keeping them across assembly boundaries is not valid, because relinking their ValRefs + // does not work correctly (they may get incorrectly relinked to a default member) + |> List.filter (fun (isExplicitImpl, _) -> not isExplicitImpl) + |> List.map (fun (_, vref) -> vref.LogicalName, vref)), + p.tcaug_interfaces, + p.tcaug_super, + p.tcaug_abstract, + space) st + +and p_entity_spec x st = p_osgn_decl st.oentities p_entity_spec_data x st + +and p_parentref x st = + match x with + | ParentNone -> p_byte 0 st + | Parent x -> p_byte 1 st; p_tcref "parent tycon" x st + +and p_attribkind x st = + match x with + | ILAttrib x -> p_byte 0 st; p_ILMethodRef x st + | FSAttrib x -> p_byte 1 st; p_vref "attrib" x st + +and p_attrib (Attrib (a, b, c, d, e, _targets, f)) st = // AttributeTargets are not preserved + p_tup6 (p_tcref "attrib") p_attribkind (p_list p_attrib_expr) (p_list p_attrib_arg) p_bool p_dummy_range (a, b, c, d, e, f) st + +and p_attrib_expr (AttribExpr(e1, e2)) st = + p_tup2 p_expr p_expr (e1, e2) st + +and p_attrib_arg (AttribNamedArg(a, b, c, d)) st = + p_tup4 p_string p_ty p_bool p_attrib_expr (a, b, c, d) st + +and p_member_info (x: ValMemberInfo) st = + p_tup4 (p_tcref "member_info") p_MemberFlags (p_list p_slotsig) p_bool + (x.ApparentEnclosingEntity, x.MemberFlags, x.ImplementedSlotSigs, x.IsImplemented) st + +and p_tycon_objmodel_kind x st = + match x with + | TFSharpClass -> p_byte 0 st + | TFSharpInterface -> p_byte 1 st + | TFSharpStruct -> p_byte 2 st + | TFSharpDelegate ss -> p_byte 3 st; p_slotsig ss st + | TFSharpEnum -> p_byte 4 st + +and p_vrefFlags x st = + match x with + | NormalValUse -> p_byte 0 st + | CtorValUsedAsSuperInit -> p_byte 1 st + | CtorValUsedAsSelfInit -> p_byte 2 st + | PossibleConstrainedCall ty -> p_byte 3 st; p_ty ty st + | VSlotDirectCall -> p_byte 4 st + +and p_ValData x st = + p_string x.val_logical_name st + p_option p_string x.ValCompiledName st + // only keep range information on published values, not on optimization data + p_ranges (x.ValReprInfo |> Option.map (fun _ -> x.val_range, x.DefinitionRange)) st + + let isStructThisArgPos = x.IsMember && checkForInRefStructThisArg st x.Type + p_ty2 isStructThisArgPos x.val_type st + + p_int64 x.val_flags.PickledBits st + p_option p_member_info x.MemberInfo st + p_attribs x.Attribs st + p_option p_ValReprInfo x.ValReprInfo st + p_string x.XmlDocSig st + p_access x.Accessibility st + p_parentref x.DeclaringEntity st + p_option p_const x.LiteralValue st + if st.oInMem then + p_used_space1 (p_xmldoc x.XmlDoc) st + else + p_space 1 () st + +and p_Val x st = + p_osgn_decl st.ovals p_ValData x st + +and p_modul_typ (x: ModuleOrNamespaceType) st = + p_tup3 + p_istype + (p_qlist p_Val) + (p_qlist p_entity_spec) + (x.ModuleOrNamespaceKind, x.AllValsAndMembers, x.AllEntities) + st + +and u_tycon_repr st = + let tag1 = u_byte st + match tag1 with + | 0 -> (fun _flagBit -> TNoRepr) + | 1 -> + let tag2 = u_byte st + match tag2 with + | 0 -> + let v = u_rfield_table st + (fun _flagBit -> TFSharpRecdRepr v) + | 1 -> + let v = u_list u_unioncase_spec st + (fun _flagBit -> Construct.MakeUnionRepr v) + | 2 -> + let v = u_ILType st + // This is the F# 3.0 extension to the format used for F# provider-generated types, which record an ILTypeRef in the format + // You can think of an F# 2.0 reader as always taking the path where 'flagBit' is false. Thus the F# 2.0 reader will + // interpret provider-generated types as TAsmRepr. + (fun flagBit -> + if flagBit then + let iltref = v.TypeRef + match st.iILModule with + | None -> TNoRepr + | Some iILModule -> + try + let rec find acc enclosingTypeNames (tdefs: ILTypeDefs) = + match enclosingTypeNames with + | [] -> List.rev acc, tdefs.FindByName iltref.Name + | h :: t -> + let nestedTypeDef = tdefs.FindByName h + find (tdefs.FindByName h :: acc) t nestedTypeDef.NestedTypes + let nestedILTypeDefs, ilTypeDef = find [] iltref.Enclosing iILModule.TypeDefs + TILObjectRepr(TILObjectReprData(st.iilscope, nestedILTypeDefs, ilTypeDef)) + with _ -> + System.Diagnostics.Debug.Assert(false, sprintf "failed to find IL backing metadata for cross-assembly generated type %s" iltref.FullName) + TNoRepr + else + TAsmRepr v) + | 3 -> + let v = u_tycon_objmodel_data st + (fun _flagBit -> TFSharpObjectRepr v) + | 4 -> + let v = u_ty st + (fun _flagBit -> TMeasureableRepr v) + | _ -> ufailwith st "u_tycon_repr" + | _ -> ufailwith st "u_tycon_repr" + +and u_tycon_objmodel_data st = + let x1, x2, x3 = u_tup3 u_tycon_objmodel_kind u_vrefs u_rfield_table st + {fsobjmodel_kind=x1; fsobjmodel_vslots=x2; fsobjmodel_rfields=x3 } + +and u_attribs_ext extraf st = u_list_ext extraf u_attrib st +and u_unioncase_spec st = + let a = u_rfield_table st + let b = u_ty st + + // The union case compiled name is now computed from Id field when needed and is not stored in UnionCase record. + let _c = u_string st + let d = u_ident st + // The XmlDoc is only present in the extended in-memory format. We detect its presence using a marker bit here + let xmldoc, e = u_attribs_ext u_xmldoc st + let f = u_string st + let i = u_access st + { FieldTable=a + ReturnType=b + Id=d + Attribs=e + XmlDoc= defaultArg xmldoc XmlDoc.Empty + XmlDocSig=f + Accessibility=i + OtherRangeOpt=None } + +and u_exnc_spec_data st = u_entity_spec_data st + +and u_exnc_repr st = + let tag = u_byte st + match tag with + | 0 -> u_tcref st |> TExnAbbrevRepr + | 1 -> u_ILTypeRef st |> TExnAsmRepr + | 2 -> u_rfield_table st |> TExnFresh + | 3 -> TExnNone + | _ -> ufailwith st "u_exnc_repr" + +and u_exnc_spec st = u_entity_spec st + +and u_access st = + match u_list u_cpath st with + | [] -> taccessPublic // save unnecessary allocations + | res -> TAccess res + +and u_recdfield_spec st = + let a = u_bool st + let b = u_bool st + let c1 = u_ty st + let c2 = u_bool st + let c2b = u_bool st + let c3 = u_option u_const st + let d = u_ident st + // The XmlDoc is only present in the extended in-memory format. We detect its presence using a marker bit here + let xmldoc, e1 = u_attribs_ext u_xmldoc st + let e2 = u_attribs st + let f = u_string st + let g = u_access st + { rfield_mutable=a + rfield_volatile=b + rfield_type=c1 + rfield_static=c2 + rfield_secret=c2b + rfield_const=c3 + rfield_id=d + rfield_pattribs=e1 + rfield_fattribs=e2 + rfield_xmldoc= defaultArg xmldoc XmlDoc.Empty + rfield_xmldocsig=f + rfield_access=g + rfield_name_generated = false + rfield_other_range = None } + +and u_rfield_table st = Construct.MakeRecdFieldsTable (u_list u_recdfield_spec st) + +and u_entity_spec_data st : Entity = + let x1, x2a, x2b, x2c, x3, (x4a, x4b), x6, x7f, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = + u_tup17 + u_tyar_specs + u_string + (u_option u_string) + u_range + (u_option u_pubpath) + (u_tup2 u_access u_access) + u_attribs + u_tycon_repr + (u_option u_ty) + u_tcaug + u_string + u_kind + u_int64 + (u_option u_cpath ) + (u_lazy u_modul_typ) + u_exnc_repr + (u_used_space1 u_xmldoc) + st + // We use a bit that was unused in the F# 2.0 format to indicate two possible representations in the F# 3.0 tycon_repr format + let x7 = x7f (x11 &&& EntityFlags.ReservedBitForPickleFormatTyconReprFlag <> 0L) + let x11 = x11 &&& ~~~EntityFlags.ReservedBitForPickleFormatTyconReprFlag + + { entity_typars=LazyWithContext.NotLazy x1 + entity_stamp=newStamp() + entity_logical_name=x2a + entity_range=x2c + entity_pubpath=x3 + entity_attribs=x6 + entity_tycon_repr=x7 + entity_tycon_tcaug=x9 + entity_flags=EntityFlags x11 + entity_cpath=x12 + entity_modul_contents=MaybeLazy.Lazy x13 + entity_il_repr_cache=newCache() + entity_opt_data= + match x2b, x10b, x15, x8, x4a, x4b, x14 with + | None, TyparKind.Type, None, None, TAccess [], TAccess [], TExnNone -> None + | _ -> + Some { Entity.NewEmptyEntityOptData() with + entity_compiled_name = x2b + entity_kind = x10b + entity_xmldoc= defaultArg x15 XmlDoc.Empty + entity_xmldocsig = System.String.Empty + entity_tycon_abbrev = x8 + entity_accessibility = x4a + entity_tycon_repr_accessibility = x4b + entity_exn_info = x14 } + } + +and u_tcaug st = + let a1, a2, a3, b2, c, d, e, g, _space = + u_tup9 + (u_option (u_tup2 u_vref u_vref)) + (u_option u_vref) + (u_option (u_tup3 u_vref u_vref u_vref)) + (u_option (u_tup2 u_vref u_vref)) + (u_list (u_tup2 u_string u_vref)) + (u_list (u_tup3 u_ty u_bool u_dummy_range)) + (u_option u_ty) + u_bool + (u_space 1) + st + {tcaug_compare=a1 + tcaug_compare_withc=a2 + tcaug_hash_and_equals_withc=a3 + tcaug_equals=b2 + // only used for code generation and checking - hence don't care about the values when reading back in + tcaug_hasObjectGetHashCode=false + tcaug_adhoc_list= ResizeArray<_>(c |> List.map (fun (_, vref) -> (false, vref))) + tcaug_adhoc=NameMultiMap.ofList c + tcaug_interfaces=d + tcaug_super=e + // pickled type definitions are always closed (i.e. no more intrinsic members allowed) + tcaug_closed=true + tcaug_abstract=g} + +and u_entity_spec st = + u_osgn_decl st.ientities u_entity_spec_data st + +and u_parentref st = + let tag = u_byte st + match tag with + | 0 -> ParentNone + | 1 -> u_tcref st |> Parent + | _ -> ufailwith st "u_attribkind" + +and u_attribkind st = + let tag = u_byte st + match tag with + | 0 -> u_ILMethodRef st |> ILAttrib + | 1 -> u_vref st |> FSAttrib + | _ -> ufailwith st "u_attribkind" + +and u_attrib st : Attrib = + let a, b, c, d, e, f = u_tup6 u_tcref u_attribkind (u_list u_attrib_expr) (u_list u_attrib_arg) u_bool u_dummy_range st + Attrib(a, b, c, d, e, None, f) // AttributeTargets are not preserved + +and u_attrib_expr st = + let a, b = u_tup2 u_expr u_expr st + AttribExpr(a, b) + +and u_attrib_arg st = + let a, b, c, d = u_tup4 u_string u_ty u_bool u_attrib_expr st + AttribNamedArg(a, b, c, d) + +and u_member_info st : ValMemberInfo = + let x2, x3, x4, x5 = u_tup4 u_tcref u_MemberFlags (u_list u_slotsig) u_bool st + { ApparentEnclosingEntity=x2 + MemberFlags=x3 + ImplementedSlotSigs=x4 + IsImplemented=x5 } + +and u_tycon_objmodel_kind st = + let tag = u_byte st + match tag with + | 0 -> TFSharpClass + | 1 -> TFSharpInterface + | 2 -> TFSharpStruct + | 3 -> u_slotsig st |> TFSharpDelegate + | 4 -> TFSharpEnum + | _ -> ufailwith st "u_tycon_objmodel_kind" + +and u_vrefFlags st = + match u_byte st with + | 0 -> NormalValUse + | 1 -> CtorValUsedAsSuperInit + | 2 -> CtorValUsedAsSelfInit + | 3 -> PossibleConstrainedCall (u_ty st) + | 4 -> VSlotDirectCall + | _ -> ufailwith st "u_vrefFlags" + +and u_ValData st = + let x1, x1z, x1a, x2, x4, x8, x9, x10, x12, x13, x13b, x14, x15 = + u_tup13 + u_string + (u_option u_string) + u_ranges + u_ty + u_int64 + (u_option u_member_info) + u_attribs + (u_option u_ValReprInfo) + u_string + u_access + u_parentref + (u_option u_const) + (u_used_space1 u_xmldoc) + st + + { val_logical_name = x1 + val_range = (match x1a with None -> range0 | Some(a, _) -> a) + val_type = x2 + val_stamp = newStamp() + val_flags = ValFlags x4 + val_opt_data = + match x1z, x1a, x10, x14, x13, x15, x8, x13b, x12, x9 with + | None, None, None, None, TAccess [], None, None, ParentNone, "", [] -> None + | _ -> + Some { val_compiled_name = x1z + val_other_range = (match x1a with None -> None | Some(_, b) -> Some(b, true)) + val_defn = None + val_repr_info = x10 + val_const = x14 + val_access = x13 + val_xmldoc = defaultArg x15 XmlDoc.Empty + val_member_info = x8 + val_declaring_entity = x13b + val_xmldocsig = x12 + val_attribs = x9 } + } + +and u_Val st = u_osgn_decl st.ivals u_ValData st + + +and u_modul_typ st = + let x1, x3, x5 = + u_tup3 + u_istype + (u_qlist u_Val) + (u_qlist u_entity_spec) st + ModuleOrNamespaceType(x1, x3, x5) + + +//--------------------------------------------------------------------------- +// Pickle/unpickle for F# expressions (for optimization data) +//--------------------------------------------------------------------------- + +and p_const x st = + match x with + | Const.Bool x -> p_byte 0 st; p_bool x st + | Const.SByte x -> p_byte 1 st; p_int8 x st + | Const.Byte x -> p_byte 2 st; p_uint8 x st + | Const.Int16 x -> p_byte 3 st; p_int16 x st + | Const.UInt16 x -> p_byte 4 st; p_uint16 x st + | Const.Int32 x -> p_byte 5 st; p_int32 x st + | Const.UInt32 x -> p_byte 6 st; p_uint32 x st + | Const.Int64 x -> p_byte 7 st; p_int64 x st + | Const.UInt64 x -> p_byte 8 st; p_uint64 x st + | Const.IntPtr x -> p_byte 9 st; p_int64 x st + | Const.UIntPtr x -> p_byte 10 st; p_uint64 x st + | Const.Single x -> p_byte 11 st; p_single x st + | Const.Double x -> p_byte 12 st; p_int64 (bits_of_float x) st + | Const.Char c -> p_byte 13 st; p_char c st + | Const.String s -> p_byte 14 st; p_string s st + | Const.Unit -> p_byte 15 st + | Const.Zero -> p_byte 16 st + | Const.Decimal s -> p_byte 17 st; p_array p_int32 (System.Decimal.GetBits s) st + +and u_const st = + let tag = u_byte st + match tag with + | 0 -> u_bool st |> Const.Bool + | 1 -> u_int8 st |> Const.SByte + | 2 -> u_uint8 st |> Const.Byte + | 3 -> u_int16 st |> Const.Int16 + | 4 -> u_uint16 st |> Const.UInt16 + | 5 -> u_int32 st |> Const.Int32 + | 6 -> u_uint32 st |> Const.UInt32 + | 7 -> u_int64 st |> Const.Int64 + | 8 -> u_uint64 st |> Const.UInt64 + | 9 -> u_int64 st |> Const.IntPtr + | 10 -> u_uint64 st |> Const.UIntPtr + | 11 -> u_single st |> Const.Single + | 12 -> u_int64 st |> float_of_bits |> Const.Double + | 13 -> u_char st |> Const.Char + | 14 -> u_string st |> Const.String + | 15 -> Const.Unit + | 16 -> Const.Zero + | 17 -> u_array u_int32 st |> (fun bits -> Const.Decimal (System.Decimal bits)) + | _ -> ufailwith st "u_const" + + +and p_dtree x st = + match x with + | TDSwitch (_sp, a, b, c, d) -> p_byte 0 st; p_tup4 p_expr (p_list p_dtree_case) (p_option p_dtree) p_dummy_range (a, b, c, d) st + | TDSuccess (a, b) -> p_byte 1 st; p_tup2 p_Exprs p_int (a, b) st + | TDBind (a, b) -> p_byte 2 st; p_tup2 p_bind p_dtree (a, b) st + +and p_dtree_case (TCase(a, b)) st = p_tup2 p_dtree_discrim p_dtree (a, b) st + +and p_dtree_discrim x st = + match x with + | DecisionTreeTest.UnionCase (ucref, tinst) -> p_byte 0 st; p_tup2 p_ucref p_tys (ucref, tinst) st + | DecisionTreeTest.Const c -> p_byte 1 st; p_const c st + | DecisionTreeTest.IsNull -> p_byte 2 st + | DecisionTreeTest.IsInst (srcty, tgty) -> p_byte 3 st; p_ty srcty st; p_ty tgty st + | DecisionTreeTest.ArrayLength (n, ty) -> p_byte 4 st; p_tup2 p_int p_ty (n, ty) st + | DecisionTreeTest.ActivePatternCase _ -> pfailwith st "DecisionTreeTest.ActivePatternCase: only used during pattern match compilation" + | DecisionTreeTest.Error _ -> pfailwith st "DecisionTreeTest.Error: only used during pattern match compilation" + +and p_target (TTarget(a, b, _, _)) st = p_tup2 p_Vals p_expr (a, b) st +and p_bind (TBind(a, b, _)) st = p_tup2 p_Val p_expr (a, b) st + +and p_lval_op_kind x st = + p_byte (match x with LAddrOf _ -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st + +and p_recdInfo x st = + match x with + | RecdExpr -> () + | RecdExprIsObjInit -> pfailwith st "explicit object constructors can't be inlined and should not have optimization information" + +and u_dtree st = + let tag = u_byte st + match tag with + | 0 -> + let a,b,c,d = u_tup4 u_expr (u_list u_dtree_case) (u_option u_dtree) u_dummy_range st + TDSwitch(DebugPointAtSwitch.No, a, b, c, d) + | 1 -> u_tup2 u_Exprs u_int st |> TDSuccess + | 2 -> u_tup2 u_bind u_dtree st |> TDBind + | _ -> ufailwith st "u_dtree" + +and u_dtree_case st = let a, b = u_tup2 u_dtree_discrim u_dtree st in (TCase(a, b)) + +and u_dtree_discrim st = + let tag = u_byte st + match tag with + | 0 -> u_tup2 u_ucref u_tys st |> DecisionTreeTest.UnionCase + | 1 -> u_const st |> DecisionTreeTest.Const + | 2 -> DecisionTreeTest.IsNull + | 3 -> u_tup2 u_ty u_ty st |> DecisionTreeTest.IsInst + | 4 -> u_tup2 u_int u_ty st |> DecisionTreeTest.ArrayLength + | _ -> ufailwith st "u_dtree_discrim" + +and u_target st = let a, b = u_tup2 u_Vals u_expr st in (TTarget(a, b, DebugPointAtTarget.No, None)) + +and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a, b, DebugPointAtBinding.NoneAtSticky) + +and u_lval_op_kind st = + match u_byte st with + | 0 -> LAddrOf false + | 1 -> LByrefGet + | 2 -> LSet + | 3 -> LByrefSet + | _ -> ufailwith st "uval_op_kind" + + +and p_op x st = + match x with + | TOp.UnionCase c -> p_byte 0 st; p_ucref c st + | TOp.ExnConstr c -> p_byte 1 st; p_tcref "op" c st + | TOp.Tuple tupInfo -> + if evalTupInfoIsStruct tupInfo then + p_byte 29 st + else + p_byte 2 st + | TOp.Recd (a, b) -> p_byte 3 st; p_tup2 p_recdInfo (p_tcref "recd op") (a, b) st + | TOp.ValFieldSet a -> p_byte 4 st; p_rfref a st + | TOp.ValFieldGet a -> p_byte 5 st; p_rfref a st + | TOp.UnionCaseTagGet a -> p_byte 6 st; p_tcref "cnstr op" a st + | TOp.UnionCaseFieldGet (a, b) -> p_byte 7 st; p_tup2 p_ucref p_int (a, b) st + | TOp.UnionCaseFieldSet (a, b) -> p_byte 8 st; p_tup2 p_ucref p_int (a, b) st + | TOp.ExnFieldGet (a, b) -> p_byte 9 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.ExnFieldSet (a, b) -> p_byte 10 st; p_tup2 (p_tcref "exn op") p_int (a, b) st + | TOp.TupleFieldGet (tupInfo, a) -> + if evalTupInfoIsStruct tupInfo then + p_byte 30 st; p_int a st + else + p_byte 11 st; p_int a st + | TOp.ILAsm (a, b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_tys (a, b) st + | TOp.RefAddrGet _ -> p_byte 13 st + | TOp.UnionCaseProof a -> p_byte 14 st; p_ucref a st + | TOp.Coerce -> p_byte 15 st + | TOp.TraitCall b -> p_byte 16 st; p_trait b st + | TOp.LValueOp (a, b) -> p_byte 17 st; p_tup2 p_lval_op_kind (p_vref "lval") (a, b) st + | TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + -> p_byte 18 st; p_tup11 p_bool p_bool p_bool p_bool p_vrefFlags p_bool p_bool p_ILMethodRef p_tys p_tys p_tys (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) st + | TOp.Array -> p_byte 19 st + | TOp.While _ -> p_byte 20 st + | TOp.For (_, dir) -> p_byte 21 st; p_int (match dir with FSharpForLoopUp -> 0 | CSharpForLoopUp -> 1 | FSharpForLoopDown -> 2) st + | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st + | TOp.TryWith _ -> p_byte 23 st + | TOp.TryFinally _ -> p_byte 24 st + | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st + | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st + | TOp.Reraise -> p_byte 27 st + | TOp.UnionCaseFieldGetAddr (a, b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a, b) st + // Note tag byte 29 is taken for struct tuples, see above + // Note tag byte 30 is taken for struct tuples, see above + (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) + (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) + | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st + | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st + | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" + +and u_op st = + let tag = u_byte st + match tag with + | 0 -> let a = u_ucref st + TOp.UnionCase a + | 1 -> let a = u_tcref st + TOp.ExnConstr a + | 2 -> TOp.Tuple tupInfoRef + | 3 -> let b = u_tcref st + TOp.Recd (RecdExpr, b) + | 4 -> let a = u_rfref st + TOp.ValFieldSet a + | 5 -> let a = u_rfref st + TOp.ValFieldGet a + | 6 -> let a = u_tcref st + TOp.UnionCaseTagGet a + | 7 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGet (a, b) + | 8 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldSet (a, b) + | 9 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldGet (a, b) + | 10 -> let a = u_tcref st + let b = u_int st + TOp.ExnFieldSet (a, b) + | 11 -> let a = u_int st + TOp.TupleFieldGet (tupInfoRef, a) + | 12 -> let a = (u_list u_ILInstr) st + let b = u_tys st + TOp.ILAsm (a, b) + | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes + | 14 -> let a = u_ucref st + TOp.UnionCaseProof a + | 15 -> TOp.Coerce + | 16 -> let a = u_trait st + TOp.TraitCall a + | 17 -> let a = u_lval_op_kind st + let b = u_vref st + TOp.LValueOp (a, b) + | 18 -> let a1, a2, a3, a4, a5, a7, a8, a9 = (u_tup8 u_bool u_bool u_bool u_bool u_vrefFlags u_bool u_bool u_ILMethodRef) st + let b = u_tys st + let c = u_tys st + let d = u_tys st + TOp.ILCall (a1, a2, a3, a4, a5, a7, a8, a9, b, c, d) + | 19 -> TOp.Array + | 20 -> TOp.While (DebugPointAtWhile.No, NoSpecialWhileLoopMarker) + | 21 -> let dir = match u_int st with 0 -> FSharpForLoopUp | 1 -> CSharpForLoopUp | 2 -> FSharpForLoopDown | _ -> failwith "unknown for loop" + TOp.For (DebugPointAtFor.No, dir) + | 22 -> TOp.Bytes (u_bytes st) + | 23 -> TOp.TryWith (DebugPointAtTry.No, DebugPointAtWith.No) + | 24 -> TOp.TryFinally (DebugPointAtTry.No, DebugPointAtFinally.No) + | 25 -> let a = u_rfref st + TOp.ValFieldGetAddr (a, false) + | 26 -> TOp.UInt16s (u_array u_uint16 st) + | 27 -> TOp.Reraise + | 28 -> let a = u_ucref st + let b = u_int st + TOp.UnionCaseFieldGetAddr (a, b, false) + | 29 -> TOp.Tuple tupInfoStruct + | 30 -> let a = u_int st + TOp.TupleFieldGet (tupInfoStruct, a) + | 31 -> let info = u_anonInfo st + TOp.AnonRecd info + | 32 -> let info = u_anonInfo st + let n = u_int st + TOp.AnonRecdGet (info, n) + | _ -> ufailwith st "u_op" + +and p_expr expr st = + match expr with + | Expr.Link e -> p_expr !e st + | Expr.Const (x, m, ty) -> p_byte 0 st; p_tup3 p_const p_dummy_range p_ty (x, m, ty) st + | Expr.Val (a, b, m) -> p_byte 1 st; p_tup3 (p_vref "val") p_vrefFlags p_dummy_range (a, b, m) st + | Expr.Op (a, b, c, d) -> p_byte 2 st; p_tup4 p_op p_tys p_Exprs p_dummy_range (a, b, c, d) st + | Expr.Sequential (a, b, c, _, d) -> p_byte 3 st; p_tup4 p_expr p_expr p_int p_dummy_range (a, b, (match c with NormalSeq -> 0 | ThenDoSeq -> 1), d) st + | Expr.Lambda (_, a1, b0, b1, c, d, e) -> p_byte 4 st; p_tup6 (p_option p_Val) (p_option p_Val) p_Vals p_expr p_dummy_range p_ty (a1, b0, b1, c, d, e) st + | Expr.TyLambda (_, b, c, d, e) -> p_byte 5 st; p_tup4 p_tyar_specs p_expr p_dummy_range p_ty (b, c, d, e) st + | Expr.App (a1, a2, b, c, d) -> p_byte 6 st; p_tup5 p_expr p_ty p_tys p_Exprs p_dummy_range (a1, a2, b, c, d) st + | Expr.LetRec (a, b, c, _) -> p_byte 7 st; p_tup3 p_binds p_expr p_dummy_range (a, b, c) st + | Expr.Let (a, b, c, _) -> p_byte 8 st; p_tup3 p_bind p_expr p_dummy_range (a, b, c) st + | Expr.Match (_, a, b, c, d, e) -> p_byte 9 st; p_tup5 p_dummy_range p_dtree p_targets p_dummy_range p_ty (a, b, c, d, e) st + | Expr.Obj (_, b, c, d, e, f, g) -> p_byte 10 st; p_tup6 p_ty (p_option p_Val) p_expr p_methods p_intfs p_dummy_range (b, c, d, e, f, g) st + | Expr.StaticOptimization (a, b, c, d) -> p_byte 11 st; p_tup4 p_constraints p_expr p_expr p_dummy_range (a, b, c, d) st + | Expr.TyChoose (a, b, c) -> p_byte 12 st; p_tup3 p_tyar_specs p_expr p_dummy_range (a, b, c) st + | Expr.Quote (ast, _, _, m, ty) -> p_byte 13 st; p_tup3 p_expr p_dummy_range p_ty (ast, m, ty) st + | Expr.WitnessArg (traitInfo, m) -> p_byte 14 st; p_trait traitInfo st; p_dummy_range m st + +and u_expr st = + let tag = u_byte st + match tag with + | 0 -> let a = u_const st + let b = u_dummy_range st + let c = u_ty st + Expr.Const (a, b, c) + | 1 -> let a = u_vref st + let b = u_vrefFlags st + let c = u_dummy_range st + Expr.Val (a, b, c) + | 2 -> let a = u_op st + let b = u_tys st + let c = u_Exprs st + let d = u_dummy_range st + Expr.Op (a, b, c, d) + | 3 -> let a = u_expr st + let b = u_expr st + let c = u_int st + let d = u_dummy_range st + let dir = match c with 0 -> NormalSeq | 1 -> ThenDoSeq | _ -> ufailwith st "specialSeqFlag" + Expr.Sequential (a, b, dir, DebugPointAtSequential.SuppressStmt, d) + | 4 -> let a0 = u_option u_Val st + let b0 = u_option u_Val st + let b1 = u_Vals st + let c = u_expr st + let d = u_dummy_range st + let e = u_ty st + Expr.Lambda (newUnique(), a0, b0, b1, c, d, e) + | 5 -> let b = u_tyar_specs st + let c = u_expr st + let d = u_dummy_range st + let e = u_ty st + Expr.TyLambda (newUnique(), b, c, d, e) + | 6 -> let a1 = u_expr st + let a2 = u_ty st + let b = u_tys st + let c = u_Exprs st + let d = u_dummy_range st + Expr.App (a1, a2, b, c, d) + | 7 -> let a = u_binds st + let b = u_expr st + let c = u_dummy_range st + Expr.LetRec (a, b, c, Construct.NewFreeVarsCache()) + | 8 -> let a = u_bind st + let b = u_expr st + let c = u_dummy_range st + Expr.Let (a, b, c, Construct.NewFreeVarsCache()) + | 9 -> let a = u_dummy_range st + let b = u_dtree st + let c = u_targets st + let d = u_dummy_range st + let e = u_ty st + Expr.Match (DebugPointAtBinding.NoneAtSticky, a, b, c, d, e) + | 10 -> let b = u_ty st + let c = (u_option u_Val) st + let d = u_expr st + let e = u_methods st + let f = u_intfs st + let g = u_dummy_range st + Expr.Obj (newUnique(), b, c, d, e, f, g) + | 11 -> let a = u_constraints st + let b = u_expr st + let c = u_expr st + let d = u_dummy_range st + Expr.StaticOptimization (a, b, c, d) + | 12 -> let a = u_tyar_specs st + let b = u_expr st + let c = u_dummy_range st + Expr.TyChoose (a, b, c) + | 13 -> let b = u_expr st + let c = u_dummy_range st + let d = u_ty st + Expr.Quote (b, ref None, false, c, d) // isFromQueryExpression=false + | 14 -> + let traitInfo = u_trait st + let m = u_dummy_range st + Expr.WitnessArg (traitInfo, m) + | _ -> ufailwith st "u_expr" + +and p_static_optimization_constraint x st = + match x with + | TTyconEqualsTycon (a, b) -> p_byte 0 st; p_tup2 p_ty p_ty (a, b) st + | TTyconIsStruct a -> p_byte 1 st; p_ty a st + +and p_slotparam (TSlotParam (a, b, c, d, e, f)) st = p_tup6 (p_option p_string) p_ty p_bool p_bool p_bool p_attribs (a, b, c, d, e, f) st +and p_slotsig (TSlotSig (a, b, c, d, e, f)) st = p_tup6 p_string p_ty p_tyar_specs p_tyar_specs (p_list (p_list p_slotparam)) (p_option p_ty) (a, b, c, d, e, f) st +and p_method (TObjExprMethod (a, b, c, d, e, f)) st = p_tup6 p_slotsig p_attribs p_tyar_specs (p_list p_Vals) p_expr p_dummy_range (a, b, c, d, e, f) st +and p_methods x st = p_list p_method x st +and p_intf x st = p_tup2 p_ty p_methods x st +and p_intfs x st = p_list p_intf x st + +and u_static_optimization_constraint st = + let tag = u_byte st + match tag with + | 0 -> u_tup2 u_ty u_ty st |> TTyconEqualsTycon + | 1 -> u_ty st |> TTyconIsStruct + | _ -> ufailwith st "u_static_optimization_constraint" + +and u_slotparam st = + let a, b, c, d, e, f = u_tup6 (u_option u_string) u_ty u_bool u_bool u_bool u_attribs st + TSlotParam(a, b, c, d, e, f) + +and u_slotsig st = + let a, b, c, d, e, f = u_tup6 u_string u_ty u_tyar_specs u_tyar_specs (u_list (u_list u_slotparam)) (u_option u_ty) st + TSlotSig(a, b, c, d, e, f) + +and u_method st = + let a, b, c, d, e, f = u_tup6 u_slotsig u_attribs u_tyar_specs (u_list u_Vals) u_expr u_dummy_range st + TObjExprMethod(a, b, c, d, e, f) + +and u_methods st = u_list u_method st + +and u_intf st = u_tup2 u_ty u_methods st + +and u_intfs st = u_list u_intf st + +let _ = fill_p_binds (p_List p_bind) +let _ = fill_p_targets (p_array p_target) +let _ = fill_p_constraints (p_list p_static_optimization_constraint) +let _ = fill_p_Exprs (p_list p_expr) +let _ = fill_p_Expr_hole p_expr +let _ = fill_p_Exprs (p_List p_expr) +let _ = fill_p_attribs (p_list p_attrib) +let _ = fill_p_Vals (p_list p_Val) + +let _ = fill_u_binds (u_List u_bind) +let _ = fill_u_targets (u_array u_target) +let _ = fill_u_constraints (u_list u_static_optimization_constraint) +let _ = fill_u_Exprs (u_list u_expr) +let _ = fill_u_Expr_hole u_expr +let _ = fill_u_attribs (u_list u_attrib) +let _ = fill_u_Vals (u_list u_Val) + +//--------------------------------------------------------------------------- +// Pickle/unpickle F# interface data +//--------------------------------------------------------------------------- + +let pickleModuleOrNamespace mspec st = p_entity_spec mspec st + +let pickleCcuInfo (minfo: PickledCcuInfo) st = + p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations, ()) st + +let unpickleModuleOrNamespace st = u_entity_spec st + +let unpickleCcuInfo st = + let a, b, c, _space = u_tup4 unpickleModuleOrNamespace u_string u_bool (u_space 3) st + { mspec=a; compileTimeWorkingDir=b; usesQuotations=c } diff --git a/src/fsharp/TypedTreePickle.fsi b/src/fsharp/TypedTreePickle.fsi new file mode 100644 index 00000000000..a0b7d717ef9 --- /dev/null +++ b/src/fsharp/TypedTreePickle.fsi @@ -0,0 +1,146 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines the framework for serializing and de-serializing TAST data structures as binary blobs for the F# metadata format. +module internal FSharp.Compiler.TypedTreePickle + +open FSharp.Compiler.IO +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TcGlobals + +/// Represents deserialized data with a dangling set of CCU fixup thunks indexed by name +[] +type PickledDataWithReferences<'RawData> = + { + /// The data that uses a collection of CcuThunks internally + RawData: 'RawData + + /// The assumptions that need to be fixed up + FixupThunks: CcuThunk [] + } + + member Fixup : (CcuReference -> CcuThunk) -> 'RawData + + /// Like Fixup but loader may return None, in which case there is no fixup. + member OptionalFixup: (CcuReference -> CcuThunk option) -> 'RawData + +/// The type of state written to by picklers +type WriterState + +/// A function to pickle a value into a given stateful writer +type pickler<'T> = 'T -> WriterState -> unit + +/// Serialize a byte +val internal p_byte : int -> WriterState -> unit + +/// Serialize a boolean value +val internal p_bool : bool -> WriterState -> unit + +/// Serialize an integer +val internal p_int : int -> WriterState -> unit + +/// Serialize a string +val internal p_string : string -> WriterState -> unit + +/// Serialize a lazy value (eagerly) +val internal p_lazy : pickler<'T> -> Lazy<'T> pickler + +/// Serialize a tuple of data +val inline internal p_tup2 : pickler<'T1> -> pickler<'T2> -> pickler<'T1 * 'T2> + +/// Serialize a tuple of data +val inline internal p_tup3 : pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T1 * 'T2 * 'T3> + +/// Serialize a tuple of data +val inline internal p_tup4 : pickler<'T1> -> pickler<'T2> -> pickler<'T3> -> pickler<'T4> -> pickler<'T1 * 'T2 * 'T3 * 'T4> + +/// Serialize an array of data +val internal p_array : pickler<'T> -> pickler<'T[]> + +/// Serialize a namemap of data +val internal p_namemap : pickler<'T> -> pickler> + +/// Serialize a TAST constant +val internal p_const : pickler + +/// Serialize a TAST value reference +val internal p_vref : string -> pickler + +/// Serialize a TAST type or entity reference +val internal p_tcref : string -> pickler + +/// Serialize a TAST union case reference +val internal p_ucref : pickler + +/// Serialize a TAST expression +val internal p_expr : pickler + +/// Serialize a TAST type +val internal p_ty : pickler + +/// Serialize a TAST description of a compilation unit +val internal pickleCcuInfo : pickler + +/// Serialize an arbitrary object using the given pickler +val pickleObjWithDanglingCcus : inMem: bool -> file: string -> TcGlobals -> scope:CcuThunk -> pickler<'T> -> 'T -> ByteBuffer + +/// The type of state unpicklers read from +type ReaderState + +/// A function to read a value from a given state +type unpickler<'T> = ReaderState -> 'T + +/// Deserialize a byte +val internal u_byte : ReaderState -> int + +/// Deserialize a bool +val internal u_bool : ReaderState -> bool + +/// Deserialize an integer +val internal u_int : ReaderState -> int + +/// Deserialize a string +val internal u_string : ReaderState -> string + +/// Deserialize a lazy value (eagerly) +val internal u_lazy : unpickler<'T> -> unpickler> + +/// Deserialize a tuple +val inline internal u_tup2 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T2 * 'T3> + +/// Deserialize a tuple +val inline internal u_tup3 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T2 * 'T3 * 'T4> + +/// Deserialize a tuple +val inline internal u_tup4 : unpickler<'T2> -> unpickler<'T3> -> unpickler<'T4> -> unpickler<'T5> -> unpickler<'T2 * 'T3 * 'T4 * 'T5> + +/// Deserialize an array of values +val internal u_array : unpickler<'T> -> unpickler<'T[]> + +/// Deserialize a namemap +val internal u_namemap : unpickler<'T> -> unpickler> + +/// Deserialize a TAST constant +val internal u_const : unpickler + +/// Deserialize a TAST value reference +val internal u_vref : unpickler + +/// Deserialize a TAST type reference +val internal u_tcref : unpickler + +/// Deserialize a TAST union case reference +val internal u_ucref : unpickler + +/// Deserialize a TAST expression +val internal u_expr : unpickler + +/// Deserialize a TAST type +val internal u_ty : unpickler + +/// Deserialize a TAST description of a compilation unit +val internal unpickleCcuInfo : ReaderState -> PickledCcuInfo + +/// Deserialize an arbitrary object which may have holes referring to other compilation units +val internal unpickleObjWithDanglingCcus : file:string -> viewedScope:ILScopeRef -> ilModule:ILModuleDef option -> 'T unpickler -> ReadOnlyByteMemory -> PickledDataWithReferences<'T> diff --git a/src/fsharp/UnicodeLexing.fs b/src/fsharp/UnicodeLexing.fs index 70a253da1b6..e828d9fe56f 100644 --- a/src/fsharp/UnicodeLexing.fs +++ b/src/fsharp/UnicodeLexing.fs @@ -1,30 +1,25 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +/// Functions for Unicode char-based lexing module internal FSharp.Compiler.UnicodeLexing -//------------------------------------------------------------------ -// Functions for Unicode char-based lexing (new code). -// - -open FSharp.Compiler.AbstractIL.Internal.Library open System.IO - open Internal.Utilities.Text.Lexing type Lexbuf = LexBuffer -let StringAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, s:string) : Lexbuf = - LexBuffer<_>.FromChars (supportsFeature, s.ToCharArray()) +let StringAsLexbuf (reportLibraryOnlyFeatures, langVersion, s: string) = + LexBuffer.FromChars (reportLibraryOnlyFeatures, langVersion, s.ToCharArray()) -let FunctionAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, bufferFiller: char[] * int * int -> int) : Lexbuf = - LexBuffer<_>.FromFunction(supportsFeature, bufferFiller) +let FunctionAsLexbuf (reportLibraryOnlyFeatures, langVersion, bufferFiller) = + LexBuffer.FromFunction(reportLibraryOnlyFeatures, langVersion, bufferFiller) -let SourceTextAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, sourceText) = - LexBuffer.FromSourceText(supportsFeature, sourceText) +let SourceTextAsLexbuf (reportLibraryOnlyFeatures, langVersion, sourceText) = + LexBuffer.FromSourceText(reportLibraryOnlyFeatures, langVersion, sourceText) -let StreamReaderAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, reader: StreamReader) = +let StreamReaderAsLexbuf (reportLibraryOnlyFeatures, langVersion, reader: StreamReader) = let mutable isFinished = false - FunctionAsLexbuf (supportsFeature, fun (chars, start, length) -> + FunctionAsLexbuf (reportLibraryOnlyFeatures, langVersion, fun (chars, start, length) -> if isFinished then 0 else let nBytesRead = reader.Read(chars, start, length) diff --git a/src/fsharp/UnicodeLexing.fsi b/src/fsharp/UnicodeLexing.fsi index a3f0fb8fb32..a63cc4d6bb2 100644 --- a/src/fsharp/UnicodeLexing.fsi +++ b/src/fsharp/UnicodeLexing.fsi @@ -5,13 +5,15 @@ module internal FSharp.Compiler.UnicodeLexing open System.IO open FSharp.Compiler.Features open FSharp.Compiler.Text -open Microsoft.FSharp.Text open Internal.Utilities.Text.Lexing -type Lexbuf = LexBuffer -val internal StringAsLexbuf: (Features.LanguageFeature -> bool) * string -> Lexbuf -val public FunctionAsLexbuf: (Features.LanguageFeature -> bool) * (char [] * int * int -> int) -> Lexbuf -val public SourceTextAsLexbuf: (Features.LanguageFeature -> bool) * ISourceText -> Lexbuf +type Lexbuf = LexBuffer + +val internal StringAsLexbuf: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * string -> Lexbuf + +val public FunctionAsLexbuf: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * (char [] * int * int -> int) -> Lexbuf + +val public SourceTextAsLexbuf: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * ISourceText -> Lexbuf /// Will not dispose of the stream reader. -val public StreamReaderAsLexbuf: (Features.LanguageFeature -> bool) * StreamReader -> Lexbuf +val public StreamReaderAsLexbuf: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * StreamReader -> Lexbuf diff --git a/src/fsharp/XmlAdapters.fs b/src/fsharp/XmlAdapters.fs index 2e04733fc18..f4bde8561b7 100644 --- a/src/fsharp/XmlAdapters.fs +++ b/src/fsharp/XmlAdapters.fs @@ -1,19 +1,18 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace Microsoft.FSharp.Core +module internal Internal.Utilities.XmlAdapters //Replacement for: System.Security.SecurityElement.Escape(line) All platforms -module internal XmlAdapters = - let s_escapeChars = [| '<'; '>'; '\"'; '\''; '&' |] +let s_escapeChars = [| '<'; '>'; '\"'; '\''; '&' |] - let getEscapeSequence c = - match c with - | '<' -> "<" - | '>' -> ">" - | '\"' -> """ - | '\'' -> "'" - | '&' -> "&" - | _ as ch -> ch.ToString() +let getEscapeSequence c = + match c with + | '<' -> "<" + | '>' -> ">" + | '\"' -> """ + | '\'' -> "'" + | '&' -> "&" + | _ as ch -> ch.ToString() - let escape str = String.collect getEscapeSequence str +let escape str = String.collect getEscapeSequence str diff --git a/src/fsharp/XmlAdapters.fsi b/src/fsharp/XmlAdapters.fsi new file mode 100644 index 00000000000..eb45763930c --- /dev/null +++ b/src/fsharp/XmlAdapters.fsi @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal Internal.Utilities.XmlAdapters + + val s_escapeChars : char [] + + val getEscapeSequence : c:char -> string + + val escape : str:string -> string diff --git a/src/fsharp/XmlDoc.fs b/src/fsharp/XmlDoc.fs new file mode 100644 index 00000000000..3a30e6033c8 --- /dev/null +++ b/src/fsharp/XmlDoc.fs @@ -0,0 +1,279 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.Xml + +open System +open System.IO +open System.Xml +open System.Xml.Linq +open Internal.Utilities.Library +open Internal.Utilities.Collections +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.AbstractIL.IL + +/// Represents collected XmlDoc lines +[] +type XmlDoc(unprocessedLines: string[], range: range) = + let rec processLines (lines: string list) = + match lines with + | [] -> [] + | lineA :: rest as lines -> + let lineAT = lineA.TrimStart([|' '|]) + if lineAT = "" then processLines rest + elif lineAT.StartsWithOrdinal("<") then lines + else + [""] @ + (lines |> List.map Internal.Utilities.XmlAdapters.escape) @ + [""] + + /// Get the lines before insertion of implicit summary tags and encoding + member _.UnprocessedLines = unprocessedLines + + /// Get the lines after insertion of implicit summary tags and encoding + member _.GetElaboratedXmlLines() = + let processedLines = processLines (Array.toList unprocessedLines) + + let lines = Array.ofList processedLines + + lines + + member _.Range = range + + static member Empty = XmlDocStatics.Empty + + member _.IsEmpty = + unprocessedLines |> Array.forall String.IsNullOrWhiteSpace + + member doc.NonEmpty = not doc.IsEmpty + + static member Merge (doc1: XmlDoc) (doc2: XmlDoc) = + XmlDoc(Array.append doc1.UnprocessedLines doc2.UnprocessedLines, + unionRanges doc1.Range doc2.Range) + + member doc.GetXmlText() = + if doc.IsEmpty then "" + else + doc.GetElaboratedXmlLines() + |> String.concat Environment.NewLine + + member doc.Check(paramNamesOpt: string list option) = + try + // We must wrap with in order to have only one root element + let xml = + XDocument.Parse("\n"+doc.GetXmlText()+"\n", + LoadOptions.SetLineInfo ||| LoadOptions.PreserveWhitespace) + + // The parameter names are checked for consistency, so parameter references and + // parameter documentation must match an actual parameter. In addition, if any parameters + // have documentation then all parameters must have documentation + match paramNamesOpt with + | None -> () + | Some paramNames -> + for p in xml.Descendants(XName.op_Implicit "param") do + match p.Attribute(XName.op_Implicit "name") with + | null -> + warning (Error (FSComp.SR.xmlDocMissingParameterName(), doc.Range)) + | attr -> + let nm = attr.Value + if not (paramNames |> List.contains nm) then + warning (Error (FSComp.SR.xmlDocInvalidParameterName(nm), doc.Range)) + + let paramsWithDocs = + [ for p in xml.Descendants(XName.op_Implicit "param") do + match p.Attribute(XName.op_Implicit "name") with + | null -> () + | attr -> attr.Value ] + + if paramsWithDocs.Length > 0 then + for p in paramNames do + if not (paramsWithDocs |> List.contains p) then + warning (Error (FSComp.SR.xmlDocMissingParameter(p), doc.Range)) + + let duplicates = paramsWithDocs |> List.duplicates + + for d in duplicates do + warning (Error (FSComp.SR.xmlDocDuplicateParameter(d), doc.Range)) + + for pref in xml.Descendants(XName.op_Implicit "paramref") do + match pref.Attribute(XName.op_Implicit "name") with + | null -> warning (Error (FSComp.SR.xmlDocMissingParameterName(), doc.Range)) + | attr -> + let nm = attr.Value + if not (paramNames |> List.contains nm) then + warning (Error (FSComp.SR.xmlDocInvalidParameterName(nm), doc.Range)) + + with e -> + warning (Error (FSComp.SR.xmlDocBadlyFormed(e.Message), doc.Range)) + +#if CREF_ELABORATION + member doc.Elaborate (crefResolver) = + for see in seq { yield! xml.Descendants(XName.op_Implicit "see") + yield! xml.Descendants(XName.op_Implicit "seealso") + yield! xml.Descendants(XName.op_Implicit "exception") } do + match see.Attribute(XName.op_Implicit "cref") with + | null -> warning (Error (FSComp.SR.xmlDocMissingCrossReference(), doc.Range)) + | attr -> + let cref = attr.Value + if cref.StartsWith("T:") || cref.StartsWith("P:") || cref.StartsWith("M:") || + cref.StartsWith("E:") || cref.StartsWith("F:") then + () + else + match crefResolver cref with + | None -> + warning (Error (FSComp.SR.xmlDocUnresolvedCrossReference(nm), doc.Range)) + | Some text -> + attr.Value <- text + modified <- true + if modified then + let m = doc.Range + let newLines = + [| for e in xml.Elements() do + yield! e.ToString().Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries) |] + lines <- newLines +#endif + +// Discriminated unions can't contain statics, so we use a separate type +and XmlDocStatics() = + + static let empty = XmlDoc ([| |], range0) + + static member Empty = empty + +/// Used to collect XML documentation during lexing and parsing. +type XmlDocCollector() = + let mutable savedLines = ResizeArray() + let mutable savedGrabPoints = ResizeArray() + let posCompare p1 p2 = if posGeq p1 p2 then 1 else if posEq p1 p2 then 0 else -1 + let savedGrabPointsAsArray = + lazy (savedGrabPoints.ToArray() |> Array.sortWith posCompare) + + let savedLinesAsArray = + lazy (savedLines.ToArray() |> Array.sortWith (fun (_, p1) (_, p2) -> posCompare p1.End p2.End)) + + let check() = + // can't add more XmlDoc elements to XmlDocCollector after extracting first XmlDoc from the overall results + assert (not savedLinesAsArray.IsValueCreated) + + member x.AddGrabPoint pos = + check() + savedGrabPoints.Add pos + + member x.AddXmlDocLine(line, range) = + check() + savedLines.Add(line, range) + + member x.LinesBefore grabPointPos = + try + let lines = savedLinesAsArray.Force() + let grabPoints = savedGrabPointsAsArray.Force() + let firstLineIndexAfterGrabPoint = Array.findFirstIndexWhereTrue lines (fun (_, m) -> posGeq m.End grabPointPos) + let grabPointIndex = Array.findFirstIndexWhereTrue grabPoints (fun pos -> posGeq pos grabPointPos) + assert (posEq grabPoints.[grabPointIndex] grabPointPos) + let firstLineIndexAfterPrevGrabPoint = + if grabPointIndex = 0 then + 0 + else + let prevGrabPointPos = grabPoints.[grabPointIndex-1] + Array.findFirstIndexWhereTrue lines (fun (_, m) -> posGeq m.End prevGrabPointPos) + + let lines = lines.[firstLineIndexAfterPrevGrabPoint..firstLineIndexAfterGrabPoint-1] + lines + with e -> + [| |] + +/// Represents the XmlDoc fragments as collected from the lexer during parsing +type PreXmlDoc = + | PreXmlDirect of unprocessedLines: string[] * range: range + | PreXmlMerge of PreXmlDoc * PreXmlDoc + | PreXmlDoc of pos * XmlDocCollector + | PreXmlDocEmpty + + member x.ToXmlDoc(check: bool, paramNamesOpt: string list option) = + match x with + | PreXmlDirect (lines, m) -> XmlDoc(lines, m) + | PreXmlMerge(a, b) -> XmlDoc.Merge (a.ToXmlDoc(check, paramNamesOpt)) (b.ToXmlDoc(check, paramNamesOpt)) + | PreXmlDocEmpty -> XmlDoc.Empty + | PreXmlDoc (pos, collector) -> + let preLines = collector.LinesBefore pos + if preLines.Length = 0 then + XmlDoc.Empty + else + let lines = Array.map fst preLines + let m = Array.reduce unionRanges (Array.map snd preLines) + let doc = XmlDoc (lines, m) + if check then + doc.Check(paramNamesOpt) + doc + + static member CreateFromGrabPoint(collector: XmlDocCollector, grabPointPos) = + collector.AddGrabPoint grabPointPos + PreXmlDoc(grabPointPos, collector) + + static member Empty = PreXmlDocEmpty + + static member Create(unprocessedLines, range) = PreXmlDirect(unprocessedLines, range) + + static member Merge a b = PreXmlMerge (a, b) + +[] +type XmlDocumentationInfo private (tryGetXmlDocument: unit -> XmlDocument option) = + + // 2 and 4 are arbitrary but should be reasonable enough + [] + static let cacheStrongSize = 2 + [] + static let cacheMaxSize = 4 + static let cacheAreSimilar = + fun ((str1: string, dt1: DateTime), (str2: string, dt2: DateTime)) -> + str1.Equals(str2, StringComparison.OrdinalIgnoreCase) && + dt1 = dt2 + static let cache = AgedLookup(keepStrongly=cacheStrongSize, areSimilar=cacheAreSimilar, keepMax=cacheMaxSize) + + let tryGetSummaryNode xmlDocSig = + tryGetXmlDocument() + |> Option.bind (fun doc -> + match doc.SelectSingleNode(sprintf "doc/members/member[@name='%s']" xmlDocSig) with + | null -> None + | node when node.HasChildNodes -> Some node + | _ -> None) + + member _.TryGetXmlDocBySig(xmlDocSig: string) = + tryGetSummaryNode xmlDocSig + |> Option.map (fun node -> + let childNodes = node.ChildNodes + let lines = Array.zeroCreate childNodes.Count + for i = 0 to childNodes.Count - 1 do + let childNode = childNodes.[i] + lines.[i] <- childNode.OuterXml + XmlDoc(lines, range0) + ) + + static member TryCreateFromFile(xmlFileName: string) = + if not (FileSystem.FileExistsShim(xmlFileName)) || not (String.Equals(Path.GetExtension(xmlFileName), ".xml", StringComparison.OrdinalIgnoreCase)) then + None + else + let tryGetXmlDocument = + fun () -> + try + let lastWriteTime = FileSystem.GetLastWriteTimeShim(xmlFileName) + let cacheKey = (xmlFileName, lastWriteTime) + match cache.TryGet((), cacheKey) with + | Some doc -> Some doc + | _ -> + let doc = XmlDocument() + use xmlStream = FileSystem.OpenFileForReadShim(xmlFileName) + doc.Load(xmlStream) + cache.Put((), cacheKey, doc) + Some doc + with + | _ -> + None + Some(XmlDocumentationInfo(tryGetXmlDocument)) + +type IXmlDocumentationInfoLoader = + + abstract TryLoad : assemblyFileName: string * ILModuleDef -> XmlDocumentationInfo option diff --git a/src/fsharp/XmlDoc.fsi b/src/fsharp/XmlDoc.fsi new file mode 100644 index 00000000000..e451312f4a5 --- /dev/null +++ b/src/fsharp/XmlDoc.fsi @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.Xml + +open FSharp.Compiler.Text +open FSharp.Compiler.AbstractIL.IL + +/// Represents collected XmlDoc lines +[] +type public XmlDoc = + + new: unprocessedLines:string [] * range:range -> XmlDoc + + /// Merge two XML documentation + static member Merge: doc1:XmlDoc -> doc2:XmlDoc -> XmlDoc + + /// Check the XML documentation + member internal Check: paramNamesOpt:string list option -> unit + + /// Get the lines after insertion of implicit summary tags and encoding + member GetElaboratedXmlLines: unit -> string [] + + /// Get the elaborated XML documentation as XML text + member GetXmlText: unit -> string + + member IsEmpty: bool + + member NonEmpty: bool + + member Range: range + + /// Get the lines before insertion of implicit summary tags and encoding + member UnprocessedLines: string [] + + static member Empty: XmlDoc + +/// Used to collect XML documentation during lexing and parsing. +type internal XmlDocCollector = + + new: unit -> XmlDocCollector + + member AddGrabPoint: pos: pos -> unit + + member AddXmlDocLine: line:string * range:range -> unit + + member LinesBefore: grabPointPos: pos -> (string * range) [] + +/// Represents the XmlDoc fragments as collected from the lexer during parsing +[] +type public PreXmlDoc = + + static member internal CreateFromGrabPoint: collector:XmlDocCollector * grabPointPos: pos -> PreXmlDoc + + static member Merge: a:PreXmlDoc -> b:PreXmlDoc -> PreXmlDoc + + static member Create: unprocessedLines:string [] * range:range -> PreXmlDoc + + member ToXmlDoc: check:bool * paramNamesOpt:string list option -> XmlDoc + + static member Empty: PreXmlDoc + +[] +type internal XmlDocumentationInfo = + + member TryGetXmlDocBySig : xmlDocSig: string -> XmlDoc option + + static member TryCreateFromFile : xmlFileName: string -> XmlDocumentationInfo option + +type internal IXmlDocumentationInfoLoader = + + abstract TryLoad : assemblyFileName: string * ILModuleDef -> XmlDocumentationInfo option diff --git a/src/fsharp/XmlDocFileWriter.fs b/src/fsharp/XmlDocFileWriter.fs new file mode 100644 index 00000000000..60ec69d07ac --- /dev/null +++ b/src/fsharp/XmlDocFileWriter.fs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.XmlDocFileWriter + +open System.IO +open System.Reflection +open Internal.Utilities.Library +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +module XmlDocWriter = + + let hasDoc (doc: XmlDoc) = not doc.IsEmpty + + let ComputeXmlDocSigs (tcGlobals, generatedCcu: CcuThunk) = + let g = tcGlobals + let doValSig ptext (v: Val) = if hasDoc v.XmlDoc then v.XmlDocSig <- XmlDocSigOfVal g false ptext v + let doTyconSig ptext (tc: Tycon) = + if (hasDoc tc.XmlDoc) then tc.XmlDocSig <- XmlDocSigOfTycon [ptext; tc.CompiledName] + for vref in tc.MembersOfFSharpTyconSorted do + doValSig ptext vref.Deref + for uc in tc.UnionCasesArray do + if (hasDoc uc.XmlDoc) then uc.XmlDocSig <- XmlDocSigOfUnionCase [ptext; tc.CompiledName; uc.Id.idText] + for rf in tc.AllFieldsArray do + if (hasDoc rf.XmlDoc) then + rf.XmlDocSig <- + if tc.IsRecordTycon && (not rf.IsStatic) then + // represents a record field, which is exposed as a property + XmlDocSigOfProperty [ptext; tc.CompiledName; rf.Id.idText] + else + XmlDocSigOfField [ptext; tc.CompiledName; rf.Id.idText] + + let doModuleMemberSig path (m: ModuleOrNamespace) = m.XmlDocSig <- XmlDocSigOfSubModul [path] + (* moduleSpec - recurses *) + let rec doModuleSig path (mspec: ModuleOrNamespace) = + let mtype = mspec.ModuleOrNamespaceType + let path = + (* skip the first item in the path which is the assembly name *) + match path with + | None -> Some "" + | Some "" -> Some mspec.LogicalName + | Some p -> Some (p+"."+mspec.LogicalName) + let ptext = match path with None -> "" | Some t -> t + if mspec.IsModule then doModuleMemberSig ptext mspec + let vals = + mtype.AllValsAndMembers + |> Seq.toList + |> List.filter (fun x -> not x.IsCompilerGenerated) + |> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember) + List.iter (doModuleSig path) mtype.ModuleAndNamespaceDefinitions + List.iter (doTyconSig ptext) mtype.ExceptionDefinitions + List.iter (doValSig ptext) vals + List.iter (doTyconSig ptext) mtype.TypeDefinitions + + doModuleSig None generatedCcu.Contents + + let WriteXmlDocFile (assemblyName, generatedCcu: CcuThunk, xmlfile) = + if not (FileSystemUtils.hasSuffixCaseInsensitive "xml" xmlfile ) then + error(Error(FSComp.SR.docfileNoXmlSuffix(), Range.rangeStartup)) + + let mutable members = [] + let addMember id xmlDoc = + if hasDoc xmlDoc then + let doc = xmlDoc.GetXmlText() + members <- (id, doc) :: members + let doVal (v: Val) = addMember v.XmlDocSig v.XmlDoc + let doUnionCase (uc: UnionCase) = addMember uc.XmlDocSig uc.XmlDoc + let doField (rf: RecdField) = addMember rf.XmlDocSig rf.XmlDoc + let doTycon (tc: Tycon) = + addMember tc.XmlDocSig tc.XmlDoc + for vref in tc.MembersOfFSharpTyconSorted do + doVal vref.Deref + for uc in tc.UnionCasesArray do + doUnionCase uc + for rf in tc.AllFieldsArray do + doField rf + + let modulMember (m: ModuleOrNamespace) = addMember m.XmlDocSig m.XmlDoc + + let rec doModule (mspec: ModuleOrNamespace) = + let mtype = mspec.ModuleOrNamespaceType + if mspec.IsModule then modulMember mspec + let vals = + mtype.AllValsAndMembers + |> Seq.toList + |> List.filter (fun x -> not x.IsCompilerGenerated) + |> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember) + List.iter doModule mtype.ModuleAndNamespaceDefinitions + List.iter doTycon mtype.ExceptionDefinitions + List.iter doVal vals + List.iter doTycon mtype.TypeDefinitions + + doModule generatedCcu.Contents + + use os = FileSystem.OpenFileForWriteShim(xmlfile, FileMode.OpenOrCreate).GetWriter() + + fprintfn os "" + fprintfn os "" + fprintfn os "%s" assemblyName + fprintfn os "" + members |> List.iter (fun (id, doc) -> + fprintfn os "" id + fprintfn os "%s" doc + fprintfn os "") + fprintfn os "" + fprintfn os "" diff --git a/src/fsharp/XmlDocFileWriter.fsi b/src/fsharp/XmlDocFileWriter.fsi new file mode 100644 index 00000000000..23319eae40e --- /dev/null +++ b/src/fsharp/XmlDocFileWriter.fsi @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.XmlDocFileWriter + +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TcGlobals + +module XmlDocWriter = + + /// Writes the XML document signature to the XmlDocSig property of each + /// element (field, union case, etc) of the specified compilation unit. + /// The XmlDocSig is the unique identifier of this XmlDoc in the generated Xml documentation file. + /// The full format is described at https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/documentation-comments#id-string-format + val ComputeXmlDocSigs: tcGlobals: TcGlobals * generatedCcu: CcuThunk -> unit + + /// Writes the XmlDocSig property of each element (field, union case, etc) + /// of the specified compilation unit to an XML document in a new text file. + val WriteXmlDocFile: assemblyName: string * generatedCcu: CcuThunk * xmlfile: string -> unit diff --git a/src/fsharp/absil/bytes.fs b/src/fsharp/absil/bytes.fs new file mode 100644 index 00000000000..ef5556513c9 --- /dev/null +++ b/src/fsharp/absil/bytes.fs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Byte arrays +namespace FSharp.Compiler.IO + + + + diff --git a/src/fsharp/absil/bytes.fsi b/src/fsharp/absil/bytes.fsi new file mode 100644 index 00000000000..fe7d77679af --- /dev/null +++ b/src/fsharp/absil/bytes.fsi @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Blobs of bytes, cross-compiling +namespace FSharp.Compiler.IO + +open System.IO +open System.IO.MemoryMappedFiles + +module internal Bytes = + /// returned int will be 0 <= x <= 255 + val get: byte[] -> int -> int + val zeroCreate: int -> byte[] + /// each int must be 0 <= x <= 255 + val ofInt32Array: int[] -> byte[] + /// each int will be 0 <= x <= 255 + + val blit: byte[] -> int -> byte[] -> int -> int -> unit + + val stringAsUnicodeNullTerminated: string -> byte[] + val stringAsUtf8NullTerminated: string -> byte[] + +/// A view over bytes. +/// May be backed by managed or unmanaged memory, or memory mapped file. +[] +type ByteMemory = + + abstract Item: int -> byte with get + + abstract Length: int + + abstract ReadBytes: pos: int * count: int -> byte[] + + abstract ReadInt32: pos: int -> int + + abstract ReadUInt16: pos: int -> uint16 + + abstract ReadUtf8String: pos: int * count: int -> string + + abstract Slice: pos: int * count: int -> ByteMemory + + abstract CopyTo: Stream -> unit + + abstract Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit + + abstract ToArray: unit -> byte[] + + /// Get a stream representation of the backing memory. + /// Disposing this will not free up any of the backing memory. + abstract AsStream: unit -> Stream + + /// Get a stream representation of the backing memory. + /// Disposing this will not free up any of the backing memory. + /// Stream cannot be written to. + abstract AsReadOnlyStream: unit -> Stream + +[] +type ReadOnlyByteMemory = + + new: ByteMemory -> ReadOnlyByteMemory + + member Item: int -> byte with get + + member Length: int + + member ReadBytes: pos: int * count: int -> byte[] + + member ReadInt32: pos: int -> int + + member ReadUInt16: pos: int -> uint16 + + member ReadUtf8String: pos: int * count: int -> string + + member Slice: pos: int * count: int -> ReadOnlyByteMemory + + member CopyTo: Stream -> unit + + member Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit + + member ToArray: unit -> byte[] + + member AsStream: unit -> Stream + +[] +module MemoryMappedFileExtensions = + + type MemoryMappedFile with + + /// Create a memory mapped file based on the given ByteMemory's contents. + /// If the given ByteMemory's length is zero or a memory mapped file is not supported, the result will be None. + static member TryFromByteMemory : bytes: ReadOnlyByteMemory -> MemoryMappedFile option + +type ByteMemory with + + member AsReadOnly: unit -> ReadOnlyByteMemory + + /// Empty byte memory. + static member Empty: ByteMemory + + /// Create a ByteMemory object that has a backing memory mapped file. + static member FromMemoryMappedFile: MemoryMappedFile -> ByteMemory + + /// Creates a ByteMemory object that has a backing memory mapped file from a file on-disk. + static member FromFile: path: string * FileAccess * ?canShadowCopy: bool -> ByteMemory + + /// Creates a ByteMemory object that is backed by a raw pointer. + /// Use with care. + static member FromUnsafePointer: addr: nativeint * length: int * holder: obj -> ByteMemory + + /// Creates a ByteMemory object that is backed by a byte array with the specified offset and length. + static member FromArray: bytes: byte[] * offset: int * length: int -> ByteMemory + + /// Creates a ByteMemory object that is backed by a byte array. + static member FromArray: bytes: byte[] -> ByteMemory + +/// Imperative buffers and streams of byte[] +[] +type internal ByteBuffer = + member Close : unit -> byte[] + member EmitIntAsByte : int -> unit + member EmitIntsAsBytes : int[] -> unit + member EmitByte : byte -> unit + member EmitBytes : byte[] -> unit + member EmitByteMemory : ReadOnlyByteMemory -> unit + member EmitInt32 : int32 -> unit + member EmitInt64 : int64 -> unit + member FixupInt32 : pos: int -> value: int32 -> unit + member EmitInt32AsUInt16 : int32 -> unit + member EmitBoolAsByte : bool -> unit + member EmitUInt16 : uint16 -> unit + member Position : int + static member Create : int -> ByteBuffer + + +[] +type internal ByteStream = + member ReadByte : unit -> byte + member ReadBytes : int -> ReadOnlyByteMemory + member ReadUtf8String : int -> string + member Position : int + static member FromBytes : ReadOnlyByteMemory * start:int * length:int -> ByteStream + +#if LAZY_UNPICKLE + member CloneAndSeek : int -> ByteStream + member Skip : int -> unit +#endif + +[] +type internal ByteStorage = + + member GetByteMemory : unit -> ReadOnlyByteMemory + + /// Creates a ByteStorage whose backing bytes are the given ByteMemory. Does not make a copy. + static member FromByteMemory : ReadOnlyByteMemory -> ByteStorage + + /// Creates a ByteStorage whose backing bytes are the given byte array. Does not make a copy. + static member FromByteArray : byte [] -> ByteStorage + + /// Creates a ByteStorage that has a copy of the given ByteMemory. + static member FromByteMemoryAndCopy : ReadOnlyByteMemory * useBackingMemoryMappedFile: bool -> ByteStorage + + /// Creates a ByteStorage that has a copy of the given byte array. + static member FromByteArrayAndCopy : byte [] * useBackingMemoryMappedFile: bool -> ByteStorage \ No newline at end of file diff --git a/src/absil/il.fs b/src/fsharp/absil/il.fs similarity index 89% rename from src/absil/il.fs rename to src/fsharp/absil/il.fs index 7e27e71da2a..e93cda242a9 100644 --- a/src/absil/il.fs +++ b/src/fsharp/absil/il.fs @@ -2,47 +2,28 @@ module FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.IO + #nowarn "49" #nowarn "343" // The type 'ILAssemblyRef' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'. #nowarn "346" // The struct, record or union type 'IlxExtensionType' has an explicit implementation of 'Object.Equals'. ... open System open System.Diagnostics -open System.IO open System.Collections open System.Collections.Generic open System.Collections.Concurrent +open System.Collections.ObjectModel open System.Reflection open System.Text open System.Threading -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library - +open Internal.Utilities.Library open Internal.Utilities let logging = false -let runningOnMono = -#if ENABLE_MONO_SUPPORT -// Officially supported way to detect if we are running on Mono. -// See http://www.mono-project.com/FAQ:_Technical -// "How can I detect if am running in Mono?" section - try - System.Type.GetType ("Mono.Runtime") <> null - with e-> - // Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent - // that is not reliable. - // This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is - // called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get - // their issue fixed but we need to be robust here anyway. - false -#else - false -#endif - let _ = if logging then dprintn "* warning: Il.logging is on" let int_order = LanguagePrimitives.FastGenericComparer @@ -87,10 +68,10 @@ let rec splitNamespaceAux (nm: string) = /// Global State. All namespace splits ever seen // ++GLOBAL MUTABLE STATE (concurrency-safe) -let memoizeNamespaceTable = new ConcurrentDictionary() +let memoizeNamespaceTable = ConcurrentDictionary() // ++GLOBAL MUTABLE STATE (concurrency-safe) -let memoizeNamespaceRightTable = new ConcurrentDictionary() +let memoizeNamespaceRightTable = ConcurrentDictionary() let splitNamespace nm = @@ -100,7 +81,7 @@ let splitNamespaceMemoized nm = splitNamespace nm // ++GLOBAL MUTABLE STATE (concurrency-safe) let memoizeNamespaceArrayTable = - Concurrent.ConcurrentDictionary() + ConcurrentDictionary() let splitNamespaceToArray nm = memoizeNamespaceArrayTable.GetOrAdd (nm, fun nm -> @@ -114,8 +95,6 @@ let splitILTypeName (nm: string) = let s1, s2 = splitNameAt nm idx splitNamespace s1, s2 -let emptyStringArray = ([| |] : string[]) - // Duplicate of comment in import.fs: // The type names that flow to the point include the "mangled" type names used for static parameters for provided types. // For example, @@ -130,7 +109,7 @@ let splitILTypeNameWithPossibleStaticArguments (nm: string) = let nsp, nm = match nm.LastIndexOf '.' with - | -1 -> emptyStringArray, nm + | -1 -> [| |], nm | idx -> let s1, s2 = splitNameAt nm idx splitNamespaceToArray s1, s2 @@ -168,7 +147,7 @@ type LazyOrderedMultiMap<'Key, 'Data when 'Key : equality>(keyf : 'Data -> 'Key, let quickMap = lazyItems |> lazyMap (fun entries -> - let t = new Dictionary<_, _>(entries.Length, HashIdentity.Structural) + let t = Dictionary<_, _>(entries.Length, HashIdentity.Structural) do entries |> List.iter (fun y -> let key = keyf y let v = @@ -302,11 +281,11 @@ module SHA1 = h0, h1, h2, h3, h4 let sha1HashBytes s = - let (_h0, _h1, _h2, h3, h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 + let _h0, _h1, _h2, h3, h4 = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 Array.map byte [| b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |] let sha1HashInt64 s = - let (_h0,_h1,_h2,h3,h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 + let _h0,_h1,_h2,h3,h4 = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 (int64 h3 <<< 32) ||| int64 h4 let sha1HashBytes s = SHA1.sha1HashBytes s @@ -327,6 +306,10 @@ type ILVersionInfo = new (major, minor, build, revision) = { Major = major; Minor = minor; Build = build; Revision = revision } + /// For debugging + override x.ToString() = sprintf "ILVersionInfo: %u %u %u %u" x.Major x.Minor x.Build x.Revision + + type Locale = string [] @@ -361,15 +344,24 @@ type AssemblyRefData = assemRefLocale: Locale option } /// Global state: table of all assembly references keyed by AssemblyRefData. -let AssemblyRefUniqueStampGenerator = new UniqueStampGenerator() +let AssemblyRefUniqueStampGenerator = UniqueStampGenerator() let isMscorlib data = data.assemRefName = "mscorlib" [] type ILAssemblyRef(data) = - let uniqueStamp = AssemblyRefUniqueStampGenerator.Encode data - let uniqueIgnoringVersionStamp = AssemblyRefUniqueStampGenerator.Encode { data with assemRefVersion = None } + let pkToken key = + match key with + | Some (PublicKey bytes) -> Some (PublicKey (SHA1.sha1HashBytes bytes)) + | Some (PublicKeyToken token) -> Some (PublicKey token) + | None -> None + + let uniqueStamp = + AssemblyRefUniqueStampGenerator.Encode { data with assemRefPublicKeyInfo = pkToken data.assemRefPublicKeyInfo } + + let uniqueIgnoringVersionStamp = + AssemblyRefUniqueStampGenerator.Encode { data with assemRefVersion = None; assemRefPublicKeyInfo = pkToken data.assemRefPublicKeyInfo } member x.Name=data.assemRefName @@ -435,7 +427,7 @@ type ILAssemblyRef(data) = add aref.Name match aref.Version with | None -> () - | Some (version) -> + | Some version -> add ", Version=" add (string (int version.Major)) add "." @@ -468,7 +460,6 @@ type ILAssemblyRef(data) = add ", Retargetable=Yes" b.ToString() - [] type ILModuleRef = { name: string @@ -584,8 +575,11 @@ type ILTypeRef = hashCode : int mutable asBoxedType: ILType } + static member ComputeHash(scope, enclosing, name) = + hash scope * 17 ^^^ (hash enclosing * 101 <<< 1) ^^^ (hash name * 47 <<< 2) + static member Create (scope, enclosing, name) = - let hashCode = hash scope * 17 ^^^ (hash enclosing * 101 <<< 1) ^^^ (hash name * 47 <<< 2) + let hashCode = ILTypeRef.ComputeHash(scope, enclosing, name) { trefScope=scope trefEnclosing=enclosing trefName=name @@ -615,11 +609,31 @@ type ILTypeRef = override x.GetHashCode() = x.hashCode override x.Equals yobj = - let y = (yobj :?> ILTypeRef) - (x.ApproxId = y.ApproxId) && - (x.Scope = y.Scope) && - (x.Name = y.Name) && - (x.Enclosing = y.Enclosing) + let y = (yobj :?> ILTypeRef) + (x.ApproxId = y.ApproxId) && + (x.Scope = y.Scope) && + (x.Name = y.Name) && + (x.Enclosing = y.Enclosing) + + member x.EqualsWithPrimaryScopeRef(primaryScopeRef:ILScopeRef, yobj:obj) = + let y = (yobj :?> ILTypeRef) + let isPrimary (v:ILTypeRef) = + match v.Scope with + | ILScopeRef.PrimaryAssembly -> true + | _ -> false + + // Since we can remap the scope, we need to recompute hash ... this is not an expensive operation + let isPrimaryX = isPrimary x + let isPrimaryY = isPrimary y + let xApproxId = if isPrimaryX && not(isPrimaryY) then ILTypeRef.ComputeHash(primaryScopeRef, x.Enclosing, x.Name) else x.ApproxId + let yApproxId = if isPrimaryY && not(isPrimaryX) then ILTypeRef.ComputeHash(primaryScopeRef, y.Enclosing, y.Name) else y.ApproxId + let xScope = if isPrimaryX then primaryScopeRef else x.Scope + let yScope = if isPrimaryY then primaryScopeRef else y.Scope + + (xApproxId = yApproxId) && + (xScope = yScope) && + (x.Name = y.Name) && + (x.Enclosing = y.Enclosing) interface IComparable with @@ -669,7 +683,7 @@ and [] member x.DebugText = x.ToString() + member x.EqualsWithPrimaryScopeRef(primaryScopeRef:ILScopeRef, yobj:obj) = + let y = (yobj :?> ILTypeSpec) + x.tspecTypeRef.EqualsWithPrimaryScopeRef(primaryScopeRef, y.TypeRef) && (x.GenericArgs = y.GenericArgs) + override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>" and [] @@ -801,8 +819,13 @@ type ILMethodRef = member x.CallingSignature = mkILCallSig (x.CallingConv, x.ArgTypes, x.ReturnType) - static member Create (a, b, c, d, e, f) = - { mrefParent=a; mrefCallconv=b; mrefName=c; mrefGenericArity=d; mrefArgs=e; mrefReturn=f } + static member Create (enclosingTypeRef, callingConv, name, genericArity, argTypes, returnType) = + { mrefParent=enclosingTypeRef + mrefCallconv=callingConv + mrefName=name + mrefGenericArity=genericArity + mrefArgs=argTypes + mrefReturn=returnType } /// For debugging [] @@ -888,10 +911,10 @@ type ILSourceDocument = sourceDocType: ILGuid option sourceFile: string } - static member Create (language, vendor, docType, file) = + static member Create (language, vendor, documentType, file) = { sourceLanguage=language sourceVendor=vendor - sourceDocType=docType + sourceDocType=documentType sourceFile=file } member x.Language=x.sourceLanguage @@ -903,7 +926,7 @@ type ILSourceDocument = member x.File=x.sourceFile [] -type ILSourceMarker = +type ILDebugPoint = { sourceDocument: ILSourceDocument sourceLine: int sourceColumn: int @@ -952,7 +975,7 @@ type ILAttribElem = | TypeRef of ILTypeRef option | Array of ILType * ILAttribElem list -type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem) +type ILAttributeNamedArg = string * ILType * bool * ILAttribElem [] type ILAttribute = @@ -1183,7 +1206,7 @@ type ILInstr = | I_refanyval of ILType | I_break - | I_seqpoint of ILSourceMarker + | I_seqpoint of ILDebugPoint | I_arglist @@ -1200,12 +1223,12 @@ type ILInstr = type ILExceptionClause = | Finally of (ILCodeLabel * ILCodeLabel) | Fault of (ILCodeLabel * ILCodeLabel) - | FilterCatch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel) + | FilterCatch of filterRange: (ILCodeLabel * ILCodeLabel) * handlerRange: (ILCodeLabel * ILCodeLabel) | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel) [] type ILExceptionSpec = - { Range: (ILCodeLabel * ILCodeLabel) + { Range: ILCodeLabel * ILCodeLabel Clause: ILExceptionClause } /// Indicates that a particular local variable has a particular source @@ -1218,7 +1241,7 @@ type ILLocalDebugMapping = [] type ILLocalDebugInfo = - { Range: (ILCodeLabel * ILCodeLabel) + { Range: ILCodeLabel * ILCodeLabel DebugMappings: ILLocalDebugMapping list } [] @@ -1236,15 +1259,32 @@ type ILLocal = type ILLocals = list +[] +type ILDebugImport = + | ImportType of targetType: ILType // * alias: string option + | ImportNamespace of targetNamespace: string // * assembly: ILAssemblyRef option * alias: string option + + //| ReferenceAlias of string + //| OpenXmlNamespace of prefix: string * xmlNamespace: string + +type ILDebugImports = + { + Parent: ILDebugImports option + Imports: ILDebugImport[] + } + [] type ILMethodBody = - { IsZeroInit: bool + { + IsZeroInit: bool MaxStack: int32 NoInlining: bool AggressiveInlining: bool Locals: ILLocals Code: ILCode - SourceMarker: ILSourceMarker option } + DebugPoint: ILDebugPoint option + DebugImports: ILDebugImports option + } [] type ILMemberAccess = @@ -1273,16 +1313,33 @@ type ILFieldInit = | Double of double | Null + member x.AsObject() = + match x with + | ILFieldInit.String s -> box s + | ILFieldInit.Bool bool -> box bool + | ILFieldInit.Char u16 -> box (char (int u16)) + | ILFieldInit.Int8 i8 -> box i8 + | ILFieldInit.Int16 i16 -> box i16 + | ILFieldInit.Int32 i32 -> box i32 + | ILFieldInit.Int64 i64 -> box i64 + | ILFieldInit.UInt8 u8 -> box u8 + | ILFieldInit.UInt16 u16 -> box u16 + | ILFieldInit.UInt32 u32 -> box u32 + | ILFieldInit.UInt64 u64 -> box u64 + | ILFieldInit.Single ieee32 -> box ieee32 + | ILFieldInit.Double ieee64 -> box ieee64 + | ILFieldInit.Null -> (null :> Object) + // -------------------------------------------------------------------- // Native Types, for marshalling to the native C interface. // These are taken directly from the ILASM syntax, and don't really -// correspond yet to the ECMA Spec (Partition II, 7.4). +// correspond yet to the CLI ECMA-335 Spec (Partition II, 7.4). // -------------------------------------------------------------------- [] type ILNativeType = | Empty - | Custom of ILGuid * string * string * byte[] (* guid, nativeTypeName, custMarshallerName, cookieString *) + | Custom of ILGuid * nativeTypeName: string * custMarshallerName: string * cookieString: byte[] | FixedSysString of int32 | FixedArray of int32 | Currency @@ -1501,36 +1558,20 @@ type ILMethodVirtualInfo = IsCheckAccessOnOverride: bool IsAbstract: bool } -type MethodKind = - | Static - | Cctor - | Ctor - | NonVirtual - | Virtual of ILMethodVirtualInfo - [] type MethodBody = - | IL of ILMethodBody - | PInvoke of PInvokeMethod (* platform invoke to native *) + | IL of Lazy + | PInvoke of Lazy (* platform invoke to native *) | Abstract | Native | NotAvailable -type ILLazyMethodBody = - | ILLazyMethodBody of Lazy - - member x.Contents = let (ILLazyMethodBody mb) = x in mb.Force() - [] type MethodCodeKind = | IL | Native | Runtime -let mkMethBodyAux mb = ILLazyMethodBody (notlazy mb) - -let mkMethBodyLazyAux mb = ILLazyMethodBody mb - let typesOfILParams (ps: ILParameters) : ILTypes = ps |> List.map (fun p -> p.Type) [] @@ -1586,41 +1627,43 @@ let NoMetadataIdx = -1 [] type ILMethodDef (name: string, attributes: MethodAttributes, implAttributes: MethodImplAttributes, callingConv: ILCallingConv, - parameters: ILParameters, ret: ILReturn, body: ILLazyMethodBody, isEntryPoint: bool, genericParams: ILGenericParameterDefs, + parameters: ILParameters, ret: ILReturn, body: Lazy, isEntryPoint: bool, genericParams: ILGenericParameterDefs, securityDeclsStored: ILSecurityDeclsStored, customAttrsStored: ILAttributesStored, metadataIndex: int32) = new (name, attributes, implAttributes, callingConv, parameters, ret, body, isEntryPoint, genericParams, securityDecls, customAttrs) = ILMethodDef (name, attributes, implAttributes, callingConv, parameters, ret, body, isEntryPoint, genericParams, storeILSecurityDecls securityDecls, storeILCustomAttrs customAttrs, NoMetadataIdx) + member private _.LazyBody = body + // The captured data - remember the object will be as large as the data captured by these members - member __.Name = name + member _.Name = name - member __.Attributes = attributes + member _.Attributes = attributes - member __.ImplAttributes = implAttributes + member _.ImplAttributes = implAttributes - member __.CallingConv = callingConv + member _.CallingConv = callingConv - member __.Parameters = parameters + member _.Parameters = parameters - member __.Return = ret + member _.Return = ret - member __.Body = body + member _.Body = body.Value - member __.SecurityDeclsStored = securityDeclsStored + member _.SecurityDeclsStored = securityDeclsStored - member __.IsEntryPoint = isEntryPoint + member _.IsEntryPoint = isEntryPoint - member __.GenericParams = genericParams + member _.GenericParams = genericParams - member __.CustomAttrsStored = customAttrsStored + member _.CustomAttrsStored = customAttrsStored - member __.MetadataIndex = metadataIndex + member _.MetadataIndex = metadataIndex member x.With (?name: string, ?attributes: MethodAttributes, ?implAttributes: MethodImplAttributes, ?callingConv: ILCallingConv, ?parameters: ILParameters, ?ret: ILReturn, - ?body: ILLazyMethodBody, ?securityDecls: ILSecurityDecls, ?isEntryPoint: bool, + ?body: Lazy, ?securityDecls: ILSecurityDecls, ?isEntryPoint: bool, ?genericParams: ILGenericParameterDefs, ?customAttrs: ILAttributes) = ILMethodDef (name = defaultArg name x.Name, @@ -1629,7 +1672,7 @@ type ILMethodDef (name: string, attributes: MethodAttributes, implAttributes: Me callingConv = defaultArg callingConv x.CallingConv, parameters = defaultArg parameters x.Parameters, ret = defaultArg ret x.Return, - body = defaultArg body x.Body, + body = defaultArg body x.LazyBody, securityDecls = (match securityDecls with None -> x.SecurityDecls | Some attrs -> attrs), isEntryPoint = defaultArg isEntryPoint x.IsEntryPoint, genericParams = defaultArg genericParams x.GenericParams, @@ -1642,17 +1685,17 @@ type ILMethodDef (name: string, attributes: MethodAttributes, implAttributes: Me member x.ParameterTypes = typesOfILParams x.Parameters member md.Code = - match md.Body.Contents with - | MethodBody.IL il-> Some il.Code + match md.Body with + | MethodBody.IL il-> Some il.Value.Code | _ -> None - member x.IsIL = match x.Body.Contents with | MethodBody.IL _ -> true | _ -> false + member x.IsIL = match x.Body with | MethodBody.IL _ -> true | _ -> false - member x.Locals = match x.Body.Contents with | MethodBody.IL il -> il.Locals | _ -> [] + member x.Locals = match x.Body with | MethodBody.IL il -> il.Value.Locals | _ -> [] - member x.MethodBody = match x.Body.Contents with MethodBody.IL il -> il | _ -> failwith "not IL" + member x.MethodBody = match x.Body with MethodBody.IL il -> il.Value | _ -> failwith "not IL" - member x.SourceMarker = x.MethodBody.SourceMarker + member x.DebugPoint = x.MethodBody.DebugPoint member x.MaxStack = x.MethodBody.MaxStack @@ -1661,54 +1704,87 @@ type ILMethodDef (name: string, attributes: MethodAttributes, implAttributes: Me member md.CallingSignature = mkILCallSig (md.CallingConv, md.ParameterTypes, md.Return.Type) member x.IsClassInitializer = x.Name = ".cctor" + member x.IsConstructor = x.Name = ".ctor" member x.Access = memberAccessOfFlags (int x.Attributes) + member x.IsStatic = x.Attributes &&& MethodAttributes.Static <> enum 0 + member x.IsNonVirtualInstance = not x.IsStatic && not x.IsVirtual + member x.IsVirtual = x.Attributes &&& MethodAttributes.Virtual <> enum 0 + member x.IsFinal = x.Attributes &&& MethodAttributes.Final <> enum 0 + member x.IsNewSlot = x.Attributes &&& MethodAttributes.NewSlot <> enum 0 + member x.IsCheckAccessOnOverride= x.Attributes &&& MethodAttributes.CheckAccessOnOverride <> enum 0 + member x.IsAbstract = x.Attributes &&& MethodAttributes.Abstract <> enum 0 + member x.IsHideBySig = x.Attributes &&& MethodAttributes.HideBySig <> enum 0 + member x.IsSpecialName = x.Attributes &&& MethodAttributes.SpecialName <> enum 0 + member x.IsUnmanagedExport = x.Attributes &&& MethodAttributes.UnmanagedExport <> enum 0 + member x.IsReqSecObj = x.Attributes &&& MethodAttributes.RequireSecObject <> enum 0 + member x.HasSecurity = x.Attributes &&& MethodAttributes.HasSecurity <> enum 0 member x.IsManaged = x.ImplAttributes &&& MethodImplAttributes.Managed <> enum 0 + member x.IsForwardRef = x.ImplAttributes &&& MethodImplAttributes.ForwardRef <> enum 0 + member x.IsInternalCall = x.ImplAttributes &&& MethodImplAttributes.InternalCall <> enum 0 + member x.IsPreserveSig = x.ImplAttributes &&& MethodImplAttributes.PreserveSig <> enum 0 + member x.IsSynchronized = x.ImplAttributes &&& MethodImplAttributes.Synchronized <> enum 0 + member x.IsNoInline = x.ImplAttributes &&& MethodImplAttributes.NoInlining <> enum 0 + member x.IsAggressiveInline= x.ImplAttributes &&& MethodImplAttributes.AggressiveInlining <> enum 0 + member x.IsMustRun = x.ImplAttributes &&& MethodImplAttributes.NoOptimization <> enum 0 member x.WithSpecialName = x.With(attributes = (x.Attributes ||| MethodAttributes.SpecialName)) + member x.WithHideBySig() = x.With(attributes = ( if x.IsVirtual then x.Attributes &&& ~~~MethodAttributes.CheckAccessOnOverride ||| MethodAttributes.HideBySig else failwith "WithHideBySig")) + member x.WithHideBySig(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.HideBySig)) + member x.WithFinal(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.Final)) + member x.WithAbstract(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.Abstract)) + member x.WithAccess(access) = x.With(attributes = (x.Attributes &&& ~~~MethodAttributes.MemberAccessMask ||| convertMemberAccess access)) + member x.WithNewSlot = x.With(attributes = (x.Attributes ||| MethodAttributes.NewSlot)) + member x.WithSecurity(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.HasSecurity)) + member x.WithPInvoke(condition) = x.With(attributes = (x.Attributes |> conditionalAdd condition MethodAttributes.PinvokeImpl)) + member x.WithPreserveSig(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.PreserveSig)) + member x.WithSynchronized(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.Synchronized)) + member x.WithNoInlining(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.NoInlining)) + member x.WithAggressiveInlining(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.AggressiveInlining)) + member x.WithRuntime(condition) = x.With(implAttributes = (x.ImplAttributes |> conditionalAdd condition MethodImplAttributes.Runtime)) /// Index table by name and arity. type MethodDefMap = Map [] -type ILMethodDefs(f : (unit -> ILMethodDef[])) = +type ILMethodDefs(f : unit -> ILMethodDef[]) = let mutable array = InlineDelayInit<_>(f) let mutable dict = InlineDelayInit<_>(fun () -> @@ -1739,6 +1815,10 @@ type ILMethodDefs(f : (unit -> ILMethodDef[])) = member x.FindByNameAndArity (nm, arity) = x.FindByName nm |> List.filter (fun x -> List.length x.Parameters = arity) + member x.TryFindInstanceByNameAndCallingSignature (nm, callingSig) = + x.FindByName nm + |> List.tryFind (fun x -> not x.IsStatic && x.CallingSignature = callingSig) + [] type ILEventDef(eventType: ILType option, name: string, attributes: EventAttributes, addMethod: ILMethodRef, removeMethod: ILMethodRef, fireMethod: ILMethodRef option, @@ -1747,15 +1827,15 @@ type ILEventDef(eventType: ILType option, name: string, attributes: EventAttribu new (eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, customAttrs) = ILEventDef(eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, storeILCustomAttrs customAttrs, NoMetadataIdx) - member __.EventType = eventType - member __.Name = name - member __.Attributes = attributes - member __.AddMethod = addMethod - member __.RemoveMethod = removeMethod - member __.FireMethod = fireMethod - member __.OtherMethods = otherMethods - member __.CustomAttrsStored = customAttrsStored - member __.MetadataIndex = metadataIndex + member _.EventType = eventType + member _.Name = name + member _.Attributes = attributes + member _.AddMethod = addMethod + member _.RemoveMethod = removeMethod + member _.FireMethod = fireMethod + member _.OtherMethods = otherMethods + member _.CustomAttrsStored = customAttrsStored + member _.MetadataIndex = metadataIndex member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex member x.With(?eventType, ?name, ?attributes, ?addMethod, ?removeMethod, ?fireMethod, ?otherMethods, ?customAttrs) = @@ -1850,13 +1930,13 @@ type ILFieldDef(name: string, fieldType: ILType, attributes: FieldAttributes, da new (name, fieldType, attributes, data, literalValue, offset, marshal, customAttrs) = ILFieldDef(name, fieldType, attributes, data, literalValue, offset, marshal, storeILCustomAttrs customAttrs, NoMetadataIdx) - member __.Name=name - member __.FieldType = fieldType - member __.Attributes=attributes - member __.Data=data - member __.LiteralValue=literalValue - member __.Offset=offset - member __.Marshal=marshal + member _.Name=name + member _.FieldType = fieldType + member _.Attributes=attributes + member _.Data=data + member _.LiteralValue=literalValue + member _.Offset=offset + member _.Marshal=marshal member x.CustomAttrsStored = customAttrsStored member x.CustomAttrs = customAttrsStored.GetCustomAttrs x.MetadataIndex member x.MetadataIndex = metadataIndex @@ -1955,22 +2035,17 @@ type ILTypeDefKind = | Enum | Delegate -let typeKindOfFlags nm _mdefs _fdefs (super: ILType option) flags = +let typeKindOfFlags nm (super: ILType option) flags = if (flags &&& 0x00000020) <> 0x0 then ILTypeDefKind.Interface else - let isEnum, isDelegate, isMulticastDelegate, isValueType = - match super with - | None -> false, false, false, false - | Some ty -> - ty.TypeSpec.Name = "System.Enum", - ty.TypeSpec.Name = "System.Delegate", - ty.TypeSpec.Name = "System.MulticastDelegate", - ty.TypeSpec.Name = "System.ValueType" && nm <> "System.Enum" - let selfIsMulticastDelegate = nm = "System.MulticastDelegate" - if isEnum then ILTypeDefKind.Enum - elif (isDelegate && not selfIsMulticastDelegate) || isMulticastDelegate then ILTypeDefKind.Delegate - elif isValueType then ILTypeDefKind.ValueType - else ILTypeDefKind.Class + match super with + | None -> ILTypeDefKind.Class + | Some ty -> + let name = ty.TypeSpec.Name + if name = "System.Enum" then ILTypeDefKind.Enum + elif (name = "System.Delegate" && nm <> "System.MulticastDelegate") || name = "System.MulticastDelegate" then ILTypeDefKind.Delegate + elif name = "System.ValueType" && nm <> "System.Enum" then ILTypeDefKind.ValueType + else ILTypeDefKind.Class let convertTypeAccessFlags access = match access with @@ -2029,21 +2104,21 @@ type ILTypeDef(name: string, attributes: TypeAttributes, layout: ILTypeDefLayout new (name, attributes, layout, implements, genericParams, extends, methods, nestedTypes, fields, methodImpls, events, properties, securityDecls, customAttrs) = ILTypeDef (name, attributes, layout, implements, genericParams, extends, methods, nestedTypes, fields, methodImpls, events, properties, storeILSecurityDecls securityDecls, storeILCustomAttrs customAttrs, NoMetadataIdx) - member __.Name = name - member __.Attributes = attributes - member __.GenericParams = genericParams - member __.Layout = layout - member __.NestedTypes = nestedTypes - member __.Implements = implements - member __.Extends = extends - member __.Methods = methods - member __.SecurityDeclsStored = securityDeclsStored - member __.Fields = fields - member __.MethodImpls = methodImpls - member __.Events = events - member __.Properties = properties - member __.CustomAttrsStored = customAttrsStored - member __.MetadataIndex = metadataIndex + member _.Name = name + member _.Attributes = attributes + member _.GenericParams = genericParams + member _.Layout = layout + member _.NestedTypes = nestedTypes + member _.Implements = implements + member _.Extends = extends + member _.Methods = methods + member _.SecurityDeclsStored = securityDeclsStored + member _.Fields = fields + member _.MethodImpls = methodImpls + member _.Events = events + member _.Properties = properties + member _.CustomAttrsStored = customAttrsStored + member _.MetadataIndex = metadataIndex member x.With(?name, ?attributes, ?layout, ?implements, ?genericParams, ?extends, ?methods, ?nestedTypes, ?fields, ?methodImpls, ?events, ?properties, ?customAttrs, ?securityDecls) = ILTypeDef(name=defaultArg name x.Name, @@ -2072,11 +2147,11 @@ type ILTypeDef(name: string, attributes: TypeAttributes, layout: ILTypeDefLayout member x.SecurityDecls = x.SecurityDeclsStored.GetSecurityDecls x.MetadataIndex - member x.IsClass = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Class - member x.IsStruct = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.ValueType - member x.IsInterface = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Interface - member x.IsEnum = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Enum - member x.IsDelegate = (typeKindOfFlags x.Name x.Methods x.Fields x.Extends (int x.Attributes)) = ILTypeDefKind.Delegate + member x.IsClass = (typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Class + member x.IsStruct = (typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.ValueType + member x.IsInterface = (typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Interface + member x.IsEnum = (typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Enum + member x.IsDelegate = (typeKindOfFlags x.Name x.Extends (int x.Attributes)) = ILTypeDefKind.Delegate member x.Access = typeAccessOfFlags (int x.Attributes) member x.IsAbstract = x.Attributes &&& TypeAttributes.Abstract <> enum 0 member x.IsSealed = x.Attributes &&& TypeAttributes.Sealed <> enum 0 @@ -2109,7 +2184,7 @@ and [] ILTypeDefs(f : unit -> ILPreTypeDef[]) = for pre in arr do let key = pre.Namespace, pre.Name t.[key] <- pre - t) + ReadOnlyDictionary t) member x.AsArray = [| for pre in array.Value -> pre.GetTypeDef() |] @@ -2140,8 +2215,8 @@ and [] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIn let mutable store : ILTypeDef = Unchecked.defaultof<_> interface ILPreTypeDef with - member __.Namespace = nameSpace - member __.Name = name + member _.Namespace = nameSpace + member _.Name = name member x.GetTypeDef() = match box store with @@ -2207,9 +2282,9 @@ type ILResourceAccess = | Public | Private -[] +[] type ILResourceLocation = - | Local of ReadOnlyByteMemory + | Local of ByteStorage | File of ILModuleRef * int32 | Assembly of ILAssemblyRef @@ -2223,7 +2298,7 @@ type ILResource = /// Read the bytes from a resource local to an assembly member r.GetBytes() = match r.Location with - | ILResourceLocation.Local bytes -> bytes + | ILResourceLocation.Local bytes -> bytes.GetByteMemory() | _ -> failwith "GetBytes" member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex @@ -2245,6 +2320,7 @@ type ILAssemblyLongevity = | PlatformProcess | PlatformSystem + static member Default = Unspecified type ILAssemblyManifest = { Name: string @@ -2424,7 +2500,6 @@ let mkILFieldSpec (tref, ty) = { FieldRef= tref; DeclaringType=ty } let mkILFieldSpecInTy (ty: ILType, nm, fty) = mkILFieldSpec (mkILFieldRef (ty.TypeRef, nm, fty), ty) - let andTailness x y = match x with Tailcall when y -> Tailcall | _ -> Normalcall @@ -2606,15 +2681,15 @@ let tname_UIntPtr = "System.UIntPtr" let tname_TypedReference = "System.TypedReference" [] -type ILGlobals(primaryScopeRef: ILScopeRef, assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list) = +type ILGlobals(primaryScopeRef: ILScopeRef, assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list, fsharpCoreAssemblyScopeRef: ILScopeRef) = let assembliesThatForwardToPrimaryAssembly = Array.ofList assembliesThatForwardToPrimaryAssembly let mkSysILTypeRef nm = mkILTyRef (primaryScopeRef, nm) member _.primaryAssemblyScopeRef = primaryScopeRef - member x.primaryAssemblyRef = - match primaryScopeRef with + member x.primaryAssemblyRef = + match primaryScopeRef with | ILScopeRef.Assembly aref -> aref | _ -> failwith "Invalid primary assembly" member x.primaryAssemblyName = x.primaryAssemblyRef.Name @@ -2639,6 +2714,8 @@ type ILGlobals(primaryScopeRef: ILScopeRef, assembliesThatForwardToPrimaryAssemb member val typ_UIntPtr = ILType.Value (mkILNonGenericTySpec (mkSysILTypeRef tname_UIntPtr)) member val typ_TypedReference = ILType.Value (mkILNonGenericTySpec (mkSysILTypeRef tname_TypedReference)) + member _.fsharpCoreAssemblyScopeRef = fsharpCoreAssemblyScopeRef + member x.IsPossiblePrimaryAssemblyRef(aref: ILAssemblyRef) = aref.EqualsIgnoringVersion x.primaryAssemblyRef || assembliesThatForwardToPrimaryAssembly @@ -2650,7 +2727,7 @@ type ILGlobals(primaryScopeRef: ILScopeRef, assembliesThatForwardToPrimaryAssemb override x.ToString() = "" -let mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly) = ILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly) +let mkILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef) = ILGlobals (primaryScopeRef, assembliesThatForwardToPrimaryAssembly, fsharpCoreAssemblyScopeRef) let mkNormalCall mspec = I_call (Normalcall, mspec, None) @@ -2695,10 +2772,15 @@ let isILBoxedTy = function ILType.Boxed _ -> true | _ -> false let isILValueTy = function ILType.Value _ -> true | _ -> false +let rec stripILModifiedFromTy (ty: ILType) = + match ty with + | ILType.Modified(_, _, ty) -> stripILModifiedFromTy ty + | _ -> ty + let isBuiltInTySpec (ilg: ILGlobals) (tspec: ILTypeSpec) n = let tref = tspec.TypeRef let scoref = tref.Scope - tref.Name = n && + tref.Name = n && (match scoref with | ILScopeRef.Local | ILScopeRef.Module _ -> false @@ -2892,16 +2974,19 @@ type ILFieldSpec with // Make a method mbody // -------------------------------------------------------------------- -let mkILMethodBody (zeroinit, locals, maxstack, code, tag) : ILMethodBody = - { IsZeroInit=zeroinit +let mkILMethodBody (initlocals, locals, maxstack, code, tag, imports) : ILMethodBody = + { IsZeroInit=initlocals MaxStack=maxstack NoInlining=false AggressiveInlining=false Locals= locals Code= code - SourceMarker=tag } + DebugPoint=tag + DebugImports=imports } -let mkMethodBody (zeroinit, locals, maxstack, code, tag) = MethodBody.IL (mkILMethodBody (zeroinit, locals, maxstack, code, tag)) +let mkMethodBody (zeroinit, locals, maxstack, code, tag, imports) = + let ilCode = mkILMethodBody (zeroinit, locals, maxstack, code, tag, imports) + MethodBody.IL (lazy ilCode) // -------------------------------------------------------------------- // Make a constructor @@ -2909,11 +2994,11 @@ let mkMethodBody (zeroinit, locals, maxstack, code, tag) = MethodBody.IL (mkILMe let mkILVoidReturn = mkILReturn ILType.Void -let methBodyNotAvailable = mkMethBodyAux MethodBody.NotAvailable +let methBodyNotAvailable = notlazy MethodBody.NotAvailable -let methBodyAbstract = mkMethBodyAux MethodBody.Abstract +let methBodyAbstract = notlazy MethodBody.Abstract -let methBodyNative = mkMethBodyAux MethodBody.Native +let methBodyNative = notlazy MethodBody.Native let mkILCtor (access, args, impl) = ILMethodDef(name=".ctor", @@ -2922,7 +3007,7 @@ let mkILCtor (access, args, impl) = callingConv=ILCallingConv.Instance, parameters = args, ret= mkILVoidReturn, - body= mkMethBodyAux impl, + body= notlazy impl, securityDecls=emptyILSecurityDecls, isEntryPoint=false, genericParams=mkILEmptyGenericParams, @@ -2951,9 +3036,10 @@ let mkNormalLdobj dt = I_ldobj (Aligned, Nonvolatile, dt) let mkNormalStobj dt = I_stobj (Aligned, Nonvolatile, dt) -let mkILNonGenericEmptyCtor tag superTy = +let mkILNonGenericEmptyCtor (superTy, tag, imports) = let ctor = mkCallBaseConstructor (superTy, []) - mkILCtor (ILMemberAccess.Public, [], mkMethodBody (false, [], 8, nonBranchingInstrsToCode ctor, tag)) + let body = mkMethodBody (false, [], 8, nonBranchingInstrsToCode ctor, tag, imports) + mkILCtor (ILMemberAccess.Public, [], body) // -------------------------------------------------------------------- // Make a static, top level monomorphic method - very useful for @@ -2971,7 +3057,7 @@ let mkILStaticMethod (genparams, nm, access, args, ret, impl) = securityDecls=emptyILSecurityDecls, isEntryPoint=false, customAttrs = emptyILCustomAttrs, - body= mkMethBodyAux impl) + body= notlazy impl) let mkILNonGenericStaticMethod (nm, access, args, ret, impl) = mkILStaticMethod (mkILEmptyGenericParams, nm, access, args, ret, impl) @@ -2987,7 +3073,7 @@ let mkILClassCtor impl = isEntryPoint=false, securityDecls=emptyILSecurityDecls, customAttrs=emptyILCustomAttrs, - body= mkMethBodyAux impl) + body= notlazy impl) // -------------------------------------------------------------------- // Make a virtual method, where the overriding is simply the default @@ -3011,7 +3097,7 @@ let mkILGenericVirtualMethod (nm, access, genparams, actual_args, actual_ret, im isEntryPoint=false, securityDecls=emptyILSecurityDecls, customAttrs = emptyILCustomAttrs, - body= mkMethBodyAux impl) + body= notlazy impl) let mkILNonGenericVirtualMethod (nm, access, args, ret, impl) = mkILGenericVirtualMethod (nm, access, mkILEmptyGenericParams, args, ret, impl) @@ -3027,7 +3113,7 @@ let mkILGenericNonVirtualMethod (nm, access, genparams, actual_args, actual_ret, isEntryPoint=false, securityDecls=emptyILSecurityDecls, customAttrs = emptyILCustomAttrs, - body= mkMethBodyAux impl) + body= notlazy impl) let mkILNonGenericInstanceMethod (nm, access, args, ret, impl) = mkILGenericNonVirtualMethod (nm, access, mkILEmptyGenericParams, args, ret, impl) @@ -3043,11 +3129,12 @@ let ilmbody_code2code f (il: ILMethodBody) = let mdef_code2code f (md: ILMethodDef) = let il = - match md.Body.Contents with + match md.Body with | MethodBody.IL il-> il | _ -> failwith "mdef_code2code - method not IL" - let b = MethodBody.IL (ilmbody_code2code f il) - md.With(body = mkMethBodyAux b) + let ilCode = ilmbody_code2code f il.Value + let b = MethodBody.IL (notlazy ilCode) + md.With(body = notlazy b) let prependInstrsToCode (instrs: ILInstr list) (c2: ILCode) = let instrs = Array.ofList instrs @@ -3069,16 +3156,18 @@ let prependInstrsToCode (instrs: ILInstr list) (c2: ILCode) = { c2 with Labels = labels Instrs = Array.append instrs c2.Instrs } -let prependInstrsToMethod new_code md = - mdef_code2code (prependInstrsToCode new_code) md +let prependInstrsToMethod newCode md = + mdef_code2code (prependInstrsToCode newCode) md // Creates cctor if needed -let cdef_cctorCode2CodeOrCreate tag f (cd: ILTypeDef) = +let cdef_cctorCode2CodeOrCreate tag imports f (cd: ILTypeDef) = let mdefs = cd.Methods let cctor = match mdefs.FindByName ".cctor" with | [mdef] -> mdef - | [] -> mkILClassCtor (mkMethodBody (false, [], 1, nonBranchingInstrsToCode [ ], tag)) + | [] -> + let body = mkMethodBody (false, [], 1, nonBranchingInstrsToCode [ ], tag, imports) + mkILClassCtor body | _ -> failwith "bad method table: more than one .cctor found" let methods = ILMethodDefs (fun () -> [| yield f cctor; for md in mdefs do if md.Name <> ".cctor" then yield md |]) @@ -3100,10 +3189,10 @@ let mkRefForILMethod scope (tdefs, tdef) mdef = mkRefToILMethod (mkRefForNestedI let mkRefForILField scope (tdefs, tdef) (fdef: ILFieldDef) = mkILFieldRef (mkRefForNestedILTypeDef scope (tdefs, tdef), fdef.Name, fdef.FieldType) // Creates cctor if needed -let prependInstrsToClassCtor instrs tag cd = - cdef_cctorCode2CodeOrCreate tag (prependInstrsToMethod instrs) cd +let prependInstrsToClassCtor instrs tag imports cd = + cdef_cctorCode2CodeOrCreate tag imports (prependInstrsToMethod instrs) cd -let mkILField (isStatic, nm, ty, (init: ILFieldInit option), (at: byte [] option), access, isLiteral) = +let mkILField (isStatic, nm, ty, init: ILFieldInit option, at: byte [] option, access, isLiteral) = ILFieldDef(name=nm, fieldType=ty, attributes= @@ -3128,10 +3217,10 @@ let mkILLiteralField (nm, ty, init, at, access) = mkILField (true, nm, ty, Some // Scopes for allocating new temporary variables. // -------------------------------------------------------------------- -type ILLocalsAllocator (numPrealloc: int) = +type ILLocalsAllocator (preAlloc: int) = let newLocals = ResizeArray() member tmps.AllocLocal loc = - let locn = uint16 (numPrealloc + newLocals.Count) + let locn = uint16 (preAlloc + newLocals.Count) newLocals.Add loc locn @@ -3179,6 +3268,7 @@ let mkILNestedExportedTypesLazy (l: Lazy<_>) = ILNestedExportedTypes (lazy (List.foldBack addNestedExportedTypeToTable (l.Force()) Map.empty)) let mkILResources l = ILResources l +let emptyILResources = ILResources [] let addMethodImplToTable y tab = let key = (y.Overrides.MethodRef.Name, y.Overrides.MethodRef.ArgTypes.Length) @@ -3193,55 +3283,64 @@ let emptyILMethodImpls = mkILMethodImpls [] /// Make a constructor that simply takes its arguments and stuffs /// them in fields. preblock is how to call the superclass constructor.... -let mkILStorageCtorWithParamNames (tag, preblock, ty, extraParams, flds, access) = +let mkILStorageCtorWithParamNames (preblock: ILInstr list, ty, extraParams, flds, access, tag, imports) = + let code = + [ match tag with + | Some x -> I_seqpoint x + | None -> () + yield! preblock + for (n, (_pnm, nm, fieldTy)) in List.indexed flds do + mkLdarg0 + mkLdarg (uint16 (n+1)) + mkNormalStfld (mkILFieldSpecInTy (ty, nm, fieldTy)) + ] + let body = mkMethodBody (false, [], 2, nonBranchingInstrsToCode code, tag, imports) mkILCtor(access, - (flds |> List.map (fun (pnm, _, ty) -> mkILParamNamed (pnm, ty))) @ extraParams, - mkMethodBody - (false, [], 2, - nonBranchingInstrsToCode - begin - (match tag with Some x -> [I_seqpoint x] | None -> []) @ - preblock @ - List.concat (List.mapi (fun n (_pnm, nm, fieldTy) -> - [ mkLdarg0 - mkLdarg (uint16 (n+1)) - mkNormalStfld (mkILFieldSpecInTy (ty, nm, fieldTy)) - ]) flds) - end, tag)) - -let mkILSimpleStorageCtorWithParamNames (tag, baseTySpec, ty, extraParams, flds, access) = + (flds |> List.map (fun (pnm, _, ty) -> mkILParamNamed (pnm, ty))) @ extraParams, body + ) + +let mkILSimpleStorageCtorWithParamNames (baseTySpec, ty, extraParams, flds, access, tag, imports) = let preblock = match baseTySpec with - None -> [] + | None -> [] | Some tspec -> - ([ mkLdarg0 - mkNormalCall (mkILCtorMethSpecForTy (mkILBoxedType tspec, [])) ]) - mkILStorageCtorWithParamNames (tag, preblock, ty, extraParams, flds, access) + [ mkLdarg0 + mkNormalCall (mkILCtorMethSpecForTy (mkILBoxedType tspec, [])) ] + mkILStorageCtorWithParamNames (preblock, ty, extraParams, flds, access, tag, imports) let addParamNames flds = flds |> List.map (fun (nm, ty) -> (nm, nm, ty)) -let mkILSimpleStorageCtor (tag, baseTySpec, ty, extraParams, flds, access) = - mkILSimpleStorageCtorWithParamNames (tag, baseTySpec, ty, extraParams, addParamNames flds, access) +let mkILSimpleStorageCtor (baseTySpec, ty, extraParams, flds, access, tag, imports) = + mkILSimpleStorageCtorWithParamNames (baseTySpec, ty, extraParams, addParamNames flds, access, tag, imports) -let mkILStorageCtor (tag, preblock, ty, flds, access) = mkILStorageCtorWithParamNames (tag, preblock, ty, [], addParamNames flds, access) +let mkILStorageCtor (preblock, ty, flds, access, tag, imports) = + mkILStorageCtorWithParamNames (preblock, ty, [], addParamNames flds, access, tag, imports) let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nestedTypes, props, events, attrs, init) = + let attributes = + convertTypeAccessFlags access ||| + TypeAttributes.AutoLayout ||| + TypeAttributes.Class ||| + (match init with + | ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit + | _ -> enum 0) + ||| TypeAttributes.AnsiClass + ILTypeDef(name=nm, - attributes=(convertTypeAccessFlags access ||| TypeAttributes.AutoLayout ||| TypeAttributes.Class ||| - (match init with | ILTypeInit.BeforeField -> TypeAttributes.BeforeFieldInit | _ -> enum 0) ||| TypeAttributes.AnsiClass), - genericParams= genparams, - implements = impl, - layout=ILTypeDefLayout.Auto, - extends = Some extends, - methods= methods, - fields= fields, - nestedTypes=nestedTypes, - customAttrs=attrs, - methodImpls=emptyILMethodImpls, - properties=props, - events=events, - securityDecls=emptyILSecurityDecls) + attributes=attributes, + genericParams= genparams, + implements = impl, + layout=ILTypeDefLayout.Auto, + extends = Some extends, + methods= methods, + fields= fields, + nestedTypes=nestedTypes, + customAttrs=attrs, + methodImpls=emptyILMethodImpls, + properties=props, + events=events, + securityDecls=emptyILSecurityDecls) let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) = ILTypeDef(name = nm, @@ -3273,7 +3372,7 @@ let destTypeDefsWithGlobalFunctionsFirst ilg (tdefs: ILTypeDefs) = let top2 = if isNil top then [ mkILTypeDefForGlobalFunctions ilg (emptyILMethods, emptyILFields) ] else top top2@nontop -let mkILSimpleModule assemblyName modname dll subsystemVersion useHighEntropyVA tdefs hashalg locale flags exportedTypes metadataVersion = +let mkILSimpleModule assemblyName moduleName dll subsystemVersion useHighEntropyVA tdefs hashalg locale flags exportedTypes metadataVersion = let manifest = { Name=assemblyName AuxModuleHashAlgorithm= match hashalg with | Some alg -> alg | _ -> 0x8004 // SHA1 @@ -3292,7 +3391,7 @@ let mkILSimpleModule assemblyName modname dll subsystemVersion useHighEntropyVA MetadataIndex = NoMetadataIdx } { Manifest= Some manifest CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs - Name=modname + Name=moduleName NativeResources=[] TypeDefs=tdefs SubsystemVersion = subsystemVersion @@ -3337,7 +3436,7 @@ let buildILCode (_methName: string) lab2pc instrs tryspecs localspecs : ILCode = // Detecting Delegates // -------------------------------------------------------------------- -let mkILDelegateMethods (access) (ilg: ILGlobals) (iltyp_AsyncCallback, iltyp_IAsyncResult) (parms, rtv: ILReturn) = +let mkILDelegateMethods access (ilg: ILGlobals) (iltyp_AsyncCallback, iltyp_IAsyncResult) (parms, rtv: ILReturn) = let rty = rtv.Type let one nm args ret = let mdef = mkILNonGenericVirtualMethod (nm, access, args, mkILReturn ret, MethodBody.Abstract) @@ -3465,7 +3564,7 @@ let sigptr_get_z_i32 bytes sigptr = let sigptr_get_serstring bytes sigptr = let len, sigptr = sigptr_get_z_i32 bytes sigptr - sigptr_get_string ( len) bytes sigptr + sigptr_get_string len bytes sigptr let sigptr_get_serstring_possibly_null bytes sigptr = let b0, new_sigptr = sigptr_get_byte bytes sigptr @@ -3575,7 +3674,7 @@ let formatILVersion (version: ILVersionInfo) = sprintf "%d.%d.%d.%d" (int versio let encodeCustomAttrString s = let arr = string_as_utf8_bytes s - Array.concat [ z_unsigned_int arr.Length; arr ] + Array.append (z_unsigned_int arr.Length) arr let rec encodeCustomAttrElemType x = match x with @@ -3620,32 +3719,85 @@ let rec encodeCustomAttrElemTypeForObject x = | ILAttribElem.Double _ -> [| et_R8 |] | ILAttribElem.Array (elemTy, _) -> [| yield et_SZARRAY; yield! encodeCustomAttrElemType elemTy |] -let rec decodeCustomAttrElemType (ilg: ILGlobals) bytes sigptr x = +let tspan = TimeSpan (DateTime.UtcNow.Ticks - DateTime(2000, 1, 1).Ticks) + +let parseILVersion (vstr : string) = + // matches "v1.2.3.4" or "1.2.3.4". Note, if numbers are missing, returns -1 (not 0). + let mutable vstr = vstr.TrimStart [|'v'|] + // if the version string contains wildcards, replace them + let versionComponents = vstr.Split [|'.'|] + + // account for wildcards + if versionComponents.Length > 2 then + let defaultBuild = uint16 tspan.Days % UInt16.MaxValue - 1us + let defaultRevision = uint16 (DateTime.UtcNow.TimeOfDay.TotalSeconds / 2.0) % UInt16.MaxValue - 1us + if versionComponents.[2] = "*" then + if versionComponents.Length > 3 then + failwith "Invalid version format" + else + // set the build number to the number of days since Jan 1, 2000 + versionComponents.[2] <- defaultBuild.ToString() + // Set the revision number to number of seconds today / 2 + vstr <- String.Join (".", versionComponents) + "." + defaultRevision.ToString() + elif versionComponents.Length > 3 && versionComponents.[3] = "*" then + // Set the revision number to number of seconds today / 2 + versionComponents.[3] <- defaultRevision.ToString() + vstr <- String.Join (".", versionComponents) + + let version = Version vstr + let zero32 n = if n < 0 then 0us else uint16 n + // since the minor revision will be -1 if none is specified, we need to truncate to 0 to not break existing code + let minorRevision = if version.Revision = -1 then 0us else uint16 version.MinorRevision + ILVersionInfo (zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision) + +let compareILVersions (version1 : ILVersionInfo) (version2 : ILVersionInfo) = + let c = compare version1.Major version2.Major + if c <> 0 then c else + let c = compare version1.Minor version2.Minor + if c <> 0 then c else + let c = compare version1.Build version2.Build + if c <> 0 then c else + let c = compare version1.Revision version2.Revision + if c <> 0 then c else + 0 + +let DummyFSharpCoreScopeRef = + let asmRef = + // The exact public key token and version used here don't actually matter, or shouldn't. + ILAssemblyRef.Create("FSharp.Core", None, + Some (PublicKeyToken(Bytes.ofInt32Array [| 0xb0; 0x3f; 0x5f; 0x7f; 0x11; 0xd5; 0x0a; 0x3a |])), + false, + Some (parseILVersion "0.0.0.0"), None) + ILScopeRef.Assembly asmRef + +let PrimaryAssemblyILGlobals = mkILGlobals (ILScopeRef.PrimaryAssembly, [], DummyFSharpCoreScopeRef) + +let rec decodeCustomAttrElemType bytes sigptr x = match x with - | x when x = et_I1 -> ilg.typ_SByte, sigptr - | x when x = et_U1 -> ilg.typ_Byte, sigptr - | x when x = et_I2 -> ilg.typ_Int16, sigptr - | x when x = et_U2 -> ilg.typ_UInt16, sigptr - | x when x = et_I4 -> ilg.typ_Int32, sigptr - | x when x = et_U4 -> ilg.typ_UInt32, sigptr - | x when x = et_I8 -> ilg.typ_Int64, sigptr - | x when x = et_U8 -> ilg.typ_UInt64, sigptr - | x when x = et_R8 -> ilg.typ_Double, sigptr - | x when x = et_R4 -> ilg.typ_Single, sigptr - | x when x = et_CHAR -> ilg.typ_Char, sigptr - | x when x = et_BOOLEAN -> ilg.typ_Bool, sigptr - | x when x = et_STRING -> ilg.typ_String, sigptr - | x when x = et_OBJECT -> ilg.typ_Object, sigptr + | x when x = et_I1 -> PrimaryAssemblyILGlobals.typ_SByte, sigptr + | x when x = et_U1 -> PrimaryAssemblyILGlobals.typ_Byte, sigptr + | x when x = et_I2 -> PrimaryAssemblyILGlobals.typ_Int16, sigptr + | x when x = et_U2 -> PrimaryAssemblyILGlobals.typ_UInt16, sigptr + | x when x = et_I4 -> PrimaryAssemblyILGlobals.typ_Int32, sigptr + | x when x = et_U4 -> PrimaryAssemblyILGlobals.typ_UInt32, sigptr + | x when x = et_I8 -> PrimaryAssemblyILGlobals.typ_Int64, sigptr + | x when x = et_U8 -> PrimaryAssemblyILGlobals.typ_UInt64, sigptr + | x when x = et_R8 -> PrimaryAssemblyILGlobals.typ_Double, sigptr + | x when x = et_R4 -> PrimaryAssemblyILGlobals.typ_Single, sigptr + | x when x = et_CHAR -> PrimaryAssemblyILGlobals.typ_Char, sigptr + | x when x = et_BOOLEAN -> PrimaryAssemblyILGlobals.typ_Bool, sigptr + | x when x = et_STRING -> PrimaryAssemblyILGlobals.typ_String, sigptr + | x when x = et_OBJECT -> PrimaryAssemblyILGlobals.typ_Object, sigptr | x when x = et_SZARRAY -> let et, sigptr = sigptr_get_u8 bytes sigptr - let elemTy, sigptr = decodeCustomAttrElemType ilg bytes sigptr et + let elemTy, sigptr = decodeCustomAttrElemType bytes sigptr et mkILArr1DTy elemTy, sigptr - | x when x = 0x50uy -> ilg.typ_Type, sigptr + | x when x = 0x50uy -> PrimaryAssemblyILGlobals.typ_Type, sigptr | _ -> failwithf "decodeCustomAttrElemType ilg: unrecognized custom element type: %A" x /// Given a custom attribute element, encode it to a binary representation according to the rules in Ecma 335 Partition II. -let rec encodeCustomAttrPrimValue ilg c = +let rec encodeCustomAttrPrimValue c = match c with | ILAttribElem.Bool b -> [| (if b then 0x01uy else 0x00uy) |] | ILAttribElem.String None @@ -3667,53 +3819,49 @@ let rec encodeCustomAttrPrimValue ilg c = | ILAttribElem.Type (Some ty) -> encodeCustomAttrString ty.QualifiedName | ILAttribElem.TypeRef (Some tref) -> encodeCustomAttrString tref.QualifiedName | ILAttribElem.Array (_, elems) -> - [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue ilg elem |] + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue elem |] -and encodeCustomAttrValue ilg ty c = +and encodeCustomAttrValue ty c = match ty, c with | ILType.Boxed tspec, _ when tspec.Name = tname_Object -> - [| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue ilg c |] + [| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue c |] | ILType.Array (shape, _), ILAttribElem.Null when shape = ILArrayShape.SingleDimensional -> [| yield! i32AsBytes 0xFFFFFFFF |] | ILType.Array (shape, elemType), ILAttribElem.Array (_, elems) when shape = ILArrayShape.SingleDimensional -> - [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue ilg elemType elem |] + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue elemType elem |] | _ -> - encodeCustomAttrPrimValue ilg c + encodeCustomAttrPrimValue c -let encodeCustomAttrNamedArg ilg (nm, ty, prop, elem) = +let encodeCustomAttrNamedArg (nm, ty, prop, elem) = [| yield (if prop then 0x54uy else 0x53uy) yield! encodeCustomAttrElemType ty yield! encodeCustomAttrString nm - yield! encodeCustomAttrValue ilg ty elem |] + yield! encodeCustomAttrValue ty elem |] -let encodeCustomAttrArgs (ilg: ILGlobals) (mspec: ILMethodSpec) (fixedArgs: list<_>) (namedArgs: list<_>) = +let encodeCustomAttrArgs (mspec: ILMethodSpec) (fixedArgs: list<_>) (namedArgs: list<_>) = let argtys = mspec.MethodRef.ArgTypes [| yield! [| 0x01uy; 0x00uy; |] - for (argty, fixedArg) in Seq.zip argtys fixedArgs do - yield! encodeCustomAttrValue ilg argty fixedArg + for argty, fixedArg in Seq.zip argtys fixedArgs do + yield! encodeCustomAttrValue argty fixedArg yield! u16AsBytes (uint16 namedArgs.Length) for namedArg in namedArgs do - yield! encodeCustomAttrNamedArg ilg namedArg |] + yield! encodeCustomAttrNamedArg namedArg |] -let encodeCustomAttr (ilg: ILGlobals) (mspec: ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = - let args = encodeCustomAttrArgs ilg mspec fixedArgs namedArgs +let encodeCustomAttr (mspec: ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = + let args = encodeCustomAttrArgs mspec fixedArgs namedArgs ILAttribute.Encoded (mspec, args, fixedArgs @ (namedArgs |> List.map (fun (_, _, _, e) -> e))) -let mkILCustomAttribMethRef (ilg: ILGlobals) (mspec: ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = - encodeCustomAttr ilg (mspec, fixedArgs, namedArgs) +let mkILCustomAttribMethRef (mspec: ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = + encodeCustomAttr (mspec, fixedArgs, namedArgs) -let mkILCustomAttribute ilg (tref, argtys, argvs, propvs) = - encodeCustomAttr ilg (mkILNonGenericCtorMethSpec (tref, argtys), argvs, propvs) +let mkILCustomAttribute (tref, argtys, argvs, propvs) = + encodeCustomAttr (mkILNonGenericCtorMethSpec (tref, argtys), argvs, propvs) -let getCustomAttrData (ilg: ILGlobals) cattr = +let getCustomAttrData cattr = match cattr with | ILAttribute.Encoded (_, data, _) -> data | ILAttribute.Decoded (mspec, fixedArgs, namedArgs) -> - encodeCustomAttrArgs ilg mspec fixedArgs namedArgs - -let MscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef.Create ("mscorlib", None, Some ecmaPublicKey, true, None, None)) - -let EcmaMscorlibILGlobals = mkILGlobals (MscorlibScopeRef, []) + encodeCustomAttrArgs mspec fixedArgs namedArgs // ILSecurityDecl is a 'blob' having the following format: // - A byte containing a period (.). @@ -3723,16 +3871,16 @@ let EcmaMscorlibILGlobals = mkILGlobals (MscorlibScopeRef, []) // as a compressed int to indicate the size followed by an array of UTF8 characters.) // - A set of properties, encoded as the named arguments to a custom attribute would be (as // in §23.3, beginning with NumNamed). -let mkPermissionSet (ilg: ILGlobals) (action, attributes: list<(ILTypeRef * (string * ILType * ILAttribElem) list)>) = +let mkPermissionSet (action, attributes: list) = let bytes = [| yield (byte '.') yield! z_unsigned_int attributes.Length - for (tref: ILTypeRef, props) in attributes do + for tref: ILTypeRef, props in attributes do yield! encodeCustomAttrString tref.QualifiedName let bytes = [| yield! z_unsigned_int props.Length - for (nm, ty, value) in props do - yield! encodeCustomAttrNamedArg ilg (nm, ty, true, value)|] + for nm, ty, value in props do + yield! encodeCustomAttrNamedArg (nm, ty, true, value)|] yield! z_unsigned_int bytes.Length yield! bytes |] @@ -3796,12 +3944,12 @@ type ILTypeSigParser (tstring : string) = drop() // step to the number // fetch the arity let arity = - while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step() + while (int(here()) >= (int('0'))) && (int(here()) <= (int('9'))) && (int(peek()) >= (int('0'))) && (int(peek()) <= (int('9'))) do step() Int32.Parse(take()) // skip the '[' drop() // get the specializations - typeName+"`"+(arity.ToString()), Some(([for _i in 0..arity-1 do yield x.ParseType()])) + typeName+"`"+(arity.ToString()), Some [for _i in 0..arity-1 do yield x.ParseType()] else typeName, None @@ -3876,7 +4024,7 @@ type ILTypeSigParser (tstring : string) = let ilty = x.ParseType() ILAttribElem.Type (Some ilty) -let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = +let decodeILAttribData (ca: ILAttribute) = match ca with | ILAttribute.Decoded (_, fixedArgs, namedArgs) -> fixedArgs, namedArgs | ILAttribute.Encoded (_, bytes, _) -> @@ -3942,7 +4090,7 @@ let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = if et = 0xFFuy then ILAttribElem.Null, sigptr else - let ty, sigptr = decodeCustomAttrElemType ilg bytes sigptr et + let ty, sigptr = decodeCustomAttrElemType bytes sigptr et parseVal ty sigptr | ILType.Array (shape, elemTy) when shape = ILArrayShape.SingleDimensional -> let n, sigptr = sigptr_get_i32 bytes sigptr @@ -3976,7 +4124,7 @@ let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = if ( (* 0x50 = (int et) || *) 0x55 = (int et)) then let qualified_tname, sigptr = sigptr_get_serstring bytes sigptr let unqualified_tname, rest = - let pieces = qualified_tname.Split (',') + let pieces = qualified_tname.Split ',' if pieces.Length > 1 then pieces.[0], Some (String.concat "," pieces.[1..]) else @@ -3984,13 +4132,13 @@ let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = let scoref = match rest with | Some aname -> ILScopeRef.Assembly (ILAssemblyRef.FromAssemblyName (AssemblyName aname)) - | None -> ilg.primaryAssemblyScopeRef + | None -> PrimaryAssemblyILGlobals.primaryAssemblyScopeRef let tref = mkILTyRef (scoref, unqualified_tname) let tspec = mkILNonGenericTySpec tref ILType.Value tspec, sigptr else - decodeCustomAttrElemType ilg bytes sigptr et + decodeCustomAttrElemType bytes sigptr et let nm, sigptr = sigptr_get_serstring bytes sigptr let v, sigptr = parseVal ty sigptr parseNamed ((nm, ty, isProp, v) :: acc) (n-1) sigptr @@ -4131,14 +4279,14 @@ and refs_of_local s loc = refs_of_typ s loc.Type and refs_of_mbody s x = match x with - | MethodBody.IL il -> refs_of_ilmbody s il - | MethodBody.PInvoke (attr) -> refs_of_modref s attr.Where + | MethodBody.IL il -> refs_of_ilmbody s il.Value + | MethodBody.PInvoke attr -> refs_of_modref s attr.Value.Where | _ -> () and refs_of_mdef s (md: ILMethodDef) = List.iter (refs_of_param s) md.Parameters refs_of_return s md.Return - refs_of_mbody s md.Body.Contents + refs_of_mbody s md.Body refs_of_custom_attrs s md.CustomAttrs refs_of_genparams s md.GenericParams @@ -4234,48 +4382,6 @@ let computeILRefs ilg modul = { AssemblyReferences = Seq.fold (fun acc x -> x :: acc) [] s.refsA ModuleReferences = Seq.fold (fun acc x -> x :: acc) [] s.refsM } -let tspan = TimeSpan (DateTime.UtcNow.Ticks - DateTime(2000, 1, 1).Ticks) - -let parseILVersion (vstr : string) = - // matches "v1.2.3.4" or "1.2.3.4". Note, if numbers are missing, returns -1 (not 0). - let mutable vstr = vstr.TrimStart [|'v'|] - // if the version string contains wildcards, replace them - let versionComponents = vstr.Split ([|'.'|]) - - // account for wildcards - if versionComponents.Length > 2 then - let defaultBuild = uint16 tspan.Days % UInt16.MaxValue - 1us - let defaultRevision = uint16 (DateTime.UtcNow.TimeOfDay.TotalSeconds / 2.0) % UInt16.MaxValue - 1us - if versionComponents.[2] = "*" then - if versionComponents.Length > 3 then - failwith "Invalid version format" - else - // set the build number to the number of days since Jan 1, 2000 - versionComponents.[2] <- defaultBuild.ToString() - // Set the revision number to number of seconds today / 2 - vstr <- String.Join (".", versionComponents) + "." + defaultRevision.ToString() - elif versionComponents.Length > 3 && versionComponents.[3] = "*" then - // Set the revision number to number of seconds today / 2 - versionComponents.[3] <- defaultRevision.ToString() - vstr <- String.Join (".", versionComponents) - - let version = System.Version vstr - let zero32 n = if n < 0 then 0us else uint16 n - // since the minor revision will be -1 if none is specified, we need to truncate to 0 to not break existing code - let minorRevision = if version.Revision = -1 then 0us else uint16 version.MinorRevision - ILVersionInfo (zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision) - -let compareILVersions (version1 : ILVersionInfo) (version2 : ILVersionInfo) = - let c = compare version1.Major version2.Major - if c <> 0 then c else - let c = compare version1.Minor version2.Minor - if c <> 0 then c else - let c = compare version1.Build version2.Build - if c <> 0 then c else - let c = compare version1.Revision version2.Revision - if c <> 0 then c else - 0 - let unscopeILTypeRef (x: ILTypeRef) = ILTypeRef.Create (ILScopeRef.Local, x.Enclosing, x.Name) let rec unscopeILTypeSpec (tspec: ILTypeSpec) = diff --git a/src/fsharp/absil/il.fsi b/src/fsharp/absil/il.fsi new file mode 100644 index 00000000000..d214323f2b0 --- /dev/null +++ b/src/fsharp/absil/il.fsi @@ -0,0 +1,2106 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The "unlinked" view of .NET metadata and code. Central to the Abstract IL library + +module rec FSharp.Compiler.AbstractIL.IL + +open FSharp.Compiler.IO +open System.Collections.Generic +open System.Reflection + +[] +type internal PrimaryAssembly = + | Mscorlib + | System_Runtime + | NetStandard + + member Name: string + +/// Represents guids +type ILGuid = byte[] + +[] +type ILPlatform = + internal + | X86 + | AMD64 + | IA64 + +/// Debug info. Values of type "source" can be attached at sequence +/// points and some other locations. +[] +type ILSourceDocument = + static member Create: language: ILGuid option * vendor: ILGuid option * documentType: ILGuid option * file: string -> ILSourceDocument + member Language: ILGuid option + member Vendor: ILGuid option + member DocumentType: ILGuid option + member File: string + +[] +type internal ILDebugPoint = + static member Create: document: ILSourceDocument * line: int * column: int * endLine:int * endColumn: int-> ILDebugPoint + member Document: ILSourceDocument + member Line: int + member Column: int + member EndLine: int + member EndColumn: int + +[] +type PublicKey = + | PublicKey of byte[] + | PublicKeyToken of byte[] + member IsKey: bool + member IsKeyToken: bool + member Key: byte[] + member KeyToken: byte[] + static member KeyAsToken: byte[] -> PublicKey + +[] +type ILVersionInfo = + + val Major: uint16 + val Minor: uint16 + val Build: uint16 + val Revision: uint16 + + new : major: uint16 * minor: uint16 * build: uint16 * revision: uint16 -> ILVersionInfo + +[] +type ILAssemblyRef = + static member Create: name: string * hash: byte[] option * publicKey: PublicKey option * retargetable: bool * version: ILVersionInfo option * locale: string option -> ILAssemblyRef + + static member FromAssemblyName: AssemblyName -> ILAssemblyRef + + member Name: string + + /// The fully qualified name of the assembly reference, e.g. mscorlib, Version=1.0.3705 etc. + member QualifiedName: string + + member Hash: byte[] option + + member PublicKey: PublicKey option + + /// CLI says this indicates if the assembly can be retargeted (at runtime) to be from a different publisher. + member Retargetable: bool + + member Version: ILVersionInfo option + + member Locale: string option + + member EqualsIgnoringVersion: ILAssemblyRef -> bool + + interface System.IComparable + +[] +type ILModuleRef = + static member Create: name: string * hasMetadata: bool * hash: byte[] option -> ILModuleRef + + member Name: string + + member HasMetadata: bool + + member Hash: byte[] option + + interface System.IComparable + +// Scope references +[] +type ILScopeRef = + /// A reference to the type in the current module + | Local + + /// A reference to a type in a module in the same assembly + | Module of ILModuleRef + + /// A reference to a type in another assembly + | Assembly of ILAssemblyRef + + /// A reference to a type in the primary assembly + | PrimaryAssembly + + member IsLocalRef: bool + + member QualifiedName: string + +// Calling conventions. +// +// For nearly all purposes you simply want to use ILArgConvention.Default combined +// with ILThisConvention.Instance or ILThisConvention.Static, i.e. +// ILCallingConv.Instance == Callconv(ILThisConvention.Instance, ILArgConvention.Default): for an instance method +// ILCallingConv.Static == Callconv(ILThisConvention.Static, ILArgConvention.Default): for a static method +// +// ILThisConvention.InstanceExplicit is only used by Managed C++, and indicates +// that the 'this' pointer is actually explicit in the signature. +[] +type ILArgConvention = + | Default + | CDecl + | StdCall + | ThisCall + | FastCall + | VarArg + +[] +type ILThisConvention = + /// accepts an implicit 'this' pointer + | Instance + + /// accepts an explicit 'this' pointer + | InstanceExplicit + + /// no 'this' pointer is passed + | Static + +[] +type ILCallingConv = + | Callconv of ILThisConvention * ILArgConvention + + member internal IsInstance: bool + member internal IsInstanceExplicit: bool + member internal IsStatic: bool + member internal ThisConv: ILThisConvention + member internal BasicConv: ILArgConvention + + static member Instance: ILCallingConv + static member Static : ILCallingConv + +/// Array shapes. For most purposes the rank is the only thing that matters. +type internal ILArrayBound = int32 option + +/// Lower-bound/size pairs +type internal ILArrayBounds = ILArrayBound * ILArrayBound + +type ILArrayShape = + internal + | ILArrayShape of ILArrayBounds list + + member Rank: int + + /// Bounds for a single dimensional, zero based array + static member SingleDimensional: ILArrayShape + static member FromRank: int -> ILArrayShape + +type internal ILBoxity = + | AsObject + | AsValue + +type ILGenericVariance = + | NonVariant + | CoVariant + | ContraVariant + +/// Type refs, i.e. references to types in some .NET assembly +[] +type ILTypeRef = + + /// Create a ILTypeRef. + static member Create: scope: ILScopeRef * enclosing: string list * name: string -> ILTypeRef + + /// Where is the type, i.e. is it in this module, in another module in this assembly or in another assembly? + member Scope: ILScopeRef + + /// The list of enclosing type names for a nested type. If non-nil then the first of these also contains the namespace. + member Enclosing: string list + + /// The name of the type. This also contains the namespace if Enclosing is empty. + member Name: string + + /// The name of the type in the assembly using the '.' notation for nested types. + member FullName: string + + /// The name of the type in the assembly using the '+' notation for nested types. + member BasicQualifiedName: string + + member QualifiedName: string + + member internal EqualsWithPrimaryScopeRef: ILScopeRef * obj -> bool + + interface System.IComparable + +/// Type specs and types. +[] +type ILTypeSpec = + /// Create an ILTypeSpec. + static member Create: typeRef:ILTypeRef * instantiation:ILGenericArgs -> ILTypeSpec + + /// Which type is being referred to? + member TypeRef: ILTypeRef + + /// The type instantiation if the type is generic, otherwise empty + member GenericArgs: ILGenericArgs + + /// Where is the type, i.e. is it in this module, in another module in this assembly or in another assembly? + member Scope: ILScopeRef + + /// The list of enclosing type names for a nested type. If non-nil then the first of these also contains the namespace. + member Enclosing: string list + + /// The name of the type. This also contains the namespace if Enclosing is empty. + member Name: string + + /// The name of the type in the assembly using the '.' notation for nested types. + member FullName: string + + member internal EqualsWithPrimaryScopeRef: ILScopeRef * obj -> bool + + interface System.IComparable + +[] +type ILType = + + /// Used only in return and pointer types. + | Void + + /// Array types + | Array of ILArrayShape * ILType + + /// Unboxed types, including builtin types. + | Value of ILTypeSpec + + /// Reference types. Also may be used for parents of members even if for members in value types. + | Boxed of ILTypeSpec + + /// Unmanaged pointers. Nb. the type is used by tools and for binding only, not by the verifier. + | Ptr of ILType + + /// Managed pointers. + | Byref of ILType + + /// ILCode pointers. + | FunctionPointer of ILCallingSignature + + /// Reference a generic arg. + | TypeVar of uint16 + + /// Custom modifiers. + | Modified of + /// True if modifier is "required". + bool * + /// The class of the custom modifier. + ILTypeRef * + /// The type being modified. + ILType + + member TypeSpec: ILTypeSpec + + member internal Boxity: ILBoxity + + member TypeRef: ILTypeRef + + member IsNominal: bool + + member GenericArgs: ILGenericArgs + + member IsTyvar: bool + + member BasicQualifiedName: string + + member QualifiedName: string + +[] +type ILCallingSignature = + { CallingConv: ILCallingConv + ArgTypes: ILTypes + ReturnType: ILType } + +/// Actual generic parameters are always types. +type ILGenericArgs = ILType list + +type ILTypes = ILType list + +/// Formal identities of methods. +[] +type ILMethodRef = + + /// Functional creation + static member Create: + enclosingTypeRef: ILTypeRef * + callingConv: ILCallingConv * + name: string * + genericArity: int * + argTypes: ILTypes * + returnType: ILType -> ILMethodRef + + member DeclaringTypeRef: ILTypeRef + + member CallingConv: ILCallingConv + + member Name: string + + member GenericArity: int + + member ArgCount: int + + member ArgTypes: ILTypes + + member ReturnType: ILType + + member CallingSignature: ILCallingSignature + + interface System.IComparable + +/// Formal identities of fields. +[] +type ILFieldRef = + { DeclaringTypeRef: ILTypeRef + Name: string + Type: ILType } + +/// The information at the callsite of a method +[] +type ILMethodSpec = + + /// Functional creation + static member Create: ILType * ILMethodRef * ILGenericArgs -> ILMethodSpec + + member MethodRef: ILMethodRef + + member DeclaringType: ILType + + member GenericArgs: ILGenericArgs + + member CallingConv: ILCallingConv + + member GenericArity: int + + member Name: string + + member FormalArgTypes: ILTypes + + member FormalReturnType: ILType + + interface System.IComparable + +/// Field specs. The data given for a ldfld, stfld etc. instruction. +[] +type ILFieldSpec = + { FieldRef: ILFieldRef + DeclaringType: ILType } + + member DeclaringTypeRef: ILTypeRef + + member Name: string + + member FormalType: ILType + + member ActualType: ILType + +/// ILCode labels. In structured code each code label refers to a basic block somewhere in the code of the method. +type internal ILCodeLabel = int + +[] +type internal ILBasicType = + | DT_R + | DT_I1 + | DT_U1 + | DT_I2 + | DT_U2 + | DT_I4 + | DT_U4 + | DT_I8 + | DT_U8 + | DT_R4 + | DT_R8 + | DT_I + | DT_U + | DT_REF + +[] +type internal ILToken = + | ILType of ILType + | ILMethod of ILMethodSpec + | ILField of ILFieldSpec + +[] +type internal ILConst = + | I4 of int32 + | I8 of int64 + | R4 of single + | R8 of double + +type internal ILTailcall = + | Tailcall + | Normalcall + +type internal ILAlignment = + | Aligned + | Unaligned1 + | Unaligned2 + | Unaligned4 + +type internal ILVolatility = + | Volatile + | Nonvolatile + +type internal ILReadonly = + | ReadonlyAddress + | NormalAddress + +type internal ILVarArgs = ILTypes option + +[] +type internal ILComparisonInstr = + | BI_beq + | BI_bge + | BI_bge_un + | BI_bgt + | BI_bgt_un + | BI_ble + | BI_ble_un + | BI_blt + | BI_blt_un + | BI_bne_un + | BI_brfalse + | BI_brtrue + +/// The instruction set. +[] +type internal ILInstr = + | AI_add + | AI_add_ovf + | AI_add_ovf_un + | AI_and + | AI_div + | AI_div_un + | AI_ceq + | AI_cgt + | AI_cgt_un + | AI_clt + | AI_clt_un + | AI_conv of ILBasicType + | AI_conv_ovf of ILBasicType + | AI_conv_ovf_un of ILBasicType + | AI_mul + | AI_mul_ovf + | AI_mul_ovf_un + | AI_rem + | AI_rem_un + | AI_shl + | AI_shr + | AI_shr_un + | AI_sub + | AI_sub_ovf + | AI_sub_ovf_un + | AI_xor + | AI_or + | AI_neg + | AI_not + | AI_ldnull + | AI_dup + | AI_pop + | AI_ckfinite + | AI_nop + | AI_ldc of ILBasicType * ILConst + | I_ldarg of uint16 + | I_ldarga of uint16 + | I_ldind of ILAlignment * ILVolatility * ILBasicType + | I_ldloc of uint16 + | I_ldloca of uint16 + | I_starg of uint16 + | I_stind of ILAlignment * ILVolatility * ILBasicType + | I_stloc of uint16 + + // Control transfer + | I_br of ILCodeLabel + | I_jmp of ILMethodSpec + | I_brcmp of ILComparisonInstr * ILCodeLabel + | I_switch of ILCodeLabel list + | I_ret + + // Method call + | I_call of ILTailcall * ILMethodSpec * ILVarArgs + | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs + | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs + | I_calli of ILTailcall * ILCallingSignature * ILVarArgs + | I_ldftn of ILMethodSpec + | I_newobj of ILMethodSpec * ILVarArgs + + // Exceptions + | I_throw + | I_endfinally + | I_endfilter + | I_leave of ILCodeLabel + | I_rethrow + + // Object instructions + | I_ldsfld of ILVolatility * ILFieldSpec + | I_ldfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldsflda of ILFieldSpec + | I_ldflda of ILFieldSpec + | I_stsfld of ILVolatility * ILFieldSpec + | I_stfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldstr of string + | I_isinst of ILType + | I_castclass of ILType + | I_ldtoken of ILToken + | I_ldvirtftn of ILMethodSpec + + // Value type instructions + | I_cpobj of ILType + | I_initobj of ILType + | I_ldobj of ILAlignment * ILVolatility * ILType + | I_stobj of ILAlignment * ILVolatility * ILType + | I_box of ILType + | I_unbox of ILType + | I_unbox_any of ILType + | I_sizeof of ILType + + // Generalized array instructions. In AbsIL these instructions include + // both the single-dimensional variants (with ILArrayShape == ILArrayShape.SingleDimensional) + // and calls to the "special" multi-dimensional "methods" such as: + // newobj void string[,]::.ctor(int32, int32) + // call string string[,]::Get(int32, int32) + // call string& string[,]::Address(int32, int32) + // call void string[,]::Set(int32, int32,string) + // + // The IL reader transforms calls of this form to the corresponding + // generalized instruction with the corresponding ILArrayShape + // argument. This is done to simplify the IL and make it more uniform. + // The IL writer then reverses this when emitting the binary. + | I_ldelem of ILBasicType + | I_stelem of ILBasicType + | I_ldelema of ILReadonly * bool * ILArrayShape * ILType + | I_ldelem_any of ILArrayShape * ILType + | I_stelem_any of ILArrayShape * ILType + | I_newarr of ILArrayShape * ILType + | I_ldlen + + // "System.TypedReference" related instructions: almost + // no languages produce these, though they do occur in mscorlib.dll + // System.TypedReference represents a pair of a type and a byref-pointer + // to a value of that type. + | I_mkrefany of ILType + | I_refanytype + | I_refanyval of ILType + + // Debug-specific + // I_seqpoint is a fake instruction to represent a sequence point: + // the next instruction starts the execution of the + // statement covered by the given range - this is a + // dummy instruction and is not emitted + | I_break + | I_seqpoint of ILDebugPoint + + // Varargs - C++ only + | I_arglist + + // Local aggregates, i.e. stack allocated data (alloca): C++ only + | I_localloc + | I_cpblk of ILAlignment * ILVolatility + | I_initblk of ILAlignment * ILVolatility + + // EXTENSIONS + | EI_ilzero of ILType + | EI_ldlen_multi of int32 * int32 + +[] +type internal ILExceptionClause = + | Finally of (ILCodeLabel * ILCodeLabel) + | Fault of (ILCodeLabel * ILCodeLabel) + | FilterCatch of filterRange: (ILCodeLabel * ILCodeLabel) * handlerRange: (ILCodeLabel * ILCodeLabel) + | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel) + +[] +type internal ILExceptionSpec = + { Range: ILCodeLabel * ILCodeLabel + Clause: ILExceptionClause } + +/// Indicates that a particular local variable has a particular source +/// language name within a given set of ranges. This does not effect local +/// variable numbering, which is global over the whole method. +[] +type internal ILLocalDebugMapping = + { LocalIndex: int + LocalName: string } + +[] +type internal ILLocalDebugInfo = + { Range: ILCodeLabel * ILCodeLabel; + DebugMappings: ILLocalDebugMapping list } + +[] +type internal ILCode = + { Labels: Dictionary + Instrs:ILInstr[] + Exceptions: ILExceptionSpec list + Locals: ILLocalDebugInfo list } + +/// Field Init +[] +type ILFieldInit = + | String of string + | Bool of bool + | Char of uint16 + | Int8 of sbyte + | Int16 of int16 + | Int32 of int32 + | Int64 of int64 + | UInt8 of byte + | UInt16 of uint16 + | UInt32 of uint32 + | UInt64 of uint64 + | Single of single + | Double of double + | Null + + member AsObject: unit -> obj + +[] +type internal ILNativeVariant = + | Empty + | Null + | Variant + | Currency + | Decimal + | Date + | BSTR + | LPSTR + | LPWSTR + | IUnknown + | IDispatch + | SafeArray + | Error + | HRESULT + | CArray + | UserDefined + | Record + | FileTime + | Blob + | Stream + | Storage + | StreamedObject + | StoredObject + | BlobObject + | CF + | CLSID + | Void + | Bool + | Int8 + | Int16 + | Int32 + | Int64 + | Single + | Double + | UInt8 + | UInt16 + | UInt32 + | UInt64 + | PTR + | Array of ILNativeVariant + | Vector of ILNativeVariant + | Byref of ILNativeVariant + | Int + | UInt + +/// Native Types, for marshalling to the native C interface. +/// These are taken directly from the ILASM syntax. +/// Most of these are listed in the CLI ECMA-335 Spec (Partition II, 7.4). +[] +type ILNativeType = + | Empty + | Custom of ILGuid * nativeTypeName: string * custMarshallerName: string * cookieString: byte[] + | FixedSysString of int32 + | FixedArray of int32 + | Currency + | LPSTR + | LPWSTR + | LPTSTR + | LPUTF8STR + | ByValStr + | TBSTR + | LPSTRUCT + | Struct + | Void + | Bool + | Int8 + | Int16 + | Int32 + | Int64 + | Single + | Double + | Byte + | UInt16 + | UInt32 + | UInt64 + /// optional idx of parameter giving size plus optional additive i.e. num elems + | Array of ILNativeType option * (int32 * int32 option) option + | Int + | UInt + | Method + | AsAny + | BSTR + | IUnknown + | IDispatch + | Interface + | Error + | SafeArray of ILNativeVariant * string option + | ANSIBSTR + | VariantBool + +/// Local variables +[] +type internal ILLocal = + { Type: ILType + IsPinned: bool + DebugInfo: (string * int * int) option } + +type internal ILLocals = list + +/// Defines an opened namespace, type relevant to a code location. +/// +/// Emitted to the PortablePDB format. Note the format supports additional variations on +/// imported things that are not yet emitted in F#. +[] +type ILDebugImport = + + /// Represents an 'open type XYZ' opening a type + | ImportType of targetType: ILType // * alias: string option + + /// Represents an 'open XYZ' opening a namespace + | ImportNamespace of targetNamespace: string // * assembly: ILAssemblyRef option * alias: string option + + //| ReferenceAlias of string + //| OpenXmlNamespace of prefix: string * xmlNamespace: string + +/// Defines a set of opened namespace, type relevant to a code location. +/// +/// Emitted to the PortablePDB format. +type ILDebugImports = + { + Parent: ILDebugImports option + Imports: ILDebugImport[] + } + +/// IL method bodies +[] +type internal ILMethodBody = + { + IsZeroInit: bool + MaxStack: int32 + NoInlining: bool + AggressiveInlining: bool + Locals: ILLocals + Code: ILCode + DebugPoint: ILDebugPoint option + DebugImports: ILDebugImports option + } + +/// Member Access +[] +type ILMemberAccess = + | Assembly + | CompilerControlled + | FamilyAndAssembly + | FamilyOrAssembly + | Family + | Private + | Public + +[] +type ILAttribElem = + /// Represents a custom attribute parameter of type 'string'. These may be null, in which case they are encoded in a special + /// way as indicated by Ecma-335 Partition II. + | String of string option + | Bool of bool + | Char of char + | SByte of sbyte + | Int16 of int16 + | Int32 of int32 + | Int64 of int64 + | Byte of byte + | UInt16 of uint16 + | UInt32 of uint32 + | UInt64 of uint64 + | Single of single + | Double of double + | Null + | Type of ILType option + | TypeRef of ILTypeRef option + | Array of ILType * ILAttribElem list + +/// Named args: values and flags indicating if they are fields or properties. +type ILAttributeNamedArg = string * ILType * bool * ILAttribElem + +/// Custom attribute. +type ILAttribute = + /// Attribute with args encoded to a binary blob according to ECMA-335 II.21 and II.23.3. + /// 'decodeILAttribData' is used to parse the byte[] blob to ILAttribElem's as best as possible. + | Encoded of method: ILMethodSpec * data: byte[] * elements: ILAttribElem list + + /// Attribute with args in decoded form. + | Decoded of method: ILMethodSpec * fixedArgs: ILAttribElem list * namedArgs: ILAttributeNamedArg list + + /// Attribute instance constructor. + member internal Method: ILMethodSpec + + /// Decoded arguments. May be empty in encoded attribute form. + member internal Elements: ILAttribElem list + + member internal WithMethod: method: ILMethodSpec -> ILAttribute + +[] +type ILAttributes = + member AsArray: ILAttribute [] + + member AsList: ILAttribute list + +/// Represents the efficiency-oriented storage of ILAttributes in another item. +[] +type ILAttributesStored + +/// Method parameters and return values. +[] +type ILParameter = + { Name: string option + Type: ILType + Default: ILFieldInit option + /// Marshalling map for parameters. COM Interop only. + Marshal: ILNativeType option + IsIn: bool + IsOut: bool + IsOptional: bool + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + member CustomAttrs: ILAttributes + +type ILParameters = ILParameter list + +val internal typesOfILParams: ILParameters -> ILType list + +/// Method return values. +[] +type ILReturn = + { Marshal: ILNativeType option + Type: ILType + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + + member CustomAttrs: ILAttributes + + member WithCustomAttrs: customAttrs: ILAttributes -> ILReturn + +[] +type internal ILSecurityAction = + | Request + | Demand + | Assert + | Deny + | PermitOnly + | LinkCheck + | InheritCheck + | ReqMin + | ReqOpt + | ReqRefuse + | PreJitGrant + | PreJitDeny + | NonCasDemand + | NonCasLinkDemand + | NonCasInheritance + | LinkDemandChoice + | InheritanceDemandChoice + | DemandChoice + +type internal ILSecurityDecl = + | ILSecurityDecl of ILSecurityAction * byte[] + +/// Abstract type equivalent to ILSecurityDecl list - use helpers +/// below to construct/destruct these. +[] +type internal ILSecurityDecls = + member AsList: ILSecurityDecl list + +/// Represents the efficiency-oriented storage of ILSecurityDecls in another item. +[] +type ILSecurityDeclsStored + +/// PInvoke attributes. +[] +type internal PInvokeCallingConvention = + | None + | Cdecl + | Stdcall + | Thiscall + | Fastcall + | WinApi + +[] +type internal PInvokeCharEncoding = + | None + | Ansi + | Unicode + | Auto + +[] +type internal PInvokeCharBestFit = + | UseAssembly + | Enabled + | Disabled + +[] +type internal PInvokeThrowOnUnmappableChar = + | UseAssembly + | Enabled + | Disabled + +[] +type internal PInvokeMethod = + { Where: ILModuleRef + Name: string + CallingConv: PInvokeCallingConvention + CharEncoding: PInvokeCharEncoding + NoMangle: bool + LastError: bool + ThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar + CharBestFit: PInvokeCharBestFit } + +/// Represents a reference to a method declaration in a superclass or interface. +type internal ILOverridesSpec = + | OverridesSpec of ILMethodRef * ILType + member MethodRef: ILMethodRef + member DeclaringType: ILType + +[] +type MethodBody = + | IL of Lazy + | PInvoke of Lazy + | Abstract + | Native + | NotAvailable + +/// Generic parameters. Formal generic parameter declarations may include the bounds, if any, on the generic parameter. +type ILGenericParameterDef = + { Name: string + + /// At most one is the parent type, the others are interface types. + Constraints: ILTypes + + /// Variance of type parameters, only applicable to generic parameters for generic interfaces and delegates. + Variance: ILGenericVariance + + /// Indicates the type argument must be a reference type. + HasReferenceTypeConstraint: bool + + /// Indicates the type argument must be a value type, but not Nullable. + HasNotNullableValueTypeConstraint: bool + + /// Indicates the type argument must have a public nullary constructor. + HasDefaultConstructorConstraint: bool + + /// Do not use this + CustomAttrsStored: ILAttributesStored + + /// Do not use this + MetadataIndex: int32 } + + member CustomAttrs: ILAttributes + +type ILGenericParameterDefs = ILGenericParameterDef list + +/// IL Method definitions. +[] +type ILMethodDef = + + /// Functional creation of a value, with delayed reading of some elements via a metadata index + internal new: + name: string * attributes: MethodAttributes * implAttributes: MethodImplAttributes * callingConv: ILCallingConv * + parameters: ILParameters * ret: ILReturn * body: Lazy * isEntryPoint:bool * genericParams: ILGenericParameterDefs * + securityDeclsStored: ILSecurityDeclsStored * customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILMethodDef + + /// Functional creation of a value, immediate + new: name: string * attributes: MethodAttributes * implAttributes: MethodImplAttributes * callingConv: ILCallingConv * + parameters: ILParameters * ret: ILReturn * body: Lazy * isEntryPoint:bool * genericParams: ILGenericParameterDefs * + securityDecls: ILSecurityDecls * customAttrs: ILAttributes -> ILMethodDef + + member Name: string + member Attributes: MethodAttributes + member ImplAttributes: MethodImplAttributes + member CallingConv: ILCallingConv + member Parameters: ILParameters + member Return: ILReturn + member Body: MethodBody + member SecurityDecls: ILSecurityDecls + member IsEntryPoint:bool + member GenericParams: ILGenericParameterDefs + member CustomAttrs: ILAttributes + member ParameterTypes: ILTypes + member IsIL: bool + member Code: ILCode option + member Locals: ILLocals + member MaxStack: int32 + member IsZeroInit: bool + + /// Indicates a .cctor method. + member IsClassInitializer: bool + + /// Indicates a .ctor method. + member IsConstructor: bool + + /// Indicates a static method. + member IsStatic: bool + + /// Indicates this is an instance methods that is not virtual. + member IsNonVirtualInstance: bool + + /// Indicates an instance methods that is virtual or abstract or implements an interface slot. + member IsVirtual: bool + + member IsFinal: bool + member IsNewSlot: bool + member IsCheckAccessOnOverride: bool + member IsAbstract: bool + member MethodBody: ILMethodBody + member CallingSignature: ILCallingSignature + member Access: ILMemberAccess + member IsHideBySig: bool + member IsSpecialName: bool + + /// The method is exported to unmanaged code using COM interop. + member IsUnmanagedExport: bool + member IsReqSecObj: bool + + /// Some methods are marked "HasSecurity" even if there are no permissions attached, e.g. if they use SuppressUnmanagedCodeSecurityAttribute + member HasSecurity: bool + member IsManaged: bool + member IsForwardRef: bool + member IsInternalCall: bool + member IsPreserveSig: bool + member IsSynchronized: bool + member IsNoInline: bool + member IsAggressiveInline: bool + + /// SafeHandle finalizer must be run. + member IsMustRun: bool + + /// Functional update of the value + member internal + With: ?name: string * ?attributes: MethodAttributes * ?implAttributes: MethodImplAttributes * ?callingConv: ILCallingConv * + ?parameters: ILParameters * ?ret: ILReturn * ?body: Lazy * ?securityDecls: ILSecurityDecls * ?isEntryPoint:bool * + ?genericParams: ILGenericParameterDefs * ?customAttrs: ILAttributes -> ILMethodDef + member internal WithSpecialName: ILMethodDef + member internal WithHideBySig: unit -> ILMethodDef + member internal WithHideBySig: bool -> ILMethodDef + member internal WithFinal: bool -> ILMethodDef + member internal WithAbstract: bool -> ILMethodDef + member internal WithAccess: ILMemberAccess -> ILMethodDef + member internal WithNewSlot: ILMethodDef + member internal WithSecurity: bool -> ILMethodDef + member internal WithPInvoke: bool -> ILMethodDef + member internal WithPreserveSig: bool -> ILMethodDef + member internal WithSynchronized: bool -> ILMethodDef + member internal WithNoInlining: bool -> ILMethodDef + member internal WithAggressiveInlining: bool -> ILMethodDef + member internal WithRuntime: bool -> ILMethodDef + +/// Tables of methods. Logically equivalent to a list of methods but +/// the table is kept in a form optimized for looking up methods by +/// name and arity. +[] +type ILMethodDefs = + interface IEnumerable + member AsArray: ILMethodDef[] + member AsList: ILMethodDef list + member FindByName: string -> ILMethodDef list + member TryFindInstanceByNameAndCallingSignature: string * ILCallingSignature -> ILMethodDef option + +/// Field definitions. +[] +type ILFieldDef = + + /// Functional creation of a value using delayed reading via a metadata index + internal new: + name: string * fieldType: ILType * attributes: FieldAttributes * data: byte[] option * + literalValue: ILFieldInit option * offset: int32 option * marshal: ILNativeType option * + customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILFieldDef + + /// Functional creation of a value, immediate + new: name: string * fieldType: ILType * attributes: FieldAttributes * data: byte[] option * + literalValue: ILFieldInit option * offset: int32 option * marshal: ILNativeType option * + customAttrs: ILAttributes -> ILFieldDef + + member Name: string + member FieldType: ILType + member Attributes: FieldAttributes + member Data: byte[] option + member LiteralValue: ILFieldInit option + + /// The explicit offset in bytes when explicit layout is used. + member Offset: int32 option + member Marshal: ILNativeType option + member CustomAttrs: ILAttributes + member IsStatic: bool + member IsSpecialName: bool + member IsLiteral: bool + member NotSerialized: bool + member IsInitOnly: bool + member Access: ILMemberAccess + + /// Functional update of the value + member internal With: + ?name: string * ?fieldType: ILType * ?attributes: FieldAttributes * ?data: byte[] option * ?literalValue: ILFieldInit option * + ?offset: int32 option * ?marshal: ILNativeType option * ?customAttrs: ILAttributes -> ILFieldDef + member internal WithAccess: ILMemberAccess -> ILFieldDef + member internal WithInitOnly: bool -> ILFieldDef + member internal WithStatic: bool -> ILFieldDef + member internal WithSpecialName: bool -> ILFieldDef + member internal WithNotSerialized: bool -> ILFieldDef + member internal WithLiteralDefaultValue: ILFieldInit option -> ILFieldDef + member internal WithFieldMarshal: ILNativeType option -> ILFieldDef + +/// Tables of fields. Logically equivalent to a list of fields but the table is kept in +/// a form to allow efficient looking up fields by name. +[] +type ILFieldDefs = + member internal AsList: ILFieldDef list + member internal LookupByName: string -> ILFieldDef list + +/// Event definitions. +[] +type ILEventDef = + + /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs + internal new: + eventType: ILType option * name: string * attributes: EventAttributes * addMethod: ILMethodRef * + removeMethod: ILMethodRef * fireMethod: ILMethodRef option * otherMethods: ILMethodRef list * + customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILEventDef + + /// Functional creation of a value, immediate + new: eventType: ILType option * name: string * attributes: EventAttributes * addMethod: ILMethodRef * + removeMethod: ILMethodRef * fireMethod: ILMethodRef option * otherMethods: ILMethodRef list * + customAttrs: ILAttributes -> ILEventDef + + member EventType: ILType option + member Name: string + member Attributes: EventAttributes + member AddMethod: ILMethodRef + member RemoveMethod: ILMethodRef + member FireMethod: ILMethodRef option + member OtherMethods: ILMethodRef list + member CustomAttrs: ILAttributes + member IsSpecialName: bool + member IsRTSpecialName: bool + + /// Functional update of the value + member internal With: + ?eventType: ILType option * ?name: string * ?attributes: EventAttributes * ?addMethod: ILMethodRef * + ?removeMethod: ILMethodRef * ?fireMethod: ILMethodRef option * ?otherMethods: ILMethodRef list * + ?customAttrs: ILAttributes -> ILEventDef + +/// Table of those events in a type definition. +[] +type ILEventDefs = + member internal AsList: ILEventDef list + member internal LookupByName: string -> ILEventDef list + +/// Property definitions +[] +type ILPropertyDef = + + /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs + internal new: + name: string * attributes: PropertyAttributes * setMethod: ILMethodRef option * getMethod: ILMethodRef option * + callingConv: ILThisConvention * propertyType: ILType * init: ILFieldInit option * args: ILTypes * + customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILPropertyDef + + /// Functional creation of a value, immediate + new: name: string * attributes: PropertyAttributes * setMethod: ILMethodRef option * getMethod: ILMethodRef option * + callingConv: ILThisConvention * propertyType: ILType * init: ILFieldInit option * args: ILTypes * + customAttrs: ILAttributes -> ILPropertyDef + + member Name: string + member Attributes: PropertyAttributes + member SetMethod: ILMethodRef option + member GetMethod: ILMethodRef option + member CallingConv: ILThisConvention + member PropertyType: ILType + member Init: ILFieldInit option + member Args: ILTypes + member CustomAttrs: ILAttributes + member IsSpecialName: bool + member IsRTSpecialName: bool + + /// Functional update of the value + member internal With: + ?name: string * ?attributes: PropertyAttributes * ?setMethod: ILMethodRef option * ?getMethod: ILMethodRef option * + ?callingConv: ILThisConvention * ?propertyType: ILType * ?init: ILFieldInit option * ?args: ILTypes * + ?customAttrs: ILAttributes -> ILPropertyDef + +/// Table of properties in an IL type definition. +[] +[] +type ILPropertyDefs = + member internal AsList: ILPropertyDef list + member internal LookupByName: string -> ILPropertyDef list + +/// Method Impls +type ILMethodImplDef = + { Overrides: ILOverridesSpec + OverrideBy: ILMethodSpec } + +[] +type ILMethodImplDefs = + member internal AsList: ILMethodImplDef list + +/// Type Layout information. +[] +type ILTypeDefLayout = + | Auto + | Sequential of ILTypeDefLayoutInfo + | Explicit of ILTypeDefLayoutInfo + +type internal ILTypeDefLayoutInfo = + { Size: int32 option + Pack: uint16 option } + +/// Indicate the initialization semantics of a type. +[] +type ILTypeInit = + | BeforeField + | OnAny + +/// Default Unicode encoding for P/Invoke within a type. +[] +type ILDefaultPInvokeEncoding = + | Ansi + | Auto + | Unicode + +/// Type Access. +[] +type ILTypeDefAccess = + | Public + | Private + | Nested of ILMemberAccess + +/// A categorization of type definitions into "kinds" +[] +type ILTypeDefKind = + | Class + | ValueType + | Interface + | Enum + | Delegate + +/// Tables of named type definitions. +[] +type ILTypeDefs = + interface IEnumerable + + member internal AsArray: ILTypeDef[] + + member internal AsList: ILTypeDef list + + /// Get some information about the type defs, but do not force the read of the type defs themselves. + member internal AsArrayOfPreTypeDefs: ILPreTypeDef[] + + /// Calls to FindByName will result in any laziness in the overall + /// set of ILTypeDefs being read in in addition + /// to the details for the type found, but the remaining individual + /// type definitions will not be read. + member internal FindByName: string -> ILTypeDef + +/// Represents IL Type Definitions. +[] +type ILTypeDef = + + /// Functional creation of a value, using delayed reading via a metadata index, for ilread.fs + internal new: + name: string * attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * genericParams: ILGenericParameterDefs * + extends: ILType option * methods: ILMethodDefs * nestedTypes: ILTypeDefs * fields: ILFieldDefs * methodImpls: ILMethodImplDefs * + events: ILEventDefs * properties: ILPropertyDefs * securityDeclsStored: ILSecurityDeclsStored * customAttrsStored: ILAttributesStored * metadataIndex: int32 -> ILTypeDef + + /// Functional creation of a value, immediate + new: name: string * attributes: TypeAttributes * layout: ILTypeDefLayout * implements: ILTypes * genericParams: ILGenericParameterDefs * + extends: ILType option * methods: ILMethodDefs * nestedTypes: ILTypeDefs * fields: ILFieldDefs * methodImpls: ILMethodImplDefs * + events: ILEventDefs * properties: ILPropertyDefs * securityDecls: ILSecurityDecls * customAttrs: ILAttributes -> ILTypeDef + + member Name: string + member Attributes: TypeAttributes + member GenericParams: ILGenericParameterDefs + member Layout: ILTypeDefLayout + member NestedTypes: ILTypeDefs + member Implements: ILTypes + member Extends: ILType option + member Methods: ILMethodDefs + member SecurityDecls: ILSecurityDecls + member Fields: ILFieldDefs + member MethodImpls: ILMethodImplDefs + member Events: ILEventDefs + member Properties: ILPropertyDefs + member CustomAttrs: ILAttributes + member IsClass: bool + member IsStruct: bool + member IsInterface: bool + member IsEnum: bool + member IsDelegate: bool + member IsStructOrEnum: bool + member Access: ILTypeDefAccess + member IsAbstract: bool + member IsSealed: bool + member IsSerializable: bool + /// Class or interface generated for COM interop. + member IsComInterop: bool + member IsSpecialName: bool + /// Some classes are marked "HasSecurity" even if there are no permissions attached, + /// e.g. if they use SuppressUnmanagedCodeSecurityAttribute + member HasSecurity: bool + member Encoding: ILDefaultPInvokeEncoding + + member internal WithAccess: ILTypeDefAccess -> ILTypeDef + member internal WithNestedAccess: ILMemberAccess -> ILTypeDef + member internal WithSealed: bool -> ILTypeDef + member internal WithSerializable: bool -> ILTypeDef + member internal WithAbstract: bool -> ILTypeDef + member internal WithImport: bool -> ILTypeDef + member internal WithHasSecurity: bool -> ILTypeDef + member internal WithLayout: ILTypeDefLayout -> ILTypeDef + member internal WithKind: ILTypeDefKind -> ILTypeDef + member internal WithEncoding: ILDefaultPInvokeEncoding -> ILTypeDef + member internal WithSpecialName: bool -> ILTypeDef + member internal WithInitSemantics: ILTypeInit -> ILTypeDef + + /// Functional update + member With: ?name: string * ?attributes: TypeAttributes * ?layout: ILTypeDefLayout * ?implements: ILTypes * + ?genericParams:ILGenericParameterDefs * ?extends:ILType option * ?methods:ILMethodDefs * + ?nestedTypes:ILTypeDefs * ?fields: ILFieldDefs * ?methodImpls:ILMethodImplDefs * ?events:ILEventDefs * + ?properties:ILPropertyDefs * ?customAttrs:ILAttributes * ?securityDecls: ILSecurityDecls -> ILTypeDef + +/// Represents a prefix of information for ILTypeDef. +/// +/// The information is enough to perform name resolution for the F# compiler, probe attributes +/// for ExtensionAttribute etc. This is key to the on-demand exploration of .NET metadata. +/// This information has to be "Goldilocks" - not too much, not too little, just right. +[] +type ILPreTypeDef = + abstract Namespace: string list + abstract Name: string + /// Realise the actual full typedef + abstract GetTypeDef : unit -> ILTypeDef + + +[] +type internal ILPreTypeDefImpl = + interface ILPreTypeDef + +[] +type internal ILTypeDefStored + +val internal mkILPreTypeDef : ILTypeDef -> ILPreTypeDef +val internal mkILPreTypeDefComputed : string list * string * (unit -> ILTypeDef) -> ILPreTypeDef +val internal mkILPreTypeDefRead : string list * string * int32 * ILTypeDefStored -> ILPreTypeDef +val internal mkILTypeDefReader: (int32 -> ILTypeDef) -> ILTypeDefStored + +[] +type ILNestedExportedTypes = + member internal AsList: ILNestedExportedType list + +/// "Classes Elsewhere" - classes in auxiliary modules. +/// +/// Manifests include declarations for all the classes in an +/// assembly, regardless of which module they are in. +/// +/// The ".class extern" construct describes so-called exported types -- +/// these are public classes defined in the auxiliary modules of this assembly, +/// i.e. modules other than the manifest-carrying module. +/// +/// For example, if you have a two-module +/// assembly (A.DLL and B.DLL), and the manifest resides in the A.DLL, +/// then in the manifest all the public classes declared in B.DLL should +/// be defined as exported types, i.e., as ".class extern". The public classes +/// defined in A.DLL should not be defined as ".class extern" -- they are +/// already available in the manifest-carrying module. The union of all +/// public classes defined in the manifest-carrying module and all +/// exported types defined there is the set of all classes exposed by +/// this assembly. Thus, by analysing the metadata of the manifest-carrying +/// module of an assembly, you can identify all the classes exposed by +/// this assembly, and where to find them. +/// +/// Nested classes found in external modules should also be located in +/// this table, suitably nested inside another "ILExportedTypeOrForwarder" +/// definition. + +/// these are only found in the "Nested" field of ILExportedTypeOrForwarder objects +// REVIEW: fold this into ILExportedTypeOrForwarder. There's not much value in keeping these distinct +type ILNestedExportedType = + { Name: string + Access: ILMemberAccess + Nested: ILNestedExportedTypes + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + + member CustomAttrs: ILAttributes + +/// these are only found in the ILExportedTypesAndForwarders table in the manifest +[] +type ILExportedTypeOrForwarder = + { ScopeRef: ILScopeRef + /// [Namespace.]Name + Name: string + Attributes: TypeAttributes + Nested: ILNestedExportedTypes + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + + member Access: ILTypeDefAccess + + member IsForwarder: bool + + member CustomAttrs: ILAttributes + +[] +[] +type ILExportedTypesAndForwarders = + member internal AsList: ILExportedTypeOrForwarder list + member internal TryFindByName: string -> ILExportedTypeOrForwarder option + +[] +type internal ILResourceAccess = + | Public + | Private + +[] +type internal ILResourceLocation = + + /// Represents a manifest resource that can be read or written to a PE file + | Local of ByteStorage + + /// Represents a manifest resource in an associated file + | File of ILModuleRef * int32 + + /// Represents a manifest resource in a different assembly + | Assembly of ILAssemblyRef + +/// "Manifest ILResources" are chunks of resource data, being one of: +/// - the data section of the current module (byte[] of resource given directly). +/// - in an external file in this assembly (offset given in the ILResourceLocation field). +/// - as a resources in another assembly of the same name. +type internal ILResource = + { Name: string + Location: ILResourceLocation + Access: ILResourceAccess + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + + /// Read the bytes from a resource local to an assembly. Will fail for non-local resources. + member internal GetBytes : unit -> ReadOnlyByteMemory + + member CustomAttrs: ILAttributes + +/// Table of resources in a module. +[] +[] +type ILResources = + member internal AsList: ILResource list + +[] +type ILAssemblyLongevity = + internal + | Unspecified + | Library + | PlatformAppDomain + | PlatformProcess + | PlatformSystem + + static member Default : ILAssemblyLongevity + +/// The main module of an assembly is a module plus some manifest information. +type ILAssemblyManifest = + { Name: string + /// This is the ID of the algorithm used for the hashes of auxiliary + /// files in the assembly. These hashes are stored in the + /// ILModuleRef.Hash fields of this assembly. These are not + /// cryptographic hashes: they are simple file hashes. The algorithm + /// is normally 0x00008004 indicating the SHA1 hash algorithm. + AuxModuleHashAlgorithm: int32 + + SecurityDeclsStored: ILSecurityDeclsStored + + /// This is the public key used to sign this + /// assembly (the signature itself is stored elsewhere: see the + /// binary format, and may not have been written if delay signing + /// is used). (member Name, member PublicKey) forms the full + /// public name of the assembly. + PublicKey: byte[] option + + Version: ILVersionInfo option + + Locale: string option + + CustomAttrsStored: ILAttributesStored + + AssemblyLongevity: ILAssemblyLongevity + + DisableJitOptimizations: bool + + JitTracking: bool + + IgnoreSymbolStoreSequencePoints: bool + + Retargetable: bool + + /// Records the types implemented by this assembly in auxiliary + /// modules. + ExportedTypes: ILExportedTypesAndForwarders + + /// Records whether the entrypoint resides in another module. + EntrypointElsewhere: ILModuleRef option + + MetadataIndex: int32 + } + member CustomAttrs: ILAttributes + member SecurityDecls: ILSecurityDecls + + +[] +type ILNativeResource = + internal + /// Represents a native resource to be read from the PE file + | In of fileName: string * linkedResourceBase: int * linkedResourceStart: int * linkedResourceLength: int + + /// Represents a native resource to be written in an output file + | Out of unlinkedResource: byte[] + +/// One module in the "current" assembly, either a main-module or +/// an auxiliary module. The main module will have a manifest. +/// +/// An assembly is built by joining together a "main" module plus +/// several auxiliary modules. +type ILModuleDef = + { Manifest: ILAssemblyManifest option + Name: string + TypeDefs: ILTypeDefs + SubsystemVersion: int * int + UseHighEntropyVA: bool + SubSystemFlags: int32 + IsDLL: bool + IsILOnly: bool + Platform: ILPlatform option + StackReserveSize: int32 option + Is32Bit: bool + Is32BitPreferred: bool + Is64Bit: bool + VirtualAlignment: int32 + PhysicalAlignment: int32 + ImageBase: int32 + MetadataVersion: string + Resources: ILResources + /// e.g. win86 resources, as the exact contents of a .res or .obj file. Must be unlinked manually. + NativeResources: ILNativeResource list + CustomAttrsStored: ILAttributesStored + MetadataIndex: int32 } + + member ManifestOfAssembly: ILAssemblyManifest + + member HasManifest: bool + + member CustomAttrs: ILAttributes + +/// Find the method definition corresponding to the given property or +/// event operation. These are always in the same class as the property +/// or event. This is useful especially if your code is not using the Ilbind +/// API to bind references. +val internal resolveILMethodRef: ILTypeDef -> ILMethodRef -> ILMethodDef + +val internal resolveILMethodRefWithRescope: (ILType -> ILType) -> ILTypeDef -> ILMethodRef -> ILMethodDef + +// ------------------------------------------------------------------ +// Type Names +// +// The name of a type stored in the Name field is as follows: +// - For outer types it is, for example, System.String, i.e. +// the namespace followed by the type name. +// - For nested types, it is simply the type name. The namespace +// must be gleaned from the context in which the nested type +// lies. +// ------------------------------------------------------------------ + +val internal splitNamespace: string -> string list + +val internal splitNamespaceToArray: string -> string[] + +/// The splitILTypeName utility helps you split a string representing +/// a type name into the leading namespace elements (if any), the +/// names of any nested types and the type name itself. This function +/// memoizes and interns the splitting of the namespace portion of +/// the type name. +val internal splitILTypeName: string -> string list * string + +val internal splitILTypeNameWithPossibleStaticArguments: string -> string[] * string + +/// splitTypeNameRight is like splitILTypeName except the +/// namespace is kept as a whole string, rather than split at dots. +val internal splitTypeNameRight: string -> string option * string + +val internal typeNameForGlobalFunctions: string + +val internal isTypeNameForGlobalFunctions: string -> bool + +// ==================================================================== +// PART 2 +// +// Making metadata. Where no explicit constructor +// is given, you should create the concrete datatype directly, +// e.g. by filling in all appropriate record fields. +// ==================================================================== *) + +/// A table of common references to items in primary assembly (System.Runtime or mscorlib). +/// If a particular version of System.Runtime.dll has been loaded then you should +/// reference items from it via an ILGlobals for that specific version built using mkILGlobals. +[] +type internal ILGlobals = + member primaryAssemblyScopeRef: ILScopeRef + member primaryAssemblyRef: ILAssemblyRef + member primaryAssemblyName: string + member typ_Object: ILType + member typ_String: ILType + member typ_Type: ILType + member typ_Array: ILType + member typ_IntPtr: ILType + member typ_UIntPtr: ILType + member typ_Byte: ILType + member typ_Int16: ILType + member typ_Int32: ILType + member typ_Int64: ILType + member typ_SByte: ILType + member typ_UInt16: ILType + member typ_UInt32: ILType + member typ_UInt64: ILType + member typ_Single: ILType + member typ_Double: ILType + member typ_Bool: ILType + member typ_Char: ILType + member typ_TypedReference: ILType + + member fsharpCoreAssemblyScopeRef: ILScopeRef + + /// Is the given assembly possibly a primary assembly? + /// In practice, a primary assembly is an assembly that contains the System.Object type definition + /// and has no referenced assemblies. + /// However, we must consider assemblies that forward the System.Object type definition + /// to be possible primary assemblies. + /// Therefore, this will return true if the given assembly is the real primary assembly or an assembly that forwards + /// the System.Object type definition. + /// Assembly equivalency ignores the version here. + member IsPossiblePrimaryAssemblyRef: ILAssemblyRef -> bool + +/// Build the table of commonly used references given functions to find types in system assemblies +val internal mkILGlobals: primaryScopeRef: ILScopeRef * assembliesThatForwardToPrimaryAssembly: ILAssemblyRef list * fsharpCoreAssemblyScopeRef: ILScopeRef -> ILGlobals + +val internal PrimaryAssemblyILGlobals: ILGlobals + +/// When writing a binary the fake "toplevel" type definition (called ) +/// must come first. This function puts it first, and creates it in the returned +/// list as an empty typedef if it doesn't already exist. +val internal destTypeDefsWithGlobalFunctionsFirst: ILGlobals -> ILTypeDefs -> ILTypeDef list + +/// Not all custom attribute data can be decoded without binding types. In particular +/// enums must be bound in order to discover the size of the underlying integer. +/// The following assumes enums have size int32. +val internal decodeILAttribData: + ILAttribute -> + ILAttribElem list * (* fixed args *) + ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) + +/// Generate simple references to assemblies and modules. +val internal mkSimpleAssemblyRef: string -> ILAssemblyRef + +val internal mkSimpleModRef: string -> ILModuleRef + +val internal mkILTyvarTy: uint16 -> ILType + +/// Make type refs. +val internal mkILNestedTyRef: ILScopeRef * string list * string -> ILTypeRef +val internal mkILTyRef: ILScopeRef * string -> ILTypeRef +val internal mkILTyRefInTyRef: ILTypeRef * string -> ILTypeRef + +type internal ILGenericArgsList = ILType list + +/// Make type specs. +val internal mkILNonGenericTySpec: ILTypeRef -> ILTypeSpec +val internal mkILTySpec: ILTypeRef * ILGenericArgsList -> ILTypeSpec + +/// Make types. +val internal mkILTy: ILBoxity -> ILTypeSpec -> ILType +val internal mkILNamedTy: ILBoxity -> ILTypeRef -> ILGenericArgsList -> ILType +val internal mkILBoxedTy: ILTypeRef -> ILGenericArgsList -> ILType +val internal mkILValueTy: ILTypeRef -> ILGenericArgsList -> ILType +val internal mkILNonGenericBoxedTy: ILTypeRef -> ILType +val internal mkILNonGenericValueTy: ILTypeRef -> ILType +val internal mkILArrTy: ILType * ILArrayShape -> ILType +val internal mkILArr1DTy: ILType -> ILType +val internal isILArrTy: ILType -> bool +val internal destILArrTy: ILType -> ILArrayShape * ILType +val internal mkILBoxedType: ILTypeSpec -> ILType + +/// Make method references and specs. +val internal mkILMethRef: ILTypeRef * ILCallingConv * string * int * ILType list * ILType -> ILMethodRef +val internal mkILMethSpec: ILMethodRef * ILBoxity * ILGenericArgsList * ILGenericArgsList -> ILMethodSpec +val internal mkILMethSpecForMethRefInTy: ILMethodRef * ILType * ILGenericArgsList -> ILMethodSpec +val internal mkILMethSpecInTy: ILType * ILCallingConv * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec + +/// Construct references to methods on a given type . +val internal mkILNonGenericMethSpecInTy: ILType * ILCallingConv * string * ILType list * ILType -> ILMethodSpec + +/// Construct references to instance methods. +val internal mkILInstanceMethSpecInTy: ILType * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec + +/// Construct references to instance methods. +val internal mkILNonGenericInstanceMethSpecInTy: ILType * string * ILType list * ILType -> ILMethodSpec + +/// Construct references to static methods. +val internal mkILStaticMethSpecInTy: ILType * string * ILType list * ILType * ILGenericArgsList -> ILMethodSpec + +/// Construct references to static, non-generic methods. +val internal mkILNonGenericStaticMethSpecInTy: ILType * string * ILType list * ILType -> ILMethodSpec + +/// Construct references to constructors. +val internal mkILCtorMethSpecForTy: ILType * ILType list -> ILMethodSpec + +/// Construct references to fields. +val internal mkILFieldRef: ILTypeRef * string * ILType -> ILFieldRef +val internal mkILFieldSpec: ILFieldRef * ILType -> ILFieldSpec +val internal mkILFieldSpecInTy: ILType * string * ILType -> ILFieldSpec + +val internal mkILCallSig: ILCallingConv * ILType list * ILType -> ILCallingSignature + +/// Make generalized versions of possibly-generic types, e.g. Given the ILTypeDef for List, return the type "List". +val internal mkILFormalBoxedTy: ILTypeRef -> ILGenericParameterDef list -> ILType +val internal mkILFormalNamedTy: ILBoxity -> ILTypeRef -> ILGenericParameterDef list -> ILType + +val internal mkILFormalTypars: ILType list -> ILGenericParameterDefs +val internal mkILFormalGenericArgs: int -> ILGenericParameterDefs -> ILGenericArgsList +val internal mkILSimpleTypar: string -> ILGenericParameterDef + +/// Make custom attributes. +val internal mkILCustomAttribMethRef: + ILMethodSpec + * ILAttribElem list (* fixed args: values and implicit types *) + * ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) + -> ILAttribute + +val internal mkILCustomAttribute: + ILTypeRef * ILType list * + ILAttribElem list (* fixed args: values and implicit types *) * + ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) + -> ILAttribute + +val internal getCustomAttrData: ILAttribute -> byte[] + +val internal mkPermissionSet: ILSecurityAction * (ILTypeRef * (string * ILType * ILAttribElem) list) list -> ILSecurityDecl + +/// Making code. +val internal generateCodeLabel: unit -> ILCodeLabel +val internal formatCodeLabel: ILCodeLabel -> string + +/// Make some code that is a straight line sequence of instructions. +/// The function will add a "return" if the last instruction is not an exiting instruction. +val internal nonBranchingInstrsToCode: ILInstr list -> ILCode + +/// Helpers for codegen: scopes for allocating new temporary variables. +type internal ILLocalsAllocator = + new: preAlloc: int -> ILLocalsAllocator + member AllocLocal: ILLocal -> uint16 + member Close: unit -> ILLocal list + +/// Derived functions for making some common patterns of instructions. +val internal mkNormalCall: ILMethodSpec -> ILInstr +val internal mkNormalCallvirt: ILMethodSpec -> ILInstr +val internal mkNormalCallconstraint: ILType * ILMethodSpec -> ILInstr +val internal mkNormalNewobj: ILMethodSpec -> ILInstr +val internal mkCallBaseConstructor: ILType * ILType list -> ILInstr list +val internal mkNormalStfld: ILFieldSpec -> ILInstr +val internal mkNormalStsfld: ILFieldSpec -> ILInstr +val internal mkNormalLdsfld: ILFieldSpec -> ILInstr +val internal mkNormalLdfld: ILFieldSpec -> ILInstr +val internal mkNormalLdflda: ILFieldSpec -> ILInstr +val internal mkNormalLdobj: ILType -> ILInstr +val internal mkNormalStobj: ILType -> ILInstr +val internal mkLdcInt32: int32 -> ILInstr +val internal mkLdarg0: ILInstr +val internal mkLdloc: uint16 -> ILInstr +val internal mkStloc: uint16 -> ILInstr +val internal mkLdarg: uint16 -> ILInstr + +val internal andTailness: ILTailcall -> bool -> ILTailcall + +/// Derived functions for making return, parameter and local variable +/// objects for use in method definitions. +val internal mkILParam: string option * ILType -> ILParameter +val internal mkILParamAnon: ILType -> ILParameter +val internal mkILParamNamed: string * ILType -> ILParameter +val mkILReturn: ILType -> ILReturn +val internal mkILLocal: ILType -> (string * int * int) option -> ILLocal + +/// Make a formal generic parameters. +val internal mkILEmptyGenericParams: ILGenericParameterDefs + +/// Make method definitions. +val internal mkILMethodBody: initlocals:bool * ILLocals * int * ILCode * ILDebugPoint option * ILDebugImports option -> ILMethodBody + +val internal mkMethodBody: bool * ILLocals * int * ILCode * ILDebugPoint option * ILDebugImports option -> MethodBody + +val internal methBodyNotAvailable: Lazy + +val internal methBodyAbstract: Lazy + +val internal methBodyNative: Lazy + +val internal mkILCtor: ILMemberAccess * ILParameter list * MethodBody -> ILMethodDef + +val internal mkILClassCtor: MethodBody -> ILMethodDef + +val internal mkILNonGenericEmptyCtor: ILType * ILDebugPoint option * ILDebugImports option -> ILMethodDef + +val internal mkILStaticMethod: ILGenericParameterDefs * string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +val internal mkILNonGenericStaticMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +val internal mkILGenericVirtualMethod: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +val internal mkILGenericNonVirtualMethod: string * ILMemberAccess * ILGenericParameterDefs * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +val internal mkILNonGenericVirtualMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +val internal mkILNonGenericInstanceMethod: string * ILMemberAccess * ILParameter list * ILReturn * MethodBody -> ILMethodDef + +/// Make field definitions. +val internal mkILInstanceField: string * ILType * ILFieldInit option * ILMemberAccess -> ILFieldDef +val internal mkILStaticField: string * ILType * ILFieldInit option * byte[] option * ILMemberAccess -> ILFieldDef +val internal mkILLiteralField: string * ILType * ILFieldInit * byte[] option * ILMemberAccess -> ILFieldDef + +/// Make a type definition. +val internal mkILGenericClass: string * ILTypeDefAccess * ILGenericParameterDefs * ILType * ILType list * ILMethodDefs * ILFieldDefs * ILTypeDefs * ILPropertyDefs * ILEventDefs * ILAttributes * ILTypeInit -> ILTypeDef +val internal mkILSimpleClass: ILGlobals -> string * ILTypeDefAccess * ILMethodDefs * ILFieldDefs * ILTypeDefs * ILPropertyDefs * ILEventDefs * ILAttributes * ILTypeInit -> ILTypeDef +val internal mkILTypeDefForGlobalFunctions: ILGlobals -> ILMethodDefs * ILFieldDefs -> ILTypeDef + +/// Make a type definition for a value type used to point to raw data. +/// These are useful when generating array initialization code +/// according to the +/// ldtoken field valuetype ''/'$$struct0x6000127-1' ''::'$$method0x6000127-1' +/// call void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class System.Array,valuetype System.RuntimeFieldHandle) +/// idiom. +val internal mkRawDataValueTypeDef: ILType -> string * size:int32 * pack:uint16 -> ILTypeDef + +/// Injecting code into existing code blocks. A branch will +/// be added from the given instructions to the (unique) entry of +/// the code, and the first instruction will be the new entry +/// of the method. The instructions should be non-branching. + +val internal prependInstrsToCode: ILInstr list -> ILCode -> ILCode +val internal prependInstrsToMethod: ILInstr list -> ILMethodDef -> ILMethodDef + +/// Injecting initialization code into a class. +/// Add some code to the end of the .cctor for a type. Create a .cctor +/// if one doesn't exist already. +val internal prependInstrsToClassCtor: ILInstr list -> ILDebugPoint option -> ILDebugImports option -> ILTypeDef -> ILTypeDef + +/// Derived functions for making some simple constructors +val internal mkILStorageCtor: ILInstr list * ILType * (string * ILType) list * ILMemberAccess * ILDebugPoint option * ILDebugImports option -> ILMethodDef + +val internal mkILSimpleStorageCtor: ILTypeSpec option * ILType * ILParameter list * (string * ILType) list * ILMemberAccess * ILDebugPoint option * ILDebugImports option -> ILMethodDef + +val internal mkILSimpleStorageCtorWithParamNames: ILTypeSpec option * ILType * ILParameter list * (string * string * ILType) list * ILMemberAccess * ILDebugPoint option * ILDebugImports option -> ILMethodDef + +val internal mkILDelegateMethods: ILMemberAccess -> ILGlobals -> ILType * ILType -> ILParameter list * ILReturn -> ILMethodDef list + +/// Given a delegate type definition which lies in a particular scope, +/// make a reference to its constructor. +val internal mkCtorMethSpecForDelegate: ILGlobals -> ILType * bool -> ILMethodSpec + +/// The toplevel "class" for a module or assembly. +val internal mkILTypeForGlobalFunctions: ILScopeRef -> ILType + +/// Making tables of custom attributes, etc. +val mkILCustomAttrs: ILAttribute list -> ILAttributes +val mkILCustomAttrsFromArray: ILAttribute[] -> ILAttributes +val storeILCustomAttrs: ILAttributes -> ILAttributesStored +val internal mkILCustomAttrsReader: (int32 -> ILAttribute[]) -> ILAttributesStored +val emptyILCustomAttrs: ILAttributes + +val mkILSecurityDecls: ILSecurityDecl list -> ILSecurityDecls +val emptyILSecurityDecls: ILSecurityDecls +val storeILSecurityDecls: ILSecurityDecls -> ILSecurityDeclsStored +val internal mkILSecurityDeclsReader: (int32 -> ILSecurityDecl[]) -> ILSecurityDeclsStored + +val mkILEvents: ILEventDef list -> ILEventDefs +val mkILEventsLazy: Lazy -> ILEventDefs +val emptyILEvents: ILEventDefs + +val mkILProperties: ILPropertyDef list -> ILPropertyDefs +val mkILPropertiesLazy: Lazy -> ILPropertyDefs +val emptyILProperties: ILPropertyDefs + +val mkILMethods: ILMethodDef list -> ILMethodDefs +val mkILMethodsFromArray: ILMethodDef[] -> ILMethodDefs +val mkILMethodsComputed: (unit -> ILMethodDef[]) -> ILMethodDefs +val emptyILMethods: ILMethodDefs + +val mkILFields: ILFieldDef list -> ILFieldDefs +val mkILFieldsLazy: Lazy -> ILFieldDefs +val emptyILFields: ILFieldDefs + +val mkILMethodImpls: ILMethodImplDef list -> ILMethodImplDefs +val mkILMethodImplsLazy: Lazy -> ILMethodImplDefs +val emptyILMethodImpls: ILMethodImplDefs + +val mkILTypeDefs: ILTypeDef list -> ILTypeDefs +val mkILTypeDefsFromArray: ILTypeDef[] -> ILTypeDefs +val emptyILTypeDefs: ILTypeDefs + +/// Create table of types which is loaded/computed on-demand, and whose individual +/// elements are also loaded/computed on-demand. Any call to tdefs.AsList will +/// result in the laziness being forced. Operations can examine the +/// custom attributes and name of each type in order to decide whether +/// to proceed with examining the other details of the type. +/// +/// Note that individual type definitions may contain further delays +/// in their method, field and other tables. +val mkILTypeDefsComputed: (unit -> ILPreTypeDef[]) -> ILTypeDefs +val internal addILTypeDef: ILTypeDef -> ILTypeDefs -> ILTypeDefs + +val internal mkTypeForwarder: ILScopeRef -> string -> ILNestedExportedTypes -> ILAttributes -> ILTypeDefAccess -> ILExportedTypeOrForwarder +val mkILNestedExportedTypes: ILNestedExportedType list -> ILNestedExportedTypes +val internal mkILNestedExportedTypesLazy: Lazy -> ILNestedExportedTypes + +val mkILExportedTypes: ILExportedTypeOrForwarder list -> ILExportedTypesAndForwarders +val internal mkILExportedTypesLazy: Lazy -> ILExportedTypesAndForwarders + +val emptyILResources: ILResources +val internal mkILResources: ILResource list -> ILResources + +/// Making modules. +val mkILSimpleModule: assemblyName:string -> moduleName:string -> dll:bool -> subsystemVersion: (int * int) -> useHighEntropyVA: bool -> ILTypeDefs -> int32 option -> string option -> int -> ILExportedTypesAndForwarders -> string -> ILModuleDef + +/// Generate references to existing type definitions, method definitions +/// etc. Useful for generating references, e.g. to a class we're processing +/// Also used to reference type definitions that we've generated. [ILScopeRef] +/// is normally ILScopeRef.Local, unless we've generated the ILTypeDef in +/// an auxiliary module or are generating multiple assemblies at +/// once. + +val internal mkRefForNestedILTypeDef: ILScopeRef -> ILTypeDef list * ILTypeDef -> ILTypeRef +val internal mkRefForILMethod : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILMethodDef -> ILMethodRef +val internal mkRefForILField : ILScopeRef -> ILTypeDef list * ILTypeDef -> ILFieldDef -> ILFieldRef + +val internal mkRefToILMethod: ILTypeRef * ILMethodDef -> ILMethodRef +val internal mkRefToILField: ILTypeRef * ILFieldDef -> ILFieldRef + +val internal mkRefToILAssembly: ILAssemblyManifest -> ILAssemblyRef +val internal mkRefToILModule: ILModuleDef -> ILModuleRef + +val NoMetadataIdx: int32 + +// -------------------------------------------------------------------- +// Rescoping. +// +// Given an object O1 referenced from where1 (e.g. O1 binds to some +// result R when referenced from where1), and given that SR2 resolves to where1 from where2, +// produce a new O2 for use from where2 (e.g. O2 binds to R from where2) +// +// So, ILScopeRef tells you how to reference the original scope from +// the new scope. e.g. if ILScopeRef is: +// [ILScopeRef.Local] then the object is returned unchanged +// [ILScopeRef.Module m] then an object is returned +// where all ILScopeRef.Local references +// become ILScopeRef.Module m +// [ILScopeRef.Assembly m] then an object is returned +// where all ILScopeRef.Local and ILScopeRef.Module references +// become ILScopeRef.Assembly m +// -------------------------------------------------------------------- + +/// Rescoping. The first argument tells the function how to reference the original scope from +/// the new scope. +val internal rescopeILScopeRef: ILScopeRef -> ILScopeRef -> ILScopeRef + +/// Rescoping. The first argument tells the function how to reference the original scope from +/// the new scope. +val internal rescopeILTypeSpec: ILScopeRef -> ILTypeSpec -> ILTypeSpec + +/// Rescoping. The first argument tells the function how to reference the original scope from +/// the new scope. +val internal rescopeILType: ILScopeRef -> ILType -> ILType + +/// Rescoping. The first argument tells the function how to reference the original scope from +/// the new scope. +val internal rescopeILMethodRef: ILScopeRef -> ILMethodRef -> ILMethodRef + +/// Rescoping. The first argument tells the function how to reference the original scope from +/// the new scope. +val internal rescopeILFieldRef: ILScopeRef -> ILFieldRef -> ILFieldRef + +/// Unscoping. Clears every scope information, use for looking up IL method references only. +val internal unscopeILType: ILType -> ILType + +val internal buildILCode: string -> lab2pc: Dictionary -> instrs:ILInstr[] -> ILExceptionSpec list -> ILLocalDebugInfo list -> ILCode + +/// Instantiate type variables that occur within types and other items. +val internal instILTypeAux: int -> ILGenericArgs -> ILType -> ILType + +/// Instantiate type variables that occur within types and other items. +val internal instILType: ILGenericArgs -> ILType -> ILType + +/// This is a 'vendor neutral' way of referencing mscorlib. +val internal ecmaPublicKey: PublicKey + +/// Strips ILType.Modified from the ILType. +val internal stripILModifiedFromTy: ILType -> ILType + +/// Discriminating different important built-in types. +val internal isILObjectTy: ILGlobals -> ILType -> bool +val internal isILStringTy: ILGlobals -> ILType -> bool +val internal isILSByteTy: ILGlobals -> ILType -> bool +val internal isILByteTy: ILGlobals -> ILType -> bool +val internal isILInt16Ty: ILGlobals -> ILType -> bool +val internal isILUInt16Ty: ILGlobals -> ILType -> bool +val internal isILInt32Ty: ILGlobals -> ILType -> bool +val internal isILUInt32Ty: ILGlobals -> ILType -> bool +val internal isILInt64Ty: ILGlobals -> ILType -> bool +val internal isILUInt64Ty: ILGlobals -> ILType -> bool +val internal isILIntPtrTy: ILGlobals -> ILType -> bool +val internal isILUIntPtrTy: ILGlobals -> ILType -> bool +val internal isILBoolTy: ILGlobals -> ILType -> bool +val internal isILCharTy: ILGlobals -> ILType -> bool +val internal isILTypedReferenceTy: ILGlobals -> ILType -> bool +val internal isILDoubleTy: ILGlobals -> ILType -> bool +val internal isILSingleTy: ILGlobals -> ILType -> bool + +val internal sha1HashInt64 : byte[] -> int64 +/// Get a public key token from a public key. +val internal sha1HashBytes: byte[] -> byte[] (* SHA1 hash *) + +/// Get a version number from a CLR version string, e.g. 1.0.3705.0 +val internal parseILVersion: string -> ILVersionInfo +val internal formatILVersion: ILVersionInfo -> string +val internal compareILVersions: ILVersionInfo -> ILVersionInfo -> int + +/// Decompose a type definition according to its kind. +type internal ILEnumInfo = + { enumValues: (string * ILFieldInit) list + enumType: ILType } + +val internal getTyOfILEnumInfo: ILEnumInfo -> ILType + +val internal computeILEnumInfo: string * ILFieldDefs -> ILEnumInfo + +/// A utility type provided for completeness +[] +type internal ILEventRef = + static member Create: ILTypeRef * string -> ILEventRef + member DeclaringTypeRef: ILTypeRef + member Name: string + +/// A utility type provided for completeness +[] +type internal ILPropertyRef = + static member Create: ILTypeRef * string -> ILPropertyRef + member DeclaringTypeRef: ILTypeRef + member Name: string + interface System.IComparable + +type internal ILReferences = + { AssemblyReferences: ILAssemblyRef list + ModuleReferences: ILModuleRef list } + +/// Find the full set of assemblies referenced by a module. +val internal computeILRefs: ILGlobals -> ILModuleDef -> ILReferences +val internal emptyILRefs: ILReferences + diff --git a/src/absil/ilascii.fs b/src/fsharp/absil/ilascii.fs similarity index 91% rename from src/absil/ilascii.fs rename to src/fsharp/absil/ilascii.fs index e5b7782ba7e..fd8b8e758dc 100644 --- a/src/absil/ilascii.fs +++ b/src/fsharp/absil/ilascii.fs @@ -1,16 +1,11 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module internal FSharp.Compiler.AbstractIL.Internal.AsciiConstants +module internal FSharp.Compiler.AbstractIL.AsciiConstants open Internal.Utilities.Collections - -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -// set to the proper value at CompileOps.fs (BuildFrameworkTcImports) -// Only relevant when compiling FSharp.Core.dll -let mutable parseILGlobals = EcmaMscorlibILGlobals - /// Table of parsing and pretty printing data for instructions. let noArgInstrs = lazy [ @@ -150,18 +145,18 @@ let wordsOfNoArgInstr, isNoArgInstr = let mk_stind (nm, dt) = (nm, (fun () -> I_stind(Aligned, Nonvolatile, dt))) let mk_ldind (nm, dt) = (nm, (fun () -> I_ldind(Aligned, Nonvolatile, dt))) -type NoArgInstr = (unit -> ILInstr) -type Int32Instr = (int32 -> ILInstr) -type Int32Int32Instr = (int32 * int32 -> ILInstr) -type Int64Instr = (int64 -> ILInstr) -type DoubleInstr = (ILConst -> ILInstr) -type MethodSpecInstr = (ILMethodSpec * ILVarArgs -> ILInstr) -type TypeInstr = (ILType -> ILInstr) -type IntTypeInstr = (int * ILType -> ILInstr) -type ValueTypeInstr = (ILType -> ILInstr) (* nb. diff. interp of types to TypeInstr *) -type StringInstr = (string -> ILInstr) -type TokenInstr = (ILToken -> ILInstr) -type SwitchInstr = (ILCodeLabel list * ILCodeLabel -> ILInstr) +type NoArgInstr = unit -> ILInstr +type Int32Instr = int32 -> ILInstr +type Int32Int32Instr = int32 * int32 -> ILInstr +type Int64Instr = int64 -> ILInstr +type DoubleInstr = ILConst -> ILInstr +type MethodSpecInstr = ILMethodSpec * ILVarArgs -> ILInstr +type TypeInstr = ILType -> ILInstr +type IntTypeInstr = int * ILType -> ILInstr +type ValueTypeInstr = ILType -> ILInstr (* nb. diff. interp of types to TypeInstr *) +type StringInstr = string -> ILInstr +type TokenInstr = ILToken -> ILInstr +type SwitchInstr = ILCodeLabel list * ILCodeLabel -> ILInstr type InstrTable<'T> = (string list * 'T) list type LazyInstrTable<'T> = Lazy> @@ -169,7 +164,7 @@ type LazyInstrTable<'T> = Lazy> /// Table of parsing and pretty printing data for instructions. let NoArgInstrs : Lazy> = lazy [ - for (nm, i) in noArgInstrs.Force() do + for nm, i in noArgInstrs.Force() do yield (nm, (fun () -> i)) yield mk_stind (["stind";"u"], DT_I) yield mk_stind (["stind";"i"], DT_I) diff --git a/src/absil/ilascii.fsi b/src/fsharp/absil/ilascii.fsi similarity index 77% rename from src/absil/ilascii.fsi rename to src/fsharp/absil/ilascii.fsi index 67a5c9eb4b1..f787dc11c1e 100644 --- a/src/absil/ilascii.fsi +++ b/src/fsharp/absil/ilascii.fsi @@ -1,21 +1,10 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. /// Various constants and utilities used when parsing the ILASM format for IL -module internal FSharp.Compiler.AbstractIL.Internal.AsciiConstants +module internal FSharp.Compiler.AbstractIL.AsciiConstants -open Internal.Utilities - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types open FSharp.Compiler.AbstractIL.IL -// -------------------------------------------------------------------- -// IL Parser state - must be initialized before parsing a module -// -------------------------------------------------------------------- - -val mutable parseILGlobals: ILGlobals - // -------------------------------------------------------------------- // IL Lexer and pretty-printer tables // -------------------------------------------------------------------- diff --git a/src/absil/ilbinary.fs b/src/fsharp/absil/ilbinary.fs similarity index 99% rename from src/absil/ilbinary.fs rename to src/fsharp/absil/ilbinary.fs index eea2f06bfda..18f15bc62ac 100644 --- a/src/absil/ilbinary.fs +++ b/src/fsharp/absil/ilbinary.fs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module internal FSharp.Compiler.AbstractIL.Internal.BinaryConstants +module internal FSharp.Compiler.AbstractIL.BinaryConstants open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library [] type TableName(idx: int) = diff --git a/src/absil/ilbinary.fsi b/src/fsharp/absil/ilbinary.fsi similarity index 98% rename from src/absil/ilbinary.fsi rename to src/fsharp/absil/ilbinary.fsi index 200ee8b0274..30295cebdbd 100644 --- a/src/absil/ilbinary.fsi +++ b/src/fsharp/absil/ilbinary.fsi @@ -1,13 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. /// Compiler use only. Code and constants shared between binary reader/writer. -module internal FSharp.Compiler.AbstractIL.Internal.BinaryConstants +module internal FSharp.Compiler.AbstractIL.BinaryConstants -open Internal.Utilities -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal - [] type TableName = diff --git a/src/absil/ildiag.fs b/src/fsharp/absil/ildiag.fs similarity index 100% rename from src/absil/ildiag.fs rename to src/fsharp/absil/ildiag.fs diff --git a/src/absil/ildiag.fsi b/src/fsharp/absil/ildiag.fsi similarity index 100% rename from src/absil/ildiag.fsi rename to src/fsharp/absil/ildiag.fsi diff --git a/src/absil/illex.fsl b/src/fsharp/absil/illex.fsl similarity index 81% rename from src/absil/illex.fsl rename to src/fsharp/absil/illex.fsl index 149cd087b91..aad77eb806f 100644 --- a/src/absil/illex.fsl +++ b/src/fsharp/absil/illex.fsl @@ -2,21 +2,20 @@ { -module internal FSharp.Compiler.AbstractIL.Internal.AsciiLexer +module internal FSharp.Compiler.AbstractIL.AsciiLexer -open Internal.Utilities open Internal.Utilities.Collections open Internal.Utilities.Text open Internal.Utilities.Text.Lexing -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library -open FSharp.Compiler.AbstractIL.Internal.AsciiParser -open FSharp.Compiler.AbstractIL.Internal.AsciiConstants +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.AsciiParser +open FSharp.Compiler.AbstractIL.AsciiConstants -let lexeme (lexbuf : LexBuffer) = new System.String(lexbuf.Lexeme) +let lexeme (lexbuf : LexBuffer) = LexBuffer.LexemeString lexbuf +let lexemeChar (lexbuf : LexBuffer) n = lexbuf.LexemeChar n let unexpectedChar _lexbuf = raise Parsing.RecoverableParseError ;; @@ -79,12 +78,7 @@ let kwdInstrTable = let kwdOrInstr s = (Lazy.force kwdInstrTable).[s] (* words *) -let eval = function - | '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4 | '5' -> 5 - | '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9 - | 'A' -> 10 | 'B' -> 11 | 'C' -> 12 | 'D' -> 13 | 'E' -> 14 | 'F' -> 15 - | 'a' -> 10 | 'b' -> 11 | 'c' -> 12 | 'd' -> 13 | 'e' -> 14 | 'f' -> 15 - | _ -> failwith "bad hexbyte" +let evalDigit ch = (int ch) - (int '0') let kwdOrInstrOrId s = match (Lazy.force kwdInstrTable).TryFind s with Some v -> v | _ -> VAL_ID s @@ -119,21 +113,21 @@ rule token = parse (* The problem is telling an integer-followed-by-ellipses from a floating-point-nubmer-followed-by-dots *) | ((['0'-'9']) | (['0'-'9']['0'-'9']['0'-'9']+)) "..." - { let b = lexeme lexbuf in - VAL_INT32_ELIPSES(int32(String.sub b 0 (String.length b - 3))) } + { let b = lexbuf.LexemeView in + VAL_INT32_ELIPSES(int32(b.Slice(0, (b.Length - 3)).ToString())) } | ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ] - { let c1 = String.get (lexeme lexbuf) 0 in - let c2 = String.get (lexeme lexbuf) 1 in + { let c1 = (lexemeChar lexbuf 0) in + let c2 = (lexemeChar lexbuf 1) in if c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9' then - VAL_INT64(int64 (10*eval c1 + eval c2) ) + VAL_INT64(int64 (10*evalDigit c1 + evalDigit c2) ) else VAL_ID(lexeme lexbuf) } | '0' 'x' ['0'-'9' 'a'-'f' 'A'-'F']+ { VAL_INT64(int64(lexeme lexbuf)) } | "FFFFFF" ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ] - { let c1 = (lexeme lexbuf).[6] in - let c2 = (lexeme lexbuf).[7] in + { let c1 = (lexemeChar lexbuf 6) in + let c2 = (lexemeChar lexbuf 7) in if c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9' then - VAL_INT64(int64 (10*eval c1 + eval c2)) + VAL_INT64(int64 (10*evalDigit c1 + evalDigit c2)) else VAL_ID(lexeme lexbuf) } | '-' ['0'-'9']+ diff --git a/src/fsharp/absil/illib.fs b/src/fsharp/absil/illib.fs new file mode 100644 index 00000000000..2cd1f328f82 --- /dev/null +++ b/src/fsharp/absil/illib.fs @@ -0,0 +1,1160 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Internal.Utilities.Library + +open System +open System.Collections.Generic +open System.Collections.Concurrent +open System.Diagnostics +open System.IO +open System.Threading +open System.Threading.Tasks +open System.Runtime.CompilerServices + +[] +module internal PervasiveAutoOpens = + /// Logical shift right treating int32 as unsigned integer. + /// Code that uses this should probably be adjusted to use unsigned integer types. + let (>>>&) (x: int32) (n: int32) = int32 (uint32 x >>> n) + + let notlazy v = Lazy<_>.CreateFromValue v + + let inline isNil l = List.isEmpty l + + /// Returns true if the list has less than 2 elements. Otherwise false. + let inline isNilOrSingleton l = + match l with + | [] + | [_] -> true + | _ -> false + + /// Returns true if the list contains exactly 1 element. Otherwise false. + let inline isSingleton l = + match l with + | [_] -> true + | _ -> false + + let inline isNonNull x = not (isNull x) + + let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x + + let inline (===) x y = LanguagePrimitives.PhysicalEquality x y + + /// Per the docs the threshold for the Large Object Heap is 85000 bytes: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap#how-an-object-ends-up-on-the-large-object-heap-and-how-gc-handles-them + /// We set the limit to be 80k to account for larger pointer sizes for when F# is running 64-bit. + let LOH_SIZE_THRESHOLD_BYTES = 80_000 + + let runningOnMono = +#if ENABLE_MONO_SUPPORT + // Officially supported way to detect if we are running on Mono. + // See http://www.mono-project.com/FAQ:_Technical + // "How can I detect if am running in Mono?" section + try + Type.GetType "Mono.Runtime" <> null + with _ -> + // Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent + // that is not reliable. + // This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is + // called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get + // their issue fixed but we need to be robust here anyway. + false +#else + false +#endif + + type String with + member inline x.StartsWithOrdinal value = + x.StartsWith(value, StringComparison.Ordinal) + + member inline x.EndsWithOrdinal value = + x.EndsWith(value, StringComparison.Ordinal) + + /// Get an initialization hole + let getHole r = match !r with None -> failwith "getHole" | Some x -> x + + let reportTime = + let mutable tFirst =None + let mutable tPrev = None + fun showTimes descr -> + if showTimes then + let t = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds + let prev = match tPrev with None -> 0.0 | Some t -> t + let first = match tFirst with None -> (tFirst <- Some t; t) | Some t -> t + printf "ilwrite: TIME %10.3f (total) %10.3f (delta) - %s\n" (t - first) (t - prev) descr + tPrev <- Some t + + let foldOn p f z x = f z (p x) + + let notFound() = raise (KeyNotFoundException()) + + type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + +[] +/// An efficient lazy for inline storage in a class type. Results in fewer thunks. +type InlineDelayInit<'T when 'T : not struct> = + new (f: unit -> 'T) = {store = Unchecked.defaultof<'T>; func = Func<_>(f) } + val mutable store : 'T + val mutable func : Func<'T> + + member x.Value = + match x.func with + | null -> x.store + | _ -> + let res = LazyInitializer.EnsureInitialized(&x.store, x.func) + x.func <- Unchecked.defaultof<_> + res + +//------------------------------------------------------------------------- +// Library: projections +//------------------------------------------------------------------------ + +module Order = + let orderBy (p : 'T -> 'U) = + { new IComparer<'T> with member _.Compare(x, xx) = compare (p x) (p xx) } + + let orderOn p (pxOrder: IComparer<'U>) = + { new IComparer<'T> with member _.Compare(x, xx) = pxOrder.Compare (p x, p xx) } + + let toFunction (pxOrder: IComparer<'U>) x y = pxOrder.Compare(x, y) + +//------------------------------------------------------------------------- +// Library: arrays, lists, options, resizearrays +//------------------------------------------------------------------------- + +module Array = + + let mapq f inp = + match inp with + | [| |] -> inp + | _ -> + let res = Array.map f inp + let len = inp.Length + let mutable eq = true + let mutable i = 0 + while eq && i < len do + if not (inp.[i] === res.[i]) then eq <- false + i <- i + 1 + if eq then inp else res + + let lengthsEqAndForall2 p l1 l2 = + Array.length l1 = Array.length l2 && + Array.forall2 p l1 l2 + + let order (eltOrder: IComparer<'T>) = + { new IComparer> with + member _.Compare(xs, ys) = + let c = compare xs.Length ys.Length + if c <> 0 then c else + let rec loop i = + if i >= xs.Length then 0 else + let c = eltOrder.Compare(xs.[i], ys.[i]) + if c <> 0 then c else + loop (i+1) + loop 0 } + + let existsOne p l = + let rec forallFrom p l n = + (n >= Array.length l) || (p l.[n] && forallFrom p l (n+1)) + + let rec loop p l n = + (n < Array.length l) && + (if p l.[n] then forallFrom (fun x -> not (p x)) l (n+1) else loop p l (n+1)) + + loop p l 0 + + let existsTrue (arr: bool[]) = + let rec loop n = (n < arr.Length) && (arr.[n] || loop (n+1)) + loop 0 + + let findFirstIndexWhereTrue (arr: _[]) p = + let rec look lo hi = + assert ((lo >= 0) && (hi >= 0)) + assert ((lo <= arr.Length) && (hi <= arr.Length)) + if lo = hi then lo + else + let i = (lo+hi)/2 + if p arr.[i] then + if i = 0 then i + else + if p arr.[i-1] then + look lo i + else + i + else + // not true here, look after + look (i+1) hi + look 0 arr.Length + + /// pass an array byref to reverse it in place + let revInPlace (array: 'T []) = + if Array.isEmpty array then () else + let arrLen, revLen = array.Length-1, array.Length/2 - 1 + for idx in 0 .. revLen do + let t1 = array.[idx] + let t2 = array.[arrLen-idx] + array.[idx] <- t2 + array.[arrLen-idx] <- t1 + + /// Async implementation of Array.map. + let mapAsync (mapping : 'T -> Async<'U>) (array : 'T[]) : Async<'U[]> = + let len = Array.length array + let result = Array.zeroCreate len + + async { // Apply the mapping function to each array element. + for i in 0 .. len - 1 do + let! mappedValue = mapping array.[i] + result.[i] <- mappedValue + + // Return the completed results. + return result + } + + /// Returns a new array with an element replaced with a given value. + let replace index value (array: _ []) = + if index >= array.Length then raise (IndexOutOfRangeException "index") + let res = Array.copy array + res.[index] <- value + res + + /// Optimized arrays equality. ~100x faster than `array1 = array2` on strings. + /// ~2x faster for floats + /// ~0.8x slower for ints + let inline areEqual (xs: 'T []) (ys: 'T []) = + match xs, ys with + | null, null -> true + | [||], [||] -> true + | null, _ | _, null -> false + | _ when xs.Length <> ys.Length -> false + | _ -> + let mutable break' = false + let mutable i = 0 + let mutable result = true + while i < xs.Length && not break' do + if xs.[i] <> ys.[i] then + break' <- true + result <- false + i <- i + 1 + result + + /// Returns all heads of a given array. + /// For [|1;2;3|] it returns [|[|1; 2; 3|]; [|1; 2|]; [|1|]|] + let heads (array: 'T []) = + let res = Array.zeroCreate<'T[]> array.Length + for i = array.Length - 1 downto 0 do + res.[i] <- array.[0..i] + res + + /// check if subArray is found in the wholeArray starting + /// at the provided index + let inline isSubArray (subArray: 'T []) (wholeArray:'T []) index = + if isNull subArray || isNull wholeArray then false + elif subArray.Length = 0 then true + elif subArray.Length > wholeArray.Length then false + elif subArray.Length = wholeArray.Length then areEqual subArray wholeArray else + let rec loop subidx idx = + if subidx = subArray.Length then true + elif subArray.[subidx] = wholeArray.[idx] then loop (subidx+1) (idx+1) + else false + loop 0 index + + /// Returns true if one array has another as its subset from index 0. + let startsWith (prefix: _ []) (whole: _ []) = + isSubArray prefix whole 0 + + /// Returns true if one array has trailing elements equal to another's. + let endsWith (suffix: _ []) (whole: _ []) = + isSubArray suffix whole (whole.Length-suffix.Length) + +module Option = + + let mapFold f s opt = + match opt with + | None -> None, s + | Some x -> + let x2, s2 = f s x + Some x2, s2 + + let attempt (f: unit -> 'T) = try Some (f()) with _ -> None + +module List = + + let sortWithOrder (c: IComparer<'T>) elements = List.sortWith (Order.toFunction c) elements + + let splitAfter n l = + let rec split_after_acc n l1 l2 = if n <= 0 then List.rev l1, l2 else split_after_acc (n-1) ((List.head l2) :: l1) (List.tail l2) + split_after_acc n [] l + + let existsi f xs = + let rec loop i xs = match xs with [] -> false | h :: t -> f i h || loop (i+1) t + loop 0 xs + + let lengthsEqAndForall2 p l1 l2 = + List.length l1 = List.length l2 && + List.forall2 p l1 l2 + + let rec findi n f l = + match l with + | [] -> None + | h :: t -> if f h then Some (h, n) else findi (n+1) f t + + let splitChoose select l = + let rec ch acc1 acc2 l = + match l with + | [] -> List.rev acc1, List.rev acc2 + | x :: xs -> + match select x with + | Choice1Of2 sx -> ch (sx :: acc1) acc2 xs + | Choice2Of2 sx -> ch acc1 (sx :: acc2) xs + + ch [] [] l + + let rec checkq l1 l2 = + match l1, l2 with + | h1 :: t1, h2 :: t2 -> h1 === h2 && checkq t1 t2 + | _ -> true + + let mapq (f: 'T -> 'T) inp = + assert not typeof<'T>.IsValueType + match inp with + | [] -> inp + | [h1a] -> + let h2a = f h1a + if h1a === h2a then inp else [h2a] + | [h1a; h1b] -> + let h2a = f h1a + let h2b = f h1b + if h1a === h2a && h1b === h2b then inp else [h2a; h2b] + | [h1a; h1b; h1c] -> + let h2a = f h1a + let h2b = f h1b + let h2c = f h1c + if h1a === h2a && h1b === h2b && h1c === h2c then inp else [h2a; h2b; h2c] + | _ -> + let res = List.map f inp + if checkq inp res then inp else res + + let frontAndBack l = + let rec loop acc l = + match l with + | [] -> + Debug.Assert(false, "empty list") + invalidArg "l" "empty list" + | [h] -> List.rev acc, h + | h :: t -> loop (h :: acc) t + loop [] l + + let tryRemove f inp = + let rec loop acc l = + match l with + | [] -> None + | h :: t -> if f h then Some (h, List.rev acc @ t) else loop (h :: acc) t + loop [] inp + + let zip4 l1 l2 l3 l4 = + List.zip l1 (List.zip3 l2 l3 l4) |> List.map (fun (x1, (x2, x3, x4)) -> (x1, x2, x3, x4)) + + let unzip4 l = + let a, b, cd = List.unzip3 (List.map (fun (x, y, z, w) -> (x, y, (z, w))) l) + let c, d = List.unzip cd + a, b, c, d + + let rec iter3 f l1 l2 l3 = + match l1, l2, l3 with + | h1 :: t1, h2 :: t2, h3 :: t3 -> f h1 h2 h3; iter3 f t1 t2 t3 + | [], [], [] -> () + | _ -> failwith "iter3" + + let takeUntil p l = + let rec loop acc l = + match l with + | [] -> List.rev acc, [] + | x :: xs -> if p x then List.rev acc, l else loop (x :: acc) xs + loop [] l + + let order (eltOrder: IComparer<'T>) = + { new IComparer> with + member _.Compare(xs, ys) = + let rec loop xs ys = + match xs, ys with + | [], [] -> 0 + | [], _ -> -1 + | _, [] -> 1 + | x :: xs, y :: ys -> + let cxy = eltOrder.Compare(x, y) + if cxy=0 then loop xs ys else cxy + loop xs ys } + + let indexNotFound() = raise (KeyNotFoundException("An index satisfying the predicate was not found in the collection")) + + let rec assoc x l = + match l with + | [] -> indexNotFound() + | (h, r) :: t -> if x = h then r else assoc x t + + let rec memAssoc x l = + match l with + | [] -> false + | (h, _) :: t -> x = h || memAssoc x t + + let rec memq x l = + match l with + | [] -> false + | h :: t -> LanguagePrimitives.PhysicalEquality x h || memq x t + + let mapNth n f xs = + let rec mn i = function + | [] -> [] + | x :: xs -> if i=n then f x :: xs else x :: mn (i+1) xs + + mn 0 xs + let count pred xs = List.fold (fun n x -> if pred x then n+1 else n) 0 xs + + let headAndTail l = + match l with + | [] -> failwith "headAndTail" + | h::t -> (h,t) + + // WARNING: not tail-recursive + let mapHeadTail fhead ftail = function + | [] -> [] + | [x] -> [fhead x] + | x :: xs -> fhead x :: List.map ftail xs + + let collectFold f s l = + let l, s = List.mapFold f s l + List.concat l, s + + let collect2 f xs ys = List.concat (List.map2 f xs ys) + + let toArraySquared xss = xss |> List.map List.toArray |> List.toArray + + let iterSquared f xss = xss |> List.iter (List.iter f) + + let collectSquared f xss = xss |> List.collect (List.collect f) + + let mapSquared f xss = xss |> List.map (List.map f) + + let mapFoldSquared f z xss = List.mapFold (List.mapFold f) z xss + + let forallSquared f xss = xss |> List.forall (List.forall f) + + let mapiSquared f xss = xss |> List.mapi (fun i xs -> xs |> List.mapi (fun j x -> f i j x)) + + let existsSquared f xss = xss |> List.exists (fun xs -> xs |> List.exists (fun x -> f x)) + + let mapiFoldSquared f z xss = mapFoldSquared f z (xss |> mapiSquared (fun i j x -> (i, j, x))) + + let duplicates (xs: 'T list) = + xs + |> List.groupBy id + |> List.filter (fun (_, elems) -> Seq.length elems > 1) + |> List.map fst + + let internal allEqual (xs: 'T list) = + match xs with + | [] -> true + | h::t -> t |> List.forall (fun h2 -> h = h2) + +module ResizeArray = + + /// Split a ResizeArray into an array of smaller chunks. + /// This requires `items/chunkSize` Array copies of length `chunkSize` if `items/chunkSize % 0 = 0`, + /// otherwise `items/chunkSize + 1` Array copies. + let chunkBySize chunkSize f (items: ResizeArray<'t>) = + // we could use Seq.chunkBySize here, but that would involve many enumerator.MoveNext() calls that we can sidestep with a bit of math + let itemCount = items.Count + if itemCount = 0 + then [||] + else + let chunksCount = + match itemCount / chunkSize with + | n when itemCount % chunkSize = 0 -> n + | n -> n + 1 // any remainder means we need an additional chunk to store it + + [| for index in 0..chunksCount-1 do + let startIndex = index * chunkSize + let takeCount = min (itemCount - startIndex) chunkSize + + let holder = Array.zeroCreate takeCount + // we take a bounds-check hit here on each access. + // other alternatives here include + // * iterating across an IEnumerator (incurs MoveNext penalty) + // * doing a block copy using `List.CopyTo(index, array, index, count)` (requires more copies to do the mapping) + // none are significantly better. + for i in 0 .. takeCount - 1 do + holder.[i] <- f items.[i] + yield holder |] + + /// Split a large ResizeArray into a series of array chunks that are each under the Large Object Heap limit. + /// This is done to help prevent a stop-the-world collection of the single large array, instead allowing for a greater + /// probability of smaller collections. Stop-the-world is still possible, just less likely. + let mapToSmallArrayChunks f (inp: ResizeArray<'t>) = + let itemSizeBytes = sizeof<'t> + // rounding down here is good because it ensures we don't go over + let maxArrayItemCount = LOH_SIZE_THRESHOLD_BYTES / itemSizeBytes + + /// chunk the provided input into arrays that are smaller than the LOH limit + /// in order to prevent long-term storage of those values + chunkBySize maxArrayItemCount f inp + +module ValueOptionInternal = + + let inline ofOption x = match x with Some x -> ValueSome x | None -> ValueNone + + let inline bind f x = match x with ValueSome x -> f x | ValueNone -> ValueNone + +module String = + let make (n: int) (c: char) : string = String(c, n) + + let get (str: string) i = str.[i] + + let sub (s: string) (start: int) (len: int) = s.Substring(start, len) + + let contains (s: string) (c: char) = s.IndexOf c <> -1 + + let order = LanguagePrimitives.FastGenericComparer + + let lowercase (s: string) = + s.ToLowerInvariant() + + let uppercase (s: string) = + s.ToUpperInvariant() + + // Scripts that distinguish between upper and lower case (bicameral) DU Discriminators and Active Pattern identifiers are required to start with an upper case character. + // For valid identifiers where the case of the identifier can not be determined because there is no upper and lower case we will allow DU Discriminators and upper case characters + // to be used. This means that developers using unicameral scripts such as hindi, are not required to prefix these identifiers with an Upper case latin character. + // + let isLeadingIdentifierCharacterUpperCase (s:string) = + let isUpperCaseCharacter c = + // if IsUpper and IsLower return the same value, then we can't tell if it's upper or lower case, so ensure it is a letter + // otherwise it is bicameral, so must be upper case + let isUpper = Char.IsUpper c + if isUpper = Char.IsLower c then Char.IsLetter c + else isUpper + + s.Length >= 1 && isUpperCaseCharacter s.[0] + + let capitalize (s: string) = + if s.Length = 0 then s + else uppercase s.[0..0] + s.[ 1.. s.Length - 1 ] + + let uncapitalize (s: string) = + if s.Length = 0 then s + else lowercase s.[0..0] + s.[ 1.. s.Length - 1 ] + + let dropPrefix (s: string) (t: string) = s.[t.Length..s.Length - 1] + + let dropSuffix (s: string) (t: string) = s.[0..s.Length - t.Length - 1] + + let inline toCharArray (str: string) = str.ToCharArray() + + let lowerCaseFirstChar (str: string) = + if String.IsNullOrEmpty str + || Char.IsLower(str, 0) then str else + let strArr = toCharArray str + match Array.tryHead strArr with + | None -> str + | Some c -> + strArr.[0] <- Char.ToLower c + String strArr + + let extractTrailingIndex (str: string) = + match str with + | null -> null, None + | _ -> + let charr = str.ToCharArray() + Array.revInPlace charr + let digits = Array.takeWhile Char.IsDigit charr + Array.revInPlace digits + String digits + |> function + | "" -> str, None + | index -> str.Substring (0, str.Length - index.Length), Some (int index) + + /// Remove all trailing and leading whitespace from the string + /// return null if the string is null + let trim (value: string) = if isNull value then null else value.Trim() + + /// Splits a string into substrings based on the strings in the array separators + let split options (separator: string []) (value: string) = + if isNull value then null else value.Split(separator, options) + + let (|StartsWith|_|) pattern value = + if String.IsNullOrWhiteSpace value then + None + elif value.StartsWithOrdinal pattern then + Some() + else None + + let (|Contains|_|) pattern value = + if String.IsNullOrWhiteSpace value then + None + elif value.Contains pattern then + Some() + else None + + let getLines (str: string) = + use reader = new StringReader(str) + [| + let mutable line = reader.ReadLine() + while not (isNull line) do + yield line + line <- reader.ReadLine() + if str.EndsWithOrdinal("\n") then + // last trailing space not returned + // http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak + yield String.Empty + |] + +module Dictionary = + let inline newWithSize (size: int) = Dictionary<_, _>(size, HashIdentity.Structural) + + let inline ofList (xs: ('Key * 'Value) list) = + let t = Dictionary<_, _>(List.length xs, HashIdentity.Structural) + for k,v in xs do + t.Add(k,v) + t + +[] +type DictionaryExtensions() = + + [] + static member inline BagAdd(dic: Dictionary<'key, 'value list>, key: 'key, value: 'value) = + match dic.TryGetValue key with + | true, values -> dic.[key] <- value :: values + | _ -> dic.[key] <- [value] + + [] + static member inline BagExistsValueForKey(dic: Dictionary<'key, 'value list>, key: 'key, f: 'value -> bool) = + match dic.TryGetValue key with + | true, values -> values |> List.exists f + | _ -> false + +module Lazy = + let force (x: Lazy<'T>) = x.Force() + +//---------------------------------------------------------------------------- +// Single threaded execution and mutual exclusion + +/// Represents a permission active at this point in execution +type ExecutionToken = interface end + +/// Represents a token that indicates execution on the compilation thread, i.e. +/// - we have full access to the (partially mutable) TAST and TcImports data structures +/// - compiler execution may result in type provider invocations when resolving types and members +/// - we can access various caches in the SourceCodeServices +/// +/// Like other execution tokens this should be passed via argument passing and not captured/stored beyond +/// the lifetime of stack-based calls. This is not checked, it is a discipline within the compiler code. +[] +type CompilationThreadToken() = interface ExecutionToken + +/// A base type for various types of tokens that must be passed when a lock is taken. +/// Each different static lock should declare a new subtype of this type. +type LockToken = inherit ExecutionToken + +/// Represents a token that indicates execution on any of several potential user threads calling the F# compiler services. +[] +type AnyCallerThreadToken() = interface ExecutionToken + +[] +module internal LockAutoOpens = + /// Represents a place where we are stating that execution on the compilation thread is required. The + /// reason why will be documented in a comment in the code at the callsite. + let RequireCompilationThread (_ctok: CompilationThreadToken) = () + + /// Represents a place in the compiler codebase where we are passed a CompilationThreadToken unnecessarily. + /// This represents code that may potentially not need to be executed on the compilation thread. + let DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent (_ctok: CompilationThreadToken) = () + + /// Represents a place in the compiler codebase where we assume we are executing on a compilation thread + let AssumeCompilationThreadWithoutEvidence () = Unchecked.defaultof + + let AnyCallerThread = Unchecked.defaultof + + let AssumeLockWithoutEvidence<'LockTokenType when 'LockTokenType :> LockToken> () = Unchecked.defaultof<'LockTokenType> + +/// Encapsulates a lock associated with a particular token-type representing the acquisition of that lock. +type Lock<'LockTokenType when 'LockTokenType :> LockToken>() = + let lockObj = obj() + member _.AcquireLock f = lock lockObj (fun () -> f (AssumeLockWithoutEvidence<'LockTokenType>())) + +//--------------------------------------------------- +// Misc + +module Map = + let tryFindMulti k map = match Map.tryFind k map with Some res -> res | None -> [] + +[] +type ResultOrException<'TResult> = + | Result of result: 'TResult + | Exception of ``exception``: Exception + +module ResultOrException = + + let success a = Result a + + let raze (b: exn) = Exception b + + // map + let (|?>) res f = + match res with + | Result x -> Result(f x ) + | Exception err -> Exception err + + let ForceRaise res = + match res with + | Result x -> x + | Exception err -> raise err + + let otherwise f x = + match x with + | Result x -> success x + | Exception _err -> f() + +[] +type ValueOrCancelled<'TResult> = + | Value of result: 'TResult + | Cancelled of ``exception``: OperationCanceledException + +/// Represents a cancellable computation with explicit representation of a cancelled result. +/// +/// A cancellable computation is passed may be cancelled via a CancellationToken, which is propagated implicitly. +/// If cancellation occurs, it is propagated as data rather than by raising an OperationCanceledException. +[] +type Cancellable<'TResult> = Cancellable of (CancellationToken -> ValueOrCancelled<'TResult>) + +module Cancellable = + + /// Run a cancellable computation using the given cancellation token + let run (ct: CancellationToken) (Cancellable oper) = + if ct.IsCancellationRequested then + ValueOrCancelled.Cancelled (OperationCanceledException ct) + else + oper ct + + /// Bind the result of a cancellable computation + let inline bind f comp1 = + Cancellable (fun ct -> + match run ct comp1 with + | ValueOrCancelled.Value v1 -> run ct (f v1) + | ValueOrCancelled.Cancelled err1 -> ValueOrCancelled.Cancelled err1) + + /// Map the result of a cancellable computation + let inline map f oper = + Cancellable (fun ct -> + match run ct oper with + | ValueOrCancelled.Value res -> ValueOrCancelled.Value (f res) + | ValueOrCancelled.Cancelled err -> ValueOrCancelled.Cancelled err) + + /// Return a simple value as the result of a cancellable computation + let inline ret x = Cancellable (fun _ -> ValueOrCancelled.Value x) + + /// Fold a cancellable computation along a sequence of inputs + let fold f acc seq = + Cancellable (fun ct -> + (ValueOrCancelled.Value acc, seq) + ||> Seq.fold (fun acc x -> + match acc with + | ValueOrCancelled.Value accv -> run ct (f accv x) + | res -> res)) + + /// Iterate a cancellable computation over a collection + let inline each f seq = + fold (fun acc x -> f x |> map (fun y -> (y :: acc))) [] seq |> map List.rev + + /// Delay a cancellable computation + let inline delay (f: unit -> Cancellable<'T>) = Cancellable (fun ct -> let (Cancellable g) = f() in g ct) + + /// Run the computation in a mode where it may not be cancelled. The computation never results in a + /// ValueOrCancelled.Cancelled. + let runWithoutCancellation comp = + let res = run CancellationToken.None comp + match res with + | ValueOrCancelled.Cancelled _ -> failwith "unexpected cancellation" + | ValueOrCancelled.Value r -> r + + let toAsync c = + async { + let! ct = Async.CancellationToken + let res = run ct c + return! Async.FromContinuations (fun (cont, _econt, ccont) -> + match res with + | ValueOrCancelled.Value v -> cont v + | ValueOrCancelled.Cancelled ce -> ccont ce) + } + + /// Bind the cancellation token associated with the computation + let token () = Cancellable (fun ct -> ValueOrCancelled.Value ct) + + /// Represents a canceled computation + let canceled() = Cancellable (fun ct -> ValueOrCancelled.Cancelled (OperationCanceledException ct)) + + /// Catch exceptions in a computation + let inline catch e = + let (Cancellable f) = e + Cancellable (fun ct -> + try + match f ct with + | ValueOrCancelled.Value r -> ValueOrCancelled.Value (Choice1Of2 r) + | ValueOrCancelled.Cancelled e -> ValueOrCancelled.Cancelled e + with err -> + ValueOrCancelled.Value (Choice2Of2 err)) + + /// Implement try/finally for a cancellable computation + let inline tryFinally e compensation = + catch e |> bind (fun res -> + compensation() + match res with Choice1Of2 r -> ret r | Choice2Of2 err -> raise err) + + /// Implement try/with for a cancellable computation + let inline tryWith e handler = + catch e |> bind (fun res -> + match res with Choice1Of2 r -> ret r | Choice2Of2 err -> handler err) + +type CancellableBuilder() = + + member inline _.BindReturn(e, k) = Cancellable.map k e + + member inline _.Bind(e, k) = Cancellable.bind k e + + member inline _.Return v = Cancellable.ret v + + member inline _.ReturnFrom (v: Cancellable<'T>) = v + + member inline _.Combine(e1, e2) = e1 |> Cancellable.bind (fun () -> e2) + + member inline _.For(es, f) = es |> Cancellable.each f + + member inline _.TryWith(e, handler) = Cancellable.tryWith e handler + + member inline _.Using(resource, e) = Cancellable.tryFinally (e resource) (fun () -> (resource :> IDisposable).Dispose()) + + member inline _.TryFinally(e, compensation) = Cancellable.tryFinally e compensation + + member inline _.Delay f = Cancellable.delay f + + member inline _.Zero() = Cancellable.ret () + +[] +module CancellableAutoOpens = + let cancellable = CancellableBuilder() + +/// Generates unique stamps +type UniqueStampGenerator<'T when 'T : equality>() = + let gate = obj () + let encodeTab = ConcurrentDictionary<'T, int>(HashIdentity.Structural) + let mutable nItems = 0 + let encode str = + match encodeTab.TryGetValue str with + | true, idx -> idx + | _ -> + lock gate (fun () -> + let idx = nItems + encodeTab.[str] <- idx + nItems <- nItems + 1 + idx) + + member this.Encode str = encode str + + member this.Table = encodeTab.Keys + +/// memoize tables (all entries cached, never collected) +type MemoizationTable<'T, 'U>(compute: 'T -> 'U, keyComparer: IEqualityComparer<'T>, ?canMemoize) = + + let table = new ConcurrentDictionary<'T, 'U>(keyComparer) + + member t.Apply x = + if (match canMemoize with None -> true | Some f -> f x) then + match table.TryGetValue x with + | true, res -> res + | _ -> + lock table (fun () -> + match table.TryGetValue x with + | true, res -> res + | _ -> + let res = compute x + table.[x] <- res + res) + else compute x + + +exception UndefinedException + +type LazyWithContextFailure(exn: exn) = + + static let undefined = LazyWithContextFailure(UndefinedException) + + member _.Exception = exn + + static member Undefined = undefined + +/// Just like "Lazy" but EVERY forcer must provide an instance of "ctxt", e.g. to help track errors +/// on forcing back to at least one sensible user location +[] +[] +type LazyWithContext<'T, 'ctxt> = + { /// This field holds the result of a successful computation. It's initial value is Unchecked.defaultof + mutable value : 'T + + /// This field holds either the function to run or a LazyWithContextFailure object recording the exception raised + /// from running the function. It is null if the thunk has been evaluated successfully. + mutable funcOrException: obj + + /// A helper to ensure we rethrow the "original" exception + findOriginalException : exn -> exn } + + static member Create(f: 'ctxt->'T, findOriginalException) : LazyWithContext<'T, 'ctxt> = + { value = Unchecked.defaultof<'T> + funcOrException = box f + findOriginalException = findOriginalException } + + static member NotLazy(x:'T) : LazyWithContext<'T, 'ctxt> = + { value = x + funcOrException = null + findOriginalException = id } + + member x.IsDelayed = (match x.funcOrException with null -> false | :? LazyWithContextFailure -> false | _ -> true) + + member x.IsForced = (match x.funcOrException with null -> true | _ -> false) + + member x.Force(ctxt:'ctxt) = + match x.funcOrException with + | null -> x.value + | _ -> + // Enter the lock in case another thread is in the process of evaluating the result + Monitor.Enter x; + try + x.UnsynchronizedForce ctxt + finally + Monitor.Exit x + + member x.UnsynchronizedForce ctxt = + match x.funcOrException with + | null -> x.value + | :? LazyWithContextFailure as res -> + // Re-raise the original exception + raise (x.findOriginalException res.Exception) + | :? ('ctxt -> 'T) as f -> + x.funcOrException <- box(LazyWithContextFailure.Undefined) + try + let res = f ctxt + x.value <- res + x.funcOrException <- null + res + with e -> + x.funcOrException <- box(LazyWithContextFailure(e)) + reraise() + | _ -> + failwith "unreachable" + +/// Intern tables to save space. +module Tables = + let memoize f = + let t = ConcurrentDictionary<_, _>(Environment.ProcessorCount, 1000, HashIdentity.Structural) + fun x -> + match t.TryGetValue x with + | true, res -> res + | _ -> + let res = f x + t.[x] <- res + res + +/// Interface that defines methods for comparing objects using partial equality relation +type IPartialEqualityComparer<'T> = + inherit IEqualityComparer<'T> + /// Can the specified object be tested for equality? + abstract InEqualityRelation : 'T -> bool + +module IPartialEqualityComparer = + + let On f (c: IPartialEqualityComparer<_>) = + { new IPartialEqualityComparer<_> with + member _.InEqualityRelation x = c.InEqualityRelation (f x) + member _.Equals(x, y) = c.Equals(f x, f y) + member _.GetHashCode x = c.GetHashCode(f x) } + + // Wrapper type for use by the 'partialDistinctBy' function + [] + type private WrapType<'T> = Wrap of 'T + + // Like Seq.distinctBy but only filters out duplicates for some of the elements + let partialDistinctBy (per: IPartialEqualityComparer<'T>) seq = + let wper = + { new IPartialEqualityComparer> with + member _.InEqualityRelation (Wrap x) = per.InEqualityRelation x + member _.Equals(Wrap x, Wrap y) = per.Equals(x, y) + member _.GetHashCode (Wrap x) = per.GetHashCode x } + // Wrap a Wrap _ around all keys in case the key type is itself a type using null as a representation + let dict = Dictionary, obj>(wper) + seq |> List.filter (fun v -> + let key = Wrap v + if (per.InEqualityRelation v) then + if dict.ContainsKey key then false else (dict.[key] <- null; true) + else true) + +//------------------------------------------------------------------------- +// Library: Name maps +//------------------------------------------------------------------------ + +type NameMap<'T> = Map + +type NameMultiMap<'T> = NameMap<'T list> + +type MultiMap<'T, 'U when 'T : comparison> = Map<'T, 'U list> + +module NameMap = + + let empty = Map.empty + + let range m = List.rev (Map.foldBack (fun _ x sofar -> x :: sofar) m []) + + let foldBack f (m: NameMap<'T>) z = Map.foldBack f m z + + let forall f m = Map.foldBack (fun x y sofar -> sofar && f x y) m true + + let exists f m = Map.foldBack (fun x y sofar -> sofar || f x y) m false + + let ofKeyedList f l = List.foldBack (fun x acc -> Map.add (f x) x acc) l Map.empty + + let ofList l : NameMap<'T> = Map.ofList l + + let ofSeq l : NameMap<'T> = Map.ofSeq l + + let toList (l: NameMap<'T>) = Map.toList l + + let layer (m1 : NameMap<'T>) m2 = Map.foldBack Map.add m1 m2 + + /// Not a very useful function - only called in one place - should be changed + let layerAdditive addf m1 m2 = + Map.foldBack (fun x y sofar -> Map.add x (addf (Map.tryFindMulti x sofar) y) sofar) m1 m2 + + /// Union entries by identical key, using the provided function to union sets of values + let union unionf (ms: NameMap<_> seq) = + seq { for m in ms do yield! m } + |> Seq.groupBy (fun (KeyValue(k, _v)) -> k) + |> Seq.map (fun (k, es) -> (k, unionf (Seq.map (fun (KeyValue(_k, v)) -> v) es))) + |> Map.ofSeq + + /// For every entry in m2 find an entry in m1 and fold + let subfold2 errf f m1 m2 acc = + Map.foldBack (fun n x2 acc -> try f n (Map.find n m1) x2 acc with :? KeyNotFoundException -> errf n x2) m2 acc + + let suball2 errf p m1 m2 = subfold2 errf (fun _ x1 x2 acc -> p x1 x2 && acc) m1 m2 true + + let mapFold f s (l: NameMap<'T>) = + Map.foldBack (fun x y (l2, sx) -> let y2, sy = f sx x y in Map.add x y2 l2, sy) l (Map.empty, s) + + let foldBackRange f (l: NameMap<'T>) acc = Map.foldBack (fun _ y acc -> f y acc) l acc + + let filterRange f (l: NameMap<'T>) = Map.foldBack (fun x y acc -> if f y then Map.add x y acc else acc) l Map.empty + + let mapFilter f (l: NameMap<'T>) = Map.foldBack (fun x y acc -> match f y with None -> acc | Some y' -> Map.add x y' acc) l Map.empty + + let map f (l : NameMap<'T>) = Map.map (fun _ x -> f x) l + + let iter f (l : NameMap<'T>) = Map.iter (fun _k v -> f v) l + + let partition f (l : NameMap<'T>) = Map.filter (fun _ x-> f x) l, Map.filter (fun _ x -> not (f x)) l + + let mem v (m: NameMap<'T>) = Map.containsKey v m + + let find v (m: NameMap<'T>) = Map.find v m + + let tryFind v (m: NameMap<'T>) = Map.tryFind v m + + let add v x (m: NameMap<'T>) = Map.add v x m + + let isEmpty (m: NameMap<'T>) = (Map.isEmpty m) + + let existsInRange p m = Map.foldBack (fun _ y acc -> acc || p y) m false + + let tryFindInRange p m = + Map.foldBack (fun _ y acc -> + match acc with + | None -> if p y then Some y else None + | _ -> acc) m None + +module NameMultiMap = + + let existsInRange f (m: NameMultiMap<'T>) = NameMap.exists (fun _ l -> List.exists f l) m + + let find v (m: NameMultiMap<'T>) = match m.TryGetValue v with true, r -> r | _ -> [] + + let add v x (m: NameMultiMap<'T>) = NameMap.add v (x :: find v m) m + + let range (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] + + let rangeReversingEachBucket (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.rev x @ sofar) m [] + + let chooseRange f (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.choose f x @ sofar) m [] + + let map f (m: NameMultiMap<'T>) = NameMap.map (List.map f) m + + let empty : NameMultiMap<'T> = Map.empty + + let initBy f xs : NameMultiMap<'T> = xs |> Seq.groupBy f |> Seq.map (fun (k, v) -> (k, List.ofSeq v)) |> Map.ofSeq + + let ofList (xs: (string * 'T) list) : NameMultiMap<'T> = xs |> Seq.groupBy fst |> Seq.map (fun (k, v) -> (k, List.ofSeq (Seq.map snd v))) |> Map.ofSeq + +module MultiMap = + + let existsInRange f (m: MultiMap<_, _>) = Map.exists (fun _ l -> List.exists f l) m + + let find v (m: MultiMap<_, _>) = match m.TryGetValue v with true, r -> r | _ -> [] + + let add v x (m: MultiMap<_, _>) = Map.add v (x :: find v m) m + + let range (m: MultiMap<_, _>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] + + let empty : MultiMap<_, _> = Map.empty + + let initBy f xs : MultiMap<_, _> = xs |> Seq.groupBy f |> Seq.map (fun (k, v) -> (k, List.ofSeq v)) |> Map.ofSeq + +type LayeredMap<'Key, 'Value when 'Key : comparison> = Map<'Key, 'Value> + +[] +module MapAutoOpens = + type Map<'Key, 'Value when 'Key : comparison> with + + static member Empty : Map<'Key, 'Value> = Map.empty + + member x.AddAndMarkAsCollapsible (kvs: _[]) = (x, kvs) ||> Array.fold (fun x (KeyValue(k, v)) -> x.Add(k, v)) + + member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) = x.Add (key, f (x.TryFind key)) + + member x.MarkAsCollapsible () = x + +/// Immutable map collection, with explicit flattening to a backing dictionary +[] +type LayeredMultiMap<'Key, 'Value when 'Key : equality and 'Key : comparison>(contents : LayeredMap<'Key, 'Value list>) = + + member x.Add (k, v) = LayeredMultiMap(contents.Add(k, v :: x.[k])) + + member x.Item with get k = match contents.TryGetValue k with true, l -> l | _ -> [] + + member x.AddAndMarkAsCollapsible (kvs: _[]) = + let x = (x, kvs) ||> Array.fold (fun x (KeyValue(k, v)) -> x.Add(k, v)) + x.MarkAsCollapsible() + + member x.MarkAsCollapsible() = LayeredMultiMap(contents.MarkAsCollapsible()) + + member x.TryFind k = contents.TryFind k + + member x.TryGetValue k = contents.TryGetValue k + + member x.Values = contents.Values |> List.concat + + static member Empty : LayeredMultiMap<'Key, 'Value> = LayeredMultiMap LayeredMap.Empty + diff --git a/src/fsharp/absil/illib.fsi b/src/fsharp/absil/illib.fsi new file mode 100644 index 00000000000..f74e6b47755 --- /dev/null +++ b/src/fsharp/absil/illib.fsi @@ -0,0 +1,628 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Internal.Utilities.Library + +open System +open System.Threading +open System.Collections.Generic +open System.Runtime.CompilerServices + +[] +module internal PervasiveAutoOpens = + /// Logical shift right treating int32 as unsigned integer. + /// Code that uses this should probably be adjusted to use unsigned integer types. + val ( >>>& ): x:int32 -> n:int32 -> int32 + + val notlazy: v:'a -> Lazy<'a> + + val inline isNil: l:'a list -> bool + + /// Returns true if the list has less than 2 elements. Otherwise false. + val inline isNilOrSingleton: l:'a list -> bool + + /// Returns true if the list contains exactly 1 element. Otherwise false. + val inline isSingleton: l:'a list -> bool + + val inline isNonNull: x:'a -> bool when 'a: null + + val inline nonNull: msg:string -> x:'a -> 'a when 'a: null + + val inline ( === ): x:'a -> y:'a -> bool when 'a: not struct + + /// Per the docs the threshold for the Large Object Heap is 85000 bytes: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap#how-an-object-ends-up-on-the-large-object-heap-and-how-gc-handles-them + /// We set the limit to be 80k to account for larger pointer sizes for when F# is running 64-bit. + val LOH_SIZE_THRESHOLD_BYTES: int + + val reportTime: (bool -> string -> unit) + + val runningOnMono: bool + + /// Get an initialization hole + val getHole: r:'a option ref -> 'a + + type String with + + member inline StartsWithOrdinal: value:string -> bool + + member inline EndsWithOrdinal: value:string -> bool + + type Async with + /// Runs the computation synchronously, always starting on the current thread. + static member RunImmediate: computation: Async<'T> * ?cancellationToken: CancellationToken -> 'T + + val foldOn: p:('a -> 'b) -> f:('c -> 'b -> 'd) -> z:'c -> x:'a -> 'd + + val notFound: unit -> 'a + +[] +type internal InlineDelayInit<'T when 'T: not struct> = + + new: f:(unit -> 'T) -> InlineDelayInit<'T> + val mutable store: 'T + val mutable func: Func<'T> + member Value: 'T + +module internal Order = + + val orderBy: p:('T -> 'U) -> IComparer<'T> when 'U: comparison + + val orderOn: p:('T -> 'U) -> pxOrder:IComparer<'U> -> IComparer<'T> + + val toFunction: pxOrder:IComparer<'U> -> x:'U -> y:'U -> int + +module internal Array = + + val mapq: f:('a -> 'a) -> inp:'a [] -> 'a [] when 'a: not struct + + val lengthsEqAndForall2 : p:('a -> 'b -> bool) -> l1:'a [] -> l2:'b [] -> bool + + val order : eltOrder:IComparer<'T> -> IComparer<'T array> + + val existsOne: p:('a -> bool) -> l:'a [] -> bool + + val existsTrue: arr:bool [] -> bool + + val findFirstIndexWhereTrue: arr:'a [] -> p:('a -> bool) -> int + + /// pass an array byref to reverse it in place + val revInPlace: array:'T [] -> unit + + /// Async implementation of Array.map. + val mapAsync: mapping:('T -> Async<'U>) -> array:'T [] -> Async<'U []> + + /// Returns a new array with an element replaced with a given value. + val replace: index:int -> value:'a -> array:'a [] -> 'a [] + + /// Optimized arrays equality. ~100x faster than `array1 = array2` on strings. + /// ~2x faster for floats + /// ~0.8x slower for ints + val inline areEqual: xs:'T [] -> ys:'T [] -> bool when 'T: equality + + /// Returns all heads of a given array. + val heads: array:'T [] -> 'T [] [] + + /// Check if subArray is found in the wholeArray starting at the provided index + val inline isSubArray : subArray:'T [] -> wholeArray:'T [] -> index:int -> bool when 'T: equality + + /// Returns true if one array has another as its subset from index 0. + val startsWith: prefix:'a [] -> whole:'a [] -> bool when 'a: equality + + /// Returns true if one array has trailing elements equal to another's. + val endsWith: suffix:'a [] -> whole:'a [] -> bool when 'a: equality + +module internal Option = + + val mapFold: f:('a -> 'b -> 'c * 'a) -> s:'a -> opt:'b option -> 'c option * 'a + + val attempt: f:(unit -> 'T) -> 'T option + +module internal List = + + val sortWithOrder : c:IComparer<'T> -> elements:'T list -> 'T list + + val splitAfter: n:int -> l:'a list -> 'a list * 'a list + + val existsi: f:(int -> 'a -> bool) -> xs:'a list -> bool + + val lengthsEqAndForall2 : p:('a -> 'b -> bool) -> l1:'a list -> l2:'b list -> bool + + val findi: n:int -> f:('a -> bool) -> l:'a list -> ('a * int) option + + val splitChoose : select:('a -> Choice<'b,'c>) -> l:'a list -> 'b list * 'c list + + val checkq: l1:'a list -> l2:'a list -> bool when 'a: not struct + + val mapq: f:('T -> 'T) -> inp:'T list -> 'T list when 'T: not struct + + val frontAndBack: l:'a list -> 'a list * 'a + + val tryRemove: f:('a -> bool) -> inp:'a list -> ('a * 'a list) option + + val zip4 : l1:'a list -> l2:'b list -> l3:'c list -> l4:'d list -> ('a * 'b * 'c * 'd) list + + val unzip4 : l:('a * 'b * 'c * 'd) list -> 'a list * 'b list * 'c list * 'd list + + val iter3 : f:('a -> 'b -> 'c -> unit) -> l1:'a list -> l2:'b list -> l3:'c list -> unit + + val takeUntil: p:('a -> bool) -> l:'a list -> 'a list * 'a list + + val order : eltOrder:IComparer<'T> -> IComparer<'T list> + + val indexNotFound: unit -> 'a + + val assoc: x:'a -> l:('a * 'b) list -> 'b when 'a: equality + + val memAssoc: x:'a -> l:('a * 'b) list -> bool when 'a: equality + + val memq: x:'a -> l:'a list -> bool when 'a: not struct + + val mapNth: n:int -> f:('a -> 'a) -> xs:'a list -> 'a list + + val count: pred:('a -> bool) -> xs:'a list -> int + + val headAndTail: l:'a list -> 'a * 'a list + + // WARNING: not tail-recursive + val mapHeadTail : fhead:('a -> 'b) -> ftail:('a -> 'b) -> _arg1:'a list -> 'b list + + val collectFold : f:('a -> 'b -> 'c list * 'a) -> s:'a -> l:'b list -> 'c list * 'a + + val collect2 : f:('a -> 'b -> 'c list) -> xs:'a list -> ys:'b list -> 'c list + + val toArraySquared: xss:'a list list -> 'a [] [] + + val iterSquared: f:('a -> unit) -> xss:'a list list -> unit + + val collectSquared: f:('a -> 'b list) -> xss:'a list list -> 'b list + + val mapSquared: f:('a -> 'b) -> xss:'a list list -> 'b list list + + val mapFoldSquared : f:('a -> 'b -> 'c * 'a) -> z:'a -> xss:'b list list -> 'c list list * 'a + + val forallSquared: f:('a -> bool) -> xss:'a list list -> bool + + val mapiSquared : f:(int -> int -> 'a -> 'b) -> xss:'a list list -> 'b list list + + val existsSquared: f:('a -> bool) -> xss:'a list list -> bool + + val mapiFoldSquared : f:('a -> int * int * 'b -> 'c * 'a) -> z:'a -> xss:'b list list -> 'c list list * 'a + + val duplicates: xs:'T list -> 'T list when 'T: equality + + val internal allEqual: xs:'T list -> bool when 'T: equality + +module internal ResizeArray = + + /// Split a ResizeArray into an array of smaller chunks. + /// This requires `items/chunkSize` Array copies of length `chunkSize` if `items/chunkSize % 0 = 0`, + /// otherwise `items/chunkSize + 1` Array copies. + val chunkBySize : chunkSize:int -> f:('t -> 'a) -> items:ResizeArray<'t> -> 'a [] [] + + /// Split a large ResizeArray into a series of array chunks that are each under the Large Object Heap limit. + /// This is done to help prevent a stop-the-world collection of the single large array, instead allowing for a greater + /// probability of smaller collections. Stop-the-world is still possible, just less likely. + val mapToSmallArrayChunks : f:('t -> 'a) -> inp:ResizeArray<'t> -> 'a [] [] + +module internal ValueOptionInternal = + + val inline ofOption: x:'a option -> 'a voption + + val inline bind: f:('a -> 'b voption) -> x:'a voption -> 'b voption + + +module internal String = + + val make: n:int -> c:char -> string + + val get: str:string -> i:int -> char + + val sub: s:string -> start:int -> len:int -> string + + val contains: s:string -> c:char -> bool + + val order: IComparer + + val lowercase: s:string -> string + + val uppercase: s:string -> string + + val isLeadingIdentifierCharacterUpperCase: s:string -> bool + + val capitalize: s:string -> string + + val uncapitalize: s:string -> string + + val dropPrefix: s:string -> t:string -> string + + val dropSuffix: s:string -> t:string -> string + + val inline toCharArray: str:string -> char [] + + val lowerCaseFirstChar: str:string -> string + + val extractTrailingIndex: str:string -> string * int option + + /// Remove all trailing and leading whitespace from the string, return null if the string is null + val trim: value:string -> string + + /// Splits a string into substrings based on the strings in the array separators + val split : options:StringSplitOptions -> separator:string [] -> value:string -> string [] + + val (|StartsWith|_|): pattern:string -> value:string -> unit option + + val (|Contains|_|): pattern:string -> value:string -> unit option + + val getLines: str:string -> string [] + +module internal Dictionary = + val inline newWithSize : size:int -> Dictionary<'a,'b> when 'a: equality + val inline ofList : xs: ('Key * 'Value) list -> Dictionary<'Key,'Value> when 'Key: equality + +[] +type internal DictionaryExtensions = + + [] + static member inline BagAdd: dic:Dictionary<'key,'value list> * key:'key * value:'value -> unit + + [] + static member inline BagExistsValueForKey: dic:Dictionary<'key,'value list> * key:'key * f:('value -> bool) -> bool + +module internal Lazy = + val force: x:Lazy<'T> -> 'T + +/// Represents a permission active at this point in execution +type internal ExecutionToken = interface end + +/// Represents a token that indicates execution on the compilation thread, i.e. +/// - we have full access to the (partially mutable) TAST and TcImports data structures +/// - compiler execution may result in type provider invocations when resolving types and members +/// - we can access various caches in the SourceCodeServices +/// +/// Like other execution tokens this should be passed via argument passing and not captured/stored beyond +/// the lifetime of stack-based calls. This is not checked, it is a discipline within the compiler code. +[] +type internal CompilationThreadToken = + + interface ExecutionToken + new: unit -> CompilationThreadToken + +/// Represents a token that indicates execution on any of several potential user threads calling the F# compiler services. +[] +type internal AnyCallerThreadToken = + + interface ExecutionToken + new: unit -> AnyCallerThreadToken + +/// A base type for various types of tokens that must be passed when a lock is taken. +/// Each different static lock should declare a new subtype of this type. +type internal LockToken = + interface + inherit ExecutionToken + end + +/// Encapsulates a lock associated with a particular token-type representing the acquisition of that lock. +type internal Lock<'LockTokenType when 'LockTokenType :> LockToken> = + + new: unit -> Lock<'LockTokenType> + member AcquireLock: f:('LockTokenType -> 'a) -> 'a + +[] +module internal LockAutoOpens = + /// Represents a place where we are stating that execution on the compilation thread is required. The + /// reason why will be documented in a comment in the code at the callsite. + val RequireCompilationThread: _ctok:CompilationThreadToken -> unit + + /// Represents a place in the compiler codebase where we are passed a CompilationThreadToken unnecessarily. + /// This represents code that may potentially not need to be executed on the compilation thread. + val DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent : _ctok:CompilationThreadToken -> unit + + /// Represents a place in the compiler codebase where we assume we are executing on a compilation thread + val AssumeCompilationThreadWithoutEvidence: unit -> CompilationThreadToken + + val AnyCallerThread: AnyCallerThreadToken + + val AssumeLockWithoutEvidence: unit -> #LockToken + +module internal Map = + val tryFindMulti : + k:'a -> map:Map<'a,'b list> -> 'b list when 'a: comparison + +[] +type internal ResultOrException<'TResult> = + | Result of result: 'TResult + | Exception of ``exception``: Exception + +module internal ResultOrException = + + val success: a:'a -> ResultOrException<'a> + + val raze: b:exn -> ResultOrException<'a> + + val ( |?> ) : res:ResultOrException<'a> -> f:('a -> 'b) -> ResultOrException<'b> + + val ForceRaise: res:ResultOrException<'a> -> 'a + + val otherwise : f:(unit -> ResultOrException<'a>) -> x:ResultOrException<'a> -> ResultOrException<'a> + +[] +type internal ValueOrCancelled<'TResult> = + | Value of result: 'TResult + | Cancelled of ``exception``: OperationCanceledException + +/// Represents a synchronous cancellable computation with explicit representation of a cancelled result. +/// +/// A cancellable computation is passed may be cancelled via a CancellationToken, which is propagated implicitly. +/// If cancellation occurs, it is propagated as data rather than by raising an OperationCanceledException. +[] +type internal Cancellable<'TResult> = + | Cancellable of (CancellationToken -> ValueOrCancelled<'TResult>) + +module internal Cancellable = + + /// Run a cancellable computation using the given cancellation token + val run : ct:CancellationToken -> Cancellable<'a> -> ValueOrCancelled<'a> + + /// Bind the result of a cancellable computation + val inline bind : f:('a -> Cancellable<'b>) -> comp1:Cancellable<'a> -> Cancellable<'b> + + /// Map the result of a cancellable computation + val inline map: f:('a -> 'b) -> oper:Cancellable<'a> -> Cancellable<'b> + + /// Return a simple value as the result of a cancellable computation + val inline ret: x:'a -> Cancellable<'a> + + /// Fold a cancellable computation along a sequence of inputs + val fold : f:('a -> 'b -> Cancellable<'a>) -> acc:'a -> seq:seq<'b> -> Cancellable<'a> + + /// Iterate a cancellable computation over a collection + val inline each : f:('a -> Cancellable<'b>) -> seq:seq<'a> -> Cancellable<'b list> + + /// Delay a cancellable computation + val inline delay: f:(unit -> Cancellable<'T>) -> Cancellable<'T> + + /// Run the computation in a mode where it may not be cancelled. The computation never results in a + /// ValueOrCancelled.Cancelled. + val runWithoutCancellation: comp:Cancellable<'a> -> 'a + + /// Bind the cancellation token associated with the computation + val token: unit -> Cancellable + + /// Represents a canceled computation + val canceled: unit -> Cancellable<'a> + + /// Implement try/finally for a cancellable computation + val inline catch : e:Cancellable<'a> -> Cancellable> + + /// Implement try/finally for a cancellable computation + val inline tryFinally : e:Cancellable<'a> -> compensation:(unit -> unit) -> Cancellable<'a> + + /// Implement try/with for a cancellable computation + val inline tryWith : e:Cancellable<'a> -> handler:(exn -> Cancellable<'a>) -> Cancellable<'a> + + val toAsync: Cancellable<'a> -> Async<'a> + +type internal CancellableBuilder = + + new: unit -> CancellableBuilder + + member inline BindReturn: e:Cancellable<'T> * k:('T -> 'U) -> Cancellable<'U> + + member inline Bind: e:Cancellable<'T> * k:('T -> Cancellable<'U>) -> Cancellable<'U> + + member inline Combine: e1:Cancellable * e2:Cancellable<'T> -> Cancellable<'T> + + member inline Delay: f:(unit -> Cancellable<'T>) -> Cancellable<'T> + + member inline For: es:seq<'T> * f:('T -> Cancellable<'U>) -> Cancellable<'U list> + + member inline Return: v:'T -> Cancellable<'T> + + member inline ReturnFrom: v:Cancellable<'T> -> Cancellable<'T> + + member inline TryFinally: e:Cancellable<'T> * compensation:(unit -> unit) -> Cancellable<'T> + + member inline TryWith: e:Cancellable<'T> * handler:(exn -> Cancellable<'T>) -> Cancellable<'T> + + member inline Using: resource:'c * e:('c -> Cancellable<'T>) -> Cancellable<'T> when 'c :> IDisposable + + member inline Zero: unit -> Cancellable + +[] +module internal CancellableAutoOpens = + val cancellable: CancellableBuilder + +/// Generates unique stamps +type internal UniqueStampGenerator<'T when 'T: equality> = + + new: unit -> UniqueStampGenerator<'T> + + member Encode: str:'T -> int + + member Table: ICollection<'T> + +/// Memoize tables (all entries cached, never collected unless whole table is collected) +type internal MemoizationTable<'T,'U> = + + new: compute:('T -> 'U) * keyComparer:IEqualityComparer<'T> * ?canMemoize:('T -> bool) -> MemoizationTable<'T,'U> + + member Apply: x:'T -> 'U + +exception internal UndefinedException + +type internal LazyWithContextFailure = + + new: exn:exn -> LazyWithContextFailure + + member Exception: exn + + static member Undefined: LazyWithContextFailure + +/// Just like "Lazy" but EVERY forcer must provide an instance of "ctxt", e.g. to help track errors +/// on forcing back to at least one sensible user location +[] +type internal LazyWithContext<'T,'ctxt> = + static member Create: f:('ctxt -> 'T) * findOriginalException:(exn -> exn) -> LazyWithContext<'T,'ctxt> + static member NotLazy: x:'T -> LazyWithContext<'T,'ctxt> + member Force: ctxt:'ctxt -> 'T + member UnsynchronizedForce: ctxt:'ctxt -> 'T + member IsDelayed: bool + member IsForced: bool + +/// Intern tables to save space. +module internal Tables = + val memoize: f:('a -> 'b) -> ('a -> 'b) when 'a: equality + +/// Interface that defines methods for comparing objects using partial equality relation +type internal IPartialEqualityComparer<'T> = + inherit IEqualityComparer<'T> + abstract InEqualityRelation: 'T -> bool + +/// Interface that defines methods for comparing objects using partial equality relation +module internal IPartialEqualityComparer = + val On : f:('a -> 'b) -> c:IPartialEqualityComparer<'b> -> IPartialEqualityComparer<'a> + + /// Like Seq.distinctBy but only filters out duplicates for some of the elements + val partialDistinctBy : per:IPartialEqualityComparer<'T> -> seq:'T list -> 'T list + +type internal NameMap<'T> = Map + +type internal NameMultiMap<'T> = NameMap<'T list> + +type internal MultiMap<'T,'U when 'T: comparison> = Map<'T,'U list> + +module internal NameMap = + + val empty: Map<'a,'b> when 'a: comparison + + val range: m:Map<'a,'b> -> 'b list when 'a: comparison + + val foldBack: f:(string -> 'T -> 'a -> 'a) -> m:NameMap<'T> -> z:'a -> 'a + + val forall : f:('a -> 'b -> bool) -> m:Map<'a,'b> -> bool when 'a: comparison + + val exists : f:('a -> 'b -> bool) -> m:Map<'a,'b> -> bool when 'a: comparison + + + val ofKeyedList : f:('a -> 'b) -> l:'a list -> Map<'b,'a> when 'b: comparison + + val ofList: l:(string * 'T) list -> NameMap<'T> + + val ofSeq: l:seq -> NameMap<'T> + + val toList: l:NameMap<'T> -> (string * 'T) list + + val layer: m1:NameMap<'T> -> m2:Map -> Map + + /// Not a very useful function - only called in one place - should be changed + val layerAdditive : addf:('a list -> 'b -> 'a list) -> m1:Map<'c,'b> -> m2:Map<'c,'a list> -> Map<'c,'a list> when 'c: comparison + + /// Union entries by identical key, using the provided function to union sets of values + val union : unionf:(seq<'a> -> 'b) -> ms:seq> -> Map + + /// For every entry in m2 find an entry in m1 and fold + val subfold2 : errf:('a -> 'b -> 'c) -> f:('a -> 'd -> 'b -> 'c -> 'c) -> m1:Map<'a,'d> -> m2:Map<'a,'b> -> acc:'c -> 'c when 'a: comparison + + val suball2 : errf:('a -> 'b -> bool) -> p:('c -> 'b -> bool) -> m1:Map<'a,'c> -> m2:Map<'a,'b> -> bool when 'a: comparison + + val mapFold : f:('a -> string -> 'T -> 'b * 'a) -> s:'a -> l:NameMap<'T> -> Map * 'a + + val foldBackRange: f:('T -> 'a -> 'a) -> l:NameMap<'T> -> acc:'a -> 'a + + val filterRange: f:('T -> bool) -> l:NameMap<'T> -> Map + + val mapFilter: f:('T -> 'a option) -> l:NameMap<'T> -> Map + + val map: f:('T -> 'a) -> l:NameMap<'T> -> Map + + val iter: f:('T -> unit) -> l:NameMap<'T> -> unit + + val partition : f:('T -> bool) -> l:NameMap<'T> -> Map * Map + + val mem: v:string -> m:NameMap<'T> -> bool + + val find: v:string -> m:NameMap<'T> -> 'T + + val tryFind: v:string -> m:NameMap<'T> -> 'T option + + val add: v:string -> x:'T -> m:NameMap<'T> -> Map + + val isEmpty: m:NameMap<'T> -> bool + + val existsInRange : p:('a -> bool) -> m:Map<'b,'a> -> bool when 'b: comparison + + val tryFindInRange : p:('a -> bool) -> m:Map<'b,'a> -> 'a option when 'b: comparison + +module internal NameMultiMap = + + val existsInRange: f:('T -> bool) -> m:NameMultiMap<'T> -> bool + + val find: v:string -> m:NameMultiMap<'T> -> 'T list + + val add: v:string -> x:'T -> m:NameMultiMap<'T> -> Map + + val range: m:NameMultiMap<'T> -> 'T list + + val rangeReversingEachBucket: m:NameMultiMap<'T> -> 'T list + + val chooseRange: f:('T -> 'a option) -> m:NameMultiMap<'T> -> 'a list + + val map: f:('T -> 'a) -> m:NameMultiMap<'T> -> Map + + val empty: NameMultiMap<'T> + + val initBy: f:('T -> string) -> xs:seq<'T> -> NameMultiMap<'T> + + val ofList: xs:(string * 'T) list -> NameMultiMap<'T> + +module internal MultiMap = + + val existsInRange : f:('a -> bool) -> m:MultiMap<'b,'a> -> bool when 'b: comparison + + val find: v:'a -> m:MultiMap<'a,'b> -> 'b list when 'a: comparison + + val add : v:'a -> x:'b -> m:MultiMap<'a,'b> -> Map<'a,'b list> when 'a: comparison + + val range: m:MultiMap<'a,'b> -> 'b list when 'a: comparison + + val empty: MultiMap<'a,'b> when 'a: comparison + + val initBy : f:('a -> 'b) -> xs:seq<'a> -> MultiMap<'b,'a> when 'b: comparison + +type internal LayeredMap<'Key,'Value when 'Key: comparison> = Map<'Key,'Value> + + +[] +module internal MapAutoOpens = + type internal Map<'Key,'Value when 'Key: comparison> with + + static member Empty: Map<'Key,'Value> when 'Key: comparison + + member AddAndMarkAsCollapsible: kvs:KeyValuePair<'Key,'Value> [] -> Map<'Key,'Value> when 'Key: comparison + + member LinearTryModifyThenLaterFlatten: key:'Key * f:('Value option -> 'Value) -> Map<'Key,'Value> when 'Key: comparison + + type internal Map<'Key,'Value when 'Key: comparison> with + member MarkAsCollapsible: unit -> Map<'Key,'Value> when 'Key: comparison + +/// Immutable map collection, with explicit flattening to a backing dictionary +[] +type internal LayeredMultiMap<'Key,'Value when 'Key: comparison> = + + new: contents:LayeredMap<'Key,'Value list> -> LayeredMultiMap<'Key,'Value> + + member Add: k:'Key * v:'Value -> LayeredMultiMap<'Key,'Value> + + member AddAndMarkAsCollapsible: kvs:KeyValuePair<'Key,'Value> [] -> LayeredMultiMap<'Key,'Value> + + member MarkAsCollapsible: unit -> LayeredMultiMap<'Key,'Value> + + member TryFind: k:'Key -> 'Value list option + + member TryGetValue: k:'Key -> bool * 'Value list + + member Item: k:'Key -> 'Value list with get + + member Values: 'Value list + + static member Empty: LayeredMultiMap<'Key,'Value> + diff --git a/src/fsharp/absil/ilmorph.fs b/src/fsharp/absil/ilmorph.fs new file mode 100644 index 00000000000..558bae43600 --- /dev/null +++ b/src/fsharp/absil/ilmorph.fs @@ -0,0 +1,318 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.AbstractIL.Morphs + +open System.Collections.Generic +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL + +let mutable morphCustomAttributeData = false + +let enableMorphCustomAttributeData() = + morphCustomAttributeData <- true + +let disableMorphCustomAttributeData() = + morphCustomAttributeData <- false + +let code_instr2instr f (code: ILCode) = {code with Instrs= Array.map f code.Instrs} + +let code_instr2instrs f (code: ILCode) = + let instrs = code.Instrs + let codebuf = ResizeArray() + let adjust = Dictionary() + let mutable old = 0 + let mutable nw = 0 + for instr in instrs do + adjust.[old] <- nw + let instrs : list<_> = f instr + for instr2 in instrs do + codebuf.Add instr2 + nw <- nw + 1 + old <- old + 1 + adjust.[old] <- nw + let labels = + let dict = Dictionary.newWithSize code.Labels.Count + for kvp in code.Labels do dict.Add(kvp.Key, adjust.[kvp.Value]) + dict + { code with + Instrs = codebuf.ToArray() + Labels = labels } + + + +let code_instr2instr_ty2ty (finstr,fty) (c:ILCode) = + let c = code_instr2instr finstr c + { c with + Exceptions = c.Exceptions |> List.map (fun e -> { e with Clause = e.Clause |> (function ILExceptionClause.TypeCatch (ilty, b) -> ILExceptionClause.TypeCatch (fty ilty, b) | cl -> cl) }) } + +// -------------------------------------------------------------------- +// Standard morphisms - mapping types etc. +// -------------------------------------------------------------------- + +let rec ty_tref2tref f x = + match x with + | ILType.Ptr t -> ILType.Ptr (ty_tref2tref f t) + | ILType.FunctionPointer x -> + ILType.FunctionPointer + { x with + ArgTypes=List.map (ty_tref2tref f) x.ArgTypes + ReturnType=ty_tref2tref f x.ReturnType} + | ILType.Byref t -> ILType.Byref (ty_tref2tref f t) + | ILType.Boxed cr -> mkILBoxedType (tspec_tref2tref f cr) + | ILType.Value ir -> ILType.Value (tspec_tref2tref f ir) + | ILType.Array (s,ty) -> ILType.Array (s,ty_tref2tref f ty) + | ILType.TypeVar v -> ILType.TypeVar v + | ILType.Modified (req,tref,ty) -> ILType.Modified (req, f tref, ty_tref2tref f ty) + | ILType.Void -> ILType.Void +and tspec_tref2tref f (x:ILTypeSpec) = + mkILTySpec(f x.TypeRef, List.map (ty_tref2tref f) x.GenericArgs) + +let rec ty_scoref2scoref_tyvar2ty (_fscope,ftyvar as fs)x = + match x with + | ILType.Ptr t -> ILType.Ptr (ty_scoref2scoref_tyvar2ty fs t) + | ILType.FunctionPointer t -> ILType.FunctionPointer (callsig_scoref2scoref_tyvar2ty fs t) + | ILType.Byref t -> ILType.Byref (ty_scoref2scoref_tyvar2ty fs t) + | ILType.Boxed cr -> mkILBoxedType (tspec_scoref2scoref_tyvar2ty fs cr) + | ILType.Value ir -> ILType.Value (tspec_scoref2scoref_tyvar2ty fs ir) + | ILType.Array (s,ty) -> ILType.Array (s,ty_scoref2scoref_tyvar2ty fs ty) + | ILType.TypeVar v -> ftyvar v + | x -> x +and tspec_scoref2scoref_tyvar2ty fs (x:ILTypeSpec) = + ILTypeSpec.Create(morphILScopeRefsInILTypeRef (fst fs) x.TypeRef,tys_scoref2scoref_tyvar2ty fs x.GenericArgs) +and callsig_scoref2scoref_tyvar2ty f x = + { x with + ArgTypes=List.map (ty_scoref2scoref_tyvar2ty f) x.ArgTypes + ReturnType=ty_scoref2scoref_tyvar2ty f x.ReturnType} +and tys_scoref2scoref_tyvar2ty f i = List.map (ty_scoref2scoref_tyvar2ty f) i +and gparams_scoref2scoref_tyvar2ty f i = List.map (gparam_scoref2scoref_tyvar2ty f) i +and gparam_scoref2scoref_tyvar2ty _f i = i +and morphILScopeRefsInILTypeRef fscope (x:ILTypeRef) = + ILTypeRef.Create(scope=fscope x.Scope, enclosing=x.Enclosing, name = x.Name) + + +let callsig_ty2ty f (x: ILCallingSignature) = + { CallingConv=x.CallingConv + ArgTypes=List.map f x.ArgTypes + ReturnType=f x.ReturnType} + +let gparam_ty2ty f gf = {gf with Constraints = List.map f gf.Constraints} +let gparams_ty2ty f gfs = List.map (gparam_ty2ty f) gfs +let tys_ty2ty (f: ILType -> ILType) x = List.map f x +let mref_ty2ty (f: ILType -> ILType) (x:ILMethodRef) = + ILMethodRef.Create(enclosingTypeRef= (f (mkILBoxedType (mkILNonGenericTySpec x.DeclaringTypeRef))).TypeRef, + callingConv=x.CallingConv, + name=x.Name, + genericArity=x.GenericArity, + argTypes= List.map f x.ArgTypes, + returnType= f x.ReturnType) + + +type formal_scopeCtxt = Choice + +let mspec_ty2ty ((factualty : ILType -> ILType, fformalty: formal_scopeCtxt -> ILType -> ILType)) (x: ILMethodSpec) = + mkILMethSpecForMethRefInTy(mref_ty2ty (fformalty (Choice1Of2 x)) x.MethodRef, + factualty x.DeclaringType, + tys_ty2ty factualty x.GenericArgs) + +let fref_ty2ty (f: ILType -> ILType) x = + { x with DeclaringTypeRef = (f (mkILBoxedType (mkILNonGenericTySpec x.DeclaringTypeRef))).TypeRef + Type= f x.Type } + +let fspec_ty2ty ((factualty,fformalty : formal_scopeCtxt -> ILType -> ILType)) x = + { FieldRef=fref_ty2ty (fformalty (Choice2Of2 x)) x.FieldRef + DeclaringType= factualty x.DeclaringType } + +let rec celem_ty2ty f celem = + match celem with + | ILAttribElem.Type (Some ty) -> ILAttribElem.Type (Some (f ty)) + | ILAttribElem.TypeRef (Some tref) -> ILAttribElem.TypeRef (Some (f (mkILBoxedType (mkILNonGenericTySpec tref))).TypeRef) + | ILAttribElem.Array (elemTy,elems) -> ILAttribElem.Array (f elemTy, List.map (celem_ty2ty f) elems) + | _ -> celem + +let cnamedarg_ty2ty f ((nm, ty, isProp, elem) : ILAttributeNamedArg) = + (nm, f ty, isProp, celem_ty2ty f elem) + +let cattr_ty2ty f (c: ILAttribute) = + let meth = mspec_ty2ty (f, (fun _ -> f)) c.Method + // dev11 M3 defensive coding: if anything goes wrong with attribute decoding or encoding, then back out. + if morphCustomAttributeData then + try + let elems,namedArgs = decodeILAttribData c + let elems = elems |> List.map (celem_ty2ty f) + let namedArgs = namedArgs |> List.map (cnamedarg_ty2ty f) + mkILCustomAttribMethRef (meth, elems, namedArgs) + with _ -> + c.WithMethod(meth) + else + c.WithMethod(meth) + + +let cattrs_ty2ty f (cs: ILAttributes) = + mkILCustomAttrs (List.map (cattr_ty2ty f) cs.AsList) + +let fdef_ty2ty ftye (fd: ILFieldDef) = + fd.With(fieldType=ftye fd.FieldType, + customAttrs=cattrs_ty2ty ftye fd.CustomAttrs) + +let local_ty2ty f (l: ILLocal) = {l with Type = f l.Type} +let varargs_ty2ty f (varargs: ILVarArgs) = Option.map (List.map f) varargs +(* REVIEW: convert varargs *) +let morphILTypesInILInstr ((factualty,fformalty)) i = + let factualty = factualty (Some i) + let conv_fspec fr = fspec_ty2ty (factualty,fformalty (Some i)) fr + let conv_mspec mr = mspec_ty2ty (factualty,fformalty (Some i)) mr + match i with + | I_calli (a,mref,varargs) -> I_calli (a,callsig_ty2ty factualty mref,varargs_ty2ty factualty varargs) + | I_call (a,mr,varargs) -> I_call (a,conv_mspec mr,varargs_ty2ty factualty varargs) + | I_callvirt (a,mr,varargs) -> I_callvirt (a,conv_mspec mr,varargs_ty2ty factualty varargs) + | I_callconstraint (a,ty,mr,varargs) -> I_callconstraint (a,factualty ty,conv_mspec mr,varargs_ty2ty factualty varargs) + | I_newobj (mr,varargs) -> I_newobj (conv_mspec mr,varargs_ty2ty factualty varargs) + | I_ldftn mr -> I_ldftn (conv_mspec mr) + | I_ldvirtftn mr -> I_ldvirtftn (conv_mspec mr) + | I_ldfld (a,b,fr) -> I_ldfld (a,b,conv_fspec fr) + | I_ldsfld (a,fr) -> I_ldsfld (a,conv_fspec fr) + | I_ldsflda fr -> I_ldsflda (conv_fspec fr) + | I_ldflda fr -> I_ldflda (conv_fspec fr) + | I_stfld (a,b,fr) -> I_stfld (a,b,conv_fspec fr) + | I_stsfld (a,fr) -> I_stsfld (a,conv_fspec fr) + | I_castclass ty -> I_castclass (factualty ty) + | I_isinst ty -> I_isinst (factualty ty) + | I_initobj ty -> I_initobj (factualty ty) + | I_cpobj ty -> I_cpobj (factualty ty) + | I_stobj (al,vol,ty) -> I_stobj (al,vol,factualty ty) + | I_ldobj (al,vol,ty) -> I_ldobj (al,vol,factualty ty) + | I_box ty -> I_box (factualty ty) + | I_unbox ty -> I_unbox (factualty ty) + | I_unbox_any ty -> I_unbox_any (factualty ty) + | I_ldelem_any (shape,ty) -> I_ldelem_any (shape,factualty ty) + | I_stelem_any (shape,ty) -> I_stelem_any (shape,factualty ty) + | I_newarr (shape,ty) -> I_newarr (shape,factualty ty) + | I_ldelema (ro,isNativePtr,shape,ty) -> I_ldelema (ro,isNativePtr,shape,factualty ty) + | I_sizeof ty -> I_sizeof (factualty ty) + | I_ldtoken tok -> + match tok with + | ILToken.ILType ty -> I_ldtoken (ILToken.ILType (factualty ty)) + | ILToken.ILMethod mr -> I_ldtoken (ILToken.ILMethod (conv_mspec mr)) + | ILToken.ILField fr -> I_ldtoken (ILToken.ILField (conv_fspec fr)) + | x -> x + +let return_ty2ty f (r:ILReturn) = {r with Type=f r.Type; CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty f r.CustomAttrs)} +let param_ty2ty f (p: ILParameter) = {p with Type=f p.Type; CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty f p.CustomAttrs)} + +let morphILMethodDefs f (m:ILMethodDefs) = mkILMethods (List.map f m.AsList) +let fdefs_fdef2fdef f (m:ILFieldDefs) = mkILFields (List.map f m.AsList) + +(* use this when the conversion produces just one tye... *) +let morphILTypeDefs f (m: ILTypeDefs) = mkILTypeDefsFromArray (Array.map f m.AsArray) + +let locals_ty2ty f ls = List.map (local_ty2ty f) ls + +let ilmbody_instr2instr_ty2ty fs (il: ILMethodBody) = + let finstr,ftye = fs + {il with Code=code_instr2instr_ty2ty (finstr,ftye) il.Code + Locals = locals_ty2ty ftye il.Locals } + +let morphILMethodBody filmbody (x: MethodBody) = + match x with + | MethodBody.IL il -> + let ilCode = filmbody il.Value // Eager + MethodBody.IL (lazy ilCode) + | x -> x + +let ospec_ty2ty f (OverridesSpec(mref,ty)) = OverridesSpec(mref_ty2ty f mref, f ty) + +let mdef_ty2ty_ilmbody2ilmbody fs (md: ILMethodDef) = + let ftye,filmbody = fs + let ftye' = ftye (Some md) + let body' = morphILMethodBody (filmbody (Some md)) md.Body + md.With(genericParams=gparams_ty2ty ftye' md.GenericParams, + body= notlazy body', + parameters = List.map (param_ty2ty ftye') md.Parameters, + ret = return_ty2ty ftye' md.Return, + customAttrs=cattrs_ty2ty ftye' md.CustomAttrs) + +let fdefs_ty2ty f x = fdefs_fdef2fdef (fdef_ty2ty f) x + +let mdefs_ty2ty_ilmbody2ilmbody fs x = morphILMethodDefs (mdef_ty2ty_ilmbody2ilmbody fs) x + +let mimpl_ty2ty f e = + { Overrides = ospec_ty2ty f e.Overrides + OverrideBy = mspec_ty2ty (f,(fun _ -> f)) e.OverrideBy; } + +let edef_ty2ty f (e: ILEventDef) = + e.With(eventType = Option.map f e.EventType, + addMethod = mref_ty2ty f e.AddMethod, + removeMethod = mref_ty2ty f e.RemoveMethod, + fireMethod = Option.map (mref_ty2ty f) e.FireMethod, + otherMethods = List.map (mref_ty2ty f) e.OtherMethods, + customAttrs = cattrs_ty2ty f e.CustomAttrs) + +let pdef_ty2ty f (p: ILPropertyDef) = + p.With(setMethod = Option.map (mref_ty2ty f) p.SetMethod, + getMethod = Option.map (mref_ty2ty f) p.GetMethod, + propertyType = f p.PropertyType, + args = List.map f p.Args, + customAttrs = cattrs_ty2ty f p.CustomAttrs) + +let pdefs_ty2ty f (pdefs: ILPropertyDefs) = mkILProperties (List.map (pdef_ty2ty f) pdefs.AsList) +let edefs_ty2ty f (edefs: ILEventDefs) = mkILEvents (List.map (edef_ty2ty f) edefs.AsList) + +let mimpls_ty2ty f (mimpls : ILMethodImplDefs) = mkILMethodImpls (List.map (mimpl_ty2ty f) mimpls.AsList) + +let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs enc fs (td: ILTypeDef) = + let ftye,fmdefs = fs + let ftye' = ftye (Some (enc,td)) None + let mdefs' = fmdefs (enc,td) td.Methods + let fdefs' = fdefs_ty2ty ftye' td.Fields + td.With(implements= List.map ftye' td.Implements, + genericParams= gparams_ty2ty ftye' td.GenericParams, + extends = Option.map ftye' td.Extends, + methods=mdefs', + nestedTypes=tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs (enc@[td]) fs td.NestedTypes, + fields=fdefs', + methodImpls = mimpls_ty2ty ftye' td.MethodImpls, + events = edefs_ty2ty ftye' td.Events, + properties = pdefs_ty2ty ftye' td.Properties, + customAttrs = cattrs_ty2ty ftye' td.CustomAttrs) + +and tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs enc fs tdefs = + morphILTypeDefs (tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs enc fs) tdefs + +// -------------------------------------------------------------------- +// Derived versions of the above, e.g. with defaults added +// -------------------------------------------------------------------- + +let manifest_ty2ty f (m : ILAssemblyManifest) = + { m with CustomAttrsStored = storeILCustomAttrs (cattrs_ty2ty f m.CustomAttrs) } + +let morphILTypeInILModule_ilmbody2ilmbody_mdefs2mdefs (ftye: ILModuleDef -> (ILTypeDef list * ILTypeDef) option -> ILMethodDef option -> ILType -> ILType,fmdefs) m = + + let ftdefs = tdefs_ty2ty_ilmbody2ilmbody_mdefs2mdefs [] (ftye m,fmdefs m) + + { m with TypeDefs=ftdefs m.TypeDefs + CustomAttrsStored= storeILCustomAttrs (cattrs_ty2ty (ftye m None None) m.CustomAttrs) + Manifest=Option.map (manifest_ty2ty (ftye m None None)) m.Manifest } + +let module_instr2instr_ty2ty fs x = + let fcode,ftye = fs + let filmbody modCtxt tdefCtxt mdefCtxt = ilmbody_instr2instr_ty2ty (fcode modCtxt tdefCtxt mdefCtxt, ftye modCtxt (Some tdefCtxt) mdefCtxt) + let fmdefs modCtxt tdefCtxt = mdefs_ty2ty_ilmbody2ilmbody (ftye modCtxt (Some tdefCtxt), filmbody modCtxt tdefCtxt) + morphILTypeInILModule_ilmbody2ilmbody_mdefs2mdefs (ftye, fmdefs) x + +let morphILInstrsAndILTypesInILModule (f1,f2) x = + module_instr2instr_ty2ty (f1, f2) x + +let morphILInstrsInILCode f x = code_instr2instrs f x + +let morphILTypeInILModule ftye y = + let finstr modCtxt tdefCtxt mdefCtxt = + let fty = ftye modCtxt (Some tdefCtxt) mdefCtxt + morphILTypesInILInstr ((fun _instrCtxt -> fty), (fun _instrCtxt _formalCtxt -> fty)) + morphILInstrsAndILTypesInILModule (finstr,ftye) y + +let morphILTypeRefsInILModuleMemoized f modul = + let fty = Tables.memoize (ty_tref2tref f) + morphILTypeInILModule (fun _ _ _ ty -> fty ty) modul + +let morphILScopeRefsInILModuleMemoized f modul = + morphILTypeRefsInILModuleMemoized (morphILScopeRefsInILTypeRef f) modul diff --git a/src/absil/ilmorph.fsi b/src/fsharp/absil/ilmorph.fsi similarity index 79% rename from src/absil/ilmorph.fsi rename to src/fsharp/absil/ilmorph.fsi index 1b5fc1499d9..70cb7808f2e 100644 --- a/src/absil/ilmorph.fsi +++ b/src/fsharp/absil/ilmorph.fsi @@ -8,16 +8,15 @@ /// the ILMethodDef (if any) where the item occurs. etc. module internal FSharp.Compiler.AbstractIL.Morphs -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL /// Morph each scope reference inside a type signature. val morphILScopeRefsInILTypeRef: (ILScopeRef -> ILScopeRef) -> ILTypeRef -> ILTypeRef /// Morph all type references throughout an entire module. -val morphILTypeRefsInILModuleMemoized: ILGlobals -> (ILTypeRef -> ILTypeRef) -> ILModuleDef -> ILModuleDef +val morphILTypeRefsInILModuleMemoized: (ILTypeRef -> ILTypeRef) -> ILModuleDef -> ILModuleDef -val morphILScopeRefsInILModuleMemoized: ILGlobals -> (ILScopeRef -> ILScopeRef) -> ILModuleDef -> ILModuleDef +val morphILScopeRefsInILModuleMemoized: (ILScopeRef -> ILScopeRef) -> ILModuleDef -> ILModuleDef val morphILInstrsInILCode: (ILInstr -> ILInstr list) -> ILCode -> ILCode diff --git a/src/absil/ilnativeres.fs b/src/fsharp/absil/ilnativeres.fs similarity index 77% rename from src/absil/ilnativeres.fs rename to src/fsharp/absil/ilnativeres.fs index 7b54df1e6f6..e4af77d07cc 100644 --- a/src/absil/ilnativeres.fs +++ b/src/fsharp/absil/ilnativeres.fs @@ -3,12 +3,14 @@ // And https://github.com/dotnet/roslyn/blob/d36121da4b527ee0617e4b0940b9d0b17b584470/src/Compilers/Core/Portable/CvtRes.cs // And their dependencies (some classes) -module internal FSharp.Compiler.AbstractIL.Internal.NativeRes +module internal FSharp.Compiler.AbstractIL.NativeRes open System open System.Collections.Generic open System.Diagnostics open System.IO +open System.Globalization +open System.Runtime.InteropServices open System.Linq open System.Reflection.Metadata open System.Reflection.PortableExecutable @@ -17,10 +19,10 @@ open System.Text open Checked -type BYTE = System.Byte -type DWORD = System.UInt32 -type WCHAR = System.Char -type WORD = System.UInt16 +type BYTE = byte +type DWORD = uint32 +type WCHAR = Char +type WORD = uint16 let inline WORD s = uint16 s let inline DWORD s = uint32 s @@ -51,7 +53,7 @@ type CvtResFile () = static member ReadResFile (stream: Stream) = let mutable reader = new BinaryReader (stream, Encoding.Unicode) - let mutable resourceNames = new List() + let mutable resourceNames = List() // The stream might be empty, so let's check if not (reader.PeekChar () = -1) then @@ -76,8 +78,8 @@ type CvtResFile () = let mutable pAdditional = RESOURCE() pAdditional.HeaderSize <- cbHdr pAdditional.DataSize <- cbData - pAdditional.pstringType <- CvtResFile.ReadStringOrID (reader) - pAdditional.pstringName <- CvtResFile.ReadStringOrID (reader) + pAdditional.pstringType <- CvtResFile.ReadStringOrID reader + pAdditional.pstringName <- CvtResFile.ReadStringOrID reader stream.Position <- stream.Position + 3L &&& ~~~3L pAdditional.DataVersion <- reader.ReadUInt32 () pAdditional.MemoryFlags <- reader.ReadUInt16 () @@ -90,7 +92,7 @@ type CvtResFile () = if pAdditional.pstringType.theString = Unchecked.defaultof<_> && (pAdditional.pstringType.Ordinal = uint16 CvtResFile.RT_DLGINCLUDE) then () (* ERROR ContinueNotSupported *) else - resourceNames.Add (pAdditional) + resourceNames.Add pAdditional resourceNames static member private ReadStringOrID (fhIn: BinaryReader) = @@ -188,12 +190,12 @@ type StreamExtensions () = totalBytesRead type COFFResourceReader() = - static member private ConfirmSectionValues (hdr: SectionHeader, fileSize: System.Int64) = + static member private ConfirmSectionValues (hdr: SectionHeader, fileSize: int64) = if int64 hdr.PointerToRawData + int64 hdr.SizeOfRawData > fileSize then - raise <| ResourceException ("CoffResourceInvalidSectionSize") + raise <| ResourceException "CoffResourceInvalidSectionSize" static member ReadWin32ResourcesFromCOFF (stream: Stream) = - let mutable peHeaders = new PEHeaders (stream) + let mutable peHeaders = PEHeaders(stream) let mutable rsrc1 = SectionHeader () let mutable rsrc2 = SectionHeader () let mutable (foundCount: int) = 0 @@ -206,7 +208,7 @@ type COFFResourceReader() = rsrc2 <- sectionHeader foundCount <- foundCount + 1 if foundCount <> 2 then - raise <| ResourceException ("CoffResourceMissingSection") + raise <| ResourceException "CoffResourceMissingSection" COFFResourceReader.ConfirmSectionValues (rsrc1, stream.Length) COFFResourceReader.ConfirmSectionValues (rsrc2, stream.Length) let mutable imageResourceSectionBytes = Array.zeroCreate (rsrc1.SizeOfRawData + rsrc2.SizeOfRawData) @@ -218,7 +220,7 @@ type COFFResourceReader() = try let mutable relocLastAddress = rsrc1.PointerToRelocations + (int rsrc1.NumberOfRelocations * SizeOfRelocationEntry) if int64 relocLastAddress > stream.Length then - raise <| ResourceException ("CoffResourceInvalidRelocation") + raise <| ResourceException "CoffResourceInvalidRelocation" with :? OverflowException -> (raise <| ResourceException("CoffResourceInvalidRelocation")) let mutable relocationOffsets = Array.zeroCreate (int rsrc1.NumberOfRelocations) @@ -233,11 +235,11 @@ type COFFResourceReader() = reader.ReadUInt16 () |> ignore //we do nothing with the "Type" i <- i + 1 stream.Position <- int64 peHeaders.CoffHeader.PointerToSymbolTable - let mutable (ImageSizeOfSymbol: System.UInt32) = 18u + let mutable (ImageSizeOfSymbol: uint32) = 18u try let mutable lastSymAddress = int64 peHeaders.CoffHeader.PointerToSymbolTable + int64 peHeaders.CoffHeader.NumberOfSymbols * int64 ImageSizeOfSymbol (* ERROR UnknownNode *) if lastSymAddress > stream.Length then - raise <| ResourceException ("CoffResourceInvalidSymbol") + raise <| ResourceException "CoffResourceInvalidSymbol" with :? OverflowException -> (raise <| ResourceException("CoffResourceInvalidSymbol")) let mutable outputStream = new MemoryStream (imageResourceSectionBytes) @@ -246,14 +248,14 @@ type COFFResourceReader() = let mutable (i: int) = 0 while (i < relocationSymbolIndices.Length) do if int relocationSymbolIndices.[i] > peHeaders.CoffHeader.NumberOfSymbols then - raise <| ResourceException ("CoffResourceInvalidRelocation") + raise <| ResourceException "CoffResourceInvalidRelocation" let mutable offsetOfSymbol = int64 peHeaders.CoffHeader.PointerToSymbolTable + int64 relocationSymbolIndices.[i] * int64 ImageSizeOfSymbol stream.Position <- offsetOfSymbol stream.Position <- stream.Position + 8L let mutable symValue = reader.ReadUInt32 () let mutable symSection = reader.ReadInt16 () let mutable symType = reader.ReadUInt16 () - let mutable (IMAGE_SYM_TYPE_NULL: System.UInt16) = uint16 0x0000 + let mutable (IMAGE_SYM_TYPE_NULL: uint16) = uint16 0x0000 if symType <> IMAGE_SYM_TYPE_NULL || symSection <> 3s then raise <| ResourceException("CoffResourceInvalidSymbol") outputStream.Position <- int64 relocationOffsets.[i] @@ -277,33 +279,38 @@ type VersionHelper() = /// /// Parses a version string of the form "major [ '.' minor [ '.' build [ '.' revision ] ] ]". /// + /// /// The version string to parse. /// If parsing succeeds, the parsed version. Otherwise a version that represents as much of the input as could be parsed successfully. + /// /// True when parsing succeeds completely (i.e. every character in the string was consumed), false otherwise. - static member TryParse(s: string, [] version: byref) = + static member TryParse(s: string, [] version: byref) = VersionHelper.TryParse (s, false, UInt16.MaxValue, true, ref version) /// /// Parses a version string of the form "major [ '.' minor [ '.' ( '*' | ( build [ '.' ( '*' | revision ) ] ) ) ] ]" /// as accepted by System.Reflection.AssemblyVersionAttribute. /// + /// /// The version string to parse. /// Indicates whether or not a wildcard is accepted as the terminal component. /// /// If parsing succeeded, the parsed version. Otherwise a version instance with all parts set to zero. /// If contains * the version build and/or revision numbers are set to . /// + /// /// True when parsing succeeds completely (i.e. every character in the string was consumed), false otherwise. - static member TryParseAssemblyVersion (s: string, allowWildcard: System.Boolean, [] version: byref) = + static member TryParseAssemblyVersion (s: string, allowWildcard: bool, [] version: byref) = VersionHelper.TryParse (s, allowWildcard, (UInt16.MaxValue - 1us), false, ref version) - static member private NullVersion = new Version (0, 0, 0, 0) + static member private NullVersion = Version(0, 0, 0, 0) /// /// Parses a version string of the form "major [ '.' minor [ '.' ( '*' | ( build [ '.' ( '*' | revision ) ] ) ) ] ]" /// as accepted by System.Reflection.AssemblyVersionAttribute. /// + /// /// The version string to parse. /// Indicates whether or not we're parsing an assembly version string. If so, wildcards are accepted and each component must be less than 65535. /// The maximum value that a version component may have. @@ -312,15 +319,16 @@ type VersionHelper() = /// If parsing succeeded, the parsed version. When is true a version with values up to the first invalid character set. Otherwise a version with all parts set to zero. /// If contains * and wildcard is allowed the version build and/or revision numbers are set to . /// + /// /// True when parsing succeeds completely (i.e. every character in the string was consumed), false otherwise. - static member private TryParse(s: string, allowWildcard: System.Boolean, maxValue: System.UInt16, allowPartialParse: System.Boolean, [] version: byref) = + static member private TryParse(s: string, allowWildcard: bool, maxValue: uint16, allowPartialParse: bool, [] version: byref) = Debug.Assert (not allowWildcard || maxValue < UInt16.MaxValue) - if String.IsNullOrWhiteSpace (s) then + if String.IsNullOrWhiteSpace s then version <- VersionHelper.NullVersion false else - let mutable (elements: string[]) = s.Split ('.') - let mutable (hasWildcard: System.Boolean) = allowWildcard && elements.[(int (elements.Length - 1))] = "*" + let mutable (elements: string[]) = s.Split '.' + let mutable (hasWildcard: bool) = allowWildcard && elements.[(int (elements.Length - 1))] = "*" if hasWildcard && elements.Length < 3 || elements.Length > 4 then version <- VersionHelper.NullVersion false @@ -330,20 +338,20 @@ type VersionHelper() = if hasWildcard then elements.Length - 1 else elements.Length - let mutable (parseError: System.Boolean) = false + let mutable (parseError: bool) = false let mutable earlyReturn = None do let mutable (i: int) = 0 let mutable breakLoop = false while (i < lastExplicitValue) && not breakLoop do - if not (UInt16.TryParse (elements.[i], System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, ref values.[i])) || values.[i] > maxValue then + if not (UInt16.TryParse (elements.[i], NumberStyles.None, CultureInfo.InvariantCulture, ref values.[i])) || values.[i] > maxValue then if not allowPartialParse then earlyReturn <- Some false breakLoop <- true version <- VersionHelper.NullVersion else parseError <- true - if String.IsNullOrWhiteSpace (elements.[i]) then + if String.IsNullOrWhiteSpace elements.[i] then values.[i] <- 0us breakLoop <- true else @@ -351,13 +359,13 @@ type VersionHelper() = values.[i] <- 0us breakLoop <- true else - let mutable (invalidFormat: System.Boolean) = false - //let mutable (number: System.Numerics.BigInteger) = 0I + let mutable (invalidFormat: bool) = false + //let mutable (number: bigint) = 0I do let mutable idx = 0 let mutable breakLoop = false while (idx < elements.[i].Length) && not breakLoop do - if not (Char.IsDigit (elements.[i].[idx])) then + if not (Char.IsDigit elements.[i].[idx]) then invalidFormat <- true VersionHelper.TryGetValue ((elements.[i].Substring (0, idx)), ref values.[i]) |> ignore breakLoop <- true @@ -378,12 +386,12 @@ type VersionHelper() = while (i < values.Length) do values.[i] <- UInt16.MaxValue i <- i + 1 - version <- new Version(int values.[0], int values.[1], int values.[2], int values.[3]) + version <- Version(int values.[0], int values.[1], int values.[2], int values.[3]) not parseError - static member private TryGetValue(s: string, [] value: byref): bool = - let mutable (number: System.Numerics.BigInteger) = Unchecked.defaultof - if System.Numerics.BigInteger.TryParse (s, System.Globalization.NumberStyles.None, System.Globalization.CultureInfo.InvariantCulture, ref number) then + static member private TryGetValue(s: string, [] value: byref): bool = + let mutable (number: bigint) = Unchecked.defaultof + if bigint.TryParse (s, NumberStyles.None, CultureInfo.InvariantCulture, ref number) then value <- uint16 (number % bigint 65536) true else @@ -403,11 +411,11 @@ type VersionHelper() = let mutable (revision: int) = int time.TimeOfDay.TotalSeconds / 2 Debug.Assert (revision < int UInt16.MaxValue) if pattern.Build = int UInt16.MaxValue then - let mutable (days: TimeSpan) = time.Date - new DateTime(2000, 1, 1) + let mutable (days: TimeSpan) = time.Date - DateTime(2000, 1, 1) let mutable (build: int) = Math.Min (int UInt16.MaxValue, (int days.TotalDays)) - new Version(pattern.Major, pattern.Minor, int (uint16 build), int (uint16 revision)) + Version(pattern.Major, pattern.Minor, int (uint16 build), int (uint16 revision)) else - new Version(pattern.Major, pattern.Minor, pattern.Build, int (uint16 revision)) + Version(pattern.Major, pattern.Minor, pattern.Build, int (uint16 revision)) type VersionResourceSerializer () = member val private _commentsContents = Unchecked.defaultof with get, set @@ -430,10 +438,22 @@ type VersionResourceSerializer () = static member val private CP_WINUNICODE = 1200u static member val private sizeVS_FIXEDFILEINFO = uint16 (sizeof * 13) - member val private _isDll = Unchecked.defaultof with get, set - - new(isDll: System.Boolean, comments: string, companyName: string, fileDescription: string, fileVersion: string, internalName: string, legalCopyright: string, legalTrademark: string, originalFileName: string, productName: string, productVersion: string, assemblyVersion: Version) as this = - (VersionResourceSerializer ()) + member val private _isDll = Unchecked.defaultof with get, set + + new(isDll: bool, + comments: string, + companyName: string, + fileDescription: string, + fileVersion: string, + internalName: string, + legalCopyright: string, + legalTrademark: string, + originalFileName: string, + productName: string, + productVersion: string, + assemblyVersion: Version) as this = + + VersionResourceSerializer () then this._isDll <- isDll this._commentsContents <- comments @@ -447,7 +467,7 @@ type VersionResourceSerializer () = this._productNameContents <- productName this._productVersionContents <- productVersion this._assemblyVersionContents <- assemblyVersion - this._langIdAndCodePageKey <- System.String.Format ("{0:x4}{1:x4}", 0, VersionResourceSerializer.CP_WINUNICODE) + this._langIdAndCodePageKey <- String.Format ("{0:x4}{1:x4}", 0, VersionResourceSerializer.CP_WINUNICODE) static member val private VFT_APP = 0x00000001u static member val private VFT_DLL = 0x00000002u @@ -486,19 +506,19 @@ type VersionResourceSerializer () = VersionHelper.TryParse (this._fileVersionContents, ref fileVersion) |> ignore let mutable (productVersion: Version) = Unchecked.defaultof VersionHelper.TryParse (this._productVersionContents, ref productVersion) |> ignore - writer.Write (0xFEEF04BDu) - writer.Write (0x00010000u) + writer.Write 0xFEEF04BDu + writer.Write 0x00010000u writer.Write ((uint32 fileVersion.Major <<< 16) ||| uint32 fileVersion.Minor) writer.Write ((uint32 fileVersion.Build <<< 16) ||| uint32 fileVersion.Revision) writer.Write ((uint32 productVersion.Major <<< 16) ||| uint32 productVersion.Minor) writer.Write ((uint32 productVersion.Build <<< 16) ||| uint32 productVersion.Revision) - writer.Write (0x0000003Fu) - writer.Write (0u) - writer.Write (0x00000004u) - writer.Write (this.FileType) - writer.Write (0u) - writer.Write (0u) - writer.Write (0u) + writer.Write 0x0000003Fu + writer.Write 0u + writer.Write 0x00000004u + writer.Write this.FileType + writer.Write 0u + writer.Write 0u + writer.Write 0u static member private PadKeyLen(cb: int) = VersionResourceSerializer.PadToDword (cb + 3 * sizeof) - 3 * sizeof @@ -517,17 +537,17 @@ type VersionResourceSerializer () = static member private WriteVersionString(keyValuePair: KeyValuePair, writer: BinaryWriter) = Debug.Assert (keyValuePair.Value <> Unchecked.defaultof<_>) - let mutable (cbBlock: System.UInt16) = uint16 <| VersionResourceSerializer.SizeofVerString (keyValuePair.Key, keyValuePair.Value) + let mutable (cbBlock: uint16) = uint16 <| VersionResourceSerializer.SizeofVerString (keyValuePair.Key, keyValuePair.Value) let mutable (cbKey: int) = keyValuePair.Key.Length + 1 * 2 //let mutable (cbVal: int) = keyValuePair.Value.Length + 1 * 2 let mutable startPos = writer.BaseStream.Position Debug.Assert (startPos &&& 3L = 0L) - writer.Write (cbBlock) + writer.Write cbBlock writer.Write (uint16 (keyValuePair.Value.Length + 1)) - writer.Write (1us) + writer.Write 1us writer.Write (keyValuePair.Key.ToCharArray ()) writer.Write (uint16 0) //(WORD)'\0' - writer.Write (Array.zeroCreate (VersionResourceSerializer.PadKeyLen (cbKey) - cbKey): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.PadKeyLen cbKey - cbKey): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) writer.Write (keyValuePair.Value.ToCharArray ()) writer.Write (uint16 0) // (WORD)'\0' @@ -537,7 +557,7 @@ type VersionResourceSerializer () = VersionResourceSerializer.PadKeyLen (sz.Length + 1 * sizeof) / sizeof static member private KEYBYTES(sz: string) = - VersionResourceSerializer.KEYSIZE (sz) * sizeof + VersionResourceSerializer.KEYSIZE sz * sizeof member private this.GetStringsSize() = let mutable (sum: int) = 0 @@ -549,11 +569,11 @@ type VersionResourceSerializer () = member this.GetDataSize () = let mutable (sizeEXEVERRESOURCE: int) = sizeof * 3 * 5 + 2 * sizeof + - VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.vsVersionInfoKey) + - VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.varFileInfoKey) + - VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.translationKey) + - VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.stringFileInfoKey) + - VersionResourceSerializer.KEYBYTES (this._langIdAndCodePageKey) + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.vsVersionInfoKey + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.varFileInfoKey + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.translationKey + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.stringFileInfoKey + + VersionResourceSerializer.KEYBYTES this._langIdAndCodePageKey + int VersionResourceSerializer.sizeVS_FIXEDFILEINFO this.GetStringsSize () + sizeEXEVERRESOURCE @@ -564,35 +584,40 @@ type VersionResourceSerializer () = writer.Write (WORD VersionResourceSerializer.sizeVS_FIXEDFILEINFO) writer.Write (WORD 0us) writer.Write (VersionResourceSerializer.vsVersionInfoKey.ToCharArray ()) - writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.vsVersionInfoKey) - VersionResourceSerializer.vsVersionInfoKey.Length * 2): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES VersionResourceSerializer.vsVersionInfoKey - VersionResourceSerializer.vsVersionInfoKey.Length * 2): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) - this.WriteVSFixedFileInfo (writer) - writer.Write (WORD (sizeof * 2 + 2 * VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.varFileInfoKey) + VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.translationKey))) + this.WriteVSFixedFileInfo writer + writer.Write (WORD (sizeof * 2 + + 2 * VersionResourceSerializer.HDRSIZE + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.varFileInfoKey + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.translationKey)) writer.Write (WORD 0us) writer.Write (WORD 1us) writer.Write (VersionResourceSerializer.varFileInfoKey.ToCharArray ()) - writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.varFileInfoKey) - VersionResourceSerializer.varFileInfoKey.Length * 2): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES VersionResourceSerializer.varFileInfoKey - VersionResourceSerializer.varFileInfoKey.Length * 2): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) - writer.Write (WORD (sizeof * 2 + VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.translationKey))) + writer.Write (WORD (sizeof * 2 + VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.translationKey)) writer.Write (WORD (sizeof * 2)) writer.Write (WORD 0us) writer.Write (VersionResourceSerializer.translationKey.ToCharArray ()) - writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.translationKey) - VersionResourceSerializer.translationKey.Length * 2): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES VersionResourceSerializer.translationKey - VersionResourceSerializer.translationKey.Length * 2): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) - writer.Write (0us) + writer.Write 0us writer.Write (WORD VersionResourceSerializer.CP_WINUNICODE) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) - writer.Write (WORD (2 * VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.stringFileInfoKey) + VersionResourceSerializer.KEYBYTES (this._langIdAndCodePageKey) + this.GetStringsSize ())) - writer.Write (0us) - writer.Write (1us) + writer.Write (WORD (2 * VersionResourceSerializer.HDRSIZE + + VersionResourceSerializer.KEYBYTES VersionResourceSerializer.stringFileInfoKey + + VersionResourceSerializer.KEYBYTES this._langIdAndCodePageKey + this.GetStringsSize ())) + writer.Write 0us + writer.Write 1us writer.Write (VersionResourceSerializer.stringFileInfoKey.ToCharArray ()) - writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES (VersionResourceSerializer.stringFileInfoKey) - VersionResourceSerializer.stringFileInfoKey.Length * 2): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES VersionResourceSerializer.stringFileInfoKey - VersionResourceSerializer.stringFileInfoKey.Length * 2): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) - writer.Write (WORD (VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES (this._langIdAndCodePageKey) + this.GetStringsSize ())) - writer.Write (0us) - writer.Write (1us) + writer.Write (WORD (VersionResourceSerializer.HDRSIZE + VersionResourceSerializer.KEYBYTES this._langIdAndCodePageKey + this.GetStringsSize ())) + writer.Write 0us + writer.Write 1us writer.Write (this._langIdAndCodePageKey.ToCharArray ()) - writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES (this._langIdAndCodePageKey) - this._langIdAndCodePageKey.Length * 2): byte[]) + writer.Write (Array.zeroCreate (VersionResourceSerializer.KEYBYTES this._langIdAndCodePageKey - this._langIdAndCodePageKey.Length * 2): byte[]) Debug.Assert (writer.BaseStream.Position &&& 3L = 0L) Debug.Assert (writer.BaseStream.Position - debugPos = int64 dataSize - int64 (this.GetStringsSize ())) debugPos <- writer.BaseStream.Position @@ -617,7 +642,7 @@ type Win32ResourceConversions () = raise <| ResourceException("IconStreamUnexpectedFormat") let mutable iconDirEntries: ICONDIRENTRY [] = Array.zeroCreate (int count) do - let mutable (i: System.UInt16) = 0us + let mutable (i: uint16) = 0us while (i < count) do iconDirEntries.[(int i)].bWidth <- iconReader.ReadByte () iconDirEntries.[(int i)].bHeight <- iconReader.ReadByte () @@ -629,7 +654,7 @@ type Win32ResourceConversions () = iconDirEntries.[(int i)].dwImageOffset <- iconReader.ReadUInt32 () i <- i + 1us do - let mutable (i: System.UInt16) = 0us + let mutable (i: uint16) = 0us while (i < count) do iconStream.Position <- int64 iconDirEntries.[(int i)].dwImageOffset if iconReader.ReadUInt32 () = 40u then @@ -641,55 +666,67 @@ type Win32ResourceConversions () = let mutable resWriter = new BinaryWriter(resStream) let mutable (RT_ICON: WORD) = 3us do - let mutable (i: System.UInt16) = 0us + let mutable (i: uint16) = 0us while (i < count) do resStream.Position <- resStream.Position + 3L &&& ~~~3L - resWriter.Write (iconDirEntries.[(int i)].dwBytesInRes) - resWriter.Write (0x00000020u) - resWriter.Write (0xFFFFus) - resWriter.Write (RT_ICON) - resWriter.Write (0xFFFFus) - resWriter.Write ((i + 1us)) - resWriter.Write (0x00000000u) - resWriter.Write (0x1010us) - resWriter.Write (0x0000us) - resWriter.Write (0x00000000u) - resWriter.Write (0x00000000u) + resWriter.Write iconDirEntries.[(int i)].dwBytesInRes + resWriter.Write 0x00000020u + resWriter.Write 0xFFFFus + resWriter.Write RT_ICON + resWriter.Write 0xFFFFus + resWriter.Write (i + 1us) + resWriter.Write 0x00000000u + resWriter.Write 0x1010us + resWriter.Write 0x0000us + resWriter.Write 0x00000000u + resWriter.Write 0x00000000u iconStream.Position <- int64 iconDirEntries.[(int i)].dwImageOffset - resWriter.Write (iconReader.ReadBytes (int (iconDirEntries.[int i].dwBytesInRes))) + resWriter.Write (iconReader.ReadBytes (int iconDirEntries.[int i].dwBytesInRes)) i <- i + 1us let mutable (RT_GROUP_ICON: WORD) = (RT_ICON + 11us) resStream.Position <- resStream.Position + 3L &&& ~~~3L resWriter.Write (uint32 (3 * sizeof + int count * 14)) - resWriter.Write (0x00000020u) - resWriter.Write (0xFFFFus) - resWriter.Write (RT_GROUP_ICON) - resWriter.Write (0xFFFFus) - resWriter.Write (0x7F00us) - resWriter.Write (0x00000000u) - resWriter.Write (0x1030us) - resWriter.Write (0x0000us) - resWriter.Write (0x00000000u) - resWriter.Write (0x00000000u) - resWriter.Write (0x0000us) - resWriter.Write (0x0001us) - resWriter.Write (count) + resWriter.Write 0x00000020u + resWriter.Write 0xFFFFus + resWriter.Write RT_GROUP_ICON + resWriter.Write 0xFFFFus + resWriter.Write 0x7F00us + resWriter.Write 0x00000000u + resWriter.Write 0x1030us + resWriter.Write 0x0000us + resWriter.Write 0x00000000u + resWriter.Write 0x00000000u + resWriter.Write 0x0000us + resWriter.Write 0x0001us + resWriter.Write count do - let mutable (i: System.UInt16) = 0us + let mutable (i: uint16) = 0us while (i < count) do - resWriter.Write (iconDirEntries.[(int i)].bWidth) - resWriter.Write (iconDirEntries.[(int i)].bHeight) - resWriter.Write (iconDirEntries.[(int i)].bColorCount) - resWriter.Write (iconDirEntries.[(int i)].bReserved) - resWriter.Write (iconDirEntries.[(int i)].wPlanes) - resWriter.Write (iconDirEntries.[(int i)].wBitCount) - resWriter.Write (iconDirEntries.[(int i)].dwBytesInRes) - resWriter.Write ((i + 1us)) + resWriter.Write iconDirEntries.[(int i)].bWidth + resWriter.Write iconDirEntries.[(int i)].bHeight + resWriter.Write iconDirEntries.[(int i)].bColorCount + resWriter.Write iconDirEntries.[(int i)].bReserved + resWriter.Write iconDirEntries.[(int i)].wPlanes + resWriter.Write iconDirEntries.[(int i)].wBitCount + resWriter.Write iconDirEntries.[(int i)].dwBytesInRes + resWriter.Write (i + 1us) i <- i + 1us () - static member AppendVersionToResourceStream (resStream: Stream, isDll: System.Boolean, fileVersion: string, originalFileName: string, internalName: string, productVersion: string, assemblyVersion: Version, ?fileDescription: string, ?legalCopyright: string, ?legalTrademarks: string, ?productName: string, ?comments: string, ?companyName: string) = + static member AppendVersionToResourceStream (resStream: Stream, + isDll: bool, + fileVersion: string, + originalFileName: string, + internalName: string, + productVersion: string, + assemblyVersion: Version, + ?fileDescription: string, + ?legalCopyright: string, + ?legalTrademarks: string, + ?productName: string, + ?comments: string, + ?companyName: string) = let fileDescription = (defaultArg fileDescription) " " let legalCopyright = (defaultArg legalCopyright) " " let legalTrademarks = (defaultArg legalTrademarks) Unchecked.defaultof<_> @@ -699,40 +736,44 @@ type Win32ResourceConversions () = let mutable resWriter = new BinaryWriter(resStream, Encoding.Unicode) resStream.Position <- resStream.Position + 3L &&& ~~~3L let mutable (RT_VERSION: DWORD) = 16u - let mutable ver = new VersionResourceSerializer(isDll, comments, companyName, fileDescription, fileVersion, internalName, legalCopyright, legalTrademarks, originalFileName, productName, productVersion, assemblyVersion) + let mutable ver = + VersionResourceSerializer(isDll, comments, companyName, + fileDescription, fileVersion, internalName, legalCopyright, + legalTrademarks, originalFileName, productName, productVersion, + assemblyVersion) let mutable startPos = resStream.Position let mutable dataSize = ver.GetDataSize () let mutable (headerSize: int) = 0x20 resWriter.Write (uint32 dataSize) resWriter.Write (uint32 headerSize) - resWriter.Write (0xFFFFus) + resWriter.Write 0xFFFFus resWriter.Write (uint16 RT_VERSION) - resWriter.Write (0xFFFFus) - resWriter.Write (0x0001us) - resWriter.Write (0x00000000u) - resWriter.Write (0x0030us) - resWriter.Write (0x0000us) - resWriter.Write (0x00000000u) - resWriter.Write (0x00000000u) - ver.WriteVerResource (resWriter) + resWriter.Write 0xFFFFus + resWriter.Write 0x0001us + resWriter.Write 0x00000000u + resWriter.Write 0x0030us + resWriter.Write 0x0000us + resWriter.Write 0x00000000u + resWriter.Write 0x00000000u + ver.WriteVerResource resWriter Debug.Assert (resStream.Position - startPos = int64 dataSize + int64 headerSize) - static member AppendManifestToResourceStream(resStream: Stream, manifestStream: Stream, isDll: System.Boolean) = + static member AppendManifestToResourceStream(resStream: Stream, manifestStream: Stream, isDll: bool) = resStream.Position <- resStream.Position + 3L &&& ~~~3L (* ERROR UnknownPrefixOperator "~" *) let mutable (RT_MANIFEST: WORD) = 24us let mutable resWriter = new BinaryWriter(resStream) resWriter.Write (uint32 manifestStream.Length) - resWriter.Write (0x00000020u) - resWriter.Write (0xFFFFus) - resWriter.Write (RT_MANIFEST) - resWriter.Write (0xFFFFus) + resWriter.Write 0x00000020u + resWriter.Write 0xFFFFus + resWriter.Write RT_MANIFEST + resWriter.Write 0xFFFFus resWriter.Write (if isDll then 0x0002us else 0x0001us) - resWriter.Write (0x00000000u) - resWriter.Write (0x1030us) - resWriter.Write (0x0000us) - resWriter.Write (0x00000000u) - resWriter.Write (0x00000000u) - manifestStream.CopyTo (resStream) + resWriter.Write 0x00000000u + resWriter.Write 0x1030us + resWriter.Write 0x0000us + resWriter.Write 0x00000000u + resWriter.Write 0x00000000u + manifestStream.CopyTo resStream type Win32Resource (data: byte[], codePage: DWORD, languageId: DWORD, id: int, name: string, typeId: int, typeName: string) = @@ -747,9 +788,9 @@ type Win32Resource (data: byte[], codePage: DWORD, languageId: DWORD, id: int, n type Directory (name, id) = member val Name = name member val ID = id - member val NumberOfNamedEntries = Unchecked.defaultof with get, set - member val NumberOfIdEntries = Unchecked.defaultof with get, set - member val Entries = new List() + member val NumberOfNamedEntries = Unchecked.defaultof with get, set + member val NumberOfIdEntries = Unchecked.defaultof with get, set + member val Entries = List() type NativeResourceWriter () = static member private CompareResources (left: Win32Resource) (right: Win32Resource) = @@ -774,17 +815,17 @@ type NativeResourceWriter () = resources.OrderBy ((fun d -> d), Comparer<_>.Create(Comparison<_> NativeResourceWriter.CompareResources)) :> IEnumerable static member SerializeWin32Resources (builder: BlobBuilder, theResources: IEnumerable, resourcesRva: int) = - let theResources = NativeResourceWriter.SortResources (theResources) - let mutable (typeDirectory: Directory) = new Directory(String.Empty, 0) + let theResources = NativeResourceWriter.SortResources theResources + let mutable (typeDirectory: Directory) = Directory(String.Empty, 0) let mutable (nameDirectory: Directory) = Unchecked.defaultof<_> let mutable (languageDirectory: Directory) = Unchecked.defaultof<_> let mutable (lastTypeID: int) = Int32.MinValue let mutable (lastTypeName: string) = Unchecked.defaultof<_> let mutable (lastID: int) = Int32.MinValue let mutable (lastName: string) = Unchecked.defaultof<_> - let mutable (sizeOfDirectoryTree: System.UInt32) = 16u - for (r: Win32Resource) in theResources do - let mutable (typeDifferent: System.Boolean) = r.TypeId < 0 && r.TypeName <> lastTypeName || r.TypeId > lastTypeID + let mutable (sizeOfDirectoryTree: uint32) = 16u + for r: Win32Resource in theResources do + let mutable (typeDifferent: bool) = r.TypeId < 0 && r.TypeName <> lastTypeName || r.TypeId > lastTypeID if typeDifferent then lastTypeID <- r.TypeId lastTypeName <- r.TypeName @@ -794,8 +835,8 @@ type NativeResourceWriter () = else typeDirectory.NumberOfIdEntries <- typeDirectory.NumberOfIdEntries + 1us sizeOfDirectoryTree <- sizeOfDirectoryTree + 24u - nameDirectory <- new Directory(lastTypeName, lastTypeID) - typeDirectory.Entries.Add (nameDirectory) + nameDirectory <- Directory(lastTypeName, lastTypeID) + typeDirectory.Entries.Add nameDirectory if typeDifferent || r.Id < 0 && r.Name <> lastName || r.Id > lastID then lastID <- r.Id lastName <- r.Name @@ -805,38 +846,40 @@ type NativeResourceWriter () = else nameDirectory.NumberOfIdEntries <- nameDirectory.NumberOfIdEntries + 1us sizeOfDirectoryTree <- sizeOfDirectoryTree + 24u - languageDirectory <- new Directory (lastName, lastID) - nameDirectory.Entries.Add (languageDirectory) + languageDirectory <- Directory(lastName, lastID) + nameDirectory.Entries.Add languageDirectory languageDirectory.NumberOfIdEntries <- languageDirectory.NumberOfIdEntries + 1us sizeOfDirectoryTree <- sizeOfDirectoryTree + 8u - languageDirectory.Entries.Add (r) - let mutable dataWriter = new BlobBuilder() - NativeResourceWriter.WriteDirectory (typeDirectory, builder, (0u), (0u), sizeOfDirectoryTree, resourcesRva, dataWriter) - builder.LinkSuffix (dataWriter) - builder.WriteByte (0uy) - builder.Align (4) - - static member private WriteDirectory (directory: Directory, writer: BlobBuilder, offset: System.UInt32, level: System.UInt32, sizeOfDirectoryTree: System.UInt32, virtualAddressBase: int, dataWriter: BlobBuilder) = - writer.WriteUInt32 (0u) - writer.WriteUInt32 (0u) - writer.WriteUInt32 (0u) - writer.WriteUInt16 (directory.NumberOfNamedEntries) - writer.WriteUInt16 (directory.NumberOfIdEntries) - let mutable (n: System.UInt32) = uint32 directory.Entries.Count - let mutable (k: System.UInt32) = offset + 16u + n * 8u + languageDirectory.Entries.Add r + let mutable dataWriter = BlobBuilder() + NativeResourceWriter.WriteDirectory (typeDirectory, builder, 0u, 0u, sizeOfDirectoryTree, resourcesRva, dataWriter) + builder.LinkSuffix dataWriter + builder.WriteByte 0uy + builder.Align 4 + + static member private WriteDirectory (directory: Directory, writer: BlobBuilder, offset: uint32, + level: uint32, sizeOfDirectoryTree: uint32, + virtualAddressBase: int, dataWriter: BlobBuilder) = + writer.WriteUInt32 0u + writer.WriteUInt32 0u + writer.WriteUInt32 0u + writer.WriteUInt16 directory.NumberOfNamedEntries + writer.WriteUInt16 directory.NumberOfIdEntries + let mutable (n: uint32) = uint32 directory.Entries.Count + let mutable (k: uint32) = offset + 16u + n * 8u do let mutable (i: uint32) = 0u while (i < n) do let mutable (id: int) = Unchecked.defaultof let mutable (name: string) = Unchecked.defaultof - let mutable (nameOffset: System.UInt32) = uint32 dataWriter.Count + sizeOfDirectoryTree - let mutable (directoryOffset: System.UInt32) = k + let mutable (nameOffset: uint32) = uint32 dataWriter.Count + sizeOfDirectoryTree + let mutable (directoryOffset: uint32) = k let isDir = match directory.Entries.[int i] with | :? Directory as subDir -> id <- subDir.ID name <- subDir.Name - if level = 0u then k <- k + NativeResourceWriter.SizeOfDirectory (subDir) + if level = 0u then k <- k + NativeResourceWriter.SizeOfDirectory subDir else k <- k + 16u + 8u * uint32 subDir.Entries.Count true | :? Win32Resource as r -> @@ -856,25 +899,25 @@ type NativeResourceWriter () = r.Name else Unchecked.defaultof<_> - dataWriter.WriteUInt32 ((uint32 virtualAddressBase + sizeOfDirectoryTree + 16u + uint32 dataWriter.Count)) - let mutable (data: byte[]) = (new List (r.Data)).ToArray () + dataWriter.WriteUInt32 (uint32 virtualAddressBase + sizeOfDirectoryTree + 16u + uint32 dataWriter.Count) + let mutable (data: byte[]) = (List(r.Data)).ToArray () dataWriter.WriteUInt32 (uint32 data.Length) - dataWriter.WriteUInt32 (r.CodePage) - dataWriter.WriteUInt32 (0u) - dataWriter.WriteBytes (data) + dataWriter.WriteUInt32 r.CodePage + dataWriter.WriteUInt32 0u + dataWriter.WriteBytes data while (dataWriter.Count % 4 <> 0) do - dataWriter.WriteByte (0uy) + dataWriter.WriteByte 0uy false | e -> failwithf "Unknown entry %s" (if isNull e then "" else e.GetType().FullName) - if id >= 0 then writer.WriteInt32 (id) + if id >= 0 then writer.WriteInt32 id else if name = Unchecked.defaultof<_> then name <- String.Empty writer.WriteUInt32 (nameOffset ||| 0x80000000u) dataWriter.WriteUInt16 (uint16 name.Length) - dataWriter.WriteUTF16 (name) + dataWriter.WriteUTF16 name if isDir then writer.WriteUInt32 (directoryOffset ||| 0x80000000u) - else writer.WriteUInt32 (nameOffset) + else writer.WriteUInt32 nameOffset i <- i + 1u k <- offset + 16u + n * 8u @@ -885,7 +928,7 @@ type NativeResourceWriter () = | :? Directory as subDir -> NativeResourceWriter.WriteDirectory (subDir, writer, k, (level + 1u), sizeOfDirectoryTree, virtualAddressBase, dataWriter) if level = 0u then - k <- k + NativeResourceWriter.SizeOfDirectory (subDir) + k <- k + NativeResourceWriter.SizeOfDirectory subDir else k <- k + 16u + 8u * uint32 subDir.Entries.Count | _ -> () @@ -893,8 +936,8 @@ type NativeResourceWriter () = () static member private SizeOfDirectory (directory: Directory) = - let mutable (n: System.UInt32) = uint32 directory.Entries.Count - let mutable (size: System.UInt32) = 16u + 8u * n + let mutable (n: uint32) = uint32 directory.Entries.Count + let mutable (size: uint32) = 16u + 8u * n do let mutable (i: int) = 0 while (uint32 i < n) do @@ -914,5 +957,5 @@ type NativeResourceWriter () = for (addressToFixup: int) in resourceSections.Relocations do sectionWriter.Offset <- addressToFixup reader.BaseStream.Position <- addressToFixup - sectionWriter.WriteUInt32 (reader.ReadUInt32 () + resourcesRva :> System.UInt32) + sectionWriter.WriteUInt32 (reader.ReadUInt32 () + resourcesRva :> uint32) ()*) \ No newline at end of file diff --git a/src/fsharp/absil/ilnativeres.fsi b/src/fsharp/absil/ilnativeres.fsi new file mode 100644 index 00000000000..d44851521ca --- /dev/null +++ b/src/fsharp/absil/ilnativeres.fsi @@ -0,0 +1,60 @@ + +module internal FSharp.Compiler.AbstractIL.NativeRes + +open System +open System.Collections.Generic +open System.IO +open System.Reflection.Metadata + +type BYTE = Byte +type DWORD = UInt32 +type WCHAR = Char +type WORD = UInt16 + +[] +type RESOURCE_STRING = + member Ordinal: WORD with get, set + member theString : string with get, set + +[] +type RESOURCE = + member pstringType : RESOURCE_STRING with get, set + member pstringName : RESOURCE_STRING with get, set + member DataSize : DWORD with get, set + member HeaderSize : DWORD with get, set + member DataVersion : DWORD with get, set + member MemoryFlags : WORD with get, set + member LanguageId : WORD with get, set + member Version : DWORD with get, set + member Characteristics : DWORD with get, set + member data : byte[] with get, set + +type Win32Resource = + new : data:byte [] * codePage: DWORD * languageId: DWORD * id: int * + name: string * typeId:int * typeName : string -> Win32Resource + member CodePage: DWORD + member Data: byte [] + member Id: int + member LanguageId : DWORD + member Name: string + member TypeId: int + member TypeName: string + +[] +type CvtResFile = + static member ReadResFile : stream:Stream -> List + +[] +type Win32ResourceConversions = + static member AppendIconToResourceStream : resStream:Stream * iconStream:Stream -> unit + static member AppendVersionToResourceStream : resStream:Stream * isDll:Boolean * fileVersion:string * originalFileName:string * internalName:string * productVersion:string * assemblyVersion:Version * ?fileDescription:string * ?legalCopyright:string * ?legalTrademarks:string * ?productName:string * ?comments:string * ?companyName:string -> unit + static member AppendManifestToResourceStream : resStream:Stream * manifestStream:Stream * isDll:Boolean -> unit + +// Write native resources +[] +type NativeResourceWriter = + static member SortResources: resources: IEnumerable -> IEnumerable + static member SerializeWin32Resources: builder:BlobBuilder * theResources: IEnumerable * resourcesRva: int -> unit + (* + static member SerializeWin32Resources (builder : BlobBuilder, resourceSections : ResourceSection, resourcesRva : int) -> unit + ()*) \ No newline at end of file diff --git a/src/absil/ilpars.fsy b/src/fsharp/absil/ilpars.fsy similarity index 82% rename from src/absil/ilpars.fsy rename to src/fsharp/absil/ilpars.fsy index e831677e50a..29b3dd9127e 100644 --- a/src/absil/ilpars.fsy +++ b/src/fsharp/absil/ilpars.fsy @@ -5,15 +5,15 @@ #nowarn "1182" // the generated code often has unused variable "parseState" open Internal.Utilities +open Internal.Utilities.Library open Internal.Utilities.Text open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.AsciiConstants +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.AsciiConstants open FSharp.Compiler.AbstractIL.Diagnostics -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types +open FSharp.Compiler.AbstractIL.ILX.Types open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library let pfailwith s = @@ -31,17 +31,6 @@ let resolveMethodSpecScopeThen (ResolvedAtMethodSpecScope f) g = let resolveCurrentMethodSpecScope obj = resolveMethodSpecScope obj mkILEmptyGenericParams - -let findSystemRuntimeAssemblyRef() = - match parseILGlobals.primaryAssemblyScopeRef with - | ILScopeRef.Assembly aref -> aref - | _ -> pfailwith "systemRuntimeScopeRef not set to valid assembly reference in parseILGlobals" - -let findAssemblyRef nm = - if nm = "mscorlib" then findSystemRuntimeAssemblyRef() - else - pfailwith ("Undefined assembly ref '" + nm + "'") - %} /*----------------------------------------------------------------------- @@ -178,8 +167,7 @@ name1: className: LBRACK name1 RBRACK slashedName { let (enc,nm) = $4 - let aref = findAssemblyRef $2 - ILScopeRef.Assembly aref, enc, nm } + ILScopeRef.PrimaryAssembly, enc, nm } | slashedName { let enc, nm = $1 in (ILScopeRef.Local, enc, nm) } @@ -235,9 +223,9 @@ callKind: *---------------------------------------------*/ typ: STRING - { noMethodSpecScope parseILGlobals.typ_String } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_String } | OBJECT - { noMethodSpecScope parseILGlobals.typ_Object } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Object } | CLASS typeNameInst { resolveMethodSpecScopeThen $2 (fun tspec -> noMethodSpecScope (mkILBoxedType tspec)) } @@ -256,45 +244,45 @@ typ: STRING | typ STAR { resolveMethodSpecScopeThen $1 (fun ty -> noMethodSpecScope (ILType.Ptr ty)) } | CHAR - { noMethodSpecScope parseILGlobals.typ_Char } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Char } | VOID { noMethodSpecScope ILType.Void } | BOOL - { noMethodSpecScope parseILGlobals.typ_Bool } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Bool } | INT8 - { noMethodSpecScope parseILGlobals.typ_SByte } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_SByte } | INT16 - { noMethodSpecScope parseILGlobals.typ_Int16 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Int16 } | INT32 - { noMethodSpecScope parseILGlobals.typ_Int32 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Int32 } | INT64 - { noMethodSpecScope parseILGlobals.typ_Int64 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Int64 } | FLOAT32 - { noMethodSpecScope parseILGlobals.typ_Single } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Single } | FLOAT64 - { noMethodSpecScope parseILGlobals.typ_Double } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Double } | UNSIGNED INT8 - { noMethodSpecScope parseILGlobals.typ_Byte } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Byte } | UNSIGNED INT16 - { noMethodSpecScope parseILGlobals.typ_UInt16 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt16 } | UNSIGNED INT32 - { noMethodSpecScope parseILGlobals.typ_UInt32 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt32 } | UNSIGNED INT64 - { noMethodSpecScope parseILGlobals.typ_UInt64 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt64 } | UINT8 - { noMethodSpecScope parseILGlobals.typ_Byte } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_Byte } | UINT16 - { noMethodSpecScope parseILGlobals.typ_UInt16 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt16 } | UINT32 - { noMethodSpecScope parseILGlobals.typ_UInt32 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt32 } | UINT64 - { noMethodSpecScope parseILGlobals.typ_UInt64 } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UInt64 } | NATIVE INT - { noMethodSpecScope parseILGlobals.typ_IntPtr } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_IntPtr } | NATIVE UNSIGNED INT - { noMethodSpecScope parseILGlobals.typ_UIntPtr } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UIntPtr } | NATIVE UINT - { noMethodSpecScope parseILGlobals.typ_UIntPtr } + { noMethodSpecScope PrimaryAssemblyILGlobals.typ_UIntPtr } | BANG int32 { noMethodSpecScope (ILType.TypeVar (uint16 ( $2))) } diff --git a/src/absil/ilprint.fs b/src/fsharp/absil/ilprint.fs similarity index 93% rename from src/absil/ilprint.fs rename to src/fsharp/absil/ilprint.fs index 42c0dcddd6a..3a831bc1b5b 100644 --- a/src/absil/ilprint.fs +++ b/src/fsharp/absil/ilprint.fs @@ -2,15 +2,16 @@ module internal FSharp.Compiler.AbstractIL.ILAsciiWriter -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types -open FSharp.Compiler.AbstractIL.Internal.AsciiConstants -open FSharp.Compiler.AbstractIL.IL - open System.IO open System.Reflection +open FSharp.Compiler.IO +open Internal.Utilities.Library + +open FSharp.Compiler.AbstractIL.AsciiConstants +open FSharp.Compiler.AbstractIL.ILX.Types +open FSharp.Compiler.AbstractIL.IL + #if DEBUG let pretty () = true @@ -107,7 +108,7 @@ let output_array sep f os (a:_ []) = for i in 0..a.Length-2 do f os a.[i] output_string os sep - f os (a.[a.Length - 1]) + f os a.[a.Length - 1] let output_parens f os a = output_string os "("; f os a; output_string os ")" @@ -193,20 +194,20 @@ and goutput_typ env os ty = | ILType.Byref typ -> goutput_typ env os typ; output_string os "&" | ILType.Ptr typ -> goutput_typ env os typ; output_string os "*" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_SByte.TypeSpec.Name -> output_string os "int8" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Int16.TypeSpec.Name -> output_string os "int16" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Int32.TypeSpec.Name -> output_string os "int32" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Int64.TypeSpec.Name -> output_string os "int64" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_IntPtr.TypeSpec.Name -> output_string os "native int" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Byte.TypeSpec.Name -> output_string os "unsigned int8" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_UInt16.TypeSpec.Name -> output_string os "unsigned int16" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_UInt32.TypeSpec.Name -> output_string os "unsigned int32" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_UInt64.TypeSpec.Name -> output_string os "unsigned int64" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_UIntPtr.TypeSpec.Name -> output_string os "native unsigned int" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Double.TypeSpec.Name -> output_string os "float64" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Single.TypeSpec.Name -> output_string os "float32" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Bool.TypeSpec.Name -> output_string os "bool" - | ILType.Value tspec when tspec.Name = EcmaMscorlibILGlobals.typ_Char.TypeSpec.Name -> output_string os "char" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_SByte.TypeSpec.Name -> output_string os "int8" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Int16.TypeSpec.Name -> output_string os "int16" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Int32.TypeSpec.Name -> output_string os "int32" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Int64.TypeSpec.Name -> output_string os "int64" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_IntPtr.TypeSpec.Name -> output_string os "native int" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Byte.TypeSpec.Name -> output_string os "unsigned int8" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_UInt16.TypeSpec.Name -> output_string os "unsigned int16" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_UInt32.TypeSpec.Name -> output_string os "unsigned int32" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_UInt64.TypeSpec.Name -> output_string os "unsigned int64" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_UIntPtr.TypeSpec.Name -> output_string os "native unsigned int" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Double.TypeSpec.Name -> output_string os "float64" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Single.TypeSpec.Name -> output_string os "float32" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Bool.TypeSpec.Name -> output_string os "bool" + | ILType.Value tspec when tspec.Name = PrimaryAssemblyILGlobals.typ_Char.TypeSpec.Name -> output_string os "char" | ILType.Value tspec -> output_string os "value class " goutput_tref env os tspec.TypeRef @@ -258,13 +259,13 @@ and output_arr_bounds os = function | ILArrayShape l -> output_seq ", " (fun os -> function - | (None, None) -> output_string os "" - | (None, Some sz) -> + | None, None -> output_string os "" + | None, Some sz -> output_int os sz - | (Some lower, None) -> + | Some lower, None -> output_int os lower output_string os " ... " - | (Some lower, Some d) -> + | Some lower, Some d -> output_int os lower output_string os " ... " output_int os d) @@ -459,7 +460,7 @@ let output_at os b = let output_option f os = function None -> () | Some x -> f os x -let goutput_alternative_ref env os (alt: IlxUnionAlternative) = +let goutput_alternative_ref env os (alt: IlxUnionCase) = output_id os alt.Name alt.FieldDefs |> output_parens (output_array ", " (fun os fdef -> goutput_typ env os fdef.Type)) os @@ -497,7 +498,7 @@ let output_custom_attr_data os data = let goutput_custom_attr env os (attr: ILAttribute) = output_string os " .custom " goutput_mspec env os attr.Method - let data = getCustomAttrData env.ilGlobals attr + let data = getCustomAttrData attr output_custom_attr_data os data let goutput_custom_attrs env os (attrs : ILAttributes) = @@ -582,7 +583,7 @@ let goutput_freevar env os l = let goutput_freevars env os ps = output_parens (output_seq ", " (goutput_freevar env)) os ps -let output_source os (s:ILSourceMarker) = +let output_source os (s:ILDebugPoint) = if s.Document.File <> "" then output_string os " .line " output_int os s.Line @@ -633,13 +634,13 @@ let rec goutput_instr env os inst = output_after_tailcall os tl | I_ldarg u16 -> output_string os "ldarg"; output_short_u16 os u16 | I_ldarga u16 -> output_string os "ldarga "; output_u16 os u16 - | (AI_ldc (dt, ILConst.I4 x)) -> + | AI_ldc (dt, ILConst.I4 x) -> output_string os "ldc."; output_basic_type os dt; output_short_i32 os x - | (AI_ldc (dt, ILConst.I8 x)) -> + | AI_ldc (dt, ILConst.I8 x) -> output_string os "ldc."; output_basic_type os dt; output_string os " "; output_i64 os x - | (AI_ldc (dt, ILConst.R4 x)) -> + | AI_ldc (dt, ILConst.R4 x) -> output_string os "ldc."; output_basic_type os dt; output_string os " "; output_ieee32 os x - | (AI_ldc (dt, ILConst.R8 x)) -> + | AI_ldc (dt, ILConst.R8 x) -> output_string os "ldc."; output_basic_type os dt; output_string os " "; output_ieee64 os x | I_ldftn mspec -> output_string os "ldftn "; goutput_mspec env os mspec | I_ldvirtftn mspec -> output_string os "ldvirtftn "; goutput_mspec env os mspec @@ -728,7 +729,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(typ, shape)) output_string os ".ctor" let rank = shape.Rank - output_parens (output_array ", " (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) + output_parens (output_array ", " (goutput_typ env)) os (Array.create rank PrimaryAssemblyILGlobals.typ_Int32) | I_stelem_any (shape, dt) -> if shape = ILArrayShape.SingleDimensional then output_string os "stelem.any "; goutput_typ env os dt @@ -737,7 +738,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(dt, shape)) output_string os "Set" let rank = shape.Rank - let arr = Array.create (rank + 1) EcmaMscorlibILGlobals.typ_Int32 + let arr = Array.create (rank + 1) PrimaryAssemblyILGlobals.typ_Int32 arr.[rank] <- dt output_parens (output_array ", " (goutput_typ env)) os arr | I_ldelem_any (shape, tok) -> @@ -750,7 +751,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(tok, shape)) output_string os "Get" let rank = shape.Rank - output_parens (output_array ", " (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) + output_parens (output_array ", " (goutput_typ env)) os (Array.create rank PrimaryAssemblyILGlobals.typ_Int32) | I_ldelema (ro, _, shape, tok) -> if ro = ReadonlyAddress then output_string os "readonly. " if shape = ILArrayShape.SingleDimensional then @@ -762,7 +763,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(tok, shape)) output_string os "Address" let rank = shape.Rank - output_parens (output_array ", " (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) + output_parens (output_array ", " (goutput_typ env)) os (Array.create rank PrimaryAssemblyILGlobals.typ_Int32) | I_box tok -> output_string os "box "; goutput_typ env os tok | I_unbox tok -> output_string os "unbox "; goutput_typ env os tok @@ -807,8 +808,8 @@ let goutput_mbody is_entrypoint env os (md: ILMethodDef) = output_string os " \n{ \n" goutput_security_decls env os md.SecurityDecls goutput_custom_attrs env os md.CustomAttrs - match md.Body.Contents with - | MethodBody.IL il -> goutput_ilmbody env os il + match md.Body with + | MethodBody.IL il -> goutput_ilmbody env os il.Value | _ -> () if is_entrypoint then output_string os " .entrypoint" output_string os "\n" @@ -827,8 +828,9 @@ let goutput_mdef env os (md:ILMethodDef) = elif md.IsConstructor then "rtspecialname" elif md.IsStatic then "static " + - (match md.Body.Contents with - MethodBody.PInvoke (attr) -> + (match md.Body with + MethodBody.PInvoke attrLazy -> + let attr = attrLazy.Value "pinvokeimpl(\"" + attr.Where.Name + "\" as \"" + attr.Name + "\"" + (match attr.CallingConv with | PInvokeCallingConvention.None -> "" @@ -1060,8 +1062,8 @@ let output_module_fragment_aux _refs os (ilg: ILGlobals) modul = try let env = mk_ppenv ilg let env = ppenv_enter_modul env - goutput_tdefs false ([]) env os modul.TypeDefs - goutput_tdefs true ([]) env os modul.TypeDefs + goutput_tdefs false [] env os modul.TypeDefs + goutput_tdefs true [] env os modul.TypeDefs with e -> output_string os "*** Error during printing : "; output_string os (e.ToString()); os.Flush() reraise() diff --git a/src/absil/ilprint.fsi b/src/fsharp/absil/ilprint.fsi similarity index 83% rename from src/absil/ilprint.fsi rename to src/fsharp/absil/ilprint.fsi index 9ba4ccb1bf7..be5e4f53dce 100644 --- a/src/absil/ilprint.fsi +++ b/src/fsharp/absil/ilprint.fsi @@ -3,9 +3,7 @@ /// Printer for the abstract syntax. module internal FSharp.Compiler.AbstractIL.ILAsciiWriter -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal open System.IO #if DEBUG diff --git a/src/fsharp/absil/ilread.fs b/src/fsharp/absil/ilread.fs new file mode 100644 index 00000000000..6e497b1ccc6 --- /dev/null +++ b/src/fsharp/absil/ilread.fs @@ -0,0 +1,4075 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +//--------------------------------------------------------------------- +// The big binary reader +// +//--------------------------------------------------------------------- + +module FSharp.Compiler.AbstractIL.ILBinaryReader + +#nowarn "42" // This construct is deprecated: it is only for use in the F# library + +open System +open System.Collections.Concurrent +open System.Collections.Generic +open System.Collections.Immutable +open System.Diagnostics +open System.IO +open System.Text +open Internal.Utilities.Collections +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.BinaryConstants +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.Support +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range +open System.Reflection +open System.Reflection.PortableExecutable +open FSharp.NativeInterop + +#nowarn "9" + +let checking = false +let logging = false +let _ = if checking then dprintn "warning: ILBinaryReader.checking is on" +let noStableFileHeuristic = try (Environment.GetEnvironmentVariable("FSharp_NoStableFileHeuristic") <> null) with _ -> false +let alwaysMemoryMapFSC = try (Environment.GetEnvironmentVariable("FSharp_AlwaysMemoryMapCommandLineCompiler") <> null) with _ -> false +let stronglyHeldReaderCacheSizeDefault = 30 +let stronglyHeldReaderCacheSize = try (match Environment.GetEnvironmentVariable("FSharp_StronglyHeldBinaryReaderCacheSize") with null -> stronglyHeldReaderCacheSizeDefault | s -> int32 s) with _ -> stronglyHeldReaderCacheSizeDefault + +let singleOfBits (x: int32) = BitConverter.ToSingle(BitConverter.GetBytes x, 0) +let doubleOfBits (x: int64) = BitConverter.Int64BitsToDouble x + +//--------------------------------------------------------------------- +// Utilities. +//--------------------------------------------------------------------- + +let align alignment n = ((n + alignment - 0x1) / alignment) * alignment + +let uncodedToken (tab: TableName) idx = ((tab.Index <<< 24) ||| idx) + +let i32ToUncodedToken tok = + let idx = tok &&& 0xffffff + let tab = tok >>>& 24 + (TableName.FromIndex tab, idx) + + +[] +type TaggedIndex<'T> = + val tag: 'T + val index: int32 + new(tag, index) = { tag=tag; index=index } + +let uncodedTokenToTypeDefOrRefOrSpec (tab, tok) = + let tag = + if tab = TableNames.TypeDef then tdor_TypeDef + elif tab = TableNames.TypeRef then tdor_TypeRef + elif tab = TableNames.TypeSpec then tdor_TypeSpec + else failwith "bad table in uncodedTokenToTypeDefOrRefOrSpec" + TaggedIndex(tag, tok) + +let uncodedTokenToMethodDefOrRef (tab, tok) = + let tag = + if tab = TableNames.Method then mdor_MethodDef + elif tab = TableNames.MemberRef then mdor_MemberRef + else failwith "bad table in uncodedTokenToMethodDefOrRef" + TaggedIndex(tag, tok) + +let (|TaggedIndex|) (x: TaggedIndex<'T>) = x.tag, x.index +let inline tokToTaggedIdx f nbits tok = + let tagmask = + if nbits = 1 then 1 + elif nbits = 2 then 3 + elif nbits = 3 then 7 + elif nbits = 4 then 15 + elif nbits = 5 then 31 + else failwith "too many nbits" + let tag = tok &&& tagmask + let idx = tok >>>& nbits + TaggedIndex(f tag, idx) + +type Statistics = + { mutable rawMemoryFileCount: int + mutable memoryMapFileOpenedCount: int + mutable memoryMapFileClosedCount: int + mutable weakByteFileCount: int + mutable byteFileCount: int } + +let stats = + { rawMemoryFileCount = 0 + memoryMapFileOpenedCount = 0 + memoryMapFileClosedCount = 0 + weakByteFileCount = 0 + byteFileCount = 0 } + +let GetStatistics() = stats + +type private BinaryView = ReadOnlyByteMemory + +/// An abstraction over how we access the contents of .NET binaries. +type BinaryFile = + abstract GetView: unit -> BinaryView + +/// Gives views over a raw chunk of memory, for example those returned to us by the memory manager in Roslyn's +/// Visual Studio integration. 'obj' must keep the memory alive. The object will capture it and thus also keep the memory alive for +/// the lifetime of this object. +type RawMemoryFile = + val mutable private holder: obj + val mutable private fileName: string + val mutable private view: ReadOnlyByteMemory + + new (fileName: string, obj: obj, addr: nativeint, length: int) = + stats.rawMemoryFileCount <- stats.rawMemoryFileCount + 1 + { + holder = obj + fileName = fileName + view = ByteMemory.FromUnsafePointer(addr, length, obj).AsReadOnly() + } + + new (fileName: string, holder: obj, bmem: ByteMemory) = + { + holder = holder // gonna be finalized due to how we pass the holder when create RawByteMemory + fileName = fileName + view = bmem.AsReadOnly() + } + + member r.HoldObj() = r.holder // make sure we capture the holder. + member r.FileName = r.fileName + + interface BinaryFile with + override r.GetView() = r.view + +/// Gives a view over any ByteMemory, can be stream-based, mmap-ed, or just byte array. +type ByteMemoryFile(fileName: string, view: ByteMemory) = + member _.FileName = fileName + interface BinaryFile with + override _.GetView() = view.AsReadOnly() + +/// A BinaryFile backed by an array of bytes held strongly as managed memory +[] +type ByteFile(fileName: string, bytes: byte[]) = + let view = ByteMemory.FromArray(bytes).AsReadOnly() + do stats.byteFileCount <- stats.byteFileCount + 1 + member _.FileName = fileName + interface BinaryFile with + override bf.GetView() = view + +type PEFile(fileName: string, peReader: PEReader) as this = + + // We store a weak byte memory reference so we do not constantly create a lot of byte memory objects. + // We could just have a single ByteMemory stored in the PEFile, but we need to dispose of the stream via the finalizer; we cannot have a cicular reference. + let mutable weakMemory = WeakReference(Unchecked.defaultof<_>) + + member _.FileName = fileName + + override _.Finalize() = + peReader.Dispose() + + interface BinaryFile with + override _.GetView() = + match weakMemory.TryGetTarget() with + | true, m -> m.AsReadOnly() + | _ -> + let block = peReader.GetEntireImage() // it's ok to call this everytime we do GetView as it is cached in the PEReader. + let m = ByteMemory.FromUnsafePointer(block.Pointer |> NativePtr.toNativeInt, block.Length, this) + weakMemory <- WeakReference(m) + m.AsReadOnly() + +/// Same as ByteFile but holds the bytes weakly. The bytes will be re-read from the backing file when a view is requested. +/// This is the default implementation used by F# Compiler Services when accessing "stable" binaries. It is not used +/// by Visual Studio, where tryGetMetadataSnapshot provides a RawMemoryFile backed by Roslyn data. +[] +type WeakByteFile(fileName: string, chunk: (int * int) option) = + + do stats.weakByteFileCount <- stats.weakByteFileCount + 1 + + /// Used to check that the file hasn't changed + let fileStamp = FileSystem.GetLastWriteTimeShim fileName + + /// The weak handle to the bytes for the file + let weakBytes = WeakReference(null) + + member _.FileName = fileName + + /// Get the bytes for the file + interface BinaryFile with + + override this.GetView() = + let strongBytes = + let mutable tg = null + if not (weakBytes.TryGetTarget(&tg)) then + if FileSystem.GetLastWriteTimeShim fileName <> fileStamp then + error (Error (FSComp.SR.ilreadFileChanged fileName, range0)) + + let bytes = + use stream = FileSystem.OpenFileForReadShim(fileName) + match chunk with + | None -> stream.ReadAllBytes() + | Some(start, length) -> stream.ReadBytes(start, length) + + tg <- bytes + + weakBytes.SetTarget bytes + + tg + + ByteMemory.FromArray(strongBytes).AsReadOnly() + + +let seekReadByte (mdv: BinaryView) addr = mdv.[addr] +let seekReadBytes (mdv: BinaryView) addr len = mdv.ReadBytes(addr, len) +let seekReadInt32 (mdv: BinaryView) addr = mdv.ReadInt32 addr +let seekReadUInt16 (mdv: BinaryView) addr = mdv.ReadUInt16 addr + +let seekReadByteAsInt32 mdv addr = int32 (seekReadByte mdv addr) + +let seekReadInt64 mdv addr = + let b0 = seekReadByte mdv addr + let b1 = seekReadByte mdv (addr+1) + let b2 = seekReadByte mdv (addr+2) + let b3 = seekReadByte mdv (addr+3) + let b4 = seekReadByte mdv (addr+4) + let b5 = seekReadByte mdv (addr+5) + let b6 = seekReadByte mdv (addr+6) + let b7 = seekReadByte mdv (addr+7) + int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| + (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56) + +let seekReadUInt16AsInt32 mdv addr = int32 (seekReadUInt16 mdv addr) + +let seekReadCompressedUInt32 mdv addr = + let b0 = seekReadByte mdv addr + if b0 <= 0x7Fuy then struct (int b0, addr+1) + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1 = seekReadByteAsInt32 mdv (addr+1) + struct ((int b0 <<< 8) ||| int b1, addr+2) + else + let b0 = b0 &&& 0x3Fuy + let b1 = seekReadByteAsInt32 mdv (addr+1) + let b2 = seekReadByteAsInt32 mdv (addr+2) + let b3 = seekReadByteAsInt32 mdv (addr+3) + struct ((int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, addr+4) + +let seekReadSByte mdv addr = sbyte (seekReadByte mdv addr) +let seekReadSingle mdv addr = singleOfBits (seekReadInt32 mdv addr) +let seekReadDouble mdv addr = doubleOfBits (seekReadInt64 mdv addr) + +let rec seekCountUtf8String mdv addr n = + let c = seekReadByteAsInt32 mdv addr + if c = 0 then n + else seekCountUtf8String mdv (addr+1) (n+1) + +let seekReadUTF8String (mdv: BinaryView) addr = + let n = seekCountUtf8String mdv addr 0 + mdv.ReadUtf8String (addr, n) + +let seekReadBlob mdv addr = + let struct (len, addr) = seekReadCompressedUInt32 mdv addr + seekReadBytes mdv addr len + +let seekReadUserString mdv addr = + let struct (len, addr) = seekReadCompressedUInt32 mdv addr + let bytes = seekReadBytes mdv addr (len - 1) + Encoding.Unicode.GetString(bytes, 0, bytes.Length) + +let seekReadGuid mdv addr = seekReadBytes mdv addr 0x10 + +let seekReadUncodedToken mdv addr = + i32ToUncodedToken (seekReadInt32 mdv addr) + + +//--------------------------------------------------------------------- +// Primitives to help read signatures. These do not use the file cursor +//--------------------------------------------------------------------- + +let sigptrCheck (bytes: byte[]) sigptr = + if checking && sigptr >= bytes.Length then failwith "read past end of sig. " + +// All this code should be moved to use a mutable index into the signature +// +//type SigPtr(bytes: byte[], sigptr: int) = +// let mutable curr = sigptr +// member x.GetByte() = let res = bytes.[curr] in curr <- curr + 1; res + +let sigptrGetByte (bytes: byte[]) sigptr = + sigptrCheck bytes sigptr + bytes.[sigptr], sigptr + 1 + +let sigptrGetBool bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + (b0 = 0x01uy), sigptr + +let sigptrGetSByte bytes sigptr = + let i, sigptr = sigptrGetByte bytes sigptr + sbyte i, sigptr + +let sigptrGetUInt16 bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + let b1, sigptr = sigptrGetByte bytes sigptr + uint16 (int b0 ||| (int b1 <<< 8)), sigptr + +let sigptrGetInt16 bytes sigptr = + let u, sigptr = sigptrGetUInt16 bytes sigptr + int16 u, sigptr + +let sigptrGetInt32 bytes sigptr = + sigptrCheck bytes sigptr + let b0 = bytes.[sigptr] + let b1 = bytes.[sigptr+1] + let b2 = bytes.[sigptr+2] + let b3 = bytes.[sigptr+3] + let res = int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) + res, sigptr + 4 + +let sigptrGetUInt32 bytes sigptr = + let u, sigptr = sigptrGetInt32 bytes sigptr + uint32 u, sigptr + +let sigptrGetUInt64 bytes sigptr = + let u0, sigptr = sigptrGetUInt32 bytes sigptr + let u1, sigptr = sigptrGetUInt32 bytes sigptr + (uint64 u0 ||| (uint64 u1 <<< 32)), sigptr + +let sigptrGetInt64 bytes sigptr = + let u, sigptr = sigptrGetUInt64 bytes sigptr + int64 u, sigptr + +let sigptrGetSingle bytes sigptr = + let u, sigptr = sigptrGetInt32 bytes sigptr + singleOfBits u, sigptr + +let sigptrGetDouble bytes sigptr = + let u, sigptr = sigptrGetInt64 bytes sigptr + doubleOfBits u, sigptr + +let sigptrGetZInt32 bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + if b0 <= 0x7Fuy then struct (int b0, sigptr) + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1, sigptr = sigptrGetByte bytes sigptr + struct ((int b0 <<< 8) ||| int b1, sigptr) + else + let b0 = b0 &&& 0x3Fuy + let b1, sigptr = sigptrGetByte bytes sigptr + let b2, sigptr = sigptrGetByte bytes sigptr + let b3, sigptr = sigptrGetByte bytes sigptr + struct ((int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, sigptr) + +let rec sigptrFoldAcc f n (bytes: byte[]) (sigptr: int) i acc = + if i < n then + let x, sp = f bytes sigptr + sigptrFoldAcc f n bytes sp (i+1) (x :: acc) + else + List.rev acc, sigptr + +let sigptrFold f n (bytes: byte[]) (sigptr: int) = + sigptrFoldAcc f n bytes sigptr 0 [] + +let sigptrFoldStruct f n (bytes: byte[]) (sigptr: int) = + let rec sigptrFoldAcc f n (bytes: byte[]) (sigptr: int) i acc = + if i < n then + let struct (x, sp) = f bytes sigptr + sigptrFoldAcc f n bytes sp (i+1) (x :: acc) + else + struct (List.rev acc, sigptr) + sigptrFoldAcc f n bytes sigptr 0 [] + +let sigptrGetBytes n (bytes: byte[]) sigptr = + if checking && sigptr + n >= bytes.Length then + dprintn "read past end of sig. in sigptrGetString" + Bytes.zeroCreate 0, sigptr + else + let res = Bytes.zeroCreate n + for i = 0 to (n - 1) do + res.[i] <- bytes.[sigptr + i] + res, sigptr + n + +let sigptrGetString n bytes sigptr = + let bytearray, sigptr = sigptrGetBytes n bytes sigptr + (Encoding.UTF8.GetString(bytearray, 0, bytearray.Length)), sigptr + + +// -------------------------------------------------------------------- +// Now the tables of instructions +// -------------------------------------------------------------------- + +[] +type ILInstrPrefixesRegister = + { mutable al: ILAlignment + mutable tl: ILTailcall + mutable vol: ILVolatility + mutable ro: ILReadonly + mutable constrained: ILType option} + +let noPrefixes mk prefixes = + if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" + if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" + if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" + if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" + if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" + mk + +let volatileOrUnalignedPrefix mk prefixes = + if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" + if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" + if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" + mk (prefixes.al, prefixes.vol) + +let volatilePrefix mk prefixes = + if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" + if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" + if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" + if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" + mk prefixes.vol + +let tailPrefix mk prefixes = + if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" + if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" + if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" + if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" + mk prefixes.tl + +let constraintOrTailPrefix mk prefixes = + if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" + if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" + if prefixes.ro <> NormalAddress then failwith "a readonly prefix is not allowed here" + mk (prefixes.constrained, prefixes.tl ) + +let readonlyPrefix mk prefixes = + if prefixes.al <> Aligned then failwith "an unaligned prefix is not allowed here" + if prefixes.vol <> Nonvolatile then failwith "a volatile prefix is not allowed here" + if prefixes.tl <> Normalcall then failwith "a tailcall prefix is not allowed here" + if prefixes.constrained <> None then failwith "a constrained prefix is not allowed here" + mk prefixes.ro + + +[] +type ILInstrDecoder = + | I_u16_u8_instr of (ILInstrPrefixesRegister -> uint16 -> ILInstr) + | I_u16_u16_instr of (ILInstrPrefixesRegister -> uint16 -> ILInstr) + | I_none_instr of (ILInstrPrefixesRegister -> ILInstr) + | I_i64_instr of (ILInstrPrefixesRegister -> int64 -> ILInstr) + | I_i32_i32_instr of (ILInstrPrefixesRegister -> int32 -> ILInstr) + | I_i32_i8_instr of (ILInstrPrefixesRegister -> int32 -> ILInstr) + | I_r4_instr of (ILInstrPrefixesRegister -> single -> ILInstr) + | I_r8_instr of (ILInstrPrefixesRegister -> double -> ILInstr) + | I_field_instr of (ILInstrPrefixesRegister -> ILFieldSpec -> ILInstr) + | I_method_instr of (ILInstrPrefixesRegister -> ILMethodSpec * ILVarArgs -> ILInstr) + | I_unconditional_i32_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) + | I_unconditional_i8_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) + | I_conditional_i32_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) + | I_conditional_i8_instr of (ILInstrPrefixesRegister -> ILCodeLabel -> ILInstr) + | I_string_instr of (ILInstrPrefixesRegister -> string -> ILInstr) + | I_switch_instr of (ILInstrPrefixesRegister -> ILCodeLabel list -> ILInstr) + | I_tok_instr of (ILInstrPrefixesRegister -> ILToken -> ILInstr) + | I_sig_instr of (ILInstrPrefixesRegister -> ILCallingSignature * ILVarArgs -> ILInstr) + | I_type_instr of (ILInstrPrefixesRegister -> ILType -> ILInstr) + | I_invalid_instr + +let mkStind dt = volatileOrUnalignedPrefix (fun (x, y) -> I_stind(x, y, dt)) +let mkLdind dt = volatileOrUnalignedPrefix (fun (x, y) -> I_ldind(x, y, dt)) + +let instrs () = + [ i_ldarg_s, I_u16_u8_instr (noPrefixes mkLdarg) + i_starg_s, I_u16_u8_instr (noPrefixes I_starg) + i_ldarga_s, I_u16_u8_instr (noPrefixes I_ldarga) + i_stloc_s, I_u16_u8_instr (noPrefixes mkStloc) + i_ldloc_s, I_u16_u8_instr (noPrefixes mkLdloc) + i_ldloca_s, I_u16_u8_instr (noPrefixes I_ldloca) + i_ldarg, I_u16_u16_instr (noPrefixes mkLdarg) + i_starg, I_u16_u16_instr (noPrefixes I_starg) + i_ldarga, I_u16_u16_instr (noPrefixes I_ldarga) + i_stloc, I_u16_u16_instr (noPrefixes mkStloc) + i_ldloc, I_u16_u16_instr (noPrefixes mkLdloc) + i_ldloca, I_u16_u16_instr (noPrefixes I_ldloca) + i_stind_i, I_none_instr (mkStind DT_I) + i_stind_i1, I_none_instr (mkStind DT_I1) + i_stind_i2, I_none_instr (mkStind DT_I2) + i_stind_i4, I_none_instr (mkStind DT_I4) + i_stind_i8, I_none_instr (mkStind DT_I8) + i_stind_r4, I_none_instr (mkStind DT_R4) + i_stind_r8, I_none_instr (mkStind DT_R8) + i_stind_ref, I_none_instr (mkStind DT_REF) + i_ldind_i, I_none_instr (mkLdind DT_I) + i_ldind_i1, I_none_instr (mkLdind DT_I1) + i_ldind_i2, I_none_instr (mkLdind DT_I2) + i_ldind_i4, I_none_instr (mkLdind DT_I4) + i_ldind_i8, I_none_instr (mkLdind DT_I8) + i_ldind_u1, I_none_instr (mkLdind DT_U1) + i_ldind_u2, I_none_instr (mkLdind DT_U2) + i_ldind_u4, I_none_instr (mkLdind DT_U4) + i_ldind_r4, I_none_instr (mkLdind DT_R4) + i_ldind_r8, I_none_instr (mkLdind DT_R8) + i_ldind_ref, I_none_instr (mkLdind DT_REF) + i_cpblk, I_none_instr (volatileOrUnalignedPrefix I_cpblk) + i_initblk, I_none_instr (volatileOrUnalignedPrefix I_initblk) + i_ldc_i8, I_i64_instr (noPrefixes (fun x ->(AI_ldc (DT_I8, ILConst.I8 x)))) + i_ldc_i4, I_i32_i32_instr (noPrefixes mkLdcInt32) + i_ldc_i4_s, I_i32_i8_instr (noPrefixes mkLdcInt32) + i_ldc_r4, I_r4_instr (noPrefixes (fun x -> (AI_ldc (DT_R4, ILConst.R4 x)))) + i_ldc_r8, I_r8_instr (noPrefixes (fun x -> (AI_ldc (DT_R8, ILConst.R8 x)))) + i_ldfld, I_field_instr (volatileOrUnalignedPrefix(fun (x, y) fspec -> I_ldfld (x, y, fspec))) + i_stfld, I_field_instr (volatileOrUnalignedPrefix(fun (x, y) fspec -> I_stfld (x, y, fspec))) + i_ldsfld, I_field_instr (volatilePrefix (fun x fspec -> I_ldsfld (x, fspec))) + i_stsfld, I_field_instr (volatilePrefix (fun x fspec -> I_stsfld (x, fspec))) + i_ldflda, I_field_instr (noPrefixes I_ldflda) + i_ldsflda, I_field_instr (noPrefixes I_ldsflda) + i_call, I_method_instr (tailPrefix (fun tl (mspec, y) -> I_call (tl, mspec, y))) + i_ldftn, I_method_instr (noPrefixes (fun (mspec, _y) -> I_ldftn mspec)) + i_ldvirtftn, I_method_instr (noPrefixes (fun (mspec, _y) -> I_ldvirtftn mspec)) + i_newobj, I_method_instr (noPrefixes I_newobj) + i_callvirt, I_method_instr (constraintOrTailPrefix (fun (c, tl) (mspec, y) -> match c with Some ty -> I_callconstraint(tl, ty, mspec, y) | None -> I_callvirt (tl, mspec, y))) + i_leave_s, I_unconditional_i8_instr (noPrefixes (fun x -> I_leave x)) + i_br_s, I_unconditional_i8_instr (noPrefixes I_br) + i_leave, I_unconditional_i32_instr (noPrefixes (fun x -> I_leave x)) + i_br, I_unconditional_i32_instr (noPrefixes I_br) + i_brtrue_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_brtrue, x))) + i_brfalse_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_brfalse, x))) + i_beq_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_beq, x))) + i_blt_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_blt, x))) + i_blt_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_blt_un, x))) + i_ble_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_ble, x))) + i_ble_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_ble_un, x))) + i_bgt_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bgt, x))) + i_bgt_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bgt_un, x))) + i_bge_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bge, x))) + i_bge_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bge_un, x))) + i_bne_un_s, I_conditional_i8_instr (noPrefixes (fun x -> I_brcmp (BI_bne_un, x))) + i_brtrue, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_brtrue, x))) + i_brfalse, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_brfalse, x))) + i_beq, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_beq, x))) + i_blt, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_blt, x))) + i_blt_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_blt_un, x))) + i_ble, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_ble, x))) + i_ble_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_ble_un, x))) + i_bgt, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bgt, x))) + i_bgt_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bgt_un, x))) + i_bge, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bge, x))) + i_bge_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bge_un, x))) + i_bne_un, I_conditional_i32_instr (noPrefixes (fun x -> I_brcmp (BI_bne_un, x))) + i_ldstr, I_string_instr (noPrefixes I_ldstr) + i_switch, I_switch_instr (noPrefixes I_switch) + i_ldtoken, I_tok_instr (noPrefixes I_ldtoken) + i_calli, I_sig_instr (tailPrefix (fun tl (x, y) -> I_calli (tl, x, y))) + i_mkrefany, I_type_instr (noPrefixes I_mkrefany) + i_refanyval, I_type_instr (noPrefixes I_refanyval) + i_ldelema, I_type_instr (readonlyPrefix (fun ro x -> I_ldelema (ro, false, ILArrayShape.SingleDimensional, x))) + i_ldelem_any, I_type_instr (noPrefixes (fun x -> I_ldelem_any (ILArrayShape.SingleDimensional, x))) + i_stelem_any, I_type_instr (noPrefixes (fun x -> I_stelem_any (ILArrayShape.SingleDimensional, x))) + i_newarr, I_type_instr (noPrefixes (fun x -> I_newarr (ILArrayShape.SingleDimensional, x))) + i_castclass, I_type_instr (noPrefixes I_castclass) + i_isinst, I_type_instr (noPrefixes I_isinst) + i_unbox_any, I_type_instr (noPrefixes I_unbox_any) + i_cpobj, I_type_instr (noPrefixes I_cpobj) + i_initobj, I_type_instr (noPrefixes I_initobj) + i_ldobj, I_type_instr (volatileOrUnalignedPrefix (fun (x, y) z -> I_ldobj (x, y, z))) + i_stobj, I_type_instr (volatileOrUnalignedPrefix (fun (x, y) z -> I_stobj (x, y, z))) + i_sizeof, I_type_instr (noPrefixes I_sizeof) + i_box, I_type_instr (noPrefixes I_box) + i_unbox, I_type_instr (noPrefixes I_unbox) ] + +// The tables are delayed to avoid building them unnecessarily at startup +// Many applications of AbsIL (e.g. a compiler) don't need to read instructions. +let mutable oneByteInstrs = None +let mutable twoByteInstrs = None +let fillInstrs () = + let oneByteInstrTable = Array.create 256 I_invalid_instr + let twoByteInstrTable = Array.create 256 I_invalid_instr + let addInstr (i, f) = + if i > 0xff then + assert (i >>>& 8 = 0xfe) + let i = (i &&& 0xff) + match twoByteInstrTable.[i] with + | I_invalid_instr -> () + | _ -> dprintn ("warning: duplicate decode entries for "+string i) + twoByteInstrTable.[i] <- f + else + match oneByteInstrTable.[i] with + | I_invalid_instr -> () + | _ -> dprintn ("warning: duplicate decode entries for "+string i) + oneByteInstrTable.[i] <- f + List.iter addInstr (instrs()) + List.iter (fun (x, mk) -> addInstr (x, I_none_instr (noPrefixes mk))) (noArgInstrs.Force()) + oneByteInstrs <- Some oneByteInstrTable + twoByteInstrs <- Some twoByteInstrTable + +let rec getOneByteInstr i = + match oneByteInstrs with + | None -> fillInstrs(); getOneByteInstr i + | Some t -> t.[i] + +let rec getTwoByteInstr i = + match twoByteInstrs with + | None -> fillInstrs(); getTwoByteInstr i + | Some t -> t.[i] + +//--------------------------------------------------------------------- +// +//--------------------------------------------------------------------- + +type ImageChunk = { size: int32; addr: int32 } + +let chunk sz next = ({addr=next; size=sz}, next + sz) +let nochunk next = ({addr= 0x0;size= 0x0; }, next) + +type RowElementKind = + | UShort + | ULong + | Byte + | Data + | GGuid + | Blob + | SString + | SimpleIndex of TableName + | TypeDefOrRefOrSpec + | TypeOrMethodDef + | HasConstant + | HasCustomAttribute + | HasFieldMarshal + | HasDeclSecurity + | MemberRefParent + | HasSemantics + | MethodDefOrRef + | MemberForwarded + | Implementation + | CustomAttributeType + | ResolutionScope + +type RowKind = RowKind of RowElementKind list + +let kindAssemblyRef = RowKind [ UShort; UShort; UShort; UShort; ULong; Blob; SString; SString; Blob; ] +let kindModuleRef = RowKind [ SString ] +let kindFileRef = RowKind [ ULong; SString; Blob ] +let kindTypeRef = RowKind [ ResolutionScope; SString; SString ] +let kindTypeSpec = RowKind [ Blob ] +let kindTypeDef = RowKind [ ULong; SString; SString; TypeDefOrRefOrSpec; SimpleIndex TableNames.Field; SimpleIndex TableNames.Method ] +let kindPropertyMap = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.Property ] +let kindEventMap = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.Event ] +let kindInterfaceImpl = RowKind [ SimpleIndex TableNames.TypeDef; TypeDefOrRefOrSpec ] +let kindNested = RowKind [ SimpleIndex TableNames.TypeDef; SimpleIndex TableNames.TypeDef ] +let kindCustomAttribute = RowKind [ HasCustomAttribute; CustomAttributeType; Blob ] +let kindDeclSecurity = RowKind [ UShort; HasDeclSecurity; Blob ] +let kindMemberRef = RowKind [ MemberRefParent; SString; Blob ] +let kindStandAloneSig = RowKind [ Blob ] +let kindFieldDef = RowKind [ UShort; SString; Blob ] +let kindFieldRVA = RowKind [ Data; SimpleIndex TableNames.Field ] +let kindFieldMarshal = RowKind [ HasFieldMarshal; Blob ] +let kindConstant = RowKind [ UShort;HasConstant; Blob ] +let kindFieldLayout = RowKind [ ULong; SimpleIndex TableNames.Field ] +let kindParam = RowKind [ UShort; UShort; SString ] +let kindMethodDef = RowKind [ ULong; UShort; UShort; SString; Blob; SimpleIndex TableNames.Param ] +let kindMethodImpl = RowKind [ SimpleIndex TableNames.TypeDef; MethodDefOrRef; MethodDefOrRef ] +let kindImplMap = RowKind [ UShort; MemberForwarded; SString; SimpleIndex TableNames.ModuleRef ] +let kindMethodSemantics = RowKind [ UShort; SimpleIndex TableNames.Method; HasSemantics ] +let kindProperty = RowKind [ UShort; SString; Blob ] +let kindEvent = RowKind [ UShort; SString; TypeDefOrRefOrSpec ] +let kindManifestResource = RowKind [ ULong; ULong; SString; Implementation ] +let kindClassLayout = RowKind [ UShort; ULong; SimpleIndex TableNames.TypeDef ] +let kindExportedType = RowKind [ ULong; ULong; SString; SString; Implementation ] +let kindAssembly = RowKind [ ULong; UShort; UShort; UShort; UShort; ULong; Blob; SString; SString ] +let kindGenericParam_v1_1 = RowKind [ UShort; UShort; TypeOrMethodDef; SString; TypeDefOrRefOrSpec ] +let kindGenericParam_v2_0 = RowKind [ UShort; UShort; TypeOrMethodDef; SString ] +let kindMethodSpec = RowKind [ MethodDefOrRef; Blob ] +let kindGenericParamConstraint = RowKind [ SimpleIndex TableNames.GenericParam; TypeDefOrRefOrSpec ] +let kindModule = RowKind [ UShort; SString; GGuid; GGuid; GGuid ] +let kindIllegal = RowKind [ ] + +//--------------------------------------------------------------------- +// Used for binary searches of sorted tables. Each function that reads +// a table row returns a tuple that contains the elements of the row. +// One of these elements may be a key for a sorted table. These +// keys can be compared using the functions below depending on the +// kind of element in that column. +//--------------------------------------------------------------------- + +let hcCompare (TaggedIndex(t1: HasConstantTag, idx1: int)) (TaggedIndex(t2: HasConstantTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let hsCompare (TaggedIndex(t1: HasSemanticsTag, idx1: int)) (TaggedIndex(t2: HasSemanticsTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let hcaCompare (TaggedIndex(t1: HasCustomAttributeTag, idx1: int)) (TaggedIndex(t2: HasCustomAttributeTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let mfCompare (TaggedIndex(t1: MemberForwardedTag, idx1: int)) (TaggedIndex(t2: MemberForwardedTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let hdsCompare (TaggedIndex(t1: HasDeclSecurityTag, idx1: int)) (TaggedIndex(t2: HasDeclSecurityTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let hfmCompare (TaggedIndex(t1: HasFieldMarshalTag, idx1)) (TaggedIndex(t2: HasFieldMarshalTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let tomdCompare (TaggedIndex(t1: TypeOrMethodDefTag, idx1)) (TaggedIndex(t2: TypeOrMethodDefTag, idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + +let simpleIndexCompare (idx1: int) (idx2: int) = + compare idx1 idx2 + +//--------------------------------------------------------------------- +// The various keys for the various caches. +//--------------------------------------------------------------------- + +type TypeDefAsTypIdx = TypeDefAsTypIdx of ILBoxity * ILGenericArgs * int +type TypeRefAsTypIdx = TypeRefAsTypIdx of ILBoxity * ILGenericArgs * int +type BlobAsMethodSigIdx = BlobAsMethodSigIdx of numtypars: int * blobIdx: int32 +type BlobAsFieldSigIdx = BlobAsFieldSigIdx of numtypars: int * blobIdx: int32 +type BlobAsPropSigIdx = BlobAsPropSigIdx of numtypars: int * blobIdx: int32 +type BlobAsLocalSigIdx = BlobAsLocalSigIdx of numtypars: int * blobIdx: int32 +type MemberRefAsMspecIdx = MemberRefAsMspecIdx of numtypars: int * idx: int +type MethodSpecAsMspecIdx = MethodSpecAsMspecIdx of numtypars: int * idx: int +type MemberRefAsFspecIdx = MemberRefAsFspecIdx of numtypars: int * idx: int +type CustomAttrIdx = CustomAttrIdx of CustomAttributeTypeTag * idx: int * valIdx: int32 +type GenericParamsIdx = GenericParamsIdx of numtypars: int * TypeOrMethodDefTag * idx: int + +//--------------------------------------------------------------------- +// Polymorphic caches for row and heap readers +//--------------------------------------------------------------------- + +let mkCacheInt32 lowMem _inbase _nm _sz = + if lowMem then (fun f x -> f x) else + let mutable cache = null + let mutable count = 0 +#if STATISTICS + addReport (fun oc -> if count <> 0 then oc.WriteLine ((_inbase + string count + " "+ _nm + " cache hits"): string)) +#endif + fun f (idx: int32) -> + let cache = + match cache with + | null -> cache <- ConcurrentDictionary(Environment.ProcessorCount, 11) + | _ -> () + cache + match cache.TryGetValue idx with + | true, res -> + count <- count + 1 + res + | _ -> + let res = f idx + cache.[idx] <- res + res + +let mkCacheGeneric lowMem _inbase _nm _sz = + if lowMem then (fun f x -> f x) else + let mutable cache = null + let mutable count = 0 +#if STATISTICS + addReport (fun oc -> if !count <> 0 then oc.WriteLine ((_inbase + string !count + " " + _nm + " cache hits"): string)) +#endif + fun f (idx :'T) -> + let cache = + match cache with + | null -> + cache <- ConcurrentDictionary<_, _>(Environment.ProcessorCount, 11 (* sz: int *) ) + | _ -> () + cache + + match cache.TryGetValue idx with + | true, v -> + count <- count + 1 + v + | _ -> + let res = f idx + cache.[idx] <- res + res + +//----------------------------------------------------------------------- +// Polymorphic general helpers for searching for particular rows. +// ---------------------------------------------------------------------- + +let seekFindRow numRows rowChooser = + let mutable i = 1 + while (i <= numRows && not (rowChooser i)) do + i <- i + 1 + if i > numRows then dprintn "warning: seekFindRow: row not found" + i + +// search for rows satisfying predicate +let seekReadIndexedRows (numRows, rowReader, keyFunc, keyComparer, binaryChop, rowConverter) = + if binaryChop then + let mutable low = 0 + let mutable high = numRows + 1 + begin + let mutable fin = false + while not fin do + if high - low <= 1 then + fin <- true + else + let mid = (low + high) / 2 + let midrow = rowReader mid + let c = keyComparer (keyFunc midrow) + if c > 0 then + low <- mid + elif c < 0 then + high <- mid + else + fin <- true + end + let mutable res = [] + if high - low > 1 then + // now read off rows, forward and backwards + let mid = (low + high) / 2 + // read forward + let mutable fin = false + let mutable curr = mid + while not fin do + if curr > numRows then + fin <- true + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res + else + fin <- true + curr <- curr + 1 + + res <- List.rev res + // read backwards + let mutable fin = false + let mutable curr = mid - 1 + while not fin do + if curr = 0 then + fin <- true + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res + else + fin <- true + curr <- curr - 1 + // sanity check +#if CHECKING + if checking then + let res2 = + [ for i = 1 to numRows do + let rowinfo = rowReader i + if keyComparer (keyFunc rowinfo) = 0 then + yield rowConverter rowinfo ] + if (res2 <> res) then + failwith ("results of binary search did not match results of linear search: linear search produced "+string res2.Length+", binary search produced "+string res.Length) +#endif + + res + else + [ for i = 1 to numRows do + let rowinfo = rowReader i + if keyComparer (keyFunc rowinfo) = 0 then + yield rowConverter rowinfo ] + + +let seekReadOptionalIndexedRow info = + match seekReadIndexedRows info with + | [k] -> Some k + | [] -> None + | h :: _ -> + dprintn "multiple rows found when indexing table" + Some h + +let seekReadIndexedRow info = + match seekReadOptionalIndexedRow info with + | Some row -> row + | None -> failwith "no row found for key when indexing table" + +//--------------------------------------------------------------------- +// IL Reading proper +//--------------------------------------------------------------------- + +type MethodData = MethodData of enclTy: ILType * ILCallingConv * name: string * argtys: ILTypes * retty: ILType * minst: ILTypes +type VarArgMethodData = VarArgMethodData of enclTy: ILType * ILCallingConv * name: string * argtys: ILTypes * ILVarArgs * retty: ILType * minst: ILTypes + +[] +type PEReader = + { fileName: string +#if FX_NO_PDB_READER + pdb: obj option +#else + pdb: (PdbReader * (string -> ILSourceDocument)) option +#endif + entryPointToken: TableName * int + pefile: BinaryFile + textSegmentPhysicalLoc: int32 + textSegmentPhysicalSize: int32 + dataSegmentPhysicalLoc: int32 + dataSegmentPhysicalSize: int32 + anyV2P: string * int32 -> int32 + metadataAddr: int32 + sectionHeaders: (int32 * int32 * int32) list + nativeResourcesAddr: int32 + nativeResourcesSize: int32 + resourcesAddr: int32 + strongnameAddr: int32 + vtableFixupsAddr: int32 + noFileOnDisk: bool +} + +[] +type ILMetadataReader = + { sorted: int64 + mdfile: BinaryFile + pectxtCaptured: PEReader option // only set when reading full PE including code etc. for static linking + entryPointToken: TableName * int + dataEndPoints: Lazy + fileName: string + getNumRows: TableName -> int + userStringsStreamPhysicalLoc: int32 + stringsStreamPhysicalLoc: int32 + blobsStreamPhysicalLoc: int32 + blobsStreamSize: int32 + readUserStringHeap: int32 -> string + memoizeString: string -> string + readStringHeap: int32 -> string + readBlobHeap: int32 -> byte[] + guidsStreamPhysicalLoc: int32 + rowAddr: TableName -> int -> int32 + tableBigness: bool [] + rsBigness: bool + tdorBigness: bool + tomdBigness: bool + hcBigness: bool + hcaBigness: bool + hfmBigness: bool + hdsBigness: bool + mrpBigness: bool + hsBigness: bool + mdorBigness: bool + mfBigness: bool + iBigness: bool + catBigness: bool + stringsBigness: bool + guidsBigness: bool + blobsBigness: bool + seekReadNestedRow: int -> int * int + seekReadConstantRow: int -> uint16 * TaggedIndex * int32 + seekReadMethodSemanticsRow: int -> int32 * int * TaggedIndex + seekReadTypeDefRow: int -> int32 * int32 * int32 * TaggedIndex * int * int + seekReadAssemblyRef: int -> ILAssemblyRef + seekReadMethodSpecAsMethodData: MethodSpecAsMspecIdx -> VarArgMethodData + seekReadMemberRefAsMethodData: MemberRefAsMspecIdx -> VarArgMethodData + seekReadMemberRefAsFieldSpec: MemberRefAsFspecIdx -> ILFieldSpec + seekReadCustomAttr: CustomAttrIdx -> ILAttribute + seekReadTypeRef: int ->ILTypeRef + seekReadTypeRefAsType: TypeRefAsTypIdx -> ILType + readBlobHeapAsPropertySig: BlobAsPropSigIdx -> ILThisConvention * ILType * ILTypes + readBlobHeapAsFieldSig: BlobAsFieldSigIdx -> ILType + readBlobHeapAsMethodSig: BlobAsMethodSigIdx -> bool * int32 * ILCallingConv * ILType * ILTypes * ILVarArgs + readBlobHeapAsLocalsSig: BlobAsLocalSigIdx -> ILLocal list + seekReadTypeDefAsType: TypeDefAsTypIdx -> ILType + seekReadMethodDefAsMethodData: int -> MethodData + seekReadGenericParams: GenericParamsIdx -> ILGenericParameterDef list + seekReadFieldDefAsFieldSpec: int -> ILFieldSpec + customAttrsReader_Module: ILAttributesStored + customAttrsReader_Assembly: ILAttributesStored + customAttrsReader_TypeDef: ILAttributesStored + customAttrsReader_GenericParam: ILAttributesStored + customAttrsReader_FieldDef: ILAttributesStored + customAttrsReader_MethodDef: ILAttributesStored + customAttrsReader_ParamDef: ILAttributesStored + customAttrsReader_Event: ILAttributesStored + customAttrsReader_Property: ILAttributesStored + customAttrsReader_ManifestResource: ILAttributesStored + customAttrsReader_ExportedType: ILAttributesStored + securityDeclsReader_TypeDef: ILSecurityDeclsStored + securityDeclsReader_MethodDef: ILSecurityDeclsStored + securityDeclsReader_Assembly: ILSecurityDeclsStored + typeDefReader: ILTypeDefStored } + +type ISeekReadIndexedRowReader<'RowT, 'KeyT, 'T when 'RowT : struct> = + abstract GetRow: int * byref<'RowT> -> unit + abstract GetKey: byref<'RowT> -> 'KeyT + abstract CompareKey: 'KeyT -> int + abstract ConvertRow: byref<'RowT> -> 'T + +let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedRowReader<'RowT, _, _>) = + let mutable row = Unchecked.defaultof<'RowT> + if binaryChop then + let mutable low = 0 + let mutable high = numRows + 1 + + let mutable fin = false + while not fin do + if high - low <= 1 then + fin <- true + else + let mid = (low + high) / 2 + reader.GetRow(mid, &row) + let c = reader.CompareKey(reader.GetKey(&row)) + if c > 0 then + low <- mid + elif c < 0 then + high <- mid + else + fin <- true + + let res = ImmutableArray.CreateBuilder() + if high - low > 1 then + // now read off rows, forward and backwards + let mid = (low + high) / 2 + + // read backwards + let mutable fin = false + let mutable curr = mid - 1 + while not fin do + if curr = 0 then + fin <- true + else + reader.GetRow(curr, &row) + if reader.CompareKey(reader.GetKey(&row)) = 0 then + res.Add(reader.ConvertRow(&row)) + else + fin <- true + curr <- curr - 1 + + res.Reverse() + + // read forward + let mutable fin = false + let mutable curr = mid + while not fin do + if curr > numRows then + fin <- true + else + reader.GetRow(curr, &row) + if reader.CompareKey(reader.GetKey(&row)) = 0 then + res.Add(reader.ConvertRow(&row)) + else + fin <- true + curr <- curr + 1 + + res.ToArray() + else + let res = ImmutableArray.CreateBuilder() + for i = 1 to numRows do + reader.GetRow(i, &row) + if reader.CompareKey(reader.GetKey(&row)) = 0 then + res.Add(reader.ConvertRow(&row)) + res.ToArray() + +[] +type CustomAttributeRow = + val mutable parentIndex: TaggedIndex + val mutable typeIndex: TaggedIndex + val mutable valueIndex: int + +let seekReadUInt16Adv mdv (addr: byref) = + let res = seekReadUInt16 mdv addr + addr <- addr + 2 + res + +let seekReadInt32Adv mdv (addr: byref) = + let res = seekReadInt32 mdv addr + addr <- addr+4 + res + +let seekReadUInt16AsInt32Adv mdv (addr: byref) = + let res = seekReadUInt16AsInt32 mdv addr + addr <- addr+2 + res + +let inline seekReadTaggedIdx f nbits big mdv (addr: byref) = + let tok = if big then seekReadInt32Adv mdv &addr else seekReadUInt16AsInt32Adv mdv &addr + tokToTaggedIdx f nbits tok + +let seekReadIdx big mdv (addr: byref) = + if big then seekReadInt32Adv mdv &addr else seekReadUInt16AsInt32Adv mdv &addr + +let seekReadUntaggedIdx (tab: TableName) (ctxt: ILMetadataReader) mdv (addr: byref) = + seekReadIdx ctxt.tableBigness.[tab.Index] mdv &addr + +let seekReadResolutionScopeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkResolutionScopeTag 2 ctxt.rsBigness mdv &addr +let seekReadTypeDefOrRefOrSpecIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkTypeDefOrRefOrSpecTag 2 ctxt.tdorBigness mdv &addr +let seekReadTypeOrMethodDefIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkTypeOrMethodDefTag 1 ctxt.tomdBigness mdv &addr +let seekReadHasConstantIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasConstantTag 2 ctxt.hcBigness mdv &addr +let seekReadHasCustomAttributeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasCustomAttributeTag 5 ctxt.hcaBigness mdv &addr +let seekReadHasFieldMarshalIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasFieldMarshalTag 1 ctxt.hfmBigness mdv &addr +let seekReadHasDeclSecurityIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasDeclSecurityTag 2 ctxt.hdsBigness mdv &addr +let seekReadMemberRefParentIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMemberRefParentTag 3 ctxt.mrpBigness mdv &addr +let seekReadHasSemanticsIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkHasSemanticsTag 1 ctxt.hsBigness mdv &addr +let seekReadMethodDefOrRefIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMethodDefOrRefTag 1 ctxt.mdorBigness mdv &addr +let seekReadMemberForwardedIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkMemberForwardedTag 1 ctxt.mfBigness mdv &addr +let seekReadImplementationIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkImplementationTag 2 ctxt.iBigness mdv &addr +let seekReadCustomAttributeTypeIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadTaggedIdx mkILCustomAttributeTypeTag 3 ctxt.catBigness mdv &addr +let seekReadStringIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.stringsBigness mdv &addr +let seekReadGuidIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.guidsBigness mdv &addr +let seekReadBlobIdx (ctxt: ILMetadataReader) mdv (addr: byref) = seekReadIdx ctxt.blobsBigness mdv &addr + +let seekReadModuleRow (ctxt: ILMetadataReader) mdv idx = + if idx = 0 then failwith "cannot read Module table row 0" + let mutable addr = ctxt.rowAddr TableNames.Module idx + let generation = seekReadUInt16Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let mvidIdx = seekReadGuidIdx ctxt mdv &addr + let encidIdx = seekReadGuidIdx ctxt mdv &addr + let encbaseidIdx = seekReadGuidIdx ctxt mdv &addr + (generation, nameIdx, mvidIdx, encidIdx, encbaseidIdx) + +/// Read Table ILTypeRef. +let seekReadTypeRefRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.TypeRef idx + let scopeIdx = seekReadResolutionScopeIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let namespaceIdx = seekReadStringIdx ctxt mdv &addr + (scopeIdx, nameIdx, namespaceIdx) + +/// Read Table ILTypeDef. +let seekReadTypeDefRow (ctxt: ILMetadataReader) idx = ctxt.seekReadTypeDefRow idx +let seekReadTypeDefRowUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mutable addr = ctxt.rowAddr TableNames.TypeDef idx + let flags = seekReadInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let namespaceIdx = seekReadStringIdx ctxt mdv &addr + let extendsIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr + let fieldsIdx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr + let methodsIdx = seekReadUntaggedIdx TableNames.Method ctxt mdv &addr + (flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) + +/// Read Table Field. +let seekReadFieldRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Field idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let typeIdx = seekReadBlobIdx ctxt mdv &addr + (flags, nameIdx, typeIdx) + +/// Read Table Method. +let seekReadMethodRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Method idx + let codeRVA = seekReadInt32Adv mdv &addr + let implflags = seekReadUInt16AsInt32Adv mdv &addr + let flags = seekReadUInt16AsInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let typeIdx = seekReadBlobIdx ctxt mdv &addr + let paramIdx = seekReadUntaggedIdx TableNames.Param ctxt mdv &addr + (codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) + +/// Read Table Param. +let seekReadParamRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Param idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let seq = seekReadUInt16AsInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + (flags, seq, nameIdx) + +/// Read Table InterfaceImpl. +let seekReadInterfaceImplRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.InterfaceImpl idx + let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + let intfIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr + (tidx, intfIdx) + +/// Read Table MemberRef. +let seekReadMemberRefRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.MemberRef idx + let mrpIdx = seekReadMemberRefParentIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let typeIdx = seekReadBlobIdx ctxt mdv &addr + (mrpIdx, nameIdx, typeIdx) + +/// Read Table Constant. +let seekReadConstantRow (ctxt: ILMetadataReader) idx = ctxt.seekReadConstantRow idx +let seekReadConstantRowUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mutable addr = ctxt.rowAddr TableNames.Constant idx + let kind = seekReadUInt16Adv mdv &addr + let parentIdx = seekReadHasConstantIdx ctxt mdv &addr + let valIdx = seekReadBlobIdx ctxt mdv &addr + (kind, parentIdx, valIdx) + +/// Read Table CustomAttribute. +let seekReadCustomAttributeRow (ctxt: ILMetadataReader) mdv idx (attrRow: byref) = + let mutable addr = ctxt.rowAddr TableNames.CustomAttribute idx + attrRow.parentIndex <- seekReadHasCustomAttributeIdx ctxt mdv &addr + attrRow.typeIndex <- seekReadCustomAttributeTypeIdx ctxt mdv &addr + attrRow.valueIndex <- seekReadBlobIdx ctxt mdv &addr + +/// Read Table FieldMarshal. +let seekReadFieldMarshalRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.FieldMarshal idx + let parentIdx = seekReadHasFieldMarshalIdx ctxt mdv &addr + let typeIdx = seekReadBlobIdx ctxt mdv &addr + (parentIdx, typeIdx) + +/// Read Table Permission. +let seekReadPermissionRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Permission idx + let action = seekReadUInt16Adv mdv &addr + let parentIdx = seekReadHasDeclSecurityIdx ctxt mdv &addr + let typeIdx = seekReadBlobIdx ctxt mdv &addr + (action, parentIdx, typeIdx) + +/// Read Table ClassLayout. +let seekReadClassLayoutRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.ClassLayout idx + let pack = seekReadUInt16Adv mdv &addr + let size = seekReadInt32Adv mdv &addr + let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + (pack, size, tidx) + +/// Read Table FieldLayout. +let seekReadFieldLayoutRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.FieldLayout idx + let offset = seekReadInt32Adv mdv &addr + let fidx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr + (offset, fidx) + +//// Read Table StandAloneSig. +let seekReadStandAloneSigRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.StandAloneSig idx + let sigIdx = seekReadBlobIdx ctxt mdv &addr + sigIdx + +/// Read Table EventMap. +let seekReadEventMapRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.EventMap idx + let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + let eventsIdx = seekReadUntaggedIdx TableNames.Event ctxt mdv &addr + (tidx, eventsIdx) + +/// Read Table Event. +let seekReadEventRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Event idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let typIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr + (flags, nameIdx, typIdx) + +/// Read Table PropertyMap. +let seekReadPropertyMapRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.PropertyMap idx + let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + let propsIdx = seekReadUntaggedIdx TableNames.Property ctxt mdv &addr + (tidx, propsIdx) + +/// Read Table Property. +let seekReadPropertyRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Property idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let typIdx = seekReadBlobIdx ctxt mdv &addr + (flags, nameIdx, typIdx) + +/// Read Table MethodSemantics. +let seekReadMethodSemanticsRow (ctxt: ILMetadataReader) idx = ctxt.seekReadMethodSemanticsRow idx +let seekReadMethodSemanticsRowUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mutable addr = ctxt.rowAddr TableNames.MethodSemantics idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let midx = seekReadUntaggedIdx TableNames.Method ctxt mdv &addr + let assocIdx = seekReadHasSemanticsIdx ctxt mdv &addr + (flags, midx, assocIdx) + +/// Read Table MethodImpl. +let seekReadMethodImplRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.MethodImpl idx + let tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + let mbodyIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr + let mdeclIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr + (tidx, mbodyIdx, mdeclIdx) + +/// Read Table ILModuleRef. +let seekReadModuleRefRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.ModuleRef idx + let nameIdx = seekReadStringIdx ctxt mdv &addr + nameIdx + +/// Read Table ILTypeSpec. +let seekReadTypeSpecRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.TypeSpec idx + let blobIdx = seekReadBlobIdx ctxt mdv &addr + blobIdx + +/// Read Table ImplMap. +let seekReadImplMapRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.ImplMap idx + let flags = seekReadUInt16AsInt32Adv mdv &addr + let forwrdedIdx = seekReadMemberForwardedIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let scopeIdx = seekReadUntaggedIdx TableNames.ModuleRef ctxt mdv &addr + (flags, forwrdedIdx, nameIdx, scopeIdx) + +/// Read Table FieldRVA. +let seekReadFieldRVARow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.FieldRVA idx + let rva = seekReadInt32Adv mdv &addr + let fidx = seekReadUntaggedIdx TableNames.Field ctxt mdv &addr + (rva, fidx) + +/// Read Table Assembly. +let seekReadAssemblyRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.Assembly idx + let hash = seekReadInt32Adv mdv &addr + let v1 = seekReadUInt16Adv mdv &addr + let v2 = seekReadUInt16Adv mdv &addr + let v3 = seekReadUInt16Adv mdv &addr + let v4 = seekReadUInt16Adv mdv &addr + let flags = seekReadInt32Adv mdv &addr + let publicKeyIdx = seekReadBlobIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let localeIdx = seekReadStringIdx ctxt mdv &addr + (hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx) + +/// Read Table ILAssemblyRef. +let seekReadAssemblyRefRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.AssemblyRef idx + let v1 = seekReadUInt16Adv mdv &addr + let v2 = seekReadUInt16Adv mdv &addr + let v3 = seekReadUInt16Adv mdv &addr + let v4 = seekReadUInt16Adv mdv &addr + let flags = seekReadInt32Adv mdv &addr + let publicKeyOrTokenIdx = seekReadBlobIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let localeIdx = seekReadStringIdx ctxt mdv &addr + let hashValueIdx = seekReadBlobIdx ctxt mdv &addr + (v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx) + +/// Read Table File. +let seekReadFileRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.File idx + let flags = seekReadInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let hashValueIdx = seekReadBlobIdx ctxt mdv &addr + (flags, nameIdx, hashValueIdx) + +/// Read Table ILExportedTypeOrForwarder. +let seekReadExportedTypeRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.ExportedType idx + let flags = seekReadInt32Adv mdv &addr + let tok = seekReadInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let namespaceIdx = seekReadStringIdx ctxt mdv &addr + let implIdx = seekReadImplementationIdx ctxt mdv &addr + (flags, tok, nameIdx, namespaceIdx, implIdx) + +/// Read Table ManifestResource. +let seekReadManifestResourceRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.ManifestResource idx + let offset = seekReadInt32Adv mdv &addr + let flags = seekReadInt32Adv mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + let implIdx = seekReadImplementationIdx ctxt mdv &addr + (offset, flags, nameIdx, implIdx) + +/// Read Table Nested. +let seekReadNestedRow (ctxt: ILMetadataReader) idx = ctxt.seekReadNestedRow idx +let seekReadNestedRowUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mutable addr = ctxt.rowAddr TableNames.Nested idx + let nestedIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + let enclIdx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr + (nestedIdx, enclIdx) + +/// Read Table GenericParam. +let seekReadGenericParamRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.GenericParam idx + let seq = seekReadUInt16Adv mdv &addr + let flags = seekReadUInt16Adv mdv &addr + let ownerIdx = seekReadTypeOrMethodDefIdx ctxt mdv &addr + let nameIdx = seekReadStringIdx ctxt mdv &addr + (idx, seq, flags, ownerIdx, nameIdx) + +// Read Table GenericParamConstraint. +let seekReadGenericParamConstraintRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.GenericParamConstraint idx + let pidx = seekReadUntaggedIdx TableNames.GenericParam ctxt mdv &addr + let constraintIdx = seekReadTypeDefOrRefOrSpecIdx ctxt mdv &addr + (pidx, constraintIdx) + +/// Read Table ILMethodSpec. +let seekReadMethodSpecRow (ctxt: ILMetadataReader) mdv idx = + let mutable addr = ctxt.rowAddr TableNames.MethodSpec idx + let mdorIdx = seekReadMethodDefOrRefIdx ctxt mdv &addr + let instIdx = seekReadBlobIdx ctxt mdv &addr + (mdorIdx, instIdx) + + +let readUserStringHeapUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + seekReadUserString mdv (ctxt.userStringsStreamPhysicalLoc + idx) + +let readUserStringHeap (ctxt: ILMetadataReader) idx = ctxt.readUserStringHeap idx + +let readStringHeapUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + seekReadUTF8String mdv (ctxt.stringsStreamPhysicalLoc + idx) + +let readStringHeap (ctxt: ILMetadataReader) idx = ctxt.readStringHeap idx + +let readStringHeapOption (ctxt: ILMetadataReader) idx = if idx = 0 then None else Some (readStringHeap ctxt idx) + +let readBlobHeapUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + // valid index lies in range [1..streamSize) + // NOTE: idx cannot be 0 - Blob\String heap has first empty element that mdv one byte 0 + if idx <= 0 || idx >= ctxt.blobsStreamSize then [| |] + else seekReadBlob mdv (ctxt.blobsStreamPhysicalLoc + idx) + +let readBlobHeap (ctxt: ILMetadataReader) idx = ctxt.readBlobHeap idx + +let readBlobHeapOption ctxt idx = if idx = 0 then None else Some (readBlobHeap ctxt idx) + +//let readGuidHeap ctxt idx = seekReadGuid ctxt.mdv (ctxt.guidsStreamPhysicalLoc + idx) + +// read a single value out of a blob heap using the given function +let readBlobHeapAsBool ctxt vidx = fst (sigptrGetBool (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsSByte ctxt vidx = fst (sigptrGetSByte (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsInt16 ctxt vidx = fst (sigptrGetInt16 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsInt32 ctxt vidx = fst (sigptrGetInt32 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsInt64 ctxt vidx = fst (sigptrGetInt64 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsByte ctxt vidx = fst (sigptrGetByte (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsUInt16 ctxt vidx = fst (sigptrGetUInt16 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsUInt32 ctxt vidx = fst (sigptrGetUInt32 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsUInt64 ctxt vidx = fst (sigptrGetUInt64 (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsSingle ctxt vidx = fst (sigptrGetSingle (readBlobHeap ctxt vidx) 0) +let readBlobHeapAsDouble ctxt vidx = fst (sigptrGetDouble (readBlobHeap ctxt vidx) 0) + +//----------------------------------------------------------------------- +// Some binaries have raw data embedded their text sections, e.g. mscorlib, for +// field inits. And there is no information that definitively tells us the extent of +// the text section that may be interesting data. But we certainly don't want to duplicate +// the entire text section as data! +// +// So, we assume: +// 1. no part of the metadata is double-used for raw data +// 2. the data bits are all the bits of the text section +// that stretch from a Field or Resource RVA to one of +// (a) the next Field or resource RVA +// (b) a MethodRVA +// (c) the start of the metadata +// (d) the end of a section +// (e) the start of the native resources attached to the binary if any +// ----------------------------------------------------------------------*) + +// noFileOnDisk indicates that the PE file was read from Memory using OpenILModuleReaderFromBytes +// For example the assembly came from a type provider +// In this case we eagerly read the native resources into memory +let readNativeResources (pectxt: PEReader) = + [ if pectxt.nativeResourcesSize <> 0x0 && pectxt.nativeResourcesAddr <> 0x0 then + let start = pectxt.anyV2P (pectxt.fileName + ": native resources", pectxt.nativeResourcesAddr) + if pectxt.noFileOnDisk then + let unlinkedResource = + let linkedResource = seekReadBytes (pectxt.pefile.GetView()) start pectxt.nativeResourcesSize + unlinkResource pectxt.nativeResourcesAddr linkedResource + yield ILNativeResource.Out unlinkedResource + else + yield ILNativeResource.In (pectxt.fileName, pectxt.nativeResourcesAddr, start, pectxt.nativeResourcesSize ) ] + + +let getDataEndPointsDelayed (pectxt: PEReader) ctxtH = + lazy + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let dataStartPoints = + [ for i = 1 to ctxt.getNumRows TableNames.FieldRVA do + let rva, _fidx = seekReadFieldRVARow ctxt mdv i + ("field", rva) + for i = 1 to ctxt.getNumRows TableNames.ManifestResource do + let offset, _, _, TaggedIndex(_tag, idx) = seekReadManifestResourceRow ctxt mdv i + if idx = 0 then + let rva = pectxt.resourcesAddr + offset + ("manifest resource", rva) ] + + if isNil dataStartPoints then [] + else + let methodRVAs = + [ for i = 1 to ctxt.getNumRows TableNames.Method do + let rva, _, _, nameIdx, _, _ = seekReadMethodRow ctxt mdv i + if rva <> 0 then + let nm = readStringHeap ctxt nameIdx + (nm, rva) ] + ([ pectxt.textSegmentPhysicalLoc + pectxt.textSegmentPhysicalSize + pectxt.dataSegmentPhysicalLoc + pectxt.dataSegmentPhysicalSize ] + @ + (List.map pectxt.anyV2P + (dataStartPoints + @ [for virtAddr, _virtSize, _physLoc in pectxt.sectionHeaders do yield ("section start", virtAddr) done] + @ [("md", pectxt.metadataAddr)] + @ (if pectxt.nativeResourcesAddr = 0x0 then [] else [("native resources", pectxt.nativeResourcesAddr) ]) + @ (if pectxt.resourcesAddr = 0x0 then [] else [("managed resources", pectxt.resourcesAddr) ]) + @ (if pectxt.strongnameAddr = 0x0 then [] else [("managed strongname", pectxt.strongnameAddr) ]) + @ (if pectxt.vtableFixupsAddr = 0x0 then [] else [("managed vtable_fixups", pectxt.vtableFixupsAddr) ]) + @ methodRVAs))) + |> List.distinct + |> List.sort + + +let rvaToData (ctxt: ILMetadataReader) (pectxt: PEReader) nm rva = + if rva = 0x0 then failwith "rva is zero" + let start = pectxt.anyV2P (nm, rva) + let endPoints = (Lazy.force ctxt.dataEndPoints) + let rec look l = + match l with + | [] -> + failwithf "find_text_data_extent: none found for fileName=%s, name=%s, rva=0x%08x, start=0x%08x" ctxt.fileName nm rva start + | e :: t -> + if start < e then + let pev = pectxt.pefile.GetView() + seekReadBytes pev start (e - start) + else look t + look endPoints + + +//----------------------------------------------------------------------- +// Read the AbsIL structure (lazily) by reading off the relevant rows. +// ---------------------------------------------------------------------- + +let isSorted (ctxt: ILMetadataReader) (tab: TableName) = ((ctxt.sorted &&& (int64 1 <<< tab.Index)) <> int64 0x0) + +// Note, pectxtEager and pevEager must not be captured by the results of this function +let rec seekReadModule (ctxt: ILMetadataReader) canReduceMemory (pectxtEager: PEReader) pevEager peinfo ilMetadataVersion idx = + let subsys, subsysversion, useHighEntropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal = peinfo + let mdv = ctxt.mdfile.GetView() + let _generation, nameIdx, _mvidIdx, _encidIdx, _encbaseidIdx = seekReadModuleRow ctxt mdv idx + let ilModuleName = readStringHeap ctxt nameIdx + let nativeResources = readNativeResources pectxtEager + + { Manifest = + if ctxt.getNumRows TableNames.Assembly > 0 then Some (seekReadAssemblyManifest ctxt pectxtEager 1) + else None + CustomAttrsStored = ctxt.customAttrsReader_Module + MetadataIndex = idx + Name = ilModuleName + NativeResources=nativeResources + TypeDefs = mkILTypeDefsComputed (fun () -> seekReadTopTypeDefs ctxt) + SubSystemFlags = int32 subsys + IsILOnly = ilOnly + SubsystemVersion = subsysversion + UseHighEntropyVA = useHighEntropyVA + Platform = platform + StackReserveSize = None // TODO + Is32Bit = only32 + Is32BitPreferred = is32bitpreferred + Is64Bit = only64 + IsDLL=isDll + VirtualAlignment = alignVirt + PhysicalAlignment = alignPhys + ImageBase = imageBaseReal + MetadataVersion = ilMetadataVersion + Resources = seekReadManifestResources ctxt canReduceMemory mdv pectxtEager pevEager } + +and seekReadAssemblyManifest (ctxt: ILMetadataReader) pectxt idx = + let mdview = ctxt.mdfile.GetView() + let hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx = seekReadAssemblyRow ctxt mdview idx + let name = readStringHeap ctxt nameIdx + let pubkey = readBlobHeapOption ctxt publicKeyIdx + { Name= name + AuxModuleHashAlgorithm=hash + SecurityDeclsStored= ctxt.securityDeclsReader_Assembly + PublicKey= pubkey + Version= Some (ILVersionInfo (v1, v2, v3, v4)) + Locale= readStringHeapOption ctxt localeIdx + CustomAttrsStored = ctxt.customAttrsReader_Assembly + MetadataIndex = idx + AssemblyLongevity = + let masked = flags &&& 0x000e + if masked = 0x0000 then ILAssemblyLongevity.Unspecified + elif masked = 0x0002 then ILAssemblyLongevity.Library + elif masked = 0x0004 then ILAssemblyLongevity.PlatformAppDomain + elif masked = 0x0006 then ILAssemblyLongevity.PlatformProcess + elif masked = 0x0008 then ILAssemblyLongevity.PlatformSystem + else ILAssemblyLongevity.Unspecified + ExportedTypes= seekReadTopExportedTypes ctxt + EntrypointElsewhere= + let tab, tok = pectxt.entryPointToken + if tab = TableNames.File then Some (seekReadFile ctxt mdview tok) else None + Retargetable = 0 <> (flags &&& 0x100) + DisableJitOptimizations = 0 <> (flags &&& 0x4000) + JitTracking = 0 <> (flags &&& 0x8000) + IgnoreSymbolStoreSequencePoints = 0 <> (flags &&& 0x2000) } + +and seekReadAssemblyRef (ctxt: ILMetadataReader) idx = ctxt.seekReadAssemblyRef idx +and seekReadAssemblyRefUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx = seekReadAssemblyRefRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + let publicKey = + match readBlobHeapOption ctxt publicKeyOrTokenIdx with + | None -> None + | Some blob -> Some (if (flags &&& 0x0001) <> 0x0 then PublicKey blob else PublicKeyToken blob) + + ILAssemblyRef.Create + (name = nm, + hash = readBlobHeapOption ctxt hashValueIdx, + publicKey = publicKey, + retargetable = ((flags &&& 0x0100) <> 0x0), + version = Some (ILVersionInfo (v1, v2, v3, v4)), + locale = readStringHeapOption ctxt localeIdx) + +and seekReadModuleRef (ctxt: ILMetadataReader) mdv idx = + let nameIdx = seekReadModuleRefRow ctxt mdv idx + ILModuleRef.Create(name = readStringHeap ctxt nameIdx, hasMetadata=true, hash=None) + +and seekReadFile (ctxt: ILMetadataReader) mdv idx = + let flags, nameIdx, hashValueIdx = seekReadFileRow ctxt mdv idx + ILModuleRef.Create(name = readStringHeap ctxt nameIdx, hasMetadata= ((flags &&& 0x0001) = 0x0), hash= readBlobHeapOption ctxt hashValueIdx) + +and seekReadClassLayout (ctxt: ILMetadataReader) mdv idx = + let res = + seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.ClassLayout, + seekReadClassLayoutRow ctxt mdv, + (fun (_, _, tidx) -> tidx), + simpleIndexCompare idx, + isSorted ctxt TableNames.ClassLayout, + (fun (pack, size, _) -> pack, size)) + match res with + | None -> { Size = None; Pack = None } + | Some (pack, size) -> { Size = Some size; Pack = Some pack } + +and typeAccessOfFlags flags = + let f = (flags &&& 0x00000007) + if f = 0x00000001 then ILTypeDefAccess.Public + elif f = 0x00000002 then ILTypeDefAccess.Nested ILMemberAccess.Public + elif f = 0x00000003 then ILTypeDefAccess.Nested ILMemberAccess.Private + elif f = 0x00000004 then ILTypeDefAccess.Nested ILMemberAccess.Family + elif f = 0x00000006 then ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly + elif f = 0x00000007 then ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly + elif f = 0x00000005 then ILTypeDefAccess.Nested ILMemberAccess.Assembly + else ILTypeDefAccess.Private + +and typeLayoutOfFlags (ctxt: ILMetadataReader) mdv flags tidx = + let f = (flags &&& 0x00000018) + if f = 0x00000008 then ILTypeDefLayout.Sequential (seekReadClassLayout ctxt mdv tidx) + elif f = 0x00000010 then ILTypeDefLayout.Explicit (seekReadClassLayout ctxt mdv tidx) + else ILTypeDefLayout.Auto + +and isTopTypeDef flags = + (typeAccessOfFlags flags = ILTypeDefAccess.Private) || + typeAccessOfFlags flags = ILTypeDefAccess.Public + +and seekIsTopTypeDefOfIdx ctxt idx = + let flags, _, _, _, _, _ = seekReadTypeDefRow ctxt idx + isTopTypeDef flags + +and readBlobHeapAsSplitTypeName ctxt (nameIdx, namespaceIdx) = + let name = readStringHeap ctxt nameIdx + let nspace = readStringHeapOption ctxt namespaceIdx + match nspace with + | Some nspace -> splitNamespace nspace, name + | None -> [], name + +and readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) = + let name = readStringHeap ctxt nameIdx + let nspace = readStringHeapOption ctxt namespaceIdx + match nspace with + | None -> name + | Some ns -> ctxt.memoizeString (ns+"."+name) + +and seekReadTypeDefRowExtents (ctxt: ILMetadataReader) _info (idx: int) = + if idx >= ctxt.getNumRows TableNames.TypeDef then + struct (ctxt.getNumRows TableNames.Field + 1, ctxt.getNumRows TableNames.Method + 1) + else + let _, _, _, _, fieldsIdx, methodsIdx = seekReadTypeDefRow ctxt (idx + 1) + struct (fieldsIdx, methodsIdx ) + +and seekReadTypeDefRowWithExtents ctxt (idx: int) = + let info= seekReadTypeDefRow ctxt idx + info, seekReadTypeDefRowExtents ctxt info idx + +and seekReadPreTypeDef ctxt toponly (idx: int) = + let flags, nameIdx, namespaceIdx, _, _, _ = seekReadTypeDefRow ctxt idx + if toponly && not (isTopTypeDef flags) then None + else + let ns, n = readBlobHeapAsSplitTypeName ctxt (nameIdx, namespaceIdx) + // Return the ILPreTypeDef + Some (mkILPreTypeDefRead (ns, n, idx, ctxt.typeDefReader)) + +and typeDefReader ctxtH: ILTypeDefStored = + mkILTypeDefReader + (fun idx -> + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + // Re-read so as not to save all these in the lazy closure - this suspension ctxt.is the largest + // heavily allocated one in all of AbsIL + + let flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx as info = seekReadTypeDefRow ctxt idx + let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + let struct (endFieldsIdx, endMethodsIdx) = seekReadTypeDefRowExtents ctxt info idx + let typars = seekReadGenericParams ctxt 0 (tomd_TypeDef, idx) + let numtypars = typars.Length + let super = seekReadOptionalTypeDefOrRef ctxt numtypars AsObject extendsIdx + let layout = typeLayoutOfFlags ctxt mdv flags idx + let hasLayout = (match layout with ILTypeDefLayout.Explicit _ -> true | _ -> false) + let mdefs = seekReadMethods ctxt numtypars methodsIdx endMethodsIdx + let fdefs = seekReadFields ctxt (numtypars, hasLayout) fieldsIdx endFieldsIdx + let nested = seekReadNestedTypeDefs ctxt idx + let impls = seekReadInterfaceImpls ctxt mdv numtypars idx + let mimpls = seekReadMethodImpls ctxt numtypars idx + let props = seekReadProperties ctxt numtypars idx + let events = seekReadEvents ctxt numtypars idx + ILTypeDef(name=nm, + genericParams=typars, + attributes= enum(flags), + layout = layout, + nestedTypes= nested, + implements = impls, + extends = super, + methods = mdefs, + securityDeclsStored = ctxt.securityDeclsReader_TypeDef, + fields=fdefs, + methodImpls=mimpls, + events= events, + properties=props, + customAttrsStored=ctxt.customAttrsReader_TypeDef, + metadataIndex=idx) + ) + +and seekReadTopTypeDefs (ctxt: ILMetadataReader) = + [| for i = 1 to ctxt.getNumRows TableNames.TypeDef do + match seekReadPreTypeDef ctxt true i with + | None -> () + | Some td -> yield td |] + +and seekReadNestedTypeDefs (ctxt: ILMetadataReader) tidx = + mkILTypeDefsComputed (fun () -> + let nestedIdxs = seekReadIndexedRows (ctxt.getNumRows TableNames.Nested, seekReadNestedRow ctxt, snd, simpleIndexCompare tidx, false, fst) + [| for i in nestedIdxs do + match seekReadPreTypeDef ctxt false i with + | None -> () + | Some td -> yield td |]) + +and seekReadInterfaceImpls (ctxt: ILMetadataReader) mdv numtypars tidx = + seekReadIndexedRows (ctxt.getNumRows TableNames.InterfaceImpl, + seekReadInterfaceImplRow ctxt mdv, + fst, + simpleIndexCompare tidx, + isSorted ctxt TableNames.InterfaceImpl, + (snd >> seekReadTypeDefOrRef ctxt numtypars AsObject (*ok*) [])) + +and seekReadGenericParams ctxt numtypars (a, b): ILGenericParameterDefs = + ctxt.seekReadGenericParams (GenericParamsIdx(numtypars, a, b)) + +and seekReadGenericParamsUncached ctxtH (GenericParamsIdx(numtypars, a, b)) = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let pars = + seekReadIndexedRows + (ctxt.getNumRows TableNames.GenericParam, seekReadGenericParamRow ctxt mdv, + (fun (_, _, _, tomd, _) -> tomd), + tomdCompare (TaggedIndex(a, b)), + isSorted ctxt TableNames.GenericParam, + (fun (gpidx, seq, flags, _, nameIdx) -> + let flags = int32 flags + let variance_flags = flags &&& 0x0003 + let variance = + if variance_flags = 0x0000 then NonVariant + elif variance_flags = 0x0001 then CoVariant + elif variance_flags = 0x0002 then ContraVariant + else NonVariant + let constraints = seekReadGenericParamConstraints ctxt mdv numtypars gpidx + seq, {Name=readStringHeap ctxt nameIdx + Constraints = constraints + Variance=variance + CustomAttrsStored = ctxt.customAttrsReader_GenericParam + MetadataIndex=gpidx + HasReferenceTypeConstraint= (flags &&& 0x0004) <> 0 + HasNotNullableValueTypeConstraint= (flags &&& 0x0008) <> 0 + HasDefaultConstructorConstraint=(flags &&& 0x0010) <> 0 })) + pars |> List.sortBy fst |> List.map snd + +and seekReadGenericParamConstraints (ctxt: ILMetadataReader) mdv numtypars gpidx = + seekReadIndexedRows + (ctxt.getNumRows TableNames.GenericParamConstraint, + seekReadGenericParamConstraintRow ctxt mdv, + fst, + simpleIndexCompare gpidx, + isSorted ctxt TableNames.GenericParamConstraint, + (snd >> seekReadTypeDefOrRef ctxt numtypars AsObject (*ok*) List.empty)) + +and seekReadTypeDefAsType (ctxt: ILMetadataReader) boxity (ginst: ILTypes) idx = + ctxt.seekReadTypeDefAsType (TypeDefAsTypIdx (boxity, ginst, idx)) + +and seekReadTypeDefAsTypeUncached ctxtH (TypeDefAsTypIdx (boxity, ginst, idx)) = + let ctxt = getHole ctxtH + mkILTy boxity (ILTypeSpec.Create(seekReadTypeDefAsTypeRef ctxt idx, ginst)) + +and seekReadTypeDefAsTypeRef (ctxt: ILMetadataReader) idx = + let enc = + if seekIsTopTypeDefOfIdx ctxt idx then [] + else + let enclIdx = seekReadIndexedRow (ctxt.getNumRows TableNames.Nested, seekReadNestedRow ctxt, fst, simpleIndexCompare idx, isSorted ctxt TableNames.Nested, snd) + let tref = seekReadTypeDefAsTypeRef ctxt enclIdx + tref.Enclosing@[tref.Name] + let _, nameIdx, namespaceIdx, _, _, _ = seekReadTypeDefRow ctxt idx + let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + ILTypeRef.Create(scope=ILScopeRef.Local, enclosing=enc, name = nm ) + +and seekReadTypeRef (ctxt: ILMetadataReader) idx = ctxt.seekReadTypeRef idx +and seekReadTypeRefUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let scopeIdx, nameIdx, namespaceIdx = seekReadTypeRefRow ctxt mdv idx + let scope, enc = seekReadTypeRefScope ctxt mdv scopeIdx + let nm = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + ILTypeRef.Create(scope=scope, enclosing=enc, name = nm) + +and seekReadTypeRefAsType (ctxt: ILMetadataReader) boxity ginst idx = ctxt.seekReadTypeRefAsType (TypeRefAsTypIdx (boxity, ginst, idx)) +and seekReadTypeRefAsTypeUncached ctxtH (TypeRefAsTypIdx (boxity, ginst, idx)) = + let ctxt = getHole ctxtH + mkILTy boxity (ILTypeSpec.Create(seekReadTypeRef ctxt idx, ginst)) + +and seekReadTypeDefOrRef (ctxt: ILMetadataReader) numtypars boxity (ginst: ILTypes) (TaggedIndex(tag, idx) ) = + let mdv = ctxt.mdfile.GetView() + match tag with + | tag when tag = tdor_TypeDef -> seekReadTypeDefAsType ctxt boxity ginst idx + | tag when tag = tdor_TypeRef -> seekReadTypeRefAsType ctxt boxity ginst idx + | tag when tag = tdor_TypeSpec -> + if not (List.isEmpty ginst) then dprintn "type spec used as type constructor for a generic instantiation: ignoring instantiation" + readBlobHeapAsType ctxt numtypars (seekReadTypeSpecRow ctxt mdv idx) + | _ -> failwith "seekReadTypeDefOrRef ctxt" + +and seekReadTypeDefOrRefAsTypeRef (ctxt: ILMetadataReader) (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = tdor_TypeDef -> seekReadTypeDefAsTypeRef ctxt idx + | tag when tag = tdor_TypeRef -> seekReadTypeRef ctxt idx + | tag when tag = tdor_TypeSpec -> + dprintn "type spec used where a type ref or def is required" + PrimaryAssemblyILGlobals.typ_Object.TypeRef + | _ -> failwith "seekReadTypeDefOrRefAsTypeRef_readTypeDefOrRefOrSpec" + +and seekReadMethodRefParent (ctxt: ILMetadataReader) mdv numtypars (TaggedIndex(tag, idx)) = + match tag with + | tag when tag = mrp_TypeRef -> seekReadTypeRefAsType ctxt AsObject (* not ok - no way to tell if a member ref parent is a value type or not *) List.empty idx + | tag when tag = mrp_ModuleRef -> mkILTypeForGlobalFunctions (ILScopeRef.Module (seekReadModuleRef ctxt mdv idx)) + | tag when tag = mrp_MethodDef -> + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx + let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + mspec.DeclaringType + | tag when tag = mrp_TypeSpec -> readBlobHeapAsType ctxt numtypars (seekReadTypeSpecRow ctxt mdv idx) + | _ -> failwith "seekReadMethodRefParent" + +and seekReadMethodDefOrRef (ctxt: ILMetadataReader) numtypars (TaggedIndex(tag, idx)) = + match tag with + | tag when tag = mdor_MethodDef -> + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx + VarArgMethodData(enclTy, cc, nm, argtys, None, retty, minst) + | tag when tag = mdor_MemberRef -> + seekReadMemberRefAsMethodData ctxt numtypars idx + | _ -> failwith "seekReadMethodDefOrRef" + +and seekReadMethodDefOrRefNoVarargs (ctxt: ILMetadataReader) numtypars x = + let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = seekReadMethodDefOrRef ctxt numtypars x + if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" + MethodData(enclTy, cc, nm, argtys, retty, minst) + +and seekReadCustomAttrType (ctxt: ILMetadataReader) (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = cat_MethodDef -> + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt idx + mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + | tag when tag = cat_MemberRef -> + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMemberRefAsMethDataNoVarArgs ctxt 0 idx + mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + | _ -> failwith "seekReadCustomAttrType ctxt" + +and seekReadImplAsScopeRef (ctxt: ILMetadataReader) mdv (TaggedIndex(tag, idx) ) = + if idx = 0 then ILScopeRef.Local + else + match tag with + | tag when tag = i_File -> ILScopeRef.Module (seekReadFile ctxt mdv idx) + | tag when tag = i_AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef ctxt idx) + | tag when tag = i_ExportedType -> failwith "seekReadImplAsScopeRef" + | _ -> failwith "seekReadImplAsScopeRef" + +and seekReadTypeRefScope (ctxt: ILMetadataReader) mdv (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = rs_Module -> ILScopeRef.Local, [] + | tag when tag = rs_ModuleRef -> ILScopeRef.Module (seekReadModuleRef ctxt mdv idx), [] + | tag when tag = rs_AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef ctxt idx), [] + | tag when tag = rs_TypeRef -> + let tref = seekReadTypeRef ctxt idx + tref.Scope, (tref.Enclosing@[tref.Name]) + | _ -> failwith "seekReadTypeRefScope" + +and seekReadOptionalTypeDefOrRef (ctxt: ILMetadataReader) numtypars boxity idx = + if idx = TaggedIndex(tdor_TypeDef, 0) then None + else Some (seekReadTypeDefOrRef ctxt numtypars boxity List.empty idx) + +and seekReadField ctxt mdv (numtypars, hasLayout) (idx: int) = + let flags, nameIdx, typeIdx = seekReadFieldRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + let isStatic = (flags &&& 0x0010) <> 0 + ILFieldDef(name = nm, + fieldType= readBlobHeapAsFieldSig ctxt numtypars typeIdx, + attributes = enum(flags), + literalValue = (if (flags &&& 0x8000) = 0 then None else Some (seekReadConstant ctxt (TaggedIndex(hc_FieldDef, idx)))), + marshal = + (if (flags &&& 0x1000) = 0 then + None + else + Some (seekReadIndexedRow (ctxt.getNumRows TableNames.FieldMarshal, seekReadFieldMarshalRow ctxt mdv, + fst, hfmCompare (TaggedIndex(hfm_FieldDef, idx)), + isSorted ctxt TableNames.FieldMarshal, + (snd >> readBlobHeapAsNativeType ctxt)))), + data = + (if (flags &&& 0x0100) = 0 then + None + else + match ctxt.pectxtCaptured with + | None -> None // indicates metadata only, where Data is not available + | Some pectxt -> + let rva = seekReadIndexedRow (ctxt.getNumRows TableNames.FieldRVA, seekReadFieldRVARow ctxt mdv, + snd, simpleIndexCompare idx, isSorted ctxt TableNames.FieldRVA, fst) + Some (rvaToData ctxt pectxt "field" rva)), + offset = + (if hasLayout && not isStatic then + Some (seekReadIndexedRow (ctxt.getNumRows TableNames.FieldLayout, seekReadFieldLayoutRow ctxt mdv, + snd, simpleIndexCompare idx, isSorted ctxt TableNames.FieldLayout, fst)) else None), + customAttrsStored=ctxt.customAttrsReader_FieldDef, + metadataIndex = idx) + +and seekReadFields (ctxt: ILMetadataReader) (numtypars, hasLayout) fidx1 fidx2 = + mkILFieldsLazy + (lazy + let mdv = ctxt.mdfile.GetView() + [ if fidx1 > 0 then + for i = fidx1 to fidx2 - 1 do + yield seekReadField ctxt mdv (numtypars, hasLayout) i ]) + +and seekReadMethods (ctxt: ILMetadataReader) numtypars midx1 midx2 = + mkILMethodsComputed (fun () -> + let mdv = ctxt.mdfile.GetView() + [| if midx1 > 0 then + for i = midx1 to midx2 - 1 do + yield seekReadMethod ctxt mdv numtypars i |]) + +and sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr = + let struct (n, sigptr) = sigptrGetZInt32 bytes sigptr + if (n &&& 0x01) = 0x0 then (* Type Def *) + TaggedIndex(tdor_TypeDef, (n >>>& 2)), sigptr + else (* Type Ref *) + TaggedIndex(tdor_TypeRef, (n >>>& 2)), sigptr + +and sigptrGetTy (ctxt: ILMetadataReader) numtypars bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + if b0 = et_OBJECT then PrimaryAssemblyILGlobals.typ_Object, sigptr + elif b0 = et_STRING then PrimaryAssemblyILGlobals.typ_String, sigptr + elif b0 = et_I1 then PrimaryAssemblyILGlobals.typ_SByte, sigptr + elif b0 = et_I2 then PrimaryAssemblyILGlobals.typ_Int16, sigptr + elif b0 = et_I4 then PrimaryAssemblyILGlobals.typ_Int32, sigptr + elif b0 = et_I8 then PrimaryAssemblyILGlobals.typ_Int64, sigptr + elif b0 = et_I then PrimaryAssemblyILGlobals.typ_IntPtr, sigptr + elif b0 = et_U1 then PrimaryAssemblyILGlobals.typ_Byte, sigptr + elif b0 = et_U2 then PrimaryAssemblyILGlobals.typ_UInt16, sigptr + elif b0 = et_U4 then PrimaryAssemblyILGlobals.typ_UInt32, sigptr + elif b0 = et_U8 then PrimaryAssemblyILGlobals.typ_UInt64, sigptr + elif b0 = et_U then PrimaryAssemblyILGlobals.typ_UIntPtr, sigptr + elif b0 = et_R4 then PrimaryAssemblyILGlobals.typ_Single, sigptr + elif b0 = et_R8 then PrimaryAssemblyILGlobals.typ_Double, sigptr + elif b0 = et_CHAR then PrimaryAssemblyILGlobals.typ_Char, sigptr + elif b0 = et_BOOLEAN then PrimaryAssemblyILGlobals.typ_Bool, sigptr + elif b0 = et_WITH then + let b0, sigptr = sigptrGetByte bytes sigptr + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let struct (n, sigptr) = sigptrGetZInt32 bytes sigptr + let argtys, sigptr = sigptrFold (sigptrGetTy ctxt numtypars) n bytes sigptr + seekReadTypeDefOrRef ctxt numtypars (if b0 = et_CLASS then AsObject else AsValue) argtys tdorIdx, + sigptr + + elif b0 = et_CLASS then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef ctxt numtypars AsObject List.empty tdorIdx, sigptr + elif b0 = et_VALUETYPE then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef ctxt numtypars AsValue List.empty tdorIdx, sigptr + elif b0 = et_VAR then + let struct (n, sigptr) = sigptrGetZInt32 bytes sigptr + ILType.TypeVar (uint16 n), sigptr + elif b0 = et_MVAR then + let struct (n, sigptr) = sigptrGetZInt32 bytes sigptr + ILType.TypeVar (uint16 (n + numtypars)), sigptr + elif b0 = et_BYREF then + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + ILType.Byref ty, sigptr + elif b0 = et_PTR then + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + ILType.Ptr ty, sigptr + elif b0 = et_SZARRAY then + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + mkILArr1DTy ty, sigptr + elif b0 = et_ARRAY then + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + let struct (rank, sigptr) = sigptrGetZInt32 bytes sigptr + let struct (numSized, sigptr) = sigptrGetZInt32 bytes sigptr + let struct (sizes, sigptr) = sigptrFoldStruct sigptrGetZInt32 numSized bytes sigptr + let struct (numLoBounded, sigptr) = sigptrGetZInt32 bytes sigptr + let struct (lobounds, sigptr) = sigptrFoldStruct sigptrGetZInt32 numLoBounded bytes sigptr + let shape = + let dim i = + (if i < numLoBounded then Some (List.item i lobounds) else None), + (if i < numSized then Some (List.item i sizes) else None) + ILArrayShape (List.init rank dim) + mkILArrTy (ty, shape), sigptr + + elif b0 = et_VOID then ILType.Void, sigptr + elif b0 = et_TYPEDBYREF then + PrimaryAssemblyILGlobals.typ_TypedReference, sigptr + elif b0 = et_CMOD_REQD || b0 = et_CMOD_OPT then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + ILType.Modified((b0 = et_CMOD_REQD), seekReadTypeDefOrRefAsTypeRef ctxt tdorIdx, ty), sigptr + elif b0 = et_FNPTR then + let ccByte, sigptr = sigptrGetByte bytes sigptr + let generic, cc = byteAsCallConv ccByte + if generic then failwith "fptr sig may not be generic" + let struct (numparams, sigptr) = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + let argtys, sigptr = sigptrFold (sigptrGetTy ctxt numtypars) numparams bytes sigptr + let typ = + ILType.FunctionPointer + { CallingConv=cc + ArgTypes = argtys + ReturnType=retty } + typ, sigptr + elif b0 = et_SENTINEL then failwith "varargs NYI" + else ILType.Void, sigptr + +and sigptrGetVarArgTys (ctxt: ILMetadataReader) n numtypars bytes sigptr = + sigptrFold (sigptrGetTy ctxt numtypars) n bytes sigptr + +and sigptrGetArgTys (ctxt: ILMetadataReader) n numtypars bytes sigptr acc = + if n <= 0 then (List.rev acc, None), sigptr + else + let b0, sigptr2 = sigptrGetByte bytes sigptr + if b0 = et_SENTINEL then + let varargs, sigptr = sigptrGetVarArgTys ctxt n numtypars bytes sigptr2 + (List.rev acc, Some varargs), sigptr + else + let x, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + sigptrGetArgTys ctxt (n-1) numtypars bytes sigptr (x :: acc) + +and sigptrGetLocal (ctxt: ILMetadataReader) numtypars bytes sigptr = + let pinned, sigptr = + let b0, sigptr' = sigptrGetByte bytes sigptr + if b0 = et_PINNED then + true, sigptr' + else + false, sigptr + let ty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + let loc: ILLocal = { IsPinned = pinned; Type = ty; DebugInfo = None } + loc, sigptr + +and readBlobHeapAsMethodSig (ctxt: ILMetadataReader) numtypars blobIdx = + ctxt.readBlobHeapAsMethodSig (BlobAsMethodSigIdx (numtypars, blobIdx)) + +and readBlobHeapAsMethodSigUncached ctxtH (BlobAsMethodSigIdx (numtypars, blobIdx)) = + let (ctxt: ILMetadataReader) = getHole ctxtH + let bytes = readBlobHeap ctxt blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + let generic, cc = byteAsCallConv ccByte + let struct (genarity, sigptr) = if generic then sigptrGetZInt32 bytes sigptr else 0x0, sigptr + let struct (numparams, sigptr) = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + let (argtys, varargs), _sigptr = sigptrGetArgTys ctxt numparams numtypars bytes sigptr [] + generic, genarity, cc, retty, argtys, varargs + +and readBlobHeapAsType ctxt numtypars blobIdx = + let bytes = readBlobHeap ctxt blobIdx + let ty, _sigptr = sigptrGetTy ctxt numtypars bytes 0 + ty + +and readBlobHeapAsFieldSig ctxt numtypars blobIdx = + ctxt.readBlobHeapAsFieldSig (BlobAsFieldSigIdx (numtypars, blobIdx)) + +and readBlobHeapAsFieldSigUncached ctxtH (BlobAsFieldSigIdx (numtypars, blobIdx)) = + let ctxt = getHole ctxtH + let bytes = readBlobHeap ctxt blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + if ccByte <> e_IMAGE_CEE_CS_CALLCONV_FIELD then dprintn "warning: field sig was not CC_FIELD" + let retty, _sigptr = sigptrGetTy ctxt numtypars bytes sigptr + retty + + +and readBlobHeapAsPropertySig (ctxt: ILMetadataReader) numtypars blobIdx = + ctxt.readBlobHeapAsPropertySig (BlobAsPropSigIdx (numtypars, blobIdx)) + +and readBlobHeapAsPropertySigUncached ctxtH (BlobAsPropSigIdx (numtypars, blobIdx)) = + let ctxt = getHole ctxtH + let bytes = readBlobHeap ctxt blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + let hasthis = byteAsHasThis ccByte + let ccMaxked = (ccByte &&& 0x0Fuy) + if ccMaxked <> e_IMAGE_CEE_CS_CALLCONV_PROPERTY then dprintn ("warning: property sig was "+string ccMaxked+" instead of CC_PROPERTY") + let struct (numparams, sigptr) = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy ctxt numtypars bytes sigptr + let argtys, _sigptr = sigptrFold (sigptrGetTy ctxt numtypars) numparams bytes sigptr + hasthis, retty, argtys + +and readBlobHeapAsLocalsSig (ctxt: ILMetadataReader) numtypars blobIdx = + ctxt.readBlobHeapAsLocalsSig (BlobAsLocalSigIdx (numtypars, blobIdx)) + +and readBlobHeapAsLocalsSigUncached ctxtH (BlobAsLocalSigIdx (numtypars, blobIdx)) = + let ctxt = getHole ctxtH + let bytes = readBlobHeap ctxt blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + if ccByte <> e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG then dprintn "warning: local sig was not CC_LOCAL" + let struct (numlocals, sigptr) = sigptrGetZInt32 bytes sigptr + let localtys, _sigptr = sigptrFold (sigptrGetLocal ctxt numtypars) numlocals bytes sigptr + localtys + +and byteAsHasThis b = + let hasthis_masked = b &&& 0x60uy + if hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE then ILThisConvention.Instance + elif hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT then ILThisConvention.InstanceExplicit + else ILThisConvention.Static + +and byteAsCallConv b = + let cc = + let ccMaxked = b &&& 0x0Fuy + if ccMaxked = e_IMAGE_CEE_CS_CALLCONV_FASTCALL then ILArgConvention.FastCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_STDCALL then ILArgConvention.StdCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_THISCALL then ILArgConvention.ThisCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_CDECL then ILArgConvention.CDecl + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_VARARG then ILArgConvention.VarArg + else ILArgConvention.Default + let generic = (b &&& e_IMAGE_CEE_CS_CALLCONV_GENERIC) <> 0x0uy + generic, Callconv (byteAsHasThis b, cc) + +and seekReadMemberRefAsMethodData ctxt numtypars idx: VarArgMethodData = + ctxt.seekReadMemberRefAsMethodData (MemberRefAsMspecIdx (numtypars, idx)) + +and seekReadMemberRefAsMethodDataUncached ctxtH (MemberRefAsMspecIdx (numtypars, idx)) = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mrpIdx, nameIdx, typeIdx = seekReadMemberRefRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + let enclTy = seekReadMethodRefParent ctxt mdv numtypars mrpIdx + let _generic, genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt enclTy.GenericArgs.Length typeIdx + let minst = List.init genarity (fun n -> mkILTyvarTy (uint16 (numtypars+n))) + (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) + +and seekReadMemberRefAsMethDataNoVarArgs ctxt numtypars idx: MethodData = + let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = seekReadMemberRefAsMethodData ctxt numtypars idx + if Option.isSome varargs then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" + (MethodData(enclTy, cc, nm, argtys, retty, minst)) + +and seekReadMethodSpecAsMethodData (ctxt: ILMetadataReader) numtypars idx = + ctxt.seekReadMethodSpecAsMethodData (MethodSpecAsMspecIdx (numtypars, idx)) + +and seekReadMethodSpecAsMethodDataUncached ctxtH (MethodSpecAsMspecIdx (numtypars, idx)) = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mdorIdx, instIdx = seekReadMethodSpecRow ctxt mdv idx + let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, _)) = seekReadMethodDefOrRef ctxt numtypars mdorIdx + let minst = + let bytes = readBlobHeap ctxt instIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + if ccByte <> e_IMAGE_CEE_CS_CALLCONV_GENERICINST then dprintn ("warning: method inst ILCallingConv was "+string ccByte+" instead of CC_GENERICINST") + let struct (numgpars, sigptr) = sigptrGetZInt32 bytes sigptr + let argtys, _sigptr = sigptrFold (sigptrGetTy ctxt numtypars) numgpars bytes sigptr + argtys + VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst) + +and seekReadMemberRefAsFieldSpec (ctxt: ILMetadataReader) numtypars idx = + ctxt.seekReadMemberRefAsFieldSpec (MemberRefAsFspecIdx (numtypars, idx)) + +and seekReadMemberRefAsFieldSpecUncached ctxtH (MemberRefAsFspecIdx (numtypars, idx)) = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let mrpIdx, nameIdx, typeIdx = seekReadMemberRefRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + let enclTy = seekReadMethodRefParent ctxt mdv numtypars mrpIdx + let retty = readBlobHeapAsFieldSig ctxt numtypars typeIdx + mkILFieldSpecInTy(enclTy, nm, retty) + +// One extremely annoying aspect of the MD format is that given a +// ILMethodDef token it is non-trivial to find which ILTypeDef it belongs +// to. So we do a binary chop through the ILTypeDef table +// looking for which ILTypeDef has the ILMethodDef within its range. +// Although the ILTypeDef table is not "sorted", it is effectively sorted by +// method-range and field-range start/finish indexes +and seekReadMethodDefAsMethodData ctxt idx = + ctxt.seekReadMethodDefAsMethodData idx + +and seekReadMethodDefAsMethodDataUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + // Look for the method def parent. + let tidx = + seekReadIndexedRow (ctxt.getNumRows TableNames.TypeDef, + (fun i -> i, seekReadTypeDefRowWithExtents ctxt i), + (fun r -> r), + (fun (_, ((_, _, _, _, _, methodsIdx), + (_, endMethodsIdx))) -> + if endMethodsIdx <= idx then 1 + elif methodsIdx <= idx && idx < endMethodsIdx then 0 + else -1), + true, fst) + // Create a formal instantiation if needed + let typeGenericArgs = seekReadGenericParams ctxt 0 (tomd_TypeDef, tidx) + let typeGenericArgsCount = typeGenericArgs.Length + + let methodGenericArgs = seekReadGenericParams ctxt typeGenericArgsCount (tomd_MethodDef, idx) + + let finst = mkILFormalGenericArgs 0 typeGenericArgs + let minst = mkILFormalGenericArgs typeGenericArgsCount methodGenericArgs + + // Read the method def parent. + let enclTy = seekReadTypeDefAsType ctxt AsObject (* not ok: see note *) finst tidx + + // Return the constituent parts: put it together at the place where this is called. + let _code_rva, _implflags, _flags, nameIdx, typeIdx, _paramIdx = seekReadMethodRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + + // Read the method def signature. + let _generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt typeGenericArgsCount typeIdx + if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" + + MethodData(enclTy, cc, nm, argtys, retty, minst) + + +and seekReadFieldDefAsFieldSpec (ctxt: ILMetadataReader) idx = + ctxt.seekReadFieldDefAsFieldSpec idx + +and seekReadFieldDefAsFieldSpecUncached ctxtH idx = + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let _flags, nameIdx, typeIdx = seekReadFieldRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + (* Look for the field def parent. *) + let tidx = + seekReadIndexedRow (ctxt.getNumRows TableNames.TypeDef, + (fun i -> i, seekReadTypeDefRowWithExtents ctxt i), + (fun r -> r), + (fun (_, ((_, _, _, _, fieldsIdx, _), (endFieldsIdx, _))) -> + if endFieldsIdx <= idx then 1 + elif fieldsIdx <= idx && idx < endFieldsIdx then 0 + else -1), + true, fst) + // Read the field signature. + let retty = readBlobHeapAsFieldSig ctxt 0 typeIdx + + // Create a formal instantiation if needed + let finst = mkILFormalGenericArgs 0 (seekReadGenericParams ctxt 0 (tomd_TypeDef, tidx)) + + // Read the field def parent. + let enclTy = seekReadTypeDefAsType ctxt AsObject (* not ok: see note *) finst tidx + + // Put it together. + mkILFieldSpecInTy(enclTy, nm, retty) + +and seekReadMethod (ctxt: ILMetadataReader) mdv numtypars (idx: int) = + let codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx = seekReadMethodRow ctxt mdv idx + let nm = readStringHeap ctxt nameIdx + let abstr = (flags &&& 0x0400) <> 0x0 + let pinvoke = (flags &&& 0x2000) <> 0x0 + let codetype = implflags &&& 0x0003 + let unmanaged = (implflags &&& 0x0004) <> 0x0 + let internalcall = (implflags &&& 0x1000) <> 0x0 + let noinline = (implflags &&& 0x0008) <> 0x0 + let aggressiveinline = (implflags &&& 0x0100) <> 0x0 + let _generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt numtypars typeIdx + if varargs <> None then dprintf "ignoring sentinel and varargs in ILMethodDef signature" + + let endParamIdx = + if idx >= ctxt.getNumRows TableNames.Method then + ctxt.getNumRows TableNames.Param + 1 + else + let _, _, _, _, _, paramIdx = seekReadMethodRow ctxt mdv (idx + 1) + paramIdx + + let ret, ilParams = seekReadParams ctxt mdv (retty, argtys) paramIdx endParamIdx + + let isEntryPoint = + let tab, tok = ctxt.entryPointToken + (tab = TableNames.Method && tok = idx) + + let body = + if (codetype = 0x01) && pinvoke then + methBodyNative + elif pinvoke then + seekReadImplMap ctxt nm idx + elif internalcall || abstr || unmanaged || (codetype <> 0x00) then + methBodyAbstract + else + match ctxt.pectxtCaptured with + | None -> methBodyNotAvailable + | Some pectxt -> seekReadMethodRVA pectxt ctxt (idx, nm, internalcall, noinline, aggressiveinline, numtypars) codeRVA + + ILMethodDef(name=nm, + attributes = enum(flags), + implAttributes= enum(implflags), + securityDeclsStored=ctxt.securityDeclsReader_MethodDef, + isEntryPoint=isEntryPoint, + genericParams=seekReadGenericParams ctxt numtypars (tomd_MethodDef, idx), + parameters= ilParams, + callingConv=cc, + ret=ret, + body=body, + customAttrsStored=ctxt.customAttrsReader_MethodDef, + metadataIndex=idx) + + +and seekReadParams (ctxt: ILMetadataReader) mdv (retty, argtys) pidx1 pidx2 = + let mutable retRes = mkILReturn retty + let paramsRes = argtys |> List.toArray |> Array.map mkILParamAnon + for i = pidx1 to pidx2 - 1 do + seekReadParamExtras ctxt mdv (&retRes, paramsRes) i + retRes, List.ofArray paramsRes + +and seekReadParamExtras (ctxt: ILMetadataReader) mdv (retRes: byref, paramsRes) (idx: int) = + let flags, seq, nameIdx = seekReadParamRow ctxt mdv idx + let inOutMasked = (flags &&& 0x00FF) + let hasMarshal = (flags &&& 0x2000) <> 0x0 + let hasDefault = (flags &&& 0x1000) <> 0x0 + let fmReader idx = seekReadIndexedRow (ctxt.getNumRows TableNames.FieldMarshal, seekReadFieldMarshalRow ctxt mdv, fst, hfmCompare idx, isSorted ctxt TableNames.FieldMarshal, (snd >> readBlobHeapAsNativeType ctxt)) + if seq = 0 then + retRes <- { retRes with + Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None) + CustomAttrsStored = ctxt.customAttrsReader_ParamDef + MetadataIndex = idx} + elif seq > Array.length paramsRes then dprintn "bad seq num. for param" + else + paramsRes.[seq - 1] <- + { paramsRes.[seq - 1] with + Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None) + Default = (if hasDefault then Some (seekReadConstant ctxt (TaggedIndex(hc_ParamDef, idx))) else None) + Name = readStringHeapOption ctxt nameIdx + IsIn = ((inOutMasked &&& 0x0001) <> 0x0) + IsOut = ((inOutMasked &&& 0x0002) <> 0x0) + IsOptional = ((inOutMasked &&& 0x0010) <> 0x0) + CustomAttrsStored = ctxt.customAttrsReader_ParamDef + MetadataIndex = idx } + +and seekReadMethodImpls (ctxt: ILMetadataReader) numtypars tidx = + mkILMethodImplsLazy + (lazy + let mdv = ctxt.mdfile.GetView() + let mimpls = seekReadIndexedRows (ctxt.getNumRows TableNames.MethodImpl, seekReadMethodImplRow ctxt mdv, (fun (a, _, _) -> a), simpleIndexCompare tidx, isSorted ctxt TableNames.MethodImpl, (fun (_, b, c) -> b, c)) + mimpls |> List.map (fun (b, c) -> + { OverrideBy= + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars b + mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + Overrides= + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars c + let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + OverridesSpec(mspec.MethodRef, mspec.DeclaringType) })) + +and seekReadMultipleMethodSemantics (ctxt: ILMetadataReader) (flags, id) = + seekReadIndexedRows + (ctxt.getNumRows TableNames.MethodSemantics, + seekReadMethodSemanticsRow ctxt, + (fun (_flags, _, c) -> c), + hsCompare id, + isSorted ctxt TableNames.MethodSemantics, + (fun (a, b, _c) -> + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData ctxt b + a, (mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst)).MethodRef)) + |> List.filter (fun (flags2, _) -> flags = flags2) + |> List.map snd + + +and seekReadOptionalMethodSemantics ctxt id = + match seekReadMultipleMethodSemantics ctxt id with + | [] -> None + | [h] -> Some h + | h :: _ -> dprintn "multiple method semantics found"; Some h + +and seekReadMethodSemantics ctxt id = + match seekReadOptionalMethodSemantics ctxt id with + | None -> failwith "seekReadMethodSemantics ctxt: no method found" + | Some x -> x + +and seekReadEvent ctxt mdv numtypars idx = + let flags, nameIdx, typIdx = seekReadEventRow ctxt mdv idx + ILEventDef(eventType = seekReadOptionalTypeDefOrRef ctxt numtypars AsObject typIdx, + name = readStringHeap ctxt nameIdx, + attributes = enum(flags), + addMethod= seekReadMethodSemantics ctxt (0x0008, TaggedIndex(hs_Event, idx)), + removeMethod=seekReadMethodSemantics ctxt (0x0010, TaggedIndex(hs_Event, idx)), + fireMethod=seekReadOptionalMethodSemantics ctxt (0x0020, TaggedIndex(hs_Event, idx)), + otherMethods = seekReadMultipleMethodSemantics ctxt (0x0004, TaggedIndex(hs_Event, idx)), + customAttrsStored=ctxt.customAttrsReader_Event, + metadataIndex = idx ) + + (* REVIEW: can substantially reduce numbers of EventMap and PropertyMap reads by first checking if the whole table mdv sorted according to ILTypeDef tokens and then doing a binary chop *) +and seekReadEvents (ctxt: ILMetadataReader) numtypars tidx = + mkILEventsLazy + (lazy + let mdv = ctxt.mdfile.GetView() + match seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.EventMap, (fun i -> i, seekReadEventMapRow ctxt mdv i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + | None -> [] + | Some (rowNum, beginEventIdx) -> + let endEventIdx = + if rowNum >= ctxt.getNumRows TableNames.EventMap then + ctxt.getNumRows TableNames.Event + 1 + else + let _, endEventIdx = seekReadEventMapRow ctxt mdv (rowNum + 1) + endEventIdx + + [ if beginEventIdx > 0 then + for i in beginEventIdx .. endEventIdx - 1 do + yield seekReadEvent ctxt mdv numtypars i ]) + +and seekReadProperty ctxt mdv numtypars idx = + let flags, nameIdx, typIdx = seekReadPropertyRow ctxt mdv idx + let cc, retty, argtys = readBlobHeapAsPropertySig ctxt numtypars typIdx + let setter= seekReadOptionalMethodSemantics ctxt (0x0001, TaggedIndex(hs_Property, idx)) + let getter = seekReadOptionalMethodSemantics ctxt (0x0002, TaggedIndex(hs_Property, idx)) +(* NOTE: the "ThisConv" value on the property is not reliable: better to look on the getter/setter *) +(* NOTE: e.g. tlbimp on Office msword.olb seems to set this incorrectly *) + let cc2 = + match getter with + | Some mref -> mref.CallingConv.ThisConv + | None -> + match setter with + | Some mref -> mref.CallingConv .ThisConv + | None -> cc + + ILPropertyDef(name=readStringHeap ctxt nameIdx, + callingConv = cc2, + attributes = enum(flags), + setMethod=setter, + getMethod=getter, + propertyType=retty, + init= (if (flags &&& 0x1000) = 0 then None else Some (seekReadConstant ctxt (TaggedIndex(hc_Property, idx)))), + args=argtys, + customAttrsStored=ctxt.customAttrsReader_Property, + metadataIndex = idx ) + +and seekReadProperties (ctxt: ILMetadataReader) numtypars tidx = + mkILPropertiesLazy + (lazy + let mdv = ctxt.mdfile.GetView() + match seekReadOptionalIndexedRow (ctxt.getNumRows TableNames.PropertyMap, (fun i -> i, seekReadPropertyMapRow ctxt mdv i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + | None -> [] + | Some (rowNum, beginPropIdx) -> + let endPropIdx = + if rowNum >= ctxt.getNumRows TableNames.PropertyMap then + ctxt.getNumRows TableNames.Property + 1 + else + let _, endPropIdx = seekReadPropertyMapRow ctxt mdv (rowNum + 1) + endPropIdx + [ if beginPropIdx > 0 then + for i in beginPropIdx .. endPropIdx - 1 do + yield seekReadProperty ctxt mdv numtypars i ]) + + +and customAttrsReader ctxtH tag: ILAttributesStored = + mkILCustomAttrsReader + (fun idx -> + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + let reader = + { new ISeekReadIndexedRowReader, ILAttribute> with + member _.GetRow(i, row) = seekReadCustomAttributeRow ctxt mdv i &row + member _.GetKey(attrRow) = attrRow.parentIndex + member _.CompareKey(key) = hcaCompare (TaggedIndex(tag, idx)) key + member _.ConvertRow(attrRow) = seekReadCustomAttr ctxt (attrRow.typeIndex, attrRow.valueIndex) + } + seekReadIndexedRowsByInterface (ctxt.getNumRows TableNames.CustomAttribute) (isSorted ctxt TableNames.CustomAttribute) reader) + +and seekReadCustomAttr ctxt (TaggedIndex(cat, idx), b) = + ctxt.seekReadCustomAttr (CustomAttrIdx (cat, idx, b)) + +and seekReadCustomAttrUncached ctxtH (CustomAttrIdx (cat, idx, valIdx)) = + let ctxt = getHole ctxtH + let method = seekReadCustomAttrType ctxt (TaggedIndex(cat, idx)) + let data = + match readBlobHeapOption ctxt valIdx with + | Some bytes -> bytes + | None -> Bytes.ofInt32Array [| |] + let elements = [] + ILAttribute.Encoded (method, data, elements) + +and securityDeclsReader ctxtH tag = + mkILSecurityDeclsReader + (fun idx -> + let (ctxt: ILMetadataReader) = getHole ctxtH + let mdv = ctxt.mdfile.GetView() + seekReadIndexedRows (ctxt.getNumRows TableNames.Permission, + seekReadPermissionRow ctxt mdv, + (fun (_, par, _) -> par), + hdsCompare (TaggedIndex(tag,idx)), + isSorted ctxt TableNames.Permission, + (fun (act, _, ty) -> seekReadSecurityDecl ctxt (act, ty))) + |> List.toArray) + +and seekReadSecurityDecl ctxt (act, ty) = + ILSecurityDecl ((if List.memAssoc (int act) (Lazy.force ILSecurityActionRevMap) then List.assoc (int act) (Lazy.force ILSecurityActionRevMap) else failwith "unknown security action"), + readBlobHeap ctxt ty) + +and seekReadConstant (ctxt: ILMetadataReader) idx = + let kind, vidx = seekReadIndexedRow (ctxt.getNumRows TableNames.Constant, + seekReadConstantRow ctxt, + (fun (_, key, _) -> key), + hcCompare idx, isSorted ctxt TableNames.Constant, (fun (kind, _, v) -> kind, v)) + match kind with + | x when x = uint16 et_STRING -> + let blobHeap = readBlobHeap ctxt vidx + let s = Encoding.Unicode.GetString(blobHeap, 0, blobHeap.Length) + ILFieldInit.String s + | x when x = uint16 et_BOOLEAN -> ILFieldInit.Bool (readBlobHeapAsBool ctxt vidx) + | x when x = uint16 et_CHAR -> ILFieldInit.Char (readBlobHeapAsUInt16 ctxt vidx) + | x when x = uint16 et_I1 -> ILFieldInit.Int8 (readBlobHeapAsSByte ctxt vidx) + | x when x = uint16 et_I2 -> ILFieldInit.Int16 (readBlobHeapAsInt16 ctxt vidx) + | x when x = uint16 et_I4 -> ILFieldInit.Int32 (readBlobHeapAsInt32 ctxt vidx) + | x when x = uint16 et_I8 -> ILFieldInit.Int64 (readBlobHeapAsInt64 ctxt vidx) + | x when x = uint16 et_U1 -> ILFieldInit.UInt8 (readBlobHeapAsByte ctxt vidx) + | x when x = uint16 et_U2 -> ILFieldInit.UInt16 (readBlobHeapAsUInt16 ctxt vidx) + | x when x = uint16 et_U4 -> ILFieldInit.UInt32 (readBlobHeapAsUInt32 ctxt vidx) + | x when x = uint16 et_U8 -> ILFieldInit.UInt64 (readBlobHeapAsUInt64 ctxt vidx) + | x when x = uint16 et_R4 -> ILFieldInit.Single (readBlobHeapAsSingle ctxt vidx) + | x when x = uint16 et_R8 -> ILFieldInit.Double (readBlobHeapAsDouble ctxt vidx) + | x when x = uint16 et_CLASS || x = uint16 et_OBJECT -> ILFieldInit.Null + | _ -> ILFieldInit.Null + +and seekReadImplMap (ctxt: ILMetadataReader) nm midx = + lazy + MethodBody.PInvoke + (lazy + let mdv = ctxt.mdfile.GetView() + let flags, nameIdx, scopeIdx = seekReadIndexedRow (ctxt.getNumRows TableNames.ImplMap, + seekReadImplMapRow ctxt mdv, + (fun (_, m, _, _) -> m), + mfCompare (TaggedIndex(mf_MethodDef, midx)), + isSorted ctxt TableNames.ImplMap, + (fun (a, _, c, d) -> a, c, d)) + let cc = + let masked = flags &&& 0x0700 + if masked = 0x0000 then PInvokeCallingConvention.None + elif masked = 0x0200 then PInvokeCallingConvention.Cdecl + elif masked = 0x0300 then PInvokeCallingConvention.Stdcall + elif masked = 0x0400 then PInvokeCallingConvention.Thiscall + elif masked = 0x0500 then PInvokeCallingConvention.Fastcall + elif masked = 0x0100 then PInvokeCallingConvention.WinApi + else (dprintn "strange CallingConv"; PInvokeCallingConvention.None) + + let enc = + let masked = flags &&& 0x0006 + if masked = 0x0000 then PInvokeCharEncoding.None + elif masked = 0x0002 then PInvokeCharEncoding.Ansi + elif masked = 0x0004 then PInvokeCharEncoding.Unicode + elif masked = 0x0006 then PInvokeCharEncoding.Auto + else (dprintn "strange CharEncoding"; PInvokeCharEncoding.None) + + let bestfit = + let masked = flags &&& 0x0030 + if masked = 0x0000 then PInvokeCharBestFit.UseAssembly + elif masked = 0x0010 then PInvokeCharBestFit.Enabled + elif masked = 0x0020 then PInvokeCharBestFit.Disabled + else (dprintn "strange CharBestFit"; PInvokeCharBestFit.UseAssembly) + + let unmap = + let masked = flags &&& 0x3000 + if masked = 0x0000 then PInvokeThrowOnUnmappableChar.UseAssembly + elif masked = 0x1000 then PInvokeThrowOnUnmappableChar.Enabled + elif masked = 0x2000 then PInvokeThrowOnUnmappableChar.Disabled + else (dprintn "strange ThrowOnUnmappableChar"; PInvokeThrowOnUnmappableChar.UseAssembly) + + { CallingConv = cc + CharEncoding = enc + CharBestFit=bestfit + ThrowOnUnmappableChar=unmap + NoMangle = (flags &&& 0x0001) <> 0x0 + LastError = (flags &&& 0x0040) <> 0x0 + Name = + (match readStringHeapOption ctxt nameIdx with + | None -> nm + | Some nm2 -> nm2) + Where = seekReadModuleRef ctxt mdv scopeIdx }) + +and seekReadTopCode (ctxt: ILMetadataReader) pev mdv numtypars (sz: int) start seqpoints = + let labelsOfRawOffsets = Dictionary<_, _>(sz/2) + let ilOffsetsOfLabels = Dictionary<_, _>(sz/2) + + let rawToLabel rawOffset = + match labelsOfRawOffsets.TryGetValue rawOffset with + | true, l -> l + | _ -> + let lab = generateCodeLabel() + labelsOfRawOffsets.[rawOffset] <- lab + lab + + let markAsInstructionStart rawOffset ilOffset = + let lab = rawToLabel rawOffset + ilOffsetsOfLabels.[lab] <- ilOffset + + let ibuf = ResizeArray<_>(sz/2) + let mutable curr = 0 + let prefixes = { al=Aligned; tl= Normalcall; vol= Nonvolatile;ro=NormalAddress;constrained=None } + let mutable lastb = 0x0 + let mutable lastb2 = 0x0 + let mutable b = 0x0 + let get () = + lastb <- seekReadByteAsInt32 pev (start + curr) + curr <- curr + 1 + b <- + if lastb = 0xfe && curr < sz then + lastb2 <- seekReadByteAsInt32 pev (start + curr) + curr <- curr + 1 + lastb2 + else + lastb + + let mutable seqPointsRemaining = seqpoints + + while curr < sz do + // registering "+string !curr+" as start of an instruction") + markAsInstructionStart curr ibuf.Count + + // Insert any sequence points into the instruction sequence + while + (match seqPointsRemaining with + | (i, _tag) :: _rest when i <= curr -> true + | _ -> false) + do + // Emitting one sequence point + let _, tag = List.head seqPointsRemaining + seqPointsRemaining <- List.tail seqPointsRemaining + ibuf.Add (I_seqpoint tag) + + // Read the prefixes. Leave lastb and lastb2 holding the instruction byte(s) + begin + prefixes.al <- Aligned + prefixes.tl <- Normalcall + prefixes.vol <- Nonvolatile + prefixes.ro<-NormalAddress + prefixes.constrained<-None + get () + while curr < sz && + lastb = 0xfe && + (b = (i_constrained &&& 0xff) || + b = (i_readonly &&& 0xff) || + b = (i_unaligned &&& 0xff) || + b = (i_volatile &&& 0xff) || + b = (i_tail &&& 0xff)) do + begin + if b = (i_unaligned &&& 0xff) then + let unal = seekReadByteAsInt32 pev (start + curr) + curr <- curr + 1 + prefixes.al <- + if unal = 0x1 then Unaligned1 + elif unal = 0x2 then Unaligned2 + elif unal = 0x4 then Unaligned4 + else (dprintn "bad alignment for unaligned"; Aligned) + elif b = (i_volatile &&& 0xff) then prefixes.vol <- Volatile + elif b = (i_readonly &&& 0xff) then prefixes.ro <- ReadonlyAddress + elif b = (i_constrained &&& 0xff) then + let uncoded = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + let ty = seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec uncoded) + prefixes.constrained <- Some ty + else prefixes.tl <- Tailcall + end + get () + end + + // data for instruction begins at "+string !curr + // Read and decode the instruction + if (curr <= sz) then + let idecoder = + if lastb = 0xfe then getTwoByteInstr lastb2 + else getOneByteInstr lastb + let instr = + match idecoder with + | I_u16_u8_instr f -> + let x = seekReadByte pev (start + curr) |> uint16 + curr <- curr + 1 + f prefixes x + | I_u16_u16_instr f -> + let x = seekReadUInt16 pev (start + curr) + curr <- curr + 2 + f prefixes x + | I_none_instr f -> + f prefixes + | I_i64_instr f -> + let x = seekReadInt64 pev (start + curr) + curr <- curr + 8 + f prefixes x + | I_i32_i8_instr f -> + let x = seekReadSByte pev (start + curr) |> int32 + curr <- curr + 1 + f prefixes x + | I_i32_i32_instr f -> + let x = seekReadInt32 pev (start + curr) + curr <- curr + 4 + f prefixes x + | I_r4_instr f -> + let x = seekReadSingle pev (start + curr) + curr <- curr + 4 + f prefixes x + | I_r8_instr f -> + let x = seekReadDouble pev (start + curr) + curr <- curr + 8 + f prefixes x + | I_field_instr f -> + let tab, tok = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + let fspec = + if tab = TableNames.Field then + seekReadFieldDefAsFieldSpec ctxt tok + elif tab = TableNames.MemberRef then + seekReadMemberRefAsFieldSpec ctxt numtypars tok + else failwith "bad table in FieldDefOrRef" + f prefixes fspec + | I_method_instr f -> + // method instruction, curr = "+string !curr + + let tab, idx = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + let (VarArgMethodData(enclTy, cc, nm, argtys, varargs, retty, minst)) = + if tab = TableNames.Method then + seekReadMethodDefOrRef ctxt numtypars (TaggedIndex(mdor_MethodDef, idx)) + elif tab = TableNames.MemberRef then + seekReadMethodDefOrRef ctxt numtypars (TaggedIndex(mdor_MemberRef, idx)) + elif tab = TableNames.MethodSpec then + seekReadMethodSpecAsMethodData ctxt numtypars idx + else failwith "bad table in MethodDefOrRefOrSpec" + match enclTy with + | ILType.Array (shape, ty) -> + match nm with + | "Get" -> I_ldelem_any(shape, ty) + | "Set" -> I_stelem_any(shape, ty) + | "Address" -> I_ldelema(prefixes.ro, false, shape, ty) + | ".ctor" -> I_newarr(shape, ty) + | _ -> failwith "bad method on array type" + | _ -> + let mspec = mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst) + f prefixes (mspec, varargs) + | I_type_instr f -> + let uncoded = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + let ty = seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec uncoded) + f prefixes ty + | I_string_instr f -> + let tab, idx = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + if tab <> TableNames.UserStrings then dprintn "warning: bad table in user string for ldstr" + f prefixes (readUserStringHeap ctxt idx) + + | I_conditional_i32_instr f -> + let offsDest = (seekReadInt32 pev (start + curr)) + curr <- curr + 4 + let dest = curr + offsDest + f prefixes (rawToLabel dest) + | I_conditional_i8_instr f -> + let offsDest = int (seekReadSByte pev (start + curr)) + curr <- curr + 1 + let dest = curr + offsDest + f prefixes (rawToLabel dest) + | I_unconditional_i32_instr f -> + let offsDest = (seekReadInt32 pev (start + curr)) + curr <- curr + 4 + let dest = curr + offsDest + f prefixes (rawToLabel dest) + | I_unconditional_i8_instr f -> + let offsDest = int (seekReadSByte pev (start + curr)) + curr <- curr + 1 + let dest = curr + offsDest + f prefixes (rawToLabel dest) + | I_invalid_instr -> + dprintn ("invalid instruction: "+string lastb+ (if lastb = 0xfe then ", "+string lastb2 else "")) + I_ret + | I_tok_instr f -> + let tab, idx = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + (* REVIEW: this incorrectly labels all MemberRef tokens as ILMethod's: we should go look at the MemberRef sig to determine if it is a field or method *) + let token_info = + if tab = TableNames.Method || tab = TableNames.MemberRef (* REVIEW: generics or tab = TableNames.MethodSpec *) then + let (MethodData(enclTy, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs ctxt numtypars (uncodedTokenToMethodDefOrRef (tab, idx)) + ILToken.ILMethod (mkILMethSpecInTy (enclTy, cc, nm, argtys, retty, minst)) + elif tab = TableNames.Field then + ILToken.ILField (seekReadFieldDefAsFieldSpec ctxt idx) + elif tab = TableNames.TypeDef || tab = TableNames.TypeRef || tab = TableNames.TypeSpec then + ILToken.ILType (seekReadTypeDefOrRef ctxt numtypars AsObject [] (uncodedTokenToTypeDefOrRefOrSpec (tab, idx))) + else failwith "bad token for ldtoken" + f prefixes token_info + | I_sig_instr f -> + let tab, idx = seekReadUncodedToken pev (start + curr) + curr <- curr + 4 + if tab <> TableNames.StandAloneSig then dprintn "strange table for callsig token" + let generic, _genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig ctxt numtypars (seekReadStandAloneSigRow ctxt mdv idx) + if generic then failwith "bad image: a generic method signature is begin used at a calli instruction" + f prefixes (mkILCallSig (cc, argtys, retty), varargs) + | I_switch_instr f -> + let n = (seekReadInt32 pev (start + curr)) + curr <- curr + 4 + let offsets = + List.init n (fun _ -> + let i = (seekReadInt32 pev (start + curr)) + curr <- curr + 4 + i) + let dests = List.map (fun offs -> rawToLabel (curr + offs)) offsets + f prefixes dests + ibuf.Add instr + done + // Finished reading instructions - mark the end of the instruction stream in case the PDB information refers to it. + markAsInstructionStart curr ibuf.Count + // Build the function that maps from raw labels (offsets into the bytecode stream) to indexes in the AbsIL instruction stream + let lab2pc = ilOffsetsOfLabels + + // Some offsets used in debug info refer to the end of an instruction, rather than the + // start of the subsequent instruction. But all labels refer to instruction starts, + // apart from a final label which refers to the end of the method. This function finds + // the start of the next instruction referred to by the raw offset. + let raw2nextLab rawOffset = + let isInstrStart x = + match labelsOfRawOffsets.TryGetValue x with + | true, lab -> ilOffsetsOfLabels.ContainsKey lab + | _ -> false + if isInstrStart rawOffset then rawToLabel rawOffset + elif isInstrStart (rawOffset+1) then rawToLabel (rawOffset+1) + else failwith ("the bytecode raw offset "+string rawOffset+" did not refer either to the start or end of an instruction") + let instrs = ibuf.ToArray() + instrs, rawToLabel, lab2pc, raw2nextLab + +#if FX_NO_PDB_READER +and seekReadMethodRVA (pectxt: PEReader) (ctxt: ILMetadataReader) (_idx, nm, _internalcall, noinline, aggressiveinline, numtypars) rva = +#else +and seekReadMethodRVA (pectxt: PEReader) (ctxt: ILMetadataReader) (idx, nm, _internalcall, noinline, aggressiveinline, numtypars) rva = +#endif + lazy + let pev = pectxt.pefile.GetView() + let baseRVA = pectxt.anyV2P("method rva", rva) + // ": reading body of method "+nm+" at rva "+string rva+", phys "+string baseRVA + let b = seekReadByte pev baseRVA + + let isTinyFormat = (b &&& e_CorILMethod_FormatMask) = e_CorILMethod_TinyFormat + let isFatFormat = (b &&& e_CorILMethod_FormatMask) = e_CorILMethod_FatFormat + + if not isTinyFormat && not isFatFormat then + if logging then failwith "unknown format" + MethodBody.Abstract + else + + MethodBody.IL + (lazy + let pev = pectxt.pefile.GetView() + let mdv = ctxt.mdfile.GetView() + + // Read any debug information for this method into temporary data structures + // -- a list of locals, marked with the raw offsets (actually closures which accept the resolution function that maps raw offsets to labels) + // -- an overall range for the method + // -- the sequence points for the method + let localPdbInfos, methRangePdbInfo, seqpoints = +#if FX_NO_PDB_READER + [], None, [] +#else + match pectxt.pdb with + | None -> + [], None, [] + | Some (pdbr, get_doc) -> + try + + let pdbm = pdbReaderGetMethod pdbr (uncodedToken TableNames.Method idx) + let sps = pdbMethodGetDebugPoints pdbm + (* let roota, rootb = pdbScopeGetOffsets rootScope in *) + let seqpoints = + let arr = + sps |> Array.map (fun sp -> + // It is VERY annoying to have to call GetURL for the document for + // each sequence point. This appears to be a short coming of the PDB + // reader API. They should return an index into the array of documents for the reader + let sourcedoc = get_doc (pdbDocumentGetURL sp.pdbSeqPointDocument) + let source = + ILDebugPoint.Create(document = sourcedoc, + line = sp.pdbSeqPointLine, + column = sp.pdbSeqPointColumn, + endLine = sp.pdbSeqPointEndLine, + endColumn = sp.pdbSeqPointEndColumn) + (sp.pdbSeqPointOffset, source)) + + Array.sortInPlaceBy fst arr + + Array.toList arr + + let rec scopes scp = + let a, b = pdbScopeGetOffsets scp + let lvs = pdbScopeGetLocals scp + let ilvs = + lvs + |> Array.toList + |> List.filter (fun l -> + let k, _idx = pdbVariableGetAddressAttributes l + k = 1 (* ADDR_IL_OFFSET *)) + let ilinfos: ILLocalDebugMapping list = + ilvs |> List.map (fun ilv -> + let _k, idx = pdbVariableGetAddressAttributes ilv + let n = pdbVariableGetName ilv + { LocalIndex= idx + LocalName=n}) + + let thisOne = + (fun raw2nextLab -> + { Range= (raw2nextLab a, raw2nextLab b) + DebugMappings = ilinfos }: ILLocalDebugInfo ) + let others = List.foldBack (scopes >> (@)) (Array.toList (pdbScopeGetChildren scp)) [] + thisOne :: others + let localPdbInfos = [] (* scopes fail for mscorlib scopes rootScope *) + // REVIEW: look through sps to get ranges? Use GetRanges?? Change AbsIL?? + (localPdbInfos, None, seqpoints) + with e -> + // "* Warning: PDB info for method "+nm+" could not be read and will be ignored: "+e.Message + [], None, [] +#endif + + if isTinyFormat then + let codeBase = baseRVA + 1 + let codeSize = (int32 b >>>& 2) + // tiny format for "+nm+", code size = " + string codeSize) + let instrs, _, lab2pc, raw2nextLab = seekReadTopCode ctxt pev mdv numtypars codeSize codeBase seqpoints + + // Convert the linear code format to the nested code format + let localPdbInfos2 = List.map (fun f -> f raw2nextLab) localPdbInfos + let code = buildILCode nm lab2pc instrs [] localPdbInfos2 + + { + IsZeroInit=false + MaxStack= 8 + NoInlining=noinline + AggressiveInlining=aggressiveinline + Locals=List.empty + Code=code + DebugPoint=methRangePdbInfo + DebugImports=None + } + + else + let hasMoreSections = (b &&& e_CorILMethod_MoreSects) <> 0x0uy + let initlocals = (b &&& e_CorILMethod_InitLocals) <> 0x0uy + let maxstack = seekReadUInt16AsInt32 pev (baseRVA + 2) + let codeSize = seekReadInt32 pev (baseRVA + 4) + let localsTab, localToken = seekReadUncodedToken pev (baseRVA + 8) + let codeBase = baseRVA + 12 + let locals = + if localToken = 0x0 then [] + else + if localsTab <> TableNames.StandAloneSig then dprintn "strange table for locals token" + readBlobHeapAsLocalsSig ctxt numtypars (seekReadStandAloneSigRow ctxt pev localToken) + + // fat format for "+nm+", code size = " + string codeSize+", hasMoreSections = "+(if hasMoreSections then "true" else "false")+", b = "+string b) + + // Read the method body + let instrs, rawToLabel, lab2pc, raw2nextLab = seekReadTopCode ctxt pev mdv numtypars codeSize codeBase seqpoints + + // Read all the sections that follow the method body. + // These contain the exception clauses. + let mutable nextSectionBase = align 4 (codeBase + codeSize) + let mutable moreSections = hasMoreSections + let mutable seh = [] + while moreSections do + let sectionBase = nextSectionBase + let sectionFlag = seekReadByte pev sectionBase + // fat format for "+nm+", sectionFlag = " + string sectionFlag) + let sectionSize, clauses = + if (sectionFlag &&& e_CorILMethod_Sect_FatFormat) <> 0x0uy then + let bigSize = (seekReadInt32 pev sectionBase) >>>& 8 + // bigSize = "+string bigSize) + let clauses = + if (sectionFlag &&& e_CorILMethod_Sect_EHTable) <> 0x0uy then + // WORKAROUND: The ECMA spec says this should be + // let numClauses = ((bigSize - 4) / 24) in + // but the CCI IL generator generates multiples of 24 + let numClauses = (bigSize / 24) + + List.init numClauses (fun i -> + let clauseBase = sectionBase + 4 + (i * 24) + let kind = seekReadInt32 pev (clauseBase + 0) + let st1 = seekReadInt32 pev (clauseBase + 4) + let sz1 = seekReadInt32 pev (clauseBase + 8) + let st2 = seekReadInt32 pev (clauseBase + 12) + let sz2 = seekReadInt32 pev (clauseBase + 16) + let extra = seekReadInt32 pev (clauseBase + 20) + (kind, st1, sz1, st2, sz2, extra)) + else [] + bigSize, clauses + else + let smallSize = seekReadByteAsInt32 pev (sectionBase + 0x01) + let clauses = + if (sectionFlag &&& e_CorILMethod_Sect_EHTable) <> 0x0uy then + // WORKAROUND: The ECMA spec says this should be + // let numClauses = ((smallSize - 4) / 12) in + // but the C# compiler (or some IL generator) generates multiples of 12 + let numClauses = (smallSize / 12) + // dprintn (nm+" has " + string numClauses + " tiny seh clauses") + List.init numClauses (fun i -> + let clauseBase = sectionBase + 4 + (i * 12) + let kind = seekReadUInt16AsInt32 pev (clauseBase + 0) + if logging then dprintn ("One tiny SEH clause, kind = "+string kind) + let st1 = seekReadUInt16AsInt32 pev (clauseBase + 2) + let sz1 = seekReadByteAsInt32 pev (clauseBase + 4) + let st2 = seekReadUInt16AsInt32 pev (clauseBase + 5) + let sz2 = seekReadByteAsInt32 pev (clauseBase + 7) + let extra = seekReadInt32 pev (clauseBase + 8) + (kind, st1, sz1, st2, sz2, extra)) + else + [] + smallSize, clauses + + // Morph together clauses that cover the same range + let sehClauses = + let sehMap = Dictionary<_, _>(clauses.Length, HashIdentity.Structural) + + List.iter + (fun (kind, st1, sz1, st2, sz2, extra) -> + let tryStart = rawToLabel st1 + let tryFinish = rawToLabel (st1 + sz1) + let handlerStart = rawToLabel st2 + let handlerFinish = rawToLabel (st2 + sz2) + let clause = + if kind = e_COR_ILEXCEPTION_CLAUSE_EXCEPTION then + ILExceptionClause.TypeCatch(seekReadTypeDefOrRef ctxt numtypars AsObject List.empty (uncodedTokenToTypeDefOrRefOrSpec (i32ToUncodedToken extra)), (handlerStart, handlerFinish) ) + elif kind = e_COR_ILEXCEPTION_CLAUSE_FILTER then + let filterStart = rawToLabel extra + let filterFinish = handlerStart + ILExceptionClause.FilterCatch((filterStart, filterFinish), (handlerStart, handlerFinish)) + elif kind = e_COR_ILEXCEPTION_CLAUSE_FINALLY then + ILExceptionClause.Finally(handlerStart, handlerFinish) + elif kind = e_COR_ILEXCEPTION_CLAUSE_FAULT then + ILExceptionClause.Fault(handlerStart, handlerFinish) + else begin + dprintn (ctxt.fileName + ": unknown exception handler kind: "+string kind) + ILExceptionClause.Finally(handlerStart, handlerFinish) + end + + let key = (tryStart, tryFinish) + match sehMap.TryGetValue key with + | true, prev -> sehMap.[key] <- prev @ [clause] + | _ -> sehMap.[key] <- [clause]) + clauses + ([], sehMap) ||> Seq.fold (fun acc (KeyValue(key, bs)) -> [ for b in bs -> {Range=key; Clause=b}: ILExceptionSpec ] @ acc) + seh <- sehClauses + moreSections <- (sectionFlag &&& e_CorILMethod_Sect_MoreSects) <> 0x0uy + nextSectionBase <- sectionBase + sectionSize + done (* while *) + + // Convert the linear code format to the nested code format + if logging then dprintn "doing localPdbInfos2" + let localPdbInfos2 = List.map (fun f -> f raw2nextLab) localPdbInfos + if logging then dprintn "done localPdbInfos2, checking code..." + let code = buildILCode nm lab2pc instrs seh localPdbInfos2 + if logging then dprintn "done checking code." + { + IsZeroInit=initlocals + MaxStack= maxstack + NoInlining=noinline + AggressiveInlining=aggressiveinline + Locals = locals + Code=code + DebugPoint=methRangePdbInfo + DebugImports = None + }) + +and int32AsILVariantType (ctxt: ILMetadataReader) (n: int32) = + if List.memAssoc n (Lazy.force ILVariantTypeRevMap) then + List.assoc n (Lazy.force ILVariantTypeRevMap) + elif (n &&& vt_ARRAY) <> 0x0 then ILNativeVariant.Array (int32AsILVariantType ctxt (n &&& (~~~ vt_ARRAY))) + elif (n &&& vt_VECTOR) <> 0x0 then ILNativeVariant.Vector (int32AsILVariantType ctxt (n &&& (~~~ vt_VECTOR))) + elif (n &&& vt_BYREF) <> 0x0 then ILNativeVariant.Byref (int32AsILVariantType ctxt (n &&& (~~~ vt_BYREF))) + else (dprintn (ctxt.fileName + ": int32AsILVariantType ctxt: unexpected variant type, n = "+string n) ; ILNativeVariant.Empty) + +and readBlobHeapAsNativeType ctxt blobIdx = + // reading native type blob "+string blobIdx) + let bytes = readBlobHeap ctxt blobIdx + let res, _ = sigptrGetILNativeType ctxt bytes 0 + res + +and sigptrGetILNativeType ctxt bytes sigptr : ILNativeType * int = + // reading native type blob, sigptr= "+string sigptr) + let ntbyte, sigptr = sigptrGetByte bytes sigptr + if List.memAssoc ntbyte (Lazy.force ILNativeTypeMap) then + List.assoc ntbyte (Lazy.force ILNativeTypeMap), sigptr + elif ntbyte = 0x0uy then ILNativeType.Empty, sigptr + elif ntbyte = nt_CUSTOMMARSHALER then + // reading native type blob CM1, sigptr= "+string sigptr+ ", bytes.Length = "+string bytes.Length) + let struct (guidLen, sigptr) = sigptrGetZInt32 bytes sigptr + // reading native type blob CM2, sigptr= "+string sigptr+", guidLen = "+string ( guidLen)) + let guid, sigptr = sigptrGetBytes guidLen bytes sigptr + // reading native type blob CM3, sigptr= "+string sigptr) + let struct (nativeTypeNameLen, sigptr) = sigptrGetZInt32 bytes sigptr + // reading native type blob CM4, sigptr= "+string sigptr+", nativeTypeNameLen = "+string ( nativeTypeNameLen)) + let nativeTypeName, sigptr = sigptrGetString nativeTypeNameLen bytes sigptr + // reading native type blob CM4, sigptr= "+string sigptr+", nativeTypeName = "+nativeTypeName) + // reading native type blob CM5, sigptr= "+string sigptr) + let struct (custMarshallerNameLen, sigptr) = sigptrGetZInt32 bytes sigptr + // reading native type blob CM6, sigptr= "+string sigptr+", custMarshallerNameLen = "+string ( custMarshallerNameLen)) + let custMarshallerName, sigptr = sigptrGetString custMarshallerNameLen bytes sigptr + // reading native type blob CM7, sigptr= "+string sigptr+", custMarshallerName = "+custMarshallerName) + let struct (cookieStringLen, sigptr) = sigptrGetZInt32 bytes sigptr + // reading native type blob CM8, sigptr= "+string sigptr+", cookieStringLen = "+string ( cookieStringLen)) + let cookieString, sigptr = sigptrGetBytes cookieStringLen bytes sigptr + // reading native type blob CM9, sigptr= "+string sigptr) + ILNativeType.Custom (guid, nativeTypeName, custMarshallerName, cookieString), sigptr + elif ntbyte = nt_FIXEDSYSSTRING then + let struct (i, sigptr) = sigptrGetZInt32 bytes sigptr + ILNativeType.FixedSysString i, sigptr + elif ntbyte = nt_FIXEDARRAY then + let struct (i, sigptr) = sigptrGetZInt32 bytes sigptr + ILNativeType.FixedArray i, sigptr + elif ntbyte = nt_SAFEARRAY then + (if sigptr >= bytes.Length then + ILNativeType.SafeArray(ILNativeVariant.Empty, None), sigptr + else + let struct (i, sigptr) = sigptrGetZInt32 bytes sigptr + if sigptr >= bytes.Length then + ILNativeType.SafeArray (int32AsILVariantType ctxt i, None), sigptr + else + let struct (len, sigptr) = sigptrGetZInt32 bytes sigptr + let s, sigptr = sigptrGetString len bytes sigptr + ILNativeType.SafeArray (int32AsILVariantType ctxt i, Some s), sigptr) + elif ntbyte = nt_ARRAY then + if sigptr >= bytes.Length then + ILNativeType.Array(None, None), sigptr + else + let nt, sigptr = + let struct (u, sigptr') = sigptrGetZInt32 bytes sigptr + if (u = int nt_MAX) then + ILNativeType.Empty, sigptr' + else + // NOTE: go back to start and read native type + sigptrGetILNativeType ctxt bytes sigptr + if sigptr >= bytes.Length then + ILNativeType.Array (Some nt, None), sigptr + else + let struct (pnum, sigptr) = sigptrGetZInt32 bytes sigptr + if sigptr >= bytes.Length then + ILNativeType.Array (Some nt, Some(pnum, None)), sigptr + else + let struct (additive, sigptr) = + if sigptr >= bytes.Length then 0, sigptr + else sigptrGetZInt32 bytes sigptr + ILNativeType.Array (Some nt, Some(pnum, Some additive)), sigptr + else (ILNativeType.Empty, sigptr) + +// Note, pectxtEager and pevEager must not be captured by the results of this function +// As a result, reading the resource offsets in the physical file is done eagerly to avoid holding on to any resources +and seekReadManifestResources (ctxt: ILMetadataReader) canReduceMemory (mdv: BinaryView) (pectxtEager: PEReader) (pevEager: BinaryView) = + mkILResources + [ for i = 1 to ctxt.getNumRows TableNames.ManifestResource do + let offset, flags, nameIdx, implIdx = seekReadManifestResourceRow ctxt mdv i + + let scoref = seekReadImplAsScopeRef ctxt mdv implIdx + + let location = + match scoref with + | ILScopeRef.Local -> + let start = pectxtEager.anyV2P ("resource", offset + pectxtEager.resourcesAddr) + let resourceLength = seekReadInt32 pevEager start + let offsetOfBytesFromStartOfPhysicalPEFile = start + 4 + let byteStorage = + let bytes = pevEager.Slice(offsetOfBytesFromStartOfPhysicalPEFile, resourceLength) + ByteStorage.FromByteMemoryAndCopy(bytes, useBackingMemoryMappedFile = canReduceMemory) + ILResourceLocation.Local(byteStorage) + + | ILScopeRef.Module mref -> ILResourceLocation.File (mref, offset) + | ILScopeRef.Assembly aref -> ILResourceLocation.Assembly aref + | _ -> failwith "seekReadManifestResources: Invalid ILScopeRef" + + let r = + { Name= readStringHeap ctxt nameIdx + Location = location + Access = (if (flags &&& 0x01) <> 0x0 then ILResourceAccess.Public else ILResourceAccess.Private) + CustomAttrsStored = ctxt.customAttrsReader_ManifestResource + MetadataIndex = i } + yield r ] + +and seekReadNestedExportedTypes ctxt (exported: _ []) (nested: Lazy<_ []>) parentIdx = + mkILNestedExportedTypesLazy + (lazy + nested.Force().[parentIdx-1] + |> List.map (fun i -> + let flags, _tok, nameIdx, namespaceIdx, _implIdx = exported.[i-1] + { Name = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + Access = (match typeAccessOfFlags flags with + | ILTypeDefAccess.Nested n -> n + | _ -> failwith "non-nested access for a nested type described as being in an auxiliary module") + Nested = seekReadNestedExportedTypes ctxt exported nested i + CustomAttrsStored = ctxt.customAttrsReader_ExportedType + MetadataIndex = i } + )) + +and seekReadTopExportedTypes (ctxt: ILMetadataReader) = + mkILExportedTypesLazy + (lazy + let mdv = ctxt.mdfile.GetView() + let numRows = ctxt.getNumRows TableNames.ExportedType + let exported = [| for i in 1..numRows -> seekReadExportedTypeRow ctxt mdv i |] + + // add each nested type id to their parent's children list + let nested = lazy ( + let nested = [| for _i in 1..numRows -> [] |] + for i = 1 to numRows do + let flags,_,_,_,TaggedIndex(tag, idx) = exported.[i-1] + if not (isTopTypeDef flags) && (tag = i_ExportedType) then + nested.[idx-1] <- i :: nested.[idx-1] + nested) + + // return top exported types + [ for i = 1 to numRows do + let flags, _tok, nameIdx, namespaceIdx, implIdx = exported.[i-1] + let (TaggedIndex(tag, _idx)) = implIdx + + // if not a nested type + if (isTopTypeDef flags) && (tag <> i_ExportedType) then + yield + { ScopeRef = seekReadImplAsScopeRef ctxt mdv implIdx + Name = readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + Attributes = enum(flags) + Nested = seekReadNestedExportedTypes ctxt exported nested i + CustomAttrsStored = ctxt.customAttrsReader_ExportedType + MetadataIndex = i } + ]) + +#if !FX_NO_PDB_READER +let getPdbReader pdbDirPath fileName = + match pdbDirPath with + | None -> None + | Some pdbpath -> + try + let pdbr = pdbReadOpen fileName pdbpath + let pdbdocs = pdbReaderGetDocuments pdbr + + let tab = new Dictionary<_, _>(Array.length pdbdocs) + pdbdocs |> Array.iter (fun pdbdoc -> + let url = pdbDocumentGetURL pdbdoc + tab.[url] <- + ILSourceDocument.Create(language=Some (pdbDocumentGetLanguage pdbdoc), + vendor = Some (pdbDocumentGetLanguageVendor pdbdoc), + documentType = Some (pdbDocumentGetType pdbdoc), + file = url)) + + let docfun url = + match tab.TryGetValue url with + | true, doc -> doc + | _ -> failwith ("Document with URL " + url + " not found in list of documents in the PDB file") + Some (pdbr, docfun) + with e -> dprintn ("* Warning: PDB file could not be read and will be ignored: "+e.Message); None +#endif + +// Note, pectxtEager and pevEager must not be captured by the results of this function +let openMetadataReader (fileName, mdfile: BinaryFile, metadataPhysLoc, peinfo, pectxtEager: PEReader, pevEager, pectxtCaptured, reduceMemoryUsage) = + let mdv = mdfile.GetView() + let magic = seekReadUInt16AsInt32 mdv metadataPhysLoc + if magic <> 0x5342 then failwith (fileName + ": bad metadata magic number: " + string magic) + let magic2 = seekReadUInt16AsInt32 mdv (metadataPhysLoc + 2) + if magic2 <> 0x424a then failwith "bad metadata magic number" + let _majorMetadataVersion = seekReadUInt16 mdv (metadataPhysLoc + 4) + let _minorMetadataVersion = seekReadUInt16 mdv (metadataPhysLoc + 6) + + let versionLength = seekReadInt32 mdv (metadataPhysLoc + 12) + let ilMetadataVersion = seekReadBytes mdv (metadataPhysLoc + 16) versionLength |> Array.filter (fun b -> b <> 0uy) + let x = align 0x04 (16 + versionLength) + let numStreams = seekReadUInt16AsInt32 mdv (metadataPhysLoc + x + 2) + let streamHeadersStart = (metadataPhysLoc + x + 4) + + let tryFindStream name = + let rec look i pos = + if i >= numStreams then None + else + let offset = seekReadInt32 mdv (pos + 0) + let length = seekReadInt32 mdv (pos + 4) + let mutable res = true + let mutable fin = false + let mutable n = 0 + // read and compare the stream name byte by byte + while not fin do + let c= seekReadByteAsInt32 mdv (pos + 8 + n) + if c = 0 then + fin <- true + elif n >= Array.length name || c <> name.[n] then + res <- false + n <- n + 1 + if res then Some(offset + metadataPhysLoc, length) + else look (i+1) (align 0x04 (pos + 8 + n)) + look 0 streamHeadersStart + + let findStream name = + match tryFindStream name with + | None -> (0x0, 0x0) + | Some positions -> positions + + let tablesStreamPhysLoc, _tablesStreamSize = + match tryFindStream [| 0x23; 0x7e |] (* #~ *) with + | Some res -> res + | None -> + match tryFindStream [| 0x23; 0x2d |] (* #-: at least one DLL I've seen uses this! *) with + | Some res -> res + | None -> + let firstStreamOffset = seekReadInt32 mdv (streamHeadersStart + 0) + let firstStreamLength = seekReadInt32 mdv (streamHeadersStart + 4) + firstStreamOffset, firstStreamLength + + let stringsStreamPhysicalLoc, stringsStreamSize = findStream [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; |] (* #Strings *) + let userStringsStreamPhysicalLoc, userStringsStreamSize = findStream [| 0x23; 0x55; 0x53; |] (* #US *) + let guidsStreamPhysicalLoc, _guidsStreamSize = findStream [| 0x23; 0x47; 0x55; 0x49; 0x44; |] (* #GUID *) + let blobsStreamPhysicalLoc, blobsStreamSize = findStream [| 0x23; 0x42; 0x6c; 0x6f; 0x62; |] (* #Blob *) + + let tableKinds = + [|kindModule (* Table 0 *) + kindTypeRef (* Table 1 *) + kindTypeDef (* Table 2 *) + kindIllegal (* kindFieldPtr *) (* Table 3 *) + kindFieldDef (* Table 4 *) + kindIllegal (* kindMethodPtr *) (* Table 5 *) + kindMethodDef (* Table 6 *) + kindIllegal (* kindParamPtr *) (* Table 7 *) + kindParam (* Table 8 *) + kindInterfaceImpl (* Table 9 *) + kindMemberRef (* Table 10 *) + kindConstant (* Table 11 *) + kindCustomAttribute (* Table 12 *) + kindFieldMarshal (* Table 13 *) + kindDeclSecurity (* Table 14 *) + kindClassLayout (* Table 15 *) + kindFieldLayout (* Table 16 *) + kindStandAloneSig (* Table 17 *) + kindEventMap (* Table 18 *) + kindIllegal (* kindEventPtr *) (* Table 19 *) + kindEvent (* Table 20 *) + kindPropertyMap (* Table 21 *) + kindIllegal (* kindPropertyPtr *) (* Table 22 *) + kindProperty (* Table 23 *) + kindMethodSemantics (* Table 24 *) + kindMethodImpl (* Table 25 *) + kindModuleRef (* Table 26 *) + kindTypeSpec (* Table 27 *) + kindImplMap (* Table 28 *) + kindFieldRVA (* Table 29 *) + kindIllegal (* kindENCLog *) (* Table 30 *) + kindIllegal (* kindENCMap *) (* Table 31 *) + kindAssembly (* Table 32 *) + kindIllegal (* kindAssemblyProcessor *) (* Table 33 *) + kindIllegal (* kindAssemblyOS *) (* Table 34 *) + kindAssemblyRef (* Table 35 *) + kindIllegal (* kindAssemblyRefProcessor *) (* Table 36 *) + kindIllegal (* kindAssemblyRefOS *) (* Table 37 *) + kindFileRef (* Table 38 *) + kindExportedType (* Table 39 *) + kindManifestResource (* Table 40 *) + kindNested (* Table 41 *) + kindGenericParam_v2_0 (* Table 42 *) + kindMethodSpec (* Table 43 *) + kindGenericParamConstraint (* Table 44 *) + kindIllegal (* Table 45 *) + kindIllegal (* Table 46 *) + kindIllegal (* Table 47 *) + kindIllegal (* Table 48 *) + kindIllegal (* Table 49 *) + kindIllegal (* Table 50 *) + kindIllegal (* Table 51 *) + kindIllegal (* Table 52 *) + kindIllegal (* Table 53 *) + kindIllegal (* Table 54 *) + kindIllegal (* Table 55 *) + kindIllegal (* Table 56 *) + kindIllegal (* Table 57 *) + kindIllegal (* Table 58 *) + kindIllegal (* Table 59 *) + kindIllegal (* Table 60 *) + kindIllegal (* Table 61 *) + kindIllegal (* Table 62 *) + kindIllegal (* Table 63 *) + |] + + let heapSizes = seekReadByteAsInt32 mdv (tablesStreamPhysLoc + 6) + let valid = seekReadInt64 mdv (tablesStreamPhysLoc + 8) + let sorted = seekReadInt64 mdv (tablesStreamPhysLoc + 16) + let tablesPresent, tableRowCount, startOfTables = + let mutable present = [] + let numRows = Array.create 64 0 + let mutable prevNumRowIdx = tablesStreamPhysLoc + 24 + for i = 0 to 63 do + if (valid &&& (int64 1 <<< i)) <> int64 0 then + present <- i :: present + numRows.[i] <- (seekReadInt32 mdv prevNumRowIdx) + prevNumRowIdx <- prevNumRowIdx + 4 + List.rev present, numRows, prevNumRowIdx + + let getNumRows (tab: TableName) = tableRowCount.[tab.Index] + let numTables = tablesPresent.Length + let stringsBigness = (heapSizes &&& 1) <> 0 + let guidsBigness = (heapSizes &&& 2) <> 0 + let blobsBigness = (heapSizes &&& 4) <> 0 + + if logging then dprintn (fileName + ": numTables = "+string numTables) + if logging && stringsBigness then dprintn (fileName + ": strings are big") + if logging && blobsBigness then dprintn (fileName + ": blobs are big") + + let tableBigness = Array.map (fun n -> n >= 0x10000) tableRowCount + + let codedBigness nbits tab = + let rows = getNumRows tab + rows >= (0x10000 >>>& nbits) + + let tdorBigness = + codedBigness 2 TableNames.TypeDef || + codedBigness 2 TableNames.TypeRef || + codedBigness 2 TableNames.TypeSpec + + let tomdBigness = + codedBigness 1 TableNames.TypeDef || + codedBigness 1 TableNames.Method + + let hcBigness = + codedBigness 2 TableNames.Field || + codedBigness 2 TableNames.Param || + codedBigness 2 TableNames.Property + + let hcaBigness = + codedBigness 5 TableNames.Method || + codedBigness 5 TableNames.Field || + codedBigness 5 TableNames.TypeRef || + codedBigness 5 TableNames.TypeDef || + codedBigness 5 TableNames.Param || + codedBigness 5 TableNames.InterfaceImpl || + codedBigness 5 TableNames.MemberRef || + codedBigness 5 TableNames.Module || + codedBigness 5 TableNames.Permission || + codedBigness 5 TableNames.Property || + codedBigness 5 TableNames.Event || + codedBigness 5 TableNames.StandAloneSig || + codedBigness 5 TableNames.ModuleRef || + codedBigness 5 TableNames.TypeSpec || + codedBigness 5 TableNames.Assembly || + codedBigness 5 TableNames.AssemblyRef || + codedBigness 5 TableNames.File || + codedBigness 5 TableNames.ExportedType || + codedBigness 5 TableNames.ManifestResource || + codedBigness 5 TableNames.GenericParam || + codedBigness 5 TableNames.GenericParamConstraint || + codedBigness 5 TableNames.MethodSpec + + + let hfmBigness = + codedBigness 1 TableNames.Field || + codedBigness 1 TableNames.Param + + let hdsBigness = + codedBigness 2 TableNames.TypeDef || + codedBigness 2 TableNames.Method || + codedBigness 2 TableNames.Assembly + + let mrpBigness = + codedBigness 3 TableNames.TypeDef || + codedBigness 3 TableNames.TypeRef || + codedBigness 3 TableNames.ModuleRef || + codedBigness 3 TableNames.Method || + codedBigness 3 TableNames.TypeSpec + + let hsBigness = + codedBigness 1 TableNames.Event || + codedBigness 1 TableNames.Property + + let mdorBigness = + codedBigness 1 TableNames.Method || + codedBigness 1 TableNames.MemberRef + + let mfBigness = + codedBigness 1 TableNames.Field || + codedBigness 1 TableNames.Method + + let iBigness = + codedBigness 2 TableNames.File || + codedBigness 2 TableNames.AssemblyRef || + codedBigness 2 TableNames.ExportedType + + let catBigness = + codedBigness 3 TableNames.Method || + codedBigness 3 TableNames.MemberRef + + let rsBigness = + codedBigness 2 TableNames.Module || + codedBigness 2 TableNames.ModuleRef || + codedBigness 2 TableNames.AssemblyRef || + codedBigness 2 TableNames.TypeRef + + let rowKindSize (RowKind kinds) = + kinds |> List.sumBy (fun x -> + match x with + | UShort -> 2 + | ULong -> 4 + | Byte -> 1 + | Data -> 4 + | GGuid -> (if guidsBigness then 4 else 2) + | Blob -> (if blobsBigness then 4 else 2) + | SString -> (if stringsBigness then 4 else 2) + | SimpleIndex tab -> (if tableBigness.[tab.Index] then 4 else 2) + | TypeDefOrRefOrSpec -> (if tdorBigness then 4 else 2) + | TypeOrMethodDef -> (if tomdBigness then 4 else 2) + | HasConstant -> (if hcBigness then 4 else 2) + | HasCustomAttribute -> (if hcaBigness then 4 else 2) + | HasFieldMarshal -> (if hfmBigness then 4 else 2) + | HasDeclSecurity -> (if hdsBigness then 4 else 2) + | MemberRefParent -> (if mrpBigness then 4 else 2) + | HasSemantics -> (if hsBigness then 4 else 2) + | MethodDefOrRef -> (if mdorBigness then 4 else 2) + | MemberForwarded -> (if mfBigness then 4 else 2) + | Implementation -> (if iBigness then 4 else 2) + | CustomAttributeType -> (if catBigness then 4 else 2) + | ResolutionScope -> (if rsBigness then 4 else 2)) + + let tableRowSizes = tableKinds |> Array.map rowKindSize + + let tablePhysLocations = + let res = Array.create 64 0x0 + let mutable prevTablePhysLoc = startOfTables + for i = 0 to 63 do + res.[i] <- prevTablePhysLoc + prevTablePhysLoc <- prevTablePhysLoc + (tableRowCount.[i] * tableRowSizes.[i]) + res + + let inbase = FileSystemUtils.fileNameOfPath fileName + ": " + + // All the caches. The sizes are guesstimates for the rough sharing-density of the assembly + let cacheAssemblyRef = mkCacheInt32 false inbase "ILAssemblyRef" (getNumRows TableNames.AssemblyRef) + let cacheMethodSpecAsMethodData = mkCacheGeneric reduceMemoryUsage inbase "MethodSpecAsMethodData" (getNumRows TableNames.MethodSpec / 20 + 1) + let cacheMemberRefAsMemberData = mkCacheGeneric reduceMemoryUsage inbase "MemberRefAsMemberData" (getNumRows TableNames.MemberRef / 20 + 1) + let cacheCustomAttr = mkCacheGeneric reduceMemoryUsage inbase "CustomAttr" (getNumRows TableNames.CustomAttribute / 50 + 1) + let cacheTypeRef = mkCacheInt32 false inbase "ILTypeRef" (getNumRows TableNames.TypeRef / 20 + 1) + let cacheTypeRefAsType = mkCacheGeneric reduceMemoryUsage inbase "TypeRefAsType" (getNumRows TableNames.TypeRef / 20 + 1) + let cacheBlobHeapAsPropertySig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsPropertySig" (getNumRows TableNames.Property / 20 + 1) + let cacheBlobHeapAsFieldSig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsFieldSig" (getNumRows TableNames.Field / 20 + 1) + let cacheBlobHeapAsMethodSig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsMethodSig" (getNumRows TableNames.Method / 20 + 1) + let cacheTypeDefAsType = mkCacheGeneric reduceMemoryUsage inbase "TypeDefAsType" (getNumRows TableNames.TypeDef / 20 + 1) + let cacheMethodDefAsMethodData = mkCacheInt32 reduceMemoryUsage inbase "MethodDefAsMethodData" (getNumRows TableNames.Method / 20 + 1) + let cacheGenericParams = mkCacheGeneric reduceMemoryUsage inbase "GenericParams" (getNumRows TableNames.GenericParam / 20 + 1) + let cacheFieldDefAsFieldSpec = mkCacheInt32 reduceMemoryUsage inbase "FieldDefAsFieldSpec" (getNumRows TableNames.Field / 20 + 1) + let cacheUserStringHeap = mkCacheInt32 reduceMemoryUsage inbase "UserStringHeap" ( userStringsStreamSize / 20 + 1) + // nb. Lots and lots of cache hits on this cache, hence never optimize cache away + let cacheStringHeap = mkCacheInt32 false inbase "string heap" ( stringsStreamSize / 50 + 1) + let cacheBlobHeap = mkCacheInt32 reduceMemoryUsage inbase "blob heap" ( blobsStreamSize / 50 + 1) + + // These tables are not required to enforce sharing fo the final data + // structure, but are very useful as searching these tables gives rise to many reads + // in standard applications. + + let cacheNestedRow = mkCacheInt32 reduceMemoryUsage inbase "Nested Table Rows" (getNumRows TableNames.Nested / 20 + 1) + let cacheConstantRow = mkCacheInt32 reduceMemoryUsage inbase "Constant Rows" (getNumRows TableNames.Constant / 20 + 1) + let cacheMethodSemanticsRow = mkCacheInt32 reduceMemoryUsage inbase "MethodSemantics Rows" (getNumRows TableNames.MethodSemantics / 20 + 1) + let cacheTypeDefRow = mkCacheInt32 reduceMemoryUsage inbase "ILTypeDef Rows" (getNumRows TableNames.TypeDef / 20 + 1) + + let rowAddr (tab: TableName) idx = tablePhysLocations.[tab.Index] + (idx - 1) * tableRowSizes.[tab.Index] + + // Build the reader context + // Use an initialization hole + let ctxtH = ref None + let ctxt: ILMetadataReader = + { sorted=sorted + getNumRows=getNumRows + mdfile=mdfile + dataEndPoints = match pectxtCaptured with None -> notlazy [] | Some pectxt -> getDataEndPointsDelayed pectxt ctxtH + pectxtCaptured=pectxtCaptured + entryPointToken=pectxtEager.entryPointToken + fileName=fileName + userStringsStreamPhysicalLoc = userStringsStreamPhysicalLoc + stringsStreamPhysicalLoc = stringsStreamPhysicalLoc + blobsStreamPhysicalLoc = blobsStreamPhysicalLoc + blobsStreamSize = blobsStreamSize + memoizeString = Tables.memoize id + readUserStringHeap = cacheUserStringHeap (readUserStringHeapUncached ctxtH) + readStringHeap = cacheStringHeap (readStringHeapUncached ctxtH) + readBlobHeap = cacheBlobHeap (readBlobHeapUncached ctxtH) + seekReadNestedRow = cacheNestedRow (seekReadNestedRowUncached ctxtH) + seekReadConstantRow = cacheConstantRow (seekReadConstantRowUncached ctxtH) + seekReadMethodSemanticsRow = cacheMethodSemanticsRow (seekReadMethodSemanticsRowUncached ctxtH) + seekReadTypeDefRow = cacheTypeDefRow (seekReadTypeDefRowUncached ctxtH) + seekReadAssemblyRef = cacheAssemblyRef (seekReadAssemblyRefUncached ctxtH) + seekReadMethodSpecAsMethodData = cacheMethodSpecAsMethodData (seekReadMethodSpecAsMethodDataUncached ctxtH) + seekReadMemberRefAsMethodData = cacheMemberRefAsMemberData (seekReadMemberRefAsMethodDataUncached ctxtH) + seekReadMemberRefAsFieldSpec = seekReadMemberRefAsFieldSpecUncached ctxtH + seekReadCustomAttr = cacheCustomAttr (seekReadCustomAttrUncached ctxtH) + seekReadTypeRef = cacheTypeRef (seekReadTypeRefUncached ctxtH) + readBlobHeapAsPropertySig = cacheBlobHeapAsPropertySig (readBlobHeapAsPropertySigUncached ctxtH) + readBlobHeapAsFieldSig = cacheBlobHeapAsFieldSig (readBlobHeapAsFieldSigUncached ctxtH) + readBlobHeapAsMethodSig = cacheBlobHeapAsMethodSig (readBlobHeapAsMethodSigUncached ctxtH) + readBlobHeapAsLocalsSig = readBlobHeapAsLocalsSigUncached ctxtH + seekReadTypeDefAsType = cacheTypeDefAsType (seekReadTypeDefAsTypeUncached ctxtH) + seekReadTypeRefAsType = cacheTypeRefAsType (seekReadTypeRefAsTypeUncached ctxtH) + seekReadMethodDefAsMethodData = cacheMethodDefAsMethodData (seekReadMethodDefAsMethodDataUncached ctxtH) + seekReadGenericParams = cacheGenericParams (seekReadGenericParamsUncached ctxtH) + seekReadFieldDefAsFieldSpec = cacheFieldDefAsFieldSpec (seekReadFieldDefAsFieldSpecUncached ctxtH) + customAttrsReader_Module = customAttrsReader ctxtH hca_Module + customAttrsReader_Assembly = customAttrsReader ctxtH hca_Assembly + customAttrsReader_TypeDef = customAttrsReader ctxtH hca_TypeDef + customAttrsReader_GenericParam= customAttrsReader ctxtH hca_GenericParam + customAttrsReader_FieldDef= customAttrsReader ctxtH hca_FieldDef + customAttrsReader_MethodDef= customAttrsReader ctxtH hca_MethodDef + customAttrsReader_ParamDef= customAttrsReader ctxtH hca_ParamDef + customAttrsReader_Event= customAttrsReader ctxtH hca_Event + customAttrsReader_Property= customAttrsReader ctxtH hca_Property + customAttrsReader_ManifestResource= customAttrsReader ctxtH hca_ManifestResource + customAttrsReader_ExportedType= customAttrsReader ctxtH hca_ExportedType + securityDeclsReader_TypeDef = securityDeclsReader ctxtH hds_TypeDef + securityDeclsReader_MethodDef = securityDeclsReader ctxtH hds_MethodDef + securityDeclsReader_Assembly = securityDeclsReader ctxtH hds_Assembly + typeDefReader = typeDefReader ctxtH + guidsStreamPhysicalLoc = guidsStreamPhysicalLoc + rowAddr=rowAddr + rsBigness=rsBigness + tdorBigness=tdorBigness + tomdBigness=tomdBigness + hcBigness=hcBigness + hcaBigness=hcaBigness + hfmBigness=hfmBigness + hdsBigness=hdsBigness + mrpBigness=mrpBigness + hsBigness=hsBigness + mdorBigness=mdorBigness + mfBigness=mfBigness + iBigness=iBigness + catBigness=catBigness + stringsBigness=stringsBigness + guidsBigness=guidsBigness + blobsBigness=blobsBigness + tableBigness=tableBigness } + ctxtH.Value <- Some ctxt + + let ilModule = seekReadModule ctxt reduceMemoryUsage pectxtEager pevEager peinfo (Encoding.UTF8.GetString (ilMetadataVersion, 0, ilMetadataVersion.Length)) 1 + let ilAssemblyRefs = lazy [ for i in 1 .. getNumRows TableNames.AssemblyRef do yield seekReadAssemblyRef ctxt i ] + + ilModule, ilAssemblyRefs + +//----------------------------------------------------------------------- +// Crack the binary headers, build a reader context and return the lazy +// read of the AbsIL module. +// ---------------------------------------------------------------------- + +let openPEFileReader (fileName, pefile: BinaryFile, pdbDirPath, noFileOnDisk) = + let pev = pefile.GetView() + (* MSDOS HEADER *) + let peSignaturePhysLoc = seekReadInt32 pev 0x3c + + (* PE HEADER *) + let peFileHeaderPhysLoc = peSignaturePhysLoc + 0x04 + let peOptionalHeaderPhysLoc = peFileHeaderPhysLoc + 0x14 + let peSignature = seekReadInt32 pev (peSignaturePhysLoc + 0) + if peSignature <> 0x4550 then failwithf "not a PE file - bad magic PE number 0x%08x, is = %A" peSignature pev + + + (* PE SIGNATURE *) + let machine = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 0) + let numSections = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 2) + let optHeaderSize = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 16) + if optHeaderSize <> 0xe0 && + optHeaderSize <> 0xf0 then failwith "not a PE file - bad optional header size" + let x64adjust = optHeaderSize - 0xe0 + let only64 = (optHeaderSize = 0xf0) (* May want to read in the optional header Magic number and check that as well... *) + let platform = match machine with | 0x8664 -> Some AMD64 | 0x200 -> Some IA64 | _ -> Some X86 + let sectionHeadersStartPhysLoc = peOptionalHeaderPhysLoc + optHeaderSize + + let flags = seekReadUInt16AsInt32 pev (peFileHeaderPhysLoc + 18) + let isDll = (flags &&& 0x2000) <> 0x0 + + (* OPTIONAL PE HEADER *) + let _textPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 4) (* Size of the code (text) section, or the sum of all code sections if there are multiple sections. *) + (* x86: 000000a0 *) + let _initdataPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 8) (* Size of the initialized data section, or the sum of all such sections if there are multiple data sections. *) + let _uninitdataPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 12) (* Size of the uninitialized data section, or the sum of all such sections if there are multiple data sections. *) + let _entrypointAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 16) (* RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 in a section marked execute/read for EXEs or 0 for DLLs e.g. 0x0000b57e *) + let _textAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 20) (* e.g. 0x0002000 *) + (* x86: 000000b0 *) + let dataSegmentAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 24) (* e.g. 0x0000c000 *) + (* REVIEW: For now, we'll use the DWORD at offset 24 for x64. This currently ok since fsc doesn't support true 64-bit image bases, + but we'll have to fix this up when such support is added. *) + let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 pev (peOptionalHeaderPhysLoc + 28) // Image Base Always 0x400000 (see Section 23.1). + let alignVirt = seekReadInt32 pev (peOptionalHeaderPhysLoc + 32) // Section Alignment Always 0x2000 (see Section 23.1). + let alignPhys = seekReadInt32 pev (peOptionalHeaderPhysLoc + 36) // File Alignment Either 0x200 or 0x1000. + (* x86: 000000c0 *) + let _osMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 40) // OS Major Always 4 (see Section 23.1). + let _osMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 42) // OS Minor Always 0 (see Section 23.1). + let _userMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 44) // User Major Always 0 (see Section 23.1). + let _userMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 46) // User Minor Always 0 (see Section 23.1). + let subsysMajor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 48) // SubSys Major Always 4 (see Section 23.1). + let subsysMinor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 50) // SubSys Minor Always 0 (see Section 23.1). + (* x86: 000000d0 *) + let _imageEndAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 56) // Image Size: Size, in bytes, of image, including all headers and padding + let _headerPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 60) // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding + let subsys = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 68) // SubSystem Subsystem required to run this image. + let useHighEnthropyVA = + let n = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 70) + let highEnthropyVA = 0x20us + (n &&& highEnthropyVA) = highEnthropyVA + + (* x86: 000000e0 *) + + (* WARNING: THESE ARE 64 bit ON x64/ia64 *) + (* REVIEW: If we ever decide that we need these values for x64, we'll have to read them in as 64bit and fix up the rest of the offsets. + Then again, it should suffice to just use the defaults, and still not bother... *) + (* let stackReserve = seekReadInt32 is (peOptionalHeaderPhysLoc + 72) in *) (* Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). *) + (* let stackCommit = seekReadInt32 is (peOptionalHeaderPhysLoc + 76) in *) (* Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). *) + (* let heapReserve = seekReadInt32 is (peOptionalHeaderPhysLoc + 80) in *) (* Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). *) + (* let heapCommit = seekReadInt32 is (peOptionalHeaderPhysLoc + 84) in *) (* Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). *) + + (* x86: 000000f0, x64: 00000100 *) + let _numDataDirectories = seekReadInt32 pev (peOptionalHeaderPhysLoc + 92 + x64adjust) (* Number of Data Directories: Always 0x10 (see Section 23.1). *) + (* 00000100 - these addresses are for x86 - for the x64 location, add x64adjust (0x10) *) + let _importTableAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 104 + x64adjust) (* Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 *) + let _importTableSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 108 + x64adjust) (* Size of Import Table, (see clause 24.3.1). *) + let nativeResourcesAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 112 + x64adjust) + let nativeResourcesSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 116 + x64adjust) + (* 00000110 *) + (* 00000120 *) + (* let base_relocTableNames.addr = seekReadInt32 is (peOptionalHeaderPhysLoc + 136) + let base_relocTableNames.size = seekReadInt32 is (peOptionalHeaderPhysLoc + 140) in *) + (* 00000130 *) + (* 00000140 *) + (* 00000150 *) + let _importAddrTableAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 192 + x64adjust) (* RVA of Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 *) + let _importAddrTableSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 196 + x64adjust) (* Size of Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 *) + (* 00000160 *) + let cliHeaderAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 208 + x64adjust) + let _cliHeaderSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 212 + x64adjust) + (* 00000170 *) + + + (* Crack section headers *) + + let sectionHeaders = + [ for i in 0 .. numSections-1 do + let pos = sectionHeadersStartPhysLoc + i * 0x28 + let virtSize = seekReadInt32 pev (pos + 8) + let virtAddr = seekReadInt32 pev (pos + 12) + let physLoc = seekReadInt32 pev (pos + 20) + yield (virtAddr, virtSize, physLoc) ] + + let findSectionHeader addr = + let rec look i pos = + if i >= numSections then 0x0 + else + let virtSize = seekReadInt32 pev (pos + 8) + let virtAddr = seekReadInt32 pev (pos + 12) + if (addr >= virtAddr && addr < virtAddr + virtSize) then pos + else look (i+1) (pos + 0x28) + look 0 sectionHeadersStartPhysLoc + + let textHeaderStart = findSectionHeader cliHeaderAddr + let dataHeaderStart = findSectionHeader dataSegmentAddr + (* let relocHeaderStart = findSectionHeader base_relocTableNames.addr in *) + + let _textSize = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 8) + let _textAddr = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 12) + let textSegmentPhysicalSize = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 16) + let textSegmentPhysicalLoc = if textHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (textHeaderStart + 20) + + //let dataSegmentSize = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 8) + //let dataSegmentAddr = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 12) + let dataSegmentPhysicalSize = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 16) + let dataSegmentPhysicalLoc = if dataHeaderStart = 0x0 then 0x0 else seekReadInt32 pev (dataHeaderStart + 20) + + let anyV2P (n, v) = + let pev = pefile.GetView() + let rec look i pos = + if i >= numSections then (failwith (fileName + ": bad "+n+", rva "+string v); 0x0) + else + let virtSize = seekReadInt32 pev (pos + 8) + let virtAddr = seekReadInt32 pev (pos + 12) + let physLoc = seekReadInt32 pev (pos + 20) + if (v >= virtAddr && (v < virtAddr + virtSize)) then (v - virtAddr) + physLoc + else look (i+1) (pos + 0x28) + look 0 sectionHeadersStartPhysLoc + + let cliHeaderPhysLoc = anyV2P ("cli header", cliHeaderAddr) + + let _majorRuntimeVersion = seekReadUInt16 pev (cliHeaderPhysLoc + 4) + let _minorRuntimeVersion = seekReadUInt16 pev (cliHeaderPhysLoc + 6) + let metadataAddr = seekReadInt32 pev (cliHeaderPhysLoc + 8) + let metadataSize = seekReadInt32 pev (cliHeaderPhysLoc + 12) + let cliFlags = seekReadInt32 pev (cliHeaderPhysLoc + 16) + + let ilOnly = (cliFlags &&& 0x01) <> 0x00 + let only32 = (cliFlags &&& 0x02) <> 0x00 + let is32bitpreferred = (cliFlags &&& 0x00020003) <> 0x00 + let _strongnameSigned = (cliFlags &&& 0x08) <> 0x00 + let _trackdebugdata = (cliFlags &&& 0x010000) <> 0x00 + + let entryPointToken = seekReadUncodedToken pev (cliHeaderPhysLoc + 20) + let resourcesAddr = seekReadInt32 pev (cliHeaderPhysLoc + 24) + let resourcesSize = seekReadInt32 pev (cliHeaderPhysLoc + 28) + let strongnameAddr = seekReadInt32 pev (cliHeaderPhysLoc + 32) + let _strongnameSize = seekReadInt32 pev (cliHeaderPhysLoc + 36) + let vtableFixupsAddr = seekReadInt32 pev (cliHeaderPhysLoc + 40) + let _vtableFixupsSize = seekReadInt32 pev (cliHeaderPhysLoc + 44) + + if logging then dprintn (fileName + ": metadataAddr = "+string metadataAddr) + if logging then dprintn (fileName + ": resourcesAddr = "+string resourcesAddr) + if logging then dprintn (fileName + ": resourcesSize = "+string resourcesSize) + if logging then dprintn (fileName + ": nativeResourcesAddr = "+string nativeResourcesAddr) + if logging then dprintn (fileName + ": nativeResourcesSize = "+string nativeResourcesSize) + + let metadataPhysLoc = anyV2P ("metadata", metadataAddr) + //----------------------------------------------------------------------- + // Set up the PDB reader so we can read debug info for methods. + // ---------------------------------------------------------------------- +#if FX_NO_PDB_READER + let pdb = ignore pdbDirPath; None +#else + let pdb = + if runningOnMono then + None + else + getPdbReader pdbDirPath fileName +#endif + + let pectxt: PEReader = + { pdb=pdb + textSegmentPhysicalLoc=textSegmentPhysicalLoc + textSegmentPhysicalSize=textSegmentPhysicalSize + dataSegmentPhysicalLoc=dataSegmentPhysicalLoc + dataSegmentPhysicalSize=dataSegmentPhysicalSize + anyV2P=anyV2P + metadataAddr=metadataAddr + sectionHeaders=sectionHeaders + nativeResourcesAddr=nativeResourcesAddr + nativeResourcesSize=nativeResourcesSize + resourcesAddr=resourcesAddr + strongnameAddr=strongnameAddr + vtableFixupsAddr=vtableFixupsAddr + pefile=pefile + fileName=fileName + entryPointToken=entryPointToken + noFileOnDisk=noFileOnDisk + } + let peinfo = (subsys, (subsysMajor, subsysMinor), useHighEnthropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal) + (metadataPhysLoc, metadataSize, peinfo, pectxt, pev, pdb) + +let openPE (fileName, pefile, pdbDirPath, reduceMemoryUsage, noFileOnDisk) = + let metadataPhysLoc, _metadataSize, peinfo, pectxt, pev, pdb = openPEFileReader (fileName, pefile, pdbDirPath, noFileOnDisk) + let ilModule, ilAssemblyRefs = openMetadataReader (fileName, pefile, metadataPhysLoc, peinfo, pectxt, pev, Some pectxt, reduceMemoryUsage) + ilModule, ilAssemblyRefs, pdb + +let openPEMetadataOnly (fileName, peinfo, pectxtEager, pevEager, mdfile: BinaryFile, reduceMemoryUsage) = + openMetadataReader (fileName, mdfile, 0, peinfo, pectxtEager, pevEager, None, reduceMemoryUsage) + +let ClosePdbReader pdb = +#if FX_NO_PDB_READER + ignore pdb + () +#else + match pdb with + | Some (pdbr, _) -> pdbReadClose pdbr + | None -> () +#endif + +type ILReaderMetadataSnapshot = obj * nativeint * int +type ILReaderTryGetMetadataSnapshot = (* path: *) string * (* snapshotTimeStamp: *) DateTime -> ILReaderMetadataSnapshot option + +[] +type MetadataOnlyFlag = Yes | No + +[] +type ReduceMemoryFlag = Yes | No + +type ILReaderOptions = + { pdbDirPath: string option + reduceMemoryUsage: ReduceMemoryFlag + metadataOnly: MetadataOnlyFlag + tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot } + +type ILModuleReader = + abstract ILModuleDef: ILModuleDef + abstract ILAssemblyRefs: ILAssemblyRef list + + /// ILModuleReader objects only need to be explicitly disposed if memory mapping is used, i.e. reduceMemoryUsage = false + inherit IDisposable + +[] +type ILModuleReaderImpl(ilModule: ILModuleDef, ilAssemblyRefs: Lazy, dispose: unit -> unit) = + interface ILModuleReader with + member x.ILModuleDef = ilModule + member x.ILAssemblyRefs = ilAssemblyRefs.Force() + member x.Dispose() = dispose() + +// ++GLOBAL MUTABLE STATE (concurrency safe via locking) +type ILModuleReaderCacheKey = ILModuleReaderCacheKey of string * DateTime * bool * ReduceMemoryFlag * MetadataOnlyFlag + +// Cache to extend the lifetime of a limited number of readers that are otherwise eligible for GC +type ILModuleReaderCache1LockToken() = interface LockToken +let ilModuleReaderCache1 = + AgedLookup + (stronglyHeldReaderCacheSize, + keepMax=stronglyHeldReaderCacheSize, // only strong entries + areSimilar=(fun (x, y) -> x = y)) +let ilModuleReaderCache1Lock = Lock() + +// // Cache to reuse readers that have already been created and are not yet GC'd +let ilModuleReaderCache2 = ConcurrentDictionary>(HashIdentity.Structural) + +let stableFileHeuristicApplies fileName = + not noStableFileHeuristic && try FileSystem.IsStableFileHeuristic fileName with _ -> false + +let createByteFileChunk opts fileName chunk = + // If we're trying to reduce memory usage then we are willing to go back and re-read the binary, so we can use + // a weakly-held handle to an array of bytes. + if opts.reduceMemoryUsage = ReduceMemoryFlag.Yes && stableFileHeuristicApplies fileName then + WeakByteFile(fileName, chunk) :> BinaryFile + else + let bytes = + use stream = FileSystem.OpenFileForReadShim(fileName) + match chunk with + | None -> stream.ReadAllBytes() + | Some(start, length) -> stream.ReadBytes(start, length) + + ByteFile(fileName, bytes) :> BinaryFile + +let getBinaryFile fileName useMemoryMappedFile = + let stream = FileSystem.OpenFileForReadShim(fileName, useMemoryMappedFile = useMemoryMappedFile) + let byteMem = stream.AsByteMemory() + + let safeHolder = + { new obj() with + override x.Finalize() = + (x :?> IDisposable).Dispose() + interface IDisposable with + member x.Dispose() = + GC.SuppressFinalize x + stream.Dispose() + stats.memoryMapFileClosedCount <- stats.memoryMapFileClosedCount + 1 } + + stats.memoryMapFileOpenedCount <- stats.memoryMapFileOpenedCount + 1 + + safeHolder, RawMemoryFile(fileName, safeHolder, byteMem) :> BinaryFile + +let OpenILModuleReaderFromBytes fileName assemblyContents options = + let pefile = ByteFile(fileName, assemblyContents) :> BinaryFile + let ilModule, ilAssemblyRefs, pdb = openPE (fileName, pefile, options.pdbDirPath, (options.reduceMemoryUsage = ReduceMemoryFlag.Yes), true) + new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) :> ILModuleReader + +let OpenILModuleReaderFromStream fileName (peStream: Stream) options = + let peReader = new System.Reflection.PortableExecutable.PEReader(peStream, PEStreamOptions.PrefetchEntireImage) + let pefile = PEFile(fileName, peReader) :> BinaryFile + let ilModule, ilAssemblyRefs, pdb = openPE (fileName, pefile, options.pdbDirPath, (options.reduceMemoryUsage = ReduceMemoryFlag.Yes), true) + new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) :> ILModuleReader + +let ClearAllILModuleReaderCache() = + ilModuleReaderCache1.Clear(ILModuleReaderCache1LockToken()) + ilModuleReaderCache2.Clear() + +let OpenILModuleReader fileName opts = + // Pseudo-normalize the paths. + let ILModuleReaderCacheKey (fullPath,writeStamp,_,_,_) as key, keyOk = + try + let fullPath = FileSystem.GetFullPathShim fileName + let writeTime = FileSystem.GetLastWriteTimeShim fileName + let key = ILModuleReaderCacheKey (fullPath, writeTime, opts.pdbDirPath.IsSome, opts.reduceMemoryUsage, opts.metadataOnly) + key, true + with exn -> + Debug.Assert(false, sprintf "Failed to compute key in OpenILModuleReader cache for '%s'. Falling back to uncached. Error = %s" fileName (exn.ToString())) + let fakeKey = ILModuleReaderCacheKey(fileName, DateTime.UtcNow, false, ReduceMemoryFlag.Yes, MetadataOnlyFlag.Yes) + fakeKey, false + + let cacheResult1 = + // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable + if keyOk && opts.pdbDirPath.IsNone then + ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.TryGet(ltok, key)) + else + None + + match cacheResult1 with + | Some ilModuleReader -> ilModuleReader + | None -> + + let cacheResult2 = + // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable + if keyOk && opts.pdbDirPath.IsNone then + ilModuleReaderCache2.TryGetValue key + else + false, Unchecked.defaultof<_> + + let mutable res = Unchecked.defaultof<_> + match cacheResult2 with + | true, weak when weak.TryGetTarget(&res) -> res + | _ -> + + let reduceMemoryUsage = (opts.reduceMemoryUsage = ReduceMemoryFlag.Yes) + let metadataOnly = (opts.metadataOnly = MetadataOnlyFlag.Yes) + + if reduceMemoryUsage && opts.pdbDirPath.IsNone then + + // This case is used in FCS applications, devenv.exe and fsi.exe + // + let ilModuleReader = + // Check if we are doing metadataOnly reading (the most common case in both the compiler and IDE) + if not runningOnMono && metadataOnly then + + // See if tryGetMetadata gives us a BinaryFile for the metadata section alone. + let mdfileOpt = + match opts.tryGetMetadataSnapshot (fullPath, writeStamp) with + | Some (obj, start, len) -> Some (RawMemoryFile(fullPath, obj, start, len) :> BinaryFile) + | None -> None + + // For metadata-only, always use a temporary, short-lived PE file reader, preferably over a memory mapped file. + // Then use the metadata blob as the long-lived memory resource. + let disposer, pefileEager = getBinaryFile fullPath false + use _disposer = disposer + let metadataPhysLoc, metadataSize, peinfo, pectxtEager, pevEager, _pdb = openPEFileReader (fullPath, pefileEager, None, false) + let mdfile = + match mdfileOpt with + | Some mdfile -> mdfile + | None -> + // If tryGetMetadata doesn't give anything, then just read the metadata chunk out of the binary + createByteFileChunk opts fullPath (Some (metadataPhysLoc, metadataSize)) + + let ilModule, ilAssemblyRefs = openPEMetadataOnly (fullPath, peinfo, pectxtEager, pevEager, mdfile, reduceMemoryUsage) + new ILModuleReaderImpl(ilModule, ilAssemblyRefs, ignore) + else + // If we are not doing metadata-only, then just go ahead and read all the bytes and hold them either strongly or weakly + // depending on the heuristic + let pefile = createByteFileChunk opts fullPath None + let ilModule, ilAssemblyRefs, _pdb = openPE (fullPath, pefile, None, reduceMemoryUsage, false) + new ILModuleReaderImpl(ilModule, ilAssemblyRefs, ignore) + + let ilModuleReader = ilModuleReader :> ILModuleReader + if keyOk then + ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) + ilModuleReaderCache2.[key] <- System.WeakReference<_>(ilModuleReader) + ilModuleReader + + + else + // This case is primarily used in fsc.exe. + // + // In fsc.exe, we're not trying to reduce memory usage, nor do we really care if we leak memory. + // + // Note we ignore the "metadata only" flag as it's generally OK to read in the + // whole binary for the command-line compiler: address space is rarely an issue. + // + // We do however care about avoiding locks on files that prevent their deletion during a + // multi-proc build. So use memory mapping, but only for stable files. Other files + // still use an in-memory ByteFile + let pefile = + if not runningOnMono && (alwaysMemoryMapFSC || stableFileHeuristicApplies fullPath) then + let _, pefile = getBinaryFile fullPath false + pefile + else + createByteFileChunk opts fullPath None + + let ilModule, ilAssemblyRefs, pdb = openPE (fullPath, pefile, opts.pdbDirPath, reduceMemoryUsage, false) + let ilModuleReader = new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) + + let ilModuleReader = ilModuleReader :> ILModuleReader + + // Readers with PDB reader disposal logic don't go in the cache. Note the PDB reader is only used in static linking. + if keyOk && opts.pdbDirPath.IsNone then + ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) + ilModuleReaderCache2.[key] <- WeakReference<_>(ilModuleReader) + + ilModuleReader + +[] +module Shim = + + type IAssemblyReader = + abstract GetILModuleReader: filename: string * readerOptions: ILReaderOptions -> ILModuleReader + + [] + type DefaultAssemblyReader() = + interface IAssemblyReader with + member _.GetILModuleReader(filename, readerOptions) = + OpenILModuleReader filename readerOptions + + let mutable AssemblyReader = DefaultAssemblyReader() :> IAssemblyReader diff --git a/src/absil/ilread.fsi b/src/fsharp/absil/ilread.fsi similarity index 83% rename from src/absil/ilread.fsi rename to src/fsharp/absil/ilread.fsi index aaa2b0b6e82..a9cc50ad0c1 100644 --- a/src/absil/ilread.fsi +++ b/src/fsharp/absil/ilread.fsi @@ -26,15 +26,11 @@ /// you need. module FSharp.Compiler.AbstractIL.ILBinaryReader -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.ErrorLogger open System.IO +open FSharp.Compiler.AbstractIL.IL /// Used to implement a Binary file over native memory, used by Roslyn integration -type ILReaderMetadataSnapshot = (obj * nativeint * int) +type ILReaderMetadataSnapshot = obj * nativeint * int type ILReaderTryGetMetadataSnapshot = (* path: *) string * (* snapshotTimeStamp: *) System.DateTime -> ILReaderMetadataSnapshot option [] @@ -65,7 +61,7 @@ type ILReaderOptions = /// Represents a reader of the metadata of a .NET binary. May also give some values (e.g. IL code) from the PE file /// if it was provided. -type ILModuleReader = +type public ILModuleReader = abstract ILModuleDef: ILModuleDef abstract ILAssemblyRefs: ILAssemblyRef list @@ -76,30 +72,34 @@ type ILModuleReader = /// Open a binary reader, except first copy the entire contents of the binary into /// memory, close the file and ensure any subsequent reads happen from the in-memory store. /// PDB files may not be read with this option. +/// Binary reader is internally cached. val internal OpenILModuleReader: string -> ILReaderOptions -> ILModuleReader val internal ClearAllILModuleReaderCache : unit -> unit /// Open a binary reader based on the given bytes. -val internal OpenILModuleReaderFromBytes: fileNameForDebugOutput:string -> assemblyContents: byte[] -> options: ILReaderOptions -> ILModuleReader +/// This binary reader is not internally cached. +val internal OpenILModuleReaderFromBytes: fileName:string -> assemblyContents: byte[] -> options: ILReaderOptions -> ILModuleReader -type Statistics = +/// Open a binary reader based on the given stream. +/// This binary reader is not internally cached. +/// The binary reader will own the given stream and the stream will be disposed when there are no references to the binary reader. +val internal OpenILModuleReaderFromStream: fileName:string -> peStream: Stream -> options: ILReaderOptions -> ILModuleReader + +type internal Statistics = { mutable rawMemoryFileCount : int mutable memoryMapFileOpenedCount : int mutable memoryMapFileClosedCount : int mutable weakByteFileCount : int mutable byteFileCount : int } -val GetStatistics : unit -> Statistics +val internal GetStatistics : unit -> Statistics +/// The public API hook for changing the IL assembly reader, used by Resharper [] -module Shim = +module public Shim = - type IAssemblyReader = + type public IAssemblyReader = abstract GetILModuleReader: filename: string * readerOptions: ILReaderOptions -> ILModuleReader - [] - type DefaultAssemblyReader = - interface IAssemblyReader - val mutable AssemblyReader: IAssemblyReader diff --git a/src/absil/ilreflect.fs b/src/fsharp/absil/ilreflect.fs similarity index 80% rename from src/absil/ilreflect.fs rename to src/fsharp/absil/ilreflect.fs index 9657cf1794d..2eff2b6d4ee 100644 --- a/src/absil/ilreflect.fs +++ b/src/fsharp/absil/ilreflect.fs @@ -1,26 +1,21 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//---------------------------------------------------------------------------- -// Write Abstract IL structures at runtime using Reflection.Emit -//---------------------------------------------------------------------------- - - -module internal FSharp.Compiler.AbstractIL.ILRuntimeWriter +/// Write Abstract IL structures at runtime using Reflection.Emit +module internal FSharp.Compiler.AbstractIL.ILRuntimeWriter open System -open System.IO open System.Reflection open System.Reflection.Emit open System.Runtime.InteropServices open System.Collections.Generic -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Diagnostics +open Internal.Utilities.Collections +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range open FSharp.Core.Printf let codeLabelOrder = ComparisonIdentity.Structural @@ -29,14 +24,13 @@ let codeLabelOrder = ComparisonIdentity.Structural let wrapCustomAttr setCustomAttr (cinfo, bytes) = setCustomAttr(cinfo, bytes) - //---------------------------------------------------------------------------- // logging to enable debugging //---------------------------------------------------------------------------- let logRefEmitCalls = false -type System.Reflection.Emit.AssemblyBuilder with +type AssemblyBuilder with member asmB.DefineDynamicModuleAndLog (a, b, c) = #if FX_RESHAPED_REFEMIT ignore b @@ -47,22 +41,22 @@ type System.Reflection.Emit.AssemblyBuilder with if logRefEmitCalls then printfn "let moduleBuilder%d = assemblyBuilder%d.DefineDynamicModule(%A, %A, %A)" (abs <| hash modB) (abs <| hash asmB) a b c #endif modB - - member asmB.SetCustomAttributeAndLog (cinfo, bytes) = + + member asmB.SetCustomAttributeAndLog (cinfo, bytes) = if logRefEmitCalls then printfn "assemblyBuilder%d.SetCustomAttribute(%A, %A)" (abs <| hash asmB) cinfo bytes wrapCustomAttr asmB.SetCustomAttribute (cinfo, bytes) #if !FX_RESHAPED_REFEMIT - member asmB.AddResourceFileAndLog (nm1, nm2, attrs) = + member asmB.AddResourceFileAndLog (nm1, nm2, attrs) = if logRefEmitCalls then printfn "assemblyBuilder%d.AddResourceFile(%A, %A, enum %d)" (abs <| hash asmB) nm1 nm2 (LanguagePrimitives.EnumToValue attrs) asmB.AddResourceFile(nm1, nm2, attrs) #endif - member asmB.SetCustomAttributeAndLog cab = + member asmB.SetCustomAttributeAndLog cab = if logRefEmitCalls then printfn "assemblyBuilder%d.SetCustomAttribute(%A)" (abs <| hash asmB) cab asmB.SetCustomAttribute cab -type System.Reflection.Emit.ModuleBuilder with +type ModuleBuilder with member modB.GetArrayMethodAndLog (aty, nm, flags, rty, tys) = if logRefEmitCalls then printfn "moduleBuilder%d.GetArrayMethod(%A, %A, %A, %A, %A)" (abs <| hash modB) aty nm flags rty tys modB.GetArrayMethod(aty, nm, flags, rty, tys) @@ -81,18 +75,18 @@ type System.Reflection.Emit.ModuleBuilder with let typB = modB.DefineType(name, attrs) if logRefEmitCalls then printfn "let typeBuilder%d = moduleBuilder%d.DefineType(%A, enum %d)" (abs <| hash typB) (abs <| hash modB) name (LanguagePrimitives.EnumToValue attrs) typB - + #if !FX_RESHAPED_REFEMIT member modB.DefineManifestResourceAndLog (name, stream, attrs) = if logRefEmitCalls then printfn "moduleBuilder%d.DefineManifestResource(%A, %A, enum %d)" (abs <| hash modB) name stream (LanguagePrimitives.EnumToValue attrs) modB.DefineManifestResource(name, stream, attrs) #endif - member modB.SetCustomAttributeAndLog (cinfo, bytes) = + member modB.SetCustomAttributeAndLog (cinfo, bytes) = if logRefEmitCalls then printfn "moduleBuilder%d.SetCustomAttribute(%A, %A)" (abs <| hash modB) cinfo bytes wrapCustomAttr modB.SetCustomAttribute (cinfo, bytes) -type System.Reflection.Emit.ConstructorBuilder with +type ConstructorBuilder with member consB.SetImplementationFlagsAndLog attrs = if logRefEmitCalls then printfn "constructorBuilder%d.SetImplementationFlags(enum %d)" (abs <| hash consB) (LanguagePrimitives.EnumToValue attrs) consB.SetImplementationFlags attrs @@ -103,16 +97,16 @@ type System.Reflection.Emit.ConstructorBuilder with member consB.GetILGeneratorAndLog () = let ilG = consB.GetILGenerator() - if logRefEmitCalls then printfn "let ilg%d = constructorBuilder%d.GetILGenerator()" (abs <| hash ilG) (abs <| hash consB) + if logRefEmitCalls then printfn "let ilg%d = constructorBuilder%d.GetILGenerator()" (abs <| hash ilG) (abs <| hash consB) ilG -type System.Reflection.Emit.MethodBuilder with +type MethodBuilder with member methB.SetImplementationFlagsAndLog attrs = if logRefEmitCalls then printfn "methodBuilder%d.SetImplementationFlags(enum %d)" (abs <| hash methB) (LanguagePrimitives.EnumToValue attrs) methB.SetImplementationFlags attrs member methB.SetSignatureAndLog (returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers) = - if logRefEmitCalls then printfn "methodBuilder%d.SetSignature(...)" (abs <| hash methB) + if logRefEmitCalls then printfn "methodBuilder%d.SetSignature(...)" (abs <| hash methB) methB.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers) member methB.DefineParameterAndLog (n, attr, nm) = @@ -125,62 +119,62 @@ type System.Reflection.Emit.MethodBuilder with member methB.GetILGeneratorAndLog () = let ilG = methB.GetILGenerator() - if logRefEmitCalls then printfn "let ilg%d = methodBuilder%d.GetILGenerator()" (abs <| hash ilG) (abs <| hash methB) + if logRefEmitCalls then printfn "let ilg%d = methodBuilder%d.GetILGenerator()" (abs <| hash ilG) (abs <| hash methB) ilG - member methB.SetCustomAttributeAndLog (cinfo, bytes) = + member methB.SetCustomAttributeAndLog (cinfo, bytes) = if logRefEmitCalls then printfn "methodBuilder%d.SetCustomAttribute(%A, %A)" (abs <| hash methB) cinfo bytes wrapCustomAttr methB.SetCustomAttribute (cinfo, bytes) -type System.Reflection.Emit.TypeBuilder with - member typB.CreateTypeAndLog () = +type TypeBuilder with + member typB.CreateTypeAndLog () = if logRefEmitCalls then printfn "typeBuilder%d.CreateType()" (abs <| hash typB) #if FX_RESHAPED_REFEMIT typB.CreateTypeInfo().AsType() #else typB.CreateType() #endif - member typB.DefineNestedTypeAndLog (name, attrs) = + member typB.DefineNestedTypeAndLog (name, attrs) = let res = typB.DefineNestedType(name, attrs) if logRefEmitCalls then printfn "let typeBuilder%d = typeBuilder%d.DefineNestedType(\"%s\", enum %d)" (abs <| hash res) (abs <| hash typB) name (LanguagePrimitives.EnumToValue attrs) res - member typB.DefineMethodAndLog (name, attrs, cconv) = + member typB.DefineMethodAndLog (name, attrs, cconv) = let methB = typB.DefineMethod(name, attrs, cconv) if logRefEmitCalls then printfn "let methodBuilder%d = typeBuilder%d.DefineMethod(\"%s\", enum %d, enum %d)" (abs <| hash methB) (abs <| hash typB) name (LanguagePrimitives.EnumToValue attrs) (LanguagePrimitives.EnumToValue cconv) methB - member typB.DefineGenericParametersAndLog gps = + member typB.DefineGenericParametersAndLog gps = if logRefEmitCalls then printfn "typeBuilder%d.DefineGenericParameters(%A)" (abs <| hash typB) gps typB.DefineGenericParameters gps - member typB.DefineConstructorAndLog (attrs, cconv, parms) = + member typB.DefineConstructorAndLog (attrs, cconv, parms) = let consB = typB.DefineConstructor(attrs, cconv, parms) if logRefEmitCalls then printfn "let constructorBuilder%d = typeBuilder%d.DefineConstructor(enum %d, CallingConventions.%A, %A)" (abs <| hash consB) (abs <| hash typB) (LanguagePrimitives.EnumToValue attrs) cconv parms consB - member typB.DefineFieldAndLog (nm, ty: System.Type, attrs) = + member typB.DefineFieldAndLog (nm, ty: Type, attrs) = let fieldB = typB.DefineField(nm, ty, attrs) if logRefEmitCalls then printfn "let fieldBuilder%d = typeBuilder%d.DefineField(\"%s\", typeof<%s>, enum %d)" (abs <| hash fieldB) (abs <| hash typB) nm ty.FullName (LanguagePrimitives.EnumToValue attrs) fieldB - member typB.DefinePropertyAndLog (nm, attrs, ty: System.Type, args) = + member typB.DefinePropertyAndLog (nm, attrs, ty: Type, args) = if logRefEmitCalls then printfn "typeBuilder%d.DefineProperty(\"%A\", enum %d, typeof<%s>, %A)" (abs <| hash typB) nm (LanguagePrimitives.EnumToValue attrs) ty.FullName args typB.DefineProperty(nm, attrs, ty, args) - member typB.DefineEventAndLog (nm, attrs, ty: System.Type) = + member typB.DefineEventAndLog (nm, attrs, ty: Type) = if logRefEmitCalls then printfn "typeBuilder%d.DefineEvent(\"%A\", enum %d, typeof<%A>)" (abs <| hash typB) nm (LanguagePrimitives.EnumToValue attrs) ty.FullName typB.DefineEvent(nm, attrs, ty) - member typB.SetParentAndLog (ty: System.Type) = + member typB.SetParentAndLog (ty: Type) = if logRefEmitCalls then printfn "typeBuilder%d.SetParent(typeof<%s>)" (abs <| hash typB) ty.FullName typB.SetParent ty - member typB.AddInterfaceImplementationAndLog ty = + member typB.AddInterfaceImplementationAndLog ty = if logRefEmitCalls then printfn "typeBuilder%d.AddInterfaceImplementation(%A)" (abs <| hash typB) ty typB.AddInterfaceImplementation ty - member typB.InvokeMemberAndLog (nm, _flags, args) = + member typB.InvokeMemberAndLog (nm, _flags, args) = #if FX_RESHAPED_REFEMIT let t = typB.CreateTypeAndLog () let m = @@ -193,85 +187,85 @@ type System.Reflection.Emit.TypeBuilder with typB.InvokeMember(nm, _flags, null, null, args, Globalization.CultureInfo.InvariantCulture) #endif - member typB.SetCustomAttributeAndLog (cinfo, bytes) = + member typB.SetCustomAttributeAndLog (cinfo, bytes) = if logRefEmitCalls then printfn "typeBuilder%d.SetCustomAttribute(%A, %A)" (abs <| hash typB) cinfo bytes wrapCustomAttr typB.SetCustomAttribute (cinfo, bytes) -type System.Reflection.Emit.OpCode with - member opcode.RefEmitName = (string (System.Char.ToUpper(opcode.Name.[0])) + opcode.Name.[1..]).Replace(".", "_").Replace("_i4", "_I4") +type OpCode with + member opcode.RefEmitName = (string (Char.ToUpper(opcode.Name.[0])) + opcode.Name.[1..]).Replace(".", "_").Replace("_i4", "_I4") -type System.Reflection.Emit.ILGenerator with - member ilG.DeclareLocalAndLog (ty: System.Type, isPinned) = +type ILGenerator with + member ilG.DeclareLocalAndLog (ty: Type, isPinned) = if logRefEmitCalls then printfn "ilg%d.DeclareLocal(typeof<%s>, %b)" (abs <| hash ilG) ty.FullName isPinned ilG.DeclareLocal(ty, isPinned) - member ilG.MarkLabelAndLog lab = + member ilG.MarkLabelAndLog lab = if logRefEmitCalls then printfn "ilg%d.MarkLabel(label%d_%d)" (abs <| hash ilG) (abs <| hash ilG) (abs <| hash lab) ilG.MarkLabel lab #if !FX_RESHAPED_REFEMIT - member ilG.MarkSequencePointAndLog (symDoc, l1, c1, l2, c2) = + member ilG.MarkSequencePointAndLog (symDoc, l1, c1, l2, c2) = if logRefEmitCalls then printfn "ilg%d.MarkSequencePoint(docWriter%d, %A, %A, %A, %A)" (abs <| hash ilG) (abs <| hash symDoc) l1 c1 l2 c2 ilG.MarkSequencePoint(symDoc, l1, c1, l2, c2) #endif - member ilG.BeginExceptionBlockAndLog () = - if logRefEmitCalls then printfn "ilg%d.BeginExceptionBlock()" (abs <| hash ilG) + member ilG.BeginExceptionBlockAndLog () = + if logRefEmitCalls then printfn "ilg%d.BeginExceptionBlock()" (abs <| hash ilG) ilG.BeginExceptionBlock() - member ilG.EndExceptionBlockAndLog () = - if logRefEmitCalls then printfn "ilg%d.EndExceptionBlock()" (abs <| hash ilG) + member ilG.EndExceptionBlockAndLog () = + if logRefEmitCalls then printfn "ilg%d.EndExceptionBlock()" (abs <| hash ilG) ilG.EndExceptionBlock() - member ilG.BeginFinallyBlockAndLog () = - if logRefEmitCalls then printfn "ilg%d.BeginFinallyBlock()" (abs <| hash ilG) + member ilG.BeginFinallyBlockAndLog () = + if logRefEmitCalls then printfn "ilg%d.BeginFinallyBlock()" (abs <| hash ilG) ilG.BeginFinallyBlock() - member ilG.BeginCatchBlockAndLog ty = + member ilG.BeginCatchBlockAndLog ty = if logRefEmitCalls then printfn "ilg%d.BeginCatchBlock(%A)" (abs <| hash ilG) ty ilG.BeginCatchBlock ty - member ilG.BeginExceptFilterBlockAndLog () = - if logRefEmitCalls then printfn "ilg%d.BeginExceptFilterBlock()" (abs <| hash ilG) + member ilG.BeginExceptFilterBlockAndLog () = + if logRefEmitCalls then printfn "ilg%d.BeginExceptFilterBlock()" (abs <| hash ilG) ilG.BeginExceptFilterBlock() - member ilG.BeginFaultBlockAndLog () = - if logRefEmitCalls then printfn "ilg%d.BeginFaultBlock()" (abs <| hash ilG) + member ilG.BeginFaultBlockAndLog () = + if logRefEmitCalls then printfn "ilg%d.BeginFaultBlock()" (abs <| hash ilG) ilG.BeginFaultBlock() - member ilG.DefineLabelAndLog () = + member ilG.DefineLabelAndLog () = let lab = ilG.DefineLabel() - if logRefEmitCalls then printfn "let label%d_%d = ilg%d.DefineLabel()" (abs <| hash ilG) (abs <| hash lab) (abs <| hash ilG) + if logRefEmitCalls then printfn "let label%d_%d = ilg%d.DefineLabel()" (abs <| hash ilG) (abs <| hash lab) (abs <| hash ilG) lab - member x.EmitAndLog (op: OpCode) = + member x.EmitAndLog (op: OpCode) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s)" (abs <| hash x) op.RefEmitName - x.Emit op - member x.EmitAndLog (op: OpCode, v: Label) = + x.Emit op + member x.EmitAndLog (op: OpCode, v: Label) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, label%d_%d)" (abs <| hash x) op.RefEmitName (abs <| hash x) (abs <| hash v) x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: int16) = + member x.EmitAndLog (op: OpCode, v: int16) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, int16 %d)" (abs <| hash x) op.RefEmitName v x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: int32) = + member x.EmitAndLog (op: OpCode, v: int32) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, %d)" (abs <| hash x) op.RefEmitName v x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: MethodInfo) = + member x.EmitAndLog (op: OpCode, v: MethodInfo) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, methodBuilder%d) // method %s" (abs <| hash x) op.RefEmitName (abs <| hash v) v.Name x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: string) = + member x.EmitAndLog (op: OpCode, v: string) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, \"@%s\")" (abs <| hash x) op.RefEmitName v x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: Type) = + member x.EmitAndLog (op: OpCode, v: Type) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, typeof<%s>)" (abs <| hash x) op.RefEmitName v.FullName x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: FieldInfo) = + member x.EmitAndLog (op: OpCode, v: FieldInfo) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, fieldBuilder%d) // field %s" (abs <| hash x) op.RefEmitName (abs <| hash v) v.Name x.Emit(op, v) - member x.EmitAndLog (op: OpCode, v: ConstructorInfo) = + member x.EmitAndLog (op: OpCode, v: ConstructorInfo) = if logRefEmitCalls then printfn "ilg%d.Emit(OpCodes.%s, constructor_%s)" (abs <| hash x) op.RefEmitName v.DeclaringType.Name x.Emit(op, v) - + //---------------------------------------------------------------------------- // misc @@ -279,34 +273,34 @@ type System.Reflection.Emit.ILGenerator with let inline flagsIf b x = if b then x else enum 0 -module Zmap = +module Zmap = let force x m str = match Zmap.tryFind x m with Some y -> y | None -> failwithf "Zmap.force: %s: x = %+A" str x let equalTypes (s: Type) (t: Type) = s.Equals t let equalTypeLists ss tt = List.lengthsEqAndForall2 equalTypes ss tt let equalTypeArrays ss tt = Array.lengthsEqAndForall2 equalTypes ss tt -let getGenericArgumentsOfType (typT: Type) = +let getGenericArgumentsOfType (typT: Type) = if typT.IsGenericType then typT.GetGenericArguments() else [| |] -let getGenericArgumentsOfMethod (methI: MethodInfo) = - if methI.IsGenericMethod then methI.GetGenericArguments() else [| |] +let getGenericArgumentsOfMethod (methI: MethodInfo) = + if methI.IsGenericMethod then methI.GetGenericArguments() else [| |] -let getTypeConstructor (ty: Type) = +let getTypeConstructor (ty: Type) = if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty //---------------------------------------------------------------------------- // convAssemblyRef //---------------------------------------------------------------------------- -let convAssemblyRef (aref: ILAssemblyRef) = - let asmName = new System.Reflection.AssemblyName() +let convAssemblyRef (aref: ILAssemblyRef) = + let asmName = AssemblyName() asmName.Name <- aref.Name - (match aref.PublicKey with + (match aref.PublicKey with | None -> () | Some (PublicKey bytes) -> asmName.SetPublicKey bytes | Some (PublicKeyToken bytes) -> asmName.SetPublicKeyToken bytes) - let setVersion (version: ILVersionInfo) = - asmName.Version <- System.Version (int32 version.Major, int32 version.Minor, int32 version.Build, int32 version.Revision) + let setVersion (version: ILVersionInfo) = + asmName.Version <- Version (int32 version.Major, int32 version.Minor, int32 version.Build, int32 version.Revision) Option.iter setVersion aref.Version // asmName.ProcessorArchitecture <- System.Reflection.ProcessorArchitecture.MSIL //Option.iter (fun name -> asmName.CultureInfo <- System.Globalization.CultureInfo.CreateSpecificCulture name) aref.Locale @@ -314,73 +308,75 @@ let convAssemblyRef (aref: ILAssemblyRef) = asmName /// The global environment. -type cenv = +type cenv = { ilg: ILGlobals + emitTailcalls: bool tryFindSysILTypeRef: string -> ILTypeRef option generatePdb: bool - resolveAssemblyRef: (ILAssemblyRef -> Choice option) } + resolveAssemblyRef: ILAssemblyRef -> Choice option } override x.ToString() = "" let convResolveAssemblyRef (cenv: cenv) (asmref: ILAssemblyRef) qualifiedName = - let assembly = - match cenv.resolveAssemblyRef asmref with + let assembly = + match cenv.resolveAssemblyRef asmref with | Some (Choice1Of2 path) -> - FileSystem.AssemblyLoadFrom path + // asmRef is a path but the runtime is smarter with assembly names so make one + let asmName = AssemblyName.GetAssemblyName(path) + asmName.CodeBase <- path + FileSystem.AssemblyLoader.AssemblyLoad asmName | Some (Choice2Of2 assembly) -> assembly | None -> let asmName = convAssemblyRef asmref - FileSystem.AssemblyLoad asmName + FileSystem.AssemblyLoader.AssemblyLoad asmName let typT = assembly.GetType qualifiedName - match typT with + match typT with | null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", qualifiedName, asmref.QualifiedName), range0)) | res -> res /// Convert an Abstract IL type reference to Reflection.Emit System.Type value. -// This ought to be an adequate substitute for this whole function, but it needs +// This ought to be an adequate substitute for this whole function, but it needs // to be thoroughly tested. -// Type.GetType(tref.QualifiedName) +// Type.GetType(tref.QualifiedName) // [] , name -> name // [ns] , name -> ns+name // [ns;typeA;typeB], name -> ns+typeA+typeB+name -let convTypeRefAux (cenv: cenv) (tref: ILTypeRef) = +let convTypeRefAux (cenv: cenv) (tref: ILTypeRef) = let qualifiedName = (String.concat "+" (tref.Enclosing @ [ tref.Name ])).Replace(",", @"\,") match tref.Scope with | ILScopeRef.Assembly asmref -> convResolveAssemblyRef cenv asmref qualifiedName - | ILScopeRef.Module _ + | ILScopeRef.Module _ | ILScopeRef.Local _ -> - let typT = Type.GetType qualifiedName - match typT with + let typT = Type.GetType qualifiedName + match typT with | null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", qualifiedName, ""), range0)) | res -> res | ILScopeRef.PrimaryAssembly -> convResolveAssemblyRef cenv cenv.ilg.primaryAssemblyRef qualifiedName - - /// The (local) emitter env (state). Some of these fields are effectively global accumulators /// and could be placed as hash tables in the global environment. [] type emEnv = - { emTypMap: Zmap + { emTypMap: Zmap emConsMap: Zmap emMethMap: Zmap emFieldMap: Zmap emPropMap: Zmap emLocals: LocalBuilder[] - emLabels: Zmap + emLabels: Zmap emTyvars: Type[] list; // stack emEntryPts: (TypeBuilder * string) list delayedFieldInits: (unit -> unit) list} - + let orderILTypeRef = ComparisonIdentity.Structural let orderILMethodRef = ComparisonIdentity.Structural -let orderILFieldRef = ComparisonIdentity.Structural +let orderILFieldRef = ComparisonIdentity.Structural let orderILPropertyRef = ComparisonIdentity.Structural -let emEnv0 = +let emEnv0 = { emTypMap = Zmap.empty orderILTypeRef emConsMap = Zmap.empty orderILMethodRef emMethMap = Zmap.empty orderILMethodRef @@ -392,8 +388,8 @@ let emEnv0 = emEntryPts = [] delayedFieldInits = [] } -let envBindTypeRef emEnv (tref: ILTypeRef) (typT, typB, typeDef) = - match typT with +let envBindTypeRef emEnv (tref: ILTypeRef) (typT, typB, typeDef) = + match typT with | null -> failwithf "binding null type in envBindTypeRef: %s\n" tref.Name | _ -> {emEnv with emTypMap = Zmap.add tref (typT, typB, typeDef, None) emEnv.emTypMap} @@ -409,10 +405,10 @@ let envUpdateCreatedTypeRef emEnv (tref: ILTypeRef) = // match "match x with :? C[] -> ..." before the full loading of an object of type // causes a failure when C is later loaded. One workaround for this is to attempt to do a fake allocation // of objects. We use System.Runtime.Serialization.FormatterServices.GetUninitializedObject to do - // the fake allocation - this creates an "empty" object, even if the object doesn't have + // the fake allocation - this creates an "empty" object, even if the object doesn't have // a constructor. It is not usable in partial trust code. - if runningOnMono && ty.IsClass && not ty.IsAbstract && not ty.IsGenericType && not ty.IsGenericTypeDefinition then - try + if runningOnMono && ty.IsClass && not ty.IsAbstract && not ty.IsGenericType && not ty.IsGenericTypeDefinition then + try System.Runtime.Serialization.FormatterServices.GetUninitializedObject ty |> ignore with e -> () #endif @@ -423,48 +419,48 @@ let envUpdateCreatedTypeRef emEnv (tref: ILTypeRef) = #endif emEnv -let convTypeRef cenv emEnv preferCreated (tref: ILTypeRef) = - let res = +let convTypeRef cenv emEnv preferCreated (tref: ILTypeRef) = + let res = match Zmap.tryFind tref emEnv.emTypMap with - | Some (_typT, _typB, _typeDef, Some createdTy) when preferCreated -> createdTy - | Some (typT, _typB, _typeDef, _) -> typT - | None -> convTypeRefAux cenv tref - match res with + | Some (_typT, _typB, _typeDef, Some createdTy) when preferCreated -> createdTy + | Some (typT, _typB, _typeDef, _) -> typT + | None -> convTypeRefAux cenv tref + match res with | null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", tref.QualifiedName, tref.Scope.QualifiedName), range0)) | _ -> res - -let envBindConsRef emEnv (mref: ILMethodRef) consB = + +let envBindConsRef emEnv (mref: ILMethodRef) consB = {emEnv with emConsMap = Zmap.add mref consB emEnv.emConsMap} -let envGetConsB emEnv (mref: ILMethodRef) = +let envGetConsB emEnv (mref: ILMethodRef) = Zmap.force mref emEnv.emConsMap "envGetConsB: failed" -let envBindMethodRef emEnv (mref: ILMethodRef) methB = +let envBindMethodRef emEnv (mref: ILMethodRef) methB = {emEnv with emMethMap = Zmap.add mref methB emEnv.emMethMap} -let envGetMethB emEnv (mref: ILMethodRef) = +let envGetMethB emEnv (mref: ILMethodRef) = Zmap.force mref emEnv.emMethMap "envGetMethB: failed" -let envBindFieldRef emEnv fref fieldB = +let envBindFieldRef emEnv fref fieldB = {emEnv with emFieldMap = Zmap.add fref fieldB emEnv.emFieldMap} let envGetFieldB emEnv fref = Zmap.force fref emEnv.emFieldMap "- envGetMethB: failed" - -let envBindPropRef emEnv (pref: ILPropertyRef) propB = + +let envBindPropRef emEnv (pref: ILPropertyRef) propB = {emEnv with emPropMap = Zmap.add pref propB emEnv.emPropMap} let envGetPropB emEnv pref = Zmap.force pref emEnv.emPropMap "- envGetPropB: failed" - -let envGetTypB emEnv (tref: ILTypeRef) = + +let envGetTypB emEnv (tref: ILTypeRef) = Zmap.force tref emEnv.emTypMap "envGetTypB: failed" |> (fun (_typT, typB, _typeDef, _createdTypOpt) -> typB) - -let envGetTypeDef emEnv (tref: ILTypeRef) = + +let envGetTypeDef emEnv (tref: ILTypeRef) = Zmap.force tref emEnv.emTypMap "envGetTypeDef: failed" |> (fun (_typT, _typB, typeDef, _createdTypOpt) -> typeDef) - + let envSetLocals emEnv locs = assert (emEnv.emLocals.Length = 0); // check "locals" is not yet set (scopes once only) {emEnv with emLocals = locs} let envGetLocal emEnv i = emEnv.emLocals.[i] // implicit bounds checking @@ -472,19 +468,19 @@ let envGetLocal emEnv i = emEnv.emLocals.[i] // implicit bounds checking let envSetLabel emEnv name lab = assert (not (Zmap.mem name emEnv.emLabels)) {emEnv with emLabels = Zmap.add name lab emEnv.emLabels} - -let envGetLabel emEnv name = + +let envGetLabel emEnv name = Zmap.find name emEnv.emLabels let envPushTyvars emEnv tys = {emEnv with emTyvars = tys :: emEnv.emTyvars} let envPopTyvars emEnv = {emEnv with emTyvars = List.tail emEnv.emTyvars} -let envGetTyvar emEnv u16 = +let envGetTyvar emEnv u16 = match emEnv.emTyvars with | [] -> failwith "envGetTyvar: not scope of type vars" - | tvs :: _ -> - let i = int32 u16 + | tvs :: _ -> + let i = int32 u16 if i<0 || i>= Array.length tvs then failwith (sprintf "want tyvar #%d, but only had %d tyvars" i (Array.length tvs)) else @@ -501,13 +497,13 @@ let envPopEntryPts emEnv = {emEnv with emEntryPts = []}, emEnv.emEntryPts //---------------------------------------------------------------------------- let convCallConv (Callconv (hasThis, basic)) = - let ccA = + let ccA = match hasThis with | ILThisConvention.Static -> CallingConventions.Standard | ILThisConvention.InstanceExplicit -> CallingConventions.ExplicitThis | ILThisConvention.Instance -> CallingConventions.HasThis - let ccB = + let ccB = match basic with | ILArgConvention.Default -> enum 0 | ILArgConvention.CDecl -> enum 0 @@ -524,22 +520,22 @@ let convCallConv (Callconv (hasThis, basic)) = //---------------------------------------------------------------------------- let rec convTypeSpec cenv emEnv preferCreated (tspec: ILTypeSpec) = - let typT = convTypeRef cenv emEnv preferCreated tspec.TypeRef + let typT = convTypeRef cenv emEnv preferCreated tspec.TypeRef let tyargs = List.map (convTypeAux cenv emEnv preferCreated) tspec.GenericArgs - let res = + let res = match isNil tyargs, typT.IsGenericType with - | _, true -> typT.MakeGenericType(List.toArray tyargs) - | true, false -> typT + | _, true -> typT.MakeGenericType(List.toArray tyargs) + | true, false -> typT | _, false -> null - match res with + match res with | null -> error(Error(FSComp.SR.itemNotFoundDuringDynamicCodeGen ("type", tspec.TypeRef.QualifiedName, tspec.Scope.QualifiedName), range0)) | _ -> res - + and convTypeAux cenv emEnv preferCreated ty = match ty with | ILType.Void -> Type.GetType("System.Void") - | ILType.Array (shape, eltType) -> - let baseT = convTypeAux cenv emEnv preferCreated eltType + | ILType.Array (shape, eltType) -> + let baseT = convTypeAux cenv emEnv preferCreated eltType let nDims = shape.Rank // MakeArrayType() returns "eltType[]" // MakeArrayType(1) returns "eltType[*]" @@ -547,20 +543,19 @@ and convTypeAux cenv emEnv preferCreated ty = // MakeArrayType(3) returns "eltType[, , ]" // All non-equal. if nDims=1 - then baseT.MakeArrayType() + then baseT.MakeArrayType() else baseT.MakeArrayType shape.Rank | ILType.Value tspec -> convTypeSpec cenv emEnv preferCreated tspec | ILType.Boxed tspec -> convTypeSpec cenv emEnv preferCreated tspec - | ILType.Ptr eltType -> + | ILType.Ptr eltType -> let baseT = convTypeAux cenv emEnv preferCreated eltType baseT.MakePointerType() - | ILType.Byref eltType -> + | ILType.Byref eltType -> let baseT = convTypeAux cenv emEnv preferCreated eltType baseT.MakeByRefType() | ILType.TypeVar tv -> envGetTyvar emEnv tv - // Consider completing the following cases: - | ILType.Modified (_, _, modifiedTy) -> - // Note, "modreq" are not being emitted. This is + | ILType.Modified (_, _, modifiedTy) -> + convTypeAux cenv emEnv preferCreated modifiedTy | ILType.FunctionPointer _callsig -> failwith "convType: fptr" @@ -576,39 +571,39 @@ and convTypeAux cenv emEnv preferCreated ty = // The external use (reflection and pretty printing) requires the created Type (rather than the builder). // convCreatedType ensures created types are used where possible. // Note: typeBuilder.CreateType() freezes the type and makes a proper Type for the collected information. -//------ +//------ // REVIEW: "convType becomes convCreatedType", the functions could be combined. // If convCreatedType replaced convType functions like convMethodRef, convConstructorSpec, ... (and more?) // will need to be fixed for emitted types to handle both TypeBuilder and later Type proper. - + /// Uses TypeBuilder/TypeBuilderInstantiation for emitted types. let convType cenv emEnv ty = convTypeAux cenv emEnv false ty // Used for ldtoken -let convTypeOrTypeDef cenv emEnv ty = +let convTypeOrTypeDef cenv emEnv ty = match ty with // represents an uninstantiated "TypeDef" or "TypeRef" - | ILType.Boxed tspec when tspec.GenericArgs.IsEmpty -> convTypeRef cenv emEnv false tspec.TypeRef + | ILType.Boxed tspec when tspec.GenericArgs.IsEmpty -> convTypeRef cenv emEnv false tspec.TypeRef | _ -> convType cenv emEnv ty let convTypes cenv emEnv (tys: ILTypes) = List.map (convType cenv emEnv) tys -let convTypesToArray cenv emEnv (tys: ILTypes) = convTypes cenv emEnv tys |> List.toArray +let convTypesToArray cenv emEnv (tys: ILTypes) = convTypes cenv emEnv tys |> List.toArray /// Uses the .CreateType() for emitted type if available. -let convCreatedType cenv emEnv ty = convTypeAux cenv emEnv true ty -let convCreatedTypeRef cenv emEnv ty = convTypeRef cenv emEnv true ty - +let convCreatedType cenv emEnv ty = convTypeAux cenv emEnv true ty +let convCreatedTypeRef cenv emEnv ty = convTypeRef cenv emEnv true ty + let rec convParamModifiersOfType cenv emEnv (pty: ILType) = [| match pty with - | ILType.Modified (modreq, ty, modifiedTy) -> + | ILType.Modified (modreq, ty, modifiedTy) -> yield (modreq, convTypeRef cenv emEnv false ty) yield! convParamModifiersOfType cenv emEnv modifiedTy | _ -> () |] let splitModifiers mods = - let reqd = mods |> Array.choose (function (true, ty) -> Some ty | _ -> None) - let optional = mods |> Array.choose (function (false, ty) -> Some ty | _ -> None) + let reqd = mods |> Array.choose (function true, ty -> Some ty | _ -> None) + let optional = mods |> Array.choose (function false, ty -> Some ty | _ -> None) reqd, optional let convParamModifiers cenv emEnv (p: ILParameter) = @@ -619,36 +614,15 @@ let convReturnModifiers cenv emEnv (p: ILReturn) = let mods = convParamModifiersOfType cenv emEnv p.Type splitModifiers mods -//---------------------------------------------------------------------------- -// convFieldInit -//---------------------------------------------------------------------------- - -let convFieldInit x = - match x with - | ILFieldInit.String s -> box s - | ILFieldInit.Bool bool -> box bool - | ILFieldInit.Char u16 -> box (char (int u16)) - | ILFieldInit.Int8 i8 -> box i8 - | ILFieldInit.Int16 i16 -> box i16 - | ILFieldInit.Int32 i32 -> box i32 - | ILFieldInit.Int64 i64 -> box i64 - | ILFieldInit.UInt8 u8 -> box u8 - | ILFieldInit.UInt16 u16 -> box u16 - | ILFieldInit.UInt32 u32 -> box u32 - | ILFieldInit.UInt64 u64 -> box u64 - | ILFieldInit.Single ieee32 -> box ieee32 - | ILFieldInit.Double ieee64 -> box ieee64 - | ILFieldInit.Null -> (null :> Object) - //---------------------------------------------------------------------------- // Some types require hard work... //---------------------------------------------------------------------------- // This is gross. TypeBuilderInstantiation should really be a public type, since we -// have to use alternative means for various Method/Field/Constructor lookups. However since +// have to use alternative means for various Method/Field/Constructor lookups. However since // it isn't we resort to this technique... -let TypeBuilderInstantiationT = - let ty = +let TypeBuilderInstantiationT = + let ty = #if ENABLE_MONO_SUPPORT if runningOnMono then let ty = Type.GetType("System.Reflection.MonoGenericClass") @@ -662,30 +636,30 @@ let TypeBuilderInstantiationT = assert (not (isNull ty)) ty -let typeIsNotQueryable (ty: Type) = +let typeIsNotQueryable (ty: Type) = (ty :? TypeBuilder) || ((ty.GetType()).Equals(TypeBuilderInstantiationT)) //---------------------------------------------------------------------------- // convFieldSpec //---------------------------------------------------------------------------- let queryableTypeGetField _emEnv (parentT: Type) (fref: ILFieldRef) = - let res = parentT.GetField(fref.Name, BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.Static ) - match res with + let res = parentT.GetField(fref.Name, BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.Static ) + match res with | null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("field", fref.Name, fref.DeclaringTypeRef.FullName, fref.DeclaringTypeRef.Scope.QualifiedName), range0)) | _ -> res - -let nonQueryableTypeGetField (parentTI: Type) (fieldInfo: FieldInfo) : FieldInfo = - let res = - if parentTI.IsGenericType then TypeBuilder.GetField(parentTI, fieldInfo) + +let nonQueryableTypeGetField (parentTI: Type) (fieldInfo: FieldInfo) : FieldInfo = + let res = + if parentTI.IsGenericType then TypeBuilder.GetField(parentTI, fieldInfo) else fieldInfo - match res with + match res with | null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("field", fieldInfo.Name, parentTI.AssemblyQualifiedName, parentTI.Assembly.FullName), range0)) | _ -> res let convFieldSpec cenv emEnv fspec = let fref = fspec.FieldRef - let tref = fref.DeclaringTypeRef + let tref = fref.DeclaringTypeRef let parentTI = convType cenv emEnv fspec.DeclaringType if isEmittedTypeRef emEnv tref then // NOTE: if "convType becomes convCreatedType", then handle queryable types here too. [bug 4063] (necessary? what repro?) @@ -693,11 +667,11 @@ let convFieldSpec cenv emEnv fspec = nonQueryableTypeGetField parentTI fieldB else // Prior type. - if typeIsNotQueryable parentTI then + if typeIsNotQueryable parentTI then let parentT = getTypeConstructor parentTI - let fieldInfo = queryableTypeGetField emEnv parentT fref + let fieldInfo = queryableTypeGetField emEnv parentT fref nonQueryableTypeGetField parentTI fieldInfo - else + else queryableTypeGetField emEnv parentTI fspec.FieldRef //---------------------------------------------------------------------------- @@ -708,10 +682,10 @@ let queryableTypeGetMethodBySearch cenv emEnv parentT (mref: ILMethodRef) = let cconv = (if mref.CallingConv.IsStatic then BindingFlags.Static else BindingFlags.Instance) let methInfos = parentT.GetMethods(cconv ||| BindingFlags.Public ||| BindingFlags.NonPublic) |> Array.toList (* First, filter on name, if unique, then binding "done" *) - let tyargTs = getGenericArgumentsOfType parentT + let tyargTs = getGenericArgumentsOfType parentT let methInfos = methInfos |> List.filter (fun methInfo -> methInfo.Name = mref.Name) - match methInfos with - | [methInfo] -> + match methInfos with + | [methInfo] -> methInfo | _ -> (* Second, type match. Note type erased (non-generic) F# code would not type match but they have unique names *) @@ -720,29 +694,29 @@ let queryableTypeGetMethodBySearch cenv emEnv parentT (mref: ILMethodRef) = match a with | None -> true | Some a -> - if + if // obvious case - p.IsAssignableFrom a + p.IsAssignableFrom a then true elif // both are generic - p.IsGenericType && a.IsGenericType + p.IsGenericType && a.IsGenericType // non obvious due to contravariance: Action where T: IFoo accepts Action (for FooImpl: IFoo) - && p.GetGenericTypeDefinition().IsAssignableFrom(a.GetGenericTypeDefinition()) + && p.GetGenericTypeDefinition().IsAssignableFrom(a.GetGenericTypeDefinition()) then true else false let satisfiesAllParameters (args: Type option array) (ps: Type array) = if Array.length args <> Array.length ps then false else Array.forall2 satisfiesParameter args ps - + let select (methInfo: MethodInfo) = // mref implied Types - let mtyargTIs = getGenericArgumentsOfMethod methInfo - + let mtyargTIs = getGenericArgumentsOfMethod methInfo + if mtyargTIs.Length <> mref.GenericArity then false (* method generic arity mismatch *) else - // methInfo implied Types + // methInfo implied Types let methodParameters = methInfo.GetParameters() let argTypes = mref.ArgTypes |> List.toArray if argTypes.Length <> methodParameters.Length then false (* method argument length mismatch *) else @@ -756,134 +730,134 @@ let queryableTypeGetMethodBySearch cenv emEnv parentT (mref: ILMethodRef) = // without this check, subsequent call to convTypes would fail because it // constructs generic type without checking constraints if not (satisfiesAllParameters mrefParameterTypes haveArgTs) then false else - - let argTs, resT = + + let argTs, resT = let emEnv = envPushTyvars emEnv (Array.append tyargTs mtyargTIs) let argTs = convTypes cenv emEnv mref.ArgTypes let resT = convType cenv emEnv mref.ReturnType - argTs, resT - + argTs, resT + let haveResT = methInfo.ReturnType (* check for match *) if argTs.Length <> methodParameters.Length then false (* method argument length mismatch *) else let res = equalTypes resT haveResT && equalTypeLists argTs (haveArgTs |> Array.toList) res - + match List.tryFind select methInfos with - | None -> + | None -> let methNames = methInfos |> List.map (fun m -> m.Name) |> List.distinct - failwithf "convMethodRef: could not bind to method '%A' of type '%s'" (System.String.Join(", ", methNames)) parentT.AssemblyQualifiedName + failwithf "convMethodRef: could not bind to method '%A' of type '%s'" (String.Join(", ", methNames)) parentT.AssemblyQualifiedName | Some methInfo -> methInfo (* return MethodInfo for (generic) type's (generic) method *) - + let queryableTypeGetMethod cenv emEnv parentT (mref: ILMethodRef) = assert(not (typeIsNotQueryable parentT)) - if mref.GenericArity = 0 then - let tyargTs = getGenericArgumentsOfType parentT - let argTs, resT = + if mref.GenericArity = 0 then + let tyargTs = getGenericArgumentsOfType parentT + let argTs, resT = let emEnv = envPushTyvars emEnv tyargTs let argTs = convTypesToArray cenv emEnv mref.ArgTypes let resT = convType cenv emEnv mref.ReturnType - argTs, resT + argTs, resT let stat = mref.CallingConv.IsStatic let cconv = (if stat then BindingFlags.Static else BindingFlags.Instance) - let methInfo = - try - parentT.GetMethod(mref.Name, cconv ||| BindingFlags.Public ||| BindingFlags.NonPublic, - null, - argTs, + let methInfo = + try + parentT.GetMethod(mref.Name, cconv ||| BindingFlags.Public ||| BindingFlags.NonPublic, + null, + argTs, (null: ParameterModifier[])) - // This can fail if there is an ambiguity w.r.t. return type + // This can fail if there is an ambiguity w.r.t. return type with _ -> null - if (isNonNull methInfo && equalTypes resT methInfo.ReturnType) then + if (isNonNull methInfo && equalTypes resT methInfo.ReturnType) then methInfo else queryableTypeGetMethodBySearch cenv emEnv parentT mref - else + else queryableTypeGetMethodBySearch cenv emEnv parentT mref -let nonQueryableTypeGetMethod (parentTI: Type) (methInfo: MethodInfo) : MethodInfo = +let nonQueryableTypeGetMethod (parentTI: Type) (methInfo: MethodInfo) : MethodInfo = if (parentTI.IsGenericType && - not (equalTypes parentTI (getTypeConstructor parentTI))) + not (equalTypes parentTI (getTypeConstructor parentTI))) then TypeBuilder.GetMethod(parentTI, methInfo ) - else methInfo + else methInfo let convMethodRef cenv emEnv (parentTI: Type) (mref: ILMethodRef) = let parent = mref.DeclaringTypeRef - let res = + let res = if isEmittedTypeRef emEnv parent then - // NOTE: if "convType becomes convCreatedType", then handle queryable types here too. [bug 4063] + // NOTE: if "convType becomes convCreatedType", then handle queryable types here too. [bug 4063] // Emitted type, can get fully generic MethodBuilder from env. let methB = envGetMethB emEnv mref nonQueryableTypeGetMethod parentTI methB else // Prior type. - if typeIsNotQueryable parentTI then + if typeIsNotQueryable parentTI then let parentT = getTypeConstructor parentTI - let methInfo = queryableTypeGetMethod cenv emEnv parentT mref + let methInfo = queryableTypeGetMethod cenv emEnv parentT mref nonQueryableTypeGetMethod parentTI methInfo - else - queryableTypeGetMethod cenv emEnv parentTI mref - match res with + else + queryableTypeGetMethod cenv emEnv parentTI mref + match res with | null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("method", mref.Name, parentTI.FullName, parentTI.Assembly.FullName), range0)) | _ -> res //---------------------------------------------------------------------------- // convMethodSpec //---------------------------------------------------------------------------- - + let convMethodSpec cenv emEnv (mspec: ILMethodSpec) = let typT = convType cenv emEnv mspec.DeclaringType (* (instanced) parent Type *) let methInfo = convMethodRef cenv emEnv typT mspec.MethodRef (* (generic) method of (generic) parent *) let methInfo = - if isNil mspec.GenericArgs then - methInfo // non generic - else + if isNil mspec.GenericArgs then + methInfo // non generic + else let minstTs = convTypesToArray cenv emEnv mspec.GenericArgs - let methInfo = methInfo.MakeGenericMethod minstTs // instantiate method + let methInfo = methInfo.MakeGenericMethod minstTs // instantiate method methInfo - methInfo + methInfo /// Get a constructor on a non-TypeBuilder type let queryableTypeGetConstructor cenv emEnv (parentT: Type) (mref: ILMethodRef) = let tyargTs = getGenericArgumentsOfType parentT - let reqArgTs = + let reqArgTs = let emEnv = envPushTyvars emEnv tyargTs convTypesToArray cenv emEnv mref.ArgTypes - let res = parentT.GetConstructor(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, null, reqArgTs, null) - match res with + let res = parentT.GetConstructor(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, null, reqArgTs, null) + match res with | null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("constructor", mref.Name, parentT.FullName, parentT.Assembly.FullName), range0)) | _ -> res -let nonQueryableTypeGetConstructor (parentTI: Type) (consInfo: ConstructorInfo) : ConstructorInfo = +let nonQueryableTypeGetConstructor (parentTI: Type) (consInfo: ConstructorInfo) : ConstructorInfo = if parentTI.IsGenericType then TypeBuilder.GetConstructor(parentTI, consInfo) else consInfo -/// convConstructorSpec (like convMethodSpec) +/// convConstructorSpec (like convMethodSpec) let convConstructorSpec cenv emEnv (mspec: ILMethodSpec) = let mref = mspec.MethodRef let parentTI = convType cenv emEnv mspec.DeclaringType - let res = + let res = if isEmittedTypeRef emEnv mref.DeclaringTypeRef then - let consB = envGetConsB emEnv mref - nonQueryableTypeGetConstructor parentTI consB + let consB = envGetConsB emEnv mref + nonQueryableTypeGetConstructor parentTI consB else // Prior type. - if typeIsNotQueryable parentTI then - let parentT = getTypeConstructor parentTI - let ctorG = queryableTypeGetConstructor cenv emEnv parentT mref + if typeIsNotQueryable parentTI then + let parentT = getTypeConstructor parentTI + let ctorG = queryableTypeGetConstructor cenv emEnv parentT mref nonQueryableTypeGetConstructor parentTI ctorG else - queryableTypeGetConstructor cenv emEnv parentTI mref - match res with + queryableTypeGetConstructor cenv emEnv parentTI mref + match res with | null -> error(Error(FSComp.SR.itemNotFoundInTypeDuringDynamicCodeGen ("constructor", "", parentTI.FullName, parentTI.Assembly.FullName), range0)) | _ -> res let emitLabelMark emEnv (ilG: ILGenerator) (label: ILCodeLabel) = let lab = envGetLabel emEnv label ilG.MarkLabelAndLog lab - + ///Emit comparison instructions. -let emitInstrCompare emEnv (ilG: ILGenerator) comp targ = +let emitInstrCompare emEnv (ilG: ILGenerator) comp targ = match comp with | BI_beq -> ilG.EmitAndLog (OpCodes.Beq, envGetLabel emEnv targ) | BI_bge -> ilG.EmitAndLog (OpCodes.Bge, envGetLabel emEnv targ) @@ -905,17 +879,17 @@ let emitInstrVolatile (ilG: ILGenerator) = function | Nonvolatile -> () /// Emit the align. prefix -let emitInstrAlign (ilG: ILGenerator) = function +let emitInstrAlign (ilG: ILGenerator) = function | Aligned -> () | Unaligned1 -> ilG.Emit(OpCodes.Unaligned, 1L) // note: doc says use "long" overload! | Unaligned2 -> ilG.Emit(OpCodes.Unaligned, 2L) | Unaligned4 -> ilG.Emit(OpCodes.Unaligned, 3L) /// Emit the tail. prefix if necessary -let emitInstrTail (ilG: ILGenerator) tail emitTheCall = +let emitInstrTail (cenv: cenv) (ilG: ILGenerator) tail emitTheCall = match tail with - | Tailcall -> ilG.EmitAndLog OpCodes.Tailcall; emitTheCall(); ilG.EmitAndLog OpCodes.Ret - | Normalcall -> emitTheCall() + | Tailcall when cenv.emitTailcalls -> ilG.EmitAndLog OpCodes.Tailcall; emitTheCall(); ilG.EmitAndLog OpCodes.Ret + | _ -> emitTheCall() let emitInstrNewobj cenv emEnv (ilG: ILGenerator) mspec varargs = match varargs with @@ -927,7 +901,7 @@ let emitSilverlightCheck (ilG: ILGenerator) = () let emitInstrCall cenv emEnv (ilG: ILGenerator) opCall tail (mspec: ILMethodSpec) varargs = - emitInstrTail ilG tail (fun () -> + emitInstrTail cenv ilG tail (fun () -> if mspec.MethodRef.Name = ".ctor" || mspec.MethodRef.Name = ".cctor" then let cinfo = convConstructorSpec cenv emEnv mspec match varargs with @@ -940,22 +914,22 @@ let emitInstrCall cenv emEnv (ilG: ILGenerator) opCall tail (mspec: ILMethodSpec | Some varargTys -> ilG.EmitCall (opCall, minfo, convTypesToArray cenv emEnv varargTys) ) -let getGenericMethodDefinition q (ty: Type) = - let gminfo = - match q with +let getGenericMethodDefinition q (ty: Type) = + let gminfo = + match q with | Quotations.Patterns.Call(_, minfo, _) -> minfo.GetGenericMethodDefinition() | _ -> failwith "unexpected failure decoding quotation at ilreflect startup" gminfo.MakeGenericMethod [| ty |] -let getArrayMethInfo n ty = - match n with +let getArrayMethInfo n ty = + match n with | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray2D null 0 0 @@> ty | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray3D null 0 0 0 @@> ty | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.GetArray4D null 0 0 0 0 @@> ty | _ -> invalidArg "n" "not expecting array dimension > 4" - -let setArrayMethInfo n ty = - match n with + +let setArrayMethInfo n ty = + match n with | 2 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray2D null 0 0 0 @@> ty | 3 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray3D null 0 0 0 0 @@> ty | 4 -> getGenericMethodDefinition <@@ LanguagePrimitives.IntrinsicFunctions.SetArray4D null 0 0 0 0 0 @@> ty @@ -966,10 +940,10 @@ let setArrayMethInfo n ty = // emitInstr cenv //---------------------------------------------------------------------------- -let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = - match instr with - | AI_add -> ilG.EmitAndLog OpCodes.Add - | AI_add_ovf -> ilG.EmitAndLog OpCodes.Add_Ovf +let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = + match instr with + | AI_add -> ilG.EmitAndLog OpCodes.Add + | AI_add_ovf -> ilG.EmitAndLog OpCodes.Add_Ovf | AI_add_ovf_un -> ilG.EmitAndLog OpCodes.Add_Ovf_Un | AI_and -> ilG.EmitAndLog OpCodes.And | AI_div -> ilG.EmitAndLog OpCodes.Div @@ -979,56 +953,56 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | AI_cgt_un -> ilG.EmitAndLog OpCodes.Cgt_Un | AI_clt -> ilG.EmitAndLog OpCodes.Clt | AI_clt_un -> ilG.EmitAndLog OpCodes.Clt_Un - // conversion - | AI_conv dt -> + // conversion + | AI_conv dt -> match dt with | DT_I -> ilG.EmitAndLog OpCodes.Conv_I | DT_I1 -> ilG.EmitAndLog OpCodes.Conv_I1 | DT_I2 -> ilG.EmitAndLog OpCodes.Conv_I2 | DT_I4 -> ilG.EmitAndLog OpCodes.Conv_I4 | DT_I8 -> ilG.EmitAndLog OpCodes.Conv_I8 - | DT_U -> ilG.EmitAndLog OpCodes.Conv_U - | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_U1 - | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_U2 - | DT_U4 -> ilG.EmitAndLog OpCodes.Conv_U4 + | DT_U -> ilG.EmitAndLog OpCodes.Conv_U + | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_U1 + | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_U2 + | DT_U4 -> ilG.EmitAndLog OpCodes.Conv_U4 | DT_U8 -> ilG.EmitAndLog OpCodes.Conv_U8 | DT_R -> ilG.EmitAndLog OpCodes.Conv_R_Un | DT_R4 -> ilG.EmitAndLog OpCodes.Conv_R4 | DT_R8 -> ilG.EmitAndLog OpCodes.Conv_R8 | DT_REF -> failwith "AI_conv DT_REF?" // XXX - check // conversion - ovf checks - | AI_conv_ovf dt -> + | AI_conv_ovf dt -> match dt with | DT_I -> ilG.EmitAndLog OpCodes.Conv_Ovf_I | DT_I1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I1 | DT_I2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I2 | DT_I4 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I4 | DT_I8 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I8 - | DT_U -> ilG.EmitAndLog OpCodes.Conv_Ovf_U - | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U1 - | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U2 + | DT_U -> ilG.EmitAndLog OpCodes.Conv_Ovf_U + | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U1 + | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U2 | DT_U4 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U4 | DT_U8 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U8 - | DT_R -> failwith "AI_conv_ovf DT_R?" // XXX - check - | DT_R4 -> failwith "AI_conv_ovf DT_R4?" // XXX - check - | DT_R8 -> failwith "AI_conv_ovf DT_R8?" // XXX - check + | DT_R -> failwith "AI_conv_ovf DT_R?" // XXX - check + | DT_R4 -> failwith "AI_conv_ovf DT_R4?" // XXX - check + | DT_R8 -> failwith "AI_conv_ovf DT_R8?" // XXX - check | DT_REF -> failwith "AI_conv_ovf DT_REF?" // XXX - check - // conversion - ovf checks and unsigned - | AI_conv_ovf_un dt -> + // conversion - ovf checks and unsigned + | AI_conv_ovf_un dt -> match dt with | DT_I -> ilG.EmitAndLog OpCodes.Conv_Ovf_I_Un | DT_I1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I1_Un | DT_I2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I2_Un | DT_I4 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I4_Un | DT_I8 -> ilG.EmitAndLog OpCodes.Conv_Ovf_I8_Un - | DT_U -> ilG.EmitAndLog OpCodes.Conv_Ovf_U_Un - | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U1_Un - | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U2_Un - | DT_U4 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U4_Un + | DT_U -> ilG.EmitAndLog OpCodes.Conv_Ovf_U_Un + | DT_U1 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U1_Un + | DT_U2 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U2_Un + | DT_U4 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U4_Un | DT_U8 -> ilG.EmitAndLog OpCodes.Conv_Ovf_U8_Un - | DT_R -> failwith "AI_conv_ovf_un DT_R?" // XXX - check - | DT_R4 -> failwith "AI_conv_ovf_un DT_R4?" // XXX - check - | DT_R8 -> failwith "AI_conv_ovf_un DT_R8?" // XXX - check + | DT_R -> failwith "AI_conv_ovf_un DT_R?" // XXX - check + | DT_R4 -> failwith "AI_conv_ovf_un DT_R4?" // XXX - check + | DT_R8 -> failwith "AI_conv_ovf_un DT_R8?" // XXX - check | DT_REF -> failwith "AI_conv_ovf_un DT_REF?" // XXX - check | AI_mul -> ilG.EmitAndLog OpCodes.Mul | AI_mul_ovf -> ilG.EmitAndLog OpCodes.Mul_Ovf @@ -1054,10 +1028,10 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | AI_ldc (DT_I8, ILConst.I8 i64) -> ilG.Emit(OpCodes.Ldc_I8, i64) | AI_ldc (DT_R4, ILConst.R4 r32) -> ilG.Emit(OpCodes.Ldc_R4, r32) | AI_ldc (DT_R8, ILConst.R8 r64) -> ilG.Emit(OpCodes.Ldc_R8, r64) - | AI_ldc (_, _ ) -> failwith "emitInstrI_arith (AI_ldc (ty, const)) iltyped" + | AI_ldc _ -> failwith "emitInstrI_arith (AI_ldc (ty, const)) iltyped" | I_ldarg u16 -> ilG.EmitAndLog (OpCodes.Ldarg, int16 u16) | I_ldarga u16 -> ilG.EmitAndLog (OpCodes.Ldarga, int16 u16) - | I_ldind (align, vol, dt) -> + | I_ldind (align, vol, dt) -> emitInstrAlign ilG align emitInstrVolatile ilG vol match dt with @@ -1078,7 +1052,7 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_ldloc u16 -> ilG.EmitAndLog (OpCodes.Ldloc, int16 u16) | I_ldloca u16 -> ilG.EmitAndLog (OpCodes.Ldloca, int16 u16) | I_starg u16 -> ilG.EmitAndLog (OpCodes.Starg, int16 u16) - | I_stind (align, vol, dt) -> + | I_stind (align, vol, dt) -> emitInstrAlign ilG align emitInstrVolatile ilG vol match dt with @@ -1099,58 +1073,58 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_stloc u16 -> ilG.EmitAndLog (OpCodes.Stloc, int16 u16) | I_br targ -> ilG.EmitAndLog (OpCodes.Br, envGetLabel emEnv targ) | I_jmp mspec -> ilG.EmitAndLog (OpCodes.Jmp, convMethodSpec cenv emEnv mspec) - | I_brcmp (comp, targ) -> emitInstrCompare emEnv ilG comp targ + | I_brcmp (comp, targ) -> emitInstrCompare emEnv ilG comp targ | I_switch labels -> ilG.Emit(OpCodes.Switch, Array.ofList (List.map (envGetLabel emEnv) labels)) | I_ret -> ilG.EmitAndLog OpCodes.Ret - | I_call (tail, mspec, varargs) -> + | I_call (tail, mspec, varargs) -> emitSilverlightCheck ilG emitInstrCall cenv emEnv ilG OpCodes.Call tail mspec varargs - | I_callvirt (tail, mspec, varargs) -> + | I_callvirt (tail, mspec, varargs) -> emitSilverlightCheck ilG emitInstrCall cenv emEnv ilG OpCodes.Callvirt tail mspec varargs - | I_callconstraint (tail, ty, mspec, varargs) -> + | I_callconstraint (tail, ty, mspec, varargs) -> ilG.Emit(OpCodes.Constrained, convType cenv emEnv ty) - emitInstrCall cenv emEnv ilG OpCodes.Callvirt tail mspec varargs - - | I_calli (tail, callsig, None) -> - emitInstrTail ilG tail (fun () -> - ilG.EmitCalli(OpCodes.Calli, - convCallConv callsig.CallingConv, - convType cenv emEnv callsig.ReturnType, - convTypesToArray cenv emEnv callsig.ArgTypes, - Unchecked.defaultof)) - - | I_calli (tail, callsig, Some varargTys) -> - emitInstrTail ilG tail (fun () -> - ilG.EmitCalli(OpCodes.Calli, - convCallConv callsig.CallingConv, - convType cenv emEnv callsig.ReturnType, - convTypesToArray cenv emEnv callsig.ArgTypes, - convTypesToArray cenv emEnv varargTys)) - - | I_ldftn mspec -> + emitInstrCall cenv emEnv ilG OpCodes.Callvirt tail mspec varargs + + | I_calli (tail, callsig, None) -> + emitInstrTail cenv ilG tail (fun () -> + ilG.EmitCalli(OpCodes.Calli, + convCallConv callsig.CallingConv, + convType cenv emEnv callsig.ReturnType, + convTypesToArray cenv emEnv callsig.ArgTypes, + Unchecked.defaultof)) + + | I_calli (tail, callsig, Some varargTys) -> + emitInstrTail cenv ilG tail (fun () -> + ilG.EmitCalli(OpCodes.Calli, + convCallConv callsig.CallingConv, + convType cenv emEnv callsig.ReturnType, + convTypesToArray cenv emEnv callsig.ArgTypes, + convTypesToArray cenv emEnv varargTys)) + + | I_ldftn mspec -> ilG.EmitAndLog (OpCodes.Ldftn, convMethodSpec cenv emEnv mspec) - | I_newobj (mspec, varargs) -> + | I_newobj (mspec, varargs) -> emitInstrNewobj cenv emEnv ilG mspec varargs | I_throw -> ilG.EmitAndLog OpCodes.Throw | I_endfinally -> ilG.EmitAndLog OpCodes.Endfinally - | I_endfilter -> ilG.EmitAndLog OpCodes.Endfilter + | I_endfilter -> ilG.EmitAndLog OpCodes.Endfilter | I_leave label -> ilG.EmitAndLog (OpCodes.Leave, envGetLabel emEnv label) | I_ldsfld (vol, fspec) -> emitInstrVolatile ilG vol; ilG.EmitAndLog (OpCodes.Ldsfld, convFieldSpec cenv emEnv fspec) | I_ldfld (align, vol, fspec) -> emitInstrAlign ilG align; emitInstrVolatile ilG vol; ilG.EmitAndLog (OpCodes.Ldfld, convFieldSpec cenv emEnv fspec) | I_ldsflda fspec -> ilG.EmitAndLog (OpCodes.Ldsflda, convFieldSpec cenv emEnv fspec) | I_ldflda fspec -> ilG.EmitAndLog (OpCodes.Ldflda, convFieldSpec cenv emEnv fspec) - | I_stsfld (vol, fspec) -> + | I_stsfld (vol, fspec) -> emitInstrVolatile ilG vol ilG.EmitAndLog (OpCodes.Stsfld, convFieldSpec cenv emEnv fspec) - | I_stfld (align, vol, fspec) -> + | I_stfld (align, vol, fspec) -> emitInstrAlign ilG align emitInstrVolatile ilG vol ilG.EmitAndLog (OpCodes.Stfld, convFieldSpec cenv emEnv fspec) @@ -1166,12 +1140,12 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_cpobj ty -> ilG.EmitAndLog (OpCodes.Cpobj, convType cenv emEnv ty) | I_initobj ty -> ilG.EmitAndLog (OpCodes.Initobj, convType cenv emEnv ty) - | I_ldobj (align, vol, ty) -> + | I_ldobj (align, vol, ty) -> emitInstrAlign ilG align emitInstrVolatile ilG vol ilG.EmitAndLog (OpCodes.Ldobj, convType cenv emEnv ty) - | I_stobj (align, vol, ty) -> + | I_stobj (align, vol, ty) -> emitInstrAlign ilG align emitInstrVolatile ilG vol ilG.EmitAndLog (OpCodes.Stobj, convType cenv emEnv ty) @@ -1181,19 +1155,19 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_unbox_any ty -> ilG.EmitAndLog (OpCodes.Unbox_Any, convType cenv emEnv ty) | I_sizeof ty -> ilG.EmitAndLog (OpCodes.Sizeof, convType cenv emEnv ty) - // Generalized array instructions. - // In AbsIL these instructions include - // both the single-dimensional variants (with ILArrayShape == ILArrayShape.SingleDimensional) - // and calls to the "special" multi-dimensional "methods" such as - // newobj void string[, ] :: .ctor(int32, int32) - // call string string[, ] :: Get(int32, int32) - // call string& string[, ] :: Address(int32, int32) - // call void string[, ] :: Set(int32, int32, string) - // The IL reader transforms calls of this form to the corresponding - // generalized instruction with the corresponding ILArrayShape - // argument. This is done to simplify the IL and make it more uniform. - // The IL writer then reverses this when emitting the binary. - | I_ldelem dt -> + // Generalized array instructions. + // In AbsIL these instructions include + // both the single-dimensional variants (with ILArrayShape == ILArrayShape.SingleDimensional) + // and calls to the "special" multi-dimensional "methods" such as + // newobj void string[, ] :: .ctor(int32, int32) + // call string string[, ] :: Get(int32, int32) + // call string& string[, ] :: Address(int32, int32) + // call void string[, ] :: Set(int32, int32, string) + // The IL reader transforms calls of this form to the corresponding + // generalized instruction with the corresponding ILArrayShape + // argument. This is done to simplify the IL and make it more uniform. + // The IL writer then reverses this when emitting the binary. + | I_ldelem dt -> match dt with | DT_I -> ilG.EmitAndLog OpCodes.Ldelem_I | DT_I1 -> ilG.EmitAndLog OpCodes.Ldelem_I1 @@ -1210,7 +1184,7 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | DT_U8 -> failwith "emitInstr cenv: ldelem U8" | DT_REF -> ilG.EmitAndLog OpCodes.Ldelem_Ref - | I_stelem dt -> + | I_stelem dt -> match dt with | DT_I -> ilG.EmitAndLog OpCodes.Stelem_I | DT_I1 -> ilG.EmitAndLog OpCodes.Stelem_I1 @@ -1227,53 +1201,53 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | DT_U8 -> failwith "emitInstr cenv: stelem U8" | DT_REF -> ilG.EmitAndLog OpCodes.Stelem_Ref - | I_ldelema (ro, _isNativePtr, shape, ty) -> + | I_ldelema (ro, _isNativePtr, shape, ty) -> if (ro = ReadonlyAddress) then ilG.EmitAndLog OpCodes.Readonly - if (shape = ILArrayShape.SingleDimensional) + if (shape = ILArrayShape.SingleDimensional) then ilG.EmitAndLog (OpCodes.Ldelema, convType cenv emEnv ty) - else - let aty = convType cenv emEnv (ILType.Array(shape, ty)) + else + let aty = convType cenv emEnv (ILType.Array(shape, ty)) let ety = aty.GetElementType() - let rty = ety.MakeByRefType() - let meth = modB.GetArrayMethodAndLog (aty, "Address", System.Reflection.CallingConventions.HasThis, rty, Array.create shape.Rank (typeof) ) + let rty = ety.MakeByRefType() + let meth = modB.GetArrayMethodAndLog (aty, "Address", CallingConventions.HasThis, rty, Array.create shape.Rank typeof ) ilG.EmitAndLog (OpCodes.Call, meth) - | I_ldelem_any (shape, ty) -> + | I_ldelem_any (shape, ty) -> if (shape = ILArrayShape.SingleDimensional) then ilG.EmitAndLog (OpCodes.Ldelem, convType cenv emEnv ty) - else - let aty = convType cenv emEnv (ILType.Array(shape, ty)) + else + let aty = convType cenv emEnv (ILType.Array(shape, ty)) let ety = aty.GetElementType() - let meth = + let meth = #if ENABLE_MONO_SUPPORT // See bug 6254: Mono has a bug in reflection-emit dynamic calls to the "Get", "Address" or "Set" methods on arrays - if runningOnMono then + if runningOnMono then getArrayMethInfo shape.Rank ety else #endif - modB.GetArrayMethodAndLog (aty, "Get", System.Reflection.CallingConventions.HasThis, ety, Array.create shape.Rank (typeof) ) + modB.GetArrayMethodAndLog (aty, "Get", CallingConventions.HasThis, ety, Array.create shape.Rank typeof ) ilG.EmitAndLog (OpCodes.Call, meth) - | I_stelem_any (shape, ty) -> + | I_stelem_any (shape, ty) -> if (shape = ILArrayShape.SingleDimensional) then ilG.EmitAndLog (OpCodes.Stelem, convType cenv emEnv ty) - else - let aty = convType cenv emEnv (ILType.Array(shape, ty)) + else + let aty = convType cenv emEnv (ILType.Array(shape, ty)) let ety = aty.GetElementType() - let meth = + let meth = #if ENABLE_MONO_SUPPORT // See bug 6254: Mono has a bug in reflection-emit dynamic calls to the "Get", "Address" or "Set" methods on arrays - if runningOnMono then + if runningOnMono then setArrayMethInfo shape.Rank ety else #endif - modB.GetArrayMethodAndLog (aty, "Set", System.Reflection.CallingConventions.HasThis, (null: Type), Array.append (Array.create shape.Rank (typeof)) (Array.ofList [ ety ])) + modB.GetArrayMethodAndLog (aty, "Set", CallingConventions.HasThis, (null: Type), Array.append (Array.create shape.Rank typeof) (Array.ofList [ ety ])) ilG.EmitAndLog (OpCodes.Call, meth) - | I_newarr (shape, ty) -> + | I_newarr (shape, ty) -> if (shape = ILArrayShape.SingleDimensional) then ilG.EmitAndLog (OpCodes.Newarr, convType cenv emEnv ty) - else - let aty = convType cenv emEnv (ILType.Array(shape, ty)) - let meth = modB.GetArrayMethodAndLog (aty, ".ctor", System.Reflection.CallingConventions.HasThis, (null: Type), Array.create shape.Rank (typeof)) + else + let aty = convType cenv emEnv (ILType.Array(shape, ty)) + let meth = modB.GetArrayMethodAndLog (aty, ".ctor", CallingConventions.HasThis, (null: Type), Array.create shape.Rank typeof) ilG.EmitAndLog (OpCodes.Newobj, meth) | I_ldlen -> ilG.EmitAndLog OpCodes.Ldlen @@ -1282,7 +1256,7 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_refanyval ty -> ilG.EmitAndLog (OpCodes.Refanyval, convType cenv emEnv ty) | I_rethrow -> ilG.EmitAndLog OpCodes.Rethrow | I_break -> ilG.EmitAndLog OpCodes.Break - | I_seqpoint src -> + | I_seqpoint src -> #if FX_RESHAPED_REFEMIT ignore src () @@ -1295,17 +1269,17 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = | I_arglist -> ilG.EmitAndLog OpCodes.Arglist | I_localloc -> ilG.EmitAndLog OpCodes.Localloc - | I_cpblk (align, vol) -> + | I_cpblk (align, vol) -> emitInstrAlign ilG align emitInstrVolatile ilG vol ilG.EmitAndLog OpCodes.Cpblk - | I_initblk (align, vol) -> + | I_initblk (align, vol) -> emitInstrAlign ilG align emitInstrVolatile ilG vol ilG.EmitAndLog OpCodes.Initblk - | EI_ldlen_multi (_, m) -> + | EI_ldlen_multi (_, m) -> emitInstr cenv modB emEnv ilG (mkLdcInt32 m) emitInstr cenv modB emEnv ilG (mkNormalCall(mkILNonGenericMethSpecInTy(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [cenv.ilg.typ_Int32], cenv.ilg.typ_Int32))) @@ -1315,19 +1289,19 @@ let rec emitInstr cenv (modB: ModuleBuilder) emEnv (ilG: ILGenerator) instr = let emitCode cenv modB emEnv (ilG: ILGenerator) (code: ILCode) = // Pre-define the labels pending determining their actual marks let pc2lab = Dictionary() - let emEnv = - (emEnv, code.Labels) ||> Seq.fold (fun emEnv (KeyValue(label, pc)) -> + let emEnv = + (emEnv, code.Labels) ||> Seq.fold (fun emEnv (KeyValue(label, pc)) -> let lab = ilG.DefineLabelAndLog () pc2lab.[pc] <- match pc2lab.TryGetValue pc with | true, labels -> lab :: labels | _ -> [lab] envSetLabel emEnv label lab) - + // Build a table that contains the operations that define where exception handlers are let pc2action = Dictionary() let lab2pc = code.Labels - let add lab action = + let add lab action = let pc = lab2pc.[lab] pc2action.[pc] <- match pc2action.TryGetValue pc with @@ -1335,25 +1309,25 @@ let emitCode cenv modB emEnv (ilG: ILGenerator) (code: ILCode) = | _ -> [action] for e in code.Exceptions do - let (startTry, _endTry) = e.Range + let startTry, _endTry = e.Range add startTry (fun () -> ilG.BeginExceptionBlockAndLog () |> ignore) - match e.Clause with - | ILExceptionClause.Finally(startHandler, endHandler) -> + match e.Clause with + | ILExceptionClause.Finally(startHandler, endHandler) -> add startHandler ilG.BeginFinallyBlockAndLog add endHandler ilG.EndExceptionBlockAndLog - | ILExceptionClause.Fault(startHandler, endHandler) -> + | ILExceptionClause.Fault(startHandler, endHandler) -> add startHandler ilG.BeginFaultBlockAndLog add endHandler ilG.EndExceptionBlockAndLog - | ILExceptionClause.FilterCatch((startFilter, _), (startHandler, endHandler)) -> + | ILExceptionClause.FilterCatch((startFilter, _), (startHandler, endHandler)) -> add startFilter ilG.BeginExceptFilterBlockAndLog add startHandler (fun () -> ilG.BeginCatchBlockAndLog null) add endHandler ilG.EndExceptionBlockAndLog - | ILExceptionClause.TypeCatch(ty, (startHandler, endHandler)) -> + | ILExceptionClause.TypeCatch(ty, (startHandler, endHandler)) -> add startHandler (fun () -> ilG.BeginCatchBlockAndLog (convType cenv emEnv ty)) add endHandler ilG.EndExceptionBlockAndLog @@ -1363,7 +1337,7 @@ let emitCode cenv modB emEnv (ilG: ILGenerator) (code: ILCode) = for pc = 0 to instrs.Length do match pc2action.TryGetValue pc with | true, actions -> - for action in actions do + for action in actions do action() | _ -> () @@ -1373,8 +1347,8 @@ let emitCode cenv modB emEnv (ilG: ILGenerator) (code: ILCode) = ilG.MarkLabelAndLog lab | _ -> () - if pc < instrs.Length then - match instrs.[pc] with + if pc < instrs.Length then + match instrs.[pc] with | I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction | i -> emitInstr cenv modB emEnv ilG i @@ -1392,23 +1366,23 @@ let emitLocal cenv emEnv (ilG: ILGenerator) (local: ILLocal) = let emitILMethodBody cenv modB emEnv (ilG: ILGenerator) (ilmbody: ILMethodBody) = let localBs = Array.map (emitLocal cenv emEnv ilG) (List.toArray ilmbody.Locals) let emEnv = envSetLocals emEnv localBs - emitCode cenv modB emEnv ilG ilmbody.Code + emitCode cenv modB emEnv ilG ilmbody.Code -let emitMethodBody cenv modB emEnv ilG _name (mbody: ILLazyMethodBody) = - match mbody.Contents with - | MethodBody.IL ilmbody -> emitILMethodBody cenv modB emEnv (ilG()) ilmbody +let emitMethodBody cenv modB emEnv ilG _name (mbody: MethodBody) = + match mbody with + | MethodBody.IL ilmbody -> emitILMethodBody cenv modB emEnv (ilG()) ilmbody.Value | MethodBody.PInvoke _pinvoke -> () | MethodBody.Abstract -> () - | MethodBody.Native -> failwith "emitMethodBody: native" + | MethodBody.Native -> failwith "emitMethodBody: native" | MethodBody.NotAvailable -> failwith "emitMethodBody: metadata only" let convCustomAttr cenv emEnv (cattr: ILAttribute) = - let methInfo = - match convConstructorSpec cenv emEnv cattr.Method with + let methInfo = + match convConstructorSpec cenv emEnv cattr.Method with | null -> failwithf "convCustomAttr: %+A" cattr.Method | res -> res - let data = getCustomAttrData cenv.ilg cattr + let data = getCustomAttrData cattr (methInfo, data) let emitCustomAttr cenv emEnv add cattr = add (convCustomAttr cenv emEnv cattr) @@ -1418,21 +1392,21 @@ let emitCustomAttrs cenv emEnv add (cattrs: ILAttributes) = Array.iter (emitCust // buildGenParams //---------------------------------------------------------------------------- -let buildGenParamsPass1 _emEnv defineGenericParameters (gps: ILGenericParameterDefs) = - match gps with - | [] -> () +let buildGenParamsPass1 _emEnv defineGenericParameters (gps: ILGenericParameterDefs) = + match gps with + | [] -> () | gps -> - let gpsNames = gps |> List.map (fun gp -> gp.Name) + let gpsNames = gps |> List.map (fun gp -> gp.Name) defineGenericParameters (Array.ofList gpsNames) |> ignore -let buildGenParamsPass1b cenv emEnv (genArgs: Type array) (gps: ILGenericParameterDefs) = - let genpBs = genArgs |> Array.map (fun x -> (x :?> GenericTypeParameterBuilder)) +let buildGenParamsPass1b cenv emEnv (genArgs: Type array) (gps: ILGenericParameterDefs) = + let genpBs = genArgs |> Array.map (fun x -> (x :?> GenericTypeParameterBuilder)) gps |> List.iteri (fun i (gp: ILGenericParameterDef) -> let gpB = genpBs.[i] // the Constraints are either the parent (base) type or interfaces. let constraintTs = convTypes cenv emEnv gp.Constraints - let interfaceTs, baseTs = List.partition (fun (ty: System.Type) -> ty.IsInterface) constraintTs + let interfaceTs, baseTs = List.partition (fun (ty: Type) -> ty.IsInterface) constraintTs // set base type constraint (match baseTs with [ ] -> () // Q: should a baseType be set? It is in some samples. Should this be a failure case? @@ -1443,17 +1417,17 @@ let buildGenParamsPass1b cenv emEnv (genArgs: Type array) (gps: ILGenericParamet gpB.SetInterfaceConstraints(Array.ofList interfaceTs) gp.CustomAttrs |> emitCustomAttrs cenv emEnv (wrapCustomAttr gpB.SetCustomAttribute) - let flags = GenericParameterAttributes.None + let flags = GenericParameterAttributes.None let flags = match gp.Variance with | NonVariant -> flags | CoVariant -> flags ||| GenericParameterAttributes.Covariant | ContraVariant -> flags ||| GenericParameterAttributes.Contravariant - - let flags = if gp.HasReferenceTypeConstraint then flags ||| GenericParameterAttributes.ReferenceTypeConstraint else flags + + let flags = if gp.HasReferenceTypeConstraint then flags ||| GenericParameterAttributes.ReferenceTypeConstraint else flags let flags = if gp.HasNotNullableValueTypeConstraint then flags ||| GenericParameterAttributes.NotNullableValueTypeConstraint else flags let flags = if gp.HasDefaultConstructorConstraint then flags ||| GenericParameterAttributes.DefaultConstructorConstraint else flags - + gpB.SetGenericParameterAttributes flags ) //---------------------------------------------------------------------------- @@ -1464,14 +1438,14 @@ let emitParameter cenv emEnv (defineParameter: int * ParameterAttributes * strin // -Type: ty // -Default: ILFieldInit option // -Marshal: NativeType option; (* Marshalling map for parameters. COM Interop only. *) - let attrs = flagsIf param.IsIn ParameterAttributes.In ||| + let attrs = flagsIf param.IsIn ParameterAttributes.In ||| flagsIf param.IsOut ParameterAttributes.Out ||| flagsIf param.IsOptional ParameterAttributes.Optional - let name = + let name = match param.Name with | Some name -> name | None -> "X" + string(i+1) - + let parB = defineParameter(i, attrs, name) emitCustomAttrs cenv emEnv (wrapCustomAttr parB.SetCustomAttribute) param.CustomAttrs @@ -1479,29 +1453,28 @@ let emitParameter cenv emEnv (defineParameter: int * ParameterAttributes * strin // buildMethodPass2 //---------------------------------------------------------------------------- -#if !FX_RESHAPED_REFEMIT || NETCOREAPP3_0 +#if !FX_RESHAPED_REFEMIT || NETCOREAPP3_1 let enablePInvoke = true #else -// We currently build targeting netcoreapp2_1, and will continue to do so through this VS cycle -// but we can run on Netcoreapp3.0 so ... use reflection to invoke the api, when we are executing on netcoreapp3.0 +// Use reflection to invoke the api when we are executing on a platform that doesn't directly have this API. let definePInvokeMethod = typeof.GetMethod("DefinePInvokeMethod", [| typeof typeof typeof - typeof - typeof + typeof + typeof typeof typeof typeof typeof typeof typeof - typeof - typeof |]) + typeof + typeof |]) let enablePInvoke = definePInvokeMethod <> null #endif @@ -1511,41 +1484,41 @@ let rec buildMethodPass2 cenv tref (typB: TypeBuilder) emEnv (mdef: ILMethodDef) let implflags = mdef.ImplAttributes let cconv = convCallConv mdef.CallingConv let mref = mkRefToILMethod (tref, mdef) - let emEnv = + let emEnv = if mdef.IsEntryPoint && isNil mdef.ParameterTypes then envAddEntryPt emEnv (typB, mdef.Name) else emEnv - match mdef.Body.Contents with - | MethodBody.PInvoke p when enablePInvoke -> + match mdef.Body with + | MethodBody.PInvoke pLazy when enablePInvoke -> + let p = pLazy.Value let argtys = convTypesToArray cenv emEnv mdef.ParameterTypes let rty = convType cenv emEnv mdef.Return.Type let pcc = - match p.CallingConv with + match p.CallingConv with | PInvokeCallingConvention.Cdecl -> CallingConvention.Cdecl | PInvokeCallingConvention.Stdcall -> CallingConvention.StdCall | PInvokeCallingConvention.Thiscall -> CallingConvention.ThisCall | PInvokeCallingConvention.Fastcall -> CallingConvention.FastCall - | PInvokeCallingConvention.None - | PInvokeCallingConvention.WinApi -> CallingConvention.Winapi - let pcs = - match p.CharEncoding with + | PInvokeCallingConvention.None + | PInvokeCallingConvention.WinApi -> CallingConvention.Winapi + let pcs = + match p.CharEncoding with | PInvokeCharEncoding.None -> CharSet.None | PInvokeCharEncoding.Ansi -> CharSet.Ansi | PInvokeCharEncoding.Unicode -> CharSet.Unicode - | PInvokeCharEncoding.Auto -> CharSet.Auto + | PInvokeCharEncoding.Auto -> CharSet.Auto (* p.ThrowOnUnmappableChar *) (* p.CharBestFit *) (* p.NoMangle *) -#if !FX_RESHAPED_REFEMIT || NETCOREAPP3_0 - // DefinePInvokeMethod was removed in early versions of coreclr, it was added back in NETCORE_APP3_0. +#if !FX_RESHAPED_REFEMIT || NETCOREAPP3_1 + // DefinePInvokeMethod was removed in early versions of coreclr, it was added back in NETCOREAPP3. // It has always been available in the desktop framework let methB = typB.DefinePInvokeMethod(mdef.Name, p.Where.Name, p.Name, attrs, cconv, rty, null, null, argtys, null, null, pcc, pcs) #else - // We currently build targeting netcoreapp2_1, and will continue to do so through this VS cycle - // but we can run on Netcoreapp3.0 so ... use reflection to invoke the api, when we are executing on netcoreapp3.0 + // Use reflection to invoke the api when we are executing on a platform that doesn't directly have this API. let methB = System.Diagnostics.Debug.Assert(definePInvokeMethod <> null, "Runtime does not have DefinePInvokeMethod") // Absolutely can't happen definePInvokeMethod.Invoke(typB, [| mdef.Name; p.Where.Name; p.Name; attrs; cconv; rty; null; null; argtys; null; null; pcc; pcs |]) :?> MethodBuilder @@ -1553,29 +1526,29 @@ let rec buildMethodPass2 cenv tref (typB: TypeBuilder) emEnv (mdef: ILMethodDef) methB.SetImplementationFlagsAndLog implflags envBindMethodRef emEnv mref methB - | _ -> + | _ -> match mdef.Name with - | ".cctor" + | ".cctor" | ".ctor" -> let consB = typB.DefineConstructorAndLog (attrs, cconv, convTypesToArray cenv emEnv mdef.ParameterTypes) consB.SetImplementationFlagsAndLog implflags envBindConsRef emEnv mref consB | _name -> // The return/argument types may involve the generic parameters - let methB = typB.DefineMethodAndLog (mdef.Name, attrs, cconv) - - // Method generic type parameters + let methB = typB.DefineMethodAndLog (mdef.Name, attrs, cconv) + + // Method generic type parameters buildGenParamsPass1 emEnv methB.DefineGenericParametersAndLog mdef.GenericParams - let genArgs = getGenericArgumentsOfMethod methB + let genArgs = getGenericArgumentsOfMethod methB let emEnv = envPushTyvars emEnv (Array.append (getGenericArgumentsOfType (typB.AsType())) genArgs) buildGenParamsPass1b cenv emEnv genArgs mdef.GenericParams // Set parameter and return types (may depend on generic args) let parameterTypes = convTypesToArray cenv emEnv mdef.ParameterTypes - let parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers = - mdef.Parameters - |> List.toArray - |> Array.map (convParamModifiers cenv emEnv) + let parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers = + mdef.Parameters + |> List.toArray + |> Array.map (convParamModifiers cenv emEnv) |> Array.unzip let returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers = mdef.Return |> convReturnModifiers cenv emEnv @@ -1591,11 +1564,11 @@ let rec buildMethodPass2 cenv tref (typB: TypeBuilder) emEnv (mdef: ILMethodDef) //---------------------------------------------------------------------------- // buildMethodPass3 cenv //---------------------------------------------------------------------------- - + let rec buildMethodPass3 cenv tref modB (typB: TypeBuilder) emEnv (mdef: ILMethodDef) = let mref = mkRefToILMethod (tref, mdef) - let isPInvoke = - match mdef.Body.Contents with + let isPInvoke = + match mdef.Body with | MethodBody.PInvoke _p -> true | _ -> false match mdef.Name with @@ -1603,7 +1576,7 @@ let rec buildMethodPass3 cenv tref modB (typB: TypeBuilder) emEnv (mdef: ILMetho let consB = envGetConsB emEnv mref // Constructors can not have generic parameters assert isNil mdef.GenericParams - // Value parameters + // Value parameters let defineParameter (i, attr, name) = consB.DefineParameterAndLog (i+1, attr, name) mdef.Parameters |> List.iteri (emitParameter cenv emEnv defineParameter) // Body @@ -1611,100 +1584,100 @@ let rec buildMethodPass3 cenv tref modB (typB: TypeBuilder) emEnv (mdef: ILMetho emitCustomAttrs cenv emEnv (wrapCustomAttr consB.SetCustomAttribute) mdef.CustomAttrs () | _name -> - + let methB = envGetMethB emEnv mref let emEnv = envPushTyvars emEnv (Array.append (getGenericArgumentsOfType (typB.AsType())) (getGenericArgumentsOfMethod methB)) if not (Array.isEmpty mdef.Return.CustomAttrs.AsArray) then - let retB = methB.DefineParameterAndLog (0, System.Reflection.ParameterAttributes.Retval, null) + let retB = methB.DefineParameterAndLog (0, ParameterAttributes.Retval, null) emitCustomAttrs cenv emEnv (wrapCustomAttr retB.SetCustomAttribute) mdef.Return.CustomAttrs // Value parameters - let defineParameter (i, attr, name) = methB.DefineParameterAndLog (i+1, attr, name) + let defineParameter (i, attr, name) = methB.DefineParameterAndLog (i+1, attr, name) mdef.Parameters |> List.iteri (fun a b -> emitParameter cenv emEnv defineParameter a b) // Body - if not isPInvoke then + if not isPInvoke then emitMethodBody cenv modB emEnv methB.GetILGeneratorAndLog mdef.Name mdef.Body let emEnv = envPopTyvars emEnv // case fold later... emitCustomAttrs cenv emEnv methB.SetCustomAttributeAndLog mdef.CustomAttrs - + //---------------------------------------------------------------------------- // buildFieldPass2 //---------------------------------------------------------------------------- - + let buildFieldPass2 cenv tref (typB: TypeBuilder) emEnv (fdef: ILFieldDef) = - + let attrs = fdef.Attributes let fieldT = convType cenv emEnv fdef.FieldType - let fieldB = - match fdef.Data with + let fieldB = + match fdef.Data with | Some d -> typB.DefineInitializedData(fdef.Name, d, attrs) - | None -> + | None -> typB.DefineFieldAndLog (fdef.Name, fieldT, attrs) - + // set default value - let emEnv = + let emEnv = match fdef.LiteralValue with | None -> emEnv - | Some initial -> - if not fieldT.IsEnum + | Some initial -> + if not fieldT.IsEnum // it is ok to init fields with type = enum that are defined in other assemblies - || not fieldT.Assembly.IsDynamic - then - fieldB.SetConstant(convFieldInit initial) + || not fieldT.Assembly.IsDynamic + then + fieldB.SetConstant(initial.AsObject()) emEnv else - // if field type (enum) is defined in FSI dynamic assembly it is created as nested type + // if field type (enum) is defined in FSI dynamic assembly it is created as nested type // => its underlying type cannot be explicitly specified and will be inferred at the very moment of first field definition // => here we cannot detect if underlying type is already set so as a conservative solution we delay initialization of fields // to the end of pass2 (types and members are already created but method bodies are yet not emitted) - { emEnv with delayedFieldInits = (fun() -> fieldB.SetConstant(convFieldInit initial)) :: emEnv.delayedFieldInits } + { emEnv with delayedFieldInits = (fun() -> fieldB.SetConstant(initial.AsObject())) :: emEnv.delayedFieldInits } fdef.Offset |> Option.iter (fun offset -> fieldB.SetOffset offset) // custom attributes: done on pass 3 as they may reference attribute constructors generated on // pass 2. - let fref = mkILFieldRef (tref, fdef.Name, fdef.FieldType) + let fref = mkILFieldRef (tref, fdef.Name, fdef.FieldType) envBindFieldRef emEnv fref fieldB let buildFieldPass3 cenv tref (_typB: TypeBuilder) emEnv (fdef: ILFieldDef) = - let fref = mkILFieldRef (tref, fdef.Name, fdef.FieldType) + let fref = mkILFieldRef (tref, fdef.Name, fdef.FieldType) let fieldB = envGetFieldB emEnv fref emitCustomAttrs cenv emEnv (wrapCustomAttr fieldB.SetCustomAttribute) fdef.CustomAttrs //---------------------------------------------------------------------------- // buildPropertyPass2, 3 //---------------------------------------------------------------------------- - + let buildPropertyPass2 cenv tref (typB: TypeBuilder) emEnv (prop: ILPropertyDef) = let attrs = flagsIf prop.IsRTSpecialName PropertyAttributes.RTSpecialName ||| flagsIf prop.IsSpecialName PropertyAttributes.SpecialName let propB = typB.DefinePropertyAndLog (prop.Name, attrs, convType cenv emEnv prop.PropertyType, convTypesToArray cenv emEnv prop.Args) - + prop.SetMethod |> Option.iter (fun mref -> propB.SetSetMethod(envGetMethB emEnv mref)) prop.GetMethod |> Option.iter (fun mref -> propB.SetGetMethod(envGetMethB emEnv mref)) // set default value - prop.Init |> Option.iter (fun initial -> propB.SetConstant(convFieldInit initial)) + prop.Init |> Option.iter (fun initial -> propB.SetConstant(initial.AsObject())) // custom attributes - let pref = ILPropertyRef.Create (tref, prop.Name) + let pref = ILPropertyRef.Create (tref, prop.Name) envBindPropRef emEnv pref propB -let buildPropertyPass3 cenv tref (_typB: TypeBuilder) emEnv (prop: ILPropertyDef) = - let pref = ILPropertyRef.Create (tref, prop.Name) +let buildPropertyPass3 cenv tref (_typB: TypeBuilder) emEnv (prop: ILPropertyDef) = + let pref = ILPropertyRef.Create (tref, prop.Name) let propB = envGetPropB emEnv pref emitCustomAttrs cenv emEnv (wrapCustomAttr propB.SetCustomAttribute) prop.CustomAttrs //---------------------------------------------------------------------------- // buildEventPass3 //---------------------------------------------------------------------------- - -let buildEventPass3 cenv (typB: TypeBuilder) emEnv (eventDef: ILEventDef) = + +let buildEventPass3 cenv (typB: TypeBuilder) emEnv (eventDef: ILEventDef) = let attrs = flagsIf eventDef.IsSpecialName EventAttributes.SpecialName ||| - flagsIf eventDef.IsRTSpecialName EventAttributes.RTSpecialName + flagsIf eventDef.IsRTSpecialName EventAttributes.RTSpecialName assert eventDef.EventType.IsSome - let eventB = typB.DefineEventAndLog (eventDef.Name, attrs, convType cenv emEnv eventDef.EventType.Value) + let eventB = typB.DefineEventAndLog (eventDef.Name, attrs, convType cenv emEnv eventDef.EventType.Value) eventDef.AddMethod |> (fun mref -> eventB.SetAddOnMethod(envGetMethB emEnv mref)) eventDef.RemoveMethod |> (fun mref -> eventB.SetRemoveOnMethod(envGetMethB emEnv mref)) @@ -1715,11 +1688,11 @@ let buildEventPass3 cenv (typB: TypeBuilder) emEnv (eventDef: ILEventDef) = //---------------------------------------------------------------------------- // buildMethodImplsPass3 //---------------------------------------------------------------------------- - -let buildMethodImplsPass3 cenv _tref (typB: TypeBuilder) emEnv (mimpl: IL.ILMethodImplDef) = + +let buildMethodImplsPass3 cenv _tref (typB: TypeBuilder) emEnv (mimpl: ILMethodImplDef) = let bodyMethInfo = convMethodRef cenv emEnv (typB.AsType()) mimpl.OverrideBy.MethodRef // doc: must be MethodBuilder let (OverridesSpec (mref, dtyp)) = mimpl.Overrides - let declMethTI = convType cenv emEnv dtyp + let declMethTI = convType cenv emEnv dtyp let declMethInfo = convMethodRef cenv emEnv declMethTI mref typB.DefineMethodOverride(bodyMethInfo, declMethInfo) emEnv @@ -1728,8 +1701,8 @@ let buildMethodImplsPass3 cenv _tref (typB: TypeBuilder) emEnv (mimpl: IL.ILMeth // typeAttributesOf* //---------------------------------------------------------------------------- -let typeAttributesOfTypeDefKind x = - match x with +let typeAttributesOfTypeDefKind x = + match x with // required for a TypeBuilder | ILTypeDefKind.Class -> TypeAttributes.Class | ILTypeDefKind.ValueType -> TypeAttributes.Class @@ -1738,10 +1711,10 @@ let typeAttributesOfTypeDefKind x = | ILTypeDefKind.Delegate -> TypeAttributes.Class let typeAttributesOfTypeAccess x = - match x with + match x with | ILTypeDefAccess.Public -> TypeAttributes.Public | ILTypeDefAccess.Private -> TypeAttributes.NotPublic - | ILTypeDefAccess.Nested macc -> + | ILTypeDefAccess.Nested macc -> match macc with | ILMemberAccess.Assembly -> TypeAttributes.NestedAssembly | ILMemberAccess.CompilerControlled -> failwith "Nested compiler controlled." @@ -1750,29 +1723,29 @@ let typeAttributesOfTypeAccess x = | ILMemberAccess.Family -> TypeAttributes.NestedFamily | ILMemberAccess.Private -> TypeAttributes.NestedPrivate | ILMemberAccess.Public -> TypeAttributes.NestedPublic - -let typeAttributesOfTypeEncoding x = - match x with - | ILDefaultPInvokeEncoding.Ansi -> TypeAttributes.AnsiClass + +let typeAttributesOfTypeEncoding x = + match x with + | ILDefaultPInvokeEncoding.Ansi -> TypeAttributes.AnsiClass | ILDefaultPInvokeEncoding.Auto -> TypeAttributes.AutoClass | ILDefaultPInvokeEncoding.Unicode -> TypeAttributes.UnicodeClass -let typeAttributesOfTypeLayout cenv emEnv x = - let attr x p = +let typeAttributesOfTypeLayout cenv emEnv x = + let attr x p = if p.Size =None && p.Pack = None then None - else + else match cenv.tryFindSysILTypeRef "System.Runtime.InteropServices.StructLayoutAttribute", cenv.tryFindSysILTypeRef "System.Runtime.InteropServices.LayoutKind" with | Some tref1, Some tref2 -> Some(convCustomAttr cenv emEnv - (IL.mkILCustomAttribute cenv.ilg - (tref1, - [mkILNonGenericValueTy tref2 ], - [ ILAttribElem.Int32 x ], + (mkILCustomAttribute + (tref1, + [mkILNonGenericValueTy tref2 ], + [ ILAttribElem.Int32 x ], (p.Pack |> Option.toList |> List.map (fun x -> ("Pack", cenv.ilg.typ_Int32, false, ILAttribElem.Int32 (int32 x)))) @ - (p.Size |> Option.toList |> List.map (fun x -> ("Size", cenv.ilg.typ_Int32, false, ILAttribElem.Int32 x)))))) + (p.Size |> Option.toList |> List.map (fun x -> ("Size", cenv.ilg.typ_Int32, false, ILAttribElem.Int32 x)))))) | _ -> None - match x with + match x with | ILTypeDefLayout.Auto -> None | ILTypeDefLayout.Explicit p -> (attr 0x02 p) | ILTypeDefLayout.Sequential p -> (attr 0x00 p) @@ -1781,14 +1754,14 @@ let typeAttributesOfTypeLayout cenv emEnv x = //---------------------------------------------------------------------------- // buildTypeDefPass1 cenv //---------------------------------------------------------------------------- - + let rec buildTypeDefPass1 cenv emEnv (modB: ModuleBuilder) rootTypeBuilder nesting (tdef: ILTypeDef) = - // -IsComInterop: bool; (* Class or interface generated for COM interop *) + // -IsComInterop: bool; (* Class or interface generated for COM interop *) // -SecurityDecls: Permissions // -InitSemantics: ILTypeInit // TypeAttributes let cattrsLayout = typeAttributesOfTypeLayout cenv emEnv tdef.Layout - + let attrsType = tdef.Attributes // TypeBuilder from TypeAttributes. @@ -1797,16 +1770,16 @@ let rec buildTypeDefPass1 cenv emEnv (modB: ModuleBuilder) rootTypeBuilder nesti buildGenParamsPass1 emEnv typB.DefineGenericParametersAndLog tdef.GenericParams // bind tref -> (typT, typB) - let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) + let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) let typT = // Q: would it be ok to use typB :> Type ? // Maybe not, recall TypeBuilder maybe subtype of Type, but it is not THE Type. let nameInModule = tref.QualifiedName modB.GetTypeAndLog (nameInModule, false, false) - + let emEnv = envBindTypeRef emEnv tref (typT, typB, tdef) // recurse on nested types - let nesting = nesting @ [tdef] + let nesting = nesting @ [tdef] let buildNestedType emEnv tdef = buildTypeTypeDef cenv emEnv modB typB nesting tdef let emEnv = List.fold buildNestedType emEnv tdef.NestedTypes.AsList emEnv @@ -1817,35 +1790,35 @@ and buildTypeTypeDef cenv emEnv modB (typB: TypeBuilder) nesting tdef = //---------------------------------------------------------------------------- // buildTypeDefPass1b //---------------------------------------------------------------------------- - -let rec buildTypeDefPass1b cenv nesting emEnv (tdef: ILTypeDef) = + +let rec buildTypeDefPass1b cenv nesting emEnv (tdef: ILTypeDef) = let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) let typB = envGetTypB emEnv tref let genArgs = getGenericArgumentsOfType (typB.AsType()) let emEnv = envPushTyvars emEnv genArgs - // Parent may reference types being defined, so has to come after it's Pass1 creation + // Parent may reference types being defined, so has to come after it's Pass1 creation tdef.Extends |> Option.iter (fun ty -> typB.SetParentAndLog (convType cenv emEnv ty)) - // build constraints on ILGenericParameterDefs. Constraints may reference types being defined, + // build constraints on ILGenericParameterDefs. Constraints may reference types being defined, // so have to come after all types are created buildGenParamsPass1b cenv emEnv genArgs tdef.GenericParams - let emEnv = envPopTyvars emEnv - let nesting = nesting @ [tdef] + let emEnv = envPopTyvars emEnv + let nesting = nesting @ [tdef] List.iter (buildTypeDefPass1b cenv nesting emEnv) tdef.NestedTypes.AsList //---------------------------------------------------------------------------- // buildTypeDefPass2 //---------------------------------------------------------------------------- -let rec buildTypeDefPass2 cenv nesting emEnv (tdef: ILTypeDef) = +let rec buildTypeDefPass2 cenv nesting emEnv (tdef: ILTypeDef) = let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) let typB = envGetTypB emEnv tref let emEnv = envPushTyvars emEnv (getGenericArgumentsOfType (typB.AsType())) // add interface impls tdef.Implements |> convTypes cenv emEnv |> List.iter (fun implT -> typB.AddInterfaceImplementationAndLog implT) // add methods, properties - let emEnv = Array.fold (buildMethodPass2 cenv tref typB) emEnv tdef.Methods.AsArray - let emEnv = List.fold (buildFieldPass2 cenv tref typB) emEnv tdef.Fields.AsList - let emEnv = List.fold (buildPropertyPass2 cenv tref typB) emEnv tdef.Properties.AsList + let emEnv = Array.fold (buildMethodPass2 cenv tref typB) emEnv tdef.Methods.AsArray + let emEnv = List.fold (buildFieldPass2 cenv tref typB) emEnv tdef.Fields.AsList + let emEnv = List.fold (buildPropertyPass2 cenv tref typB) emEnv tdef.Properties.AsList let emEnv = envPopTyvars emEnv // nested types let nesting = nesting @ [tdef] @@ -1855,7 +1828,7 @@ let rec buildTypeDefPass2 cenv nesting emEnv (tdef: ILTypeDef) = //---------------------------------------------------------------------------- // buildTypeDefPass3 cenv //---------------------------------------------------------------------------- - + let rec buildTypeDefPass3 cenv nesting modB emEnv (tdef: ILTypeDef) = let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) let typB = envGetTypB emEnv tref @@ -1866,7 +1839,7 @@ let rec buildTypeDefPass3 cenv nesting modB emEnv (tdef: ILTypeDef) = tdef.Events.AsList |> List.iter (buildEventPass3 cenv typB emEnv) tdef.Fields.AsList |> List.iter (buildFieldPass3 cenv tref typB emEnv) let emEnv = List.fold (buildMethodImplsPass3 cenv tref typB) emEnv tdef.MethodImpls.AsList - tdef.CustomAttrs |> emitCustomAttrs cenv emEnv typB.SetCustomAttributeAndLog + tdef.CustomAttrs |> emitCustomAttrs cenv emEnv typB.SetCustomAttributeAndLog // custom attributes let emEnv = envPopTyvars emEnv // nested types @@ -1878,7 +1851,7 @@ let rec buildTypeDefPass3 cenv nesting modB emEnv (tdef: ILTypeDef) = // buildTypeDefPass4 - Create the Types // // The code in this phase is fragile. -// +// // THe background is that System.Reflection.Emit implementations can be finnickity about the // order that CreateType calls are made when types refer to each other. Some of these restrictions // are not well documented, or are related to historical bugs where the F# emit code worked around the @@ -1887,34 +1860,34 @@ let rec buildTypeDefPass3 cenv nesting modB emEnv (tdef: ILTypeDef) = // // Here are some known cases: // -// MSDN says: If this type is a nested type, the CreateType method must +// MSDN says: If this type is a nested type, the CreateType method must // be called on the enclosing type before it is called on the nested type. // -// MSDN says: If the current type derives from an incomplete type or implements -// incomplete interfaces, call the CreateType method on the parent +// MSDN says: If the current type derives from an incomplete type or implements +// incomplete interfaces, call the CreateType method on the parent // type and the interface types before calling it on the current type. // -// MSDN says: If the enclosing type contains a field that is a value type -// defined as a nested type (for example, a field that is an -// enumeration defined as a nested type), calling the CreateType method -// on the enclosing type will generate a AppDomain.TypeResolve event. -// This is because the loader cannot determine the size of the enclosing -// type until the nested type has been completed. The caller should define -// a handler for the TypeResolve event to complete the definition of the -// nested type by calling CreateType on the TypeBuilder object that represents -// the nested type. The code example for this topic shows how to define such +// MSDN says: If the enclosing type contains a field that is a value type +// defined as a nested type (for example, a field that is an +// enumeration defined as a nested type), calling the CreateType method +// on the enclosing type will generate a AppDomain.TypeResolve event. +// This is because the loader cannot determine the size of the enclosing +// type until the nested type has been completed. The caller should define +// a handler for the TypeResolve event to complete the definition of the +// nested type by calling CreateType on the TypeBuilder object that represents +// the nested type. The code example for this topic shows how to define such // an event handler. // -// +// // There is also a case where generic parameter constraints were being checked before -// a generic method was called. This forced the loading of the types involved in the +// a generic method was called. This forced the loading of the types involved in the // constraints very early. // //---------------------------------------------------------------------------- -let getEnclosingTypeRefs (tref: ILTypeRef) = - match tref.Enclosing with +let getEnclosingTypeRefs (tref: ILTypeRef) = + match tref.Enclosing with | [] -> [] | h :: t -> List.scan (fun tr nm -> mkILTyRefInTyRef (tr, nm)) (mkILTyRef(tref.Scope, h)) t @@ -1922,38 +1895,38 @@ let getEnclosingTypeRefs (tref: ILTypeRef) = type CollectTypes = ValueTypesOnly | All // Find all constituent type references -let rec getTypeRefsInType (allTypes: CollectTypes) ty acc = +let rec getTypeRefsInType (allTypes: CollectTypes) ty acc = match ty with - | ILType.Void + | ILType.Void | ILType.TypeVar _ -> acc - | ILType.Ptr eltType | ILType.Byref eltType -> + | ILType.Ptr eltType | ILType.Byref eltType -> getTypeRefsInType allTypes eltType acc - | ILType.Array (_, eltType) -> - match allTypes with - | CollectTypes.ValueTypesOnly -> acc + | ILType.Array (_, eltType) -> + match allTypes with + | CollectTypes.ValueTypesOnly -> acc | CollectTypes.All -> getTypeRefsInType allTypes eltType acc - | ILType.Value tspec -> + | ILType.Value tspec -> // We use CollectTypes.All because the .NET type loader appears to always eagerly require all types // referred to in an instantiation of a generic value type tspec.TypeRef :: List.foldBack (getTypeRefsInType CollectTypes.All) tspec.GenericArgs acc - | ILType.Boxed tspec -> - match allTypes with - | CollectTypes.ValueTypesOnly -> acc + | ILType.Boxed tspec -> + match allTypes with + | CollectTypes.ValueTypesOnly -> acc | CollectTypes.All -> tspec.TypeRef :: List.foldBack (getTypeRefsInType allTypes) tspec.GenericArgs acc | ILType.FunctionPointer _callsig -> failwith "getTypeRefsInType: fptr" | ILType.Modified _ -> failwith "getTypeRefsInType: modified" let verbose2 = false -let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv tref = +let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv tref = let rec traverseTypeDef (tref: ILTypeRef) (tdef: ILTypeDef) = if verbose2 then dprintf "buildTypeDefPass4: Creating Enclosing Types of %s\n" tdef.Name for enc in getEnclosingTypeRefs tref do traverseTypeRef enc - - // WORKAROUND (ProductStudio FSharp 1.0 bug 615): the constraints on generic method parameters - // are resolved overly eagerly by reflection emit's CreateType. + + // WORKAROUND (ProductStudio FSharp 1.0 bug 615): the constraints on generic method parameters + // are resolved overly eagerly by reflection emit's CreateType. if verbose2 then dprintf "buildTypeDefPass4: Doing type typar constraints of %s\n" tdef.Name for gp in tdef.GenericParams do for cx in gp.Constraints do @@ -1961,34 +1934,34 @@ let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv t if verbose2 then dprintf "buildTypeDefPass4: Doing method constraints of %s\n" tdef.Name for md in tdef.Methods.AsArray do - for gp in md.GenericParams do - for cx in gp.Constraints do + for gp in md.GenericParams do + for cx in gp.Constraints do traverseType CollectTypes.All cx - + // We absolutely need the exact parent type... if verbose2 then dprintf "buildTypeDefPass4: Creating Super Class Chain of %s\n" tdef.Name tdef.Extends |> Option.iter (traverseType CollectTypes.All) - + // We absolutely need the exact interface types... if verbose2 then dprintf "buildTypeDefPass4: Creating Interface Chain of %s\n" tdef.Name tdef.Implements |> List.iter (traverseType CollectTypes.All) - + if verbose2 then dprintf "buildTypeDefPass4: Do value types in fields of %s\n" tdef.Name tdef.Fields.AsList |> List.iter (fun fd -> traverseType CollectTypes.ValueTypesOnly fd.FieldType) - - if verbose2 then dprintf "buildTypeDefPass4: Done with dependencies of %s\n" tdef.Name - - and traverseType allTypes ty = + + if verbose2 then dprintf "buildTypeDefPass4: Done with dependencies of %s\n" tdef.Name + + and traverseType allTypes ty = getTypeRefsInType allTypes ty [] |> List.filter (isEmittedTypeRef emEnv) - |> List.iter traverseTypeRef + |> List.iter traverseTypeRef - and traverseTypeRef tref = + and traverseTypeRef tref = let typB = envGetTypB emEnv tref if verbose2 then dprintf "- considering reference to type %s\n" typB.FullName // Re-run traverseTypeDef if we've never visited the type. - if not (visited.ContainsKey tref) then + if not (visited.ContainsKey tref) then visited.[tref] <- true let tdef = envGetTypeDef emEnv tref if verbose2 then dprintf "- traversing type %s\n" typB.FullName @@ -1996,13 +1969,13 @@ let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv t // we require the type r.Name, though with "nestingToProbe" being the enclosing types of the // type being defined. let typeCreationHandler = - let nestingToProbe = tref.Enclosing + let nestingToProbe = tref.Enclosing ResolveEventHandler( fun o r -> let typeName = r.Name let typeRef = ILTypeRef.Create(ILScopeRef.Local, nestingToProbe, typeName) match emEnv.emTypMap.TryFind typeRef with - | Some(_, tb, _, _) -> + | Some(_, tb, _, _) -> if not (tb.IsCreated()) then tb.CreateTypeAndLog () |> ignore tb.Assembly @@ -2010,27 +1983,27 @@ let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv t ) // For some reason, the handler is installed while running 'traverseTypeDef' but not while defining the type // itself. - System.AppDomain.CurrentDomain.add_TypeResolve typeCreationHandler + AppDomain.CurrentDomain.add_TypeResolve typeCreationHandler try traverseTypeDef tref tdef finally - System.AppDomain.CurrentDomain.remove_TypeResolve typeCreationHandler + AppDomain.CurrentDomain.remove_TypeResolve typeCreationHandler // At this point, we've done everything we can to prepare the type for loading by eagerly forcing the // load of other types. Everything else is up to the implementation of System.Reflection.Emit. - if not (created.ContainsKey tref) then + if not (created.ContainsKey tref) then created.[tref] <- true if verbose2 then dprintf "- creating type %s\n" typB.FullName typB.CreateTypeAndLog () |> ignore - - traverseTypeRef tref + + traverseTypeRef tref let rec buildTypeDefPass4 (visited, created) nesting emEnv (tdef: ILTypeDef) = if verbose2 then dprintf "buildTypeDefPass4 %s\n" tdef.Name let tref = mkRefForNestedILTypeDef ILScopeRef.Local (nesting, tdef) createTypeRef (visited, created) emEnv tref - - + + // nested types let nesting = nesting @ [tdef] tdef.NestedTypes |> Seq.iter (buildTypeDefPass4 (visited, created) nesting emEnv) @@ -2038,7 +2011,7 @@ let rec buildTypeDefPass4 (visited, created) nesting emEnv (tdef: ILTypeDef) = //---------------------------------------------------------------------------- // buildModuleType //---------------------------------------------------------------------------- - + let buildModuleTypePass1 cenv (modB: ModuleBuilder) emEnv (tdef: ILTypeDef) = buildTypeDefPass1 cenv emEnv modB modB.DefineTypeAndLog [] tdef @@ -2050,37 +2023,37 @@ let buildModuleTypePass4 visited emEnv tdef = buildTypeDefPass4 visited [] emEnv //---------------------------------------------------------------------------- // buildModuleFragment - only the types the fragment get written //---------------------------------------------------------------------------- - + let buildModuleFragment cenv emEnv (asmB: AssemblyBuilder) (modB: ModuleBuilder) (m: ILModuleDef) = let tdefs = m.TypeDefs.AsList - let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass1 cenv modB) - tdefs |> List.iter (buildModuleTypePass1b cenv emEnv) - let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass2 cenv) - + let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass1 cenv modB) + tdefs |> List.iter (buildModuleTypePass1b cenv emEnv) + let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass2 cenv) + for delayedFieldInit in emEnv.delayedFieldInits do delayedFieldInit() let emEnv = { emEnv with delayedFieldInits = [] } - let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass3 cenv modB) - let visited = new Dictionary<_, _>(10) - let created = new Dictionary<_, _>(10) - tdefs |> List.iter (buildModuleTypePass4 (visited, created) emEnv) + let emEnv = (emEnv, tdefs) ||> List.fold (buildModuleTypePass3 cenv modB) + let visited = Dictionary<_, _>(10) + let created = Dictionary<_, _>(10) + tdefs |> List.iter (buildModuleTypePass4 (visited, created) emEnv) let emEnv = Seq.fold envUpdateCreatedTypeRef emEnv created.Keys // update typT with the created typT emitCustomAttrs cenv emEnv modB.SetCustomAttributeAndLog m.CustomAttrs #if FX_RESHAPED_REFEMIT ignore asmB #else - m.Resources.AsList |> List.iter (fun r -> - let attribs = (match r.Access with ILResourceAccess.Public -> ResourceAttributes.Public | ILResourceAccess.Private -> ResourceAttributes.Private) - match r.Location with - | ILResourceLocation.Local bytes -> - use stream = bytes.AsStream() + m.Resources.AsList |> List.iter (fun r -> + let attribs = (match r.Access with ILResourceAccess.Public -> ResourceAttributes.Public | ILResourceAccess.Private -> ResourceAttributes.Private) + match r.Location with + | ILResourceLocation.Local bytes -> + use stream = bytes.GetByteMemory().AsStream() modB.DefineManifestResourceAndLog (r.Name, stream, attribs) - | ILResourceLocation.File (mr, _) -> + | ILResourceLocation.File (mr, _) -> asmB.AddResourceFileAndLog (r.Name, mr.Name, attribs) - | ILResourceLocation.Assembly _ -> + | ILResourceLocation.Assembly _ -> failwith "references to resources other assemblies may not be emitted using System.Reflection") #endif emEnv @@ -2095,53 +2068,53 @@ let defineDynamicAssemblyAndLog (asmName, flags, asmDir: string) = let currentDom = System.AppDomain.CurrentDomain let asmB = currentDom.DefineDynamicAssembly(asmName, flags, asmDir) #endif - if logRefEmitCalls then + if logRefEmitCalls then printfn "open System" printfn "open System.Reflection" printfn "open System.Reflection.Emit" printfn "let assemblyBuilder%d = System.AppDomain.CurrentDomain.DefineDynamicAssembly(AssemblyName(Name=\"%s\"), enum %d, %A)" (abs <| hash asmB) asmName.Name (LanguagePrimitives.EnumToValue flags) asmDir asmB -let mkDynamicAssemblyAndModule (assemblyName, optimize, debugInfo, collectible) = +let mkDynamicAssemblyAndModule (assemblyName, optimize, debugInfo: bool, collectible) = let filename = assemblyName + ".dll" let asmDir = "." - let asmName = new AssemblyName() + let asmName = AssemblyName() asmName.Name <- assemblyName - let asmAccess = - if collectible then AssemblyBuilderAccess.RunAndCollect + let asmAccess = + if collectible then AssemblyBuilderAccess.RunAndCollect #if FX_RESHAPED_REFEMIT else AssemblyBuilderAccess.Run #else else AssemblyBuilderAccess.RunAndSave #endif - let asmB = defineDynamicAssemblyAndLog (asmName, asmAccess, asmDir) - if not optimize then + let asmB = defineDynamicAssemblyAndLog (asmName, asmAccess, asmDir) + if not optimize then let daType = typeof let daCtor = daType.GetConstructor [| typeof |] - let daBuilder = new CustomAttributeBuilder(daCtor, [| System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations ||| System.Diagnostics.DebuggableAttribute.DebuggingModes.Default |]) + let daBuilder = CustomAttributeBuilder(daCtor, [| System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations ||| System.Diagnostics.DebuggableAttribute.DebuggingModes.Default |]) asmB.SetCustomAttributeAndLog daBuilder let modB = asmB.DefineDynamicModuleAndLog (assemblyName, filename, debugInfo) asmB, modB -let emitModuleFragment (ilg, emEnv, asmB: AssemblyBuilder, modB: ModuleBuilder, modul: IL.ILModuleDef, debugInfo: bool, resolveAssemblyRef, tryFindSysILTypeRef) = - let cenv = { ilg = ilg ; generatePdb = debugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=tryFindSysILTypeRef } +let emitModuleFragment (ilg, emitTailcalls, emEnv, asmB: AssemblyBuilder, modB: ModuleBuilder, modul: ILModuleDef, debugInfo: bool, resolveAssemblyRef, tryFindSysILTypeRef) = + let cenv = { ilg = ilg ; emitTailcalls=emitTailcalls; generatePdb = debugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=tryFindSysILTypeRef } let emEnv = buildModuleFragment cenv emEnv asmB modB modul - match modul.Manifest with + match modul.Manifest with | None -> () - | Some mani -> + | Some mani -> // REVIEW: remainder of manifest emitCustomAttrs cenv emEnv asmB.SetCustomAttributeAndLog mani.CustomAttrs // invoke entry point methods - let execEntryPtFun ((typB: TypeBuilder), methodName) () = - try + let execEntryPtFun (typB: TypeBuilder, methodName) () = + try ignore (typB.InvokeMemberAndLog (methodName, BindingFlags.InvokeMethod ||| BindingFlags.Public ||| BindingFlags.Static, [| |])) None - with - | :? System.Reflection.TargetInvocationException as e -> + with + | :? TargetInvocationException as e -> Some e.InnerException - + let emEnv, entryPts = envPopEntryPts emEnv let execs = List.map execEntryPtFun entryPts emEnv, execs @@ -2154,7 +2127,7 @@ let emitModuleFragment (ilg, emEnv, asmB: AssemblyBuilder, modB: ModuleBuilder, // TypeBuilder is a subtype of Type. // However, casting TypeBuilder to Type is not the same as getting Type proper. // The builder version does not implement all methods on the parent. -// +// // The emEnv stores (typT: Type) for each tref. // Once the emitted type is created this typT is updated to ensure it is the Type proper. // So Type lookup will return the proper Type not TypeBuilder. diff --git a/src/fsharp/absil/ilreflect.fsi b/src/fsharp/absil/ilreflect.fsi new file mode 100644 index 00000000000..61d9102fc9e --- /dev/null +++ b/src/fsharp/absil/ilreflect.fsi @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Write Abstract IL structures at runtime using Reflection.Emit +module internal FSharp.Compiler.AbstractIL.ILRuntimeWriter + +open System.Reflection +open System.Reflection.Emit + +open FSharp.Compiler.AbstractIL.IL + +val mkDynamicAssemblyAndModule: assemblyName: string * optimize: bool * debugInfo: bool * collectible: bool -> AssemblyBuilder * ModuleBuilder + +type cenv = + { ilg: ILGlobals + emitTailcalls: bool + tryFindSysILTypeRef: string -> ILTypeRef option + generatePdb: bool + resolveAssemblyRef: ILAssemblyRef -> Choice option } + +type emEnv + +val emEnv0: emEnv + +val emitModuleFragment: + ilg: ILGlobals * + emitTailcalls: bool * + emEnv: emEnv * + asmB: AssemblyBuilder * + modB: ModuleBuilder * + modul: ILModuleDef * + debugInfo: bool * + resolveAssemblyRef: (ILAssemblyRef -> Choice option) * + tryFindSysILTypeRef: (string -> ILTypeRef option) -> + emEnv * (unit -> exn option) list + +val LookupTypeRef: cenv: cenv -> emEnv: emEnv -> tref: ILTypeRef -> System.Type + +val LookupType: cenv: cenv -> emEnv: emEnv -> ty: ILType -> System.Type + +val LookupFieldRef: emEnv: emEnv -> fref: ILFieldRef -> FieldInfo option + +val LookupMethodRef: emEnv: emEnv -> mref: ILMethodRef -> MethodInfo option diff --git a/src/fsharp/absil/ilsign.fs b/src/fsharp/absil/ilsign.fs new file mode 100644 index 00000000000..5a5f904eb50 --- /dev/null +++ b/src/fsharp/absil/ilsign.fs @@ -0,0 +1,581 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.AbstractIL.StrongNameSign + +#nowarn "9" + + open System + open System.IO + open System.Collections.Immutable + open System.Reflection.PortableExecutable + open System.Security.Cryptography + open System.Reflection + open System.Runtime.InteropServices + + open Internal.Utilities.Library + open FSharp.Compiler.IO + + type KeyType = + | Public + | KeyPair + + let ALG_TYPE_RSA = int (2 <<< 9) + let ALG_CLASS_KEY_EXCHANGE = int (5 <<< 13) + let ALG_CLASS_SIGNATURE = int (1 <<< 13) + let CALG_RSA_KEYX = int (ALG_CLASS_KEY_EXCHANGE ||| ALG_TYPE_RSA) + let CALG_RSA_SIGN = int (ALG_CLASS_SIGNATURE ||| ALG_TYPE_RSA) + + let ALG_CLASS_HASH = int (4 <<< 13) + let ALG_TYPE_ANY = int 0 + let CALG_SHA1 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 4) + let CALG_SHA_256 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 12) + let CALG_SHA_384 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 13) + let CALG_SHA_512 = int (ALG_CLASS_HASH ||| ALG_TYPE_ANY ||| 14) + + let PUBLICKEYBLOB = int 0x6 + let PRIVATEKEYBLOB = int 0x7 + let BLOBHEADER_CURRENT_BVERSION = int 0x2 + let BLOBHEADER_LENGTH = int 20 + let RSA_PUB_MAGIC = int 0x31415352 + let RSA_PRIV_MAGIC = int 0x32415352 + + let getResourceString (_, str) = str + let check _action hresult = + if uint32 hresult >= 0x80000000ul then + Marshal.ThrowExceptionForHR hresult + + [] + type ByteArrayUnion = + [] + val UnderlyingArray: byte[] + + [] + val ImmutableArray: ImmutableArray + + new (immutableArray: ImmutableArray) = { UnderlyingArray = Array.empty; ImmutableArray = immutableArray} + + let getUnderlyingArray (array: ImmutableArray) =ByteArrayUnion(array).UnderlyingArray + + // Compute a hash over the elements of an assembly manifest file that should + // remain static (skip checksum, Authenticode signatures and strong name signature blob) + let hashAssembly (peReader:PEReader) (hashAlgorithm:IncrementalHash ) = + // Hash content of all headers + let peHeaders = peReader.PEHeaders + let peHeaderOffset = peHeaders.PEHeaderStartOffset + + // Even though some data in OptionalHeader is different for 32 and 64, this field is the same + let checkSumOffset = peHeaderOffset + 0x40; // offsetof(IMAGE_OPTIONAL_HEADER, CheckSum) + let securityDirectoryEntryOffset, peHeaderSize = + match peHeaders.PEHeader.Magic with + | PEMagic.PE32 -> peHeaderOffset + 0x80, 0xE0 // offsetof(IMAGE_OPTIONAL_HEADER32, DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]), sizeof(IMAGE_OPTIONAL_HEADER32) + | PEMagic.PE32Plus -> peHeaderOffset + 0x90,0xF0 // offsetof(IMAGE_OPTIONAL_HEADER64, DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]), sizeof(IMAGE_OPTIONAL_HEADER64) + | _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignInvalidMagicValue()))) + + let allHeadersSize = peHeaderOffset + peHeaderSize + int peHeaders.CoffHeader.NumberOfSections * 0x28; // sizeof(IMAGE_SECTION_HEADER) + let allHeaders = + let array:byte[] = Array.zeroCreate allHeadersSize + peReader.GetEntireImage().GetContent().CopyTo(0, array, 0, allHeadersSize) + array + + // Clear checksum and security data directory + for i in 0 .. 3 do allHeaders.[checkSumOffset + i] <- 0uy + for i in 0 .. 7 do allHeaders.[securityDirectoryEntryOffset + i] <- 0uy + hashAlgorithm.AppendData(allHeaders, 0, allHeadersSize) + + // Hash content of all sections + let signatureDirectory = peHeaders.CorHeader.StrongNameSignatureDirectory + let signatureStart = + match peHeaders.TryGetDirectoryOffset signatureDirectory with + | true, value -> value + | _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignBadImageFormat()))) + let signatureEnd = signatureStart + signatureDirectory.Size + let buffer = getUnderlyingArray (peReader.GetEntireImage().GetContent()) + let sectionHeaders = peHeaders.SectionHeaders + + for i in 0 .. (sectionHeaders.Length - 1) do + let section = sectionHeaders.[i] + let mutable st = section.PointerToRawData + let en = st + section.SizeOfRawData + + if st <= signatureStart && signatureStart < en then do + // The signature should better end within this section as well + if not ( (st < signatureEnd) && (signatureEnd <= en)) then raise (BadImageFormatException()) + + // Signature starts within this section - hash everything up to the signature start + hashAlgorithm.AppendData(buffer, st, signatureStart - st) + + // Trim what we have written + st <- signatureEnd + + hashAlgorithm.AppendData(buffer, st, en - st) + () + hashAlgorithm.GetHashAndReset() + + type BlobReader = + val mutable _blob:byte[] + val mutable _offset:int + new (blob:byte[]) = { _blob = blob; _offset = 0; } + + member x.ReadInt32:int = + let offset = x._offset + x._offset <- offset + 4 + int x._blob.[offset] ||| (int x._blob.[offset + 1] <<< 8) ||| (int x._blob.[offset + 2] <<< 16) ||| (int x._blob.[offset + 3] <<< 24) + + member x.ReadBigInteger (length:int):byte[] = + let arr:byte[] = Array.zeroCreate length + Array.Copy(x._blob, x._offset, arr, 0, length) + x._offset <- x._offset + length + arr |> Array.rev + + let RSAParamatersFromBlob (blob:byte[]) keyType = + let mutable reader = BlobReader blob + if reader.ReadInt32 <> 0x00000207 && keyType = KeyType.KeyPair then raise (CryptographicException(getResourceString(FSComp.SR.ilSignPrivateKeyExpected()))) + reader.ReadInt32 |>ignore // ALG_ID + if reader.ReadInt32 <> RSA_PRIV_MAGIC then raise (CryptographicException(getResourceString(FSComp.SR.ilSignRsaKeyExpected()))) // 'RSA2' + let byteLen, halfLen = + let bitLen = reader.ReadInt32 + match bitLen % 16 with + | 0 -> (bitLen / 8, bitLen / 16) + | _ -> raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidBitLen()))) + let mutable key = RSAParameters() + key.Exponent <- reader.ReadBigInteger 4 + key.Modulus <- reader.ReadBigInteger byteLen + key.P <- reader.ReadBigInteger halfLen + key.Q <- reader.ReadBigInteger halfLen + key.DP <- reader.ReadBigInteger halfLen + key.DQ <- reader.ReadBigInteger halfLen + key.InverseQ <- reader.ReadBigInteger halfLen + key.D <- reader.ReadBigInteger byteLen + key + + let toCLRKeyBlob (rsaParameters:RSAParameters) (algId:int) : byte[] = + let validateRSAField (field:byte[]) expected (name:string) = + if field <> null && field.Length <> expected then + raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), name))) + + // The original FCall this helper emulates supports other algId's - however, the only algid we need to support is CALG_RSA_KEYX. We will not port the codepaths dealing with other algid's. + if algId <> CALG_RSA_KEYX then raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidAlgId()))) + + // Validate the RSA structure first. + if rsaParameters.Modulus = null then raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), "Modulus"))) + if rsaParameters.Exponent = null || rsaParameters.Exponent.Length > 4 then raise (CryptographicException(String.Format(getResourceString(FSComp.SR.ilSignInvalidRSAParams()), "Exponent"))) + + let modulusLength = rsaParameters.Modulus.Length + let halfModulusLength = (modulusLength + 1) / 2 + + // We assume that if P != null, then so are Q, DP, DQ, InverseQ and D and indicate KeyPair RSA Parameters + let isPrivate = + if rsaParameters.P <> null then + validateRSAField rsaParameters.P halfModulusLength "P" + validateRSAField rsaParameters.Q halfModulusLength "Q" + validateRSAField rsaParameters.DP halfModulusLength "DP" + validateRSAField rsaParameters.InverseQ halfModulusLength "InverseQ" + validateRSAField rsaParameters.D halfModulusLength "D" + true + else false + + let key = + use ms = new MemoryStream() + use bw = new BinaryWriter(ms) + + bw.Write(int CALG_RSA_SIGN) // CLRHeader.aiKeyAlg + bw.Write(int CALG_SHA1) // CLRHeader.aiHashAlg + bw.Write(int (modulusLength + BLOBHEADER_LENGTH)) // CLRHeader.KeyLength + + // Write out the BLOBHEADER + bw.Write(byte (if isPrivate = true then PRIVATEKEYBLOB else PUBLICKEYBLOB))// BLOBHEADER.bType + bw.Write(byte BLOBHEADER_CURRENT_BVERSION) // BLOBHEADER.bVersion + bw.Write(int16 0) // BLOBHEADER.wReserved + bw.Write(int CALG_RSA_SIGN) // BLOBHEADER.aiKeyAlg + + // Write the RSAPubKey header + bw.Write(int (if isPrivate then RSA_PRIV_MAGIC else RSA_PUB_MAGIC)) // RSAPubKey.magic + bw.Write(int (modulusLength * 8)) // RSAPubKey.bitLen + + let expAsDword = + let mutable buffer = int 0 + for i in 0 .. rsaParameters.Exponent.Length - 1 do + buffer <- (buffer <<< 8) ||| int rsaParameters.Exponent.[i] + buffer + + bw.Write expAsDword // RSAPubKey.pubExp + bw.Write(rsaParameters.Modulus |> Array.rev) // Copy over the modulus for both public and private + if isPrivate = true then do + bw.Write(rsaParameters.P |> Array.rev) + bw.Write(rsaParameters.Q |> Array.rev) + bw.Write(rsaParameters.DP |> Array.rev) + bw.Write(rsaParameters.DQ |> Array.rev) + bw.Write(rsaParameters.InverseQ |> Array.rev) + bw.Write(rsaParameters.D |> Array.rev) + + bw.Flush() + ms.ToArray() + key + + let createSignature (hash:byte[]) (keyBlob:byte[]) keyType = + use rsa = RSA.Create() + rsa.ImportParameters(RSAParamatersFromBlob keyBlob keyType) + let signature = rsa.SignHash(hash, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1) + signature |>Array.rev + + let patchSignature (stream:Stream) (peReader:PEReader) (signature:byte[]) = + let peHeaders = peReader.PEHeaders + let signatureDirectory = peHeaders.CorHeader.StrongNameSignatureDirectory + let signatureOffset = + if signatureDirectory.Size > signature.Length then raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignInvalidSignatureSize()))) + match peHeaders.TryGetDirectoryOffset signatureDirectory with + | false, _ -> raise (BadImageFormatException(getResourceString(FSComp.SR.ilSignNoSignatureDirectory()))) + | true, signatureOffset -> int64 signatureOffset + stream.Seek(signatureOffset, SeekOrigin.Begin) |>ignore + stream.Write(signature, 0, signature.Length) + + let corHeaderFlagsOffset = int64(peHeaders.CorHeaderStartOffset + 16) // offsetof(IMAGE_COR20_HEADER, Flags) + stream.Seek(corHeaderFlagsOffset, SeekOrigin.Begin) |>ignore + stream.WriteByte (byte (peHeaders.CorHeader.Flags ||| CorFlags.StrongNameSigned)) + () + + let signStream stream keyBlob = + use peReader = new PEReader(stream, PEStreamOptions.PrefetchEntireImage ||| PEStreamOptions.LeaveOpen) + let hash = + use hashAlgorithm = IncrementalHash.CreateHash(HashAlgorithmName.SHA1) + hashAssembly peReader hashAlgorithm + let signature = createSignature hash keyBlob KeyType.KeyPair + patchSignature stream peReader signature + + let signFile filename keyBlob = + use fs = FileSystem.OpenFileForWriteShim(filename, FileMode.Open, FileAccess.ReadWrite) + signStream fs keyBlob + + let signatureSize (pk:byte[]) = + if pk.Length < 25 then raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidPKBlob()))) + let mutable reader = BlobReader pk + reader.ReadBigInteger 12 |> ignore // Skip CLRHeader + reader.ReadBigInteger 8 |> ignore // Skip BlobHeader + let magic = reader.ReadInt32 // Read magic + if not (magic = RSA_PRIV_MAGIC || magic = RSA_PUB_MAGIC) then // RSAPubKey.magic + raise (CryptographicException(getResourceString(FSComp.SR.ilSignInvalidPKBlob()))) + let x = reader.ReadInt32 / 8 + x + + // Returns a CLR Format Blob public key + let getPublicKeyForKeyPair keyBlob = + use rsa = RSA.Create() + rsa.ImportParameters(RSAParamatersFromBlob keyBlob KeyType.KeyPair) + let rsaParameters = rsa.ExportParameters false + toCLRKeyBlob rsaParameters CALG_RSA_KEYX + + // Key signing + type keyContainerName = string + type keyPair = byte[] + type pubkey = byte[] + type pubkeyOptions = byte[] * bool + + let signerOpenPublicKeyFile filePath = FileSystem.OpenFileForReadShim(filePath).ReadAllBytes() + + let signerOpenKeyPairFile filePath = FileSystem.OpenFileForReadShim(filePath).ReadAllBytes() + + let signerGetPublicKeyForKeyPair (kp: keyPair) : pubkey = getPublicKeyForKeyPair kp + + let signerGetPublicKeyForKeyContainer (_kcName: keyContainerName) : pubkey = + raise (NotImplementedException("signerGetPublicKeyForKeyContainer is not yet implemented")) + + let signerCloseKeyContainer (_kc: keyContainerName) : unit = + raise (NotImplementedException("signerCloseKeyContainer is not yet implemented")) + + let signerSignatureSize (pk: pubkey) : int = signatureSize pk + + let signerSignFileWithKeyPair (fileName: string) (kp: keyPair) : unit = signFile fileName kp + + let signerSignFileWithKeyContainer (_fileName: string) (_kcName: keyContainerName) : unit = + raise (NotImplementedException("signerSignFileWithKeyContainer is not yet implemented")) + +#if !FX_NO_CORHOST_SIGNER + open System.Runtime.CompilerServices + + // New mscoree functionality + // This type represents methods that we don't currently need, so I'm leaving unimplemented + type UnusedCOMMethod = unit -> unit + [] + [] + type ICLRMetaHost = + [] + abstract GetRuntime: + [] version: string * + [] interfaceId: System.Guid -> [] System.Object + + // Methods that we don't need are stubbed out for now... + abstract GetVersionFromFile: UnusedCOMMethod + abstract EnumerateInstalledRuntimes: UnusedCOMMethod + abstract EnumerateLoadedRuntimes: UnusedCOMMethod + abstract Reserved01: UnusedCOMMethod + + // We don't currently support ComConversionLoss + [] + [] + type ICLRStrongName = + // Methods that we don't need are stubbed out for now... + abstract GetHashFromAssemblyFile: UnusedCOMMethod + abstract GetHashFromAssemblyFileW: UnusedCOMMethod + abstract GetHashFromBlob: UnusedCOMMethod + abstract GetHashFromFile: UnusedCOMMethod + abstract GetHashFromFileW: UnusedCOMMethod + abstract GetHashFromHandle: UnusedCOMMethod + abstract StrongNameCompareAssemblies: UnusedCOMMethod + + [] + abstract StrongNameFreeBuffer: [] pbMemory: nativeint -> unit + + abstract StrongNameGetBlob: UnusedCOMMethod + abstract StrongNameGetBlobFromImage: UnusedCOMMethod + + [] + abstract StrongNameGetPublicKey : + [] pwzKeyContainer: string * + [] pbKeyBlob: byte[] * + [] cbKeyBlob: uint32 * + [] ppbPublicKeyBlob: nativeint byref * + [] pcbPublicKeyBlob: uint32 byref -> unit + + abstract StrongNameHashSize: UnusedCOMMethod + + [] + abstract StrongNameKeyDelete: [] pwzKeyContainer: string -> unit + + abstract StrongNameKeyGen: UnusedCOMMethod + abstract StrongNameKeyGenEx: UnusedCOMMethod + abstract StrongNameKeyInstall: UnusedCOMMethod + + [] + abstract StrongNameSignatureGeneration : + [] pwzFilePath: string * + [] pwzKeyContainer: string * + [] pbKeyBlob: byte [] * + [] cbKeyBlob: uint32 * + [] ppbSignatureBlob: nativeint * + [] pcbSignatureBlob: uint32 byref -> unit + + abstract StrongNameSignatureGenerationEx: UnusedCOMMethod + + [] + abstract StrongNameSignatureSize : + [] pbPublicKeyBlob: byte[] * + [] cbPublicKeyBlob: uint32 * + [] pcbSize: uint32 byref -> unit + + abstract StrongNameSignatureVerification: UnusedCOMMethod + + [] + abstract StrongNameSignatureVerificationEx : + [] pwzFilePath: string * + [] fForceVerification: bool * + [] pfWasVerified: bool byref -> [] bool + + abstract StrongNameSignatureVerificationFromImage: UnusedCOMMethod + abstract StrongNameTokenFromAssembly: UnusedCOMMethod + abstract StrongNameTokenFromAssemblyEx: UnusedCOMMethod + abstract StrongNameTokenFromPublicKey: UnusedCOMMethod + + + [] + [] + type ICLRRuntimeInfo = + // REVIEW: Methods that we don't need will be stubbed out for now... + abstract GetVersionString: unit -> unit + abstract GetRuntimeDirectory: unit -> unit + abstract IsLoaded: unit -> unit + abstract LoadErrorString: unit -> unit + abstract LoadLibrary: unit -> unit + abstract GetProcAddress: unit -> unit + + [] + abstract GetInterface : + [] coClassId: System.Guid * + [] interfaceId: System.Guid -> []System.Object + + [] + [] + let CreateInterface ( + ([] _clsidguid: System.Guid), + ([] _guid: System.Guid), + ([] _metaHost : + ICLRMetaHost byref)) : unit = failwith "CreateInterface" + + let legacySignerOpenPublicKeyFile filePath = FileSystem.OpenFileForReadShim(filePath).ReadAllBytes() + + let legacySignerOpenKeyPairFile filePath = FileSystem.OpenFileForReadShim(filePath).ReadAllBytes() + + let mutable iclrsn: ICLRStrongName option = None + let getICLRStrongName () = + match iclrsn with + | None -> + let CLSID_CLRStrongName = System.Guid(0xB79B0ACDu, 0xF5CDus, 0x409bus, 0xB5uy, 0xA5uy, 0xA1uy, 0x62uy, 0x44uy, 0x61uy, 0x0Buy, 0x92uy) + let IID_ICLRStrongName = System.Guid(0x9FD93CCFu, 0x3280us, 0x4391us, 0xB3uy, 0xA9uy, 0x96uy, 0xE1uy, 0xCDuy, 0xE7uy, 0x7Cuy, 0x8Duy) + let CLSID_CLRMetaHost = System.Guid(0x9280188Du, 0x0E8Eus, 0x4867us, 0xB3uy, 0x0Cuy, 0x7Fuy, 0xA8uy, 0x38uy, 0x84uy, 0xE8uy, 0xDEuy) + let IID_ICLRMetaHost = System.Guid(0xD332DB9Eu, 0xB9B3us, 0x4125us, 0x82uy, 0x07uy, 0xA1uy, 0x48uy, 0x84uy, 0xF5uy, 0x32uy, 0x16uy) + let clrRuntimeInfoGuid = System.Guid(0xBD39D1D2u, 0xBA2Fus, 0x486aus, 0x89uy, 0xB0uy, 0xB4uy, 0xB0uy, 0xCBuy, 0x46uy, 0x68uy, 0x91uy) + + let runtimeVer = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion() + let mutable metaHost = Unchecked.defaultof + CreateInterface(CLSID_CLRMetaHost, IID_ICLRMetaHost, &metaHost) + if Unchecked.defaultof = metaHost then + failwith "Unable to obtain ICLRMetaHost object - check freshness of mscoree.dll" + let runtimeInfo = metaHost.GetRuntime(runtimeVer, clrRuntimeInfoGuid) :?> ICLRRuntimeInfo + let sn = runtimeInfo.GetInterface(CLSID_CLRStrongName, IID_ICLRStrongName) :?> ICLRStrongName + if Unchecked.defaultof = sn then + failwith "Unable to obtain ICLRStrongName object" + iclrsn <- Some sn + sn + | Some sn -> sn + + let legacySignerGetPublicKeyForKeyPair kp = + if runningOnMono then + let snt = System.Type.GetType("Mono.Security.StrongName") + let sn = System.Activator.CreateInstance(snt, [| box kp |]) + snt.InvokeMember("PublicKey", (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| |], Globalization.CultureInfo.InvariantCulture) :?> byte[] + else + let mutable pSize = 0u + let mutable pBuffer: nativeint = (nativeint)0 + let iclrSN = getICLRStrongName() + + iclrSN.StrongNameGetPublicKey(Unchecked.defaultof, kp, (uint32) kp.Length, &pBuffer, &pSize) |> ignore + let mutable keybuffer: byte [] = Bytes.zeroCreate (int pSize) + // Copy the marshalled data over - we'll have to free this ourselves + Marshal.Copy(pBuffer, keybuffer, 0, int pSize) + iclrSN.StrongNameFreeBuffer pBuffer |> ignore + keybuffer + + let legacySignerGetPublicKeyForKeyContainer kc = + let mutable pSize = 0u + let mutable pBuffer: nativeint = (nativeint)0 + let iclrSN = getICLRStrongName() + iclrSN.StrongNameGetPublicKey(kc, Unchecked.defaultof, 0u, &pBuffer, &pSize) |> ignore + let mutable keybuffer: byte [] = Bytes.zeroCreate (int pSize) + // Copy the marshalled data over - we'll have to free this ourselves later + Marshal.Copy(pBuffer, keybuffer, 0, int pSize) + iclrSN.StrongNameFreeBuffer pBuffer |> ignore + keybuffer + + let legacySignerCloseKeyContainer kc = + let iclrSN = getICLRStrongName() + iclrSN.StrongNameKeyDelete kc |> ignore + + let legacySignerSignatureSize (pk: byte[]) = + if runningOnMono then + if pk.Length > 32 then pk.Length - 32 else 128 + else + let mutable pSize = 0u + let iclrSN = getICLRStrongName() + iclrSN.StrongNameSignatureSize(pk, uint32 pk.Length, &pSize) |> ignore + int pSize + + let legacySignerSignFileWithKeyPair fileName kp = + if runningOnMono then + let snt = System.Type.GetType("Mono.Security.StrongName") + let sn = System.Activator.CreateInstance(snt, [| box kp |]) + let conv (x: obj) = if (unbox x: bool) then 0 else -1 + snt.InvokeMember("Sign", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| box fileName |], Globalization.CultureInfo.InvariantCulture) |> conv |> check "Sign" + snt.InvokeMember("Verify", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| box fileName |], Globalization.CultureInfo.InvariantCulture) |> conv |> check "Verify" + else + let mutable pcb = 0u + let mutable ppb = (nativeint)0 + let mutable ok = false + let iclrSN = getICLRStrongName() + iclrSN.StrongNameSignatureGeneration(fileName, Unchecked.defaultof, kp, uint32 kp.Length, ppb, &pcb) |> ignore + iclrSN.StrongNameSignatureVerificationEx(fileName, true, &ok) |> ignore + + let legacySignerSignFileWithKeyContainer fileName kcName = + let mutable pcb = 0u + let mutable ppb = (nativeint)0 + let mutable ok = false + let iclrSN = getICLRStrongName() + iclrSN.StrongNameSignatureGeneration(fileName, kcName, Unchecked.defaultof, 0u, ppb, &pcb) |> ignore + iclrSN.StrongNameSignatureVerificationEx(fileName, true, &ok) |> ignore +#endif + + let failWithContainerSigningUnsupportedOnThisPlatform() = failwith (FSComp.SR.containerSigningUnsupportedOnThisPlatform() |> snd) + + //--------------------------------------------------------------------- + // Strong name signing + //--------------------------------------------------------------------- + type ILStrongNameSigner = + | PublicKeySigner of pubkey + | PublicKeyOptionsSigner of pubkeyOptions + | KeyPair of keyPair + | KeyContainer of keyContainerName + + static member OpenPublicKeyOptions s p = PublicKeyOptionsSigner((signerOpenPublicKeyFile s), p) + static member OpenPublicKey pubkey = PublicKeySigner pubkey + static member OpenKeyPairFile s = KeyPair(signerOpenKeyPairFile s) + static member OpenKeyContainer s = KeyContainer s + + member s.Close () = + match s with + | PublicKeySigner _ + | PublicKeyOptionsSigner _ + | KeyPair _ -> () + | KeyContainer containerName -> +#if !FX_NO_CORHOST_SIGNER + legacySignerCloseKeyContainer containerName +#else + ignore containerName + failWithContainerSigningUnsupportedOnThisPlatform() +#endif + member s.IsFullySigned = + match s with + | PublicKeySigner _ -> false + | PublicKeyOptionsSigner pko -> let _, usePublicSign = pko + usePublicSign + | KeyPair _ -> true + | KeyContainer _ -> +#if !FX_NO_CORHOST_SIGNER + true +#else + failWithContainerSigningUnsupportedOnThisPlatform() +#endif + + member s.PublicKey = + match s with + | PublicKeySigner pk -> pk + | PublicKeyOptionsSigner pko -> let pk, _ = pko + pk + | KeyPair kp -> signerGetPublicKeyForKeyPair kp + | KeyContainer containerName -> +#if !FX_NO_CORHOST_SIGNER + legacySignerGetPublicKeyForKeyContainer containerName +#else + ignore containerName + failWithContainerSigningUnsupportedOnThisPlatform() +#endif + + member s.SignatureSize = + let pkSignatureSize pk = + try + signerSignatureSize pk + with e -> + failwith ("A call to StrongNameSignatureSize failed ("+e.Message+")") + 0x80 + match s with + | PublicKeySigner pk -> pkSignatureSize pk + | PublicKeyOptionsSigner pko -> let pk, _ = pko + pkSignatureSize pk + | KeyPair kp -> pkSignatureSize (signerGetPublicKeyForKeyPair kp) + | KeyContainer containerName -> +#if !FX_NO_CORHOST_SIGNER + pkSignatureSize (legacySignerGetPublicKeyForKeyContainer containerName) +#else + ignore containerName + failWithContainerSigningUnsupportedOnThisPlatform() +#endif + + member s.SignFile file = + match s with + | PublicKeySigner _ -> () + | PublicKeyOptionsSigner _ -> () + | KeyPair kp -> signerSignFileWithKeyPair file kp + | KeyContainer containerName -> +#if !FX_NO_CORHOST_SIGNER + legacySignerSignFileWithKeyContainer file containerName +#else + ignore containerName + failWithContainerSigningUnsupportedOnThisPlatform() +#endif diff --git a/src/fsharp/absil/ilsign.fsi b/src/fsharp/absil/ilsign.fsi new file mode 100644 index 00000000000..23a82daffca --- /dev/null +++ b/src/fsharp/absil/ilsign.fsi @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Functions associated with signing il assemblies which +/// vary between supported implementations of the CLI Common Language +/// Runtime, e.g. between the SSCLI, Mono and the Microsoft CLR. +/// + +module internal FSharp.Compiler.AbstractIL.StrongNameSign + +//--------------------------------------------------------------------- +// Strong name signing +//--------------------------------------------------------------------- +[] +type ILStrongNameSigner = + member PublicKey: byte[] + static member OpenPublicKeyOptions: string -> bool -> ILStrongNameSigner + static member OpenPublicKey: byte[] -> ILStrongNameSigner + static member OpenKeyPairFile: string -> ILStrongNameSigner + static member OpenKeyContainer: string -> ILStrongNameSigner + member Close: unit -> unit + member IsFullySigned: bool + member PublicKey: byte[] + member SignatureSize: int + member SignFile: string -> unit diff --git a/src/absil/ilsupp.fs b/src/fsharp/absil/ilsupp.fs similarity index 76% rename from src/absil/ilsupp.fs rename to src/fsharp/absil/ilsupp.fs index a5dbe768b88..6e98d486954 100644 --- a/src/absil/ilsupp.fs +++ b/src/fsharp/absil/ilsupp.fs @@ -1,27 +1,21 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module internal FSharp.Compiler.AbstractIL.Internal.Support - -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Internal.NativeRes -#if FX_NO_CORHOST_SIGNER -open FSharp.Compiler.AbstractIL.Internal.StrongNameSign -#endif +module internal FSharp.Compiler.AbstractIL.Support open System open System.IO open System.Reflection - #if !FX_NO_SYMBOLSTORE open System.Diagnostics.SymbolStore #endif open System.Runtime.InteropServices -open System.Runtime.CompilerServices - +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.NativeRes +open FSharp.Compiler.IO +#if FX_NO_CORHOST_SIGNER +#endif -let DateTime1970Jan01 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) (* ECMA Spec (Oct2002), Part II, 24.2.2 PE File Header. *) +let DateTime1970Jan01 = DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) (* ECMA Spec (Oct2002), Part II, 24.2.2 PE File Header. *) let absilWriteGetTimeStamp () = (DateTime.UtcNow - DateTime1970Jan01).TotalSeconds |> int // Force inline, so GetLastWin32Error calls are immediately after interop calls as seen by FxCop under Debug build. @@ -30,22 +24,22 @@ let inline ignore _x = () // Native Resource linking/unlinking type IStream = System.Runtime.InteropServices.ComTypes.IStream -let check _action (hresult) = +let check _action hresult = if uint32 hresult >= 0x80000000ul then - System.Runtime.InteropServices.Marshal.ThrowExceptionForHR hresult + Marshal.ThrowExceptionForHR hresult //printf "action = %s, hresult = 0x%nx \n" action hresult let MAX_PATH = 260 let E_FAIL = 0x80004005 -let bytesToWord ((b0: byte), (b1: byte)) = +let bytesToWord (b0: byte, b1: byte) = int16 b0 ||| (int16 b1 <<< 8) -let bytesToDWord ((b0: byte), (b1: byte), (b2: byte), (b3: byte)) = +let bytesToDWord (b0: byte, b1: byte, b2: byte, b3: byte) = int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) -let bytesToQWord ((b0: byte), (b1: byte), (b2: byte), (b3: byte), (b4: byte), (b5: byte), (b6: byte), (b7: byte)) = +let bytesToQWord (b0: byte, b1: byte, b2: byte, b3: byte, b4: byte, b5: byte, b6: byte, b7: byte) = int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56) let dwToBytes n = [| byte (n &&& 0xff) ; byte ((n >>> 8) &&& 0xff) ; byte ((n >>> 16) &&& 0xff) ; byte ((n >>> 24) &&& 0xff) |], 4 @@ -94,7 +88,7 @@ type IMAGE_FILE_HEADER (m: int16, secs: int16, tds: int32, ptst: int32, nos: int with get() = 20 member x.toBytes () = - let buf = ByteBuffer.Create IMAGE_FILE_HEADER.Width + use buf = ByteBuffer.Create IMAGE_FILE_HEADER.Width buf.EmitUInt16 (uint16 machine) buf.EmitUInt16 (uint16 numberOfSections) buf.EmitInt32 timeDateStamp @@ -102,7 +96,7 @@ type IMAGE_FILE_HEADER (m: int16, secs: int16, tds: int32, ptst: int32, nos: int buf.EmitInt32 numberOfSymbols buf.EmitUInt16 (uint16 sizeOfOptionalHeader) buf.EmitUInt16 (uint16 characteristics) - buf.Close() + buf.AsMemory().ToArray() let bytesToIFH (buffer: byte[]) (offset: int) = if (buffer.Length - offset) < IMAGE_FILE_HEADER.Width then @@ -175,7 +169,7 @@ type IMAGE_SECTION_HEADER(n: int64, ai: int32, va: int32, srd: int32, prd: int32 with get() = 40 member x.toBytes () = - let buf = ByteBuffer.Create IMAGE_SECTION_HEADER.Width + use buf = ByteBuffer.Create IMAGE_SECTION_HEADER.Width buf.EmitInt64 name buf.EmitInt32 addressInfo buf.EmitInt32 virtualAddress @@ -186,7 +180,7 @@ type IMAGE_SECTION_HEADER(n: int64, ai: int32, va: int32, srd: int32, prd: int32 buf.EmitUInt16 (uint16 numberOfRelocations) buf.EmitUInt16 (uint16 numberOfLineNumbers) buf.EmitInt32 characteristics - buf.Close() + buf.AsMemory().ToArray() let bytesToISH (buffer: byte[]) (offset: int) = @@ -239,14 +233,14 @@ type IMAGE_SYMBOL(n: int64, v: int32, sn: int16, t: int16, sc: byte, nas: byte) with get() = 18 member x.toBytes() = - let buf = ByteBuffer.Create IMAGE_SYMBOL.Width + use buf = ByteBuffer.Create IMAGE_SYMBOL.Width buf.EmitInt64 name buf.EmitInt32 value buf.EmitUInt16 (uint16 sectionNumber) buf.EmitUInt16 (uint16 stype) buf.EmitByte storageClass buf.EmitByte numberOfAuxSymbols - buf.Close() + buf.AsMemory().ToArray() let bytesToIS (buffer: byte[]) (offset: int) = if (buffer.Length - offset) < IMAGE_SYMBOL.Width then @@ -283,11 +277,11 @@ type IMAGE_RELOCATION(va: int32, sti: int32, t: int16) = with get() = 10 member x.toBytes() = - let buf = ByteBuffer.Create IMAGE_RELOCATION.Width + use buf = ByteBuffer.Create IMAGE_RELOCATION.Width buf.EmitInt32 virtualAddress buf.EmitInt32 symbolTableIndex buf.EmitUInt16 (uint16 ty) - buf.Close() + buf.AsMemory().ToArray() let bytesToIR (buffer: byte[]) (offset: int) = if (buffer.Length - offset) < IMAGE_RELOCATION.Width then @@ -331,14 +325,14 @@ type IMAGE_RESOURCE_DIRECTORY(c: int32, tds: int32, mjv: int16, mnv: int16, nne: static member Width = 16 member x.toBytes () = - let buf = ByteBuffer.Create IMAGE_RESOURCE_DIRECTORY.Width + use buf = ByteBuffer.Create IMAGE_RESOURCE_DIRECTORY.Width buf.EmitInt32 characteristics buf.EmitInt32 timeDateStamp buf.EmitUInt16 (uint16 majorVersion) buf.EmitUInt16 (uint16 minorVersion) buf.EmitUInt16 (uint16 numberOfNamedEntries) buf.EmitUInt16 (uint16 numberOfIdEntries) - buf.Close() + buf.AsMemory().ToArray() let bytesToIRD (buffer: byte[]) (offset: int) = if (buffer.Length - offset) < IMAGE_RESOURCE_DIRECTORY.Width then @@ -371,10 +365,10 @@ type IMAGE_RESOURCE_DIRECTORY_ENTRY(n: int32, o: int32) = static member Width = 8 member x.toBytes () = - let buf = ByteBuffer.Create IMAGE_RESOURCE_DIRECTORY_ENTRY.Width + use buf = ByteBuffer.Create IMAGE_RESOURCE_DIRECTORY_ENTRY.Width buf.EmitInt32 name buf.EmitInt32 offset - buf.Close() + buf.AsMemory().ToArray() let bytesToIRDE (buffer: byte[]) (offset: int) = if (buffer.Length - offset) < IMAGE_RESOURCE_DIRECTORY_ENTRY.Width then @@ -404,7 +398,7 @@ type IMAGE_RESOURCE_DATA_ENTRY(o: int32, s: int32, c: int32, r: int32) = static member Width = 16 member x.toBytes() = - let buf = ByteBuffer.Create IMAGE_RESOURCE_DATA_ENTRY.Width + use buf = ByteBuffer.Create IMAGE_RESOURCE_DATA_ENTRY.Width buf.EmitInt32 offsetToData buf.EmitInt32 size buf.EmitInt32 codePage @@ -469,7 +463,7 @@ type ResFormatHeader() = static member Width = 32 member x.toBytes() = - let buf = ByteBuffer.Create ResFormatHeader.Width + use buf = ByteBuffer.Create ResFormatHeader.Width buf.EmitInt32 dwDataSize buf.EmitInt32 dwHeaderSize buf.EmitInt32 dwTypeID @@ -479,7 +473,7 @@ type ResFormatHeader() = buf.EmitUInt16 (uint16 wLangID) buf.EmitInt32 dwVersion buf.EmitInt32 dwCharacteristics - buf.Close() + buf.AsMemory().ToArray() type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLinkedResource: byte[]) = let mutable resHdr = ResFormatHeader() @@ -508,7 +502,7 @@ type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLink else resHdr.NameID <- (0xffff ||| ((nid &&& 0xffff) <<< 16)) - resHdr.LangID <- (int16)lid + resHdr.LangID <- int16 lid dataEntry <- bytesToIRDataE pbLinkedResource dataOffset resHdr.DataSize <- dataEntry.Size @@ -520,8 +514,8 @@ type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLink member x.Save(ulLinkedResourceBaseRVA: int32, pbLinkedResource: byte[], pUnlinkedResource: byte[], offset: int) = // Dump them to pUnlinkedResource // For each resource write header and data - let size = ref 0 - let unlinkedResourceOffset = ref 0 + let mutable size = 0 + let mutable unlinkedResourceOffset = 0 //resHdr.HeaderSize <- 32 if Unchecked.defaultof <> wzType then resHdr.HeaderSize <- resHdr.HeaderSize + ((cType + 1) * 2) - 4 @@ -530,9 +524,9 @@ type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLink let SaveChunk(p: byte[], sz: int) = if Unchecked.defaultof <> pUnlinkedResource then - Bytes.blit p 0 pUnlinkedResource (!unlinkedResourceOffset + offset) sz - unlinkedResourceOffset := !unlinkedResourceOffset + sz - size := !size + sz + Bytes.blit p 0 pUnlinkedResource (unlinkedResourceOffset + offset) sz + unlinkedResourceOffset <- unlinkedResourceOffset + sz + size <- size + sz () @@ -575,24 +569,24 @@ type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLink if dwFiller <> 0 then SaveChunk(bNil, 4 - dwFiller) - !size + size -let linkNativeResources (unlinkedResources: byte[] list) (ulLinkedResourceBaseRVA: int32) = +let linkNativeResources (unlinkedResources: byte[] list) (rva: int32) = let resources = unlinkedResources |> Seq.map (fun s -> new MemoryStream(s)) - |> Seq.map (fun s -> + |> Seq.map (fun s -> let res = CvtResFile.ReadResFile s s.Dispose() res) |> Seq.collect id // See MakeWin32ResourceList https://github.com/dotnet/roslyn/blob/f40b89234db51da1e1153c14af184e618504be41/src/Compilers/Core/Portable/Compilation/Compilation.cs - |> Seq.map (fun r -> - Win32Resource(data = r.data, codePage = 0u, languageId = uint32 r.LanguageId, + |> Seq.map (fun r -> + Win32Resource(data = r.data, codePage = 0u, languageId = uint32 r.LanguageId, id = int (int16 r.pstringName.Ordinal), name = r.pstringName.theString, typeId = int (int16 r.pstringType.Ordinal), typeName = r.pstringType.theString)) - let bb = new System.Reflection.Metadata.BlobBuilder() - NativeResourceWriter.SerializeWin32Resources(bb, resources, ulLinkedResourceBaseRVA) + let bb = System.Reflection.Metadata.BlobBuilder() + NativeResourceWriter.SerializeWin32Resources(bb, resources, rva) bb.ToArray() let unlinkResource (ulLinkedResourceBaseRVA: int32) (pbLinkedResource: byte[]) = @@ -659,7 +653,7 @@ let unlinkResource (ulLinkedResourceBaseRVA: int32) (pbLinkedResource: byte[]) = if pirdeLang.DataIsDirectory then // Resource hierarchy exceeds three levels - System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(E_FAIL) + Marshal.ThrowExceptionForHR(E_FAIL) else if (not skipResource) then let rfn = ResFormatNode(dwTypeID, dwNameID, dwLangID, pirdeLang.OffsetToData, pbLinkedResource) @@ -884,7 +878,7 @@ let pdbInitialize (binaryName: string) (pdbName: string) = { symWriter = writer } -[] +[] do() let pdbCloseDocument(documentWriter: PdbDocumentWriter) = @@ -908,7 +902,7 @@ let pdbClose (writer: PdbWriter) dllFilename pdbFilename = let isLocked filename = try - use x = File.Open (filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None) + use x = FileSystem.OpenFileForWriteShim(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None) false with | _ -> true @@ -934,7 +928,7 @@ let hashSizeOfMD5 = 16 // In this case, catch the failure, and not set a checksum. let internal setCheckSum (url: string, writer: ISymUnmanagedDocumentWriter) = try - use file = FileSystem.FileStreamReadShim url + use file = FileSystem.OpenFileForReadShim(url) use md5 = System.Security.Cryptography.MD5.Create() let checkSum = md5.ComputeHash file if (checkSum.Length = hashSizeOfMD5) then @@ -1003,7 +997,7 @@ type PdbMethod = { symMethod: ISymbolMethod } type PdbVariable = { symVariable: ISymbolVariable } type PdbMethodScope = { symScope: ISymbolScope } -type PdbSequencePoint = +type PdbDebugPoint = { pdbSeqPointOffset: int pdbSeqPointDocument: PdbDocument pdbSeqPointLine: int @@ -1078,7 +1072,7 @@ let pdbMethodGetToken (meth: PdbMethod) : int32 = let token = meth.symMethod.Token token.GetToken() -let pdbMethodGetSequencePoints (meth: PdbMethod) : PdbSequencePoint[] = +let pdbMethodGetDebugPoints (meth: PdbMethod) : PdbDebugPoint[] = let pSize = meth.symMethod.SequencePointCount let offsets = Array.zeroCreate pSize let docs = Array.zeroCreate pSize @@ -1118,235 +1112,3 @@ let pdbVariableGetSignature (variable: PdbVariable) : byte[] = let pdbVariableGetAddressAttributes (variable: PdbVariable) : (int32 * int32) = (int32 variable.symVariable.AddressKind, variable.symVariable.AddressField1) #endif - -// Key signing -type keyContainerName = string -type keyPair = byte[] -type pubkey = byte[] -type pubkeyOptions = byte[] * bool - -#if FX_NO_CORHOST_SIGNER - -let signerOpenPublicKeyFile filePath = FileSystem.ReadAllBytesShim filePath - -let signerOpenKeyPairFile filePath = FileSystem.ReadAllBytesShim filePath - -let signerGetPublicKeyForKeyPair (kp: keyPair) : pubkey = - let reply = (StrongNameSign.getPublicKeyForKeyPair kp) - reply - -let signerGetPublicKeyForKeyContainer (_kcName: keyContainerName) : pubkey = - raise (NotImplementedException("signerGetPublicKeyForKeyContainer is not yet implemented")) - -let signerCloseKeyContainer (_kc: keyContainerName) : unit = - raise (NotImplementedException("signerCloseKeyContainer is not yet implemented")) - -let signerSignatureSize (pk: pubkey) : int = - (StrongNameSign.signatureSize pk) - -let signerSignFileWithKeyPair (fileName: string) (kp: keyPair) : unit = - (StrongNameSign.signFile fileName kp) - -let signerSignFileWithKeyContainer (_fileName: string) (_kcName: keyContainerName) : unit = - raise (NotImplementedException("signerSignFileWithKeyContainer is not yet implemented")) - -#else -// New mscoree functionality -// This type represents methods that we don't currently need, so I'm leaving unimplemented -type UnusedCOMMethod = unit -> unit -[] -[] -type ICLRMetaHost = - [] - abstract GetRuntime: - [] version: string * - [] interfaceId: System.Guid -> [] System.Object - - // Methods that we don't need are stubbed out for now... - abstract GetVersionFromFile: UnusedCOMMethod - abstract EnumerateInstalledRuntimes: UnusedCOMMethod - abstract EnumerateLoadedRuntimes: UnusedCOMMethod - abstract Reserved01: UnusedCOMMethod - -// We don't currently support ComConversionLoss -[] -[] -type ICLRStrongName = - // Methods that we don't need are stubbed out for now... - abstract GetHashFromAssemblyFile: UnusedCOMMethod - abstract GetHashFromAssemblyFileW: UnusedCOMMethod - abstract GetHashFromBlob: UnusedCOMMethod - abstract GetHashFromFile: UnusedCOMMethod - abstract GetHashFromFileW: UnusedCOMMethod - abstract GetHashFromHandle: UnusedCOMMethod - abstract StrongNameCompareAssemblies: UnusedCOMMethod - - [] - abstract StrongNameFreeBuffer: [] pbMemory: nativeint -> unit - - abstract StrongNameGetBlob: UnusedCOMMethod - abstract StrongNameGetBlobFromImage: UnusedCOMMethod - - [] - abstract StrongNameGetPublicKey : - [] pwzKeyContainer: string * - [] pbKeyBlob: byte[] * - [] cbKeyBlob: uint32 * - [] ppbPublicKeyBlob: nativeint byref * - [] pcbPublicKeyBlob: uint32 byref -> unit - - abstract StrongNameHashSize: UnusedCOMMethod - - [] - abstract StrongNameKeyDelete: [] pwzKeyContainer: string -> unit - - abstract StrongNameKeyGen: UnusedCOMMethod - abstract StrongNameKeyGenEx: UnusedCOMMethod - abstract StrongNameKeyInstall: UnusedCOMMethod - - [] - abstract StrongNameSignatureGeneration : - [] pwzFilePath: string * - [] pwzKeyContainer: string * - [] pbKeyBlob: byte [] * - [] cbKeyBlob: uint32 * - [] ppbSignatureBlob: nativeint * - [] pcbSignatureBlob: uint32 byref -> unit - - abstract StrongNameSignatureGenerationEx: UnusedCOMMethod - - [] - abstract StrongNameSignatureSize : - [] pbPublicKeyBlob: byte[] * - [] cbPublicKeyBlob: uint32 * - [] pcbSize: uint32 byref -> unit - - abstract StrongNameSignatureVerification: UnusedCOMMethod - - [] - abstract StrongNameSignatureVerificationEx : - [] pwzFilePath: string * - [] fForceVerification: bool * - [] pfWasVerified: bool byref -> [] bool - - abstract StrongNameSignatureVerificationFromImage: UnusedCOMMethod - abstract StrongNameTokenFromAssembly: UnusedCOMMethod - abstract StrongNameTokenFromAssemblyEx: UnusedCOMMethod - abstract StrongNameTokenFromPublicKey: UnusedCOMMethod - - -[] -[] -type ICLRRuntimeInfo = - // REVIEW: Methods that we don't need will be stubbed out for now... - abstract GetVersionString: unit -> unit - abstract GetRuntimeDirectory: unit -> unit - abstract IsLoaded: unit -> unit - abstract LoadErrorString: unit -> unit - abstract LoadLibrary: unit -> unit - abstract GetProcAddress: unit -> unit - - [] - abstract GetInterface : - [] coClassId: System.Guid * - [] interfaceId: System.Guid -> []System.Object - -[] -[] -let CreateInterface ( - ([] _clsidguid: System.Guid), - ([] _guid: System.Guid), - ([] _metaHost : - ICLRMetaHost byref)) : unit = failwith "CreateInterface" - -let signerOpenPublicKeyFile filePath = FileSystem.ReadAllBytesShim filePath - -let signerOpenKeyPairFile filePath = FileSystem.ReadAllBytesShim filePath - -let mutable iclrsn: ICLRStrongName option = None -let getICLRStrongName () = - match iclrsn with - | None -> - let CLSID_CLRStrongName = System.Guid(0xB79B0ACDu, 0xF5CDus, 0x409bus, 0xB5uy, 0xA5uy, 0xA1uy, 0x62uy, 0x44uy, 0x61uy, 0x0Buy, 0x92uy) - let IID_ICLRStrongName = System.Guid(0x9FD93CCFu, 0x3280us, 0x4391us, 0xB3uy, 0xA9uy, 0x96uy, 0xE1uy, 0xCDuy, 0xE7uy, 0x7Cuy, 0x8Duy) - let CLSID_CLRMetaHost = System.Guid(0x9280188Du, 0x0E8Eus, 0x4867us, 0xB3uy, 0x0Cuy, 0x7Fuy, 0xA8uy, 0x38uy, 0x84uy, 0xE8uy, 0xDEuy) - let IID_ICLRMetaHost = System.Guid(0xD332DB9Eu, 0xB9B3us, 0x4125us, 0x82uy, 0x07uy, 0xA1uy, 0x48uy, 0x84uy, 0xF5uy, 0x32uy, 0x16uy) - let clrRuntimeInfoGuid = System.Guid(0xBD39D1D2u, 0xBA2Fus, 0x486aus, 0x89uy, 0xB0uy, 0xB4uy, 0xB0uy, 0xCBuy, 0x46uy, 0x68uy, 0x91uy) - - let runtimeVer = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion() - let mutable metaHost = Unchecked.defaultof - CreateInterface(CLSID_CLRMetaHost, IID_ICLRMetaHost, &metaHost) - if Unchecked.defaultof = metaHost then - failwith "Unable to obtain ICLRMetaHost object - check freshness of mscoree.dll" - let runtimeInfo = metaHost.GetRuntime(runtimeVer, clrRuntimeInfoGuid) :?> ICLRRuntimeInfo - let sn = runtimeInfo.GetInterface(CLSID_CLRStrongName, IID_ICLRStrongName) :?> ICLRStrongName - if Unchecked.defaultof = sn then - failwith "Unable to obtain ICLRStrongName object" - iclrsn <- Some sn - sn - | Some sn -> sn - -let signerGetPublicKeyForKeyPair kp = - if IL.runningOnMono then - let snt = System.Type.GetType("Mono.Security.StrongName") - let sn = System.Activator.CreateInstance(snt, [| box kp |]) - snt.InvokeMember("PublicKey", (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| |], Globalization.CultureInfo.InvariantCulture) :?> byte[] - else - let mutable pSize = 0u - let mutable pBuffer: nativeint = (nativeint)0 - let iclrSN = getICLRStrongName() - - iclrSN.StrongNameGetPublicKey(Unchecked.defaultof, kp, (uint32) kp.Length, &pBuffer, &pSize) |> ignore - let mutable keybuffer: byte [] = Bytes.zeroCreate (int pSize) - // Copy the marshalled data over - we'll have to free this ourselves - Marshal.Copy(pBuffer, keybuffer, 0, int pSize) - iclrSN.StrongNameFreeBuffer pBuffer |> ignore - keybuffer - -let signerGetPublicKeyForKeyContainer kc = - let mutable pSize = 0u - let mutable pBuffer: nativeint = (nativeint)0 - let iclrSN = getICLRStrongName() - iclrSN.StrongNameGetPublicKey(kc, Unchecked.defaultof, 0u, &pBuffer, &pSize) |> ignore - let mutable keybuffer: byte [] = Bytes.zeroCreate (int pSize) - // Copy the marshalled data over - we'll have to free this ourselves later - Marshal.Copy(pBuffer, keybuffer, 0, int pSize) - iclrSN.StrongNameFreeBuffer pBuffer |> ignore - keybuffer - -let signerCloseKeyContainer kc = - let iclrSN = getICLRStrongName() - iclrSN.StrongNameKeyDelete kc |> ignore - -let signerSignatureSize (pk: byte[]) = - if IL.runningOnMono then - if pk.Length > 32 then pk.Length - 32 else 128 - else - let mutable pSize = 0u - let iclrSN = getICLRStrongName() - iclrSN.StrongNameSignatureSize(pk, uint32 pk.Length, &pSize) |> ignore - int pSize - -let signerSignFileWithKeyPair fileName kp = - if IL.runningOnMono then - let snt = System.Type.GetType("Mono.Security.StrongName") - let sn = System.Activator.CreateInstance(snt, [| box kp |]) - let conv (x: obj) = if (unbox x: bool) then 0 else -1 - snt.InvokeMember("Sign", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| box fileName |], Globalization.CultureInfo.InvariantCulture) |> conv |> check "Sign" - snt.InvokeMember("Verify", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| box fileName |], Globalization.CultureInfo.InvariantCulture) |> conv |> check "Verify" - else - let mutable pcb = 0u - let mutable ppb = (nativeint)0 - let mutable ok = false - let iclrSN = getICLRStrongName() - iclrSN.StrongNameSignatureGeneration(fileName, Unchecked.defaultof, kp, uint32 kp.Length, ppb, &pcb) |> ignore - iclrSN.StrongNameSignatureVerificationEx(fileName, true, &ok) |> ignore - -let signerSignFileWithKeyContainer fileName kcName = - let mutable pcb = 0u - let mutable ppb = (nativeint)0 - let mutable ok = false - let iclrSN = getICLRStrongName() - iclrSN.StrongNameSignatureGeneration(fileName, kcName, Unchecked.defaultof, 0u, ppb, &pcb) |> ignore - iclrSN.StrongNameSignatureVerificationEx(fileName, true, &ok) |> ignore -#endif diff --git a/src/absil/ilsupp.fsi b/src/fsharp/absil/ilsupp.fsi similarity index 78% rename from src/absil/ilsupp.fsi rename to src/fsharp/absil/ilsupp.fsi index a32cdb605fe..0ac08c01a3b 100644 --- a/src/absil/ilsupp.fsi +++ b/src/fsharp/absil/ilsupp.fsi @@ -5,12 +5,17 @@ /// Runtime, e.g. between the SSCLI, Mono and the Microsoft CLR. /// /// The implementation of the functions can be found in ilsupp-*.fs -module internal FSharp.Compiler.AbstractIL.Internal.Support +module internal FSharp.Compiler.AbstractIL.Support + +#if !FX_NO_SYMBOLSTORE +open System.Diagnostics.SymbolStore +#endif #if !FX_NO_PDB_WRITER type PdbWriter val pdbInitialize : string -> string -> PdbWriter #endif + #if !FX_NO_PDB_READER type PdbReader val pdbReadClose: PdbReader -> unit @@ -18,17 +23,6 @@ val pdbReadClose: PdbReader -> unit val absilWriteGetTimeStamp: unit -> int32 -open System -open System.Runtime.InteropServices -#if FX_NO_SYMBOLSTORE -#else -open System.Diagnostics.SymbolStore -#endif -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.IL - type IStream = System.Runtime.InteropServices.ComTypes.IStream /// Unmanaged resource file linker - for native resources (not managed ones). @@ -45,7 +39,7 @@ type PdbMethod type PdbVariable type PdbMethodScope -type PdbSequencePoint = +type PdbDebugPoint = { pdbSeqPointOffset: int; pdbSeqPointDocument: PdbDocument; pdbSeqPointLine: int; @@ -67,7 +61,7 @@ val pdbDocumentGetLanguageVendor: PdbDocument -> byte[] (* guid *) val pdbDocumentFindClosestLine: PdbDocument -> int -> int val pdbMethodGetToken: PdbMethod -> int32 -val pdbMethodGetSequencePoints: PdbMethod -> PdbSequencePoint array +val pdbMethodGetDebugPoints: PdbMethod -> PdbDebugPoint array val pdbScopeGetChildren: PdbMethodScope -> PdbMethodScope array val pdbScopeGetOffsets: PdbMethodScope -> int * int @@ -109,21 +103,3 @@ val pdbSetMethodRange: PdbWriter -> PdbDocumentWriter -> int -> int -> PdbDocume val pdbDefineSequencePoints: PdbWriter -> PdbDocumentWriter -> (int * int * int * int * int) array -> unit val pdbWriteDebugInfo: PdbWriter -> idd #endif - -//--------------------------------------------------------------------- -// Strong name signing -//--------------------------------------------------------------------- - -type keyContainerName = string -type keyPair = byte[] -type pubkey = byte[] -type pubkeyOptions = byte[] * bool - -val signerOpenPublicKeyFile: string -> pubkey -val signerOpenKeyPairFile: string -> keyPair -val signerSignatureSize: pubkey -> int -val signerGetPublicKeyForKeyPair: keyPair -> pubkey -val signerGetPublicKeyForKeyContainer: string -> pubkey -val signerCloseKeyContainer: keyContainerName -> unit -val signerSignFileWithKeyPair: string -> keyPair -> unit -val signerSignFileWithKeyContainer: string -> keyContainerName -> unit diff --git a/src/fsharp/absil/ilwrite.fs b/src/fsharp/absil/ilwrite.fs new file mode 100644 index 00000000000..e63d543677b --- /dev/null +++ b/src/fsharp/absil/ilwrite.fs @@ -0,0 +1,4376 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.AbstractIL.ILBinaryWriter + +open System +open System.Collections.Generic +open System.IO + +open Internal.Utilities +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.AbstractIL.BinaryConstants +open FSharp.Compiler.AbstractIL.Support +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.StrongNameSign +open FSharp.Compiler.AbstractIL.ILPdbWriter +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range + +#if DEBUG +let showEntryLookups = false +#endif + +//--------------------------------------------------------------------- +// Byte, byte array fragments and other concrete representations +// manipulations. +//--------------------------------------------------------------------- + +// Little-endian encoding of int32 +let b0 n = byte (n &&& 0xFF) +let b1 n = byte ((n >>> 8) &&& 0xFF) +let b2 n = byte ((n >>> 16) &&& 0xFF) +let b3 n = byte ((n >>> 24) &&& 0xFF) + +// Little-endian encoding of int64 +let dw7 n = byte ((n >>> 56) &&& 0xFFL) +let dw6 n = byte ((n >>> 48) &&& 0xFFL) +let dw5 n = byte ((n >>> 40) &&& 0xFFL) +let dw4 n = byte ((n >>> 32) &&& 0xFFL) +let dw3 n = byte ((n >>> 24) &&& 0xFFL) +let dw2 n = byte ((n >>> 16) &&& 0xFFL) +let dw1 n = byte ((n >>> 8) &&& 0xFFL) +let dw0 n = byte (n &&& 0xFFL) + +let bitsOfSingle (x: float32) = BitConverter.ToInt32(BitConverter.GetBytes x, 0) +let bitsOfDouble (x: float) = BitConverter.DoubleToInt64Bits x + +/// Arbitrary value +[] +let EmitBytesViaBufferCapacity = 10 +let emitBytesViaBuffer f = use bb = ByteBuffer.Create EmitBytesViaBufferCapacity in f bb; bb.AsMemory().ToArray() + +/// Alignment and padding +let align alignment n = ((n + alignment - 1) / alignment) * alignment + +//--------------------------------------------------------------------- +// Concrete token representations etc. used in PE files +//--------------------------------------------------------------------- + +type ByteBuffer with + + /// Z32 = compressed unsigned integer + static member Z32Size n = + if n <= 0x7F then 1 + elif n <= 0x3FFF then 2 + else 4 + + /// Emit int32 as compressed unsigned integer + member buf.EmitZ32 n = + if n >= 0 && n <= 0x7F then + buf.EmitIntAsByte n + elif n >= 0x80 && n <= 0x3FFF then + buf.EmitIntAsByte (0x80 ||| (n >>> 8)) + buf.EmitIntAsByte (n &&& 0xFF) + else + buf.EmitIntAsByte (0xC0 ||| ((n >>> 24) &&& 0xFF)) + buf.EmitIntAsByte ((n >>> 16) &&& 0xFF) + buf.EmitIntAsByte ((n >>> 8) &&& 0xFF) + buf.EmitIntAsByte (n &&& 0xFF) + + member buf.EmitPadding n = + for i = 0 to n-1 do + buf.EmitByte 0x0uy + + // Emit compressed untagged integer + member buf.EmitZUntaggedIndex big idx = + if big then buf.EmitInt32 idx + else + // Note, we can have idx=0x10000 generated for method table idx + 1 for just beyond last index of method table. + // This indicates that a MethodList, FieldList, PropertyList or EventList has zero entries + // For this case, the EmitInt32AsUInt16 writes a 0 (null) into the field. Binary readers respect this as an empty + // list of methods/fields/properties/events. + if idx > 0x10000 then + System.Diagnostics.Debug.Assert (false, "EmitZUntaggedIndex: too big for small address or simple index") + buf.EmitInt32AsUInt16 idx + + // Emit compressed tagged integer + member buf.EmitZTaggedIndex tag nbits big idx = + let idx2 = (idx <<< nbits) ||| tag + if big then buf.EmitInt32 idx2 + else buf.EmitInt32AsUInt16 idx2 + +let getUncodedToken (tab: TableName) idx = ((tab.Index <<< 24) ||| idx) + +// From ECMA for UserStrings: +// This final byte holds the value 1 if and only if any UTF16 character within the string has any bit set in its top byte, or its low byte is any of the following: +// 0x01-0x08, 0x0E-0x1F, 0x27, 0x2D, +// 0x7F. Otherwise, it holds 0. The 1 signifies Unicode characters that require handling beyond that normally provided for 8-bit encoding sets. + +// HOWEVER, there is a discrepancy here between the ECMA spec and the Microsoft C# implementation. +// The code below follows the latter. We've raised the issue with both teams. See Dev10 bug 850073 for details. + +let markerForUnicodeBytes (b: byte[]) = + let len = b.Length + let rec scan i = + i < len/2 && + (let b1 = Bytes.get b (i*2) + let b2 = Bytes.get b (i*2+1) + (b2 <> 0) + || (b1 >= 0x01 && b1 <= 0x08) // as per ECMA and C# + || (b1 >= 0xE && b1 <= 0x1F) // as per ECMA and C# + || (b1 = 0x27) // as per ECMA and C# + || (b1 = 0x2D) // as per ECMA and C# + || (b1 > 0x7F) // as per C# (but ECMA omits this) + || scan (i+1)) + let marker = if scan 0 then 0x01 else 0x00 + marker + + +// -------------------------------------------------------------------- +// Fixups +// -------------------------------------------------------------------- + +/// Check that the data held at a fixup is some special magic value, as a sanity check +/// to ensure the fixup is being placed at a ood location. +let checkFixup32 (data: byte[]) offset exp = + if data.[offset + 3] <> b3 exp then failwith "fixup sanity check failed" + if data.[offset + 2] <> b2 exp then failwith "fixup sanity check failed" + if data.[offset + 1] <> b1 exp then failwith "fixup sanity check failed" + if data.[offset] <> b0 exp then failwith "fixup sanity check failed" + +let applyFixup32 (data: byte[]) offset v = + data.[offset] <- b0 v + data.[offset+1] <- b1 v + data.[offset+2] <- b2 v + data.[offset+3] <- b3 v + +//--------------------------------------------------------------------- +// TYPES FOR TABLES +//--------------------------------------------------------------------- + +module RowElementTags = + let [] UShort = 0 + let [] ULong = 1 + let [] Data = 2 + let [] DataResources = 3 + let [] Guid = 4 + let [] Blob = 5 + let [] String = 6 + let [] SimpleIndexMin = 7 + let SimpleIndex (t : TableName) = assert (t.Index <= 112); SimpleIndexMin + t.Index + let [] SimpleIndexMax = 119 + + let [] TypeDefOrRefOrSpecMin = 120 + let TypeDefOrRefOrSpec (t: TypeDefOrRefTag) = assert (t.Tag <= 2); TypeDefOrRefOrSpecMin + t.Tag (* + 111 + 1 = 0x70 + 1 = max TableName.Tndex + 1 *) + let [] TypeDefOrRefOrSpecMax = 122 + + let [] TypeOrMethodDefMin = 123 + let TypeOrMethodDef (t: TypeOrMethodDefTag) = assert (t.Tag <= 1); TypeOrMethodDefMin + t.Tag (* + 2 + 1 = max TypeDefOrRefOrSpec.Tag + 1 *) + let [] TypeOrMethodDefMax = 124 + + let [] HasConstantMin = 125 + let HasConstant (t: HasConstantTag) = assert (t.Tag <= 2); HasConstantMin + t.Tag (* + 1 + 1 = max TypeOrMethodDef.Tag + 1 *) + let [] HasConstantMax = 127 + + let [] HasCustomAttributeMin = 128 + let HasCustomAttribute (t: HasCustomAttributeTag) = assert (t.Tag <= 21); HasCustomAttributeMin + t.Tag (* + 2 + 1 = max HasConstant.Tag + 1 *) + let [] HasCustomAttributeMax = 149 + + let [] HasFieldMarshalMin = 150 + let HasFieldMarshal (t: HasFieldMarshalTag) = assert (t.Tag <= 1); HasFieldMarshalMin + t.Tag (* + 21 + 1 = max HasCustomAttribute.Tag + 1 *) + let [] HasFieldMarshalMax = 151 + + let [] HasDeclSecurityMin = 152 + let HasDeclSecurity (t: HasDeclSecurityTag) = assert (t.Tag <= 2); HasDeclSecurityMin + t.Tag (* + 1 + 1 = max HasFieldMarshal.Tag + 1 *) + let [] HasDeclSecurityMax = 154 + + let [] MemberRefParentMin = 155 + let MemberRefParent (t: MemberRefParentTag) = assert (t.Tag <= 4); MemberRefParentMin + t.Tag (* + 2 + 1 = max HasDeclSecurity.Tag + 1 *) + let [] MemberRefParentMax = 159 + + let [] HasSemanticsMin = 160 + let HasSemantics (t: HasSemanticsTag) = assert (t.Tag <= 1); HasSemanticsMin + t.Tag (* + 4 + 1 = max MemberRefParent.Tag + 1 *) + let [] HasSemanticsMax = 161 + + let [] MethodDefOrRefMin = 162 + let MethodDefOrRef (t: MethodDefOrRefTag) = assert (t.Tag <= 2); MethodDefOrRefMin + t.Tag (* + 1 + 1 = max HasSemantics.Tag + 1 *) + let [] MethodDefOrRefMax = 164 + + let [] MemberForwardedMin = 165 + let MemberForwarded (t: MemberForwardedTag) = assert (t.Tag <= 1); MemberForwardedMin + t.Tag (* + 2 + 1 = max MethodDefOrRef.Tag + 1 *) + let [] MemberForwardedMax = 166 + + let [] ImplementationMin = 167 + let Implementation (t: ImplementationTag) = assert (t.Tag <= 2); ImplementationMin + t.Tag (* + 1 + 1 = max MemberForwarded.Tag + 1 *) + let [] ImplementationMax = 169 + + let [] CustomAttributeTypeMin = 170 + let CustomAttributeType (t: CustomAttributeTypeTag) = assert (t.Tag <= 3); CustomAttributeTypeMin + t.Tag (* + 2 + 1 = max Implementation.Tag + 1 *) + let [] CustomAttributeTypeMax = 173 + + let [] ResolutionScopeMin = 174 + let ResolutionScope (t: ResolutionScopeTag) = assert (t.Tag <= 4); ResolutionScopeMin + t.Tag (* + 3 + 1 = max CustomAttributeType.Tag + 1 *) + let [] ResolutionScopeMax = 178 + +[] +type RowElement(tag: int32, idx: int32) = + + member x.Tag = tag + member x.Val = idx + +// These create RowElements +let UShort (x: uint16) = RowElement(RowElementTags.UShort, int32 x) + +let ULong (x: int32) = RowElement(RowElementTags.ULong, x) + +/// Index into cenv.data or cenv.resources. Gets fixed up later once we known an overall +/// location for the data section. flag indicates if offset is relative to cenv.resources. +let Data (x: int, k: bool) = RowElement((if k then RowElementTags.DataResources else RowElementTags.Data ), x) + +/// pos. in guid array +let Guid (x: int) = RowElement(RowElementTags.Guid, x) + +/// pos. in blob array +let Blob (x: int) = RowElement(RowElementTags.Blob, x) + +/// pos. in string array +let StringE (x: int) = RowElement(RowElementTags.String, x) + +/// pos. in some table +let SimpleIndex (t, x: int) = RowElement(RowElementTags.SimpleIndex t, x) + +let TypeDefOrRefOrSpec (t, x: int) = RowElement(RowElementTags.TypeDefOrRefOrSpec t, x) + +let TypeOrMethodDef (t, x: int) = RowElement(RowElementTags.TypeOrMethodDef t, x) + +let HasConstant (t, x: int) = RowElement(RowElementTags.HasConstant t, x) + +let HasCustomAttribute (t, x: int) = RowElement(RowElementTags.HasCustomAttribute t, x) + +let HasFieldMarshal (t, x: int) = RowElement(RowElementTags.HasFieldMarshal t, x) + +let HasDeclSecurity (t, x: int) = RowElement(RowElementTags.HasDeclSecurity t, x) + +let MemberRefParent (t, x: int) = RowElement(RowElementTags.MemberRefParent t, x) + +let HasSemantics (t, x: int) = RowElement(RowElementTags.HasSemantics t, x) + +let MethodDefOrRef (t, x: int) = RowElement(RowElementTags.MethodDefOrRef t, x) + +let MemberForwarded (t, x: int) = RowElement(RowElementTags.MemberForwarded t, x) + +let Implementation (t, x: int) = RowElement(RowElementTags.Implementation t, x) + +let CustomAttributeType (t, x: int) = RowElement(RowElementTags.CustomAttributeType t, x) + +let ResolutionScope (t, x: int) = RowElement(RowElementTags.ResolutionScope t, x) + +type BlobIndex = int + +type StringIndex = int + +let BlobIndex (x: BlobIndex) : int = x + +let StringIndex (x: StringIndex) : int = x + +let inline combineHash x2 acc = 37 * acc + x2 // (acc <<< 6 + acc >>> 2 + x2 + 0x9e3779b9) + +let hashRow (elems: RowElement[]) = + let mutable acc = 0 + for i in 0 .. elems.Length - 1 do + acc <- (acc <<< 1) + elems.[i].Tag + elems.[i].Val + 631 + acc + +let equalRows (elems: RowElement[]) (elems2: RowElement[]) = + if elems.Length <> elems2.Length then false else + let mutable ok = true + let n = elems.Length + let mutable i = 0 + while ok && i < n do + if elems.[i].Tag <> elems2.[i].Tag || elems.[i].Val <> elems2.[i].Val then ok <- false + i <- i + 1 + ok + +type GenericRow = RowElement[] + +/// This is the representation of shared rows is used for most shared row types. +/// Rows ILAssemblyRef and ILMethodRef are very common and are given their own +/// representations. +[] +type SharedRow(elems: RowElement[], hashCode: int) = + + member x.GenericRow = elems + + override x.GetHashCode() = hashCode + + override x.Equals(obj: obj) = + match obj with + | :? SharedRow as y -> equalRows elems y.GenericRow + | _ -> false + +let SharedRow(elems: RowElement[]) = SharedRow(elems, hashRow elems) + +/// Special representation : Note, only hashing by name +let AssemblyRefRow(s1, s2, s3, s4, l1, b1, nameIdx, str2, b2) = + let hashCode = hash nameIdx + let genericRow = [| UShort s1; UShort s2; UShort s3; UShort s4; ULong l1; Blob b1; StringE nameIdx; StringE str2; Blob b2 |] + new SharedRow(genericRow, hashCode) + +/// Special representation the computes the hash more efficiently +let MemberRefRow(mrp: RowElement, nmIdx: StringIndex, blobIdx: BlobIndex) = + let hashCode = combineHash (hash blobIdx) (combineHash (hash nmIdx) (hash mrp)) + let genericRow = [| mrp; StringE nmIdx; Blob blobIdx |] + new SharedRow(genericRow, hashCode) + +/// Unshared rows are used for definitional tables where elements do not need to be made unique +/// e.g. ILMethodDef and ILTypeDef. Most tables are like this. We don't precompute a +/// hash code for these rows, and indeed the GetHashCode and Equals should not be needed. +[] +type UnsharedRow(elems: RowElement[]) = + + member x.GenericRow = elems + + override x.GetHashCode() = hashRow elems + + override x.Equals(obj: obj) = + match obj with + | :? UnsharedRow as y -> equalRows elems y.GenericRow + | _ -> false + +//===================================================================== +//===================================================================== +// IL --> TABLES+CODE +//===================================================================== +//===================================================================== + +// This environment keeps track of how many generic parameters are in scope. +// This lets us translate AbsIL type variable number to IL type variable numbering +type ILTypeWriterEnv = { EnclosingTyparCount: int } +let envForTypeDef (td: ILTypeDef) = { EnclosingTyparCount=td.GenericParams.Length } +let envForMethodRef env (ty: ILType) = { EnclosingTyparCount=(match ty with ILType.Array _ -> env.EnclosingTyparCount | _ -> ty.GenericArgs.Length) } +let envForNonGenericMethodRef _mref = { EnclosingTyparCount=Int32.MaxValue } +let envForFieldSpec (fspec: ILFieldSpec) = { EnclosingTyparCount=fspec.DeclaringType.GenericArgs.Length } +let envForOverrideSpec (ospec: ILOverridesSpec) = { EnclosingTyparCount=ospec.DeclaringType.GenericArgs.Length } + +//--------------------------------------------------------------------- +// TABLES +//--------------------------------------------------------------------- + +[] +type MetadataTable<'T> = + { name: string + dict: Dictionary<'T, int> // given a row, find its entry number + mutable rows: ResizeArray<'T> } + + member x.Count = x.rows.Count + + static member New(nm, hashEq) = + { name=nm + dict = Dictionary<_, _>(100, hashEq) + rows= ResizeArray<_>() } + + member tbl.EntriesAsArray = + tbl.rows |> ResizeArray.toArray + + member tbl.Entries = + tbl.rows |> ResizeArray.toList + + member tbl.AddSharedEntry x = + let n = tbl.rows.Count + 1 + tbl.dict.[x] <- n + tbl.rows.Add x + n + + member tbl.AddUnsharedEntry x = + let n = tbl.rows.Count + 1 + tbl.rows.Add x + n + + member tbl.FindOrAddSharedEntry x = + match tbl.dict.TryGetValue x with + | true, res -> res + | _ -> tbl.AddSharedEntry x + + + /// This is only used in one special place - see further below. + member tbl.SetRowsOfTable t = + tbl.rows <- ResizeArray.ofArray t + let h = tbl.dict + h.Clear() + t |> Array.iteri (fun i x -> h.[x] <- (i+1)) + + member tbl.AddUniqueEntry nm getter x = + if tbl.dict.ContainsKey x then failwith ("duplicate entry '"+getter x+"' in "+nm+" table") + else tbl.AddSharedEntry x + + member tbl.GetTableEntry x = tbl.dict.[x] + +//--------------------------------------------------------------------- +// Keys into some of the tables +//--------------------------------------------------------------------- + +/// We use this key type to help find ILMethodDefs for MethodRefs +type MethodDefKey(ilg:ILGlobals, tidx: int, garity: int, nm: string, rty: ILType, argtys: ILTypes, isStatic: bool) = + // Precompute the hash. The hash doesn't include the return type or + // argument types (only argument type count). This is very important, since + // hashing these is way too expensive + let hashCode = + hash tidx + |> combineHash (hash garity) + |> combineHash (hash nm) + |> combineHash (hash argtys.Length) + |> combineHash (hash isStatic) + + member _.TypeIdx = tidx + + member _.GenericArity = garity + + member _.Name = nm + + member _.ReturnType = rty + + member _.ArgTypes = argtys + + member _.IsStatic = isStatic + + override _.GetHashCode() = hashCode + + override _.Equals(obj: obj) = + match obj with + | :? MethodDefKey as y -> + let compareILTypes o1 o2 = + match o1, o2 with + | ILType.Value v1, ILType.Value v2 -> v1.EqualsWithPrimaryScopeRef(ilg.primaryAssemblyScopeRef, v2 :> obj ) + | _ -> o1 = o2 + + tidx = y.TypeIdx && + garity = y.GenericArity && + nm = y.Name && + // note: these next two use structural equality on AbstractIL ILType values + rty = y.ReturnType && List.lengthsEqAndForall2 compareILTypes argtys y.ArgTypes && + isStatic = y.IsStatic + | _ -> false + +/// We use this key type to help find ILFieldDefs for FieldRefs +type FieldDefKey(tidx: int, nm: string, ty: ILType) = + // precompute the hash. hash doesn't include the type + let hashCode = hash tidx |> combineHash (hash nm) + + member _.TypeIdx = tidx + + member _.Name = nm + + member _.Type = ty + + override _.GetHashCode() = hashCode + + override _.Equals(obj: obj) = + match obj with + | :? FieldDefKey as y -> + tidx = y.TypeIdx && + nm = y.Name && + ty = y.Type + | _ -> false + +type PropertyTableKey = PropKey of int (* type. def. idx. *) * string * ILType * ILTypes + +type EventTableKey = EventKey of int (* type. def. idx. *) * string + +type TypeDefTableKey = TdKey of string list (* enclosing *) * string (* type name *) + +//--------------------------------------------------------------------- +// The Writer Context +//--------------------------------------------------------------------- + +[] +type MetadataTable = + | Shared of MetadataTable + | Unshared of MetadataTable + member t.FindOrAddSharedEntry x = match t with Shared u -> u.FindOrAddSharedEntry x | Unshared u -> failwithf "FindOrAddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddSharedEntry x = match t with | Shared u -> u.AddSharedEntry x | Unshared u -> failwithf "AddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddUnsharedEntry x = match t with Unshared u -> u.AddUnsharedEntry x | Shared u -> failwithf "AddUnsharedEntry: incorrect table kind, u.name = %s" u.name + member t.GenericRowsOfTable = match t with Unshared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) | Shared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) + member t.SetRowsOfSharedTable rows = match t with Shared u -> u.SetRowsOfTable (Array.map SharedRow rows) | Unshared u -> failwithf "SetRowsOfSharedTable: incorrect table kind, u.name = %s" u.name + member t.Count = match t with Unshared u -> u.Count | Shared u -> u.Count + + +[] +type cenv = + { ilg: ILGlobals + + emitTailcalls: bool + + deterministic: bool + + showTimes: bool + + desiredMetadataVersion: ILVersionInfo + + requiredDataFixups: (int32 * (int * bool)) list ref + + /// References to strings in codestreams: offset of code and a (fixup-location, string token) list) + mutable requiredStringFixups: (int32 * (int * int) list) list + + codeChunks: ByteBuffer + + mutable nextCodeAddr: int32 + + /// Collected debug information + mutable moduleGuid: byte[] + + generatePdb: bool + + pdbinfo: ResizeArray + + documents: MetadataTable + + /// Raw data, to go into the data section + data: ByteBuffer + + /// Raw resource data, to go into the data section + resources: ByteBuffer + + mutable entrypoint: (bool * int) option + + /// Caches + trefCache: Dictionary + + /// The following are all used to generate unique items in the output + tables: MetadataTable[] + + AssemblyRefs: MetadataTable + + fieldDefs: MetadataTable + + methodDefIdxsByKey: MetadataTable + + methodDefIdxs: Dictionary + + propertyDefs: MetadataTable + + eventDefs: MetadataTable + + typeDefs: MetadataTable + + guids: MetadataTable + + blobs: MetadataTable + + strings: MetadataTable + + userStrings: MetadataTable + + normalizeAssemblyRefs: ILAssemblyRef -> ILAssemblyRef + + pdbImports: Dictionary + } + member cenv.GetTable (tab: TableName) = cenv.tables.[tab.Index] + + + member cenv.AddCode ((reqdStringFixupsOffset, requiredStringFixups), code) = + if align 4 cenv.nextCodeAddr <> cenv.nextCodeAddr then dprintn "warning: code not 4-byte aligned" + cenv.requiredStringFixups <- (cenv.nextCodeAddr + reqdStringFixupsOffset, requiredStringFixups) :: cenv.requiredStringFixups + cenv.codeChunks.EmitBytes code + cenv.nextCodeAddr <- cenv.nextCodeAddr + code.Length + + member cenv.GetCode() = cenv.codeChunks.AsMemory().ToArray() + + override x.ToString() = "" + + interface IDisposable with + member this.Dispose() = + (this.codeChunks :> IDisposable).Dispose() + (this.data :> IDisposable).Dispose() + (this.resources :> IDisposable).Dispose() + +let FindOrAddSharedRow (cenv: cenv) tbl x = cenv.GetTable(tbl).FindOrAddSharedEntry x + +// Shared rows must be hash-cons'd to be made unique (no duplicates according to contents) +let AddSharedRow (cenv: cenv) tbl x = cenv.GetTable(tbl).AddSharedEntry x + +// Unshared rows correspond to definition elements (e.g. a ILTypeDef or a ILMethodDef) +let AddUnsharedRow (cenv: cenv) tbl (x: UnsharedRow) = cenv.GetTable(tbl).AddUnsharedEntry x + +let metadataSchemaVersionSupportedByCLRVersion v = + // Whidbey Beta 1 version numbers are between 2.0.40520.0 and 2.0.40607.0 + // Later Whidbey versions are post 2.0.40607.0.. However we assume + // internal builds such as 2.0.x86chk are Whidbey Beta 2 or later + if compareILVersions v (parseILVersion "2.0.40520.0") >= 0 && + compareILVersions v (parseILVersion "2.0.40608.0") < 0 then 1, 1 + elif compareILVersions v (parseILVersion "2.0.0.0") >= 0 then 2, 0 + else 1, 0 + +let headerVersionSupportedByCLRVersion v = + // The COM20HEADER version number + // Whidbey version numbers are 2.5 + // Earlier are 2.0 + // From an email from jeffschw: "Be built with a compiler that marks the COM20HEADER with Major >=2 and Minor >= 5. The V2.0 compilers produce images with 2.5, V1.x produces images with 2.0." + if compareILVersions v (parseILVersion "2.0.0.0") >= 0 then 2, 5 + else 2, 0 + +let peOptionalHeaderByteByCLRVersion v = + // A flag in the PE file optional header seems to depend on CLI version + // Whidbey version numbers are 8 + // Earlier are 6 + // Tools are meant to ignore this, but the VS Profiler wants it to have the right value + if compareILVersions v (parseILVersion "2.0.0.0") >= 0 then 8 + else 6 + +// returned by writeBinaryAndReportMappings +[] +type ILTokenMappings = + { TypeDefTokenMap: ILTypeDef list * ILTypeDef -> int32 + FieldDefTokenMap: ILTypeDef list * ILTypeDef -> ILFieldDef -> int32 + MethodDefTokenMap: ILTypeDef list * ILTypeDef -> ILMethodDef -> int32 + PropertyTokenMap: ILTypeDef list * ILTypeDef -> ILPropertyDef -> int32 + EventTokenMap: ILTypeDef list * ILTypeDef -> ILEventDef -> int32 } + +let recordRequiredDataFixup (requiredDataFixups: ('T * 'U) list ref) (buf: ByteBuffer) pos lab = + requiredDataFixups.Value <- (pos, lab) :: requiredDataFixups.Value + // Write a special value in that we check later when applying the fixup + buf.EmitInt32 0xdeaddddd + +//--------------------------------------------------------------------- +// The UserString, BlobHeap, GuidHeap tables +//--------------------------------------------------------------------- + +let GetUserStringHeapIdx cenv s = + cenv.userStrings.FindOrAddSharedEntry s + +let GetBytesAsBlobIdx cenv (bytes: byte[]) = + if bytes.Length = 0 then 0 + else cenv.blobs.FindOrAddSharedEntry bytes + +let GetStringHeapIdx cenv s = + if s = "" then 0 + else cenv.strings.FindOrAddSharedEntry s + +let GetGuidIdx cenv info = cenv.guids.FindOrAddSharedEntry info + +let GetStringHeapIdxOption cenv sopt = + match sopt with + | Some ns -> GetStringHeapIdx cenv ns + | None -> 0 + +let GetTypeNameAsElemPair cenv n = + let n1, n2 = splitTypeNameRight n + StringE (GetStringHeapIdxOption cenv n1), + StringE (GetStringHeapIdx cenv n2) + +//===================================================================== +// Pass 1 - allocate indexes for types +//===================================================================== + +let rec GenTypeDefPass1 enc cenv (td: ILTypeDef) = + ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, td.Name))) + GenTypeDefsPass1 (enc@[td.Name]) cenv td.NestedTypes.AsList + +and GenTypeDefsPass1 enc cenv tds = List.iter (GenTypeDefPass1 enc cenv) tds + +//===================================================================== +// Pass 2 - allocate indexes for methods and fields and write rows for types +//===================================================================== + +let rec GetIdxForTypeDef cenv key = + try cenv.typeDefs.GetTableEntry key + with + :? KeyNotFoundException -> + let (TdKey (enc, n) ) = key + errorR(InternalError("One of your modules expects the type '"+String.concat "." (enc@[n])+"' to be defined within the module being emitted. You may be missing an input file", range0)) + 0 + +// -------------------------------------------------------------------- +// Assembly and module references +// -------------------------------------------------------------------- + +let rec GetAssemblyRefAsRow cenv (aref: ILAssemblyRef) = + AssemblyRefRow + ((match aref.Version with None -> 0us | Some version -> version.Major), + (match aref.Version with None -> 0us | Some version -> version.Minor), + (match aref.Version with None -> 0us | Some version -> version.Build), + (match aref.Version with None -> 0us | Some version -> version.Revision), + ((match aref.PublicKey with Some (PublicKey _) -> 0x0001 | _ -> 0x0000) + ||| (if aref.Retargetable then 0x0100 else 0x0000)), + BlobIndex (match aref.PublicKey with + | None -> 0 + | Some (PublicKey b | PublicKeyToken b) -> GetBytesAsBlobIdx cenv b), + StringIndex (GetStringHeapIdx cenv aref.Name), + StringIndex (match aref.Locale with None -> 0 | Some s -> GetStringHeapIdx cenv s), + BlobIndex (match aref.Hash with None -> 0 | Some s -> GetBytesAsBlobIdx cenv s)) + +and GetAssemblyRefAsIdx cenv aref = + FindOrAddSharedRow cenv TableNames.AssemblyRef (GetAssemblyRefAsRow cenv (cenv.normalizeAssemblyRefs aref)) + +and GetModuleRefAsRow cenv (mref: ILModuleRef) = + SharedRow + [| StringE (GetStringHeapIdx cenv mref.Name) |] + +and GetModuleRefAsFileRow cenv (mref: ILModuleRef) = + SharedRow + [| ULong (if mref.HasMetadata then 0x0000 else 0x0001) + StringE (GetStringHeapIdx cenv mref.Name) + (match mref.Hash with None -> Blob 0 | Some s -> Blob (GetBytesAsBlobIdx cenv s)) |] + +and GetModuleRefAsIdx cenv mref = + FindOrAddSharedRow cenv TableNames.ModuleRef (GetModuleRefAsRow cenv mref) + +and GetModuleRefAsFileIdx cenv mref = + FindOrAddSharedRow cenv TableNames.File (GetModuleRefAsFileRow cenv mref) + +// -------------------------------------------------------------------- +// Does a ILScopeRef point to this module? +// -------------------------------------------------------------------- + +let isScopeRefLocal scoref = (scoref = ILScopeRef.Local) +let isTypeRefLocal (tref: ILTypeRef) = isScopeRefLocal tref.Scope +let isTypeLocal (ty: ILType) = ty.IsNominal && isNil ty.GenericArgs && isTypeRefLocal ty.TypeRef + +// -------------------------------------------------------------------- +// Scopes to Implementation elements. +// -------------------------------------------------------------------- + +let GetScopeRefAsImplementationElem cenv scoref = + match scoref with + | ILScopeRef.Local -> (i_AssemblyRef, 0) + | ILScopeRef.Assembly aref -> (i_AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (i_File, GetModuleRefAsFileIdx cenv mref) + | ILScopeRef.PrimaryAssembly -> (i_AssemblyRef, GetAssemblyRefAsIdx cenv cenv.ilg.primaryAssemblyRef) + +// -------------------------------------------------------------------- +// Type references, types etc. +// -------------------------------------------------------------------- + +let rec GetTypeRefAsTypeRefRow cenv (tref: ILTypeRef) = + let nselem, nelem = GetTypeNameAsElemPair cenv tref.Name + let rs1, rs2 = GetResolutionScopeAsElem cenv (tref.Scope, tref.Enclosing) + SharedRow [| ResolutionScope (rs1, rs2); nelem; nselem |] + +and GetTypeRefAsTypeRefIdx cenv tref = + match cenv.trefCache.TryGetValue tref with + | true, res -> res + | _ -> + let res = FindOrAddSharedRow cenv TableNames.TypeRef (GetTypeRefAsTypeRefRow cenv tref) + cenv.trefCache.[tref] <- res + res + +and GetTypeDescAsTypeRefIdx cenv (scoref, enc, n) = + GetTypeRefAsTypeRefIdx cenv (mkILNestedTyRef (scoref, enc, n)) + +and GetResolutionScopeAsElem cenv (scoref, enc) = + if isNil enc then + match scoref with + | ILScopeRef.Local -> (rs_Module, 1) + | ILScopeRef.Assembly aref -> (rs_AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (rs_ModuleRef, GetModuleRefAsIdx cenv mref) + | ILScopeRef.PrimaryAssembly -> (rs_AssemblyRef, GetAssemblyRefAsIdx cenv cenv.ilg.primaryAssemblyRef) + else + let enc2, n2 = List.frontAndBack enc + (rs_TypeRef, GetTypeDescAsTypeRefIdx cenv (scoref, enc2, n2)) + + +let emitTypeInfoAsTypeDefOrRefEncoded cenv (bb: ByteBuffer) (scoref, enc, nm) = + if isScopeRefLocal scoref then + let idx = GetIdxForTypeDef cenv (TdKey(enc, nm)) + bb.EmitZ32 (idx <<< 2) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeDef + else + let idx = GetTypeDescAsTypeRefIdx cenv (scoref, enc, nm) + bb.EmitZ32 ((idx <<< 2) ||| 0x01) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeRef + +let getTypeDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = tdor_TypeDef then TableNames.TypeDef + elif tag = tdor_TypeRef then TableNames.TypeRef + elif tag = tdor_TypeSpec then TableNames.TypeSpec + else failwith "getTypeDefOrRefAsUncodedToken" + getUncodedToken tab idx + +// REVIEW: write into an accumulating buffer +let EmitArrayShape (bb: ByteBuffer) (ILArrayShape shape) = + let sized = List.filter (function _, Some _ -> true | _ -> false) shape + let lobounded = List.filter (function Some _, _ -> true | _ -> false) shape + bb.EmitZ32 shape.Length + bb.EmitZ32 sized.Length + sized |> List.iter (function _, Some sz -> bb.EmitZ32 sz | _ -> failwith "?") + bb.EmitZ32 lobounded.Length + lobounded |> List.iter (function Some low, _ -> bb.EmitZ32 low | _ -> failwith "?") + +let hasthisToByte hasthis = + match hasthis with + | ILThisConvention.Instance -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE + | ILThisConvention.InstanceExplicit -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT + | ILThisConvention.Static -> 0x00uy + +let callconvToByte ntypars (Callconv (hasthis, bcc)) = + hasthisToByte hasthis ||| + (if ntypars > 0 then e_IMAGE_CEE_CS_CALLCONV_GENERIC else 0x00uy) ||| + (match bcc with + | ILArgConvention.FastCall -> e_IMAGE_CEE_CS_CALLCONV_FASTCALL + | ILArgConvention.StdCall -> e_IMAGE_CEE_CS_CALLCONV_STDCALL + | ILArgConvention.ThisCall -> e_IMAGE_CEE_CS_CALLCONV_THISCALL + | ILArgConvention.CDecl -> e_IMAGE_CEE_CS_CALLCONV_CDECL + | ILArgConvention.Default -> 0x00uy + | ILArgConvention.VarArg -> e_IMAGE_CEE_CS_CALLCONV_VARARG) + + +// REVIEW: write into an accumulating buffer +let rec EmitTypeSpec cenv env (bb: ByteBuffer) (et, tspec: ILTypeSpec) = + if isNil tspec.GenericArgs then + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Enclosing, tspec.Name) + else + bb.EmitByte et_WITH + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Enclosing, tspec.Name) + bb.EmitZ32 tspec.GenericArgs.Length + EmitTypes cenv env bb tspec.GenericArgs + +and GetTypeAsTypeDefOrRef cenv env (ty: ILType) = + if isTypeLocal ty then + let tref = ty.TypeRef + (tdor_TypeDef, GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name))) + elif ty.IsNominal && isNil ty.GenericArgs then + (tdor_TypeRef, GetTypeRefAsTypeRefIdx cenv ty.TypeRef) + else + (tdor_TypeSpec, GetTypeAsTypeSpecIdx cenv env ty) + +and GetTypeAsBytes cenv env ty = emitBytesViaBuffer (fun bb -> EmitType cenv env bb ty) + +and GetTypeOfLocalAsBytes cenv env (l: ILLocal) = + emitBytesViaBuffer (fun bb -> EmitLocalInfo cenv env bb l) + +and GetTypeAsBlobIdx cenv env (ty: ILType) = + GetBytesAsBlobIdx cenv (GetTypeAsBytes cenv env ty) + +and GetTypeAsTypeSpecRow cenv env (ty: ILType) = + SharedRow [| Blob (GetTypeAsBlobIdx cenv env ty) |] + +and GetTypeAsTypeSpecIdx cenv env ty = + FindOrAddSharedRow cenv TableNames.TypeSpec (GetTypeAsTypeSpecRow cenv env ty) + +and EmitType cenv env bb ty = + let ilg = cenv.ilg + match ty with + | ty when isILSByteTy ilg ty -> bb.EmitByte et_I1 + | ty when isILInt16Ty ilg ty -> bb.EmitByte et_I2 + | ty when isILInt32Ty ilg ty -> bb.EmitByte et_I4 + | ty when isILInt64Ty ilg ty -> bb.EmitByte et_I8 + | ty when isILByteTy ilg ty -> bb.EmitByte et_U1 + | ty when isILUInt16Ty ilg ty -> bb.EmitByte et_U2 + | ty when isILUInt32Ty ilg ty -> bb.EmitByte et_U4 + | ty when isILUInt64Ty ilg ty -> bb.EmitByte et_U8 + | ty when isILDoubleTy ilg ty -> bb.EmitByte et_R8 + | ty when isILSingleTy ilg ty -> bb.EmitByte et_R4 + | ty when isILBoolTy ilg ty -> bb.EmitByte et_BOOLEAN + | ty when isILCharTy ilg ty -> bb.EmitByte et_CHAR + | ty when isILStringTy ilg ty -> bb.EmitByte et_STRING + | ty when isILObjectTy ilg ty -> bb.EmitByte et_OBJECT + | ty when isILIntPtrTy ilg ty -> bb.EmitByte et_I + | ty when isILUIntPtrTy ilg ty -> bb.EmitByte et_U + | ty when isILTypedReferenceTy ilg ty -> bb.EmitByte et_TYPEDBYREF + + | ILType.Boxed tspec -> EmitTypeSpec cenv env bb (et_CLASS, tspec) + | ILType.Value tspec -> EmitTypeSpec cenv env bb (et_VALUETYPE, tspec) + | ILType.Array (shape, ty) -> + if shape = ILArrayShape.SingleDimensional then (bb.EmitByte et_SZARRAY ; EmitType cenv env bb ty) + else (bb.EmitByte et_ARRAY; EmitType cenv env bb ty; EmitArrayShape bb shape) + | ILType.TypeVar tv -> + let cgparams = env.EnclosingTyparCount + if int32 tv < cgparams then + bb.EmitByte et_VAR + bb.EmitZ32 (int32 tv) + else + bb.EmitByte et_MVAR + bb.EmitZ32 (int32 tv - cgparams) + + | ILType.Byref ty -> + bb.EmitByte et_BYREF + EmitType cenv env bb ty + | ILType.Ptr ty -> + bb.EmitByte et_PTR + EmitType cenv env bb ty + | ILType.Void -> + bb.EmitByte et_VOID + | ILType.FunctionPointer x -> + bb.EmitByte et_FNPTR + EmitCallsig cenv env bb (x.CallingConv, x.ArgTypes, x.ReturnType, None, 0) + | ILType.Modified (req, tref, ty) -> + bb.EmitByte (if req then et_CMOD_REQD else et_CMOD_OPT) + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tref.Scope, tref.Enclosing, tref.Name) + EmitType cenv env bb ty + | _ -> failwith "EmitType" + +and EmitLocalInfo cenv env (bb: ByteBuffer) (l: ILLocal) = + if l.IsPinned then + bb.EmitByte et_PINNED + EmitType cenv env bb l.Type + +and EmitCallsig cenv env bb (callconv, args: ILTypes, ret, varargs: ILVarArgs, genarity) = + bb.EmitByte (callconvToByte genarity callconv) + if genarity > 0 then bb.EmitZ32 genarity + bb.EmitZ32 (args.Length + (match varargs with None -> 0 | Some l -> l.Length)) + EmitType cenv env bb ret + args |> List.iter (EmitType cenv env bb) + match varargs with + | None -> ()// no extra arg = no sentinel + | Some tys -> + if isNil tys then () // no extra arg = no sentinel + else + bb.EmitByte et_SENTINEL + List.iter (EmitType cenv env bb) tys + +and GetCallsigAsBytes cenv env x = emitBytesViaBuffer (fun bb -> EmitCallsig cenv env bb x) + +// REVIEW: write into an accumulating buffer +and EmitTypes cenv env bb (inst: ILTypes) = + inst |> List.iter (EmitType cenv env bb) + +let GetTypeAsMemberRefParent cenv env ty = + match GetTypeAsTypeDefOrRef cenv env ty with + | tag, _ when tag = tdor_TypeDef -> dprintn "GetTypeAsMemberRefParent: mspec should have been encoded as mdtMethodDef?"; MemberRefParent (mrp_TypeRef, 1) + | tag, tok when tag = tdor_TypeRef -> MemberRefParent (mrp_TypeRef, tok) + | tag, tok when tag = tdor_TypeSpec -> MemberRefParent (mrp_TypeSpec, tok) + | _ -> failwith "GetTypeAsMemberRefParent" + + +// -------------------------------------------------------------------- +// Native types +// -------------------------------------------------------------------- + +let rec GetVariantTypeAsInt32 ty = + if List.memAssoc ty (Lazy.force ILVariantTypeMap) then + (List.assoc ty (Lazy.force ILVariantTypeMap )) + else + match ty with + | ILNativeVariant.Array vt -> vt_ARRAY ||| GetVariantTypeAsInt32 vt + | ILNativeVariant.Vector vt -> vt_VECTOR ||| GetVariantTypeAsInt32 vt + | ILNativeVariant.Byref vt -> vt_BYREF ||| GetVariantTypeAsInt32 vt + | _ -> failwith "Unexpected variant type" + +// based on information in ECMA and asmparse.y in the CLR codebase +let rec GetNativeTypeAsBlobIdx cenv (ty: ILNativeType) = + GetBytesAsBlobIdx cenv (GetNativeTypeAsBytes ty) + +and GetNativeTypeAsBytes ty = emitBytesViaBuffer (fun bb -> EmitNativeType bb ty) + +// REVIEW: write into an accumulating buffer +and EmitNativeType bb ty = + if List.memAssoc ty (Lazy.force ILNativeTypeRevMap) then + bb.EmitByte (List.assoc ty (Lazy.force ILNativeTypeRevMap)) + else + match ty with + | ILNativeType.Empty -> () + | ILNativeType.Custom (guid, nativeTypeName, custMarshallerName, cookieString) -> + let u1 = System.Text.Encoding.UTF8.GetBytes nativeTypeName + let u2 = System.Text.Encoding.UTF8.GetBytes custMarshallerName + let u3 = cookieString + bb.EmitByte nt_CUSTOMMARSHALER + bb.EmitZ32 guid.Length + bb.EmitBytes guid + bb.EmitZ32 u1.Length; bb.EmitBytes u1 + bb.EmitZ32 u2.Length; bb.EmitBytes u2 + bb.EmitZ32 u3.Length; bb.EmitBytes u3 + | ILNativeType.FixedSysString i -> + bb.EmitByte nt_FIXEDSYSSTRING + bb.EmitZ32 i + + | ILNativeType.FixedArray i -> + bb.EmitByte nt_FIXEDARRAY + bb.EmitZ32 i + | (* COM interop *) ILNativeType.SafeArray (vt, name) -> + bb.EmitByte nt_SAFEARRAY + bb.EmitZ32 (GetVariantTypeAsInt32 vt) + match name with + | None -> () + | Some n -> + let u1 = Bytes.stringAsUtf8NullTerminated n + bb.EmitZ32 (Array.length u1) ; bb.EmitBytes u1 + | ILNativeType.Array (nt, sizeinfo) -> (* REVIEW: check if this corresponds to the ECMA spec *) + bb.EmitByte nt_ARRAY + match nt with + | None -> bb.EmitZ32 (int nt_MAX) + | Some ntt -> + (if ntt = ILNativeType.Empty then + bb.EmitZ32 (int nt_MAX) + else + EmitNativeType bb ntt) + match sizeinfo with + | None -> () // chunk out with zeroes because some tools (e.g. asmmeta) read these poorly and expect further elements. + | Some (pnum, additive) -> + // ParamNum + bb.EmitZ32 pnum + (* ElemMul *) (* z_u32 0x1l *) + match additive with + | None -> () + | Some n -> (* NumElem *) bb.EmitZ32 n + | _ -> failwith "Unexpected native type" + +// -------------------------------------------------------------------- +// Native types +// -------------------------------------------------------------------- + +let rec GetFieldInitAsBlobIdx cenv (x: ILFieldInit) = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> GetFieldInit bb x)) + +// REVIEW: write into an accumulating buffer +and GetFieldInit (bb: ByteBuffer) x = + match x with + | ILFieldInit.String b -> bb.EmitBytes (System.Text.Encoding.Unicode.GetBytes b) + | ILFieldInit.Bool b -> bb.EmitByte (if b then 0x01uy else 0x00uy) + | ILFieldInit.Char x -> bb.EmitUInt16 x + | ILFieldInit.Int8 x -> bb.EmitByte (byte x) + | ILFieldInit.Int16 x -> bb.EmitUInt16 (uint16 x) + | ILFieldInit.Int32 x -> bb.EmitInt32 x + | ILFieldInit.Int64 x -> bb.EmitInt64 x + | ILFieldInit.UInt8 x -> bb.EmitByte x + | ILFieldInit.UInt16 x -> bb.EmitUInt16 x + | ILFieldInit.UInt32 x -> bb.EmitInt32 (int32 x) + | ILFieldInit.UInt64 x -> bb.EmitInt64 (int64 x) + | ILFieldInit.Single x -> bb.EmitInt32 (bitsOfSingle x) + | ILFieldInit.Double x -> bb.EmitInt64 (bitsOfDouble x) + | ILFieldInit.Null -> bb.EmitInt32 0 + +and GetFieldInitFlags i = + UShort + (uint16 + (match i with + | ILFieldInit.String _ -> et_STRING + | ILFieldInit.Bool _ -> et_BOOLEAN + | ILFieldInit.Char _ -> et_CHAR + | ILFieldInit.Int8 _ -> et_I1 + | ILFieldInit.Int16 _ -> et_I2 + | ILFieldInit.Int32 _ -> et_I4 + | ILFieldInit.Int64 _ -> et_I8 + | ILFieldInit.UInt8 _ -> et_U1 + | ILFieldInit.UInt16 _ -> et_U2 + | ILFieldInit.UInt32 _ -> et_U4 + | ILFieldInit.UInt64 _ -> et_U8 + | ILFieldInit.Single _ -> et_R4 + | ILFieldInit.Double _ -> et_R8 + | ILFieldInit.Null -> et_CLASS)) + +// -------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------- + +let GetMemberAccessFlags access = + match access with + | ILMemberAccess.Public -> 0x00000006 + | ILMemberAccess.Private -> 0x00000001 + | ILMemberAccess.Family -> 0x00000004 + | ILMemberAccess.CompilerControlled -> 0x00000000 + | ILMemberAccess.FamilyAndAssembly -> 0x00000002 + | ILMemberAccess.FamilyOrAssembly -> 0x00000005 + | ILMemberAccess.Assembly -> 0x00000003 + +let GetTypeAccessFlags access = + match access with + | ILTypeDefAccess.Public -> 0x00000001 + | ILTypeDefAccess.Private -> 0x00000000 + | ILTypeDefAccess.Nested ILMemberAccess.Public -> 0x00000002 + | ILTypeDefAccess.Nested ILMemberAccess.Private -> 0x00000003 + | ILTypeDefAccess.Nested ILMemberAccess.Family -> 0x00000004 + | ILTypeDefAccess.Nested ILMemberAccess.CompilerControlled -> failwith "bad type access" + | ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly -> 0x00000006 + | ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> 0x00000007 + | ILTypeDefAccess.Nested ILMemberAccess.Assembly -> 0x00000005 + +let rec GetTypeDefAsRow cenv env _enc (td: ILTypeDef) = + let nselem, nelem = GetTypeNameAsElemPair cenv td.Name + let flags = + if (isTypeNameForGlobalFunctions td.Name) then 0x00000000 + else + int td.Attributes + + let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env td.Extends + UnsharedRow + [| ULong flags + nelem + nselem + TypeDefOrRefOrSpec (tdorTag, tdorRow) + SimpleIndex (TableNames.Field, cenv.fieldDefs.Count + 1) + SimpleIndex (TableNames.Method, cenv.methodDefIdxsByKey.Count + 1) |] + +and GetTypeOptionAsTypeDefOrRef cenv env tyOpt = + match tyOpt with + | None -> (tdor_TypeDef, 0) + | Some ty -> (GetTypeAsTypeDefOrRef cenv env ty) + +and GetTypeDefAsPropertyMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (TableNames.TypeDef, tidx) + SimpleIndex (TableNames.Property, cenv.propertyDefs.Count + 1) |] + +and GetTypeDefAsEventMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (TableNames.TypeDef, tidx) + SimpleIndex (TableNames.Event, cenv.eventDefs.Count + 1) |] + +and GetKeyForFieldDef tidx (fd: ILFieldDef) = + FieldDefKey (tidx, fd.Name, fd.FieldType) + +and GenFieldDefPass2 cenv tidx fd = + ignore (cenv.fieldDefs.AddUniqueEntry "field" (fun (fdkey: FieldDefKey) -> fdkey.Name) (GetKeyForFieldDef tidx fd)) + +and GetKeyForMethodDef cenv tidx (md: ILMethodDef) = + MethodDefKey (cenv.ilg, tidx, md.GenericParams.Length, md.Name, md.Return.Type, md.ParameterTypes, md.CallingConv.IsStatic) + +and GenMethodDefPass2 cenv tidx md = + let idx = + cenv.methodDefIdxsByKey.AddUniqueEntry + "method" + (fun (key: MethodDefKey) -> + dprintn "Duplicate in method table is:" + dprintn (" Type index: "+string key.TypeIdx) + dprintn (" Method name: "+key.Name) + dprintn (" Method arity (num generic params): "+string key.GenericArity) + key.Name + ) + (GetKeyForMethodDef cenv tidx md) + + cenv.methodDefIdxs.[md] <- idx + +and GetKeyForPropertyDef tidx (x: ILPropertyDef) = + PropKey (tidx, x.Name, x.PropertyType, x.Args) + +and GenPropertyDefPass2 cenv tidx x = + ignore (cenv.propertyDefs.AddUniqueEntry "property" (fun (PropKey (_, n, _, _)) -> n) (GetKeyForPropertyDef tidx x)) + +and GetTypeAsImplementsRow cenv env tidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (TableNames.TypeDef, tidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + +and GenImplementsPass2 cenv env tidx ty = + AddUnsharedRow cenv TableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) |> ignore + +and GetKeyForEvent tidx (x: ILEventDef) = + EventKey (tidx, x.Name) + +and GenEventDefPass2 cenv tidx x = + ignore (cenv.eventDefs.AddUniqueEntry "event" (fun (EventKey(_, b)) -> b) (GetKeyForEvent tidx x)) + +and GenTypeDefPass2 pidx enc cenv (td: ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) + let tidx2 = AddUnsharedRow cenv TableNames.TypeDef (GetTypeDefAsRow cenv env enc td) + if tidx <> tidx2 then failwith "index of typedef on second pass does not match index on first pass" + + // Add entries to auxiliary mapping tables, e.g. Nested, PropertyMap etc. + // Note Nested is organised differently to the others... + if not (isNil enc) then + AddUnsharedRow cenv TableNames.Nested + (UnsharedRow + [| SimpleIndex (TableNames.TypeDef, tidx) + SimpleIndex (TableNames.TypeDef, pidx) |]) |> ignore + let props = td.Properties.AsList + if not (isNil props) then + AddUnsharedRow cenv TableNames.PropertyMap (GetTypeDefAsPropertyMapRow cenv tidx) |> ignore + let events = td.Events.AsList + if not (isNil events) then + AddUnsharedRow cenv TableNames.EventMap (GetTypeDefAsEventMapRow cenv tidx) |> ignore + + // Now generate or assign index numbers for tables referenced by the maps. + // Don't yet generate contents of these tables - leave that to pass3, as + // code may need to embed these entries. + td.Implements |> List.iter (GenImplementsPass2 cenv env tidx) + props |> List.iter (GenPropertyDefPass2 cenv tidx) + events |> List.iter (GenEventDefPass2 cenv tidx) + td.Fields.AsList |> List.iter (GenFieldDefPass2 cenv tidx) + td.Methods |> Seq.iter (GenMethodDefPass2 cenv tidx) + td.NestedTypes.AsList |> GenTypeDefsPass2 tidx (enc@[td.Name]) cenv + with e -> + failwith ("Error in pass2 for type "+td.Name+", error: "+e.Message) + +and GenTypeDefsPass2 pidx enc cenv tds = + List.iter (GenTypeDefPass2 pidx enc cenv) tds + +//===================================================================== +// Pass 3 - write details of methods, fields, IL code, custom attrs etc. +//===================================================================== + +exception MethodDefNotFound +let FindMethodDefIdx cenv mdkey = + try cenv.methodDefIdxsByKey.GetTableEntry mdkey + with :? KeyNotFoundException -> + let typeNameOfIdx i = + match + (cenv.typeDefs.dict + |> Seq.fold (fun sofar kvp -> + let tkey2 = kvp.Key + let tidx2 = kvp.Value + if i = tidx2 then + if sofar = None then + Some tkey2 + else failwith "multiple type names map to index" + else sofar) None) with + | Some x -> x + | None -> raise MethodDefNotFound + let (TdKey (tenc, tname)) = typeNameOfIdx mdkey.TypeIdx + dprintn ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") + dprintn ("generic arity: "+string mdkey.GenericArity) + cenv.methodDefIdxsByKey.dict |> Seq.iter (fun (KeyValue(mdkey2, _)) -> + if mdkey2.TypeIdx = mdkey.TypeIdx && mdkey.Name = mdkey2.Name then + let (TdKey (tenc2, tname2)) = typeNameOfIdx mdkey2.TypeIdx + dprintn ("A method in '"+(String.concat "." (tenc2@[tname2]))+"' had the right name but the wrong signature:") + dprintn ("generic arity: "+string mdkey2.GenericArity) + dprintn (sprintf "mdkey2: %+A" mdkey2)) + raise MethodDefNotFound + + +let rec GetMethodDefIdx cenv md = + cenv.methodDefIdxs.[md] + +and FindFieldDefIdx cenv fdkey = + try cenv.fieldDefs.GetTableEntry fdkey + with :? KeyNotFoundException -> + errorR(InternalError("The local field "+fdkey.Name+" was referenced but not declared", range0)) + 1 + +and GetFieldDefAsFieldDefIdx cenv tidx fd = + FindFieldDefIdx cenv (GetKeyForFieldDef tidx fd) + +// -------------------------------------------------------------------- +// ILMethodRef --> ILMethodDef. +// +// Only successfully converts ILMethodRef's referring to +// methods in the module being emitted. +// -------------------------------------------------------------------- + +let GetMethodRefAsMethodDefIdx cenv (mref: ILMethodRef) = + let tref = mref.DeclaringTypeRef + try + if not (isTypeRefLocal tref) then + failwithf "method referred to by method impl, event or property is not in a type defined in this module, method ref is %A" mref + let tidx = GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name)) + let mdkey = MethodDefKey (cenv.ilg, tidx, mref.GenericArity, mref.Name, mref.ReturnType, mref.ArgTypes, mref.CallingConv.IsStatic) + FindMethodDefIdx cenv mdkey + with e -> + failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" (mref.Name, tref.Name) e.Message + +let rec MethodRefInfoAsMemberRefRow cenv env fenv (nm, ty, callconv, args, ret, varargs, genarity) = + MemberRefRow(GetTypeAsMemberRefParent cenv env ty, + GetStringHeapIdx cenv nm, + GetMethodRefInfoAsBlobIdx cenv fenv (callconv, args, ret, varargs, genarity)) + +and GetMethodRefInfoAsBlobIdx cenv env info = + GetBytesAsBlobIdx cenv (GetCallsigAsBytes cenv env info) + +let GetMethodRefInfoAsMemberRefIdx cenv env (_, ty, _, _, _, _, _ as minfo) = + let fenv = envForMethodRef env ty + FindOrAddSharedRow cenv TableNames.MemberRef (MethodRefInfoAsMemberRefRow cenv env fenv minfo) + +let GetMethodRefInfoAsMethodRefOrDef isAlwaysMethodDef cenv env (nm, ty: ILType, cc, args, ret, varargs, genarity as minfo) = + if Option.isNone varargs && (isAlwaysMethodDef || isTypeLocal ty) then + if not ty.IsNominal then failwith "GetMethodRefInfoAsMethodRefOrDef: unexpected local tref-ty" + try (mdor_MethodDef, GetMethodRefAsMethodDefIdx cenv (mkILMethRef (ty.TypeRef, cc, nm, genarity, args, ret))) + with MethodDefNotFound -> (mdor_MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + else (mdor_MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + + +// -------------------------------------------------------------------- +// ILMethodSpec --> ILMethodRef/ILMethodDef/ILMethodSpec +// -------------------------------------------------------------------- + +let rec GetMethodSpecInfoAsMethodSpecIdx cenv env (nm, ty, cc, args, ret, varargs, minst: ILGenericArgs) = + let mdorTag, mdorRow = GetMethodRefInfoAsMethodRefOrDef false cenv env (nm, ty, cc, args, ret, varargs, minst.Length) + let blob = + emitBytesViaBuffer (fun bb -> + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_GENERICINST + bb.EmitZ32 minst.Length + minst |> List.iter (EmitType cenv env bb)) + FindOrAddSharedRow cenv TableNames.MethodSpec + (SharedRow + [| MethodDefOrRef (mdorTag, mdorRow) + Blob (GetBytesAsBlobIdx cenv blob) |]) + +and GetMethodDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = mdor_MethodDef then TableNames.Method + elif tag = mdor_MemberRef then TableNames.MemberRef + else failwith "GetMethodDefOrRefAsUncodedToken" + getUncodedToken tab idx + +and GetMethodSpecInfoAsUncodedToken cenv env (_, _, _, _, _, _, minst: ILGenericArgs as minfo) = + if List.isEmpty minst then + GetMethodDefOrRefAsUncodedToken (GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo minfo)) + else + getUncodedToken TableNames.MethodSpec (GetMethodSpecInfoAsMethodSpecIdx cenv env minfo) + +and GetMethodSpecAsUncodedToken cenv env mspec = + GetMethodSpecInfoAsUncodedToken cenv env (InfoOfMethodSpec mspec) + +and GetMethodRefInfoOfMethodSpecInfo (nm, ty, cc, args, ret, varargs, minst: ILGenericArgs) = + (nm, ty, cc, args, ret, varargs, minst.Length) + +and GetMethodSpecAsMethodDefOrRef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + +and GetMethodSpecAsMethodDef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef true cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + +and InfoOfMethodSpec (mspec: ILMethodSpec, varargs) = + (mspec.Name, + mspec.DeclaringType, + mspec.CallingConv, + mspec.FormalArgTypes, + mspec.FormalReturnType, + varargs, + mspec.GenericArgs) + +// -------------------------------------------------------------------- +// method_in_parent --> ILMethodRef/ILMethodDef +// +// Used for MethodImpls. +// -------------------------------------------------------------------- + +let rec GetOverridesSpecAsMemberRefIdx cenv env ospec = + let fenv = envForOverrideSpec ospec + let row = MethodRefInfoAsMemberRefRow cenv env fenv (ospec.MethodRef.Name, ospec.DeclaringType, ospec.MethodRef.CallingConv, ospec.MethodRef.ArgTypes, ospec.MethodRef.ReturnType, None, ospec.MethodRef.GenericArity) + FindOrAddSharedRow cenv TableNames.MemberRef row + +and GetOverridesSpecAsMethodDefOrRef cenv env (ospec: ILOverridesSpec) = + let ty = ospec.DeclaringType + if isTypeLocal ty then + if not ty.IsNominal then failwith "GetOverridesSpecAsMethodDefOrRef: unexpected local tref-ty" + try (mdor_MethodDef, GetMethodRefAsMethodDefIdx cenv ospec.MethodRef) + with MethodDefNotFound -> (mdor_MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + else + (mdor_MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + +// -------------------------------------------------------------------- +// ILMethodRef --> ILMethodRef/ILMethodDef +// +// Used for Custom Attrs. +// -------------------------------------------------------------------- + +let rec GetMethodRefAsMemberRefIdx cenv env fenv (mref: ILMethodRef) = + let row = MethodRefInfoAsMemberRefRow cenv env fenv (mref.Name, mkILNonGenericBoxedTy mref.DeclaringTypeRef, mref.CallingConv, mref.ArgTypes, mref.ReturnType, None, mref.GenericArity) + FindOrAddSharedRow cenv TableNames.MemberRef row + +and GetMethodRefAsCustomAttribType cenv (mref: ILMethodRef) = + let fenv = envForNonGenericMethodRef mref + let tref = mref.DeclaringTypeRef + if isTypeRefLocal tref then + try (cat_MethodDef, GetMethodRefAsMethodDefIdx cenv mref) + with MethodDefNotFound -> (cat_MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + else + (cat_MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + +// -------------------------------------------------------------------- +// ILAttributes --> CustomAttribute rows +// -------------------------------------------------------------------- + +let rec GetCustomAttrDataAsBlobIdx cenv (data: byte[]) = + if data.Length = 0 then 0 else GetBytesAsBlobIdx cenv data + +and GetCustomAttrRow cenv hca (attr: ILAttribute) = + let cat = GetMethodRefAsCustomAttribType cenv attr.Method.MethodRef + let data = getCustomAttrData attr + for element in attr.Elements do + match element with + | ILAttribElem.Type (Some ty) when ty.IsNominal -> GetTypeRefAsTypeRefIdx cenv ty.TypeRef |> ignore + | ILAttribElem.TypeRef (Some tref) -> GetTypeRefAsTypeRefIdx cenv tref |> ignore + | _ -> () + + UnsharedRow + [| HasCustomAttribute (fst hca, snd hca) + CustomAttributeType (fst cat, snd cat) + Blob (GetCustomAttrDataAsBlobIdx cenv data) + |] + +and GenCustomAttrPass3Or4 cenv hca attr = + AddUnsharedRow cenv TableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore + +and GenCustomAttrsPass3Or4 cenv hca (attrs: ILAttributes) = + attrs.AsArray |> Array.iter (GenCustomAttrPass3Or4 cenv hca) + +// -------------------------------------------------------------------- +// ILSecurityDecl --> DeclSecurity rows +// -------------------------------------------------------------------- *) + +let rec GetSecurityDeclRow cenv hds (ILSecurityDecl (action, s)) = + UnsharedRow + [| UShort (uint16 (List.assoc action (Lazy.force ILSecurityActionMap))) + HasDeclSecurity (fst hds, snd hds) + Blob (GetBytesAsBlobIdx cenv s) |] + +and GenSecurityDeclPass3 cenv hds attr = + AddUnsharedRow cenv TableNames.Permission (GetSecurityDeclRow cenv hds attr) |> ignore + +and GenSecurityDeclsPass3 cenv hds attrs = + List.iter (GenSecurityDeclPass3 cenv hds) attrs + +// -------------------------------------------------------------------- +// ILFieldSpec --> FieldRef or ILFieldDef row +// -------------------------------------------------------------------- + +let rec GetFieldSpecAsMemberRefRow cenv env fenv (fspec: ILFieldSpec) = + MemberRefRow (GetTypeAsMemberRefParent cenv env fspec.DeclaringType, + GetStringHeapIdx cenv fspec.Name, + GetFieldSpecSigAsBlobIdx cenv fenv fspec) + +and GetFieldSpecAsMemberRefIdx cenv env fspec = + let fenv = envForFieldSpec fspec + FindOrAddSharedRow cenv TableNames.MemberRef (GetFieldSpecAsMemberRefRow cenv env fenv fspec) + +// REVIEW: write into an accumulating buffer +and EmitFieldSpecSig cenv env (bb: ByteBuffer) (fspec: ILFieldSpec) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb fspec.FormalType + +and GetFieldSpecSigAsBytes cenv env x = + emitBytesViaBuffer (fun bb -> EmitFieldSpecSig cenv env bb x) + +and GetFieldSpecSigAsBlobIdx cenv env x = + GetBytesAsBlobIdx cenv (GetFieldSpecSigAsBytes cenv env x) + +and GetFieldSpecAsFieldDefOrRef cenv env (fspec: ILFieldSpec) = + let ty = fspec.DeclaringType + if isTypeLocal ty then + if not ty.IsNominal then failwith "GetFieldSpecAsFieldDefOrRef: unexpected local tref-ty" + let tref = ty.TypeRef + let tidx = GetIdxForTypeDef cenv (TdKey(tref.Enclosing, tref.Name)) + let fdkey = FieldDefKey (tidx, fspec.Name, fspec.FormalType) + (true, FindFieldDefIdx cenv fdkey) + else + (false, GetFieldSpecAsMemberRefIdx cenv env fspec) + +and GetFieldDefOrRefAsUncodedToken (tag, idx) = + let tab = if tag then TableNames.Field else TableNames.MemberRef + getUncodedToken tab idx + +// -------------------------------------------------------------------- +// callsig --> StandAloneSig +// -------------------------------------------------------------------- + +let GetCallsigAsBlobIdx cenv env (callsig: ILCallingSignature, varargs) = + GetBytesAsBlobIdx cenv + (GetCallsigAsBytes cenv env (callsig.CallingConv, + callsig.ArgTypes, + callsig.ReturnType, varargs, 0)) + +let GetCallsigAsStandAloneSigRow cenv env x = + SharedRow [| Blob (GetCallsigAsBlobIdx cenv env x) |] + +let GetCallsigAsStandAloneSigIdx cenv env info = + FindOrAddSharedRow cenv TableNames.StandAloneSig (GetCallsigAsStandAloneSigRow cenv env info) + +// -------------------------------------------------------------------- +// local signatures --> BlobHeap idx +// -------------------------------------------------------------------- + +let EmitLocalSig cenv env (bb: ByteBuffer) (locals: ILLocals) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG + bb.EmitZ32 locals.Length + locals |> List.iter (EmitLocalInfo cenv env bb) + +let GetLocalSigAsBlobHeapIdx cenv env locals = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> EmitLocalSig cenv env bb locals)) + +let GetLocalSigAsStandAloneSigIdx cenv env locals = + SharedRow [| Blob (GetLocalSigAsBlobHeapIdx cenv env locals) |] + + + +type ExceptionClauseKind = + | FinallyClause + | FaultClause + | TypeFilterClause of int32 + | FilterClause of int + +type ExceptionClauseSpec = int * int * int * int * ExceptionClauseKind + +/// Arbitrary value +[] +let CodeBufferCapacity = 200 + +type CodeBuffer = + + // -------------------------------------------------------------------- + // Buffer to write results of emitting code into. Also record: + // - branch sources (where fixups will occur) + // - possible branch destinations + // - locations of embedded handles into the string table + // - the exception table + // -------------------------------------------------------------------- + { code: ByteBuffer + /// (instruction; optional short form); start of instr in code buffer; code loc for the end of the instruction the fixup resides in ; where is the destination of the fixup + mutable reqdBrFixups: ((int * int option) * int * ILCodeLabel list) list + availBrFixups: Dictionary + /// code loc to fixup in code buffer + mutable reqdStringFixupsInMethod: (int * int) list + /// data for exception handling clauses + mutable seh: ExceptionClauseSpec list + seqpoints: ResizeArray } + + interface IDisposable with + member this.Dispose() = + (this.code :> IDisposable).Dispose() + + static member Create _nm = + { seh = [] + code= ByteBuffer.Create CodeBufferCapacity + reqdBrFixups=[] + reqdStringFixupsInMethod=[] + availBrFixups = Dictionary<_, _>(10, HashIdentity.Structural) + seqpoints = ResizeArray<_>(10) + } + + member codebuf.EmitExceptionClause seh = codebuf.seh <- seh :: codebuf.seh + + member codebuf.EmitSeqPoint cenv (m: ILDebugPoint) = + if cenv.generatePdb then + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + codebuf.seqpoints.Add + { Document=doc + Offset= codebuf.code.Position + Line=m.Line + Column=m.Column + EndLine=m.EndLine + EndColumn=m.EndColumn } + + member codebuf.EmitByte x = codebuf.code.EmitIntAsByte x + member codebuf.EmitUInt16 x = codebuf.code.EmitUInt16 x + member codebuf.EmitInt32 x = codebuf.code.EmitInt32 x + member codebuf.EmitInt64 x = codebuf.code.EmitInt64 x + + member codebuf.EmitUncodedToken u = codebuf.EmitInt32 u + + member codebuf.RecordReqdStringFixup stringIdx = + codebuf.reqdStringFixupsInMethod <- (codebuf.code.Position, stringIdx) :: codebuf.reqdStringFixupsInMethod + // Write a special value in that we check later when applying the fixup + codebuf.EmitInt32 0xdeadbeef + + member codebuf.RecordReqdBrFixups i tgs = + codebuf.reqdBrFixups <- (i, codebuf.code.Position, tgs) :: codebuf.reqdBrFixups + // Write a special value in that we check later when applying the fixup + // Value is 0x11 {deadbbbb}* where 11 is for the instruction and deadbbbb is for each target + codebuf.EmitByte 0x11 // for the instruction + (if fst i = i_switch then + codebuf.EmitInt32 tgs.Length) + List.iter (fun _ -> codebuf.EmitInt32 0xdeadbbbb) tgs + + member codebuf.RecordReqdBrFixup i tg = codebuf.RecordReqdBrFixups i [tg] + member codebuf.RecordAvailBrFixup tg = + codebuf.availBrFixups.[tg] <- codebuf.code.Position + +module Codebuf = + // -------------------------------------------------------------------- + // Applying branch fixups. Use short versions of instructions + // wherever possible. Sadly we can only determine if we can use a short + // version after we've layed out the code for all other instructions. + // This in turn means that using a short version may change + // the various offsets into the code. + // -------------------------------------------------------------------- + + let binaryChop p (arr: 'T[]) = + let rec go n m = + if n > m then raise (KeyNotFoundException("binary chop did not find element")) + else + let i = (n+m)/2 + let c = p arr.[i] + if c = 0 then i elif c < 0 then go n (i-1) else go (i+1) m + go 0 (Array.length arr) + + let applyBrFixups (origCode : byte[]) origExnClauses origReqdStringFixups (origAvailBrFixups: Dictionary) origReqdBrFixups origSeqPoints origScopes = + let orderedOrigReqdBrFixups = origReqdBrFixups |> List.sortBy (fun (_, fixupLoc, _) -> fixupLoc) + + use newCode = ByteBuffer.Create origCode.Length + + // Copy over all the code, working out whether the branches will be short + // or long and adjusting the branch destinations. Record an adjust function to adjust all the other + // gumpf that refers to fixed offsets in the code stream. + let newCode, newReqdBrFixups, adjuster = + let mutable remainingReqdFixups = orderedOrigReqdBrFixups + let mutable origWhere = 0 + let mutable newWhere = 0 + let mutable doneLast = false + let mutable newReqdBrFixups = [] + let mutable adjustments = [] + + while (remainingReqdFixups <> [] || not doneLast) do + let doingLast = isNil remainingReqdFixups + let origStartOfNoBranchBlock = origWhere + let newStartOfNoBranchBlock = newWhere + + let origEndOfNoBranchBlock = + if doingLast then origCode.Length + else + let _, origStartOfInstr, _ = List.head remainingReqdFixups + origStartOfInstr + + // Copy over a chunk of non-branching code + let nobranch_len = origEndOfNoBranchBlock - origStartOfNoBranchBlock + newCode.EmitBytes origCode.[origStartOfNoBranchBlock..origStartOfNoBranchBlock+nobranch_len-1] + + // Record how to adjust addresses in this range, including the branch instruction + // we write below, or the end of the method if we're doing the last bblock + adjustments <- (origStartOfNoBranchBlock, origEndOfNoBranchBlock, newStartOfNoBranchBlock) :: adjustments + + // Increment locations to the branch instruction we're really interested in + origWhere <- origEndOfNoBranchBlock + newWhere <- newWhere + nobranch_len + + // Now do the branch instruction. Decide whether the fixup will be short or long in the new code + if doingLast then + doneLast <- true + else + let (i, origStartOfInstr, tgs: ILCodeLabel list) = List.head remainingReqdFixups + remainingReqdFixups <-List.tail remainingReqdFixups + if origCode.[origStartOfInstr] <> 0x11uy then failwith "br fixup sanity check failed (1)" + let i_length = if fst i = i_switch then 5 else 1 + origWhere <- origWhere + i_length + + let origEndOfInstr = origStartOfInstr + i_length + 4 * tgs.Length + let newEndOfInstrIfSmall = newWhere + i_length + 1 + let newEndOfInstrIfBig = newWhere + i_length + 4 * tgs.Length + + let short = + match i, tgs with + | (_, Some i_short), [tg] + when + // Use the original offsets to compute if the branch is small or large. This is + // a safe approximation because code only gets smaller. + (let origDest = + match origAvailBrFixups.TryGetValue tg with + | true, fixup -> fixup + | _ -> + dprintn ("branch target " + formatCodeLabel tg + " not found in code") + 666666 + let origRelOffset = origDest - origEndOfInstr + -128 <= origRelOffset && origRelOffset <= 127) + -> + newCode.EmitIntAsByte i_short + true + | (i_long, _), _ -> + newCode.EmitIntAsByte i_long + (if i_long = i_switch then + newCode.EmitInt32 tgs.Length) + false + + newWhere <- newWhere + i_length + if newWhere <> newCode.Position then dprintn "mismatch between newWhere and newCode" + + tgs |> List.iter (fun tg -> + let origFixupLoc = origWhere + checkFixup32 origCode origFixupLoc 0xdeadbbbb + + if short then + newReqdBrFixups <- (newWhere, newEndOfInstrIfSmall, tg, true) :: newReqdBrFixups + newCode.EmitIntAsByte 0x98 (* sanity check *) + newWhere <- newWhere + 1 + else + newReqdBrFixups <- (newWhere, newEndOfInstrIfBig, tg, false) :: newReqdBrFixups + newCode.EmitInt32 0xf00dd00f (* sanity check *) + newWhere <- newWhere + 4 + if newWhere <> newCode.Position then dprintn "mismatch between newWhere and newCode" + origWhere <- origWhere + 4) + + if origWhere <> origEndOfInstr then dprintn "mismatch between origWhere and origEndOfInstr" + + let adjuster = + let arr = Array.ofList (List.rev adjustments) + fun addr -> + let i = + try binaryChop (fun (a1, a2, _) -> if addr < a1 then -1 elif addr > a2 then 1 else 0) arr + with + :? KeyNotFoundException -> + failwith ("adjuster: address "+string addr+" is out of range") + let origStartOfNoBranchBlock, _, newStartOfNoBranchBlock = arr.[i] + addr - (origStartOfNoBranchBlock - newStartOfNoBranchBlock) + + newCode.AsMemory().ToArray(), + newReqdBrFixups, + adjuster + + // Now adjust everything + let newAvailBrFixups = + let tab = Dictionary<_, _>(10, HashIdentity.Structural) + for KeyValue(tglab, origBrDest) in origAvailBrFixups do + tab.[tglab] <- adjuster origBrDest + tab + let newReqdStringFixups = List.map (fun (origFixupLoc, stok) -> adjuster origFixupLoc, stok) origReqdStringFixups + let newSeqPoints = Array.map (fun (sp: PdbDebugPoint) -> {sp with Offset=adjuster sp.Offset}) origSeqPoints + let newExnClauses = + origExnClauses |> List.map (fun (st1, sz1, st2, sz2, kind) -> + (adjuster st1, (adjuster (st1 + sz1) - adjuster st1), + adjuster st2, (adjuster (st2 + sz2) - adjuster st2), + (match kind with + | FinallyClause | FaultClause | TypeFilterClause _ -> kind + | FilterClause n -> FilterClause (adjuster n)))) + + let newScopes = + let rec remap scope = + {scope with StartOffset = adjuster scope.StartOffset + EndOffset = adjuster scope.EndOffset + Children = Array.map remap scope.Children } + List.map remap origScopes + + // Now apply the adjusted fixups in the new code + newReqdBrFixups |> List.iter (fun (newFixupLoc, endOfInstr, tg, small) -> + match newAvailBrFixups.TryGetValue tg with + | true, n -> + let relOffset = n - endOfInstr + if small then + if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixup sanity check failed" + newCode.[newFixupLoc] <- b0 relOffset + else + checkFixup32 newCode newFixupLoc 0xf00dd00fl + applyFixup32 newCode newFixupLoc relOffset + | _ -> failwith ("target " + formatCodeLabel tg + " not found in new fixups")) + + newCode, newReqdStringFixups, newExnClauses, newSeqPoints, newScopes + + + // -------------------------------------------------------------------- + // Structured residue of emitting instructions: SEH exception handling + // and scopes for local variables. + // -------------------------------------------------------------------- + + // Emitting instructions generates a tree of seh specifications + // We then emit the exception handling specs separately. + // nb. ECMA spec says the SEH blocks must be returned inside-out + type SEHTree = + | Node of ExceptionClauseSpec option * SEHTree list + + + // -------------------------------------------------------------------- + // Table of encodings for instructions without arguments, also indexes + // for all instructions. + // -------------------------------------------------------------------- + + let encodingsForNoArgInstrs = Dictionary<_, _>(300, HashIdentity.Structural) + let _ = + List.iter + (fun (x, mk) -> encodingsForNoArgInstrs.[mk] <- x) + (noArgInstrs.Force()) + let encodingsOfNoArgInstr si = encodingsForNoArgInstrs.[si] + + // -------------------------------------------------------------------- + // Emit instructions + // -------------------------------------------------------------------- + + /// Emit the code for an instruction + let emitInstrCode (codebuf: CodeBuffer) i = + if i > 0xFF then + assert (i >>> 8 = 0xFE) + codebuf.EmitByte ((i >>> 8) &&& 0xFF) + codebuf.EmitByte (i &&& 0xFF) + else + codebuf.EmitByte i + + let emitTypeInstr cenv codebuf env i ty = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + + let emitMethodSpecInfoInstr cenv codebuf env i mspecinfo = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecInfoAsUncodedToken cenv env mspecinfo) + + let emitMethodSpecInstr cenv codebuf env i mspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecAsUncodedToken cenv env mspec) + + let emitFieldSpecInstr cenv codebuf env i fspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetFieldDefOrRefAsUncodedToken (GetFieldSpecAsFieldDefOrRef cenv env fspec)) + + let emitShortUInt16Instr codebuf (i_short, i) x = + let n = int32 x + if n <= 255 then + emitInstrCode codebuf i_short + codebuf.EmitByte n + else + emitInstrCode codebuf i + codebuf.EmitUInt16 x + + let emitShortInt32Instr codebuf (i_short, i) x = + if x >= -128 && x <= 127 then + emitInstrCode codebuf i_short + codebuf.EmitByte (if x < 0x0 then x + 256 else x) + else + emitInstrCode codebuf i + codebuf.EmitInt32 x + + let emitTailness (cenv: cenv) codebuf tl = + if tl = Tailcall && cenv.emitTailcalls then emitInstrCode codebuf i_tail + + //let emitAfterTailcall codebuf tl = + // if tl = Tailcall then emitInstrCode codebuf i_ret + + let emitVolatility codebuf tl = + if tl = Volatile then emitInstrCode codebuf i_volatile + + let emitConstrained cenv codebuf env ty = + emitInstrCode codebuf i_constrained + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + + let emitAlignment codebuf tl = + match tl with + | Aligned -> () + | Unaligned1 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x1 + | Unaligned2 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x2 + | Unaligned4 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x4 + + let rec emitInstr cenv codebuf env instr = + match instr with + | si when isNoArgInstr si -> + emitInstrCode codebuf (encodingsOfNoArgInstr si) + | I_brcmp (cmp, tg1) -> + codebuf.RecordReqdBrFixup ((Lazy.force ILCmpInstrMap).[cmp], Some (Lazy.force ILCmpInstrRevMap).[cmp]) tg1 + | I_br tg -> codebuf.RecordReqdBrFixup (i_br, Some i_br_s) tg + | I_seqpoint s -> codebuf.EmitSeqPoint cenv s + | I_leave tg -> codebuf.RecordReqdBrFixup (i_leave, Some i_leave_s) tg + | I_call (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_call (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callvirt (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callconstraint (tl, ty, mspec, varargs) -> + emitTailness cenv codebuf tl + emitConstrained cenv codebuf env ty + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_newobj (mspec, varargs) -> + emitMethodSpecInstr cenv codebuf env i_newobj (mspec, varargs) + | I_ldftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldftn (mspec, None) + | I_ldvirtftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldvirtftn (mspec, None) + + | I_calli (tl, callsig, varargs) -> + emitTailness cenv codebuf tl + emitInstrCode codebuf i_calli + codebuf.EmitUncodedToken (getUncodedToken TableNames.StandAloneSig (GetCallsigAsStandAloneSigIdx cenv env (callsig, varargs))) + //emitAfterTailcall codebuf tl + + | I_ldarg u16 -> emitShortUInt16Instr codebuf (i_ldarg_s, i_ldarg) u16 + | I_starg u16 -> emitShortUInt16Instr codebuf (i_starg_s, i_starg) u16 + | I_ldarga u16 -> emitShortUInt16Instr codebuf (i_ldarga_s, i_ldarga) u16 + | I_ldloc u16 -> emitShortUInt16Instr codebuf (i_ldloc_s, i_ldloc) u16 + | I_stloc u16 -> emitShortUInt16Instr codebuf (i_stloc_s, i_stloc) u16 + | I_ldloca u16 -> emitShortUInt16Instr codebuf (i_ldloca_s, i_ldloca) u16 + + | I_cpblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_cpblk + | I_initblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_initblk + + | AI_ldc (DT_I4, ILConst.I4 x) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) x + | AI_ldc (DT_I8, ILConst.I8 x) -> + emitInstrCode codebuf i_ldc_i8 + codebuf.EmitInt64 x + | AI_ldc (_, ILConst.R4 x) -> + emitInstrCode codebuf i_ldc_r4 + codebuf.EmitInt32 (bitsOfSingle x) + | AI_ldc (_, ILConst.R8 x) -> + emitInstrCode codebuf i_ldc_r8 + codebuf.EmitInt64 (bitsOfDouble x) + + | I_ldind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldind_i + | DT_I1 -> i_ldind_i1 + | DT_I2 -> i_ldind_i2 + | DT_I4 -> i_ldind_i4 + | DT_U1 -> i_ldind_u1 + | DT_U2 -> i_ldind_u2 + | DT_U4 -> i_ldind_u4 + | DT_I8 -> i_ldind_i8 + | DT_R4 -> i_ldind_r4 + | DT_R8 -> i_ldind_r8 + | DT_REF -> i_ldind_ref + | _ -> failwith "ldind") + + | I_stelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I | DT_U -> i_stelem_i + | DT_U1 | DT_I1 -> i_stelem_i1 + | DT_I2 | DT_U2 -> i_stelem_i2 + | DT_I4 | DT_U4 -> i_stelem_i4 + | DT_I8 | DT_U8 -> i_stelem_i8 + | DT_R4 -> i_stelem_r4 + | DT_R8 -> i_stelem_r8 + | DT_REF -> i_stelem_ref + | _ -> failwith "stelem") + + | I_ldelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldelem_i + | DT_I1 -> i_ldelem_i1 + | DT_I2 -> i_ldelem_i2 + | DT_I4 -> i_ldelem_i4 + | DT_I8 -> i_ldelem_i8 + | DT_U1 -> i_ldelem_u1 + | DT_U2 -> i_ldelem_u2 + | DT_U4 -> i_ldelem_u4 + | DT_R4 -> i_ldelem_r4 + | DT_R8 -> i_ldelem_r8 + | DT_REF -> i_ldelem_ref + | _ -> failwith "ldelem") + + | I_stind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_U | DT_I -> i_stind_i + | DT_U1 | DT_I1 -> i_stind_i1 + | DT_U2 | DT_I2 -> i_stind_i2 + | DT_U4 | DT_I4 -> i_stind_i4 + | DT_U8 | DT_I8 -> i_stind_i8 + | DT_R4 -> i_stind_r4 + | DT_R8 -> i_stind_r8 + | DT_REF -> i_stind_ref + | _ -> failwith "stelem") + + | I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs + + | I_ldfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldfld fspec + | I_ldflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldflda fspec + | I_ldsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldsfld fspec + | I_ldsflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldsflda fspec + | I_stfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stfld fspec + | I_stsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stsfld fspec + + | I_ldtoken tok -> + emitInstrCode codebuf i_ldtoken + codebuf.EmitUncodedToken + (match tok with + | ILToken.ILType ty -> + match GetTypeAsTypeDefOrRef cenv env ty with + | tag, idx when tag = tdor_TypeDef -> getUncodedToken TableNames.TypeDef idx + | tag, idx when tag = tdor_TypeRef -> getUncodedToken TableNames.TypeRef idx + | tag, idx when tag = tdor_TypeSpec -> getUncodedToken TableNames.TypeSpec idx + | _ -> failwith "?" + | ILToken.ILMethod mspec -> + match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with + | tag, idx when tag = mdor_MethodDef -> getUncodedToken TableNames.Method idx + | tag, idx when tag = mdor_MemberRef -> getUncodedToken TableNames.MemberRef idx + | _ -> failwith "?" + + | ILToken.ILField fspec -> + match GetFieldSpecAsFieldDefOrRef cenv env fspec with + | true, idx -> getUncodedToken TableNames.Field idx + | false, idx -> getUncodedToken TableNames.MemberRef idx) + | I_ldstr s -> + emitInstrCode codebuf i_ldstr + codebuf.RecordReqdStringFixup (GetUserStringHeapIdx cenv s) + + | I_box ty -> emitTypeInstr cenv codebuf env i_box ty + | I_unbox ty -> emitTypeInstr cenv codebuf env i_unbox ty + | I_unbox_any ty -> emitTypeInstr cenv codebuf env i_unbox_any ty + + | I_newarr (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_newarr ty + else + let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_newobj (".ctor", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, []) + + | I_stelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_stelem_any ty + else + let args = List.init (shape.Rank+1) (fun i -> if i < shape.Rank then cenv.ilg.typ_Int32 else ty) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Set", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, []) + + | I_ldelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelem_any ty + else + let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Get", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ty, None, []) + + | I_ldelema (ro, _isNativePtr, shape, ty) -> + if (ro = ReadonlyAddress) then + emitInstrCode codebuf i_readonly + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelema ty + else + let args = List.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Address", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Byref ty, None, []) + + | I_castclass ty -> emitTypeInstr cenv codebuf env i_castclass ty + | I_isinst ty -> emitTypeInstr cenv codebuf env i_isinst ty + | I_refanyval ty -> emitTypeInstr cenv codebuf env i_refanyval ty + | I_mkrefany ty -> emitTypeInstr cenv codebuf env i_mkrefany ty + | I_initobj ty -> emitTypeInstr cenv codebuf env i_initobj ty + | I_ldobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_ldobj ty + | I_stobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_stobj ty + | I_cpobj ty -> emitTypeInstr cenv codebuf env i_cpobj ty + | I_sizeof ty -> emitTypeInstr cenv codebuf env i_sizeof ty + | EI_ldlen_multi (_, m) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) m + emitInstr cenv codebuf env (mkNormalCall(mkILNonGenericMethSpecInTy(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [cenv.ilg.typ_Int32], cenv.ilg.typ_Int32))) + + | _ -> failwith "an IL instruction cannot be emitted" + + + let mkScopeNode cenv importScope (localSigs: _[]) (startOffset, endOffset, ls: ILLocalDebugMapping list, childScopes) = + if isNil ls || not cenv.generatePdb then + childScopes + else + [ { Children= Array.ofList childScopes + StartOffset=startOffset + EndOffset=endOffset + Locals= + [| for x in ls do + if x.LocalName <> "" then + { Name=x.LocalName + Signature= (try localSigs.[x.LocalIndex] with _ -> failwith ("local variable index "+string x.LocalIndex+"in debug info does not reference a valid local")) + Index= x.LocalIndex } |] + Imports = importScope + } ] + + + // Used to put local debug scopes and exception handlers into a tree form + let rangeInsideRange (start_pc1, end_pc1) (start_pc2, end_pc2) = + (start_pc1: int) >= start_pc2 && start_pc1 < end_pc2 && + (end_pc1: int) > start_pc2 && end_pc1 <= end_pc2 + + let lranges_of_clause cl = + match cl with + | ILExceptionClause.Finally r1 -> [r1] + | ILExceptionClause.Fault r1 -> [r1] + | ILExceptionClause.FilterCatch (r1, r2) -> [r1;r2] + | ILExceptionClause.TypeCatch (_ty, r1) -> [r1] + + + let labelsToRange (lab2pc : Dictionary) p = let l1, l2 = p in lab2pc.[l1], lab2pc.[l2] + + let labelRangeInsideLabelRange lab2pc ls1 ls2 = + rangeInsideRange (labelsToRange lab2pc ls1) (labelsToRange lab2pc ls2) + + let findRoots contains vs = + // For each item, either make it a root or make it a child of an existing root + let addToRoot roots x = + // Look to see if 'x' is inside one of the roots + let roots, found = + (false, roots) ||> List.mapFold (fun found (r, children) -> + if found then ((r, children), true) + elif contains x r then ((r, x :: children), true) + else ((r, children), false)) + + if found then roots + else + // Find the ones that 'x' encompasses and collapse them + let yes, others = roots |> List.partition (fun (r, _) -> contains r x) + (x, yes |> List.collect (fun (r, ch) -> r :: ch)) :: others + + ([], vs) ||> List.fold addToRoot + + let rec makeSEHTree cenv env (pc2pos: int[]) (lab2pc : Dictionary) (exs : ILExceptionSpec list) = + + let clause_inside_lrange cl lr = + List.forall (fun lr1 -> labelRangeInsideLabelRange lab2pc lr1 lr) (lranges_of_clause cl) + + let tryspec_inside_lrange (tryspec1: ILExceptionSpec) lr = + (labelRangeInsideLabelRange lab2pc tryspec1.Range lr && clause_inside_lrange tryspec1.Clause lr) + + let tryspec_inside_clause tryspec1 cl = + List.exists (fun lr -> tryspec_inside_lrange tryspec1 lr) (lranges_of_clause cl) + + let tryspec_inside_tryspec tryspec1 (tryspec2: ILExceptionSpec) = + tryspec_inside_lrange tryspec1 tryspec2.Range || + tryspec_inside_clause tryspec1 tryspec2.Clause + + let roots = findRoots tryspec_inside_tryspec exs + let trees = + roots |> List.map (fun (cl, ch) -> + let r1 = labelsToRange lab2pc cl.Range + let conv ((s1, e1), (s2, e2)) x = pc2pos.[s1], pc2pos.[e1] - pc2pos.[s1], pc2pos.[s2], pc2pos.[e2] - pc2pos.[s2], x + let children = makeSEHTree cenv env pc2pos lab2pc ch + let n = + match cl.Clause with + | ILExceptionClause.Finally r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FinallyClause + | ILExceptionClause.Fault r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FaultClause + | ILExceptionClause.FilterCatch ((filterStart, _), r3) -> + conv (r1, labelsToRange lab2pc r3) (ExceptionClauseKind.FilterClause pc2pos.[lab2pc.[filterStart]]) + | ILExceptionClause.TypeCatch (ty, r2) -> + conv (r1, labelsToRange lab2pc r2) (TypeFilterClause (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty))) + SEHTree.Node (Some n, children) ) + + trees + + let rec makeLocalsTree cenv importScope localSigs (pc2pos: int[]) (lab2pc : Dictionary) (exs : ILLocalDebugInfo list) = + let localInsideLocal (locspec1: ILLocalDebugInfo) (locspec2: ILLocalDebugInfo) = + labelRangeInsideLabelRange lab2pc locspec1.Range locspec2.Range + + let roots = findRoots localInsideLocal exs + + let trees = + roots |> List.collect (fun (cl, ch) -> + let s1, e1 = labelsToRange lab2pc cl.Range + let s1, e1 = pc2pos.[s1], pc2pos.[e1] + let children = makeLocalsTree cenv importScope localSigs pc2pos lab2pc ch + mkScopeNode cenv importScope localSigs (s1, e1, cl.DebugMappings, children)) + trees + + // Emit the SEH tree + let rec emitExceptionHandlerTree (codebuf: CodeBuffer) (Node (x, childSEH)) = + List.iter (emitExceptionHandlerTree codebuf) childSEH // internal first + x |> Option.iter codebuf.EmitExceptionClause + + let emitCode cenv importScope localSigs (codebuf: CodeBuffer) env (code: ILCode) = + let instrs = code.Instrs + + // Build a table mapping Abstract IL pcs to positions in the generated code buffer + let pc2pos = Array.zeroCreate (instrs.Length+1) + let pc2labs = Dictionary() + for KeyValue (lab, pc) in code.Labels do + match pc2labs.TryGetValue pc with + | true, labels -> + pc2labs.[pc] <- lab :: labels + | _ -> pc2labs.[pc] <- [lab] + + // Emit the instructions + for pc = 0 to instrs.Length do + match pc2labs.TryGetValue pc with + | true, labels -> + for lab in labels do + codebuf.RecordAvailBrFixup lab + | _ -> () + pc2pos.[pc] <- codebuf.code.Position + if pc < instrs.Length then + match instrs.[pc] with + | I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction + | i -> emitInstr cenv codebuf env i + + // Build the exceptions and locals information, ready to emit + let SEHTree = makeSEHTree cenv env pc2pos code.Labels code.Exceptions + List.iter (emitExceptionHandlerTree codebuf) SEHTree + + // Build the locals information, ready to emit + let localsTree = makeLocalsTree cenv importScope localSigs pc2pos code.Labels code.Locals + + // Adjust the scopes for shadowing + let unshadowed = List.collect (unshadowScopes >> Array.toList) localsTree + unshadowed + + let EmitMethodCode cenv importScope localSigs env nm code = + use codebuf = CodeBuffer.Create nm + let origScopes = emitCode cenv importScope localSigs codebuf env code + let origCode = codebuf.code.AsMemory().ToArray() + let origExnClauses = List.rev codebuf.seh + let origReqdStringFixups = codebuf.reqdStringFixupsInMethod + let origAvailBrFixups = codebuf.availBrFixups + let origReqdBrFixups = codebuf.reqdBrFixups + let origSeqPoints = codebuf.seqpoints.ToArray() + + let newCode, newReqdStringFixups, newExnClauses, newSeqPoints, newScopes = + applyBrFixups origCode origExnClauses origReqdStringFixups origAvailBrFixups origReqdBrFixups origSeqPoints origScopes + + let rootScope = + { + Children= Array.ofList newScopes + StartOffset=0 + EndOffset=newCode.Length + Locals=[| |] + Imports = importScope + } + + (newReqdStringFixups, newExnClauses, newCode, newSeqPoints, rootScope) + +// -------------------------------------------------------------------- +// ILMethodBody --> bytes +// -------------------------------------------------------------------- +let GetFieldDefTypeAsBlobIdx cenv env ty = + let bytes = emitBytesViaBuffer (fun bb -> bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb ty) + GetBytesAsBlobIdx cenv bytes + +let GenPdbImport (cenv: cenv) env (input: ILDebugImport) = + match input with + | ILDebugImport.ImportType ty -> PdbImport.ImportType (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + | ILDebugImport.ImportNamespace nsp -> PdbImport.ImportNamespace nsp + +let rec GenPdbImports (cenv: cenv) env (input: ILDebugImports option) = + match input with + | None -> None + | Some ilImports -> + match cenv.pdbImports.TryGetValue(ilImports) with + | true, v -> Some v + | _ -> + let v : PdbImports = + { Imports = ilImports.Imports |> Array.map (GenPdbImport cenv env) + Parent = GenPdbImports cenv env ilImports.Parent } + cenv.pdbImports.[ilImports] <- v + Some v + +let GenILMethodBody mname cenv env (il: ILMethodBody) = + let localSigs = + if cenv.generatePdb then + il.Locals |> List.toArray |> Array.map (fun l -> + // Write a fake entry for the local signature headed by e_IMAGE_CEE_CS_CALLCONV_FIELD. This is referenced by the PDB file + ignore (FindOrAddSharedRow cenv TableNames.StandAloneSig (SharedRow [| Blob (GetFieldDefTypeAsBlobIdx cenv env l.Type) |])) + // Now write the type + GetTypeOfLocalAsBytes cenv env l) + else + [| |] + + let imports = GenPdbImports cenv env il.DebugImports + let requiredStringFixups, seh, code, seqpoints, scopes = Codebuf.EmitMethodCode cenv imports localSigs env mname il.Code + let codeSize = code.Length + use methbuf = ByteBuffer.Create (codeSize * 3) + // Do we use the tiny format? + if isNil il.Locals && il.MaxStack <= 8 && isNil seh && codeSize < 64 then + // Use Tiny format + let alignedCodeSize = align 4 (codeSize + 1) + let codePadding = (alignedCodeSize - (codeSize + 1)) + let requiredStringFixups' = (1, requiredStringFixups) + methbuf.EmitByte (byte codeSize <<< 2 ||| e_CorILMethod_TinyFormat) + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + 0x0, (requiredStringFixups', methbuf.AsMemory().ToArray()), seqpoints, scopes + else + // Use Fat format + let flags = + e_CorILMethod_FatFormat ||| + (if seh <> [] then e_CorILMethod_MoreSects else 0x0uy) ||| + (if il.IsZeroInit then e_CorILMethod_InitLocals else 0x0uy) + + let localToken = + if isNil il.Locals then 0x0 else + getUncodedToken TableNames.StandAloneSig + (FindOrAddSharedRow cenv TableNames.StandAloneSig (GetLocalSigAsStandAloneSigIdx cenv env il.Locals)) + + let alignedCodeSize = align 0x4 codeSize + let codePadding = (alignedCodeSize - codeSize) + + methbuf.EmitByte flags + methbuf.EmitByte 0x30uy // last four bits record size of fat header in 4 byte chunks - this is always 12 bytes = 3 four word chunks + methbuf.EmitUInt16 (uint16 il.MaxStack) + methbuf.EmitInt32 codeSize + methbuf.EmitInt32 localToken + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + + if not (isNil seh) then + // Can we use the small exception handling table format? + let smallSize = (seh.Length * 12 + 4) + let canUseSmall = + smallSize <= 0xFF && + seh |> List.forall (fun (st1, sz1, st2, sz2, _) -> + st1 <= 0xFFFF && st2 <= 0xFFFF && sz1 <= 0xFF && sz2 <= 0xFF) + + let kindAsInt32 k = + match k with + | FinallyClause -> e_COR_ILEXCEPTION_CLAUSE_FINALLY + | FaultClause -> e_COR_ILEXCEPTION_CLAUSE_FAULT + | FilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_FILTER + | TypeFilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_EXCEPTION + let kindAsExtraInt32 k = + match k with + | FinallyClause | FaultClause -> 0x0 + | FilterClause i -> i + | TypeFilterClause uncoded -> uncoded + + if canUseSmall then + methbuf.EmitByte e_CorILMethod_Sect_EHTable + methbuf.EmitByte (b0 smallSize) + methbuf.EmitByte 0x00uy + methbuf.EmitByte 0x00uy + seh |> List.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32AsUInt16 k32 + methbuf.EmitInt32AsUInt16 st1 + methbuf.EmitByte (b0 sz1) + methbuf.EmitInt32AsUInt16 st2 + methbuf.EmitByte (b0 sz2) + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + else + let bigSize = (seh.Length * 24 + 4) + methbuf.EmitByte (e_CorILMethod_Sect_EHTable ||| e_CorILMethod_Sect_FatFormat) + methbuf.EmitByte (b0 bigSize) + methbuf.EmitByte (b1 bigSize) + methbuf.EmitByte (b2 bigSize) + seh |> List.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32 k32 + methbuf.EmitInt32 st1 + methbuf.EmitInt32 sz1 + methbuf.EmitInt32 st2 + methbuf.EmitInt32 sz2 + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + + let requiredStringFixups' = (12, requiredStringFixups) + + localToken, (requiredStringFixups', methbuf.AsMemory().ToArray()), seqpoints, scopes + +// -------------------------------------------------------------------- +// ILFieldDef --> FieldDef Row +// -------------------------------------------------------------------- + +let rec GetFieldDefAsFieldDefRow cenv env (fd: ILFieldDef) = + let flags = int fd.Attributes + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv fd.Name) + Blob (GetFieldDefSigAsBlobIdx cenv env fd ) |] + +and GetFieldDefSigAsBlobIdx cenv env fd = GetFieldDefTypeAsBlobIdx cenv env fd.FieldType + +and GenFieldDefPass3 cenv env fd = + let fidx = AddUnsharedRow cenv TableNames.Field (GetFieldDefAsFieldDefRow cenv env fd) + GenCustomAttrsPass3Or4 cenv (hca_FieldDef, fidx) fd.CustomAttrs + // Write FieldRVA table - fixups into data section done later + match fd.Data with + | None -> () + | Some b -> + let offs = cenv.data.Position + cenv.data.EmitBytes b + AddUnsharedRow cenv TableNames.FieldRVA + (UnsharedRow [| Data (offs, false); SimpleIndex (TableNames.Field, fidx) |]) |> ignore + // Write FieldMarshal table + match fd.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv TableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_FieldDef, fidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore + // Write Content table + match fd.LiteralValue with + | None -> () + | Some i -> + AddUnsharedRow cenv TableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (hc_FieldDef, fidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + // Write FieldLayout table + match fd.Offset with + | None -> () + | Some offset -> + AddUnsharedRow cenv TableNames.FieldLayout + (UnsharedRow [| ULong offset; SimpleIndex (TableNames.Field, fidx) |]) |> ignore + + +// -------------------------------------------------------------------- +// ILGenericParameterDef --> GenericParam Row +// -------------------------------------------------------------------- + +let rec GetGenericParamAsGenericParamRow cenv _env idx owner gp = + let flags = + (match gp.Variance with + | NonVariant -> 0x0000 + | CoVariant -> 0x0001 + | ContraVariant -> 0x0002) ||| + (if gp.HasReferenceTypeConstraint then 0x0004 else 0x0000) ||| + (if gp.HasNotNullableValueTypeConstraint then 0x0008 else 0x0000) ||| + (if gp.HasDefaultConstructorConstraint then 0x0010 else 0x0000) + + let mdVersionMajor, _ = metadataSchemaVersionSupportedByCLRVersion cenv.desiredMetadataVersion + if (mdVersionMajor = 1) then + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) + TypeDefOrRefOrSpec (tdor_TypeDef, 0) (* empty kind field in deprecated metadata *) |] + else + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) |] + +and GenTypeAsGenericParamConstraintRow cenv env gpidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (TableNames.GenericParam, gpidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + +and GenGenericParamConstraintPass4 cenv env gpidx ty = + AddUnsharedRow cenv TableNames.GenericParamConstraint (GenTypeAsGenericParamConstraintRow cenv env gpidx ty) |> ignore + +and GenGenericParamPass3 cenv env idx owner gp = + // here we just collect generic params, its constraints\custom attributes will be processed on pass4 + // shared since we look it up again below in GenGenericParamPass4 + AddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + |> ignore + + +and GenGenericParamPass4 cenv env idx owner gp = + let gpidx = FindOrAddSharedRow cenv TableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + GenCustomAttrsPass3Or4 cenv (hca_GenericParam, gpidx) gp.CustomAttrs + gp.Constraints |> List.iter (GenGenericParamConstraintPass4 cenv env gpidx) + +// -------------------------------------------------------------------- +// param and return --> Param Row +// -------------------------------------------------------------------- + +let rec GetParamAsParamRow cenv _env seq (param: ILParameter) = + let flags = + (if param.IsIn then 0x0001 else 0x0000) ||| + (if param.IsOut then 0x0002 else 0x0000) ||| + (if param.IsOptional then 0x0010 else 0x0000) ||| + (if param.Default <> None then 0x1000 else 0x0000) ||| + (if param.Marshal <> None then 0x2000 else 0x0000) + + UnsharedRow + [| UShort (uint16 flags) + UShort (uint16 seq) + StringE (GetStringHeapIdxOption cenv param.Name) |] + +and GenParamPass3 cenv env seq (param: ILParameter) = + if not param.IsIn && not param.IsOut && not param.IsOptional && Option.isNone param.Default && Option.isNone param.Name && Option.isNone param.Marshal + then () + else + let pidx = AddUnsharedRow cenv TableNames.Param (GetParamAsParamRow cenv env seq param) + GenCustomAttrsPass3Or4 cenv (hca_ParamDef, pidx) param.CustomAttrs + // Write FieldRVA table - fixups into data section done later + match param.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv TableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_ParamDef, pidx); Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore + // Write Content table for DefaultParameterValue attr + match param.Default with + | None -> () + | Some i -> + AddUnsharedRow cenv TableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (hc_ParamDef, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + +let GenReturnAsParamRow (returnv : ILReturn) = + let flags = (if returnv.Marshal <> None then 0x2000 else 0x0000) + UnsharedRow + [| UShort (uint16 flags) + UShort 0us (* sequence num. *) + StringE 0 |] + +let GenReturnPass3 cenv (returnv: ILReturn) = + if Option.isSome returnv.Marshal || not (Array.isEmpty returnv.CustomAttrs.AsArray) then + let pidx = AddUnsharedRow cenv TableNames.Param (GenReturnAsParamRow returnv) + GenCustomAttrsPass3Or4 cenv (hca_ParamDef, pidx) returnv.CustomAttrs + match returnv.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv TableNames.FieldMarshal + (UnsharedRow + [| HasFieldMarshal (hfm_ParamDef, pidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore + +// -------------------------------------------------------------------- +// ILMethodDef --> ILMethodDef Row +// -------------------------------------------------------------------- + +let GetMethodDefSigAsBytes cenv env (mdef: ILMethodDef) = + emitBytesViaBuffer (fun bb -> + bb.EmitByte (callconvToByte mdef.GenericParams.Length mdef.CallingConv) + if not (List.isEmpty mdef.GenericParams) then bb.EmitZ32 mdef.GenericParams.Length + bb.EmitZ32 mdef.Parameters.Length + EmitType cenv env bb mdef.Return.Type + mdef.ParameterTypes |> List.iter (EmitType cenv env bb)) + +let GenMethodDefSigAsBlobIdx cenv env mdef = + GetBytesAsBlobIdx cenv (GetMethodDefSigAsBytes cenv env mdef) + +let GenMethodDefAsRow cenv env midx (md: ILMethodDef) = + let flags = md.Attributes + + let implflags = md.ImplAttributes + + if md.IsEntryPoint then + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (true, midx) + let codeAddr = + (match md.Body with + | MethodBody.IL ilmbodyLazy -> + let ilmbody = ilmbodyLazy.Value + let addr = cenv.nextCodeAddr + let localToken, code, seqpoints, rootScope = GenILMethodBody md.Name cenv env ilmbody + + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken=getUncodedToken TableNames.Method midx + MethName=md.Name + LocalSignatureToken=localToken + Params= [| |] (* REVIEW *) + RootScope = Some rootScope + Range= + match ilmbody.DebugPoint with + | Some m when cenv.generatePdb -> + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + + Some ({ Document=doc + Line=m.Line + Column=m.Column }, + { Document=doc + Line=m.EndLine + Column=m.EndColumn }) + | _ -> None + DebugPoints=seqpoints } + cenv.AddCode code + addr + | MethodBody.Abstract + | MethodBody.PInvoke _ -> + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken = getUncodedToken TableNames.Method midx + MethName = md.Name + LocalSignatureToken = 0x0 // No locals it's abstract + Params = [| |] + RootScope = None + Range = None + DebugPoints = [| |] } + 0x0000 + | MethodBody.Native -> + failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries" + | _ -> 0x0000) + + UnsharedRow + [| ULong codeAddr + UShort (uint16 implflags) + UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + Blob (GenMethodDefSigAsBlobIdx cenv env md) + SimpleIndex(TableNames.Param, cenv.GetTable(TableNames.Param).Count + 1) |] + +let GenMethodImplPass3 cenv env _tgparams tidx mimpl = + let midxTag, midxRow = GetMethodSpecAsMethodDef cenv env (mimpl.OverrideBy, None) + let midx2Tag, midx2Row = GetOverridesSpecAsMethodDefOrRef cenv env mimpl.Overrides + AddUnsharedRow cenv TableNames.MethodImpl + (UnsharedRow + [| SimpleIndex (TableNames.TypeDef, tidx) + MethodDefOrRef (midxTag, midxRow) + MethodDefOrRef (midx2Tag, midx2Row) |]) |> ignore + +let GenMethodDefPass3 cenv env (md: ILMethodDef) = + let midx = GetMethodDefIdx cenv md + let idx2 = AddUnsharedRow cenv TableNames.Method (GenMethodDefAsRow cenv env midx md) + if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2" + GenReturnPass3 cenv md.Return + md.Parameters |> List.iteri (fun n param -> GenParamPass3 cenv env (n+1) param) + md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_MethodDef, midx) + md.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx) + md.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_MethodDef, midx) gp) + match md.Body with + | MethodBody.PInvoke attrLazy -> + let attr = attrLazy.Value + let flags = + begin match attr.CallingConv with + | PInvokeCallingConvention.None -> 0x0000 + | PInvokeCallingConvention.Cdecl -> 0x0200 + | PInvokeCallingConvention.Stdcall -> 0x0300 + | PInvokeCallingConvention.Thiscall -> 0x0400 + | PInvokeCallingConvention.Fastcall -> 0x0500 + | PInvokeCallingConvention.WinApi -> 0x0100 + end ||| + begin match attr.CharEncoding with + | PInvokeCharEncoding.None -> 0x0000 + | PInvokeCharEncoding.Ansi -> 0x0002 + | PInvokeCharEncoding.Unicode -> 0x0004 + | PInvokeCharEncoding.Auto -> 0x0006 + end ||| + begin match attr.CharBestFit with + | PInvokeCharBestFit.UseAssembly -> 0x0000 + | PInvokeCharBestFit.Enabled -> 0x0010 + | PInvokeCharBestFit.Disabled -> 0x0020 + end ||| + begin match attr.ThrowOnUnmappableChar with + | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000 + | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000 + | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000 + end ||| + (if attr.NoMangle then 0x0001 else 0x0000) ||| + (if attr.LastError then 0x0040 else 0x0000) + AddUnsharedRow cenv TableNames.ImplMap + (UnsharedRow + [| UShort (uint16 flags) + MemberForwarded (mf_MethodDef, midx) + StringE (GetStringHeapIdx cenv attr.Name) + SimpleIndex (TableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore + | _ -> () + +let GenMethodDefPass4 cenv env md = + let midx = GetMethodDefIdx cenv md + List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_MethodDef, midx) gp) md.GenericParams + +let GenPropertyMethodSemanticsPass3 cenv pidx kind mref = + // REVIEW: why are we catching exceptions here? + let midx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv TableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (TableNames.Method, midx) + HasSemantics (hs_Property, pidx) |]) |> ignore + +let rec GetPropertySigAsBlobIdx cenv env prop = + GetBytesAsBlobIdx cenv (GetPropertySigAsBytes cenv env prop) + +and GetPropertySigAsBytes cenv env (prop: ILPropertyDef) = + emitBytesViaBuffer (fun bb -> + let b = ((hasthisToByte prop.CallingConv) ||| e_IMAGE_CEE_CS_CALLCONV_PROPERTY) + bb.EmitByte b + bb.EmitZ32 prop.Args.Length + EmitType cenv env bb prop.PropertyType + prop.Args |> List.iter (EmitType cenv env bb)) + +and GetPropertyAsPropertyRow cenv env (prop: ILPropertyDef) = + let flags = prop.Attributes + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv prop.Name) + Blob (GetPropertySigAsBlobIdx cenv env prop) |] + +/// ILPropertyDef --> Property Row + MethodSemantics entries +and GenPropertyPass3 cenv env prop = + let pidx = AddUnsharedRow cenv TableNames.Property (GetPropertyAsPropertyRow cenv env prop) + prop.SetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0001) + prop.GetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0002) + // Write Constant table + match prop.Init with + | None -> () + | Some i -> + AddUnsharedRow cenv TableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (hc_Property, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + GenCustomAttrsPass3Or4 cenv (hca_Property, pidx) prop.CustomAttrs + +let rec GenEventMethodSemanticsPass3 cenv eidx kind mref = + let addIdx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv TableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (TableNames.Method, addIdx) + HasSemantics (hs_Event, eidx) |]) |> ignore + +/// ILEventDef --> Event Row + MethodSemantics entries +and GenEventAsEventRow cenv env (md: ILEventDef) = + let flags = md.Attributes + let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env md.EventType + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + +and GenEventPass3 cenv env (md: ILEventDef) = + let eidx = AddUnsharedRow cenv TableNames.Event (GenEventAsEventRow cenv env md) + md.AddMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0008 + md.RemoveMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0010 + Option.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0020) md.FireMethod + List.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0004) md.OtherMethods + GenCustomAttrsPass3Or4 cenv (hca_Event, eidx) md.CustomAttrs + + +// -------------------------------------------------------------------- +// resource --> generate ... +// -------------------------------------------------------------------- + +let rec GetResourceAsManifestResourceRow cenv r = + let data, impl = + let embedManagedResources (bytes: ReadOnlyByteMemory) = + // Embedded managed resources must be word-aligned. However resource format is + // not specified in ECMA. Some mscorlib resources appear to be non-aligned - it seems it doesn't matter.. + let offset = cenv.resources.Position + let alignedOffset = (align 0x8 offset) + let pad = alignedOffset - offset + let resourceSize = bytes.Length + cenv.resources.EmitPadding pad + cenv.resources.EmitInt32 resourceSize + cenv.resources.EmitByteMemory bytes + Data (alignedOffset, true), (i_File, 0) + + match r.Location with + | ILResourceLocation.Local bytes -> embedManagedResources (bytes.GetByteMemory()) + | ILResourceLocation.File (mref, offset) -> ULong offset, (i_File, GetModuleRefAsFileIdx cenv mref) + | ILResourceLocation.Assembly aref -> ULong 0x0, (i_AssemblyRef, GetAssemblyRefAsIdx cenv aref) + + UnsharedRow + [| data + ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02) + StringE (GetStringHeapIdx cenv r.Name) + Implementation (fst impl, snd impl) |] + +and GenResourcePass3 cenv r = + let idx = AddUnsharedRow cenv TableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r) + GenCustomAttrsPass3Or4 cenv (hca_ManifestResource, idx) r.CustomAttrs + +// -------------------------------------------------------------------- +// ILTypeDef --> generate ILFieldDef, ILMethodDef, ILPropertyDef etc. rows +// -------------------------------------------------------------------- + +let rec GenTypeDefPass3 enc cenv (td: ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) + td.Properties.AsList |> List.iter (GenPropertyPass3 cenv env) + td.Events.AsList |> List.iter (GenEventPass3 cenv env) + td.Fields.AsList |> List.iter (GenFieldDefPass3 cenv env) + td.Methods |> Seq.iter (GenMethodDefPass3 cenv env) + td.MethodImpls.AsList |> List.iter (GenMethodImplPass3 cenv env td.GenericParams.Length tidx) + // ClassLayout entry if needed + match td.Layout with + | ILTypeDefLayout.Auto -> () + | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> + if Option.isSome layout.Pack || Option.isSome layout.Size then + AddUnsharedRow cenv TableNames.ClassLayout + (UnsharedRow + [| UShort (defaultArg layout.Pack (uint16 0x0)) + ULong (defaultArg layout.Size 0x0) + SimpleIndex (TableNames.TypeDef, tidx) |]) |> ignore + + td.SecurityDecls.AsList |> GenSecurityDeclsPass3 cenv (hds_TypeDef, tidx) + td.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (hca_TypeDef, tidx) + td.GenericParams |> List.iteri (fun n gp -> GenGenericParamPass3 cenv env n (tomd_TypeDef, tidx) gp) + td.NestedTypes.AsList |> GenTypeDefsPass3 (enc@[td.Name]) cenv + with e -> + failwith ("Error in pass3 for type "+td.Name+", error: "+e.Message) + reraise() + raise e + +and GenTypeDefsPass3 enc cenv tds = + List.iter (GenTypeDefPass3 enc cenv) tds + +/// ILTypeDef --> generate generic params on ILMethodDef: ensures +/// GenericParam table is built sorted by owner. + +let rec GenTypeDefPass4 enc cenv (td: ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Name)) + td.Methods |> Seq.iter (GenMethodDefPass4 cenv env) + List.iteri (fun n gp -> GenGenericParamPass4 cenv env n (tomd_TypeDef, tidx) gp) td.GenericParams + GenTypeDefsPass4 (enc@[td.Name]) cenv td.NestedTypes.AsList + with e -> + failwith ("Error in pass4 for type "+td.Name+", error: "+e.Message) + reraise() + raise e + +and GenTypeDefsPass4 enc cenv tds = + List.iter (GenTypeDefPass4 enc cenv) tds + + +let timestamp = absilWriteGetTimeStamp () + +// -------------------------------------------------------------------- +// ILExportedTypesAndForwarders --> ILExportedTypeOrForwarder table +// -------------------------------------------------------------------- + +let rec GenNestedExportedTypePass3 cenv cidx (ce: ILNestedExportedType) = + let flags = GetMemberAccessFlags ce.Access + let nidx = + AddUnsharedRow cenv TableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + StringE (GetStringHeapIdx cenv ce.Name) + StringE 0 + Implementation (i_ExportedType, cidx) |]) + GenCustomAttrsPass3Or4 cenv (hca_ExportedType, nidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv nidx ce.Nested + +and GenNestedExportedTypesPass3 cenv nidx (nce: ILNestedExportedTypes) = + nce.AsList |> List.iter (GenNestedExportedTypePass3 cenv nidx) + +and GenExportedTypePass3 cenv (ce: ILExportedTypeOrForwarder) = + let nselem, nelem = GetTypeNameAsElemPair cenv ce.Name + let flags = int32 ce.Attributes + let impl = GetScopeRefAsImplementationElem cenv ce.ScopeRef + let cidx = + AddUnsharedRow cenv TableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + nelem + nselem + Implementation (fst impl, snd impl) |]) + GenCustomAttrsPass3Or4 cenv (hca_ExportedType, cidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv cidx ce.Nested + +and GenExportedTypesPass3 cenv (ce: ILExportedTypesAndForwarders) = + List.iter (GenExportedTypePass3 cenv) ce.AsList + +// -------------------------------------------------------------------- +// manifest --> generate Assembly row +// -------------------------------------------------------------------- + +and GetManifestAsAssemblyRow cenv m = + UnsharedRow + [|ULong m.AuxModuleHashAlgorithm + UShort (match m.Version with None -> 0us | Some version -> version.Major) + UShort (match m.Version with None -> 0us | Some version -> version.Minor) + UShort (match m.Version with None -> 0us | Some version -> version.Build) + UShort (match m.Version with None -> 0us | Some version -> version.Revision) + ULong + ( (match m.AssemblyLongevity with + | ILAssemblyLongevity.Unspecified -> 0x0000 + | ILAssemblyLongevity.Library -> 0x0002 + | ILAssemblyLongevity.PlatformAppDomain -> 0x0004 + | ILAssemblyLongevity.PlatformProcess -> 0x0006 + | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| + (if m.Retargetable then 0x100 else 0x0) ||| + // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. + // Any debugging customAttributes will automatically propagate + // REVIEW: No longer appears to be the case + (if m.JitTracking then 0x8000 else 0x0) ||| + (match m.PublicKey with None -> 0x0000 | Some _ -> 0x0001) ||| 0x0000) + (match m.PublicKey with None -> Blob 0 | Some x -> Blob (GetBytesAsBlobIdx cenv x)) + StringE (GetStringHeapIdx cenv m.Name) + (match m.Locale with None -> StringE 0 | Some x -> StringE (GetStringHeapIdx cenv x)) |] + +and GenManifestPass3 cenv m = + let aidx = AddUnsharedRow cenv TableNames.Assembly (GetManifestAsAssemblyRow cenv m) + GenSecurityDeclsPass3 cenv (hds_Assembly, aidx) m.SecurityDecls.AsList + GenCustomAttrsPass3Or4 cenv (hca_Assembly, aidx) m.CustomAttrs + GenExportedTypesPass3 cenv m.ExportedTypes + // Record the entrypoint decl if needed. + match m.EntrypointElsewhere with + | Some mref -> + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) + | None -> () + +and newGuid (modul: ILModuleDef) = + let n = timestamp + let m = hash n + let m2 = hash modul.Name + [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + +and deterministicGuid (modul: ILModuleDef) = + let n = 16909060 + let m2 = Seq.sum (Seq.mapi (fun i x -> i + int x) modul.Name) // use a stable hash + [| b0 n; b1 n; b2 n; b3 n; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + +and GetModuleAsRow (cenv: cenv) (modul: ILModuleDef) = + // Store the generated MVID in the environment (needed for generating debug information) + let modulGuid = if cenv.deterministic then deterministicGuid modul else newGuid modul + cenv.moduleGuid <- modulGuid + UnsharedRow + [| UShort (uint16 0x0) + StringE (GetStringHeapIdx cenv modul.Name) + Guid (GetGuidIdx cenv modulGuid) + Guid 0 + Guid 0 |] + + +let rowElemCompare (e1: RowElement) (e2: RowElement) = + let c = compare e1.Val e2.Val + if c <> 0 then c else + compare e1.Tag e2.Tag + +let TableRequiresSorting tab = + List.memAssoc tab sortedTableInfo + +let SortTableRows tab (rows: GenericRow[]) = + assert (TableRequiresSorting tab) + let col = List.assoc tab sortedTableInfo + rows + // This needs to be a stable sort, so we use List.sortWith + |> Array.toList + |> List.sortWith (fun r1 r2 -> rowElemCompare r1.[col] r2.[col]) + |> Array.ofList + //|> Array.map SharedRow + +let GenModule (cenv : cenv) (modul: ILModuleDef) = + let midx = AddUnsharedRow cenv TableNames.Module (GetModuleAsRow cenv modul) + List.iter (GenResourcePass3 cenv) modul.Resources.AsList + let tds = destTypeDefsWithGlobalFunctionsFirst cenv.ilg modul.TypeDefs + reportTime cenv.showTimes "Module Generation Preparation" + GenTypeDefsPass1 [] cenv tds + reportTime cenv.showTimes "Module Generation Pass 1" + GenTypeDefsPass2 0 [] cenv tds + reportTime cenv.showTimes "Module Generation Pass 2" + (match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m) + GenTypeDefsPass3 [] cenv tds + reportTime cenv.showTimes "Module Generation Pass 3" + GenCustomAttrsPass3Or4 cenv (hca_Module, midx) modul.CustomAttrs + // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes). + // Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params. + // Note this mutates the rows in a table. 'SetRowsOfTable' clears + // the key --> index map since it is no longer valid + cenv.GetTable(TableNames.GenericParam).SetRowsOfSharedTable (SortTableRows TableNames.GenericParam (cenv.GetTable(TableNames.GenericParam).GenericRowsOfTable)) + GenTypeDefsPass4 [] cenv tds + reportTime cenv.showTimes "Module Generation Pass 4" + +/// Arbitrary value +[] +let CodeChunkCapacity = 40000 +/// Arbitrary value +[] +let DataCapacity = 200 +/// Arbitrary value +[] +let ResourceCapacity = 200 + +let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg : ILGlobals, emitTailcalls, deterministic, showTimes) (m : ILModuleDef) cilStartAddress normalizeAssemblyRefs = + let isDll = m.IsDLL + + let tables = + Array.init 64 (fun i -> + if (i = TableNames.AssemblyRef.Index || + i = TableNames.MemberRef.Index || + i = TableNames.ModuleRef.Index || + i = TableNames.File.Index || + i = TableNames.TypeRef.Index || + i = TableNames.TypeSpec.Index || + i = TableNames.MethodSpec.Index || + i = TableNames.StandAloneSig.Index || + i = TableNames.GenericParam.Index) then + MetadataTable.Shared (MetadataTable.New ("row table "+string i, EqualityComparer.Default)) + else + MetadataTable.Unshared (MetadataTable.New ("row table "+string i, EqualityComparer.Default))) + use cenv = + { emitTailcalls=emitTailcalls + deterministic = deterministic + showTimes=showTimes + ilg = ilg + desiredMetadataVersion=desiredMetadataVersion + requiredDataFixups= requiredDataFixups + requiredStringFixups = [] + codeChunks=ByteBuffer.Create(CodeChunkCapacity, useArrayPool = true) + nextCodeAddr = cilStartAddress + data = ByteBuffer.Create DataCapacity + resources = ByteBuffer.Create ResourceCapacity + tables= tables + AssemblyRefs = MetadataTable<_>.New("ILAssemblyRef", EqualityComparer.Default) + documents=MetadataTable<_>.New("pdbdocs", EqualityComparer.Default) + trefCache=Dictionary<_, _>(100) + pdbinfo= ResizeArray<_>(200) + moduleGuid= Array.zeroCreate 16 + fieldDefs= MetadataTable<_>.New("field defs", EqualityComparer.Default) + methodDefIdxsByKey = MetadataTable<_>.New("method defs", EqualityComparer.Default) + // This uses reference identity on ILMethodDef objects + methodDefIdxs = Dictionary<_, _>(100, HashIdentity.Reference) + propertyDefs = MetadataTable<_>.New("property defs", EqualityComparer.Default) + eventDefs = MetadataTable<_>.New("event defs", EqualityComparer.Default) + typeDefs = MetadataTable<_>.New("type defs", EqualityComparer.Default) + entrypoint=None + generatePdb=generatePdb + // These must use structural comparison since they are keyed by arrays + guids=MetadataTable<_>.New("guids", HashIdentity.Structural) + blobs= MetadataTable<_>.New("blobs", HashIdentity.Structural) + strings= MetadataTable<_>.New("strings", EqualityComparer.Default) + userStrings= MetadataTable<_>.New("user strings", EqualityComparer.Default) + normalizeAssemblyRefs = normalizeAssemblyRefs + pdbImports = Dictionary<_, _>(HashIdentity.Reference) } + + // Now the main compilation step + GenModule cenv m + + // .exe files have a .entrypoint instruction. Do not write it to the entrypoint when writing dll. + let entryPointToken = + match cenv.entrypoint with + | Some (epHere, tok) -> + if isDll then 0x0 + else getUncodedToken (if epHere then TableNames.Method else TableNames.File) tok + | None -> + if not isDll then dprintn "warning: no entrypoint specified in executable binary" + 0x0 + + let pdbData = + { EntryPoint= (if isDll then None else Some entryPointToken) + Timestamp = timestamp + ModuleID = cenv.moduleGuid + Documents = cenv.documents.EntriesAsArray + Methods = cenv.pdbinfo.ToArray() + TableRowCounts = cenv.tables |> Seq.map(fun t -> t.Count) |> Seq.toArray } + + let idxForNextedTypeDef (tds: ILTypeDef list, td: ILTypeDef) = + let enc = tds |> List.map (fun td -> td.Name) + GetIdxForTypeDef cenv (TdKey(enc, td.Name)) + + let strings = Array.map Bytes.stringAsUtf8NullTerminated cenv.strings.EntriesAsArray + let userStrings = cenv.userStrings.EntriesAsArray |> Array.map System.Text.Encoding.Unicode.GetBytes + let blobs = cenv.blobs.EntriesAsArray + let guids = cenv.guids.EntriesAsArray + let tables = cenv.tables + let code = cenv.GetCode() + // turn idx tbls into token maps + let mappings = + { TypeDefTokenMap = (fun t -> + getUncodedToken TableNames.TypeDef (idxForNextedTypeDef t)) + FieldDefTokenMap = (fun t fd -> + let tidx = idxForNextedTypeDef t + getUncodedToken TableNames.Field (GetFieldDefAsFieldDefIdx cenv tidx fd)) + MethodDefTokenMap = (fun t md -> + let tidx = idxForNextedTypeDef t + getUncodedToken TableNames.Method (FindMethodDefIdx cenv (GetKeyForMethodDef cenv tidx md))) + PropertyTokenMap = (fun t pd -> + let tidx = idxForNextedTypeDef t + getUncodedToken TableNames.Property (cenv.propertyDefs.GetTableEntry (GetKeyForPropertyDef tidx pd))) + EventTokenMap = (fun t ed -> + let tidx = idxForNextedTypeDef t + getUncodedToken TableNames.Event (cenv.eventDefs.GetTableEntry (EventKey (tidx, ed.Name)))) } + reportTime cenv.showTimes "Finalize Module Generation Results" + // New return the results + let data = cenv.data.AsMemory().ToArray() + let resources = cenv.resources.AsMemory().ToArray() + (strings, userStrings, blobs, guids, tables, entryPointToken, code, cenv.requiredStringFixups, data, resources, pdbData, mappings) + + +//===================================================================== +// TABLES+BLOBS --> PHYSICAL METADATA+BLOBS +//===================================================================== +let chunk sz next = ({addr=next; size=sz}, next + sz) +let emptychunk next = ({addr=next; size=0}, next) +let nochunk next = ({addr= 0x0;size= 0x0; }, next) + +let count f arr = + Array.fold (fun x y -> x + f y) 0x0 arr + +module FileSystemUtilities = + open System.Reflection + open System.Globalization + let progress = try Environment.GetEnvironmentVariable("FSharp_DebugSetFilePermissions") <> null with _ -> false + let setExecutablePermission (filename: string) = + +#if ENABLE_MONO_SUPPORT + if runningOnMono then + try + let monoPosix = Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756") + if progress then eprintf "loading type Mono.Unix.UnixFileInfo...\n" + let monoUnixFileInfo = monoPosix.GetType("Mono.Unix.UnixFileSystemInfo") + let fileEntry = monoUnixFileInfo.InvokeMember("GetFileSystemEntry", (BindingFlags.InvokeMethod ||| BindingFlags.Static ||| BindingFlags.Public), null, null, [| box filename |], CultureInfo.InvariantCulture) + let prevPermissions = monoUnixFileInfo.InvokeMember("get_FileAccessPermissions", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, fileEntry, [| |], CultureInfo.InvariantCulture) + let prevPermissionsValue = prevPermissions |> unbox + let newPermissionsValue = prevPermissionsValue ||| 0x000001ED + let newPermissions = Enum.ToObject(prevPermissions.GetType(), newPermissionsValue) + // Add 0x000001ED (UserReadWriteExecute, GroupReadExecute, OtherReadExecute) to the access permissions on Unix + monoUnixFileInfo.InvokeMember("set_FileAccessPermissions", (BindingFlags.InvokeMethod ||| BindingFlags.Instance ||| BindingFlags.Public), null, fileEntry, [| newPermissions |], CultureInfo.InvariantCulture) |> ignore + with e -> + if progress then eprintf "failure: %s...\n" (e.ToString()) + // Fail silently + else +#else + ignore filename +#endif + () + +/// Arbitrary value +[] +let TableCapacity = 20000 +/// Arbitrary value +[] +let MetadataCapacity = 500000 + +let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs = + + // When we know the real RVAs of the data section we fixup the references for the FieldRVA table. + // These references are stored as offsets into the metadata we return from this function + let requiredDataFixups = ref [] + + let next = cilStartAddress + + let strings, userStrings, blobs, guids, tables, entryPointToken, code, requiredStringFixups, data, resources, pdbData, mappings = + generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress normalizeAssemblyRefs + + reportTime showTimes "Generated Tables and Code" + let tableSize (tab: TableName) = tables.[tab.Index].Count + + // Now place the code + let codeSize = code.Length + let alignedCodeSize = align 0x4 codeSize + let codep, next = chunk codeSize next + let codePadding = Array.create (alignedCodeSize - codeSize) 0x0uy + let _codePaddingChunk, next = chunk codePadding.Length next + + // Now layout the chunks of metadata and IL + let metadataHeaderStartChunk, _next = chunk 0x10 next + + let numStreams = 0x05 + + let mdtableVersionMajor, mdtableVersionMinor = metadataSchemaVersionSupportedByCLRVersion desiredMetadataVersion + + let version = + System.Text.Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" desiredMetadataVersion.Major desiredMetadataVersion.Minor desiredMetadataVersion.Build) + + + let paddedVersionLength = align 0x4 (Array.length version) + + // Most addresses after this point are measured from the MD root + // Switch to md-rooted addresses + let next = metadataHeaderStartChunk.size + let _metadataHeaderVersionChunk, next = chunk paddedVersionLength next + let _metadataHeaderEndChunk, next = chunk 0x04 next + let _tablesStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#~".Length + 0x01))) next + let _stringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Strings".Length + 0x01))) next + let _userStringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#US".Length + 0x01))) next + let _guidsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#GUID".Length + 0x01))) next + let _blobsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Blob".Length + 0x01))) next + + let tablesStreamStart = next + + let stringsStreamUnpaddedSize = count (fun (s: byte[]) -> s.Length) strings + 1 + let stringsStreamPaddedSize = align 4 stringsStreamUnpaddedSize + + let userStringsStreamUnpaddedSize = count (fun (s: byte[]) -> let n = s.Length + 1 in n + ByteBuffer.Z32Size n) userStrings + 1 + let userStringsStreamPaddedSize = align 4 userStringsStreamUnpaddedSize + + let guidsStreamUnpaddedSize = (Array.length guids) * 0x10 + let guidsStreamPaddedSize = align 4 guidsStreamUnpaddedSize + + let blobsStreamUnpaddedSize = count (fun (blob: byte[]) -> let n = blob.Length in n + ByteBuffer.Z32Size n) blobs + 1 + let blobsStreamPaddedSize = align 4 blobsStreamUnpaddedSize + + let guidsBig = guidsStreamPaddedSize >= 0x10000 + let stringsBig = stringsStreamPaddedSize >= 0x10000 + let blobsBig = blobsStreamPaddedSize >= 0x10000 + + // 64bit bitvector indicating which tables are in the metadata. + let (valid1, valid2), _ = + (((0, 0), 0), tables) ||> Array.fold (fun (valid1, valid2 as valid, n) rows -> + let valid = + if rows.Count = 0 then valid else + ( (if n < 32 then valid1 ||| (1 <<< n ) else valid1), + (if n >= 32 then valid2 ||| (1 <<< (n-32)) else valid2) ) + (valid, n+1)) + + // 64bit bitvector indicating which tables are sorted. + // Constant - REVIEW: make symbolic! compute from sorted table info! + let sorted1 = 0x3301fa00 + let sorted2 = + // If there are any generic parameters in the binary we're emitting then mark that + // table as sorted, otherwise don't. This maximizes the number of assemblies we emit + // which have an ECMA-v.1. compliant set of sorted tables. + (if tableSize TableNames.GenericParam > 0 then 0x00000400 else 0x00000000) ||| + (if tableSize TableNames.GenericParamConstraint > 0 then 0x00001000 else 0x00000000) ||| + 0x00000200 + + reportTime showTimes "Layout Header of Tables" + + let guidAddress n = (if n = 0 then 0 else (n - 1) * 0x10 + 0x01) + + let stringAddressTable = + let tab = Array.create (strings.Length + 1) 0 + let mutable pos = 1 + for i = 1 to strings.Length do + tab.[i] <- pos + let s = strings.[i - 1] + pos <- pos + s.Length + tab + + let stringAddress n = + if n >= Array.length stringAddressTable then failwith ("string index "+string n+" out of range") + stringAddressTable.[n] + + let userStringAddressTable = + let tab = Array.create (Array.length userStrings + 1) 0 + let mutable pos = 1 + for i = 1 to Array.length userStrings do + tab.[i] <- pos + let s = userStrings.[i - 1] + let n = s.Length + 1 + pos <- pos + n + ByteBuffer.Z32Size n + tab + + let userStringAddress n = + if n >= Array.length userStringAddressTable then failwith "userString index out of range" + userStringAddressTable.[n] + + let blobAddressTable = + let tab = Array.create (blobs.Length + 1) 0 + let mutable pos = 1 + for i = 1 to blobs.Length do + tab.[i] <- pos + let blob = blobs.[i - 1] + pos <- pos + blob.Length + ByteBuffer.Z32Size blob.Length + tab + + let blobAddress n = + if n >= blobAddressTable.Length then failwith "blob index out of range" + blobAddressTable.[n] + + reportTime showTimes "Build String/Blob Address Tables" + + let sortedTables = + Array.init 64 (fun i -> + let tab = tables.[i] + let tabName = TableName.FromIndex i + let rows = tab.GenericRowsOfTable + if TableRequiresSorting tabName then SortTableRows tabName rows else rows) + + reportTime showTimes "Sort Tables" + + let codedTables = + + let bignessTable = Array.map (fun rows -> Array.length rows >= 0x10000) sortedTables + let bigness (tab: int32) = bignessTable.[tab] + + let codedBigness nbits tab = + (tableSize tab) >= (0x10000 >>> nbits) + + let tdorBigness = + codedBigness 2 TableNames.TypeDef || + codedBigness 2 TableNames.TypeRef || + codedBigness 2 TableNames.TypeSpec + + let tomdBigness = + codedBigness 1 TableNames.TypeDef || + codedBigness 1 TableNames.Method + + let hcBigness = + codedBigness 2 TableNames.Field || + codedBigness 2 TableNames.Param || + codedBigness 2 TableNames.Property + + let hcaBigness = + codedBigness 5 TableNames.Method || + codedBigness 5 TableNames.Field || + codedBigness 5 TableNames.TypeRef || + codedBigness 5 TableNames.TypeDef || + codedBigness 5 TableNames.Param || + codedBigness 5 TableNames.InterfaceImpl || + codedBigness 5 TableNames.MemberRef || + codedBigness 5 TableNames.Module || + codedBigness 5 TableNames.Permission || + codedBigness 5 TableNames.Property || + codedBigness 5 TableNames.Event || + codedBigness 5 TableNames.StandAloneSig || + codedBigness 5 TableNames.ModuleRef || + codedBigness 5 TableNames.TypeSpec || + codedBigness 5 TableNames.Assembly || + codedBigness 5 TableNames.AssemblyRef || + codedBigness 5 TableNames.File || + codedBigness 5 TableNames.ExportedType || + codedBigness 5 TableNames.ManifestResource || + codedBigness 5 TableNames.GenericParam || + codedBigness 5 TableNames.GenericParamConstraint || + codedBigness 5 TableNames.MethodSpec + + + let hfmBigness = + codedBigness 1 TableNames.Field || + codedBigness 1 TableNames.Param + + let hdsBigness = + codedBigness 2 TableNames.TypeDef || + codedBigness 2 TableNames.Method || + codedBigness 2 TableNames.Assembly + + let mrpBigness = + codedBigness 3 TableNames.TypeRef || + codedBigness 3 TableNames.ModuleRef || + codedBigness 3 TableNames.Method || + codedBigness 3 TableNames.TypeSpec + + let hsBigness = + codedBigness 1 TableNames.Event || + codedBigness 1 TableNames.Property + + let mdorBigness = + codedBigness 1 TableNames.Method || + codedBigness 1 TableNames.MemberRef + + let mfBigness = + codedBigness 1 TableNames.Field || + codedBigness 1 TableNames.Method + + let iBigness = + codedBigness 2 TableNames.File || + codedBigness 2 TableNames.AssemblyRef || + codedBigness 2 TableNames.ExportedType + + let catBigness = + codedBigness 3 TableNames.Method || + codedBigness 3 TableNames.MemberRef + + let rsBigness = + codedBigness 2 TableNames.Module || + codedBigness 2 TableNames.ModuleRef || + codedBigness 2 TableNames.AssemblyRef || + codedBigness 2 TableNames.TypeRef + + use tablesBuf = ByteBuffer.Create(TableCapacity, useArrayPool = true) + + // Now the coded tables themselves - first the schemata header + tablesBuf.EmitIntsAsBytes + [| 0x00; 0x00; 0x00; 0x00 + mdtableVersionMajor // major version of table schemata + mdtableVersionMinor // minor version of table schemata + + ((if stringsBig then 0x01 else 0x00) ||| // bit vector for heap size + (if guidsBig then 0x02 else 0x00) ||| + (if blobsBig then 0x04 else 0x00)) + 0x01 (* reserved, always 1 *) |] + + tablesBuf.EmitInt32 valid1 + tablesBuf.EmitInt32 valid2 + tablesBuf.EmitInt32 sorted1 + tablesBuf.EmitInt32 sorted2 + + // Numbers of rows in various tables + for rows in sortedTables do + if rows.Length <> 0 then + tablesBuf.EmitInt32 rows.Length + + + reportTime showTimes "Write Header of tablebuf" + + // The tables themselves + for rows in sortedTables do + for row in rows do + for x in row do + // Emit the coded token for the array element + let t = x.Tag + let n = x.Val + match t with + | _ when t = RowElementTags.UShort -> tablesBuf.EmitUInt16 (uint16 n) + | _ when t = RowElementTags.ULong -> tablesBuf.EmitInt32 n + | _ when t = RowElementTags.Data -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, false) + | _ when t = RowElementTags.DataResources -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, true) + | _ when t = RowElementTags.Guid -> tablesBuf.EmitZUntaggedIndex guidsBig (guidAddress n) + | _ when t = RowElementTags.Blob -> tablesBuf.EmitZUntaggedIndex blobsBig (blobAddress n) + | _ when t = RowElementTags.String -> tablesBuf.EmitZUntaggedIndex stringsBig (stringAddress n) + | _ when t <= RowElementTags.SimpleIndexMax -> tablesBuf.EmitZUntaggedIndex (bigness (t - RowElementTags.SimpleIndexMin)) n + | _ when t <= RowElementTags.TypeDefOrRefOrSpecMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeDefOrRefOrSpecMin) 2 tdorBigness n + | _ when t <= RowElementTags.TypeOrMethodDefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeOrMethodDefMin) 1 tomdBigness n + | _ when t <= RowElementTags.HasConstantMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasConstantMin) 2 hcBigness n + | _ when t <= RowElementTags.HasCustomAttributeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasCustomAttributeMin) 5 hcaBigness n + | _ when t <= RowElementTags.HasFieldMarshalMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasFieldMarshalMin) 1 hfmBigness n + | _ when t <= RowElementTags.HasDeclSecurityMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasDeclSecurityMin) 2 hdsBigness n + | _ when t <= RowElementTags.MemberRefParentMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberRefParentMin) 3 mrpBigness n + | _ when t <= RowElementTags.HasSemanticsMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasSemanticsMin) 1 hsBigness n + | _ when t <= RowElementTags.MethodDefOrRefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MethodDefOrRefMin) 1 mdorBigness n + | _ when t <= RowElementTags.MemberForwardedMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberForwardedMin) 1 mfBigness n + | _ when t <= RowElementTags.ImplementationMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ImplementationMin) 2 iBigness n + | _ when t <= RowElementTags.CustomAttributeTypeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.CustomAttributeTypeMin) 3 catBigness n + | _ when t <= RowElementTags.ResolutionScopeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ResolutionScopeMin) 2 rsBigness n + | _ -> failwith "invalid tag in row element" + + tablesBuf.AsMemory().ToArray() + + reportTime showTimes "Write Tables to tablebuf" + + let tablesStreamUnpaddedSize = codedTables.Length + // QUERY: extra 4 empty bytes in array.exe - why? Include some extra padding after + // the tables just in case there is a mistake in the ECMA spec. + let tablesStreamPaddedSize = align 4 (tablesStreamUnpaddedSize + 4) + let tablesChunk, next = chunk tablesStreamPaddedSize next + let tablesStreamPadding = tablesChunk.size - tablesStreamUnpaddedSize + + let stringsChunk, next = chunk stringsStreamPaddedSize next + let stringsStreamPadding = stringsChunk.size - stringsStreamUnpaddedSize + let userStringsChunk, next = chunk userStringsStreamPaddedSize next + let userStringsStreamPadding = userStringsChunk.size - userStringsStreamUnpaddedSize + let guidsChunk, next = chunk (0x10 * guids.Length) next + let blobsChunk, _next = chunk blobsStreamPaddedSize next + let blobsStreamPadding = blobsChunk.size - blobsStreamUnpaddedSize + + reportTime showTimes "Layout Metadata" + + let metadata, guidStart = + use mdbuf = ByteBuffer.Create(MetadataCapacity, useArrayPool = true) + mdbuf.EmitIntsAsBytes + [| 0x42; 0x53; 0x4a; 0x42 // Magic signature + 0x01; 0x00 // Major version + 0x01; 0x00 // Minor version + |] + mdbuf.EmitInt32 0x0 // Reserved + + mdbuf.EmitInt32 paddedVersionLength + mdbuf.EmitBytes version + for i = 1 to (paddedVersionLength - Array.length version) do + mdbuf.EmitIntAsByte 0x00 + + mdbuf.EmitBytes + [| 0x00uy; 0x00uy // flags, reserved + b0 numStreams; b1 numStreams; |] + mdbuf.EmitInt32 tablesChunk.addr + mdbuf.EmitInt32 tablesChunk.size + mdbuf.EmitIntsAsBytes [| 0x23; 0x7e; 0x00; 0x00; (* #~00 *)|] + mdbuf.EmitInt32 stringsChunk.addr + mdbuf.EmitInt32 stringsChunk.size + mdbuf.EmitIntsAsBytes [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; 0x00; 0x00; 0x00; 0x00 (* "#Strings0000" *)|] + mdbuf.EmitInt32 userStringsChunk.addr + mdbuf.EmitInt32 userStringsChunk.size + mdbuf.EmitIntsAsBytes [| 0x23; 0x55; 0x53; 0x00; (* #US0*) |] + mdbuf.EmitInt32 guidsChunk.addr + mdbuf.EmitInt32 guidsChunk.size + mdbuf.EmitIntsAsBytes [| 0x23; 0x47; 0x55; 0x49; 0x44; 0x00; 0x00; 0x00; (* #GUID000 *)|] + mdbuf.EmitInt32 blobsChunk.addr + mdbuf.EmitInt32 blobsChunk.size + mdbuf.EmitIntsAsBytes [| 0x23; 0x42; 0x6c; 0x6f; 0x62; 0x00; 0x00; 0x00; (* #Blob000 *)|] + + reportTime showTimes "Write Metadata Header" + // Now the coded tables themselves + mdbuf.EmitBytes codedTables + for i = 1 to tablesStreamPadding do + mdbuf.EmitIntAsByte 0x00 + reportTime showTimes "Write Metadata Tables" + + // The string stream + mdbuf.EmitByte 0x00uy + for s in strings do + mdbuf.EmitBytes s + for i = 1 to stringsStreamPadding do + mdbuf.EmitIntAsByte 0x00 + reportTime showTimes "Write Metadata Strings" + // The user string stream + mdbuf.EmitByte 0x00uy + for s in userStrings do + mdbuf.EmitZ32 (s.Length + 1) + mdbuf.EmitBytes s + mdbuf.EmitIntAsByte (markerForUnicodeBytes s) + for i = 1 to userStringsStreamPadding do + mdbuf.EmitIntAsByte 0x00 + + reportTime showTimes "Write Metadata User Strings" + // The GUID stream + let guidStart = mdbuf.Position + Array.iter mdbuf.EmitBytes guids + + // The blob stream + mdbuf.EmitByte 0x00uy + for s in blobs do + mdbuf.EmitZ32 s.Length + mdbuf.EmitBytes s + for i = 1 to blobsStreamPadding do + mdbuf.EmitIntAsByte 0x00 + reportTime showTimes "Write Blob Stream" + // Done - close the buffer and return the result. + mdbuf.AsMemory().ToArray(), guidStart + + + // Now we know the user string tables etc. we can fixup the + // uses of strings in the code + for codeStartAddr, l in requiredStringFixups do + for codeOffset, userStringIndex in l do + if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then + failwith "strings-in-code fixup: a group of fixups is located outside the code array" + let locInCode = ((codeStartAddr + codeOffset) - codep.addr) + checkFixup32 code locInCode 0xdeadbeef + let token = getUncodedToken TableNames.UserStrings (userStringAddress userStringIndex) + if (Bytes.get code (locInCode-1) <> i_ldstr) then failwith "strings-in-code fixup: not at ldstr instruction!" + applyFixup32 code locInCode token + reportTime showTimes "Fixup Metadata" + + entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups.Value, pdbData, mappings, guidStart + +//--------------------------------------------------------------------- +// PHYSICAL METADATA+BLOBS --> PHYSICAL PE FORMAT +//--------------------------------------------------------------------- + +// THIS LAYS OUT A 2-SECTION .NET PE BINARY +// SECTIONS +// TEXT: physical 0x0200 --> RVA 0x00020000 +// e.g. raw size 0x9600, +// e.g. virt size 0x9584 +// RELOC: physical 0x9800 --> RVA 0x0000c000 +// i.e. physbase --> rvabase +// where physbase = textbase + text raw size +// phsrva = roundup(0x2000, 0x0002000 + text virt size) + +let msdosHeader : byte[] = + [| 0x4duy; 0x5auy; 0x90uy; 0x00uy; 0x03uy; 0x00uy; 0x00uy; 0x00uy + 0x04uy; 0x00uy; 0x00uy; 0x00uy; 0xFFuy; 0xFFuy; 0x00uy; 0x00uy + 0xb8uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x40uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy + 0x0euy; 0x1fuy; 0xbauy; 0x0euy; 0x00uy; 0xb4uy; 0x09uy; 0xcduy + 0x21uy; 0xb8uy; 0x01uy; 0x4cuy; 0xcduy; 0x21uy; 0x54uy; 0x68uy + 0x69uy; 0x73uy; 0x20uy; 0x70uy; 0x72uy; 0x6fuy; 0x67uy; 0x72uy + 0x61uy; 0x6duy; 0x20uy; 0x63uy; 0x61uy; 0x6euy; 0x6euy; 0x6fuy + 0x74uy; 0x20uy; 0x62uy; 0x65uy; 0x20uy; 0x72uy; 0x75uy; 0x6euy + 0x20uy; 0x69uy; 0x6euy; 0x20uy; 0x44uy; 0x4fuy; 0x53uy; 0x20uy + 0x6duy; 0x6fuy; 0x64uy; 0x65uy; 0x2euy; 0x0duy; 0x0duy; 0x0auy + 0x24uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] + +let writeInt64 (os: BinaryWriter) x = + os.Write (dw0 x) + os.Write (dw1 x) + os.Write (dw2 x) + os.Write (dw3 x) + os.Write (dw4 x) + os.Write (dw5 x) + os.Write (dw6 x) + os.Write (dw7 x) + +let writeInt32 (os: BinaryWriter) x = + os.Write (byte (b0 x)) + os.Write (byte (b1 x)) + os.Write (byte (b2 x)) + os.Write (byte (b3 x)) + +let writeInt32AsUInt16 (os: BinaryWriter) x = + os.Write (byte (b0 x)) + os.Write (byte (b1 x)) + +let writeDirectory os dict = + writeInt32 os (if dict.size = 0x0 then 0x0 else dict.addr) + writeInt32 os dict.size + +let writeBytes (os: BinaryWriter) (chunk: byte[]) = os.Write(chunk, 0, chunk.Length) + +let rec writeBinaryAndReportMappings (outfile, + ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, + embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, dumpDebugInfo, pathMap) + modul normalizeAssemblyRefs = + + let stream = + try + // Ensure the output directory exists otherwise it will fail + let dir = FileSystem.GetDirectoryNameShim outfile + if not (FileSystem.DirectoryExistsShim dir) then FileSystem.DirectoryCreateShim dir |> ignore + FileSystem.OpenFileForWriteShim(outfile, FileMode.Create, FileAccess.Write, FileShare.Read) + with _ -> + failwith ("Could not open file for writing (binary mode): " + outfile) + + let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings = + try + let res = writeBinaryAndReportMappingsAux(stream, false, ilg, pdbfile, signer, portablePDB, embeddedPDB, embedAllSource, embedSourceList, sourceLink, + checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) modul normalizeAssemblyRefs + + try + FileSystemUtilities.setExecutablePermission outfile + with _ -> + () + + res + with + | _ -> + try FileSystem.FileDeleteShim outfile with | _ -> () + reraise() + + writePdb + (dumpDebugInfo, showTimes, portablePDB, embeddedPDB, pdbfile, outfile, signer, deterministic, pathMap) + (pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings) + +and writeBinaryWithNoPdb (stream: Stream, + ilg: ILGlobals, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, + embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) + modul normalizeAssemblyRefs = + + writeBinaryAndReportMappingsAux(stream, true, ilg, None, signer, portablePDB, embeddedPDB, embedAllSource, embedSourceList, sourceLink, + checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) modul normalizeAssemblyRefs + |> ignore + +and writeBinaryAndReportMappingsAux (stream: Stream, leaveStreamOpen: bool, + ilg: ILGlobals, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, + embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, emitTailcalls, deterministic, showTimes, pathMap) + modul normalizeAssemblyRefs = + // Store the public key from the signer into the manifest. This means it will be written + // to the binary and also acts as an indicator to leave space for delay sign + + reportTime showTimes "Write Started" + let isDll = modul.IsDLL + + let signer = + match signer, modul.Manifest with + | Some _, _ -> signer + | _, None -> signer + | None, Some {PublicKey=Some pubkey} -> + (dprintn "Note: The output assembly will be delay-signed using the original public" + dprintn "Note: key. In order to load it you will need to either sign it with" + dprintn "Note: the original private key or to turn off strong-name verification" + dprintn "Note: (use sn.exe from the .NET Framework SDK to do this, e.g. 'sn -Vr *')." + dprintn "Note: Alternatively if this tool supports it you can provide the original" + dprintn "Note: private key when converting the assembly, assuming you have access to" + dprintn "Note: it." + Some (ILStrongNameSigner.OpenPublicKey pubkey)) + | _ -> signer + + let modul = + let pubkey = + match signer with + | None -> None + | Some s -> + try Some s.PublicKey + with e -> + failwith ("A call to StrongNameGetPublicKey failed ("+e.Message+")") + None + begin match modul.Manifest with + | None -> () + | Some m -> + if m.PublicKey <> None && m.PublicKey <> pubkey then + dprintn "Warning: The output assembly is being signed or delay-signed with a strong name that is different to the original." + end + { modul with Manifest = match modul.Manifest with None -> None | Some m -> Some {m with PublicKey = pubkey} } + + let os = new BinaryWriter(stream, System.Text.Encoding.UTF8, leaveOpen=leaveStreamOpen) + + let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings = + try + + let imageBaseReal = modul.ImageBase // FIXED CHOICE + let alignVirt = modul.VirtualAlignment // FIXED CHOICE + let alignPhys = modul.PhysicalAlignment // FIXED CHOICE + + let isItanium = modul.Platform = Some IA64 + + let numSections = 3 // .text, .sdata, .reloc + + + // HEADERS + let next = 0x0 + let headerSectionPhysLoc = 0x0 + let headerAddr = next + let next = headerAddr + + let msdosHeaderSize = 0x80 + let msdosHeaderChunk, next = chunk msdosHeaderSize next + + let peSignatureSize = 0x04 + let peSignatureChunk, next = chunk peSignatureSize next + + let peFileHeaderSize = 0x14 + let peFileHeaderChunk, next = chunk peFileHeaderSize next + + let peOptionalHeaderSize = if modul.Is64Bit then 0xf0 else 0xe0 + let peOptionalHeaderChunk, next = chunk peOptionalHeaderSize next + + let textSectionHeaderSize = 0x28 + let textSectionHeaderChunk, next = chunk textSectionHeaderSize next + + let dataSectionHeaderSize = 0x28 + let dataSectionHeaderChunk, next = chunk dataSectionHeaderSize next + + let relocSectionHeaderSize = 0x28 + let relocSectionHeaderChunk, next = chunk relocSectionHeaderSize next + + let headerSize = next - headerAddr + let nextPhys = align alignPhys (headerSectionPhysLoc + headerSize) + let headerSectionPhysSize = nextPhys - headerSectionPhysLoc + let next = align alignVirt (headerAddr + headerSize) + + // TEXT SECTION: 8 bytes IAT table 72 bytes CLI header + + let textSectionPhysLoc = nextPhys + let textSectionAddr = next + let next = textSectionAddr + + let importAddrTableChunk, next = chunk 0x08 next + let cliHeaderPadding = (if isItanium then (align 16 next) else next) - next + let next = next + cliHeaderPadding + let cliHeaderChunk, next = chunk 0x48 next + + let desiredMetadataVersion = + if modul.MetadataVersion <> "" then + parseILVersion modul.MetadataVersion + else + match ilg.primaryAssemblyScopeRef with + | ILScopeRef.Local -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Local" + | ILScopeRef.Module _ -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module" + | ILScopeRef.PrimaryAssembly -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.PrimaryAssembly" + | ILScopeRef.Assembly aref -> + match aref.Version with + | Some version when version.Major = 2us -> parseILVersion "2.0.50727.0" + | Some v -> v + | None -> failwith "Expected mscorlib to have a version number" + + let entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups, pdbData, mappings, guidStart = + writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul next normalizeAssemblyRefs + + reportTime showTimes "Generated IL and metadata" + let _codeChunk, next = chunk code.Length next + let _codePaddingChunk, next = chunk codePadding.Length next + + let metadataChunk, next = chunk metadata.Length next + + let strongnameChunk, next = + match signer with + | None -> nochunk next + | Some s -> chunk s.SignatureSize next + + let resourcesChunk, next = chunk resources.Length next + + let rawdataChunk, next = chunk data.Length next + + let vtfixupsChunk, next = nochunk next // Note: only needed for mixed mode assemblies + let importTableChunkPrePadding = (if isItanium then (align 16 next) else next) - next + let next = next + importTableChunkPrePadding + let importTableChunk, next = chunk 0x28 next + let importLookupTableChunk, next = chunk 0x14 next + let importNameHintTableChunk, next = chunk 0x0e next + let mscoreeStringChunk, next = chunk 0x0c next + + let next = align 0x10 (next + 0x05) - 0x05 + let importTableChunk = { addr=importTableChunk.addr; size = next - importTableChunk.addr} + let importTableChunkPadding = importTableChunk.size - (0x28 + 0x14 + 0x0e + 0x0c) + + let next = next + 0x03 + let entrypointCodeChunk, next = chunk 0x06 next + let globalpointerCodeChunk, next = chunk (if isItanium then 0x8 else 0x0) next + + let pdbOpt = + match portablePDB with + | true -> + let uncompressedLength, contentId, stream, algorithmName, checkSum as pdbStream = + generatePortablePdb embedAllSource embedSourceList sourceLink checksumAlgorithm showTimes pdbData pathMap + + if embeddedPDB then + let uncompressedLength, contentId, stream = compressPortablePdbStream uncompressedLength contentId stream + Some (uncompressedLength, contentId, stream, algorithmName, checkSum) + else Some pdbStream + + | _ -> None + + let debugDirectoryChunk, next = + chunk (if pdbfile = None then + 0x0 + else + sizeof_IMAGE_DEBUG_DIRECTORY * 2 + + (if embeddedPDB then sizeof_IMAGE_DEBUG_DIRECTORY else 0) + + (if deterministic then sizeof_IMAGE_DEBUG_DIRECTORY else 0) + ) next + + // The debug data is given to us by the PDB writer and appears to + // typically be the type of the data plus the PDB file name. We fill + // this in after we've written the binary. We approximate the size according + // to what PDB writers seem to require and leave extra space just in case... + let debugDataJustInCase = 40 + let debugDataChunk, next = + chunk (align 0x4 (match pdbfile with + | None -> 0 + | Some f -> (24 + + System.Text.Encoding.Unicode.GetByteCount f // See bug 748444 + + debugDataJustInCase))) next + + let debugChecksumPdbChunk, next = + chunk (align 0x4 (match pdbOpt with + | Some (_, _, _, algorithmName, checkSum) -> + let alg = System.Text.Encoding.UTF8.GetBytes(algorithmName) + let size = alg.Length + 1 + checkSum.Length + size + | None -> 0)) next + + let debugEmbeddedPdbChunk, next = + if embeddedPDB then + let streamLength = + match pdbOpt with + | Some (_, _, stream, _, _) -> int stream.Length + | None -> 0 + chunk (align 0x4 (match embeddedPDB with + | true -> 8 + streamLength + | _ -> 0 )) next + else + nochunk next + + let debugDeterministicPdbChunk, next = + if deterministic then emptychunk next + else nochunk next + + + let textSectionSize = next - textSectionAddr + let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) + let textSectionPhysSize = nextPhys - textSectionPhysLoc + let next = align alignVirt (textSectionAddr + textSectionSize) + + // .RSRC SECTION (DATA) + let dataSectionPhysLoc = nextPhys + let dataSectionAddr = next + let dataSectionVirtToPhys v = v - dataSectionAddr + dataSectionPhysLoc + let nativeResources = + match modul.NativeResources with + | [] -> [||] + | resources -> + let unlinkedResources = + resources |> List.map (function + | ILNativeResource.Out bytes -> bytes + | ILNativeResource.In (fileName, linkedResourceBase, start, len) -> + use stream = FileSystem.OpenFileForReadShim(fileName) + let linkedResource = stream.ReadBytes(start, len) + unlinkResource linkedResourceBase linkedResource) + + begin + try linkNativeResources unlinkedResources next + with e -> failwith ("Linking a native resource failed: "+e.Message+"") + end + + let nativeResourcesSize = nativeResources.Length + + let nativeResourcesChunk, next = chunk nativeResourcesSize next + + let dummydatap, next = chunk (if next = dataSectionAddr then 0x01 else 0x0) next + + let dataSectionSize = next - dataSectionAddr + let nextPhys = align alignPhys (dataSectionPhysLoc + dataSectionSize) + let dataSectionPhysSize = nextPhys - dataSectionPhysLoc + let next = align alignVirt (dataSectionAddr + dataSectionSize) + + // .RELOC SECTION base reloc table: 0x0c size + let relocSectionPhysLoc = nextPhys + let relocSectionAddr = next + let baseRelocTableChunk, next = chunk 0x0c next + + let relocSectionSize = next - relocSectionAddr + let nextPhys = align alignPhys (relocSectionPhysLoc + relocSectionSize) + let relocSectionPhysSize = nextPhys - relocSectionPhysLoc + let next = align alignVirt (relocSectionAddr + relocSectionSize) + + // Now we know where the data section lies we can fix up the + // references into the data section from the metadata tables. + begin + requiredDataFixups |> List.iter + (fun (metadataOffset32, (dataOffset, kind)) -> + let metadataOffset = metadataOffset32 + if metadataOffset < 0 || metadataOffset >= metadata.Length - 4 then failwith "data RVA fixup: fixup located outside metadata" + checkFixup32 metadata metadataOffset 0xdeaddddd + let dataRva = + if kind then + let res = dataOffset + if res >= resourcesChunk.size then dprintn "resource offset bigger than resource data section" + res + else + let res = rawdataChunk.addr + dataOffset + if res < rawdataChunk.addr then dprintn "data rva before data section" + if res >= rawdataChunk.addr + rawdataChunk.size then + dprintn ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr + + ", rawdataChunk.size = "+string rawdataChunk.size) + res + applyFixup32 metadata metadataOffset dataRva) + end + + // IMAGE TOTAL SIZE + let imageEndSectionPhysLoc = nextPhys + let imageEndAddr = next + + reportTime showTimes "Layout image" + + let write p (os: BinaryWriter) chunkName chunk = + match p with + | None -> () + | Some pExpected -> + os.Flush() + let pCurrent = int32 os.BaseStream.Position + if pCurrent <> pExpected then + failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected) + writeBytes os chunk + + let writePadding (os: BinaryWriter) _comment sz = + if sz < 0 then failwith "writePadding: size < 0" + for i = 0 to sz - 1 do + os.Write 0uy + + // Now we've computed all the offsets, write the image + + write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader + + write (Some peSignatureChunk.addr) os "pe signature" [| |] + + writeInt32 os 0x4550 + + write (Some peFileHeaderChunk.addr) os "pe file header" [| |] + + if (modul.Platform = Some AMD64) then + writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64 + elif isItanium then + writeInt32AsUInt16 os 0x200 + else + writeInt32AsUInt16 os 0x014c // Machine - IMAGE_FILE_MACHINE_I386 + + writeInt32AsUInt16 os numSections + + let pdbData = + // Hash code, data and metadata + if deterministic then + use sha = + match checksumAlgorithm with + | HashAlgorithm.Sha1 -> System.Security.Cryptography.SHA1.Create() :> System.Security.Cryptography.HashAlgorithm + | HashAlgorithm.Sha256 -> System.Security.Cryptography.SHA256.Create() :> System.Security.Cryptography.HashAlgorithm + + let hCode = sha.ComputeHash code + let hData = sha.ComputeHash data + let hMeta = sha.ComputeHash metadata + let final = [| hCode; hData; hMeta |] |> Array.collect id |> sha.ComputeHash + + // Confirm we have found the correct data and aren't corrupting the metadata + if metadata.[ guidStart..guidStart+3] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + if metadata.[ guidStart+12..guidStart+15] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + + // Update MVID guid in metadata + Array.blit final 0 metadata guidStart 16 + + // Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused + let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24) + writeInt32 os timestamp + + // Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID + // Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-deterministic Windows native code + { pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp } + else + writeInt32 os timestamp // date since 1970 + pdbData + + writeInt32 os 0x00 // Pointer to Symbol Table Always 0 + // 00000090 + writeInt32 os 0x00 // Number of Symbols Always 0 + writeInt32AsUInt16 os peOptionalHeaderSize // Size of the optional header, the format is described below. + + // 64bit: IMAGE_FILE_32BIT_MACHINE ||| IMAGE_FILE_LARGE_ADDRESS_AWARE + // 32bit: IMAGE_FILE_32BIT_MACHINE + // Yes, 32BIT_MACHINE is set for AMD64... + let iMachineCharacteristic = match modul.Platform with | Some IA64 -> 0x20 | Some AMD64 -> 0x0120 | _ -> 0x0100 + + writeInt32AsUInt16 os ((if isDll then 0x2000 else 0x0000) ||| 0x0002 ||| 0x0004 ||| 0x0008 ||| iMachineCharacteristic) + + // Now comes optional header + + let peOptionalHeaderByte = peOptionalHeaderByteByCLRVersion desiredMetadataVersion + + write (Some peOptionalHeaderChunk.addr) os "pe optional header" [| |] + if modul.Is64Bit then + writeInt32AsUInt16 os 0x020B // Magic number is 0x020B for 64-bit + else + writeInt32AsUInt16 os 0x010b // Always 0x10B (see Section 23.1). + writeInt32AsUInt16 os peOptionalHeaderByte // ECMA spec says 6, some binaries, e.g. fscmanaged.exe say 7, Whidbey binaries say 8 + writeInt32 os textSectionPhysSize // Size of the code (text) section, or the sum of all code sections if there are multiple sections. + // 000000a0 + writeInt32 os dataSectionPhysSize // Size of the initialized data section + writeInt32 os 0x00 // Size of the uninitialized data section + writeInt32 os entrypointCodeChunk.addr // RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 + writeInt32 os textSectionAddr // e.g. 0x0002000 + // 000000b0 + if modul.Is64Bit then + writeInt64 os (int64 imageBaseReal) // REVIEW: For 64-bit, we should use a 64-bit image base + else + writeInt32 os dataSectionAddr // e.g. 0x0000c000 + writeInt32 os imageBaseReal // Image Base Always 0x400000 (see Section 23.1). - QUERY : no it's not always 0x400000, e.g. 0x034f0000 + + writeInt32 os alignVirt // Section Alignment Always 0x2000 (see Section 23.1). + writeInt32 os alignPhys // File Alignment Either 0x200 or 0x1000. + // 000000c0 + writeInt32AsUInt16 os 0x04 // OS Major Always 4 (see Section 23.1). + writeInt32AsUInt16 os 0x00 // OS Minor Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00 // User Major Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00 // User Minor Always 0 (see Section 23.1). + do + let major, minor = modul.SubsystemVersion + writeInt32AsUInt16 os major + writeInt32AsUInt16 os minor + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + // 000000d0 + writeInt32 os imageEndAddr // Image Size: Size, in bytes, of image, including all headers and padding + writeInt32 os headerSectionPhysSize // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding + writeInt32 os 0x00 // File Checksum Always 0 (see Section 23.1). QUERY: NOT ALWAYS ZERO + writeInt32AsUInt16 os modul.SubSystemFlags // SubSystem Subsystem required to run this image. + // DLL Flags Always 0x400 (no unmanaged windows exception handling - see Section 23.1). + // Itanium: see notes at end of file + // IMAGE_DLLCHARACTERISTICS_NX_COMPAT: See FSharp 1.0 bug 5019 and http://blogs.msdn.com/ed_maurer/archive/2007/12/14/nxcompat-and-the-c-compiler.aspx + // Itanium : IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE | IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x86 : IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x64 : IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + let dllCharacteristics = + let flags = + if modul.Is64Bit then (if isItanium then 0x8540 else 0x540) + else 0x540 + if modul.UseHighEntropyVA then flags ||| 0x20 // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA + else flags + writeInt32AsUInt16 os dllCharacteristics + // 000000e0 + // Note that the defaults differ between x86 and x64 + if modul.Is64Bit then + let size = defaultArg modul.StackReserveSize 0x400000 |> int64 + writeInt64 os size // Stack Reserve Size Always 0x400000 (4Mb) (see Section 23.1). + writeInt64 os 0x4000L // Stack Commit Size Always 0x4000 (16Kb) (see Section 23.1). + writeInt64 os 0x100000L // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt64 os 0x2000L // Heap Commit Size Always 0x800 (8Kb) (see Section 23.1). + else + let size = defaultArg modul.StackReserveSize 0x100000 + writeInt32 os size // Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). + writeInt32 os 0x100000 // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). + // 000000f0 - x86 location, moving on, for x64, add 0x10 + writeInt32 os 0x00 // Loader Flags Always 0 (see Section 23.1) + writeInt32 os 0x10 // Number of Data Directories: Always 0x10 (see Section 23.1). + writeInt32 os 0x00 + writeInt32 os 0x00 // Export Table Always 0 (see Section 23.1). + // 00000100 + writeDirectory os importTableChunk // Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 + // Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not. + writeDirectory os nativeResourcesChunk + + // 00000110 + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + // 00000120 + writeDirectory os baseRelocTableChunk + writeDirectory os debugDirectoryChunk // Debug Directory + // 00000130 + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + // 00000140 + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + // 00000150 + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeDirectory os importAddrTableChunk // Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 + // 00000160 + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeDirectory os cliHeaderChunk + // 00000170 + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + + write (Some textSectionHeaderChunk.addr) os "text section header" [| |] + + // 00000178 + writeBytes os [| 0x2euy; 0x74uy; 0x65uy; 0x78uy; 0x74uy; 0x00uy; 0x00uy; 0x00uy; |] // ".text\000\000\000" + // 00000180 + writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. + writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section + writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes + writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file. + // 00000190 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 00000198 + writeInt32AsUInt16 os 0x00// NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ + + write (Some dataSectionHeaderChunk.addr) os "data section header" [| |] + + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x73uy; 0x72uy; 0x63uy; 0x00uy; 0x00uy; 0x00uy; |] // ".rsrc\000\000\000" + // writeBytes os [| 0x2e; 0x73; 0x64; 0x61; 0x74; 0x61; 0x00; 0x00; |] // ".sdata\000\000" + writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. + writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section. + // 000001b0 + writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, + writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x40uy |] // Characteristics Flags: IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA + + write (Some relocSectionHeaderChunk.addr) os "reloc section header" [| |] + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x65uy; 0x6cuy; 0x6fuy; 0x63uy; 0x00uy; 0x00uy; |] // ".reloc\000\000" + writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. + writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section. + // 000001b0 + writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes + writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x42uy |] // Characteristics Flags: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | + + writePadding os "pad to text begin" (textSectionPhysLoc - headerSize) + + // TEXT SECTION: e.g. 0x200 + + let textV2P v = v - textSectionAddr + textSectionPhysLoc + + // e.g. 0x0200 + write (Some (textV2P importAddrTableChunk.addr)) os "import addr table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 // QUERY 4 bytes of zeros not 2 like ECMA 24.3.1 says + + // e.g. 0x0208 + + let flags = + (if modul.IsILOnly then 0x01 else 0x00) ||| + (if modul.Is32Bit then 0x02 else 0x00) ||| + (if modul.Is32BitPreferred then 0x00020003 else 0x00) ||| + (if (match signer with None -> false | Some s -> s.IsFullySigned) then 0x08 else 0x00) + + let headerVersionMajor, headerVersionMinor = headerVersionSupportedByCLRVersion desiredMetadataVersion + + writePadding os "pad to cli header" cliHeaderPadding + write (Some (textV2P cliHeaderChunk.addr)) os "cli header" [| |] + writeInt32 os 0x48 // size of header + writeInt32AsUInt16 os headerVersionMajor // Major part of minimum version of CLR reqd. + writeInt32AsUInt16 os headerVersionMinor // Minor part of minimum version of CLR reqd. ... + // e.g. 0x0210 + writeDirectory os metadataChunk + writeInt32 os flags + + writeInt32 os entryPointToken + write None os "rest of cli header" [| |] + + // e.g. 0x0220 + writeDirectory os resourcesChunk + writeDirectory os strongnameChunk + // e.g. 0x0230 + writeInt32 os 0x00 // code manager table, always 0 + writeInt32 os 0x00 // code manager table, always 0 + writeDirectory os vtfixupsChunk + // e.g. 0x0240 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // managed native header, always 0 + writeInt32 os 0x00 // managed native header, always 0 + + writeBytes os code + write None os "code padding" codePadding + + writeBytes os metadata + + // write 0x80 bytes of empty space for encrypted SHA1 hash, written by SN.EXE or call to signing API + if signer <> None then + write (Some (textV2P strongnameChunk.addr)) os "strongname" (Array.create strongnameChunk.size 0x0uy) + + write (Some (textV2P resourcesChunk.addr)) os "raw resources" [| |] + writeBytes os resources + write (Some (textV2P rawdataChunk.addr)) os "raw data" [| |] + writeBytes os data + + writePadding os "start of import table" importTableChunkPrePadding + + // vtfixups would go here + write (Some (textV2P importTableChunk.addr)) os "import table" [| |] + + writeInt32 os importLookupTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os mscoreeStringChunk.addr + writeInt32 os importAddrTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + write (Some (textV2P importLookupTableChunk.addr)) os "import lookup table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + + write (Some (textV2P importNameHintTableChunk.addr)) os "import name hint table" [| |] + // Two zero bytes of hint, then Case sensitive, null-terminated ASCII string containing name to import. + // Shall _CorExeMain a .exe file _CorDllMain for a .dll file. + if isDll then + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy ; 0x6fuy; 0x72uy; 0x44uy; 0x6cuy; 0x6cuy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + else + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy; 0x6fuy; 0x72uy; 0x45uy; 0x78uy; 0x65uy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + + write (Some (textV2P mscoreeStringChunk.addr)) os "mscoree string" + [| 0x6duy; 0x73uy; 0x63uy; 0x6fuy ; 0x72uy; 0x65uy ; 0x65uy; 0x2euy ; 0x64uy; 0x6cuy ; 0x6cuy; 0x00uy ; |] + + writePadding os "end of import tab" importTableChunkPadding + + writePadding os "head of entrypoint" 0x03 + let ep = (imageBaseReal + textSectionAddr) + write (Some (textV2P entrypointCodeChunk.addr)) os " entrypoint code" + [| 0xFFuy; 0x25uy; (* x86 Instructions for entry *) b0 ep; b1 ep; b2 ep; b3 ep |] + if isItanium then + write (Some (textV2P globalpointerCodeChunk.addr)) os " itanium global pointer" + [| 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy |] + + if pdbfile.IsSome then + write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy) + write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy) + write (Some (textV2P debugChecksumPdbChunk.addr)) os "debug checksum" (Array.create debugChecksumPdbChunk.size 0x0uy) + + if embeddedPDB then + write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy) + + if deterministic then + write (Some (textV2P debugDeterministicPdbChunk.addr)) os "debug deterministic" Array.empty + + writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize) + + // DATA SECTION + match nativeResources with + | [||] -> () + | resources -> + write (Some (dataSectionVirtToPhys nativeResourcesChunk.addr)) os "raw native resources" [| |] + writeBytes os resources + + if dummydatap.size <> 0x0 then + write (Some (dataSectionVirtToPhys dummydatap.addr)) os "dummy data" [| 0x0uy |] + + writePadding os "end of .rsrc" (relocSectionPhysLoc - dataSectionPhysLoc - dataSectionSize) + + // RELOC SECTION + + // See ECMA 24.3.2 + let relocV2P v = v - relocSectionAddr + relocSectionPhysLoc + + let entrypointFixupAddr = entrypointCodeChunk.addr + 0x02 + let entrypointFixupBlock = (entrypointFixupAddr / 4096) * 4096 + let entrypointFixupOffset = entrypointFixupAddr - entrypointFixupBlock + let reloc = (if modul.Is64Bit then 0xA000 (* IMAGE_REL_BASED_DIR64 *) else 0x3000 (* IMAGE_REL_BASED_HIGHLOW *)) ||| entrypointFixupOffset + // For the itanium, you need to set a relocation entry for the global pointer + let reloc2 = + if not isItanium then + 0x0 + else + 0xA000 ||| (globalpointerCodeChunk.addr - ((globalpointerCodeChunk.addr / 4096) * 4096)) + + write (Some (relocV2P baseRelocTableChunk.addr)) os "base reloc table" + [| b0 entrypointFixupBlock; b1 entrypointFixupBlock; b2 entrypointFixupBlock; b3 entrypointFixupBlock + 0x0cuy; 0x00uy; 0x00uy; 0x00uy + b0 reloc; b1 reloc + b0 reloc2; b1 reloc2; |] + writePadding os "end of .reloc" (imageEndSectionPhysLoc - relocSectionPhysLoc - relocSectionSize) + + os.Dispose() + + pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings + + // Looks like a finally + with e -> + (try + os.Dispose() + with _ -> ()) + reraise() + + reportTime showTimes "Writing Image" + pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings + +and writePdb (dumpDebugInfo, showTimes, portablePDB, embeddedPDB, pdbfile, outfile, signer, deterministic, pathMap) (pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings) = + if dumpDebugInfo then logDebugInfo outfile pdbData + + // Now we've done the bulk of the binary, do the PDB file and fixup the binary. + begin match pdbfile with + | None -> () +#if ENABLE_MONO_SUPPORT + | Some fmdb when runningOnMono && not portablePDB -> + writeMdbInfo fmdb outfile pdbData +#endif + | Some fpdb -> + try + let idd = + match pdbOpt with + | Some (originalLength, contentId, stream, algorithmName, checkSum) -> + if embeddedPDB then + embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic + else + writePortablePdbInfo contentId stream showTimes fpdb pathMap debugDataChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic + | None -> +#if FX_NO_PDB_WRITER + Array.empty +#else + writePdbInfo showTimes outfile fpdb pdbData debugDataChunk +#endif + reportTime showTimes "Generate PDB Info" + + // Now we have the debug data we can go back and fill in the debug directory in the image + use fs2 = FileSystem.OpenFileForWriteShim(outfile, FileMode.Open, FileAccess.Write, FileShare.Read) + let os2 = new BinaryWriter(fs2) + try + // write the IMAGE_DEBUG_DIRECTORY + os2.BaseStream.Seek (int64 (textV2P debugDirectoryChunk.addr), SeekOrigin.Begin) |> ignore + for i in idd do + writeInt32 os2 i.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics + writeInt32 os2 i.iddTimestamp + writeInt32AsUInt16 os2 i.iddMajorVersion + writeInt32AsUInt16 os2 i.iddMinorVersion + writeInt32 os2 i.iddType + writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData + writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData + writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData + + // Write the Debug Data + for i in idd do + if i.iddChunk.size <> 0 then + // write the debug raw data as given us by the PDB writer + os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore + if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable" + writeBytes os2 i.iddData + os2.Dispose() + with e -> + failwith ("Error while writing debug directory entry: "+e.Message) + (try os2.Dispose(); FileSystem.FileDeleteShim outfile with _ -> ()) + reraise() + with e -> + reraise() + + end + reportTime showTimes "Finalize PDB" + + /// Sign the binary. No further changes to binary allowed past this point! + match signer with + | None -> () + | Some s -> + try + s.SignFile outfile + s.Close() + with e -> + failwith ("Warning: A call to SignFile failed ("+e.Message+")") + (try s.Close() with _ -> ()) + (try FileSystem.FileDeleteShim outfile with _ -> ()) + () + + reportTime showTimes "Signing Image" + //Finished writing and signing the binary and debug info... + mappings + +type options = + { ilg: ILGlobals + pdbfile: string option + portablePDB: bool + embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list + sourceLink: string + checksumAlgorithm: HashAlgorithm + signer: ILStrongNameSigner option + emitTailcalls: bool + deterministic: bool + showTimes: bool + dumpDebugInfo: bool + pathMap: PathMap } + +let WriteILBinary (filename, options: options, inputModule, normalizeAssemblyRefs) = + writeBinaryAndReportMappings (filename, + options.ilg, options.pdbfile, options.signer, options.portablePDB, options.embeddedPDB, options.embedAllSource, + options.embedSourceList, options.sourceLink, options.checksumAlgorithm, options.emitTailcalls, options.deterministic, options.showTimes, options.dumpDebugInfo, options.pathMap) inputModule normalizeAssemblyRefs + |> ignore + +let WriteILBinaryStreamWithNoPDB (stream, options: options, inputModule, normalizeAssemblyRefs) = + writeBinaryWithNoPdb (stream, + options.ilg, options.signer, options.portablePDB, options.embeddedPDB, options.embedAllSource, + options.embedSourceList, options.sourceLink, options.checksumAlgorithm, options.emitTailcalls, options.deterministic, options.showTimes, options.pathMap) inputModule normalizeAssemblyRefs + |> ignore diff --git a/src/fsharp/absil/ilwrite.fsi b/src/fsharp/absil/ilwrite.fsi new file mode 100644 index 00000000000..152c9abc45f --- /dev/null +++ b/src/fsharp/absil/ilwrite.fsi @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The IL Binary writer. +module internal FSharp.Compiler.AbstractIL.ILBinaryWriter + +open Internal.Utilities +open System.IO +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILPdbWriter +open FSharp.Compiler.AbstractIL.StrongNameSign + +type options = + { ilg: ILGlobals + pdbfile: string option + portablePDB: bool + embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list + sourceLink: string + checksumAlgorithm: HashAlgorithm + signer : ILStrongNameSigner option + emitTailcalls: bool + deterministic: bool + showTimes : bool + dumpDebugInfo : bool + pathMap : PathMap } + +/// Write a binary to the file system. Extra configuration parameters can also be specified. +val WriteILBinary: filename: string * options: options * inputModule: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit + +/// Write a binary to the given stream. Extra configuration parameters can also be specified. +val WriteILBinaryStreamWithNoPDB: stream: Stream * options: options * inputModule: ILModuleDef * (ILAssemblyRef -> ILAssemblyRef) -> unit \ No newline at end of file diff --git a/src/fsharp/absil/ilwritepdb.fs b/src/fsharp/absil/ilwritepdb.fs new file mode 100644 index 00000000000..dcfed598615 --- /dev/null +++ b/src/fsharp/absil/ilwritepdb.fs @@ -0,0 +1,1062 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.AbstractIL.ILPdbWriter + +open System +open System.Collections.Generic +open System.Collections.Immutable +open System.IO +open System.IO.Compression +open System.Reflection +open System.Reflection.Metadata +open System.Reflection.Metadata.Ecma335 +open System.Security.Cryptography +open System.Text +open Internal.Utilities +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.Support +open Internal.Utilities.Library +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range + +type BlobBuildingStream () = + inherit Stream() + + static let chunkSize = 32 * 1024 + let builder = BlobBuilder(chunkSize) + + override _.CanWrite = true + override _.CanRead = false + override _.CanSeek = false + override _.Length = int64 builder.Count + + override _.Write(buffer: byte array, offset: int, count: int) = builder.WriteBytes(buffer, offset, count) + override _.WriteByte(value: byte) = builder.WriteByte value + member _.WriteInt32(value: int) = builder.WriteInt32 value + member _.ToImmutableArray() = builder.ToImmutableArray() + member _.TryWriteBytes(stream: Stream, length: int) = builder.TryWriteBytes(stream, length) + + override _.Flush() = () + override _.Dispose(_disposing: bool) = () + override _.Seek(_offset: int64, _origin: SeekOrigin) = raise (NotSupportedException()) + override _.Read(_buffer: byte array, _offset: int, _count: int) = raise (NotSupportedException()) + override _.SetLength(_value: int64) = raise (NotSupportedException()) + override val Position = 0L with get, set + +// -------------------------------------------------------------------- +// PDB types +// -------------------------------------------------------------------- +type PdbDocumentData = ILSourceDocument + +type PdbLocalVar = + { + Name: string + Signature: byte[] + /// the local index the name corresponds to + Index: int32 + } + +type PdbImport = + | ImportType of targetTypeToken: int32 (* alias: string option *) + | ImportNamespace of targetNamespace: string (* assembly: ILAssemblyRef option * alias: string option *) + //| ReferenceAlias of string + //| OpenXmlNamespace of prefix: string * xmlNamespace: string + +type PdbImports = + { + Parent: PdbImports option + Imports: PdbImport[] + } + +type PdbMethodScope = + { + Children: PdbMethodScope[] + StartOffset: int + EndOffset: int + Locals: PdbLocalVar[] + Imports: PdbImports option + } + +type PdbSourceLoc = + { + Document: int + Line: int + Column: int + } + +type PdbDebugPoint = + { + Document: int + Offset: int + Line: int + Column: int + EndLine: int + EndColumn: int + } + override x.ToString() = sprintf "(%d,%d)-(%d,%d)" x.Line x.Column x.EndLine x.EndColumn + +type PdbMethodData = + { + MethToken: int32 + MethName: string + LocalSignatureToken: int32 + Params: PdbLocalVar array + RootScope: PdbMethodScope option + Range: (PdbSourceLoc * PdbSourceLoc) option + DebugPoints: PdbDebugPoint [] + } + +module SequencePoint = + let orderBySource sp1 sp2 = + let c1 = compare sp1.Document sp2.Document + if c1 <> 0 then + c1 + else + let c1 = compare sp1.Line sp2.Line + if c1 <> 0 then + c1 + else + compare sp1.Column sp2.Column + + let orderByOffset sp1 sp2 = + compare sp1.Offset sp2.Offset + +/// 28 is the size of the IMAGE_DEBUG_DIRECTORY in ntimage.h +let sizeof_IMAGE_DEBUG_DIRECTORY = 28 + +[] +type PdbData = + { EntryPoint: int32 option + Timestamp: int32 + ModuleID: byte[] + Documents: PdbDocumentData[] + Methods: PdbMethodData[] + TableRowCounts: int[] } + +type BinaryChunk = + { size: int32 + addr: int32 } + +type idd = + { iddCharacteristics: int32 + iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) + iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) + iddType: int32 + iddTimestamp: int32 + iddData: byte[] + iddChunk: BinaryChunk } + +/// The specified Hash algorithm to use on portable pdb files. +type HashAlgorithm = + | Sha1 + | Sha256 + +// Document checksum algorithms +let guidSha1 = Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460") +let guidSha2 = Guid("8829d00f-11b8-4213-878b-770e8597ac16") + +let checkSum (url: string) (checksumAlgorithm: HashAlgorithm) = + try + use file = FileSystem.OpenFileForReadShim(url) + let guid, alg = + match checksumAlgorithm with + | HashAlgorithm.Sha1 -> guidSha1, SHA1.Create() :> System.Security.Cryptography.HashAlgorithm + | HashAlgorithm.Sha256 -> guidSha2, SHA256.Create() :> System.Security.Cryptography.HashAlgorithm + + let checkSum = alg.ComputeHash file + Some (guid, checkSum) + with _ -> None + +//--------------------------------------------------------------------- +// Portable PDB Writer +//--------------------------------------------------------------------- + +let b0 n = (n &&& 0xFF) +let b1 n = ((n >>> 8) &&& 0xFF) +let b2 n = ((n >>> 16) &&& 0xFF) +let b3 n = ((n >>> 24) &&& 0xFF) +let i32AsBytes i = [| byte (b0 i); byte (b1 i); byte (b2 i); byte (b3 i) |] + +let cvMagicNumber = 0x53445352L +let pdbGetCvDebugInfo (mvid: byte[]) (timestamp: int32) (filepath: string) (cvChunk: BinaryChunk) = + let iddCvBuffer = + // Debug directory entry + let path = (Encoding.UTF8.GetBytes filepath) + let buffer = Array.zeroCreate (sizeof + mvid.Length + sizeof + path.Length + 1) + let offset, size = (0, sizeof) // Magic Number RSDS dword: 0x53445352L + Buffer.BlockCopy(i32AsBytes (int cvMagicNumber), 0, buffer, offset, size) + let offset, size = (offset + size, mvid.Length) // mvid Guid + Buffer.BlockCopy(mvid, 0, buffer, offset, size) + let offset, size = (offset + size, sizeof) // # of pdb files generated (1) + Buffer.BlockCopy(i32AsBytes 1, 0, buffer, offset, size) + let offset, size = (offset + size, path.Length) // Path to pdb string + Buffer.BlockCopy(path, 0, buffer, offset, size) + buffer + { iddCharacteristics = 0 // Reserved + iddMajorVersion = 0x0100 // VersionMajor should be 0x0100 + iddMinorVersion = 0x504d // VersionMinor should be 0x504d + iddType = 2 // IMAGE_DEBUG_TYPE_CODEVIEW + iddTimestamp = timestamp + iddData = iddCvBuffer // Path name to the pdb file when built + iddChunk = cvChunk + } + +let pdbMagicNumber= 0x4244504dL +let pdbGetEmbeddedPdbDebugInfo (embeddedPdbChunk: BinaryChunk) (uncompressedLength: int64) (stream: MemoryStream) = + let iddPdbBuffer = + let buffer = Array.zeroCreate (sizeof + sizeof + int(stream.Length)) + let offset, size = (0, sizeof) // Magic Number dword: 0x4244504dL + Buffer.BlockCopy(i32AsBytes (int pdbMagicNumber), 0, buffer, offset, size) + let offset, size = (offset + size, sizeof) // Uncompressed size + Buffer.BlockCopy(i32AsBytes (int uncompressedLength), 0, buffer, offset, size) + let offset, size = (offset + size, int(stream.Length)) // Uncompressed size + Buffer.BlockCopy(stream.ToArray(), 0, buffer, offset, size) + buffer + { iddCharacteristics = 0 // Reserved + iddMajorVersion = 0x0100 // VersionMajor should be 0x0100 + iddMinorVersion = 0x0100 // VersionMinor should be 0x0100 + iddType = 17 // IMAGE_DEBUG_TYPE_EMBEDDEDPDB + iddTimestamp = 0 + iddData = iddPdbBuffer // Path name to the pdb file when built + iddChunk = embeddedPdbChunk + } + +let pdbChecksumDebugInfo timestamp (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte[]) = + let iddBuffer = + let alg = Encoding.UTF8.GetBytes(algorithmName) + let buffer = Array.zeroCreate (alg.Length + 1 + checksum.Length) + Buffer.BlockCopy(alg, 0, buffer, 0, alg.Length) + Buffer.BlockCopy(checksum, 0, buffer, alg.Length + 1, checksum.Length) + buffer + { iddCharacteristics = 0 // Reserved + iddMajorVersion = 1 // VersionMajor should be 1 + iddMinorVersion = 0 // VersionMinor should be 0 + iddType = 19 // IMAGE_DEBUG_TYPE_CHECKSUMPDB + iddTimestamp = timestamp + iddData = iddBuffer // Path name to the pdb file when built + iddChunk = checksumPdbChunk + } + +let pdbGetPdbDebugDeterministicInfo (deterministicPdbChunk: BinaryChunk) = + { iddCharacteristics = 0 // Reserved + iddMajorVersion = 0 // VersionMajor should be 0 + iddMinorVersion = 0 // VersionMinor should be 00 + iddType = 16 // IMAGE_DEBUG_TYPE_DETERMINISTIC + iddTimestamp = 0 + iddData = Array.empty // No DATA + iddChunk = deterministicPdbChunk + } + +let pdbGetDebugInfo (contentId: byte[]) (timestamp: int32) (filepath: string) + (cvChunk: BinaryChunk) + (embeddedPdbChunk: BinaryChunk option) + (deterministicPdbChunk: BinaryChunk) + (checksumPdbChunk: BinaryChunk) (algorithmName:string) (checksum: byte []) + (uncompressedLength: int64) (stream: MemoryStream option) + (embeddedPdb: bool) (deterministic: bool) = + [| yield pdbGetCvDebugInfo contentId timestamp filepath cvChunk + yield pdbChecksumDebugInfo timestamp checksumPdbChunk algorithmName checksum + if embeddedPdb then + match stream, embeddedPdbChunk with + | None, _ | _, None -> () + | Some s, Some chunk -> + yield pdbGetEmbeddedPdbDebugInfo chunk uncompressedLength s + if deterministic then + yield pdbGetPdbDebugDeterministicInfo deterministicPdbChunk + |] + +//------------------------------------------------------------------------------ +// PDB Writer. The function [WritePdbInfo] abstracts the +// imperative calls to the Symbol Writer API. +//------------------------------------------------------------------------------ + +// This function takes output file name and returns debug file name. +let getDebugFileName outfile (portablePDB: bool) = +#if ENABLE_MONO_SUPPORT + if runningOnMono && not portablePDB then + outfile + ".mdb" + else +#else + ignore portablePDB +#endif + (FileSystemUtils.chopExtension outfile) + ".pdb" + +let sortMethods showTimes info = + reportTime showTimes (sprintf "PDB: Defined %d documents" info.Documents.Length) + Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods + reportTime showTimes (sprintf "PDB: Sorted %d methods" info.Methods.Length) + () + +let getRowCounts tableRowCounts = + let builder = ImmutableArray.CreateBuilder(tableRowCounts |> Array.length) + tableRowCounts |> Seq.iter(fun x -> builder.Add x) + builder.MoveToImmutable() + +let scopeSorter (scope1: PdbMethodScope) (scope2: PdbMethodScope) = + if scope1.StartOffset > scope2.StartOffset then 1 + elif scope1.StartOffset < scope2.StartOffset then -1 + elif (scope1.EndOffset - scope1.StartOffset) > (scope2.EndOffset - scope2.StartOffset) then -1 + elif (scope1.EndOffset - scope1.StartOffset) < (scope2.EndOffset - scope2.StartOffset) then 1 + else 0 + +type PortablePdbGenerator (embedAllSource: bool, embedSourceList: string list, sourceLink: string, checksumAlgorithm, showTimes, info: PdbData, pathMap: PathMap) = + + let docs = + match info.Documents with + | null -> Array.empty + | _ -> info.Documents + + // The metadata to wite to the PoortablePDB (Roslyn = _debugMetadataOpt) + + let metadata = MetadataBuilder() + + let serializeDocumentName (name: string) = + let name = PathMap.apply pathMap name + let count s c = s |> Seq.filter(fun ch -> c = ch) |> Seq.length + + let s1, s2 = '/', '\\' + let separator = if (count name s1) >= (count name s2) then s1 else s2 + + let writer = BlobBuilder() + writer.WriteByte(byte separator) + + for part in name.Split( [| separator |] ) do + let partIndex = MetadataTokens.GetHeapOffset(BlobHandle.op_Implicit(metadata.GetOrAddBlobUTF8 part)) + writer.WriteCompressedInteger(int partIndex) + + metadata.GetOrAddBlob writer + + let corSymLanguageTypeId = Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) + let embeddedSourceId = Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) + let sourceLinkId = Guid(0xcc110556u, 0xa091us, 0x4d38us, 0x9fuy, 0xecuy, 0x25uy, 0xabuy, 0x9auy, 0x35uy, 0x1auy, 0x6auy) + + /// + /// The maximum number of bytes in to write out uncompressed. + /// + /// This prevents wasting resources on compressing tiny files with little to negative gain + /// in PDB file size. + /// + /// Chosen as the point at which we start to see > 10% blob size reduction using all + /// current source files in corefx and roslyn as sample data. + /// + let sourceCompressionThreshold = 200 + + let includeSource file = + let isInList = embedSourceList |> List.exists (fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) + + if not embedAllSource && not isInList || not (FileSystem.FileExistsShim file) then + None + else + use stream = FileSystem.OpenFileForReadShim(file) + + let length64 = stream.Length + if length64 > int64 Int32.MaxValue then raise (IOException("File is too long")) + + let builder = new BlobBuildingStream() + let length = int length64 + if length < sourceCompressionThreshold then + builder.WriteInt32 0 + builder.TryWriteBytes(stream, length) |> ignore + else + builder.WriteInt32 length + use deflater = new DeflateStream(builder, CompressionMode.Compress, true) + stream.CopyTo deflater + Some (builder.ToImmutableArray()) + + let documentIndex = + let mutable index = Dictionary(docs.Length) + let docLength = docs.Length + if String.IsNullOrEmpty sourceLink then 1 else 0 + metadata.SetCapacity(TableIndex.Document, docLength) + for doc in docs do + let handle = + match checkSum doc.File checksumAlgorithm with + | Some (hashAlg, checkSum) -> + let dbgInfo = + (serializeDocumentName doc.File, + metadata.GetOrAddGuid hashAlg, + metadata.GetOrAddBlob(checkSum.ToImmutableArray()), + metadata.GetOrAddGuid corSymLanguageTypeId) |> metadata.AddDocument + match includeSource doc.File with + | None -> () + | Some blob -> + metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit dbgInfo, + metadata.GetOrAddGuid embeddedSourceId, + metadata.GetOrAddBlob blob) |> ignore + dbgInfo + | None -> + let dbgInfo = + (serializeDocumentName doc.File, + metadata.GetOrAddGuid(Guid.Empty), + metadata.GetOrAddBlob(ImmutableArray.Empty), + metadata.GetOrAddGuid corSymLanguageTypeId) |> metadata.AddDocument + dbgInfo + index.Add(doc.File, handle) + + if not (String.IsNullOrWhiteSpace sourceLink) then + use fs = FileSystem.OpenFileForReadShim(sourceLink) + use ms = new MemoryStream() + fs.CopyTo ms + metadata.AddCustomDebugInformation( + ModuleDefinitionHandle.op_Implicit(EntityHandle.ModuleDefinition), + metadata.GetOrAddGuid sourceLinkId, + metadata.GetOrAddBlob(ms.ToArray())) |> ignore + index + + let mutable lastLocalVariableHandle = Unchecked.defaultof + + let getDocumentHandle d = + if docs.Length = 0 || d < 0 || d > docs.Length then + Unchecked.defaultof + else + match documentIndex.TryGetValue(docs.[d].File) with + | false, _ -> Unchecked.defaultof + | true, h -> h + + let moduleImportScopeHandle = MetadataTokens.ImportScopeHandle(1) + let importScopesTable = new Dictionary() + + let serializeImport (writer: BlobBuilder) (import: PdbImport) = + match import with + // We don't yet emit these kinds of imports + //| AssemblyReferenceAlias alias-> + // // ::= AliasAssemblyReference + // writer.WriteByte((byte)ImportDefinitionKind.AliasAssemblyReference); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(alias.Name))); + // writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(GetOrAddAssemblyReferenceHandle(alias.Assembly))); + + //| OpenXmlNamespace(prefix, xmlNamespace) -> + // Debug.Assert(import.TargetNamespaceOpt == null); + // Debug.Assert(import.TargetAssemblyOpt == null); + // Debug.Assert(import.TargetTypeOpt == null); + + // // ::= ImportXmlNamespace + // writer.WriteByte((byte)ImportDefinitionKind.ImportXmlNamespace); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.TargetXmlNamespaceOpt))); + // Corresponds to an 'open ' or 'open type' in F# + | ImportType targetTypeToken -> + + //if (import.AliasOpt != null) + //{ + // // ::= AliasType + // writer.WriteByte((byte)ImportDefinitionKind.AliasType); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); + //} + //else + // ::= ImportType + writer.WriteByte(byte ImportDefinitionKind.ImportType) + + writer.WriteCompressedInteger(targetTypeToken) + + // Corresponds to an 'open ' + | ImportNamespace targetNamespace -> + //if (import.TargetAssemblyOpt != null) + //{ + // if (import.AliasOpt != null) + // { + // // ::= AliasAssemblyNamespace + // writer.WriteByte((byte)ImportDefinitionKind.AliasAssemblyNamespace); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); + // } + // else + // { + // // ::= ImportAssemblyNamespace + // writer.WriteByte((byte)ImportDefinitionKind.ImportAssemblyNamespace); + // } + + // writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(GetAssemblyReferenceHandle(import.TargetAssemblyOpt))); + //} + //else + //{ + //if (import.AliasOpt != null) + //{ + // // ::= AliasNamespace + // writer.WriteByte((byte)ImportDefinitionKind.AliasNamespace); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); + //} + //else + //{ + // ::= ImportNamespace + writer.WriteByte(byte ImportDefinitionKind.ImportNamespace); + writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(metadata.GetOrAddBlobUTF8(targetNamespace))) + + //| ReferenceAlias alias -> + // // ::= ImportReferenceAlias + // Debug.Assert(import.AliasOpt != null); + // Debug.Assert(import.TargetAssemblyOpt == null); + + // writer.WriteByte((byte)ImportDefinitionKind.ImportAssemblyReferenceAlias); + // writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(_debugMetadataOpt.GetOrAddBlobUTF8(import.AliasOpt))); + + let serializeImportsBlob (scope: PdbImports) = + let writer = new BlobBuilder() + + for import in scope.Imports do + serializeImport writer import + + metadata.GetOrAddBlob(writer) + + // Define the empty global imports scope for the whole assembly,it gets index #1 (the first entry in the table) + let defineModuleImportScope() = + let writer = new BlobBuilder() + let blob = metadata.GetOrAddBlob writer + let rid = metadata.AddImportScope(parentScope=Unchecked.defaultof<_>,imports=blob) + assert(rid = moduleImportScopeHandle) + + let rec getImportScopeIndex (imports: PdbImports) = + match importScopesTable.TryGetValue(imports) with + | true, v -> v + | _ -> + + let parentScopeHandle = + match imports.Parent with + | None -> moduleImportScopeHandle + | Some parent -> getImportScopeIndex parent + + let blob = serializeImportsBlob imports + let result = metadata.AddImportScope(parentScopeHandle, blob) + + importScopesTable.Add(imports, result) + result + + let flattenScopes rootScope = + let list = List() + let rec flattenScopes scope parent = + + list.Add scope + for nestedScope in scope.Children do + let isNested = + match parent with + | Some p -> nestedScope.StartOffset >= p.StartOffset && nestedScope.EndOffset <= p.EndOffset + | None -> true + + flattenScopes nestedScope (if isNested then Some scope else parent) + + flattenScopes rootScope None + + list.ToArray() + |> Array.sortWith scopeSorter + + let writeMethodScopes methToken rootScope = + + let flattenedScopes = flattenScopes rootScope + + // Get or create the import scope for this method + let importScopeHandle = +#if EMIT_IMPORT_SCOPES + match s.Imports with + | None -> Unchecked.defaultof<_> + | Some imports -> getImportScopeIndex imports +#else + getImportScopeIndex |> ignore // make sure this code counts as used + Unchecked.defaultof<_> +#endif + + for scope in flattenedScopes do + let lastRowNumber = MetadataTokens.GetRowNumber(LocalVariableHandle.op_Implicit lastLocalVariableHandle) + let nextHandle = MetadataTokens.LocalVariableHandle(lastRowNumber + 1) + + metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(methToken), + importScopeHandle, + nextHandle, + Unchecked.defaultof, + scope.StartOffset, scope.EndOffset - scope.StartOffset ) |>ignore + + for localVariable in scope.Locals do + lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) + + let emitMethod minfo = + let docHandle, sequencePointBlob = + let sps = + match minfo.DebugPoints with + | null -> Array.empty + | _ -> + match minfo.Range with + | None -> Array.empty + | Some _ -> minfo.DebugPoints + + let builder = BlobBuilder() + builder.WriteCompressedInteger(minfo.LocalSignatureToken) + + if sps.Length = 0 then + builder.WriteCompressedInteger( 0 ) + builder.WriteCompressedInteger( 0 ) + Unchecked.defaultof, Unchecked.defaultof + else + + // Return a document that the entire method body is declared within. + // If part of the method body is in another document returns nil handle. + let tryGetSingleDocumentIndex = + let mutable singleDocumentIndex = sps.[0].Document + for i in 1 .. sps.Length - 1 do + if sps.[i].Document <> singleDocumentIndex then + singleDocumentIndex <- -1 + singleDocumentIndex + + // Initial document: When sp's spread over more than one document we put the initial document here. + let singleDocumentIndex = tryGetSingleDocumentIndex + if singleDocumentIndex = -1 then + builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle sps.[0].Document)) ) + + let mutable previousNonHiddenStartLine = -1 + let mutable previousNonHiddenStartColumn = 0 + + for i in 0 .. (sps.Length - 1) do + + if singleDocumentIndex <> -1 && sps.[i].Document <> singleDocumentIndex then + builder.WriteCompressedInteger( 0 ) + builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle sps.[i].Document)) ) + else + //============================================================================================================================================= + // Sequence-point-record + // Validate these with magic numbers according to the portable pdb spec Sequence point dexcription: + // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#methoddebuginformation-table-0x31 + // + // So the spec is actually bit iffy!!!!! (More like guidelines really. ) + // It uses code similar to this to validate the values + // if (result < 0 || result >= ushort.MaxValue) // be errorfull + // Spec Says 0x10000 and value max = 0xFFFF but it can't even be = to maxvalue, and so the range is 0 .. 0xfffe inclusive + //============================================================================================================================================= + + let capValue v maxValue = + if v < 0 then 0 + elif v > maxValue then maxValue + else v + + let capOffset v = capValue v 0xfffe + let capLine v = capValue v 0x1ffffffe + let capColumn v = capValue v 0xfffe + + let offset = capOffset sps.[i].Offset + let startLine = capLine sps.[i].Line + let endLine = capLine sps.[i].EndLine + let startColumn = capColumn sps.[i].Column + let endColumn = capColumn sps.[i].EndColumn + + let offsetDelta = // delta from previous offset + if i > 0 then offset - capOffset sps.[i - 1].Offset + else offset + + if i < 1 || offsetDelta > 0 then + builder.WriteCompressedInteger offsetDelta + + // Check for hidden-sequence-point-record + if startLine = 0xfeefee || + endLine = 0xfeefee || + (startColumn = 0 && endColumn = 0) || + ((endLine - startLine) = 0 && (endColumn - startColumn) = 0) + then + // Hidden-sequence-point-record + builder.WriteCompressedInteger 0 + builder.WriteCompressedInteger 0 + else + // Non-hidden-sequence-point-record + let deltaLines = endLine - startLine // lines + builder.WriteCompressedInteger deltaLines + + let deltaColumns = endColumn - startColumn // Columns + if deltaLines = 0 then + builder.WriteCompressedInteger deltaColumns + else + builder.WriteCompressedSignedInteger deltaColumns + + if previousNonHiddenStartLine < 0 then // delta Start Line & Column: + builder.WriteCompressedInteger startLine + builder.WriteCompressedInteger startColumn + else + builder.WriteCompressedSignedInteger(startLine - previousNonHiddenStartLine) + builder.WriteCompressedSignedInteger(startColumn - previousNonHiddenStartColumn) + + previousNonHiddenStartLine <- startLine + previousNonHiddenStartColumn <- startColumn + + getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob builder + + metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore + + match minfo.RootScope with + | None -> () + | Some scope -> writeMethodScopes minfo.MethToken scope + + member _.Emit() = + sortMethods showTimes info + metadata.SetCapacity(TableIndex.MethodDebugInformation, info.Methods.Length) + +// Currently disabled, see +#if EMIT_IMPORT_SCOPES + defineModuleImportScope() +#else + defineModuleImportScope |> ignore // make sure this function counts as used +#endif + + for minfo in info.Methods do + emitMethod minfo + + let entryPoint = + match info.EntryPoint with + | None -> MetadataTokens.MethodDefinitionHandle 0 + | Some x -> MetadataTokens.MethodDefinitionHandle x + + // Compute the contentId for the pdb. Always do it deterministically, since we have to compute the anyway. + // The contentId is the hash of the ID using whichever algorithm has been specified to the compiler + let mutable contentHash = Array.empty + + let algorithmName, hashAlgorithm = + match checksumAlgorithm with + | HashAlgorithm.Sha1 -> "SHA1", SHA1.Create() :> System.Security.Cryptography.HashAlgorithm + | HashAlgorithm.Sha256 -> "SHA256", SHA256.Create() :> System.Security.Cryptography.HashAlgorithm + + let idProvider = + let convert (content: IEnumerable) = + let contentBytes = content |> Seq.collect (fun c -> c.GetBytes()) |> Array.ofSeq + contentHash <- contentBytes |> hashAlgorithm.ComputeHash + BlobContentId.FromHash contentHash + Func, BlobContentId>(convert) + + let externalRowCounts = getRowCounts info.TableRowCounts + + let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, idProvider) + let blobBuilder = BlobBuilder() + let contentId= serializer.Serialize blobBuilder + let portablePdbStream = new MemoryStream() + blobBuilder.WriteContentTo portablePdbStream + reportTime showTimes "PDB: Created" + (portablePdbStream.Length, contentId, portablePdbStream, algorithmName, contentHash) + +let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (sourceLink: string) checksumAlgorithm showTimes (info: PdbData) (pathMap: PathMap) = + let generator = PortablePdbGenerator (embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, showTimes, info, pathMap) + generator.Emit() + +let compressPortablePdbStream (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) = + let compressedStream = new MemoryStream() + use compressionStream = new DeflateStream(compressedStream, CompressionMode.Compress,true) + stream.WriteTo compressionStream + (uncompressedLength, contentId, compressedStream) + +let writePortablePdbInfo (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb pathMap cvChunk deterministicPdbChunk checksumPdbChunk algorithmName checksum embeddedPdb deterministic = + try FileSystem.FileDeleteShim fpdb with _ -> () + use fs = FileSystem.OpenFileForWriteShim(fpdb, fileMode = FileMode.Create, fileAccess = FileAccess.ReadWrite) + stream.WriteTo fs + reportTime showTimes "PDB: Closed" + pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 contentId.Stamp) (PathMap.apply pathMap fpdb) cvChunk None deterministicPdbChunk checksumPdbChunk algorithmName checksum 0L None embeddedPdb deterministic + +let embedPortablePdbInfo (uncompressedLength: int64) (contentId: BlobContentId) (stream: MemoryStream) showTimes fpdb cvChunk pdbChunk deterministicPdbChunk checksumPdbChunk algorithmName checksum embeddedPdb deterministic = + reportTime showTimes "PDB: Closed" + let fn = Path.GetFileName fpdb + pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 contentId.Stamp) fn cvChunk (Some pdbChunk) deterministicPdbChunk checksumPdbChunk algorithmName checksum uncompressedLength (Some stream) embeddedPdb deterministic + +#if !FX_NO_PDB_WRITER + +open Microsoft.Win32 + +//--------------------------------------------------------------------- +// PDB Writer. The function [WritePdbInfo] abstracts the +// imperative calls to the Symbol Writer API. +//--------------------------------------------------------------------- +let writePdbInfo showTimes f fpdb info cvChunk = + + try FileSystem.FileDeleteShim fpdb with _ -> () + + let pdbw = + try + pdbInitialize f fpdb + with _ -> + error(Error(FSComp.SR.ilwriteErrorCreatingPdb fpdb, rangeCmdArgs)) + + match info.EntryPoint with + | None -> () + | Some x -> pdbSetUserEntryPoint pdbw x + + let docs = info.Documents |> Array.map (fun doc -> pdbDefineDocument pdbw doc.File) + let getDocument i = + if i < 0 || i > docs.Length then failwith "getDocument: bad doc number" + docs.[i] + reportTime showTimes (sprintf "PDB: Defined %d documents" info.Documents.Length) + Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods + reportTime showTimes (sprintf "PDB: Sorted %d methods" info.Methods.Length) + + let spCounts = info.Methods |> Array.map (fun x -> x.DebugPoints.Length) + let allSps = Array.collect (fun x -> x.DebugPoints) info.Methods |> Array.indexed + + let mutable spOffset = 0 + info.Methods |> Array.iteri (fun i minfo -> + + let sps = Array.sub allSps spOffset spCounts.[i] + spOffset <- spOffset + spCounts.[i] + begin match minfo.Range with + | None -> () + | Some (a,b) -> + pdbOpenMethod pdbw minfo.MethToken + + pdbSetMethodRange pdbw + (getDocument a.Document) a.Line a.Column + (getDocument b.Document) b.Line b.Column + + // Partition the sequence points by document + let spsets = + let res = Dictionary() + for (_,sp) in sps do + let k = sp.Document + match res.TryGetValue(k) with + | true, xsR -> + xsR.Value <- sp :: xsR.Value + | _ -> + res.[k] <- ref [sp] + + res + + spsets + |> Seq.iter (fun (KeyValue(_, vref)) -> + let spset = vref.Value + if not spset.IsEmpty then + let spset = Array.ofList spset + Array.sortInPlaceWith SequencePoint.orderByOffset spset + let sps = + spset |> Array.map (fun sp -> + // Ildiag.dprintf "token 0x%08lx has an sp at offset 0x%08x\n" minfo.MethToken sp.Offset + (sp.Offset, sp.Line, sp.Column,sp.EndLine, sp.EndColumn)) + // Use of alloca in implementation of pdbDefineSequencePoints can give stack overflow here + if sps.Length < 5000 then + pdbDefineSequencePoints pdbw (getDocument spset.[0].Document) sps) + + // Write the scopes + let rec writePdbScope parent sco = + if parent = None || sco.Locals.Length <> 0 || sco.Children.Length <> 0 then + // Only nest scopes if the child scope is a different size from + let nested = + match parent with + | Some p -> sco.StartOffset <> p.StartOffset || sco.EndOffset <> p.EndOffset + | None -> true + if nested then pdbOpenScope pdbw sco.StartOffset + sco.Locals |> Array.iter (fun v -> pdbDefineLocalVariable pdbw v.Name v.Signature v.Index) + sco.Children |> Array.iter (writePdbScope (if nested then Some sco else parent)) + if nested then pdbCloseScope pdbw sco.EndOffset + + match minfo.RootScope with + | None -> () + | Some rootscope -> writePdbScope None rootscope + pdbCloseMethod pdbw + end) + reportTime showTimes "PDB: Wrote methods" + + let res = pdbWriteDebugInfo pdbw + for pdbDoc in docs do pdbCloseDocument pdbDoc + pdbClose pdbw f fpdb + + reportTime showTimes "PDB: Closed" + [| { iddCharacteristics = res.iddCharacteristics + iddMajorVersion = res.iddMajorVersion + iddMinorVersion = res.iddMinorVersion + iddType = res.iddType + iddTimestamp = info.Timestamp + iddData = res.iddData + iddChunk = cvChunk } |] +#endif + +#if ENABLE_MONO_SUPPORT +//--------------------------------------------------------------------- +// Support functions for calling 'Mono.CompilerServices.SymbolWriter' +// assembly dynamically if it is available to the compiler +//--------------------------------------------------------------------- +open Microsoft.FSharp.Reflection + +// Dynamic invoke operator. Implements simple overload resolution based +// on the name and number of parameters only. +// Supports the following cases: +// obj?Foo() // call with no arguments +// obj?Foo(1, "a") // call with two arguments (extracted from tuple) +// NOTE: This doesn't actually handle all overloads. It just picks first entry with right +// number of arguments. +let (?) this memb (args:'Args) : 'R = + // Get array of 'obj' arguments for the reflection call + let args = + if typeof<'Args> = typeof then [| |] + elif FSharpType.IsTuple typeof<'Args> then FSharpValue.GetTupleFields args + else [| box args |] + + // Get methods and perform overload resolution + let methods = this.GetType().GetMethods() + let bestMatch = methods |> Array.tryFind (fun mi -> mi.Name = memb && mi.GetParameters().Length = args.Length) + match bestMatch with + | Some mi -> unbox(mi.Invoke(this, args)) + | None -> error(Error(FSComp.SR.ilwriteMDBMemberMissing memb, rangeCmdArgs)) + +// Creating instances of needed classes from 'Mono.CompilerServices.SymbolWriter' assembly + +let monoCompilerSvc = AssemblyName("Mono.CompilerServices.SymbolWriter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756") +let ctor (asmName: AssemblyName) clsName (args: obj[]) = + let asm = Assembly.Load asmName + let ty = asm.GetType clsName + Activator.CreateInstance(ty, args) + +let createSourceMethodImpl (name: string) (token: int) (namespaceID: int) = + ctor monoCompilerSvc "Mono.CompilerServices.SymbolWriter.SourceMethodImpl" [| box name; box token; box namespaceID |] + +let createWriter (f: string) = + ctor monoCompilerSvc "Mono.CompilerServices.SymbolWriter.MonoSymbolWriter" [| box f |] + +//--------------------------------------------------------------------- +// MDB Writer. Generate debug symbols using the MDB format +//--------------------------------------------------------------------- +let writeMdbInfo fmdb f info = + // Note, if we can't delete it code will fail later + try FileSystem.FileDeleteShim fmdb with _ -> () + + // Try loading the MDB symbol writer from an assembly available on Mono dynamically + // Report an error if the assembly is not available. + let wr = + try createWriter f + with e -> error(Error(FSComp.SR.ilwriteErrorCreatingMdb(), rangeCmdArgs)) + + // NOTE: MonoSymbolWriter doesn't need information about entrypoints, so 'info.EntryPoint' is unused here. + // Write information about Documents. Returns '(SourceFileEntry*CompileUnitEntry)[]' + let docs = + [| for doc in info.Documents do + let doc = wr?DefineDocument(doc.File) + let unit = wr?DefineCompilationUnit doc + yield doc, unit |] + + let getDocument i = + if i < 0 || i >= Array.length docs then failwith "getDocument: bad doc number" else docs.[i] + + // Sort methods and write them to the MDB file + Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods + for meth in info.Methods do + // Creates an instance of 'SourceMethodImpl' which is a private class that implements 'IMethodDef' interface + // We need this as an argument to 'OpenMethod' below. Using private class is ugly, but since we don't reference + // the assembly, the only way to implement 'IMethodDef' interface would be dynamically using Reflection.Emit... + let sm = createSourceMethodImpl meth.MethName meth.MethToken 0 + match meth.Range with + | Some(mstart, _) -> + // NOTE: 'meth.Params' is not needed, Mono debugger apparently reads this from meta-data + let _, cue = getDocument mstart.Document + wr?OpenMethod(cue, 0, sm) |> ignore + + // Write sequence points + for sp in meth.DebugPoints do + wr?MarkSequencePoint(sp.Offset, cue?get_SourceFile(), sp.Line, sp.Column, false) + + // Walk through the tree of scopes and write all variables + let rec writeScope (scope: PdbMethodScope) = + wr?OpenScope(scope.StartOffset) |> ignore + for local in scope.Locals do + wr?DefineLocalVariable(local.Index, local.Name) + for child in scope.Children do + writeScope child + wr?CloseScope(scope.EndOffset) + match meth.RootScope with + | None -> () + | Some rootscope -> writeScope rootscope + + + // Finished generating debug information for the curretn method + wr?CloseMethod() + | _ -> () + + // Finalize - MDB requires the MVID of the generated .NET module + let moduleGuid = Guid(info.ModuleID |> Array.map byte) + wr?WriteSymbolFile moduleGuid +#endif + +//--------------------------------------------------------------------- +// Dumps debug info into a text file for testing purposes +//--------------------------------------------------------------------- +open Printf + +let logDebugInfo (outfile: string) (info: PdbData) = + use sw = new StreamWriter(new FileStream(outfile + ".debuginfo", FileMode.Create)) + + fprintfn sw "ENTRYPOINT\r\n %b\r\n" info.EntryPoint.IsSome + fprintfn sw "DOCUMENTS" + for i, doc in Seq.zip [0 .. info.Documents.Length-1] info.Documents do + // File names elided because they are ephemeral during testing + fprintfn sw " [%d] " i // doc.File + fprintfn sw " Type: %A" doc.DocumentType + fprintfn sw " Language: %A" doc.Language + fprintfn sw " Vendor: %A" doc.Vendor + + // Sort methods (because they are sorted in PDBs/MDBs too) + fprintfn sw "\r\nMETHODS" + Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods + for meth in info.Methods do + fprintfn sw " %s" meth.MethName + fprintfn sw " Params: %A" [ for p in meth.Params -> sprintf "%d: %s" p.Index p.Name ] + fprintfn sw " Range: %A" (meth.Range |> Option.map (fun (f, t) -> + sprintf "[%d,%d:%d] - [%d,%d:%d]" f.Document f.Line f.Column t.Document t.Line t.Column)) + fprintfn sw " Points:" + + for sp in meth.DebugPoints do + fprintfn sw " - Doc: %d Offset:%d [%d:%d]-[%d-%d]" sp.Document sp.Offset sp.Line sp.Column sp.EndLine sp.EndColumn + + // Walk through the tree of scopes and write all variables + fprintfn sw " Scopes:" + let rec writeScope offs (scope: PdbMethodScope) = + fprintfn sw " %s- [%d-%d]" offs scope.StartOffset scope.EndOffset + if scope.Locals.Length > 0 then + fprintfn sw " %s Locals: %A" offs [ for p in scope.Locals -> sprintf "%d: %s" p.Index p.Name ] + for child in scope.Children do writeScope (offs + " ") child + + match meth.RootScope with + | None -> () + | Some rootscope -> writeScope "" rootscope + fprintfn sw "" + +let rec allNamesOfScope acc (scope: PdbMethodScope) = + let acc = (acc, scope.Locals) ||> Array.fold (fun z l -> Set.add l.Name z) + let acc = (acc, scope.Children) ||> allNamesOfScopes + acc +and allNamesOfScopes acc (scopes: PdbMethodScope[]) = + (acc, scopes) ||> Array.fold allNamesOfScope + +let rec pushShadowedLocals (localsToPush: PdbLocalVar[]) (scope: PdbMethodScope) = + // Check if child scopes are properly nested + if scope.Children |> Array.forall (fun child -> + child.StartOffset >= scope.StartOffset && child.EndOffset <= scope.EndOffset) then + + let children = scope.Children |> Array.sortWith scopeSorter + + // Find all the names defined in this scope + let scopeNames = set [| for n in scope.Locals -> n.Name |] + + // Rename if necessary as we push + let rename, unprocessed = localsToPush |> Array.partition (fun l -> scopeNames.Contains l.Name) + let renamed = [| for l in rename -> { l with Name = l.Name + " (shadowed)" } |] + + let localsToPush2 = [| yield! renamed; yield! unprocessed; yield! scope.Locals |] + let newChildren, splits = children |> Array.map (pushShadowedLocals localsToPush2) |> Array.unzip + + // Check if a rename in any of the children forces a split + if splits |> Array.exists id then + let results = + [| + // First fill in the gaps between the children with an adjusted version of this scope. + let gaps = + [| yield (scope.StartOffset, scope.StartOffset) + for newChild in children do + yield (newChild.StartOffset, newChild.EndOffset) + yield (scope.EndOffset, scope.EndOffset) |] + + for ((_,a),(b,_)) in Array.pairwise gaps do + if a < b then + yield { scope with Locals=localsToPush2; Children = [| |]; StartOffset = a; EndOffset = b} + + yield! Array.concat newChildren + |] + let results2 = results |> Array.sortWith scopeSorter + results2, true + else + let splitsParent = renamed.Length > 0 + [| { scope with Locals=localsToPush2 } |], splitsParent + else + [| scope |], false + +// Check to see if a scope has a local with the same name as any of its children +// +// If so, do not emit 'scope' itself. Instead, +// 1. Emit a copy of 'scope' in each true gap, with all locals +// 2. Adjust each child scope to also contain the locals from 'scope', +// adding the text " (shadowed)" to the names of those with name conflicts. +let unshadowScopes rootScope = + let result, _ = pushShadowedLocals [| |] rootScope + result diff --git a/src/fsharp/absil/ilwritepdb.fsi b/src/fsharp/absil/ilwritepdb.fsi new file mode 100644 index 00000000000..f4f1eb86f96 --- /dev/null +++ b/src/fsharp/absil/ilwritepdb.fsi @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// The ILPdbWriter +module internal FSharp.Compiler.AbstractIL.ILPdbWriter + +open Internal.Utilities +open FSharp.Compiler.AbstractIL.IL +open System.IO +open System.Reflection.Metadata + +type PdbDocumentData = ILSourceDocument + +type PdbLocalVar = + { + Name: string + + Signature: byte[] + + /// the local index the name corresponds to + Index: int32 + } + +/// Defines the set of 'imports' - that is, opened namespaces, types etc. - at each code location +/// +/// Note the C# debug evaluation engine used for F# will give C# semantics to these. That in general +/// is very close to F# semantics, except for things like union type. +type PdbImport = + + /// Represents an 'open type XYZ' opening a type + | ImportType of targetTypeToken: int32 (* alias: string option *) + + /// Represents an 'open XYZ' opening a namespace + | ImportNamespace of targetNamespace: string (* assembly: ILAssemblyRef option * alias: string option *) + //| ReferenceAlias of string + //| OpenXmlNamespace of prefix: string * xmlNamespace: string + +type PdbImports = + { + Parent: PdbImports option + Imports: PdbImport[] + } + +type PdbMethodScope = + { + Children: PdbMethodScope[] + StartOffset: int + EndOffset: int + Locals: PdbLocalVar[] + Imports: PdbImports option + } + +type PdbSourceLoc = + { + Document: int + Line: int + Column: int + } + +type PdbDebugPoint = + { + Document: int + Offset: int + Line: int + Column: int + EndLine: int + EndColumn: int + } + +type PdbMethodData = + { + MethToken: int32 + MethName:string + LocalSignatureToken: int32 + Params: PdbLocalVar[] + RootScope: PdbMethodScope option + Range: (PdbSourceLoc * PdbSourceLoc) option + DebugPoints: PdbDebugPoint[] + } + +[] +type PdbData = + { + EntryPoint: int32 option + Timestamp: int32 + /// MVID of the generated .NET module (used by MDB files to identify debug info) + ModuleID: byte[] + Documents: PdbDocumentData[] + Methods: PdbMethodData[] + TableRowCounts: int[] + } + +/// Takes the output file name and returns debug file name. +val getDebugFileName: string -> bool -> string + +/// 28 is the size of the IMAGE_DEBUG_DIRECTORY in ntimage.h +val sizeof_IMAGE_DEBUG_DIRECTORY : System.Int32 + +val logDebugInfo : string -> PdbData -> unit + +#if ENABLE_MONO_SUPPORT +val writeMdbInfo<'a> : string -> string -> PdbData -> 'a +#endif + +type BinaryChunk = + { size: int32 + addr: int32 } + +type idd = + { iddCharacteristics: int32; + iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) + iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) + iddType: int32; + iddTimestamp: int32; + iddData: byte[]; + iddChunk: BinaryChunk } + +type HashAlgorithm = + | Sha1 + | Sha256 + +val generatePortablePdb : embedAllSource: bool -> embedSourceList: string list -> sourceLink: string -> checksumAlgorithm: HashAlgorithm -> showTimes: bool -> info: PdbData -> pathMap:PathMap -> int64 * BlobContentId * MemoryStream * string * byte[] + +val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> int64 * BlobContentId * MemoryStream + +val embedPortablePdbInfo: uncompressedLength: int64 -> contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> cvChunk: BinaryChunk -> pdbChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPdb: bool -> deterministic: bool -> idd[] + +val writePortablePdbInfo: contentId: BlobContentId -> stream: MemoryStream -> showTimes: bool -> fpdb: string -> pathMap: PathMap -> cvChunk: BinaryChunk -> deterministicPdbChunk: BinaryChunk -> checksumPdbChunk: BinaryChunk -> algorithmName: string -> checksum: byte[] -> embeddedPdb: bool -> deterministic: bool -> idd[] + +#if !FX_NO_PDB_WRITER +val writePdbInfo : showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> cvChunk:BinaryChunk -> idd[] +#endif + +/// Check to see if a scope has a local with the same name as any of its children +/// +/// If so, do not emit 'scope' itself. Instead, +/// 1. Emit a copy of 'scope' in each true gap, with all locals +/// 2. Adjust each child scope to also contain the locals from 'scope', +/// adding the text " (shadowed)" to the names of those with name conflicts. +val unshadowScopes: PdbMethodScope -> PdbMethodScope[] diff --git a/src/fsharp/absil/ilx.fs b/src/fsharp/absil/ilx.fs new file mode 100644 index 00000000000..dd6a842e868 --- /dev/null +++ b/src/fsharp/absil/ilx.fs @@ -0,0 +1,164 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Defines an extension of the IL algebra +module internal FSharp.Compiler.AbstractIL.ILX.Types + +open FSharp.Compiler.AbstractIL.IL +open Internal.Utilities.Library + +let mkLowerName (nm: string) = + // Use the lower case name of a field or constructor as the field/parameter name if it differs from the uppercase name + let lowerName = String.uncapitalize nm + if lowerName = nm then "_" + nm else lowerName + +[] +type IlxUnionCaseField(fd: ILFieldDef) = + let lowerName = mkLowerName fd.Name + member x.ILField = fd + member x.Type = x.ILField.FieldType + member x.Name = x.ILField.Name + member x.LowerName = lowerName + +type IlxUnionCase = + { altName: string + altFields: IlxUnionCaseField[] + altCustomAttrs: ILAttributes } + + member x.FieldDefs = x.altFields + member x.FieldDef n = x.altFields.[n] + member x.Name = x.altName + member x.IsNullary = (x.FieldDefs.Length = 0) + member x.FieldTypes = x.FieldDefs |> Array.map (fun fd -> fd.Type) + +type IlxUnionHasHelpers = + | NoHelpers + | AllHelpers + | SpecialFSharpListHelpers + | SpecialFSharpOptionHelpers + +type IlxUnionRef = + | IlxUnionRef of boxity: ILBoxity * ILTypeRef * IlxUnionCase[] * bool * (* hasHelpers: *) IlxUnionHasHelpers + +type IlxUnionSpec = + | IlxUnionSpec of IlxUnionRef * ILGenericArgs + member x.DeclaringType = let (IlxUnionSpec(IlxUnionRef(bx, tref, _, _, _), inst)) = x in mkILNamedTy bx tref inst + member x.Boxity = let (IlxUnionSpec(IlxUnionRef(bx, _, _, _, _), _)) = x in bx + member x.TypeRef = let (IlxUnionSpec(IlxUnionRef(_, tref, _, _, _), _)) = x in tref + member x.GenericArgs = let (IlxUnionSpec(_, inst)) = x in inst + member x.AlternativesArray = let (IlxUnionSpec(IlxUnionRef(_, _, alts, _, _), _)) = x in alts + member x.IsNullPermitted = let (IlxUnionSpec(IlxUnionRef(_, _, _, np, _), _)) = x in np + member x.HasHelpers = let (IlxUnionSpec(IlxUnionRef(_, _, _, _, b), _)) = x in b + member x.Alternatives = Array.toList x.AlternativesArray + member x.Alternative idx = x.AlternativesArray.[idx] + member x.FieldDef idx fidx = x.Alternative(idx).FieldDef(fidx) + +type IlxClosureLambdas = + | Lambdas_forall of ILGenericParameterDef * IlxClosureLambdas + | Lambdas_lambda of ILParameter * IlxClosureLambdas + | Lambdas_return of ILType + +type IlxClosureApps = + | Apps_tyapp of ILType * IlxClosureApps + | Apps_app of ILType * IlxClosureApps + | Apps_done of ILType + +let rec instAppsAux n inst = function + | Apps_tyapp (ty, rty) -> Apps_tyapp(instILTypeAux n inst ty, instAppsAux n inst rty) + | Apps_app (dty, rty) -> Apps_app(instILTypeAux n inst dty, instAppsAux n inst rty) + | Apps_done rty -> Apps_done(instILTypeAux n inst rty) + +let rec instLambdasAux n inst = function + | Lambdas_forall (b, rty) -> + Lambdas_forall(b, instLambdasAux n inst rty) + | Lambdas_lambda (p, rty) -> + Lambdas_lambda({ p with Type=instILTypeAux n inst p.Type}, instLambdasAux n inst rty) + | Lambdas_return rty -> Lambdas_return(instILTypeAux n inst rty) + +let instLambdas i t = instLambdasAux 0 i t + +type IlxClosureFreeVar = + { fvName: string + fvCompilerGenerated:bool + fvType: ILType } + +let mkILFreeVar (name, compgen, ty) = + { fvName=name + fvCompilerGenerated=compgen + fvType=ty } + + +type IlxClosureRef = + | IlxClosureRef of ILTypeRef * IlxClosureLambdas * IlxClosureFreeVar[] + +type IlxClosureSpec = + | IlxClosureSpec of IlxClosureRef * ILGenericArgs * ILType * useStaticField: bool + + member x.TypeRef = let (IlxClosureRef(tref, _, _)) = x.ClosureRef in tref + + member x.ILType = let (IlxClosureSpec(_, _, ty, _)) = x in ty + + member x.ClosureRef = let (IlxClosureSpec(cloref, _, _, _)) = x in cloref + + member x.FormalFreeVars = let (IlxClosureRef(_, _, fvs)) = x.ClosureRef in fvs + + member x.FormalLambdas = let (IlxClosureRef(_, lambdas, _)) = x.ClosureRef in lambdas + + member x.GenericArgs = let (IlxClosureSpec(_, inst, _, _)) = x in inst + + static member Create (cloref, inst, useStaticField) = + let (IlxClosureRef(tref, _, _)) = cloref + IlxClosureSpec(cloref, inst, mkILBoxedType (mkILTySpec (tref, inst)), useStaticField) + + member x.Constructor = + let cloTy = x.ILType + let fields = x.FormalFreeVars + mkILCtorMethSpecForTy (cloTy, fields |> Array.map (fun fv -> fv.fvType) |> Array.toList) + + member x.UseStaticField = + let (IlxClosureSpec(_, _, _, useStaticField)) = x + useStaticField + + member x.GetStaticFieldSpec() = + assert x.UseStaticField + let formalCloTy = mkILFormalBoxedTy x.TypeRef (mkILFormalTypars x.GenericArgs) + mkILFieldSpecInTy (x.ILType, "@_instance", formalCloTy) + +// Define an extension of the IL algebra of type definitions +type IlxClosureInfo = + { cloStructure: IlxClosureLambdas + cloFreeVars: IlxClosureFreeVar[] + cloCode: Lazy + cloUseStaticField: bool} + +type IlxUnionInfo = + { + UnionCasesAccessibility: ILMemberAccess + + HelpersAccessibility: ILMemberAccess + + HasHelpers: IlxUnionHasHelpers + + GenerateDebugProxies: bool + + DebugDisplayAttributes: ILAttribute list + + UnionCases: IlxUnionCase[] + + IsNullPermitted: bool + + DebugPoint: ILDebugPoint option + + DebugImports: ILDebugImports option + } + +// -------------------------------------------------------------------- +// Define these as extensions of the IL types +// -------------------------------------------------------------------- + +let destTyFuncApp = function Apps_tyapp (b, c) -> b, c | _ -> failwith "destTyFuncApp" + +let mkILFormalCloRef gparams csig useStaticField = IlxClosureSpec.Create(csig, mkILFormalGenericArgs 0 gparams, useStaticField) + +let actualTypOfIlxUnionField (cuspec : IlxUnionSpec) idx fidx = + instILType cuspec.GenericArgs (cuspec.FieldDef idx fidx).Type + diff --git a/src/fsharp/absil/ilx.fsi b/src/fsharp/absil/ilx.fsi new file mode 100644 index 00000000000..b718761b971 --- /dev/null +++ b/src/fsharp/absil/ilx.fsi @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// ILX extensions to Abstract IL types and instructions F# +module internal FSharp.Compiler.AbstractIL.ILX.Types + +open FSharp.Compiler.AbstractIL.IL + +/// Union case field +[] +type IlxUnionCaseField = + new: ILFieldDef -> IlxUnionCaseField + member Type: ILType + member Name: string + /// The name used for the field in parameter or IL field position. + member LowerName: string + member ILField: ILFieldDef + +/// Union alternative +type IlxUnionCase = + { altName: string + altFields: IlxUnionCaseField[] + altCustomAttrs: ILAttributes } + + member FieldDefs: IlxUnionCaseField[] + member FieldDef: int -> IlxUnionCaseField + member Name: string + member IsNullary : bool + member FieldTypes: ILType[] + + +type IlxUnionHasHelpers = + | NoHelpers + | AllHelpers + | SpecialFSharpListHelpers + | SpecialFSharpOptionHelpers + +/// Union references +type IlxUnionRef = + | IlxUnionRef of boxity: ILBoxity * ILTypeRef * IlxUnionCase[] * bool (* IsNullPermitted *) * IlxUnionHasHelpers (* HasHelpers *) + +type IlxUnionSpec = + | IlxUnionSpec of IlxUnionRef * ILGenericArgs + + member DeclaringType: ILType + + member GenericArgs: ILGenericArgs + + member Alternatives: IlxUnionCase list + + member AlternativesArray: IlxUnionCase[] + + member Boxity: ILBoxity + + member TypeRef: ILTypeRef + + member IsNullPermitted: bool + + member HasHelpers: IlxUnionHasHelpers + + member Alternative: int -> IlxUnionCase + + member FieldDef: int -> int -> IlxUnionCaseField + +// -------------------------------------------------------------------- +// Closure references +// -------------------------------------------------------------------- + +type IlxClosureLambdas = + | Lambdas_forall of ILGenericParameterDef * IlxClosureLambdas + | Lambdas_lambda of ILParameter * IlxClosureLambdas + | Lambdas_return of ILType + +type IlxClosureFreeVar = + { fvName: string + fvCompilerGenerated:bool + fvType: ILType } + +type IlxClosureRef = + | IlxClosureRef of ILTypeRef * IlxClosureLambdas * IlxClosureFreeVar[] + +/// Represents a usage of a closure +type IlxClosureSpec = + | IlxClosureSpec of IlxClosureRef * ILGenericArgs * ILType * useStaticField: bool + + member TypeRef: ILTypeRef + + member ILType: ILType + + member ClosureRef: IlxClosureRef + + member FormalLambdas: IlxClosureLambdas + + member FormalFreeVars: IlxClosureFreeVar[] + + member GenericArgs: ILGenericArgs + + static member Create: IlxClosureRef * ILGenericArgs * useStaticField: bool -> IlxClosureSpec + + /// Get the constructor for the closure + member Constructor: ILMethodSpec + + /// Get the static field used to store an instance of this closure, if useStaticField is true + member GetStaticFieldSpec: unit -> ILFieldSpec + + /// Indicates if a static field being used to store an instance of this closure (because it has no free variables) + member UseStaticField: bool + + +/// IlxClosureApps - i.e. types being applied at a callsite. +type IlxClosureApps = + | Apps_tyapp of ILType * IlxClosureApps + | Apps_app of ILType * IlxClosureApps + | Apps_done of ILType + +/// Represents a closure prior to erasure +type IlxClosureInfo = + { + cloStructure: IlxClosureLambdas + cloFreeVars: IlxClosureFreeVar[] + cloCode: Lazy + cloUseStaticField: bool + } + +/// Represents a discriminated union type prior to erasure +type IlxUnionInfo = + { + /// Is the representation public? + UnionCasesAccessibility: ILMemberAccess + + /// Are the representation helpers public? + HelpersAccessibility: ILMemberAccess + + /// Generate the helpers? + HasHelpers: IlxUnionHasHelpers + + GenerateDebugProxies: bool + + DebugDisplayAttributes: ILAttribute list + + UnionCases: IlxUnionCase[] + + IsNullPermitted: bool + + /// Debug info for generated code for classunions. + DebugPoint: ILDebugPoint option + + /// Debug info for generated code for classunions + DebugImports: ILDebugImports option + } + +// -------------------------------------------------------------------- +// MS-ILX constructs: Closures, thunks, classunions +// -------------------------------------------------------------------- + +val instAppsAux: int -> ILGenericArgs -> IlxClosureApps -> IlxClosureApps +val destTyFuncApp: IlxClosureApps -> ILType * IlxClosureApps + +val mkILFormalCloRef: ILGenericParameterDefs -> IlxClosureRef -> useStaticField: bool -> IlxClosureSpec + +// -------------------------------------------------------------------- +// MS-ILX: Unions +// -------------------------------------------------------------------- + +val actualTypOfIlxUnionField: IlxUnionSpec -> int -> int -> ILType + +val mkILFreeVar: string * bool * ILType -> IlxClosureFreeVar diff --git a/src/absil/zmap.fs b/src/fsharp/absil/zmap.fs similarity index 86% rename from src/absil/zmap.fs rename to src/fsharp/absil/zmap.fs index 5378c262957..92edf3d1d1f 100644 --- a/src/absil/zmap.fs +++ b/src/fsharp/absil/zmap.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.AbstractIL.Internal +namespace Internal.Utilities.Collections open Internal.Utilities.Collections.Tagged open System.Collections.Generic @@ -8,7 +8,6 @@ open System.Collections.Generic /// Maps with a specific comparison function type internal Zmap<'Key,'T> = Internal.Utilities.Collections.Tagged.Map<'Key,'T> -[] module internal Zmap = let empty (ord: IComparer<'T>) = Map<_,_,_>.Empty(ord) @@ -18,12 +17,12 @@ module internal Zmap = let tryFind k (m: Zmap<_,_>) = m.TryFind(k) let remove k (m: Zmap<_,_>) = m.Remove(k) let mem k (m: Zmap<_,_>) = m.ContainsKey(k) - let iter f (m: Zmap<_,_>) = m.Iterate(f) + let iter action (m: Zmap<_,_>) = m.Iterate(action) let first f (m: Zmap<_,_>) = m.First(fun k v -> if f k v then Some (k,v) else None) let exists f (m: Zmap<_,_>) = m.Exists(f) let forall f (m: Zmap<_,_>) = m.ForAll(f) - let map f (m: Zmap<_,_>) = m.MapRange(f) - let mapi f (m: Zmap<_,_>) = m.Map(f) + let map mapping (m: Zmap<_,_>) = m.MapRange(mapping) + let mapi mapping (m: Zmap<_,_>) = m.Map(mapping) let fold f (m: Zmap<_,_>) x = m.Fold f x let toList (m: Zmap<_,_>) = m.ToList() let foldSection lo hi f (m: Zmap<_,_>) x = m.FoldSection lo hi f x diff --git a/src/absil/zmap.fsi b/src/fsharp/absil/zmap.fsi similarity index 85% rename from src/absil/zmap.fsi rename to src/fsharp/absil/zmap.fsi index 733d11870f1..6c67f239770 100644 --- a/src/absil/zmap.fsi +++ b/src/fsharp/absil/zmap.fsi @@ -1,16 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.AbstractIL.Internal +namespace Internal.Utilities.Collections -open Internal.Utilities -open Internal.Utilities.Collections.Tagged -open FSharp.Compiler.AbstractIL.Internal.Library open System.Collections.Generic /// Maps with a specific comparison function type internal Zmap<'Key,'T> = Internal.Utilities.Collections.Tagged.Map<'Key,'T> -[] module internal Zmap = val empty : IComparer<'Key> -> Zmap<'Key,'T> @@ -24,7 +20,7 @@ module internal Zmap = val find : 'Key -> Zmap<'Key,'T> -> 'T // raises KeyNotFoundException val map : mapping:('T -> 'U) -> Zmap<'Key,'T> -> Zmap<'Key,'U> - val mapi : ('Key -> 'T -> 'U) -> Zmap<'Key,'T> -> Zmap<'Key,'U> + val mapi : mapping:('Key -> 'T -> 'U) -> Zmap<'Key,'T> -> Zmap<'Key,'U> val fold : ('Key -> 'T -> 'U -> 'U) -> Zmap<'Key,'T> -> 'U -> 'U val foldMap : ('State -> 'Key -> 'T -> 'State * 'U) -> 'State -> Zmap<'Key,'T> -> 'State * Zmap<'Key,'U> val iter : action:('T -> 'U -> unit) -> Zmap<'T, 'U> -> unit diff --git a/src/absil/zset.fs b/src/fsharp/absil/zset.fs similarity index 81% rename from src/absil/zset.fs rename to src/fsharp/absil/zset.fs index aee52eb68e3..c8314294108 100644 --- a/src/absil/zset.fs +++ b/src/fsharp/absil/zset.fs @@ -1,16 +1,13 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.AbstractIL.Internal +namespace Internal.Utilities.Collections -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal.Library open Internal.Utilities.Collections.Tagged open System.Collections.Generic /// Sets with a specific comparison function type internal Zset<'T> = Internal.Utilities.Collections.Tagged.Set<'T> -[] module internal Zset = let empty (ord : IComparer<'T>) = Internal.Utilities.Collections.Tagged.Set<_,_>.Empty(ord) @@ -31,11 +28,11 @@ module internal Zset = let iter f (s: Zset<_>) = s.Iterate f - let forall p (s: Zset<_>) = s.ForAll p + let forall predicate (s: Zset<_>) = s.ForAll predicate let count (s: Zset<_>) = s.Count - let exists p (s: Zset<_>) = s.Exists p + let exists predicate (s: Zset<_>) = s.Exists predicate let subset (s1: Zset<_>) (s2: Zset<_>) = s1.IsSubsetOf s2 @@ -43,7 +40,7 @@ module internal Zset = let elements (s: Zset<_>) = s.ToList() - let filter p (s: Zset<_>) = s.Filter p + let filter predicate (s: Zset<_>) = s.Filter predicate let union (s1: Zset<_>) (s2: Zset<_>) = Internal.Utilities.Collections.Tagged.Set<_,_>.Union(s1,s2) diff --git a/src/absil/zset.fsi b/src/fsharp/absil/zset.fsi similarity index 85% rename from src/absil/zset.fsi rename to src/fsharp/absil/zset.fsi index 5d1d3419747..e78b28fb2d5 100644 --- a/src/absil/zset.fsi +++ b/src/fsharp/absil/zset.fsi @@ -1,17 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.AbstractIL.Internal +namespace Internal.Utilities.Collections -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal.Library open System.Collections.Generic /// Sets with a specific comparison function type internal Zset<'T> = Internal.Utilities.Collections.Tagged.Set<'T> - -[] module internal Zset = val empty : IComparer<'T> -> Zset<'T> diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs deleted file mode 100644 index 524f73965ed..00000000000 --- a/src/fsharp/ast.fs +++ /dev/null @@ -1,2480 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module public FSharp.Compiler.Ast - -open Internal.Utilities.Text.Lexing -open Internal.Utilities.Text.Parsing -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler -open FSharp.Compiler.UnicodeLexing -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Features -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range - -/// The prefix of the names used for the fake namespace path added to all dynamic code entries in FSI.EXE -let FsiDynamicModulePrefix = "FSI_" - -[] -module FSharpLib = - let Root = "Microsoft.FSharp" - let RootPath = IL.splitNamespace Root - let Core = Root + ".Core" - let CorePath = IL.splitNamespace Core - -[] -module CustomOperations = - [] - let Into = "into" - -//------------------------------------------------------------------------ -// XML doc pre-processing -//----------------------------------------------------------------------- - - -/// Used to collect XML documentation during lexing and parsing. -type XmlDocCollector() = - let mutable savedLines = new ResizeArray<(string * pos)>() - let mutable savedGrabPoints = new ResizeArray() - let posCompare p1 p2 = if posGeq p1 p2 then 1 else if posEq p1 p2 then 0 else -1 - let savedGrabPointsAsArray = - lazy (savedGrabPoints.ToArray() |> Array.sortWith posCompare) - - let savedLinesAsArray = - lazy (savedLines.ToArray() |> Array.sortWith (fun (_, p1) (_, p2) -> posCompare p1 p2)) - - let check() = - assert (not savedLinesAsArray.IsValueCreated && "can't add more XmlDoc elements to XmlDocCollector after extracting first XmlDoc from the overall results" <> "") - - member x.AddGrabPoint pos = - check() - savedGrabPoints.Add pos - - member x.AddXmlDocLine(line, pos) = - check() - savedLines.Add(line, pos) - - member x.LinesBefore grabPointPos = - try - let lines = savedLinesAsArray.Force() - let grabPoints = savedGrabPointsAsArray.Force() - let firstLineIndexAfterGrabPoint = Array.findFirstIndexWhereTrue lines (fun (_, pos) -> posGeq pos grabPointPos) - let grabPointIndex = Array.findFirstIndexWhereTrue grabPoints (fun pos -> posGeq pos grabPointPos) - assert (posEq grabPoints.[grabPointIndex] grabPointPos) - let firstLineIndexAfterPrevGrabPoint = - if grabPointIndex = 0 then - 0 - else - let prevGrabPointPos = grabPoints.[grabPointIndex-1] - Array.findFirstIndexWhereTrue lines (fun (_, pos) -> posGeq pos prevGrabPointPos) - //printfn "#lines = %d, firstLineIndexAfterPrevGrabPoint = %d, firstLineIndexAfterGrabPoint = %d" lines.Length firstLineIndexAfterPrevGrabPoint firstLineIndexAfterGrabPoint - - let lines = lines.[firstLineIndexAfterPrevGrabPoint..firstLineIndexAfterGrabPoint-1] |> Array.rev - if lines.Length = 0 then - [| |] - else - let firstLineNumber = (snd lines.[0]).Line - lines - |> Array.mapi (fun i x -> firstLineNumber - i, x) - |> Array.takeWhile (fun (sequencedLineNumber, (_, pos)) -> sequencedLineNumber = pos.Line) - |> Array.map (fun (_, (lineStr, _)) -> lineStr) - |> Array.rev - with e -> - //printfn "unexpected error in LinesBefore:\n%s" (e.ToString()) - [| |] - -type XmlDoc = - | XmlDoc of string[] - - static member Empty = XmlDocStatics.Empty - - member x.NonEmpty = (let (XmlDoc lines) = x in lines.Length <> 0) - - static member Merge (XmlDoc lines) (XmlDoc lines') = XmlDoc (Array.append lines lines') - - /// This code runs for .XML generation and thus influences cross-project xmldoc tooltips; for within-project tooltips, - /// see XmlDocumentation.fs in the language service - static member Process (XmlDoc lines) = - let rec processLines (lines: string list) = - match lines with - | [] -> [] - | (lineA :: rest) as lines -> - let lineAT = lineA.TrimStart([|' '|]) - if lineAT = "" then processLines rest - else if lineAT.StartsWithOrdinal("<") then lines - else [""] @ - (lines |> List.map (fun line -> Microsoft.FSharp.Core.XmlAdapters.escape line)) @ - [""] - - let lines = processLines (Array.toList lines) - if isNil lines then XmlDoc.Empty - else XmlDoc (Array.ofList lines) - -// Discriminated unions can't contain statics, so we use a separate type -and XmlDocStatics() = - - static let empty = XmlDoc[| |] - - static member Empty = empty - -type PreXmlDoc = - | PreXmlMerge of PreXmlDoc * PreXmlDoc - | PreXmlDoc of pos * XmlDocCollector - | PreXmlDocEmpty - - member x.ToXmlDoc() = - match x with - | PreXmlMerge(a, b) -> XmlDoc.Merge (a.ToXmlDoc()) (b.ToXmlDoc()) - | PreXmlDocEmpty -> XmlDoc.Empty - | PreXmlDoc (pos, collector) -> - let lines = collector.LinesBefore pos - if lines.Length = 0 then XmlDoc.Empty - else XmlDoc lines - - static member CreateFromGrabPoint(collector: XmlDocCollector, grabPointPos) = - collector.AddGrabPoint grabPointPos - PreXmlDoc(grabPointPos, collector) - - static member Empty = PreXmlDocEmpty - - static member Merge a b = PreXmlMerge (a, b) - -type ParserDetail = - | Ok - | ThereWereSignificantParseErrorsSoDoNotTypecheckThisNode // would cause spurious/misleading diagnostics - -//------------------------------------------------------------------------ -// AST: identifiers and long identifiers -//----------------------------------------------------------------------- - -// PERFORMANCE: consider making this a struct. -[] -[] -[] -type Ident (text: string, range: range) = - member x.idText = text - member x.idRange = range - override x.ToString() = text - -type LongIdent = Ident list - -type LongIdentWithDots = - /// LongIdentWithDots(lid, dotms) - /// Typically dotms.Length = lid.Length-1, but they may be same if (incomplete) code ends in a dot, e.g. "Foo.Bar." - /// The dots mostly matter for parsing, and are typically ignored by the typechecker, but - /// if dotms.Length = lid.Length, then the parser must have reported an error, so the typechecker is allowed - /// more freedom about typechecking these expressions. - /// LongIdent can be empty list - it is used to denote that name of some AST element is absent (i.e. empty type name in inherit) - | LongIdentWithDots of id: LongIdent * dotms: range list - - member this.Range = - match this with - | LongIdentWithDots([], _) -> failwith "rangeOfLidwd" - | LongIdentWithDots([id], []) -> id.idRange - | LongIdentWithDots([id], [m]) -> unionRanges id.idRange m - | LongIdentWithDots(h :: t, []) -> unionRanges h.idRange (List.last t).idRange - | LongIdentWithDots(h :: t, dotms) -> unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last dotms) - - member this.Lid = match this with LongIdentWithDots(lid, _) -> lid - - member this.ThereIsAnExtraDotAtTheEnd = match this with LongIdentWithDots(lid, dots) -> lid.Length = dots.Length - - member this.RangeSansAnyExtraDot = - match this with - | LongIdentWithDots([], _) -> failwith "rangeOfLidwd" - | LongIdentWithDots([id], _) -> id.idRange - | LongIdentWithDots(h :: t, dotms) -> - let nonExtraDots = if dotms.Length = t.Length then dotms else List.truncate t.Length dotms - unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last nonExtraDots) - -//------------------------------------------------------------------------ -// AST: the grammar of implicitly scoped type parameters -//----------------------------------------------------------------------- - -type TyparStaticReq = - | NoStaticReq - | HeadTypeStaticReq - -[] -type SynTypar = - | Typar of ident: Ident * staticReq: TyparStaticReq * isCompGen: bool - - member this.Range = - match this with - | Typar(id, _, _) -> - id.idRange - -//------------------------------------------------------------------------ -// AST: the grammar of constants and measures -//----------------------------------------------------------------------- - -type - [] - /// The unchecked abstract syntax tree of constants in F# types and expressions. - SynConst = - - /// F# syntax: () - | Unit - - /// F# syntax: true, false - | Bool of bool - - /// F# syntax: 13y, 0xFFy, 0o077y, 0b0111101y - | SByte of sbyte - - /// F# syntax: 13uy, 0x40uy, 0oFFuy, 0b0111101uy - | Byte of byte - - /// F# syntax: 13s, 0x4000s, 0o0777s, 0b0111101s - | Int16 of int16 - - /// F# syntax: 13us, 0x4000us, 0o0777us, 0b0111101us - | UInt16 of uint16 - - /// F# syntax: 13, 0x4000, 0o0777 - | Int32 of int32 - - /// F# syntax: 13u, 0x4000u, 0o0777u - | UInt32 of uint32 - - /// F# syntax: 13L - | Int64 of int64 - - /// F# syntax: 13UL - | UInt64 of uint64 - - /// F# syntax: 13n - | IntPtr of int64 - - /// F# syntax: 13un - | UIntPtr of uint64 - - /// F# syntax: 1.30f, 1.40e10f etc. - | Single of single - - /// F# syntax: 1.30, 1.40e10 etc. - | Double of double - - /// F# syntax: 'a' - | Char of char - - /// F# syntax: 23.4M - | Decimal of System.Decimal - - /// UserNum(value, suffix) - /// - /// F# syntax: 1Q, 1Z, 1R, 1N, 1G - | UserNum of value: string * suffix: string - - /// F# syntax: verbatim or regular string, e.g. "abc" - | String of text: string * range: range - - /// F# syntax: verbatim or regular byte string, e.g. "abc"B. - /// - /// Also used internally in the typechecker once an array of unit16 constants - /// is detected, to allow more efficient processing of large arrays of uint16 constants. - | Bytes of bytes: byte[] * range: range - - /// Used internally in the typechecker once an array of unit16 constants - /// is detected, to allow more efficient processing of large arrays of uint16 constants. - | UInt16s of uint16[] - - /// Old comment: "we never iterate, so the const here is not another SynConst.Measure" - | Measure of constant: SynConst * SynMeasure - - member c.Range dflt = - match c with - | SynConst.String (_, m0) | SynConst.Bytes (_, m0) -> m0 - | _ -> dflt - -and - [] - /// The unchecked abstract syntax tree of F# unit of measure annotations. - /// This should probably be merged with the representation of SynType. - SynMeasure = - | Named of longId: LongIdent * range: range - - | Product of SynMeasure * SynMeasure * range: range - - | Seq of SynMeasure list * range: range - - | Divide of SynMeasure * SynMeasure * range: range - - | Power of SynMeasure * SynRationalConst * range: range - - | One - - | Anon of range: range - - | Var of SynTypar * range: range - -and - [] - /// The unchecked abstract syntax tree of F# unit of measure exponents. - SynRationalConst = - | Integer of int32 - - | Rational of int32 * int32 * range: range - - | Negate of SynRationalConst - -//------------------------------------------------------------------------ -// AST: the grammar of types, expressions, declarations etc. -//----------------------------------------------------------------------- - -[] -type SynAccess = - | Public - | Internal - | Private - -type SequencePointInfoForTarget = - | SequencePointAtTarget - | SuppressSequencePointAtTarget - -type SequencePointInfoForSeq = - | SequencePointsAtSeq - - // This means "suppress a in 'a;b'" and "suppress b in 'a before b'" - | SuppressSequencePointOnExprOfSequential - - // This means "suppress b in 'a;b'" and "suppress a in 'a before b'" - | SuppressSequencePointOnStmtOfSequential - -type SequencePointInfoForTry = - | SequencePointAtTry of range: range - // Used for "use" and "for" - | SequencePointInBodyOfTry - | NoSequencePointAtTry - -type SequencePointInfoForWith = - | SequencePointAtWith of range: range - | NoSequencePointAtWith - -type SequencePointInfoForFinally = - | SequencePointAtFinally of range: range - | NoSequencePointAtFinally - -type SequencePointInfoForForLoop = - | SequencePointAtForLoop of range: range - | NoSequencePointAtForLoop - -type SequencePointInfoForWhileLoop = - | SequencePointAtWhileLoop of range: range - | NoSequencePointAtWhileLoop - -type SequencePointInfoForBinding = - | SequencePointAtBinding of range: range - - // Indicates the omission of a sequence point for a binding for a 'do expr' - | NoSequencePointAtDoBinding - - // Indicates the omission of a sequence point for a binding for a 'let e = expr' where - // 'expr' has immediate control flow - | NoSequencePointAtLetBinding - - // Indicates the omission of a sequence point for a compiler generated binding - // where we've done a local expansion of some construct into something that involves - // a 'let'. e.g. we've inlined a function and bound its arguments using 'let' - // The let bindings are 'sticky' in that the inversion of the inlining would involve - // replacing the entire expression with the original and not just the let bindings alone. - | NoSequencePointAtStickyBinding - - // Given 'let v = e1 in e2', where this is a compiler generated binding, - // we are sometimes forced to generate a sequence point for the expression anyway based on its - // overall range. If the let binding is given the flag below then it is asserting that - // the binding has no interesting side effects and can be totally ignored and the range - // of the inner expression is used instead - | NoSequencePointAtInvisibleBinding - - // Don't drop sequence points when combining sequence points - member x.Combine(y: SequencePointInfoForBinding) = - match x, y with - | SequencePointAtBinding _ as g, _ -> g - | _, (SequencePointAtBinding _ as g) -> g - | _ -> x - -/// Indicates if a for loop is 'for x in e1 -> e2', only valid in sequence expressions -type SeqExprOnly = - /// Indicates if a for loop is 'for x in e1 -> e2', only valid in sequence expressions - | SeqExprOnly of bool - -/// denotes location of the separator block + optional position of the semicolon (used for tooling support) -type BlockSeparator = range * pos option - -/// stores pair: record field name + (true if given record field name is syntactically correct and can be used in name resolution) -type RecordFieldName = LongIdentWithDots * bool - -type ExprAtomicFlag = - - /// Says that the expression is an atomic expression, i.e. is of a form that has no whitespace unless - /// enclosed in parentheses, e.g. 1, "3", ident, ident.[expr] and (expr). If an atomic expression has - /// type T, then the largest expression ending at the same range as the atomic expression also has type T. - | Atomic = 0 - - | NonAtomic = 1 - -/// The kind associated with a binding - "let", "do" or a standalone expression -type SynBindingKind = - - /// A standalone expression in a module - | StandaloneExpression - - /// A normal 'let' binding in a module - | NormalBinding - - /// A 'do' binding in a module. Must have type 'unit' - | DoBinding - -type - [] - /// Represents the explicit declaration of a type parameter - SynTyparDecl = - | TyparDecl of attributes: SynAttributes * SynTypar - -and - [] - /// The unchecked abstract syntax tree of F# type constraints - SynTypeConstraint = - - /// F# syntax: is 'typar: struct - | WhereTyparIsValueType of genericName: SynTypar * range: range - - /// F# syntax: is 'typar: not struct - | WhereTyparIsReferenceType of genericName: SynTypar * range: range - - /// F# syntax is 'typar: unmanaged - | WhereTyparIsUnmanaged of genericName: SynTypar * range: range - - /// F# syntax is 'typar: null - | WhereTyparSupportsNull of genericName: SynTypar * range: range - - /// F# syntax is 'typar: comparison - | WhereTyparIsComparable of genericName: SynTypar * range: range - - /// F# syntax is 'typar: equality - | WhereTyparIsEquatable of genericName: SynTypar * range: range - - /// F# syntax is default ^T: type - | WhereTyparDefaultsToType of genericName: SynTypar * typeName: SynType * range: range - - /// F# syntax is 'typar :> type - | WhereTyparSubtypeOfType of genericName: SynTypar * typeName: SynType * range: range - - /// F# syntax is ^T: (static member MemberName: ^T * int -> ^T) - | WhereTyparSupportsMember of genericNames: SynType list * memberSig: SynMemberSig * range: range - - /// F# syntax is 'typar: enum<'UnderlyingType> - | WhereTyparIsEnum of genericName: SynTypar * SynType list * range: range - - /// F# syntax is 'typar: delegate<'Args, unit> - | WhereTyparIsDelegate of genericName: SynTypar * SynType list * range: range - -and - [] - /// The unchecked abstract syntax tree of F# types - SynType = - /// F# syntax: A.B.C - | LongIdent of longDotId: LongIdentWithDots - /// App(typeName, LESSm, typeArgs, commasm, GREATERm, isPostfix, m) - /// - /// F# syntax: type or type type or (type, ..., type) type - /// isPostfix: indicates a postfix type application e.g. "int list" or "(int, string) dict" - /// commasm: ranges for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them - | App of typeName: SynType * LESSrange: range option * typeArgs: SynType list * commaRanges: range list * GREATERrange: range option * isPostfix: bool * range: range - /// LongIdentApp(typeName, longId, LESSm, tyArgs, commasm, GREATERm, wholem) - /// - /// F# syntax: type.A.B.C - /// commasm: ranges for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them - | LongIdentApp of typeName: SynType * longDotId: LongIdentWithDots * LESSRange: range option * typeArgs: SynType list * commaRanges: range list * GREATERrange: range option * range: range - - /// F# syntax: type * ... * type - /// F# syntax: struct (type * ... * type) - // the bool is true if / rather than * follows the type - | Tuple of isStruct: bool * typeNames:(bool*SynType) list * range: range - - /// F# syntax: {| id: type; ...; id: type |} - /// F# syntax: struct {| id: type; ...; id: type |} - | AnonRecd of isStruct: bool * typeNames:(Ident * SynType) list * range: range - - /// F# syntax: type[] - | Array of int * elementType: SynType * range: range - - /// F# syntax: type -> type - | Fun of argType: SynType * returnType: SynType * range: range - - /// F# syntax: 'Var - | Var of genericName: SynTypar * range: range - - /// F# syntax: _ - | Anon of range: range - - /// F# syntax: typ with constraints - | WithGlobalConstraints of typeName: SynType * constraints: SynTypeConstraint list * range: range - - /// F# syntax: #type - | HashConstraint of SynType * range: range - - /// F# syntax: for units of measure e.g. m / s - | MeasureDivide of dividendType: SynType * divisorType: SynType * range: range - - /// F# syntax: for units of measure e.g. m^3, kg^1/2 - | MeasurePower of measureType: SynType * SynRationalConst * range: range - - /// F# syntax: 1, "abc" etc, used in parameters to type providers - /// For the dimensionless units i.e. 1, and static parameters to provided types - | StaticConstant of constant: SynConst * range: range - - /// F# syntax: const expr, used in static parameters to type providers - | StaticConstantExpr of expr: SynExpr * range: range - - /// F# syntax: ident=1 etc., used in static parameters to type providers - | StaticConstantNamed of expr: SynType * SynType * range: range - - /// Get the syntactic range of source code covered by this construct. - member x.Range = - match x with - | SynType.App (range=m) - | SynType.LongIdentApp (range=m) - | SynType.Tuple (range=m) - | SynType.Array (range=m) - | SynType.AnonRecd (range=m) - | SynType.Fun (range=m) - | SynType.Var (range=m) - | SynType.Anon (range=m) - | SynType.WithGlobalConstraints (range=m) - | SynType.StaticConstant (range=m) - | SynType.StaticConstantExpr (range=m) - | SynType.StaticConstantNamed (range=m) - | SynType.HashConstraint (range=m) - | SynType.MeasureDivide (range=m) - | SynType.MeasurePower (range=m) -> m - | SynType.LongIdent lidwd -> lidwd.Range - -and - [] - SynExpr = - - /// F# syntax: (expr) - /// - /// Paren(expr, leftParenRange, rightParenRange, wholeRangeIncludingParentheses) - /// - /// Parenthesized expressions. Kept in AST to distinguish A.M((x, y)) - /// from A.M(x, y), among other things. - | Paren of expr: SynExpr * leftParenRange: range * rightParenRange: range option * range: range - - /// F# syntax: <@ expr @>, <@@ expr @@> - /// - /// Quote(operator, isRaw, quotedSynExpr, isFromQueryExpression, m) - | Quote of operator: SynExpr * isRaw: bool * quotedSynExpr: SynExpr * isFromQueryExpression: bool * range: range - - /// F# syntax: 1, 1.3, () etc. - | Const of constant: SynConst * range: range - - /// F# syntax: expr: type - | Typed of expr: SynExpr * typeName: SynType * range: range - - /// F# syntax: e1, ..., eN - | Tuple of isStruct: bool * exprs: SynExpr list * commaRanges: range list * range: range // "range list" is for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them - - /// F# syntax: {| id1=e1; ...; idN=eN |} - /// F# syntax: struct {| id1=e1; ...; idN=eN |} - | AnonRecd of isStruct: bool * copyInfo:(SynExpr * BlockSeparator) option * recordFields:(Ident * SynExpr) list * range: range - - /// F# syntax: [ e1; ...; en ], [| e1; ...; en |] - | ArrayOrList of isList: bool * exprs: SynExpr list * range: range - - /// F# syntax: { f1=e1; ...; fn=en } - /// SynExpr.Record ((baseType, baseCtorArgs, mBaseCtor, sepAfterBase, mInherits), (copyExpr, sepAfterCopyExpr), (recordFieldName, fieldValue, sepAfterField), mWholeExpr) - /// inherit includes location of separator (for tooling) - /// copyOpt contains range of the following WITH part (for tooling) - /// every field includes range of separator after the field (for tooling) - | Record of baseInfo:(SynType * SynExpr * range * BlockSeparator option * range) option * copyInfo:(SynExpr * BlockSeparator) option * recordFields:(RecordFieldName * (SynExpr option) * BlockSeparator option) list * range: range - - /// F# syntax: new C(...) - /// The flag is true if known to be 'family' ('protected') scope - | New of isProtected: bool * typeName: SynType * expr: SynExpr * range: range - - /// SynExpr.ObjExpr (objTy, argOpt, binds, extraImpls, mNewExpr, mWholeExpr) - /// - /// F# syntax: { new ... with ... } - | ObjExpr of objType: SynType * argOptions:(SynExpr * Ident option) option * bindings: SynBinding list * extraImpls: SynInterfaceImpl list * newExprRange: range * range: range - - /// F# syntax: 'while ... do ...' - | While of whileSeqPoint: SequencePointInfoForWhileLoop * whileExpr: SynExpr * doExpr: SynExpr * range: range - - /// F# syntax: 'for i = ... to ... do ...' - | For of forSeqPoint: SequencePointInfoForForLoop * ident: Ident * identBody: SynExpr * bool * toBody: SynExpr * doBody: SynExpr * range: range - - /// SynExpr.ForEach (spBind, seqExprOnly, isFromSource, pat, enumExpr, bodyExpr, mWholeExpr). - /// - /// F# syntax: 'for ... in ... do ...' - | ForEach of forSeqPoint: SequencePointInfoForForLoop * seqExprOnly: SeqExprOnly * isFromSource: bool * pat: SynPat * enumExpr: SynExpr * bodyExpr: SynExpr * range: range - - /// F# syntax: [ expr ], [| expr |] - | ArrayOrListOfSeqExpr of isArray: bool * expr: SynExpr * range: range - - /// CompExpr(isArrayOrList, isNotNakedRefCell, expr) - /// - /// F# syntax: { expr } - | CompExpr of isArrayOrList: bool * isNotNakedRefCell: bool ref * expr: SynExpr * range: range - - /// First bool indicates if lambda originates from a method. Patterns here are always "simple" - /// Second bool indicates if this is a "later" part of an iterated sequence of lambdas - /// - /// F# syntax: fun pat -> expr - | Lambda of fromMethod: bool * inLambdaSeq: bool * args: SynSimplePats * body: SynExpr * range: range - - /// F# syntax: function pat1 -> expr | ... | patN -> exprN - | MatchLambda of isExnMatch: bool * range * SynMatchClause list * matchSeqPoint: SequencePointInfoForBinding * range: range - - /// F# syntax: match expr with pat1 -> expr | ... | patN -> exprN - | Match of matchSeqPoint: SequencePointInfoForBinding * expr: SynExpr * clauses: SynMatchClause list * range: range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) - - /// F# syntax: do expr - | Do of expr: SynExpr * range: range - - /// F# syntax: assert expr - | Assert of expr: SynExpr * range: range - - /// App(exprAtomicFlag, isInfix, funcExpr, argExpr, m) - /// - exprAtomicFlag: indicates if the application is syntactically atomic, e.g. f.[1] is atomic, but 'f x' is not - /// - isInfix is true for the first app of an infix operator, e.g. 1+2 becomes App(App(+, 1), 2), where the inner node is marked isInfix - /// (or more generally, for higher operator fixities, if App(x, y) is such that y comes before x in the source code, then the node is marked isInfix=true) - /// - /// F# syntax: f x - | App of ExprAtomicFlag * isInfix: bool * funcExpr: SynExpr * argExpr: SynExpr * range: range - - /// TypeApp(expr, mLessThan, types, mCommas, mGreaterThan, mTypeArgs, mWholeExpr) - /// "mCommas" are the ranges for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them - /// - /// F# syntax: expr - | TypeApp of expr: SynExpr * LESSrange: range * typeNames: SynType list * commaRanges: range list * GREATERrange: range option * typeArgsRange: range * range: range - - /// LetOrUse(isRecursive, isUse, bindings, body, wholeRange) - /// - /// F# syntax: let pat = expr in expr - /// F# syntax: let f pat1 .. patN = expr in expr - /// F# syntax: let rec f pat1 .. patN = expr in expr - /// F# syntax: use pat = expr in expr - | LetOrUse of isRecursive: bool * isUse: bool * bindings: SynBinding list * body: SynExpr * range: range - - /// F# syntax: try expr with pat -> expr - | TryWith of tryExpr: SynExpr * tryRange: range * withCases: SynMatchClause list * withRange: range * range: range * trySeqPoint: SequencePointInfoForTry * withSeqPoint: SequencePointInfoForWith - - /// F# syntax: try expr finally expr - | TryFinally of tryExpr: SynExpr * finallyExpr: SynExpr * range: range * trySeqPoint: SequencePointInfoForTry * finallySeqPoint: SequencePointInfoForFinally - - /// F# syntax: lazy expr - | Lazy of SynExpr * range: range - - /// Sequential(seqPoint, isTrueSeq, e1, e2, m) - /// isTrueSeq: false indicates "let v = a in b; v" - /// - /// F# syntax: expr; expr - | Sequential of seqPoint: SequencePointInfoForSeq * isTrueSeq: bool * expr1: SynExpr * expr2: SynExpr * range: range - - /// IfThenElse(exprGuard, exprThen, optionalExprElse, spIfToThen, isFromErrorRecovery, mIfToThen, mIfToEndOfLastBranch) - /// - /// F# syntax: if expr then expr - /// F# syntax: if expr then expr else expr - | IfThenElse of ifExpr: SynExpr * thenExpr: SynExpr * elseExpr: SynExpr option * spIfToThen: SequencePointInfoForBinding * isFromErrorRecovery: bool * ifToThenRange: range * range: range - - /// F# syntax: ident - /// Optimized representation, = SynExpr.LongIdent (false, [id], id.idRange) - | Ident of Ident - - /// F# syntax: ident.ident...ident - /// LongIdent(isOptional, longIdent, altNameRefCell, m) - /// isOptional: true if preceded by a '?' for an optional named parameter - /// altNameRefCell: Normally 'None' except for some compiler-generated variables in desugaring pattern matching. See SynSimplePat.Id - | LongIdent of isOptional: bool * longDotId: LongIdentWithDots * altNameRefCell: SynSimplePatAlternativeIdInfo ref option * range: range - - /// F# syntax: ident.ident...ident <- expr - | LongIdentSet of longDotId: LongIdentWithDots * expr: SynExpr * range: range - - /// DotGet(expr, rangeOfDot, lid, wholeRange) - /// - /// F# syntax: expr.ident.ident - | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: LongIdentWithDots * range: range - - /// F# syntax: expr.ident...ident <- expr - | DotSet of SynExpr * longDotId: LongIdentWithDots * SynExpr * range: range - - /// F# syntax: expr <- expr - | Set of SynExpr * SynExpr * range: range - - /// F# syntax: expr.[expr, ..., expr] - | DotIndexedGet of SynExpr * SynIndexerArg list * range * range: range - - /// DotIndexedSet (objectExpr, indexExprs, valueExpr, rangeOfLeftOfSet, rangeOfDot, rangeOfWholeExpr) - /// - /// F# syntax: expr.[expr, ..., expr] <- expr - | DotIndexedSet of objectExpr: SynExpr * indexExprs: SynIndexerArg list * valueExpr: SynExpr * leftOfSetRange: range * dotRange: range * range: range - - /// F# syntax: Type.Items(e1) <- e2, rarely used named-property-setter notation, e.g. Foo.Bar.Chars(3) <- 'a' - | NamedIndexedPropertySet of longDotId: LongIdentWithDots * SynExpr * SynExpr * range: range - - /// F# syntax: Expr.Items (e1) <- e2, rarely used named-property-setter notation, e.g. (stringExpr).Chars(3) <- 'a' - | DotNamedIndexedPropertySet of SynExpr * longDotId: LongIdentWithDots * SynExpr * SynExpr * range: range - - /// F# syntax: expr :? type - | TypeTest of expr: SynExpr * typeName: SynType * range: range - - /// F# syntax: expr :> type - | Upcast of expr: SynExpr * typeName: SynType * range: range - - /// F# syntax: expr :?> type - | Downcast of expr: SynExpr * typeName: SynType * range: range - - /// F# syntax: upcast expr - | InferredUpcast of expr: SynExpr * range: range - - /// F# syntax: downcast expr - | InferredDowncast of expr: SynExpr * range: range - - /// F# syntax: null - | Null of range: range - - /// F# syntax: &expr, &&expr - | AddressOf of isByref: bool * SynExpr * range * range: range - - /// F# syntax: ((typar1 or ... or typarN): (member-dig) expr) - | TraitCall of SynTypar list * SynMemberSig * SynExpr * range: range - - /// F# syntax: ... in ... - /// Computation expressions only, based on JOIN_IN token from lex filter - | JoinIn of SynExpr * range * SynExpr * range: range - - /// Used in parser error recovery and internally during type checking for translating computation expressions. - | ImplicitZero of range: range - - /// Used internally during type checking for translating computation expressions. - | SequentialOrImplicitYield of seqPoint:SequencePointInfoForSeq * expr1:SynExpr * expr2:SynExpr * ifNotStmt:SynExpr * range:range - - /// F# syntax: yield expr - /// F# syntax: return expr - /// Computation expressions only - | YieldOrReturn of (bool * bool) * expr: SynExpr * range: range - - /// F# syntax: yield! expr - /// F# syntax: return! expr - /// Computation expressions only - | YieldOrReturnFrom of (bool * bool) * expr: SynExpr * range: range - - /// SynExpr.LetOrUseBang (spBind, isUse, isFromSource, pat, rhsExpr, bodyExpr, mWholeExpr). - /// - /// F# syntax: let! pat = expr in expr - /// F# syntax: use! pat = expr in expr - /// Computation expressions only - | LetOrUseBang of bindSeqPoint: SequencePointInfoForBinding * isUse: bool * isFromSource: bool * SynPat * SynExpr * SynExpr * range: range - - /// F# syntax: match! expr with pat1 -> expr | ... | patN -> exprN - | MatchBang of matchSeqPoint: SequencePointInfoForBinding * expr: SynExpr * clauses: SynMatchClause list * range: range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) - - /// F# syntax: do! expr - /// Computation expressions only - | DoBang of expr: SynExpr * range: range - - /// Only used in FSharp.Core - | LibraryOnlyILAssembly of ILInstr array * SynType list * SynExpr list * SynType list * range: range (* Embedded IL assembly code *) - - /// Only used in FSharp.Core - | LibraryOnlyStaticOptimization of SynStaticOptimizationConstraint list * SynExpr * SynExpr * range: range - - /// Only used in FSharp.Core - | LibraryOnlyUnionCaseFieldGet of expr: SynExpr * longId: LongIdent * int * range: range - - /// Only used in FSharp.Core - | LibraryOnlyUnionCaseFieldSet of SynExpr * longId: LongIdent * int * SynExpr * range: range - - /// Inserted for error recovery - | ArbitraryAfterError of debugStr: string * range: range - - /// Inserted for error recovery - | FromParseError of expr: SynExpr * range: range - - /// Inserted for error recovery when there is "expr." and missing tokens or error recovery after the dot - | DiscardAfterMissingQualificationAfterDot of SynExpr * range: range - - /// 'use x = fixed expr' - | Fixed of expr: SynExpr * range: range - - /// Get the syntactic range of source code covered by this construct. - member e.Range = - match e with - | SynExpr.Paren (_, leftParenRange, rightParenRange, r) -> - match rightParenRange with - | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex -> leftParenRange - | _ -> r - | SynExpr.Quote (range=m) - | SynExpr.Const (range=m) - | SynExpr.Typed (range=m) - | SynExpr.Tuple (range=m) - | SynExpr.AnonRecd (range=m) - | SynExpr.ArrayOrList (range=m) - | SynExpr.Record (range=m) - | SynExpr.New (range=m) - | SynExpr.ObjExpr (range=m) - | SynExpr.While (range=m) - | SynExpr.For (range=m) - | SynExpr.ForEach (range=m) - | SynExpr.CompExpr (range=m) - | SynExpr.ArrayOrListOfSeqExpr (range=m) - | SynExpr.Lambda (range=m) - | SynExpr.Match (range=m) - | SynExpr.MatchLambda (range=m) - | SynExpr.Do (range=m) - | SynExpr.Assert (range=m) - | SynExpr.App (range=m) - | SynExpr.TypeApp (range=m) - | SynExpr.LetOrUse (range=m) - | SynExpr.TryWith (range=m) - | SynExpr.TryFinally (range=m) - | SynExpr.Sequential (range=m) - | SynExpr.SequentialOrImplicitYield (range=m) - | SynExpr.ArbitraryAfterError (range=m) - | SynExpr.FromParseError (range=m) - | SynExpr.DiscardAfterMissingQualificationAfterDot (range=m) - | SynExpr.IfThenElse (range=m) - | SynExpr.LongIdent (range=m) - | SynExpr.LongIdentSet (range=m) - | SynExpr.NamedIndexedPropertySet (range=m) - | SynExpr.DotIndexedGet (range=m) - | SynExpr.DotIndexedSet (range=m) - | SynExpr.DotGet (range=m) - | SynExpr.DotSet (range=m) - | SynExpr.Set (range=m) - | SynExpr.DotNamedIndexedPropertySet (range=m) - | SynExpr.LibraryOnlyUnionCaseFieldGet (range=m) - | SynExpr.LibraryOnlyUnionCaseFieldSet (range=m) - | SynExpr.LibraryOnlyILAssembly (range=m) - | SynExpr.LibraryOnlyStaticOptimization (range=m) - | SynExpr.TypeTest (range=m) - | SynExpr.Upcast (range=m) - | SynExpr.AddressOf (range=m) - | SynExpr.Downcast (range=m) - | SynExpr.JoinIn (range=m) - | SynExpr.InferredUpcast (range=m) - | SynExpr.InferredDowncast (range=m) - | SynExpr.Null (range=m) - | SynExpr.Lazy (range=m) - | SynExpr.TraitCall (range=m) - | SynExpr.ImplicitZero (range=m) - | SynExpr.YieldOrReturn (range=m) - | SynExpr.YieldOrReturnFrom (range=m) - | SynExpr.LetOrUseBang (range=m) - | SynExpr.MatchBang (range=m) - | SynExpr.DoBang (range=m) - | SynExpr.Fixed (range=m) -> m - | SynExpr.Ident id -> id.idRange - - /// range ignoring any (parse error) extra trailing dots - member e.RangeSansAnyExtraDot = - match e with - | SynExpr.DotGet (expr, _, lidwd, m) -> if lidwd.ThereIsAnExtraDotAtTheEnd then unionRanges expr.Range lidwd.RangeSansAnyExtraDot else m - | SynExpr.LongIdent (_, lidwd, _, _) -> lidwd.RangeSansAnyExtraDot - | SynExpr.DiscardAfterMissingQualificationAfterDot (expr, _) -> expr.Range - | _ -> e.Range - - /// Attempt to get the range of the first token or initial portion only - this is extremely ad-hoc, just a cheap way to improve a certain 'query custom operation' error range - member e.RangeOfFirstPortion = - match e with - // these are better than just .Range, and also commonly applicable inside queries - | SynExpr.Paren (_, m, _, _) -> m - | SynExpr.Sequential (_, _, e1, _, _) - | SynExpr.SequentialOrImplicitYield (_, e1, _, _, _) - | SynExpr.App (_, _, e1, _, _) -> - e1.RangeOfFirstPortion - | SynExpr.ForEach (_, _, _, pat, _, _, r) -> - let start = r.Start - let e = (pat.Range: range).Start - mkRange r.FileName start e - | _ -> e.Range - -and - [] - SynIndexerArg = - - | Two of SynExpr * fromEnd1: bool * SynExpr * fromEnd2: bool * range1: range * range2: range - - | One of SynExpr * fromEnd: bool * range - - member x.Range = match x with Two (e1, _, e2, _, _, _) -> unionRanges e1.Range e2.Range | One (e, _, _) -> e.Range - - member x.Exprs = match x with Two (e1, _, e2, _, _, _) -> [e1;e2] | One (e, _, _) -> [e] - -and - [] - SynSimplePat = - - /// Id (ident, altNameRefCell, isCompilerGenerated, isThisVar, isOptArg, range) - /// - /// Indicates a simple pattern variable. - /// - /// altNameRefCell - /// Normally 'None' except for some compiler-generated variables in desugaring pattern matching. - /// Pattern processing sets this reference for hidden variable introduced by desugaring pattern matching in arguments. - /// The info indicates an alternative (compiler generated) identifier to be used because the name of the identifier is already bound. - /// See Product Studio FSharp 1.0, bug 6389. - /// - /// isCompilerGenerated: true if a compiler generated name - /// isThisVar: true if 'this' variable in member - /// isOptArg: true if a '?' is in front of the name - | Id of ident: Ident * altNameRefCell: SynSimplePatAlternativeIdInfo ref option * isCompilerGenerated: bool * isThisVar: bool * isOptArg: bool * range: range - - | Typed of SynSimplePat * SynType * range: range - - | Attrib of SynSimplePat * SynAttributes * range: range - -and SynSimplePatAlternativeIdInfo = - - /// We have not decided to use an alternative name in tha pattern and related expression - | Undecided of Ident - - /// We have decided to use an alternative name in tha pattern and related expression - | Decided of Ident - -and - [] - SynStaticOptimizationConstraint = - - | WhenTyparTyconEqualsTycon of SynTypar * SynType * range: range - - | WhenTyparIsStruct of SynTypar * range: range - -and - [] - /// Represents a simple set of variable bindings a, (a, b) or (a: Type, b: Type) at a lambda, - /// function definition or other binding point, after the elimination of pattern matching - /// from the construct, e.g. after changing a "function pat1 -> rule1 | ..." to a - /// "fun v -> match v with ..." - SynSimplePats = - - | SimplePats of SynSimplePat list * range: range - - | Typed of SynSimplePats * SynType * range: range - -and SynConstructorArgs = - | Pats of SynPat list - | NamePatPairs of (Ident * SynPat) list * range: range -and - [] - SynPat = - - | Const of SynConst * range: range - - | Wild of range: range - - | Named of SynPat * Ident * isSelfIdentifier: bool (* true if 'this' variable *) * accessibility: SynAccess option * range: range - - | Typed of SynPat * SynType * range: range - - | Attrib of SynPat * SynAttributes * range: range - - | Or of SynPat * SynPat * range: range - - | Ands of SynPat list * range: range - - | LongIdent of - longDotId: LongIdentWithDots * - Ident option * // holds additional ident for tooling - SynValTyparDecls option * // usually None: temporary used to parse "f<'a> x = x"*) - SynConstructorArgs * - accessibility: SynAccess option * - range: range - - | Tuple of isStruct: bool * SynPat list * range: range - - | Paren of SynPat * range: range - - | ArrayOrList of bool * SynPat list * range: range - - | Record of ((LongIdent * Ident) * SynPat) list * range: range - - /// 'null' - | Null of range: range - - /// '?id' -- for optional argument names - | OptionalVal of Ident * range: range - - /// ':? type ' - | IsInst of SynType * range: range - - /// <@ expr @>, used for active pattern arguments - | QuoteExpr of SynExpr * range: range - - /// Deprecated character range: ranges - | DeprecatedCharRange of char * char * range: range - - /// Used internally in the type checker - | InstanceMember of Ident * Ident * (* holds additional ident for tooling *) Ident option * accessibility: SynAccess option * range: range (* adhoc overloaded method/property *) - - /// A pattern arising from a parse error - | FromParseError of SynPat * range: range - - member p.Range = - match p with - | SynPat.Const (range=m) - | SynPat.Wild (range=m) - | SynPat.Named (range=m) - | SynPat.Or (range=m) - | SynPat.Ands (range=m) - | SynPat.LongIdent (range=m) - | SynPat.ArrayOrList (range=m) - | SynPat.Tuple (range=m) - | SynPat.Typed (range=m) - | SynPat.Attrib (range=m) - | SynPat.Record (range=m) - | SynPat.DeprecatedCharRange (range=m) - | SynPat.Null (range=m) - | SynPat.IsInst (range=m) - | SynPat.QuoteExpr (range=m) - | SynPat.InstanceMember (range=m) - | SynPat.OptionalVal (range=m) - | SynPat.Paren (range=m) - | SynPat.FromParseError (range=m) -> m - -and - [] - SynInterfaceImpl = - | InterfaceImpl of SynType * SynBinding list * range: range - -and - [] - SynMatchClause = - | Clause of SynPat * whenExpr: SynExpr option * SynExpr * range: range * SequencePointInfoForTarget - - member this.RangeOfGuardAndRhs = - match this with - | Clause(_, eo, e, _, _) -> - match eo with - | None -> e.Range - | Some x -> unionRanges e.Range x.Range - - member this.Range = - match this with - | Clause(_, eo, e, m, _) -> - match eo with - | None -> unionRanges e.Range m - | Some x -> unionRanges (unionRanges e.Range m) x.Range - -and - /// List of attributes enclosed in [< ... >]. - SynAttributeList = - { Attributes: SynAttribute list - Range: range } - -and SynAttributes = SynAttributeList list - -and - [] - SynAttribute = - { TypeName: LongIdentWithDots - - ArgExpr: SynExpr - - /// Target specifier, e.g. "assembly", "module", etc. - Target: Ident option - - /// Is this attribute being applied to a property getter or setter? - AppliesToGetterAndSetter: bool - - Range: range } - -and - [] - SynValData = - | SynValData of MemberFlags option * SynValInfo * Ident option - -and - [] - SynBinding = - | Binding of - accessibility: SynAccess option * - kind: SynBindingKind * - mustInline: bool * - isMutable: bool * - attrs: SynAttributes * - xmlDoc: PreXmlDoc * - valData: SynValData * - headPat: SynPat * - returnInfo: SynBindingReturnInfo option * - expr: SynExpr * - range: range * - seqPoint: SequencePointInfoForBinding - - // no member just named "Range", as that would be confusing: - // - for everything else, the 'range' member that appears last/second-to-last is the 'full range' of the whole tree construct - // - but for Binding, the 'range' is only the range of the left-hand-side, the right-hand-side range is in the SynExpr - // - so we use explicit names to avoid confusion - member x.RangeOfBindingSansRhs = let (Binding(range=m)) = x in m - - member x.RangeOfBindingAndRhs = let (Binding(expr=e; range=m)) = x in unionRanges e.Range m - - member x.RangeOfHeadPat = let (Binding(headPat=headPat)) = x in headPat.Range - -and - [] - SynBindingReturnInfo = - | SynBindingReturnInfo of typeName: SynType * range: range * attributes: SynAttributes - - -and - [] - MemberFlags = - { IsInstance: bool - IsDispatchSlot: bool - IsOverrideOrExplicitImpl: bool - IsFinal: bool - MemberKind: MemberKind } - -/// Note the member kind is actually computed partially by a syntax tree transformation in tc.fs -and - [] - MemberKind = - - | ClassConstructor - - | Constructor - - | Member - - | PropertyGet - - | PropertySet - - /// An artificial member kind used prior to the point where a get/set property is split into two distinct members. - | PropertyGetSet - -and - [] - /// The untyped, unchecked syntax tree for a member signature, used in signature files, abstract member declarations - /// and member constraints. - SynMemberSig = - - | Member of SynValSig * MemberFlags * range: range - - | Interface of typeName: SynType * range: range - - | Inherit of typeName: SynType * range: range - - | ValField of SynField * range: range - - | NestedType of SynTypeDefnSig * range: range - -and SynMemberSigs = SynMemberSig list - -and - [] - SynTypeDefnKind = - | TyconUnspecified - | TyconClass - | TyconInterface - | TyconStruct - | TyconRecord - | TyconUnion - | TyconAbbrev - | TyconHiddenRepr - | TyconAugmentation - | TyconILAssemblyCode - | TyconDelegate of SynType * SynValInfo - -and - [] - /// The untyped, unchecked syntax tree for the core of a simple type definition, in either signature - /// or implementation. - SynTypeDefnSimpleRepr = - - /// A union type definition, type X = A | B - | Union of accessibility: SynAccess option * unionCases: SynUnionCases * range: range - - /// An enum type definition, type X = A = 1 | B = 2 - | Enum of SynEnumCases * range: range - - /// A record type definition, type X = { A: int; B: int } - | Record of accessibility: SynAccess option * recordFields: SynFields * range: range - - /// An object oriented type definition. This is not a parse-tree form, but represents the core - /// type representation which the type checker splits out from the "ObjectModel" cases of type definitions. - | General of SynTypeDefnKind * (SynType * range * Ident option) list * (SynValSig * MemberFlags) list * SynField list * bool * bool * SynSimplePats option * range: range - - /// A type defined by using an IL assembly representation. Only used in FSharp.Core. - /// - /// F# syntax: "type X = (# "..."#) - | LibraryOnlyILAssembly of ILType * range: range - - /// A type abbreviation, "type X = A.B.C" - | TypeAbbrev of ParserDetail * SynType * range: range - - /// An abstract definition, "type X" - | None of range: range - - /// An exception definition, "exception E = ..." - | Exception of SynExceptionDefnRepr - - member this.Range = - match this with - | Union (range=m) - | Enum (range=m) - | Record (range=m) - | General (range=m) - | LibraryOnlyILAssembly (range=m) - | TypeAbbrev (range=m) - | None (range=m) -> m - | Exception t -> t.Range - -and SynEnumCases = SynEnumCase list - -and - [] - SynEnumCase = - - /// The untyped, unchecked syntax tree for one case in an enum definition. - | EnumCase of attrs: SynAttributes * ident: Ident * SynConst * PreXmlDoc * range: range - - member this.Range = - match this with - | EnumCase (range=m) -> m - -and SynUnionCases = SynUnionCase list - -and - [] - SynUnionCase = - - /// The untyped, unchecked syntax tree for one case in a union definition. - | UnionCase of SynAttributes * ident: Ident * SynUnionCaseType * PreXmlDoc * accessibility: SynAccess option * range: range - - member this.Range = - match this with - | UnionCase (range=m) -> m - -and - [] - /// The untyped, unchecked syntax tree for the right-hand-side of union definition, excluding members, - /// in either a signature or implementation. - SynUnionCaseType = - - /// Normal style declaration - | UnionCaseFields of cases: SynField list - - /// Full type spec given by 'UnionCase: ty1 * tyN -> rty'. Only used in FSharp.Core, otherwise a warning. - | UnionCaseFullType of (SynType * SynValInfo) - -and - [] - /// The untyped, unchecked syntax tree for the right-hand-side of a type definition in a signature. - /// Note: in practice, using a discriminated union to make a distinction between - /// "simple" types and "object oriented" types is not particularly useful. - SynTypeDefnSigRepr = - - /// Indicates the right right-hand-side is a class, struct, interface or other object-model type - | ObjectModel of SynTypeDefnKind * memberSigs: SynMemberSigs * range: range - - /// Indicates the right right-hand-side is a record, union or other simple type. - | Simple of SynTypeDefnSimpleRepr * range: range - - | Exception of SynExceptionDefnRepr - - member this.Range = - match this with - | ObjectModel (range=m) - | Simple (range=m) -> m - | Exception e -> e.Range - -and - [] - /// The untyped, unchecked syntax tree for a type definition in a signature - SynTypeDefnSig = - - /// The information for a type definition in a signature - | TypeDefnSig of SynComponentInfo * SynTypeDefnSigRepr * SynMemberSigs * range: range - -and SynFields = SynField list - -and - [] - /// The untyped, unchecked syntax tree for a field declaration in a record or class - SynField = - | Field of attrs: SynAttributes * isStatic: bool * Ident option * SynType * isMutable: bool * xmlDoc: PreXmlDoc * accessibility: SynAccess option * range: range - -and - [] - /// The untyped, unchecked syntax tree associated with the name of a type definition or module - /// in signature or implementation. - /// - /// This includes the name, attributes, type parameters, constraints, documentation and accessibility - /// for a type definition or module. For modules, entries such as the type parameters are - /// always empty. - SynComponentInfo = - | ComponentInfo of attribs: SynAttributes * typeParams: SynTyparDecl list * constraints: SynTypeConstraint list * longId: LongIdent * xmlDoc: PreXmlDoc * preferPostfix: bool * accessibility: SynAccess option * range: range - - member this.Range = - match this with - | ComponentInfo (range=m) -> m - -and - [] - SynValSig = - | ValSpfn of - synAttributes: SynAttributes * - ident: Ident * - explicitValDecls: SynValTyparDecls * - synType: SynType * - arity: SynValInfo * - isInline: bool * - isMutable: bool * - xmlDoc: PreXmlDoc * - accessibility: SynAccess option * - synExpr: SynExpr option * - range: range - - member x.RangeOfId = let (ValSpfn(ident=id)) = x in id.idRange - - member x.SynInfo = let (ValSpfn(arity=v)) = x in v - - member x.SynType = let (ValSpfn(synType=ty)) = x in ty - -/// The argument names and other metadata for a member or function -and - [] - SynValInfo = - - /// SynValInfo(curriedArgInfos, returnInfo) - | SynValInfo of SynArgInfo list list * SynArgInfo - - member x.ArgInfos = (let (SynValInfo(args, _)) = x in args) - -/// The argument names and other metadata for a parameter for a member or function -and - [] - SynArgInfo = - - | SynArgInfo of SynAttributes * optional: bool * Ident option - -/// The names and other metadata for the type parameters for a member or function -and - [] - SynValTyparDecls = - - | SynValTyparDecls of SynTyparDecl list * bool * constraints: SynTypeConstraint list - -/// 'exception E = ... ' -and [] - SynExceptionDefnRepr = - - | SynExceptionDefnRepr of SynAttributes * SynUnionCase * longId: LongIdent option * xmlDoc: PreXmlDoc * accessibility: SynAccess option * range: range - - member this.Range = match this with SynExceptionDefnRepr (range=m) -> m - -/// 'exception E = ... with ...' -and - [] - SynExceptionDefn = - - | SynExceptionDefn of SynExceptionDefnRepr * SynMemberDefns * range: range - - member this.Range = - match this with - | SynExceptionDefn (range=m) -> m - -and - [] - SynTypeDefnRepr = - - | ObjectModel of SynTypeDefnKind * SynMemberDefns * range: range - - | Simple of SynTypeDefnSimpleRepr * range: range - - | Exception of SynExceptionDefnRepr - - member this.Range = - match this with - | ObjectModel (range=m) - | Simple (range=m) -> m - | Exception t -> t.Range - -and - [] - SynTypeDefn = - | TypeDefn of SynComponentInfo * SynTypeDefnRepr * members: SynMemberDefns * range: range - member this.Range = - match this with - | TypeDefn (range=m) -> m - -and - [] - SynMemberDefn = - - | Open of longId: LongIdent * range: range - - | Member of memberDefn: SynBinding * range: range - - /// implicit ctor args as a defn line, 'as' specification - | ImplicitCtor of accessibility: SynAccess option * attributes: SynAttributes * ctorArgs: SynSimplePats * selfIdentifier: Ident option * range: range - - /// inherit (args...) as base - | ImplicitInherit of inheritType: SynType * inheritArgs: SynExpr * inheritAlias: Ident option * range: range - - /// LetBindings(bindingList, isStatic, isRecursive, wholeRange) - /// - /// localDefns - | LetBindings of SynBinding list * isStatic: bool * isRecursive: bool * range: range - - | AbstractSlot of SynValSig * MemberFlags * range: range - - | Interface of SynType * SynMemberDefns option * range: range - - | Inherit of SynType * Ident option * range: range - - | ValField of SynField * range: range - - /// A feature that is not implemented - | NestedType of typeDefn: SynTypeDefn * accessibility: SynAccess option * range: range - - /// SynMemberDefn.AutoProperty (attribs, isStatic, id, tyOpt, propKind, memberFlags, xmlDoc, access, synExpr, mGetSet, mWholeAutoProp). - /// - /// F# syntax: 'member val X = expr' - | AutoProperty of - attribs: SynAttributes * - isStatic: bool * - ident: Ident * - typeOpt: SynType option * - propKind: MemberKind * - memberFlags:(MemberKind -> MemberFlags) * - xmlDoc: PreXmlDoc * - accessibility: SynAccess option * - synExpr: SynExpr * - getSetRange: range option * - range: range - - member d.Range = - match d with - | SynMemberDefn.Member (range=m) - | SynMemberDefn.Interface (range=m) - | SynMemberDefn.Open (range=m) - | SynMemberDefn.LetBindings (range=m) - | SynMemberDefn.ImplicitCtor (range=m) - | SynMemberDefn.ImplicitInherit (range=m) - | SynMemberDefn.AbstractSlot (range=m) - | SynMemberDefn.Inherit (range=m) - | SynMemberDefn.ValField (range=m) - | SynMemberDefn.AutoProperty (range=m) - | SynMemberDefn.NestedType (range=m) -> m - -and SynMemberDefns = SynMemberDefn list - -and - [] - SynModuleDecl = - | ModuleAbbrev of ident: Ident * longId: LongIdent * range: range - | NestedModule of SynComponentInfo * isRecursive: bool * SynModuleDecls * bool * range: range - | Let of isRecursive: bool * SynBinding list * range: range - | DoExpr of SequencePointInfoForBinding * SynExpr * range: range - | Types of SynTypeDefn list * range: range - | Exception of SynExceptionDefn * range: range - | Open of longDotId: LongIdentWithDots * range: range - | Attributes of SynAttributes * range: range - | HashDirective of ParsedHashDirective * range: range - | NamespaceFragment of SynModuleOrNamespace - member d.Range = - match d with - | SynModuleDecl.ModuleAbbrev (range=m) - | SynModuleDecl.NestedModule (range=m) - | SynModuleDecl.Let (range=m) - | SynModuleDecl.DoExpr (range=m) - | SynModuleDecl.Types (range=m) - | SynModuleDecl.Exception (range=m) - | SynModuleDecl.Open (range=m) - | SynModuleDecl.HashDirective (range=m) - | SynModuleDecl.NamespaceFragment (SynModuleOrNamespace (range=m)) - | SynModuleDecl.Attributes (range=m) -> m - -and SynModuleDecls = SynModuleDecl list - -and - [] - SynExceptionSig = - | SynExceptionSig of SynExceptionDefnRepr * SynMemberSigs * range: range - -and - [] - SynModuleSigDecl = - | ModuleAbbrev of ident: Ident * longId: LongIdent * range: range - | NestedModule of SynComponentInfo * isRecursive: bool * SynModuleSigDecls * range: range - | Val of SynValSig * range: range - | Types of SynTypeDefnSig list * range: range - | Exception of SynExceptionSig * range: range - | Open of longId: LongIdent * range: range - | HashDirective of ParsedHashDirective * range: range - | NamespaceFragment of SynModuleOrNamespaceSig - - member d.Range = - match d with - | SynModuleSigDecl.ModuleAbbrev (range=m) - | SynModuleSigDecl.NestedModule (range=m) - | SynModuleSigDecl.Val (range=m) - | SynModuleSigDecl.Types (range=m) - | SynModuleSigDecl.Exception (range=m) - | SynModuleSigDecl.Open (range=m) - | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig(range=m)) - | SynModuleSigDecl.HashDirective (range=m) -> m - -and SynModuleSigDecls = SynModuleSigDecl list - -and - [] - SynModuleOrNamespaceKind = - | NamedModule - | AnonModule - | DeclaredNamespace - | GlobalNamespace - - member x.IsModule = - match x with - | NamedModule | AnonModule -> true - | _ -> false - -and - [] - SynModuleOrNamespace = - | SynModuleOrNamespace of longId: LongIdent * isRecursive: bool * kind: SynModuleOrNamespaceKind * decls: SynModuleDecls * xmlDoc: PreXmlDoc * attribs: SynAttributes * accessibility: SynAccess option * range: range - member this.Range = - match this with - | SynModuleOrNamespace (range=m) -> m - -and - [] - SynModuleOrNamespaceSig = - | SynModuleOrNamespaceSig of longId: LongIdent * isRecursive: bool * kind: SynModuleOrNamespaceKind * SynModuleSigDecls * xmlDoc: PreXmlDoc * attribs: SynAttributes * accessibility: SynAccess option * range: range - -and [] - ParsedHashDirective = - | ParsedHashDirective of string * string list * range: range - -[] -type ParsedImplFileFragment = - | AnonModule of SynModuleDecls * range: range - | NamedModule of SynModuleOrNamespace - | NamespaceFragment of longId: LongIdent * bool * SynModuleOrNamespaceKind * SynModuleDecls * xmlDoc: PreXmlDoc * SynAttributes * range: range - -[] -type ParsedSigFileFragment = - | AnonModule of SynModuleSigDecls * range: range - | NamedModule of SynModuleOrNamespaceSig - | NamespaceFragment of longId: LongIdent * bool * SynModuleOrNamespaceKind * SynModuleSigDecls * xmlDoc: PreXmlDoc * SynAttributes * range: range - -[] -type ParsedFsiInteraction = - | IDefns of SynModuleDecl list * range: range - | IHash of ParsedHashDirective * range: range - -[] -type ParsedImplFile = - | ParsedImplFile of hashDirectives: ParsedHashDirective list * ParsedImplFileFragment list - -[] -type ParsedSigFile = - | ParsedSigFile of hashDirectives: ParsedHashDirective list * ParsedSigFileFragment list - -//---------------------------------------------------------------------- -// AST and parsing utilities. -//---------------------------------------------------------------------- - -let ident (s, r) = new Ident(s, r) -let textOfId (id: Ident) = id.idText -let pathOfLid lid = List.map textOfId lid -let arrPathOfLid lid = Array.ofList (pathOfLid lid) -let textOfPath path = String.concat "." path -let textOfLid lid = textOfPath (pathOfLid lid) - -let rangeOfLid (lid: Ident list) = - match lid with - | [] -> failwith "rangeOfLid" - | [id] -> id.idRange - | h :: t -> unionRanges h.idRange (List.last t).idRange - -[] -type ScopedPragma = - | WarningOff of range: range * int - // Note: this type may be extended in the future with optimization on/off switches etc. - -// These are the results of parsing + folding in the implicit file name -/// ImplFile (modname, isScript, qualName, hashDirectives, modules, isLastCompiland) - -/// QualifiedNameOfFile acts to fully-qualify module specifications and implementations, -/// most importantly the ones that simply contribute fragments to a namespace (i.e. the ParsedSigFileFragment.NamespaceFragment case) -/// There may be multiple such fragments in a single assembly. There may thus also -/// be multiple matching pairs of these in an assembly, all contributing types to the same -/// namespace. -[] -type QualifiedNameOfFile = - | QualifiedNameOfFile of Ident - member x.Text = (let (QualifiedNameOfFile t) = x in t.idText) - member x.Id = (let (QualifiedNameOfFile t) = x in t) - member x.Range = (let (QualifiedNameOfFile t) = x in t.idRange) - -[] -type ParsedImplFileInput = - | ParsedImplFileInput of - fileName: string * - isScript: bool * - qualifiedNameOfFile: QualifiedNameOfFile * - scopedPragmas: ScopedPragma list * - hashDirectives: ParsedHashDirective list * - modules: SynModuleOrNamespace list * - isLastCompiland: (bool * bool) - -[] -type ParsedSigFileInput = - | ParsedSigFileInput of - fileName: string * - qualifiedNameOfFile: QualifiedNameOfFile * - scopedPragmas: ScopedPragma list * - hashDirectives: ParsedHashDirective list * - modules: SynModuleOrNamespaceSig list - -[] -type ParsedInput = - | ImplFile of ParsedImplFileInput - | SigFile of ParsedSigFileInput - - member inp.Range = - match inp with - | ParsedInput.ImplFile (ParsedImplFileInput (modules=SynModuleOrNamespace(range=m) :: _)) - | ParsedInput.SigFile (ParsedSigFileInput (modules=SynModuleOrNamespaceSig(range=m) :: _)) -> m - | ParsedInput.ImplFile (ParsedImplFileInput (fileName=filename)) - | ParsedInput.SigFile (ParsedSigFileInput (fileName=filename)) -> -#if DEBUG - assert("" = "compiler expects ParsedInput.ImplFile and ParsedInput.SigFile to have at least one fragment, 4488") -#endif - rangeN filename 0 (* There are no implementations, e.g. due to errors, so return a default range for the file *) - - -//---------------------------------------------------------------------- -// Construct syntactic AST nodes -//----------------------------------------------------------------------- - -// REVIEW: get rid of this global state -type SynArgNameGenerator() = - let mutable count = 0 - let generatedArgNamePrefix = "_arg" - - member __.New() : string = count <- count + 1; generatedArgNamePrefix + string count - member __.Reset() = count <- 0 - -//---------------------------------------------------------------------- -// Construct syntactic AST nodes -//----------------------------------------------------------------------- - - -let mkSynId m s = Ident(s, m) -let pathToSynLid m p = List.map (mkSynId m) p -let mkSynIdGet m n = SynExpr.Ident (mkSynId m n) -let mkSynLidGet m path n = - let lid = pathToSynLid m path @ [mkSynId m n] - let dots = List.replicate (lid.Length - 1) m - SynExpr.LongIdent (false, LongIdentWithDots(lid, dots), None, m) -let mkSynIdGetWithAlt m id altInfo = - match altInfo with - | None -> SynExpr.Ident id - | _ -> SynExpr.LongIdent (false, LongIdentWithDots([id], []), altInfo, m) - -let mkSynSimplePatVar isOpt id = SynSimplePat.Id (id, None, false, false, isOpt, id.idRange) -let mkSynCompGenSimplePatVar id = SynSimplePat.Id (id, None, true, false, false, id.idRange) - -/// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree. -let (|LongOrSingleIdent|_|) inp = - match inp with - | SynExpr.LongIdent (isOpt, lidwd, altId, _m) -> Some (isOpt, lidwd, altId, lidwd.RangeSansAnyExtraDot) - | SynExpr.Ident id -> Some (false, LongIdentWithDots([id], []), None, id.idRange) - | _ -> None - -let (|SingleIdent|_|) inp = - match inp with - | SynExpr.LongIdent (false, LongIdentWithDots([id], _), None, _) -> Some id - | SynExpr.Ident id -> Some id - | _ -> None - -/// This affects placement of sequence points -let rec IsControlFlowExpression e = - match e with - | SynExpr.ObjExpr _ - | SynExpr.Lambda _ - | SynExpr.LetOrUse _ - | SynExpr.Sequential _ - // Treat "ident { ... }" as a control flow expression - | SynExpr.App (_, _, SynExpr.Ident _, SynExpr.CompExpr _, _) - | SynExpr.IfThenElse _ - | SynExpr.LetOrUseBang _ - | SynExpr.Match _ - | SynExpr.TryWith _ - | SynExpr.TryFinally _ - | SynExpr.For _ - | SynExpr.ForEach _ - | SynExpr.While _ -> true - | SynExpr.Typed (e, _, _) -> IsControlFlowExpression e - | _ -> false - -let mkAnonField (ty: SynType) = Field([], false, None, ty, false, PreXmlDoc.Empty, None, ty.Range) -let mkNamedField (ident, ty: SynType) = Field([], false, Some ident, ty, false, PreXmlDoc.Empty, None, ty.Range) - -let mkSynPatVar vis (id: Ident) = SynPat.Named (SynPat.Wild id.idRange, id, false, vis, id.idRange) -let mkSynThisPatVar (id: Ident) = SynPat.Named (SynPat.Wild id.idRange, id, true, None, id.idRange) -let mkSynPatMaybeVar lidwd vis m = SynPat.LongIdent (lidwd, None, None, SynConstructorArgs.Pats [], vis, m) - -/// Extract the argument for patterns corresponding to the declaration of 'new ... = ...' -let (|SynPatForConstructorDecl|_|) x = - match x with - | SynPat.LongIdent (LongIdentWithDots([_], _), _, _, SynConstructorArgs.Pats [arg], _, _) -> Some arg - | _ -> None - -/// Recognize the '()' in 'new()' -let (|SynPatForNullaryArgs|_|) x = - match x with - | SynPat.Paren(SynPat.Const(SynConst.Unit, _), _) -> Some() - | _ -> None - -let (|SynExprErrorSkip|) (p: SynExpr) = - match p with - | SynExpr.FromParseError (p, _) -> p - | _ -> p - -let (|SynExprParen|_|) (e: SynExpr) = - match e with - | SynExpr.Paren (SynExprErrorSkip e, a, b, c) -> Some (e, a, b, c) - | _ -> None - -let (|SynPatErrorSkip|) (p: SynPat) = - match p with - | SynPat.FromParseError(p, _) -> p - | _ -> p - -/// Push non-simple parts of a patten match over onto the r.h.s. of a lambda. -/// Return a simple pattern and a function to build a match on the r.h.s. if the pattern is complex -let rec SimplePatOfPat (synArgNameGenerator: SynArgNameGenerator) p = - match p with - | SynPat.Typed(p', ty, m) -> - let p2, laterF = SimplePatOfPat synArgNameGenerator p' - SynSimplePat.Typed(p2, ty, m), - laterF - | SynPat.Attrib(p', attribs, m) -> - let p2, laterF = SimplePatOfPat synArgNameGenerator p' - SynSimplePat.Attrib(p2, attribs, m), - laterF - | SynPat.Named (SynPat.Wild _, v, thisV, _, m) -> - SynSimplePat.Id (v, None, false, thisV, false, m), - None - | SynPat.OptionalVal (v, m) -> - SynSimplePat.Id (v, None, false, false, true, m), - None - | SynPat.Paren (p, _) -> SimplePatOfPat synArgNameGenerator p - | SynPat.FromParseError (p, _) -> SimplePatOfPat synArgNameGenerator p - | _ -> - let m = p.Range - let isCompGen, altNameRefCell, id, item = - match p with - | SynPat.LongIdent(LongIdentWithDots([id], _), _, None, SynConstructorArgs.Pats [], None, _) -> - // The pattern is 'V' or some other capitalized identifier. - // It may be a real variable, in which case we want to maintain its name. - // But it may also be a nullary union case or some other identifier. - // In this case, we want to use an alternate compiler generated name for the hidden variable. - let altNameRefCell = Some (ref (Undecided (mkSynId m (synArgNameGenerator.New())))) - let item = mkSynIdGetWithAlt m id altNameRefCell - false, altNameRefCell, id, item - | _ -> - let nm = synArgNameGenerator.New() - let id = mkSynId m nm - let item = mkSynIdGet m nm - true, None, id, item - SynSimplePat.Id (id, altNameRefCell, isCompGen, false, false, id.idRange), - Some (fun e -> - let clause = Clause(p, None, e, m, SuppressSequencePointAtTarget) - SynExpr.Match (NoSequencePointAtInvisibleBinding, item, [clause], clause.Range)) - -let appFunOpt funOpt x = match funOpt with None -> x | Some f -> f x -let composeFunOpt funOpt1 funOpt2 = match funOpt2 with None -> funOpt1 | Some f -> Some (fun x -> appFunOpt funOpt1 (f x)) -let rec SimplePatsOfPat synArgNameGenerator p = - match p with - | SynPat.FromParseError (p, _) -> SimplePatsOfPat synArgNameGenerator p - | SynPat.Typed(p', ty, m) -> - let p2, laterF = SimplePatsOfPat synArgNameGenerator p' - SynSimplePats.Typed(p2, ty, m), - laterF -// | SynPat.Paren (p, m) -> SimplePatsOfPat synArgNameGenerator p - | SynPat.Tuple (false, ps, m) - | SynPat.Paren(SynPat.Tuple (false, ps, m), _) -> - let ps2, laterF = - List.foldBack - (fun (p', rhsf) (ps', rhsf') -> - p':: ps', - (composeFunOpt rhsf rhsf')) - (List.map (SimplePatOfPat synArgNameGenerator) ps) - ([], None) - SynSimplePats.SimplePats (ps2, m), - laterF - | SynPat.Paren(SynPat.Const (SynConst.Unit, m), _) - | SynPat.Const (SynConst.Unit, m) -> - SynSimplePats.SimplePats ([], m), - None - | _ -> - let m = p.Range - let sp, laterF = SimplePatOfPat synArgNameGenerator p - SynSimplePats.SimplePats ([sp], m), laterF - -let PushPatternToExpr synArgNameGenerator isMember pat (rhs: SynExpr) = - let nowPats, laterF = SimplePatsOfPat synArgNameGenerator pat - nowPats, SynExpr.Lambda (isMember, false, nowPats, appFunOpt laterF rhs, rhs.Range) - -let private isSimplePattern pat = - let _nowPats, laterF = SimplePatsOfPat (SynArgNameGenerator()) pat - Option.isNone laterF - -/// "fun (UnionCase x) (UnionCase y) -> body" -/// ==> -/// "fun tmp1 tmp2 -> -/// let (UnionCase x) = tmp1 in -/// let (UnionCase y) = tmp2 in -/// body" -let PushCurriedPatternsToExpr synArgNameGenerator wholem isMember pats rhs = - // Two phases - // First phase: Fold back, from right to left, pushing patterns into r.h.s. expr - let spatsl, rhs = - (pats, ([], rhs)) - ||> List.foldBack (fun arg (spatsl, body) -> - let spats, bodyf = SimplePatsOfPat synArgNameGenerator arg - // accumulate the body. This builds "let (UnionCase y) = tmp2 in body" - let body = appFunOpt bodyf body - // accumulate the patterns - let spatsl = spats :: spatsl - (spatsl, body)) - // Second phase: build lambdas. Mark subsequent ones with "true" indicating they are part of an iterated sequence of lambdas - let expr = - match spatsl with - | [] -> rhs - | h :: t -> - let expr = List.foldBack (fun spats e -> SynExpr.Lambda (isMember, true, spats, e, wholem)) t rhs - let expr = SynExpr.Lambda (isMember, false, h, expr, wholem) - expr - spatsl, expr - -let internal internalParseAssemblyCodeInstructions s isFeatureSupported m = -#if NO_INLINE_IL_PARSER - ignore s - ignore isFeatureSupported - - errorR(Error((193, "Inline IL not valid in a hosted environment"), m)) - [| |] -#else - try - FSharp.Compiler.AbstractIL.Internal.AsciiParser.ilInstrs - FSharp.Compiler.AbstractIL.Internal.AsciiLexer.token - (UnicodeLexing.StringAsLexbuf(isFeatureSupported, s)) - with _ -> - errorR(Error(FSComp.SR.astParseEmbeddedILError(), m)); [||] -#endif - -let ParseAssemblyCodeInstructions s m = - // Public API can not answer the isFeatureSupported questions, so here we support everything - let isFeatureSupported (_featureId:LanguageFeature) = true - internalParseAssemblyCodeInstructions s isFeatureSupported m - -let internal internalParseAssemblyCodeType s isFeatureSupported m = - ignore s - ignore isFeatureSupported - -#if NO_INLINE_IL_PARSER - errorR(Error((193, "Inline IL not valid in a hosted environment"), m)) - IL.EcmaMscorlibILGlobals.typ_Object -#else - let isFeatureSupported (_featureId:LanguageFeature) = true - try - FSharp.Compiler.AbstractIL.Internal.AsciiParser.ilType - FSharp.Compiler.AbstractIL.Internal.AsciiLexer.token - (UnicodeLexing.StringAsLexbuf(isFeatureSupported, s)) - with RecoverableParseError -> - errorR(Error(FSComp.SR.astParseEmbeddedILTypeError(), m)); - IL.EcmaMscorlibILGlobals.typ_Object -#endif - -/// Helper for parsing the inline IL fragments. -let ParseAssemblyCodeType s m = - // Public API can not answer the isFeatureSupported questions, so here we support everything - let isFeatureSupported (_featureId:LanguageFeature) = true - internalParseAssemblyCodeType s isFeatureSupported m - -//------------------------------------------------------------------------ -// AST constructors -//------------------------------------------------------------------------ - -let opNameParenGet = CompileOpName parenGet -let opNameQMark = CompileOpName qmark -let mkSynOperator opm oper = mkSynIdGet opm (CompileOpName oper) - -let mkSynInfix opm (l: SynExpr) oper (r: SynExpr) = - let firstTwoRange = unionRanges l.Range opm - let wholeRange = unionRanges l.Range r.Range - SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator opm oper, l, firstTwoRange), r, wholeRange) - -let mkSynBifix m oper x1 x2 = - SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator m oper, x1, m), x2, m) - -let mkSynTrifix m oper x1 x2 x3 = - SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynOperator m oper, x1, m), x2, m), x3, m) - -let mkSynPrefixPrim opm m oper x = - SynExpr.App (ExprAtomicFlag.NonAtomic, false, mkSynOperator opm oper, x, m) - -let mkSynPrefix opm m oper x = - if oper = "~&" then - SynExpr.AddressOf (true, x, opm, m) - elif oper = "~&&" then - SynExpr.AddressOf (false, x, opm, m) - else - mkSynPrefixPrim opm m oper x - -let mkSynCaseName m n = [mkSynId m (CompileOpName n)] - -let mkSynApp1 f x1 m = SynExpr.App (ExprAtomicFlag.NonAtomic, false, f, x1, m) -let mkSynApp2 f x1 x2 m = mkSynApp1 (mkSynApp1 f x1 m) x2 m -let mkSynApp3 f x1 x2 x3 m = mkSynApp1 (mkSynApp2 f x1 x2 m) x3 m -let mkSynApp4 f x1 x2 x3 x4 m = mkSynApp1 (mkSynApp3 f x1 x2 x3 m) x4 m -let mkSynApp5 f x1 x2 x3 x4 x5 m = mkSynApp1 (mkSynApp4 f x1 x2 x3 x4 m) x5 m -let mkSynDotParenSet m a b c = mkSynTrifix m parenSet a b c -let mkSynDotBrackGet m mDot a b fromEnd = SynExpr.DotIndexedGet (a, [SynIndexerArg.One (b, fromEnd, m)], mDot, m) -let mkSynQMarkSet m a b c = mkSynTrifix m qmarkSet a b c -let mkSynDotBrackSliceGet m mDot arr sliceArg = SynExpr.DotIndexedGet (arr, [sliceArg], mDot, m) - -let mkSynDotBrackSeqSliceGet m mDot arr (argsList: list) = - SynExpr.DotIndexedGet (arr, argsList, mDot, m) - -let mkSynDotParenGet lhsm dotm a b = - match b with - | SynExpr.Tuple (false, [_;_], _, _) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(), lhsm)) ; SynExpr.Const (SynConst.Unit, lhsm) - | SynExpr.Tuple (false, [_;_;_], _, _) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(), lhsm)) ; SynExpr.Const (SynConst.Unit, lhsm) - | _ -> mkSynInfix dotm a parenGet b - -let mkSynUnit m = SynExpr.Const (SynConst.Unit, m) -let mkSynUnitPat m = SynPat.Const(SynConst.Unit, m) -let mkSynDelay m e = SynExpr.Lambda (false, false, SynSimplePats.SimplePats ([mkSynCompGenSimplePatVar (mkSynId m "unitVar")], m), e, m) - -let mkSynAssign (l: SynExpr) (r: SynExpr) = - let m = unionRanges l.Range r.Range - match l with - //| SynExpr.Paren (l2, m2) -> mkSynAssign m l2 r - | LongOrSingleIdent(false, v, None, _) -> SynExpr.LongIdentSet (v, r, m) - | SynExpr.DotGet (e, _, v, _) -> SynExpr.DotSet (e, v, r, m) - | SynExpr.DotIndexedGet (e1, e2, mDot, mLeft) -> SynExpr.DotIndexedSet (e1, e2, r, mLeft, mDot, m) - | SynExpr.LibraryOnlyUnionCaseFieldGet (x, y, z, _) -> SynExpr.LibraryOnlyUnionCaseFieldSet (x, y, z, r, m) - | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent nm, a, _), b, _) when nm.idText = opNameQMark -> - mkSynQMarkSet m a b r - | SynExpr.App (_, _, SynExpr.App (_, _, SingleIdent nm, a, _), b, _) when nm.idText = opNameParenGet -> - mkSynDotParenSet m a b r - | SynExpr.App (_, _, SynExpr.LongIdent (false, v, None, _), x, _) -> SynExpr.NamedIndexedPropertySet (v, x, r, m) - | SynExpr.App (_, _, SynExpr.DotGet (e, _, v, _), x, _) -> SynExpr.DotNamedIndexedPropertySet (e, v, x, r, m) - | l -> SynExpr.Set (l, r, m) - //| _ -> errorR(Error(FSComp.SR.astInvalidExprLeftHandOfAssignment(), m)); l // return just the LHS, so the typechecker can see it and capture expression typings that may be useful for dot lookups - -let rec mkSynDot dotm m l r = - match l with - | SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots), None, _) -> - SynExpr.LongIdent (isOpt, LongIdentWithDots(lid@[r], dots@[dotm]), None, m) // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) - an ImmutableArray would be better here - | SynExpr.Ident id -> - SynExpr.LongIdent (false, LongIdentWithDots([id;r], [dotm]), None, m) - | SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots), _) -> - SynExpr.DotGet (e, dm, LongIdentWithDots(lid@[r], dots@[dotm]), m)// REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) - an ImmutableArray would be better here - | expr -> - SynExpr.DotGet (expr, dotm, LongIdentWithDots([r], []), m) - -let rec mkSynDotMissing dotm m l = - match l with - | SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots), None, _) -> - SynExpr.LongIdent (isOpt, LongIdentWithDots(lid, dots@[dotm]), None, m) // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) - an ImmutableArray would be better here - | SynExpr.Ident id -> - SynExpr.LongIdent (false, LongIdentWithDots([id], [dotm]), None, m) - | SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots), _) -> - SynExpr.DotGet (e, dm, LongIdentWithDots(lid, dots@[dotm]), m)// REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) - an ImmutableArray would be better here - | expr -> - SynExpr.DiscardAfterMissingQualificationAfterDot (expr, m) - -let mkSynFunMatchLambdas synArgNameGenerator isMember wholem ps e = - let _, e = PushCurriedPatternsToExpr synArgNameGenerator wholem isMember ps e - e - - -// error recovery - the contract is that these expressions can only be produced if an error has already been reported -// (as a result, future checking may choose not to report errors involving these, to prevent noisy cascade errors) -let arbExpr(debugStr, range: range) = SynExpr.ArbitraryAfterError (debugStr, range.MakeSynthetic()) -type SynExpr with - member this.IsArbExprAndThusAlreadyReportedError = - match this with - | SynExpr.ArbitraryAfterError _ -> true - | _ -> false - -/// The syntactic elements associated with the "return" of a function or method. Some of this is -/// mostly dummy information to make the return element look like an argument, -/// the important thing is that (a) you can give a return type for the function or method, and -/// (b) you can associate .NET attributes to return of a function or method and these get stored in .NET metadata. -type SynReturnInfo = SynReturnInfo of (SynType * SynArgInfo) * range: range - - -let mkAttributeList attrs range = - [{ Attributes = attrs - Range = range }] - -let ConcatAttributesLists (attrsLists: SynAttributeList list) = - attrsLists - |> List.map (fun x -> x.Attributes) - |> List.concat - -let (|Attributes|) synAttributes = - ConcatAttributesLists synAttributes - -/// Operations related to the syntactic analysis of arguments of value, function and member definitions and signatures. -/// -/// Function and member definitions have strongly syntactically constrained arities. We infer -/// the arity from the syntax. -/// -/// For example, we record the arity for: -/// StaticProperty --> [1] -- for unit arg -/// this.InstanceProperty --> [1;1] -- for unit arg -/// StaticMethod(args) --> map InferSynArgInfoFromSimplePat args -/// this.InstanceMethod() --> 1 :: map InferSynArgInfoFromSimplePat args -/// this.InstanceProperty with get(argpat) --> 1 :: [InferSynArgInfoFromSimplePat argpat] -/// StaticProperty with get(argpat) --> [InferSynArgInfoFromSimplePat argpat] -/// this.InstanceProperty with get() --> 1 :: [InferSynArgInfoFromSimplePat argpat] -/// StaticProperty with get() --> [InferSynArgInfoFromSimplePat argpat] -/// -/// this.InstanceProperty with set(argpat)(v) --> 1 :: [InferSynArgInfoFromSimplePat argpat; 1] -/// StaticProperty with set(argpat)(v) --> [InferSynArgInfoFromSimplePat argpat; 1] -/// this.InstanceProperty with set(v) --> 1 :: [1] -/// StaticProperty with set(v) --> [1] -module SynInfo = - /// The argument information for an argument without a name - let unnamedTopArg1 = SynArgInfo([], false, None) - - /// The argument information for a curried argument without a name - let unnamedTopArg = [unnamedTopArg1] - - /// The argument information for a '()' argument - let unitArgData = unnamedTopArg - - /// The 'argument' information for a return value where no attributes are given for the return value (the normal case) - let unnamedRetVal = SynArgInfo([], false, None) - - /// The 'argument' information for the 'this'/'self' parameter in the cases where it is not given explicitly - let selfMetadata = unnamedTopArg - - /// Determine if a syntactic information represents a member without arguments (which is implicitly a property getter) - let HasNoArgs (SynValInfo(args, _)) = isNil args - - /// Check if one particular argument is an optional argument. Used when adjusting the - /// types of optional arguments for function and member signatures. - let IsOptionalArg (SynArgInfo(_, isOpt, _)) = isOpt - - /// Check if there are any optional arguments in the syntactic argument information. Used when adjusting the - /// types of optional arguments for function and member signatures. - let HasOptionalArgs (SynValInfo(args, _)) = List.exists (List.exists IsOptionalArg) args - - /// Add a parameter entry to the syntactic value information to represent the '()' argument to a property getter. This is - /// used for the implicit '()' argument in property getter signature specifications. - let IncorporateEmptyTupledArgForPropertyGetter (SynValInfo(args, retInfo)) = SynValInfo([] :: args, retInfo) - - /// Add a parameter entry to the syntactic value information to represent the 'this' argument. This is - /// used for the implicit 'this' argument in member signature specifications. - let IncorporateSelfArg (SynValInfo(args, retInfo)) = SynValInfo(selfMetadata :: args, retInfo) - - /// Add a parameter entry to the syntactic value information to represent the value argument for a property setter. This is - /// used for the implicit value argument in property setter signature specifications. - let IncorporateSetterArg (SynValInfo(args, retInfo)) = - let args = - match args with - | [] -> [unnamedTopArg] - | [arg] -> [arg@[unnamedTopArg1]] - | _ -> failwith "invalid setter type" - SynValInfo(args, retInfo) - - /// Get the argument counts for each curried argument group. Used in some adhoc places in tc.fs. - let AritiesOfArgs (SynValInfo(args, _)) = List.map List.length args - - /// Get the argument attributes from the syntactic information for an argument. - let AttribsOfArgData (SynArgInfo(Attributes attribs, _, _)) = attribs - - /// Infer the syntactic argument info for a single argument from a simple pattern. - let rec InferSynArgInfoFromSimplePat attribs p = - match p with - | SynSimplePat.Id(nm, _, isCompGen, _, isOpt, _) -> - SynArgInfo(attribs, isOpt, (if isCompGen then None else Some nm)) - | SynSimplePat.Typed(a, _, _) -> InferSynArgInfoFromSimplePat attribs a - | SynSimplePat.Attrib(a, attribs2, _) -> InferSynArgInfoFromSimplePat (attribs @ attribs2) a - - /// Infer the syntactic argument info for one or more arguments one or more simple patterns. - let rec InferSynArgInfoFromSimplePats x = - match x with - | SynSimplePats.SimplePats(ps, _) -> List.map (InferSynArgInfoFromSimplePat []) ps - | SynSimplePats.Typed(ps, _, _) -> InferSynArgInfoFromSimplePats ps - - /// Infer the syntactic argument info for one or more arguments a pattern. - let InferSynArgInfoFromPat p = - // It is ok to use a fresh SynArgNameGenerator here, because compiler generated names are filtered from SynArgInfo, see InferSynArgInfoFromSimplePat above - let sp, _ = SimplePatsOfPat (SynArgNameGenerator()) p - InferSynArgInfoFromSimplePats sp - - /// Make sure only a solitary unit argument has unit elimination - let AdjustArgsForUnitElimination infosForArgs = - match infosForArgs with - | [[]] -> infosForArgs - | _ -> infosForArgs |> List.map (function [] -> unitArgData | x -> x) - - /// Transform a property declared using '[static] member P = expr' to a method taking a "unit" argument. - /// This is similar to IncorporateEmptyTupledArgForPropertyGetter, but applies to member definitions - /// rather than member signatures. - let AdjustMemberArgs memFlags infosForArgs = - match infosForArgs with - | [] when memFlags=MemberKind.Member -> [] :: infosForArgs - | _ -> infosForArgs - - /// For 'let' definitions, we infer syntactic argument information from the r.h.s. of a definition, if it - /// is an immediate 'fun ... -> ...' or 'function ...' expression. This is noted in the F# language specification. - /// This does not apply to member definitions. - let InferLambdaArgs origRhsExpr = - let rec loop e = - match e with - | SynExpr.Lambda (false, _, spats, rest, _) -> - InferSynArgInfoFromSimplePats spats :: loop rest - | _ -> [] - loop origRhsExpr - - let InferSynReturnData (retInfo: SynReturnInfo option) = - match retInfo with - | None -> unnamedRetVal - | Some(SynReturnInfo((_, retInfo), _)) -> retInfo - - let private emptySynValInfo = SynValInfo([], unnamedRetVal) - - let emptySynValData = SynValData(None, emptySynValInfo, None) - - /// Infer the syntactic information for a 'let' or 'member' definition, based on the argument pattern, - /// any declared return information (e.g. .NET attributes on the return element), and the r.h.s. expression - /// in the case of 'let' definitions. - let InferSynValData (memberFlagsOpt, pat, retInfo, origRhsExpr) = - - let infosForExplicitArgs = - match pat with - | Some(SynPat.LongIdent(_, _, _, SynConstructorArgs.Pats curriedArgs, _, _)) -> List.map InferSynArgInfoFromPat curriedArgs - | _ -> [] - - let explicitArgsAreSimple = - match pat with - | Some(SynPat.LongIdent(_, _, _, SynConstructorArgs.Pats curriedArgs, _, _)) -> List.forall isSimplePattern curriedArgs - | _ -> true - - let retInfo = InferSynReturnData retInfo - - match memberFlagsOpt with - | None -> - let infosForLambdaArgs = InferLambdaArgs origRhsExpr - let infosForArgs = infosForExplicitArgs @ (if explicitArgsAreSimple then infosForLambdaArgs else []) - let infosForArgs = AdjustArgsForUnitElimination infosForArgs - SynValData(None, SynValInfo(infosForArgs, retInfo), None) - - | Some memFlags -> - let infosForObjArgs = - if memFlags.IsInstance then [ selfMetadata ] else [] - - let infosForArgs = AdjustMemberArgs memFlags.MemberKind infosForExplicitArgs - let infosForArgs = AdjustArgsForUnitElimination infosForArgs - - let argInfos = infosForObjArgs @ infosForArgs - SynValData(Some memFlags, SynValInfo(argInfos, retInfo), None) - - - -let mkSynBindingRhs staticOptimizations rhsExpr mRhs retInfo = - let rhsExpr = List.foldBack (fun (c, e1) e2 -> SynExpr.LibraryOnlyStaticOptimization (c, e1, e2, mRhs)) staticOptimizations rhsExpr - let rhsExpr, retTyOpt = - match retInfo with - | Some (SynReturnInfo((ty, SynArgInfo(rAttribs, _, _)), tym)) -> SynExpr.Typed (rhsExpr, ty, rhsExpr.Range), Some(SynBindingReturnInfo(ty, tym, rAttribs) ) - | None -> rhsExpr, None - rhsExpr, retTyOpt - -let mkSynBinding (xmlDoc, headPat) (vis, isInline, isMutable, mBind, spBind, retInfo, origRhsExpr, mRhs, staticOptimizations, attrs, memberFlagsOpt) = - let info = SynInfo.InferSynValData (memberFlagsOpt, Some headPat, retInfo, origRhsExpr) - let rhsExpr, retTyOpt = mkSynBindingRhs staticOptimizations origRhsExpr mRhs retInfo - Binding (vis, NormalBinding, isInline, isMutable, attrs, xmlDoc, info, headPat, retTyOpt, rhsExpr, mBind, spBind) - -let NonVirtualMemberFlags k = { MemberKind=k; IsInstance=true; IsDispatchSlot=false; IsOverrideOrExplicitImpl=false; IsFinal=false } -let CtorMemberFlags = { MemberKind=MemberKind.Constructor; IsInstance=false; IsDispatchSlot=false; IsOverrideOrExplicitImpl=false; IsFinal=false } -let ClassCtorMemberFlags = { MemberKind=MemberKind.ClassConstructor; IsInstance=false; IsDispatchSlot=false; IsOverrideOrExplicitImpl=false; IsFinal=false } -let OverrideMemberFlags k = { MemberKind=k; IsInstance=true; IsDispatchSlot=false; IsOverrideOrExplicitImpl=true; IsFinal=false } -let AbstractMemberFlags k = { MemberKind=k; IsInstance=true; IsDispatchSlot=true; IsOverrideOrExplicitImpl=false; IsFinal=false } -let StaticMemberFlags k = { MemberKind=k; IsInstance=false; IsDispatchSlot=false; IsOverrideOrExplicitImpl=false; IsFinal=false } - -let inferredTyparDecls = SynValTyparDecls([], true, []) -let noInferredTypars = SynValTyparDecls([], false, []) - -//------------------------------------------------------------------------ -// Lexer args: status of #if/#endif processing. -//------------------------------------------------------------------------ - -type LexerIfdefStackEntry = IfDefIf | IfDefElse -type LexerIfdefStackEntries = (LexerIfdefStackEntry * range) list -type LexerIfdefStack = LexerIfdefStackEntries - -/// Specifies how the 'endline' function in the lexer should continue after -/// it reaches end of line or eof. The options are to continue with 'token' function -/// or to continue with 'skip' function. -type LexerEndlineContinuation = - | Token of LexerIfdefStackEntries - | Skip of LexerIfdefStackEntries * int * range: range - member x.LexerIfdefStack = - match x with - | LexerEndlineContinuation.Token ifd - | LexerEndlineContinuation.Skip(ifd, _, _) -> ifd - -type LexerIfdefExpression = - | IfdefAnd of LexerIfdefExpression*LexerIfdefExpression - | IfdefOr of LexerIfdefExpression*LexerIfdefExpression - | IfdefNot of LexerIfdefExpression - | IfdefId of string - -let rec LexerIfdefEval (lookup: string -> bool) = function - | IfdefAnd (l, r) -> (LexerIfdefEval lookup l) && (LexerIfdefEval lookup r) - | IfdefOr (l, r) -> (LexerIfdefEval lookup l) || (LexerIfdefEval lookup r) - | IfdefNot e -> not (LexerIfdefEval lookup e) - | IfdefId id -> lookup id - -/// The parser defines a number of tokens for whitespace and -/// comments eliminated by the lexer. These carry a specification of -/// a continuation for the lexer for continued processing after we've dealt with -/// the whitespace. -[] -[] -type LexerWhitespaceContinuation = - | Token of ifdef: LexerIfdefStackEntries - | IfDefSkip of ifdef: LexerIfdefStackEntries * int * range: range - | String of ifdef: LexerIfdefStackEntries * range: range - | VerbatimString of ifdef: LexerIfdefStackEntries * range: range - | TripleQuoteString of ifdef: LexerIfdefStackEntries * range: range - | Comment of ifdef: LexerIfdefStackEntries * int * range: range - | SingleLineComment of ifdef: LexerIfdefStackEntries * int * range: range - | StringInComment of ifdef: LexerIfdefStackEntries * int * range: range - | VerbatimStringInComment of ifdef: LexerIfdefStackEntries * int * range: range - | TripleQuoteStringInComment of ifdef: LexerIfdefStackEntries * int * range: range - | MLOnly of ifdef: LexerIfdefStackEntries * range: range - | EndLine of LexerEndlineContinuation - - member x.LexerIfdefStack = - match x with - | LexCont.Token (ifdef=ifd) - | LexCont.IfDefSkip (ifdef=ifd) - | LexCont.String (ifdef=ifd) - | LexCont.VerbatimString (ifdef=ifd) - | LexCont.Comment (ifdef=ifd) - | LexCont.SingleLineComment (ifdef=ifd) - | LexCont.TripleQuoteString (ifdef=ifd) - | LexCont.StringInComment (ifdef=ifd) - | LexCont.VerbatimStringInComment (ifdef=ifd) - | LexCont.TripleQuoteStringInComment (ifdef=ifd) - | LexCont.MLOnly (ifdef=ifd) -> ifd - | LexCont.EndLine endl -> endl.LexerIfdefStack - -and LexCont = LexerWhitespaceContinuation - -//------------------------------------------------------------------------ -// Parser/Lexer state -//------------------------------------------------------------------------ - -/// The error raised by the parse_error_rich function, which is called by the parser engine -/// when a syntax error occurs. The first object is the ParseErrorContext which contains a dump of -/// information about the grammar at the point where the error occurred, e.g. what tokens -/// are valid to shift next at that point in the grammar. This information is processed in CompileOps.fs. -[] -exception SyntaxError of obj (* ParseErrorContext<_> *) * range: range - -/// Get an F# compiler position from a lexer position -let internal posOfLexPosition (p: Position) = - mkPos p.Line p.Column - -/// Get an F# compiler range from a lexer range -let internal mkSynRange (p1: Position) (p2: Position) = - mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2) - -type LexBuffer<'Char> with - member internal lexbuf.LexemeRange = mkSynRange lexbuf.StartPos lexbuf.EndPos - -/// Get the range corresponding to the result of a grammar rule while it is being reduced -let internal lhs (parseState: IParseState) = - let p1 = parseState.ResultStartPosition - let p2 = parseState.ResultEndPosition - mkSynRange p1 p2 - -/// Get the range covering two of the r.h.s. symbols of a grammar rule while it is being reduced -let internal rhs2 (parseState: IParseState) i j = - let p1 = parseState.InputStartPosition i - let p2 = parseState.InputEndPosition j - mkSynRange p1 p2 - -/// Get the range corresponding to one of the r.h.s. symbols of a grammar rule while it is being reduced -let internal rhs parseState i = rhs2 parseState i i - -type IParseState with - - /// Get the generator used for compiler-generated argument names. - member internal x.SynArgNameGenerator = - let key = "SynArgNameGenerator" - let bls = x.LexBuffer.BufferLocalStore - let gen = - match bls.TryGetValue key with - | true, gen -> gen - | _ -> - let gen = box (SynArgNameGenerator()) - bls.[key] <- gen - gen - gen :?> SynArgNameGenerator - - /// Reset the generator used for compiler-generated argument names. - member internal x.ResetSynArgNameGenerator() = x.SynArgNameGenerator.Reset() - - -/// XmlDoc F# lexer/parser state, held in the BufferLocalStore for the lexer. -/// This is the only use of the lexer BufferLocalStore in the codebase. -module LexbufLocalXmlDocStore = - // The key into the BufferLocalStore used to hold the current accumulated XmlDoc lines - let private xmlDocKey = "XmlDoc" - - let internal ClearXmlDoc (lexbuf: Lexbuf) = - lexbuf.BufferLocalStore.[xmlDocKey] <- box (XmlDocCollector()) - - /// Called from the lexer to save a single line of XML doc comment. - let internal SaveXmlDocLine (lexbuf: Lexbuf, lineText, pos) = - let collector = - match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with - | true, collector -> collector - | _ -> - let collector = box (XmlDocCollector()) - lexbuf.BufferLocalStore.[xmlDocKey] <- collector - collector - let collector = unbox(collector) - collector.AddXmlDocLine(lineText, pos) - - /// Called from the parser each time we parse a construct that marks the end of an XML doc comment range, - /// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct. - let internal GrabXmlDocBeforeMarker (lexbuf: Lexbuf, markerRange: range) = - match lexbuf.BufferLocalStore.TryGetValue xmlDocKey with - | true, collector -> - let collector = unbox(collector) - PreXmlDoc.CreateFromGrabPoint(collector, markerRange.End) - | _ -> - PreXmlDoc.Empty - -let rec synExprContainsError inpExpr = - let rec walkBind (Binding(_, _, _, _, _, _, _, _, _, synExpr, _, _)) = walkExpr synExpr - and walkExprs es = es |> List.exists walkExpr - and walkBinds es = es |> List.exists walkBind - and walkMatchClauses cl = cl |> List.exists (fun (Clause(_, whenExpr, e, _, _)) -> walkExprOpt whenExpr || walkExpr e) - and walkExprOpt eOpt = eOpt |> Option.exists walkExpr - and walkExpr e = - match e with - | SynExpr.FromParseError _ - | SynExpr.DiscardAfterMissingQualificationAfterDot _ - | SynExpr.ArbitraryAfterError _ -> true - | SynExpr.LongIdent _ - | SynExpr.Quote _ - | SynExpr.LibraryOnlyILAssembly _ - | SynExpr.LibraryOnlyStaticOptimization _ - | SynExpr.Null _ - | SynExpr.Ident _ - | SynExpr.ImplicitZero _ - | SynExpr.Const _ -> false - - | SynExpr.TypeTest (e, _, _) - | SynExpr.Upcast (e, _, _) - | SynExpr.AddressOf (_, e, _, _) - | SynExpr.CompExpr (_, _, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) - | SynExpr.Typed (e, _, _) - | SynExpr.FromParseError (e, _) - | SynExpr.Do (e, _) - | SynExpr.Assert (e, _) - | SynExpr.DotGet (e, _, _, _) - | SynExpr.LongIdentSet (_, e, _) - | SynExpr.New (_, _, e, _) - | SynExpr.TypeApp (e, _, _, _, _, _, _) - | SynExpr.LibraryOnlyUnionCaseFieldGet (e, _, _, _) - | SynExpr.Downcast (e, _, _) - | SynExpr.InferredUpcast (e, _) - | SynExpr.InferredDowncast (e, _) - | SynExpr.Lazy (e, _) - | SynExpr.TraitCall (_, _, e, _) - | SynExpr.YieldOrReturn (_, e, _) - | SynExpr.YieldOrReturnFrom (_, e, _) - | SynExpr.DoBang (e, _) - | SynExpr.Fixed (e, _) - | SynExpr.Paren (e, _, _, _) -> - walkExpr e - - | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) - | SynExpr.DotSet (e1, _, e2, _) - | SynExpr.Set (e1, e2, _) - | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, _, _, e2, _) - | SynExpr.JoinIn (e1, _, e2, _) - | SynExpr.App (_, _, e1, e2, _) -> - walkExpr e1 || walkExpr e2 - - | SynExpr.ArrayOrList (_, es, _) - | SynExpr.Tuple (_, es, _, _) -> - walkExprs es - - | SynExpr.AnonRecd (_, origExpr, flds, _) -> - (match origExpr with Some (e, _) -> walkExpr e | None -> false) || - walkExprs (List.map snd flds) - - | SynExpr.Record (_, origExpr, fs, _) -> - (match origExpr with Some (e, _) -> walkExpr e | None -> false) || - let flds = fs |> List.choose (fun (_, v, _) -> v) - walkExprs flds - - | SynExpr.ObjExpr (_, _, bs, is, _, _) -> - walkBinds bs || walkBinds [ for (InterfaceImpl(_, bs, _)) in is do yield! bs ] - | SynExpr.ForEach (_, _, _, _, e1, e2, _) - | SynExpr.While (_, e1, e2, _) -> - walkExpr e1 || walkExpr e2 - | SynExpr.For (_, _, e1, _, e2, e3, _) -> - walkExpr e1 || walkExpr e2 || walkExpr e3 - | SynExpr.MatchLambda (_, _, cl, _, _) -> - walkMatchClauses cl - | SynExpr.Lambda (_, _, _, e, _) -> - walkExpr e - | SynExpr.Match (_, e, cl, _) -> - walkExpr e || walkMatchClauses cl - | SynExpr.LetOrUse (_, _, bs, e, _) -> - walkBinds bs || walkExpr e - - | SynExpr.TryWith (e, _, cl, _, _, _, _) -> - walkExpr e || walkMatchClauses cl - - | SynExpr.TryFinally (e1, e2, _, _, _) -> - walkExpr e1 || walkExpr e2 - | SynExpr.Sequential (_, _, e1, e2, _) -> - walkExpr e1 || walkExpr e2 - | SynExpr.SequentialOrImplicitYield (_, e1, e2, _, _) -> - walkExpr e1 || walkExpr e2 - | SynExpr.IfThenElse (e1, e2, e3opt, _, _, _, _) -> - walkExpr e1 || walkExpr e2 || walkExprOpt e3opt - | SynExpr.DotIndexedGet (e1, es, _, _) -> - walkExpr e1 || walkExprs [ for e in es do yield! e.Exprs ] - - | SynExpr.DotIndexedSet (e1, es, e2, _, _, _) -> - walkExpr e1 || walkExprs [ for e in es do yield! e.Exprs ] || walkExpr e2 - | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> - walkExpr e1 || walkExpr e2 || walkExpr e3 - - | SynExpr.MatchBang (_, e, cl, _) -> - walkExpr e || walkMatchClauses cl - | SynExpr.LetOrUseBang (_, _, _, _, e1, e2, _) -> - walkExpr e1 || walkExpr e2 - walkExpr inpExpr diff --git a/src/fsharp/autobox.fs b/src/fsharp/autobox.fs index 8c7036e72ce..31c555e7a9c 100644 --- a/src/fsharp/autobox.fs +++ b/src/fsharp/autobox.fs @@ -2,12 +2,13 @@ module internal FSharp.Compiler.AutoBox -open FSharp.Compiler.AbstractIL.Internal +open Internal.Utilities.Collections +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypeRelations @@ -22,12 +23,15 @@ type cenv = /// Find all the mutable locals that escape a method, function or lambda expression let DecideEscapes syntacticArgs body = - let cantBeFree v = + let isMutableEscape v = let passedIn = ListSet.contains valEq v syntacticArgs - not passedIn && (v.IsMutable && v.ValReprInfo.IsNone) + not passedIn && + v.IsMutable && + v.ValReprInfo.IsNone && + not (Optimizer.IsKnownOnlyMutableBeforeUse (mkLocalValRef v)) let frees = freeInExpr CollectLocals body - frees.FreeLocals |> Zset.filter cantBeFree + frees.FreeLocals |> Zset.filter isMutableEscape /// Find all the mutable locals that escape a lambda expression, ignoring the arguments to the lambda let DecideLambda exprF cenv topValInfo expr ety z = @@ -56,10 +60,10 @@ let DecideExprOp exprF noInterceptF (z: Zset) (expr: Expr) (op, tyargs, arg | TOp.TryFinally _, [_], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)] -> exprF (exprF z e1) e2 - | TOp.For (_), _, [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [_], e3, _, _)] -> + | TOp.For _, _, [Expr.Lambda (_, _, _, [_], e1, _, _);Expr.Lambda (_, _, _, [_], e2, _, _);Expr.Lambda (_, _, _, [_], e3, _, _)] -> exprF (exprF (exprF z e1) e2) e3 - | TOp.TryCatch _, [_], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], _e2, _, _); Expr.Lambda (_, _, _, [_], e3, _, _)] -> + | TOp.TryWith _, [_], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], _e2, _, _); Expr.Lambda (_, _, _, [_], e3, _, _)] -> exprF (exprF (exprF z e1) _e2) e3 // In Check code it said // e2; -- don't check filter body - duplicates logic in 'catch' body @@ -126,7 +130,6 @@ let DecideImplFile g amap implFile = z - //---------------------------------------------------------------------------- // Apply the transform @@ -154,7 +157,6 @@ let TransformExpr g (nvs: ValMap<_>) exprF expr = | _ -> None - /// Rewrite bindings for mutable locals which we are transforming let TransformBinding g (nvs: ValMap<_>) exprF (TBind(v, expr, m)) = if nvs.ContainsVal v then diff --git a/src/fsharp/autobox.fsi b/src/fsharp/autobox.fsi index 2ec2e9ba7fb..00feb25f75a 100644 --- a/src/fsharp/autobox.fsi +++ b/src/fsharp/autobox.fsi @@ -2,9 +2,9 @@ module internal FSharp.Compiler.AutoBox -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals open FSharp.Compiler.Import +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree /// Rewrite mutable locals to reference cells across an entire implementation file val TransformImplFile: g: TcGlobals -> amap: ImportMap -> implFile: TypedImplFile -> TypedImplFile diff --git a/src/fsharp/block.fs b/src/fsharp/block.fs new file mode 100644 index 00000000000..ca74049032f --- /dev/null +++ b/src/fsharp/block.fs @@ -0,0 +1,187 @@ +module Internal.Utilities.Library.Block + +open System.Collections.Immutable + +type block<'T> = ImmutableArray<'T> +type blockbuilder<'T> = ImmutableArray<'T>.Builder + +[] +module BlockBuilder = + + let create size : blockbuilder<'T> = + ImmutableArray.CreateBuilder(size) + +[] +module Block = + + [] + let empty<'T> = ImmutableArray<'T>.Empty + + let init n (f: int -> 'T) : block<_> = + match n with + | 0 -> ImmutableArray.Empty + | 1 -> ImmutableArray.Create(f 0) + | n -> + if n < 0 then + invalidArg "n" "Below zero." + + let builder = ImmutableArray.CreateBuilder(n) + for i = 0 to n - 1 do + builder.Add(f i) + builder.MoveToImmutable() + + let iter f (arr: block<'T>) = + for i = 0 to arr.Length - 1 do + f arr.[i] + + let iteri f (arr: block<'T>) = + for i = 0 to arr.Length - 1 do + f i arr.[i] + + let iter2 f (arr1: block<'T1>) (arr2: block<'T2>) = + if arr1.Length <> arr2.Length then + invalidOp "Block lengths do not match." + + for i = 0 to arr1.Length - 1 do + f arr1.[i] arr2.[i] + + let iteri2 f (arr1: block<'T1>) (arr2: block<'T2>) = + if arr1.Length <> arr2.Length then + invalidOp "Block lengths do not match." + + for i = 0 to arr1.Length - 1 do + f i arr1.[i] arr2.[i] + + let map (mapper: 'T -> 'U) (arr: block<'T>) : block<_> = + match arr.Length with + | 0 -> ImmutableArray.Empty + | 1 -> ImmutableArray.Create(mapper arr.[0]) + | _ -> + let builder = ImmutableArray.CreateBuilder(arr.Length) + for i = 0 to arr.Length - 1 do + builder.Add(mapper arr.[i]) + builder.MoveToImmutable() + + let mapi (mapper: int -> 'T -> 'U) (arr: block<'T>) : block<_> = + match arr.Length with + | 0 -> ImmutableArray.Empty + | 1 -> ImmutableArray.Create(mapper 0 arr.[0]) + | _ -> + let builder = ImmutableArray.CreateBuilder(arr.Length) + for i = 0 to arr.Length - 1 do + builder.Add(mapper i arr.[i]) + builder.MoveToImmutable() + + let map2 (mapper: 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> = + if arr1.Length <> arr2.Length then + invalidOp "Block lengths do not match." + + match arr1.Length with + | 0 -> ImmutableArray.Empty + | 1 -> ImmutableArray.Create(mapper arr1.[0] arr2.[0]) + | n -> + let builder = ImmutableArray.CreateBuilder(n) + for i = 0 to n - 1 do + builder.Add(mapper arr1.[i] arr2.[i]) + builder.MoveToImmutable() + + let mapi2 (mapper: int -> 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> = + if arr1.Length <> arr2.Length then + invalidOp "Block lengths do not match." + + match arr1.Length with + | 0 -> ImmutableArray.Empty + | 1 -> ImmutableArray.Create(mapper 0 arr1.[0] arr2.[0]) + | n -> + let builder = ImmutableArray.CreateBuilder(n) + for i = 0 to n - 1 do + builder.Add(mapper i arr1.[i] arr2.[i]) + builder.MoveToImmutable() + + let concat (arrs: block>) : block<'T> = + match arrs.Length with + | 0 -> ImmutableArray.Empty + | 1 -> arrs.[0] + | 2 -> arrs.[0].AddRange(arrs.[1]) + | _ -> + let mutable acc = 0 + for h in arrs do + acc <- acc + h.Length + + let builder = ImmutableArray.CreateBuilder(acc) + for i = 0 to arrs.Length - 1 do + builder.AddRange(arrs.[i]) + builder.MoveToImmutable() + + let forall predicate (arr: block<'T>) = + let len = arr.Length + let rec loop i = i >= len || (predicate arr.[i] && loop (i+1)) + loop 0 + + let forall2 predicate (arr1: block<'T1>) (arr2: block<'T2>) = + if arr1.Length <> arr2.Length then + invalidOp "Block lengths do not match." + + let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(predicate) + let len1 = arr1.Length + let rec loop i = i >= len1 || (f.Invoke(arr1.[i], arr2.[i]) && loop (i+1)) + loop 0 + + let tryFind predicate (arr: block<'T>) = + let rec loop i = + if i >= arr.Length then None else + if predicate arr.[i] then Some arr.[i] else loop (i+1) + loop 0 + + let tryFindIndex predicate (arr: block<'T>) = + let len = arr.Length + let rec go n = if n >= len then None elif predicate arr.[n] then Some n else go (n+1) + go 0 + + let tryPick chooser (arr: block<'T>) = + let rec loop i = + if i >= arr.Length then None else + match chooser arr.[i] with + | None -> loop(i+1) + | res -> res + loop 0 + + let ofSeq (xs: 'T seq) = + ImmutableArray.CreateRange(xs) + + let append (arr1: block<'T1>) (arr2: block<'T1>) : block<_> = + arr1.AddRange(arr2) + + let createOne (item: 'T) : block<_> = + ImmutableArray.Create(item) + + let filter predicate (arr: block<'T>) : block<'T> = + let builder = ImmutableArray.CreateBuilder(arr.Length) + for i = 0 to arr.Length - 1 do + if predicate arr.[i] then + builder.Add(arr.[i]) + builder.Capacity <- builder.Count + builder.MoveToImmutable() + + let exists predicate (arr: block<'T>) = + let len = arr.Length + let rec loop i = i < len && (predicate arr.[i] || loop (i+1)) + len > 0 && loop 0 + + let choose (chooser: 'T -> 'U option) (arr: block<'T>) : block<'U> = + let builder = ImmutableArray.CreateBuilder(arr.Length) + for i = 0 to arr.Length - 1 do + let result = chooser arr.[i] + if result.IsSome then + builder.Add(result.Value) + builder.Capacity <- builder.Count + builder.MoveToImmutable() + + let isEmpty (arr: block<_>) = arr.IsEmpty + + let fold folder state (arr: block<_>) = + let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(folder) + let mutable state = state + for i = 0 to arr.Length - 1 do + state <- f.Invoke(state, arr.[i]) + state diff --git a/src/fsharp/block.fsi b/src/fsharp/block.fsi new file mode 100644 index 00000000000..ec7ef7fa5a0 --- /dev/null +++ b/src/fsharp/block.fsi @@ -0,0 +1,63 @@ +[] +module internal Internal.Utilities.Library.Block + +open System.Collections.Immutable + +/// Type alias for System.Collections.Immutable.ImmutableArray<'T> +type block<'T> = ImmutableArray<'T> + +/// Type alias for System.Collections.Immutable.ImmutableArray<'T>.Builder +type blockbuilder<'T> = ImmutableArray<'T>.Builder + +[] +module BlockBuilder = + + val create : size: int -> blockbuilder<'T> + +[] +module Block = + + [] + val empty<'T> : block<'T> + + val init : n: int -> f: (int -> 'T) -> block<'T> + + val iter : f: ('T -> unit) -> block<'T> -> unit + + val iteri : f: (int -> 'T -> unit) -> block<'T> -> unit + + val iter2 : f: ('T1 -> 'T2 -> unit) -> block<'T1> -> block<'T2> -> unit + + val iteri2 : f: (int -> 'T1 -> 'T2 -> unit) -> block<'T1> -> block<'T2> -> unit + + val map : mapper: ('T1 -> 'T2) -> block<'T1> -> block<'T2> + + val mapi : mapper: (int -> 'T1 -> 'T2) -> block<'T1> -> block<'T2> + + val concat : block> -> block<'T> + + val forall : predicate: ('T -> bool) -> block<'T> -> bool + + val forall2 : predicate: ('T1 -> 'T2 -> bool) -> block<'T1> -> block<'T2> -> bool + + val tryFind : predicate: ('T -> bool) -> block<'T> -> 'T option + + val tryFindIndex : predicate: ('T -> bool) -> block<'T> -> int option + + val tryPick : chooser: ('T1 -> 'T2 option) -> block<'T1> -> 'T2 option + + val ofSeq : seq<'T> -> block<'T> + + val append : block<'T> -> block<'T> -> block<'T> + + val createOne : 'T -> block<'T> + + val filter : predicate: ('T -> bool) -> block<'T> -> block<'T> + + val exists : predicate: ('T -> bool) -> block<'T> -> bool + + val choose : chooser: ('T -> 'U option) -> block<'T> -> block<'U> + + val isEmpty : block<'T> -> bool + + val fold : folder: ('State -> 'T -> 'State) -> 'State -> block<'T> -> 'State \ No newline at end of file diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 839d7b4d631..54edda22d2e 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// Driver for F# compiler. -// +// Driver for F# compiler. +// // Roughly divides into: // - Parsing -// - Flags +// - Flags // - Importing IL assemblies // - Compiling (including optimizing) // - Linking (including ILX-IL transformation) - -module internal FSharp.Compiler.Driver +module internal FSharp.Compiler.Driver open System open System.Collections.Generic @@ -22,36 +21,40 @@ open System.Text open System.Threading open Internal.Utilities -open Internal.Utilities.Collections -open Internal.Utilities.Filename +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras -open FSharp.Compiler -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Diagnostics - -open FSharp.Compiler.IlxGen +open FSharp.Compiler +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOps -open FSharp.Compiler.CompileOptions +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.CreateILModule +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IlxGen open FSharp.Compiler.InfoReader -open FSharp.Compiler.Lib -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.IO +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.OptimizeInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Syntax +open FSharp.Compiler.StaticLinking open FSharp.Compiler.TcGlobals -open FSharp.Compiler.TypeChecker - -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -#endif - -#nowarn "45" // This method will be made public in the underlying IL because it may implement an interface or override a method +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.XmlDocFileWriter +open FSharp.Compiler.BuildGraph //---------------------------------------------------------------------------- // Reporting - warnings, errors @@ -59,59 +62,62 @@ open FSharp.Compiler.ExtensionTyping /// An error logger that reports errors up to some maximum, notifying the exiter when that maximum is reached [] -type ErrorLoggerUpToMaxErrors(tcConfigB: TcConfigBuilder, exiter: Exiter, nameForDebugging) = +type ErrorLoggerUpToMaxErrors(tcConfigB: TcConfigBuilder, exiter: Exiter, nameForDebugging) = inherit ErrorLogger(nameForDebugging) let mutable errors = 0 /// Called when an error or warning occurs - abstract HandleIssue: tcConfigB: TcConfigBuilder * error: PhasedDiagnostic * isError: bool -> unit + abstract HandleIssue: tcConfigB: TcConfigBuilder * error: PhasedDiagnostic * severity: FSharpDiagnosticSeverity -> unit /// Called when 'too many errors' has occurred abstract HandleTooManyErrors: text: string -> unit override x.ErrorCount = errors - override x.DiagnosticSink(err, isError) = - if isError || ReportWarningAsError tcConfigB.errorSeverityOptions err then - if errors >= tcConfigB.maxErrors then + override x.DiagnosticSink(err, severity) = + if ReportDiagnosticAsError tcConfigB.errorSeverityOptions (err, severity) then + if errors >= tcConfigB.maxErrors then x.HandleTooManyErrors(FSComp.SR.fscTooManyErrors()) exiter.Exit 1 - x.HandleIssue(tcConfigB, err, true) + x.HandleIssue(tcConfigB, err, FSharpDiagnosticSeverity.Error) errors <- errors + 1 - match err.Exception, tcConfigB.simulateException with - | InternalError (msg, _), None + match err.Exception, tcConfigB.simulateException with + | InternalError (msg, _), None | Failure msg, None -> Debug.Assert(false, sprintf "Bug in compiler: %s\n%s" msg (err.Exception.ToString())) | :? KeyNotFoundException, None -> Debug.Assert(false, sprintf "Lookup exception in compiler: %s" (err.Exception.ToString())) | _ -> () - elif ReportWarning tcConfigB.errorSeverityOptions err then - x.HandleIssue(tcConfigB, err, isError) - + elif ReportDiagnosticAsWarning tcConfigB.errorSeverityOptions (err, severity) then + x.HandleIssue(tcConfigB, err, FSharpDiagnosticSeverity.Warning) -/// Create an error logger that counts and prints errors -let ConsoleErrorLoggerUpToMaxErrors (tcConfigB: TcConfigBuilder, exiter : Exiter) = + elif ReportDiagnosticAsInfo tcConfigB.errorSeverityOptions (err, severity) then + x.HandleIssue(tcConfigB, err, severity) + + +/// Create an error logger that counts and prints errors +let ConsoleErrorLoggerUpToMaxErrors (tcConfigB: TcConfigBuilder, exiter : Exiter) = { new ErrorLoggerUpToMaxErrors(tcConfigB, exiter, "ConsoleErrorLoggerUpToMaxErrors") with - - member __.HandleTooManyErrors(text : string) = - DoWithErrorColor false (fun () -> Printf.eprintfn "%s" text) - - member __.HandleIssue(tcConfigB, err, isError) = - DoWithErrorColor isError (fun () -> - let diag = OutputDiagnostic (tcConfigB.implicitIncludeDir, tcConfigB.showFullPaths, tcConfigB.flatErrors, tcConfigB.errorStyle, isError) - writeViaBufferWithEnvironmentNewLines stderr diag err + + member _.HandleTooManyErrors(text : string) = + DoWithDiagnosticColor FSharpDiagnosticSeverity.Warning (fun () -> Printf.eprintfn "%s" text) + + member _.HandleIssue(tcConfigB, err, severity) = + DoWithDiagnosticColor severity (fun () -> + let diag = OutputDiagnostic (tcConfigB.implicitIncludeDir, tcConfigB.showFullPaths, tcConfigB.flatErrors, tcConfigB.errorStyle, severity) + writeViaBuffer stderr diag err stderr.WriteLine()) } :> ErrorLogger /// This error logger delays the messages it receives. At the end, call ForwardDelayedDiagnostics -/// to send the held messages. +/// to send the held messages. type DelayAndForwardErrorLogger(exiter: Exiter, errorLoggerProvider: ErrorLoggerProvider) = inherit CapturingErrorLogger("DelayAndForwardErrorLogger") - member x.ForwardDelayedDiagnostics(tcConfigB: TcConfigBuilder) = + member x.ForwardDelayedDiagnostics(tcConfigB: TcConfigBuilder) = let errorLogger = errorLoggerProvider.CreateErrorLoggerUpToMaxErrors(tcConfigB, exiter) x.CommitDelayedDiagnostics errorLogger @@ -122,131 +128,145 @@ and [] abstract CreateErrorLoggerUpToMaxErrors : tcConfigBuilder : TcConfigBuilder * exiter : Exiter -> ErrorLogger - + /// Part of LegacyHostedCompilerForTesting /// /// Yet another ErrorLogger implementation, capturing the messages but only up to the maxerrors maximum -type InProcErrorLoggerProvider() = +type InProcErrorLoggerProvider() = let errors = ResizeArray() let warnings = ResizeArray() - member __.Provider = + member _.Provider = { new ErrorLoggerProvider() with member log.CreateErrorLoggerUpToMaxErrors(tcConfigBuilder, exiter) = { new ErrorLoggerUpToMaxErrors(tcConfigBuilder, exiter, "InProcCompilerErrorLoggerUpToMaxErrors") with - member this.HandleTooManyErrors text = warnings.Add(Diagnostic.Short(false, text)) + member this.HandleTooManyErrors text = + warnings.Add(Diagnostic.Short(FSharpDiagnosticSeverity.Warning, text)) - member this.HandleIssue(tcConfigBuilder, err, isError) = + member this.HandleIssue(tcConfigBuilder, err, severity) = // 'true' is passed for "suggestNames", since we want to suggest names with fsc.exe runs and this doesn't affect IDE perf - let errs = + let diagnostics = CollectDiagnostic (tcConfigBuilder.implicitIncludeDir, tcConfigBuilder.showFullPaths, - tcConfigBuilder.flatErrors, tcConfigBuilder.errorStyle, isError, err, true) - let container = if isError then errors else warnings - container.AddRange(errs) } + tcConfigBuilder.flatErrors, tcConfigBuilder.errorStyle, severity, err, true) + match severity with + | FSharpDiagnosticSeverity.Error -> + errors.AddRange(diagnostics) + | FSharpDiagnosticSeverity.Warning -> + warnings.AddRange(diagnostics) + | _ -> ()} :> ErrorLogger } - member __.CapturedErrors = errors.ToArray() + member _.CapturedErrors = errors.ToArray() - member __.CapturedWarnings = warnings.ToArray() + member _.CapturedWarnings = warnings.ToArray() /// The default ErrorLogger implementation, reporting messages to the Console up to the maxerrors maximum -type ConsoleLoggerProvider() = +type ConsoleLoggerProvider() = inherit ErrorLoggerProvider() override this.CreateErrorLoggerUpToMaxErrors(tcConfigBuilder, exiter) = ConsoleErrorLoggerUpToMaxErrors(tcConfigBuilder, exiter) -/// Notify the exiter if any error has occurred -let AbortOnError (errorLogger: ErrorLogger, exiter : Exiter) = +/// Notify the exiter if any error has occurred +let AbortOnError (errorLogger: ErrorLogger, exiter : Exiter) = if errorLogger.ErrorCount > 0 then exiter.Exit 1 -//---------------------------------------------------------------------------- -// DisposablesTracker -//---------------------------------------------------------------------------- - -/// Track a set of resources to cleanup -type DisposablesTracker() = - - let items = Stack() - - member this.Register i = items.Push i - - interface IDisposable with - - member this.Dispose() = - let l = List.ofSeq items - items.Clear() - for i in l do - try i.Dispose() with _ -> () - - -let TypeCheck (ctok, tcConfig, tcImports, tcGlobals, errorLogger: ErrorLogger, assemblyName, niceNameGen, tcEnv0, inputs, exiter: Exiter) = - try - if isNil inputs then error(Error(FSComp.SR.fscNoImplementationFiles(), Range.rangeStartup)) +let TypeCheck (ctok, tcConfig, tcImports, tcGlobals, errorLogger: ErrorLogger, assemblyName, niceNameGen, tcEnv0, openDecls0, inputs, exiter: Exiter) = + try + if isNil inputs then error(Error(FSComp.SR.fscNoImplementationFiles(), rangeStartup)) let ccuName = assemblyName - let tcInitialState = GetInitialTcState (rangeStartup, ccuName, tcConfig, tcGlobals, tcImports, niceNameGen, tcEnv0) + let tcInitialState = GetInitialTcState (rangeStartup, ccuName, tcConfig, tcGlobals, tcImports, niceNameGen, tcEnv0, openDecls0) TypeCheckClosedInputSet (ctok, (fun () -> errorLogger.ErrorCount > 0), tcConfig, tcImports, tcGlobals, None, tcInitialState, inputs) - with e -> + with e -> errorRecovery e rangeStartup exiter.Exit 1 /// Check for .fsx and, if present, compute the load closure for of #loaded files. -let AdjustForScriptCompile(ctok, tcConfigB: TcConfigBuilder, commandLineSourceFiles, lexResourceManager) = +/// +/// This is the "script compilation" feature that has always been present in the F# compiler, that allows you to compile scripts +/// and get the load closure and references from them. This applies even if the script is in a project (with 'Compile' action), for example. +/// +/// Any DLL references implied by package references are also retrieved from the script. +/// +/// When script compilation is invoked, the outputs are not necessarily a functioning application - the referenced DLLs are not +/// copied to the output folder, for example (except perhaps FSharp.Core.dll). +/// +/// NOTE: there is similar code in IncrementalBuilder.fs and this code should really be reconciled with that +let AdjustForScriptCompile(tcConfigB: TcConfigBuilder, commandLineSourceFiles, lexResourceManager, dependencyProvider) = let combineFilePath file = try if FileSystem.IsPathRootedShim file then file else Path.Combine(tcConfigB.implicitIncludeDir, file) with _ -> - error (Error(FSComp.SR.pathIsInvalid file, rangeStartup)) - - let commandLineSourceFiles = - commandLineSourceFiles + error (Error(FSComp.SR.pathIsInvalid file, rangeStartup)) + + let commandLineSourceFiles = + commandLineSourceFiles |> List.map combineFilePath - - let mutable allSources = [] - - let tcConfig = TcConfig.Create(tcConfigB, validate=false) - + + // Script compilation is active if the last item being compiled is a script and --noframework has not been specified + let mutable allSources = [] + + let tcConfig = TcConfig.Create(tcConfigB, validate=false) + let AddIfNotPresent(filename: string) = if not(allSources |> List.contains filename) then allSources <- filename :: allSources - + let AppendClosureInformation filename = - if IsScript filename then - let closure = + if IsScript filename then + let closure = LoadClosure.ComputeClosureOfScriptFiles - (ctok, tcConfig, [filename, rangeStartup], CodeContext.Compilation, lexResourceManager=lexResourceManager) + (tcConfig, [filename, rangeStartup], CodeContext.Compilation, + lexResourceManager, dependencyProvider) - // Record the references from the analysis of the script. The full resolutions are recorded as the corresponding #I paths used to resolve them - // are local to the scripts and not added to the tcConfigB (they are added to localized clones of the tcConfigB). + // Record the new references (non-framework) references from the analysis of the script. (The full resolutions are recorded + // as the corresponding #I paths used to resolve them are local to the scripts and not added to the tcConfigB - they are + // added to localized clones of the tcConfigB). let references = closure.References |> List.collect snd - |> List.filter (fun r -> not (Range.equals r.originalReference.Range range0) && not (Range.equals r.originalReference.Range rangeStartup)) + |> List.filter (fun r -> not (equals r.originalReference.Range range0) && not (equals r.originalReference.Range rangeStartup)) references |> List.iter (fun r -> tcConfigB.AddReferencedAssemblyByPath(r.originalReference.Range, r.resolvedPath)) + + // Also record the other declarations from the script. closure.NoWarns |> List.collect (fun (n, ms) -> ms|>List.map(fun m->m, n)) |> List.iter (fun (x,m) -> tcConfigB.TurnWarningOff(x, m)) closure.SourceFiles |> List.map fst |> List.iter AddIfNotPresent closure.AllRootFileDiagnostics |> List.iter diagnosticSink - + + // If there is a target framework for the script then push that as a requirement into the overall compilation and add all the framework references implied + // by the script too. + tcConfigB.SetPrimaryAssembly (if closure.UseDesktopFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) + if tcConfigB.framework then + let references = closure.References |> List.collect snd + references |> List.iter (fun r -> tcConfigB.AddReferencedAssemblyByPath(r.originalReference.Range, r.resolvedPath)) + else AddIfNotPresent filename - + // Find closure of .fsx files. commandLineSourceFiles |> List.iter AppendClosureInformation List.rev allSources -let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, setProcessThreadLocals, lcidFromCodePage, argv) = +let SetProcessThreadLocals tcConfigB = + match tcConfigB.preferredUiLang with + | Some s -> Thread.CurrentThread.CurrentUICulture <- CultureInfo(s) + | None -> () + if tcConfigB.utf8output then + Console.OutputEncoding <- Encoding.UTF8 + +let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, lcidFromCodePage, argv) = let mutable inputFilesRef = [] - let collect name = + let collect name = let lower = String.lowercase name - if List.exists (Filename.checkSuffix lower) [".resx"] then + if List.exists (FileSystemUtils.checkSuffix lower) [".resx"] then error(Error(FSComp.SR.fscResxSourceFileDeprecated name, rangeStartup)) else inputFilesRef <- name :: inputFilesRef @@ -275,10 +295,10 @@ let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, setProcessThreadLocals, | Some _ -> () | None -> tcConfigB.lcid <- lcidFromCodePage - setProcessThreadLocals tcConfigB + SetProcessThreadLocals tcConfigB (* step - get dll references *) - let dllFiles, sourceFiles = inputFiles |> List.map(fun p -> trimQuotes p) |> List.partition Filename.isDll + let dllFiles, sourceFiles = inputFiles |> List.map(fun p -> FileSystemUtils.trimQuotes p) |> List.partition FileSystemUtils.isDll match dllFiles with | [] -> () | h :: _ -> errorR (Error(FSComp.SR.fscReferenceOnCommandLine h, rangeStartup)) @@ -286,1387 +306,57 @@ let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, setProcessThreadLocals, dllFiles |> List.iter (fun f->tcConfigB.AddReferencedAssemblyByPath(rangeStartup, f)) sourceFiles +/// Write a .fsi file for the --sig option module InterfaceFileWriter = + let WriteInterfaceFile (tcGlobals, tcConfig: TcConfig, infoReader, declaredImpls: TypedImplFile list) = + // there are two modes here: + // * write one unified sig file to a given path, or + // * write individual sig files to paths matching their impl files + let denv = DisplayEnv.InitialForSigFileGeneration tcGlobals + let denv = { denv with shrinkOverloads = false; printVerboseSignatures = true } + + let writeToFile os (TImplFile (_, _, mexpr, _, _, _)) = + writeViaBuffer os (fun os s -> Printf.bprintf os "%s\n\n" s) + (NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr |> Display.squashTo 80 |> LayoutRender.showL) + + let writeHeader filePath os = + if filePath <> "" && not (List.exists (FileSystemUtils.checkSuffix filePath) FSharpLightSyntaxFileSuffixes) then + fprintfn os "#light" + fprintfn os "" + + let writeAllToSameFile declaredImpls = + /// Use a UTF-8 Encoding with no Byte Order Mark + let os = + if tcConfig.printSignatureFile = "" then + Console.Out + else + FileSystem.OpenFileForWriteShim(tcConfig.printSignatureFile, FileMode.Create).GetWriter() - let BuildInitialDisplayEnvForSigFileGeneration tcGlobals = - let denv = DisplayEnv.Empty tcGlobals - let denv = - { denv with - showImperativeTyparAnnotations=true - showHiddenMembers=true - showObsoleteMembers=true - showAttributes=true } - denv.SetOpenPaths - [ FSharpLib.RootPath - FSharpLib.CorePath - FSharpLib.CollectionsPath - FSharpLib.ControlPath - (IL.splitNamespace FSharpLib.ExtraTopLevelOperatorsName) ] - - let WriteInterfaceFile (tcGlobals, tcConfig: TcConfig, infoReader, declaredImpls) = - - /// Use a UTF-8 Encoding with no Byte Order Mark - let os = - if tcConfig.printSignatureFile="" then Console.Out - else (File.CreateText tcConfig.printSignatureFile :> TextWriter) - - if tcConfig.printSignatureFile <> "" && not (List.exists (Filename.checkSuffix tcConfig.printSignatureFile) FSharpLightSyntaxFileSuffixes) then - fprintfn os "#light" - fprintfn os "" - - for (TImplFile (_, _, mexpr, _, _, _)) in declaredImpls do - let denv = BuildInitialDisplayEnvForSigFileGeneration tcGlobals - writeViaBufferWithEnvironmentNewLines os (fun os s -> Printf.bprintf os "%s\n\n" s) - (NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr |> Layout.squashTo 80 |> Layout.showL) - - if tcConfig.printSignatureFile <> "" then os.Dispose() - -module XmlDocWriter = - - let getDoc xmlDoc = - match XmlDoc.Process xmlDoc with - | XmlDoc [| |] -> "" - | XmlDoc strs -> strs |> Array.toList |> String.concat Environment.NewLine - - let hasDoc xmlDoc = - // No need to process the xml doc - just need to know if there's anything there - match xmlDoc with - | XmlDoc [| |] -> false - | _ -> true - - let computeXmlDocSigs (tcGlobals, generatedCcu: CcuThunk) = - (* the xmlDocSigOf* functions encode type into string to be used in "id" *) - let g = tcGlobals - let doValSig ptext (v: Val) = if (hasDoc v.XmlDoc) then v.XmlDocSig <- XmlDocSigOfVal g ptext v - let doTyconSig ptext (tc: Tycon) = - if (hasDoc tc.XmlDoc) then tc.XmlDocSig <- XmlDocSigOfTycon [ptext; tc.CompiledName] - for vref in tc.MembersOfFSharpTyconSorted do - doValSig ptext vref.Deref - for uc in tc.UnionCasesArray do - if (hasDoc uc.XmlDoc) then uc.XmlDocSig <- XmlDocSigOfUnionCase [ptext; tc.CompiledName; uc.Id.idText] - for rf in tc.AllFieldsArray do - if (hasDoc rf.XmlDoc) then - rf.XmlDocSig <- - if tc.IsRecordTycon && (not rf.IsStatic) then - // represents a record field, which is exposed as a property - XmlDocSigOfProperty [ptext; tc.CompiledName; rf.Id.idText] - else - XmlDocSigOfField [ptext; tc.CompiledName; rf.Id.idText] - - let doModuleMemberSig path (m: ModuleOrNamespace) = m.XmlDocSig <- XmlDocSigOfSubModul [path] - (* moduleSpec - recurses *) - let rec doModuleSig path (mspec: ModuleOrNamespace) = - let mtype = mspec.ModuleOrNamespaceType - let path = - (* skip the first item in the path which is the assembly name *) - match path with - | None -> Some "" - | Some "" -> Some mspec.LogicalName - | Some p -> Some (p+"."+mspec.LogicalName) - let ptext = match path with None -> "" | Some t -> t - if mspec.IsModule then doModuleMemberSig ptext mspec - let vals = - mtype.AllValsAndMembers - |> Seq.toList - |> List.filter (fun x -> not x.IsCompilerGenerated) - |> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember) - List.iter (doModuleSig path) mtype.ModuleAndNamespaceDefinitions - List.iter (doTyconSig ptext) mtype.ExceptionDefinitions - List.iter (doValSig ptext) vals - List.iter (doTyconSig ptext) mtype.TypeDefinitions - - doModuleSig None generatedCcu.Contents - - let writeXmlDoc (assemblyName, generatedCcu: CcuThunk, xmlfile) = - if not (Filename.hasSuffixCaseInsensitive "xml" xmlfile ) then - error(Error(FSComp.SR.docfileNoXmlSuffix(), Range.rangeStartup)) - (* the xmlDocSigOf* functions encode type into string to be used in "id" *) - let mutable members = [] - let addMember id xmlDoc = - if hasDoc xmlDoc then - let doc = getDoc xmlDoc - members <- (id, doc) :: members - let doVal (v: Val) = addMember v.XmlDocSig v.XmlDoc - let doUnionCase (uc: UnionCase) = addMember uc.XmlDocSig uc.XmlDoc - let doField (rf: RecdField) = addMember rf.XmlDocSig rf.XmlDoc - let doTycon (tc: Tycon) = - addMember tc.XmlDocSig tc.XmlDoc - for vref in tc.MembersOfFSharpTyconSorted do - doVal vref.Deref - for uc in tc.UnionCasesArray do - doUnionCase uc - for rf in tc.AllFieldsArray do - doField rf - - let modulMember (m: ModuleOrNamespace) = addMember m.XmlDocSig m.XmlDoc - - (* moduleSpec - recurses *) - let rec doModule (mspec: ModuleOrNamespace) = - let mtype = mspec.ModuleOrNamespaceType - if mspec.IsModule then modulMember mspec - let vals = - mtype.AllValsAndMembers - |> Seq.toList - |> List.filter (fun x -> not x.IsCompilerGenerated) - |> List.filter (fun x -> x.MemberInfo.IsNone || x.IsExtensionMember) - List.iter doModule mtype.ModuleAndNamespaceDefinitions - List.iter doTycon mtype.ExceptionDefinitions - List.iter doVal vals - List.iter doTycon mtype.TypeDefinitions - - doModule generatedCcu.Contents - - use os = File.CreateText xmlfile - - fprintfn os ("") - fprintfn os ("") - fprintfn os ("%s") assemblyName - fprintfn os ("") - members |> List.iter (fun (id, doc) -> - fprintfn os "" id - fprintfn os "%s" doc - fprintfn os "") - fprintfn os "" - fprintfn os "" - - -let DefaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(FSharpEnvironment.tryCurrentDomain()).Value - -let GenerateInterfaceData(tcConfig: TcConfig) = - not tcConfig.standalone && not tcConfig.noSignatureData - -let EncodeInterfaceData(tcConfig: TcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) = - if GenerateInterfaceData tcConfig then - let resource = WriteSignatureData (tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, isIncrementalBuild) - // The resource gets written to a file for FSharp.Core - let useDataFiles = (tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib) && not isIncrementalBuild - if useDataFiles then - let sigDataFileName = (Filename.chopExtension outfile)+".sigdata" - let bytes = resource.GetBytes() - use fileStream = File.Create(sigDataFileName, bytes.Length) - bytes.CopyTo fileStream - let resources = - [ resource ] - let sigAttr = mkSignatureDataVersionAttr tcGlobals (IL.parseILVersion Internal.Utilities.FSharpEnvironment.FSharpBinaryMetadataFormatRevision) - [sigAttr], resources - else - [], [] - -let GenerateOptimizationData tcConfig = - GenerateInterfaceData tcConfig - -let EncodeOptimizationData(tcGlobals, tcConfig: TcConfig, outfile, exportRemapping, data, isIncrementalBuild) = - if GenerateOptimizationData tcConfig then - let data = map2Of2 (Optimizer.RemapOptimizationInfo tcGlobals exportRemapping) data - // As with the sigdata file, the optdata gets written to a file for FSharp.Core - let useDataFiles = (tcConfig.useOptimizationDataFile || tcGlobals.compilingFslib) && not isIncrementalBuild - if useDataFiles then - let ccu, modulInfo = data - let bytes = TastPickle.pickleObjWithDanglingCcus isIncrementalBuild outfile tcGlobals ccu Optimizer.p_CcuOptimizationInfo modulInfo - let optDataFileName = (Filename.chopExtension outfile)+".optdata" - File.WriteAllBytes(optDataFileName, bytes) - let (ccu, optData) = - if tcConfig.onlyEssentialOptimizationData then - map2Of2 Optimizer.AbstractOptimizationInfoToEssentials data - else - data - [ WriteOptimizationData (tcGlobals, outfile, isIncrementalBuild, ccu, optData) ] - else - [ ] - -//---------------------------------------------------------------------------- -// .res file format, for encoding the assembly version attribute. -//-------------------------------------------------------------------------- - -// Helpers for generating binary blobs -module BinaryGenerationUtilities = - // Little-endian encoding of int32 - let b0 n = byte (n &&& 0xFF) - let b1 n = byte ((n >>> 8) &&& 0xFF) - let b2 n = byte ((n >>> 16) &&& 0xFF) - let b3 n = byte ((n >>> 24) &&& 0xFF) - - let i16 (i: int32) = [| b0 i; b1 i |] - let i32 (i: int32) = [| b0 i; b1 i; b2 i; b3 i |] - - // Emit the bytes and pad to a 32-bit alignment - let Padded initialAlignment (v: byte[]) = - [| yield! v - for _ in 1..(4 - (initialAlignment + v.Length) % 4) % 4 do - yield 0x0uy |] - -// Generate nodes in a .res file format. These are then linked by Abstract IL using linkNativeResources -module ResFileFormat = - open BinaryGenerationUtilities - - let ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, data: byte[]) = - [| yield! i32 data.Length // DWORD ResHdr.dwDataSize - yield! i32 0x00000020 // dwHeaderSize - yield! i32 ((dwTypeID <<< 16) ||| 0x0000FFFF) // dwTypeID, sizeof(DWORD) - yield! i32 ((dwNameID <<< 16) ||| 0x0000FFFF) // dwNameID, sizeof(DWORD) - yield! i32 0x00000000 // DWORD dwDataVersion - yield! i16 wMemFlags // WORD wMemFlags - yield! i16 wLangID // WORD wLangID - yield! i32 0x00000000 // DWORD dwVersion - yield! i32 0x00000000 // DWORD dwCharacteristics - yield! Padded 0 data |] - - let ResFileHeader() = ResFileNode(0x0, 0x0, 0x0, 0x0, [| |]) - -// Generate the VS_VERSION_INFO structure held in a Win32 Version Resource in a PE file -// -// Web reference: http://www.piclist.com/tecHREF/os/win/api/win32/struc/src/str24_5.htm -module VersionResourceFormat = - open BinaryGenerationUtilities - - let VersionInfoNode(data: byte[]) = - [| yield! i16 (data.Length + 2) // wLength : int16 // Specifies the length, in bytes, of the VS_VERSION_INFO structure. - yield! data |] - - let VersionInfoElement(wType, szKey, valueOpt: byte[] option, children: byte[][], isString) = - // for String structs, wValueLength represents the word count, not the byte count - let wValueLength = (match valueOpt with None -> 0 | Some value -> (if isString then value.Length / 2 else value.Length)) - VersionInfoNode - [| yield! i16 wValueLength // wValueLength: int16. Specifies the length, in words, of the Value member. - yield! i16 wType // wType : int16 Specifies the type of data in the version resource. - yield! Padded 2 szKey - match valueOpt with - | None -> yield! [] - | Some value -> yield! Padded 0 value - for child in children do - yield! child |] - - let Version(version: ILVersionInfo) = - [| // DWORD dwFileVersionMS - // Specifies the most significant 32 bits of the file's binary - // version number. This member is used with dwFileVersionLS to form a 64-bit value used - // for numeric comparisons. - yield! i32 (int32 version.Major <<< 16 ||| int32 version.Minor) - - // DWORD dwFileVersionLS - // Specifies the least significant 32 bits of the file's binary - // version number. This member is used with dwFileVersionMS to form a 64-bit value used - // for numeric comparisons. - yield! i32 (int32 version.Build <<< 16 ||| int32 version.Revision) - |] - - let String(string, value) = - let wType = 0x1 // Specifies the type of data in the version resource. - let szKey = Bytes.stringAsUnicodeNullTerminated string - VersionInfoElement(wType, szKey, Some (Bytes.stringAsUnicodeNullTerminated value), [| |], true) - - let StringTable(language, strings) = - let wType = 0x1 // Specifies the type of data in the version resource. - let szKey = Bytes.stringAsUnicodeNullTerminated language - // Specifies an 8-digit hexadecimal number stored as a Unicode string. - - let children = - [| for string in strings do - yield String string |] - VersionInfoElement(wType, szKey, None, children, false) - - let StringFileInfo(stringTables: #seq >) = - let wType = 0x1 // Specifies the type of data in the version resource. - let szKey = Bytes.stringAsUnicodeNullTerminated "StringFileInfo" // Contains the Unicode string StringFileInfo - // Contains an array of one or more StringTable structures. - let children = - [| for stringTable in stringTables do - yield StringTable stringTable |] - VersionInfoElement(wType, szKey, None, children, false) - - let VarFileInfo(vars: #seq) = - let wType = 0x1 // Specifies the type of data in the version resource. - let szKey = Bytes.stringAsUnicodeNullTerminated "VarFileInfo" // Contains the Unicode string StringFileInfo - // Contains an array of one or more StringTable structures. - let children = - [| for (lang, codePage) in vars do - let szKey = Bytes.stringAsUnicodeNullTerminated "Translation" - yield VersionInfoElement(0x0, szKey, Some([| yield! i16 lang - yield! i16 codePage |]), [| |], false) |] - VersionInfoElement(wType, szKey, None, children, false) - - let VS_FIXEDFILEINFO(fileVersion: ILVersionInfo, - productVersion: ILVersionInfo, - dwFileFlagsMask, - dwFileFlags, dwFileOS, - dwFileType, dwFileSubtype, - lwFileDate: int64) = - let dwStrucVersion = 0x00010000 - [| // DWORD dwSignature // Contains the value 0xFEEFO4BD. - yield! i32 0xFEEF04BD - - // DWORD dwStrucVersion // Specifies the binary version number of this structure. - yield! i32 dwStrucVersion - - // DWORD dwFileVersionMS, dwFileVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. - yield! Version fileVersion - - // DWORD dwProductVersionMS, dwProductVersionLS // Specifies the most/least significant 32 bits of the file's binary version number. - yield! Version productVersion - - // DWORD dwFileFlagsMask // Contains a bitmask that specifies the valid bits in dwFileFlags. - yield! i32 dwFileFlagsMask - - // DWORD dwFileFlags // Contains a bitmask that specifies the Boolean attributes of the file. - yield! i32 dwFileFlags - // VS_FF_DEBUG 0x1L The file contains debugging information or is compiled with debugging features enabled. - // VS_FF_INFOINFERRED The file's version structure was created dynamically; therefore, some of the members - // in this structure may be empty or incorrect. This flag should never be set in a file's - // VS_VERSION_INFO data. - // VS_FF_PATCHED The file has been modified and is not identical to the original shipping file of - // the same version number. - // VS_FF_PRERELEASE The file is a development version, not a commercially released product. - // VS_FF_PRIVATEBUILD The file was not built using standard release procedures. If this flag is - // set, the StringFileInfo structure should contain a PrivateBuild entry. - // VS_FF_SPECIALBUILD The file was built by the original company using standard release procedures - // but is a variation of the normal file of the same version number. If this - // flag is set, the StringFileInfo structure should contain a SpecialBuild entry. - - //Specifies the operating system for which this file was designed. This member can be one of the following values: Flag - yield! i32 dwFileOS - //VOS_DOS 0x0001L The file was designed for MS-DOS. - //VOS_NT 0x0004L The file was designed for Windows NT. - //VOS__WINDOWS16 The file was designed for 16-bit Windows. - //VOS__WINDOWS32 The file was designed for the Win32 API. - //VOS_OS216 0x00020000L The file was designed for 16-bit OS/2. - //VOS_OS232 0x00030000L The file was designed for 32-bit OS/2. - //VOS__PM16 The file was designed for 16-bit Presentation Manager. - //VOS__PM32 The file was designed for 32-bit Presentation Manager. - //VOS_UNKNOWN The operating system for which the file was designed is unknown to Windows. - - // Specifies the general type of file. This member can be one of the following values: - yield! i32 dwFileType - - //VFT_UNKNOWN The file type is unknown to Windows. - //VFT_APP The file contains an application. - //VFT_DLL The file contains a dynamic-link library (DLL). - //VFT_DRV The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver. - //VFT_FONT The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file. - //VFT_VXD The file contains a virtual device. - //VFT_STATIC_LIB The file contains a static-link library. - - // Specifies the function of the file. The possible values depend on the value of - // dwFileType. For all values of dwFileType not described in the following list, - // dwFileSubtype is zero. If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values: - yield! i32 dwFileSubtype - //VFT2_UNKNOWN The driver type is unknown by Windows. - //VFT2_DRV_COMM The file contains a communications driver. - //VFT2_DRV_PRINTER The file contains a printer driver. - //VFT2_DRV_KEYBOARD The file contains a keyboard driver. - //VFT2_DRV_LANGUAGE The file contains a language driver. - //VFT2_DRV_DISPLAY The file contains a display driver. - //VFT2_DRV_MOUSE The file contains a mouse driver. - //VFT2_DRV_NETWORK The file contains a network driver. - //VFT2_DRV_SYSTEM The file contains a system driver. - //VFT2_DRV_INSTALLABLE The file contains an installable driver. - //VFT2_DRV_SOUND The file contains a sound driver. - // - //If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values: - // - //VFT2_UNKNOWN The font type is unknown by Windows. - //VFT2_FONT_RASTER The file contains a raster font. - //VFT2_FONT_VECTOR The file contains a vector font. - //VFT2_FONT_TRUETYPE The file contains a TrueType font. - // - //If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block. - - // Specifies the most significant 32 bits of the file's 64-bit binary creation date and time stamp. - yield! i32 (int32 (lwFileDate >>> 32)) - - //Specifies the least significant 32 bits of the file's 64-bit binary creation date and time stamp. - yield! i32 (int32 lwFileDate) - |] - - - let VS_VERSION_INFO(fixedFileInfo, stringFileInfo, varFileInfo) = - let wType = 0x0 - let szKey = Bytes.stringAsUnicodeNullTerminated "VS_VERSION_INFO" // Contains the Unicode string VS_VERSION_INFO - let value = VS_FIXEDFILEINFO (fixedFileInfo) - let children = - [| yield StringFileInfo stringFileInfo - yield VarFileInfo varFileInfo - |] - VersionInfoElement(wType, szKey, Some value, children, false) - - let VS_VERSION_INFO_RESOURCE data = - let dwTypeID = 0x0010 - let dwNameID = 0x0001 - let wMemFlags = 0x0030 // REVIEW: HARDWIRED TO ENGLISH - let wLangID = 0x0 - ResFileFormat.ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, VS_VERSION_INFO data) - -module ManifestResourceFormat = - - let VS_MANIFEST_RESOURCE(data, isLibrary) = - let dwTypeID = 0x0018 - let dwNameID = if isLibrary then 0x2 else 0x1 - let wMemFlags = 0x0 - let wLangID = 0x0 - ResFileFormat.ResFileNode(dwTypeID, dwNameID, wMemFlags, wLangID, data) - -//---------------------------------------------------------------------------- -// Helpers for finding attributes -//---------------------------------------------------------------------------- - -module AttributeHelpers = + writeHeader tcConfig.printSignatureFile os - /// Try to find an attribute that takes a string argument - let TryFindStringAttribute (g: TcGlobals) attrib attribs = - match g.TryFindSysAttrib attrib with - | None -> None - | Some attribRef -> - match TryFindFSharpAttribute g attribRef attribs with - | Some (Attrib(_, _, [ AttribStringArg s ], _, _, _, _)) -> Some (s) - | _ -> None - - let TryFindIntAttribute (g: TcGlobals) attrib attribs = - match g.TryFindSysAttrib attrib with - | None -> None - | Some attribRef -> - match TryFindFSharpAttribute g attribRef attribs with - | Some (Attrib(_, _, [ AttribInt32Arg i ], _, _, _, _)) -> Some (i) - | _ -> None - - let TryFindBoolAttribute (g: TcGlobals) attrib attribs = - match g.TryFindSysAttrib attrib with - | None -> None - | Some attribRef -> - match TryFindFSharpAttribute g attribRef attribs with - | Some (Attrib(_, _, [ AttribBoolArg p ], _, _, _, _)) -> Some (p) - | _ -> None + for impl in declaredImpls do + writeToFile os impl - let (|ILVersion|_|) (versionString: string) = - try Some (IL.parseILVersion versionString) - with e -> - None + if tcConfig.printSignatureFile <> "" then os.Dispose() - // Try to find an AssemblyVersion attribute - let TryFindVersionAttribute g attrib attribName attribs deterministic = - match TryFindStringAttribute g attrib attribs with - | Some versionString -> - if deterministic && versionString.Contains("*") then - errorR(Error(FSComp.SR.fscAssemblyWildcardAndDeterminism(attribName, versionString), Range.rangeStartup)) - try Some (IL.parseILVersion versionString) - with e -> - // Warning will be reported by TypeChecker.fs - None - | _ -> None - -//---------------------------------------------------------------------------- -// Building the contents of the finalized IL module -//---------------------------------------------------------------------------- - -module MainModuleBuilder = - - let injectedCompatTypes = - set [ "System.Tuple`1" - "System.Tuple`2" - "System.Tuple`3" - "System.Tuple`4" - "System.Tuple`5" - "System.Tuple`6" - "System.Tuple`7" - "System.Tuple`8" - "System.ITuple" - "System.Tuple" - "System.Collections.IStructuralComparable" - "System.Collections.IStructuralEquatable" ] - - let typesForwardedToMscorlib = - set [ "System.AggregateException" - "System.Threading.CancellationTokenRegistration" - "System.Threading.CancellationToken" - "System.Threading.CancellationTokenSource" - "System.Lazy`1" - "System.IObservable`1" - "System.IObserver`1" ] - - let typesForwardedToSystemNumerics = - set [ "System.Numerics.BigInteger" ] - - let createMscorlibExportList (tcGlobals: TcGlobals) = - // We want to write forwarders out for all injected types except for System.ITuple, which is internal - // Forwarding System.ITuple will cause FxCop failures on 4.0 - Set.union (Set.filter (fun t -> t <> "System.ITuple") injectedCompatTypes) typesForwardedToMscorlib |> - Seq.map (fun t -> mkTypeForwarder (tcGlobals.ilg.primaryAssemblyScopeRef) t (mkILNestedExportedTypes List.empty) (mkILCustomAttrs List.empty) ILTypeDefAccess.Public ) - |> Seq.toList - - let createSystemNumericsExportList (tcConfig: TcConfig) (tcImports: TcImports) = - let refNumericsDllName = - if (tcConfig.primaryAssembly.Name = "mscorlib") then "System.Numerics" - else "System.Runtime.Numerics" - let numericsAssemblyRef = - match tcImports.GetImportedAssemblies() |> List.tryFind(fun a -> a.FSharpViewOfMetadata.AssemblyName = refNumericsDllName) with - | Some asm -> - match asm.ILScopeRef with - | ILScopeRef.Assembly aref -> Some aref - | _ -> None - | None -> None - match numericsAssemblyRef with - | Some aref -> - let systemNumericsAssemblyRef = ILAssemblyRef.Create(refNumericsDllName, aref.Hash, aref.PublicKey, aref.Retargetable, aref.Version, aref.Locale) - typesForwardedToSystemNumerics |> - Seq.map (fun t -> - { ScopeRef = ILScopeRef.Assembly systemNumericsAssemblyRef - Name = t - Attributes = enum(0x00200000) ||| TypeAttributes.Public - Nested = mkILNestedExportedTypes [] - CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx }) |> - Seq.toList - | None -> [] - - let fileVersion findStringAttr (assemblyVersion: ILVersionInfo) = - let attrName = "System.Reflection.AssemblyFileVersionAttribute" - match findStringAttr attrName with - | None -> assemblyVersion - | Some (AttributeHelpers.ILVersion v) -> v - | Some _ -> - // Warning will be reported by TypeChecker.fs - assemblyVersion - - let productVersion findStringAttr (fileVersion: ILVersionInfo) = - let attrName = "System.Reflection.AssemblyInformationalVersionAttribute" - let toDotted (version: ILVersionInfo) = sprintf "%d.%d.%d.%d" version.Major version.Minor version.Build version.Revision - match findStringAttr attrName with - | None | Some "" -> fileVersion |> toDotted - | Some (AttributeHelpers.ILVersion v) -> v |> toDotted - | Some v -> - // Warning will be reported by TypeChecker.fs - v - - let productVersionToILVersionInfo (version: string) : ILVersionInfo = - let parseOrZero v = match System.UInt16.TryParse v with (true, i) -> i | (false, _) -> 0us - let validParts = - version.Split('.') - |> Seq.map parseOrZero - |> Seq.takeWhile ((<>) 0us) - |> Seq.toList - match validParts @ [0us; 0us; 0us; 0us] with - | major :: minor :: build :: rev :: _ -> ILVersionInfo(major, minor, build, rev) - | x -> failwithf "error converting product version '%s' to binary, tried '%A' " version x - - - let CreateMainModule - (ctok, tcConfig: TcConfig, tcGlobals, tcImports: TcImports, - pdbfile, assemblyName, outfile, topAttrs, - (iattrs, intfDataResources), optDataResources, - codegenResults, assemVerFromAttrib, metadataVersion, secDecls) = - - RequireCompilationThread ctok - let ilTypeDefs = - //let topTypeDef = mkILTypeDefForGlobalFunctions tcGlobals.ilg (mkILMethods [], emptyILFields) - mkILTypeDefs codegenResults.ilTypeDefs - - let mainModule = - let hashAlg = AttributeHelpers.TryFindIntAttribute tcGlobals "System.Reflection.AssemblyAlgorithmIdAttribute" topAttrs.assemblyAttrs - let locale = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyCultureAttribute" topAttrs.assemblyAttrs - let flags = match AttributeHelpers.TryFindIntAttribute tcGlobals "System.Reflection.AssemblyFlagsAttribute" topAttrs.assemblyAttrs with | Some f -> f | _ -> 0x0 - - // You're only allowed to set a locale if the assembly is a library - if (locale <> None && locale.Value <> "") && tcConfig.target <> CompilerTarget.Dll then - error(Error(FSComp.SR.fscAssemblyCultureAttributeError(), rangeCmdArgs)) - - // Add the type forwarders to any .NET DLL post-.NET-2.0, to give binary compatibility - let exportedTypesList = - if tcConfig.compilingFslib then - List.append (createMscorlibExportList tcGlobals) (createSystemNumericsExportList tcConfig tcImports) - else - [] - - let ilModuleName = GetGeneratedILModuleName tcConfig.target assemblyName - let isDLL = (tcConfig.target = CompilerTarget.Dll || tcConfig.target = CompilerTarget.Module) - mkILSimpleModule assemblyName ilModuleName isDLL tcConfig.subsystemVersion tcConfig.useHighEntropyVA ilTypeDefs hashAlg locale flags (mkILExportedTypes exportedTypesList) metadataVersion - - let disableJitOptimizations = not (tcConfig.optSettings.jitOpt()) - - let tcVersion = tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) - - let reflectedDefinitionAttrs, reflectedDefinitionResources = - codegenResults.quotationResourceInfo - |> List.map (fun (referencedTypeDefs, reflectedDefinitionBytes) -> - let reflectedDefinitionResourceName = QuotationPickler.SerializedReflectedDefinitionsResourceNameBase+"-"+assemblyName+"-"+string(newUnique())+"-"+string(hash reflectedDefinitionBytes) - let reflectedDefinitionAttrs = - match QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat tcGlobals with - | QuotationTranslator.QuotationSerializationFormat.FSharp_40_Plus -> - [ mkCompilationMappingAttrForQuotationResource tcGlobals (reflectedDefinitionResourceName, referencedTypeDefs) ] - | QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus -> - [ ] - let reflectedDefinitionResource = - { Name=reflectedDefinitionResourceName - Location = ILResourceLocation.Local(ByteMemory.FromArray(reflectedDefinitionBytes).AsReadOnly()) - Access= ILResourceAccess.Public - CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx } - reflectedDefinitionAttrs, reflectedDefinitionResource) - |> List.unzip - |> (fun (attrs, resource) -> List.concat attrs, resource) - - let manifestAttrs = - mkILCustomAttrs - [ if not tcConfig.internConstantStrings then - yield mkILCustomAttribute tcGlobals.ilg - (tcGlobals.FindSysILTypeRef "System.Runtime.CompilerServices.CompilationRelaxationsAttribute", - [tcGlobals.ilg.typ_Int32], [ILAttribElem.Int32( 8)], []) - yield! iattrs - yield! codegenResults.ilAssemAttrs - if Option.isSome pdbfile then - yield (tcGlobals.mkDebuggableAttributeV2 (tcConfig.jitTracking, tcConfig.ignoreSymbolStoreSequencePoints, disableJitOptimizations, false (* enableEnC *) )) - yield! reflectedDefinitionAttrs ] - - // Make the manifest of the assembly - let manifest = - if tcConfig.target = CompilerTarget.Module then None else - let man = mainModule.ManifestOfAssembly - let ver = - match assemVerFromAttrib with - | None -> tcVersion - | Some v -> v - Some { man with Version= Some ver - CustomAttrsStored = storeILCustomAttrs manifestAttrs - DisableJitOptimizations=disableJitOptimizations - JitTracking= tcConfig.jitTracking - IgnoreSymbolStoreSequencePoints = tcConfig.ignoreSymbolStoreSequencePoints - SecurityDeclsStored=storeILSecurityDecls secDecls } - - let resources = - mkILResources - [ for file in tcConfig.embedResources do - let name, bytes, pub = - let file, name, pub = TcConfigBuilder.SplitCommandLineResourceInfo file - let file = tcConfig.ResolveSourceFile(rangeStartup, file, tcConfig.implicitIncludeDir) - let bytes = FileSystem.ReadAllBytesShim file - name, bytes, pub - yield { Name=name - Location=ILResourceLocation.Local(ByteMemory.FromArray(bytes).AsReadOnly()) - Access=pub - CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx } - - yield! reflectedDefinitionResources - yield! intfDataResources - yield! optDataResources - for ri in tcConfig.linkResources do - let file, name, pub = TcConfigBuilder.SplitCommandLineResourceInfo ri - yield { Name=name - Location=ILResourceLocation.File(ILModuleRef.Create(name=file, hasMetadata=false, hash=Some (sha1HashBytes (FileSystem.ReadAllBytesShim file))), 0) - Access=pub - CustomAttrsStored=storeILCustomAttrs emptyILCustomAttrs - MetadataIndex = NoMetadataIdx } ] - - let assemblyVersion = - match tcConfig.version with - | VersionNone -> assemVerFromAttrib - | _ -> Some tcVersion - - let findAttribute name = - AttributeHelpers.TryFindStringAttribute tcGlobals name topAttrs.assemblyAttrs - - - //NOTE: the culture string can be turned into a number using this: - // sprintf "%04x" (CultureInfo.GetCultureInfo("en").KeyboardLayoutId ) - let assemblyVersionResources findAttr assemblyVersion = - match assemblyVersion with - | None -> [] - | Some assemblyVersion -> - let FindAttribute key attrib = - match findAttr attrib with - | Some text -> [(key, text)] - | _ -> [] - - let fileVersionInfo = fileVersion findAttr assemblyVersion - - let productVersionString = productVersion findAttr fileVersionInfo - - let stringFileInfo = - // 000004b0: - // Specifies an 8-digit hexadecimal number stored as a Unicode string. The - // four most significant digits represent the language identifier. The four least - // significant digits represent the code page for which the data is formatted. - // Each Microsoft Standard Language identifier contains two parts: the low-order 10 bits - // specify the major language, and the high-order 6 bits specify the sublanguage. - // For a table of valid identifiers see Language Identifiers. // - // see e.g. http://msdn.microsoft.com/en-us/library/aa912040.aspx 0000 is neutral and 04b0(hex)=1252(dec) is the code page. - [ ("000004b0", [ yield ("Assembly Version", (sprintf "%d.%d.%d.%d" assemblyVersion.Major assemblyVersion.Minor assemblyVersion.Build assemblyVersion.Revision)) - yield ("FileVersion", (sprintf "%d.%d.%d.%d" fileVersionInfo.Major fileVersionInfo.Minor fileVersionInfo.Build fileVersionInfo.Revision)) - yield ("ProductVersion", productVersionString) - match tcConfig.outputFile with - | Some f -> yield ("OriginalFilename", Path.GetFileName f) - | None -> () - yield! FindAttribute "Comments" "System.Reflection.AssemblyDescriptionAttribute" - yield! FindAttribute "FileDescription" "System.Reflection.AssemblyTitleAttribute" - yield! FindAttribute "ProductName" "System.Reflection.AssemblyProductAttribute" - yield! FindAttribute "CompanyName" "System.Reflection.AssemblyCompanyAttribute" - yield! FindAttribute "LegalCopyright" "System.Reflection.AssemblyCopyrightAttribute" - yield! FindAttribute "LegalTrademarks" "System.Reflection.AssemblyTrademarkAttribute" ]) ] - - // These entries listed in the MSDN documentation as "standard" string entries are not yet settable - - // InternalName: - // The Value member identifies the file's internal name, if one exists. For example, this - // string could contain the module name for Windows dynamic-link libraries (DLLs), a virtual - // device name for Windows virtual devices, or a device name for MS-DOS device drivers. - // OriginalFilename: - // The Value member identifies the original name of the file, not including a path. This - // enables an application to determine whether a file has been renamed by a user. This name - // may not be MS-DOS 8.3-format if the file is specific to a non-FAT file system. - // PrivateBuild: - // The Value member describes by whom, where, and why this private version of the - // file was built. This string should only be present if the VS_FF_PRIVATEBUILD flag - // is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, - // Value could be 'Built by OSCAR on \OSCAR2'. - // SpecialBuild: - // The Value member describes how this version of the file differs from the normal version. - // This entry should only be present if the VS_FF_SPECIALBUILD flag is set in the dwFileFlags - // member of the VS_FIXEDFILEINFO structure. For example, Value could be 'Private build - // for Olivetti solving mouse problems on M250 and M250E computers'. - - // "If you use the Var structure to list the languages your application - // or DLL supports instead of using multiple version resources, - // use the Value member to contain an array of DWORD values indicating the - // language and code page combinations supported by this file. The - // low-order word of each DWORD must contain a Microsoft language identifier, - // and the high-order word must contain the IBM code page number. - // Either high-order or low-order word can be zero, indicating that - // the file is language or code page independent. If the Var structure is - // omitted, the file will be interpreted as both language and code page independent. " - let varFileInfo = [ (0x0, 0x04b0) ] - - let fixedFileInfo = - let dwFileFlagsMask = 0x3f // REVIEW: HARDWIRED - let dwFileFlags = 0x00 // REVIEW: HARDWIRED - let dwFileOS = 0x04 // REVIEW: HARDWIRED - let dwFileType = 0x01 // REVIEW: HARDWIRED - let dwFileSubtype = 0x00 // REVIEW: HARDWIRED - let lwFileDate = 0x00L // REVIEW: HARDWIRED - (fileVersionInfo, productVersionString |> productVersionToILVersionInfo, dwFileFlagsMask, dwFileFlags, dwFileOS, dwFileType, dwFileSubtype, lwFileDate) - - let vsVersionInfoResource = - VersionResourceFormat.VS_VERSION_INFO_RESOURCE(fixedFileInfo, stringFileInfo, varFileInfo) - - let resource = - [| yield! ResFileFormat.ResFileHeader() - yield! vsVersionInfoResource |] - - [ resource ] - - // a user cannot specify both win32res and win32manifest - if not(tcConfig.win32manifest = "") && not(tcConfig.win32res = "") then - error(Error(FSComp.SR.fscTwoResourceManifests(), rangeCmdArgs)) - - let win32Manifest = - // use custom manifest if provided - if not(tcConfig.win32manifest = "") then tcConfig.win32manifest - - // don't embed a manifest if target is not an exe, if manifest is specifically excluded, if another native resource is being included, or if running on mono - elif not(tcConfig.target.IsExe) || not(tcConfig.includewin32manifest) || not(tcConfig.win32res = "") || runningOnMono then "" - // otherwise, include the default manifest + let extensionForFile (filePath: string) = + if (List.exists (FileSystemUtils.checkSuffix filePath) mlCompatSuffixes) then + ".mli" else - let path = Path.Combine(System.AppContext.BaseDirectory, @"default.win32manifest") - if File.Exists(path) then path - else Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), @"default.win32manifest") - - let nativeResources = - [ for av in assemblyVersionResources findAttribute assemblyVersion do - yield ILNativeResource.Out av - if not(tcConfig.win32res = "") then - yield ILNativeResource.Out (FileSystem.ReadAllBytesShim tcConfig.win32res) - if tcConfig.includewin32manifest && not(win32Manifest = "") && not runningOnMono then - yield ILNativeResource.Out [| yield! ResFileFormat.ResFileHeader() - yield! (ManifestResourceFormat.VS_MANIFEST_RESOURCE((FileSystem.ReadAllBytesShim win32Manifest), tcConfig.target = CompilerTarget.Dll)) |]] - - // Add attributes, version number, resources etc. - {mainModule with - StackReserveSize = tcConfig.stackReserveSize - Name = (if tcConfig.target = CompilerTarget.Module then Filename.fileNameOfPath outfile else mainModule.Name) - SubSystemFlags = (if tcConfig.target = CompilerTarget.WinExe then 2 else 3) - Resources= resources - ImageBase = (match tcConfig.baseAddress with None -> 0x00400000l | Some b -> b) - IsDLL=(tcConfig.target = CompilerTarget.Dll || tcConfig.target=CompilerTarget.Module) - Platform = tcConfig.platform - Is32Bit=(match tcConfig.platform with Some X86 -> true | _ -> false) - Is64Bit=(match tcConfig.platform with Some AMD64 | Some IA64 -> true | _ -> false) - Is32BitPreferred = if tcConfig.prefer32Bit && not tcConfig.target.IsExe then (error(Error(FSComp.SR.invalidPlatformTarget(), rangeCmdArgs))) else tcConfig.prefer32Bit - CustomAttrsStored= - storeILCustomAttrs - (mkILCustomAttrs - [ if tcConfig.target = CompilerTarget.Module then - yield! iattrs - yield! codegenResults.ilNetModuleAttrs ]) - NativeResources=nativeResources - Manifest = manifest } - + ".fsi" -//---------------------------------------------------------------------------- -// Static linking -//---------------------------------------------------------------------------- - -/// Optional static linking of all DLLs that depend on the F# Library, plus other specified DLLs -module StaticLinker = - - - // Handles TypeForwarding for the generated IL model - type TypeForwarding (tcImports: TcImports) = - - // Make a dictionary of ccus passed to the compiler will be looked up by qualified assembly name - let ccuThunksQualifiedName = - tcImports.GetCcusInDeclOrder() - |> List.filter(fun ccuThunk -> ccuThunk.QualifiedName |> Option.isSome) - |> List.map(fun ccuThunk -> ccuThunk.QualifiedName |> Option.defaultValue "Assembly Name Not Passed", ccuThunk) - |> dict - - // If we can't type forward using exact assembly match, we need to rely on the loader (Policy, Configuration or the coreclr load heuristics), so use try simple name - let ccuThunksSimpleName = - tcImports.GetCcusInDeclOrder() - |> List.filter(fun ccuThunk -> not (String.IsNullOrEmpty(ccuThunk.AssemblyName))) - |> List.map(fun ccuThunk -> ccuThunk.AssemblyName, ccuThunk) - |> dict - - let followTypeForwardForILTypeRef (tref:ILTypeRef) = - let typename = - let parts = tref.FullName.Split([|'.'|]) - match parts.Length with - | 0 -> None - | 1 -> Some (Array.empty, parts.[0]) - | n -> Some (parts.[0..n-2], parts.[n-1]) - - let scoref = tref.Scope - match scoref with - | ILScopeRef.Assembly scope -> - match ccuThunksQualifiedName.TryGetValue(scope.QualifiedName) with - | true, ccu -> - match typename with - | Some (parts, name) -> - let forwarded = ccu.TryForward(parts, name) - let result = - match forwarded with - | Some fwd -> fwd.CompilationPath.ILScopeRef - | None -> scoref - result - | None -> scoref - | false, _ -> - // Couldn't find an assembly with the version so try using a simple name - match ccuThunksSimpleName.TryGetValue(scope.Name) with - | true, ccu -> - match typename with - | Some (parts, name) -> - let forwarded = ccu.TryForward(parts, name) - let result = - match forwarded with - | Some fwd -> fwd.CompilationPath.ILScopeRef - | None -> scoref - result - | None -> scoref - | false, _ -> scoref - | _ -> scoref - - let typeForwardILTypeRef (tref: ILTypeRef) = - let scoref1 = tref.Scope - let scoref2 = followTypeForwardForILTypeRef tref - if scoref1 === scoref2 then tref - else ILTypeRef.Create (scoref2, tref.Enclosing, tref.Name) - - member __.TypeForwardILTypeRef tref = typeForwardILTypeRef tref - - let debugStaticLinking = condition "FSHARP_DEBUG_STATIC_LINKING" - - let StaticLinkILModules (tcConfig:TcConfig, ilGlobals, tcImports, ilxMainModule, dependentILModules: (CcuThunk option * ILModuleDef) list) = - if isNil dependentILModules then - ilxMainModule, (fun x -> x) - else - let typeForwarding = new TypeForwarding(tcImports) - - // Check no dependent assemblies use quotations - let dependentCcuUsingQuotations = dependentILModules |> List.tryPick (function (Some ccu, _) when ccu.UsesFSharp20PlusQuotations -> Some ccu | _ -> None) - match dependentCcuUsingQuotations with - | Some ccu -> error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking(ccu.AssemblyName), rangeStartup)) - | None -> () - - // Check we're not static linking a .EXE - if dependentILModules |> List.exists (fun (_, x) -> not x.IsDLL) then - error(Error(FSComp.SR.fscStaticLinkingNoEXE(), rangeStartup)) - - // Check we're not static linking something that is not pure IL - if dependentILModules |> List.exists (fun (_, x) -> not x.IsILOnly) then - error(Error(FSComp.SR.fscStaticLinkingNoMixedDLL(), rangeStartup)) - - // The set of short names for the all dependent assemblies - let assems = - set [ for (_, m) in dependentILModules do - match m.Manifest with - | Some m -> yield m.Name - | _ -> () ] - - // A rewriter which rewrites scope references to things in dependent assemblies to be local references - let rewriteExternalRefsToLocalRefs x = - if assems.Contains (getNameOfScopeRef x) then ILScopeRef.Local else x - - let savedManifestAttrs = - [ for (_, depILModule) in dependentILModules do - match depILModule.Manifest with - | Some m -> - for ca in m.CustomAttrs.AsArray do - if ca.Method.MethodRef.DeclaringTypeRef.FullName = typeof.FullName then - yield ca - | _ -> () ] - - let savedResources = - let allResources = [ for (ccu, m) in dependentILModules do for r in m.Resources.AsList do yield (ccu, r) ] - // Don't save interface, optimization or resource definitions for provider-generated assemblies. - // These are "fake". - let isProvided (ccu: CcuThunk option) = -#if !NO_EXTENSIONTYPING - match ccu with - | Some c -> c.IsProviderGenerated - | None -> false -#else - ignore ccu - false -#endif - - // Save only the interface/optimization attributes of generated data - let intfDataResources, others = allResources |> List.partition (snd >> IsSignatureDataResource) - let intfDataResources = - [ for (ccu, r) in intfDataResources do - if GenerateInterfaceData tcConfig && not (isProvided ccu) then - yield r ] - - let optDataResources, others = others |> List.partition (snd >> IsOptimizationDataResource) - let optDataResources = - [ for (ccu, r) in optDataResources do - if GenerateOptimizationData tcConfig && not (isProvided ccu) then - yield r ] - - let otherResources = others |> List.map snd - - let result = intfDataResources@optDataResources@otherResources - result - - let moduls = ilxMainModule :: (List.map snd dependentILModules) - - let savedNativeResources = - [ //yield! ilxMainModule.NativeResources - for m in moduls do - yield! m.NativeResources ] - - let topTypeDefs, normalTypeDefs = - moduls - |> List.map (fun m -> m.TypeDefs.AsList |> List.partition (fun td -> isTypeNameForGlobalFunctions td.Name)) - |> List.unzip - - let topTypeDef = - let topTypeDefs = List.concat topTypeDefs - mkILTypeDefForGlobalFunctions ilGlobals - (mkILMethods (topTypeDefs |> List.collect (fun td -> td.Methods.AsList)), - mkILFields (topTypeDefs |> List.collect (fun td -> td.Fields.AsList))) - - let ilxMainModule = - let main = - { ilxMainModule with - Manifest = (let m = ilxMainModule.ManifestOfAssembly in Some {m with CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (m.CustomAttrs.AsList @ savedManifestAttrs)) }) - CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs [ for m in moduls do yield! m.CustomAttrs.AsArray ]) - TypeDefs = mkILTypeDefs (topTypeDef :: List.concat normalTypeDefs) - Resources = mkILResources (savedResources @ ilxMainModule.Resources.AsList) - NativeResources = savedNativeResources } - Morphs.morphILTypeRefsInILModuleMemoized ilGlobals typeForwarding.TypeForwardILTypeRef main - - ilxMainModule, rewriteExternalRefsToLocalRefs - - [] - type Node = - { name: string - data: ILModuleDef - ccu: option - refs: ILReferences - mutable edges: list - mutable visited: bool } - - // Find all IL modules that are to be statically linked given the static linking roots. - let FindDependentILModulesForStaticLinking (ctok, tcConfig: TcConfig, tcImports: TcImports, ilGlobals: ILGlobals, ilxMainModule) = - if not tcConfig.standalone && tcConfig.extraStaticLinkRoots.IsEmpty then - [] - else - // Recursively find all referenced modules and add them to a module graph - let depModuleTable = HashMultiMap(0, HashIdentity.Structural) - let dummyEntry nm = - { refs = IL.emptyILRefs - name=nm - ccu=None - data=ilxMainModule // any old module - edges = [] - visited = true } - let assumedIndependentSet = set [ "mscorlib"; "System"; "System.Core"; "System.Xml"; "Microsoft.Build.Framework"; "Microsoft.Build.Utilities" ] - - begin - let mutable remaining = (computeILRefs ilGlobals ilxMainModule).AssemblyReferences - while not (isNil remaining) do - let ilAssemRef = List.head remaining - remaining <- List.tail remaining - if assumedIndependentSet.Contains ilAssemRef.Name || (ilAssemRef.PublicKey = Some ecmaPublicKey) then - depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name - else - if not (depModuleTable.ContainsKey ilAssemRef.Name) then - match tcImports.TryFindDllInfo(ctok, Range.rangeStartup, ilAssemRef.Name, lookupOnly=false) with - | Some dllInfo -> - let ccu = - match tcImports.FindCcuFromAssemblyRef (ctok, Range.rangeStartup, ilAssemRef) with - | ResolvedCcu ccu -> Some ccu - | UnresolvedCcu(_ccuName) -> None - - let fileName = dllInfo.FileName - let modul = - let pdbDirPathOption = - // We open the pdb file if one exists parallel to the binary we - // are reading, so that --standalone will preserve debug information. - if tcConfig.openDebugInformationForLaterStaticLinking then - let pdbDir = (try Filename.directoryName fileName with _ -> ".") - let pdbFile = (try Filename.chopExtension fileName with _ -> fileName)+".pdb" - if FileSystem.SafeExists pdbFile then - if verbose then dprintf "reading PDB file %s from directory %s during static linking\n" pdbFile pdbDir - Some pdbDir - else - None - else - None - - let opts : ILReaderOptions = - { metadataOnly = MetadataOnlyFlag.No // turn this off here as we need the actual IL code - reduceMemoryUsage = tcConfig.reduceMemoryUsage - pdbDirPath = pdbDirPathOption - tryGetMetadataSnapshot = (fun _ -> None) } - - let reader = ILBinaryReader.OpenILModuleReader dllInfo.FileName opts - reader.ILModuleDef - - let refs = - if ilAssemRef.Name = GetFSharpCoreLibraryName() then - IL.emptyILRefs - elif not modul.IsILOnly then - warning(Error(FSComp.SR.fscIgnoringMixedWhenLinking ilAssemRef.Name, rangeStartup)) - IL.emptyILRefs - else - { AssemblyReferences = dllInfo.ILAssemblyRefs - ModuleReferences = [] } - - depModuleTable.[ilAssemRef.Name] <- - { refs=refs - name=ilAssemRef.Name - ccu=ccu - data=modul - edges = [] - visited = false } - - // Push the new work items - remaining <- refs.AssemblyReferences @ remaining - - | None -> - warning(Error(FSComp.SR.fscAssumeStaticLinkContainsNoDependencies(ilAssemRef.Name), rangeStartup)) - depModuleTable.[ilAssemRef.Name] <- dummyEntry ilAssemRef.Name - done - end - - ReportTime tcConfig "Find dependencies" - - // Add edges from modules to the modules that depend on them - for (KeyValue(_, n)) in depModuleTable do - for aref in n.refs.AssemblyReferences do - let n2 = depModuleTable.[aref.Name] - n2.edges <- n :: n2.edges - - // Find everything that depends on FSharp.Core - let roots = - [ if tcConfig.standalone && depModuleTable.ContainsKey (GetFSharpCoreLibraryName()) then - yield depModuleTable.[GetFSharpCoreLibraryName()] - for n in tcConfig.extraStaticLinkRoots do - match depModuleTable.TryFind n with - | Some x -> yield x - | None -> error(Error(FSComp.SR.fscAssemblyNotFoundInDependencySet n, rangeStartup)) - ] - - let mutable remaining = roots - [ while not (isNil remaining) do - let n = List.head remaining - remaining <- List.tail remaining - if not n.visited then - if verbose then dprintn ("Module "+n.name+" depends on "+GetFSharpCoreLibraryName()) - n.visited <- true - remaining <- n.edges @ remaining - yield (n.ccu, n.data) ] - - // Add all provider-generated assemblies into the static linking set - let FindProviderGeneratedILModules (ctok, tcImports: TcImports, providerGeneratedAssemblies: (ImportedBinary * _) list) = - [ for (importedBinary, provAssemStaticLinkInfo) in providerGeneratedAssemblies do - let ilAssemRef = - match importedBinary.ILScopeRef with - | ILScopeRef.Assembly aref -> aref - | _ -> failwith "Invalid ILScopeRef, expected ILScopeRef.Assembly" - if debugStaticLinking then printfn "adding provider-generated assembly '%s' into static linking set" ilAssemRef.Name - match tcImports.TryFindDllInfo(ctok, Range.rangeStartup, ilAssemRef.Name, lookupOnly=false) with - | Some dllInfo -> - let ccu = - match tcImports.FindCcuFromAssemblyRef (ctok, Range.rangeStartup, ilAssemRef) with - | ResolvedCcu ccu -> Some ccu - | UnresolvedCcu(_ccuName) -> None - - let modul = dllInfo.RawMetadata.TryGetILModuleDef().Value - yield (ccu, dllInfo.ILScopeRef, modul), (ilAssemRef.Name, provAssemStaticLinkInfo) - | None -> () ] - - // Compute a static linker. This only captures tcImports (a large data structure) if - // static linking is enabled. Normally this is not the case, which lets us collect tcImports - // prior to this point. - let StaticLink (ctok, tcConfig: TcConfig, tcImports: TcImports, ilGlobals: ILGlobals) = - -#if !NO_EXTENSIONTYPING - let providerGeneratedAssemblies = - - [ // Add all EST-generated assemblies into the static linking set - for KeyValue(_, importedBinary: ImportedBinary) in tcImports.DllTable do - if importedBinary.IsProviderGenerated then - match importedBinary.ProviderGeneratedStaticLinkMap with - | None -> () - | Some provAssemStaticLinkInfo -> yield (importedBinary, provAssemStaticLinkInfo) ] -#endif - if not tcConfig.standalone && tcConfig.extraStaticLinkRoots.IsEmpty -#if !NO_EXTENSIONTYPING - && providerGeneratedAssemblies.IsEmpty -#endif - then - (fun ilxMainModule -> ilxMainModule) - else - (fun ilxMainModule -> - ReportTime tcConfig "Find assembly references" - - let dependentILModules = FindDependentILModulesForStaticLinking (ctok, tcConfig, tcImports, ilGlobals, ilxMainModule) - - ReportTime tcConfig "Static link" - -#if !NO_EXTENSIONTYPING - Morphs.enableMorphCustomAttributeData() - let providerGeneratedILModules = FindProviderGeneratedILModules (ctok, tcImports, providerGeneratedAssemblies) - - // Transform the ILTypeRefs references in the IL of all provider-generated assemblies so that the references - // are now local. - let providerGeneratedILModules = - - providerGeneratedILModules |> List.map (fun ((ccu, ilOrigScopeRef, ilModule), (_, localProvAssemStaticLinkInfo)) -> - let ilAssemStaticLinkMap = - dict [ for (_, (_, provAssemStaticLinkInfo)) in providerGeneratedILModules do - for KeyValue(k, v) in provAssemStaticLinkInfo.ILTypeMap do - yield (k, v) - for KeyValue(k, v) in localProvAssemStaticLinkInfo.ILTypeMap do - yield (ILTypeRef.Create(ILScopeRef.Local, k.Enclosing, k.Name), v) ] - - let ilModule = - ilModule |> Morphs.morphILTypeRefsInILModuleMemoized ilGlobals (fun tref -> - if debugStaticLinking then printfn "deciding whether to rewrite type ref %A" tref.QualifiedName - let ok, v = ilAssemStaticLinkMap.TryGetValue tref - if ok then - if debugStaticLinking then printfn "rewriting type ref %A to %A" tref.QualifiedName v.QualifiedName - v - else - tref) - (ccu, ilOrigScopeRef, ilModule)) - - // Relocate provider generated type definitions into the expected shape for the [] declarations in an assembly - let providerGeneratedILModules, ilxMainModule = - // Build a dictionary of all remapped IL type defs - let ilOrigTyRefsForProviderGeneratedTypesToRelocate = - let rec walk acc (ProviderGeneratedType(ilOrigTyRef, _, xs) as node) = List.fold walk ((ilOrigTyRef, node) :: acc) xs - dict (Seq.fold walk [] tcImports.ProviderGeneratedTypeRoots) - - // Build a dictionary of all IL type defs, mapping ilOrigTyRef --> ilTypeDef - let allTypeDefsInProviderGeneratedAssemblies = - let rec loop ilOrigTyRef (ilTypeDef: ILTypeDef) = - seq { yield (ilOrigTyRef, ilTypeDef) - for ntdef in ilTypeDef.NestedTypes do - yield! loop (mkILTyRefInTyRef (ilOrigTyRef, ntdef.Name)) ntdef } - dict [ - for (_ccu, ilOrigScopeRef, ilModule) in providerGeneratedILModules do - for td in ilModule.TypeDefs do - yield! loop (mkILTyRef (ilOrigScopeRef, td.Name)) td ] - - - // Debugging output - if debugStaticLinking then - for (ProviderGeneratedType(ilOrigTyRef, _, _)) in tcImports.ProviderGeneratedTypeRoots do - printfn "Have [] root '%s'" ilOrigTyRef.QualifiedName - - // Build the ILTypeDefs for generated types, starting with the roots - let generatedILTypeDefs = - let rec buildRelocatedGeneratedType (ProviderGeneratedType(ilOrigTyRef, ilTgtTyRef, ch)) = - let isNested = not (isNil ilTgtTyRef.Enclosing) - match allTypeDefsInProviderGeneratedAssemblies.TryGetValue ilOrigTyRef with - | true, ilOrigTypeDef -> - if debugStaticLinking then printfn "Relocating %s to %s " ilOrigTyRef.QualifiedName ilTgtTyRef.QualifiedName - let ilOrigTypeDef = - if isNested then - ilOrigTypeDef - .WithAccess(match ilOrigTypeDef.Access with - | ILTypeDefAccess.Public -> ILTypeDefAccess.Nested ILMemberAccess.Public - | ILTypeDefAccess.Private -> ILTypeDefAccess.Nested ILMemberAccess.Private - | _ -> ilOrigTypeDef.Access) - else ilOrigTypeDef - ilOrigTypeDef.With(name = ilTgtTyRef.Name, - nestedTypes = mkILTypeDefs (List.map buildRelocatedGeneratedType ch)) - | _ -> - // If there is no matching IL type definition, then make a simple container class - if debugStaticLinking then - printfn "Generating simple class '%s' because we didn't find an original type '%s' in a provider generated assembly" - ilTgtTyRef.QualifiedName ilOrigTyRef.QualifiedName - - let access = (if isNested then ILTypeDefAccess.Nested ILMemberAccess.Public else ILTypeDefAccess.Public) - let tdefs = mkILTypeDefs (List.map buildRelocatedGeneratedType ch) - mkILSimpleClass ilGlobals (ilTgtTyRef.Name, access, emptyILMethods, emptyILFields, tdefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.OnAny) - - [ for (ProviderGeneratedType(_, ilTgtTyRef, _) as node) in tcImports.ProviderGeneratedTypeRoots do - yield (ilTgtTyRef, buildRelocatedGeneratedType node) ] - - // Implant all the generated type definitions into the ilxMainModule (generating a new ilxMainModule) - let ilxMainModule = - - /// Split the list into left, middle and right parts at the first element satisfying 'p'. If no element matches return - /// 'None' for the middle part. - let trySplitFind p xs = - let rec loop xs acc = - match xs with - | [] -> List.rev acc, None, [] - | h :: t -> if p h then List.rev acc, Some h, t else loop t (h :: acc) - loop xs [] - - /// Implant the (nested) type definition 'td' at path 'enc' in 'tdefs'. - let rec implantTypeDef isNested (tdefs: ILTypeDefs) (enc: string list) (td: ILTypeDef) = - match enc with - | [] -> addILTypeDef td tdefs - | h :: t -> - let tdefs = tdefs.AsList - let (ltdefs, htd, rtdefs) = - match tdefs |> trySplitFind (fun td -> td.Name = h) with - | (ltdefs, None, rtdefs) -> - let access = if isNested then ILTypeDefAccess.Nested ILMemberAccess.Public else ILTypeDefAccess.Public - let fresh = mkILSimpleClass ilGlobals (h, access, emptyILMethods, emptyILFields, emptyILTypeDefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.OnAny) - (ltdefs, fresh, rtdefs) - | (ltdefs, Some htd, rtdefs) -> - (ltdefs, htd, rtdefs) - let htd = htd.With(nestedTypes = implantTypeDef true htd.NestedTypes t td) - mkILTypeDefs (ltdefs @ [htd] @ rtdefs) - - let newTypeDefs = - (ilxMainModule.TypeDefs, generatedILTypeDefs) ||> List.fold (fun acc (ilTgtTyRef, td) -> - if debugStaticLinking then printfn "implanting '%s' at '%s'" td.Name ilTgtTyRef.QualifiedName - implantTypeDef false acc ilTgtTyRef.Enclosing td) - { ilxMainModule with TypeDefs = newTypeDefs } - - // Remove any ILTypeDefs from the provider generated modules if they have been relocated because of a [] declaration. - let providerGeneratedILModules = - providerGeneratedILModules |> List.map (fun (ccu, ilOrigScopeRef, ilModule) -> - let ilTypeDefsAfterRemovingRelocatedTypes = - let rec rw enc (tdefs: ILTypeDefs) = - mkILTypeDefs - [ for tdef in tdefs do - let ilOrigTyRef = mkILNestedTyRef (ilOrigScopeRef, enc, tdef.Name) - if not (ilOrigTyRefsForProviderGeneratedTypesToRelocate.ContainsKey ilOrigTyRef) then - if debugStaticLinking then printfn "Keep provided type %s in place because it wasn't relocated" ilOrigTyRef.QualifiedName - yield tdef.With(nestedTypes = rw (enc@[tdef.Name]) tdef.NestedTypes) ] - rw [] ilModule.TypeDefs - (ccu, { ilModule with TypeDefs = ilTypeDefsAfterRemovingRelocatedTypes })) - - providerGeneratedILModules, ilxMainModule - - Morphs.disableMorphCustomAttributeData() -#else - let providerGeneratedILModules = [] -#endif - - // Glue all this stuff into ilxMainModule - let ilxMainModule, rewriteExternalRefsToLocalRefs = - StaticLinkILModules (tcConfig, ilGlobals, tcImports, ilxMainModule, dependentILModules @ providerGeneratedILModules) - - // Rewrite type and assembly references - let ilxMainModule = - let isMscorlib = ilGlobals.primaryAssemblyName = PrimaryAssembly.Mscorlib.Name - let validateTargetPlatform (scopeRef : ILScopeRef) = - let name = getNameOfScopeRef scopeRef - if (not isMscorlib && name = PrimaryAssembly.Mscorlib.Name) then - error (Error(FSComp.SR.fscStaticLinkingNoProfileMismatches(), rangeCmdArgs)) - scopeRef - let rewriteAssemblyRefsToMatchLibraries = NormalizeAssemblyRefs (ctok, ilGlobals, tcImports) - Morphs.morphILTypeRefsInILModuleMemoized ilGlobals (Morphs.morphILScopeRefsInILTypeRef (validateTargetPlatform >> rewriteExternalRefsToLocalRefs >> rewriteAssemblyRefsToMatchLibraries)) ilxMainModule - - ilxMainModule) - -//---------------------------------------------------------------------------- -// ValidateKeySigningAttributes, GetStrongNameSigner -//---------------------------------------------------------------------------- + let writeToSeparateFiles (declaredImpls: TypedImplFile list) = + for TImplFile (name, _, _, _, _, _) as impl in declaredImpls do + let filename = Path.ChangeExtension(name.Range.FileName, extensionForFile name.Range.FileName) + printfn "writing impl file to %s" filename + use os = FileSystem.OpenFileForWriteShim(filename, FileMode.Create).GetWriter() + writeHeader filename os + writeToFile os impl -type StrongNameSigningInfo = StrongNameSigningInfo of (* delaysign:*) bool * (* publicsign:*) bool * (*signer:*) string option * (*container:*) string option - -let ValidateKeySigningAttributes (tcConfig : TcConfig, tcGlobals, topAttrs) = - let delaySignAttrib = AttributeHelpers.TryFindBoolAttribute tcGlobals "System.Reflection.AssemblyDelaySignAttribute" topAttrs.assemblyAttrs - let signerAttrib = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyKeyFileAttribute" topAttrs.assemblyAttrs - let containerAttrib = AttributeHelpers.TryFindStringAttribute tcGlobals "System.Reflection.AssemblyKeyNameAttribute" topAttrs.assemblyAttrs - - // if delaySign is set via an attribute, validate that it wasn't set via an option - let delaysign = - match delaySignAttrib with - | Some delaysign -> - if tcConfig.delaysign then - warning(Error(FSComp.SR.fscDelaySignWarning(), rangeCmdArgs)) - tcConfig.delaysign - else - delaysign - | _ -> tcConfig.delaysign - - // if signer is set via an attribute, validate that it wasn't set via an option - let signer = - match signerAttrib with - | Some signer -> - if tcConfig.signer.IsSome && tcConfig.signer <> Some signer then - warning(Error(FSComp.SR.fscKeyFileWarning(), rangeCmdArgs)) - tcConfig.signer - else - Some signer - | None -> tcConfig.signer - - // if container is set via an attribute, validate that it wasn't set via an option, and that they keyfile wasn't set - // if keyfile was set, use that instead (silently) - // REVIEW: This is C# behavior, but it seems kind of sketchy that we fail silently - let container = - match containerAttrib with - | Some container -> - if tcConfig.container.IsSome && tcConfig.container <> Some container then - warning(Error(FSComp.SR.fscKeyNameWarning(), rangeCmdArgs)) - tcConfig.container - else - Some container - | None -> tcConfig.container - - StrongNameSigningInfo (delaysign, tcConfig.publicsign, signer, container) - -/// Checks if specified file name is absolute path. If yes - returns the name as is, otherwise makes full path using tcConfig.implicitIncludeDir as base. -let expandFileNameIfNeeded (tcConfig : TcConfig) name = - if FileSystem.IsPathRootedShim name then - name - else - Path.Combine(tcConfig.implicitIncludeDir, name) - -let GetStrongNameSigner signingInfo = - let (StrongNameSigningInfo(delaysign, publicsign, signer, container)) = signingInfo - // REVIEW: favor the container over the key file - C# appears to do this - if Option.isSome container then - Some (ILBinaryWriter.ILStrongNameSigner.OpenKeyContainer container.Value) - else - match signer with - | None -> None - | Some s -> - try - if publicsign || delaysign then - Some (ILBinaryWriter.ILStrongNameSigner.OpenPublicKeyOptions s publicsign) - else - Some (ILBinaryWriter.ILStrongNameSigner.OpenKeyPairFile s) - with e -> - // Note :: don't use errorR here since we really want to fail and not produce a binary - error(Error(FSComp.SR.fscKeyFileCouldNotBeOpened s, rangeCmdArgs)) + if tcConfig.printSignature then + writeAllToSameFile declaredImpls + else if tcConfig.printAllSignatureFiles then + writeToSeparateFiles declaredImpls //---------------------------------------------------------------------------- // CopyFSharpCore @@ -1681,8 +371,8 @@ let CopyFSharpCore(outFile: string, referencedDlls: AssemblyReference list) = let fsharpCoreAssemblyName = GetFSharpCoreLibraryName() + ".dll" let fsharpCoreDestinationPath = Path.Combine(outDir, fsharpCoreAssemblyName) let copyFileIfDifferent src dest = - if not (File.Exists dest) || (File.GetCreationTimeUtc src <> File.GetCreationTimeUtc dest) then - File.Copy(src, dest, true) + if not (FileSystem.FileExistsShim dest) || (FileSystem.GetCreationTimeShim src <> FileSystem.GetCreationTimeShim dest) then + FileSystem.CopyShim(src, dest, true) match referencedDlls |> Seq.tryFind (fun dll -> String.Equals(Path.GetFileName(dll.Text), fsharpCoreAssemblyName, StringComparison.CurrentCultureIgnoreCase)) with | Some referencedFsharpCoreDll -> copyFileIfDifferent referencedFsharpCoreDll.Text fsharpCoreDestinationPath @@ -1691,253 +381,259 @@ let CopyFSharpCore(outFile: string, referencedDlls: AssemblyReference list) = Assembly.GetExecutingAssembly().Location let compilerLocation = Path.GetDirectoryName executionLocation let compilerFsharpCoreDllPath = Path.Combine(compilerLocation, fsharpCoreAssemblyName) - if File.Exists compilerFsharpCoreDllPath then + if FileSystem.FileExistsShim compilerFsharpCoreDllPath then copyFileIfDifferent compilerFsharpCoreDllPath fsharpCoreDestinationPath else errorR(Error(FSComp.SR.fsharpCoreNotFoundToBeCopied(), rangeCmdArgs)) +// Try to find an AssemblyVersion attribute +let TryFindVersionAttribute g attrib attribName attribs deterministic = + match AttributeHelpers.TryFindStringAttribute g attrib attribs with + | Some versionString -> + if deterministic && versionString.Contains("*") then + errorR(Error(FSComp.SR.fscAssemblyWildcardAndDeterminism(attribName, versionString), rangeStartup)) + try Some (parseILVersion versionString) + with e -> + // Warning will be reported by CheckExpressions.fs + None + | _ -> None + //---------------------------------------------------------------------------- -// Main phases of compilation +// Main phases of compilation. These are written as separate functions with explicit argument passing +// to ensure transient objects are eligible for GC and only actual required information +// is propagated. //----------------------------------------------------------------------------- [] type Args<'T> = Args of 'T -let main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, - reduceMemoryUsage: ReduceMemoryFlag, defaultCopyFSharpCore: CopyFSharpCoreFlag, - exiter: Exiter, errorLoggerProvider : ErrorLoggerProvider, disposables : DisposablesTracker) = - - // See Bug 735819 +/// First phase of compilation. +/// - Set up console encoding and code page settings +/// - Process command line, flags and collect filenames +/// - Resolve assemblies +/// - Import assemblies +/// - Parse source files +/// - Check the inputs +let main1(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, + reduceMemoryUsage: ReduceMemoryFlag, defaultCopyFSharpCore: CopyFSharpCoreFlag, + exiter: Exiter, errorLoggerProvider: ErrorLoggerProvider, disposables: DisposablesTracker) = + + // See Bug 735819 let lcidFromCodePage = if (Console.OutputEncoding.CodePage <> 65001) && (Console.OutputEncoding.CodePage <> Thread.CurrentThread.CurrentUICulture.TextInfo.OEMCodePage) && (Console.OutputEncoding.CodePage <> Thread.CurrentThread.CurrentUICulture.TextInfo.ANSICodePage) then - Thread.CurrentThread.CurrentUICulture <- new CultureInfo("en-US") + Thread.CurrentThread.CurrentUICulture <- CultureInfo("en-US") Some 1033 else None let directoryBuildingFrom = Directory.GetCurrentDirectory() - let setProcessThreadLocals tcConfigB = - match tcConfigB.preferredUiLang with - | Some s -> Thread.CurrentThread.CurrentUICulture <- new CultureInfo(s) - | None -> () - if tcConfigB.utf8output then - Console.OutputEncoding <- Encoding.UTF8 - - let displayBannerIfNeeded tcConfigB = - // display the banner text, if necessary - if not bannerAlreadyPrinted then - DisplayBannerText tcConfigB let tryGetMetadataSnapshot = (fun _ -> None) - let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, DefaultFSharpBinariesDir, - reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=directoryBuildingFrom, - isInteractive=false, isInvalidationSupported=false, - defaultCopyFSharpCore=defaultCopyFSharpCore, - tryGetMetadataSnapshot=tryGetMetadataSnapshot) + let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None).Value + + let tcConfigB = + TcConfigBuilder.CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir, + reduceMemoryUsage=reduceMemoryUsage, + implicitIncludeDir=directoryBuildingFrom, + isInteractive=false, + isInvalidationSupported=false, + defaultCopyFSharpCore=defaultCopyFSharpCore, + tryGetMetadataSnapshot=tryGetMetadataSnapshot, + sdkDirOverride=None, + rangeForErrors=range0) // Preset: --optimize+ -g --tailcalls+ (see 4505) SetOptimizeSwitch tcConfigB OptionSwitch.On SetDebugSwitch tcConfigB None OptionSwitch.Off - SetTailcallSwitch tcConfigB OptionSwitch.On + SetTailcallSwitch tcConfigB OptionSwitch.On // Now install a delayed logger to hold all errors from flags until after all flags have been parsed (for example, --vserrors) let delayForFlagsLogger = errorLoggerProvider.CreateDelayAndForwardLogger exiter - let _unwindEL_1 = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayForFlagsLogger) - + + let _unwindEL_1 = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayForFlagsLogger) + // Share intern'd strings across all lexing/parsing - let lexResourceManager = new Lexhelp.LexResourceManager() + let lexResourceManager = Lexhelp.LexResourceManager() + + let dependencyProvider = new DependencyProvider() - // process command line, flags and collect filenames - let sourceFiles = + // Process command line, flags and collect filenames + let sourceFiles = // The ParseCompilerOptions function calls imperative function to process "real" args - // Rather than start processing, just collect names, then process them. - try - let sourceFiles = - let files = ProcessCommandLineFlags (tcConfigB, setProcessThreadLocals, lcidFromCodePage, argv) - AdjustForScriptCompile(ctok, tcConfigB, files, lexResourceManager) - sourceFiles - - with e -> + // Rather than start processing, just collect names, then process them. + try + let files = ProcessCommandLineFlags (tcConfigB, lcidFromCodePage, argv) + AdjustForScriptCompile(tcConfigB, files, lexResourceManager, dependencyProvider) + with e -> errorRecovery e rangeStartup delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB - exiter.Exit 1 - - tcConfigB.conditionalCompilationDefines <- "COMPILED" :: tcConfigB.conditionalCompilationDefines - displayBannerIfNeeded tcConfigB + exiter.Exit 1 + + tcConfigB.conditionalCompilationDefines <- "COMPILED" :: tcConfigB.conditionalCompilationDefines + + // Display the banner text, if necessary + if not bannerAlreadyPrinted then + DisplayBannerText tcConfigB // Create tcGlobals and frameworkTcImports - let outfile, pdbfile, assemblyName = - try + let outfile, pdbfile, assemblyName = + try tcConfigB.DecideNames sourceFiles with e -> errorRecovery e rangeStartup delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB - exiter.Exit 1 - + exiter.Exit 1 + // DecideNames may give "no inputs" error. Abort on error at this point. bug://3911 if not tcConfigB.continueAfterParseFailure && delayForFlagsLogger.ErrorCount > 0 then delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB exiter.Exit 1 - - // If there's a problem building TcConfig, abort - let tcConfig = + + // If there's a problem building TcConfig, abort + let tcConfig = try TcConfig.Create(tcConfigB, validate=false) with e -> + errorRecovery e rangeStartup delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB exiter.Exit 1 - + let errorLogger = errorLoggerProvider.CreateErrorLoggerUpToMaxErrors(tcConfigB, exiter) // Install the global error logger and never remove it. This logger does have all command-line flags considered. let _unwindEL_2 = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) - + // Forward all errors from flags delayForFlagsLogger.CommitDelayedDiagnostics errorLogger - if not tcConfigB.continueAfterParseFailure then + if not tcConfigB.continueAfterParseFailure then AbortOnError(errorLogger, exiter) // Resolve assemblies ReportTime tcConfig "Import mscorlib and FSharp.Core.dll" let foundationalTcConfigP = TcConfigProvider.Constant tcConfig - let sysRes, otherRes, knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) - + + let sysRes, otherRes, knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(tcConfig) + // Import basic assemblies - let tcGlobals, frameworkTcImports = TcImports.BuildFrameworkTcImports (ctok, foundationalTcConfigP, sysRes, otherRes) |> Cancellable.runWithoutCancellation + let tcGlobals, frameworkTcImports = + TcImports.BuildFrameworkTcImports (foundationalTcConfigP, sysRes, otherRes) + |> NodeCode.RunImmediateWithoutCancellation // Register framework tcImports to be disposed in future disposables.Register frameworkTcImports - // Parse sourceFiles + // Parse sourceFiles ReportTime tcConfig "Parse inputs" use unwindParsePhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - let inputs = - try - let isLastCompiland, isExe = sourceFiles |> tcConfig.ComputeCanContainEntryPoint - isLastCompiland |> List.zip sourceFiles - // PERF: consider making this parallel, once uses of global state relevant to parsing are cleaned up - |> List.choose (fun (filename: string, isLastCompiland) -> - let pathOfMetaCommandSource = Path.GetDirectoryName filename - match ParseOneInputFile(tcConfig, lexResourceManager, ["COMPILED"], filename, (isLastCompiland, isExe), errorLogger, (*retryLocked*)false) with - | Some input -> Some (input, pathOfMetaCommandSource) - | None -> None - ) - with e -> - errorRecoveryNoRange e - exiter.Exit 1 - + + let createErrorLogger = (fun exiter -> errorLoggerProvider.CreateDelayAndForwardLogger(exiter) :> CapturingErrorLogger) + let inputs = ParseInputFiles(tcConfig, lexResourceManager, ["COMPILED"], sourceFiles, errorLogger, exiter, createErrorLogger, (*retryLocked*)false) + let inputs, _ = - (Map.empty, inputs) - ||> List.mapFold (fun state (input,x) -> let inputT, stateT = DeduplicateParsedInputModuleName state input in (inputT,x), stateT) + (Map.empty, inputs) ||> List.mapFold (fun state (input, x) -> + let inputT, stateT = DeduplicateParsedInputModuleName state input + (inputT, x), stateT) + + // Print the AST if requested + if tcConfig.printAst then + for input, _filename in inputs do + printf "AST:\n" + printfn "%+A" input + printf "\n" - if tcConfig.parseOnly then exiter.Exit 0 - if not tcConfig.continueAfterParseFailure then + if tcConfig.parseOnly then exiter.Exit 0 + + if not tcConfig.continueAfterParseFailure then AbortOnError(errorLogger, exiter) - if tcConfig.printAst then - inputs |> List.iter (fun (input, _filename) -> printf "AST:\n"; printfn "%+A" input; printf "\n") + // Apply any nowarn flags + let tcConfig = + (tcConfig, inputs) ||> List.fold (fun z (input, sourceFileDirectory) -> + ApplyMetaCommandsFromInputToTcConfig(z, input, sourceFileDirectory, dependencyProvider)) - let tcConfig = (tcConfig, inputs) ||> List.fold (fun z (x, m) -> ApplyMetaCommandsFromInputToTcConfig(z, x, m)) let tcConfigP = TcConfigProvider.Constant tcConfig // Import other assemblies ReportTime tcConfig "Import non-system references" - let tcImports = TcImports.BuildNonFrameworkTcImports(ctok, tcConfigP, tcGlobals, frameworkTcImports, otherRes, knownUnresolved) |> Cancellable.runWithoutCancellation + + let tcImports = + TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, otherRes, knownUnresolved, dependencyProvider) + |> NodeCode.RunImmediateWithoutCancellation // register tcImports to be disposed in future disposables.Register tcImports - if not tcConfig.continueAfterParseFailure then + if not tcConfig.continueAfterParseFailure then AbortOnError(errorLogger, exiter) - if tcConfig.importAllReferencesOnly then exiter.Exit 0 + if tcConfig.importAllReferencesOnly then exiter.Exit 0 // Build the initial type checking environment ReportTime tcConfig "Typecheck" + use unwindParsePhase = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck - let tcEnv0 = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) + + let tcEnv0, openDecls0 = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) // Type check the inputs let inputs = inputs |> List.map fst - let tcState, topAttrs, typedAssembly, _tcEnvAtEnd = - TypeCheck(ctok, tcConfig, tcImports, tcGlobals, errorLogger, assemblyName, NiceNameGenerator(), tcEnv0, inputs, exiter) + + let tcState, topAttrs, typedAssembly, _tcEnvAtEnd = + TypeCheck(ctok, tcConfig, tcImports, tcGlobals, errorLogger, assemblyName, NiceNameGenerator(), tcEnv0, openDecls0, inputs, exiter) AbortOnError(errorLogger, exiter) ReportTime tcConfig "Typechecked" Args (ctok, tcGlobals, tcImports, frameworkTcImports, tcState.Ccu, typedAssembly, topAttrs, tcConfig, outfile, pdbfile, assemblyName, errorLogger, exiter) -let main1(Args (ctok, tcGlobals, tcImports: TcImports, frameworkTcImports, generatedCcu: CcuThunk, typedImplFiles, topAttrs, tcConfig: TcConfig, outfile, pdbfile, assemblyName, errorLogger, exiter: Exiter)) = - - if tcConfig.typeCheckOnly then exiter.Exit 0 - - generatedCcu.Contents.SetAttribs(generatedCcu.Contents.Attribs @ topAttrs.assemblyAttrs) - - use unwindPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.CodeGen - let signingInfo = ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) - - AbortOnError(errorLogger, exiter) - - // Build an updated errorLogger that filters according to the scopedPragmas. Then install - // it as the updated global error logger and never remove it - let oldLogger = errorLogger - let errorLogger = - let scopedPragmas = [ for (TImplFile (_, pragmas, _, _, _, _)) in typedImplFiles do yield! pragmas ] - GetErrorLoggerFilteringByScopedPragmas(true, scopedPragmas, oldLogger) - - let _unwindEL_3 = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) - - // Try to find an AssemblyVersion attribute - let assemVerFromAttrib = - match AttributeHelpers.TryFindVersionAttribute tcGlobals "System.Reflection.AssemblyVersionAttribute" "AssemblyVersionAttribute" topAttrs.assemblyAttrs tcConfig.deterministic with - | Some v -> - match tcConfig.version with - | VersionNone -> Some v - | _ -> warning(Error(FSComp.SR.fscAssemblyVersionAttributeIgnored(), Range.rangeStartup)); None - | _ -> None - - // write interface, xmldoc - begin - ReportTime tcConfig ("Write Interface File") - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Output - if tcConfig.printSignature then InterfaceFileWriter.WriteInterfaceFile (tcGlobals, tcConfig, InfoReader(tcGlobals, tcImports.GetImportMap()), typedImplFiles) - - ReportTime tcConfig ("Write XML document signatures") - if tcConfig.xmlDocOutputFile.IsSome then - XmlDocWriter.computeXmlDocSigs (tcGlobals, generatedCcu) - - ReportTime tcConfig ("Write XML docs") - tcConfig.xmlDocOutputFile |> Option.iter ( fun xmlFile -> - let xmlFile = tcConfig.MakePathAbsolute xmlFile - XmlDocWriter.writeXmlDoc (assemblyName, generatedCcu, xmlFile) - ) - ReportTime tcConfig ("Write HTML docs") - end - - // Pass on only the minimum information required for the next phase - Args (ctok, tcConfig, tcImports, frameworkTcImports, tcGlobals, errorLogger, generatedCcu, outfile, typedImplFiles, topAttrs, pdbfile, assemblyName, assemVerFromAttrib, signingInfo, exiter) +/// Alternative first phase of compilation. This is for the compile-from-AST feature of FCS. +/// - Import assemblies +/// - Check the inputs +let main1OfAst + (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, + outfile, pdbFile, dllReferences, + noframework, exiter: Exiter, + errorLoggerProvider: ErrorLoggerProvider, + disposables: DisposablesTracker, + inputs: ParsedInput list) = + let tryGetMetadataSnapshot = (fun _ -> None) -// This is for the compile-from-AST feature of FCS. -// TODO: consider removing this feature from FCS, which as far as I know is not used by anyone. -let main1OfAst (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, outfile, pdbFile, dllReferences, noframework, exiter, errorLoggerProvider: ErrorLoggerProvider, inputs : ParsedInput list) = + let directoryBuildingFrom = Directory.GetCurrentDirectory() - let tryGetMetadataSnapshot = (fun _ -> None) + let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None).Value + + let tcConfigB = + TcConfigBuilder.CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, + reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=directoryBuildingFrom, + isInteractive=false, isInvalidationSupported=false, + defaultCopyFSharpCore=CopyFSharpCoreFlag.No, + tryGetMetadataSnapshot=tryGetMetadataSnapshot, + sdkDirOverride=None, + rangeForErrors=range0) + + let primaryAssembly = + // temporary workaround until https://github.com/dotnet/fsharp/pull/8043 is merged: + // pick a primary assembly based on whether the developer included System>Runtime in the list of reference assemblies. + // It's an ugly compromise used to avoid exposing primaryAssembly in the public api for this function. + let includesSystem_Runtime = dllReferences |> Seq.exists(fun f -> Path.GetFileName(f).Equals("system.runtime.dll",StringComparison.InvariantCultureIgnoreCase)) + if includesSystem_Runtime then + PrimaryAssembly.System_Runtime + else + PrimaryAssembly.Mscorlib - let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, DefaultFSharpBinariesDir, - reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=Directory.GetCurrentDirectory(), - isInteractive=false, isInvalidationSupported=false, - defaultCopyFSharpCore=CopyFSharpCoreFlag.No, - tryGetMetadataSnapshot=tryGetMetadataSnapshot) + tcConfigB.target <- target + tcConfigB.SetPrimaryAssembly primaryAssembly + if noframework then + tcConfigB.framework <- false + tcConfigB.implicitlyResolveAssemblies <- false - tcConfigB.framework <- not noframework // Preset: --optimize+ -g --tailcalls+ (see 4505) SetOptimizeSwitch tcConfigB OptionSwitch.On SetDebugSwitch tcConfigB None ( @@ -1945,168 +641,249 @@ let main1OfAst (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, | Some _ -> OptionSwitch.On | None -> OptionSwitch.Off) SetTailcallSwitch tcConfigB OptionSwitch.On - tcConfigB.target <- target - - let errorLogger = errorLoggerProvider.CreateErrorLoggerUpToMaxErrors (tcConfigB, exiter) + + // Now install a delayed logger to hold all errors from flags until after all flags have been parsed (for example, --vserrors) + let delayForFlagsLogger = errorLoggerProvider.CreateDelayAndForwardLogger exiter + let _unwindEL_1 = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayForFlagsLogger) tcConfigB.conditionalCompilationDefines <- "COMPILED" :: tcConfigB.conditionalCompilationDefines // append assembly dependencies dllReferences |> List.iter (fun ref -> tcConfigB.AddReferencedAssemblyByPath(rangeStartup,ref)) - // If there's a problem building TcConfig, abort - let tcConfig = + // If there's a problem building TcConfig, abort + let tcConfig = try TcConfig.Create(tcConfigB,validate=false) with e -> + delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB exiter.Exit 1 - + + let dependencyProvider = new DependencyProvider() + let errorLogger = errorLoggerProvider.CreateErrorLoggerUpToMaxErrors(tcConfigB, exiter) + + // Install the global error logger and never remove it. This logger does have all command-line flags considered. + let _unwindEL_2 = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + + // Forward all errors from flags + delayForFlagsLogger.CommitDelayedDiagnostics errorLogger + + // Resolve assemblies + ReportTime tcConfig "Import mscorlib and FSharp.Core.dll" let foundationalTcConfigP = TcConfigProvider.Constant tcConfig - let sysRes,otherRes,knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) - let tcGlobals,frameworkTcImports = TcImports.BuildFrameworkTcImports (ctok, foundationalTcConfigP, sysRes, otherRes) |> Cancellable.runWithoutCancellation + let sysRes, otherRes, knownUnresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(tcConfig) + + // Import basic assemblies + let tcGlobals, frameworkTcImports = + TcImports.BuildFrameworkTcImports (foundationalTcConfigP, sysRes, otherRes) + |> NodeCode.RunImmediateWithoutCancellation + + // Register framework tcImports to be disposed in future + disposables.Register frameworkTcImports - use unwindParsePhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.Parse) + use unwindParsePhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse let meta = Directory.GetCurrentDirectory() - let tcConfig = (tcConfig,inputs) ||> List.fold (fun tcc inp -> ApplyMetaCommandsFromInputToTcConfig (tcc, inp,meta)) + let tcConfig = (tcConfig,inputs) ||> List.fold (fun tcc inp -> ApplyMetaCommandsFromInputToTcConfig (tcc, inp, meta, dependencyProvider)) let tcConfigP = TcConfigProvider.Constant tcConfig - let tcGlobals,tcImports = - let tcImports = TcImports.BuildNonFrameworkTcImports(ctok, tcConfigP, tcGlobals, frameworkTcImports, otherRes,knownUnresolved) |> Cancellable.runWithoutCancellation - tcGlobals,tcImports + // Import other assemblies + ReportTime tcConfig "Import non-system references" - use unwindParsePhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.TypeCheck) - let tcEnv0 = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) + let tcImports = + TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, otherRes, knownUnresolved, dependencyProvider) + |> NodeCode.RunImmediateWithoutCancellation - let tcState,topAttrs,typedAssembly,_tcEnvAtEnd = - TypeCheck(ctok, tcConfig, tcImports, tcGlobals, errorLogger, assemblyName, NiceNameGenerator(), tcEnv0, inputs,exiter) + // register tcImports to be disposed in future + disposables.Register tcImports + + // Build the initial type checking environment + ReportTime tcConfig "Typecheck" + use unwindParsePhase = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck + let tcEnv0, openDecls0 = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) + + // Type check the inputs + let tcState, topAttrs, typedAssembly, _tcEnvAtEnd = + TypeCheck(ctok, tcConfig, tcImports, tcGlobals, errorLogger, assemblyName, NiceNameGenerator(), tcEnv0, openDecls0, inputs, exiter) + + AbortOnError(errorLogger, exiter) + ReportTime tcConfig "Typechecked" + + Args (ctok, tcGlobals, tcImports, frameworkTcImports, tcState.Ccu, typedAssembly, topAttrs, tcConfig, outfile, pdbFile, assemblyName, errorLogger, exiter) + +/// Second phase of compilation. +/// - Write the signature file, check some attributes +let main2(Args (ctok, tcGlobals, tcImports: TcImports, frameworkTcImports, generatedCcu: CcuThunk, typedImplFiles, topAttrs, tcConfig: TcConfig, outfile, pdbfile, assemblyName, errorLogger, exiter: Exiter)) = + + if tcConfig.typeCheckOnly then exiter.Exit 0 - let generatedCcu = tcState.Ccu generatedCcu.Contents.SetAttribs(generatedCcu.Contents.Attribs @ topAttrs.assemblyAttrs) - use unwindPhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.CodeGen) + use unwindPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.CodeGen let signingInfo = ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) - // Try to find an AssemblyVersion attribute - let assemVerFromAttrib = - match AttributeHelpers.TryFindVersionAttribute tcGlobals "System.Reflection.AssemblyVersionAttribute" "AssemblyVersionAttribute" topAttrs.assemblyAttrs tcConfig.deterministic with - | Some v -> - match tcConfig.version with - | VersionNone -> Some v - | _ -> warning(Error(FSComp.SR.fscAssemblyVersionAttributeIgnored(),Range.range0)); None + AbortOnError(errorLogger, exiter) + + // Build an updated errorLogger that filters according to the scopedPragmas. Then install + // it as the updated global error logger and never remove it + let oldLogger = errorLogger + let errorLogger = + let scopedPragmas = [ for TImplFile (_, pragmas, _, _, _, _) in typedImplFiles do yield! pragmas ] + GetErrorLoggerFilteringByScopedPragmas(true, scopedPragmas, oldLogger) + + let _unwindEL_3 = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) + + // Try to find an AssemblyVersion attribute + let assemVerFromAttrib = + match TryFindVersionAttribute tcGlobals "System.Reflection.AssemblyVersionAttribute" "AssemblyVersionAttribute" topAttrs.assemblyAttrs tcConfig.deterministic with + | Some v -> + match tcConfig.version with + | VersionNone -> Some v + | _ -> warning(Error(FSComp.SR.fscAssemblyVersionAttributeIgnored(), rangeStartup)); None | _ -> None - // Pass on only the minimum information required for the next phase to ensure GC kicks in. - // In principle the JIT should be able to do good liveness analysis to clean things up, but the - // data structures involved here are so large we can't take the risk. - Args(ctok, tcConfig, tcImports, frameworkTcImports, tcGlobals, errorLogger, - generatedCcu, outfile, typedAssembly, topAttrs, pdbFile, assemblyName, - assemVerFromAttrib, signingInfo,exiter) - - -/// Phase 2a: encode signature data, optimize, encode optimization data -let main2a(Args (ctok, tcConfig, tcImports, frameworkTcImports: TcImports, tcGlobals, - errorLogger: ErrorLogger, generatedCcu: CcuThunk, outfile, typedImplFiles, - topAttrs, pdbfile, assemblyName, assemVerFromAttrib, signingInfo, exiter: Exiter)) = - + // write interface, xmldoc + ReportTime tcConfig "Write Interface File" + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Output + if tcConfig.printSignature || tcConfig.printAllSignatureFiles then InterfaceFileWriter.WriteInterfaceFile (tcGlobals, tcConfig, InfoReader(tcGlobals, tcImports.GetImportMap()), typedImplFiles) + + ReportTime tcConfig "Write XML document signatures" + if tcConfig.xmlDocOutputFile.IsSome then + XmlDocWriter.ComputeXmlDocSigs (tcGlobals, generatedCcu) + + ReportTime tcConfig "Write XML docs" + tcConfig.xmlDocOutputFile |> Option.iter (fun xmlFile -> + let xmlFile = tcConfig.MakePathAbsolute xmlFile + XmlDocWriter.WriteXmlDocFile (assemblyName, generatedCcu, xmlFile)) + + // Pass on only the minimum information required for the next phase + Args (ctok, tcConfig, tcImports, frameworkTcImports, tcGlobals, errorLogger, generatedCcu, outfile, typedImplFiles, topAttrs, pdbfile, assemblyName, assemVerFromAttrib, signingInfo, exiter) + + +/// Third phase of compilation. +/// - encode signature data +/// - optimize +/// - encode optimization data +let main3(Args (ctok, tcConfig, tcImports, frameworkTcImports: TcImports, tcGlobals, + errorLogger: ErrorLogger, generatedCcu: CcuThunk, outfile, typedImplFiles, + topAttrs, pdbfile, assemblyName, assemVerFromAttrib, signingInfo, exiter: Exiter)) = + // Encode the signature data - ReportTime tcConfig ("Encode Interface Data") + ReportTime tcConfig "Encode Interface Data" let exportRemapping = MakeExportRemapping generatedCcu generatedCcu.Contents - - let sigDataAttributes, sigDataResources = - try - EncodeInterfaceData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, false) - with e -> - errorRecoveryNoRange e - exiter.Exit 1 - + + let sigDataAttributes, sigDataResources = + try + EncodeSignatureData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, false) + with e -> + errorRecoveryNoRange e + exiter.Exit 1 + // Perform optimization use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Optimize - + let optEnv0 = GetInitialOptimizationEnv (tcImports, tcGlobals) - + let importMap = tcImports.GetImportMap() - let metadataVersion = + + let metadataVersion = match tcConfig.metadataVersion with | Some v -> v - | _ -> - match frameworkTcImports.DllTable.TryFind tcConfig.primaryAssembly.Name with - | Some ib -> ib.RawMetadata.TryGetILModuleDef().Value.MetadataVersion + | _ -> + match frameworkTcImports.DllTable.TryFind tcConfig.primaryAssembly.Name with + | Some ib -> ib.RawMetadata.TryGetILModuleDef().Value.MetadataVersion | _ -> "" - let optimizedImpls, optimizationData, _ = - ApplyAllOptimizations - (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, + let optimizedImpls, optimizationData, _ = + ApplyAllOptimizations + (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, importMap, false, optEnv0, generatedCcu, typedImplFiles) AbortOnError(errorLogger, exiter) - + // Encode the optimization data - ReportTime tcConfig ("Encoding OptData") + ReportTime tcConfig "Encoding OptData" + let optDataResources = EncodeOptimizationData(tcGlobals, tcConfig, outfile, exportRemapping, (generatedCcu, optimizationData), false) // Pass on only the minimum information required for the next phase - Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger, - generatedCcu, outfile, optimizedImpls, topAttrs, pdbfile, assemblyName, - (sigDataAttributes, sigDataResources), optDataResources, assemVerFromAttrib, signingInfo, metadataVersion, exiter) - -/// Phase 2b: IL code generation -let main2b - (tcImportsCapture,dynamicAssemblyCreator) - (Args (ctok, tcConfig: TcConfig, tcImports, tcGlobals: TcGlobals, errorLogger, - generatedCcu: CcuThunk, outfile, optimizedImpls, topAttrs, pdbfile, assemblyName, - idata, optDataResources, assemVerFromAttrib, signingInfo, metadataVersion, exiter: Exiter)) = - - match tcImportsCapture with + Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger, + generatedCcu, outfile, optimizedImpls, topAttrs, pdbfile, assemblyName, + sigDataAttributes, sigDataResources, optDataResources, assemVerFromAttrib, signingInfo, metadataVersion, exiter) + +/// Fourth phase of compilation. +/// - Static linking +/// - IL code generation +let main4 + (tcImportsCapture,dynamicAssemblyCreator) + (Args (ctok, tcConfig: TcConfig, tcImports, tcGlobals: TcGlobals, errorLogger, + generatedCcu: CcuThunk, outfile, optimizedImpls, topAttrs, pdbfile, assemblyName, + sigDataAttributes, sigDataResources, optDataResources, assemVerFromAttrib, signingInfo, metadataVersion, exiter: Exiter)) = + + match tcImportsCapture with | None -> () | Some f -> f tcImports - // Compute a static linker. + // Compute a static linker, it gets called later. let ilGlobals = tcGlobals.ilg - if tcConfig.standalone && generatedCcu.UsesFSharp20PlusQuotations then - error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking0(), rangeStartup)) - let staticLinker = StaticLinker.StaticLink (ctok, tcConfig, tcImports, ilGlobals) + if tcConfig.standalone && generatedCcu.UsesFSharp20PlusQuotations then + error(Error(FSComp.SR.fscQuotationLiteralsStaticLinking0(), rangeStartup)) + + let staticLinker = StaticLink (ctok, tcConfig, tcImports, ilGlobals) - // Generate IL code ReportTime tcConfig "TAST -> IL" use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.IlxGen + + // Create the Abstract IL generator let ilxGenerator = CreateIlxAssemblyGenerator (tcConfig, tcImports, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), generatedCcu) let codegenBackend = (if Option.isSome dynamicAssemblyCreator then IlReflectBackend else IlWriteBackend) + + // Generate the Abstract IL Code let codegenResults = GenerateIlxCode (codegenBackend, Option.isSome dynamicAssemblyCreator, false, tcConfig, topAttrs, optimizedImpls, generatedCcu.AssemblyName, ilxGenerator) + + // Build the Abstract IL view of the final main module, prior to static linking + let topAssemblyAttrs = codegenResults.topAssemblyAttrs let topAttrs = {topAttrs with assemblyAttrs=topAssemblyAttrs} let permissionSets = codegenResults.permissionSets - let secDecls = mkILSecurityDecls permissionSets + let secDecls = mkILSecurityDecls permissionSets - let ilxMainModule = MainModuleBuilder.CreateMainModule (ctok, tcConfig, tcGlobals, tcImports, pdbfile, assemblyName, outfile, topAttrs, idata, optDataResources, codegenResults, assemVerFromAttrib, metadataVersion, secDecls) + let ilxMainModule = + MainModuleBuilder.CreateMainModule + (ctok, tcConfig, tcGlobals, tcImports, + pdbfile, assemblyName, outfile, topAttrs, + sigDataAttributes, sigDataResources, optDataResources, + codegenResults, assemVerFromAttrib, metadataVersion, secDecls) AbortOnError(errorLogger, exiter) // Pass on only the minimum information required for the next phase Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger, staticLinker, outfile, pdbfile, ilxMainModule, signingInfo, exiter) -/// Phase 3: static linking -let main3(Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger: ErrorLogger, staticLinker, outfile, pdbfile, ilxMainModule, signingInfo, exiter: Exiter)) = - +/// Fifth phase of compilation. +/// - static linking +let main5(Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger: ErrorLogger, staticLinker, outfile, pdbfile, ilxMainModule, signingInfo, exiter: Exiter)) = + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Output // Static linking, if any - let ilxMainModule = + let ilxMainModule = try staticLinker ilxMainModule - with e -> + with e -> errorRecoveryNoRange e exiter.Exit 1 AbortOnError(errorLogger, exiter) - + // Pass on only the minimum information required for the next phase Args (ctok, tcConfig, tcImports, tcGlobals, errorLogger, ilxMainModule, outfile, pdbfile, signingInfo, exiter) -/// Phase 4: write the binaries -let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, tcGlobals: TcGlobals, - errorLogger: ErrorLogger, ilxMainModule, outfile, pdbfile, - signingInfo, exiter: Exiter)) = +/// Sixth phase of compilation. +/// - write the binaries +let main6 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, tcGlobals: TcGlobals, + errorLogger: ErrorLogger, ilxMainModule, outfile, pdbfile, + signingInfo, exiter: Exiter)) = ReportTime tcConfig "Write .NET Binary" @@ -2117,20 +894,20 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t let pdbfile = pdbfile |> Option.map (tcConfig.MakePathAbsolute >> FileSystem.GetFullPathShim) - let normalizeAssemblyRefs (aref: ILAssemblyRef) = - match tcImports.TryFindDllInfo (ctok, Range.rangeStartup, aref.Name, lookupOnly=false) with + let normalizeAssemblyRefs (aref: ILAssemblyRef) = + match tcImports.TryFindDllInfo (ctok, rangeStartup, aref.Name, lookupOnly=false) with | Some dllInfo -> - match dllInfo.ILScopeRef with + match dllInfo.ILScopeRef with | ILScopeRef.Assembly ref -> ref | _ -> aref | None -> aref - match dynamicAssemblyCreator with - | None -> + match dynamicAssemblyCreator with + | None -> try - try - ILBinaryWriter.WriteILBinary - (outfile, + try + ILBinaryWriter.WriteILBinary + (outfile, { ilg = tcGlobals.ilg pdbfile=pdbfile emitTailcalls = tcConfig.emitTailcalls @@ -2148,12 +925,12 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t ilxMainModule, normalizeAssemblyRefs ) - with Failure msg -> + with Failure msg -> error(Error(FSComp.SR.fscProblemWritingBinary(outfile, msg), rangeCmdArgs)) - with e -> + with e -> errorRecoveryNoRange e - exiter.Exit 1 - | Some da -> da (tcGlobals,outfile,ilxMainModule) + exiter.Exit 1 + | Some da -> da (tcConfig, tcGlobals, outfile, ilxMainModule) AbortOnError(errorLogger, exiter) @@ -2163,48 +940,37 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t ReportTime tcConfig "Exiting" -//---------------------------------------------------------------------------- -// Entry points to compilation -//----------------------------------------------------------------------------- - -/// Entry point typecheckAndCompile -let typecheckAndCompile - (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, - defaultCopyFSharpCore, exiter: Exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) = +/// The main (non-incremental) compilation entry point used by fsc.exe +let mainCompile + (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, + defaultCopyFSharpCore, exiter: Exiter, loggerProvider, tcImportsCapture, dynamicAssemblyCreator) = - use d = new DisposablesTracker() - let savedOut = System.Console.Out + use disposables = new DisposablesTracker() + let savedOut = Console.Out use __ = { new IDisposable with - member __.Dispose() = - try - System.Console.SetOut(savedOut) + member _.Dispose() = + try + Console.SetOut(savedOut) with _ -> ()} - main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, defaultCopyFSharpCore, exiter, errorLoggerProvider, d) - |> main1 - |> main2a - |> main2b (tcImportsCapture,dynamicAssemblyCreator) - |> main3 - |> main4 dynamicAssemblyCreator - - -let compileOfAst - (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, - outFile, pdbFile, dllReferences, noframework, exiter, errorLoggerProvider, inputs, tcImportsCapture, dynamicAssemblyCreator) = - - main1OfAst (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, outFile, pdbFile, - dllReferences, noframework, exiter, errorLoggerProvider, inputs) - |> main2a - |> main2b (tcImportsCapture, dynamicAssemblyCreator) + main1(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, defaultCopyFSharpCore, exiter, loggerProvider, disposables) + |> main2 |> main3 - |> main4 dynamicAssemblyCreator - -let mainCompile - (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, - defaultCopyFSharpCore, exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) = - - typecheckAndCompile - (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, - defaultCopyFSharpCore, exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) - + |> main4 (tcImportsCapture,dynamicAssemblyCreator) + |> main5 + |> main6 dynamicAssemblyCreator + +/// An additional compilation entry point used by FSharp.Compiler.Service taking syntax trees as input +let compileOfAst + (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, + targetDll, targetPdb, dependencies, noframework, exiter, loggerProvider, inputs, tcImportsCapture, dynamicAssemblyCreator) = + + use disposables = new DisposablesTracker() + main1OfAst (ctok, legacyReferenceResolver, reduceMemoryUsage, assemblyName, target, targetDll, targetPdb, + dependencies, noframework, exiter, loggerProvider, disposables, inputs) + |> main2 + |> main3 + |> main4 (tcImportsCapture, dynamicAssemblyCreator) + |> main5 + |> main6 dynamicAssemblyCreator diff --git a/src/fsharp/fsc.fsi b/src/fsharp/fsc.fsi index b07c6fd120e..8de6f416740 100755 --- a/src/fsharp/fsc.fsi +++ b/src/fsharp/fsc.fsi @@ -2,13 +2,15 @@ module internal FSharp.Compiler.Driver -open FSharp.Compiler.Ast +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals [] @@ -16,47 +18,29 @@ type ErrorLoggerProvider = new : unit -> ErrorLoggerProvider abstract CreateErrorLoggerUpToMaxErrors : tcConfigBuilder : TcConfigBuilder * exiter : Exiter -> ErrorLogger -type StrongNameSigningInfo - -val EncodeInterfaceData: tcConfig:TcConfig * tcGlobals:TcGlobals * exportRemapping:Tastops.Remap * generatedCcu: Tast.CcuThunk * outfile: string * isIncrementalBuild: bool -> ILAttribute list * ILResource list -val ValidateKeySigningAttributes : tcConfig:TcConfig * tcGlobals:TcGlobals * TypeChecker.TopAttribs -> StrongNameSigningInfo -val GetStrongNameSigner : StrongNameSigningInfo -> ILBinaryWriter.ILStrongNameSigner option - -/// Process the given set of command line arguments -val internal ProcessCommandLineFlags : TcConfigBuilder * setProcessThreadLocals:(TcConfigBuilder -> unit) * lcidFromCodePage : int option * argv:string[] -> string list - -//--------------------------------------------------------------------------- -// The entry point used by fsc.exe - -val typecheckAndCompile : - ctok: CompilationThreadToken * - argv : string[] * - legacyReferenceResolver: ReferenceResolver.Resolver * - bannerAlreadyPrinted : bool * - reduceMemoryUsage: ReduceMemoryFlag * - defaultCopyFSharpCore: CopyFSharpCoreFlag * - exiter : Exiter * - loggerProvider: ErrorLoggerProvider * - tcImportsCapture: (TcImports -> unit) option * - dynamicAssemblyCreator: (TcGlobals * string * ILModuleDef -> unit) option - -> unit +/// The default ErrorLoggerProvider implementation, reporting messages to the Console up to the maxerrors maximum +type ConsoleLoggerProvider = + new : unit -> ConsoleLoggerProvider + inherit ErrorLoggerProvider -val mainCompile : +/// The main (non-incremental) compilation entry point used by fsc.exe +val mainCompile: ctok: CompilationThreadToken * argv: string[] * - legacyReferenceResolver: ReferenceResolver.Resolver * + legacyReferenceResolver: LegacyReferenceResolver * bannerAlreadyPrinted: bool * reduceMemoryUsage: ReduceMemoryFlag * defaultCopyFSharpCore: CopyFSharpCoreFlag * exiter: Exiter * loggerProvider: ErrorLoggerProvider * tcImportsCapture: (TcImports -> unit) option * - dynamicAssemblyCreator: (TcGlobals * string * ILModuleDef -> unit) option + dynamicAssemblyCreator: (TcConfig * TcGlobals * string * ILModuleDef -> unit) option -> unit -val compileOfAst : +/// An additional compilation entry point used by FSharp.Compiler.Service taking syntax trees as input +val compileOfAst: ctok: CompilationThreadToken * - legacyReferenceResolver: ReferenceResolver.Resolver * + legacyReferenceResolver: LegacyReferenceResolver * reduceMemoryUsage: ReduceMemoryFlag * assemblyName:string * target:CompilerTarget * @@ -68,10 +52,9 @@ val compileOfAst : loggerProvider: ErrorLoggerProvider * inputs:ParsedInput list * tcImportsCapture : (TcImports -> unit) option * - dynamicAssemblyCreator: (TcGlobals * string * ILModuleDef -> unit) option + dynamicAssemblyCreator: (TcConfig * TcGlobals * string * ILModuleDef -> unit) option -> unit - /// Part of LegacyHostedCompilerForTesting type InProcErrorLoggerProvider = new : unit -> InProcErrorLoggerProvider @@ -79,14 +62,3 @@ type InProcErrorLoggerProvider = member CapturedWarnings : Diagnostic[] member CapturedErrors : Diagnostic[] -/// The default ErrorLogger implementation, reporting messages to the Console up to the maxerrors maximum -type ConsoleLoggerProvider = - new : unit -> ConsoleLoggerProvider - inherit ErrorLoggerProvider - -// For unit testing -module internal MainModuleBuilder = - - val fileVersion: findStringAttr: (string -> string option) -> assemblyVersion: ILVersionInfo -> ILVersionInfo - val productVersion: findStringAttr: (string -> string option) -> fileVersion: ILVersionInfo -> string - val productVersionToILVersionInfo: string -> ILVersionInfo diff --git a/src/fsharp/fsc/App.config b/src/fsharp/fsc/App.config index c5ee96a1294..9ff4d9b9f78 100644 --- a/src/fsharp/fsc/App.config +++ b/src/fsharp/fsc/App.config @@ -8,10 +8,6 @@ - - - - - + \ No newline at end of file diff --git a/src/windows/default.win32manifest b/src/fsharp/fsc/default.win32manifest similarity index 100% rename from src/windows/default.win32manifest rename to src/fsharp/fsc/default.win32manifest diff --git a/src/fsharp/fsc/fsc.fsproj b/src/fsharp/fsc/fsc.fsproj index 2e5a405c6e8..1bf8a94662c 100644 --- a/src/fsharp/fsc/fsc.fsproj +++ b/src/fsharp/fsc/fsc.fsproj @@ -5,13 +5,13 @@ Exe $(ProtoTargetFramework) - net472;netcoreapp3.0 - netcoreapp3.0 - .exe - $(NoWarn);45;55;62;75;1204 + net472;net5.0 + net5.0 + $(NoWarn);44 + $(NoWarn);75 true - $(OtherFlags) --maxerrors:20 --extraoptimizationloops:1 true + true @@ -22,8 +22,7 @@ fscmain.fs - - default.win32manifest + PreserveNewest @@ -35,13 +34,14 @@ - - + + + diff --git a/src/fsharp/fscmain.fs b/src/fsharp/fscmain.fs index f4c6b87c283..947839cd5f6 100644 --- a/src/fsharp/fscmain.fs +++ b/src/fsharp/fscmain.fs @@ -3,38 +3,49 @@ module internal FSharp.Compiler.CommandLineMain open System -open System.Diagnostics -open System.IO open System.Reflection open System.Runtime.CompilerServices -open FSharp.Compiler +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.CompilerConfig open FSharp.Compiler.Driver -open FSharp.Compiler.Lib -open FSharp.Compiler.Range -open FSharp.Compiler.CompileOps -open FSharp.Compiler.AbstractIL.Internal.Library -open Internal.Utilities +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text -[] +[] do () + +[] +let main(argv) = + + // Set the garbage collector to batch mode, which improves overall performance. + System.Runtime.GCSettings.LatencyMode <- System.Runtime.GCLatencyMode.Batch + + // Set the initial phase to garbage collector to batch mode, which improves overall performance. + use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + // An SDL recommendation + UnmanagedProcessExecutionOptions.EnableHeapTerminationOnCorruption() -module Driver = - let main argv = + try + // We are on a compilation thread let ctok = AssumeCompilationThreadWithoutEvidence () + // The F# compiler expects 'argv' to include the executable name, though it makes no use of it. + let argv = Array.append [| "fsc.exe" |] argv + // Check for --pause as the very first step so that a compiler can be attached here. let pauseFlag = argv |> Array.exists (fun x -> x = "/pause" || x = "--pause") if pauseFlag then System.Console.WriteLine("Press return to continue...") System.Console.ReadLine() |> ignore + // Set up things for the --times testing flag #if !FX_NO_APP_DOMAINS let timesFlag = argv |> Array.exists (fun x -> x = "/times" || x = "--times") if timesFlag then @@ -48,6 +59,8 @@ module Driver = stats.weakByteFileCount) #endif + // This object gets invoked when two many errors have been accumulated, or an abort-on-error condition + // has been reached (e.g. type checking failed, so don't proceed to optimization). let quitProcessExiter = { new Exiter with member x.Exit(n) = @@ -55,9 +68,10 @@ module Driver = exit n with _ -> () - failwithf "%s" <| FSComp.SR.elSysEnvExitDidntExit() + failwithf "%s" (FSComp.SR.elSysEnvExitDidntExit()) } + // Get the handler for legacy resolution of references via MSBuild. let legacyReferenceResolver = #if CROSS_PLATFORM_COMPILER SimulatedMSBuildReferenceResolver.SimulatedMSBuildResolver @@ -65,6 +79,8 @@ module Driver = LegacyMSBuildReferenceResolver.getResolver() #endif + // Perform the main compilation. + // // This is the only place where ReduceMemoryFlag.No is set. This is because fsc.exe is not a long-running process and // thus we can use file-locking memory mapped files. // @@ -72,15 +88,7 @@ module Driver = mainCompile (ctok, argv, legacyReferenceResolver, (*bannerAlreadyPrinted*)false, ReduceMemoryFlag.No, CopyFSharpCoreFlag.Yes, quitProcessExiter, ConsoleLoggerProvider(), None, None) 0 -[] -let main(argv) = - System.Runtime.GCSettings.LatencyMode <- System.Runtime.GCLatencyMode.Batch - use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - - Lib.UnmanagedProcessExecutionOptions.EnableHeapTerminationOnCorruption() (* SDL recommendation *) - - try - Driver.main(Array.append [| "fsc.exe" |] argv) with e -> - errorRecovery e FSharp.Compiler.Range.range0 + // Last-chance error recovery (note, with a poor error range) + errorRecovery e Range.range0 1 diff --git a/src/fsharp/fsi/App.config b/src/fsharp/fsi/App.config index 94ab5a37ace..18af8b871fd 100644 --- a/src/fsharp/fsi/App.config +++ b/src/fsharp/fsi/App.config @@ -7,10 +7,6 @@ - - - - - + diff --git a/src/fsharp/fsi/FSIstrings.txt b/src/fsharp/fsi/FSIstrings.txt index c151f7b30e2..dbd7642476b 100644 --- a/src/fsharp/fsi/FSIstrings.txt +++ b/src/fsharp/fsi/FSIstrings.txt @@ -21,7 +21,6 @@ fsiBanner3,"For help type #help;;" fsiConsoleProblem,"A problem occurred starting the F# Interactive process. This may be due to a known problem with background process console support for Unicode-enabled applications on some Windows systems. Try selecting Tools->Options->F# Interactive for Visual Studio and enter '--fsi-server-no-unicode'." 2301,fsiInvalidAssembly,"'%s' is not a valid assembly name" 2302,fsiDirectoryDoesNotExist,"Directory '%s' doesn't exist" -fsiInvalidDirective,"Invalid directive '#%s %s'" fsiLineTooLong,"Warning: line too long, ignoring some characters\n" fsiTimeInfoMainString,"Real: %s, CPU: %s, GC %s" fsiTimeInfoGCGenerationLabelSomeShorthandForTheWordGeneration,"gen" @@ -29,6 +28,7 @@ fsiExceptionDuringPrettyPrinting,"\n\nException raised during pretty printing.\n fsiIntroTextHeader1directives," F# Interactive directives:" fsiIntroTextHashrInfo,"Reference (dynamically load) the given DLL" fsiIntroTextHashIInfo,"Add the given search path for referenced DLLs" +fsiIntroPackageSourceUriInfo,"Include package source uri when searching for packages" fsiIntroTextHashloadInfo,"Load the given file(s) as if compiled and referenced" fsiIntroTextHashtimeInfo,"Toggle timing on/off" fsiIntroTextHashhelpInfo,"Display help" @@ -53,4 +53,4 @@ fsiProductName,"Microsoft (R) F# Interactive version %s" fsiProductNameCommunity,"F# Interactive for F# %s" shadowCopyReferences,"Prevents references from being locked by the F# Interactive process" fsiOperationCouldNotBeCompleted,"Operation could not be completed due to earlier error" -fsiOperationFailed,"Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing" +fsiOperationFailed,"Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing" diff --git a/src/fsharp/fsi/console.fs b/src/fsharp/fsi/console.fs index 0ffab65b355..2c36a667f82 100644 --- a/src/fsharp/fsi/console.fs +++ b/src/fsharp/fsi/console.fs @@ -83,47 +83,27 @@ module internal Utils = with e -> FSharp.Compiler.ErrorLogger.warning(Failure(sprintf "Note: an unexpected exception in fsi.exe readline console support. Consider starting fsi.exe with the --no-readline option and report the stack trace below to the .NET or Mono implementors\n%s\n%s\n" e.Message e.StackTrace)) - // Quick and dirty dirty method lookup for inlined IL - // In some situations, we can't use ldtoken to obtain a RuntimeMethodHandle, since the method - // in question's token may contain typars from an external type environment. Such a token would - // cause the PE file to be flagged as invalid. - // In such a situation, we'll want to search out the MethodRef in a similar fashion to bindMethodBySearch - // but since we can't use ldtoken to obtain System.Type objects, we'll need to do everything with strings. - // This is the least fool-proof method for resolving the binding, but since the scenarios it's used in are - // so constrained, (fsi 2.0, methods with generic multi-dimensional arrays in their signatures), it's - // acceptable - let findMethod (parentT:Type,nm,marity,argtys : string [],rty : string) = - let staticOrInstanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly - let methInfos = parentT.GetMethods(staticOrInstanceBindingFlags) |> Array.toList - - let methInfos = methInfos |> List.filter (fun methInfo -> methInfo.Name = nm) - match methInfos with - | [methInfo] -> - methInfo - | _ -> - let select (methInfo:MethodInfo) = - let mtyargTIs = if methInfo.IsGenericMethod then methInfo.GetGenericArguments() else [| |] - if mtyargTIs.Length <> marity then false else - - let haveArgTs = - let parameters = Array.toList (methInfo.GetParameters()) - parameters |> List.map (fun param -> param.ParameterType) - let haveResT = methInfo.ReturnType - - if argtys.Length <> haveArgTs.Length then false else - let res = rty :: (Array.toList argtys) = (List.map (fun (t : System.Type) -> t.Name) (haveResT :: haveArgTs)) - res - - match List.tryFind select methInfos with - | None -> failwith "Internal Error: cannot bind to method" - | Some methInfo -> methInfo - + let rec previousWordFromIdx (line: string) (idx, isInWord) = + if idx < 0 then 0 else + match line.Chars(idx), isInWord with + | ' ', true -> idx + 1 + | ' ', false -> previousWordFromIdx line (idx - 1, false) + | _, _ -> previousWordFromIdx line (idx - 1, true) + + let rec nextWordFromIdx (line: string) (idx, isInWord) = + if idx >= line.Length then line.Length - 1 else + match line.Chars(idx), isInWord with + | ' ', true -> idx + | ' ', false -> nextWordFromIdx line (idx + 1, false) + | _, _ -> nextWordFromIdx line (idx + 1, true) + [] type internal Cursor = static member ResetTo(top,left) = Utils.guard(fun () -> Console.CursorTop <- min top (Console.BufferHeight - 1) Console.CursorLeft <- left) + static member Move(inset, delta) = let position = Console.CursorTop * (Console.BufferWidth - inset) + (Console.CursorLeft - inset) + delta let top = position / (Console.BufferWidth - inset) @@ -133,7 +113,7 @@ type internal Cursor = type internal Anchor = {top:int; left:int} static member Current(inset) = {top=Console.CursorTop;left= max inset Console.CursorLeft} - + static member Top(inset) = {top = 0; left = inset} member p.PlaceAt(inset, index) = //printf "p.top = %d, p.left = %d, inset = %d, index = %d\n" p.top p.left inset index let left = inset + (( (p.left - inset) + index) % (Console.BufferWidth - inset)) @@ -302,6 +282,24 @@ type internal ReadLineConsole() = let c = input.Chars(current) current <- current + 1 Cursor.Move(x.Inset, x.GetCharacterSize(c)) + + let moveWordLeft() = + if (current > 0 && (current - 1 < input.Length)) then + let line = input.ToString() + current <- Utils.previousWordFromIdx line (current - 1, false) + anchor.PlaceAt(x.Inset, current) + + let moveWordRight() = + if (current < input.Length) then + let line = input.ToString() + let idxToMoveTo = Utils.nextWordFromIdx line (current + 1, false) + + // if has reached end of the last word + if idxToMoveTo = current && current < line.Length + then current <- line.Length + else current <- idxToMoveTo + + anchor.PlaceAt(x.Inset, current) let setInput(line:string) = input.Length <- 0 @@ -334,6 +332,20 @@ type internal ReadLineConsole() = if (input.Length > 0 && current < input.Length) then input.Remove(current, 1) |> ignore render() + + let deleteFromStartOfLineToCursor() = + if (input.Length > 0 && current > 0) then + input.Remove (0, current) |> ignore + current <- 0 + render() + + let deleteWordLeadingToCursor() = + if (input.Length > 0 && current > 0) then + let line = input.ToString() + let idx = Utils.previousWordFromIdx line (current - 1, false) + input.Remove(idx, current - idx) |> ignore + current <- idx + render() let deleteToEndOfLine() = if (current < input.Length) then @@ -347,23 +359,40 @@ type internal ReadLineConsole() = let c = if (key.Key = ConsoleKey.F6) then '\x1A' else key.KeyChar let c = ConsoleOptions.readKeyFixup c insertChar(c) - + let backspace() = if (input.Length > 0 && current > 0) then input.Remove(current - 1, 1) |> ignore current <- current - 1 render() - - let enter() = + let enter() = Console.Write("\n") let line = input.ToString() if (line = "\x1A") then null - else - if (line.Length > 0) then + else + if (line.Length > 0) then history.AddLast(line) line + let clear() = + current <- input.Length + let setPrompt prompt = + if prompt then // We only allow clearing if prompt is ">" + Console.Clear() + Console.Write (x.Prompt) + Console.Write(input.ToString()) + anchor <- Anchor.Top(x.Inset) + let previous = history.Previous() + history.Next() |> ignore + if previous = "" then + setPrompt true + else + setPrompt (previous.EndsWith(";;")) - let rec read() = + + let home() = + current <- 0 + anchor.PlaceAt(x.Inset,0) + let rec read() = let key = Console.ReadKey true match key.Key with @@ -384,62 +413,69 @@ type internal ReadLineConsole() = | ConsoleKey.DownArrow -> setInput(history.Next()) change() - | ConsoleKey.RightArrow -> + | ConsoleKey.RightArrow when key.Modifiers &&& ConsoleModifiers.Control = enum 0 -> moveRight() change() - | ConsoleKey.LeftArrow -> + | ConsoleKey.LeftArrow when key.Modifiers &&& ConsoleModifiers.Control = enum 0 -> moveLeft() change() | ConsoleKey.Escape -> setInput String.Empty change() | ConsoleKey.Home -> - current <- 0 - anchor.PlaceAt(x.Inset,0) + home() change() | ConsoleKey.End -> current <- input.Length anchor.PlaceAt(x.Inset,rendered) change() | _ -> - match (key.Modifiers, key.KeyChar) with - // Control-A - | (ConsoleModifiers.Control, '\001') -> - current <- 0 - anchor.PlaceAt(x.Inset,0) + match (key.Modifiers, key.Key) with + | (ConsoleModifiers.Control, ConsoleKey.A) -> + home() change () - // Control-E - | (ConsoleModifiers.Control, '\005') -> - current <-input.Length - anchor.PlaceAt(x.Inset,rendered) + | (ConsoleModifiers.Control, ConsoleKey.E) -> + current <- input.Length + anchor.PlaceAt(x.Inset, rendered) change () - // Control-B - | (ConsoleModifiers.Control, '\002') -> + | (ConsoleModifiers.Control, ConsoleKey.B) -> moveLeft() change () - // Control-f - | (ConsoleModifiers.Control, '\006') -> + | (ConsoleModifiers.Control, ConsoleKey.F) -> moveRight() change () - // Control-k delete to end of line - | (ConsoleModifiers.Control, '\011') -> + | (ConsoleModifiers.Control, ConsoleKey.LeftArrow) + | (ConsoleModifiers.Alt, ConsoleKey.B) -> + moveWordLeft() + change () + | (ConsoleModifiers.Control, ConsoleKey.RightArrow) + | (ConsoleModifiers.Alt, ConsoleKey.F) -> + moveWordRight() + change () + | (ConsoleModifiers.Control, ConsoleKey.K) -> deleteToEndOfLine() change() - // Control-P - | (ConsoleModifiers.Control, '\016') -> + | (ConsoleModifiers.Control,ConsoleKey.P) -> setInput(history.Previous()) change() - // Control-n - | (ConsoleModifiers.Control, '\014') -> + | (ConsoleModifiers.Control, ConsoleKey.N) -> setInput(history.Next()) change() - // Control-d - | (ConsoleModifiers.Control, '\004') -> + | (ConsoleModifiers.Control, ConsoleKey.D) -> if (input.Length = 0) then exit 0 //quit else delete() change() + | (ConsoleModifiers.Control, ConsoleKey.L) -> + clear() + change() + | (ConsoleModifiers.Control, ConsoleKey.U) -> + deleteFromStartOfLineToCursor() + change() + | (ConsoleModifiers.Control, ConsoleKey.W) -> + deleteWordLeadingToCursor() + change() | _ -> // Note: If KeyChar=0, the not a proper char, e.g. it could be part of a multi key-press character, // e.g. e-acute is ' and e with the French (Belgium) IME and US Intl KB. diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index cd43753ab50..ee962657ad1 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -2,13 +2,15 @@ module FSharp.Compiler.Interactive.Shell +// Prevents warnings of experimental APIs - we are using FSharpLexer +#nowarn "57" + #nowarn "55" [] -[] +[] do() - open System open System.Collections.Generic open System.Diagnostics @@ -18,69 +20,84 @@ open System.Text open System.Threading open System.Reflection open System.Runtime.CompilerServices -open System.Runtime.InteropServices -#if NETSTANDARD -open System.Runtime.Loader -#endif - +open Internal.Utilities +open Internal.Utilities.Collections +open Internal.Utilities.FSharpEnvironment +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.ILRuntimeWriter -open FSharp.Compiler.Lib open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOptions -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features -open FSharp.Compiler.InfoReader -open FSharp.Compiler.NameResolution open FSharp.Compiler.IlxGen +open FSharp.Compiler.InfoReader +open FSharp.Compiler.IO open FSharp.Compiler.Lexhelp -open FSharp.Compiler.Layout -open FSharp.Compiler.Range -open FSharp.Compiler.TypeChecker -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.NameResolution +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.OptimizeInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.ReferenceResolver - -open Internal.Utilities -open Internal.Utilities.StructuredFormat +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Xml +open FSharp.Compiler.Tokenization +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.BuildGraph //---------------------------------------------------------------------------- // For the FSI as a service methods... //---------------------------------------------------------------------------- -type FsiValue(reflectionValue:obj, reflectionType:Type, fsharpType:FSharpType) = +type FsiValue(reflectionValue:obj, reflectionType:Type, fsharpType:FSharpType) = member x.ReflectionValue = reflectionValue member x.ReflectionType = reflectionType member x.FSharpType = fsharpType +[] +type FsiBoundValue(name: string, value: FsiValue) = + member _.Name = name + member _.Value = value [] -module internal Utilities = - type IAnyToLayoutCall = - abstract AnyToLayout : FormatOptions * obj * Type -> Internal.Utilities.StructuredFormat.Layout - abstract FsiAnyToLayout : FormatOptions * obj * Type -> Internal.Utilities.StructuredFormat.Layout +module internal Utilities = + type IAnyToLayoutCall = + abstract AnyToLayout : FormatOptions * obj * Type -> Layout + abstract FsiAnyToLayout : FormatOptions * obj * Type -> Layout - type private AnyToLayoutSpecialization<'T>() = + type private AnyToLayoutSpecialization<'T>() = interface IAnyToLayoutCall with - member this.AnyToLayout(options, o : obj, ty : Type) = Internal.Utilities.StructuredFormat.Display.any_to_layout options ((Unchecked.unbox o : 'T), ty) - member this.FsiAnyToLayout(options, o : obj, ty : Type) = Internal.Utilities.StructuredFormat.Display.fsi_any_to_layout options ((Unchecked.unbox o : 'T), ty) - - let getAnyToLayoutCall ty = + member _.AnyToLayout(options, o : obj, ty : Type) = Display.any_to_layout options ((Unchecked.unbox o : 'T), ty) + member _.FsiAnyToLayout(options, o : obj, ty : Type) = Display.fsi_any_to_layout options ((Unchecked.unbox o : 'T), ty) + + let getAnyToLayoutCall ty = let specialized = typedefof>.MakeGenericType [| ty |] Activator.CreateInstance(specialized) :?> IAnyToLayoutCall let callStaticMethod (ty:Type) name args = - ty.InvokeMember(name, (BindingFlags.InvokeMethod ||| BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, null, Array.ofList args,Globalization.CultureInfo.InvariantCulture) + ty.InvokeMember(name, (BindingFlags.InvokeMethod ||| BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, null, Array.ofList args,CultureInfo.InvariantCulture) let ignoreAllErrors f = try f() with _ -> () @@ -98,7 +115,7 @@ module internal Utilities = match declaringType |> getMember name memberType bindingFlags with | [||] -> declaringType.GetInterfaces() |> Array.tryPick (tryFindMember name memberType) | [|m|] -> Some m - | _ -> raise <| new AmbiguousMatchException(sprintf "Ambiguous match for member '%s'" name) + | _ -> raise <| AmbiguousMatchException(sprintf "Ambiguous match for member '%s'" name) let getInstanceProperty (obj:obj) (nm:string) = let p = (tryFindMember nm MemberTypes.Property <| obj.GetType()).Value :?> PropertyInfo @@ -131,20 +148,20 @@ module internal Utilities = member r.AddText z s = let color = match s.Tag with - | LayoutTag.Keyword -> ConsoleColor.White - | LayoutTag.TypeParameter - | LayoutTag.Alias - | LayoutTag.Class - | LayoutTag.Module - | LayoutTag.Interface - | LayoutTag.Record - | LayoutTag.Struct - | LayoutTag.Union - | LayoutTag.UnknownType -> ConsoleColor.Cyan - | LayoutTag.UnionCase - | LayoutTag.ActivePatternCase -> ConsoleColor.Magenta - | LayoutTag.StringLiteral -> ConsoleColor.Yellow - | LayoutTag.NumericLiteral -> ConsoleColor.Green + | TextTag.Keyword -> ConsoleColor.White + | TextTag.TypeParameter + | TextTag.Alias + | TextTag.Class + | TextTag.Module + | TextTag.Interface + | TextTag.Record + | TextTag.Struct + | TextTag.Union + | TextTag.UnknownType -> ConsoleColor.Cyan + | TextTag.UnionCase + | TextTag.ActivePatternCase -> ConsoleColor.Magenta + | TextTag.StringLiteral -> ConsoleColor.Yellow + | TextTag.NumericLiteral -> ConsoleColor.Green | _ -> Console.ForegroundColor DoWithColor color (fun () -> outWriter.Write s.Text) @@ -164,39 +181,49 @@ module internal Utilities = } layout - |> Internal.Utilities.StructuredFormat.Display.squash_layout opts - |> Layout.renderL renderer + |> Display.squash_layout opts + |> LayoutRender.renderL renderer |> ignore outWriter.WriteLine() + let reportError m = + let report errorType err msg = + let error = err, msg + match errorType with + | ErrorReportType.Warning -> warning(Error(error, m)) + | ErrorReportType.Error -> errorR(Error(error, m)) + ResolvingErrorReport report + + let getOutputDir (tcConfigB: TcConfigBuilder) = tcConfigB.outputDir |> Option.defaultValue "" + //---------------------------------------------------------------------------- // Timing support //---------------------------------------------------------------------------- [] type internal FsiTimeReporter(outWriter: TextWriter) = - let stopwatch = new System.Diagnostics.Stopwatch() - let ptime = System.Diagnostics.Process.GetCurrentProcess() - let numGC = System.GC.MaxGeneration + let stopwatch = Stopwatch() + let ptime = Process.GetCurrentProcess() + let numGC = GC.MaxGeneration member tr.TimeOp(f) = let startTotal = ptime.TotalProcessorTime - let startGC = [| for i in 0 .. numGC -> System.GC.CollectionCount(i) |] + let startGC = [| for i in 0 .. numGC -> GC.CollectionCount(i) |] stopwatch.Reset() stopwatch.Start() let res = f () stopwatch.Stop() let total = ptime.TotalProcessorTime - startTotal - let spanGC = [ for i in 0 .. numGC-> System.GC.CollectionCount(i) - startGC.[i] ] - let elapsed = stopwatch.Elapsed + let spanGC = [ for i in 0 .. numGC-> GC.CollectionCount(i) - startGC.[i] ] + let elapsed = stopwatch.Elapsed fprintfn outWriter "%s" (FSIstrings.SR.fsiTimeInfoMainString((sprintf "%02d:%02d:%02d.%03d" (int elapsed.TotalHours) elapsed.Minutes elapsed.Seconds elapsed.Milliseconds),(sprintf "%02d:%02d:%02d.%03d" (int total.TotalHours) total.Minutes total.Seconds total.Milliseconds),(String.concat ", " (List.mapi (sprintf "%s%d: %d" (FSIstrings.SR.fsiTimeInfoGCGenerationLabelSomeShorthandForTheWordGeneration())) spanGC)))) res member tr.TimeOpIf flag f = if flag then tr.TimeOp f else f () -type internal FsiValuePrinterMode = - | PrintExpr +type internal FsiValuePrinterMode = + | PrintExpr | PrintDecl type EvaluationEventArgs(fsivalue : FsiValue option, symbolUse : FSharpSymbolUse, decl: FSharpImplementationFileDeclaration) = @@ -210,46 +237,46 @@ type EvaluationEventArgs(fsivalue : FsiValue option, symbolUse : FSharpSymbolUse [] /// User-configurable information that changes how F# Interactive operates, stored in the 'fsi' object /// and accessible via the programming model -type FsiEvaluationSessionHostConfig () = - let evaluationEvent = new Event () +type FsiEvaluationSessionHostConfig () = + let evaluationEvent = Event() /// Called by the evaluation session to ask the host for parameters to format text for output - abstract FormatProvider: System.IFormatProvider + abstract FormatProvider: IFormatProvider /// Called by the evaluation session to ask the host for parameters to format text for output - abstract FloatingPointFormat: string + abstract FloatingPointFormat: string /// Called by the evaluation session to ask the host for parameters to format text for output - abstract AddedPrinters : Choice<(System.Type * (obj -> string)), (System.Type * (obj -> obj))> list + abstract AddedPrinters : Choice string), Type * (obj -> obj)> list /// Called by the evaluation session to ask the host for parameters to format text for output - abstract ShowDeclarationValues: bool + abstract ShowDeclarationValues: bool /// Called by the evaluation session to ask the host for parameters to format text for output - abstract ShowIEnumerable: bool + abstract ShowIEnumerable: bool /// Called by the evaluation session to ask the host for parameters to format text for output - abstract ShowProperties : bool + abstract ShowProperties : bool /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintSize : int + abstract PrintSize : int /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintDepth : int + abstract PrintDepth : int /// Called by the evaluation session to ask the host for parameters to format text for output abstract PrintWidth : int /// Called by the evaluation session to ask the host for parameters to format text for output abstract PrintLength : int - /// The evaluation session calls this to report the preferred view of the command line arguments after + /// The evaluation session calls this to report the preferred view of the command line arguments after /// stripping things like "/use:file.fsx", "-r:Foo.dll" etc. abstract ReportUserCommandLineArgs : string [] -> unit - /// The evaluation session calls this to ask the host for the special console reader. + /// The evaluation session calls this to ask the host for the special console reader. /// Returning 'Some' indicates a console is to be used, so some special rules apply. /// - /// A "console" gets used if - /// --readline- is specified (the default on Windows + .NET); and - /// not --fsi-server (which should always be combined with --readline-); and + /// A "console" gets used if + /// --readline- is specified (the default on Windows + .NET); and + /// not --fsi-server (which should always be combined with --readline-); and /// GetOptionalConsoleReadLine() returns a Some /// /// "Peekahead" occurs if --peekahead- is not specified (i.e. it is the default): - /// - If a console is being used then - /// - a prompt is printed early - /// - a background thread is created + /// - If a console is being used then + /// - a prompt is printed early + /// - a background thread is created /// - the GetOptionalConsoleReadLine() callback is used to read the first line /// - Otherwise call inReader.Peek() /// @@ -257,11 +284,11 @@ type FsiEvaluationSessionHostConfig () = /// - If a console is being used then use GetOptionalConsoleReadLine() /// - Otherwise use inReader.ReadLine() - abstract GetOptionalConsoleReadLine : probeToSeeIfConsoleWorks: bool -> (unit -> string) option + abstract GetOptionalConsoleReadLine : probeToSeeIfConsoleWorks: bool -> (unit -> string) option /// The evaluation session calls this at an appropriate point in the startup phase if the --fsi-server parameter was given abstract StartServer : fsiServerName:string -> unit - + /// Called by the evaluation session to ask the host to enter a dispatch loop like Application.Run(). /// Only called if --gui option is used (which is the default). /// Gets called towards the end of startup and every time a ThreadAbort escaped to the backup driver loop. @@ -284,86 +311,86 @@ type FsiEvaluationSessionHostConfig () = /// Used to print value signatures along with their values, according to the current /// set of pretty printers installed in the system, and default printing rules. -type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, g: TcGlobals, generateDebugInfo, resolveAssemblyRef, outWriter: TextWriter) = +type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, tcConfigB: TcConfigBuilder, g: TcGlobals, generateDebugInfo, resolveAssemblyRef, outWriter: TextWriter) = /// This printer is used by F# Interactive if no other printers apply. - let DefaultPrintingIntercept (ienv: Internal.Utilities.StructuredFormat.IEnvironment) (obj:obj) = - match obj with - | null -> None + let DefaultPrintingIntercept (ienv: IEnvironment) (obj:obj) = + match obj with + | null -> None | :? System.Collections.IDictionary as ie -> - let it = ie.GetEnumerator() - try - let itemLs = - Internal.Utilities.StructuredFormat.LayoutOps.unfoldL // the function to layout each object in the unfold - (fun obj -> ienv.GetLayout obj) + let it = ie.GetEnumerator() + try + let itemLs = + unfoldL // the function to layout each object in the unfold + (fun obj -> ienv.GetLayout obj) // the function to call at each step of the unfold - (fun () -> - if it.MoveNext() then - Some((it.Key, it.Value),()) - else None) () + (fun () -> + if it.MoveNext() then + Some((it.Key, it.Value),()) + else None) () // the maximum length - (1+fsi.PrintLength/3) + (1+fsi.PrintLength/3) let makeListL itemLs = - (leftL (TaggedTextOps.tagText "[")) ^^ - sepListL (rightL (TaggedTextOps.tagText ";")) itemLs ^^ - (rightL (TaggedTextOps.tagText "]")) - Some(wordL (TaggedTextOps.tagText "dict") --- makeListL itemLs) + (leftL (TaggedText.tagText "[")) ^^ + sepListL (rightL (TaggedText.tagText ";")) itemLs ^^ + (rightL (TaggedText.tagText "]")) + Some(wordL (TaggedText.tagText "dict") --- makeListL itemLs) finally - match it with - | :? System.IDisposable as d -> d.Dispose() + match it with + | :? IDisposable as d -> d.Dispose() | _ -> () - - | _ -> None + + | _ -> None /// Get the print options used when formatting output using the structured printer. - member __.GetFsiPrintOptions() = - { Internal.Utilities.StructuredFormat.FormatOptions.Default with + member _.GetFsiPrintOptions() = + { FormatOptions.Default with FormatProvider = fsi.FormatProvider; - PrintIntercepts = + PrintIntercepts = // The fsi object supports the addition of two kinds of printers, one which converts to a string // and one which converts to another object that is recursively formatted. // The internal AddedPrinters reports these to FSI.EXE and we pick them up here to produce a layout - [ for x in fsi.AddedPrinters do - match x with - | Choice1Of2 (aty: System.Type, printer) -> + [ for x in fsi.AddedPrinters do + match x with + | Choice1Of2 (aty: Type, printer) -> yield (fun _ienv (obj:obj) -> - match obj with - | null -> None - | _ when aty.IsAssignableFrom(obj.GetType()) -> - match printer obj with + match obj with + | null -> None + | _ when aty.IsAssignableFrom(obj.GetType()) -> + match printer obj with | null -> None - | s -> Some (wordL (TaggedTextOps.tagText s)) + | s -> Some (wordL (TaggedText.tagText s)) | _ -> None) - - | Choice2Of2 (aty: System.Type, converter) -> + + | Choice2Of2 (aty: Type, converter) -> yield (fun ienv (obj:obj) -> - match obj with - | null -> None - | _ when aty.IsAssignableFrom(obj.GetType()) -> - match converter obj with + match obj with + | null -> None + | _ when aty.IsAssignableFrom(obj.GetType()) -> + match converter obj with | null -> None | res -> Some (ienv.GetLayout res) | _ -> None) yield DefaultPrintingIntercept]; FloatingPointFormat = fsi.FloatingPointFormat; - PrintWidth = fsi.PrintWidth; - PrintDepth = fsi.PrintDepth; + PrintWidth = fsi.PrintWidth; + PrintDepth = fsi.PrintDepth; PrintLength = fsi.PrintLength; PrintSize = fsi.PrintSize; ShowProperties = fsi.ShowProperties; ShowIEnumerable = fsi.ShowIEnumerable; } /// Get the evaluation context used when inverting the storage mapping of the ILRuntimeWriter. - member __.GetEvaluationContext emEnv = - let cenv = { ilg = g.ilg ; generatePdb = generateDebugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=g.TryFindSysILTypeRef } - { LookupFieldRef = ILRuntimeWriter.LookupFieldRef emEnv >> Option.get - LookupMethodRef = ILRuntimeWriter.LookupMethodRef emEnv >> Option.get - LookupTypeRef = ILRuntimeWriter.LookupTypeRef cenv emEnv - LookupType = ILRuntimeWriter.LookupType cenv emEnv } + member _.GetEvaluationContext emEnv = + let cenv = { ilg = g.ilg ; emitTailcalls= tcConfigB.emitTailcalls; generatePdb = generateDebugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=g.TryFindSysILTypeRef } + { LookupFieldRef = LookupFieldRef emEnv >> Option.get + LookupMethodRef = LookupMethodRef emEnv >> Option.get + LookupTypeRef = LookupTypeRef cenv emEnv + LookupType = LookupType cenv emEnv } /// Generate a layout for an actual F# value, where we know the value has the given static type. - member __.PrintValue (printMode, opts:FormatOptions, x:obj, ty:System.Type) = + member _.PrintValue (printMode, opts:FormatOptions, x:obj, ty:Type) = // We do a dynamic invoke of any_to_layout with the right System.Type parameter for the static type of the saved value. // In principle this helps any_to_layout do the right thing as it descends through terms. In practice it means // it at least does the right thing for top level 'null' list and option values (but not for nested ones). @@ -372,29 +399,29 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, g: TcGlobals, // RuntimeHelpers.SaveIt has type ('a -> unit), and fetches the System.Type for 'a by using a typeof<'a> call. // The funny thing here is that you might think that the driver (this file) knows more about the static types // than the compiled code does. But it doesn't! In particular, it's not that easy to get a System.Type value based on the - // static type information we do have: we have no direct way to bind a F# TAST type or even an AbstractIL type to + // static type information we do have: we have no direct way to bind a F# TAST type or even an AbstractIL type to // a System.Type value (I guess that functionality should be in ilreflect.fs). // // This will be more significant when we print values other then 'it' // - try - let anyToLayoutCall = Utilities.getAnyToLayoutCall ty + try + let anyToLayoutCall = getAnyToLayoutCall ty match printMode with | PrintDecl -> // When printing rhs of fsi declarations, use "fsi_any_to_layout". // This will suppress some less informative values, by returning an empty layout. [fix 4343]. anyToLayoutCall.FsiAnyToLayout(opts, x, ty) - | PrintExpr -> + | PrintExpr -> anyToLayoutCall.AnyToLayout(opts, x, ty) - with - | :? ThreadAbortException -> Layout.wordL (TaggedTextOps.tagText "") + with + | :? ThreadAbortException -> wordL (TaggedText.tagText "") | e -> #if DEBUG - printf "\n\nPrintValue: x = %+A and ty=%s\n" x (ty.FullName) + printf "\n\nPrintValue: x = %+A and ty=%s\n" x ty.FullName #endif - printf "%s" (FSIstrings.SR.fsiExceptionDuringPrettyPrinting(e.ToString())); - Layout.wordL (TaggedTextOps.tagText "") - + printf "%s" (FSIstrings.SR.fsiExceptionDuringPrettyPrinting(e.ToString())); + wordL (TaggedText.tagText "") + /// Display the signature of an F# value declaration, along with its actual value. member valuePrinter.InvokeDeclLayout (emEnv, ilxGenerator: IlxAssemblyGenerator, v:Val) = // Implemented via a lookup from v to a concrete (System.Object,System.Type). @@ -406,7 +433,7 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, g: TcGlobals, // Ilreflect knows what the AbsIL was generated to. // Combining these allows for obtaining the (obj,objTy) by reflection where possible. // This assumes the v:Val was given appropriate storage, e.g. StaticField. - if fsi.ShowDeclarationValues then + if fsi.ShowDeclarationValues && not v.LiteralValue.IsSome then // Adjust "opts" for printing for "declared-values": // - No sequences, because they may have effects or time cost. // - No properties, since they may have unexpected effects. @@ -414,69 +441,70 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, g: TcGlobals, // - Limit PrintSize which is a count on nodes. let declaredValueReductionFactor = 10 (* reduce PrintSize for declared values, e.g. see less of large terms *) let opts = valuePrinter.GetFsiPrintOptions() - let opts = {opts with ShowProperties = false // properties off, motivated by Form props - ShowIEnumerable = false // seq off, motivated by db query concerns - StringLimit = max 0 (opts.PrintWidth-4) // 4 allows for an indent of 2 and 2 quotes (rough) - PrintSize = opts.PrintSize / declaredValueReductionFactor } // print less - let res = + let opts = {opts with ShowProperties = false // properties off, motivated by Form props + ShowIEnumerable = false // seq off, motivated by db query concerns + StringLimit = max 0 (opts.PrintWidth-4) // 4 allows for an indent of 2 and 2 quotes (rough) + PrintSize = opts.PrintSize / declaredValueReductionFactor } // print less + let res = try ilxGenerator.LookupGeneratedValue (valuePrinter.GetEvaluationContext emEnv, v) - with e -> + with e -> assert false #if DEBUG //fprintfn fsiConsoleOutput.Out "lookGenerateVal: failed on v=%+A v.Name=%s" v v.LogicalName #endif - None // lookup may fail + None // lookup may fail match res with - | None -> None - | Some (obj,objTy) -> - let lay = valuePrinter.PrintValue (FsiValuePrinterMode.PrintDecl, opts, obj, objTy) - if isEmptyL lay then None else Some lay // suppress empty layout - + | None -> None + | Some (obj,objTy) -> + let lay = valuePrinter.PrintValue (FsiValuePrinterMode.PrintDecl, opts, obj, objTy) + if isEmptyL lay then None else Some lay // suppress empty layout + else None - - + + /// Format a value - member valuePrinter.FormatValue (obj:obj, objTy) = + member valuePrinter.FormatValue (obj:obj, objTy) = let opts = valuePrinter.GetFsiPrintOptions() let lay = valuePrinter.PrintValue (FsiValuePrinterMode.PrintExpr, opts, obj, objTy) - Internal.Utilities.StructuredFormat.Display.layout_to_string opts lay - + Display.layout_to_string opts lay + /// Fetch the saved value of an expression out of the 'it' register and show it. - member valuePrinter.InvokeExprPrinter (denv, emEnv, ilxGenerator: IlxAssemblyGenerator, vref) = + member valuePrinter.InvokeExprPrinter (denv, infoReader, emEnv, ilxGenerator: IlxAssemblyGenerator, vref: ValRef) = let opts = valuePrinter.GetFsiPrintOptions() - let res = ilxGenerator.LookupGeneratedValue (valuePrinter.GetEvaluationContext emEnv, vref) - let rhsL = + let res = ilxGenerator.LookupGeneratedValue (valuePrinter.GetEvaluationContext emEnv, vref.Deref) + let rhsL = match res with | None -> None - | Some (obj,objTy) -> + | Some (obj,objTy) -> let lay = valuePrinter.PrintValue (FsiValuePrinterMode.PrintExpr, opts, obj, objTy) - if isEmptyL lay then None else Some lay // suppress empty layout + if isEmptyL lay then None else Some lay // suppress empty layout let denv = { denv with suppressMutableKeyword = true } // suppress 'mutable' in 'val mutable it = ...' - let fullL = + let denv = { denv with suppressInlineKeyword = false } // dont' suppress 'inline' in 'val inline f = ...' + let fullL = if Option.isNone rhsL || isEmptyL rhsL.Value then - NicePrint.prettyLayoutOfValOrMemberNoInst denv vref (* the rhs was suppressed by the printer, so no value to print *) + NicePrint.prettyLayoutOfValOrMemberNoInst denv infoReader vref (* the rhs was suppressed by the printer, so no value to print *) else - (NicePrint.prettyLayoutOfValOrMemberNoInst denv vref ++ wordL (TaggedTextOps.tagText "=")) --- rhsL.Value + (NicePrint.prettyLayoutOfValOrMemberNoInst denv infoReader vref ++ wordL (TaggedText.tagText "=")) --- rhsL.Value - Utilities.colorPrintL outWriter opts fullL + colorPrintL outWriter opts fullL /// Used to make a copy of input in order to include the input when displaying the error text. -type internal FsiStdinSyphon(errorWriter: TextWriter) = - let syphonText = new StringBuilder() +type internal FsiStdinSyphon(errorWriter: TextWriter) = + let syphonText = StringBuilder() /// Clears the syphon text - member x.Reset () = + member x.Reset () = syphonText.Clear() |> ignore /// Adds a new line to the syphon text - member x.Add (str:string) = - syphonText.Append str |> ignore + member x.Add (str:string) = + syphonText.Append str |> ignore /// Gets the indicated line in the syphon text member x.GetLine filename i = - if filename <> Lexhelp.stdinMockFilename then - "" + if filename <> stdinMockFilename then + "" else let text = syphonText.ToString() // In Visual Studio, when sending a block of text, it prefixes with '# "filename"\n' @@ -491,65 +519,72 @@ type internal FsiStdinSyphon(errorWriter: TextWriter) = prune (text.Substring(idx + stdinReset.Length)) else text - + let text = prune text let lines = text.Split '\n' if 0 < i && i <= lines.Length then lines.[i-1] else "" /// Display the given error. - member syphon.PrintError (tcConfig:TcConfigBuilder, err) = - Utilities.ignoreAllErrors (fun () -> - let isError = true - DoWithErrorColor isError (fun () -> + member syphon.PrintError (tcConfig:TcConfigBuilder, err) = + ignoreAllErrors (fun () -> + let severity = FSharpDiagnosticSeverity.Error + DoWithDiagnosticColor severity (fun () -> errorWriter.WriteLine(); - writeViaBufferWithEnvironmentNewLines errorWriter (OutputDiagnosticContext " " syphon.GetLine) err; - writeViaBufferWithEnvironmentNewLines errorWriter (OutputDiagnostic (tcConfig.implicitIncludeDir,tcConfig.showFullPaths,tcConfig.flatErrors,tcConfig.errorStyle,isError)) err; + writeViaBuffer errorWriter (OutputDiagnosticContext " " syphon.GetLine) err; + writeViaBuffer errorWriter (OutputDiagnostic (tcConfig.implicitIncludeDir,tcConfig.showFullPaths,tcConfig.flatErrors,tcConfig.errorStyle,severity)) err; errorWriter.WriteLine() errorWriter.WriteLine() errorWriter.Flush())) - + /// Encapsulates functions used to write to outWriter and errorWriter -type internal FsiConsoleOutput(tcConfigB, outWriter:TextWriter, errorWriter:TextWriter) = +type internal FsiConsoleOutput(tcConfigB, outWriter:TextWriter, errorWriter:TextWriter) = let nullOut = new StreamWriter(Stream.Null) :> TextWriter - let fprintfnn (os: TextWriter) fmt = Printf.kfprintf (fun _ -> os.WriteLine(); os.WriteLine()) os fmt + let fprintfnn (os: TextWriter) fmt = Printf.kfprintf (fun _ -> os.WriteLine(); os.WriteLine()) os fmt /// uprintf to write usual responses to stdout (suppressed by --quiet), with various pre/post newlines - member out.uprintf fmt = fprintf (if tcConfigB.noFeedback then nullOut else outWriter) fmt + member out.uprintf fmt = fprintf (if tcConfigB.noFeedback then nullOut else outWriter) fmt member out.uprintfn fmt = fprintfn (if tcConfigB.noFeedback then nullOut else outWriter) fmt member out.uprintfnn fmt = fprintfnn (if tcConfigB.noFeedback then nullOut else outWriter) fmt member out.uprintnf fmt = out.uprintfn ""; out.uprintf fmt member out.uprintnfn fmt = out.uprintfn ""; out.uprintfn fmt member out.uprintnfnn fmt = out.uprintfn ""; out.uprintfnn fmt - + member out.Out = outWriter member out.Error = errorWriter /// This ErrorLogger reports all warnings, but raises StopProcessing on first error or early exit -type internal ErrorLoggerThatStopsOnFirstError(tcConfigB:TcConfigBuilder, fsiStdinSyphon:FsiStdinSyphon, fsiConsoleOutput: FsiConsoleOutput) = +type internal ErrorLoggerThatStopsOnFirstError(tcConfigB:TcConfigBuilder, fsiStdinSyphon:FsiStdinSyphon, fsiConsoleOutput: FsiConsoleOutput) = inherit ErrorLogger("ErrorLoggerThatStopsOnFirstError") - let mutable errorCount = 0 + let mutable errorCount = 0 - member x.SetError() = + member x.SetError() = errorCount <- 1 - member x.ResetErrorCount() = (errorCount <- 0) - - override x.DiagnosticSink(err, isError) = - if isError || ReportWarningAsError tcConfigB.errorSeverityOptions err then + member x.ResetErrorCount() = errorCount <- 0 + + override x.DiagnosticSink(err, severity) = + if ReportDiagnosticAsError tcConfigB.errorSeverityOptions (err, severity) then fsiStdinSyphon.PrintError(tcConfigB,err) errorCount <- errorCount + 1 if tcConfigB.abortOnError then exit 1 (* non-zero exit code *) // STOP ON FIRST ERROR (AVOIDS PARSER ERROR RECOVERY) raise StopProcessing - else - DoWithErrorColor isError (fun () -> - if ReportWarning tcConfigB.errorSeverityOptions err then + elif ReportDiagnosticAsWarning tcConfigB.errorSeverityOptions (err, severity) then + DoWithDiagnosticColor FSharpDiagnosticSeverity.Warning (fun () -> fsiConsoleOutput.Error.WriteLine() - writeViaBufferWithEnvironmentNewLines fsiConsoleOutput.Error (OutputDiagnosticContext " " fsiStdinSyphon.GetLine) err - writeViaBufferWithEnvironmentNewLines fsiConsoleOutput.Error (OutputDiagnostic (tcConfigB.implicitIncludeDir,tcConfigB.showFullPaths,tcConfigB.flatErrors,tcConfigB.errorStyle,isError)) err + writeViaBuffer fsiConsoleOutput.Error (OutputDiagnosticContext " " fsiStdinSyphon.GetLine) err + writeViaBuffer fsiConsoleOutput.Error (OutputDiagnostic (tcConfigB.implicitIncludeDir,tcConfigB.showFullPaths,tcConfigB.flatErrors,tcConfigB.errorStyle,severity)) err + fsiConsoleOutput.Error.WriteLine() + fsiConsoleOutput.Error.WriteLine() + fsiConsoleOutput.Error.Flush()) + elif ReportDiagnosticAsInfo tcConfigB.errorSeverityOptions (err, severity) then + DoWithDiagnosticColor FSharpDiagnosticSeverity.Info (fun () -> + fsiConsoleOutput.Error.WriteLine() + writeViaBuffer fsiConsoleOutput.Error (OutputDiagnosticContext " " fsiStdinSyphon.GetLine) err + writeViaBuffer fsiConsoleOutput.Error (OutputDiagnostic (tcConfigB.implicitIncludeDir,tcConfigB.showFullPaths,tcConfigB.flatErrors,tcConfigB.errorStyle,severity)) err fsiConsoleOutput.Error.WriteLine() fsiConsoleOutput.Error.WriteLine() fsiConsoleOutput.Error.Flush()) @@ -559,62 +594,81 @@ type internal ErrorLoggerThatStopsOnFirstError(tcConfigB:TcConfigBuilder, fsiStd type ErrorLogger with member x.CheckForErrors() = (x.ErrorCount > 0) /// A helper function to check if its time to abort - member x.AbortOnError(fsiConsoleOutput:FsiConsoleOutput) = - if x.ErrorCount > 0 then + member x.AbortOnError(fsiConsoleOutput:FsiConsoleOutput) = + if x.ErrorCount > 0 then fprintf fsiConsoleOutput.Error "%s" (FSIstrings.SR.stoppedDueToError()) fsiConsoleOutput.Error.Flush() raise StopProcessing /// Get the directory name from a string, with some defaults if it doesn't have one -let internal directoryName (s:string) = +let internal directoryName (s:string) = if s = "" then "." - else - match Path.GetDirectoryName s with + else + match Path.GetDirectoryName s with | null -> if FileSystem.IsPathRootedShim s then s else "." | res -> if res = "" then "." else res - - //---------------------------------------------------------------------------- // cmd line - state for options //---------------------------------------------------------------------------- -/// Process the command line options -type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: string[], tcConfigB, fsiConsoleOutput: FsiConsoleOutput) = - let mutable enableConsoleKeyProcessing = +/// Process the command line options +type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, + argv: string[], + tcConfigB, + fsiConsoleOutput: FsiConsoleOutput) = + + let mutable enableConsoleKeyProcessing = // Mono on Win32 doesn't implement correct console processing - not (runningOnMono && System.Environment.OSVersion.Platform = System.PlatformID.Win32NT) + not (runningOnMono && Environment.OSVersion.Platform = PlatformID.Win32NT) let mutable gui = not runningOnMono // override via "--gui", on by default except when on Mono #if DEBUG - let mutable showILCode = false // show modul il code + let mutable showILCode = false // show modul il code #endif let mutable showTypes = true // show types after each interaction? let mutable fsiServerName = "" let mutable interact = true let mutable explicitArgs = [] + let mutable writeReferencesAndExit = None - let mutable inputFilesAcc = [] + let mutable inputFilesAcc = [] let mutable fsiServerInputCodePage = None let mutable fsiServerOutputCodePage = None let mutable fsiLCID = None - // internal options - let mutable probeToSeeIfConsoleWorks = true - let mutable peekAheadOnConsoleToPermitTyping = true + // internal options + let mutable probeToSeeIfConsoleWorks = true + let mutable peekAheadOnConsoleToPermitTyping = true - let isInteractiveServer() = fsiServerName <> "" + let isInteractiveServer() = fsiServerName <> "" let recordExplicitArg arg = explicitArgs <- explicitArgs @ [arg] - let executableFileName = - lazy - match tcConfigB.exename with - | Some s -> s - | None -> - let currentProcess = System.Diagnostics.Process.GetCurrentProcess() - Path.GetFileName(currentProcess.MainModule.FileName) + let executableFileNameWithoutExtension = + lazy + let getFsiCommandLine () = + let fileNameWithoutExtension path = Path.GetFileNameWithoutExtension(path) + + let currentProcess = Process.GetCurrentProcess() + let processFileName = fileNameWithoutExtension currentProcess.MainModule.FileName + + let commandLineExecutableFileName = + try fileNameWithoutExtension (Environment.GetCommandLineArgs().[0]) + with _ -> "" + + let stringComparison = + match Environment.OSVersion.Platform with + | PlatformID.MacOSX + | PlatformID.Unix -> StringComparison.Ordinal + | _ -> StringComparison.OrdinalIgnoreCase + + if String.Compare(processFileName, commandLineExecutableFileName, stringComparison) = 0 + then processFileName + else sprintf "%s %s" processFileName commandLineExecutableFileName + + tcConfigB.exename |> Option.defaultWith getFsiCommandLine // Additional fsi options are list below. @@ -623,14 +677,14 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s let displayHelpFsi tcConfigB (blocks:CompilerOptionBlock list) = DisplayBannerText tcConfigB; fprintfn fsiConsoleOutput.Out "" - fprintfn fsiConsoleOutput.Out "%s" (FSIstrings.SR.fsiUsage(executableFileName.Value)) + fprintfn fsiConsoleOutput.Out "%s" (FSIstrings.SR.fsiUsage(executableFileNameWithoutExtension.Value)) PrintCompilerOptionBlocks blocks exit 0 // option tags let tagFile = "" let tagNone = "" - + /// These options precede the FsiCoreCompilerOptions in the help blocks let fsiUsagePrefix tcConfigB = [PublicOptions(FSIstrings.SR.fsiInputFiles(), @@ -645,14 +699,15 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s PublicOptions(FSIstrings.SR.fsiMiscellaneous(),[]); PublicOptions(FSIstrings.SR.fsiAdvanced(),[]); PrivateOptions( - [// Make internal fsi-server* options. Do not print in the help. They are used by VFSI. + [// Make internal fsi-server* options. Do not print in the help. They are used by VFSI. + CompilerOption("fsi-server-report-references","", OptionString (fun s -> writeReferencesAndExit <- Some s), None, None); CompilerOption("fsi-server","", OptionString (fun s -> fsiServerName <- s), None, None); // "FSI server mode on given named channel"); - CompilerOption("fsi-server-input-codepage","",OptionInt (fun n -> fsiServerInputCodePage <- Some(n)), None, None); // " Set the input codepage for the console"); - CompilerOption("fsi-server-output-codepage","",OptionInt (fun n -> fsiServerOutputCodePage <- Some(n)), None, None); // " Set the output codepage for the console"); + CompilerOption("fsi-server-input-codepage","",OptionInt (fun n -> fsiServerInputCodePage <- Some(n)), None, None); // " Set the input codepage for the console"); + CompilerOption("fsi-server-output-codepage","",OptionInt (fun n -> fsiServerOutputCodePage <- Some(n)), None, None); // " Set the output codepage for the console"); CompilerOption("fsi-server-no-unicode","", OptionUnit (fun () -> fsiServerOutputCodePage <- None; fsiServerInputCodePage <- None), None, None); // "Do not set the codepages for the console"); CompilerOption("fsi-server-lcid","", OptionInt (fun n -> fsiLCID <- Some(n)), None, None); // "LCID from Visual Studio" - // We do not want to print the "script.fsx arg2..." as part of the options + // We do not want to print the "script.fsx arg2..." as part of the options CompilerOption("script.fsx arg1 arg2 ...","", OptionGeneral((fun args -> args.Length > 0 && IsScript args.[0]), (fun args -> let scriptFile = args.[0] @@ -667,7 +722,7 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s ]); PrivateOptions( [ - // Private options, related to diagnostics around console probing + // Private options, related to diagnostics around console probing CompilerOption("probeconsole","", OptionSwitch (fun flag -> probeToSeeIfConsoleWorks <- flag=OptionSwitch.On), None, None); // "Probe to see if Console looks functional"); CompilerOption("peekahead","", OptionSwitch (fun flag -> peekAheadOnConsoleToPermitTyping <- flag=OptionSwitch.On), None, None); // "Probe to see if Console looks functional"); @@ -684,20 +739,19 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s [CompilerOption("--","", OptionRest recordExplicitArg, None, Some (FSIstrings.SR.fsiRemaining())); ]); - PublicOptions(FSComp.SR.optsHelpBannerMisc(), - [ CompilerOption("help", tagNone, - OptionHelp (fun blocks -> displayHelpFsi tcConfigB blocks),None, - Some (FSIstrings.SR.fsiHelp())) + PublicOptions(FSComp.SR.optsHelpBannerMisc(), + [ CompilerOption("help", tagNone, + OptionHelp (displayHelpFsi tcConfigB), None, Some (FSIstrings.SR.fsiHelp())) ]); PrivateOptions( - [ CompilerOption("?", tagNone, OptionHelp (fun blocks -> displayHelpFsi tcConfigB blocks), None, None); // "Short form of --help"); - CompilerOption("help", tagNone, OptionHelp (fun blocks -> displayHelpFsi tcConfigB blocks), None, None); // "Short form of --help"); - CompilerOption("full-help", tagNone, OptionHelp (fun blocks -> displayHelpFsi tcConfigB blocks), None, None); // "Short form of --help"); + [ CompilerOption("?", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); + CompilerOption("help", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); + CompilerOption("full-help", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); ]); PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), [CompilerOption("exec", "", OptionUnit (fun () -> interact <- false), None, Some (FSIstrings.SR.fsiExec())); CompilerOption("gui", tagNone, OptionSwitch(fun flag -> gui <- (flag = OptionSwitch.On)),None,Some (FSIstrings.SR.fsiGui())); - CompilerOption("quiet", "", OptionUnit (fun () -> tcConfigB.noFeedback <- true), None,Some (FSIstrings.SR.fsiQuiet())); + CompilerOption("quiet", "", OptionUnit (fun () -> tcConfigB.noFeedback <- true), None,Some (FSIstrings.SR.fsiQuiet())); (* Renamed --readline and --no-readline to --tabcompletion:+|- *) CompilerOption("readline", tagNone, OptionSwitch(fun flag -> enableConsoleKeyProcessing <- (flag = OptionSwitch.On)), None, Some(FSIstrings.SR.fsiReadline())); CompilerOption("quotations-debug", tagNone, OptionSwitch(fun switch -> tcConfigB.emitDebugInfoInQuotations <- switch = OptionSwitch.On),None, Some(FSIstrings.SR.fsiEmitDebugInfoInQuotations())); @@ -707,13 +761,13 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s /// Process command line, flags and collect filenames. - /// The ParseCompilerOptions function calls imperative function to process "real" args - /// Rather than start processing, just collect names, then process them. - let sourceFiles = - let collect name = - let fsx = CompileOps.IsScript name + /// The ParseCompilerOptions function calls imperative function to process "real" args + /// Rather than start processing, just collect names, then process them. + let sourceFiles = + let collect name = + let fsx = IsScript name inputFilesAcc <- inputFilesAcc @ [(name,fsx)] // O(n^2), but n small... - try + try let fsiCompilerOptions = fsiUsagePrefix tcConfigB @ GetCoreFsiCompilerOptions tcConfigB @ fsiUsageSuffix tcConfigB let abbrevArgs = GetAbbrevFlagSet tcConfigB false ParseCompilerOptions (collect, fsiCompilerOptions, List.tail (PostProcessCompilerArgs abbrevArgs argv)) @@ -721,21 +775,24 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s stopProcessingRecovery e range0; failwithf "Error creating evaluation session: %A" e inputFilesAcc - do + // We need a dependency provider with native resolution. Managed resolution is handled by generated `#r` + let dependencyProvider = new DependencyProvider(NativeResolutionProbe(tcConfigB.GetNativeProbingRoots)) + + do if tcConfigB.utf8output then let prev = Console.OutputEncoding - Console.OutputEncoding <- System.Text.Encoding.UTF8 + Console.OutputEncoding <- Encoding.UTF8 #if FX_NO_APP_DOMAINS ignore prev #else System.AppDomain.CurrentDomain.ProcessExit.Add(fun _ -> Console.OutputEncoding <- prev) #endif - do - let firstArg = - match sourceFiles with - | [] -> argv.[0] + do + let firstArg = + match sourceFiles with + | [] -> argv.[0] | _ -> fst (List.head (List.rev sourceFiles) ) - let args = Array.ofList (firstArg :: explicitArgs) + let args = Array.ofList (firstArg :: explicitArgs) fsi.ReportUserCommandLineArgs args @@ -743,50 +800,62 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, argv: s // Banner //---------------------------------------------------------------------------- - member __.ShowBanner() = - fsiConsoleOutput.uprintnfn "%s" (tcConfigB.productNameForBannerText) + member _.ShowBanner() = + fsiConsoleOutput.uprintnfn "%s" tcConfigB.productNameForBannerText fsiConsoleOutput.uprintfnn "%s" (FSComp.SR.optsCopyright()) fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiBanner3()) - - member __.ShowHelp() = - let helpLine = sprintf "%s --help" (Path.GetFileNameWithoutExtension executableFileName.Value) + + member _.ShowHelp(m) = + let helpLine = sprintf "%s --help" executableFileNameWithoutExtension.Value fsiConsoleOutput.uprintfn "" - fsiConsoleOutput.uprintfnn "%s" (FSIstrings.SR.fsiIntroTextHeader1directives()); - fsiConsoleOutput.uprintfn " #r \"file.dll\";; %s" (FSIstrings.SR.fsiIntroTextHashrInfo()); - fsiConsoleOutput.uprintfn " #I \"path\";; %s" (FSIstrings.SR.fsiIntroTextHashIInfo()); - fsiConsoleOutput.uprintfn " #load \"file.fs\" ...;; %s" (FSIstrings.SR.fsiIntroTextHashloadInfo()); - fsiConsoleOutput.uprintfn " #time [\"on\"|\"off\"];; %s" (FSIstrings.SR.fsiIntroTextHashtimeInfo()); - fsiConsoleOutput.uprintfn " #help;; %s" (FSIstrings.SR.fsiIntroTextHashhelpInfo()); - fsiConsoleOutput.uprintfn " #quit;; %s" (FSIstrings.SR.fsiIntroTextHashquitInfo()); (* last thing you want to do, last thing in the list - stands out more *) + fsiConsoleOutput.uprintfnn "%s" (FSIstrings.SR.fsiIntroTextHeader1directives()) + fsiConsoleOutput.uprintfn """ #r "file.dll";; // %s""" (FSIstrings.SR.fsiIntroTextHashrInfo()) + fsiConsoleOutput.uprintfn """ #i "package source uri";; // %s""" (FSIstrings.SR.fsiIntroPackageSourceUriInfo()) + fsiConsoleOutput.uprintfn """ #I "path";; // %s""" (FSIstrings.SR.fsiIntroTextHashIInfo()) + fsiConsoleOutput.uprintfn """ #load "file.fs" ...;; // %s""" (FSIstrings.SR.fsiIntroTextHashloadInfo()) + fsiConsoleOutput.uprintfn """ #time ["on"|"off"];; // %s""" (FSIstrings.SR.fsiIntroTextHashtimeInfo()) + fsiConsoleOutput.uprintfn """ #help;; // %s""" (FSIstrings.SR.fsiIntroTextHashhelpInfo()) + + if tcConfigB.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then + for msg in dependencyProvider.GetRegisteredDependencyManagerHelpText(tcConfigB.compilerToolPaths, getOutputDir tcConfigB, reportError m) do + fsiConsoleOutput.uprintfn "%s" msg + + fsiConsoleOutput.uprintfn """ #quit;; // %s""" (FSIstrings.SR.fsiIntroTextHashquitInfo()) (* last thing you want to do, last thing in the list - stands out more *) fsiConsoleOutput.uprintfn ""; - fsiConsoleOutput.uprintfnn "%s" (FSIstrings.SR.fsiIntroTextHeader2commandLine()); - fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiIntroTextHeader3(helpLine)); - fsiConsoleOutput.uprintfn ""; - fsiConsoleOutput.uprintfn ""; + fsiConsoleOutput.uprintfnn "%s" (FSIstrings.SR.fsiIntroTextHeader2commandLine()) + fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiIntroTextHeader3(helpLine)) + fsiConsoleOutput.uprintfn "" + fsiConsoleOutput.uprintfn "" #if DEBUG - member __.ShowILCode with get() = showILCode and set v = showILCode <- v + member _.ShowILCode with get() = showILCode and set v = showILCode <- v #endif - member __.ShowTypes with get() = showTypes and set v = showTypes <- v - member __.FsiServerName = fsiServerName - member __.FsiServerInputCodePage = fsiServerInputCodePage - member __.FsiServerOutputCodePage = fsiServerOutputCodePage - member __.FsiLCID with get() = fsiLCID and set v = fsiLCID <- v - member __.IsInteractiveServer = isInteractiveServer() - member __.ProbeToSeeIfConsoleWorks = probeToSeeIfConsoleWorks - member __.EnableConsoleKeyProcessing = enableConsoleKeyProcessing - - member __.Interact = interact - member __.PeekAheadOnConsoleToPermitTyping = peekAheadOnConsoleToPermitTyping - member __.SourceFiles = sourceFiles - member __.Gui = gui + member _.ShowTypes with get() = showTypes and set v = showTypes <- v + member _.FsiServerName = fsiServerName + member _.FsiServerInputCodePage = fsiServerInputCodePage + member _.FsiServerOutputCodePage = fsiServerOutputCodePage + member _.FsiLCID with get() = fsiLCID and set v = fsiLCID <- v + member _.UseServerPrompt = isInteractiveServer() + member _.IsInteractiveServer = isInteractiveServer() + member _.ProbeToSeeIfConsoleWorks = probeToSeeIfConsoleWorks + member _.EnableConsoleKeyProcessing = enableConsoleKeyProcessing + + member _.Interact = interact + member _.PeekAheadOnConsoleToPermitTyping = peekAheadOnConsoleToPermitTyping + member _.SourceFiles = sourceFiles + member _.Gui = gui + + member _.WriteReferencesAndExit = writeReferencesAndExit + + member _.DependencyProvider = dependencyProvider + member _.FxResolver = tcConfigB.FxResolver /// Set the current ui culture for the current thread. let internal SetCurrentUICultureForThread (lcid : int option) = let culture = Thread.CurrentThread.CurrentUICulture match lcid with - | Some n -> Thread.CurrentThread.CurrentUICulture <- new CultureInfo(n) + | Some n -> Thread.CurrentThread.CurrentUICulture <- CultureInfo(n) | None -> () { new IDisposable with member x.Dispose() = Thread.CurrentThread.CurrentUICulture <- culture } @@ -799,33 +868,33 @@ let internal InstallErrorLoggingOnThisThread errorLogger = SetThreadErrorLoggerNoUnwind(errorLogger) SetThreadBuildPhaseNoUnwind(BuildPhase.Interactive) -/// Set the input/output encoding. The use of a thread is due to a known bug on +/// Set the input/output encoding. The use of a thread is due to a known bug on /// on Vista where calls to Console.InputEncoding can block the process. -let internal SetServerCodePages(fsiOptions: FsiCommandLineOptions) = - match fsiOptions.FsiServerInputCodePage, fsiOptions.FsiServerOutputCodePage with +let internal SetServerCodePages(fsiOptions: FsiCommandLineOptions) = + match fsiOptions.FsiServerInputCodePage, fsiOptions.FsiServerOutputCodePage with | None,None -> () - | inputCodePageOpt,outputCodePageOpt -> - let mutable successful = false - Async.Start (async { do match inputCodePageOpt with - | None -> () + | inputCodePageOpt,outputCodePageOpt -> + let mutable successful = false + Async.Start (async { do match inputCodePageOpt with + | None -> () | Some(n:int) -> - let encoding = System.Text.Encoding.GetEncoding(n) + let encoding = Encoding.GetEncoding(n) // Note this modifies the real honest-to-goodness settings for the current shell. // and the modifications hang around even after the process has exited. Console.InputEncoding <- encoding - do match outputCodePageOpt with - | None -> () - | Some(n:int) -> - let encoding = System.Text.Encoding.GetEncoding n + do match outputCodePageOpt with + | None -> () + | Some(n:int) -> + let encoding = Encoding.GetEncoding n // Note this modifies the real honest-to-goodness settings for the current shell. // and the modifications hang around even after the process has exited. Console.OutputEncoding <- encoding do successful <- true }); - for pause in [10;50;100;1000;2000;10000] do - if not successful then + for pause in [10;50;100;1000;2000;10000] do + if not successful then Thread.Sleep(pause); #if LOGGING_GUI - if not !successful then + if not !successful then System.Windows.Forms.MessageBox.Show(FSIstrings.SR.fsiConsoleProblem()) |> ignore #endif @@ -838,14 +907,14 @@ type internal FsiConsolePrompt(fsiOptions: FsiCommandLineOptions, fsiConsoleOutp // A prompt gets "printed ahead" at start up. Tells users to start type while initialisation completes. // A prompt can be skipped by "silent directives", e.g. ones sent to FSI by VS. let mutable dropPrompt = 0 - // NOTE: SERVER-PROMPT is not user displayed, rather it's a prefix that code elsewhere + // NOTE: SERVER-PROMPT is not user displayed, rather it's a prefix that code elsewhere // uses to identify the prompt, see service\FsPkgs\FSharp.VS.FSI\fsiSessionToolWindow.fs - let prompt = if fsiOptions.IsInteractiveServer then "SERVER-PROMPT>\n" else "> " + let prompt = if fsiOptions.UseServerPrompt then "SERVER-PROMPT>\n" else "> " - member __.Print() = if dropPrompt = 0 then fsiConsoleOutput.uprintf "%s" prompt else dropPrompt <- dropPrompt - 1 - member __.PrintAhead() = dropPrompt <- dropPrompt + 1; fsiConsoleOutput.uprintf "%s" prompt - member __.SkipNext() = dropPrompt <- dropPrompt + 1 - member __.FsiOptions = fsiOptions + member _.Print() = if dropPrompt = 0 then fsiConsoleOutput.uprintf "%s" prompt else dropPrompt <- dropPrompt - 1 + member _.PrintAhead() = dropPrompt <- dropPrompt + 1; fsiConsoleOutput.uprintf "%s" prompt + member _.SkipNext() = dropPrompt <- dropPrompt + 1 + member _.FsiOptions = fsiOptions @@ -863,7 +932,7 @@ type internal FsiConsoleInput(fsi: FsiEvaluationSessionHostConfig, fsiOptions: F None // When VFSI is running, there should be no "console", and in particular the console.fs readline code should not to run. - do if fsiOptions.IsInteractiveServer then assert(consoleOpt.IsNone) + do if fsiOptions.IsInteractiveServer then assert consoleOpt.IsNone /// This threading event gets set after the first-line-reader has finished its work let consoleReaderStartupDone = new ManualResetEvent(false) @@ -873,65 +942,143 @@ type internal FsiConsoleInput(fsi: FsiEvaluationSessionHostConfig, fsiOptions: F /// Peek on the standard input so that the user can type into it from a console window. do if fsiOptions.Interact then - if fsiOptions.PeekAheadOnConsoleToPermitTyping then - (new Thread(fun () -> - match consoleOpt with - | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.IsInteractiveServer -> - if List.isEmpty fsiOptions.SourceFiles then + if fsiOptions.PeekAheadOnConsoleToPermitTyping then + (Thread(fun () -> + match consoleOpt with + | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.UseServerPrompt -> + if List.isEmpty fsiOptions.SourceFiles then if progress then fprintfn outWriter "first-line-reader-thread reading first line..."; - firstLine <- Some(console()); + firstLine <- Some(console()); if progress then fprintfn outWriter "first-line-reader-thread got first line = %A..." firstLine; - consoleReaderStartupDone.Set() |> ignore + consoleReaderStartupDone.Set() |> ignore if progress then fprintfn outWriter "first-line-reader-thread has set signal and exited." ; - | _ -> + | _ -> ignore(inReader.Peek()); - consoleReaderStartupDone.Set() |> ignore + consoleReaderStartupDone.Set() |> ignore )).Start() else if progress then fprintfn outWriter "first-line-reader-thread not in use." consoleReaderStartupDone.Set() |> ignore /// Try to get the first line, if we snarfed it while probing. - member __.TryGetFirstLine() = let r = firstLine in firstLine <- None; r + member _.TryGetFirstLine() = let r = firstLine in firstLine <- None; r /// Try to get the console, if it appears operational. - member __.TryGetConsole() = consoleOpt + member _.TryGetConsole() = consoleOpt - member __.In = inReader + member _.In = inReader + + member _.WaitForInitialConsoleInput() = WaitHandle.WaitAll [| consoleReaderStartupDone |] |> ignore; - member __.WaitForInitialConsoleInput() = WaitHandle.WaitAll [| consoleReaderStartupDone |] |> ignore; - //---------------------------------------------------------------------------- // FsiDynamicCompilerState //---------------------------------------------------------------------------- -type internal FsiInteractionStepStatus = - | CtrlC - | EndOfFile +type internal FsiInteractionStepStatus = + | CtrlC + | EndOfFile | Completed of option - | CompletedWithReportedError of exn + | CompletedWithAlreadyReportedError + | CompletedWithReportedError of exn [] [] type internal FsiDynamicCompilerState = { optEnv : Optimizer.IncrementalOptimizationEnv - emEnv : ILRuntimeWriter.emEnv + emEnv : emEnv tcGlobals : TcGlobals - tcState : TcState + tcState : TcState tcImports : TcImports - ilxGenerator : IlxGen.IlxAssemblyGenerator + ilxGenerator : IlxAssemblyGenerator + boundValues : NameMap // Why is this not in FsiOptions? timing : bool debugBreak : bool } -let internal WithImplicitHome (tcConfigB, dir) f = - let old = tcConfigB.implicitIncludeDir +let internal WithImplicitHome (tcConfigB, dir) f = + let old = tcConfigB.implicitIncludeDir tcConfigB.implicitIncludeDir <- dir; - try f() + try f() finally tcConfigB.implicitIncludeDir <- old +let internal convertReflectionTypeToILTypeRef (reflectionTy: Type) = + if reflectionTy.Assembly.IsDynamic then + raise (NotSupportedException(sprintf "Unable to import type, %A, from a dynamic assembly." reflectionTy)) + + if not reflectionTy.IsPublic && not reflectionTy.IsNestedPublic then + invalidOp (sprintf "Cannot import the non-public type, %A." reflectionTy) + let aref = ILAssemblyRef.FromAssemblyName(reflectionTy.Assembly.GetName()) + let scoref = ILScopeRef.Assembly aref + + let fullName = reflectionTy.FullName + let index = fullName.IndexOf("[") + let fullName = + if index = -1 then + fullName + else + fullName.Substring(0, index) + + let isTop = reflectionTy.DeclaringType = null + if isTop then + ILTypeRef.Create(scoref, [], fullName) + else + let names = String.split StringSplitOptions.None [|"+";"."|] fullName + let enc = names.[..names.Length - 2] + let nm = names.[names.Length - 1] + ILTypeRef.Create(scoref, List.ofArray enc, nm) + +let rec internal convertReflectionTypeToILType (reflectionTy: Type) = + let reflectionTy = + // Special case functions. + if FSharp.Reflection.FSharpType.IsFunction reflectionTy then + let ctors = reflectionTy.GetConstructors(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance) + if ctors.Length = 1 && + ctors.[0].GetCustomAttribute() <> null && + not ctors.[0].IsPublic && + IsCompilerGeneratedName reflectionTy.Name then + let rec get (typ: Type) = if FSharp.Reflection.FSharpType.IsFunction typ.BaseType then get typ.BaseType else typ + get reflectionTy + else + reflectionTy + else + reflectionTy + + let tref = convertReflectionTypeToILTypeRef reflectionTy + let genericArgs = + reflectionTy.GenericTypeArguments + |> Seq.map convertReflectionTypeToILType + |> List.ofSeq + + let boxity = + if reflectionTy.IsValueType then + ILBoxity.AsValue + else + ILBoxity.AsObject + + let tspec = ILTypeSpec.Create(tref, genericArgs) + + mkILTy boxity tspec + +let internal mkBoundValueTypedImpl tcGlobals m moduleName name ty = + let vis = Accessibility.TAccess([]) + let compPath = (CompilationPath.CompPath(ILScopeRef.Local, [])) + let mutable mty = Unchecked.defaultof<_> + let moduleOrNamespace = Construct.NewModuleOrNamespace (Some compPath) vis (Ident(moduleName, m)) XmlDoc.Empty [] (MaybeLazy.Lazy(lazy mty)) + let v = + Construct.NewVal + (name, m, None, ty, ValMutability.Immutable, + false, Some(ValReprInfo([], [], { Attribs = []; Name = None })), vis, ValNotInRecScope, None, NormalVal, [], ValInline.Optional, + XmlDoc.Empty, true, false, false, false, + false, false, None, Parent(TypedTreeBasics.ERefLocal moduleOrNamespace)) + mty <- ModuleOrNamespaceType(ModuleOrNamespaceKind.ModuleOrType, QueueList.one v, QueueList.empty) + + let bindExpr = mkCallDefaultOf tcGlobals range0 ty + let binding = Binding.TBind(v, bindExpr, DebugPointAtBinding.NoneAtLet) + let mbinding = ModuleOrNamespaceBinding.Module(moduleOrNamespace, TMDefs([TMDefLet(binding, m)])) + let expr = ModuleOrNamespaceExprWithSig(mty, TMDefs([TMDefs[TMDefRec(false, [], [], [mbinding], m)]]), range0) + moduleOrNamespace, v, TypedImplFile.TImplFile(QualifiedNameOfFile.QualifiedNameOfFile(Ident(moduleName, m)), [], expr, false, false, StampMap.Empty) /// Encapsulates the coordination of the typechecking, optimization and code generation /// components of the F# compiler for interactively executed fragments of code. @@ -939,109 +1086,74 @@ let internal WithImplicitHome (tcConfigB, dir) f = /// A single instance of this object is created per interactive session. type internal FsiDynamicCompiler (fsi: FsiEvaluationSessionHostConfig, - timeReporter : FsiTimeReporter, - tcConfigB: TcConfigBuilder, - tcLockObject : obj, + timeReporter : FsiTimeReporter, + tcConfigB: TcConfigBuilder, + tcLockObject : obj, outWriter: TextWriter, - tcImports: TcImports, - tcGlobals: TcGlobals, + tcImports: TcImports, + tcGlobals: TcGlobals, fsiOptions : FsiCommandLineOptions, fsiConsoleOutput : FsiConsoleOutput, fsiCollectible: bool, niceNameGen, - resolveAssemblyRef) = + resolveAssemblyRef) = let ilGlobals = tcGlobals.ilg let outfile = "TMPFSCI.exe" let assemblyName = "FSI-ASSEMBLY" - let assemblyReferenceAddedEvent = Control.Event() let valueBoundEvent = Control.Event<_>() - let dependencyAddingEvent = Control.Event() - let dependencyAddedEvent = Control.Event() - let dependencyFailedEvent = Control.Event() let mutable fragmentId = 0 let mutable prevIt : ValRef option = None let mutable needsPackageResolution = false - let mutable subscribedDependencyManagers = HashSet() - let generateDebugInfo = tcConfigB.debuginfo - let valuePrinter = FsiValuePrinter(fsi, tcGlobals, generateDebugInfo, resolveAssemblyRef, outWriter) + let valuePrinter = FsiValuePrinter(fsi, tcConfigB, tcGlobals, generateDebugInfo, resolveAssemblyRef, outWriter) - let assemblyBuilder,moduleBuilder = ILRuntimeWriter.mkDynamicAssemblyAndModule (assemblyName, tcConfigB.optSettings.localOpt(), generateDebugInfo, fsiCollectible) + let assemblyBuilder,moduleBuilder = mkDynamicAssemblyAndModule (assemblyName, tcConfigB.optSettings.LocalOptimizationsEnabled, generateDebugInfo, fsiCollectible) - let rangeStdin = rangeN Lexhelp.stdinMockFilename 0 + let rangeStdin = rangeN stdinMockFilename 0 //let _writer = moduleBuilder.GetSymWriter() - let infoReader = InfoReader(tcGlobals,tcImports.GetImportMap()) + let infoReader = InfoReader(tcGlobals,tcImports.GetImportMap()) - /// Add attributes + /// Add attributes let CreateModuleFragment (tcConfigB: TcConfigBuilder, assemblyName, codegenResults) = if progress then fprintfn fsiConsoleOutput.Out "Creating main module..."; let mainModule = mkILSimpleModule assemblyName (GetGeneratedILModuleName tcConfigB.target assemblyName) (tcConfigB.target = CompilerTarget.Dll) tcConfigB.subsystemVersion tcConfigB.useHighEntropyVA (mkILTypeDefs codegenResults.ilTypeDefs) None None 0x0 (mkILExportedTypes []) "" - { mainModule - with Manifest = + { mainModule + with Manifest = (let man = mainModule.ManifestOfAssembly Some { man with CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs codegenResults.ilAssemAttrs) }) } - let ProcessInputs (ctok, errorLogger: ErrorLogger, istate: FsiDynamicCompilerState, inputs: ParsedInput list, showTypes: bool, isIncrementalFragment: bool, isInteractiveItExpr: bool, prefixPath: LongIdent) = - let optEnv = istate.optEnv - let emEnv = istate.emEnv - let tcState = istate.tcState - let ilxGenerator = istate.ilxGenerator - let tcConfig = TcConfig.Create(tcConfigB,validate=false) + let ProcessCodegenResults (ctok, errorLogger: ErrorLogger, istate, optEnv, tcState: TcState, tcConfig, prefixPath, showTypes: bool, isIncrementalFragment, fragName, declaredImpls, ilxGenerator: IlxAssemblyGenerator, codegenResults) = + let emEnv = istate.emEnv - // Typecheck. The lock stops the type checker running at the same time as the - // server intellisense implementation (which is currently incomplete and #if disabled) - let (tcState:TcState),topCustomAttrs,declaredImpls,tcEnvAtEndOfLastInput = - lock tcLockObject (fun _ -> TypeCheckClosedInputSet(ctok, errorLogger.CheckForErrors, tcConfig, tcImports, tcGlobals, Some prefixPath, tcState, inputs)) - -#if DEBUG - // Logging/debugging - if tcConfig.printAst then - for input in declaredImpls do - fprintfn fsiConsoleOutput.Out "AST:" - fprintfn fsiConsoleOutput.Out "%+A" input -#endif - - errorLogger.AbortOnError(fsiConsoleOutput); - - let importMap = tcImports.GetImportMap() - - // optimize: note we collect the incremental optimization environment - let optimizedImpls, _optData, optEnv = ApplyAllOptimizations (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, importMap, isIncrementalFragment, optEnv, tcState.Ccu, declaredImpls) - errorLogger.AbortOnError(fsiConsoleOutput); - - let fragName = textOfLid prefixPath - let codegenResults = GenerateIlxCode (IlReflectBackend, isInteractiveItExpr, runningOnMono, tcConfig, topCustomAttrs, optimizedImpls, fragName, ilxGenerator) - errorLogger.AbortOnError(fsiConsoleOutput); - - // Each input is like a small separately compiled extension to a single source file. - // The incremental extension to the environment is dictated by the "signature" of the values as they come out - // of the type checker. Hence we add the declaredImpls (unoptimized) to the environment, rather than the - // optimizedImpls. + // Each input is like a small separately compiled extension to a single source file. + // The incremental extension to the environment is dictated by the "signature" of the values as they come out + // of the type checker. Hence we add the declaredImpls (unoptimized) to the environment, rather than the + // optimizedImpls. ilxGenerator.AddIncrementalLocalAssemblyFragment (isIncrementalFragment, fragName, declaredImpls) ReportTime tcConfig "TAST -> ILX"; errorLogger.AbortOnError(fsiConsoleOutput); - + ReportTime tcConfig "Linking"; let ilxMainModule = CreateModuleFragment (tcConfigB, assemblyName, codegenResults) errorLogger.AbortOnError(fsiConsoleOutput); - - ReportTime tcConfig "Assembly refs Normalised"; - let mainmod3 = Morphs.morphILScopeRefsInILModuleMemoized ilGlobals (NormalizeAssemblyRefs (ctok, ilGlobals, tcImports)) ilxMainModule + + ReportTime tcConfig "Assembly refs Normalised"; + let mainmod3 = Morphs.morphILScopeRefsInILModuleMemoized (NormalizeAssemblyRefs (ctok, ilGlobals, tcImports)) ilxMainModule errorLogger.AbortOnError(fsiConsoleOutput); #if DEBUG - if fsiOptions.ShowILCode then + if fsiOptions.ShowILCode then fsiConsoleOutput.uprintnfn "--------------------"; ILAsciiWriter.output_module outWriter ilGlobals mainmod3; fsiConsoleOutput.uprintnfn "--------------------" @@ -1051,32 +1163,32 @@ type internal FsiDynamicCompiler ReportTime tcConfig "Reflection.Emit"; - let emEnv,execs = ILRuntimeWriter.emitModuleFragment(ilGlobals, emEnv, assemblyBuilder, moduleBuilder, mainmod3, generateDebugInfo, resolveAssemblyRef, tcGlobals.TryFindSysILTypeRef) + let emEnv,execs = emitModuleFragment(ilGlobals, tcConfig.emitTailcalls, emEnv, assemblyBuilder, moduleBuilder, mainmod3, generateDebugInfo, resolveAssemblyRef, tcGlobals.TryFindSysILTypeRef) errorLogger.AbortOnError(fsiConsoleOutput); - // Explicitly register the resources with the QuotationPickler module - // We would save them as resources into the dynamic assembly but there is missing - // functionality System.Reflection for dynamic modules that means they can't be read back out - let cenv = { ilg = ilGlobals ; generatePdb = generateDebugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=tcGlobals.TryFindSysILTypeRef } - for (referencedTypeDefs, bytes) in codegenResults.quotationResourceInfo do - let referencedTypes = - [| for tref in referencedTypeDefs do - yield ILRuntimeWriter.LookupTypeRef cenv emEnv tref |] + // Explicitly register the resources with the QuotationPickler module + // We would save them as resources into the dynamic assembly but there is missing + // functionality System.Reflection for dynamic modules that means they can't be read back out + let cenv = { ilg = ilGlobals ; emitTailcalls = tcConfig.emitTailcalls; generatePdb = generateDebugInfo; resolveAssemblyRef=resolveAssemblyRef; tryFindSysILTypeRef=tcGlobals.TryFindSysILTypeRef } + for referencedTypeDefs, bytes in codegenResults.quotationResourceInfo do + let referencedTypes = + [| for tref in referencedTypeDefs do + yield LookupTypeRef cenv emEnv tref |] Microsoft.FSharp.Quotations.Expr.RegisterReflectedDefinitions (assemblyBuilder, fragName, bytes, referencedTypes); - + ReportTime tcConfig "Run Bindings"; - timeReporter.TimeOpIf istate.timing (fun () -> - execs |> List.iter (fun exec -> - match exec() with - | Some err -> - match errorLogger with - | :? ErrorLoggerThatStopsOnFirstError as errorLogger -> + timeReporter.TimeOpIf istate.timing (fun () -> + execs |> List.iter (fun exec -> + match exec() with + | Some err -> + match errorLogger with + | :? ErrorLoggerThatStopsOnFirstError as errorLogger -> fprintfn fsiConsoleOutput.Error "%s" (err.ToString()) errorLogger.SetError() errorLogger.AbortOnError(fsiConsoleOutput) - | _ -> + | _ -> raise (StopProcessingExn (Some err)) | None -> ())) ; @@ -1086,66 +1198,90 @@ type internal FsiDynamicCompiler // Echo the decls (reach inside wrapping) // This code occurs AFTER the execution of the declarations. // So stored values will have been initialised, modified etc. - if showTypes && not tcConfig.noFeedback then + if showTypes && not tcConfig.noFeedback then let denv = tcState.TcEnvFromImpls.DisplayEnv - let denv = + let denv = if isIncrementalFragment then // Extend denv with a (Val -> layout option) function for printing of val bindings. {denv with generatedValueLayout = (fun v -> valuePrinter.InvokeDeclLayout (emEnv, ilxGenerator, v)) } else // With #load items, the vals in the inferred signature do not tie up with those generated. Disable printing. - denv + denv + let denv = { denv with suppressInlineKeyword = false } // dont' suppress 'inline' in 'val inline f = ...' // 'Open' the path for the fragment we just compiled for any future printing. - let denv = denv.AddOpenPath (pathOfLid prefixPath) + let denv = denv.AddOpenPath (pathOfLid prefixPath) - for (TImplFile (_qname,_,mexpr,_,_,_)) in declaredImpls do - let responseL = NicePrint.layoutInferredSigOfModuleExpr false denv infoReader AccessibleFromSomewhere rangeStdin mexpr - if not (Layout.isEmptyL responseL) then + for TImplFile (_qname,_,mexpr,_,_,_) in declaredImpls do + let responseL = NicePrint.layoutInferredSigOfModuleExpr false denv infoReader AccessibleFromSomewhere rangeStdin mexpr + if not (isEmptyL responseL) then let opts = valuePrinter.GetFsiPrintOptions() - Utilities.colorPrintL outWriter opts responseL |> ignore + colorPrintL outWriter opts responseL // Build the new incremental state. let istate = {istate with optEnv = optEnv; emEnv = emEnv; ilxGenerator = ilxGenerator; tcState = tcState } - + // Return the new state and the environment at the end of the last input, ready for further inputs. - (istate,tcEnvAtEndOfLastInput,declaredImpls) + (istate,declaredImpls) - let nextFragmentId() = fragmentId <- fragmentId + 1; fragmentId + let ProcessTypedImpl (errorLogger: ErrorLogger, optEnv, tcState: TcState, tcConfig: TcConfig, isInteractiveItExpr, topCustomAttrs, prefixPath, isIncrementalFragment, declaredImpls, ilxGenerator: IlxAssemblyGenerator) = + #if DEBUG + // Logging/debugging + if tcConfig.printAst then + for input in declaredImpls do + fprintfn fsiConsoleOutput.Out "AST:" + fprintfn fsiConsoleOutput.Out "%+A" input +#endif - let mkFragmentPath i = - // NOTE: this text shows in exn traces and type names. Make it clear and fixed width - [mkSynId rangeStdin (FsiDynamicModulePrefix + sprintf "%04d" i)] + errorLogger.AbortOnError(fsiConsoleOutput); - member __.DynamicAssemblyName = assemblyName + let importMap = tcImports.GetImportMap() - member __.DynamicAssembly = (assemblyBuilder :> Assembly) + // optimize: note we collect the incremental optimization environment + let optimizedImpls, _optData, optEnv = ApplyAllOptimizations (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, importMap, isIncrementalFragment, optEnv, tcState.Ccu, declaredImpls) + errorLogger.AbortOnError(fsiConsoleOutput); - member __.EvalParsedSourceFiles (ctok, errorLogger, istate, inputs) = - let i = nextFragmentId() - let prefix = mkFragmentPath i - // Ensure the path includes the qualifying name - let inputs = inputs |> List.map (PrependPathToInput prefix) - let istate,_,_ = ProcessInputs (ctok, errorLogger, istate, inputs, true, false, false, prefix) - istate + let fragName = textOfLid prefixPath + let codegenResults = GenerateIlxCode (IlReflectBackend, isInteractiveItExpr, runningOnMono, tcConfig, topCustomAttrs, optimizedImpls, fragName, ilxGenerator) + errorLogger.AbortOnError(fsiConsoleOutput); + codegenResults, optEnv, fragName - /// Evaluate the given definitions and produce a new interactive state. - member __.EvalParsedDefinitions (ctok, errorLogger: ErrorLogger, istate, showTypes, isInteractiveItExpr, defs: SynModuleDecls) = - let filename = Lexhelp.stdinMockFilename - let i = nextFragmentId() - let prefix = mkFragmentPath i - let prefixPath = pathOfLid prefix - let impl = SynModuleOrNamespace(prefix,(*isRec*)false, NamedModule,defs,PreXmlDoc.Empty,[],None,rangeStdin) - let input = ParsedInput.ImplFile (ParsedImplFileInput (filename,true, ComputeQualifiedNameOfFileFromUniquePath (rangeStdin,prefixPath),[],[],[impl],(true (* isLastCompiland *), false (* isExe *)) )) - let istate,tcEnvAtEndOfLastInput,declaredImpls = ProcessInputs (ctok, errorLogger, istate, [input], showTypes, true, isInteractiveItExpr, prefix) - let tcState = istate.tcState - let newState = { istate with tcState = tcState.NextStateAfterIncrementalFragment(tcEnvAtEndOfLastInput) } + let ProcessInputs (ctok, errorLogger: ErrorLogger, istate: FsiDynamicCompilerState, inputs: ParsedInput list, showTypes: bool, isIncrementalFragment: bool, isInteractiveItExpr: bool, prefixPath: LongIdent) = + let optEnv = istate.optEnv + let tcState = istate.tcState + let ilxGenerator = istate.ilxGenerator + let tcConfig = TcConfig.Create(tcConfigB,validate=false) + + // Typecheck. The lock stops the type checker running at the same time as the + // server intellisense implementation (which is currently incomplete and #if disabled) + let (tcState:TcState), topCustomAttrs, declaredImpls, tcEnvAtEndOfLastInput = + lock tcLockObject (fun _ -> TypeCheckClosedInputSet(ctok, errorLogger.CheckForErrors, tcConfig, tcImports, tcGlobals, Some prefixPath, tcState, inputs)) + + let codegenResults, optEnv, fragName = ProcessTypedImpl(errorLogger, optEnv, tcState, tcConfig, isInteractiveItExpr, topCustomAttrs, prefixPath, isIncrementalFragment, declaredImpls, ilxGenerator) + let newState, declaredImpls = ProcessCodegenResults(ctok, errorLogger, istate, optEnv, tcState, tcConfig, prefixPath, showTypes, isIncrementalFragment, fragName, declaredImpls, ilxGenerator, codegenResults) + (newState, tcEnvAtEndOfLastInput, declaredImpls) + + let tryGetGeneratedValue istate cenv v = + match istate.ilxGenerator.LookupGeneratedValue(valuePrinter.GetEvaluationContext(istate.emEnv), v) with + | Some (res, ty) -> + Some (FsiValue(res, ty, FSharpType(cenv, v.Type))) + | _ -> + None + + let nextFragmentId() = fragmentId <- fragmentId + 1; fragmentId + + let mkFragmentPath i = + // NOTE: this text shows in exn traces and type names. Make it clear and fixed width + [mkSynId rangeStdin (FsiDynamicModulePrefix + sprintf "%04d" i)] + + let processContents istate declaredImpls = + let tcState = istate.tcState - // Find all new declarations the EvaluationListener let mutable itValue = None + let mutable boundValues = istate.boundValues try let contents = FSharpAssemblyContents(tcGlobals, tcState.Ccu, Some tcState.CcuSig, tcImports, declaredImpls) let contentFile = contents.ImplementationFiles.[0] @@ -1153,7 +1289,7 @@ type internal FsiDynamicCompiler // Skip the "FSI_NNNN" match contentFile.Declarations with | [FSharpImplementationFileDeclaration.Entity (_eFakeModule,modDecls) ] -> - let cenv = SymbolEnv(newState.tcGlobals, newState.tcState.Ccu, Some newState.tcState.CcuSig, newState.tcImports) + let cenv = SymbolEnv(istate.tcGlobals, istate.tcState.Ccu, Some istate.tcState.CcuSig, istate.tcImports) for decl in modDecls do match decl with | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue (v,_,_) -> @@ -1162,10 +1298,10 @@ type internal FsiDynamicCompiler let fsiValueOpt = match v.Item with | Item.Value vref -> - let optValue = newState.ilxGenerator.LookupGeneratedValue(valuePrinter.GetEvaluationContext(newState.emEnv), vref.Deref) - match optValue with - | Some (res, ty) -> Some(FsiValue(res, ty, FSharpType(cenv, vref.Type))) - | None -> None + let fsiValueOpt = tryGetGeneratedValue istate cenv vref.Deref + if fsiValueOpt.IsSome then + boundValues <- boundValues |> NameMap.add v.CompiledName vref.Deref + fsiValueOpt | _ -> None if v.CompiledName = "it" then @@ -1176,13 +1312,13 @@ type internal FsiDynamicCompiler | None -> () let symbol = FSharpSymbol.Create(cenv, v.Item) - let symbolUse = FSharpSymbolUse(tcGlobals, newState.tcState.TcEnvFromImpls.DisplayEnv, symbol, ItemOccurence.Binding, v.DeclarationLocation) + let symbolUse = FSharpSymbolUse(istate.tcState.TcEnvFromImpls.DisplayEnv, symbol, [], ItemOccurence.Binding, v.DeclarationLocation) fsi.TriggerEvaluation (fsiValueOpt, symbolUse, decl) | FSharpImplementationFileDeclaration.Entity (e,_) -> // Report a top-level module or namespace definition let symbol = FSharpSymbol.Create(cenv, e.Item) - let symbolUse = FSharpSymbolUse(tcGlobals, newState.tcState.TcEnvFromImpls.DisplayEnv, symbol, ItemOccurence.Binding, e.DeclarationLocation) + let symbolUse = FSharpSymbolUse(istate.tcState.TcEnvFromImpls.DisplayEnv, symbol, [], ItemOccurence.Binding, e.DeclarationLocation) fsi.TriggerEvaluation (None, symbolUse, decl) | FSharpImplementationFileDeclaration.InitAction _ -> @@ -1191,12 +1327,82 @@ type internal FsiDynamicCompiler | _ -> () with _ -> () - newState, Completed itValue + { istate with boundValues = boundValues }, Completed itValue + + let addCcusToIncrementalEnv istate ccuinfos = + let optEnv = List.fold (AddExternalCcuToOptimizationEnv tcGlobals) istate.optEnv ccuinfos + istate.ilxGenerator.AddExternalCcus (ccuinfos |> List.map (fun ccuinfo -> ccuinfo.FSharpViewOfMetadata)) + { istate with optEnv = optEnv } + + let importReflectionType istate reflectionTy = + let tcImports = istate.tcImports + let tcGlobals = istate.tcGlobals + let amap = tcImports.GetImportMap() + + let prevCcuinfos = tcImports.GetImportedAssemblies() + + let rec import ccuinfos (ilTy: ILType) = + let ccuinfos, tinst = + (ilTy.GenericArgs, (ccuinfos, [])) + ||> List.foldBack (fun ilGenericArgTy (ccuInfos, tinst) -> + let ccuinfos2, ty = import ccuInfos ilGenericArgTy + (ccuinfos2 @ ccuinfos, ty :: tinst)) + + let ty = Import.ImportILType amap range0 tinst ilTy + let ccuinfos = + match tryTcrefOfAppTy tcGlobals ty with + | ValueSome tcref -> + match tcref.CompilationPath.ILScopeRef with + | ILScopeRef.Assembly aref -> + (tcImports.GetImportedAssemblies() |> List.find (fun x -> x.FSharpViewOfMetadata.AssemblyName = aref.Name)) :: ccuinfos + | _ -> + ccuinfos + | _ -> + ccuinfos + ccuinfos, ty + + let ilTy = convertReflectionTypeToILType reflectionTy + + if not (Import.CanImportILType amap range0 ilTy) then + invalidOp (sprintf "Unable to import type, %A." reflectionTy) + + let ccuinfos, ty = import [] ilTy + let ccuinfos = + ccuinfos + |> List.distinctBy (fun x -> x.FSharpViewOfMetadata.AssemblyName) + |> List.filter (fun asm1 -> not (prevCcuinfos |> List.exists (fun asm2 -> asm2.FSharpViewOfMetadata.AssemblyName = asm1.FSharpViewOfMetadata.AssemblyName))) + // After we have successfully imported the type, then we can add newly resolved ccus to the env. + addCcusToIncrementalEnv istate ccuinfos, ty + + member _.DynamicAssemblyName = assemblyName + + member _.DynamicAssembly = (assemblyBuilder :> Assembly) + + member _.EvalParsedSourceFiles (ctok, errorLogger, istate, inputs) = + let i = nextFragmentId() + let prefix = mkFragmentPath i + // Ensure the path includes the qualifying name + let inputs = inputs |> List.map (PrependPathToInput prefix) + let istate,_,_ = ProcessInputs (ctok, errorLogger, istate, inputs, true, false, false, prefix) + istate + + /// Evaluate the given definitions and produce a new interactive state. + member _.EvalParsedDefinitions (ctok, errorLogger: ErrorLogger, istate, showTypes, isInteractiveItExpr, defs) = + let filename = stdinMockFilename + let i = nextFragmentId() + let prefix = mkFragmentPath i + let prefixPath = pathOfLid prefix + let impl = SynModuleOrNamespace(prefix,(*isRec*)false, SynModuleOrNamespaceKind.NamedModule,defs,PreXmlDoc.Empty,[],None,rangeStdin) + let input = ParsedInput.ImplFile (ParsedImplFileInput (filename,true, ComputeQualifiedNameOfFileFromUniquePath (rangeStdin,prefixPath),[],[],[impl],(true (* isLastCompiland *), false (* isExe *)) )) + let istate,tcEnvAtEndOfLastInput,declaredImpls = ProcessInputs (ctok, errorLogger, istate, [input], showTypes, true, isInteractiveItExpr, prefix) + let tcState = istate.tcState + let newState = { istate with tcState = tcState.NextStateAfterIncrementalFragment(tcEnvAtEndOfLastInput) } + processContents newState declaredImpls /// Evaluate the given expression and produce a new interactive state. member fsiDynamicCompiler.EvalParsedExpression (ctok, errorLogger: ErrorLogger, istate, expr: SynExpr) = let tcConfig = TcConfig.Create (tcConfigB, validate=false) - let itName = "it" + let itName = "it" // Construct the code that saves the 'it' value into the 'SaveIt' register. let defs = fsiDynamicCompiler.BuildItBinding expr @@ -1204,14 +1410,15 @@ type internal FsiDynamicCompiler // Evaluate the overall definitions. let istate = fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, false, true, defs) |> fst // Snarf the type for 'it' via the binding - match istate.tcState.TcEnvFromImpls.NameEnv.FindUnqualifiedItem itName with - | NameResolution.Item.Value vref -> - if not tcConfig.noFeedback then - valuePrinter.InvokeExprPrinter (istate.tcState.TcEnvFromImpls.DisplayEnv, istate.emEnv, istate.ilxGenerator, vref.Deref) + match istate.tcState.TcEnvFromImpls.NameEnv.FindUnqualifiedItem itName with + | Item.Value vref -> + if not tcConfig.noFeedback then + let infoReader = InfoReader(istate.tcGlobals, istate.tcImports.GetImportMap()) + valuePrinter.InvokeExprPrinter (istate.tcState.TcEnvFromImpls.DisplayEnv, infoReader, istate.emEnv, istate.ilxGenerator, vref) /// Clear the value held in the previous "it" binding, if any, as long as it has never been referenced. match prevIt with - | Some prevVal when not prevVal.Deref.HasBeenReferenced -> + | Some prevVal when not prevVal.Deref.HasBeenReferenced -> istate.ilxGenerator.ClearGeneratedValue (valuePrinter.GetEvaluationContext istate.emEnv, prevVal.Deref) | _ -> () prevIt <- Some vref @@ -1226,127 +1433,156 @@ type internal FsiDynamicCompiler | _ -> istate, Completed None // Construct the code that saves the 'it' value into the 'SaveIt' register. - member __.BuildItBinding (expr: SynExpr) = + member _.BuildItBinding (expr: SynExpr) = let m = expr.Range - let itName = "it" + let itName = "it" let itID = mkSynId m itName //let itExp = SynExpr.Ident itID - let mkBind pat expr = Binding (None, DoBinding, false, (*mutable*)false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, pat, None, expr, m, NoSequencePointAtInvisibleBinding) - let bindingA = mkBind (mkSynPatVar None itID) expr (* let it = *) // NOTE: the generalizability of 'expr' must not be damaged, e.g. this can't be an application + let mkBind pat expr = SynBinding (None, SynBindingKind.Do, false, (*mutable*)false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, pat, None, expr, m, DebugPointAtBinding.NoneAtInvisible) + let bindingA = mkBind (mkSynPatVar None itID) expr (* let it = *) // NOTE: the generalizability of 'expr' must not be damaged, e.g. this can't be an application //let saverPath = ["Microsoft";"FSharp";"Compiler";"Interactive";"RuntimeHelpers";"SaveIt"] //let dots = List.replicate (saverPath.Length - 1) m //let bindingB = mkBind (SynPat.Wild m) (SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.LongIdent (false, LongIdentWithDots(List.map (mkSynId m) saverPath,dots),None,m), itExp,m)) (* let _ = saverPath it *) let defA = SynModuleDecl.Let (false, [bindingA], m) //let defB = SynModuleDecl.Let (false, [bindingB], m) - + [defA (* ; defB *) ] // construct an invisible call to Debugger.Break(), in the specified range - member __.CreateDebuggerBreak (m : range) = + member _.CreateDebuggerBreak (m : range) = let breakPath = ["System";"Diagnostics";"Debugger";"Break"] let dots = List.replicate (breakPath.Length - 1) m let methCall = SynExpr.LongIdent (false, LongIdentWithDots(List.map (mkSynId m) breakPath, dots), None, m) let args = SynExpr.Const (SynConst.Unit, m) let breakStatement = SynExpr.App (ExprAtomicFlag.Atomic, false, methCall, args, m) - SynModuleDecl.DoExpr(SequencePointInfoForBinding.NoSequencePointAtDoBinding, breakStatement, m) + SynModuleDecl.DoExpr(DebugPointAtBinding.NoneAtDo, breakStatement, m) - member __.EvalRequireReference (ctok, istate, m, path) = + member _.EvalRequireReference (ctok, istate, m, path) = if FileSystem.IsInvalidPathShim(path) then error(Error(FSIstrings.SR.fsiInvalidAssembly(path),m)) - // Check the file can be resolved before calling requireDLLReference + // Check the file can be resolved before calling requireDLLReference let resolutions = tcImports.ResolveAssemblyReference(ctok, AssemblyReference(m,path,None), ResolveAssemblyReferenceMode.ReportErrors) tcConfigB.AddReferencedAssemblyByPath(m,path) - let tcState = istate.tcState - let tcEnv,(_dllinfos,ccuinfos) = + let tcState = istate.tcState + let tcEnv,(_dllinfos,ccuinfos) = try - RequireDLL (ctok, tcImports, tcState.TcEnvFromImpls, assemblyName, m, path, assemblyReferenceAddedEvent.Trigger) + RequireDLL (ctok, tcImports, tcState.TcEnvFromImpls, assemblyName, m, path) with e -> tcConfigB.RemoveReferencedAssemblyByPath(m,path) reraise() - let optEnv = List.fold (AddExternalCcuToOptimizationEnv tcGlobals) istate.optEnv ccuinfos - istate.ilxGenerator.AddExternalCcus (ccuinfos |> List.map (fun ccuinfo -> ccuinfo.FSharpViewOfMetadata)) resolutions, - { istate with tcState = tcState.NextStateAfterIncrementalFragment(tcEnv); optEnv = optEnv } - + { addCcusToIncrementalEnv istate ccuinfos with tcState = tcState.NextStateAfterIncrementalFragment(tcEnv) } - member __.EvalDependencyManagerTextFragment (packageManager:DependencyManagerIntegration.IDependencyManagerProvider,m,path: string) = - let path = DependencyManagerIntegration.removeDependencyManagerKey packageManager.Key path - - match tcConfigB.packageManagerLines |> Map.tryFind packageManager.Key with - | Some lines -> tcConfigB.packageManagerLines <- Map.add packageManager.Key (lines @ [false, path, m]) tcConfigB.packageManagerLines - | _ -> tcConfigB.packageManagerLines <- Map.add packageManager.Key [false, path, m] tcConfigB.packageManagerLines + member _.EvalDependencyManagerTextFragment (packageManager:IDependencyManagerProvider, lt, m, path: string) = + tcConfigB.packageManagerLines <- PackageManagerLine.AddLineWithKey packageManager.Key lt path m tcConfigB.packageManagerLines needsPackageResolution <- true - member fsiDynamicCompiler.CommitDependencyManagerText (ctok, istate: FsiDynamicCompilerState, lexResourceManager, errorLogger) = + member fsiDynamicCompiler.CommitDependencyManagerText (ctok, istate: FsiDynamicCompilerState, lexResourceManager, errorLogger) = if not needsPackageResolution then istate else needsPackageResolution <- false tcConfigB.packageManagerLines |> Seq.fold(fun istate kv -> - let inline snd3 (_, b, _) = b let packageManagerKey, packageManagerLines = kv.Key, kv.Value match packageManagerLines with | [] -> istate - | (_, _, m)::_ -> - match DependencyManagerIntegration.tryFindDependencyManagerByKey tcConfigB.compilerToolPaths tcConfigB.outputDir m packageManagerKey with - | None -> - errorR(DependencyManagerIntegration.createPackageManagerUnknownError tcConfigB.compilerToolPaths tcConfigB.outputDir packageManagerKey m) + | { Directive=_; LineStatus=_; Line=_; Range=m } :: _ -> + let outputDir = tcConfigB.outputDir |> Option.defaultValue "" + + match fsiOptions.DependencyProvider.TryFindDependencyManagerByKey(tcConfigB.compilerToolPaths, getOutputDir tcConfigB, reportError m, packageManagerKey) with + | null -> + errorR(Error(fsiOptions.DependencyProvider.CreatePackageManagerUnknownError(tcConfigB.compilerToolPaths, outputDir, packageManagerKey, reportError m), m)) istate - | Some packageManager -> - let packageManagerTextLines = packageManagerLines |> List.map snd3 - let removeErrorLinesFromScript () = - tcConfigB.packageManagerLines <- tcConfigB.packageManagerLines |> Map.map(fun _ l -> l |> List.filter(fun (tried, _, _) -> tried)) + | dependencyManager -> + let directive d = + match d with + | Directive.Resolution -> "r" + | Directive.Include -> "i" + + let packageManagerTextLines = + packageManagerLines |> List.map (fun line -> directive line.Directive, line.Line) + try - let newDependencyManager = subscribedDependencyManagers.Add(packageManagerKey) - if newDependencyManager then - Event.add dependencyAddingEvent.Trigger packageManager.DependencyAdding - Event.add dependencyAddedEvent.Trigger packageManager.DependencyAdded - Event.add dependencyFailedEvent.Trigger packageManager.DependencyFailed - match DependencyManagerIntegration.resolve packageManager tcConfigB.implicitIncludeDir "stdin.fsx" "stdin.fsx" m packageManagerTextLines with - | None -> istate // error already reported - | Some (succeeded, generatedScripts, additionalIncludeFolders) -> //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - if succeeded then - tcConfigB.packageManagerLines <- tcConfigB.packageManagerLines |> Map.map(fun _ l -> l |> List.map(fun (_, p, m) -> true, p, m)) - else - removeErrorLinesFromScript () - for folder in additionalIncludeFolders do + let tfm, rid = fsiOptions.FxResolver.GetTfmAndRid() + let result = fsiOptions.DependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError m, tfm, rid, tcConfigB.implicitIncludeDir, "stdin.fsx", "stdin.fsx") + if result.Success then + for line in result.StdOut do Console.Out.WriteLine(line) + for line in result.StdError do Console.Error.WriteLine(line) + tcConfigB.packageManagerLines <- PackageManagerLine.SetLinesAsProcessed packageManagerKey tcConfigB.packageManagerLines + for folder in result.Roots do tcConfigB.AddIncludePath(m, folder, "") - if generatedScripts.Length > 0 then - fsiDynamicCompiler.EvalSourceFiles(ctok, istate, m, generatedScripts, lexResourceManager, errorLogger) + for resolution in result.Resolutions do + tcConfigB.AddReferencedAssemblyByPath(m, resolution) + let scripts = result.SourceFiles |> Seq.toList + if not (isNil scripts) then + fsiDynamicCompiler.EvalSourceFiles(ctok, istate, m, scripts, lexResourceManager, errorLogger) else istate + else + // Send outputs via diagnostics + if (result.StdOut.Length > 0 || result.StdError.Length > 0) then + for line in Array.append result.StdOut result.StdError do + errorR(Error(FSComp.SR.packageManagerError(line), m)) + //Write outputs in F# Interactive and compiler + tcConfigB.packageManagerLines <- PackageManagerLine.RemoveUnprocessedLines packageManagerKey tcConfigB.packageManagerLines + istate // error already reported + + with _ -> // An exception occured during processing, so remove the lines causing the error from the package manager list. - removeErrorLinesFromScript () + tcConfigB.packageManagerLines <- PackageManagerLine.RemoveUnprocessedLines packageManagerKey tcConfigB.packageManagerLines reraise () ) istate member fsiDynamicCompiler.ProcessMetaCommandsFromInputAsInteractiveCommands(ctok, istate, sourceFile, inp) = WithImplicitHome - (tcConfigB, directoryName sourceFile) + (tcConfigB, directoryName sourceFile) (fun () -> - ProcessMetaCommandsFromInput + ProcessMetaCommandsFromInput ((fun st (m,nm) -> tcConfigB.TurnWarningOff(m,nm); st), - (fun st (m,nm) -> snd (fsiDynamicCompiler.EvalRequireReference (ctok, st, m, nm))), - (fun st (packageManagerPrefix,m,nm) -> fsiDynamicCompiler.EvalDependencyManagerTextFragment (packageManagerPrefix,m,nm); st), - (fun _ _ -> ())) + (fun st (m, path, directive) -> + + let dm = tcImports.DependencyProvider.TryFindDependencyManagerInPath(tcConfigB.compilerToolPaths, getOutputDir tcConfigB, reportError m, path) + + match dm with + | _, dependencyManager when not(isNull dependencyManager) -> + if tcConfigB.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then + fsiDynamicCompiler.EvalDependencyManagerTextFragment (dependencyManager, directive, m, path) + st + else + errorR(Error(FSComp.SR.packageManagementRequiresVFive(), m)) + st + + | _, _ when directive = Directive.Include -> + errorR(Error(FSComp.SR.poundiNotSupportedByRegisteredDependencyManagers(), m)) + st + + // #r "Assembly" + | path, _ -> + snd (fsiDynamicCompiler.EvalRequireReference (ctok, st, m, path)) + ), + (fun _ _ -> ())) (tcConfigB, inp, Path.GetDirectoryName sourceFile, istate)) - + member fsiDynamicCompiler.EvalSourceFiles(ctok, istate, m, sourceFiles, lexResourceManager, errorLogger: ErrorLogger) = let tcConfig = TcConfig.Create(tcConfigB,validate=false) - match sourceFiles with + match sourceFiles with | [] -> istate - | _ -> + | _ -> // use a set of source files as though they were command line inputs - let sourceFiles = sourceFiles |> List.map (fun nm -> tcConfig.ResolveSourceFile(m, nm, tcConfig.implicitIncludeDir),m) - + let sourceFiles = sourceFiles |> List.map (fun nm -> tcConfig.ResolveSourceFile(m, nm, tcConfig.implicitIncludeDir),m) + // Close the #load graph on each file and gather the inputs from the scripts. let tcConfig = TcConfig.Create(tcConfigB,validate=false) - let closure = LoadClosure.ComputeClosureOfScriptFiles(ctok, tcConfig, sourceFiles, CodeContext.CompilationAndEvaluation, lexResourceManager=lexResourceManager) - + + let closure = + LoadClosure.ComputeClosureOfScriptFiles(tcConfig, + sourceFiles, CodeContext.CompilationAndEvaluation, + lexResourceManager, fsiOptions.DependencyProvider) + // Intent "[Loading %s]\n" (String.concat "\n and " sourceFiles) fsiConsoleOutput.uprintf "[%s " (FSIstrings.SR.fsiLoadingFilesPrefixText()) - closure.Inputs |> List.iteri (fun i input -> + closure.Inputs |> List.iteri (fun i input -> if i=0 then fsiConsoleOutput.uprintf "%s" input.FileName else fsiConsoleOutput.uprintnf " %s %s" (FSIstrings.SR.fsiLoadingFilesPrefixText()) input.FileName) fsiConsoleOutput.uprintfn "]" @@ -1355,35 +1591,109 @@ type internal FsiDynamicCompiler // Play errors and warnings from resolution closure.ResolutionDiagnostics |> List.iter diagnosticSink - + // Non-scripts will not have been parsed during #load closure so parse them now - let sourceFiles,inputs = - closure.Inputs - |> List.map (fun input-> + let sourceFiles,inputs = + closure.Inputs + |> List.map (fun input-> input.ParseDiagnostics |> List.iter diagnosticSink input.MetaCommandDiagnostics |> List.iter diagnosticSink - let parsedInput = - match input.SyntaxTree with + let parsedInput = + match input.SyntaxTree with | None -> ParseOneInputFile(tcConfig,lexResourceManager,["INTERACTIVE"],input.FileName,(true,false),errorLogger,(*retryLocked*)false) - | _-> input.SyntaxTree + | Some parseTree -> parseTree input.FileName, parsedInput) |> List.unzip - + errorLogger.AbortOnError(fsiConsoleOutput); - if inputs |> List.exists Option.isNone then failwith "parse error" - let inputs = List.map Option.get inputs let istate = (istate, sourceFiles, inputs) |||> List.fold2 (fun istate sourceFile input -> fsiDynamicCompiler.ProcessMetaCommandsFromInputAsInteractiveCommands(ctok, istate, sourceFile, input)) fsiDynamicCompiler.EvalParsedSourceFiles (ctok, errorLogger, istate, inputs) - - member __.GetInitialInteractiveState () = + member _.GetBoundValues istate = + let cenv = SymbolEnv(istate.tcGlobals, istate.tcState.Ccu, Some istate.tcState.CcuSig, istate.tcImports) + [ for pair in istate.boundValues do + let nm = pair.Key + let v = pair.Value + match tryGetGeneratedValue istate cenv v with + | Some fsiValue -> + yield FsiBoundValue(nm, fsiValue) + | _ -> + () ] + + member _.TryFindBoundValue(istate, nm) = + match istate.boundValues.TryFind nm with + | Some v -> + let cenv = SymbolEnv(istate.tcGlobals, istate.tcState.Ccu, Some istate.tcState.CcuSig, istate.tcImports) + match tryGetGeneratedValue istate cenv v with + | Some fsiValue -> + Some (FsiBoundValue(nm, fsiValue)) + | _ -> + None + | _ -> + None + + member this.AddBoundValue (ctok, errorLogger: ErrorLogger, istate, name: string, value: obj) = + try + match value with + | null -> nullArg "value" + | _ -> () + + if String.IsNullOrWhiteSpace name then + invalidArg "name" "Name cannot be null or white-space." + + // Verify that the name is a valid identifier for a value. + FSharpLexer.Tokenize(SourceText.ofString name, + let mutable foundOne = false + fun t -> + if not t.IsIdentifier || foundOne then + invalidArg "name" "Name is not a valid identifier." + foundOne <- true) + + if IsCompilerGeneratedName name then + invalidArg "name" (FSComp.SR.lexhlpIdentifiersContainingAtSymbolReserved() |> snd) + + let istate, ty = importReflectionType istate (value.GetType()) + let amap = istate.tcImports.GetImportMap() + + let i = nextFragmentId() + let prefix = mkFragmentPath i + let prefixPath = pathOfLid prefix + let qualifiedName = ComputeQualifiedNameOfFileFromUniquePath (rangeStdin,prefixPath) + + let tcConfig = TcConfig.Create(tcConfigB,validate=false) + + // Build a simple module with a single 'let' decl with a default value. + let moduleOrNamespace, v, impl = mkBoundValueTypedImpl istate.tcGlobals range0 qualifiedName.Text name ty + let tcEnvAtEndOfLastInput = + AddLocalSubModule tcGlobals amap range0 istate.tcState.TcEnvFromImpls moduleOrNamespace + |> AddLocalVal tcGlobals TcResultsSink.NoSink range0 v + + // Generate IL for the given typled impl and create new interactive state. + let ilxGenerator = istate.ilxGenerator + let isIncrementalFragment = true + let showTypes = false + let declaredImpls = [impl] + let codegenResults, optEnv, fragName = ProcessTypedImpl(errorLogger, istate.optEnv, istate.tcState, tcConfig, false, EmptyTopAttrs, prefix, isIncrementalFragment, declaredImpls, ilxGenerator) + let istate, declaredImpls = ProcessCodegenResults(ctok, errorLogger, istate, optEnv, istate.tcState, tcConfig, prefix, showTypes, isIncrementalFragment, fragName, declaredImpls, ilxGenerator, codegenResults) + let newState = { istate with tcState = istate.tcState.NextStateAfterIncrementalFragment tcEnvAtEndOfLastInput } + + // Force set the val with the given value obj. + let ctxt = valuePrinter.GetEvaluationContext(newState.emEnv) + ilxGenerator.ForceSetGeneratedValue(ctxt, v, value) + + processContents newState declaredImpls + with + | ex -> + istate, CompletedWithReportedError(StopProcessingExn(Some ex)) + + member _.GetInitialInteractiveState () = let tcConfig = TcConfig.Create(tcConfigB,validate=false) let optEnv0 = GetInitialOptimizationEnv (tcImports, tcGlobals) - let emEnv = ILRuntimeWriter.emEnv0 - let tcEnv = GetInitialTcEnv (assemblyName, rangeStdin, tcConfig, tcImports, tcGlobals) - let ccuName = assemblyName + let emEnv = emEnv0 + let tcEnv, openDecls0 = GetInitialTcEnv (assemblyName, rangeStdin, tcConfig, tcImports, tcGlobals) + let ccuName = assemblyName - let tcState = GetInitialTcState (rangeStdin, ccuName, tcConfig, tcGlobals, tcImports, niceNameGen, tcEnv) + let tcState = GetInitialTcState (rangeStdin, ccuName, tcConfig, tcGlobals, tcImports, niceNameGen, tcEnv, openDecls0) let ilxGenerator = CreateIlxAssemblyGenerator (tcConfig, tcImports, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), tcState.Ccu) {optEnv = optEnv0 @@ -1392,25 +1702,18 @@ type internal FsiDynamicCompiler tcState = tcState tcImports = tcImports ilxGenerator = ilxGenerator + boundValues = NameMap.empty timing = false debugBreak = false - } + } - member __.CurrentPartialAssemblySignature(istate) = + member _.CurrentPartialAssemblySignature(istate) = FSharpAssemblySignature(istate.tcGlobals, istate.tcState.Ccu, istate.tcState.CcuSig, istate.tcImports, None, istate.tcState.CcuSig) - member __.FormatValue(obj:obj, objTy) = + member _.FormatValue(obj:obj, objTy) = valuePrinter.FormatValue(obj, objTy) - member __.AssemblyReferenceAdded = assemblyReferenceAddedEvent.Publish - - member __.ValueBound = valueBoundEvent.Publish - - member __.DependencyAdding = dependencyAddingEvent.Publish - - member __.DependencyAdded = dependencyAddedEvent.Publish - - member __.DependencyFailed = dependencyFailedEvent.Publish + member _.ValueBound = valueBoundEvent.Publish //---------------------------------------------------------------------------- // ctrl-c handling @@ -1418,29 +1721,29 @@ type internal FsiDynamicCompiler type ControlEventHandler = delegate of int -> bool -// One strange case: when a TAE happens a strange thing +// One strange case: when a TAE happens a strange thing // occurs the next read from stdin always returns // 0 bytes, i.e. the channel will look as if it has been closed. So we check // for this condition explicitly. We also recreate the lexbuf whenever CtrlC kicks. -type internal FsiInterruptStdinState = - | StdinEOFPermittedBecauseCtrlCRecentlyPressed +type internal FsiInterruptStdinState = + | StdinEOFPermittedBecauseCtrlCRecentlyPressed | StdinNormal -type internal FsiInterruptControllerState = - | InterruptCanRaiseException - | InterruptIgnored +type internal FsiInterruptControllerState = + | InterruptCanRaiseException + | InterruptIgnored -type internal FsiInterruptControllerKillerThreadRequest = - | ThreadAbortRequest - | NoRequest - | ExitRequest +type internal FsiInterruptControllerKillerThreadRequest = + | ThreadAbortRequest + | NoRequest + | ExitRequest | PrintInterruptRequest type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConsoleOutput: FsiConsoleOutput) = let mutable stdinInterruptState = StdinNormal - let CTRL_C = 0 + let CTRL_C = 0 let mutable interruptAllowed = InterruptIgnored let mutable killThreadRequest = NoRequest @@ -1450,24 +1753,24 @@ type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConso let mutable posixReinstate = (fun () -> ()) - member __.Exit() = + member _.Exit() = if exitViaKillThread then killThreadRequest <- ExitRequest Thread.Sleep(1000) exit 0 - member __.FsiInterruptStdinState + member _.FsiInterruptStdinState with get () = stdinInterruptState and set v = stdinInterruptState <- v - member __.ClearInterruptRequest() = killThreadRequest <- NoRequest + member _.ClearInterruptRequest() = killThreadRequest <- NoRequest - member __.InterruptAllowed + member _.InterruptAllowed with set v = interruptAllowed <- v - member __.Interrupt() = ctrlEventActions |> List.iter (fun act -> act()) + member _.Interrupt() = ctrlEventActions |> List.iter (fun act -> act()) - member __.EventHandlers = ctrlEventHandlers + member _.EventHandlers = ctrlEventHandlers member controller.InstallKillThread(threadToKill:Thread, pauseMilliseconds:int) = @@ -1477,19 +1780,19 @@ type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConso fprintf fsiConsoleOutput.Error "%s" (FSIstrings.SR.fsiInterrupt()) stdinInterruptState <- StdinEOFPermittedBecauseCtrlCRecentlyPressed - if (interruptAllowed = InterruptCanRaiseException) then + if (interruptAllowed = InterruptCanRaiseException) then killThreadRequest <- ThreadAbortRequest - let killerThread = - new Thread(new ThreadStart(fun () -> + let killerThread = + Thread(ThreadStart(fun () -> use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID - // sleep long enough to allow ControlEventHandler handler on main thread to return - // Also sleep to give computations a bit of time to terminate + // sleep long enough to allow ControlEventHandler handler on main thread to return + // Also sleep to give computations a bit of time to terminate Thread.Sleep(pauseMilliseconds) - if (killThreadRequest = ThreadAbortRequest) then - if progress then fsiConsoleOutput.uprintnfn "%s" (FSIstrings.SR.fsiAbortingMainThread()) + if (killThreadRequest = ThreadAbortRequest) then + if progress then fsiConsoleOutput.uprintnfn "%s" (FSIstrings.SR.fsiAbortingMainThread()) killThreadRequest <- NoRequest threadToKill.Abort() - ()),Name="ControlCAbortThread") + ()),Name="ControlCAbortThread") killerThread.IsBackground <- true killerThread.Start() @@ -1499,18 +1802,18 @@ type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConso do Console.CancelKeyPress.Add(fsiInterruptHandler) - // WINDOWS TECHNIQUE: .NET has more safe points, and you can do more when a safe point. + // WINDOWS TECHNIQUE: .NET has more safe points, and you can do more when a safe point. // Hence we actually start up the killer thread within the handler. - let ctrlEventHandler = new ControlEventHandler(fun i -> if i = CTRL_C then (raiseCtrlC(); true) else false ) + let ctrlEventHandler = ControlEventHandler(fun i -> if i = CTRL_C then (raiseCtrlC(); true) else false ) ctrlEventHandlers <- ctrlEventHandler :: ctrlEventHandlers ctrlEventActions <- raiseCtrlC :: ctrlEventActions exitViaKillThread <- false // don't exit via kill thread - member x.PosixInvoke(n:int) = + member x.PosixInvoke(n:int) = // we run this code once with n = -1 to make sure it is JITted before execution begins // since we are not allowed to JIT a signal handler. This also ensures the "PosixInvoke" // method is not eliminated by dead-code elimination - if n >= 0 then + if n >= 0 then posixReinstate() stdinInterruptState <- StdinEOFPermittedBecauseCtrlCRecentlyPressed killThreadRequest <- if (interruptAllowed = InterruptCanRaiseException) then ThreadAbortRequest else PrintInterruptRequest @@ -1524,39 +1827,39 @@ type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConso // From http://msdn.microsoft.com/en-us/library/ff527268.aspx // What the Event Handler Does // -// The handler for the AssemblyResolve event receives the display name of the assembly to -// be loaded, in the ResolveEventArgs.Name property. If the handler does not recognize the -// assembly name, it returns null (Nothing in Visual Basic, nullptr in Visual C++). +// The handler for the AssemblyResolve event receives the display name of the assembly to +// be loaded, in the ResolveEventArgs.Name property. If the handler does not recognize the +// assembly name, it returns null (Nothing in Visual Basic, nullptr in Visual C++). // -// - If the handler recognizes the assembly name, it can load and return an assembly that -// satisfies the request. The following list describes some sample scenarios. +// - If the handler recognizes the assembly name, it can load and return an assembly that +// satisfies the request. The following list describes some sample scenarios. // -// - If the handler knows the location of a version of the assembly, it can load the assembly by -// using the Assembly.LoadFrom or Assembly.LoadFile method, and can return the loaded assembly if successful. +// - If the handler knows the location of a version of the assembly, it can load the assembly by +// using the Assembly.LoadFrom or Assembly.LoadFile method, and can return the loaded assembly if successful. // -// - If the handler has access to a database of assemblies stored as byte arrays, it can load a byte array by -// using one of the Assembly.Load method overloads that take a byte array. +// - If the handler has access to a database of assemblies stored as byte arrays, it can load a byte array by +// using one of the Assembly.Load method overloads that take a byte array. // // - The handler can generate a dynamic assembly and return it. -// -// It is the responsibility of the event handler to return a suitable assembly. The handler can parse the display -// name of the requested assembly by passing the ResolveEventArgs.Name property value to the AssemblyName(String) -// constructor. Beginning with the .NET Framework version 4, the handler can use the ResolveEventArgs.RequestingAssembly -// property to determine whether the current request is a dependency of another assembly. This information can help +// +// It is the responsibility of the event handler to return a suitable assembly. The handler can parse the display +// name of the requested assembly by passing the ResolveEventArgs.Name property value to the AssemblyName(String) +// constructor. Beginning with the .NET Framework version 4, the handler can use the ResolveEventArgs.RequestingAssembly +// property to determine whether the current request is a dependency of another assembly. This information can help // identify an assembly that will satisfy the dependency. -// -// The event handler can return a different version of the assembly than the version that was requested. -// -// In most cases, the assembly that is returned by the handler appears in the load context, regardless of the context -// the handler loads it into. For example, if the handler uses the Assembly.LoadFrom method to load an assembly into -// the load-from context, the assembly appears in the load context when the handler returns it. However, in the following +// +// The event handler can return a different version of the assembly than the version that was requested. +// +// In most cases, the assembly that is returned by the handler appears in the load context, regardless of the context +// the handler loads it into. For example, if the handler uses the Assembly.LoadFrom method to load an assembly into +// the load-from context, the assembly appears in the load context when the handler returns it. However, in the following // case the assembly appears without context when the handler returns it: -// +// // - The handler loads an assembly without context. // - The ResolveEventArgs.RequestingAssembly property is not null. -// - The requesting assembly (that is, the assembly that is returned by the ResolveEventArgs.RequestingAssembly property) -// was loaded without context. -// +// - The requesting assembly (that is, the assembly that is returned by the ResolveEventArgs.RequestingAssembly property) +// was loaded without context. +// // On the coreclr we add an UnmanagedDll Resoution handler to ensure that native dll's can be searched for, // the desktop version of the Clr does not support this mechanism. // @@ -1564,276 +1867,160 @@ type internal FsiInterruptController(fsiOptions: FsiCommandLineOptions, fsiConso module internal MagicAssemblyResolution = -#if NETSTANDARD - // Cut down AssemblyLoadContext, for loading native libraries - type FsiNativeAssemblyLoadContext () = - inherit AssemblyLoadContext() - - member this.LoadNativeLibrary(path: string): IntPtr = - base.LoadUnmanagedDllFromPath(path) - - override _.Load(_path: AssemblyName): Assembly = - raise (NotImplementedException()) - - static member NativeLoadContext = new FsiNativeAssemblyLoadContext() -#endif - // See bug 5501 for details on decision to use UnsafeLoadFrom here. // Summary: // It is an explicit user trust decision to load an assembly with #r. Scripts are not run automatically (for example, by double-clicking in explorer). - // We considered setting loadFromRemoteSources in fsi.exe.config but this would transitively confer unsafe loading to the code in the referenced + // We considered setting loadFromRemoteSources in fsi.exe.config but this would transitively confer unsafe loading to the code in the referenced // assemblies. Better to let those assemblies decide for themselves which is safer. [] let private assemblyLoadFrom (path:string) = Assembly.UnsafeLoadFrom(path) - let Install(tcConfigB, tcImports: TcImports, fsiDynamicCompiler: FsiDynamicCompiler, fsiConsoleOutput: FsiConsoleOutput) = + let Install(tcConfigB, tcImports: TcImports, fsiDynamicCompiler: FsiDynamicCompiler, fsiConsoleOutput: FsiConsoleOutput) = let ResolveAssembly (ctok, m, tcConfigB, tcImports: TcImports, fsiDynamicCompiler: FsiDynamicCompiler, fsiConsoleOutput: FsiConsoleOutput, fullAssemName: string) = - try + try // Grab the name of the assembly let tcConfig = TcConfig.Create(tcConfigB,validate=false) let simpleAssemName = fullAssemName.Split([| ',' |]).[0] - if progress then fsiConsoleOutput.uprintfn "ATTEMPT MAGIC LOAD ON ASSEMBLY, simpleAssemName = %s" simpleAssemName // "Attempting to load a dynamically required assembly in response to an AssemblyResolve event by using known static assembly references..." + if progress then fsiConsoleOutput.uprintfn "ATTEMPT MAGIC LOAD ON ASSEMBLY, simpleAssemName = %s" simpleAssemName // "Attempting to load a dynamically required assembly in response to an AssemblyResolve event by using known static assembly references..." // Special case: Mono Windows Forms attempts to load an assembly called something like "Windows.Forms.resources" // We can't resolve this, so don't try. // REVIEW: Suggest 4481, delete this special case. - if simpleAssemName.EndsWith(".resources",StringComparison.OrdinalIgnoreCase) || - // See F# 1.0 Product Studio bug 1171 - simpleAssemName.EndsWith(".XmlSerializers",StringComparison.OrdinalIgnoreCase) || - (runningOnMono && simpleAssemName = "UIAutomationWinforms") then null else - + if (runningOnMono && simpleAssemName.EndsWith(".resources",StringComparison.OrdinalIgnoreCase)) || + simpleAssemName.EndsWith(".XmlSerializers", StringComparison.OrdinalIgnoreCase) || + (runningOnMono && simpleAssemName = "UIAutomationWinforms") then null + else // Special case: Is this the global unique dynamic assembly for FSI code? In this case just - // return the dynamic assembly itself. + // return the dynamic assembly itself. if fsiDynamicCompiler.DynamicAssemblyName = simpleAssemName then fsiDynamicCompiler.DynamicAssembly else // Otherwise continue - let assemblyReferenceTextDll = (simpleAssemName + ".dll") - let assemblyReferenceTextExe = (simpleAssemName + ".exe") + let assemblyReferenceTextDll = (simpleAssemName + ".dll") + let assemblyReferenceTextExe = (simpleAssemName + ".exe") let overallSearchResult = // OK, try to resolve as an existing DLL in the resolved reference set. This does unification by assembly name // once an assembly has been referenced. - let searchResult = tcImports.TryFindExistingFullyQualifiedPathBySimpleAssemblyName (ctok, simpleAssemName) + let searchResult = tcImports.TryFindExistingFullyQualifiedPathBySimpleAssemblyName simpleAssemName match searchResult with | Some r -> OkResult ([], Choice1Of2 r) - | _ -> + | _ -> // OK, try to resolve as a .dll let searchResult = tcImports.TryResolveAssemblyReference (ctok, AssemblyReference (m, assemblyReferenceTextDll, None), ResolveAssemblyReferenceMode.Speculative) match searchResult with | OkResult (warns,[r]) -> OkResult (warns, Choice1Of2 r.resolvedPath) - | _ -> + | _ -> // OK, try to resolve as a .exe let searchResult = tcImports.TryResolveAssemblyReference (ctok, AssemblyReference (m, assemblyReferenceTextExe, None), ResolveAssemblyReferenceMode.Speculative) match searchResult with | OkResult (warns, [r]) -> OkResult (warns, Choice1Of2 r.resolvedPath) - | _ -> + | _ -> if progress then fsiConsoleOutput.uprintfn "ATTEMPT LOAD, assemblyReferenceTextDll = %s" assemblyReferenceTextDll /// Take a look through the files quoted, perhaps with explicit paths - let searchResult = - (tcConfig.referencedDLLs - |> List.tryPick (fun assemblyReference -> + let searchResult = + (tcConfig.referencedDLLs + |> List.tryPick (fun assemblyReference -> if progress then fsiConsoleOutput.uprintfn "ATTEMPT MAGIC LOAD ON FILE, referencedDLL = %s" assemblyReference.Text - if System.String.Compare(Filename.fileNameOfPath assemblyReference.Text, assemblyReferenceTextDll,StringComparison.OrdinalIgnoreCase) = 0 || - System.String.Compare(Filename.fileNameOfPath assemblyReference.Text, assemblyReferenceTextExe,StringComparison.OrdinalIgnoreCase) = 0 then + if String.Compare(FileSystemUtils.fileNameOfPath assemblyReference.Text, assemblyReferenceTextDll,StringComparison.OrdinalIgnoreCase) = 0 || + String.Compare(FileSystemUtils.fileNameOfPath assemblyReference.Text, assemblyReferenceTextExe,StringComparison.OrdinalIgnoreCase) = 0 then Some(tcImports.TryResolveAssemblyReference (ctok, assemblyReference, ResolveAssemblyReferenceMode.Speculative)) else None )) match searchResult with | Some (OkResult (warns,[r])) -> OkResult (warns, Choice1Of2 r.resolvedPath) - | _ -> + | _ -> #if !NO_EXTENSIONTYPING match tcImports.TryFindProviderGeneratedAssemblyByName(ctok, simpleAssemName) with | Some(assembly) -> OkResult([],Choice2Of2 assembly) - | None -> + | None -> #endif // As a last resort, try to find the reference without an extension - match tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(ctok, ILAssemblyRef.Create(simpleAssemName,None,None,false,None,None)) with - | Some(resolvedPath) -> + match tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(ILAssemblyRef.Create(simpleAssemName,None,None,false,None,None)) with + | Some(resolvedPath) -> OkResult([],Choice1Of2 resolvedPath) - | None -> + | None -> ErrorResult([],Failure (FSIstrings.SR.fsiFailedToResolveAssembly(simpleAssemName))) - match overallSearchResult with + match overallSearchResult with | ErrorResult _ -> null - | OkResult _ -> + | OkResult _ -> let res = CommitOperationResult overallSearchResult - match res with - | Choice1Of2 assemblyName -> + match res with + | Choice1Of2 assemblyName -> if simpleAssemName <> "Mono.Posix" then fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiBindingSessionTo(assemblyName)) - assemblyLoadFrom assemblyName - | Choice2Of2 assembly -> + if isRunningOnCoreClr then + assemblyLoadFrom assemblyName + else + try + let an = AssemblyName.GetAssemblyName(assemblyName) + an.CodeBase <- assemblyName + Assembly.Load an + with | _ -> + assemblyLoadFrom assemblyName + | Choice2Of2 assembly -> assembly with e -> stopProcessingRecovery e range0 null -#if NETSTANDARD - let probingFileNames (name: string) = - // coreclr native library probing algorithm: https://github.com/dotnet/coreclr/blob/9773db1e7b1acb3ec75c9cc0e36bd62dcbacd6d5/src/System.Private.CoreLib/shared/System/Runtime/Loader/LibraryNameVariation.Unix.cs - let isRooted = Path.IsPathRooted name - let useSuffix s = not (name.Contains(s + ".") || name.EndsWith(s)) // linux devs often append version # to libraries I.e mydll.so.5.3.2 - let usePrefix = name.IndexOf(Path.DirectorySeparatorChar) = -1 // If name has directory information no add no prefix - && name.IndexOf(Path.AltDirectorySeparatorChar) = -1 - && name.IndexOf(Path.PathSeparator) = -1 - && name.IndexOf(Path.VolumeSeparatorChar) = -1 - let prefix = [| "lib" |] - let suffix = [| - if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then - ".dll" - ".exe" - elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then - ".dylib" - else - ".so" - |] - - [| - yield name // Bare name - if not (isRooted) then - for s in suffix do - if useSuffix s then // Suffix without prefix - yield (sprintf "%s%s" name s) - if usePrefix then - for p in prefix do // Suffix with prefix - yield (sprintf "%s%s%s" p name s) - elif usePrefix then - for p in prefix do // Prefix - yield (sprintf "%s%s" p name) - |] - - // Directories to start probing in - // Algorithm: - // Search for native libraries using: - // 1. Include directories - // 2. compilerToolPath directories - // 3. reference dll's - // 4. The implicit include directory - let probingRoots = - seq { - yield! tcConfigB.includes - yield! tcConfigB.compilerToolPaths - yield! (tcConfigB.referencedDLLs |> Seq.map(fun ref -> Path.GetDirectoryName(ref.Text))) - yield tcConfigB.implicitIncludeDir - } |>Seq.distinct - - // Computer valid dotnet-rids for this environment: - // https://docs.microsoft.com/en-us/dotnet/core/rid-catalog - // - // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... - let probingRids = - let processArchitecture = RuntimeInformation.ProcessArchitecture - let baseRid = - if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then "win" - elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then "osx" - else "linux" - let platformRid = - match processArchitecture with - | Architecture.X64 -> baseRid + "-x64" - | Architecture.X86 -> baseRid + "-x86" - | Architecture.Arm64 -> baseRid + "-arm64" - | _ -> baseRid + "arm" - [| "any"; baseRid; platformRid |] - - let resolveUnmanagedDll (assembly : Assembly) (name : string) : IntPtr = - ignore assembly - - // Enumerate probing roots looking for a dll that matches the probing name in the probed locations - let probeForNativeLibrary root rid name = - // Look for name in root - probingFileNames name |> Array.tryPick(fun name -> - let path = Path.Combine(root, "runtimes", rid, "native", name) - if File.Exists(path) then - Some path - else - None) - - let probe = - probingRoots |> Seq.tryPick(fun root -> - probingFileNames name |> Seq.tryPick(fun name -> - let path = Path.Combine(root, name) - if File.Exists(path) then - Some path - else - probingRids |> Seq.tryPick(fun rid -> probeForNativeLibrary root rid name))) - - match probe with - | Some path -> FsiNativeAssemblyLoadContext.NativeLoadContext.LoadNativeLibrary(path) - | None -> IntPtr.Zero -#endif - - let rangeStdin = rangeN Lexhelp.stdinMockFilename 0 + let rangeStdin = rangeN stdinMockFilename 0 - let resolveAssembly = new ResolveEventHandler(fun _ args -> - // Explanation: our understanding is that magic assembly resolution happens + let resolveAssembly = ResolveEventHandler(fun _ args -> + // Explanation: our understanding is that magic assembly resolution happens // during compilation. So we recover the CompilationThreadToken here. let ctok = AssumeCompilationThreadWithoutEvidence () ResolveAssembly (ctok, rangeStdin, tcConfigB, tcImports, fsiDynamicCompiler, fsiConsoleOutput, args.Name)) AppDomain.CurrentDomain.add_AssemblyResolve(resolveAssembly) -#if NETSTANDARD - // netstandard 2.1 has this property, unfortunately we don't build with that yet - //public event Func ResolvingUnmanagedDll - let resolveUnmanagedHandler = Func (resolveUnmanagedDll) - let eventInfo = typeof.GetEvent("ResolvingUnmanagedDll") - if not (isNull eventInfo) then - eventInfo.AddEventHandler(AssemblyLoadContext.Default, resolveUnmanagedHandler) -#endif - - { new System.IDisposable with + { new IDisposable with member x.Dispose() = AppDomain.CurrentDomain.remove_AssemblyResolve(resolveAssembly) -#if NETSTANDARD - if not (isNull eventInfo) then - eventInfo.RemoveEventHandler(AssemblyLoadContext.Default, resolveUnmanagedHandler) -#endif } //---------------------------------------------------------------------------- -// Reading stdin +// Reading stdin //---------------------------------------------------------------------------- type internal FsiStdinLexerProvider - (tcConfigB, fsiStdinSyphon, - fsiConsoleInput : FsiConsoleInput, - fsiConsoleOutput : FsiConsoleOutput, + (tcConfigB, fsiStdinSyphon, + fsiConsoleInput : FsiConsoleInput, + fsiConsoleOutput : FsiConsoleOutput, fsiOptions : FsiCommandLineOptions, - lexResourceManager : LexResourceManager) = + lexResourceManager : LexResourceManager) = // #light is the default for FSI - let interactiveInputLightSyntaxStatus = + let interactiveInputLightSyntaxStatus = let initialLightSyntaxStatus = tcConfigB.light <> Some false LightSyntaxStatus (initialLightSyntaxStatus, false (* no warnings *)) - let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId - - let LexbufFromLineReader (fsiStdinSyphon: FsiStdinSyphon) readF = + let LexbufFromLineReader (fsiStdinSyphon: FsiStdinSyphon) readF = UnicodeLexing.FunctionAsLexbuf - (isFeatureSupported, (fun (buf: char[], start, len) -> + (true, tcConfigB.langVersion, (fun (buf: char[], start, len) -> //fprintf fsiConsoleOutput.Out "Calling ReadLine\n" let inputOption = try Some(readF()) with :? EndOfStreamException -> None inputOption |> Option.iter (fun t -> fsiStdinSyphon.Add (t + "\n")) - match inputOption with - | Some(null) | None -> + match inputOption with + | Some(null) | None -> if progress then fprintfn fsiConsoleOutput.Out "End of file from TextReader.ReadLine" 0 | Some (input:string) -> - let input = input + "\n" - let ninput = input.Length + let input = input + "\n" + let ninput = input.Length if ninput > len then fprintf fsiConsoleOutput.Error "%s" (FSIstrings.SR.fsiLineTooLong()) - let ntrimmed = min len ninput + let ntrimmed = min len ninput for i = 0 to ntrimmed-1 do buf.[i+start] <- input.[i] ntrimmed @@ -1843,51 +2030,49 @@ type internal FsiStdinLexerProvider // Reading stdin as a lex stream //---------------------------------------------------------------------------- - let removeZeroCharsFromString (str:string) = (* bug://4466 *) + let removeZeroCharsFromString (str:string) = (* bug:/4466 *) if str<>null && str.Contains("\000") then - System.String(str |> Seq.filter (fun c -> c<>'\000') |> Seq.toArray) + String(str |> Seq.filter (fun c -> c<>'\000') |> Seq.toArray) else str let CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger) = - Lexhelp.resetLexbufPos sourceFileName lexbuf - let skip = true // don't report whitespace from lexer + resetLexbufPos sourceFileName lexbuf + let skip = true // don't report whitespace from lexer let defines = "INTERACTIVE"::tcConfigB.conditionalCompilationDefines - let lexargs = mkLexargs (sourceFileName,defines, interactiveInputLightSyntaxStatus, lexResourceManager, [], errorLogger, PathMap.empty) + let lexargs = mkLexargs (defines, interactiveInputLightSyntaxStatus, lexResourceManager, [], errorLogger, PathMap.empty) let tokenizer = LexFilter.LexFilter(interactiveInputLightSyntaxStatus, tcConfigB.compilingFslib, Lexer.token lexargs skip, lexbuf) tokenizer - let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId - - // Create a new lexer to read stdin - member __.CreateStdinLexer (errorLogger) = - let lexbuf = - match fsiConsoleInput.TryGetConsole() with - | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.IsInteractiveServer -> - LexbufFromLineReader fsiStdinSyphon (fun () -> - match fsiConsoleInput.TryGetFirstLine() with + // Create a new lexer to read stdin + member _.CreateStdinLexer errorLogger = + let lexbuf = + match fsiConsoleInput.TryGetConsole() with + | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.UseServerPrompt -> + LexbufFromLineReader fsiStdinSyphon (fun () -> + match fsiConsoleInput.TryGetFirstLine() with | Some firstLine -> firstLine | None -> console()) - | _ -> + | _ -> LexbufFromLineReader fsiStdinSyphon (fun () -> fsiConsoleInput.In.ReadLine() |> removeZeroCharsFromString) fsiStdinSyphon.Reset() - CreateLexerForLexBuffer (Lexhelp.stdinMockFilename, lexbuf, errorLogger) + CreateLexerForLexBuffer (stdinMockFilename, lexbuf, errorLogger) // Create a new lexer to read an "included" script file - member __.CreateIncludedScriptLexer (sourceFileName, reader, errorLogger) = - let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(isFeatureSupported, reader) + member _.CreateIncludedScriptLexer (sourceFileName, reader, errorLogger) = + let lexbuf = UnicodeLexing.StreamReaderAsLexbuf(true, tcConfigB.langVersion, reader) CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger) // Create a new lexer to read a string member this.CreateStringLexer (sourceFileName, source, errorLogger) = - let lexbuf = UnicodeLexing.StringAsLexbuf(isFeatureSupported, source) + let lexbuf = UnicodeLexing.StringAsLexbuf(true, tcConfigB.langVersion, source) CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger) - member __.ConsoleInput = fsiConsoleInput + member _.ConsoleInput = fsiConsoleInput - member __.CreateBufferLexer (sourceFileName, lexbuf, errorLogger) = CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger) + member _.CreateBufferLexer (sourceFileName, lexbuf, errorLogger) = CreateLexerForLexBuffer (sourceFileName, lexbuf, errorLogger) //---------------------------------------------------------------------------- @@ -1896,8 +2081,8 @@ type internal FsiStdinLexerProvider //---------------------------------------------------------------------------- type internal FsiInteractionProcessor - (fsi: FsiEvaluationSessionHostConfig, - tcConfigB, + (fsi: FsiEvaluationSessionHostConfig, + tcConfigB, fsiOptions: FsiCommandLineOptions, fsiDynamicCompiler: FsiDynamicCompiler, fsiConsolePrompt : FsiConsolePrompt, @@ -1905,224 +2090,234 @@ type internal FsiInteractionProcessor fsiInterruptController : FsiInterruptController, fsiStdinLexerProvider : FsiStdinLexerProvider, lexResourceManager : LexResourceManager, - initialInteractiveState) = + initialInteractiveState) = let referencedAssemblies = Dictionary() - let assemblyReferencedEvent = Control.Event() - let mutable currState = initialInteractiveState let event = Control.Event() let setCurrState s = currState <- s; event.Trigger() - let runCodeOnEventLoop errorLogger f istate = - try - fsi.EventLoopInvoke (fun () -> + let runCodeOnEventLoop errorLogger f istate = + try + fsi.EventLoopInvoke (fun () -> - // Explanation: We assume the event loop on the 'fsi' object correctly transfers control to + // Explanation: We assume the event loop on the 'fsi' object correctly transfers control to // a unique compilation thread. let ctok = AssumeCompilationThreadWithoutEvidence() // FSI error logging on switched to thread InstallErrorLoggingOnThisThread errorLogger use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID - f ctok istate) - with _ -> + f ctok istate) + with _ -> (istate,Completed None) - - let InteractiveCatch (errorLogger: ErrorLogger) (f:_ -> _ * FsiInteractionStepStatus) istate = + + let InteractiveCatch (errorLogger: ErrorLogger) (f:_ -> _ * FsiInteractionStepStatus) istate = try - // reset error count - match errorLogger with - | :? ErrorLoggerThatStopsOnFirstError as errorLogger -> errorLogger.ResetErrorCount() + // reset error count + match errorLogger with + | :? ErrorLoggerThatStopsOnFirstError as errorLogger -> errorLogger.ResetErrorCount() | _ -> () f istate with e -> stopProcessingRecovery e range0 - istate,CompletedWithReportedError e - - let isFeatureSupported featureId = tcConfigB.langVersion.SupportsFeature featureId + istate, CompletedWithReportedError e - let rangeStdin = rangeN Lexhelp.stdinMockFilename 0 + let rangeStdin = rangeN stdinMockFilename 0 let ChangeDirectory (path:string) m = let tcConfig = TcConfig.Create(tcConfigB,validate=false) - let path = tcConfig.MakePathAbsolute path - if Directory.Exists(path) then + let path = tcConfig.MakePathAbsolute path + if FileSystem.DirectoryExistsShim(path) then tcConfigB.implicitIncludeDir <- path else error(Error(FSIstrings.SR.fsiDirectoryDoesNotExist(path),m)) /// Parse one interaction. Called on the parser thread. - let ParseInteraction (tokenizer:LexFilter.LexFilter) = - let mutable lastToken = Parser.ELSE // Any token besides SEMICOLON_SEMICOLON will do for initial value - try + let ParseInteraction (tokenizer:LexFilter.LexFilter) = + let mutable lastToken = Parser.ELSE // Any token besides SEMICOLON_SEMICOLON will do for initial value + try if progress then fprintfn fsiConsoleOutput.Out "In ParseInteraction..." - let input = - Lexhelp.reusingLexbufForParsing tokenizer.LexBuffer (fun () -> - let lexerWhichSavesLastToken lexbuf = - let tok = tokenizer.Lexer lexbuf + let input = + reusingLexbufForParsing tokenizer.LexBuffer (fun () -> + let lexerWhichSavesLastToken _lexbuf = + let tok = tokenizer.GetToken() lastToken <- tok - tok + tok Parser.interaction lexerWhichSavesLastToken tokenizer.LexBuffer) Some input with e -> // On error, consume tokens until to ;; or EOF. // Caveat: Unless the error parse ended on ;; - so check the lastToken returned by the lexer function. - // Caveat: What if this was a look-ahead? That's fine! Since we need to skip to the ;; anyway. + // Caveat: What if this was a look-ahead? That's fine! Since we need to skip to the ;; anyway. if (match lastToken with Parser.SEMICOLON_SEMICOLON -> false | _ -> true) then let mutable tok = Parser.ELSE (* <-- any token <> SEMICOLON_SEMICOLON will do *) - while (match tok with Parser.SEMICOLON_SEMICOLON -> false | _ -> true) + while (match tok with Parser.SEMICOLON_SEMICOLON -> false | _ -> true) && not tokenizer.LexBuffer.IsPastEndOfStream do - tok <- tokenizer.Lexer tokenizer.LexBuffer + tok <- tokenizer.GetToken() - stopProcessingRecovery e range0 + stopProcessingRecovery e range0 None /// Execute a single parsed interaction. Called on the GUI/execute/main thread. - let ExecInteraction (ctok, tcConfig:TcConfig, istate, action:ParsedFsiInteraction, errorLogger: ErrorLogger) = + let ExecInteraction (ctok, tcConfig:TcConfig, istate, action:ParsedScriptInteraction, errorLogger: ErrorLogger) = + let packageManagerDirective directive path m = + let dm = fsiOptions.DependencyProvider.TryFindDependencyManagerInPath(tcConfigB.compilerToolPaths, getOutputDir tcConfigB, reportError m, path) + match dm with + | null, null -> + // error already reported + istate, CompletedWithAlreadyReportedError + + | _, dependencyManager when not(isNull dependencyManager) -> + if tcConfig.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then + fsiDynamicCompiler.EvalDependencyManagerTextFragment(dependencyManager, directive, m, path) + istate, Completed None + else + errorR(Error(FSComp.SR.packageManagementRequiresVFive(), m)) + istate, Completed None + + | _, _ when directive = Directive.Include -> + errorR(Error(FSComp.SR.poundiNotSupportedByRegisteredDependencyManagers(), m)) + istate,Completed None + + | p, _ -> + let path = + if String.IsNullOrWhiteSpace(p) then "" + else p + let resolutions,istate = fsiDynamicCompiler.EvalRequireReference(ctok, istate, m, path) + resolutions |> List.iter (fun ar -> + let format = + if tcConfig.shadowCopyReferences then + let resolvedPath = ar.resolvedPath.ToUpperInvariant() + let fileTime = FileSystem.GetLastWriteTimeShim(resolvedPath) + match referencedAssemblies.TryGetValue resolvedPath with + | false, _ -> + referencedAssemblies.Add(resolvedPath, fileTime) + FSIstrings.SR.fsiDidAHashr(ar.resolvedPath) + | true, time when time <> fileTime -> + FSIstrings.SR.fsiDidAHashrWithStaleWarning(ar.resolvedPath) + | _ -> + FSIstrings.SR.fsiDidAHashr(ar.resolvedPath) + else + FSIstrings.SR.fsiDidAHashrWithLockWarning(ar.resolvedPath) + fsiConsoleOutput.uprintnfnn "%s" format) + istate,Completed None + istate |> InteractiveCatch errorLogger (fun istate -> - match action with - | IDefns ([ ],_) -> - let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) + match action with + | ParsedScriptInteraction.Definitions ([], _) -> + let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) istate,Completed None - | IDefns ([ SynModuleDecl.DoExpr(_,expr,_)],_) -> - let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) + | ParsedScriptInteraction.Definitions ([SynModuleDecl.DoExpr(_, expr, _)], _) -> + let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalParsedExpression(ctok, errorLogger, istate, expr) - | IDefns (defs,_) -> - let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) + | ParsedScriptInteraction.Definitions (defs,_) -> + let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, true, false, defs) - | IHash (ParsedHashDirective("load",sourceFiles,m),_) -> - let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("load", ParsedHashDirectiveArguments sourceFiles, m), _) -> + let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) fsiDynamicCompiler.EvalSourceFiles (ctok, istate, m, sourceFiles, lexResourceManager, errorLogger),Completed None - | IHash (ParsedHashDirective(("reference" | "r"), [path], m), _) -> - match DependencyManagerIntegration.tryFindDependencyManagerInPath tcConfigB.compilerToolPaths tcConfigB.outputDir m (path:string) with - | DependencyManagerIntegration.ReferenceType.RegisteredDependencyManager packageManager -> - if tcConfig.langVersion.SupportsFeature(LanguageFeature.PackageManagement) then - fsiDynamicCompiler.EvalDependencyManagerTextFragment(packageManager, m, path) - istate,Completed None - else - errorR(Error(FSComp.SR.packageManagementRequiresVFive(), m)) - istate, Completed None - - | DependencyManagerIntegration.ReferenceType.UnknownType -> - // error already reported - istate,Completed None - - | DependencyManagerIntegration.ReferenceType.Library path -> - let resolutions,istate = fsiDynamicCompiler.EvalRequireReference(ctok, istate, m, path) - resolutions |> List.iter (fun ar -> - let format = - if tcConfig.shadowCopyReferences then - let resolvedPath = ar.resolvedPath.ToUpperInvariant() - let fileTime = File.GetLastWriteTimeUtc(resolvedPath) - match referencedAssemblies.TryGetValue resolvedPath with - | false, _ -> - referencedAssemblies.Add(resolvedPath, fileTime) - FSIstrings.SR.fsiDidAHashr(ar.resolvedPath) - | true, time when time <> fileTime -> - FSIstrings.SR.fsiDidAHashrWithStaleWarning(ar.resolvedPath) - | _ -> - FSIstrings.SR.fsiDidAHashr(ar.resolvedPath) - else - FSIstrings.SR.fsiDidAHashrWithLockWarning(ar.resolvedPath) - fsiConsoleOutput.uprintnfnn "%s" format) - istate,Completed None + | ParsedScriptInteraction.HashDirective (ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments [path], m), _) -> + packageManagerDirective Directive.Resolution path m - | IHash (ParsedHashDirective("I",[path],m),_) -> - tcConfigB.AddIncludePath (m,path, tcConfig.implicitIncludeDir) + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("i", ParsedHashDirectiveArguments [path], m), _) -> + packageManagerDirective Directive.Include path m + + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("I", ParsedHashDirectiveArguments [path], m), _) -> + tcConfigB.AddIncludePath (m, path, tcConfig.implicitIncludeDir) fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiDidAHashI(tcConfig.MakePathAbsolute path)) - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("cd",[path],m),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("cd", ParsedHashDirectiveArguments [path], m), _) -> ChangeDirectory path m - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("silentCd",[path],m),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("silentCd", ParsedHashDirectiveArguments [path], m), _) -> ChangeDirectory path m fsiConsolePrompt.SkipNext() (* "silent" directive *) - istate,Completed None - - | IHash (ParsedHashDirective("dbgbreak",[],_),_) -> - {istate with debugBreak = true},Completed None + istate, Completed None + + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("dbgbreak", [], _), _) -> + {istate with debugBreak = true}, Completed None - | IHash (ParsedHashDirective("time",[],_),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", [], _), _) -> if istate.timing then fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff()) else fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn()) - {istate with timing = not istate.timing},Completed None + {istate with timing = not istate.timing}, Completed None - | IHash (ParsedHashDirective("time",[("on" | "off") as v],_),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", ParsedHashDirectiveArguments ["on" | "off" as v], _), _) -> if v <> "on" then fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff()) else fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn()) - {istate with timing = (v = "on")},Completed None + {istate with timing = (v = "on")}, Completed None - | IHash (ParsedHashDirective("nowarn",numbers,m),_) -> - List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m,d)) numbers - istate,Completed None + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers, m), _) -> + List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m, d)) numbers + istate, Completed None - | IHash (ParsedHashDirective("terms",[],_),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("terms", [], _), _) -> tcConfigB.showTerms <- not tcConfig.showTerms - istate,Completed None + istate, Completed None - | IHash (ParsedHashDirective("types",[],_),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("types", [], _), _) -> fsiOptions.ShowTypes <- not fsiOptions.ShowTypes - istate,Completed None + istate, Completed None #if DEBUG - | IHash (ParsedHashDirective("ilcode",[],_m),_) -> - fsiOptions.ShowILCode <- not fsiOptions.ShowILCode; - istate,Completed None + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("ilcode", [], _m), _) -> + fsiOptions.ShowILCode <- not fsiOptions.ShowILCode; + istate, Completed None - | IHash (ParsedHashDirective("info",[],_m),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("info", [], _m), _) -> PrintOptionInfo tcConfigB - istate,Completed None + istate, Completed None #endif - | IHash (ParsedHashDirective(("q" | "quit"),[],_),_) -> + | ParsedScriptInteraction.HashDirective (ParsedHashDirective(("q" | "quit"), [], _), _) -> fsiInterruptController.Exit() - | IHash (ParsedHashDirective("help",[],_),_) -> - fsiOptions.ShowHelp() - istate,Completed None + | ParsedScriptInteraction.HashDirective (ParsedHashDirective("help", [], m), _) -> + fsiOptions.ShowHelp(m) + istate, Completed None - | IHash (ParsedHashDirective(c,arg,_),_) -> - fsiConsoleOutput.uprintfn "%s" (FSIstrings.SR.fsiInvalidDirective(c, String.concat " " arg)) // REVIEW: uprintnfnn - like other directives above - istate,Completed None (* REVIEW: cont = CompletedWithReportedError *) + | ParsedScriptInteraction.HashDirective (ParsedHashDirective(c, ParsedHashDirectiveArguments arg, m), _) -> + warning(Error((FSComp.SR.fsiInvalidDirective(c, String.concat " " arg)), m)) + istate, Completed None ) /// Execute a single parsed interaction which may contain multiple items to be executed /// independently, because some are #directives. Called on the GUI/execute/main thread. - /// + /// /// #directive comes through with other definitions as a SynModuleDecl.HashDirective. /// We split these out for individual processing. let rec execParsedInteractions (ctok, tcConfig, istate, action, errorLogger: ErrorLogger, lastResult:option, cancellationToken: CancellationToken) = cancellationToken.ThrowIfCancellationRequested() - let action,nextAction,istate = + let action,nextAction,istate = match action with | None -> None,None,istate - | Some (IHash _) -> action,None,istate - | Some (IDefns ([],_)) -> None,None,istate - | Some (IDefns (SynModuleDecl.HashDirective(hash,mh) :: defs,m)) -> - Some (IHash(hash,mh)),Some (IDefns(defs,m)),istate - - | Some (IDefns (defs,m)) -> - let isDefHash = function SynModuleDecl.HashDirective(_,_) -> true | _ -> false - let isBreakable def = + | Some (ParsedScriptInteraction.HashDirective _) -> action,None,istate + | Some (ParsedScriptInteraction.Definitions ([],_)) -> None,None,istate + | Some (ParsedScriptInteraction.Definitions (SynModuleDecl.HashDirective(hash,mh) :: defs,m)) -> + Some (ParsedScriptInteraction.HashDirective(hash,mh)),Some (ParsedScriptInteraction.Definitions(defs,m)),istate + + | Some (ParsedScriptInteraction.Definitions (defs,m)) -> + let isDefHash = function SynModuleDecl.HashDirective _ -> true | _ -> false + let isBreakable def = // only add automatic debugger breaks before 'let' or 'do' expressions with sequence points match def with - | SynModuleDecl.DoExpr (SequencePointInfoForBinding.SequencePointAtBinding _, _, _) - | SynModuleDecl.Let (_, SynBinding.Binding(_, _, _, _, _, _, _, _,_,_,_, SequencePointInfoForBinding.SequencePointAtBinding _) :: _, _) -> true + | SynModuleDecl.DoExpr (DebugPointAtBinding.Yes _, _, _) + | SynModuleDecl.Let (_, SynBinding(_, _, _, _, _, _, _, _,_,_,_, DebugPointAtBinding.Yes _) :: _, _) -> true | _ -> false let defsA = Seq.takeWhile (isDefHash >> not) defs |> Seq.toList let defsB = Seq.skipWhile (isDefHash >> not) defs |> Seq.toList @@ -2139,31 +2334,47 @@ type internal FsiInteractionProcessor | _ -> defsA, istate else defsA,istate - // When the last declaration has a shape of DoExp (i.e., non-binding), + // When the last declaration has a shape of DoExp (i.e., non-binding), // transform it to a shape of "let it = ", so we can refer it. - let defsA = if defsA.Length <= 1 || not (List.isEmpty defsB) then defsA else - match List.headAndTail (List.rev defsA) with - | SynModuleDecl.DoExpr(_,exp,_), rest -> (rest |> List.rev) @ (fsiDynamicCompiler.BuildItBinding exp) - | _ -> defsA - - Some (IDefns(defsA,m)),Some (IDefns(defsB,m)),istate + let defsA = + if not (isNil defsB) then defsA else + match defsA with + | [] -> defsA + | [_] -> defsA + | _ -> + match List.rev defsA with + | SynModuleDecl.DoExpr(_,exp,_) :: rest -> (rest |> List.rev) @ (fsiDynamicCompiler.BuildItBinding exp) + | _ -> defsA + + Some (ParsedScriptInteraction.Definitions(defsA,m)),Some (ParsedScriptInteraction.Definitions(defsB,m)),istate match action, lastResult with - | None, Some prev -> assert(nextAction.IsNone); istate, prev - | None,_ -> assert(nextAction.IsNone); istate, Completed None + | None, Some prev -> assert nextAction.IsNone; istate, prev + | None,_ -> assert nextAction.IsNone; istate, Completed None | Some action, _ -> let istate,cont = ExecInteraction (ctok, tcConfig, istate, action, errorLogger) match cont with | Completed _ -> execParsedInteractions (ctok, tcConfig, istate, nextAction, errorLogger, Some cont, cancellationToken) | CompletedWithReportedError e -> istate,CompletedWithReportedError e (* drop nextAction on error *) + | CompletedWithAlreadyReportedError -> istate,CompletedWithAlreadyReportedError (* drop nextAction on error *) | EndOfFile -> istate,defaultArg lastResult (Completed None) (* drop nextAction on EOF *) | CtrlC -> istate,CtrlC (* drop nextAction on CtrlC *) + /// Execute a single parsed interaction which may contain multiple items to be executed + /// independently + let executeParsedInteractions (ctok, tcConfig, istate, action, errorLogger: ErrorLogger, lastResult:option, cancellationToken: CancellationToken) = + let istate, completed = execParsedInteractions (ctok, tcConfig, istate, action, errorLogger, lastResult, cancellationToken) + match completed with + | Completed _ -> + let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger) + istate, completed + | _ -> istate, completed + /// Execute a single parsed interaction on the parser/execute thread. - let mainThreadProcessAction ctok action istate = - try + let mainThreadProcessAction ctok action istate = + try let tcConfig = TcConfig.Create(tcConfigB,validate=false) - if progress then fprintfn fsiConsoleOutput.Out "In mainThreadProcessAction..."; + if progress then fprintfn fsiConsoleOutput.Out "In mainThreadProcessAction..."; fsiInterruptController.InterruptAllowed <- InterruptCanRaiseException; let res = action ctok tcConfig istate fsiInterruptController.ClearInterruptRequest() @@ -2181,95 +2392,100 @@ type internal FsiInteractionProcessor stopProcessingRecovery e range0; istate, CompletedWithReportedError e - let mainThreadProcessParsedInteractions ctok errorLogger (action, istate) cancellationToken = + let mainThreadProcessParsedInteractions ctok errorLogger (action, istate) cancellationToken = istate |> mainThreadProcessAction ctok (fun ctok tcConfig istate -> - execParsedInteractions (ctok, tcConfig, istate, action, errorLogger, None, cancellationToken)) + executeParsedInteractions (ctok, tcConfig, istate, action, errorLogger, None, cancellationToken)) let parseExpression (tokenizer:LexFilter.LexFilter) = reusingLexbufForParsing tokenizer.LexBuffer (fun () -> - Parser.typedSeqExprEOF tokenizer.Lexer tokenizer.LexBuffer) + Parser.typedSequentialExprEOF (fun _ -> tokenizer.GetToken()) tokenizer.LexBuffer) - let mainThreadProcessParsedExpression ctok errorLogger (expr, istate) = + let mainThreadProcessParsedExpression ctok errorLogger (expr, istate) = istate |> InteractiveCatch errorLogger (fun istate -> istate |> mainThreadProcessAction ctok (fun ctok _tcConfig istate -> - fsiDynamicCompiler.EvalParsedExpression(ctok, errorLogger, istate, expr) )) + fsiDynamicCompiler.EvalParsedExpression(ctok, errorLogger, istate, expr) )) let commitResult (istate, result) = match result with | FsiInteractionStepStatus.CtrlC -> Choice2Of2 (Some (OperationCanceledException() :> exn)) | FsiInteractionStepStatus.EndOfFile -> Choice2Of2 (Some (System.Exception "End of input")) - | FsiInteractionStepStatus.Completed res -> + | FsiInteractionStepStatus.Completed res -> setCurrState istate Choice1Of2 res - | FsiInteractionStepStatus.CompletedWithReportedError (StopProcessingExn userExnOpt) -> + | FsiInteractionStepStatus.CompletedWithReportedError (StopProcessingExn userExnOpt) -> Choice2Of2 userExnOpt - | FsiInteractionStepStatus.CompletedWithReportedError _ -> + | FsiInteractionStepStatus.CompletedWithReportedError _ + | FsiInteractionStepStatus.CompletedWithAlreadyReportedError -> Choice2Of2 None - /// Parse then process one parsed interaction. + /// Parse then process one parsed interaction. /// /// During normal execution, this initially runs on the parser - /// thread, then calls runCodeOnMainThread when it has completed + /// thread, then calls runCodeOnMainThread when it has completed /// parsing and needs to typecheck and execute a definition. This blocks the parser thread /// until execution has competed on the GUI thread. /// /// During processing of startup scripts, this runs on the main thread. /// /// This is blocking: it reads until one chunk of input have been received, unless IsPastEndOfStream is true - member __.ParseAndExecOneSetOfInteractionsFromLexbuf (runCodeOnMainThread, istate:FsiDynamicCompilerState, tokenizer:LexFilter.LexFilter, errorLogger, ?cancellationToken: CancellationToken) = + member _.ParseAndExecOneSetOfInteractionsFromLexbuf (runCodeOnMainThread, istate:FsiDynamicCompilerState, tokenizer:LexFilter.LexFilter, errorLogger, ?cancellationToken: CancellationToken) = let cancellationToken = defaultArg cancellationToken CancellationToken.None - if tokenizer.LexBuffer.IsPastEndOfStream then - let stepStatus = - if fsiInterruptController.FsiInterruptStdinState = StdinEOFPermittedBecauseCtrlCRecentlyPressed then - fsiInterruptController.FsiInterruptStdinState <- StdinNormal; + if tokenizer.LexBuffer.IsPastEndOfStream then + let stepStatus = + if fsiInterruptController.FsiInterruptStdinState = StdinEOFPermittedBecauseCtrlCRecentlyPressed then + fsiInterruptController.FsiInterruptStdinState <- StdinNormal; CtrlC - else + else EndOfFile istate,stepStatus - else + else fsiConsolePrompt.Print(); - istate |> InteractiveCatch errorLogger (fun istate -> + istate |> InteractiveCatch errorLogger (fun istate -> if progress then fprintfn fsiConsoleOutput.Out "entering ParseInteraction..."; - // Parse the interaction. When FSI.EXE is waiting for input from the console the - // parser thread is blocked somewhere deep this call. + // Parse the interaction. When FSI.EXE is waiting for input from the console the + // parser thread is blocked somewhere deep this call. let action = ParseInteraction tokenizer if progress then fprintfn fsiConsoleOutput.Out "returned from ParseInteraction...calling runCodeOnMainThread..."; - // After we've unblocked and got something to run we switch - // over to the run-thread (e.g. the GUI thread) + // After we've unblocked and got something to run we switch + // over to the run-thread (e.g. the GUI thread) let res = istate |> runCodeOnMainThread (fun ctok istate -> mainThreadProcessParsedInteractions ctok errorLogger (action, istate) cancellationToken) if progress then fprintfn fsiConsoleOutput.Out "Just called runCodeOnMainThread, res = %O..." res; res) - - member __.CurrentState = currState + + member _.CurrentState = currState /// Perform an "include" on a script file (i.e. a script file specified on the command line) member processor.EvalIncludedScript (ctok, istate, sourceFile, m, errorLogger) = let tcConfig = TcConfig.Create(tcConfigB, validate=false) // Resolve the filename to an absolute filename - let sourceFile = tcConfig.ResolveSourceFile(m, sourceFile, tcConfig.implicitIncludeDir) - // During the processing of the file, further filenames are + let sourceFile = tcConfig.ResolveSourceFile(m, sourceFile, tcConfig.implicitIncludeDir) + // During the processing of the file, further filenames are // resolved relative to the home directory of the loaded file. WithImplicitHome (tcConfigB, directoryName sourceFile) (fun () -> // An included script file may contain maybe several interaction blocks. // We repeatedly parse and process these, until an error occurs. - use reader = File.OpenReaderAndRetry (sourceFile, tcConfigB.inputCodePage, (*retryLocked*)false) + + use fileStream = FileSystem.OpenFileForReadShim(sourceFile) + use reader = fileStream.GetReader(tcConfigB.inputCodePage, false) + let tokenizer = fsiStdinLexerProvider.CreateIncludedScriptLexer (sourceFile, reader, errorLogger) let rec run istate = let istate,cont = processor.ParseAndExecOneSetOfInteractionsFromLexbuf ((fun f istate -> f ctok istate), istate, tokenizer, errorLogger) - match cont with Completed _ -> run istate | _ -> istate,cont + match cont with Completed _ -> run istate | _ -> istate,cont - let istate,cont = run istate + let istate,cont = run istate match cont with | Completed _ -> failwith "EvalIncludedScript: Completed expected to have relooped" + | CompletedWithAlreadyReportedError -> istate,CompletedWithAlreadyReportedError | CompletedWithReportedError e -> istate,CompletedWithReportedError e - | EndOfFile -> istate,Completed None// here file-EOF is normal, continue required + | EndOfFile -> istate,Completed None// here file-EOF is normal, continue required | CtrlC -> istate,CtrlC ) @@ -2283,9 +2499,10 @@ type internal FsiInteractionProcessor let istate,cont = InteractiveCatch errorLogger (fun istate -> processor.EvalIncludedScript (ctok, istate, sourceFile, rangeStdin, errorLogger)) istate match cont with | Completed _ -> processor.EvalIncludedScripts (ctok, istate, moreSourceFiles, errorLogger) - | CompletedWithReportedError _ -> istate // do not process any more files - | CtrlC -> istate // do not process any more files - | EndOfFile -> assert false; istate // This is unexpected. EndOfFile is replaced by Completed in the called function + | CompletedWithAlreadyReportedError -> istate // do not process any more files + | CompletedWithReportedError _ -> istate // do not process any more files + | CtrlC -> istate // do not process any more files + | EndOfFile -> assert false; istate // This is unexpected. EndOfFile is replaced by Completed in the called function member processor.LoadInitialFiles (ctok, errorLogger) = @@ -2293,34 +2510,34 @@ type internal FsiInteractionProcessor let rec consume istate sourceFiles = match sourceFiles with | [] -> istate - | (_,isScript1) :: _ -> - let sourceFiles,rest = List.takeUntil (fun (_,isScript2) -> isScript1 <> isScript2) sourceFiles - let sourceFiles = List.map fst sourceFiles - let istate = - if isScript1 then + | (_,isScript1) :: _ -> + let sourceFiles,rest = List.takeUntil (fun (_,isScript2) -> isScript1 <> isScript2) sourceFiles + let sourceFiles = List.map fst sourceFiles + let istate = + if isScript1 then processor.EvalIncludedScripts (ctok, istate, sourceFiles, errorLogger) - else - istate |> InteractiveCatch errorLogger (fun istate -> fsiDynamicCompiler.EvalSourceFiles(ctok, istate, rangeStdin, sourceFiles, lexResourceManager, errorLogger), Completed None) |> fst - consume istate rest + else + istate |> InteractiveCatch errorLogger (fun istate -> fsiDynamicCompiler.EvalSourceFiles(ctok, istate, rangeStdin, sourceFiles, lexResourceManager, errorLogger), Completed None) |> fst + consume istate rest setCurrState (consume currState fsiOptions.SourceFiles) - if not (List.isEmpty fsiOptions.SourceFiles) then + if not (List.isEmpty fsiOptions.SourceFiles) then fsiConsolePrompt.PrintAhead(); // Seems required. I expected this could be deleted. Why not? - /// Send a dummy interaction through F# Interactive, to ensure all the most common code generation paths are + /// Send a dummy interaction through F# Interactive, to ensure all the most common code generation paths are /// JIT'ed and ready for use. - member __.LoadDummyInteraction(ctok, errorLogger) = + member _.LoadDummyInteraction(ctok, errorLogger) = setCurrState (currState |> InteractiveCatch errorLogger (fun istate -> fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, true, false, []) |> fst, Completed None) |> fst) - - member __.EvalInteraction(ctok, sourceText, scriptFileName, errorLogger, ?cancellationToken) = + + member _.EvalInteraction(ctok, sourceText, scriptFileName, errorLogger, ?cancellationToken) = let cancellationToken = defaultArg cancellationToken CancellationToken.None - use _unwind1 = ErrorLogger.PushThreadBuildPhaseUntilUnwind(ErrorLogger.BuildPhase.Interactive) - use _unwind2 = ErrorLogger.PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) + use _unwind1 = PushThreadBuildPhaseUntilUnwind(BuildPhase.Interactive) + use _unwind2 = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID - let lexbuf = UnicodeLexing.StringAsLexbuf(isFeatureSupported, sourceText) + let lexbuf = UnicodeLexing.StringAsLexbuf(true, tcConfigB.langVersion, sourceText) let tokenizer = fsiStdinLexerProvider.CreateBufferLexer(scriptFileName, lexbuf, errorLogger) - currState + currState |> InteractiveCatch errorLogger (fun istate -> let expr = ParseInteraction tokenizer mainThreadProcessParsedInteractions ctok errorLogger (expr, istate) cancellationToken) @@ -2331,74 +2548,81 @@ type internal FsiInteractionProcessor let sourceText = sprintf "#load @\"%s\" " scriptPath this.EvalInteraction (ctok, sourceText, scriptPath, errorLogger) - member __.EvalExpression (ctok, sourceText, scriptFileName, errorLogger) = - use _unwind1 = ErrorLogger.PushThreadBuildPhaseUntilUnwind(ErrorLogger.BuildPhase.Interactive) - use _unwind2 = ErrorLogger.PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) + member _.EvalExpression (ctok, sourceText, scriptFileName, errorLogger) = + use _unwind1 = PushThreadBuildPhaseUntilUnwind(BuildPhase.Interactive) + use _unwind2 = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID - let lexbuf = UnicodeLexing.StringAsLexbuf(isFeatureSupported, sourceText) + let lexbuf = UnicodeLexing.StringAsLexbuf(true, tcConfigB.langVersion, sourceText) let tokenizer = fsiStdinLexerProvider.CreateBufferLexer(scriptFileName, lexbuf, errorLogger) - currState + currState |> InteractiveCatch errorLogger (fun istate -> - let expr = parseExpression tokenizer + let expr = parseExpression tokenizer let m = expr.Range // Make this into "(); expr" to suppress generalization and compilation-as-function - let exprWithSeq = SynExpr.Sequential (SequencePointInfoForSeq.SuppressSequencePointOnStmtOfSequential,true,SynExpr.Const (SynConst.Unit,m.StartRange), expr, m) + let exprWithSeq = SynExpr.Sequential (DebugPointAtSequential.SuppressExpr, true, SynExpr.Const (SynConst.Unit,m.StartRange), expr, m) mainThreadProcessParsedExpression ctok errorLogger (exprWithSeq, istate)) |> commitResult - member __.PartialAssemblySignatureUpdated = event.Publish + member _.AddBoundValue(ctok, errorLogger, name, value: obj) = + currState + |> InteractiveCatch errorLogger (fun istate -> + fsiDynamicCompiler.AddBoundValue(ctok, errorLogger, istate, name, value)) + |> commitResult + + member _.PartialAssemblySignatureUpdated = event.Publish /// Start the background thread used to read the input reader and/or console /// /// This is the main stdin loop, running on the stdinReaderThread. - /// + /// // We run the actual computations for each action on the main GUI thread by using - // mainForm.Invoke to pipe a message back through the form's main event loop. (The message + // mainForm.Invoke to pipe a message back through the form's main event loop. (The message // is a delegate to execute on the main Thread) // - member processor.StartStdinReadAndProcessThread (errorLogger) = + member processor.StartStdinReadAndProcessThread errorLogger = if progress then fprintfn fsiConsoleOutput.Out "creating stdinReaderThread"; - let stdinReaderThread = - new Thread(new ThreadStart(fun () -> + let stdinReaderThread = + Thread(ThreadStart(fun () -> InstallErrorLoggingOnThisThread errorLogger // FSI error logging on stdinReaderThread, e.g. parse errors. use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID - try - try + try + try let initialTokenizer = fsiStdinLexerProvider.CreateStdinLexer(errorLogger) if progress then fprintfn fsiConsoleOutput.Out "READER: stdin thread started..."; // Delay until we've peeked the input or read the entire first line fsiStdinLexerProvider.ConsoleInput.WaitForInitialConsoleInput() - + if progress then fprintfn fsiConsoleOutput.Out "READER: stdin thread got first line..."; - let runCodeOnMainThread = runCodeOnEventLoop errorLogger + let runCodeOnMainThread = runCodeOnEventLoop errorLogger // Keep going until EndOfFile on the inReader or console - let rec loop currTokenizer = + let rec loop currTokenizer = - let istateNew,contNew = - processor.ParseAndExecOneSetOfInteractionsFromLexbuf (runCodeOnMainThread, currState, currTokenizer, errorLogger) + let istateNew,contNew = + processor.ParseAndExecOneSetOfInteractionsFromLexbuf (runCodeOnMainThread, currState, currTokenizer, errorLogger) setCurrState istateNew - match contNew with + match contNew with | EndOfFile -> () | CtrlC -> loop (fsiStdinLexerProvider.CreateStdinLexer(errorLogger)) // After each interrupt, restart to a brand new tokenizer - | CompletedWithReportedError _ + | CompletedWithAlreadyReportedError + | CompletedWithReportedError _ | Completed _ -> loop currTokenizer loop initialTokenizer - if progress then fprintfn fsiConsoleOutput.Out "- READER: Exiting stdinReaderThread"; + if progress then fprintfn fsiConsoleOutput.Out "- READER: Exiting stdinReaderThread"; with e -> stopProcessingRecovery e range0; - finally - if progress then fprintfn fsiConsoleOutput.Out "- READER: Exiting process because of failure/exit on stdinReaderThread"; + finally + if progress then fprintfn fsiConsoleOutput.Out "- READER: Exiting process because of failure/exit on stdinReaderThread"; // REVIEW: On some flavors of Mono, calling exit may freeze the process if we're using the WinForms event handler // Basically, on Mono 2.6.3, the GUI thread may be left dangling on exit. At that point: // -- System.Environment.Exit will cause the process to stop responding @@ -2406,7 +2630,7 @@ type internal FsiInteractionProcessor // -- Calling Abort() on the Main thread or the GUI thread will have no effect, and the process will remain unresponsive // Also, even the the GUI thread is up and running, the WinForms event loop will be listed as closed // In this case, killing the process is harmless, since we've already cleaned up after ourselves and FSI is responding - // to an error. (CTRL-C is handled elsewhere.) + // to an error. (CTRL-C is handled elsewhere.) // We'll only do this if we're running on Mono, "--gui" is specified and our input is piped in from stdin, so it's still // fairly constrained. #if FX_NO_WINFORMS @@ -2424,34 +2648,32 @@ type internal FsiInteractionProcessor if progress then fprintfn fsiConsoleOutput.Out "MAIN: starting stdin thread..." stdinReaderThread.Start() - member __.CompletionsForPartialLID (istate, prefix:string) = + member _.CompletionsForPartialLID (istate, prefix:string) = let lid,stem = if prefix.IndexOf(".",StringComparison.Ordinal) >= 0 then let parts = prefix.Split('.') let n = parts.Length Array.sub parts 0 (n-1) |> Array.toList,parts.[n-1] else - [],prefix + [],prefix let tcState = istate.tcState let amap = istate.tcImports.GetImportMap() - let infoReader = new InfoReader(istate.tcGlobals,amap) - let ncenv = new NameResolver(istate.tcGlobals,amap,infoReader,FakeInstantiationGenerator) + let infoReader = InfoReader(istate.tcGlobals,amap) + let ncenv = NameResolver(istate.tcGlobals,amap,infoReader,FakeInstantiationGenerator) let ad = tcState.TcEnvFromImpls.AccessRights let nenv = tcState.TcEnvFromImpls.NameEnv - let nItems = NameResolution.ResolvePartialLongIdent ncenv nenv (ConstraintSolver.IsApplicableMethApprox istate.tcGlobals amap rangeStdin) rangeStdin ad lid false - let names = nItems |> List.map (fun d -> d.DisplayName) - let names = names |> List.filter (fun name -> name.StartsWithOrdinal(stem)) + let nItems = ResolvePartialLongIdent ncenv nenv (ConstraintSolver.IsApplicableMethApprox istate.tcGlobals amap rangeStdin) rangeStdin ad lid false + let names = nItems |> List.map (fun d -> d.DisplayName) + let names = names |> List.filter (fun name -> name.StartsWithOrdinal(stem)) names - member __.ParseAndCheckInteraction (ctok, legacyReferenceResolver, checker, istate, text:string) = + member _.ParseAndCheckInteraction (legacyReferenceResolver, istate, text:string) = let tcConfig = TcConfig.Create(tcConfigB,validate=false) - let fsiInteractiveChecker = FsiInteractiveChecker(legacyReferenceResolver, checker, tcConfig, istate.tcGlobals, istate.tcImports, istate.tcState) - fsiInteractiveChecker.ParseAndCheckInteraction(ctok, SourceText.ofString text) - - member __.AssemblyReferenceAdded = assemblyReferencedEvent.Publish + let fsiInteractiveChecker = FsiInteractiveChecker(legacyReferenceResolver, tcConfig, istate.tcGlobals, istate.tcImports, istate.tcState) + fsiInteractiveChecker.ParseAndCheckInteraction(SourceText.ofString text) //---------------------------------------------------------------------------- @@ -2459,14 +2681,14 @@ type internal FsiInteractionProcessor //---------------------------------------------------------------------------- let internal SpawnThread name f = - let th = new Thread(new ThreadStart(f),Name=name) + let th = Thread(ThreadStart(f),Name=name) th.IsBackground <- true; th.Start() -let internal SpawnInteractiveServer +let internal SpawnInteractiveServer (fsi: FsiEvaluationSessionHostConfig, - fsiOptions : FsiCommandLineOptions, - fsiConsoleOutput: FsiConsoleOutput) = + fsiOptions : FsiCommandLineOptions, + fsiConsoleOutput: FsiConsoleOutput) = //printf "Spawning fsi server on channel '%s'" !fsiServerName; SpawnThread "ServerThread" (fun () -> use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID @@ -2478,41 +2700,41 @@ let internal SpawnInteractiveServer /// Repeatedly drive the event loop (e.g. Application.Run()) but catching ThreadAbortException and re-running. /// /// This gives us a last chance to catch an abort on the main execution thread. -let internal DriveFsiEventLoop (fsi: FsiEvaluationSessionHostConfig, fsiConsoleOutput: FsiConsoleOutput) = - let rec runLoop() = +let internal DriveFsiEventLoop (fsi: FsiEvaluationSessionHostConfig, fsiConsoleOutput: FsiConsoleOutput) = + let rec runLoop() = if progress then fprintfn fsiConsoleOutput.Out "GUI thread runLoop"; - let restart = - try + let restart = + try // BLOCKING POINT: The GUI Thread spends most (all) of its time this event loop if progress then fprintfn fsiConsoleOutput.Out "MAIN: entering event loop..."; fsi.EventLoopRun() with | :? ThreadAbortException -> // If this TAE handler kicks it's almost certainly too late to save the - // state of the process - the state of the message loop may have been corrupted - fsiConsoleOutput.uprintnfn "%s" (FSIstrings.SR.fsiUnexpectedThreadAbortException()); + // state of the process - the state of the message loop may have been corrupted + fsiConsoleOutput.uprintnfn "%s" (FSIstrings.SR.fsiUnexpectedThreadAbortException()); (try Thread.ResetAbort() with _ -> ()); true // Try again, just case we can restart - | e -> + | e -> stopProcessingRecovery e range0; true // Try again, just case we can restart if progress then fprintfn fsiConsoleOutput.Out "MAIN: exited event loop..."; - if restart then runLoop() + if restart then runLoop() runLoop(); /// Thrown when there was an error compiling the given code in FSI. -type FsiCompilationException(message: string, errorInfos: FSharpErrorInfo[] option) = +type FsiCompilationException(message: string, errorInfos: FSharpDiagnostic[] option) = inherit System.Exception(message) - member __.ErrorInfos = errorInfos + member _.ErrorInfos = errorInfos /// The primary type, representing a full F# Interactive session, reading from the given /// text input, writing to the given text output and error writers. -type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], inReader:TextReader, outWriter:TextWriter, errorWriter: TextWriter, fsiCollectible: bool, legacyReferenceResolver: ReferenceResolver.Resolver option) = +type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], inReader:TextReader, outWriter:TextWriter, errorWriter: TextWriter, fsiCollectible: bool, legacyReferenceResolver: LegacyReferenceResolver option) = - do if not runningOnMono then Lib.UnmanagedProcessExecutionOptions.EnableHeapTerminationOnCorruption() (* SDL recommendation *) + do if not runningOnMono then UnmanagedProcessExecutionOptions.EnableHeapTerminationOnCorruption() (* SDL recommendation *) // Explanation: When FsiEvaluationSession.Create is called we do a bunch of processing. For fsi.exe // and fsiAnyCpu.exe there are no other active threads at this point, so we can assume this is the @@ -2530,8 +2752,7 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // Testing shows "console coloring" is broken on some Mono configurations (e.g. Mono 2.4 Suse LiveCD). // To support fsi usage, the console coloring is switched off by default on Mono. - do if runningOnMono then enableConsoleColoring <- false - + do if runningOnMono then enableConsoleColoring <- false //---------------------------------------------------------------------------- // tcConfig - build the initial config @@ -2540,40 +2761,39 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i let currentDirectory = Directory.GetCurrentDirectory() let tryGetMetadataSnapshot = (fun _ -> None) - let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(FSharpEnvironment.tryCurrentDomain()).Value + let defaultFSharpBinariesDir = BinFolderOfDefaultFSharpCompiler(None).Value - let legacyReferenceResolver = - match legacyReferenceResolver with + let legacyReferenceResolver = + match legacyReferenceResolver with | None -> SimulatedMSBuildReferenceResolver.getResolver() | Some rr -> rr - let includePathAddedEvent = Control.Event<_>() - let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, - defaultFSharpBinariesDir=defaultFSharpBinariesDir, - reduceMemoryUsage=ReduceMemoryFlag.Yes, - implicitIncludeDir=currentDirectory, - isInteractive=true, - isInvalidationSupported=false, - defaultCopyFSharpCore=CopyFSharpCoreFlag.No, + TcConfigBuilder.CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir=defaultFSharpBinariesDir, + reduceMemoryUsage=ReduceMemoryFlag.Yes, + implicitIncludeDir=currentDirectory, + isInteractive=true, + isInvalidationSupported=false, + defaultCopyFSharpCore=CopyFSharpCoreFlag.No, tryGetMetadataSnapshot=tryGetMetadataSnapshot, - includePathAdded=includePathAddedEvent.Trigger) + sdkDirOverride=None, + rangeForErrors=range0) let tcConfigP = TcConfigProvider.BasedOnMutableBuilder(tcConfigB) - do tcConfigB.resolutionEnvironment <- ResolutionEnvironment.CompilationAndEvaluation // See Bug 3608 + do tcConfigB.resolutionEnvironment <- LegacyResolutionEnvironment.CompilationAndEvaluation // See Bug 3608 do tcConfigB.useFsiAuxLib <- fsi.UseFsiAuxLib #if NETSTANDARD - do tcConfigB.useSdkRefs <- true + do tcConfigB.SetUseSdkRefs true do tcConfigB.useSimpleResolution <- true - do SetTargetProfile tcConfigB "netcore" // always assume System.Runtime codegen + do if isRunningOnCoreClr then SetTargetProfile tcConfigB "netcore" // always assume System.Runtime codegen #endif // Preset: --optimize+ -g --tailcalls+ (see 4505) do SetOptimizeSwitch tcConfigB OptionSwitch.On do SetDebugSwitch tcConfigB (Some "pdbonly") OptionSwitch.On - do SetTailcallSwitch tcConfigB OptionSwitch.On + do SetTailcallSwitch tcConfigB OptionSwitch.On #if NETSTANDARD // set platform depending on whether the current process is a 64-bit process. @@ -2581,7 +2801,7 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i do tcConfigB.platform <- if IntPtr.Size = 8 then Some AMD64 else Some X86 #endif - let fsiStdinSyphon = new FsiStdinSyphon(errorWriter) + let fsiStdinSyphon = FsiStdinSyphon(errorWriter) let fsiConsoleOutput = FsiConsoleOutput(tcConfigB, outWriter, errorWriter) let errorLogger = ErrorLoggerThatStopsOnFirstError(tcConfigB, fsiStdinSyphon, fsiConsoleOutput) @@ -2589,16 +2809,27 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i do InstallErrorLoggingOnThisThread errorLogger // FSI error logging on main thread. let updateBannerText() = - tcConfigB.productNameForBannerText <- FSIstrings.SR.fsiProductName(FSharpEnvironment.FSharpBannerVersion) - + tcConfigB.productNameForBannerText <- FSIstrings.SR.fsiProductName(FSharpBannerVersion) + do updateBannerText() // setting the correct banner so that 'fsi -?' display the right thing - let fsiOptions = FsiCommandLineOptions(fsi, argv, tcConfigB, fsiConsoleOutput) + let fsiOptions = FsiCommandLineOptions(fsi, argv, tcConfigB, fsiConsoleOutput) + + do + match fsiOptions.WriteReferencesAndExit with + | Some outFile -> + let tcConfig = tcConfigP.Get(ctokStartup) + let references, _unresolvedReferences = TcAssemblyResolutions.GetAssemblyResolutionInformation(tcConfig) + let lines = [ for r in references -> r.resolvedPath ] + FileSystem.OpenFileForWriteShim(outFile).WriteAllLines(lines) + exit 0 + | _ -> () + let fsiConsolePrompt = FsiConsolePrompt(fsiOptions, fsiConsoleOutput) do match tcConfigB.preferredUiLang with - | Some s -> Thread.CurrentThread.CurrentUICulture <- new System.Globalization.CultureInfo(s) + | Some s -> Thread.CurrentThread.CurrentUICulture <- CultureInfo(s) | None -> () do @@ -2607,42 +2838,44 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i with e -> warning(e) - do + do updateBannerText() // resetting banner text after parsing options - if tcConfigB.showBanner then + if tcConfigB.showBanner then fsiOptions.ShowBanner() do fsiConsoleOutput.uprintfn "" - // When no source files to load, print ahead prompt here - do if List.isEmpty fsiOptions.SourceFiles then - fsiConsolePrompt.PrintAhead() + // When no source files to load, print ahead prompt here + do if List.isEmpty fsiOptions.SourceFiles then + fsiConsolePrompt.PrintAhead() let fsiConsoleInput = FsiConsoleInput(fsi, fsiOptions, inReader, outWriter) /// The single, global interactive checker that can be safely used in conjunction with other operations - /// on the FsiEvaluationSession. + /// on the FsiEvaluationSession. let checker = FSharpChecker.Create(legacyReferenceResolver=legacyReferenceResolver) - let (tcGlobals,frameworkTcImports,nonFrameworkResolutions,unresolvedReferences) = - try + let tcGlobals,frameworkTcImports,nonFrameworkResolutions,unresolvedReferences = + try let tcConfig = tcConfigP.Get(ctokStartup) - checker.FrameworkImportsCache.Get (ctokStartup, tcConfig) |> Cancellable.runWithoutCancellation - with e -> + checker.FrameworkImportsCache.Get tcConfig + |> NodeCode.RunImmediateWithoutCancellation + with e -> stopProcessingRecovery e range0; failwithf "Error creating evaluation session: %A" e - let tcImports = - try - TcImports.BuildNonFrameworkTcImports(ctokStartup, tcConfigP, tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences) |> Cancellable.runWithoutCancellation - with e -> + let tcImports = + try + TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences, fsiOptions.DependencyProvider) + |> NodeCode.RunImmediateWithoutCancellation + with e -> stopProcessingRecovery e range0; failwithf "Error creating evaluation session: %A" e - let niceNameGen = NiceNameGenerator() + let niceNameGen = NiceNameGenerator() // Share intern'd strings across all lexing/parsing - let lexResourceManager = new Lexhelp.LexResourceManager() + let lexResourceManager = LexResourceManager() /// The lock stops the type checker running at the same time as the server intellisense implementation. let tcLockObject = box 7 // any new object will do @@ -2654,9 +2887,9 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i #if !NO_EXTENSIONTYPING match tcImports.TryFindProviderGeneratedAssemblyByName (ctok, aref.Name) with | Some assembly -> Some (Choice2Of2 assembly) - | None -> + | None -> #endif - match tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef (ctok, aref) with + match tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef aref with | Some resolvedPath -> Some (Choice1Of2 resolvedPath) | None -> None @@ -2668,20 +2901,27 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i /// This reference cell holds the most recent interactive state let initialInteractiveState = fsiDynamicCompiler.GetInitialInteractiveState () - + let fsiStdinLexerProvider = FsiStdinLexerProvider(tcConfigB, fsiStdinSyphon, fsiConsoleInput, fsiConsoleOutput, fsiOptions, lexResourceManager) - let fsiInteractionProcessor = FsiInteractionProcessor(fsi, tcConfigB, fsiOptions, fsiDynamicCompiler, fsiConsolePrompt, fsiConsoleOutput, fsiInterruptController, fsiStdinLexerProvider, lexResourceManager, initialInteractiveState) + let fsiInteractionProcessor = FsiInteractionProcessor(fsi, tcConfigB, fsiOptions, fsiDynamicCompiler, fsiConsolePrompt, fsiConsoleOutput, fsiInterruptController, fsiStdinLexerProvider, lexResourceManager, initialInteractiveState) + + // Raising an exception throws away the exception stack making diagnosis hard + // this wraps the existing exception as the inner exception + let makeNestedException (userExn: #Exception) = + // clone userExn -- make userExn the inner exception, to retain the stacktrace on raise + let arguments = [| userExn.Message :> obj; userExn :> obj |] + Activator.CreateInstance(userExn.GetType(), arguments) :?> Exception let commitResult res = match res with | Choice1Of2 r -> r | Choice2Of2 None -> raise (FsiCompilationException(FSIstrings.SR.fsiOperationFailed(), None)) - | Choice2Of2 (Some userExn) -> raise userExn + | Choice2Of2 (Some userExn) -> raise (makeNestedException userExn) let commitResultNonThrowing errorOptions scriptFile (errorLogger: CompilationErrorLogger) res = - let errs = errorLogger.GetErrors() - let errorInfos = ErrorHelpers.CreateErrorInfos (errorOptions, true, scriptFile, errs, true) + let errs = errorLogger.GetDiagnostics() + let errorInfos = DiagnosticHelpers.CreateDiagnostics (errorOptions, true, scriptFile, errs, true) let userRes = match res with | Choice1Of2 r -> Choice1Of2 r @@ -2693,8 +2933,8 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i let dummyScriptFileName = "input.fsx" - interface IDisposable with - member x.Dispose() = + interface IDisposable with + member x.Dispose() = (tcImports :> IDisposable).Dispose() uninstallMagicAssemblyResolution.Dispose() @@ -2703,22 +2943,23 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i member x.Interrupt() = fsiInterruptController.Interrupt() /// A host calls this to get the completions for a long identifier, e.g. in the console - member x.GetCompletions(longIdent) = + member x.GetCompletions(longIdent) = fsiInteractionProcessor.CompletionsForPartialLID (fsiInteractionProcessor.CurrentState, longIdent) |> Seq.ofList - member x.ParseAndCheckInteraction(code) = - let ctok = AssumeCompilationThreadWithoutEvidence () - fsiInteractionProcessor.ParseAndCheckInteraction (ctok, legacyReferenceResolver, checker.ReactorOps, fsiInteractionProcessor.CurrentState, code) + member x.ParseAndCheckInteraction(code) = + fsiInteractionProcessor.ParseAndCheckInteraction (legacyReferenceResolver, fsiInteractionProcessor.CurrentState, code) + |> Cancellable.runWithoutCancellation member x.InteractiveChecker = checker - member x.CurrentPartialAssemblySignature = - fsiDynamicCompiler.CurrentPartialAssemblySignature (fsiInteractionProcessor.CurrentState) + member x.CurrentPartialAssemblySignature = + fsiDynamicCompiler.CurrentPartialAssemblySignature fsiInteractionProcessor.CurrentState - member x.DynamicAssembly = + member x.DynamicAssembly = fsiDynamicCompiler.DynamicAssembly + /// A host calls this to determine if the --gui parameter is active - member x.IsGui = fsiOptions.Gui + member x.IsGui = fsiOptions.Gui /// A host calls this to get the active language ID if provided by fsi-server-lcid member x.LCID = fsiOptions.FsiLCID @@ -2729,16 +2970,16 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i /// A host calls this to report an unhandled exception in a standard way, e.g. an exception on the GUI thread gets printed to stderr member x.ReportUnhandledException exn = x.ReportUnhandledExceptionSafe true exn - member x.ReportUnhandledExceptionSafe isFromThreadException (exn:exn) = + member x.ReportUnhandledExceptionSafe isFromThreadException (exn:exn) = fsi.EventLoopInvoke ( - fun () -> + fun () -> fprintfn fsiConsoleOutput.Error "%s" (exn.ToString()) errorLogger.SetError() - try - errorLogger.AbortOnError(fsiConsoleOutput) + try + errorLogger.AbortOnError(fsiConsoleOutput) with StopProcessing -> // BUG 664864 some window that use System.Windows.Forms.DataVisualization types (possible FSCharts) was created in FSI. - // at some moment one chart has raised InvalidArgumentException from OnPaint, this exception was intercepted by the code in higher layer and + // at some moment one chart has raised InvalidArgumentException from OnPaint, this exception was intercepted by the code in higher layer and // passed to Application.OnThreadException. FSI has already attached its own ThreadException handler, inside it will log the original error // and then raise StopProcessing exception to unwind the stack (and possibly shut down current Application) and get to DriveFsiEventLoop. // DriveFsiEventLoop handles StopProcessing by suppressing it and restarting event loop from the beginning. @@ -2746,21 +2987,21 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx // Remarks: - // If your application runs on a 32-bit version of Windows operating system, uncaught exceptions from the callback - // will be passed onto higher-level exception handlers of your application when available. - // The system then calls the unhandled exception filter to handle the exception prior to terminating the process. + // If your application runs on a 32-bit version of Windows operating system, uncaught exceptions from the callback + // will be passed onto higher-level exception handlers of your application when available. + // The system then calls the unhandled exception filter to handle the exception prior to terminating the process. // If the PCA is enabled, it will offer to fix the problem the next time you run the application. - // However, if your application runs on a 64-bit version of Windows operating system or WOW64, - // you should be aware that a 64-bit operating system handles uncaught exceptions differently based on its 64-bit processor architecture, - // exception architecture, and calling convention. + // However, if your application runs on a 64-bit version of Windows operating system or WOW64, + // you should be aware that a 64-bit operating system handles uncaught exceptions differently based on its 64-bit processor architecture, + // exception architecture, and calling convention. // The following table summarizes all possible ways that a 64-bit Windows operating system or WOW64 handles uncaught exceptions. // 1. The system suppresses any uncaught exceptions. - // 2. The system first terminates the process, and then the Program Compatibility Assistant (PCA) offers to fix it the next time + // 2. The system first terminates the process, and then the Program Compatibility Assistant (PCA) offers to fix it the next time // you run the application. You can disable the PCA mitigation by adding a Compatibility section to the application manifest. - // 3. The system calls the exception filters but suppresses any uncaught exceptions when it leaves the callback scope, + // 3. The system calls the exception filters but suppresses any uncaught exceptions when it leaves the callback scope, // without invoking the associated handlers. // Behavior type 2 only applies to the 64-bit version of the Windows 7 operating system. - + // NOTE: tests on Win8 box showed that 64 bit version of the Windows 8 always apply type 2 behavior // Effectively this means that when StopProcessing exception is raised from ThreadException callback - it won't be intercepted in DriveFsiEventLoop. @@ -2769,7 +3010,7 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // FIX: detect if current process in 64 bit running on Windows 7 or Windows 8 and if yes - swallow the StopProcessing and ScheduleRestart instead. // Visible behavior should not be different, previously exception unwinds the stack and aborts currently running Application. // After that it will be intercepted and suppressed in DriveFsiEventLoop. - // Now we explicitly shut down Application so after execution of callback will be completed the control flow + // Now we explicitly shut down Application so after execution of callback will be completed the control flow // will also go out of WinFormsEventLoop.Run and again get to DriveFsiEventLoop => restart the loop. I'd like the fix to be as conservative as possible // so we use special case for problematic case instead of just always scheduling restart. @@ -2794,42 +3035,42 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i member x.PartialAssemblySignatureUpdated = fsiInteractionProcessor.PartialAssemblySignatureUpdated - member x.FormatValue(obj:obj, objTy) = - fsiDynamicCompiler.FormatValue(obj, objTy) + member x.FormatValue(reflectionValue:obj, reflectionType) = + fsiDynamicCompiler.FormatValue(reflectionValue, reflectionType) - member x.EvalExpression(sourceText) = + member x.EvalExpression(code) = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() - fsiInteractionProcessor.EvalExpression(ctok, sourceText, dummyScriptFileName, errorLogger) + fsiInteractionProcessor.EvalExpression(ctok, code, dummyScriptFileName, errorLogger) |> commitResult - member x.EvalExpressionNonThrowing(sourceText) = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + member x.EvalExpressionNonThrowing(code) = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() let errorOptions = TcConfig.Create(tcConfigB,validate = false).errorSeverityOptions let errorLogger = CompilationErrorLogger("EvalInteraction", errorOptions) - fsiInteractionProcessor.EvalExpression(ctok, sourceText, dummyScriptFileName, errorLogger) + fsiInteractionProcessor.EvalExpression(ctok, code, dummyScriptFileName, errorLogger) |> commitResultNonThrowing errorOptions dummyScriptFileName errorLogger - member x.EvalInteraction(sourceText, ?cancellationToken) : unit = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + member x.EvalInteraction(code, ?cancellationToken) : unit = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() let cancellationToken = defaultArg cancellationToken CancellationToken.None - fsiInteractionProcessor.EvalInteraction(ctok, sourceText, dummyScriptFileName, errorLogger, cancellationToken) + fsiInteractionProcessor.EvalInteraction(ctok, code, dummyScriptFileName, errorLogger, cancellationToken) |> commitResult |> ignore - member x.EvalInteractionNonThrowing(sourceText, ?cancellationToken) = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + member x.EvalInteractionNonThrowing(code, ?cancellationToken) = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() @@ -2837,54 +3078,50 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i let errorOptions = TcConfig.Create(tcConfigB,validate = false).errorSeverityOptions let errorLogger = CompilationErrorLogger("EvalInteraction", errorOptions) - fsiInteractionProcessor.EvalInteraction(ctok, sourceText, dummyScriptFileName, errorLogger, cancellationToken) + fsiInteractionProcessor.EvalInteraction(ctok, code, dummyScriptFileName, errorLogger, cancellationToken) |> commitResultNonThrowing errorOptions "input.fsx" errorLogger - member x.EvalScript(scriptPath) : unit = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + member x.EvalScript(filePath) : unit = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() - fsiInteractionProcessor.EvalScript(ctok, scriptPath, errorLogger) + fsiInteractionProcessor.EvalScript(ctok, filePath, errorLogger) |> commitResult |> ignore - member x.EvalScriptNonThrowing(scriptPath) = - // Explanation: When the user of the FsiInteractiveSession object calls this method, the + member x.EvalScriptNonThrowing(filePath) = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the // code is parsed, checked and evaluated on the calling thread. This means EvalExpression // is not safe to call concurrently. let ctok = AssumeCompilationThreadWithoutEvidence() let errorOptions = TcConfig.Create(tcConfigB, validate = false).errorSeverityOptions let errorLogger = CompilationErrorLogger("EvalInteraction", errorOptions) - fsiInteractionProcessor.EvalScript(ctok, scriptPath, errorLogger) - |> commitResultNonThrowing errorOptions scriptPath errorLogger - |> function Choice1Of2 (_), errs -> Choice1Of2 (), errs | Choice2Of2 exn, errs -> Choice2Of2 exn, errs - - [] - /// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`. - member __.AssemblyReferenceAdded = fsiDynamicCompiler.AssemblyReferenceAdded + fsiInteractionProcessor.EvalScript(ctok, filePath, errorLogger) + |> commitResultNonThrowing errorOptions filePath errorLogger + |> function Choice1Of2 _, errs -> Choice1Of2 (), errs | Choice2Of2 exn, errs -> Choice2Of2 exn, errs /// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`. - member __.ValueBound = fsiDynamicCompiler.ValueBound + member _.ValueBound = fsiDynamicCompiler.ValueBound - [] - /// Event fires every time a path is added to the include search list, e.g., via `#I`. - member __.IncludePathAdded = includePathAddedEvent.Publish + member _.GetBoundValues() = + fsiDynamicCompiler.GetBoundValues fsiInteractionProcessor.CurrentState - [] - /// Event fires at the start of adding a dependency via the dependency manager. - member __.DependencyAdding = fsiDynamicCompiler.DependencyAdding + member _.TryFindBoundValue(name: string) = + fsiDynamicCompiler.TryFindBoundValue(fsiInteractionProcessor.CurrentState, name) - [] - /// Event fires at the successful completion of adding a dependency via the dependency manager. - member __.DependencyAdded = fsiDynamicCompiler.DependencyAdded + member _.AddBoundValue(name: string, value: obj) = + // Explanation: When the user of the FsiInteractiveSession object calls this method, the + // code is parsed, checked and evaluated on the calling thread. This means EvalExpression + // is not safe to call concurrently. + let ctok = AssumeCompilationThreadWithoutEvidence() + + fsiInteractionProcessor.AddBoundValue(ctok, errorLogger, name, value) + |> commitResult + |> ignore - [] - /// Event fires at the failure to adding a dependency via the dependency manager. - member __.DependencyFailed = fsiDynamicCompiler.DependencyFailed - /// Performs these steps: /// - Load the dummy interaction, if any /// - Set up exception handling, if any @@ -2893,15 +3130,15 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i /// - Sit in the GUI event loop indefinitely, if needed /// /// This method only returns after "exit". The method repeatedly calls the event loop and - /// the thread may be subject to Thread.Abort() signals if Interrupt() is used, giving rise + /// the thread may be subject to Thread.Abort() signals if Interrupt() is used, giving rise /// to internal ThreadAbortExceptions. /// /// A background thread is started by this thread to read from the inReader and/or console reader. [] - member x.Run() = + member x.Run() = progress <- condition "FSHARP_INTERACTIVE_PROGRESS" - + // Explanation: When Run is called we do a bunch of processing. For fsi.exe // and fsiAnyCpu.exe there are no other active threads at this point, so we can assume this is the // unique compilation thread. For other users of FsiEvaluationSession it is reasonable to assume that @@ -2910,16 +3147,16 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // We later switch to doing interaction-by-interaction processing on the "event loop" thread let ctokRun = AssumeCompilationThreadWithoutEvidence () - if not runningOnMono && fsiOptions.IsInteractiveServer then + if not runningOnMono && fsiOptions.IsInteractiveServer then SpawnInteractiveServer (fsi, fsiOptions, fsiConsoleOutput) use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Interactive - if fsiOptions.Interact then - // page in the type check env + if fsiOptions.Interact then + // page in the type check env fsiInteractionProcessor.LoadDummyInteraction(ctokStartup, errorLogger) if progress then fprintfn fsiConsoleOutput.Out "MAIN: InstallKillThread!"; - + // Compute how long to pause before a ThreadAbort is actually executed. // A somewhat arbitrary choice. let pauseMilliseconds = (if fsiOptions.Gui then 400 else 100) @@ -2930,15 +3167,15 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i #if !FX_NO_APP_DOMAINS // Route background exceptions to the exception handlers - AppDomain.CurrentDomain.UnhandledException.Add (fun args -> - match args.ExceptionObject with - | :? System.Exception as err -> x.ReportUnhandledExceptionSafe false err + AppDomain.CurrentDomain.UnhandledException.Add (fun args -> + match args.ExceptionObject with + | :? System.Exception as err -> x.ReportUnhandledExceptionSafe false err | _ -> ()) #endif fsiInteractionProcessor.LoadInitialFiles(ctokRun, errorLogger) - fsiInteractionProcessor.StartStdinReadAndProcessThread(errorLogger) + fsiInteractionProcessor.StartStdinReadAndProcessThread(errorLogger) DriveFsiEventLoop (fsi, fsiConsoleOutput ) @@ -2953,7 +3190,7 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // to be explicitly kept alive. GC.KeepAlive fsiInterruptController.EventHandlers - static member Create(fsiConfig, argv, inReader, outWriter, errorWriter, ?collectible, ?legacyReferenceResolver) = + static member Create(fsiConfig, argv, inReader, outWriter, errorWriter, ?collectible, ?legacyReferenceResolver) = new FsiEvaluationSession(fsiConfig, argv, inReader, outWriter, errorWriter, defaultArg collectible false, legacyReferenceResolver) static member GetDefaultConfiguration(fsiObj:obj) = FsiEvaluationSession.GetDefaultConfiguration(fsiObj, true) @@ -2962,40 +3199,40 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i // We want to avoid modifying FSharp.Compiler.Interactive.Settings to avoid republishing that DLL. // So we access these via reflection { // Connect the configuration through to the 'fsi' object from FSharp.Compiler.Interactive.Settings - new FsiEvaluationSessionHostConfig () with - member __.FormatProvider = getInstanceProperty fsiObj "FormatProvider" - member __.FloatingPointFormat = getInstanceProperty fsiObj "FloatingPointFormat" - member __.AddedPrinters = getInstanceProperty fsiObj "AddedPrinters" - member __.ShowDeclarationValues = getInstanceProperty fsiObj "ShowDeclarationValues" - member __.ShowIEnumerable = getInstanceProperty fsiObj "ShowIEnumerable" - member __.ShowProperties = getInstanceProperty fsiObj "ShowProperties" - member __.PrintSize = getInstanceProperty fsiObj "PrintSize" - member __.PrintDepth = getInstanceProperty fsiObj "PrintDepth" - member __.PrintWidth = getInstanceProperty fsiObj "PrintWidth" - member __.PrintLength = getInstanceProperty fsiObj "PrintLength" - member __.ReportUserCommandLineArgs args = setInstanceProperty fsiObj "CommandLineArgs" args - member __.StartServer(fsiServerName) = failwith "--fsi-server not implemented in the default configuration" - member __.EventLoopRun() = callInstanceMethod0 (getInstanceProperty fsiObj "EventLoop") [||] "Run" - member __.EventLoopInvoke(f : unit -> 'T) = callInstanceMethod1 (getInstanceProperty fsiObj "EventLoop") [|typeof<'T>|] "Invoke" f - member __.EventLoopScheduleRestart() = callInstanceMethod0 (getInstanceProperty fsiObj "EventLoop") [||] "ScheduleRestart" - member __.UseFsiAuxLib = useFsiAuxLib - member __.GetOptionalConsoleReadLine(_probe) = None } + new FsiEvaluationSessionHostConfig () with + member _.FormatProvider = getInstanceProperty fsiObj "FormatProvider" + member _.FloatingPointFormat = getInstanceProperty fsiObj "FloatingPointFormat" + member _.AddedPrinters = getInstanceProperty fsiObj "AddedPrinters" + member _.ShowDeclarationValues = getInstanceProperty fsiObj "ShowDeclarationValues" + member _.ShowIEnumerable = getInstanceProperty fsiObj "ShowIEnumerable" + member _.ShowProperties = getInstanceProperty fsiObj "ShowProperties" + member _.PrintSize = getInstanceProperty fsiObj "PrintSize" + member _.PrintDepth = getInstanceProperty fsiObj "PrintDepth" + member _.PrintWidth = getInstanceProperty fsiObj "PrintWidth" + member _.PrintLength = getInstanceProperty fsiObj "PrintLength" + member _.ReportUserCommandLineArgs args = setInstanceProperty fsiObj "CommandLineArgs" args + member _.StartServer(fsiServerName) = failwith "--fsi-server not implemented in the default configuration" + member _.EventLoopRun() = callInstanceMethod0 (getInstanceProperty fsiObj "EventLoop") [||] "Run" + member _.EventLoopInvoke(f : unit -> 'T) = callInstanceMethod1 (getInstanceProperty fsiObj "EventLoop") [|typeof<'T>|] "Invoke" f + member _.EventLoopScheduleRestart() = callInstanceMethod0 (getInstanceProperty fsiObj "EventLoop") [||] "ScheduleRestart" + member _.UseFsiAuxLib = useFsiAuxLib + member _.GetOptionalConsoleReadLine(_probe) = None } //------------------------------------------------------------------------------- // If no "fsi" object for the configuration is specified, make the default -// configuration one which stores the settings in-process +// configuration one which stores the settings in-process -module Settings = +module Settings = type IEventLoop = abstract Run : unit -> bool - abstract Invoke : (unit -> 'T) -> 'T + abstract Invoke : (unit -> 'T) -> 'T abstract ScheduleRestart : unit -> unit - // fsi.fs in FSHarp.Compiler.Service.dll avoids a hard dependency on FSharp.Compiler.Interactive.Settings.dll + // fsi.fs in FSHarp.Compiler.Service.dll avoids a hard dependency on FSharp.Compiler.Interactive.Settings.dll // by providing an optional reimplementation of the functionality // An implementation of IEventLoop suitable for the command-line console [] - type internal SimpleEventLoop() = + type internal SimpleEventLoop() = let runSignal = new AutoResetEvent(false) let exitSignal = new AutoResetEvent(false) let doneSignal = new AutoResetEvent(false) @@ -3003,34 +3240,34 @@ module Settings = let mutable result = (None : obj option) let setSignal(signal : AutoResetEvent) = while not (signal.Set()) do Thread.Sleep(1); done let waitSignal signal = WaitHandle.WaitAll([| (signal :> WaitHandle) |]) |> ignore - let waitSignal2 signal1 signal2 = + let waitSignal2 signal1 signal2 = WaitHandle.WaitAny([| (signal1 :> WaitHandle); (signal2 :> WaitHandle) |]) let mutable running = false let mutable restart = false - interface IEventLoop with - member x.Run() = + interface IEventLoop with + member x.Run() = running <- true - let rec run() = - match waitSignal2 runSignal exitSignal with - | 0 -> - queue |> List.iter (fun f -> result <- try Some(f()) with _ -> None); + let rec run() = + match waitSignal2 runSignal exitSignal with + | 0 -> + queue |> List.iter (fun f -> result <- try Some(f()) with _ -> None); setSignal doneSignal run() - | 1 -> + | 1 -> running <- false; restart | _ -> run() run(); - member x.Invoke(f : unit -> 'T) : 'T = + member x.Invoke(f : unit -> 'T) : 'T = queue <- [f >> box] setSignal runSignal waitSignal doneSignal result.Value |> unbox - member x.ScheduleRestart() = - if running then + member x.ScheduleRestart() = + if running then restart <- true setSignal exitSignal - interface System.IDisposable with + interface IDisposable with member x.Dispose() = runSignal.Dispose() exitSignal.Dispose() @@ -3038,13 +3275,13 @@ module Settings = [] - type InteractiveSettings() = + type InteractiveSettings() = let mutable evLoop = (new SimpleEventLoop() :> IEventLoop) let mutable showIDictionary = true let mutable showDeclarationValues = true let mutable args = Environment.GetCommandLineArgs() let mutable fpfmt = "g10" - let mutable fp = (CultureInfo.InvariantCulture :> System.IFormatProvider) + let mutable fp = (CultureInfo.InvariantCulture :> IFormatProvider) let mutable printWidth = 78 let mutable printDepth = 100 let mutable printLength = 100 @@ -3053,82 +3290,82 @@ module Settings = let mutable showProperties = true let mutable addedPrinters = [] - member __.FloatingPointFormat with get() = fpfmt and set v = fpfmt <- v - member __.FormatProvider with get() = fp and set v = fp <- v - member __.PrintWidth with get() = printWidth and set v = printWidth <- v - member __.PrintDepth with get() = printDepth and set v = printDepth <- v - member __.PrintLength with get() = printLength and set v = printLength <- v - member __.PrintSize with get() = printSize and set v = printSize <- v - member __.ShowDeclarationValues with get() = showDeclarationValues and set v = showDeclarationValues <- v - member __.ShowProperties with get() = showProperties and set v = showProperties <- v - member __.ShowIEnumerable with get() = showIEnumerable and set v = showIEnumerable <- v - member __.ShowIDictionary with get() = showIDictionary and set v = showIDictionary <- v - member __.AddedPrinters with get() = addedPrinters and set v = addedPrinters <- v - member __.CommandLineArgs with get() = args and set v = args <- v - member __.AddPrinter(printer : 'T -> string) = + member _.FloatingPointFormat with get() = fpfmt and set v = fpfmt <- v + member _.FormatProvider with get() = fp and set v = fp <- v + member _.PrintWidth with get() = printWidth and set v = printWidth <- v + member _.PrintDepth with get() = printDepth and set v = printDepth <- v + member _.PrintLength with get() = printLength and set v = printLength <- v + member _.PrintSize with get() = printSize and set v = printSize <- v + member _.ShowDeclarationValues with get() = showDeclarationValues and set v = showDeclarationValues <- v + member _.ShowProperties with get() = showProperties and set v = showProperties <- v + member _.ShowIEnumerable with get() = showIEnumerable and set v = showIEnumerable <- v + member _.ShowIDictionary with get() = showIDictionary and set v = showIDictionary <- v + member _.AddedPrinters with get() = addedPrinters and set v = addedPrinters <- v + member _.CommandLineArgs with get() = args and set v = args <- v + member _.AddPrinter(printer : 'T -> string) = addedPrinters <- Choice1Of2 (typeof<'T>, (fun (x:obj) -> printer (unbox x))) :: addedPrinters - member __.EventLoop + member _.EventLoop with get () = evLoop and set (x:IEventLoop) = evLoop.ScheduleRestart(); evLoop <- x - member __.AddPrintTransformer(printer : 'T -> obj) = + member _.AddPrintTransformer(printer : 'T -> obj) = addedPrinters <- Choice2Of2 (typeof<'T>, (fun (x:obj) -> printer (unbox x))) :: addedPrinters - + let fsi = InteractiveSettings() -type FsiEvaluationSession with - static member GetDefaultConfiguration() = +type FsiEvaluationSession with + static member GetDefaultConfiguration() = FsiEvaluationSession.GetDefaultConfiguration(Settings.fsi, false) /// Defines a read-only input stream used to feed content to the hosted F# Interactive dynamic compiler. [] -type CompilerInputStream() = +type CompilerInputStream() = inherit Stream() - // Duration (in milliseconds) of the pause in the loop of waitForAtLeastOneByte. + // Duration (in milliseconds) of the pause in the loop of waitForAtLeastOneByte. let pauseDuration = 100 // Queue of characters waiting to be read. - let readQueue = new Queue() + let readQueue = Queue() let waitForAtLeastOneByte(count : int) = - let rec loop() = - let attempt = + let rec loop() = + let attempt = lock readQueue (fun () -> let n = readQueue.Count - if (n >= 1) then + if (n >= 1) then let lengthToRead = if (n < count) then n else count let ret = Array.zeroCreate lengthToRead for i in 0 .. lengthToRead - 1 do ret.[i] <- readQueue.Dequeue() Some ret - else + else None) - match attempt with - | None -> System.Threading.Thread.Sleep(pauseDuration); loop() + match attempt with + | None -> Thread.Sleep(pauseDuration); loop() | Some res -> res - loop() + loop() - override x.CanRead = true + override x.CanRead = true override x.CanWrite = false override x.CanSeek = false override x.Position with get() = raise (NotSupportedException()) and set _v = raise (NotSupportedException()) - override x.Length = raise (NotSupportedException()) + override x.Length = raise (NotSupportedException()) override x.Flush() = () - override x.Seek(_offset, _origin) = raise (NotSupportedException()) - override x.SetLength(_value) = raise (NotSupportedException()) - override x.Write(_buffer, _offset, _count) = raise (NotSupportedException("Cannot write to input stream")) - override x.Read(buffer, offset, count) = + override x.Seek(_offset, _origin) = raise (NotSupportedException()) + override x.SetLength(_value) = raise (NotSupportedException()) + override x.Write(_buffer, _offset, _count) = raise (NotSupportedException("Cannot write to input stream")) + override x.Read(buffer, offset, count) = let bytes = waitForAtLeastOneByte count Array.Copy(bytes, 0, buffer, offset, bytes.Length) bytes.Length /// Feeds content into the stream. member x.Add(str:string) = - if (System.String.IsNullOrEmpty(str)) then () else + if (String.IsNullOrEmpty(str)) then () else - lock readQueue (fun () -> - let bytes = System.Text.Encoding.UTF8.GetBytes(str) + lock readQueue (fun () -> + let bytes = Encoding.UTF8.GetBytes(str) for i in 0 .. bytes.Length - 1 do readQueue.Enqueue(bytes.[i])) @@ -3139,35 +3376,34 @@ type CompilerInputStream() = type CompilerOutputStream() = inherit Stream() // Queue of characters waiting to be read. - let contentQueue = new Queue() + let contentQueue = Queue() let nyi() = raise (NotSupportedException()) override x.CanRead = false override x.CanWrite = true override x.CanSeek = false override x.Position with get() = nyi() and set _v = nyi() - override x.Length = nyi() + override x.Length = nyi() override x.Flush() = () - override x.Seek(_offset, _origin) = nyi() - override x.SetLength(_value) = nyi() - override x.Read(_buffer, _offset, _count) = raise (NotSupportedException("Cannot write to input stream")) - override x.Write(buffer, offset, count) = + override x.Seek(_offset, _origin) = nyi() + override x.SetLength(_value) = nyi() + override x.Read(_buffer, _offset, _count) = raise (NotSupportedException("Cannot write to input stream")) + override x.Write(buffer, offset, count) = let stop = offset + count if (stop > buffer.Length) then raise (ArgumentException("offset,count")) - lock contentQueue (fun () -> + lock contentQueue (fun () -> for i in offset .. stop - 1 do contentQueue.Enqueue(buffer.[i])) - member x.Read() = - lock contentQueue (fun () -> + member x.Read() = + lock contentQueue (fun () -> let n = contentQueue.Count - if (n > 0) then + if (n > 0) then let bytes = Array.zeroCreate n - for i in 0 .. n-1 do - bytes.[i] <- contentQueue.Dequeue() + for i in 0 .. n-1 do + bytes.[i] <- contentQueue.Dequeue() - System.Text.Encoding.UTF8.GetString(bytes, 0, n) + Encoding.UTF8.GetString(bytes, 0, n) else "") - diff --git a/src/fsharp/fsi/fsi.fsi b/src/fsharp/fsi/fsi.fsi index d9bf96f123d..63f8d980c71 100644 --- a/src/fsharp/fsi/fsi.fsi +++ b/src/fsharp/fsi/fsi.fsi @@ -1,74 +1,96 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - module public FSharp.Compiler.Interactive.Shell +open System open System.IO open System.Threading -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Symbols [] /// Represents an evaluated F# value type FsiValue = + /// The value, as an object - member ReflectionValue : obj + member ReflectionValue: obj + /// The type of the value, from the point of view of the .NET type system - member ReflectionType : System.Type -#if COMPILER_API + member ReflectionType: Type + /// The type of the value, from the point of view of the F# type system - member FSharpType : FSharpType -#endif + member FSharpType: FSharpType + +[] +/// Represents an evaluated F# value that is bound to an identifier +type FsiBoundValue = + + /// The identifier of the value + member Name: string + + /// The evaluated F# value + member Value: FsiValue [] type EvaluationEventArgs = - inherit System.EventArgs + inherit EventArgs /// The display name of the symbol defined - member Name : string + member Name: string /// The value of the symbol defined, if any - member FsiValue : FsiValue option + member FsiValue: FsiValue option /// The FSharpSymbolUse for the symbol defined - member SymbolUse : FSharpSymbolUse + member SymbolUse: FSharpSymbolUse /// The symbol defined - member Symbol : FSharpSymbol + member Symbol: FSharpSymbol /// The details of the expression defined - member ImplementationDeclaration : FSharpImplementationFileDeclaration + member ImplementationDeclaration: FSharpImplementationFileDeclaration [] type public FsiEvaluationSessionHostConfig = - new : unit -> FsiEvaluationSessionHostConfig + new: unit -> FsiEvaluationSessionHostConfig + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract FormatProvider: System.IFormatProvider + abstract FormatProvider: IFormatProvider + /// Called by the evaluation session to ask the host for parameters to format text for output abstract FloatingPointFormat: string + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract AddedPrinters : Choice<(System.Type * (obj -> string)), (System.Type * (obj -> obj))> list + abstract AddedPrinters: Choice string), Type * (obj -> obj)> list + /// Called by the evaluation session to ask the host for parameters to format text for output abstract ShowDeclarationValues: bool + /// Called by the evaluation session to ask the host for parameters to format text for output abstract ShowIEnumerable: bool + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract ShowProperties : bool + abstract ShowProperties: bool + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintSize : int + abstract PrintSize: int + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintDepth : int + abstract PrintDepth: int + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintWidth : int + abstract PrintWidth: int + /// Called by the evaluation session to ask the host for parameters to format text for output - abstract PrintLength : int + abstract PrintLength: int + /// The evaluation session calls this to report the preferred view of the command line arguments after /// stripping things like "/use:file.fsx", "-r:Foo.dll" etc. - abstract ReportUserCommandLineArgs : string [] -> unit + abstract ReportUserCommandLineArgs: string [] -> unit /// Hook for listening for evaluation bindings - member OnEvaluation : IEvent - + member OnEvaluation: IEvent /// /// Indicate a special console "readline" reader for the evaluation session, if any.  @@ -87,58 +109,58 @@ type public FsiEvaluationSessionHostConfig = ///   /// - abstract GetOptionalConsoleReadLine : probeToSeeIfConsoleWorks: bool -> (unit -> string) option + abstract GetOptionalConsoleReadLine: probeToSeeIfConsoleWorks: bool -> (unit -> string) option /// The evaluation session calls this at an appropriate point in the startup phase if the --fsi-server parameter was given - abstract StartServer : fsiServerName:string -> unit + abstract StartServer: fsiServerName:string -> unit /// Called by the evaluation session to ask the host to enter a dispatch loop like Application.Run(). /// Only called if --gui option is used (which is the default). /// Gets called towards the end of startup and every time a ThreadAbort escaped to the backup driver loop. /// Return true if a 'restart' is required, which is a bit meaningless. - abstract EventLoopRun : unit -> bool + abstract EventLoopRun: unit -> bool /// Request that the given operation be run synchronously on the event loop. - abstract EventLoopInvoke : codeToRun: (unit -> 'T) -> 'T + abstract EventLoopInvoke: codeToRun: (unit -> 'T) -> 'T /// Schedule a restart for the event loop. - abstract EventLoopScheduleRestart : unit -> unit + abstract EventLoopScheduleRestart: unit -> unit /// Implicitly reference FSharp.Compiler.Interactive.Settings.dll - abstract UseFsiAuxLib : bool + abstract UseFsiAuxLib: bool /// Thrown when there was an error compiling the given code in FSI. [] type FsiCompilationException = - inherit System.Exception - new : string * FSharpErrorInfo[] option -> FsiCompilationException - member ErrorInfos : FSharpErrorInfo[] option + inherit Exception + new: string * FSharpDiagnostic[] option -> FsiCompilationException + member ErrorInfos: FSharpDiagnostic[] option /// Represents an F# Interactive evaluation session. [] type FsiEvaluationSession = - interface System.IDisposable + interface IDisposable - /// Create an FsiEvaluationSession, reading from the given text input, writing to the given text output and error writers. - /// /// Create an FsiEvaluationSession, reading from the given text input, writing to the given text output and error writers /// /// The dynamic configuration of the evaluation session /// The command line arguments for the evaluation session /// Read input from the given reader + /// Write errors to the given writer /// Write output to the given writer /// Optionally make the dynamic assembly for the session collectible - static member Create : fsiConfig: FsiEvaluationSessionHostConfig * argv:string[] * inReader:TextReader * outWriter:TextWriter * errorWriter: TextWriter * ?collectible: bool * ?legacyReferenceResolver: ReferenceResolver.Resolver -> FsiEvaluationSession + /// An optional resolver for legacy MSBuild references + static member Create: fsiConfig: FsiEvaluationSessionHostConfig * argv:string[] * inReader:TextReader * outWriter:TextWriter * errorWriter: TextWriter * ?collectible: bool * ?legacyReferenceResolver: LegacyReferenceResolver -> FsiEvaluationSession /// A host calls this to request an interrupt on the evaluation thread. - member Interrupt : unit -> unit + member Interrupt: unit -> unit /// A host calls this to get the completions for a long identifier, e.g. in the console /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member GetCompletions : longIdent: string -> seq + member GetCompletions: longIdent: string -> seq /// Execute the code as if it had been entered as one or more interactions, with an /// implicit termination at the end of the input. Stop on first error, discarding the rest @@ -147,7 +169,7 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalInteraction : code: string * ?cancellationToken: CancellationToken -> unit + member EvalInteraction: code: string * ?cancellationToken: CancellationToken -> unit /// Execute the code as if it had been entered as one or more interactions, with an /// implicit termination at the end of the input. Stop on first error, discarding the rest @@ -156,7 +178,7 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalInteractionNonThrowing : code: string * ?cancellationToken: CancellationToken -> Choice * FSharpErrorInfo[] + member EvalInteractionNonThrowing: code: string * ?cancellationToken: CancellationToken -> Choice * FSharpDiagnostic[] /// Execute the given script. Stop on first error, discarding the rest /// of the script. Errors are sent to the output writer, a 'true' return value indicates there @@ -164,7 +186,7 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalScript : filePath: string -> unit + member EvalScript: filePath: string -> unit /// Execute the given script. Stop on first error, discarding the rest /// of the script. Errors and warnings are collected apart from any exception arising from execution @@ -172,7 +194,7 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalScriptNonThrowing : filePath: string -> Choice * FSharpErrorInfo[] + member EvalScriptNonThrowing: filePath: string -> Choice * FSharpDiagnostic[] /// Execute the code as if it had been entered as one or more interactions, with an /// implicit termination at the end of the input. Stop on first error, discarding the rest @@ -181,7 +203,7 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalExpression : code: string -> FsiValue option + member EvalExpression: code: string -> FsiValue option /// Execute the code as if it had been entered as one or more interactions, with an /// implicit termination at the end of the input. Stop on first error, discarding the rest @@ -191,26 +213,23 @@ type FsiEvaluationSession = /// /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered /// by input from 'stdin'. - member EvalExpressionNonThrowing : code: string -> Choice * FSharpErrorInfo[] + member EvalExpressionNonThrowing: code: string -> Choice * FSharpDiagnostic[] /// Format a value to a string using the current PrintDepth, PrintLength etc settings provided by the active fsi configuration object - member FormatValue : reflectionValue: obj * reflectionType: System.Type -> string + member FormatValue: reflectionValue: obj * reflectionType: Type -> string /// Raised when an interaction is successfully typechecked and executed, resulting in an update to the /// type checking state. /// /// This event is triggered after parsing and checking, either via input from 'stdin', or via a call to EvalInteraction. - member PartialAssemblySignatureUpdated : IEvent + member PartialAssemblySignatureUpdated: IEvent /// Typecheck the given script fragment in the type checking context implied by the current state /// of F# Interactive. The results can be used to access intellisense, perform resolutions, /// check brace matching and other information. /// /// Operations may be run concurrently with other requests to the InteractiveChecker. - /// - /// Due to a current limitation, it is not fully thread-safe to run this operation concurrently with evaluation triggered - /// by input from 'stdin'. - member ParseAndCheckInteraction : code: string -> Async + member ParseAndCheckInteraction: code: string -> FSharpParseFileResults * FSharpCheckFileResults * FSharpCheckProjectResults /// The single, global interactive checker to use in conjunction with other operations /// on the FsiEvaluationSession. @@ -220,42 +239,33 @@ type FsiEvaluationSession = member InteractiveChecker: FSharpChecker /// Get a handle to the resolved view of the current signature of the incrementally generated assembly. - member CurrentPartialAssemblySignature : FSharpAssemblySignature + member CurrentPartialAssemblySignature: FSharpAssemblySignature /// Get a handle to the dynamically generated assembly - member DynamicAssembly : System.Reflection.Assembly + member DynamicAssembly: System.Reflection.Assembly /// A host calls this to determine if the --gui parameter is active - member IsGui : bool + member IsGui: bool /// A host calls this to get the active language ID if provided by fsi-server-lcid - member LCID : int option + member LCID: int option /// A host calls this to report an unhandled exception in a standard way, e.g. an exception on the GUI thread gets printed to stderr - member ReportUnhandledException : exn: exn -> unit - - [] - /// Event fires every time an assembly reference is added to the execution environment, e.g., via `#r`. - member AssemblyReferenceAdded: IEvent - - [] - /// Event fires every time a path is added to the include search list, e.g., via `#I`. - member IncludePathAdded: IEvent + member ReportUnhandledException: exn: exn -> unit - [] - /// Event fires at the start of adding a dependency via the dependency manager. - member DependencyAdding: IEvent + /// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`. + member ValueBound: IEvent - [] - /// Event fires at the successful completion of adding a dependency via the dependency manager. - member DependencyAdded: IEvent + /// Gets the root-level values that are bound to an identifier + member GetBoundValues: unit -> FsiBoundValue list - [] - /// Event fires at the failure to adding a dependency via the dependency manager. - member DependencyFailed: IEvent + /// Tries to find a root-level value that is bound to the given identifier + member TryFindBoundValue: name: string -> FsiBoundValue option - /// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`. - member ValueBound : IEvent + /// Creates a root-level value with the given name and .NET object. + /// If the .NET object contains types from assemblies that are not referenced in the interactive session, it will try to implicitly resolve them by default configuration. + /// Name must be a valid identifier. + member AddBoundValue: name: string * value: obj -> unit /// Load the dummy interaction, load the initial files, and, /// if interacting, start the background thread to read the standard input. @@ -267,7 +277,7 @@ type FsiEvaluationSession = /// - Start the background thread to read the standard input, if any /// - Sit in the GUI event loop indefinitely, if needed - member Run : unit -> unit + member Run: unit -> unit /// Get a configuration that uses the 'fsi' object (normally from FSharp.Compiler.Interactive.Settings.dll, /// an object from another DLL with identical characteristics) to provide an implementation of the configuration. @@ -283,7 +293,6 @@ type FsiEvaluationSession = /// implicitly reference FSharp.Compiler.Interactive.Settings.dll. static member GetDefaultConfiguration: unit -> FsiEvaluationSessionHostConfig - /// A default implementation of the 'fsi' object, used by GetDefaultConfiguration() module Settings = /// An event loop used by the currently executing F# Interactive session to execute code @@ -291,41 +300,51 @@ module Settings = type IEventLoop = /// Run the event loop. /// True if the event loop was restarted; false otherwise. - abstract Run : unit -> bool + abstract Run: unit -> bool /// Request that the given operation be run synchronously on the event loop. /// The result of the operation. - abstract Invoke : (unit -> 'T) -> 'T + abstract Invoke: (unit -> 'T) -> 'T /// Schedule a restart for the event loop. - abstract ScheduleRestart : unit -> unit + abstract ScheduleRestart: unit -> unit [] /// Operations supported by the currently executing F# Interactive session. type InteractiveSettings = /// Get or set the floating point format used in the output of the interactive session. member FloatingPointFormat: string with get,set + /// Get or set the format provider used in the output of the interactive session. - member FormatProvider: System.IFormatProvider with get,set + member FormatProvider: IFormatProvider with get,set + /// Get or set the print width of the interactive session. - member PrintWidth : int with get,set + member PrintWidth: int with get,set + /// Get or set the print depth of the interactive session. - member PrintDepth : int with get,set + member PrintDepth: int with get,set + /// Get or set the total print length of the interactive session. - member PrintLength : int with get,set + member PrintLength: int with get,set + /// Get or set the total print size of the interactive session. - member PrintSize : int with get,set + member PrintSize: int with get,set + /// When set to 'false', disables the display of properties of evaluated objects in the output of the interactive session. - member ShowProperties : bool with get,set + member ShowProperties: bool with get,set + /// When set to 'false', disables the display of sequences in the output of the interactive session. member ShowIEnumerable: bool with get,set + /// When set to 'false', disables the display of declaration values in the output of the interactive session. member ShowDeclarationValues: bool with get,set + /// Register a printer that controls the output of the interactive session. member AddPrinter: ('T -> string) -> unit + /// Register a print transformer that controls the output of the interactive session. member AddPrintTransformer: ('T -> obj) -> unit - member internal AddedPrinters : Choice<(System.Type * (obj -> string)), - (System.Type * (obj -> obj))> list + member internal AddedPrinters: Choice string), + Type * (obj -> obj)> list /// The command line arguments after ignoring the arguments relevant to the interactive @@ -333,7 +352,7 @@ module Settings = /// if any. Thus 'fsi.exe test1.fs test2.fs -- hello goodbye' will give arguments /// 'test2.fs', 'hello', 'goodbye'. This value will normally be different to those /// returned by System.Environment.GetCommandLineArgs. - member CommandLineArgs : string [] with get,set + member CommandLineArgs: string [] with get,set /// Gets or sets a the current event loop being used to process interactions. member EventLoop: IEventLoop with get,set @@ -342,13 +361,13 @@ module Settings = /// is a different object to FSharp.Compiler.Interactive.Settings.fsi in FSharp.Compiler.Interactive.Settings.dll, /// which can be used as an alternative implementation of the interactive settings if passed as a parameter /// to GetDefaultConfiguration(fsiObj). - val fsi : InteractiveSettings + val fsi: InteractiveSettings /// Defines a read-only input stream used to feed content to the hosted F# Interactive dynamic compiler. [] type CompilerInputStream = inherit Stream - new : unit -> CompilerInputStream + new: unit -> CompilerInputStream /// Feeds content into the stream. member Add: str:string -> unit @@ -356,6 +375,6 @@ type CompilerInputStream = [] type CompilerOutputStream = inherit Stream - new : unit -> CompilerOutputStream + new: unit -> CompilerOutputStream - member Read : unit -> string + member Read: unit -> string diff --git a/src/fsharp/fsi/fsi.fsproj b/src/fsharp/fsi/fsi.fsproj index 88b15449cd2..92a49762975 100644 --- a/src/fsharp/fsi/fsi.fsproj +++ b/src/fsharp/fsi/fsi.fsproj @@ -5,14 +5,14 @@ Exe $(ProtoTargetFramework) - net472;netcoreapp3.0 - netcoreapp3.0 - .exe - $(NoWarn);45;55;62;75;1204 + net472;net5.0 + net5.0 + $(NoWarn);44 true - $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 + $(OtherFlags) --warnon:1182 fsi.res true + true @@ -31,12 +31,8 @@ - + - - - - @@ -50,7 +46,7 @@ - + diff --git a/src/fsharp/fsi/fsimain.fs b/src/fsharp/fsi/fsimain.fs index 3fdf044f782..142c5b8561c 100644 --- a/src/fsharp/fsi/fsimain.fs +++ b/src/fsharp/fsi/fsimain.fs @@ -25,13 +25,14 @@ open FSharp.Compiler open FSharp.Compiler.AbstractIL open FSharp.Compiler.Interactive.Shell open FSharp.Compiler.Interactive.Shell.Settings +open FSharp.Compiler.CodeAnalysis #nowarn "55" #nowarn "40" // let rec on value 'fsiConfig' // Hardbinding dependencies should we NGEN fsi.exe -[] do () +[] do () [] do () // Standard attributes [] @@ -66,7 +67,7 @@ type WinFormsEventLoop() = let mutable lcid = None // Set the default thread exception handler let mutable restart = false - member __.LCID with get () = lcid and set v = lcid <- v + member _.LCID with get () = lcid and set v = lcid <- v interface IEventLoop with member x.Run() = restart <- false @@ -225,32 +226,32 @@ let evaluateSession(argv: string[]) = // Update the configuration to include 'StartServer', WinFormsEventLoop and 'GetOptionalConsoleReadLine()' let rec fsiConfig = { new FsiEvaluationSessionHostConfig () with - member __.FormatProvider = fsiConfig0.FormatProvider - member __.FloatingPointFormat = fsiConfig0.FloatingPointFormat - member __.AddedPrinters = fsiConfig0.AddedPrinters - member __.ShowDeclarationValues = fsiConfig0.ShowDeclarationValues - member __.ShowIEnumerable = fsiConfig0.ShowIEnumerable - member __.ShowProperties = fsiConfig0.ShowProperties - member __.PrintSize = fsiConfig0.PrintSize - member __.PrintDepth = fsiConfig0.PrintDepth - member __.PrintWidth = fsiConfig0.PrintWidth - member __.PrintLength = fsiConfig0.PrintLength - member __.ReportUserCommandLineArgs args = fsiConfig0.ReportUserCommandLineArgs args - member __.EventLoopRun() = + member _.FormatProvider = fsiConfig0.FormatProvider + member _.FloatingPointFormat = fsiConfig0.FloatingPointFormat + member _.AddedPrinters = fsiConfig0.AddedPrinters + member _.ShowDeclarationValues = fsiConfig0.ShowDeclarationValues + member _.ShowIEnumerable = fsiConfig0.ShowIEnumerable + member _.ShowProperties = fsiConfig0.ShowProperties + member _.PrintSize = fsiConfig0.PrintSize + member _.PrintDepth = fsiConfig0.PrintDepth + member _.PrintWidth = fsiConfig0.PrintWidth + member _.PrintLength = fsiConfig0.PrintLength + member _.ReportUserCommandLineArgs args = fsiConfig0.ReportUserCommandLineArgs args + member _.EventLoopRun() = #if !FX_NO_WINFORMS match (if fsiSession.IsGui then fsiWinFormsLoop.Value else None) with | Some l -> (l :> IEventLoop).Run() | _ -> #endif fsiConfig0.EventLoopRun() - member __.EventLoopInvoke(f) = + member _.EventLoopInvoke(f) = #if !FX_NO_WINFORMS match (if fsiSession.IsGui then fsiWinFormsLoop.Value else None) with | Some l -> (l :> IEventLoop).Invoke(f) | _ -> #endif fsiConfig0.EventLoopInvoke(f) - member __.EventLoopScheduleRestart() = + member _.EventLoopScheduleRestart() = #if !FX_NO_WINFORMS match (if fsiSession.IsGui then fsiWinFormsLoop.Value else None) with | Some l -> (l :> IEventLoop).ScheduleRestart() @@ -258,12 +259,12 @@ let evaluateSession(argv: string[]) = #endif fsiConfig0.EventLoopScheduleRestart() - member __.UseFsiAuxLib = fsiConfig0.UseFsiAuxLib + member _.UseFsiAuxLib = fsiConfig0.UseFsiAuxLib - member __.StartServer(fsiServerName) = StartServer fsiSession fsiServerName + member _.StartServer(fsiServerName) = StartServer fsiSession fsiServerName // Connect the configuration through to the 'fsi' Event loop - member __.GetOptionalConsoleReadLine(probe) = getConsoleReadLine(probe) } + member _.GetOptionalConsoleReadLine(probe) = getConsoleReadLine(probe) } // Create the console and fsiSession : FsiEvaluationSession = FsiEvaluationSession.Create (fsiConfig, argv, Console.In, Console.Out, Console.Error, collectible=false, legacyReferenceResolver=legacyReferenceResolver) @@ -302,16 +303,20 @@ let evaluateSession(argv: string[]) = | e -> eprintf "Exception by fsi.exe:\n%+A\n" e; 1 // Mark the main thread as STAThread since it is a GUI thread +// We only set this for the desktop build of fsi.exe. When we run on the coreclr we choose not to rely +// On apartment threads. A windows NanoServer docker container does not support apartment thread +#if !FX_NO_WINFORMS +[] +#endif [] -[] -[] +[] let MainMain argv = ignore argv let argv = System.Environment.GetCommandLineArgs() let savedOut = Console.Out use __ = { new IDisposable with - member __.Dispose() = + member _.Dispose() = try Console.SetOut(savedOut) with _ -> ()} diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf index 2d4481919d4..e7c41ab141d 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Při vyhledávání balíčků zahrnout identifikátor zdroje balíčku + + Operation could not be completed due to earlier error Operaci nešlo dokončit z důvodu dřívější chyby. - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Operace nebyla úspěšná. Text chyby se vytiskl do streamu chyb. Pokud chcete vrátit odpovídající FSharpErrorInfo, použijte EvalInteractionNonThrowing, EvalScriptNonThrowing nebo EvalExpressionNonThrowing. + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Operace nebyla úspěšná. Text chyby se vytiskl do streamu chyb. Pokud chcete vrátit odpovídající FSharpDiagnostic, použijte EvalInteractionNonThrowing, EvalScriptNonThrowing nebo EvalExpressionNonThrowing. @@ -122,11 +127,6 @@ Adresář {0} neexistuje. - - Invalid directive '#{0} {1}' - Neplatná direktiva #{0} {1} - - Warning: line too long, ignoring some characters\n Upozornění: řádek je příliš dlouhý, některé znaky se ignorují.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf index 80ec70245dc..e75d448790d 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + URI der Paketquelle bei Suche nach Paketen einschließen + + Operation could not be completed due to earlier error Der Vorgang konnte aufgrund eines vorherigen Fehlers nicht abgeschlossen werden. - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Der Vorgang ist fehlgeschlagen. Der Fehlertext wurde im Fehlerstream ausgegeben. Verwenden Sie EvalInteractionNonThrowing, EvalScriptNonThrowing oder EvalExpressionNonThrowing, um die entsprechende FSharpErrorInfo zurückzugeben. + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Fehler beim Vorgang. Der Fehlertext wurde im Fehlerstream ausgegeben. Verwenden Sie "EvalInteractionNonThrowing", "EvalScriptNonThrowing" oder "EvalExpressionNonThrowing", um die entsprechende FSharpDiagnostic zurückzugeben. @@ -24,27 +29,27 @@ - INPUT FILES - - – EINGABEDATEIEN – + - EINGABEDATEIEN - - CODE GENERATION - - – CODEGENERIERUNG – + - CODEGENERIERUNG - - ERRORS AND WARNINGS - - – FEHLER UND WARNUNGEN – + - FEHLER UND WARNUNGEN - - LANGUAGE - - – SPRACHE – + - SPRACHE - - MISCELLANEOUS - - – VERSCHIEDENES – + - VERSCHIEDENES - @@ -122,11 +127,6 @@ Das Verzeichnis "{0}" ist nicht vorhanden. - - Invalid directive '#{0} {1}' - Ungültige Direktive "#{0} {1}" - - Warning: line too long, ignoring some characters\n Warnung: Die Zeile ist zu lang, einige Zeichen werden ignoriert.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf index d5ec3bf213c..21655a4e010 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Incluir el URI de origen del paquete al buscar paquetes + + Operation could not be completed due to earlier error La operación no se pudo completar debido a un error anterior - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Error en la operación. El texto del error se ha impreso en la secuencia de errores. Para devolver el correspondiente FSharpErrorInfo, use EvalInteractionNonThrowing, EvalScriptNonThrowing o EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Error en la operación. El texto del error se ha impreso en la secuencia de errores. Para devolver el valor FSharpDiagnostic correspondiente, use EvalInteractionNonThrowing, EvalScriptNonThrowing o EvalExpressionNonThrowing @@ -122,11 +127,6 @@ El directorio '{0}' no existe. - - Invalid directive '#{0} {1}' - Directiva '#{0} {1}' no válida. - - Warning: line too long, ignoring some characters\n Advertencia: línea demasiado larga, omitiendo algunos caracteres.\n @@ -149,7 +149,7 @@ F# Interactive directives: - Directivas de F# interactivo: + Directivas de F# interactivo: diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf index 963d52c6504..fc42cf0b812 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Inclure l'URI de source de package au moment de la recherche des packages + + Operation could not be completed due to earlier error Impossible d'exécuter l'opération en raison d'une erreur antérieure - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - L'opération a échoué. Le texte d'erreur a été imprimé dans le flux d'erreurs. Pour retourner le FSharpErrorInfo correspondant, utiliser EvalInteractionNonThrowing, EvalScriptNonThrowing ou EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Échec de l'opération. Le texte d'erreur est affiché dans le flux d'erreur. Pour retourner le FSharpDiagnostic correspondant, utilisez EvalInteractionNonThrowing, EvalScriptNonThrowing ou EvalExpressionNonThrowing @@ -122,11 +127,6 @@ Le répertoire '{0}' n'existe pas - - Invalid directive '#{0} {1}' - Directive non valide '#{0} {1}' - - Warning: line too long, ignoring some characters\n Avertissement : ligne trop longue, certains caractères sont ignorés\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf index aa030eb6b34..de4f016ad9a 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Includi l'URI di origine pacchetti durante la ricerca di pacchetti + + Operation could not be completed due to earlier error Non è stato possibile completare l'operazione a causa di un errore precedente - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - L'operazione non è riuscita. Il testo dell'errore è stato stampato nel flusso degli errori. Per restituire l'elemento FSharpErrorInfo corrispondente, usare EvalInteractionNonThrowing, EvalScriptNonThrowing o EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + L'operazione non è riuscita. Il testo dell'errore è stato stampato nel flusso degli errori. Per restituire l'elemento FSharpDiagnostic corrispondente, usare EvalInteractionNonThrowing, EvalScriptNonThrowing o EvalExpressionNonThrowing @@ -122,11 +127,6 @@ La directory '{0}' non esiste - - Invalid directive '#{0} {1}' - Direttiva '#{0} {1}' non valida - - Warning: line too long, ignoring some characters\n Avviso: riga troppo lunga; alcuni caratteri verranno ignorati\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf index ad4b06f0fd0..614ddf284ac 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ja.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + パッケージの検索時にパッケージ ソースの URI を含める + + Operation could not be completed due to earlier error 以前のエラーが原因で操作を完了できませんでした - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - 操作に失敗しました。エラー テキストがエラー ストリームで印刷されました。対応する FSharpErrorInfo を戻すには、EvalInteractionNonThrowing、EvalScriptuNonThrowing、または EvalExpressionNonThrowing を使用します + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + 操作に失敗しました。エラー テキストがエラー ストリームに出力されました。対応する FSharpDiagnostic を戻すには、EvalInteractionNonThrowing、EvalScriptNonThrowing、または EvalExpressionNonThrowing を使用します @@ -122,11 +127,6 @@ ディレクトリ "{0}" は存在しません - - Invalid directive '#{0} {1}' - 無効なディレクティブ '#{0} {1}' - - Warning: line too long, ignoring some characters\n 警告: 行が長すぎます。一部の文字は無視されます\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf index 53f9f276082..4f132496c00 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + 패키지를 검색할 때 패키지 원본 URI 포함 + + Operation could not be completed due to earlier error 이전 오류로 인해 작업을 완료할 수 없습니다. - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - 작업이 실패했습니다. 오류 텍스트가 오류 스트림에 인쇄되었습니다. 해당 FSharpErrorInfo를 반환하려면 EvalInteractionNonThrowing, EvalScriptNonThrowing 또는 EvalExpressionNonThrowing를 사용하세요. + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + 작업이 실패했습니다. 오류 텍스트가 오류 스트림에 출력되었습니다. 해당 FSharpDiagnostic을 반환하려면 EvalInteractionNonThrowing, EvalScriptNonThrowing 또는 EvalExpressionNonThrowing을 사용하세요. @@ -122,11 +127,6 @@ '{0}' 디렉터리가 없습니다. - - Invalid directive '#{0} {1}' - 잘못된 지시문 '#{0} {1}' - - Warning: line too long, ignoring some characters\n 경고: 줄이 너무 길어 일부 문자가 무시됩니다.\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf index 3666ea478ed..8806c4ace6e 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Uwzględnij identyfikator URI źródła pakietów podczas wyszukiwania pakietów + + Operation could not be completed due to earlier error Nie udało się ukończyć operacji z powodu wcześniejszego błędu - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Operacja nie powiodła się. Tekst błędu został umieszczony w strumieniu błędów. Aby zwrócić odpowiedni element FSharpErrorInfo, użyj elementu EvalInteractionNonThrowing, eEvalScriptNonThrowing lub EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Operacja nie powiodła się. Tekst błędu został umieszczony w strumieniu błędów. Aby zwrócić odpowiedni element FSharpDiagnostic, użyj elementu EvalInteractionNonThrowing, eEvalScriptNonThrowing lub EvalExpressionNonThrowing @@ -122,11 +127,6 @@ Katalog „{0}” nie istnieje - - Invalid directive '#{0} {1}' - Nieprawidłowa dyrektywa „#{0} {1}” - - Warning: line too long, ignoring some characters\n Ostrzeżenie: wiersz jest zbyt długi, niektóre znaki zostaną zignorowane\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf index 9adafa2f096..c67ed4a0e70 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Incluir o URI de origem do pacote ao pesquisar pacotes + + Operation could not be completed due to earlier error Não foi possível concluir a operação devido a um erro anterior - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Falha na operação. O texto do erro foi impresso no fluxo de erros. Para retornar o FSharpErrorInfo correspondente, use EvalInteractionNonThrowing, EvalScriptNonThrowing ou EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Falha na operação. O texto do erro foi impresso no fluxo de erros. Para retornar o FSharpDiagnostic correspondente, use EvalInteractionNonThrowing, EvalScriptNonThrowing ou EvalExpressionNonThrowing @@ -122,11 +127,6 @@ O diretório '{0}' não existe - - Invalid directive '#{0} {1}' - Diretriz inválida '#{0} {1}' - - Warning: line too long, ignoring some characters\n Aviso: linha muito longa, ignore alguns caracteres\n diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf index 9cbfe6ff50f..efd1f831714 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Включать исходный URI пакета при поиске пакетов + + Operation could not be completed due to earlier error Операция не может быть завершена из-за предыдущей ошибки - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - Не удалось выполнить операцию. Текст ошибки был выведен в потоке ошибок. Чтобы вернуть соответствующие сведения FSharpErrorInfo, используйте EvalInteractionNonThrowing, EvalScriptNonThrowing или EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + Не удалось выполнить операцию. Текст ошибки был выведен в потоке ошибок. Чтобы вернуть соответствующие сведения FSharpDiagnostic, используйте EvalInteractionNonThrowing, EvalScriptNonThrowing или EvalExpressionNonThrowing @@ -122,11 +127,6 @@ Каталог "{0}" не существует - - Invalid directive '#{0} {1}' - Недопустимая директива "#{0} {1}" - - Warning: line too long, ignoring some characters\n Предупреждение: слишком длинная строка, некоторые знаки игнорируются\n @@ -209,7 +209,7 @@ - Aborting main thread... - — Отменяется главный поток… + — Отменяется главный поток... diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf index 65042521c76..0aa1916e2de 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + Paketler aranırken paket kaynağı URI'si ekleyin + + Operation could not be completed due to earlier error Önceki hata nedeniyle işlem tamamlanamadı - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - İşlem başarısız oldu. Hata metni hata akışında yazdırıldı. İlgili FSharpErrorInfo bilgilerini döndürmek için EvalInteractionNonThrowing, EvalScriptNonThrowing veya EvalExpressionNonThrowing kullanın + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + İşlem başarısız oldu. Hata metni hata akışında yazdırıldı. İlgili FSharpDiagnostic'i döndürmek için EvalInteractionNonThrowing, EvalScriptNonThrowing veya EvalExpressionNonThrowing kullanın @@ -122,11 +127,6 @@ '{0}' dizini yok - - Invalid directive '#{0} {1}' - Geçersiz yönerge '#{0} {1}' - - Warning: line too long, ignoring some characters\n Uyarı: satır çok uzun, bazı karakterler yok sayılıyor\n @@ -149,7 +149,7 @@ F# Interactive directives: - F# Etkileşimli yönergeleri: + F# Etkileşimli yönergeleri: diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf index a97b57363e8..d183e5f2349 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hans.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + 搜索包时包含包源 uri + + Operation could not be completed due to earlier error 由于早期错误,无法完成操作 - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - 操作失败。错误文本已在错误流中打印。要返回相应的 FSharpErrorInfo,请使用 EvalInteractionNonThrowing、EvalScriptNonThrowing 或 EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + 操作失败。错误文本已在错误流中打印。若要返回相应的 FSharpDiagnostic,请使用 EvalInteractionNonThrowing、EvalScriptNonThrowing 或 EvalExpressionNonThrowing @@ -122,11 +127,6 @@ 目录“{0}”不存在 - - Invalid directive '#{0} {1}' - 无效的指令“#{0} {1}” - - Warning: line too long, ignoring some characters\n 警告: 由于行太长,将忽略某些字符\n @@ -149,7 +149,7 @@ F# Interactive directives: - F# 交互窗口指令: + F# 交互窗口指令: @@ -184,7 +184,7 @@ F# Interactive command line options: - F# 交互窗口命令行选项: + F# 交互窗口命令行选项: diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf index 936f04dd787..ccb733230cb 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.zh-Hant.xlf @@ -2,14 +2,19 @@ + + Include package source uri when searching for packages + 搜尋套件時包含套件來源 URI + + Operation could not be completed due to earlier error 因為先前發生錯誤,所以無法完成作業 - Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing - 作業失敗。錯誤文字已列印在錯誤資料流中。若要傳回相對應的 FSharpErrorInfo,請使用 EvalInteractionNonThrowing、EvalScriptNonThrowing 或 EvalExpressionNonThrowing + Operation failed. The error text has been printed in the error stream. To return the corresponding FSharpDiagnostic use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing + 作業失敗。錯誤文字已列印在錯誤串流中。若要傳回相對應的 FSharpDiagnostic,請使用 EvalInteractionNonThrowing、EvalScriptNonThrowing 或 EvalExpressionNonThrowing @@ -122,11 +127,6 @@ 目錄 '{0}' 不存在 - - Invalid directive '#{0} {1}' - 無效的指示詞 '#{0} {1}' - - Warning: line too long, ignoring some characters\n 警告: 行太長,將忽略某些字元\n @@ -149,7 +149,7 @@ F# Interactive directives: - F# 互動指示詞: + F# 互動指示詞: @@ -184,7 +184,7 @@ F# Interactive command line options: - F# 互動命令列選項: + F# 互動命令列選項: diff --git a/src/fsharp/fsiAnyCpu/App.config b/src/fsharp/fsiAnyCpu/App.config index af303c8db16..0978bc125a4 100644 --- a/src/fsharp/fsiAnyCpu/App.config +++ b/src/fsharp/fsiAnyCpu/App.config @@ -8,10 +8,6 @@ - - - - diff --git a/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj b/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj index 3bf0d326d34..a95e06a40b2 100644 --- a/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj +++ b/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj @@ -7,9 +7,9 @@ net472 AnyCPU .exe - $(NoWarn);45;55;62;75;1204 + $(NoWarn);44 true - $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 + $(OtherFlags) --warnon:1182 ..\fsi\fsi.res true true @@ -30,8 +30,8 @@ - - + + diff --git a/src/fsharp/fsiaux.fs b/src/fsharp/fsiaux.fs index f4c5ed9cd57..3c12d56812d 100644 --- a/src/fsharp/fsiaux.fs +++ b/src/fsharp/fsiaux.fs @@ -111,9 +111,9 @@ type InteractiveSession() = member internal self.SetEventLoop (run: (unit -> bool), invoke: ((unit -> obj) -> obj), restart: (unit -> unit)) = evLoop.ScheduleRestart() evLoop <- { new IEventLoop with - member __.Run() = run() - member __.Invoke(f) = invoke((fun () -> f() |> box)) |> unbox - member __.ScheduleRestart() = restart() } + member _.Run() = run() + member _.Invoke(f) = invoke((fun () -> f() |> box)) |> unbox + member _.ScheduleRestart() = restart() } [] do() diff --git a/src/fsharp/fsiaux.fsi b/src/fsharp/fsiaux.fsi index d557c17331b..a225e48e7aa 100644 --- a/src/fsharp/fsiaux.fsi +++ b/src/fsharp/fsiaux.fsi @@ -7,10 +7,12 @@ namespace FSharp.Compiler.Interactive type IEventLoop = /// Run the event loop. + /// /// True if the event loop was restarted; false otherwise. abstract Run : unit -> bool /// Request that the given operation be run synchronously on the event loop. + /// /// The result of the operation. abstract Invoke : (unit -> 'T) -> 'T diff --git a/src/ilx/EraseClosures.fs b/src/fsharp/ilx/EraseClosures.fs similarity index 84% rename from src/ilx/EraseClosures.fs rename to src/fsharp/ilx/EraseClosures.fs index abc5e4bc977..8a73f9c860f 100644 --- a/src/ilx/EraseClosures.fs +++ b/src/fsharp/ilx/EraseClosures.fs @@ -1,14 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.EraseClosures +module internal FSharp.Compiler.AbstractIL.ILX.EraseClosures - -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.ILX.Types open FSharp.Compiler.AbstractIL.Morphs open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.PrettyNaming +open FSharp.Compiler.Syntax.PrettyNaming // -------------------------------------------------------------------- // Erase closures and function types @@ -105,10 +103,13 @@ let isSupportedDirectCall apps = // for more refined types later. // -------------------------------------------------------------------- -let mkFuncTypeRef n = - if n = 1 then mkILTyRef (IlxSettings.ilxFsharpCoreLibScopeRef (), IlxSettings.ilxNamespace () + ".FSharpFunc`2") - else mkILNestedTyRef (IlxSettings.ilxFsharpCoreLibScopeRef (), - [IlxSettings.ilxNamespace () + ".OptimizedClosures"], +[] +let fsharpCoreNamespace = "Microsoft.FSharp.Core" + +let mkFuncTypeRef fsharpCoreAssemblyScopeRef n = + if n = 1 then mkILTyRef (fsharpCoreAssemblyScopeRef, fsharpCoreNamespace + ".FSharpFunc`2") + else mkILNestedTyRef (fsharpCoreAssemblyScopeRef, + [fsharpCoreNamespace + ".OptimizedClosures"], "FSharpFunc`"+ string (n + 1)) type cenv = { @@ -125,7 +126,7 @@ type cenv = addMethodGeneratedAttrs: ILMethodDef -> ILMethodDef } - override __.ToString() = "" + override _.ToString() = "" let addMethodGeneratedAttrsToTypeDef cenv (tdef: ILTypeDef) = @@ -133,8 +134,8 @@ let addMethodGeneratedAttrsToTypeDef cenv (tdef: ILTypeDef) = let newIlxPubCloEnv(ilg, addMethodGeneratedAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs) = { ilg = ilg - tref_Func = Array.init 10 (fun i -> mkFuncTypeRef(i+1)) - mkILTyFuncTy = ILType.Boxed (mkILNonGenericTySpec (mkILTyRef (IlxSettings.ilxFsharpCoreLibScopeRef (), IlxSettings.ilxNamespace () + ".FSharpTypeFunc"))) + tref_Func = Array.init 10 (fun i -> mkFuncTypeRef ilg.fsharpCoreAssemblyScopeRef (i+1)) + mkILTyFuncTy = ILType.Boxed (mkILNonGenericTySpec (mkILTyRef (ilg.fsharpCoreAssemblyScopeRef, fsharpCoreNamespace + ".FSharpTypeFunc"))) addMethodGeneratedAttrs = addMethodGeneratedAttrs addFieldGeneratedAttrs = addFieldGeneratedAttrs addFieldNeverAttrs = addFieldNeverAttrs } @@ -145,7 +146,7 @@ let mkILCurriedFuncTy cenv dtys rty = List.foldBack (mkILFuncTy cenv) dtys rty let typ_Func cenv (dtys: ILType list) rty = let n = dtys.Length - let tref = if n <= 10 then cenv.tref_Func.[n-1] else mkFuncTypeRef n + let tref = if n <= 10 then cenv.tref_Func.[n-1] else mkFuncTypeRef cenv.ilg.fsharpCoreAssemblyScopeRef n mkILBoxedTy tref (dtys @ [rty]) let rec mkTyOfApps cenv apps = @@ -236,7 +237,7 @@ let mkCallFunc cenv allocLocal numThisGenParams tl apps = let storers, (loaders2 : ILInstr list list) = unwind rest (List.rev (List.concat storers) : ILInstr list) , List.concat loaders2 else - stripUpTo n (function (_x :: _y) -> true | _ -> false) (function (x :: y) -> (x, y) | _ -> failwith "no!") loaders + stripUpTo n (function _x :: _y -> true | _ -> false) (function x :: y -> (x, y) | _ -> failwith "no!") loaders let rec buildApp fst loaders apps = // Strip off one valid indirect call. [fst] indicates if this is the @@ -247,7 +248,7 @@ let mkCallFunc cenv allocLocal numThisGenParams tl apps = // Type applications: REVIEW: get rid of curried tyapps - just tuple them | tyargs, [], _ when not (isNil tyargs) -> // strip again, instantiating as we go. we could do this while we count. - let (revInstTyArgs, rest') = + let revInstTyArgs, rest' = (([], apps), tyargs) ||> List.fold (fun (revArgsSoFar, cs) _ -> let actual, rest' = destTyFuncApp cs let rest'' = instAppsAux varCount [ actual ] rest' @@ -312,15 +313,17 @@ let convILMethodBody (thisClo, boxReturnTy) (il: ILMethodBody) = match boxReturnTy with | None -> code | Some ty -> morphILInstrsInILCode (convReturnInstr ty) code - {il with MaxStack=newMax; IsZeroInit=true; Code= code } + { il with MaxStack = newMax; Code = code } let convMethodBody thisClo = function - | MethodBody.IL il -> MethodBody.IL (convILMethodBody (thisClo, None) il) + | MethodBody.IL il -> + let convil = convILMethodBody (thisClo, None) il.Value + MethodBody.IL (lazy convil) | x -> x let convMethodDef thisClo (md: ILMethodDef) = - let b' = convMethodBody thisClo (md.Body.Contents) - md.With(body=mkMethBodyAux b') + let b' = convMethodBody thisClo md.Body + md.With(body=notlazy b') // -------------------------------------------------------------------- // Make fields for free variables of a type abstraction. @@ -361,8 +364,11 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let nowTypeRef = mkILNestedTyRef (ILScopeRef.Local, encl, td.Name) let nowTy = mkILFormalBoxedTy nowTypeRef td.GenericParams let nowCloRef = IlxClosureRef(nowTypeRef, clo.cloStructure, nowFields) - let nowCloSpec = mkILFormalCloRef td.GenericParams nowCloRef - let tagApp = (Lazy.force clo.cloCode).SourceMarker + let nowCloSpec = mkILFormalCloRef td.GenericParams nowCloRef clo.cloUseStaticField + let nowMethods = List.map (convMethodDef (Some nowCloSpec)) td.Methods.AsList + let ilCloCode = Lazy.force clo.cloCode + let cloTag = ilCloCode.DebugPoint + let cloImports = ilCloCode.DebugImports let tyargsl, tmargsl, laterStruct = stripSupportedAbstraction clo.cloStructure @@ -374,7 +380,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let fixupArg mkEnv mkArg n = let rec findMatchingArg l c = match l with - | ((m, _) :: t) -> + | (m, _) :: t -> if n = m then mkEnv c else findMatchingArg t (c+1) | [] -> mkArg (n - argToFreeVarMap.Length + 1) @@ -409,7 +415,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = match tyargsl, tmargsl, laterStruct with // CASE 1 - Type abstraction - | (_ :: _), [], _ -> + | _ :: _, [], _ -> let addedGenParams = tyargsl let nowReturnTy = (mkTyOfLambdas cenv laterStruct) @@ -428,12 +434,12 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let selfFreeVar = mkILFreeVar(CompilerGeneratedName ("self"+string nowFields.Length), true, nowCloSpec.ILType) let laterFields = Array.append nowFields [| selfFreeVar |] let laterCloRef = IlxClosureRef(laterTypeRef, laterStruct, laterFields) - let laterCloSpec = mkILFormalCloRef laterGenericParams laterCloRef + let laterCloSpec = mkILFormalCloRef laterGenericParams laterCloRef false let laterCode = rewriteCodeToAccessArgsFromEnv laterCloSpec [(0, selfFreeVar)] let laterTypeDefs = convIlxClosureDef cenv encl - (td.With(genericParams=laterGenericParams, name=laterTypeName)) + (td.With(genericParams=laterGenericParams, name=laterTypeName, methods=emptyILMethods, fields=emptyILFields)) {clo with cloStructure=laterStruct cloFreeVars=laterFields cloCode=notlazy laterCode} @@ -441,19 +447,16 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = // This is the code which will get called when then "now" // arguments get applied. Convert it with the information // that it is the code for a closure... - let nowCode = - mkILMethodBody - (false, [], nowFields.Length + 1, - nonBranchingInstrsToCode - begin - // Load up the environment, including self... - (nowFields |> Array.toList |> List.collect (mkLdFreeVar nowCloSpec)) @ - [ mkLdarg0 ] @ - // Make the instance of the delegated closure && return it. - // This passes the method type params. as class type params. - [ I_newobj (laterCloSpec.Constructor, None) ] - end, - tagApp) + let nowInstrs = + // Load up the environment, including self... + [ for fld in nowFields do + yield! mkLdFreeVar nowCloSpec fld + mkLdarg0 + // Make the instance of the delegated closure && return it. + // This passes the method type params. as class type params. + I_newobj (laterCloSpec.Constructor, None) ] + + let nowCode = mkILMethodBody (false, [], nowFields.Length + 1, nonBranchingInstrsToCode nowInstrs, cloTag, cloImports) let nowTypeDefs = convIlxClosureDef cenv encl td {clo with cloStructure=nowStruct @@ -465,6 +468,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = else // CASE 1b. Build a type application. let boxReturnTy = Some nowReturnTy (* box prior to all I_ret *) + let convil = convILMethodBody (Some nowCloSpec, boxReturnTy) (Lazy.force clo.cloCode) let nowApplyMethDef = mkILGenericVirtualMethod ("Specialize", @@ -472,14 +476,15 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = addedGenParams, (* method is generic over added ILGenericParameterDefs *) [], mkILReturn(cenv.ilg.typ_Object), - MethodBody.IL (convILMethodBody (Some nowCloSpec, boxReturnTy) (Lazy.force clo.cloCode))) + MethodBody.IL (lazy convil)) let ctorMethodDef = mkILStorageCtor - (None, - [ mkLdarg0; mkNormalCall (mkILCtorMethSpecForTy (cenv.mkILTyFuncTy, [])) ], + ([ mkLdarg0; mkNormalCall (mkILCtorMethSpecForTy (cenv.mkILTyFuncTy, [])) ], nowTy, mkILCloFldSpecs cenv nowFields, - ILMemberAccess.Assembly) + ILMemberAccess.Assembly, + None, + None) |> cenv.addMethodGeneratedAttrs let cloTypeDef = @@ -490,8 +495,8 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = nestedTypes = emptyILTypeDefs, layout=ILTypeDefLayout.Auto, extends= Some cenv.mkILTyFuncTy, - methods= mkILMethods ([ctorMethodDef] @ [nowApplyMethDef]) , - fields= mkILFields (mkILCloFldDefs cenv nowFields), + methods= mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods) , + fields= mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList), customAttrs=emptyILCustomAttrs, methodImpls=emptyILMethodImpls, properties=emptyILProperties, @@ -522,22 +527,20 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let laterFreeVars = argToFreeVarMap |> List.map snd |> List.toArray let laterFields = Array.append nowFields laterFreeVars let laterCloRef = IlxClosureRef(laterTypeRef, laterStruct, laterFields) - let laterCloSpec = mkILFormalCloRef laterGenericParams laterCloRef - + let laterCloSpec = mkILFormalCloRef laterGenericParams laterCloRef false + + let nowInstrs = + [ // Load up the environment + for nowField in nowFields do + yield! mkLdFreeVar nowCloSpec nowField + // Load up all the arguments (including self), which become free variables in the delegated closure + for (n, _) in argToFreeVarMap do + mkLdarg (uint16 n) + // Make the instance of the delegated closure && return it. + I_newobj (laterCloSpec.Constructor, None) ] + // This is the code which will first get called. - let nowCode = - mkILMethodBody - (false, [], argToFreeVarMap.Length + nowFields.Length, - nonBranchingInstrsToCode - begin - // Load up the environment - (nowFields |> Array.toList |> List.collect (mkLdFreeVar nowCloSpec)) @ - // Load up all the arguments (including self), which become free variables in the delegated closure - (argToFreeVarMap |> List.map (fun (n, _) -> mkLdarg (uint16 n))) @ - // Make the instance of the delegated closure && return it. - [ I_newobj (laterCloSpec.Constructor, None) ] - end, - tagApp) + let nowCode = mkILMethodBody (false, [], argToFreeVarMap.Length + nowFields.Length, nonBranchingInstrsToCode nowInstrs, cloTag, cloImports) let nowTypeDefs = convIlxClosureDef cenv encl td {clo with cloStructure=nowStruct @@ -547,7 +550,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let laterTypeDefs = convIlxClosureDef cenv encl - (td.With(genericParams=laterGenericParams, name=laterTypeName)) + (td.With(genericParams=laterGenericParams, name=laterTypeName, methods=emptyILMethods, fields=emptyILFields)) {clo with cloStructure=laterStruct cloFreeVars=laterFields cloCode=notlazy laterCode} @@ -564,20 +567,21 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = let nowEnvParentClass = typ_Func cenv (typesOfILParams nowParams) nowReturnTy let cloTypeDef = + let convil = convILMethodBody (Some nowCloSpec, None) (Lazy.force clo.cloCode) let nowApplyMethDef = mkILNonGenericVirtualMethod ("Invoke", ILMemberAccess.Public, nowParams, mkILReturn nowReturnTy, - MethodBody.IL (convILMethodBody (Some nowCloSpec, None) (Lazy.force clo.cloCode))) + MethodBody.IL (lazy convil)) let ctorMethodDef = mkILStorageCtor - (None, - [ mkLdarg0; mkNormalCall (mkILCtorMethSpecForTy (nowEnvParentClass, [])) ], + ([ mkLdarg0; mkNormalCall (mkILCtorMethSpecForTy (nowEnvParentClass, [])) ], nowTy, mkILCloFldSpecs cenv nowFields, - ILMemberAccess.Assembly) + ILMemberAccess.Assembly, + None, cloImports) |> cenv.addMethodGeneratedAttrs ILTypeDef(name = td.Name, @@ -587,8 +591,8 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = layout=ILTypeDefLayout.Auto, nestedTypes = emptyILTypeDefs, extends= Some nowEnvParentClass, - methods= mkILMethods ([ctorMethodDef] @ [nowApplyMethDef]), - fields= mkILFields (mkILCloFldDefs cenv nowFields), + methods= mkILMethods (ctorMethodDef :: nowApplyMethDef :: nowMethods), + fields= mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList), customAttrs=emptyILCustomAttrs, methodImpls=emptyILMethodImpls, properties=emptyILProperties, @@ -607,34 +611,36 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo = | [], [], Lambdas_return _ -> // No code is being declared: just bake a (mutable) environment - let cloCode' = + let cloCodeR = match td.Extends with - | None -> (mkILNonGenericEmptyCtor None cenv.ilg.typ_Object).MethodBody + | None -> (mkILNonGenericEmptyCtor (cenv.ilg.typ_Object, None, cloImports)).MethodBody | Some _ -> convILMethodBody (Some nowCloSpec, None) (Lazy.force clo.cloCode) let ctorMethodDef = let flds = (mkILCloFldSpecs cenv nowFields) - mkILCtor(ILMemberAccess.Public, - List.map mkILParamNamed flds, - mkMethodBody - (cloCode'.IsZeroInit, - cloCode'.Locals, - cloCode'.MaxStack, - prependInstrsToCode - (List.concat (List.mapi (fun n (nm, ty) -> - [ mkLdarg0 - mkLdarg (uint16 (n+1)) - mkNormalStfld (mkILFieldSpecInTy (nowTy, nm, ty)) - ]) flds)) - cloCode'.Code, - None)) + mkILCtor( + ILMemberAccess.Public, + List.map mkILParamNamed flds, + mkMethodBody + (cloCodeR.IsZeroInit, + cloCodeR.Locals, + cloCodeR.MaxStack, + prependInstrsToCode + (List.concat (List.mapi (fun n (nm, ty) -> + [ mkLdarg0 + mkLdarg (uint16 (n+1)) + mkNormalStfld (mkILFieldSpecInTy (nowTy, nm, ty)) + ]) flds)) + cloCodeR.Code, + None, + None)) let cloTypeDef = td.With(implements= td.Implements, extends= (match td.Extends with None -> Some cenv.ilg.typ_Object | Some x -> Some(x)), name = td.Name, genericParams= td.GenericParams, - methods= mkILMethods (ctorMethodDef :: List.map (convMethodDef (Some nowCloSpec)) td.Methods.AsList), + methods= mkILMethods (ctorMethodDef :: nowMethods), fields= mkILFields (mkILCloFldDefs cenv nowFields @ td.Fields.AsList)) [cloTypeDef] diff --git a/src/ilx/EraseClosures.fsi b/src/fsharp/ilx/EraseClosures.fsi similarity index 79% rename from src/ilx/EraseClosures.fsi rename to src/fsharp/ilx/EraseClosures.fsi index 9a0d886ca53..f7426491da2 100644 --- a/src/ilx/EraseClosures.fsi +++ b/src/fsharp/ilx/EraseClosures.fsi @@ -1,19 +1,21 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. /// Compiler use only. Erase closures -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.EraseClosures +module internal FSharp.Compiler.AbstractIL.ILX.EraseClosures -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Extensions.ILX -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types +open FSharp.Compiler.AbstractIL.ILX.Types type cenv + val mkCallFunc : cenv -> allocLocal:(ILType -> uint16) -> numThisGenParams:int -> ILTailcall -> IlxClosureApps -> ILInstr list val mkILFuncTy : cenv -> ILType -> ILType -> ILType + val mkILTyFuncTy : cenv -> ILType + val newIlxPubCloEnv : ILGlobals * addMethodGeneratedAttrs: (ILMethodDef -> ILMethodDef) * addFieldGeneratedAttrs: (ILFieldDef -> ILFieldDef) * addFieldNeverAttrs: (ILFieldDef -> ILFieldDef) -> cenv + val mkTyOfLambdas: cenv -> IlxClosureLambdas -> ILType val convIlxClosureDef : cenv -> encl: string list -> ILTypeDef -> IlxClosureInfo -> ILTypeDef list diff --git a/src/ilx/EraseUnions.fs b/src/fsharp/ilx/EraseUnions.fs similarity index 86% rename from src/ilx/EraseUnions.fs rename to src/fsharp/ilx/EraseUnions.fs index c24a30a6105..b03c89d3172 100644 --- a/src/ilx/EraseUnions.fs +++ b/src/fsharp/ilx/EraseUnions.fs @@ -1,34 +1,33 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// -------------------------------------------------------------------- -// Erase discriminated unions. -// -------------------------------------------------------------------- - - -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.EraseUnions +/// Erase discriminated unions. +module internal FSharp.Compiler.AbstractIL.ILX.EraseUnions open System.Collections.Generic - -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types open System.Reflection - +open Internal.Utilities.Library +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILX.Types [] let TagNil = 0 + [] let TagCons = 1 + [] let ALT_NAME_CONS = "Cons" type DiscriminationTechnique = /// Indicates a special representation for the F# list type where the "empty" value has a tail field of value null | TailOrNull + /// Indicates a type with either number of cases < 4, and not a single-class type with an integer tag (IntegerTag) | RuntimeTypes + /// Indicates a type with a single case, e.g. ``type X = ABC of string * int`` | SingleCase + /// Indicates a type with either cases >= 4, or a type like // type X = A | B | C // or type X = A | B | C of string @@ -104,7 +103,7 @@ type UnionReprDecisions<'Union,'Alt,'Type> // Check this is the one and only non-nullary constructor Array.existsOne (isNullary >> not) alts - member repr.RepresentAlternativeAsStructValue (cu) = + member repr.RepresentAlternativeAsStructValue cu = isStruct cu member repr.RepresentAlternativeAsFreshInstancesOfRootClass (cu,alt) = @@ -163,37 +162,41 @@ let cuspecRepr = UnionReprDecisions ((fun (cuspec:IlxUnionSpec) -> cuspec.AlternativesArray), (fun (cuspec:IlxUnionSpec) -> cuspec.IsNullPermitted), - (fun (alt:IlxUnionAlternative) -> alt.IsNullary), + (fun (alt:IlxUnionCase) -> alt.IsNullary), (fun cuspec -> cuspec.HasHelpers = IlxUnionHasHelpers.SpecialFSharpListHelpers), (fun cuspec -> cuspec.Boxity = ILBoxity.AsValue), - (fun (alt:IlxUnionAlternative) -> alt.Name), + (fun (alt:IlxUnionCase) -> alt.Name), (fun cuspec -> cuspec.DeclaringType), (fun (cuspec,nm) -> mkILNamedTy cuspec.Boxity (mkILTyRefInTyRef (mkCasesTypeRef cuspec, nm)) cuspec.GenericArgs)) type NoTypesGeneratedViaThisReprDecider = NoTypesGeneratedViaThisReprDecider + let cudefRepr = UnionReprDecisions - ((fun (_td,cud) -> cud.cudAlternatives), - (fun (_td,cud) -> cud.cudNullPermitted), - (fun (alt:IlxUnionAlternative) -> alt.IsNullary), - (fun (_td,cud) -> cud.cudHasHelpers = IlxUnionHasHelpers.SpecialFSharpListHelpers), + ((fun (_td,cud) -> cud.UnionCases), + (fun (_td,cud) -> cud.IsNullPermitted), + (fun (alt:IlxUnionCase) -> alt.IsNullary), + (fun (_td,cud) -> cud.HasHelpers = IlxUnionHasHelpers.SpecialFSharpListHelpers), (fun (td:ILTypeDef,_cud) -> td.IsStruct), - (fun (alt:IlxUnionAlternative) -> alt.Name), + (fun (alt:IlxUnionCase) -> alt.Name), (fun (_td,_cud) -> NoTypesGeneratedViaThisReprDecider), (fun ((_td,_cud),_nm) -> NoTypesGeneratedViaThisReprDecider)) let mkTesterName nm = "Is" + nm + let tagPropertyName = "Tag" -let mkUnionCaseFieldId (fdef: IlxUnionField) = +let mkUnionCaseFieldId (fdef: IlxUnionCaseField) = // Use the lower case name of a field or constructor as the field/parameter name if it differs from the uppercase name fdef.LowerName, fdef.Type let refToFieldInTy ty (nm, fldTy) = mkILFieldSpecInTy (ty, nm, fldTy) let formalTypeArgs (baseTy:ILType) = List.mapi (fun i _ -> mkILTyvarTy (uint16 i)) baseTy.GenericArgs + let constFieldName nm = "_unique_" + nm + let constFormalFieldTy (baseTy:ILType) = mkILNamedTy baseTy.Boxity baseTy.TypeRef (formalTypeArgs baseTy) @@ -203,16 +206,17 @@ let mkConstFieldSpecFromId (baseTy:ILType) constFieldId = let mkConstFieldSpec nm (baseTy:ILType) = mkConstFieldSpecFromId baseTy (constFieldName nm, constFormalFieldTy baseTy) - let tyForAlt cuspec alt = cuspecRepr.TypeForAlternative(cuspec,alt) let GetILTypeForAlternative cuspec alt = cuspecRepr.TypeForAlternative(cuspec,cuspec.Alternative alt) let mkTagFieldType (ilg: ILGlobals) _cuspec = ilg.typ_Int32 + let mkTagFieldFormalType (ilg: ILGlobals) _cuspec = ilg.typ_Int32 + let mkTagFieldId ilg cuspec = "_tag", mkTagFieldType ilg cuspec -let mkTailOrNullId baseTy = "tail", constFormalFieldTy baseTy +let mkTailOrNullId baseTy = "tail", constFormalFieldTy baseTy let altOfUnionSpec (cuspec:IlxUnionSpec) cidx = try cuspec.Alternative cidx @@ -224,7 +228,7 @@ let altOfUnionSpec (cuspec:IlxUnionSpec) cidx = // calling the IsFoo helper. This only applies to discriminations outside the // assembly where the type is defined (indicated by 'avoidHelpers' flag - if this is true // then the reference is intra-assembly). -let doesRuntimeTypeDiscriminateUseHelper avoidHelpers (cuspec: IlxUnionSpec) (alt: IlxUnionAlternative) = +let doesRuntimeTypeDiscriminateUseHelper avoidHelpers (cuspec: IlxUnionSpec) (alt: IlxUnionCase) = not avoidHelpers && alt.IsNullary && cuspec.HasHelpers = IlxUnionHasHelpers.AllHelpers let mkRuntimeTypeDiscriminate (ilg: ILGlobals) avoidHelpers cuspec alt altName altTy = @@ -274,7 +278,6 @@ let mkLdDataAddr (avoidHelpers, cuspec, cidx, fidx) = let mkGetTailOrNull avoidHelpers cuspec = mkLdData (avoidHelpers, cuspec, 1, 1) (* tail is in alternative 1, field number 1 *) - let mkGetTagFromHelpers ilg (cuspec: IlxUnionSpec) = let baseTy = baseTyOfUnionSpec cuspec if cuspecRepr.RepresentOneAlternativeAsNull cuspec then @@ -293,7 +296,6 @@ let mkCeqThen after = | I_brcmp (BI_brtrue,a) -> [I_brcmp (BI_beq,a)] | _ -> [AI_ceq; after] - let mkTagDiscriminate ilg cuspec _baseTy cidx = mkGetTag ilg cuspec @ [ mkLdcInt32 cidx; AI_ceq ] @@ -315,7 +317,7 @@ let rec extraTysAndInstrsForStructCtor (ilg: ILGlobals) cidx = let tys, instrs = extraTysAndInstrsForStructCtor ilg (cidx - 7) (ilg.typ_UInt32 :: tys, mkLdcInt32 0 :: instrs) -let takesExtraParams (alts: IlxUnionAlternative[]) = +let takesExtraParams (alts: IlxUnionCase[]) = alts.Length > 1 && (alts |> Array.exists (fun d -> d.FieldDefs.Length > 0) || // Check if not all lengths are distinct @@ -419,20 +421,19 @@ let genWith g : ILCode = let instrs = ResizeArray() let lab2pc = Dictionary() g { new ICodeGen with - member __.CodeLabel(m) = m - member __.GenerateDelayMark() = generateCodeLabel() - member __.GenLocal(ilty) = failwith "not needed" - member __.SetMarkToHere(m) = lab2pc.[m] <- instrs.Count - member __.EmitInstr x = instrs.Add x + member _.CodeLabel(m) = m + member _.GenerateDelayMark() = generateCodeLabel() + member _.GenLocal(ilty) = failwith "not needed" + member _.SetMarkToHere(m) = lab2pc.[m] <- instrs.Count + member _.EmitInstr x = instrs.Add x member cg.EmitInstrs xs = for i in xs do cg.EmitInstr i - member __.MkInvalidCastExnNewobj () = failwith "not needed" } + member _.MkInvalidCastExnNewobj () = failwith "not needed" } { Labels = lab2pc Instrs = instrs.ToArray() Exceptions = [] Locals = [] } - let mkBrIsData ilg sense (avoidHelpers, cuspec,cidx,tg) = let neg = (if sense then BI_brfalse else BI_brtrue) let pos = (if sense then BI_brtrue else BI_brfalse) @@ -459,7 +460,7 @@ let mkBrIsData ilg sense (avoidHelpers, cuspec,cidx,tg) = let emitLdDataTagPrim ilg ldOpt (cg: ICodeGen<'Mark>) (avoidHelpers,cuspec: IlxUnionSpec) = // If helpers exist, use them match cuspec.HasHelpers with - | (SpecialFSharpListHelpers | AllHelpers) when not avoidHelpers -> + | SpecialFSharpListHelpers | AllHelpers when not avoidHelpers -> ldOpt |> Option.iter cg.EmitInstr cg.EmitInstr (mkGetTagFromHelpers ilg cuspec) | _ -> @@ -560,7 +561,7 @@ let emitDataSwitch ilg (cg: ICodeGen<'Mark>) (avoidHelpers, cuspec, cases) = cg.EmitInstr (mkStloc locn) - for (cidx,tg) in cases do + for cidx,tg in cases do let alt = altOfUnionSpec cuspec cidx let altTy = tyForAlt cuspec alt let altName = alt.Name @@ -582,7 +583,7 @@ let emitDataSwitch ilg (cg: ICodeGen<'Mark>) (avoidHelpers, cuspec, cases) = | _ -> // Use a dictionary to avoid quadratic lookup in case list let dict = Dictionary() - for (i,case) in cases do dict.[i] <- case + for i,case in cases do dict.[i] <- case let failLab = cg.GenerateDelayMark () let emitCase i _ = match dict.TryGetValue i with @@ -603,12 +604,10 @@ let emitDataSwitch ilg (cg: ICodeGen<'Mark>) (avoidHelpers, cuspec, cases) = | TailOrNull -> failwith "unexpected: switches on lists should have been eliminated to brisdata tests" - - //--------------------------------------------------- // Generate the union classes -let mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) access attr hasHelpers (ilTy: ILType) (fields: IlxUnionField[]) = +let mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) access attr imports hasHelpers (ilTy: ILType) (fields: IlxUnionCaseField[]) = let basicProps = fields |> Array.map (fun field -> @@ -632,14 +631,17 @@ let mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGenerat mkILNonGenericInstanceMethod ("get_" + adjustFieldName hasHelpers field.Name, access, [], mkILReturn field.Type, - mkMethodBody(true,[],2,nonBranchingInstrsToCode [ mkLdarg 0us; mkNormalLdfld fspec ], attr)) + mkMethodBody(true,[],2,nonBranchingInstrsToCode [ mkLdarg 0us; mkNormalLdfld fspec ], attr, imports)) |> addMethodGeneratedAttrs ] basicProps, basicMethods - -let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs, mkDebuggerTypeProxyAttribute) (ilg: ILGlobals) num (td:ILTypeDef) cud info cuspec (baseTy:ILType) (alt:IlxUnionAlternative) = - let attr = cud.cudWhere +let convAlternativeDef + (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs, mkDebuggerTypeProxyAttribute) + (ilg: ILGlobals) num (td:ILTypeDef) (cud : IlxUnionInfo) info cuspec (baseTy:ILType) (alt:IlxUnionCase) = + + let imports = cud.DebugImports + let attr = cud.DebugPoint let altName = alt.Name let fields = alt.FieldDefs let altTy = tyForAlt cuspec alt @@ -652,13 +654,13 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP // // Microsoft.FSharp.Collections.List`1 is indeed logically immutable, but we use mutation on this type internally // within FSharp.Core.dll on fresh unpublished cons cells. - let isTotallyImmutable = (cud.cudHasHelpers <> SpecialFSharpListHelpers) + let isTotallyImmutable = (cud.HasHelpers <> SpecialFSharpListHelpers) let altUniqObjMeths = // This method is only generated if helpers are not available. It fetches the unique object for the alternative // without exposing direct access to the underlying field - match cud.cudHasHelpers with + match cud.HasHelpers with | AllHelpers | SpecialFSharpOptionHelpers | SpecialFSharpListHelpers -> [] @@ -668,10 +670,8 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP let meth = mkILNonGenericStaticMethod (methName, - cud.cudReprAccess,[],mkILReturn(baseTy), - mkMethodBody(true,[],fields.Length, - nonBranchingInstrsToCode - [ I_ldsfld (Nonvolatile,mkConstFieldSpec altName baseTy) ], attr)) + cud.UnionCasesAccessibility,[],mkILReturn(baseTy), + mkMethodBody(true,[],fields.Length, nonBranchingInstrsToCode [ I_ldsfld (Nonvolatile,mkConstFieldSpec altName baseTy) ], attr, imports)) |> addMethodGeneratedAttrs [meth] @@ -680,21 +680,20 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP let baseMakerMeths, baseMakerProps = - match cud.cudHasHelpers with + match cud.HasHelpers with | AllHelpers | SpecialFSharpOptionHelpers | SpecialFSharpListHelpers -> let baseTesterMeths, baseTesterProps = - if cud.cudAlternatives.Length <= 1 then [], [] + if cud.UnionCases.Length <= 1 then [], [] elif repr.RepresentOneAlternativeAsNull info then [], [] else [ mkILNonGenericInstanceMethod ("get_" + mkTesterName altName, - cud.cudHelpersAccess,[], + cud.HelpersAccessibility,[], mkILReturn ilg.typ_Bool, - mkMethodBody(true,[],2,nonBranchingInstrsToCode - ([ mkLdarg0 ] @ mkIsData ilg (true, cuspec, num)), attr)) + mkMethodBody(true,[],2,nonBranchingInstrsToCode ([ mkLdarg0 ] @ mkIsData ilg (true, cuspec, num)), attr, imports)) |> addMethodGeneratedAttrs ], [ ILPropertyDef(name = mkTesterName altName, attributes = PropertyAttributes.None, @@ -717,8 +716,8 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP let nullaryMeth = mkILNonGenericStaticMethod ("get_" + altName, - cud.cudHelpersAccess, [], mkILReturn baseTy, - mkMethodBody(true,[],fields.Length, nonBranchingInstrsToCode (convNewDataInstrInternal ilg cuspec num), attr)) + cud.HelpersAccessibility, [], mkILReturn baseTy, + mkMethodBody(true,[],fields.Length, nonBranchingInstrsToCode (convNewDataInstrInternal ilg cuspec num), attr, imports)) |> addMethodGeneratedAttrs |> addAltAttribs @@ -739,16 +738,19 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP [nullaryMeth],[nullaryProp] else + let ilInstrs = + [ for i in 0..fields.Length-1 do + mkLdarg (uint16 i) + yield! convNewDataInstrInternal ilg cuspec num ] + |> nonBranchingInstrsToCode + let mdef = mkILNonGenericStaticMethod (mkMakerName cuspec altName, - cud.cudHelpersAccess, + cud.HelpersAccessibility, fields |> Array.map (fun fd -> mkILParamNamed (fd.LowerName, fd.Type)) |> Array.toList, mkILReturn baseTy, - mkMethodBody(true,[],fields.Length, - nonBranchingInstrsToCode - (Array.toList (Array.mapi (fun i _ -> mkLdarg (uint16 i)) fields) @ - (convNewDataInstrInternal ilg cuspec num)), attr)) + mkMethodBody(true, [], fields.Length, ilInstrs, attr, imports)) |> addMethodGeneratedAttrs |> addAltAttribs @@ -781,7 +783,7 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP if repr.OptimizeAlternativeToRootClass (info,alt) then [], [] else let altDebugTypeDefs, debugAttrs = - if not cud.cudDebugProxies then [], [] + if not cud.GenerateDebugProxies then [], [] else let debugProxyTypeName = altTy.TypeSpec.Name + "@DebugTypeProxy" @@ -791,17 +793,18 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP let debugProxyFields = [ mkILInstanceField (debugProxyFieldName,altTy, None, ILMemberAccess.Assembly) |> addFieldNeverAttrs |> addFieldGeneratedAttrs] + let debugProxyCode = + [ mkLdarg0 + mkNormalCall (mkILCtorMethSpecForTy (ilg.typ_Object,[])) + mkLdarg0 + mkLdarg 1us + mkNormalStfld (mkILFieldSpecInTy (debugProxyTy,debugProxyFieldName,altTy)) ] + |> nonBranchingInstrsToCode + let debugProxyCtor = mkILCtor(ILMemberAccess.Public (* must always be public - see jared parson blog entry on implementing debugger type proxy *), [ mkILParamNamed ("obj",altTy) ], - mkMethodBody - (false,[],3, - nonBranchingInstrsToCode - [ yield mkLdarg0 - yield mkNormalCall (mkILCtorMethSpecForTy (ilg.typ_Object,[])) - yield mkLdarg0 - yield mkLdarg 1us - yield mkNormalStfld (mkILFieldSpecInTy (debugProxyTy,debugProxyFieldName,altTy)) ],None)) + mkMethodBody (false, [], 3, debugProxyCode, None, imports)) |> addMethodGeneratedAttrs @@ -809,16 +812,15 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP fields |> Array.map (fun field -> let fldName,fldTy = mkUnionCaseFieldId field - mkILNonGenericInstanceMethod - ("get_" + field.Name, - ILMemberAccess.Public,[], - mkILReturn field.Type, - mkMethodBody(true,[],2, - nonBranchingInstrsToCode - [ mkLdarg0 - (if td.IsStruct then mkNormalLdflda else mkNormalLdfld) - (mkILFieldSpecInTy (debugProxyTy,debugProxyFieldName,altTy)) - mkNormalLdfld (mkILFieldSpecInTy(altTy,fldName,fldTy))],None)) + let instrs = + [ mkLdarg0 + (if td.IsStruct then mkNormalLdflda else mkNormalLdfld) (mkILFieldSpecInTy (debugProxyTy,debugProxyFieldName,altTy)) + mkNormalLdfld (mkILFieldSpecInTy(altTy,fldName,fldTy))] + |> nonBranchingInstrsToCode + + let mbody = mkMethodBody(true,[],2, instrs, None, imports) + + mkILNonGenericInstanceMethod ("get_" + field.Name, ILMemberAccess.Public, [], mkILReturn field.Type, mbody) |> addMethodGeneratedAttrs ) |> Array.toList @@ -851,7 +853,7 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP ILTypeInit.BeforeField) [ debugProxyTypeDef.WithSpecialName(true) ], - ( [mkDebuggerTypeProxyAttribute debugProxyTy] @ cud.cudDebugDisplayAttributes) + ( [mkDebuggerTypeProxyAttribute debugProxyTy] @ cud.DebugDisplayAttributes) let altTypeDef = let basicFields = @@ -863,30 +865,32 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP |> Array.toList - let basicProps, basicMethods = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) (cud.cudReprAccess) attr cud.cudHasHelpers altTy fields + let basicProps, basicMethods = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) cud.UnionCasesAccessibility attr imports cud.HasHelpers altTy fields + + let basicCtorInstrs = + [ yield mkLdarg0 + match repr.DiscriminationTechnique info with + | IntegerTag -> + yield mkLdcInt32 num + yield mkNormalCall (mkILCtorMethSpecForTy (baseTy,[mkTagFieldType ilg cuspec])) + | SingleCase + | RuntimeTypes -> + yield mkNormalCall (mkILCtorMethSpecForTy (baseTy,[])) + | TailOrNull -> + failwith "unreachable" ] + + let basicCtorAccess = (if cuspec.HasHelpers = AllHelpers then ILMemberAccess.Assembly else cud.UnionCasesAccessibility) + + let basicCtorFields = basicFields |> List.map (fun fdef -> fdef.Name, fdef.FieldType) - let basicCtorMeth = - mkILStorageCtor - (attr , - [ yield mkLdarg0 - match repr.DiscriminationTechnique info with - | IntegerTag -> - yield mkLdcInt32 num - yield mkNormalCall (mkILCtorMethSpecForTy (baseTy,[mkTagFieldType ilg cuspec])) - | SingleCase - | RuntimeTypes -> - yield mkNormalCall (mkILCtorMethSpecForTy (baseTy,[])) - | TailOrNull -> - failwith "unreachable" ], - altTy, - (basicFields |> List.map (fun fdef -> fdef.Name, fdef.FieldType) ), - (if cuspec.HasHelpers = AllHelpers then ILMemberAccess.Assembly else cud.cudReprAccess)) + let basicCtorMeth = + mkILStorageCtor (basicCtorInstrs, altTy, basicCtorFields, basicCtorAccess, attr, imports) |> addMethodGeneratedAttrs let altTypeDef = mkILGenericClass (altTy.TypeSpec.Name, // Types for nullary's become private, they also have names like _Empty - ILTypeDefAccess.Nested (if alt.IsNullary && cud.cudHasHelpers = IlxUnionHasHelpers.AllHelpers then ILMemberAccess.Assembly else cud.cudReprAccess), + ILTypeDefAccess.Nested (if alt.IsNullary && cud.HasHelpers = IlxUnionHasHelpers.AllHelpers then ILMemberAccess.Assembly else cud.UnionCasesAccessibility), td.GenericParams, baseTy, [], mkILMethods ([basicCtorMeth] @ basicMethods), @@ -910,13 +914,13 @@ let convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addP let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs: ILFieldDef -> ILFieldDef, addFieldNeverAttrs: ILFieldDef -> ILFieldDef, mkDebuggerTypeProxyAttribute) ilg tref (td:ILTypeDef) cud = let boxity = if td.IsStruct then ILBoxity.AsValue else ILBoxity.AsObject let baseTy = mkILFormalNamedTy boxity tref td.GenericParams - let cuspec = IlxUnionSpec(IlxUnionRef(boxity,baseTy.TypeRef, cud.cudAlternatives, cud.cudNullPermitted, cud.cudHasHelpers), baseTy.GenericArgs) + let cuspec = IlxUnionSpec(IlxUnionRef(boxity,baseTy.TypeRef, cud.UnionCases, cud.IsNullPermitted, cud.HasHelpers), baseTy.GenericArgs) let info = (td,cud) let repr = cudefRepr - let isTotallyImmutable = (cud.cudHasHelpers <> SpecialFSharpListHelpers) + let isTotallyImmutable = (cud.HasHelpers <> SpecialFSharpListHelpers) let results = - cud.cudAlternatives + cud.UnionCases |> List.ofArray |> List.mapi (fun i alt -> convAlternativeDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addPropertyNeverAttrs, addFieldGeneratedAttrs, addFieldNeverAttrs, mkDebuggerTypeProxyAttribute) ilg i td cud info cuspec baseTy alt) @@ -936,7 +940,7 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp let selfFields, selfMeths, selfProps = - [ for (cidx, alt) in Array.indexed cud.cudAlternatives do + [ for cidx, alt in Array.indexed cud.UnionCases do if repr.RepresentAlternativeAsFreshInstancesOfRootClass (info,alt) || repr.RepresentAlternativeAsStructValue info then // TODO @@ -948,47 +952,52 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp | Some ilTy -> Some ilTy.TypeSpec let extraParamsForCtor = - if isStruct && takesExtraParams cud.cudAlternatives then + if isStruct && takesExtraParams cud.UnionCases then let extraTys, _extraInstrs = extraTysAndInstrsForStructCtor ilg cidx List.map mkILParamAnon extraTys else [] + let ctorAccess = (if cuspec.HasHelpers = AllHelpers then ILMemberAccess.Assembly else cud.UnionCasesAccessibility) + let ctor = mkILSimpleStorageCtor - (cud.cudWhere, - baseInit, + (baseInit, baseTy, extraParamsForCtor, (fields @ tagFieldsInObject), - (if cuspec.HasHelpers = AllHelpers then ILMemberAccess.Assembly else cud.cudReprAccess)) + ctorAccess, + cud.DebugPoint, + cud.DebugImports) |> addMethodGeneratedAttrs - let props, meths = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) (cud.cudReprAccess) cud.cudWhere cud.cudHasHelpers baseTy alt.FieldDefs + let props, meths = mkMethodsAndPropertiesForFields (addMethodGeneratedAttrs, addPropertyGeneratedAttrs) cud.UnionCasesAccessibility cud.DebugPoint cud.DebugImports cud.HasHelpers baseTy alt.FieldDefs yield (fields,([ctor] @ meths),props) ] |> List.unzip3 |> (fun (a,b,c) -> List.concat a, List.concat b, List.concat c) let selfAndTagFields = - [ for (fldName,fldTy) in (selfFields @ tagFieldsInObject) do + [ for fldName,fldTy in (selfFields @ tagFieldsInObject) do let fdef = mkILInstanceField (fldName,fldTy, None, ILMemberAccess.Assembly) |> addFieldNeverAttrs |> addFieldGeneratedAttrs yield fdef.WithInitOnly(not isStruct && isTotallyImmutable) ] let ctorMeths = if (List.isEmpty selfFields && List.isEmpty tagFieldsInObject && not (List.isEmpty selfMeths)) || isStruct - || cud.cudAlternatives |> Array.forall (fun alt -> repr.RepresentAlternativeAsFreshInstancesOfRootClass (info,alt)) then + || cud.UnionCases |> Array.forall (fun alt -> repr.RepresentAlternativeAsFreshInstancesOfRootClass (info,alt)) then [] (* no need for a second ctor in these cases *) else + let baseTySpec = (match td.Extends with None -> ilg.typ_Object | Some ilTy -> ilTy).TypeSpec [ mkILSimpleStorageCtor - (cud.cudWhere, - Some (match td.Extends with None -> ilg.typ_Object | Some ilTy -> ilTy).TypeSpec, + (Some baseTySpec, baseTy, [], tagFieldsInObject, - ILMemberAccess.Assembly) // cud.cudReprAccess) + ILMemberAccess.Assembly, + cud.DebugPoint, + cud.DebugImports) |> addMethodGeneratedAttrs ] // Now initialize the constant fields wherever they are stored... @@ -997,7 +1006,7 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp cd else prependInstrsToClassCtor - [ for (info,_alt,altTy,fidx,fd,inRootClass) in altNullaryFields do + [ for info,_alt,altTy,fidx,fd,inRootClass in altNullaryFields do let constFieldId = (fd.Name,baseTy) let constFieldSpec = mkConstFieldSpecFromId baseTy constFieldId match repr.DiscriminationTechnique info with @@ -1012,29 +1021,31 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp else yield mkNormalNewobj (mkILCtorMethSpecForTy (altTy,[])) yield mkNormalStsfld constFieldSpec ] - cud.cudWhere + cud.DebugPoint + cud.DebugImports cd let tagMeths, tagProps, tagEnumFields = let tagFieldType = mkTagFieldType ilg cuspec let tagEnumFields = - cud.cudAlternatives + cud.UnionCases |> Array.mapi (fun num alt -> mkILLiteralField (alt.Name, tagFieldType, ILFieldInit.Int32 num, None, ILMemberAccess.Public)) |> Array.toList let tagMeths,tagProps = - let body = mkMethodBody(true,[],2,genWith (fun cg -> emitLdDataTagPrim ilg (Some mkLdarg0) cg (true, cuspec); cg.EmitInstr I_ret), cud.cudWhere) + let code = genWith (fun cg -> emitLdDataTagPrim ilg (Some mkLdarg0) cg (true, cuspec); cg.EmitInstr I_ret) + let body = mkMethodBody(true, [], 2, code, cud.DebugPoint, cud.DebugImports) // // If we are using NULL as a representation for an element of this type then we cannot // // use an instance method if (repr.RepresentOneAlternativeAsNull info) then - [ mkILNonGenericStaticMethod("Get" + tagPropertyName,cud.cudHelpersAccess,[mkILParamAnon baseTy],mkILReturn tagFieldType,body) + [ mkILNonGenericStaticMethod("Get" + tagPropertyName,cud.HelpersAccessibility,[mkILParamAnon baseTy],mkILReturn tagFieldType,body) |> addMethodGeneratedAttrs ], [] else - [ mkILNonGenericInstanceMethod("get_" + tagPropertyName,cud.cudHelpersAccess,[],mkILReturn tagFieldType,body) + [ mkILNonGenericInstanceMethod("get_" + tagPropertyName,cud.HelpersAccessibility,[],mkILReturn tagFieldType,body) |> addMethodGeneratedAttrs ], [ ILPropertyDef(name = tagPropertyName, @@ -1052,7 +1063,7 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp tagMeths, tagProps, tagEnumFields // The class can be abstract if each alternative is represented by a derived type - let isAbstract = (altTypeDefs.Length = cud.cudAlternatives.Length) + let isAbstract = (altTypeDefs.Length = cud.UnionCases.Length) let existingMeths = td.Methods.AsList let existingProps = td.Properties.AsList @@ -1078,7 +1089,7 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp events=emptyILEvents, properties=emptyILProperties, customAttrs= emptyILCustomAttrs) - .WithNestedAccess(cud.cudReprAccess) + .WithNestedAccess(cud.UnionCasesAccessibility) .WithAbstract(true) .WithSealed(true) .WithImport(false) @@ -1097,5 +1108,3 @@ let mkClassUnionDef (addMethodGeneratedAttrs, addPropertyGeneratedAttrs, addProp |> addConstFieldInit baseTypeDef.WithAbstract(isAbstract).WithSealed(altTypeDefs.IsEmpty) - - diff --git a/src/ilx/EraseUnions.fsi b/src/fsharp/ilx/EraseUnions.fsi similarity index 95% rename from src/ilx/EraseUnions.fsi rename to src/fsharp/ilx/EraseUnions.fsi index b263a9bf33c..acfeab71424 100644 --- a/src/ilx/EraseUnions.fsi +++ b/src/fsharp/ilx/EraseUnions.fsi @@ -4,10 +4,10 @@ // Compiler use only. Erase discriminated unions. // -------------------------------------------------------------------- -module internal FSharp.Compiler.AbstractIL.Extensions.ILX.EraseUnions +module internal FSharp.Compiler.AbstractIL.ILX.EraseUnions open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types +open FSharp.Compiler.AbstractIL.ILX.Types /// Make the instruction sequence for a "newdata" operation val mkNewData : ILGlobals -> IlxUnionSpec * int -> ILInstr list diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index 849d7fff709..cc3cb3bd641 100644 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -5,16 +5,20 @@ module internal FSharp.Compiler.Import open System.Collections.Concurrent open System.Collections.Generic - -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Ast +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals + #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping #endif @@ -25,6 +29,9 @@ type AssemblyLoader = /// Resolve an Abstract IL assembly reference to a Ccu abstract FindCcuFromAssemblyRef : CompilationThreadToken * range * ILAssemblyRef -> CcuResolutionResult + + abstract TryFindXmlDocumentationInfo : assemblyName: string -> XmlDocumentationInfo option + #if !NO_EXTENSIONTYPING /// Get a flag indicating if an assembly is a provided assembly, plus the @@ -105,9 +112,9 @@ let ImportTypeRefData (env: ImportMap) m (scoref, path, typeName) = #if !NO_EXTENSIONTYPING // Validate (once because of caching) match tycon.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> + | TProvidedTypeRepr info -> //printfn "ImportTypeRefData: validating type: typeLogicalName = %A" typeName - ExtensionTyping.ValidateProvidedTypeAfterStaticInstantiation(m, info.ProvidedType, path, typeName) + ValidateProvidedTypeAfterStaticInstantiation(m, info.ProvidedType, path, typeName) | _ -> () #endif @@ -183,6 +190,7 @@ let rec ImportILType (env: ImportMap) m tinst ty = with _ -> error(Error(FSComp.SR.impNotEnoughTypeParamsInScopeWhileImporting(), m)) +/// Determines if an IL type can be imported as an F# type let rec CanImportILType (env: ImportMap) m ty = match ty with | ILType.Void -> true @@ -204,7 +212,7 @@ let ImportProvidedNamedType (env: ImportMap) (m: range) (st: Tainted st.TryGetTyconRef()), m) with | Some x -> (x :?> TyconRef) | None -> - let tref = ExtensionTyping.GetILTypeRefOfProvidedType (st, m) + let tref = GetILTypeRefOfProvidedType (st, m) ImportILTypeRef env m tref /// Import a provided type as an AbstractIL type @@ -229,7 +237,7 @@ let rec ImportProvidedTypeAsILType (env: ImportMap) (m: range) (st: Tainted genericArgs.Length then @@ -280,20 +288,35 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( let tcref = ImportProvidedNamedType env m st tcref, [] + let genericArgsLength = genericArgs.Length /// Adjust for the known primitive numeric types that accept units of measure. - let tcref = - if tyconRefEq g tcref g.system_Double_tcref && genericArgs.Length = 1 then g.pfloat_tcr - elif tyconRefEq g tcref g.system_Single_tcref && genericArgs.Length = 1 then g.pfloat32_tcr - elif tyconRefEq g tcref g.system_Decimal_tcref && genericArgs.Length = 1 then g.pdecimal_tcr - elif tyconRefEq g tcref g.system_Int16_tcref && genericArgs.Length = 1 then g.pint16_tcr - elif tyconRefEq g tcref g.system_Int32_tcref && genericArgs.Length = 1 then g.pint_tcr - elif tyconRefEq g tcref g.system_Int64_tcref && genericArgs.Length = 1 then g.pint64_tcr - elif tyconRefEq g tcref g.system_SByte_tcref && genericArgs.Length = 1 then g.pint8_tcr - else tcref - + let tcref = + if genericArgsLength = 1 then + // real + if tyconRefEq g tcref g.system_Double_tcref then g.pfloat_tcr + elif tyconRefEq g tcref g.system_Single_tcref then g.pfloat32_tcr + elif tyconRefEq g tcref g.system_Decimal_tcref then g.pdecimal_tcr + // signed + elif tyconRefEq g tcref g.system_Int16_tcref then g.pint16_tcr + elif tyconRefEq g tcref g.system_Int32_tcref then g.pint_tcr + elif tyconRefEq g tcref g.system_Int64_tcref then g.pint64_tcr + elif tyconRefEq g tcref g.system_SByte_tcref then g.pint8_tcr + // unsigned + elif tyconRefEq g tcref g.system_UInt16_tcref then g.puint16_tcr + elif tyconRefEq g tcref g.system_UInt32_tcref then g.puint_tcr + elif tyconRefEq g tcref g.system_UInt64_tcref then g.puint64_tcr + elif tyconRefEq g tcref g.system_Byte_tcref then g.puint8_tcr + //native + elif tyconRefEq g tcref g.system_IntPtr_tcref then g.pnativeint_tcr + elif tyconRefEq g tcref g.system_UIntPtr_tcref then g.punativeint_tcr + // other + else tcref + else + tcref + let tps = tcref.Typars m - if tps.Length <> genericArgs.Length then - error(Error(FSComp.SR.impInvalidNumberOfGenericArguments(tcref.CompiledName, tps.Length, genericArgs.Length), m)) + if tps.Length <> genericArgsLength then + error(Error(FSComp.SR.impInvalidNumberOfGenericArguments(tcref.CompiledName, tps.Length, genericArgsLength), m)) let genericArgs = (tps, genericArgs) ||> List.map2 (fun tp genericArg -> @@ -320,7 +343,7 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( /// Import a provided method reference as an Abstract IL method reference let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Tainted) = - let tref = ExtensionTyping.GetILTypeRefOfProvidedType (mbase.PApply((fun mbase -> mbase.DeclaringType), m), m) + let tref = GetILTypeRefOfProvidedType (mbase.PApply((fun mbase -> mbase.DeclaringType), m), m) let mbase = // Find the formal member corresponding to the called member @@ -341,7 +364,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta | None -> let methodName = minfo.PUntaint((fun minfo -> minfo.Name), m) let typeName = declaringGenericTypeDefn.PUntaint((fun declaringGenericTypeDefn -> declaringGenericTypeDefn.FullName), m) - error(NumberedError(FSComp.SR.etIncorrectProvidedMethod(ExtensionTyping.DisplayNameOfTypeProvider(minfo.TypeProvider, m), methodName, metadataToken, typeName), m)) + error(Error(FSComp.SR.etIncorrectProvidedMethod(DisplayNameOfTypeProvider(minfo.TypeProvider, m), methodName, metadataToken, typeName), m)) | _ -> match mbase.OfType() with | Some cinfo when cinfo.PUntaint((fun x -> x.DeclaringType.IsGenericType), m) -> @@ -367,7 +390,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta | Some found -> found.Coerce(m) | None -> let typeName = declaringGenericTypeDefn.PUntaint((fun x -> x.FullName), m) - error(NumberedError(FSComp.SR.etIncorrectProvidedConstructor(ExtensionTyping.DisplayNameOfTypeProvider(cinfo.TypeProvider, m), typeName), m)) + error(Error(FSComp.SR.etIncorrectProvidedConstructor(DisplayNameOfTypeProvider(cinfo.TypeProvider, m), typeName), m)) | _ -> mbase let rty = @@ -394,7 +417,6 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta // assembly on startup. //-------------------------------------------------------------------------- - /// Import a set of Abstract IL generic parameter specifications as a list of new /// F# generic parameters. /// @@ -405,7 +427,7 @@ let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) | [] -> [] | _ -> let amap = amap() - let tps = gps |> List.map (fun gp -> NewRigidTypar gp.Name m) + let tps = gps |> List.map (fun gp -> Construct.NewRigidTypar gp.Name m) let tptys = tps |> List.map mkTyparTy let importInst = tinst@tptys @@ -417,7 +439,6 @@ let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) tp.SetConstraints constraints) tps - /// Given a list of items each keyed by an ordered list of keys, apply 'nodef' to the each group /// with the same leading key. Apply 'tipf' to the elements where the keylist is empty, and return /// the overall results. Used to bucket types, so System.Char and System.Collections.Generic.List @@ -425,7 +446,7 @@ let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) = // Find all the items with an empty key list and call 'tipf' let tips = - [ for (keylist, v) in items do + [ for keylist, v in items do match keylist with | [] -> yield tipf v | _ -> () ] @@ -433,8 +454,8 @@ let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) = // Find all the items with a non-empty key list. Bucket them together by // the first key. For each bucket, call 'nodef' on that head key and the bucket. let nodes = - let buckets = new Dictionary<_, _>(10) - for (keylist, v) in items do + let buckets = Dictionary<_, _>(10) + for keylist, v in items do match keylist with | [] -> () | key :: rest -> @@ -443,10 +464,9 @@ let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) = | true, b -> (rest, v) :: b | _ -> (rest, v) :: [] - [ for (KeyValue(key, items)) in buckets -> nodef key items ] + [ for KeyValue(key, items) in buckets -> nodef key items ] tips @ nodes - /// Import an IL type definition as a new F# TAST Entity node. let rec ImportILTypeDef amap m scoref (cpath: CompilationPath) enc nm (tdef: ILTypeDef) = @@ -455,12 +475,12 @@ let rec ImportILTypeDef amap m scoref (cpath: CompilationPath) enc nm (tdef: ILT let cpath = cpath.NestedCompPath nm ModuleOrType ImportILTypeDefs amap m scoref cpath (enc@[tdef]) tdef.NestedTypes // Add the type itself. - NewILTycon + Construct.NewILTycon (Some cpath) (nm, m) // The read of the type parameters may fail to resolve types. We pick up a new range from the point where that read is forced // Make sure we reraise the original exception one occurs - see findOriginalException. - (LazyWithContext.Create((fun m -> ImportILGenericParameters amap m scoref [] tdef.GenericParams), ErrorLogger.findOriginalException)) + (LazyWithContext.Create((fun m -> ImportILGenericParameters amap m scoref [] tdef.GenericParams), findOriginalException)) (scoref, enc, tdef) (MaybeLazy.Lazy lazyModuleOrNamespaceTypeForNestedTypes) @@ -481,13 +501,13 @@ and ImportILTypeDefList amap m (cpath: CompilationPath) enc items = |> multisetDiscriminateAndMap (fun n tgs -> let modty = lazy (ImportILTypeDefList amap m (cpath.NestedCompPath n Namespace) enc tgs) - NewModuleOrNamespace (Some cpath) taccessPublic (mkSynId m n) XmlDoc.Empty [] (MaybeLazy.Lazy modty)) + Construct.NewModuleOrNamespace (Some cpath) taccessPublic (mkSynId m n) XmlDoc.Empty [] (MaybeLazy.Lazy modty)) (fun (n, info: Lazy<_>) -> let (scoref2, lazyTypeDef: ILPreTypeDef) = info.Force() ImportILTypeDef amap m scoref2 cpath enc n (lazyTypeDef.GetTypeDef())) let kind = match enc with [] -> Namespace | _ -> ModuleOrType - NewModuleOrNamespaceType kind entities [] + Construct.NewModuleOrNamespaceType kind entities [] /// Import a table of IL types as a ModuleOrNamespaceType. /// @@ -560,36 +580,42 @@ let ImportILAssemblyTypeForwarders (amap, m, exportedTypes: ILExportedTypesAndFo yield! nested net.Nested (enc @ [ net.Name ]) ] yield! nested exportedType.Nested (ns@[n]) ] |> Map.ofList - /// Import an IL assembly as a new TAST CCU -let ImportILAssembly(amap:(unit -> ImportMap), m, auxModuleLoader, ilScopeRef, sourceDir, filename, ilModule: ILModuleDef, invalidateCcu: IEvent) = - invalidateCcu |> ignore - let aref = - match ilScopeRef with - | ILScopeRef.Assembly aref -> aref - | _ -> error(InternalError("ImportILAssembly: cannot reference .NET netmodules directly, reference the containing assembly instead", m)) - let nm = aref.Name - let mty = ImportILAssemblyTypeDefs(amap, m, auxModuleLoader, aref, ilModule) - let ccuData : CcuData = - { IsFSharp=false - UsesFSharp20PlusQuotations=false +let ImportILAssembly(amap: unit -> ImportMap, m, auxModuleLoader, xmlDocInfoLoader: IXmlDocumentationInfoLoader option, ilScopeRef, sourceDir, filename, ilModule: ILModuleDef, invalidateCcu: IEvent) = + invalidateCcu |> ignore + let aref = + match ilScopeRef with + | ILScopeRef.Assembly aref -> aref + | _ -> error(InternalError("ImportILAssembly: cannot reference .NET netmodules directly, reference the containing assembly instead", m)) + let nm = aref.Name + let mty = ImportILAssemblyTypeDefs(amap, m, auxModuleLoader, aref, ilModule) + let forwarders = + match ilModule.Manifest with + | None -> Map.empty + | Some manifest -> ImportILAssemblyTypeForwarders(amap, m, manifest.ExportedTypes) + + let ccuData: CcuData = + { IsFSharp=false + UsesFSharp20PlusQuotations=false #if !NO_EXTENSIONTYPING - InvalidateEvent=invalidateCcu - IsProviderGenerated = false - ImportProvidedType = (fun ty -> ImportProvidedType (amap()) m ty) + InvalidateEvent=invalidateCcu + IsProviderGenerated = false + ImportProvidedType = (fun ty -> ImportProvidedType (amap()) m ty) #endif - QualifiedName= Some ilScopeRef.QualifiedName - Contents = NewCcuContents ilScopeRef m nm mty - ILScopeRef = ilScopeRef - Stamp = newStamp() - SourceCodeDirectory = sourceDir // note: not an accurate value, but IL assemblies don't give us this information in any attributes. - FileName = filename - MemberSignatureEquality= (fun ty1 ty2 -> Tastops.typeEquivAux EraseAll (amap()).g ty1 ty2) - TryGetILModuleDef = (fun () -> Some ilModule) - TypeForwarders = - (match ilModule.Manifest with - | None -> Map.empty - | Some manifest -> ImportILAssemblyTypeForwarders(amap, m, manifest.ExportedTypes)) } + QualifiedName= Some ilScopeRef.QualifiedName + Contents = Construct.NewCcuContents ilScopeRef m nm mty + ILScopeRef = ilScopeRef + Stamp = newStamp() + SourceCodeDirectory = sourceDir // note: not an accurate value, but IL assemblies don't give us this information in any attributes. + FileName = filename + MemberSignatureEquality= (fun ty1 ty2 -> typeEquivAux EraseAll (amap()).g ty1 ty2) + TryGetILModuleDef = (fun () -> Some ilModule) + TypeForwarders = forwarders + XmlDocumentationInfo = + match xmlDocInfoLoader, filename with + | Some xmlDocInfoLoader, Some filename -> xmlDocInfoLoader.TryLoad(filename, ilModule) + | _ -> None + } - CcuThunk.Create(nm, ccuData) + CcuThunk.Create(nm, ccuData) diff --git a/src/fsharp/import.fsi b/src/fsharp/import.fsi index 1070bd302ae..5d21ea6bfb2 100644 --- a/src/fsharp/import.fsi +++ b/src/fsharp/import.fsi @@ -3,17 +3,17 @@ /// Functions to import .NET binary metadata as TAST objects module internal FSharp.Compiler.Import -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Range +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree + #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping #endif - - /// Represents an interface to some of the functionality of TcImports, for loading assemblies /// and accessing information about generated provided assemblies. type AssemblyLoader = @@ -21,6 +21,8 @@ type AssemblyLoader = /// Resolve an Abstract IL assembly reference to a Ccu abstract FindCcuFromAssemblyRef : CompilationThreadToken * range * ILAssemblyRef -> CcuResolutionResult + abstract TryFindXmlDocumentationInfo : assemblyName: string -> XmlDocumentationInfo option + #if !NO_EXTENSIONTYPING /// Get a flag indicating if an assembly is a provided assembly, plus the /// table of information recording remappings from type names in the provided assembly to type @@ -31,14 +33,13 @@ type AssemblyLoader = abstract RecordGeneratedTypeRoot : ProviderGeneratedType -> unit #endif - /// Represents a context used for converting AbstractIL .NET and provided types to F# internal compiler data structures. /// Also cache the conversion of AbstractIL ILTypeRef nodes, based on hashes of these. /// /// There is normally only one ImportMap for any assembly compilation, though additional instances can be created /// using tcImports.GetImportMap() if needed, and it is not harmful if multiple instances are used. The object /// serves as an interface through to the tables stored in the primary TcImports structures defined in CompileOps.fs. -[] +[] type ImportMap = new : g:TcGlobals * assemblyLoader:AssemblyLoader -> ImportMap @@ -61,7 +62,6 @@ val internal ImportILType : ImportMap -> range -> TType list -> ILType -> TType val internal CanImportILType : ImportMap -> range -> ILType -> bool #if !NO_EXTENSIONTYPING - /// Import a provided type as an F# type. val internal ImportProvidedType : ImportMap -> range -> (* TType list -> *) Tainted -> TType @@ -79,7 +79,7 @@ val internal ImportProvidedMethodBaseAsILMethodRef : ImportMap -> range -> Taint val internal ImportILGenericParameters : (unit -> ImportMap) -> range -> ILScopeRef -> TType list -> ILGenericParameterDef list -> Typar list /// Import an IL assembly as a new TAST CCU -val internal ImportILAssembly : (unit -> ImportMap) * range * (ILScopeRef -> ILModuleDef) * ILScopeRef * sourceDir:string * filename: string option * ILModuleDef * IEvent -> CcuThunk +val internal ImportILAssembly : (unit -> ImportMap) * range * (ILScopeRef -> ILModuleDef) * IXmlDocumentationInfoLoader option * ILScopeRef * sourceDir:string * filename: string option * ILModuleDef * IEvent -> CcuThunk /// Import the type forwarder table for an IL assembly -val internal ImportILAssemblyTypeForwarders : (unit -> ImportMap) * range * ILExportedTypesAndForwarders -> Map<(string array * string), Lazy> +val internal ImportILAssemblyTypeForwarders : (unit -> ImportMap) * range * ILExportedTypesAndForwarders -> Map> diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 83d7ab4c358..3c60e70ddbd 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -2,19 +2,21 @@ module internal FSharp.Compiler.Infos -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open System +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.Tastops.DebugPrint +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib -open Microsoft.FSharp.Core.Printf +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TypedTreeOps.DebugPrint #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping @@ -38,13 +40,18 @@ let CanImportILType scoref amap m ilty = /// Indicates if an F# type is the type associated with an F# exception declaration let isExnDeclTy g ty = - isAppTy g ty && (tcrefOfAppTy g ty).IsExceptionDecl + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> tcref.IsExceptionDecl + | _ -> false /// Get the base type of a type, taking into account type instantiations. Return None if the /// type has no base type. let GetSuperTypeOfType g amap m ty = #if !NO_EXTENSIONTYPING - let ty = (if isAppTy g ty && (tcrefOfAppTy g ty).IsProvided then stripTyEqns g ty else stripTyEqnsAndMeasureEqns g ty) + let ty = + match tryTcrefOfAppTy g ty with + | ValueSome tcref when tcref.IsProvided -> stripTyEqns g ty + | _ -> stripTyEqnsAndMeasureEqns g ty #else let ty = stripTyEqnsAndMeasureEqns g ty #endif @@ -73,12 +80,14 @@ let GetSuperTypeOfType g amap m ty = elif isRefTy g ty && not (isObjTy g ty) then Some g.obj_ty elif isStructTupleTy g ty then - Some g.obj_ty + Some g.system_Value_ty elif isFSharpStructOrEnumTy g ty then if isFSharpEnumTy g ty then Some g.system_Enum_ty else Some g.system_Value_ty + elif isStructAnonRecdTy g ty then + Some g.system_Value_ty elif isAnonRecdTy g ty then Some g.obj_ty elif isRecdTy g ty || isUnionTy g ty then @@ -93,10 +102,33 @@ let mkSystemCollectionsGenericIListTy (g: TcGlobals) ty = TType_app(g.tcref_Syst /// Indicates whether we can skip interface types that lie outside the reference set type SkipUnrefInterfaces = Yes | No - /// Collect the set of immediate declared interface types for an F# type, but do not /// traverse the type hierarchy to collect further interfaces. let rec GetImmediateInterfacesOfType skipUnref g amap m ty = + + let getInterfaces ty (tcref:TyconRef) tinst = + match metadataOfTy g ty with +#if !NO_EXTENSIONTYPING + | ProvidedTypeMetadata info -> + [ for ity in info.ProvidedType.PApplyArray((fun st -> st.GetInterfaces()), "GetInterfaces", m) do + yield Import.ImportProvidedType amap m ity ] +#endif + | ILTypeMetadata (TILObjectReprData(scoref, _, tdef)) -> + // ImportILType may fail for an interface if the assembly load set is incomplete and the interface + // comes from another assembly. In this case we simply skip the interface: + // if we don't skip it, then compilation will just fail here, and if type checking + // succeeds with fewer non-dereferencable interfaces reported then it would have + // succeeded with more reported. There are pathological corner cases where this + // doesn't apply: e.g. for mscorlib interfaces like IComparable, but we can always + // assume those are present. + tdef.Implements |> List.choose (fun ity -> + if skipUnref = SkipUnrefInterfaces.No || CanImportILType scoref amap m ity then + Some (ImportILType scoref amap m tinst ity) + else + None) + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> + tcref.ImmediateInterfaceTypesOfFSharpTycon |> List.map (instType (mkInstForAppTy g ty)) + let itys = match tryAppTy g ty with | ValueSome(tcref, tinst) -> @@ -104,38 +136,34 @@ let rec GetImmediateInterfacesOfType skipUnref g amap m ty = [ match tcref.TypeReprInfo with | TMeasureableRepr reprTy -> for ity in GetImmediateInterfacesOfType skipUnref g amap m reprTy do - if isAppTy g ity then - let itcref = tcrefOfAppTy g ity + match tryTcrefOfAppTy g ity with + | ValueNone -> () + | ValueSome itcref -> if not (tyconRefEq g itcref g.system_GenericIComparable_tcref) && - not (tyconRefEq g itcref g.system_GenericIEquatable_tcref) then + not (tyconRefEq g itcref g.system_GenericIEquatable_tcref) then yield ity | _ -> () yield mkAppTy g.system_GenericIComparable_tcref [ty] yield mkAppTy g.system_GenericIEquatable_tcref [ty]] else - match metadataOfTy g ty with -#if !NO_EXTENSIONTYPING - | ProvidedTypeMetadata info -> - [ for ity in info.ProvidedType.PApplyArray((fun st -> st.GetInterfaces()), "GetInterfaces", m) do - yield Import.ImportProvidedType amap m ity ] -#endif - | ILTypeMetadata (TILObjectReprData(scoref, _, tdef)) -> - - // ImportILType may fail for an interface if the assembly load set is incomplete and the interface - // comes from another assembly. In this case we simply skip the interface: - // if we don't skip it, then compilation will just fail here, and if type checking - // succeeds with fewer non-dereferencable interfaces reported then it would have - // succeeded with more reported. There are pathological corner cases where this - // doesn't apply: e.g. for mscorlib interfaces like IComparable, but we can always - // assume those are present. - tdef.Implements |> List.choose (fun ity -> - if skipUnref = SkipUnrefInterfaces.No || CanImportILType scoref amap m ity then - Some (ImportILType scoref amap m tinst ity) - else None) - - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - tcref.ImmediateInterfaceTypesOfFSharpTycon |> List.map (instType (mkInstForAppTy g ty)) - | _ -> [] + getInterfaces ty tcref tinst + | _ -> + let tyWithMetadata = convertToTypeWithMetadataIfPossible g ty + match tryAppTy g tyWithMetadata with + | ValueSome (tcref, tinst) -> + if isAnyTupleTy g ty then + getInterfaces tyWithMetadata tcref tinst + else + [] + | _ -> [] + + // NOTE: Anonymous record types are not directly considered to implement IComparable, + // IComparable or IEquatable. This is because whether they support these interfaces depend on their + // consitutent types, which may not yet be known in type inference. + // + // NOTE: Tuples could in theory always support IComparable etc. because this + // is in the .NET metadata for System.Tuple etc. However from the F# perspective tuple types don't + // always support the 'comparable' and 'equality' constraints (again, it depends on their constitutent types). // .NET array types are considered to implement IList let itys = @@ -143,18 +171,22 @@ let rec GetImmediateInterfacesOfType skipUnref g amap m ty = mkSystemCollectionsGenericIListTy g (destArrayTy g ty) :: itys else itys + itys -[] /// Indicates whether we should visit multiple instantiations of the same generic interface or not +[] type AllowMultiIntfInstantiations = Yes | No /// Traverse the type hierarchy, e.g. f D (f C (f System.Object acc)). /// Visit base types and interfaces first. let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref visitor g amap m ty acc = - let rec loop ndeep ty ((visitedTycon, visited: TyconRefMultiMap<_>, acc) as state) = + let rec loop ndeep ty (visitedTycon, visited: TyconRefMultiMap<_>, acc as state) = - let seenThisTycon = isAppTy g ty && Set.contains (tcrefOfAppTy g ty).Stamp visitedTycon + let seenThisTycon = + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> Set.contains tcref.Stamp visitedTycon + | _ -> false // Do not visit the same type twice. Could only be doing this if we've seen this tycon if seenThisTycon && List.exists (typeEquiv g ty) (visited.Find (tcrefOfAppTy g ty)) then state else @@ -163,11 +195,11 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref if seenThisTycon && allowMultiIntfInst = AllowMultiIntfInstantiations.No then state else let state = - if isAppTy g ty then - let tcref = tcrefOfAppTy g ty + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> let visitedTycon = Set.add tcref.Stamp visitedTycon visitedTycon, visited.Add (tcref, ty), acc - else + | _ -> state if ndeep > 100 then (errorR(Error((FSComp.SR.recursiveClassHierarchy (showType ty)), m)); (visitedTycon, visited, acc)) else @@ -254,14 +286,18 @@ let AllInterfacesOfType g amap m allowMultiIntfInst ty = /// Check if two types have the same nominal head type let HaveSameHeadType g ty1 ty2 = - isAppTy g ty1 && isAppTy g ty2 && - tyconRefEq g (tcrefOfAppTy g ty1) (tcrefOfAppTy g ty2) + match tryTcrefOfAppTy g ty1 with + | ValueSome tcref1 -> + match tryTcrefOfAppTy g ty2 with + | ValueSome tcref2 -> tyconRefEq g tcref1 tcref2 + | _ -> false + | _ -> false /// Check if a type has a particular head type let HasHeadType g tcref ty2 = - isAppTy g ty2 && - tyconRefEq g tcref (tcrefOfAppTy g ty2) - + match tryTcrefOfAppTy g ty2 with + | ValueSome tcref2 -> tyconRefEq g tcref tcref2 + | ValueNone -> false /// Check if a type exists somewhere in the hierarchy which has the same head type as the given type (note, the given type need not have a head type at all) let ExistsSameHeadTypeInHierarchy g amap m typeToSearchFrom typeToLookFor = @@ -271,7 +307,6 @@ let ExistsSameHeadTypeInHierarchy g amap m typeToSearchFrom typeToLookFor = let ExistsHeadTypeInEntireHierarchy g amap m typeToSearchFrom tcrefToLookFor = ExistsInEntireHierarchyOfType (HasHeadType g tcrefToLookFor) g amap m AllowMultiIntfInstantiations.Yes typeToSearchFrom - /// Read an Abstract IL type from metadata and convert to an F# type. let ImportILTypeFromMetadata amap m scoref tinst minst ilty = ImportILType scoref amap m (tinst@minst) ilty @@ -357,7 +392,6 @@ let FixupNewTypars m (formalEnclosingTypars: Typars) (tinst: TType list) (tpsori //------------------------------------------------------------------------- // Predicates and properties on values and members - type ValRef with /// Indicates if an F#-declared function or member value is a CLIEvent property compiled as a .NET event member x.IsFSharpEventProperty g = @@ -422,21 +456,19 @@ let ReparentSlotSigToUseMethodTypars g m ovByMethValRef slotsig = // Note: it appears PartitionValRefTypars should never return 'None' slotsig - /// Construct the data representing a parameter in the signature of an abstract method slot let MakeSlotParam (ty, argInfo: ArgReprInfo) = TSlotParam(Option.map textOfId argInfo.Name, ty, false, false, false, argInfo.Attribs) /// Construct the data representing the signature of an abstract method slot let MakeSlotSig (nm, ty, ctps, mtps, paraml, retTy) = copySlotSig (TSlotSig(nm, ty, ctps, mtps, paraml, retTy)) - /// Split the type of an F# member value into /// - the type parameters associated with method but matching those of the enclosing type /// - the type parameters associated with a generic method /// - the return type of the method /// - the actual type arguments of the enclosing type. let private AnalyzeTypeOfMemberVal isCSharpExt g (ty, vref: ValRef) = - let memberAllTypars, _, retTy, _ = GetTypeOfMemberInMemberForm g vref + let memberAllTypars, _, _, retTy, _ = GetTypeOfMemberInMemberForm g vref if isCSharpExt || vref.IsExtensionMember then [], memberAllTypars, retTy, [] else @@ -446,13 +478,15 @@ let private AnalyzeTypeOfMemberVal isCSharpExt g (ty, vref: ValRef) = /// Get the object type for a member value which is an extension method (C#-style or F#-style) let private GetObjTypeOfInstanceExtensionMethod g (vref: ValRef) = - let _, curriedArgInfos, _, _ = GetTopValTypeInCompiledForm g vref.ValReprInfo.Value vref.Type vref.Range + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let _, _, curriedArgInfos, _, _ = GetTopValTypeInCompiledForm g vref.ValReprInfo.Value numEnclosingTypars vref.Type vref.Range curriedArgInfos.Head.Head |> fst -/// Get the object type for a member value which is a C#-style extension method +/// Get the object type for a member value, which might be a C#-style extension method let private GetArgInfosOfMember isCSharpExt g (vref: ValRef) = if isCSharpExt then - let _, curriedArgInfos, _, _ = GetTopValTypeInCompiledForm g vref.ValReprInfo.Value vref.Type vref.Range + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let _, _, curriedArgInfos, _, _ = GetTopValTypeInCompiledForm g vref.ValReprInfo.Value numEnclosingTypars vref.Type vref.Range [ curriedArgInfos.Head.Tail ] else ArgInfosOfMember g vref @@ -490,7 +524,7 @@ type ExtensionMethodPriority = uint64 /// The caller-side value for the optional arg, if any type OptionalArgCallerSideValue = - | Constant of IL.ILFieldInit + | Constant of ILFieldInit | DefaultValue | MissingValue | WrapperForIDispatch @@ -501,8 +535,10 @@ type OptionalArgCallerSideValue = type OptionalArgInfo = /// The argument is not optional | NotOptional + /// The argument is optional, and is an F# callee-side optional arg | CalleeSide + /// The argument is optional, and is a caller-side .NET optional or default arg. /// Note this is correctly termed caller side, even though the default value is optically specified on the callee: /// in fact the default value is read from the metadata and passed explicitly to the callee on the caller side. @@ -540,7 +576,7 @@ type OptionalArgInfo = static member ValueOfDefaultParameterValueAttrib (Attrib (_, _, exprs, _, _, _, _)) = let (AttribExpr (_, defaultValueExpr)) = List.head exprs match defaultValueExpr with - | Expr.Const (_, _, _) -> Some defaultValueExpr + | Expr.Const _ -> Some defaultValueExpr | _ -> None static member FieldInitForDefaultParameterValueAttrib attrib = match OptionalArgInfo.ValueOfDefaultParameterValueAttrib attrib with @@ -577,11 +613,15 @@ type ParamNameAndType = [] /// Full information about a parameter returned for use by the type checker and language service. type ParamData = - ParamData of isParamArray: bool * isInArg: bool * isOut: bool * optArgInfo: OptionalArgInfo * callerInfo: CallerInfo * nameOpt: Ident option * reflArgInfo: ReflectedArgInfo * ttype: TType - - -//------------------------------------------------------------------------- -// Helper methods associated with type providers + ParamData of + isParamArray: bool * + isInArg: bool * + isOut: bool * + optArgInfo: OptionalArgInfo * + callerInfo: CallerInfo * + nameOpt: Ident option * + reflArgInfo: ReflectedArgInfo * + ttype: TType #if !NO_EXTENSIONTYPING @@ -654,9 +694,6 @@ let ArbitraryMethodInfoOfPropertyInfo (pi: Tainted) m = #endif -//------------------------------------------------------------------------- -// ILTypeInfo - /// Describes an F# use of an IL type, including the type instantiation associated with the type at a particular usage point. /// /// This is really just 1:1 with the subset ot TType which result from building types using IL type definitions. @@ -708,20 +745,14 @@ type ILTypeInfo = else failwith "ILTypeInfo.FromType - no IL metadata for type" -//------------------------------------------------------------------------- -// ILMethInfo - - /// Describes an F# use of an IL method. [] type ILMethInfo = - /// ILMethInfo(g, ilApparentType, ilDeclaringTyconRefOpt, ilMethodDef, ilGenericMethodTyArgs) - /// /// Describes an F# use of an IL method. /// /// If ilDeclaringTyconRefOpt is 'Some' then this is an F# use of an C#-style extension method. /// If ilDeclaringTyconRefOpt is 'None' then ilApparentType is an IL type definition. - | ILMethInfo of TcGlobals * TType * TyconRef option * ILMethodDef * Typars + | ILMethInfo of g: TcGlobals * ilApparentType: TType * ilDeclaringTyconRefOpt: TyconRef option * ilMethodDef: ILMethodDef * ilGenericMethodTyArgs: Typars member x.TcGlobals = match x with ILMethInfo(g, _, _, _, _) -> g @@ -866,32 +897,23 @@ type ILMethInfo = x.GetCompiledReturnTy(amap, m, minst) |> GetFSharpViewOfReturnType amap.g -//------------------------------------------------------------------------- -// MethInfo - -#if DEBUG -[] -#endif /// Describes an F# use of a method +[] [] type MethInfo = - /// FSMeth(tcGlobals, enclosingType, valRef, extensionMethodPriority). - /// /// Describes a use of a method declared in F# code and backed by F# metadata. - | FSMeth of TcGlobals * TType * ValRef * ExtensionMethodPriority option + | FSMeth of tcGlobals: TcGlobals * enclosingType: TType * valRef: ValRef * extensionMethodPriority: ExtensionMethodPriority option - /// ILMeth(tcGlobals, ilMethInfo, extensionMethodPriority). - /// /// Describes a use of a method backed by Abstract IL # metadata - | ILMeth of TcGlobals * ILMethInfo * ExtensionMethodPriority option + | ILMeth of tcGlobals: TcGlobals * ilMethInfo: ILMethInfo * extensionMethodPriority: ExtensionMethodPriority option /// Describes a use of a pseudo-method corresponding to the default constructor for a .NET struct type - | DefaultStructCtor of TcGlobals * TType + | DefaultStructCtor of tcGlobals: TcGlobals * structTy: TType #if !NO_EXTENSIONTYPING /// Describes a use of a method backed by provided metadata - | ProvidedMeth of Import.ImportMap * Tainted * ExtensionMethodPriority option * range + | ProvidedMeth of amap: Import.ImportMap * methodBase: Tainted * extensionMethodPriority: ExtensionMethodPriority option * m: range #endif /// Get the enclosing type of the method info. @@ -939,7 +961,6 @@ type MethInfo = #endif | DefaultStructCtor _ -> None - /// Get the extension method priority of the method, if it has one. member x.ExtensionMemberPriorityOption = match x with @@ -950,13 +971,12 @@ type MethInfo = #endif | DefaultStructCtor _ -> None - /// Get the extension method priority of the method. If it is not an extension method - /// then use the highest possible value since non-extension methods always take priority - /// over extension members. - member x.ExtensionMemberPriority = defaultArg x.ExtensionMemberPriorityOption System.UInt64.MaxValue + /// Get the extension method priority of the method. If it is not an extension method + /// then use the highest possible value since non-extension methods always take priority + /// over extension members. + member x.ExtensionMemberPriority = defaultArg x.ExtensionMemberPriorityOption UInt64.MaxValue -#if DEBUG - /// Get the method name in DebuggerDisplayForm + /// Get the method name in DebuggerDisplayForm member x.DebuggerDisplayName = match x with | ILMeth(_, y, _) -> "ILMeth: " + y.ILName @@ -965,9 +985,8 @@ type MethInfo = | ProvidedMeth(_, mi, _, m) -> "ProvidedMeth: " + mi.PUntaint((fun mi -> mi.Name), m) #endif | DefaultStructCtor _ -> ".ctor" -#endif - /// Get the method name in LogicalName form, i.e. the name as it would be stored in .NET metadata + /// Get the method name in LogicalName form, i.e. the name as it would be stored in .NET metadata member x.LogicalName = match x with | ILMeth(_, y, _) -> y.ILName @@ -981,7 +1000,13 @@ type MethInfo = member x.DisplayName = match x with | FSMeth(_, _, vref, _) -> vref.DisplayName - | _ -> x.LogicalName + | _ -> x.LogicalName |> PrettyNaming.ConvertValNameToDisplayName false + + /// Get the method name in DisplayName form + member x.DisplayNameCore = + match x with + | FSMeth(_, _, vref, _) -> vref.DisplayNameCore + | _ -> x.LogicalName |> PrettyNaming.DecompileOpName /// Indicates if this is a method defined in this assembly with an internal XML comment member x.HasDirectXmlComment = @@ -1025,20 +1050,21 @@ type MethInfo = | ProvidedMeth _ -> [] // There will already have been an error if there are generic parameters here. #endif - /// Get the formal generic method parameters for the method as a list of variable types. + /// Get the formal generic method parameters for the method as a list of variable types. member x.FormalMethodInst = generalizeTypars x.FormalMethodTypars member x.FormalMethodTyparInst = mkTyparInst x.FormalMethodTypars x.FormalMethodInst - /// Get the XML documentation associated with the method + /// Get the XML documentation associated with the method member x.XmlDoc = match x with - | ILMeth(_, _, _) -> XmlDoc.Empty + | ILMeth _ -> XmlDoc.Empty | FSMeth(_, _, vref, _) -> vref.XmlDoc | DefaultStructCtor _ -> XmlDoc.Empty #if !NO_EXTENSIONTYPING | ProvidedMeth(_, mi, _, m)-> - XmlDoc (mi.PUntaint((fun mix -> (mix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(mi.TypeProvider.PUntaintNoFailure id)), m)) + let lines = mi.PUntaint((fun mix -> (mix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(mi.TypeProvider.PUntaintNoFailure id)), m) + XmlDoc (lines, m) #endif /// Try to get an arbitrary F# ValRef associated with the member. This is to determine if the member is virtual, amongst other things. @@ -1071,7 +1097,6 @@ type MethInfo = | ProvidedMeth(_, mi, _, m) -> mi.PUntaint((fun mi -> not mi.IsConstructor && not mi.IsStatic), m) #endif - /// Get the number of generic method parameters for a method. /// For an extension method this includes all type parameters, even if it is extending a generic type. member x.GenericArity = x.FormalMethodTypars.Length @@ -1097,7 +1122,7 @@ type MethInfo = member x.IsConstructor = match x with | ILMeth(_, ilmeth, _) -> ilmeth.IsConstructor - | FSMeth(_g, _, vref, _) -> (vref.MemberInfo.Value.MemberFlags.MemberKind = MemberKind.Constructor) + | FSMeth(_g, _, vref, _) -> (vref.MemberInfo.Value.MemberFlags.MemberKind = SynMemberKind.Constructor) | DefaultStructCtor _ -> true #if !NO_EXTENSIONTYPING | ProvidedMeth(_, mi, _, m) -> mi.PUntaint((fun mi -> mi.IsConstructor), m) @@ -1153,16 +1178,21 @@ type MethInfo = #endif member x.IsNewSlot = - isInterfaceTy x.TcGlobals x.ApparentEnclosingType || (x.IsVirtual && (match x with - | ILMeth(_, x, _) -> x.IsNewSlot + | ILMeth(_, x, _) -> x.IsNewSlot || (isInterfaceTy x.TcGlobals x.ApparentEnclosingType && not x.IsFinal) | FSMeth(_, _, vref, _) -> vref.IsDispatchSlotMember #if !NO_EXTENSIONTYPING | ProvidedMeth(_, mi, _, m) -> mi.PUntaint((fun mi -> mi.IsHideBySig), m) // REVIEW: Check this is correct #endif | DefaultStructCtor _ -> false)) + /// Indicates if this is an IL method. + member x.IsILMethod = + match x with + | ILMeth _ -> true + | _ -> false + /// Check if this method is an explicit implementation of an interface member member x.IsFSharpExplicitInterfaceImplementation = match x with @@ -1384,7 +1414,7 @@ type MethInfo = [ [ for p in ilMethInfo.ParamMetadata do let isParamArrayArg = TryFindILAttribute g.attrib_ParamArrayAttribute p.CustomAttrs let reflArgInfo = - match TryDecodeILAttribute g g.attrib_ReflectedDefinitionAttribute.TypeRef p.CustomAttrs with + match TryDecodeILAttribute g.attrib_ReflectedDefinitionAttribute.TypeRef p.CustomAttrs with | Some ([ILAttribElem.Bool b ], _) -> ReflectedArgInfo.Quote b | Some _ -> ReflectedArgInfo.Quote false | _ -> ReflectedArgInfo.None @@ -1441,7 +1471,7 @@ type MethInfo = // Emit a warning, and ignore the DefaultParameterValue argument altogether. warning(Error(FSComp.SR.DefaultParameterValueNotAppropriateForArgument(), m)) NotOptional - | Some (Expr.Const ((ConstToILFieldInit fi), _, _)) -> + | Some (Expr.Const (ConstToILFieldInit fi, _, _)) -> // Good case - all is well. CallerSide (Constant fi) | _ -> @@ -1482,10 +1512,10 @@ type MethInfo = | ProvidedMeth(amap, mi, _, _) -> // A single group of tupled arguments [ [for p in mi.PApplyArray((fun mi -> mi.GetParameters()), "GetParameters", m) do - let isParamArrayArg = p.PUntaint((fun px -> (px :> IProvidedCustomAttributeProvider).GetAttributeConstructorArgs(p.TypeProvider.PUntaintNoFailure id, typeof.FullName).IsSome), m) + let isParamArrayArg = p.PUntaint((fun px -> (px :> IProvidedCustomAttributeProvider).GetAttributeConstructorArgs(p.TypeProvider.PUntaintNoFailure id, typeof.FullName).IsSome), m) let optArgInfo = OptionalArgInfoOfProvidedParameter amap m p let reflArgInfo = - match p.PUntaint((fun px -> (px :> IProvidedCustomAttributeProvider).GetAttributeConstructorArgs(p.TypeProvider.PUntaintNoFailure id, typeof.FullName)), m) with + match p.PUntaint((fun px -> (px :> IProvidedCustomAttributeProvider).GetAttributeConstructorArgs(p.TypeProvider.PUntaintNoFailure id, typeof.FullName)), m) with | Some ([ Some (:? bool as b) ], _) -> ReflectedArgInfo.Quote b | Some _ -> ReflectedArgInfo.Quote false | None -> ReflectedArgInfo.None @@ -1494,8 +1524,6 @@ type MethInfo = yield (isParamArrayArg, isInArg, isOutArg, optArgInfo, NoCallerInfo, reflArgInfo)] ] #endif - - /// Get the signature of an abstract method slot. // // This code has grown organically over time. We've managed to unify the ILMeth+ProvidedMeth paths. @@ -1507,7 +1535,8 @@ type MethInfo = | ValInRecScope false -> error(Error((FSComp.SR.InvalidRecursiveReferenceToAbstractSlot()), m)) | _ -> () - let allTyparsFromMethod, _, retTy, _ = GetTypeOfMemberInMemberForm g vref + let allTyparsFromMethod, _, _, retTy, _ = GetTypeOfMemberInMemberForm g vref + // A slot signature is w.r.t. the type variables of the type it is associated with. // So we have to rename from the member type variables to the type variables of the type. let formalEnclosingTypars = x.ApparentEnclosingTyconRef.Typars m @@ -1540,7 +1569,7 @@ type MethInfo = let formalRetTy = ImportReturnTypeFromMetadata amap m ilminfo.RawMetadata.Return.Type ilminfo.RawMetadata.Return.CustomAttrs ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys let formalParams = [ [ for p in ilminfo.RawMetadata.Parameters do - let paramType = ImportILTypeFromMetadata amap m ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys p.Type + let paramType = ImportILTypeFromMetadataWithAttributes amap m ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys p.Type p.CustomAttrs yield TSlotParam(p.Name, paramType, p.IsIn, p.IsOut, p.IsOptional, []) ] ] formalRetTy, formalParams #if !NO_EXTENSIONTYPING @@ -1598,7 +1627,6 @@ type MethInfo = member x.HasParamArrayArg(amap, m, minst) = x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _, _, _, _, _, _, _)) -> isParamArrayArg) - /// Select all the type parameters of the declaring type of a method. /// /// For extension methods, no type parameters are returned, because all the @@ -1623,18 +1651,14 @@ type MethInfo = if isByrefTy x.TcGlobals ty then Some ty else None) -//------------------------------------------------------------------------- -// ILFieldInfo - - /// Represents a single use of a IL or provided field from one point in an F# program [] type ILFieldInfo = /// Represents a single use of a field backed by Abstract IL metadata - | ILFieldInfo of ILTypeInfo * ILFieldDef // .NET IL fields + | ILFieldInfo of ilTypeInfo: ILTypeInfo * ilFieldDef: ILFieldDef #if !NO_EXTENSIONTYPING /// Represents a single use of a field backed by provided metadata - | ProvidedField of Import.ImportMap * Tainted * range + | ProvidedField of amap: Import.ImportMap * providedField: Tainted * range: range #endif /// Get the enclosing ("parent"/"declaring") type of the field. @@ -1766,7 +1790,7 @@ type ILFieldInfo = /// Describes an F# use of a field in an F#-declared record, class or struct type [] type RecdFieldInfo = - | RecdFieldInfo of TypeInst * Tast.RecdFieldRef + | RecdFieldInfo of typeInst: TypeInst * recdFieldRef: RecdFieldRef /// Get the generic instantiation of the declaring type of the field member x.TypeInst = let (RecdFieldInfo(tinst, _)) = x in tinst @@ -1789,21 +1813,25 @@ type RecdFieldInfo = /// Get the F# metadata for the F#-declared record, class or struct type member x.Tycon = x.RecdFieldRef.Tycon - /// Get the name of the field in an F#-declared record, class or struct type - member x.Name = x.RecdField.Name + /// Get the logical name of the field in an F#-declared record, class or struct type + member x.LogicalName = x.RecdField.LogicalName + + member x.DisplayNameCore = x.RecdField.DisplayNameCore + + member x.DisplayName = x.RecdField.DisplayName /// Get the (instantiated) type of the field in an F#-declared record, class or struct type member x.FieldType = actualTyOfRecdFieldRef x.RecdFieldRef x.TypeInst /// Get the enclosing (declaring) type of the field in an F#-declared record, class or struct type member x.DeclaringType = TType_app (x.RecdFieldRef.TyconRef, x.TypeInst) - override x.ToString() = x.TyconRef.ToString() + "::" + x.Name + override x.ToString() = x.TyconRef.ToString() + "::" + x.LogicalName /// Describes an F# use of a union case [] type UnionCaseInfo = - | UnionCaseInfo of TypeInst * Tast.UnionCaseRef + | UnionCaseInfo of typeInst: TypeInst * unionCaseRef: UnionCaseRef /// Get the list of types for the instantiation of the type parameters of the declaring type of the union case member x.TypeInst = let (UnionCaseInfo(tinst, _)) = x in tinst @@ -1820,19 +1848,32 @@ type UnionCaseInfo = /// Get the F# metadata for the declaring union type member x.Tycon = x.UnionCaseRef.Tycon - /// Get the name of the union case - member x.Name = x.UnionCase.DisplayName + /// Get the logical name of the union case. + member x.LogicalName = x.UnionCase.LogicalName + + /// Get the core of the display name of the union case + /// + /// Backticks and parens are not added for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become [] and :: respectively. + member x.DisplayNameCore = x.UnionCase.DisplayNameCore + + /// Get the display name of the union case + /// + /// Backticks and parens are added implicitly for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively. + member x.DisplayName = x.UnionCase.DisplayName /// Get the instantiation of the type parameters of the declaring type of the union case member x.GetTyparInst m = mkTyparInst (x.TyconRef.Typars m) x.TypeInst - override x.ToString() = x.TyconRef.ToString() + "::" + x.Name - + override x.ToString() = x.TyconRef.ToString() + "::" + x.DisplayNameCore /// Describes an F# use of a property backed by Abstract IL metadata [] type ILPropInfo = - | ILPropInfo of ILTypeInfo * ILPropertyDef + | ILPropInfo of ilTypeInfo: ILTypeInfo * ilPropertyDef: ILPropertyDef /// Get the TcGlobals governing this value member x.TcGlobals = match x with ILPropInfo(tinfo, _) -> tinfo.TcGlobals @@ -1908,18 +1949,18 @@ type ILPropInfo = override x.ToString() = x.ILTypeInfo.ToString() + "::" + x.PropertyName - - /// Describes an F# use of a property [] type PropInfo = /// An F# use of a property backed by F#-declared metadata - | FSProp of TcGlobals * TType * ValRef option * ValRef option + | FSProp of tcGlobals: TcGlobals * apparentEnclTy: TType * getter: ValRef option * setter: ValRef option + /// An F# use of a property backed by Abstract IL metadata - | ILProp of ILPropInfo + | ILProp of ilPropInfo: ILPropInfo + #if !NO_EXTENSIONTYPING /// An F# use of a property backed by provided metadata - | ProvidedProp of Import.ImportMap * Tainted * range + | ProvidedProp of amap: Import.ImportMap * providedProp: Tainted * range: range #endif /// Get the enclosing type of the property. @@ -1998,7 +2039,6 @@ type PropInfo = | ProvidedProp(_, pi, m) -> pi.PUntaint((fun pi -> pi.CanWrite), m) #endif - /// Indicates if this is an extension member member x.IsExtensionMember = match x.ArbitraryValRef with @@ -2032,7 +2072,6 @@ type PropInfo = mi.PUntaint((fun mi -> mi.IsHideBySig), m) #endif - /// Indicates if the getter (or, if absent, the setter) for the property is a dispatch slot. // REVIEW: for IL properties this is getter OR setter. For F# properties it is getter ELSE setter member x.IsDispatchSlot = @@ -2040,7 +2079,7 @@ type PropInfo = | ILProp ilpinfo -> ilpinfo.IsVirtual | FSProp(g, ty, Some vref, _) | FSProp(g, ty, _, Some vref) -> - isInterfaceTy g ty || (vref.MemberInfo.Value.MemberFlags.IsDispatchSlot) + isInterfaceTy g ty || vref.MemberInfo.Value.MemberFlags.IsDispatchSlot | FSProp _ -> failwith "unreachable" #if !NO_EXTENSIONTYPING | ProvidedProp(_, pi, m) -> @@ -2074,7 +2113,6 @@ type PropInfo = | Some vref -> vref.IsFSharpExplicitInterfaceImplementation x.TcGlobals | None -> false - /// Indicates if this property is an indexer property, i.e. a property with arguments. member x.IsIndexer = match x with @@ -2109,14 +2147,13 @@ type PropInfo = /// /// Property infos can combine getters and setters, assuming they are consistent w.r.t. 'virtual', indexer argument types etc. /// When checking consistency we split these apart - member x.DropSetter = + member x.DropSetter() = match x with | FSProp(g, ty, Some vref, _) -> FSProp(g, ty, Some vref, None) | _ -> x - /// Return a new property info where there is no associated getter, only an associated setter. - member x.DropGetter = + member x.DropGetter() = match x with | FSProp(g, ty, _, Some vref) -> FSProp(g, ty, None, Some vref) | _ -> x @@ -2130,7 +2167,8 @@ type PropInfo = | FSProp(_, _, None, None) -> failwith "unreachable" #if !NO_EXTENSIONTYPING | ProvidedProp(_, pi, m) -> - XmlDoc (pi.PUntaint((fun pix -> (pix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(pi.TypeProvider.PUntaintNoFailure id)), m)) + let lines = pi.PUntaint((fun pix -> (pix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(pi.TypeProvider.PUntaintNoFailure id)), m) + XmlDoc (lines, m) #endif /// Get the TcGlobals associated with the object @@ -2147,7 +2185,6 @@ type PropInfo = /// For an extension property, this indicates if the property extends a struct type. member x.IsValueType = isStructTy x.TcGlobals x.ApparentEnclosingType - /// Get the result type of the property member x.GetPropertyType (amap, m) = match x with @@ -2164,7 +2201,6 @@ type PropInfo = Import.ImportProvidedType amap m (pi.PApply((fun pi -> pi.PropertyType), m)) #endif - /// Get the names and types of the indexer parameters associated with the property /// /// If the property is in a generic type, then the type parameters are instantiated in the types returned. @@ -2247,6 +2283,8 @@ type PropInfo = | ProvidedProp(_, pi, _) -> ProvidedPropertyInfo.TaintedGetHashCode pi #endif + override x.ToString() = "property " + x.PropertyName + //------------------------------------------------------------------------- // ILEventInfo @@ -2254,7 +2292,7 @@ type PropInfo = /// Describes an F# use of an event backed by Abstract IL metadata [] type ILEventInfo = - | ILEventInfo of ILTypeInfo * ILEventDef + | ILEventInfo of ilTypeInfo: ILTypeInfo * ilEventDef: ILEventDef /// Get the enclosing ("parent"/"declaring") type of the field. member x.ApparentEnclosingType = match x with ILEventInfo(tinfo, _) -> tinfo.ToType @@ -2287,11 +2325,12 @@ type ILEventInfo = member x.TypeRef = x.ILTypeInfo.ILTypeRef /// Get the name of the event - member x.Name = x.RawMetadata.Name + member x.EventName = x.RawMetadata.Name /// Indicates if the property is static member x.IsStatic = x.AddMethod.IsStatic - override x.ToString() = x.ILTypeInfo.ToString() + "::" + x.Name + + override x.ToString() = x.ILTypeInfo.ToString() + "::" + x.EventName //------------------------------------------------------------------------- // Helpers for EventInfo @@ -2330,12 +2369,14 @@ let FindDelegateTypeOfPropertyEvent g amap nm m ty = [] type EventInfo = /// An F# use of an event backed by F#-declared metadata - | FSEvent of TcGlobals * PropInfo * ValRef * ValRef + | FSEvent of tcGlobals: TcGlobals * propInfo: PropInfo * addMethod: ValRef * removeMethod: ValRef + /// An F# use of an event backed by .NET metadata - | ILEvent of ILEventInfo + | ILEvent of ilEventInfo: ILEventInfo + #if !NO_EXTENSIONTYPING /// An F# use of an event backed by provided metadata - | ProvidedEvent of Import.ImportMap * Tainted * range + | ProvidedEvent of amap: Import.ImportMap * providedEvent: Tainted * range: range #endif /// Get the enclosing type of the event. @@ -2365,7 +2406,6 @@ type EventInfo = | Some vref when x.IsExtensionMember && vref.HasDeclaringEntity -> vref.TopValDeclaringEntity | _ -> x.ApparentEnclosingTyconRef - /// Indicates if this event has an associated XML comment authored in this assembly. member x.HasDirectXmlComment = match x with @@ -2382,13 +2422,14 @@ type EventInfo = | FSEvent (_, p, _, _) -> p.XmlDoc #if !NO_EXTENSIONTYPING | ProvidedEvent (_, ei, m) -> - XmlDoc (ei.PUntaint((fun eix -> (eix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(ei.TypeProvider.PUntaintNoFailure id)), m)) + let lines = ei.PUntaint((fun eix -> (eix :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(ei.TypeProvider.PUntaintNoFailure id)), m) + XmlDoc (lines, m) #endif /// Get the logical name of the event. member x.EventName = match x with - | ILEvent ileinfo -> ileinfo.Name + | ILEvent ileinfo -> ileinfo.EventName | FSEvent (_, p, _, _) -> p.PropertyName #if !NO_EXTENSIONTYPING | ProvidedEvent (_, ei, m) -> ei.PUntaint((fun ei -> ei.Name), m) @@ -2472,7 +2513,6 @@ type EventInfo = Import.ImportProvidedType amap m (ei.PApply((fun ei -> ei.EventHandlerType), m)) #endif - /// Test whether two event infos have the same underlying definition. /// Must be compatible with ItemsAreEffectivelyEqual relation. static member EventInfosUseIdenticalDefinitions x1 x2 = @@ -2494,6 +2534,7 @@ type EventInfo = #if !NO_EXTENSIONTYPING | ProvidedEvent (_, ei, _) -> ProvidedEventInfo.TaintedGetHashCode ei #endif + override x.ToString() = "event " + x.EventName //------------------------------------------------------------------------- // Helpers associated with getting and comparing method signatures @@ -2505,7 +2546,7 @@ let stripByrefTy g ty = /// Represents the information about the compiled form of a method signature. Used when analyzing implementation /// relations between members and abstract slots. -type CompiledSig = CompiledSig of TType list list * TType option * Typars * TyparInst +type CompiledSig = CompiledSig of argTys: TType list list * returnTy: TType option * formalMethTypars: Typars * formalMethTyparInst: TyparInst /// Get the information about the compiled form of a method signature. Used when analyzing implementation /// relations between members and abstract slots. @@ -2525,10 +2566,8 @@ let CompiledSigOfMeth g amap m (minfo: MethInfo) = CompiledSig(vargtys, vrty, formalMethTypars, fmtpinst) -/// Used to hide/filter members from super classes based on signature /// Inref and outref parameter types will be treated as a byref type for equivalency. -let MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m (minfo: MethInfo) (minfo2: MethInfo) = - (minfo.LogicalName = minfo2.LogicalName) && +let MethInfosEquivByPartialSig erasureFlag ignoreFinal g amap m (minfo: MethInfo) (minfo2: MethInfo) = (minfo.GenericArity = minfo2.GenericArity) && (ignoreFinal || minfo.IsFinal = minfo2.IsFinal) && let formalMethTypars = minfo.FormalMethodTypars @@ -2541,13 +2580,19 @@ let MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m (minfo: M typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2))) /// Used to hide/filter members from super classes based on signature +/// Inref and outref parameter types will be treated as a byref type for equivalency. +let MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m (minfo: MethInfo) (minfo2: MethInfo) = + (minfo.LogicalName = minfo2.LogicalName) && + MethInfosEquivByPartialSig erasureFlag ignoreFinal g amap m minfo minfo2 + +/// Used to hide/filter members from base classes based on signature let PropInfosEquivByNameAndPartialSig erasureFlag g amap m (pinfo: PropInfo) (pinfo2: PropInfo) = pinfo.PropertyName = pinfo2.PropertyName && let argtys = pinfo.GetParamTypes(amap, m) let argtys2 = pinfo2.GetParamTypes(amap, m) List.lengthsEqAndForall2 (typeEquivAux erasureFlag g) argtys argtys2 -/// Used to hide/filter members from super classes based on signature +/// Used to hide/filter members from base classes based on signature let MethInfosEquivByNameAndSig erasureFlag ignoreFinal g amap m minfo minfo2 = MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m minfo minfo2 && let (CompiledSig(_, retTy, formalMethTypars, _)) = CompiledSigOfMeth g amap m minfo @@ -2565,5 +2610,5 @@ let PropInfosEquivByNameAndSig erasureFlag g amap m (pinfo: PropInfo) (pinfo2: P typeEquivAux erasureFlag g retTy retTy2 let SettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasSetter then Some(pinfo.SetterMethod, Some pinfo) else None) -let GettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasGetter then Some(pinfo.GetterMethod, Some pinfo) else None) +let GettersOfPropInfos (pinfos: PropInfo list) = pinfos |> List.choose (fun pinfo -> if pinfo.HasGetter then Some(pinfo.GetterMethod, Some pinfo) else None) diff --git a/src/fsharp/infos.fsi b/src/fsharp/infos.fsi new file mode 100644 index 00000000000..30a96aeb08a --- /dev/null +++ b/src/fsharp/infos.fsi @@ -0,0 +1,1064 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.Infos + +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Syntax +open FSharp.Compiler.Import +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +#if !NO_EXTENSIONTYPING +open FSharp.Compiler.ExtensionTyping +#endif + +/// Import an IL type as an F# type. importInst gives the context for interpreting type variables. +val ImportILType: scoref:ILScopeRef -> amap:ImportMap -> m:range -> importInst:TType list -> ilty:ILType -> TType + +val CanImportILType: scoref:ILScopeRef -> amap:ImportMap -> m:range -> ilty:ILType -> bool + +/// Indicates if an F# type is the type associated with an F# exception declaration +val isExnDeclTy: g:TcGlobals -> ty:TType -> bool + +/// Get the base type of a type, taking into account type instantiations. Return None if the +/// type has no base type. +val GetSuperTypeOfType: g:TcGlobals -> amap:ImportMap -> m:range -> ty:TType -> TType option + +/// Indicates whether we can skip interface types that lie outside the reference set +[] +type SkipUnrefInterfaces = + | Yes + | No + +/// Collect the set of immediate declared interface types for an F# type, but do not +/// traverse the type hierarchy to collect further interfaces. +val GetImmediateInterfacesOfType: skipUnref:SkipUnrefInterfaces -> g:TcGlobals -> amap:ImportMap -> m:range -> ty:TType -> TType list + +/// Indicates whether we should visit multiple instantiations of the same generic interface or not +[] +type AllowMultiIntfInstantiations = + | Yes + | No + +/// Fold, do not follow interfaces (unless the type is itself an interface) +val FoldPrimaryHierarchyOfType: f:(TType -> 'a -> 'a) -> g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> acc:'a -> 'a + +/// Fold, following interfaces. Skipping interfaces that lie outside the referenced assembly set is allowed. +val FoldEntireHierarchyOfType: f:(TType -> 'a -> 'a) -> g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> acc:'a -> 'a + +/// Iterate, following interfaces. Skipping interfaces that lie outside the referenced assembly set is allowed. +val IterateEntireHierarchyOfType: f:(TType -> unit) -> g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> unit + +/// Search for one element satisfying a predicate, following interfaces +val ExistsInEntireHierarchyOfType: f:(TType -> bool) -> g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> bool + +/// Search for one element where a function returns a 'Some' result, following interfaces +val SearchEntireHierarchyOfType: f:(TType -> bool) -> g:TcGlobals -> amap:ImportMap -> m:range -> ty:TType -> TType option + +/// Get all super types of the type, including the type itself +val AllSuperTypesOfType: g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> TType list + +/// Get all interfaces of a type, including the type itself if it is an interface +val AllInterfacesOfType: g:TcGlobals -> amap:ImportMap -> m:range -> allowMultiIntfInst:AllowMultiIntfInstantiations -> ty:TType -> TType list + +/// Check if two types have the same nominal head type +val HaveSameHeadType: g:TcGlobals -> ty1:TType -> ty2:TType -> bool + +/// Check if a type has a particular head type +val HasHeadType: g:TcGlobals -> tcref:TyconRef -> ty2:TType -> bool + +/// Check if a type exists somewhere in the hierarchy which has the same head type as the given type (note, the given type need not have a head type at all) +val ExistsSameHeadTypeInHierarchy: g:TcGlobals -> amap:ImportMap -> m:range -> typeToSearchFrom:TType -> typeToLookFor:TType -> bool + +/// Check if a type exists somewhere in the hierarchy which has the given head type. +val ExistsHeadTypeInEntireHierarchy: g:TcGlobals -> amap:ImportMap -> m:range -> typeToSearchFrom:TType -> tcrefToLookFor:TyconRef -> bool + +/// Read an Abstract IL type from metadata and convert to an F# type. +val ImportILTypeFromMetadata: amap:ImportMap -> m:range -> scoref:ILScopeRef -> tinst:TType list -> minst:TType list -> ilty:ILType -> TType + +/// Read an Abstract IL type from metadata, including any attributes that may affect the type itself, and convert to an F# type. +val ImportILTypeFromMetadataWithAttributes: amap:ImportMap -> m:range -> scoref:ILScopeRef -> tinst:TType list -> minst:TType list -> ilty:ILType -> cattrs:ILAttributes -> TType + +/// Get the parameter type of an IL method. +val ImportParameterTypeFromMetadata: amap:ImportMap -> m:range -> ilty:ILType -> cattrs:ILAttributes -> scoref:ILScopeRef -> tinst:TType list -> mist:TType list -> TType + +/// Get the return type of an IL method, taking into account instantiations for type, return attributes and method generic parameters, and +/// translating 'void' to 'None'. +val ImportReturnTypeFromMetadata: amap:ImportMap -> m:range -> ilty:ILType -> cattrs:ILAttributes -> scoref:ILScopeRef -> tinst:TType list -> minst:TType list -> TType option + +/// Copy constraints. If the constraint comes from a type parameter associated +/// with a type constructor then we are simply renaming type variables. If it comes +/// from a generic method in a generic class (e.g. ty.M<_>) then we may be both substituting the +/// instantiation associated with 'ty' as well as copying the type parameters associated with +/// M and instantiating their constraints +/// +/// Note: this now looks identical to constraint instantiation. + +val CopyTyparConstraints: m:range -> tprefInst:TyparInst -> tporig:Typar -> TyparConstraint list + +/// The constraints for each typar copied from another typar can only be fixed up once +/// we have generated all the new constraints, e.g. f List, B :> List> ... +val FixupNewTypars: m:range -> formalEnclosingTypars:Typars -> tinst:TType list -> tpsorig:Typars -> tps:Typars -> TyparInst * TTypes + +type ValRef with + /// Indicates if an F#-declared function or member value is a CLIEvent property compiled as a .NET event + member IsFSharpEventProperty: g:TcGlobals -> bool + + /// Check if an F#-declared member value is a virtual method + member IsVirtualMember: bool + + /// Check if an F#-declared member value is a dispatch slot + member IsDispatchSlotMember: bool + + /// Check if an F#-declared member value is an 'override' or explicit member implementation + member IsDefiniteFSharpOverrideMember: bool + + /// Check if an F#-declared member value is an explicit interface member implementation + member IsFSharpExplicitInterfaceImplementation: g:TcGlobals -> bool + + member ImplementedSlotSignatures: SlotSig list + +#if !NO_EXTENSIONTYPING +/// Get the return type of a provided method, where 'void' is returned as 'None' +val GetCompiledReturnTyOfProvidedMethodInfo: amap:ImportMap ->m:range -> mi:Tainted -> TType option +#endif + +/// The slotsig returned by methInfo.GetSlotSig is in terms of the type parameters on the parent type of the overriding method. +/// Reverse-map the slotsig so it is in terms of the type parameters for the overriding method +val ReparentSlotSigToUseMethodTypars: g:TcGlobals -> m:range -> ovByMethValRef:ValRef -> slotsig:SlotSig -> SlotSig + +/// Construct the data representing a parameter in the signature of an abstract method slot +val MakeSlotParam: ty:TType * argInfo:ArgReprInfo -> SlotParam + +/// Construct the data representing the signature of an abstract method slot +val MakeSlotSig: nm:string * ty:TType * ctps:Typars * mtps:Typars * paraml:SlotParam list list * retTy:TType option -> SlotSig + +/// Describes the sequence order of the introduction of an extension method. Extension methods that are introduced +/// later through 'open' get priority in overload resolution. +type ExtensionMethodPriority = uint64 + +/// The caller-side value for the optional arg, if any +type OptionalArgCallerSideValue = + | Constant of ILFieldInit + | DefaultValue + | MissingValue + | WrapperForIDispatch + | WrapperForIUnknown + | PassByRef of TType * OptionalArgCallerSideValue + +/// Represents information about a parameter indicating if it is optional. +type OptionalArgInfo = + /// The argument is not optional + | NotOptional + + /// The argument is optional, and is an F# callee-side optional arg + | CalleeSide + + /// The argument is optional, and is a caller-side .NET optional or default arg. + /// Note this is correctly termed caller side, even though the default value is optically specified on the callee: + /// in fact the default value is read from the metadata and passed explicitly to the callee on the caller side. + | CallerSide of OptionalArgCallerSideValue + + static member FieldInitForDefaultParameterValueAttrib: attrib:Attrib -> ILFieldInit option + + /// Compute the OptionalArgInfo for an IL parameter + /// + /// This includes the Visual Basic rules for IDispatchConstant and IUnknownConstant and optional arguments. + static member FromILParameter: g:TcGlobals -> amap:ImportMap -> m:range -> ilScope:ILScopeRef -> ilTypeInst:TType list -> ilParam:ILParameter -> OptionalArgInfo + + static member ValueOfDefaultParameterValueAttrib: Attrib -> Expr option + + member IsOptional: bool + +type CallerInfo = + | NoCallerInfo + | CallerLineNumber + | CallerMemberName + | CallerFilePath + +[] +type ReflectedArgInfo = + | None + | Quote of bool + + member AutoQuote: bool + +/// Partial information about a parameter returned for use by the Language Service +[] +type ParamNameAndType = + | ParamNameAndType of Ident option * TType + + static member FromArgInfo: ty:TType * argInfo:ArgReprInfo -> ParamNameAndType + + static member FromMember: isCSharpExtMem:bool -> g:TcGlobals -> vref:ValRef -> ParamNameAndType list list + + static member Instantiate: inst:TyparInst -> p:ParamNameAndType -> ParamNameAndType + + static member InstantiateCurried: inst:TyparInst -> paramTypes:ParamNameAndType list list -> ParamNameAndType list list + +/// Full information about a parameter returned for use by the type checker and language service. +[] +type ParamData = + | ParamData of + isParamArray: bool * + isInArg: bool * + isOut: bool * + optArgInfo: OptionalArgInfo * + callerInfo: CallerInfo * + nameOpt: Ident option * + reflArgInfo: ReflectedArgInfo * + ttype: TType + +/// Describes an F# use of an IL type, including the type instantiation associated with the type at a particular usage point. +[] +type ILTypeInfo = + | ILTypeInfo of TcGlobals * TType * ILTypeRef * ILTypeDef + static member FromType: g:TcGlobals -> ty:TType -> ILTypeInfo + + member Instantiate: inst:TyparInst -> ILTypeInfo + + member ILScopeRef: ILScopeRef + + member ILTypeRef: ILTypeRef + + member IsValueType: bool + + member Name: string + + member RawMetadata: ILTypeDef + + member TcGlobals: TcGlobals + + /// Get the compiled nominal type. In the case of tuple types, this is a .NET tuple type + member ToAppType: TType + + member ToType: TType + + member TyconRefOfRawMetadata: TyconRef + + member TypeInstOfRawMetadata: TypeInst + +/// Describes an F# use of an IL method. +[] +type ILMethInfo = + | ILMethInfo of g: TcGlobals * ilApparentType: TType * ilDeclaringTyconRefOpt: TyconRef option * ilMethodDef: ILMethodDef * ilGenericMethodTyArgs: Typars + + /// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type + member ApparentEnclosingAppType: TType + + /// Get the apparent declaring type of the method as an F# type. + /// If this is a C#-style extension method then this is the type which the method + /// appears to extend. This may be a variable type. + member ApparentEnclosingType: TType + + /// Get the declaring type of the method. If this is an C#-style extension method then this is the IL type + /// holding the static member that is the extension method. + member DeclaringTyconRef: TyconRef + + /// Get the instantiation of the declaring type of the method. + /// If this is an C#-style extension method then this is empty because extension members + /// are never in generic classes. + member DeclaringTypeInst: TType list + + /// Get the formal method type parameters associated with a method. + member FormalMethodTypars: Typars + + /// Get the declaring type associated with an extension member, if any. + member ILExtensionMethodDeclaringTyconRef: TyconRef option + + /// Get a reference to the method (dropping all generic instantiations), as an Abstract IL ILMethodRef. + member ILMethodRef: ILMethodRef + + /// Get the IL name of the method + member ILName: string + + /// Indicates if the IL method is marked abstract. + member IsAbstract: bool + + /// Indicates if the method is a class initializer. + member IsClassConstructor: bool + + /// Indicates if the method is a constructor + member IsConstructor: bool + + /// Indicates if the IL method is marked final. + member IsFinal: bool + + /// Indicates if the method is an extension method + member IsILExtensionMethod: bool + + /// Does it appear to the user as an instance method? + member IsInstance: bool + + /// Does it have the .NET IL 'newslot' flag set, and is also a virtual? + member IsNewSlot: bool + + /// Indicates if the method has protected accessibility, + member IsProtectedAccessibility: bool + + /// Does it appear to the user as a static method? + member IsStatic: bool + + /// Indicates if the IL method is marked virtual. + member IsVirtual: bool + + /// Get the Abstract IL scope information associated with interpreting the Abstract IL metadata that backs this method. + member MetadataScope: ILScopeRef + + /// Get the number of parameters of the method + member NumParams: int + + /// Get the Abstract IL metadata corresponding to the parameters of the method. + /// If this is an C#-style extension method then drop the object argument. + member ParamMetadata: ILParameter list + + /// Get the Abstract IL metadata associated with the method. + member RawMetadata: ILMethodDef + + member TcGlobals: TcGlobals + + /// Get the compiled return type of the method, where 'void' is None. + member GetCompiledReturnTy: amap:ImportMap * m:range * minst:TType list -> TType option + + /// Get the F# view of the return type of the method, where 'void' is 'unit'. + member GetFSharpReturnTy: amap:ImportMap * m:range * minst:TType list -> TType + + /// Get the (zero or one) 'self'/'this'/'object' arguments associated with an IL method. + /// An instance extension method returns one object argument. + member GetObjArgTypes: amap:ImportMap * m:range * minst:TType list -> TType list + + /// Get info about the arguments of the IL method. If this is an C#-style extension method then + /// drop the object argument. + /// + /// Any type parameters of the enclosing type are instantiated in the type returned. + member GetParamNamesAndTypes: amap:ImportMap * m:range * minst:TType list -> ParamNameAndType list + + /// Get the argument types of the the IL method. If this is an C#-style extension method + /// then drop the object argument. + member GetParamTypes: amap:ImportMap * m:range * minst:TType list -> TType list + + /// Get all the argument types of the IL method. Include the object argument even if this is + /// an C#-style extension method. + member GetRawArgTypes: amap:ImportMap * m:range * minst:TType list -> TType list + + /// Indicates if the method is marked as a DllImport (a PInvoke). This is done by looking at the IL custom attributes on + /// the method. + member IsDllImport: g:TcGlobals -> bool + + /// Indicates if the method is marked with the [] attribute. This is done by looking at the IL custom attributes on + /// the method. + member IsReadOnly: g:TcGlobals -> bool + +/// Describes an F# use of a method +[] +type MethInfo = + + /// Describes a use of a method declared in F# code and backed by F# metadata. + | FSMeth of tcGlobals: TcGlobals * enclosingType: TType * valRef: ValRef * extensionMethodPriority: ExtensionMethodPriority option + + /// Describes a use of a method backed by Abstract IL # metadata + | ILMeth of tcGlobals: TcGlobals * ilMethInfo: ILMethInfo * extensionMethodPriority: ExtensionMethodPriority option + + /// Describes a use of a pseudo-method corresponding to the default constructor for a .NET struct type + | DefaultStructCtor of tcGlobals: TcGlobals * structTy: TType + +#if !NO_EXTENSIONTYPING + /// Describes a use of a method backed by provided metadata + | ProvidedMeth of amap: ImportMap * methodBase: Tainted * extensionMethodPriority: ExtensionMethodPriority option * m: range +#endif + + /// Get the enclosing type of the method info, using a nominal type for tuple types + member ApparentEnclosingAppType: TType + + member ApparentEnclosingTyconRef: TyconRef + + /// Get the enclosing type of the method info. + /// + /// If this is an extension member, then this is the apparent parent, i.e. the type the method appears to extend. + /// This may be a variable type. + member ApparentEnclosingType: TType + + /// Try to get an arbitrary F# ValRef associated with the member. This is to determine if the member is virtual, amongst other things. + member ArbitraryValRef: ValRef option + + /// Get the method name in DebuggerDisplayForm + member DebuggerDisplayName: string + + /// Get the declaring type or module holding the method. If this is an C#-style extension method then this is the type + /// holding the static member that is the extension method. If this is an F#-style extension method it is the logical module + /// holding the value for the extension method. + member DeclaringTyconRef: TyconRef + + /// Get the actual type instantiation of the declaring type associated with this use of the method. + /// + /// For extension members this is empty (the instantiation of the declaring type). + member DeclaringTypeInst: TType list + + /// Get the method name in DisplayName form + member DisplayName: string + + /// Get the method name in core DisplayName form (no backticks or parens added) + member DisplayNameCore: string + + /// Get the extension method priority of the method. If it is not an extension method + /// then use the highest possible value since non-extension methods always take priority + /// over extension members. + member ExtensionMemberPriority: ExtensionMethodPriority + + /// Get the extension method priority of the method, if it has one. + member ExtensionMemberPriorityOption: ExtensionMethodPriority option + + /// Get the formal generic method parameters for the method as a list of variable types. + member FormalMethodInst: TypeInst + + member FormalMethodTyparInst: TyparInst + + /// Get the formal generic method parameters for the method as a list of type variables. + /// + /// For an extension method this includes all type parameters, even if it is extending a generic type. + member FormalMethodTypars: Typars + + /// Get the number of generic method parameters for a method. + /// For an extension method this includes all type parameters, even if it is extending a generic type. + member GenericArity: int + + /// Indicates if this is a method defined in this assembly with an internal XML comment + member HasDirectXmlComment: bool + + member ImplementedSlotSignatures: SlotSig list + + // Is this particular MethInfo one that doesn't provide an implementation? + /// + // For F# methods, this is 'true' for the MethInfos corresponding to 'abstract' declarations, + // and false for the (potentially) matching 'default' implementation MethInfos that eventually + // provide an implementation for the dispatch slot. + // + // For IL methods, this is 'true' for abstract methods, and 'false' for virtual methods + member IsAbstract: bool + + /// Indicates if this is an C#-style extension member. + member IsCSharpStyleExtensionMember: bool + + member IsClassConstructor: bool + + member IsConstructor: bool + + member IsCurried: bool + + /// Check if this method is marked 'override' and thus definitely overrides another method. + member IsDefiniteFSharpOverride: bool + + member IsDispatchSlot: bool + + /// Indicates if this is an extension member. + member IsExtensionMember: bool + + /// Indicates if this method is a generated method associated with an F# CLIEvent property compiled as a .NET event + member IsFSharpEventPropertyMethod: bool + + /// Check if this method is an explicit implementation of an interface member + member IsFSharpExplicitInterfaceImplementation: bool + + /// Indicates if this is an F#-style extension member. + member IsFSharpStyleExtensionMember: bool + + member IsFinal: bool + + /// Indicates if this is an IL method. + member IsILMethod: bool + + /// Does the method appear to the user as an instance method? + member IsInstance: bool + + member IsNewSlot: bool + + /// Indicates if this method takes no arguments + member IsNullary: bool + + member IsProtectedAccessibility: bool + + /// Indicates if this method is read-only; usually by the [] attribute. + /// Must be an instance method. + /// Receiver must be a struct type. + member IsReadOnly: bool + + /// Indicates if the enclosing type for the method is a value type. + /// + /// For an extension method, this indicates if the method extends a struct type. + member IsStruct: bool + + member IsVirtual: bool + + /// Get the method name in LogicalName form, i.e. the name as it would be stored in .NET metadata + member LogicalName: string + + /// Get a list of argument-number counts, one count for each set of curried arguments. + /// + /// For an extension member, drop the 'this' argument. + member NumArgs: int list + +/// Get the information about provided static parameters, if any +#if NO_EXTENSIONTYPING + member ProvidedStaticParameterInfo: obj option +#else + member ProvidedStaticParameterInfo: (Tainted * Tainted []) option +#endif + + /// Get the TcGlobals value that governs the method declaration + member TcGlobals: TcGlobals + + /// Get the XML documentation associated with the method + member XmlDoc: XmlDoc + + /// Build IL method infos. + static member CreateILMeth: amap:ImportMap * m:range * ty:TType * md:ILMethodDef -> MethInfo + + /// Build IL method infos for a C#-style extension method + static member CreateILExtensionMeth: amap:ImportMap * m:range * apparentTy:TType * declaringTyconRef:TyconRef * extMethPri:ExtensionMethodPriority option * md:ILMethodDef -> MethInfo + + /// Tests whether two method infos have the same underlying definition. + /// Used to merge operator overloads collected from left and right of an operator constraint. + /// + /// Compatible with ItemsAreEffectivelyEqual relation. + static member MethInfosUseIdenticalDefinitions: x1:MethInfo -> x2:MethInfo -> bool + + /// Add the actual type instantiation of the apparent type of an F# extension method. + member AdjustUserTypeInstForFSharpStyleIndexedExtensionMembers: tyargs:TType list -> TType list + + /// Calculates a hash code of method info. Compatible with ItemsAreEffectivelyEqual relation. + member ComputeHashCode: unit -> int + + /// Get the return type of a method info, where 'void' is returned as 'None' + member GetCompiledReturnTy: amap:ImportMap * m:range * minst:TType list -> TType option + + /// Get the return type of a method info, where 'void' is returned as 'unit' + member GetFSharpReturnTy: amap:ImportMap * m:range * minst:TType list -> TType + + /// Select all the type parameters of the declaring type of a method. + /// + /// For extension methods, no type parameters are returned, because all the + /// type parameters are part of the apparent type, rather the + /// declaring type, even for extension methods extending generic types. + member GetFormalTyparsOfDeclaringType: m:range -> Typar list + + /// Get the (zero or one) 'self'/'this'/'object' arguments associated with a method. + /// An instance method returns one object argument. + member GetObjArgTypes: amap:ImportMap * m:range * minst:TypeInst -> TType list + + /// Get the parameter attributes of a method info, which get combined with the parameter names and types + member GetParamAttribs: amap:ImportMap * m:range -> (bool * bool * bool * OptionalArgInfo * CallerInfo * ReflectedArgInfo) list list + + /// Get the ParamData objects for the parameters of a MethInfo + member GetParamDatas: amap:ImportMap * m:range * minst:TType list -> ParamData list list + + /// Get the parameter types of a method info + member GetParamTypes: amap:ImportMap * m:range * minst:TType list -> TType list list + + /// Get the signature of an abstract method slot. + member GetSlotSig: amap:ImportMap * m:range -> SlotSig + + /// Get the ParamData objects for the parameters of a MethInfo + member HasParamArrayArg: amap:ImportMap * m:range * minst:TType list -> bool + + /// Apply a type instantiation to a method info, i.e. apply the instantiation to the enclosing type. + member Instantiate: amap:ImportMap * m:range * inst:TyparInst -> MethInfo + + /// Indicates if this method is an extension member that is read-only. + /// An extension member is considered read-only if the first argument is a read-only byref (inref) type. + member IsReadOnlyExtensionMember: amap:ImportMap * m:range -> bool + + /// Indicates if this is an extension member (e.g. on a struct) that takes a byref arg + member ObjArgNeedsAddress: amap:ImportMap * m:range -> bool + + /// Tries to get the object arg type if it's a byref type. + member TryObjArgByrefType: amap:ImportMap * m:range * minst:TypeInst -> TType option + +/// Represents a single use of a IL or provided field from one point in an F# program +[] +type ILFieldInfo = + /// Represents a single use of a field backed by Abstract IL metadata + | ILFieldInfo of ilTypeInfo: ILTypeInfo * ilFieldDef: ILFieldDef + +#if !NO_EXTENSIONTYPING + /// Represents a single use of a field backed by provided metadata + | ProvidedField of amap: ImportMap * providedField: Tainted * range: range +#endif + + /// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type + member ApparentEnclosingAppType: TType + + member ApparentEnclosingTyconRef: TyconRef + + /// Get the enclosing ("parent"/"declaring") type of the field. + member ApparentEnclosingType: TType + + member DeclaringTyconRef: TyconRef + + /// Get the name of the field + member FieldName: string + + /// Get an (uninstantiated) reference to the field as an Abstract IL ILFieldRef + member ILFieldRef: ILFieldRef + + /// Get the type of the field as an IL type + member ILFieldType: ILType + + /// Get a reference to the declaring type of the field as an ILTypeRef + member ILTypeRef: ILTypeRef + + /// Indicates if the field is readonly (in the .NET/C# sense of readonly) + member IsInitOnly: bool + + /// Indicates if the field has the 'specialname' property in the .NET IL + member IsSpecialName: bool + + /// Indicates if the field is static + member IsStatic: bool + + /// Indicates if the field is a member of a struct or enum type + member IsValueType: bool + + /// Indicates if the field is a literal field with an associated literal value + member LiteralValue: ILFieldInit option + + /// Get the scope used to interpret IL metadata + member ScopeRef: ILScopeRef + + member TcGlobals: TcGlobals + + /// Get the type instantiation of the declaring type of the field + member TypeInst: TypeInst + + /// Tests whether two infos have the same underlying definition. + /// Compatible with ItemsAreEffectivelyEqual relation. + static member ILFieldInfosUseIdenticalDefinitions: x1:ILFieldInfo -> x2:ILFieldInfo -> bool + + /// Calculates a hash code of field info. Must be compatible with ItemsAreEffectivelyEqual relation. + member ComputeHashCode: unit -> int + + /// Get the type of the field as an F# type + member FieldType: amap:ImportMap * m:range -> TType + +/// Describes an F# use of a field in an F#-declared record, class or struct type +[] +type RecdFieldInfo = + | RecdFieldInfo of typeInst: TypeInst * recdFieldRef: RecdFieldRef + + /// Get the enclosing (declaring) type of the field in an F#-declared record, class or struct type + member DeclaringType: TType + + /// Get the (instantiated) type of the field in an F#-declared record, class or struct type + member FieldType: TType + + /// Indicate if the field is a static field in an F#-declared record, class or struct type + member IsStatic: bool + + /// Indicate if the field is a literal field in an F#-declared record, class or struct type + member LiteralValue: Const option + + /// Get the logical name of the field in an F#-declared record, class or struct type + member LogicalName: string + + /// Get the name of the field, same as LogicalName + /// Note: no double-backticks added for non-identifiers + member DisplayNameCore: string + + /// Get the name of the field, with double-backticks added if necessary + member DisplayName: string + + /// Get the F# metadata for the uninstantiated field + member RecdField: RecdField + + /// Get a reference to the F# metadata for the uninstantiated field + member RecdFieldRef: RecdFieldRef + + /// Get the F# metadata for the F#-declared record, class or struct type + member Tycon: Entity + + /// Get a reference to the F# metadata for the F#-declared record, class or struct type + member TyconRef: TyconRef + + /// Get the generic instantiation of the declaring type of the field + member TypeInst: TypeInst + +/// Describes an F# use of a union case +[] +type UnionCaseInfo = + | UnionCaseInfo of typeInst: TypeInst * unionCaseRef: UnionCaseRef + + /// Get the logical name of the union case. + member LogicalName: string + + /// Get the core of the display name of the union case + /// + /// Backticks and parens are not added for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become [] and :: respectively. + member DisplayNameCore: string + + /// Get the display name of the union case + /// + /// Backticks and parens are added implicitly for non-identifiers. + /// + /// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively. + member DisplayName: string + + /// Get the F# metadata for the declaring union type + member Tycon: Entity + + /// Get a reference to the F# metadata for the declaring union type + member TyconRef: TyconRef + + /// Get the list of types for the instantiation of the type parameters of the declaring type of the union case + member TypeInst: TypeInst + + /// Get the F# metadata for the uninstantiated union case + member UnionCase: UnionCase + + /// Get a reference to the F# metadata for the uninstantiated union case + member UnionCaseRef: UnionCaseRef + + /// Get the instantiation of the type parameters of the declaring type of the union case + member GetTyparInst: m:range -> TyparInst + +/// Describes an F# use of a property backed by Abstract IL metadata +[] +type ILPropInfo = + | ILPropInfo of ilTypeInfo: ILTypeInfo * ilPropertyDef: ILPropertyDef + + /// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type + member ApparentEnclosingAppType: TType + + /// Get the apparent declaring type of the method as an F# type. + /// If this is a C#-style extension method then this is the type which the method + /// appears to extend. This may be a variable type. + member ApparentEnclosingType: TType + + /// Gets the ILMethInfo of the 'get' method for the IL property + member GetterMethod: ILMethInfo + + /// Indicates if the IL property has a 'get' method + member HasGetter: bool + + /// Indicates if the IL property has a 'set' method + member HasSetter: bool + + /// Get the declaring IL type of the IL property, including any generic instantiation + member ILTypeInfo: ILTypeInfo + + /// Indicates if the IL property is logically a 'newslot', i.e. hides any previous slots of the same name. + member IsNewSlot: bool + + /// Indicates if the IL property is static + member IsStatic: bool + + /// Indicates if the IL property is virtual + member IsVirtual: bool + + /// Get the name of the IL property + member PropertyName: string + + /// Get the raw Abstract IL metadata for the IL property + member RawMetadata: ILPropertyDef + + /// Gets the ILMethInfo of the 'set' method for the IL property + member SetterMethod: ILMethInfo + + /// Get the TcGlobals governing this value + member TcGlobals: TcGlobals + + /// Get the names and types of the indexer arguments associated with the IL property. + /// + /// Any type parameters of the enclosing type are instantiated in the type returned. + member GetParamNamesAndTypes: amap:ImportMap * m:range -> ParamNameAndType list + + /// Get the types of the indexer arguments associated with the IL property. + /// + /// Any type parameters of the enclosing type are instantiated in the type returned. + member GetParamTypes: amap:ImportMap * m:range -> TType list + + /// Get the return type of the IL property. + /// + /// Any type parameters of the enclosing type are instantiated in the type returned. + member GetPropertyType: amap:ImportMap * m:range -> TType + +/// Describes an F# use of a property +[] +type PropInfo = + /// An F# use of a property backed by F#-declared metadata + | FSProp of tcGlobals: TcGlobals * apparentEnclTy: TType * getter: ValRef option * setter: ValRef option + + /// An F# use of a property backed by Abstract IL metadata + | ILProp of ilPropInfo: ILPropInfo + +#if !NO_EXTENSIONTYPING + /// An F# use of a property backed by provided metadata + | ProvidedProp of amap: ImportMap * providedProp: Tainted * range: range +#endif + + /// Get the enclosing type of the method info, using a nominal type for tuple types + member ApparentEnclosingAppType: TType + + member ApparentEnclosingTyconRef: TyconRef + + /// Get the enclosing type of the property. + /// + /// If this is an extension member, then this is the apparent parent, i.e. the type the property appears to extend. + member ApparentEnclosingType: TType + + /// Try to get an arbitrary F# ValRef associated with the member. This is to determine if the member is virtual, amongst other things. + member ArbitraryValRef: ValRef option + + /// Get the declaring type or module holding the method. + /// Note that C#-style extension properties don't exist in the C# design as yet. + /// If this is an F#-style extension method it is the logical module + /// holding the value for the extension method. + member DeclaringTyconRef: EntityRef + + /// Return a new property info where there is no associated getter, only an associated setter. + /// + /// Property infos can combine getters and setters, assuming they are consistent w.r.t. 'virtual', indexer argument types etc. + /// When checking consistency we split these apart + member DropGetter: unit -> PropInfo + + /// Return a new property info where there is no associated setter, only an associated getter. + /// + /// Property infos can combine getters and setters, assuming they are consistent w.r.t. 'virtual', indexer argument types etc. + /// When checking consistency we split these apart + member DropSetter: unit -> PropInfo + + member GetterMethod: MethInfo + + /// Indicates if this property has an associated XML comment authored in this assembly. + member HasDirectXmlComment: bool + + /// Indicates if this property has an associated getter method. + member HasGetter: bool + + /// Indicates if this property has an associated setter method. + member HasSetter: bool + + member ImplementedSlotSignatures: SlotSig list + + /// Indicates if this property is marked 'override' and thus definitely overrides another property. + member IsDefiniteFSharpOverride: bool + + /// Indicates if the getter (or, if absent, the setter) for the property is a dispatch slot. + member IsDispatchSlot: bool + + /// Indicates if this is an extension member + member IsExtensionMember: bool + + /// Indicates if this is an F# property compiled as a CLI event, e.g. a [] property. + member IsFSharpEventProperty: bool + + member IsFSharpExplicitInterfaceImplementation: bool + + /// Indicates if this property is an indexer property, i.e. a property with arguments. + member IsIndexer: bool + + /// Indicates if the property is logically a 'newslot', i.e. hides any previous slots of the same name. + member IsNewSlot: bool + + /// Indicates if this property is static. + member IsStatic: bool + + /// Indicates if the enclosing type for the property is a value type. + /// + /// For an extension property, this indicates if the property extends a struct type. + member IsValueType: bool + + /// True if the getter (or, if absent, the setter) is a virtual method + member IsVirtualProperty: bool + + /// Get the logical name of the property. + member PropertyName: string + + /// Get a MethInfo for the 'setter' method associated with the property + member SetterMethod: MethInfo + + /// Get the TcGlobals associated with the object + member TcGlobals: TcGlobals + + /// Get the intra-assembly XML documentation for the property. + member XmlDoc: XmlDoc + + /// Test whether two property infos have the same underlying definition. + /// Uses the same techniques as 'MethInfosUseIdenticalDefinitions'. + /// Compatible with ItemsAreEffectivelyEqual relation. + static member PropInfosUseIdenticalDefinitions: x1:PropInfo -> x2:PropInfo -> bool + + /// Calculates a hash code of property info. Must be compatible with ItemsAreEffectivelyEqual relation. + member ComputeHashCode: unit -> int + + /// Get the details of the indexer parameters associated with the property + member GetParamDatas: amap:ImportMap * m:range -> ParamData list + + /// Get the names and types of the indexer parameters associated with the property + /// + /// If the property is in a generic type, then the type parameters are instantiated in the types returned. + member GetParamNamesAndTypes: amap:ImportMap * m:range -> ParamNameAndType list + + /// Get the types of the indexer parameters associated with the property + member GetParamTypes: amap:ImportMap * m:range -> TType list + + /// Get the result type of the property + member GetPropertyType: amap:ImportMap * m:range -> TType + +/// Describes an F# use of an event backed by Abstract IL metadata +[] +type ILEventInfo = + | ILEventInfo of ilTypeInfo: ILTypeInfo * ilEventDef: ILEventDef + + /// Get the ILMethInfo describing the 'add' method associated with the event + member AddMethod: ILMethInfo + + // Note: events are always associated with nominal types + member ApparentEnclosingAppType: TType + + /// Get the enclosing ("parent"/"declaring") type of the field. + member ApparentEnclosingType: TType + + // Note: IL Events are never extension members as C# has no notion of extension events as yet + member DeclaringTyconRef: TyconRef + + /// Get the declaring IL type of the event as an ILTypeInfo + member ILTypeInfo: ILTypeInfo + + /// Indicates if the property is static + member IsStatic: bool + + /// Get the name of the event + member EventName: string + + /// Get the raw Abstract IL metadata for the event + member RawMetadata: ILEventDef + + /// Get the ILMethInfo describing the 'remove' method associated with the event + member RemoveMethod: ILMethInfo + + member TcGlobals: TcGlobals + + /// Get the declaring type of the event as an ILTypeRef + member TypeRef: ILTypeRef + +/// Describes an F# use of an event +[] +type EventInfo = + /// An F# use of an event backed by F#-declared metadata + | FSEvent of tcGlobals: TcGlobals * propInfo: PropInfo * addMethod: ValRef * removeMethod: ValRef + + /// An F# use of an event backed by .NET metadata + | ILEvent of ilEventInfo: ILEventInfo + +#if !NO_EXTENSIONTYPING + /// An F# use of an event backed by provided metadata + | ProvidedEvent of amap: ImportMap * providedEvent: Tainted * range: range +#endif + + /// Get the enclosing type of the method info, using a nominal type for tuple types + member ApparentEnclosingAppType: TType + + member ApparentEnclosingTyconRef: TyconRef + + /// Get the enclosing type of the event. + /// + /// If this is an extension member, then this is the apparent parent, i.e. the type the event appears to extend. + member ApparentEnclosingType: TType + + /// Try to get an arbitrary F# ValRef associated with the member. This is to determine if the member is virtual, amongst other things. + member ArbitraryValRef: ValRef option + + /// Get the declaring type or module holding the method. + /// Note that C#-style extension properties don't exist in the C# design as yet. + /// If this is an F#-style extension method it is the logical module + /// holding the value for the extension method. + member DeclaringTyconRef: EntityRef + + /// Get the logical name of the event. + member EventName: string + + /// Indicates if this event has an associated XML comment authored in this assembly. + member HasDirectXmlComment: bool + + /// Indicates if this is an extension member + member IsExtensionMember: bool + + /// Indicates if this property is static. + member IsStatic: bool + + /// Indicates if the enclosing type for the event is a value type. + /// + /// For an extension event, this indicates if the event extends a struct type. + member IsValueType: bool + + /// Get the 'add' method associated with an event + member AddMethod: MethInfo + + /// Get the 'remove' method associated with an event + member RemoveMethod: MethInfo + + /// Get the TcGlobals associated with the object + member TcGlobals: TcGlobals + + /// Get the intra-assembly XML documentation for the property. + member XmlDoc: XmlDoc + + /// Test whether two event infos have the same underlying definition. + /// Compatible with ItemsAreEffectivelyEqual relation. + static member EventInfosUseIdenticalDefinitions: x1:EventInfo -> x2:EventInfo -> bool + + /// Calculates a hash code of event info (similar as previous) + /// Compatible with ItemsAreEffectivelyEqual relation. + member ComputeHashCode: unit -> int + + /// Get the delegate type associated with the event. + member GetDelegateType: amap:ImportMap * m:range -> TType + +/// An exception type used to raise an error using the old error system. +/// +/// Error text: "A definition to be compiled as a .NET event does not have the expected form. Only property members can be compiled as .NET events." +exception BadEventTransformation of range + +/// Create an error object to raise should an event not have the shape expected by the .NET idiom described further below +val nonStandardEventError: nm:System.String -> m:range -> exn + +/// Find the delegate type that an F# event property implements by looking through the type hierarchy of the type of the property +/// for the first instantiation of IDelegateEvent. +val FindDelegateTypeOfPropertyEvent: g:TcGlobals -> amap:ImportMap -> nm:System.String -> m:range -> ty:TType -> TType + +/// Strips inref and outref to be a byref. +val stripByrefTy: g:TcGlobals -> ty:TType -> TType + +/// Represents the information about the compiled form of a method signature. Used when analyzing implementation +/// relations between members and abstract slots. +type CompiledSig = CompiledSig of argTys: TType list list * returnTy: TType option * formalMethTypars: Typars * formalMethTyparInst: TyparInst + +/// Get the information about the compiled form of a method signature. Used when analyzing implementation +/// relations between members and abstract slots. +val CompiledSigOfMeth: g:TcGlobals -> amap:ImportMap -> m:range -> minfo:MethInfo -> CompiledSig + +/// Inref and outref parameter types will be treated as a byref type for equivalency. +val MethInfosEquivByPartialSig: erasureFlag:Erasure -> ignoreFinal:bool -> g:TcGlobals -> amap:ImportMap -> m:range -> minfo:MethInfo -> minfo2:MethInfo -> bool + +/// Used to hide/filter members from super classes based on signature +/// Inref and outref parameter types will be treated as a byref type for equivalency. +val MethInfosEquivByNameAndPartialSig: erasureFlag:Erasure -> ignoreFinal:bool -> g:TcGlobals -> amap:ImportMap -> m:range -> minfo:MethInfo -> minfo2:MethInfo -> bool + +/// Used to hide/filter members from super classes based on signature +val PropInfosEquivByNameAndPartialSig: erasureFlag:Erasure -> g:TcGlobals -> amap:ImportMap -> m:range -> pinfo:PropInfo -> pinfo2:PropInfo -> bool + +/// Used to hide/filter members from base classes based on signature +val MethInfosEquivByNameAndSig: erasureFlag:Erasure -> ignoreFinal:bool -> g:TcGlobals -> amap:ImportMap -> m:range -> minfo:MethInfo -> minfo2:MethInfo -> bool + +/// Used to hide/filter members from super classes based on signature +val PropInfosEquivByNameAndSig: erasureFlag:Erasure -> g:TcGlobals -> amap:ImportMap -> m:range -> pinfo:PropInfo -> pinfo2:PropInfo -> bool + +val SettersOfPropInfos: pinfos:PropInfo list -> (MethInfo * PropInfo option) list + +val GettersOfPropInfos: pinfos:PropInfo list -> (MethInfo * PropInfo option) list + diff --git a/src/fsharp/layout.fs b/src/fsharp/layout.fs deleted file mode 100644 index c54a545a2bb..00000000000 --- a/src/fsharp/layout.fs +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module FSharp.Compiler.Layout - -open System -open System.IO -open Internal.Utilities.StructuredFormat -open Microsoft.FSharp.Core.Printf - -#nowarn "62" // This construct is for ML compatibility. - -type layout = Internal.Utilities.StructuredFormat.Layout -type LayoutTag = Internal.Utilities.StructuredFormat.LayoutTag -type TaggedText = Internal.Utilities.StructuredFormat.TaggedText - -type NavigableTaggedText(taggedText: TaggedText, range: Range.range) = - member val Range = range - interface TaggedText with - member x.Tag = taggedText.Tag - member x.Text = taggedText.Text -let mkNav r t = NavigableTaggedText(t, r) :> TaggedText - -let spaces n = new String(' ', n) - - -//-------------------------------------------------------------------------- -// INDEX: support -//-------------------------------------------------------------------------- - -let rec juxtLeft = function - | ObjLeaf (jl, _text, _jr) -> jl - | Leaf (jl, _text, _jr) -> jl - | Node (jl, _l, _jm, _r, _jr, _joint) -> jl - | Attr (_tag, _attrs, l) -> juxtLeft l - -let rec juxtRight = function - | ObjLeaf (_jl, _text, jr) -> jr - | Leaf (_jl, _text, jr) -> jr - | Node (_jl, _l, _jm, _r, jr, _joint) -> jr - | Attr (_tag, _attrs, l) -> juxtRight l - -// NOTE: emptyL might be better represented as a constructor, so then (Sep"") would have true meaning -let emptyL = Leaf (true, Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Text "", true) -let isEmptyL = function Leaf(true, tag, true) when tag.Text = "" -> true | _ -> false - -let mkNode l r joint = - if isEmptyL l then r else - if isEmptyL r then l else - let jl = juxtLeft l - let jm = juxtRight l || juxtLeft r - let jr = juxtRight r - Node(jl, l, jm, r, jr, joint) - - -//-------------------------------------------------------------------------- -//INDEX: constructors -//-------------------------------------------------------------------------- - -let wordL (str:TaggedText) = Leaf (false, str, false) -let sepL (str:TaggedText) = Leaf (true, str, true) -let rightL (str:TaggedText) = Leaf (true, str, false) -let leftL (str:TaggedText) = Leaf (false, str, true) - -module TaggedTextOps = - let tagActivePatternCase = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.ActivePatternCase - let tagActivePatternResult = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.ActivePatternResult - let tagAlias = Internal.Utilities.StructuredFormat.TaggedTextOps.tagAlias - let tagClass = Internal.Utilities.StructuredFormat.TaggedTextOps.tagClass - let tagUnion = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Union - let tagUnionCase = Internal.Utilities.StructuredFormat.TaggedTextOps.tagUnionCase - let tagDelegate = Internal.Utilities.StructuredFormat.TaggedTextOps.tagDelegate - let tagEnum = Internal.Utilities.StructuredFormat.TaggedTextOps.tagEnum - let tagEvent = Internal.Utilities.StructuredFormat.TaggedTextOps.tagEvent - let tagField = Internal.Utilities.StructuredFormat.TaggedTextOps.tagField - let tagInterface = Internal.Utilities.StructuredFormat.TaggedTextOps.tagInterface - let tagKeyword = Internal.Utilities.StructuredFormat.TaggedTextOps.tagKeyword - let tagLineBreak = Internal.Utilities.StructuredFormat.TaggedTextOps.tagLineBreak - let tagLocal = Internal.Utilities.StructuredFormat.TaggedTextOps.tagLocal - let tagRecord = Internal.Utilities.StructuredFormat.TaggedTextOps.tagRecord - let tagRecordField = Internal.Utilities.StructuredFormat.TaggedTextOps.tagRecordField - let tagMethod = Internal.Utilities.StructuredFormat.TaggedTextOps.tagMethod - let tagMember = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.Member - let tagModule = Internal.Utilities.StructuredFormat.TaggedTextOps.tagModule - let tagModuleBinding = Internal.Utilities.StructuredFormat.TaggedTextOps.tagModuleBinding - let tagNamespace = Internal.Utilities.StructuredFormat.TaggedTextOps.tagNamespace - let tagNumericLiteral = Internal.Utilities.StructuredFormat.TaggedTextOps.tagNumericLiteral - let tagOperator = Internal.Utilities.StructuredFormat.TaggedTextOps.tagOperator - let tagParameter = Internal.Utilities.StructuredFormat.TaggedTextOps.tagParameter - let tagProperty = Internal.Utilities.StructuredFormat.TaggedTextOps.tagProperty - let tagSpace = Internal.Utilities.StructuredFormat.TaggedTextOps.tagSpace - let tagStringLiteral = Internal.Utilities.StructuredFormat.TaggedTextOps.tagStringLiteral - let tagStruct = Internal.Utilities.StructuredFormat.TaggedTextOps.tagStruct - let tagTypeParameter = Internal.Utilities.StructuredFormat.TaggedTextOps.tagTypeParameter - let tagText = Internal.Utilities.StructuredFormat.TaggedTextOps.tagText - let tagPunctuation = Internal.Utilities.StructuredFormat.TaggedTextOps.tagPunctuation - let tagUnknownEntity = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.UnknownEntity - let tagUnknownType = Internal.Utilities.StructuredFormat.TaggedTextOps.tag LayoutTag.UnknownType - - module Literals = - // common tagged literals - let lineBreak = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.lineBreak - let space = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.space - let comma = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.comma - let semicolon = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.semicolon - let leftParen = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftParen - let rightParen = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightParen - let leftBracket = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBracket - let rightBracket = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBracket - let leftBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBrace - let rightBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBrace - let leftBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBraceBar - let rightBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBraceBar - let equals = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.equals - let arrow = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.arrow - let questionMark = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.questionMark - let dot = tagPunctuation "." - let leftAngle = tagPunctuation "<" - let rightAngle = tagPunctuation ">" - let star = tagOperator "*" - let colon = tagPunctuation ":" - let minus = tagPunctuation "-" - let keywordNew = tagKeyword "new" - let leftBracketAngle = tagPunctuation "[<" - let rightBracketAngle = tagPunctuation ">]" - let structUnit = tagStruct "unit" - let keywordStatic = tagKeyword "static" - let keywordMember = tagKeyword "member" - let keywordVal = tagKeyword "val" - let keywordEvent = tagKeyword "event" - let keywordWith = tagKeyword "with" - let keywordSet = tagKeyword "set" - let keywordGet = tagKeyword "get" - let keywordTrue = tagKeyword "true" - let keywordFalse = tagKeyword "false" - let bar = tagPunctuation "|" - let keywordStruct = tagKeyword "struct" - let keywordInherit = tagKeyword "inherit" - let keywordEnd = tagKeyword "end" - let keywordNested = tagKeyword "nested" - let keywordType = tagKeyword "type" - let keywordDelegate = tagKeyword "delegate" - let keywordOf = tagKeyword "of" - let keywordInternal = tagKeyword "internal" - let keywordPrivate = tagKeyword "private" - let keywordAbstract = tagKeyword "abstract" - let keywordOverride = tagKeyword "override" - let keywordEnum = tagKeyword "enum" - let leftBracketBar = tagPunctuation "[|" - let rightBracketBar = tagPunctuation "|]" - let keywordTypeof = tagKeyword "typeof" - let keywordTypedefof = tagKeyword "typedefof" - -open TaggedTextOps - -module SepL = - let dot = sepL Literals.dot - let star = sepL Literals.star - let colon = sepL Literals.colon - let questionMark = sepL Literals.questionMark - let leftParen = sepL Literals.leftParen - let comma = sepL Literals.comma - let space = sepL Literals.space - let leftBracket = sepL Literals.leftBracket - let leftAngle = sepL Literals.leftAngle - let lineBreak = sepL Literals.lineBreak - let rightParen = sepL Literals.rightParen - -module WordL = - let arrow = wordL Literals.arrow - let star = wordL Literals.star - let colon = wordL Literals.colon - let equals = wordL Literals.equals - let keywordNew = wordL Literals.keywordNew - let structUnit = wordL Literals.structUnit - let keywordStatic = wordL Literals.keywordStatic - let keywordMember = wordL Literals.keywordMember - let keywordVal = wordL Literals.keywordVal - let keywordEvent = wordL Literals.keywordEvent - let keywordWith = wordL Literals.keywordWith - let keywordSet = wordL Literals.keywordSet - let keywordGet = wordL Literals.keywordGet - let keywordTrue = wordL Literals.keywordTrue - let keywordFalse = wordL Literals.keywordFalse - let bar = wordL Literals.bar - let keywordStruct = wordL Literals.keywordStruct - let keywordInherit = wordL Literals.keywordInherit - let keywordEnd = wordL Literals.keywordEnd - let keywordNested = wordL Literals.keywordNested - let keywordType = wordL Literals.keywordType - let keywordDelegate = wordL Literals.keywordDelegate - let keywordOf = wordL Literals.keywordOf - let keywordInternal = wordL Literals.keywordInternal - let keywordPrivate = wordL Literals.keywordPrivate - let keywordAbstract = wordL Literals.keywordAbstract - let keywordOverride = wordL Literals.keywordOverride - let keywordEnum = wordL Literals.keywordEnum - -module LeftL = - let leftParen = leftL Literals.leftParen - let questionMark = leftL Literals.questionMark - let colon = leftL Literals.colon - let leftBracketAngle = leftL Literals.leftBracketAngle - let leftBracketBar = leftL Literals.leftBracketBar - let keywordTypeof = leftL Literals.keywordTypeof - let keywordTypedefof = leftL Literals.keywordTypedefof - -module RightL = - let comma = rightL Literals.comma - let rightParen = rightL Literals.rightParen - let colon = rightL Literals.colon - let rightBracket = rightL Literals.rightBracket - let rightAngle = rightL Literals.rightAngle - let rightBracketAngle = rightL Literals.rightBracketAngle - let rightBracketBar = rightL Literals.rightBracketBar - -let aboveL l r = mkNode l r (Broken 0) - -let tagAttrL str attrs ly = Attr (str, attrs, ly) - -//-------------------------------------------------------------------------- -//INDEX: constructors derived -//-------------------------------------------------------------------------- - -let apply2 f l r = if isEmptyL l then r else - if isEmptyL r then l else f l r - -let (^^) l r = mkNode l r (Unbreakable) -let (++) l r = mkNode l r (Breakable 0) -let (--) l r = mkNode l r (Breakable 1) -let (---) l r = mkNode l r (Breakable 2) -let (----) l r = mkNode l r (Breakable 3) -let (-----) l r = mkNode l r (Breakable 4) -let (@@) l r = apply2 (fun l r -> mkNode l r (Broken 0)) l r -let (@@-) l r = apply2 (fun l r -> mkNode l r (Broken 1)) l r -let (@@--) l r = apply2 (fun l r -> mkNode l r (Broken 2)) l r - -let tagListL tagger = function - | [] -> emptyL - | [x] -> x - | x :: xs -> - let rec process' prefixL = function - | [] -> prefixL - | y :: ys -> process' ((tagger prefixL) ++ y) ys in - process' x xs - -let commaListL x = tagListL (fun prefixL -> prefixL ^^ rightL Literals.comma) x -let semiListL x = tagListL (fun prefixL -> prefixL ^^ rightL Literals.semicolon) x -let spaceListL x = tagListL (fun prefixL -> prefixL) x -let sepListL x y = tagListL (fun prefixL -> prefixL ^^ x) y - -let bracketL l = leftL Literals.leftParen ^^ l ^^ rightL Literals.rightParen -let tupleL xs = bracketL (sepListL (sepL Literals.comma) xs) -let aboveListL = function - | [] -> emptyL - | [x] -> x - | x :: ys -> List.fold (fun pre y -> pre @@ y) x ys - -let optionL xL = function - | None -> wordL (tagUnionCase "None") - | Some x -> wordL (tagUnionCase "Some") -- (xL x) - -let listL xL xs = leftL Literals.leftBracket ^^ sepListL (sepL Literals.semicolon) (List.map xL xs) ^^ rightL Literals.rightBracket - - -//-------------------------------------------------------------------------- -//INDEX: breaks v2 -//-------------------------------------------------------------------------- - -// A very quick implementation of break stack. -type breaks = Breaks of - /// pos of next free slot - int * - /// pos of next possible "outer" break - OR - outer=next if none possible - int * - /// stack of savings, -ve means it has been broken - int array - -// next is next slot to push into - aka size of current occupied stack. -// outer counts up from 0, and is next slot to break if break forced. -// - if all breaks forced, then outer=next. -// - popping under these conditions needs to reduce outer and next. -let chunkN = 400 -let breaks0 () = Breaks(0, 0, Array.create chunkN 0) -let pushBreak saving (Breaks(next, outer, stack)) = - let stack = if next = stack.Length then - Array.append stack (Array.create chunkN 0) (* expand if full *) - else - stack - stack.[next] <- saving - Breaks(next+1, outer, stack) - -let popBreak (Breaks(next, outer, stack)) = - if next=0 then raise (Failure "popBreak: underflow") - let topBroke = stack.[next-1] < 0 - let outer = if outer=next then outer-1 else outer (* if all broken, unwind *) - let next = next - 1 - Breaks(next, outer, stack), topBroke - -let forceBreak (Breaks(next, outer, stack)) = - if outer=next then - (* all broken *) - None - else - let saving = stack.[outer] - stack.[outer] <- -stack.[outer] - let outer = outer+1 - Some (Breaks(next, outer, stack), saving) - -let squashTo maxWidth layout = - // breaks = break context, can force to get indentation savings. - // pos = current position in line - // layout = to fit - //------ - // returns: - // breaks - // layout - with breaks put in to fit it. - // pos - current pos in line = rightmost position of last line of block. - // offset - width of last line of block - // NOTE: offset <= pos -- depending on tabbing of last block - let rec fit breaks (pos, layout) = - (*printf "\n\nCalling pos=%d layout=[%s]\n" pos (showL layout)*) - let breaks, layout, pos, offset = - match layout with - | ObjLeaf _ -> failwith "ObjLeaf should not appear here" - | Attr (tag, attrs, l) -> - let breaks, layout, pos, offset = fit breaks (pos, l) - let layout = Attr (tag, attrs, layout) - breaks, layout, pos, offset - | Leaf (_jl, taggedText, _jr) -> - let textWidth = taggedText.Text.Length - let rec fitLeaf breaks pos = - if pos + textWidth <= maxWidth then - breaks, layout, pos + textWidth, textWidth (* great, it fits *) - else - match forceBreak breaks with - None -> (breaks, layout, pos + textWidth, textWidth (* tough, no more breaks *)) - | Some (breaks, saving) -> (let pos = pos - saving in fitLeaf breaks pos) - fitLeaf breaks pos - - | Node (jl, l, jm, r, jr, joint) -> - let mid = if jm then 0 else 1 - match joint with - | Unbreakable -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - let pos = pos + mid (* fit space if juxt says so *) - let breaks, r, pos, offsetr = fit breaks (pos, r) (* fit right *) - breaks, Node (jl, l, jm, r, jr, Unbreakable), pos, offsetl + mid + offsetr - | Broken indent -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - let pos = pos - offsetl + indent (* broken so - offset left + indent *) - let breaks, r, pos, offsetr = fit breaks (pos, r) (* fit right *) - breaks, Node (jl, l, jm, r, jr, Broken indent), pos, indent + offsetr - | Breakable indent -> - let breaks, l, pos, offsetl = fit breaks (pos, l) (* fit left *) - (* have a break possibility, with saving *) - let saving = offsetl + mid - indent - let pos = pos + mid - if saving>0 then - let breaks = pushBreak saving breaks - let breaks, r, pos, offsetr = fit breaks (pos, r) - let breaks, broken = popBreak breaks - if broken then - breaks, Node (jl, l, jm, r, jr, Broken indent), pos, indent + offsetr - else - breaks, Node (jl, l, jm, r, jr, Breakable indent), pos, offsetl + mid + offsetr - else - (* actually no saving so no break *) - let breaks, r, pos, offsetr = fit breaks (pos, r) - breaks, Node (jl, l, jm, r, jr, Breakable indent), pos, offsetl + mid + offsetr - (*printf "\nDone: pos=%d offset=%d" pos offset*) - breaks, layout, pos, offset - let breaks = breaks0 () - let pos = 0 - let _breaks, layout, _pos, _offset = fit breaks (pos, layout) - layout - -//-------------------------------------------------------------------------- -//INDEX: LayoutRenderer -//-------------------------------------------------------------------------- - -type LayoutRenderer<'a, 'b> = - abstract Start : unit -> 'b - abstract AddText : 'b -> TaggedText -> 'b - abstract AddBreak : 'b -> int -> 'b - abstract AddTag : 'b -> string * (string * string) list * bool -> 'b - abstract Finish : 'b -> 'a - -let renderL (rr: LayoutRenderer<_, _>) layout = - let rec addL z pos i layout k = - match layout with - | ObjLeaf _ -> failwith "ObjLeaf should never appear here" - (* pos is tab level *) - | Leaf (_, text, _) -> - k(rr.AddText z text, i + text.Text.Length) - | Node (_, l, _, r, _, Broken indent) -> - addL z pos i l <| - fun (z, _i) -> - let z, i = rr.AddBreak z (pos+indent), (pos+indent) - addL z (pos+indent) i r k - | Node (_, l, jm, r, _, _) -> - addL z pos i l <| - fun (z, i) -> - let z, i = if jm then z, i else rr.AddText z Literals.space, i+1 - let pos = i - addL z pos i r k - | Attr (tag, attrs, l) -> - let z = rr.AddTag z (tag, attrs, true) - addL z pos i l <| - fun (z, i) -> - let z = rr.AddTag z (tag, attrs, false) - k(z, i) - let pos = 0 - let z, i = rr.Start(), 0 - let z, _i = addL z pos i layout id - rr.Finish z - -/// string render -let stringR = - { new LayoutRenderer with - member x.Start () = [] - member x.AddText rstrs taggedText = taggedText.Text :: rstrs - member x.AddBreak rstrs n = (spaces n) :: "\n" :: rstrs - member x.AddTag z (_, _, _) = z - member x.Finish rstrs = String.Join("", Array.ofList (List.rev rstrs)) } - -type NoState = NoState -type NoResult = NoResult - -/// string render -let taggedTextListR collector = - { new LayoutRenderer with - member x.Start () = NoState - member x.AddText z text = collector text; z - member x.AddBreak rstrs n = collector Literals.lineBreak; collector (tagSpace(spaces n)); rstrs - member x.AddTag z (_, _, _) = z - member x.Finish rstrs = NoResult } - - -/// channel LayoutRenderer -let channelR (chan:TextWriter) = - { new LayoutRenderer with - member r.Start () = NoState - member r.AddText z s = chan.Write s.Text; z - member r.AddBreak z n = chan.WriteLine(); chan.Write (spaces n); z - member r.AddTag z (tag, attrs, start) = z - member r.Finish z = NoResult } - -/// buffer render -let bufferR os = - { new LayoutRenderer with - member r.Start () = NoState - member r.AddText z s = bprintf os "%s" s.Text; z - member r.AddBreak z n = bprintf os "\n"; bprintf os "%s" (spaces n); z - member r.AddTag z (tag, attrs, start) = z - member r.Finish z = NoResult } - -//-------------------------------------------------------------------------- -//INDEX: showL, outL are most common -//-------------------------------------------------------------------------- - -let showL layout = renderL stringR layout -let outL (chan:TextWriter) layout = renderL (channelR chan) layout |> ignore -let bufferL os layout = renderL (bufferR os) layout |> ignore \ No newline at end of file diff --git a/src/fsharp/layout.fsi b/src/fsharp/layout.fsi deleted file mode 100644 index 00831d49ca6..00000000000 --- a/src/fsharp/layout.fsi +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module public FSharp.Compiler.Layout - -open System.Text -open System.Collections.Generic -open System.IO -open Internal.Utilities.StructuredFormat -open Internal.Utilities.StructuredFormat.TaggedTextOps - -type layout = Internal.Utilities.StructuredFormat.Layout -type LayoutTag = Internal.Utilities.StructuredFormat.LayoutTag -type TaggedText = Internal.Utilities.StructuredFormat.TaggedText - -type NavigableTaggedText = - new : TaggedText * Range.range -> NavigableTaggedText - member Range: Range.range - interface TaggedText -val mkNav : Range.range -> TaggedText -> TaggedText - -module TaggedTextOps = Internal.Utilities.StructuredFormat.TaggedTextOps - -val emptyL : Layout -val isEmptyL : Layout -> bool - -val wordL : TaggedText -> Layout -val sepL : TaggedText -> Layout -val rightL : TaggedText -> Layout -val leftL : TaggedText -> Layout -val ( ^^ ) : Layout -> Layout -> Layout (* never break "glue" *) -val ( ++ ) : Layout -> Layout -> Layout (* if break, indent=0 *) -val ( -- ) : Layout -> Layout -> Layout (* if break, indent=1 *) -val ( --- ) : Layout -> Layout -> Layout (* if break, indent=2 *) -val ( ---- ) : Layout -> Layout -> Layout (* if break, indent=2 *) -val ( ----- ) : Layout -> Layout -> Layout (* if break, indent=2 *) -val ( @@ ) : Layout -> Layout -> Layout (* broken ident=0 *) -val ( @@- ) : Layout -> Layout -> Layout (* broken ident=1 *) -val ( @@-- ) : Layout -> Layout -> Layout (* broken ident=2 *) - -val commaListL : Layout list -> Layout -val spaceListL : Layout list -> Layout -val semiListL : Layout list -> Layout -val sepListL : Layout -> Layout list -> Layout - -val bracketL : Layout -> Layout -val tupleL : Layout list -> Layout -val aboveL : Layout -> Layout -> Layout -val aboveListL : Layout list -> Layout - -val optionL : ('a -> Layout) -> 'a option -> Layout -val listL : ('a -> Layout) -> 'a list -> Layout - -val squashTo : int -> Layout -> Layout - -val showL : Layout -> string -val outL : TextWriter -> Layout -> unit -val bufferL : StringBuilder -> Layout -> unit - -module TaggedTextOps = - val tagActivePatternCase : (string -> TaggedText) - val tagActivePatternResult : (string -> TaggedText) - val tagAlias : (string -> TaggedText) - val tagClass : (string -> TaggedText) - val tagUnion : (string -> TaggedText) - val tagUnionCase : (string -> TaggedText) - val tagDelegate : (string -> TaggedText) - val tagEnum : (string -> TaggedText) - val tagEvent : (string -> TaggedText) - val tagField : (string -> TaggedText) - val tagInterface : (string -> TaggedText) - val tagKeyword : (string -> TaggedText) - val tagLineBreak : (string -> TaggedText) - val tagMethod : (string -> TaggedText) - val tagLocal : (string -> TaggedText) - val tagRecord : (string -> TaggedText) - val tagRecordField : (string -> TaggedText) - val tagModule : (string -> TaggedText) - val tagModuleBinding : (string -> TaggedText) - val tagMember : (string -> TaggedText) - val tagNamespace : (string -> TaggedText) - val tagNumericLiteral : (string -> TaggedText) - val tagOperator : (string -> TaggedText) - val tagParameter : (string -> TaggedText) - val tagProperty : (string -> TaggedText) - val tagSpace : (string -> TaggedText) - val tagStringLiteral : (string -> TaggedText) - val tagStruct : (string -> TaggedText) - val tagTypeParameter : (string -> TaggedText) - val tagText : (string -> TaggedText) - val tagPunctuation : (string -> TaggedText) - val tagUnknownEntity : (string -> TaggedText) - val tagUnknownType : (string -> TaggedText) - - module Literals = - // common tagged literals - val lineBreak : TaggedText - val space : TaggedText - val comma : TaggedText - val dot : TaggedText - val semicolon : TaggedText - val leftParen : TaggedText - val rightParen : TaggedText - val leftBracket : TaggedText - val rightBracket : TaggedText - val leftBrace: TaggedText - val rightBrace : TaggedText - val leftBraceBar: TaggedText - val rightBraceBar : TaggedText - val leftAngle: TaggedText - val rightAngle: TaggedText - val equals : TaggedText - val arrow : TaggedText - val questionMark : TaggedText - val colon: TaggedText - val minus: TaggedText - val keywordTrue: TaggedText - val keywordFalse: TaggedText - -module SepL = - val dot: Layout - val star: Layout - val colon: Layout - val questionMark: Layout - val leftParen: Layout - val comma: Layout - val space: Layout - val leftBracket: Layout - val leftAngle: Layout - val lineBreak: Layout - val rightParen: Layout - -module WordL = - val arrow: Layout - val star: Layout - val colon: Layout - val equals: Layout - val keywordNew: Layout - val structUnit: Layout - val keywordStatic: Layout - val keywordMember: Layout - val keywordVal: Layout - val keywordEvent: Layout - val keywordWith: Layout - val keywordSet: Layout - val keywordGet: Layout - val keywordTrue: Layout - val keywordFalse: Layout - val bar: Layout - val keywordStruct: Layout - val keywordInherit: Layout - val keywordEnd: Layout - val keywordNested: Layout - val keywordType: Layout - val keywordDelegate: Layout - val keywordOf: Layout - val keywordInternal: Layout - val keywordPrivate: Layout - val keywordAbstract: Layout - val keywordOverride: Layout - val keywordEnum: Layout - -module LeftL = - val leftParen: Layout - val questionMark: Layout - val colon: Layout - val leftBracketAngle: Layout - val leftBracketBar: Layout - val keywordTypeof: Layout - val keywordTypedefof: Layout - -module RightL = - val comma: Layout - val rightParen: Layout - val colon: Layout - val rightBracket: Layout - val rightAngle: Layout - val rightBracketAngle: Layout - val rightBracketBar: Layout - -/// render a Layout yielding an 'a using a 'b (hidden state) type -type LayoutRenderer<'a,'b> = - abstract Start : unit -> 'b - abstract AddText : 'b -> TaggedText -> 'b - abstract AddBreak : 'b -> int -> 'b - abstract AddTag : 'b -> string * (string * string) list * bool -> 'b - abstract Finish : 'b -> 'a - -type NoState = NoState -type NoResult = NoResult - -/// Run a render on a Layout -val renderL : LayoutRenderer<'b,'a> -> Layout -> 'b - -/// Primitive renders -val stringR : LayoutRenderer -val channelR : TextWriter -> LayoutRenderer -val bufferR : StringBuilder -> LayoutRenderer -val taggedTextListR : collector: (TaggedText -> unit) -> LayoutRenderer - diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl index 901a203b832..f726fcafbd8 100644 --- a/src/fsharp/lex.fsl +++ b/src/fsharp/lex.fsl @@ -5,41 +5,64 @@ module internal FSharp.Compiler.Lexer //------------------------------------------------------------------------ -// The Lexer. Some of the complication arises from the fact it is -// reused by the Visual Studio mode to do partial lexing reporting +// The Lexer. Some of the complication arises from the fact it is +// reused by the Visual Studio mode to do partial lexing reporting // whitespace etc. //----------------------------------------------------------------------- open System open System.Globalization open System.Text + open Internal.Utilities +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open Internal.Utilities.Text.Lexing -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler - -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.AbstractIL open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features -open FSharp.Compiler.Parser +open FSharp.Compiler.IO open FSharp.Compiler.Lexhelp -open FSharp.Compiler.Lib -open Internal.Utilities.Text.Lexing +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Parser +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range + +module Ranges = + /// Whether valid as signed int8 when a minus sign is prepended, compares true to 0x80 + let isInt8BadMax x = 1 <<< 7 = x + + /// Whether valid as signed int16 when a minus sign is prepended, compares true to 0x8000 + let isInt16BadMax x = 1 <<< 15 = x + /// Whether valid as signed int32 when a minus sign is prepended, compares as string against "2147483648". + let isInt32BadMax = let max = string(1UL <<< 31) in fun s -> max = s + + /// Whether valid as signed int64 when a minus sign is prepended, compares as string against "9223372036854775808". + let isInt64BadMax = let max = string(1UL <<< 63) in fun s -> max = s + +/// Get string from lexbuf let lexeme (lexbuf : UnicodeLexing.Lexbuf) = UnicodeLexing.Lexbuf.LexemeString lexbuf -let trimBoth (s:string) n m = s.Substring(n, s.Length - (n+m)) -let lexemeTrimBoth lexbuf n m = trimBoth (lexeme lexbuf) n m +/// Trim n chars from both sides of lexbuf, return string +let lexemeTrimBoth (lexbuf : UnicodeLexing.Lexbuf) (n:int) (m:int) = + let s = lexbuf.LexemeView + s.Slice(n, s.Length - (n+m)).ToString() + +/// Trim n chars from the right of lexbuf, return string let lexemeTrimRight lexbuf n = lexemeTrimBoth lexbuf 0 n + +/// Trim n chars from the left of lexbuf, return string let lexemeTrimLeft lexbuf n = lexemeTrimBoth lexbuf n 0 +/// Throw a lexing error with a message let fail args (lexbuf:UnicodeLexing.Lexbuf) msg dflt = let m = lexbuf.LexemeRange args.errorLogger.ErrorR(Error(msg,m)) - dflt + dflt //-------------------------- // Integer parsing @@ -49,25 +72,26 @@ let fail args (lexbuf:UnicodeLexing.Lexbuf) msg dflt = // version of the F# core library parsing code with the call to "Trim" // removed, which appears in profiling runs as a small but significant cost. -let getSign32 (s:string) (p:byref) l = - if (l >= p + 1 && s.[p] = '-') - then p <- p + 1; -1 - else 1 +let getSign32 (s:string) (p:byref) l = + if (l >= p + 1 && s.[p] = '-') + then p <- p + 1; -1 + else 1 -let isOXB c = +let isOXB c = let c = Char.ToLowerInvariant c c = 'x' || c = 'o' || c = 'b' -let is0OXB (s:string) p l = +let is0OXB (s:string) p l = l >= p + 2 && s.[p] = '0' && isOXB s.[p+1] -let get0OXB (s:string) (p:byref) l = + +let get0OXB (s:string) (p:byref) l = if is0OXB s p l then let r = Char.ToLowerInvariant s.[p+1] in p <- p + 2; r - else 'd' + else 'd' let formatError() = raise (new System.FormatException(SR.GetString("bad format string"))) -let parseBinaryUInt64 (s:string) = +let parseBinaryUInt64 (s:string) = Convert.ToUInt64(s, 2) let parseOctalUInt64 (s:string) = @@ -78,553 +102,861 @@ let removeUnderscores (s:string) = | null -> null | s -> s.Replace("_", "") -let parseInt32 (s:string) = +let parseInt32 (s:string) = let s = removeUnderscores s - let l = s.Length - let mutable p = 0 - let sign = getSign32 s &p l - let specifier = get0OXB s &p l - match Char.ToLower(specifier,CultureInfo.InvariantCulture) with + let l = s.Length + let mutable p = 0 + let sign = getSign32 s &p l + let specifier = get0OXB s &p l + match Char.ToLower(specifier,CultureInfo.InvariantCulture) with | 'x' -> sign * (int32 (Convert.ToUInt32(UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)))) | 'b' -> sign * (int32 (Convert.ToUInt32(parseBinaryUInt64 (s.Substring(p))))) | 'o' -> sign * (int32 (Convert.ToUInt32(parseOctalUInt64 (s.Substring(p))))) | _ -> Int32.Parse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture) - -let lexemeTrimRightToInt32 args lexbuf n = + +let lexemeTrimRightToInt32 args lexbuf n = try parseInt32 (lexemeTrimRight lexbuf n) with _ -> fail args lexbuf (FSComp.SR.lexOutsideIntegerRange()) 0 //-------------------------- // Checks -let checkExprOp (lexbuf:UnicodeLexing.Lexbuf) = - if String.contains (lexeme lexbuf) ':' then +let checkExprOp (lexbuf:UnicodeLexing.Lexbuf) = + if lexbuf.LexemeContains ':' then deprecatedWithError (FSComp.SR.lexCharNotAllowedInOperatorNames(":")) lexbuf.LexemeRange - if String.contains (lexeme lexbuf) '$' then - deprecatedWithError (FSComp.SR.lexCharNotAllowedInOperatorNames("$")) lexbuf.LexemeRange + if lexbuf.LexemeContains '$' then + deprecatedWithError (FSComp.SR.lexCharNotAllowedInOperatorNames("$")) lexbuf.LexemeRange let unexpectedChar lexbuf = LEX_FAILURE (FSComp.SR.lexUnexpectedChar(lexeme lexbuf)) +/// Arbitrary value +[] +let StringCapacity = 100 + let startString args (lexbuf: UnicodeLexing.Lexbuf) = - let buf = ByteBuffer.Create 100 - let m = lexbuf.LexemeRange - let startp = lexbuf.StartPos - let fin = (fun _m2 b s -> - // Adjust the start-of-token mark back to the true start of the token - lexbuf.StartPos <- startp - if b then - if Lexhelp.stringBufferIsBytes buf then - BYTEARRAY (Lexhelp.stringBufferAsBytes buf) - else ( - fail args lexbuf (FSComp.SR.lexByteArrayCannotEncode()) () - BYTEARRAY (Lexhelp.stringBufferAsBytes buf) - ) - else - STRING (Lexhelp.stringBufferAsString s)) + let buf = ByteBuffer.Create StringCapacity + let m = lexbuf.LexemeRange + let startp = lexbuf.StartPos + let fin = + LexerStringFinisher (fun buf kind context cont -> + // Adjust the start-of-token mark back to the true start of the token + lexbuf.StartPos <- startp + let isPart = context.HasFlag(LexerStringFinisherContext.InterpolatedPart) + let isVerbatim = context.HasFlag(LexerStringFinisherContext.Verbatim) + let isTripleQuote = context.HasFlag(LexerStringFinisherContext.TripleQuote) + + if kind.IsByteString then + let synByteStringKind = if isVerbatim then SynByteStringKind.Verbatim else SynByteStringKind.Regular + if kind.IsInterpolated then + fail args lexbuf (FSComp.SR.lexByteStringMayNotBeInterpolated()) () + BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont) + elif Lexhelp.stringBufferIsBytes buf then + BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont) + else + fail args lexbuf (FSComp.SR.lexByteArrayCannotEncode()) () + BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont) + elif kind.IsInterpolated then + let s = Lexhelp.stringBufferAsString buf + if kind.IsInterpolatedFirst then + let synStringKind = + if isTripleQuote then + SynStringKind.TripleQuote + elif isVerbatim then + SynStringKind.Verbatim + else + SynStringKind.Regular + if isPart then + INTERP_STRING_BEGIN_PART (s, synStringKind, cont) + else + INTERP_STRING_BEGIN_END (s, synStringKind, cont) + else + if isPart then + INTERP_STRING_PART (s, cont) + else + INTERP_STRING_END (s, cont) + else + let s = Lexhelp.stringBufferAsString buf + let synStringKind = + if isVerbatim then + SynStringKind.Verbatim + elif isTripleQuote then + SynStringKind.TripleQuote + else + SynStringKind.Regular + STRING (s, synStringKind, cont)) buf,fin,m - -// Utility functions for processing XML documentation - -let trySaveXmlDoc lexbuf (buff:option) = - match buff with - | None -> () - | Some sb -> LexbufLocalXmlDocStore.SaveXmlDocLine (lexbuf, sb.ToString(), posOfLexPosition lexbuf.StartPos) - -let tryAppendXmlDoc (buff:option) (s:string) = - match buff with + + +// Utility functions for processing XML documentation + +let trySaveXmlDoc (lexbuf: LexBuffer) (buff: (range * StringBuilder) option) = + match buff with | None -> () - | Some sb -> ignore(sb.Append s) + | Some (start, sb) -> + let xmlCommentLineRange = mkFileIndexRange start.FileIndex start.Start (posOfLexPosition lexbuf.StartPos) + LexbufLocalXmlDocStore.SaveXmlDocLine (lexbuf, sb.ToString(), xmlCommentLineRange) -// Utilities for parsing #if/#else/#endif +let tryAppendXmlDoc (buff: (range * StringBuilder) option) (s:string) = + match buff with + | None -> () + | Some (_, sb) -> ignore(sb.Append s) + +// Utilities for parsing #if/#else/#endif -let shouldStartLine args lexbuf (m:range) err tok = +let shouldStartLine args lexbuf (m:range) err tok = if (m.StartColumn <> 0) then fail args lexbuf err tok else tok -let shouldStartFile args lexbuf (m:range) err tok = +let shouldStartFile args lexbuf (m:range) err tok = if (m.StartColumn <> 0 || m.StartLine <> 1) then fail args lexbuf err tok else tok -let evalIfDefExpression startPos isFeatureSupported args (lookup:string->bool) (lexed:string) = - let lexbuf = LexBuffer.FromChars (isFeatureSupported, lexed.ToCharArray ()) +let evalIfDefExpression startPos reportLibraryOnlyFeatures langVersion args (lookup:string->bool) (lexed:string) = + let lexbuf = LexBuffer.FromChars (reportLibraryOnlyFeatures, langVersion, lexed.ToCharArray ()) lexbuf.StartPos <- startPos lexbuf.EndPos <- startPos let tokenStream = FSharp.Compiler.PPLexer.tokenstream args let expr = FSharp.Compiler.PPParser.start tokenStream lexbuf LexerIfdefEval lookup expr +let evalFloat args lexbuf = + try + float32(removeUnderscores (lexemeTrimRight lexbuf 1)) + with _ -> + fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0.0f + } + let letter = '\Lu' | '\Ll' | '\Lt' | '\Lm' | '\Lo' | '\Nl' + let surrogateChar = '\Cs' + let digit = '\Nd' + let hex = ['0'-'9'] | ['A'-'F'] | ['a'-'f'] + let truewhite = [' '] + let offwhite = ['\t'] + let anywhite = truewhite | offwhite + let anychar = [^'\n''\r'] + let anystring = anychar* + let op_char = '!'|'$'|'%'|'&'|'*'|'+'|'-'|'.'|'/'|'<'|'='|'>'|'?'|'@'|'^'|'|'|'~'|':' + let ignored_op_char = '.' | '$' | '?' + let separator = '_' -let xinteger = + +let xinteger = ( '0' ('x'| 'X') hex ((hex | separator)* hex)? | '0' ('o'| 'O') (['0'-'7']) (((['0'-'7']) | separator)* (['0'-'7']))? | '0' ('b'| 'B') (['0'-'1']) (((['0'-'1']) | separator)* (['0'-'1']))?) + let integer = digit ((digit | separator)* digit)? + let int8 = integer 'y' -let uint8 = (xinteger | integer) 'u' 'y' + +let uint8 = (xinteger | integer) 'u' 'y' + let int16 = integer 's' + let uint16 = (xinteger | integer) 'u' 's' -let int = integer + +let int = integer + let int32 = integer 'l' -let uint32 = (xinteger | integer) 'u' + +let uint32 = (xinteger | integer) 'u' + let uint32l = (xinteger | integer) 'u' 'l' + let nativeint = (xinteger | integer) 'n' + let unativeint = (xinteger | integer) 'u' 'n' -let int64 = (xinteger | integer) 'L' -let uint64 = (xinteger | integer) ('u' | 'U') 'L' + +let int64 = (xinteger | integer) 'L' + +let uint64 = (xinteger | integer) ('u' | 'U') 'L' + let xint8 = xinteger 'y' + let xint16 = xinteger 's' -let xint = xinteger + +let xint = xinteger + let xint32 = xinteger 'l' -let floatp = digit ((digit | separator)* digit)? '.' (digit ((digit | separator)* digit)?)? + +let floatp = digit ((digit | separator)* digit)? '.' (digit ((digit | separator)* digit)?)? + let floate = digit ((digit | separator)* digit)? ('.' (digit ((digit | separator)* digit)?)? )? ('e'| 'E') ['+' '-']? digit ((digit | separator)* digit)? -let float = floatp | floate + +let float = floatp | floate + let bignum = integer ('I' | 'N' | 'Z' | 'Q' | 'R' | 'G') + let ieee64 = float -let ieee32 = (float | integer) ('f' | 'F') + +let ieee32 = float ('f' | 'F') + +let ieee32_dotless_no_exponent = integer ('f' | 'F') + let decimal = (float | integer) ('m' | 'M') + let xieee32 = xinteger 'l' 'f' + let xieee64 = xinteger 'L' 'F' + let escape_char = ('\\' ( '\\' | "\"" | '\'' | 'a' | 'f' | 'v' | 'n' | 't' | 'b' | 'r')) + let char = '\'' ( [^'\\''\n''\r''\t''\b'] | escape_char) '\'' + let trigraph = '\\' digit digit digit -let hexGraphShort = '\\' 'x' hex hex + +let hexGraphShort = '\\' 'x' hex hex + let unicodeGraphShort = '\\' 'u' hex hex hex hex + let unicodeGraphLong = '\\' 'U' hex hex hex hex hex hex hex hex + let newline = ('\n' | '\r' '\n') let connecting_char = '\Pc' + let combining_char = '\Mn' | '\Mc' -let formatting_char = '\Cf' -let ident_start_char = +let formatting_char = '\Cf' + +let ident_start_char = letter | '_' -let ident_char = +let ident_char = letter - | connecting_char - | combining_char - | formatting_char - | digit + | connecting_char + | combining_char + | formatting_char + | digit | ['\''] - + let ident = ident_start_char ident_char* rule token args skip = parse - | ident + | ident { Keywords.KeywordOrIdentifierToken args lexbuf (lexeme lexbuf) } - | "do!" - { DO_BANG } - | "yield!" - { YIELD_BANG(true) } - | "return!" - { YIELD_BANG(false) } + + | "do!" + { DO_BANG } + + | "yield!" + { YIELD_BANG(true) } + + | "return!" + { YIELD_BANG(false) } + | "match!" { MATCH_BANG } - | ident '!' - { let tok = Keywords.KeywordOrIdentifierToken args lexbuf (lexemeTrimRight lexbuf 1) - match tok with - | LET _ -> BINDER (lexemeTrimRight lexbuf 1) - | _ -> fail args lexbuf (FSComp.SR.lexIdentEndInMarkReserved("!")) (Keywords.KeywordOrIdentifierToken args lexbuf (lexeme lexbuf)) } - | ident ('#') + + | "and!" + { AND_BANG(false) } + + | ident '!' + { let tok = Keywords.KeywordOrIdentifierToken args lexbuf (lexemeTrimRight lexbuf 1) + match tok with + | LET _ -> BINDER (lexemeTrimRight lexbuf 1) + | _ -> fail args lexbuf (FSComp.SR.lexIdentEndInMarkReserved("!")) (Keywords.KeywordOrIdentifierToken args lexbuf (lexeme lexbuf)) } + + | ident ('#') { fail args lexbuf (FSComp.SR.lexIdentEndInMarkReserved("#")) (Keywords.KeywordOrIdentifierToken args lexbuf (lexeme lexbuf)) } - | int8 + + | int8 { let n = lexemeTrimRightToInt32 args lexbuf 1 - if n > 0x80 || n < -0x80 then fail args lexbuf (FSComp.SR.lexOutsideEightBitSigned()) (INT8(0y,false)) - // Allow to parse as min_int. Allowed only because we parse '-' as an operator. - else if n = 0x80 then INT8(sbyte(-0x80), true (* 'true' = 'bad'*) ) - else INT8(sbyte n,false) } - | xint8 + // Allow to parse as min_int. Allowed only because we parse '-' as an operator. + if Ranges.isInt8BadMax n then INT8(SByte.MinValue, true (* 'true' = 'bad'*) ) + else if n > int SByte.MaxValue || n < int SByte.MinValue then fail args lexbuf (FSComp.SR.lexOutsideEightBitSigned()) (INT8(0y, false)) + else INT8(sbyte n, false) } + + | xint8 { let n = lexemeTrimRightToInt32 args lexbuf 1 - if n > 0xFF || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideEightBitSignedHex()) (INT8(0y,false)) - else INT8(sbyte(byte(n)),false) } + if n > int Byte.MaxValue || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideEightBitSignedHex()) (INT8(0y, false)) + else INT8(sbyte(byte(n)), false) } + | uint8 { let n = lexemeTrimRightToInt32 args lexbuf 2 - if n > 0xFF || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideEightBitUnsigned()) (UINT8(0uy)) - else UINT8(byte n) } - | int16 + if n > int Byte.MaxValue || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideEightBitUnsigned()) (UINT8(0uy)) + else UINT8(byte n) } + + | int16 { let n = lexemeTrimRightToInt32 args lexbuf 1 - if n > 0x8000 || n < -0x8000 then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitSigned()) (INT16(0s,false)) - // Allow to parse as min_int. Allowed only because we parse '-' as an operator. - else if n = 0x8000 then INT16(-0x8000s,true) - else INT16(int16 n,false) } - | xint16 + // Allow to parse as min_int. Allowed only because we parse '-' as an operator. + if Ranges.isInt16BadMax n then INT16(Int16.MinValue, true (* 'true' = 'bad'*) ) + else if n > int Int16.MaxValue || n < int Int16.MinValue then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitSigned()) (INT16(0s, false)) + else INT16(int16 n, false) } + + | xint16 { let n = lexemeTrimRightToInt32 args lexbuf 1 - if n > 0xFFFF || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitSigned()) (INT16(0s,false)) - else INT16(int16(uint16(n)),false) } - | uint16 + if n > int UInt16.MaxValue || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitSigned()) (INT16(0s,false)) + else INT16(int16(uint16(n)), false) } + + | uint16 { let n = lexemeTrimRightToInt32 args lexbuf 2 - if n > 0xFFFF || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitUnsigned()) (UINT16(0us)) + if n > int UInt16.MaxValue || n < 0 then fail args lexbuf (FSComp.SR.lexOutsideSixteenBitUnsigned()) (UINT16(0us)) else UINT16(uint16 n) } - | int '.' '.' + + | int '.' '.' { let s = removeUnderscores (lexemeTrimRight lexbuf 2) - // Allow to parse as min_int. Allowed only because we parse '-' as an operator. - if s = "2147483648" then INT32_DOT_DOT(-2147483648,true) else + // Allow to parse as min_int. Allowed only because we parse '-' as an operator. + if Ranges.isInt32BadMax s then INT32_DOT_DOT(Int32.MinValue, true (* 'true' = 'bad'*) ) else let n = try int32 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitSigned()) 0 - INT32_DOT_DOT(n,false) - } - | xint - | int + INT32_DOT_DOT(n, false) + } + + | xint + | int { let s = removeUnderscores (lexeme lexbuf) - // Allow to parse as min_int. Allowed only because we parse '-' as an operator. - if s = "2147483648" then INT32(-2147483648,true) else + // Allow to parse as min_int. Allowed only because we parse '-' as an operator. + if Ranges.isInt32BadMax s then INT32(Int32.MinValue, true (* 'true' = 'bad'*) ) else let n = try int32 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitSigned()) 0 - INT32(n,false) - } - | xint32 - | int32 + INT32(n, false) + } + + | xint32 + | int32 { let s = removeUnderscores (lexemeTrimRight lexbuf 1) - // Allow to parse as min_int. Allowed only because we parse '-' as an operator. - if s = "2147483648" then INT32(-2147483648,true) else - let n = + // Allow to parse as min_int. Allowed only because we parse '-' as an operator. + if Ranges.isInt32BadMax s then INT32(Int32.MinValue, true (* 'true' = 'bad'*) ) else + let n = try int32 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitSigned()) 0 - INT32(n,false) - } + INT32(n, false) + } | uint32 - { + { let s = removeUnderscores (lexemeTrimRight lexbuf 1) - let n = + let n = try int64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) 0L - if n > 0xFFFFFFFFL || n < 0L then fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) (UINT32(0u)) else - UINT32(uint32 (uint64 n)) } + if n > int64 UInt32.MaxValue || n < 0L then fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) (UINT32(0u)) else + UINT32(uint32 (uint64 n)) } | uint32l - { + { let s = removeUnderscores (lexemeTrimRight lexbuf 2) - let n = + let n = try int64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) 0L - if n > 0xFFFFFFFFL || n < 0L then fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) (UINT32(0u)) else - UINT32(uint32 (uint64 n)) } + if n > int64 UInt32.MaxValue || n < 0L then fail args lexbuf (FSComp.SR.lexOutsideThirtyTwoBitUnsigned()) (UINT32(0u)) else + UINT32(uint32 (uint64 n)) } - | int64 + | int64 { let s = removeUnderscores (lexemeTrimRight lexbuf 1) - // Allow to parse as min_int. Stupid but allowed because we parse '-' as an operator. - if s = "9223372036854775808" then INT64(-9223372036854775808L,true) else - let n = - try int64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideSixtyFourBitSigned()) 0L + // Allow to parse as min_int. Stupid but allowed because we parse '-' as an operator. + if Ranges.isInt64BadMax s then INT64(Int64.MinValue, true (* 'true' = 'bad'*) ) else + let n = + try int64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideSixtyFourBitSigned()) 0L INT64(n,false) } - | uint64 + | uint64 { let s = removeUnderscores (lexemeTrimRight lexbuf 2) - let n = + let n = try uint64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideSixtyFourBitUnsigned()) 0UL - UINT64(n) } + UINT64(n) } - | nativeint - { try - NATIVEINT(int64 (removeUnderscores (lexemeTrimRight lexbuf 1))) - with _ -> fail args lexbuf (FSComp.SR.lexOutsideNativeSigned()) (NATIVEINT(0L)) } + | nativeint + { let s = removeUnderscores (lexemeTrimRight lexbuf 1) + // Allow to parse as min_nativeint. Stupid but allowed because we parse '-' as an operator. + if Ranges.isInt64BadMax s then NATIVEINT(Int64.MinValue, true) else + let n = + try int64 s with _ -> fail args lexbuf (FSComp.SR.lexOutsideNativeSigned()) 0L + NATIVEINT(n,false) + } - | unativeint - { try + | unativeint + { try UNATIVEINT(uint64 (removeUnderscores (lexemeTrimRight lexbuf 2))) with _ -> fail args lexbuf (FSComp.SR.lexOutsideNativeUnsigned()) (UNATIVEINT(0UL)) } | ieee32 - { let s = lexemeTrimRight lexbuf 1 - if lexbuf.SupportsFeature LanguageFeature.DotlessFloat32Literal || s.Contains "." then - try - IEEE32 (float32 (removeUnderscores s)) - with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) (IEEE32 0.0f) + { IEEE32 (evalFloat args lexbuf) } + + | ieee32_dotless_no_exponent + { if lexbuf.SupportsFeature LanguageFeature.DotlessFloat32Literal then + IEEE32 (evalFloat args lexbuf) else fail args lexbuf (FSComp.SR.lexInvalidFloat()) (IEEE32 0.0f) } - | ieee64 + | ieee64 { IEEE64 (try float(lexeme lexbuf) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0.0) } - | decimal - { try + | decimal + { try let s = removeUnderscores (lexemeTrimRight lexbuf 1) - // This implements a range check for decimal literals + // This implements a range check for decimal literals let d = System.Decimal.Parse(s,System.Globalization.NumberStyles.AllowExponent ||| System.Globalization.NumberStyles.Number,System.Globalization.CultureInfo.InvariantCulture) - DECIMAL d - with + DECIMAL d + with e -> fail args lexbuf (FSComp.SR.lexOusideDecimal()) (DECIMAL (decimal 0)) } - | xieee32 - { + | xieee32 + { let s = removeUnderscores (lexemeTrimRight lexbuf 2) - // Even though the intermediate step is an int64, display the "invalid float" message, since it will be less confusing to the user - let n64 = (try (int64 s) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0L) + // Even though the intermediate step is an int64, display the "invalid float" message, since it will be less confusing to the user + let n64 = (try (int64 s) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0L) if n64 > 0xFFFFFFFFL || n64 < 0L then fail args lexbuf (FSComp.SR.lexOusideThirtyTwoBitFloat()) (IEEE32 0.0f) else IEEE32 (System.BitConverter.ToSingle(System.BitConverter.GetBytes(int32 (uint32 (uint64 n64))),0)) } - | xieee64 - { - let n64 = (try int64 (removeUnderscores (lexemeTrimRight lexbuf 2)) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0L) + | xieee64 + { + let n64 = (try int64 (removeUnderscores (lexemeTrimRight lexbuf 2)) with _ -> fail args lexbuf (FSComp.SR.lexInvalidFloat()) 0L) IEEE64 (System.BitConverter.Int64BitsToDouble(n64)) } - - | bignum - { let s = lexeme lexbuf + + | bignum + { let s = lexeme lexbuf BIGNUM (removeUnderscores (lexemeTrimRight lexbuf 1), s.[s.Length-1..s.Length-1]) } | (int | xint | float) ident_char+ { fail args lexbuf (FSComp.SR.lexInvalidNumericLiteral()) (INT32(0,false)) } - + | char - { let s = lexeme lexbuf + { let s = lexeme lexbuf CHAR (if s.[1] = '\\' then escape s.[2] else s.[1]) } - | char 'B' - { let s = lexeme lexbuf + | char 'B' + { let s = lexeme lexbuf let x = int32 (if s.[1] = '\\' then escape s.[2] else s.[1]) - if x < 0 || x > 127 then + if x < 0 || x > 127 then fail args lexbuf (FSComp.SR.lexInvalidByteLiteral()) (UINT8(byte 0)) else UINT8 (byte(x)) } - + | '\'' trigraph '\'' - { let s = lexeme lexbuf - let c = trigraph s.[2] s.[3] s.[4] + { let s = lexeme lexbuf + let c = trigraph s.[2] s.[3] s.[4] let x = int32 c - if x < 0 || x > 255 then + if x < 0 || x > 255 then fail args lexbuf (FSComp.SR.lexInvalidCharLiteral()) (CHAR c) else CHAR c } | '\'' trigraph '\'' 'B' - { let s = lexeme lexbuf + { let s = lexeme lexbuf let x = int32 (trigraph s.[2] s.[3] s.[4]) - if x < 0 || x > 255 then + if x < 0 || x > 255 then fail args lexbuf (FSComp.SR.lexInvalidByteLiteral()) (UINT8(byte 0)) else UINT8 (byte(x)) } | '\'' unicodeGraphShort '\'' 'B' { let x = int32 (unicodeGraphShort (lexemeTrimBoth lexbuf 3 2)) - if x < 0 || x > 127 then + if x < 0 || x > 127 then fail args lexbuf (FSComp.SR.lexInvalidByteLiteral()) (UINT8(byte 0)) else UINT8 (byte(x)) } - + | '\'' hexGraphShort '\'' { CHAR (char (int32 (hexGraphShort (lexemeTrimBoth lexbuf 3 1)))) } + | '\'' unicodeGraphShort '\'' { CHAR (char (int32 (unicodeGraphShort (lexemeTrimBoth lexbuf 3 1)))) } - | '\'' unicodeGraphLong '\'' + + | '\'' unicodeGraphLong '\'' { match unicodeGraphLong (lexemeTrimBoth lexbuf 3 1) with | SingleChar(c) -> CHAR (char c) | _ -> fail args lexbuf (FSComp.SR.lexThisUnicodeOnlyInStringLiterals()) (CHAR (char 0)) } - | "(*IF-FSHARP" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - | "(*F#" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - | "ENDIF-FSHARP*)" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - | "F#*)" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - - | "(*)" + + | "(*IF-FSHARP" + { if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatWarning (FSComp.SR.lexIndentOffForML()) lexbuf.LexemeRange + if not skip then COMMENT (LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | "(*F#" + { if not skip then COMMENT (LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | "ENDIF-FSHARP*)" + { if not skip then COMMENT (LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | "F#*)" + { if not skip then COMMENT (LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | "(*)" { LPAREN_STAR_RPAREN } | "(*" - { let m = lexbuf.LexemeRange - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,1,m))) else comment (1,m,args) skip lexbuf } - - | "(*IF-CAML*)" | "(*IF-OCAML*)" - { let m = lexbuf.LexemeRange - if not skip then (COMMENT (LexCont.MLOnly(args.ifdefStack,m))) else mlOnly m args skip lexbuf } - - | '"' - { let buf,fin,m = startString args lexbuf - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string (buf,fin,m,args) skip lexbuf } - - | '"' '"' '"' - { let buf,fin,m = startString args lexbuf - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString (buf,fin,m,args) skip lexbuf } - - | '$' '"' - { fail args lexbuf (FSComp.SR.lexTokenReserved()) (WHITESPACE (LexCont.Token args.ifdefStack)) } - - | '@' '"' - { let buf,fin,m = startString args lexbuf - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString (buf,fin,m,args) skip lexbuf } - - | truewhite+ + { let m = lexbuf.LexemeRange + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, 1, m)) + else comment (1,m,args) skip lexbuf } + + | "(*IF-CAML*)" | "(*IF-OCAML*)" + { let m = lexbuf.LexemeRange + if not skip then COMMENT (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) + else mlOnly m args skip lexbuf } + + | '"' + { let buf, fin, m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | (_, LexerStringStyle.TripleQuote, _) :: _ -> () + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | [] -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.String, m)) + else singleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf } + + | '$' '"' '"' '"' + { let buf, fin, m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) + | [] -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, LexerStringKind.InterpolatedStringFirst, m)) + else tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf } + + | '$' '"' + { let buf,fin,m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | (_, LexerStringStyle.TripleQuote, _) :: _ -> () + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.InterpolatedStringFirst, m)) + else singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf } + + | '"' '"' '"' + { let buf, fin, m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) + | _ -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, LexerStringKind.String, m)) + else tripleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf } + + | '@' '"' + { let buf, fin, m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | (_, LexerStringStyle.TripleQuote, _) :: _ -> () + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, LexerStringKind.String, m)) + else verbatimString (buf, fin, m, LexerStringKind.String, args) skip lexbuf } + + | ("$@" | "@$") '"' + { let buf, fin, m = startString args lexbuf + + // Single quote in triple quote ok, others disallowed + match args.stringNest with + | (_, LexerStringStyle.TripleQuote, _) :: _ -> () + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ -> () + + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, LexerStringKind.InterpolatedStringFirst, m)) + else verbatimString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf } + + | truewhite+ { if skip then token args skip lexbuf - else WHITESPACE (LexCont.Token args.ifdefStack) } + else WHITESPACE (LexCont.Token(args.ifdefStack, args.stringNest)) } - | offwhite+ - { if args.lightSyntaxStatus.Status then errorR(Error(FSComp.SR.lexTabsNotAllowed(),lexbuf.LexemeRange)) - if not skip then (WHITESPACE (LexCont.Token args.ifdefStack)) else token args skip lexbuf } + | offwhite+ + { if args.lightStatus.Status then errorR(Error(FSComp.SR.lexTabsNotAllowed(), lexbuf.LexemeRange)) + if not skip then WHITESPACE (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } - | "////" op_char* - { // 4+ slash are 1-line comments, online 3 slash are XmlDoc - let m = lexbuf.LexemeRange - if not skip then (LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack,1,m))) else singleLineComment (None,1,m,args) skip lexbuf } + | "////" op_char* + { // 4+ slash are 1-line comments, online 3 slash are XmlDoc + let m = lexbuf.LexemeRange + if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) + else singleLineComment (None,1,m,args) skip lexbuf } | "///" op_char* - { // Match exactly 3 slash, 4+ slash caught by preceding rule + { // Match exactly 3 slash, 4+ slash caught by preceding rule let m = lexbuf.LexemeRange - let doc = lexemeTrimLeft lexbuf 3 + let doc = lexemeTrimLeft lexbuf 3 let sb = (new StringBuilder(100)).Append(doc) - if not skip then (LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack,1,m))) else singleLineComment (Some sb,1,m,args) skip lexbuf } + if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) + else singleLineComment (Some (m, sb),1,m,args) skip lexbuf } | "//" op_char* - { // Need to read all operator symbols too, otherwise it might be parsed by a rule below + { // Need to read all operator symbols too, otherwise it might be parsed by a rule below let m = lexbuf.LexemeRange - if not skip then (LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack,1,m))) else singleLineComment (None,1,m,args) skip lexbuf } + if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) + else singleLineComment (None,1,m,args) skip lexbuf } - | newline - { newline lexbuf; if not skip then (WHITESPACE (LexCont.Token args.ifdefStack)) else token args skip lexbuf } + | newline + { newline lexbuf + if not skip then WHITESPACE (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } - | '`' '`' ([^'`' '\n' '\r' '\t'] | '`' [^'`''\n' '\r' '\t']) + '`' '`' + | '`' '`' ([^'`' '\n' '\r' '\t'] | '`' [^'`''\n' '\r' '\t']) + '`' '`' { Keywords.IdentifierToken args lexbuf (lexemeTrimBoth lexbuf 2 2) } | ('#' anywhite* | "#line" anywhite+ ) digit+ anywhite* ('@'? "\"" [^'\n''\r''"']+ '"')? anywhite* newline - { let pos = lexbuf.EndPos - if skip then - let s = lexeme lexbuf - let rec parseLeadingDirective n = - match s.[n] with - | c when c >= 'a' && c <= 'z' -> parseLeadingDirective (n+1) + { let pos = lexbuf.EndPos + if skip then + let s = lexeme lexbuf + let rec parseLeadingDirective n = + match s.[n] with + | c when c >= 'a' && c <= 'z' -> parseLeadingDirective (n+1) | _ -> parseLeadingWhitespace n // goto the next state - - and parseLeadingWhitespace n = - match s.[n] with - | ' ' | '\t' -> parseLeadingWhitespace (n+1) + + and parseLeadingWhitespace n = + match s.[n] with + | ' ' | '\t' -> parseLeadingWhitespace (n+1) | _ -> parseLineNumber n n // goto the next state - - and parseLineNumber start n = - match s.[n] with + + and parseLineNumber start n = + match s.[n] with | c when c >= '0' && c <= '9' -> parseLineNumber start (n+1) - | _ -> let text = (String.sub s start (n-start)) - let lineNumber = + | _ -> let text = (String.sub s start (n-start)) + let lineNumber = try int32 text - with err -> errorR(Error(FSComp.SR.lexInvalidLineNumber(text),lexbuf.LexemeRange)); 0 + with err -> errorR(Error(FSComp.SR.lexInvalidLineNumber(text), lexbuf.LexemeRange)); 0 lineNumber, parseWhitespaceBeforeFile n // goto the next state - - and parseWhitespaceBeforeFile n = - match s.[n] with - | ' ' | '\t' | '@' -> parseWhitespaceBeforeFile (n+1) + + and parseWhitespaceBeforeFile n = + match s.[n] with + | ' ' | '\t' | '@' -> parseWhitespaceBeforeFile (n+1) | '"' -> Some (parseFile (n+1) (n+1)) | _ -> None - - and parseFile start n = - match s.[n] with - | '"' -> String.sub s start (n-start) - | _ -> parseFile start (n+1) + + and parseFile start n = + match s.[n] with + | '"' -> String.sub s start (n-start) + | _ -> parseFile start (n+1) // Call the parser - let line,file = parseLeadingDirective 1 + let line,file = parseLeadingDirective 1 // Construct the new position - if args.applyLineDirectives then - lexbuf.EndPos <- pos.ApplyLineDirective((match file with Some f -> fileIndexOfFile f | None -> pos.FileIndex), line) + if args.applyLineDirectives then + lexbuf.EndPos <- pos.ApplyLineDirective((match file with Some f -> FileIndex.fileIndexOfFile f | None -> pos.FileIndex), line) else // add a newline when we don't apply a directive since we consumed a newline getting here newline lexbuf - token args skip lexbuf + token args skip lexbuf else // add a newline when we don't apply a directive since we consumed a newline getting here newline lexbuf - (HASH_LINE (LexCont.Token args.ifdefStack)) } - + HASH_LINE (LexCont.Token (args.ifdefStack, args.stringNest)) } + | "<@" { checkExprOp lexbuf; LQUOTE ("<@ @>", false) } + | "<@@" { checkExprOp lexbuf; LQUOTE ("<@@ @@>", true) } + | "@>" { checkExprOp lexbuf; RQUOTE ("<@ @>", false) } + | "@@>" { checkExprOp lexbuf; RQUOTE ("<@@ @@>", true) } + | '#' { HASH } + | '&' { AMP } + | "&&" { AMP_AMP } + | "||" { BAR_BAR } + | '\'' { QUOTE } + | '(' { LPAREN } + | ')' { RPAREN } + | '*' { STAR } + | ',' { COMMA } + | "->" { RARROW } + | "?" { QMARK } + | "??" { QMARK_QMARK } + | ".." { DOT_DOT } + | "..^" { DOT_DOT_HAT } + | "." { DOT } + | ":" { COLON } + | "::" { COLON_COLON } + | ":>" { COLON_GREATER } + | "@>." { RQUOTE_DOT ("<@ @>",false) } + | "@@>." { RQUOTE_DOT ("<@@ @@>",true) } + | ">|]" { GREATER_BAR_RBRACK } + | ":?>" { COLON_QMARK_GREATER } + | ":?" { COLON_QMARK } + | ":=" { COLON_EQUALS } + | ";;" { SEMICOLON_SEMICOLON } + | ";" { SEMICOLON } + | "<-" { LARROW } + | "=" { EQUALS } + | "[" { LBRACK } + | "[|" { LBRACK_BAR } + | "{|" { LBRACE_BAR } + | "<" { LESS false } + | ">" { GREATER false } + | "[<" { LBRACK_LESS } + | "]" { RBRACK } + | "|]" { BAR_RBRACK } + | "|}" { BAR_RBRACE } + | ">]" { GREATER_RBRACK } - | "{" { LBRACE } + + | "{" + { + match args.stringNest with + | [] -> () + | (counter, style, m) :: rest -> + // Note, we do not update the 'm', any incomplete-interpolation error + // will be reported w.r.t. the first '{' + args.stringNest <- (counter + 1, style, m) :: rest + // To continue token-by-token lexing may involve picking up the new args.stringNes + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + LBRACE cont + } + | "|" { BAR } - | "}" { RBRACE } + + | "}" + { + // We encounter a '}' in the expression token stream. First check if we're in an interpolated string expression + // and continue the string if necessary + match args.stringNest with + | (1, style, _) :: rest -> + args.stringNest <- rest + let buf, fin, m = startString args lexbuf + if not skip then + STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, style, LexerStringKind.InterpolatedStringPart, m)) + else + match style with + | LexerStringStyle.Verbatim -> verbatimString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf + | LexerStringStyle.SingleQuote -> singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf + | LexerStringStyle.TripleQuote -> tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf + + | (counter, style, m) :: rest -> + // Note, we do not update the 'm', any incomplete-interpolation error + // will be reported w.r.t. the first '{' + args.stringNest <- (counter - 1, style, m) :: rest + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + RBRACE cont + + | _ -> + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + RBRACE cont + } + | "$" { DOLLAR } + | "%" { PERCENT_OP("%") } + | "%%" { PERCENT_OP("%%") } + | "-" { MINUS } + | "~" { RESERVED } + | "`" { RESERVED } + | ignored_op_char* '*' '*' op_char* { checkExprOp lexbuf; INFIX_STAR_STAR_OP(lexeme lexbuf) } + | ignored_op_char* ('*' | '/'|'%') op_char* { checkExprOp lexbuf; INFIX_STAR_DIV_MOD_OP(lexeme lexbuf) } + | ignored_op_char* ('+'|'-') op_char* { checkExprOp lexbuf; PLUS_MINUS_OP(lexeme lexbuf) } + | ignored_op_char* ('@'|'^') op_char* { checkExprOp lexbuf; INFIX_AT_HAT_OP(lexeme lexbuf) } + | ignored_op_char* ('=' | "!=" | '<' | '>' | '$') op_char* { checkExprOp lexbuf; INFIX_COMPARE_OP(lexeme lexbuf) } + | ignored_op_char* ('&') op_char* { checkExprOp lexbuf; INFIX_AMP_OP(lexeme lexbuf) } + | ignored_op_char* '|' op_char* { checkExprOp lexbuf; INFIX_BAR_OP(lexeme lexbuf) } + | ignored_op_char* ('!' | '~' ) op_char* { checkExprOp lexbuf; PREFIX_OP(lexeme lexbuf) } + | ".[]" | ".[]<-" | ".[,]<-" | ".[,,]<-" | ".[,,,]<-" | ".[,,,]" | ".[,,]" | ".[,]" | ".[..]" | ".[..,..]" | ".[..,..,..]" | ".[..,..,..,..]" + | ".()" | ".()<-" { FUNKY_OPERATOR_NAME(lexeme lexbuf) } - | "#!" op_char* + + | "#!" op_char* { // Treat shebangs like regular comments, but they are only allowed at the start of a file let m = lexbuf.LexemeRange - let tok = shouldStartFile args lexbuf m (0,FSComp.SR.lexHashBangMustBeFirstInFile()) (LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack,1,m))) + let tok = LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, 1, m)) + let tok = shouldStartFile args lexbuf m (0,FSComp.SR.lexHashBangMustBeFirstInFile()) tok if not skip then tok else singleLineComment (None,1,m,args) skip lexbuf } - | "#light" anywhite* + | "#light" anywhite* | ("#indent" | "#light") anywhite+ "\"on\"" - { if args.lightSyntaxStatus.ExplicitlySet && args.lightSyntaxStatus.WarnOnMultipleTokens then - warning(Error((0,"#light should only occur as the first non-comment text in an F# source file"),lexbuf.LexemeRange)) - // TODO unreachable error above, I think? - brianmcn - args.lightSyntaxStatus.Status <- true - if not skip then (HASH_LIGHT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - - | ("#indent" | "#light") anywhite+ "\"off\"" - { args.lightSyntaxStatus.Status <- false - mlCompatWarning (FSComp.SR.lexIndentOffForML()) lexbuf.LexemeRange - if not skip then (HASH_LIGHT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - + { if args.lightStatus.ExplicitlySet && args.lightStatus.WarnOnMultipleTokens then + let s = lexeme lexbuf + warning(Error((0, sprintf "%s should only be set once in an F# source file." s), lexbuf.LexemeRange)) + // TODO: where should this go? (abelb) + //warning(Error((0,"#light should only occur as the first non-comment text in an F# source file."), lexbuf.LexemeRange)) + args.lightStatus.Status <- true + if not skip then HASH_LIGHT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | ("#indent" | "#light") anywhite+ "\"off\"" + { args.lightStatus.Status <- false + if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatLightOffNoLongerSupported()) lexbuf.LexemeRange + else + mlCompatWarning (FSComp.SR.lexIndentOffForML()) lexbuf.LexemeRange + if not skip then HASH_LIGHT (LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + | anywhite* "#if" anywhite+ anystring - { let m = lexbuf.LexemeRange + { let m = lexbuf.LexemeRange let lookup id = List.contains id args.defines let lexed = lexeme lexbuf - let isTrue = evalIfDefExpression lexbuf.StartPos lexbuf.SupportsFeature args lookup lexed + let isTrue = evalIfDefExpression lexbuf.StartPos lexbuf.ReportLibraryOnlyFeatures lexbuf.LanguageVersion args lookup lexed args.ifdefStack <- (IfDefIf,m) :: args.ifdefStack - + // Get the token; make sure it starts at zero position & return - let cont, f = - ( if isTrue then (LexCont.EndLine(LexerEndlineContinuation.Token(args.ifdefStack)), endline (LexerEndlineContinuation.Token args.ifdefStack) args skip) - else (LexCont.EndLine(LexerEndlineContinuation.Skip(args.ifdefStack,0,m)), endline (LexerEndlineContinuation.Skip(args.ifdefStack,0,m)) args skip) ) + let cont, f = + if isTrue then + let cont = LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Token) + let f = endline LexerEndlineContinuation.Token args skip + cont, f + else + let cont = LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Skip(0, m)) + let f = endline (LexerEndlineContinuation.Skip(0, m)) args skip + cont, f + let tok = shouldStartLine args lexbuf m (FSComp.SR.lexHashIfMustBeFirst()) (HASH_IF(m,lexed,cont)) if not skip then tok else f lexbuf } @@ -633,452 +965,661 @@ rule token args skip = parse match args.ifdefStack with | [] -> LEX_FAILURE (FSComp.SR.lexHashElseNoMatchingIf()) | (IfDefElse,_) :: _rest -> LEX_FAILURE (FSComp.SR.lexHashEndifRequiredForElse()) - | (IfDefIf,_) :: rest -> - let m = lexbuf.LexemeRange + | (IfDefIf,_) :: rest -> + let m = lexbuf.LexemeRange args.ifdefStack <- (IfDefElse,m) :: rest - let tok = HASH_ELSE(m,lexed, LexCont.EndLine(LexerEndlineContinuation.Skip(args.ifdefStack,0,m))) + let tok = HASH_ELSE(m, lexed, LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Skip(0, m))) let tok = shouldStartLine args lexbuf m (FSComp.SR.lexHashElseMustBeFirst()) tok - if not skip then tok else endline (LexerEndlineContinuation.Skip(args.ifdefStack,0,m)) args skip lexbuf } + if not skip then tok else endline (LexerEndlineContinuation.Skip(0, m)) args skip lexbuf } | anywhite* "#endif" anywhite* ("//" [^'\n''\r']*)? - { let lexed = (lexeme lexbuf) - let m = lexbuf.LexemeRange + { let lexed = (lexeme lexbuf) + let m = lexbuf.LexemeRange match args.ifdefStack with | []-> LEX_FAILURE (FSComp.SR.lexHashEndingNoMatchingIf()) - | _ :: rest -> - args.ifdefStack <- rest - let tok = HASH_ENDIF(m,lexed,LexCont.EndLine(LexerEndlineContinuation.Token(args.ifdefStack))) - let tok = shouldStartLine args lexbuf m (FSComp.SR.lexHashEndifMustBeFirst()) tok - if not skip then tok else endline (LexerEndlineContinuation.Token(args.ifdefStack)) args skip lexbuf } - - | "#if" - { let tok = fail args lexbuf (FSComp.SR.lexHashIfMustHaveIdent()) (WHITESPACE (LexCont.Token args.ifdefStack)) + | _ :: rest -> + args.ifdefStack <- rest + let tok = HASH_ENDIF(m,lexed,LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Token)) + let tok = shouldStartLine args lexbuf m (FSComp.SR.lexHashEndifMustBeFirst()) tok + if not skip then tok else endline LexerEndlineContinuation.Token args skip lexbuf } + + | "#if" + { let tok = WHITESPACE (LexCont.Token (args.ifdefStack, args.stringNest)) + let tok = fail args lexbuf (FSComp.SR.lexHashIfMustHaveIdent()) tok if not skip then tok else token args skip lexbuf } + | anywhite* "#if" ident_char+ + | anywhite* "#else" ident_char+ + | anywhite* "#endif" ident_char+ + | anywhite* "#light" ident_char+ + { let n = (lexeme lexbuf).IndexOf('#') + lexbuf.StartPos <- lexbuf.StartPos.ShiftColumnBy(n) + HASH_IDENT(lexemeTrimLeft lexbuf (n+1)) } + | surrogateChar surrogateChar - | _ - { unexpectedChar lexbuf } - | eof - { EOF (LexCont.Token args.ifdefStack) } -// Skips INACTIVE code until if finds #else / #endif matching with the #if or #else + | _ + { unexpectedChar lexbuf } -and ifdefSkip n m args skip = parse + | eof + { EOF (LexCont.Token(args.ifdefStack, args.stringNest)) } + +// Skips INACTIVE code until if finds #else / #endif matching with the #if or #else + +and ifdefSkip n m args skip = parse | anywhite* "#if" anywhite+ anystring - { let m = lexbuf.LexemeRange - + { let m = lexbuf.LexemeRange + // If #if is the first thing on the line then increase depth, otherwise skip, because it is invalid (e.g. "(**) #if ...") if (m.StartColumn <> 0) then - if not skip then (INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack,n,m))) else ifdefSkip n m args skip lexbuf + if not skip then INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) + else ifdefSkip n m args skip lexbuf else - let tok = INACTIVECODE(LexCont.EndLine(LexerEndlineContinuation.Skip(args.ifdefStack,n+1,m))) - if not skip then tok else endline (LexerEndlineContinuation.Skip(args.ifdefStack,n+1,m)) args skip lexbuf } + let tok = INACTIVECODE(LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Skip(n+1, m))) + if not skip then tok else endline (LexerEndlineContinuation.Skip(n+1, m)) args skip lexbuf } | anywhite* "#else" anywhite* ("//" [^'\n''\r']*)? - { let lexed = (lexeme lexbuf) - let m = lexbuf.LexemeRange - + { let lexed = (lexeme lexbuf) + let m = lexbuf.LexemeRange + // If #else is the first thing on the line then process it, otherwise ignore, because it is invalid (e.g. "(**) #else ...") if (m.StartColumn <> 0) then - if not skip then (INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack,n,m))) else ifdefSkip n m args skip lexbuf - elif n = 0 then + if not skip then INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) + else ifdefSkip n m args skip lexbuf + elif n = 0 then match args.ifdefStack with | []-> LEX_FAILURE (FSComp.SR.lexHashElseNoMatchingIf()) | (IfDefElse,_) :: _rest -> LEX_FAILURE (FSComp.SR.lexHashEndifRequiredForElse()) - | (IfDefIf,_) :: rest -> - let m = lexbuf.LexemeRange + | (IfDefIf,_) :: rest -> + let m = lexbuf.LexemeRange args.ifdefStack <- (IfDefElse,m) :: rest - if not skip then (HASH_ELSE(m,lexed,LexCont.EndLine(LexerEndlineContinuation.Token(args.ifdefStack)))) else endline (LexerEndlineContinuation.Token(args.ifdefStack)) args skip lexbuf + if not skip then HASH_ELSE(m,lexed,LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Token)) + else endline LexerEndlineContinuation.Token args skip lexbuf else - if not skip then (INACTIVECODE(LexCont.EndLine(LexerEndlineContinuation.Skip(args.ifdefStack,n,m)))) else endline (LexerEndlineContinuation.Skip(args.ifdefStack,n,m)) args skip lexbuf } - + if not skip then INACTIVECODE(LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Skip(n, m))) + else endline (LexerEndlineContinuation.Skip(n, m)) args skip lexbuf } + | anywhite* "#endif" anywhite* ("//" [^'\n''\r']*)? { let lexed = lexeme lexbuf - let m = lexbuf.LexemeRange - + let m = lexbuf.LexemeRange + // If #endif is the first thing on the line then process it, otherwise ignore, because it is invalid (e.g. "(**) #endif ...") if (m.StartColumn <> 0) then - if not skip then (INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack,n,m))) else ifdefSkip n m args skip lexbuf - elif n = 0 then + if not skip then INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) + else ifdefSkip n m args skip lexbuf + elif n = 0 then match args.ifdefStack with | [] -> LEX_FAILURE (FSComp.SR.lexHashEndingNoMatchingIf()) - | _ :: rest -> + | _ :: rest -> args.ifdefStack <- rest - if not skip then (HASH_ENDIF(m,lexed,LexCont.EndLine(LexerEndlineContinuation.Token(args.ifdefStack)))) else endline (LexerEndlineContinuation.Token(args.ifdefStack)) args skip lexbuf + if not skip then HASH_ENDIF(m,lexed,LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Token)) + else endline LexerEndlineContinuation.Token args skip lexbuf else - let tok = INACTIVECODE(LexCont.EndLine(LexerEndlineContinuation.Skip(args.ifdefStack,n-1,m))) + let tok = INACTIVECODE(LexCont.EndLine(args.ifdefStack, args.stringNest, LexerEndlineContinuation.Skip(n-1, m))) let tok = shouldStartLine args lexbuf m (FSComp.SR.lexWrongNestedHashEndif()) tok - if not skip then tok else endline (LexerEndlineContinuation.Skip(args.ifdefStack,(n-1),m)) args skip lexbuf } - - | newline + if not skip then tok else endline (LexerEndlineContinuation.Skip(n-1, m)) args skip lexbuf } + + | newline { newline lexbuf; ifdefSkip n m args skip lexbuf } - + | [^ ' ' '\n' '\r' ]+ + | anywhite+ + | surrogateChar surrogateChar - | _ + + | _ { // This tries to be nice and get tokens as 'words' because VS uses this when selecting stuff - if not skip then (INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack,n,m))) else ifdefSkip n m args skip lexbuf } - | eof - { EOF (LexCont.IfDefSkip(args.ifdefStack,n,m)) } + if not skip then INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) + else ifdefSkip n m args skip lexbuf } + + | eof + { EOF (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) } -// Called after lexing #if IDENT/#else/#endif - this checks whether there is nothing except end of line -// or end of file and then calls the lexing function specified by 'cont' - either token or ifdefSkip +// Called after lexing #if IDENT/#else/#endif - this checks whether there is nothing except end of line +// or end of file and then calls the lexing function specified by 'cont' - either token or ifdefSkip and endline cont args skip = parse | newline - { newline lexbuf + { newline lexbuf match cont with - | LexerEndlineContinuation.Token(ifdefStack) -> if not skip then (WHITESPACE(LexCont.Token ifdefStack)) else token args skip lexbuf - | LexerEndlineContinuation.Skip(ifdefStack, n, m) -> if not skip then (INACTIVECODE (LexCont.IfDefSkip(ifdefStack,n,m))) else ifdefSkip n m args skip lexbuf + | LexerEndlineContinuation.Token -> + if not skip then WHITESPACE(LexCont.Token (args.ifdefStack, args.stringNest)) + else token args skip lexbuf + + | LexerEndlineContinuation.Skip(n, m) -> + if not skip then INACTIVECODE (LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) + else ifdefSkip n m args skip lexbuf } + | eof { match cont with - | LexerEndlineContinuation.Token(ifdefStack) -> (EOF(LexCont.Token ifdefStack)) - | LexerEndlineContinuation.Skip(ifdefStack, n, m) -> (EOF(LexCont.IfDefSkip(ifdefStack,n,m))) + | LexerEndlineContinuation.Token -> + EOF(LexCont.Token(args.ifdefStack, args.stringNest)) + | LexerEndlineContinuation.Skip(n, m) -> + EOF(LexCont.IfDefSkip(args.ifdefStack, args.stringNest, n, m)) } + | [^'\r' '\n']+ + | _ - { let tok = fail args lexbuf (FSComp.SR.pplexExpectedSingleLineComment()) (WHITESPACE (LexCont.Token args.ifdefStack)) - if not skip then tok else token args skip lexbuf } + { let tok = WHITESPACE (LexCont.Token (args.ifdefStack, args.stringNest)) + let tok = fail args lexbuf (FSComp.SR.pplexExpectedSingleLineComment()) tok + if not skip then tok else token args skip lexbuf } -and string sargs skip = parse - | '\\' newline anywhite* - { let (_buf,_fin,m,args) = sargs - newline lexbuf - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } +and singleQuoteString sargs skip = parse + | '\\' newline anywhite* + { let (_buf, _fin, m, kind, args) = sargs + newline lexbuf + let text = lexeme lexbuf + let text2 = text |> String.filter (fun c -> c <> ' ' && c <> '\t') + advanceColumnBy lexbuf (text.Length - text2.Length) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } | escape_char - { let (buf,_fin,m,args) = sargs + { let (buf, _fin, m, kind, args) = sargs addByteChar buf (escape (lexeme lexbuf).[1]) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } | trigraph - { let (buf,_fin,m,args) = sargs - let s = lexeme lexbuf + { let (buf, _fin, m, kind, args) = sargs + let s = lexeme lexbuf addByteChar buf (trigraph s.[1] s.[2] s.[3]) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } | hexGraphShort - { let (buf,_fin,m,args) = sargs + { let (buf, _fin, m, kind, args) = sargs addUnicodeChar buf (int (hexGraphShort (lexemeTrimLeft lexbuf 2))) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } - + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + | unicodeGraphShort - { let (buf,_fin,m,args) = sargs + { let (buf, _fin, m, kind, args) = sargs addUnicodeChar buf (int (unicodeGraphShort (lexemeTrimLeft lexbuf 2))) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } - + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + | unicodeGraphLong - { let (buf,_fin,m,args) = sargs + { let (buf, _fin, m, kind, args) = sargs let hexChars = lexemeTrimLeft lexbuf 2 - let result () = if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf + let result() = + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf match unicodeGraphLong hexChars with | Invalid -> - fail args lexbuf (FSComp.SR.lexInvalidUnicodeLiteral hexChars) (result ()) + fail args lexbuf (FSComp.SR.lexInvalidUnicodeLiteral hexChars) (result()) | SingleChar(c) -> addUnicodeChar buf (int c) - result () - | SurrogatePair(hi, lo) -> + result() + | SurrogatePair(hi, lo) -> addUnicodeChar buf (int hi) addUnicodeChar buf (int lo) - result () } - - | '"' - { let (buf,fin,_m,_args) = sargs - let m2 = lexbuf.LexemeRange - callStringFinisher fin buf m2 false } - - | '"''B' - { let (buf,fin,_m,_args) = sargs - let m2 = lexbuf.LexemeRange - callStringFinisher fin buf m2 true } + result() } + + | '"' + { let (buf, fin, _m, kind, args) = sargs + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind (enum(0)) cont + } + + | '"''B' + { let (buf, fin, _m, kind, args) = sargs + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf { kind with IsByteString = true } (enum(0)) cont + } + + | ("{{" | "}}") + { let (buf, _fin, m, kind, args) = sargs + let s = lexeme lexbuf + addUnicodeString buf (if kind.IsInterpolated then s.[0..0] else s) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + + | "{" + { let (buf, fin, m, kind, args) = sargs + if kind.IsInterpolated then + // get a new range for where the fill starts + let m2 = lexbuf.LexemeRange + args.stringNest <- (1, LexerStringStyle.SingleQuote, m2) :: args.stringNest + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind LexerStringFinisherContext.InterpolatedPart cont + else + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf + } + + | "}" + { let (buf, _fin, m, kind, args) = sargs + let result() = + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf + if kind.IsInterpolated then + fail args lexbuf (FSComp.SR.lexRBraceInInterpolatedString()) (result()) + else + addUnicodeString buf (lexeme lexbuf) + (result()) + } | newline - { let (buf,_fin,m,args) = sargs - newline lexbuf - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } - - | ident - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } + { let (buf, _fin, m, kind, args) = sargs + newline lexbuf + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + + | ident + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } - | integer + | integer | xinteger - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } - - | anywhite + - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } - - | eof - { let (_buf,_fin,m,args) = sargs - EOF (LexCont.String(args.ifdefStack,m)) } - | surrogateChar surrogateChar // surrogate code points always come in pairs - | _ - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.String(args.ifdefStack,m))) else string sargs skip lexbuf } + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + + | anywhite + + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } + + | eof + { let (_buf, _fin, m, kind, args) = sargs + EOF (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) } + + | surrogateChar surrogateChar // surrogate code points always come in pairs + + | _ + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m)) + else singleQuoteString sargs skip lexbuf } and verbatimString sargs skip = parse | '"' '"' - { let (buf,_fin,m,args) = sargs + { let (buf, _fin, m, kind, args) = sargs addByteChar buf '\"' - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } - - | '"' - { let (buf,fin,_m,_args) = sargs - let m2 = lexbuf.LexemeRange - callStringFinisher fin buf m2 false } - - | '"''B' - { let (buf,fin,_m,_args) = sargs - let m2 = lexbuf.LexemeRange - callStringFinisher fin buf m2 true } - - | newline - { let (buf,_fin,m,args) = sargs - newline lexbuf - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } - - | ident - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } - - | integer + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | '"' + { let (buf, fin, _m, kind, args) = sargs + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind LexerStringFinisherContext.Verbatim cont + } + + | '"''B' + { let (buf, fin, _m, kind, args) = sargs + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf { kind with IsByteString = true } LexerStringFinisherContext.Verbatim cont + } + + | newline + { let (buf, _fin, m, kind, args) = sargs + newline lexbuf + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | ("{{" | "}}") + { let (buf, _fin, m, kind, args) = sargs + let s = lexeme lexbuf + addUnicodeString buf (if kind.IsInterpolated then s.[0..0] else s) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | "{" + { let (buf, fin, m, kind, args) = sargs + if kind.IsInterpolated then + // get a new range for where the fill starts + let m2 = lexbuf.LexemeRange + args.stringNest <- (1, LexerStringStyle.Verbatim, m2) :: args.stringNest + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind (enum(3)) cont + else + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf + } + + | "}" + { let (buf, _fin, m, kind, args) = sargs + let result() = + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf + if kind.IsInterpolated then + fail args lexbuf (FSComp.SR.lexRBraceInInterpolatedString()) (result()) + else + addUnicodeString buf (lexeme lexbuf) + (result()) + } + + | ident + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | integer | xinteger - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } - - | anywhite + - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } - - | eof - { let (_buf,_fin,m,args) = sargs - EOF (LexCont.VerbatimString(args.ifdefStack,m)) } - | surrogateChar surrogateChar // surrogate code points always come in pairs - | _ - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.VerbatimString(args.ifdefStack,m))) else verbatimString sargs skip lexbuf } + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | anywhite + + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } + + | eof + { let (_buf, _fin, m, kind, args) = sargs + EOF (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) } + + | surrogateChar surrogateChar // surrogate code points always come in pairs + | _ + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m)) + else verbatimString sargs skip lexbuf } and tripleQuoteString sargs skip = parse - | '"' '"' '"' - { let (buf,fin,_m,_args) = sargs - let m2 = lexbuf.LexemeRange - callStringFinisher fin buf m2 false } - - | newline - { let (buf,_fin,m,args) = sargs - newline lexbuf - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString sargs skip lexbuf } - -// The rest is to break into pieces to allow double-click-on-word and other such things - | ident - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString sargs skip lexbuf } - - | integer + | '"' '"' '"' + { let (buf, fin, _m, kind, args) = sargs + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind (enum(4)) cont } + + | newline + { let (buf, _fin, m, kind, args) = sargs + newline lexbuf + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + +// The rest is to break into pieces to allow double-click-on-word and other such things + | ident + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + + | integer | xinteger - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString sargs skip lexbuf } - - | anywhite + - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString sargs skip lexbuf } - - | eof - { let (_buf,_fin,m,args) = sargs - EOF (LexCont.TripleQuoteString(args.ifdefStack,m)) } - | surrogateChar surrogateChar // surrogate code points always come in pairs - | _ - { let (buf,_fin,m,args) = sargs - addUnicodeString buf (lexeme lexbuf) - if not skip then (STRING_TEXT (LexCont.TripleQuoteString(args.ifdefStack,m))) else tripleQuoteString sargs skip lexbuf } - -// Parsing single-line comment - we need to split it into words for Visual Studio IDE -and singleLineComment cargs skip = parse + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + + | anywhite + + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + + | ("{{" | "}}") + { let (buf, _fin, m, kind, args) = sargs + let s = lexeme lexbuf + addUnicodeString buf (if kind.IsInterpolated then s.[0..0] else s) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + + | "{" + { let (buf, fin, m, kind, args) = sargs + if kind.IsInterpolated then + // get a new range for where the fill starts + let m2 = lexbuf.LexemeRange + args.stringNest <- (1, LexerStringStyle.TripleQuote, m2) :: args.stringNest + let cont = LexCont.Token(args.ifdefStack, args.stringNest) + fin.Finish buf kind (enum(5)) cont + else + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf + } + + | "}" + { let (buf, _fin, m, kind, args) = sargs + let result() = + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf + if kind.IsInterpolated then + fail args lexbuf (FSComp.SR.lexRBraceInInterpolatedString()) (result()) + else + addUnicodeString buf (lexeme lexbuf) + (result()) + } + + | eof + { let (_buf, _fin, m, kind, args) = sargs + EOF (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) } + + | surrogateChar surrogateChar // surrogate code points always come in pairs + | _ + { let (buf, _fin, m, kind, args) = sargs + addUnicodeString buf (lexeme lexbuf) + if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m)) + else tripleQuoteString sargs skip lexbuf } + +// Parsing single-line comment - we need to split it into words for Visual Studio IDE +and singleLineComment cargs skip = parse | newline - { let buff,_n,_m,args = cargs + { let buff,_n, _m, args = cargs trySaveXmlDoc lexbuf buff - newline lexbuf + newline lexbuf // Saves the documentation (if we're collecting any) into a buffer-local variable. - if not skip then (LINE_COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - - | eof - { let _, _n,_m,args = cargs - // NOTE: it is legal to end a file with this comment, so we'll return EOF as a token - EOF (LexCont.Token args.ifdefStack) } - + if not skip then LINE_COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | eof + { let _, _n, _m, args = cargs + // NOTE: it is legal to end a file with this comment, so we'll return EOF as a token + EOF (LexCont.Token(args.ifdefStack, args.stringNest)) } + | [^ ' ' '\n' '\r' ]+ | anywhite+ - { let buff,n,m,args = cargs - // Append the current token to the XML documentation if we're collecting it + { let buff, n, m, args = cargs + // Append the current token to the XML documentation if we're collecting it tryAppendXmlDoc buff (lexeme lexbuf) - if not skip then (LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack,n,m))) else singleLineComment (buff,n,m,args) skip lexbuf } - + if not skip then LINE_COMMENT (LexCont.SingleLineComment(args.ifdefStack, args.stringNest, n, m)) + else singleLineComment (buff, n, m, args) skip lexbuf } + | surrogateChar surrogateChar - | _ { let _, _n,_m,args = cargs - if not skip then (LINE_COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } + | _ { let _, _n, _m, args = cargs + if not skip then LINE_COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + - and comment cargs skip = parse | char - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment (n,m,args) skip lexbuf } - - | '"' - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.StringInComment(args.ifdefStack,n,m))) else stringInComment n m args skip lexbuf } + { let n, m, args = cargs + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment (n, m, args) skip lexbuf } - | '"' '"' '"' - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.TripleQuoteStringInComment(args.ifdefStack,n,m))) else tripleQuoteStringInComment n m args skip lexbuf } + | '"' + { let n, m, args = cargs + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) + else stringInComment n m args skip lexbuf } + + | '"' '"' '"' + { let n, m, args = cargs + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, n, m)) + else tripleQuoteStringInComment n m args skip lexbuf } | '@' '"' - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.VerbatimStringInComment(args.ifdefStack,n,m))) else verbatimStringInComment n m args skip lexbuf } + { let n, m, args = cargs + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) + else verbatimStringInComment n m args skip lexbuf } | "(*)" - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment cargs skip lexbuf } + { let n, m, args = cargs + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment cargs skip lexbuf } | '(' '*' - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n+1,m))) else comment (n+1,m,args) skip lexbuf } - + { let n, m, args = cargs + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n+1, m)) + else comment (n+1,m,args) skip lexbuf } + | newline - { let n,m,args = cargs - newline lexbuf - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment cargs skip lexbuf } - | "*)" - { - let n,m,args = cargs - if n > 1 then if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n-1,m))) else comment (n-1,m,args) skip lexbuf - else if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - + { let n, m, args = cargs + newline lexbuf + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment cargs skip lexbuf } + | "*)" + { + let n, m, args = cargs + if n > 1 then + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n-1, m)) + else comment (n-1,m,args) skip lexbuf + else + if not skip then COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + | anywhite+ - | [^ '\'' '(' '*' '\n' '\r' '"' ')' '@' ' ' '\t' ]+ - { let n,m,args = cargs - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment cargs skip lexbuf } - - | eof - { let n,m,args = cargs - EOF (LexCont.Comment(args.ifdefStack,n,m)) } - + | [^ '\'' '(' '*' '\n' '\r' '"' ')' '@' ' ' '\t' ]+ + { let n, m, args = cargs + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment cargs skip lexbuf } + + | eof + { let n, m, args = cargs + EOF (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) } + | surrogateChar surrogateChar - | _ { let n,m,args = cargs - if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment (n,m,args) skip lexbuf } + | _ { let n, m, args = cargs + if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment (n, m, args) skip lexbuf } and stringInComment n m args skip = parse - // Follow string lexing, skipping tokens until it finishes - | '\\' newline anywhite* - { newline lexbuf - if not skip then (COMMENT (LexCont.StringInComment(args.ifdefStack,n,m))) else stringInComment n m args skip lexbuf } + // Follow string lexing, skipping tokens until it finishes + | '\\' newline anywhite* + { newline lexbuf + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) + else stringInComment n m args skip lexbuf } | escape_char | trigraph | hexGraphShort | unicodeGraphShort | unicodeGraphLong - | ident + | ident | integer | xinteger - | anywhite + - { if not skip then (COMMENT (LexCont.StringInComment(args.ifdefStack,n,m))) else stringInComment n m args skip lexbuf } - - - | '"' - { if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment (n,m,args) skip lexbuf } - - | newline - { newline lexbuf - if not skip then (COMMENT (LexCont.StringInComment(args.ifdefStack,n,m))) else stringInComment n m args skip lexbuf } - - | eof - { EOF (LexCont.StringInComment(args.ifdefStack,n,m)) } - + | anywhite + + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) + else stringInComment n m args skip lexbuf } + + + | '"' + { if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment (n, m, args) skip lexbuf } + + | newline + { newline lexbuf + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) + else stringInComment n m args skip lexbuf } + + | eof + { EOF (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) } + | surrogateChar surrogateChar - | _ - { if not skip then (COMMENT (LexCont.StringInComment(args.ifdefStack,n,m))) else stringInComment n m args skip lexbuf } + | _ + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, n, m)) + else stringInComment n m args skip lexbuf } and verbatimStringInComment n m args skip = parse - // Follow verbatimString lexing, in short, skip double-quotes and other chars until we hit a single quote + // Follow verbatimString lexing, in short, skip double-quotes and other chars until we hit a single quote | '"' '"' - { if not skip then (COMMENT (LexCont.VerbatimStringInComment(args.ifdefStack,n,m))) else verbatimStringInComment n m args skip lexbuf } + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) + else verbatimStringInComment n m args skip lexbuf } - | '"' - { if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment (n,m,args) skip lexbuf } + | '"' + { if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment (n, m, args) skip lexbuf } - | ident - | integer + | ident + | integer | xinteger - | anywhite + - { if not skip then (COMMENT (LexCont.VerbatimStringInComment(args.ifdefStack,n,m))) else verbatimStringInComment n m args skip lexbuf } - - | newline + | anywhite + + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) + else verbatimStringInComment n m args skip lexbuf } + + | newline { newline lexbuf - if not skip then (COMMENT (LexCont.VerbatimStringInComment(args.ifdefStack,n,m))) else verbatimStringInComment n m args skip lexbuf } - - | eof - { EOF (LexCont.VerbatimStringInComment(args.ifdefStack,n,m)) } - + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) + else verbatimStringInComment n m args skip lexbuf } + + | eof + { EOF (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) } + | surrogateChar surrogateChar - | _ - { if not skip then (COMMENT (LexCont.VerbatimStringInComment(args.ifdefStack,n,m))) else verbatimStringInComment n m args skip lexbuf } - + | _ + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, n, m)) + else verbatimStringInComment n m args skip lexbuf } + and tripleQuoteStringInComment n m args skip = parse - // Follow tripleQuoteString lexing + // Follow tripleQuoteString lexing | '"' '"' '"' - { if not skip then (COMMENT (LexCont.Comment(args.ifdefStack,n,m))) else comment (n,m,args) skip lexbuf } + { if not skip then COMMENT (LexCont.Comment(args.ifdefStack, args.stringNest, n, m)) + else comment (n, m, args) skip lexbuf } - | ident - | integer + | ident + | integer | xinteger - | anywhite + - { if not skip then (COMMENT (LexCont.TripleQuoteStringInComment(args.ifdefStack,n,m))) else tripleQuoteStringInComment n m args skip lexbuf } - - | newline + | anywhite + + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, n, m)) + else tripleQuoteStringInComment n m args skip lexbuf } + + | newline { newline lexbuf - if not skip then (COMMENT (LexCont.TripleQuoteStringInComment(args.ifdefStack,n,m))) else tripleQuoteStringInComment n m args skip lexbuf } - - | eof - { EOF (LexCont.TripleQuoteStringInComment(args.ifdefStack,n,m)) } - + if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, n, m)) + else tripleQuoteStringInComment n m args skip lexbuf } + + | eof + { EOF (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, n, m)) } + | surrogateChar surrogateChar - | _ - { if not skip then (COMMENT (LexCont.TripleQuoteStringInComment(args.ifdefStack,n,m))) else tripleQuoteStringInComment n m args skip lexbuf } - + | _ + { if not skip then COMMENT (LexCont.StringInComment(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, n, m)) + else tripleQuoteStringInComment n m args skip lexbuf } + and mlOnly m args skip = parse | "\"" - { let buf = ByteBuffer.Create 100 - let m2 = lexbuf.LexemeRange - let _ = string (buf,defaultStringFinisher,m2,args) skip lexbuf - if not skip then (COMMENT (LexCont.MLOnly(args.ifdefStack,m))) else mlOnly m args skip lexbuf } - | newline - { newline lexbuf; if not skip then (COMMENT (LexCont.MLOnly(args.ifdefStack,m))) else mlOnly m args skip lexbuf } - | "(*ENDIF-CAML*)" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - | "(*ENDIF-OCAML*)" - { if not skip then (COMMENT (LexCont.Token args.ifdefStack)) else token args skip lexbuf } - | [^ '(' '"' '\n' '\r' ]+ - { if not skip then (COMMENT (LexCont.MLOnly(args.ifdefStack,m))) else mlOnly m args skip lexbuf } - | eof - { EOF (LexCont.MLOnly(args.ifdefStack,m)) } - | surrogateChar surrogateChar - | _ - { if not skip then (COMMENT (LexCont.MLOnly(args.ifdefStack,m))) else mlOnly m args skip lexbuf } + { let buf = ByteBuffer.Create StringCapacity + let m2 = lexbuf.LexemeRange + let _ = singleQuoteString (buf, LexerStringFinisher.Default, m2, LexerStringKind.String, args) skip lexbuf + if not skip then COMMENT (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) + else mlOnly m args skip lexbuf } + + | newline + { newline lexbuf + if not skip then COMMENT (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) + else mlOnly m args skip lexbuf } + + | "(*ENDIF-CAML*)" + { if not skip then COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | "(*ENDIF-OCAML*)" + { if not skip then COMMENT (LexCont.Token(args.ifdefStack, args.stringNest)) + else token args skip lexbuf } + + | [^ '(' '"' '\n' '\r' ]+ + { if not skip then COMMENT (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) + else mlOnly m args skip lexbuf } + + | eof + { EOF (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) } + + | surrogateChar surrogateChar + | _ + { if not skip then COMMENT (LexCont.MLOnly(args.ifdefStack, args.stringNest, m)) + else mlOnly m args skip lexbuf } diff --git a/src/fsharp/lexhelp.fs b/src/fsharp/lexhelp.fs index 6201ec8a41e..fa24ddfb90e 100644 --- a/src/fsharp/lexhelp.fs +++ b/src/fsharp/lexhelp.fs @@ -6,17 +6,19 @@ open System open System.Text open Internal.Utilities +open Internal.Utilities.Library open Internal.Utilities.Text.Lexing -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Lib -open FSharp.Compiler.Ast -open FSharp.Compiler.PrettyNaming +open FSharp.Compiler.IO open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Range +open FSharp.Compiler.Features +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.UnicodeLexing open FSharp.Compiler.Parser +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range /// The "mock" filename used by fsi.exe when reading from stdin. /// Has special treatment by the lexer, i.e. __SOURCE_DIRECTORY__ becomes GetCurrentDirectory() @@ -33,11 +35,10 @@ type LightSyntaxStatus(initial:bool,warn:bool) = member x.ExplicitlySet = status.IsSome member x.WarnOnMultipleTokens = warn - /// Manage lexer resources (string interning) [] -type LexResourceManager() = - let strings = new System.Collections.Generic.Dictionary(1024) +type LexResourceManager(?capacity: int) = + let strings = System.Collections.Concurrent.ConcurrentDictionary(Environment.ProcessorCount, defaultArg capacity 1024) member x.InternIdentifierToken(s) = match strings.TryGetValue s with | true, res -> res @@ -47,14 +48,17 @@ type LexResourceManager() = res /// Lexer parameters -type lexargs = - { defines: string list - mutable ifdefStack: LexerIfdefStack +type LexArgs = + { + defines: string list resourceManager: LexResourceManager - lightSyntaxStatus : LightSyntaxStatus errorLogger: ErrorLogger applyLineDirectives: bool - pathMap: PathMap } + pathMap: PathMap + mutable ifdefStack: LexerIfdefStack + mutable lightStatus : LightSyntaxStatus + mutable stringNest: LexerInterpolatedStringNesting + } /// possible results of lexing a long Unicode escape sequence in a string literal, e.g. "\U0001F47D", /// "\U000000E7", or "\UDEADBEEF" returning SurrogatePair, SingleChar, or Invalid, respectively @@ -63,14 +67,17 @@ type LongUnicodeLexResult = | SingleChar of uint16 | Invalid -let mkLexargs (_filename, defines, lightSyntaxStatus, resourceManager, ifdefStack, errorLogger, pathMap:PathMap) = - { defines = defines +let mkLexargs (defines, lightStatus, resourceManager, ifdefStack, errorLogger, pathMap:PathMap) = + { + defines = defines ifdefStack= ifdefStack - lightSyntaxStatus=lightSyntaxStatus + lightStatus=lightStatus resourceManager=resourceManager errorLogger=errorLogger applyLineDirectives=true - pathMap=pathMap } + stringNest = [] + pathMap=pathMap + } /// Register the lexbuf and call the given function let reusingLexbufForParsing lexbuf f = @@ -81,11 +88,11 @@ let reusingLexbufForParsing lexbuf f = with e -> raise (WrappedError(e, (try lexbuf.LexemeRange with _ -> range0))) -let resetLexbufPos filename (lexbuf: UnicodeLexing.Lexbuf) = - lexbuf.EndPos <- Position.FirstLine (fileIndexOfFile filename) +let resetLexbufPos filename (lexbuf: Lexbuf) = + lexbuf.EndPos <- Position.FirstLine (FileIndex.fileIndexOfFile filename) /// Reset the lexbuf, configure the initial position with the given filename and call the given function -let usingLexbufForParsing (lexbuf:UnicodeLexing.Lexbuf, filename) f = +let usingLexbufForParsing (lexbuf:Lexbuf, filename) f = resetLexbufPos filename lexbuf reusingLexbufForParsing lexbuf (fun () -> f lexbuf) @@ -93,28 +100,16 @@ let usingLexbufForParsing (lexbuf:UnicodeLexing.Lexbuf, filename) f = // Functions to manipulate lexer transient state //----------------------------------------------------------------------- -let defaultStringFinisher = (fun _endm _b s -> STRING (Encoding.Unicode.GetString(s, 0, s.Length))) - -let callStringFinisher fin (buf: ByteBuffer) endm b = fin endm b (buf.Close()) - -let addUnicodeString (buf: ByteBuffer) (x:string) = buf.EmitBytes (Encoding.Unicode.GetBytes x) - -let addIntChar (buf: ByteBuffer) c = - buf.EmitIntAsByte (c % 256) - buf.EmitIntAsByte (c / 256) - -let addUnicodeChar buf c = addIntChar buf (int c) -let addByteChar buf (c:char) = addIntChar buf (int32 c % 256) - -let stringBufferAsString (buf: byte[]) = +let stringBufferAsString (buf: ByteBuffer) = + let buf = buf.AsMemory() if buf.Length % 2 <> 0 then failwith "Expected even number of bytes" let chars : char[] = Array.zeroCreate (buf.Length/2) for i = 0 to (buf.Length/2) - 1 do - let hi = buf.[i*2+1] - let lo = buf.[i*2] + let hi = buf.Span.[i*2+1] + let lo = buf.Span.[i*2] let c = char (((int hi) * 256) + (int lo)) chars.[i] <- c - System.String(chars) + String(chars) /// When lexing bytearrays we don't expect to see any unicode stuff. /// Likewise when lexing string constants we shouldn't see any trigraphs > 127 @@ -122,20 +117,86 @@ let stringBufferAsString (buf: byte[]) = /// we just take every second byte we stored. Note all bytes > 127 should have been /// stored using addIntChar let stringBufferAsBytes (buf: ByteBuffer) = - let bytes = buf.Close() - Array.init (bytes.Length / 2) (fun i -> bytes.[i*2]) + let bytes = buf.AsMemory() + Array.init (bytes.Length / 2) (fun i -> bytes.Span.[i*2]) + +[] +type LexerStringFinisherContext = + | InterpolatedPart = 1 + | Verbatim = 2 + | TripleQuote = 4 + +type LexerStringFinisher = + | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> LexerStringFinisherContext -> LexerContinuation -> token) + + member fin.Finish (buf: ByteBuffer) kind context cont = + let (LexerStringFinisher f) = fin + f buf kind context cont + + static member Default = + LexerStringFinisher (fun buf kind context cont -> + let isPart = context.HasFlag(LexerStringFinisherContext.InterpolatedPart) + let isVerbatim = context.HasFlag(LexerStringFinisherContext.Verbatim) + let isTripleQuote = context.HasFlag(LexerStringFinisherContext.TripleQuote) + + if kind.IsInterpolated then + let s = stringBufferAsString buf + if kind.IsInterpolatedFirst then + let synStringKind = + if isTripleQuote then + SynStringKind.TripleQuote + elif isVerbatim then + SynStringKind.Verbatim + else + SynStringKind.Regular + if isPart then + INTERP_STRING_BEGIN_PART (s, synStringKind, cont) + else + INTERP_STRING_BEGIN_END (s, synStringKind, cont) + else + if isPart then + INTERP_STRING_PART (s, cont) + else + INTERP_STRING_END (s, cont) + elif kind.IsByteString then + let synByteStringKind = if isVerbatim then SynByteStringKind.Verbatim else SynByteStringKind.Regular + BYTEARRAY (stringBufferAsBytes buf, synByteStringKind, cont) + else + let synStringKind = + if isVerbatim then + SynStringKind.Verbatim + elif isTripleQuote then + SynStringKind.TripleQuote + else + SynStringKind.Regular + STRING (stringBufferAsString buf, synStringKind, cont) + ) + +let addUnicodeString (buf: ByteBuffer) (x:string) = + buf.EmitBytes (Encoding.Unicode.GetBytes x) + +let addIntChar (buf: ByteBuffer) c = + buf.EmitIntAsByte (c % 256) + buf.EmitIntAsByte (c / 256) + +let addUnicodeChar buf c = addIntChar buf (int c) + +let addByteChar buf (c:char) = addIntChar buf (int32 c % 256) /// Sanity check that high bytes are zeros. Further check each low byte <= 127 let stringBufferIsBytes (buf: ByteBuffer) = - let bytes = buf.Close() + let bytes = buf.AsMemory() let mutable ok = true for i = 0 to bytes.Length / 2-1 do - if bytes.[i*2+1] <> 0uy then ok <- false + if bytes.Span.[i*2+1] <> 0uy then ok <- false ok let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine +let advanceColumnBy (lexbuf:LexBuffer<_>) n = + lexbuf.EndPos <- lexbuf.EndPos.ShiftColumnBy(n) + let trigraph c1 c2 c3 = let digit (c:char) = int c - int '0' char (digit c1 * 100 + digit c2 * 10 + digit c3) @@ -193,7 +254,6 @@ let escape c = //----------------------------------------------------------------------- exception ReservedKeyword of string * range -exception IndentationProblem of string * range module Keywords = type private compatibilityMode = @@ -292,9 +352,6 @@ module Keywords = "parallel"; "params"; "process"; "protected"; "pure" "sealed"; "trait"; "tailcall"; "virtual" ] - let private unreserveWords = - keywordList |> List.choose (function (mode, keyword, _) -> if mode = FSHARP then Some keyword else None) - //------------------------------------------------------------------------ // Keywords //----------------------------------------------------------------------- @@ -310,23 +367,30 @@ module Keywords = let KeywordToken s = keywordTable.[s] - let IdentifierToken args (lexbuf:UnicodeLexing.Lexbuf) (s:string) = + let IdentifierToken args (lexbuf:Lexbuf) (s:string) = if IsCompilerGeneratedName s then warning(Error(FSComp.SR.lexhlpIdentifiersContainingAtSymbolReserved(), lexbuf.LexemeRange)) args.resourceManager.InternIdentifierToken s - let KeywordOrIdentifierToken args (lexbuf:UnicodeLexing.Lexbuf) s = + let KeywordOrIdentifierToken args (lexbuf:Lexbuf) s = match keywordTable.TryGetValue s with | true, v -> match v with | RESERVED -> warning(ReservedKeyword(FSComp.SR.lexhlpIdentifierReserved(s), lexbuf.LexemeRange)) IdentifierToken args lexbuf s - | _ -> v + | _ -> + match s with + | "land" | "lor" | "lxor" + | "lsl" | "lsr" | "asr" -> + if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatWarning (FSComp.SR.mlCompatKeyword(s)) lexbuf.LexemeRange + | _ -> () + v | _ -> match s with | "__SOURCE_DIRECTORY__" -> - let filename = fileOfFileIndex lexbuf.StartPos.FileIndex + let filename = FileIndex.fileOfFileIndex lexbuf.StartPos.FileIndex let dirname = if String.IsNullOrWhiteSpace(filename) then String.Empty @@ -339,107 +403,11 @@ module Keywords = if String.IsNullOrEmpty dirname then dirname else PathMap.applyDir args.pathMap dirname - |> KEYWORD_STRING + |> fun dir -> KEYWORD_STRING(s, dir) | "__SOURCE_FILE__" -> - KEYWORD_STRING (System.IO.Path.GetFileName((fileOfFileIndex lexbuf.StartPos.FileIndex))) + KEYWORD_STRING (s, System.IO.Path.GetFileName (FileIndex.fileOfFileIndex lexbuf.StartPos.FileIndex)) | "__LINE__" -> - KEYWORD_STRING (string lexbuf.StartPos.Line) + KEYWORD_STRING (s, string lexbuf.StartPos.Line) | _ -> IdentifierToken args lexbuf s - let DoesIdentifierNeedQuotation (s : string) : bool = - not (String.forall IsIdentifierPartCharacter s) // if it has funky chars - || s.Length > 0 && (not(IsIdentifierFirstCharacter s.[0])) // or if it starts with a non-(letter-or-underscore) - || keywordTable.ContainsKey s // or if it's a language keyword like "type" - - /// A utility to help determine if an identifier needs to be quoted - let QuoteIdentifierIfNeeded (s : string) : string = - if DoesIdentifierNeedQuotation s then "``" + s + "``" else s - - /// Quote identifier with double backticks if needed, remove unnecessary double backticks quotation. - let NormalizeIdentifierBackticks (s : string) : string = - let s = - if s.StartsWithOrdinal("``") && s.EndsWithOrdinal("``") then - s.[2..s.Length - 3] - else s - QuoteIdentifierIfNeeded s - - /// Keywords paired with their descriptions. Used in completion and quick info. - let keywordsWithDescription : (string * string) list = - [ "abstract", FSComp.SR.keywordDescriptionAbstract() - "and", FSComp.SR.keyworkDescriptionAnd() - "as", FSComp.SR.keywordDescriptionAs() - "assert", FSComp.SR.keywordDescriptionAssert() - "base", FSComp.SR.keywordDescriptionBase() - "begin", FSComp.SR.keywordDescriptionBegin() - "class", FSComp.SR.keywordDescriptionClass() - "default", FSComp.SR.keywordDescriptionDefault() - "delegate", FSComp.SR.keywordDescriptionDelegate() - "do", FSComp.SR.keywordDescriptionDo() - "done", FSComp.SR.keywordDescriptionDone() - "downcast", FSComp.SR.keywordDescriptionDowncast() - "downto", FSComp.SR.keywordDescriptionDownto() - "elif", FSComp.SR.keywordDescriptionElif() - "else", FSComp.SR.keywordDescriptionElse() - "end", FSComp.SR.keywordDescriptionEnd() - "exception", FSComp.SR.keywordDescriptionException() - "extern", FSComp.SR.keywordDescriptionExtern() - "false", FSComp.SR.keywordDescriptionTrueFalse() - "finally", FSComp.SR.keywordDescriptionFinally() - "for", FSComp.SR.keywordDescriptionFor() - "fun", FSComp.SR.keywordDescriptionFun() - "function", FSComp.SR.keywordDescriptionFunction() - "global", FSComp.SR.keywordDescriptionGlobal() - "if", FSComp.SR.keywordDescriptionIf() - "in", FSComp.SR.keywordDescriptionIn() - "inherit", FSComp.SR.keywordDescriptionInherit() - "inline", FSComp.SR.keywordDescriptionInline() - "interface", FSComp.SR.keywordDescriptionInterface() - "internal", FSComp.SR.keywordDescriptionInternal() - "lazy", FSComp.SR.keywordDescriptionLazy() - "let", FSComp.SR.keywordDescriptionLet() - "let!", FSComp.SR.keywordDescriptionLetBang() - "match", FSComp.SR.keywordDescriptionMatch() - "match!", FSComp.SR.keywordDescriptionMatchBang() - "member", FSComp.SR.keywordDescriptionMember() - "module", FSComp.SR.keywordDescriptionModule() - "mutable", FSComp.SR.keywordDescriptionMutable() - "namespace", FSComp.SR.keywordDescriptionNamespace() - "new", FSComp.SR.keywordDescriptionNew() - "not", FSComp.SR.keywordDescriptionNot() - "null", FSComp.SR.keywordDescriptionNull() - "of", FSComp.SR.keywordDescriptionOf() - "open", FSComp.SR.keywordDescriptionOpen() - "or", FSComp.SR.keywordDescriptionOr() - "override", FSComp.SR.keywordDescriptionOverride() - "private", FSComp.SR.keywordDescriptionPrivate() - "public", FSComp.SR.keywordDescriptionPublic() - "rec", FSComp.SR.keywordDescriptionRec() - "return", FSComp.SR.keywordDescriptionReturn() - "return!", FSComp.SR.keywordDescriptionReturnBang() - "select", FSComp.SR.keywordDescriptionSelect() - "static", FSComp.SR.keywordDescriptionStatic() - "struct", FSComp.SR.keywordDescriptionStruct() - "then", FSComp.SR.keywordDescriptionThen() - "to", FSComp.SR.keywordDescriptionTo() - "true", FSComp.SR.keywordDescriptionTrueFalse() - "try", FSComp.SR.keywordDescriptionTry() - "type", FSComp.SR.keywordDescriptionType() - "upcast", FSComp.SR.keywordDescriptionUpcast() - "use", FSComp.SR.keywordDescriptionUse() - "use!", FSComp.SR.keywordDescriptionUseBang() - "val", FSComp.SR.keywordDescriptionVal() - "void", FSComp.SR.keywordDescriptionVoid() - "when", FSComp.SR.keywordDescriptionWhen() - "while", FSComp.SR.keywordDescriptionWhile() - "with", FSComp.SR.keywordDescriptionWith() - "yield", FSComp.SR.keywordDescriptionYield() - "yield!", FSComp.SR.keywordDescriptionYieldBang() - "->", FSComp.SR.keywordDescriptionRightArrow() - "<-", FSComp.SR.keywordDescriptionLeftArrow() - ":>", FSComp.SR.keywordDescriptionCast() - ":?>", FSComp.SR.keywordDescriptionDynamicCast() - "<@", FSComp.SR.keywordDescriptionTypedQuotation() - "@>", FSComp.SR.keywordDescriptionTypedQuotation() - "<@@", FSComp.SR.keywordDescriptionUntypedQuotation() - "@@>", FSComp.SR.keywordDescriptionUntypedQuotation() ] diff --git a/src/fsharp/lexhelp.fsi b/src/fsharp/lexhelp.fsi index bcc1bc3dc8a..9f6981610b8 100644 --- a/src/fsharp/lexhelp.fsi +++ b/src/fsharp/lexhelp.fsi @@ -2,76 +2,107 @@ module internal FSharp.Compiler.Lexhelp +open FSharp.Compiler.IO open Internal.Utilities open Internal.Utilities.Text -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Ast -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler - +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.UnicodeLexing +open FSharp.Compiler.Parser +open FSharp.Compiler.Text -val stdinMockFilename : string +val stdinMockFilename: string +/// Lexer args: status of #light processing. Mutated when a #light +/// directive is processed. This alters the behaviour of the lexfilter. [] type LightSyntaxStatus = - new : initial:bool * warn : bool -> LightSyntaxStatus - member ExplicitlySet : bool - member Status : bool - member Status : bool with set - member WarnOnMultipleTokens : bool + new: initial:bool * warn: bool -> LightSyntaxStatus + member ExplicitlySet: bool + member Status: bool + member Status: bool with set + member WarnOnMultipleTokens: bool [] type LexResourceManager = - new : unit -> LexResourceManager + new: ?capacity: int -> LexResourceManager -type lexargs = - { defines: string list - mutable ifdefStack: LexerIfdefStack +/// The context applicable to all lexing functions (tokens, strings etc.) +type LexArgs = + { + defines: string list resourceManager: LexResourceManager - lightSyntaxStatus : LightSyntaxStatus errorLogger: ErrorLogger applyLineDirectives: bool - pathMap: PathMap } + pathMap: PathMap + mutable ifdefStack: LexerIfdefStack + mutable lightStatus : LightSyntaxStatus + mutable stringNest: LexerInterpolatedStringNesting + } type LongUnicodeLexResult = | SurrogatePair of uint16 * uint16 | SingleChar of uint16 | Invalid -val resetLexbufPos : string -> UnicodeLexing.Lexbuf -> unit -val mkLexargs : 'a * string list * LightSyntaxStatus * LexResourceManager * LexerIfdefStack * ErrorLogger * PathMap -> lexargs -val reusingLexbufForParsing : UnicodeLexing.Lexbuf -> (unit -> 'a) -> 'a - -val usingLexbufForParsing : UnicodeLexing.Lexbuf * string -> (UnicodeLexing.Lexbuf -> 'a) -> 'a -val defaultStringFinisher : 'a -> 'b -> byte[] -> Parser.token -val callStringFinisher : ('a -> 'b -> byte[] -> 'c) -> AbstractIL.Internal.ByteBuffer -> 'a -> 'b -> 'c -val addUnicodeString : AbstractIL.Internal.ByteBuffer -> string -> unit -val addUnicodeChar : AbstractIL.Internal.ByteBuffer -> int -> unit -val addByteChar : AbstractIL.Internal.ByteBuffer -> char -> unit -val stringBufferAsString : byte[] -> string -val stringBufferAsBytes : AbstractIL.Internal.ByteBuffer -> byte[] -val stringBufferIsBytes : AbstractIL.Internal.ByteBuffer -> bool -val newline : Lexing.LexBuffer<'a> -> unit -val trigraph : char -> char -> char -> char -val digit : char -> int32 -val hexdigit : char -> int32 -val unicodeGraphShort : string -> uint16 -val hexGraphShort : string -> uint16 -val unicodeGraphLong : string -> LongUnicodeLexResult -val escape : char -> char - -exception ReservedKeyword of string * Range.range -exception IndentationProblem of string * Range.range - -module Keywords = - val KeywordOrIdentifierToken : lexargs -> UnicodeLexing.Lexbuf -> string -> Parser.token - val IdentifierToken : lexargs -> UnicodeLexing.Lexbuf -> string -> Parser.token - val DoesIdentifierNeedQuotation : string -> bool - val QuoteIdentifierIfNeeded : string -> string - val NormalizeIdentifierBackticks : string -> string - val keywordNames : string list - /// Keywords paired with their descriptions. Used in completion and quick info. - val keywordsWithDescription : (string * string) list +val resetLexbufPos: string -> Lexbuf -> unit + +val mkLexargs: string list * LightSyntaxStatus * LexResourceManager * LexerIfdefStack * ErrorLogger * PathMap -> LexArgs + +val reusingLexbufForParsing: Lexbuf -> (unit -> 'a) -> 'a + +val usingLexbufForParsing: Lexbuf * string -> (Lexbuf -> 'a) -> 'a + +type LexerStringFinisherContext = + | InterpolatedPart = 1 + | Verbatim = 2 + | TripleQuote = 4 + +type LexerStringFinisher = + | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> LexerStringFinisherContext -> LexerContinuation -> token) + + member Finish: buf: ByteBuffer -> kind: LexerStringKind -> context: LexerStringFinisherContext -> cont: LexerContinuation -> token + + static member Default: LexerStringFinisher + +val addUnicodeString: ByteBuffer -> string -> unit + +val addUnicodeChar: ByteBuffer -> int -> unit + +val addByteChar: ByteBuffer -> char -> unit + +val stringBufferAsString: ByteBuffer -> string + +val stringBufferAsBytes: ByteBuffer -> byte[] + +val stringBufferIsBytes: ByteBuffer -> bool + +val newline: Lexing.LexBuffer<'a> -> unit + +val advanceColumnBy: Lexing.LexBuffer<'a> -> n: int -> unit + +val trigraph: char -> char -> char -> char + +val digit: char -> int32 + +val hexdigit: char -> int32 + +val unicodeGraphShort: string -> uint16 + +val hexGraphShort: string -> uint16 + +val unicodeGraphLong: string -> LongUnicodeLexResult + +val escape: char -> char + +exception ReservedKeyword of string * range + +module Keywords = + + val KeywordOrIdentifierToken: LexArgs -> Lexbuf -> string -> token + + val IdentifierToken: LexArgs -> Lexbuf -> string -> token + + val keywordNames: string list + diff --git a/src/fsharp/lib.fs b/src/fsharp/lib.fs index b9653f35c7d..0a0352a7e2b 100755 --- a/src/fsharp/lib.fs +++ b/src/fsharp/lib.fs @@ -1,135 +1,114 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module internal FSharp.Compiler.Lib +module internal Internal.Utilities.Library.Extras +open System open System.IO open System.Collections.Generic +open System.Threading +open System.Threading.Tasks open System.Runtime.InteropServices -open Internal.Utilities -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Collections +open Internal.Utilities.Library +let debug = false -/// is this the developer-debug build? -let debug = false let verbose = false -let mutable progress = false -let mutable tracking = false // intended to be a general hook to control diagnostic output when tracking down bugs -let condition s = - try (System.Environment.GetEnvironmentVariable(s) <> null) with _ -> false +let mutable progress = false -let GetEnvInteger e dflt = match System.Environment.GetEnvironmentVariable(e) with null -> dflt | t -> try int t with _ -> dflt +// Intended to be a general hook to control diagnostic output when tracking down bugs +let mutable tracking = false -let dispose (x:System.IDisposable) = match x with null -> () | x -> x.Dispose() +let condition s = + try (Environment.GetEnvironmentVariable(s) <> null) with _ -> false + +let GetEnvInteger e dflt = match Environment.GetEnvironmentVariable(e) with null -> dflt | t -> try int t with _ -> dflt + +let dispose (x:IDisposable) = match x with null -> () | x -> x.Dispose() //------------------------------------------------------------------------- // Library: bits //------------------------------------------------------------------------ -module Bits = - let b0 n = (n &&& 0xFF) - let b1 n = ((n >>> 8) &&& 0xFF) - let b2 n = ((n >>> 16) &&& 0xFF) - let b3 n = ((n >>> 24) &&& 0xFF) +module Bits = + let b0 n = (n &&& 0xFF) + let b1 n = ((n >>> 8) &&& 0xFF) + let b2 n = ((n >>> 16) &&& 0xFF) + let b3 n = ((n >>> 24) &&& 0xFF) let rec pown32 n = if n = 0 then 0 else (pown32 (n-1) ||| (1 <<< (n-1))) let rec pown64 n = if n = 0 then 0L else (pown64 (n-1) ||| (1L <<< (n-1))) let mask32 m n = (pown32 n) <<< m let mask64 m n = (pown64 n) <<< m - -//------------------------------------------------------------------------- -// Library: files -//------------------------------------------------------------------------ - -module Filename = - let fullpath cwd nm = - let p = if FileSystem.IsPathRootedShim(nm) then nm else Path.Combine(cwd, nm) - try FileSystem.GetFullPathShim(p) with - | :? System.ArgumentException - | :? System.ArgumentNullException - | :? System.NotSupportedException - | :? System.IO.PathTooLongException - | :? System.Security.SecurityException -> p - - let hasSuffixCaseInsensitive suffix filename = (* case-insensitive *) - Filename.checkSuffix (String.lowercase filename) (String.lowercase suffix) - - let isDll file = hasSuffixCaseInsensitive ".dll" file - //------------------------------------------------------------------------- // Library: Orders //------------------------------------------------------------------------ -module Bool = +module Bool = let order = LanguagePrimitives.FastGenericComparer -module Int32 = +module Int32 = let order = LanguagePrimitives.FastGenericComparer -module Int64 = +module Int64 = let order = LanguagePrimitives.FastGenericComparer -module Pair = +module Pair = let order (compare1: IComparer<'T1>, compare2: IComparer<'T2>) = - { new IComparer<'T1 * 'T2> with - member __.Compare((a1, a2), (aa1, aa2)) = + { new IComparer<'T1 * 'T2> with + member _.Compare((a1, a2), (aa1, aa2)) = let res1 = compare1.Compare (a1, aa1) if res1 <> 0 then res1 else compare2.Compare (a2, aa2) } type NameSet = Zset -[] + module NameSet = let ofList l : NameSet = List.foldBack Zset.add l (Zset.empty String.order) -[] -module NameMap = +module NameMap = let domain m = Map.foldBack (fun x _ acc -> Zset.add x acc) m (Zset.empty String.order) let domainL m = Zset.elements (domain m) - - -//--------------------------------------------------------------------------- // Library: Pre\Post checks -//------------------------------------------------------------------------- -module Check = - - /// Throw System.InvalidOperationException() if argument is None. +//------------------------------------------------------------------------- +module Check = + + /// Throw System.InvalidOperationException if argument is None. /// If there is a value (e.g. Some(value)) then value is returned. - let NotNone argName (arg:'T option) : 'T = - match arg with - | None -> raise (new System.InvalidOperationException(argName)) + let NotNone argName (arg:'T option) : 'T = + match arg with + | None -> raise (InvalidOperationException(argName)) | Some x -> x - /// Throw System.ArgumentNullException() if argument is null. - let ArgumentNotNull arg argName = - match box(arg) with - | null -> raise (new System.ArgumentNullException(argName)) + /// Throw System.ArgumentNullException if argument is null. + let ArgumentNotNull arg argName = + match box(arg) with + | null -> raise (ArgumentNullException(argName)) | _ -> () - - - /// Throw System.ArgumentNullException() if array argument is null. - /// Throw System.ArgumentOutOfRangeException() is array argument is empty. - let ArrayArgumentNotNullOrEmpty (arr:'T[]) argName = + + /// Throw System.ArgumentNullException if array argument is null. + /// Throw System.ArgumentOutOfRangeException is array argument is empty. + let ArrayArgumentNotNullOrEmpty (arr:'T[]) argName = ArgumentNotNull arr argName if (0 = arr.Length) then - raise (new System.ArgumentOutOfRangeException(argName)) + raise (ArgumentOutOfRangeException(argName)) - /// Throw System.ArgumentNullException() if string argument is null. - /// Throw System.ArgumentOutOfRangeException() is string argument is empty. - let StringArgumentNotNullOrEmpty (s:string) argName = + /// Throw System.ArgumentNullException if string argument is null. + /// Throw System.ArgumentOutOfRangeException is string argument is empty. + let StringArgumentNotNullOrEmpty (s:string) argName = ArgumentNotNull s argName if s.Length = 0 then - raise (new System.ArgumentNullException(argName)) + raise (ArgumentNullException(argName)) //------------------------------------------------------------------------- -// Library +// Library //------------------------------------------------------------------------ type IntMap<'T> = Zmap -module IntMap = +module IntMap = let empty () = Zmap.empty Int32.order let add k v (t:IntMap<'T>) = Zmap.add k v t @@ -138,7 +117,7 @@ module IntMap = let remove k (t:IntMap<'T>) = Zmap.remove k t let mem k (t:IntMap<'T>) = Zmap.mem k t let iter f (t:IntMap<'T>) = Zmap.iter f t - let map f (t:IntMap<'T>) = Zmap.map f t + let map f (t:IntMap<'T>) = Zmap.map f t let fold f (t:IntMap<'T>) z = Zmap.fold f t z @@ -151,16 +130,16 @@ module ListAssoc = /// Treat a list of key-value pairs as a lookup collection. /// This function looks up a value based on a match from the supplied /// predicate function. - let rec find f x l = - match l with + let rec find f x l = + match l with | [] -> notFound() | (x2, y) :: t -> if f x x2 then y else find f x t /// Treat a list of key-value pairs as a lookup collection. /// This function looks up a value based on a match from the supplied /// predicate function and returns None if value does not exist. - let rec tryFind (f:'key->'key->bool) (x:'key) (l:('key*'value) list) : 'value option = - match l with + let rec tryFind (f:'key->'key->bool) (x:'key) (l:('key*'value) list) : 'value option = + match l with | [] -> None | (x2, y) :: t -> if f x x2 then Some y else tryFind f x t @@ -168,56 +147,58 @@ module ListAssoc = // Library: lists as generalized sets //------------------------------------------------------------------------ -module ListSet = +module ListSet = let inline contains f x l = List.exists (f x) l - (* NOTE: O(n)! *) + /// NOTE: O(n)! let insert f x l = if contains f x l then l else x :: l - let unionFavourRight f l1 l2 = - match l1, l2 with + let unionFavourRight f l1 l2 = + match l1, l2 with | _, [] -> l1 - | [], _ -> l2 + | [], _ -> l2 | _ -> List.foldBack (insert f) l1 l2 (* nb. foldBack to preserve natural orders *) - (* NOTE: O(n)! *) + /// NOTE: O(n)! let rec private findIndexAux eq x l n = match l with | [] -> notFound() - | (h :: t) -> if eq h x then n else findIndexAux eq x t (n+1) + | h :: t -> if eq h x then n else findIndexAux eq x t (n+1) + /// NOTE: O(n)! let findIndex eq x l = findIndexAux eq x l 0 - let rec remove f x l = - match l with - | (h :: t) -> if f x h then t else h :: remove f x t + let rec remove f x l = + match l with + | h :: t -> if f x h then t else h :: remove f x t | [] -> [] - (* NOTE: quadratic! *) - let rec subtract f l1 l2 = - match l2 with - | (h :: t) -> subtract f (remove (fun y2 y1 -> f y1 y2) h l1) t + /// NOTE: quadratic! + let rec subtract f l1 l2 = + match l2 with + | h :: t -> subtract f (remove (fun y2 y1 -> f y1 y2) h l1) t | [] -> l1 let isSubsetOf f l1 l2 = List.forall (fun x1 -> contains f x1 l2) l1 - (* nb. preserve orders here: f must be applied to elements of l1 then elements of l2*) + + /// nb. preserve orders here: f must be applied to elements of l1 then elements of l2 let isSupersetOf f l1 l2 = List.forall (fun x2 -> contains (fun y2 y1 -> f y1 y2) x2 l1) l2 + let equals f l1 l2 = isSubsetOf f l1 l2 && isSupersetOf f l1 l2 - let unionFavourLeft f l1 l2 = - match l1, l2 with - | _, [] -> l1 - | [], _ -> l2 + let unionFavourLeft f l1 l2 = + match l1, l2 with + | _, [] -> l1 + | [], _ -> l2 | _ -> l1 @ (subtract f l2 l1) - - (* NOTE: not tail recursive! *) - let rec intersect f l1 l2 = - match l2 with - | (h :: t) -> if contains f h l1 then h :: intersect f l1 t else intersect f l1 t + /// NOTE: not tail recursive! + let rec intersect f l1 l2 = + match l2 with + | h :: t -> if contains f h l1 then h :: intersect f l1 t else intersect f l1 t | [] -> [] - // Note: if duplicates appear, keep the ones toward the _front_ of the list + /// Note: if duplicates appear, keep the ones toward the _front_ of the list let setify f l = List.fold (fun acc x -> insert f x acc) [] l |> List.rev let hasDuplicates f l = @@ -231,7 +212,7 @@ module ListSet = | [] -> false | x :: rest -> if contains f x acc then - true + true else loop (x :: acc) rest @@ -242,41 +223,74 @@ module ListSet = //------------------------------------------------------------------------ let mapFoldFst f s (x, y) = let x2, s = f s x in (x2, y), s + let mapFoldSnd f s (x, y) = let y2, s = f s y in (x, y2), s -let pair a b = a, b + +let pair a b = a, b let p13 (x, _y, _z) = x + let p23 (_x, y, _z) = y + let p33 (_x, _y, z) = z +let p14 (x1, _x2, _x3, _x4) = x1 + +let p24 (_x1, x2, _x3, _x4) = x2 + +let p34 (_x1, _x2, x3, _x4) = x3 + +let p44 (_x1, _x2, _x3, x4) = x4 + +let p15 (x1, _x2, _x3, _x4, _x5) = x1 + +let p25 (_x1, x2, _x3, _x4, _x5) = x2 + +let p35 (_x1, _x2, x3, _x4, _x5) = x3 + +let p45 (_x1, _x2, _x3, x4, _x5) = x4 + +let p55 (_x1, _x2, _x3, _x4, x5) = x5 + let map1Of2 f (a1, a2) = (f a1, a2) + let map2Of2 f (a1, a2) = (a1, f a2) + let map1Of3 f (a1, a2, a3) = (f a1, a2, a3) + let map2Of3 f (a1, a2, a3) = (a1, f a2, a3) + let map3Of3 f (a1, a2, a3) = (a1, a2, f a3) + let map3Of4 f (a1, a2, a3, a4) = (a1, a2, f a3, a4) + let map4Of4 f (a1, a2, a3, a4) = (a1, a2, a3, f a4) + let map5Of5 f (a1, a2, a3, a4, a5) = (a1, a2, a3, a4, f a5) + let map6Of6 f (a1, a2, a3, a4, a5, a6) = (a1, a2, a3, a4, a5, f a6) + let foldPair (f1, f2) acc (a1, a2) = f2 (f1 acc a1) a2 + let fold1Of2 f1 acc (a1, _a2) = f1 acc a1 + let foldTriple (f1, f2, f3) acc (a1, a2, a3) = f3 (f2 (f1 acc a1) a2) a3 + let foldQuadruple (f1, f2, f3, f4) acc (a1, a2, a3, a4) = f4 (f3 (f2 (f1 acc a1) a2) a3) a4 + let mapPair (f1, f2) (a1, a2) = (f1 a1, f2 a2) + let mapTriple (f1, f2, f3) (a1, a2, a3) = (f1 a1, f2 a2, f3 a3) + let mapQuadruple (f1, f2, f3, f4) (a1, a2, a3, a4) = (f1 a1, f2 a2, f3 a3, f4 a4) -let fmap2Of2 f z (a1, a2) = let z, a2 = f z a2 in z, (a1, a2) -module List = - let noRepeats xOrder xs = - let s = Zset.addList xs (Zset.empty xOrder) // build set - Zset.elements s // get elements... no repeats +let fmap2Of2 f z (a1, a2) = let z, a2 = f z a2 in z, (a1, a2) //--------------------------------------------------------------------------- // Zmap rebinds -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- -module Zmap = +module Zmap = let force k mp = match Zmap.tryFind k mp with Some x -> x | None -> failwith "Zmap.force: lookup failed" let mapKey key f mp = @@ -286,7 +300,7 @@ module Zmap = //--------------------------------------------------------------------------- // Zset -//------------------------------------------------------------------------- +//------------------------------------------------------------------------- module Zset = let ofList order xs = Zset.addList xs (Zset.empty order) @@ -297,60 +311,45 @@ module Zset = if Zset.equal s s0 then s0 (* fixed *) else fixpoint f s (* iterate *) -//--------------------------------------------------------------------------- -// Misc -//------------------------------------------------------------------------- - let equalOn f x y = (f x) = (f y) - -//--------------------------------------------------------------------------- -// Buffer printing utilities -//--------------------------------------------------------------------------- - -let bufs f = - let buf = System.Text.StringBuilder 100 - f buf +/// Buffer printing utility +let bufs f = + let buf = System.Text.StringBuilder 100 + f buf buf.ToString() -let buff (os: TextWriter) f x = - let buf = System.Text.StringBuilder 100 - f buf x +/// Writing to output stream via a string buffer. +let writeViaBuffer (os: TextWriter) f x = + let buf = System.Text.StringBuilder 100 + f buf x os.Write(buf.ToString()) -// Converts "\n" into System.Environment.NewLine before writing to os. See lib.fs:buff -let writeViaBufferWithEnvironmentNewLines (os: TextWriter) f x = - let buf = System.Text.StringBuilder 100 - f buf x - let text = buf.ToString() - let text = text.Replace("\n", System.Environment.NewLine) - os.Write text - //--------------------------------------------------------------------------- -// Imperative Graphs +// Imperative Graphs //--------------------------------------------------------------------------- type GraphNode<'Data, 'Id> = { nodeId: 'Id; nodeData: 'Data; mutable nodeNeighbours: GraphNode<'Data, 'Id> list } type Graph<'Data, 'Id when 'Id : comparison and 'Id : equality> - (nodeIdentity: ('Data -> 'Id), + (nodeIdentity: 'Data -> 'Id, nodes: 'Data list, edges: ('Data * 'Data) list) = let edges = edges |> List.map (fun (v1, v2) -> nodeIdentity v1, nodeIdentity v2) - let nodes = nodes |> List.map (fun d -> nodeIdentity d, { nodeId = nodeIdentity d; nodeData=d; nodeNeighbours=[] }) - let tab = Map.ofList nodes + let nodes = nodes |> List.map (fun d -> nodeIdentity d, { nodeId = nodeIdentity d; nodeData=d; nodeNeighbours=[] }) + let tab = Map.ofList nodes let nodes = List.map snd nodes - do for node in nodes do + do for node in nodes do node.nodeNeighbours <- edges |> List.filter (fun (x, _y) -> x = node.nodeId) |> List.map (fun (_, nodeId) -> tab.[nodeId]) member g.GetNodeData nodeId = tab.[nodeId].nodeData - member g.IterateCycles f = - let rec trace path node = + member g.IterateCycles f = + let rec trace path node = if List.exists (nodeIdentity >> (=) node.nodeId) path then f (List.rev path) else List.iter (trace (node.nodeData :: path)) node.nodeNeighbours - List.iter (fun node -> trace [] node) nodes + List.iter (fun node -> trace [] node) nodes //--------------------------------------------------------------------------- // In some cases we play games where we use 'null' as a more efficient representation @@ -362,8 +361,8 @@ type Graph<'Data, 'Id when 'Id : comparison and 'Id : equality> // The following DEBUG code does not currently compile. //#if DEBUG -//type 'T NonNullSlot = 'T option -//let nullableSlotEmpty() = None +//type 'T NonNullSlot = 'T option +//let nullableSlotEmpty() = None //let nullableSlotFull(x) = Some x //#else type NonNullSlot<'T> = 'T @@ -378,19 +377,19 @@ let nullableSlotFull x = x type cache<'T> = { mutable cacheVal: 'T NonNullSlot } let newCache() = { cacheVal = nullableSlotEmpty() } -let inline cached cache resF = - match box cache.cacheVal with - | null -> - let res = resF() - cache.cacheVal <- nullableSlotFull res +let inline cached cache resF = + match box cache.cacheVal with + | null -> + let res = resF() + cache.cacheVal <- nullableSlotFull res res - | _ -> + | _ -> cache.cacheVal -let inline cacheOptByref (cache: byref<'T option>) f = - match cache with +let inline cacheOptByref (cache: byref<'T option>) f = + match cache with | Some v -> v - | None -> + | None -> let res = f() cache <- Some res res @@ -398,13 +397,13 @@ let inline cacheOptByref (cache: byref<'T option>) f = // REVIEW: this is only used because we want to mutate a record field, // and because you cannot take a byref<_> of such a thing directly, // we cannot use 'cacheOptByref'. If that is changed, this can be removed. -let inline cacheOptRef cache f = - match !cache with +let inline cacheOptRef (cache: _ ref) f = + match cache.Value with | Some v -> v - | None -> + | None -> let res = f() - cache := Some res - res + cache.Value <- Some res + res let inline tryGetCacheValue cache = match box cache.cacheVal with @@ -414,7 +413,7 @@ let inline tryGetCacheValue cache = #if DUMPER type Dumper(x:obj) = [] - member self.Dump = sprintf "%A" x + member self.Dump = sprintf "%A" x #endif //--------------------------------------------------------------------------- @@ -422,8 +421,6 @@ type Dumper(x:obj) = //--------------------------------------------------------------------------- module internal AsyncUtil = - open System - open System.Threading open Microsoft.FSharp.Control /// Represents the reified result of an asynchronous computation. @@ -446,9 +443,9 @@ module internal AsyncUtil = let mutable result = None // The continuation for the result, if any let mutable savedConts = [] - - let syncRoot = new obj() - + + let syncRoot = obj() + // Record the result in the AsyncResultCell. // Ignore subsequent sets of the result. This can happen, e.g. for a race between @@ -462,7 +459,7 @@ module internal AsyncUtil = result <- Some res // Invoke continuations in FIFO order // Continuations that Async.FromContinuations provide do QUWI/SyncContext.Post, - // so the order is not overly relevant but still. + // so the order is not overly relevant but still. List.rev savedConts) let postOrQueue (sc:SynchronizationContext, cont) = match sc with @@ -472,7 +469,7 @@ module internal AsyncUtil = // Run continuations outside the lock match grabbedConts with | [] -> () - | [(sc, cont) as c] -> + | [sc, cont as c] -> if SynchronizationContext.Current = sc then cont res else @@ -497,7 +494,7 @@ module internal AsyncUtil = match grabbedResult with | None -> () | Some res -> cont res) - + /// Get the result and Commit(...). member x.AsyncResult = @@ -511,14 +508,12 @@ module internal AsyncUtil = // USAGE: call UnmanagedProcessExecutionOptions.EnableHeapTerminationOnCorruption() from "main()". // Note: This is not SDL required but recommended. module UnmanagedProcessExecutionOptions = - open System - open System.Runtime.InteropServices - [] + [] extern UIntPtr private GetProcessHeap() [] - extern bool private HeapSetInformation( + extern bool private HeapSetInformation( UIntPtr _HeapHandle, UInt32 _HeapInformationClass, UIntPtr _HeapInformation, @@ -528,10 +523,10 @@ module UnmanagedProcessExecutionOptions = extern UInt32 private GetLastError() // Translation of C# from http://swikb/v1/DisplayOnlineDoc.aspx?entryID=826 and copy in bug://5018 - [] + [] let EnableHeapTerminationOnCorruption() = - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && System.Environment.OSVersion.Version.Major >= 6 && // If OS is Vista or higher - System.Environment.Version.Major < 3) then // and CLR not 3.0 or higher + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version.Major >= 6 && // If OS is Vista or higher + Environment.Version.Major < 3) then // and CLR not 3.0 or higher // "The flag HeapSetInformation sets is available in Windows XP SP3 and later. // The data structure used for heap information is available on earlier versions of Windows. // The call will either return TRUE (found and set the flag) or false (flag not found). @@ -544,9 +539,9 @@ module UnmanagedProcessExecutionOptions = // http://blogs.msdn.com/michael_howard/archive/2008/02/18/faq-about-heapsetinformation-in-windows-vista-and-heap-based-buffer-overruns.aspx let HeapEnableTerminationOnCorruption = 1u : uint32 if not (HeapSetInformation(GetProcessHeap(), HeapEnableTerminationOnCorruption, UIntPtr.Zero, UIntPtr.Zero)) then - raise (System.Security.SecurityException( - "Unable to enable unmanaged process execution option TerminationOnCorruption. " + - "HeapSetInformation() returned FALSE; LastError = 0x" + + raise (System.Security.SecurityException( + "Unable to enable unmanaged process execution option TerminationOnCorruption. " + + "HeapSetInformation() returned FALSE; LastError = 0x" + GetLastError().ToString("X").PadLeft(8, '0') + ".")) [] @@ -554,9 +549,70 @@ module StackGuard = open System.Runtime.CompilerServices - [] + [] let private MaxUncheckedRecursionDepth = 20 let EnsureSufficientExecutionStack recursionDepth = if recursionDepth > MaxUncheckedRecursionDepth then RuntimeHelpers.EnsureSufficientExecutionStack () + +[] +type MaybeLazy<'T> = + | Strict of 'T + | Lazy of Lazy<'T> + + member this.Value: 'T = + match this with + | Strict x -> x + | Lazy x -> x.Value + + member this.Force() : 'T = + match this with + | Strict x -> x + | Lazy x -> x.Force() + +let inline vsnd ((_, y): struct('T * 'T)) = y + +/// Track a set of resources to cleanup +type DisposablesTracker() = + + let items = Stack() + + /// Register some items to dispose + member _.Register i = items.Push i + + interface IDisposable with + + member _.Dispose() = + let l = List.ofSeq items + items.Clear() + for i in l do + try i.Dispose() with _ -> () + +/// Specialized parallel functions for an array. +/// Different from Array.Parallel as it will try to minimize the max degree of parallelism. +/// Will flatten aggregate exceptions that contain one exception. +[] +module ArrayParallel = + + let inline iteri f (arr: 'T []) = + let parallelOptions = ParallelOptions(MaxDegreeOfParallelism = max (min Environment.ProcessorCount arr.Length) 1) + try + Parallel.For(0, arr.Length, parallelOptions, fun i -> + f i arr.[i] + ) |> ignore + with + | :? AggregateException as ex when ex.InnerExceptions.Count = 1 -> + raise(ex.InnerExceptions.[0]) + + let inline iter f (arr: 'T []) = + arr |> iteri (fun _ item -> f item) + + let inline mapi f (arr: 'T []) = + let mapped = Array.zeroCreate arr.Length + arr |> iteri (fun i item -> mapped.[i] <- f i item) + mapped + + let inline map f (arr: 'T []) = + arr |> mapi (fun _ item -> f item) + \ No newline at end of file diff --git a/src/fsharp/lib.fsi b/src/fsharp/lib.fsi new file mode 100644 index 00000000000..bfa6f20296e --- /dev/null +++ b/src/fsharp/lib.fsi @@ -0,0 +1,310 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal Internal.Utilities.Library.Extras + +open System.IO +open System.Text +open System.Collections.Generic +open Internal.Utilities.Collections + +val debug: bool + +val verbose: bool + +val mutable progress: bool + +val mutable tracking: bool + +val condition: s:string -> bool + +val GetEnvInteger: e:string -> dflt:int -> int + +val dispose: x:System.IDisposable -> unit + +module Bits = + /// Get the least significant byte of a 32-bit integer + val b0: n:int -> int + + /// Get the 2nd least significant byte of a 32-bit integer + val b1: n:int -> int + + /// Get the 3rd least significant byte of a 32-bit integer + val b2: n:int -> int + + /// Get the most significant byte of a 32-bit integer + val b3: n:int -> int + + val pown32: n:int -> int + + val pown64: n:int -> int64 + + val mask32: m:int32 -> n:int -> int + + val mask64: m:int32 -> n:int -> int64 + +module Bool = + val order: IComparer + +module Int32 = + val order: IComparer + +module Int64 = + val order: IComparer + +module Pair = + val order : + compare1:IComparer<'T1> * + compare2:IComparer<'T2> -> + IComparer<'T1 * 'T2> + +type NameSet = Zset + +module NameSet = + val ofList: l:string list -> NameSet + +module NameMap = + val domain: m:Map -> Zset + + val domainL: m:Map -> string list + +module Check = + /// Throw System.InvalidOperationException if argument is None. + /// If there is a value (e.g. Some(value)) then value is returned. + val NotNone: argName:string -> arg:'T option -> 'T + + /// Throw System.ArgumentNullException if argument is null. + val ArgumentNotNull: arg:'a -> argName:string -> unit + + /// Throw System.ArgumentNullException if array argument is null. + /// Throw System.ArgumentOutOfRangeException is array argument is empty. + val ArrayArgumentNotNullOrEmpty: arr:'T [] -> argName:string -> unit + + /// Throw System.ArgumentNullException if string argument is null. + /// Throw System.ArgumentOutOfRangeException is string argument is empty. + val StringArgumentNotNullOrEmpty: s:string -> argName:string -> unit + +type IntMap<'T> = Zmap + +module IntMap = + val empty: unit -> Zmap + + val add : k:int -> v:'T -> t:IntMap<'T> -> Zmap + + val find: k:int -> t:IntMap<'T> -> 'T + + val tryFind: k:int -> t:IntMap<'T> -> 'T option + + val remove: k:int -> t:IntMap<'T> -> Zmap + + val mem: k:int -> t:IntMap<'T> -> bool + + val iter: f:(int -> 'T -> unit) -> t:IntMap<'T> -> unit + + val map: f:('T -> 'a) -> t:IntMap<'T> -> Zmap + + val fold: f:(int -> 'T -> 'a -> 'a) -> t:IntMap<'T> -> z:'a -> 'a + +module ListAssoc = + + /// Treat a list of key-value pairs as a lookup collection. + /// This function looks up a value based on a match from the supplied predicate function. + val find: f:('a -> 'b -> bool) -> x:'a -> l:('b * 'c) list -> 'c + + /// Treat a list of key-value pairs as a lookup collection. + /// This function looks up a value based on a match from the supplied + /// predicate function and returns None if value does not exist. + val tryFind : f:('key -> 'key -> bool) -> x:'key -> l:('key * 'value) list -> 'value option + +module ListSet = + val inline contains: f:('a -> 'b -> bool) -> x:'a -> l:'b list -> bool + + /// NOTE: O(n)! + val insert: f:('a -> 'a -> bool) -> x:'a -> l:'a list -> 'a list + + val unionFavourRight : f:('a -> 'a -> bool) -> l1:'a list -> l2:'a list -> 'a list + + /// NOTE: O(n)! + val findIndex: eq:('a -> 'b -> bool) -> x:'b -> l:'a list -> int + + val remove: f:('a -> 'b -> bool) -> x:'a -> l:'b list -> 'b list + + /// NOTE: quadratic! + val subtract: f:('a -> 'b -> bool) -> l1:'a list -> l2:'b list -> 'a list + + val isSubsetOf: f:('a -> 'b -> bool) -> l1:'a list -> l2:'b list -> bool + + val isSupersetOf : f:('a -> 'b -> bool) -> l1:'a list -> l2:'b list -> bool + + val equals: f:('a -> 'b -> bool) -> l1:'a list -> l2:'b list -> bool + + val unionFavourLeft : f:('a -> 'a -> bool) -> l1:'a list -> l2:'a list -> 'a list + + /// NOTE: not tail recursive! + val intersect : f:('a -> 'b -> bool) -> l1:'b list -> l2:'a list -> 'a list + + /// Note: if duplicates appear, keep the ones toward the _front_ of the list + val setify: f:('a -> 'a -> bool) -> l:'a list -> 'a list + + val hasDuplicates: f:('a -> 'a -> bool) -> l:'a list -> bool + +val mapFoldFst : f:('a -> 'b -> 'c * 'd) -> s:'a -> x:'b * y:'e -> ('c * 'e) * 'd + +val mapFoldSnd : f:('a -> 'b -> 'c * 'd) -> s:'a -> x:'e * y:'b -> ('e * 'c) * 'd + +val pair: a:'a -> b:'b -> 'a * 'b + +val p13: x:'a * _y:'b * _z:'c -> 'a + +val p23: _x:'a * y:'b * _z:'c -> 'b + +val p33: _x:'a * _y:'b * z:'c -> 'c + +val p14: x1:'a * _x2:'b * _x3:'c * _x4:'d -> 'a + +val p24: _x1:'a * x2:'b * _x3:'c * _x4:'d -> 'b + +val p34: _x1:'a * _x2:'b * x3:'c * _x4:'d -> 'c + +val p44: _x1:'a * _x2:'b * _x3:'c * x4:'d -> 'd + +val p15: x1:'a * _x2:'b * _x3:'c * _x4:'d * _x5:'e -> 'a + +val p25: _x1:'a * x2:'b * _x3:'c * _x4:'d * _x5:'e -> 'b + +val p35: _x1:'a * _x2:'b * x3:'c * _x4:'d * _x5:'e -> 'c + +val p45: _x1:'a * _x2:'b * _x3:'c * x4:'d * _x5:'e -> 'd + +val p55: _x1:'a * _x2:'b * _x3:'c * _x4:'d * x5:'e -> 'e + +val map1Of2: f:('a -> 'b) -> a1:'a * a2:'c -> 'b * 'c + +val map2Of2: f:('a -> 'b) -> a1:'c * a2:'a -> 'c * 'b + +val map1Of3: f:('a -> 'b) -> a1:'a * a2:'c * a3:'d -> 'b * 'c * 'd + +val map2Of3: f:('a -> 'b) -> a1:'c * a2:'a * a3:'d -> 'c * 'b * 'd + +val map3Of3: f:('a -> 'b) -> a1:'c * a2:'d * a3:'a -> 'c * 'd * 'b + +val map3Of4 : f:('a -> 'b) -> a1:'c * a2:'d * a3:'a * a4:'e -> 'c * 'd * 'b * 'e + +val map4Of4 : f:('a -> 'b) -> a1:'c * a2:'d * a3:'e * a4:'a -> 'c * 'd * 'e * 'b + +val map5Of5 : f:('a -> 'b) -> a1:'c * a2:'d * a3:'e * a4:'f * a5:'a -> 'c * 'd * 'e * 'f * 'b + +val map6Of6 : f:('a -> 'b) -> a1:'c * a2:'d * a3:'e * a4:'f * a5:'g * a6:'a -> 'c * 'd * 'e * 'f * 'g * 'b + +val foldPair : f1:('a -> 'b -> 'c) * f2:('c -> 'd -> 'e) -> acc:'a -> a1:'b * a2:'d -> 'e + +val fold1Of2: f1:('a -> 'b -> 'c) -> acc:'a -> a1:'b * _a2:'d -> 'c + +val foldTriple : f1:('a -> 'b -> 'c) * f2:('c -> 'd -> 'e) * f3:('e -> 'f -> 'g) -> acc:'a -> a1:'b * a2:'d * a3:'f -> 'g + +val foldQuadruple : f1:('a -> 'b -> 'c) * f2:('c -> 'd -> 'e) * f3:('e -> 'f -> 'g) * f4:('g -> 'h -> 'i) -> acc:'a -> a1:'b * a2:'d * a3:'f * a4:'h -> 'i val mapPair: f1:('a -> 'b) * f2:('c -> 'd) -> a1:'a * a2:'c -> 'b * 'd + +val mapTriple : f1:('a -> 'b) * f2:('c -> 'd) * f3:('e -> 'f) -> a1:'a * a2:'c * a3:'e -> 'b * 'd * 'f + +val mapQuadruple : f1:('a -> 'b) * f2:('c -> 'd) * f3:('e -> 'f) * f4:('g -> 'h) -> a1:'a * a2:'c * a3:'e * a4:'g -> 'b * 'd * 'f * 'h + +val fmap2Of2 : f:('a -> 'b -> 'c * 'd) -> z:'a -> a1:'e * a2:'b -> 'c * ('e * 'd) + +module Zmap = + val force: k:'a -> mp:Zmap<'a,'b> -> 'b + val mapKey :key:'a -> f:('b option -> 'b option) -> mp:Zmap<'a,'b> -> Zmap<'a,'b> + +module Zset = + val ofList : order:IComparer<'a> -> xs:'a list -> Zset<'a> + val fixpoint : f:(Zset<'a> -> Zset<'a>) -> Zset<'a> -> Zset<'a> + +val equalOn: f:('a -> 'b) -> x:'a -> y:'a -> bool when 'b: equality + +/// Buffer printing utility +val bufs: f:(StringBuilder -> unit) -> string + +/// Writing to output stream via a string buffer. +val writeViaBuffer : os:TextWriter -> f:(StringBuilder -> 'a -> unit) -> x:'a -> unit + +type Graph<'Data,'Id when 'Id: comparison> = + + new: nodeIdentity:('Data -> 'Id) * nodes:'Data list * + edges:('Data * 'Data) list -> Graph<'Data,'Id> + member GetNodeData: nodeId:'Id -> 'Data + member IterateCycles: f:('Data list -> unit) -> unit + +/// In some cases we play games where we use 'null' as a more efficient representation +/// in F#. The functions below are used to give initial values to mutable fields. +/// This is an unsafe trick, as it relies on the fact that the type of values +/// being placed into the slot never utilizes "null" as a representation. To be used with +/// with care. +type NonNullSlot<'T> = 'T + +val nullableSlotEmpty: unit -> 'T + +val nullableSlotFull: x:'a -> 'a + +/// Caches, mainly for free variables +type cache<'T> = { mutable cacheVal: NonNullSlot<'T> } + +val newCache: unit -> cache<'a> + +val inline cached: cache:cache<'a> -> resF:(unit -> 'a) -> 'a + +val inline cacheOptByref: cache:byref<'T option> -> f:(unit -> 'T) -> 'T + +val inline cacheOptRef: cache:'a option ref -> f:(unit -> 'a) -> 'a + +val inline tryGetCacheValue: cache:cache<'a> -> NonNullSlot<'a> voption + +module AsyncUtil = + + /// Represents the reified result of an asynchronous computation. + [] + type AsyncResult<'T> = + | AsyncOk of 'T + | AsyncException of exn + | AsyncCanceled of System.OperationCanceledException + static member Commit: res:AsyncResult<'T> -> Async<'T> + + /// When using .NET 4.0 you can replace this type by + [] + type AsyncResultCell<'T> = + + new: unit -> AsyncResultCell<'T> + member RegisterResult: res:AsyncResult<'T> -> unit + member AsyncResult: Async<'T> + +module UnmanagedProcessExecutionOptions = + val EnableHeapTerminationOnCorruption: unit -> unit + +module StackGuard = + val EnsureSufficientExecutionStack: recursionDepth:int -> unit + +[] +type MaybeLazy<'T> = + | Strict of 'T + | Lazy of System.Lazy<'T> + member Force: unit -> 'T + member Value: 'T + +val inline vsnd: struct ('T * 'T) -> 'T + +/// Track a set of resources to cleanup +type DisposablesTracker = + + new: unit -> DisposablesTracker + + /// Register some items to dispose + member Register: i:System.IDisposable -> unit + + interface System.IDisposable + +/// Specialized parallel functions for an array. +/// Different from Array.Parallel as it will try to minimize the max degree of parallelism. +/// Will flatten aggregate exceptions that contain one exception. +[] +module ArrayParallel = + + val inline map : ('T -> 'U) -> 'T [] -> 'U [] + + val inline mapi : (int -> 'T -> 'U) -> 'T [] -> 'U [] diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index e1d888196b5..d4dd38e53d2 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -4,38 +4,39 @@ #nowarn "1182" // generated code has lots of unused "parseState" -open Internal.Utilities +open System -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler +open Internal.Utilities open Internal.Utilities.Text.Parsing +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras -open System -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming +open FSharp.Compiler +open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml #if DEBUG -let debugPrint(s) = +let debugPrint s = if Internal.Utilities.Text.Parsing.Flags.debug then printfn "\n%s" s #else -let debugPrint(s) = ignore s +let debugPrint s = ignore s #endif -let exprFromParseError (e:SynExpr) = SynExpr.FromParseError (e,e.Range) -let patFromParseError (e:SynPat) = SynPat.FromParseError(e, e.Range) +let exprFromParseError (e:SynExpr) = SynExpr.FromParseError (e, e.Range) -let mkSynOptionalExpr (m: range) xopt = - let m = m.MakeSynthetic() - match xopt with - | None -> mkSynLidGet m Ast.FSharpLib.CorePath "None" - | Some x -> SynExpr.App (ExprAtomicFlag.NonAtomic, false, mkSynLidGet m Ast.FSharpLib.CorePath "Some",x,m) +let patFromParseError (e:SynPat) = SynPat.FromParseError(e, e.Range) // record bindings returned by the recdExprBindings rule has shape: // (binding, separator-before-this-binding) @@ -51,23 +52,24 @@ let rebindRanges first fields lastSep = run first fields [] let mkUnderscoreRecdField m = LongIdentWithDots([ident("_", m)], []), false + let mkRecdField lidwd = lidwd, true -let mkSynDoBinding (vis,strict,expr,m) = +let mkSynDoBinding (vis, strict, expr, m) = match vis with - | Some vis -> errorR(Error(FSComp.SR.parsDoCannotHaveVisibilityDeclarations (vis.ToString()),m)) + | Some vis -> errorR(Error(FSComp.SR.parsDoCannotHaveVisibilityDeclarations (vis.ToString()), m)) | None -> () - Binding (None, - (if strict then DoBinding else StandaloneExpression), - false,false,[],PreXmlDoc.Empty,SynInfo.emptySynValData, - (if strict then SynPat.Const(SynConst.Unit,m) else SynPat.Wild m), - None,expr,m,NoSequencePointAtDoBinding) + SynBinding(None, + (if strict then SynBindingKind.Do else SynBindingKind.StandaloneExpression), + false, false, [], PreXmlDoc.Empty, SynInfo.emptySynValData, + (if strict then SynPat.Const(SynConst.Unit, m) else SynPat.Wild m), + None, expr, m, DebugPointAtBinding.NoneAtDo) let mkSynDoDecl (e: SynExpr) = - let spExpr = if IsControlFlowExpression e then NoSequencePointAtDoBinding else SequencePointAtBinding e.Range in + let spExpr = if IsControlFlowExpression e then DebugPointAtBinding.NoneAtDo else DebugPointAtBinding.Yes e.Range SynModuleDecl.DoExpr(spExpr, e, e.Range) -let addAttribs attrs p = SynPat.Attrib(p,attrs,p.Range) +let addAttribs attrs p = SynPat.Attrib(p, attrs, p.Range) // This function is called by the generated parser code. Returning initiates error recovery @@ -75,7 +77,7 @@ let addAttribs attrs p = SynPat.Attrib(p,attrs,p.Range) let parse_error_rich = Some (fun (ctxt: ParseErrorContext<_>) -> errorR(SyntaxError(box ctxt, ctxt.ParseState.LexBuffer.LexemeRange))) -let reportParseErrorAt m s = errorR(Error(s,m)) +let reportParseErrorAt m s = errorR(Error(s, m)) let unionRangeWithPos (r:range) p = let r2 = mkRange r.FileName p p @@ -86,81 +88,121 @@ let raiseParseErrorAt m s = // This initiates error recovery raise RecoverableParseError +/// Report a good error at the end of file, e.g. for non-terminated strings let checkEndOfFileError t = match t with - | LexCont.IfDefSkip(_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInHashIf()) - | LexCont.String (_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInString()) - | LexCont.TripleQuoteString (_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteString()) - | LexCont.VerbatimString (_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInVerbatimString()) - | LexCont.Comment (_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInComment()) - | LexCont.SingleLineComment (_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInComment()) - | LexCont.StringInComment (_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInStringInComment()) - | LexCont.VerbatimStringInComment (_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInVerbatimStringInComment()) - | LexCont.TripleQuoteStringInComment (_,_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteStringInComment()) - | LexCont.MLOnly (_,m) -> reportParseErrorAt m (FSComp.SR.parsEofInIfOcaml()) - | LexCont.EndLine(LexerEndlineContinuation.Skip(_,_,m)) -> reportParseErrorAt m (FSComp.SR.parsEofInDirective()) - | LexCont.EndLine(LexerEndlineContinuation.Token(stack)) - | LexCont.Token(stack) -> - match stack with + | LexCont.IfDefSkip(_, _, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInHashIf()) + + | LexCont.String (_, _, LexerStringStyle.SingleQuote, kind, m) -> + if kind.IsInterpolated then + reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedString()) + else + reportParseErrorAt m (FSComp.SR.parsEofInString()) + + | LexCont.String (_, _, LexerStringStyle.TripleQuote, kind, m) -> + if kind.IsInterpolated then + reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedTripleQuoteString()) + else + reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteString()) + + | LexCont.String (_, _, LexerStringStyle.Verbatim, kind, m) -> + if kind.IsInterpolated then + reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedVerbatimString()) + else + reportParseErrorAt m (FSComp.SR.parsEofInVerbatimString()) + + | LexCont.Comment (_, _, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInComment()) + + | LexCont.SingleLineComment (_, _, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInComment()) + + | LexCont.StringInComment (_, _, LexerStringStyle.SingleQuote, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInStringInComment()) + + | LexCont.StringInComment (_, _, LexerStringStyle.Verbatim, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInVerbatimStringInComment()) + + | LexCont.StringInComment (_, _, LexerStringStyle.TripleQuote, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInTripleQuoteStringInComment()) + + | LexCont.MLOnly (_, _, m) -> + reportParseErrorAt m (FSComp.SR.parsEofInIfOcaml()) + + | LexCont.EndLine(_, _, LexerEndlineContinuation.Skip(_, m)) -> + reportParseErrorAt m (FSComp.SR.parsEofInDirective()) + + | LexCont.EndLine(endifs, nesting, LexerEndlineContinuation.Token) + | LexCont.Token(endifs, nesting) -> + match endifs with | [] -> () - | (_,m) :: _ -> reportParseErrorAt m (FSComp.SR.parsNoHashEndIfFound()) + | (_, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsNoHashEndIfFound()) + match nesting with + | [] -> () + | (_, _, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedStringFill()) -// BindingSetPreAttrs(letRange, isRec, isUse, builderFunction, wholeRange) type BindingSet = BindingSetPreAttrs of range * bool * bool * (SynAttributes -> SynAccess option -> SynAttributes * SynBinding list) * range -let mkClassMemberLocalBindings(isStatic,initialRangeOpt,attrs,vis,BindingSetPreAttrs(_,isRec,isUse,declsPreAttrs,bindingSetRange)) = - let ignoredFreeAttrs,decls = declsPreAttrs attrs vis +let mkClassMemberLocalBindings(isStatic, initialRangeOpt, attrs, vis, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, bindingSetRange)) = + let ignoredFreeAttrs, decls = declsPreAttrs attrs vis let wholeRange = match initialRangeOpt with | None -> bindingSetRange | Some m -> unionRanges m bindingSetRange - if not (isNil ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(),wholeRange)); - if isUse then errorR(Error(FSComp.SR.parsUseBindingsIllegalInImplicitClassConstructors(),wholeRange)) - SynMemberDefn.LetBindings (decls,isStatic,isRec,wholeRange) - -let mkLocalBindings (mWhole,BindingSetPreAttrs(_,isRec,isUse,declsPreAttrs,_),body) = - let ignoredFreeAttrs,decls = declsPreAttrs [] None - if not (isNil ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(),mWhole)) - SynExpr.LetOrUse (isRec,isUse,decls,body,mWhole) - -let mkDefnBindings (mWhole,BindingSetPreAttrs(_,isRec,isUse,declsPreAttrs,_bindingSetRange),attrs,vis,attrsm) = - if isUse then warning(Error(FSComp.SR.parsUseBindingsIllegalInModules(),mWhole)) - let freeAttrs,decls = declsPreAttrs attrs vis - let letDecls = [ SynModuleDecl.Let (isRec,decls,mWhole) ] - let attrDecls = if not (isNil freeAttrs) then [ SynModuleDecl.Attributes (freeAttrs,attrsm) ] else [] + // decls could have a leading attribute + |> fun m -> (m, decls) ||> unionRangeWithListBy (fun (SynBinding(range = m)) -> m) + if not (isNil ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(), wholeRange)); + if isUse then errorR(Error(FSComp.SR.parsUseBindingsIllegalInImplicitClassConstructors(), wholeRange)) + SynMemberDefn.LetBindings (decls, isStatic, isRec, wholeRange) + +let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _), body) = + let ignoredFreeAttrs, decls = declsPreAttrs [] None + if not (isNil ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(), mWhole)) + SynExpr.LetOrUse (isRec, isUse, decls, body, mWhole) + +let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) = + if isUse then warning(Error(FSComp.SR.parsUseBindingsIllegalInModules(), mWhole)) + let freeAttrs, decls = declsPreAttrs attrs vis + // decls might have an extended range due to leading attributes + let mWhole = (mWhole, decls) ||> unionRangeWithListBy (fun (SynBinding(range = m)) -> m) + let letDecls = [ SynModuleDecl.Let (isRec, decls, mWhole) ] + let attrDecls = if not (isNil freeAttrs) then [ SynModuleDecl.Attributes (freeAttrs, attrsm) ] else [] attrDecls @ letDecls let idOfPat (parseState:IParseState) m p = match p with | SynPat.Wild r when parseState.LexBuffer.SupportsFeature LanguageFeature.WildCardInForLoop -> mkSynId r "_" - | SynPat.Named (SynPat.Wild _,id,false,_,_) -> id - | SynPat.LongIdent(LongIdentWithDots([id],_),_,None, SynConstructorArgs.Pats [], None,_) -> id + | SynPat.Named (id, false, _, _) -> id + | SynPat.LongIdent(LongIdentWithDots([id], _), _, None, SynArgPats.Pats [], None, _) -> id | _ -> raiseParseErrorAt m (FSComp.SR.parsIntegerForLoopRequiresSimpleIdentifier()) let checkForMultipleAugmentations m a1 a2 = if not (isNil a1) && not (isNil a2) then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) a1 @ a2 -let grabXmlDoc(parseState:IParseState,elemIdx) = - LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer,rhs parseState elemIdx) - -let unionRangeWithListBy projectRangeFromThing m listOfThing = - (m, listOfThing) ||> List.fold (fun m thing -> unionRanges m (projectRangeFromThing thing)) - -let rangeOfNonNilAttrs(attrs:SynAttributes) = - (attrs.Head.Range,attrs.Tail) ||> unionRangeWithListBy (fun a -> a.Range) +let grabXmlDoc(parseState:IParseState, elemIdx) = + LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, rhs parseState elemIdx) let rangeOfLongIdent(lid:LongIdent) = System.Diagnostics.Debug.Assert(not lid.IsEmpty, "the parser should never produce a long-id that is the empty list") - (lid.Head.idRange,lid) ||> unionRangeWithListBy (fun id -> id.idRange) + (lid.Head.idRange, lid) ||> unionRangeWithListBy (fun id -> id.idRange) %} -%token BYTEARRAY -%token STRING -%token KEYWORD_STRING // Like __SOURCE_DIRECTORY__ +// Producing these changes the lex state, e.g. string --> token, or nesting level of braces in interpolated strings +%token BYTEARRAY +%token STRING +%token INTERP_STRING_BEGIN_END +%token INTERP_STRING_BEGIN_PART +%token INTERP_STRING_PART +%token INTERP_STRING_END +%token LBRACE RBRACE + +%token KEYWORD_STRING // Like __SOURCE_DIRECTORY__ %token IDENT +%token HASH_IDENT %token INFIX_STAR_STAR_OP %token INFIX_COMPARE_OP %token INFIX_AT_HAT_OP @@ -177,19 +219,19 @@ let rangeOfLongIdent(lid:LongIdent) = %token INT16 %token INT32 INT32_DOT_DOT %token INT64 +%token NATIVEINT %token UINT8 %token UINT16 %token UINT32 %token UINT64 %token UNATIVEINT -%token NATIVEINT %token IEEE32 %token IEEE64 %token CHAR %token DECIMAL %token <(string * string)> BIGNUM -%token LET YIELD YIELD_BANG +%token LET YIELD YIELD_BANG AND_BANG %token LESS GREATER /* here the bool indicates if the tokens are part of a type application or type parameter declaration, e.g. C, detected by the lex filter */ %token PERCENT_OP BINDER %token LQUOTE RQUOTE RQUOTE_DOT @@ -200,9 +242,9 @@ let rangeOfLongIdent(lid:LongIdent) = %token OPEN OR REC THEN TO TRUE TRY TYPE VAL INLINE INTERFACE INSTANCE CONST %token WHEN WHILE WITH HASH AMP AMP_AMP QUOTE LPAREN RPAREN RPAREN_COMING_SOON RPAREN_IS_HERE STAR COMMA RARROW GREATER_BAR_RBRACK LPAREN_STAR_RPAREN %token QMARK QMARK_QMARK DOT COLON COLON_COLON COLON_GREATER COLON_QMARK_GREATER COLON_QMARK COLON_EQUALS SEMICOLON -%token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS LBRACE +%token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS %token BAR_RBRACK BAR_RBRACE UNDERSCORE -%token BAR RBRACK RBRACE RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR +%token BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL @@ -218,6 +260,7 @@ let rangeOfLongIdent(lid:LongIdent) = /* for offside rule */ %token OLET /* LexFilter #light converts 'LET' tokens to 'OLET' when starting (CtxtLetDecl(blockLet=true)) */ %token OBINDER /* LexFilter #light converts 'BINDER' tokens to 'OBINDER' when starting (CtxtLetDecl(blockLet=true)) */ +%token OAND_BANG /* LexFilter #light converts 'AND_BANG' tokens to 'OAND_BANG' when starting (CtxtLetDecl(blockLet=true)) */ %token ODO /* LexFilter #light converts 'DO' tokens to 'ODO' */ %token ODO_BANG /* LexFilter #light converts 'DO_BANG' tokens to 'ODO_BANG' */ %token OTHEN /* LexFilter #light converts 'THEN' tokens to 'OTHEN' */ @@ -248,13 +291,13 @@ let rangeOfLongIdent(lid:LongIdent) = - just after '->' in any context - when opening CtxtNamespaceHead, CtxtModuleHead */ -%token OBLOCKSEP /* LexFilter #light inserts when transforming CtxtSeqBlock(NotFirstInSeqBlock,_,AddBlockEnd) to CtxtSeqBlock(FirstInSeqBlock,_,AddBlockEnd) on exact alignment */ +%token OBLOCKSEP /* LexFilter #light inserts when transforming CtxtSeqBlock(NotFirstInSeqBlock, _, AddBlockEnd) to CtxtSeqBlock(FirstInSeqBlock, _, AddBlockEnd) on exact alignment */ /* REVIEW: merge OEND, ODECLEND, OBLOCKEND and ORIGHT_BLOCK_END into one token */ %token OEND /* LexFilter #light inserts when closing CtxtFun, CtxtMatchClauses, CtxtWithAsLet _ */ %token ODECLEND /* LexFilter #light inserts when closing CtxtDo and CtxtLetDecl(block) */ -%token ORIGHT_BLOCK_END /* LexFilter #light inserts when closing CtxtSeqBlock(_,_,AddOneSidedBlockEnd) */ -%token OBLOCKEND OBLOCKEND_COMING_SOON OBLOCKEND_IS_HERE /* LexFilter #light inserts when closing CtxtSeqBlock(_,_,AddBlockEnd) */ +%token ORIGHT_BLOCK_END /* LexFilter #light inserts when closing CtxtSeqBlock(_, _, AddOneSidedBlockEnd) */ +%token OBLOCKEND OBLOCKEND_COMING_SOON OBLOCKEND_IS_HERE /* LexFilter #light inserts when closing CtxtSeqBlock(_, _, AddBlockEnd) */ %token OINTERFACE_MEMBER /* inserted for non-paranthetical use of 'INTERFACE', i.e. not INTERFACE/END */ %token FIXED @@ -262,41 +305,42 @@ let rangeOfLongIdent(lid:LongIdent) = /* These are artificial */ %token LEX_FAILURE -%token COMMENT WHITESPACE HASH_LINE HASH_LIGHT INACTIVECODE LINE_COMMENT STRING_TEXT EOF -%token HASH_IF HASH_ELSE HASH_ENDIF - -%start signatureFile implementationFile interaction typedSeqExprEOF typEOF -%type typedSeqExprEOF -%type implementationFile -%type signatureFile -%type interaction -%type ident -%type typ typEOF -%type tyconSpfns -%type patternResult -%type declExpr -%type minusExpr -%type appExpr -%type argExpr -%type declExprBlock -%type headBindingPattern -%type atomicExprAfterType -%type typedSeqExprBlock -%type atomicExpr -%type tyconDefnOrSpfnSimpleRepr -%type <(Ast.SynEnumCase, Ast.SynUnionCase) Choice list> unionTypeRepr -%type tyconDefnAugmentation -%type exconDefn -%type exconCore -%type moduleDefnsOrExprPossiblyEmptyOrBlock -%type openDecl -%type path -%type pathOp +%token COMMENT WHITESPACE HASH_LINE HASH_LIGHT INACTIVECODE LINE_COMMENT STRING_TEXT EOF +%token HASH_IF HASH_ELSE HASH_ENDIF + +%start signatureFile implementationFile interaction typedSequentialExprEOF typEOF +%type typedSequentialExprEOF +%type implementationFile +%type signatureFile +%type interaction +%type ident +%type typ typEOF +%type tyconSpfnList +%type atomicPatsOrNamePatPairs +%type atomicPatterns +%type patternResult +%type declExpr +%type minusExpr +%type appExpr +%type argExpr +%type declExprBlock +%type headBindingPattern +%type atomicExprAfterType +%type typedSequentialExprBlock +%type atomicExpr +%type tyconDefnOrSpfnSimpleRepr +%type list> unionTypeRepr +%type tyconDefnAugmentation +%type exconDefn +%type exconCore +%type moduleDefnsOrExprPossiblyEmptyOrBlock +%type path +%type pathOp /* LESS GREATER parsedOk typeArgs m for each mWhole */ -%type typeArgsActual +%type typeArgsActual /* LESS GREATER typeArgs m for each mWhole */ -%type typeArgsNoHpaDeprecated -%type typar +%type typeArgsNoHpaDeprecated +%type typar /* About precedence rules: * @@ -378,11 +422,12 @@ let rangeOfLongIdent(lid:LongIdent) = * - constant terminals. * - null * - LBRACK = [ - * - TRUE,FALSE + * - TRUE, FALSE */ %nonassoc prec_atompat_pathop %nonassoc INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NATIVEINT UNATIVEINT IEEE32 IEEE64 CHAR KEYWORD_STRING STRING BYTEARRAY BIGNUM DECIMAL +%nonassoc INTERP_STRING_BEGIN INTERP_STRING_PART INTERP_STRING_END %nonassoc LPAREN LBRACE LBRACK_BAR %nonassoc TRUE FALSE UNDERSCORE NULL @@ -408,9 +453,9 @@ let rangeOfLongIdent(lid:LongIdent) = * Committing to an opt_attribute (reduce) forces the decision that a following LET is a moduleDefn. * At the top-level, it could turn out to be an expr, so prefer to shift and find out... */ -%nonassoc prec_opt_attributes_none /* lower than LET,NEW */ +%nonassoc prec_opt_attributes_none /* lower than LET, NEW */ -/* LET,NEW higher than SEMICOLON so shift +/* LET, NEW higher than SEMICOLON so shift * "seqExpr = seqExpr; . let x = y in z" * "seqExpr = seqExpr; . new...." */ @@ -427,7 +472,7 @@ let rangeOfLongIdent(lid:LongIdent) = %nonassoc ELSE /* prec_atomtyp_path = precedence of atomType "path" - * Lower than possible extension "path" to allow "path . <" shift. + * Lower than possible extension "path" to allow "path . <" shift. * Extensions: LESS */ %nonassoc prec_atomtyp_path /* lower than LESS */ @@ -447,13 +492,14 @@ let rangeOfLongIdent(lid:LongIdent) = %right COLON_EQUALS %nonassoc pat_tuple expr_tuple %left COMMA -%nonassoc slice_expr /* matrix.[e COMMA e] has higher precedence than "e COMMA e" */ -%nonassoc DOT_DOT /* for matrix.[1..2,3..4] the ".." has higher precedence than expression "2 COMMA 3" */ -%nonassoc slice_comma /* for matrix.[1..2,3..4] the "," has higher precedence than ".." */ +%nonassoc open_range_expr +%left DOT_DOT /* for matrix.[1..2, 3..4] the ".." has higher precedence than expression "2 COMMA 3" */ +%nonassoc interpolation_fill /* "...{3,N4}..." .NET style fill has higher precedence than "e COMMA e" */ %nonassoc paren_pat_colon %nonassoc paren_pat_attribs %left OR BAR_BAR JOIN_IN -%left AND /* check */ +%left AND +%left AND_BANG %left AMP AMP_AMP %nonassoc pat_conj %nonassoc expr_not @@ -494,14 +540,14 @@ let rangeOfLongIdent(lid:LongIdent) = /* An interaction in F# Interactive */ interaction: | interactiveItemsTerminator - { IDefns ($1,lhs parseState) } + { ParsedScriptInteraction.Definitions ($1, lhs parseState) } | SEMICOLON - { warning(Error(FSComp.SR.parsUnexpectedSemicolon(),rhs parseState 1)) - IDefns ([],lhs parseState) } + { warning(Error(FSComp.SR.parsUnexpectedSemicolon(), rhs parseState 1)) + ParsedScriptInteraction.Definitions ([], lhs parseState) } | OBLOCKSEP - { IDefns ([],lhs parseState) } + { ParsedScriptInteraction.Definitions ([], lhs parseState) } interactiveTerminator: @@ -554,7 +600,7 @@ interactiveDefns: interactiveExpr: | opt_attributes opt_declVisibility declExpr { match $2 with - | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()),rhs parseState 3)) + | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()), rhs parseState 3)) | _ -> () let attrDecls = if not (isNil $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] in attrDecls @ [ mkSynDoDecl($3)] } @@ -563,21 +609,20 @@ interactiveExpr: /* A #directive interaction in F# Interactive */ interactiveHash: | hashDirective - { [SynModuleDecl.HashDirective($1,rhs parseState 1)] } + { [SynModuleDecl.HashDirective($1, rhs parseState 1)] } /* One or more separators between interactions in F# Interactive */ interactiveSeparators: - | interactiveSeparator { } - | interactiveSeparator interactiveSeparators { } + | interactiveSeparator { } + | interactiveSeparator interactiveSeparators { } /* One separator between interactions in F# Interactive */ interactiveSeparator: | SEMICOLON { } | OBLOCKSEP { } - /*--------------------------------------------------------------------------*/ /* #directives - used by both F# Interactive directives and #nowarn etc. */ @@ -585,7 +630,8 @@ interactiveSeparator: /* A #directive in a module, namespace or an interaction */ hashDirective: | HASH IDENT hashDirectiveArgs - { ParsedHashDirective ($2,$3,lhs parseState) } + { let m = match $3 with [] -> rhs2 parseState 1 2 | _ -> rhs2 parseState 1 3 + ParsedHashDirective ($2, $3, m) } /* The arguments to a #directive */ @@ -598,10 +644,14 @@ hashDirectiveArgs: /* One argument to a #directive */ -hashDirectiveArg: - | stringOrKeywordString - { $1 } - +hashDirectiveArg: + | string + { let s, kind = $1 + ParsedHashDirectiveArgument.String (s, kind, lhs parseState) } + | sourceIdentifier + { let c,v = $1 + ParsedHashDirectiveArgument.SourceIdentifier (c, v, lhs parseState) } + /*--------------------------------------------------------------------------*/ /* F# Language Proper - signature files */ @@ -618,39 +668,41 @@ signatureFile: /* This will result in NO intellisense for the file! Ideally we wouldn't need this rule */ /* Note: the compiler assumes there is at least one "fragment", so an empty one is used (see 4488) */ | error EOF - { let emptySigFileFrag = ParsedSigFileFragment.AnonModule([],rhs parseState 1) in - ParsedSigFile ([],[emptySigFileFrag]) } + { let emptySigFileFrag = ParsedSigFileFragment.AnonModule([], rhs parseState 1) in + ParsedSigFile ([], [emptySigFileFrag]) } /* The start of a module declaration */ moduleIntro: - | moduleKeyword opt_access opt_rec path - { $3, $4.Lid, grabXmlDoc(parseState,1), $2 } + | moduleKeyword opt_attributes opt_access opt_rec path + { if not (isNil $2) then + parseState.LexBuffer.CheckLanguageFeatureErrorRecover LanguageFeature.AttributesToRightOfModuleKeyword <| rhs parseState 4 + $4, $5.Lid, grabXmlDoc(parseState, 1), $3, $2 } /* The start of a namespace declaration */ namespaceIntro: | NAMESPACE opt_rec path - { $2, $3.Lid, grabXmlDoc(parseState,1) } + { $2, $3.Lid, grabXmlDoc(parseState, 1) } /* The contents of a signature file */ fileNamespaceSpecs: | fileModuleSpec - { ParsedSigFile ([],[ ($1 (false,[],PreXmlDoc.Empty)) ]) } + { ParsedSigFile ([], [ ($1 (false, [], PreXmlDoc.Empty)) ]) } | fileModuleSpec fileNamespaceSpecList { // If there are namespaces, the first fileModuleImpl may only contain # directives let decls = - match ($1 (false,[],PreXmlDoc.Empty)) with - | ParsedSigFileFragment.AnonModule(decls,m) -> decls - | ParsedSigFileFragment.NamespaceFragment(_,_,_, decls, _,_,_) -> decls - | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(_,_,_,_,_,_,_,m)) -> + match ($1 (false, [], PreXmlDoc.Empty)) with + | ParsedSigFileFragment.AnonModule(decls, m) -> decls + | ParsedSigFileFragment.NamespaceFragment(_, _, _, decls, _, _, _) -> decls + | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(_, _, _, _, _, _, _, m)) -> raiseParseErrorAt m (FSComp.SR.parsOnlyHashDirectivesAllowed()) let decls = decls |> List.collect (function - | (SynModuleSigDecl.HashDirective (hd,_)) -> [hd] + | (SynModuleSigDecl.HashDirective (hd, _)) -> [hd] | d -> reportParseErrorAt d.Range (FSComp.SR.parsOnlyHashDirectivesAllowed()) []) @@ -666,27 +718,31 @@ fileNamespaceSpecList: fileNamespaceSpec: | namespaceIntro deprecated_opt_equals fileModuleSpec - { let isRec,path,xml = $1 in ($3 (isRec,path,xml)) } + { let isRec, path, xml = $1 in ($3 (isRec, path, xml)) } /* The single module declaration that can make up a signature file */ fileModuleSpec: - | opt_attributes opt_declVisibility moduleIntro moduleSpfnsPossiblyEmptyBlock - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + | opt_attributes opt_declVisibility moduleIntro moduleSpfnsPossiblyEmptyBlock + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let m2 = rhs parseState 3 - let m = (rhs2 parseState 3 4) - let isRec,path2,xml,vis = $3 - (fun (isRec2,path,_) -> - if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) + let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleSigDecl) -> d.Range) $4) + let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id + let isRec, path2, xml, vis, attribs2 = $3 + (fun (isRec2, path, _) -> + if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2)) let lid = path@path2 - ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), NamedModule, $4, xml,$1,vis,m))) } + ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1 @ attribs2, vis, m))) } | moduleSpfnsPossiblyEmptyBlock { let m = (rhs parseState 1) (fun (isRec, path, xml) -> - match path with + match path with | [] -> ParsedSigFileFragment.AnonModule($1, m) - | _ -> ParsedSigFileFragment.NamespaceFragment(path, isRec, DeclaredNamespace, $1, xml,[],m)) } + | _ -> + let lastDeclRange = List.tryLast $1 |> Option.map (fun decl -> decl.Range) |> Option.defaultValue (rhs parseState 1) + let m = mkRange lastDeclRange.FileName (lhs parseState).Start lastDeclRange.End + ParsedSigFileFragment.NamespaceFragment(path, isRec, SynModuleOrNamespaceKind.DeclaredNamespace, $1, xml, [], m)) } moduleSpfnsPossiblyEmptyBlock: @@ -730,55 +786,64 @@ moduleSpfns: moduleSpfn: | hashDirective - { SynModuleSigDecl.HashDirective ($1,rhs2 parseState 1 1) } + { SynModuleSigDecl.HashDirective ($1, rhs2 parseState 1 1) } | valSpfn { $1 } | opt_attributes opt_declVisibility moduleIntro colonOrEquals namedModuleAbbrevBlock - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let isRec, path, xml, vis = $3 + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let isRec, path, xml, vis, attribs2 = $3 if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) if not (isNil $1) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) + if not (isNil attribs2) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) match vis with | Some vis -> raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate(vis.ToString())) - | _ -> SynModuleSigDecl.ModuleAbbrev(List.head path,$5,rhs2 parseState 3 5) } + | _ -> SynModuleSigDecl.ModuleAbbrev(List.head path, $5, rhs2 parseState 1 5) } - | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock - { let isRec, path, xml, vis = $3 + | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock + { let isRec, path, xml, vis, attribs2 = $3 if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleDefnMustBeSimpleName()) if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) - let info = ComponentInfo($1,[],[],path,xml,false,vis,rhs parseState 3) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - SynModuleSigDecl.NestedModule(info, isRec, $5, rhs2 parseState 3 5) } - - | opt_attributes opt_declVisibility tyconSpfns - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let (TypeDefnSig(ComponentInfo(cas,a,cs,b,c,d,d2,d3),e,f,g)),rest = - match $3 with - | [] -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEmptyModuleDefn()) - | h :: t -> h,t - let tc = (TypeDefnSig(ComponentInfo($1@cas,a,cs,b,c,d,d2,d3),e,f,g))in - SynModuleSigDecl.Types (tc :: rest,rhs parseState 3) } + let info = SynComponentInfo($1 @ attribs2, None, [], path, xml, false, vis, rhs parseState 3) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let m = (rhs2 parseState 1 4, $5) ||> unionRangeWithListBy (fun (d: SynModuleSigDecl) -> d.Range) + SynModuleSigDecl.NestedModule(info, isRec, $5, m) } + + | opt_attributes opt_declVisibility typeKeyword tyconSpfnList + { if Option.isSome $2 then + errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) + + match $4 with + | [] -> raiseParseErrorAt (rhs2 parseState 3 4) (FSComp.SR.parsUnexpectedEmptyModuleDefn ()) + | SynTypeDefnSig (SynComponentInfo (cas, a, cs, b, c, d, d2, d3), e, f, g) :: tail -> + let attrs = $1 @ cas + let mTc = + let keywordM = rhs parseState 3 + (keywordM, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) |> unionRanges g + let tc = (SynTypeDefnSig(SynComponentInfo(attrs, a, cs, b, c, d, d2, d3), e, f, mTc)) + let m = (mTc, tail) ||> unionRangeWithListBy (fun (a: SynTypeDefnSig) -> a.Range) + + SynModuleSigDecl.Types (tc :: tail, m) } | opt_attributes opt_declVisibility exconSpfn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let (SynExceptionSig(SynExceptionDefnRepr(cas,a,b,c,d,d2),e,f)) = $3 - let ec = (SynExceptionSig(SynExceptionDefnRepr($1@cas,a,b,c,d,d2),e,f)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let (SynExceptionSig(SynExceptionDefnRepr(cas, a, b, c, d, d2), e, f)) = $3 + let ec = SynExceptionSig(SynExceptionDefnRepr($1@cas, a, b, c, d, d2), e, f) SynModuleSigDecl.Exception(ec, rhs parseState 3) } - | OPEN path - { SynModuleSigDecl.Open ($2.Lid, unionRanges (rhs parseState 1) $2.Range) } + | openDecl + { SynModuleSigDecl.Open($1, (rhs parseState 1)) } valSpfn: | opt_attributes opt_declVisibility VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let attr1,attr2,isInline,isMutable,vis2,id,doc,explicitValTyparDecls,(ty,arity),konst = ($1),($4),($5),($6),($7),($8),grabXmlDoc(parseState,3),($9),($11),($12) - if not (isNil attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(),rhs parseState 4)) - let m = rhs2 parseState 3 11 - let valSpfn = ValSpfn((attr1@attr2),id,explicitValTyparDecls,ty,arity,isInline,isMutable,doc, vis2,konst,m) - SynModuleSigDecl.Val(valSpfn,m) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), konst = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, 3), ($9), ($11), ($12) + if not (isNil attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(), rhs parseState 4)) + let m = rhs2 parseState 1 11 + let valSpfn = SynValSig((attr1@attr2), id, explicitValTyparDecls, ty, arity, isInline, isMutable, doc, vis2, konst, m) + SynModuleSigDecl.Val(valSpfn, m) } /* The optional literal value on a literal specification in a signature */ @@ -809,12 +874,6 @@ moduleSpecBlock: { $2 } -/* A group of type definitions in a signature */ -tyconSpfns: - | typeKeyword tyconSpfnList - { $2 } - - tyconSpfnList: | tyconSpfn AND tyconSpfnList { $1 :: $3 } @@ -829,7 +888,7 @@ tyconSpfn: { let lhsm = rhs parseState 1 $3 lhsm $1 } | typeNameInfo opt_classSpfn - { TypeDefnSig($1,SynTypeDefnSigRepr.Simple (SynTypeDefnSimpleRepr.None (lhs parseState),lhs parseState),$2,lhs parseState) } + { SynTypeDefnSig($1, SynTypeDefnSigRepr.Simple (SynTypeDefnSimpleRepr.None (lhs parseState), lhs parseState), $2, lhs parseState) } /* The right-hand-side of a type definition in a signature */ @@ -856,43 +915,48 @@ tyconSpfnRhsBlock: /* The right-hand-side of a type definition in a signature */ tyconSpfnRhs: | tyconDefnOrSpfnSimpleRepr - { let m = $1.Range - (fun lhsm nameInfo augmentation -> - TypeDefnSig(nameInfo,SynTypeDefnSigRepr.Simple ($1,m),augmentation,m)) } + { (fun lhsm nameInfo augmentation -> + let declRange = unionRanges lhsm $1.Range + let mWhole = (declRange, augmentation) ||> unionRangeWithListBy (fun (mem: SynMemberSig) -> mem.Range) + SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.Simple ($1, $1.Range), augmentation, mWhole)) } | tyconClassSpfn - { let m = lhs parseState - let needsCheck,(kind,decls) = $1 + { let objectModelRange = lhs parseState + let needsCheck, (kind, decls) = $1 (fun nameRange nameInfo augmentation -> if needsCheck && isNil decls then reportParseErrorAt nameRange (FSComp.SR.parsEmptyTypeDefinition()) - TypeDefnSig(nameInfo,SynTypeDefnSigRepr.ObjectModel (kind,decls,m),augmentation,m)) } + + let declRange = unionRanges nameRange objectModelRange + let mWhole = (declRange, augmentation) ||> unionRangeWithListBy (fun (mem: SynMemberSig) -> mem.Range) + SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (kind, decls, objectModelRange), augmentation, mWhole)) } | DELEGATE OF topType { let m = lhs parseState - let ty,arity = $3 - let invoke = SynMemberSig.Member(ValSpfn([],mkSynId m "Invoke",inferredTyparDecls,ty,arity,false,false,PreXmlDoc.Empty,None,None,m),AbstractMemberFlags MemberKind.Member,m) + let ty, arity = $3 + let invoke = SynMemberSig.Member(SynValSig([], mkSynId m "Invoke", inferredTyparDecls, ty, arity, false, false, PreXmlDoc.Empty, None, None, m), AbstractMemberFlags SynMemberKind.Member, m) (fun nameRange nameInfo augmentation -> if not (isNil augmentation) then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) - TypeDefnSig(nameInfo,SynTypeDefnSigRepr.ObjectModel (TyconDelegate (ty,arity),[invoke],m),[],m)) } + let mWhole = unionRanges nameRange m + SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (SynTypeDefnKind.Delegate (ty, arity), [invoke], m), [], mWhole)) } /* The right-hand-side of an object type definition in a signature */ tyconClassSpfn: | classSpfnBlockKindUnspecified - { let needsCheck,decls = $1 - needsCheck,(TyconUnspecified, decls) } + { let needsCheck, decls = $1 + needsCheck, (SynTypeDefnKind.Unspecified, decls) } | classOrInterfaceOrStruct classSpfnBlock END - { false,($1,$2) } + { false, ($1, $2) } | classOrInterfaceOrStruct classSpfnBlock recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedClassInterfaceOrStruct()) - false,($1,$2) } + false, ($1, $2) } | classOrInterfaceOrStruct error END { // silent recovery - false,($1,[]) } + false, ($1, []) } /* The right-hand-side of an object type definition in a signature with no explicit kind */ @@ -941,52 +1005,55 @@ classSpfnMembersAtLeastOne: /* A object member in a signature */ classMemberSpfn: | opt_attributes opt_declVisibility memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let isInline,doc,vis2,id,explicitValTyparDecls,(ty,arity),optLiteralValue = $4,grabXmlDoc(parseState,3),$5,$6,$7,$9,$11 + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), optLiteralValue = $4, grabXmlDoc(parseState, 3), $5, $6, $7, $9, $11 let getSetRangeOpt, getSet = $10 - let getSetAdjuster arity = match arity,getSet with SynValInfo([],_),MemberKind.Member -> MemberKind.PropertyGet | _ -> getSet + let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let wholeRange = let m = rhs parseState 3 match getSetRangeOpt with | None -> unionRanges m ty.Range | Some m2 -> unionRanges m m2 - let valSpfn = ValSpfn($1,id,explicitValTyparDecls,ty,arity, isInline,false,doc, vis2,optLiteralValue,wholeRange) - let _,flags = $3 - SynMemberSig.Member(valSpfn, flags (getSetAdjuster arity),wholeRange) } + |> fun m -> (m, $1) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + let valSpfn = SynValSig($1, id, explicitValTyparDecls, ty, arity, isInline, false, doc, vis2, optLiteralValue, wholeRange) + let _, flags = $3 + SynMemberSig.Member(valSpfn, flags (getSetAdjuster arity), wholeRange) } | opt_attributes opt_declVisibility interfaceMember appType - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - SynMemberSig.Interface ($4,unionRanges (rhs parseState 3) ($4).Range) } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + SynMemberSig.Interface ($4, unionRanges (rhs parseState 3) ($4).Range) } | opt_attributes opt_declVisibility INHERIT appType - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - SynMemberSig.Inherit ($4,unionRanges (rhs parseState 3) ($4).Range) } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + SynMemberSig.Inherit ($4, unionRanges (rhs parseState 3) ($4).Range) } | opt_attributes opt_declVisibility VAL fieldDecl - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let fld = $4 $1 false - SynMemberSig.ValField(fld,rhs2 parseState 3 4) } + { let wholeRange = rhs2 parseState 1 4 + if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) + let fld = $4 $1 false wholeRange + SynMemberSig.ValField (fld, wholeRange) } | opt_attributes opt_declVisibility STATIC VAL fieldDecl - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - SynMemberSig.ValField($5 $1 true,rhs2 parseState 3 5) } + { let wholeRange = rhs2 parseState 1 5 + if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) + SynMemberSig.ValField($5 $1 true wholeRange, wholeRange) } | opt_attributes opt_declVisibility STATIC typeKeyword tyconSpfn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - SynMemberSig.NestedType($5,rhs2 parseState 3 5) } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + SynMemberSig.NestedType($5, rhs2 parseState 1 5) } | opt_attributes opt_declVisibility NEW COLON topTypeWithTypeConstraints - { let vis,doc,(ty,valSynInfo) = $2,grabXmlDoc(parseState,3),$5 - let m = unionRanges (rhs parseState 3) ty.Range + { let vis, doc, (ty, valSynInfo) = $2, grabXmlDoc(parseState, 3), $5 + let m = unionRanges (rhs parseState 1) ty.Range let isInline = false - let valSpfn = ValSpfn ($1, mkSynId (rhs parseState 3) "new", noInferredTypars, ty, valSynInfo, isInline, false, doc, vis, None, m) - SynMemberSig.Member(valSpfn, CtorMemberFlags,m) } + let valSpfn = SynValSig ($1, mkSynId (rhs parseState 3) "new", noInferredTypars, ty, valSynInfo, isInline, false, doc, vis, None, m) + SynMemberSig.Member(valSpfn, CtorMemberFlags, m) } -/* The optional "with get,set" on a member in a signature */ +/* The optional "with get, set" on a member in a signature */ classMemberSpfnGetSet: | /* EMPTY */ - { None, MemberKind.Member } + { None, SynMemberKind.Member } | WITH classMemberSpfnGetSetElements { Some (rhs2 parseState 1 2), $2 } @@ -999,12 +1066,12 @@ classMemberSpfnGetSet: Some (rhs2 parseState 1 2), $2 } -/* The "get,set" on a property member in a signature */ +/* The "get, set" on a property member in a signature */ classMemberSpfnGetSetElements: | nameop { (let (id:Ident) = $1 - if id.idText = "get" then MemberKind.PropertyGet - else if id.idText = "set" then MemberKind.PropertySet + if id.idText = "get" then SynMemberKind.PropertyGet + else if id.idText = "set" then SynMemberKind.PropertySet else raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsGetOrSetRequired())) } | nameop COMMA nameop @@ -1012,18 +1079,18 @@ classMemberSpfnGetSetElements: if not ((id.idText = "get" && $3.idText = "set") || (id.idText = "set" && $3.idText = "get")) then raiseParseErrorAt (rhs2 parseState 1 3) (FSComp.SR.parsGetOrSetRequired()) - MemberKind.PropertyGetSet } + SynMemberKind.PropertyGetSet } memberSpecFlags: | memberFlags { $1 } - | ABSTRACT { (false,AbstractMemberFlags) } - | ABSTRACT MEMBER { (false,AbstractMemberFlags) } + | ABSTRACT { (false, AbstractMemberFlags) } + | ABSTRACT MEMBER { (false, AbstractMemberFlags) } /* Part of an exception definition in a signature file */ exconSpfn: | exconCore opt_classSpfn - { SynExceptionSig($1,$2,lhs parseState) } + { SynExceptionSig($1, $2, lhs parseState) } /* The optional augmentation on a type definition in a signature */ @@ -1050,26 +1117,26 @@ implementationFile: /* This will result in NO intellisense for the file! Ideally we wouldn't need this rule */ /* Note: the compiler assumes there is at least one "fragment", so an empty one is used (see 4488) */ | error EOF - { let emptyImplFileFrag = ParsedImplFileFragment.AnonModule([],rhs parseState 1) in - ParsedImplFile ([],[emptyImplFileFrag]) } + { let emptyImplFileFrag = ParsedImplFileFragment.AnonModule([], rhs parseState 1) in + ParsedImplFile ([], [emptyImplFileFrag]) } /* The sequence of namespace definitions or a single module definition that makes up an implementation file */ fileNamespaceImpls: | fileModuleImpl - { ParsedImplFile ([], [ ($1 (false,[],PreXmlDoc.Empty)) ]) } + { ParsedImplFile ([], [ ($1 (false, [], PreXmlDoc.Empty)) ]) } | fileModuleImpl fileNamespaceImplList { // If there are namespaces, the first fileModuleImpl may only contain # directives let decls = - match ($1 (false,[],PreXmlDoc.Empty)) with - | ParsedImplFileFragment.AnonModule(decls,m) -> decls - | ParsedImplFileFragment.NamespaceFragment(_,_,_, decls, _,_,_) -> decls - | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(_,_,_,_,_,_,_,m)) -> + match ($1 (false, [], PreXmlDoc.Empty)) with + | ParsedImplFileFragment.AnonModule(decls, m) -> decls + | ParsedImplFileFragment.NamespaceFragment(_, _, _, decls, _, _, _) -> decls + | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(_, _, _, _, _, _, _, m)) -> raiseParseErrorAt m (FSComp.SR.parsOnlyHashDirectivesAllowed()) let decls = decls |> List.collect (function - | (SynModuleDecl.HashDirective (hd,_)) -> [hd] + | (SynModuleDecl.HashDirective (hd, _)) -> [hd] | d -> reportParseErrorAt d.Range (FSComp.SR.parsOnlyHashDirectivesAllowed()) []) @@ -1094,21 +1161,25 @@ fileNamespaceImpl: /* A single module definition in an implementation file */ fileModuleImpl: | opt_attributes opt_declVisibility moduleIntro moduleDefnsOrExprPossiblyEmptyOrBlock - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let m2 = rhs parseState 3 - let m = (m2, $4) ||> unionRangeWithListBy (fun modu -> modu.Range) - let isRec2,path2,xml,vis = $3 + let mDeclsAndAttrs = (List.map (fun (a: SynAttributeList) -> a.Range) $1) @ (List.map (fun (d: SynModuleDecl) -> d.Range) $4) + let m = (m2, mDeclsAndAttrs) ||> unionRangeWithListBy id + let isRec2, path2, xml, vis, attribs2 = $3 (fun (isRec, path, _) -> - if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) + if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(), m2)) let lid = path@path2 - ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), NamedModule, $4, xml,$1,vis,m))) } + ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), SynModuleOrNamespaceKind.NamedModule, $4, xml, $1@attribs2, vis, m))) } | moduleDefnsOrExprPossiblyEmptyOrBlock { let m = (rhs parseState 1) (fun (isRec, path, xml) -> match path with - | [] -> ParsedImplFileFragment.AnonModule($1,m) - | _ -> ParsedImplFileFragment.NamespaceFragment(path, isRec, DeclaredNamespace, $1, xml,[],m)) } + | [] -> ParsedImplFileFragment.AnonModule($1, m) + | _ -> + let lastDeclRange = List.tryLast $1 |> Option.map (fun decl -> decl.Range) |> Option.defaultValue (rhs parseState 1) + let m = mkRange lastDeclRange.FileName (lhs parseState).Start lastDeclRange.End + ParsedImplFileFragment.NamespaceFragment(path, isRec, SynModuleOrNamespaceKind.DeclaredNamespace, $1, xml, [], m)) } /* A collection/block of definitions or expressions making up a module or namespace, possibly empty */ @@ -1142,21 +1213,21 @@ moduleDefnsOrExprPossiblyEmpty: moduleDefnsOrExpr: | opt_attributes opt_declVisibility declExpr topSeparators moduleDefnsOrExpr { match $2 with - | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()),rhs parseState 3)) + | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()), rhs parseState 3)) | _ -> () let attrDecls = if not (isNil $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ mkSynDoDecl ($3) :: $5 } | opt_attributes opt_declVisibility declExpr topSeparators { match $2 with - | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()),rhs parseState 3)) + | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()), rhs parseState 3)) | _ -> () let attrDecls = if not (isNil $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ [ mkSynDoDecl($3) ] } | opt_attributes opt_declVisibility declExpr { match $2 with - | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()),rhs parseState 3)) + | Some vis -> errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(vis.ToString()), rhs parseState 3)) | _ -> () let attrDecls = if not (isNil $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ [ mkSynDoDecl($3) ] } @@ -1192,7 +1263,7 @@ moduleDefnOrDirective: { $1 } | hashDirective - { [ SynModuleDecl.HashDirective ($1,rhs2 parseState 1 1) ] } + { [ SynModuleDecl.HashDirective ($1, rhs2 parseState 1 1) ] } /* A single definition in a namespace, module or interaction. */ @@ -1201,68 +1272,78 @@ moduleDefn: /* 'let' definitions in non-#light*/ | opt_attributes opt_declVisibility defnBindings %prec decl_let - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) parseState.ResetSynArgNameGenerator() - let (BindingSetPreAttrs(_,_,_,_,mWhole)) = $3 - mkDefnBindings (mWhole,$3,$1,$2,mWhole) } + let (BindingSetPreAttrs(_, _, _, _, mWhole)) = $3 + mkDefnBindings (mWhole, $3, $1, $2, mWhole) } /* 'let' or 'do' definitions in #light */ | opt_attributes opt_declVisibility hardwhiteLetBindings %prec decl_let - { let hwlb,m = $3 - if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { let hwlb, m = $3 + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) parseState.ResetSynArgNameGenerator() - mkDefnBindings (m,hwlb,$1,$2,m) } + mkDefnBindings (m, hwlb, $1, $2, m) } /* 'do' definitions in non-#light*/ | opt_attributes opt_declVisibility doBinding %prec decl_let - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let mWhole = rhs parseState 3 - mkDefnBindings (mWhole,$3,$1,$2,mWhole) } + mkDefnBindings (mWhole, $3, $1, $2, mWhole) } /* 'type' definitions */ | opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let (TypeDefn(ComponentInfo(cas,a,cs,b,c,d,d2,d3),e,f,g)) = $4 - let tc = (TypeDefn(ComponentInfo($1@cas,a,cs,b,c,d,d2,d3),e,f,g)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, c, d, d2, d3), e, f, g, h)) = $4 + let attrs = $1@cas + let mTc = (h, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + let tc = (SynTypeDefn(SynComponentInfo(attrs, a, cs, b, c, d, d2, d3), e, f, g, mTc)) let types = tc :: $5 [ SynModuleDecl.Types(types, (rhs parseState 3, types) ||> unionRangeWithListBy (fun t -> t.Range) ) ] } /* 'exception' definitions */ | opt_attributes opt_declVisibility exconDefn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let (SynExceptionDefn(SynExceptionDefnRepr(cas,a,b,c,d,d2),e,f)) = $3 + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let (SynExceptionDefn(SynExceptionDefnRepr(cas, a, b, c, d, d2), e, f)) = $3 let f = (f, $1) ||> unionRangeWithListBy (fun a -> a.Range) - let ec = (SynExceptionDefn(SynExceptionDefnRepr($1@cas,a,b,c,d,d2),e,f)) + let ec = (SynExceptionDefn(SynExceptionDefnRepr($1@cas, a, b, c, d, d2), e, f)) [ SynModuleDecl.Exception(ec, f) ] } /* 'module' definitions */ - | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - let attribs, (isRec, path, xml, vis) = $1,$3 - match $5 with + | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let attribs, (isRec, path, xml, vis, attribs2) = $1, $3 + match $5 with | Choice1Of2 eqn -> - if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) - if not (isNil $1) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) + if not (isNil attribs) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) + if not (isNil attribs2) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) match vis with | Some vis -> raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate(vis.ToString())) - | _ -> () - [ SynModuleDecl.ModuleAbbrev(List.head path,eqn,(rhs parseState 3, eqn) ||> unionRangeWithListBy (fun id -> id.idRange) ) ] + | None -> () + [ SynModuleDecl.ModuleAbbrev(List.head path, eqn, (rhs parseState 3, eqn) ||> unionRangeWithListBy (fun id -> id.idRange) ) ] | Choice2Of2 def -> if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) - let info = ComponentInfo(attribs,[],[],path,xml,false,vis,rhs parseState 3) - [ SynModuleDecl.NestedModule(info, isRec, def, false,(rhs2 parseState 3 4, def) ||> unionRangeWithListBy (fun d -> d.Range) ) ] } + let info = SynComponentInfo(attribs @ attribs2, None, [], path, xml, false, vis, rhs parseState 3) + [ SynModuleDecl.NestedModule(info, isRec, def, false, (rhs2 parseState 1 4, def) ||> unionRangeWithListBy (fun d -> d.Range) ) ] } /* unattached custom attributes */ | attributes recover - { errorR(Error(FSComp.SR.parsAttributeOnIncompleteCode(),rhs parseState 1)) - [] } + { errorR(Error(FSComp.SR.parsAttributeOnIncompleteCode(), rhs parseState 1)) + [ SynModuleDecl.Attributes($1, rhs parseState 1) ] } /* 'open' declarations */ - | openDecl - { [SynModuleDecl.Open($1, $1.Range)] } + | openDecl + { [ SynModuleDecl.Open($1, (rhs parseState 1)) ] } +openDecl: + /* 'open' declarations */ + | OPEN path + { SynOpenDeclTarget.ModuleOrNamespace($2.Lid, (rhs parseState 2)) } + + | OPEN typeKeyword appType + { SynOpenDeclTarget.Type($3, (rhs parseState 3)) } /* The right-hand-side of a module abbreviation definition */ /* This occurs on the right of a module abbreviation (#light encloses the r.h.s. with OBLOCKBEGIN/OBLOCKEND) */ @@ -1304,7 +1385,7 @@ namedModuleDefnBlock: // However in that case we do use type name lookup to make the resolution. match $2 with - | [ SynModuleDecl.DoExpr (_,LongOrSingleIdent(false,LongIdentWithDots(path,_),None,_),_) ] -> + | [ SynModuleDecl.DoExpr (_, LongOrSingleIdent(false, LongIdentWithDots(path, _), None, _), _) ] -> Choice1Of2 path | _ -> Choice2Of2 $2 @@ -1363,7 +1444,7 @@ attributes: /* One set of custom attributes, including [< ... >] */ attributeList: | LBRACK_LESS attributeListElements opt_seps GREATER_RBRACK opt_OBLOCKSEP - { mkAttributeList $2 (rhs2 parseState 1 3) } + { mkAttributeList $2 (rhs2 parseState 1 4) } | LBRACK_LESS error GREATER_RBRACK opt_OBLOCKSEP { mkAttributeList [] (rhs2 parseState 1 3) } @@ -1407,31 +1488,30 @@ attribute: /* The target of a custom attribute */ attributeTarget: | moduleKeyword COLON - { Some(ident("module",(rhs parseState 1))) } + { Some(ident("module", (rhs parseState 1))) } | typeKeyword COLON - { Some(ident("type",(rhs parseState 1))) } + { Some(ident("type", (rhs parseState 1))) } | ident COLON { Some($1) } /* return */ | YIELD COLON { if $1 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsSyntaxError()) - Some(ident("return",(rhs parseState 1))) } + Some(ident("return", (rhs parseState 1))) } /* Flags on a member */ memberFlags: - | STATIC MEMBER { (true,StaticMemberFlags) } - | MEMBER { (false,NonVirtualMemberFlags) } - | OVERRIDE { (false,OverrideMemberFlags) } - | DEFAULT { (false,OverrideMemberFlags) } + | STATIC MEMBER { (true, StaticMemberFlags) } + | MEMBER { (false, NonVirtualMemberFlags) } + | OVERRIDE { (false, OverrideMemberFlags) } + | DEFAULT { (false, OverrideMemberFlags) } /* The name of a type in a signature or implementation, possibly with type parameters and constraints */ typeNameInfo: | opt_attributes tyconNameAndTyparDecls opt_typeConstraints - { let typars,lid,fixity,tpcs1,vis,xmlDoc = $2 - let tpcs2 = $3 - ComponentInfo($1,typars,(tpcs1 @ tpcs2),lid,xmlDoc,fixity,vis,rangeOfLid lid) } + { let typars, lid, fixity, vis, xmlDoc = $2 + SynComponentInfo ($1, typars, $3, lid, xmlDoc, fixity, vis, rangeOfLid lid) } /* Part of a set of type definitions */ tyconDefnList: @@ -1443,33 +1523,41 @@ tyconDefnList: /* A type definition */ tyconDefn: | typeNameInfo - { TypeDefn($1,SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range),$1.Range),[],$1.Range) } - - | typeNameInfo EQUALS tyconDefnRhsBlock - { let nameRange = rhs parseState 1 - let (tcDefRepr:SynTypeDefnRepr),members = $3 nameRange + { SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range), $1.Range), [], None, $1.Range) } + + | typeNameInfo opt_equals tyconDefnRhsBlock + { if not $2 then ( + let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 + // While the spec doesn't allow long idents here, the parser doesn't enforce this, so take one ident + let typeNameId = List.last lid + raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsEqualsMissingInTypeDefinition(typeNameId.ToString())) + ) + let nameRange = rhs parseState 1 + let (tcDefRepr:SynTypeDefnRepr), members = $3 nameRange let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range) - TypeDefn($1, tcDefRepr, members, mWhole) } + SynTypeDefn($1, tcDefRepr, members, None, mWhole) } | typeNameInfo tyconDefnAugmentation { let m = (rhs parseState 1, $2) ||> unionRangeWithListBy (fun mem -> mem.Range) - TypeDefn($1,SynTypeDefnRepr.ObjectModel(TyconAugmentation,[],m),$2,m) } + SynTypeDefn($1, SynTypeDefnRepr.ObjectModel(SynTypeDefnKind.Augmentation, [], m), $2, None, m) } | typeNameInfo opt_attributes opt_declVisibility opt_HIGH_PRECEDENCE_APP simplePatterns optAsSpec EQUALS tyconDefnRhsBlock - { let vis,spats, az = $3,$5,$6 + { let vis, spats, az = $3, $5, $6 let nameRange = rhs parseState 1 - let (tcDefRepr,members) = $8 nameRange - let (ComponentInfo(_,_,_,lid,_,_,_,_)) = $1 - let memberCtorPattern = SynMemberDefn.ImplicitCtor (vis,$2,spats,az,rangeOfLid lid) + let (tcDefRepr, members) = $8 nameRange + let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 + // Gets the XML doc comments prior to the implicit constructor + let xmlDoc = grabXmlDoc(parseState, 5) + let memberCtorPattern = SynMemberDefn.ImplicitCtor (vis, $2, spats, az, xmlDoc, rangeOfLid lid) let tcDefRepr = match tcDefRepr with - | SynTypeDefnRepr.ObjectModel (k,cspec,m) -> SynTypeDefnRepr.ObjectModel (k,memberCtorPattern :: cspec,m) + | SynTypeDefnRepr.ObjectModel (k, cspec, m) -> SynTypeDefnRepr.ObjectModel (k, memberCtorPattern :: cspec, m) | _ -> reportParseErrorAt (rhs2 parseState 1 5) (FSComp.SR.parsOnlyClassCanTakeValueArguments()); tcDefRepr let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range) - TypeDefn($1,tcDefRepr,members,mWhole) } + SynTypeDefn($1, tcDefRepr, members, Some memberCtorPattern, mWhole) } /* The right-hand-side of a type definition */ @@ -1502,48 +1590,47 @@ tyconDefnRhs: /* A simple type definition */ | tyconDefnOrSpfnSimpleRepr { let m = $1.Range - (fun nameRange augmentation -> SynTypeDefnRepr.Simple ($1,m),augmentation) } + (fun nameRange augmentation -> SynTypeDefnRepr.Simple ($1, m), augmentation) } /* An object type definition */ | tyconClassDefn - { let needsCheck,(kind,decls),mopt = $1 + { let needsCheck, (kind, decls), mopt = $1 let m = match mopt with | None -> (lhs parseState).StartRange // create a zero-width range | Some m -> m (fun nameRange augmentation -> if needsCheck && isNil decls then reportParseErrorAt nameRange (FSComp.SR.parsEmptyTypeDefinition()) - SynTypeDefnRepr.ObjectModel (kind,decls,m),augmentation) } + SynTypeDefnRepr.ObjectModel (kind, decls, m), augmentation) } /* A delegate type definition */ | DELEGATE OF topType { let m = lhs parseState - let ty,arity = $3 + let ty, arity = $3 (fun nameRange augmentation -> - let valSpfn = ValSpfn([],mkSynId m "Invoke",inferredTyparDecls,ty,arity,false,false,PreXmlDoc.Empty,None,None,m) - let invoke = SynMemberDefn.AbstractSlot(valSpfn,AbstractMemberFlags MemberKind.Member,m) + let valSpfn = SynValSig([], mkSynId m "Invoke", inferredTyparDecls, ty, arity, false, false, PreXmlDoc.Empty, None, None, m) + let invoke = SynMemberDefn.AbstractSlot(valSpfn, AbstractMemberFlags SynMemberKind.Member, m) if not (isNil augmentation) then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) - SynTypeDefnRepr.ObjectModel (TyconDelegate (ty,arity),[invoke],m),[]) } + SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Delegate (ty, arity), [invoke], m), []) } /* The right-hand-side of a object type definition */ tyconClassDefn: | classDefnBlockKindUnspecified - { let needsCheck,decls,mopt = $1 - needsCheck,(TyconUnspecified, decls),mopt } + { let needsCheck, decls, mopt = $1 + needsCheck, (SynTypeDefnKind.Unspecified, decls), mopt } | classOrInterfaceOrStruct classDefnBlock END - { let m = (rhs parseState 1, $2) ||> unionRangeWithListBy (fun (d:SynMemberDefn) -> d.Range) - false,($1,$2),Some(m) } + { false, ($1, $2), Some (rhs2 parseState 1 3) } | classOrInterfaceOrStruct classDefnBlock recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedClassInterfaceOrStruct()) let m = (rhs parseState 1, $2) ||> unionRangeWithListBy (fun (d:SynMemberDefn) -> d.Range) - false,($1,$2),Some(m) } + false, ($1, $2), Some(m) } | classOrInterfaceOrStruct error END { // silent recovery - false,($1,[]),Some(rhs parseState 1) } + false, ($1, []), Some (rhs2 parseState 1 3) } /* The right-hand-side of a object type definition where the class/interface/struct kind has not been specified */ @@ -1554,7 +1641,7 @@ classDefnBlockKindUnspecified: match $2 with | _ :: _ -> Some( (rhs parseState 1, $2) ||> unionRangeWithListBy (fun (d:SynMemberDefn) -> d.Range) ) | _ -> None - false,$2,mopt } + false, $2, mopt } | OBLOCKBEGIN classDefnMembers oblockend { let mopt = @@ -1591,12 +1678,16 @@ classDefnMembers: /* The members of an object type definition or type augmentation */ -classDefnMembersAtLeastOne: - | classDefnMember opt_seps classDefnMembers - { $1 @ $3 } +classDefnMembersAtLeastOne: + | classDefnMember opt_seps classDefnMembers + { match $1, $3 with + | [ SynMemberDefn.Interface (_, Some [], m) ], nextMember :: _ -> + warning(IndentationProblem(FSComp.SR.lexfltTokenIsOffsideOfContextStartedEarlier(warningStringOfPos m.Start), nextMember.Range)) + | _ -> () + $1 @ $3 } -/* The "with get,set" part of a member definition */ +/* The "with get, set" part of a member definition */ classDefnMemberGetSet: | WITH classDefnMemberGetSetElements { $2 } @@ -1608,7 +1699,7 @@ classDefnMemberGetSet: { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedWith()) $2 } -/* The "get,set" part of a member definition */ +/* The "get, set" part of a member definition */ classDefnMemberGetSetElements: | classDefnMemberGetSetElement { [$1] } @@ -1616,36 +1707,37 @@ classDefnMemberGetSetElements: { [$1;$3] } classDefnMemberGetSetElement: - | opt_inline opt_attributes bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSeqExprBlock + | opt_inline opt_attributes bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock { let mRhs = ($6 : SynExpr).Range - ($1,$2,$3,$4,$6,mRhs) } + ($1, $2, $3, $4, $6, mRhs) } /* The core of a member definition */ memberCore: /* Methods and simple getter properties */ - | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSeqExprBlock + | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedSequentialExprBlock { let mRhs = $5.Range let optReturnType = $3 let bindingBuilder, mBindLhs = $2 (fun vis memFlagsBuilder attrs rangeStart -> - let memberFlags = Some (memFlagsBuilder MemberKind.Member) - let binding = bindingBuilder (vis, $1, false, mBindLhs, NoSequencePointAtInvisibleBinding, optReturnType, $5, mRhs, [], attrs, memberFlags) + let memberFlags = Some (memFlagsBuilder SynMemberKind.Member) + let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + let binding = bindingBuilder (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags) let memberRange = unionRanges rangeStart mRhs [ SynMemberDefn.Member (binding, memberRange) ]) } /* Properties with explicit get/set, also indexer properties */ | opt_inline bindingPattern opt_topReturnTypeWithTypeConstraints classDefnMemberGetSet - { let mWhole = (rhs parseState 2, $4) ||> unionRangeWithListBy (fun (_,_,_,_,_,m2) -> m2) + { let mWhole = (rhs parseState 2, $4) ||> unionRangeWithListBy (fun (_, _, _, _, _, m2) -> m2) let propertyNameBindingBuilder, _ = $2 let optPropertyType = $3 let isMutable = false (fun visNoLongerUsed memFlagsBuilder attrs rangeStart -> - let hasGet = ref false - let hasSet = ref false + let mutable hasGet = false + let mutable hasSet = false // Iterate over 1 or 2 'get'/'set' entries - $4 |> List.choose (fun (optInline,optAttrs,(bindingBuilder,mBindLhs),optReturnType,expr,exprm) -> + $4 |> List.choose (fun (optInline, optAttrs, (bindingBuilder, mBindLhs), optReturnType, expr, exprm) -> let optInline = $1 || optInline // optional attributes are only applied to getters and setters @@ -1656,32 +1748,32 @@ memberCore: let attrs = attrs @ optAttrs - let binding = bindingBuilder (visNoLongerUsed,optInline,isMutable,mBindLhs,NoSequencePointAtInvisibleBinding,optReturnType,expr,exprm,[],attrs,Some (memFlagsBuilder MemberKind.Member)) - let (Binding (vis, _, isInline, _, attrs, doc, valSynData, pv, _, _, mBindLhs, spBind)) = binding + let binding = bindingBuilder (visNoLongerUsed, optInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some (memFlagsBuilder SynMemberKind.Member)) + let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, _, _, mBindLhs, spBind)) = binding let memberKind = let getset = let rec go p = match p with - | SynPat.LongIdent (LongIdentWithDots([id],_),_,_,_,_,_) -> id.idText - | SynPat.Named (_,nm,_,_,_) -> nm.idText - | SynPat.Typed (p,_,_) -> go p - | SynPat.Attrib (p,_,_) -> go p + | SynPat.LongIdent (LongIdentWithDots([id], _), _, _, _, _, _) -> id.idText + | SynPat.Named (nm, _, _, _) | SynPat.As (_, SynPat.Named (nm, _, _, _), _) -> nm.idText + | SynPat.Typed (p, _, _) -> go p + | SynPat.Attrib (p, _, _) -> go p | _ -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax()) go pv if getset = "get" then - if !hasGet then + if hasGet then reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired()) None else - hasGet := true - Some MemberKind.PropertyGet + hasGet <- true + Some SynMemberKind.PropertyGet else if getset = "set" then - if !hasSet then + if hasSet then reportParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired()) None else - hasSet := true - Some MemberKind.PropertySet + hasSet <- true + Some SynMemberKind.PropertySet else raiseParseErrorAt mBindLhs (FSComp.SR.parsGetAndOrSetRequired()) @@ -1689,31 +1781,32 @@ memberCore: | None -> None | Some memberKind -> - // REVIEW: It's hard not to ignore the optPropertyType type annotation for 'set' properties. To apply it, + // REVIEW: It's hard not to ignore the optPropertyType type annotation for 'set' properties. To apply it, // we should apply it to the last argument, but at this point we've already pushed the patterns that // make up the arguments onto the RHS. So we just always give a warning. begin match optPropertyType with - | Some _ -> errorR(Error(FSComp.SR.parsTypeAnnotationsOnGetSet(),mBindLhs)) + | Some _ -> errorR(Error(FSComp.SR.parsTypeAnnotationsOnGetSet(), mBindLhs)) | None -> () end let optReturnType = match (memberKind, optReturnType) with - | MemberKind.PropertySet, _ -> optReturnType + | SynMemberKind.PropertySet, _ -> optReturnType | _, None -> optPropertyType | _ -> optReturnType // REDO with the correct member kind - let binding = bindingBuilder(vis,isInline,isMutable,mBindLhs,NoSequencePointAtInvisibleBinding,optReturnType,expr,exprm,[],attrs,Some(memFlagsBuilder memberKind)) + let binding = bindingBuilder(vis, isInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder memberKind)) - let (Binding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind)) = binding + let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind)) = binding + let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - let (SynValData(_,valSynInfo,_)) = valSynData + let (SynValData(_, valSynInfo, _)) = valSynData // Setters have all arguments tupled in their internal TAST form, though they don't appear to be // tupled from the syntax - let memFlags = memFlagsBuilder memberKind + let memFlags : SynMemberFlags = memFlagsBuilder memberKind let valSynInfo = let adjustValueArg valueArg = @@ -1722,100 +1815,100 @@ memberCore: | _ -> SynInfo.unnamedTopArg match memberKind, valSynInfo, memFlags.IsInstance with - | MemberKind.PropertyGet, SynValInfo ([], _ret), false - | MemberKind.PropertyGet, SynValInfo ([_], _ret), true -> - raiseParseErrorAt mBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument()) + | SynMemberKind.PropertyGet, SynValInfo ([], _ret), false + | SynMemberKind.PropertyGet, SynValInfo ([_], _ret), true -> + raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument()) - | MemberKind.PropertyGet, SynValInfo (thisArg :: indexOrUnitArgs :: rest, ret), true -> + | SynMemberKind.PropertyGet, SynValInfo (thisArg :: indexOrUnitArgs :: rest, ret), true -> if not rest.IsEmpty then - reportParseErrorAt mBindLhs (FSComp.SR.parsGetterAtMostOneArgument ()) + reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ()) SynValInfo ([thisArg; indexOrUnitArgs], ret) - | MemberKind.PropertyGet, SynValInfo (indexOrUnitArgs :: rest,ret), false -> + | SynMemberKind.PropertyGet, SynValInfo (indexOrUnitArgs :: rest, ret), false -> if not rest.IsEmpty then - reportParseErrorAt mBindLhs (FSComp.SR.parsGetterAtMostOneArgument ()) + reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ()) SynValInfo ([indexOrUnitArgs], ret) - | MemberKind.PropertySet, SynValInfo ([thisArg;valueArg], ret), true -> + | SynMemberKind.PropertySet, SynValInfo ([thisArg;valueArg], ret), true -> SynValInfo ([thisArg; adjustValueArg valueArg], ret) - | MemberKind.PropertySet, SynValInfo (thisArg :: indexArgs :: valueArg :: rest, ret), true -> + | SynMemberKind.PropertySet, SynValInfo (thisArg :: indexArgs :: valueArg :: rest, ret), true -> if not rest.IsEmpty then - reportParseErrorAt mBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ()) + reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ()) SynValInfo ([thisArg; indexArgs @ adjustValueArg valueArg], ret) - | MemberKind.PropertySet, SynValInfo ([valueArg], ret), false -> + | SynMemberKind.PropertySet, SynValInfo ([valueArg], ret), false -> SynValInfo ([adjustValueArg valueArg], ret) - | MemberKind.PropertySet, SynValInfo (indexArgs :: valueArg :: rest,ret), _ -> + | SynMemberKind.PropertySet, SynValInfo (indexArgs :: valueArg :: rest, ret), _ -> if not rest.IsEmpty then - reportParseErrorAt mBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ()) + reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ()) SynValInfo ([indexArgs @ adjustValueArg valueArg], ret) | _ -> // should be unreachable, cover just in case - raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidProperty ()) + raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidProperty ()) - let valSynData = SynValData(Some(memFlags), valSynInfo,None) + let valSynData = SynValData(Some(memFlags), valSynInfo, None) // Fold together the information from the first lambda pattern and the get/set binding - // This uses the 'this' variable from the first and the patterns for the get/set binding, + // This uses the 'this' variable from the first and the patterns for the get/set binding, // replacing the get/set identifier. A little gross. let bindingPatAdjusted, xmlDocAdjusted = - let bindingOuter = propertyNameBindingBuilder(vis,optInline,isMutable,mBindLhs,spBind,optReturnType,expr,exprm,[],attrs,Some(memFlagsBuilder MemberKind.Member)) + let bindingOuter = propertyNameBindingBuilder(vis, optInline, isMutable, mWholeBindLhs, spBind, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder SynMemberKind.Member)) - let (Binding (_,_,_,_,_,doc2,_,bindingPatOuter,_,_,_,_)) = bindingOuter - + let (SynBinding (_, _, _, _, _, doc2, _, bindingPatOuter, _, _, _, _)) = bindingOuter - let lidOuter,lidVisOuter = + let lidOuter, lidVisOuter = match bindingPatOuter with - | SynPat.LongIdent (lid,None,None, SynConstructorArgs.Pats [],lidVisOuter,m) -> lid,lidVisOuter - | SynPat.Named (_,id,_,visOuter,m) -> LongIdentWithDots([id],[]),visOuter - | p -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax()) + | SynPat.LongIdent (lid, None, None, SynArgPats.Pats [], lidVisOuter, m) -> lid, lidVisOuter + | SynPat.Named (id, _, visOuter, m) | SynPat.As(_, SynPat.Named (id, _, visOuter, m), _) -> LongIdentWithDots([id], []), visOuter + | p -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax()) // Merge the visibility from the outer point with the inner point, e.g. // member this.Size with get () = m_size let mergeLidVisOuter lidVisInner = - match lidVisInner,lidVisOuter with - | None,None -> None - | Some lidVisInner,None | None,Some lidVisInner -> Some lidVisInner + match lidVisInner, lidVisOuter with + | None, None -> None + | Some lidVisInner, None | None, Some lidVisInner -> Some lidVisInner | Some _, Some _ -> - errorR(Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet(),mBindLhs)) + errorR(Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet(), mWholeBindLhs)) lidVisInner // Replace the "get" or the "set" with the right name let rec go p = match p with - | SynPat.LongIdent (LongIdentWithDots([id],_),_,tyargs,SynConstructorArgs.Pats args,lidVisInner,m) -> + | SynPat.LongIdent (LongIdentWithDots([id], _), _, tyargs, SynArgPats.Pats args, lidVisInner, m) -> // Setters have all arguments tupled in their internal form, though they don't // appear to be tupled from the syntax. Somewhat unfortunate let args = if id.idText = "set" then match args with - | [SynPat.Paren(SynPat.Tuple (false,indexPats,_),indexPatRange);valuePat] when id.idText = "set" -> - [SynPat.Tuple(false,indexPats@[valuePat],unionRanges indexPatRange valuePat.Range)] + | [SynPat.Paren(SynPat.Tuple (false, indexPats, _), indexPatRange);valuePat] when id.idText = "set" -> + [SynPat.Tuple(false, indexPats@[valuePat], unionRanges indexPatRange valuePat.Range)] | [indexPat;valuePat] -> - [SynPat.Tuple(false,args,unionRanges indexPat.Range valuePat.Range)] + [SynPat.Tuple(false, args, unionRanges indexPat.Range valuePat.Range)] | [valuePat] -> [valuePat] | _ -> raiseParseErrorAt m (FSComp.SR.parsSetSyntax()) else args -// let idTool : Ident list = lidOuter |> List.map (fun (li:Ident) -> ident(li.idText,id.idRange)) |> List.rev |> List.take 1 - SynPat.LongIdent (lidOuter,Some(id),tyargs, SynConstructorArgs.Pats args,mergeLidVisOuter lidVisInner,m) - | SynPat.Named (_,nm,_,lidVisInner,m) -> SynPat.LongIdent (lidOuter,None,None, SynConstructorArgs.Pats [], mergeLidVisOuter lidVisInner,m) - | SynPat.Typed (p,ty,m) -> SynPat.Typed(go p,ty,m) - | SynPat.Attrib (p,attribs,m) -> SynPat.Attrib(go p,attribs,m) +// let idTool : Ident list = lidOuter |> List.map (fun (li:Ident) -> ident(li.idText, id.idRange)) |> List.rev |> List.take 1 + SynPat.LongIdent (lidOuter, Some(id), tyargs, SynArgPats.Pats args, mergeLidVisOuter lidVisInner, m) + | SynPat.Named (nm, _, lidVisInner, m) + | SynPat.As (_, SynPat.Named (nm, _, lidVisInner, m), _) -> SynPat.LongIdent (lidOuter, None, None, SynArgPats.Pats [], mergeLidVisOuter lidVisInner, m) + | SynPat.Typed (p, ty, m) -> SynPat.Typed(go p, ty, m) + | SynPat.Attrib (p, attribs, m) -> SynPat.Attrib(go p, attribs, m) | SynPat.Wild(m) -> SynPat.Wild(m) - | _ -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax()) + | _ -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax()) - go pv,PreXmlDoc.Merge doc2 doc + go pv, PreXmlDoc.Merge doc2 doc - let binding = Binding (vis, NormalBinding, isInline, isMutable, attrs, xmlDocAdjusted, valSynData, bindingPatAdjusted, rhsRetInfo, rhsExpr, mBindLhs, spBind) + let binding = SynBinding (vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDocAdjusted, valSynData, bindingPatAdjusted, rhsRetInfo, rhsExpr, mWholeBindLhs, spBind) let memberRange = unionRanges rangeStart mWhole Some (SynMemberDefn.Member (binding, memberRange)))) } @@ -1829,12 +1922,12 @@ abstractMemberFlags: /* A member definition */ classDefnMember: | opt_attributes opt_declVisibility classDefnBindings - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - [mkClassMemberLocalBindings(false,None,$1,$2,$3)] } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + [mkClassMemberLocalBindings(false, None, $1, $2, $3)] } | opt_attributes opt_declVisibility STATIC classDefnBindings - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - [mkClassMemberLocalBindings(true,Some (rhs parseState 3),$1,$2,$4)] } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + [mkClassMemberLocalBindings(true, Some (rhs parseState 3), $1, $2, $4)] } | opt_attributes opt_declVisibility memberFlags memberCore opt_ODECLEND { let rangeStart = rhs parseState 1 @@ -1844,78 +1937,82 @@ classDefnMember: $4 $2 flags $1 rangeStart } | opt_attributes opt_declVisibility interfaceMember appType opt_interfaceImplDefn - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(),rhs parseState 1)) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(),rhs parseState 3)) - let mWhole = + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(), rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(), rhs parseState 3)) + let members = Option.map fst $5 + let mWhole = match $5 with - | None -> rhs2 parseState 3 4 - | Some(mems) -> (rhs2 parseState 3 4, mems) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range) - [ SynMemberDefn.Interface ($4, $5, mWhole) ] } + | None -> rhs2 parseState 1 4 + | Some (_, m) -> unionRanges (rhs2 parseState 1 4) m + [ SynMemberDefn.Interface ($4, members, mWhole) ] } | opt_attributes opt_declVisibility abstractMemberFlags opt_inline nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet opt_ODECLEND - { let ty,arity = $8 - let isInline,doc,id,explicitValTyparDecls = $4,grabXmlDoc(parseState,3),$5,$6 + { let ty, arity = $8 + let isInline, doc, id, explicitValTyparDecls = $4, grabXmlDoc(parseState, 3), $5, $6 let getSetRangeOpt, getSet = $9 - let getSetAdjuster arity = match arity,getSet with SynValInfo([],_),MemberKind.Member -> MemberKind.PropertyGet | _ -> getSet + let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let wholeRange = - let m = rhs parseState 3 + let m = rhs parseState 1 match getSetRangeOpt with | None -> unionRanges m ty.Range | Some m2 -> unionRanges m m2 - if Option.isSome $2 then errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(),wholeRange)) - let valSpfn = ValSpfn($1,id,explicitValTyparDecls,ty,arity, isInline,false,doc, None,None,wholeRange) - [ SynMemberDefn.AbstractSlot(valSpfn,AbstractMemberFlags (getSetAdjuster arity), wholeRange) ] } + if Option.isSome $2 then errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(), wholeRange)) + let valSpfn = SynValSig($1, id, explicitValTyparDecls, ty, arity, isInline, false, doc, None, None, wholeRange) + [ SynMemberDefn.AbstractSlot(valSpfn, AbstractMemberFlags (getSetAdjuster arity), wholeRange) ] } | opt_attributes opt_declVisibility inheritsDefn - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(),rhs parseState 1)) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityIllegalOnInherit(),rhs parseState 1)) + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(), rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityIllegalOnInherit(), rhs parseState 1)) [ $3 ] } | opt_attributes opt_declVisibility valDefnDecl opt_ODECLEND - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - $3 None $1 false } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let rangeStart = rhs parseState 1 + $3 rangeStart $1 false } | opt_attributes opt_declVisibility STATIC valDefnDecl opt_ODECLEND - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - $4 (Some (rhs parseState 3)) $1 true } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let rangeStart = rhs parseState 1 + $4 rangeStart $1 true } | opt_attributes opt_declVisibility memberFlags autoPropsDefnDecl opt_ODECLEND { let rangeStart = rhs parseState 1 if Option.isSome $2 then - errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) let isStatic, flags = $3 $4 $1 isStatic flags rangeStart } - | opt_attributes opt_declVisibility NEW atomicPattern optAsSpec EQUALS typedSeqExprBlock opt_ODECLEND - { let m = unionRanges (rhs2 parseState 3 6) $7.Range + | opt_attributes opt_declVisibility NEW atomicPattern optAsSpec EQUALS typedSequentialExprBlock opt_ODECLEND + { let mWholeBindLhs = rhs2 parseState 1 (if Option.isSome $5 then 5 else 4) + let m = unionRanges mWholeBindLhs $7.Range let expr = $7 - let valSynData = SynValData (Some CtorMemberFlags, SynValInfo([SynInfo.InferSynArgInfoFromPat $4],SynInfo.unnamedRetVal), $5) + let valSynData = SynValData (Some CtorMemberFlags, SynValInfo([SynInfo.InferSynArgInfoFromPat $4], SynInfo.unnamedRetVal), $5) let vis = $2 - let declPat = SynPat.LongIdent (LongIdentWithDots([mkSynId (rhs parseState 3) "new"],[]),None,Some noInferredTypars, SynConstructorArgs.Pats [$4],vis,rhs parseState 3) + let declPat = SynPat.LongIdent (LongIdentWithDots([mkSynId (rhs parseState 3) "new"], []), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3) // Check that 'SynPatForConstructorDecl' matches this correctly assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false) - [ SynMemberDefn.Member(Binding (None,NormalBinding,false,false,$1,grabXmlDoc(parseState,3),valSynData, declPat,None,expr,m,NoSequencePointAtInvisibleBinding),m) ] } + [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, 3), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] } | opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) - [ SynMemberDefn.NestedType($5,None,rhs2 parseState 3 5) ] } + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + [ SynMemberDefn.NestedType($5, None, rhs2 parseState 1 5) ] } /* A 'val' definition in an object type definition */ valDefnDecl: | VAL opt_mutable opt_access ident COLON typ { let mRhs = rhs2 parseState 4 6 - let doc = grabXmlDoc(parseState,4) + let doc = grabXmlDoc(parseState, 4) let mValDecl = rhs2 parseState 1 6 - (fun mLeft attribs isStatic -> - let mValDecl = match mLeft with None -> mValDecl | Some m -> unionRanges m mValDecl - let fld = Field(attribs,isStatic,Some $4,$6,$2,doc,$3,mRhs) + (fun rangeStart attribs isStatic -> + let mValDecl = unionRanges rangeStart mValDecl + let fld = SynField(attribs, isStatic, Some $4, $6, $2, doc, $3, mRhs) [ SynMemberDefn.ValField(fld, mValDecl) ]) } /* An auto-property definition in an object type definition */ autoPropsDefnDecl: - | VAL opt_mutable opt_access ident opt_typ EQUALS typedSeqExprBlock classMemberSpfnGetSet + | VAL opt_mutable opt_access ident opt_typ EQUALS typedSequentialExprBlock classMemberSpfnGetSet { let doc = grabXmlDoc(parseState, 5) let mGetSetOpt, getSet = $8 if $2 then @@ -1930,85 +2027,121 @@ opt_typ: | /* EMPTY */ { None } | COLON typ { Some $2 } + atomicPatternLongIdent: - | UNDERSCORE DOT pathOp { - if not (parseState.LexBuffer.SupportsFeature LanguageFeature.SingleUnderscorePattern) then - raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolDot()) - let (LongIdentWithDots(lid,dotms)) = $3 in (None,LongIdentWithDots(ident("_",rhs parseState 1)::lid, rhs parseState 2::dotms)) - } - | GLOBAL DOT pathOp { let (LongIdentWithDots(lid,dotms)) = $3 in (None,LongIdentWithDots(ident(MangledGlobalName,rhs parseState 1) :: lid, rhs parseState 2 :: dotms)) } - | pathOp { (None,$1) } - | access UNDERSCORE DOT pathOp { - if not (parseState.LexBuffer.SupportsFeature LanguageFeature.SingleUnderscorePattern) then - raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolDot()) - let (LongIdentWithDots(lid,dotms)) = $4 in (Some($1),LongIdentWithDots(ident("_",rhs parseState 1)::lid, rhs parseState 2::dotms)) - } - | access pathOp { (Some($1), $2) } + | UNDERSCORE DOT pathOp + { if not (parseState.LexBuffer.SupportsFeature LanguageFeature.SingleUnderscorePattern) then + raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolDot()) + let (LongIdentWithDots(lid, dotms)) = $3 + (None, LongIdentWithDots(ident("_", rhs parseState 1)::lid, rhs parseState 2::dotms)) } + + | GLOBAL DOT pathOp + { let (LongIdentWithDots(lid, dotms)) = $3 + (None, LongIdentWithDots(ident(MangledGlobalName, rhs parseState 1) :: lid, rhs parseState 2 :: dotms)) } + + | pathOp + { (None, $1) } + + | access UNDERSCORE DOT pathOp + { if not (parseState.LexBuffer.SupportsFeature LanguageFeature.SingleUnderscorePattern) then + raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedSymbolDot()) + let (LongIdentWithDots(lid, dotms)) = $4 + (Some($1), LongIdentWithDots(ident("_", rhs parseState 2)::lid, rhs parseState 3::dotms)) } + + | access pathOp + { (Some($1), $2) } opt_access: - | /* EMPTY */ { None } - | access { Some($1) } + | /* EMPTY */ + { None } + + | access + { Some($1) } access: - | PRIVATE { SynAccess.Private } - | PUBLIC { SynAccess.Public } - | INTERNAL { SynAccess.Internal } + | PRIVATE + { SynAccess.Private } + + | PUBLIC + { SynAccess.Public } + + | INTERNAL + { SynAccess.Internal } /* only valid on 'NEW' */ opt_declVisibility: - | access { Some($1) } - | /* EMPTY */ { None } + | access + { Some($1) } + + | /* EMPTY */ + { None } -opt_interfaceImplDefn: - | WITH objectImplementationBlock declEnd { Some($2) } - | /* EMPTY */ { None } +opt_interfaceImplDefn: + | WITH objectImplementationBlock declEnd + { let members = $2 + let m = (rhs parseState 1, members) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range) + Some (members, m) } + + | WITH + { Some ([], rhs parseState 1) } + + | /* EMPTY */ + { None } opt_classDefn: - | WITH classDefnBlock declEnd { $2 } - | /* EMPTY */ { [] } + | WITH classDefnBlock declEnd + { $2 } + + | /* EMPTY */ + { [] } /* An 'inherits' definition in an object type definition */ inheritsDefn: | INHERIT atomTypeNonAtomicDeprecated optBaseSpec { let mDecl = unionRanges (rhs parseState 1) (($2): SynType).Range - SynMemberDefn.Inherit($2,$3,mDecl) } + SynMemberDefn.Inherit($2, $3, mDecl) } | INHERIT atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType optBaseSpec { let mDecl = unionRanges (rhs parseState 1) $4.Range - SynMemberDefn.ImplicitInherit($2,$4,$5,mDecl) } + SynMemberDefn.ImplicitInherit($2, $4, $5, mDecl) } | INHERIT ends_coming_soon_or_recover { let mDecl = (rhs parseState 1) if not $2 then errorR(Error(FSComp.SR.parsTypeNameCannotBeEmpty(), mDecl)) - SynMemberDefn.Inherit(SynType.LongIdent(LongIdentWithDots([], [])), None,mDecl) } + SynMemberDefn.Inherit(SynType.LongIdent(LongIdentWithDots([], [])), None, mDecl) } optAsSpec: - | asSpec { Some($1) } - | { None } + | asSpec + { Some($1) } -asSpec: - | AS ident { $2 } + | /* EMPTY */ + { None } +asSpec: + | AS ident + { $2 } optBaseSpec: - | baseSpec { Some($1) } - | { None } + | baseSpec + { Some($1) } + | /* EMPTY */ + { None } baseSpec: | AS ident { if ($2).idText <> "base" then - errorR(Error(FSComp.SR.parsInheritDeclarationsCannotHaveAsBindings(),rhs2 parseState 1 2)) - ident("base",rhs parseState 2) } + errorR(Error(FSComp.SR.parsInheritDeclarationsCannotHaveAsBindings(), rhs2 parseState 1 2)) + ident("base", rhs parseState 2) } | AS BASE - { errorR(Error(FSComp.SR.parsInheritDeclarationsCannotHaveAsBindings(),rhs2 parseState 1 2)) - ident("base",rhs parseState 2) } + { errorR(Error(FSComp.SR.parsInheritDeclarationsCannotHaveAsBindings(), rhs2 parseState 1 2)) + ident("base", rhs parseState 2) } /* The members in an object expression or interface implementation */ @@ -2061,43 +2194,46 @@ tyconDefnOrSpfnSimpleRepr: /* type MyAlias = SomeTypeProvider<@"foo"> is a common error, special-case it */ | opt_attributes opt_declVisibility path LQUOTE STRING recover { errorR(Error(FSComp.SR.parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString(), rhs parseState 4)) - SynTypeDefnSimpleRepr.TypeAbbrev (ParserDetail.ThereWereSignificantParseErrorsSoDoNotTypecheckThisNode, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } + SynTypeDefnSimpleRepr.TypeAbbrev (ParserDetail.ErrorRecovery, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } /* A type abbreviation */ | opt_attributes opt_declVisibility typ - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) SynTypeDefnSimpleRepr.TypeAbbrev (ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A union type definition */ | opt_attributes opt_declVisibility unionTypeRepr - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) let rangesOf3 = $3 |> List.map (function |Choice1Of2(ec)->ec.Range | Choice2Of2(uc)->uc.Range) let mWhole = (rhs2 parseState 1 2, rangesOf3) ||> List.fold unionRanges if $3 |> List.exists (function Choice1Of2 _ -> true | _ -> false) then ( - if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumTypesCannotHaveVisibilityDeclarations(),rhs parseState 2)); + if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumTypesCannotHaveVisibilityDeclarations(), rhs parseState 2)); SynTypeDefnSimpleRepr.Enum ($3 |> List.choose (function | Choice1Of2 data -> Some(data) - | Choice2Of2(UnionCase(_,_,_,_,_,m)) -> - errorR(Error(FSComp.SR.parsAllEnumFieldsRequireValues(),m)); None), + | Choice2Of2(SynUnionCase(_, _, _, _, _, m)) -> + errorR(Error(FSComp.SR.parsAllEnumFieldsRequireValues(), m)); None), mWhole) ) else - SynTypeDefnSimpleRepr.Union ($2, + SynTypeDefnSimpleRepr.Union ($2, $3 |> List.choose (function Choice2Of2 data -> Some(data) | Choice1Of2 _ -> failwith "huh?"), mWhole) } /* A record type definition */ | opt_attributes opt_declVisibility braceFieldDeclList - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) - SynTypeDefnSimpleRepr.Record ($2,$3,lhs parseState) } + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) + SynTypeDefnSimpleRepr.Record ($2, $3, lhs parseState) } /* An inline-assembly type definition, for FSharp.Core library only */ - | opt_attributes opt_declVisibility LPAREN inlineAssemblyTyconRepr rparen - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) - libraryOnlyError (lhs parseState) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsInlineAssemblyCannotHaveVisibilityDeclarations(),rhs parseState 2)) - $4 } + | opt_attributes opt_declVisibility LPAREN HASH string HASH rparen + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) + let lhsm = lhs parseState + if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyError lhsm + if Option.isSome $2 then errorR(Error(FSComp.SR.parsInlineAssemblyCannotHaveVisibilityDeclarations(), rhs parseState 2)) + let s, _ = $5 + let ilType = ParseAssemblyCodeType s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.LanguageVersion (rhs parseState 5) + SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (box ilType, lhsm) } /* The core of a record type definition */ @@ -2114,9 +2250,9 @@ braceFieldDeclList: anonRecdType: | STRUCT braceBarFieldDeclListCore - { $2,true } + { $2, true } | braceBarFieldDeclListCore - { $1,false } + { $1, false } /* The core of a record type definition */ braceBarFieldDeclListCore: @@ -2130,16 +2266,15 @@ braceBarFieldDeclListCore: | LBRACE_BAR error bar_rbrace { [] } -inlineAssemblyTyconRepr: - | HASH stringOrKeywordString HASH - { libraryOnlyError (lhs parseState) - let lhsm = lhs parseState - SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (internalParseAssemblyCodeType $2 parseState.LexBuffer.SupportsFeature (rhs parseState 2),lhsm) } - classOrInterfaceOrStruct: - | CLASS { TyconClass } - | INTERFACE { TyconInterface } - | STRUCT { TyconStruct } + | CLASS + { SynTypeDefnKind.Class } + + | INTERFACE + { SynTypeDefnKind.Interface } + + | STRUCT + { SynTypeDefnKind.Struct } interfaceMember: | INTERFACE { } @@ -2147,18 +2282,20 @@ interfaceMember: tyconNameAndTyparDecls: | opt_access path - { [], $2.Lid,false,[],$1,grabXmlDoc(parseState,2) } + { None, $2.Lid, false, $1, grabXmlDoc(parseState, 2) } | opt_access prefixTyparDecls path - { $2, $3.Lid,false,[],$1,grabXmlDoc(parseState,2) } + { Some $2, $3.Lid, false, $1, grabXmlDoc(parseState, 2) } | opt_access path postfixTyparDecls - { let tps,tpcs = $3 - tps, $2.Lid,true,tpcs,$1,grabXmlDoc(parseState,2) } + { Some $3, $2.Lid, true, $1, grabXmlDoc(parseState, 2) } prefixTyparDecls: - | typar { [ TyparDecl([],$1) ] } - | LPAREN typarDeclList rparen { List.rev $2 } + | typar + { SynTyparDecls.SinglePrefix (SynTyparDecl([], $1), rhs parseState 1) } + + | LPAREN typarDeclList rparen + { SynTyparDecls.PrefixList (List.rev $2, rhs2 parseState 1 3) } typarDeclList: | typarDeclList COMMA typarDecl { $3 :: $1 } @@ -2166,101 +2303,111 @@ typarDeclList: typarDecl : | opt_attributes typar - { TyparDecl($1,$2) } + { SynTyparDecl($1, $2) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ postfixTyparDecls: | opt_HIGH_PRECEDENCE_TYAPP LESS typarDeclList opt_typeConstraints GREATER - { if not $2 then warning(Error(FSComp.SR.parsNonAdjacentTypars(),rhs2 parseState 2 5)) - List.rev $3, $4 } + { let m = rhs2 parseState 2 5 + if not $2 then warning(Error(FSComp.SR.parsNonAdjacentTypars(), m)) + SynTyparDecls.PostfixList (List.rev $3, $4, m) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ explicitValTyparDeclsCore: | typarDeclList COMMA DOT_DOT - { (List.rev $1,true) } + { (List.rev $1, true) } + | typarDeclList - { (List.rev $1,false) } - | - { ([],false) } + { (List.rev $1, false) } + + | /* EMPTY */ + { ([], false) } explicitValTyparDecls: | opt_HIGH_PRECEDENCE_TYAPP LESS explicitValTyparDeclsCore opt_typeConstraints GREATER - { if not $2 then warning(Error(FSComp.SR.parsNonAdjacentTypars(),rhs2 parseState 2 5)) - let tps,flex = $3 - SynValTyparDecls(tps,flex,$4) } + { let m = rhs2 parseState 2 5 + if not $2 then warning(Error(FSComp.SR.parsNonAdjacentTypars(), m)) + let tps, flex = $3 + let tps = SynTyparDecls.PostfixList (tps, $4, m) + SynValTyparDecls(Some tps, flex) } opt_explicitValTyparDecls: | explicitValTyparDecls { $1 } | - { SynValTyparDecls([],true,[]) } - -opt_explicitValTyparDecls2: - | explicitValTyparDecls - { Some $1 } - | - { None } + { SynValTyparDecls(None, true) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ opt_typeConstraints: - | + | /* EMPTY */ { [] } + | WHEN typeConstraints { List.rev $2 } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ typeConstraints: - | typeConstraints AND typeConstraint { $3 :: $1 } - | typeConstraint { [$1] } + | typeConstraints AND typeConstraint + { $3 :: $1 } + + | typeConstraint + { [$1] } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ typeConstraint: | DEFAULT typar COLON typ - { libraryOnlyError (lhs parseState); WhereTyparDefaultsToType($2,$4,lhs parseState) } + { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyError (lhs parseState) + SynTypeConstraint.WhereTyparDefaultsToType($2, $4, lhs parseState) } | typar COLON_GREATER typ - { WhereTyparSubtypeOfType($1,$3,lhs parseState) } + { SynTypeConstraint.WhereTyparSubtypeOfType($1, $3, lhs parseState) } | typar COLON STRUCT - { WhereTyparIsValueType($1,lhs parseState) } + { SynTypeConstraint.WhereTyparIsValueType($1, lhs parseState) } | typar COLON IDENT STRUCT - { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3)) - WhereTyparIsReferenceType($1,lhs parseState) } + { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3)) + SynTypeConstraint.WhereTyparIsReferenceType($1, lhs parseState) } | typar COLON NULL - { WhereTyparSupportsNull($1,lhs parseState) } + { SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) } | typar COLON LPAREN classMemberSpfn rparen - { let tp = $1 - WhereTyparSupportsMember([ SynType.Var(tp, tp.Range) ],$4,lhs parseState) } + { let tp = $1 + SynTypeConstraint.WhereTyparSupportsMember([ SynType.Var(tp, tp.Range) ], $4, lhs parseState) } | LPAREN typarAlts rparen COLON LPAREN classMemberSpfn rparen - { WhereTyparSupportsMember(List.rev($2),$6,lhs parseState) } + { SynTypeConstraint.WhereTyparSupportsMember(List.rev($2), $6, lhs parseState) } | typar COLON DELEGATE typeArgsNoHpaDeprecated - { let _ltm,_gtm,args,_commas,mWhole = $4 in WhereTyparIsDelegate($1, args, unionRanges $1.Range mWhole) } + { let _ltm, _gtm, args, _commas, mWhole = $4 + SynTypeConstraint.WhereTyparIsDelegate($1, args, unionRanges $1.Range mWhole) } | typar COLON IDENT typeArgsNoHpaDeprecated - { match $3 with - | "enum" -> let _ltm,_gtm,args,_commas,mWhole = $4 in WhereTyparIsEnum($1, args, unionRanges $1.Range mWhole) - | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } + { match $3 with + | "enum" -> + let _ltm, _gtm, args, _commas, mWhole = $4 + SynTypeConstraint.WhereTyparIsEnum($1, args, unionRanges $1.Range mWhole) + | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } | typar COLON IDENT - { match $3 with - | "comparison" -> WhereTyparIsComparable($1,lhs parseState) - | "equality" -> WhereTyparIsEquatable($1,lhs parseState) - | "unmanaged" -> WhereTyparIsUnmanaged($1,lhs parseState) - | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } + { match $3 with + | "comparison" -> SynTypeConstraint.WhereTyparIsComparable($1, lhs parseState) + | "equality" -> SynTypeConstraint.WhereTyparIsEquatable($1, lhs parseState) + | "unmanaged" -> SynTypeConstraint.WhereTyparIsUnmanaged($1, lhs parseState) + | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } typarAlts: - | typarAlts OR appType { $3 :: $1 } - | appType { [$1] } + | typarAlts OR appType + { $3 :: $1 } + + | appType + { [$1] } /* The core of a union type definition */ unionTypeRepr: @@ -2276,38 +2423,43 @@ unionTypeRepr: { [$1] } barAndgrabXmlDoc : - | BAR { grabXmlDoc(parseState,1) } + | BAR + { grabXmlDoc(parseState, 1) } attrUnionCaseDecls: - | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls { (fun xmlDoc -> $1 xmlDoc :: $3 $2) } - | attrUnionCaseDecl { (fun xmlDoc -> [ $1 xmlDoc ]) } + | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls + { (fun xmlDoc -> $1 xmlDoc :: $3 $2) } + + | attrUnionCaseDecl + { (fun xmlDoc -> [ $1 xmlDoc ]) } /* The core of a union case definition */ -attrUnionCaseDecl: - | opt_attributes opt_access unionCaseName opt_OBLOCKSEP - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) +attrUnionCaseDecl: + | opt_attributes opt_access unionCaseName + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) let mDecl = rhs parseState 3 - (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFields [],xmlDoc,None,mDecl))) - } - - | opt_attributes opt_access unionCaseName OF unionCaseRepr opt_OBLOCKSEP - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) - let mDecl = rhs2 parseState 3 5 - (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFields $5,xmlDoc,None,mDecl))) - } - - | opt_attributes opt_access unionCaseName COLON topType opt_OBLOCKSEP - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) - libraryOnlyWarning(lhs parseState) - let mDecl = rhs2 parseState 3 5 - (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFullType $5,xmlDoc,None,mDecl))) - } + (fun xmlDoc -> Choice2Of2 (SynUnionCase ( $1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl))) } + + | opt_attributes opt_access unionCaseName OF unionCaseRepr + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) + let mDecl = rhs2 parseState 1 5 + (fun xmlDoc -> Choice2Of2 (SynUnionCase ( $1, $3, SynUnionCaseKind.Fields $5, xmlDoc, None, mDecl))) } + + | opt_attributes opt_access unionCaseName OF recover + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) + let mDecl = rhs2 parseState 1 4 + (fun xmlDoc -> Choice2Of2 (SynUnionCase ( $1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl))) } + + | opt_attributes opt_access unionCaseName COLON topType + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) + if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) + let mDecl = rhs2 parseState 1 5 + (fun xmlDoc -> Choice2Of2 (SynUnionCase ( $1, $3, SynUnionCaseKind.FullType $5, xmlDoc, None, mDecl))) } - | opt_attributes opt_access unionCaseName EQUALS constant opt_OBLOCKSEP - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) - let mDecl = rhs2 parseState 3 5 - (fun xmlDoc -> Choice1Of2 (EnumCase ( $1, $3,$5,xmlDoc,mDecl))) - } + | opt_attributes opt_access unionCaseName EQUALS constant + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(), rhs parseState 2)) + let mDecl = rhs2 parseState 1 5 + (fun xmlDoc -> Choice1Of2 (SynEnumCase ( $1, $3, fst $5, snd $5, xmlDoc, mDecl))) } /* The name of a union case */ unionCaseName: @@ -2315,39 +2467,46 @@ unionCaseName: { $1 } | LPAREN COLON_COLON rparen - { ident(opNameCons,rhs parseState 2) } + { ident(opNameCons, rhs parseState 2) } | LPAREN LBRACK RBRACK rparen - { ident(opNameNil,rhs2 parseState 2 3) } + { ident(opNameNil, rhs2 parseState 2 3) } firstUnionCaseDeclOfMany: | ident opt_OBLOCKSEP - { Choice2Of2 (UnionCase ( [], $1,UnionCaseFields [],PreXmlDoc.Empty,None,rhs parseState 1)) } + { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields [], PreXmlDoc.Empty, None, rhs parseState 1)) } | ident EQUALS constant opt_OBLOCKSEP - { Choice1Of2 (EnumCase ([],$1,$3,PreXmlDoc.Empty,rhs2 parseState 1 3)) } + { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, PreXmlDoc.Empty, rhs2 parseState 1 3)) } | firstUnionCaseDecl opt_OBLOCKSEP { $1 } firstUnionCaseDecl: | ident OF unionCaseRepr - { Choice2Of2 (UnionCase ( [],$1,UnionCaseFields $3,PreXmlDoc.Empty,None,rhs2 parseState 1 3)) } + { Choice2Of2 (SynUnionCase ( [], $1, SynUnionCaseKind.Fields $3, PreXmlDoc.Empty, None, rhs2 parseState 1 3)) } | ident EQUALS constant opt_OBLOCKSEP - { Choice1Of2 (EnumCase ([],$1,$3,PreXmlDoc.Empty,rhs2 parseState 1 3)) } + { Choice1Of2 (SynEnumCase ([], $1, fst $3, snd $3, PreXmlDoc.Empty, rhs2 parseState 1 3)) } unionCaseReprElements: - | unionCaseReprElement STAR unionCaseReprElements { $1 :: $3 } - | unionCaseReprElement %prec prec_toptuptyptail_prefix { [$1] } + | unionCaseReprElement STAR unionCaseReprElements + { $1 :: $3 } + + | unionCaseReprElement %prec prec_toptuptyptail_prefix + { [$1] } unionCaseReprElement: - | ident COLON appType { mkNamedField($1, $3) } - | appType { mkAnonField $1 } + | ident COLON appType + { let wholeRange = rhs2 parseState 1 3 + mkSynNamedField($1, $3, wholeRange) } + + | appType + { mkSynAnonField $1 } unionCaseRepr: | braceFieldDeclList - { errorR(Deprecated(FSComp.SR.parsConsiderUsingSeparateRecordType(),lhs parseState)) + { errorR(Deprecated(FSComp.SR.parsConsiderUsingSeparateRecordType(), lhs parseState)) $1 } | unionCaseReprElements @@ -2363,49 +2522,51 @@ recdFieldDeclList: /* A field declaration in a record type */ recdFieldDecl: - | opt_attributes fieldDecl - { let fld = $2 $1 false - let (Field(a,b,c,d,e,f,vis,g)) = fld - if Option.isSome vis then errorR(Error(FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) - Field(a,b,c,d,e,f,None,g) } + | opt_attributes fieldDecl + { let wholeRange = rhs2 parseState 1 2 + let fld = $2 $1 false wholeRange + let (SynField (a, b, c, d, e, f, vis, wholeRange)) = fld + if Option.isSome vis then errorR (Error (FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations (), rhs parseState 2)) + SynField (a, b, c, d, e, f, None, wholeRange) } /* Part of a field or val declaration in a record type or object type */ fieldDecl: | opt_mutable opt_access ident COLON typ - { let mRhs = rhs2 parseState 3 5 - let xmlDoc = grabXmlDoc(parseState,3) - (fun attrs stat -> Field(attrs, stat,Some $3,$5,$1,xmlDoc,$2,mRhs)) } - + { let xmlDoc = grabXmlDoc (parseState, 3) + fun attrs stat wholeRange -> SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, wholeRange) } /* An exception definition */ exconDefn: | exconCore opt_classDefn - { SynExceptionDefn($1,$2, ($1.Range,$2) ||> unionRangeWithListBy (fun cd -> cd.Range) ) } + { SynExceptionDefn($1, $2, ($1.Range, $2) ||> unionRangeWithListBy (fun cd -> cd.Range) ) } /* Part of an exception definition */ exceptionAndGrabDoc: - | EXCEPTION { grabXmlDoc(parseState,1) } + | EXCEPTION + { grabXmlDoc(parseState, 1) } /* Part of an exception definition */ exconCore: | exceptionAndGrabDoc opt_attributes opt_access exconIntro exconRepr - { SynExceptionDefnRepr($2,$4,$5,$1,$3,(match $5 with None -> rhs2 parseState 1 4 | Some p -> unionRanges (rangeOfLongIdent p) (rhs2 parseState 1 4))) } + { SynExceptionDefnRepr($2, $4, $5, $1, $3, (match $5 with None -> rhs2 parseState 1 4 | Some p -> unionRanges (rangeOfLongIdent p) (rhs2 parseState 1 4))) } /* Part of an exception definition */ -exconIntro: - | ident - { UnionCase ( [], $1,UnionCaseFields [],PreXmlDoc.Empty,None,lhs parseState) } +exconIntro: + | ident + { SynUnionCase([], $1, SynUnionCaseKind.Fields [], PreXmlDoc.Empty, None, lhs parseState) } - | ident OF unionCaseRepr - { UnionCase ( [], $1,UnionCaseFields $3,PreXmlDoc.Empty,None,lhs parseState) } + | ident OF unionCaseRepr + { SynUnionCase([], $1, SynUnionCaseKind.Fields $3, PreXmlDoc.Empty, None, lhs parseState) } -exconRepr: - | { None } - | EQUALS path { Some ($2.Lid) } + | ident OF recover + { SynUnionCase([], $1, SynUnionCaseKind.Fields [], PreXmlDoc.Empty, None, lhs parseState) } -openDecl: - | OPEN path { $2 } +exconRepr: + | /* EMPTY */ + { None } + | EQUALS path + { Some ($2.Lid) } /*-------------------------------------------------------------------------*/ /* F# Definitions, Types, Patterns and Expressions */ @@ -2425,28 +2586,28 @@ defnBindings: | Some lastRange -> unionRanges mLetKwd lastRange // The first binding swallows any attributes prior to the 'let' - BindingSetPreAttrs(mLetKwd,isRec,isUse, + BindingSetPreAttrs(mLetKwd, isRec, isUse, (fun attrs vis -> // apply the builder let binds = localBindingsBuilder attrs vis mLetKwd if not isRec && not (isNilOrSingleton binds) then reportParseErrorAt mLetKwd (FSComp.SR.parsLetAndForNonRecBindings()) - [],binds), + [], binds), bindingSetRange) } | cPrototype { let bindRange = lhs parseState - BindingSetPreAttrs(bindRange, false,false,$1,bindRange) } + BindingSetPreAttrs(bindRange, false, false, $1, bindRange) } /* A 'do ...' statement in the non-#light syntax */ doBinding: - | DO typedSeqExprBlock + | DO typedSequentialExprBlock { let mDoKwd = rhs parseState 1 let mWhole = unionRanges mDoKwd $2.Range // any attributes prior to the 'let' are left free, e.g. become top-level attributes // associated with the module, 'main' function or assembly depending on their target - BindingSetPreAttrs(mDoKwd,false,false,(fun attrs vis -> attrs,[mkSynDoBinding (vis,true,$2,mWhole)]), mWhole) } + BindingSetPreAttrs(mDoKwd, false, false, (fun attrs vis -> attrs, [mkSynDoBinding (vis, true, $2, mWhole)]), mWhole) } /* A 'let ....' binding in the #light syntax */ @@ -2466,65 +2627,77 @@ hardwhiteLetBindings: | Some lastRange -> unionRanges mLetKwd lastRange // the first binding swallow any attributes prior to the 'let' - BindingSetPreAttrs(mLetKwd,isRec,isUse, + BindingSetPreAttrs(mLetKwd, isRec, isUse, (fun attrs vis -> let binds = localBindingsBuilder attrs vis mLetKwd if not isRec && not (isNilOrSingleton binds) then reportParseErrorAt mLetKwd (FSComp.SR.parsLetAndForNonRecBindings()) - [],binds), + [], binds), bindingSetRange), (unionRanges mLetKwd bindingSetRange) } /* A 'do ...' statement */ hardwhiteDoBinding: - | ODO typedSeqExprBlock hardwhiteDefnBindingsTerminator + | ODO typedSequentialExprBlock hardwhiteDefnBindingsTerminator { let mLetKwd = rhs parseState 1 let bindingSetRange = unionRanges mLetKwd $2.Range - let seqPt = NoSequencePointAtDoBinding + let seqPt = DebugPointAtBinding.NoneAtDo // any attributes prior to the 'let' are left free, e.g. become top-level attributes // associated with the module, 'main' function or assembly depending on their target - BindingSetPreAttrs(mLetKwd,false,false,(fun attrs vis -> attrs,[mkSynDoBinding (vis,true,$2,bindingSetRange)]),bindingSetRange), $2 } + BindingSetPreAttrs(mLetKwd, false, false, (fun attrs vis -> attrs, [mkSynDoBinding (vis, true, $2, bindingSetRange)]), bindingSetRange), $2 } /* The bindings in a class type definition */ classDefnBindings: - | defnBindings { $1 } - | doBinding { $1 } - | hardwhiteLetBindings { let b,m = $1 in b } - | hardwhiteDoBinding { fst $1 } + | defnBindings + { $1 } + + | doBinding + { $1 } + + | hardwhiteLetBindings + { let b, m = $1 in b } + + | hardwhiteDoBinding + { fst $1 } /* The terminator for a 'let ....' binding in the #light syntax */ hardwhiteDefnBindingsTerminator: | ODECLEND { (fun _ m -> ()) } + | recover - { (fun kwd m -> reportParseErrorAt m (match kwd with - | "let!" -> FSComp.SR.parsUnmatchedLetBang() - | "use!" -> FSComp.SR.parsUnmatchedUseBang() - | "use" -> FSComp.SR.parsUnmatchedUse() - | _ (*"let" *) -> FSComp.SR.parsUnmatchedLet())) } + { (fun kwd m -> + let msg = + match kwd with + | "let!" -> FSComp.SR.parsUnmatchedLetBang() + | "use!" -> FSComp.SR.parsUnmatchedUseBang() + | "use" -> FSComp.SR.parsUnmatchedUse() + | _ (*"let" *) -> FSComp.SR.parsUnmatchedLet() + reportParseErrorAt m msg) } /* An 'extern' DllImport function definition in C-style syntax */ cPrototype: | EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN cArgs rparen - { let rty,vis,nm,args = $2,$3,$4,$7 - let xmlDoc = grabXmlDoc(parseState,1) + { let rty, vis, nm, args = $2, $3, $4, $7 + let xmlDoc = grabXmlDoc(parseState, 1) let nmm = rhs parseState 3 let argsm = rhs parseState 6 let mBindLhs = lhs parseState let mWhole = lhs parseState let mRhs = lhs parseState let rhsExpr = SynExpr.App (ExprAtomicFlag.NonAtomic, - false, - SynExpr.Ident (ident("failwith",rhs parseState 6)), - SynExpr.Const (SynConst.String("extern was not given a DllImport attribute",rhs parseState 8),rhs parseState 8), + false, + SynExpr.Ident (ident("failwith", rhs parseState 6)), + SynExpr.Const (SynConst.String("extern was not given a DllImport attribute", SynStringKind.Regular, rhs parseState 8), rhs parseState 8), mRhs) - (fun attrs vis -> - let bindingId = SynPat.LongIdent (LongIdentWithDots([nm],[]), None, Some noInferredTypars, SynConstructorArgs.Pats [SynPat.Tuple(false,args,argsm)], vis, nmm) + (fun attrs _ -> + let bindingId = SynPat.LongIdent (LongIdentWithDots([nm], []), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm) + let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let binding = mkSynBinding (xmlDoc, bindingId) - (vis, false, false, mBindLhs, NoSequencePointAtInvisibleBinding, Some rty, rhsExpr, mRhs, [], attrs, None) + (vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None) [], [binding]) } /* A list of arguments in an 'extern' DllImport function definition */ @@ -2550,42 +2723,42 @@ cMoreArgs: /* A single argument in an 'extern' DllImport function definition */ cArg: | opt_attributes cType - { let m = lhs parseState in SynPat.Typed(SynPat.Wild m,$2,m) |> addAttribs $1 } + { let m = lhs parseState in SynPat.Typed(SynPat.Wild m, $2, m) |> addAttribs $1 } | opt_attributes cType ident - { let m = lhs parseState in SynPat.Typed(SynPat.Named (SynPat.Wild m,$3,false,None,m),$2,m) |> addAttribs $1 } + { let m = lhs parseState in SynPat.Typed(SynPat.Named ($3, false, None, m), $2, m) |> addAttribs $1 } /* An type in an 'extern' DllImport function definition */ cType: | path { let m = $1.Range - SynType.App(SynType.LongIdent($1),None,[],[],None,false,m) } + SynType.App(SynType.LongIdent($1), None, [], [], None, false, m) } | cType opt_HIGH_PRECEDENCE_APP LBRACK RBRACK { let m = lhs parseState - SynType.App(SynType.LongIdent(LongIdentWithDots([ident("[]",m)],[])),None,[$1],[],None,true,m) } + SynType.App(SynType.LongIdent(LongIdentWithDots([ident("[]", m)], [])), None, [$1], [], None, true, m) } | cType STAR { let m = lhs parseState - SynType.App(SynType.LongIdent(LongIdentWithDots([ident("nativeptr",m)],[])),None,[$1],[],None,true,m) } + SynType.App(SynType.LongIdent(LongIdentWithDots([ident("nativeptr", m)], [])), None, [$1], [], None, true, m) } | cType AMP { let m = lhs parseState - SynType.App(SynType.LongIdent(LongIdentWithDots([ident("byref",m)],[])),None,[$1],[],None,true,m) } + SynType.App(SynType.LongIdent(LongIdentWithDots([ident("byref", m)], [])), None, [$1], [], None, true, m) } | VOID STAR { let m = lhs parseState - SynType.App(SynType.LongIdent(LongIdentWithDots([ident("nativeint",m)],[])),None,[],[],None,true,m) } + SynType.App(SynType.LongIdent(LongIdentWithDots([ident("nativeint", m)], [])), None, [], [], None, true, m) } /* A return type in an 'extern' DllImport function definition */ cRetType: | opt_attributes cType - { SynReturnInfo(($2,SynArgInfo($1,false,None)),rhs parseState 2) } + { SynReturnInfo(($2, SynArgInfo($1, false, None)), rhs parseState 2) } | opt_attributes VOID { let m = rhs parseState 2 - SynReturnInfo((SynType.App(SynType.LongIdent(LongIdentWithDots([ident("unit",m)],[])),None,[],[],None,false,m),SynArgInfo($1,false,None)),m) } + SynReturnInfo((SynType.App(SynType.LongIdent(LongIdentWithDots([ident("unit", m)], [])), None, [], [], None, false, m), SynArgInfo($1, false, None)), m) } localBindings: @@ -2593,7 +2766,7 @@ localBindings: { let (moreBindings, moreBindingRanges) = List.unzip $2 let moreLocalBindingsLastRange = if moreBindingRanges.IsEmpty then None else Some (List.last moreBindingRanges) match $1 with - | Some (localBindingRange,attrLocalBindingBuilder) -> + | Some (localBindingRange, attrLocalBindingBuilder) -> let lastRange = match moreLocalBindingsLastRange with | None -> localBindingRange @@ -2607,7 +2780,7 @@ moreLocalBindings: | AND attr_localBinding moreLocalBindings { let mLetKwd = rhs parseState 1 (match $2 with - | Some (localBindingRange,attrLocalBindingBuilder) -> (attrLocalBindingBuilder [] None mLetKwd false,localBindingRange) :: $3 + | Some (localBindingRange, attrLocalBindingBuilder) -> (attrLocalBindingBuilder [] None mLetKwd false, localBindingRange) :: $3 | None -> $3) } | %prec prec_no_more_attr_bindings @@ -2618,9 +2791,9 @@ moreLocalBindings: attr_localBinding: | opt_attributes localBinding { let attrs2 = $1 - let localBindingRange,localBindingBuilder = $2 + let localBindingRange, localBindingBuilder = $2 let attrLocalBindingBuilder = (fun attrs vis mLetKwd _ -> localBindingBuilder (attrs@attrs2) vis mLetKwd) - Some(localBindingRange,attrLocalBindingBuilder) } + Some(localBindingRange, attrLocalBindingBuilder) } | error { None } @@ -2629,43 +2802,44 @@ attr_localBinding: /* A single binding in an expression or definition */ localBinding: | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS typedExprWithStaticOptimizationsBlock - { let (expr:SynExpr),opts = $6 + { let (expr:SynExpr), opts = $6 let eqm = rhs parseState 5 let mRhs = expr.Range let optReturnType = $4 let bindingBuilder, mBindLhs = $3 - let localBindingRange = unionRanges (rhs2 parseState 3 5) mRhs + let localBindingRange = unionRanges (rhs2 parseState 1 5) mRhs let localBindingBuilder = (fun attrs vis mLetKwd -> - let mWhole = unionRanges mLetKwd mRhs - let spBind = if IsControlFlowExpression expr then NoSequencePointAtLetBinding else SequencePointAtBinding(mWhole) - bindingBuilder (vis,$1,$2,mBindLhs,spBind,optReturnType,expr,mRhs,opts,attrs,None)) - localBindingRange,localBindingBuilder } + let mWhole = (unionRanges mLetKwd mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + let spBind = if IsControlFlowExpression expr then DebugPointAtBinding.NoneAtLet else DebugPointAtBinding.Yes mWhole + let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) + bindingBuilder (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None)) + localBindingRange, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error - { let mWhole = rhs2 parseState 3 5 + { let mWhole = rhs2 parseState 1 5 let mRhs = rhs parseState 5 let optReturnType = $4 - let bindingBuilder,mBindLhs = $3 + let bindingBuilder, mBindLhs = $3 let localBindingBuilder = (fun attrs vis mLetKwd -> - let spBind = SequencePointAtBinding(unionRanges mLetKwd mRhs) + let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) let eqm = rhs parseState 5 let zeroWidthAtEnd = eqm.EndRange - bindingBuilder (vis,$1,$2,mBindLhs,spBind,optReturnType,arbExpr("localBinding1",zeroWidthAtEnd),mRhs,[],attrs,None)) - mWhole,localBindingBuilder } + bindingBuilder (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding1", zeroWidthAtEnd), mRhs, [], attrs, None)) + mWhole, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints recover { if not $5 then reportParseErrorAt (rhs parseState 5) (FSComp.SR.parsUnexpectedEndOfFileDefinition()) let optReturnType = $4 - let mWhole = match optReturnType with None -> rhs parseState 3 | Some _ -> rhs2 parseState 3 4 + let mWhole = rhs2 parseState 1 (match optReturnType with None -> 3 | _ -> 4) let mRhs = mWhole.EndRange // zero-width range at end of last good token - let bindingBuilder,mBindLhs = $3 + let bindingBuilder, mBindLhs = $3 let localBindingBuilder = (fun attrs vis mLetKwd -> - let spBind = SequencePointAtBinding(unionRanges mLetKwd mRhs) - bindingBuilder (vis,$1,$2,mBindLhs,spBind,optReturnType,arbExpr("localBinding2",mRhs),mRhs,[],attrs,None)) - mWhole,localBindingBuilder } + let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs) + bindingBuilder (vis, $1, $2, mBindLhs, spBind, optReturnType, arbExpr("localBinding2", mRhs), mRhs, [], attrs, None)) + mWhole, localBindingBuilder } /* A single expression with an optional type annotation, and an optional static optimization block */ @@ -2675,52 +2849,103 @@ typedExprWithStaticOptimizationsBlock: | OBLOCKBEGIN typedExprWithStaticOptimizations recover { if not $3 then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEndOfFile()) - let a,b = $2 + let a, b = $2 (exprFromParseError a, b) } | typedExprWithStaticOptimizations { $1 } typedExprWithStaticOptimizations : - | typedSeqExpr opt_staticOptimizations { $1, List.rev $2 } + | typedSequentialExpr opt_staticOptimizations + { $1, List.rev $2 } opt_staticOptimizations: - | opt_staticOptimizations staticOptimization { $2 :: $1 } - | { [] } + | opt_staticOptimizations staticOptimization + { $2 :: $1 } + + | /* EMPTY */ + { [] } staticOptimization: - | WHEN staticOptimizationConditions EQUALS typedSeqExprBlock { ($2,$4) } + | WHEN staticOptimizationConditions EQUALS typedSequentialExprBlock + { ($2, $4) } staticOptimizationConditions: - | staticOptimizationConditions AND staticOptimizationCondition { $3 :: $1 } - | staticOptimizationCondition { [$1 ] } + | staticOptimizationConditions AND staticOptimizationCondition + { $3 :: $1 } + + | staticOptimizationCondition + { [$1 ] } staticOptimizationCondition: - | typar COLON typ { WhenTyparTyconEqualsTycon($1,$3,lhs parseState) } - | typar STRUCT { WhenTyparIsStruct($1,lhs parseState) } + | typar COLON typ + { SynStaticOptimizationConstraint.WhenTyparTyconEqualsTycon($1, $3, lhs parseState) } + + | typar STRUCT + { SynStaticOptimizationConstraint.WhenTyparIsStruct($1, lhs parseState) } rawConstant: - | INT8 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideEightBitSigned(), lhs parseState)) - SynConst.SByte (fst $1) } - | UINT8 { SynConst.Byte $1 } - | INT16 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideSixteenBitSigned(), lhs parseState)) - SynConst.Int16 (fst $1) } - | UINT16 { SynConst.UInt16 $1 } - | INT32 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) - SynConst.Int32 (fst $1) } - | UINT32 { SynConst.UInt32 $1 } - | INT64 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideSixtyFourBitSigned(), lhs parseState)) - SynConst.Int64 (fst $1) } - | UINT64 { SynConst.UInt64 $1 } - | NATIVEINT { SynConst.IntPtr $1 } - | UNATIVEINT { SynConst.UIntPtr $1 } - | IEEE32 { SynConst.Single $1 } - | IEEE64 { SynConst.Double $1 } - | CHAR { SynConst.Char $1 } - | DECIMAL { SynConst.Decimal $1 } - | BIGNUM { SynConst.UserNum $1 } - | stringOrKeywordString { SynConst.String ($1,lhs parseState) } - | BYTEARRAY { SynConst.Bytes ($1,lhs parseState) } + | INT8 + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideEightBitSigned(), lhs parseState)) + SynConst.SByte (fst $1) } + + | UINT8 + { SynConst.Byte $1 } + + | INT16 + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideSixteenBitSigned(), lhs parseState)) + SynConst.Int16 (fst $1) } + + | UINT16 + { SynConst.UInt16 $1 } + + | INT32 + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) + SynConst.Int32 (fst $1) } + + | UINT32 + { SynConst.UInt32 $1 } + + | INT64 + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideSixtyFourBitSigned(), lhs parseState)) + SynConst.Int64 (fst $1) } + + | UINT64 + { SynConst.UInt64 $1 } + + | NATIVEINT + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideNativeSigned(), lhs parseState)) + SynConst.IntPtr (fst $1) } + + | UNATIVEINT + { SynConst.UIntPtr $1 } + + | IEEE32 + { SynConst.Single $1 } + + | IEEE64 + { SynConst.Double $1 } + + | CHAR + { SynConst.Char $1 } + + | DECIMAL + { SynConst.Decimal $1 } + + | BIGNUM + { SynConst.UserNum $1 } + + | string + { let s, synStringKind = $1 + SynConst.String (s, synStringKind, lhs parseState) } + + | sourceIdentifier + { let c,v = $1 + SynConst.SourceIdentifier (c, v, lhs parseState) } + + | BYTEARRAY + { let (v, synByteStringKind, _) = $1 + SynConst.Bytes (v, synByteStringKind, lhs parseState) } rationalConstant: | INT32 INFIX_STAR_DIV_MOD_OP INT32 @@ -2735,11 +2960,13 @@ rationalConstant: if (snd $2) || (snd $4) then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) SynRationalConst.Negate(SynRationalConst.Rational(fst $2, fst $4, lhs parseState)) } - | INT32 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) - SynRationalConst.Integer(fst $1) } + | INT32 + { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) + SynRationalConst.Integer(fst $1) } - | MINUS INT32 { if snd $2 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) - SynRationalConst.Negate(SynRationalConst.Integer(fst $2)) } + | MINUS INT32 + { if snd $2 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) + SynRationalConst.Negate(SynRationalConst.Integer(fst $2)) } atomicUnsignedRationalConstant: | INT32 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState)) @@ -2755,13 +2982,21 @@ atomicRationalConstant: { SynRationalConst.Negate($2) } constant: - | rawConstant { $1 } - | rawConstant HIGH_PRECEDENCE_TYAPP measureTypeArg { SynConst.Measure($1, $3) } + | rawConstant + { $1, rhs parseState 1 } + + | rawConstant HIGH_PRECEDENCE_TYAPP measureTypeArg + { SynConst.Measure($1, rhs parseState 1, $3), lhs parseState } bindingPattern: - | headBindingPattern - { let xmlDoc = grabXmlDoc(parseState,1) - mkSynBinding (xmlDoc,$1), rhs parseState 1 } + | headBindingPattern + + { // Adds a grab point at the start of the binding, so as not to include XML doc comments on the arguments + let xmlDoc = LexbufLocalXmlDocStore.GrabXmlDocBeforeMarker(parseState.LexBuffer, (lhs parseState).StartRange) + // Adds grab point at the end of the binding head, so subsequent types don't erroneously include argument doc comemnts + grabXmlDoc(parseState, 1) |> ignore + + mkSynBinding (xmlDoc, $1), rhs parseState 1 } // Subset of patterns allowed to be used in implicit ctors. // For a better error recovery we could replace these rules with the actual SynPat parsing @@ -2769,17 +3004,21 @@ bindingPattern: simplePattern: | ident { let m = rhs parseState 1 - SynPat.Named(SynPat.Wild m, $1, false, None, m) } + SynPat.Named($1, false, None, m) } + | QMARK ident { SynPat.OptionalVal($2, rhs parseState 2) } + | simplePattern COLON typeWithTypeConstraints { SynPat.Typed($1, $3, lhs parseState) } + | attributes simplePattern %prec paren_pat_attribs { SynPat.Attrib($2, $1, lhs parseState) } simplePatternCommaList: | simplePattern { $1 } + | simplePattern COMMA simplePatternCommaList { match $3 with | SynPat.Tuple(_, pats, _) -> SynPat.Tuple(false, $1 :: pats, rhs2 parseState 1 3) @@ -2790,19 +3029,23 @@ simplePatterns: { let parenPat = SynPat.Paren($2, rhs2 parseState 1 3) let simplePats, _ = SimplePatsOfPat parseState.SynArgNameGenerator parenPat simplePats } + | LPAREN rparen { let pat = SynPat.Const(SynConst.Unit, rhs2 parseState 1 2) let simplePats, _ = SimplePatsOfPat parseState.SynArgNameGenerator pat simplePats } + | LPAREN simplePatternCommaList recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) let parenPat = SynPat.Paren(SynPat.Tuple(false, [], rhs2 parseState 1 2), rhs2 parseState 1 2) // todo: report parsed pats anyway? let simplePats, _ = SimplePatsOfPat parseState.SynArgNameGenerator parenPat simplePats } + | LPAREN error rparen { let parenPat = SynPat.Paren(SynPat.Wild(rhs parseState 2), rhs2 parseState 1 3) // silent recovery let simplePats, _ = SimplePatsOfPat parseState.SynArgNameGenerator parenPat simplePats } + | LPAREN recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) let pat = SynPat.Wild(lhs parseState) @@ -2811,342 +3054,464 @@ simplePatterns: headBindingPattern: - | headBindingPattern AS ident - { SynPat.Named ($1,$3,false,None,rhs2 parseState 1 3) } + | headBindingPattern AS constrPattern + { SynPat.As($1, $3, rhs2 parseState 1 3) } + | headBindingPattern BAR headBindingPattern - { SynPat.Or($1,$3,rhs2 parseState 1 3) } + { SynPat.Or($1, $3, rhs2 parseState 1 3) } + | headBindingPattern COLON_COLON headBindingPattern - { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [SynPat.Tuple (false,[$1;$3],rhs2 parseState 1 3)],None,lhs parseState) } + { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons, []), None, None, SynArgPats.Pats [SynPat.Tuple (false, [$1;$3], rhs2 parseState 1 3)], None, lhs parseState) } + | tuplePatternElements %prec pat_tuple - { SynPat.Tuple(false,List.rev $1, lhs parseState) } + { SynPat.Tuple(false, List.rev $1, lhs parseState) } + | conjPatternElements %prec pat_conj { SynPat.Ands(List.rev $1, lhs parseState) } + | constrPattern { $1 } tuplePatternElements: | tuplePatternElements COMMA headBindingPattern { $3 :: $1 } + | headBindingPattern COMMA headBindingPattern { $3 :: $1 :: [] } conjPatternElements: | conjPatternElements AMP headBindingPattern - { $3 :: $1 } + { $3 :: $1 } + | headBindingPattern AMP headBindingPattern - { $3 :: $1 :: [] } + { $3 :: $1 :: [] } namePatPairs: - | namePatPair opt_seps { [$1], lhs parseState } - | namePatPair seps namePatPairs { let (rs, _) = $3 in ($1 :: rs), lhs parseState } + | namePatPair opt_seps + { [$1], lhs parseState } + + | namePatPair seps namePatPairs + { let (rs, _) = $3 in ($1 :: rs), lhs parseState } namePatPair: - | ident EQUALS parenPattern { ($1, $3) } + | ident EQUALS parenPattern + { ($1, $3) } constrPattern: - | atomicPatternLongIdent explicitValTyparDecls - { let vis,lid = $1 in SynPat.LongIdent (lid,None,Some $2, SynConstructorArgs.Pats [],vis,lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 atomicPatsOrNamePatPairs %prec pat_app - { let vis,lid = $1 in SynPat.LongIdent (lid,None,$2, $3,vis,lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs - { let vis,lid = $1 in SynPat.LongIdent (lid,None,$2, $4,vis,lhs parseState) } - | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs - { let vis,lid = $1 in SynPat.LongIdent (lid,None,$2, $4,vis,lhs parseState) } + | atomicPatternLongIdent explicitValTyparDecls + { let vis, lid = $1 + SynPat.LongIdent (lid, None, Some $2, SynArgPats.Pats [], vis, lhs parseState) } + + | atomicPatternLongIdent explicitValTyparDecls atomicPatsOrNamePatPairs %prec pat_app + { let vis, lid = $1 + let args, argsM = $3 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } + + | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 + let args, argsM = $4 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } + + | atomicPatternLongIdent explicitValTyparDecls HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 + let args, argsM = $4 + let m = unionRanges (rhs2 parseState 1 2) argsM + SynPat.LongIdent (lid, None, Some $2, args, vis, m) } + + | atomicPatternLongIdent atomicPatsOrNamePatPairs %prec pat_app + { let vis, lid = $1 + let args, argsM = $2 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } + + | atomicPatternLongIdent HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 + let args, argsM = $3 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } + + | atomicPatternLongIdent HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs + { let vis, lid = $1 + let args, argsM = $3 + let m = unionRanges (rhs parseState 1) argsM + SynPat.LongIdent (lid, None, None, args, vis, m) } + | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst - { SynPat.IsInst($2,lhs parseState) } + { SynPat.IsInst($2, lhs parseState) } + | atomicPattern { $1 } atomicPatsOrNamePatPairs: - | LPAREN namePatPairs rparen { SynConstructorArgs.NamePatPairs $2 } - | atomicPatterns { SynConstructorArgs.Pats $1 } + | LPAREN namePatPairs rparen + { SynArgPats.NamePatPairs $2, snd $2 } + + | atomicPatterns + { let mParsed = rhs parseState 1 + let mAll = (mParsed.StartRange, $1) ||> unionRangeWithListBy (fun p -> p.Range) + SynArgPats.Pats $1, mAll } atomicPatterns: | atomicPattern atomicPatterns %prec pat_args { $1 :: $2 } + | atomicPattern HIGH_PRECEDENCE_BRACK_APP atomicPatterns { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsSuccessivePatternsShouldBeSpacedOrTupled()) $1 :: $3 } + | atomicPattern HIGH_PRECEDENCE_PAREN_APP atomicPatterns { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsSuccessivePatternsShouldBeSpacedOrTupled()) $1 :: $3 } - | atomicPattern { [$1] } + + | atomicPattern + { [$1] } atomicPattern: | quoteExpr - { SynPat.QuoteExpr($1,lhs parseState) } - | CHAR DOT_DOT CHAR { SynPat.DeprecatedCharRange ($1,$3,rhs2 parseState 1 3) } + { SynPat.QuoteExpr($1, lhs parseState) } + + | CHAR DOT_DOT CHAR + { SynPat.DeprecatedCharRange ($1, $3, rhs2 parseState 1 3) } + | LBRACE recordPatternElementsAux rbrace { let rs, m = $2 in SynPat.Record (rs, rhs2 parseState 1 3) } + | LBRACK listPatternElements RBRACK - { SynPat.ArrayOrList(false,$2,lhs parseState) } + { SynPat.ArrayOrList(false, $2, lhs parseState) } + | LBRACK_BAR listPatternElements BAR_RBRACK - { SynPat.ArrayOrList(true,$2, lhs parseState) } + { SynPat.ArrayOrList(true, $2, lhs parseState) } + | UNDERSCORE { SynPat.Wild (lhs parseState) } + | QMARK ident - { SynPat.OptionalVal($2,lhs parseState) } + { SynPat.OptionalVal($2, lhs parseState) } + | atomicPatternLongIdent %prec prec_atompat_pathop - { let vis,lidwd = $1 - if not (isNilOrSingleton lidwd.Lid) || (let c = (List.head lidwd.Lid).idText.[0] in Char.IsUpper(c) && not (Char.IsLower c)) + { let vis, lidwd = $1 + if not (isNilOrSingleton lidwd.Lid) || String.isLeadingIdentifierCharacterUpperCase (List.head lidwd.Lid).idText then mkSynPatMaybeVar lidwd vis (lhs parseState) else mkSynPatVar vis (List.head lidwd.Lid) } + | constant - { SynPat.Const ($1,$1.Range (lhs parseState)) } + { SynPat.Const (fst $1, snd $1) } + | FALSE - { SynPat.Const(SynConst.Bool false,lhs parseState) } + { SynPat.Const(SynConst.Bool false, lhs parseState) } + | TRUE - { SynPat.Const(SynConst.Bool true,lhs parseState) } + { SynPat.Const(SynConst.Bool true, lhs parseState) } + | NULL { SynPat.Null(lhs parseState) } - | LPAREN parenPatternBody rparen - { let m = (lhs parseState) - SynPat.Paren($2 m,m) } - | LPAREN parenPatternBody recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) - patFromParseError ($2 (rhs2 parseState 1 2)) } - | LPAREN error rparen - { (* silent recovery *) SynPat.Wild (lhs parseState) } - | LPAREN recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) - SynPat.Wild (lhs parseState)} + + | LPAREN parenPatternBody rparen + { let m = lhs parseState + SynPat.Paren($2 m, m) } + + | LPAREN parenPatternBody recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) + let m = rhs2 parseState 1 2 + let parenPat = SynPat.Paren($2 m, m) + patFromParseError parenPat } + + | LPAREN error rparen + { let innerPat = patFromParseError (SynPat.Wild (rhs parseState 2)) + SynPat.Paren(innerPat, lhs parseState) } + + | LPAREN recover + { let parenM = rhs parseState 1 + reportParseErrorAt parenM (FSComp.SR.parsUnmatchedParen()) + let innerPat = patFromParseError (SynPat.Wild parenM.EndRange) + let parenPat = SynPat.Paren(innerPat, parenM) + patFromParseError parenPat } + | STRUCT LPAREN tupleParenPatternElements rparen - { SynPat.Tuple(true, List.rev $3,lhs parseState) } + { SynPat.Tuple(true, List.rev $3, lhs parseState) } + | STRUCT LPAREN tupleParenPatternElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()); - SynPat.Tuple(true, List.rev $3,lhs parseState) } + SynPat.Tuple(true, List.rev $3, lhs parseState) } + | STRUCT LPAREN error rparen { (* silent recovery *) SynPat.Wild (lhs parseState) } + | STRUCT LPAREN recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()); SynPat.Wild (lhs parseState)} - - parenPatternBody: | parenPattern { (fun m -> $1) } - | - { (fun m -> SynPat.Const(SynConst.Unit,m)) } + + | /* EMPTY */ + { (fun m -> SynPat.Const(SynConst.Unit, m)) } /* This duplicates out 'patterns' in order to give type annotations */ /* the desired precedence w.r.t. patterns, tuple patterns in particular. */ /* Duplication requried to minimize the disturbance to the grammar, */ /* in particular the expected property that "pat" parses the same as */ /* "(pat)"! Here are some examples: */ -/* a,b parses as (a,b) */ -/* (a,b) also parses as (a,b) */ -/* (a,b : t) parses as (a, (b:t)) */ -/* a,b as t parses as ((a,b) as t) */ -/* (a,b as t) also parses as ((a,b) as t) */ -/* a,b | c,d parses as ((a,b) | (c,d)) */ -/* (a,b | c,d) also parses as ((a,b) | (c,d)) */ -/* (a : t,b) parses as ((a:t),b) */ -/* (a : t1,b : t2) parses as ((a:t),(b:t2)) */ -/* (a,b as nm : t) parses as (((a,b) as nm) : t) */ -/* (a,b :: c : t) parses as (((a,b) :: c) : t) */ +/* a, b parses as (a, b) */ +/* (a, b) also parses as (a, b) */ +/* (a, b : t) parses as (a, (b:t)) */ +/* a, b as t parses as ((a, b) as t) */ +/* (a, b as t) also parses as ((a, b) as t) */ +/* a, b | c, d parses as ((a, b) | (c, d)) */ +/* (a, b | c, d) also parses as ((a, b) | (c, d)) */ +/* (a : t, b) parses as ((a:t), b) */ +/* (a : t1, b : t2) parses as ((a:t), (b:t2)) */ +/* (a, b as nm : t) parses as (((a, b) as nm) : t) */ +/* (a, b :: c : t) parses as (((a, b) :: c) : t) */ /* */ /* Probably the most unexpected thing here is that 'as nm' binds the */ /* whole pattern to the left, whereas ': t' binds only the pattern */ /* immediately preceding in the tuple. */ /* */ -/* Also, it is unexpected that '(a,b : t)' in a pattern binds differently to */ -/* '(a,b : t)' in an expression. It's not that easy to solve that without */ +/* Also, it is unexpected that '(a, b : t)' in a pattern (a, (b : 't)) binds differently to */ +/* '(a, b : t)' in an expression ((a, b) : 't). It's not that easy to solve that without */ /* duplicating the entire expression grammar, or making a fairly severe breaking change */ /* to the language. */ parenPattern: - | parenPattern AS ident - { SynPat.Named ($1,$3,false,None,rhs2 parseState 1 3) } + | parenPattern AS constrPattern + { SynPat.As($1, $3, rhs2 parseState 1 3) } + | parenPattern BAR parenPattern - { SynPat.Or($1,$3,rhs2 parseState 1 3) } + { SynPat.Or($1, $3, rhs2 parseState 1 3) } + | tupleParenPatternElements - { SynPat.Tuple(false,List.rev $1,lhs parseState) } + { SynPat.Tuple(false, List.rev $1, lhs parseState) } + | conjParenPatternElements - { SynPat.Ands(List.rev $1,rhs2 parseState 1 3) } + { SynPat.Ands(List.rev $1, rhs2 parseState 1 3) } + | parenPattern COLON typeWithTypeConstraints %prec paren_pat_colon { let lhsm = lhs parseState - SynPat.Typed($1,$3,lhsm) } + SynPat.Typed($1, $3, lhsm) } + | attributes parenPattern %prec paren_pat_attribs { let lhsm = lhs parseState - SynPat.Attrib($2,$1,lhsm) } + SynPat.Attrib($2, $1, lhsm) } + | parenPattern COLON_COLON parenPattern - { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [ SynPat.Tuple (false,[$1;$3],rhs2 parseState 1 3) ],None,lhs parseState) } + { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons, []), None, None, SynArgPats.Pats [ SynPat.Tuple (false, [$1;$3], rhs2 parseState 1 3) ], None, lhs parseState) } + | constrPattern { $1 } tupleParenPatternElements: | tupleParenPatternElements COMMA parenPattern { $3 :: $1 } + | parenPattern COMMA parenPattern { $3 :: $1 :: [] } conjParenPatternElements: | conjParenPatternElements AMP parenPattern { $3 :: $1 } + | parenPattern AMP parenPattern { $3 :: $1 :: [] } recordPatternElementsAux: /* Fix 1190 */ | recordPatternElement opt_seps - { [$1],lhs parseState } + { [$1], lhs parseState } + | recordPatternElement seps recordPatternElementsAux - { let r = $1 in let (rs,dropMark) = $3 in (r :: rs),lhs parseState } + { let r = $1 in let (rs, dropMark) = $3 in (r :: rs), lhs parseState } recordPatternElement: - | path EQUALS parenPattern { (List.frontAndBack $1.Lid,$3) } + | path EQUALS parenPattern { (List.frontAndBack $1.Lid, $3) } -listPatternElements: /* Fix 3569 */ - | +listPatternElements: + | /* EMPTY */ { [] } + | parenPattern opt_seps { [$1] } + | parenPattern seps listPatternElements { $1 :: $3 } /* The lexfilter likes to insert OBLOCKBEGIN/OBLOCKEND pairs */ -typedSeqExprBlock: - | OBLOCKBEGIN typedSeqExpr oblockend +typedSequentialExprBlock: + | OBLOCKBEGIN typedSequentialExpr oblockend { $2 } - | OBLOCKBEGIN typedSeqExpr recover + + | OBLOCKBEGIN typedSequentialExpr recover { if not $3 then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEndOfFileExpression()) exprFromParseError $2 } - | typedSeqExpr + + | typedSequentialExpr { $1 } /* The lexfilter likes to insert OBLOCKBEGIN/OBLOCKEND pairs */ declExprBlock: - | OBLOCKBEGIN typedSeqExpr oblockend + | OBLOCKBEGIN typedSequentialExpr oblockend { $2 } + | declExpr { $1 } /* For some constructs the lex filter can't be sure to insert a matching OBLOCKEND, e.g. "function a -> b | c -> d" all in one line */ /* for these it only inserts a trailing ORIGHT_BLOCK_END */ -typedSeqExprBlockR: - | typedSeqExpr ORIGHT_BLOCK_END { $1 } - | typedSeqExpr { $1 } +typedSequentialExprBlockR: + | typedSequentialExpr ORIGHT_BLOCK_END + { $1 } + + | typedSequentialExpr + { $1 } + +typedSequentialExpr: + | sequentialExpr COLON typeWithTypeConstraints + { SynExpr.Typed ($1, $3, unionRanges $1.Range $3.Range) } -typedSeqExpr: - | seqExpr COLON typeWithTypeConstraints { SynExpr.Typed ($1,$3, unionRanges $1.Range $3.Range) } - | seqExpr { $1 } + | sequentialExpr + { $1 } + +typedSequentialExprEOF: + | typedSequentialExpr EOF + { checkEndOfFileError $2; $1 } -typedSeqExprEOF: - | typedSeqExpr EOF { checkEndOfFileError $2; $1 } +sequentialExpr: + | declExpr seps sequentialExpr + { SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, true, $1, $3, unionRanges $1.Range $3.Range) } -seqExpr: - | declExpr seps seqExpr - { SynExpr.Sequential (SequencePointsAtSeq,true,$1,$3,unionRanges $1.Range $3.Range) } | declExpr seps { $1 } + | declExpr %prec SEMICOLON { $1 } - | declExpr THEN seqExpr %prec prec_then_before - { SynExpr.Sequential (SequencePointsAtSeq,false,$1,$3,unionRanges $1.Range $3.Range ) } - | declExpr OTHEN OBLOCKBEGIN typedSeqExpr oblockend %prec prec_then_before - { SynExpr.Sequential (SequencePointsAtSeq,false,$1,$4,unionRanges $1.Range $4.Range) } + + | declExpr THEN sequentialExpr %prec prec_then_before + { SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, false, $1, $3, unionRanges $1.Range $3.Range ) } + + | declExpr OTHEN OBLOCKBEGIN typedSequentialExpr oblockend %prec prec_then_before + { SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, false, $1, $4, unionRanges $1.Range $4.Range) } + | hardwhiteLetBindings %prec prec_args_error - { let hwlb,m = $1 - let mLetKwd,isUse = match hwlb with (BindingSetPreAttrs(m,_,isUse,_,_)) -> m,isUse + { let hwlb, m = $1 + let mLetKwd, isUse = match hwlb with (BindingSetPreAttrs(m, _, isUse, _, _)) -> m, isUse let usedKeyword = if isUse then "use" else "let" - reportParseErrorAt mLetKwd (FSComp.SR.parsExpectedExpressionAfterLet(usedKeyword,usedKeyword)) + reportParseErrorAt mLetKwd (FSComp.SR.parsExpectedExpressionAfterLet(usedKeyword, usedKeyword)) let fauxRange = m.EndRange // zero width range at end of m - mkLocalBindings (m,hwlb,arbExpr("seqExpr",fauxRange)) } + mkLocalBindings (m, hwlb, arbExpr("seqExpr", fauxRange)) } /* Use this as the last terminal when performing error recovery */ /* The contract for using this is that (a) if EOF occurs then the */ /* the using production must report an error and (b) the using production */ /* can report an error anyway if it is helpful, e.g. "unclosed '('" (giving two errors) */ recover: - | error { debugPrint("recovering via error"); true } - | EOF { debugPrint("recovering via EOF"); false } + | error + { debugPrint("recovering via error"); true } + + | EOF + { debugPrint("recovering via EOF"); false } +moreBinders: + | AND_BANG headBindingPattern EQUALS typedSequentialExprBlock IN moreBinders %prec expr_let + { let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) (* TODO Pretty sure this is wrong *) + let m = rhs parseState 1 (* TODO Pretty sure this is wrong *) + (spBind, $1, true, $2, $4, m) :: $6 } + + | OAND_BANG headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders %prec expr_let + { $5 "and!" (rhs parseState 1) // report unterminated error + let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) (* TODO Pretty sure this is wrong *) + let m = rhs parseState 1 (* TODO Pretty sure this is wrong *) + (spBind, $1, true, $2, $4, m) :: $7 } + + | %prec prec_no_more_attr_bindings + { [] } declExpr: - | defnBindings IN typedSeqExpr %prec expr_let - { mkLocalBindings (unionRanges (rhs2 parseState 1 2) $3.Range,$1,$3) } + | defnBindings IN typedSequentialExpr %prec expr_let + { mkLocalBindings (unionRanges (rhs2 parseState 1 2) $3.Range, $1, $3) } | defnBindings IN error %prec expr_let - { mkLocalBindings (rhs2 parseState 1 2,$1,arbExpr("declExpr1",(rhs parseState 3))) } + { mkLocalBindings (rhs2 parseState 1 2, $1, arbExpr("declExpr1", (rhs parseState 3))) } /* FSComp.SR.parsNoMatchingInForLet() -- leave this in for now - it's an unused error string */ - | hardwhiteLetBindings typedSeqExprBlock %prec expr_let - { let hwlb,m = $1 - mkLocalBindings (unionRanges m $2.Range,hwlb,$2) } + | hardwhiteLetBindings typedSequentialExprBlock %prec expr_let + { let hwlb, m = $1 + mkLocalBindings (unionRanges m $2.Range, hwlb, $2) } | hardwhiteLetBindings error %prec expr_let - { let hwlb,m = $1 - reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m,_,_,_,_)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) - mkLocalBindings (m,hwlb,arbExpr("declExpr2",(rhs parseState 2))) } + { let hwlb, m = $1 + reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) + mkLocalBindings (m, hwlb, arbExpr("declExpr2", (rhs parseState 2))) } - | hardwhiteLetBindings OBLOCKSEP typedSeqExprBlock %prec expr_let - { let hwlb,m = $1 + | hardwhiteLetBindings OBLOCKSEP typedSequentialExprBlock %prec expr_let + { let hwlb, m = $1 mkLocalBindings (unionRanges m $3.Range, hwlb, $3) } | hardwhiteLetBindings OBLOCKSEP error %prec expr_let - { let hwlb,m = $1 - //reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m,_,_,_,_)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) - mkLocalBindings (unionRanges m (rhs parseState 3),hwlb,arbExpr("declExpr3",(rhs parseState 3))) } + { let hwlb, m = $1 + //reportParseErrorAt (match hwlb with (BindingSetPreAttrs(m, _, _, _, _)) -> m) (FSComp.SR.parsErrorInReturnForLetIncorrectIndentation()) + mkLocalBindings (unionRanges m (rhs parseState 3), hwlb, arbExpr("declExpr3", (rhs parseState 3))) } - | hardwhiteDoBinding %prec expr_let + | hardwhiteDoBinding %prec expr_let { let e = snd $1 - SynExpr.Do (e,e.Range) } - + SynExpr.Do (e, unionRanges (rhs parseState 1).StartRange e.Range) } + | anonMatchingExpr %prec expr_function { $1 } | anonLambdaExpr %prec expr_fun { $1 } - | MATCH typedSeqExpr withClauses %prec expr_match + | MATCH typedSequentialExpr withClauses %prec expr_match { let mMatch = (rhs parseState 1) - let mWith,(clauses,mLast) = $3 - let spBind = SequencePointAtBinding(unionRanges mMatch mWith) - SynExpr.Match (spBind, $2,clauses,unionRanges mMatch mLast) } + let mWith, (clauses, mLast) = $3 + let spBind = DebugPointAtBinding.Yes(unionRanges mMatch mWith) + SynExpr.Match (spBind, $2, clauses, unionRanges mMatch mLast) } - | MATCH typedSeqExpr recover %prec expr_match + | MATCH typedSequentialExpr recover %prec expr_match { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileMatch()) // Produce approximate expression during error recovery exprFromParseError $2 } - | MATCH_BANG typedSeqExpr withClauses %prec expr_match + | MATCH_BANG typedSequentialExpr withClauses %prec expr_match { let mMatch = (rhs parseState 1) - let mWith,(clauses,mLast) = $3 - let spBind = SequencePointAtBinding(unionRanges mMatch mWith) - SynExpr.MatchBang (spBind, $2,clauses,unionRanges mMatch mLast) } + let mWith, (clauses, mLast) = $3 + let spBind = DebugPointAtBinding.Yes(unionRanges mMatch mWith) + SynExpr.MatchBang (spBind, $2, clauses, unionRanges mMatch mLast) } - | MATCH_BANG typedSeqExpr recover %prec expr_match + | MATCH_BANG typedSequentialExpr recover %prec expr_match { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileMatch()) // Produce approximate expression during error recovery exprFromParseError $2 } - | TRY typedSeqExprBlockR withClauses %prec expr_try + | TRY typedSequentialExprBlockR withClauses %prec expr_try { let mTry = (rhs parseState 1) - let spTry = SequencePointAtTry(mTry) - let mWith,(clauses,mLast) = $3 - let spWith = SequencePointAtWith(mWith) + let spTry = DebugPointAtTry.Yes mTry + let mWith, (clauses, mLast) = $3 + let spWith = DebugPointAtWith.Yes mWith let mTryToWith = unionRanges mTry mWith let mWithToLast = unionRanges mWith mLast let mTryToLast = unionRanges mTry mLast - SynExpr.TryWith ($2, mTryToWith, clauses,mWithToLast, mTryToLast,spTry,spWith) } + SynExpr.TryWith ($2, mTryToWith, clauses, mWithToLast, mTryToLast, spTry, spWith) } - | TRY typedSeqExprBlockR recover %prec expr_try + | TRY typedSequentialExprBlockR recover %prec expr_try { // Produce approximate expression during error recovery // Include any expressions to make sure they gets type checked in case that generates useful results for intellisense if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileTry()) exprFromParseError $2 } - | TRY typedSeqExprBlockR FINALLY typedSeqExprBlock %prec expr_try + | TRY typedSequentialExprBlockR FINALLY typedSequentialExprBlock %prec expr_try { let mTry = rhs parseState 1 - let spTry = SequencePointAtTry(mTry) - let spFinally = SequencePointAtFinally(rhs parseState 3) + let spTry = DebugPointAtTry.Yes mTry + let spFinally = DebugPointAtFinally.Yes (rhs parseState 3) let mTryToLast = unionRanges mTry $4.Range - SynExpr.TryFinally ($2, $4,mTryToLast,spTry,spFinally) } + SynExpr.TryFinally ($2, $4, mTryToLast, spTry, spFinally) } | IF declExpr ifExprCases %prec expr_if - { let mIf = (rhs parseState 1) - $3 $2 mIf } + { let mIf = rhs parseState 1 + $3 $2 mIf false } | IF declExpr recover %prec expr_if { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsIncompleteIf()) @@ -3160,13 +3525,13 @@ declExpr: { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsIncompleteIf()) // Produce an approximate expression during error recovery. There can still be value in doing this even // for this pathological case. - let m = (rhs parseState 1) + let m = rhs parseState 1 let mEnd = m.EndRange - let spIfToThen = SequencePointAtBinding mEnd - exprFromParseError (SynExpr.IfThenElse (arbExpr("ifGuard1",mEnd),arbExpr("thenBody1",mEnd),None,spIfToThen,true,m,m)) } + let spIfToThen = DebugPointAtBinding.Yes mEnd + exprFromParseError (SynExpr.IfThenElse (m, false, arbExpr("ifGuard1", mEnd), m, arbExpr("thenBody1", mEnd), None, None, spIfToThen, true, m, m)) } | LAZY declExpr %prec expr_lazy - { SynExpr.Lazy ($2,unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.Lazy ($2, unionRanges (rhs parseState 1) $2.Range) } | ASSERT declExpr %prec expr_assert { SynExpr.Assert ($2, unionRanges (rhs parseState 1) $2.Range) } @@ -3175,7 +3540,7 @@ declExpr: { raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsAssertIsNotFirstClassValue()) } | OLAZY declExprBlock %prec expr_lazy - { SynExpr.Lazy ($2,unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.Lazy ($2, unionRanges (rhs parseState 1) $2.Range) } | OASSERT declExprBlock %prec expr_assert { SynExpr.Assert ($2, unionRanges (rhs parseState 1) $2.Range) } @@ -3183,302 +3548,418 @@ declExpr: | OASSERT %prec expr_assert { raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsAssertIsNotFirstClassValue()) } - | WHILE declExpr doToken typedSeqExprBlock doneDeclEnd + | WHILE declExpr doToken typedSequentialExprBlock doneDeclEnd { let mWhileHeader = unionRanges (rhs parseState 1) $2.Range - let spWhile = SequencePointAtWhileLoop mWhileHeader + let spWhile = DebugPointAtWhile.Yes mWhileHeader let mWhileAll = unionRanges (rhs parseState 1) $4.Range - SynExpr.While (spWhile,$2,$4,mWhileAll) } + SynExpr.While (spWhile, $2, $4, mWhileAll) } - | WHILE declExpr doToken typedSeqExprBlock recover + | WHILE declExpr doToken typedSequentialExprBlock recover { if not $5 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileWhile()) let mWhileHeader = unionRanges (rhs parseState 1) $2.Range - let spWhile = SequencePointAtWhileLoop mWhileHeader + let spWhile = DebugPointAtWhile.Yes mWhileHeader let mWhileAll = unionRanges (rhs parseState 1) $4.Range - exprFromParseError (SynExpr.While (spWhile,$2,$4,mWhileAll)) } + exprFromParseError (SynExpr.While (spWhile, $2, $4, mWhileAll)) } | WHILE declExpr doToken error doneDeclEnd { // silent recovery let mWhileHeader = unionRanges (rhs parseState 1) $2.Range - let spWhile = SequencePointAtWhileLoop mWhileHeader + let spWhile = DebugPointAtWhile.Yes mWhileHeader let mWhileBodyArb = unionRanges (rhs parseState 4) (rhs parseState 5) let mWhileAll = unionRanges (rhs parseState 1) (rhs parseState 5) - SynExpr.While (spWhile,$2,arbExpr("whileBody1",mWhileBodyArb),mWhileAll) } + SynExpr.While (spWhile, $2, arbExpr("whileBody1", mWhileBodyArb), mWhileAll) } | WHILE declExpr recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsWhileDoExpected()) let mWhileHeader = unionRanges (rhs parseState 1) $2.Range - let spWhile = SequencePointAtWhileLoop mWhileHeader + let spWhile = DebugPointAtWhile.Yes mWhileHeader let mWhileBodyArb = rhs parseState 3 let mWhileAll = unionRanges (rhs parseState 1) (rhs parseState 3) - exprFromParseError (SynExpr.While (spWhile,$2,arbExpr("whileBody2",mWhileBodyArb),mWhileAll)) } + exprFromParseError (SynExpr.While (spWhile, $2, arbExpr("whileBody2", mWhileBodyArb), mWhileAll)) } | WHILE recover { if not $2 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileWhile()) - arbExpr("whileLoop1",rhs parseState 1) } + arbExpr("whileLoop1", rhs parseState 1) } | WHILE error doneDeclEnd { //silent recovery let mWhileHeader = rhs parseState 1 - let spWhile = SequencePointAtWhileLoop mWhileHeader + let spWhile = DebugPointAtWhile.Yes mWhileHeader let mWhileBodyArb = rhs parseState 3 let mWhileAll = unionRanges (rhs parseState 1) (rhs parseState 3) - exprFromParseError (SynExpr.While (spWhile,arbExpr("whileGuard1",mWhileHeader),arbExpr("whileBody3",mWhileBodyArb),mWhileAll)) } + exprFromParseError (SynExpr.While (spWhile, arbExpr("whileGuard1", mWhileHeader), arbExpr("whileBody3", mWhileBodyArb), mWhileAll)) } - | FOR forLoopBinder doToken typedSeqExprBlock doneDeclEnd - { let spBind = SequencePointAtForLoop(rhs2 parseState 1 3) - let (a,b,_) = $2 - SynExpr.ForEach (spBind,SeqExprOnly false,true,a,b,$4,unionRanges (rhs parseState 1) $4.Range) } + | FOR forLoopBinder doToken typedSequentialExprBlock doneDeclEnd + { let mForLoopHeader = rhs2 parseState 1 3 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, _) = $2 + SynExpr.ForEach (spBind, SeqExprOnly false, true, a, b, $4, unionRanges (rhs parseState 1) $4.Range) } - | FOR forLoopBinder doToken typedSeqExprBlock ends_coming_soon_or_recover + | FOR forLoopBinder doToken typedSequentialExprBlock ends_coming_soon_or_recover { if not $5 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFor()) - let spBind = SequencePointAtForLoop(rhs2 parseState 1 3) - let (a,b,_) = $2 + let mForLoopHeader = rhs2 parseState 1 3 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, _) = $2 let mForLoopAll = unionRanges (rhs parseState 1) $4.Range - SynExpr.ForEach (spBind,SeqExprOnly false,true,a,b,$4,mForLoopAll) } + SynExpr.ForEach (spBind, SeqExprOnly false, true, a, b, $4, mForLoopAll) } | FOR forLoopBinder doToken error doneDeclEnd { // Silent recovery let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,_) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, _) = $2 let mForLoopBodyArb = rhs parseState 5 let mForLoopAll = rhs2 parseState 1 5 - SynExpr.ForEach (spBind,SeqExprOnly false,true,a,b,arbExpr("forLoopBody2a",mForLoopBodyArb),mForLoopAll) } + SynExpr.ForEach (spBind, SeqExprOnly false, true, a, b, arbExpr("forLoopBody2a", mForLoopBodyArb), mForLoopAll) } | FOR forLoopBinder doToken ends_coming_soon_or_recover { if not $4 then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsExpectedExpressionAfterToken()) let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,_) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, _) = $2 let mForLoopBodyArb = rhs parseState 3 let mForLoopAll = rhs2 parseState 1 3 - SynExpr.ForEach (spBind,SeqExprOnly false,true,a,b,arbExpr("forLoopBody2",mForLoopBodyArb),mForLoopAll) } + SynExpr.ForEach (spBind, SeqExprOnly false, true, a, b, arbExpr("forLoopBody2", mForLoopBodyArb), mForLoopAll) } | FOR forLoopBinder ends_coming_soon_or_recover - { let (a,b,ok) = $2 + { let (a, b, ok) = $2 if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsForDoExpected()) let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader + let spBind = DebugPointAtFor.Yes mForLoopHeader let mForLoopBodyArb = rhs parseState 3 let mForLoopAll = rhs2 parseState 1 3 - SynExpr.ForEach (spBind,SeqExprOnly false,true,a,b,arbExpr("forLoopBody1",mForLoopBodyArb),mForLoopAll) } + SynExpr.ForEach (spBind, SeqExprOnly false, true, a, b, arbExpr("forLoopBody1", mForLoopBodyArb), mForLoopAll) } - | FOR forLoopRange doToken typedSeqExprBlock doneDeclEnd + | FOR forLoopRange doToken typedSequentialExprBlock doneDeclEnd { let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,c,d) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, c, d) = $2 let mForLoopAll = unionRanges (rhs parseState 1) $4.Range - SynExpr.For (spBind,a,b,c,d,$4,mForLoopAll) } + SynExpr.For (spBind, a, b, c, d, $4, mForLoopAll) } - | FOR forLoopRange doToken typedSeqExprBlock recover + | FOR forLoopRange doToken typedSequentialExprBlock recover { if not $5 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFor()) // Still produce an expression let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,c,d) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, c, d) = $2 let mForLoopAll = unionRanges (rhs parseState 1) $4.Range - exprFromParseError (SynExpr.For (spBind,a,b,c,d,$4,mForLoopAll)) } + exprFromParseError (SynExpr.For (spBind, a, b, c, d, $4, mForLoopAll)) } | FOR forLoopRange doToken error doneDeclEnd { // silent recovery let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,c,d) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, c, d) = $2 let mForLoopBodyArb = rhs parseState 5 let mForLoopAll = rhs2 parseState 1 5 - SynExpr.For (spBind,a,b,c,d,arbExpr("declExpr11",mForLoopBodyArb),mForLoopAll) } + SynExpr.For (spBind, a, b, c, d, arbExpr("declExpr11", mForLoopBodyArb), mForLoopAll) } | FOR forLoopRange doToken recover { if not $4 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFor()) let mForLoopHeader = rhs2 parseState 1 3 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,c,d) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, c, d) = $2 let mForLoopBodyArb = rhs parseState 3 let mForLoopAll = rhs2 parseState 1 3 - exprFromParseError (SynExpr.For (spBind,a,b,c,d,arbExpr("declExpr11",mForLoopBodyArb),mForLoopAll)) } + exprFromParseError (SynExpr.For (spBind, a, b, c, d, arbExpr("declExpr11", mForLoopBodyArb), mForLoopAll)) } | FOR forLoopRange recover { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFor()) let mForLoopHeader = rhs2 parseState 1 2 - let spBind = SequencePointAtForLoop mForLoopHeader - let (a,b,c,d) = $2 + let spBind = DebugPointAtFor.Yes mForLoopHeader + let (a, b, c, d) = $2 let mForLoopBodyArb = (rhs parseState 2).EndRange let mForLoopAll = rhs2 parseState 1 2 - exprFromParseError (SynExpr.For (spBind,a,b,c,d,arbExpr("declExpr11",mForLoopBodyArb),mForLoopAll)) } + exprFromParseError (SynExpr.For (spBind, a, b, c, d, arbExpr("declExpr11", mForLoopBodyArb), mForLoopAll)) } - | FOR error doToken typedSeqExprBlock doneDeclEnd + | FOR error doToken typedSequentialExprBlock doneDeclEnd { // silent recovery let mForLoopHeader = rhs2 parseState 1 2 let mForLoopAll = unionRanges (rhs parseState 1) $4.Range - let spBind = SequencePointAtForLoop(mForLoopHeader) - SynExpr.For (spBind,mkSynId mForLoopHeader "_loopVar",arbExpr("startLoopRange1",mForLoopHeader),true,arbExpr("endLoopRange1",rhs parseState 3),$4,mForLoopAll) } - -/* do not include this one - though for fairly bizarre reasons! - If the user has simply typed 'for'as the - start of a variable name, and intellisense parsing - kicks in, then we can't be sure we're parsing a for-loop. The general rule is that you shoudn't - commit to aggressive look-for-a-matching-construct error recovery until - you're sure you're parsing a particular construct. + let spBind = DebugPointAtFor.Yes mForLoopHeader + SynExpr.For (spBind, mkSynId mForLoopHeader "_loopVar", arbExpr("startLoopRange1", mForLoopHeader), true, arbExpr("endLoopRange1", rhs parseState 3), $4, mForLoopAll) } - This probably affects 'and' as well, but it's hard to change that. - 'for' is a particularly common prefix of identifiers. - - | FOR error doneDeclEnd { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsIdentifierExpected()); arbExpr("declExpr12",(lhs parseState)) } -*/ | FOR ends_coming_soon_or_recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsIdentifierExpected()) - arbExpr("declExpr12",(rhs parseState 1)) } + arbExpr("declExpr12", (rhs parseState 1)) } | FOR parenPattern error doneDeclEnd { reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsInOrEqualExpected()) let mForLoopHeader = rhs2 parseState 1 2 - let spBind = SequencePointAtForLoop mForLoopHeader + let spBind = DebugPointAtFor.Yes mForLoopHeader let mForLoopBodyArb = rhs parseState 4 let mForLoopAll = rhs2 parseState 1 4 - SynExpr.ForEach (spBind,SeqExprOnly false,true,$2,arbExpr("forLoopCollection",mForLoopHeader),arbExpr("forLoopBody3",mForLoopBodyArb),mForLoopAll) } + SynExpr.ForEach (spBind, SeqExprOnly false, true, $2, arbExpr("forLoopCollection", mForLoopHeader), arbExpr("forLoopBody3", mForLoopBodyArb), mForLoopAll) } | FOR parenPattern recover { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFor()) let mForLoopHeader = rhs2 parseState 1 2 - let spBind = SequencePointAtForLoop mForLoopHeader + let spBind = DebugPointAtFor.Yes mForLoopHeader let mForLoopBodyArb = (rhs parseState 2).EndRange let mForLoopAll = rhs2 parseState 1 2 - exprFromParseError (SynExpr.ForEach (spBind,SeqExprOnly false,true,$2,arbExpr("forLoopCollection",mForLoopHeader),arbExpr("forLoopBody3",mForLoopBodyArb),mForLoopAll)) } + exprFromParseError (SynExpr.ForEach (spBind, SeqExprOnly false, true, $2, arbExpr("forLoopCollection", mForLoopHeader), arbExpr("forLoopBody3", mForLoopBodyArb), mForLoopAll)) } - /* START MONADIC SYNTAX ONLY */ | YIELD declExpr - { SynExpr.YieldOrReturn (($1,not $1),$2, unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.YieldOrReturn (($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) } | YIELD_BANG declExpr - { SynExpr.YieldOrReturnFrom (($1,not $1), $2, unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.YieldOrReturnFrom (($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) } - | BINDER headBindingPattern EQUALS typedSeqExprBlock IN opt_OBLOCKSEP typedSeqExprBlock %prec expr_let - { let spBind = SequencePointAtBinding(rhs2 parseState 1 5) - let m = unionRanges (rhs parseState 1) $7.Range - SynExpr.LetOrUseBang (spBind,($1 = "use"),true,$2,$4,$7,m) } + | YIELD recover + { let mYieldAll = rhs parseState 1 + SynExpr.YieldOrReturn (($1, not $1), arbExpr("yield", mYieldAll), mYieldAll) } - | OBINDER headBindingPattern EQUALS typedSeqExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP typedSeqExprBlock %prec expr_let + | YIELD_BANG recover + { let mYieldAll = rhs parseState 1 + SynExpr.YieldOrReturnFrom (($1, not $1), arbExpr("yield!", mYieldAll), mYieldAll) } + + | BINDER headBindingPattern EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let + { let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) + let m = unionRanges (rhs parseState 1) $8.Range + SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, $7, $8, m) } + + | OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let { $5 (if $1 = "use" then "use!" else "let!") (rhs parseState 1) // report unterminated error - let spBind = SequencePointAtBinding(unionRanges (rhs parseState 1) $4.Range) - let m = unionRanges (rhs parseState 1) $7.Range - SynExpr.LetOrUseBang (spBind,($1 = "use"),true,$2,$4,$7,m) } + let spBind = DebugPointAtBinding.Yes(unionRanges (rhs parseState 1) $4.Range) + let m = unionRanges (rhs parseState 1) $8.Range + SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, $7, $8, m) } - | OBINDER headBindingPattern EQUALS typedSeqExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error %prec expr_let + | OBINDER headBindingPattern EQUALS typedSequentialExprBlock hardwhiteDefnBindingsTerminator opt_OBLOCKSEP error %prec expr_let { // error recovery that allows intellisense when writing incomplete computation expressions - let spBind = SequencePointAtBinding(unionRanges (rhs parseState 1) $4.Range) + let spBind = DebugPointAtBinding.Yes(unionRanges (rhs parseState 1) $4.Range) let mAll = unionRanges (rhs parseState 1) (rhs parseState 7) let m = $4.Range.EndRange // zero-width range - SynExpr.LetOrUseBang (spBind,($1 = "use"),true,$2,$4, SynExpr.ImplicitZero m, mAll) } + SynExpr.LetOrUseBang(spBind, ($1 = "use"), true, $2, $4, [], SynExpr.ImplicitZero m, mAll) } - | DO_BANG typedSeqExpr IN opt_OBLOCKSEP typedSeqExprBlock %prec expr_let - { let spBind = NoSequencePointAtDoBinding - SynExpr.LetOrUseBang (spBind,false,true,SynPat.Const(SynConst.Unit,$2.Range),$2,$5, unionRanges (rhs parseState 1) $5.Range) } + | DO_BANG typedSequentialExpr IN opt_OBLOCKSEP typedSequentialExprBlock %prec expr_let + { let spBind = DebugPointAtBinding.NoneAtDo + SynExpr.LetOrUseBang(spBind, false, true, SynPat.Const(SynConst.Unit, $2.Range), $2, [], $5, unionRanges (rhs parseState 1) $5.Range) } - | ODO_BANG typedSeqExprBlock hardwhiteDefnBindingsTerminator %prec expr_let + | ODO_BANG typedSequentialExprBlock hardwhiteDefnBindingsTerminator %prec expr_let { SynExpr.DoBang ($2, unionRanges (rhs parseState 1) $2.Range) } | FOR forLoopBinder opt_OBLOCKSEP arrowThenExprR %prec expr_let - { let spBind = SequencePointAtForLoop(rhs2 parseState 1 2) - let (a,b,_) = $2 in SynExpr.ForEach (spBind,SeqExprOnly true,true,a,b,$4,unionRanges (rhs parseState 1) $4.Range) } + { let spBind = DebugPointAtFor.Yes (rhs2 parseState 1 2) + let (a, b, _) = $2 in SynExpr.ForEach (spBind, SeqExprOnly true, true, a, b, $4, unionRanges (rhs parseState 1) $4.Range) } | FIXED declExpr { SynExpr.Fixed ($2, (unionRanges (rhs parseState 1) $2.Range)) } - | RARROW typedSeqExprBlockR - { errorR(Error(FSComp.SR.parsArrowUseIsLimited(),lhs parseState)) - SynExpr.YieldOrReturn ((true,true),$2, (unionRanges (rhs parseState 1) $2.Range)) } - - /* END MONADIC SYNTAX ONLY */ - - | declExpr COLON_QMARK typ { SynExpr.TypeTest ($1,$3, unionRanges $1.Range $3.Range) } - | declExpr COLON_GREATER typ { SynExpr.Upcast ($1,$3, unionRanges $1.Range $3.Range) } - | declExpr COLON_QMARK_GREATER typ { SynExpr.Downcast ($1,$3, unionRanges $1.Range $3.Range) } - - /* NOTE: any change to the "INFIX" tokens (or their definitions) should be reflected in PrettyNaming.IsInfixOperator */ - | declExpr COLON_EQUALS declExpr { mkSynInfix (rhs parseState 2) $1 ":=" $3 } - | minusExpr LARROW declExprBlock { mkSynAssign $1 $3 } -/* | minusExpr LARROW recover { mkSynAssign $1 (arbExpr("assignRhs",rhs parseState 2)) } */ - | tupleExpr %prec expr_tuple { let exprs,commas = $1 in SynExpr.Tuple (false, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ) } - | declExpr JOIN_IN declExpr { SynExpr.JoinIn ($1,rhs parseState 2,$3,unionRanges $1.Range $3.Range) } - | declExpr BAR_BAR declExpr { mkSynInfix (rhs parseState 2) $1 "||" $3 } - | declExpr INFIX_BAR_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr OR declExpr { mkSynInfix (rhs parseState 2) $1 "or" $3 } - | declExpr AMP declExpr { mkSynInfix (rhs parseState 2) $1 "&" $3 } - | declExpr AMP_AMP declExpr { mkSynInfix (rhs parseState 2) $1 "&&" $3 } - | declExpr INFIX_AMP_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr EQUALS declExpr { mkSynInfix (rhs parseState 2) $1 "=" $3 } - | declExpr INFIX_COMPARE_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr DOLLAR declExpr { mkSynInfix (rhs parseState 2) $1 "$" $3 } - | declExpr LESS declExpr { mkSynInfix (rhs parseState 2) $1 "<" $3 } - | declExpr LESS recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("<")) - exprFromParseError (mkSynInfix (rhs parseState 2) $1 "<" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr GREATER declExpr { mkSynInfix (rhs parseState 2) $1 ">" $3 } - | declExpr INFIX_AT_HAT_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr PERCENT_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr COLON_COLON declExpr { SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple (false,[$1;$3],[rhs parseState 2],unionRanges $1.Range $3.Range),unionRanges $1.Range $3.Range) } - | declExpr PLUS_MINUS_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr MINUS declExpr { mkSynInfix (rhs parseState 2) $1 "-" $3 } - | declExpr STAR declExpr { mkSynInfix (rhs parseState 2) $1 "*" $3 } - | declExpr INFIX_STAR_DIV_MOD_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr INFIX_STAR_STAR_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - - | declExpr JOIN_IN OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("in")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "@in" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr BAR_BAR OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("||")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "||" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_BAR_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr OR OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("or")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "or" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr AMP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr AMP_AMP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&&")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&&" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_AMP_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr EQUALS OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("=")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "=" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_COMPARE_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr DOLLAR OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("$")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "$" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr LESS OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("<")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "<" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr GREATER OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression(">")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 ">" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_AT_HAT_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr PERCENT_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr COLON_COLON OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("::")) - SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple (false,[$1;(arbExpr("declExprInfix",(rhs parseState 3).StartRange))],[rhs parseState 2],unionRanges $1.Range (rhs parseState 3).StartRange),unionRanges $1.Range (rhs parseState 3).StartRange) } - | declExpr PLUS_MINUS_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr MINUS OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("-")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "-" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr STAR OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("*")) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 "*" (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_STAR_DIV_MOD_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } - | declExpr INFIX_STAR_STAR_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) - exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } + | RARROW typedSequentialExprBlockR + { errorR(Error(FSComp.SR.parsArrowUseIsLimited(), lhs parseState)) + SynExpr.YieldOrReturn ((true, true), $2, (unionRanges (rhs parseState 1) $2.Range)) } + + | declExpr COLON_QMARK typ + { SynExpr.TypeTest ($1, $3, unionRanges $1.Range $3.Range) } + + | declExpr COLON_GREATER typ + { SynExpr.Upcast ($1, $3, unionRanges $1.Range $3.Range) } + + | declExpr COLON_QMARK_GREATER typ + { SynExpr.Downcast ($1, $3, unionRanges $1.Range $3.Range) } + + | declExpr COLON_EQUALS declExpr + { mkSynInfix (rhs parseState 2) $1 ":=" $3 } + + | minusExpr LARROW declExprBlock + { mkSynAssign $1 $3 } + + | tupleExpr %prec expr_tuple + { let exprs, commas = $1 + SynExpr.Tuple (false, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ) } + + | declExpr JOIN_IN declExpr + { SynExpr.JoinIn ($1, rhs parseState 2, $3, unionRanges $1.Range $3.Range) } + + | declExpr BAR_BAR declExpr + { mkSynInfix (rhs parseState 2) $1 "||" $3 } + + | declExpr INFIX_BAR_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr OR declExpr + { mkSynInfix (rhs parseState 2) $1 "or" $3 } + + | declExpr AMP declExpr + { mkSynInfix (rhs parseState 2) $1 "&" $3 } + + | declExpr AMP_AMP declExpr + { mkSynInfix (rhs parseState 2) $1 "&&" $3 } + + | declExpr INFIX_AMP_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr EQUALS declExpr + { mkSynInfix (rhs parseState 2) $1 "=" $3 } + + | declExpr INFIX_COMPARE_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr DOLLAR declExpr + { mkSynInfix (rhs parseState 2) $1 "$" $3 } + + | declExpr LESS declExpr + { mkSynInfix (rhs parseState 2) $1 "<" $3 } + + | declExpr LESS recover + { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("<")) + exprFromParseError (mkSynInfix (rhs parseState 2) $1 "<" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr GREATER declExpr + { mkSynInfix (rhs parseState 2) $1 ">" $3 } + + | declExpr INFIX_AT_HAT_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr PERCENT_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr COLON_COLON declExpr + { let tupExpr = SynExpr.Tuple (false, [$1;$3], [rhs parseState 2], unionRanges $1.Range $3.Range) + SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons, tupExpr, unionRanges $1.Range $3.Range) } + + | declExpr PLUS_MINUS_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr MINUS declExpr + { mkSynInfix (rhs parseState 2) $1 "-" $3 } + + | declExpr STAR declExpr + { mkSynInfix (rhs parseState 2) $1 "*" $3 } + + | declExpr INFIX_STAR_DIV_MOD_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr INFIX_STAR_STAR_OP declExpr + { mkSynInfix (rhs parseState 2) $1 $2 $3 } + + | declExpr JOIN_IN OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("in")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "@in" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr BAR_BAR OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("||")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "||" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_BAR_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr OR OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("or")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "or" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr AMP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr AMP_AMP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("&&")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "&&" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_AMP_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr EQUALS OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("=")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "=" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_COMPARE_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr DOLLAR OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("$")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "$" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr LESS OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("<")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "<" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr GREATER OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression(">")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 ">" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_AT_HAT_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr PERCENT_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr COLON_COLON OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("::")) + let tupExpr = SynExpr.Tuple (false, [$1;(arbExpr("declExprInfix", (rhs parseState 3).StartRange))], [rhs parseState 2], unionRanges $1.Range (rhs parseState 3).StartRange) + SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons, tupExpr, unionRanges $1.Range (rhs parseState 3).StartRange) } + + | declExpr PLUS_MINUS_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr MINUS OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("-")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "-" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr STAR OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("*")) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 "*" (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_STAR_DIV_MOD_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr INFIX_STAR_STAR_OP OBLOCKEND_COMING_SOON + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) + exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix", (rhs parseState 3).StartRange))) } + + | declExpr DOT_DOT declExpr + { let wholem = rhs2 parseState 1 3 + let opm = rhs parseState 2 + SynExpr.IndexRange(Some $1, opm, Some $3, rhs parseState 1, rhs parseState 3, wholem) } + + | declExpr DOT_DOT %prec open_range_expr + { let wholem = rhs2 parseState 1 2 + let opm = rhs parseState 2 + SynExpr.IndexRange(Some $1, opm, None, rhs parseState 1, opm, wholem) } + + | DOT_DOT declExpr %prec open_range_expr + { let wholem = rhs2 parseState 1 2 + let opm = rhs parseState 1 + SynExpr.IndexRange(None, opm, Some $2, opm, rhs parseState 2, wholem) } + + | STAR + { let m = rhs parseState 1 + SynExpr.IndexRange(None, m, None, m, m, m) } + + | INFIX_AT_HAT_OP declExpr + { if not (parseState.LexBuffer.SupportsFeature LanguageFeature.FromEndSlicing) then + raiseParseErrorAt (rhs parseState 1) (FSComp.SR.fromEndSlicingRequiresVFive()) + if $1 <> "^" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidPrefixOperator()) + let m = (rhs2 parseState 1 2) + SynExpr.IndexFromEnd($2, m) } | minusExpr %prec expr_prefix_plus_minus { $1 } dynamicArg: | IDENT - { let con = SynConst.String ($1,rhs parseState 1) - let arg2 = SynExpr.Const (con,con.Range (rhs parseState 1)) + { let con = SynConst.String ($1, SynStringKind.Regular, rhs parseState 1) + let arg2 = SynExpr.Const (con, con.Range (rhs parseState 1)) arg2 } - | LPAREN typedSeqExpr rparen + + | LPAREN typedSequentialExpr rparen { $2 } withClauses: | WITH withPatternClauses { rhs parseState 1, $2 } + | OWITH withPatternClauses OEND { rhs parseState 1, $2 } + | OWITH withPatternClauses recover { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileWith()) rhs parseState 1, $2 } @@ -3486,16 +3967,19 @@ withClauses: withPatternClauses: | patternClauses { $1 } + | BAR patternClauses - { $2 } + { $2 } + | BAR error - { // silent recovery - let mLast = rhs parseState 1 - [], mLast } + { // silent recovery + let mLast = rhs parseState 1 + [], mLast } + | error - { // silent recovery - let mLast = rhs parseState 1 - [], mLast } + { // silent recovery + let mLast = rhs parseState 1 + [], mLast } patternAndGuard: @@ -3504,93 +3988,127 @@ patternAndGuard: patternClauses: | patternAndGuard patternResult %prec prec_pat_pat_action - { let pat,guard,patm = $1 - let mLast = $2.Range - [Clause(pat,guard,$2,patm,SequencePointAtTarget)], mLast } + { let pat, guard, patm = $1 + let mArrow, resultExpr = $2 + let mLast = resultExpr.Range + let m = unionRanges resultExpr.Range patm + [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } + | patternAndGuard patternResult BAR patternClauses - { let pat,guard,patm = $1 - let clauses,mLast = $4 - (Clause(pat,guard,$2,patm,SequencePointAtTarget) :: clauses), mLast } + { let pat, guard, patm = $1 + let mArrow, resultExpr = $2 + let clauses, mLast = $4 + let m = unionRanges resultExpr.Range patm + (SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes) :: clauses), mLast } + + | patternAndGuard error BAR patternClauses + { let pat, guard, patm = $1 + let clauses, mLast = $4 + let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm + (SynMatchClause(pat, guard, None, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes) :: clauses), mLast } + | patternAndGuard patternResult BAR error - { let pat,guard,patm = $1 + { let pat, guard, patm = $1 + let mArrow, resultExpr = $2 let mLast = rhs parseState 3 - // silent recovery - [Clause(pat,guard,$2,patm,SequencePointAtTarget)], mLast } + let m = unionRanges resultExpr.Range patm + // silent recovery + [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } + | patternAndGuard patternResult error - { let pat,guard,patm = $1 - let mLast = $2.Range + { let pat, guard, patm = $1 + let mArrow, resultExpr = $2 + let mLast = resultExpr.Range + let m = unionRanges resultExpr.Range patm // silent recovery - [Clause(pat,guard,$2,patm,SequencePointAtTarget)], mLast } + [SynMatchClause(pat, guard, (Some mArrow), resultExpr, m, DebugPointAtTarget.Yes)], mLast } + | patternAndGuard error - { let pat,guard,patm = $1 + { let pat, guard, patm = $1 let mLast = rhs parseState 2 + let m = guard |> Option.map (fun e -> unionRanges patm e.Range) |> Option.defaultValue patm // silent recovery - [Clause(pat,guard,SynExpr.Const (SynConst.Unit,mLast.EndRange),patm,SequencePointAtTarget)], mLast } + [SynMatchClause(pat, guard, None, arbExpr ("patternClauses2", m.EndRange), m, DebugPointAtTarget.Yes)], mLast } patternGuard: | WHEN declExpr { Some $2 } - | + + | /* EMPTY */ { None } patternResult: - | RARROW typedSeqExprBlockR - { $2 } + | RARROW typedSequentialExprBlockR + { let mArrow = rhs parseState 1 + mArrow, $2 } ifExprCases: | ifExprThen ifExprElifs - { let exprThen,mThen = $1 - (fun exprGuard mIf -> + { let exprThen, mThen = $1 + let mElse, elseExpr = $2 + (fun exprGuard mIf isElif -> let mIfToThen = unionRanges mIf mThen - let lastBranch : SynExpr = match $2 with None -> exprThen | Some e -> e + let lastBranch : SynExpr = match elseExpr with None -> exprThen | Some e -> e let mIfToEndOfLastBranch = unionRanges mIf lastBranch.Range - let spIfToThen = SequencePointAtBinding(mIfToThen) - SynExpr.IfThenElse (exprGuard,exprThen,$2,spIfToThen,false,mIfToThen,mIfToEndOfLastBranch)) } + let spIfToThen = DebugPointAtBinding.Yes(mIfToThen) + SynExpr.IfThenElse (mIf, isElif, exprGuard, mThen, exprThen, mElse, elseExpr, spIfToThen, false, mIfToThen, mIfToEndOfLastBranch)) } ifExprThen: | THEN declExpr %prec prec_then_if { $2, rhs parseState 1 } - | OTHEN OBLOCKBEGIN typedSeqExpr oblockend %prec prec_then_if - { $3,rhs parseState 1 } - | OTHEN OBLOCKBEGIN typedSeqExpr recover %prec prec_then_if + + | OTHEN OBLOCKBEGIN typedSequentialExpr oblockend %prec prec_then_if + { $3, rhs parseState 1 } + + | OTHEN OBLOCKBEGIN typedSequentialExpr recover %prec prec_then_if { if not $4 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileThen()) - exprFromParseError $3,rhs parseState 1 } + exprFromParseError $3, rhs parseState 1 } ifExprElifs: - | - { None } + | /* EMPTY */ + { None, None } | ELSE declExpr - { Some $2 } + { let mElse = rhs parseState 1 + Some mElse, Some $2 } - | OELSE OBLOCKBEGIN typedSeqExpr oblockend - { Some $3 } + | OELSE OBLOCKBEGIN typedSequentialExpr oblockend + { let mElse = rhs parseState 1 + Some mElse, Some $3 } - | OELSE OBLOCKBEGIN typedSeqExpr recover - { if not $4 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileElse()) - Some (exprFromParseError $3) } + | OELSE OBLOCKBEGIN typedSequentialExpr recover + { let mElse = rhs parseState 1 + if not $4 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileElse()) + Some mElse, Some (exprFromParseError $3) } | ELIF declExpr ifExprCases - { let mElif = rhs parseState 1 - Some ($3 $2 mElif) } + { let mElif = rhs parseState 1 + // verify if `ELIF` is not a merged token + let length = mElif.EndColumn - mElif.StartColumn + if length > 4 then + let mElse = mkRange mElif.FileName (mkPos mElif.StartLine mElif.StartColumn) (mkPos mElif.StartLine (mElif.StartColumn + 4)) + let mIf = mkRange mElif.FileName (mkPos mElif.StartLine (mElif.EndColumn - 2)) (mkPos mElif.StartLine mElif.EndColumn) + Some mElse, (Some ($3 $2 mIf false)) + else + None, Some ($3 $2 mElif true) } | ELIF declExpr recover - { Some (exprFromParseError $2) } + { None, Some (exprFromParseError $2) } tupleExpr: | tupleExpr COMMA declExpr - { let exprs,commas = $1 in ($3 :: exprs),((rhs parseState 2) :: commas) } + { let exprs, commas = $1 in ($3 :: exprs), ((rhs parseState 2) :: commas) } | tupleExpr COMMA ends_coming_soon_or_recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsExpectedExpressionAfterToken()) - let exprs,commas = $1 + let exprs, commas = $1 let zeroWidthAtNextToken = (rhs parseState 3).StartRange - ((arbExpr("tupleExpr1",zeroWidthAtNextToken)) :: exprs), (rhs parseState 2) :: commas } + ((arbExpr("tupleExpr1", zeroWidthAtNextToken)) :: exprs), (rhs parseState 2) :: commas } | declExpr COMMA ends_coming_soon_or_recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsExpectedExpressionAfterToken()) let zeroWidthAtNextToken = (rhs parseState 3).StartRange - ((arbExpr("tupleExpr2",zeroWidthAtNextToken)) :: [$1]), [rhs parseState 2] } + ((arbExpr("tupleExpr2", zeroWidthAtNextToken)) :: [$1]), [rhs parseState 2] } | declExpr COMMA declExpr { [$3 ; $1], [rhs parseState 2] } @@ -3601,131 +4119,135 @@ minusExpr: | PLUS_MINUS_OP minusExpr { if not (IsValidPrefixOperatorUse $1) then reportParseErrorAt $2.Range (FSComp.SR.parsInvalidPrefixOperator()) - mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~"^($1)) $2 } + mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~" + ($1)) $2 } | ADJACENT_PREFIX_OP minusExpr { if not (IsValidPrefixOperatorUse $1) then reportParseErrorAt $2.Range (FSComp.SR.parsInvalidPrefixOperator()) - mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~"^($1)) $2 } + mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~" + ($1)) $2 } | PERCENT_OP minusExpr { if not (IsValidPrefixOperatorUse $1) then reportParseErrorAt $2.Range (FSComp.SR.parsInvalidPrefixOperator()) - mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~"^($1)) $2 } + mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) $2.Range) ("~" + ($1)) $2 } | AMP minusExpr - { SynExpr.AddressOf (true,$2,rhs parseState 1,unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.AddressOf (true, $2, rhs parseState 1, unionRanges (rhs parseState 1) $2.Range) } | AMP_AMP minusExpr - { SynExpr.AddressOf (false,$2,rhs parseState 1, unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.AddressOf (false, $2, rhs parseState 1, unionRanges (rhs parseState 1) $2.Range) } | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType - { SynExpr.New (false,$2,$4,unionRanges (rhs parseState 1) $4.Range) } + { SynExpr.New (false, $2, $4, unionRanges (rhs parseState 1) $4.Range) } | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP error - { SynExpr.New (false,$2,arbExpr("minusExpr",(rhs parseState 4)),unionRanges (rhs parseState 1) ($2).Range) } + { SynExpr.New (false, $2, arbExpr("minusExpr", (rhs parseState 4)), unionRanges (rhs parseState 1) ($2).Range) } | NEW error - { arbExpr("minusExpr2",(rhs parseState 1)) } + { arbExpr("minusExpr2", (rhs parseState 1)) } | UPCAST minusExpr - { SynExpr.InferredUpcast ($2,unionRanges (rhs parseState 1) $2.Range) } + { SynExpr.InferredUpcast ($2, unionRanges (rhs parseState 1) $2.Range) } | DOWNCAST minusExpr - { SynExpr.InferredDowncast ($2,unionRanges (rhs parseState 1) $2.Range)} + { SynExpr.InferredDowncast ($2, unionRanges (rhs parseState 1) $2.Range)} | appExpr { $1 } appExpr: | appExpr argExpr %prec expr_app - { SynExpr.App (ExprAtomicFlag.NonAtomic, false, $1,$2,unionRanges $1.Range $2.Range) } + { SynExpr.App (ExprAtomicFlag.NonAtomic, false, $1, $2, unionRanges $1.Range $2.Range) } | atomicExpr - { let arg,_ = $1 + { let arg, _ = $1 arg } argExpr: | ADJACENT_PREFIX_OP atomicExpr - { let arg2,hpa2 = $2 + { let arg2, hpa2 = $2 if not (IsValidPrefixOperatorUse $1) then reportParseErrorAt arg2.Range (FSComp.SR.parsInvalidPrefixOperator()) if hpa2 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsSuccessiveArgsShouldBeSpacedOrTupled()) - mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) arg2.Range) ("~"^($1)) arg2 } + mkSynPrefix (rhs parseState 1) (unionRanges (rhs parseState 1) arg2.Range) ("~" + ($1)) arg2 } | atomicExpr - { let arg,hpa = $1 + { let arg, hpa = $1 if hpa then reportParseErrorAt arg.Range (FSComp.SR.parsSuccessiveArgsShouldBeSpacedOrTupled()) arg } atomicExpr: | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr - { let arg1,_ = $1 - let arg2,_ = $3 - SynExpr.App (ExprAtomicFlag.Atomic, false, arg1,arg2,unionRanges arg1.Range arg2.Range),true } + { let arg1, _ = $1 + let arg2, hpa = $3 + SynExpr.App (ExprAtomicFlag.Atomic, false, arg1, arg2, unionRanges arg1.Range arg2.Range), hpa } | atomicExpr HIGH_PRECEDENCE_PAREN_APP atomicExpr - { let arg1,_ = $1 - let arg2,_ = $3 - SynExpr.App (ExprAtomicFlag.Atomic, false, arg1,arg2,unionRanges arg1.Range arg2.Range),true } + { let arg1, _ = $1 + let arg2, _ = $3 + SynExpr.App (ExprAtomicFlag.Atomic, false, arg1, arg2, unionRanges arg1.Range arg2.Range), true } | atomicExpr HIGH_PRECEDENCE_TYAPP typeArgsActual - { let arg1,_ = $1 - let mLessThan,mGreaterThan,_,args,commas,mTypeArgs = $3 + { let arg1, _ = $1 + let mLessThan, mGreaterThan, _, args, commas, mTypeArgs = $3 let mWholeExpr = unionRanges arg1.Range mTypeArgs SynExpr.TypeApp (arg1, mLessThan, args, commas, mGreaterThan, mTypeArgs, mWholeExpr), false } - | PREFIX_OP atomicExpr - { let arg2,hpa2 = $2 + | PREFIX_OP atomicExpr + { let arg2, hpa2 = $2 if not (IsValidPrefixOperatorUse $1) then reportParseErrorAt arg2.Range (FSComp.SR.parsInvalidPrefixOperator()) - mkSynPrefixPrim (rhs parseState 1) (unionRanges (rhs parseState 1) arg2.Range) $1 arg2,hpa2 } + mkSynPrefixPrim (rhs parseState 1) (unionRanges (rhs parseState 1) arg2.Range) $1 arg2, hpa2 } | atomicExpr DOT atomicExprQualification - { let arg1,hpa1 = $1 - $3 arg1 (lhs parseState) (rhs parseState 2),hpa1 } + { let arg1, hpa1 = $1 + $3 arg1 (lhs parseState) (rhs parseState 2), hpa1 } | BASE DOT atomicExprQualification - { let arg1 = SynExpr.Ident (ident("base",rhs parseState 1)) - $3 arg1 (lhs parseState) (rhs parseState 2),false } + { let arg1 = SynExpr.Ident (ident("base", rhs parseState 1)) + $3 arg1 (lhs parseState) (rhs parseState 2), false } | QMARK nameop - { SynExpr.LongIdent (true,LongIdentWithDots([$2],[]),None,rhs parseState 2),false } + { SynExpr.LongIdent (true, LongIdentWithDots([$2], []), None, rhs parseState 2), false } | atomicExpr QMARK dynamicArg - { let arg1,hpa1 = $1 + { let arg1, hpa1 = $1 mkSynInfix (rhs parseState 2) arg1 "?" $3, hpa1 } | GLOBAL - { SynExpr.Ident (ident(MangledGlobalName,rhs parseState 1)), false } + { SynExpr.Ident (ident(MangledGlobalName, rhs parseState 1)), false } - | nameop - { SynExpr.Ident ($1),false } + | identExpr + { $1, false } | LBRACK listExprElements RBRACK - { $2 (lhs parseState) false,false } + { $2 (lhs parseState), false } | LBRACK listExprElements recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()) - exprFromParseError ($2 (rhs2 parseState 1 2) false), false } + exprFromParseError ($2 (rhs2 parseState 1 2)), false } | LBRACK error RBRACK { // silent recovery - SynExpr.ArrayOrList (false,[ ], lhs parseState),false } + SynExpr.ArrayOrList (false, [ ], lhs parseState), false } | LBRACK recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()) // silent recovery - exprFromParseError (SynExpr.ArrayOrList (false,[ ], rhs parseState 1)),false } + exprFromParseError (SynExpr.ArrayOrList (false, [ ], rhs parseState 1)), false } - | STRUCT LPAREN tupleExpr rparen - { let exprs,commas = $3 in SynExpr.Tuple (true, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } + | STRUCT LPAREN tupleExpr rparen + { let exprs, commas = $3 + let m = rhs2 parseState 1 4 + SynExpr.Tuple (true, List.rev exprs, List.rev commas, m), false } - | STRUCT LPAREN tupleExpr recover - { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedBracket()); - let exprs,commas = $3 in SynExpr.Tuple (true, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } + | STRUCT LPAREN tupleExpr recover + { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedBracket()); + let exprs, commas = $3 + let m = (rhs parseState 1, exprs) ||> unionRangeWithListBy (fun e -> e.Range) + SynExpr.Tuple (true, List.rev exprs, List.rev commas, m), false } | atomicExprAfterType - { $1,false } + { $1, false } atomicExprQualification: - | identOrOp + | identOrOp { let idm = rhs parseState 1 (fun e lhsm dotm -> mkSynDot dotm lhsm e $1) } @@ -3735,173 +4257,137 @@ atomicExprQualification: let fixedLhsm = mkRange lhsm.FileName lhsm.Start dotm.End // previous lhsm is wrong after 'recover' mkSynDotMissing dotm fixedLhsm e) } - | /* empty */ + | /* empty */ { (fun e lhsm dotm -> reportParseErrorAt dotm (FSComp.SR.parsMissingQualificationAfterDot()) let fixedLhsm = mkRange lhsm.FileName lhsm.Start dotm.End // previous lhsm is wrong after 'recover' mkSynDotMissing dotm fixedLhsm e) } - | recover + | recover { (fun e lhsm dotm -> reportParseErrorAt dotm (FSComp.SR.parsMissingQualificationAfterDot()) let fixedLhsm = mkRange lhsm.FileName lhsm.Start dotm.End // previous lhsm is wrong after 'recover' // Include 'e' in the returned expression but throw it away - SynExpr.DiscardAfterMissingQualificationAfterDot (e,fixedLhsm)) } - | LPAREN COLON_COLON rparen DOT INT32 + SynExpr.DiscardAfterMissingQualificationAfterDot (e, fixedLhsm)) } + | LPAREN COLON_COLON rparen DOT INT32 { (fun e lhsm dotm -> - libraryOnlyError(lhs parseState) - SynExpr.LibraryOnlyUnionCaseFieldGet (e,mkSynCaseName lhsm opNameCons,(fst $5),lhsm)) } + if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyError(lhs parseState) + SynExpr.LibraryOnlyUnionCaseFieldGet (e, mkSynCaseName lhsm opNameCons, (fst $5), lhsm)) } - | LPAREN typedSeqExpr rparen + | LPAREN typedSequentialExpr rparen { (fun e lhsm dotm -> - mlCompatWarning (FSComp.SR.parsParenFormIsForML()) (lhs parseState) - mkSynDotParenGet lhsm dotm e $2) } - - | LBRACK typedSeqExpr recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()) - (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e $2 false)) } - - | LBRACK optRangeSeqExpr RBRACK - { (fun e lhsm dotm -> mkSynDotBrackSeqSliceGet lhsm dotm e $2) } - - | LBRACK optRangeSeqExpr recover + // Check for expr.( * ) + // Note that "*" is parsed as an expression (it is allowed in "foo.[3,*]") + match $2 with + | SynExpr.IndexRange (None, opm, None, _m1, _m2, _) -> + mkSynDot dotm lhsm e (ident(CompileOpName "*", opm)) + | _ -> + if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatMultiPrefixTyparsNoLongerSupported()) (lhs parseState) + else + mlCompatWarning (FSComp.SR.parsParenFormIsForML()) (lhs parseState) + mkSynDotParenGet lhsm dotm e $2) } + + | LBRACK typedSequentialExpr RBRACK + { (fun e lhsm dotm -> mkSynDotBrackGet lhsm dotm e $2) } + + | LBRACK typedSequentialExpr recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()) - (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackSeqSliceGet lhsm dotm e $2)) } + (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e $2)) } - | LBRACK error RBRACK + | LBRACK error RBRACK { let mArg = rhs2 parseState 1 3 - (fun e lhsm dotm -> mkSynDotBrackGet lhsm dotm e (arbExpr("indexerExpr1",mArg)) false) } + (fun e lhsm dotm -> mkSynDotBrackGet lhsm dotm e (arbExpr("indexerExpr1", mArg))) } - | LBRACK recover + | LBRACK recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()) let mArg = (rhs parseState 1).EndRange - (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e (arbExpr("indexerExpr2",mArg)) false)) } - -optRangeSeqExpr: - | optRange COMMA optRangeSeqExpr %prec slice_comma { $1 :: $3 } - | optRange { [$1] } - -optRange: - | rangeDeclExpr DOT_DOT rangeDeclExpr - { SynIndexerArg.Two( - mkSynOptionalExpr (rhs parseState 1) (Some (fst $1)), - (snd $1), - mkSynOptionalExpr (rhs parseState 3) (Some (fst $3)), - (snd $3), - (rhs parseState 1), - (rhs parseState 3)) } - - | rangeDeclExpr DOT_DOT - { SynIndexerArg.Two( - mkSynOptionalExpr (rhs parseState 1) (Some (fst $1)), - (snd $1), - mkSynOptionalExpr (rhs parseState 2) None, - false, - (rhs parseState 1), - (rhs parseState 2)) } - - | DOT_DOT rangeDeclExpr - { SynIndexerArg.Two( - mkSynOptionalExpr (rhs parseState 1) None, - false, - mkSynOptionalExpr (rhs parseState 2) (Some (fst $2)), - (snd $2), - (rhs parseState 2), - (rhs parseState 1)) } - - | STAR - { SynIndexerArg.Two( - mkSynOptionalExpr (rhs parseState 1) None, - false, - (mkSynOptionalExpr (rhs parseState 1) None), - false, - (rhs parseState 1), - (rhs parseState 1)) } - - | rangeDeclExpr - { SynIndexerArg.One((fst $1), (snd $1), (rhs parseState 1)) } - -rangeDeclExpr: - | declExpr %prec slice_expr - { $1, false } - - | INFIX_AT_HAT_OP declExpr %prec slice_expr - { if not (parseState.LexBuffer.SupportsFeature LanguageFeature.FromEndSlicing) then - raiseParseErrorAt (rhs parseState 1) (FSComp.SR.fromEndSlicingRequiresVFive()) - if $1 <> "^" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidPrefixOperator()) - $2, true } + (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e (arbExpr("indexerExpr2", mArg)))) } -/* the start et of atomicExprAfterType must not overlap with the valid postfix tokens of the type syntax, e.g. new List(...) */ +/* the start of atomicExprAfterType must not overlap with the valid postfix tokens of the type syntax, e.g. new List(...) */ atomicExprAfterType: | constant - { SynExpr.Const ($1,$1.Range (lhs parseState)) } + { SynExpr.Const (fst $1, snd $1) } + | parenExpr { $1 } + | braceExpr { $1 } + | braceBarExpr { $1 } + + | interpolatedString + { let parts, synStringKind = $1 + SynExpr.InterpolatedString(parts, synStringKind, rhs parseState 1) } + | NULL { SynExpr.Null (lhs parseState) } + | FALSE - { SynExpr.Const (SynConst.Bool false,lhs parseState) } + { SynExpr.Const (SynConst.Bool false, lhs parseState) } + | TRUE - { SynExpr.Const (SynConst.Bool true,lhs parseState) } + { SynExpr.Const (SynConst.Bool true, lhs parseState) } + | quoteExpr { $1 } + | arrayExpr { $1 } + | beginEndExpr { $1 } beginEndExpr: - | BEGIN typedSeqExpr END + | BEGIN typedSequentialExpr END { SynExpr.Paren ($2, rhs parseState 1, Some(rhs parseState 3), rhs2 parseState 1 3) } - | BEGIN typedSeqExpr recover + | BEGIN typedSequentialExpr recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBegin()); exprFromParseError $2 } | BEGIN error END - { (* silent recovery *) arbExpr("beginEndExpr",(lhs parseState)) } + { (* silent recovery *) arbExpr("beginEndExpr", (lhs parseState)) } | BEGIN END { mkSynUnit (lhs parseState) } quoteExpr: - | LQUOTE typedSeqExpr RQUOTE + | LQUOTE typedSequentialExpr RQUOTE { if $1 <> $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsMismatchedQuote(fst $1)) (SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)), snd $1, $2, false, lhs parseState)) } - | LQUOTE typedSeqExpr recover + | LQUOTE typedSequentialExpr recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatched(fst $1)) let mExpr = rhs2 parseState 1 2 - exprFromParseError (SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)),snd $1, $2, false, mExpr)) } + exprFromParseError (SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)), snd $1, $2, false, mExpr)) } | LQUOTE error RQUOTE - { (* silent recovery *) SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)),snd $1, arbExpr("quoteExpr",(rhs parseState 2)), false, lhs parseState) } + { (* silent recovery *) SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)), snd $1, arbExpr("quoteExpr", (rhs parseState 2)), false, lhs parseState) } | LQUOTE recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatched(fst $1)) - exprFromParseError (SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)),snd $1, arbExpr("quoteExpr2",(rhs parseState 1).EndRange), false, rhs parseState 1)) } + exprFromParseError (SynExpr.Quote (mkSynIdGet (lhs parseState) (CompileOpName (fst $1)), snd $1, arbExpr("quoteExpr2", (rhs parseState 1).EndRange), false, rhs parseState 1)) } arrayExpr: - | LBRACK_BAR listExprElements BAR_RBRACK - { $2 (lhs parseState) true } + | LBRACK_BAR arrayExprElements BAR_RBRACK + { $2 (lhs parseState) } - | LBRACK_BAR listExprElements recover + | LBRACK_BAR arrayExprElements recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracketBar()) - exprFromParseError ($2 (rhs2 parseState 1 2) true) } + exprFromParseError ($2 (rhs2 parseState 1 2)) } | LBRACK_BAR error BAR_RBRACK - { (* silent recovery *) SynExpr.ArrayOrList (true,[ ], lhs parseState) } + { (* silent recovery *) SynExpr.ArrayOrList (true, [ ], lhs parseState) } | LBRACK_BAR recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracketBar()) (* silent recovery *) - exprFromParseError (SynExpr.ArrayOrList (true,[ ], rhs parseState 1)) } + exprFromParseError (SynExpr.ArrayOrList (true, [ ], rhs parseState 1)) } parenExpr: | LPAREN rparen - { SynExpr.Const (SynConst.Unit,(rhs2 parseState 1 2)) } + { SynExpr.Const (SynConst.Unit, (rhs2 parseState 1 2)) } | LPAREN parenExprBody rparen { let m = rhs2 parseState 1 3 @@ -3914,7 +4400,7 @@ parenExpr: | LPAREN error rparen { // silent recovery - SynExpr.Paren (arbExpr("parenExpr1",(rhs parseState 1).EndRange),(rhs parseState 1),Some(rhs parseState 3),(rhs2 parseState 1 3)) } + SynExpr.Paren (arbExpr("parenExpr1", (rhs parseState 1).EndRange), (rhs parseState 1), Some(rhs parseState 3), (rhs2 parseState 1 3)) } | LPAREN TYPE_COMING_SOON { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) @@ -3938,20 +4424,22 @@ parenExpr: | LPAREN recover %prec prec_atomexpr_lparen_error { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) - arbExpr("parenExpr2",(lhs parseState)) } + arbExpr("parenExpr2", (lhs parseState)) } // This is really what we should be doing, but it fails because param info expects the range of the expression // to extend all the way over the "recover", to the end of the file if necessary // // let mLeftParen = rhs parseState 1 //let lhsm = if $2 then unionRangeWithPos mLeftParen (rhs parseState 2).Start else mLeftParen - //arbExpr("parenExpr2",lhsm) } + //arbExpr("parenExpr2", lhsm) } parenExprBody: - | staticallyKnownHeadTypars COLON LPAREN classMemberSpfn rparen typedSeqExpr - { (fun m -> SynExpr.TraitCall ($1,$4,$6,m)) } /* disambiguate: x $a.id(x) */ - | typedSeqExpr + | staticallyKnownHeadTypars COLON LPAREN classMemberSpfn rparen typedSequentialExpr + { (fun m -> SynExpr.TraitCall ($1, $4, $6, m)) } /* disambiguate: x $a.id(x) */ + + | typedSequentialExpr { (fun _m -> $1) } + | inlineAssemblyExpr { $1 } @@ -3971,131 +4459,111 @@ staticallyKnownHeadTyparAlts: braceExpr: | LBRACE braceExprBody rbrace - { let m,r = $2 in r (rhs2 parseState 1 3) } + { let m, r = $2 in r (rhs2 parseState 1 3) } | LBRACE braceExprBody recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBrace()) - let m,r = $2 + let m, r = $2 // Note, we can't use 'exprFromParseError' because the extra syntax node interferes with some syntax-directed transformations for computation expressions r (unionRanges (rhs parseState 1) m) } | LBRACE error rbrace { // silent recovery - arbExpr("braceExpr",rhs2 parseState 1 3) } + arbExpr("braceExpr", rhs2 parseState 1 3) } | LBRACE recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBrace()) // Note, we can't use 'exprFromParseError' because the extra syntax node interferes with some syntax-directed transformations for computation expressions - SynExpr.Record (None,None,[],rhs parseState 1) } + SynExpr.Record (None, None, [], rhs parseState 1) } | LBRACE rbrace { let m = rhs2 parseState 1 2 - SynExpr.Record (None,None,[],m) } + SynExpr.Record (None, None, [], m) } braceExprBody: | recdExpr - { (lhs parseState), (fun m -> let a,b,c = $1 in SynExpr.Record (a,b,c,m)) } + { (lhs parseState), (fun m -> let a, b, c = $1 in SynExpr.Record (a, b, c, m)) } | objExpr { $1 } - | monadicExprInitial - { let m,r = $1 in (m, r false) } + | computationExpr + { $1 } listExprElements: - | monadicExprInitial - { let m,r = $1 in (fun lhsm isArray -> SynExpr.ArrayOrListOfSeqExpr (isArray, r true m, lhsm)) } + | sequentialExpr + { (fun lhsm -> SynExpr.ArrayOrListComputed (false, $1, lhsm)) } + | - { (fun lhsm isArray -> SynExpr.ArrayOrList (isArray,[ ], lhsm)) } + { (fun lhsm -> SynExpr.ArrayOrList (false, [ ], lhsm)) } -monadicExprInitial: - | seqExpr - { $1.Range, (fun isArrayOrList lhsm -> SynExpr.CompExpr (isArrayOrList,ref(isArrayOrList),$1,lhsm)) } +arrayExprElements: + | sequentialExpr + { (fun lhsm -> SynExpr.ArrayOrListComputed (true, $1, lhsm)) } - | rangeSequenceExpr - { $1 } - -rangeSequenceExpr: - | declExpr DOT_DOT declExpr - { let opm = (rhs parseState 2) - (unionRanges $1.Range $3.Range),(fun _isArray wholem -> - // in the case of "{ 1 .. 10 }", we want the range of the expression to include the curlies, that comes from a higher level rule in the grammar, - // passed down as 'wholem', so patch up that range here - match (mkSynInfix opm $1 ".." $3) with - | SynExpr.App (a,b,c,d,_) -> SynExpr.App (a,b,c,d,wholem) - | _ -> failwith "impossible") } - | declExpr DOT_DOT declExpr DOT_DOT declExpr - { (unionRanges $1.Range $5.Range),(fun _isArray wholem -> mkSynTrifix wholem ".. .." $1 $3 $5) } - - | declExpr DOT_DOT recover - { if not $3 then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEndOfFileExpression()) - let opm = (rhs parseState 2) - let e = arbExpr("rangeSeqError1", (rhs parseState 3).StartRange) - (unionRanges $1.Range e.Range),(fun _isArray wholem -> - // in the case of "{ 1 .. 10 }", we want the range of the expression to include the curlies, that comes from a higher level rule in the grammar, - // passed down as 'wholem', so patch up that range here - match (mkSynInfix opm $1 ".." e) with - | SynExpr.App (a,b,c,d,_) -> SynExpr.App (a,b,c,d,wholem) - | _ -> failwith "impossible") } + | + { (fun lhsm -> SynExpr.ArrayOrList (true, [ ], lhsm)) } +computationExpr: + | sequentialExpr + { $1.Range, (fun lhsm -> SynExpr.ComputationExpr (false, $1, lhsm)) } arrowThenExprR: - | RARROW typedSeqExprBlockR - { SynExpr.YieldOrReturn ((true,false), $2, unionRanges (rhs parseState 1) $2.Range) } - + | RARROW typedSequentialExprBlockR + { SynExpr.YieldOrReturn ((true, false), $2, unionRanges (rhs parseState 1) $2.Range) } forLoopBinder: | parenPattern IN declExpr { ($1, $3, true) } - | parenPattern IN rangeSequenceExpr - { let m,r = $3 in ($1, r false m, true) } - | parenPattern IN ends_coming_soon_or_recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsExpectedExpressionAfterToken()) - ($1, arbExpr("forLoopBinder",(rhs parseState 2)), false) } + ($1, arbExpr("forLoopBinder", (rhs parseState 2)), false) } | parenPattern ends_coming_soon_or_recover { if not $2 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInOrEqualExpected()) - ($1, arbExpr("forLoopBinder2",(rhs parseState 1).EndRange), false) } + ($1, arbExpr("forLoopBinder2", (rhs parseState 1).EndRange), false) } forLoopRange: | parenPattern EQUALS declExpr forLoopDirection declExpr - { idOfPat parseState (rhs parseState 1) $1,$3,$4,$5 } - - | parenPattern EQUALS rangeSequenceExpr - { raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolEqualsInsteadOfIn()) } + { idOfPat parseState (rhs parseState 1) $1, $3, $4, $5 } forLoopDirection: | TO { true } + | DOWNTO { false } inlineAssemblyExpr: - | HASH stringOrKeywordString opt_inlineAssemblyTypeArg opt_curriedArgExprs opt_inlineAssemblyReturnTypes HASH - { libraryOnlyWarning (lhs parseState) - let s,sm = $2,rhs parseState 2 - (fun m -> SynExpr.LibraryOnlyILAssembly (internalParseAssemblyCodeInstructions s parseState.LexBuffer.SupportsFeature sm, $3, List.rev $4, $5, m)) } - -opt_curriedArgExprs: - | opt_curriedArgExprs argExpr %prec expr_args + | HASH string opt_inlineAssemblyTypeArg optCurriedArgExprs optInlineAssemblyReturnTypes HASH + { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning (lhs parseState) + let (s, _), sm = $2, rhs parseState 2 + (fun m -> + let ilInstrs = ParseAssemblyCodeInstructions s parseState.LexBuffer.ReportLibraryOnlyFeatures parseState.LexBuffer.LanguageVersion sm + SynExpr.LibraryOnlyILAssembly (box ilInstrs, $3, List.rev $4, $5, m)) } + +optCurriedArgExprs: + | optCurriedArgExprs argExpr %prec expr_args { $2 :: $1 } - | + | /* EMPTY */ { [] } opt_atomicExprAfterType: - | + | /* EMPTY */ { None } - | atomicExprAfterType + | atomicExprAfterType { Some($1) } opt_inlineAssemblyTypeArg: - | { [] } - | typeKeyword LPAREN typ rparen { [$3] } + | /* EMPTY */ + { [] } -opt_inlineAssemblyReturnTypes: - | + | typeKeyword LPAREN typ rparen + { [$3] } + +optInlineAssemblyReturnTypes: + | /* EMPTY */ { [] } | COLON typ @@ -4112,14 +4580,15 @@ recdExpr: let l = rebindRanges (dummyField, None) l $6 let (_, _, inheritsSep) = List.head l let bindings = List.tail l - (Some ($2,arg,rhs2 parseState 2 4, inheritsSep, rhs parseState 1), None, bindings) } + (Some ($2, arg, rhs2 parseState 2 4, inheritsSep, rhs parseState 1), None, bindings) } + | recdExprCore - { let a,b = $1 in (None, a, b) } + { let a, b = $1 in (None, a, b) } recdExprCore: | appExpr EQUALS declExprBlock recdExprBindings opt_seps_recd { match $1 with - | LongOrSingleIdent(false, (LongIdentWithDots(_,_) as f),None,m) -> + | LongOrSingleIdent(false, (LongIdentWithDots(_, _) as f), None, m) -> let f = mkRecdField f let l = List.rev $4 let l = rebindRanges (f, Some $3) l $5 @@ -4168,21 +4637,31 @@ recdExprCore: (Some ($1, (rhs parseState 2, None)), l) } opt_seps_recd: - | seps_recd { Some $1 } - | { None } + | seps_recd + { Some $1 } + + | /* EMPTY */ + { None } seps_recd: - | OBLOCKSEP { (rhs parseState 1), None } - | SEMICOLON { let m = (rhs parseState 1) in (m, Some m.End) } - | SEMICOLON OBLOCKSEP { (rhs2 parseState 1 2), Some (rhs parseState 1).End } - | OBLOCKSEP SEMICOLON { (rhs2 parseState 1 2), Some (rhs parseState 2).End } + | OBLOCKSEP + { (rhs parseState 1), None } + | SEMICOLON + { let m = (rhs parseState 1) in (m, Some m.End) } -/* - identifier can start from the underscore -*/ + | SEMICOLON OBLOCKSEP + { (rhs2 parseState 1 2), Some (rhs parseState 1).End } + + | OBLOCKSEP SEMICOLON + { (rhs2 parseState 1 2), Some (rhs parseState 2).End } + + +/* identifier can start from the underscore */ pathOrUnderscore : - | path { mkRecdField $1 } + | path + { mkRecdField $1 } + | UNDERSCORE { let m = rhs parseState 1 reportParseErrorAt m (FSComp.SR.parsUnderscoreInvalidFieldName()) @@ -4191,27 +4670,29 @@ pathOrUnderscore : recdExprBindings: | recdExprBindings seps_recd recdBinding { ($3, Some $2) :: $1 } - | { [] } + + | /* EMPTY */ + { [] } recdBinding: - | pathOrUnderscore EQUALS declExprBlock - { ($1, Some $3) } + | pathOrUnderscore EQUALS declExprBlock + { ($1, Some $3) } - | pathOrUnderscore EQUALS - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) - ($1, None) } + | pathOrUnderscore EQUALS + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) + ($1, None) } - | pathOrUnderscore EQUALS ends_coming_soon_or_recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) - ($1, None) } + | pathOrUnderscore EQUALS ends_coming_soon_or_recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) + ($1, None) } - | pathOrUnderscore - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) - ($1, None) } + | pathOrUnderscore + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) + ($1, None) } - | pathOrUnderscore ends_coming_soon_or_recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) - ($1, None) } + | pathOrUnderscore ends_coming_soon_or_recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsFieldBinding()) + ($1, None) } /* There is a minor conflict between seq { new ty() } // sequence expression with one very odd 'action' expression @@ -4223,33 +4704,35 @@ objExpr: | objExprBaseCall objExprBindings opt_OBLOCKSEP opt_objExprInterfaces { let mNewExpr = rhs parseState 1 let fullRange = match $4 with [] -> (rhs parseState 1) | _ -> (rhs2 parseState 1 4) - fullRange, (fun m -> let (a,b) = $1 in SynExpr.ObjExpr (a,b,$2,$4, mNewExpr, m)) } + fullRange, (fun m -> let (a, b) = $1 in SynExpr.ObjExpr (a, b, $2, $4, mNewExpr, m)) } | objExprBaseCall opt_OBLOCKSEP objExprInterfaces { let mNewExpr = rhs parseState 1 let fullRange = match $3 with [] -> (rhs parseState 1) | _ -> (rhs2 parseState 1 3) - fullRange, (fun m -> let (a,b) = $1 in SynExpr.ObjExpr (a,b,[],$3, mNewExpr, m)) } + fullRange, (fun m -> let (a, b) = $1 in SynExpr.ObjExpr (a, b, [], $3, mNewExpr, m)) } | NEW atomTypeNonAtomicDeprecated { let mNewExpr = rhs parseState 1 - (rhs2 parseState 1 2), (fun m -> let (a,b) = $2,None in SynExpr.ObjExpr (a,b,[],[], mNewExpr, m)) } - + (rhs2 parseState 1 2), (fun m -> let (a, b) = $2, None in SynExpr.ObjExpr (a, b, [], [], mNewExpr, m)) } objExprBaseCall: | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType baseSpec - { ($2, Some($4,Some($5))) } + { ($2, Some($4, Some($5))) } | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType - { ($2, Some($4,None)) } + { ($2, Some($4, None)) } | NEW atomTypeNonAtomicDeprecated - { $2,None } + { $2, None } opt_objExprBindings: - | objExprBindings { $1 } - | { [] } + | objExprBindings + { $1 } + + | /* EMPTY */ + { [] } objExprBindings: | WITH localBindings @@ -4265,9 +4748,9 @@ objExprBindings: | WITH objectImplementationBlock opt_declEnd { $2 |> (List.choose (function - | SynMemberDefn.Member(b,m) -> Some b - | SynMemberDefn.AutoProperty(_,_,_,_,_,_,_,_,_,_,m) -> errorR(Error(FSComp.SR.parsIllegalMemberVarInObjectImplementation(),m)); None - | x -> errorR(Error(FSComp.SR.parsMemberIllegalInObjectImplementation(),x.Range)); None)) } + | SynMemberDefn.Member(b, m) -> Some b + | SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, _, _, m) -> errorR(Error(FSComp.SR.parsIllegalMemberVarInObjectImplementation(), m)); None + | x -> errorR(Error(FSComp.SR.parsMemberIllegalInObjectImplementation(), x.Range)); None)) } objExprInterfaces: | objExprInterface opt_objExprInterfaces { $1 :: $2 } @@ -4283,12 +4766,13 @@ opt_objExprInterfaces: { (* silent recovery *) $2 } objExprInterface: - | interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP - { InterfaceImpl($2, $3, lhs parseState) } + | interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP + { SynInterfaceImpl($2, $3, lhs parseState) } braceBarExpr: | STRUCT braceBarExprCore { $2 true } + | braceBarExprCore { $1 false } @@ -4297,79 +4781,88 @@ braceBarExprCore: { let orig, flds = $2 let flds = flds |> List.choose (function - | ((LongIdentWithDots([id],_),_),Some e,_) -> Some (id,e) - | ((LongIdentWithDots([id],_),_),None,_) -> Some (id, arbExpr("anonField",id.idRange)) + | ((LongIdentWithDots([id], _), _), Some e, _) -> Some (id, e) + | ((LongIdentWithDots([id], _), _), None, _) -> Some (id, arbExpr("anonField", id.idRange)) | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) let m = rhs2 parseState 1 3 - (fun isStruct -> SynExpr.AnonRecd (isStruct,orig,flds,m)) } + (fun isStruct -> SynExpr.AnonRecd (isStruct, orig, flds, m)) } | LBRACE_BAR recdExprCore recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBraceBar()) let orig, flds = $2 let flds = flds |> List.choose (function - | ((LongIdentWithDots([id],_),_),Some e,_) -> Some (id,e) - | ((LongIdentWithDots([id],_),_),None,_) -> Some (id, arbExpr("anonField",id.idRange)) + | ((LongIdentWithDots([id], _), _), Some e, _) -> Some (id, e) + | ((LongIdentWithDots([id], _), _), None, _) -> Some (id, arbExpr("anonField", id.idRange)) | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) let m = rhs2 parseState 1 2 - (fun isStruct -> SynExpr.AnonRecd (isStruct,orig,flds,m)) } + (fun isStruct -> SynExpr.AnonRecd (isStruct, orig, flds, m)) } | LBRACE_BAR error bar_rbrace { // silent recovery let m = rhs2 parseState 1 3 - (fun _ -> arbExpr("braceBarExpr",m)) } + (fun _ -> arbExpr("braceBarExpr", m)) } | LBRACE_BAR recover { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBraceBar()) let m = rhs2 parseState 1 1 - (fun isStruct -> SynExpr.AnonRecd (isStruct,None,[],m)) } + (fun isStruct -> SynExpr.AnonRecd (isStruct, None, [], m)) } | LBRACE_BAR bar_rbrace { let m = rhs2 parseState 1 2 - (fun isStruct -> SynExpr.AnonRecd (isStruct,None,[],m)) } + (fun isStruct -> SynExpr.AnonRecd (isStruct, None, [], m)) } anonLambdaExpr: - | FUN atomicPatterns RARROW typedSeqExprBlock + | FUN atomicPatterns RARROW typedSequentialExprBlock { let mAll = unionRanges (rhs parseState 1) $4.Range - mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 $4 } + let mArrow = Some (rhs parseState 3) + mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 mArrow $4 } | FUN atomicPatterns RARROW error { let mAll = rhs2 parseState 1 3 - mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 (arbExpr("anonLambdaExpr1",(rhs parseState 4))) } + let mArrow = Some (rhs parseState 3) + mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 mArrow (arbExpr("anonLambdaExpr1", (rhs parseState 4))) } - | OFUN atomicPatterns RARROW typedSeqExprBlockR OEND + | OFUN atomicPatterns RARROW typedSequentialExprBlockR OEND { let mAll = unionRanges (rhs parseState 1) $4.Range - mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 $4 } + let mArrow = Some (rhs parseState 3) + mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 mArrow $4 } - | OFUN atomicPatterns RARROW typedSeqExprBlockR recover + | OFUN atomicPatterns RARROW typedSequentialExprBlockR recover { if not $5 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFunBody()); let mAll = unionRanges (rhs parseState 1) $4.Range - exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 $4) } + let mArrow = Some (rhs parseState 3) + exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false mAll $2 mArrow $4) } | OFUN atomicPatterns RARROW ORIGHT_BLOCK_END OEND - { reportParseErrorAt (rhs2 parseState 1 3) (FSComp.SR.parsMissingFunctionBody()) - mkSynFunMatchLambdas parseState.SynArgNameGenerator false (rhs2 parseState 1 3) $2 (arbExpr("anonLambdaExpr2",(rhs parseState 4))) } + { let mLambda = rhs2 parseState 1 3 + reportParseErrorAt mLambda (FSComp.SR.parsMissingFunctionBody()) + let mArrow = Some (rhs parseState 3) + mkSynFunMatchLambdas parseState.SynArgNameGenerator false mLambda $2 mArrow (arbExpr("anonLambdaExpr2", mLambda.EndRange)) } | OFUN atomicPatterns RARROW recover { if not $4 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileFunBody()) - exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false (rhs2 parseState 1 3) $2 (arbExpr("anonLambdaExpr3",(rhs parseState 4)))) } + let mLambda = rhs2 parseState 1 3 + let mArrow = Some (rhs parseState 3) + exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false mLambda $2 mArrow (arbExpr("anonLambdaExpr3", mLambda.EndRange))) } | OFUN atomicPatterns error OEND - { exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false (rhs2 parseState 1 2) $2 (arbExpr("anonLambdaExpr4",(rhs parseState 3)))) } + { let mLambda = rhs2 parseState 1 2 + exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false mLambda $2 None (arbExpr("anonLambdaExpr4", mLambda.EndRange))) } | OFUN error OEND - { exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false (rhs parseState 1) [] (arbExpr("anonLambdaExpr5",(rhs parseState 2)))) } + { exprFromParseError (mkSynFunMatchLambdas parseState.SynArgNameGenerator false (rhs parseState 1) [] None (arbExpr("anonLambdaExpr5", (rhs parseState 2)))) } anonMatchingExpr: | FUNCTION withPatternClauses %prec expr_function - { let clauses,mLast = $2 - let mAll = unionRanges (rhs parseState 1) mLast - SynExpr.MatchLambda (false,(rhs parseState 1),clauses,NoSequencePointAtInvisibleBinding,mAll) } + { let clauses, mLast = $2 + let mAll = unionRanges (rhs parseState 1) mLast + SynExpr.MatchLambda (false, (rhs parseState 1), clauses, DebugPointAtBinding.NoneAtInvisible, mAll) } | OFUNCTION withPatternClauses OEND %prec expr_function - { let clauses,mLast = $2 - let mAll = unionRanges (rhs parseState 1) mLast - SynExpr.MatchLambda (false,(rhs parseState 1),clauses,NoSequencePointAtInvisibleBinding,mAll) } + { let clauses, mLast = $2 + let mAll = unionRanges (rhs parseState 1) mLast + SynExpr.MatchLambda (false, (rhs parseState 1), clauses, DebugPointAtBinding.NoneAtInvisible, mAll) } /*--------------------------------------------------------------------------*/ /* TYPE ALGEBRA */ @@ -4379,41 +4872,41 @@ typeWithTypeConstraints: { $1 } | typ WHEN typeConstraints - { SynType.WithGlobalConstraints($1, List.rev $3,lhs parseState) } + { SynType.WithGlobalConstraints($1, List.rev $3, lhs parseState) } topTypeWithTypeConstraints: | topType { $1 } | topType WHEN typeConstraints - { let ty,arity = $1 + { let ty, arity = $1 // nb. it doesn't matter where the constraints go in the structure of the type. - SynType.WithGlobalConstraints(ty,List.rev $3,lhs parseState), arity } + SynType.WithGlobalConstraints(ty, List.rev $3, lhs parseState), arity } opt_topReturnTypeWithTypeConstraints: | { None } | COLON topTypeWithTypeConstraints - { let ty,arity = $2 - let arity = (match arity with SynValInfo([],rmdata)-> rmdata | _ -> SynInfo.unnamedRetVal) - Some (SynReturnInfo((ty,arity),rhs parseState 2)) } + { let ty, arity = $2 + let arity = (match arity with SynValInfo([], rmdata)-> rmdata | _ -> SynInfo.unnamedRetVal) + Some (SynReturnInfo((ty, arity), rhs parseState 2)) } topType: | topTupleType RARROW topType - { let dty,dmdata= $1 - let rty,(SynValInfo(dmdatas,rmdata)) = $3 - SynType.Fun(dty,rty,lhs parseState), (SynValInfo(dmdata :: dmdatas, rmdata)) } + { let dty, dmdata= $1 + let rty, (SynValInfo(dmdatas, rmdata)) = $3 + SynType.Fun(dty, rty, lhs parseState), (SynValInfo(dmdata :: dmdatas, rmdata)) } | topTupleType - { let ty,rmdata = $1 in ty, (SynValInfo([],(match rmdata with [md] -> md | _ -> SynInfo.unnamedRetVal))) } + { let ty, rmdata = $1 in ty, (SynValInfo([], (match rmdata with [md] -> md | _ -> SynInfo.unnamedRetVal))) } topTupleType: | topAppType STAR topTupleTypeElements - { let ty,mdata = $1 in let tys,mdatas = List.unzip $3 in (SynType.Tuple(false,List.map (fun ty -> (false,ty)) (ty :: tys), lhs parseState)),(mdata :: mdatas) } + { let ty, mdata = $1 in let tys, mdatas = List.unzip $3 in (SynType.Tuple(false, List.map (fun ty -> (false, ty)) (ty :: tys), lhs parseState)), (mdata :: mdatas) } | topAppType - { let ty,mdata = $1 in ty,[mdata] } + { let ty, mdata = $1 in ty, [mdata] } topTupleTypeElements: | topAppType STAR topTupleTypeElements @@ -4425,31 +4918,31 @@ topTupleTypeElements: topAppType: | attributes appType COLON appType { match $2 with - | SynType.LongIdent(LongIdentWithDots([id],_)) -> $4,SynArgInfo($1,false,Some id) + | SynType.LongIdent(LongIdentWithDots([id], _)) -> $4, SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } | attributes QMARK ident COLON appType - { $5,SynArgInfo($1,true,Some $3) } + { $5, SynArgInfo($1, true, Some $3) } | attributes appType - { ($2,SynArgInfo($1,false,None)) } + { ($2, SynArgInfo($1, false, None)) } | appType COLON appType { match $1 with - | SynType.LongIdent(LongIdentWithDots([id],_)) -> $3,SynArgInfo([],false,Some id) + | SynType.LongIdent(LongIdentWithDots([id], _)) -> $3, SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } | QMARK ident COLON appType - { $4,SynArgInfo([],true,Some $2) } + { $4, SynArgInfo([], true, Some $2) } | appType - { $1,SynArgInfo([],false,None) } + { $1, SynArgInfo([], false, None) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ typ: | tupleType RARROW typ - { SynType.Fun($1,$3,lhs parseState) } + { SynType.Fun($1, $3, lhs parseState) } | tupleType %prec prec_typ_prefix { $1 } @@ -4460,29 +4953,29 @@ typEOF: tupleType: | appType STAR tupleOrQuotTypeElements - { SynType.Tuple(false,(false,$1) :: $3,lhs parseState) } + { SynType.Tuple(false, (false, $1) :: $3, lhs parseState) } | INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $1 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()); - SynType.Tuple(false,(true, SynType.StaticConstant (SynConst.Int32 1, lhs parseState)) :: $2, lhs parseState) } + SynType.Tuple(false, (true, SynType.StaticConstant (SynConst.Int32 1, lhs parseState)) :: $2, lhs parseState) } | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()); - SynType.Tuple(false,(true,$1) :: $3, lhs parseState) } + SynType.Tuple(false, (true, $1) :: $3, lhs parseState) } | appType %prec prec_tuptyp_prefix { $1 } tupleOrQuotTypeElements: | appType STAR tupleOrQuotTypeElements - { (false,$1) :: $3 } + { (false, $1) :: $3 } | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()); - (true,$1) :: $3 } + (true, $1) :: $3 } | appType %prec prec_tuptyptail_prefix - { [(false,$1)] } + { [(false, $1)] } appTypeCon: | path %prec prec_atomtyp_path @@ -4502,26 +4995,30 @@ appTypeConPower: appType: | appType arrayTypeSuffix - { SynType.Array($2,$1,lhs parseState) } + { SynType.Array($2, $1, lhs parseState) } | appType HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ - { SynType.Array($3,$1,lhs parseState) } + { SynType.Array($3, $1, lhs parseState) } | appType appTypeConPower - { SynType.App($2, None, [$1], [], None, true, unionRanges (rhs parseState 1) $2.Range) } /* note: use "rhs parseState 1" to deal with parens in "(int) list" */ + /* note: use "rhs parseState 1" to deal with parens in "(int) list" */ + { SynType.App($2, None, [$1], [], None, true, unionRanges (rhs parseState 1) $2.Range) } | LPAREN appTypePrefixArguments rparen appTypeConPower { let args, commas = $2 - mlCompatWarning (FSComp.SR.parsMultiArgumentGenericTypeFormDeprecated()) (unionRanges (rhs parseState 1) $4.Range); + if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatMultiPrefixTyparsNoLongerSupported()) (unionRanges (rhs parseState 1) $4.Range) + else + mlCompatWarning (FSComp.SR.parsMultiArgumentGenericTypeFormDeprecated()) (unionRanges (rhs parseState 1) $4.Range) SynType.App($4, None, args, commas, None, true, unionRanges (rhs parseState 1) $4.Range) } | powerType { $1 } - | typar COLON_GREATER typ - { let tp,typ = $1,$3 + | typar COLON_GREATER typ + { let tp, typ = $1, $3 let m = lhs parseState - SynType.WithGlobalConstraints(SynType.Var (tp, rhs parseState 1), [WhereTyparSubtypeOfType(tp,typ,m)],m) } + SynType.WithGlobalConstraints(SynType.Var (tp, rhs parseState 1), [SynTypeConstraint.WhereTyparSubtypeOfType(tp, typ, m)], m) } | UNDERSCORE COLON_GREATER typ %prec COLON_GREATER { SynType.HashConstraint($3, lhs parseState) } @@ -4571,7 +5068,10 @@ powerType: atomTypeNonAtomicDeprecated: | LPAREN appTypePrefixArguments rparen appTypeConPower { let args, commas = $2 - mlCompatWarning (FSComp.SR.parsMultiArgumentGenericTypeFormDeprecated()) (unionRanges (rhs parseState 1) $4.Range); + if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatMultiPrefixTyparsNoLongerSupported()) (unionRanges (rhs parseState 1) $4.Range) + else + mlCompatWarning (FSComp.SR.parsMultiArgumentGenericTypeFormDeprecated()) (unionRanges (rhs parseState 1) $4.Range) SynType.App($4, None, args, commas, None, true, unionRanges (rhs parseState 1) $4.Range) } | atomType @@ -4580,15 +5080,14 @@ atomTypeNonAtomicDeprecated: atomTypeOrAnonRecdType: | atomType { $1 } + | anonRecdType - { let flds,isStruct = $1 + { let flds, isStruct = $1 let flds2 = flds |> List.choose (function - | (Field([],false,Some id,ty,false,_xmldoc,None,_m)) -> Some (id,ty) + | (SynField([], false, Some id, ty, false, _xmldoc, None, _m)) -> Some (id, ty) | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) - SynType.AnonRecd (isStruct,flds2, rhs parseState 1) } - - + SynType.AnonRecd (isStruct, flds2, rhs parseState 1) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ /* See the F# specification "Lexical analysis of type applications and type parameter definitions" */ @@ -4602,19 +5101,19 @@ atomType: | UNDERSCORE { SynType.Anon (lhs parseState) } - | LPAREN typ rparen - { $2 } + | LPAREN typ rparen + { SynType.Paren ($2, lhs parseState) } - | LPAREN typ recover - { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) - $2 } + | LPAREN typ recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen ()) + SynType.Paren ($2, lhs parseState) } | STRUCT LPAREN appType STAR tupleOrQuotTypeElements rparen - { SynType.Tuple(true, (false,$3) :: $5,lhs parseState) } + { SynType.Tuple(true, (false, $3) :: $5, lhs parseState) } | STRUCT LPAREN appType STAR tupleOrQuotTypeElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) - SynType.Tuple(true, (false,$3) :: $5,lhs parseState) } + SynType.Tuple(true, (false, $3) :: $5, lhs parseState) } | STRUCT LPAREN appType STAR recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) @@ -4633,41 +5132,40 @@ atomType: | NULL { let m = rhs parseState 1 - SynType.StaticConstant(SynConst.String (null, m), m) } + SynType.StaticConstant(SynConst.String (null, SynStringKind.Regular, m), m) } | CONST atomicExpr - { let e,_ = $2 - SynType.StaticConstantExpr(e, e.Range) } + { let e, _ = $2 + SynType.StaticConstantExpr(e, lhs parseState) } | FALSE - { SynType.StaticConstant(SynConst.Bool false,lhs parseState) } + { SynType.StaticConstant(SynConst.Bool false, lhs parseState) } | TRUE - { SynType.StaticConstant(SynConst.Bool true,lhs parseState) } + { SynType.StaticConstant(SynConst.Bool true, lhs parseState) } | LPAREN error rparen { (* silent recovery *) SynType.Anon (lhs parseState) } | appTypeCon typeArgsNoHpaDeprecated %prec prec_atomtyp_path - { let mLessThan,mGreaterThan,args,commas,mWhole = $2 in SynType.App($1, Some(mLessThan), args, commas, mGreaterThan, false, unionRanges $1.Range mWhole) } + { let mLessThan, mGreaterThan, args, commas, mWhole = $2 in SynType.App($1, Some(mLessThan), args, commas, mGreaterThan, false, unionRanges $1.Range mWhole) } | atomType DOT path %prec prec_atomtyp_get_path { SynType.LongIdentApp($1, $3, None, [], [], None, unionRanges (rhs parseState 1) $3.Range) } | atomType DOT path typeArgsNoHpaDeprecated %prec prec_atomtyp_get_path - { let mLessThan,mGreaterThan,args,commas,mWhole = $4 + { let mLessThan, mGreaterThan, args, commas, mWhole = $4 SynType.LongIdentApp($1, $3, Some(mLessThan), args, commas, mGreaterThan, unionRanges $1.Range mWhole) } | appTypeCon DOT ends_coming_soon_or_recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsExpectedNameAfterToken()) $1 } - typeArgsNoHpaDeprecated: | typeArgsActual { let mLessThan, mGreaterThan, parsedOk, args, commas, mAll = $1 if parsedOk then // if someone has "foo "^" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedTypeParameter()); let id = mkSynId (lhs parseState) ($2).idText - Typar(id,HeadTypeStaticReq,false) } - - + SynTypar(id, TyparStaticReq.HeadType, false) } ident: | IDENT - { ident($1,rhs parseState 1) } - + { ident($1, rhs parseState 1) } /* A A.B.C path used to an identifier */ path: | GLOBAL - { LongIdentWithDots([ident(MangledGlobalName,rhs parseState 1)],[]) } + { LongIdentWithDots([ident(MangledGlobalName, rhs parseState 1)], []) } | ident - { LongIdentWithDots([$1],[]) } + { LongIdentWithDots([$1], []) } | path DOT ident - { let (LongIdentWithDots(lid,dotms)) = $1 in LongIdentWithDots(lid @ [$3], dotms @ [rhs parseState 2]) } + { let (LongIdentWithDots(lid, dotms)) = $1 in LongIdentWithDots(lid @ [$3], dotms @ [rhs parseState 2]) } | path DOT ends_coming_soon_or_recover { if not $3 then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsExpectedNameAfterToken()) - let (LongIdentWithDots(lid,dotms)) = $1 in LongIdentWithDots(lid, dotms @ [rhs parseState 2]) } + let (LongIdentWithDots(lid, dotms)) = $1 in LongIdentWithDots(lid, dotms @ [rhs parseState 2]) } /* An operator name, with surrounnding parentheses */ opName: | LPAREN operatorName rparen - { ident(CompileOpName $2,rhs parseState 2) } + { ident(CompileOpName $2, rhs parseState 2) } | LPAREN error rparen - { reportParseErrorAt (lhs parseState) (FSComp.SR.parsErrorParsingAsOperatorName()); ident(CompileOpName "****",rhs parseState 2) } + { reportParseErrorAt (lhs parseState) (FSComp.SR.parsErrorParsingAsOperatorName()); ident(CompileOpName "****", rhs parseState 2) } | LPAREN_STAR_RPAREN - { ident(CompileOpName "*",rhs parseState 1) } + { ident(CompileOpName "*", rhs parseState 1) } /* active pattern name */ | LPAREN activePatternCaseNames BAR rparen { let text = ("|" + String.concat "|" (List.rev $2) + "|") - ident(text,rhs2 parseState 2 3) } + ident(text, rhs2 parseState 2 3) } /* partial active pattern name */ | LPAREN activePatternCaseNames BAR UNDERSCORE BAR rparen { let text = ("|" + String.concat "|" (List.rev $2) + "|_|" ) - ident(text,rhs2 parseState 2 5) } + ident(text, rhs2 parseState 2 5) } /* An operator name, without surrounding parentheses */ operatorName: | PREFIX_OP - { if not (IsValidPrefixOperatorDefinitionName $1) then - reportParseErrorAt (lhs parseState) (FSComp.SR.parsInvalidPrefixOperatorDefinition()); - $1 } + { if not (IsValidPrefixOperatorDefinitionName $1) then + reportParseErrorAt (lhs parseState) (FSComp.SR.parsInvalidPrefixOperatorDefinition()); + $1 } - | INFIX_STAR_STAR_OP { $1 } + | INFIX_STAR_STAR_OP + { $1 } - | INFIX_COMPARE_OP { $1 } + | INFIX_COMPARE_OP + { $1 } - | INFIX_AT_HAT_OP { $1 } + | INFIX_AT_HAT_OP + { $1 } - | INFIX_BAR_OP { $1 } + | INFIX_BAR_OP + { $1 } - | INFIX_AMP_OP { $1 } + | INFIX_AMP_OP + { $1 } - | PLUS_MINUS_OP { $1 } + | PLUS_MINUS_OP + { $1 } - | INFIX_STAR_DIV_MOD_OP { $1 } + | INFIX_STAR_DIV_MOD_OP + { $1 } - | DOLLAR { "$" } + | DOLLAR + { "$" } - | ADJACENT_PREFIX_OP { $1 } + | ADJACENT_PREFIX_OP + { $1 } - | MINUS { "-" } + | MINUS + { "-" } - | STAR { "*" } + | STAR + { "*" } - | EQUALS { "=" } + | EQUALS + { "=" } - | OR { "or" } + | OR + { "or" } - | LESS { "<" } + | LESS + { "<" } - | GREATER { ">" } + | GREATER + { ">" } - | QMARK { "?" } + | QMARK + { "?" } - | AMP { "&" } + | AMP + { "&" } - | AMP_AMP { "&&" } + | AMP_AMP + { "&&" } - | BAR_BAR { "||" } + | BAR_BAR + { "||" } - | COLON_EQUALS { ":=" } + | COLON_EQUALS + { ":=" } | FUNKY_OPERATOR_NAME - { if $1 <> ".[]" && $1 <> ".()" && $1 <> ".()<-" then - deprecatedOperator (lhs parseState); - $1 } + { if $1 <> ".[]" && $1 <> ".()" && $1 <> ".()<-" then + deprecatedOperator (lhs parseState); + $1 } - | PERCENT_OP { $1 } + | PERCENT_OP + { $1 } - | DOT_DOT { ".." } + | DOT_DOT + { ".." } - | DOT_DOT DOT_DOT { ".. .." } + | DOT_DOT DOT_DOT + { ".. .." } | LQUOTE RQUOTE - { if $1 <> $2 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsMismatchedQuotationName(fst $1)); - fst $1 } + { if $1 <> $2 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsMismatchedQuotationName(fst $1)); + fst $1 } /* One part of an active pattern name */ activePatternCaseName: - | IDENT - { if not (String.isUpper $1) then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsActivePatternCaseMustBeginWithUpperCase()); - if ($1.IndexOf('|') <> -1) then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsActivePatternCaseContainsPipe()); - $1 } + | IDENT + { if not (String.isLeadingIdentifierCharacterUpperCase _1) then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsActivePatternCaseMustBeginWithUpperCase()); + if ($1.IndexOf('|') <> -1) then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsActivePatternCaseContainsPipe()); + $1 } /* Multiple parts of an active pattern name */ activePatternCaseNames: | BAR activePatternCaseName - { [$2] } + { [$2] } | activePatternCaseNames BAR activePatternCaseName - { $3 :: $1 } + { $3 :: $1 } /* A single item that is an identifier or operator name */ identOrOp: @@ -4946,21 +5463,31 @@ identOrOp: /* Note, only used in atomicPatternLongIdent */ pathOp: | ident - { LongIdentWithDots([$1],[]) } + { LongIdentWithDots([$1], []) } | opName - { LongIdentWithDots([$1],[]) } + { LongIdentWithDots([$1], []) } | ident DOT pathOp - { let (LongIdentWithDots(lid,dotms)) = $3 in LongIdentWithDots($1 :: lid, rhs parseState 2 :: dotms) } + { let (LongIdentWithDots(lid, dotms)) = $3 in LongIdentWithDots($1 :: lid, rhs parseState 2 :: dotms) } | ident DOT error - { (* silent recovery *) LongIdentWithDots([$1],[rhs parseState 2]) } + { (* silent recovery *) LongIdentWithDots([$1], [rhs parseState 2]) } /* nameop is identOrOp not used as part of a path */ nameop: - | identOrOp { $1 } + | identOrOp { $1 } + +identExpr: + | ident + { SynExpr.Ident($1) } + + | opName + { let m = lhs parseState + let mLparen = mkFileIndexRange m.FileIndex m.Start (mkPos m.StartLine (m.StartColumn + 1)) + let mRparen = mkFileIndexRange m.FileIndex (mkPos m.EndLine (m.EndColumn - 1)) m.End + SynExpr.Paren(SynExpr.Ident($1), mLparen, Some mRparen, m) } topSeparator: | SEMICOLON { } @@ -4968,7 +5495,7 @@ topSeparator: | OBLOCKSEP { } topSeparators: - | topSeparator { } + | topSeparator { } | topSeparator topSeparators { } opt_topSeparators: @@ -5010,6 +5537,10 @@ deprecated_opt_equals: | EQUALS { deprecatedWithError (FSComp.SR.parsNoEqualShouldFollowNamespace()) (lhs parseState); () } | /* EMPTY */ { } +opt_equals: + | EQUALS { true } + | /* EMPTY */ { false } + opt_OBLOCKSEP: | OBLOCKSEP { } | /* EMPTY */ { } @@ -5044,22 +5575,82 @@ doneDeclEnd: | ODECLEND { } /* DONE gets thrown away by the lexfilter in favour of ODECLEND */ structOrBegin: - | STRUCT { mlCompatWarning (FSComp.SR.parsSyntaxModuleStructEndDeprecated()) (lhs parseState); } + | STRUCT + { if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatStructEndNoLongerSupported()) (lhs parseState) + else + mlCompatWarning (FSComp.SR.parsSyntaxModuleStructEndDeprecated()) (lhs parseState) + } | BEGIN { } sigOrBegin: - | SIG { mlCompatWarning (FSComp.SR.parsSyntaxModuleSigEndDeprecated()) (lhs parseState); } + | SIG + { if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatSigEndNoLongerSupported())(lhs parseState) + else + mlCompatWarning (FSComp.SR.parsSyntaxModuleSigEndDeprecated()) (lhs parseState) + } | BEGIN { } colonOrEquals: - | COLON { mlCompatWarning (FSComp.SR.parsSyntaxModuleSigEndDeprecated()) (lhs parseState); } + | COLON + { if parseState.LexBuffer.SupportsFeature LanguageFeature.MLCompatRevisions then + mlCompatError (FSComp.SR.mlCompatSigColonNoLongerSupported())(lhs parseState) + else + mlCompatWarning (FSComp.SR.parsSyntaxModuleSigEndDeprecated()) (lhs parseState) + } | EQUALS { } -/* A literal string or a string fromm a keyword like __SOURCE_FILE__ */ -stringOrKeywordString: - | STRING { $1 } +/* A literal string or a string from a keyword like __SOURCE_FILE__ */ +string: + | STRING + { let (s, synStringKind, _) = $1 + s, synStringKind } + +sourceIdentifier: | KEYWORD_STRING { $1 } +interpolatedStringFill: + | declExpr + { ($1, None) } + + | declExpr COLON ident %prec interpolation_fill + { ($1, Some $3) } + +interpolatedStringParts: + | INTERP_STRING_END + { [ SynInterpolatedStringPart.String (fst $1, rhs parseState 1) ] } + + | INTERP_STRING_PART interpolatedStringFill interpolatedStringParts + { SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 } + + | INTERP_STRING_PART interpolatedStringParts + { + let rbrace = parseState.InputEndPosition 1 + let lbrace = parseState.InputStartPosition 2 + reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString()) + SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 } + +/* INTERP_STRING_BEGIN_END */ +/* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_END */ +/* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_PART int32 INTERP_STRING_END */ +interpolatedString: + | INTERP_STRING_BEGIN_PART interpolatedStringFill interpolatedStringParts + { let s, synStringKind, _ = $1 + SynInterpolatedStringPart.String (s, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3, synStringKind } + + | INTERP_STRING_BEGIN_END + { let s, synStringKind, _ = $1 + [ SynInterpolatedStringPart.String (s, rhs parseState 1) ], synStringKind } + + | INTERP_STRING_BEGIN_PART interpolatedStringParts + { + let s, synStringKind, _ = $1 + let rbrace = parseState.InputEndPosition 1 + let lbrace = parseState.InputStartPosition 2 + reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString()) + SynInterpolatedStringPart.String (s, rhs parseState 1) :: $2, synStringKind } + opt_HIGH_PRECEDENCE_APP: | HIGH_PRECEDENCE_BRACK_APP { } | HIGH_PRECEDENCE_PAREN_APP { } diff --git a/src/fsharp/pplex.fsl b/src/fsharp/pplex.fsl index 35d1c7fc3b7..fdd59bc6f81 100644 --- a/src/fsharp/pplex.fsl +++ b/src/fsharp/pplex.fsl @@ -6,15 +6,16 @@ module internal FSharp.Compiler.PPLexer open System -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Lexhelp +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax open Internal.Utilities.Text.Lexing let lexeme (lexbuf : UnicodeLexing.Lexbuf) = UnicodeLexing.Lexbuf.LexemeString lexbuf -let fail (args : lexargs) (lexbuf:UnicodeLexing.Lexbuf) e = +let fail (args : LexArgs) (lexbuf:UnicodeLexing.Lexbuf) e = let m = lexbuf.LexemeRange args.errorLogger.ErrorR(Error(e,m)) PPParser.EOF diff --git a/src/fsharp/pppars.fsy b/src/fsharp/pppars.fsy index 354fd0ac38f..5775c898670 100644 --- a/src/fsharp/pppars.fsy +++ b/src/fsharp/pppars.fsy @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. %{ -open FSharp.Compiler.Ast open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax let dummy = IfdefId("DUMMY") diff --git a/src/fsharp/range.fs b/src/fsharp/range.fs index 2de5498d551..b9d43ee376b 100755 --- a/src/fsharp/range.fs +++ b/src/fsharp/range.fs @@ -1,37 +1,41 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -/// Anything to do with special names of identifiers and other lexical rules -module FSharp.Compiler.Range +/// Anything to do with special names of identifiers and other lexical rules +namespace FSharp.Compiler.Text open System open System.IO open System.Collections.Concurrent +open System.Collections.Generic open Microsoft.FSharp.Core.Printf -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Lib -open FSharp.Compiler.Lib.Bits +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras.Bits +open FSharp.Compiler.IO +open Internal.Utilities.Library.Extras -type FileIndex = int32 +type FileIndex = int32 -[] -let columnBitCount = 20 +[] +module PosImpl = + [] + let columnBitCount = 20 -[] -let lineBitCount = 31 + [] + let lineBitCount = 31 -let posBitCount = lineBitCount + columnBitCount + let posBitCount = lineBitCount + columnBitCount -let posColumnMask = mask64 0 columnBitCount + let posColumnMask = mask64 0 columnBitCount -let lineColumnMask = mask64 columnBitCount lineBitCount + let lineColumnMask = mask64 columnBitCount lineBitCount [] [] -type pos(code:int64) = +type Position(code:int64) = - new (l, c) = - let l = max 0 l - let c = max 0 c + new (l, c) = + let l = max 0 l + let c = max 0 c let p = (int64 c &&& posColumnMask) ||| ((int64 l <<< columnBitCount) &&& lineColumnMask) pos p @@ -44,100 +48,119 @@ type pos(code:int64) = static member EncodingSize = posBitCount - static member Decode (code:int64) : pos = pos code + static member Decode (code:int64) : pos = Position(code) - override p.Equals(obj) = match obj with :? pos as p2 -> code = p2.Encoding | _ -> false + override p.Equals(obj) = match obj with :? Position as p2 -> code = p2.Encoding | _ -> false override p.GetHashCode() = hash code override p.ToString() = sprintf "(%d,%d)" p.Line p.Column -[] -let fileIndexBitCount = 24 + member p.IsAdjacentTo(otherPos: Position) = + p.Line = otherPos.Line && p.Column + 1 = otherPos.Column -[] -let startColumnBitCount = columnBitCount // 20 +and pos = Position -[] -let endColumnBitCount = columnBitCount // 20 +[] +type RangeDebugPointKind = + | None + | While + | For + | Try + | Binding + | Finally -[] -let startLineBitCount = lineBitCount // 31 +[] +module RangeImpl = + [] + let fileIndexBitCount = 24 -[] -let heightBitCount = 27 + [] + let startColumnBitCount = columnBitCount // 20 -[] -let isSyntheticBitCount = 1 + [] + let endColumnBitCount = columnBitCount // 20 -[] -let fileIndexShift = 0 + [] + let startLineBitCount = lineBitCount // 31 -[] -let startColumnShift = 24 + [] + let heightBitCount = 27 -[] -let endColumnShift = 44 + [] + let isSyntheticBitCount = 1 -[] -let startLineShift = 0 + [] + let debugPointKindBitCount = 3 -[] -let heightShift = 31 + [] + let fileIndexShift = 0 -[] -let isSyntheticShift = 58 + [] + let startColumnShift = 24 -[] -let fileIndexMask = 0b0000000000000000000000000000000000000000111111111111111111111111L + [] + let endColumnShift = 44 -[] -let startColumnMask = 0b0000000000000000000011111111111111111111000000000000000000000000L + [] + let startLineShift = 0 -[] -let endColumnMask = 0b1111111111111111111100000000000000000000000000000000000000000000L + [] + let heightShift = 31 -[] -let startLineMask = 0b0000000000000000000000000000000001111111111111111111111111111111L + [] + let isSyntheticShift = 58 -[] -let heightMask = 0b0000001111111111111111111111111110000000000000000000000000000000L + [] + let debugPointKindShift = 59 -[] -let isSyntheticMask = 0b0000010000000000000000000000000000000000000000000000000000000000L + [] + let fileIndexMask = 0b0000000000000000000000000000000000000000111111111111111111111111L -#if DEBUG -let _ = assert (posBitCount <= 64) -let _ = assert (fileIndexBitCount + startColumnBitCount + endColumnBitCount <= 64) -let _ = assert (startLineBitCount + heightBitCount + isSyntheticBitCount <= 64) + [] + let startColumnMask = 0b0000000000000000000011111111111111111111000000000000000000000000L -let _ = assert (startColumnShift = fileIndexShift + fileIndexBitCount) -let _ = assert (endColumnShift = startColumnShift + startColumnBitCount) + [] + let endColumnMask = 0b1111111111111111111100000000000000000000000000000000000000000000L -let _ = assert (heightShift = startLineShift + startLineBitCount) -let _ = assert (isSyntheticShift = heightShift + heightBitCount) + [] + let startLineMask = 0b0000000000000000000000000000000001111111111111111111111111111111L -let _ = assert (fileIndexMask = mask64 fileIndexShift fileIndexBitCount) -let _ = assert (startLineMask = mask64 startLineShift startLineBitCount) -let _ = assert (startColumnMask = mask64 startColumnShift startColumnBitCount) -let _ = assert (heightMask = mask64 heightShift heightBitCount) -let _ = assert (endColumnMask = mask64 endColumnShift endColumnBitCount) -let _ = assert (isSyntheticMask = mask64 isSyntheticShift isSyntheticBitCount) -#endif + [] + let heightMask = 0b0000001111111111111111111111111110000000000000000000000000000000L + + [] + let isSyntheticMask = 0b0000010000000000000000000000000000000000000000000000000000000000L + + [] + let debugPointKindMask= 0b0011100000000000000000000000000000000000000000000000000000000000L + + #if DEBUG + let _ = assert (posBitCount <= 64) + let _ = assert (fileIndexBitCount + startColumnBitCount + endColumnBitCount <= 64) + let _ = assert (startLineBitCount + heightBitCount + isSyntheticBitCount + debugPointKindBitCount <= 64) + + let _ = assert (startColumnShift = fileIndexShift + fileIndexBitCount) + let _ = assert (endColumnShift = startColumnShift + startColumnBitCount) + + let _ = assert (heightShift = startLineShift + startLineBitCount) + let _ = assert (isSyntheticShift = heightShift + heightBitCount) + let _ = assert (debugPointKindShift = isSyntheticShift + isSyntheticBitCount) + + let _ = assert (fileIndexMask = mask64 fileIndexShift fileIndexBitCount) + let _ = assert (startLineMask = mask64 startLineShift startLineBitCount) + let _ = assert (startColumnMask = mask64 startColumnShift startColumnBitCount) + let _ = assert (heightMask = mask64 heightShift heightBitCount) + let _ = assert (endColumnMask = mask64 endColumnShift endColumnBitCount) + let _ = assert (isSyntheticMask = mask64 isSyntheticShift isSyntheticBitCount) + let _ = assert (debugPointKindMask = mask64 debugPointKindShift debugPointKindBitCount) + #endif -/// Removes relative parts from any full paths -let normalizeFilePath (filePath: string) = - try - if FileSystem.IsPathRootedShim filePath then - FileSystem.GetFullPathShim filePath - else - filePath - with _ -> filePath /// A unique-index table for file names. -type FileIndexTable() = - let indexToFileTable = new ResizeArray<_>(11) - let fileToIndexTable = new ConcurrentDictionary() +type FileIndexTable() = + let indexToFileTable = ResizeArray<_>(11) + let fileToIndexTable = ConcurrentDictionary() // Note: we should likely adjust this code to always normalize. However some testing (and possibly some // product behaviour) appears to be sensitive to error messages reporting un-normalized file names. @@ -145,78 +168,74 @@ type FileIndexTable() = // do not. Also any file names which are not put into ranges at all are non-normalized. // // TO move forward we should eventually introduce a new type NormalizedFileName that tracks this invariant. - member t.FileToIndex normalize filePath = - match fileToIndexTable.TryGetValue filePath with + member t.FileToIndex normalize filePath = + match fileToIndexTable.TryGetValue filePath with | true, idx -> idx - | _ -> - + | _ -> + // Try again looking for a normalized entry. - let normalizedFilePath = if normalize then normalizeFilePath filePath else filePath - match fileToIndexTable.TryGetValue normalizedFilePath with + let normalizedFilePath = if normalize then FileSystem.NormalizePathShim filePath else filePath + match fileToIndexTable.TryGetValue normalizedFilePath with | true, idx -> // Record the non-normalized entry if necessary - if filePath <> normalizedFilePath then - lock fileToIndexTable (fun () -> + if filePath <> normalizedFilePath then + lock fileToIndexTable (fun () -> fileToIndexTable.[filePath] <- idx) - + // Return the index idx - - | _ -> - lock fileToIndexTable (fun () -> + + | _ -> + lock fileToIndexTable (fun () -> // Get the new index let idx = indexToFileTable.Count - + // Record the normalized entry indexToFileTable.Add normalizedFilePath fileToIndexTable.[normalizedFilePath] <- idx - + // Record the non-normalized entry if necessary - if filePath <> normalizedFilePath then + if filePath <> normalizedFilePath then fileToIndexTable.[filePath] <- idx // Return the index idx) - member t.IndexToFile n = - if n < 0 then + member t.IndexToFile n = + if n < 0 then failwithf "fileOfFileIndex: negative argument: n = %d\n" n if n >= indexToFileTable.Count then failwithf "fileOfFileIndex: invalid argument: n = %d\n" n indexToFileTable.[n] -let maxFileIndex = pown32 fileIndexBitCount - -// ++GLOBAL MUTABLE STATE -// WARNING: Global Mutable State, holding a mapping between integers and filenames -let fileIndexTable = new FileIndexTable() +[] +module FileIndex = + let maxFileIndex = pown32 fileIndexBitCount -// If we exceed the maximum number of files we'll start to report incorrect file names -let fileIndexOfFileAux normalize f = fileIndexTable.FileToIndex normalize f % maxFileIndex + // ++GLOBAL MUTABLE STATE + // WARNING: Global Mutable State, holding a mapping between integers and filenames + let fileIndexTable = FileIndexTable() -let fileIndexOfFile filePath = fileIndexOfFileAux false filePath + // If we exceed the maximum number of files we'll start to report incorrect file names + let fileIndexOfFileAux normalize f = fileIndexTable.FileToIndex normalize f % maxFileIndex -let fileOfFileIndex idx = fileIndexTable.IndexToFile idx + let fileIndexOfFile filePath = fileIndexOfFileAux false filePath -let mkPos l c = pos (l, c) + let fileOfFileIndex idx = fileIndexTable.IndexToFile idx -let unknownFileName = "unknown" -let startupFileName = "startup" -let commandLineArgsFileName = "commandLineArgs" + let unknownFileName = "unknown" + let startupFileName = "startup" + let commandLineArgsFileName = "commandLineArgs" [] -#if DEBUG -[ {DebugCode}")>] -#else -[] -#endif -type range(code1:int64, code2: int64) = +[ {DebugCode}")>] +type Range(code1:int64, code2: int64) = static member Zero = range(0L, 0L) - new (fIdx, bl, bc, el, ec) = + new (fIdx, bl, bc, el, ec) = let code1 = ((int64 fIdx) &&& fileIndexMask) ||| ((int64 bc <<< startColumnShift) &&& startColumnMask) ||| ((int64 ec <<< endColumnShift) &&& endColumnMask) - let code2 = + let code2 = ((int64 bl <<< startLineShift) &&& startLineMask) ||| ((int64 (el-bl) <<< heightShift) &&& heightMask) range(code1, code2) @@ -225,13 +244,22 @@ type range(code1:int64, code2: int64) = member r.StartLine = int32((code2 &&& startLineMask) >>> startLineShift) - member r.StartColumn = int32((code1 &&& startColumnMask) >>> startColumnShift) + member r.StartColumn = int32((code1 &&& startColumnMask) >>> startColumnShift) member r.EndLine = int32((code2 &&& heightMask) >>> heightShift) + r.StartLine member r.EndColumn = int32((code1 &&& endColumnMask) >>> endColumnShift) - member r.IsSynthetic = int32((code2 &&& isSyntheticMask) >>> isSyntheticShift) <> 0 + member r.IsSynthetic = int32((code2 &&& isSyntheticMask) >>> isSyntheticShift) <> 0 + + member r.DebugPointKind = + match int32((code2 &&& debugPointKindMask) >>> debugPointKindShift) with + | 1 -> RangeDebugPointKind.While + | 2 -> RangeDebugPointKind.For + | 3 -> RangeDebugPointKind.Try + | 4 -> RangeDebugPointKind.Finally + | 5 -> RangeDebugPointKind.Binding + | _ -> RangeDebugPointKind.None member r.Start = pos (r.StartLine, r.StartColumn) @@ -245,13 +273,28 @@ type range(code1:int64, code2: int64) = member r.FileName = fileOfFileIndex r.FileIndex + member r.ShortFileName = Path.GetFileName(fileOfFileIndex r.FileIndex) + member r.MakeSynthetic() = range(code1, code2 ||| isSyntheticMask) + member r.IsAdjacentTo(otherRange: Range) = + r.FileIndex = otherRange.FileIndex && r.End.Encoding = otherRange.Start.Encoding + + member r.NoteDebugPoint(kind) = + let code = + match kind with + | RangeDebugPointKind.None -> 0 + | RangeDebugPointKind.While -> 1 + | RangeDebugPointKind.For -> 2 + | RangeDebugPointKind.Try -> 3 + | RangeDebugPointKind.Finally -> 4 + | RangeDebugPointKind.Binding -> 5 + range(code1, code2 ||| (int64 code <<< debugPointKindShift)) + member r.Code1 = code1 member r.Code2 = code2 -#if DEBUG member r.DebugCode = let name = r.FileName if name = unknownFileName || name = startupFileName || name = commandLineArgsFileName then name else @@ -260,16 +303,15 @@ type range(code1:int64, code2: int64) = let endCol = r.EndColumn - 1 let startCol = r.StartColumn - 1 if FileSystem.IsInvalidPathShim r.FileName then "path invalid: " + r.FileName - elif not (FileSystem.SafeExists r.FileName) then "non existing file: " + r.FileName + elif not (FileSystem.FileExistsShim r.FileName) then "non existing file: " + r.FileName else - File.ReadAllLines(r.FileName) + FileSystem.OpenFileForReadShim(r.FileName).ReadLines() |> Seq.skip (r.StartLine - 1) |> Seq.take (r.EndLine - r.StartLine + 1) |> String.concat "\n" |> fun s -> s.Substring(startCol + 1, s.LastIndexOf("\n", StringComparison.Ordinal) + 1 - startCol + endCol) with e -> - e.ToString() -#endif + e.ToString() member r.ToShortString() = sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn @@ -277,107 +319,137 @@ type range(code1:int64, code2: int64) = override r.GetHashCode() = hash code1 + hash code2 - override r.ToString() = sprintf "%s (%d,%d--%d,%d) IsSynthetic=%b" r.FileName r.StartLine r.StartColumn r.EndLine r.EndColumn r.IsSynthetic + override r.ToString() = sprintf "%s (%d,%d--%d,%d)" r.FileName r.StartLine r.StartColumn r.EndLine r.EndColumn + +and range = Range + +#if CHECK_LINE0_TYPES // turn on to check that we correctly transform zero-based line counts to one-based line counts +// Visual Studio uses line counts starting at 0, F# uses them starting at 1 +[] type ZeroBasedLineAnnotation + +type Line0 = int +#else +type Line0 = int +#endif -let mkRange filePath startPos endPos = range (fileIndexOfFileAux true filePath, startPos, endPos) +type Position01 = Line0 * int -let equals (r1: range) (r2: range) = - r1.Code1 = r2.Code1 && r1.Code2 = r2.Code2 +type Range01 = Position01 * Position01 -let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos) +module Line = -let posOrder = Order.orderOn (fun (p:pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order)) + let fromZ (line:Line0) = int line+1 -/// rangeOrder: not a total order, but enough to sort on ranges -let rangeOrder = Order.orderOn (fun (r:range) -> r.FileName, r.Start) (Pair.order (String.order, posOrder)) + let toZ (line:int) : Line0 = LanguagePrimitives.Int32WithMeasure(line - 1) -let outputPos (os:TextWriter) (m:pos) = fprintf os "(%d,%d)" m.Line m.Column +[] +module Position = -let outputRange (os:TextWriter) (m:range) = fprintf os "%s%a-%a" m.FileName outputPos m.Start outputPos m.End - -let posGt (p1:pos) (p2:pos) = (p1.Line > p2.Line || (p1.Line = p2.Line && p1.Column > p2.Column)) + let mkPos line column = Position (line, column) -let posEq (p1:pos) (p2:pos) = (p1.Line = p2.Line && p1.Column = p2.Column) + let outputPos (os:TextWriter) (m:pos) = fprintf os "(%d,%d)" m.Line m.Column -let posGeq p1 p2 = posEq p1 p2 || posGt p1 p2 + let posGt (p1: pos) (p2: pos) = + let p1Line = p1.Line + let p2Line = p2.Line + p1Line > p2Line || p1Line = p2Line && p1.Column > p2.Column -let posLt p1 p2 = posGt p2 p1 + let posEq (p1: pos) (p2: pos) = p1.Encoding = p2.Encoding -/// This is deliberately written in an allocation-free way, i.e. m1.Start, m1.End etc. are not called -let unionRanges (m1:range) (m2:range) = - if m1.FileIndex <> m2.FileIndex then m2 else - let b = - if (m1.StartLine > m2.StartLine || (m1.StartLine = m2.StartLine && m1.StartColumn > m2.StartColumn)) then m2 - else m1 - let e = - if (m1.EndLine > m2.EndLine || (m1.EndLine = m2.EndLine && m1.EndColumn > m2.EndColumn)) then m1 - else m2 - range (m1.FileIndex, b.StartLine, b.StartColumn, e.EndLine, e.EndColumn) + let posGeq p1 p2 = posEq p1 p2 || posGt p1 p2 -let rangeContainsRange (m1:range) (m2:range) = - m1.FileIndex = m2.FileIndex && - posGeq m2.Start m1.Start && - posGeq m1.End m2.End + let posLt p1 p2 = posGt p2 p1 -let rangeContainsPos (m1:range) p = - posGeq p m1.Start && - posGeq m1.End p + let fromZ (line:Line0) column = mkPos (Line.fromZ line) column -let rangeBeforePos (m1:range) p = - posGeq p m1.End + let toZ (p:pos) = (Line.toZ p.Line, p.Column) -let rangeN filename line = mkRange filename (mkPos line 0) (mkPos line 0) + (* For Diagnostics *) + let stringOfPos (pos:pos) = sprintf "(%d,%d)" pos.Line pos.Column -let pos0 = mkPos 1 0 + let pos0 = mkPos 1 0 -let range0 = rangeN unknownFileName 1 +module Range = + let mkRange filePath startPos endPos = range (fileIndexOfFileAux true filePath, startPos, endPos) -let rangeStartup = rangeN startupFileName 1 + let equals (r1: range) (r2: range) = + r1.Code1 = r2.Code1 && r1.Code2 = r2.Code2 -let rangeCmdArgs = rangeN commandLineArgsFileName 0 + let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos) -let trimRangeToLine (r:range) = - let startL, startC = r.StartLine, r.StartColumn - let endL, _endC = r.EndLine, r.EndColumn - if endL <= startL then - r - else - let endL, endC = startL+1, 0 (* Trim to the start of the next line (we do not know the end of the current line) *) - range (r.FileIndex, startL, startC, endL, endC) + let posOrder = Order.orderOn (fun (p:pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order)) -(* For Diagnostics *) -let stringOfPos (pos:pos) = sprintf "(%d,%d)" pos.Line pos.Column + /// rangeOrder: not a total order, but enough to sort on ranges + let rangeOrder = Order.orderOn (fun (r:range) -> r.FileName, r.Start) (Pair.order (String.order, posOrder)) -let stringOfRange (r:range) = sprintf "%s%s-%s" r.FileName (stringOfPos r.Start) (stringOfPos r.End) + let outputRange (os:TextWriter) (m:range) = fprintf os "%s%a-%a" m.FileName outputPos m.Start outputPos m.End -#if CHECK_LINE0_TYPES // turn on to check that we correctly transform zero-based line counts to one-based line counts -// Visual Studio uses line counts starting at 0, F# uses them starting at 1 -[] type ZeroBasedLineAnnotation + /// This is deliberately written in an allocation-free way, i.e. m1.Start, m1.End etc. are not called + let unionRanges (m1:range) (m2:range) = + if m1.FileIndex <> m2.FileIndex then m2 else + + // If all identical then return m1. This preserves DebugPointKind when no merging takes place + if m1.Code1 = m2.Code1 && m1.Code2 = m2.Code2 then m1 else -type Line0 = int -#else -type Line0 = int -#endif -type Pos01 = Line0 * int -type Range01 = Pos01 * Pos01 + let b = + if (m1.StartLine > m2.StartLine || (m1.StartLine = m2.StartLine && m1.StartColumn > m2.StartColumn)) then m2 + else m1 + let e = + if (m1.EndLine > m2.EndLine || (m1.EndLine = m2.EndLine && m1.EndColumn > m2.EndColumn)) then m1 + else m2 + let m = range (m1.FileIndex, b.StartLine, b.StartColumn, e.EndLine, e.EndColumn) + if m1.IsSynthetic || m2.IsSynthetic then m.MakeSynthetic() else m -module Line = + let rangeContainsRange (m1:range) (m2:range) = + m1.FileIndex = m2.FileIndex && + posGeq m2.Start m1.Start && + posGeq m1.End m2.End - // Visual Studio uses line counts starting at 0, F# uses them starting at 1 - let fromZ (line:Line0) = int line+1 + let rangeContainsPos (m1:range) p = + posGeq p m1.Start && + posGeq m1.End p - let toZ (line:int) : Line0 = LanguagePrimitives.Int32WithMeasure(line - 1) + let rangeBeforePos (m1:range) p = + posGeq p m1.End -module Pos = + let rangeN filename line = mkRange filename (mkPos line 0) (mkPos line 0) - let fromZ (line:Line0) idx = mkPos (Line.fromZ line) idx + let range0 = rangeN unknownFileName 1 - let toZ (p:pos) = (Line.toZ p.Line, p.Column) + let rangeStartup = rangeN startupFileName 1 -module Range = + let rangeCmdArgs = rangeN commandLineArgsFileName 0 + + let trimRangeToLine (r:range) = + let startL, startC = r.StartLine, r.StartColumn + let endL, _endC = r.EndLine, r.EndColumn + if endL <= startL then + r + else + let endL, endC = startL+1, 0 (* Trim to the start of the next line (we do not know the end of the current line) *) + range (r.FileIndex, startL, startC, endL, endC) + + let stringOfRange (r:range) = sprintf "%s%s-%s" r.FileName (stringOfPos r.Start) (stringOfPos r.End) - let toZ (m:range) = Pos.toZ m.Start, Pos.toZ m.End + let toZ (m:range) = toZ m.Start, toZ m.End let toFileZ (m:range) = m.FileName, toZ m + let comparer = + { new IEqualityComparer with + member _.Equals(x1, x2) = equals x1 x2 + member _.GetHashCode o = o.GetHashCode() } + let mkFirstLineOfFile (file: string) = + try + let lines = FileSystem.OpenFileForReadShim(file).ReadLines() |> Seq.indexed + let nonWhiteLine = lines |> Seq.tryFind (fun (_,s) -> not (String.IsNullOrWhiteSpace s)) + match nonWhiteLine with + | Some (i,s) -> mkRange file (mkPos (i+1) 0) (mkPos (i+1) s.Length) + | None -> + let nonEmptyLine = lines |> Seq.tryFind (fun (_,s) -> not (String.IsNullOrEmpty s)) + match nonEmptyLine with + | Some (i,s) -> mkRange file (mkPos (i+1) 0) (mkPos (i+1) s.Length) + | None -> mkRange file (mkPos 1 0) (mkPos 1 80) + with _ -> + mkRange file (mkPos 1 0) (mkPos 1 80) diff --git a/src/fsharp/range.fsi b/src/fsharp/range.fsi index fdb63ec2a29..8913f498b07 100755 --- a/src/fsharp/range.fsi +++ b/src/fsharp/range.fsi @@ -1,74 +1,68 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module public FSharp.Compiler.Range +/// The Range and Pos types form part of the public API of FSharp.Compiler.Service +namespace FSharp.Compiler.Text -open System.Text open System.Collections.Generic -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler - /// An index into a global tables of filenames -type FileIndex = int32 - -/// Convert a file path to an index -val fileIndexOfFile : filePath: string -> FileIndex +type internal FileIndex = int32 -/// Convert an index into a file path -val fileOfFileIndex : FileIndex -> string +[] +type internal RangeDebugPointKind = + | None + | While + | For + | Try + | Binding + | Finally /// Represents a position in a file [] -type pos = +type Position = /// The line number for the position - member Line : int + member Line: int /// The column number for the position - member Column : int + member Column: int /// The encoding of the position as a 64-bit integer - member Encoding : int64 + member internal Encoding: int64 + + /// Check if the position is adjacent to another postition + member internal IsAdjacentTo: otherPos: Position -> bool /// Decode a position fro a 64-bit integer - static member Decode : int64 -> pos + static member internal Decode: int64 -> pos /// The maximum number of bits needed to store an encoded position - static member EncodingSize : int - -/// Create a position for the given line and column -val mkPos : line:int -> column:int -> pos + static member internal EncodingSize: int -/// Ordering on positions -val posOrder : IComparer - -val unknownFileName: string -val startupFileName: string -val commandLineArgsFileName: string +/// Represents a position in a file +and pos = Position -/// Represents a range within a known file +/// Represents a range within a file [] -type range = +type Range = /// The start line of the range - member StartLine : int + member StartLine: int /// The start column of the range - member StartColumn : int + member StartColumn: int /// The line number for the end position of the range - member EndLine : int + member EndLine: int /// The column number for the end position of the range - member EndColumn : int + member EndColumn: int /// The start position of the range - member Start : pos + member Start: pos /// The end position of the range - member End : pos + member End: pos /// The empty range that is located at the start position of the range member StartRange: range @@ -77,126 +71,164 @@ type range = member EndRange: range /// The file index for the range - member FileIndex : int + member internal FileIndex: int /// The file name for the file of the range - member FileName : string + member FileName: string /// Synthetic marks ranges which are produced by intermediate compilation phases. This /// bit signifies that the range covers something that should not be visible to language /// service operations like dot-completion. - member IsSynthetic : bool + member IsSynthetic: bool + + /// When de-sugaring computation expressions we convert a debug point into a plain range, and then later + /// recover that the range definitely indicates a debug point. + member internal DebugPointKind: RangeDebugPointKind /// Convert a range to be synthetic - member MakeSynthetic : unit -> range + member internal MakeSynthetic: unit -> range + + /// Note that a range indicates a debug point + member internal NoteDebugPoint: kind: RangeDebugPointKind -> range + + /// Check if the range is adjacent to another range + member internal IsAdjacentTo: otherRange: Range -> bool /// Convert a range to string - member ToShortString : unit -> string + member internal ToShortString: unit -> string /// The range where all values are zero - static member Zero : range + static member Zero: range -/// This view of range marks uses file indexes explicitly -val mkFileIndexRange : FileIndex -> pos -> pos -> range +/// Represents a range within a file +and range = Range -/// This view hides the use of file indexes and just uses filenames -val mkRange : string -> pos -> pos -> range +/// Represents a line number when using zero-based line counting (used by Visual Studio) +#if CHECK_LINE0_TYPES +// Visual Studio uses line counts starting at 0, F# uses them starting at 1 +[] type ZeroBasedLineAnnotation -val equals : range -> range -> bool +type Line0 = int +#else +type Line0 = int +#endif -/// Reduce a range so it only covers a line -val trimRangeToLine : range -> range +/// Represents a position using zero-based line counting (used by Visual Studio) +type Position01 = Line0 * int -/// not a total order, but enough to sort on ranges -val rangeOrder : IComparer +/// Represents a range using zero-based line counting (used by Visual Studio) +type Range01 = Position01 * Position01 -/// Output a position -val outputPos : System.IO.TextWriter -> pos -> unit +module Position = + /// Create a position for the given line and column + val mkPos: line:int -> column:int -> pos -/// Output a range -val outputRange : System.IO.TextWriter -> range -> unit - -/// Compare positions for less-than -val posLt : pos -> pos -> bool + /// Compare positions for less-than + val posLt: pos -> pos -> bool -/// Compare positions for greater-than -val posGt : pos -> pos -> bool + /// Compare positions for greater-than + val posGt: pos -> pos -> bool -/// Compare positions for equality -val posEq : pos -> pos -> bool + /// Compare positions for equality + val posEq: pos -> pos -> bool -/// Compare positions for greater-than-or-equal-to -val posGeq : pos -> pos -> bool + /// Compare positions for greater-than-or-equal-to + val posGeq: pos -> pos -> bool -/// Union two ranges, taking their first occurring start position and last occurring end position -val unionRanges : range -> range -> range + /// Convert a position from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) + val fromZ: line:Line0 -> column:int -> pos -/// Test to see if one range contains another range -val rangeContainsRange : range -> range -> bool + /// Convert a position from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) + val toZ: pos -> Position01 -/// Test to see if a range contains a position -val rangeContainsPos : range -> pos -> bool + /// Output a position + val outputPos: System.IO.TextWriter -> pos -> unit -/// Test to see if a range occurs fully before a position -val rangeBeforePos : range -> pos -> bool + /// Convert a position to a string + val stringOfPos: pos -> string -/// Make a dummy range for a file -val rangeN : string -> int -> range + /// The zero position + val pos0: pos -/// The zero position -val pos0 : pos +module internal FileIndex = -/// The zero range -val range0 : range + /// Convert a file path to an index + val fileIndexOfFile: filePath: string -> FileIndex -/// A range associated with a dummy file called "startup" -val rangeStartup : range + /// Convert an index into a file path + val fileOfFileIndex: FileIndex -> string -/// A range associated with a dummy file for the command line arguments -val rangeCmdArgs : range - -/// Convert a position to a string -val stringOfPos : pos -> string + val startupFileName: string -/// Convert a range to a string -val stringOfRange : range -> string +module Range = -/// Represents a line number when using zero-based line counting (used by Visual Studio) -#if CHECK_LINE0_TYPES -// Visual Studio uses line counts starting at 0, F# uses them starting at 1 -[] type ZeroBasedLineAnnotation + /// Ordering on positions + val posOrder: IComparer -type Line0 = int -#else -type Line0 = int -#endif + /// This view of range marks uses file indexes explicitly + val mkFileIndexRange: FileIndex -> pos -> pos -> range -/// Represents a position using zero-based line counting (used by Visual Studio) -type Pos01 = Line0 * int + /// This view hides the use of file indexes and just uses filenames + val mkRange: string -> pos -> pos -> range -/// Represents a range using zero-based line counting (used by Visual Studio) -type Range01 = Pos01 * Pos01 + /// Make a range for the first non-whitespace line of the file if any. Otherwise use line 1 chars 0-80. + /// This involves reading the file. + val mkFirstLineOfFile: string -> range -module Line = + val equals: range -> range -> bool - /// Convert a line number from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) - val fromZ : Line0 -> int + /// Reduce a range so it only covers a line + val trimRangeToLine: range -> range - /// Convert a line number from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) - val toZ : int -> Line0 + /// not a total order, but enough to sort on ranges + val rangeOrder: IComparer -module Pos = + /// Output a range + val outputRange: System.IO.TextWriter -> range -> unit - /// Convert a position from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) - val fromZ : line:Line0 -> column:int -> pos + /// Union two ranges, taking their first occurring start position and last occurring end position + val unionRanges: range -> range -> range - /// Convert a position from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) - val toZ : pos -> Pos01 + /// Test to see if one range contains another range + val rangeContainsRange: range -> range -> bool -module Range = + /// Test to see if a range contains a position + val rangeContainsPos: range -> pos -> bool + + /// Test to see if a range occurs fully before a position + val rangeBeforePos: range -> pos -> bool + + /// Make a dummy range for a file + val rangeN: string -> int -> range + + /// The zero range + val range0: range + + /// A range associated with a dummy file called "startup" + val rangeStartup: range + + /// A range associated with a dummy file for the command line arguments + val rangeCmdArgs: range + + /// Convert a range to a string + val stringOfRange: range -> string /// Convert a range from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) - val toZ : range -> Range01 + val toZ: range -> Range01 /// Convert a range from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) - val toFileZ : range -> string * Range01 + val toFileZ: range -> string * Range01 + + /// Equality comparer for range. + val comparer: IEqualityComparer + +/// Functions related to converting between lines indexed at 0 and 1 +module Line = + + /// Convert a line number from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) + val fromZ: Line0 -> int + + /// Convert a line number from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) + val toZ: int -> Line0 + + diff --git a/src/fsharp/rational.fs b/src/fsharp/rational.fs index 5b36a9e349e..51d7e2f6eb0 100644 --- a/src/fsharp/rational.fs +++ b/src/fsharp/rational.fs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. /// Rational arithmetic, used for exponents on units-of-measure -module internal FSharp.Compiler.Rational +module internal Internal.Utilities.Rational open System.Numerics diff --git a/src/fsharp/rational.fsi b/src/fsharp/rational.fsi index 30b5d6b8e7d..0bcfc6dd99e 100644 --- a/src/fsharp/rational.fsi +++ b/src/fsharp/rational.fsi @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. /// Rational arithmetic, used for exponents on units-of-measure -module internal FSharp.Compiler.Rational +module internal Internal.Utilities.Rational type Rational diff --git a/src/fsharp/service/ExternalSymbol.fs b/src/fsharp/service/ExternalSymbol.fs index c0b4352c473..f91a586cd48 100644 --- a/src/fsharp/service/ExternalSymbol.fs +++ b/src/fsharp/service/ExternalSymbol.fs @@ -1,12 +1,13 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices open FSharp.Reflection +open FSharp.Compiler.Text open FSharp.Compiler.AbstractIL.IL open System.Diagnostics -module private Option = +module Option = let ofOptionList (xs : 'a option list) : 'a list option = @@ -17,15 +18,19 @@ module private Option = /// Represents a type in an external (non F#) assembly. [] -type ExternalType = - /// Type defined in non-F# assembly. - | Type of fullName: string * genericArgs: ExternalType list - /// Array of type that is defined in non-F# assembly. - | Array of inner: ExternalType - /// Pointer defined in non-F# assembly. - | Pointer of inner: ExternalType - /// Type variable defined in non-F# assembly. +type FindDeclExternalType = + /// Type defined in non-F# assembly. + | Type of fullName: string * genericArgs: FindDeclExternalType list + + /// Array of type that is defined in non-F# assembly. + | Array of inner: FindDeclExternalType + + /// Pointer defined in non-F# assembly. + | Pointer of inner: FindDeclExternalType + + /// Type variable defined in non-F# assembly. | TypeVar of typeName: string + override this.ToString() = match this with | Type (name, genericArgs) -> @@ -41,54 +46,65 @@ type ExternalType = | Pointer inner -> sprintf "&%O" inner | TypeVar name -> sprintf "'%s" name -module ExternalType = - let rec internal tryOfILType (typeVarNames: string array) (ilType: ILType) = +module FindDeclExternalType = + let rec tryOfILType (typeVarNames: string array) (ilType: ILType) = match ilType with | ILType.Array (_, inner) -> - tryOfILType typeVarNames inner |> Option.map ExternalType.Array + tryOfILType typeVarNames inner |> Option.map FindDeclExternalType.Array | ILType.Boxed tyspec | ILType.Value tyspec -> tyspec.GenericArgs |> List.map (tryOfILType typeVarNames) |> Option.ofOptionList - |> Option.map (fun genericArgs -> ExternalType.Type (tyspec.FullName, genericArgs)) + |> Option.map (fun genericArgs -> FindDeclExternalType.Type (tyspec.FullName, genericArgs)) | ILType.Ptr inner -> - tryOfILType typeVarNames inner |> Option.map ExternalType.Pointer + tryOfILType typeVarNames inner |> Option.map FindDeclExternalType.Pointer | ILType.TypeVar ordinal -> typeVarNames |> Array.tryItem (int ordinal) - |> Option.map (fun typeVarName -> ExternalType.TypeVar typeVarName) + |> Option.map (fun typeVarName -> FindDeclExternalType.TypeVar typeVarName) | _ -> None [] -type ParamTypeSymbol = - | Param of ExternalType - | Byref of ExternalType +type FindDeclExternalParam = + + | Param of parameterType: FindDeclExternalType + + | Byref of parameterType: FindDeclExternalType + + member c.IsByRef = match c with Byref _ -> true | _ -> false + + member c.ParameterType = match c with Byref ty -> ty | Param ty -> ty + + static member Create(parameterType, isByRef) = + if isByRef then Byref parameterType else Param parameterType + override this.ToString () = match this with | Param t -> t.ToString() | Byref t -> sprintf "ref %O" t -module ParamTypeSymbol = - let rec internal tryOfILType (typeVarNames : string array) = +module FindDeclExternalParam = + let tryOfILType (typeVarNames : string array) = function - | ILType.Byref inner -> ExternalType.tryOfILType typeVarNames inner |> Option.map ParamTypeSymbol.Byref - | ilType -> ExternalType.tryOfILType typeVarNames ilType |> Option.map ParamTypeSymbol.Param + | ILType.Byref inner -> FindDeclExternalType.tryOfILType typeVarNames inner |> Option.map FindDeclExternalParam.Byref + | ilType -> FindDeclExternalType.tryOfILType typeVarNames ilType |> Option.map FindDeclExternalParam.Param - let internal tryOfILTypes typeVarNames ilTypes = + let tryOfILTypes typeVarNames ilTypes = ilTypes |> List.map (tryOfILType typeVarNames) |> Option.ofOptionList [] [] -type ExternalSymbol = +type FindDeclExternalSymbol = | Type of fullName: string - | Constructor of typeName: string * args: ParamTypeSymbol list - | Method of typeName: string * name: string * paramSyms: ParamTypeSymbol list * genericArity: int + | Constructor of typeName: string * args: FindDeclExternalParam list + | Method of typeName: string * name: string * paramSyms: FindDeclExternalParam list * genericArity: int | Field of typeName: string * name: string | Event of typeName: string * name: string | Property of typeName: string * name: string + override this.ToString () = match this with | Type fullName -> fullName @@ -111,6 +127,34 @@ type ExternalSymbol = | Property (typeName, name) -> sprintf "%s.%s" typeName name - member internal this.ToDebuggerDisplay () = - let caseInfo, _ = FSharpValue.GetUnionFields(this, typeof) + member this.ToDebuggerDisplay () = + let caseInfo, _ = FSharpValue.GetUnionFields(this, typeof) sprintf "%s %O" caseInfo.Name this + +[] +type FindDeclFailureReason = + + // generic reason: no particular information about error + | Unknown of message: string + + // source code file is not available + | NoSourceCode + + // trying to find declaration of ProvidedType without TypeProviderDefinitionLocationAttribute + | ProvidedType of typeName: string + + // trying to find declaration of ProvidedMember without TypeProviderDefinitionLocationAttribute + | ProvidedMember of memberName: string + +[] +type FindDeclResult = + + /// declaration not found + reason + | DeclNotFound of FindDeclFailureReason + + /// found declaration + | DeclFound of location: range + + /// Indicates an external declaration was found + | ExternalDecl of assembly : string * externalSym : FindDeclExternalSymbol + diff --git a/src/fsharp/service/ExternalSymbol.fsi b/src/fsharp/service/ExternalSymbol.fsi index 36d290db4d0..1a0492d3c27 100644 --- a/src/fsharp/service/ExternalSymbol.fsi +++ b/src/fsharp/service/ExternalSymbol.fsi @@ -1,47 +1,93 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Reflection +open FSharp.Compiler.Text open FSharp.Compiler.AbstractIL.IL /// Represents a type in an external (non F#) assembly. [] -type ExternalType = - /// Type defined in non-F# assembly. - | Type of fullName: string * genericArgs: ExternalType list - /// Array of type that is defined in non-F# assembly. - | Array of inner: ExternalType - /// Pointer defined in non-F# assembly. - | Pointer of inner: ExternalType - /// Type variable defined in non-F# assembly. +type public FindDeclExternalType = + /// Type defined in non-F# assembly. + | Type of fullName: string * genericArgs: FindDeclExternalType list + + /// Array of type that is defined in non-F# assembly. + | Array of inner: FindDeclExternalType + + /// Pointer defined in non-F# assembly. + | Pointer of inner: FindDeclExternalType + + /// Type variable defined in non-F# assembly. | TypeVar of typeName: string + override ToString : unit -> string -module ExternalType = - val internal tryOfILType : string array -> ILType -> ExternalType option - +module internal FindDeclExternalType = + val internal tryOfILType : string array -> ILType -> FindDeclExternalType option /// Represents the type of a single method parameter -[] -type ParamTypeSymbol = - | Param of ExternalType - | Byref of ExternalType +[] +type public FindDeclExternalParam = + + member IsByRef: bool + + member ParameterType: FindDeclExternalType + + static member Create: parameterType: FindDeclExternalType * isByRef: bool -> FindDeclExternalParam + override ToString : unit -> string -module ParamTypeSymbol = - val internal tryOfILType : string array -> ILType -> ParamTypeSymbol option - val internal tryOfILTypes : string array -> ILType list -> ParamTypeSymbol list option - +module internal FindDeclExternalParam = + + val internal tryOfILType : string array -> ILType -> FindDeclExternalParam option + + val internal tryOfILTypes : string array -> ILType list -> FindDeclExternalParam list option /// Represents a symbol in an external (non F#) assembly [] -type ExternalSymbol = +type public FindDeclExternalSymbol = | Type of fullName: string - | Constructor of typeName: string * args: ParamTypeSymbol list - | Method of typeName: string * name: string * paramSyms: ParamTypeSymbol list * genericArity: int + + | Constructor of typeName: string * args: FindDeclExternalParam list + + | Method of typeName: string * name: string * paramSyms: FindDeclExternalParam list * genericArity: int + | Field of typeName: string * name: string + | Event of typeName: string * name: string + | Property of typeName: string * name: string + override ToString : unit -> string - member internal ToDebuggerDisplay : unit -> string \ No newline at end of file + + member internal ToDebuggerDisplay : unit -> string + +/// Represents the reason why the GetDeclarationLocation operation failed. +[] +type public FindDeclFailureReason = + + /// Generic reason: no particular information about error apart from a message + | Unknown of message: string + + /// Source code file is not available + | NoSourceCode + + /// Trying to find declaration of ProvidedType without TypeProviderDefinitionLocationAttribute + | ProvidedType of typeName: string + + /// Trying to find declaration of ProvidedMember without TypeProviderDefinitionLocationAttribute + | ProvidedMember of memberName: string + +/// Represents the result of the GetDeclarationLocation operation. +[] +type public FindDeclResult = + + /// Indicates a declaration location was not found, with an additional reason + | DeclNotFound of FindDeclFailureReason + + /// Indicates a declaration location was found + | DeclFound of location: range + + /// Indicates an external declaration was found + | ExternalDecl of assembly: string * externalSym : FindDeclExternalSymbol + diff --git a/src/fsharp/service/FSharpCheckerResults.fs b/src/fsharp/service/FSharpCheckerResults.fs index 76585ba9d58..ca208b7201b 100644 --- a/src/fsharp/service/FSharpCheckerResults.fs +++ b/src/fsharp/service/FSharpCheckerResults.fs @@ -3,45 +3,194 @@ // Open up the compiler as an incremental service for parsing, // type checking and intellisense-like environment-reporting. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.CodeAnalysis open System open System.Diagnostics open System.IO open System.Reflection - +open System.Threading +open FSharp.Compiler.IO +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Core.Printf -open FSharp.Compiler -open FSharp.Compiler.AbstractIL +open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library - open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOps -open FSharp.Compiler.CompileOptions +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.EditorServices.DeclarationListHelpers open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Parser -open FSharp.Compiler.Range -open FSharp.Compiler.Lexhelp -open FSharp.Compiler.Layout -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Text open FSharp.Compiler.Infos open FSharp.Compiler.InfoReader +open FSharp.Compiler.Lexhelp open FSharp.Compiler.NameResolution -open FSharp.Compiler.TypeChecker -open FSharp.Compiler.SourceCodeServices.SymbolHelpers +open FSharp.Compiler.OptimizeInputs +open FSharp.Compiler.Parser +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Symbols +open FSharp.Compiler.Symbols.SymbolHelpers +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.BuildGraph open Internal.Utilities open Internal.Utilities.Collections open FSharp.Compiler.AbstractIL.ILBinaryReader +type FSharpUnresolvedReferencesSet = FSharpUnresolvedReferencesSet of UnresolvedAssemblyReference list + +[] +type internal DelayedILModuleReader = + + val private name : string + val private gate : obj + val mutable private getStream : (CancellationToken -> Stream option) + val mutable private result : ILModuleReader + + new (name, getStream) = { name = name; gate = obj(); getStream = getStream; result = Unchecked.defaultof<_> } + + member this.TryGetILModuleReader() = + // fast path + match box this.result with + | null -> + cancellable { + let! ct = Cancellable.token() + return + lock this.gate (fun () -> + // see if we have a result or not after the lock so we do not evaluate the stream more than once + match box this.result with + | null -> + try + let streamOpt = this.getStream ct + match streamOpt with + | Some stream -> + let ilReaderOptions: ILReaderOptions = + { + pdbDirPath = None + reduceMemoryUsage = ReduceMemoryFlag.Yes + metadataOnly = MetadataOnlyFlag.Yes + tryGetMetadataSnapshot = fun _ -> None + } + let ilReader = OpenILModuleReaderFromStream this.name stream ilReaderOptions + this.result <- ilReader + this.getStream <- Unchecked.defaultof<_> // clear out the function so we do not hold onto anything + Some ilReader + | _ -> + None + with + | ex -> + Trace.TraceInformation("FCS: Unable to get an ILModuleReader: {0}", ex) + None + | _ -> + Some this.result + ) + } + | _ -> + Cancellable.ret (Some this.result) + + +[] +type FSharpReferencedProject = + | FSharpReference of projectFileName: string * options: FSharpProjectOptions + | PEReference of projectFileName: string * stamp: DateTime * delayedReader: DelayedILModuleReader + | ILModuleReference of projectFileName: string * getStamp: (unit -> DateTime) * getReader: (unit -> ILModuleReader) + + member this.FileName = + match this with + | FSharpReference(projectFileName=projectFileName) + | PEReference(projectFileName=projectFileName) + | ILModuleReference(projectFileName=projectFileName) -> projectFileName + + static member CreateFSharp(projectFileName, options) = + FSharpReference(projectFileName, options) + + static member CreatePortableExecutable(projectFileName, stamp, getStream) = + PEReference(projectFileName, stamp, DelayedILModuleReader(projectFileName, getStream)) + + static member CreateFromILModuleReader(projectFileName, getStamp, getReader) = + ILModuleReference(projectFileName, getStamp, getReader) + + override this.Equals(o) = + match o with + | :? FSharpReferencedProject as o -> + match this, o with + | FSharpReference(projectFileName1, options1), FSharpReference(projectFileName2, options2) -> + projectFileName1 = projectFileName2 && options1 = options2 + | PEReference(projectFileName1, stamp1, _), PEReference(projectFileName2, stamp2, _) -> + projectFileName1 = projectFileName2 && stamp1 = stamp2 + | ILModuleReference(projectFileName1, getStamp1, _), ILModuleReference(projectFileName2, getStamp2, _) -> + projectFileName1 = projectFileName2 && (getStamp1()) = (getStamp2()) + | _ -> + false + | _ -> + false + + override this.GetHashCode() = this.FileName.GetHashCode() + +// NOTE: may be better just to move to optional arguments here +and FSharpProjectOptions = + { + ProjectFileName: string + ProjectId: string option + SourceFiles: string[] + OtherOptions: string[] + ReferencedProjects: FSharpReferencedProject[] + IsIncompleteTypeCheckEnvironment : bool + UseScriptResolutionRules : bool + LoadTime : DateTime + UnresolvedReferences : FSharpUnresolvedReferencesSet option + OriginalLoadReferences: (range * string * string) list + Stamp : int64 option + } + + static member UseSameProject(options1,options2) = + match options1.ProjectId, options2.ProjectId with + | Some(projectId1), Some(projectId2) when not (String.IsNullOrWhiteSpace(projectId1)) && not (String.IsNullOrWhiteSpace(projectId2)) -> + projectId1 = projectId2 + | Some _, Some _ + | None, None -> options1.ProjectFileName = options2.ProjectFileName + | _ -> false + + static member AreSameForChecking(options1,options2) = + match options1.Stamp, options2.Stamp with + | Some x, Some y -> (x = y) + | _ -> + FSharpProjectOptions.UseSameProject(options1, options2) && + options1.SourceFiles = options2.SourceFiles && + options1.OtherOptions = options2.OtherOptions && + options1.UnresolvedReferences = options2.UnresolvedReferences && + options1.OriginalLoadReferences = options2.OriginalLoadReferences && + options1.ReferencedProjects.Length = options2.ReferencedProjects.Length && + (options1.ReferencedProjects, options2.ReferencedProjects) + ||> Array.forall2 (fun r1 r2 -> + match r1, r2 with + | FSharpReferencedProject.FSharpReference(n1,a), FSharpReferencedProject.FSharpReference(n2,b) -> + n1 = n2 && FSharpProjectOptions.AreSameForChecking(a,b) + | FSharpReferencedProject.PEReference(n1, stamp1, _), FSharpReferencedProject.PEReference(n2, stamp2, _) -> + n1 = n2 && stamp1 = stamp2 + | _ -> + false) && + options1.LoadTime = options2.LoadTime + + member po.ProjectDirectory = Path.GetDirectoryName(po.ProjectFileName) + + override this.ToString() = "FSharpProjectOptions(" + this.ProjectFileName + ")" + [] module internal FSharpCheckerResultsSettings = @@ -49,55 +198,83 @@ module internal FSharpCheckerResultsSettings = let maxTypeCheckErrorsOutOfProjectContext = GetEnvInteger "FCS_MaxErrorsOutOfProjectContext" 3 - /// Maximum time share for a piece of background work before it should (cooperatively) yield - /// to enable other requests to be serviced. Yielding means returning a continuation function - /// (via an Eventually<_> value of case NotYetDone) that can be called as the next piece of work. - let maxTimeShareMilliseconds = - match System.Environment.GetEnvironmentVariable("FCS_MaxTimeShare") with - | null | "" -> 100L - | s -> int64 s - // Look for DLLs in the location of the service DLL first. let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(Some(Path.GetDirectoryName(typeof.Assembly.Location))).Value -[] -type FSharpFindDeclFailureReason = +[] +type FSharpSymbolUse(denv: DisplayEnv, symbol:FSharpSymbol, inst: TyparInst, itemOcc, range: range) = - // generic reason: no particular information about error - | Unknown of message: string + member _.Symbol = symbol - // source code file is not available - | NoSourceCode + member _.GenericArguments = + let cenv = symbol.SymbolEnv + inst |> List.map (fun (v, ty) -> FSharpGenericParameter(cenv, v), FSharpType(cenv, ty)) - // trying to find declaration of ProvidedType without TypeProviderDefinitionLocationAttribute - | ProvidedType of string + member _.DisplayContext = FSharpDisplayContext(fun _ -> denv) - // trying to find declaration of ProvidedMember without TypeProviderDefinitionLocationAttribute - | ProvidedMember of string + member x.IsDefinition = x.IsFromDefinition -[] -type FSharpFindDeclResult = + member _.IsFromDefinition = itemOcc = ItemOccurence.Binding + + member _.IsFromPattern = itemOcc = ItemOccurence.Pattern + + member _.IsFromType = itemOcc = ItemOccurence.UseInType + + member _.IsFromAttribute = itemOcc = ItemOccurence.UseInAttribute - /// declaration not found + reason - | DeclNotFound of FSharpFindDeclFailureReason + member _.IsFromDispatchSlotImplementation = itemOcc = ItemOccurence.Implemented - /// found declaration - | DeclFound of range + member _.IsFromComputationExpression = + match symbol.Item, itemOcc with + // 'seq' in 'seq { ... }' gets colored as keywords + | Item.Value vref, ItemOccurence.Use when valRefEq denv.g denv.g.seq_vref vref -> true + // custom builders, custom operations get colored as keywords + | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use -> true + | _ -> false + + member _.IsFromOpenStatement = itemOcc = ItemOccurence.Open + + member _.FileName = range.FileName + + member _.Range = range + + member this.IsPrivateToFile = + let isPrivate = + match this.Symbol with + | :? FSharpMemberOrFunctionOrValue as m -> not m.IsModuleValueOrMember || m.Accessibility.IsPrivate + | :? FSharpEntity as m -> m.Accessibility.IsPrivate + | :? FSharpGenericParameter -> true + | :? FSharpUnionCase as m -> m.Accessibility.IsPrivate + | :? FSharpField as m -> m.Accessibility.IsPrivate + | _ -> false + + let declarationLocation = + match this.Symbol.SignatureLocation with + | Some x -> Some x + | _ -> + match this.Symbol.DeclarationLocation with + | Some x -> Some x + | _ -> this.Symbol.ImplementationLocation + + let declaredInTheFile = + match declarationLocation with + | Some declRange -> declRange.FileName = this.Range.FileName + | _ -> false - /// Indicates an external declaration was found - | ExternalDecl of assembly : string * externalSym : ExternalSymbol + isPrivate && declaredInTheFile + + override _.ToString() = sprintf "%O, %O, %O" symbol itemOcc range /// This type is used to describe what was found during the name resolution. /// (Depending on the kind of the items, we may stop processing or continue to find better items) [] -type internal NameResResult = +type NameResResult = | Members of (ItemWithInst list * DisplayEnv * range) | Cancel of DisplayEnv * range | Empty - | TypecheckStaleAndTextChanged [] -type ResolveOverloads = +type ResolveOverloads = | Yes | No @@ -108,26 +285,8 @@ type GetPreciseCompletionListFromExprTypingsResult = | None | Some of (ItemWithInst list * DisplayEnv * range) * TType -type Names = string list +type Names = string list -[] -type SemanticClassificationType = - | ReferenceType - | ValueType - | UnionCase - | Function - | Property - | MutableVar - | Module - | Printf - | ComputationExpression - | IntrinsicFunction - | Enumeration - | Interface - | TypeArgument - | Operator - | Disposable - /// A TypeCheckInfo represents everything we get back from the typecheck of a file. /// It acts like an in-memory database about the file. /// It is effectively immutable and not updated: when we re-typecheck we just drop the previous @@ -144,165 +303,164 @@ type internal TypeCheckInfo tcAccessRights: AccessorDomain, projectFileName: string, mainInputFileName: string, + projectOptions: FSharpProjectOptions, sResolutions: TcResolutions, sSymbolUses: TcSymbolUses, // This is a name resolution environment to use if no better match can be found. sFallback: NameResolutionEnv, loadClosure : LoadClosure option, - reactorOps : IReactorOperations, - textSnapshotInfo:obj option, implFileOpt: TypedImplFile option, - openDeclarations: OpenDeclaration[]) = - - let textSnapshotInfo = defaultArg textSnapshotInfo null - let (|CNR|) (cnr:CapturedNameResolution) = - (cnr.Pos, cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range) + openDeclarations: OpenDeclaration[]) = // These strings are potentially large and the editor may choose to hold them for a while. - // Use this cache to fold together data tip text results that are the same. - // Is not keyed on 'Names' collection because this is invariant for the current position in + // Use this cache to fold together data tip text results that are the same. + // Is not keyed on 'Names' collection because this is invariant for the current position in // this unchanged file. Keyed on lineStr though to prevent a change to the currently line // being available against a stale scope. - let getToolTipTextCache = AgedLookup>(getToolTipTextSize,areSimilar=(fun (x,y) -> x = y)) - + let getToolTipTextCache = AgedLookup(getToolTipTextSize,areSimilar=(fun (x,y) -> x = y)) + let amap = tcImports.GetImportMap() - let infoReader = new InfoReader(g,amap) - let ncenv = new NameResolver(g,amap,infoReader,NameResolution.FakeInstantiationGenerator) + let infoReader = InfoReader(g,amap) + let ncenv = NameResolver(g,amap,infoReader,FakeInstantiationGenerator) let cenv = SymbolEnv(g, thisCcu, Some ccuSigForFile, tcImports, amap, infoReader) - + /// Find the most precise naming environment for the given line and column let GetBestEnvForPos cursorPos = - + let mutable bestSoFar = None // Find the most deeply nested enclosing scope that contains given position - sResolutions.CapturedEnvs |> ResizeArray.iter (fun (possm,env,ad) -> + sResolutions.CapturedEnvs |> ResizeArray.iter (fun (possm,env,ad) -> if rangeContainsPos possm cursorPos then - match bestSoFar with - | Some (bestm,_,_) -> - if rangeContainsRange bestm possm then + match bestSoFar with + | Some (bestm,_,_) -> + if rangeContainsRange bestm possm then bestSoFar <- Some (possm,env,ad) - | None -> + | None -> bestSoFar <- Some (possm,env,ad)) - let mostDeeplyNestedEnclosingScope = bestSoFar - - // Look for better subtrees on the r.h.s. of the subtree to the left of where we are - // Should really go all the way down the r.h.s. of the subtree to the left of where we are - // This is all needed when the index is floating free in the area just after the environment we really want to capture - // We guarantee to only refine to a more nested environment. It may not be strictly - // the right environment, but will always be at least as rich + let mostDeeplyNestedEnclosingScope = bestSoFar - let mutable bestAlmostIncludedSoFar = None + // Look for better subtrees on the r.h.s. of the subtree to the left of where we are + // Should really go all the way down the r.h.s. of the subtree to the left of where we are + // This is all needed when the index is floating free in the area just after the environment we really want to capture + // We guarantee to only refine to a more nested environment. It may not be strictly + // the right environment, but will always be at least as rich - sResolutions.CapturedEnvs |> ResizeArray.iter (fun (possm,env,ad) -> + let mutable bestAlmostIncludedSoFar = None + + sResolutions.CapturedEnvs |> ResizeArray.iter (fun (possm,env,ad) -> // take only ranges that strictly do not include cursorPos (all ranges that touch cursorPos were processed during 'Strict Inclusion' part) - if rangeBeforePos possm cursorPos && not (posEq possm.End cursorPos) then - let contained = - match mostDeeplyNestedEnclosingScope with - | Some (bestm,_,_) -> rangeContainsRange bestm possm - | None -> true - - if contained then - match bestAlmostIncludedSoFar with - | Some (rightm:range,_,_) -> - if posGt possm.End rightm.End || + if rangeBeforePos possm cursorPos && not (posEq possm.End cursorPos) then + let contained = + match mostDeeplyNestedEnclosingScope with + | Some (bestm,_,_) -> rangeContainsRange bestm possm + | None -> true + + if contained then + match bestAlmostIncludedSoFar with + | Some (rightm:range,_,_) -> + if posGt possm.End rightm.End || (posEq possm.End rightm.End && posGt possm.Start rightm.Start) then bestAlmostIncludedSoFar <- Some (possm,env,ad) | _ -> bestAlmostIncludedSoFar <- Some (possm,env,ad)) - - let resEnv = - match bestAlmostIncludedSoFar, mostDeeplyNestedEnclosingScope with + + let resEnv = + match bestAlmostIncludedSoFar, mostDeeplyNestedEnclosingScope with | Some (_,env,ad), None -> env, ad - | Some (_,almostIncludedEnv,ad), Some (_,mostDeeplyNestedEnv,_) - when almostIncludedEnv.eFieldLabels.Count >= mostDeeplyNestedEnv.eFieldLabels.Count -> + | Some (_,almostIncludedEnv,ad), Some (_,mostDeeplyNestedEnv,_) + when almostIncludedEnv.eFieldLabels.Count >= mostDeeplyNestedEnv.eFieldLabels.Count -> almostIncludedEnv,ad - | _ -> - match mostDeeplyNestedEnclosingScope with - | Some (_,env,ad) -> + | _ -> + match mostDeeplyNestedEnclosingScope with + | Some (_,env,ad) -> env,ad - | None -> + | None -> sFallback,AccessibleFromSomeFSharpCode - let pm = mkRange mainInputFileName cursorPos cursorPos + let pm = mkRange mainInputFileName cursorPos cursorPos resEnv,pm /// The items that come back from ResolveCompletionsInType are a bit /// noisy. Filter a few things out. /// - /// e.g. prefer types to constructors for FSharpToolTipText + /// e.g. prefer types to constructors for ToolTipText let FilterItemsForCtors filterCtors (items: ItemWithInst list) = - let items = items |> List.filter (fun item -> match item.Item with (Item.CtorGroup _) when filterCtors = ResolveTypeNamesToTypeRefs -> false | _ -> true) + let items = items |> List.filter (fun item -> match item.Item with Item.CtorGroup _ when filterCtors = ResolveTypeNamesToTypeRefs -> false | _ -> true) items - + // Filter items to show only valid & return Some if there are any - let ReturnItemsOfType (items: ItemWithInst list) g denv (m:range) filterCtors hasTextChangedSinceLastTypecheck = - let items = - items + let ReturnItemsOfType (items: ItemWithInst list) g denv (m:range) filterCtors = + let items = + items |> RemoveDuplicateItems g |> RemoveExplicitlySuppressed g |> FilterItemsForCtors filterCtors if not (isNil items) then - if hasTextChangedSinceLastTypecheck(textSnapshotInfo, m) then - NameResResult.TypecheckStaleAndTextChanged // typecheck is stale, wait for second-chance IntelliSense to bring up right result - else - NameResResult.Members (items, denv, m) - else NameResResult.Empty + NameResResult.Members (items, denv, m) + else + NameResResult.Empty - let GetCapturedNameResolutions endOfNamesPos resolveOverloads = + let GetCapturedNameResolutions (endOfNamesPos: pos) resolveOverloads = + let filter (endPos: pos) items = + items |> ResizeArray.filter (fun (cnr: CapturedNameResolution) -> + let range = cnr.Range + range.EndLine = endPos.Line && range.EndColumn = endPos.Column) - let quals = - match resolveOverloads with - | ResolveOverloads.Yes -> sResolutions.CapturedNameResolutions - | ResolveOverloads.No -> sResolutions.CapturedMethodGroupResolutions + match resolveOverloads with + | ResolveOverloads.Yes -> + filter endOfNamesPos sResolutions.CapturedNameResolutions - let quals = quals |> ResizeArray.filter (fun cnr -> posEq cnr.Pos endOfNamesPos) - - quals + | ResolveOverloads.No -> + let items = filter endOfNamesPos sResolutions.CapturedMethodGroupResolutions + if items.Count <> 0 then + items + else + filter endOfNamesPos sResolutions.CapturedNameResolutions /// Looks at the exact name resolutions that occurred during type checking - /// If 'membersByResidue' is specified, we look for members of the item obtained + /// If 'membersByResidue' is specified, we look for members of the item obtained /// from the name resolution and filter them by the specified residue (?) - let GetPreciseItemsFromNameResolution(line, colAtEndOfNames, membersByResidue, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck) = + let GetPreciseItemsFromNameResolution(line, colAtEndOfNames, membersByResidue, filterCtors, resolveOverloads) = let endOfNamesPos = mkPos line colAtEndOfNames // Logic below expects the list to be in reverse order of resolution let cnrs = GetCapturedNameResolutions endOfNamesPos resolveOverloads |> ResizeArray.toList |> List.rev - match cnrs, membersByResidue with - + match cnrs, membersByResidue with + // If we're looking for members using a residue, we'd expect only // a single item (pick the first one) and we need the residue (which may be "") - | CNR(_,Item.Types(_,(ty::_)), _, denv, nenv, ad, m)::_, Some _ -> - let items = ResolveCompletionsInType ncenv nenv (ResolveCompletionTargets.All(ConstraintSolver.IsApplicableMethApprox g amap m)) m ad true ty + | CNR(Item.Types(_,ty::_), _, denv, nenv, ad, m)::_, Some _ -> + let items = ResolveCompletionsInType ncenv nenv (ResolveCompletionTargets.All(ConstraintSolver.IsApplicableMethApprox g amap m)) m ad true ty let items = List.map ItemWithNoInst items - ReturnItemsOfType items g denv m filterCtors hasTextChangedSinceLastTypecheck - + ReturnItemsOfType items g denv m filterCtors + // Value reference from the name resolution. Primarily to disallow "let x.$ = 1" // In most of the cases, value references can be obtained from expression typings or from environment, // so we wouldn't have to handle values here. However, if we have something like: // let varA = "string" // let varA = if b then 0 else varA. // then the expression typings get confused (thinking 'varA:int'), so we use name resolution even for usual values. - - | CNR(_, Item.Value(vref), occurence, denv, nenv, ad, m)::_, Some _ -> - if (occurence = ItemOccurence.Binding || occurence = ItemOccurence.Pattern) then + + | CNR(Item.Value(vref), occurence, denv, nenv, ad, m)::_, Some _ -> + if occurence = ItemOccurence.Binding || occurence = ItemOccurence.Pattern then // Return empty list to stop further lookup - for value declarations NameResResult.Cancel(denv, m) - else + else // If we have any valid items for the value, then return completions for its type now. // Adjust the type in case this is the 'this' pointer stored in a reference cell. - let ty = StripSelfRefCell(g, vref.BaseOrThisInfo, vref.TauType) + let ty = StripSelfRefCell(g, vref.BaseOrThisInfo, vref.TauType) // patch accessibility domain to remove protected members if accessing NormalVal - let ad = + let ad = match vref.BaseOrThisInfo, ad with | ValBaseOrThisInfo.NormalVal, AccessibleFrom(paths, Some tcref) -> let tcref = generalizedTyconRef tcref // check that type of value is the same or subtype of tcref // yes - allow access to protected members // no - strip ability to access protected members - if FSharp.Compiler.TypeRelations.TypeFeasiblySubsumesType 0 g amap m tcref FSharp.Compiler.TypeRelations.CanCoerce ty then + if TypeRelations.TypeFeasiblySubsumesType 0 g amap m tcref TypeRelations.CanCoerce ty then ad else AccessibleFrom(paths, None) @@ -310,35 +468,35 @@ type internal TypeCheckInfo let items = ResolveCompletionsInType ncenv nenv (ResolveCompletionTargets.All(ConstraintSolver.IsApplicableMethApprox g amap m)) m ad false ty let items = List.map ItemWithNoInst items - ReturnItemsOfType items g denv m filterCtors hasTextChangedSinceLastTypecheck - + ReturnItemsOfType items g denv m filterCtors + // No residue, so the items are the full resolution of the name - | CNR(_, _, _, denv, _, _, m) :: _, None -> - let items = - cnrs + | CNR(_, _, denv, _, _, m) :: _, None -> + let items = + cnrs |> List.map (fun cnr -> cnr.ItemWithInst) - // "into" is special magic syntax, not an identifier or a library call. It is part of capturedNameResolutions as an + // "into" is special magic syntax, not an identifier or a library call. It is part of capturedNameResolutions as an // implementation detail of syntax coloring, but we should not report name resolution results for it, to prevent spurious QuickInfo. - |> List.filter (fun item -> match item.Item with Item.CustomOperation(CustomOperations.Into,_,_) -> false | _ -> true) - ReturnItemsOfType items g denv m filterCtors hasTextChangedSinceLastTypecheck + |> List.filter (fun item -> match item.Item with Item.CustomOperation(CustomOperations.Into,_,_) -> false | _ -> true) + ReturnItemsOfType items g denv m filterCtors | _, _ -> NameResResult.Empty - - let TryGetTypeFromNameResolution(line, colAtEndOfNames, membersByResidue, resolveOverloads) = + + let TryGetTypeFromNameResolution(line, colAtEndOfNames, membersByResidue, resolveOverloads) = let endOfNamesPos = mkPos line colAtEndOfNames let items = GetCapturedNameResolutions endOfNamesPos resolveOverloads |> ResizeArray.toList |> List.rev - - match items, membersByResidue with - | CNR(_,Item.Types(_,(ty::_)),_,_,_,_,_)::_, Some _ -> Some ty - | CNR(_, Item.Value(vref), occurence,_,_,_,_)::_, Some _ -> + + match items, membersByResidue with + | CNR(Item.Types(_,ty::_),_,_,_,_,_)::_, Some _ -> Some ty + | CNR(Item.Value(vref), occurence,_,_,_,_)::_, Some _ -> if (occurence = ItemOccurence.Binding || occurence = ItemOccurence.Pattern) then None else Some (StripSelfRefCell(g, vref.BaseOrThisInfo, vref.TauType)) | _, _ -> None - let CollectParameters (methods: MethInfo list) amap m: Item list = + let CollectParameters (methods: MethInfo list) amap m: Item list = methods |> List.collect (fun meth -> match meth.GetParamDatas(amap, m, meth.FormalMethodInst) with - | x::_ -> x |> List.choose(fun (ParamData(_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfo, name, _, ty)) -> + | x::_ -> x |> List.choose(fun (ParamData(_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfo, name, _, ty)) -> match name with | Some n -> Some (Item.ArgName(n, ty, Some (ArgumentContainer.Method meth))) | None -> None @@ -346,17 +504,17 @@ type internal TypeCheckInfo | _ -> [] ) - let GetNamedParametersAndSettableFields endOfExprPos hasTextChangedSinceLastTypecheck = + let GetNamedParametersAndSettableFields endOfExprPos = let cnrs = GetCapturedNameResolutions endOfExprPos ResolveOverloads.No |> ResizeArray.toList |> List.rev let result = match cnrs with - | CNR(_, Item.CtorGroup(_, ((ctor::_) as ctors)), _, denv, nenv, ad, m) ::_ -> + | CNR(Item.CtorGroup(_, (ctor::_ as ctors)), _, denv, nenv, ad, m) ::_ -> let props = ResolveCompletionsInType ncenv nenv ResolveCompletionTargets.SettablePropertiesAndFields m ad false ctor.ApparentEnclosingType let parameters = CollectParameters ctors amap m let items = props @ parameters Some (denv, m, items) - | CNR(_, Item.MethodGroup(_, methods, _), _, denv, nenv, ad, m) ::_ -> - let props = + | CNR(Item.MethodGroup(_, methods, _), _, denv, nenv, ad, m) ::_ -> + let props = methods |> List.collect (fun meth -> let retTy = meth.GetFSharpReturnTy(amap, m, meth.FormalMethodInst) @@ -365,202 +523,209 @@ type internal TypeCheckInfo let parameters = CollectParameters methods amap m let items = props @ parameters Some (denv, m, items) - | _ -> + | _ -> None match result with - | None -> + | None -> NameResResult.Empty - | Some (denv, m, items) -> + | Some (denv, m, items) -> let items = List.map ItemWithNoInst items - ReturnItemsOfType items g denv m TypeNameResolutionFlag.ResolveTypeNamesToTypeRefs hasTextChangedSinceLastTypecheck - + ReturnItemsOfType items g denv m TypeNameResolutionFlag.ResolveTypeNamesToTypeRefs + /// finds captured typing for the given position - let GetExprTypingForPosition(endOfExprPos) = - let quals = - sResolutions.CapturedExpressionTypings - |> Seq.filter (fun (pos,ty,denv,_,_,_) -> + let GetExprTypingForPosition endOfExprPos = + let quals = + sResolutions.CapturedExpressionTypings + |> Seq.filter (fun (ty,nenv,_,m) -> // We only want expression types that end at the particular position in the file we are looking at. - let isLocationWeCareAbout = posEq pos endOfExprPos + posEq m.End endOfExprPos && + // Get rid of function types. True, given a 2-arg curried function "f x y", it is legal to do "(f x).GetType()", - // but you almost never want to do this in practice, and we choose not to offer up any intellisense for + // but you almost never want to do this in practice, and we choose not to offer up any intellisense for // F# function types. - let isFunction = isFunTy denv.g ty - isLocationWeCareAbout && not isFunction) + not (isFunTy nenv.DisplayEnv.g ty)) |> Seq.toArray - let thereWereSomeQuals = not (Array.isEmpty quals) // filter out errors - let quals = quals - |> Array.filter (fun (_,ty,denv,_,_,_) -> not (isTyparTy denv.g ty && (destTyparTy denv.g ty).IsFromError)) + let quals = quals + |> Array.filter (fun (ty,nenv,_,_) -> + let denv = nenv.DisplayEnv + not (isTyparTy denv.g ty && (destTyparTy denv.g ty).IsFromError)) + + let thereWereSomeQuals = not (Array.isEmpty quals) thereWereSomeQuals, quals - + /// obtains captured typing for the given position /// if type of captured typing is record - returns list of record fields - let GetRecdFieldsForExpr(r : range) = + let GetRecdFieldsForExpr(r : range) = let _, quals = GetExprTypingForPosition(r.End) - let bestQual = + let bestQual = match quals with | [||] -> None - | quals -> - quals |> Array.tryFind (fun (_,_,_,_,_,rq) -> + | quals -> + quals |> Array.tryFind (fun (_,_,_,rq) -> ignore(r) // for breakpoint posEq r.Start rq.Start) match bestQual with - | Some (_,ty,denv,_nenv,ad,m) when isRecdTy denv.g ty -> - let items = NameResolution.ResolveRecordOrClassFieldsOfType ncenv m ad ty false - Some (items, denv, m) + | Some (ty,nenv,ad,m) when isRecdTy nenv.DisplayEnv.g ty -> + let items = ResolveRecordOrClassFieldsOfType ncenv m ad ty false + Some (items, nenv.DisplayEnv, m) | _ -> None - /// Looks at the exact expression types at the position to the left of the + /// Looks at the exact expression types at the position to the left of the /// residue then the source when it was typechecked. - let GetPreciseCompletionListFromExprTypings(parseResults:FSharpParseFileResults, endOfExprPos, filterCtors, hasTextChangedSinceLastTypecheck: (obj * range -> bool)) = - + let GetPreciseCompletionListFromExprTypings(parseResults:FSharpParseFileResults, endOfExprPos, filterCtors) = + let thereWereSomeQuals, quals = GetExprTypingForPosition(endOfExprPos) match quals with - | [| |] -> + | [| |] -> if thereWereSomeQuals then - GetPreciseCompletionListFromExprTypingsResult.NoneBecauseThereWereTypeErrors + GetPreciseCompletionListFromExprTypingsResult.NoneBecauseThereWereTypeErrors else GetPreciseCompletionListFromExprTypingsResult.None | _ -> - let bestQual, textChanged = - match parseResults.ParseTree with - | Some(input) -> - match UntypedParseImpl.GetRangeOfExprLeftOfDot(endOfExprPos,Some(input)) with // TODO we say "colAtEndOfNames" everywhere, but that's not really a good name ("foo . $" hit Ctrl-Space at $) - | Some( exprRange) -> - if hasTextChangedSinceLastTypecheck(textSnapshotInfo, exprRange) then - None, true // typecheck is stale, wait for second-chance IntelliSense to bring up right result - else - // See bug 130733. We have an up-to-date sync parse, and know the exact range of the prior expression. - // The quals all already have the same ending position, so find one with a matching starting position, if it exists. - // If not, then the stale typecheck info does not have a capturedExpressionTyping for this exact expression, and the - // user can wait for typechecking to catch up and second-chance intellisense to give the right result. - let qual = - quals |> Array.tryFind (fun (_,_,_,_,_,r) -> - ignore(r) // for breakpoint - posEq exprRange.Start r.Start) - qual, false - | None -> - // TODO In theory I think we should never get to this code path; it would be nice to add an assert. - // In practice, we do get here in some weird cases like "2.0 .. 3.0" and hitting Ctrl-Space in between the two dots of the range operator. - // I wasn't able to track down what was happening in those weird cases, not worth worrying about, it doesn't manifest as a product bug or anything. - None, false - | _ -> None, false + let bestQual, textChanged = + let input = parseResults.ParseTree + match ParsedInput.GetRangeOfExprLeftOfDot(endOfExprPos,input) with // TODO we say "colAtEndOfNames" everywhere, but that's not really a good name ("foo . $" hit Ctrl-Space at $) + | Some( exprRange) -> + // We have an up-to-date sync parse, and know the exact range of the prior expression. + // The quals all already have the same ending position, so find one with a matching starting position, if it exists. + // If not, then the stale typecheck info does not have a capturedExpressionTyping for this exact expression, and the + // user can wait for typechecking to catch up and second-chance intellisense to give the right result. + let qual = + quals |> Array.tryFind (fun (_,_,_,r) -> + ignore(r) // for breakpoint + posEq exprRange.Start r.Start) + qual, false + | None -> + // TODO In theory I think we should never get to this code path; it would be nice to add an assert. + // In practice, we do get here in some weird cases like "2.0 .. 3.0" and hitting Ctrl-Space in between the two dots of the range operator. + // I wasn't able to track down what was happening in those weird cases, not worth worrying about, it doesn't manifest as a product bug or anything. + None, false match bestQual with | Some bestQual -> - let (_,ty,denv,nenv,ad,m) = bestQual - let items = ResolveCompletionsInType ncenv nenv (ResolveCompletionTargets.All(ConstraintSolver.IsApplicableMethApprox g amap m)) m ad false ty + let ty,nenv,ad,m = bestQual + let items = ResolveCompletionsInType ncenv nenv (ResolveCompletionTargets.All(ConstraintSolver.IsApplicableMethApprox g amap m)) m ad false ty let items = items |> List.map ItemWithNoInst let items = items |> RemoveDuplicateItems g let items = items |> RemoveExplicitlySuppressed g - let items = items |> FilterItemsForCtors filterCtors - GetPreciseCompletionListFromExprTypingsResult.Some((items,denv,m), ty) - | None -> + let items = items |> FilterItemsForCtors filterCtors + GetPreciseCompletionListFromExprTypingsResult.Some((items,nenv.DisplayEnv,m), ty) + | None -> if textChanged then GetPreciseCompletionListFromExprTypingsResult.NoneBecauseTypecheckIsStaleAndTextChanged else GetPreciseCompletionListFromExprTypingsResult.None /// Find items in the best naming environment. - let GetEnvironmentLookupResolutions(nenv, ad, m, plid, filterCtors, showObsolete) = - let items = NameResolution.ResolvePartialLongIdent ncenv nenv (ConstraintSolver.IsApplicableMethApprox g amap m) m ad plid showObsolete + let GetEnvironmentLookupResolutions(nenv, ad, m, plid, filterCtors, showObsolete) = + let items = ResolvePartialLongIdent ncenv nenv (ConstraintSolver.IsApplicableMethApprox g amap m) m ad plid showObsolete let items = items |> List.map ItemWithNoInst - let items = items |> RemoveDuplicateItems g + let items = items |> RemoveDuplicateItems g let items = items |> RemoveExplicitlySuppressed g - let items = items |> FilterItemsForCtors filterCtors + let items = items |> FilterItemsForCtors filterCtors (items, nenv.DisplayEnv, m) /// Find items in the best naming environment. - let GetEnvironmentLookupResolutionsAtPosition(cursorPos, plid, filterCtors, showObsolete) = + let GetEnvironmentLookupResolutionsAtPosition(cursorPos, plid, filterCtors, showObsolete) = let (nenv,ad),m = GetBestEnvForPos cursorPos GetEnvironmentLookupResolutions(nenv, ad, m, plid, filterCtors, showObsolete) /// Find record fields in the best naming environment. - let GetClassOrRecordFieldsEnvironmentLookupResolutions(cursorPos, plid) = + let GetClassOrRecordFieldsEnvironmentLookupResolutions(cursorPos, plid) = let (nenv, ad),m = GetBestEnvForPos cursorPos - let items = NameResolution.ResolvePartialLongIdentToClassOrRecdFields ncenv nenv m ad plid false + let items = ResolvePartialLongIdentToClassOrRecdFields ncenv nenv m ad plid false let items = items |> List.map ItemWithNoInst - let items = items |> RemoveDuplicateItems g + let items = items |> RemoveDuplicateItems g let items = items |> RemoveExplicitlySuppressed g - items, nenv.DisplayEnv, m + items, nenv.DisplayEnv, m /// Resolve a location and/or text to items. // Three techniques are used // - look for an exact known name resolution from type checking - // - use the known type of an expression, e.g. (expr).Name, to generate an item list + // - use the known type of an expression, e.g. (expr).Name, to generate an item list // - lookup an entire name in the name resolution environment, e.g. A.B.Name, to generate an item list // // The overall aim is to resolve as accurately as possible based on what we know from type inference - + let GetBaseClassCandidates = function | Item.ModuleOrNamespaces _ -> true | Item.Types(_, ty::_) when (isClassTy g ty) && not (isSealedTy g ty) -> true - | _ -> false + | _ -> false let GetInterfaceCandidates = function | Item.ModuleOrNamespaces _ -> true | Item.Types(_, ty::_) when (isInterfaceTy g ty) -> true - | _ -> false + | _ -> false // Return only items with the specified name - let FilterDeclItemsByResidue (getItem: 'a -> Item) residue (items: 'a list) = + let FilterDeclItemsByResidue (getItem: 'a -> Item) residue (items: 'a list) = let attributedResidue = residue + "Attribute" let nameMatchesResidue name = (residue = name) || (attributedResidue = name) - items |> List.filter (fun x -> + items |> List.filter (fun x -> let item = getItem x - let n1 = item.DisplayName + let n1 = item.DisplayName match item with | Item.Types _ -> nameMatchesResidue n1 | Item.CtorGroup (_, meths) -> nameMatchesResidue n1 || meths |> List.exists (fun meth -> let tcref = meth.ApparentEnclosingTyconRef - tcref.IsProvided || nameMatchesResidue tcref.DisplayName) +#if !NO_EXTENSIONTYPING + tcref.IsProvided || +#endif + nameMatchesResidue tcref.DisplayName) | _ -> residue = n1) - + /// Post-filter items to make sure they have precisely the right name - /// This also checks that there are some remaining results + /// This also checks that there are some remaining results /// exactMatchResidueOpt = Some _ -- means that we are looking for exact matches let FilterRelevantItemsBy (getItem: 'a -> Item) (exactMatchResidueOpt : _ option) check (items: 'a list, denv, m) = - // can throw if type is in located in non-resolved CCU: i.e. bigint if reference to System.Numerics is absent - let safeCheck item = try check item with _ -> false - + let inline safeCheck item = try check item with _ -> false + // Are we looking for items with precisely the given name? - if not (isNil items) && exactMatchResidueOpt.IsSome then - let items = items |> FilterDeclItemsByResidue getItem exactMatchResidueOpt.Value |> List.filter safeCheck - if not (isNil items) then Some(items, denv, m) else None - else + if isNil items then // When (items = []) we must returns Some([],..) and not None // because this value is used if we want to stop further processing (e.g. let x.$ = ...) - let items = items |> List.filter safeCheck - Some(items, denv, m) + Some(items, denv, m) + else + match exactMatchResidueOpt with + | Some exactMatchResidue -> + let items = + items + |> FilterDeclItemsByResidue getItem exactMatchResidue + |> List.filter safeCheck + if not (isNil items) then Some(items, denv, m) else None + | _ -> + let items = items |> List.filter safeCheck + Some(items, denv, m) /// Post-filter items to make sure they have precisely the right name - /// This also checks that there are some remaining results + /// This also checks that there are some remaining results let (|FilterRelevantItems|_|) getItem exactMatchResidueOpt orig = FilterRelevantItemsBy getItem exactMatchResidueOpt (fun _ -> true) orig - + /// Find the first non-whitespace position in a line prior to the given character - let FindFirstNonWhitespacePosition (lineStr: string) i = + let FindFirstNonWhitespacePosition (lineStr: string) i = if i >= lineStr.Length then None else let mutable p = i - while p >= 0 && System.Char.IsWhiteSpace(lineStr.[p]) do + while p >= 0 && Char.IsWhiteSpace(lineStr.[p]) do p <- p - 1 if p >= 0 then Some p else None - + let CompletionItem (ty: ValueOption) (assemblySymbol: ValueOption) (item: ItemWithInst) = - let kind = + let kind = match item.Item with | Item.MethodGroup (_, minfo :: _, _) -> CompletionItemKind.Method minfo.IsExtensionMember | Item.RecdField _ | Item.Property _ -> CompletionItemKind.Property | Item.Event _ -> CompletionItemKind.Event - | Item.ILField _ + | Item.ILField _ | Item.Value _ -> CompletionItemKind.Field | Item.CustomOperation _ -> CompletionItemKind.CustomOperation | _ -> CompletionItemKind.Other @@ -573,46 +738,46 @@ type internal TypeCheckInfo Unresolved = match assemblySymbol with ValueSome x -> Some x.UnresolvedSymbol | _ -> None } let DefaultCompletionItem item = CompletionItem ValueNone ValueNone item - + let getItem (x: ItemWithInst) = x.Item - let GetDeclaredItems (parseResultsOpt: FSharpParseFileResults option, lineStr: string, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, - filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, isInRangeOperator, allSymbols: unit -> AssemblySymbol list) = + let GetDeclaredItems (parseResultsOpt: FSharpParseFileResults option, lineStr: string, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, + filterCtors, resolveOverloads, isInRangeOperator, allSymbols: unit -> AssemblySymbol list) = // Are the last two chars (except whitespaces) = ".." - let isLikeRangeOp = + let isLikeRangeOp = match FindFirstNonWhitespacePosition lineStr (colAtEndOfNamesAndResidue - 1) with | Some x when x >= 1 && lineStr.[x] = '.' && lineStr.[x - 1] = '.' -> true | _ -> false // if last two chars are .. and we are not in range operator context - no completion if isLikeRangeOp && not isInRangeOperator then None else - + // Try to use the exact results of name resolution during type checking to generate the results // This is based on position (i.e. colAtEndOfNamesAndResidue). This is not used if a residueOpt is given. - let nameResItems = - match residueOpt with - | None -> GetPreciseItemsFromNameResolution(line, colAtEndOfNamesAndResidue, None, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck) + let nameResItems = + match residueOpt with + | None -> GetPreciseItemsFromNameResolution(line, colAtEndOfNamesAndResidue, None, filterCtors,resolveOverloads) | Some residue -> // deals with cases when we have spaces between dot and\or identifier, like A . $ // if this is our case - then we need to locate end position of the name skipping whitespaces - // this allows us to handle cases like: let x . $ = 1 + // this allows us to handle cases like: let x . $ = 1 match lastDotPos |> Option.orElseWith (fun _ -> FindFirstNonWhitespacePosition lineStr (colAtEndOfNamesAndResidue - 1)) with | Some p when lineStr.[p] = '.' -> match FindFirstNonWhitespacePosition lineStr (p - 1) with - | Some colAtEndOfNames -> + | Some colAtEndOfNames -> let colAtEndOfNames = colAtEndOfNames + 1 // convert 0-based to 1-based - GetPreciseItemsFromNameResolution(line, colAtEndOfNames, Some(residue), filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck) + GetPreciseItemsFromNameResolution(line, colAtEndOfNames, Some(residue), filterCtors,resolveOverloads) | None -> NameResResult.Empty - | _ -> NameResResult.Empty - + | _ -> NameResResult.Empty + // Normalize to form A.B.C.D where D is the residue. It may be empty for "A.B.C." // residueOpt = Some when we are looking for the exact match - let plid, exactMatchResidueOpt = + let plid, exactMatchResidueOpt = match origLongIdentOpt, residueOpt with | None, _ -> [], None | Some(origLongIdent), Some _ -> origLongIdent, None | Some(origLongIdent), None -> - System.Diagnostics.Debug.Assert(not (isNil origLongIdent), "origLongIdent is empty") + Debug.Assert(not (isNil origLongIdent), "origLongIdent is empty") // note: as above, this happens when we are called for "precise" resolution - (F1 keyword, data tip etc..) let plid, residue = List.frontAndBack origLongIdent plid, Some residue @@ -621,53 +786,52 @@ type internal TypeCheckInfo let (nenv, ad), m = GetBestEnvForPos pos let getType() = - match NameResolution.TryToResolveLongIdentAsType ncenv nenv m plid with - | Some x -> tryDestAppTy g x + match TryToResolveLongIdentAsType ncenv nenv m plid with + | Some x -> tryTcrefOfAppTy g x | None -> match lastDotPos |> Option.orElseWith (fun _ -> FindFirstNonWhitespacePosition lineStr (colAtEndOfNamesAndResidue - 1)) with | Some p when lineStr.[p] = '.' -> match FindFirstNonWhitespacePosition lineStr (p - 1) with - | Some colAtEndOfNames -> + | Some colAtEndOfNames -> let colAtEndOfNames = colAtEndOfNames + 1 // convert 0-based to 1-based match TryGetTypeFromNameResolution(line, colAtEndOfNames, residueOpt, resolveOverloads) with - | Some x -> tryDestAppTy g x + | Some x -> tryTcrefOfAppTy g x | _ -> ValueNone | None -> ValueNone | _ -> ValueNone - match nameResItems with - | NameResResult.TypecheckStaleAndTextChanged -> None // second-chance intellisense will try again + match nameResItems with | NameResResult.Cancel(denv,m) -> Some([], denv, m) - | NameResResult.Members(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m)) -> + | NameResResult.Members(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m)) -> // lookup based on name resolution results successful Some (items |> List.map (CompletionItem (getType()) ValueNone), denv, m) | _ -> match origLongIdentOpt with | None -> None - | Some _ -> - + | Some _ -> + // Try to use the type of the expression on the left to help generate a completion list - let qualItems, thereIsADotInvolved = + let qualItems, thereIsADotInvolved = match parseResultsOpt with - | None -> - // Note, you will get here if the 'reason' is not CompleteWord/MemberSelect/DisplayMemberList, as those are currently the + | None -> + // Note, you will get here if the 'reason' is not CompleteWord/MemberSelect/DisplayMemberList, as those are currently the // only reasons we do a sync parse to have the most precise and likely-to-be-correct-and-up-to-date info. So for example, // if you do QuickInfo hovering over A in "f(x).A()", you will only get a tip if typechecking has a name-resolution recorded - // for A, not if merely we know the capturedExpressionTyping of f(x) and you very recently typed ".A()" - in that case, + // for A, not if merely we know the capturedExpressionTyping of f(x) and you very recently typed ".A()" - in that case, // you won't won't get a tip until the typechecking catches back up. GetPreciseCompletionListFromExprTypingsResult.None, false - | Some parseResults -> - - match UntypedParseImpl.TryFindExpressionASTLeftOfDotLeftOfCursor(mkPos line colAtEndOfNamesAndResidue,parseResults.ParseTree) with + | Some parseResults -> + + match ParsedInput.TryFindExpressionASTLeftOfDotLeftOfCursor(mkPos line colAtEndOfNamesAndResidue,parseResults.ParseTree) with | Some(pos,_) -> - GetPreciseCompletionListFromExprTypings(parseResults, pos, filterCtors, hasTextChangedSinceLastTypecheck), true - | None -> + GetPreciseCompletionListFromExprTypings(parseResults, pos, filterCtors), true + | None -> // Can get here in a case like: if "f xxx yyy" is legal, and we do "f xxx y" // We have no interest in expression typings, those are only useful for dot-completion. We want to fallback // to "Use an environment lookup as the last resort" below GetPreciseCompletionListFromExprTypingsResult.None, false - - match qualItems,thereIsADotInvolved with + + match qualItems,thereIsADotInvolved with | GetPreciseCompletionListFromExprTypingsResult.Some(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m), ty), _ // Initially we only use the expression typings when looking up, e.g. (expr).Nam or (expr).Name1.Nam // These come through as an empty plid and residue "". Otherwise we try an environment lookup @@ -675,12 +839,12 @@ type internal TypeCheckInfo // it appears we're getting some typings recorded for non-atomic expressions like "f x" when isNil plid -> // lookup based on expression typings successful - Some (items |> List.map (CompletionItem (tryDestAppTy g ty) ValueNone), denv, m) + Some (items |> List.map (CompletionItem (tryTcrefOfAppTy g ty) ValueNone), denv, m) | GetPreciseCompletionListFromExprTypingsResult.NoneBecauseThereWereTypeErrors, _ -> - // There was an error, e.g. we have "." and there is an error determining the type of + // There was an error, e.g. we have "." and there is an error determining the type of // In this case, we don't want any of the fallback logic, rather, we want to produce zero results. None - | GetPreciseCompletionListFromExprTypingsResult.NoneBecauseTypecheckIsStaleAndTextChanged, _ -> + | GetPreciseCompletionListFromExprTypingsResult.NoneBecauseTypecheckIsStaleAndTextChanged, _ -> // we want to report no result and let second-chance intellisense kick in None | _, true when isNil plid -> @@ -688,47 +852,47 @@ type internal TypeCheckInfo // The user might by typing quickly, and the LS didn't have an expression type right before the dot yet. // Second-chance intellisense will bring up the correct list in a moment. None - | _ -> + | _ -> // Use an environment lookup as the last resort let envItems, denv, m = GetEnvironmentLookupResolutions(nenv, ad, m, plid, filterCtors, residueOpt.IsSome) - + let envResult = match nameResItems, (envItems, denv, m), qualItems with - + // First, use unfiltered name resolution items, if they're not empty - | NameResResult.Members(items, denv, m), _, _ when not (isNil items) -> + | NameResResult.Members(items, denv, m), _, _ when not (isNil items) -> // lookup based on name resolution results successful - ValueSome(items |> List.map (CompletionItem (getType()) ValueNone), denv, m) - - // If we have nonempty items from environment that were resolved from a type, then use them... + ValueSome(items |> List.map (CompletionItem (getType()) ValueNone), denv, m) + + // If we have nonempty items from environment that were resolved from a type, then use them... // (that's better than the next case - here we'd return 'int' as a type) | _, FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m), _ when not (isNil items) -> // lookup based on name and environment successful ValueSome(items |> List.map (CompletionItem (getType()) ValueNone), denv, m) - + // Try again with the qualItems | _, _, GetPreciseCompletionListFromExprTypingsResult.Some(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m), ty) -> - ValueSome(items |> List.map (CompletionItem (tryDestAppTy g ty) ValueNone), denv, m) - + ValueSome(items |> List.map (CompletionItem (tryTcrefOfAppTy g ty) ValueNone), denv, m) + | _ -> ValueNone let globalResult = match origLongIdentOpt with | None | Some [] -> - let globalItems = - allSymbols() + let globalItems = + allSymbols() |> List.filter (fun x -> not x.Symbol.IsExplicitlySuppressed && match x.Symbol with - | :? FSharpMemberOrFunctionOrValue as m when m.IsConstructor && filterCtors = ResolveTypeNamesToTypeRefs -> false + | :? FSharpMemberOrFunctionOrValue as m when m.IsConstructor && filterCtors = ResolveTypeNamesToTypeRefs -> false | _ -> true) - + let getItem (x: AssemblySymbol) = x.Symbol.Item - + match globalItems, denv, m with | FilterRelevantItems getItem exactMatchResidueOpt (globalItemsFiltered, denv, m) when not (isNil globalItemsFiltered) -> - globalItemsFiltered + globalItemsFiltered |> List.map(fun globalItem -> CompletionItem (getType()) (ValueSome globalItem) (ItemWithNoInst globalItem.Symbol.Item)) |> fun r -> ValueSome(r, denv, m) | _ -> ValueNone @@ -745,13 +909,12 @@ type internal TypeCheckInfo items |> List.map DefaultCompletionItem, denv, m /// Get the auto-complete items at a particular location. - let GetDeclItemsForNamesAtPosition(ctok: CompilationThreadToken, parseResultsOpt: FSharpParseFileResults option, origLongIdentOpt: string list option, - residueOpt:string option, lastDotPos: int option, line:int, lineStr:string, colAtEndOfNamesAndResidue, filterCtors, resolveOverloads, - getAllSymbols: unit -> AssemblySymbol list, hasTextChangedSinceLastTypecheck: (obj * range -> bool)) - : (CompletionItem list * DisplayEnv * CompletionContext option * range) option = - RequireCompilationThread ctok // the operations in this method need the reactor thread + let GetDeclItemsForNamesAtPosition(parseResultsOpt: FSharpParseFileResults option, origLongIdentOpt: string list option, + residueOpt:string option, lastDotPos: int option, line:int, lineStr:string, colAtEndOfNamesAndResidue, filterCtors, resolveOverloads, + getAllSymbols: unit -> AssemblySymbol list) + : (CompletionItem list * DisplayEnv * CompletionContext option * range) option = - let loc = + let loc = match colAtEndOfNamesAndResidue with | pastEndOfLine when pastEndOfLine >= lineStr.Length -> lineStr.Length | atDot when lineStr.[atDot] = '.' -> atDot + 1 @@ -759,110 +922,110 @@ type internal TypeCheckInfo | otherwise -> otherwise - 1 // Look for a "special" completion context - let completionContext = - parseResultsOpt - |> Option.bind (fun x -> x.ParseTree) - |> Option.bind (fun parseTree -> UntypedParseImpl.TryGetCompletionContext(mkPos line colAtEndOfNamesAndResidue, parseTree, lineStr)) - + let completionContext = + parseResultsOpt + |> Option.map (fun x -> x.ParseTree) + |> Option.bind (fun parseTree -> ParsedInput.TryGetCompletionContext(mkPos line colAtEndOfNamesAndResidue, parseTree, lineStr)) + let res = match completionContext with // Invalid completion locations | Some CompletionContext.Invalid -> None - + // Completion at 'inherit C(...)" | Some (CompletionContext.Inherit(InheritanceContext.Class, (plid, _))) -> GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false) |> FilterRelevantItemsBy getItem None (getItem >> GetBaseClassCandidates) |> Option.map toCompletionItems - + // Completion at 'interface ..." | Some (CompletionContext.Inherit(InheritanceContext.Interface, (plid, _))) -> GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false) |> FilterRelevantItemsBy getItem None (getItem >> GetInterfaceCandidates) |> Option.map toCompletionItems - + // Completion at 'implement ..." | Some (CompletionContext.Inherit(InheritanceContext.Unknown, (plid, _))) -> - GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false) + GetEnvironmentLookupResolutionsAtPosition(mkPos line loc, plid, filterCtors, false) |> FilterRelevantItemsBy getItem None (getItem >> (fun t -> GetBaseClassCandidates t || GetInterfaceCandidates t)) |> Option.map toCompletionItems - + // Completion at ' { XXX = ... } " | Some(CompletionContext.RecordField(RecordContext.New(plid, _))) -> // { x. } can be either record construction or computation expression. Try to get all visible record fields first match GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid) |> toCompletionItems with - | [],_,_ -> + | [],_,_ -> // no record fields found, return completion list as if we were outside any computation expression - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, false, fun() -> []) + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors,resolveOverloads, false, fun() -> []) | result -> Some(result) - + // Completion at ' { XXX = ... with ... } " - | Some(CompletionContext.RecordField(RecordContext.CopyOnUpdate(r, (plid, _)))) -> + | Some(CompletionContext.RecordField(RecordContext.CopyOnUpdate(r, (plid, _)))) -> match GetRecdFieldsForExpr(r) with - | None -> + | None -> Some (GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, plid)) |> Option.map toCompletionItems - | Some (items, denv, m) -> - Some (List.map ItemWithNoInst items, denv, m) + | Some (items, denv, m) -> + Some (List.map ItemWithNoInst items, denv, m) |> Option.map toCompletionItems - + // Completion at ' { XXX = ... with ... } " | Some(CompletionContext.RecordField(RecordContext.Constructor(typeName))) -> Some(GetClassOrRecordFieldsEnvironmentLookupResolutions(mkPos line loc, [typeName])) |> Option.map toCompletionItems - - // Completion at ' SomeMethod( ... ) ' with named arguments + + // Completion at ' SomeMethod( ... ) ' with named arguments | Some(CompletionContext.ParameterList (endPos, fields)) -> - let results = GetNamedParametersAndSettableFields endPos hasTextChangedSinceLastTypecheck - - let declaredItems = - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, - hasTextChangedSinceLastTypecheck, false, getAllSymbols) - + let results = GetNamedParametersAndSettableFields endPos + + let declaredItems = + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, + false, getAllSymbols) + match results with - | NameResResult.Members(items, denv, m) -> - let filtered = - items + | NameResResult.Members(items, denv, m) -> + let filtered = + items |> RemoveDuplicateItems g |> RemoveExplicitlySuppressed g |> List.filter (fun item -> not (fields.Contains item.Item.DisplayName)) - |> List.map (fun item -> + |> List.map (fun item -> { ItemWithInst = item Kind = CompletionItemKind.Argument MinorPriority = 0 IsOwnMember = false - Type = None + Type = None Unresolved = None }) match declaredItems with | None -> Some (toCompletionItems (items, denv, m)) | Some (declItems, declaredDisplayEnv, declaredRange) -> Some (filtered @ declItems, declaredDisplayEnv, declaredRange) | _ -> declaredItems - + | Some(CompletionContext.AttributeApplication) -> - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols) - |> Option.map (fun (items, denv, m) -> - items + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false, getAllSymbols) + |> Option.map (fun (items, denv, m) -> + items |> List.filter (fun cItem -> match cItem.Item with | Item.ModuleOrNamespaces _ -> true | _ when IsAttribute infoReader cItem.Item -> true | _ -> false), denv, m) - - | Some(CompletionContext.OpenDeclaration) -> - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols) + + | Some(CompletionContext.OpenDeclaration isOpenType) -> + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false, getAllSymbols) |> Option.map (fun (items, denv, m) -> - items + items |> List.filter (fun x -> match x.Item with | Item.ModuleOrNamespaces _ -> true - | Item.Types (_, tcrefs) when tcrefs |> List.exists (fun ty -> isAppTy g ty && isStaticClass g (tcrefOfAppTy g ty)) -> true + | Item.Types _ when isOpenType -> true | _ -> false), denv, m) - + // Completion at '(x: ...)" - | Some (CompletionContext.PatternType) -> - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, hasTextChangedSinceLastTypecheck, false, getAllSymbols) + | Some CompletionContext.PatternType -> + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false, getAllSymbols) |> Option.map (fun (items, denv, m) -> - items + items |> List.filter (fun cItem -> match cItem.Item with | Item.ModuleOrNamespaces _ @@ -875,16 +1038,18 @@ type internal TypeCheckInfo | cc -> match residueOpt |> Option.bind Seq.tryHead with | Some ''' -> - // The last token in + // The last token in // let x = 'E - // is Ident with text "'E", however it's either unfinished char literal or generic parameter. + // is Ident with text "'E", however it's either unfinished char literal or generic parameter. // We should not provide any completion in the former case, and we don't provide it for the latter one for now // because providing generic parameters list is context aware, which we don't have here (yet). None | _ -> - let isInRangeOperator = (match cc with Some (CompletionContext.RangeOperator) -> true | _ -> false) - GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors,resolveOverloads, hasTextChangedSinceLastTypecheck, isInRangeOperator, getAllSymbols) - + let isInRangeOperator = (match cc with Some CompletionContext.RangeOperator -> true | _ -> false) + GetDeclaredItems (parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, + residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, + isInRangeOperator, getAllSymbols) + res |> Option.map (fun (items, denv, m) -> items, denv, completionContext, m) /// Return 'false' if this is not a completion item valid in an interface file. @@ -892,78 +1057,92 @@ type internal TypeCheckInfo match item with | Item.Types _ | Item.ModuleOrNamespaces _ -> true | _ -> false - + /// Find the most precise display context for the given line and column. - member __.GetBestDisplayEnvForPos cursorPos = GetBestEnvForPos cursorPos + member _.GetBestDisplayEnvForPos cursorPos = GetBestEnvForPos cursorPos - member __.GetVisibleNamespacesAndModulesAtPosition(cursorPos: pos) : ModuleOrNamespaceRef list = + member _.GetVisibleNamespacesAndModulesAtPosition(cursorPos: pos) : ModuleOrNamespaceRef list = let (nenv, ad), m = GetBestEnvForPos cursorPos - NameResolution.GetVisibleNamespacesAndModulesAtPoint ncenv nenv m ad + GetVisibleNamespacesAndModulesAtPoint ncenv nenv m ad /// Determines if a long ident is resolvable at a specific point. - member __.IsRelativeNameResolvable(cursorPos: pos, plid: string list, item: Item) : bool = + member _.IsRelativeNameResolvable(cursorPos: pos, plid: string list, item: Item) : bool = ErrorScope.Protect - Range.range0 + range0 (fun () -> /// Find items in the best naming environment. let (nenv, ad), m = GetBestEnvForPos cursorPos - NameResolution.IsItemResolvable ncenv nenv m ad plid item) - (fun msg -> + IsItemResolvable ncenv nenv m ad plid item) + (fun msg -> Trace.TraceInformation(sprintf "FCS: recovering from error in IsRelativeNameResolvable: '%s'" msg) false) /// Determines if a long ident is resolvable at a specific point. member scope.IsRelativeNameResolvableFromSymbol(cursorPos: pos, plid: string list, symbol: FSharpSymbol) : bool = scope.IsRelativeNameResolvable(cursorPos, plid, symbol.Item) - + /// Get the auto-complete items at a location - member __.GetDeclarations (ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck) = + member _.GetDeclarations (parseResultsOpt, line, lineStr, partialName, getAllEntities) = let isInterfaceFile = SourceFileImpl.IsInterfaceFile mainInputFileName - ErrorScope.Protect Range.range0 + ErrorScope.Protect range0 (fun () -> - match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllEntities, hasTextChangedSinceLastTypecheck) with - | None -> FSharpDeclarationListInfo.Empty + + let declItemsOpt = + GetDeclItemsForNamesAtPosition(parseResultsOpt, Some partialName.QualifyingIdents, + Some partialName.PartialIdent, partialName.LastDotPos, line, + lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, + getAllEntities) + + match declItemsOpt with + | None -> DeclarationListInfo.Empty | Some (items, denv, ctx, m) -> let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items - let getAccessibility item = FSharpSymbol.GetAccessibility (FSharpSymbol.Create(cenv, item)) + let getAccessibility item = FSharpSymbol.Create(cenv, item).Accessibility let currentNamespaceOrModule = parseResultsOpt - |> Option.bind (fun x -> x.ParseTree) - |> Option.map (fun parsedInput -> UntypedParseImpl.GetFullNameOfSmallestModuleOrNamespaceAtPoint(parsedInput, mkPos line 0)) + |> Option.map (fun x -> x.ParseTree) + |> Option.map (fun parsedInput -> ParsedInput.GetFullNameOfSmallestModuleOrNamespaceAtPoint(mkPos line 0, parsedInput)) let isAttributeApplication = ctx = Some CompletionContext.AttributeApplication - FSharpDeclarationListInfo.Create(infoReader,m,denv,getAccessibility,items,reactorOps,currentNamespaceOrModule,isAttributeApplication)) - (fun msg -> + DeclarationListInfo.Create(infoReader,tcAccessRights,m,denv,getAccessibility,items,currentNamespaceOrModule,isAttributeApplication)) + (fun msg -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetDeclarations: '%s'" msg) - FSharpDeclarationListInfo.Error msg) + DeclarationListInfo.Error msg) /// Get the symbols for auto-complete items at a location - member __.GetDeclarationListSymbols (ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck) = + member _.GetDeclarationListSymbols (parseResultsOpt, line, lineStr, partialName, getAllEntities) = let isInterfaceFile = SourceFileImpl.IsInterfaceFile mainInputFileName - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllEntities, hasTextChangedSinceLastTypecheck) with - | None -> List.Empty - | Some (items, denv, _, m) -> + ErrorScope.Protect range0 + (fun () -> + + let declItemsOpt = + GetDeclItemsForNamesAtPosition(parseResultsOpt, Some partialName.QualifyingIdents, + Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, + partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, + getAllEntities) + + match declItemsOpt with + | None -> List.Empty + | Some (items, denv, _, m) -> let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items //do filtering like Declarationset let items = items |> RemoveExplicitlySuppressedCompletionItems g - - // Sort by name. For things with the same name, + + // Sort by name. For things with the same name, // - show types with fewer generic parameters first - // - show types before over other related items - they usually have very useful XmlDocs - let items = + // - show types before over other related items - they usually have very useful XmlDocs + let items = items |> List.sortBy (fun d -> - let n = - match d.Item with - | Item.Types (_,(TType_app(tcref,_) :: _)) -> 1 + tcref.TyparsNoRange.Length + let n = + match d.Item with + | Item.Types (_,TType_app(tcref,_) :: _) -> 1 + tcref.TyparsNoRange.Length // Put delegate ctors after types, sorted by #typars. RemoveDuplicateItems will remove FakeInterfaceCtor and DelegateCtor if an earlier type is also reported with this name - | Item.FakeInterfaceCtor (TType_app(tcref,_)) + | Item.FakeInterfaceCtor (TType_app(tcref,_)) | Item.DelegateCtor (TType_app(tcref,_)) -> 1000 + tcref.TyparsNoRange.Length // Put type ctors after types, sorted by #typars. RemoveDuplicateItems will remove DefaultStructCtors if a type is also reported with this name - | Item.CtorGroup (_, (cinfo :: _)) -> 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length + | Item.CtorGroup (_, cinfo :: _) -> 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length | _ -> 0 - (d.Item.DisplayName,n)) + (d.Item.DisplayName, n)) // Remove all duplicates. We've put the types first, so this removes the DelegateCtor and DefaultStructCtor's. let items = items |> RemoveDuplicateCompletionItems g @@ -972,453 +1151,379 @@ type internal TypeCheckInfo // (We don't want types with the same display name to be grouped as overloads) let items = items |> List.groupBy (fun d -> - match d.Item with - | Item.Types (_,(TType_app(tcref,_) :: _)) + match d.Item with + | Item.Types (_,TType_app(tcref,_) :: _) | Item.ExnCase tcref -> tcref.LogicalName | Item.UnqualifiedType(tcref :: _) - | Item.FakeInterfaceCtor (TType_app(tcref,_)) + | Item.FakeInterfaceCtor (TType_app(tcref,_)) | Item.DelegateCtor (TType_app(tcref,_)) -> tcref.CompiledName - | Item.CtorGroup (_, (cinfo :: _)) -> + | Item.CtorGroup (_, cinfo :: _) -> cinfo.ApparentEnclosingTyconRef.CompiledName | _ -> d.Item.DisplayName) // Filter out operators (and list) - let items = + let items = // Check whether this item looks like an operator. - let isOpItem(nm, item: CompletionItem list) = - match item |> List.map (fun x -> x.Item) with + let isOpItem(nm, item: CompletionItem list) = + match item |> List.map (fun x -> x.Item) with | [Item.Value _] - | [Item.MethodGroup(_,[_],_)] -> IsOperatorName nm - | [Item.UnionCase _] -> IsOperatorName nm - | _ -> false + | [Item.MethodGroup(_,[_],_)] -> IsOperatorDisplayName nm + | [Item.UnionCase _] -> IsOperatorDisplayName nm + | _ -> false let isFSharpList nm = (nm = "[]") // list shows up as a Type and a UnionCase, only such entity with a symbolic name, but want to filter out of intellisense - items |> List.filter (fun (nm,items) -> not (isOpItem(nm,items)) && not(isFSharpList nm)) + items |> List.filter (fun (nm,items) -> not (isOpItem(nm,items)) && not(isFSharpList nm)) - let items = + let items = // Filter out duplicate names - items |> List.map (fun (_nm,itemsWithSameName) -> + items |> List.map (fun (_nm,itemsWithSameName) -> match itemsWithSameName with | [] -> failwith "Unexpected empty bag" | items -> - items + items |> List.map (fun item -> let symbol = FSharpSymbol.Create(cenv, item.Item) - FSharpSymbolUse(g, denv, symbol, ItemOccurence.Use, m))) + FSharpSymbolUse(denv, symbol, item.ItemWithInst.TyparInst, ItemOccurence.Use, m))) //end filtering items) - (fun msg -> + (fun msg -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetDeclarationListSymbols: '%s'" msg) []) - - /// Get the "reference resolution" tooltip for at a location - member __.GetReferenceResolutionStructuredToolTipText(ctok, line,col) = - RequireCompilationThread ctok // the operations in this method need the reactor thread but the reasons why are not yet grounded + /// Get the "reference resolution" tooltip for at a location + member _.GetReferenceResolutionStructuredToolTipText(line,col) = let pos = mkPos line col - let isPosMatch(pos, ar:AssemblyReference) : bool = - let isRangeMatch = (Range.rangeContainsPos ar.Range pos) - let isNotSpecialRange = not (Range.equals ar.Range rangeStartup) && not (Range.equals ar.Range range0) && not (Range.equals ar.Range rangeCmdArgs) + let isPosMatch(pos, ar:AssemblyReference) : bool = + let isRangeMatch = (rangeContainsPos ar.Range pos) + let isNotSpecialRange = not (equals ar.Range rangeStartup) && not (equals ar.Range range0) && not (equals ar.Range rangeCmdArgs) let isMatch = isRangeMatch && isNotSpecialRange - isMatch - - let dataTipOfReferences() = + isMatch + + let dataTipOfReferences() = let matches = match loadClosure with | None -> [] - | Some(loadClosure) -> + | Some(loadClosure) -> loadClosure.References - |> List.map snd - |> List.concat - |> List.filter(fun ar->isPosMatch(pos, ar.originalReference)) + |> List.collect snd + |> List.filter(fun ar -> isPosMatch(pos, ar.originalReference)) - match matches with + match matches with | resolved::_ // Take the first seen - | [resolved] -> - let tip = wordL (TaggedTextOps.tagStringLiteral((resolved.prepareToolTip ()).TrimEnd([|'\n'|]))) - FSharpStructuredToolTipText.FSharpToolTipText [FSharpStructuredToolTipElement.Single(tip, FSharpXmlDoc.None)] - - | [] -> FSharpStructuredToolTipText.FSharpToolTipText [] - - ErrorScope.Protect Range.range0 + | [resolved] -> + let tip = wordL (TaggedText.tagStringLiteral((resolved.prepareToolTip ()).TrimEnd([|'\n'|]))) + let tip = LayoutRender.toArray tip + ToolTipText.ToolTipText [ToolTipElement.Single(tip, FSharpXmlDoc.None)] + + | [] -> + let matches = + match loadClosure with + | None -> None + | Some(loadClosure) -> + loadClosure.PackageReferences + |> Array.tryFind (fun (m, _) -> rangeContainsPos m pos) + match matches with + | None -> ToolTipText.ToolTipText [] + | Some (_, lines) -> + let lines = lines |> List.filter (fun line -> not (line.StartsWith("//")) && not (String.IsNullOrEmpty line)) + ToolTipText.ToolTipText + [ for line in lines -> + let tip = wordL (TaggedText.tagStringLiteral line) + let tip = LayoutRender.toArray tip + ToolTipElement.Single(tip, FSharpXmlDoc.None)] + + ErrorScope.Protect range0 dataTipOfReferences - (fun err -> + (fun err -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetReferenceResolutionStructuredToolTipText: '%s'" err) - FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError err]) + ToolTipText [ToolTipElement.CompositionError err]) // GetToolTipText: return the "pop up" (or "Quick Info") text given a certain context. - member __.GetStructuredToolTipText(ctok, line, lineStr, colAtEndOfNames, names) = - let Compute() = - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition(ctok, None,Some(names),None,None,line,lineStr,colAtEndOfNames,ResolveTypeNamesToCtors,ResolveOverloads.Yes,(fun() -> []),fun _ -> false) with - | None -> FSharpToolTipText [] + member _.GetStructuredToolTipText(line, lineStr, colAtEndOfNames, names) = + let Compute() = + ErrorScope.Protect range0 + (fun () -> + let declItemsOpt = + GetDeclItemsForNamesAtPosition(None, Some names, None, None, + line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, + ResolveOverloads.Yes, (fun() -> [])) + + match declItemsOpt with + | None -> ToolTipText [] | Some(items, denv, _, m) -> - FSharpToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem false infoReader m denv x.ItemWithInst))) - (fun err -> + ToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem false infoReader tcAccessRights m denv x.ItemWithInst))) + + (fun err -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetStructuredToolTipText: '%s'" err) - FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError err]) - + ToolTipText [ToolTipElement.CompositionError err]) + // See devdiv bug 646520 for rationale behind truncating and caching these quick infos (they can be big!) let key = line,colAtEndOfNames,lineStr - match getToolTipTextCache.TryGet (ctok, key) with + match getToolTipTextCache.TryGet (AnyCallerThread, key) with | Some res -> res | None -> let res = Compute() - getToolTipTextCache.Put(ctok, key,res) + getToolTipTextCache.Put(AnyCallerThread, key,res) res - member __.GetF1Keyword (ctok, line, lineStr, colAtEndOfNames, names) : string option = - ErrorScope.Protect Range.range0 + member _.GetF1Keyword (line, lineStr, colAtEndOfNames, names) : string option = + ErrorScope.Protect range0 (fun () -> - match GetDeclItemsForNamesAtPosition(ctok, None, Some names, None, None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.No,(fun() -> []), fun _ -> false) with // F1 Keywords do not distinguish between overloads + + let declItemsOpt = + GetDeclItemsForNamesAtPosition(None, Some names, None, None, + line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, + ResolveOverloads.No, (fun() -> [])) + + match declItemsOpt with | None -> None | Some (items: CompletionItem list, _,_, _) -> match items with | [] -> None | [item] -> - GetF1Keyword g item.Item + GetF1Keyword g item.Item | _ -> // handle new Type() let allTypes, constr, ty = - List.fold + List.fold (fun (allTypes,constr,ty) (item: CompletionItem) -> match item.Item, constr, ty with - | (Item.Types _) as t, _, None -> allTypes, constr, Some t - | (Item.Types _), _, _ -> allTypes, constr, ty - | (Item.CtorGroup _), None, _ -> allTypes, Some item.Item, ty - | _ -> false, None, None) + | Item.Types _ as t, _, None -> allTypes, constr, Some t + | Item.Types _, _, _ -> allTypes, constr, ty + | Item.CtorGroup _, None, _ -> allTypes, Some item.Item, ty + | _ -> false, None, None) (true,None,None) items match allTypes, constr, ty with - | true, Some (Item.CtorGroup(_, _) as item), _ - -> GetF1Keyword g item + | true, Some (Item.CtorGroup _ as item), _ + -> GetF1Keyword g item | true, _, Some ty -> GetF1Keyword g ty | _ -> None - ) - (fun msg -> + ) + (fun msg -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetF1Keyword: '%s'" msg) None) - member __.GetMethods (ctok, line, lineStr, colAtEndOfNames, namesOpt) = - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition(ctok, None,namesOpt,None,None,line,lineStr,colAtEndOfNames,ResolveTypeNamesToCtors,ResolveOverloads.No,(fun() -> []),fun _ -> false) with - | None -> FSharpMethodGroup("",[| |]) - | Some (items, denv, _, m) -> - // GetDeclItemsForNamesAtPosition returns Items.Types and Item.CtorGroup for `new T(|)`, + member _.GetMethods (line, lineStr, colAtEndOfNames, namesOpt) = + ErrorScope.Protect range0 + (fun () -> + + let declItemsOpt = + GetDeclItemsForNamesAtPosition(None, namesOpt, None, None, + line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, + ResolveOverloads.No, (fun() -> [])) + + match declItemsOpt with + | None -> MethodGroup("",[| |]) + | Some (items, denv, _, m) -> + // GetDeclItemsForNamesAtPosition returns Items.Types and Item.CtorGroup for `new T(|)`, // the Item.Types is not needed here as it duplicates (at best) parameterless ctor. let ctors = items |> List.filter (fun x -> match x.Item with Item.CtorGroup _ -> true | _ -> false) let items = match ctors with | [] -> items | ctors -> ctors - FSharpMethodGroup.Create(infoReader, m, denv, items |> List.map (fun x -> x.ItemWithInst))) - (fun msg -> + MethodGroup.Create(infoReader, tcAccessRights, m, denv, items |> List.map (fun x -> x.ItemWithInst))) + (fun msg -> Trace.TraceInformation(sprintf "FCS: recovering from error in GetMethods: '%s'" msg) - FSharpMethodGroup(msg,[| |])) - - member __.GetMethodsAsSymbols (ctok, line, lineStr, colAtEndOfNames, names) = - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, None,line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.No,(fun() -> []),fun _ -> false) with - | None | Some ([],_,_,_) -> None - | Some (items, denv, _, m) -> - let allItems = items |> List.collect (fun item -> SymbolHelpers.FlattenItems g m item.Item) - let symbols = allItems |> List.map (fun item -> FSharpSymbol.Create(cenv, item)) - Some (symbols, denv, m) - ) - (fun msg -> - Trace.TraceInformation(sprintf "FCS: recovering from error in GetMethodsAsSymbols: '%s'" msg) - None) - - member __.GetDeclarationLocation (ctok, line, lineStr, colAtEndOfNames, names, preferFlag) = - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors,ResolveOverloads.Yes,(fun() -> []), fun _ -> false) with - | None - | Some ([], _, _, _) -> FSharpFindDeclResult.DeclNotFound (FSharpFindDeclFailureReason.Unknown "") - | Some (item :: _, _, _, _) -> - let getTypeVarNames (ilinfo: ILMethInfo) = - let classTypeParams = ilinfo.DeclaringTyconRef.ILTyconRawMetadata.GenericParams |> List.map (fun paramDef -> paramDef.Name) - let methodTypeParams = ilinfo.FormalMethodTypars |> List.map (fun ty -> ty.Name) - classTypeParams @ methodTypeParams |> Array.ofList - - let result = - match item.Item with - | Item.CtorGroup (_, (ILMeth (_,ilinfo,_)) :: _) -> - match ilinfo.MetadataScope with - | ILScopeRef.Assembly assemblyRef -> - let typeVarNames = getTypeVarNames ilinfo - ParamTypeSymbol.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes - |> Option.map (fun args -> - let externalSym = ExternalSymbol.Constructor (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, args) - FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) - | _ -> None - - | Item.MethodGroup (name, (ILMeth (_,ilinfo,_)) :: _, _) -> - match ilinfo.MetadataScope with - | ILScopeRef.Assembly assemblyRef -> - let typeVarNames = getTypeVarNames ilinfo - ParamTypeSymbol.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes - |> Option.map (fun args -> - let externalSym = ExternalSymbol.Method (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, name, args, ilinfo.ILMethodRef.GenericArity) - FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) - | _ -> None - - | Item.Property (name, ILProp propInfo :: _) -> - let methInfo = - if propInfo.HasGetter then Some propInfo.GetterMethod - elif propInfo.HasSetter then Some propInfo.SetterMethod - else None - - match methInfo with - | Some methInfo -> - match methInfo.MetadataScope with - | ILScopeRef.Assembly assemblyRef -> - let externalSym = ExternalSymbol.Property (methInfo.ILMethodRef.DeclaringTypeRef.FullName, name) - Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) - | _ -> None - | None -> None - - | Item.ILField (ILFieldInfo (typeInfo, fieldDef)) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> - match typeInfo.ILScopeRef with - | ILScopeRef.Assembly assemblyRef -> - let externalSym = ExternalSymbol.Field (typeInfo.ILTypeRef.FullName, fieldDef.Name) - Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) - | _ -> None - - | Item.Event (ILEvent (ILEventInfo (typeInfo, eventDef))) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> - match typeInfo.ILScopeRef with - | ILScopeRef.Assembly assemblyRef -> - let externalSym = ExternalSymbol.Event (typeInfo.ILTypeRef.FullName, eventDef.Name) - Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) - | _ -> None - - | Item.ImplicitOp(_, {contents = Some(TraitConstraintSln.FSMethSln(_, _vref, _))}) -> - //Item.Value(vref) - None - - | Item.Types (_, TType_app (tr, _) :: _) when tr.IsLocalRef && tr.IsTypeAbbrev -> None - - | Item.Types (_, [ AppTy g (tr, _) ]) when not tr.IsLocalRef -> - match tr.TypeReprInfo, tr.PublicPath with - | TILObjectRepr(TILObjectReprData (ILScopeRef.Assembly assemblyRef, _, _)), Some (PubPath parts) -> - let fullName = parts |> String.concat "." - Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, ExternalSymbol.Type fullName)) - | _ -> None - | _ -> None - match result with - | Some x -> x - | None -> - match rangeOfItem g preferFlag item.Item with - | Some itemRange -> - let projectDir = Filename.directoryName (if projectFileName = "" then mainInputFileName else projectFileName) - let range = fileNameOfItem g (Some projectDir) itemRange item.Item - mkRange range itemRange.Start itemRange.End - |> FSharpFindDeclResult.DeclFound - | None -> - match item.Item with + MethodGroup(msg,[| |])) + + member _.GetMethodsAsSymbols (line, lineStr, colAtEndOfNames, names) = + ErrorScope.Protect range0 + (fun () -> + let declItemsOpt = + GetDeclItemsForNamesAtPosition (None, Some names, None, + None, line, lineStr, colAtEndOfNames, + ResolveTypeNamesToCtors, ResolveOverloads.No, + (fun() -> [])) + + match declItemsOpt with + | None | Some ([],_,_,_) -> None + | Some (items, denv, _, m) -> + let allItems = items |> List.collect (fun item -> FlattenItems g m item.ItemWithInst) + let symbols = allItems |> List.map (fun item -> FSharpSymbol.Create(cenv, item.Item), item) + Some (symbols, denv, m) + ) + (fun msg -> + Trace.TraceInformation(sprintf "FCS: recovering from error in GetMethodsAsSymbols: '%s'" msg) + None) + + member _.GetDeclarationLocation (line, lineStr, colAtEndOfNames, names, preferFlag) = + ErrorScope.Protect range0 + (fun () -> + + let declItemsOpt = + GetDeclItemsForNamesAtPosition (None, Some names, None, None, + line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, + ResolveOverloads.Yes, (fun() -> [])) + + match declItemsOpt with + | None + | Some ([], _, _, _) -> FindDeclResult.DeclNotFound (FindDeclFailureReason.Unknown "") + | Some (item :: _, _, _, _) -> + let getTypeVarNames (ilinfo: ILMethInfo) = + let classTypeParams = ilinfo.DeclaringTyconRef.ILTyconRawMetadata.GenericParams |> List.map (fun paramDef -> paramDef.Name) + let methodTypeParams = ilinfo.FormalMethodTypars |> List.map (fun ty -> ty.Name) + classTypeParams @ methodTypeParams |> Array.ofList + + let result = + match item.Item with + | Item.CtorGroup (_, ILMeth (_,ilinfo,_) :: _) -> + match ilinfo.MetadataScope with + | ILScopeRef.Assembly assemblyRef -> + let typeVarNames = getTypeVarNames ilinfo + FindDeclExternalParam.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes + |> Option.map (fun args -> + let externalSym = FindDeclExternalSymbol.Constructor (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, args) + FindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) + | _ -> None + + | Item.MethodGroup (name, ILMeth (_,ilinfo,_) :: _, _) -> + match ilinfo.MetadataScope with + | ILScopeRef.Assembly assemblyRef -> + let typeVarNames = getTypeVarNames ilinfo + FindDeclExternalParam.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes + |> Option.map (fun args -> + let externalSym = FindDeclExternalSymbol.Method (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, name, args, ilinfo.ILMethodRef.GenericArity) + FindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) + | _ -> None + + | Item.Property (name, ILProp propInfo :: _) -> + let methInfo = + if propInfo.HasGetter then Some propInfo.GetterMethod + elif propInfo.HasSetter then Some propInfo.SetterMethod + else None + + match methInfo with + | Some methInfo -> + match methInfo.MetadataScope with + | ILScopeRef.Assembly assemblyRef -> + let externalSym = FindDeclExternalSymbol.Property (methInfo.ILMethodRef.DeclaringTypeRef.FullName, name) + Some (FindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) + | _ -> None + | None -> None + + | Item.ILField (ILFieldInfo (typeInfo, fieldDef)) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> + match typeInfo.ILScopeRef with + | ILScopeRef.Assembly assemblyRef -> + let externalSym = FindDeclExternalSymbol.Field (typeInfo.ILTypeRef.FullName, fieldDef.Name) + Some (FindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) + | _ -> None + + | Item.Event (ILEvent (ILEventInfo (typeInfo, eventDef))) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> + match typeInfo.ILScopeRef with + | ILScopeRef.Assembly assemblyRef -> + let externalSym = FindDeclExternalSymbol.Event (typeInfo.ILTypeRef.FullName, eventDef.Name) + Some (FindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) + | _ -> None + + | Item.ImplicitOp(_, {contents = Some(TraitConstraintSln.FSMethSln(_, _vref, _))}) -> + //Item.Value(vref) + None + + | Item.Types (_, TType_app (tr, _) :: _) when tr.IsLocalRef && tr.IsTypeAbbrev -> None + + | Item.Types (_, [ AppTy g (tr, _) ]) when not tr.IsLocalRef -> + match tr.TypeReprInfo, tr.PublicPath with + | TILObjectRepr(TILObjectReprData (ILScopeRef.Assembly assemblyRef, _, _)), Some (PubPath parts) -> + let fullName = parts |> String.concat "." + Some (FindDeclResult.ExternalDecl (assemblyRef.Name, FindDeclExternalSymbol.Type fullName)) + | _ -> None + | _ -> None + match result with + | Some x -> x + | None -> + match rangeOfItem g preferFlag item.Item with + | Some itemRange -> + let projectDir = FileSystem.GetDirectoryNameShim (if projectFileName = "" then mainInputFileName else projectFileName) + let range = fileNameOfItem g (Some projectDir) itemRange item.Item + mkRange range itemRange.Start itemRange.End + |> FindDeclResult.DeclFound + | None -> + match item.Item with #if !NO_EXTENSIONTYPING // provided items may have TypeProviderDefinitionLocationAttribute that binds them to some location - | Item.CtorGroup (name, ProvidedMeth (_)::_ ) - | Item.MethodGroup(name, ProvidedMeth (_)::_, _) - | Item.Property (name, ProvidedProp (_)::_ ) -> FSharpFindDeclFailureReason.ProvidedMember name - | Item.Event ( ProvidedEvent(_) as e ) -> FSharpFindDeclFailureReason.ProvidedMember e.EventName - | Item.ILField ( ProvidedField(_) as f ) -> FSharpFindDeclFailureReason.ProvidedMember f.FieldName - | SymbolHelpers.ItemIsProvidedType g (tcref) -> FSharpFindDeclFailureReason.ProvidedType tcref.DisplayName + | Item.CtorGroup (name, ProvidedMeth _::_ ) + | Item.MethodGroup(name, ProvidedMeth _::_, _) + | Item.Property (name, ProvidedProp _::_ ) -> FindDeclFailureReason.ProvidedMember name + | Item.Event ( ProvidedEvent _ as e ) -> FindDeclFailureReason.ProvidedMember e.EventName + | Item.ILField ( ProvidedField _ as f ) -> FindDeclFailureReason.ProvidedMember f.FieldName + | ItemIsProvidedType g tcref -> FindDeclFailureReason.ProvidedType tcref.DisplayName #endif - | _ -> FSharpFindDeclFailureReason.Unknown "" - |> FSharpFindDeclResult.DeclNotFound - ) - (fun msg -> - Trace.TraceInformation(sprintf "FCS: recovering from error in GetDeclarationLocation: '%s'" msg) - FSharpFindDeclResult.DeclNotFound (FSharpFindDeclFailureReason.Unknown msg)) - - member __.GetSymbolUseAtLocation (ctok, line, lineStr, colAtEndOfNames, names) = - ErrorScope.Protect Range.range0 - (fun () -> - match GetDeclItemsForNamesAtPosition (ctok, None,Some(names), None, None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.Yes,(fun() -> []), fun _ -> false) with - | None | Some ([], _, _, _) -> None - | Some (item :: _, denv, _, m) -> - let symbol = FSharpSymbol.Create(cenv, item.Item) - Some (symbol, denv, m) - ) - (fun msg -> - Trace.TraceInformation(sprintf "FCS: recovering from error in GetSymbolUseAtLocation: '%s'" msg) - None) - - member __.PartialAssemblySignatureForFile = + | _ -> FindDeclFailureReason.Unknown "" + |> FindDeclResult.DeclNotFound + ) + (fun msg -> + Trace.TraceInformation(sprintf "FCS: recovering from error in GetDeclarationLocation: '%s'" msg) + FindDeclResult.DeclNotFound (FindDeclFailureReason.Unknown msg)) + + member _.GetSymbolUseAtLocation (line, lineStr, colAtEndOfNames, names) = + ErrorScope.Protect range0 + (fun () -> + let declItemsOpt = + GetDeclItemsForNamesAtPosition (None, Some names, None, None, + line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, + ResolveOverloads.Yes, (fun() -> [])) + + match declItemsOpt with + | None | Some ([], _, _, _) -> None + | Some (item :: _, denv, _, m) -> + let symbol = FSharpSymbol.Create(cenv, item.Item) + Some (symbol, item.ItemWithInst, denv, m) + ) + (fun msg -> + Trace.TraceInformation(sprintf "FCS: recovering from error in GetSymbolUseAtLocation: '%s'" msg) + None) + + member _.PartialAssemblySignatureForFile = FSharpAssemblySignature(g, thisCcu, ccuSigForFile, tcImports, None, ccuSigForFile) - member __.AccessRights = tcAccessRights + member _.AccessRights = tcAccessRights + + member _.ProjectOptions = projectOptions - member __.GetReferencedAssemblies() = - [ for x in tcImports.GetImportedAssemblies() do + member _.GetReferencedAssemblies() = + [ for x in tcImports.GetImportedAssemblies() do yield FSharpAssembly(g, tcImports, x.FSharpViewOfMetadata) ] - member __.GetFormatSpecifierLocationsAndArity() = + member _.GetFormatSpecifierLocationsAndArity() = sSymbolUses.GetFormatSpecifierLocationsAndArity() - member __.GetSemanticClassification(range: range option) : (range * SemanticClassificationType) [] = - ErrorScope.Protect Range.range0 - (fun () -> - let (|LegitTypeOccurence|_|) = function - | ItemOccurence.UseInType - | ItemOccurence.UseInAttribute - | ItemOccurence.Use _ - | ItemOccurence.Binding _ - | ItemOccurence.Pattern _ -> Some() - | _ -> None - - let (|OptionalArgumentAttribute|_|) ttype = - match ttype with - | TType.TType_app(tref, _) when tref.Stamp = g.attrib_OptionalArgumentAttribute.TyconRef.Stamp -> Some() - | _ -> None - - let (|KeywordIntrinsicValue|_|) (vref: ValRef) = - if valRefEq g g.raise_vref vref || - valRefEq g g.reraise_vref vref || - valRefEq g g.typeof_vref vref || - valRefEq g g.typedefof_vref vref || - valRefEq g g.sizeof_vref vref || - valRefEq g g.nameof_vref vref - then Some() - else None - - let (|EnumCaseFieldInfo|_|) (rfinfo : RecdFieldInfo) = - match rfinfo.TyconRef.TypeReprInfo with - | TFSharpObjectRepr x -> - match x.fsobjmodel_kind with - | TTyconEnum -> Some () - | _ -> None - | _ -> None - - let resolutions = - match range with - | Some range -> - sResolutions.CapturedNameResolutions - |> Seq.filter (fun cnr -> rangeContainsPos range cnr.Range.Start || rangeContainsPos range cnr.Range.End) - | None -> - sResolutions.CapturedNameResolutions :> seq<_> - - let isDisposableTy (ty: TType) = - protectAssemblyExplorationNoReraise false false (fun () -> Infos.ExistsHeadTypeInEntireHierarchy g amap range0 ty g.tcref_System_IDisposable) - - let isStructTyconRef (tyconRef: TyconRef) = - let ty = generalizedTyconRef tyconRef - let underlyingTy = stripTyEqnsAndMeasureEqns g ty - isStructTy g underlyingTy - - let isValRefMutable (vref: ValRef) = - // Mutable values, ref cells, and non-inref byrefs are mutable. - vref.IsMutable - || Tastops.isRefCellTy g vref.Type - || (Tastops.isByrefTy g vref.Type && not (Tastops.isInByrefTy g vref.Type)) - - let isRecdFieldMutable (rfinfo: RecdFieldInfo) = - (rfinfo.RecdField.IsMutable && rfinfo.LiteralValue.IsNone) - || Tastops.isRefCellTy g rfinfo.RecdField.FormalType - - resolutions - |> Seq.choose (fun cnr -> - match cnr with - // 'seq' in 'seq { ... }' gets colored as keywords - | CNR(_, (Item.Value vref), ItemOccurence.Use, _, _, _, m) when valRefEq g g.seq_vref vref -> - Some (m, SemanticClassificationType.ComputationExpression) - | CNR(_, (Item.Value vref), _, _, _, _, m) when isValRefMutable vref -> - Some (m, SemanticClassificationType.MutableVar) - | CNR(_, Item.Value KeywordIntrinsicValue, ItemOccurence.Use, _, _, _, m) -> - Some (m, SemanticClassificationType.IntrinsicFunction) - | CNR(_, (Item.Value vref), _, _, _, _, m) when isFunction g vref.Type -> - if valRefEq g g.range_op_vref vref || valRefEq g g.range_step_op_vref vref then - None - elif vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then - Some (m, SemanticClassificationType.Property) - elif IsOperatorName vref.DisplayName then - Some (m, SemanticClassificationType.Operator) - else - Some (m, SemanticClassificationType.Function) - | CNR(_, Item.RecdField rfinfo, _, _, _, _, m) when isRecdFieldMutable rfinfo -> - Some (m, SemanticClassificationType.MutableVar) - | CNR(_, Item.RecdField rfinfo, _, _, _, _, m) when isFunction g rfinfo.FieldType -> - Some (m, SemanticClassificationType.Function) - | CNR(_, Item.RecdField EnumCaseFieldInfo, _, _, _, _, m) -> - Some (m, SemanticClassificationType.Enumeration) - | CNR(_, Item.MethodGroup _, _, _, _, _, m) -> - Some (m, SemanticClassificationType.Function) - // custom builders, custom operations get colored as keywords - | CNR(_, (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use, _, _, _, m) -> - Some (m, SemanticClassificationType.ComputationExpression) - // types get colored as types when they occur in syntactic types or custom attributes - // type variables get colored as types when they occur in syntactic types custom builders, custom operations get colored as keywords - | CNR(_, Item.Types (_, [OptionalArgumentAttribute]), LegitTypeOccurence, _, _, _, _) -> None - | CNR(_, Item.CtorGroup(_, [MethInfo.FSMeth(_, OptionalArgumentAttribute, _, _)]), LegitTypeOccurence, _, _, _, _) -> None - | CNR(_, Item.Types(_, types), LegitTypeOccurence, _, _, _, m) when types |> List.exists (isInterfaceTy g) -> - Some (m, SemanticClassificationType.Interface) - | CNR(_, Item.Types(_, types), LegitTypeOccurence, _, _, _, m) when types |> List.exists (isStructTy g) -> - Some (m, SemanticClassificationType.ValueType) - | CNR(_, Item.Types(_, TType_app(tyconRef, TType_measure _ :: _) :: _), LegitTypeOccurence, _, _, _, m) when isStructTyconRef tyconRef -> - Some (m, SemanticClassificationType.ValueType) - | CNR(_, Item.Types(_, types), LegitTypeOccurence, _, _, _, m) when types |> List.exists isDisposableTy -> - Some (m, SemanticClassificationType.Disposable) - | CNR(_, Item.Types _, LegitTypeOccurence, _, _, _, m) -> - Some (m, SemanticClassificationType.ReferenceType) - | CNR(_, (Item.TypeVar _ ), LegitTypeOccurence, _, _, _, m) -> - Some (m, SemanticClassificationType.TypeArgument) - | CNR(_, Item.UnqualifiedType tyconRefs, LegitTypeOccurence, _, _, _, m) -> - if tyconRefs |> List.exists (fun tyconRef -> tyconRef.Deref.IsStructOrEnumTycon) then - Some (m, SemanticClassificationType.ValueType) - else Some (m, SemanticClassificationType.ReferenceType) - | CNR(_, Item.CtorGroup(_, minfos), LegitTypeOccurence, _, _, _, m) -> - if minfos |> List.exists (fun minfo -> isStructTy g minfo.ApparentEnclosingType) then - Some (m, SemanticClassificationType.ValueType) - else Some (m, SemanticClassificationType.ReferenceType) - | CNR(_, Item.ExnCase _, LegitTypeOccurence, _, _, _, m) -> - Some (m, SemanticClassificationType.ReferenceType) - | CNR(_, Item.ModuleOrNamespaces refs, LegitTypeOccurence, _, _, _, m) when refs |> List.exists (fun x -> x.IsModule) -> - Some (m, SemanticClassificationType.Module) - | CNR(_, (Item.ActivePatternCase _ | Item.UnionCase _ | Item.ActivePatternResult _), _, _, _, _, m) -> - Some (m, SemanticClassificationType.UnionCase) - | _ -> None) - |> Seq.toArray - |> Array.append (sSymbolUses.GetFormatSpecifierLocationsAndArity() |> Array.map (fun m -> fst m, SemanticClassificationType.Printf)) - ) - (fun msg -> - Trace.TraceInformation(sprintf "FCS: recovering from error in GetSemanticClassification: '%s'" msg) - Array.empty) + member _.GetSemanticClassification(range: range option) : SemanticClassificationItem [] = + sResolutions.GetSemanticClassification(g, amap, sSymbolUses.GetFormatSpecifierLocationsAndArity(), range) /// The resolutions in the file - member __.ScopeResolutions = sResolutions + member _.ScopeResolutions = sResolutions /// The uses of symbols in the analyzed file - member __.ScopeSymbolUses = sSymbolUses + member _.ScopeSymbolUses = sSymbolUses - member __.TcGlobals = g + member _.TcGlobals = g - member __.TcImports = tcImports + member _.TcImports = tcImports /// The inferred signature of the file - member __.CcuSigForFile = ccuSigForFile + member _.CcuSigForFile = ccuSigForFile /// The assembly being analyzed - member __.ThisCcu = thisCcu + member _.ThisCcu = thisCcu - member __.ImplementationFile = implFileOpt + member _.ImplementationFile = implFileOpt /// All open declarations in the file, including auto open modules - member __.OpenDeclarations = openDeclarations + member _.OpenDeclarations = openDeclarations - member __.SymbolEnv = cenv + member _.SymbolEnv = cenv - override __.ToString() = "TypeCheckInfo(" + mainInputFileName + ")" + override _.ToString() = "TypeCheckInfo(" + mainInputFileName + ")" type FSharpParsingOptions = { SourceFiles: string [] ConditionalCompilationDefines: string list - ErrorSeverityOptions: FSharpErrorSeverityOptions + ErrorSeverityOptions: FSharpDiagnosticOptions + LangVersionText: string IsInteractive: bool LightSyntax: bool option CompilingFsLib: bool @@ -1431,7 +1536,8 @@ type FSharpParsingOptions = static member Default = { SourceFiles = Array.empty ConditionalCompilationDefines = [] - ErrorSeverityOptions = FSharpErrorSeverityOptions.Default + ErrorSeverityOptions = FSharpDiagnosticOptions.Default + LangVersionText = LanguageVersion.Default.VersionText IsInteractive = false LightSyntax = None CompilingFsLib = false @@ -1441,6 +1547,7 @@ type FSharpParsingOptions = { SourceFiles = sourceFiles ConditionalCompilationDefines = tcConfig.conditionalCompilationDefines ErrorSeverityOptions = tcConfig.errorSeverityOptions + LangVersionText = tcConfig.langVersion.VersionText IsInteractive = isInteractive LightSyntax = tcConfig.light CompilingFsLib = tcConfig.compilingFslib @@ -1451,18 +1558,19 @@ type FSharpParsingOptions = SourceFiles = sourceFiles ConditionalCompilationDefines = tcConfigB.conditionalCompilationDefines ErrorSeverityOptions = tcConfigB.errorSeverityOptions + LangVersionText = tcConfigB.langVersion.VersionText IsInteractive = isInteractive LightSyntax = tcConfigB.light CompilingFsLib = tcConfigB.compilingFslib IsExe = tcConfigB.target.IsExe } -module internal ParseAndCheckFile = +module internal ParseAndCheckFile = /// Error handler for parsing & type checking while processing a single file - type ErrorHandler(reportErrors, mainInputFileName, errorSeverityOptions: FSharpErrorSeverityOptions, sourceText: ISourceText, suggestNamesForErrors: bool) = + type ErrorHandler(reportErrors, mainInputFileName, errorSeverityOptions: FSharpDiagnosticOptions, sourceText: ISourceText, suggestNamesForErrors: bool) = let mutable options = errorSeverityOptions - let errorsAndWarningsCollector = new ResizeArray<_>() + let errorsAndWarningsCollector = ResizeArray<_>() let mutable errorCount = 0 // We'll need number of lines for adjusting error messages at EOF @@ -1480,63 +1588,60 @@ module internal ParseAndCheckFile = else exn if reportErrors then let report exn = - for ei in ErrorHelpers.ReportError (options, false, mainInputFileName, fileInfo, (exn, sev), suggestNamesForErrors) do + for ei in DiagnosticHelpers.ReportDiagnostic (options, false, mainInputFileName, fileInfo, (exn, sev), suggestNamesForErrors) do errorsAndWarningsCollector.Add ei - if sev = FSharpErrorSeverity.Error then + if sev = FSharpDiagnosticSeverity.Error then errorCount <- errorCount + 1 match exn with #if !NO_EXTENSIONTYPING - | { Exception = (:? TypeProviderError as tpe) } -> tpe.Iter(fun e -> report { exn with Exception = e }) + | { Exception = :? TypeProviderError as tpe } -> tpe.Iter(fun e -> report { exn with Exception = e }) #endif | e -> report e let errorLogger = { new ErrorLogger("ErrorHandler") with - member x.DiagnosticSink (exn, isError) = diagnosticSink (if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning) exn + member x.DiagnosticSink (exn, severity) = diagnosticSink severity exn member x.ErrorCount = errorCount } // Public members - member __.ErrorLogger = errorLogger + member _.ErrorLogger = errorLogger - member __.CollectedDiagnostics = errorsAndWarningsCollector.ToArray() + member _.CollectedDiagnostics = errorsAndWarningsCollector.ToArray() - member __.ErrorCount = errorCount + member _.ErrorCount = errorCount - member __.ErrorSeverityOptions with set opts = options <- opts + member _.ErrorSeverityOptions with set opts = options <- opts - member __.AnyErrors = errorCount > 0 + member _.AnyErrors = errorCount > 0 let getLightSyntaxStatus fileName options = let lower = String.lowercase fileName - let lightOnByDefault = List.exists (Filename.checkSuffix lower) FSharpLightSyntaxFileSuffixes - let lightSyntaxStatus = if lightOnByDefault then (options.LightSyntax <> Some false) else (options.LightSyntax = Some true) - LightSyntaxStatus(lightSyntaxStatus, true) + let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix lower) FSharpLightSyntaxFileSuffixes + let lightStatus = if lightOnByDefault then (options.LightSyntax <> Some false) else (options.LightSyntax = Some true) + LightSyntaxStatus(lightStatus, true) let createLexerFunction fileName options lexbuf (errHandler: ErrorHandler) = - let lightSyntaxStatus = getLightSyntaxStatus fileName options + let lightStatus = getLightSyntaxStatus fileName options // If we're editing a script then we define INTERACTIVE otherwise COMPILED. // Since this parsing for intellisense we always define EDITING. let defines = (SourceFileImpl.AdditionalDefinesForUseInEditor options.IsInteractive) @ options.ConditionalCompilationDefines // Note: we don't really attempt to intern strings across a large scope. - let lexResourceManager = new Lexhelp.LexResourceManager() - + let lexResourceManager = LexResourceManager() + // When analyzing files using ParseOneFile, i.e. for the use of editing clients, we do not apply line directives. // TODO(pathmap): expose PathMap on the service API, and thread it through here - let lexargs = mkLexargs(fileName, defines, lightSyntaxStatus, lexResourceManager, [], errHandler.ErrorLogger, PathMap.empty) + let lexargs = mkLexargs(defines, lightStatus, lexResourceManager, [], errHandler.ErrorLogger, PathMap.empty) let lexargs = { lexargs with applyLineDirectives = false } - let tokenizer = LexFilter.LexFilter(lightSyntaxStatus, options.CompilingFsLib, Lexer.token lexargs true, lexbuf) - tokenizer.Lexer + let tokenizer = LexFilter.LexFilter(lightStatus, options.CompilingFsLib, Lexer.token lexargs true, lexbuf) + (fun _ -> tokenizer.GetToken()) - // Public callers are unable to answer LanguageVersion feature support questions. - // External Tools including the VS IDE will enable the default LanguageVersion - let isFeatureSupported (_featureId:LanguageFeature) = true - let createLexbuf sourceText isFeatureSupported = - UnicodeLexing.SourceTextAsLexbuf(isFeatureSupported, sourceText) + let createLexbuf langVersion sourceText = + UnicodeLexing.SourceTextAsLexbuf(true, LanguageVersion(langVersion), sourceText) let matchBraces(sourceText: ISourceText, fileName, options: FSharpParsingOptions, userOpName: string, suggestNamesForErrors: bool) = let delayedLogger = CapturingErrorLogger("matchBraces") @@ -1544,37 +1649,78 @@ module internal ParseAndCheckFile = use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "matchBraces", fileName) - + // Make sure there is an ErrorLogger installed whenever we do stuff that might record errors, even if we ultimately ignore the errors let delayedLogger = CapturingErrorLogger("matchBraces") use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayedLogger) use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse - - let matchingBraces = new ResizeArray<_>() - Lexhelp.usingLexbufForParsing(createLexbuf sourceText isFeatureSupported, fileName) (fun lexbuf -> + + let matchingBraces = ResizeArray<_>() + usingLexbufForParsing(createLexbuf options.LangVersionText sourceText, fileName) (fun lexbuf -> let errHandler = ErrorHandler(false, fileName, options.ErrorSeverityOptions, sourceText, suggestNamesForErrors) let lexfun = createLexerFunction fileName options lexbuf errHandler let parenTokensBalance t1 t2 = match t1, t2 with - | (LPAREN, RPAREN) - | (LPAREN, RPAREN_IS_HERE) - | (LBRACE, RBRACE) - | (LBRACE, RBRACE_IS_HERE) - | (SIG, END) - | (STRUCT, END) - | (LBRACK_BAR, BAR_RBRACK) - | (LBRACK, RBRACK) - | (LBRACK_LESS, GREATER_RBRACK) - | (BEGIN, END) -> true - | (LQUOTE q1, RQUOTE q2) -> q1 = q2 + | LPAREN, RPAREN + | LPAREN, RPAREN_IS_HERE + | LBRACE _, RBRACE _ + | LBRACE_BAR, BAR_RBRACE + | LBRACE _, RBRACE_IS_HERE + | INTERP_STRING_BEGIN_PART _, INTERP_STRING_END _ + | INTERP_STRING_BEGIN_PART _, INTERP_STRING_PART _ + | INTERP_STRING_PART _, INTERP_STRING_PART _ + | INTERP_STRING_PART _, INTERP_STRING_END _ + | SIG, END + | STRUCT, END + | LBRACK_BAR, BAR_RBRACK + | LBRACK, RBRACK + | LBRACK_LESS, GREATER_RBRACK + | BEGIN, END -> true + | LQUOTE q1, RQUOTE q2 -> q1 = q2 | _ -> false + let rec matchBraces stack = match lexfun lexbuf, stack with - | tok2, ((tok1, m1) :: stack') when parenTokensBalance tok1 tok2 -> - matchingBraces.Add(m1, lexbuf.LexemeRange) - matchBraces stack' - | ((LPAREN | LBRACE | LBRACK | LBRACK_BAR | LQUOTE _ | LBRACK_LESS) as tok), _ -> + | tok2, (tok1, m1) :: stackAfterMatch when parenTokensBalance tok1 tok2 -> + let m2 = lexbuf.LexemeRange + + // For INTERP_STRING_PART and INTERP_STRING_END grab the one character + // range that corresponds to the "}" at the start of the token + let m2Start = + match tok2 with + | INTERP_STRING_PART _ + | INTERP_STRING_END _ -> + mkFileIndexRange m2.FileIndex m2.Start (mkPos m2.Start.Line (m2.Start.Column+1)) + | _ -> m2 + + matchingBraces.Add(m1, m2Start) + + // INTERP_STRING_PART corresponds to both "} ... {" i.e. both the completion + // of a match and the start of a potential new one. + let stackAfterMatch = + match tok2 with + | INTERP_STRING_PART _ -> + let m2End = mkFileIndexRange m2.FileIndex (mkPos m2.End.Line (max (m2.End.Column-1) 0)) m2.End + (tok2, m2End) :: stackAfterMatch + | _ -> stackAfterMatch + + matchBraces stackAfterMatch + + | LPAREN | LBRACE _ | LBRACK | LBRACE_BAR | LBRACK_BAR | LQUOTE _ | LBRACK_LESS as tok, _ -> matchBraces ((tok, lexbuf.LexemeRange) :: stack) + + // INTERP_STRING_BEGIN_PART corresponds to $"... {" at the start of an interpolated string + // + // INTERP_STRING_PART corresponds to "} ... {" in the middle of an interpolated string (in + // this case it msut not have matched something on the stack, e.g. an incomplete '[' in the + // interpolation expression) + // + // Either way we start a new potential match at the last character + | INTERP_STRING_BEGIN_PART _ | INTERP_STRING_PART _ as tok, _ -> + let m = lexbuf.LexemeRange + let m2 = mkFileIndexRange m.FileIndex (mkPos m.End.Line (max (m.End.Column-1) 0)) m.End + matchBraces ((tok, m2) :: stack) + | (EOF _ | LEX_FAILURE _), _ -> () | _ -> matchBraces stack matchBraces []) @@ -1582,87 +1728,99 @@ module internal ParseAndCheckFile = let parseFile(sourceText: ISourceText, fileName, options: FSharpParsingOptions, userOpName: string, suggestNamesForErrors: bool) = Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "parseFile", fileName) - let errHandler = new ErrorHandler(true, fileName, options.ErrorSeverityOptions, sourceText, suggestNamesForErrors) + let errHandler = ErrorHandler(true, fileName, options.ErrorSeverityOptions, sourceText, suggestNamesForErrors) use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _oldLogger -> errHandler.ErrorLogger) use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse let parseResult = - Lexhelp.usingLexbufForParsing(createLexbuf sourceText isFeatureSupported, fileName) (fun lexbuf -> + usingLexbufForParsing(createLexbuf options.LangVersionText sourceText, fileName) (fun lexbuf -> + let lexfun = createLexerFunction fileName options lexbuf errHandler let isLastCompiland = fileName.Equals(options.LastFileName, StringComparison.CurrentCultureIgnoreCase) || - CompileOps.IsScript(fileName) + IsScript(fileName) let isExe = options.IsExe - try Some (ParseInput(lexfun, errHandler.ErrorLogger, lexbuf, None, fileName, (isLastCompiland, isExe))) + + try + ParseInput(lexfun, errHandler.ErrorLogger, lexbuf, None, fileName, (isLastCompiland, isExe)) with e -> - errHandler.ErrorLogger.StopProcessingRecovery e Range.range0 // don't re-raise any exceptions, we must return None. - None) + errHandler.ErrorLogger.StopProcessingRecovery e range0 // don't re-raise any exceptions, we must return None. + EmptyParsedInput(fileName, (isLastCompiland, isExe))) + errHandler.CollectedDiagnostics, parseResult, errHandler.AnyErrors - let ApplyLoadClosure(tcConfig, parsedMainInput, mainInputFileName, loadClosure: LoadClosure option, tcImports: TcImports, backgroundDiagnostics) = + let ApplyLoadClosure(tcConfig, parsedMainInput, mainInputFileName, loadClosure: LoadClosure option, tcImports: TcImports, backgroundDiagnostics) = // If additional references were brought in by the preprocessor then we need to process them match loadClosure with | Some loadClosure -> // Play unresolved references for this file. tcImports.ReportUnresolvedAssemblyReferences(loadClosure.UnresolvedReferences) - + // If there was a loadClosure, replay the errors and warnings from resolution, excluding parsing loadClosure.LoadClosureRootFileDiagnostics |> List.iter diagnosticSink - + let fileOfBackgroundError err = (match GetRangeOfDiagnostic (fst err) with Some m-> m.FileName | None -> null) - let sameFile file hashLoadInFile = + let sameFile file hashLoadInFile = (0 = String.Compare(hashLoadInFile, file, StringComparison.OrdinalIgnoreCase)) - + // walk the list of #loads and keep the ones for this file. - let hashLoadsInFile = - loadClosure.SourceFiles + let hashLoadsInFile = + loadClosure.SourceFiles |> List.filter(fun (_,ms) -> ms<>[]) // #loaded file, ranges of #load - - let hashLoadBackgroundDiagnostics, otherBackgroundDiagnostics = - backgroundDiagnostics - |> Array.partition (fun backgroundError -> - hashLoadsInFile + + let hashLoadBackgroundDiagnostics, otherBackgroundDiagnostics = + backgroundDiagnostics + |> Array.partition (fun backgroundError -> + hashLoadsInFile |> List.exists (fst >> sameFile (fileOfBackgroundError backgroundError))) - + // Create single errors for the #load-ed files. // Group errors and warnings by file name. - let hashLoadBackgroundDiagnosticsGroupedByFileName = - hashLoadBackgroundDiagnostics - |> Array.map(fun err -> fileOfBackgroundError err,err) + let hashLoadBackgroundDiagnosticsGroupedByFileName = + hashLoadBackgroundDiagnostics + |> Array.map(fun err -> fileOfBackgroundError err,err) |> Array.groupBy fst // fileWithErrors, error list - - // Join the sets and report errors. + + // Join the sets and report errors. // It is by-design that these messages are only present in the language service. A true build would report the errors at their // spots in the individual source files. - for (fileOfHashLoad, rangesOfHashLoad) in hashLoadsInFile do - for (file, errorGroupedByFileName) in hashLoadBackgroundDiagnosticsGroupedByFileName do + for fileOfHashLoad, rangesOfHashLoad in hashLoadsInFile do + for file, errorGroupedByFileName in hashLoadBackgroundDiagnosticsGroupedByFileName do if sameFile file fileOfHashLoad then for rangeOfHashLoad in rangesOfHashLoad do // Handle the case of two #loads of the same file let diagnostics = errorGroupedByFileName |> Array.map(fun (_,(pe,f)) -> pe.Exception,f) // Strip the build phase here. It will be replaced, in total, with TypeCheck - let errors = [ for (err,sev) in diagnostics do if sev = FSharpErrorSeverity.Error then yield err ] - let warnings = [ for (err,sev) in diagnostics do if sev = FSharpErrorSeverity.Warning then yield err ] - - let message = HashLoadedSourceHasIssues(warnings,errors,rangeOfHashLoad) - if errors=[] then warning(message) - else errorR(message) - + let errors = [ for err, sev in diagnostics do if sev = FSharpDiagnosticSeverity.Error then yield err ] + let warnings = [ for err, sev in diagnostics do if sev = FSharpDiagnosticSeverity.Warning then yield err ] + let infos = [ for err, sev in diagnostics do if sev = FSharpDiagnosticSeverity.Info then yield err ] + + let message = HashLoadedSourceHasIssues(infos, warnings, errors, rangeOfHashLoad) + if isNil errors && isNil warnings then + warning message + elif isNil errors then + warning message + else + errorR message + // Replay other background errors. - for (phasedError,sev) in otherBackgroundDiagnostics do - if sev = FSharpErrorSeverity.Warning then - warning phasedError.Exception - else errorR phasedError.Exception - - | None -> + for phasedError, sev in otherBackgroundDiagnostics do + match sev with + | FSharpDiagnosticSeverity.Info -> informationalWarning phasedError.Exception + | FSharpDiagnosticSeverity.Warning -> warning phasedError.Exception + | FSharpDiagnosticSeverity.Error -> errorR phasedError.Exception + | FSharpDiagnosticSeverity.Hidden -> () + + | None -> // For non-scripts, check for disallow #r and #load. - ApplyMetaCommandsFromInputToTcConfig (tcConfig, parsedMainInput,Path.GetDirectoryName mainInputFileName) |> ignore - + ApplyMetaCommandsFromInputToTcConfig (tcConfig, parsedMainInput, Path.GetDirectoryName mainInputFileName, tcImports.DependencyProvider) |> ignore + // Type check a single file against an initial context, gleaning both errors and intellisense information. let CheckOneFile (parseResults: FSharpParseFileResults, sourceText: ISourceText, mainInputFileName: string, + projectOptions: FSharpProjectOptions, projectFileName: string, tcConfig: TcConfig, tcGlobals: TcGlobals, @@ -1670,54 +1828,44 @@ module internal ParseAndCheckFile = tcState: TcState, moduleNamesDict: ModuleNamesDict, loadClosure: LoadClosure option, - // These are the errors and warnings seen by the background compiler for the entire antecedent - backgroundDiagnostics: (PhasedDiagnostic * FSharpErrorSeverity)[], - reactorOps: IReactorOperations, - // Used by 'FSharpDeclarationListInfo' to check the IncrementalBuilder is still alive. - textSnapshotInfo : obj option, - userOpName: string, - suggestNamesForErrors: bool) = async { + // These are the errors and warnings seen by the background compiler for the entire antecedent + backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[], + suggestNamesForErrors: bool) = + cancellable { use _logBlock = Logger.LogBlock LogCompilerFunctionId.Service_CheckOneFile - match parseResults.ParseTree with - // When processing the following cases, we don't need to type-check - | None -> return [||], Result.Error() - - // Run the type checker... - | Some parsedMainInput -> + let parsedMainInput = parseResults.ParseTree + + // Initialize the error handler + let errHandler = ErrorHandler(true, mainInputFileName, tcConfig.errorSeverityOptions, sourceText, suggestNamesForErrors) - // Initialize the error handler - let errHandler = new ErrorHandler(true, mainInputFileName, tcConfig.errorSeverityOptions, sourceText, suggestNamesForErrors) - use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _oldLogger -> errHandler.ErrorLogger) use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck - + // Apply nowarns to tcConfig (may generate errors, so ensure errorLogger is installed) let tcConfig = ApplyNoWarnsToTcConfig (tcConfig, parsedMainInput,Path.GetDirectoryName mainInputFileName) - + // update the error handler with the modified tcConfig errHandler.ErrorSeverityOptions <- tcConfig.errorSeverityOptions - + // Play background errors and warnings for this file. - for (err,sev) in backgroundDiagnostics do - diagnosticSink (err, (sev = FSharpErrorSeverity.Error)) - + do for err, severity in backgroundDiagnostics do + diagnosticSink (err, severity) + // If additional references were brought in by the preprocessor then we need to process them ApplyLoadClosure(tcConfig, parsedMainInput, mainInputFileName, loadClosure, tcImports, backgroundDiagnostics) - - // A problem arises with nice name generation, which really should only - // be done in the backend, but is also done in the typechecker for better or worse. - // If we don't do this the NNG accumulates data and we get a memory leak. + + // A problem arises with nice name generation, which really should only + // be done in the backend, but is also done in the typechecker for better or worse. + // If we don't do this the NNG accumulates data and we get a memory leak. tcState.NiceNameGenerator.Reset() - - // Typecheck the real input. + + // Typecheck the real input. let sink = TcResultsSinkImpl(tcGlobals, sourceText = sourceText) - let! ct = Async.CancellationToken - let! resOpt = - async { + cancellable { try let checkForErrors() = (parseResults.ParseHadErrors || errHandler.ErrorCount > 0) @@ -1725,315 +1873,284 @@ module internal ParseAndCheckFile = // Typecheck is potentially a long running operation. We chop it up here with an Eventually continuation and, at each slice, give a chance // for the client to claim the result as obsolete and have the typecheck abort. - - let! result = - TypeCheckOneInputAndFinishEventually(checkForErrors, tcConfig, tcImports, tcGlobals, None, TcResultsSink.WithSink sink, tcState, parsedMainInput) - |> Eventually.repeatedlyProgressUntilDoneOrTimeShareOverOrCanceled maxTimeShareMilliseconds ct (fun ctok f -> f ctok) - |> Eventually.forceAsync - (fun work -> - reactorOps.EnqueueAndAwaitOpAsync(userOpName, "CheckOneFile.Fragment", mainInputFileName, - fun ctok -> - // This work is not cancellable - let res = - // Reinstall the compilation globals each time we start or restart - use unwind = new CompilationGlobalsScope (errHandler.ErrorLogger, BuildPhase.TypeCheck) - work ctok - cancellable.Return(res) - )) - + + use _unwind = new CompilationGlobalsScope (errHandler.ErrorLogger, BuildPhase.TypeCheck) + let! result = + TypeCheckOneInputAndFinish(checkForErrors, tcConfig, tcImports, tcGlobals, None, TcResultsSink.WithSink sink, tcState, parsedMainInput) + return result with e -> errorR e - return Some((tcState.TcEnvFromSignatures, EmptyTopAttrs, [], [NewEmptyModuleOrNamespaceType Namespace]), tcState) - } - + let mty = Construct.NewEmptyModuleOrNamespaceType ModuleOrNamespaceKind.Namespace + return ((tcState.TcEnvFromSignatures, EmptyTopAttrs, [], [ mty ]), tcState) + } + let errors = errHandler.CollectedDiagnostics - - let res = + + let res = match resOpt with - | Some ((tcEnvAtEnd, _, implFiles, ccuSigsForFiles), tcState) -> - TypeCheckInfo(tcConfig, tcGlobals, - List.head ccuSigsForFiles, + | (tcEnvAtEnd, _, implFiles, ccuSigsForFiles), tcState -> + TypeCheckInfo(tcConfig, tcGlobals, + List.head ccuSigsForFiles, tcState.Ccu, tcImports, tcEnvAtEnd.AccessRights, - projectFileName, - mainInputFileName, - sink.GetResolutions(), + projectFileName, + mainInputFileName, + projectOptions, + sink.GetResolutions(), sink.GetSymbolUses(), tcEnvAtEnd.NameEnv, loadClosure, - reactorOps, - textSnapshotInfo, List.tryHead implFiles, - sink.GetOpenDeclarations()) - |> Result.Ok - | None -> - Result.Error() + sink.GetOpenDeclarations()) return errors, res - } + } +[] +type FSharpProjectContext(thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad: AccessorDomain, projectOptions: FSharpProjectOptions) = -[] -type FSharpProjectContext(thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad: AccessorDomain) = + member _.ProjectOptions = projectOptions - /// Get the assemblies referenced - member __.GetReferencedAssemblies() = assemblies + member _.GetReferencedAssemblies() = assemblies - member __.AccessibilityRights = FSharpAccessibilityRights(thisCcu, ad) + member _.AccessibilityRights = FSharpAccessibilityRights(thisCcu, ad) [] /// A live object of this type keeps the background corresponding background builder (and type providers) alive (through reference-counting). // -// There is an important property of all the objects returned by the methods of this type: they do not require -// the corresponding background builder to be alive. That is, they are simply plain-old-data through pre-formatting of all result text. +// Note: objects returned by the methods of this type do not require the corresponding background builder to be alive. type FSharpCheckFileResults - (filename: string, - errors: FSharpErrorInfo[], - scopeOptX: TypeCheckInfo option, - dependencyFiles: string[], - builderX: IncrementalBuilder option, - reactorOpsX:IReactorOperations, + (filename: string, + errors: FSharpDiagnostic[], + scopeOptX: TypeCheckInfo option, + dependencyFiles: string[], + builderX: IncrementalBuilder option, keepAssemblyContents: bool) = - // This may be None initially - let mutable details = match scopeOptX with None -> None | Some scopeX -> Some (scopeX, builderX, reactorOpsX) - - // Run an operation that needs to access a builder and be run in the reactor thread - let reactorOp userOpName opName dflt f = - async { - match details with - | None -> - return dflt - | Some (scope, _, reactor) -> - // Increment the usage count to ensure the builder doesn't get released while running operations asynchronously. - let! res = reactor.EnqueueAndAwaitOpAsync(userOpName, opName, filename, fun ctok -> f ctok scope |> cancellable.Return) - return res - } + // Here 'details' keeps 'builder' alive + let details = match scopeOptX with None -> None | Some scopeX -> Some (scopeX, builderX) // Run an operation that can be called from any thread - let threadSafeOp dflt f = + let threadSafeOp dflt f = match details with | None -> dflt() - | Some (scope, _builderOpt, _ops) -> f scope + | Some (scope, _builderOpt) -> f scope - member __.Errors = errors + member _.Diagnostics = errors - member __.HasFullTypeCheckInfo = details.IsSome - - member info.TryGetCurrentTcImports () = - match builderX with - | Some builder -> builder.TryGetCurrentTcImports () - | _ -> None + member _.HasFullTypeCheckInfo = details.IsSome + + member _.TryGetCurrentTcImports () = + match details with + | None -> None + | Some (scope, _builderOpt) -> Some scope.TcImports /// Intellisense autocompletions - member __.GetDeclarationListInfo(parseResultsOpt, line, lineStr, partialName, ?getAllEntities, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" + member _.GetDeclarationListInfo(parsedFileResults, line, lineText, partialName, ?getAllEntities) = let getAllEntities = defaultArg getAllEntities (fun() -> []) - let hasTextChangedSinceLastTypecheck = defaultArg hasTextChangedSinceLastTypecheck (fun _ -> false) - reactorOp userOpName "GetDeclarations" FSharpDeclarationListInfo.Empty (fun ctok scope -> - scope.GetDeclarations(ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck)) + threadSafeOp (fun () -> DeclarationListInfo.Empty) (fun scope -> + scope.GetDeclarations(parsedFileResults, line, lineText, partialName, getAllEntities)) - member __.GetDeclarationListSymbols(parseResultsOpt, line, lineStr, partialName, ?getAllEntities, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - let hasTextChangedSinceLastTypecheck = defaultArg hasTextChangedSinceLastTypecheck (fun _ -> false) + member _.GetDeclarationListSymbols(parsedFileResults, line, lineText, partialName, ?getAllEntities) = let getAllEntities = defaultArg getAllEntities (fun() -> []) - reactorOp userOpName "GetDeclarationListSymbols" List.empty (fun ctok scope -> - scope.GetDeclarationListSymbols(ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck)) - - /// Resolve the names at the given location to give a data tip - member __.GetStructuredToolTipText(line, colAtEndOfNames, lineStr, names, tokenTag, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - let dflt = FSharpToolTipText [] - match tokenTagToTokenId tokenTag with - | TOKEN_IDENT -> - reactorOp userOpName "GetStructuredToolTipText" dflt (fun ctok scope -> - scope.GetStructuredToolTipText(ctok, line, lineStr, colAtEndOfNames, names)) - | TOKEN_STRING | TOKEN_STRING_TEXT -> - reactorOp userOpName "GetReferenceResolutionToolTipText" dflt (fun ctok scope -> - scope.GetReferenceResolutionStructuredToolTipText(ctok, line, colAtEndOfNames) ) - | _ -> - async.Return dflt - - member info.GetToolTipText(line, colAtEndOfNames, lineStr, names, tokenTag, userOpName) = - info.GetStructuredToolTipText(line, colAtEndOfNames, lineStr, names, tokenTag, ?userOpName=userOpName) - |> Tooltips.Map Tooltips.ToFSharpToolTipText - - member __.GetF1Keyword (line, colAtEndOfNames, lineStr, names, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "GetF1Keyword" None (fun ctok scope -> - scope.GetF1Keyword (ctok, line, lineStr, colAtEndOfNames, names)) + threadSafeOp (fun () -> []) (fun scope -> + scope.GetDeclarationListSymbols(parsedFileResults, line, lineText, partialName, getAllEntities)) + + /// Resolve the names at the given location to give a data tip + member _.GetToolTip(line, colAtEndOfNames, lineText, names, tokenTag) = + let dflt = ToolTipText [] + match tokenTagToTokenId tokenTag with + | TOKEN_IDENT -> + threadSafeOp (fun () -> dflt) (fun scope -> + scope.GetStructuredToolTipText(line, lineText, colAtEndOfNames, names)) + | TOKEN_STRING | TOKEN_STRING_TEXT -> + threadSafeOp (fun () -> dflt) (fun scope -> + scope.GetReferenceResolutionStructuredToolTipText(line, colAtEndOfNames) ) + | _ -> + dflt + + member _.GetF1Keyword (line, colAtEndOfNames, lineText, names) = + threadSafeOp (fun () -> None) (fun scope -> + scope.GetF1Keyword (line, lineText, colAtEndOfNames, names)) // Resolve the names at the given location to a set of methods - member __.GetMethods(line, colAtEndOfNames, lineStr, names, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - let dflt = FSharpMethodGroup("",[| |]) - reactorOp userOpName "GetMethods" dflt (fun ctok scope -> - scope.GetMethods (ctok, line, lineStr, colAtEndOfNames, names)) - - member __.GetDeclarationLocation (line, colAtEndOfNames, lineStr, names, ?preferFlag, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - let dflt = FSharpFindDeclResult.DeclNotFound (FSharpFindDeclFailureReason.Unknown "") - reactorOp userOpName "GetDeclarationLocation" dflt (fun ctok scope -> - scope.GetDeclarationLocation (ctok, line, lineStr, colAtEndOfNames, names, preferFlag)) - - member __.GetSymbolUseAtLocation (line, colAtEndOfNames, lineStr, names, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "GetSymbolUseAtLocation" None (fun ctok scope -> - scope.GetSymbolUseAtLocation (ctok, line, lineStr, colAtEndOfNames, names) - |> Option.map (fun (sym,denv,m) -> FSharpSymbolUse(scope.TcGlobals,denv,sym,ItemOccurence.Use,m))) - - member __.GetMethodsAsSymbols (line, colAtEndOfNames, lineStr, names, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "GetMethodsAsSymbols" None (fun ctok scope -> - scope.GetMethodsAsSymbols (ctok, line, lineStr, colAtEndOfNames, names) + member _.GetMethods(line, colAtEndOfNames, lineText, names) = + let dflt = MethodGroup("",[| |]) + threadSafeOp (fun () -> dflt) (fun scope -> + scope.GetMethods (line, lineText, colAtEndOfNames, names)) + + member _.GetDeclarationLocation (line, colAtEndOfNames, lineText, names, ?preferFlag) = + let dflt = FindDeclResult.DeclNotFound (FindDeclFailureReason.Unknown "") + threadSafeOp (fun () -> dflt) (fun scope -> + scope.GetDeclarationLocation (line, lineText, colAtEndOfNames, names, preferFlag)) + + member _.GetSymbolUseAtLocation (line, colAtEndOfNames, lineText, names) = + threadSafeOp (fun () -> None) (fun scope -> + scope.GetSymbolUseAtLocation (line, lineText, colAtEndOfNames, names) + |> Option.map (fun (sym, itemWithInst, denv,m) -> FSharpSymbolUse(denv,sym,itemWithInst.TyparInst,ItemOccurence.Use,m))) + + member _.GetMethodsAsSymbols (line, colAtEndOfNames, lineText, names) = + threadSafeOp (fun () -> None) (fun scope -> + scope.GetMethodsAsSymbols (line, lineText, colAtEndOfNames, names) |> Option.map (fun (symbols,denv,m) -> - symbols |> List.map (fun sym -> FSharpSymbolUse(scope.TcGlobals,denv,sym,ItemOccurence.Use,m)))) + symbols |> List.map (fun (sym, itemWithInst) -> FSharpSymbolUse(denv,sym,itemWithInst.TyparInst,ItemOccurence.Use,m)))) - member __.GetSymbolAtLocation (line, colAtEndOfNames, lineStr, names, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "GetSymbolAtLocation" None (fun ctok scope -> - scope.GetSymbolUseAtLocation (ctok, line, lineStr, colAtEndOfNames, names) - |> Option.map (fun (sym,_,_) -> sym)) + member _.GetSymbolAtLocation (line, colAtEndOfNames, lineStr, names) = + threadSafeOp (fun () -> None) (fun scope -> + scope.GetSymbolUseAtLocation (line, lineStr, colAtEndOfNames, names) + |> Option.map (fun (sym,_,_,_) -> sym)) - member info.GetFormatSpecifierLocations() = + member info.GetFormatSpecifierLocations() = info.GetFormatSpecifierLocationsAndArity() |> Array.map fst - member __.GetFormatSpecifierLocationsAndArity() = - threadSafeOp - (fun () -> [| |]) - (fun scope -> - // This operation is not asynchronous - GetFormatSpecifierLocationsAndArity can be run on the calling thread + member _.GetFormatSpecifierLocationsAndArity() = + threadSafeOp + (fun () -> [| |]) + (fun scope -> scope.GetFormatSpecifierLocationsAndArity()) - member __.GetSemanticClassification(range: range option) = - threadSafeOp - (fun () -> [| |]) - (fun scope -> - // This operation is not asynchronous - GetSemanticClassification can be run on the calling thread + member _.GetSemanticClassification(range: range option) = + threadSafeOp + (fun () -> [| |]) + (fun scope -> scope.GetSemanticClassification(range)) - - member __.PartialAssemblySignature = - threadSafeOp - (fun () -> failwith "not available") - (fun scope -> - // This operation is not asynchronous - PartialAssemblySignature can be run on the calling thread + + member _.PartialAssemblySignature = + threadSafeOp + (fun () -> failwith "not available") + (fun scope -> scope.PartialAssemblySignatureForFile) - member __.ProjectContext = - threadSafeOp - (fun () -> failwith "not available") - (fun scope -> - // This operation is not asynchronous - GetReferencedAssemblies can be run on the calling thread - FSharpProjectContext(scope.ThisCcu, scope.GetReferencedAssemblies(), scope.AccessRights)) + member _.ProjectContext = + threadSafeOp + (fun () -> failwith "not available") + (fun scope -> + FSharpProjectContext(scope.ThisCcu, scope.GetReferencedAssemblies(), scope.AccessRights, scope.ProjectOptions)) - member __.DependencyFiles = dependencyFiles + member _.DependencyFiles = dependencyFiles - member __.GetAllUsesOfAllSymbolsInFile() = - threadSafeOp - (fun () -> [| |]) + member _.GetAllUsesOfAllSymbolsInFile(?cancellationToken: CancellationToken ) = + threadSafeOp + (fun () -> Seq.empty) (fun scope -> let cenv = scope.SymbolEnv - [| for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do - for symbolUse in symbolUseChunk do - if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then - let symbol = FSharpSymbol.Create(cenv, symbolUse.Item) - yield FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |]) - |> async.Return - - member __.GetUsesOfSymbolInFile(symbol:FSharpSymbol) = - threadSafeOp - (fun () -> [| |]) - (fun scope -> + seq { + for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do + for symbolUse in symbolUseChunk do + cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested()) + if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then + let symbol = FSharpSymbol.Create(cenv, symbolUse.ItemWithInst.Item) + FSharpSymbolUse(symbolUse.DisplayEnv, symbol, symbolUse.ItemWithInst.TyparInst, symbolUse.ItemOccurence, symbolUse.Range) + }) + + member _.GetUsesOfSymbolInFile(symbol:FSharpSymbol, ?cancellationToken: CancellationToken) = + threadSafeOp + (fun () -> [| |]) + (fun scope -> [| for symbolUse in scope.ScopeSymbolUses.GetUsesOfSymbol(symbol.Item) |> Seq.distinctBy (fun symbolUse -> symbolUse.ItemOccurence, symbolUse.Range) do + cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested()) if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then - yield FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |]) - |> async.Return + yield FSharpSymbolUse(symbolUse.DisplayEnv, symbol, symbolUse.ItemWithInst.TyparInst, symbolUse.ItemOccurence, symbolUse.Range) |]) - member __.GetVisibleNamespacesAndModulesAtPoint(pos: pos) = - threadSafeOp - (fun () -> [| |]) + member _.GetVisibleNamespacesAndModulesAtPoint(pos: pos) = + threadSafeOp + (fun () -> [| |]) (fun scope -> scope.GetVisibleNamespacesAndModulesAtPosition(pos) |> List.toArray) - |> async.Return - - member __.IsRelativeNameResolvable(pos: pos, plid: string list, item: Item, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "IsRelativeNameResolvable" true (fun ctok scope -> - RequireCompilationThread ctok - scope.IsRelativeNameResolvable(pos, plid, item)) - - member __.IsRelativeNameResolvableFromSymbol(pos: pos, plid: string list, symbol: FSharpSymbol, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - reactorOp userOpName "IsRelativeNameResolvableFromSymbol" true (fun ctok scope -> - RequireCompilationThread ctok - scope.IsRelativeNameResolvableFromSymbol(pos, plid, symbol)) - - member __.GetDisplayContextForPos(pos: pos) : Async = - let userOpName = "CodeLens" - reactorOp userOpName "GetDisplayContextAtPos" None (fun ctok scope -> - DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok - let (nenv, _), _ = scope.GetBestDisplayEnvForPos pos + + member _.IsRelativeNameResolvable(cursorPos: pos, plid: string list, item: Item) = + threadSafeOp (fun () -> true) (fun scope -> + scope.IsRelativeNameResolvable(cursorPos, plid, item)) + + member _.IsRelativeNameResolvableFromSymbol(cursorPos: pos, plid: string list, symbol: FSharpSymbol) = + threadSafeOp (fun () -> true) (fun scope -> + scope.IsRelativeNameResolvableFromSymbol(cursorPos, plid, symbol)) + + member _.GetDisplayContextForPos(cursorPos: pos) = + threadSafeOp (fun () -> None) (fun scope -> + let (nenv, _), _ = scope.GetBestDisplayEnvForPos cursorPos Some(FSharpDisplayContext(fun _ -> nenv.DisplayEnv))) - - member __.ImplementationFile = + + member _.GenerateSignature () = + threadSafeOp (fun () -> None) (fun scope -> + scope.ImplementationFile + |> Option.map (fun implFile -> + let denv = DisplayEnv.InitialForSigFileGeneration scope.TcGlobals + let infoReader = InfoReader(scope.TcGlobals, scope.TcImports.GetImportMap()) + let (TImplFile (_, _, mexpr, _, _, _)) = implFile + let ad = + match scopeOptX with + | Some scope -> scope.AccessRights + | _ -> AccessibleFromSomewhere + let layout = NicePrint.layoutInferredSigOfModuleExpr true denv infoReader ad range0 mexpr + layout |> LayoutRender.showL |> SourceText.ofString + ) + ) + + member _.ImplementationFile = if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies" - scopeOptX - |> Option.map (fun scope -> + scopeOptX + |> Option.map (fun scope -> let cenv = SymbolEnv(scope.TcGlobals, scope.ThisCcu, Some scope.CcuSigForFile, scope.TcImports) scope.ImplementationFile |> Option.map (fun implFile -> FSharpImplementationFileContents(cenv, implFile))) |> Option.defaultValue None - member __.OpenDeclarations = - scopeOptX - |> Option.map (fun scope -> + member _.OpenDeclarations = + scopeOptX + |> Option.map (fun scope -> let cenv = scope.SymbolEnv - scope.OpenDeclarations |> Array.map (fun x -> FSharpOpenDeclaration(x.LongId, x.Range, (x.Modules |> List.map (fun x -> FSharpEntity(cenv, x))), x.AppliedScope, x.IsOwnNamespace))) + scope.OpenDeclarations |> Array.map (fun x -> + let modules = x.Modules |> List.map (fun x -> FSharpEntity(cenv, x)) + let types = x.Types |> List.map (fun x -> FSharpType(cenv, x)) + FSharpOpenDeclaration(x.Target, x.Range, modules, types, x.AppliedScope, x.IsOwnNamespace))) |> Option.defaultValue [| |] - override __.ToString() = "FSharpCheckFileResults(" + filename + ")" + override _.ToString() = "FSharpCheckFileResults(" + filename + ")" - static member MakeEmpty(filename: string, creationErrors: FSharpErrorInfo[], reactorOps, keepAssemblyContents) = - FSharpCheckFileResults (filename, creationErrors, None, [| |], None, reactorOps, keepAssemblyContents) + static member MakeEmpty(filename: string, creationErrors: FSharpDiagnostic[], keepAssemblyContents) = + FSharpCheckFileResults (filename, creationErrors, None, [| |], None, keepAssemblyContents) - static member JoinErrors(isIncompleteTypeCheckEnvironment, - creationErrors: FSharpErrorInfo[], - parseErrors: FSharpErrorInfo[], - tcErrors: FSharpErrorInfo[]) = - [| yield! creationErrors + static member JoinErrors(isIncompleteTypeCheckEnvironment, + creationErrors: FSharpDiagnostic[], + parseErrors: FSharpDiagnostic[], + tcErrors: FSharpDiagnostic[]) = + [| yield! creationErrors yield! parseErrors - if isIncompleteTypeCheckEnvironment then + if isIncompleteTypeCheckEnvironment then yield! Seq.truncate maxTypeCheckErrorsOutOfProjectContext tcErrors - else + else yield! tcErrors |] static member Make - (mainInputFileName: string, - projectFileName, - tcConfig, tcGlobals, - isIncompleteTypeCheckEnvironment: bool, - builder: IncrementalBuilder, - dependencyFiles, - creationErrors: FSharpErrorInfo[], - parseErrors: FSharpErrorInfo[], - tcErrors: FSharpErrorInfo[], - reactorOps, + (mainInputFileName: string, + projectFileName, + tcConfig, tcGlobals, + isIncompleteTypeCheckEnvironment: bool, + builder: IncrementalBuilder, + projectOptions, + dependencyFiles, + creationErrors: FSharpDiagnostic[], + parseErrors: FSharpDiagnostic[], + tcErrors: FSharpDiagnostic[], keepAssemblyContents, - ccuSigForFile, - thisCcu, tcImports, tcAccessRights, - sResolutions, sSymbolUses, + ccuSigForFile, + thisCcu, tcImports, tcAccessRights, + sResolutions, sSymbolUses, sFallback, loadClosure, - implFileOpt, - openDeclarations) = - - let tcFileInfo = - TypeCheckInfo(tcConfig, tcGlobals, ccuSigForFile, thisCcu, tcImports, tcAccessRights, - projectFileName, mainInputFileName, sResolutions, sSymbolUses, - sFallback, loadClosure, reactorOps, - None, implFileOpt, openDeclarations) - + implFileOpt, + openDeclarations) = + + let tcFileInfo = + TypeCheckInfo(tcConfig, tcGlobals, ccuSigForFile, thisCcu, tcImports, tcAccessRights, + projectFileName, mainInputFileName, + projectOptions, + sResolutions, sSymbolUses, + sFallback, loadClosure, + implFileOpt, openDeclarations) + let errors = FSharpCheckFileResults.JoinErrors(isIncompleteTypeCheckEnvironment, creationErrors, parseErrors, tcErrors) - FSharpCheckFileResults (mainInputFileName, errors, Some tcFileInfo, dependencyFiles, Some builder, reactorOps, keepAssemblyContents) + FSharpCheckFileResults (mainInputFileName, errors, Some tcFileInfo, dependencyFiles, Some builder, keepAssemblyContents) static member CheckOneFile (parseResults: FSharpParseFileResults, @@ -2046,205 +2163,248 @@ type FSharpCheckFileResults tcState: TcState, moduleNamesDict: ModuleNamesDict, loadClosure: LoadClosure option, - backgroundDiagnostics: (PhasedDiagnostic * FSharpErrorSeverity)[], - reactorOps: IReactorOperations, - textSnapshotInfo : obj option, - userOpName: string, - isIncompleteTypeCheckEnvironment: bool, - builder: IncrementalBuilder, - dependencyFiles: string[], - creationErrors: FSharpErrorInfo[], - parseErrors: FSharpErrorInfo[], + backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[], + isIncompleteTypeCheckEnvironment: bool, + projectOptions: FSharpProjectOptions, + builder: IncrementalBuilder, + dependencyFiles: string[], + creationErrors: FSharpDiagnostic[], + parseErrors: FSharpDiagnostic[], keepAssemblyContents: bool, - suggestNamesForErrors: bool) = - async { - let! tcErrors, tcFileInfo = + suggestNamesForErrors: bool) = + cancellable { + let! tcErrors, tcFileInfo = ParseAndCheckFile.CheckOneFile - (parseResults, sourceText, mainInputFileName, projectFileName, tcConfig, tcGlobals, tcImports, - tcState, moduleNamesDict, loadClosure, backgroundDiagnostics, reactorOps, - textSnapshotInfo, userOpName, suggestNamesForErrors) - match tcFileInfo with - | Result.Error () -> - return FSharpCheckFileAnswer.Aborted - | Result.Ok tcFileInfo -> - let errors = FSharpCheckFileResults.JoinErrors(isIncompleteTypeCheckEnvironment, creationErrors, parseErrors, tcErrors) - let results = FSharpCheckFileResults (mainInputFileName, errors, Some tcFileInfo, dependencyFiles, Some builder, reactorOps, keepAssemblyContents) - return FSharpCheckFileAnswer.Succeeded(results) + (parseResults, sourceText, mainInputFileName, projectOptions, + projectFileName, tcConfig, tcGlobals, tcImports, + tcState, moduleNamesDict, loadClosure, backgroundDiagnostics, suggestNamesForErrors) + let errors = FSharpCheckFileResults.JoinErrors(isIncompleteTypeCheckEnvironment, creationErrors, parseErrors, tcErrors) + let results = FSharpCheckFileResults (mainInputFileName, errors, Some tcFileInfo, dependencyFiles, Some builder, keepAssemblyContents) + return results } -and [] FSharpCheckFileAnswer = - | Aborted - | Succeeded of FSharpCheckFileResults - - [] // 'details' is an option because the creation of the tcGlobals etc. for the project may have failed. type FSharpCheckProjectResults - (projectFileName:string, - tcConfigOption: TcConfig option, - keepAssemblyContents: bool, - errors: FSharpErrorInfo[], - details:(TcGlobals * TcImports * CcuThunk * ModuleOrNamespaceType * TcSymbolUses list * TopAttribs option * CompileOps.IRawFSharpAssemblyData option * ILAssemblyRef * AccessorDomain * TypedImplFile list option * string[]) option) = - - let getDetails() = - match details with - | None -> invalidOp ("The project has no results due to critical errors in the project options. Check the HasCriticalErrors before accessing the detailed results. Errors: " + String.concat "\n" [ for e in errors -> e.Message ]) + (projectFileName:string, + tcConfigOption: TcConfig option, + keepAssemblyContents: bool, + diagnostics: FSharpDiagnostic[], + details:(TcGlobals * TcImports * CcuThunk * ModuleOrNamespaceType * Choice * + TopAttribs option * ILAssemblyRef * + AccessorDomain * TypedImplFile list option * string[] * FSharpProjectOptions) option) = + + let getDetails() = + match details with + | None -> invalidOp ("The project has no results due to critical errors in the project options. Check the HasCriticalErrors before accessing the detailed results. Errors: " + String.concat "\n" [ for e in diagnostics -> e.Message ]) | Some d -> d - let getTcConfig() = - match tcConfigOption with - | None -> invalidOp ("The project has no results due to critical errors in the project options. Check the HasCriticalErrors before accessing the detailed results. Errors: " + String.concat "\n" [ for e in errors -> e.Message ]) + let getTcConfig() = + match tcConfigOption with + | None -> invalidOp ("The project has no results due to critical errors in the project options. Check the HasCriticalErrors before accessing the detailed results. Errors: " + String.concat "\n" [ for e in diagnostics -> e.Message ]) | Some d -> d - member __.Errors = errors + member _.Diagnostics = diagnostics - member __.HasCriticalErrors = details.IsNone + member _.HasCriticalErrors = details.IsNone - member __.AssemblySignature = - let (tcGlobals, tcImports, thisCcu, ccuSig, _tcSymbolUses, topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() + member _.AssemblySignature = + let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() FSharpAssemblySignature(tcGlobals, thisCcu, ccuSig, tcImports, topAttribs, ccuSig) - member __.TypedImplementationFiles = + member _.TypedImplementationFiles = if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies" - let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles) = getDetails() - let mimpls = - match tcAssemblyExpr with + let tcGlobals, tcImports, thisCcu, _ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() + let mimpls = + match tcAssemblyExpr with | None -> [] | Some mimpls -> mimpls tcGlobals, thisCcu, tcImports, mimpls - member info.AssemblyContents = + member info.AssemblyContents = if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies" - let (tcGlobals, tcImports, thisCcu, ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles) = getDetails() - let mimpls = - match tcAssemblyExpr with + let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() + let mimpls = + match tcAssemblyExpr with | None -> [] | Some mimpls -> mimpls FSharpAssemblyContents(tcGlobals, thisCcu, Some ccuSig, tcImports, mimpls) - member __.GetOptimizedAssemblyContents() = + member _.GetOptimizedAssemblyContents() = if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to true on the FSharpChecker in order to access the checked contents of assemblies" - let (tcGlobals, tcImports, thisCcu, ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles) = getDetails() - let mimpls = - match tcAssemblyExpr with + let tcGlobals, tcImports, thisCcu, ccuSig, _builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() + let mimpls = + match tcAssemblyExpr with | None -> [] | Some mimpls -> mimpls let outfile = "" // only used if tcConfig.writeTermsToFiles is true let importMap = tcImports.GetImportMap() let optEnv0 = GetInitialOptimizationEnv (tcImports, tcGlobals) let tcConfig = getTcConfig() - let optimizedImpls, _optimizationData, _ = ApplyAllOptimizations (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, importMap, false, optEnv0, thisCcu, mimpls) + let optimizedImpls, _optimizationData, _ = ApplyAllOptimizations (tcConfig, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), outfile, importMap, false, optEnv0, thisCcu, mimpls) let mimpls = match optimizedImpls with | TypedAssemblyAfterOptimization files -> - files |> List.map fst + files |> List.map (fun implFile -> implFile.ImplFile) FSharpAssemblyContents(tcGlobals, thisCcu, Some ccuSig, tcImports, mimpls) // Not, this does not have to be a SyncOp, it can be called from any thread - member __.GetUsesOfSymbol(symbol:FSharpSymbol) = - let (tcGlobals, _tcImports, _thisCcu, _ccuSig, tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() - - tcSymbolUses - |> Seq.collect (fun r -> r.GetUsesOfSymbol symbol.Item) - |> Seq.distinctBy (fun symbolUse -> symbolUse.ItemOccurence, symbolUse.Range) - |> Seq.filter (fun symbolUse -> symbolUse.ItemOccurence <> ItemOccurence.RelatedText) - |> Seq.map (fun symbolUse -> FSharpSymbolUse(tcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range)) + member _.GetUsesOfSymbol(symbol:FSharpSymbol, ?cancellationToken: CancellationToken) = + let _, _tcImports, _thisCcu, _ccuSig, builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() + + let results = + match builderOrSymbolUses with + | Choice1Of2 builder -> + builder.SourceFiles + |> Array.ofList + |> Array.collect (fun x -> + match builder.GetCheckResultsForFileInProjectEvenIfStale x with + | Some partialCheckResults -> + match partialCheckResults.TryPeekTcInfoWithExtras() with + | Some(_, tcInfoExtras) -> + tcInfoExtras.TcSymbolUses.GetUsesOfSymbol symbol.Item + | _ -> + [||] + | _ -> + [||] + ) + | Choice2Of2 tcSymbolUses -> + tcSymbolUses.GetUsesOfSymbol symbol.Item + + results + |> Seq.filter (fun symbolUse -> symbolUse.ItemOccurence <> ItemOccurence.RelatedText) + |> Seq.distinctBy (fun symbolUse -> symbolUse.ItemOccurence, symbolUse.Range) + |> Seq.map (fun symbolUse -> + cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested()) + FSharpSymbolUse(symbolUse.DisplayEnv, symbol, symbolUse.ItemWithInst.TyparInst, symbolUse.ItemOccurence, symbolUse.Range)) |> Seq.toArray - |> async.Return // Not, this does not have to be a SyncOp, it can be called from any thread - member __.GetAllUsesOfAllSymbols() = - let (tcGlobals, tcImports, thisCcu, ccuSig, tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() + member _.GetAllUsesOfAllSymbols(?cancellationToken: CancellationToken) = + let tcGlobals, tcImports, thisCcu, ccuSig, builderOrSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() let cenv = SymbolEnv(tcGlobals, thisCcu, Some ccuSig, tcImports) + let tcSymbolUses = + match builderOrSymbolUses with + | Choice1Of2 builder -> + builder.SourceFiles + |> Array.ofList + |> Array.map (fun x -> + match builder.GetCheckResultsForFileInProjectEvenIfStale x with + | Some partialCheckResults -> + match partialCheckResults.TryPeekTcInfoWithExtras() with + | Some(_, tcInfoExtras) -> + tcInfoExtras.TcSymbolUses + | _ -> + TcSymbolUses.Empty + | _ -> + TcSymbolUses.Empty + ) + | Choice2Of2 tcSymbolUses -> + [|tcSymbolUses|] + [| for r in tcSymbolUses do - for symbolUseChunk in r.AllUsesOfSymbols do + for symbolUseChunk in r.AllUsesOfSymbols do for symbolUse in symbolUseChunk do - if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then - let symbol = FSharpSymbol.Create(cenv, symbolUse.Item) - yield FSharpSymbolUse(tcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |] - |> async.Return - - member __.ProjectContext = - let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() - let assemblies = - [ for x in tcImports.GetImportedAssemblies() do - yield FSharpAssembly(tcGlobals, tcImports, x.FSharpViewOfMetadata) ] - FSharpProjectContext(thisCcu, assemblies, ad) - - member __.RawFSharpAssemblyData = - let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() - tcAssemblyData - - member __.DependencyFiles = - let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr, dependencyFiles) = getDetails() + cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested()) + if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then + let symbol = FSharpSymbol.Create(cenv, symbolUse.ItemWithInst.Item) + yield FSharpSymbolUse(symbolUse.DisplayEnv, symbol, symbolUse.ItemWithInst.TyparInst, symbolUse.ItemOccurence, symbolUse.Range) |] + + member _.ProjectContext = + let tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _ilAssemRef, ad, _tcAssemblyExpr, _dependencyFiles, projectOptions = getDetails() + let assemblies = + tcImports.GetImportedAssemblies() + |> List.map (fun x -> FSharpAssembly(tcGlobals, tcImports, x.FSharpViewOfMetadata)) + FSharpProjectContext(thisCcu, assemblies, ad, projectOptions) + + member _.DependencyFiles = + let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _ilAssemRef, _ad, _tcAssemblyExpr, dependencyFiles, _projectOptions = getDetails() dependencyFiles - member __.AssemblyFullName = - let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles) = getDetails() + member _.AssemblyFullName = + let _tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, ilAssemRef, _ad, _tcAssemblyExpr, _dependencyFiles, _projectOptions = getDetails() ilAssemRef.QualifiedName - override __.ToString() = "FSharpCheckProjectResults(" + projectFileName + ")" + override _.ToString() = "FSharpCheckProjectResults(" + projectFileName + ")" -type FsiInteractiveChecker(legacyReferenceResolver, - reactorOps: IReactorOperations, +type FsiInteractiveChecker(legacyReferenceResolver, tcConfig: TcConfig, - tcGlobals, - tcImports, + tcGlobals: TcGlobals, + tcImports: TcImports, tcState) = let keepAssemblyContents = false - member __.ParseAndCheckInteraction (ctok, sourceText: ISourceText, ?userOpName: string) = - async { + member _.ParseAndCheckInteraction (sourceText: ISourceText, ?userOpName: string) = + cancellable { let userOpName = defaultArg userOpName "Unknown" let filename = Path.Combine(tcConfig.implicitIncludeDir, "stdin.fsx") let suggestNamesForErrors = true // Will always be true, this is just for readability // Note: projectSourceFiles is only used to compute isLastCompiland, and is ignored if Build.IsScript(mainInputFileName) is true (which it is in this case). let parsingOptions = FSharpParsingOptions.FromTcConfig(tcConfig, [| filename |], true) - let parseErrors, parseTreeOpt, anyErrors = ParseAndCheckFile.parseFile (sourceText, filename, parsingOptions, userOpName, suggestNamesForErrors) + let parseErrors, parsedInput, anyErrors = ParseAndCheckFile.parseFile (sourceText, filename, parsingOptions, userOpName, suggestNamesForErrors) let dependencyFiles = [| |] // interactions have no dependencies - let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, parseHadErrors = anyErrors, dependencyFiles = dependencyFiles) - + let parseResults = FSharpParseFileResults(parseErrors, parsedInput, parseHadErrors = anyErrors, dependencyFiles = dependencyFiles) + let backgroundDiagnostics = [| |] let reduceMemoryUsage = ReduceMemoryFlag.Yes - let assumeDotNetFramework = tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib + let assumeDotNetFramework = (tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib) - let applyCompilerOptions tcConfigB = - let fsiCompilerOptions = CompileOptions.GetCoreFsiCompilerOptions tcConfigB - CompileOptions.ParseCompilerOptions (ignore, fsiCompilerOptions, [ ]) + let applyCompilerOptions tcConfigB = + let fsiCompilerOptions = CompilerOptions.GetCoreFsiCompilerOptions tcConfigB + CompilerOptions.ParseCompilerOptions (ignore, fsiCompilerOptions, [ ]) let loadClosure = - LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, + LoadClosure.ComputeClosureOfScriptText(legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, CodeContext.Editing, tcConfig.useSimpleResolution, tcConfig.useFsiAuxLib, - tcConfig.useSdkRefs, new Lexhelp.LexResourceManager(), + tcConfig.useSdkRefs, tcConfig.sdkDirOverride, LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, - tryGetMetadataSnapshot=(fun _ -> None), reduceMemoryUsage=reduceMemoryUsage) - - let! tcErrors, tcFileInfo = + tryGetMetadataSnapshot=(fun _ -> None), + reduceMemoryUsage=reduceMemoryUsage, + dependencyProvider=tcImports.DependencyProvider) + + let projectOptions = + { + ProjectFileName="script.fsproj" + ProjectId=None + SourceFiles=[||] + OtherOptions=[||] + ReferencedProjects=[||] + IsIncompleteTypeCheckEnvironment=false + UseScriptResolutionRules =false + LoadTime=DateTime.Now + UnresolvedReferences =None + OriginalLoadReferences = [] + Stamp = None + } + + let! tcErrors, tcFileInfo = ParseAndCheckFile.CheckOneFile - (parseResults, sourceText, filename, "project", - tcConfig, tcGlobals, tcImports, tcState, + (parseResults, sourceText, filename, projectOptions, projectOptions.ProjectFileName, + tcConfig, tcGlobals, tcImports, tcState, Map.empty, Some loadClosure, backgroundDiagnostics, - reactorOps, None, userOpName, suggestNamesForErrors) - - return - match tcFileInfo with - | Result.Ok tcFileInfo -> - let errors = [| yield! parseErrors; yield! tcErrors |] - let typeCheckResults = FSharpCheckFileResults (filename, errors, Some tcFileInfo, dependencyFiles, None, reactorOps, false) - let projectResults = - FSharpCheckProjectResults (filename, Some tcConfig, - keepAssemblyContents, errors, - Some(tcGlobals, tcImports, tcFileInfo.ThisCcu, tcFileInfo.CcuSigForFile, - [tcFileInfo.ScopeSymbolUses], None, None, mkSimpleAssemblyRef "stdin", - tcState.TcEnvFromImpls.AccessRights, None, dependencyFiles)) - - parseResults, typeCheckResults, projectResults - - | Result.Error () -> - failwith "unexpected aborted" + suggestNamesForErrors) + + let errors = Array.append parseErrors tcErrors + let typeCheckResults = FSharpCheckFileResults (filename, errors, Some tcFileInfo, dependencyFiles, None, false) + let projectResults = + FSharpCheckProjectResults (filename, Some tcConfig, + keepAssemblyContents, errors, + Some(tcGlobals, tcImports, tcFileInfo.ThisCcu, tcFileInfo.CcuSigForFile, + (Choice2Of2 tcFileInfo.ScopeSymbolUses), None, mkSimpleAssemblyRef "stdin", + tcState.TcEnvFromImpls.AccessRights, None, dependencyFiles, + projectOptions)) + + return parseResults, typeCheckResults, projectResults } +/// The result of calling TypeCheckResult including the possibility of abort and background compiler not caught up. +type [] public FSharpCheckFileAnswer = + /// Aborted because cancellation caused an abandonment of the operation + | Aborted + + /// Success + | Succeeded of FSharpCheckFileResults diff --git a/src/fsharp/service/FSharpCheckerResults.fsi b/src/fsharp/service/FSharpCheckerResults.fsi index 13496225bfb..0c312386520 100644 --- a/src/fsharp/service/FSharpCheckerResults.fsi +++ b/src/fsharp/service/FSharpCheckerResults.fsi @@ -1,51 +1,165 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.CodeAnalysis -open FSharp.Compiler +open System +open System.IO +open System.Threading +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.AbstractIL.ILBinaryReader open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Symbols open FSharp.Compiler.NameResolution -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Syntax +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TcGlobals open FSharp.Compiler.Text -open FSharp.Compiler.TypeChecker -/// Represents the reason why the GetDeclarationLocation operation failed. -[] -type public FSharpFindDeclFailureReason = +/// Delays the creation of an ILModuleReader +[] +type internal DelayedILModuleReader = + + new : name: string * getStream: (CancellationToken -> Stream option) -> DelayedILModuleReader + + /// Will lazily create the ILModuleReader. + /// Is only evaluated once and can be called by multiple threads. + member TryGetILModuleReader : unit -> Cancellable + +/// Unused in this API +type public FSharpUnresolvedReferencesSet = + internal + | FSharpUnresolvedReferencesSet of UnresolvedAssemblyReference list + +/// A set of information describing a project or script build configuration. +type public FSharpProjectOptions = + { + // Note that this may not reduce to just the project directory, because there may be two projects in the same directory. + ProjectFileName: string + + /// This is the unique identifier for the project, it is case sensitive. If it's None, will key off of ProjectFileName in our caching. + ProjectId: string option + + /// The files in the project + SourceFiles: string[] + + /// Additional command line argument options for the project. These can include additional files and references. + OtherOptions: string[] + + /// The command line arguments for the other projects referenced by this project, indexed by the + /// exact text used in the "-r:" reference in FSharpProjectOptions. + ReferencedProjects: FSharpReferencedProject[] + + /// When true, the typechecking environment is known a priori to be incomplete, for + /// example when a .fs file is opened outside of a project. In this case, the number of error + /// messages reported is reduced. + IsIncompleteTypeCheckEnvironment: bool + + /// When true, use the reference resolution rules for scripts rather than the rules for compiler. + UseScriptResolutionRules: bool - /// Generic reason: no particular information about error apart from a message - | Unknown of message: string + /// Timestamp of project/script load, used to differentiate between different instances of a project load. + /// This ensures that a complete reload of the project or script type checking + /// context occurs on project or script unload/reload. + LoadTime: DateTime - /// Source code file is not available - | NoSourceCode + /// Unused in this API and should be 'None' when used as user-specified input + UnresolvedReferences: FSharpUnresolvedReferencesSet option - /// Trying to find declaration of ProvidedType without TypeProviderDefinitionLocationAttribute - | ProvidedType of string + /// Unused in this API and should be '[]' when used as user-specified input + OriginalLoadReferences: (range * string * string) list + + /// An optional stamp to uniquely identify this set of options + /// If two sets of options both have stamps, then they are considered equal + /// if and only if the stamps are equal + Stamp: int64 option + } + + /// Whether the two parse options refer to the same project. + static member internal UseSameProject: options1: FSharpProjectOptions * options2: FSharpProjectOptions -> bool + + /// Compare two options sets with respect to the parts of the options that are important to building. + static member internal AreSameForChecking: options1: FSharpProjectOptions * options2: FSharpProjectOptions -> bool + + /// Compute the project directory. + member internal ProjectDirectory: string + +and [] public FSharpReferencedProject = + internal + | FSharpReference of projectFileName: string * options: FSharpProjectOptions + | PEReference of projectFileName: string * stamp: DateTime * delayedReader: DelayedILModuleReader + | ILModuleReference of projectFileName: string * getStamp: (unit -> DateTime) * getReader: (unit -> ILModuleReader) + + member FileName : string + + /// Creates a reference for an F# project. The physical data for it is stored/cached inside of the compiler service. + static member CreateFSharp : projectFileName: string * options: FSharpProjectOptions -> FSharpReferencedProject + + /// Creates a reference for any portable executable, including F#. The stream is owned by this reference. + /// The stream will be automatically disposed when there are no references to FSharpReferencedProject and is GC collected. + /// Once the stream is evaluated, the function that constructs the stream will no longer be referenced by anything. + /// If the stream evaluation throws an exception, it will be automatically handled. + static member CreatePortableExecutable : projectFileName: string * stamp: DateTime * getStream: (CancellationToken -> Stream option) -> FSharpReferencedProject + + /// Creates a reference from an ILModuleReader. + static member CreateFromILModuleReader : projectFileName: string * getStamp: (unit -> DateTime) * getReader: (unit -> ILModuleReader) -> FSharpReferencedProject + +/// Represents the use of an F# symbol from F# source code +[] +type public FSharpSymbolUse = - /// Trying to find declaration of ProvidedMember without TypeProviderDefinitionLocationAttribute - | ProvidedMember of string + /// The symbol referenced + member Symbol: FSharpSymbol -/// Represents the result of the GetDeclarationLocation operation. -[] -type public FSharpFindDeclResult = + member GenericArguments: (FSharpGenericParameter * FSharpType) list - /// Indicates a declaration location was not found, with an additional reason - | DeclNotFound of FSharpFindDeclFailureReason + /// The display context active at the point where the symbol is used. Can be passed to FSharpType.Format + /// and other methods to format items in a way that is suitable for a specific source code location. + member DisplayContext: FSharpDisplayContext - /// Indicates a declaration location was found - | DeclFound of range + /// Indicates if the reference is a definition for the symbol, either in a signature or implementation + member IsFromDefinition: bool + + /// Indicates if the reference is in a pattern + member IsFromPattern: bool + + /// Indicates if the reference is in a syntactic type + member IsFromType: bool + + /// Indicates if the reference is in an attribute + member IsFromAttribute: bool + + /// Indicates if the reference is via the member being implemented in a class or object expression + member IsFromDispatchSlotImplementation: bool + + /// Indicates if the reference is either a builder or a custom operation in a computation expression + member IsFromComputationExpression: bool + + /// Indicates if the reference is in open statement + member IsFromOpenStatement: bool + + /// The file name the reference occurs in + member FileName: string + + /// The range of text representing the reference to the symbol + member Range: range + + /// Indicates if the FSharpSymbolUse is declared as private + member IsPrivateToFile: bool + + // For internal use only + internal new: denv: DisplayEnv * symbol:FSharpSymbol * inst: TyparInst * itemOcc:ItemOccurence * range: range -> FSharpSymbolUse - /// Indicates an external declaration was found - | ExternalDecl of assembly : string * externalSym : ExternalSymbol - /// Represents the checking context implied by the ProjectOptions [] type public FSharpProjectContext = @@ -56,30 +170,16 @@ type public FSharpProjectContext = /// Get the accessibility rights for this project context w.r.t. InternalsVisibleTo attributes granting access to other assemblies member AccessibilityRights : FSharpAccessibilityRights -[] -type public SemanticClassificationType = - | ReferenceType - | ValueType - | UnionCase - | Function - | Property - | MutableVar - | Module - | Printf - | ComputationExpression - | IntrinsicFunction - | Enumeration - | Interface - | TypeArgument - | Operator - | Disposable + /// Get the project options + member ProjectOptions: FSharpProjectOptions /// Options used to determine active --define conditionals and other options relevant to parsing files in a project type public FSharpParsingOptions = { SourceFiles: string[] ConditionalCompilationDefines: string list - ErrorSeverityOptions: FSharpErrorSeverityOptions + ErrorSeverityOptions: FSharpDiagnosticOptions + LangVersionText: string IsInteractive: bool LightSyntax: bool option CompilingFsLib: bool @@ -95,7 +195,7 @@ type public FSharpParsingOptions = [] type public FSharpCheckFileResults = /// The errors returned by parsing a source file. - member Errors : FSharpErrorInfo[] + member Diagnostics: FSharpDiagnostic[] /// Get a view of the contents of the assembly up to and including the file just checked member PartialAssemblySignature : FSharpAssemblySignature @@ -117,7 +217,7 @@ type public FSharpCheckFileResults = /// Get the items for a declaration list /// - /// + /// /// If this is present, it is used to filter declarations based on location in the /// parse tree, specifically at 'open' declarations, 'inherit' of class or interface /// 'record field' locations and r.h.s. of 'range' operator a..b @@ -133,17 +233,11 @@ type public FSharpCheckFileResults = /// /// Function that returns all entities from current and referenced assemblies. /// - /// - /// If text has been used from a captured name resolution from the typecheck, then - /// callback to the client to check if the text has changed. If it has, then give up - /// and assume that we're going to repeat the operation later on. - /// - /// An optional string used for tracing compiler operations associated with this request. - member GetDeclarationListInfo : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async + member GetDeclarationListInfo: parsedFileResults:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) -> DeclarationListInfo /// Get the items for a declaration list in FSharpSymbol format /// - /// + /// /// If this is present, it is used to filter declarations based on location in the /// parse tree, specifically at 'open' declarations, 'inherit' of class or interface /// 'record field' locations and r.h.s. of 'range' operator a..b @@ -159,13 +253,7 @@ type public FSharpCheckFileResults = /// /// Function that returns all entities from current and referenced assemblies. /// - /// - /// If text has been used from a captured name resolution from the typecheck, then - /// callback to the client to check if the text has changed. If it has, then give up - /// and assume that we're going to repeat the operation later on. - /// - /// An optional string used for tracing compiler operations associated with this request. - member GetDeclarationListSymbols : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async + member GetDeclarationListSymbols: parsedFileResults:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) -> FSharpSymbolUse list list /// Compute a formatted tooltip for the given location /// @@ -174,18 +262,7 @@ type public FSharpCheckFileResults = /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. /// Used to discriminate between 'identifiers', 'strings' and others. For strings, an attempt is made to give a tooltip for a #r "..." location. Use a value from FSharpTokenInfo.Tag, or FSharpTokenTag.Identifier, unless you have other information available. - /// An optional string used for tracing compiler operations associated with this request. - member GetStructuredToolTipText : line:int * colAtEndOfNames:int * lineText:string * names:string list * tokenTag:int * ?userOpName: string -> Async - - /// Compute a formatted tooltip for the given location - /// - /// The line number where the information is being requested. - /// The column number at the end of the identifiers where the information is being requested. - /// The text of the line where the information is being requested. - /// The identifiers at the location where the information is being requested. - /// Used to discriminate between 'identifiers', 'strings' and others. For strings, an attempt is made to give a tooltip for a #r "..." location. Use a value from FSharpTokenInfo.Tag, or FSharpTokenTag.Identifier, unless you have other information available. - /// An optional string used for tracing compiler operations associated with this request. - member GetToolTipText : line:int * colAtEndOfNames:int * lineText:string * names:string list * tokenTag:int * ?userOpName: string -> Async + member GetToolTip: line:int * colAtEndOfNames:int * lineText:string * names:string list * tokenTag:int -> ToolTipText /// Compute the Visual Studio F1-help key identifier for the given location, based on name resolution results /// @@ -193,9 +270,7 @@ type public FSharpCheckFileResults = /// The column number at the end of the identifiers where the information is being requested. /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. - /// An optional string used for tracing compiler operations associated with this request. - member GetF1Keyword : line:int * colAtEndOfNames:int * lineText:string * names:string list * ?userOpName: string -> Async - + member GetF1Keyword : line:int * colAtEndOfNames:int * lineText:string * names:string list -> string option /// Compute a set of method overloads to show in a dialog relevant to the given code location. /// @@ -203,16 +278,14 @@ type public FSharpCheckFileResults = /// The column number at the end of the identifiers where the information is being requested. /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. - /// An optional string used for tracing compiler operations associated with this request. - member GetMethods : line:int * colAtEndOfNames:int * lineText:string * names:string list option * ?userOpName: string -> Async + member GetMethods : line:int * colAtEndOfNames:int * lineText:string * names:string list option -> MethodGroup /// Compute a set of method overloads to show in a dialog relevant to the given code location. The resulting method overloads are returned as symbols. /// The line number where the information is being requested. /// The column number at the end of the identifiers where the information is being requested. /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. - /// An optional string used for tracing compiler operations associated with this request. - member GetMethodsAsSymbols : line:int * colAtEndOfNames:int * lineText:string * names:string list * ?userOpName: string -> Async + member GetMethodsAsSymbols : line:int * colAtEndOfNames:int * lineText:string * names:string list -> FSharpSymbolUse list option /// Resolve the names at the given location to the declaration location of the corresponding construct. /// @@ -221,8 +294,7 @@ type public FSharpCheckFileResults = /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. /// If not given, then get the location of the symbol. If false, then prefer the location of the corresponding symbol in the implementation of the file (rather than the signature if present). If true, prefer the location of the corresponding symbol in the signature of the file (rather than the implementation). - /// An optional string used for tracing compiler operations associated with this request. - member GetDeclarationLocation : line:int * colAtEndOfNames:int * lineText:string * names:string list * ?preferFlag:bool * ?userOpName: string -> Async + member GetDeclarationLocation : line:int * colAtEndOfNames:int * lineText:string * names:string list * ?preferFlag:bool -> FindDeclResult /// Resolve the names at the given location to a use of symbol. /// @@ -230,37 +302,34 @@ type public FSharpCheckFileResults = /// The column number at the end of the identifiers where the information is being requested. /// The text of the line where the information is being requested. /// The identifiers at the location where the information is being requested. - /// An optional string used for tracing compiler operations associated with this request. - member GetSymbolUseAtLocation : line:int * colAtEndOfNames:int * lineText:string * names:string list * ?userOpName: string -> Async + member GetSymbolUseAtLocation : line:int * colAtEndOfNames:int * lineText:string * names:string list -> FSharpSymbolUse option /// Get any extra colorization info that is available after the typecheck - member GetSemanticClassification : range option -> (range * SemanticClassificationType)[] + member GetSemanticClassification : range option -> SemanticClassificationItem[] /// Get the locations of format specifiers - [] + [] member GetFormatSpecifierLocations : unit -> range[] /// Get the locations of and number of arguments associated with format specifiers member GetFormatSpecifierLocationsAndArity : unit -> (range*int)[] /// Get all textual usages of all symbols throughout the file - member GetAllUsesOfAllSymbolsInFile : unit -> Async + member GetAllUsesOfAllSymbolsInFile : ?cancellationToken: CancellationToken -> seq /// Get the textual usages that resolved to the given symbol throughout the file - member GetUsesOfSymbolInFile : symbol:FSharpSymbol -> Async + member GetUsesOfSymbolInFile : symbol:FSharpSymbol * ?cancellationToken: CancellationToken -> FSharpSymbolUse[] - member internal GetVisibleNamespacesAndModulesAtPoint : pos -> Async + member internal GetVisibleNamespacesAndModulesAtPoint : pos -> ModuleOrNamespaceRef[] /// Find the most precise display environment for the given line and column. - member GetDisplayContextForPos : pos : pos -> Async + member GetDisplayContextForPos : cursorPos : pos -> FSharpDisplayContext option /// Determines if a long ident is resolvable at a specific point. - /// An optional string used for tracing compiler operations associated with this request. - member internal IsRelativeNameResolvable: cursorPos : pos * plid : string list * item: Item * ?userOpName: string -> Async + member internal IsRelativeNameResolvable: cursorPos : pos * plid : string list * item: Item -> bool /// Determines if a long ident is resolvable at a specific point. - /// An optional string used for tracing compiler operations associated with this request. - member IsRelativeNameResolvableFromSymbol: cursorPos : pos * plid : string list * symbol: FSharpSymbol * ?userOpName: string -> Async + member IsRelativeNameResolvableFromSymbol: cursorPos : pos * plid : string list * symbol: FSharpSymbol -> bool /// Represents complete typechecked implementation file, including its typechecked signatures if any. member ImplementationFile: FSharpImplementationFileContents option @@ -268,11 +337,13 @@ type public FSharpCheckFileResults = /// Open declarations in the file, including auto open modules. member OpenDeclarations: FSharpOpenDeclaration[] + /// Lays out and returns the formatted signature for the typechecked file as source text. + member GenerateSignature: unit -> ISourceText option + /// Internal constructor static member internal MakeEmpty : filename: string * - creationErrors: FSharpErrorInfo[] * - reactorOps: IReactorOperations * + creationErrors: FSharpDiagnostic[] * keepAssemblyContents: bool -> FSharpCheckFileResults @@ -284,11 +355,11 @@ type public FSharpCheckFileResults = tcGlobals: TcGlobals * isIncompleteTypeCheckEnvironment: bool * builder: IncrementalBuilder * + projectOptions: FSharpProjectOptions * dependencyFiles: string[] * - creationErrors: FSharpErrorInfo[] * - parseErrors: FSharpErrorInfo[] * - tcErrors: FSharpErrorInfo[] * - reactorOps : IReactorOperations * + creationErrors: FSharpDiagnostic[] * + parseErrors: FSharpDiagnostic[] * + tcErrors: FSharpDiagnostic[] * keepAssemblyContents: bool * ccuSigForFile: ModuleOrNamespaceType * thisCcu: CcuThunk * @@ -314,18 +385,16 @@ type public FSharpCheckFileResults = tcState: TcState * moduleNamesDict: ModuleNamesDict * loadClosure: LoadClosure option * - backgroundDiagnostics: (PhasedDiagnostic * FSharpErrorSeverity)[] * - reactorOps: IReactorOperations * - textSnapshotInfo : obj option * - userOpName: string * + backgroundDiagnostics: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] * isIncompleteTypeCheckEnvironment: bool * + projectOptions: FSharpProjectOptions * builder: IncrementalBuilder * dependencyFiles: string[] * - creationErrors:FSharpErrorInfo[] * - parseErrors:FSharpErrorInfo[] * + creationErrors:FSharpDiagnostic[] * + parseErrors:FSharpDiagnostic[] * keepAssemblyContents: bool * suggestNamesForErrors: bool - -> Async + -> Cancellable /// The result of calling TypeCheckResult including the possibility of abort and background compiler not caught up. and [] public FSharpCheckFileAnswer = @@ -340,7 +409,7 @@ and [] public FSharpCheckFileAnswer = type public FSharpCheckProjectResults = /// The errors returned by processing the project - member Errors: FSharpErrorInfo[] + member Diagnostics: FSharpDiagnostic[] /// Get a view of the overall signature of the assembly. Only valid to use if HasCriticalErrors is false. member AssemblySignature: FSharpAssemblySignature @@ -355,10 +424,10 @@ type public FSharpCheckProjectResults = member ProjectContext: FSharpProjectContext /// Get the textual usages that resolved to the given symbol throughout the project - member GetUsesOfSymbol: symbol:FSharpSymbol -> Async + member GetUsesOfSymbol: symbol:FSharpSymbol * ?cancellationToken: CancellationToken -> FSharpSymbolUse[] /// Get all textual usages of all symbols throughout the project - member GetAllUsesOfAllSymbols: unit -> Async + member GetAllUsesOfAllSymbols: ?cancellationToken: CancellationToken -> FSharpSymbolUse[] /// Indicates if critical errors existed in the project options member HasCriticalErrors: bool @@ -368,15 +437,23 @@ type public FSharpCheckProjectResults = /// in the documentation for compiler service. member DependencyFiles: string[] - member internal RawFSharpAssemblyData : IRawFSharpAssemblyData option - // Internal constructor. internal new : projectFileName:string * tcConfigOption: TcConfig option * keepAssemblyContents: bool * - errors: FSharpErrorInfo[] * - details:(TcGlobals * TcImports * CcuThunk * ModuleOrNamespaceType * TcSymbolUses list * TopAttribs option * CompileOps.IRawFSharpAssemblyData option * ILAssemblyRef * AccessorDomain * TypedImplFile list option * string[]) option + diagnostics: FSharpDiagnostic[] * + details:(TcGlobals * + TcImports * + CcuThunk * + ModuleOrNamespaceType * + Choice * + TopAttribs option * + ILAssemblyRef * + AccessorDomain * + TypedImplFile list option * + string[] * + FSharpProjectOptions) option -> FSharpCheckProjectResults module internal ParseAndCheckFile = @@ -387,7 +464,7 @@ module internal ParseAndCheckFile = options: FSharpParsingOptions * userOpName: string * suggestNamesForErrors: bool - -> FSharpErrorInfo[] * ParsedInput option * bool + -> FSharpDiagnostic[] * ParsedInput * bool val matchBraces: sourceText: ISourceText * @@ -401,8 +478,7 @@ module internal ParseAndCheckFile = // Used internally to provide intellisense over F# Interactive. type internal FsiInteractiveChecker = internal new: - ReferenceResolver.Resolver * - ops: IReactorOperations * + LegacyReferenceResolver * tcConfig: TcConfig * tcGlobals: TcGlobals * tcImports: TcImports * @@ -410,12 +486,10 @@ type internal FsiInteractiveChecker = -> FsiInteractiveChecker member internal ParseAndCheckInteraction : - ctok: CompilationThreadToken * sourceText:ISourceText * ?userOpName: string - -> Async + -> Cancellable module internal FSharpCheckerResultsSettings = val defaultFSharpBinariesDir: string - val maxTimeShareMilliseconds : int64 \ No newline at end of file diff --git a/src/fsharp/service/FSharpParseFileResults.fs b/src/fsharp/service/FSharpParseFileResults.fs new file mode 100644 index 00000000000..39e7f852aa6 --- /dev/null +++ b/src/fsharp/service/FSharpParseFileResults.fs @@ -0,0 +1,798 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open System.IO +open System.Collections.Generic +open System.Diagnostics +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range + +module SourceFileImpl = + let IsInterfaceFile file = + let ext = Path.GetExtension file + 0 = String.Compare(".fsi", ext, StringComparison.OrdinalIgnoreCase) + + /// Additional #defines that should be in place when editing a file in a file editor such as VS. + let AdditionalDefinesForUseInEditor(isInteractive: bool) = + if isInteractive then ["INTERACTIVE";"EDITING"] // This is still used by the foreground parse + else ["COMPILED";"EDITING"] + +type CompletionPath = string list * string option // plid * residue + +[] +type FSharpInheritanceOrigin = + | Class + | Interface + | Unknown + +[] +type InheritanceContext = + | Class + | Interface + | Unknown + +[] +type RecordContext = + | CopyOnUpdate of range: range * path: CompletionPath + | Constructor of typeName: string + | New of path: CompletionPath + +[] +type CompletionContext = + /// Completion context cannot be determined due to errors + | Invalid + + /// Completing something after the inherit keyword + | Inherit of context: InheritanceContext * path: CompletionPath + + /// Completing records field + | RecordField of context: RecordContext + + | RangeOperator + + /// Completing named parameters\setters in parameter list of constructor\method calls + /// end of name ast node * list of properties\parameters that were already set + | ParameterList of pos * HashSet + + | AttributeApplication + + | OpenDeclaration of isOpenType: bool + + /// Completing pattern type (e.g. foo (x: |)) + | PatternType + +//---------------------------------------------------------------------------- +// FSharpParseFileResults +//---------------------------------------------------------------------------- + +[] +type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, parseHadErrors: bool, dependencyFiles: string[]) = + + member _.Diagnostics = diagnostics + + member _.ParseHadErrors = parseHadErrors + + member _.ParseTree = input + + member _.TryRangeOfNameOfNearestOuterBindingContainingPos pos = + let tryGetIdentRangeFromBinding binding = + match binding with + | SynBinding(_, _, _, _, _, _, _, headPat, _, _, _, _) -> + match headPat with + | SynPat.LongIdent (longIdentWithDots, _, _, _, _, _) -> + Some longIdentWithDots.Range + | SynPat.As (_, SynPat.Named (ident, false, _, _), _) + | SynPat.Named (ident, false, _, _) -> + Some ident.idRange + | _ -> + None + + let rec walkBinding expr workingRange = + match expr with + + // This lets us dive into subexpressions that may contain the binding we're after + | SynExpr.Sequential (_, _, expr1, expr2, _) -> + if rangeContainsPos expr1.Range pos then + walkBinding expr1 workingRange + else + walkBinding expr2 workingRange + + + | SynExpr.LetOrUse(_, _, bindings, bodyExpr, _) -> + let potentialNestedRange = + bindings + |> List.tryFind (fun binding -> rangeContainsPos binding.RangeOfBindingWithRhs pos) + |> Option.bind tryGetIdentRangeFromBinding + match potentialNestedRange with + | Some range -> + walkBinding bodyExpr range + | None -> + walkBinding bodyExpr workingRange + + + | _ -> + Some workingRange + + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + override _.VisitExpr(_, _, defaultTraverse, expr) = + defaultTraverse expr + + override _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding(_, _, _, _, _, _, SynValData (None, _, _), _, _, expr, _range, _) as b when rangeContainsPos b.RangeOfBindingWithRhs pos -> + match tryGetIdentRangeFromBinding b with + | Some range -> walkBinding expr range + | None -> None + | _ -> defaultTraverse binding }) + + member _.TryIdentOfPipelineContainingPosAndNumArgsApplied pos = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App (_, _, SynExpr.App(_, true, SynExpr.Ident ident, _, _), argExpr, _) when rangeContainsPos argExpr.Range pos -> + match argExpr with + | SynExpr.App(_, _, _, SynExpr.Paren(expr, _, _, _), _) when rangeContainsPos expr.Range pos -> + None + | _ -> + if ident.idText = "op_PipeRight" then + Some (ident, 1) + elif ident.idText = "op_PipeRight2" then + Some (ident, 2) + elif ident.idText = "op_PipeRight3" then + Some (ident, 3) + else + None + | _ -> defaultTraverse expr + }) + + member _.IsPosContainedInApplication pos = + let result = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.TypeApp (_, _, _, _, _, _, range) when rangeContainsPos range pos -> + Some range + | SynExpr.App(_, _, _, SynExpr.ComputationExpr (_, expr, _), range) when rangeContainsPos range pos -> + traverseSynExpr expr + | SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos -> + Some range + | _ -> defaultTraverse expr + }) + result.IsSome + + member _.TryRangeOfFunctionOrMethodBeingApplied pos = + let rec getIdentRangeForFuncExprInApp traverseSynExpr expr pos = + match expr with + | SynExpr.Ident ident -> Some ident.idRange + + | SynExpr.LongIdent (_, _, _, range) -> Some range + + | SynExpr.Paren (expr, _, _, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.TypeApp (expr, _, _, _, _, _, _) -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.App (_, _, funcExpr, argExpr, _) -> + match argExpr with + | SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos + + // Special case: `async { ... }` is actually a ComputationExpr inside of the argExpr of a SynExpr.App + | SynExpr.ComputationExpr (_, expr, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.Paren (expr, _, _, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | _ -> + match funcExpr with + | SynExpr.App (_, true, _, _, _) when rangeContainsPos argExpr.Range pos -> + // x |> List.map + // Don't dive into the funcExpr (the operator expr) + // because we dont want to offer sig help for that! + getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos + | _ -> + // Generally, we want to dive into the func expr to get the range + // of the identifier of the function we're after + getIdentRangeForFuncExprInApp traverseSynExpr funcExpr pos + + | SynExpr.LetOrUse (_, _, bindings, body, range) when rangeContainsPos range pos -> + let binding = + bindings + |> List.tryFind (fun x -> rangeContainsPos x.RangeOfBindingWithRhs pos) + match binding with + | Some(SynBinding.SynBinding(_, _, _, _, _, _, _, _, _, expr, _, _)) -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + | None -> + getIdentRangeForFuncExprInApp traverseSynExpr body pos + + | SynExpr.IfThenElse (_, _, ifExpr, _, thenExpr, _, elseExpr, _, _, _, range) when rangeContainsPos range pos -> + if rangeContainsPos ifExpr.Range pos then + getIdentRangeForFuncExprInApp traverseSynExpr ifExpr pos + elif rangeContainsPos thenExpr.Range pos then + getIdentRangeForFuncExprInApp traverseSynExpr thenExpr pos + else + match elseExpr with + | None -> None + | Some expr -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.Match (_, expr, clauses, range) when rangeContainsPos range pos -> + if rangeContainsPos expr.Range pos then + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + else + let clause = clauses |> List.tryFind (fun clause -> rangeContainsPos clause.Range pos) + match clause with + | None -> None + | Some clause -> + match clause with + | SynMatchClause.SynMatchClause (_, whenExprOpt, _, resultExpr, _, _) -> + match whenExprOpt with + | None -> + getIdentRangeForFuncExprInApp traverseSynExpr resultExpr pos + | Some whenExpr -> + if rangeContainsPos whenExpr.Range pos then + getIdentRangeForFuncExprInApp traverseSynExpr whenExpr pos + else + getIdentRangeForFuncExprInApp traverseSynExpr resultExpr pos + + + // Ex: C.M(x, y, ...) <--- We want to find where in the tupled application the call is being made + | SynExpr.Tuple(_, exprs, _, tupRange) when rangeContainsPos tupRange pos -> + let expr = exprs |> List.tryFind (fun expr -> rangeContainsPos expr.Range pos) + match expr with + | None -> None + | Some expr -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + // Capture the body of a lambda, often nested in a call to a collection function + | SynExpr.Lambda(_, _, _args, _, body, _, _) when rangeContainsPos body.Range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr body pos + + | SynExpr.Do(expr, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.Assert(expr, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + + | SynExpr.ArbitraryAfterError (_debugStr, range) when rangeContainsPos range pos -> + Some range + + | expr -> + traverseSynExpr expr + |> Option.map id + + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.TypeApp (expr, _, _, _, _, _, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + | SynExpr.App (_, _, _funcExpr, _, range) as app when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr app pos + | _ -> defaultTraverse expr + }) + + member _.GetAllArgumentsForFunctionApplicationAtPostion pos = + SynExprAppLocationsImpl.getAllCurriedArgsAtPosition pos input + + member _.TryRangeOfParenEnclosingOpEqualsGreaterUsage opGreaterEqualPos = + let (|Ident|_|) ofName = + function | SynExpr.Ident ident when ident.idText = ofName -> Some () + | _ -> None + let (|InfixAppOfOpEqualsGreater|_|) = + function | SynExpr.App(ExprAtomicFlag.NonAtomic, false, SynExpr.App(ExprAtomicFlag.NonAtomic, true, Ident "op_EqualsGreater", actualParamListExpr, _), actualLambdaBodyExpr, _) -> + Some (actualParamListExpr, actualLambdaBodyExpr) + | _ -> None + + SyntaxTraversal.Traverse(opGreaterEqualPos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.Paren(InfixAppOfOpEqualsGreater(lambdaArgs, lambdaBody) as app, _, _, _) -> + Some (app.Range, lambdaArgs.Range, lambdaBody.Range) + | _ -> defaultTraverse expr + + member _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding(_, SynBindingKind.Normal, _, _, _, _, _, _, _, (InfixAppOfOpEqualsGreater(lambdaArgs, lambdaBody) as app), _, _) -> + Some(app.Range, lambdaArgs.Range, lambdaBody.Range) + | _ -> defaultTraverse binding }) + + member _.TryRangeOfExprInYieldOrReturn pos = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _, defaultTraverse, expr) = + match expr with + | SynExpr.YieldOrReturn(_, expr, range) + | SynExpr.YieldOrReturnFrom(_, expr, range) when rangeContainsPos range pos -> + Some expr.Range + | _ -> defaultTraverse expr }) + + member _.TryRangeOfRecordExpressionContainingPos pos = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.Record(_, _, _, range) when rangeContainsPos range pos -> + Some range + | _ -> defaultTraverse expr }) + + member _.TryRangeOfRefCellDereferenceContainingPos expressionPos = + SyntaxTraversal.Traverse(expressionPos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> + if funcIdent.idText = "op_Dereference" && rangeContainsPos expr.Range expressionPos then + Some funcIdent.idRange + else + None + | _ -> defaultTraverse expr }) + + member _.TryRangeOfExpressionBeingDereferencedContainingPos expressionPos = + SyntaxTraversal.Traverse(expressionPos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> + if funcIdent.idText = "op_Dereference" && rangeContainsPos expr.Range expressionPos then + Some expr.Range + else + None + | _ -> defaultTraverse expr }) + + member _.FindParameterLocations pos = + ParameterLocations.Find(pos, input) + + member _.IsPositionContainedInACurriedParameter pos = + let result = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + defaultTraverse(expr) + + override _.VisitBinding (_path, _, binding) = + match binding with + | SynBinding(_, _, _, _, _, _, valData, _, _, _, range, _) when rangeContainsPos range pos -> + let info = valData.SynValInfo.CurriedArgInfos + let mutable found = false + for group in info do + for arg in group do + match arg.Ident with + | Some ident when rangeContainsPos ident.idRange pos -> + found <- true + | _ -> () + if found then Some range else None + | _ -> + None + }) + result.IsSome + + member _.IsTypeAnnotationGivenAtPosition pos = + let result = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.Typed (_expr, _typeExpr, range) when Position.posEq range.Start pos -> + Some range + | _ -> defaultTraverse expr + + override _.VisitSimplePats(_path, pats) = + match pats with + | [] -> None + | _ -> + let exprFunc pat = + match pat with + | SynSimplePat.Typed (_pat, _targetExpr, range) when Position.posEq range.Start pos -> + Some range + | _ -> + None + + pats |> List.tryPick exprFunc + + override _.VisitPat(_path, defaultTraverse, pat) = + match pat with + | SynPat.Typed (_pat, _targetType, range) when Position.posEq range.Start pos -> + Some range + | _ -> defaultTraverse pat }) + result.IsSome + + member _.IsBindingALambdaAtPosition pos = + let result = + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = + defaultTraverse expr + + override _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding.SynBinding(_, _, _, _, _, _, _, _, _, expr, range, _) when Position.posEq range.Start pos -> + match expr with + | SynExpr.Lambda _ -> Some range + | _ -> None + | _ -> defaultTraverse binding }) + result.IsSome + + /// Get declared items and the selected item at the specified location + member _.GetNavigationItemsImpl() = + ErrorScope.Protect range0 + (fun () -> + match input with + | ParsedInput.ImplFile _ as p -> + Navigation.getNavigation p + | ParsedInput.SigFile _ -> + Navigation.empty) + (fun err -> + Trace.TraceInformation(sprintf "FCS: recovering from error in GetNavigationItemsImpl: '%s'" err) + Navigation.empty) + + member _.ValidateBreakpointLocationImpl pos = + let isMatchRange m = rangeContainsPos m pos || m.StartLine = pos.Line + + // Process let-binding + let findBreakPoints () = + let checkRange m = [ if isMatchRange m && not m.IsSynthetic then yield m ] + let walkBindSeqPt sp = [ match sp with DebugPointAtBinding.Yes m -> yield! checkRange m | _ -> () ] + let walkForSeqPt sp = [ match sp with DebugPointAtFor.Yes m -> yield! checkRange m | _ -> () ] + let walkWhileSeqPt sp = [ match sp with DebugPointAtWhile.Yes m -> yield! checkRange m | _ -> () ] + let walkTrySeqPt sp = [ match sp with DebugPointAtTry.Yes m -> yield! checkRange m | _ -> () ] + let walkWithSeqPt sp = [ match sp with DebugPointAtWith.Yes m -> yield! checkRange m | _ -> () ] + let walkFinallySeqPt sp = [ match sp with DebugPointAtFinally.Yes m -> yield! checkRange m | _ -> () ] + + let rec walkBind (SynBinding(_, _, _, _, _, _, SynValData(memFlagsOpt, _, _), synPat, _, synExpr, _, spInfo)) = + [ // Don't yield the binding sequence point if there are any arguments, i.e. we're defining a function or a method + let isFunction = + Option.isSome memFlagsOpt || + match synPat with + | SynPat.LongIdent (_, _, _, SynArgPats.Pats args, _, _) when not (List.isEmpty args) -> true + | _ -> false + if not isFunction then + yield! walkBindSeqPt spInfo + + yield! walkExpr (isFunction || (match spInfo with DebugPointAtBinding.Yes _ -> false | _-> true)) synExpr ] + + and walkExprs es = List.collect (walkExpr false) es + + and walkBinds es = List.collect walkBind es + + and walkMatchClauses cl = + [ for SynMatchClause(_, whenExprOpt, _, tgtExpr, _, _) in cl do + match whenExprOpt with + | Some whenExpr -> yield! walkExpr false whenExpr + | _ -> () + yield! walkExpr true tgtExpr ] + + and walkExprOpt (spAlways: bool) eOpt = + [ match eOpt with Some e -> yield! walkExpr spAlways e | _ -> () ] + + and IsBreakableExpression e = + match e with + | SynExpr.Match _ + | SynExpr.IfThenElse _ + | SynExpr.For _ + | SynExpr.ForEach _ + | SynExpr.While _ -> true + | _ -> not (IsControlFlowExpression e) + + // Determine the breakpoint locations for an expression. spAlways indicates we always + // emit a breakpoint location for the expression unless it is a syntactic control flow construct + and walkExpr (spAlways: bool) expr = + let m = expr.Range + if not (isMatchRange m) then [] else + [ if spAlways && IsBreakableExpression expr then + yield! checkRange m + + match expr with + | SynExpr.ArbitraryAfterError _ + | SynExpr.LongIdent _ + | SynExpr.LibraryOnlyILAssembly _ + | SynExpr.LibraryOnlyStaticOptimization _ + | SynExpr.Null _ + | SynExpr.Ident _ + | SynExpr.ImplicitZero _ + | SynExpr.Const _ -> + () + + | SynExpr.Quote (_, _, e, _, _) + | SynExpr.TypeTest (e, _, _) + | SynExpr.Upcast (e, _, _) + | SynExpr.AddressOf (_, e, _, _) + | SynExpr.ComputationExpr (_, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) + | SynExpr.Typed (e, _, _) + | SynExpr.FromParseError (e, _) + | SynExpr.DiscardAfterMissingQualificationAfterDot (e, _) + | SynExpr.Do (e, _) + | SynExpr.Assert (e, _) + | SynExpr.Fixed (e, _) + | SynExpr.DotGet (e, _, _, _) + | SynExpr.LongIdentSet (_, e, _) + | SynExpr.New (_, _, e, _) + | SynExpr.TypeApp (e, _, _, _, _, _, _) + | SynExpr.LibraryOnlyUnionCaseFieldGet (e, _, _, _) + | SynExpr.Downcast (e, _, _) + | SynExpr.InferredUpcast (e, _) + | SynExpr.InferredDowncast (e, _) + | SynExpr.Lazy (e, _) + | SynExpr.TraitCall (_, _, e, _) + | SynExpr.Paren (e, _, _, _) -> + yield! walkExpr false e + + | SynExpr.InterpolatedString (parts, _, _) -> + yield! walkExprs [ for part in parts do + match part with + | SynInterpolatedStringPart.String _ -> () + | SynInterpolatedStringPart.FillExpr (fillExpr, _) -> yield fillExpr ] + + | SynExpr.YieldOrReturn (_, e, m) -> + yield! checkRange m + yield! walkExpr false e + | SynExpr.YieldOrReturnFrom (_, e, _) + | SynExpr.DoBang (e, _) -> + yield! checkRange e.Range + yield! walkExpr false e + + // Always allow breakpoints on input and stages of x |> f1 |> f2 pipelines + | SynPipeRight _ -> + let rec loop e = + seq { + match e with + | SynPipeRight (xExpr, fExpr) -> + yield! checkRange fExpr.Range + yield! walkExpr false fExpr + yield! loop xExpr + | SynPipeRight2 (xExpr1, xExpr2, fExpr) -> + yield! checkRange fExpr.Range + yield! checkRange xExpr1.Range + yield! checkRange xExpr2.Range + yield! walkExpr false xExpr1 + yield! walkExpr false xExpr2 + yield! walkExpr false fExpr + | SynPipeRight3 (xExpr1, xExpr2, xExpr3, fExpr) -> + yield! checkRange fExpr.Range + yield! checkRange xExpr1.Range + yield! checkRange xExpr2.Range + yield! checkRange xExpr3.Range + yield! walkExpr false xExpr1 + yield! walkExpr false xExpr2 + yield! walkExpr false xExpr3 + yield! walkExpr false fExpr + | _ -> + yield! checkRange e.Range + yield! walkExpr false e + } + yield! loop expr + | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) + | SynExpr.DotSet (e1, _, e2, _) + | SynExpr.Set (e1, e2, _) + | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, _, _, e2, _) + | SynExpr.App (_, _, e1, e2, _) -> + yield! walkExpr false e1 + yield! walkExpr false e2 + + | SynExpr.ArrayOrList (_, es, _) + | SynExpr.Tuple (_, es, _, _) -> + yield! walkExprs es + + | SynExpr.Record (_, copyExprOpt, fs, _) -> + match copyExprOpt with + | Some (e, _) -> yield! walkExpr true e + | None -> () + yield! walkExprs (fs |> List.choose p23) + + | SynExpr.AnonRecd (_isStruct, copyExprOpt, fs, _) -> + match copyExprOpt with + | Some (e, _) -> yield! walkExpr true e + | None -> () + yield! walkExprs (fs |> List.map snd) + + | SynExpr.ObjExpr (_, args, bs, is, _, _) -> + match args with + | None -> () + | Some (arg, _) -> yield! walkExpr false arg + yield! walkBinds bs + for SynInterfaceImpl(_, bs, _) in is do yield! walkBinds bs + + | SynExpr.While (spWhile, e1, e2, _) -> + yield! walkWhileSeqPt spWhile + yield! walkExpr false e1 + yield! walkExpr true e2 + + | SynExpr.JoinIn (e1, _range, e2, _range2) -> + yield! walkExpr false e1 + yield! walkExpr false e2 + + | SynExpr.For (spFor, _, e1, _, e2, e3, _) -> + yield! walkForSeqPt spFor + yield! walkExpr false e1 + yield! walkExpr true e2 + yield! walkExpr true e3 + + | SynExpr.ForEach (spFor, _, _, _, e1, e2, _) -> + yield! walkForSeqPt spFor + yield! walkExpr false e1 + yield! walkExpr true e2 + + | SynExpr.MatchLambda (_isExnMatch, _argm, cl, spBind, _wholem) -> + yield! walkBindSeqPt spBind + for SynMatchClause(_, whenExpr, _, e, _, _) in cl do + yield! walkExprOpt true whenExpr + yield! walkExpr true e + + | SynExpr.Lambda (body = bodyExpr) -> + yield! walkExpr true bodyExpr + + | SynExpr.Match (spBind, inpExpr, cl, _) -> + yield! walkBindSeqPt spBind + yield! walkExpr false inpExpr + for SynMatchClause(_, whenExpr, _, tgtExpr, _, _) in cl do + yield! walkExprOpt true whenExpr + yield! walkExpr true tgtExpr + + | SynExpr.LetOrUse (_, _, binds, bodyExpr, _) -> + yield! walkBinds binds + yield! walkExpr true bodyExpr + + | SynExpr.TryWith (tryExpr, _, cl, _, _, spTry, spWith) -> + yield! walkTrySeqPt spTry + yield! walkWithSeqPt spWith + yield! walkExpr true tryExpr + yield! walkMatchClauses cl + + | SynExpr.TryFinally (e1, e2, _, spTry, spFinally) -> + yield! walkExpr true e1 + yield! walkExpr true e2 + yield! walkTrySeqPt spTry + yield! walkFinallySeqPt spFinally + + | SynExpr.SequentialOrImplicitYield (spSeq, e1, e2, _, _) + | SynExpr.Sequential (spSeq, _, e1, e2, _) -> + yield! walkExpr (match spSeq with DebugPointAtSequential.SuppressExpr | DebugPointAtSequential.SuppressBoth -> false | _ -> true) e1 + yield! walkExpr (match spSeq with DebugPointAtSequential.SuppressStmt | DebugPointAtSequential.SuppressBoth -> false | _ -> true) e2 + + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3opt, spBind, _, _, _) -> + yield! walkBindSeqPt spBind + yield! walkExpr false e1 + yield! walkExpr true e2 + yield! walkExprOpt true e3opt + + | SynExpr.DotIndexedGet (e1, es, _, _) -> + yield! walkExpr false e1 + yield! walkExpr false es + + | SynExpr.IndexRange (expr1, _, expr2, _, _, _) -> + match expr1 with Some e -> yield! walkExpr false e | None -> () + match expr2 with Some e -> yield! walkExpr false e | None -> () + + | SynExpr.IndexFromEnd (e, _) -> + yield! walkExpr false e + + | SynExpr.DotIndexedSet (e1, es, e2, _, _, _) -> + yield! walkExpr false e1 + yield! walkExpr false es + yield! walkExpr false e2 + + | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> + yield! walkExpr false e1 + yield! walkExpr false e2 + yield! walkExpr false e3 + + | SynExpr.LetOrUseBang (spBind, _, _, _, e1, es, e2, _) -> + yield! walkBindSeqPt spBind + yield! walkExpr true e1 + for andBangSpBind,_,_,_,eAndBang,_ in es do + yield! walkBindSeqPt andBangSpBind + yield! walkExpr true eAndBang + yield! walkExpr true e2 + + | SynExpr.MatchBang (spBind, e, cl, _) -> + yield! walkBindSeqPt spBind + yield! walkExpr false e + for SynMatchClause(_, whenExpr, _, e, _, _) in cl do + yield! walkExprOpt true whenExpr + yield! walkExpr true e ] + + // Process a class declaration or F# type declaration + let rec walkTycon (SynTypeDefn(SynComponentInfo _, repr, membDefns, implicitCtor, m)) = + if not (isMatchRange m) then [] else + [ for memb in membDefns do yield! walkMember memb + match repr with + | SynTypeDefnRepr.ObjectModel(_, membDefns, _) -> + for memb in membDefns do yield! walkMember memb + | _ -> () + for memb in membDefns do yield! walkMember memb + for memb in Option.toList implicitCtor do yield! walkMember memb] + + // Returns class-members for the right dropdown + and walkMember memb = + if not (rangeContainsPos memb.Range pos) then [] else + [ match memb with + | SynMemberDefn.LetBindings(binds, _, _, _) -> yield! walkBinds binds + | SynMemberDefn.AutoProperty(_attribs, _isStatic, _id, _tyOpt, _propKind, _, _xmlDoc, _access, synExpr, _, _) -> yield! walkExpr true synExpr + | SynMemberDefn.ImplicitCtor(_, _, _, _, _, m) -> yield! checkRange m + | SynMemberDefn.Member(bind, _) -> yield! walkBind bind + | SynMemberDefn.Interface(_, Some membs, _) -> for m in membs do yield! walkMember m + | SynMemberDefn.Inherit(_, _, m) -> + // can break on the "inherit" clause + yield! checkRange m + | SynMemberDefn.ImplicitInherit(_, arg, _, m) -> + // can break on the "inherit" clause + yield! checkRange m + yield! walkExpr true arg + | _ -> () ] + + // Process declarations nested in a module that should be displayed in the left dropdown + // (such as type declarations, nested modules etc.) + let rec walkDecl decl = + [ match decl with + | SynModuleDecl.Let(_, binds, m) when isMatchRange m -> + yield! walkBinds binds + | SynModuleDecl.DoExpr(spExpr, expr, m) when isMatchRange m -> + yield! walkBindSeqPt spExpr + yield! walkExpr false expr + | SynModuleDecl.ModuleAbbrev _ -> () + | SynModuleDecl.NestedModule(_, _isRec, decls, _, m) when isMatchRange m -> + for d in decls do yield! walkDecl d + | SynModuleDecl.Types(tydefs, m) when isMatchRange m -> + for d in tydefs do yield! walkTycon d + | SynModuleDecl.Exception(SynExceptionDefn(SynExceptionDefnRepr _, membDefns, _), m) + when isMatchRange m -> + for m in membDefns do yield! walkMember m + | _ -> () ] + + // Collect all the items in a module + let walkModule (SynModuleOrNamespace(_, _, _, decls, _, _, _, m)) = + if isMatchRange m then + List.collect walkDecl decls + else + [] + + /// Get information for implementation file + let walkImplFile (modules: SynModuleOrNamespace list) = List.collect walkModule modules + + match input with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules)) -> walkImplFile modules + | _ -> [] + + ErrorScope.Protect range0 + (fun () -> + let locations = findBreakPoints() + + if pos.Column = 0 then + // we have a breakpoint that was set with mouse at line start + match locations |> List.filter (fun m -> m.StartLine = m.EndLine && pos.Line = m.StartLine) with + | [] -> + match locations |> List.filter (fun m -> rangeContainsPos m pos) with + | [] -> + match locations |> List.filter (fun m -> rangeBeforePos m pos |> not) with + | [] -> Seq.tryHead locations + | locationsAfterPos -> Seq.tryHead locationsAfterPos + | coveringLocations -> Seq.tryLast coveringLocations + | locationsOnSameLine -> Seq.tryHead locationsOnSameLine + else + match locations |> List.filter (fun m -> rangeContainsPos m pos) with + | [] -> + match locations |> List.filter (fun m -> rangeBeforePos m pos |> not) with + | [] -> Seq.tryHead locations + | locationsAfterPos -> Seq.tryHead locationsAfterPos + | coveringLocations -> Seq.tryLast coveringLocations) + (fun msg -> + Trace.TraceInformation(sprintf "FCS: recovering from error in ValidateBreakpointLocationImpl: '%s'" msg) + None) + + /// When these files appear or disappear the configuration for the current project is invalidated. + member _.DependencyFiles = dependencyFiles + + member _.FileName = input.FileName + + // Get items for the navigation drop down bar + member scope.GetNavigationItems() = + // This does not need to be run on the background thread + scope.GetNavigationItemsImpl() + + member scope.ValidateBreakpointLocation pos = + // This does not need to be run on the background thread + scope.ValidateBreakpointLocationImpl pos + diff --git a/src/fsharp/service/FSharpParseFileResults.fsi b/src/fsharp/service/FSharpParseFileResults.fsi new file mode 100644 index 00000000000..9d3378a7b9a --- /dev/null +++ b/src/fsharp/service/FSharpParseFileResults.fsi @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +[] +/// Represents the results of parsing an F# file and a set of analysis operations based on the parse tree alone. +type public FSharpParseFileResults = + + /// The syntax tree resulting from the parse + member ParseTree: ParsedInput + + /// Attempts to find the range of the name of the nearest outer binding that contains a given position. + member TryRangeOfNameOfNearestOuterBindingContainingPos: pos: pos -> range option + + /// Attempts to find the range of an attempted lambda expression or pattern, the argument range, and the expr range when writing a C#-style "lambda" (which is actually an operator application) + member TryRangeOfParenEnclosingOpEqualsGreaterUsage: opGreaterEqualPos: pos -> (range * range * range) option + + /// Attempts to find the range of an expression `expr` contained in a `yield expr` or `return expr` expression (and bang-variants). + member TryRangeOfExprInYieldOrReturn: pos: pos -> range option + + /// Attempts to find the range of a record expression containing the given position. + member TryRangeOfRecordExpressionContainingPos: pos: pos -> range option + + /// Attempts to find an Ident of a pipeline containing the given position, and the number of args already applied in that pipeline. + /// For example, '[1..10] |> List.map ' would give back the ident of '|>' and 1, because it applied 1 arg (the list) to 'List.map'. + member TryIdentOfPipelineContainingPosAndNumArgsApplied: pos: pos -> (Ident * int) option + + /// Determines if the given position is inside a function or method application. + member IsPosContainedInApplication: pos: pos -> bool + + /// Attempts to find the range of a function or method that is being applied. Also accounts for functions in pipelines. + member TryRangeOfFunctionOrMethodBeingApplied: pos: pos -> range option + + /// Gets the ranges of all arguments, if they can be found, for a function application at the given position. + member GetAllArgumentsForFunctionApplicationAtPostion: pos: pos -> range list option + + /// + /// Given the position of an expression, attempts to find the range of the + /// '!' in a derefence operation of that expression, like: + /// '!expr', '!(expr)', etc. + /// + member TryRangeOfRefCellDereferenceContainingPos: expressionPos: pos -> range option + + /// Gets the range of an expression being dereferenced. For `!expr`, gives the range of `expr` + member TryRangeOfExpressionBeingDereferencedContainingPos: expressionPos: pos -> range option + + /// Notable parse info for ParameterInfo at a given location + member FindParameterLocations: pos:pos -> ParameterLocations option + + /// Determines if the given position is contained within a curried parameter in a binding. + member IsPositionContainedInACurriedParameter: pos: pos -> bool + + /// Determines if the expression or pattern at the given position has a type annotation + member IsTypeAnnotationGivenAtPosition: pos -> bool + + /// Determines if the binding at the given position is bound to a lambda expression + member IsBindingALambdaAtPosition: pos -> bool + + /// Name of the file for which this information were created + member FileName: string + + /// Get declared items and the selected item at the specified location + member GetNavigationItems: unit -> NavigationItems + + /// Return the inner-most range associated with a possible breakpoint location + member ValidateBreakpointLocation: pos:pos -> range option + + /// When these files change then the build is invalid + member DependencyFiles: string[] + + /// Get the errors and warnings for the parse + member Diagnostics: FSharpDiagnostic[] + + /// Indicates if any errors occurred during the parse + member ParseHadErrors: bool + + internal new: diagnostics: FSharpDiagnostic[] * input: ParsedInput * parseHadErrors: bool * dependencyFiles: string[] -> FSharpParseFileResults + diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs old mode 100755 new mode 100644 index de773fd3aa3..8909575da24 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -1,979 +1,54 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler - +namespace FSharp.Compiler.CodeAnalysis open System open System.Collections.Generic open System.IO open System.Threading +open Internal.Utilities.Library +open Internal.Utilities.Collections open FSharp.Compiler -open FSharp.Compiler.NameResolution -open FSharp.Compiler.Tastops -open FSharp.Compiler.Lib -open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.CompileOps -open FSharp.Compiler.CompileOptions +open FSharp.Compiler.CheckExpressions +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.CreateILModule +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.NameResolution +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals -open FSharp.Compiler.TypeChecker -open FSharp.Compiler.Tast -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open Internal.Utilities.Collections +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.BuildGraph + [] module internal IncrementalBuild = - /// A particular node in the Expr language. Use an int for keys instead of the entire Expr to avoid extra hashing. - type Id = Id of int - - [] - /// A build rule representing a single output - type ScalarBuildRule = - /// ScalarInput (uniqueRuleId, outputName) - /// - /// A build rule representing a single input, producing the input as its single scalar result - | ScalarInput of Id * string - - /// ScalarDemultiplex (uniqueRuleId, outputName, input, taskFunction) - /// - /// A build rule representing the merge of a set of inputs to a single output - | ScalarDemultiplex of Id * string * VectorBuildRule * (CompilationThreadToken -> obj[] -> Cancellable) - - /// ScalarMap (uniqueRuleId, outputName, input, taskFunction) - /// - /// A build rule representing the transformation of a single input to a single output - /// THIS CASE IS CURRENTLY UNUSED - | ScalarMap of Id * string * ScalarBuildRule * (CompilationThreadToken -> obj -> obj) - - /// Get the Id for the given ScalarBuildRule. - member x.Id = - match x with - | ScalarInput(id, _) -> id - | ScalarDemultiplex(id, _, _, _) -> id - | ScalarMap(id, _, _, _) -> id - - /// Get the Name for the givenScalarExpr. - member x.Name = - match x with - | ScalarInput(_, n) -> n - | ScalarDemultiplex(_, n, _, _) -> n - | ScalarMap(_, n, _, _) -> n - - /// A build rule with a vector of outputs - and VectorBuildRule = - /// VectorInput (uniqueRuleId, outputName) - /// - /// A build rule representing the transformation of a single input to a single output - | VectorInput of Id * string - - /// VectorInput (uniqueRuleId, outputName, initialAccumulator, inputs, taskFunction) - /// - /// A build rule representing the scan-left combining a single scalar accumulator input with a vector of inputs - | VectorScanLeft of Id * string * ScalarBuildRule * VectorBuildRule * (CompilationThreadToken -> obj -> obj->Eventually) - - /// VectorMap (uniqueRuleId, outputName, inputs, taskFunction) - /// - /// A build rule representing the parallel map of the inputs to outputs - | VectorMap of Id * string * VectorBuildRule * (CompilationThreadToken -> obj -> obj) - - /// VectorStamp (uniqueRuleId, outputName, inputs, stampFunction) - /// - /// A build rule representing pairing the inputs with a timestamp specified by the given function. - | VectorStamp of Id * string * VectorBuildRule * (TimeStampCache -> CompilationThreadToken -> obj -> DateTime) - - /// VectorMultiplex (uniqueRuleId, outputName, input, taskFunction) - /// - /// A build rule representing taking a single input and transforming it to a vector of outputs - | VectorMultiplex of Id * string * ScalarBuildRule * (CompilationThreadToken -> obj -> obj[]) - - /// Get the Id for the given VectorBuildRule. - member x.Id = - match x with - | VectorInput(id, _) -> id - | VectorScanLeft(id, _, _, _, _) -> id - | VectorMap(id, _, _, _) -> id - | VectorStamp (id, _, _, _) -> id - | VectorMultiplex(id, _, _, _) -> id - /// Get the Name for the given VectorBuildRule. - member x.Name = - match x with - | VectorInput(_, n) -> n - | VectorScanLeft(_, n, _, _, _) -> n - | VectorMap(_, n, _, _) -> n - | VectorStamp (_, n, _, _) -> n - | VectorMultiplex(_, n, _, _) -> n - - [] - type BuildRuleExpr = - | ScalarBuildRule of ScalarBuildRule - | VectorBuildRule of VectorBuildRule - /// Get the Id for the given Expr. - member x.Id = - match x with - | ScalarBuildRule se -> se.Id - | VectorBuildRule ve -> ve.Id - /// Get the Name for the given Expr. - member x.Name = - match x with - | ScalarBuildRule se -> se.Name - | VectorBuildRule ve -> ve.Name - - // Ids of exprs - let mutable nextid = 999 // Number ids starting with 1000 to discern them - let NextId() = - nextid <- nextid + 1 - Id(nextid) - - type INode = - abstract Name: string - - type IScalar = - inherit INode - abstract Expr: ScalarBuildRule - - type IVector = - inherit INode - abstract Expr: VectorBuildRule - - type Scalar<'T> = interface inherit IScalar end - - type Vector<'T> = interface inherit IVector end - - /// The outputs of a build - [] - type NamedOutput = - | NamedVectorOutput of IVector - | NamedScalarOutput of IScalar - - type BuildRules = { RuleList: (string * BuildRuleExpr) list } - - /// Visit each task and call op with the given accumulator. - let FoldOverBuildRules(rules: BuildRules, op, acc)= - let rec visitVector (ve: VectorBuildRule) acc = - match ve with - | VectorInput _ -> op (VectorBuildRule ve) acc - | VectorScanLeft(_, _, a, i, _) -> op (VectorBuildRule ve) (visitVector i (visitScalar a acc)) - | VectorMap(_, _, i, _) - | VectorStamp (_, _, i, _) -> op (VectorBuildRule ve) (visitVector i acc) - | VectorMultiplex(_, _, i, _) -> op (VectorBuildRule ve) (visitScalar i acc) - - and visitScalar (se: ScalarBuildRule) acc = - match se with - | ScalarInput _ -> op (ScalarBuildRule se) acc - | ScalarDemultiplex(_, _, i, _) -> op (ScalarBuildRule se) (visitVector i acc) - | ScalarMap(_, _, i, _) -> op (ScalarBuildRule se) (visitScalar i acc) - - let visitRule (expr: BuildRuleExpr) acc = - match expr with - | ScalarBuildRule se ->visitScalar se acc - | VectorBuildRule ve ->visitVector ve acc - - List.foldBack visitRule (rules.RuleList |> List.map snd) acc - - /// Convert from interfaces into discriminated union. - let ToBuild (names: NamedOutput list): BuildRules = - - // Create the rules. - let createRules() = - { RuleList = names |> List.map (function NamedVectorOutput v -> v.Name, VectorBuildRule(v.Expr) - | NamedScalarOutput s -> s.Name, ScalarBuildRule(s.Expr)) } - - // Ensure that all names are unique. - let ensureUniqueNames (expr: BuildRuleExpr) (acc: Map) = - let AddUniqueIdToNameMapping(id, name)= - match acc.TryFind name with - | Some priorId -> - if id<>priorId then failwith (sprintf "Two build expressions had the same name: %s" name) - else acc - | None-> Map.add name id acc - let id = expr.Id - let name = expr.Name - AddUniqueIdToNameMapping(id, name) - - // Validate the rule tree - let validateRules (rules: BuildRules) = - FoldOverBuildRules(rules, ensureUniqueNames, Map.empty) |> ignore - - // Convert and validate - let rules = createRules() - validateRules rules - rules - - /// These describe the input conditions for a result. If conditions change then the result is invalid. - type InputSignature = - | SingleMappedVectorInput of InputSignature[] - | EmptyTimeStampedInput of DateTime - | BoundInputScalar // An external input into the build - | BoundInputVector // An external input into the build - | IndexedValueElement of DateTime - | UnevaluatedInput - - /// Return true if the result is fully evaluated - member is.IsEvaluated = - match is with - | UnevaluatedInput -> false - | SingleMappedVectorInput iss -> iss |> Array.forall (fun is -> is.IsEvaluated) - | _ -> true - - - /// A slot for holding a single result. - type Result = - | NotAvailable - | InProgress of (CompilationThreadToken -> Eventually) * DateTime - | Available of obj * DateTime * InputSignature - - /// Get the available result. Throw an exception if not available. - member x.GetAvailable() = match x with Available (o, _, _) ->o | _ -> failwith "No available result" - - /// Get the time stamp if available. Otherwise MaxValue. - member x.Timestamp = match x with Available (_, ts, _) -> ts | InProgress(_, ts) -> ts | _ -> DateTime.MaxValue - - /// Get the time stamp if available. Otherwise MaxValue. - member x.InputSignature = match x with Available (_, _, signature) -> signature | _ -> UnevaluatedInput - - member x.ResultIsInProgress = match x with | InProgress _ -> true | _ -> false - member x.GetInProgressContinuation ctok = match x with | InProgress (f, _) -> f ctok | _ -> failwith "not in progress" - member x.TryGetAvailable() = match x with | InProgress _ | NotAvailable -> None | Available (obj, dt, i) -> Some (obj, dt, i) - - /// An immutable sparse vector of results. - type ResultVector(size, zeroElementTimestamp, map) = - let get slot = - match Map.tryFind slot map with - | Some result ->result - | None->NotAvailable - let asList = lazy List.map (fun i->i, get i) [0..size-1] - - static member OfSize size = ResultVector(size, DateTime.MinValue, Map.empty) - member rv.Size = size - member rv.Get slot = get slot - member rv.Resize newSize = - if size<>newSize then - ResultVector(newSize, zeroElementTimestamp, map |> Map.filter(fun s _ -> s < newSize)) - else rv - - member rv.Set(slot, value) = -#if DEBUG - if slot<0 then failwith "ResultVector slot less than zero" - if slot>=size then failwith "ResultVector slot too big" -#endif - ResultVector(size, zeroElementTimestamp, Map.add slot value map) - - member rv.MaxTimestamp() = - let maximize (lastTimestamp: DateTime) (_, result: Result) = max lastTimestamp result.Timestamp - List.fold maximize zeroElementTimestamp (asList.Force()) - - member rv.Signature() = - let l = asList.Force() - let l = l |> List.map (fun (_, result) -> result.InputSignature) - SingleMappedVectorInput (l|>List.toArray) - - member rv.FoldLeft f s: 'a = List.fold f s (asList.Force()) - - /// A result of performing build actions - [] - type ResultSet = - | ScalarResult of Result - | VectorResult of ResultVector - - /// Result of a particular action over the bound build tree - [] - type ActionResult = - | IndexedResult of Id * int * (*slotcount*) int * Eventually * DateTime - | ScalarValuedResult of Id * obj * DateTime * InputSignature - | VectorValuedResult of Id * obj[] * DateTime * InputSignature - | ResizeResult of Id * (*slotcount*) int - - - /// A pending action over the bound build tree - [] - type Action = - | IndexedAction of Id * (*taskname*)string * int * (*slotcount*) int * DateTime * (CompilationThreadToken -> Eventually) - | ScalarAction of Id * (*taskname*)string * DateTime * InputSignature * (CompilationThreadToken -> Cancellable) - | VectorAction of Id * (*taskname*)string * DateTime * InputSignature * (CompilationThreadToken -> Cancellable) - | ResizeResultAction of Id * (*slotcount*) int - /// Execute one action and return a corresponding result. - member action.Execute ctok = - cancellable { - match action with - | IndexedAction(id, _taskname, slot, slotcount, timestamp, func) -> let res = func ctok in return IndexedResult(id, slot, slotcount, res, timestamp) - | ScalarAction(id, _taskname, timestamp, inputsig, func) -> let! res = func ctok in return ScalarValuedResult(id, res, timestamp, inputsig) - | VectorAction(id, _taskname, timestamp, inputsig, func) -> let! res = func ctok in return VectorValuedResult(id, res, timestamp, inputsig) - | ResizeResultAction(id, slotcount) -> return ResizeResult(id, slotcount) - } - - /// A set of build rules and the corresponding, possibly partial, results from building. - [] - type PartialBuild(rules: BuildRules, results: Map) = - member bt.Rules = rules - member bt.Results = results - - /// Given an expression, find the expected width. - let rec GetVectorWidthByExpr(bt: PartialBuild, ve: VectorBuildRule) = - let id = ve.Id - let KnownValue() = - match bt.Results.TryFind id with - | Some resultSet -> - match resultSet with - | VectorResult rv ->Some rv.Size - | _ -> failwith "Expected vector to have vector result." - | None-> None - match ve with - | VectorScanLeft(_, _, _, i, _) - | VectorMap(_, _, i, _) - | VectorStamp (_, _, i, _) -> - match GetVectorWidthByExpr(bt, i) with - | Some _ as r -> r - | None -> KnownValue() - | VectorInput _ - | VectorMultiplex _ -> KnownValue() - - /// Given an expression name, get the corresponding expression. - let GetTopLevelExprByName(bt: PartialBuild, seek: string) = - bt.Rules.RuleList |> List.filter(fun(name, _) ->name=seek) |> List.map (fun(_, root) ->root) |> List.head - - /// Get an expression matching the given name. - let GetExprByName(bt: PartialBuild, node: INode): BuildRuleExpr = - let matchName (expr: BuildRuleExpr) (acc: BuildRuleExpr option): BuildRuleExpr option = - if expr.Name = node.Name then Some expr else acc - let matchOption = FoldOverBuildRules(bt.Rules, matchName, None) - Option.get matchOption - - // Given an Id, find the corresponding expression. - let GetExprById(bt: PartialBuild, seek: Id): BuildRuleExpr= - let rec vectorExprOfId ve = - match ve with - | VectorInput(id, _) ->if seek=id then Some (VectorBuildRule ve) else None - | VectorScanLeft(id, _, a, i, _) -> - if seek=id then Some (VectorBuildRule ve) else - let result = scalarExprOfId a - match result with Some _ -> result | None->vectorExprOfId i - | VectorMap(id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i - | VectorStamp (id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i - | VectorMultiplex(id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else scalarExprOfId i - - and scalarExprOfId se = - match se with - | ScalarInput(id, _) ->if seek=id then Some (ScalarBuildRule se) else None - | ScalarDemultiplex(id, _, i, _) ->if seek=id then Some (ScalarBuildRule se) else vectorExprOfId i - | ScalarMap(id, _, i, _) ->if seek=id then Some (ScalarBuildRule se) else scalarExprOfId i - - let exprOfId(expr: BuildRuleExpr) = - match expr with - | ScalarBuildRule se ->scalarExprOfId se - | VectorBuildRule ve ->vectorExprOfId ve - - let exprs = bt.Rules.RuleList |> List.map (fun(_, root) ->exprOfId root) |> List.filter Option.isSome - match exprs with - | Some expr :: _ -> expr - | _ -> failwith (sprintf "GetExprById did not find an expression for Id") - - let GetVectorWidthById (bt: PartialBuild) seek = - match GetExprById(bt, seek) with - | ScalarBuildRule _ ->failwith "Attempt to get width of scalar." - | VectorBuildRule ve -> Option.get (GetVectorWidthByExpr(bt, ve)) - - let GetScalarExprResult (bt: PartialBuild, se: ScalarBuildRule) = - match bt.Results.TryFind (se.Id) with - | Some resultSet -> - match se, resultSet with - | ScalarInput _, ScalarResult r - | ScalarMap _, ScalarResult r - | ScalarDemultiplex _, ScalarResult r ->r - | _ ->failwith "GetScalarExprResult had no match" - | None->NotAvailable - - let GetVectorExprResultVector (bt: PartialBuild, ve: VectorBuildRule) = - match bt.Results.TryFind (ve.Id) with - | Some resultSet -> - match ve, resultSet with - | VectorScanLeft _, VectorResult rv - | VectorMap _, VectorResult rv - | VectorInput _, VectorResult rv - | VectorStamp _, VectorResult rv - | VectorMultiplex _, VectorResult rv -> Some rv - | _ -> failwith "GetVectorExprResultVector had no match" - | None->None - - let GetVectorExprResult (bt: PartialBuild, ve: VectorBuildRule, slot) = - match bt.Results.TryFind ve.Id with - | Some resultSet -> - match ve, resultSet with - | VectorScanLeft _, VectorResult rv - | VectorMap _, VectorResult rv - | VectorInput _, VectorResult rv - | VectorStamp _, VectorResult rv -> rv.Get slot - | VectorMultiplex _, VectorResult rv -> rv.Get slot - | _ -> failwith "GetVectorExprResult had no match" - | None->NotAvailable - - /// Get the maximum build stamp for an output. - let MaxTimestamp(bt: PartialBuild, id) = - match bt.Results.TryFind id with - | Some resultSet -> - match resultSet with - | ScalarResult rs -> rs.Timestamp - | VectorResult rv -> rv.MaxTimestamp() - | None -> DateTime.MaxValue - - let Signature(bt: PartialBuild, id) = - match bt.Results.TryFind id with - | Some resultSet -> - match resultSet with - | ScalarResult rs -> rs.InputSignature - | VectorResult rv -> rv.Signature() - | None -> UnevaluatedInput - - /// Get all the results for the given expr. - let AllResultsOfExpr extractor (bt: PartialBuild) (expr: VectorBuildRule) = - let GetAvailable (rv: ResultVector) = - let Extract acc (_, result) = (extractor result) :: acc - List.rev (rv.FoldLeft Extract []) - let GetVectorResultById id = - match bt.Results.TryFind id with - | Some found -> - match found with - | VectorResult rv ->GetAvailable rv - | _ -> failwith "wrong result type" - | None -> [] - - GetVectorResultById(expr.Id) - - - - [] - type BuildInput = - | Vector of INode * obj list - | Scalar of INode * obj - - /// Declare a named scalar output. - static member ScalarInput (node: Scalar<'T>, value: 'T) = BuildInput.Scalar(node, box value) - static member VectorInput(node: Vector<'T>, values: 'T list) = BuildInput.Vector(node, List.map box values) - - - let AvailableAllResultsOfExpr bt expr = - let msg = "Expected all results to be available" - AllResultsOfExpr (function Available (o, _, _) -> o | _ -> failwith msg) bt expr - - /// Bind a set of build rules to a set of input values. - let ToBound(buildRules: BuildRules, inputs: BuildInput list) = - let now = DateTime.UtcNow - let rec applyScalarExpr(se, results) = - match se with - | ScalarInput(id, n) -> - let matches = - [ for input in inputs do - match input with - | BuildInput.Scalar (node, value) -> - if node.Name = n then - yield ScalarResult(Available (value, now, BoundInputScalar)) - | _ -> () ] - List.foldBack (Map.add id) matches results - | ScalarMap(_, _, se, _) ->applyScalarExpr(se, results) - | ScalarDemultiplex(_, _, ve, _) ->ApplyVectorExpr(ve, results) - and ApplyVectorExpr(ve, results) = - match ve with - | VectorInput(id, n) -> - let matches = - [ for input in inputs do - match input with - | BuildInput.Scalar _ -> () - | BuildInput.Vector (node, values) -> - if node.Name = n then - let results = values|>List.mapi(fun i value->i, Available (value, now, BoundInputVector)) - yield VectorResult(ResultVector(values.Length, DateTime.MinValue, results|>Map.ofList)) ] - List.foldBack (Map.add id) matches results - | VectorScanLeft(_, _, a, i, _) ->ApplyVectorExpr(i, applyScalarExpr(a, results)) - | VectorMap(_, _, i, _) - | VectorStamp (_, _, i, _) ->ApplyVectorExpr(i, results) - | VectorMultiplex(_, _, i, _) ->applyScalarExpr(i, results) - - let applyExpr expr results = - match expr with - | ScalarBuildRule se ->applyScalarExpr(se, results) - | VectorBuildRule ve ->ApplyVectorExpr(ve, results) - - // Place vector inputs into results map. - let results = List.foldBack applyExpr (buildRules.RuleList |> List.map snd) Map.empty - PartialBuild(buildRules, results) - - type Target = Target of INode * int option - - /// Visit each executable action necessary to evaluate the given output (with an optional slot in a - /// vector output). Call actionFunc with the given accumulator. - let ForeachAction cache ctok (Target(output, optSlot)) bt (actionFunc: Action -> 'T -> 'T) (acc:'T) = - let seen = Dictionary() - let isSeen id = - if seen.ContainsKey id then true - else - seen.[id] <- true - false - - let shouldEvaluate(bt, currentSig: InputSignature, id) = - if currentSig.IsEvaluated then - currentSig <> Signature(bt, id) - else false - - /// Make sure the result vector saved matches the size of expr - let resizeVectorExpr(ve: VectorBuildRule, acc) = - match GetVectorWidthByExpr(bt, ve) with - | Some expectedWidth -> - match bt.Results.TryFind ve.Id with - | Some found -> - match found with - | VectorResult rv -> - if rv.Size <> expectedWidth then - actionFunc (ResizeResultAction(ve.Id, expectedWidth)) acc - else acc - | _ -> acc - | None -> acc - | None -> acc - - let rec visitVector optSlot (ve: VectorBuildRule) acc = - - if isSeen ve.Id then acc - else - let acc = resizeVectorExpr(ve, acc) - match ve with - | VectorInput _ -> acc - | VectorScanLeft(id, taskname, accumulatorExpr, inputExpr, func) -> - let acc = - match GetVectorWidthByExpr(bt, ve) with - | Some cardinality -> - let limit = match optSlot with None -> cardinality | Some slot -> (slot+1) - - let Scan slot = - let accumulatorResult = - if slot=0 then GetScalarExprResult (bt, accumulatorExpr) - else GetVectorExprResult (bt, ve, slot-1) - - let inputResult = GetVectorExprResult (bt, inputExpr, slot) - match accumulatorResult, inputResult with - | Available (accumulator, accumulatorTimestamp, _accumulatorInputSig), Available (input, inputTimestamp, _inputSig) -> - let inputTimestamp = max inputTimestamp accumulatorTimestamp - let prevOutput = GetVectorExprResult (bt, ve, slot) - let outputTimestamp = prevOutput.Timestamp - let scanOpOpt = - if inputTimestamp <> outputTimestamp then - Some (fun ctok -> func ctok accumulator input) - elif prevOutput.ResultIsInProgress then - Some prevOutput.GetInProgressContinuation - else - // up-to-date and complete, no work required - None - match scanOpOpt with - | Some scanOp -> Some (actionFunc (IndexedAction(id, taskname, slot, cardinality, inputTimestamp, scanOp)) acc) - | None -> None - | _ -> None - - match ([0..limit-1]|>List.tryPick Scan) with Some acc ->acc | None->acc - | None -> acc - - // Check each slot for an action that may be performed. - visitVector None inputExpr (visitScalar accumulatorExpr acc) - - | VectorMap(id, taskname, inputExpr, func) -> - let acc = - match GetVectorWidthByExpr(bt, ve) with - | Some cardinality -> - if cardinality=0 then - // For vector length zero, just propagate the prior timestamp. - let inputTimestamp = MaxTimestamp(bt, inputExpr.Id) - let outputTimestamp = MaxTimestamp(bt, id) - if inputTimestamp <> outputTimestamp then - actionFunc (VectorAction(id, taskname, inputTimestamp, EmptyTimeStampedInput inputTimestamp, fun _ -> cancellable.Return [||])) acc - else acc - else - let MapResults acc slot = - let inputTimestamp = GetVectorExprResult(bt, inputExpr, slot).Timestamp - let outputTimestamp = GetVectorExprResult(bt, ve, slot).Timestamp - if inputTimestamp <> outputTimestamp then - let OneToOneOp ctok = - Eventually.Done (func ctok (GetVectorExprResult(bt, inputExpr, slot).GetAvailable())) - actionFunc (IndexedAction(id, taskname, slot, cardinality, inputTimestamp, OneToOneOp)) acc - else acc - match optSlot with - | None -> - [0..cardinality-1] |> List.fold MapResults acc - | Some slot -> - MapResults acc slot - | None -> acc - - visitVector optSlot inputExpr acc - - | VectorStamp (id, taskname, inputExpr, func) -> - - // For every result that is available, check time stamps. - let acc = - match GetVectorWidthByExpr(bt, ve) with - | Some cardinality -> - if cardinality=0 then - // For vector length zero, just propagate the prior timestamp. - let inputTimestamp = MaxTimestamp(bt, inputExpr.Id) - let outputTimestamp = MaxTimestamp(bt, id) - if inputTimestamp <> outputTimestamp then - actionFunc (VectorAction(id, taskname, inputTimestamp, EmptyTimeStampedInput inputTimestamp, fun _ -> cancellable.Return [||])) acc - else acc - else - let checkStamp acc slot = - let inputResult = GetVectorExprResult (bt, inputExpr, slot) - match inputResult with - | Available (ires, _, _) -> - let oldTimestamp = GetVectorExprResult(bt, ve, slot).Timestamp - let newTimestamp = func cache ctok ires - if newTimestamp <> oldTimestamp then - actionFunc (IndexedAction(id, taskname, slot, cardinality, newTimestamp, fun _ -> Eventually.Done ires)) acc - else acc - | _ -> acc - match optSlot with - | None -> - [0..cardinality-1] |> List.fold checkStamp acc - | Some slot -> - checkStamp acc slot - | None -> acc - visitVector optSlot inputExpr acc - - | VectorMultiplex(id, taskname, inputExpr, func) -> - let acc = - match GetScalarExprResult (bt, inputExpr) with - | Available (inp, inputTimestamp, inputsig) -> - let outputTimestamp = MaxTimestamp(bt, id) - if inputTimestamp <> outputTimestamp then - let MultiplexOp ctok = func ctok inp |> cancellable.Return - actionFunc (VectorAction(id, taskname, inputTimestamp, inputsig, MultiplexOp)) acc - else acc - | _ -> acc - visitScalar inputExpr acc - - and visitScalar (se: ScalarBuildRule) acc = - if isSeen se.Id then acc - else - match se with - | ScalarInput _ -> acc - | ScalarDemultiplex (id, taskname, inputExpr, func) -> - let acc = - match GetVectorExprResultVector (bt, inputExpr) with - | Some inputResult -> - let currentSig = inputResult.Signature() - if shouldEvaluate(bt, currentSig, id) then - let inputTimestamp = MaxTimestamp(bt, inputExpr.Id) - let DemultiplexOp ctok = - cancellable { - let input = AvailableAllResultsOfExpr bt inputExpr |> List.toArray - return! func ctok input - } - actionFunc (ScalarAction(id, taskname, inputTimestamp, currentSig, DemultiplexOp)) acc - else acc - | None -> acc - - visitVector None inputExpr acc - - | ScalarMap (id, taskname, inputExpr, func) -> - let acc = - match GetScalarExprResult (bt, inputExpr) with - | Available (inp, inputTimestamp, inputsig) -> - let outputTimestamp = MaxTimestamp(bt, id) - if inputTimestamp <> outputTimestamp then - let MapOp ctok = func ctok inp |> cancellable.Return - actionFunc (ScalarAction(id, taskname, inputTimestamp, inputsig, MapOp)) acc - else acc - | _ -> acc - - visitScalar inputExpr acc - - - let expr = bt.Rules.RuleList |> List.find (fun (s, _) -> s = output.Name) |> snd - match expr with - | ScalarBuildRule se -> visitScalar se acc - | VectorBuildRule ve -> visitVector optSlot ve acc - - let CollectActions cache target (bt: PartialBuild) = - // Explanation: This is a false reuse of 'ForeachAction' where the ctok is unused, we are - // just iterating to determine if there is work to do. This means this is safe to call from any thread. - let ctok = AssumeCompilationThreadWithoutEvidence () - ForeachAction cache ctok target bt (fun a l -> a :: l) [] - - /// Compute the max timestamp on all available inputs - let ComputeMaxTimeStamp cache ctok output (bt: PartialBuild) acc = - let expr = bt.Rules.RuleList |> List.find (fun (s, _) -> s = output) |> snd - match expr with - | VectorBuildRule (VectorStamp (_id, _taskname, inputExpr, func) as ve) -> - match GetVectorWidthByExpr(bt, ve) with - | Some cardinality -> - let CheckStamp acc slot = - match GetVectorExprResult (bt, inputExpr, slot) with - | Available (ires, _, _) -> max acc (func cache ctok ires) - | _ -> acc - [0..cardinality-1] |> List.fold CheckStamp acc - | None -> acc - - | _ -> failwith "expected a VectorStamp" - - /// Given the result of a single action, apply that action to the Build - let ApplyResult(actionResult: ActionResult, bt: PartialBuild) = - match actionResult with - | ResizeResult(id, slotcount) -> - match bt.Results.TryFind id with - | Some resultSet -> - match resultSet with - | VectorResult rv -> - let rv = rv.Resize slotcount - let results = Map.add id (VectorResult rv) bt.Results - PartialBuild(bt.Rules, results) - | _ -> failwith "Unexpected" - | None -> failwith "Unexpected" - | ScalarValuedResult(id, value, timestamp, inputsig) -> - PartialBuild(bt.Rules, Map.add id (ScalarResult(Available (value, timestamp, inputsig))) bt.Results) - | VectorValuedResult(id, values, timestamp, inputsig) -> - let Append acc slot = - Map.add slot (Available (values.[slot], timestamp, inputsig)) acc - let results = [0..values.Length-1]|>List.fold Append Map.empty - let results = VectorResult(ResultVector(values.Length, timestamp, results)) - let bt = PartialBuild(bt.Rules, Map.add id results bt.Results) - bt - - | IndexedResult(id, index, slotcount, value, timestamp) -> - let width = GetVectorWidthById bt id - let priorResults = bt.Results.TryFind id - let prior = - match priorResults with - | Some prior ->prior - | None->VectorResult(ResultVector.OfSize width) - match prior with - | VectorResult rv -> - let result = - match value with - | Eventually.Done res -> - Available (res, timestamp, IndexedValueElement timestamp) - | Eventually.NotYetDone f -> - InProgress (f, timestamp) - let results = rv.Resize(slotcount).Set(index, result) - PartialBuild(bt.Rules, Map.add id (VectorResult results) bt.Results) - | _ -> failwith "Unexpected" - let mutable injectCancellationFault = false - let LocallyInjectCancellationFault() = + let LocallyInjectCancellationFault() = injectCancellationFault <- true - { new IDisposable with member __.Dispose() = injectCancellationFault <- false } - - /// Apply the result, and call the 'save' function to update the build. - let ExecuteApply (ctok: CompilationThreadToken) save (action: Action) bt = - cancellable { - let! actionResult = action.Execute ctok - let newBt = ApplyResult(actionResult, bt) - save ctok newBt - return newBt - } + { new IDisposable with member _.Dispose() = injectCancellationFault <- false } - /// Evaluate the result of a single output - let EvalLeafsFirst cache ctok save target bt = - - let rec eval(bt, gen) = - cancellable { - #if DEBUG - // This can happen, for example, if there is a task whose timestamp never stops increasing. - // Possibly could detect this case directly. - if gen>5000 then failwith "Infinite loop in incremental builder?" - #endif - - let workList = CollectActions cache target bt - - let! newBt = - (bt, workList) ||> Cancellable.fold (fun bt action -> - if injectCancellationFault then - Cancellable.canceled() - else - ExecuteApply ctok save action bt) - - if newBt=bt then return bt else return! eval(newBt, gen+1) - } - eval(bt, 0) - - /// Evaluate one step of the build. Call the 'save' function to save the intermediate result. - let Step cache ctok save target (bt: PartialBuild) = - cancellable { - // REVIEW: we're building up the whole list of actions on the fringe of the work tree, - // executing one thing and then throwing the list away. What about saving the list inside the Build instance? - let workList = CollectActions cache target bt - - match workList with - | action :: _ -> - let! res = ExecuteApply ctok save action bt - return Some res - | _ -> - return None - } - - /// Evaluate an output of the build. - /// - /// Intermediate progress along the way may be saved through the use of the 'save' function. - let Eval cache ctok save node bt = EvalLeafsFirst cache ctok save (Target(node, None)) bt - - /// Evaluate an output of the build. - /// - /// Intermediate progress along the way may be saved through the use of the 'save' function. - let EvalUpTo cache ctok save (node, n) bt = EvalLeafsFirst cache ctok save (Target(node, Some n)) bt - - /// Check if an output is up-to-date and ready - let IsReady cache target bt = - let workList = CollectActions cache target bt - workList.IsEmpty - - /// Check if an output is up-to-date and ready - let MaxTimeStampInDependencies cache ctok target bt = - ComputeMaxTimeStamp cache ctok target bt DateTime.MinValue - - /// Get a scalar vector. Result must be available - let GetScalarResult<'T>(node: Scalar<'T>, bt): ('T*DateTime) option = - match GetTopLevelExprByName(bt, node.Name) with - | ScalarBuildRule se -> - match bt.Results.TryFind se.Id with - | Some result -> - match result with - | ScalarResult sr -> - match sr.TryGetAvailable() with - | Some (r, timestamp, _) -> Some (downcast r, timestamp) - | None -> None - | _ ->failwith "Expected a scalar result." - | None->None - | VectorBuildRule _ -> failwith "Expected scalar." - - /// Get a result vector. All results must be available or thrown an exception. - let GetVectorResult<'T>(node: Vector<'T>, bt): 'T[] = - match GetTopLevelExprByName(bt, node.Name) with - | ScalarBuildRule _ -> failwith "Expected vector." - | VectorBuildRule ve -> AvailableAllResultsOfExpr bt ve |> List.map unbox |> Array.ofList - - /// Get an element of vector result or None if there were no results. - let GetVectorResultBySlot<'T>(node: Vector<'T>, slot, bt): ('T*DateTime) option = - match GetTopLevelExprByName(bt, node.Name) with - | ScalarBuildRule _ -> failwith "Expected vector expression" - | VectorBuildRule ve -> - match GetVectorExprResult(bt, ve, slot).TryGetAvailable() with - | Some (o, timestamp, _) -> Some (downcast o, timestamp) - | None->None - - /// Given an input value, find the corresponding slot. - let TryGetSlotByInput<'T>(node: Vector<'T>, build: PartialBuild, found:'T->bool): int option = - let expr = GetExprByName(build, node) - let id = expr.Id - match build.Results.TryFind id with - | None -> None - | Some resultSet -> - match resultSet with - | VectorResult rv -> - let MatchNames acc (slot, result) = - match result with - | Available (o, _, _) -> - let o = o :?> 'T - if found o then Some slot else acc - | _ -> acc - let slotOption = rv.FoldLeft MatchNames None - slotOption - // failwith (sprintf "Could not find requested input '%A' named '%s' in set %+A" input name rv) - | _ -> None // failwith (sprintf "Could not find requested input: %A" input) - - - // Redeclare functions in the incremental build scope----------------------------------------------------------------------- - - // Methods for declaring inputs and outputs - - /// Declares a vector build input. - let InputVector<'T> name = - let expr = VectorInput(NextId(), name) - { new Vector<'T> - interface IVector with - override __.Name = name - override pe.Expr = expr } - - /// Declares a scalar build input. - let InputScalar<'T> name = - let expr = ScalarInput(NextId(), name) - { new Scalar<'T> - interface IScalar with - override __.Name = name - override pe.Expr = expr } - - - module Vector = - /// Maps one vector to another using the given function. - let Map (taskname: string) (task: CompilationThreadToken -> 'I -> 'O) (input: Vector<'I>): Vector<'O> = - let input = input.Expr - let expr = VectorMap(NextId(), taskname, input, (fun ctok x -> box (task ctok (unbox x)))) - { new Vector<'O> - interface IVector with - override __.Name = taskname - override pe.Expr = expr } - - - /// Apply a function to each element of the vector, threading an accumulator argument - /// through the computation. Returns intermediate results in a vector. - let ScanLeft (taskname: string) (task: CompilationThreadToken -> 'A -> 'I -> Eventually<'A>) (acc: Scalar<'A>) (input: Vector<'I>): Vector<'A> = - let BoxingScanLeft ctok a i = Eventually.box(task ctok (unbox a) (unbox i)) - let acc = acc.Expr - let input = input.Expr - let expr = VectorScanLeft(NextId(), taskname, acc, input, BoxingScanLeft) - { new Vector<'A> - interface IVector with - override __.Name = taskname - override pe.Expr = expr } - - /// Apply a function to a vector to get a scalar value. - let Demultiplex (taskname: string) (task: CompilationThreadToken -> 'I[] -> Cancellable<'O>) (input: Vector<'I>): Scalar<'O> = - let BoxingDemultiplex ctok inps = - cancellable { - let! res = task ctok (Array.map unbox inps) - return box res - } - let input = input.Expr - let expr = ScalarDemultiplex(NextId(), taskname, input, BoxingDemultiplex) - { new Scalar<'O> - interface IScalar with - override __.Name = taskname - override pe.Expr = expr } - - /// Creates a new vector with the same items but with - /// timestamp specified by the passed-in function. - let Stamp (taskname: string) (task: TimeStampCache -> CompilationThreadToken -> 'I -> DateTime) (input: Vector<'I>): Vector<'I> = - let input = input.Expr - let expr = VectorStamp (NextId(), taskname, input, (fun cache ctok x -> task cache ctok (unbox x))) - { new Vector<'I> - interface IVector with - override __.Name = taskname - override pe.Expr = expr } - - let AsScalar (taskname: string) (input: Vector<'I>): Scalar<'I array> = - Demultiplex taskname (fun _ctok x -> cancellable.Return x) input - - let VectorInput(node: Vector<'T>, values: 'T list) = (node.Name, values.Length, List.map box values) - - /// Declare build outputs and bind them to real values. - type BuildDescriptionScope() = - let mutable outputs = [] - - /// Declare a named scalar output. - member b.DeclareScalarOutput(output: Scalar<'T>)= - outputs <- NamedScalarOutput output :: outputs - - /// Declare a named vector output. - member b.DeclareVectorOutput(output: Vector<'T>)= - outputs <- NamedVectorOutput output :: outputs - - /// Set the concrete inputs for this build - member b.GetInitialPartialBuild(inputs: BuildInput list) = - ToBound(ToBuild outputs, inputs) - - - - -// Record the most recent IncrementalBuilder events, so we can more easily unit test/debug the +// Record the most recent IncrementalBuilder events, so we can more easily unit test/debug the // 'incremental' behavior of the product. -module IncrementalBuilderEventTesting = +module IncrementalBuilderEventTesting = type internal FixedLengthMRU<'T>() = let MAX = 400 // Length of the MRU. For our current unit tests, 400 is enough. @@ -989,7 +64,7 @@ module IncrementalBuilderEventTesting = // called by unit tests, returns 'n' most recent additions. member this.MostRecentList(n: int) : list<'T> = if n < 0 || n > MAX then - raise <| new System.ArgumentOutOfRangeException("n", sprintf "n must be between 0 and %d, inclusive, but got %d" MAX n) + raise <| ArgumentOutOfRangeException("n", sprintf "n must be between 0 and %d, inclusive, but got %d" MAX n) let mutable remaining = n let mutable s = [] let mutable i = curIndex - 1 @@ -1009,162 +84,584 @@ module IncrementalBuilderEventTesting = | IBECreated // ++GLOBAL MUTABLE STATE FOR TESTING++ - let MRU = new FixedLengthMRU() + let MRU = FixedLengthMRU() let GetMostRecentIncrementalBuildEvents n = MRU.MostRecentList n - let GetCurrentIncrementalBuildEventNum() = MRU.CurrentEventNum + let GetCurrentIncrementalBuildEventNum() = MRU.CurrentEventNum -module Tc = FSharp.Compiler.TypeChecker +module Tc = CheckExpressions +// This module is only here to contain the SyntaxTree type as to avoid amiguity with the module FSharp.Compiler.Syntax. +[] +module IncrementalBuildSyntaxTree = -/// Accumulated results of type checking. + /// Information needed to lazily parse a file to get a ParsedInput. Internally uses a weak cache. + [] + type SyntaxTree (tcConfig: TcConfig, fileParsed: Event, lexResourceManager, sourceRange: range, filename: string, isLastCompiland) = + + let mutable weakCache: WeakReference<_> option = None + + let parse(sigNameOpt: QualifiedNameOfFile option) = + let errorLogger = CompilationErrorLogger("Parse", tcConfig.errorSeverityOptions) + // Return the disposable object that cleans up + use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parse) + + try + IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename) + let lower = String.lowercase filename + let canSkip = sigNameOpt.IsSome && FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) + let input = + if canSkip then + ParsedInput.ImplFile( + ParsedImplFileInput( + filename, + false, + sigNameOpt.Value, + [], + [], + [], + isLastCompiland + ) + ) + else + ParseOneInputFile(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, (*retryLocked*)true) + + fileParsed.Trigger filename + + let res = input, sourceRange, filename, errorLogger.GetDiagnostics() + // If we do not skip parsing the file, then we can cache the real result. + if not canSkip then + weakCache <- Some(WeakReference<_>(res)) + res + with exn -> + let msg = sprintf "unexpected failure in SyntaxTree.parse\nerror = %s" (exn.ToString()) + System.Diagnostics.Debug.Assert(false, msg) + failwith msg + + /// Parse the given file and return the given input. + member _.Parse sigNameOpt = + match weakCache with + | Some weakCache -> + match weakCache.TryGetTarget() with + | true, res -> res + | _ -> parse sigNameOpt + | _ -> parse sigNameOpt + + member _.Invalidate() = + SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland) + + member _.FileName = filename + +/// Accumulated results of type checking. The minimum amount of state in order to continue type-checking following files. [] -type TypeCheckAccumulator = - { tcState: TcState - tcImports: TcImports - tcGlobals: TcGlobals - tcConfig: TcConfig - tcEnvAtEndOfFile: TcEnv +type TcInfo = + { + tcState: TcState + tcEnvAtEndOfFile: TcEnv + + /// Disambiguation table for module names + moduleNamesDict: ModuleNamesDict + + topAttribs: TopAttribs option - /// Accumulated resolutions, last file first - tcResolutionsRev: TcResolutions list + latestCcuSigForFile: ModuleOrNamespaceType option - /// Accumulated symbol uses, last file first - tcSymbolUsesRev: TcSymbolUses list + /// Accumulated errors, last file first + tcErrorsRev:(PhasedDiagnostic * FSharpDiagnosticSeverity)[] list - /// Accumulated 'open' declarations, last file first - tcOpenDeclarationsRev: OpenDeclaration[] list + tcDependencyFiles: string list - topAttribs: TopAttribs option + sigNameOpt: (string * QualifiedNameOfFile) option + } + + member x.TcErrors = + Array.concat (List.rev x.tcErrorsRev) + +/// Accumulated results of type checking. Optional data that isn't needed to type-check a file, but needed for more information for in tooling. +[] +type TcInfoExtras = + { + tcResolutions: TcResolutions + tcSymbolUses: TcSymbolUses + tcOpenDeclarations: OpenDeclaration[] /// Result of checking most recent file, if any latestImplFile: TypedImplFile option - latestCcuSigForFile: ModuleOrNamespaceType option + /// If enabled, stores a linear list of ranges and strings that identify an Item(symbol) in a file. Used for background find all references. + itemKeyStore: ItemKeyStore option + + /// If enabled, holds semantic classification information for Item(symbol)s in a file. + semanticClassificationKeyStore: SemanticClassificationKeyStore option + } + + member x.TcSymbolUses = + x.tcSymbolUses + +[] +module TcInfoHelpers = + + let emptyTcInfoExtras = + { + tcResolutions = TcResolutions.Empty + tcSymbolUses = TcSymbolUses.Empty + tcOpenDeclarations = [||] + latestImplFile = None + itemKeyStore = None + semanticClassificationKeyStore = None + } + +/// Accumulated results of type checking. +[] +type TcInfoState = + | PartialState of TcInfo + | FullState of TcInfo * TcInfoExtras + + member x.TcInfo = + match x with + | PartialState tcInfo -> tcInfo + | FullState (tcInfo, _) -> tcInfo + + member x.TcInfoExtras = + match x with + | PartialState _ -> None + | FullState (_, tcInfoExtras) -> Some tcInfoExtras + +[] +type TcInfoNode = + | TcInfoNode of partial: GraphNode * full: GraphNode + + member this.HasFull = + match this with + | TcInfoNode(_, full) -> full.HasValue + + static member FromState(state: TcInfoState) = + let tcInfo = state.TcInfo + let tcInfoExtras = state.TcInfoExtras + TcInfoNode(GraphNode(node { return tcInfo }), GraphNode(node { return tcInfo, defaultArg tcInfoExtras emptyTcInfoExtras })) + +/// Bound model of an underlying syntax and typed tree. +[] +type BoundModel private (tcConfig: TcConfig, + tcGlobals: TcGlobals, + tcImports: TcImports, + keepAssemblyContents, keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked: Event, + fileChecked: Event, + prevTcInfo: TcInfo, + syntaxTreeOpt: SyntaxTree option, + tcInfoStateOpt: TcInfoState option) as this = + + let tcInfoNode = + match tcInfoStateOpt with + | Some tcInfoState -> TcInfoNode.FromState(tcInfoState) + | _ -> + let fullGraphNode = + GraphNode(node { + match! this.TypeCheck(false) with + | FullState(tcInfo, tcInfoExtras) -> return tcInfo, tcInfoExtras + | PartialState(tcInfo) -> return tcInfo, emptyTcInfoExtras + }) + + let partialGraphNode = + GraphNode(node { + if enablePartialTypeChecking then + // Optimization so we have less of a chance to duplicate work. + if fullGraphNode.IsComputing then + let! tcInfo, _ = fullGraphNode.GetOrComputeValue() + return tcInfo + else + match fullGraphNode.TryPeekValue() with + | ValueSome(tcInfo, _) -> return tcInfo + | _ -> + let! tcInfoState = this.TypeCheck(true) + return tcInfoState.TcInfo + else + let! tcInfo, _ = fullGraphNode.GetOrComputeValue() + return tcInfo + }) + + TcInfoNode(partialGraphNode, fullGraphNode) + + let defaultTypeCheck () = + node { + return PartialState(prevTcInfo) + } + + member _.TcConfig = tcConfig + + member _.TcGlobals = tcGlobals + + member _.TcImports = tcImports + + member _.BackingSignature = + match syntaxTreeOpt with + | Some syntaxTree -> + let sigFileName = Path.ChangeExtension(syntaxTree.FileName, ".fsi") + match prevTcInfo.sigNameOpt with + | Some (expectedSigFileName, sigName) when String.Equals(expectedSigFileName, sigFileName, StringComparison.OrdinalIgnoreCase) -> + Some sigName + | _ -> + None + | _ -> + None + + /// If partial type-checking is enabled, + /// this will create a new bound-model that will only have the partial state if the + /// the current bound-model has the full state. + member this.ClearTcInfoExtras() = + let hasSig = this.BackingSignature.IsSome + + // If partial checking is enabled and we have a backing sig file, then use the partial state. The partial state contains the sig state. + if tcInfoNode.HasFull && enablePartialTypeChecking && hasSig then + // Always invalidate the syntax tree cache. + let newSyntaxTreeOpt = + syntaxTreeOpt + |> Option.map (fun x -> x.Invalidate()) + + let newTcInfoStateOpt = + match tcInfoNode with + | TcInfoNode(_, fullGraphNode) -> + let tcInfo, _ = fullGraphNode.TryPeekValue().Value + Some(PartialState tcInfo) + + BoundModel( + tcConfig, + tcGlobals, + tcImports, + keepAssemblyContents, keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, + prevTcInfo, + newSyntaxTreeOpt, + newTcInfoStateOpt) + else + this + + member this.Next(syntaxTree, tcInfo) = + BoundModel( + tcConfig, + tcGlobals, + tcImports, + keepAssemblyContents, + keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, + tcInfo, + Some syntaxTree, + None) + + member this.Finish(finalTcErrorsRev, finalTopAttribs) = + node { + let createFinish tcInfo = + { tcInfo with tcErrorsRev = finalTcErrorsRev; topAttribs = finalTopAttribs } + + let! finishState = + node { + match tcInfoNode with + | TcInfoNode(partialGraphNode, fullGraphNode) -> + if fullGraphNode.HasValue then + let! tcInfo, tcInfoExtras = fullGraphNode.GetOrComputeValue() + let finishTcInfo = createFinish tcInfo + return FullState(finishTcInfo, tcInfoExtras) + else + let! tcInfo = partialGraphNode.GetOrComputeValue() + let finishTcInfo = createFinish tcInfo + return PartialState(finishTcInfo) + } + + return + BoundModel( + tcConfig, + tcGlobals, + tcImports, + keepAssemblyContents, + keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, + prevTcInfo, + syntaxTreeOpt, + Some finishState) + } + + member _.TryPeekTcInfo() = + match tcInfoNode with + | TcInfoNode(partialGraphNode, fullGraphNode) -> + match partialGraphNode.TryPeekValue() with + | ValueSome tcInfo -> Some tcInfo + | _ -> + match fullGraphNode.TryPeekValue() with + | ValueSome(tcInfo, _) -> Some tcInfo + | _ -> None + + member _.TryPeekTcInfoWithExtras() = + match tcInfoNode with + | TcInfoNode(_, fullGraphNode) -> + match fullGraphNode.TryPeekValue() with + | ValueSome(tcInfo, tcInfoExtras) -> Some(tcInfo, tcInfoExtras) + | _ -> None + + member _.GetOrComputeTcInfo() = + match tcInfoNode with + | TcInfoNode(partialGraphNode, _) -> + partialGraphNode.GetOrComputeValue() + + member _.GetOrComputeTcInfoExtras() : NodeCode = + match tcInfoNode with + | TcInfoNode(_, fullGraphNode) -> + node { + let! _, tcInfoExtras = fullGraphNode.GetOrComputeValue() + return tcInfoExtras + } - tcDependencyFiles: string list + member _.GetOrComputeTcInfoWithExtras() = + match tcInfoNode with + | TcInfoNode(_, fullGraphNode) -> + fullGraphNode.GetOrComputeValue() - /// Disambiguation table for module names - tcModuleNamesDict: ModuleNamesDict + member private this.TypeCheck (partialCheck: bool) : NodeCode = + match partialCheck, tcInfoStateOpt with + | true, Some (PartialState _ as state) + | true, Some (FullState _ as state) -> node { return state } + | false, Some (FullState _ as state) -> node { return state } + | _ -> - /// Accumulated errors, last file first - tcErrorsRev:(PhasedDiagnostic * FSharpErrorSeverity)[] list } + node { + match syntaxTreeOpt with + | None -> + let! res = defaultTypeCheck () + return res + | Some syntaxTree -> + let sigNameOpt = + if partialCheck then + this.BackingSignature + else + None + match syntaxTree.Parse sigNameOpt with + | input, _sourceRange, filename, parseErrors -> + + IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBETypechecked filename) + let capturingErrorLogger = CompilationErrorLogger("TypeCheck", tcConfig.errorSeverityOptions) + let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput input, capturingErrorLogger) + use _ = new CompilationGlobalsScope(errorLogger, BuildPhase.TypeCheck) + + beforeFileChecked.Trigger filename + let prevModuleNamesDict = prevTcInfo.moduleNamesDict + let prevTcState = prevTcInfo.tcState + let prevTcErrorsRev = prevTcInfo.tcErrorsRev + let prevTcDependencyFiles = prevTcInfo.tcDependencyFiles + + ApplyMetaCommandsFromInputToTcConfig (tcConfig, input, Path.GetDirectoryName filename, tcImports.DependencyProvider) |> ignore + let sink = TcResultsSinkImpl(tcGlobals) + let hadParseErrors = not (Array.isEmpty parseErrors) + let input, moduleNamesDict = DeduplicateParsedInputModuleName prevModuleNamesDict input + + Logger.LogBlockMessageStart filename LogCompilerFunctionId.IncrementalBuild_TypeCheck + + let! (tcEnvAtEndOfFile, topAttribs, implFile, ccuSigForFile), tcState = + TypeCheckOneInput + ((fun () -> hadParseErrors || errorLogger.ErrorCount > 0), + tcConfig, tcImports, + tcGlobals, + None, + (if partialCheck then TcResultsSink.NoSink else TcResultsSink.WithSink sink), + prevTcState, input, + partialCheck) + |> NodeCode.FromCancellable + + Logger.LogBlockMessageStop filename LogCompilerFunctionId.IncrementalBuild_TypeCheck + + fileChecked.Trigger filename + let newErrors = Array.append parseErrors (capturingErrorLogger.GetDiagnostics()) + + let tcEnvAtEndOfFile = if keepAllBackgroundResolutions then tcEnvAtEndOfFile else tcState.TcEnvFromImpls + + let tcInfo = + { + tcState = tcState + tcEnvAtEndOfFile = tcEnvAtEndOfFile + moduleNamesDict = moduleNamesDict + latestCcuSigForFile = Some ccuSigForFile + tcErrorsRev = newErrors :: prevTcErrorsRev + topAttribs = Some topAttribs + tcDependencyFiles = filename :: prevTcDependencyFiles + sigNameOpt = + match input with + | ParsedInput.SigFile(ParsedSigFileInput(fileName=fileName;qualifiedNameOfFile=qualName)) -> + Some(fileName, qualName) + | _ -> + None + } + + if partialCheck then + return PartialState tcInfo + else + // Build symbol keys + let itemKeyStore, semanticClassification = + if enableBackgroundItemKeyStoreAndSemanticClassification then + Logger.LogBlockMessageStart filename LogCompilerFunctionId.IncrementalBuild_CreateItemKeyStoreAndSemanticClassification + let sResolutions = sink.GetResolutions() + let builder = ItemKeyStoreBuilder() + let preventDuplicates = HashSet({ new IEqualityComparer with + member _.Equals((s1, e1): struct(pos * pos), (s2, e2): struct(pos * pos)) = Position.posEq s1 s2 && Position.posEq e1 e2 + member _.GetHashCode o = o.GetHashCode() }) + sResolutions.CapturedNameResolutions + |> Seq.iter (fun cnr -> + let r = cnr.Range + if preventDuplicates.Add struct(r.Start, r.End) then + builder.Write(cnr.Range, cnr.Item)) + + let semanticClassification = sResolutions.GetSemanticClassification(tcGlobals, tcImports.GetImportMap(), sink.GetFormatSpecifierLocations(), None) + + let sckBuilder = SemanticClassificationKeyStoreBuilder() + sckBuilder.WriteAll semanticClassification + + let res = builder.TryBuildAndReset(), sckBuilder.TryBuildAndReset() + Logger.LogBlockMessageStop filename LogCompilerFunctionId.IncrementalBuild_CreateItemKeyStoreAndSemanticClassification + res + else + None, None + + let tcInfoExtras = + { + /// Only keep the typed interface files when doing a "full" build for fsc.exe, otherwise just throw them away + latestImplFile = if keepAssemblyContents then implFile else None + tcResolutions = (if keepAllBackgroundResolutions then sink.GetResolutions() else TcResolutions.Empty) + tcSymbolUses = (if keepAllBackgroundSymbolUses then sink.GetSymbolUses() else TcSymbolUses.Empty) + tcOpenDeclarations = sink.GetOpenDeclarations() + itemKeyStore = itemKeyStore + semanticClassificationKeyStore = semanticClassification + } + + return FullState(tcInfo, tcInfoExtras) + } + + static member Create(tcConfig: TcConfig, + tcGlobals: TcGlobals, + tcImports: TcImports, + keepAssemblyContents, keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked: Event, + fileChecked: Event, + prevTcInfo: TcInfo, + syntaxTreeOpt: SyntaxTree option) = + BoundModel(tcConfig, tcGlobals, tcImports, + keepAssemblyContents, keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, + prevTcInfo, + syntaxTreeOpt, + None) - /// Global service state type FrameworkImportsCacheKey = (*resolvedpath*)string list * string * (*TargetFrameworkDirectories*)string list * (*fsharpBinaries*)string * (*langVersion*)decimal /// Represents a cache of 'framework' references that can be shared between multiple incremental builds -type FrameworkImportsCache(keepStrongly) = +type FrameworkImportsCache(size) = + + let gate = obj() - // Mutable collection protected via CompilationThreadToken - let frameworkTcImportsCache = AgedLookup(keepStrongly, areSimilar=(fun (x, y) -> x = y)) + // Mutable collection protected via CompilationThreadToken + let frameworkTcImportsCache = AgedLookup>(size, areSimilar=(fun (x, y) -> x = y)) /// Reduce the size of the cache in low-memory scenarios - member __.Downsize ctok = frameworkTcImportsCache.Resize(ctok, keepStrongly=0) + member _.Downsize() = frameworkTcImportsCache.Resize(AnyCallerThread, newKeepStrongly=0) /// Clear the cache - member __.Clear ctok = frameworkTcImportsCache.Clear ctok + member _.Clear() = frameworkTcImportsCache.Clear AnyCallerThread /// This function strips the "System" assemblies from the tcConfig and returns a age-cached TcImports for them. - member __.Get(ctok, tcConfig: TcConfig) = - cancellable { - // Split into installed and not installed. - let frameworkDLLs, nonFrameworkResolutions, unresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) - let frameworkDLLsKey = - frameworkDLLs + member _.GetNode(tcConfig: TcConfig, frameworkDLLs: AssemblyResolution list, nonFrameworkResolutions: AssemblyResolution list) = + let frameworkDLLsKey = + frameworkDLLs |> List.map (fun ar->ar.resolvedPath) // The cache key. Just the minimal data. |> List.sort // Sort to promote cache hits. - let! tcGlobals, frameworkTcImports = - cancellable { - // Prepare the frameworkTcImportsCache - // - // The data elements in this key are very important. There should be nothing else in the TcConfig that logically affects - // the import of a set of framework DLLs into F# CCUs. That is, the F# CCUs that result from a set of DLLs (including - // FSharp.Core.dll and mscorlib.dll) must be logically invariant of all the other compiler configuration parameters. - let key = (frameworkDLLsKey, - tcConfig.primaryAssembly.Name, - tcConfig.GetTargetFrameworkDirectories(), - tcConfig.fsharpBinariesDir, - tcConfig.langVersion.SpecifiedVersion) - - match frameworkTcImportsCache.TryGet (ctok, key) with - | Some res -> return res - | None -> - let tcConfigP = TcConfigProvider.Constant tcConfig - let! ((tcGlobals, tcImports) as res) = TcImports.BuildFrameworkTcImports (ctok, tcConfigP, frameworkDLLs, nonFrameworkResolutions) - frameworkTcImportsCache.Put(ctok, key, res) - return tcGlobals, tcImports - } + // Prepare the frameworkTcImportsCache + // + // The data elements in this key are very important. There should be nothing else in the TcConfig that logically affects + // the import of a set of framework DLLs into F# CCUs. That is, the F# CCUs that result from a set of DLLs (including + // FSharp.Core.dll and mscorlib.dll) must be logically invariant of all the other compiler configuration parameters. + let key = (frameworkDLLsKey, + tcConfig.primaryAssembly.Name, + tcConfig.GetTargetFrameworkDirectories(), + tcConfig.fsharpBinariesDir, + tcConfig.langVersion.SpecifiedVersion) + + let node = + lock gate (fun () -> + match frameworkTcImportsCache.TryGet (AnyCallerThread, key) with + | Some lazyWork -> lazyWork + | None -> + let lazyWork = GraphNode(node { + let tcConfigP = TcConfigProvider.Constant tcConfig + return! TcImports.BuildFrameworkTcImports (tcConfigP, frameworkDLLs, nonFrameworkResolutions) + }) + frameworkTcImportsCache.Put(AnyCallerThread, key, lazyWork) + lazyWork + ) + node + + /// This function strips the "System" assemblies from the tcConfig and returns a age-cached TcImports for them. + member this.Get(tcConfig: TcConfig) = + node { + // Split into installed and not installed. + let frameworkDLLs, nonFrameworkResolutions, unresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(tcConfig) + let node = this.GetNode(tcConfig, frameworkDLLs, nonFrameworkResolutions) + let! tcGlobals, frameworkTcImports = node.GetOrComputeValue() return tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolved } - -//------------------------------------------------------------------------------------ -// Rules for reactive building. -// -// This phrases the compile as a series of vector functions and vector manipulations. -// Rules written in this language are then transformed into a plan to execute the -// various steps of the process. -//----------------------------------------------------------------------------------- - - /// Represents the interim state of checking an assembly -type PartialCheckResults = - { TcState: TcState - TcImports: TcImports - TcGlobals: TcGlobals - TcConfig: TcConfig - TcEnvAtEnd: TcEnv - - /// Kept in a stack so that each incremental update shares storage with previous files - TcErrorsRev: (PhasedDiagnostic * FSharpErrorSeverity)[] list +[] +type PartialCheckResults (boundModel: BoundModel, timeStamp: DateTime) = - /// Kept in a stack so that each incremental update shares storage with previous files - TcResolutionsRev: TcResolutions list + member _.TcImports = boundModel.TcImports - /// Kept in a stack so that each incremental update shares storage with previous files - TcSymbolUsesRev: TcSymbolUses list + member _.TcGlobals = boundModel.TcGlobals - /// Kept in a stack so that each incremental update shares storage with previous files - TcOpenDeclarationsRev: OpenDeclaration[] list + member _.TcConfig = boundModel.TcConfig - /// Disambiguation table for module names - ModuleNamesDict: ModuleNamesDict + member _.TimeStamp = timeStamp - TcDependencyFiles: string list + member _.TryPeekTcInfo() = boundModel.TryPeekTcInfo() - TopAttribs: TopAttribs option + member _.TryPeekTcInfoWithExtras() = boundModel.TryPeekTcInfoWithExtras() - TimeStamp: DateTime + member _.GetOrComputeTcInfo() = boundModel.GetOrComputeTcInfo() - LatestImplementationFile: TypedImplFile option + member _.GetOrComputeTcInfoWithExtras() = boundModel.GetOrComputeTcInfoWithExtras() - LatestCcuSigForFile: ModuleOrNamespaceType option } - - member x.TcErrors = Array.concat (List.rev x.TcErrorsRev) - member x.TcSymbolUses = List.rev x.TcSymbolUsesRev - - static member Create (tcAcc: TypeCheckAccumulator, timestamp) = - { TcState = tcAcc.tcState - TcImports = tcAcc.tcImports - TcGlobals = tcAcc.tcGlobals - TcConfig = tcAcc.tcConfig - TcEnvAtEnd = tcAcc.tcEnvAtEndOfFile - TcErrorsRev = tcAcc.tcErrorsRev - TcResolutionsRev = tcAcc.tcResolutionsRev - TcSymbolUsesRev = tcAcc.tcSymbolUsesRev - TcOpenDeclarationsRev = tcAcc.tcOpenDeclarationsRev - TcDependencyFiles = tcAcc.tcDependencyFiles - TopAttribs = tcAcc.topAttribs - ModuleNamesDict = tcAcc.tcModuleNamesDict - TimeStamp = timestamp - LatestImplementationFile = tcAcc.latestImplFile - LatestCcuSigForFile = tcAcc.latestCcuSigForFile } + member _.GetOrComputeItemKeyStoreIfEnabled() = + node { + let! info = boundModel.GetOrComputeTcInfoExtras() + return info.itemKeyStore + } + member _.GetOrComputeSemanticClassificationIfEnabled() = + node { + let! info = boundModel.GetOrComputeTcInfoExtras() + return info.semanticClassificationKeyStore + } [] -module Utilities = +module Utilities = let TryFindFSharpStringAttribute tcGlobals attribSpec attribs = match TryFindFSharpAttribute tcGlobals attribSpec attribs with | Some (Attrib(_, _, [ AttribStringArg s ], _, _, _, _)) -> Some s @@ -1172,16 +669,15 @@ module Utilities = /// The implementation of the information needed by TcImports in CompileOps.fs for an F# assembly reference. // -/// Constructs the build data (IRawFSharpAssemblyData) representing the assembly when used +/// Constructs the build data (IRawFSharpAssemblyData) representing the assembly when used /// as a cross-assembly reference. Note the assembly has not been generated on disk, so this is /// a virtualized view of the assembly contents as computed by background checking. -type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState: TcState, outfile, topAttrs, assemblyName, ilAssemRef) = +type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, generatedCcu: CcuThunk, outfile, topAttrs, assemblyName, ilAssemRef) = - let generatedCcu = tcState.Ccu let exportRemapping = MakeExportRemapping generatedCcu generatedCcu.Contents - - let sigData = - let _sigDataAttributes, sigDataResources = Driver.EncodeInterfaceData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, true) + + let sigData = + let _sigDataAttributes, sigDataResources = EncodeSignatureData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, true) [ for r in sigDataResources do let ccuName = GetSignatureDataResourceName r yield (ccuName, (fun () -> r.GetBytes())) ] @@ -1190,115 +686,62 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState: let ivtAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute) - interface IRawFSharpAssemblyData with - member __.GetAutoOpenAttributes(_ilg) = autoOpenAttrs - member __.GetInternalsVisibleToAttributes(_ilg) = ivtAttrs - member __.TryGetILModuleDef() = None - member __.GetRawFSharpSignatureData(_m, _ilShortAssemName, _filename) = sigData - member __.GetRawFSharpOptimizationData(_m, _ilShortAssemName, _filename) = [ ] - member __.GetRawTypeForwarders() = mkILExportedTypes [] // TODO: cross-project references with type forwarders - member __.ShortAssemblyName = assemblyName - member __.ILScopeRef = IL.ILScopeRef.Assembly ilAssemRef - member __.ILAssemblyRefs = [] // These are not significant for service scenarios - member __.HasAnyFSharpSignatureDataAttribute = true - member __.HasMatchingFSharpSignatureDataAttribute _ilg = true + interface IRawFSharpAssemblyData with + member _.GetAutoOpenAttributes() = autoOpenAttrs + member _.GetInternalsVisibleToAttributes() = ivtAttrs + member _.TryGetILModuleDef() = None + member _.GetRawFSharpSignatureData(_m, _ilShortAssemName, _filename) = sigData + member _.GetRawFSharpOptimizationData(_m, _ilShortAssemName, _filename) = [ ] + member _.GetRawTypeForwarders() = mkILExportedTypes [] // TODO: cross-project references with type forwarders + member _.ShortAssemblyName = assemblyName + member _.ILScopeRef = ILScopeRef.Assembly ilAssemRef + member _.ILAssemblyRefs = [] // These are not significant for service scenarios + member _.HasAnyFSharpSignatureDataAttribute = true + member _.HasMatchingFSharpSignatureDataAttribute = true +[] +module IncrementalBuilderHelpers = -/// Manages an incremental build graph for the build of a single F# project -type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInputs, nonFrameworkResolutions, unresolvedReferences, tcConfig: TcConfig, projectDirectory, outfile, - assemblyName, niceNameGen: NiceNameGenerator, lexResourceManager, - sourceFiles, loadClosureOpt: LoadClosure option, - keepAssemblyContents, keepAllBackgroundResolutions, maxTimeShareMilliseconds) = - - let tcConfigP = TcConfigProvider.Constant tcConfig - let fileParsed = new Event() - let beforeFileChecked = new Event() - let fileChecked = new Event() - let projectChecked = new Event() -#if !NO_EXTENSIONTYPING - let importsInvalidatedByTypeProvider = new Event() -#endif - let mutable currentTcImportsOpt = None - - // Check for the existence of loaded sources and prepend them to the sources list if present. - let sourceFiles = tcConfig.GetAvailableLoadedSources() @ (sourceFiles |>List.map (fun s -> rangeStartup, s)) - - // Mark up the source files with an indicator flag indicating if they are the last source file in the project - let sourceFiles = - let flags, isExe = tcConfig.ComputeCanContainEntryPoint(sourceFiles |> List.map snd) - ((sourceFiles, flags) ||> List.map2 (fun (m, nm) flag -> (m, nm, (flag, isExe)))) - - let defaultTimeStamp = DateTime.UtcNow - - let basicDependencies = - [ for (UnresolvedAssemblyReference(referenceText, _)) in unresolvedReferences do - // Exclude things that are definitely not a file name - if not(FileSystem.IsInvalidPathShim referenceText) then - let file = if FileSystem.IsPathRootedShim referenceText then referenceText else Path.Combine(projectDirectory, referenceText) - yield file - - for r in nonFrameworkResolutions do - yield r.resolvedPath ] - - let allDependencies = - [| yield! basicDependencies - for (_, f, _) in sourceFiles do - yield f |] - - //---------------------------------------------------- - // START OF BUILD TASK FUNCTIONS - - /// This is a build task function that gets placed into the build rules as the computation for a VectorStamp - /// /// Get the timestamp of the given file name. - let StampFileNameTask (cache: TimeStampCache) _ctok (_m: range, filename: string, _isLastCompiland) = + let StampFileNameTask (cache: TimeStampCache) (_m: range, filename: string, _isLastCompiland) = cache.GetFileTimeStamp filename - /// This is a build task function that gets placed into the build rules as the computation for a VectorMap - /// - /// Parse the given file and return the given input. - let ParseTask ctok (sourceRange: range, filename: string, isLastCompiland) = - DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok - - let errorLogger = CompilationErrorLogger("ParseTask", tcConfig.errorSeverityOptions) - // Return the disposable object that cleans up - use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parse) - - try - IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename) - let input = ParseOneInputFile(tcConfig, lexResourceManager, [], filename, isLastCompiland, errorLogger, (*retryLocked*)true) - fileParsed.Trigger filename - - input, sourceRange, filename, errorLogger.GetErrors () - with exn -> - let msg = sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString()) - System.Diagnostics.Debug.Assert(false, msg) - failwith msg - - - /// This is a build task function that gets placed into the build rules as the computation for a Vector.Stamp - /// /// Timestamps of referenced assemblies are taken from the file's timestamp. - let StampReferencedAssemblyTask (cache: TimeStampCache) ctok (_ref, timeStamper) = - timeStamper cache ctok - - - /// This is a build task function that gets placed into the build rules as the computation for a Vector.Demultiplex - /// - // Link all the assemblies together and produce the input typecheck accumulator - let CombineImportedAssembliesTask ctok _ : Cancellable = - cancellable { + let StampReferencedAssemblyTask (cache: TimeStampCache) (_ref, timeStamper) = + timeStamper cache + + // Link all the assemblies together and produce the input typecheck accumulator + let CombineImportedAssembliesTask ( + assemblyName, + tcConfig: TcConfig, + tcConfigP, + tcGlobals, + frameworkTcImports, + nonFrameworkResolutions, + unresolvedReferences, + dependencyProvider, + loadClosureOpt: LoadClosure option, + niceNameGen, + basicDependencies, + keepAssemblyContents, + keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + defaultPartialTypeChecking, + beforeFileChecked, + fileChecked, + importsInvalidatedByTypeProvider: Event) : NodeCode = + node { let errorLogger = CompilationErrorLogger("CombineImportedAssembliesTask", tcConfig.errorSeverityOptions) - // Return the disposable object that cleans up - use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) + use _ = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) - let! tcImports = - cancellable { + let! tcImports = + node { try - let! tcImports = TcImports.BuildNonFrameworkTcImports(ctok, tcConfigP, tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences) + let! tcImports = TcImports.BuildNonFrameworkTcImports(tcConfigP, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences, dependencyProvider) #if !NO_EXTENSIONTYPING - tcImports.GetCcusExcludingBase() |> Seq.iter (fun ccu -> - // When a CCU reports an invalidation, merge them together and just report a + tcImports.GetCcusExcludingBase() |> Seq.iter (fun ccu -> + // When a CCU reports an invalidation, merge them together and just report a // general "imports invalidated". This triggers a rebuild. // // We are explicit about what the handler closure captures to help reason about the @@ -1306,440 +749,688 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput // or keeps itself alive mistakenly, e.g. via some global state in the type provider instance. // // The handler only captures - // 1. a weak reference to the importsInvalidated event. + // 1. a weak reference to the importsInvalidated event. // // The IncrementalBuilder holds the strong reference the importsInvalidated event. // - // In the invalidation handler we use a weak reference to allow the IncrementalBuilder to + // In the invalidation handler we use a weak reference to allow the IncrementalBuilder to // be collected if, for some reason, a TP instance is not disposed or not GC'd. let capturedImportsInvalidated = WeakReference<_>(importsInvalidatedByTypeProvider) - ccu.Deref.InvalidateEvent.Add(fun msg -> - match capturedImportsInvalidated.TryGetTarget() with - | true, tg -> tg.Trigger msg - | _ -> ())) + ccu.Deref.InvalidateEvent.Add(fun _ -> + match capturedImportsInvalidated.TryGetTarget() with + | true, tg -> tg.Trigger() + | _ -> ())) #endif - currentTcImportsOpt <- Some tcImports return tcImports - with e -> + with e -> System.Diagnostics.Debug.Assert(false, sprintf "Could not BuildAllReferencedDllTcImports %A" e) errorLogger.Warning e - return frameworkTcImports + return frameworkTcImports } - let tcInitial = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) - let tcState = GetInitialTcState (rangeStartup, assemblyName, tcConfig, tcGlobals, tcImports, niceNameGen, tcInitial) - let loadClosureErrors = - [ match loadClosureOpt with + let tcInitial, openDecls0 = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals) + let tcState = GetInitialTcState (rangeStartup, assemblyName, tcConfig, tcGlobals, tcImports, niceNameGen, tcInitial, openDecls0) + let loadClosureErrors = + [ match loadClosureOpt with | None -> () - | Some loadClosure -> + | Some loadClosure -> for inp in loadClosure.Inputs do - for (err, isError) in inp.MetaCommandDiagnostics do - yield err, (if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning) ] + yield! inp.MetaCommandDiagnostics ] - let initialErrors = Array.append (Array.ofList loadClosureErrors) (errorLogger.GetErrors()) - let tcAcc = - { tcGlobals=tcGlobals - tcImports=tcImports + let initialErrors = Array.append (Array.ofList loadClosureErrors) (errorLogger.GetDiagnostics()) + let tcInfo = + { tcState=tcState - tcConfig=tcConfig tcEnvAtEndOfFile=tcInitial - tcResolutionsRev=[] - tcSymbolUsesRev=[] - tcOpenDeclarationsRev=[] topAttribs=None - latestImplFile=None latestCcuSigForFile=None - tcDependencyFiles=basicDependencies - tcErrorsRev = [ initialErrors ] - tcModuleNamesDict = Map.empty } - return tcAcc } - - /// This is a build task function that gets placed into the build rules as the computation for a Vector.ScanLeft - /// - /// Type check all files. - let TypeCheckTask ctok (tcAcc: TypeCheckAccumulator) input: Eventually = - match input with - | Some input, _sourceRange, filename, parseErrors-> - IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBETypechecked filename) - let capturingErrorLogger = CompilationErrorLogger("TypeCheckTask", tcConfig.errorSeverityOptions) - let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput input, capturingErrorLogger) - let fullComputation = - eventually { - beforeFileChecked.Trigger filename - - ApplyMetaCommandsFromInputToTcConfig (tcConfig, input, Path.GetDirectoryName filename) |> ignore - let sink = TcResultsSinkImpl(tcAcc.tcGlobals) - let hadParseErrors = not (Array.isEmpty parseErrors) - - let input, moduleNamesDict = DeduplicateParsedInputModuleName tcAcc.tcModuleNamesDict input + tcErrorsRev = [ initialErrors ] + moduleNamesDict = Map.empty + tcDependencyFiles = basicDependencies + sigNameOpt = None + } + return + BoundModel.Create( + tcConfig, + tcGlobals, + tcImports, + keepAssemblyContents, + keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + defaultPartialTypeChecking, + beforeFileChecked, + fileChecked, + tcInfo, + None) } + + /// Type check all files eagerly. + let TypeCheckTask partialCheck (prevBoundModel: BoundModel) syntaxTree: NodeCode = + node { + let! tcInfo = prevBoundModel.GetOrComputeTcInfo() + let boundModel = prevBoundModel.Next(syntaxTree, tcInfo) + + // Eagerly type check + // We need to do this to keep the expected behavior of events (namely fileChecked) when checking a file/project. + if partialCheck then + let! _ = boundModel.GetOrComputeTcInfo() + () + else + let! _ = boundModel.GetOrComputeTcInfoWithExtras() + () - let! (tcEnvAtEndOfFile, topAttribs, implFile, ccuSigForFile), tcState = - TypeCheckOneInputEventually - ((fun () -> hadParseErrors || errorLogger.ErrorCount > 0), - tcConfig, tcAcc.tcImports, - tcAcc.tcGlobals, - None, - TcResultsSink.WithSink sink, - tcAcc.tcState, input) - - /// Only keep the typed interface files when doing a "full" build for fsc.exe, otherwise just throw them away - let implFile = if keepAssemblyContents then implFile else None - let tcResolutions = if keepAllBackgroundResolutions then sink.GetResolutions() else TcResolutions.Empty - let tcEnvAtEndOfFile = (if keepAllBackgroundResolutions then tcEnvAtEndOfFile else tcState.TcEnvFromImpls) - let tcSymbolUses = sink.GetSymbolUses() - - RequireCompilationThread ctok // Note: events get raised on the CompilationThread + return boundModel + } - fileChecked.Trigger filename - let newErrors = Array.append parseErrors (capturingErrorLogger.GetErrors()) - return {tcAcc with tcState=tcState - tcEnvAtEndOfFile=tcEnvAtEndOfFile - topAttribs=Some topAttribs - latestImplFile=implFile - latestCcuSigForFile=Some ccuSigForFile - tcResolutionsRev=tcResolutions :: tcAcc.tcResolutionsRev - tcSymbolUsesRev=tcSymbolUses :: tcAcc.tcSymbolUsesRev - tcOpenDeclarationsRev = sink.GetOpenDeclarations() :: tcAcc.tcOpenDeclarationsRev - tcErrorsRev = newErrors :: tcAcc.tcErrorsRev - tcModuleNamesDict = moduleNamesDict - tcDependencyFiles = filename :: tcAcc.tcDependencyFiles } - } - - // Run part of the Eventually<_> computation until a timeout is reached. If not complete, - // return a new Eventually<_> computation which recursively runs more of the computation. - // - When the whole thing is finished commit the error results sent through the errorLogger. - // - Each time we do real work we reinstall the CompilationGlobalsScope - let timeSlicedComputation = - fullComputation |> - Eventually.repeatedlyProgressUntilDoneOrTimeShareOverOrCanceled - maxTimeShareMilliseconds - CancellationToken.None - (fun ctok f -> - // Reinstall the compilation globals each time we start or restart - use unwind = new CompilationGlobalsScope (errorLogger, BuildPhase.TypeCheck) - f ctok) - - timeSlicedComputation - | _ -> - Eventually.Done tcAcc - - - /// This is a build task function that gets placed into the build rules as the computation for a Vector.Demultiplex - /// /// Finish up the typechecking to produce outputs for the rest of the compilation process - let FinalizeTypeCheckTask ctok (tcStates: TypeCheckAccumulator[]) = - cancellable { - DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok + let FinalizeTypeCheckTask (tcConfig: TcConfig) tcGlobals enablePartialTypeChecking assemblyName outfile (boundModels: block) = + node { + let errorLogger = CompilationErrorLogger("FinalizeTypeCheckTask", tcConfig.errorSeverityOptions) + use _ = new CompilationGlobalsScope(errorLogger, BuildPhase.TypeCheck) + + let! results = + boundModels + |> Block.map (fun boundModel -> node { + if enablePartialTypeChecking then + let! tcInfo = boundModel.GetOrComputeTcInfo() + return tcInfo, None + else + let! tcInfo, tcInfoExtras = boundModel.GetOrComputeTcInfoWithExtras() + return tcInfo, tcInfoExtras.latestImplFile + }) + |> Block.map (fun work -> + node { + let! tcInfo, latestImplFile = work + return (tcInfo.tcEnvAtEndOfFile, defaultArg tcInfo.topAttribs EmptyTopAttrs, latestImplFile, tcInfo.latestCcuSigForFile) + } + ) + |> NodeCode.Sequential - let errorLogger = CompilationErrorLogger("CombineImportedAssembliesTask", tcConfig.errorSeverityOptions) - use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.TypeCheck) + let results = results |> List.ofSeq // Get the state at the end of the type-checking of the last file - let finalAcc = tcStates.[tcStates.Length-1] + let finalBoundModel = boundModels.[boundModels.Length-1] + + let! finalInfo = finalBoundModel.GetOrComputeTcInfo() // Finish the checking - let (_tcEnvAtEndOfLastFile, topAttrs, mimpls, _), tcState = - let results = tcStates |> List.ofArray |> List.map (fun acc-> acc.tcEnvAtEndOfFile, defaultArg acc.topAttribs EmptyTopAttrs, acc.latestImplFile, acc.latestCcuSigForFile) - TypeCheckMultipleInputsFinish (results, finalAcc.tcState) - - let ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt = - try - // TypeCheckClosedInputSetFinish fills in tcState.Ccu but in incremental scenarios we don't want this, - // so we make this temporary here - let oldContents = tcState.Ccu.Deref.Contents - try - let tcState, tcAssemblyExpr = TypeCheckClosedInputSetFinish (mimpls, tcState) - - // Compute the identity of the generated assembly based on attributes, options etc. - // Some of this is duplicated from fsc.fs - let ilAssemRef = - let publicKey = - try - let signingInfo = Driver.ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) - match Driver.GetStrongNameSigner signingInfo with - | None -> None - | Some s -> Some (PublicKey.KeyAsToken(s.PublicKey)) - with e -> - errorRecoveryNoRange e - None - let locale = TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs - let assemVerFromAttrib = - TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs - |> Option.bind (fun v -> try Some (parseILVersion v) with _ -> None) - let ver = - match assemVerFromAttrib with - | None -> tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) - | Some v -> v - ILAssemblyRef.Create(assemblyName, None, publicKey, false, Some ver, locale) - - let tcAssemblyDataOpt = - try + let (_tcEnvAtEndOfLastFile, topAttrs, mimpls, _), tcState = + TypeCheckMultipleInputsFinish (results, finalInfo.tcState) - // Assemblies containing type provider components can not successfully be used via cross-assembly references. - // We return 'None' for the assembly portion of the cross-assembly reference - let hasTypeProviderAssemblyAttrib = - topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref, _, _, _, _, _, _)) -> - let nm = tcref.CompiledRepresentationForNamedType.BasicQualifiedName - nm = typeof.FullName) + let ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt = + try + let tcState, tcAssemblyExpr, ccuContents = TypeCheckClosedInputSetFinish (mimpls, tcState) - if tcState.CreatesGeneratedProvidedTypes || hasTypeProviderAssemblyAttrib then - None - else - Some (RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState, outfile, topAttrs, assemblyName, ilAssemRef) :> IRawFSharpAssemblyData) + let generatedCcu = tcState.Ccu.CloneWithFinalizedContents(ccuContents) - with e -> + // Compute the identity of the generated assembly based on attributes, options etc. + // Some of this is duplicated from fsc.fs + let ilAssemRef = + let publicKey = + try + let signingInfo = ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) + match GetStrongNameSigner signingInfo with + | None -> None + | Some s -> Some (PublicKey.KeyAsToken(s.PublicKey)) + with e -> errorRecoveryNoRange e None - ilAssemRef, tcAssemblyDataOpt, Some tcAssemblyExpr - finally - tcState.Ccu.Deref.Contents <- oldContents - with e -> + let locale = TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs + let assemVerFromAttrib = + TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs + |> Option.bind (fun v -> try Some (parseILVersion v) with _ -> None) + let ver = + match assemVerFromAttrib with + | None -> tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) + | Some v -> v + ILAssemblyRef.Create(assemblyName, None, publicKey, false, Some ver, locale) + + let tcAssemblyDataOpt = + try + // Assemblies containing type provider components can not successfully be used via cross-assembly references. + // We return 'None' for the assembly portion of the cross-assembly reference + let hasTypeProviderAssemblyAttrib = + topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref, _, _, _, _, _, _)) -> + let nm = tcref.CompiledRepresentationForNamedType.BasicQualifiedName + nm = typeof.FullName) + + if tcState.CreatesGeneratedProvidedTypes || hasTypeProviderAssemblyAttrib then + ProjectAssemblyDataResult.Unavailable true + else + ProjectAssemblyDataResult.Available (RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, generatedCcu, outfile, topAttrs, assemblyName, ilAssemRef) :> IRawFSharpAssemblyData) + with e -> + errorRecoveryNoRange e + ProjectAssemblyDataResult.Unavailable true + ilAssemRef, tcAssemblyDataOpt, Some tcAssemblyExpr + with e -> errorRecoveryNoRange e - mkSimpleAssemblyRef assemblyName, None, None - - let finalAccWithErrors = - { finalAcc with - tcErrorsRev = errorLogger.GetErrors() :: finalAcc.tcErrorsRev - topAttribs = Some topAttrs + mkSimpleAssemblyRef assemblyName, ProjectAssemblyDataResult.Unavailable true, None + + let diagnostics = errorLogger.GetDiagnostics() :: finalInfo.tcErrorsRev + let! finalBoundModelWithErrors = finalBoundModel.Finish(diagnostics, Some topAttrs) + return ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, finalBoundModelWithErrors + } + + let GetSyntaxTree tcConfig fileParsed lexResourceManager (sourceRange: range, filename: string, isLastCompiland) = + SyntaxTree(tcConfig, fileParsed, lexResourceManager, sourceRange, filename, isLastCompiland) + +[] +type IncrementalBuilderInitialState = + { + initialBoundModel: BoundModel + tcGlobals: TcGlobals + referencedAssemblies: block * (TimeStampCache -> DateTime)> + tcConfig: TcConfig + outfile: string + assemblyName: string + lexResourceManager: Lexhelp.LexResourceManager + fileNames: block + enablePartialTypeChecking: bool + beforeFileChecked: Event + fileChecked: Event + fileParsed: Event + projectChecked: Event +#if !NO_EXTENSIONTYPING + importsInvalidatedByTypeProvider: Event +#endif + allDependencies: string [] + defaultTimeStamp: DateTime + mutable isImportsInvalidated: bool + } + + static member Create( + initialBoundModel: BoundModel, + tcGlobals, + nonFrameworkAssemblyInputs, + tcConfig: TcConfig, + outfile, + assemblyName, + lexResourceManager, + sourceFiles, + enablePartialTypeChecking, + beforeFileChecked: Event, + fileChecked: Event, +#if !NO_EXTENSIONTYPING + importsInvalidatedByTypeProvider: Event, +#endif + allDependencies, + defaultTimeStamp: DateTime) = + + let initialState = + { + initialBoundModel = initialBoundModel + tcGlobals = tcGlobals + referencedAssemblies = nonFrameworkAssemblyInputs |> Block.ofSeq + tcConfig = tcConfig + outfile = outfile + assemblyName = assemblyName + lexResourceManager = lexResourceManager + fileNames = sourceFiles |> Block.ofSeq + enablePartialTypeChecking = enablePartialTypeChecking + beforeFileChecked = beforeFileChecked + fileChecked = fileChecked + fileParsed = Event() + projectChecked = Event() +#if !NO_EXTENSIONTYPING + importsInvalidatedByTypeProvider = importsInvalidatedByTypeProvider +#endif + allDependencies = allDependencies + defaultTimeStamp = defaultTimeStamp + isImportsInvalidated = false } - return ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, finalAccWithErrors - } +#if !NO_EXTENSIONTYPING + importsInvalidatedByTypeProvider.Publish.Add(fun () -> initialState.isImportsInvalidated <- true) +#endif + initialState + +[] +type IncrementalBuilderState = + { + // stampedFileNames represent the real stamps of the files. + // logicalStampedFileNames represent the stamps of the files that are used to calculate the project's logical timestamp. + stampedFileNames: block + logicalStampedFileNames: block + stampedReferencedAssemblies: block + initialBoundModel: GraphNode + boundModels: block> + finalizedBoundModel: GraphNode<(ILAssemblyRef * ProjectAssemblyDataResult * TypedImplFile list option * BoundModel) * DateTime> + } - // END OF BUILD TASK FUNCTIONS - // --------------------------------------------------------------------------------------------- +[] +module IncrementalBuilderStateHelpers = + + let createBoundModelGraphNode (initialState: IncrementalBuilderInitialState) initialBoundModel (boundModels: blockbuilder>) i = + let fileInfo = initialState.fileNames.[i] + let prevBoundModelGraphNode = + match i with + | 0 (* first file *) -> initialBoundModel + | _ -> boundModels.[i - 1] + let syntaxTree = GetSyntaxTree initialState.tcConfig initialState.fileParsed initialState.lexResourceManager fileInfo + GraphNode(node { + let! prevBoundModel = prevBoundModelGraphNode.GetOrComputeValue() + return! TypeCheckTask initialState.enablePartialTypeChecking prevBoundModel syntaxTree + }) + + let rec createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: blockbuilder>) = + GraphNode(node { + // Compute last bound model then get all the evaluated models. + let! _ = boundModels.[boundModels.Count - 1].GetOrComputeValue() + let boundModels = + boundModels.ToImmutable() + |> Block.map (fun x -> x.TryPeekValue().Value) + + let! result = + FinalizeTypeCheckTask + initialState.tcConfig + initialState.tcGlobals + initialState.enablePartialTypeChecking + initialState.assemblyName + initialState.outfile + boundModels + let result = (result, DateTime.UtcNow) + return result + }) + + and computeStampedFileName (initialState: IncrementalBuilderInitialState) (state: IncrementalBuilderState) (cache: TimeStampCache) slot fileInfo = + let currentStamp = state.stampedFileNames.[slot] + let stamp = StampFileNameTask cache fileInfo + + if currentStamp <> stamp then + match state.boundModels.[slot].TryPeekValue() with + // This prevents an implementation file that has a backing signature file from invalidating the rest of the build. + | ValueSome(boundModel) when initialState.enablePartialTypeChecking && boundModel.BackingSignature.IsSome -> + let newBoundModel = boundModel.ClearTcInfoExtras() + { state with + boundModels = state.boundModels.RemoveAt(slot).Insert(slot, GraphNode(node { return newBoundModel })) + stampedFileNames = state.stampedFileNames.SetItem(slot, StampFileNameTask cache fileInfo) + } + | _ -> - // --------------------------------------------------------------------------------------------- - // START OF BUILD DESCRIPTION + let stampedFileNames = state.stampedFileNames.ToBuilder() + let logicalStampedFileNames = state.logicalStampedFileNames.ToBuilder() + let boundModels = state.boundModels.ToBuilder() - // Inputs - let fileNamesNode = InputVector "FileNames" - let referencedAssembliesNode = InputVector*(TimeStampCache -> CompilationThreadToken -> DateTime)> "ReferencedAssemblies" - - // Build - let stampedFileNamesNode = Vector.Stamp "SourceFileTimeStamps" StampFileNameTask fileNamesNode - let stampedReferencedAssembliesNode = Vector.Stamp "StampReferencedAssembly" StampReferencedAssemblyTask referencedAssembliesNode - let initialTcAccNode = Vector.Demultiplex "CombineImportedAssemblies" CombineImportedAssembliesTask stampedReferencedAssembliesNode - let tcStatesNode = Vector.ScanLeft "TypeCheckingStates" (fun ctok tcAcc n -> TypeCheckTask ctok tcAcc (ParseTask ctok n)) initialTcAccNode stampedFileNamesNode - let finalizedTypeCheckNode = Vector.Demultiplex "FinalizeTypeCheck" FinalizeTypeCheckTask tcStatesNode + // Invalidate the file and all files below it. + for j = 0 to stampedFileNames.Count - slot - 1 do + let stamp = StampFileNameTask cache initialState.fileNames.[slot + j] + stampedFileNames.[slot + j] <- stamp + logicalStampedFileNames.[slot + j] <- stamp + boundModels.[slot + j] <- createBoundModelGraphNode initialState state.initialBoundModel boundModels (slot + j) - // Outputs - let buildDescription = new BuildDescriptionScope () + { state with + // Something changed, the finalized view of the project must be invalidated. + finalizedBoundModel = createFinalizeBoundModelGraphNode initialState boundModels - do buildDescription.DeclareVectorOutput stampedFileNamesNode - do buildDescription.DeclareVectorOutput stampedReferencedAssembliesNode - do buildDescription.DeclareVectorOutput tcStatesNode - do buildDescription.DeclareScalarOutput initialTcAccNode - do buildDescription.DeclareScalarOutput finalizedTypeCheckNode + stampedFileNames = stampedFileNames.ToImmutable() + logicalStampedFileNames = logicalStampedFileNames.ToImmutable() + boundModels = boundModels.ToImmutable() + } + else + state + + and computeStampedFileNames (initialState: IncrementalBuilderInitialState) state (cache: TimeStampCache) = + let mutable i = 0 + (state, initialState.fileNames) + ||> Block.fold (fun state fileInfo -> + let newState = computeStampedFileName initialState state cache i fileInfo + i <- i + 1 + newState + ) + + and computeStampedReferencedAssemblies (initialState: IncrementalBuilderInitialState) state canTriggerInvalidation (cache: TimeStampCache) = + let stampedReferencedAssemblies = state.stampedReferencedAssemblies.ToBuilder() + + let mutable referencesUpdated = false + initialState.referencedAssemblies + |> Block.iteri (fun i asmInfo -> + + let currentStamp = state.stampedReferencedAssemblies.[i] + let stamp = StampReferencedAssemblyTask cache asmInfo + + if currentStamp <> stamp then + referencesUpdated <- true + stampedReferencedAssemblies.[i] <- stamp + ) + + if referencesUpdated then + // Build is invalidated. The build must be rebuilt with the newly updated references. + if not initialState.isImportsInvalidated && canTriggerInvalidation then + initialState.isImportsInvalidated <- true + { state with + stampedReferencedAssemblies = stampedReferencedAssemblies.ToImmutable() + } + else + state + +type IncrementalBuilderState with + + (* + The data below represents a dependency graph. + + ReferencedAssembliesStamps => FileStamps => BoundModels => FinalizedBoundModel + *) + static member Create(initialState: IncrementalBuilderInitialState) = + let defaultTimeStamp = initialState.defaultTimeStamp + let initialBoundModel = initialState.initialBoundModel + let fileNames = initialState.fileNames + let referencedAssemblies = initialState.referencedAssemblies + + let cache = TimeStampCache(defaultTimeStamp) + let initialBoundModel = GraphNode(node { return initialBoundModel }) + let boundModels = BlockBuilder.create fileNames.Length + + for slot = 0 to fileNames.Length - 1 do + boundModels.Add(createBoundModelGraphNode initialState initialBoundModel boundModels slot) + + let state = + { + stampedFileNames = Block.init fileNames.Length (fun _ -> DateTime.MinValue) + logicalStampedFileNames = Block.init fileNames.Length (fun _ -> DateTime.MinValue) + stampedReferencedAssemblies = Block.init referencedAssemblies.Length (fun _ -> DateTime.MinValue) + initialBoundModel = initialBoundModel + boundModels = boundModels.ToImmutable() + finalizedBoundModel = createFinalizeBoundModelGraphNode initialState boundModels + } + let state = computeStampedReferencedAssemblies initialState state false cache + let state = computeStampedFileNames initialState state cache + state - // END OF BUILD DESCRIPTION - // --------------------------------------------------------------------------------------------- +/// Manages an incremental build graph for the build of a single F# project +type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: IncrementalBuilderState) = - do IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBECreated) + let initialBoundModel = initialState.initialBoundModel + let tcConfig = initialState.tcConfig + let fileNames = initialState.fileNames + let beforeFileChecked = initialState.beforeFileChecked + let fileChecked = initialState.fileChecked +#if !NO_EXTENSIONTYPING + let importsInvalidatedByTypeProvider = initialState.importsInvalidatedByTypeProvider +#endif + let allDependencies = initialState.allDependencies + let defaultTimeStamp = initialState.defaultTimeStamp + let fileParsed = initialState.fileParsed + let projectChecked = initialState.projectChecked + + let tryGetSlot (state: IncrementalBuilderState) slot = + match state.boundModels.[slot].TryPeekValue() with + | ValueSome boundModel -> + (boundModel, state.stampedFileNames.[slot]) + |> Some + | _ -> + None + + let tryGetBeforeSlot (state: IncrementalBuilderState) slot = + match slot with + | 0 (* first file *) -> + (initialBoundModel, defaultTimeStamp) + |> Some + | _ -> + tryGetSlot state (slot - 1) + + let evalUpToTargetSlot (state: IncrementalBuilderState) targetSlot = + node { + if targetSlot < 0 then + return Some(initialBoundModel, defaultTimeStamp) + else + let! boundModel = state.boundModels.[targetSlot].GetOrComputeValue() + return Some(boundModel, state.stampedFileNames.[targetSlot]) + } + + let MaxTimeStampInDependencies stamps = + if Seq.isEmpty stamps then + defaultTimeStamp + else + stamps + |> Seq.max + + let computeProjectTimeStamp (state: IncrementalBuilderState) = + let t1 = MaxTimeStampInDependencies state.stampedReferencedAssemblies + let t2 = MaxTimeStampInDependencies state.logicalStampedFileNames + max t1 t2 - let buildInputs = [ BuildInput.VectorInput (fileNamesNode, sourceFiles) - BuildInput.VectorInput (referencedAssembliesNode, nonFrameworkAssemblyInputs) ] + let gate = obj() + let mutable currentState = state - // This is the initial representation of progress through the build, i.e. we have made no progress. - let mutable partialBuild = buildDescription.GetInitialPartialBuild buildInputs + let setCurrentState state cache (ct: CancellationToken) = + lock gate (fun () -> + ct.ThrowIfCancellationRequested() + currentState <- computeStampedFileNames initialState state cache + ) - let SavePartialBuild (ctok: CompilationThreadToken) b = - RequireCompilationThread ctok // modifying state - partialBuild <- b + let checkFileTimeStamps (cache: TimeStampCache) = + node { + let! ct = NodeCode.CancellationToken + setCurrentState currentState cache ct + } - let MaxTimeStampInDependencies cache (ctok: CompilationThreadToken) (output: INode) = - IncrementalBuild.MaxTimeStampInDependencies cache ctok output.Name partialBuild + do IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBECreated) - member __.TcConfig = tcConfig + member _.TcConfig = tcConfig - member __.FileParsed = fileParsed.Publish + member _.FileParsed = fileParsed.Publish - member __.BeforeFileChecked = beforeFileChecked.Publish + member _.BeforeFileChecked = beforeFileChecked.Publish - member __.FileChecked = fileChecked.Publish + member _.FileChecked = fileChecked.Publish - member __.ProjectChecked = projectChecked.Publish + member _.ProjectChecked = projectChecked.Publish #if !NO_EXTENSIONTYPING - member __.ImportsInvalidatedByTypeProvider = importsInvalidatedByTypeProvider.Publish + member _.ImportsInvalidatedByTypeProvider = importsInvalidatedByTypeProvider.Publish #endif - member __.TryGetCurrentTcImports () = currentTcImportsOpt + member _.IsReferencesInvalidated = + // fast path + if initialState.isImportsInvalidated then true + else + computeStampedReferencedAssemblies initialState currentState true (TimeStampCache(defaultTimeStamp)) |> ignore + initialState.isImportsInvalidated - member __.AllDependenciesDeprecated = allDependencies + member _.AllDependenciesDeprecated = allDependencies - member __.Step (ctok: CompilationThreadToken) = - cancellable { + member _.PopulatePartialCheckingResults () = + node { let cache = TimeStampCache defaultTimeStamp // One per step - let! res = IncrementalBuild.Step cache ctok SavePartialBuild (Target(tcStatesNode, None)) partialBuild - match res with - | None -> - projectChecked.Trigger() - return false - | Some _ -> - return true + do! checkFileTimeStamps cache + let! _ = currentState.finalizedBoundModel.GetOrComputeValue() + projectChecked.Trigger() } - - member builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename: PartialCheckResults option = + + member builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename: PartialCheckResults option = let slotOfFile = builder.GetSlotOfFileName filename - let result = - match slotOfFile with - | (*first file*) 0 -> GetScalarResult(initialTcAccNode, partialBuild) - | _ -> GetVectorResultBySlot(tcStatesNode, slotOfFile-1, partialBuild) - + let result = tryGetBeforeSlot currentState slotOfFile + match result with - | Some (tcAcc, timestamp) -> Some (PartialCheckResults.Create (tcAcc, timestamp)) + | Some (boundModel, timestamp) -> Some (PartialCheckResults (boundModel, timestamp)) | _ -> None - - - member builder.AreCheckResultsBeforeFileInProjectReady filename = + + member builder.GetCheckResultsForFileInProjectEvenIfStale filename: PartialCheckResults option = let slotOfFile = builder.GetSlotOfFileName filename + let result = tryGetSlot currentState slotOfFile + + match result with + | Some (boundModel, timestamp) -> Some (PartialCheckResults (boundModel, timestamp)) + | _ -> None + + member builder.TryGetCheckResultsBeforeFileInProject filename = let cache = TimeStampCache defaultTimeStamp - match slotOfFile with - | (*first file*) 0 -> IncrementalBuild.IsReady cache (Target(initialTcAccNode, None)) partialBuild - | _ -> IncrementalBuild.IsReady cache (Target(tcStatesNode, Some (slotOfFile-1))) partialBuild - - member __.GetCheckResultsBeforeSlotInProject (ctok: CompilationThreadToken, slotOfFile) = - cancellable { + let tmpState = computeStampedFileNames initialState currentState cache + + let slotOfFile = builder.GetSlotOfFileName filename + match tryGetBeforeSlot tmpState slotOfFile with + | Some(boundModel, timestamp) -> PartialCheckResults(boundModel, timestamp) |> Some + | _ -> None + + member builder.AreCheckResultsBeforeFileInProjectReady filename = + (builder.TryGetCheckResultsBeforeFileInProject filename).IsSome + + member _.GetCheckResultsBeforeSlotInProject slotOfFile = + node { let cache = TimeStampCache defaultTimeStamp - let! result = - cancellable { - match slotOfFile with - | (*first file*) 0 -> - let! build = IncrementalBuild.Eval cache ctok SavePartialBuild initialTcAccNode partialBuild - return GetScalarResult(initialTcAccNode, build) - | _ -> - let! build = IncrementalBuild.EvalUpTo cache ctok SavePartialBuild (tcStatesNode, (slotOfFile-1)) partialBuild - return GetVectorResultBySlot(tcStatesNode, slotOfFile-1, build) - } - + do! checkFileTimeStamps cache + let! result = evalUpToTargetSlot currentState (slotOfFile - 1) + match result with + | Some (boundModel, timestamp) -> return PartialCheckResults(boundModel, timestamp) + | None -> return! failwith "Expected results to be ready. (GetCheckResultsBeforeSlotInProject)." + } + + member _.GetFullCheckResultsBeforeSlotInProject slotOfFile = + node { + let cache = TimeStampCache defaultTimeStamp + do! checkFileTimeStamps cache + let! result = evalUpToTargetSlot currentState (slotOfFile - 1) match result with - | Some (tcAcc, timestamp) -> return PartialCheckResults.Create (tcAcc, timestamp) - | None -> return! failwith "Build was not evaluated, expected the results to be ready after 'Eval' (GetCheckResultsBeforeSlotInProject)." + | Some (boundModel, timestamp) -> + let! _ = boundModel.GetOrComputeTcInfoExtras() + return PartialCheckResults(boundModel, timestamp) + | None -> return! failwith "Expected results to be ready. (GetFullCheckResultsBeforeSlotInProject)." } - member builder.GetCheckResultsBeforeFileInProject (ctok: CompilationThreadToken, filename) = + member builder.GetCheckResultsBeforeFileInProject filename = let slotOfFile = builder.GetSlotOfFileName filename - builder.GetCheckResultsBeforeSlotInProject (ctok, slotOfFile) + builder.GetCheckResultsBeforeSlotInProject slotOfFile - member builder.GetCheckResultsAfterFileInProject (ctok: CompilationThreadToken, filename) = + member builder.GetCheckResultsAfterFileInProject filename = let slotOfFile = builder.GetSlotOfFileName filename + 1 - builder.GetCheckResultsBeforeSlotInProject (ctok, slotOfFile) - - member builder.GetCheckResultsAfterLastFileInProject (ctok: CompilationThreadToken) = - builder.GetCheckResultsBeforeSlotInProject(ctok, builder.GetSlotsCount()) + builder.GetCheckResultsBeforeSlotInProject slotOfFile - member __.GetCheckResultsAndImplementationsForProject(ctok: CompilationThreadToken) = - cancellable { - let cache = TimeStampCache defaultTimeStamp - let! build = IncrementalBuild.Eval cache ctok SavePartialBuild finalizedTypeCheckNode partialBuild - match GetScalarResult(finalizedTypeCheckNode, build) with - | Some ((ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, tcAcc), timestamp) -> - return PartialCheckResults.Create (tcAcc, timestamp), ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt - | None -> - // helpers to diagnose https://github.com/Microsoft/visualfsharp/pull/2460/ - let brname = match GetTopLevelExprByName(build, finalizedTypeCheckNode.Name) with ScalarBuildRule se ->se.Id | _ -> Id 0xdeadbeef - let data = (finalizedTypeCheckNode.Name, - ((build.Results :> IDictionary<_, _>).Keys |> Seq.toArray), - brname, - build.Results.ContainsKey brname, - build.Results.TryFind brname |> Option.map (function ScalarResult sr -> Some(sr.TryGetAvailable().IsSome) | _ -> None)) - let msg = sprintf "Build was not evaluated, expected the results to be ready after 'Eval' (GetCheckResultsAndImplementationsForProject, data = %A)." data - return! failwith msg + member builder.GetFullCheckResultsBeforeFileInProject filename = + let slotOfFile = builder.GetSlotOfFileName filename + builder.GetFullCheckResultsBeforeSlotInProject slotOfFile + + member builder.GetFullCheckResultsAfterFileInProject filename = + node { + let slotOfFile = builder.GetSlotOfFileName filename + 1 + let! result = builder.GetFullCheckResultsBeforeSlotInProject(slotOfFile) + return result + } + + member builder.GetCheckResultsAfterLastFileInProject () = + builder.GetCheckResultsBeforeSlotInProject(builder.GetSlotsCount()) + + member _.GetCheckResultsAndImplementationsForProject() = + node { + let cache = TimeStampCache(defaultTimeStamp) + do! checkFileTimeStamps cache + let! result = currentState.finalizedBoundModel.GetOrComputeValue() + match result with + | (ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, boundModel), timestamp -> + return PartialCheckResults (boundModel, timestamp), ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt } - - member __.GetLogicalTimeStampForProject(cache, ctok: CompilationThreadToken) = - let t1 = MaxTimeStampInDependencies cache ctok stampedFileNamesNode - let t2 = MaxTimeStampInDependencies cache ctok stampedReferencedAssembliesNode - max t1 t2 - - member __.GetSlotOfFileName(filename: string) = + + member builder.GetFullCheckResultsAndImplementationsForProject() = + node { + let! result = builder.GetCheckResultsAndImplementationsForProject() + let results, _, _, _ = result + let! _ = results.GetOrComputeTcInfoWithExtras() // Make sure we forcefully evaluate the info + return result + } + + member _.GetLogicalTimeStampForProject(cache) = + let tmpState = computeStampedFileNames initialState currentState cache + computeProjectTimeStamp tmpState + + member _.TryGetSlotOfFileName(filename: string) = // Get the slot of the given file and force it to build. - let CompareFileNames (_, f2, _) = - let result = + let CompareFileNames (_, f2, _) = + let result = String.Compare(filename, f2, StringComparison.CurrentCultureIgnoreCase)=0 || String.Compare(FileSystem.GetFullPathShim filename, FileSystem.GetFullPathShim f2, StringComparison.CurrentCultureIgnoreCase)=0 result - match TryGetSlotByInput(fileNamesNode, partialBuild, CompareFileNames) with + match fileNames |> Block.tryFindIndex CompareFileNames with + | Some slot -> Some slot + | None -> None + + member this.GetSlotOfFileName(filename: string) = + match this.TryGetSlotOfFileName(filename) with | Some slot -> slot | None -> failwith (sprintf "The file '%s' was not part of the project. Did you call InvalidateConfiguration when the list of files in the project changed?" filename) - - member __.GetSlotsCount () = - let expr = GetExprByName(partialBuild, fileNamesNode) - match partialBuild.Results.TryFind(expr.Id) with - | Some (VectorResult vr) -> vr.Size - | _ -> failwith "Failed to find sizes" - - member builder.GetParseResultsForFile (ctok: CompilationThreadToken, filename) = - cancellable { + + member _.GetSlotsCount () = fileNames.Length + + member this.ContainsFile(filename: string) = + (this.TryGetSlotOfFileName filename).IsSome + + member builder.GetParseResultsForFile filename = let slotOfFile = builder.GetSlotOfFileName filename - let! results = - cancellable { - match GetVectorResultBySlot(stampedFileNamesNode, slotOfFile, partialBuild) with - | Some (results, _) -> return results - | None -> - let cache = TimeStampCache defaultTimeStamp - let! build = IncrementalBuild.EvalUpTo cache ctok SavePartialBuild (stampedFileNamesNode, slotOfFile) partialBuild - match GetVectorResultBySlot(stampedFileNamesNode, slotOfFile, build) with - | Some (results, _) -> return results - | None -> return! failwith "Build was not evaluated, expected the results to be ready after 'Eval' (GetParseResultsForFile)." - } + let fileInfo = fileNames.[slotOfFile] // re-parse on demand instead of retaining - return ParseTask ctok results - } + let syntaxTree = GetSyntaxTree initialState.tcConfig initialState.fileParsed initialState.lexResourceManager fileInfo + syntaxTree.Parse None - member __.SourceFiles = sourceFiles |> List.map (fun (_, f, _) -> f) + member _.SourceFiles = fileNames |> Seq.map (fun (_, f, _) -> f) |> List.ofSeq /// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also /// creates an incremental builder used by the command line compiler. - static member TryCreateBackgroundBuilderForProjectOptions - (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, + static member TryCreateIncrementalBuilderForProjectOptions + (legacyReferenceResolver, defaultFSharpBinariesDir, frameworkTcImportsCache: FrameworkImportsCache, loadClosureOpt: LoadClosure option, sourceFiles: string list, commandLineArgs: string list, projectReferences, projectDirectory, useScriptResolutionRules, keepAssemblyContents, - keepAllBackgroundResolutions, maxTimeShareMilliseconds, - tryGetMetadataSnapshot, suggestNamesForErrors) = + keepAllBackgroundResolutions, + tryGetMetadataSnapshot, suggestNamesForErrors, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking: bool, + dependencyProvider) = + let useSimpleResolutionSwitch = "--simpleresolution" - cancellable { + node { // Trap and report warnings and errors from creation. let delayedLogger = CapturingErrorLogger("IncrementalBuilderCreation") - use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayedLogger) - use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter + use _ = new CompilationGlobalsScope(delayedLogger, BuildPhase.Parameter) let! builderOpt = - cancellable { + node { try - // Create the builder. + // Create the builder. // Share intern'd strings across all lexing/parsing - let resourceManager = new Lexhelp.LexResourceManager() + let resourceManager = Lexhelp.LexResourceManager() /// Create a type-check configuration - let tcConfigB, sourceFilesNew = + let tcConfigB, sourceFiles = let getSwitchValue switchString = - match commandLineArgs |> Seq.tryFindIndex(fun s -> s.StartsWithOrdinal switchString) with + match commandLineArgs |> List.tryFindIndex(fun s -> s.StartsWithOrdinal switchString) with | Some idx -> Some(commandLineArgs.[idx].Substring(switchString.Length)) | _ -> None + let sdkDirOverride = + match loadClosureOpt with + | None -> None + | Some loadClosure -> loadClosure.SdkDirOverride + // see also fsc.fs: runFromCommandLineToImportingAssemblies(), as there are many similarities to where the PS creates a tcConfigB - let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, - defaultFSharpBinariesDir, - implicitIncludeDir=projectDirectory, - reduceMemoryUsage=ReduceMemoryFlag.Yes, - isInteractive=useScriptResolutionRules, - isInvalidationSupported=true, - defaultCopyFSharpCore=CopyFSharpCoreFlag.No, - tryGetMetadataSnapshot=tryGetMetadataSnapshot) - - tcConfigB.resolutionEnvironment <- (ReferenceResolver.ResolutionEnvironment.EditingOrCompilation true) - - tcConfigB.conditionalCompilationDefines <- + let tcConfigB = + TcConfigBuilder.CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir, + implicitIncludeDir=projectDirectory, + reduceMemoryUsage=ReduceMemoryFlag.Yes, + isInteractive=useScriptResolutionRules, + isInvalidationSupported=true, + defaultCopyFSharpCore=CopyFSharpCoreFlag.No, + tryGetMetadataSnapshot=tryGetMetadataSnapshot, + sdkDirOverride=sdkDirOverride, + rangeForErrors=range0) + + tcConfigB.primaryAssembly <- + match loadClosureOpt with + | None -> PrimaryAssembly.Mscorlib + | Some loadClosure -> + if loadClosure.UseDesktopFramework then + PrimaryAssembly.Mscorlib + else + PrimaryAssembly.System_Runtime + + tcConfigB.resolutionEnvironment <- (LegacyResolutionEnvironment.EditingOrCompilation true) + + tcConfigB.conditionalCompilationDefines <- let define = if useScriptResolutionRules then "INTERACTIVE" else "COMPILED" define :: tcConfigB.conditionalCompilationDefines @@ -1753,76 +1444,168 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput // Never open PDB files for the language service, even if --standalone is specified tcConfigB.openDebugInformationForLaterStaticLinking <- false - tcConfigB.compilationThread <- - { new ICompilationThread with - member __.EnqueueWork work = - Reactor.Singleton.EnqueueOp ("Unknown", "ICompilationThread.EnqueueWork", "work", fun ctok -> - work ctok - ) + tcConfigB.xmlDocInfoLoader <- + { new IXmlDocumentationInfoLoader with + /// Try to load xml documentation associated with an assembly by the same file path with the extension ".xml". + member _.TryLoad(assemblyFileName, _ilModule) = + let xmlFileName = Path.ChangeExtension(assemblyFileName, ".xml") + + // REVIEW: File IO - Will eventually need to change this to use a file system interface of some sort. + XmlDocumentationInfo.TryCreateFromFile(xmlFileName) } + |> Some tcConfigB, sourceFilesNew - match loadClosureOpt with - | Some loadClosure -> - let dllReferences = - [for reference in tcConfigB.referencedDLLs do - // If there's (one or more) resolutions of closure references then yield them all - match loadClosure.References |> List.tryFind (fun (resolved, _)->resolved=reference.Text) with - | Some (resolved, closureReferences) -> - for closureReference in closureReferences do - yield AssemblyReference(closureReference.originalReference.Range, resolved, None) - | None -> yield reference] - tcConfigB.referencedDLLs <- [] - // Add one by one to remove duplicates - dllReferences |> List.iter (fun dllReference -> - tcConfigB.AddReferencedAssemblyByPath(dllReference.Range, dllReference.Text)) - tcConfigB.knownUnresolvedReferences <- loadClosure.UnresolvedReferences - | None -> () + // If this is a builder for a script, re-apply the settings inferred from the + // script and its load closure to the configuration. + // + // NOTE: it would probably be cleaner and more accurate to re-run the load closure at this point. + let setupConfigFromLoadClosure () = + match loadClosureOpt with + | Some loadClosure -> + let dllReferences = + [for reference in tcConfigB.referencedDLLs do + // If there's (one or more) resolutions of closure references then yield them all + match loadClosure.References |> List.tryFind (fun (resolved, _)->resolved=reference.Text) with + | Some (resolved, closureReferences) -> + for closureReference in closureReferences do + yield AssemblyReference(closureReference.originalReference.Range, resolved, None) + | None -> yield reference] + tcConfigB.referencedDLLs <- [] + tcConfigB.primaryAssembly <- (if loadClosure.UseDesktopFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) + // Add one by one to remove duplicates + dllReferences |> List.iter (fun dllReference -> + tcConfigB.AddReferencedAssemblyByPath(dllReference.Range, dllReference.Text)) + tcConfigB.knownUnresolvedReferences <- loadClosure.UnresolvedReferences + | None -> () + + setupConfigFromLoadClosure() let tcConfig = TcConfig.Create(tcConfigB, validate=true) let niceNameGen = NiceNameGenerator() - let outfile, _, assemblyName = tcConfigB.DecideNames sourceFilesNew + let outfile, _, assemblyName = tcConfigB.DecideNames sourceFiles // Resolve assemblies and create the framework TcImports. This is done when constructing the - // builder itself, rather than as an incremental task. This caches a level of "system" references. No type providers are - // included in these references. - let! (tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences) = frameworkTcImportsCache.Get(ctok, tcConfig) + // builder itself, rather than as an incremental task. This caches a level of "system" references. No type providers are + // included in these references. + let! tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences = frameworkTcImportsCache.Get(tcConfig) - // Note we are not calling errorLogger.GetErrors() anywhere for this task. + // Note we are not calling errorLogger.GetDiagnostics() anywhere for this task. // This is ok because not much can actually go wrong here. let errorOptions = tcConfig.errorSeverityOptions let errorLogger = CompilationErrorLogger("nonFrameworkAssemblyInputs", errorOptions) - // Return the disposable object that cleans up - use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) + use _ = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) - // Get the names and time stamps of all the non-framework referenced assemblies, which will act - // as inputs to one of the nodes in the build. + // Get the names and time stamps of all the non-framework referenced assemblies, which will act + // as inputs to one of the nodes in the build. // - // This operation is done when constructing the builder itself, rather than as an incremental task. - let nonFrameworkAssemblyInputs = - // Note we are not calling errorLogger.GetErrors() anywhere for this task. + // This operation is done when constructing the builder itself, rather than as an incremental task. + let nonFrameworkAssemblyInputs = + // Note we are not calling errorLogger.GetDiagnostics() anywhere for this task. // This is ok because not much can actually go wrong here. let errorLogger = CompilationErrorLogger("nonFrameworkAssemblyInputs", errorOptions) // Return the disposable object that cleans up - use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) + use _holder = new CompilationGlobalsScope(errorLogger, BuildPhase.Parameter) [ for r in nonFrameworkResolutions do let fileName = r.resolvedPath - yield (Choice1Of2 fileName, (fun (cache: TimeStampCache) _ctok -> cache.GetFileTimeStamp fileName)) + yield (Choice1Of2 fileName, (fun (cache: TimeStampCache) -> cache.GetFileTimeStamp fileName)) for pr in projectReferences do - yield Choice2Of2 pr, (fun (cache: TimeStampCache) ctok -> cache.GetProjectReferenceTimeStamp (pr, ctok)) ] - - let builder = - new IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInputs, nonFrameworkResolutions, unresolvedReferences, - tcConfig, projectDirectory, outfile, assemblyName, niceNameGen, - resourceManager, sourceFilesNew, loadClosureOpt, - keepAssemblyContents=keepAssemblyContents, - keepAllBackgroundResolutions=keepAllBackgroundResolutions, - maxTimeShareMilliseconds=maxTimeShareMilliseconds) + yield Choice2Of2 pr, (fun (cache: TimeStampCache) -> cache.GetProjectReferenceTimeStamp pr) ] + + // + // + // + // + // Start importing + + let tcConfigP = TcConfigProvider.Constant tcConfig + let beforeFileChecked = Event() + let fileChecked = Event() + +#if !NO_EXTENSIONTYPING + let importsInvalidatedByTypeProvider = Event() +#endif + + // Check for the existence of loaded sources and prepend them to the sources list if present. + let sourceFiles = tcConfig.GetAvailableLoadedSources() @ (sourceFiles |>List.map (fun s -> rangeStartup, s)) + + // Mark up the source files with an indicator flag indicating if they are the last source file in the project + let sourceFiles = + let flags, isExe = tcConfig.ComputeCanContainEntryPoint(sourceFiles |> List.map snd) + ((sourceFiles, flags) ||> List.map2 (fun (m, nm) flag -> (m, nm, (flag, isExe)))) + + let basicDependencies = + [ for UnresolvedAssemblyReference(referenceText, _) in unresolvedReferences do + // Exclude things that are definitely not a file name + if not(FileSystem.IsInvalidPathShim referenceText) then + let file = if FileSystem.IsPathRootedShim referenceText then referenceText else Path.Combine(projectDirectory, referenceText) + yield file + + for r in nonFrameworkResolutions do + yield r.resolvedPath ] + + let allDependencies = + [| yield! basicDependencies + for _, f, _ in sourceFiles do + yield f |] + + // For scripts, the dependency provider is already available. + // For projects create a fresh one for the project. + let dependencyProvider = + match dependencyProvider with + | None -> new DependencyProvider() + | Some dependencyProvider -> dependencyProvider + + let defaultTimeStamp = DateTime.UtcNow + + let! initialBoundModel = + CombineImportedAssembliesTask( + assemblyName, + tcConfig, + tcConfigP, + tcGlobals, + frameworkTcImports, + nonFrameworkResolutions, + unresolvedReferences, + dependencyProvider, + loadClosureOpt, + niceNameGen, + basicDependencies, + keepAssemblyContents, + keepAllBackgroundResolutions, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, + importsInvalidatedByTypeProvider + ) + + let initialState = + IncrementalBuilderInitialState.Create( + initialBoundModel, + tcGlobals, + nonFrameworkAssemblyInputs, + tcConfig, + outfile, + assemblyName, + resourceManager, + sourceFiles, + enablePartialTypeChecking, + beforeFileChecked, + fileChecked, +#if !NO_EXTENSIONTYPING + importsInvalidatedByTypeProvider, +#endif + allDependencies, + defaultTimeStamp) + + let builder = IncrementalBuilder(initialState, IncrementalBuilderState.Create(initialState)) return Some builder - with e -> + with e -> errorRecoveryNoRange e return None } @@ -1833,10 +1616,10 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let errorSeverityOptions = builder.TcConfig.errorSeverityOptions let errorLogger = CompilationErrorLogger("IncrementalBuilderCreation", errorSeverityOptions) delayedLogger.CommitDelayedDiagnostics errorLogger - errorLogger.GetErrors() |> Array.map (fun (d, severity) -> d, severity = FSharpErrorSeverity.Error) + errorLogger.GetDiagnostics() | _ -> Array.ofList delayedLogger.Diagnostics - |> Array.map (fun (d, isError) -> FSharpErrorInfo.CreateFromException(d, isError, range.Zero, suggestNamesForErrors)) + |> Array.map (fun (d, severity) -> FSharpDiagnostic.CreateFromException(d, severity, range.Zero, suggestNamesForErrors)) return builderOpt, diagnostics } diff --git a/src/fsharp/service/IncrementalBuild.fsi b/src/fsharp/service/IncrementalBuild.fsi index fb60dbff690..015c88db66d 100755 --- a/src/fsharp/service/IncrementalBuild.fsi +++ b/src/fsharp/service/IncrementalBuild.fsi @@ -1,25 +1,36 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler +namespace FSharp.Compiler.CodeAnalysis open System open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.ErrorLogger open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.ErrorLogger open FSharp.Compiler.NameResolution -open FSharp.Compiler.Tast -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Syntax +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.BuildGraph /// Lookup the global static cache for building the FrameworkTcImports type internal FrameworkImportsCache = new : size: int -> FrameworkImportsCache - member Get : CompilationThreadToken * TcConfig -> Cancellable - member Clear: CompilationThreadToken -> unit - member Downsize: CompilationThreadToken -> unit + + member Get : TcConfig -> NodeCode + + member Clear: unit -> unit + + member Downsize: unit -> unit /// Used for unit testing module internal IncrementalBuilderEventTesting = @@ -32,49 +43,89 @@ module internal IncrementalBuilderEventTesting = val GetMostRecentIncrementalBuildEvents : int -> IBEvent list val GetCurrentIncrementalBuildEventNum : unit -> int -/// Represents the state in the incremental graph associated with checking a file -type internal PartialCheckResults = - { /// This field is None if a major unrecovered error occurred when preparing the initial state - TcState : TcState - TcImports: TcImports - TcGlobals: TcGlobals - TcConfig: TcConfig +/// Accumulated results of type checking. The minimum amount of state in order to continue type-checking following files. +[] +type internal TcInfo = + { + tcState: TcState + tcEnvAtEndOfFile: CheckExpressions.TcEnv - /// This field is None if a major unrecovered error occurred when preparing the initial state - TcEnvAtEnd : TypeChecker.TcEnv + /// Disambiguation table for module names + moduleNamesDict: ModuleNamesDict - /// Represents the collected errors from type checking - TcErrorsRev : (PhasedDiagnostic * FSharpErrorSeverity)[] list + topAttribs: TopAttribs option - /// Represents the collected name resolutions from type checking - TcResolutionsRev: TcResolutions list + latestCcuSigForFile: ModuleOrNamespaceType option - /// Represents the collected uses of symbols from type checking - TcSymbolUsesRev: TcSymbolUses list + /// Accumulated errors, last file first + tcErrorsRev:(PhasedDiagnostic * FSharpDiagnosticSeverity)[] list - /// Represents open declarations - TcOpenDeclarationsRev: OpenDeclaration[] list + tcDependencyFiles: string list - /// Disambiguation table for module names - ModuleNamesDict: ModuleNamesDict + sigNameOpt: (string * QualifiedNameOfFile) option + } - TcDependencyFiles: string list + member TcErrors: (PhasedDiagnostic * FSharpDiagnosticSeverity)[] - /// Represents the collected attributes to apply to the module of assembly generates - TopAttribs: TypeChecker.TopAttribs option +/// Accumulated results of type checking. Optional data that isn't needed to type-check a file, but needed for more information for in tooling. +[] +type internal TcInfoExtras = + { + tcResolutions: TcResolutions + tcSymbolUses: TcSymbolUses + tcOpenDeclarations: OpenDeclaration[] - TimeStamp: DateTime + /// Result of checking most recent file, if any + latestImplFile: TypedImplFile option - /// Represents latest complete typechecked implementation file, including its typechecked signature if any. - /// Empty for a signature file. - LatestImplementationFile: TypedImplFile option + /// If enabled, stores a linear list of ranges and strings that identify an Item(symbol) in a file. Used for background find all references. + itemKeyStore: ItemKeyStore option - /// Represents latest inferred signature contents. - LatestCcuSigForFile: ModuleOrNamespaceType option} + /// If enabled, holds semantic classification information for Item(symbol)s in a file. + semanticClassificationKeyStore: SemanticClassificationKeyStore option + } - member TcErrors: (PhasedDiagnostic * FSharpErrorSeverity)[] + member TcSymbolUses: TcSymbolUses + +/// Represents the state in the incremental graph associated with checking a file +[] +type internal PartialCheckResults = - member TcSymbolUses: TcSymbolUses list + member TcImports: TcImports + + member TcGlobals: TcGlobals + + member TcConfig: TcConfig + + member TimeStamp: DateTime + + member TryPeekTcInfo: unit -> TcInfo option + + member TryPeekTcInfoWithExtras: unit -> (TcInfo * TcInfoExtras) option + + /// Compute the "TcInfo" part of the results. If `enablePartialTypeChecking` is false then + /// extras will also be available. + member GetOrComputeTcInfo: unit -> NodeCode + + /// Compute both the "TcInfo" and "TcInfoExtras" parts of the results. + /// Can cause a second type-check if `enablePartialTypeChecking` is true in the checker. + /// Only use when it's absolutely necessary to get rich information on a file. + member GetOrComputeTcInfoWithExtras: unit -> NodeCode + + /// Compute the "ItemKeyStore" parts of the results. + /// Can cause a second type-check if `enablePartialTypeChecking` is true in the checker. + /// Only use when it's absolutely necessary to get rich information on a file. + /// + /// Will return 'None' for enableBackgroundItemKeyStoreAndSemanticClassification=false. + member GetOrComputeItemKeyStoreIfEnabled: unit -> NodeCode + + /// Can cause a second type-check if `enablePartialTypeChecking` is true in the checker. + /// Only use when it's absolutely necessary to get rich information on a file. + /// + /// Will return 'None' for enableBackgroundItemKeyStoreAndSemanticClassification=false. + member GetOrComputeSemanticClassificationIfEnabled: unit -> NodeCode + + member TimeStamp: DateTime /// Manages an incremental build graph for the build of an F# project [] @@ -102,18 +153,18 @@ type internal IncrementalBuilder = member ProjectChecked : IEvent #if !NO_EXTENSIONTYPING - /// Raised when a type provider invalidates the build. - member ImportsInvalidatedByTypeProvider : IEvent + /// Raised when the build is invalidated. + member ImportsInvalidatedByTypeProvider : IEvent #endif - /// Tries to get the current successful TcImports. This is only used in testing. Do not use it for other stuff. - member TryGetCurrentTcImports : unit -> TcImports option + /// Check if one of the build's references is invalidated. + member IsReferencesInvalidated : bool /// The list of files the build depends on member AllDependenciesDeprecated : string[] - /// Perform one step in the F# build. Return true if the background work is finished. - member Step : CompilationThreadToken -> Cancellable + /// The project build. Return true if the background work is finished. + member PopulatePartialCheckingResults: unit -> NodeCode /// Get the preceding typecheck state of a slot, without checking if it is up-to-date w.r.t. /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available. @@ -122,6 +173,13 @@ type internal IncrementalBuilder = /// This is safe for use from non-compiler threads but the objects returned must in many cases be accessed only from the compiler thread. member GetCheckResultsBeforeFileInProjectEvenIfStale: filename:string -> PartialCheckResults option + /// Get the typecheck state of a slot, without checking if it is up-to-date w.r.t. + /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available. + /// This is a very quick operation. + /// + /// This is safe for use from non-compiler threads but the objects returned must in many cases be accessed only from the compiler thread. + member GetCheckResultsForFileInProjectEvenIfStale: filename:string -> PartialCheckResults option + /// Get the preceding typecheck state of a slot, but only if it is up-to-date w.r.t. /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available. /// This is a relatively quick operation. @@ -129,126 +187,77 @@ type internal IncrementalBuilder = /// This is safe for use from non-compiler threads member AreCheckResultsBeforeFileInProjectReady: filename:string -> bool + /// Get the preceding typecheck state of a slot, WITH checking if it is up-to-date w.r.t. However, files will not be parsed or checked. + /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available or if it is not up-to-date. + /// + /// This is safe for use from non-compiler threads but the objects returned must in many cases be accessed only from the compiler thread. + member TryGetCheckResultsBeforeFileInProject: filename: string -> PartialCheckResults option + /// Get the preceding typecheck state of a slot. Compute the entire type check of the project up /// to the necessary point if the result is not available. This may be a long-running operation. - /// - // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) - member GetCheckResultsBeforeFileInProject : CompilationThreadToken * filename:string -> Cancellable + member GetCheckResultsBeforeFileInProject : filename:string -> NodeCode + + /// Get the preceding typecheck state of a slot. Compute the entire type check of the project up + /// to the necessary point if the result is not available. This may be a long-running operation. + /// This will get full type-check info for the file, meaning no partial type-checking. + member GetFullCheckResultsBeforeFileInProject : filename:string -> NodeCode /// Get the typecheck state after checking a file. Compute the entire type check of the project up /// to the necessary point if the result is not available. This may be a long-running operation. - /// - // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) - member GetCheckResultsAfterFileInProject : CompilationThreadToken * filename:string -> Cancellable + member GetCheckResultsAfterFileInProject : filename:string -> NodeCode + + /// Get the typecheck state after checking a file. Compute the entire type check of the project up + /// to the necessary point if the result is not available. This may be a long-running operation. + /// This will get full type-check info for the file, meaning no partial type-checking. + member GetFullCheckResultsAfterFileInProject : filename:string -> NodeCode /// Get the typecheck result after the end of the last file. The typecheck of the project is not 'completed'. /// This may be a long-running operation. - /// - // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) - member GetCheckResultsAfterLastFileInProject : CompilationThreadToken -> Cancellable + member GetCheckResultsAfterLastFileInProject : unit -> NodeCode /// Get the final typecheck result. If 'generateTypedImplFiles' was set on Create then the TypedAssemblyAfterOptimization will contain implementations. /// This may be a long-running operation. - /// - // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) - member GetCheckResultsAndImplementationsForProject : CompilationThreadToken -> Cancellable + member GetCheckResultsAndImplementationsForProject : unit -> NodeCode + + /// Get the final typecheck result. If 'generateTypedImplFiles' was set on Create then the TypedAssemblyAfterOptimization will contain implementations. + /// This may be a long-running operation. + /// This will get full type-check info for the project, meaning no partial type-checking. + member GetFullCheckResultsAndImplementationsForProject : unit -> NodeCode /// Get the logical time stamp that is associated with the output of the project if it were gully built immediately - member GetLogicalTimeStampForProject: TimeStampCache * CompilationThreadToken -> DateTime + member GetLogicalTimeStampForProject: TimeStampCache -> DateTime + + /// Does the given file exist in the builder's pipeline? + member ContainsFile: filename: string -> bool /// Await the untyped parse results for a particular slot in the vector of parse results. /// /// This may be a marginally long-running operation (parses are relatively quick, only one file needs to be parsed) - member GetParseResultsForFile : CompilationThreadToken * filename:string -> Cancellable - - static member TryCreateBackgroundBuilderForProjectOptions : CompilationThreadToken * ReferenceResolver.Resolver * defaultFSharpBinariesDir: string * FrameworkImportsCache * scriptClosureOptions:LoadClosure option * sourceFiles:string list * commandLineArgs:string list * projectReferences: IProjectReference list * projectDirectory:string * useScriptResolutionRules:bool * keepAssemblyContents: bool * keepAllBackgroundResolutions: bool * maxTimeShareMilliseconds: int64 * tryGetMetadataSnapshot: ILBinaryReader.ILReaderTryGetMetadataSnapshot * suggestNamesForErrors: bool -> Cancellable + member GetParseResultsForFile: filename:string -> ParsedInput * range * string * (PhasedDiagnostic * FSharpDiagnosticSeverity)[] + + /// Create the incremental builder + static member TryCreateIncrementalBuilderForProjectOptions: + LegacyReferenceResolver * + defaultFSharpBinariesDir: string * + FrameworkImportsCache * + loadClosureOpt:LoadClosure option * + sourceFiles:string list * + commandLineArgs:string list * + projectReferences: IProjectReference list * + projectDirectory:string * + useScriptResolutionRules:bool * + keepAssemblyContents: bool * + keepAllBackgroundResolutions: bool * + tryGetMetadataSnapshot: ILBinaryReader.ILReaderTryGetMetadataSnapshot * + suggestNamesForErrors: bool * + keepAllBackgroundSymbolUses: bool * + enableBackgroundItemKeyStoreAndSemanticClassification: bool * + enablePartialTypeChecking: bool * + dependencyProvider: DependencyProvider option + -> NodeCode /// Generalized Incremental Builder. This is exposed only for unit testing purposes. module internal IncrementalBuild = - type INode = - abstract Name: string - - type ScalarBuildRule - type VectorBuildRule - - [] - type IScalar = - inherit INode - abstract Expr: ScalarBuildRule - - [] - type IVector = - inherit INode - abstract Expr: VectorBuildRule - - type Scalar<'T> = interface inherit IScalar end - - type Vector<'T> = interface inherit IVector end - - /// A set of build rules and the corresponding, possibly partial, results from building. - type PartialBuild - - /// Declares a vector build input. - /// Only required for unit testing. - val InputScalar : string -> Scalar<'T> - - /// Declares a scalar build input. - /// Only required for unit testing. - val InputVector : string -> Vector<'T> - - /// Methods for acting on build Vectors - /// Only required for unit testing. - module Vector = - /// Maps one vector to another using the given function. - val Map : string -> (CompilationThreadToken -> 'I -> 'O) -> Vector<'I> -> Vector<'O> - /// Updates the creates a new vector with the same items but with - /// timestamp specified by the passed-in function. - val Stamp : string -> (TimeStampCache -> CompilationThreadToken -> 'I -> System.DateTime) -> Vector<'I> -> Vector<'I> - /// Apply a function to each element of the vector, threading an accumulator argument - /// through the computation. Returns intermediate results in a vector. - val ScanLeft : string -> (CompilationThreadToken -> 'A -> 'I -> Eventually<'A>) -> Scalar<'A> -> Vector<'I> -> Vector<'A> - /// Apply a function to a vector to get a scalar value. - val Demultiplex : string -> (CompilationThreadToken -> 'I[] -> Cancellable<'O>)->Vector<'I> -> Scalar<'O> - /// Convert a Vector into a Scalar. - val AsScalar: string -> Vector<'I> -> Scalar<'I[]> - - type Target = Target of INode * int option /// Used for unit testing. Causes all steps of underlying incremental graph evaluation to cancel val LocallyInjectCancellationFault : unit -> IDisposable - - /// Evaluate a build. Only required for unit testing. - val Eval : TimeStampCache -> CompilationThreadToken -> (CompilationThreadToken -> PartialBuild -> unit) -> INode -> PartialBuild -> Cancellable - - /// Evaluate a build for a vector up to a limit. Only required for unit testing. - val EvalUpTo : TimeStampCache -> CompilationThreadToken -> (CompilationThreadToken -> PartialBuild -> unit) -> INode * int -> PartialBuild -> Cancellable - - /// Do one step in the build. Only required for unit testing. - val Step : TimeStampCache -> CompilationThreadToken -> (CompilationThreadToken -> PartialBuild -> unit) -> Target -> PartialBuild -> Cancellable - - /// Get a scalar vector. Result must be available. Only required for unit testing. - val GetScalarResult : Scalar<'T> * PartialBuild -> ('T * System.DateTime) option - - /// Get a result vector. All results must be available or thrown an exception. Only required for unit testing. - val GetVectorResult : Vector<'T> * PartialBuild -> 'T[] - - /// Get an element of vector result or None if there were no results. Only required for unit testing. - val GetVectorResultBySlot<'T> : Vector<'T> * int * PartialBuild -> ('T * System.DateTime) option - - [] - type BuildInput = - /// Declare a named scalar output. - static member ScalarInput: node:Scalar<'T> * value: 'T -> BuildInput - static member VectorInput: node:Vector<'T> * value: 'T list -> BuildInput - - /// Declare build outputs and bind them to real values. - /// Only required for unit testing. - type BuildDescriptionScope = - new : unit -> BuildDescriptionScope - /// Declare a named scalar output. - member DeclareScalarOutput : output:Scalar<'T> -> unit - /// Declare a named vector output. - member DeclareVectorOutput : output:Vector<'T> -> unit - /// Set the concrete inputs for this build. - member GetInitialPartialBuild : vectorinputs: BuildInput list -> PartialBuild - diff --git a/src/fsharp/service/ItemKey.fs b/src/fsharp/service/ItemKey.fs new file mode 100644 index 00000000000..0613af95551 --- /dev/null +++ b/src/fsharp/service/ItemKey.fs @@ -0,0 +1,434 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open System.IO +open System.IO.MemoryMappedFiles +open System.Reflection.Metadata +open System.Runtime.InteropServices +open FSharp.NativeInterop +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Infos +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics + +#nowarn "9" +#nowarn "51" + +/// These tags are used to create unique item key strings to decrease possible key string collisions when the Items are actually completely different. +[] +module ItemKeyTags = + + [] + let entityRef = "#E#" + + [] + let typeTuple = "#T#" + + [] + let typeAnonymousRecord = "#N#" + + [] + let typeFunction = "#F#" + + [] + let typeMeasure = "#M#" + + [] + let typeUnionCase = "#U#" + + [] + let typeMeasureVar = "#p#" + + [] + let typeMeasureCon = "#c#" + + [] + let itemValueMember = "m$" + + [] + let itemValue = "v$" + + [] + let itemUnionCase = "u$" + + [] + let itemActivePattern = "r$" + + [] + let itemExnCase = "e$" + + [] + let itemRecordField = "d$" + + [] + let itemAnonymousRecordField = "a$" + + [] + let itemNewDef = "n$" + + [] + let itemILField = "l$" + + [] + let itemEvent = "t$" + + [] + let itemProperty = "p$" + + [] + let itemTypeVar = "y$" + + [] + let itemModuleOrNamespace = "o$" + + [] + let itemDelegateCtor = "g$" + + [] + let parameters = "p$p$" + +[] +type ItemKeyStore(mmf: MemoryMappedFile, length) = + + let rangeBuffer = Array.zeroCreate sizeof + + let mutable isDisposed = false + let checkDispose() = + if isDisposed then + raise (ObjectDisposedException("ItemKeyStore")) + + member _.ReadRange(reader: byref) = + reader.ReadBytes(sizeof, rangeBuffer, 0) + MemoryMarshal.Cast(Span(rangeBuffer)).[0] + + member _.ReadKeyString(reader: byref) = + let size = reader.ReadInt32() + let keyString = ReadOnlySpan(reader.CurrentPointer |> NativePtr.toVoidPtr, size) + reader.Offset <- reader.Offset + size + keyString + + member this.ReadFirstKeyString() = + use view = mmf.CreateViewAccessor(0L, length) + let mutable reader = BlobReader(view.SafeMemoryMappedViewHandle.DangerousGetHandle() |> NativePtr.ofNativeInt, int length) + this.ReadRange &reader |> ignore + let bytes = (this.ReadKeyString &reader).ToArray() + ReadOnlySpan.op_Implicit bytes + + member this.FindAll(item: Item) = + checkDispose () + + let builder = ItemKeyStoreBuilder() + builder.Write(range0, item) + match builder.TryBuildAndReset() with + | None -> Seq.empty + | Some(singleStore : ItemKeyStore) -> + let keyString1 = singleStore.ReadFirstKeyString() + (singleStore :> IDisposable).Dispose() + + let results = ResizeArray() + + use view = mmf.CreateViewAccessor(0L, length) + let mutable reader = BlobReader(view.SafeMemoryMappedViewHandle.DangerousGetHandle() |> NativePtr.ofNativeInt, int length) + + reader.Offset <- 0 + while reader.Offset < reader.Length do + let m = this.ReadRange &reader + let keyString2 = this.ReadKeyString &reader + if keyString1.SequenceEqual keyString2 then + results.Add m + + results :> range seq + + interface IDisposable with + + member _.Dispose() = + isDisposed <- true + mmf.Dispose() + +and [] ItemKeyStoreBuilder() = + + let b = BlobBuilder() + + let writeChar (c: char) = + b.WriteUInt16(uint16 c) + + let writeUInt16 (i: uint16) = + b.WriteUInt16 i + + let writeInt32 (i: int) = + b.WriteInt32 i + + let writeInt64 (i: int64) = + b.WriteInt64 i + + let writeString (str: string) = + b.WriteUTF16 str + + let writeRange (m: range) = + let mutable m = m + let ptr = &&m |> NativePtr.toNativeInt |> NativePtr.ofNativeInt + b.WriteBytes(ptr, sizeof) + + let writeEntityRef (eref: EntityRef) = + writeString ItemKeyTags.entityRef + writeString eref.CompiledName + eref.CompilationPath.MangledPath + |> List.iter (fun str -> writeString str) + + let rec writeILType (ilty: ILType) = + match ilty with + | ILType.TypeVar n -> writeString "!"; writeUInt16 n + | ILType.Modified (_, _, ty2) -> writeILType ty2 + | ILType.Array (ILArrayShape s, ty) -> + writeILType ty + writeString "[" + writeInt32 (s.Length-1) + writeString "]" + | ILType.Value tr + | ILType.Boxed tr -> + tr.TypeRef.Enclosing + |> List.iter (fun x -> + writeString x + writeChar '.') + writeChar '.' + writeString tr.TypeRef.Name + | ILType.Void -> + writeString "void" + | ILType.Ptr ty -> + writeString "ptr<" + writeILType ty + writeChar '>' + | ILType.Byref ty -> + writeString "byref<" + writeILType ty + writeChar '>' + | ILType.FunctionPointer mref -> + mref.ArgTypes + |> List.iter (fun x -> + writeILType x) + writeILType mref.ReturnType + + let rec writeType isStandalone (ty: TType) = + match stripTyparEqns ty with + | TType_forall (_, ty) -> + writeType false ty + | TType_app (tcref, _) -> + writeEntityRef tcref + | TType_tuple (_, tinst) -> + writeString ItemKeyTags.typeTuple + tinst |> List.iter (writeType false) + | TType_anon (anonInfo, tinst) -> + writeString ItemKeyTags.typeAnonymousRecord + writeString anonInfo.ILTypeRef.BasicQualifiedName + tinst |> List.iter (writeType false) + | TType_fun (d, r) -> + writeString ItemKeyTags.typeFunction + writeType false d + writeType false r + | TType_measure ms -> + if isStandalone then + writeString ItemKeyTags.typeMeasure + writeMeasure isStandalone ms + | TType_var tp -> + writeTypar isStandalone tp + | TType_ucase (uc, _) -> + match uc with + | UnionCaseRef.UnionCaseRef(tcref, nm) -> + writeString ItemKeyTags.typeUnionCase + writeEntityRef tcref + writeString nm + + and writeMeasure isStandalone (ms: Measure) = + match ms with + | Measure.Var typar -> + writeString ItemKeyTags.typeMeasureVar + writeTypar isStandalone typar + | Measure.Con tcref -> + writeString ItemKeyTags.typeMeasureCon + writeEntityRef tcref + | _ -> + () + + and writeTypar (isStandalone: bool) (typar: Typar) = + match typar.Solution with + | Some ty -> writeType isStandalone ty + | _ -> + if isStandalone then + writeInt64 typar.Stamp + + let writeValRef (vref: ValRef) = + match vref.MemberInfo with + | Some memberInfo -> + writeString ItemKeyTags.itemValueMember + writeEntityRef memberInfo.ApparentEnclosingEntity + writeString vref.LogicalName + writeString ItemKeyTags.parameters + writeType false vref.Type + | _ -> + writeString ItemKeyTags.itemValue + writeString vref.LogicalName + writeString ItemKeyTags.parameters + writeType false vref.Type + match vref.DeclaringEntity with + | ParentNone -> writeChar '%' + | Parent eref -> writeEntityRef eref + + member _.Write (m: range, item: Item) = + writeRange m + + let fixup = b.ReserveBytes 4 |> BlobWriter + + let preCount = b.Count + + match item with + | Item.Value vref -> + if vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then + writeString ItemKeyTags.itemProperty + writeString vref.PropertyName + match vref.DeclaringEntity with + | ParentRef.Parent parent -> + writeEntityRef parent + | _ -> + () + else + writeValRef vref + + | Item.UnionCase(info, _) -> + writeString ItemKeyTags.typeUnionCase + writeEntityRef info.TyconRef + writeString info.LogicalName + + | Item.ActivePatternResult(info, _, _, _) -> + writeString ItemKeyTags.itemActivePattern + info.ActiveTags + |> List.iter writeString + + | Item.ActivePatternCase elemRef -> + writeString ItemKeyTags.itemActivePattern + elemRef.ActivePatternInfo.ActiveTags + |> List.iter writeString + + | Item.ExnCase tcref -> + writeString ItemKeyTags.itemExnCase + writeEntityRef tcref + + | Item.RecdField info -> + writeString ItemKeyTags.itemRecordField + writeEntityRef info.TyconRef + writeString info.LogicalName + writeType false info.FieldType + + | Item.UnionCaseField(info, fieldIndex) -> + writeString ItemKeyTags.typeUnionCase + writeEntityRef info.TyconRef + writeString info.LogicalName + writeInt32 fieldIndex + + | Item.AnonRecdField(info, tys, i, _) -> + writeString ItemKeyTags.itemAnonymousRecordField + writeString info.ILTypeRef.BasicQualifiedName + tys |> List.iter (writeType false) + writeInt32 i + + | Item.NewDef ident -> + writeString ItemKeyTags.itemNewDef + writeString ident.idText + + | Item.ILField info -> + writeString ItemKeyTags.itemILField + writeString info.ILTypeRef.BasicQualifiedName + writeString info.FieldName + + | Item.Event info -> + writeString ItemKeyTags.itemEvent + writeString info.EventName + writeEntityRef info.DeclaringTyconRef + + | Item.Property(nm, infos) -> + writeString ItemKeyTags.itemProperty + writeString nm + match infos |> List.tryHead with + | Some info -> + writeEntityRef info.DeclaringTyconRef + | _ -> + () + + | Item.TypeVar(_, typar) -> + writeTypar true typar + + | Item.Types(_, [ty]) -> + writeType true ty + + | Item.UnqualifiedType [tcref] -> + writeEntityRef tcref + + | Item.MethodGroup(_, [info], _) + | Item.CtorGroup(_, [info]) -> + match info with + | FSMeth(_, _, vref, _) -> + writeValRef vref + | ILMeth(_, info, _) -> + info.ILMethodRef.ArgTypes + |> List.iter writeILType + writeILType info.ILMethodRef.ReturnType + writeString info.ILName + writeType false info.ApparentEnclosingType + | _ -> + writeString ItemKeyTags.itemValueMember + writeEntityRef info.DeclaringTyconRef + writeString info.LogicalName + + | Item.ModuleOrNamespaces [x] -> + writeString ItemKeyTags.itemModuleOrNamespace + x.CompilationPath.DemangledPath + |> List.iter (fun x -> + writeString x + writeString ".") + writeString x.LogicalName + + | Item.DelegateCtor ty -> + writeString ItemKeyTags.itemDelegateCtor + writeType false ty + + | Item.MethodGroup _ -> () + | Item.CtorGroup _ -> () + | Item.FakeInterfaceCtor _ -> () + | Item.Types _ -> () + | Item.CustomOperation _ -> () + | Item.CustomBuilder _ -> () + | Item.ModuleOrNamespaces _ -> () + | Item.ImplicitOp _ -> () + | Item.ArgName _ -> () + | Item.SetterArg _ -> () + | Item.UnqualifiedType _ -> () + + let postCount = b.Count + + fixup.WriteInt32(postCount - preCount) + + member _.TryBuildAndReset() = + if b.Count > 0 then + let length = int64 b.Count + let mmf = + let mmf = + MemoryMappedFile.CreateNew( + null, + length, + MemoryMappedFileAccess.ReadWrite, + MemoryMappedFileOptions.None, + HandleInheritability.None) + use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite) + b.WriteContentTo stream + mmf + + b.Clear() + + Some(new ItemKeyStore(mmf, length)) + else + b.Clear() + None diff --git a/src/fsharp/service/ItemKey.fsi b/src/fsharp/service/ItemKey.fsi new file mode 100644 index 00000000000..fa82eddf0a1 --- /dev/null +++ b/src/fsharp/service/ItemKey.fsi @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.CodeAnalysis + +open System +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Text + +/// Stores a list of item key strings and their ranges in a memory mapped file. +[] +type internal ItemKeyStore = + interface IDisposable + + member FindAll: Item -> seq + +/// A builder that will build an item key store based on the written Item and its associated range. +[] +type internal ItemKeyStoreBuilder = + + new: unit -> ItemKeyStoreBuilder + + member Write: range * Item -> unit + + member TryBuildAndReset: unit -> ItemKeyStore option \ No newline at end of file diff --git a/src/fsharp/service/QuickParse.fs b/src/fsharp/service/QuickParse.fs index 434a0312da1..d01772621c0 100644 --- a/src/fsharp/service/QuickParse.fs +++ b/src/fsharp/service/QuickParse.fs @@ -1,14 +1,16 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler +namespace FSharp.Compiler.EditorServices open System -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.SourceCodeServices +open Internal.Utilities.Library +open FSharp.Compiler.Syntax +open FSharp.Compiler.Tokenization /// Qualified long name. type PartialLongName = - { /// Qualifying idents, prior to the last dot, not including the last part. + { + /// Qualifying idents, prior to the last dot, not including the last part. QualifyingIdents: string list /// Last part of long ident. @@ -18,7 +20,8 @@ type PartialLongName = EndColumn: int /// Position of the last dot. - LastDotPos: int option } + LastDotPos: int option + } /// Empty partial long name. static member Empty(endColumn: int) = { QualifyingIdents = []; PartialIdent = ""; EndColumn = endColumn; LastDotPos = None } @@ -51,7 +54,7 @@ module QuickParse = FSharp.Compiler.Parser.tagOfToken (FSharp.Compiler.Parser.token.IDENT tokenText) else tokenTag - let rec isValidStrippedName (name:string) idx = + let rec isValidStrippedName (name: ReadOnlySpan) idx = if idx = name.Length then false elif IsIdentifierPartCharacter name.[idx] then true else isValidStrippedName name (idx + 1) @@ -64,8 +67,8 @@ module QuickParse = // Strip the surrounding bars (e.g. from "|xyz|_|") to get "xyz" match name.StartsWithOrdinal("|"), name.EndsWithOrdinal("|_|"), name.EndsWithOrdinal("|") with - | true, true, _ when name.Length > 4 -> isValidStrippedName (name.Substring(1, name.Length - 4)) 0 - | true, _, true when name.Length > 2 -> isValidStrippedName (name.Substring(1, name.Length - 2)) 0 + | true, true, _ when name.Length > 4 -> isValidStrippedName (name.AsSpan(1, name.Length - 4)) 0 + | true, _, true when name.Length > 2 -> isValidStrippedName (name.AsSpan(1, name.Length - 2)) 0 | _ -> false let GetCompleteIdentifierIslandImpl (lineStr: string) (index: int) : (string * int * bool) option = @@ -164,12 +167,12 @@ module QuickParse = /// a call to `DeclItemsForNamesAtPosition` for intellisense. This will /// allow us to use find the correct qualified items rather than resorting /// to the more expensive and less accurate environment lookup. - let GetCompleteIdentifierIsland (tolerateJustAfter: bool) (lineStr: string) (index: int) : (string * int * bool) option = - if String.IsNullOrEmpty lineStr then None + let GetCompleteIdentifierIsland (tolerateJustAfter: bool) (tokenText: string) (index: int) : (string * int * bool) option = + if String.IsNullOrEmpty tokenText then None else - let directResult = GetCompleteIdentifierIslandImpl lineStr index + let directResult = GetCompleteIdentifierIslandImpl tokenText index if tolerateJustAfter && directResult = None then - GetCompleteIdentifierIslandImpl lineStr (index - 1) + GetCompleteIdentifierIslandImpl tokenText (index - 1) else directResult diff --git a/src/fsharp/service/QuickParse.fsi b/src/fsharp/service/QuickParse.fsi index 3c2adfd0df8..b4b27fc64bb 100644 --- a/src/fsharp/service/QuickParse.fsi +++ b/src/fsharp/service/QuickParse.fsi @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler +namespace FSharp.Compiler.EditorServices -open System -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Tokenization /// Qualified long name. type public PartialLongName = - { /// Qualifying idents, prior to the last dot, not including the last part. + { + /// Qualifying idents, prior to the last dot, not including the last part. QualifyingIdents: string list /// Last part of long ident. @@ -17,7 +17,8 @@ type public PartialLongName = EndColumn: int /// Position of the last dot. - LastDotPos: int option } + LastDotPos: int option + } /// Empty partial long name. static member Empty: endColumn: int -> PartialLongName @@ -39,6 +40,7 @@ type public PartialLongName = /// below is inaccurate for long identifier chains involving ``...`` identifiers. And there are special cases /// for active pattern names and so on. module public QuickParse = + /// Puts us after the last character. val MagicalAdjustmentConstant : int @@ -72,7 +74,7 @@ module public QuickParse = val GetCompleteIdentifierIsland : tolerateJustAfter: bool -> tokenText: string -> index: int -> (string * int * bool) option /// Get the partial long name of the identifier to the left of index. - val GetPartialLongName : lineStr: string * index: int -> (string list * string) + val GetPartialLongName : lineStr: string * index: int -> string list * string /// Get the partial long name of the identifier to the left of index. /// For example, for `System.DateTime.Now` it returns PartialLongName ([|"System"; "DateTime"|], "Now", Some 32), where "32" pos of the last dot. diff --git a/src/fsharp/service/Reactor.fs b/src/fsharp/service/Reactor.fs deleted file mode 100755 index b4c487caebf..00000000000 --- a/src/fsharp/service/Reactor.fs +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.SourceCodeServices -open System -open System.Diagnostics -open System.Globalization -open System.Threading -open Microsoft.FSharp.Control -open FSharp.Compiler.Lib -open FSharp.Compiler.AbstractIL.Internal.Library - -/// Represents the capability to schedule work in the compiler service operations queue for the compilation thread -type internal IReactorOperations = - abstract EnqueueAndAwaitOpAsync : userOpName:string * opName:string * opArg:string * (CompilationThreadToken -> Cancellable<'T>) -> Async<'T> - abstract EnqueueOp: userOpName:string * opName:string * opArg:string * (CompilationThreadToken -> unit) -> unit - -[] -type internal ReactorCommands = - /// Kick off a build. - | SetBackgroundOp of ( (* userOpName: *) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> CancellationToken -> bool)) option - /// Do some work not synchronized in the mailbox. - | Op of userOpName: string * opName: string * opArg: string * CancellationToken * (CompilationThreadToken -> unit) * (unit -> unit) - /// Finish the background building - | WaitForBackgroundOpCompletion of AsyncReplyChannel - /// Finish all the queued ops - | CompleteAllQueuedOps of AsyncReplyChannel - -[] -/// There is one global Reactor for the entire language service, no matter how many projects or files -/// are open. -type Reactor() = - static let pauseBeforeBackgroundWorkDefault = GetEnvInteger "FCS_PauseBeforeBackgroundWorkMilliseconds" 10 - static let theReactor = Reactor() - let mutable pauseBeforeBackgroundWork = pauseBeforeBackgroundWorkDefault - - // We need to store the culture for the VS thread that is executing now, - // so that when the reactor picks up a thread from the thread pool we can set the culture - let mutable culture = CultureInfo(CultureInfo.CurrentUICulture.Name) - - let mutable bgOpCts = new CancellationTokenSource() - /// Mailbox dispatch function. - let builder = - MailboxProcessor<_>.Start <| fun inbox -> - - // Async workflow which receives messages and dispatches to worker functions. - let rec loop (bgOpOpt, onComplete, bg) = - async { //Trace.TraceInformation("Reactor: receiving..., remaining {0}", inbox.CurrentQueueLength) - - // Explanation: The reactor thread acts as the compilation thread in hosted scenarios - let ctok = AssumeCompilationThreadWithoutEvidence() - - // Messages always have priority over the background op. - let! msg = - async { match bgOpOpt, onComplete with - | None, None -> - let! msg = inbox.Receive() - return Some msg - | _, Some _ -> - return! inbox.TryReceive(0) - | Some _, _ -> - let timeout = - if bg then 0 - else - Trace.TraceInformation("Reactor: {0:n3} pausing {1} milliseconds", DateTime.Now.TimeOfDay.TotalSeconds, pauseBeforeBackgroundWork) - pauseBeforeBackgroundWork - return! inbox.TryReceive(timeout) } - Thread.CurrentThread.CurrentUICulture <- culture - match msg with - | Some (SetBackgroundOp bgOpOpt) -> - //Trace.TraceInformation("Reactor: --> set background op, remaining {0}", inbox.CurrentQueueLength) - return! loop (bgOpOpt, onComplete, false) - - | Some (Op (userOpName, opName, opArg, ct, op, ccont)) -> - if ct.IsCancellationRequested then ccont() else - Trace.TraceInformation("Reactor: {0:n3} --> {1}.{2} ({3}), remaining {4}", DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, inbox.CurrentQueueLength) - let time = Stopwatch() - time.Start() - op ctok - time.Stop() - let span = time.Elapsed - //if span.TotalMilliseconds > 100.0 then - let taken = span.TotalMilliseconds - let msg = (if taken > 10000.0 then "BAD-OP: >10s " elif taken > 3000.0 then "BAD-OP: >3s " elif taken > 1000.0 then "BAD-OP: > 1s " elif taken > 500.0 then "BAD-OP: >0.5s " else "") - Trace.TraceInformation("Reactor: {0:n3} {1}<-- {2}.{3}, took {4} ms", DateTime.Now.TimeOfDay.TotalSeconds, msg, userOpName, opName, span.TotalMilliseconds) - return! loop (bgOpOpt, onComplete, false) - | Some (WaitForBackgroundOpCompletion channel) -> - match bgOpOpt with - | None -> () - | Some (bgUserOpName, bgOpName, bgOpArg, bgOp) -> - Trace.TraceInformation("Reactor: {0:n3} --> wait for background {1}.{2} ({3}), remaining {4}", DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg, inbox.CurrentQueueLength) - bgOpCts.Dispose() - bgOpCts <- new CancellationTokenSource() - while not bgOpCts.IsCancellationRequested && bgOp ctok bgOpCts.Token do - () - - if bgOpCts.IsCancellationRequested then - Trace.TraceInformation("FCS: <-- wait for background was cancelled {0}.{1}", bgUserOpName, bgOpName) - - channel.Reply(()) - return! loop (None, onComplete, false) - - | Some (CompleteAllQueuedOps channel) -> - Trace.TraceInformation("Reactor: {0:n3} --> stop background work and complete all queued ops, remaining {1}", DateTime.Now.TimeOfDay.TotalSeconds, inbox.CurrentQueueLength) - return! loop (None, Some channel, false) - - | None -> - match bgOpOpt, onComplete with - | _, Some onComplete -> onComplete.Reply() - | Some (bgUserOpName, bgOpName, bgOpArg, bgOp), None -> - Trace.TraceInformation("Reactor: {0:n3} --> background step {1}.{2} ({3})", DateTime.Now.TimeOfDay.TotalSeconds, bgUserOpName, bgOpName, bgOpArg) - let time = Stopwatch() - time.Start() - bgOpCts.Dispose() - bgOpCts <- new CancellationTokenSource() - let res = bgOp ctok bgOpCts.Token - if bgOpCts.IsCancellationRequested then - Trace.TraceInformation("FCS: <-- background step {0}.{1}, was cancelled", bgUserOpName, bgOpName) - time.Stop() - let taken = time.Elapsed.TotalMilliseconds - //if span.TotalMilliseconds > 100.0 then - let msg = (if taken > 10000.0 then "BAD-BG-SLICE: >10s " elif taken > 3000.0 then "BAD-BG-SLICE: >3s " elif taken > 1000.0 then "BAD-BG-SLICE: > 1s " else "") - Trace.TraceInformation("Reactor: {0:n3} {1}<-- background step, took {2}ms", DateTime.Now.TimeOfDay.TotalSeconds, msg, taken) - return! loop ((if res then bgOpOpt else None), onComplete, true) - | None, None -> failwith "unreachable, should have used inbox.Receive" - } - async { - while true do - try - do! loop (None, None, false) - with e -> - Debug.Assert(false, String.Format("unexpected failure in reactor loop {0}, restarting", e)) - } - - member __.SetPreferredUILang(preferredUiLang: string option) = - match preferredUiLang with - | Some s -> - culture <- CultureInfo s -#if FX_RESHAPED_GLOBALIZATION - CultureInfo.CurrentUICulture <- culture -#else - Thread.CurrentThread.CurrentUICulture <- culture -#endif - | None -> () - - // [Foreground Mailbox Accessors] ----------------------------------------------------------- - member r.SetBackgroundOp(bgOpOpt) = - Trace.TraceInformation("Reactor: {0:n3} enqueue start background, length {1}", DateTime.Now.TimeOfDay.TotalSeconds, builder.CurrentQueueLength) - bgOpCts.Cancel() - builder.Post(SetBackgroundOp bgOpOpt) - - member r.CancelBackgroundOp() = - Trace.TraceInformation("FCS: trying to cancel any active background work") - bgOpCts.Cancel() - - member r.EnqueueOp(userOpName, opName, opArg, op) = - Trace.TraceInformation("Reactor: {0:n3} enqueue {1}.{2} ({3}), length {4}", DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, builder.CurrentQueueLength) - builder.Post(Op(userOpName, opName, opArg, CancellationToken.None, op, (fun () -> ()))) - - member r.EnqueueOpPrim(userOpName, opName, opArg, ct, op, ccont) = - Trace.TraceInformation("Reactor: {0:n3} enqueue {1}.{2} ({3}), length {4}", DateTime.Now.TimeOfDay.TotalSeconds, userOpName, opName, opArg, builder.CurrentQueueLength) - builder.Post(Op(userOpName, opName, opArg, ct, op, ccont)) - - member r.CurrentQueueLength = - builder.CurrentQueueLength - - // This is for testing only - member r.WaitForBackgroundOpCompletion() = - Trace.TraceInformation("Reactor: {0:n3} enqueue wait for background, length {0}", DateTime.Now.TimeOfDay.TotalSeconds, builder.CurrentQueueLength) - builder.PostAndReply WaitForBackgroundOpCompletion - - // This is for testing only - member r.CompleteAllQueuedOps() = - Trace.TraceInformation("Reactor: {0:n3} enqueue wait for all ops, length {0}", DateTime.Now.TimeOfDay.TotalSeconds, builder.CurrentQueueLength) - builder.PostAndReply CompleteAllQueuedOps - - member r.EnqueueAndAwaitOpAsync (userOpName, opName, opArg, f) = - async { - let! ct = Async.CancellationToken - let resultCell = AsyncUtil.AsyncResultCell<_>() - r.EnqueueOpPrim(userOpName, opName, opArg, ct, - op=(fun ctok -> - let result = - try - match Cancellable.run ct (f ctok) with - | ValueOrCancelled.Value r -> AsyncUtil.AsyncOk r - | ValueOrCancelled.Cancelled e -> AsyncUtil.AsyncCanceled e - with e -> e |> AsyncUtil.AsyncException - - resultCell.RegisterResult(result)), - ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException(ct))) ) - - ) - return! resultCell.AsyncResult - } - member __.PauseBeforeBackgroundWork with get() = pauseBeforeBackgroundWork and set v = pauseBeforeBackgroundWork <- v - - static member Singleton = theReactor - diff --git a/src/fsharp/service/Reactor.fsi b/src/fsharp/service/Reactor.fsi deleted file mode 100755 index 3040ca65eee..00000000000 --- a/src/fsharp/service/Reactor.fsi +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.SourceCodeServices - -open System.Threading -open FSharp.Compiler.AbstractIL.Internal.Library - -/// Represents the capability to schedule work in the compiler service operations queue for the compilation thread -type internal IReactorOperations = - - /// Put the operation in the queue, and return an async handle to its result. - abstract EnqueueAndAwaitOpAsync : userOpName:string * opName:string * opArg:string * action: (CompilationThreadToken -> Cancellable<'T>) -> Async<'T> - - /// Enqueue an operation and return immediately. - abstract EnqueueOp: userOpName:string * opName:string * opArg:string * action: (CompilationThreadToken -> unit) -> unit - -/// Reactor is intended for long-running but interruptible operations, interleaved -/// with one-off asynchronous operations. -/// -/// It is used to guard the global compiler state while maintaining responsiveness on -/// the UI thread. -/// Reactor operations -[] -type internal Reactor = - - /// Allows to specify the language for error messages - member SetPreferredUILang : string option -> unit - - /// Set the background building function, which is called repeatedly - /// until it returns 'false'. If None then no background operation is used. - member SetBackgroundOp : ( (* userOpName:*) string * (* opName: *) string * (* opArg: *) string * (CompilationThreadToken -> CancellationToken -> bool)) option -> unit - - /// Cancel any work being don by the background building function. - member CancelBackgroundOp : unit -> unit - - /// Block until the current implicit background build is complete. Unit test only. - member WaitForBackgroundOpCompletion : unit -> unit - - /// Block until all operations in the queue are complete - member CompleteAllQueuedOps : unit -> unit - - /// Enqueue an uncancellable operation and return immediately. - member EnqueueOp : userOpName:string * opName: string * opArg: string * op:(CompilationThreadToken -> unit) -> unit - - /// For debug purposes - member CurrentQueueLength : int - - /// Put the operation in the queue, and return an async handle to its result. - member EnqueueAndAwaitOpAsync : userOpName:string * opName:string * opArg:string * (CompilationThreadToken -> Cancellable<'T>) -> Async<'T> - - /// The timespan in milliseconds before background work begins after the operations queue is empty - member PauseBeforeBackgroundWork : int with get, set - - /// Get the reactor - static member Singleton : Reactor - diff --git a/src/fsharp/service/SemanticClassification.fs b/src/fsharp/service/SemanticClassification.fs new file mode 100644 index 00000000000..917f7eda9bd --- /dev/null +++ b/src/fsharp/service/SemanticClassification.fs @@ -0,0 +1,382 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open System.Diagnostics +open System.Collections.Generic +open System.Collections.Immutable +open Internal.Utilities.Library +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Import +open FSharp.Compiler.Infos +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps + +type SemanticClassificationType = + | ReferenceType = 0 + | ValueType = 1 + | UnionCase = 2 + | UnionCaseField = 3 + | Function = 4 + | Property = 5 + | MutableVar = 6 + | Module = 7 + | Namespace = 8 + | Printf = 9 + | ComputationExpression = 10 + | IntrinsicFunction = 11 + | Enumeration = 12 + | Interface = 13 + | TypeArgument = 14 + | Operator = 15 + | DisposableType = 16 + | DisposableTopLevelValue = 17 + | DisposableLocalValue = 18 + | Method = 19 + | ExtensionMethod = 20 + | ConstructorForReferenceType = 21 + | ConstructorForValueType = 22 + | Literal = 23 + | RecordField = 24 + | MutableRecordField = 25 + | RecordFieldAsFunction = 26 + | Exception = 27 + | Field = 28 + | Event = 29 + | Delegate = 30 + | NamedArgument = 31 + | Value = 32 + | LocalValue = 33 + | Type = 34 + | TypeDef = 35 + | Plaintext = 36 + +[] +[] +type SemanticClassificationItem = + val Range: range + val Type: SemanticClassificationType + new((range, ty)) = { Range = range; Type = ty } + +[] +module TcResolutionsExtensions = + let (|CNR|) (cnr:CapturedNameResolution) = + (cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range) + + type TcResolutions with + member sResolutions.GetSemanticClassification(g: TcGlobals, amap: ImportMap, formatSpecifierLocations: (range * int) [], range: range option) : SemanticClassificationItem [] = + ErrorScope.Protect range0 (fun () -> + let (|LegitTypeOccurence|_|) = function + | ItemOccurence.UseInType + | ItemOccurence.UseInAttribute + | ItemOccurence.Use _ + | ItemOccurence.Binding _ + | ItemOccurence.Pattern _ + | ItemOccurence.Open -> Some() + | _ -> None + + let (|KeywordIntrinsicValue|_|) (vref: ValRef) = + if valRefEq g g.raise_vref vref || + valRefEq g g.reraise_vref vref || + valRefEq g g.typeof_vref vref || + valRefEq g g.typedefof_vref vref || + valRefEq g g.sizeof_vref vref || + valRefEq g g.nameof_vref vref then Some() + else None + + let (|EnumCaseFieldInfo|_|) (rfinfo : RecdFieldInfo) = + match rfinfo.TyconRef.TypeReprInfo with + | TFSharpObjectRepr x -> + match x.fsobjmodel_kind with + | TFSharpEnum -> Some () + | _ -> None + | _ -> None + + // Custome builders like 'async { }' are both Item.Value and Item.CustomBuilder. + // We should prefer the latter, otherwise they would not get classified as CEs. + let takeCustomBuilder (cnrs: CapturedNameResolution[]) = + assert (cnrs.Length > 0) + if cnrs.Length = 1 then + cnrs + elif cnrs.Length = 2 then + match cnrs.[0].Item, cnrs.[1].Item with + | Item.Value _, Item.CustomBuilder _ -> + [| cnrs.[1] |] + | Item.CustomBuilder _, Item.Value _ -> + [| cnrs.[0] |] + | _ -> + cnrs + else + cnrs + + let resolutions = + match range with + | Some range -> + sResolutions.CapturedNameResolutions.ToArray() + |> Array.filter (fun cnr -> rangeContainsPos range cnr.Range.Start || rangeContainsPos range cnr.Range.End) + |> Array.groupBy (fun cnr -> cnr.Range) + |> Array.map (fun (_, cnrs) -> takeCustomBuilder cnrs) + |> Array.concat + | None -> + sResolutions.CapturedNameResolutions.ToArray() + + let isDisposableTy (ty: TType) = + not (typeEquiv g ty g.system_IDisposable_ty) && + protectAssemblyExplorationNoReraise false false (fun () -> ExistsHeadTypeInEntireHierarchy g amap range0 ty g.tcref_System_IDisposable) + + let isDiscard (str: string) = str.StartsWith("_") + + let isValRefDisposable (vref: ValRef) = + not (isDiscard vref.DisplayName) && + // For values, we actually do want to color things if they literally are IDisposables + protectAssemblyExplorationNoReraise false false (fun () -> ExistsHeadTypeInEntireHierarchy g amap range0 vref.Type g.tcref_System_IDisposable) + + let isStructTyconRef (tyconRef: TyconRef) = + let ty = generalizedTyconRef tyconRef + let underlyingTy = stripTyEqnsAndMeasureEqns g ty + isStructTy g underlyingTy + + let isValRefMutable (vref: ValRef) = + // Mutable values, ref cells, and non-inref byrefs are mutable. + vref.IsMutable + || isRefCellTy g vref.Type + || (isByrefTy g vref.Type && not (isInByrefTy g vref.Type)) + + let isRecdFieldMutable (rfinfo: RecdFieldInfo) = + (rfinfo.RecdField.IsMutable && rfinfo.LiteralValue.IsNone) + || isRefCellTy g rfinfo.RecdField.FormalType + + let duplicates = HashSet(comparer) + + let results = ImmutableArray.CreateBuilder() + let inline add m (typ: SemanticClassificationType) = + if duplicates.Add m then + results.Add (SemanticClassificationItem((m, typ))) + + resolutions + |> Array.iter (fun cnr -> + match cnr.Item, cnr.ItemOccurence, cnr.DisplayEnv, cnr.NameResolutionEnv, cnr.AccessorDomain, cnr.Range with + | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use, _, _, _, m -> + add m SemanticClassificationType.ComputationExpression + + | Item.Value vref, _, _, _, _, m when isValRefMutable vref -> + add m SemanticClassificationType.MutableVar + + | Item.Value KeywordIntrinsicValue, ItemOccurence.Use, _, _, _, m -> + add m SemanticClassificationType.IntrinsicFunction + + | Item.Value vref, _, _, _, _, m when isForallFunctionTy g vref.Type -> + if isDiscard vref.DisplayName then + add m SemanticClassificationType.Plaintext + elif valRefEq g g.range_op_vref vref || valRefEq g g.range_step_op_vref vref then + add m SemanticClassificationType.Operator + elif vref.IsPropertyGetterMethod || vref.IsPropertySetterMethod then + add m SemanticClassificationType.Property + elif vref.IsMember then + add m SemanticClassificationType.Method + elif IsOperatorDisplayName vref.DisplayName then + add m SemanticClassificationType.Operator + else + add m SemanticClassificationType.Function + + | Item.Value vref, _, _, _, _, m -> + if isValRefDisposable vref then + if vref.IsCompiledAsTopLevel then + add m SemanticClassificationType.DisposableTopLevelValue + else + add m SemanticClassificationType.DisposableLocalValue + elif Option.isSome vref.LiteralValue then + add m SemanticClassificationType.Literal + elif not vref.IsCompiledAsTopLevel && not(isDiscard vref.DisplayName) then + add m SemanticClassificationType.LocalValue + else + add m SemanticClassificationType.Value + + | Item.RecdField rfinfo, _, _, _, _, m -> + match rfinfo with + | EnumCaseFieldInfo -> + add m SemanticClassificationType.Enumeration + | _ -> + if isRecdFieldMutable rfinfo then + add m SemanticClassificationType.MutableRecordField + elif isFunTy g rfinfo.FieldType then + add m SemanticClassificationType.RecordFieldAsFunction + else + add m SemanticClassificationType.RecordField + + | Item.AnonRecdField(_, tys, idx, m), _, _, _, _, _ -> + let ty = tys.[idx] + + // It's not currently possible for anon record fields to be mutable, but they can be ref cells + if isRefCellTy g ty then + add m SemanticClassificationType.MutableRecordField + elif isFunTy g ty then + add m SemanticClassificationType.RecordFieldAsFunction + else + add m SemanticClassificationType.RecordField + + | Item.Property (_, pinfo :: _), _, _, _, _, m -> + if not pinfo.IsIndexer then + add m SemanticClassificationType.Property + + | Item.CtorGroup (_, minfos), _, _, _, _, m -> + match minfos with + | [] -> + add m SemanticClassificationType.ConstructorForReferenceType + | _ -> + if minfos |> List.forall (fun minfo -> isDisposableTy minfo.ApparentEnclosingType) then + add m SemanticClassificationType.DisposableType + elif minfos |> List.forall (fun minfo -> isStructTy g minfo.ApparentEnclosingType) then + add m SemanticClassificationType.ConstructorForValueType + else + add m SemanticClassificationType.ConstructorForReferenceType + + | (Item.DelegateCtor _ | Item.FakeInterfaceCtor _), _, _, _, _, m -> + add m SemanticClassificationType.ConstructorForReferenceType + + | Item.MethodGroup (_, minfos, _), _, _, _, _, m -> + match minfos with + | [] -> + add m SemanticClassificationType.Method + | _ -> + if minfos |> List.forall (fun minfo -> minfo.IsExtensionMember || minfo.IsCSharpStyleExtensionMember) then + add m SemanticClassificationType.ExtensionMethod + else + add m SemanticClassificationType.Method + + // Special case measures for struct types + | Item.Types(_, TType_app(tyconRef, TType_measure _ :: _) :: _), LegitTypeOccurence, _, _, _, m when isStructTyconRef tyconRef -> + add m SemanticClassificationType.ValueType + + | Item.Types (_, ty :: _), LegitTypeOccurence, _, _, _, m -> + let reprToClassificationType repr tcref = + match repr with + | TFSharpObjectRepr om -> + match om.fsobjmodel_kind with + | TFSharpClass -> SemanticClassificationType.ReferenceType + | TFSharpInterface -> SemanticClassificationType.Interface + | TFSharpStruct -> SemanticClassificationType.ValueType + | TFSharpDelegate _ -> SemanticClassificationType.Delegate + | TFSharpEnum _ -> SemanticClassificationType.Enumeration + | TFSharpRecdRepr _ + | TFSharpUnionRepr _ -> + if isStructTyconRef tcref then + SemanticClassificationType.ValueType + else + SemanticClassificationType.Type + | TILObjectRepr (TILObjectReprData (_, _, td)) -> + if td.IsClass then + SemanticClassificationType.ReferenceType + elif td.IsStruct then + SemanticClassificationType.ValueType + elif td.IsInterface then + SemanticClassificationType.Interface + elif td.IsEnum then + SemanticClassificationType.Enumeration + else + SemanticClassificationType.Delegate + | TAsmRepr _ -> SemanticClassificationType.TypeDef + | TMeasureableRepr _-> SemanticClassificationType.TypeDef +#if !NO_EXTENSIONTYPING + | TProvidedTypeRepr _-> SemanticClassificationType.TypeDef + | TProvidedNamespaceRepr _-> SemanticClassificationType.TypeDef +#endif + | TNoRepr -> SemanticClassificationType.ReferenceType + + let ty = stripTyEqns g ty + if isDisposableTy ty then + add m SemanticClassificationType.DisposableType + else + match tryTcrefOfAppTy g ty with + | ValueSome tcref -> + add m (reprToClassificationType tcref.TypeReprInfo tcref) + | ValueNone -> + if isStructTupleTy g ty then + add m SemanticClassificationType.ValueType + elif isRefTupleTy g ty then + add m SemanticClassificationType.ReferenceType + elif isForallFunctionTy g ty then + add m SemanticClassificationType.Function + elif isTyparTy g ty then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.TypeDef + + | Item.TypeVar _, LegitTypeOccurence, _, _, _, m -> + add m SemanticClassificationType.TypeArgument + + | Item.ExnCase _, LegitTypeOccurence, _, _, _, m -> + add m SemanticClassificationType.Exception + + | Item.ModuleOrNamespaces (modref :: _), LegitTypeOccurence, _, _, _, m -> + if modref.IsNamespace then + add m SemanticClassificationType.Namespace + else + add m SemanticClassificationType.Module + + | (Item.ActivePatternCase _ | Item.UnionCase _ | Item.ActivePatternResult _), _, _, _, _, m -> + add m SemanticClassificationType.UnionCase + + | Item.UnionCaseField _, _, _, _, _, m -> + add m SemanticClassificationType.UnionCaseField + + | Item.ILField _, _, _, _, _, m -> + add m SemanticClassificationType.Field + + | Item.Event _, _, _, _, _, m -> + add m SemanticClassificationType.Event + + | (Item.ArgName _ | Item.SetterArg _), _, _, _, _, m -> + add m SemanticClassificationType.NamedArgument + + | Item.SetterArg _, _, _, _, _, m -> + add m SemanticClassificationType.Property + + | Item.UnqualifiedType (tcref :: _), LegitTypeOccurence, _, _, _, m -> + if tcref.IsEnumTycon || tcref.IsILEnumTycon then + add m SemanticClassificationType.Enumeration + elif tcref.IsExceptionDecl then + add m SemanticClassificationType.Exception + elif tcref.IsFSharpDelegateTycon then + add m SemanticClassificationType.Delegate + elif tcref.IsFSharpInterfaceTycon then + add m SemanticClassificationType.Interface + elif tcref.IsFSharpStructOrEnumTycon then + add m SemanticClassificationType.ValueType + elif tcref.IsModule then + add m SemanticClassificationType.Module + elif tcref.IsNamespace then + add m SemanticClassificationType.Namespace + elif tcref.IsUnionTycon || tcref.IsRecordTycon then + if isStructTyconRef tcref then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.UnionCase + elif tcref.IsILTycon then + let (TILObjectReprData (_, _, tydef)) = tcref.ILTyconInfo + + if tydef.IsInterface then + add m SemanticClassificationType.Interface + elif tydef.IsDelegate then + add m SemanticClassificationType.Delegate + elif tydef.IsEnum then + add m SemanticClassificationType.Enumeration + elif tydef.IsStruct then + add m SemanticClassificationType.ValueType + else + add m SemanticClassificationType.ReferenceType + + | _, _, _, _, _, m -> + add m SemanticClassificationType.Plaintext) + results.AddRange(formatSpecifierLocations |> Array.map (fun (m, _) -> SemanticClassificationItem((m, SemanticClassificationType.Printf)))) + results.ToArray() + ) + (fun msg -> + Trace.TraceInformation(sprintf "FCS: recovering from error in GetSemanticClassification: '%s'" msg) + Array.empty) \ No newline at end of file diff --git a/src/fsharp/service/SemanticClassification.fsi b/src/fsharp/service/SemanticClassification.fsi new file mode 100644 index 00000000000..a22c73f3b02 --- /dev/null +++ b/src/fsharp/service/SemanticClassification.fsi @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Import +open FSharp.Compiler.NameResolution +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTreeOps + +/// A kind that determines what range in a source's text is semantically classified as after type-checking. +type SemanticClassificationType = + | ReferenceType = 0 + | ValueType = 1 + | UnionCase = 2 + | UnionCaseField = 3 + | Function = 4 + | Property = 5 + | MutableVar = 6 + | Module = 7 + | Namespace = 8 + | Printf = 9 + | ComputationExpression = 10 + | IntrinsicFunction = 11 + | Enumeration = 12 + | Interface = 13 + | TypeArgument = 14 + | Operator = 15 + | DisposableType = 16 + | DisposableTopLevelValue = 17 + | DisposableLocalValue = 18 + | Method = 19 + | ExtensionMethod = 20 + | ConstructorForReferenceType = 21 + | ConstructorForValueType = 22 + | Literal = 23 + | RecordField = 24 + | MutableRecordField = 25 + | RecordFieldAsFunction = 26 + | Exception = 27 + | Field = 28 + | Event = 29 + | Delegate = 30 + | NamedArgument = 31 + | Value = 32 + | LocalValue = 33 + | Type = 34 + | TypeDef = 35 + | Plaintext = 36 + +[] +[] +type SemanticClassificationItem = + val Range: range + val Type: SemanticClassificationType + new: (range * SemanticClassificationType) -> SemanticClassificationItem + +/// Extension methods for the TcResolutions type. +[] +module internal TcResolutionsExtensions = + val (|CNR|) : cnr: CapturedNameResolution -> Item * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range + + type TcResolutions with + member GetSemanticClassification: g: TcGlobals * amap: ImportMap * formatSpecifierLocations: (range * int) [] * range: range option -> SemanticClassificationItem [] \ No newline at end of file diff --git a/src/fsharp/service/SemanticClassificationKey.fs b/src/fsharp/service/SemanticClassificationKey.fs new file mode 100644 index 00000000000..153c33a5e7a --- /dev/null +++ b/src/fsharp/service/SemanticClassificationKey.fs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open System +open System.IO +open System.IO.MemoryMappedFiles +open System.Reflection.Metadata +open System.Runtime.InteropServices +open FSharp.NativeInterop + +#nowarn "9" + +[] +type SemanticClassificationView(mmf: MemoryMappedFile, length) = + + let buffer = Array.zeroCreate sizeof + + member _.ReadItem(reader: byref) = + reader.ReadBytes(sizeof, buffer, 0) + MemoryMarshal.Cast(Span(buffer)).[0] + + member this.ForEach(f: SemanticClassificationItem -> unit) = + use view = mmf.CreateViewAccessor(0L, length) + let mutable reader = BlobReader(view.SafeMemoryMappedViewHandle.DangerousGetHandle() |> NativePtr.ofNativeInt, int length) + + reader.Offset <- 0 + while reader.Offset < reader.Length do + let item = this.ReadItem(&reader) + f item + +[] +type SemanticClassificationKeyStore(mmf: MemoryMappedFile, length) = + let mutable isDisposed = false + let checkDispose() = + if isDisposed then + raise (ObjectDisposedException("SemanticClassificationKeyStore")) + + member _.GetView() = + checkDispose() + SemanticClassificationView(mmf, length) + + interface IDisposable with + + member _.Dispose() = + isDisposed <- true + mmf.Dispose() + +[] +type SemanticClassificationKeyStoreBuilder() = + + let b = BlobBuilder() + + member _.WriteAll (semanticClassification: SemanticClassificationItem[]) = + use ptr = fixed semanticClassification + b.WriteBytes(NativePtr.ofNativeInt (NativePtr.toNativeInt ptr), semanticClassification.Length * sizeof) + + member _.TryBuildAndReset() = + if b.Count > 0 then + let length = int64 b.Count + let mmf = + let mmf = + MemoryMappedFile.CreateNew( + null, + length, + MemoryMappedFileAccess.ReadWrite, + MemoryMappedFileOptions.None, + HandleInheritability.None) + use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite) + b.WriteContentTo stream + mmf + + b.Clear() + + Some(new SemanticClassificationKeyStore(mmf, length)) + else + b.Clear() + None diff --git a/src/fsharp/service/SemanticClassificationKey.fsi b/src/fsharp/service/SemanticClassificationKey.fsi new file mode 100644 index 00000000000..14e5e46c6d5 --- /dev/null +++ b/src/fsharp/service/SemanticClassificationKey.fsi @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open System + +/// Provides a read only view to iterate over the semantic classification contents. +[] +type SemanticClassificationView = + + /// Iterate through the stored SemanticClassificationItem entries from the store and apply the passed function on each entry. + member ForEach: (SemanticClassificationItem -> unit) -> unit + +/// Stores a list of semantic classification key strings and their ranges in a memory mapped file. +/// Provides a view to iterate over the contents of the file. +[] +type internal SemanticClassificationKeyStore = + interface IDisposable + + /// Get a read only view on the semantic classification key store + member GetView: unit -> SemanticClassificationView + + +/// A builder that will build an semantic classification key store based on the written Item and its associated range. +[] +type internal SemanticClassificationKeyStoreBuilder = + + new: unit -> SemanticClassificationKeyStoreBuilder + + member WriteAll: SemanticClassificationItem[] -> unit + + member TryBuildAndReset: unit -> SemanticClassificationKeyStore option diff --git a/src/fsharp/service/ServiceAnalysis.fs b/src/fsharp/service/ServiceAnalysis.fs index e568767a1e8..92753daa477 100644 --- a/src/fsharp/service/ServiceAnalysis.fs +++ b/src/fsharp/service/ServiceAnalysis.fs @@ -1,13 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.PrettyNaming open System.Collections.Generic open System.Runtime.CompilerServices -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range module UnusedOpens = @@ -27,16 +29,16 @@ module UnusedOpens = for rf in ent.FSharpFields do yield rf :> FSharpSymbol - if ent.IsFSharpUnion && not (Symbol.hasAttribute ent.Attributes) then + if ent.IsFSharpUnion && not (ent.HasAttribute()) then for unionCase in ent.UnionCases do yield unionCase :> FSharpSymbol - if Symbol.hasAttribute ent.Attributes then + if ent.HasAttribute() then for fv in ent.MembersFunctionsAndValues do // fv.IsExtensionMember is always false for C# extension methods returning by `MembersFunctionsAndValues`, // so we have to check Extension attribute instead. // (note: fv.IsExtensionMember has proper value for symbols returning by GetAllUsesOfAllSymbolsInFile though) - if Symbol.hasAttribute fv.Attributes then + if fv.HasAttribute() then yield fv :> FSharpSymbol for apCase in entity.ActivePatternCases do @@ -49,24 +51,25 @@ module UnusedOpens = HashSet<_>(symbols, symbolHash) - member __.Entity = entity - member __.IsNestedAutoOpen = isNestedAutoOpen - member __.RevealedSymbolsContains(symbol) = revealedSymbols.Force().Contains symbol + member _.Entity = entity + member _.IsNestedAutoOpen = isNestedAutoOpen + member _.RevealedSymbolsContains(symbol) = revealedSymbols.Force().Contains symbol type OpenedModuleGroup = - { OpenedModules: OpenedModule list } + { OpenedModules: OpenedModule [] } static member Create (modul: FSharpEntity) = let rec getModuleAndItsAutoOpens (isNestedAutoOpen: bool) (modul: FSharpEntity) = - [ yield OpenedModule (modul, isNestedAutoOpen) - for ent in modul.NestedEntities do - if ent.IsFSharpModule && Symbol.hasAttribute ent.Attributes then - yield! getModuleAndItsAutoOpens true ent ] + [| + yield OpenedModule (modul, isNestedAutoOpen) + for ent in modul.NestedEntities do + if ent.IsFSharpModule && ent.HasAttribute() then + yield! getModuleAndItsAutoOpens true ent |] { OpenedModules = getModuleAndItsAutoOpens false modul } - /// Represents single open statement. + /// Represents a single open statement type OpenStatement = - { /// All namespaces and modules which this open declaration effectively opens, including the AutoOpen ones + { /// All namespaces, modules and types which this open declaration effectively opens, including the AutoOpen ones OpenedGroups: OpenedModuleGroup list /// The range of open statement itself @@ -78,56 +81,63 @@ module UnusedOpens = /// Gets the open statements, their scopes and their resolutions let getOpenStatements (openDeclarations: FSharpOpenDeclaration[]) : OpenStatement[] = openDeclarations - |> Array.filter (fun x -> not x.IsOwnNamespace) |> Array.choose (fun openDecl -> - match openDecl.LongId, openDecl.Range with - | firstId :: _, Some range -> - if firstId.idText = MangledGlobalName then - None - else - Some { OpenedGroups = openDecl.Modules |> List.map OpenedModuleGroup.Create - Range = range - AppliedScope = openDecl.AppliedScope } - | _ -> None) + if openDecl.IsOwnNamespace then + None + else + match openDecl.LongId, openDecl.Range with + | firstId :: _, Some range -> + if firstId.idText = MangledGlobalName then + None + else + let openedModulesAndTypes = List.concat [openDecl.Modules; openDecl.Types |> List.map(fun ty -> ty.TypeDefinition)] + Some { OpenedGroups = openedModulesAndTypes |> List.map OpenedModuleGroup.Create + Range = range + AppliedScope = openDecl.AppliedScope } + | _ -> None) /// Only consider symbol uses which are the first part of a long ident, i.e. with no qualifying identifiers - let filterSymbolUses (getSourceLineStr: int -> string) (symbolUses: FSharpSymbolUse[]) : FSharpSymbolUse[] = + let filterSymbolUses (getSourceLineStr: int -> string) (symbolUses: seq) = symbolUses - |> Array.filter (fun su -> - match su.Symbol with - | :? FSharpMemberOrFunctionOrValue as fv when fv.IsExtensionMember -> + |> Seq.filter(fun (su: FSharpSymbolUse) -> + match su.Symbol with + | :? FSharpMemberOrFunctionOrValue as fv when fv.IsExtensionMember -> // Extension members should be taken into account even though they have a prefix (as they do most of the time) true - | :? FSharpMemberOrFunctionOrValue as fv when not fv.IsModuleValueOrMember -> + | :? FSharpMemberOrFunctionOrValue as fv when not fv.IsModuleValueOrMember -> // Local values can be ignored false - | :? FSharpMemberOrFunctionOrValue when su.IsFromDefinition -> + | :? FSharpMemberOrFunctionOrValue when su.IsFromDefinition -> // Value definitions should be ignored false - | :? FSharpGenericParameter -> + | :? FSharpGenericParameter -> // Generic parameters can be ignored, they never come into scope via 'open' false - | :? FSharpUnionCase when su.IsFromDefinition -> + | :? FSharpUnionCase when su.IsFromDefinition -> false - | :? FSharpField as field when - field.DeclaringEntity.IsSome && field.DeclaringEntity.Value.IsFSharpRecord -> + | :? FSharpField as field when + field.DeclaringEntity.IsSome && field.DeclaringEntity.Value.IsFSharpRecord -> // Record fields are used in name resolution true - | _ -> + | :? FSharpField as field when field.IsUnionCaseField -> + false + + | _ -> // For the rest of symbols we pick only those which are the first part of a long ident, because it's they which are // contained in opened namespaces / modules. For example, we pick `IO` from long ident `IO.File.OpenWrite` because // it's `open System` which really brings it into scope. - let partialName = QuickParse.GetPartialLongNameEx (getSourceLineStr su.RangeAlternate.StartLine, su.RangeAlternate.EndColumn - 1) + let partialName = QuickParse.GetPartialLongNameEx (getSourceLineStr su.Range.StartLine, su.Range.EndColumn - 1) List.isEmpty partialName.QualifyingIdents) + |> Array.ofSeq /// Split symbol uses into cases that are easy to handle (via DeclaringEntity) and those that don't have a good DeclaringEntity - let splitSymbolUses (symbolUses: FSharpSymbolUse[]) : FSharpSymbolUse[] * FSharpSymbolUse[] = + let splitSymbolUses (symbolUses: FSharpSymbolUse[]) = symbolUses |> Array.partition (fun symbolUse -> let symbol = symbolUse.Symbol match symbol with @@ -149,36 +159,36 @@ module UnusedOpens = openStatement.OpenedGroups |> List.choose (fun openedGroup -> let openedEntitiesToExamine = openedGroup.OpenedModules - |> List.filter (fun openedEntity -> + |> Array.filter (fun openedEntity -> not (usedModules.BagExistsValueForKey(openedEntity.Entity, fun scope -> rangeContainsRange scope openStatement.AppliedScope))) match openedEntitiesToExamine with - | [] -> None - | _ when openedEntitiesToExamine |> List.exists (fun x -> not x.IsNestedAutoOpen) -> Some { OpenedModules = openedEntitiesToExamine } + | [||] -> None + | _ when openedEntitiesToExamine |> Array.exists (fun x -> not x.IsNestedAutoOpen) -> Some { OpenedModules = openedEntitiesToExamine } | _ -> None) // Find the opened groups that are used by some symbol use let newlyUsedOpenedGroups = openedGroupsToExamine |> List.filter (fun openedGroup -> - openedGroup.OpenedModules |> List.exists (fun openedEntity -> + openedGroup.OpenedModules |> Array.exists (fun openedEntity -> symbolUsesRangesByDeclaringEntity.BagExistsValueForKey(openedEntity.Entity, fun symbolUseRange -> rangeContainsRange openStatement.AppliedScope symbolUseRange && - Range.posGt symbolUseRange.Start openStatement.Range.End) || + Position.posGt symbolUseRange.Start openStatement.Range.End) || symbolUses2 |> Array.exists (fun symbolUse -> - rangeContainsRange openStatement.AppliedScope symbolUse.RangeAlternate && - Range.posGt symbolUse.RangeAlternate.Start openStatement.Range.End && + rangeContainsRange openStatement.AppliedScope symbolUse.Range && + Position.posGt symbolUse.Range.Start openStatement.Range.End && openedEntity.RevealedSymbolsContains symbolUse.Symbol))) // Return them as interim used entities - let newlyOpenedModules = newlyUsedOpenedGroups |> List.collect (fun openedGroup -> openedGroup.OpenedModules) + let newlyOpenedModules = newlyUsedOpenedGroups |> List.collect (fun openedGroup -> openedGroup.OpenedModules |> List.ofArray) for openedModule in newlyOpenedModules do let scopes = match usedModules.TryGetValue openedModule.Entity with | true, scopes -> openStatement.AppliedScope :: scopes | _ -> [openStatement.AppliedScope] usedModules.[openedModule.Entity] <- scopes - newlyOpenedModules.Length > 0 + not newlyOpenedModules.IsEmpty /// Incrementally filter out the open statements one by one. Filter those whose contents are referred to somewhere in the symbol uses. /// Async to allow cancellation. @@ -209,7 +219,7 @@ module UnusedOpens = | :? FSharpMemberOrFunctionOrValue as f -> match f.DeclaringEntity with | Some entity when entity.IsNamespace || entity.IsFSharpModule -> - symbolUsesRangesByDeclaringEntity.BagAdd(entity, symbolUse.RangeAlternate) + symbolUsesRangesByDeclaringEntity.BagAdd(entity, symbolUse.Range) | _ -> () | _ -> () @@ -221,9 +231,124 @@ module UnusedOpens = /// Async to allow cancellation. let getUnusedOpens (checkFileResults: FSharpCheckFileResults, getSourceLineStr: int -> string) : Async = async { - let! symbolUses = checkFileResults.GetAllUsesOfAllSymbolsInFile() + let! ct = Async.CancellationToken + let symbolUses = checkFileResults.GetAllUsesOfAllSymbolsInFile(ct) let symbolUses = filterSymbolUses getSourceLineStr symbolUses let symbolUses = splitSymbolUses symbolUses let openStatements = getOpenStatements checkFileResults.OpenDeclarations return! filterOpenStatements symbolUses openStatements + } + +module SimplifyNames = + type SimplifiableRange = + { + Range: range + RelativeName: string + } + + let getPlidLength (plid: string list) = (plid |> List.sumBy String.length) + plid.Length + + let getSimplifiableNames (checkFileResults: FSharpCheckFileResults, getSourceLineStr: int -> string) = + async { + let result = ResizeArray() + let! ct = Async.CancellationToken + let symbolUses = + checkFileResults.GetAllUsesOfAllSymbolsInFile(ct) + |> Seq.choose (fun symbolUse -> + if symbolUse.IsFromOpenStatement || symbolUse.IsFromDefinition then + None + else + let lineStr = getSourceLineStr symbolUse.Range.StartLine + // for `System.DateTime.Now` it returns ([|"System"; "DateTime"|], "Now") + let partialName = QuickParse.GetPartialLongNameEx(lineStr, symbolUse.Range.EndColumn - 1) + // `symbolUse.Range.Start` does not point to the start of plid, it points to start of `name`, + // so we have to calculate plid's start ourselves. + let plidStartCol = symbolUse.Range.EndColumn - partialName.PartialIdent.Length - (getPlidLength partialName.QualifyingIdents) + if partialName.PartialIdent = "" || List.isEmpty partialName.QualifyingIdents then + None + else + Some (symbolUse, partialName.QualifyingIdents, plidStartCol, partialName.PartialIdent)) + |> Seq.groupBy (fun (symbolUse, _, plidStartCol, _) -> symbolUse.Range.StartLine, plidStartCol) + |> Seq.map (fun (_, xs) -> xs |> Seq.maxBy (fun (symbolUse, _, _, _) -> symbolUse.Range.EndColumn)) + + for symbolUse, plid, plidStartCol, name in symbolUses do + let posAtStartOfName = + let r = symbolUse.Range + if r.StartLine = r.EndLine then Position.mkPos r.StartLine (r.EndColumn - name.Length) + else r.Start + + let getNecessaryPlid (plid: string list) : string list = + let rec loop (rest: string list) (current: string list) = + match rest with + | [] -> current + | headIdent :: restPlid -> + let res = checkFileResults.IsRelativeNameResolvableFromSymbol(posAtStartOfName, current, symbolUse.Symbol) + if res then current + else loop restPlid (headIdent :: current) + loop (List.rev plid) [] + + let necessaryPlid = getNecessaryPlid plid + + match necessaryPlid with + | necessaryPlid when necessaryPlid = plid -> () + | necessaryPlid -> + let r = symbolUse.Range + let necessaryPlidStartCol = r.EndColumn - name.Length - (getPlidLength necessaryPlid) + + let unnecessaryRange = + mkRange r.FileName (Position.mkPos r.StartLine plidStartCol) (Position.mkPos r.EndLine necessaryPlidStartCol) + + let relativeName = (String.concat "." plid) + "." + name + result.Add({Range = unnecessaryRange; RelativeName = relativeName}) + + return (result :> seq<_>) + } + +module UnusedDeclarations = + let isPotentiallyUnusedDeclaration (symbol: FSharpSymbol) : bool = + match symbol with + + // Determining that a record, DU or module is used anywhere requires inspecting all their enclosed entities (fields, cases and func / vals) + // for usages, which is too expensive to do. Hence we never gray them out. + | :? FSharpEntity as e when e.IsFSharpRecord || e.IsFSharpUnion || e.IsInterface || e.IsFSharpModule || e.IsClass || e.IsNamespace -> false + + // FCS returns inconsistent results for override members; we're skipping these symbols. + | :? FSharpMemberOrFunctionOrValue as f when + f.IsOverrideOrExplicitInterfaceImplementation || + f.IsBaseValue || + f.IsConstructor -> false + + // Usage of DU case parameters does not give any meaningful feedback; we never gray them out. + | :? FSharpParameter -> false + | _ -> true + + let getUnusedDeclarationRanges (symbolsUses: seq) (isScript: bool) = + let usages = + let usages = + symbolsUses + |> Seq.choose (fun su -> if not su.IsFromDefinition then su.Symbol.DeclarationLocation else None) + HashSet(usages) + + symbolsUses + |> Seq.distinctBy (fun su -> su.Range) // Account for "hidden" uses, like a val in a member val definition. These aren't relevant + |> Seq.choose(fun (su: FSharpSymbolUse) -> + if su.IsFromDefinition && + su.Symbol.DeclarationLocation.IsSome && + (isScript || su.IsPrivateToFile) && + not (su.Symbol.DisplayName.StartsWith "_") && + isPotentiallyUnusedDeclaration su.Symbol + then + Some (su, usages.Contains su.Symbol.DeclarationLocation.Value) + else + None) + |> Seq.groupBy (fun (defSu, _) -> defSu.Range) + |> Seq.filter (fun (_, defSus) -> defSus |> Seq.forall (fun (_, isUsed) -> not isUsed)) + |> Seq.map (fun (m, _) -> m) + + let getUnusedDeclarations(checkFileResults: FSharpCheckFileResults, isScriptFile: bool) = + async { + let! ct = Async.CancellationToken + let allSymbolUsesInFile = checkFileResults.GetAllUsesOfAllSymbolsInFile(ct) + let unusedRanges = getUnusedDeclarationRanges allSymbolUsesInFile isScriptFile + return unusedRanges } \ No newline at end of file diff --git a/src/fsharp/service/ServiceAnalysis.fsi b/src/fsharp/service/ServiceAnalysis.fsi index 8d976443890..e1e4488007c 100644 --- a/src/fsharp/service/ServiceAnalysis.fsi +++ b/src/fsharp/service/ServiceAnalysis.fsi @@ -1,11 +1,31 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.Ast -open FSharp.Compiler.NameResolution -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text module public UnusedOpens = + /// Get all unused open declarations in a file - val getUnusedOpens : checkFileResults: FSharpCheckFileResults * getSourceLineStr: (int -> string) -> Async \ No newline at end of file + val getUnusedOpens : checkFileResults: FSharpCheckFileResults * getSourceLineStr: (int -> string) -> Async + +module public SimplifyNames = + + /// Data for use in finding unnecessarily-qualified names and generating diagnostics to simplify them + type SimplifiableRange = + { + /// The range of a name that can be simplified + Range: range + + /// The relative name that can be applied to a simplifiable name + RelativeName: string + } + + /// Get all ranges that can be simplified in a file + val getSimplifiableNames : checkFileResults: FSharpCheckFileResults * getSourceLineStr: (int -> string) -> Async> + +module public UnusedDeclarations = + + /// Get all unused declarations in a file + val getUnusedDeclarations : checkFileResults: FSharpCheckFileResults * isScriptFile: bool -> Async> diff --git a/src/fsharp/service/ServiceAssemblyContent.fs b/src/fsharp/service/ServiceAssemblyContent.fs index e495fa0428c..656b279a386 100644 --- a/src/fsharp/service/ServiceAssemblyContent.fs +++ b/src/fsharp/service/ServiceAssemblyContent.fs @@ -5,98 +5,17 @@ // type checking and intellisense-like environment-reporting. //-------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices open System open System.Collections.Generic +open Internal.Utilities.Library +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.IO +open FSharp.Compiler.Symbols -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.AbstractIL.Internal.Library - -type ShortIdent = string -type Idents = ShortIdent[] -type MaybeUnresolvedIdent = { Ident: ShortIdent; Resolved: bool } -type MaybeUnresolvedIdents = MaybeUnresolvedIdent[] type IsAutoOpen = bool -[] -module Extensions = - - type FSharpEntity with - member x.TryGetFullName() = - try x.TryFullName - with _ -> - try Some(String.Join(".", x.AccessPath, x.DisplayName)) - with _ -> None - - member x.TryGetFullDisplayName() = - let fullName = x.TryGetFullName() |> Option.map (fun fullName -> fullName.Split '.') - let res = - match fullName with - | Some fullName -> - match Option.attempt (fun _ -> x.DisplayName) with - | Some shortDisplayName when not (shortDisplayName.Contains ".") -> - Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) - | _ -> Some fullName - | None -> None - |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) - //debug "GetFullDisplayName: FullName = %A, Result = %A" fullName res - res - - member x.TryGetFullCompiledName() = - let fullName = x.TryGetFullName() |> Option.map (fun fullName -> fullName.Split '.') - let res = - match fullName with - | Some fullName -> - match Option.attempt (fun _ -> x.CompiledName) with - | Some shortCompiledName when not (shortCompiledName.Contains ".") -> - Some (fullName |> Array.replace (fullName.Length - 1) shortCompiledName) - | _ -> Some fullName - | None -> None - |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) - //debug "GetFullCompiledName: FullName = %A, Result = %A" fullName res - res - - member x.PublicNestedEntities = - x.NestedEntities |> Seq.filter (fun entity -> entity.Accessibility.IsPublic) - - member x.TryGetMembersFunctionsAndValues = - try x.MembersFunctionsAndValues with _ -> [||] :> _ - - let isOperator (name: string) = - name.StartsWithOrdinal("( ") && name.EndsWithOrdinal(" )") && name.Length > 4 - && name.Substring (2, name.Length - 4) - |> String.forall (fun c -> c <> ' ' && not (Char.IsLetter c)) - - type FSharpMemberOrFunctionOrValue with - // FullType may raise exceptions (see https://github.com/fsharp/fsharp/issues/307). - member x.FullTypeSafe = Option.attempt (fun _ -> x.FullType) - - member x.TryGetFullDisplayName() = - let fullName = Option.attempt (fun _ -> x.FullName.Split '.') - match fullName with - | Some fullName -> - match Option.attempt (fun _ -> x.DisplayName) with - | Some shortDisplayName when not (shortDisplayName.Contains ".") -> - Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) - | _ -> Some fullName - | None -> None - |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) - - member x.TryGetFullCompiledOperatorNameIdents() : Idents option = - // For operator ++ displayName is ( ++ ) compiledName is op_PlusPlus - if isOperator x.DisplayName && x.DisplayName <> x.CompiledName then - x.DeclaringEntity - |> Option.bind (fun e -> e.TryGetFullName()) - |> Option.map (fun enclosingEntityFullName -> - Array.append (enclosingEntityFullName.Split '.') [| x.CompiledName |]) - else None - - type FSharpAssemblySignature with - member x.TryGetEntities() = try x.Entities :> _ seq with _ -> Seq.empty - [] type LookupType = | Fuzzy @@ -105,26 +24,28 @@ type LookupType = [] type AssemblySymbol = { FullName: string - CleanedIdents: Idents - Namespace: Idents option - NearestRequireQualifiedAccessParent: Idents option - TopRequireQualifiedAccessParent: Idents option - AutoOpenParent: Idents option + CleanedIdents: ShortIdents + Namespace: ShortIdents option + NearestRequireQualifiedAccessParent: ShortIdents option + TopRequireQualifiedAccessParent: ShortIdents option + AutoOpenParent: ShortIdents option Symbol: FSharpSymbol Kind: LookupType -> EntityKind UnresolvedSymbol: UnresolvedSymbol } + override x.ToString() = sprintf "%A" x type AssemblyPath = string type AssemblyContentType = Public | Full type Parent = - { Namespace: Idents option - ThisRequiresQualifiedAccess: (* isForMemberOrValue *) bool -> Idents option - TopRequiresQualifiedAccess: (* isForMemberOrValue *) bool -> Idents option - AutoOpen: Idents option - WithModuleSuffix: Idents option + { Namespace: ShortIdents option + ThisRequiresQualifiedAccess: (* isForMemberOrValue *) bool -> ShortIdents option + TopRequiresQualifiedAccess: (* isForMemberOrValue *) bool -> ShortIdents option + AutoOpen: ShortIdents option + WithModuleSuffix: ShortIdents option IsModule: bool } + static member Empty = { Namespace = None ThisRequiresQualifiedAccess = fun _ -> None @@ -132,7 +53,8 @@ type Parent = AutoOpen = None WithModuleSuffix = None IsModule = true } - static member RewriteParentIdents (parentIdents: Idents option) (idents: Idents) = + + static member RewriteParentIdents (parentIdents: ShortIdents option) (idents: ShortIdents) = match parentIdents with | Some p when p.Length <= idents.Length -> for i in 0..p.Length - 1 do @@ -140,14 +62,14 @@ type Parent = | _ -> () idents - member x.FixParentModuleSuffix (idents: Idents) = + member x.FixParentModuleSuffix (idents: ShortIdents) = Parent.RewriteParentIdents x.WithModuleSuffix idents - member __.FormatEntityFullName (entity: FSharpEntity) = + member _.FormatEntityFullName (entity: FSharpEntity) = // remove number of arguments from generic types // e.g. System.Collections.Generic.Dictionary`2 -> System.Collections.Generic.Dictionary // and System.Data.Listeners`1.Func -> System.Data.Listeners.Func - let removeGenericParamsCount (idents: Idents) = + let removeGenericParamsCount (idents: ShortIdents) = idents |> Array.map (fun ident -> if ident.Length > 0 && Char.IsDigit ident.[ident.Length - 1] then @@ -157,7 +79,7 @@ type Parent = else ident else ident) - let removeModuleSuffix (idents: Idents) = + let removeModuleSuffix (idents: ShortIdents) = if entity.IsFSharpModule && idents.Length > 0 then let lastIdent = idents.[idents.Length - 1] if lastIdent <> entity.DisplayName then @@ -184,11 +106,10 @@ type IAssemblyContentCache = abstract TryGet: AssemblyPath -> AssemblyContentCacheEntry option abstract Set: AssemblyPath -> AssemblyContentCacheEntry -> unit -module AssemblyContentProvider = - open System.IO +module AssemblyContent = - let unresolvedSymbol (topRequireQualifiedAccessParent: Idents option) (cleanedIdents: Idents) (fullName: string) = - let getNamespace (idents: Idents) = + let UnresolvedSymbol (topRequireQualifiedAccessParent: ShortIdents option) (cleanedIdents: ShortIdents) (fullName: string) = + let getNamespace (idents: ShortIdents) = if idents.Length > 1 then Some idents.[..idents.Length - 2] else None let ns = @@ -218,17 +139,17 @@ module AssemblyContentProvider = Symbol = entity Kind = fun lookupType -> match entity, lookupType with - | Symbol.FSharpModule, _ -> + | FSharpSymbolPatterns.FSharpModule, _ -> EntityKind.Module - { IsAutoOpen = Symbol.hasAttribute entity.Attributes - HasModuleSuffix = Symbol.hasModuleSuffixAttribute entity } + { IsAutoOpen = entity.HasAttribute() + HasModuleSuffix = FSharpSymbolPatterns.hasModuleSuffixAttribute entity } | _, LookupType.Fuzzy -> EntityKind.Type | _, LookupType.Precise -> match entity with - | Symbol.Attribute -> EntityKind.Attribute + | FSharpSymbolPatterns.Attribute -> EntityKind.Attribute | _ -> EntityKind.Type - UnresolvedSymbol = unresolvedSymbol topRequireQualifiedAccessParent cleanIdents fullName + UnresolvedSymbol = UnresolvedSymbol topRequireQualifiedAccessParent cleanIdents fullName }) let traverseMemberFunctionAndValues ns (parent: Parent) (membersFunctionsAndValues: seq) = @@ -247,7 +168,7 @@ module AssemblyContentProvider = AutoOpenParent = autoOpenParent Symbol = func Kind = fun _ -> EntityKind.FunctionOrValue func.IsActivePattern - UnresolvedSymbol = unresolvedSymbol topRequireQualifiedAccessParent cleanedIdents fullName } + UnresolvedSymbol = UnresolvedSymbol topRequireQualifiedAccessParent cleanedIdents fullName } [ yield! func.TryGetFullDisplayName() |> Option.map (fun fullDisplayName -> processIdents func.FullName (fullDisplayName.Split '.')) @@ -282,7 +203,7 @@ module AssemblyContentProvider = | None -> () let rqa = parent.FormatEntityFullName entity |> Option.map snd - let rqaForType = if entity.IsFSharp && Symbol.hasAttribute entity.Attributes then rqa else None + let rqaForType = if entity.IsFSharp && entity.HasAttribute() then rqa else None let thisRequiresQualifierAccess (isForMethodOrValue: bool) = if isForMethodOrValue then rqa else rqaForType let currentParent = @@ -290,7 +211,7 @@ module AssemblyContentProvider = TopRequiresQualifiedAccess = fun forMV -> (parent.TopRequiresQualifiedAccess false) |> Option.orElse (thisRequiresQualifierAccess forMV) AutoOpen = - let isAutoOpen = entity.IsFSharpModule && Symbol.hasAttribute entity.Attributes + let isAutoOpen = entity.IsFSharpModule && entity.HasAttribute() match isAutoOpen, parent.AutoOpen with // if parent is also AutoOpen, then keep the parent | true, Some parent -> Some parent @@ -300,14 +221,14 @@ module AssemblyContentProvider = | false, _ -> None WithModuleSuffix = - if entity.IsFSharpModule && (Symbol.hasModuleSuffixAttribute entity || entity.CompiledName <> entity.DisplayName) then + if entity.IsFSharpModule && (FSharpSymbolPatterns.hasModuleSuffixAttribute entity || entity.CompiledName <> entity.DisplayName) then currentEntity |> Option.map (fun e -> e.CleanedIdents) else parent.WithModuleSuffix Namespace = ns IsModule = entity.IsFSharpModule } - match entity.TryGetMembersFunctionsAndValues with + match entity.TryGetMembersFunctionsAndValues() with | xs when xs.Count > 0 -> yield! traverseMemberFunctionAndValues ns currentParent xs | _ -> () @@ -317,7 +238,7 @@ module AssemblyContentProvider = | _ -> () } - let getAssemblySignatureContent contentType (signature: FSharpAssemblySignature) = + let GetAssemblySignatureContent contentType (signature: FSharpAssemblySignature) = // We ignore all diagnostics during this operation // @@ -334,9 +255,9 @@ module AssemblyContentProvider = |> Seq.toList let getAssemblySignaturesContent contentType (assemblies: FSharpAssembly list) = - assemblies |> List.collect (fun asm -> getAssemblySignatureContent contentType asm.Contents) + assemblies |> List.collect (fun asm -> GetAssemblySignatureContent contentType asm.Contents) - let getAssemblyContent (withCache: (IAssemblyContentCache -> _) -> _) contentType (fileName: string option) (assemblies: FSharpAssembly list) = + let GetAssemblyContent (withCache: (IAssemblyContentCache -> _) -> _) contentType (fileName: string option) (assemblies: FSharpAssembly list) = // We ignore all diagnostics during this operation // @@ -353,7 +274,7 @@ module AssemblyContentProvider = #endif | [], _ -> [] | assemblies, Some fileName -> - let fileWriteTime = FileInfo(fileName).LastWriteTime + let fileWriteTime = FileSystem.GetLastWriteTimeShim(fileName) withCache <| fun cache -> match contentType, cache.TryGet fileName with | _, Some entry @@ -365,673 +286,19 @@ module AssemblyContentProvider = | assemblies, None -> getAssemblySignaturesContent contentType assemblies |> List.filter (fun entity -> - match contentType, FSharpSymbol.GetAccessibility(entity.Symbol) with - | Full, _ -> true - | Public, access -> - match access with - | None -> true - | Some x when x.IsPublic -> true - | _ -> false) + match contentType with + | Full -> true + | Public -> entity.Symbol.Accessibility.IsPublic) type EntityCache() = let dic = Dictionary() interface IAssemblyContentCache with - member __.TryGet assembly = + member _.TryGet assembly = match dic.TryGetValue assembly with | true, entry -> Some entry | _ -> None - member __.Set assembly entry = dic.[assembly] <- entry + member _.Set assembly entry = dic.[assembly] <- entry - member __.Clear() = dic.Clear() + member _.Clear() = dic.Clear() member x.Locking f = lock dic <| fun _ -> f (x :> IAssemblyContentCache) -type StringLongIdent = string - -type Entity = - { FullRelativeName: StringLongIdent - Qualifier: StringLongIdent - Namespace: StringLongIdent option - Name: StringLongIdent - LastIdent: string } - override x.ToString() = sprintf "%A" x - -[] -module Entity = - let getRelativeNamespace (targetNs: Idents) (sourceNs: Idents) = - let rec loop index = - if index > targetNs.Length - 1 then sourceNs.[index..] - // target namespace is not a full parent of source namespace, keep the source ns as is - elif index > sourceNs.Length - 1 then sourceNs - elif targetNs.[index] = sourceNs.[index] then loop (index + 1) - else sourceNs.[index..] - if sourceNs.Length = 0 || targetNs.Length = 0 then sourceNs - else loop 0 - - let cutAutoOpenModules (autoOpenParent: Idents option) (candidateNs: Idents) = - let nsCount = - match autoOpenParent with - | Some parent when parent.Length > 0 -> - min (parent.Length - 1) candidateNs.Length - | _ -> candidateNs.Length - candidateNs.[0..nsCount - 1] - - let tryCreate (targetNamespace: Idents option, targetScope: Idents, partiallyQualifiedName: MaybeUnresolvedIdents, - requiresQualifiedAccessParent: Idents option, autoOpenParent: Idents option, candidateNamespace: Idents option, candidate: Idents) = - match candidate with - | [||] -> [||] - | _ -> - partiallyQualifiedName - |> Array.heads - // long ident must contain an unresolved part, otherwise we show false positive suggestions like - // "open System" for `let _ = System.DateTime.Naaaw`. Here only "Naaw" is unresolved. - |> Array.filter (fun x -> x |> Array.exists (fun x -> not x.Resolved)) - |> Array.choose (fun parts -> - let parts = parts |> Array.map (fun x -> x.Ident) - if not (candidate |> Array.endsWith parts) then None - else - let identCount = parts.Length - let fullOpenableNs, restIdents = - let openableNsCount = - match requiresQualifiedAccessParent with - | Some parent -> min parent.Length candidate.Length - | None -> candidate.Length - candidate.[0..openableNsCount - 2], candidate.[openableNsCount - 1..] - - let openableNs = cutAutoOpenModules autoOpenParent fullOpenableNs - - let getRelativeNs ns = - match targetNamespace, candidateNamespace with - | Some targetNs, Some candidateNs when candidateNs = targetNs -> - getRelativeNamespace targetScope ns - | None, _ -> getRelativeNamespace targetScope ns - | _ -> ns - - let relativeNs = getRelativeNs openableNs - - match relativeNs, restIdents with - | [||], [||] -> None - | [||], [|_|] -> None - | _ -> - let fullRelativeName = Array.append (getRelativeNs fullOpenableNs) restIdents - let ns = - match relativeNs with - | [||] -> None - | _ when identCount > 1 && relativeNs.Length >= identCount -> - Some (relativeNs.[0..relativeNs.Length - identCount] |> String.concat ".") - | _ -> Some (relativeNs |> String.concat ".") - let qualifier = - if fullRelativeName.Length > 1 && fullRelativeName.Length >= identCount then - fullRelativeName.[0..fullRelativeName.Length - identCount] - else fullRelativeName - Some - { FullRelativeName = String.concat "." fullRelativeName //.[0..fullRelativeName.Length - identCount - 1] - Qualifier = String.concat "." qualifier - Namespace = ns - Name = match restIdents with [|_|] -> "" | _ -> String.concat "." restIdents - LastIdent = Array.tryLast restIdents |> Option.defaultValue "" }) - -type ScopeKind = - | Namespace - | TopModule - | NestedModule - | OpenDeclaration - | HashDirective - override x.ToString() = sprintf "%A" x - -type InsertContext = - { ScopeKind: ScopeKind - Pos: pos } - -type Module = - { Idents: Idents - Range: range } - -type OpenStatementInsertionPoint = - | TopLevel - | Nearest - -module ParsedInput = - - /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException - let rec (|Sequentials|_|) = function - | SynExpr.Sequential (_, _, e, Sequentials es, _) -> - Some(e :: es) - | SynExpr.Sequential (_, _, e1, e2, _) -> - Some [e1; e2] - | _ -> None - - let (|ConstructorPats|) = function - | SynConstructorArgs.Pats ps -> ps - | SynConstructorArgs.NamePatPairs(xs, _) -> List.map snd xs - - /// Returns all `Ident`s and `LongIdent`s found in an untyped AST. - let getLongIdents (input: ParsedInput option) : IDictionary = - let identsByEndPos = Dictionary() - - let addLongIdent (longIdent: LongIdent) = - for ident in longIdent do - identsByEndPos.[ident.idRange.End] <- longIdent - - let addLongIdentWithDots (LongIdentWithDots (longIdent, lids) as value) = - match longIdent with - | [] -> () - | [_] as idents -> identsByEndPos.[value.Range.End] <- idents - | idents -> - for dotRange in lids do - identsByEndPos.[Range.mkPos dotRange.EndLine (dotRange.EndColumn - 1)] <- idents - identsByEndPos.[value.Range.End] <- idents - - let addIdent (ident: Ident) = - identsByEndPos.[ident.idRange.End] <- [ident] - - let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = - List.iter walkSynModuleOrNamespace moduleOrNamespaceList - - and walkSynModuleOrNamespace (SynModuleOrNamespace(_, _, _, decls, _, Attributes attrs, _, _)) = - List.iter walkAttribute attrs - List.iter walkSynModuleDecl decls - - and walkAttribute (attr: SynAttribute) = - addLongIdentWithDots attr.TypeName - walkExpr attr.ArgExpr - - and walkTyparDecl (SynTyparDecl.TyparDecl (Attributes attrs, typar)) = - List.iter walkAttribute attrs - walkTypar typar - - and walkTypeConstraint = function - | SynTypeConstraint.WhereTyparIsValueType (t, _) - | SynTypeConstraint.WhereTyparIsReferenceType (t, _) - | SynTypeConstraint.WhereTyparIsUnmanaged (t, _) - | SynTypeConstraint.WhereTyparSupportsNull (t, _) - | SynTypeConstraint.WhereTyparIsComparable (t, _) - | SynTypeConstraint.WhereTyparIsEquatable (t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparDefaultsToType (t, ty, _) - | SynTypeConstraint.WhereTyparSubtypeOfType (t, ty, _) -> walkTypar t; walkType ty - | SynTypeConstraint.WhereTyparIsEnum (t, ts, _) - | SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) -> walkTypar t; List.iter walkType ts - | SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) -> List.iter walkType ts; walkMemberSig sign - - and walkPat = function - | SynPat.Tuple (_,pats, _) - | SynPat.ArrayOrList (_, pats, _) - | SynPat.Ands (pats, _) -> List.iter walkPat pats - | SynPat.Named (pat, ident, _, _, _) -> - walkPat pat - addIdent ident - | SynPat.Typed (pat, t, _) -> - walkPat pat - walkType t - | SynPat.Attrib (pat, Attributes attrs, _) -> - walkPat pat - List.iter walkAttribute attrs - | SynPat.Or (pat1, pat2, _) -> List.iter walkPat [pat1; pat2] - | SynPat.LongIdent (ident, _, typars, ConstructorPats pats, _, _) -> - addLongIdentWithDots ident - typars - |> Option.iter (fun (SynValTyparDecls (typars, _, constraints)) -> - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints) - List.iter walkPat pats - | SynPat.Paren (pat, _) -> walkPat pat - | SynPat.IsInst (t, _) -> walkType t - | SynPat.QuoteExpr(e, _) -> walkExpr e - | _ -> () - - and walkTypar (Typar (_, _, _)) = () - - and walkBinding (SynBinding.Binding (_, _, _, _, Attributes attrs, _, _, pat, returnInfo, e, _, _)) = - List.iter walkAttribute attrs - walkPat pat - walkExpr e - returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t) - - and walkInterfaceImpl (InterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings - - and walkIndexerArg = function - | SynIndexerArg.One (e, _, _) -> walkExpr e - | SynIndexerArg.Two (e1, _, e2, _, _, _) -> List.iter walkExpr [e1; e2] - - and walkType = function - | SynType.Array (_, t, _) - | SynType.HashConstraint (t, _) - | SynType.MeasurePower (t, _, _) -> walkType t - | SynType.Fun (t1, t2, _) - | SynType.MeasureDivide (t1, t2, _) -> walkType t1; walkType t2 - | SynType.LongIdent ident -> addLongIdentWithDots ident - | SynType.App (ty, _, types, _, _, _, _) -> walkType ty; List.iter walkType types - | SynType.LongIdentApp (_, _, _, types, _, _, _) -> List.iter walkType types - | SynType.Tuple (_, ts, _) -> ts |> List.iter (fun (_, t) -> walkType t) - | SynType.WithGlobalConstraints (t, typeConstraints, _) -> - walkType t; List.iter walkTypeConstraint typeConstraints - | _ -> () - - and walkClause (Clause (pat, e1, e2, _, _)) = - walkPat pat - walkExpr e2 - e1 |> Option.iter walkExpr - - and walkSimplePats = function - | SynSimplePats.SimplePats (pats, _) -> List.iter walkSimplePat pats - | SynSimplePats.Typed (pats, ty, _) -> - walkSimplePats pats - walkType ty - - and walkExpr = function - | SynExpr.Paren (e, _, _, _) - | SynExpr.Quote (_, _, e, _, _) - | SynExpr.Typed (e, _, _) - | SynExpr.InferredUpcast (e, _) - | SynExpr.InferredDowncast (e, _) - | SynExpr.AddressOf (_, e, _, _) - | SynExpr.DoBang (e, _) - | SynExpr.YieldOrReturn (_, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) - | SynExpr.CompExpr (_, _, e, _) - | SynExpr.Do (e, _) - | SynExpr.Assert (e, _) - | SynExpr.Lazy (e, _) - | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExpr e - | SynExpr.Lambda (_, _, pats, e, _) -> - walkSimplePats pats - walkExpr e - | SynExpr.New (_, t, e, _) - | SynExpr.TypeTest (e, t, _) - | SynExpr.Upcast (e, t, _) - | SynExpr.Downcast (e, t, _) -> walkExpr e; walkType t - | SynExpr.Tuple (_, es, _, _) - | Sequentials es - | SynExpr.ArrayOrList (_, es, _) -> List.iter walkExpr es - | SynExpr.App (_, _, e1, e2, _) - | SynExpr.TryFinally (e1, e2, _, _, _) - | SynExpr.While (_, e1, e2, _) -> List.iter walkExpr [e1; e2] - | SynExpr.Record (_, _, fields, _) -> - fields |> List.iter (fun ((ident, _), e, _) -> - addLongIdentWithDots ident - e |> Option.iter walkExpr) - | SynExpr.Ident ident -> addIdent ident - | SynExpr.ObjExpr (ty, argOpt, bindings, ifaces, _, _) -> - argOpt |> Option.iter (fun (e, ident) -> - walkExpr e - ident |> Option.iter addIdent) - walkType ty - List.iter walkBinding bindings - List.iter walkInterfaceImpl ifaces - | SynExpr.LongIdent (_, ident, _, _) -> addLongIdentWithDots ident - | SynExpr.For (_, ident, e1, _, e2, e3, _) -> - addIdent ident - List.iter walkExpr [e1; e2; e3] - | SynExpr.ForEach (_, _, _, pat, e1, e2, _) -> - walkPat pat - List.iter walkExpr [e1; e2] - | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> - List.iter walkClause synMatchClauseList - | SynExpr.Match (_, e, synMatchClauseList, _) -> - walkExpr e - List.iter walkClause synMatchClauseList - | SynExpr.TypeApp (e, _, tys, _, _, _, _) -> - List.iter walkType tys; walkExpr e - | SynExpr.LetOrUse (_, _, bindings, e, _) -> - List.iter walkBinding bindings; walkExpr e - | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> - List.iter walkClause clauses; walkExpr e - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, _) -> - List.iter walkExpr [e1; e2] - e3 |> Option.iter walkExpr - | SynExpr.LongIdentSet (ident, e, _) - | SynExpr.DotGet (e, _, ident, _) -> - addLongIdentWithDots ident - walkExpr e - | SynExpr.DotSet (e1, idents, e2, _) -> - walkExpr e1 - addLongIdentWithDots idents - walkExpr e2 - | SynExpr.Set (e1, e2, _) -> - walkExpr e1 - walkExpr e2 - | SynExpr.DotIndexedGet (e, args, _, _) -> - walkExpr e - List.iter walkIndexerArg args - | SynExpr.DotIndexedSet (e1, args, e2, _, _, _) -> - walkExpr e1 - List.iter walkIndexerArg args - walkExpr e2 - | SynExpr.NamedIndexedPropertySet (ident, e1, e2, _) -> - addLongIdentWithDots ident - List.iter walkExpr [e1; e2] - | SynExpr.DotNamedIndexedPropertySet (e1, ident, e2, e3, _) -> - addLongIdentWithDots ident - List.iter walkExpr [e1; e2; e3] - | SynExpr.JoinIn (e1, _, e2, _) -> List.iter walkExpr [e1; e2] - | SynExpr.LetOrUseBang (_, _, _, pat, e1, e2, _) -> - walkPat pat - List.iter walkExpr [e1; e2] - | SynExpr.TraitCall (ts, sign, e, _) -> - List.iter walkTypar ts - walkMemberSig sign - walkExpr e - | SynExpr.Const (SynConst.Measure(_, m), _) -> walkMeasure m - | _ -> () - - and walkMeasure = function - | SynMeasure.Product (m1, m2, _) - | SynMeasure.Divide (m1, m2, _) -> walkMeasure m1; walkMeasure m2 - | SynMeasure.Named (longIdent, _) -> addLongIdent longIdent - | SynMeasure.Seq (ms, _) -> List.iter walkMeasure ms - | SynMeasure.Power (m, _, _) -> walkMeasure m - | SynMeasure.Var (ty, _) -> walkTypar ty - | SynMeasure.One - | SynMeasure.Anon _ -> () - - and walkSimplePat = function - | SynSimplePat.Attrib (pat, Attributes attrs, _) -> - walkSimplePat pat - List.iter walkAttribute attrs - | SynSimplePat.Typed(pat, t, _) -> - walkSimplePat pat - walkType t - | _ -> () - - and walkField (SynField.Field(Attributes attrs, _, _, t, _, _, _, _)) = - List.iter walkAttribute attrs - walkType t - - and walkValSig (SynValSig.ValSpfn(Attributes attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = - List.iter walkAttribute attrs - walkType t - argInfo :: (argInfos |> List.concat) - |> List.map (fun (SynArgInfo(Attributes attrs, _, _)) -> attrs) - |> List.concat - |> List.iter walkAttribute - - and walkMemberSig = function - | SynMemberSig.Inherit (t, _) - | SynMemberSig.Interface(t, _) -> walkType t - | SynMemberSig.Member(vs, _, _) -> walkValSig vs - | SynMemberSig.ValField(f, _) -> walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (info, repr, memberSigs, _), _) -> - let isTypeExtensionOrAlias = - match repr with - | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAbbrev, _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAugmentation, _, _) -> true - | _ -> false - walkComponentInfo isTypeExtensionOrAlias info - walkTypeDefnSigRepr repr - List.iter walkMemberSig memberSigs - - and walkMember = function - | SynMemberDefn.AbstractSlot (valSig, _, _) -> walkValSig valSig - | SynMemberDefn.Member (binding, _) -> walkBinding binding - | SynMemberDefn.ImplicitCtor (_, Attributes attrs, SynSimplePats.SimplePats(simplePats, _), _, _) -> - List.iter walkAttribute attrs - List.iter walkSimplePat simplePats - | SynMemberDefn.ImplicitInherit (t, e, _, _) -> walkType t; walkExpr e - | SynMemberDefn.LetBindings (bindings, _, _, _) -> List.iter walkBinding bindings - | SynMemberDefn.Interface (t, members, _) -> - walkType t - members |> Option.iter (List.iter walkMember) - | SynMemberDefn.Inherit (t, _, _) -> walkType t - | SynMemberDefn.ValField (field, _) -> walkField field - | SynMemberDefn.NestedType (tdef, _, _) -> walkTypeDefn tdef - | SynMemberDefn.AutoProperty (Attributes attrs, _, _, t, _, _, _, _, e, _, _) -> - List.iter walkAttribute attrs - Option.iter walkType t - walkExpr e - | _ -> () - - and walkEnumCase (EnumCase(Attributes attrs, _, _, _, _)) = List.iter walkAttribute attrs - - and walkUnionCaseType = function - | SynUnionCaseType.UnionCaseFields fields -> List.iter walkField fields - | SynUnionCaseType.UnionCaseFullType (t, _) -> walkType t - - and walkUnionCase (SynUnionCase.UnionCase (Attributes attrs, _, t, _, _, _)) = - List.iter walkAttribute attrs - walkUnionCaseType t - - and walkTypeDefnSimple = function - | SynTypeDefnSimpleRepr.Enum (cases, _) -> List.iter walkEnumCase cases - | SynTypeDefnSimpleRepr.Union (_, cases, _) -> List.iter walkUnionCase cases - | SynTypeDefnSimpleRepr.Record (_, fields, _) -> List.iter walkField fields - | SynTypeDefnSimpleRepr.TypeAbbrev (_, t, _) -> walkType t - | _ -> () - - and walkComponentInfo isTypeExtensionOrAlias (ComponentInfo(Attributes attrs, typars, constraints, longIdent, _, _, _, _)) = - List.iter walkAttribute attrs - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints - if isTypeExtensionOrAlias then - addLongIdent longIdent - - and walkTypeDefnRepr = function - | SynTypeDefnRepr.ObjectModel (_, defns, _) -> List.iter walkMember defns - | SynTypeDefnRepr.Simple(defn, _) -> walkTypeDefnSimple defn - | SynTypeDefnRepr.Exception _ -> () - - and walkTypeDefnSigRepr = function - | SynTypeDefnSigRepr.ObjectModel (_, defns, _) -> List.iter walkMemberSig defns - | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn - | SynTypeDefnSigRepr.Exception _ -> () - - and walkTypeDefn (TypeDefn (info, repr, members, _)) = - let isTypeExtensionOrAlias = - match repr with - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAugmentation, _, _) - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAbbrev, _, _) - | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.TypeAbbrev _, _) -> true - | _ -> false - walkComponentInfo isTypeExtensionOrAlias info - walkTypeDefnRepr repr - List.iter walkMember members - - and walkSynModuleDecl (decl: SynModuleDecl) = - match decl with - | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace fragment - | SynModuleDecl.NestedModule (info, _, modules, _, _) -> - walkComponentInfo false info - List.iter walkSynModuleDecl modules - | SynModuleDecl.Let (_, bindings, _) -> List.iter walkBinding bindings - | SynModuleDecl.DoExpr (_, expr, _) -> walkExpr expr - | SynModuleDecl.Types (types, _) -> List.iter walkTypeDefn types - | SynModuleDecl.Attributes (Attributes attrs, _) -> List.iter walkAttribute attrs - | _ -> () - - match input with - | Some (ParsedInput.ImplFile input) -> - walkImplFileInput input - | _ -> () - //debug "%A" idents - upcast identsByEndPos - - let getLongIdentAt ast pos = - let idents = getLongIdents (Some ast) - match idents.TryGetValue pos with - | true, idents -> Some idents - | _ -> None - - type Scope = - { Idents: Idents - Kind: ScopeKind } - - let tryFindNearestPointAndModules (currentLine: int) (ast: ParsedInput) (insertionPoint: OpenStatementInsertionPoint) = - // We ignore all diagnostics during this operation - // - // Based on an initial review, no diagnostics should be generated. However the code should be checked more closely. - use _ignoreAllDiagnostics = new ErrorScope() - - let mutable result = None - let mutable ns = None - let modules = ResizeArray() - - let inline longIdentToIdents ident = ident |> Seq.map (fun x -> string x) |> Seq.toArray - - let addModule (longIdent: LongIdent, range: range) = - modules.Add - { Idents = longIdent |> List.map string |> List.toArray - Range = range } - - let doRange kind (scope: LongIdent) line col = - if line <= currentLine then - match result, insertionPoint with - | None, _ -> - result <- Some ({ Idents = longIdentToIdents scope; Kind = kind }, mkPos line col, false) - | Some (_, _, true), _ -> () - | Some (oldScope, oldPos, false), OpenStatementInsertionPoint.TopLevel when kind <> OpenDeclaration -> - result <- Some (oldScope, oldPos, true) - | Some (oldScope, oldPos, _), _ -> - match kind, oldScope.Kind with - | (Namespace | NestedModule | TopModule), OpenDeclaration - | _ when oldPos.Line <= line -> - result <- - Some ({ Idents = - match scope with - | [] -> oldScope.Idents - | _ -> longIdentToIdents scope - Kind = kind }, - mkPos line col, - false) - | _ -> () - - let getMinColumn (decls: SynModuleDecls) = - match decls with - | [] -> None - | firstDecl :: _ -> - match firstDecl with - | SynModuleDecl.NestedModule (_, _, _, _, r) - | SynModuleDecl.Let (_, _, r) - | SynModuleDecl.DoExpr (_, _, r) - | SynModuleDecl.Types (_, r) - | SynModuleDecl.Exception (_, r) - | SynModuleDecl.Open (_, r) - | SynModuleDecl.HashDirective (_, r) -> Some r - | _ -> None - |> Option.map (fun r -> r.StartColumn) - - - let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = - List.iter (walkSynModuleOrNamespace []) moduleOrNamespaceList - - and walkSynModuleOrNamespace (parent: LongIdent) (SynModuleOrNamespace(ident, _, kind, decls, _, _, _, range)) = - if range.EndLine >= currentLine then - let isModule = kind.IsModule - match isModule, parent, ident with - | false, _, _ -> ns <- Some (longIdentToIdents ident) - // top level module with "inlined" namespace like Ns1.Ns2.TopModule - | true, [], _f :: _s :: _ -> - let ident = longIdentToIdents ident - ns <- Some (ident.[0..ident.Length - 2]) - | _ -> () - - let fullIdent = parent @ ident - - let startLine = - if isModule then range.StartLine - else range.StartLine - 1 - - let scopeKind = - match isModule, parent with - | true, [] -> TopModule - | true, _ -> NestedModule - | _ -> Namespace - - doRange scopeKind fullIdent startLine range.StartColumn - addModule (fullIdent, range) - List.iter (walkSynModuleDecl fullIdent) decls - - and walkSynModuleDecl (parent: LongIdent) (decl: SynModuleDecl) = - match decl with - | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace parent fragment - | SynModuleDecl.NestedModule(ComponentInfo(_, _, _, ident, _, _, _, _), _, decls, _, range) -> - let fullIdent = parent @ ident - addModule (fullIdent, range) - if range.EndLine >= currentLine then - let moduleBodyIndentation = getMinColumn decls |> Option.defaultValue (range.StartColumn + 4) - doRange NestedModule fullIdent range.StartLine moduleBodyIndentation - List.iter (walkSynModuleDecl fullIdent) decls - | SynModuleDecl.Open (_, range) -> doRange OpenDeclaration [] range.EndLine (range.StartColumn - 5) - | SynModuleDecl.HashDirective (_, range) -> doRange HashDirective [] range.EndLine range.StartColumn - | _ -> () - - match ast with - | ParsedInput.SigFile _ -> () - | ParsedInput.ImplFile input -> walkImplFileInput input - - let res = - result - |> Option.map (fun (scope, pos, _) -> - let ns = ns |> Option.map longIdentToIdents - scope, ns, mkPos (pos.Line + 1) pos.Column) - - let modules = - modules - |> Seq.filter (fun x -> x.Range.EndLine < currentLine) - |> Seq.sortBy (fun x -> -x.Idents.Length) - |> Seq.toList - - res, modules - - let findBestPositionToInsertOpenDeclaration (modules: Module list) scope pos (entity: Idents) = - match modules |> List.filter (fun x -> entity |> Array.startsWith x.Idents) with - | [] -> { ScopeKind = scope.Kind; Pos = pos } - | m :: _ -> - //printfn "All modules: %A, Win module: %A" modules m - let scopeKind = - match scope.Kind with - | TopModule -> NestedModule - | x -> x - { ScopeKind = scopeKind - Pos = mkPos (Line.fromZ m.Range.EndLine) m.Range.StartColumn } - - let tryFindInsertionContext (currentLine: int) (ast: ParsedInput) (partiallyQualifiedName: MaybeUnresolvedIdents) (insertionPoint: OpenStatementInsertionPoint) = - let res, modules = tryFindNearestPointAndModules currentLine ast insertionPoint - // CLEANUP: does this really need to be a partial application with pre-computation? Can this be made more explicit? - fun (requiresQualifiedAccessParent: Idents option, autoOpenParent: Idents option, entityNamespace: Idents option, entity: Idents) -> - - // We ignore all diagnostics during this operation - // - // Based on an initial review, no diagnostics should be generated. However the code should be checked more closely. - use _ignoreAllDiagnostics = new ErrorScope() - match res with - | None -> [||] - | Some (scope, ns, pos) -> - Entity.tryCreate(ns, scope.Idents, partiallyQualifiedName, requiresQualifiedAccessParent, autoOpenParent, entityNamespace, entity) - |> Array.map (fun e -> e, findBestPositionToInsertOpenDeclaration modules scope pos entity) - - /// Corrects insertion line number based on kind of scope and text surrounding the insertion point. - let adjustInsertionPoint (getLineStr: int -> string) ctx = - let line = - match ctx.ScopeKind with - | ScopeKind.TopModule -> - if ctx.Pos.Line > 1 then - // it's an implicit module without any open declarations - let line = getLineStr (ctx.Pos.Line - 2) - let isImplicitTopLevelModule = - not (line.StartsWithOrdinal("module") && not (line.EndsWithOrdinal("="))) - if isImplicitTopLevelModule then 1 else ctx.Pos.Line - else 1 - | ScopeKind.Namespace -> - // for namespaces the start line is start line of the first nested entity - if ctx.Pos.Line > 1 then - [0..ctx.Pos.Line - 1] - |> List.mapi (fun i line -> i, getLineStr line) - |> List.tryPick (fun (i, lineStr) -> - if lineStr.StartsWithOrdinal("namespace") then Some i - else None) - |> function - // move to the next line below "namespace" and convert it to F# 1-based line number - | Some line -> line + 2 - | None -> ctx.Pos.Line - else 1 - | _ -> ctx.Pos.Line - - mkPos line ctx.Pos.Column - - let findNearestPointToInsertOpenDeclaration (currentLine: int) (ast: ParsedInput) (entity: Idents) (insertionPoint: OpenStatementInsertionPoint) = - match tryFindNearestPointAndModules currentLine ast insertionPoint with - | Some (scope, _, point), modules -> - findBestPositionToInsertOpenDeclaration modules scope point entity - | _ -> - // we failed to find insertion point because ast is empty for some reason, return top left point in this case - { ScopeKind = ScopeKind.TopModule - Pos = mkPos 1 0 } diff --git a/src/fsharp/service/ServiceAssemblyContent.fsi b/src/fsharp/service/ServiceAssemblyContent.fsi index f9e9699cb7d..a03ec9f4dba 100644 --- a/src/fsharp/service/ServiceAssemblyContent.fsi +++ b/src/fsharp/service/ServiceAssemblyContent.fsi @@ -1,34 +1,18 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices - +namespace FSharp.Compiler.EditorServices open System -open System.Collections.Generic - -open FSharp.Compiler -open FSharp.Compiler.Range +open FSharp.Compiler.Symbols /// Assembly content type. +[] type public AssemblyContentType = /// Public assembly content only. | Public /// All assembly content. | Full -/// Short identifier, i.e. an identifier that contains no dots. -type public ShortIdent = string - -/// An array of `ShortIdent`. -type public Idents = ShortIdent[] - -/// `ShortIdent` with a flag indicating if it's resolved in some scope. -type public MaybeUnresolvedIdent = - { Ident: ShortIdent; Resolved: bool } - -/// Array of `MaybeUnresolvedIdent`. -type public MaybeUnresolvedIdents = MaybeUnresolvedIdent[] - /// Entity lookup type. [] type public LookupType = @@ -41,40 +25,55 @@ type public AssemblyPath = string /// Represents type, module, member, function or value in a compiled assembly. [] type public AssemblySymbol = - { /// Full entity name as it's seen in compiled code (raw FSharpEntity.FullName, FSharpValueOrFunction.FullName). + { + /// Full entity name as it's seen in compiled code (raw FSharpEntity.FullName, FSharpValueOrFunction.FullName). FullName: string + /// Entity name parts with removed module suffixes (Ns.M1Module.M2Module.M3.entity -> Ns.M1.M2.M3.entity) /// and replaced compiled names with display names (FSharpEntity.DisplayName, FSharpValueOrFunction.DisplayName). /// Note: *all* parts are cleaned, not the last one. - CleanedIdents: Idents + CleanedIdents: ShortIdents + /// `FSharpEntity.Namespace`. - Namespace: Idents option + Namespace: ShortIdents option + /// The most narrative parent module that has `RequireQualifiedAccess` attribute. - NearestRequireQualifiedAccessParent: Idents option + NearestRequireQualifiedAccessParent: ShortIdents option + /// Parent module that has the largest scope and has `RequireQualifiedAccess` attribute. - TopRequireQualifiedAccessParent: Idents option + TopRequireQualifiedAccessParent: ShortIdents option + /// Parent module that has `AutoOpen` attribute. - AutoOpenParent: Idents option + AutoOpenParent: ShortIdents option + Symbol: FSharpSymbol + /// Function that returns `EntityKind` based of given `LookupKind`. Kind: LookupType -> EntityKind + /// Cache display name and namespace, used for completion. - UnresolvedSymbol: UnresolvedSymbol } + UnresolvedSymbol: UnresolvedSymbol + } /// `RawEntity` list retrieved from an assembly. type internal AssemblyContentCacheEntry = - { /// Assembly file last write time. + { + /// Assembly file last write time. FileWriteTime: DateTime + /// Content type used to get assembly content. ContentType: AssemblyContentType + /// Assembly content. - Symbols: AssemblySymbol list } + Symbols: AssemblySymbol list + } /// Assembly content cache. [] type public IAssemblyContentCache = /// Try get an assembly cached content. abstract TryGet: AssemblyPath -> AssemblyContentCacheEntry option + /// Store an assembly content. abstract Set: AssemblyPath -> AssemblyContentCacheEntry -> unit @@ -82,107 +81,24 @@ type public IAssemblyContentCache = type public EntityCache = interface IAssemblyContentCache new : unit -> EntityCache + /// Clears the cache. member Clear : unit -> unit + /// Performs an operation on the cache in thread safe manner. member Locking : (IAssemblyContentCache -> 'T) -> 'T -/// Long identifier (i.e. it may contain dots). -type public StringLongIdent = string - -/// Helper data structure representing a symbol, suitable for implementing unresolved identifiers resolution code fixes. -type public Entity = - { /// Full name, relative to the current scope. - FullRelativeName: StringLongIdent - /// Ident parts needed to append to the current ident to make it resolvable in current scope. - Qualifier: StringLongIdent - /// Namespace that is needed to open to make the entity resolvable in the current scope. - Namespace: StringLongIdent option - /// Full display name (i.e. last ident plus modules with `RequireQualifiedAccess` attribute prefixed). - Name: StringLongIdent - /// Last part of the entity's full name. - LastIdent: string } - /// Provides assembly content. -module public AssemblyContentProvider = +module public AssemblyContent = + /// Given a `FSharpAssemblySignature`, returns assembly content. - val getAssemblySignatureContent : AssemblyContentType -> FSharpAssemblySignature -> AssemblySymbol list + val GetAssemblySignatureContent : AssemblyContentType -> FSharpAssemblySignature -> AssemblySymbol list /// Returns (possibly cached) assembly content. - val getAssemblyContent : - withCache: ((IAssemblyContentCache -> AssemblySymbol list) -> AssemblySymbol list) + val GetAssemblyContent : + withCache: ((IAssemblyContentCache -> AssemblySymbol list) -> AssemblySymbol list) -> contentType: AssemblyContentType -> fileName: string option -> assemblies: FSharpAssembly list -> AssemblySymbol list -/// Kind of lexical scope. -type public ScopeKind = - | Namespace - | TopModule - | NestedModule - | OpenDeclaration - | HashDirective - -/// Insert open namespace context. -type public InsertContext = - { /// Current scope kind. - ScopeKind: ScopeKind - /// Current position (F# compiler line number). - Pos: pos } - -/// Where open statements should be added. -type public OpenStatementInsertionPoint = - | TopLevel - | Nearest - -/// Parse AST helpers. -module public ParsedInput = - - /// Returns `InsertContext` based on current position and symbol idents. - val tryFindInsertionContext : - currentLine: int -> - ast: Ast.ParsedInput -> MaybeUnresolvedIdents -> - insertionPoint: OpenStatementInsertionPoint -> - (( (* requiresQualifiedAccessParent: *) Idents option * (* autoOpenParent: *) Idents option * (* entityNamespace *) Idents option * (* entity: *) Idents) -> (Entity * InsertContext)[]) - - /// Returns `InsertContext` based on current position and symbol idents. - val findNearestPointToInsertOpenDeclaration : currentLine: int -> ast: Ast.ParsedInput -> entity: Idents -> insertionPoint: OpenStatementInsertionPoint -> InsertContext - - /// Returns long identifier at position. - val getLongIdentAt : ast: Ast.ParsedInput -> pos: Range.pos -> Ast.LongIdent option - - /// Corrects insertion line number based on kind of scope and text surrounding the insertion point. - val adjustInsertionPoint : getLineStr: (int -> string) -> ctx: InsertContext -> pos - -[] -module public Extensions = - type FSharpEntity with - /// Safe version of `FullName`. - member TryGetFullName : unit -> string option - - /// Safe version of `DisplayName`. - member TryGetFullDisplayName : unit -> string option - - /// Safe version of `CompiledName`. - member TryGetFullCompiledName : unit -> string option - - /// Public nested entities (methods, functions, values, nested modules). - member PublicNestedEntities : seq - - /// Safe version of `GetMembersFunctionsAndValues`. - member TryGetMembersFunctionsAndValues : IList - - type FSharpMemberOrFunctionOrValue with - /// Safe version of `FullType`. - member FullTypeSafe : FSharpType option - - /// Full name with last part replaced with display name. - member TryGetFullDisplayName : unit -> string option - - /// Full operator compiled name. - member TryGetFullCompiledOperatorNameIdents : unit -> Idents option - - type FSharpAssemblySignature with - /// Safe version of `Entities`. - member TryGetEntities : unit -> seq \ No newline at end of file diff --git a/src/fsharp/service/ServiceCompilerDiagnostics.fs b/src/fsharp/service/ServiceCompilerDiagnostics.fs index 008cb327bb0..abbedea37d2 100644 --- a/src/fsharp/service/ServiceCompilerDiagnostics.fs +++ b/src/fsharp/service/ServiceCompilerDiagnostics.fs @@ -1,14 +1,26 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Diagnostics -type DiagnosticKind = +open FSharp.Compiler.ErrorResolutionHints + +[] +type FSharpDiagnosticKind = | AddIndexerDot | ReplaceWithSuggestion of suggestion:string [] module CompilerDiagnostics = - let getErrorMessage diagnosticKind = + + let GetErrorMessage diagnosticKind = match diagnosticKind with - | AddIndexerDot -> FSComp.SR.addIndexerDot() - | ReplaceWithSuggestion s -> FSComp.SR.replaceWithSuggestion(s) \ No newline at end of file + | FSharpDiagnosticKind.AddIndexerDot -> FSComp.SR.addIndexerDot() + | FSharpDiagnosticKind.ReplaceWithSuggestion s -> FSComp.SR.replaceWithSuggestion(s) + + let GetSuggestedNames (suggestionsF: FSharp.Compiler.ErrorLogger.Suggestions) (unresolvedIdentifier: string) = + let buffer = SuggestionBuffer(unresolvedIdentifier) + if buffer.Disabled then + Seq.empty + else + suggestionsF buffer.Add + buffer :> seq \ No newline at end of file diff --git a/src/fsharp/service/ServiceCompilerDiagnostics.fsi b/src/fsharp/service/ServiceCompilerDiagnostics.fsi index 4916b2c2f6b..fae4c0277b8 100644 --- a/src/fsharp/service/ServiceCompilerDiagnostics.fsi +++ b/src/fsharp/service/ServiceCompilerDiagnostics.fsi @@ -1,13 +1,19 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Diagnostics /// Supported kinds of diagnostics by this service. -type DiagnosticKind = +[] +type FSharpDiagnosticKind = | AddIndexerDot | ReplaceWithSuggestion of suggestion:string /// Exposes compiler diagnostic error messages. module CompilerDiagnostics = + /// Given a DiagnosticKind, returns the string representing the error message for that diagnostic. - val getErrorMessage: diagnosticKind: DiagnosticKind -> string \ No newline at end of file + val GetErrorMessage: diagnosticKind: FSharpDiagnosticKind -> string + + /// Given a set of names, uses and a string representing an unresolved identifier, + /// returns a list of suggested names if there are any feasible candidates. + val GetSuggestedNames: suggestionsF: ((string -> unit) -> unit) -> unresolvedIdentifier: string -> seq diff --git a/src/fsharp/service/ServiceConstants.fs b/src/fsharp/service/ServiceConstants.fs index 1628a277a35..b93d0abdab6 100644 --- a/src/fsharp/service/ServiceConstants.fs +++ b/src/fsharp/service/ServiceConstants.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices [] type FSharpGlyph = diff --git a/src/fsharp/service/ServiceDeclarationLists.fs b/src/fsharp/service/ServiceDeclarationLists.fs index ef9c0b40987..3ea07d55545 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fs +++ b/src/fsharp/service/ServiceDeclarationLists.fs @@ -5,51 +5,473 @@ // type checking and intellisense-like environment-reporting. //-------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops open FSharp.Compiler.Infos -open FSharp.Compiler.NameResolution open FSharp.Compiler.InfoReader +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Symbols +open FSharp.Compiler.Symbols.SymbolHelpers +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.LayoutRender +open FSharp.Compiler.Text.TaggedText +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps + +/// A single data tip display element +[] +type ToolTipElementData = + { MainDescription: TaggedText[] + XmlDoc: FSharpXmlDoc + TypeMapping: TaggedText[] list + Remarks: TaggedText[] option + ParamName : string option } + + static member Create(layout, xml, ?typeMapping, ?paramName, ?remarks) = + { MainDescription=layout; XmlDoc=xml; TypeMapping=defaultArg typeMapping []; ParamName=paramName; Remarks=remarks } + +/// A single data tip display element +[] +type ToolTipElement = + | None + + /// A single type, method, etc with comment. May represent a method overload group. + | Group of elements: ToolTipElementData list + + /// An error occurred formatting this element + | CompositionError of errorText: string + + static member Single(layout, xml, ?typeMapping, ?paramName, ?remarks) = + Group [ ToolTipElementData.Create(layout, xml, ?typeMapping=typeMapping, ?paramName=paramName, ?remarks=remarks) ] + +/// Information for building a data tip box. +type ToolTipText = + /// A list of data tip elements to display. + | ToolTipText of ToolTipElement list + +[] +type CompletionItemKind = + | Field + | Property + | Method of isExtension : bool + | Event + | Argument + | CustomOperation + | Other + +type UnresolvedSymbol = + { FullName: string + DisplayName: string + Namespace: string[] } + +type CompletionItem = + { ItemWithInst: ItemWithInst + Kind: CompletionItemKind + IsOwnMember: bool + MinorPriority: int + Type: TyconRef option + Unresolved: UnresolvedSymbol option } + member x.Item = x.ItemWithInst.Item [] -module EnvMisc3 = - /// dataTipSpinWaitTime limits how long we block the UI thread while a tooltip pops up next to a selected item in an IntelliSense completion list. - /// This time appears to be somewhat amortized by the time it takes the VS completion UI to actually bring up the tooltip after selecting an item in the first place. - let dataTipSpinWaitTime = GetEnvInteger "FCS_ToolTipSpinWaitTime" 5000 +module DeclarationListHelpers = + let mutable ToolTipFault = None + + /// Generate the structured tooltip for a method info + let FormatOverloadsToList (infoReader: InfoReader) m denv (item: ItemWithInst) minfos : ToolTipElement = + ToolTipFault |> Option.iter (fun msg -> + let exn = Error((0, msg), range.Zero) + let ph = PhasedDiagnostic.Create(exn, BuildPhase.TypeCheck) + simulateError ph) + + let layouts = + [ for minfo in minfos -> + let prettyTyparInst, layout = NicePrint.prettyLayoutOfMethInfoFreeStyle infoReader m denv item.TyparInst minfo + let xml = GetXmlCommentForMethInfoItem infoReader m item.Item minfo + let tpsL = FormatTyparMapping denv prettyTyparInst + let layout = toArray layout + let tpsL = List.map toArray tpsL + ToolTipElementData.Create(layout, xml, tpsL) ] + + ToolTipElement.Group layouts + + let CompletionItemDisplayPartialEquality g = + let itemComparer = ItemDisplayPartialEquality g + + { new IPartialEqualityComparer with + member x.InEqualityRelation item = itemComparer.InEqualityRelation item.Item + member x.Equals(item1, item2) = itemComparer.Equals(item1.Item, item2.Item) + member x.GetHashCode item = itemComparer.GetHashCode(item.Item) } + + /// Remove all duplicate items + let RemoveDuplicateCompletionItems g items = + if isNil items then items else + items |> IPartialEqualityComparer.partialDistinctBy (CompletionItemDisplayPartialEquality g) + + /// Filter types that are explicitly suppressed from the IntelliSense (such as uppercase "FSharpList", "Option", etc.) + let RemoveExplicitlySuppressedCompletionItems (g: TcGlobals) (items: CompletionItem list) = + items |> List.filter (fun item -> not (IsExplicitlySuppressed g item.Item)) + + // Remove items containing the same module references + let RemoveDuplicateModuleRefs modrefs = + modrefs |> IPartialEqualityComparer.partialDistinctBy + { new IPartialEqualityComparer with + member x.InEqualityRelation _ = true + member x.Equals(item1, item2) = (fullDisplayTextOfModRef item1 = fullDisplayTextOfModRef item2) + member x.GetHashCode item = hash item.Stamp } + + let OutputFullName isListItem ppF fnF r = + // Only display full names in quick info, not declaration lists or method lists + if not isListItem then + match ppF r with + | None -> emptyL + | Some _ -> wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r) + else emptyL + + let pubpathOfValRef (v: ValRef) = v.PublicPath + + let pubpathOfTyconRef (x: TyconRef) = x.PublicPath + + /// Output the quick info information of a language item + let rec FormatItemDescriptionToToolTipElement isListItem (infoReader: InfoReader) ad m denv (item: ItemWithInst) = + let g = infoReader.g + let amap = infoReader.amap + let denv = SimplerDisplayEnv denv + let xml = GetXmlCommentForItem infoReader m item.Item + match item.Item with + | Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(_, vref, _)) }) -> + // operator with solution + FormatItemDescriptionToToolTipElement isListItem infoReader ad m denv { item with Item = Item.Value vref } + + | Item.Value vref | Item.CustomBuilder (_, vref) -> + let prettyTyparInst, resL = NicePrint.layoutQualifiedValOrMember denv infoReader item.TyparInst vref + let remarks = OutputFullName isListItem pubpathOfValRef fullDisplayTextOfValRefAsLayout vref + let tpsL = FormatTyparMapping denv prettyTyparInst + let tpsL = List.map toArray tpsL + let resL = toArray resL + let remarks = toArray remarks + ToolTipElement.Single(resL, xml, tpsL, remarks=remarks) + + // Union tags (constructors) + | Item.UnionCase(ucinfo, _) -> + let uc = ucinfo.UnionCase + let rty = generalizedTyconRef ucinfo.TyconRef + let recd = uc.RecdFields + let layout = + wordL (tagText (FSComp.SR.typeInfoUnionCase())) ^^ + NicePrint.layoutTyconRef denv ucinfo.TyconRef ^^ + sepL (tagPunctuation ".") ^^ + wordL (tagUnionCase (DecompileOpName uc.Id.idText) |> mkNav uc.DefinitionRange) ^^ + RightL.colon ^^ + (if List.isEmpty recd then emptyL else NicePrint.layoutUnionCases denv infoReader ucinfo.TyconRef recd ^^ WordL.arrow) ^^ + NicePrint.layoutType denv rty + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // Active pattern tag inside the declaration (result) + | Item.ActivePatternResult(apinfo, ty, idx, _) -> + let items = apinfo.ActiveTags + let layout = + wordL (tagText (FSComp.SR.typeInfoActivePatternResult())) ^^ + wordL (tagActivePatternResult (List.item idx items) |> mkNav apinfo.Range) ^^ + RightL.colon ^^ + NicePrint.layoutType denv ty + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // Active pattern tags + | Item.ActivePatternCase apref -> + let v = apref.ActivePatternVal + // Format the type parameters to get e.g. ('a -> 'a) rather than ('?1234 -> '?1234) + let tau = v.TauType + // REVIEW: use _cxs here + let (prettyTyparInst, ptau), _cxs = PrettyTypes.PrettifyInstAndType denv.g (item.TyparInst, tau) + let remarks = OutputFullName isListItem pubpathOfValRef fullDisplayTextOfValRefAsLayout v + let layout = + wordL (tagText (FSComp.SR.typeInfoActiveRecognizer())) ^^ + wordL (tagActivePatternCase apref.Name |> mkNav v.DefinitionRange) ^^ + RightL.colon ^^ + NicePrint.layoutType denv ptau + + let tpsL = FormatTyparMapping denv prettyTyparInst + + let layout = toArray layout + let tpsL = List.map toArray tpsL + let remarks = toArray remarks + ToolTipElement.Single (layout, xml, tpsL, remarks=remarks) + + // F# exception names + | Item.ExnCase ecref -> + let layout = NicePrint.layoutExnDef denv infoReader ecref + let remarks = OutputFullName isListItem pubpathOfTyconRef fullDisplayTextOfExnRefAsLayout ecref + let layout = toArray layout + let remarks = toArray remarks + ToolTipElement.Single (layout, xml, remarks=remarks) + + | Item.RecdField rfinfo when rfinfo.TyconRef.IsExceptionDecl -> + let ty, _ = PrettyTypes.PrettifyType g rfinfo.FieldType + let id = rfinfo.RecdField.Id + let layout = + wordL (tagText (FSComp.SR.typeInfoArgument())) ^^ + wordL (tagParameter id.idText) ^^ + RightL.colon ^^ + NicePrint.layoutType denv ty + let layout = toArray layout + ToolTipElement.Single (layout, xml, paramName = id.idText) + + // F# record field names + | Item.RecdField rfinfo -> + let rfield = rfinfo.RecdField + let ty, _cxs = PrettyTypes.PrettifyType g rfinfo.FieldType + let layout = + NicePrint.layoutTyconRef denv rfinfo.TyconRef ^^ + SepL.dot ^^ + wordL (tagRecordField rfield.DisplayName |> mkNav rfield.DefinitionRange) ^^ + RightL.colon ^^ + NicePrint.layoutType denv ty ^^ + ( + match rfinfo.LiteralValue with + | None -> emptyL + | Some lit -> try WordL.equals ^^ NicePrint.layoutConst denv.g ty lit with _ -> emptyL + ) + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + | Item.UnionCaseField (ucinfo, fieldIndex) -> + let rfield = ucinfo.UnionCase.GetFieldByIndex(fieldIndex) + let fieldTy, _ = PrettyTypes.PrettifyType g rfield.rfield_type + let id = rfield.Id + let layout = + wordL (tagText (FSComp.SR.typeInfoArgument())) ^^ + wordL (tagParameter id.idText) ^^ + RightL.colon ^^ + NicePrint.layoutType denv fieldTy + let layout = toArray layout + ToolTipElement.Single (layout, xml, paramName = id.idText) + + // Not used + | Item.NewDef id -> + let layout = + wordL (tagText (FSComp.SR.typeInfoPatternVariable())) ^^ + wordL (tagUnknownEntity id.idText) + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // .NET fields + | Item.ILField finfo -> + let layout = + wordL (tagText (FSComp.SR.typeInfoField())) ^^ + NicePrint.layoutType denv finfo.ApparentEnclosingAppType ^^ + SepL.dot ^^ + wordL (tagField finfo.FieldName) ^^ + RightL.colon ^^ + NicePrint.layoutType denv (finfo.FieldType(amap, m)) ^^ + ( + match finfo.LiteralValue with + | None -> emptyL + | Some v -> + WordL.equals ^^ + try NicePrint.layoutConst denv.g (finfo.FieldType(infoReader.amap, m)) (CheckExpressions.TcFieldInit m v) with _ -> emptyL + ) + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // .NET events + | Item.Event einfo -> + let rty = PropTypOfEventInfo infoReader m AccessibleFromSomewhere einfo + let rty, _cxs = PrettyTypes.PrettifyType g rty + let layout = + wordL (tagText (FSComp.SR.typeInfoEvent())) ^^ + NicePrint.layoutTyconRef denv einfo.ApparentEnclosingTyconRef ^^ + SepL.dot ^^ + wordL (tagEvent einfo.EventName) ^^ + RightL.colon ^^ + NicePrint.layoutType denv rty + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // F# and .NET properties + | Item.Property(_, pinfo :: _) -> + let layout = NicePrint.prettyLayoutOfPropInfoFreeStyle g amap m denv pinfo + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // Custom operations in queries + | Item.CustomOperation (customOpName, usageText, Some minfo) -> + + // Build 'custom operation: where (bool) + // + // Calls QueryBuilder.Where' + let layout = + wordL (tagText (FSComp.SR.typeInfoCustomOperation())) ^^ + RightL.colon ^^ + ( + match usageText() with + | Some t -> wordL (tagText t) + | None -> + let argTys = ParamNameAndTypesOfUnaryCustomOperation g minfo |> List.map (fun (ParamNameAndType(_, ty)) -> ty) + let argTys, _ = PrettyTypes.PrettifyTypes g argTys + wordL (tagMethod customOpName) ^^ sepListL SepL.space (List.map (fun ty -> LeftL.leftParen ^^ NicePrint.layoutType denv ty ^^ SepL.rightParen) argTys) + ) ^^ + SepL.lineBreak ^^ SepL.lineBreak ^^ + wordL (tagText (FSComp.SR.typeInfoCallsWord())) ^^ + NicePrint.layoutTyconRef denv minfo.ApparentEnclosingTyconRef ^^ + SepL.dot ^^ + wordL (tagMethod minfo.DisplayName) + + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + // F# constructors and methods + | Item.CtorGroup(_, minfos) + | Item.MethodGroup(_, minfos, _) -> + FormatOverloadsToList infoReader m denv item minfos + + // The 'fake' zero-argument constructors of .NET interfaces. + // This ideally should never appear in intellisense, but we do get here in repros like: + // type IFoo = abstract F : int + // type II = IFoo // remove 'type II = ' and quickly hover over IFoo before it gets squiggled for 'invalid use of interface type' + // and in that case we'll just show the interface type name. + | Item.FakeInterfaceCtor ty -> + let ty, _ = PrettyTypes.PrettifyType g ty + let layout = NicePrint.layoutTyconRef denv (tcrefOfAppTy g ty) + let layout = toArray layout + ToolTipElement.Single(layout, xml) + + // The 'fake' representation of constructors of .NET delegate types + | Item.DelegateCtor delty -> + let delty, _cxs = PrettyTypes.PrettifyType g delty + let (SigOfFunctionForDelegate(_, _, _, fty)) = GetSigOfFunctionForDelegate infoReader delty m AccessibleFromSomewhere + let layout = + NicePrint.layoutTyconRef denv (tcrefOfAppTy g delty) ^^ + LeftL.leftParen ^^ + NicePrint.layoutType denv fty ^^ + RightL.rightParen + let layout = toArray layout + ToolTipElement.Single(layout, xml) + + // Types. + | Item.Types(_, TType_app(tcref, _) :: _) + | Item.UnqualifiedType (tcref :: _) -> + let denv = { denv with + // tooltips are space-constrained, so use shorter names + shortTypeNames = true + // tooltips are space-constrained, so don't include xml doc comments + // on types/members. The doc comments for the actual member will still + // be shown in the tip. + showDocumentation = false } + let layout = NicePrint.layoutTyconDefn denv infoReader ad m (* width *) tcref.Deref + let remarks = OutputFullName isListItem pubpathOfTyconRef fullDisplayTextOfTyconRefAsLayout tcref + let layout = toArray layout + let remarks = toArray remarks + ToolTipElement.Single (layout, xml, remarks=remarks) + + // F# Modules and namespaces + | Item.ModuleOrNamespaces(modref :: _ as modrefs) -> + //let os = StringBuilder() + let modrefs = modrefs |> RemoveDuplicateModuleRefs + let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace) + let kind = + if definiteNamespace then FSComp.SR.typeInfoNamespace() + elif modrefs |> List.forall (fun modref -> modref.IsModule) then FSComp.SR.typeInfoModule() + else FSComp.SR.typeInfoNamespaceOrModule() + + let layout = + wordL (tagKeyword kind) ^^ + (if definiteNamespace then tagNamespace (fullDisplayTextOfModRef modref) else (tagModule modref.DemangledModuleOrNamespaceName) + |> mkNav modref.DefinitionRange + |> wordL) + if not definiteNamespace then + let namesToAdd = + ([], modrefs) + ||> Seq.fold (fun st modref -> + match fullDisplayTextOfParentOfModRef modref with + | ValueSome txt -> txt :: st + | _ -> st) + |> Seq.mapi (fun i x -> i, x) + |> Seq.toList + let layout = + layout ^^ + ( + if not (List.isEmpty namesToAdd) then + SepL.lineBreak ^^ + List.fold ( fun s (i, txt) -> + s ^^ + SepL.lineBreak ^^ + wordL (tagText ((if i = 0 then FSComp.SR.typeInfoFromFirst else FSComp.SR.typeInfoFromNext) txt)) + ) emptyL namesToAdd + else + emptyL + ) + let layout = toArray layout + ToolTipElement.Single (layout, xml) + else + let layout = toArray layout + ToolTipElement.Single (layout, xml) + + | Item.AnonRecdField(anon, argTys, i, _) -> + let argTy = argTys.[i] + let nm = anon.SortedNames.[i] + let argTy, _ = PrettyTypes.PrettifyType g argTy + let layout = + wordL (tagText (FSComp.SR.typeInfoAnonRecdField())) ^^ + wordL (tagRecordField nm) ^^ + RightL.colon ^^ + NicePrint.layoutType denv argTy + let layout = toArray layout + ToolTipElement.Single (layout, FSharpXmlDoc.None) + + // Named parameters + | Item.ArgName (id, argTy, _) -> + let argTy, _ = PrettyTypes.PrettifyType g argTy + let layout = + wordL (tagText (FSComp.SR.typeInfoArgument())) ^^ + wordL (tagParameter id.idText) ^^ + RightL.colon ^^ + NicePrint.layoutType denv argTy + let layout = toArray layout + ToolTipElement.Single (layout, xml, paramName = id.idText) + + | Item.SetterArg (_, item) -> + FormatItemDescriptionToToolTipElement isListItem infoReader ad m denv (ItemWithNoInst item) + + | _ -> + ToolTipElement.None + /// Format the structured version of a tooltip for an item + let FormatStructuredDescriptionOfItem isDecl infoReader ad m denv item = + ErrorScope.Protect m + (fun () -> FormatItemDescriptionToToolTipElement isDecl infoReader ad m denv item) + (fun err -> ToolTipElement.CompositionError err) [] /// Represents one parameter for one method (or other item) in a group. -type FSharpMethodGroupItemParameter(name: string, canonicalTypeTextForSorting: string, display: layout, isOptional: bool) = +type MethodGroupItemParameter(name: string, canonicalTypeTextForSorting: string, display: TaggedText[], isOptional: bool) = /// The name of the parameter. - member __.ParameterName = name + member _.ParameterName = name /// A key that can be used for sorting the parameters, used to help sort overloads. - member __.CanonicalTypeTextForSorting = canonicalTypeTextForSorting - - /// The structured representation for the parameter including its name, its type and visual indicators of other - /// information such as whether it is optional. - member __.StructuredDisplay = display + member _.CanonicalTypeTextForSorting = canonicalTypeTextForSorting /// The text to display for the parameter including its name, its type and visual indicators of other /// information such as whether it is optional. - member __.Display = showL display + member _.Display = display /// Is the parameter optional - member __.IsOptional = isOptional + member _.IsOptional = isOptional [] module internal DescriptionListsImpl = @@ -67,34 +489,36 @@ module internal DescriptionListsImpl = NicePrint.stringOfTy denv strippedType let PrettyParamOfRecdField g denv (f: RecdField) = - FSharpMethodGroupItemParameter( - name = f.Name, + let display = NicePrint.prettyLayoutOfType denv f.FormalType + let display = toArray display + MethodGroupItemParameter( + name = f.DisplayNameCore, canonicalTypeTextForSorting = printCanonicalizedTypeName g denv f.FormalType, - // Note: the instantiation of any type parameters is currently incorporated directly into the type - // rather than being returned separately. - display = NicePrint.prettyLayoutOfType denv f.FormalType, + display = display, isOptional=false) let PrettyParamOfUnionCaseField g denv isGenerated (i: int) (f: RecdField) = let initial = PrettyParamOfRecdField g denv f let display = if isGenerated i f then - initial.StructuredDisplay + initial.Display else - // TODO: in this case ucinst is ignored - it gives the instantiation of the type parameters of - // the union type containing this case. - NicePrint.layoutOfParamData denv (ParamData(false, false, false, NotOptional, NoCallerInfo, Some f.Id, ReflectedArgInfo.None, f.FormalType)) - FSharpMethodGroupItemParameter( + let display = NicePrint.layoutOfParamData denv (ParamData(false, false, false, NotOptional, NoCallerInfo, Some f.Id, ReflectedArgInfo.None, f.FormalType)) + toArray display + + MethodGroupItemParameter( name=initial.ParameterName, canonicalTypeTextForSorting=initial.CanonicalTypeTextForSorting, display=display, isOptional=false) let ParamOfParamData g denv (ParamData(_isParamArrayArg, _isInArg, _isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty) as paramData) = - FSharpMethodGroupItemParameter( + let display = NicePrint.layoutOfParamData denv paramData + let display = toArray display + MethodGroupItemParameter( name = (match nmOpt with None -> "" | Some pn -> pn.idText), canonicalTypeTextForSorting = printCanonicalizedTypeName g denv pty, - display = NicePrint.layoutOfParamData denv paramData, + display = display, isOptional=optArgInfo.IsOptional) // TODO this code is similar to NicePrint.fs:formatParamDataToBuffer, refactor or figure out why different? @@ -109,7 +533,7 @@ module internal DescriptionListsImpl = let nm = id.idText // detect parameter type, if ptyOpt is None - this is .NET style optional argument let pty = match ptyOpt with ValueSome x -> x | _ -> pty - (nm, isOptArg, SepL.questionMark ^^ (wordL (TaggedTextOps.tagParameter nm))), pty + (nm, isOptArg, SepL.questionMark ^^ (wordL (tagParameter nm))), pty // Layout an unnamed argument | None, _, _ -> ("", isOptArg, emptyL), pty @@ -119,11 +543,11 @@ module internal DescriptionListsImpl = let prefix = if isParamArrayArg then NicePrint.PrintUtilities.layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute ^^ - wordL (TaggedTextOps.tagParameter nm) ^^ + wordL (tagParameter nm) ^^ RightL.colon //sprintf "%s %s: " (NicePrint.PrintUtilities.layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute |> showL) nm else - wordL (TaggedTextOps.tagParameter nm) ^^ + wordL (tagParameter nm) ^^ RightL.colon //sprintf "%s: " nm (nm, isOptArg, prefix), pty) @@ -136,10 +560,12 @@ module internal DescriptionListsImpl = // Remake the params using the prettified versions let prettyParams = (paramInfo, prettyParamTys, prettyParamTysL) |||> List.map3 (fun (nm, isOptArg, paramPrefix) tau tyL -> - FSharpMethodGroupItemParameter( + let display = paramPrefix ^^ tyL + let display = toArray display + MethodGroupItemParameter( name = nm, canonicalTypeTextForSorting = printCanonicalizedTypeName g denv tau, - display = paramPrefix ^^ tyL, + display = display, isOptional=isOptArg )) @@ -153,13 +579,13 @@ module internal DescriptionListsImpl = // Remake the params using the prettified versions let parameters = - (prettyParamTys, prettyParamTysL) - ||> List.zip - |> List.map (fun (tau, tyL) -> - FSharpMethodGroupItemParameter( + (prettyParamTys, prettyParamTysL) + ||> List.map2 (fun tau tyL -> + let display = toArray tyL + MethodGroupItemParameter( name = "", canonicalTypeTextForSorting = printCanonicalizedTypeName g denv tau, - display = tyL, + display = display, isOptional=false )) @@ -174,17 +600,19 @@ module internal DescriptionListsImpl = let amap = infoReader.amap let g = infoReader.g match item with - | SymbolHelpers.ItemIsWithStaticArguments m g staticParameters -> + | ItemIsWithStaticArguments m g staticParameters -> staticParameters |> Array.map (fun sp -> let ty = Import.ImportProvidedType amap m (sp.PApply((fun x -> x.ParameterType), m)) let spKind = NicePrint.prettyLayoutOfType denv ty let spName = sp.PUntaint((fun sp -> sp.Name), m) let spOpt = sp.PUntaint((fun sp -> sp.IsOptional), m) - FSharpMethodGroupItemParameter( + let display = (if spOpt then SepL.questionMark else emptyL) ^^ wordL (tagParameter spName) ^^ RightL.colon ^^ spKind + let display = toArray display + MethodGroupItemParameter( name = spName, canonicalTypeTextForSorting = showL spKind, - display = (if spOpt then SepL.questionMark else emptyL) ^^ wordL (TaggedTextOps.tagParameter spName) ^^ RightL.colon ^^ spKind, + display = display, //display = sprintf "%s%s: %s" (if spOpt then "?" else "") spName spKind, isOptional=spOpt)) | _ -> [| |] @@ -192,12 +620,12 @@ module internal DescriptionListsImpl = /// Get all the information about parameters and "prettify" the types by choosing nice type variable /// names. This is similar to the other variations on "show me an item" code. This version is - /// is used when presenting groups of methods (see FSharpMethodGroup). It is possible these different + /// is used when presenting groups of methods (see MethodGroup). It is possible these different /// versions could be better unified. let rec PrettyParamsAndReturnTypeOfItem (infoReader:InfoReader) m denv (item: ItemWithInst) = let amap = infoReader.amap let g = infoReader.g - let denv = { SymbolHelpers.SimplerDisplayEnv denv with useColonForReturnType=true} + let denv = { SimplerDisplayEnv denv with useColonForReturnType=true} match item.Item with | Item.Value vref -> let getPrettyParamsOfTypes() = @@ -222,7 +650,7 @@ module internal DescriptionListsImpl = | Some valRefInfo -> // ValReprInfo will exist for top-level syntactic functions // per spec: binding is considered to define a syntactic function if it is either a function or its immediate right-hand-side is a anonymous function - let (_, argInfos, lastRetTy, _) = GetTopValTypeInFSharpForm g valRefInfo vref.Type m + let _, argInfos, lastRetTy, _ = GetTopValTypeInFSharpForm g valRefInfo vref.Type m match argInfos with | [] -> // handles cases like 'let foo = List.map' @@ -303,8 +731,8 @@ module internal DescriptionListsImpl = // for display as part of the method group prettyParams, prettyRetTyL - | Item.CtorGroup(_, (minfo :: _)) - | Item.MethodGroup(_, (minfo :: _), _) -> + | Item.CtorGroup(_, minfo :: _) + | Item.MethodGroup(_, minfo :: _, _) -> let paramDatas = minfo.GetParamDatas(amap, m, minfo.FormalMethodInst) |> List.head let rty = minfo.GetFSharpReturnTy(amap, m, minfo.FormalMethodInst) let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst paramDatas rty @@ -321,7 +749,7 @@ module internal DescriptionListsImpl = | Item.CustomOperation (_, usageText, Some minfo) -> match usageText() with | None -> - let argNamesAndTys = SymbolHelpers.ParamNameAndTypesOfUnaryCustomOperation g minfo + let argNamesAndTys = ParamNameAndTypesOfUnaryCustomOperation g minfo let argTys, _ = PrettyTypes.PrettifyTypes g (argNamesAndTys |> List.map (fun (ParamNameAndType(_, ty)) -> ty)) let paramDatas = (argNamesAndTys, argTys) ||> List.map2 (fun (ParamNameAndType(nmOpt, _)) argTy -> ParamData(false, false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, argTy)) let rty = minfo.GetFSharpReturnTy(amap, m, minfo.FormalMethodInst) @@ -361,13 +789,13 @@ module internal DescriptionListsImpl = match repr with | TFSharpObjectRepr om -> match om.fsobjmodel_kind with - | TTyconClass -> FSharpGlyph.Class - | TTyconInterface -> FSharpGlyph.Interface - | TTyconStruct -> FSharpGlyph.Struct - | TTyconDelegate _ -> FSharpGlyph.Delegate - | TTyconEnum _ -> FSharpGlyph.Enum - | TRecdRepr _ -> FSharpGlyph.Type - | TUnionRepr _ -> FSharpGlyph.Union + | TFSharpClass -> FSharpGlyph.Class + | TFSharpInterface -> FSharpGlyph.Interface + | TFSharpStruct -> FSharpGlyph.Struct + | TFSharpDelegate _ -> FSharpGlyph.Delegate + | TFSharpEnum _ -> FSharpGlyph.Enum + | TFSharpRecdRepr _ -> FSharpGlyph.Type + | TFSharpUnionRepr _ -> FSharpGlyph.Union | TILObjectRepr (TILObjectReprData (_, _, td)) -> if td.IsClass then FSharpGlyph.Class elif td.IsStruct then FSharpGlyph.Struct @@ -377,14 +805,14 @@ module internal DescriptionListsImpl = | TAsmRepr _ -> FSharpGlyph.Typedef | TMeasureableRepr _-> FSharpGlyph.Typedef #if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint _-> FSharpGlyph.Typedef - | TProvidedNamespaceExtensionPoint _-> FSharpGlyph.Typedef + | TProvidedTypeRepr _-> FSharpGlyph.Typedef + | TProvidedNamespaceRepr _-> FSharpGlyph.Typedef #endif | TNoRepr -> FSharpGlyph.Class /// Find the glyph for the given type representation. let typeToGlyph ty = - match tryDestAppTy denv.g ty with + match tryTcrefOfAppTy denv.g ty with | ValueSome tcref -> tcref.TypeReprInfo |> reprToGlyph | _ -> if isStructTupleTy denv.g ty then FSharpGlyph.Struct @@ -408,6 +836,7 @@ module internal DescriptionListsImpl = | Item.ExnCase _ -> FSharpGlyph.Exception | Item.AnonRecdField _ -> FSharpGlyph.Field | Item.RecdField _ -> FSharpGlyph.Field + | Item.UnionCaseField _ -> FSharpGlyph.Field | Item.ILField _ -> FSharpGlyph.Field | Item.Event _ -> FSharpGlyph.Event | Item.Property _ -> FSharpGlyph.Property @@ -466,7 +895,7 @@ module internal DescriptionListsImpl = let pinfo = List.head pinfos if pinfo.IsIndexer then [item] else [] #if !NO_EXTENSIONTYPING - | SymbolHelpers.ItemIsWithStaticArguments m g _ -> + | ItemIsWithStaticArguments m g _ -> // we pretend that provided-types-with-static-args are method-like in order to get ParamInfo for them [item] #endif @@ -479,82 +908,68 @@ module internal DescriptionListsImpl = /// An intellisense declaration [] -type FSharpDeclarationListItem(name: string, nameInCode: string, fullName: string, glyph: FSharpGlyph, info, accessibility: FSharpAccessibility option, +type DeclarationListItem(textInDeclList: string, textInCode: string, fullName: string, glyph: FSharpGlyph, info, accessibility: FSharpAccessibility, kind: CompletionItemKind, isOwnMember: bool, priority: int, isResolved: bool, namespaceToOpen: string option) = + member _.Name = textInDeclList - let mutable descriptionTextHolder: FSharpToolTipText<_> option = None - let mutable task = null + member _.NameInCode = textInCode - member __.Name = name - member __.NameInCode = nameInCode - - member __.StructuredDescriptionTextAsync = - let userOpName = "ToolTip" + member _.Description = match info with - | Choice1Of2 (items: CompletionItem list, infoReader, m, denv, reactor:IReactorOperations) -> - // reactor causes the lambda to execute on the background compiler thread, through the Reactor - reactor.EnqueueAndAwaitOpAsync (userOpName, "StructuredDescriptionTextAsync", name, fun ctok -> - RequireCompilationThread ctok - cancellable.Return(FSharpToolTipText(items |> List.map (fun x -> SymbolHelpers.FormatStructuredDescriptionOfItem true infoReader m denv x.ItemWithInst))) - ) - | Choice2Of2 result -> - async.Return result - - member decl.DescriptionTextAsync = - decl.StructuredDescriptionTextAsync - |> Tooltips.Map Tooltips.ToFSharpToolTipText - - member decl.StructuredDescriptionText = - ErrorScope.Protect Range.range0 - (fun () -> - match descriptionTextHolder with - | Some descriptionText -> descriptionText - | None -> - match info with - | Choice1Of2 _ -> - // The dataTipSpinWaitTime limits how long we block the UI thread while a tooltip pops up next to a selected item in an IntelliSense completion list. - // This time appears to be somewhat amortized by the time it takes the VS completion UI to actually bring up the tooltip after selecting an item in the first place. - if isNull task then - // kick off the actual (non-cooperative) work - task <- System.Threading.Tasks.Task.Factory.StartNew(fun() -> - let text = decl.StructuredDescriptionTextAsync |> Async.RunSynchronously - descriptionTextHolder <- Some text) - - // The dataTipSpinWaitTime limits how long we block the UI thread while a tooltip pops up next to a selected item in an IntelliSense completion list. - // This time appears to be somewhat amortized by the time it takes the VS completion UI to actually bring up the tooltip after selecting an item in the first place. - task.Wait EnvMisc3.dataTipSpinWaitTime |> ignore - match descriptionTextHolder with - | Some text -> text - | None -> FSharpToolTipText [ FSharpStructuredToolTipElement.Single(wordL (tagText (FSComp.SR.loadingDescription())), FSharpXmlDoc.None) ] - - | Choice2Of2 result -> - result - ) - (fun err -> FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError err]) - member decl.DescriptionText = decl.StructuredDescriptionText |> Tooltips.ToFSharpToolTipText - member __.Glyph = glyph - member __.Accessibility = accessibility - member __.Kind = kind - member __.IsOwnMember = isOwnMember - member __.MinorPriority = priority - member __.FullName = fullName - member __.IsResolved = isResolved - member __.NamespaceToOpen = namespaceToOpen + | Choice1Of2 (items: CompletionItem list, infoReader, ad, m, denv) -> + ToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem true infoReader ad m denv x.ItemWithInst)) + | Choice2Of2 result -> + result + + member _.Glyph = glyph + + member _.Accessibility = accessibility + + member _.Kind = kind + + member _.IsOwnMember = isOwnMember + + member _.MinorPriority = priority + + member _.FullName = fullName + + member _.IsResolved = isResolved + + member _.NamespaceToOpen = namespaceToOpen /// A table of declarations for Intellisense completion [] -type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForType: bool, isError: bool) = +type DeclarationListInfo(declarations: DeclarationListItem[], isForType: bool, isError: bool) = static let fsharpNamespace = [|"Microsoft"; "FSharp"|] - member __.Items = declarations - member __.IsForType = isForType - member __.IsError = isError + // Check whether this item looks like an operator. + static let isOperatorItem name (items: CompletionItem list) = + match items with + | [item] -> + match item.Item with + | Item.Value _ | Item.MethodGroup _ | Item.UnionCase _ -> IsOperatorDisplayName name + | _ -> false + | _ -> false + + static let isActivePatternItem (items: CompletionItem list) = + match items with + | [item] -> + match item.Item with + | Item.Value vref -> IsActivePatternName vref.DisplayNameCoreMangled + | _ -> false + | _ -> false + + member _.Items = declarations + + member _.IsForType = isForType + + member _.IsError = isError // Make a 'Declarations' object for a set of selected items - static member Create(infoReader:InfoReader, m: range, denv, getAccessibility, items: CompletionItem list, reactor, currentNamespaceOrModule: string[] option, isAttributeApplicationContext: bool) = + static member Create(infoReader:InfoReader, ad, m: range, denv, getAccessibility: Item -> FSharpAccessibility, items: CompletionItem list, currentNamespace: string[] option, isAttributeApplicationContext: bool) = let g = infoReader.g let isForType = items |> List.exists (fun x -> x.Type.IsSome) - let items = items |> SymbolHelpers.RemoveExplicitlySuppressedCompletionItems g + let items = items |> RemoveExplicitlySuppressedCompletionItems g let tyconRefOptEq tref1 tref2 = match tref1, tref2 with @@ -568,12 +983,12 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT items |> List.map (fun x -> match x.Item with - | Item.Types (_, (TType_app(tcref, _) :: _)) -> { x with MinorPriority = 1 + tcref.TyparsNoRange.Length } + | Item.Types (_, TType_app(tcref, _) :: _) -> { x with MinorPriority = 1 + tcref.TyparsNoRange.Length } // Put delegate ctors after types, sorted by #typars. RemoveDuplicateItems will remove FakeInterfaceCtor and DelegateCtor if an earlier type is also reported with this name | Item.FakeInterfaceCtor (TType_app(tcref, _)) | Item.DelegateCtor (TType_app(tcref, _)) -> { x with MinorPriority = 1000 + tcref.TyparsNoRange.Length } // Put type ctors after types, sorted by #typars. RemoveDuplicateItems will remove DefaultStructCtors if a type is also reported with this name - | Item.CtorGroup (_, (cinfo :: _)) -> { x with MinorPriority = 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length } + | Item.CtorGroup (_, cinfo :: _) -> { x with MinorPriority = 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length } | Item.MethodGroup(_, minfo :: _, _) -> { x with IsOwnMember = tyconRefOptEq x.Type minfo.DeclaringTyconRef } | Item.Property(_, pinfo :: _) -> { x with IsOwnMember = tyconRefOptEq x.Type pinfo.DeclaringTyconRef } | Item.ILField finfo -> { x with IsOwnMember = tyconRefOptEq x.Type finfo.DeclaringTyconRef } @@ -590,13 +1005,13 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT if verbose then dprintf "service.ml: mkDecls: %d found groups after filtering\n" (List.length items); // Group by full name for unresolved items and by display name for resolved ones. - let items = + let decls = items |> List.rev // Prefer items from file check results to ones from referenced assemblies via GetAssemblyContent ("all entities") |> List.sortBy (fun x -> x.Unresolved.IsSome) // Remove all duplicates. We've put the types first, so this removes the DelegateCtor and DefaultStructCtor's. - |> SymbolHelpers.RemoveDuplicateCompletionItems g + |> RemoveDuplicateCompletionItems g |> List.groupBy (fun x -> match x.Unresolved with | Some u -> @@ -604,102 +1019,76 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT | [||] -> u.DisplayName | ns -> (ns |> String.concat ".") + "." + u.DisplayName | None -> x.Item.DisplayName) + |> List.map (fun (_, items) -> let item = items.Head - let name = + let textInDeclList = + match item.Unresolved with + | Some u -> u.DisplayName + | None -> item.Item.DisplayNameCore + let textInCode = match item.Unresolved with | Some u -> u.DisplayName | None -> item.Item.DisplayName - name, items) - - // Filter out operators, active patterns (as values) and the empty list - let items = - // Check whether this item looks like an operator. - let isOperatorItem(name, items: CompletionItem list) = - match items |> List.map (fun x -> x.Item) with - | [Item.Value _ | Item.MethodGroup _ | Item.UnionCase _] -> IsOperatorName name - | _ -> false - - let isActivePatternItem (items: CompletionItem list) = - match items |> List.map (fun x -> x.Item) with - | [Item.Value vref] -> IsActivePatternName (vref.CompiledName infoReader.g.CompilerGlobalState) - | _ -> false - - items |> List.filter (fun (displayName, items) -> - not (isOperatorItem(displayName, items)) && - not (displayName = "[]") && // list shows up as a Type and a UnionCase, only such entity with a symbolic name, but want to filter out of intellisense + textInDeclList, textInCode, items) + + // Filter out operators, active patterns (as values) + |> List.filter (fun (_textInDeclList, textInCode, items) -> + not (isOperatorItem textInCode items) && not (isActivePatternItem items)) - - let decls = - items - |> List.map (fun (displayName, itemsWithSameFullName) -> - match itemsWithSameFullName with - | [] -> failwith "Unexpected empty bag" - | _ -> - let items = - match itemsWithSameFullName |> List.partition (fun x -> x.Unresolved.IsNone) with - | [], unresolved -> unresolved - // if there are resolvable items, throw out unresolved to prevent duplicates like `Set` and `FSharp.Collections.Set`. - | resolved, _ -> resolved - - let item = items.Head - let glyph = GlyphOfItem(denv, item.Item) - - let name, nameInCode = - if displayName.StartsWithOrdinal("( ") && displayName.EndsWithOrdinal(" )") then - let cleanName = displayName.[2..displayName.Length - 3] - cleanName, - if IsOperatorName displayName then cleanName else "``" + cleanName + "``" - else - displayName, - match item.Unresolved with - | Some _ -> displayName - | None -> Lexhelp.Keywords.QuoteIdentifierIfNeeded displayName - let isAttributeItem = lazy (SymbolHelpers.IsAttribute infoReader item.Item) + |> List.map (fun (textInDeclList, textInCode, itemsWithSameFullName) -> + let items = + match itemsWithSameFullName |> List.partition (fun x -> x.Unresolved.IsNone) with + | [], unresolved -> unresolved + // if there are resolvable items, throw out unresolved to prevent duplicates like `Set` and `FSharp.Collections.Set`. + | resolved, _ -> resolved + + let item = items.Head + let glyph = GlyphOfItem(denv, item.Item) - let cutAttributeSuffix (name: string) = - if isAttributeApplicationContext && name <> "Attribute" && name.EndsWithOrdinal("Attribute") && isAttributeItem.Value then - name.[0..name.Length - "Attribute".Length - 1] - else name + let cutAttributeSuffix (name: string) = + if isAttributeApplicationContext && name <> "Attribute" && name.EndsWithOrdinal("Attribute") && IsAttribute infoReader item.Item then + name.[0..name.Length - "Attribute".Length - 1] + else name - let name = cutAttributeSuffix name - let nameInCode = cutAttributeSuffix nameInCode + let textInDeclList = cutAttributeSuffix textInDeclList + let textInCode = cutAttributeSuffix textInCode - let fullName = - match item.Unresolved with - | Some x -> x.FullName - | None -> SymbolHelpers.FullNameOfItem g item.Item + let fullName = + match item.Unresolved with + | Some x -> x.FullName + | None -> FullNameOfItem g item.Item - let namespaceToOpen = - item.Unresolved - |> Option.map (fun x -> x.Namespace) - |> Option.bind (fun ns -> - if ns |> Array.startsWith fsharpNamespace then None - else Some ns) - |> Option.map (fun ns -> - match currentNamespaceOrModule with - | Some currentNs -> - if ns |> Array.startsWith currentNs then - ns.[currentNs.Length..] - else ns - | None -> ns) - |> Option.bind (function - | [||] -> None - | ns -> Some (System.String.Join(".", ns))) - - FSharpDeclarationListItem( - name, nameInCode, fullName, glyph, Choice1Of2 (items, infoReader, m, denv, reactor), getAccessibility item.Item, - item.Kind, item.IsOwnMember, item.MinorPriority, item.Unresolved.IsNone, namespaceToOpen)) - - new FSharpDeclarationListInfo(Array.ofList decls, isForType, false) + let namespaceToOpen = + item.Unresolved + |> Option.map (fun x -> x.Namespace) + |> Option.bind (fun ns -> + if ns |> Array.startsWith fsharpNamespace then None + else Some ns) + |> Option.map (fun ns -> + match currentNamespace with + | Some currentNs -> + if ns |> Array.startsWith currentNs then + ns.[currentNs.Length..] + else ns + | None -> ns) + |> Option.bind (function + | [||] -> None + | ns -> Some (System.String.Join(".", ns))) + + DeclarationListItem( + textInDeclList, textInCode, fullName, glyph, Choice1Of2 (items, infoReader, ad, m, denv), getAccessibility item.Item, + item.Kind, item.IsOwnMember, item.MinorPriority, item.Unresolved.IsNone, namespaceToOpen)) + + DeclarationListInfo(Array.ofList decls, isForType, false) - static member Error msg = - new FSharpDeclarationListInfo( - [| FSharpDeclarationListItem("", "", "", FSharpGlyph.Error, Choice2Of2 (FSharpToolTipText [FSharpStructuredToolTipElement.CompositionError msg]), - None, CompletionItemKind.Other, false, 0, false, None) |], false, true) + static member Error message = + DeclarationListInfo( + [| DeclarationListItem("", "", "", FSharpGlyph.Error, Choice2Of2 (ToolTipText [ToolTipElement.CompositionError message]), + FSharpAccessibility(taccessPublic), CompletionItemKind.Other, false, 0, false, None) |], false, true) - static member Empty = FSharpDeclarationListInfo([| |], false, false) + static member Empty = DeclarationListInfo([| |], false, false) @@ -707,36 +1096,30 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT /// a single, non-overloaded item such as union case or a named function value. // Note: instances of this type do not hold any references to any compiler resources. [] -type FSharpMethodGroupItem(description: FSharpToolTipText, xmlDoc: FSharpXmlDoc, - returnType: layout, parameters: FSharpMethodGroupItemParameter[], - hasParameters: bool, hasParamArrayArg: bool, staticParameters: FSharpMethodGroupItemParameter[]) = - - /// The structured description representation for the method (or other item) - member __.StructuredDescription = description +type MethodGroupItem(description: ToolTipText, xmlDoc: FSharpXmlDoc, + returnType: TaggedText[], parameters: MethodGroupItemParameter[], + hasParameters: bool, hasParamArrayArg: bool, staticParameters: MethodGroupItemParameter[]) = - /// The formatted description text for the method (or other item) - member __.Description = Tooltips.ToFSharpToolTipText description + /// The description representation for the method (or other item) + member _.Description = description /// The documentation for the item - member __.XmlDoc = xmlDoc - - /// The The structured description representation for the method (or other item) - member __.StructuredReturnTypeText = returnType + member _.XmlDoc = xmlDoc - /// The formatted type text for the method (or other item) - member __.ReturnTypeText = showL returnType + /// The return type text for the method (or other item) + member _.ReturnTypeText = returnType /// The parameters of the method in the overload set - member __.Parameters = parameters + member _.Parameters = parameters /// Does the method support an arguments list? This is always true except for static type instantiations like TP<42, "foo">. - member __.HasParameters = hasParameters + member _.HasParameters = hasParameters /// Does the method support a params list arg? - member __.HasParamArrayArg = hasParamArrayArg + member _.HasParamArrayArg = hasParamArrayArg /// Does the type name or method support a static arguments list, like TP<42, "foo"> or conn.CreateCommand<42, "foo">(arg1, arg2)? - member __.StaticParameters = staticParameters + member _.StaticParameters = staticParameters /// A table of methods for Intellisense completion @@ -744,11 +1127,11 @@ type FSharpMethodGroupItem(description: FSharpToolTipText, xmlDoc: FShar // Note: this type does not hold any strong references to any compiler resources, nor does evaluating any of the properties execute any // code on the compiler thread. [] -type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) = +type MethodGroup( name: string, unsortedMethods: MethodGroupItem[] ) = // BUG 413009 : [ParameterInfo] takes about 3 seconds to move from one overload parameter to another // cache allows to avoid recomputing parameterinfo for the same item #if !FX_NO_WEAKTABLE - static let methodOverloadsCache = System.Runtime.CompilerServices.ConditionalWeakTable() + static let methodOverloadsCache = System.Runtime.CompilerServices.ConditionalWeakTable() #endif let methods = @@ -757,7 +1140,7 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) |> Array.map (fun meth -> let parms = meth.Parameters if parms.Length = 1 && parms.[0].CanonicalTypeTextForSorting="Microsoft.FSharp.Core.Unit" then - FSharpMethodGroupItem(meth.StructuredDescription, meth.XmlDoc, meth.StructuredReturnTypeText, [||], true, meth.HasParamArrayArg, meth.StaticParameters) + MethodGroupItem(meth.Description, meth.XmlDoc, meth.ReturnTypeText, [||], true, meth.HasParamArrayArg, meth.StaticParameters) else meth) // Fix the order of methods, to be stable for unit testing. @@ -765,13 +1148,13 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) let parms = meth.Parameters parms.Length, (parms |> Array.map (fun p -> p.CanonicalTypeTextForSorting))) - member __.MethodName = name + member _.MethodName = name - member __.Methods = methods + member _.Methods = methods - static member Create (infoReader: InfoReader, m, denv, items:ItemWithInst list) = + static member Create (infoReader: InfoReader, ad, m, denv, items:ItemWithInst list) = let g = infoReader.g - if isNil items then new FSharpMethodGroup("", [| |]) else + if isNil items then MethodGroup("", [| |]) else let name = items.Head.Item.DisplayName let methods = @@ -790,7 +1173,7 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) (fun () -> PrettyParamsAndReturnTypeOfItem infoReader m denv { item with Item = flatItem }) (fun err -> [], wordL (tagText err)) - let description = FSharpToolTipText [SymbolHelpers.FormatStructuredDescriptionOfItem true infoReader m denv { item with Item = flatItem }] + let description = ToolTipText [FormatStructuredDescriptionOfItem true infoReader ad m denv { item with Item = flatItem }] let hasParamArrayArg = match flatItem with @@ -801,14 +1184,15 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) let hasStaticParameters = match flatItem with #if !NO_EXTENSIONTYPING - | SymbolHelpers.ItemIsProvidedTypeWithStaticArguments m g _ -> false + | ItemIsProvidedTypeWithStaticArguments m g _ -> false #endif | _ -> true - FSharpMethodGroupItem( + let prettyRetTyL = toArray prettyRetTyL + MethodGroupItem( description = description, returnType = prettyRetTyL, - xmlDoc = SymbolHelpers.GetXmlCommentForItem infoReader m flatItem, + xmlDoc = GetXmlCommentForItem infoReader m flatItem, parameters = (prettyParams |> Array.ofList), hasParameters = hasStaticParameters, hasParamArrayArg = hasParamArrayArg, @@ -824,7 +1208,7 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) yield! methods |] - new FSharpMethodGroup(name, methods) + MethodGroup(name, methods) diff --git a/src/fsharp/service/ServiceDeclarationLists.fsi b/src/fsharp/service/ServiceDeclarationLists.fsi index ae8171bfb00..d8a302cef94 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fsi +++ b/src/fsharp/service/ServiceDeclarationLists.fsi @@ -1,56 +1,126 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//---------------------------------------------------------------------------- -// API for declaration lists and method overload lists +/// API for declaration lists and method overload lists +namespace FSharp.Compiler.EditorServices -namespace FSharp.Compiler.SourceCodeServices - -open FSharp.Compiler.Range open FSharp.Compiler.NameResolution open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tastops +open FSharp.Compiler.Symbols +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.AccessibilityLogic + +/// A single data tip display element +[] +type public ToolTipElementData = + { + MainDescription: TaggedText[] + + XmlDoc: FSharpXmlDoc + + /// typar instantiation text, to go after xml + TypeMapping: TaggedText[] list + + /// Extra text, goes at the end + Remarks: TaggedText[] option + + /// Parameter name + ParamName: string option + } + +/// A single tool tip display element +// +// Note: instances of this type do not hold any references to any compiler resources. +[] +type public ToolTipElement = + | None + + /// A single type, method, etc with comment. May represent a method overload group. + | Group of elements: ToolTipElementData list + + /// An error occurred formatting this element + | CompositionError of errorText: string + + static member Single: layout: TaggedText[] * xml: FSharpXmlDoc * ?typeMapping: TaggedText[] list * ?paramName: string * ?remarks: TaggedText[] -> ToolTipElement + +/// Information for building a tool tip box. +// +// Note: instances of this type do not hold any references to any compiler resources. +type public ToolTipText = + + /// A list of data tip elements to display. + | ToolTipText of ToolTipElement list + +[] +type public CompletionItemKind = + | Field + | Property + | Method of isExtension: bool + | Event + | Argument + | CustomOperation + | Other + +type public UnresolvedSymbol = + { + FullName: string + + DisplayName: string + Namespace: string[] + } + +type internal CompletionItem = + { + ItemWithInst: ItemWithInst + + Kind: CompletionItemKind + + IsOwnMember: bool + + MinorPriority: int + + Type: TyconRef option + + Unresolved: UnresolvedSymbol option + } + member Item: Item [] /// Represents a declaration in F# source code, with information attached ready for display by an editor. /// Returned by GetDeclarations. // // Note: this type holds a weak reference to compiler resources. -type public FSharpDeclarationListItem = - /// Get the display name for the declaration. - member Name : string - - /// Get the name for the declaration as it's presented in source code. - member NameInCode : string - - /// Get the description text for the declaration. Computing this property may require using compiler - /// resources and may trigger execution of a type provider method to retrieve documentation. - /// - /// May return "Loading..." if timeout occurs - member StructuredDescriptionText : FSharpStructuredToolTipText - - member DescriptionText : FSharpToolTipText +type public DeclarationListItem = + /// Get the text to display in the declaration list for the declaration. + member Name: string - /// Get the description text, asynchronously. Never returns "Loading...". - member StructuredDescriptionTextAsync : Async + /// Get the text for the declaration as it's to be inserted into source code. + member NameInCode: string - member DescriptionTextAsync : Async + /// Get the description + member Description: ToolTipText - member Glyph : FSharpGlyph + /// Get the glyph to use + member Glyph: FSharpGlyph - member Accessibility : FSharpAccessibility option + /// Get the accessibility of the item + member Accessibility: FSharpAccessibility - member Kind : CompletionItemKind + /// Get the completion kind of the item + member Kind: CompletionItemKind - member IsOwnMember : bool + member IsOwnMember: bool - member MinorPriority : int + member MinorPriority: int - member FullName : string + member FullName: string - member IsResolved : bool + member IsResolved: bool - member NamespaceToOpen : string option + member NamespaceToOpen: string option [] @@ -58,24 +128,33 @@ type public FSharpDeclarationListItem = /// Returned by GetDeclarations. // // Note: this type holds a weak reference to compiler resources. -type public FSharpDeclarationListInfo = +type public DeclarationListInfo = - member Items : FSharpDeclarationListItem[] + member Items: DeclarationListItem[] - member IsForType : bool + member IsForType: bool - member IsError : bool + member IsError: bool // Implementation details used by other code in the compiler - static member internal Create : infoReader:InfoReader * m:range * denv:DisplayEnv * getAccessibility:(Item -> FSharpAccessibility option) * items:CompletionItem list * reactor:IReactorOperations * currentNamespace:string[] option * isAttributeApplicationContex:bool -> FSharpDeclarationListInfo + static member internal Create: + infoReader:InfoReader * + ad:AccessorDomain * + m:range * + denv:DisplayEnv * + getAccessibility:(Item -> FSharpAccessibility) * + items:CompletionItem list * + currentNamespace:string[] option * + isAttributeApplicationContext:bool + -> DeclarationListInfo - static member internal Error : message:string -> FSharpDeclarationListInfo + static member internal Error: message:string -> DeclarationListInfo - static member Empty : FSharpDeclarationListInfo + static member Empty: DeclarationListInfo /// Represents one parameter for one method (or other item) in a group. [] -type public FSharpMethodGroupItemParameter = +type public MethodGroupItemParameter = /// The name of the parameter. member ParameterName: string @@ -83,13 +162,9 @@ type public FSharpMethodGroupItemParameter = /// A key that can be used for sorting the parameters, used to help sort overloads. member CanonicalTypeTextForSorting: string - /// The structured representation for the parameter including its name, its type and visual indicators of other + /// The representation for the parameter including its name, its type and visual indicators of other /// information such as whether it is optional. - member StructuredDisplay: Layout - - /// The text to display for the parameter including its name, its type and visual indicators of other - /// information such as whether it is optional. - member Display: string + member Display: TaggedText[] /// Is the parameter optional member IsOptional: bool @@ -97,25 +172,19 @@ type public FSharpMethodGroupItemParameter = /// Represents one method (or other item) in a method group. The item may represent either a method or /// a single, non-overloaded item such as union case or a named function value. [] -type public FSharpMethodGroupItem = +type public MethodGroupItem = /// The documentation for the item - member XmlDoc : FSharpXmlDoc - - /// The structured description representation for the method (or other item) - member StructuredDescription : FSharpStructuredToolTipText - - /// The formatted description text for the method (or other item) - member Description : FSharpToolTipText + member XmlDoc: FSharpXmlDoc - /// The The structured description representation for the method (or other item) - member StructuredReturnTypeText: Layout + /// The description representation for the method (or other item) + member Description: ToolTipText - /// The formatted type text for the method (or other item) - member ReturnTypeText: string + /// The tagged text for the return type for the method (or other item) + member ReturnTypeText: TaggedText[] /// The parameters of the method in the overload set - member Parameters: FSharpMethodGroupItemParameter[] + member Parameters: MethodGroupItemParameter[] /// Does the method support an arguments list? This is always true except for static type instantiations like TP<42,"foo">. member HasParameters: bool @@ -124,19 +193,28 @@ type public FSharpMethodGroupItem = member HasParamArrayArg: bool /// Does the type name or method support a static arguments list, like TP<42,"foo"> or conn.CreateCommand<42, "foo">(arg1, arg2)? - member StaticParameters: FSharpMethodGroupItemParameter[] + member StaticParameters: MethodGroupItemParameter[] /// Represents a group of methods (or other items) returned by GetMethods. [] -type public FSharpMethodGroup = +type public MethodGroup = - internal new : string * FSharpMethodGroupItem[] -> FSharpMethodGroup + internal new: string * MethodGroupItem[] -> MethodGroup /// The shared name of the methods (or other items) in the group member MethodName: string /// The methods (or other items) in the group - member Methods: FSharpMethodGroupItem[] + member Methods: MethodGroupItem[] + + static member internal Create: InfoReader * AccessorDomain * range * DisplayEnv * ItemWithInst list -> MethodGroup + +module internal DeclarationListHelpers = + val FormatStructuredDescriptionOfItem: isDecl:bool -> InfoReader -> AccessorDomain -> range -> DisplayEnv -> ItemWithInst -> ToolTipElement + + val RemoveDuplicateCompletionItems: TcGlobals -> CompletionItem list -> CompletionItem list + + val RemoveExplicitlySuppressedCompletionItems: TcGlobals -> CompletionItem list -> CompletionItem list - static member internal Create : InfoReader * range * DisplayEnv * ItemWithInst list -> FSharpMethodGroup + val mutable ToolTipFault: string option diff --git a/src/fsharp/service/ServiceErrorResolutionHints.fs b/src/fsharp/service/ServiceErrorResolutionHints.fs index 5059c2a8979..2998bdf4746 100644 --- a/src/fsharp/service/ServiceErrorResolutionHints.fs +++ b/src/fsharp/service/ServiceErrorResolutionHints.fs @@ -1,14 +1,8 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Diagnostics open FSharp.Compiler.ErrorResolutionHints module ErrorResolutionHints = - let getSuggestedNames (suggestionsF: FSharp.Compiler.ErrorLogger.Suggestions) (unresolvedIdentifier: string) = - let buffer = SuggestionBuffer(unresolvedIdentifier) - if buffer.Disabled then - Seq.empty - else - suggestionsF buffer.Add - buffer :> seq \ No newline at end of file + diff --git a/src/fsharp/service/ServiceErrorResolutionHints.fsi b/src/fsharp/service/ServiceErrorResolutionHints.fsi index 77617a09165..4c9192bdf5e 100644 --- a/src/fsharp/service/ServiceErrorResolutionHints.fsi +++ b/src/fsharp/service/ServiceErrorResolutionHints.fsi @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Diagnostics /// Exposes the string distance algorithm used to suggest names for mistyped identifiers. module ErrorResolutionHints = + /// Given a set of names, uses and a string representing an unresolved identifier, /// returns a list of suggested names if there are any feasible candidates. - val getSuggestedNames: suggestionsF: ((string -> unit) -> unit) -> unresolvedIdentifier: string -> seq + val GetSuggestedNames: suggestionsF: ((string -> unit) -> unit) -> unresolvedIdentifier: string -> seq diff --git a/src/fsharp/service/ServiceInterfaceStubGenerator.fs b/src/fsharp/service/ServiceInterfaceStubGenerator.fs index dfaa9a537ae..f22e061d18d 100644 --- a/src/fsharp/service/ServiceInterfaceStubGenerator.fs +++ b/src/fsharp/service/ServiceInterfaceStubGenerator.fs @@ -1,63 +1,57 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices open System open System.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.AbstractIL.Internal.Library - -#if !FX_NO_INDENTED_TEXT_WRITER +open Internal.Utilities.Library +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Tokenization + [] module internal CodeGenerationUtils = open System.IO open System.CodeDom.Compiler - type ColumnIndentedTextWriter() = let stringWriter = new StringWriter() let indentWriter = new IndentedTextWriter(stringWriter, " ") - member __.Write(s: string) = + member _.Write(s: string) = indentWriter.Write("{0}", s) - member __.Write(s: string, [] objs: obj []) = + member _.Write(s: string, [] objs: obj []) = indentWriter.Write(s, objs) - member __.WriteLine(s: string) = + member _.WriteLine(s: string) = indentWriter.WriteLine("{0}", s) - member __.WriteLine(s: string, [] objs: obj []) = + member _.WriteLine(s: string, [] objs: obj []) = indentWriter.WriteLine(s, objs) member x.WriteBlankLines count = for _ in 0 .. count - 1 do x.WriteLine "" - member __.Indent i = + member _.Indent i = indentWriter.Indent <- indentWriter.Indent + i - member __.Unindent i = + member _.Unindent i = indentWriter.Indent <- max 0 (indentWriter.Indent - i) - member __.Dump() = + member _.Dump() = indentWriter.InnerWriter.ToString() interface IDisposable with - member __.Dispose() = + member _.Dispose() = stringWriter.Dispose() indentWriter.Dispose() - let (|IndexerArg|) = function - | SynIndexerArg.Two(e1, _, e2, _, _, _) -> [e1; e2] - | SynIndexerArg.One (e, _, _) -> [e] - - let (|IndexerArgList|) xs = - List.collect (|IndexerArg|) xs - /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException let rec (|Sequentials|_|) = function | SynExpr.Sequential (_, _, e, Sequentials es, _) -> @@ -69,7 +63,7 @@ module internal CodeGenerationUtils = /// Represent environment where a captured identifier should be renamed type NamesWithIndices = Map> - let keywordSet = set PrettyNaming.KeywordNames + let keywordSet = set FSharpKeywords.KeywordNames /// Rename a given argument if the identifier has been used let normalizeArgName (namesWithIndices: NamesWithIndices) nm = @@ -102,18 +96,20 @@ module internal CodeGenerationUtils = /// Capture information about an interface in ASTs [] type InterfaceData = - | Interface of SynType * SynMemberDefns option - | ObjExpr of SynType * SynBinding list + | Interface of interfaceType: SynType * memberDefns: SynMemberDefns option + | ObjExpr of objType: SynType * bindings: SynBinding list + member x.Range = match x with | InterfaceData.Interface(ty, _) -> ty.Range | InterfaceData.ObjExpr(ty, _) -> ty.Range + member x.TypeParameters = match x with - | InterfaceData.Interface(ty, _) - | InterfaceData.ObjExpr(ty, _) -> + | InterfaceData.Interface(StripParenTypes ty, _) + | InterfaceData.ObjExpr(StripParenTypes ty, _) -> let rec (|RationalConst|) = function | SynRationalConst.Integer i -> string i @@ -123,11 +119,11 @@ type InterfaceData = sprintf "- %s" s let rec (|TypeIdent|_|) = function - | SynType.Var(SynTypar.Typar(s, req, _), _) -> + | SynType.Var(SynTypar(s, req, _), _) -> match req with - | NoStaticReq -> + | TyparStaticReq.None -> Some ("'" + s.idText) - | HeadTypeStaticReq -> + | TyparStaticReq.HeadType -> Some ("^" + s.idText) | SynType.LongIdent(LongIdentWithDots(xs, _)) -> xs |> Seq.map (fun x -> x.idText) |> String.concat "." |> Some @@ -153,11 +149,13 @@ type InterfaceData = | SynType.AnonRecd (_, ts, _) -> Some (ts |> Seq.choose (snd >> (|TypeIdent|_|)) |> String.concat "; ") | SynType.Array(dimension, TypeIdent typeName, _) -> - Some (sprintf "%s [%s]" typeName (new String(',', dimension-1))) + Some (sprintf "%s [%s]" typeName (String(',', dimension-1))) | SynType.MeasurePower(TypeIdent typeName, RationalConst power, _) -> Some (sprintf "%s^%s" typeName power) | SynType.MeasureDivide(TypeIdent numerator, TypeIdent denominator, _) -> Some (sprintf "%s/%s" numerator denominator) + | SynType.Paren(TypeIdent typeName, _) -> + Some typeName | _ -> None match ty with @@ -172,18 +170,25 @@ module InterfaceStubGenerator = type internal Context = { Writer: ColumnIndentedTextWriter + /// Map generic types to specific instances for specialized interface implementation TypeInstantations: Map + /// Data for interface instantiation ArgInstantiations: (FSharpGenericParameter * FSharpType) seq + /// Indentation inside method bodies Indentation: int + /// Object identifier of the interface e.g. 'x', 'this', '__', etc. ObjectIdent: string + /// A list of lines represents skeleton of each member MethodBody: string [] + /// Context in order to display types in the short form DisplayContext: FSharpDisplayContext + } // Adapt from MetadataFormat module in FSharp.Formatting @@ -219,7 +224,7 @@ module InterfaceStubGenerator = let nm, namesWithIndices = normalizeArgName namesWithIndices nm // Detect an optional argument - let isOptionalArg = Symbol.hasAttribute arg.Attributes + let isOptionalArg = arg.HasAttribute() let argName = if isOptionalArg then "?" + nm else nm (if hasTypeAnnotation && argName <> "()" then argName + ": " + formatType ctx arg.Type @@ -296,7 +301,7 @@ module InterfaceStubGenerator = else displayName let internal isEventMember (m: FSharpMemberOrFunctionOrValue) = - m.IsEvent || Symbol.hasAttribute m.Attributes + m.IsEvent || m.HasAttribute() let internal formatMember (ctx: Context) m verboseMode = let getParamArgs (argInfos: FSharpParameter list list) (ctx: Context) (v: FSharpMemberOrFunctionOrValue) = @@ -328,7 +333,7 @@ module InterfaceStubGenerator = | _, true, _, name -> name + parArgs // Ordinary functions or values | false, _, _, name when - not (Symbol.hasAttribute v.ApparentEnclosingEntity.Attributes) -> + not (v.ApparentEnclosingEntity.HasAttribute()) -> name + " " + parArgs // Ordinary static members or things (?) that require fully qualified access | _, _, _, name -> name + parArgs @@ -357,10 +362,10 @@ module InterfaceStubGenerator = match m with | MemberInfo.PropertyGetSet(getter, setter) -> - let (usage, modifiers, getterArgInfos, retType) = preprocess ctx getter + let usage, modifiers, getterArgInfos, retType = preprocess ctx getter let closeDeclaration = closeDeclaration retType let writeImplementation = writeImplementation ctx - let (_, _, setterArgInfos, _) = preprocess ctx setter + let _, _, setterArgInfos, _ = preprocess ctx setter let writer = ctx.Writer writer.Write("member ") for modifier in modifiers do @@ -387,7 +392,7 @@ module InterfaceStubGenerator = writer.Unindent ctx.Indentation | MemberInfo.Member v -> - let (usage, modifiers, argInfos, retType) = preprocess ctx v + let usage, modifiers, argInfos, retType = preprocess ctx v let closeDeclaration = closeDeclaration retType let writeImplementation = writeImplementation ctx let writer = ctx.Writer @@ -482,10 +487,10 @@ module InterfaceStubGenerator = |> Seq.distinct /// Get members in the decreasing order of inheritance chain - let getInterfaceMembers (e: FSharpEntity) = + let GetInterfaceMembers (entity: FSharpEntity) = seq { - for (iface, instantiations) in getInterfaces e do - yield! iface.TryGetMembersFunctionsAndValues + for iface, instantiations in getInterfaces entity do + yield! iface.TryGetMembersFunctionsAndValues() |> Seq.choose (fun m -> // Use this hack when FCS doesn't return enough information on .NET properties and events if m.IsProperty || m.IsEventAddMethod || m.IsEventRemoveMethod then @@ -494,8 +499,8 @@ module InterfaceStubGenerator = } /// Check whether an interface is empty - let hasNoInterfaceMember e = - getInterfaceMembers e |> Seq.isEmpty + let HasNoInterfaceMember entity = + GetInterfaceMembers entity |> Seq.isEmpty let internal (|LongIdentPattern|_|) = function | SynPat.LongIdent(LongIdentWithDots(xs, _), _, _, _, _, _) -> @@ -509,14 +514,14 @@ module InterfaceStubGenerator = // On merged properties (consisting both getters and setters), they have the same range values, // so we use 'get_' and 'set_' prefix to ensure corresponding symbols are retrieved correctly. let internal (|MemberNameAndRange|_|) = function - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = MemberKind.PropertyGet -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = SynMemberKind.PropertyGet -> if name.StartsWithOrdinal("get_") then Some(name, range) else Some("get_" + name, range) - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = MemberKind.PropertySet -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = SynMemberKind.PropertySet -> if name.StartsWithOrdinal("set_") then Some(name, range) else Some("set_" + name, range) - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) -> Some(name, range) | _ -> None @@ -524,12 +529,13 @@ module InterfaceStubGenerator = /// Get associated member names and ranges /// In case of properties, intrinsic ranges might not be correct for the purpose of getting /// positions of 'member', which indicate the indentation for generating new members - let getMemberNameAndRanges = function + let GetMemberNameAndRanges interfaceData = + match interfaceData with | InterfaceData.Interface(_, None) -> [] | InterfaceData.Interface(_, Some memberDefns) -> memberDefns - |> Seq.choose (function (SynMemberDefn.Member(binding, _)) -> Some binding | _ -> None) + |> Seq.choose (function SynMemberDefn.Member(binding, _) -> Some binding | _ -> None) |> Seq.choose (|MemberNameAndRange|_|) |> Seq.toList | InterfaceData.ObjExpr(_, bindings) -> @@ -546,7 +552,7 @@ module InterfaceStubGenerator = /// (1) Crack ASTs to get member names and their associated ranges /// (2) Check symbols of those members based on ranges /// (3) If any symbol found, capture its member signature - let getImplementedMemberSignatures (getMemberByLocation: string * range -> Async) displayContext interfaceData = + let GetImplementedMemberSignatures (getMemberByLocation: string * range -> FSharpSymbolUse option) displayContext interfaceData = let formatMemberSignature (symbolUse: FSharpSymbolUse) = match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as m -> @@ -564,23 +570,23 @@ module InterfaceStubGenerator = //fail "Should only accept symbol uses of members." None async { - let! symbolUses = - getMemberNameAndRanges interfaceData + let symbolUses = + GetMemberNameAndRanges interfaceData |> List.toArray - |> Array.mapAsync getMemberByLocation + |> Array.map getMemberByLocation return symbolUses |> Array.choose (Option.bind formatMemberSignature >> Option.map String.Concat) |> Set.ofArray } /// Check whether an entity is an interface or type abbreviation of an interface - let rec isInterface (e: FSharpEntity) = - e.IsInterface || (e.IsFSharpAbbreviation && isInterface e.AbbreviatedType.TypeDefinition) + let rec IsInterface (entity: FSharpEntity) = + entity.IsInterface || (entity.IsFSharpAbbreviation && IsInterface entity.AbbreviatedType.TypeDefinition) /// Generate stub implementation of an interface at a start column - let formatInterface startColumn indentation (typeInstances: string []) objectIdent + let FormatInterface startColumn indentation (typeInstances: string []) objectIdent (methodBody: string) (displayContext: FSharpDisplayContext) excludedMemberSignatures (e: FSharpEntity) verboseMode = - Debug.Assert(isInterface e, "The entity should be an interface.") + Debug.Assert(IsInterface e, "The entity should be an interface.") let lines = String.getLines methodBody use writer = new ColumnIndentedTextWriter() let typeParams = Seq.map getTypeParameterName e.GenericParameters @@ -601,7 +607,7 @@ module InterfaceStubGenerator = let ctx = { Writer = writer; TypeInstantations = instantiations; ArgInstantiations = Seq.empty; Indentation = indentation; ObjectIdent = objectIdent; MethodBody = lines; DisplayContext = displayContext } let missingMembers = - getInterfaceMembers e + GetInterfaceMembers e |> Seq.groupBy (fun (m, insts) -> match m with | _ when isEventMember m -> @@ -665,7 +671,7 @@ module InterfaceStubGenerator = writer.Dump() /// Find corresponding interface declaration at a given position - let tryFindInterfaceDeclaration (pos: pos) (parsedInput: ParsedInput) = + let TryFindInterfaceDeclaration (pos: pos) (parsedInput: ParsedInput) = let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = List.tryPick walkSynModuleOrNamespace moduleOrNamespaceList @@ -699,7 +705,7 @@ module InterfaceStubGenerator = | SynModuleDecl.Open _ -> None - and walkSynTypeDefn(TypeDefn(_componentInfo, representation, members, range)) = + and walkSynTypeDefn(SynTypeDefn(_componentInfo, representation, members, _, range)) = if not <| rangeContainsPos range pos then None else @@ -744,7 +750,7 @@ module InterfaceStubGenerator = | SynMemberDefn.Inherit _ -> None | SynMemberDefn.ImplicitInherit (_, expr, _, _) -> walkExpr expr - and walkBinding (Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, _retTy, expr, _bindingRange, _seqPoint)) = + and walkBinding (SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, _retTy, expr, _bindingRange, _seqPoint)) = walkExpr expr and walkExpr expr = @@ -779,7 +785,7 @@ module InterfaceStubGenerator = if rangeContainsPos ty.Range pos then Some (InterfaceData.ObjExpr(ty, binds)) else - ifaces |> List.tryPick (fun (InterfaceImpl(ty, binds, range)) -> + ifaces |> List.tryPick (fun (SynInterfaceImpl(ty, binds, range)) -> if rangeContainsPos range pos then Some (InterfaceData.ObjExpr(ty, binds)) else None) @@ -795,18 +801,18 @@ module InterfaceStubGenerator = | SynExpr.For (_sequencePointInfoForForLoop, _ident, synExpr1, _, synExpr2, synExpr3, _range) -> List.tryPick walkExpr [synExpr1; synExpr2; synExpr3] - | SynExpr.ArrayOrListOfSeqExpr (_, synExpr, _range) -> + | SynExpr.ArrayOrListComputed (_, synExpr, _range) -> walkExpr synExpr - | SynExpr.CompExpr (_, _, synExpr, _range) -> + | SynExpr.ComputationExpr (_, synExpr, _range) -> walkExpr synExpr - | SynExpr.Lambda (_, _, _synSimplePats, synExpr, _range) -> + | SynExpr.Lambda (_, _, _synSimplePats, _, synExpr, _, _range) -> walkExpr synExpr | SynExpr.MatchLambda (_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) -> - synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e) + synMatchClauseList |> List.tryPick (fun (SynMatchClause(resultExpr = e)) -> walkExpr e) | SynExpr.Match (_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> walkExpr synExpr - |> Option.orElse (synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e)) + |> Option.orElse (synMatchClauseList |> List.tryPick (fun (SynMatchClause(resultExpr = e)) -> walkExpr e)) | SynExpr.Lazy (synExpr, _range) -> walkExpr synExpr @@ -833,14 +839,14 @@ module InterfaceStubGenerator = | Sequentials exprs -> List.tryPick walkExpr exprs - | SynExpr.IfThenElse (synExpr1, synExpr2, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> + | SynExpr.IfThenElse (_, _, synExpr1, _, synExpr2, _, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> match synExprOpt with | Some synExpr3 -> List.tryPick walkExpr [synExpr1; synExpr2; synExpr3] | None -> List.tryPick walkExpr [synExpr1; synExpr2] - | SynExpr.Ident (_ident) -> + | SynExpr.Ident _ident -> None | SynExpr.LongIdent (_, _longIdent, _altNameRefCell, _range) -> @@ -858,13 +864,11 @@ module InterfaceStubGenerator = | SynExpr.Set (synExpr1, synExpr2, _range) -> List.tryPick walkExpr [synExpr1; synExpr2] - | SynExpr.DotIndexedGet (synExpr, IndexerArgList synExprList, _range, _range2) -> - Option.orElse (walkExpr synExpr) (List.tryPick walkExpr synExprList) + | SynExpr.DotIndexedGet (synExpr, indexArgs, _range, _range2) -> + Option.orElse (walkExpr synExpr) (walkExpr indexArgs) - | SynExpr.DotIndexedSet (synExpr1, IndexerArgList synExprList, synExpr2, _, _range, _range2) -> - [ yield synExpr1 - yield! synExprList - yield synExpr2 ] + | SynExpr.DotIndexedSet (synExpr1, indexArgs, synExpr2, _, _range, _range2) -> + [ synExpr1; indexArgs; synExpr2 ] |> List.tryPick walkExpr | SynExpr.JoinIn (synExpr1, _range, synExpr2, _range2) -> @@ -887,8 +891,8 @@ module InterfaceStubGenerator = | SynExpr.TraitCall (_synTyparList, _synMemberSig, synExpr, _range) -> walkExpr synExpr - | SynExpr.Null (_range) - | SynExpr.ImplicitZero (_range) -> + | SynExpr.Null _range + | SynExpr.ImplicitZero _range -> None | SynExpr.YieldOrReturn (_, synExpr, _range) @@ -896,8 +900,14 @@ module InterfaceStubGenerator = | SynExpr.DoBang (synExpr, _range) -> walkExpr synExpr - | SynExpr.LetOrUseBang (_sequencePointInfoForBinding, _, _, _synPat, synExpr1, synExpr2, _range) -> - List.tryPick walkExpr [synExpr1; synExpr2] + | SynExpr.LetOrUseBang (_sequencePointInfoForBinding, _, _, _synPat, synExpr1, synExprAndBangs, synExpr2, _range) -> + [ + yield synExpr1 + for _,_,_,_,eAndBang,_ in synExprAndBangs do + yield eAndBang + yield synExpr2 + ] + |> List.tryPick walkExpr | SynExpr.LibraryOnlyILAssembly _ | SynExpr.LibraryOnlyStaticOptimization _ @@ -918,4 +928,3 @@ module InterfaceStubGenerator = None | ParsedInput.ImplFile input -> walkImplFileInput input -#endif diff --git a/src/fsharp/service/ServiceInterfaceStubGenerator.fsi b/src/fsharp/service/ServiceInterfaceStubGenerator.fsi index 4212449408f..c75748f962a 100644 --- a/src/fsharp/service/ServiceInterfaceStubGenerator.fsi +++ b/src/fsharp/service/ServiceInterfaceStubGenerator.fsi @@ -1,41 +1,43 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices + +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices - -#if !FX_NO_INDENTED_TEXT_WRITER /// Capture information about an interface in ASTs [] type InterfaceData = - | Interface of SynType * SynMemberDefns option - | ObjExpr of SynType * SynBinding list - member Range : range - member TypeParameters : string[] + | Interface of interfaceType: SynType * memberDefns: SynMemberDefns option + | ObjExpr of objType: SynType * bindings: SynBinding list + + member Range: range + + member TypeParameters: string[] module InterfaceStubGenerator = /// Get members in the decreasing order of inheritance chain - val getInterfaceMembers : FSharpEntity -> seq> + val GetInterfaceMembers: entity: FSharpEntity -> seq> /// Check whether an interface is empty - val hasNoInterfaceMember : FSharpEntity -> bool + val HasNoInterfaceMember: entity: FSharpEntity -> bool - /// Get associated member names and ranges + /// Get associated member names and ranges. /// In case of properties, intrinsic ranges might not be correct for the purpose of getting /// positions of 'member', which indicate the indentation for generating new members - val getMemberNameAndRanges : InterfaceData -> (string * range) list + val GetMemberNameAndRanges: interfaceData: InterfaceData -> (string * range) list - val getImplementedMemberSignatures : getMemberByLocation: (string * range -> Async) -> FSharpDisplayContext -> InterfaceData -> Async> + /// Get interface member signatures + val GetImplementedMemberSignatures: getMemberByLocation: (string * range -> FSharpSymbolUse option) -> FSharpDisplayContext -> InterfaceData -> Async> /// Check whether an entity is an interface or type abbreviation of an interface - val isInterface : FSharpEntity -> bool + val IsInterface: entity: FSharpEntity -> bool /// Generate stub implementation of an interface at a start column - val formatInterface : startColumn: int -> indentation: int -> typeInstances: string [] -> objectIdent: string -> methodBody: string -> displayContext: FSharpDisplayContext -> excludedMemberSignatures : Set -> FSharpEntity -> verboseMode : bool -> string + val FormatInterface: startColumn: int -> indentation: int -> typeInstances: string [] -> objectIdent: string -> methodBody: string -> displayContext: FSharpDisplayContext -> excludedMemberSignatures: Set -> FSharpEntity -> verboseMode: bool -> string /// Find corresponding interface declaration at a given position - val tryFindInterfaceDeclaration: pos -> parsedInput: ParsedInput -> InterfaceData option -#endif + val TryFindInterfaceDeclaration: pos: pos -> parsedInput: ParsedInput -> InterfaceData option diff --git a/src/fsharp/service/ServiceLexing.fs b/src/fsharp/service/ServiceLexing.fs index e0792c9d2a8..c2d6f0f6aae 100644 --- a/src/fsharp/service/ServiceLexing.fs +++ b/src/fsharp/service/ServiceLexing.fs @@ -1,40 +1,44 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//---------------------------------------------------------------------------- -// Open up the compiler as an incremental service for lexing. -//-------------------------------------------------------------------------- - -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Tokenization open System open System.Collections.Generic -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library +open System.Threading +open FSharp.Compiler.IO +open Internal.Utilities +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler -open FSharp.Compiler.Parser -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.Diagnostics open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features open FSharp.Compiler.Lexhelp -open FSharp.Compiler.Lib -open Internal.Utilities - -type Position = int * int -type Range = Position * Position +open FSharp.Compiler.Parser +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range module FSharpTokenTag = + let Identifier = tagOfToken (IDENT "a") - let String = tagOfToken (STRING "a") + let String = tagOfToken (STRING ("a", SynStringKind.Regular, LexCont.Default)) let IDENT = tagOfToken (IDENT "a") - let STRING = tagOfToken (STRING "a") + let HASH_IDENT = tagOfToken (HASH_IDENT "a") + let STRING = String + let INTERP_STRING_BEGIN_END = tagOfToken (INTERP_STRING_BEGIN_END ("a", SynStringKind.Regular, LexCont.Default)) + let INTERP_STRING_BEGIN_PART = tagOfToken (INTERP_STRING_BEGIN_PART ("a", SynStringKind.Regular, LexCont.Default)) + let INTERP_STRING_PART = tagOfToken (INTERP_STRING_PART ("a", LexCont.Default)) + let INTERP_STRING_END = tagOfToken (INTERP_STRING_END ("a", LexCont.Default)) let LPAREN = tagOfToken LPAREN let RPAREN = tagOfToken RPAREN let LBRACK = tagOfToken LBRACK let RBRACK = tagOfToken RBRACK - let LBRACE = tagOfToken LBRACE - let RBRACE = tagOfToken RBRACE + let LBRACE = tagOfToken (LBRACE LexCont.Default) + let RBRACE = tagOfToken (RBRACE LexCont.Default) let LBRACK_LESS = tagOfToken LBRACK_LESS let GREATER_RBRACK = tagOfToken GREATER_RBRACK let LESS = tagOfToken (LESS true) @@ -164,13 +168,14 @@ module internal TokenClassifications = let tokenInfo token = match token with + | HASH_IDENT s | IDENT s -> if s.Length <= 0 then System.Diagnostics.Debug.Assert(false, "BUG: Received zero length IDENT token.") // This is related to 4783. Recover by treating as lower case identifier. (FSharpTokenColorKind.Identifier, FSharpTokenCharKind.Identifier, FSharpTokenTriggerClass.None) else - if System.Char.ToUpperInvariant s.[0] = s.[0] then + if Char.ToUpperInvariant s.[0] = s.[0] then (FSharpTokenColorKind.UpperIdentifier, FSharpTokenCharKind.Identifier, FSharpTokenTriggerClass.None) else (FSharpTokenColorKind.Identifier, FSharpTokenCharKind.Identifier, FSharpTokenTriggerClass.None) @@ -247,28 +252,28 @@ module internal TokenClassifications = | LBRACK_LESS -> (FSharpTokenColorKind.Punctuation, FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.None ) - | LQUOTE _ | LBRACK | LBRACE | LBRACK_BAR | LBRACE_BAR -> + | LQUOTE _ | LBRACK | LBRACE _ | LBRACK_BAR | LBRACE_BAR -> (FSharpTokenColorKind.Punctuation, FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.MatchBraces ) | GREATER_RBRACK | GREATER_BAR_RBRACK -> (FSharpTokenColorKind.Punctuation, FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.None ) - | RQUOTE _ | RBRACK | RBRACE | RBRACE_COMING_SOON | RBRACE_IS_HERE | BAR_RBRACK | BAR_RBRACE -> + | RQUOTE _ | RBRACK | RBRACE _ | RBRACE_COMING_SOON | RBRACE_IS_HERE | BAR_RBRACK | BAR_RBRACE -> (FSharpTokenColorKind.Punctuation, FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.MatchBraces ) | PUBLIC | PRIVATE | INTERNAL | BASE | GLOBAL | CONSTRAINT | INSTANCE | DELEGATE | INHERIT|CONSTRUCTOR|DEFAULT|OVERRIDE|ABSTRACT|CLASS | MEMBER | STATIC | NAMESPACE | OASSERT | OLAZY | ODECLEND | OBLOCKSEP | OEND | OBLOCKBEGIN | ORIGHT_BLOCK_END - | OBLOCKEND | OBLOCKEND_COMING_SOON | OBLOCKEND_IS_HERE | OTHEN | OELSE | OLET(_) - | OBINDER _ | BINDER _ | ODO | OWITH | OFUNCTION | OFUN | ORESET | ODUMMY _ | DO_BANG + | OBLOCKEND | OBLOCKEND_COMING_SOON | OBLOCKEND_IS_HERE | OTHEN | OELSE | OLET _ + | OBINDER _ | OAND_BANG _ | BINDER _ | ODO | OWITH | OFUNCTION | OFUN | ORESET | ODUMMY _ | DO_BANG | ODO_BANG | YIELD _ | YIELD_BANG _ | OINTERFACE_MEMBER | ELIF | RARROW | LARROW | SIG | STRUCT | UPCAST | DOWNCAST | NULL | RESERVED | MODULE | AND | AS | ASSERT | ASR | DOWNTO | EXCEPTION | FALSE | FOR | FUN | FUNCTION | FINALLY | LAZY | MATCH | MATCH_BANG | MUTABLE | NEW | OF | OPEN | OR | VOID | EXTERN | INTERFACE | REC | TO | TRUE | TRY | TYPE | VAL | INLINE | WHEN | WHILE | WITH - | IF | THEN | ELSE | DO | DONE | LET(_) | IN (*| NAMESPACE*) | CONST + | IF | THEN | ELSE | DO | DONE | LET _ | AND_BANG _ | IN | CONST | HIGH_PRECEDENCE_PAREN_APP | FIXED | HIGH_PRECEDENCE_BRACK_APP | TYPE_COMING_SOON | TYPE_IS_HERE | MODULE_COMING_SOON | MODULE_IS_HERE -> @@ -301,12 +306,14 @@ module internal TokenClassifications = | LINE_COMMENT _ -> (FSharpTokenColorKind.Comment, FSharpTokenCharKind.LineComment, FSharpTokenTriggerClass.None) - | STRING_TEXT _ -> - (FSharpTokenColorKind.String, FSharpTokenCharKind.String, FSharpTokenTriggerClass.None) - | KEYWORD_STRING _ -> (FSharpTokenColorKind.Keyword, FSharpTokenCharKind.Keyword, FSharpTokenTriggerClass.None) + | STRING_TEXT _ + | INTERP_STRING_BEGIN_END _ + | INTERP_STRING_BEGIN_PART _ + | INTERP_STRING_PART _ + | INTERP_STRING_END _ | BYTEARRAY _ | STRING _ | CHAR _ -> (FSharpTokenColorKind.String, FSharpTokenCharKind.String, FSharpTokenTriggerClass.None) @@ -316,9 +323,13 @@ module internal TokenClassifications = module internal TestExpose = let TokenInfo tok = TokenClassifications.tokenInfo tok - //---------------------------------------------------------------------------- - // Lexer states encoded to/from integers - //-------------------------------------------------------------------------- +/// Lexer states are encoded to/from integers. Typically one lexer state is +/// keep at the end of each line in an IDE service. IDE services are sometimes highly limited in the +/// memory they can use and this per-line state can be a significant cost if it associates with +/// many allocated objects. +/// +/// The encoding is lossy so some incremental lexing scenarios such as deeply nested #if +/// or accurate error messages from lexing for mismtached #if are not supported. [] type FSharpTokenizerLexState = { PosBits: int64 @@ -347,73 +358,125 @@ type FSharpTokenizerColorState = module internal LexerStateEncoding = - let computeNextLexState token (prevLexcont: LexerWhitespaceContinuation) = + let computeNextLexState token (prevLexcont: LexerContinuation) = match token with - | HASH_LINE s - | HASH_LIGHT s - | HASH_IF(_, _, s) - | HASH_ELSE(_, _, s) - | HASH_ENDIF(_, _, s) - | INACTIVECODE s - | WHITESPACE s - | COMMENT s - | LINE_COMMENT s - | STRING_TEXT s - | EOF s -> s - | BYTEARRAY _ | STRING _ -> LexCont.Token(prevLexcont.LexerIfdefStack) + | HASH_LINE cont + | HASH_LIGHT cont + | HASH_IF(_, _, cont) + | HASH_ELSE(_, _, cont) + | HASH_ENDIF(_, _, cont) + | INACTIVECODE cont + | WHITESPACE cont + | COMMENT cont + | LINE_COMMENT cont + | STRING_TEXT cont + | EOF cont + | INTERP_STRING_BEGIN_PART (_, _, cont) + | INTERP_STRING_PART (_, cont) + | INTERP_STRING_BEGIN_END (_, _, cont) + | INTERP_STRING_END (_, cont) + | LBRACE cont + | RBRACE cont + | BYTEARRAY (_, _, cont) + | STRING (_, _, cont) -> cont | _ -> prevLexcont // Note that this will discard all lexcont state, including the ifdefStack. - let revertToDefaultLexCont = LexCont.Token [] + let revertToDefaultLexCont = LexCont.Default let lexstateNumBits = 4 let ncommentsNumBits = 4 let hardwhiteNumBits = 1 let ifdefstackCountNumBits = 8 let ifdefstackNumBits = 24 // 0 means if, 1 means else + let stringKindBits = 3 + let nestingBits = 12 let _ = assert (lexstateNumBits + ncommentsNumBits + hardwhiteNumBits + ifdefstackCountNumBits - + ifdefstackNumBits <= 64) + + ifdefstackNumBits + + stringKindBits + + nestingBits <= 64) let lexstateStart = 0 let ncommentsStart = lexstateNumBits let hardwhitePosStart = lexstateNumBits+ncommentsNumBits let ifdefstackCountStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits let ifdefstackStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits+ifdefstackCountNumBits + let stringKindStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits+ifdefstackCountNumBits+ifdefstackNumBits + let nestingStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits+ifdefstackCountNumBits+ifdefstackNumBits+stringKindBits let lexstateMask = Bits.mask64 lexstateStart lexstateNumBits let ncommentsMask = Bits.mask64 ncommentsStart ncommentsNumBits let hardwhitePosMask = Bits.mask64 hardwhitePosStart hardwhiteNumBits let ifdefstackCountMask = Bits.mask64 ifdefstackCountStart ifdefstackCountNumBits let ifdefstackMask = Bits.mask64 ifdefstackStart ifdefstackNumBits + let stringKindMask = Bits.mask64 stringKindStart stringKindBits + let nestingMask = Bits.mask64 nestingStart nestingBits let bitOfBool b = if b then 1 else 0 let boolOfBit n = (n = 1L) - let inline colorStateOfLexState (state: FSharpTokenizerLexState) = + let colorStateOfLexState (state: FSharpTokenizerLexState) = enum (int32 ((state.OtherBits &&& lexstateMask) >>> lexstateStart)) - let inline lexStateOfColorState (state: FSharpTokenizerColorState) = + let lexStateOfColorState (state: FSharpTokenizerColorState) = (int64 state <<< lexstateStart) &&& lexstateMask - let encodeLexCont (colorState: FSharpTokenizerColorState) ncomments (b: pos) ifdefStack light = + let encodeStringStyle kind = + match kind with + | LexerStringStyle.SingleQuote -> 0 + | LexerStringStyle.Verbatim -> 1 + | LexerStringStyle.TripleQuote -> 2 + + let decodeStringStyle kind = + match kind with + | 0 -> LexerStringStyle.SingleQuote + | 1 -> LexerStringStyle.Verbatim + | 2 -> LexerStringStyle.TripleQuote + | _ -> assert false; LexerStringStyle.SingleQuote + + let encodeLexCont (colorState: FSharpTokenizerColorState, numComments, b: pos, ifdefStack, light, stringKind: LexerStringKind, stringNest) = let mutable ifdefStackCount = 0 let mutable ifdefStackBits = 0 for ifOrElse in ifdefStack do match ifOrElse with - | (IfDefIf, _) -> () - | (IfDefElse, _) -> - ifdefStackBits <- (ifdefStackBits ||| (1 <<< ifdefStackCount)) + | IfDefIf, _ -> () + | IfDefElse, _ -> + ifdefStackBits <- (ifdefStackBits ||| (1 <<< ifdefStackCount)) ifdefStackCount <- ifdefStackCount + 1 + let stringKindValue = + (if stringKind.IsByteString then 0b100 else 0) ||| + (if stringKind.IsInterpolated then 0b010 else 0) ||| + (if stringKind.IsInterpolatedFirst then 0b001 else 0) + + let nestingValue = + let tag1, i1, kind1, rest = + match stringNest with + | [] -> false, 0, 0, [] + | (i1, kind1, _)::rest -> true, i1, encodeStringStyle kind1, rest + let tag2, i2, kind2 = + match rest with + | [] -> false, 0, 0 + | (i2, kind2, _)::_ -> true, i2, encodeStringStyle kind2 + (if tag1 then 0b100000000000 else 0) ||| + (if tag2 then 0b010000000000 else 0) ||| + ((i1 <<< 7) &&& 0b001110000000) ||| + ((i2 <<< 4) &&& 0b000001110000) ||| + ((kind1 <<< 2) &&& 0b000000001100) ||| + ((kind2 <<< 0) &&& 0b000000000011) + let bits = lexStateOfColorState colorState - ||| ((ncomments <<< ncommentsStart) &&& ncommentsMask) + ||| ((numComments <<< ncommentsStart) &&& ncommentsMask) ||| ((int64 (bitOfBool light) <<< hardwhitePosStart) &&& hardwhitePosMask) ||| ((int64 ifdefStackCount <<< ifdefstackCountStart) &&& ifdefstackCountMask) ||| ((int64 ifdefStackBits <<< ifdefstackStart) &&& ifdefstackMask) + ||| ((int64 stringKindValue <<< stringKindStart) &&& stringKindMask) + ||| ((int64 nestingValue <<< nestingStart) &&& nestingMask) + { PosBits = b.Encoding OtherBits = bits } @@ -421,6 +484,11 @@ module internal LexerStateEncoding = let decodeLexCont (state: FSharpTokenizerLexState) = let mutable ifDefs = [] let bits = state.OtherBits + + let colorState = colorStateOfLexState state + let ncomments = int32 ((bits &&& ncommentsMask) >>> ncommentsStart) + let pos = pos.Decode state.PosBits + let ifdefStackCount = int32 ((bits &&& ifdefstackCountMask) >>> ifdefstackCountStart) if ifdefStackCount>0 then let ifdefStack = int32 ((bits &&& ifdefstackMask) >>> ifdefstackStart) @@ -429,73 +497,97 @@ module internal LexerStateEncoding = let mask = 1 <<< bit let ifDef = (if ifdefStack &&& mask = 0 then IfDefIf else IfDefElse) ifDefs <- (ifDef, range0) :: ifDefs - colorStateOfLexState state, - int32 ((bits &&& ncommentsMask) >>> ncommentsStart), - pos.Decode state.PosBits, - ifDefs, - boolOfBit ((bits &&& hardwhitePosMask) >>> hardwhitePosStart) - - let encodeLexInt lightSyntaxStatus (lexcont: LexerWhitespaceContinuation) = - let tag, n1, p1, ifd = - match lexcont with - | LexCont.Token ifd -> FSharpTokenizerColorState.Token, 0L, pos0, ifd - | LexCont.IfDefSkip (ifd, n, m) -> FSharpTokenizerColorState.IfDefSkip, int64 n, m.Start, ifd - | LexCont.EndLine(LexerEndlineContinuation.Skip(ifd, n, m)) -> FSharpTokenizerColorState.EndLineThenSkip, int64 n, m.Start, ifd - | LexCont.EndLine(LexerEndlineContinuation.Token ifd) -> FSharpTokenizerColorState.EndLineThenToken, 0L, pos0, ifd - | LexCont.String (ifd, m) -> FSharpTokenizerColorState.String, 0L, m.Start, ifd - | LexCont.Comment (ifd, n, m) -> FSharpTokenizerColorState.Comment, int64 n, m.Start, ifd - | LexCont.SingleLineComment (ifd, n, m) -> FSharpTokenizerColorState.SingleLineComment, int64 n, m.Start, ifd - | LexCont.StringInComment (ifd, n, m) -> FSharpTokenizerColorState.StringInComment, int64 n, m.Start, ifd - | LexCont.VerbatimStringInComment (ifd, n, m) -> FSharpTokenizerColorState.VerbatimStringInComment, int64 n, m.Start, ifd - | LexCont.TripleQuoteStringInComment (ifd, n, m) -> FSharpTokenizerColorState.TripleQuoteStringInComment, int64 n, m.Start, ifd - | LexCont.MLOnly (ifd, m) -> FSharpTokenizerColorState.CamlOnly, 0L, m.Start, ifd - | LexCont.VerbatimString (ifd, m) -> FSharpTokenizerColorState.VerbatimString, 0L, m.Start, ifd - | LexCont.TripleQuoteString (ifd, m) -> FSharpTokenizerColorState.TripleQuoteString, 0L, m.Start, ifd - encodeLexCont tag n1 p1 ifd lightSyntaxStatus + let stringKindValue = int32 ((bits &&& stringKindMask) >>> stringKindStart) + let stringKind : LexerStringKind = + { IsByteString = ((stringKindValue &&& 0b100) = 0b100) + IsInterpolated = ((stringKindValue &&& 0b010) = 0b010) + IsInterpolatedFirst = ((stringKindValue &&& 0b001) = 0b001) } + + let hardwhite = boolOfBit ((bits &&& hardwhitePosMask) >>> hardwhitePosStart) + + let nestingValue = int32 ((bits &&& nestingMask) >>> nestingStart) + let stringNest : LexerInterpolatedStringNesting = + let tag1 = ((nestingValue &&& 0b100000000000) = 0b100000000000) + let tag2 = ((nestingValue &&& 0b010000000000) = 0b010000000000) + let i1 = ((nestingValue &&& 0b001110000000) >>> 7) + let i2 = ((nestingValue &&& 0b000001110000) >>> 4) + let kind1 = ((nestingValue &&& 0b000000001100) >>> 2) + let kind2 = ((nestingValue &&& 0b000000000011) >>> 0) + [ if tag1 then + i1, decodeStringStyle kind1, range0 + if tag2 then + i2, decodeStringStyle kind2, range0 + ] + + (colorState, ncomments, pos, ifDefs, hardwhite, stringKind, stringNest) + + let encodeLexInt lightStatus (lexcont: LexerContinuation) = + match lexcont with + | LexCont.Token (ifdefs, stringNest) -> + encodeLexCont (FSharpTokenizerColorState.Token, 0L, pos0, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.IfDefSkip (ifdefs, stringNest, n, m) -> + encodeLexCont (FSharpTokenizerColorState.IfDefSkip, int64 n, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.EndLine(ifdefs, stringNest, econt) -> + match econt with + | LexerEndlineContinuation.Skip(n, m) -> + encodeLexCont (FSharpTokenizerColorState.EndLineThenSkip, int64 n, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexerEndlineContinuation.Token -> + encodeLexCont (FSharpTokenizerColorState.EndLineThenToken, 0L, pos0, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.String (ifdefs, stringNest, style, kind, m) -> + let state = + match style with + | LexerStringStyle.SingleQuote -> FSharpTokenizerColorState.String + | LexerStringStyle.Verbatim -> FSharpTokenizerColorState.VerbatimString + | LexerStringStyle.TripleQuote -> FSharpTokenizerColorState.TripleQuoteString + encodeLexCont (state, 0L, m.Start, ifdefs, lightStatus, kind, stringNest) + | LexCont.Comment (ifdefs, stringNest, n, m) -> + encodeLexCont (FSharpTokenizerColorState.Comment, int64 n, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.SingleLineComment (ifdefs, stringNest, n, m) -> + encodeLexCont (FSharpTokenizerColorState.SingleLineComment, int64 n, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.StringInComment (ifdefs, stringNest, style, n, m) -> + let state = + match style with + | LexerStringStyle.SingleQuote -> FSharpTokenizerColorState.StringInComment + | LexerStringStyle.Verbatim -> FSharpTokenizerColorState.VerbatimStringInComment + | LexerStringStyle.TripleQuote -> FSharpTokenizerColorState.TripleQuoteStringInComment + encodeLexCont (state, int64 n, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) + | LexCont.MLOnly (ifdefs, stringNest, m) -> + encodeLexCont (FSharpTokenizerColorState.CamlOnly, 0L, m.Start, ifdefs, lightStatus, LexerStringKind.String, stringNest) let decodeLexInt (state: FSharpTokenizerLexState) = - let tag, n1, p1, ifd, lightSyntaxStatusInitial = decodeLexCont state + let tag, n1, p1, ifdefs, lightSyntaxStatusInitial, stringKind, stringNest = decodeLexCont state let lexcont = match tag with - | FSharpTokenizerColorState.Token -> LexCont.Token ifd - | FSharpTokenizerColorState.IfDefSkip -> LexCont.IfDefSkip (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.String -> LexCont.String (ifd, mkRange "file" p1 p1) - | FSharpTokenizerColorState.Comment -> LexCont.Comment (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.SingleLineComment -> LexCont.SingleLineComment (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.StringInComment -> LexCont.StringInComment (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.VerbatimStringInComment -> LexCont.VerbatimStringInComment (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.TripleQuoteStringInComment -> LexCont.TripleQuoteStringInComment (ifd, n1, mkRange "file" p1 p1) - | FSharpTokenizerColorState.CamlOnly -> LexCont.MLOnly (ifd, mkRange "file" p1 p1) - | FSharpTokenizerColorState.VerbatimString -> LexCont.VerbatimString (ifd, mkRange "file" p1 p1) - | FSharpTokenizerColorState.TripleQuoteString -> LexCont.TripleQuoteString (ifd, mkRange "file" p1 p1) - | FSharpTokenizerColorState.EndLineThenSkip -> LexCont.EndLine(LexerEndlineContinuation.Skip(ifd, n1, mkRange "file" p1 p1)) - | FSharpTokenizerColorState.EndLineThenToken -> LexCont.EndLine(LexerEndlineContinuation.Token ifd) - | _ -> LexCont.Token [] + | FSharpTokenizerColorState.Token -> + LexCont.Token (ifdefs, stringNest) + | FSharpTokenizerColorState.IfDefSkip -> + LexCont.IfDefSkip (ifdefs, stringNest, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.String -> + LexCont.String (ifdefs, stringNest, LexerStringStyle.SingleQuote, stringKind, mkRange "file" p1 p1) + | FSharpTokenizerColorState.Comment -> + LexCont.Comment (ifdefs, stringNest, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.SingleLineComment -> + LexCont.SingleLineComment (ifdefs, stringNest, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.StringInComment -> + LexCont.StringInComment (ifdefs, stringNest, LexerStringStyle.SingleQuote, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.VerbatimStringInComment -> + LexCont.StringInComment (ifdefs, stringNest, LexerStringStyle.Verbatim, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.TripleQuoteStringInComment -> + LexCont.StringInComment (ifdefs, stringNest, LexerStringStyle.TripleQuote, n1, mkRange "file" p1 p1) + | FSharpTokenizerColorState.CamlOnly -> + LexCont.MLOnly (ifdefs, stringNest, mkRange "file" p1 p1) + | FSharpTokenizerColorState.VerbatimString -> + LexCont.String (ifdefs, stringNest, LexerStringStyle.Verbatim, stringKind, mkRange "file" p1 p1) + | FSharpTokenizerColorState.TripleQuoteString -> + LexCont.String (ifdefs, stringNest, LexerStringStyle.TripleQuote, stringKind, mkRange "file" p1 p1) + | FSharpTokenizerColorState.EndLineThenSkip -> + LexCont.EndLine(ifdefs, stringNest, LexerEndlineContinuation.Skip(n1, mkRange "file" p1 p1)) + | FSharpTokenizerColorState.EndLineThenToken -> + LexCont.EndLine(ifdefs, stringNest, LexerEndlineContinuation.Token) + | _ -> LexCont.Token ([], stringNest) lightSyntaxStatusInitial, lexcont - let callLexCont lexcont args skip lexbuf = - let argsWithIfDefs ifd = - if args.ifdefStack = ifd then - args - else - {args with ifdefStack = ifd} - match lexcont with - | LexCont.EndLine cont -> Lexer.endline cont args skip lexbuf - | LexCont.Token ifd -> Lexer.token (argsWithIfDefs ifd) skip lexbuf - | LexCont.IfDefSkip (ifd, n, m) -> Lexer.ifdefSkip n m (argsWithIfDefs ifd) skip lexbuf - // Q: What's this magic 100 number for? Q: it's just an initial buffer size. - | LexCont.String (ifd, m) -> Lexer.string (ByteBuffer.Create 100, defaultStringFinisher, m, (argsWithIfDefs ifd)) skip lexbuf - | LexCont.Comment (ifd, n, m) -> Lexer.comment (n, m, (argsWithIfDefs ifd)) skip lexbuf - // The first argument is 'None' because we don't need XML comments when called from VS - | LexCont.SingleLineComment (ifd, n, m) -> Lexer.singleLineComment (None, n, m, (argsWithIfDefs ifd)) skip lexbuf - | LexCont.StringInComment (ifd, n, m) -> Lexer.stringInComment n m (argsWithIfDefs ifd) skip lexbuf - | LexCont.VerbatimStringInComment (ifd, n, m) -> Lexer.verbatimStringInComment n m (argsWithIfDefs ifd) skip lexbuf - | LexCont.TripleQuoteStringInComment (ifd, n, m) -> Lexer.tripleQuoteStringInComment n m (argsWithIfDefs ifd) skip lexbuf - | LexCont.MLOnly (ifd, m) -> Lexer.mlOnly m (argsWithIfDefs ifd) skip lexbuf - | LexCont.VerbatimString (ifd, m) -> Lexer.verbatimString (ByteBuffer.Create 100, defaultStringFinisher, m, (argsWithIfDefs ifd)) skip lexbuf - | LexCont.TripleQuoteString (ifd, m) -> Lexer.tripleQuoteString (ByteBuffer.Create 100, defaultStringFinisher, m, (argsWithIfDefs ifd)) skip lexbuf - //---------------------------------------------------------------------------- // Colorization //---------------------------------------------------------------------------- @@ -511,16 +603,16 @@ type SingleLineTokenState = [] type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, maxLength: int option, - filename: Option, - lexArgsLightOn: lexargs, - lexArgsLightOff: lexargs) = + filename: string option, + lexargs: LexArgs) = let skip = false // don't skip whitespace in the lexer let mutable singleLineTokenState = SingleLineTokenState.BeforeHash - let fsx = match filename with - | None -> false - | Some value -> CompileOps.IsScript value + let fsx = + match filename with + | None -> false + | Some value -> ParseAndCheckInputs.IsScript value // ---------------------------------------------------------------------------------- // This implements post-processing of #directive tokens - not very elegant, but it works... @@ -528,7 +620,7 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, // so we need to split it into tokens that are used by VS for colorization // Stack for tokens that are split during postprocessing - let mutable tokenStack = new Stack<_>() + let mutable tokenStack = Stack<_>() let delayToken tok = tokenStack.Push tok // Process: anywhite* # @@ -548,7 +640,7 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, // Split a directive line from lexer into tokens usable in VS let processDirectiveLine ofs f = - let delayed = new ResizeArray<_>() + let delayed = ResizeArray<_>() f (fun (tok, s, e) -> delayed.Add (tok, s + ofs, e + ofs) ) // delay all the tokens and return the remaining one for i = delayed.Count - 1 downto 1 do delayToken delayed.[i] @@ -583,104 +675,160 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, let offset = beforeIdent + identLength processWhiteAndComment str offset delay cont ) - // ---------------------------------------------------------------------------------- - - - + // Set up the initial file position do match filename with | None -> lexbuf.EndPos <- Internal.Utilities.Text.Lexing.Position.Empty | Some value -> resetLexbufPos value lexbuf - member x.ScanToken lexintInitial: FSharpTokenInfo option * FSharpTokenizerLexState = + // Call the given continuation, reusing the same 'lexargs' each time but adjust + // its mutable entries to set up the right state + let callLexCont lexcont lightStatus skip = + + // Set up the arguments to lexing + lexargs.lightStatus <- lightStatus + + match lexcont with + | LexCont.EndLine (ifdefs, stringNest, cont) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + Lexer.endline cont lexargs skip lexbuf + + | LexCont.Token (ifdefs, stringNest) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + Lexer.token lexargs skip lexbuf + + | LexCont.IfDefSkip (ifdefs, stringNest, n, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + Lexer.ifdefSkip n m lexargs skip lexbuf + + | LexCont.String (ifdefs, stringNest, style, kind, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + use buf = ByteBuffer.Create Lexer.StringCapacity + let args = (buf, LexerStringFinisher.Default, m, kind, lexargs) + match style with + | LexerStringStyle.SingleQuote -> Lexer.singleQuoteString args skip lexbuf + | LexerStringStyle.Verbatim -> Lexer.verbatimString args skip lexbuf + | LexerStringStyle.TripleQuote -> Lexer.tripleQuoteString args skip lexbuf + + | LexCont.Comment (ifdefs, stringNest, n, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + Lexer.comment (n, m, lexargs) skip lexbuf + + | LexCont.SingleLineComment (ifdefs, stringNest, n, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + // The first argument is 'None' because we don't need XML comments when called from VS tokenizer + Lexer.singleLineComment (None, n, m, lexargs) skip lexbuf + + | LexCont.StringInComment (ifdefs, stringNest, style, n, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + match style with + | LexerStringStyle.SingleQuote -> Lexer.stringInComment n m lexargs skip lexbuf + | LexerStringStyle.Verbatim -> Lexer.verbatimStringInComment n m lexargs skip lexbuf + | LexerStringStyle.TripleQuote -> Lexer.tripleQuoteStringInComment n m lexargs skip lexbuf + + | LexCont.MLOnly (ifdefs, stringNest, m) -> + lexargs.ifdefStack <- ifdefs + lexargs.stringNest <- stringNest + Lexer.mlOnly m lexargs skip lexbuf + + let columnsOfCurrentToken() = + let leftp = lexbuf.StartPos + let rightp = lexbuf.EndPos + let leftc = leftp.Column + let rightc = + match maxLength with + | Some mx when rightp.Line > leftp.Line -> mx + | _ -> rightp.Column + let rightc = rightc - 1 + struct (leftc, rightc) + + let getTokenWithPosition lexcont lightStatus = + // Column of token + // Get the token & position - either from a stack or from the lexer + try + if (tokenStack.Count > 0) then + true, tokenStack.Pop() + else + // Choose which lexer entry point to call and call it + let token = callLexCont lexcont lightStatus skip + let struct (leftc, rightc) = columnsOfCurrentToken() + + // Splits tokens like ">." into multiple tokens - this duplicates behavior from the 'lexfilter' + // which cannot be (easily) used from the language service. The rules here are not always valid, + // because sometimes token shouldn't be split. However it is just for colorization & + // for VS (which needs to recognize when user types "."). + match token with + | HASH_IF (m, lineStr, cont) when lineStr <> "" -> + false, processHashIfLine m.StartColumn lineStr cont + | HASH_ELSE (m, lineStr, cont) when lineStr <> "" -> + false, processHashEndElse m.StartColumn lineStr 4 cont + | HASH_ENDIF (m, lineStr, cont) when lineStr <> "" -> + false, processHashEndElse m.StartColumn lineStr 5 cont + | HASH_IDENT(ident) -> + delayToken(IDENT ident, leftc + 1, rightc) + false, (HASH, leftc, leftc) + | RQUOTE_DOT (s, raw) -> + delayToken(DOT, rightc, rightc) + false, (RQUOTE (s, raw), leftc, rightc - 1) + | INFIX_COMPARE_OP (LexFilter.TyparsCloseOp(greaters, afterOp) as opstr) -> + match afterOp with + | None -> () + | Some tok -> delayToken(tok, leftc + greaters.Length, rightc) + for i = greaters.Length - 1 downto 1 do + delayToken(greaters.[i] false, leftc + i, rightc - opstr.Length + i + 1) + false, (greaters.[0] false, leftc, rightc - opstr.Length + 1) + // break up any operators that start with '.' so that we can get auto-popup-completion for e.g. "x.+1" when typing the dot + | INFIX_STAR_STAR_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_STAR_STAR_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | PLUS_MINUS_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(PLUS_MINUS_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | INFIX_COMPARE_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_COMPARE_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | INFIX_AT_HAT_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_AT_HAT_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | INFIX_BAR_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_BAR_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | PREFIX_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(PREFIX_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | INFIX_STAR_DIV_MOD_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_STAR_DIV_MOD_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | INFIX_AMP_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(INFIX_AMP_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | ADJACENT_PREFIX_OP opstr when opstr.StartsWithOrdinal(".") -> + delayToken(ADJACENT_PREFIX_OP(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | FUNKY_OPERATOR_NAME opstr when opstr.StartsWithOrdinal(".") -> + delayToken(FUNKY_OPERATOR_NAME(opstr.Substring 1), leftc+1, rightc) + false, (DOT, leftc, leftc) + | _ -> false, (token, leftc, rightc) + with _ -> + false, (EOF LexerStateEncoding.revertToDefaultLexCont, 0, 0) + + // Scan a token starting with the given lexer state + member x.ScanToken (lexState: FSharpTokenizerLexState) : FSharpTokenInfo option * FSharpTokenizerLexState = use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> DiscardErrorsLogger) - let lightSyntaxStatusInitial, lexcontInitial = LexerStateEncoding.decodeLexInt lexintInitial - let lightSyntaxStatus = LightSyntaxStatus(lightSyntaxStatusInitial, false) - - // Build the arguments to the lexer function - let lexargs = if lightSyntaxStatusInitial then lexArgsLightOn else lexArgsLightOff - - let GetTokenWithPosition lexcontInitial = - // Column of token - let ColumnsOfCurrentToken() = - let leftp = lexbuf.StartPos - let rightp = lexbuf.EndPos - let leftc = leftp.Column - let rightc = - match maxLength with - | Some mx when rightp.Line > leftp.Line -> mx - | _ -> rightp.Column - let rightc = rightc - 1 - leftc, rightc - - // Get the token & position - either from a stack or from the lexer - try - if (tokenStack.Count > 0) then true, tokenStack.Pop() - else - // Choose which lexer entry point to call and call it - let token = LexerStateEncoding.callLexCont lexcontInitial lexargs skip lexbuf - let leftc, rightc = ColumnsOfCurrentToken() - - // Splits tokens like ">." into multiple tokens - this duplicates behavior from the 'lexfilter' - // which cannot be (easily) used from the language service. The rules here are not always valid, - // because sometimes token shouldn't be split. However it is just for colorization & - // for VS (which needs to recognize when user types "."). - match token with - | HASH_IF (m, lineStr, cont) when lineStr <> "" -> - false, processHashIfLine m.StartColumn lineStr cont - | HASH_ELSE (m, lineStr, cont) when lineStr <> "" -> - false, processHashEndElse m.StartColumn lineStr 4 cont - | HASH_ENDIF (m, lineStr, cont) when lineStr <> "" -> - false, processHashEndElse m.StartColumn lineStr 5 cont - | RQUOTE_DOT (s, raw) -> - delayToken(DOT, rightc, rightc) - false, (RQUOTE (s, raw), leftc, rightc - 1) - | INFIX_COMPARE_OP (LexFilter.TyparsCloseOp(greaters, afterOp) as opstr) -> - match afterOp with - | None -> () - | Some tok -> delayToken(tok, leftc + greaters.Length, rightc) - for i = greaters.Length - 1 downto 1 do - delayToken(greaters.[i] false, leftc + i, rightc - opstr.Length + i + 1) - false, (greaters.[0] false, leftc, rightc - opstr.Length + 1) - // break up any operators that start with '.' so that we can get auto-popup-completion for e.g. "x.+1" when typing the dot - | INFIX_STAR_STAR_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_STAR_STAR_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | PLUS_MINUS_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(PLUS_MINUS_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | INFIX_COMPARE_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_COMPARE_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | INFIX_AT_HAT_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_AT_HAT_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | INFIX_BAR_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_BAR_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | PREFIX_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(PREFIX_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | INFIX_STAR_DIV_MOD_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_STAR_DIV_MOD_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | INFIX_AMP_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(INFIX_AMP_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | ADJACENT_PREFIX_OP opstr when opstr.StartsWithOrdinal(".") -> - delayToken(ADJACENT_PREFIX_OP(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | FUNKY_OPERATOR_NAME opstr when opstr.StartsWithOrdinal(".") -> - delayToken(FUNKY_OPERATOR_NAME(opstr.Substring 1), leftc+1, rightc) - false, (DOT, leftc, leftc) - | _ -> false, (token, leftc, rightc) - with - | e -> false, (EOF LexerStateEncoding.revertToDefaultLexCont, 0, 0) // REVIEW: report lex failure here + let lightStatus, lexcont = LexerStateEncoding.decodeLexInt lexState + let lightStatus = LightSyntaxStatus(lightStatus, false) // Grab a token - let isCached, (token, leftc, rightc) = GetTokenWithPosition lexcontInitial + let isCached, (token, leftc, rightc) = getTokenWithPosition lexcont lightStatus // Check for end-of-string and failure let tokenDataOption, lexcontFinal, tokenTag = @@ -692,14 +840,21 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, None, LexerStateEncoding.revertToDefaultLexCont, 0 | _ -> // Get the information about the token - let (colorClass, charClass, triggerClass) = TokenClassifications.tokenInfo token + let colorClass, charClass, triggerClass = TokenClassifications.tokenInfo token + let lexcontFinal = // If we're using token from cache, we don't move forward with lexing - if isCached then lexcontInitial else LexerStateEncoding.computeNextLexState token lexcontInitial + if isCached then lexcont + else LexerStateEncoding.computeNextLexState token lexcont + let tokenTag = tagOfToken token + + let tokenName = token_to_string token + let fullMatchedLength = lexbuf.EndPos.AbsoluteOffset - lexbuf.StartPos.AbsoluteOffset + let tokenData = - { TokenName = token_to_string token + { TokenName = tokenName LeftColumn=leftc RightColumn=rightc ColorClass=colorClass @@ -709,19 +864,15 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, FullMatchedLength=fullMatchedLength} Some tokenData, lexcontFinal, tokenTag - // Get the final lex int and color state - let FinalState lexcontFinal = - LexerStateEncoding.encodeLexInt lightSyntaxStatus.Status lexcontFinal - // Check for patterns like #-IDENT and see if they look like meta commands for .fsx files. If they do then merge them into a single token. let tokenDataOption, lexintFinal = - let lexintFinal = FinalState lexcontFinal + let lexintFinal = LexerStateEncoding.encodeLexInt lightStatus.Status lexcontFinal match tokenDataOption, singleLineTokenState, tokenTagToTokenId tokenTag with | Some tokenData, SingleLineTokenState.BeforeHash, TOKEN_HASH -> // Don't allow further matches. singleLineTokenState <- SingleLineTokenState.NoFurtherMatchPossible // Peek at the next token - let isCached, (nextToken, _, rightc) = GetTokenWithPosition lexcontInitial + let isCached, (nextToken, _, rightc) = getTokenWithPosition lexcont lightStatus match nextToken with | IDENT possibleMetaCommand -> match fsx, possibleMetaCommand with @@ -746,9 +897,9 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, // These are for script and non-script | _, "nowarn" -> // Merge both tokens into one. - let lexcontFinal = if isCached then lexcontInitial else LexerStateEncoding.computeNextLexState token lexcontInitial + let lexcontFinal = if isCached then lexcont else LexerStateEncoding.computeNextLexState token lexcont let tokenData = {tokenData with RightColumn=rightc;ColorClass=FSharpTokenColorKind.PreprocessorKeyword;CharClass=FSharpTokenCharKind.Keyword;FSharpTokenTriggerClass=FSharpTokenTriggerClass.None} - let lexintFinal = FinalState lexcontFinal + let lexintFinal = LexerStateEncoding.encodeLexInt lightStatus.Status lexcontFinal Some tokenData, lexintFinal | _ -> tokenDataOption, lexintFinal | _ -> tokenDataOption, lexintFinal @@ -768,30 +919,651 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, { PosBits = 0L; OtherBits = LexerStateEncoding.lexStateOfColorState colorState } [] -type FSharpSourceTokenizer(defineConstants: string list, filename: string option) = - - // Public callers are unable to answer LanguageVersion feature support questions. - // External Tools including the VS IDE will enable the default LanguageVersion - let isFeatureSupported (_featureId:LanguageFeature) = true - - let lexResourceManager = new Lexhelp.LexResourceManager() - - let lexArgsLightOn = mkLexargs(filename, defineConstants, LightSyntaxStatus(true, false), lexResourceManager, [], DiscardErrorsLogger, PathMap.empty) - let lexArgsLightOff = mkLexargs(filename, defineConstants, LightSyntaxStatus(false, false), lexResourceManager, [], DiscardErrorsLogger, PathMap.empty) - - member this.CreateLineTokenizer(lineText: string) = - let lexbuf = UnicodeLexing.StringAsLexbuf(isFeatureSupported, lineText) - FSharpLineTokenizer(lexbuf, Some lineText.Length, filename, lexArgsLightOn, lexArgsLightOff) - - member this.CreateBufferTokenizer bufferFiller = - let lexbuf = UnicodeLexing.FunctionAsLexbuf(isFeatureSupported, bufferFiller) - FSharpLineTokenizer(lexbuf, None, filename, lexArgsLightOn, lexArgsLightOff) - -module Keywords = - open FSharp.Compiler.Lexhelp.Keywords - - let DoesIdentifierNeedQuotation s = DoesIdentifierNeedQuotation s - let QuoteIdentifierIfNeeded s = QuoteIdentifierIfNeeded s - let NormalizeIdentifierBackticks s = NormalizeIdentifierBackticks s - let KeywordsWithDescription = keywordsWithDescription - +type FSharpSourceTokenizer(conditionalDefines: string list, filename: string option) = + + let langVersion = LanguageVersion.Default + let reportLibraryOnlyFeatures = true + + let lexResourceManager = LexResourceManager() + + let lexargs = mkLexargs(conditionalDefines, LightSyntaxStatus(true, false), lexResourceManager, [], DiscardErrorsLogger, PathMap.empty) + + member _.CreateLineTokenizer(lineText: string) = + let lexbuf = UnicodeLexing.StringAsLexbuf(reportLibraryOnlyFeatures, langVersion, lineText) + FSharpLineTokenizer(lexbuf, Some lineText.Length, filename, lexargs) + + member _.CreateBufferTokenizer bufferFiller = + let lexbuf = UnicodeLexing.FunctionAsLexbuf(reportLibraryOnlyFeatures, langVersion, bufferFiller) + FSharpLineTokenizer(lexbuf, None, filename, lexargs) + +module FSharpKeywords = + + let DoesIdentifierNeedBackticks s = PrettyNaming.DoesIdentifierNeedBackticks s + + let AddBackticksToIdentifierIfNeeded s = PrettyNaming.AddBackticksToIdentifierIfNeeded s + + let NormalizeIdentifierBackticks s = PrettyNaming.NormalizeIdentifierBackticks s + + let KeywordsWithDescription = PrettyNaming.keywordsWithDescription + + let KeywordNames = Lexhelp.Keywords.keywordNames + +[] +type FSharpLexerFlags = + | Default = 0x11011 + | LightSyntaxOn = 0x00001 + | Compiling = 0x00010 + | CompilingFSharpCore = 0x00110 + | SkipTrivia = 0x01000 + | UseLexFilter = 0x10000 + +[] +type FSharpTokenKind = + | None + | HashIf + | HashElse + | HashEndIf + | CommentTrivia + | WhitespaceTrivia + | HashLine + | HashLight + | InactiveCode + | LineCommentTrivia + | StringText + | Fixed + | OffsideInterfaceMember + | OffsideBlockEnd + | OffsideRightBlockEnd + | OffsideDeclEnd + | OffsideEnd + | OffsideBlockSep + | OffsideBlockBegin + | OffsideReset + | OffsideFun + | OffsideFunction + | OffsideWith + | OffsideElse + | OffsideThen + | OffsideDoBang + | OffsideDo + | OffsideBinder + | OffsideLet + | HighPrecedenceTypeApp + | HighPrecedenceParenthesisApp + | HighPrecedenceBracketApp + | Extern + | Void + | Public + | Private + | Internal + | Global + | Static + | Member + | Class + | Abstract + | Override + | Default + | Constructor + | Inherit + | GreaterRightBracket + | Struct + | Sig + | Bar + | RightBracket + | RightBrace + | Minus + | Dollar + | BarRightBracket + | BarRightBrace + | Underscore + | Semicolon + | SemicolonSemicolon + | LeftArrow + | Equals + | LeftBracket + | LeftBracketBar + | LeftBraceBar + | LeftBracketLess + | LeftBrace + | QuestionMark + | QuestionMarkQuestionMark + | Dot + | Colon + | ColonColon + | ColonGreater + | ColonQuestionMark + | ColonQuestionMarkGreater + | ColonEquals + | When + | While + | With + | Hash + | Ampersand + | AmpersandAmpersand + | Quote + | LeftParenthesis + | RightParenthesis + | Star + | Comma + | RightArrow + | GreaterBarRightBracket + | LeftParenthesisStarRightParenthesis + | Open + | Or + | Rec + | Then + | To + | True + | Try + | Type + | Val + | Inline + | Interface + | Instance + | Const + | Lazy + | OffsideLazy + | Match + | MatchBang + | Mutable + | New + | Of + | Exception + | False + | For + | Fun + | Function + | If + | In + | JoinIn + | Finally + | DoBang + | And + | As + | Assert + | OffsideAssert + | Begin + | Do + | Done + | DownTo + | Else + | Elif + | End + | DotDot + | DotDotHat + | BarBar + | Upcast + | Downcast + | Null + | Reserved + | Module + | Namespace + | Delegate + | Constraint + | Base + | LeftQuote + | RightQuote + | RightQuoteDot + | PercentOperator + | Binder + | Less + | Greater + | Let + | Yield + | YieldBang + | BigNumber + | Decimal + | Char + | Ieee64 + | Ieee32 + | NativeInt + | UNativeInt + | UInt64 + | UInt32 + | UInt16 + | UInt8 + | Int64 + | Int32 + | Int32DotDot + | Int16 + | Int8 + | FunkyOperatorName + | AdjacentPrefixOperator + | PlusMinusOperator + | InfixAmpersandOperator + | InfixStarDivideModuloOperator + | PrefixOperator + | InfixBarOperator + | InfixAtHatOperator + | InfixCompareOperator + | InfixStarStarOperator + | Identifier + | KeywordString + | String + | ByteArray + | Asr + | InfixAsr + | InfixLand + | InfixLor + | InfixLsl + | InfixLsr + | InfixLxor + | InfixMod + +[] +type FSharpToken = + + val private tok: token + val private tokRange: range + + new (tok, tokRange) = { tok = tok; tokRange = tokRange } + + member this.Range = this.tokRange + + member this.Kind = + match this.tok with + | ASR -> FSharpTokenKind.Asr + | INFIX_STAR_STAR_OP "asr" -> FSharpTokenKind.Asr + | INFIX_STAR_DIV_MOD_OP "land" -> FSharpTokenKind.InfixLand + | INFIX_STAR_DIV_MOD_OP "lor" -> FSharpTokenKind.InfixLor + | INFIX_STAR_STAR_OP "lsl" -> FSharpTokenKind.InfixLsl + | INFIX_STAR_STAR_OP "lsr" -> FSharpTokenKind.InfixLsr + | INFIX_STAR_DIV_MOD_OP "lxor" -> FSharpTokenKind.InfixLxor + | INFIX_STAR_DIV_MOD_OP "mod" -> FSharpTokenKind.InfixMod + | HASH_IF _ -> FSharpTokenKind.HashIf + | HASH_ELSE _ -> FSharpTokenKind.HashElse + | HASH_ENDIF _ -> FSharpTokenKind.HashEndIf + | COMMENT _ -> FSharpTokenKind.CommentTrivia + | WHITESPACE _ -> FSharpTokenKind.WhitespaceTrivia + | HASH_LINE _ -> FSharpTokenKind.HashLine + | HASH_LIGHT _ -> FSharpTokenKind.HashLight + | INACTIVECODE _ -> FSharpTokenKind.InactiveCode + | LINE_COMMENT _ -> FSharpTokenKind.LineCommentTrivia + | STRING_TEXT _ -> FSharpTokenKind.StringText + | FIXED -> FSharpTokenKind.Fixed + | OINTERFACE_MEMBER -> FSharpTokenKind.OffsideInterfaceMember + | OBLOCKEND -> FSharpTokenKind.OffsideBlockEnd + | ORIGHT_BLOCK_END -> FSharpTokenKind.OffsideRightBlockEnd + | ODECLEND -> FSharpTokenKind.OffsideDeclEnd + | OEND -> FSharpTokenKind.OffsideEnd + | OBLOCKSEP -> FSharpTokenKind.OffsideBlockSep + | OBLOCKBEGIN -> FSharpTokenKind.OffsideBlockBegin + | ORESET -> FSharpTokenKind.OffsideReset + | OFUN -> FSharpTokenKind.OffsideFun + | OFUNCTION -> FSharpTokenKind.OffsideFunction + | OWITH -> FSharpTokenKind.OffsideWith + | OELSE -> FSharpTokenKind.OffsideElse + | OTHEN -> FSharpTokenKind.OffsideThen + | ODO_BANG -> FSharpTokenKind.OffsideDoBang + | ODO -> FSharpTokenKind.OffsideDo + | OBINDER _ -> FSharpTokenKind.OffsideBinder + | OLET _ -> FSharpTokenKind.OffsideLet + | HIGH_PRECEDENCE_TYAPP -> FSharpTokenKind.HighPrecedenceTypeApp + | HIGH_PRECEDENCE_PAREN_APP -> FSharpTokenKind.HighPrecedenceParenthesisApp + | HIGH_PRECEDENCE_BRACK_APP -> FSharpTokenKind.HighPrecedenceBracketApp + | EXTERN -> FSharpTokenKind.Extern + | VOID -> FSharpTokenKind.Void + | PUBLIC -> FSharpTokenKind.Public + | PRIVATE -> FSharpTokenKind.Private + | INTERNAL -> FSharpTokenKind.Internal + | GLOBAL -> FSharpTokenKind.Global + | STATIC -> FSharpTokenKind.Static + | MEMBER -> FSharpTokenKind.Member + | CLASS -> FSharpTokenKind.Class + | ABSTRACT -> FSharpTokenKind.Abstract + | OVERRIDE -> FSharpTokenKind.Override + | DEFAULT -> FSharpTokenKind.Default + | CONSTRUCTOR -> FSharpTokenKind.Constructor + | INHERIT -> FSharpTokenKind.Inherit + | GREATER_RBRACK -> FSharpTokenKind.GreaterRightBracket + | STRUCT -> FSharpTokenKind.Struct + | SIG -> FSharpTokenKind.Sig + | BAR -> FSharpTokenKind.Bar + | RBRACK -> FSharpTokenKind.RightBracket + | RBRACE _ -> FSharpTokenKind.RightBrace + | MINUS -> FSharpTokenKind.Minus + | DOLLAR -> FSharpTokenKind.Dollar + | BAR_RBRACK -> FSharpTokenKind.BarRightBracket + | BAR_RBRACE -> FSharpTokenKind.BarRightBrace + | UNDERSCORE -> FSharpTokenKind.Underscore + | SEMICOLON_SEMICOLON -> FSharpTokenKind.SemicolonSemicolon + | LARROW -> FSharpTokenKind.LeftArrow + | EQUALS -> FSharpTokenKind.Equals + | LBRACK -> FSharpTokenKind.LeftBracket + | LBRACK_BAR -> FSharpTokenKind.LeftBracketBar + | LBRACE_BAR -> FSharpTokenKind.LeftBraceBar + | LBRACK_LESS -> FSharpTokenKind.LeftBracketLess + | LBRACE _ -> FSharpTokenKind.LeftBrace + | QMARK -> FSharpTokenKind.QuestionMark + | QMARK_QMARK -> FSharpTokenKind.QuestionMarkQuestionMark + | DOT -> FSharpTokenKind.Dot + | COLON -> FSharpTokenKind.Colon + | COLON_COLON -> FSharpTokenKind.ColonColon + | COLON_GREATER -> FSharpTokenKind.ColonGreater + | COLON_QMARK_GREATER -> FSharpTokenKind.ColonQuestionMarkGreater + | COLON_QMARK -> FSharpTokenKind.ColonQuestionMark + | COLON_EQUALS -> FSharpTokenKind.ColonEquals + | SEMICOLON -> FSharpTokenKind.SemicolonSemicolon + | WHEN -> FSharpTokenKind.When + | WHILE -> FSharpTokenKind.While + | WITH -> FSharpTokenKind.With + | HASH -> FSharpTokenKind.Hash + | AMP -> FSharpTokenKind.Ampersand + | AMP_AMP -> FSharpTokenKind.AmpersandAmpersand + | QUOTE -> FSharpTokenKind.RightQuote + | LPAREN -> FSharpTokenKind.LeftParenthesis + | RPAREN -> FSharpTokenKind.RightParenthesis + | STAR -> FSharpTokenKind.Star + | COMMA -> FSharpTokenKind.Comma + | RARROW -> FSharpTokenKind.RightArrow + | GREATER_BAR_RBRACK -> FSharpTokenKind.GreaterBarRightBracket + | LPAREN_STAR_RPAREN -> FSharpTokenKind.LeftParenthesisStarRightParenthesis + | OPEN -> FSharpTokenKind.Open + | OR -> FSharpTokenKind.Or + | REC -> FSharpTokenKind.Rec + | THEN -> FSharpTokenKind.Then + | TO -> FSharpTokenKind.To + | TRUE -> FSharpTokenKind.True + | TRY -> FSharpTokenKind.Try + | TYPE -> FSharpTokenKind.Type + | VAL -> FSharpTokenKind.Val + | INLINE -> FSharpTokenKind.Inline + | INTERFACE -> FSharpTokenKind.Interface + | INSTANCE -> FSharpTokenKind.Instance + | CONST -> FSharpTokenKind.Const + | LAZY -> FSharpTokenKind.Lazy + | OLAZY -> FSharpTokenKind.OffsideLazy + | MATCH -> FSharpTokenKind.Match + | MATCH_BANG -> FSharpTokenKind.MatchBang + | MUTABLE -> FSharpTokenKind.Mutable + | NEW -> FSharpTokenKind.New + | OF -> FSharpTokenKind.Of + | EXCEPTION -> FSharpTokenKind.Exception + | FALSE -> FSharpTokenKind.False + | FOR -> FSharpTokenKind.For + | FUN -> FSharpTokenKind.Fun + | FUNCTION -> FSharpTokenKind.Function + | IF -> FSharpTokenKind.If + | IN -> FSharpTokenKind.In + | JOIN_IN -> FSharpTokenKind.JoinIn + | FINALLY -> FSharpTokenKind.Finally + | DO_BANG -> FSharpTokenKind.DoBang + | AND -> FSharpTokenKind.And + | AS -> FSharpTokenKind.As + | ASSERT -> FSharpTokenKind.Assert + | OASSERT -> FSharpTokenKind.OffsideAssert + | BEGIN -> FSharpTokenKind.Begin + | DO -> FSharpTokenKind.Do + | DONE -> FSharpTokenKind.Done + | DOWNTO -> FSharpTokenKind.DownTo + | ELSE -> FSharpTokenKind.Else + | ELIF -> FSharpTokenKind.Elif + | END -> FSharpTokenKind.End + | DOT_DOT -> FSharpTokenKind.DotDot + | DOT_DOT_HAT -> FSharpTokenKind.DotDotHat + | BAR_BAR -> FSharpTokenKind.BarBar + | UPCAST -> FSharpTokenKind.Upcast + | DOWNCAST -> FSharpTokenKind.Downcast + | NULL -> FSharpTokenKind.Null + | RESERVED -> FSharpTokenKind.Reserved + | MODULE -> FSharpTokenKind.Module + | NAMESPACE -> FSharpTokenKind.Namespace + | DELEGATE -> FSharpTokenKind.Delegate + | CONSTRAINT -> FSharpTokenKind.Constraint + | BASE -> FSharpTokenKind.Base + | LQUOTE _ -> FSharpTokenKind.LeftQuote + | RQUOTE _ -> FSharpTokenKind.RightQuote + | RQUOTE_DOT _ -> FSharpTokenKind.RightQuoteDot + | PERCENT_OP _ -> FSharpTokenKind.PercentOperator + | BINDER _ -> FSharpTokenKind.Binder + | LESS _ -> FSharpTokenKind.Less + | GREATER _ -> FSharpTokenKind.Greater + | LET _ -> FSharpTokenKind.Let + | YIELD _ -> FSharpTokenKind.Yield + | YIELD_BANG _ -> FSharpTokenKind.YieldBang + | BIGNUM _ -> FSharpTokenKind.BigNumber + | DECIMAL _ -> FSharpTokenKind.Decimal + | CHAR _ -> FSharpTokenKind.Char + | IEEE64 _ -> FSharpTokenKind.Ieee64 + | IEEE32 _ -> FSharpTokenKind.Ieee32 + | NATIVEINT _ -> FSharpTokenKind.NativeInt + | UNATIVEINT _ -> FSharpTokenKind.UNativeInt + | UINT64 _ -> FSharpTokenKind.UInt64 + | UINT32 _ -> FSharpTokenKind.UInt32 + | UINT16 _ -> FSharpTokenKind.UInt16 + | UINT8 _ -> FSharpTokenKind.UInt8 + | INT64 _ -> FSharpTokenKind.UInt64 + | INT32 _ -> FSharpTokenKind.Int32 + | INT32_DOT_DOT _ -> FSharpTokenKind.Int32DotDot + | INT16 _ -> FSharpTokenKind.Int16 + | INT8 _ -> FSharpTokenKind.Int8 + | FUNKY_OPERATOR_NAME _ -> FSharpTokenKind.FunkyOperatorName + | ADJACENT_PREFIX_OP _ -> FSharpTokenKind.AdjacentPrefixOperator + | PLUS_MINUS_OP _ -> FSharpTokenKind.PlusMinusOperator + | INFIX_AMP_OP _ -> FSharpTokenKind.InfixAmpersandOperator + | INFIX_STAR_DIV_MOD_OP _ -> FSharpTokenKind.InfixStarDivideModuloOperator + | PREFIX_OP _ -> FSharpTokenKind.PrefixOperator + | INFIX_BAR_OP _ -> FSharpTokenKind.InfixBarOperator + | INFIX_AT_HAT_OP _ -> FSharpTokenKind.InfixAtHatOperator + | INFIX_COMPARE_OP _ -> FSharpTokenKind.InfixCompareOperator + | INFIX_STAR_STAR_OP _ -> FSharpTokenKind.InfixStarStarOperator + | IDENT _ -> FSharpTokenKind.Identifier + | KEYWORD_STRING _ -> FSharpTokenKind.KeywordString + | INTERP_STRING_BEGIN_END _ + | INTERP_STRING_BEGIN_PART _ + | INTERP_STRING_PART _ + | INTERP_STRING_END _ + | STRING _ -> FSharpTokenKind.String + | BYTEARRAY _ -> FSharpTokenKind.ByteArray + | _ -> FSharpTokenKind.None + + member this.IsKeyword = + match this.Kind with + | FSharpTokenKind.Abstract + | FSharpTokenKind.And + | FSharpTokenKind.As + | FSharpTokenKind.Assert + | FSharpTokenKind.OffsideAssert + | FSharpTokenKind.Base + | FSharpTokenKind.Begin + | FSharpTokenKind.Class + | FSharpTokenKind.Default + | FSharpTokenKind.Delegate + | FSharpTokenKind.Do + | FSharpTokenKind.OffsideDo + | FSharpTokenKind.Done + | FSharpTokenKind.Downcast + | FSharpTokenKind.DownTo + | FSharpTokenKind.Elif + | FSharpTokenKind.Else + | FSharpTokenKind.OffsideElse + | FSharpTokenKind.End + | FSharpTokenKind.OffsideEnd + | FSharpTokenKind.Exception + | FSharpTokenKind.Extern + | FSharpTokenKind.False + | FSharpTokenKind.Finally + | FSharpTokenKind.Fixed + | FSharpTokenKind.For + | FSharpTokenKind.Fun + | FSharpTokenKind.OffsideFun + | FSharpTokenKind.Function + | FSharpTokenKind.OffsideFunction + | FSharpTokenKind.Global + | FSharpTokenKind.If + | FSharpTokenKind.In + | FSharpTokenKind.Inherit + | FSharpTokenKind.Inline + | FSharpTokenKind.Interface + | FSharpTokenKind.OffsideInterfaceMember + | FSharpTokenKind.Internal + | FSharpTokenKind.Lazy + | FSharpTokenKind.OffsideLazy + | FSharpTokenKind.Let // "let" and "use" + | FSharpTokenKind.OffsideLet + | FSharpTokenKind.DoBang // "let!", "use!" and "do!" + | FSharpTokenKind.OffsideDoBang + | FSharpTokenKind.Match + | FSharpTokenKind.MatchBang + | FSharpTokenKind.Member + | FSharpTokenKind.Module + | FSharpTokenKind.Mutable + | FSharpTokenKind.Namespace + | FSharpTokenKind.New + // | FSharpTokenKind.Not // Not actually a keyword. However, not struct in combination is used as a generic parameter constraint. + | FSharpTokenKind.Null + | FSharpTokenKind.Of + | FSharpTokenKind.Open + | FSharpTokenKind.Or + | FSharpTokenKind.Override + | FSharpTokenKind.Private + | FSharpTokenKind.Public + | FSharpTokenKind.Rec + | FSharpTokenKind.Yield // "yield" and "return" + | FSharpTokenKind.YieldBang // "yield!" and "return!" + | FSharpTokenKind.Static + | FSharpTokenKind.Struct + | FSharpTokenKind.Then + | FSharpTokenKind.To + | FSharpTokenKind.True + | FSharpTokenKind.Try + | FSharpTokenKind.Type + | FSharpTokenKind.Upcast + | FSharpTokenKind.Val + | FSharpTokenKind.Void + | FSharpTokenKind.When + | FSharpTokenKind.While + | FSharpTokenKind.With + | FSharpTokenKind.OffsideWith + + // * Reserved - from OCAML * + | FSharpTokenKind.Asr + | FSharpTokenKind.InfixAsr + | FSharpTokenKind.InfixLand + | FSharpTokenKind.InfixLor + | FSharpTokenKind.InfixLsl + | FSharpTokenKind.InfixLsr + | FSharpTokenKind.InfixLxor + | FSharpTokenKind.InfixMod + | FSharpTokenKind.Sig + + // * Reserved - for future * + // atomic + // break + // checked + // component + // const + // constraint + // constructor + // continue + // eager + // event + // external + // functor + // include + // method + // mixin + // object + // parallel + // process + // protected + // pure + // sealed + // tailcall + // trait + // virtual + // volatile + | FSharpTokenKind.Reserved + | FSharpTokenKind.KeywordString + | FSharpTokenKind.Binder + | FSharpTokenKind.OffsideBinder -> true + | _ -> false + + member this.IsIdentifier = + match this.Kind with + | FSharpTokenKind.Identifier -> true + | _ -> false + + member this.IsStringLiteral = + match this.Kind with + | FSharpTokenKind.String -> true + | _ -> false + + member this.IsNumericLiteral = + match this.Kind with + | FSharpTokenKind.UInt8 + | FSharpTokenKind.UInt16 + | FSharpTokenKind.UInt64 + | FSharpTokenKind.Int8 + | FSharpTokenKind.Int16 + | FSharpTokenKind.Int32 + | FSharpTokenKind.Int64 + | FSharpTokenKind.Ieee32 + | FSharpTokenKind.Ieee64 + | FSharpTokenKind.BigNumber -> true + | _ -> false + + member this.IsCommentTrivia = + match this.Kind with + | FSharpTokenKind.CommentTrivia + | FSharpTokenKind.LineCommentTrivia -> true + | _ -> false + +[] +module FSharpLexerImpl = + let lexWithErrorLogger (text: ISourceText) conditionalCompilationDefines (flags: FSharpLexerFlags) reportLibraryOnlyFeatures langVersion errorLogger onToken pathMap (ct: CancellationToken) = + let canSkipTrivia = (flags &&& FSharpLexerFlags.SkipTrivia) = FSharpLexerFlags.SkipTrivia + let isLightSyntaxOn = (flags &&& FSharpLexerFlags.LightSyntaxOn) = FSharpLexerFlags.LightSyntaxOn + let isCompiling = (flags &&& FSharpLexerFlags.Compiling) = FSharpLexerFlags.Compiling + let isCompilingFSharpCore = (flags &&& FSharpLexerFlags.CompilingFSharpCore) = FSharpLexerFlags.CompilingFSharpCore + let canUseLexFilter = (flags &&& FSharpLexerFlags.UseLexFilter) = FSharpLexerFlags.UseLexFilter + + let lexbuf = UnicodeLexing.SourceTextAsLexbuf(reportLibraryOnlyFeatures, langVersion, text) + let lightStatus = LightSyntaxStatus(isLightSyntaxOn, true) + let lexargs = mkLexargs (conditionalCompilationDefines, lightStatus, LexResourceManager(0), [], errorLogger, pathMap) + let lexargs = { lexargs with applyLineDirectives = isCompiling } + + let getNextToken = + let lexer = Lexer.token lexargs canSkipTrivia + + if canUseLexFilter then + let lexFilter = LexFilter.LexFilter(lexargs.lightStatus, isCompilingFSharpCore, lexer, lexbuf) + (fun _ -> lexFilter.GetToken()) + else + lexer + + use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse + use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> DiscardErrorsLogger) + + resetLexbufPos "" lexbuf + while not lexbuf.IsPastEndOfStream do + ct.ThrowIfCancellationRequested () + onToken (getNextToken lexbuf) lexbuf.LexemeRange + + let lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures langVersion lexCallback pathMap ct = + let errorLogger = CompilationErrorLogger("Lexer", FSharpDiagnosticOptions.Default) + lexWithErrorLogger text conditionalCompilationDefines flags reportLibraryOnlyFeatures langVersion errorLogger lexCallback pathMap ct + +[] +type FSharpLexer = + + static member Tokenize(text: ISourceText, tokenCallback, ?langVersion, ?filePath: string, ?conditionalCompilationDefines, ?flags, ?pathMap, ?ct) = + let langVersion = defaultArg langVersion "latestmajor" |> LanguageVersion + let flags = defaultArg flags FSharpLexerFlags.Default + ignore filePath // can be removed at later point + let conditionalCompilationDefines = defaultArg conditionalCompilationDefines [] + let pathMap = defaultArg pathMap Map.Empty + let ct = defaultArg ct CancellationToken.None + + let pathMap = + (PathMap.empty, pathMap) + ||> Seq.fold (fun state pair -> state |> PathMap.addMapping pair.Key pair.Value) + + let onToken tok m = + let fsTok = FSharpToken(tok, m) + match fsTok.Kind with + | FSharpTokenKind.None -> () + | _ -> tokenCallback fsTok + + let reportLibraryOnlyFeatures = true + lex text conditionalCompilationDefines flags reportLibraryOnlyFeatures langVersion onToken pathMap ct diff --git a/src/fsharp/service/ServiceLexing.fsi b/src/fsharp/service/ServiceLexing.fsi index b4f24866b9c..49f1e6cc177 100755 --- a/src/fsharp/service/ServiceLexing.fsi +++ b/src/fsharp/service/ServiceLexing.fsi @@ -1,18 +1,23 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Tokenization -open FSharp.Compiler +open System +open System.Threading +open FSharp.Compiler +open FSharp.Compiler.Text -type Position = int * int -type Range = Position * Position +// Prevents warnings of experimental APIs within the signature file itself. +#nowarn "57" /// Represents encoded information for the end-of-line continuation of lexing [] type FSharpTokenizerLexState = { PosBits: int64 OtherBits: int64 } + static member Initial : FSharpTokenizerLexState + member Equals : FSharpTokenizerLexState -> bool /// Represents stable information for the state of the lexing engine at the end of a line @@ -76,122 +81,194 @@ type FSharpTokenCharKind = module FSharpTokenTag = /// Indicates the token is an identifier val Identifier: int + /// Indicates the token is a string val String : int + /// Indicates the token is an identifier (synonym for FSharpTokenTag.Identifier) val IDENT : int - /// Indicates the token is an string (synonym for FSharpTokenTag.String) + + /// Indicates the token is a string (synonym for FSharpTokenTag.String) val STRING : int + + /// Indicates the token is a part of an interpolated string + val INTERP_STRING_BEGIN_END : int + + /// Indicates the token is a part of an interpolated string + val INTERP_STRING_BEGIN_PART : int + + /// Indicates the token is a part of an interpolated string + val INTERP_STRING_PART : int + + /// Indicates the token is a part of an interpolated string + val INTERP_STRING_END : int + /// Indicates the token is a `(` val LPAREN : int + /// Indicates the token is a `)` val RPAREN : int + /// Indicates the token is a `[` val LBRACK : int + /// Indicates the token is a `]` val RBRACK : int + /// Indicates the token is a `{` val LBRACE : int + /// Indicates the token is a `}` val RBRACE : int + /// Indicates the token is a `[<` val LBRACK_LESS : int + /// Indicates the token is a `>]` val GREATER_RBRACK : int + /// Indicates the token is a `<` val LESS : int + /// Indicates the token is a `>` val GREATER : int + /// Indicates the token is a `[|` val LBRACK_BAR : int + /// Indicates the token is a `|]` val BAR_RBRACK : int + /// Indicates the token is a `+` or `-` val PLUS_MINUS_OP : int + /// Indicates the token is a `-` val MINUS : int + /// Indicates the token is a `*` val STAR : int + /// Indicates the token is a `%` val INFIX_STAR_DIV_MOD_OP : int + /// Indicates the token is a `%` val PERCENT_OP : int + /// Indicates the token is a `^` val INFIX_AT_HAT_OP : int + /// Indicates the token is a `?` val QMARK : int + /// Indicates the token is a `:` val COLON : int + /// Indicates the token is a `=` val EQUALS : int + /// Indicates the token is a `;` val SEMICOLON : int + /// Indicates the token is a `,` val COMMA : int + /// Indicates the token is a `.` val DOT : int + /// Indicates the token is a `..` val DOT_DOT : int + /// Indicates the token is a `..` val DOT_DOT_HAT : int + /// Indicates the token is a `..^` val INT32_DOT_DOT : int + /// Indicates the token is a `..` val UNDERSCORE : int + /// Indicates the token is a `_` val BAR : int + /// Indicates the token is a `:>` val COLON_GREATER : int + /// Indicates the token is a `:?>` val COLON_QMARK_GREATER : int + /// Indicates the token is a `:?` val COLON_QMARK : int + /// Indicates the token is a `|` val INFIX_BAR_OP : int + /// Indicates the token is a `|` val INFIX_COMPARE_OP : int + /// Indicates the token is a `::` val COLON_COLON : int + /// Indicates the token is a `@@` val AMP_AMP : int + /// Indicates the token is a `~` val PREFIX_OP : int + /// Indicates the token is a `:=` val COLON_EQUALS : int + /// Indicates the token is a `||` val BAR_BAR : int + /// Indicates the token is a `->` val RARROW : int + /// Indicates the token is a `<-` val LARROW : int + /// Indicates the token is a `"` val QUOTE : int + /// Indicates the token is a whitespace val WHITESPACE : int + /// Indicates the token is a comment + val COMMENT : int /// Indicates the token is a line comment + val LINE_COMMENT : int + /// Indicates the token is keyword `begin` val BEGIN : int + /// Indicates the token is keyword `do` val DO : int + /// Indicates the token is keyword `function` val FUNCTION : int + /// Indicates the token is keyword `then` val THEN : int + /// Indicates the token is keyword `else` val ELSE : int + /// Indicates the token is keyword `struct` val STRUCT : int + /// Indicates the token is keyword `class` val CLASS : int + /// Indicates the token is keyword `try` val TRY : int + /// Indicates the token is keyword `with` val WITH : int + /// Indicates the token is keyword `with` in #light val OWITH : int + /// Indicates the token is keyword `new` val NEW : int @@ -230,29 +307,275 @@ type FSharpTokenInfo = [] type FSharpLineTokenizer = /// Scan one token from the line - member ScanToken : lexState:FSharpTokenizerLexState -> FSharpTokenInfo option * FSharpTokenizerLexState - static member ColorStateOfLexState : FSharpTokenizerLexState -> FSharpTokenizerColorState - static member LexStateOfColorState : FSharpTokenizerColorState -> FSharpTokenizerLexState + member ScanToken: lexState:FSharpTokenizerLexState -> FSharpTokenInfo option * FSharpTokenizerLexState + + /// Get the color state from the lexer state + static member ColorStateOfLexState: FSharpTokenizerLexState -> FSharpTokenizerColorState + + /// Get a default lexer state for a color state. + /// + /// NOTE: This may result in an inaccurate lexer state + /// not taking into account things such as the #if/#endif and string interpolation context + /// within the file + static member LexStateOfColorState: FSharpTokenizerColorState -> FSharpTokenizerLexState /// Tokenizer for a source file. Holds some expensive-to-compute resources at the scope of the file. [] type FSharpSourceTokenizer = - new : conditionalDefines:string list * fileName:string option -> FSharpSourceTokenizer - member CreateLineTokenizer : lineText:string -> FSharpLineTokenizer + + /// Create a tokenizer for a source file. + new : conditionalDefines:string list * filename:string option -> FSharpSourceTokenizer + + /// Create a tokenizer for a line of this source file + member CreateLineTokenizer: lineText:string -> FSharpLineTokenizer + + /// Create a tokenizer for a line of this source file using a buffer filler member CreateBufferTokenizer : bufferFiller:(char[] * int * int -> int) -> FSharpLineTokenizer module internal TestExpose = - val TokenInfo : Parser.token -> (FSharpTokenColorKind * FSharpTokenCharKind * FSharpTokenTriggerClass) + val TokenInfo : Parser.token -> FSharpTokenColorKind * FSharpTokenCharKind * FSharpTokenTriggerClass -module Keywords = +module FSharpKeywords = /// Checks if adding backticks to identifier is needed. - val DoesIdentifierNeedQuotation : string -> bool + val DoesIdentifierNeedBackticks : string -> bool /// Add backticks if the identifier is a keyword. - val QuoteIdentifierIfNeeded : string -> string + /// A utility to help determine if an identifier needs to be quoted, this doesn't quote F# keywords. + val AddBackticksToIdentifierIfNeeded : string -> string /// Remove backticks if present. val NormalizeIdentifierBackticks : string -> string /// Keywords paired with their descriptions. Used in completion and quick info. val KeywordsWithDescription : (string * string) list + + /// All the keywords in the F# language + val KeywordNames: string list + +[] +type public FSharpLexerFlags = + | Default = 0x11011 + | LightSyntaxOn = 0x00001 + | Compiling = 0x00010 + | CompilingFSharpCore = 0x00110 + | SkipTrivia = 0x01000 + | UseLexFilter = 0x10000 + +[] +type public FSharpTokenKind = + | None + | HashIf + | HashElse + | HashEndIf + | CommentTrivia + | WhitespaceTrivia + | HashLine + | HashLight + | InactiveCode + | LineCommentTrivia + | StringText + | Fixed + | OffsideInterfaceMember + | OffsideBlockEnd + | OffsideRightBlockEnd + | OffsideDeclEnd + | OffsideEnd + | OffsideBlockSep + | OffsideBlockBegin + | OffsideReset + | OffsideFun + | OffsideFunction + | OffsideWith + | OffsideElse + | OffsideThen + | OffsideDoBang + | OffsideDo + | OffsideBinder + | OffsideLet + | HighPrecedenceTypeApp + | HighPrecedenceParenthesisApp + | HighPrecedenceBracketApp + | Extern + | Void + | Public + | Private + | Internal + | Global + | Static + | Member + | Class + | Abstract + | Override + | Default + | Constructor + | Inherit + | GreaterRightBracket + | Struct + | Sig + | Bar + | RightBracket + | RightBrace + | Minus + | Dollar + | BarRightBracket + | BarRightBrace + | Underscore + | Semicolon + | SemicolonSemicolon + | LeftArrow + | Equals + | LeftBracket + | LeftBracketBar + | LeftBraceBar + | LeftBracketLess + | LeftBrace + | QuestionMark + | QuestionMarkQuestionMark + | Dot + | Colon + | ColonColon + | ColonGreater + | ColonQuestionMark + | ColonQuestionMarkGreater + | ColonEquals + | When + | While + | With + | Hash + | Ampersand + | AmpersandAmpersand + | Quote + | LeftParenthesis + | RightParenthesis + | Star + | Comma + | RightArrow + | GreaterBarRightBracket + | LeftParenthesisStarRightParenthesis + | Open + | Or + | Rec + | Then + | To + | True + | Try + | Type + | Val + | Inline + | Interface + | Instance + | Const + | Lazy + | OffsideLazy + | Match + | MatchBang + | Mutable + | New + | Of + | Exception + | False + | For + | Fun + | Function + | If + | In + | JoinIn + | Finally + | DoBang + | And + | As + | Assert + | OffsideAssert + | Begin + | Do + | Done + | DownTo + | Else + | Elif + | End + | DotDot + | DotDotHat + | BarBar + | Upcast + | Downcast + | Null + | Reserved + | Module + | Namespace + | Delegate + | Constraint + | Base + | LeftQuote + | RightQuote + | RightQuoteDot + | PercentOperator + | Binder + | Less + | Greater + | Let + | Yield + | YieldBang + | BigNumber + | Decimal + | Char + | Ieee64 + | Ieee32 + | NativeInt + | UNativeInt + | UInt64 + | UInt32 + | UInt16 + | UInt8 + | Int64 + | Int32 + | Int32DotDot + | Int16 + | Int8 + | FunkyOperatorName + | AdjacentPrefixOperator + | PlusMinusOperator + | InfixAmpersandOperator + | InfixStarDivideModuloOperator + | PrefixOperator + | InfixBarOperator + | InfixAtHatOperator + | InfixCompareOperator + | InfixStarStarOperator + | Identifier + | KeywordString + | String + | ByteArray + | Asr + | InfixAsr + | InfixLand + | InfixLor + | InfixLsl + | InfixLsr + | InfixLxor + | InfixMod + +[] +type public FSharpToken = + + val private tok: Parser.token + val private tokRange: range + + member Range: range + + member Kind: FSharpTokenKind + + member IsIdentifier: bool + + member IsKeyword: bool + + member IsStringLiteral: bool + + member IsNumericLiteral: bool + + member IsCommentTrivia: bool + +[] +type public FSharpLexer = + + [] + static member Tokenize: text: ISourceText * tokenCallback: (FSharpToken -> unit) * ?langVersion: string * ?filePath: string * ?conditionalCompilationDefines: string list * ?flags: FSharpLexerFlags * ?pathMap: Map * ?ct: CancellationToken -> unit diff --git a/src/fsharp/service/ServiceNavigation.fs b/src/fsharp/service/ServiceNavigation.fs index dbecc3b101b..f60ae12e2fc 100755 --- a/src/fsharp/service/ServiceNavigation.fs +++ b/src/fsharp/service/ServiceNavigation.fs @@ -5,25 +5,30 @@ // type checking and intellisense-like environment-reporting. //-------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open System +open System.Collections.Generic +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range /// Represents the different kinds of items that can appear in the navigation bar -type FSharpNavigationDeclarationItemKind = - | NamespaceDecl - | ModuleFileDecl - | ExnDecl - | ModuleDecl - | TypeDecl - | MethodDecl - | PropertyDecl - | FieldDecl - | OtherDecl +[] +type NavigationItemKind = + | Namespace + | ModuleFile + | Exception + | Module + | Type + | Method + | Property + | Field + | Other [] -type FSharpEnclosingEntityKind = +type NavigationEntityKind = | Namespace | Module | Class @@ -31,55 +36,55 @@ type FSharpEnclosingEntityKind = | Interface | Record | Enum - | DU + | Union /// Represents an item to be displayed in the navigation bar [] -type FSharpNavigationDeclarationItem(uniqueName: string, name: string, kind: FSharpNavigationDeclarationItemKind, glyph: FSharpGlyph, range: range, - bodyRange: range, singleTopLevel: bool, enclosingEntityKind: FSharpEnclosingEntityKind, isAbstract: bool, access: SynAccess option) = +type NavigationItem(uniqueName: string, name: string, kind: NavigationItemKind, glyph: FSharpGlyph, range: range, + bodyRange: range, singleTopLevel: bool, enclosingEntityKind: NavigationEntityKind, isAbstract: bool, access: SynAccess option) = - member x.bodyRange = bodyRange - member x.UniqueName = uniqueName - member x.Name = name - member x.Glyph = glyph - member x.Kind = kind - member x.Range = range - member x.BodyRange = bodyRange - member x.IsSingleTopLevel = singleTopLevel - member x.EnclosingEntityKind = enclosingEntityKind - member x.IsAbstract = isAbstract + member _.bodyRange = bodyRange + member _.UniqueName = uniqueName + member _.Name = name + member _.Glyph = glyph + member _.Kind = kind + member _.Range = range + member _.BodyRange = bodyRange + member _.IsSingleTopLevel = singleTopLevel + member _.EnclosingEntityKind = enclosingEntityKind + member _.IsAbstract = isAbstract - member x.Access = access + member _.Access = access - member x.WithUniqueName(uniqueName: string) = - FSharpNavigationDeclarationItem(uniqueName, name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access) + member _.WithUniqueName(uniqueName: string) = + NavigationItem(uniqueName, name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access) static member Create(name: string, kind, glyph: FSharpGlyph, range: range, bodyRange: range, singleTopLevel: bool, enclosingEntityKind, isAbstract, access: SynAccess option) = - FSharpNavigationDeclarationItem("", name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access) + NavigationItem("", name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access) /// Represents top-level declarations (that should be in the type drop-down) /// with nested declarations (that can be shown in the member drop-down) [] -type FSharpNavigationTopLevelDeclaration = - { Declaration: FSharpNavigationDeclarationItem - Nested: FSharpNavigationDeclarationItem[] } +type NavigationTopLevelDeclaration = + { Declaration: NavigationItem + Nested: NavigationItem[] } /// Represents result of 'GetNavigationItems' operation - this contains /// all the members and currently selected indices. First level correspond to /// types & modules and second level are methods etc. [] -type FSharpNavigationItems(declarations:FSharpNavigationTopLevelDeclaration[]) = - member x.Declarations = declarations +type NavigationItems(declarations:NavigationTopLevelDeclaration[]) = + member _.Declarations = declarations module NavigationImpl = let unionRangesChecked r1 r2 = - if FSharp.Compiler.Range.equals r1 range.Zero then r2 - elif FSharp.Compiler.Range.equals r2 range.Zero then r1 + if equals r1 range.Zero then r2 + elif equals r2 range.Zero then r1 else unionRanges r1 r2 let rangeOfDecls2 f decls = - match (decls |> List.map (f >> (fun (d:FSharpNavigationDeclarationItem) -> d.bodyRange))) with - | hd :: tl -> tl |> List.fold unionRangesChecked hd - | [] -> range.Zero + match decls |> List.map (f >> (fun (d:NavigationItem) -> d.bodyRange)) with + | hd :: tl -> tl |> List.fold unionRangesChecked hd + | [] -> range.Zero let rangeOfDecls = rangeOfDecls2 fst @@ -88,8 +93,8 @@ module NavigationImpl = let fldspecRange fldspec = match fldspec with - | UnionCaseFields(flds) -> flds |> List.fold (fun st (Field(_, _, _, _, _, _, _, m)) -> unionRangesChecked m st) range.Zero - | UnionCaseFullType(ty, _) -> ty.Range + | SynUnionCaseKind.Fields(flds) -> flds |> List.fold (fun st (SynField(_, _, _, _, _, _, _, m)) -> unionRangesChecked m st) range.Zero + | SynUnionCaseKind.FullType(ty, _) -> ty.Range let bodyRange mb decls = unionRangesChecked (rangeOfDecls decls) mb @@ -97,37 +102,40 @@ module NavigationImpl = /// Get information for implementation file let getNavigationFromImplFile (modules: SynModuleOrNamespace list) = // Map for dealing with name conflicts - let mutable nameMap = Map.empty + let names = Dictionary() let addItemName name = - let count = defaultArg (nameMap |> Map.tryFind name) 0 - nameMap <- (Map.add name (count + 1) (nameMap)) - (count + 1) + let count = + match names.TryGetValue name with + | true, count -> count + 1 + | _ -> 1 + names.[name] <- count + count let uniqueName name idx = - let total = Map.find name nameMap + let total = names.[name] sprintf "%s_%d_of_%d" name idx total // Create declaration (for the left dropdown) let createDeclLid(baseName, lid, kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract, access) = let name = (if baseName <> "" then baseName + "." else "") + (textOfLid lid) - FSharpNavigationDeclarationItem.Create + NavigationItem.Create (name, kind, baseGlyph, m, bodym, false, enclosingEntityKind, isAbstract, access), (addItemName name), nested let createDecl(baseName, id:Ident, kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract, access) = - let name = (if baseName <> "" then baseName + "." else "") + (id.idText) - FSharpNavigationDeclarationItem.Create + let name = (if baseName <> "" then baseName + "." else "") + id.idText + NavigationItem.Create (name, kind, baseGlyph, m, bodym, false, enclosingEntityKind, isAbstract, access), (addItemName name), nested // Create member-kind-of-thing for the right dropdown let createMemberLid(lid, kind, baseGlyph, m, enclosingEntityKind, isAbstract, access) = - FSharpNavigationDeclarationItem.Create(textOfLid lid, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(textOfLid lid)) + NavigationItem.Create(textOfLid lid, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(textOfLid lid)) let createMember(id:Ident, kind, baseGlyph, m, enclosingEntityKind, isAbstract, access) = - FSharpNavigationDeclarationItem.Create(id.idText, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(id.idText)) + NavigationItem.Create(id.idText, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(id.idText)) // Process let-binding - let processBinding isMember enclosingEntityKind isAbstract (Binding(_, _, _, _, _, _, SynValData(memberOpt, _, _), synPat, _, synExpr, _, _)) = + let processBinding isMember enclosingEntityKind isAbstract (SynBinding(_, _, _, _, _, _, SynValData(memberOpt, _, _), synPat, _, synExpr, _, _)) = let m = match synExpr with | SynExpr.Typed (e, _, _) -> e.Range // fix range for properties with type annotations @@ -137,13 +145,13 @@ module NavigationImpl = | SynPat.LongIdent(longDotId=LongIdentWithDots(lid,_); accessibility=access), Some(flags) when isMember -> let icon, kind = match flags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.Member -> - (if flags.IsOverrideOrExplicitImpl then FSharpGlyph.OverridenMethod else FSharpGlyph.Method), MethodDecl - | MemberKind.PropertyGetSet - | MemberKind.PropertySet - | MemberKind.PropertyGet -> FSharpGlyph.Property, PropertyDecl + | SynMemberKind.ClassConstructor + | SynMemberKind.Constructor + | SynMemberKind.Member -> + (if flags.IsOverrideOrExplicitImpl then FSharpGlyph.OverridenMethod else FSharpGlyph.Method), NavigationItemKind.Method + | SynMemberKind.PropertyGetSet + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGet -> FSharpGlyph.Property, NavigationItemKind.Property let lidShow, rangeMerge = match lid with | _thisVar :: nm :: _ -> (List.tail lid, nm.idRange) @@ -151,63 +159,66 @@ module NavigationImpl = | _ -> (lid, m) [ createMemberLid(lidShow, kind, icon, unionRanges rangeMerge m, enclosingEntityKind, isAbstract, access) ] | SynPat.LongIdent(LongIdentWithDots(lid,_), _, _, _, access, _), _ -> - [ createMemberLid(lid, FieldDecl, FSharpGlyph.Field, unionRanges (List.head lid).idRange m, enclosingEntityKind, isAbstract, access) ] - | SynPat.Named(_, id, _, access, _), _ -> + [ createMemberLid(lid, NavigationItemKind.Field, FSharpGlyph.Field, unionRanges (List.head lid).idRange m, enclosingEntityKind, isAbstract, access) ] + | SynPat.Named (id, _, access, _), _ | SynPat.As(_, SynPat.Named (id, _, access, _), _), _ -> let glyph = if isMember then FSharpGlyph.Method else FSharpGlyph.Field - [ createMember(id, FieldDecl, glyph, unionRanges id.idRange m, enclosingEntityKind, isAbstract, access) ] + [ createMember(id, NavigationItemKind.Field, glyph, unionRanges id.idRange m, enclosingEntityKind, isAbstract, access) ] | _ -> [] // Process a class declaration or F# type declaration - let rec processExnDefnRepr baseName nested (SynExceptionDefnRepr(_, (UnionCase(_, id, fldspec, _, _, _)), _, _, access, m)) = + let rec processExnDefnRepr baseName nested (SynExceptionDefnRepr(_, SynUnionCase(_, id, fldspec, _, _, _), _, _, access, m)) = // Exception declaration - [ createDecl(baseName, id, ExnDecl, FSharpGlyph.Exception, m, fldspecRange fldspec, nested, FSharpEnclosingEntityKind.Exception, false, access) ] + [ createDecl(baseName, id, NavigationItemKind.Exception, FSharpGlyph.Exception, m, fldspecRange fldspec, nested, NavigationEntityKind.Exception, false, access) ] // Process a class declaration or F# type declaration and processExnDefn baseName (SynExceptionDefn(repr, membDefns, _)) = - let nested = processMembers membDefns FSharpEnclosingEntityKind.Exception |> snd + let nested = processMembers membDefns NavigationEntityKind.Exception |> snd processExnDefnRepr baseName nested repr - and processTycon baseName (TypeDefn(ComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, m)) = - let topMembers = processMembers membDefns FSharpEnclosingEntityKind.Class |> snd + and processTycon baseName (SynTypeDefn(SynComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, _, m)) = + let topMembers = processMembers membDefns NavigationEntityKind.Class |> snd match repr with | SynTypeDefnRepr.Exception repr -> processExnDefnRepr baseName [] repr | SynTypeDefnRepr.ObjectModel(_, membDefns, mb) -> // F# class declaration - let members = processMembers membDefns FSharpEnclosingEntityKind.Class |> snd + let members = processMembers membDefns NavigationEntityKind.Class |> snd let nested = members@topMembers - ([ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Class, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Class, false, access) ]: ((FSharpNavigationDeclarationItem * int * _) list)) + ([ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Class, m, bodyRange mb nested, nested, NavigationEntityKind.Class, false, access) ]: (NavigationItem * int * _) list) | SynTypeDefnRepr.Simple(simple, _) -> // F# type declaration match simple with | SynTypeDefnSimpleRepr.Union(_, cases, mb) -> let cases = - [ for (UnionCase(_, id, fldspec, _, _, _)) in cases -> - createMember(id, OtherDecl, FSharpGlyph.Struct, unionRanges (fldspecRange fldspec) id.idRange, FSharpEnclosingEntityKind.DU, false, access) ] + [ for SynUnionCase(_, id, fldspec, _, _, _) in cases -> + createMember(id, NavigationItemKind.Other, FSharpGlyph.Struct, unionRanges (fldspecRange fldspec) id.idRange, NavigationEntityKind.Union, false, access) ] let nested = cases@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Union, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.DU, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Union, m, bodyRange mb nested, nested, NavigationEntityKind.Union, false, access) ] | SynTypeDefnSimpleRepr.Enum(cases, mb) -> let cases = - [ for (EnumCase(_, id, _, _, m)) in cases -> - createMember(id, FieldDecl, FSharpGlyph.EnumMember, m, FSharpEnclosingEntityKind.Enum, false, access) ] + [ for SynEnumCase(_, id, _, _, _, m) in cases -> + createMember(id, NavigationItemKind.Field, FSharpGlyph.EnumMember, m, NavigationEntityKind.Enum, false, access) ] let nested = cases@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Enum, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Enum, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Enum, m, bodyRange mb nested, nested, NavigationEntityKind.Enum, false, access) ] | SynTypeDefnSimpleRepr.Record(_, fields, mb) -> let fields = - [ for (Field(_, _, id, _, _, _, _, m)) in fields do - if (id.IsSome) then - yield createMember(id.Value, FieldDecl, FSharpGlyph.Field, m, FSharpEnclosingEntityKind.Record, false, access) ] + [ for SynField(_, _, id, _, _, _, _, m) in fields do + match id with + | Some ident -> + yield createMember(ident, NavigationItemKind.Field, FSharpGlyph.Field, m, NavigationEntityKind.Record, false, access) + | _ -> + () ] let nested = fields@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Type, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Record, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Type, m, bodyRange mb nested, nested, NavigationEntityKind.Record, false, access) ] | SynTypeDefnSimpleRepr.TypeAbbrev(_, _, mb) -> - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Typedef, m, bodyRange mb topMembers, topMembers, FSharpEnclosingEntityKind.Class, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Typedef, m, bodyRange mb topMembers, topMembers, NavigationEntityKind.Class, false, access) ] - //| SynTypeDefnSimpleRepr.General of TyconKind * (SynType * range * ident option) list * (valSpfn * MemberFlags) list * fieldDecls * bool * bool * range - //| SynTypeDefnSimpleRepr.LibraryOnlyILAssembly of ILType * range - //| TyconCore_repr_hidden of range + //| SynTypeDefnSimpleRepr.General of TyconKind * (SynType * Range * ident option) list * (valSpfn * MemberFlags) list * fieldDecls * bool * bool * Range + //| SynTypeDefnSimpleRepr.LibraryOnlyILAssembly of ILType * Range + //| TyconCore_repr_hidden of Range | _ -> [] // Returns class-members for the right dropdown - and processMembers members enclosingEntityKind : (range * list) = + and processMembers members enclosingEntityKind : range * list = let members = members |> List.groupBy (fun x -> x.Range) @@ -218,19 +229,19 @@ module NavigationImpl = match memb with | SynMemberDefn.LetBindings(binds, _, _, _) -> List.collect (processBinding false enclosingEntityKind false) binds | SynMemberDefn.Member(bind, _) -> processBinding true enclosingEntityKind false bind - | SynMemberDefn.ValField(Field(_, _, Some(rcid), ty, _, _, access, _), _) -> - [ createMember(rcid, FieldDecl, FSharpGlyph.Field, ty.Range, enclosingEntityKind, false, access) ] + | SynMemberDefn.ValField(SynField(_, _, Some(rcid), _, _, _, access, range), _) -> + [ createMember(rcid, NavigationItemKind.Field, FSharpGlyph.Field, range, enclosingEntityKind, false, access) ] | SynMemberDefn.AutoProperty(_attribs,_isStatic,id,_tyOpt,_propKind,_,_xmlDoc, access,_synExpr, _, _) -> - [ createMember(id, FieldDecl, FSharpGlyph.Field, id.idRange, enclosingEntityKind, false, access) ] - | SynMemberDefn.AbstractSlot(ValSpfn(_, id, _, ty, _, _, _, _, access, _, _), _, _) -> - [ createMember(id, MethodDecl, FSharpGlyph.OverridenMethod, ty.Range, enclosingEntityKind, true, access) ] + [ createMember(id, NavigationItemKind.Field, FSharpGlyph.Field, id.idRange, enclosingEntityKind, false, access) ] + | SynMemberDefn.AbstractSlot(SynValSig(_, id, _, ty, _, _, _, _, access, _, _), _, _) -> + [ createMember(id, NavigationItemKind.Method, FSharpGlyph.OverridenMethod, ty.Range, enclosingEntityKind, true, access) ] | SynMemberDefn.NestedType _ -> failwith "tycon as member????" //processTycon tycon | SynMemberDefn.Interface(_, Some(membs), _) -> processMembers membs enclosingEntityKind |> snd | _ -> [] // can happen if one is a getter and one is a setter - | [SynMemberDefn.Member(memberDefn=Binding(headPat=SynPat.LongIdent(lid1, Some(info1),_,_,_,_)) as binding1) - SynMemberDefn.Member(memberDefn=Binding(headPat=SynPat.LongIdent(lid2, Some(info2),_,_,_,_)) as binding2)] -> + | [SynMemberDefn.Member(memberDefn=SynBinding(headPat=SynPat.LongIdent(lid1, Some(info1),_,_,_,_)) as binding1) + SynMemberDefn.Member(memberDefn=SynBinding(headPat=SynPat.LongIdent(lid2, Some(info2),_,_,_,_)) as binding2)] -> // ensure same long id assert((lid1.Lid,lid2.Lid) ||> List.forall2 (fun x y -> x.idText = y.idText)) // ensure one is getter, other is setter @@ -243,27 +254,27 @@ module NavigationImpl = | _ -> [])) (members |> Seq.map fst |> Seq.fold unionRangesChecked range.Zero), - (members |> List.map snd |> List.concat) + (members |> List.collect snd) // Process declarations in a module that belong to the right drop-down (let bindings) let processNestedDeclarations decls = decls |> List.collect (function - | SynModuleDecl.Let(_, binds, _) -> List.collect (processBinding false FSharpEnclosingEntityKind.Module false) binds + | SynModuleDecl.Let(_, binds, _) -> List.collect (processBinding false NavigationEntityKind.Module false) binds | _ -> []) // Process declarations nested in a module that should be displayed in the left dropdown // (such as type declarations, nested modules etc.) - let rec processFSharpNavigationTopLevelDeclarations(baseName, decls) = decls |> List.collect (function + let rec processNavigationTopLevelDeclarations(baseName, decls) = decls |> List.collect (function | SynModuleDecl.ModuleAbbrev(id, lid, m) -> - [ createDecl(baseName, id, ModuleDecl, FSharpGlyph.Module, m, rangeOfLid lid, [], FSharpEnclosingEntityKind.Namespace, false, None) ] + [ createDecl(baseName, id, NavigationItemKind.Module, FSharpGlyph.Module, m, rangeOfLid lid, [], NavigationEntityKind.Namespace, false, None) ] - | SynModuleDecl.NestedModule(ComponentInfo(_, _, _, lid, _, _, access, _), _isRec, decls, _, m) -> + | SynModuleDecl.NestedModule(SynComponentInfo(_, _, _, lid, _, _, access, _), _isRec, decls, _, m) -> // Find let bindings (for the right dropdown) let nested = processNestedDeclarations(decls) let newBaseName = (if (baseName = "") then "" else baseName+".") + (textOfLid lid) // Get nested modules and types (for the left dropdown) - let other = processFSharpNavigationTopLevelDeclarations(newBaseName, decls) - createDeclLid(baseName, lid, ModuleDecl, FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid lid) other), nested, FSharpEnclosingEntityKind.Module, false, access) :: other + let other = processNavigationTopLevelDeclarations(newBaseName, decls) + createDeclLid(baseName, lid, NavigationItemKind.Module, FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid lid) other), nested, NavigationEntityKind.Module, false, access) :: other | SynModuleDecl.Types(tydefs, _) -> tydefs |> List.collect (processTycon baseName) | SynModuleDecl.Exception (defn,_) -> processExnDefn baseName defn @@ -278,18 +289,18 @@ module NavigationImpl = // Find let bindings (for the right dropdown) let nested = processNestedDeclarations(decls) // Get nested modules and types (for the left dropdown) - let other = processFSharpNavigationTopLevelDeclarations(baseName, decls) + let other = processNavigationTopLevelDeclarations(baseName, decls) // Create explicitly - it can be 'single top level' thing that is hidden match id with | [] -> other | _ -> let decl = - FSharpNavigationDeclarationItem.Create - (textOfLid id, (if kind.IsModule then ModuleFileDecl else NamespaceDecl), + NavigationItem.Create + (textOfLid id, (if kind.IsModule then NavigationItemKind.ModuleFile else NavigationItemKind.Namespace), FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid id) other), - singleTopLevel, FSharpEnclosingEntityKind.Module, false, access), (addItemName(textOfLid id)), nested + singleTopLevel, NavigationEntityKind.Module, false, access), (addItemName(textOfLid id)), nested decl :: other) let items = @@ -300,7 +311,7 @@ module NavigationImpl = nest |> Array.sortInPlaceWith (fun a b -> compare a.Name b.Name) { Declaration = d.WithUniqueName(uniqueName d.Name idx); Nested = nest } ) items |> Array.sortInPlaceWith (fun a b -> compare a.Declaration.Name b.Declaration.Name) - new FSharpNavigationItems(items) + NavigationItems(items) /// Get information for signature file let getNavigationFromSigFile (modules: SynModuleOrNamespaceSig list) = @@ -308,7 +319,7 @@ module NavigationImpl = let mutable nameMap = Map.empty let addItemName name = let count = defaultArg (nameMap |> Map.tryFind name) 0 - nameMap <- (Map.add name (count + 1) (nameMap)) + nameMap <- (Map.add name (count + 1) nameMap) (count + 1) let uniqueName name idx = let total = Map.find name nameMap @@ -317,26 +328,26 @@ module NavigationImpl = // Create declaration (for the left dropdown) let createDeclLid(baseName, lid, kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract, access) = let name = (if baseName <> "" then baseName + "." else "") + (textOfLid lid) - FSharpNavigationDeclarationItem.Create + NavigationItem.Create (name, kind, baseGlyph, m, bodym, false, enclosingEntityKind, isAbstract, access), (addItemName name), nested let createDecl(baseName, id:Ident, kind, baseGlyph, m, bodym, nested, enclosingEntityKind, isAbstract, access) = - let name = (if baseName <> "" then baseName + "." else "") + (id.idText) - FSharpNavigationDeclarationItem.Create + let name = (if baseName <> "" then baseName + "." else "") + id.idText + NavigationItem.Create (name, kind, baseGlyph, m, bodym, false, enclosingEntityKind, isAbstract, access), (addItemName name), nested let createMember(id:Ident, kind, baseGlyph, m, enclosingEntityKind, isAbstract, access) = - FSharpNavigationDeclarationItem.Create(id.idText, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(id.idText)) + NavigationItem.Create(id.idText, kind, baseGlyph, m, m, false, enclosingEntityKind, isAbstract, access), (addItemName(id.idText)) - let rec processExnRepr baseName nested (SynExceptionDefnRepr(_, (UnionCase(_, id, fldspec, _, _, _)), _, _, access, m)) = + let rec processExnRepr baseName nested (SynExceptionDefnRepr(_, SynUnionCase(_, id, fldspec, _, _, _), _, _, access, m)) = // Exception declaration - [ createDecl(baseName, id, ExnDecl, FSharpGlyph.Exception, m, fldspecRange fldspec, nested, FSharpEnclosingEntityKind.Exception, false, access) ] + [ createDecl(baseName, id, NavigationItemKind.Exception, FSharpGlyph.Exception, m, fldspecRange fldspec, nested, NavigationEntityKind.Exception, false, access) ] and processExnSig baseName (SynExceptionSig(repr, memberSigs, _)) = let nested = processSigMembers memberSigs processExnRepr baseName nested repr - and processTycon baseName (TypeDefnSig(ComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, m)) = + and processTycon baseName (SynTypeDefnSig(SynComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, m)) = let topMembers = processSigMembers membDefns match repr with | SynTypeDefnSigRepr.Exception repr -> processExnRepr baseName [] repr @@ -344,66 +355,71 @@ module NavigationImpl = // F# class declaration let members = processSigMembers membDefns let nested = members @ topMembers - ([ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Class, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Class, false, access) ]: ((FSharpNavigationDeclarationItem * int * _) list)) + ([ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Class, m, bodyRange mb nested, nested, NavigationEntityKind.Class, false, access) ]: (NavigationItem * int * _) list) | SynTypeDefnSigRepr.Simple(simple, _) -> // F# type declaration match simple with | SynTypeDefnSimpleRepr.Union(_, cases, mb) -> let cases = - [ for (UnionCase(_, id, fldspec, _, _, _)) in cases -> - createMember(id, OtherDecl, FSharpGlyph.Struct, unionRanges (fldspecRange fldspec) id.idRange, FSharpEnclosingEntityKind.DU, false, access) ] + [ for SynUnionCase(_, id, fldspec, _, _, _) in cases -> + createMember(id, NavigationItemKind.Other, FSharpGlyph.Struct, unionRanges (fldspecRange fldspec) id.idRange, NavigationEntityKind.Union, false, access) ] let nested = cases@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Union, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.DU, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Union, m, bodyRange mb nested, nested, NavigationEntityKind.Union, false, access) ] | SynTypeDefnSimpleRepr.Enum(cases, mb) -> let cases = - [ for (EnumCase(_, id, _, _, m)) in cases -> - createMember(id, FieldDecl, FSharpGlyph.EnumMember, m, FSharpEnclosingEntityKind.Enum, false, access) ] + [ for SynEnumCase(_, id, _, _, _, m) in cases -> + createMember(id, NavigationItemKind.Field, FSharpGlyph.EnumMember, m, NavigationEntityKind.Enum, false, access) ] let nested = cases@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Enum, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Enum, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Enum, m, bodyRange mb nested, nested, NavigationEntityKind.Enum, false, access) ] | SynTypeDefnSimpleRepr.Record(_, fields, mb) -> let fields = - [ for (Field(_, _, id, _, _, _, _, m)) in fields do - if (id.IsSome) then - yield createMember(id.Value, FieldDecl, FSharpGlyph.Field, m, FSharpEnclosingEntityKind.Record, false, access) ] + [ for SynField(_, _, id, _, _, _, _, m) in fields do + match id with + | Some ident -> + yield createMember(ident, NavigationItemKind.Field, FSharpGlyph.Field, m, NavigationEntityKind.Record, false, access) + | _ -> + () ] let nested = fields@topMembers - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Type, m, bodyRange mb nested, nested, FSharpEnclosingEntityKind.Record, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Type, m, bodyRange mb nested, nested, NavigationEntityKind.Record, false, access) ] | SynTypeDefnSimpleRepr.TypeAbbrev(_, _, mb) -> - [ createDeclLid(baseName, lid, TypeDecl, FSharpGlyph.Typedef, m, bodyRange mb topMembers, topMembers, FSharpEnclosingEntityKind.Class, false, access) ] + [ createDeclLid(baseName, lid, NavigationItemKind.Type, FSharpGlyph.Typedef, m, bodyRange mb topMembers, topMembers, NavigationEntityKind.Class, false, access) ] //| SynTypeDefnSimpleRepr.General of TyconKind * (SynType * range * ident option) list * (valSpfn * MemberFlags) list * fieldDecls * bool * bool * range //| SynTypeDefnSimpleRepr.LibraryOnlyILAssembly of ILType * range //| TyconCore_repr_hidden of range | _ -> [] - and processSigMembers (members: SynMemberSig list): list = + and processSigMembers (members: SynMemberSig list): list = [ for memb in members do match memb with - | SynMemberSig.Member(SynValSig.ValSpfn(_, id, _, _, _, _, _, _, access, _, m), _, _) -> - yield createMember(id, MethodDecl, FSharpGlyph.Method, m, FSharpEnclosingEntityKind.Class, false, access) - | SynMemberSig.ValField(Field(_, _, Some(rcid), ty, _, _, access, _), _) -> - yield createMember(rcid, FieldDecl, FSharpGlyph.Field, ty.Range, FSharpEnclosingEntityKind.Class, false, access) + | SynMemberSig.Member(SynValSig.SynValSig(_, id, _, _, _, _, _, _, access, _, m), _, _) -> + yield createMember(id, NavigationItemKind.Method, FSharpGlyph.Method, m, NavigationEntityKind.Class, false, access) + | SynMemberSig.ValField(SynField(_, _, Some(rcid), ty, _, _, access, _), _) -> + yield createMember(rcid, NavigationItemKind.Field, FSharpGlyph.Field, ty.Range, NavigationEntityKind.Class, false, access) | _ -> () ] // Process declarations in a module that belong to the right drop-down (let bindings) let processNestedSigDeclarations decls = decls |> List.collect (function - | SynModuleSigDecl.Val(SynValSig.ValSpfn(_, id, _, _, _, _, _, _, access, _, m), _) -> - [ createMember(id, MethodDecl, FSharpGlyph.Method, m, FSharpEnclosingEntityKind.Module, false, access) ] + | SynModuleSigDecl.Val(SynValSig.SynValSig(_, id, _, _, _, _, _, _, access, _, m), _) -> + [ createMember(id, NavigationItemKind.Method, FSharpGlyph.Method, m, NavigationEntityKind.Module, false, access) ] | _ -> [] ) // Process declarations nested in a module that should be displayed in the left dropdown // (such as type declarations, nested modules etc.) - let rec processFSharpNavigationTopLevelSigDeclarations(baseName, decls) = decls |> List.collect (function + let rec processNavigationTopLevelSigDeclarations(baseName, decls) = + decls + |> List.collect (function | SynModuleSigDecl.ModuleAbbrev(id, lid, m) -> - [ createDecl(baseName, id, ModuleDecl, FSharpGlyph.Module, m, rangeOfLid lid, [], FSharpEnclosingEntityKind.Module, false, None) ] + [ createDecl(baseName, id, NavigationItemKind.Module, FSharpGlyph.Module, m, rangeOfLid lid, [], NavigationEntityKind.Module, false, None) ] - | SynModuleSigDecl.NestedModule(ComponentInfo(_, _, _, lid, _, _, access, _), _, decls, m) -> + | SynModuleSigDecl.NestedModule(SynComponentInfo(_, _, _, lid, _, _, access, _), _, decls, m) -> // Find let bindings (for the right dropdown) let nested = processNestedSigDeclarations(decls) - let newBaseName = (if (baseName = "") then "" else baseName+".") + (textOfLid lid) + let newBaseName = (if baseName = "" then "" else baseName + ".") + (textOfLid lid) // Get nested modules and types (for the left dropdown) - let other = processFSharpNavigationTopLevelSigDeclarations(newBaseName, decls) - createDeclLid(baseName, lid, ModuleDecl, FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid lid) other), nested, FSharpEnclosingEntityKind.Module, false, access) :: other + let other = processNavigationTopLevelSigDeclarations(newBaseName, decls) + createDeclLid(baseName, lid, NavigationItemKind.Module, FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid lid) other), nested, NavigationEntityKind.Module, false, access) :: other | SynModuleSigDecl.Types(tydefs, _) -> tydefs |> List.collect (processTycon baseName) | SynModuleSigDecl.Exception (defn,_) -> processExnSig baseName defn @@ -418,15 +434,15 @@ module NavigationImpl = // Find let bindings (for the right dropdown) let nested = processNestedSigDeclarations(decls) // Get nested modules and types (for the left dropdown) - let other = processFSharpNavigationTopLevelSigDeclarations(baseName, decls) + let other = processNavigationTopLevelSigDeclarations(baseName, decls) // Create explicitly - it can be 'single top level' thing that is hidden let decl = - FSharpNavigationDeclarationItem.Create - (textOfLid id, (if kind.IsModule then ModuleFileDecl else NamespaceDecl), + NavigationItem.Create + (textOfLid id, (if kind.IsModule then NavigationItemKind.ModuleFile else NavigationItemKind.Namespace), FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid id) other), - singleTopLevel, FSharpEnclosingEntityKind.Module, false, access), (addItemName(textOfLid id)), nested + singleTopLevel, NavigationEntityKind.Module, false, access), (addItemName(textOfLid id)), nested decl :: other) let items = @@ -439,56 +455,54 @@ module NavigationImpl = { Declaration = d.WithUniqueName(uniqueName d.Name idx); Nested = nest } ) items |> Array.sortInPlaceWith (fun a b -> compare a.Declaration.Name b.Declaration.Name) - new FSharpNavigationItems(items) + NavigationItems(items) [] -module FSharpNavigation = +module Navigation = let getNavigation (parsedInput: ParsedInput) = match parsedInput with | ParsedInput.SigFile (ParsedSigFileInput (modules = modules)) -> NavigationImpl.getNavigationFromSigFile modules | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules)) -> NavigationImpl.getNavigationFromImplFile modules - let empty = FSharpNavigationItems([||]) + let empty = NavigationItems([||]) [] -module NavigateTo = - open System - - [] - type NavigableItemKind = - | Module - | ModuleAbbreviation - | Exception - | Type - | ModuleValue - | Field - | Property - | Constructor - | Member - | EnumCase - | UnionCase - override x.ToString() = sprintf "%+A" x +type NavigableItemKind = + | Module + | ModuleAbbreviation + | Exception + | Type + | ModuleValue + | Field + | Property + | Constructor + | Member + | EnumCase + | UnionCase + override x.ToString() = sprintf "%+A" x - [] - type ContainerType = - | File - | Namespace - | Module - | Type - | Exception - - type Container = - { Type: ContainerType - Name: string } - - type NavigableItem = - { Name: string - Range: range - IsSignature: bool - Kind: NavigableItemKind - Container: Container } +[] +type NavigableContainerType = + | File + | Namespace + | Module + | Type + | Exception + +type NavigableContainer = + { Type: NavigableContainerType + Name: string } + +type NavigableItem = + { Name: string + Range: range + IsSignature: bool + Kind: NavigableItemKind + Container: NavigableContainer } - let getNavigableItems (parsedInput: ParsedInput) : NavigableItem [] = +[] +module NavigateTo = + let GetNavigableItems (parsedInput: ParsedInput) : NavigableItem [] = let rec lastInLid (lid: LongIdent) = match lid with | [x] -> Some x @@ -498,7 +512,7 @@ module NavigateTo = let formatLongIdent (lid: LongIdent) = lid |> List.map (fun id -> id.idText) |> String.concat "." let result = ResizeArray() - let addIdent kind (id: Ident) (isSignature: bool) (container: Container) = + let addIdent kind (id: Ident) (isSignature: bool) (container: NavigableContainer) = if not (String.IsNullOrEmpty id.idText) then let item = { Name = id.idText @@ -516,40 +530,40 @@ module NavigateTo = let addModuleAbbreviation (id: Ident) isSig container = addIdent NavigableItemKind.ModuleAbbreviation id isSig container - let addExceptionRepr (SynExceptionDefnRepr(_, UnionCase(_, id, _, _, _, _), _, _, _, _)) isSig container = + let addExceptionRepr (SynExceptionDefnRepr(_, SynUnionCase(_, id, _, _, _, _), _, _, _, _)) isSig container = addIdent NavigableItemKind.Exception id isSig container - { Type = ContainerType.Exception; Name = id.idText } + { Type = NavigableContainerType.Exception; Name = id.idText } - let addComponentInfo containerType kind (ComponentInfo(_, _, _, lid, _, _, _, _)) isSig container = + let addComponentInfo containerType kind (SynComponentInfo(_, _, _, lid, _, _, _, _)) isSig container = match lastInLid lid with | Some id -> addIdent kind id isSig container | _ -> () { Type = containerType; Name = formatLongIdent lid } - let addValSig kind (ValSpfn(_, id, _, _, _, _, _, _, _, _, _)) isSig container = + let addValSig kind (SynValSig(_, id, _, _, _, _, _, _, _, _, _)) isSig container = addIdent kind id isSig container - let addField(SynField.Field(_, _, id, _, _, _, _, _)) isSig container = + let addField(SynField(_, _, id, _, _, _, _, _)) isSig container = match id with | Some id -> addIdent NavigableItemKind.Field id isSig container | _ -> () - let addEnumCase(EnumCase(_, id, _, _, _)) isSig = + let addEnumCase(SynEnumCase(_, id, _, _, _, _)) isSig = addIdent NavigableItemKind.EnumCase id isSig - let addUnionCase(UnionCase(_, id, _, _, _, _)) isSig container = + let addUnionCase(SynUnionCase(_, id, _, _, _, _)) isSig container = addIdent NavigableItemKind.UnionCase id isSig container let mapMemberKind mk = match mk with - | MemberKind.ClassConstructor // ? - | MemberKind.Constructor -> NavigableItemKind.Constructor - | MemberKind.PropertyGet - | MemberKind.PropertySet - | MemberKind.PropertyGetSet -> NavigableItemKind.Property - | MemberKind.Member -> NavigableItemKind.Member + | SynMemberKind.ClassConstructor // ? + | SynMemberKind.Constructor -> NavigableItemKind.Constructor + | SynMemberKind.PropertyGet + | SynMemberKind.PropertySet + | SynMemberKind.PropertyGetSet -> NavigableItemKind.Property + | SynMemberKind.Member -> NavigableItemKind.Member - let addBinding (Binding(_, _, _, _, _, _, valData, headPat, _, _, _, _)) itemKind container = + let addBinding (SynBinding(_, _, _, _, _, _, valData, headPat, _, _, _, _)) itemKind container = let (SynValData(memberFlagsOpt, _, _)) = valData let kind = match itemKind with @@ -566,25 +580,25 @@ module NavigateTo = | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) -> // functions addIdent kind id false container - | SynPat.Named(_, id, _, _, _) -> + | SynPat.Named (id, _, _, _) | SynPat.As(_, SynPat.Named (id, _, _, _), _) -> // values addIdent kind id false container | _ -> () - let addMember valSig (memberFlags: MemberFlags) isSig container = + let addMember valSig (memberFlags: SynMemberFlags) isSig container = let ctor = mapMemberKind memberFlags.MemberKind addValSig ctor valSig isSig container let rec walkSigFileInput (ParsedSigFileInput (fileName, _, _, _, moduleOrNamespaceList)) = for item in moduleOrNamespaceList do - walkSynModuleOrNamespaceSig item { Type = ContainerType.File; Name = fileName } + walkSynModuleOrNamespaceSig item { Type = NavigableContainerType.File; Name = fileName } and walkSynModuleOrNamespaceSig (SynModuleOrNamespaceSig(lid, _, kind, decls, _, _, _, _)) container = let isModule = kind.IsModule if isModule then addModule lid true container let container = - { Type = if isModule then ContainerType.Module else ContainerType.Namespace + { Type = if isModule then NavigableContainerType.Module else NavigableContainerType.Namespace Name = formatLongIdent lid } for decl in decls do walkSynModuleSigDecl decl container @@ -598,7 +612,7 @@ module NavigateTo = | SynModuleSigDecl.NamespaceFragment fragment -> walkSynModuleOrNamespaceSig fragment container | SynModuleSigDecl.NestedModule(componentInfo, _, nestedDecls, _) -> - let container = addComponentInfo ContainerType.Module NavigableItemKind.Module componentInfo true container + let container = addComponentInfo NavigableContainerType.Module NavigableItemKind.Module componentInfo true container for decl in nestedDecls do walkSynModuleSigDecl decl container | SynModuleSigDecl.Types(types, _) -> @@ -609,8 +623,8 @@ module NavigateTo = | SynModuleSigDecl.HashDirective _ | SynModuleSigDecl.Open _ -> () - and walkSynTypeDefnSig (TypeDefnSig(componentInfo, repr, members, _)) container = - let container = addComponentInfo ContainerType.Type NavigableItemKind.Type componentInfo true container + and walkSynTypeDefnSig (SynTypeDefnSig(componentInfo, repr, members, _)) container = + let container = addComponentInfo NavigableContainerType.Type NavigableItemKind.Type componentInfo true container for m in members do walkSynMemberSig m container match repr with @@ -633,7 +647,7 @@ module NavigateTo = | SynMemberSig.Interface _ -> () and walkImplFileInput (ParsedImplFileInput (fileName = fileName; modules = moduleOrNamespaceList)) = - let container = { Type = ContainerType.File; Name = fileName } + let container = { Type = NavigableContainerType.File; Name = fileName } for item in moduleOrNamespaceList do walkSynModuleOrNamespace item container @@ -642,7 +656,7 @@ module NavigateTo = if isModule then addModule lid false container let container = - { Type = if isModule then ContainerType.Module else ContainerType.Namespace + { Type = if isModule then NavigableContainerType.Module else NavigableContainerType.Namespace Name = formatLongIdent lid } for decl in decls do walkSynModuleDecl decl container @@ -661,7 +675,7 @@ module NavigateTo = | SynModuleDecl.NamespaceFragment(fragment) -> walkSynModuleOrNamespace fragment container | SynModuleDecl.NestedModule(componentInfo, _, modules, _, _) -> - let container = addComponentInfo ContainerType.Module NavigableItemKind.Module componentInfo false container + let container = addComponentInfo NavigableContainerType.Module NavigableItemKind.Module componentInfo false container for m in modules do walkSynModuleDecl m container | SynModuleDecl.Types(typeDefs, _range) -> @@ -672,8 +686,8 @@ module NavigateTo = | SynModuleDecl.HashDirective _ | SynModuleDecl.Open _ -> () - and walkSynTypeDefn(TypeDefn(componentInfo, representation, members, _)) container = - let container = addComponentInfo ContainerType.Type NavigableItemKind.Type componentInfo false container + and walkSynTypeDefn(SynTypeDefn(componentInfo, representation, members, _, _)) container = + let container = addComponentInfo NavigableContainerType.Type NavigableItemKind.Type componentInfo false container walkSynTypeDefnRepr representation container for m in members do walkSynMemberDefn m container diff --git a/src/fsharp/service/ServiceNavigation.fsi b/src/fsharp/service/ServiceNavigation.fsi index b91389bbf2a..b89010c886b 100755 --- a/src/fsharp/service/ServiceNavigation.fsi +++ b/src/fsharp/service/ServiceNavigation.fsi @@ -5,24 +5,26 @@ // type checking and intellisense-like environment-reporting. //---------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text /// Indicates a kind of item to show in an F# navigation bar -type public FSharpNavigationDeclarationItemKind = - | NamespaceDecl - | ModuleFileDecl - | ExnDecl - | ModuleDecl - | TypeDecl - | MethodDecl - | PropertyDecl - | FieldDecl - | OtherDecl +[] +type public NavigationItemKind = + | Namespace + | ModuleFile + | Exception + | Module + | Type + | Method + | Property + | Field + | Other [] -type public FSharpEnclosingEntityKind = +type public NavigationEntityKind = | Namespace | Module | Class @@ -30,73 +32,82 @@ type public FSharpEnclosingEntityKind = | Interface | Record | Enum - | DU + | Union /// Represents an item to be displayed in the navigation bar [] -type public FSharpNavigationDeclarationItem = - member Name : string - member UniqueName : string - member Glyph : FSharpGlyph - member Kind : FSharpNavigationDeclarationItemKind - member Range : Range.range - member BodyRange : Range.range - member IsSingleTopLevel : bool - member EnclosingEntityKind: FSharpEnclosingEntityKind +type public NavigationItem = + member Name: string + + member UniqueName: string + + member Glyph: FSharpGlyph + + member Kind: NavigationItemKind + + member Range: range + + member BodyRange: range + + member IsSingleTopLevel: bool + + member EnclosingEntityKind: NavigationEntityKind + member IsAbstract: bool - member Access : Ast.SynAccess option + + member Access: SynAccess option /// Represents top-level declarations (that should be in the type drop-down) /// with nested declarations (that can be shown in the member drop-down) [] -type public FSharpNavigationTopLevelDeclaration = - { Declaration : FSharpNavigationDeclarationItem - Nested : FSharpNavigationDeclarationItem[] } +type public NavigationTopLevelDeclaration = + { Declaration: NavigationItem + Nested: NavigationItem[] } /// Represents result of 'GetNavigationItems' operation - this contains /// all the members and currently selected indices. First level correspond to /// types & modules and second level are methods etc. [] -type public FSharpNavigationItems = - member Declarations : FSharpNavigationTopLevelDeclaration[] +type public NavigationItems = + member Declarations: NavigationTopLevelDeclaration[] // Functionality to access navigable F# items. -module public FSharpNavigation = - val internal empty : FSharpNavigationItems - val getNavigation : Ast.ParsedInput -> FSharpNavigationItems +module public Navigation = + val internal empty: NavigationItems + val getNavigation: ParsedInput -> NavigationItems -module public NavigateTo = - [] - type NavigableItemKind = - | Module - | ModuleAbbreviation - | Exception - | Type - | ModuleValue - | Field - | Property - | Constructor - | Member - | EnumCase - | UnionCase - - [] - type ContainerType = - | File - | Namespace - | Module - | Type - | Exception - - type Container = - { Type: ContainerType - Name: string } +[] +type NavigableItemKind = + | Module + | ModuleAbbreviation + | Exception + | Type + | ModuleValue + | Field + | Property + | Constructor + | Member + | EnumCase + | UnionCase + +[] +type NavigableContainerType = + | File + | Namespace + | Module + | Type + | Exception + +type NavigableContainer = + { Type: NavigableContainerType + Name: string } - type NavigableItem = - { Name: string - Range: Range.range - IsSignature: bool - Kind: NavigableItemKind - Container: Container } - - val getNavigableItems : Ast.ParsedInput -> NavigableItem [] +type NavigableItem = + { Name: string + Range: range + IsSignature: bool + Kind: NavigableItemKind + Container: NavigableContainer } + +module public NavigateTo = + val GetNavigableItems: ParsedInput -> NavigableItem [] diff --git a/src/fsharp/service/ServiceParamInfoLocations.fs b/src/fsharp/service/ServiceParamInfoLocations.fs index 8ab5122f900..39182d983be 100755 --- a/src/fsharp/service/ServiceParamInfoLocations.fs +++ b/src/fsharp/service/ServiceParamInfoLocations.fs @@ -1,12 +1,15 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps [] -type FSharpNoteworthyParamInfoLocations(longId: string list, longIdRange: range, openParenLocation: pos, tupleEndLocations: pos list, isThereACloseParen: bool, namedParamNames: string option list) = +type ParameterLocations(longId: string list, longIdRange: range, openParenLocation: pos, tupleEndLocations: pos list, isThereACloseParen: bool, namedParamNames: string option list) = let tupleEndLocations = Array.ofList tupleEndLocations let namedParamNames = Array.ofList namedParamNames @@ -29,10 +32,10 @@ type FSharpNoteworthyParamInfoLocations(longId: string list, longIdRange: range, member this.NamedParamNames = namedParamNames [] -module internal NoteworthyParamInfoLocationsImpl = +module internal ParameterLocationsImpl = - let isStaticArg a = - match a with + let isStaticArg (StripParenTypes synType) = + match synType with | SynType.StaticConstant _ | SynType.StaticConstantExpr _ | SynType.StaticConstantNamed _ -> true | SynType.LongIdent _ -> true // NOTE: this is not a static constant, but it is a prefix of incomplete code, e.g. "TP<42, Arg3" is a prefix of "TP<42, Arg3=6>" and Arg3 shows up as a LongId | _ -> false @@ -41,17 +44,18 @@ module internal NoteworthyParamInfoLocationsImpl = let rec digOutIdentFromFuncExpr synExpr = // we found it, dig out ident match synExpr with - | SynExpr.Ident (id) -> Some ([id.idText], id.idRange) + | SynExpr.Ident id -> Some ([id.idText], id.idRange) | SynExpr.LongIdent (_, LongIdentWithDots(lid, _), _, lidRange) | SynExpr.DotGet (_, _, LongIdentWithDots(lid, _), lidRange) -> Some (pathOfLid lid, lidRange) | SynExpr.TypeApp (synExpr, _, _synTypeList, _commas, _, _, _range) -> digOutIdentFromFuncExpr synExpr + | SynExpr.Paren(expr = expr) -> digOutIdentFromFuncExpr expr | _ -> None type FindResult = | Found of openParen: pos * commasAndCloseParen: (pos * string option) list * hasClosedParen: bool | NotFound - let digOutIdentFromStaticArg synType = + let digOutIdentFromStaticArg (StripParenTypes synType) = match synType with | SynType.StaticConstantNamed(SynType.LongIdent(LongIdentWithDots([id], _)), _, _) -> Some id.idText | SynType.LongIdent(LongIdentWithDots([id], _)) -> Some id.idText // NOTE: again, not a static constant, but may be a prefix of a Named in incomplete code @@ -74,7 +78,7 @@ module internal NoteworthyParamInfoLocationsImpl = _, _) when op.idText="op_Equality" -> Some n.idText | _ -> None - let getTypeName(synType) = + let getTypeName synType = match synType with | SynType.LongIdent(LongIdentWithDots(ids, _)) -> ids |> pathOfLid | _ -> [""] // TODO type name for other cases, see also unit test named "ParameterInfo.LocationOfParams.AfterQuicklyTyping.CallConstructorViaLongId.Bug94333" @@ -83,7 +87,7 @@ module internal NoteworthyParamInfoLocationsImpl = let inner = traverseSynExpr synExpr match inner with | None -> - if AstTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then + if SyntaxTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then Found (parenRange.Start, [(parenRange.End, getNamedParamName synExpr)], rpRangeOpt.IsSome), None else NotFound, None @@ -96,11 +100,11 @@ module internal NoteworthyParamInfoLocationsImpl = // see bug 345385. let rec searchSynArgExpr traverseSynExpr pos expr = match expr with - | SynExprParen((SynExpr.Tuple (false, synExprList, commaRanges, _tupleRange) as synExpr), _lpRange, rpRangeOpt, parenRange) -> // tuple argument + | SynExprParen(SynExpr.Tuple (false, synExprList, commaRanges, _tupleRange) as synExpr, _lpRange, rpRangeOpt, parenRange) -> // tuple argument let inner = traverseSynExpr synExpr match inner with | None -> - if AstTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then + if SyntaxTraversal.rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive parenRange pos then let commasAndCloseParen = ((synExprList, commaRanges@[parenRange]) ||> List.map2 (fun e c -> c.End, getNamedParamName e)) let r = Found (parenRange.Start, commasAndCloseParen, rpRangeOpt.IsSome) r, None @@ -120,14 +124,14 @@ module internal NoteworthyParamInfoLocationsImpl = handleSingleArg traverseSynExpr (pos, synExpr, parenRange, rpRangeOpt) | SynExpr.ArbitraryAfterError (_debugStr, range) -> // single argument when e.g. after open paren you hit EOF - if AstTraversal.rangeContainsPosEdgesExclusive range pos then + if SyntaxTraversal.rangeContainsPosEdgesExclusive range pos then let r = Found (range.Start, [(range.End, None)], false) r, None else NotFound, None | SynExpr.Const (SynConst.Unit, unitRange) -> - if AstTraversal.rangeContainsPosEdgesExclusive unitRange pos then + if SyntaxTraversal.rangeContainsPosEdgesExclusive unitRange pos then let r = Found (unitRange.Start, [(unitRange.End, None)], true) r, None else @@ -137,28 +141,28 @@ module internal NoteworthyParamInfoLocationsImpl = let inner = traverseSynExpr e match inner with | None -> - if AstTraversal.rangeContainsPosEdgesExclusive e.Range pos then + if SyntaxTraversal.rangeContainsPosEdgesExclusive e.Range pos then // any other expression doesn't start with parens, so if it was the target of an App, then it must be a single argument e.g. "f x" Found (e.Range.Start, [ (e.Range.End, None) ], false), Some inner else NotFound, Some inner | _ -> NotFound, Some inner - let (|StaticParameters|_|) pos synType = + let (|StaticParameters|_|) pos (StripParenTypes synType) = match synType with - | SynType.App(SynType.LongIdent(LongIdentWithDots(lid, _) as lidwd), Some(openm), args, commas, closemOpt, _pf, wholem) -> + | SynType.App(StripParenTypes (SynType.LongIdent(LongIdentWithDots(lid, _) as lidwd)), Some(openm), args, commas, closemOpt, _pf, wholem) -> let lidm = lidwd.Range let betweenTheBrackets = mkRange wholem.FileName openm.Start wholem.End - if AstTraversal.rangeContainsPosEdgesExclusive betweenTheBrackets pos && args |> List.forall isStaticArg then + if SyntaxTraversal.rangeContainsPosEdgesExclusive betweenTheBrackets pos && args |> List.forall isStaticArg then let commasAndCloseParen = [ for c in commas -> c.End ] @ [ wholem.End ] - Some (FSharpNoteworthyParamInfoLocations(pathOfLid lid, lidm, openm.Start, commasAndCloseParen, closemOpt.IsSome, args |> List.map digOutIdentFromStaticArg)) + Some (ParameterLocations(pathOfLid lid, lidm, openm.Start, commasAndCloseParen, closemOpt.IsSome, args |> List.map digOutIdentFromStaticArg)) else None | _ -> None let traverseInput(pos, parseTree) = - AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with + SyntaxTraversal.Traverse(pos, parseTree, { new SyntaxVisitorBase<_>() with member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = let expr = expr // fix debug locals match expr with @@ -169,7 +173,7 @@ module internal NoteworthyParamInfoLocationsImpl = match constrArgsResult, cacheOpt with | Found(parenLoc, args, isThereACloseParen), _ -> let typeName = getTypeName synType - Some (FSharpNoteworthyParamInfoLocations(typeName, synType.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)) + Some (ParameterLocations(typeName, synType.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)) | NotFound, Some cache -> cache | _ -> @@ -185,10 +189,10 @@ module internal NoteworthyParamInfoLocationsImpl = | Some _ -> fResult | _ -> let typeArgsm = mkRange openm.FileName openm.Start wholem.End - if AstTraversal.rangeContainsPosEdgesExclusive typeArgsm pos then + if SyntaxTraversal.rangeContainsPosEdgesExclusive typeArgsm pos then // We found it, dig out ident match digOutIdentFromFuncExpr synExpr with - | Some(lid, lidRange) -> Some (FSharpNoteworthyParamInfoLocations(lid, lidRange, op.idRange.Start, [ wholem.End ], false, [])) + | Some(lid, lidRange) -> Some (ParameterLocations(lid, lidRange, op.idRange.Start, [ wholem.End ], false, [])) | None -> None else None @@ -213,7 +217,7 @@ module internal NoteworthyParamInfoLocationsImpl = // For now, we don't support infix operators. None else - Some (FSharpNoteworthyParamInfoLocations(lid, lidRange, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)) + Some (ParameterLocations(lid, lidRange, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)) | None -> None | NotFound, Some cache -> cache | _ -> traverseSynExpr synExpr2 @@ -224,39 +228,39 @@ module internal NoteworthyParamInfoLocationsImpl = | Some _ as r -> r | None -> let typeArgsm = mkRange openm.FileName openm.Start wholem.End - if AstTraversal.rangeContainsPosEdgesExclusive typeArgsm pos && tyArgs |> List.forall isStaticArg then + if SyntaxTraversal.rangeContainsPosEdgesExclusive typeArgsm pos && tyArgs |> List.forall isStaticArg then let commasAndCloseParen = [ for c in commas -> c.End ] @ [ wholem.End ] - let r = FSharpNoteworthyParamInfoLocations(["dummy"], synExpr.Range, openm.Start, commasAndCloseParen, closemOpt.IsSome, tyArgs |> List.map digOutIdentFromStaticArg) + let r = ParameterLocations(["dummy"], synExpr.Range, openm.Start, commasAndCloseParen, closemOpt.IsSome, tyArgs |> List.map digOutIdentFromStaticArg) Some r else None | _ -> defaultTraverse expr - member this.VisitTypeAbbrev(tyAbbrevRhs, _m) = + member this.VisitTypeAbbrev(_path, tyAbbrevRhs, _m) = match tyAbbrevRhs with | StaticParameters pos loc -> Some loc | _ -> None - member this.VisitImplicitInherit(defaultTraverse, ty, expr, m) = + member this.VisitImplicitInherit(_path, defaultTraverse, ty, expr, m) = match defaultTraverse expr with | Some _ as r -> r | None -> let inheritm = mkRange m.FileName m.Start m.End - if AstTraversal.rangeContainsPosEdgesExclusive inheritm pos then + if SyntaxTraversal.rangeContainsPosEdgesExclusive inheritm pos then // inherit ty(expr) --- treat it like an application (constructor call) let xResult, _cacheOpt = searchSynArgExpr defaultTraverse pos expr match xResult with | Found(parenLoc, args, isThereACloseParen) -> // we found it, dig out ident let typeName = getTypeName ty - let r = FSharpNoteworthyParamInfoLocations(typeName, ty.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd) + let r = ParameterLocations(typeName, ty.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd) Some r | NotFound -> None else None }) -type FSharpNoteworthyParamInfoLocations with +type ParameterLocations with static member Find(pos, parseTree) = match traverseInput(pos, parseTree) with | Some nwpl as r -> @@ -270,3 +274,59 @@ type FSharpNoteworthyParamInfoLocations with r | _ -> None + +module internal SynExprAppLocationsImpl = + let rec private searchSynArgExpr traverseSynExpr expr ranges = + match expr with + | SynExpr.Const(SynConst.Unit, _) -> + None, None + + | SynExpr.Paren(SynExpr.Tuple (_, exprs, _commas, _tupRange), _, _, _parenRange) -> + let rec loop (exprs: SynExpr list) ranges = + match exprs with + | [] -> ranges + | h::t -> + loop t (h.Range :: ranges) + + let res = loop exprs ranges + Some res, None + + | SynExpr.Paren(SynExpr.Paren _ as synExpr, _, _, _parenRange) -> + let r, _cacheOpt = searchSynArgExpr traverseSynExpr synExpr ranges + r, None + + | SynExpr.Paren(SynExpr.App (_, _isInfix, _, _, _range), _, _, parenRange) -> + Some (parenRange :: ranges), None + + | e -> + let inner = traverseSynExpr e + match inner with + | None -> + Some (e.Range :: ranges), Some inner + | _ -> None, Some inner + + let getAllCurriedArgsAtPosition pos parseTree = + SyntaxTraversal.Traverse(pos, parseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.App (_exprAtomicFlag, _isInfix, funcExpr, argExpr, range) when posEq pos range.Start -> + let isInfixFuncExpr = + match funcExpr with + | SynExpr.App (_, isInfix, _, _, _) -> isInfix + | _ -> false + + if isInfixFuncExpr then + traverseSynExpr funcExpr + else + let workingRanges = + match traverseSynExpr funcExpr with + | Some ranges -> ranges + | None -> [] + + let xResult, cacheOpt = searchSynArgExpr traverseSynExpr argExpr workingRanges + match xResult, cacheOpt with + | Some ranges, _ -> Some ranges + | None, Some cache -> cache + | _ -> traverseSynExpr argExpr + | _ -> defaultTraverse expr }) + |> Option.map List.rev diff --git a/src/fsharp/service/ServiceParamInfoLocations.fsi b/src/fsharp/service/ServiceParamInfoLocations.fsi index 6961c892b09..77fa2b46326 100755 --- a/src/fsharp/service/ServiceParamInfoLocations.fsi +++ b/src/fsharp/service/ServiceParamInfoLocations.fsi @@ -5,14 +5,14 @@ // type checking and intellisense-like environment-reporting. //---------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler -open FSharp.Compiler.Range +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text /// Represents the locations relevant to activating parameter info in an IDE [] -type public FSharpNoteworthyParamInfoLocations = +type public ParameterLocations = /// The text of the long identifier prior to the open-parentheses member LongId : string list @@ -36,5 +36,7 @@ type public FSharpNoteworthyParamInfoLocations = member NamedParamNames : string option [] /// Find the information about parameter info locations at a particular source location - static member Find : pos * Ast.ParsedInput -> FSharpNoteworthyParamInfoLocations option + static member Find : pos * ParsedInput -> ParameterLocations option +module internal SynExprAppLocationsImpl = + val getAllCurriedArgsAtPosition: pos: pos -> parseTree: ParsedInput -> range list option diff --git a/src/fsharp/service/ServiceParseTreeWalk.fs b/src/fsharp/service/ServiceParseTreeWalk.fs index eeab436524f..715695347b4 100755 --- a/src/fsharp/service/ServiceParseTreeWalk.fs +++ b/src/fsharp/service/ServiceParseTreeWalk.fs @@ -5,14 +5,129 @@ // type checking and intellisense-like environment-reporting. //-------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices - -open FSharp.Compiler.Range -open FSharp.Compiler.Ast - +namespace FSharp.Compiler.Syntax + +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range + +/// used to track route during traversal AST +[] +type SyntaxNode = + | SynPat of SynPat + | SynType of SynType + | SynExpr of SynExpr + | SynModule of SynModuleDecl + | SynModuleOrNamespace of SynModuleOrNamespace + | SynTypeDefn of SynTypeDefn + | SynMemberDefn of SynMemberDefn + | SynMatchClause of SynMatchClause + | SynBinding of SynBinding + +type SyntaxVisitorPath = SyntaxNode list + +[] +type SyntaxVisitorBase<'T>() = + abstract VisitExpr: path: SyntaxVisitorPath * traverseSynExpr: (SynExpr -> 'T option) * defaultTraverse: (SynExpr -> 'T option) * synExpr: SynExpr -> 'T option + default _.VisitExpr(path: SyntaxVisitorPath, traverseSynExpr: SynExpr -> 'T option, defaultTraverse: SynExpr -> 'T option, synExpr: SynExpr) = + ignore (path, traverseSynExpr, defaultTraverse, synExpr) + None + + /// VisitTypeAbbrev(ty,m), defaults to ignoring this leaf of the AST + abstract VisitTypeAbbrev: path: SyntaxVisitorPath * synType: SynType * range: range -> 'T option + default _.VisitTypeAbbrev(path, synType, range) = + ignore (path, synType, range) + None + + /// VisitImplicitInherit(defaultTraverse,ty,expr,m), defaults to just visiting expr + abstract VisitImplicitInherit: path: SyntaxVisitorPath * defaultTraverse: (SynExpr -> 'T option) * inheritedType: SynType * synArgs: SynExpr * range: range -> 'T option + default _.VisitImplicitInherit(path, defaultTraverse, inheritedType, synArgs, range) = + ignore (path, inheritedType, range) + defaultTraverse synArgs + + /// VisitModuleDecl allows overriding module declaration behavior + abstract VisitModuleDecl: path: SyntaxVisitorPath * defaultTraverse: (SynModuleDecl -> 'T option) * synModuleDecl: SynModuleDecl -> 'T option + default _.VisitModuleDecl(path, defaultTraverse, synModuleDecl) = + ignore path + defaultTraverse synModuleDecl + + /// VisitBinding allows overriding binding behavior (note: by default it would defaultTraverse expression) + abstract VisitBinding: path: SyntaxVisitorPath * defaultTraverse: (SynBinding -> 'T option) * synBinding: SynBinding -> 'T option + default _.VisitBinding(path, defaultTraverse, synBinding) = + ignore path + defaultTraverse synBinding + + /// VisitMatchClause allows overriding clause behavior (note: by default it would defaultTraverse expression) + abstract VisitMatchClause: path: SyntaxVisitorPath * defaultTraverse: (SynMatchClause -> 'T option) * matchClause: SynMatchClause -> 'T option + default _.VisitMatchClause(path, defaultTraverse, matchClause) = + ignore path + defaultTraverse matchClause + + /// VisitInheritSynMemberDefn allows overriding inherit behavior (by default do nothing) + abstract VisitInheritSynMemberDefn: path: SyntaxVisitorPath * componentInfo: SynComponentInfo * typeDefnKind: SynTypeDefnKind * SynType * SynMemberDefns * range -> 'T option + default _.VisitInheritSynMemberDefn(path, componentInfo, typeDefnKind, synType, members, range) = + ignore (path, componentInfo, typeDefnKind, synType, members, range) + None + + /// VisitInterfaceSynMemberDefnType allows overriding behavior for visiting interface member in types (by default - do nothing) + abstract VisitInterfaceSynMemberDefnType: path: SyntaxVisitorPath * synType: SynType -> 'T option + default _.VisitInterfaceSynMemberDefnType(path, synType) = + ignore (path, synType) + None + + /// VisitRecordField allows overriding behavior when visiting l.h.s. of constructed record instances + abstract VisitRecordField: path: SyntaxVisitorPath * copyOpt: SynExpr option * recordField: LongIdentWithDots option -> 'T option + default _.VisitRecordField (path, copyOpt, recordField) = + ignore (path, copyOpt, recordField) + None + + /// VisitHashDirective allows overriding behavior when visiting hash directives in FSX scripts, like #r, #load and #I. + abstract VisitHashDirective: path: SyntaxVisitorPath * hashDirective: ParsedHashDirective * range: range -> 'T option + default _.VisitHashDirective (path, hashDirective, range) = + ignore (path, hashDirective, range) + None + + /// VisitModuleOrNamespace allows overriding behavior when visiting module or namespaces + abstract VisitModuleOrNamespace: path: SyntaxVisitorPath * synModuleOrNamespace: SynModuleOrNamespace -> 'T option + default _.VisitModuleOrNamespace (path, synModuleOrNamespace) = + ignore (path, synModuleOrNamespace) + None + + /// VisitComponentInfo allows overriding behavior when visiting type component infos + abstract VisitComponentInfo: path: SyntaxVisitorPath * synComponentInfo: SynComponentInfo -> 'T option + default _.VisitComponentInfo (path, synComponentInfo) = + ignore (path, synComponentInfo) + None + + /// VisitLetOrUse allows overriding behavior when visiting module or local let or use bindings + abstract VisitLetOrUse: path: SyntaxVisitorPath * isRecursive: bool * defaultTraverse: (SynBinding -> 'T option) * bindings: SynBinding list * range: range -> 'T option + default _.VisitLetOrUse (path, isRecursive, defaultTraverse, bindings, range) = + ignore (path, isRecursive, defaultTraverse, bindings, range) + None + + /// VisitType allows overriding behavior when visiting simple pats + abstract VisitSimplePats: path: SyntaxVisitorPath * synPats: SynSimplePat list -> 'T option + default _.VisitSimplePats (path, synPats) = + ignore (path, synPats) + None + + /// VisitPat allows overriding behavior when visiting patterns + abstract VisitPat: path: SyntaxVisitorPath * defaultTraverse: (SynPat -> 'T option) * synPat: SynPat -> 'T option + default _.VisitPat (path, defaultTraverse, synPat) = + ignore path + defaultTraverse synPat + + /// VisitType allows overriding behavior when visiting type hints (x: ..., etc.) + abstract VisitType: path: SyntaxVisitorPath * defaultTraverse: (SynType -> 'T option) * synType: SynType -> 'T option + default _.VisitType (path, defaultTraverse, synType) = + ignore path + defaultTraverse synType /// A range of utility functions to assist with traversing an AST -module public AstTraversal = +module SyntaxTraversal = + // treat ranges as though they are half-open: [,) let rangeContainsPosLeftEdgeInclusive (m1:range) p = if posEq m1.Start m1.End then @@ -29,93 +144,10 @@ module public AstTraversal = let rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive (m1:range) p = posGt p m1.Start && posGeq m1.End p - /// used to track route during traversal AST - [] - type TraverseStep = - | Expr of SynExpr - | Module of SynModuleDecl - | ModuleOrNamespace of SynModuleOrNamespace - | TypeDefn of SynTypeDefn - | MemberDefn of SynMemberDefn - | MatchClause of SynMatchClause - | Binding of SynBinding - - type TraversePath = TraverseStep list - - [] - type AstVisitorBase<'T>() = - /// VisitExpr(path, traverseSynExpr, defaultTraverse, expr) - /// controls the behavior when a SynExpr is reached; it can just do - /// defaultTraverse(expr) if you have no special logic for this node, and want the default processing to pick which sub-node to dive deeper into - /// or can inject non-default behavior, which might incorporate: - /// traverseSynExpr(subExpr) to recurse deeper on some particular sub-expression based on your own logic - /// path helps to track AST nodes that were passed during traversal - abstract VisitExpr : TraversePath * (SynExpr -> 'T option) * (SynExpr -> 'T option) * SynExpr -> 'T option - - /// VisitTypeAbbrev(ty,m), defaults to ignoring this leaf of the AST - abstract VisitTypeAbbrev : SynType * range -> 'T option - default this.VisitTypeAbbrev(_ty,_m) = None - - /// VisitImplicitInherit(defaultTraverse,ty,expr,m), defaults to just visiting expr - abstract VisitImplicitInherit : (SynExpr -> 'T option) * SynType * SynExpr * range -> 'T option - default this.VisitImplicitInherit(defaultTraverse, _ty, expr, _m) = defaultTraverse expr - - /// VisitModuleDecl allows overriding module declaration behavior - abstract VisitModuleDecl : (SynModuleDecl -> 'T option) * SynModuleDecl -> 'T option - default this.VisitModuleDecl(defaultTraverse, decl) = defaultTraverse decl - - /// VisitBinding allows overriding binding behavior (note: by default it would defaultTraverse expression) - abstract VisitBinding : (SynBinding -> 'T option) * SynBinding -> 'T option - default this.VisitBinding(defaultTraverse, binding) = defaultTraverse binding - - /// VisitMatchClause allows overriding clause behavior (note: by default it would defaultTraverse expression) - abstract VisitMatchClause : (SynMatchClause -> 'T option) * SynMatchClause -> 'T option - default this.VisitMatchClause(defaultTraverse, mc) = defaultTraverse mc - - /// VisitInheritSynMemberDefn allows overriding inherit behavior (by default do nothing) - abstract VisitInheritSynMemberDefn : SynComponentInfo * SynTypeDefnKind * SynType * SynMemberDefns * range -> 'T option - default this.VisitInheritSynMemberDefn(_componentInfo, _typeDefnKind, _synType, _members, _range) = None - - /// VisitInterfaceSynMemberDefnType allows overriding behavior for visiting interface member in types (by default - do nothing) - abstract VisitInterfaceSynMemberDefnType : SynType -> 'T option - default this.VisitInterfaceSynMemberDefnType(_synType) = None - - /// VisitRecordField allows overriding behavior when visiting l.h.s. of constructed record instances - abstract VisitRecordField : TraversePath * SynExpr option * LongIdentWithDots option -> 'T option - default this.VisitRecordField (_path, _copyOpt, _recordField) = None - - /// VisitHashDirective allows overriding behavior when visiting hash directives in FSX scripts, like #r, #load and #I. - abstract VisitHashDirective : range -> 'T option - default this.VisitHashDirective (_) = None - - /// VisitModuleOrNamespace allows overriding behavior when visiting module or namespaces - abstract VisitModuleOrNamespace : SynModuleOrNamespace -> 'T option - default this.VisitModuleOrNamespace (_) = None - - /// VisitComponentInfo allows overriding behavior when visiting type component infos - abstract VisitComponentInfo : SynComponentInfo -> 'T option - default this.VisitComponentInfo (_) = None - - /// VisitLetOrUse allows overriding behavior when visiting module or local let or use bindings - abstract VisitLetOrUse : TraversePath * (SynBinding -> 'T option) * SynBinding list * range -> 'T option - default this.VisitLetOrUse (_, _, _, _) = None - - /// VisitType allows overriding behavior when visiting simple pats - abstract VisitSimplePats : SynSimplePat list -> 'T option - default this.VisitSimplePats (_) = None - - /// VisitPat allows overriding behavior when visiting patterns - abstract VisitPat : (SynPat -> 'T option) * SynPat -> 'T option - default this.VisitPat (defaultTraverse, pat) = defaultTraverse pat - - /// VisitType allows overriding behavior when visiting type hints (x: ..., etc.) - abstract VisitType : (SynType -> 'T option) * SynType -> 'T option - default this.VisitType (defaultTraverse, ty) = defaultTraverse ty - let dive node range project = range,(fun() -> project node) - let pick pos (outerRange:range) (_debugObj:obj) (diveResults:list) = + let pick pos (outerRange:range) (debugObj:obj) (diveResults:list) = match diveResults with | [] -> None | _ -> @@ -157,59 +189,76 @@ module public AstTraversal = | [x] -> x() | _ -> #if DEBUG - assert(false) - failwithf "multiple disjoint AST node ranges claimed to contain (%A) from %+A" pos _debugObj + assert false + failwithf "multiple disjoint AST node ranges claimed to contain (%A) from %+A" pos debugObj #else + ignore debugObj None #endif /// traverse an implementation file walking all the way down to SynExpr or TypeAbbrev at a particular location /// - let Traverse(pos:pos, parseTree, visitor:AstVisitorBase<'T>) = + let Traverse(pos:pos, parseTree, visitor:SyntaxVisitorBase<'T>) = let pick x = pick pos x - let rec traverseSynModuleDecl path (decl:SynModuleDecl) = + let rec traverseSynModuleDecl origPath (decl:SynModuleDecl) = let pick = pick decl.Range let defaultTraverse m = - let path = TraverseStep.Module m :: path + let path = SyntaxNode.SynModule m :: origPath match m with | SynModuleDecl.ModuleAbbrev(_ident, _longIdent, _range) -> None | SynModuleDecl.NestedModule(_synComponentInfo, _isRec, synModuleDecls, _, _range) -> synModuleDecls |> List.map (fun x -> dive x x.Range (traverseSynModuleDecl path)) |> pick decl - | SynModuleDecl.Let(_, synBindingList, range) -> - match visitor.VisitLetOrUse(path, traverseSynBinding path, synBindingList, range) with + | SynModuleDecl.Let(isRecursive, synBindingList, range) -> + match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with | Some x -> Some x - | None -> synBindingList |> List.map (fun x -> dive x x.RangeOfBindingAndRhs (traverseSynBinding path)) |> pick decl + | None -> synBindingList |> List.map (fun x -> dive x x.RangeOfBindingWithRhs (traverseSynBinding path)) |> pick decl | SynModuleDecl.DoExpr(_sequencePointInfoForBinding, synExpr, _range) -> traverseSynExpr path synExpr | SynModuleDecl.Types(synTypeDefnList, _range) -> synTypeDefnList |> List.map (fun x -> dive x x.Range (traverseSynTypeDefn path)) |> pick decl | SynModuleDecl.Exception(_synExceptionDefn, _range) -> None - | SynModuleDecl.Open(_longIdent, _range) -> None + | SynModuleDecl.Open(_target, _range) -> None | SynModuleDecl.Attributes(_synAttributes, _range) -> None - | SynModuleDecl.HashDirective(_parsedHashDirective, range) -> visitor.VisitHashDirective range + | SynModuleDecl.HashDirective(parsedHashDirective, range) -> visitor.VisitHashDirective (path, parsedHashDirective, range) | SynModuleDecl.NamespaceFragment(synModuleOrNamespace) -> traverseSynModuleOrNamespace path synModuleOrNamespace - visitor.VisitModuleDecl(defaultTraverse, decl) + visitor.VisitModuleDecl(origPath, defaultTraverse, decl) - and traverseSynModuleOrNamespace path (SynModuleOrNamespace(_longIdent, _isRec, _isModule, synModuleDecls, _preXmlDoc, _synAttributes, _synAccessOpt, range) as mors) = - match visitor.VisitModuleOrNamespace(mors) with + and traverseSynModuleOrNamespace origPath (SynModuleOrNamespace(_longIdent, _isRec, _isModule, synModuleDecls, _preXmlDoc, _synAttributes, _synAccessOpt, range) as mors) = + match visitor.VisitModuleOrNamespace(origPath, mors) with | Some x -> Some x | None -> - let path = TraverseStep.ModuleOrNamespace mors :: path + let path = SyntaxNode.SynModuleOrNamespace mors :: origPath synModuleDecls |> List.map (fun x -> dive x x.Range (traverseSynModuleDecl path)) |> pick range mors - and traverseSynExpr path (expr:SynExpr) = + and traverseSynExpr origPath (expr:SynExpr) = let pick = pick expr.Range let defaultTraverse e = - let origPath = path - let path = TraverseStep.Expr e :: path + let path = SyntaxNode.SynExpr e :: origPath let traverseSynExpr = traverseSynExpr path + let traverseSynType = traverseSynType path + let traversePat = traversePat path match e with + | SynExpr.Paren (synExpr, _, _, _parenRange) -> traverseSynExpr synExpr + | SynExpr.Quote (_synExpr, _, synExpr2, _, _range) -> [//dive synExpr synExpr.Range traverseSynExpr // TODO, what is this? dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.Const (_synConst, _range) -> None - | SynExpr.Typed (synExpr, synType, _range) -> [ traverseSynExpr synExpr; traverseSynType synType ] |> List.tryPick id + + | SynExpr.InterpolatedString (parts, _, _) -> + [ for part in parts do + match part with + | SynInterpolatedStringPart.String _ -> () + | SynInterpolatedStringPart.FillExpr (fillExpr, _) -> + yield dive fillExpr fillExpr.Range traverseSynExpr ] + |> pick expr + + | SynExpr.Typed (synExpr, synType, _range) -> + [ traverseSynExpr synExpr; traverseSynType synType ] |> List.tryPick id + | SynExpr.Tuple (_, synExprList, _, _range) - | SynExpr.ArrayOrList (_, synExprList, _range) -> synExprList |> List.map (fun x -> dive x x.Range traverseSynExpr) |> pick expr + | SynExpr.ArrayOrList (_, synExprList, _range) -> + synExprList |> List.map (fun x -> dive x x.Range traverseSynExpr) |> pick expr | SynExpr.AnonRecd (_isStruct, copyOpt, synExprList, _range) -> [ match copyOpt with @@ -224,9 +273,10 @@ module public AstTraversal = None ) | _ -> () - for (_,x) in synExprList do + for _,x in synExprList do yield dive x x.Range traverseSynExpr ] |> pick expr + | SynExpr.Record (inheritOpt,copyOpt,fields, _range) -> [ let diveIntoSeparator offsideColumn scPosOpt copyOpt = @@ -313,12 +363,13 @@ module public AstTraversal = | _ -> () ] |> pick expr + | SynExpr.New (_, _synType, synExpr, _range) -> traverseSynExpr synExpr | SynExpr.ObjExpr (ty,baseCallOpt,binds,ifaces,_range1,_range2) -> let result = ifaces - |> Seq.map (fun (InterfaceImpl(ty, _, _)) -> ty) - |> Seq.tryPick visitor.VisitInterfaceSynMemberDefnType + |> Seq.map (fun (SynInterfaceImpl(ty, _, _)) -> ty) + |> Seq.tryPick (fun ty -> visitor.VisitInterfaceSynMemberDefnType(path, ty)) if result.IsSome then result @@ -331,34 +382,39 @@ module public AstTraversal = yield dive newCall newCall.Range traverseSynExpr | _ -> () for b in binds do - yield dive b b.RangeOfBindingAndRhs (traverseSynBinding path) - for InterfaceImpl(_ty, binds, _range) in ifaces do + yield dive b b.RangeOfBindingWithRhs (traverseSynBinding path) + for SynInterfaceImpl(_ty, binds, _range) in ifaces do for b in binds do - yield dive b b.RangeOfBindingAndRhs (traverseSynBinding path) + yield dive b b.RangeOfBindingWithRhs (traverseSynBinding path) ] |> pick expr + | SynExpr.While (_sequencePointInfoForWhileLoop, synExpr, synExpr2, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.For (_sequencePointInfoForForLoop, _ident, synExpr, _, synExpr2, synExpr3, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr dive synExpr3 synExpr3.Range traverseSynExpr] |> pick expr + | SynExpr.ForEach (_sequencePointInfoForForLoop, _seqExprOnly, _isFromSource, synPat, synExpr, synExpr2, _range) -> [dive synPat synPat.Range traversePat dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr - | SynExpr.ArrayOrListOfSeqExpr (_, synExpr, _range) -> traverseSynExpr synExpr - | SynExpr.CompExpr (_, _, synExpr, _range) -> + + | SynExpr.ArrayOrListComputed (_, synExpr, _range) -> traverseSynExpr synExpr + + | SynExpr.ComputationExpr (_, synExpr, _range) -> // now parser treats this syntactic expression as computation expression // { identifier } - // here we detect this situation and treat CompExpr { Identifier } as attempt to create record - // note: sequence expressions use SynExpr.CompExpr too - they need to be filtered out + // here we detect this situation and treat ComputationExpr { Identifier } as attempt to create record + // note: sequence expressions use SynExpr.ComputationExpr too - they need to be filtered out let isPartOfArrayOrList = match origPath with - | TraverseStep.Expr(SynExpr.ArrayOrListOfSeqExpr (_, _, _)) :: _ -> true + | SyntaxNode.SynExpr(SynExpr.ArrayOrListComputed _) :: _ -> true | _ -> false let ok = match isPartOfArrayOrList, synExpr with @@ -368,24 +424,31 @@ module public AstTraversal = if ok.IsSome then ok else traverseSynExpr synExpr - | SynExpr.Lambda (_, _, synSimplePats, synExpr, _range) -> + + | SynExpr.Lambda (_, _, synSimplePats, _, synExpr, _, _range) -> match synSimplePats with | SynSimplePats.SimplePats(pats,_) -> - match visitor.VisitSimplePats(pats) with + match visitor.VisitSimplePats(path, pats) with | Some x -> Some x | None -> traverseSynExpr synExpr | _ -> traverseSynExpr synExpr + | SynExpr.MatchLambda (_isExnMatch,_argm,synMatchClauseList,_spBind,_wholem) -> synMatchClauseList |> List.map (fun x -> dive x x.Range (traverseSynMatchClause path)) |> pick expr + | SynExpr.Match (_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> [yield dive synExpr synExpr.Range traverseSynExpr yield! synMatchClauseList |> List.map (fun x -> dive x x.RangeOfGuardAndRhs (traverseSynMatchClause path))] |> pick expr + | SynExpr.Do (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.Assert (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.Fixed (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.App (_exprAtomicFlag, isInfix, synExpr, synExpr2, _range) -> if isInfix then [dive synExpr2 synExpr2.Range traverseSynExpr @@ -395,145 +458,197 @@ module public AstTraversal = [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.TypeApp (synExpr, _, _synTypeList, _commas, _, _, _range) -> traverseSynExpr synExpr - | SynExpr.LetOrUse (_, _, synBindingList, synExpr, range) -> - match visitor.VisitLetOrUse(path, traverseSynBinding path, synBindingList, range) with + + | SynExpr.LetOrUse (_, isRecursive, synBindingList, synExpr, range) -> + match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with | Some x -> Some x | None -> - [yield! synBindingList |> List.map (fun x -> dive x x.RangeOfBindingAndRhs (traverseSynBinding path)) + [yield! synBindingList |> List.map (fun x -> dive x x.RangeOfBindingWithRhs (traverseSynBinding path)) yield dive synExpr synExpr.Range traverseSynExpr] |> pick expr + | SynExpr.TryWith (synExpr, _range, synMatchClauseList, _range2, _range3, _sequencePointInfoForTry, _sequencePointInfoForWith) -> [yield dive synExpr synExpr.Range traverseSynExpr yield! synMatchClauseList |> List.map (fun x -> dive x x.Range (traverseSynMatchClause path))] |> pick expr + | SynExpr.TryFinally (synExpr, synExpr2, _range, _sequencePointInfoForTry, _sequencePointInfoForFinally) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.Lazy (synExpr, _range) -> traverseSynExpr synExpr - | SynExpr.SequentialOrImplicitYield (_sequencePointInfoForSeq, synExpr, synExpr2, _, _range) - | SynExpr.Sequential (_sequencePointInfoForSeq, _, synExpr, synExpr2, _range) -> + + | SynExpr.SequentialOrImplicitYield (_sequencePointInfoForSequential, synExpr, synExpr2, _, _range) + + | SynExpr.Sequential (_sequencePointInfoForSequential, _, synExpr, synExpr2, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr - | SynExpr.IfThenElse (synExpr, synExpr2, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> + + | SynExpr.IfThenElse (_, _, synExpr, _, synExpr2, _, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> [yield dive synExpr synExpr.Range traverseSynExpr yield dive synExpr2 synExpr2.Range traverseSynExpr match synExprOpt with | None -> () - | Some(x) -> yield dive x x.Range traverseSynExpr] + | Some x -> yield dive x x.Range traverseSynExpr] |> pick expr - | SynExpr.Ident (_ident) -> None + + | SynExpr.Ident _ident -> None + | SynExpr.LongIdent (_, _longIdent, _altNameRefCell, _range) -> None + | SynExpr.LongIdentSet (_longIdent, synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.DotGet (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr + | SynExpr.Set (synExpr, synExpr2, _) + | SynExpr.DotSet (synExpr, _, synExpr2, _) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr - | SynExpr.DotIndexedGet (synExpr, synExprList, _range, _range2) -> + + | SynExpr.IndexRange (expr1, _, expr2, _, _, _) -> + [ match expr1 with Some e -> dive e e.Range traverseSynExpr | None -> () + match expr2 with Some e -> dive e e.Range traverseSynExpr | None -> () ] + |> pick expr + + | SynExpr.IndexFromEnd (e, _) -> + traverseSynExpr e + + | SynExpr.DotIndexedGet (synExpr, indexArgs, _range, _range2) -> [yield dive synExpr synExpr.Range traverseSynExpr - for synExpr in synExprList do - for x in synExpr.Exprs do - yield dive x x.Range traverseSynExpr] + yield dive indexArgs indexArgs.Range traverseSynExpr] |> pick expr - | SynExpr.DotIndexedSet (synExpr, synExprList, synExpr2, _, _range, _range2) -> + + | SynExpr.DotIndexedSet (synExpr, indexArgs, synExpr2, _, _range, _range2) -> [yield dive synExpr synExpr.Range traverseSynExpr - for synExpr in synExprList do - for x in synExpr.Exprs do - yield dive x x.Range traverseSynExpr + yield dive indexArgs indexArgs.Range traverseSynExpr yield dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.JoinIn (synExpr1, _range, synExpr2, _range2) -> [dive synExpr1 synExpr1.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.NamedIndexedPropertySet (_longIdent, synExpr, synExpr2, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr + | SynExpr.DotNamedIndexedPropertySet (synExpr, _longIdent, synExpr2, synExpr3, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr dive synExpr3 synExpr3.Range traverseSynExpr] |> pick expr + | SynExpr.TypeTest (synExpr, synType, _range) + | SynExpr.Upcast (synExpr, synType, _range) + | SynExpr.Downcast (synExpr, synType, _range) -> [dive synExpr synExpr.Range traverseSynExpr dive synType synType.Range traverseSynType] |> pick expr + | SynExpr.InferredUpcast (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.InferredDowncast (synExpr, _range) -> traverseSynExpr synExpr - | SynExpr.Null (_range) -> None + + | SynExpr.Null _range -> None + | SynExpr.AddressOf (_, synExpr, _range, _range2) -> traverseSynExpr synExpr + | SynExpr.TraitCall (_synTyparList, _synMemberSig, synExpr, _range) -> traverseSynExpr synExpr - | SynExpr.ImplicitZero (_range) -> None + + | SynExpr.ImplicitZero _range -> None + | SynExpr.YieldOrReturn (_, synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.YieldOrReturnFrom (_, synExpr, _range) -> traverseSynExpr synExpr - | SynExpr.LetOrUseBang (_sequencePointInfoForBinding, _, _, synPat, synExpr, synExpr2, _range) -> - [dive synPat synPat.Range traversePat - dive synExpr synExpr.Range traverseSynExpr - dive synExpr2 synExpr2.Range traverseSynExpr] + + | SynExpr.LetOrUseBang(_sequencePointInfoForBinding, _, _, synPat, synExpr, andBangSynExprs, synExpr2, _range) -> + [ + yield dive synPat synPat.Range traversePat + yield dive synExpr synExpr.Range traverseSynExpr + yield! + [ for _,_,_,andBangSynPat,andBangSynExpr,_ in andBangSynExprs do + yield (dive andBangSynPat andBangSynPat.Range traversePat) + yield (dive andBangSynExpr andBangSynExpr.Range traverseSynExpr)] + yield dive synExpr2 synExpr2.Range traverseSynExpr + ] |> pick expr + | SynExpr.MatchBang (_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> [yield dive synExpr synExpr.Range traverseSynExpr yield! synMatchClauseList |> List.map (fun x -> dive x x.RangeOfGuardAndRhs (traverseSynMatchClause path))] |> pick expr + | SynExpr.DoBang (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.LibraryOnlyILAssembly _ -> None + | SynExpr.LibraryOnlyStaticOptimization _ -> None + | SynExpr.LibraryOnlyUnionCaseFieldGet _ -> None + | SynExpr.LibraryOnlyUnionCaseFieldSet _ -> None + | SynExpr.ArbitraryAfterError (_debugStr, _range) -> None + | SynExpr.FromParseError (synExpr, _range) -> traverseSynExpr synExpr + | SynExpr.DiscardAfterMissingQualificationAfterDot (synExpr, _range) -> traverseSynExpr synExpr - visitor.VisitExpr(path, traverseSynExpr path, defaultTraverse, expr) + visitor.VisitExpr(origPath, traverseSynExpr origPath, defaultTraverse, expr) - and traversePat (pat: SynPat) = + and traversePat origPath (pat: SynPat) = let defaultTraverse p = + let path = SyntaxNode.SynPat p :: origPath match p with - | SynPat.Paren (p, _) -> traversePat p - | SynPat.Or (p1, p2, _) -> [ p1; p2] |> List.tryPick traversePat + | SynPat.Paren (p, _) -> traversePat path p + | SynPat.Or (p1, p2, _) -> [ p1; p2] |> List.tryPick (traversePat path) | SynPat.Ands (ps, _) | SynPat.Tuple (_, ps, _) - | SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick traversePat - | SynPat.Attrib (p, _, _) -> traversePat p + | SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick (traversePat path) + | SynPat.Attrib (p, _, _) -> traversePat path p | SynPat.LongIdent(_, _, _, args, _, _) -> match args with - | SynConstructorArgs.Pats ps -> ps |> List.tryPick traversePat - | SynConstructorArgs.NamePatPairs (ps, _) -> - ps |> List.map snd |> List.tryPick traversePat + | SynArgPats.Pats ps -> ps |> List.tryPick (traversePat path) + | SynArgPats.NamePatPairs (ps, _) -> + ps |> List.map snd |> List.tryPick (traversePat path) | SynPat.Typed (p, ty, _) -> - [ traversePat p; traverseSynType ty ] |> List.tryPick id + [ traversePat path p; traverseSynType path ty ] |> List.tryPick id | _ -> None - visitor.VisitPat (defaultTraverse, pat) + visitor.VisitPat (origPath, defaultTraverse, pat) - and traverseSynType (ty: SynType) = + and traverseSynType origPath (StripParenTypes ty) = let defaultTraverse ty = + let path = SyntaxNode.SynType ty :: origPath match ty with | SynType.App (typeName, _, typeArgs, _, _, _, _) | SynType.LongIdentApp (typeName, _, _, typeArgs, _, _, _) -> [ yield typeName yield! typeArgs ] - |> List.tryPick traverseSynType - | SynType.Fun (ty1, ty2, _) -> [ty1; ty2] |> List.tryPick traverseSynType + |> List.tryPick (traverseSynType path) + | SynType.Fun (ty1, ty2, _) -> [ty1; ty2] |> List.tryPick (traverseSynType path) | SynType.MeasurePower (ty, _, _) | SynType.HashConstraint (ty, _) | SynType.WithGlobalConstraints (ty, _, _) - | SynType.Array (_, ty, _) -> traverseSynType ty + | SynType.Array (_, ty, _) -> traverseSynType path ty | SynType.StaticConstantNamed (ty1, ty2, _) - | SynType.MeasureDivide (ty1, ty2, _) -> [ty1; ty2] |> List.tryPick traverseSynType - | SynType.Tuple (_, tys, _) -> tys |> List.map snd |> List.tryPick traverseSynType + | SynType.MeasureDivide (ty1, ty2, _) -> [ty1; ty2] |> List.tryPick (traverseSynType path) + | SynType.Tuple (_, tys, _) -> tys |> List.map snd |> List.tryPick (traverseSynType path) | SynType.StaticConstantExpr (expr, _) -> traverseSynExpr [] expr | SynType.Anon _ -> None | _ -> None - visitor.VisitType (defaultTraverse, ty) + visitor.VisitType (origPath, defaultTraverse, ty) and normalizeMembersToDealWithPeculiaritiesOfGettersAndSetters path traverseInherit (synMemberDefns:SynMemberDefns) = synMemberDefns @@ -543,8 +658,8 @@ module public AstTraversal = match mems |> Seq.toList with | [mem] -> // the typical case, a single member has this range 'r' Some (dive mem r (traverseSynMemberDefn path traverseInherit)) - | [SynMemberDefn.Member(Binding(_,_,_,_,_,_,_,SynPat.LongIdent(lid1,Some(info1),_,_,_,_),_,_,_,_),_) as mem1 - SynMemberDefn.Member(Binding(_,_,_,_,_,_,_,SynPat.LongIdent(lid2,Some(info2),_,_,_,_),_,_,_,_),_) as mem2] -> // can happen if one is a getter and one is a setter + | [SynMemberDefn.Member(SynBinding(_,_,_,_,_,_,_,SynPat.LongIdent(lid1,Some(info1),_,_,_,_),_,_,_,_),_) as mem1 + SynMemberDefn.Member(SynBinding(_,_,_,_,_,_,_,SynPat.LongIdent(lid2,Some(info2),_,_,_,_),_,_,_,_),_) as mem2] -> // can happen if one is a getter and one is a setter // ensure same long id assert( (lid1.Lid,lid2.Lid) ||> List.forall2 (fun x y -> x.idText = y.idText) ) // ensure one is getter, other is setter @@ -559,7 +674,7 @@ module public AstTraversal = ) | [] -> #if DEBUG - assert(false) + assert false failwith "impossible, Seq.groupBy never returns empty results" #else // swallow AST error and recover silently @@ -567,7 +682,7 @@ module public AstTraversal = #endif | _ -> #if DEBUG - assert(false) // more than 2 members claim to have the same range, this indicates a bug in the AST + assert false // more than 2 members claim to have the same range, this indicates a bug in the AST failwith "bug in AST" #else // swallow AST error and recover silently @@ -575,27 +690,27 @@ module public AstTraversal = #endif ) - and traverseSynTypeDefn path (SynTypeDefn.TypeDefn(synComponentInfo, synTypeDefnRepr, synMemberDefns, tRange) as tydef) = - let path = TraverseStep.TypeDefn tydef :: path + and traverseSynTypeDefn origPath (SynTypeDefn(synComponentInfo, synTypeDefnRepr, synMemberDefns, _, tRange) as tydef) = + let path = SyntaxNode.SynTypeDefn tydef :: origPath - match visitor.VisitComponentInfo synComponentInfo with + match visitor.VisitComponentInfo (origPath, synComponentInfo) with | Some x -> Some x | None -> [ match synTypeDefnRepr with | SynTypeDefnRepr.Exception _ -> - // This node is generated in TypeChecker.fs, not in the AST. + // This node is generated in CheckExpressions.fs, not in the AST. // But note exception declarations are missing from this tree walk. () | SynTypeDefnRepr.ObjectModel(synTypeDefnKind, synMemberDefns, _oRange) -> // traverse inherit function is used to capture type specific data required for processing Inherit part - let traverseInherit (synType : SynType, range : range) = - visitor.VisitInheritSynMemberDefn(synComponentInfo, synTypeDefnKind, synType, synMemberDefns, range) + let traverseInherit (synType: SynType, range: range) = + visitor.VisitInheritSynMemberDefn(path, synComponentInfo, synTypeDefnKind, synType, synMemberDefns, range) yield! synMemberDefns |> normalizeMembersToDealWithPeculiaritiesOfGettersAndSetters path traverseInherit | SynTypeDefnRepr.Simple(synTypeDefnSimpleRepr, _range) -> match synTypeDefnSimpleRepr with | SynTypeDefnSimpleRepr.TypeAbbrev(_,synType,m) -> - yield dive synTypeDefnRepr synTypeDefnRepr.Range (fun _ -> visitor.VisitTypeAbbrev(synType,m)) + yield dive synTypeDefnRepr synTypeDefnRepr.Range (fun _ -> visitor.VisitTypeAbbrev(path, synType,m)) | _ -> () // enums/DUs/record definitions don't have any SynExprs inside them yield! synMemberDefns |> normalizeMembersToDealWithPeculiaritiesOfGettersAndSetters path (fun _ -> None) @@ -603,32 +718,32 @@ module public AstTraversal = and traverseSynMemberDefn path traverseInherit (m:SynMemberDefn) = let pick (debugObj:obj) = pick m.Range debugObj - let path = TraverseStep.MemberDefn m :: path + let path = SyntaxNode.SynMemberDefn m :: path match m with | SynMemberDefn.Open(_longIdent, _range) -> None | SynMemberDefn.Member(synBinding, _range) -> traverseSynBinding path synBinding - | SynMemberDefn.ImplicitCtor(_synAccessOption, _synAttributes, simplePats, _identOption, _range) -> + | SynMemberDefn.ImplicitCtor(_synAccessOption, _synAttributes, simplePats, _identOption, _doc, _range) -> match simplePats with - | SynSimplePats.SimplePats(simplePats, _) -> visitor.VisitSimplePats(simplePats) + | SynSimplePats.SimplePats(simplePats, _) -> visitor.VisitSimplePats(path, simplePats) | _ -> None | SynMemberDefn.ImplicitInherit(synType, synExpr, _identOption, range) -> [ dive () synType.Range (fun () -> match traverseInherit (synType, range) with - | None -> visitor.VisitImplicitInherit(traverseSynExpr path, synType, synExpr, range) + | None -> visitor.VisitImplicitInherit(path, traverseSynExpr path, synType, synExpr, range) | x -> x) dive () synExpr.Range (fun() -> - visitor.VisitImplicitInherit(traverseSynExpr path, synType, synExpr, range) + visitor.VisitImplicitInherit(path, traverseSynExpr path, synType, synExpr, range) ) ] |> pick m | SynMemberDefn.AutoProperty(_attribs, _isStatic, _id, _tyOpt, _propKind, _, _xmlDoc, _access, synExpr, _, _) -> traverseSynExpr path synExpr - | SynMemberDefn.LetBindings(synBindingList, _, _, range) -> - match visitor.VisitLetOrUse(path, traverseSynBinding path, synBindingList, range) with + | SynMemberDefn.LetBindings(synBindingList, isRecursive, _, range) -> + match visitor.VisitLetOrUse(path, isRecursive, traverseSynBinding path, synBindingList, range) with | Some x -> Some x - | None -> synBindingList |> List.map (fun x -> dive x x.RangeOfBindingAndRhs (traverseSynBinding path)) |> pick m + | None -> synBindingList |> List.map (fun x -> dive x x.RangeOfBindingWithRhs (traverseSynBinding path)) |> pick m | SynMemberDefn.AbstractSlot(_synValSig, _memberFlags, _range) -> None | SynMemberDefn.Interface(synType, synMemberDefnsOption, _range) -> - match visitor.VisitInterfaceSynMemberDefnType(synType) with + match visitor.VisitInterfaceSynMemberDefnType(path, synType) with | None -> match synMemberDefnsOption with | None -> None @@ -638,12 +753,12 @@ module public AstTraversal = | SynMemberDefn.ValField(_synField, _range) -> None | SynMemberDefn.NestedType(synTypeDefn, _synAccessOption, _range) -> traverseSynTypeDefn path synTypeDefn - and traverseSynMatchClause path mc = - let path = TraverseStep.MatchClause mc :: path + and traverseSynMatchClause origPath mc = let defaultTraverse mc = + let path = SyntaxNode.SynMatchClause mc :: origPath match mc with - | (SynMatchClause.Clause(synPat, synExprOption, synExpr, _range, _sequencePointInfoForTarget) as all) -> - [dive synPat synPat.Range traversePat] + | SynMatchClause(synPat, synExprOption, _, synExpr, _range, _sequencePointInfoForTarget) as all -> + [dive synPat synPat.Range (traversePat path) ] @ ([ match synExprOption with @@ -653,17 +768,17 @@ module public AstTraversal = ] |> List.map (fun x -> dive x x.Range (traverseSynExpr path)) )|> pick all.Range all - visitor.VisitMatchClause(defaultTraverse,mc) + visitor.VisitMatchClause(origPath, defaultTraverse, mc) - and traverseSynBinding path b = + and traverseSynBinding origPath b = let defaultTraverse b = - let path = TraverseStep.Binding b :: path + let path = SyntaxNode.SynBinding b :: origPath match b with - | (SynBinding.Binding(_synAccessOption, _synBindingKind, _, _, _synAttributes, _preXmlDoc, _synValData, synPat, _synBindingReturnInfoOption, synExpr, _range, _sequencePointInfoForBinding)) -> - [ traversePat synPat + | SynBinding(_synAccessOption, _synBindingKind, _, _, _synAttributes, _preXmlDoc, _synValData, synPat, _synBindingReturnInfoOption, synExpr, _range, _sequencePointInfoForBinding) -> + [ traversePat path synPat traverseSynExpr path synExpr ] |> List.tryPick id - visitor.VisitBinding(defaultTraverse,b) + visitor.VisitBinding(origPath, defaultTraverse,b) match parseTree with | ParsedInput.ImplFile (ParsedImplFileInput (_,_,_,_,_,l,_))-> diff --git a/src/fsharp/service/ServiceParseTreeWalk.fsi b/src/fsharp/service/ServiceParseTreeWalk.fsi new file mode 100644 index 00000000000..d042d7199c1 --- /dev/null +++ b/src/fsharp/service/ServiceParseTreeWalk.fsi @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.Syntax + +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +/// Used to track route during traversal of syntax using SyntaxTraversal.Traverse +[] +type SyntaxNode = + | SynPat of SynPat + | SynType of SynType + | SynExpr of SynExpr + | SynModule of SynModuleDecl + | SynModuleOrNamespace of SynModuleOrNamespace + | SynTypeDefn of SynTypeDefn + | SynMemberDefn of SynMemberDefn + | SynMatchClause of SynMatchClause + | SynBinding of SynBinding + +type SyntaxVisitorPath = SyntaxNode list + +[] +type SyntaxVisitorBase<'T> = + new: unit -> SyntaxVisitorBase<'T> + + default VisitBinding: path: SyntaxVisitorPath * defaultTraverse: (SynBinding -> 'T option) * synBinding: SynBinding -> 'T option + abstract VisitBinding: path: SyntaxVisitorPath * defaultTraverse: (SynBinding -> 'T option) * synBinding: SynBinding -> 'T option + + default VisitComponentInfo: path: SyntaxVisitorPath * synComponentInfo: SynComponentInfo -> 'T option + abstract VisitComponentInfo: path: SyntaxVisitorPath * synComponentInfo: SynComponentInfo -> 'T option + + /// Controls the behavior when a SynExpr is reached; it can just do + /// defaultTraverse(expr) if you have no special logic for this node, and want the default processing to pick which sub-node to dive deeper into + /// or can inject non-default behavior, which might incorporate: + /// traverseSynExpr(subExpr) to recurse deeper on some particular sub-expression based on your own logic + /// path helps to track AST nodes that were passed during traversal + abstract VisitExpr: path: SyntaxVisitorPath * traverseSynExpr: (SynExpr -> 'T option) * defaultTraverse: (SynExpr -> 'T option) * synExpr: SynExpr -> 'T option + default VisitExpr: path: SyntaxVisitorPath * traverseSynExpr: (SynExpr -> 'T option) * defaultTraverse: (SynExpr -> 'T option) * synExpr: SynExpr -> 'T option + + abstract VisitHashDirective: path: SyntaxVisitorPath * hashDirective: ParsedHashDirective * range: range -> 'T option + default VisitHashDirective: path: SyntaxVisitorPath * hashDirective: ParsedHashDirective * range: range -> 'T option + + abstract VisitImplicitInherit: path: SyntaxVisitorPath * defaultTraverse: (SynExpr -> 'T option) * inheritedType: SynType * synArgs: SynExpr * range: range -> 'T option + default VisitImplicitInherit: path: SyntaxVisitorPath * defaultTraverse: (SynExpr -> 'T option) * inheritedType: SynType * synArgs: SynExpr * range: range -> 'T option + + abstract VisitInheritSynMemberDefn: path: SyntaxVisitorPath * componentInfo: SynComponentInfo * typeDefnKind: SynTypeDefnKind * synType: SynType * members: SynMemberDefns * range: range -> 'T option + default VisitInheritSynMemberDefn: path: SyntaxVisitorPath * componentInfo: SynComponentInfo * typeDefnKind: SynTypeDefnKind * synType: SynType * members: SynMemberDefns * range: range -> 'T option + + abstract VisitInterfaceSynMemberDefnType: path: SyntaxVisitorPath * synType: SynType -> 'T option + default VisitInterfaceSynMemberDefnType: path: SyntaxVisitorPath * synType: SynType -> 'T option + + abstract VisitLetOrUse: path: SyntaxVisitorPath * isRecursive: bool * defaultTraverse: (SynBinding -> 'T option) * bindings: SynBinding list * range: range -> 'T option + default VisitLetOrUse: path: SyntaxVisitorPath * isRecursive: bool * defaultTraverse: (SynBinding -> 'T option) * bindings: SynBinding list * range: range -> 'T option + + abstract VisitMatchClause: path: SyntaxVisitorPath * defaultTraverse: (SynMatchClause -> 'T option) * matchClause: SynMatchClause -> 'T option + default VisitMatchClause: path: SyntaxVisitorPath * defaultTraverse: (SynMatchClause -> 'T option) * matchClause: SynMatchClause -> 'T option + + abstract VisitModuleDecl: path: SyntaxVisitorPath * defaultTraverse: (SynModuleDecl -> 'T option) * synModuleDecl: SynModuleDecl -> 'T option + default VisitModuleDecl: path: SyntaxVisitorPath * defaultTraverse: (SynModuleDecl -> 'T option) * synModuleDecl: SynModuleDecl -> 'T option + + abstract VisitModuleOrNamespace: path: SyntaxVisitorPath * synModuleOrNamespace: SynModuleOrNamespace -> 'T option + default VisitModuleOrNamespace: path: SyntaxVisitorPath * synModuleOrNamespace: SynModuleOrNamespace -> 'T option + + abstract VisitPat: path: SyntaxVisitorPath * defaultTraverse: (SynPat -> 'T option) * synPat: SynPat -> 'T option + default VisitPat: path: SyntaxVisitorPath * defaultTraverse: (SynPat -> 'T option) * synPat: SynPat -> 'T option + + abstract VisitRecordField: path: SyntaxVisitorPath * copyOpt: SynExpr option * recordField: LongIdentWithDots option -> 'T option + default VisitRecordField: path: SyntaxVisitorPath * copyOpt: SynExpr option * recordField: LongIdentWithDots option -> 'T option + + abstract VisitSimplePats: path: SyntaxVisitorPath * synPats: SynSimplePat list -> 'T option + default VisitSimplePats: path: SyntaxVisitorPath * synPats: SynSimplePat list -> 'T option + + abstract VisitType: path: SyntaxVisitorPath * defaultTraverse: (SynType -> 'T option) * synType: SynType -> 'T option + default VisitType: path: SyntaxVisitorPath * defaultTraverse: (SynType -> 'T option) * synType: SynType -> 'T option + + abstract VisitTypeAbbrev: path: SyntaxVisitorPath * synType: SynType * range: range -> 'T option + default VisitTypeAbbrev: path: SyntaxVisitorPath * synType: SynType * range: range -> 'T option + +module public SyntaxTraversal = + + val internal rangeContainsPosLeftEdgeInclusive: m1: range -> p: pos -> bool + + val internal rangeContainsPosEdgesExclusive: m1: range -> p: pos -> bool + + val internal rangeContainsPosLeftEdgeExclusiveAndRightEdgeInclusive: m1: range -> p: pos -> bool + + val internal dive: node: 'a -> range: 'b -> project: ('a -> 'c) -> 'b * (unit -> 'c) + + val internal pick: pos: pos -> outerRange: range -> debugObj: obj -> diveResults: (range * (unit -> 'a option)) list -> 'a option + + val Traverse: pos: pos * parseTree: ParsedInput * visitor: SyntaxVisitorBase<'T> -> 'T option diff --git a/src/fsharp/service/ServiceParsedInputOps.fs b/src/fsharp/service/ServiceParsedInputOps.fs new file mode 100644 index 00000000000..2df7e0f4aa7 --- /dev/null +++ b/src/fsharp/service/ServiceParsedInputOps.fs @@ -0,0 +1,1689 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open System +open System.IO +open System.Collections.Generic +open System.Text.RegularExpressions +open Internal.Utilities.Library +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Syntax +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range + +module SourceFileImpl = + let IsInterfaceFile file = + let ext = Path.GetExtension file + 0 = String.Compare(".fsi", ext, StringComparison.OrdinalIgnoreCase) + + /// Additional #defines that should be in place when editing a file in a file editor such as VS. + let AdditionalDefinesForUseInEditor(isInteractive: bool) = + if isInteractive then ["INTERACTIVE";"EDITING"] // This is still used by the foreground parse + else ["COMPILED";"EDITING"] + +type CompletionPath = string list * string option // plid * residue + +[] +type FSharpInheritanceOrigin = + | Class + | Interface + | Unknown + +[] +type InheritanceContext = + | Class + | Interface + | Unknown + +[] +type RecordContext = + | CopyOnUpdate of range: range * path: CompletionPath + | Constructor of typeName: string + | New of path: CompletionPath + +[] +type CompletionContext = + /// Completion context cannot be determined due to errors + | Invalid + + /// Completing something after the inherit keyword + | Inherit of context: InheritanceContext * path: CompletionPath + + /// Completing records field + | RecordField of context: RecordContext + + | RangeOperator + + /// Completing named parameters\setters in parameter list of constructor\method calls + /// end of name ast node * list of properties\parameters that were already set + | ParameterList of pos * HashSet + + | AttributeApplication + + | OpenDeclaration of isOpenType: bool + + /// Completing pattern type (e.g. foo (x: |)) + | PatternType + +type ShortIdent = string + +type ShortIdents = ShortIdent[] + +type MaybeUnresolvedIdent = { Ident: ShortIdent; Resolved: bool } + +type ModuleKind = { IsAutoOpen: bool; HasModuleSuffix: bool } + +[] +type EntityKind = + | Attribute + | Type + | FunctionOrValue of isActivePattern: bool + | Module of ModuleKind + override x.ToString() = sprintf "%A" x + +type InsertionContextEntity = + { FullRelativeName: string + Qualifier: string + Namespace: string option + FullDisplayName: string + LastIdent: ShortIdent } + override x.ToString() = sprintf "%A" x + +type ScopeKind = + | Namespace + | TopModule + | NestedModule + | OpenDeclaration + | HashDirective + override x.ToString() = sprintf "%A" x + +type InsertionContext = + { ScopeKind: ScopeKind + Pos: pos } + +type FSharpModule = + { Idents: ShortIdents + Range: range } + +type OpenStatementInsertionPoint = + | TopLevel + | Nearest + +[] +module Entity = + let getRelativeNamespace (targetNs: ShortIdents) (sourceNs: ShortIdents) = + let rec loop index = + if index > targetNs.Length - 1 then sourceNs.[index..] + // target namespace is not a full parent of source namespace, keep the source ns as is + elif index > sourceNs.Length - 1 then sourceNs + elif targetNs.[index] = sourceNs.[index] then loop (index + 1) + else sourceNs.[index..] + if sourceNs.Length = 0 || targetNs.Length = 0 then sourceNs + else loop 0 + + let cutAutoOpenModules (autoOpenParent: ShortIdents option) (candidateNs: ShortIdents) = + let nsCount = + match autoOpenParent with + | Some parent when parent.Length > 0 -> + min (parent.Length - 1) candidateNs.Length + | _ -> candidateNs.Length + candidateNs.[0..nsCount - 1] + + let tryCreate (targetNamespace: ShortIdents option, targetScope: ShortIdents, partiallyQualifiedName: MaybeUnresolvedIdent[], + requiresQualifiedAccessParent: ShortIdents option, autoOpenParent: ShortIdents option, candidateNamespace: ShortIdents option, candidate: ShortIdents) = + match candidate with + | [||] -> [||] + | _ -> + partiallyQualifiedName + |> Array.heads + // long ident must contain an unresolved part, otherwise we show false positive suggestions like + // "open System" for `let _ = System.DateTime.Naaaw`. Here only "Naaw" is unresolved. + |> Array.filter (fun x -> x |> Array.exists (fun x -> not x.Resolved)) + |> Array.choose (fun parts -> + let parts = parts |> Array.map (fun x -> x.Ident) + if not (candidate |> Array.endsWith parts) then None + else + let identCount = parts.Length + let fullOpenableNs, restIdents = + let openableNsCount = + match requiresQualifiedAccessParent with + | Some parent -> min parent.Length candidate.Length + | None -> candidate.Length + candidate.[0..openableNsCount - 2], candidate.[openableNsCount - 1..] + + let openableNs = cutAutoOpenModules autoOpenParent fullOpenableNs + + let getRelativeNs ns = + match targetNamespace, candidateNamespace with + | Some targetNs, Some candidateNs when candidateNs = targetNs -> + getRelativeNamespace targetScope ns + | None, _ -> getRelativeNamespace targetScope ns + | _ -> ns + + let relativeNs = getRelativeNs openableNs + + match relativeNs, restIdents with + | [||], [||] -> None + | [||], [|_|] -> None + | _ -> + let fullRelativeName = Array.append (getRelativeNs fullOpenableNs) restIdents + let ns = + match relativeNs with + | [||] -> None + | _ when identCount > 1 && relativeNs.Length >= identCount -> + Some (relativeNs.[0..relativeNs.Length - identCount] |> String.concat ".") + | _ -> Some (relativeNs |> String.concat ".") + let qualifier = + if fullRelativeName.Length > 1 && fullRelativeName.Length >= identCount then + fullRelativeName.[0..fullRelativeName.Length - identCount] + else fullRelativeName + Some + { FullRelativeName = String.concat "." fullRelativeName //.[0..fullRelativeName.Length - identCount - 1] + Qualifier = String.concat "." qualifier + Namespace = ns + FullDisplayName = match restIdents with [|_|] -> "" | _ -> String.concat "." restIdents + LastIdent = Array.tryLast restIdents |> Option.defaultValue "" }) + +module ParsedInput = + + let emptyStringSet = HashSet() + + let GetRangeOfExprLeftOfDot(pos: pos, parsedInput) = + let CheckLongIdent(longIdent: LongIdent) = + // find the longest prefix before the "pos" dot + let mutable r = (List.head longIdent).idRange + let mutable couldBeBeforeFront = true + for i in longIdent do + if posGeq pos i.idRange.End then + r <- unionRanges r i.idRange + couldBeBeforeFront <- false + couldBeBeforeFront, r + + SyntaxTraversal.Traverse(pos, parsedInput, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + let expr = expr // fix debugger locals + match expr with + | SynExpr.LongIdent (_, LongIdentWithDots(longIdent, _), _altNameRefCell, _range) -> + let _, r = CheckLongIdent longIdent + Some r + | SynExpr.LongIdentSet (LongIdentWithDots(longIdent, _), synExpr, _range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + else + let _, r = CheckLongIdent longIdent + Some r + | SynExpr.DotGet (synExpr, _dotm, LongIdentWithDots(longIdent, _), _range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + else + let inFront, r = CheckLongIdent longIdent + if inFront then + Some synExpr.Range + else + // see comment below for SynExpr.DotSet + Some (unionRanges synExpr.Range r) + | SynExpr.Set (synExpr, synExpr2, range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + elif SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then + traverseSynExpr synExpr2 + else + Some range + | SynExpr.DotSet (synExpr, LongIdentWithDots(longIdent, _), synExpr2, _range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + elif SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then + traverseSynExpr synExpr2 + else + let inFront, r = CheckLongIdent longIdent + if inFront then + Some synExpr.Range + else + // f(0).X.Y.Z + // ^ + // - r has this value + // ---- synExpr.Range has this value + // ------ we want this value + Some (unionRanges synExpr.Range r) + | SynExpr.DotNamedIndexedPropertySet (synExpr, LongIdentWithDots(longIdent, _), synExpr2, synExpr3, _range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + elif SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then + traverseSynExpr synExpr2 + elif SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr3.Range pos then + traverseSynExpr synExpr3 + else + let inFront, r = CheckLongIdent longIdent + if inFront then + Some synExpr.Range + else + Some (unionRanges synExpr.Range r) + | SynExpr.DiscardAfterMissingQualificationAfterDot (synExpr, _range) -> // get this for e.g. "bar()." + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + else + Some synExpr.Range + | SynExpr.FromParseError (synExpr, range) -> + if SyntaxTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then + traverseSynExpr synExpr + else + Some range + | SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident ident, rhs, _) + when ident.idText = "op_ArrayLookup" + && not(SyntaxTraversal.rangeContainsPosLeftEdgeInclusive rhs.Range pos) -> + match defaultTraverse expr with + | None -> + // (expr).(expr) is an ML-deprecated array lookup, but we want intellisense on the dot + // also want it for e.g. [|arr|].(0) + Some expr.Range + | x -> x // we found the answer deeper somewhere in the lhs + | SynExpr.Const (SynConst.Double _, range) -> Some range + | _ -> defaultTraverse expr + }) + + /// searches for the expression island suitable for the evaluation by the debugger + let TryFindExpressionIslandInPosition(pos: pos, parsedInput) = + let getLidParts (lid : LongIdent) = + lid + |> Seq.takeWhile (fun i -> posGeq pos i.idRange.Start) + |> Seq.map (fun i -> i.idText) + |> Seq.toList + + // tries to locate simple expression island + // foundCandidate = false means that we are looking for the candidate expression + // foundCandidate = true - we found candidate (DotGet) and now drill down to the left part + let rec TryGetExpression foundCandidate expr = + match expr with + | SynExpr.Paren (e, _, _, _) when foundCandidate -> + TryGetExpression foundCandidate e + | SynExpr.LongIdent (_isOptional, LongIdentWithDots(lid, _), _altNameRefCell, _m) -> + getLidParts lid |> Some + | SynExpr.DotGet (leftPart, _, LongIdentWithDots(lid, _), _) when (rangeContainsPos (rangeOfLid lid) pos) || foundCandidate -> + // requested position is at the lid part of the DotGet + // process left part and append result to the result of processing lid + let leftPartResult = TryGetExpression true leftPart + match leftPartResult with + | Some leftPartResult -> + [ + yield! leftPartResult + yield! getLidParts lid + ] |> Some + | None -> None + | SynExpr.FromParseError (synExpr, _range) -> TryGetExpression foundCandidate synExpr + | _ -> None + + let rec walker = + { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = + if rangeContainsPos expr.Range pos then + match TryGetExpression false expr with + | Some parts -> parts |> String.concat "." |> Some + | _ -> defaultTraverse expr + else + None } + SyntaxTraversal.Traverse(pos, parsedInput, walker) + + // Given a cursor position here: + // f(x) . ident + // ^ + // walk the AST to find the position here: + // f(x) . ident + // ^ + // On success, return Some (thatPos, boolTrueIfCursorIsAfterTheDotButBeforeTheIdentifier) + // If there's no dot, return None, so for example + // foo + // ^ + // would return None + // TODO would be great to unify this with GetRangeOfExprLeftOfDot above, if possible, as they are similar + let TryFindExpressionASTLeftOfDotLeftOfCursor(pos, parsedInput) = + let dive x = SyntaxTraversal.dive x + let pick x = SyntaxTraversal.pick pos x + let walker = + { new SyntaxVisitorBase<_>() with + member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + let pick = pick expr.Range + let traverseSynExpr, defaultTraverse, expr = traverseSynExpr, defaultTraverse, expr // for debugging: debugger does not get object expression params as local vars + if not(rangeContainsPos expr.Range pos) then + match expr with + | SynExpr.DiscardAfterMissingQualificationAfterDot (e, _m) -> + // This happens with e.g. "f(x) . $" when you bring up a completion list a few spaces after a dot. The cursor is not 'in the parse tree', + // but the dive algorithm will dive down into this node, and this is the one case where we do want to give a result despite the cursor + // not properly being in a node. + match traverseSynExpr e with + | None -> Some (e.Range.End, false) + | r -> r + | _ -> + // This happens for e.g. "System.Console.[]$", where the ".[]" token is thrown away by the parser and we dive into the System.Console longId + // even though the cursor/dot is not in there. In those cases we want to return None, because there is not really a dot completion before + // the cursor location. + None + else + let rec traverseLidOrElse (optExprIfLeftOfLongId : SynExpr option) (LongIdentWithDots(lid, dots) as lidwd) = + let resultIfLeftOfLongId = + match optExprIfLeftOfLongId with + | None -> None + | Some e -> Some (e.Range.End, posGeq lidwd.Range.Start pos) + match dots |> List.mapi (fun i x -> i, x) |> List.rev |> List.tryFind (fun (_, m) -> posGt pos m.Start) with + | None -> resultIfLeftOfLongId + | Some (n, _) -> Some ((List.item n lid).idRange.End, (List.length lid = n+1) // foo.$ + || (posGeq (List.item (n+1) lid).idRange.Start pos)) // foo.$bar + match expr with + | SynExpr.LongIdent (_isOptional, lidwd, _altNameRefCell, _m) -> + traverseLidOrElse None lidwd + | SynExpr.LongIdentSet (lidwd, exprRhs, _m) -> + [ dive lidwd lidwd.Range (traverseLidOrElse None) + dive exprRhs exprRhs.Range traverseSynExpr + ] |> pick expr + | SynExpr.DotGet (exprLeft, dotm, lidwd, _m) -> + let afterDotBeforeLid = mkRange dotm.FileName dotm.End lidwd.Range.Start + [ dive exprLeft exprLeft.Range traverseSynExpr + dive exprLeft afterDotBeforeLid (fun e -> Some (e.Range.End, true)) + dive lidwd lidwd.Range (traverseLidOrElse (Some exprLeft)) + ] |> pick expr + | SynExpr.DotSet (exprLeft, lidwd, exprRhs, _m) -> + [ dive exprLeft exprLeft.Range traverseSynExpr + dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft)) + dive exprRhs exprRhs.Range traverseSynExpr + ] |> pick expr + | SynExpr.Set (exprLeft, exprRhs, _m) -> + [ dive exprLeft exprLeft.Range traverseSynExpr + dive exprRhs exprRhs.Range traverseSynExpr + ] |> pick expr + | SynExpr.NamedIndexedPropertySet (lidwd, exprIndexer, exprRhs, _m) -> + [ dive lidwd lidwd.Range (traverseLidOrElse None) + dive exprIndexer exprIndexer.Range traverseSynExpr + dive exprRhs exprRhs.Range traverseSynExpr + ] |> pick expr + | SynExpr.DotNamedIndexedPropertySet (exprLeft, lidwd, exprIndexer, exprRhs, _m) -> + [ dive exprLeft exprLeft.Range traverseSynExpr + dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft)) + dive exprIndexer exprIndexer.Range traverseSynExpr + dive exprRhs exprRhs.Range traverseSynExpr + ] |> pick expr + | SynExpr.Const (SynConst.Double _, m) -> + if posEq m.End pos then + // the cursor is at the dot + Some (m.End, false) + else + // the cursor is left of the dot + None + | SynExpr.DiscardAfterMissingQualificationAfterDot (e, m) -> + match traverseSynExpr e with + | None -> + if posEq m.End pos then + // the cursor is at the dot + Some (e.Range.End, false) + else + // the cursor is left of the dot + None + | r -> r + | SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident ident, lhs, _m) + when ident.idText = "op_ArrayLookup" + && not(SyntaxTraversal.rangeContainsPosLeftEdgeInclusive lhs.Range pos) -> + match defaultTraverse expr with + | None -> + // (expr).(expr) is an ML-deprecated array lookup, but we want intellisense on the dot + // also want it for e.g. [|arr|].(0) + Some (lhs.Range.End, false) + | x -> x // we found the answer deeper somewhere in the lhs + | _ -> defaultTraverse expr } + SyntaxTraversal.Traverse(pos, parsedInput, walker) + + let GetEntityKind (pos: pos, parsedInput: ParsedInput) : EntityKind option = + let (|ConstructorPats|) = function + | SynArgPats.Pats ps -> ps + | SynArgPats.NamePatPairs(xs, _) -> List.map snd xs + + /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException + let rec (|Sequentials|_|) = function + | SynExpr.Sequential (_, _, e, Sequentials es, _) -> Some (e :: es) + | SynExpr.Sequential (_, _, e1, e2, _) -> Some [e1; e2] + | _ -> None + + let inline isPosInRange range = rangeContainsPos range pos + + let inline ifPosInRange range f = + if isPosInRange range then f() + else None + + let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = + List.tryPick (walkSynModuleOrNamespace true) moduleOrNamespaceList + + and walkSynModuleOrNamespace isTopLevel (SynModuleOrNamespace(_, _, _, decls, _, Attributes attrs, _, r)) = + List.tryPick walkAttribute attrs + |> Option.orElseWith (fun () -> ifPosInRange r (fun _ -> List.tryPick (walkSynModuleDecl isTopLevel) decls)) + + and walkAttribute (attr: SynAttribute) = + if isPosInRange attr.Range then Some EntityKind.Attribute else None + |> Option.orElseWith (fun () -> walkExprWithKind (Some EntityKind.Type) attr.ArgExpr) + + and walkTypar (SynTypar (ident, _, _)) = ifPosInRange ident.idRange (fun _ -> Some EntityKind.Type) + + and walkTyparDecl (SynTyparDecl.SynTyparDecl (Attributes attrs, typar)) = + List.tryPick walkAttribute attrs + |> Option.orElseWith (fun () -> walkTypar typar) + + and walkTypeConstraint = function + | SynTypeConstraint.WhereTyparDefaultsToType (t1, t2, _) -> walkTypar t1 |> Option.orElseWith (fun () -> walkType t2) + | SynTypeConstraint.WhereTyparIsValueType(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparIsReferenceType(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparIsUnmanaged(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparSupportsNull (t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparIsComparable(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparSubtypeOfType(t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty) + | SynTypeConstraint.WhereTyparSupportsMember(ts, sign, _) -> + List.tryPick walkType ts |> Option.orElseWith (fun () -> walkMemberSig sign) + | SynTypeConstraint.WhereTyparIsEnum(t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts) + | SynTypeConstraint.WhereTyparIsDelegate(t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts) + + and walkPatWithKind (kind: EntityKind option) = function + | SynPat.Ands (pats, _) -> List.tryPick walkPat pats + | SynPat.As (pat1, pat2, _) -> List.tryPick walkPat [pat1; pat2] + | SynPat.Typed(pat, t, _) -> walkPat pat |> Option.orElseWith (fun () -> walkType t) + | SynPat.Attrib(pat, Attributes attrs, _) -> walkPat pat |> Option.orElseWith (fun () -> List.tryPick walkAttribute attrs) + | SynPat.Or(pat1, pat2, _) -> List.tryPick walkPat [pat1; pat2] + | SynPat.LongIdent(_, _, typars, ConstructorPats pats, _, r) -> + ifPosInRange r (fun _ -> kind) + |> Option.orElseWith (fun () -> + typars + |> Option.bind (fun (ValTyparDecls (typars, constraints, _)) -> + List.tryPick walkTyparDecl typars + |> Option.orElseWith (fun () -> List.tryPick walkTypeConstraint constraints))) + |> Option.orElseWith (fun () -> List.tryPick walkPat pats) + | SynPat.Tuple(_, pats, _) -> List.tryPick walkPat pats + | SynPat.Paren(pat, _) -> walkPat pat + | SynPat.ArrayOrList(_, pats, _) -> List.tryPick walkPat pats + | SynPat.IsInst(t, _) -> walkType t + | SynPat.QuoteExpr(e, _) -> walkExpr e + | _ -> None + + and walkPat = walkPatWithKind None + + and walkBinding (SynBinding(_, _, _, _, Attributes attrs, _, _, pat, returnInfo, e, _, _)) = + List.tryPick walkAttribute attrs + |> Option.orElseWith (fun () -> walkPat pat) + |> Option.orElseWith (fun () -> walkExpr e) + |> Option.orElseWith (fun () -> + match returnInfo with + | Some (SynBindingReturnInfo (t, _, _)) -> walkType t + | None -> None) + + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, _)) = + List.tryPick walkBinding bindings + + and walkType = function + | SynType.LongIdent ident -> + // we protect it with try..with because System.Exception : rangeOfLidwd may raise + // at FSharp.Compiler.Syntax.LongIdentWithDots.get_Range() in D:\j\workspace\release_ci_pa---3f142ccc\src\fsharp\ast.fs: line 156 + try ifPosInRange ident.Range (fun _ -> Some EntityKind.Type) with _ -> None + | SynType.App(ty, _, types, _, _, _, _) -> + walkType ty |> Option.orElseWith (fun () -> List.tryPick walkType types) + | SynType.LongIdentApp(_, _, _, types, _, _, _) -> List.tryPick walkType types + | SynType.Tuple(_, ts, _) -> ts |> List.tryPick (fun (_, t) -> walkType t) + | SynType.Array(_, t, _) -> walkType t + | SynType.Fun(t1, t2, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2) + | SynType.WithGlobalConstraints(t, _, _) -> walkType t + | SynType.HashConstraint(t, _) -> walkType t + | SynType.MeasureDivide(t1, t2, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2) + | SynType.MeasurePower(t, _, _) -> walkType t + | SynType.Paren(t, _) -> walkType t + | _ -> None + + and walkClause (SynMatchClause(pat, e1, _, e2, _, _)) = + walkPatWithKind (Some EntityKind.Type) pat + |> Option.orElseWith (fun () -> walkExpr e2) + |> Option.orElseWith (fun () -> Option.bind walkExpr e1) + + and walkExprWithKind (parentKind: EntityKind option) = function + | SynExpr.LongIdent (_, LongIdentWithDots(_, dotRanges), _, r) -> + match dotRanges with + | [] when isPosInRange r -> parentKind |> Option.orElseWith (fun () -> Some (EntityKind.FunctionOrValue false)) + | firstDotRange :: _ -> + let firstPartRange = + mkRange "" r.Start (mkPos firstDotRange.StartLine (firstDotRange.StartColumn - 1)) + if isPosInRange firstPartRange then + parentKind |> Option.orElseWith (fun () -> Some (EntityKind.FunctionOrValue false)) + else None + | _ -> None + | SynExpr.Paren (e, _, _, _) -> walkExprWithKind parentKind e + | SynExpr.Quote (_, _, e, _, _) -> walkExprWithKind parentKind e + | SynExpr.Typed (e, _, _) -> walkExprWithKind parentKind e + | SynExpr.Tuple (_, es, _, _) -> List.tryPick (walkExprWithKind parentKind) es + | SynExpr.ArrayOrList (_, es, _) -> List.tryPick (walkExprWithKind parentKind) es + | SynExpr.Record (_, _, fields, r) -> + ifPosInRange r (fun _ -> + fields |> List.tryPick (fun (_, e, _) -> e |> Option.bind (walkExprWithKind parentKind))) + | SynExpr.New (_, t, e, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkType t) + | SynExpr.ObjExpr (ty, _, bindings, ifaces, _, _) -> + walkType ty + |> Option.orElseWith (fun () -> List.tryPick walkBinding bindings) + |> Option.orElseWith (fun () -> List.tryPick walkInterfaceImpl ifaces) + | SynExpr.While (_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.For (_, _, e1, _, e2, e3, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2; e3] + | SynExpr.ForEach (_, _, _, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.ArrayOrListComputed (_, e, _) -> walkExprWithKind parentKind e + | SynExpr.ComputationExpr (_, e, _) -> walkExprWithKind parentKind e + | SynExpr.Lambda (body = e) -> walkExprWithKind parentKind e + | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> + List.tryPick walkClause synMatchClauseList + | SynExpr.Match (_, e, synMatchClauseList, _) -> + walkExprWithKind parentKind e |> Option.orElseWith (fun () -> List.tryPick walkClause synMatchClauseList) + | SynExpr.Do (e, _) -> walkExprWithKind parentKind e + | SynExpr.Assert (e, _) -> walkExprWithKind parentKind e + | SynExpr.App (_, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.TypeApp (e, _, tys, _, _, _, _) -> + walkExprWithKind (Some EntityKind.Type) e |> Option.orElseWith (fun () -> List.tryPick walkType tys) + | SynExpr.LetOrUse (_, _, bindings, e, _) -> List.tryPick walkBinding bindings |> Option.orElseWith (fun () -> walkExprWithKind parentKind e) + | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> List.tryPick walkClause clauses) + | SynExpr.TryFinally (e1, e2, _, _, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.Lazy (e, _) -> walkExprWithKind parentKind e + | Sequentials es -> List.tryPick (walkExprWithKind parentKind) es + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, _) -> + List.tryPick (walkExprWithKind parentKind) [e1; e2] |> Option.orElseWith (fun () -> match e3 with None -> None | Some e -> walkExprWithKind parentKind e) + | SynExpr.Ident ident -> ifPosInRange ident.idRange (fun _ -> Some (EntityKind.FunctionOrValue false)) + | SynExpr.LongIdentSet (_, e, _) -> walkExprWithKind parentKind e + | SynExpr.DotGet (e, _, _, _) -> walkExprWithKind parentKind e + | SynExpr.DotSet (e, _, _, _) -> walkExprWithKind parentKind e + | SynExpr.Set (e, _, _) -> walkExprWithKind parentKind e + | SynExpr.DotIndexedGet (e, args, _, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkExprWithKind parentKind args) + | SynExpr.DotIndexedSet (e, args, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkExprWithKind parentKind args) + | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2; e3] + | SynExpr.TypeTest (e, t, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkType t) + | SynExpr.Upcast (e, t, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkType t) + | SynExpr.Downcast (e, t, _) -> walkExprWithKind parentKind e |> Option.orElseWith (fun () -> walkType t) + | SynExpr.InferredUpcast (e, _) -> walkExprWithKind parentKind e + | SynExpr.InferredDowncast (e, _) -> walkExprWithKind parentKind e + | SynExpr.AddressOf (_, e, _, _) -> walkExprWithKind parentKind e + | SynExpr.JoinIn (e1, _, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] + | SynExpr.YieldOrReturn (_, e, _) -> walkExprWithKind parentKind e + | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExprWithKind parentKind e + | SynExpr.Match (_, e, synMatchClauseList, _) + | SynExpr.MatchBang (_, e, synMatchClauseList, _) -> + walkExprWithKind parentKind e |> Option.orElseWith (fun () -> List.tryPick walkClause synMatchClauseList) + | SynExpr.LetOrUseBang(_, _, _, _, e1, es, e2, _) -> + [ + yield e1 + for _,_,_,_,eAndBang,_ in es do + yield eAndBang + yield e2 + ] + |> List.tryPick (walkExprWithKind parentKind) + | SynExpr.DoBang (e, _) -> walkExprWithKind parentKind e + | SynExpr.TraitCall (ts, sign, e, _) -> + List.tryPick walkTypar ts + |> Option.orElseWith (fun () -> walkMemberSig sign) + |> Option.orElseWith (fun () -> walkExprWithKind parentKind e) + | _ -> None + + and walkExpr = walkExprWithKind None + + and walkSimplePat = function + | SynSimplePat.Attrib (pat, Attributes attrs, _) -> + walkSimplePat pat |> Option.orElseWith (fun () -> List.tryPick walkAttribute attrs) + | SynSimplePat.Typed(pat, t, _) -> walkSimplePat pat |> Option.orElseWith (fun () -> walkType t) + | _ -> None + + and walkField (SynField(Attributes attrs, _, _, t, _, _, _, _)) = + List.tryPick walkAttribute attrs |> Option.orElseWith (fun () -> walkType t) + + and walkValSig (SynValSig(Attributes attrs, _, _, t, _, _, _, _, _, _, _)) = + List.tryPick walkAttribute attrs |> Option.orElseWith (fun () -> walkType t) + + and walkMemberSig = function + | SynMemberSig.Inherit (t, _) -> walkType t + | SynMemberSig.Member(vs, _, _) -> walkValSig vs + | SynMemberSig.Interface(t, _) -> walkType t + | SynMemberSig.ValField(f, _) -> walkField f + | SynMemberSig.NestedType(SynTypeDefnSig.SynTypeDefnSig (info, repr, memberSigs, _), _) -> + walkComponentInfo false info + |> Option.orElseWith (fun () -> walkTypeDefnSigRepr repr) + |> Option.orElseWith (fun () -> List.tryPick walkMemberSig memberSigs) + + and walkMember = function + | SynMemberDefn.AbstractSlot (valSig, _, _) -> walkValSig valSig + | SynMemberDefn.Member(binding, _) -> walkBinding binding + | SynMemberDefn.ImplicitCtor(_, Attributes attrs, SynSimplePats.SimplePats(simplePats, _), _, _, _) -> + List.tryPick walkAttribute attrs |> Option.orElseWith (fun () -> List.tryPick walkSimplePat simplePats) + | SynMemberDefn.ImplicitInherit(t, e, _, _) -> walkType t |> Option.orElseWith (fun () -> walkExpr e) + | SynMemberDefn.LetBindings(bindings, _, _, _) -> List.tryPick walkBinding bindings + | SynMemberDefn.Interface(t, members, _) -> + walkType t |> Option.orElseWith (fun () -> members |> Option.bind (List.tryPick walkMember)) + | SynMemberDefn.Inherit(t, _, _) -> walkType t + | SynMemberDefn.ValField(field, _) -> walkField field + | SynMemberDefn.NestedType(tdef, _, _) -> walkTypeDefn tdef + | SynMemberDefn.AutoProperty(Attributes attrs, _, _, t, _, _, _, _, e, _, _) -> + List.tryPick walkAttribute attrs + |> Option.orElseWith (fun () -> Option.bind walkType t) + |> Option.orElseWith (fun () -> walkExpr e) + | _ -> None + + and walkEnumCase (SynEnumCase(Attributes attrs, _, _, _, _, _)) = List.tryPick walkAttribute attrs + + and walkUnionCaseType = function + | SynUnionCaseKind.Fields fields -> List.tryPick walkField fields + | SynUnionCaseKind.FullType(t, _) -> walkType t + + and walkUnionCase (SynUnionCase(Attributes attrs, _, t, _, _, _)) = + List.tryPick walkAttribute attrs |> Option.orElseWith (fun () -> walkUnionCaseType t) + + and walkTypeDefnSimple = function + | SynTypeDefnSimpleRepr.Enum (cases, _) -> List.tryPick walkEnumCase cases + | SynTypeDefnSimpleRepr.Union(_, cases, _) -> List.tryPick walkUnionCase cases + | SynTypeDefnSimpleRepr.Record(_, fields, _) -> List.tryPick walkField fields + | SynTypeDefnSimpleRepr.TypeAbbrev(_, t, _) -> walkType t + | _ -> None + + and walkComponentInfo isModule (SynComponentInfo(Attributes attrs, TyparsAndConstraints (typars, cs1), cs2, _, _, _, _, r)) = + let constraints = cs1 @ cs2 + if isModule then None else ifPosInRange r (fun _ -> Some EntityKind.Type) + |> Option.orElseWith (fun () -> + List.tryPick walkAttribute attrs + |> Option.orElseWith (fun () -> List.tryPick walkTyparDecl typars) + |> Option.orElseWith (fun () -> List.tryPick walkTypeConstraint constraints)) + + and walkTypeDefnRepr = function + | SynTypeDefnRepr.ObjectModel (_, defns, _) -> List.tryPick walkMember defns + | SynTypeDefnRepr.Simple(defn, _) -> walkTypeDefnSimple defn + | SynTypeDefnRepr.Exception _ -> None + + and walkTypeDefnSigRepr = function + | SynTypeDefnSigRepr.ObjectModel (_, defns, _) -> List.tryPick walkMemberSig defns + | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn + | SynTypeDefnSigRepr.Exception _ -> None + + and walkTypeDefn (SynTypeDefn (info, repr, members, _, _)) = + walkComponentInfo false info + |> Option.orElseWith (fun () -> walkTypeDefnRepr repr) + |> Option.orElseWith (fun () -> List.tryPick walkMember members) + + and walkSynModuleDecl isTopLevel (decl: SynModuleDecl) = + match decl with + | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace isTopLevel fragment + | SynModuleDecl.NestedModule(info, _, modules, _, range) -> + walkComponentInfo true info + |> Option.orElseWith (fun () -> ifPosInRange range (fun _ -> List.tryPick (walkSynModuleDecl false) modules)) + | SynModuleDecl.Open _ -> None + | SynModuleDecl.Let (_, bindings, _) -> List.tryPick walkBinding bindings + | SynModuleDecl.DoExpr (_, expr, _) -> walkExpr expr + | SynModuleDecl.Types (types, _) -> List.tryPick walkTypeDefn types + | _ -> None + + match parsedInput with + | ParsedInput.SigFile _ -> None + | ParsedInput.ImplFile input -> walkImplFileInput input + + /// Matches the most nested [< and >] pair. + let insideAttributeApplicationRegex = Regex(@"(?<=\[\<)(?(.*?))(?=\>\])", RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) + + /// Try to determine completion context for the given pair (row, columns) + let TryGetCompletionContext (pos, parsedInput: ParsedInput, lineStr: string) : CompletionContext option = + + match GetEntityKind(pos, parsedInput) with + | Some EntityKind.Attribute -> Some CompletionContext.AttributeApplication + | _ -> + + let parseLid (LongIdentWithDots(lid, dots)) = + let rec collect plid (parts : Ident list) (dots : range list) = + match parts, dots with + | [], _ -> Some (plid, None) + | x :: xs, ds -> + if rangeContainsPos x.idRange pos then + // pos lies with the range of current identifier + let s = x.idText.Substring(0, pos.Column - x.idRange.Start.Column) + let residue = if s.Length <> 0 then Some s else None + Some (plid, residue) + elif posGt x.idRange.Start pos then + // can happen if caret is placed after dot but before the existing identifier A. $ B + // return accumulated plid with no residue + Some (plid, None) + else + match ds with + | [] -> + // pos lies after the id and no dots found - return accumulated plid and current id as residue + Some (plid, Some x.idText) + | d :: ds -> + if posGeq pos d.End then + // pos lies after the dot - proceed to the next identifier + collect (x.idText :: plid) xs ds + else + // pos after the id but before the dot + // A $.B - return nothing + None + + match collect [] lid dots with + | Some (parts, residue) -> + Some ((List.rev parts), residue) + | None -> None + + let (|Class|Interface|Struct|Unknown|Invalid|) synAttributes = + let (|SynAttr|_|) name (attr : SynAttribute) = + match attr with + | {TypeName = LongIdentWithDots([x], _)} when x.idText = name -> Some () + | _ -> None + + let rec getKind isClass isInterface isStruct = + function + | [] -> isClass, isInterface, isStruct + | SynAttr "Class" :: xs -> getKind true isInterface isStruct xs + | SynAttr "AbstractClass" :: xs -> getKind true isInterface isStruct xs + | SynAttr "Interface" :: xs -> getKind isClass true isStruct xs + | SynAttr "Struct" :: xs -> getKind isClass isInterface true xs + | _ :: xs -> getKind isClass isInterface isStruct xs + + match getKind false false false synAttributes with + | false, false, false -> Unknown + | true, false, false -> Class + | false, true, false -> Interface + | false, false, true -> Struct + | _ -> Invalid + + let GetCompletionContextForInheritSynMember (SynComponentInfo(Attributes synAttributes, _, _, _, _, _, _, _), typeDefnKind : SynTypeDefnKind, completionPath) = + + let success k = Some (CompletionContext.Inherit (k, completionPath)) + + // if kind is specified - take it + // if kind is non-specified + // - try to obtain it from attribute + // - if no attributes present - infer kind from members + match typeDefnKind with + | SynTypeDefnKind.Class -> + match synAttributes with + | Class | Unknown -> success InheritanceContext.Class + | _ -> Some CompletionContext.Invalid // non-matching attributes + | SynTypeDefnKind.Interface -> + match synAttributes with + | Interface | Unknown -> success InheritanceContext.Interface + | _ -> Some CompletionContext.Invalid // non-matching attributes + | SynTypeDefnKind.Struct -> + // display nothing for structs + Some CompletionContext.Invalid + | SynTypeDefnKind.Unspecified -> + match synAttributes with + | Class -> success InheritanceContext.Class + | Interface -> success InheritanceContext.Interface + | Unknown -> + // user do not specify kind explicitly or via attributes + success InheritanceContext.Unknown + | _ -> + // unable to uniquely detect kind from the attributes - return invalid context + Some CompletionContext.Invalid + | _ -> None + + let (|Operator|_|) name e = + match e with + | SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident ident, lhs, _), rhs, _) + when ident.idText = name -> Some (lhs, rhs) + | _ -> None + + // checks if we are in a range operator + let isAtRangeOp (p : SyntaxVisitorPath) = + match p with + | SyntaxNode.SynExpr(SynExpr.IndexRange _) :: _ -> true + | _ -> false + + let (|Setter|_|) e = + match e with + | Operator "op_Equality" (SynExpr.Ident id, _) -> Some id + | _ -> None + + let findSetters argList = + match argList with + | SynExpr.Paren (SynExpr.Tuple (false, parameters, _, _), _, _, _) -> + let setters = HashSet() + for p in parameters do + match p with + | Setter id -> ignore(setters.Add id.idText) + | _ -> () + setters + | _ -> emptyStringSet + + let endOfLastIdent (lid: LongIdentWithDots) = + let last = List.last lid.Lid + last.idRange.End + + let endOfClosingTokenOrLastIdent (mClosing: range option) (lid : LongIdentWithDots) = + match mClosing with + | Some m -> m.End + | None -> endOfLastIdent lid + + let endOfClosingTokenOrIdent (mClosing: range option) (id : Ident) = + match mClosing with + | Some m -> m.End + | None -> id.idRange.End + + let (|NewObjectOrMethodCall|_|) e = + match e with + | SynExpr.New (_, SynType.LongIdent typeName, arg, _) -> + // new A() + Some (endOfLastIdent typeName, findSetters arg) + | SynExpr.New (_, SynType.App(StripParenTypes (SynType.LongIdent typeName), _, _, _, mGreaterThan, _, _), arg, _) -> + // new A<_>() + Some (endOfClosingTokenOrLastIdent mGreaterThan typeName, findSetters arg) + | SynExpr.App (_, false, SynExpr.Ident id, arg, _) -> + // A() + Some (id.idRange.End, findSetters arg) + | SynExpr.App (_, false, SynExpr.TypeApp (SynExpr.Ident id, _, _, _, mGreaterThan, _, _), arg, _) -> + // A<_>() + Some (endOfClosingTokenOrIdent mGreaterThan id, findSetters arg) + | SynExpr.App (_, false, SynExpr.LongIdent (_, lid, _, _), arg, _) -> + // A.B() + Some (endOfLastIdent lid, findSetters arg) + | SynExpr.App (_, false, SynExpr.TypeApp (SynExpr.LongIdent (_, lid, _, _), _, _, _, mGreaterThan, _, _), arg, _) -> + // A.B<_>() + Some (endOfClosingTokenOrLastIdent mGreaterThan lid, findSetters arg) + | _ -> None + + let isOnTheRightOfComma (elements: SynExpr list) (commas: range list) current = + let rec loop elements (commas: range list) = + match elements with + | x :: xs -> + match commas with + | c :: cs -> + if x === current then posLt c.End pos || posEq c.End pos + else loop xs cs + | _ -> false + | _ -> false + loop elements commas + + let (|PartOfParameterList|_|) precedingArgument path = + match path with + | SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(NewObjectOrMethodCall args) :: _ -> + if Option.isSome precedingArgument then None else Some args + | SyntaxNode.SynExpr(SynExpr.Tuple (false, elements, commas, _)) :: SyntaxNode.SynExpr(SynExpr.Paren _) :: SyntaxNode.SynExpr(NewObjectOrMethodCall args) :: _ -> + match precedingArgument with + | None -> Some args + | Some e -> + // if expression is passed then + // 1. find it in among elements of the tuple + // 2. find corresponding comma + // 3. check that current position is past the comma + // this is used for cases like (a = something-here.) if the cursor is after . + // in this case this is not object initializer completion context + if isOnTheRightOfComma elements commas e then Some args else None + | _ -> None + + let (|SkipFromParseErrorPat|) pat = + match pat with + | SynPat.FromParseError(pat, _) -> pat + | _ -> pat + + let walker = + { + new SyntaxVisitorBase<_>() with + member _.VisitExpr(path, _, defaultTraverse, expr) = + + if isAtRangeOp path then + match defaultTraverse expr with + | None -> Some CompletionContext.RangeOperator // nothing was found - report that we were in the context of range operator + | x -> x // ok, we found something - return it + else + match expr with + // new A($) + | SynExpr.Const (SynConst.Unit, m) when rangeContainsPos m pos -> + match path with + | SyntaxNode.SynExpr(NewObjectOrMethodCall args) :: _ -> + Some (CompletionContext.ParameterList args) + | _ -> + defaultTraverse expr + // new (... A$) + | SynExpr.Ident id when id.idRange.End = pos -> + match path with + | PartOfParameterList None args -> + Some (CompletionContext.ParameterList args) + | _ -> + defaultTraverse expr + // new (A$ = 1) + // new (A = 1, $) + | Setter id when id.idRange.End = pos || rangeBeforePos expr.Range pos -> + let precedingArgument = if id.idRange.End = pos then None else Some expr + match path with + | PartOfParameterList precedingArgument args-> + Some (CompletionContext.ParameterList args) + | _ -> + defaultTraverse expr + + | _ -> defaultTraverse expr + + member _.VisitRecordField(path, copyOpt, field) = + let contextFromTreePath completionPath = + // detect records usage in constructor + match path with + | SyntaxNode.SynExpr _ :: SyntaxNode.SynBinding _ :: SyntaxNode.SynMemberDefn _ :: SyntaxNode.SynTypeDefn(SynTypeDefn(SynComponentInfo(_, _, _, [id], _, _, _, _), _, _, _, _)) :: _ -> + RecordContext.Constructor(id.idText) + | _ -> RecordContext.New completionPath + match field with + | Some field -> + match parseLid field with + | Some completionPath -> + let recordContext = + match copyOpt with + | Some (s : SynExpr) -> RecordContext.CopyOnUpdate(s.Range, completionPath) + | None -> contextFromTreePath completionPath + Some (CompletionContext.RecordField recordContext) + | None -> None + | None -> + let recordContext = + match copyOpt with + | Some s -> RecordContext.CopyOnUpdate(s.Range, ([], None)) + | None -> contextFromTreePath ([], None) + Some (CompletionContext.RecordField recordContext) + + member _.VisitInheritSynMemberDefn(_path, componentInfo, typeDefnKind, synType, _members, _range) = + match synType with + | SynType.LongIdent lidwd -> + match parseLid lidwd with + | Some completionPath -> GetCompletionContextForInheritSynMember (componentInfo, typeDefnKind, completionPath) + | None -> Some CompletionContext.Invalid // A $ .B -> no completion list + + | _ -> None + + member _.VisitBinding(_path, defaultTraverse, (SynBinding(headPat = headPat) as synBinding)) = + + let visitParam (SkipFromParseErrorPat pat) = + match pat with + | SynPat.Named (range = range) + | SynPat.As (_, SynPat.Named (range = range), _) when rangeContainsPos range pos -> + // parameter without type hint, no completion + Some CompletionContext.Invalid + | SynPat.Typed(SynPat.Named(_, _, _, range), _, _) when rangeContainsPos range pos -> + // parameter with type hint, but we are on its name, no completion + Some CompletionContext.Invalid + | _ -> defaultTraverse synBinding + + match headPat with + | SynPat.LongIdent(longDotId = lidwd) when rangeContainsPos lidwd.Range pos -> + // let fo|o x = () + Some CompletionContext.Invalid + | SynPat.LongIdent(_, _, _, ctorArgs, _, _) -> + match ctorArgs with + | SynArgPats.Pats pats -> + pats |> List.tryPick (fun (SkipFromParseErrorPat pat) -> + match pat with + | SynPat.Paren(pat, _) -> + match pat with + | SynPat.Tuple(_, pats, _) -> + pats |> List.tryPick visitParam + | _ -> visitParam pat + | SynPat.Wild range | SynPat.FromParseError (SynPat.Named _, range) when rangeContainsPos range pos -> + // let foo (x| + Some CompletionContext.Invalid + | _ -> visitParam pat + ) + | _ -> defaultTraverse synBinding + | SynPat.Named(range = range) + | SynPat.As (_, SynPat.Named (range = range), _) when rangeContainsPos range pos -> + // let fo|o = 1 + Some CompletionContext.Invalid + | _ -> defaultTraverse synBinding + + member _.VisitHashDirective (_path, _directive, range) = + if rangeContainsPos range pos then Some CompletionContext.Invalid + else None + + member _.VisitModuleOrNamespace(_path, SynModuleOrNamespace(longId = idents)) = + match List.tryLast idents with + | Some lastIdent when pos.Line = lastIdent.idRange.EndLine && lastIdent.idRange.EndColumn >= 0 && pos.Column <= lineStr.Length -> + let stringBetweenModuleNameAndPos = lineStr.[lastIdent.idRange.EndColumn..pos.Column - 1] + if stringBetweenModuleNameAndPos |> Seq.forall (fun x -> x = ' ' || x = '.') then + Some CompletionContext.Invalid + else None + | _ -> None + + member _.VisitComponentInfo(_path, SynComponentInfo(range = range)) = + if rangeContainsPos range pos then Some CompletionContext.Invalid + else None + + member _.VisitLetOrUse(_path, _, _, bindings, range) = + match bindings with + | [] when range.StartLine = pos.Line -> Some CompletionContext.Invalid + | _ -> None + + member _.VisitSimplePats (_path, pats) = + pats |> List.tryPick (fun pat -> + match pat with + | SynSimplePat.Id(range = range) + | SynSimplePat.Typed(SynSimplePat.Id(range = range), _, _) when rangeContainsPos range pos -> + Some CompletionContext.Invalid + | _ -> None) + + member _.VisitModuleDecl(_path, defaultTraverse, decl) = + match decl with + | SynModuleDecl.Open(target, m) -> + // in theory, this means we're "in an open" + // in practice, because the parse tree/walkers do not handle attributes well yet, need extra check below to ensure not e.g. $here$ + // open System + // [ true + | SynOpenDeclTarget.ModuleOrNamespace _ -> false + Some (CompletionContext.OpenDeclaration isOpenType) + else + None + | _ -> defaultTraverse decl + + member _.VisitType(_path, defaultTraverse, ty) = + match ty with + | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> + Some CompletionContext.PatternType + | _ -> defaultTraverse ty + } + + SyntaxTraversal.Traverse(pos, parsedInput, walker) + // Uncompleted attribute applications are not presented in the AST in any way. So, we have to parse source string. + |> Option.orElseWith (fun _ -> + let cutLeadingAttributes (str: string) = + // cut off leading attributes, i.e. we cut "[]" to " >]" + match str.LastIndexOf ';' with + | -1 -> str + | idx when idx < str.Length -> str.[idx + 1..].TrimStart() + | _ -> "" + + let isLongIdent = Seq.forall (fun c -> IsIdentifierPartCharacter c || c = '.' || c = ':') // ':' may occur in "[]" + + // match the most nested paired [< and >] first + let matches = + insideAttributeApplicationRegex.Matches lineStr + |> Seq.cast + |> Seq.filter (fun m -> m.Index <= pos.Column && m.Index + m.Length >= pos.Column) + |> Seq.toArray + + if not (Array.isEmpty matches) then + matches + |> Seq.tryPick (fun m -> + let g = m.Groups.["attribute"] + let col = pos.Column - g.Index + if col >= 0 && col < g.Length then + let str = g.Value.Substring(0, col).TrimStart() // cut other rhs attributes + let str = cutLeadingAttributes str + if isLongIdent str then + Some CompletionContext.AttributeApplication + else None + else None) + else + // Paired [< and >] were not found, try to determine that we are after [< without closing >] + match lineStr.LastIndexOf("[<", StringComparison.Ordinal) with + | -1 -> None + | openParenIndex when pos.Column >= openParenIndex + 2 -> + let str = lineStr.[openParenIndex + 2..pos.Column - 1].TrimStart() + let str = cutLeadingAttributes str + if isLongIdent str then + Some CompletionContext.AttributeApplication + else None + | _ -> None) + + /// Check if we are at an "open" declaration + let GetFullNameOfSmallestModuleOrNamespaceAtPoint (pos: pos, parsedInput: ParsedInput) = + let mutable path = [] + let visitor = + { new SyntaxVisitorBase() with + override this.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = + // don't need to keep going, namespaces and modules never appear inside Exprs + None + override this.VisitModuleOrNamespace(_path, SynModuleOrNamespace(longId = longId; range = range)) = + if rangeContainsPos range pos then + path <- path @ longId + None // we should traverse the rest of the AST to find the smallest module + } + SyntaxTraversal.Traverse(pos, parsedInput, visitor) |> ignore + path |> List.map (fun x -> x.idText) |> List.toArray + + /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException + let rec (|Sequentials|_|) = function + | SynExpr.Sequential (_, _, e, Sequentials es, _) -> + Some(e :: es) + | SynExpr.Sequential (_, _, e1, e2, _) -> + Some [e1; e2] + | _ -> None + + let (|ConstructorPats|) = function + | SynArgPats.Pats ps -> ps + | SynArgPats.NamePatPairs(xs, _) -> List.map snd xs + + /// Returns all `Ident`s and `LongIdent`s found in an untyped AST. + let getLongIdents (parsedInput: ParsedInput) : IDictionary = + let identsByEndPos = Dictionary() + + let addLongIdent (longIdent: LongIdent) = + for ident in longIdent do + identsByEndPos.[ident.idRange.End] <- longIdent + + let addLongIdentWithDots (LongIdentWithDots (longIdent, lids) as value) = + match longIdent with + | [] -> () + | [_] as idents -> identsByEndPos.[value.Range.End] <- idents + | idents -> + for dotRange in lids do + identsByEndPos.[mkPos dotRange.EndLine (dotRange.EndColumn - 1)] <- idents + identsByEndPos.[value.Range.End] <- idents + + let addIdent (ident: Ident) = + identsByEndPos.[ident.idRange.End] <- [ident] + + let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = + List.iter walkSynModuleOrNamespace moduleOrNamespaceList + + and walkSynModuleOrNamespace (SynModuleOrNamespace(_, _, _, decls, _, Attributes attrs, _, _)) = + List.iter walkAttribute attrs + List.iter walkSynModuleDecl decls + + and walkAttribute (attr: SynAttribute) = + addLongIdentWithDots attr.TypeName + walkExpr attr.ArgExpr + + and walkTyparDecl (SynTyparDecl.SynTyparDecl (Attributes attrs, typar)) = + List.iter walkAttribute attrs + walkTypar typar + + and walkTypeConstraint = function + | SynTypeConstraint.WhereTyparIsValueType (t, _) + | SynTypeConstraint.WhereTyparIsReferenceType (t, _) + | SynTypeConstraint.WhereTyparIsUnmanaged (t, _) + | SynTypeConstraint.WhereTyparSupportsNull (t, _) + | SynTypeConstraint.WhereTyparIsComparable (t, _) + | SynTypeConstraint.WhereTyparIsEquatable (t, _) -> walkTypar t + | SynTypeConstraint.WhereTyparDefaultsToType (t, ty, _) + | SynTypeConstraint.WhereTyparSubtypeOfType (t, ty, _) -> walkTypar t; walkType ty + | SynTypeConstraint.WhereTyparIsEnum (t, ts, _) + | SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) -> walkTypar t; List.iter walkType ts + | SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) -> List.iter walkType ts; walkMemberSig sign + + and walkPat = function + | SynPat.Tuple (_,pats, _) + | SynPat.ArrayOrList (_, pats, _) + | SynPat.Ands (pats, _) -> List.iter walkPat pats + | SynPat.Named (ident, _, _, _) -> addIdent ident + | SynPat.Typed (pat, t, _) -> + walkPat pat + walkType t + | SynPat.Attrib (pat, Attributes attrs, _) -> + walkPat pat + List.iter walkAttribute attrs + | SynPat.As (pat1, pat2, _) + | SynPat.Or (pat1, pat2, _) -> List.iter walkPat [pat1; pat2] + | SynPat.LongIdent (ident, _, typars, ConstructorPats pats, _, _) -> + addLongIdentWithDots ident + typars + |> Option.iter (fun (ValTyparDecls (typars, constraints, _)) -> + List.iter walkTyparDecl typars + List.iter walkTypeConstraint constraints) + List.iter walkPat pats + | SynPat.Paren (pat, _) -> walkPat pat + | SynPat.IsInst (t, _) -> walkType t + | SynPat.QuoteExpr(e, _) -> walkExpr e + | _ -> () + + and walkTypar (SynTypar _) = () + + and walkBinding (SynBinding(_, _, _, _, Attributes attrs, _, _, pat, returnInfo, e, _, _)) = + List.iter walkAttribute attrs + walkPat pat + walkExpr e + returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t) + + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings + + and walkType = function + | SynType.Array (_, t, _) + | SynType.HashConstraint (t, _) + | SynType.MeasurePower (t, _, _) + | SynType.Paren (t, _) -> walkType t + | SynType.Fun (t1, t2, _) + | SynType.MeasureDivide (t1, t2, _) -> walkType t1; walkType t2 + | SynType.LongIdent ident -> addLongIdentWithDots ident + | SynType.App (ty, _, types, _, _, _, _) -> walkType ty; List.iter walkType types + | SynType.LongIdentApp (_, _, _, types, _, _, _) -> List.iter walkType types + | SynType.Tuple (_, ts, _) -> ts |> List.iter (fun (_, t) -> walkType t) + | SynType.WithGlobalConstraints (t, typeConstraints, _) -> + walkType t; List.iter walkTypeConstraint typeConstraints + | _ -> () + + and walkClause (SynMatchClause (pat, e1, _, e2, _, _)) = + walkPat pat + walkExpr e2 + e1 |> Option.iter walkExpr + + and walkSimplePats = function + | SynSimplePats.SimplePats (pats, _) -> List.iter walkSimplePat pats + | SynSimplePats.Typed (pats, ty, _) -> + walkSimplePats pats + walkType ty + + and walkExpr = function + | SynExpr.Paren (e, _, _, _) + | SynExpr.Quote (_, _, e, _, _) + | SynExpr.Typed (e, _, _) + | SynExpr.InferredUpcast (e, _) + | SynExpr.InferredDowncast (e, _) + | SynExpr.AddressOf (_, e, _, _) + | SynExpr.DoBang (e, _) + | SynExpr.YieldOrReturn (_, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) + | SynExpr.ComputationExpr (_, e, _) + | SynExpr.Do (e, _) + | SynExpr.Assert (e, _) + | SynExpr.Lazy (e, _) + | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExpr e + | SynExpr.Lambda (_, _, pats, _, e, _, _) -> + walkSimplePats pats + walkExpr e + | SynExpr.New (_, t, e, _) + | SynExpr.TypeTest (e, t, _) + | SynExpr.Upcast (e, t, _) + | SynExpr.Downcast (e, t, _) -> walkExpr e; walkType t + | SynExpr.Tuple (_, es, _, _) + | Sequentials es + | SynExpr.ArrayOrList (_, es, _) -> List.iter walkExpr es + | SynExpr.App (_, _, e1, e2, _) + | SynExpr.TryFinally (e1, e2, _, _, _) + | SynExpr.While (_, e1, e2, _) -> List.iter walkExpr [e1; e2] + | SynExpr.Record (_, _, fields, _) -> + fields |> List.iter (fun ((ident, _), e, _) -> + addLongIdentWithDots ident + e |> Option.iter walkExpr) + | SynExpr.Ident ident -> addIdent ident + | SynExpr.ObjExpr (ty, argOpt, bindings, ifaces, _, _) -> + argOpt |> Option.iter (fun (e, ident) -> + walkExpr e + ident |> Option.iter addIdent) + walkType ty + List.iter walkBinding bindings + List.iter walkInterfaceImpl ifaces + | SynExpr.LongIdent (_, ident, _, _) -> addLongIdentWithDots ident + | SynExpr.For (_, ident, e1, _, e2, e3, _) -> + addIdent ident + List.iter walkExpr [e1; e2; e3] + | SynExpr.ForEach (_, _, _, pat, e1, e2, _) -> + walkPat pat + List.iter walkExpr [e1; e2] + | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> + List.iter walkClause synMatchClauseList + | SynExpr.Match (_, e, synMatchClauseList, _) -> + walkExpr e + List.iter walkClause synMatchClauseList + | SynExpr.TypeApp (e, _, tys, _, _, _, _) -> + List.iter walkType tys; walkExpr e + | SynExpr.LetOrUse (_, _, bindings, e, _) -> + List.iter walkBinding bindings; walkExpr e + | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> + List.iter walkClause clauses; walkExpr e + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, _) -> + List.iter walkExpr [e1; e2] + e3 |> Option.iter walkExpr + | SynExpr.LongIdentSet (ident, e, _) + | SynExpr.DotGet (e, _, ident, _) -> + addLongIdentWithDots ident + walkExpr e + | SynExpr.DotSet (e1, idents, e2, _) -> + walkExpr e1 + addLongIdentWithDots idents + walkExpr e2 + | SynExpr.Set (e1, e2, _) -> + walkExpr e1 + walkExpr e2 + | SynExpr.IndexRange (expr1, _, expr2, _, _, _) -> + match expr1 with Some e -> walkExpr e | None -> () + match expr2 with Some e -> walkExpr e | None -> () + | SynExpr.IndexFromEnd (e, _) -> + walkExpr e + | SynExpr.DotIndexedGet (e, args, _, _) -> + walkExpr e + walkExpr args + | SynExpr.DotIndexedSet (e1, args, e2, _, _, _) -> + walkExpr e1 + walkExpr args + walkExpr e2 + | SynExpr.NamedIndexedPropertySet (ident, e1, e2, _) -> + addLongIdentWithDots ident + List.iter walkExpr [e1; e2] + | SynExpr.DotNamedIndexedPropertySet (e1, ident, e2, e3, _) -> + addLongIdentWithDots ident + List.iter walkExpr [e1; e2; e3] + | SynExpr.JoinIn (e1, _, e2, _) -> List.iter walkExpr [e1; e2] + | SynExpr.LetOrUseBang (_, _, _, pat, e1, es, e2, _) -> + walkPat pat + walkExpr e1 + for _,_,_,patAndBang,eAndBang,_ in es do + walkPat patAndBang + walkExpr eAndBang + walkExpr e2 + | SynExpr.TraitCall (ts, sign, e, _) -> + List.iter walkTypar ts + walkMemberSig sign + walkExpr e + | SynExpr.Const (SynConst.Measure(_, _, m), _) -> walkMeasure m + | _ -> () + + and walkMeasure = function + | SynMeasure.Product (m1, m2, _) + | SynMeasure.Divide (m1, m2, _) -> walkMeasure m1; walkMeasure m2 + | SynMeasure.Named (longIdent, _) -> addLongIdent longIdent + | SynMeasure.Seq (ms, _) -> List.iter walkMeasure ms + | SynMeasure.Power (m, _, _) -> walkMeasure m + | SynMeasure.Var (ty, _) -> walkTypar ty + | SynMeasure.One + | SynMeasure.Anon _ -> () + + and walkSimplePat = function + | SynSimplePat.Attrib (pat, Attributes attrs, _) -> + walkSimplePat pat + List.iter walkAttribute attrs + | SynSimplePat.Typed(pat, t, _) -> + walkSimplePat pat + walkType t + | _ -> () + + and walkField (SynField(Attributes attrs, _, _, t, _, _, _, _)) = + List.iter walkAttribute attrs + walkType t + + and walkValSig (SynValSig(Attributes attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = + List.iter walkAttribute attrs + walkType t + argInfo :: (argInfos |> List.concat) + |> List.collect (fun (SynArgInfo(Attributes attrs, _, _)) -> attrs) + |> List.iter walkAttribute + + and walkMemberSig = function + | SynMemberSig.Inherit (t, _) + | SynMemberSig.Interface(t, _) -> walkType t + | SynMemberSig.Member(vs, _, _) -> walkValSig vs + | SynMemberSig.ValField(f, _) -> walkField f + | SynMemberSig.NestedType(SynTypeDefnSig.SynTypeDefnSig (info, repr, memberSigs, _), _) -> + let isTypeExtensionOrAlias = + match repr with + | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev _, _) + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Abbrev, _, _) + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Augmentation, _, _) -> true + | _ -> false + walkComponentInfo isTypeExtensionOrAlias info + walkTypeDefnSigRepr repr + List.iter walkMemberSig memberSigs + + and walkMember memb = + match memb with + | SynMemberDefn.AbstractSlot (valSig, _, _) -> walkValSig valSig + | SynMemberDefn.Member (binding, _) -> walkBinding binding + | SynMemberDefn.ImplicitCtor (_, Attributes attrs, SynSimplePats.SimplePats(simplePats, _), _, _, _) -> + List.iter walkAttribute attrs + List.iter walkSimplePat simplePats + | SynMemberDefn.ImplicitInherit (t, e, _, _) -> walkType t; walkExpr e + | SynMemberDefn.LetBindings (bindings, _, _, _) -> List.iter walkBinding bindings + | SynMemberDefn.Interface (t, members, _) -> + walkType t + members |> Option.iter (List.iter walkMember) + | SynMemberDefn.Inherit (t, _, _) -> walkType t + | SynMemberDefn.ValField (field, _) -> walkField field + | SynMemberDefn.NestedType (tdef, _, _) -> walkTypeDefn tdef + | SynMemberDefn.AutoProperty (Attributes attrs, _, _, t, _, _, _, _, e, _, _) -> + List.iter walkAttribute attrs + Option.iter walkType t + walkExpr e + | _ -> () + + and walkEnumCase (SynEnumCase(Attributes attrs, _, _, _, _, _)) = List.iter walkAttribute attrs + + and walkUnionCaseType = function + | SynUnionCaseKind.Fields fields -> List.iter walkField fields + | SynUnionCaseKind.FullType (t, _) -> walkType t + + and walkUnionCase (SynUnionCase(Attributes attrs, _, t, _, _, _)) = + List.iter walkAttribute attrs + walkUnionCaseType t + + and walkTypeDefnSimple = function + | SynTypeDefnSimpleRepr.Enum (cases, _) -> List.iter walkEnumCase cases + | SynTypeDefnSimpleRepr.Union (_, cases, _) -> List.iter walkUnionCase cases + | SynTypeDefnSimpleRepr.Record (_, fields, _) -> List.iter walkField fields + | SynTypeDefnSimpleRepr.TypeAbbrev (_, t, _) -> walkType t + | _ -> () + + and walkComponentInfo isTypeExtensionOrAlias (SynComponentInfo(Attributes attrs, TyparsAndConstraints (typars, cs1), cs2, longIdent, _, _, _, _)) = + let constraints = cs1 @ cs2 + List.iter walkAttribute attrs + List.iter walkTyparDecl typars + List.iter walkTypeConstraint constraints + if isTypeExtensionOrAlias then + addLongIdent longIdent + + and walkTypeDefnRepr = function + | SynTypeDefnRepr.ObjectModel (_, defns, _) -> List.iter walkMember defns + | SynTypeDefnRepr.Simple(defn, _) -> walkTypeDefnSimple defn + | SynTypeDefnRepr.Exception _ -> () + + and walkTypeDefnSigRepr = function + | SynTypeDefnSigRepr.ObjectModel (_, defns, _) -> List.iter walkMemberSig defns + | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn + | SynTypeDefnSigRepr.Exception _ -> () + + and walkTypeDefn (SynTypeDefn (info, repr, members, implicitCtor, _)) = + let isTypeExtensionOrAlias = + match repr with + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Augmentation, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Abbrev, _, _) + | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.TypeAbbrev _, _) -> true + | _ -> false + walkComponentInfo isTypeExtensionOrAlias info + walkTypeDefnRepr repr + List.iter walkMember members + Option.iter walkMember implicitCtor + + and walkSynModuleDecl (decl: SynModuleDecl) = + match decl with + | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace fragment + | SynModuleDecl.NestedModule (info, _, modules, _, _) -> + walkComponentInfo false info + List.iter walkSynModuleDecl modules + | SynModuleDecl.Let (_, bindings, _) -> List.iter walkBinding bindings + | SynModuleDecl.DoExpr (_, expr, _) -> walkExpr expr + | SynModuleDecl.Types (types, _) -> List.iter walkTypeDefn types + | SynModuleDecl.Attributes (Attributes attrs, _) -> List.iter walkAttribute attrs + | _ -> () + + match parsedInput with + | ParsedInput.ImplFile input -> + walkImplFileInput input + | _ -> () + //debug "%A" idents + upcast identsByEndPos + + let GetLongIdentAt parsedInput pos = + let idents = getLongIdents parsedInput + match idents.TryGetValue pos with + | true, idents -> Some idents + | _ -> None + + type Scope = + { ShortIdents: ShortIdents + Kind: ScopeKind } + + let tryFindNearestPointAndModules (currentLine: int) (ast: ParsedInput) (insertionPoint: OpenStatementInsertionPoint) = + // We ignore all diagnostics during this operation + // + // Based on an initial review, no diagnostics should be generated. However the code should be checked more closely. + use _ignoreAllDiagnostics = new ErrorScope() + + let mutable result = None + let mutable ns = None + let modules = ResizeArray() + + let inline longIdentToIdents ident = ident |> Seq.map string |> Seq.toArray + + let addModule (longIdent: LongIdent, range: range) = + modules.Add + { Idents = longIdentToIdents longIdent + Range = range } + + let doRange kind (scope: LongIdent) line col = + if line <= currentLine then + match result, insertionPoint with + | None, _ -> + result <- Some ({ ShortIdents = longIdentToIdents scope; Kind = kind }, mkPos line col, false) + | Some (_, _, true), _ -> () + | Some (oldScope, oldPos, false), OpenStatementInsertionPoint.TopLevel when kind <> OpenDeclaration -> + result <- Some (oldScope, oldPos, true) + | Some (oldScope, oldPos, _), _ -> + match kind, oldScope.Kind with + | (Namespace | NestedModule | TopModule), OpenDeclaration + | _ when oldPos.Line <= line -> + result <- + Some ({ ShortIdents = + match scope with + | [] -> oldScope.ShortIdents + | _ -> longIdentToIdents scope + Kind = kind }, + mkPos line col, + false) + | _ -> () + + let getMinColumn decls = + match decls with + | [] -> None + | firstDecl :: _ -> + match firstDecl with + | SynModuleDecl.NestedModule (_, _, _, _, r) + | SynModuleDecl.Let (_, _, r) + | SynModuleDecl.DoExpr (_, _, r) + | SynModuleDecl.Types (_, r) + | SynModuleDecl.Exception (_, r) + | SynModuleDecl.Open (_, r) + | SynModuleDecl.HashDirective (_, r) -> Some r + | _ -> None + |> Option.map (fun r -> r.StartColumn) + + + let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = + List.iter (walkSynModuleOrNamespace []) moduleOrNamespaceList + + and walkSynModuleOrNamespace (parent: LongIdent) (SynModuleOrNamespace(ident, _, kind, decls, _, _, _, range)) = + if range.EndLine >= currentLine then + let isModule = kind.IsModule + match isModule, parent, ident with + | false, _, _ -> ns <- Some (longIdentToIdents ident) + // top level module with "inlined" namespace like Ns1.Ns2.TopModule + | true, [], _f :: _s :: _ -> + let ident = longIdentToIdents ident + ns <- Some ident.[0..ident.Length - 2] + | _ -> () + + let fullIdent = parent @ ident + + let startLine = + if isModule then range.StartLine + else range.StartLine - 1 + + let scopeKind = + match isModule, parent with + | true, [] -> TopModule + | true, _ -> NestedModule + | _ -> Namespace + + doRange scopeKind fullIdent startLine range.StartColumn + addModule (fullIdent, range) + List.iter (walkSynModuleDecl fullIdent) decls + + and walkSynModuleDecl (parent: LongIdent) (decl: SynModuleDecl) = + match decl with + | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace parent fragment + | SynModuleDecl.NestedModule(SynComponentInfo(_, _, _, ident, _, _, _, _), _, decls, _, range) -> + let fullIdent = parent @ ident + addModule (fullIdent, range) + if range.EndLine >= currentLine then + let moduleBodyIndentation = getMinColumn decls |> Option.defaultValue (range.StartColumn + 4) + doRange NestedModule fullIdent range.StartLine moduleBodyIndentation + List.iter (walkSynModuleDecl fullIdent) decls + | SynModuleDecl.Open (_, range) -> doRange OpenDeclaration [] range.EndLine (range.StartColumn - 5) + | SynModuleDecl.HashDirective (_, range) -> doRange HashDirective [] range.EndLine range.StartColumn + | _ -> () + + match ast with + | ParsedInput.SigFile _ -> () + | ParsedInput.ImplFile input -> walkImplFileInput input + + let res = + result + |> Option.map (fun (scope, pos, _) -> + let ns = ns |> Option.map longIdentToIdents + scope, ns, mkPos (pos.Line + 1) pos.Column) + + let modules = + modules + |> Seq.filter (fun x -> x.Range.EndLine < currentLine) + |> Seq.sortBy (fun x -> -x.Idents.Length) + |> Seq.toList + + res, modules + + let findBestPositionToInsertOpenDeclaration (modules: FSharpModule list) scope pos (entity: ShortIdents) = + match modules |> List.filter (fun x -> entity |> Array.startsWith x.Idents) with + | [] -> { ScopeKind = scope.Kind; Pos = pos } + | m :: _ -> + //printfn "All modules: %A, Win module: %A" modules m + let scopeKind = + match scope.Kind with + | TopModule -> NestedModule + | x -> x + { ScopeKind = scopeKind + Pos = mkPos (Line.fromZ m.Range.EndLine) m.Range.StartColumn } + + let TryFindInsertionContext (currentLine: int) (parsedInput: ParsedInput) (partiallyQualifiedName: MaybeUnresolvedIdent[]) (insertionPoint: OpenStatementInsertionPoint) = + let res, modules = tryFindNearestPointAndModules currentLine parsedInput insertionPoint + fun (requiresQualifiedAccessParent: ShortIdents option, autoOpenParent: ShortIdents option, entityNamespace: ShortIdents option, entity: ShortIdents) -> + + // We ignore all diagnostics during this operation + // + // Based on an initial review, no diagnostics should be generated. However the code should be checked more closely. + use _ignoreAllDiagnostics = new ErrorScope() + match res with + | None -> [||] + | Some (scope, ns, pos) -> + Entity.tryCreate(ns, scope.ShortIdents, partiallyQualifiedName, requiresQualifiedAccessParent, autoOpenParent, entityNamespace, entity) + |> Array.map (fun e -> e, findBestPositionToInsertOpenDeclaration modules scope pos entity) + + /// Corrects insertion line number based on kind of scope and text surrounding the insertion point. + let AdjustInsertionPoint (getLineStr: int -> string) ctx = + let line = + match ctx.ScopeKind with + | ScopeKind.TopModule -> + if ctx.Pos.Line > 1 then + // it's an implicit module without any open declarations + let line = getLineStr (ctx.Pos.Line - 2) + let isImplicitTopLevelModule = + not (line.StartsWithOrdinal("module") && not (line.EndsWithOrdinal("="))) + if isImplicitTopLevelModule then 1 else ctx.Pos.Line + else 1 + | ScopeKind.Namespace -> + // for namespaces the start line is start line of the first nested entity + if ctx.Pos.Line > 1 then + [0..ctx.Pos.Line - 1] + |> List.mapi (fun i line -> i, getLineStr line) + |> List.tryPick (fun (i, lineStr) -> + if lineStr.StartsWithOrdinal("namespace") then Some i + else None) + |> function + // move to the next line below "namespace" and convert it to F# 1-based line number + | Some line -> line + 2 + | None -> ctx.Pos.Line + else 1 + | _ -> ctx.Pos.Line + + mkPos line ctx.Pos.Column + + let FindNearestPointToInsertOpenDeclaration (currentLine: int) (parsedInput: ParsedInput) (entity: ShortIdents) (insertionPoint: OpenStatementInsertionPoint) = + match tryFindNearestPointAndModules currentLine parsedInput insertionPoint with + | Some (scope, _, point), modules -> + findBestPositionToInsertOpenDeclaration modules scope point entity + | _ -> + // we failed to find insertion point because ast is empty for some reason, return top left point in this case + { ScopeKind = ScopeKind.TopModule + Pos = mkPos 1 0 } diff --git a/src/fsharp/service/ServiceParsedInputOps.fsi b/src/fsharp/service/ServiceParsedInputOps.fsi new file mode 100644 index 00000000000..d0c36e03cc9 --- /dev/null +++ b/src/fsharp/service/ServiceParsedInputOps.fsi @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.EditorServices + +open System.Collections.Generic +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +type public CompletionPath = string list * string option // plid * residue + +[] +type public InheritanceContext = + | Class + | Interface + | Unknown + +[] +type public RecordContext = + | CopyOnUpdate of range: range * path: CompletionPath + | Constructor of typeName: string + | New of path: CompletionPath + +[] +type public CompletionContext = + /// Completion context cannot be determined due to errors + | Invalid + + /// Completing something after the inherit keyword + | Inherit of context: InheritanceContext * path: CompletionPath + + /// Completing records field + | RecordField of context: RecordContext + + | RangeOperator + + /// Completing named parameters\setters in parameter list of constructor\method calls + /// end of name ast node * list of properties\parameters that were already set + | ParameterList of pos * HashSet + + | AttributeApplication + + | OpenDeclaration of isOpenType: bool + + /// Completing pattern type (e.g. foo (x: |)) + | PatternType + +type public ModuleKind = + { IsAutoOpen: bool + HasModuleSuffix: bool } + +[] +type public EntityKind = + | Attribute + | Type + | FunctionOrValue of isActivePattern:bool + | Module of ModuleKind + +/// Kind of lexical scope. +[] +type public ScopeKind = + | Namespace + | TopModule + | NestedModule + | OpenDeclaration + | HashDirective + +/// Insert open namespace context. +[] +type public InsertionContext = + { + /// Current scope kind. + ScopeKind: ScopeKind + + /// Current position (F# compiler line number). + Pos: pos + } + +/// Where open statements should be added. +[] +type public OpenStatementInsertionPoint = + | TopLevel + | Nearest + +/// Short identifier, i.e. an identifier that contains no dots. +type public ShortIdent = string + +/// An array of `ShortIdent`. +type public ShortIdents = ShortIdent[] + +/// `ShortIdent` with a flag indicating if it's resolved in some scope. +type public MaybeUnresolvedIdent = + { Ident: ShortIdent; Resolved: bool } + +/// Helper data structure representing a symbol, suitable for implementing unresolved identifiers resolution code fixes. +type public InsertionContextEntity = + { + /// Full name, relative to the current scope. + FullRelativeName: string + + /// Ident parts needed to append to the current ident to make it resolvable in current scope. + Qualifier: string + + /// Namespace that is needed to open to make the entity resolvable in the current scope. + Namespace: string option + + /// Full display name (i.e. last ident plus modules with `RequireQualifiedAccess` attribute prefixed). + FullDisplayName: string + + /// Last part of the entity's full name. + LastIdent: ShortIdent + } + +/// Operations querying the entire syntax tree +module public ParsedInput = + val TryFindExpressionASTLeftOfDotLeftOfCursor: pos: pos * parsedInput: ParsedInput -> (pos * bool) option + + val GetRangeOfExprLeftOfDot: pos: pos * parsedInput: ParsedInput -> range option + + val TryFindExpressionIslandInPosition: pos: pos * parsedInput: ParsedInput -> string option + + val TryGetCompletionContext: pos: pos * parsedInput: ParsedInput * lineStr: string -> CompletionContext option + + val GetEntityKind: pos: pos * parsedInput: ParsedInput -> EntityKind option + + val GetFullNameOfSmallestModuleOrNamespaceAtPoint: pos: pos * parsedInput: ParsedInput -> string[] + + /// Returns `InsertContext` based on current position and symbol idents. + val TryFindInsertionContext: + currentLine: int -> + parsedInput: ParsedInput -> + partiallyQualifiedName: MaybeUnresolvedIdent[] -> + insertionPoint: OpenStatementInsertionPoint -> + (( (* requiresQualifiedAccessParent: *) ShortIdents option * (* autoOpenParent: *) ShortIdents option * (* entityNamespace *) ShortIdents option * (* entity: *) ShortIdents) -> (InsertionContextEntity * InsertionContext)[]) + + /// Returns `InsertContext` based on current position and symbol idents. + val FindNearestPointToInsertOpenDeclaration: currentLine: int -> parsedInput: ParsedInput -> entity: ShortIdents -> insertionPoint: OpenStatementInsertionPoint -> InsertionContext + + /// Returns long identifier at position. + val GetLongIdentAt: parsedInput: ParsedInput -> pos: pos -> LongIdent option + + /// Corrects insertion line number based on kind of scope and text surrounding the insertion point. + val AdjustInsertionPoint: getLineStr: (int -> string) -> ctx: InsertionContext -> pos + +// implementation details used by other code in the compiler +module internal SourceFileImpl = + + val IsInterfaceFile: string -> bool + + val AdditionalDefinesForUseInEditor: isInteractive: bool -> string list + diff --git a/src/fsharp/service/ServiceStructure.fs b/src/fsharp/service/ServiceStructure.fs index 56f2312da46..a9567c6c79b 100644 --- a/src/fsharp/service/ServiceStructure.fs +++ b/src/fsharp/service/ServiceStructure.fs @@ -1,17 +1,21 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.Ast -open FSharp.Compiler -open FSharp.Compiler.Range +open Internal.Utilities.Library +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range module Structure = + /// Set of visitor utilities, designed for the express purpose of fetching ranges /// from an untyped AST for the purposes of block structure. [] module Range = + /// Create a range starting at the end of r1 and finishing at the end of r2 let endToEnd (r1: range) (r2: range) = mkFileIndexRange r1.FileIndex r1.End r2.End @@ -34,7 +38,6 @@ module Structure = let modend = mkPos r.EndLine (r.EndColumn+m) mkFileIndexRange r.FileIndex r.Start modend - /// Produce a new range by adding modStart to the StartColumn of `r` /// and subtracting modEnd from the EndColumn of `r` let modBoth modStart modEnd (r:range) = @@ -54,7 +57,7 @@ module Structure = | [] -> other | ls -> ls - |> List.map (fun (TyparDecl (_, typarg)) -> typarg.Range) + |> List.map (fun (SynTyparDecl (_, typarg)) -> typarg.Range) |> List.reduce unionRanges let rangeOfSynPatsElse other (synPats:SynSimplePat list) = @@ -67,7 +70,7 @@ module Structure = | SynSimplePat.Attrib(range = r) | SynSimplePat.Id(range = r) | SynSimplePat.Typed(range = r) -> r) - |> List.reduce Range.unionRanges + |> List.reduce unionRanges /// Collapse indicates the way a range/snapshot should be collapsed. `Same` is for a scope inside /// some kind of scope delimiter, e.g. `[| ... |]`, `[ ... ]`, `{ ... }`, etc. `Below` is for expressions @@ -87,7 +90,7 @@ module Structure = | Member | LetOrUse | Val - | CompExpr + | ComputationExpr | IfThenElse | ThenInIfThenElse | ElseInIfThenElse @@ -106,7 +109,6 @@ module Structure = | MatchLambda | MatchClause | Lambda - | CompExprInternal | Quote | Record | SpecialFunc @@ -127,6 +129,7 @@ module Structure = | UnionDefn | Comment | XmlDocComment + override self.ToString() = match self with | Open -> "Open" @@ -136,7 +139,7 @@ module Structure = | Member -> "Member" | LetOrUse -> "LetOrUse" | Val -> "Val" - | CompExpr -> "CompExpr" + | ComputationExpr -> "ComputationExpr" | IfThenElse -> "IfThenElse" | ThenInIfThenElse -> "ThenInIfThenElse" | ElseInIfThenElse -> "ElseInIfThenElse" @@ -155,7 +158,6 @@ module Structure = | MatchLambda -> "MatchLambda" | MatchClause -> "MatchClause" | Lambda -> "Lambda" - | CompExprInternal -> "CompExprInternal" | Quote -> "Quote" | Record -> "Record" | SpecialFunc -> "SpecialFunc" @@ -245,14 +247,22 @@ module Structure = | SynExpr.DoBang (e, r) -> rcheck Scope.Do Collapse.Below r <| Range.modStart 3 r parseExpr e - | SynExpr.LetOrUseBang (_, _, _, pat, e1, e2, _) -> - // for `let!` or `use!` the pattern begins at the end of the keyword so that - // this scope can be used without adjustment if there is no `=` on the same line - // if there is an `=` the range will be adjusted during the tooltip creation - let r = Range.endToEnd pat.Range e1.Range - rcheck Scope.LetOrUseBang Collapse.Below r r - parseExpr e1 - parseExpr e2 + | SynExpr.LetOrUseBang (_, _, _, pat, eLet, es, eBody, _) -> + [ + yield eLet + for _,_,_,_,eAndBang,_ in es do + yield eAndBang + ] + |> List.iter (fun e -> + // for `let!`, `use!` or `and!` the pattern begins at the end of the + // keyword so that this scope can be used without adjustment if there is no `=` + // on the same line. If there is an `=` the range will be adjusted during the + // tooltip creation + let r = Range.endToEnd pat.Range e.Range + rcheck Scope.LetOrUseBang Collapse.Below r r + parseExpr e + ) + parseExpr eBody | SynExpr.For (_, _, _, _, _, e, r) | SynExpr.ForEach (_, _, _, _, _, e, r) -> rcheck Scope.For Collapse.Below r r @@ -263,7 +273,7 @@ module Structure = | SynExpr.Match (seqPointAtBinding, _expr, clauses, r) | SynExpr.MatchBang (seqPointAtBinding, _expr, clauses, r) -> match seqPointAtBinding with - | SequencePointAtBinding sr -> + | DebugPointAtBinding.Yes sr -> let collapse = Range.endToEnd sr r rcheck Scope.Match Collapse.Same r collapse | _ -> () @@ -271,7 +281,7 @@ module Structure = | SynExpr.MatchLambda (_, caseRange, clauses, matchSeqPoint, r) -> let caseRange = match matchSeqPoint with - | SequencePointAtBinding r -> r + | DebugPointAtBinding.Yes r -> r | _ -> caseRange let collapse = Range.endToEnd caseRange r rcheck Scope.MatchLambda Collapse.Same r collapse @@ -280,24 +290,24 @@ module Structure = // seq exprs, custom operators, etc if ExprAtomicFlag.NonAtomic=atomicFlag && (not isInfix) && (function SynExpr.Ident _ -> true | _ -> false) funcExpr - && (function SynExpr.CompExpr _ -> false | _ -> true ) argExpr then + && (function SynExpr.ComputationExpr _ -> false | _ -> true ) argExpr then // if the argExpr is a computation expression another match will handle the outlining // these cases must be removed to prevent creating unnecessary tags for the same scope let collapse = Range.endToEnd funcExpr.Range r rcheck Scope.SpecialFunc Collapse.Below r collapse elif ExprAtomicFlag.NonAtomic=atomicFlag && (not isInfix) - && (function SynExpr.CompExpr _ -> true | _ -> false) argExpr then + && (function SynExpr.ComputationExpr _ -> true | _ -> false) argExpr then let collapse = Range.startToEnd argExpr.Range r - rcheck Scope.CompExpr Collapse.Same r <| Range.modBoth 1 1 collapse + rcheck Scope.ComputationExpr Collapse.Same r <| Range.modBoth 1 1 collapse parseExpr argExpr parseExpr funcExpr | SynExpr.Sequential (_, _, e1, e2, _) -> parseExpr e1 parseExpr e2 - | SynExpr.ArrayOrListOfSeqExpr (isArray, e, r) -> + | SynExpr.ArrayOrListComputed (isArray, e, r) -> rcheck Scope.ArrayOrList Collapse.Same r <| Range.modBoth (if isArray then 2 else 1) (if isArray then 2 else 1) r parseExpr e - | SynExpr.CompExpr (_arrayOrList, _, e, _r) as _c -> + | SynExpr.ComputationExpr (_, e, _r) as _c -> parseExpr e | SynExpr.ObjExpr (_, argOpt, bindings, extraImpls, newRange, wholeRange) as _objExpr -> match argOpt with @@ -311,7 +321,7 @@ module Structure = parseExprInterfaces extraImpls | SynExpr.TryWith (e, _, matchClauses, _, wholeRange, tryPoint, withPoint) -> match tryPoint, withPoint with - | SequencePointAtTry tryRange, SequencePointAtWith withRange -> + | DebugPointAtTry.Yes tryRange, DebugPointAtWith.Yes withRange -> let fullrange = Range.startToEnd tryRange wholeRange let collapse = Range.endToEnd tryRange wholeRange let collapseTry = Range.endToStart tryRange withRange @@ -326,7 +336,7 @@ module Structure = List.iter parseMatchClause matchClauses | SynExpr.TryFinally (tryExpr, finallyExpr, r, tryPoint, finallyPoint) -> match tryPoint, finallyPoint with - | SequencePointAtTry tryRange, SequencePointAtFinally finallyRange -> + | DebugPointAtTry.Yes tryRange, DebugPointAtFinally.Yes finallyRange -> let collapse = Range.endToEnd tryRange finallyExpr.Range let fullrange = Range.startToEnd tryRange finallyExpr.Range let collapseFinally = Range.endToEnd finallyRange r @@ -336,9 +346,9 @@ module Structure = | _ -> () parseExpr tryExpr parseExpr finallyExpr - | SynExpr.IfThenElse (ifExpr, thenExpr, elseExprOpt, spIfToThen, _, ifToThenRange, r) -> + | SynExpr.IfThenElse (_, _, ifExpr, _, thenExpr, _, elseExprOpt, spIfToThen, _, ifToThenRange, r) -> match spIfToThen with - | SequencePointAtBinding rt -> + | DebugPointAtBinding.Yes rt -> // Outline the entire IfThenElse let fullrange = Range.startToEnd rt r let collapse = Range.endToEnd ifExpr.Range r @@ -365,7 +375,7 @@ module Structure = | SynExpr.While (_, _, e, r) -> rcheck Scope.While Collapse.Below r r parseExpr e - | SynExpr.Lambda (_, _, pats, e, r) -> + | SynExpr.Lambda (_, _, pats, _, e, _, r) -> match pats with | SynSimplePats.SimplePats (_, pr) | SynSimplePats.Typed (_, _, pr) -> @@ -395,7 +405,7 @@ module Structure = rcheck Scope.Record Collapse.Same r <| Range.modBoth 1 1 r | _ -> () - and parseMatchClause (SynMatchClause.Clause(synPat, _, e, _r, _) as clause) = + and parseMatchClause (SynMatchClause(synPat, _, _, e, _r, _) as clause) = let rec getLastPat = function | SynPat.Or(_, pat, _) -> getLastPat pat | x -> x @@ -408,7 +418,7 @@ module Structure = and parseAttributes (Attributes attrs) = let attrListRange() = if not (List.isEmpty attrs) then - let range = Range.startToEnd (attrs.[0].Range) (attrs.[attrs.Length-1].ArgExpr.Range) + let range = Range.startToEnd attrs.[0].Range attrs.[attrs.Length-1].ArgExpr.Range rcheck Scope.Attribute Collapse.Same range range match attrs with @@ -426,19 +436,18 @@ module Structure = for attr in attrs do parseExpr attr.ArgExpr - and parseBinding (SynBinding.Binding (_, kind, _, _, attrs, _, SynValData(memberFlags, _, _), _, _, expr, br, _) as binding) = + and parseBinding (SynBinding(_, kind, _, _, attrs, _, SynValData(memberFlags, _, _), _, _, expr, br, _) as binding) = match kind with - | NormalBinding -> - let collapse = Range.endToEnd binding.RangeOfBindingSansRhs binding.RangeOfBindingAndRhs + | SynBindingKind.Normal -> + let collapse = Range.endToEnd binding.RangeOfBindingWithoutRhs binding.RangeOfBindingWithRhs match memberFlags with - | Some ({MemberKind=MemberKind.Constructor}) -> - let collapse = Range.startToEnd expr.Range br - rcheck Scope.New Collapse.Below br collapse + | Some {MemberKind=SynMemberKind.Constructor} -> + rcheck Scope.New Collapse.Below binding.RangeOfBindingWithRhs collapse | Some _ -> - rcheck Scope.Member Collapse.Below binding.RangeOfBindingAndRhs collapse + rcheck Scope.Member Collapse.Below binding.RangeOfBindingWithRhs collapse | None -> - rcheck Scope.LetOrUse Collapse.Below binding.RangeOfBindingAndRhs collapse - | DoBinding -> + rcheck Scope.LetOrUse Collapse.Below binding.RangeOfBindingWithRhs collapse + | SynBindingKind.Do -> let r = Range.modStart 2 br rcheck Scope.Do Collapse.Below br r | _ -> () @@ -447,7 +456,7 @@ module Structure = and parseBindings sqs = for bind in sqs do parseBinding bind - and parseExprInterface (InterfaceImpl(synType, bindings, range)) = + and parseExprInterface (SynInterfaceImpl(synType, bindings, range)) = let collapse = Range.endToEnd synType.Range range |> Range.modEnd -1 rcheck Scope.Interface Collapse.Below range collapse parseBindings bindings @@ -456,12 +465,12 @@ module Structure = and parseSynMemberDefn (objectModelRange: range) d = match d with - | SynMemberDefn.Member(SynBinding.Binding (attrs=attrs; valData=valData; headPat=synPat; range=bindingRange) as binding, _) -> + | SynMemberDefn.Member(SynBinding.SynBinding (attributes=attrs; valData=valData; headPat=synPat; range=bindingRange) as binding, _) -> match valData with - | SynValData (Some { MemberKind=MemberKind.Constructor }, _, _) -> + | SynValData (Some { MemberKind=SynMemberKind.Constructor }, _, _) -> let collapse = Range.endToEnd synPat.Range d.Range rcheck Scope.New Collapse.Below d.Range collapse - | SynValData (Some { MemberKind=MemberKind.PropertyGet | MemberKind.PropertySet }, _, _) -> + | SynValData (Some { MemberKind=SynMemberKind.PropertyGet | SynMemberKind.PropertySet }, _, _) -> let range = mkRange d.Range.FileName @@ -489,7 +498,7 @@ module Structure = | None -> () | SynMemberDefn.NestedType (td, _, _) -> parseTypeDefn td - | SynMemberDefn.AbstractSlot (ValSpfn(synType=synt), _, r) -> + | SynMemberDefn.AbstractSlot (SynValSig(synType=synt), _, r) -> rcheck Scope.Member Collapse.Below d.Range (Range.startToEnd synt.Range r) | SynMemberDefn.AutoProperty (synExpr=e; range=r) -> rcheck Scope.Member Collapse.Below d.Range r @@ -509,28 +518,28 @@ module Structure = and parseSimpleRepr simple = match simple with | SynTypeDefnSimpleRepr.Enum (cases, _er) -> - for EnumCase (attrs, _, _, _, cr) in cases do + for SynEnumCase (attrs, _, _, _, _, cr) in cases do rcheck Scope.EnumCase Collapse.Below cr cr parseAttributes attrs | SynTypeDefnSimpleRepr.Record (_, fields, rr) -> rcheck Scope.RecordDefn Collapse.Same rr rr - for Field (attrs, _, _, _, _, _, _, fr) in fields do + for SynField (attrs, _, _, _, _, _, _, fr) in fields do rcheck Scope.RecordField Collapse.Below fr fr parseAttributes attrs | SynTypeDefnSimpleRepr.Union (_, cases, ur) -> rcheck Scope.UnionDefn Collapse.Same ur ur - for UnionCase (attrs, _, _, _, _, cr) in cases do + for SynUnionCase (attrs, _, _, _, _, cr) in cases do rcheck Scope.UnionCase Collapse.Below cr cr parseAttributes attrs | _ -> () - and parseTypeDefn (TypeDefn(ComponentInfo(_, typeArgs, _, _, _, _, _, r), objectModel, members, fullrange)) = + and parseTypeDefn (SynTypeDefn(SynComponentInfo(_, TyparDecls typeArgs, _, _, _, _, _, r), objectModel, members, _, fullrange)) = let typeArgsRange = rangeOfTypeArgsElse r typeArgs let collapse = Range.endToEnd (Range.modEnd 1 typeArgsRange) fullrange match objectModel with | SynTypeDefnRepr.ObjectModel (defnKind, objMembers, r) -> match defnKind with - | TyconAugmentation -> + | SynTypeDefnKind.Augmentation -> rcheck Scope.TypeExtension Collapse.Below fullrange collapse | _ -> rcheck Scope.Type Collapse.Below fullrange collapse @@ -543,7 +552,7 @@ module Structure = List.iter (parseSynMemberDefn r) members | SynTypeDefnRepr.Exception _ -> () - let getConsecutiveModuleDecls (predicate: SynModuleDecl -> range option) (scope: Scope) (decls: SynModuleDecls) = + let getConsecutiveModuleDecls (predicate: SynModuleDecl -> range option) (scope: Scope) (decls: SynModuleDecl list) = let groupConsecutiveDecls input = let rec loop (input: range list) (res: range list list) currentBulk = match input, currentBulk with @@ -589,14 +598,14 @@ module Structure = match decl with | SynModuleDecl.Let (_, bindings, r) -> for binding in bindings do - let collapse = Range.endToEnd binding.RangeOfBindingSansRhs r + let collapse = Range.endToEnd binding.RangeOfBindingWithoutRhs r rcheck Scope.LetOrUse Collapse.Below r collapse parseBindings bindings | SynModuleDecl.Types (types, _r) -> for t in types do parseTypeDefn t // Fold the attributes above a module - | SynModuleDecl.NestedModule (ComponentInfo (attrs, _, _, _, _, _, _, cmpRange), _, decls, _, _) -> + | SynModuleDecl.NestedModule (SynComponentInfo (attrs, _, _, _, _, _, _, cmpRange), _, decls, _, _) -> // Outline the full scope of the module let r = Range.endToEnd cmpRange decl.Range rcheck Scope.Module Collapse.Below decl.Range r @@ -617,7 +626,7 @@ module Structure = let collapse = Range.endToEnd idRange r // do not return range for top level implicit module in scripts - if kind = NamedModule then + if kind = SynModuleOrNamespaceKind.NamedModule then rcheck Scope.Module Collapse.Below fullrange collapse collectHashDirectives decls @@ -631,7 +640,7 @@ module Structure = else None let getCommentRanges (lines: string[]) = - let rec loop ((lastLineNum, currentComment: CommentList option, result) as state) (lines: string list) lineNum = + let rec loop (lastLineNum, currentComment: CommentList option, result as state) (lines: string list) lineNum = match lines with | [] -> state | lineStr :: rest -> @@ -708,16 +717,16 @@ module Structure = match typeSigs with | [] -> range | ls -> - let (TypeDefnSig(_, _, memberSigs, r)) = List.last ls + let (SynTypeDefnSig(_, _, memberSigs, r)) = List.last ls lastMemberSigRangeElse r memberSigs - let lastModuleSigDeclRangeElse range (sigDecls:SynModuleSigDecls) = + let lastModuleSigDeclRangeElse range (sigDecls:SynModuleSigDecl list) = match sigDecls with | [] -> range | ls -> match List.last ls with | SynModuleSigDecl.Types (typeSigs, r) -> lastTypeDefnSigRangeElse r typeSigs - | SynModuleSigDecl.Val (ValSpfn(range=r), _) -> r + | SynModuleSigDecl.Val (SynValSig(range=r), _) -> r | SynModuleSigDecl.Exception(_, r) -> r | SynModuleSigDecl.Open(_, r) -> r | SynModuleSigDecl.ModuleAbbrev(_, _, r) -> r @@ -727,7 +736,7 @@ module Structure = | SynMemberSig.Member(valSigs, _, r) -> let collapse = Range.endToEnd valSigs.RangeOfId r rcheck Scope.Member Collapse.Below r collapse - | SynMemberSig.ValField(Field(attrs, _, _, _, _, _, _, fr), fullrange) -> + | SynMemberSig.ValField(SynField(attrs, _, _, _, _, _, _, fr), fullrange) -> let collapse = Range.endToEnd fr fullrange rcheck Scope.Val Collapse.Below fullrange collapse parseAttributes attrs @@ -737,7 +746,7 @@ module Structure = parseTypeDefnSig typeDefSig | _ -> () - and parseTypeDefnSig (TypeDefnSig (ComponentInfo(attribs, typeArgs, _, longId, _, _, _, r) as __, objectModel, memberSigs, _)) = + and parseTypeDefnSig (SynTypeDefnSig (SynComponentInfo(attribs, TyparDecls typeArgs, _, longId, _, _, _, r) as __, objectModel, memberSigs, _)) = parseAttributes attribs let makeRanges memberSigs = @@ -752,11 +761,11 @@ module Structure = match objectModel with // matches against a type declaration with <'T, ...> and (args, ...) | SynTypeDefnSigRepr.ObjectModel - (TyconUnspecified, objMembers, _) -> + (SynTypeDefnKind.Unspecified, objMembers, _) -> List.iter parseSynMemberDefnSig objMembers let fullrange, collapse = makeRanges objMembers rcheck Scope.Type Collapse.Below fullrange collapse - | SynTypeDefnSigRepr.ObjectModel (TyconAugmentation, objMembers, _) -> + | SynTypeDefnSigRepr.ObjectModel (SynTypeDefnKind.Augmentation, objMembers, _) -> let fullrange, collapse = makeRanges objMembers rcheck Scope.TypeExtension Collapse.Below fullrange collapse List.iter parseSynMemberDefnSig objMembers @@ -771,7 +780,7 @@ module Structure = parseSimpleRepr simpleRepr | SynTypeDefnSigRepr.Exception _ -> () - let getConsecutiveSigModuleDecls (predicate: SynModuleSigDecl -> range option) (scope:Scope) (decls: SynModuleSigDecls) = + let getConsecutiveSigModuleDecls (predicate: SynModuleSigDecl -> range option) (scope:Scope) (decls: SynModuleSigDecl list) = let groupConsecutiveSigDecls input = let rec loop (input: range list) (res: range list list) currentBulk = match input, currentBulk with @@ -801,7 +810,7 @@ module Structure = |> List.choose selectSigRanges |> acc.AddRange - let collectSigHashDirectives (decls: SynModuleSigDecls) = + let collectSigHashDirectives (decls: SynModuleSigDecl list) = decls |> getConsecutiveSigModuleDecls( function @@ -814,14 +823,14 @@ module Structure = let rec parseModuleSigDeclaration (decl: SynModuleSigDecl) = match decl with - | SynModuleSigDecl.Val ((ValSpfn(attrs, ident, _, _, _, _, _, _, _, _, valrange)), r) -> + | SynModuleSigDecl.Val (SynValSig(attrs, ident, _, _, _, _, _, _, _, _, valrange), r) -> let collapse = Range.endToEnd ident.idRange valrange rcheck Scope.Val Collapse.Below r collapse parseAttributes attrs | SynModuleSigDecl.Types (typeSigs, _) -> List.iter parseTypeDefnSig typeSigs // Fold the attributes above a module - | SynModuleSigDecl.NestedModule (ComponentInfo (attrs, _, _, _, _, _, _, cmpRange), _, decls, moduleRange) -> + | SynModuleSigDecl.NestedModule (SynComponentInfo (attrs, _, _, _, _, _, _, cmpRange), _, decls, moduleRange) -> let rangeEnd = lastModuleSigDeclRangeElse moduleRange decls // Outline the full scope of the module let collapse = Range.endToEnd cmpRange rangeEnd diff --git a/src/fsharp/service/ServiceStructure.fsi b/src/fsharp/service/ServiceStructure.fsi index 4eeefe529fd..f05df0b6da0 100644 --- a/src/fsharp/service/ServiceStructure.fsi +++ b/src/fsharp/service/ServiceStructure.fsi @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.Ast -open FSharp.Compiler.Range +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text module public Structure = @@ -25,7 +25,7 @@ module public Structure = | Member | LetOrUse | Val - | CompExpr + | ComputationExpr | IfThenElse | ThenInIfThenElse | ElseInIfThenElse @@ -44,7 +44,6 @@ module public Structure = | MatchLambda | MatchClause | Lambda - | CompExprInternal | Quote | Record | SpecialFunc @@ -75,7 +74,7 @@ module public Structure = /// HintSpan in BlockSpan Range: range /// TextSpan in BlockSpan - CollapseRange:range + CollapseRange: range } /// Returns outlining ranges for given parsed input. diff --git a/src/fsharp/service/ServiceUntypedParse.fs b/src/fsharp/service/ServiceUntypedParse.fs deleted file mode 100755 index f1422794746..00000000000 --- a/src/fsharp/service/ServiceUntypedParse.fs +++ /dev/null @@ -1,1394 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -//---------------------------------------------------------------------------- -// Open up the compiler as an incremental service for parsing, -// type checking and intellisense-like environment-reporting. -//-------------------------------------------------------------------------- - -namespace FSharp.Compiler.SourceCodeServices - -open System -open System.IO -open System.Collections.Generic -open System.Diagnostics -open System.Text.RegularExpressions - -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming - -/// Methods for dealing with F# sources files. -module SourceFile = - - /// Source file extensions - let private compilableExtensions = CompileOps.FSharpSigFileSuffixes @ CompileOps.FSharpImplFileSuffixes @ CompileOps.FSharpScriptFileSuffixes - - /// Single file projects extensions - let private singleFileProjectExtensions = CompileOps.FSharpScriptFileSuffixes - - /// Whether or not this file is compilable - let IsCompilable file = - let ext = Path.GetExtension file - compilableExtensions |> List.exists(fun e->0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) - - /// Whether or not this file should be a single-file project - let MustBeSingleFileProject file = - let ext = Path.GetExtension file - singleFileProjectExtensions |> List.exists(fun e-> 0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) - -module SourceFileImpl = - let IsInterfaceFile file = - let ext = Path.GetExtension file - 0 = String.Compare(".fsi", ext, StringComparison.OrdinalIgnoreCase) - - /// Additional #defines that should be in place when editing a file in a file editor such as VS. - let AdditionalDefinesForUseInEditor(isInteractive: bool) = - if isInteractive then ["INTERACTIVE";"EDITING"] // This is still used by the foreground parse - else ["COMPILED";"EDITING"] - -type CompletionPath = string list * string option // plid * residue - -[] -type InheritanceOrigin = - | Class - | Interface - | Unknown - -[] -type InheritanceContext = - | Class - | Interface - | Unknown - -[] -type RecordContext = - | CopyOnUpdate of range * CompletionPath // range of copy-expr + current field - | Constructor of string // typename - | New of CompletionPath - -[] -type CompletionContext = - // completion context cannot be determined due to errors - | Invalid - // completing something after the inherit keyword - | Inherit of InheritanceContext * CompletionPath - // completing records field - | RecordField of RecordContext - | RangeOperator - // completing named parameters\setters in parameter list of constructor\method calls - // end of name ast node * list of properties\parameters that were already set - | ParameterList of pos * HashSet - | AttributeApplication - | OpenDeclaration - /// completing pattern type (e.g. foo (x: |)) - | PatternType - -//---------------------------------------------------------------------------- -// FSharpParseFileResults -//---------------------------------------------------------------------------- - -[] -type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput option, parseHadErrors: bool, dependencyFiles: string[]) = - - member scope.Errors = errors - - member scope.ParseHadErrors = parseHadErrors - - member scope.ParseTree = input - - member scope.FindNoteworthyParamInfoLocations pos = - match input with - | Some input -> FSharpNoteworthyParamInfoLocations.Find(pos, input) - | _ -> None - - /// Get declared items and the selected item at the specified location - member private scope.GetNavigationItemsImpl() = - ErrorScope.Protect Range.range0 - (fun () -> - match input with - | Some (ParsedInput.ImplFile _ as p) -> - FSharpNavigation.getNavigation p - | Some (ParsedInput.SigFile _) -> - FSharpNavigation.empty - | _ -> - FSharpNavigation.empty) - (fun err -> - Trace.TraceInformation(sprintf "FCS: recovering from error in GetNavigationItemsImpl: '%s'" err) - FSharpNavigation.empty) - - member private scope.ValidateBreakpointLocationImpl pos = - let isMatchRange m = rangeContainsPos m pos || m.StartLine = pos.Line - - // Process let-binding - let findBreakPoints () = - let checkRange m = [ if isMatchRange m then yield m ] - let walkBindSeqPt sp = [ match sp with SequencePointAtBinding m -> yield! checkRange m | _ -> () ] - let walkForSeqPt sp = [ match sp with SequencePointAtForLoop m -> yield! checkRange m | _ -> () ] - let walkWhileSeqPt sp = [ match sp with SequencePointAtWhileLoop m -> yield! checkRange m | _ -> () ] - let walkTrySeqPt sp = [ match sp with SequencePointAtTry m -> yield! checkRange m | _ -> () ] - let walkWithSeqPt sp = [ match sp with SequencePointAtWith m -> yield! checkRange m | _ -> () ] - let walkFinallySeqPt sp = [ match sp with SequencePointAtFinally m -> yield! checkRange m | _ -> () ] - - let rec walkBind (Binding(_, _, _, _, _, _, SynValData(memFlagsOpt, _, _), synPat, _, synExpr, _, spInfo)) = - [ // Don't yield the binding sequence point if there are any arguments, i.e. we're defining a function or a method - let isFunction = - Option.isSome memFlagsOpt || - match synPat with - | SynPat.LongIdent (_, _, _, SynConstructorArgs.Pats args, _, _) when not (List.isEmpty args) -> true - | _ -> false - if not isFunction then - yield! walkBindSeqPt spInfo - - yield! walkExpr (isFunction || (match spInfo with SequencePointAtBinding _ -> false | _-> true)) synExpr ] - - and walkExprs es = List.collect (walkExpr false) es - and walkBinds es = List.collect walkBind es - and walkMatchClauses cl = - [ for (Clause(_, whenExpr, e, _, _)) in cl do - match whenExpr with - | Some e -> yield! walkExpr false e - | _ -> () - yield! walkExpr true e ] - - and walkExprOpt (spAlways: bool) eOpt = [ match eOpt with Some e -> yield! walkExpr spAlways e | _ -> () ] - - and IsBreakableExpression e = - match e with - | SynExpr.Match _ - | SynExpr.IfThenElse _ - | SynExpr.For _ - | SynExpr.ForEach _ - | SynExpr.While _ -> true - | _ -> not (IsControlFlowExpression e) - - // Determine the breakpoint locations for an expression. spAlways indicates we always - // emit a breakpoint location for the expression unless it is a syntactic control flow construct - and walkExpr (spAlways: bool) e = - let m = e.Range - if not (isMatchRange m) then [] else - [ if spAlways && IsBreakableExpression e then - yield! checkRange m - - match e with - | SynExpr.ArbitraryAfterError _ - | SynExpr.LongIdent _ - | SynExpr.LibraryOnlyILAssembly _ - | SynExpr.LibraryOnlyStaticOptimization _ - | SynExpr.Null _ - | SynExpr.Ident _ - | SynExpr.ImplicitZero _ - | SynExpr.Const _ -> - () - - | SynExpr.Quote (_, _, e, _, _) - | SynExpr.TypeTest (e, _, _) - | SynExpr.Upcast (e, _, _) - | SynExpr.AddressOf (_, e, _, _) - | SynExpr.CompExpr (_, _, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) - | SynExpr.Typed (e, _, _) - | SynExpr.FromParseError (e, _) - | SynExpr.DiscardAfterMissingQualificationAfterDot (e, _) - | SynExpr.Do (e, _) - | SynExpr.Assert (e, _) - | SynExpr.Fixed (e, _) - | SynExpr.DotGet (e, _, _, _) - | SynExpr.LongIdentSet (_, e, _) - | SynExpr.New (_, _, e, _) - | SynExpr.TypeApp (e, _, _, _, _, _, _) - | SynExpr.LibraryOnlyUnionCaseFieldGet (e, _, _, _) - | SynExpr.Downcast (e, _, _) - | SynExpr.InferredUpcast (e, _) - | SynExpr.InferredDowncast (e, _) - | SynExpr.Lazy (e, _) - | SynExpr.TraitCall (_, _, e, _) - | SynExpr.Paren (e, _, _, _) -> - yield! walkExpr false e - - | SynExpr.YieldOrReturn (_, e, _) - | SynExpr.YieldOrReturnFrom (_, e, _) - | SynExpr.DoBang (e, _) -> - yield! checkRange e.Range - yield! walkExpr false e - - | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) - | SynExpr.DotSet (e1, _, e2, _) - | SynExpr.Set (e1, e2, _) - | SynExpr.LibraryOnlyUnionCaseFieldSet (e1, _, _, e2, _) - | SynExpr.App (_, _, e1, e2, _) -> - yield! walkExpr false e1 - yield! walkExpr false e2 - - | SynExpr.ArrayOrList (_, es, _) - | SynExpr.Tuple (_, es, _, _) -> - yield! walkExprs es - - | SynExpr.Record (_, copyExprOpt, fs, _) -> - match copyExprOpt with - | Some (e, _) -> yield! walkExpr true e - | None -> () - yield! walkExprs (fs |> List.choose p23) - - | SynExpr.AnonRecd (_isStruct, copyExprOpt, fs, _) -> - match copyExprOpt with - | Some (e, _) -> yield! walkExpr true e - | None -> () - yield! walkExprs (fs |> List.map snd) - - | SynExpr.ObjExpr (_, args, bs, is, _, _) -> - match args with - | None -> () - | Some (arg, _) -> yield! walkExpr false arg - yield! walkBinds bs - for (InterfaceImpl(_, bs, _)) in is do yield! walkBinds bs - - | SynExpr.While (spWhile, e1, e2, _) -> - yield! walkWhileSeqPt spWhile - yield! walkExpr false e1 - yield! walkExpr true e2 - - | SynExpr.JoinIn (e1, _range, e2, _range2) -> - yield! walkExpr false e1 - yield! walkExpr false e2 - - | SynExpr.For (spFor, _, e1, _, e2, e3, _) -> - yield! walkForSeqPt spFor - yield! walkExpr false e1 - yield! walkExpr true e2 - yield! walkExpr true e3 - - | SynExpr.ForEach (spFor, _, _, _, e1, e2, _) -> - yield! walkForSeqPt spFor - yield! walkExpr false e1 - yield! walkExpr true e2 - - | SynExpr.MatchLambda (_isExnMatch, _argm, cl, spBind, _wholem) -> - yield! walkBindSeqPt spBind - for (Clause(_, whenExpr, e, _, _)) in cl do - yield! walkExprOpt false whenExpr - yield! walkExpr true e - - | SynExpr.Lambda (_, _, _, e, _) -> - yield! walkExpr true e - - | SynExpr.Match (spBind, e, cl, _) -> - yield! walkBindSeqPt spBind - yield! walkExpr false e - for (Clause(_, whenExpr, e, _, _)) in cl do - yield! walkExprOpt false whenExpr - yield! walkExpr true e - - | SynExpr.LetOrUse (_, _, bs, e, _) -> - yield! walkBinds bs - yield! walkExpr true e - - | SynExpr.TryWith (e, _, cl, _, _, spTry, spWith) -> - yield! walkTrySeqPt spTry - yield! walkWithSeqPt spWith - yield! walkExpr true e - yield! walkMatchClauses cl - - | SynExpr.TryFinally (e1, e2, _, spTry, spFinally) -> - yield! walkExpr true e1 - yield! walkExpr true e2 - yield! walkTrySeqPt spTry - yield! walkFinallySeqPt spFinally - - | SynExpr.SequentialOrImplicitYield (spSeq, e1, e2, _, _) - | SynExpr.Sequential (spSeq, _, e1, e2, _) -> - yield! walkExpr (match spSeq with SuppressSequencePointOnStmtOfSequential -> false | _ -> true) e1 - yield! walkExpr (match spSeq with SuppressSequencePointOnExprOfSequential -> false | _ -> true) e2 - - | SynExpr.IfThenElse (e1, e2, e3opt, spBind, _, _, _) -> - yield! walkBindSeqPt spBind - yield! walkExpr false e1 - yield! walkExpr true e2 - yield! walkExprOpt true e3opt - - | SynExpr.DotIndexedGet (e1, es, _, _) -> - yield! walkExpr false e1 - yield! walkExprs [ for e in es do yield! e.Exprs ] - - | SynExpr.DotIndexedSet (e1, es, e2, _, _, _) -> - yield! walkExpr false e1 - yield! walkExprs [ for e in es do yield! e.Exprs ] - yield! walkExpr false e2 - - | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> - yield! walkExpr false e1 - yield! walkExpr false e2 - yield! walkExpr false e3 - - | SynExpr.LetOrUseBang (spBind, _, _, _, e1, e2, _) -> - yield! walkBindSeqPt spBind - yield! walkExpr true e1 - yield! walkExpr true e2 - - | SynExpr.MatchBang (spBind, e, cl, _) -> - yield! walkBindSeqPt spBind - yield! walkExpr false e - for (Clause(_, whenExpr, e, _, _)) in cl do - yield! walkExprOpt false whenExpr - yield! walkExpr true e ] - - // Process a class declaration or F# type declaration - let rec walkTycon (TypeDefn(ComponentInfo(_, _, _, _, _, _, _, _), repr, membDefns, m)) = - if not (isMatchRange m) then [] else - [ for memb in membDefns do yield! walkMember memb - match repr with - | SynTypeDefnRepr.ObjectModel(_, membDefns, _) -> - for memb in membDefns do yield! walkMember memb - | _ -> () ] - - // Returns class-members for the right dropdown - and walkMember memb = - if not (rangeContainsPos memb.Range pos) then [] else - [ match memb with - | SynMemberDefn.LetBindings(binds, _, _, _) -> yield! walkBinds binds - | SynMemberDefn.AutoProperty(_attribs, _isStatic, _id, _tyOpt, _propKind, _, _xmlDoc, _access, synExpr, _, _) -> yield! walkExpr true synExpr - | SynMemberDefn.ImplicitCtor(_, _, _, _, m) -> yield! checkRange m - | SynMemberDefn.Member(bind, _) -> yield! walkBind bind - | SynMemberDefn.Interface(_synty, Some membs, _) -> for m in membs do yield! walkMember m - | SynMemberDefn.Inherit(_, _, m) -> - // can break on the "inherit" clause - yield! checkRange m - | SynMemberDefn.ImplicitInherit(_, arg, _, m) -> - // can break on the "inherit" clause - yield! checkRange m - yield! walkExpr true arg - | _ -> () ] - - // Process declarations nested in a module that should be displayed in the left dropdown - // (such as type declarations, nested modules etc.) - let rec walkDecl decl = - [ match decl with - | SynModuleDecl.Let(_, binds, m) when isMatchRange m -> - yield! walkBinds binds - | SynModuleDecl.DoExpr(spExpr, expr, m) when isMatchRange m -> - yield! walkBindSeqPt spExpr - yield! walkExpr false expr - | SynModuleDecl.ModuleAbbrev _ -> () - | SynModuleDecl.NestedModule(_, _isRec, decls, _, m) when isMatchRange m -> - for d in decls do yield! walkDecl d - | SynModuleDecl.Types(tydefs, m) when isMatchRange m -> - for d in tydefs do yield! walkTycon d - | SynModuleDecl.Exception(SynExceptionDefn(SynExceptionDefnRepr(_, _, _, _, _, _), membDefns, _), m) - when isMatchRange m -> - for m in membDefns do yield! walkMember m - | _ -> () ] - - // Collect all the items in a module - let walkModule (SynModuleOrNamespace(_, _, _, decls, _, _, _, m)) = - if isMatchRange m then - List.collect walkDecl decls - else - [] - - /// Get information for implementation file - let walkImplFile (modules: SynModuleOrNamespace list) = List.collect walkModule modules - - match input with - | Some (ParsedInput.ImplFile (ParsedImplFileInput (modules = modules))) -> walkImplFile modules - | _ -> [] - - ErrorScope.Protect Range.range0 - (fun () -> - let locations = findBreakPoints() - - if pos.Column = 0 then - // we have a breakpoint that was set with mouse at line start - match locations |> List.filter (fun m -> m.StartLine = m.EndLine && pos.Line = m.StartLine) with - | [] -> - match locations |> List.filter (fun m -> rangeContainsPos m pos) with - | [] -> - match locations |> List.filter (fun m -> rangeBeforePos m pos |> not) with - | [] -> Seq.tryHead locations - | locationsAfterPos -> Seq.tryHead locationsAfterPos - | coveringLocations -> Seq.tryLast coveringLocations - | locationsOnSameLine -> Seq.tryHead locationsOnSameLine - else - match locations |> List.filter (fun m -> rangeContainsPos m pos) with - | [] -> - match locations |> List.filter (fun m -> rangeBeforePos m pos |> not) with - | [] -> Seq.tryHead locations - | locationsAfterPos -> Seq.tryHead locationsAfterPos - | coveringLocations -> Seq.tryLast coveringLocations) - (fun msg -> - Trace.TraceInformation(sprintf "FCS: recovering from error in ValidateBreakpointLocationImpl: '%s'" msg) - None) - - /// When these files appear or disappear the configuration for the current project is invalidated. - member scope.DependencyFiles = dependencyFiles - - member scope.FileName = - match input with - | Some (ParsedInput.ImplFile (ParsedImplFileInput (fileName = modname))) - | Some (ParsedInput.SigFile (ParsedSigFileInput (fileName = modname))) -> modname - | _ -> "" - - // Get items for the navigation drop down bar - member scope.GetNavigationItems() = - // This does not need to be run on the background thread - scope.GetNavigationItemsImpl() - - member scope.ValidateBreakpointLocation pos = - // This does not need to be run on the background thread - scope.ValidateBreakpointLocationImpl pos - -type ModuleKind = { IsAutoOpen: bool; HasModuleSuffix: bool } - -[] -type EntityKind = - | Attribute - | Type - | FunctionOrValue of isActivePattern: bool - | Module of ModuleKind - override x.ToString() = sprintf "%A" x - -module UntypedParseImpl = - - let emptyStringSet = HashSet() - - let GetRangeOfExprLeftOfDot(pos: pos, parseTreeOpt) = - match parseTreeOpt with - | None -> None - | Some parseTree -> - let CheckLongIdent(longIdent: LongIdent) = - // find the longest prefix before the "pos" dot - let mutable r = (List.head longIdent).idRange - let mutable couldBeBeforeFront = true - for i in longIdent do - if posGeq pos i.idRange.End then - r <- unionRanges r i.idRange - couldBeBeforeFront <- false - couldBeBeforeFront, r - - AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with - member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = - let expr = expr // fix debugger locals - match expr with - | SynExpr.LongIdent (_, LongIdentWithDots(longIdent, _), _altNameRefCell, _range) -> - let _, r = CheckLongIdent longIdent - Some r - | SynExpr.LongIdentSet (LongIdentWithDots(longIdent, _), synExpr, _range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - else - let _, r = CheckLongIdent longIdent - Some r - | SynExpr.DotGet (synExpr, _dotm, LongIdentWithDots(longIdent, _), _range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - else - let inFront, r = CheckLongIdent longIdent - if inFront then - Some (synExpr.Range) - else - // see comment below for SynExpr.DotSet - Some ((unionRanges synExpr.Range r)) - | SynExpr.Set (synExpr, synExpr2, range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - elif AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then - traverseSynExpr synExpr2 - else - Some range - | SynExpr.DotSet (synExpr, LongIdentWithDots(longIdent, _), synExpr2, _range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - elif AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then - traverseSynExpr synExpr2 - else - let inFront, r = CheckLongIdent longIdent - if inFront then - Some (synExpr.Range) - else - // f(0).X.Y.Z - // ^ - // - r has this value - // ---- synExpr.Range has this value - // ------ we want this value - Some ((unionRanges synExpr.Range r)) - | SynExpr.DotNamedIndexedPropertySet (synExpr, LongIdentWithDots(longIdent, _), synExpr2, synExpr3, _range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - elif AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then - traverseSynExpr synExpr2 - elif AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr3.Range pos then - traverseSynExpr synExpr3 - else - let inFront, r = CheckLongIdent longIdent - if inFront then - Some (synExpr.Range) - else - Some ((unionRanges synExpr.Range r)) - | SynExpr.DiscardAfterMissingQualificationAfterDot (synExpr, _range) -> // get this for e.g. "bar()." - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - else - Some (synExpr.Range) - | SynExpr.FromParseError (synExpr, range) -> - if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then - traverseSynExpr synExpr - else - Some range - | SynExpr.App (ExprAtomicFlag.NonAtomic, true, (SynExpr.Ident ident), rhs, _) - when ident.idText = "op_ArrayLookup" - && not(AstTraversal.rangeContainsPosLeftEdgeInclusive rhs.Range pos) -> - match defaultTraverse expr with - | None -> - // (expr).(expr) is an ML-deprecated array lookup, but we want intellisense on the dot - // also want it for e.g. [|arr|].(0) - Some (expr.Range) - | x -> x // we found the answer deeper somewhere in the lhs - | SynExpr.Const (SynConst.Double(_), range) -> Some range - | _ -> defaultTraverse expr - }) - - /// searches for the expression island suitable for the evaluation by the debugger - let TryFindExpressionIslandInPosition(pos: pos, parseTreeOpt) = - match parseTreeOpt with - | None -> None - | Some parseTree -> - let getLidParts (lid : LongIdent) = - lid - |> Seq.takeWhile (fun i -> posGeq pos i.idRange.Start) - |> Seq.map (fun i -> i.idText) - |> Seq.toList - - // tries to locate simple expression island - // foundCandidate = false means that we are looking for the candidate expression - // foundCandidate = true - we found candidate (DotGet) and now drill down to the left part - let rec TryGetExpression foundCandidate expr = - match expr with - | SynExpr.Paren (e, _, _, _) when foundCandidate -> - TryGetExpression foundCandidate e - | SynExpr.LongIdent (_isOptional, LongIdentWithDots(lid, _), _altNameRefCell, _m) -> - getLidParts lid |> Some - | SynExpr.DotGet (leftPart, _, LongIdentWithDots(lid, _), _) when (rangeContainsPos (rangeOfLid lid) pos) || foundCandidate -> - // requested position is at the lid part of the DotGet - // process left part and append result to the result of processing lid - let leftPartResult = TryGetExpression true leftPart - match leftPartResult with - | Some leftPartResult -> - [ - yield! leftPartResult - yield! getLidParts lid - ] |> Some - | None -> None - | SynExpr.FromParseError (synExpr, _range) -> TryGetExpression foundCandidate synExpr - | _ -> None - - let rec walker = - { new AstTraversal.AstVisitorBase<_>() with - member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = - if rangeContainsPos expr.Range pos then - match TryGetExpression false expr with - | (Some parts) -> parts |> String.concat "." |> Some - | _ -> defaultTraverse expr - else - None } - AstTraversal.Traverse(pos, parseTree, walker) - - // Given a cursor position here: - // f(x) . ident - // ^ - // walk the AST to find the position here: - // f(x) . ident - // ^ - // On success, return Some (thatPos, boolTrueIfCursorIsAfterTheDotButBeforeTheIdentifier) - // If there's no dot, return None, so for example - // foo - // ^ - // would return None - // TODO would be great to unify this with GetRangeOfExprLeftOfDot above, if possible, as they are similar - let TryFindExpressionASTLeftOfDotLeftOfCursor(pos, parseTreeOpt) = - match parseTreeOpt with - | None -> None - | Some parseTree -> - let dive x = AstTraversal.dive x - let pick x = AstTraversal.pick pos x - let walker = - { new AstTraversal.AstVisitorBase<_>() with - member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = - let pick = pick expr.Range - let traverseSynExpr, defaultTraverse, expr = traverseSynExpr, defaultTraverse, expr // for debugging: debugger does not get object expression params as local vars - if not(rangeContainsPos expr.Range pos) then - match expr with - | SynExpr.DiscardAfterMissingQualificationAfterDot (e, _m) -> - // This happens with e.g. "f(x) . $" when you bring up a completion list a few spaces after a dot. The cursor is not 'in the parse tree', - // but the dive algorithm will dive down into this node, and this is the one case where we do want to give a result despite the cursor - // not properly being in a node. - match traverseSynExpr e with - | None -> Some (e.Range.End, false) - | r -> r - | _ -> - // This happens for e.g. "System.Console.[]$", where the ".[]" token is thrown away by the parser and we dive into the System.Console longId - // even though the cursor/dot is not in there. In those cases we want to return None, because there is not really a dot completion before - // the cursor location. - None - else - let rec traverseLidOrElse (optExprIfLeftOfLongId : SynExpr option) (LongIdentWithDots(lid, dots) as lidwd) = - let resultIfLeftOfLongId = - match optExprIfLeftOfLongId with - | None -> None - | Some e -> Some (e.Range.End, posGeq lidwd.Range.Start pos) - match dots |> List.mapi (fun i x -> i, x) |> List.rev |> List.tryFind (fun (_, m) -> posGt pos m.Start) with - | None -> resultIfLeftOfLongId - | Some (n, _) -> Some ((List.item n lid).idRange.End, (List.length lid = n+1) // foo.$ - || (posGeq (List.item (n+1) lid).idRange.Start pos)) // foo.$bar - match expr with - | SynExpr.LongIdent (_isOptional, lidwd, _altNameRefCell, _m) -> - traverseLidOrElse None lidwd - | SynExpr.LongIdentSet (lidwd, exprRhs, _m) -> - [ dive lidwd lidwd.Range (traverseLidOrElse None) - dive exprRhs exprRhs.Range traverseSynExpr - ] |> pick expr - | SynExpr.DotGet (exprLeft, dotm, lidwd, _m) -> - let afterDotBeforeLid = mkRange dotm.FileName dotm.End lidwd.Range.Start - [ dive exprLeft exprLeft.Range traverseSynExpr - dive exprLeft afterDotBeforeLid (fun e -> Some (e.Range.End, true)) - dive lidwd lidwd.Range (traverseLidOrElse (Some exprLeft)) - ] |> pick expr - | SynExpr.DotSet (exprLeft, lidwd, exprRhs, _m) -> - [ dive exprLeft exprLeft.Range traverseSynExpr - dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft)) - dive exprRhs exprRhs.Range traverseSynExpr - ] |> pick expr - | SynExpr.Set (exprLeft, exprRhs, _m) -> - [ dive exprLeft exprLeft.Range traverseSynExpr - dive exprRhs exprRhs.Range traverseSynExpr - ] |> pick expr - | SynExpr.NamedIndexedPropertySet (lidwd, exprIndexer, exprRhs, _m) -> - [ dive lidwd lidwd.Range (traverseLidOrElse None) - dive exprIndexer exprIndexer.Range traverseSynExpr - dive exprRhs exprRhs.Range traverseSynExpr - ] |> pick expr - | SynExpr.DotNamedIndexedPropertySet (exprLeft, lidwd, exprIndexer, exprRhs, _m) -> - [ dive exprLeft exprLeft.Range traverseSynExpr - dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft)) - dive exprIndexer exprIndexer.Range traverseSynExpr - dive exprRhs exprRhs.Range traverseSynExpr - ] |> pick expr - | SynExpr.Const (SynConst.Double(_), m) -> - if posEq m.End pos then - // the cursor is at the dot - Some (m.End, false) - else - // the cursor is left of the dot - None - | SynExpr.DiscardAfterMissingQualificationAfterDot (e, m) -> - match traverseSynExpr e with - | None -> - if posEq m.End pos then - // the cursor is at the dot - Some (e.Range.End, false) - else - // the cursor is left of the dot - None - | r -> r - | SynExpr.App (ExprAtomicFlag.NonAtomic, true, (SynExpr.Ident ident), lhs, _m) - when ident.idText = "op_ArrayLookup" - && not(AstTraversal.rangeContainsPosLeftEdgeInclusive lhs.Range pos) -> - match defaultTraverse expr with - | None -> - // (expr).(expr) is an ML-deprecated array lookup, but we want intellisense on the dot - // also want it for e.g. [|arr|].(0) - Some (lhs.Range.End, false) - | x -> x // we found the answer deeper somewhere in the lhs - | _ -> defaultTraverse expr } - AstTraversal.Traverse(pos, parseTree, walker) - - let GetEntityKind (pos: pos, input: ParsedInput) : EntityKind option = - let (|ConstructorPats|) = function - | Pats ps -> ps - | NamePatPairs(xs, _) -> List.map snd xs - - /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException - let rec (|Sequentials|_|) = function - | SynExpr.Sequential (_, _, e, Sequentials es, _) -> Some (e :: es) - | SynExpr.Sequential (_, _, e1, e2, _) -> Some [e1; e2] - | _ -> None - - let inline isPosInRange range = Range.rangeContainsPos range pos - - let inline ifPosInRange range f = - if isPosInRange range then f() - else None - - let rec walkImplFileInput (ParsedImplFileInput (modules = moduleOrNamespaceList)) = - List.tryPick (walkSynModuleOrNamespace true) moduleOrNamespaceList - - and walkSynModuleOrNamespace isTopLevel (SynModuleOrNamespace(_, _, _, decls, _, Attributes attrs, _, r)) = - List.tryPick walkAttribute attrs - |> Option.orElse (ifPosInRange r (fun _ -> List.tryPick (walkSynModuleDecl isTopLevel) decls)) - - and walkAttribute (attr: SynAttribute) = - if isPosInRange attr.Range then Some EntityKind.Attribute else None - |> Option.orElse (walkExprWithKind (Some EntityKind.Type) attr.ArgExpr) - - and walkTypar (Typar (ident, _, _)) = ifPosInRange ident.idRange (fun _ -> Some EntityKind.Type) - - and walkTyparDecl (SynTyparDecl.TyparDecl (Attributes attrs, typar)) = - List.tryPick walkAttribute attrs - |> Option.orElse (walkTypar typar) - - and walkTypeConstraint = function - | SynTypeConstraint.WhereTyparDefaultsToType (t1, t2, _) -> walkTypar t1 |> Option.orElse (walkType t2) - | SynTypeConstraint.WhereTyparIsValueType(t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparIsReferenceType(t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparIsUnmanaged(t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparSupportsNull (t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparIsComparable(t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t - | SynTypeConstraint.WhereTyparSubtypeOfType(t, ty, _) -> walkTypar t |> Option.orElse (walkType ty) - | SynTypeConstraint.WhereTyparSupportsMember(ts, sign, _) -> - List.tryPick walkType ts |> Option.orElse (walkMemberSig sign) - | SynTypeConstraint.WhereTyparIsEnum(t, ts, _) -> walkTypar t |> Option.orElse (List.tryPick walkType ts) - | SynTypeConstraint.WhereTyparIsDelegate(t, ts, _) -> walkTypar t |> Option.orElse (List.tryPick walkType ts) - - and walkPatWithKind (kind: EntityKind option) = function - | SynPat.Ands (pats, _) -> List.tryPick walkPat pats - | SynPat.Named(SynPat.Wild nameRange as pat, _, _, _, _) -> - if isPosInRange nameRange then None - else walkPat pat - | SynPat.Typed(pat, t, _) -> walkPat pat |> Option.orElse (walkType t) - | SynPat.Attrib(pat, Attributes attrs, _) -> walkPat pat |> Option.orElse (List.tryPick walkAttribute attrs) - | SynPat.Or(pat1, pat2, _) -> List.tryPick walkPat [pat1; pat2] - | SynPat.LongIdent(_, _, typars, ConstructorPats pats, _, r) -> - ifPosInRange r (fun _ -> kind) - |> Option.orElse ( - typars - |> Option.bind (fun (SynValTyparDecls (typars, _, constraints)) -> - List.tryPick walkTyparDecl typars - |> Option.orElse (List.tryPick walkTypeConstraint constraints))) - |> Option.orElse (List.tryPick walkPat pats) - | SynPat.Tuple(_, pats, _) -> List.tryPick walkPat pats - | SynPat.Paren(pat, _) -> walkPat pat - | SynPat.ArrayOrList(_, pats, _) -> List.tryPick walkPat pats - | SynPat.IsInst(t, _) -> walkType t - | SynPat.QuoteExpr(e, _) -> walkExpr e - | _ -> None - - and walkPat = walkPatWithKind None - - and walkBinding (SynBinding.Binding(_, _, _, _, Attributes attrs, _, _, pat, returnInfo, e, _, _)) = - List.tryPick walkAttribute attrs - |> Option.orElse (walkPat pat) - |> Option.orElse (walkExpr e) - |> Option.orElse ( - match returnInfo with - | Some (SynBindingReturnInfo (t, _, _)) -> walkType t - | None -> None) - - and walkInterfaceImpl (InterfaceImpl(_, bindings, _)) = - List.tryPick walkBinding bindings - - and walkIndexerArg = function - | SynIndexerArg.One (e, _, _) -> walkExpr e - | SynIndexerArg.Two(e1, _, e2, _, _, _) -> List.tryPick walkExpr [e1; e2] - - and walkType = function - | SynType.LongIdent ident -> - // we protect it with try..with because System.Exception : rangeOfLidwd may raise - // at FSharp.Compiler.Ast.LongIdentWithDots.get_Range() in D:\j\workspace\release_ci_pa---3f142ccc\src\fsharp\ast.fs: line 156 - try ifPosInRange ident.Range (fun _ -> Some EntityKind.Type) with _ -> None - | SynType.App(ty, _, types, _, _, _, _) -> - walkType ty |> Option.orElse (List.tryPick walkType types) - | SynType.LongIdentApp(_, _, _, types, _, _, _) -> List.tryPick walkType types - | SynType.Tuple(_, ts, _) -> ts |> List.tryPick (fun (_, t) -> walkType t) - | SynType.Array(_, t, _) -> walkType t - | SynType.Fun(t1, t2, _) -> walkType t1 |> Option.orElse (walkType t2) - | SynType.WithGlobalConstraints(t, _, _) -> walkType t - | SynType.HashConstraint(t, _) -> walkType t - | SynType.MeasureDivide(t1, t2, _) -> walkType t1 |> Option.orElse (walkType t2) - | SynType.MeasurePower(t, _, _) -> walkType t - | _ -> None - - and walkClause (Clause(pat, e1, e2, _, _)) = - walkPatWithKind (Some EntityKind.Type) pat - |> Option.orElse (walkExpr e2) - |> Option.orElse (Option.bind walkExpr e1) - - and walkExprWithKind (parentKind: EntityKind option) = function - | SynExpr.LongIdent (_, LongIdentWithDots(_, dotRanges), _, r) -> - match dotRanges with - | [] when isPosInRange r -> parentKind |> Option.orElse (Some (EntityKind.FunctionOrValue false)) - | firstDotRange :: _ -> - let firstPartRange = - Range.mkRange "" r.Start (Range.mkPos firstDotRange.StartLine (firstDotRange.StartColumn - 1)) - if isPosInRange firstPartRange then - parentKind |> Option.orElse (Some (EntityKind.FunctionOrValue false)) - else None - | _ -> None - | SynExpr.Paren (e, _, _, _) -> walkExprWithKind parentKind e - | SynExpr.Quote (_, _, e, _, _) -> walkExprWithKind parentKind e - | SynExpr.Typed (e, _, _) -> walkExprWithKind parentKind e - | SynExpr.Tuple (_, es, _, _) -> List.tryPick (walkExprWithKind parentKind) es - | SynExpr.ArrayOrList (_, es, _) -> List.tryPick (walkExprWithKind parentKind) es - | SynExpr.Record (_, _, fields, r) -> - ifPosInRange r (fun _ -> - fields |> List.tryPick (fun (_, e, _) -> e |> Option.bind (walkExprWithKind parentKind))) - | SynExpr.New (_, t, e, _) -> walkExprWithKind parentKind e |> Option.orElse (walkType t) - | SynExpr.ObjExpr (ty, _, bindings, ifaces, _, _) -> - walkType ty - |> Option.orElse (List.tryPick walkBinding bindings) - |> Option.orElse (List.tryPick walkInterfaceImpl ifaces) - | SynExpr.While (_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.For (_, _, e1, _, e2, e3, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2; e3] - | SynExpr.ForEach (_, _, _, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) -> walkExprWithKind parentKind e - | SynExpr.CompExpr (_, _, e, _) -> walkExprWithKind parentKind e - | SynExpr.Lambda (_, _, _, e, _) -> walkExprWithKind parentKind e - | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> - List.tryPick walkClause synMatchClauseList - | SynExpr.Match (_, e, synMatchClauseList, _) -> - walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkClause synMatchClauseList) - | SynExpr.Do (e, _) -> walkExprWithKind parentKind e - | SynExpr.Assert (e, _) -> walkExprWithKind parentKind e - | SynExpr.App (_, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.TypeApp (e, _, tys, _, _, _, _) -> - walkExprWithKind (Some EntityKind.Type) e |> Option.orElse (List.tryPick walkType tys) - | SynExpr.LetOrUse (_, _, bindings, e, _) -> List.tryPick walkBinding bindings |> Option.orElse (walkExprWithKind parentKind e) - | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkClause clauses) - | SynExpr.TryFinally (e1, e2, _, _, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.Lazy (e, _) -> walkExprWithKind parentKind e - | Sequentials es -> List.tryPick (walkExprWithKind parentKind) es - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, _) -> - List.tryPick (walkExprWithKind parentKind) [e1; e2] |> Option.orElse (match e3 with None -> None | Some e -> walkExprWithKind parentKind e) - | SynExpr.Ident ident -> ifPosInRange ident.idRange (fun _ -> Some (EntityKind.FunctionOrValue false)) - | SynExpr.LongIdentSet (_, e, _) -> walkExprWithKind parentKind e - | SynExpr.DotGet (e, _, _, _) -> walkExprWithKind parentKind e - | SynExpr.DotSet (e, _, _, _) -> walkExprWithKind parentKind e - | SynExpr.Set (e, _, _) -> walkExprWithKind parentKind e - | SynExpr.DotIndexedGet (e, args, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args) - | SynExpr.DotIndexedSet (e, args, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args) - | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2; e3] - | SynExpr.TypeTest (e, t, _) -> walkExprWithKind parentKind e |> Option.orElse (walkType t) - | SynExpr.Upcast (e, t, _) -> walkExprWithKind parentKind e |> Option.orElse (walkType t) - | SynExpr.Downcast (e, t, _) -> walkExprWithKind parentKind e |> Option.orElse (walkType t) - | SynExpr.InferredUpcast (e, _) -> walkExprWithKind parentKind e - | SynExpr.InferredDowncast (e, _) -> walkExprWithKind parentKind e - | SynExpr.AddressOf (_, e, _, _) -> walkExprWithKind parentKind e - | SynExpr.JoinIn (e1, _, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.YieldOrReturn (_, e, _) -> walkExprWithKind parentKind e - | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExprWithKind parentKind e - | SynExpr.Match (_, e, synMatchClauseList, _) - | SynExpr.MatchBang (_, e, synMatchClauseList, _) -> - walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkClause synMatchClauseList) - | SynExpr.LetOrUseBang (_, _, _, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] - | SynExpr.DoBang (e, _) -> walkExprWithKind parentKind e - | SynExpr.TraitCall (ts, sign, e, _) -> - List.tryPick walkTypar ts - |> Option.orElse (walkMemberSig sign) - |> Option.orElse (walkExprWithKind parentKind e) - | _ -> None - - and walkExpr = walkExprWithKind None - - and walkSimplePat = function - | SynSimplePat.Attrib (pat, Attributes attrs, _) -> - walkSimplePat pat |> Option.orElse (List.tryPick walkAttribute attrs) - | SynSimplePat.Typed(pat, t, _) -> walkSimplePat pat |> Option.orElse (walkType t) - | _ -> None - - and walkField (SynField.Field(Attributes attrs, _, _, t, _, _, _, _)) = - List.tryPick walkAttribute attrs |> Option.orElse (walkType t) - - and walkValSig (SynValSig.ValSpfn(Attributes attrs, _, _, t, _, _, _, _, _, _, _)) = - List.tryPick walkAttribute attrs |> Option.orElse (walkType t) - - and walkMemberSig = function - | SynMemberSig.Inherit (t, _) -> walkType t - | SynMemberSig.Member(vs, _, _) -> walkValSig vs - | SynMemberSig.Interface(t, _) -> walkType t - | SynMemberSig.ValField(f, _) -> walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (info, repr, memberSigs, _), _) -> - walkComponentInfo false info - |> Option.orElse (walkTypeDefnSigRepr repr) - |> Option.orElse (List.tryPick walkMemberSig memberSigs) - - and walkMember = function - | SynMemberDefn.AbstractSlot (valSig, _, _) -> walkValSig valSig - | SynMemberDefn.Member(binding, _) -> walkBinding binding - | SynMemberDefn.ImplicitCtor(_, Attributes attrs, SynSimplePats.SimplePats(simplePats, _), _, _) -> - List.tryPick walkAttribute attrs |> Option.orElse (List.tryPick walkSimplePat simplePats) - | SynMemberDefn.ImplicitInherit(t, e, _, _) -> walkType t |> Option.orElse (walkExpr e) - | SynMemberDefn.LetBindings(bindings, _, _, _) -> List.tryPick walkBinding bindings - | SynMemberDefn.Interface(t, members, _) -> - walkType t |> Option.orElse (members |> Option.bind (List.tryPick walkMember)) - | SynMemberDefn.Inherit(t, _, _) -> walkType t - | SynMemberDefn.ValField(field, _) -> walkField field - | SynMemberDefn.NestedType(tdef, _, _) -> walkTypeDefn tdef - | SynMemberDefn.AutoProperty(Attributes attrs, _, _, t, _, _, _, _, e, _, _) -> - List.tryPick walkAttribute attrs - |> Option.orElse (Option.bind walkType t) - |> Option.orElse (walkExpr e) - | _ -> None - - and walkEnumCase (EnumCase(Attributes attrs, _, _, _, _)) = List.tryPick walkAttribute attrs - - and walkUnionCaseType = function - | SynUnionCaseType.UnionCaseFields fields -> List.tryPick walkField fields - | SynUnionCaseType.UnionCaseFullType(t, _) -> walkType t - - and walkUnionCase (UnionCase(Attributes attrs, _, t, _, _, _)) = - List.tryPick walkAttribute attrs |> Option.orElse (walkUnionCaseType t) - - and walkTypeDefnSimple = function - | SynTypeDefnSimpleRepr.Enum (cases, _) -> List.tryPick walkEnumCase cases - | SynTypeDefnSimpleRepr.Union(_, cases, _) -> List.tryPick walkUnionCase cases - | SynTypeDefnSimpleRepr.Record(_, fields, _) -> List.tryPick walkField fields - | SynTypeDefnSimpleRepr.TypeAbbrev(_, t, _) -> walkType t - | _ -> None - - and walkComponentInfo isModule (ComponentInfo(Attributes attrs, typars, constraints, _, _, _, _, r)) = - if isModule then None else ifPosInRange r (fun _ -> Some EntityKind.Type) - |> Option.orElse ( - List.tryPick walkAttribute attrs - |> Option.orElse (List.tryPick walkTyparDecl typars) - |> Option.orElse (List.tryPick walkTypeConstraint constraints)) - - and walkTypeDefnRepr = function - | SynTypeDefnRepr.ObjectModel (_, defns, _) -> List.tryPick walkMember defns - | SynTypeDefnRepr.Simple(defn, _) -> walkTypeDefnSimple defn - | SynTypeDefnRepr.Exception(_) -> None - - and walkTypeDefnSigRepr = function - | SynTypeDefnSigRepr.ObjectModel (_, defns, _) -> List.tryPick walkMemberSig defns - | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn - | SynTypeDefnSigRepr.Exception(_) -> None - - and walkTypeDefn (TypeDefn (info, repr, members, _)) = - walkComponentInfo false info - |> Option.orElse (walkTypeDefnRepr repr) - |> Option.orElse (List.tryPick walkMember members) - - and walkSynModuleDecl isTopLevel (decl: SynModuleDecl) = - match decl with - | SynModuleDecl.NamespaceFragment fragment -> walkSynModuleOrNamespace isTopLevel fragment - | SynModuleDecl.NestedModule(info, _, modules, _, range) -> - walkComponentInfo true info - |> Option.orElse (ifPosInRange range (fun _ -> List.tryPick (walkSynModuleDecl false) modules)) - | SynModuleDecl.Open _ -> None - | SynModuleDecl.Let (_, bindings, _) -> List.tryPick walkBinding bindings - | SynModuleDecl.DoExpr (_, expr, _) -> walkExpr expr - | SynModuleDecl.Types (types, _) -> List.tryPick walkTypeDefn types - | _ -> None - - match input with - | ParsedInput.SigFile _ -> None - | ParsedInput.ImplFile input -> walkImplFileInput input - - type internal TS = AstTraversal.TraverseStep - /// Matches the most nested [< and >] pair. - let insideAttributeApplicationRegex = Regex(@"(?<=\[\<)(?(.*?))(?=\>\])", RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) - - /// Try to determine completion context for the given pair (row, columns) - let TryGetCompletionContext (pos, parsedInput: ParsedInput, lineStr: string) : CompletionContext option = - - match GetEntityKind(pos, parsedInput) with - | Some EntityKind.Attribute -> Some CompletionContext.AttributeApplication - | _ -> - - let parseLid (LongIdentWithDots(lid, dots)) = - let rec collect plid (parts : Ident list) (dots : range list) = - match parts, dots with - | [], _ -> Some (plid, None) - | x :: xs, ds -> - if rangeContainsPos x.idRange pos then - // pos lies with the range of current identifier - let s = x.idText.Substring(0, pos.Column - x.idRange.Start.Column) - let residue = if s.Length <> 0 then Some s else None - Some (plid, residue) - elif posGt x.idRange.Start pos then - // can happen if caret is placed after dot but before the existing identifier A. $ B - // return accumulated plid with no residue - Some (plid, None) - else - match ds with - | [] -> - // pos lies after the id and no dots found - return accumulated plid and current id as residue - Some (plid, Some (x.idText)) - | d :: ds -> - if posGeq pos d.End then - // pos lies after the dot - proceed to the next identifier - collect ((x.idText) :: plid) xs ds - else - // pos after the id but before the dot - // A $.B - return nothing - None - - match collect [] lid dots with - | Some (parts, residue) -> - Some ((List.rev parts), residue) - | None -> None - - let (|Class|Interface|Struct|Unknown|Invalid|) synAttributes = - let (|SynAttr|_|) name (attr : SynAttribute) = - match attr with - | {TypeName = LongIdentWithDots([x], _)} when x.idText = name -> Some () - | _ -> None - - let rec getKind isClass isInterface isStruct = - function - | [] -> isClass, isInterface, isStruct - | (SynAttr "Class") :: xs -> getKind true isInterface isStruct xs - | (SynAttr "AbstractClass") :: xs -> getKind true isInterface isStruct xs - | (SynAttr "Interface") :: xs -> getKind isClass true isStruct xs - | (SynAttr "Struct") :: xs -> getKind isClass isInterface true xs - | _ :: xs -> getKind isClass isInterface isStruct xs - - match getKind false false false synAttributes with - | false, false, false -> Unknown - | true, false, false -> Class - | false, true, false -> Interface - | false, false, true -> Struct - | _ -> Invalid - - let GetCompletionContextForInheritSynMember ((ComponentInfo(Attributes synAttributes, _, _, _, _, _, _, _)), typeDefnKind : SynTypeDefnKind, completionPath) = - - let success k = Some (CompletionContext.Inherit (k, completionPath)) - - // if kind is specified - take it - // if kind is non-specified - // - try to obtain it from attribute - // - if no attributes present - infer kind from members - match typeDefnKind with - | TyconClass -> - match synAttributes with - | Class | Unknown -> success InheritanceContext.Class - | _ -> Some CompletionContext.Invalid // non-matching attributes - | TyconInterface -> - match synAttributes with - | Interface | Unknown -> success InheritanceContext.Interface - | _ -> Some CompletionContext.Invalid // non-matching attributes - | TyconStruct -> - // display nothing for structs - Some CompletionContext.Invalid - | TyconUnspecified -> - match synAttributes with - | Class -> success InheritanceContext.Class - | Interface -> success InheritanceContext.Interface - | Unknown -> - // user do not specify kind explicitly or via attributes - success InheritanceContext.Unknown - | _ -> - // unable to uniquely detect kind from the attributes - return invalid context - Some CompletionContext.Invalid - | _ -> None - - let (|Operator|_|) name e = - match e with - | SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident ident, lhs, _), rhs, _) - when ident.idText = name -> Some (lhs, rhs) - | _ -> None - - // checks if we are in rhs of the range operator - let isInRhsOfRangeOp (p : AstTraversal.TraversePath) = - match p with - | TS.Expr(Operator "op_Range" _) :: _ -> true - | _ -> false - - let (|Setter|_|) e = - match e with - | Operator "op_Equality" (SynExpr.Ident id, _) -> Some id - | _ -> None - - let findSetters argList = - match argList with - | SynExpr.Paren (SynExpr.Tuple (false, parameters, _, _), _, _, _) -> - let setters = HashSet() - for p in parameters do - match p with - | Setter id -> ignore(setters.Add id.idText) - | _ -> () - setters - | _ -> emptyStringSet - - let endOfLastIdent (lid: LongIdentWithDots) = - let last = List.last lid.Lid - last.idRange.End - - let endOfClosingTokenOrLastIdent (mClosing: range option) (lid : LongIdentWithDots) = - match mClosing with - | Some m -> m.End - | None -> endOfLastIdent lid - - let endOfClosingTokenOrIdent (mClosing: range option) (id : Ident) = - match mClosing with - | Some m -> m.End - | None -> id.idRange.End - - let (|NewObjectOrMethodCall|_|) e = - match e with - | (SynExpr.New (_, SynType.LongIdent typeName, arg, _)) -> - // new A() - Some (endOfLastIdent typeName, findSetters arg) - | (SynExpr.New (_, SynType.App(SynType.LongIdent typeName, _, _, _, mGreaterThan, _, _), arg, _)) -> - // new A<_>() - Some (endOfClosingTokenOrLastIdent mGreaterThan typeName, findSetters arg) - | (SynExpr.App (_, false, SynExpr.Ident id, arg, _)) -> - // A() - Some (id.idRange.End, findSetters arg) - | (SynExpr.App (_, false, SynExpr.TypeApp (SynExpr.Ident id, _, _, _, mGreaterThan, _, _), arg, _)) -> - // A<_>() - Some (endOfClosingTokenOrIdent mGreaterThan id, findSetters arg) - | (SynExpr.App (_, false, SynExpr.LongIdent (_, lid, _, _), arg, _)) -> - // A.B() - Some (endOfLastIdent lid, findSetters arg) - | (SynExpr.App (_, false, SynExpr.TypeApp (SynExpr.LongIdent (_, lid, _, _), _, _, _, mGreaterThan, _, _), arg, _)) -> - // A.B<_>() - Some (endOfClosingTokenOrLastIdent mGreaterThan lid, findSetters arg) - | _ -> None - - let isOnTheRightOfComma (elements: SynExpr list) (commas: range list) current = - let rec loop elements (commas: range list) = - match elements with - | x :: xs -> - match commas with - | c :: cs -> - if x === current then posLt c.End pos || posEq c.End pos - else loop xs cs - | _ -> false - | _ -> false - loop elements commas - - let (|PartOfParameterList|_|) precedingArgument path = - match path with - | TS.Expr(SynExpr.Paren _) :: TS.Expr(NewObjectOrMethodCall args) :: _ -> - if Option.isSome precedingArgument then None else Some args - | TS.Expr(SynExpr.Tuple (false, elements, commas, _)) :: TS.Expr(SynExpr.Paren _) :: TS.Expr(NewObjectOrMethodCall args) :: _ -> - match precedingArgument with - | None -> Some args - | Some e -> - // if expression is passed then - // 1. find it in among elements of the tuple - // 2. find corresponding comma - // 3. check that current position is past the comma - // this is used for cases like (a = something-here.) if the cursor is after . - // in this case this is not object initializer completion context - if isOnTheRightOfComma elements commas e then Some args else None - | _ -> None - - let walker = - { - new AstTraversal.AstVisitorBase<_>() with - member __.VisitExpr(path, _, defaultTraverse, expr) = - - if isInRhsOfRangeOp path then - match defaultTraverse expr with - | None -> Some CompletionContext.RangeOperator // nothing was found - report that we were in the context of range operator - | x -> x // ok, we found something - return it - else - match expr with - // new A($) - | SynExpr.Const (SynConst.Unit, m) when rangeContainsPos m pos -> - match path with - | TS.Expr(NewObjectOrMethodCall args) :: _ -> - Some (CompletionContext.ParameterList args) - | _ -> - defaultTraverse expr - // new (... A$) - | SynExpr.Ident id when id.idRange.End = pos -> - match path with - | PartOfParameterList None args -> - Some (CompletionContext.ParameterList args) - | _ -> - defaultTraverse expr - // new (A$ = 1) - // new (A = 1, $) - | Setter id when id.idRange.End = pos || rangeBeforePos expr.Range pos -> - let precedingArgument = if id.idRange.End = pos then None else Some expr - match path with - | PartOfParameterList precedingArgument args-> - Some (CompletionContext.ParameterList args) - | _ -> - defaultTraverse expr - - | _ -> defaultTraverse expr - - member __.VisitRecordField(path, copyOpt, field) = - let contextFromTreePath completionPath = - // detect records usage in constructor - match path with - | TS.Expr(_) :: TS.Binding(_) :: TS.MemberDefn(_) :: TS.TypeDefn(SynTypeDefn.TypeDefn(ComponentInfo(_, _, _, [id], _, _, _, _), _, _, _)) :: _ -> - RecordContext.Constructor(id.idText) - | _ -> RecordContext.New completionPath - match field with - | Some field -> - match parseLid field with - | Some completionPath -> - let recordContext = - match copyOpt with - | Some (s : SynExpr) -> RecordContext.CopyOnUpdate(s.Range, completionPath) - | None -> contextFromTreePath completionPath - Some (CompletionContext.RecordField recordContext) - | None -> None - | None -> - let recordContext = - match copyOpt with - | Some s -> RecordContext.CopyOnUpdate(s.Range, ([], None)) - | None -> contextFromTreePath ([], None) - Some (CompletionContext.RecordField recordContext) - - member __.VisitInheritSynMemberDefn(componentInfo, typeDefnKind, synType, _members, _range) = - match synType with - | SynType.LongIdent lidwd -> - match parseLid lidwd with - | Some completionPath -> GetCompletionContextForInheritSynMember (componentInfo, typeDefnKind, completionPath) - | None -> Some (CompletionContext.Invalid) // A $ .B -> no completion list - - | _ -> None - - member __.VisitBinding(defaultTraverse, (Binding(headPat = headPat) as synBinding)) = - - let visitParam = function - | SynPat.Named (range = range) when rangeContainsPos range pos -> - // parameter without type hint, no completion - Some CompletionContext.Invalid - | SynPat.Typed(SynPat.Named(SynPat.Wild range, _, _, _, _), _, _) when rangeContainsPos range pos -> - // parameter with type hint, but we are on its name, no completion - Some CompletionContext.Invalid - | _ -> defaultTraverse synBinding - - match headPat with - | SynPat.LongIdent(longDotId = lidwd) when rangeContainsPos lidwd.Range pos -> - // let fo|o x = () - Some CompletionContext.Invalid - | SynPat.LongIdent(_, _, _, ctorArgs, _, _) -> - match ctorArgs with - | SynConstructorArgs.Pats pats -> - pats |> List.tryPick (fun pat -> - match pat with - | SynPat.Paren(pat, _) -> - match pat with - | SynPat.Tuple(_, pats, _) -> - pats |> List.tryPick visitParam - | _ -> visitParam pat - | SynPat.Wild range when rangeContainsPos range pos -> - // let foo (x| - Some CompletionContext.Invalid - | _ -> visitParam pat - ) - | _ -> defaultTraverse synBinding - | SynPat.Named(range = range) when rangeContainsPos range pos -> - // let fo|o = 1 - Some CompletionContext.Invalid - | _ -> defaultTraverse synBinding - - member __.VisitHashDirective range = - if rangeContainsPos range pos then Some CompletionContext.Invalid - else None - - member __.VisitModuleOrNamespace(SynModuleOrNamespace(longId = idents)) = - match List.tryLast idents with - | Some lastIdent when pos.Line = lastIdent.idRange.EndLine && lastIdent.idRange.EndColumn >= 0 && pos.Column <= lineStr.Length -> - let stringBetweenModuleNameAndPos = lineStr.[lastIdent.idRange.EndColumn..pos.Column - 1] - if stringBetweenModuleNameAndPos |> Seq.forall (fun x -> x = ' ' || x = '.') then - Some CompletionContext.Invalid - else None - | _ -> None - - member __.VisitComponentInfo(ComponentInfo(range = range)) = - if rangeContainsPos range pos then Some CompletionContext.Invalid - else None - - member __.VisitLetOrUse(_, _, bindings, range) = - match bindings with - | [] when range.StartLine = pos.Line -> Some CompletionContext.Invalid - | _ -> None - - member __.VisitSimplePats pats = - pats |> List.tryPick (fun pat -> - match pat with - | SynSimplePat.Id(range = range) - | SynSimplePat.Typed(SynSimplePat.Id(range = range), _, _) when rangeContainsPos range pos -> - Some CompletionContext.Invalid - | _ -> None) - - member __.VisitModuleDecl(defaultTraverse, decl) = - match decl with - | SynModuleDecl.Open(_, m) -> - // in theory, this means we're "in an open" - // in practice, because the parse tree/walkers do not handle attributes well yet, need extra check below to ensure not e.g. $here$ - // open System - // [ defaultTraverse decl - - member __.VisitType(defaultTraverse, ty) = - match ty with - | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> - Some CompletionContext.PatternType - | _ -> defaultTraverse ty - } - - AstTraversal.Traverse(pos, parsedInput, walker) - // Uncompleted attribute applications are not presented in the AST in any way. So, we have to parse source string. - |> Option.orElseWith (fun _ -> - let cutLeadingAttributes (str: string) = - // cut off leading attributes, i.e. we cut "[]" to " >]" - match str.LastIndexOf ';' with - | -1 -> str - | idx when idx < str.Length -> str.[idx + 1..].TrimStart() - | _ -> "" - - let isLongIdent = Seq.forall (fun c -> IsIdentifierPartCharacter c || c = '.' || c = ':') // ':' may occur in "[]" - - // match the most nested paired [< and >] first - let matches = - insideAttributeApplicationRegex.Matches lineStr - |> Seq.cast - |> Seq.filter (fun m -> m.Index <= pos.Column && m.Index + m.Length >= pos.Column) - |> Seq.toArray - - if not (Array.isEmpty matches) then - matches - |> Seq.tryPick (fun m -> - let g = m.Groups.["attribute"] - let col = pos.Column - g.Index - if col >= 0 && col < g.Length then - let str = g.Value.Substring(0, col).TrimStart() // cut other rhs attributes - let str = cutLeadingAttributes str - if isLongIdent str then - Some CompletionContext.AttributeApplication - else None - else None) - else - // Paired [< and >] were not found, try to determine that we are after [< without closing >] - match lineStr.LastIndexOf("[<", StringComparison.Ordinal) with - | -1 -> None - | openParenIndex when pos.Column >= openParenIndex + 2 -> - let str = lineStr.[openParenIndex + 2..pos.Column - 1].TrimStart() - let str = cutLeadingAttributes str - if isLongIdent str then - Some CompletionContext.AttributeApplication - else None - | _ -> None) - - /// Check if we are at an "open" declaration - let GetFullNameOfSmallestModuleOrNamespaceAtPoint (parsedInput: ParsedInput, pos: pos) = - let mutable path = [] - let visitor = - { new AstTraversal.AstVisitorBase() with - override this.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = - // don't need to keep going, namespaces and modules never appear inside Exprs - None - override this.VisitModuleOrNamespace(SynModuleOrNamespace(longId = longId; range = range)) = - if rangeContainsPos range pos then - path <- path @ longId - None // we should traverse the rest of the AST to find the smallest module - } - AstTraversal.Traverse(pos, parsedInput, visitor) |> ignore - path |> List.map (fun x -> x.idText) |> List.toArray diff --git a/src/fsharp/service/ServiceUntypedParse.fsi b/src/fsharp/service/ServiceUntypedParse.fsi deleted file mode 100755 index 8a88f766c86..00000000000 --- a/src/fsharp/service/ServiceUntypedParse.fsi +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -//---------------------------------------------------------------------------- -// API to the compiler as an incremental service for parsing, -// type checking and intellisense-like environment-reporting. -//---------------------------------------------------------------------------- - -namespace FSharp.Compiler.SourceCodeServices - -open System.Collections.Generic -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.ErrorLogger - -[] -/// Represents the results of parsing an F# file -type public FSharpParseFileResults = - - /// The syntax tree resulting from the parse - member ParseTree : Ast.ParsedInput option - - /// Notable parse info for ParameterInfo at a given location - member FindNoteworthyParamInfoLocations : pos:pos -> FSharpNoteworthyParamInfoLocations option - - /// Name of the file for which this information were created - member FileName : string - - /// Get declared items and the selected item at the specified location - member GetNavigationItems : unit -> FSharpNavigationItems - - /// Return the inner-most range associated with a possible breakpoint location - member ValidateBreakpointLocation : pos:pos -> range option - - /// When these files change then the build is invalid - member DependencyFiles : string[] - - /// Get the errors and warnings for the parse - member Errors : FSharpErrorInfo[] - - /// Indicates if any errors occurred during the parse - member ParseHadErrors : bool - - internal new: errors: FSharpErrorInfo[] * input: Ast.ParsedInput option * parseHadErrors: bool * dependencyFiles: string[] -> FSharpParseFileResults - -/// Information about F# source file names -module public SourceFile = - - /// Whether or not this file is compilable - val IsCompilable : string -> bool - - /// Whether or not this file should be a single-file project - val MustBeSingleFileProject : string -> bool - -type public CompletionPath = string list * string option // plid * residue - -[] -type public InheritanceContext = - | Class - | Interface - | Unknown - -[] -type public RecordContext = - | CopyOnUpdate of range * CompletionPath // range - | Constructor of string // typename - | New of CompletionPath - -[] -type public CompletionContext = - - /// completion context cannot be determined due to errors - | Invalid - - /// completing something after the inherit keyword - | Inherit of InheritanceContext * CompletionPath - - /// completing records field - | RecordField of RecordContext - - | RangeOperator - - /// completing named parameters\setters in parameter list of constructor\method calls - /// end of name ast node * list of properties\parameters that were already set - | ParameterList of pos * HashSet - - | AttributeApplication - - | OpenDeclaration - - /// completing pattern type (e.g. foo (x: |)) - | PatternType - -type public ModuleKind = { IsAutoOpen: bool; HasModuleSuffix: bool } - -[] -type public EntityKind = - | Attribute - | Type - | FunctionOrValue of isActivePattern:bool - | Module of ModuleKind - -// implementation details used by other code in the compiler -module public UntypedParseImpl = - val TryFindExpressionASTLeftOfDotLeftOfCursor : pos * ParsedInput option -> (pos * bool) option - val GetRangeOfExprLeftOfDot : pos * ParsedInput option -> range option - val TryFindExpressionIslandInPosition : pos * ParsedInput option -> string option - val TryGetCompletionContext : pos * ParsedInput * lineStr: string -> CompletionContext option - val GetEntityKind: pos * ParsedInput -> EntityKind option - val GetFullNameOfSmallestModuleOrNamespaceAtPoint : ParsedInput * pos -> string[] - -// implementation details used by other code in the compiler -module internal SourceFileImpl = - val IsInterfaceFile : string -> bool - val AdditionalDefinesForUseInEditor: isInteractive: bool -> string list - diff --git a/src/fsharp/service/ServiceXmlDocParser.fs b/src/fsharp/service/ServiceXmlDocParser.fs index 5b71775adce..62a12a88429 100644 --- a/src/fsharp/service/ServiceXmlDocParser.fs +++ b/src/fsharp/service/ServiceXmlDocParser.fs @@ -1,24 +1,27 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library +open FSharp.Compiler.Syntax open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml /// Represent an Xml documentation block in source code type XmlDocable = | XmlDocable of line:int * indent:int * paramNames:string list module XmlDocParsing = - open FSharp.Compiler.Range - open FSharp.Compiler.Ast let (|ConstructorPats|) = function - | Pats ps -> ps - | NamePatPairs(xs, _) -> List.map snd xs + | SynArgPats.Pats ps -> ps + | SynArgPats.NamePatPairs(xs, _) -> List.map snd xs - let rec digNamesFrom = function - | SynPat.Named(_innerPat,id,_isTheThisVar,_access,_range) -> [id.idText] + let rec digNamesFrom pat = + match pat with + | SynPat.As (_, SynPat.Named(id,_isTheThisVar,_access,_range), _) + | SynPat.Named (id,_isTheThisVar,_access,_range) -> [id.idText] | SynPat.Typed(pat,_type,_range) -> digNamesFrom pat | SynPat.Attrib(pat,_attrs,_range) -> digNamesFrom pat | SynPat.LongIdent(_lid,_idOpt,_typDeclsOpt,ConstructorPats pats,_access,_range) -> @@ -26,6 +29,7 @@ module XmlDocParsing = | SynPat.Tuple(_,pats,_range) -> pats |> List.collect digNamesFrom | SynPat.Paren(pat,_range) -> digNamesFrom pat | SynPat.OptionalVal (id, _) -> [id.idText] + | SynPat.As _ // no one uses as in fun decls | SynPat.Or _ // no one uses ors in fun decls | SynPat.Ands _ // no one uses ands in fun decls | SynPat.ArrayOrList _ // no one uses this in fun decls @@ -39,7 +43,7 @@ module XmlDocParsing = | SynPat.InstanceMember _ | SynPat.FromParseError _ -> [] - let getXmlDocablesImpl(sourceText: ISourceText, input: ParsedInput option) = + let getXmlDocablesImpl(sourceText: ISourceText, input: ParsedInput) = let indentOf (lineNum: int) = let mutable i = 0 let line = sourceText.GetLineString(lineNum-1) // -1 because lineNum reported by xmldocs are 1-based, but array is 0-based @@ -48,25 +52,23 @@ module XmlDocParsing = i let isEmptyXmlDoc (preXmlDoc: PreXmlDoc) = - match preXmlDoc.ToXmlDoc() with - | XmlDoc [||] -> true - | XmlDoc [|x|] when x.Trim() = "" -> true - | _ -> false + preXmlDoc.ToXmlDoc(false, None).IsEmpty - let rec getXmlDocablesSynModuleDecl = function + let rec getXmlDocablesSynModuleDecl decl = + match decl with | SynModuleDecl.NestedModule(_, _, synModuleDecls, _, _) -> (synModuleDecls |> List.collect getXmlDocablesSynModuleDecl) | SynModuleDecl.Let(_, synBindingList, range) -> let anyXmlDoc = - synBindingList |> List.exists (fun (SynBinding.Binding(_, _, _, _, _, preXmlDoc, _, _, _, _, _, _)) -> + synBindingList |> List.exists (fun (SynBinding(_, _, _, _, _, preXmlDoc, _, _, _, _, _, _)) -> not <| isEmptyXmlDoc preXmlDoc) if anyXmlDoc then [] else let synAttributes = - synBindingList |> List.collect (fun (SynBinding.Binding(_, _, _, _, a, _, _, _, _, _, _, _)) -> a) + synBindingList |> List.collect (fun (SynBinding(_, _, _, _, a, _, _, _, _, _, _, _)) -> a) let fullRange = synAttributes |> List.fold (fun r a -> unionRanges r a.Range) range let line = fullRange.StartLine let indent = indentOf line - [ for SynBinding.Binding(_, _, _, _, _, _, synValData, synPat, _, _, _, _) in synBindingList do + [ for SynBinding(_, _, _, _, _, _, synValData, synPat, _, _, _, _) in synBindingList do match synValData with | SynValData(_memberFlagsOpt, SynValInfo(args, _), _) when not (List.isEmpty args) -> let parameters = @@ -96,7 +98,7 @@ module XmlDocParsing = and getXmlDocablesSynModuleOrNamespace (SynModuleOrNamespace(_, _, _, synModuleDecls, _, _, _, _)) = (synModuleDecls |> List.collect getXmlDocablesSynModuleDecl) - and getXmlDocablesSynTypeDefn (SynTypeDefn.TypeDefn(ComponentInfo(synAttributes, _, _, _, preXmlDoc, _, _, compRange), synTypeDefnRepr, synMemberDefns, tRange)) = + and getXmlDocablesSynTypeDefn (SynTypeDefn(SynComponentInfo(synAttributes, _, _, _, preXmlDoc, _, _, compRange), synTypeDefnRepr, synMemberDefns, _, tRange)) = let stuff = match synTypeDefnRepr with | SynTypeDefnRepr.ObjectModel(_, synMemberDefns, _) -> (synMemberDefns |> List.collect getXmlDocablesSynMemberDefn) @@ -112,7 +114,7 @@ module XmlDocParsing = docForTypeDefn @ stuff @ (synMemberDefns |> List.collect getXmlDocablesSynMemberDefn) and getXmlDocablesSynMemberDefn = function - | SynMemberDefn.Member(SynBinding.Binding(_, _, _, _, synAttributes, preXmlDoc, _, synPat, _, _, _, _), memRange) -> + | SynMemberDefn.Member(SynBinding(_, _, _, _, synAttributes, preXmlDoc, _, synPat, _, _, _, _), memRange) -> if isEmptyXmlDoc preXmlDoc then let fullRange = synAttributes |> List.fold (fun r a -> unionRanges r a.Range) memRange let line = fullRange.StartLine @@ -120,12 +122,12 @@ module XmlDocParsing = let paramNames = digNamesFrom synPat [XmlDocable(line,indent,paramNames)] else [] - | SynMemberDefn.AbstractSlot(ValSpfn(synAttributes, _, _, _, SynValInfo(args, _), _, _, preXmlDoc, _, _, _), _, range) -> + | SynMemberDefn.AbstractSlot(SynValSig(synAttributes, _, _, _, synValInfo, _, _, preXmlDoc, _, _, _), _, range) -> if isEmptyXmlDoc preXmlDoc then let fullRange = synAttributes |> List.fold (fun r a -> unionRanges r a.Range) range let line = fullRange.StartLine let indent = indentOf line - let paramNames = args |> List.collect (fun az -> az |> List.choose (fun (SynArgInfo(_synAttributes, _, idOpt)) -> match idOpt with | Some id -> Some(id.idText) | _ -> None)) + let paramNames = synValInfo.ArgNames [XmlDocable(line,indent,paramNames)] else [] | SynMemberDefn.Interface(_synType, synMemberDefnsOption, _range) -> @@ -152,34 +154,29 @@ module XmlDocParsing = | ParsedInput.SigFile _ -> [] // Get compiler options for the 'project' implied by a single script file - match input with - | Some input -> - getXmlDocablesInput input - | None -> - // Should not fail here, just in case - [] + getXmlDocablesInput input module XmlDocComment = - let private ws (s: string, pos) = + let ws (s: string, pos) = let res = s.TrimStart() Some (res, pos + (s.Length - res.Length)) - let private str (prefix: string) (s: string, pos) = + let str (prefix: string) (s: string, pos) = match s.StartsWithOrdinal(prefix) with | true -> let res = s.Substring prefix.Length Some (res, pos + (s.Length - res.Length)) | _ -> None - let private eol (s: string, pos) = + let eol (s: string, pos) = match s with | "" -> Some ("", pos) | _ -> None - let inline private (>=>) f g = f >> Option.bind g + let (>=>) f g = f >> Option.bind g // if it's a blank XML comment with trailing "<", returns Some (index of the "<"), otherwise returns None - let isBlank (s: string) = + let IsBlank (s: string) = let parser = ws >=> str "///" >=> ws >=> str "<" >=> eol let res = parser (s.TrimEnd(), 0) |> Option.map snd |> Option.map (fun x -> x - 1) res @@ -187,5 +184,5 @@ module XmlDocComment = module XmlDocParser = /// Get the list of Xml documentation from current source code - let getXmlDocables (sourceText: ISourceText, input) = + let GetXmlDocables (sourceText: ISourceText, input) = XmlDocParsing.getXmlDocablesImpl (sourceText, input) \ No newline at end of file diff --git a/src/fsharp/service/ServiceXmlDocParser.fsi b/src/fsharp/service/ServiceXmlDocParser.fsi index 03a36a7d241..bf3ef76e2e4 100644 --- a/src/fsharp/service/ServiceXmlDocParser.fsi +++ b/src/fsharp/service/ServiceXmlDocParser.fsi @@ -1,10 +1,8 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.EditorServices -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Ast +open FSharp.Compiler.Syntax open FSharp.Compiler.Text /// Represent an Xml documentation block in source code @@ -14,10 +12,10 @@ type public XmlDocable = module public XmlDocComment = /// if it's a blank XML comment with trailing "<", returns Some (index of the "<"), otherwise returns None - val isBlank : string -> int option + val IsBlank: string -> int option module public XmlDocParser = /// Get the list of Xml documentation from current source code - val getXmlDocables : ISourceText * input: Ast.ParsedInput option -> XmlDocable list + val GetXmlDocables: ISourceText * input: ParsedInput -> XmlDocable list \ No newline at end of file diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 7030262aab5..1a852854828 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -1,33 +1,38 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.CodeAnalysis open System -open System.Collections.Concurrent open System.Diagnostics open System.IO open System.Reflection - +open System.Threading +open Internal.Utilities.Collections +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras open FSharp.Compiler open FSharp.Compiler.AbstractIL open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal.Library - -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOps -open FSharp.Compiler.CompileOptions +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.CompilerOptions +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics open FSharp.Compiler.Driver open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Lib -open FSharp.Compiler.Range -open FSharp.Compiler.TcGlobals +open FSharp.Compiler.IO +open FSharp.Compiler.ParseAndCheckInputs +open FSharp.Compiler.ScriptClosure +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Tokenization open FSharp.Compiler.Text - -open Internal.Utilities -open Internal.Utilities.Collections - -type internal Layout = StructuredFormat.Layout +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.BuildGraph [] module EnvMisc = @@ -40,54 +45,6 @@ module EnvMisc = let maxMBDefault = GetEnvInteger "FCS_MaxMB" 1000000 // a million MB = 1TB = disabled //let maxMBDefault = GetEnvInteger "FCS_maxMB" (if sizeof = 4 then 1700 else 3400) -type UnresolvedReferencesSet = UnresolvedReferencesSet of UnresolvedAssemblyReference list - -// NOTE: may be better just to move to optional arguments here -type FSharpProjectOptions = - { - ProjectFileName: string - ProjectId: string option - SourceFiles: string[] - OtherOptions: string[] - ReferencedProjects: (string * FSharpProjectOptions)[] - IsIncompleteTypeCheckEnvironment : bool - UseScriptResolutionRules : bool - LoadTime : System.DateTime - UnresolvedReferences : UnresolvedReferencesSet option - OriginalLoadReferences: (range * string * string) list - ExtraProjectInfo : obj option - Stamp : int64 option - } - member x.ProjectOptions = x.OtherOptions - /// Whether the two parse options refer to the same project. - static member UseSameProject(options1,options2) = - match options1.ProjectId, options2.ProjectId with - | Some(projectId1), Some(projectId2) when not (String.IsNullOrWhiteSpace(projectId1)) && not (String.IsNullOrWhiteSpace(projectId2)) -> - projectId1 = projectId2 - | Some(_), Some(_) - | None, None -> options1.ProjectFileName = options2.ProjectFileName - | _ -> false - - /// Compare two options sets with respect to the parts of the options that are important to building. - static member AreSameForChecking(options1,options2) = - match options1.Stamp, options2.Stamp with - | Some x, Some y -> (x = y) - | _ -> - FSharpProjectOptions.UseSameProject(options1, options2) && - options1.SourceFiles = options2.SourceFiles && - options1.OtherOptions = options2.OtherOptions && - options1.UnresolvedReferences = options2.UnresolvedReferences && - options1.OriginalLoadReferences = options2.OriginalLoadReferences && - options1.ReferencedProjects.Length = options2.ReferencedProjects.Length && - Array.forall2 (fun (n1,a) (n2,b) -> - n1 = n2 && - FSharpProjectOptions.AreSameForChecking(a,b)) options1.ReferencedProjects options2.ReferencedProjects && - options1.LoadTime = options2.LoadTime - - /// Compute the project directory. - member po.ProjectDirectory = System.IO.Path.GetDirectoryName(po.ProjectFileName) - override this.ToString() = "FSharpProjectOptions(" + this.ProjectFileName + ")" - //---------------------------------------------------------------------------- // BackgroundCompiler // @@ -112,14 +69,14 @@ module Helpers = && FSharpProjectOptions.UseSameProject(o1,o2) /// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. parsing - let AreSameForParsing((fileName1: string, source1Hash: int, options1), (fileName2, source2Hash, options2)) = + let AreSameForParsing((fileName1: string, source1Hash: int64, options1), (fileName2, source2Hash, options2)) = fileName1 = fileName2 && options1 = options2 && source1Hash = source2Hash let AreSimilarForParsing((fileName1, _, _), (fileName2, _, _)) = fileName1 = fileName2 /// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. checking - let AreSameForChecking3((fileName1: string, source1Hash: int, options1: FSharpProjectOptions), (fileName2, source2Hash, options2)) = + let AreSameForChecking3((fileName1: string, source1Hash: int64, options1: FSharpProjectOptions), (fileName2, source2Hash, options2)) = (fileName1 = fileName2) && FSharpProjectOptions.AreSameForChecking(options1,options2) && source1Hash = source2Hash @@ -135,14 +92,14 @@ module CompileHelpers = let errorSink isError exn = let mainError, relatedErrors = SplitRelatedDiagnostics exn - let oneError e = errors.Add(FSharpErrorInfo.CreateFromException (e, isError, Range.range0, true)) // Suggest names for errors + let oneError e = errors.Add(FSharpDiagnostic.CreateFromException (e, isError, range0, true)) // Suggest names for errors oneError mainError List.iter oneError relatedErrors let errorLogger = { new ErrorLogger("CompileAPI") with member x.DiagnosticSink(exn, isError) = errorSink isError exn - member x.ErrorCount = errors |> Seq.filter (fun e -> e.Severity = FSharpErrorSeverity.Error) |> Seq.length } + member x.ErrorCount = errors |> Seq.filter (fun e -> e.Severity = FSharpDiagnosticSeverity.Error) |> Seq.length } let loggerProvider = { new ErrorLoggerProvider() with @@ -150,14 +107,14 @@ module CompileHelpers = errors, errorLogger, loggerProvider let tryCompile errorLogger f = - use unwindParsePhase = PushThreadBuildPhaseUntilUnwind (BuildPhase.Parse) + use unwindParsePhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse use unwindEL_2 = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) let exiter = { new Exiter with member x.Exit n = raise StopProcessing } try f exiter 0 with e -> - stopProcessingRecovery e Range.range0 + stopProcessingRecovery e range0 1 /// Compile using the given flags. Source files names are resolved via the FileSystem API. The output file must be given by a -o flag. @@ -183,10 +140,10 @@ module CompileHelpers = errors.ToArray(), result - let createDynamicAssembly (ctok, debugInfo: bool, tcImportsRef: TcImports option ref, execute: bool, assemblyBuilderRef: _ option ref) (tcGlobals:TcGlobals, outfile, ilxMainModule) = + let createDynamicAssembly (debugInfo: bool, tcImportsRef: TcImports option ref, execute: bool, assemblyBuilderRef: _ option ref) (tcConfig: TcConfig, tcGlobals:TcGlobals, outfile, ilxMainModule) = // Create an assembly builder - let assemblyName = System.Reflection.AssemblyName(System.IO.Path.GetFileNameWithoutExtension outfile) + let assemblyName = AssemblyName(Path.GetFileNameWithoutExtension outfile) let flags = System.Reflection.Emit.AssemblyBuilderAccess.Run #if FX_NO_APP_DOMAINS let assemblyBuilder = System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(assemblyName, flags) @@ -206,12 +163,12 @@ module CompileHelpers = // The function used to resolve types while emitting the code let assemblyResolver s = - match tcImportsRef.Value.Value.TryFindExistingFullyQualifiedPathByExactAssemblyRef (ctok, s) with + match tcImportsRef.Value.Value.TryFindExistingFullyQualifiedPathByExactAssemblyRef s with | Some res -> Some (Choice1Of2 res) | None -> None // Emit the code - let _emEnv,execs = ILRuntimeWriter.emitModuleFragment(tcGlobals.ilg, ILRuntimeWriter.emEnv0, assemblyBuilder, moduleBuilder, ilxMainModule, debugInfo, assemblyResolver, tcGlobals.TryFindSysILTypeRef) + let _emEnv,execs = ILRuntimeWriter.emitModuleFragment(tcGlobals.ilg, tcConfig.emitTailcalls, ILRuntimeWriter.emEnv0, assemblyBuilder, moduleBuilder, ilxMainModule, debugInfo, assemblyResolver, tcGlobals.TryFindSysILTypeRef) // Execute the top-level initialization, if requested if execute then @@ -228,17 +185,18 @@ module CompileHelpers = Quotations.Expr.RegisterReflectedDefinitions (assemblyBuilder, moduleBuilder.Name, resource.GetBytes().ToArray()) // Save the result - assemblyBuilderRef := Some assemblyBuilder + assemblyBuilderRef.Value <- Some assemblyBuilder let setOutputStreams execute = // Set the output streams, if requested match execute with | Some (writer,error) -> - System.Console.SetOut writer - System.Console.SetError error + Console.SetOut writer + Console.SetError error | None -> () -type SourceTextHash = int +type SourceTextHash = int64 +type CacheStamp = int64 type FileName = string type FilePath = string type ProjectPath = string @@ -247,66 +205,114 @@ type FileVersion = int type ParseCacheLockToken() = interface LockToken type ScriptClosureCacheToken() = interface LockToken +type CheckFileCacheKey = FileName * SourceTextHash * FSharpProjectOptions +type CheckFileCacheValue = FSharpParseFileResults * FSharpCheckFileResults * SourceTextHash * DateTime // There is only one instance of this type, held in FSharpChecker -type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyContents, keepAllBackgroundResolutions, tryGetMetadataSnapshot, suggestNamesForErrors) as self = - // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.reactor: The one and only Reactor - let reactor = Reactor.Singleton - let beforeFileChecked = Event() - let fileParsed = Event() - let fileChecked = Event() - let projectChecked = Event() - - - let mutable implicitlyStartBackgroundWork = true - let reactorOps = - { new IReactorOperations with - member __.EnqueueAndAwaitOpAsync (userOpName, opName, opArg, op) = reactor.EnqueueAndAwaitOpAsync (userOpName, opName, opArg, op) - member __.EnqueueOp (userOpName, opName, opArg, op) = reactor.EnqueueOp (userOpName, opName, opArg, op) } +type BackgroundCompiler( + legacyReferenceResolver, + projectCacheSize, + keepAssemblyContents, + keepAllBackgroundResolutions, + tryGetMetadataSnapshot, + suggestNamesForErrors, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking) as self = + + let beforeFileChecked = Event() + let fileParsed = Event() + let fileChecked = Event() + let projectChecked = Event() // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.scriptClosureCache /// Information about the derived script closure. let scriptClosureCache = - MruCache(projectCacheSize, + MruCache(projectCacheSize, areSame=FSharpProjectOptions.AreSameForChecking, areSimilar=FSharpProjectOptions.UseSameProject) - let scriptClosureCacheLock = Lock() let frameworkTcImportsCache = FrameworkImportsCache(frameworkTcImportsCacheStrongSize) + // We currently share one global dependency provider for all scripts for the FSharpChecker. + // For projects, one is used per project. + // + // Sharing one for all scripts is necessary for good performance from GetProjectOptionsFromScript, + // which requires a dependency provider to process through the project options prior to working out + // if the cached incremental builder can be used for the project. + let dependencyProviderForScripts = new DependencyProvider() + /// CreateOneIncrementalBuilder (for background type checking). Note that fsc.fs also /// creates an incremental builder used by the command line compiler. - let CreateOneIncrementalBuilder (ctok, options:FSharpProjectOptions, userOpName) = - cancellable { + let CreateOneIncrementalBuilder (options:FSharpProjectOptions, userOpName) = + node { Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CreateOneIncrementalBuilder", options.ProjectFileName) let projectReferences = - [ for (nm,opts) in options.ReferencedProjects do - - // Don't use cross-project references for FSharp.Core, since various bits of code require a concrete FSharp.Core to exist on-disk. - // The only solutions that have these cross-project references to FSharp.Core are VisualFSharp.sln and FSharp.sln. The only ramification - // of this is that you need to build FSharp.Core to get intellisense in those projects. - - if (try Path.GetFileNameWithoutExtension(nm) with _ -> "") <> GetFSharpCoreLibraryName() then - - yield - { new IProjectReference with - member x.EvaluateRawContents(ctok) = - cancellable { - Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "ParseAndCheckProjectImpl", nm) - let! r = self.ParseAndCheckProjectImpl(opts, ctok, userOpName + ".CheckReferencedProject("+nm+")") - return r.RawFSharpAssemblyData - } - member x.TryGetLogicalTimeStamp(cache, ctok) = - self.TryGetLogicalTimeStampForProject(cache, ctok, opts, userOpName + ".TimeStampReferencedProject("+nm+")") - member x.FileName = nm } ] - - let loadClosure = scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.TryGet (ltok, options)) + [ for r in options.ReferencedProjects do + + match r with + | FSharpReferencedProject.FSharpReference(nm,opts) -> + // Don't use cross-project references for FSharp.Core, since various bits of code require a concrete FSharp.Core to exist on-disk. + // The only solutions that have these cross-project references to FSharp.Core are VisualFSharp.sln and FSharp.sln. The only ramification + // of this is that you need to build FSharp.Core to get intellisense in those projects. + + if (try Path.GetFileNameWithoutExtension(nm) with _ -> "") <> GetFSharpCoreLibraryName() then + + yield + { new IProjectReference with + member x.EvaluateRawContents() = + node { + Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "GetAssemblyData", nm) + return! self.GetAssemblyData(opts, userOpName + ".CheckReferencedProject("+nm+")") + } + member x.TryGetLogicalTimeStamp(cache) = + self.TryGetLogicalTimeStampForProject(cache, opts) + member x.FileName = nm } + + | FSharpReferencedProject.PEReference(nm,stamp,delayedReader) -> + yield + { new IProjectReference with + member x.EvaluateRawContents() = + node { + let! ilReaderOpt = delayedReader.TryGetILModuleReader() |> NodeCode.FromCancellable + match ilReaderOpt with + | Some ilReader -> + let ilModuleDef, ilAsmRefs = ilReader.ILModuleDef, ilReader.ILAssemblyRefs + let data = RawFSharpAssemblyData(ilModuleDef, ilAsmRefs) :> IRawFSharpAssemblyData + return ProjectAssemblyDataResult.Available data + | _ -> + // Note 'false' - if a PEReference doesn't find an ILModuleReader then we don't + // continue to try to use an on-disk DLL + return ProjectAssemblyDataResult.Unavailable false + } + member x.TryGetLogicalTimeStamp _ = stamp |> Some + member x.FileName = nm } + + | FSharpReferencedProject.ILModuleReference(nm,getStamp,getReader) -> + yield + { new IProjectReference with + member x.EvaluateRawContents() = + node { + let ilReader = getReader() + let ilModuleDef, ilAsmRefs = ilReader.ILModuleDef, ilReader.ILAssemblyRefs + let data = RawFSharpAssemblyData(ilModuleDef, ilAsmRefs) :> IRawFSharpAssemblyData + return ProjectAssemblyDataResult.Available data + } + member x.TryGetLogicalTimeStamp _ = getStamp() |> Some + member x.FileName = nm } + ] + + let loadClosure = scriptClosureCache.TryGet(AnyCallerThread, options) + let! builderOpt, diagnostics = - IncrementalBuilder.TryCreateBackgroundBuilderForProjectOptions - (ctok, legacyReferenceResolver, FSharpCheckerResultsSettings.defaultFSharpBinariesDir, frameworkTcImportsCache, loadClosure, Array.toList options.SourceFiles, + IncrementalBuilder.TryCreateIncrementalBuilderForProjectOptions + (legacyReferenceResolver, FSharpCheckerResultsSettings.defaultFSharpBinariesDir, frameworkTcImportsCache, loadClosure, Array.toList options.SourceFiles, Array.toList options.OtherOptions, projectReferences, options.ProjectDirectory, - options.UseScriptResolutionRules, keepAssemblyContents, keepAllBackgroundResolutions, FSharpCheckerResultsSettings.maxTimeShareMilliseconds, - tryGetMetadataSnapshot, suggestNamesForErrors) + options.UseScriptResolutionRules, keepAssemblyContents, keepAllBackgroundResolutions, + tryGetMetadataSnapshot, suggestNamesForErrors, keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking, + (if options.UseScriptResolutionRules then Some dependencyProviderForScripts else None)) match builderOpt with | None -> () @@ -315,8 +321,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC #if !NO_EXTENSIONTYPING // Register the behaviour that responds to CCUs being invalidated because of type // provider Invalidate events. This invalidates the configuration in the build. - builder.ImportsInvalidatedByTypeProvider.Add (fun _ -> - self.InvalidateConfiguration(options, None, userOpName)) + builder.ImportsInvalidatedByTypeProvider.Add(fun () -> self.InvalidateConfiguration(options, userOpName)) #endif // Register the callback called just before a file is typechecked by the background builder (without recording @@ -324,426 +329,543 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC // // This indicates to the UI that the file type check state is dirty. If the file is open and visible then // the UI will sooner or later request a typecheck of the file, recording errors and intellisense information. - builder.BeforeFileChecked.Add (fun file -> beforeFileChecked.Trigger(file, options.ExtraProjectInfo)) - builder.FileParsed.Add (fun file -> fileParsed.Trigger(file, options.ExtraProjectInfo)) - builder.FileChecked.Add (fun file -> fileChecked.Trigger(file, options.ExtraProjectInfo)) - builder.ProjectChecked.Add (fun () -> projectChecked.Trigger (options.ProjectFileName, options.ExtraProjectInfo)) + builder.BeforeFileChecked.Add (fun file -> beforeFileChecked.Trigger(file, options)) + builder.FileParsed.Add (fun file -> fileParsed.Trigger(file, options)) + builder.FileChecked.Add (fun file -> fileChecked.Trigger(file, options)) + builder.ProjectChecked.Add (fun () -> projectChecked.Trigger options) return (builderOpt, diagnostics) } - // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.incrementalBuildersCache. This root typically holds more - // live information than anything else in the F# Language Service, since it holds up to 3 (projectCacheStrongSize) background project builds - // strongly. - // - /// Cache of builds keyed by options. - let incrementalBuildersCache = - MruCache - (keepStrongly=projectCacheSize, keepMax=projectCacheSize, - areSame = FSharpProjectOptions.AreSameForChecking, - areSimilar = FSharpProjectOptions.UseSameProject) - - let getOrCreateBuilder (ctok, options, userOpName) = - cancellable { - RequireCompilationThread ctok - match incrementalBuildersCache.TryGet (ctok, options) with - | Some (builderOpt,creationErrors) -> - Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache - return builderOpt,creationErrors - | None -> - Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_BuildingNewCache - let! (builderOpt,creationErrors) as info = CreateOneIncrementalBuilder (ctok, options, userOpName) - incrementalBuildersCache.Set (ctok, options, info) - return builderOpt, creationErrors - } - let parseCacheLock = Lock() - // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseFileInProjectCache. Most recently used cache for parsing files. - let parseFileCache = MruCache(parseFileCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing) + let parseFileCache = MruCache(parseFileCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing) - // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCachePossiblyStale // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCache // /// Cache which holds recently seen type-checks. /// This cache may hold out-of-date entries, in two senses /// - there may be a more recent antecedent state available because the background build has made it available /// - the source for the file may have changed - - let checkFileInProjectCachePossiblyStale = - MruCache - (keepStrongly=checkFileInProjectCacheSize, - areSame=AreSameForChecking2, - areSimilar=AreSubsumable2) // Also keyed on source. This can only be out of date if the antecedent is out of date - let checkFileInProjectCache = - MruCache + let checkFileInProjectCache = + MruCache> (keepStrongly=checkFileInProjectCacheSize, areSame=AreSameForChecking3, areSimilar=AreSubsumable3) - /// Holds keys for files being currently checked. It's used to prevent checking same file in parallel (interleaving chunk queued to Reactor). - let beingCheckedFileTable = - ConcurrentDictionary - (HashIdentity.FromFunctions - hash - (fun (f1, o1, v1) (f2, o2, v2) -> f1 = f2 && v1 = v2 && FSharpProjectOptions.AreSameForChecking(o1, o2))) + // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.backgroundCompiler.incrementalBuildersCache. This root typically holds more + // live information than anything else in the F# Language Service, since it holds up to 3 (projectCacheStrongSize) background project builds + // strongly. + // + /// Cache of builds keyed by options. + let gate = obj() + let incrementalBuildersCache = + MruCache> + (keepStrongly=projectCacheSize, keepMax=projectCacheSize, + areSame = FSharpProjectOptions.AreSameForChecking, + areSimilar = FSharpProjectOptions.UseSameProject) - static let mutable foregroundParseCount = 0 + let tryGetBuilderNode options = + incrementalBuildersCache.TryGet (AnyCallerThread, options) + + let tryGetBuilder options : NodeCode option = + tryGetBuilderNode options + |> Option.map (fun x -> x.GetOrComputeValue()) + + let tryGetSimilarBuilder options : NodeCode option = + incrementalBuildersCache.TryGetSimilar (AnyCallerThread, options) + |> Option.map (fun x -> x.GetOrComputeValue()) + + let tryGetAnyBuilder options : NodeCode option = + incrementalBuildersCache.TryGetAny (AnyCallerThread, options) + |> Option.map (fun x -> x.GetOrComputeValue()) + + let createBuilderNode (options, userOpName, ct: CancellationToken) = + lock gate (fun () -> + if ct.IsCancellationRequested then + GraphNode(node { return None, [||] }) + else + let getBuilderNode = + GraphNode(CreateOneIncrementalBuilder(options, userOpName)) + incrementalBuildersCache.Set (AnyCallerThread, options, getBuilderNode) + getBuilderNode + ) - static let mutable foregroundTypeCheckCount = 0 + let createAndGetBuilder (options, userOpName) = + node { + let! ct = NodeCode.CancellationToken + let getBuilderNode = createBuilderNode (options, userOpName, ct) + return! getBuilderNode.GetOrComputeValue() + } - member __.RecordTypeCheckFileInProjectResults(filename,options,parsingOptions,parseResults,fileVersion,priorTimeStamp,checkAnswer,sourceText) = - match checkAnswer with - | None - | Some FSharpCheckFileAnswer.Aborted -> () - | Some (FSharpCheckFileAnswer.Succeeded typedResults) -> - foregroundTypeCheckCount <- foregroundTypeCheckCount + 1 - parseCacheLock.AcquireLock (fun ltok -> - checkFileInProjectCachePossiblyStale.Set(ltok, (filename,options),(parseResults,typedResults,fileVersion)) - checkFileInProjectCache.Set(ltok, (filename, sourceText, options),(parseResults,typedResults,fileVersion,priorTimeStamp)) - parseFileCache.Set(ltok, (filename, sourceText, parsingOptions), parseResults)) + let getOrCreateBuilder (options, userOpName) : NodeCode = + match tryGetBuilder options with + | Some getBuilder -> + node { + match! getBuilder with + | builderOpt, creationDiags when builderOpt.IsNone || not builderOpt.Value.IsReferencesInvalidated -> + Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache + return builderOpt,creationDiags + | _ -> + // The builder could be re-created, + // clear the check file caches that are associated with it. + // We must do this in order to not return stale results when references + // in the project get changed/added/removed. + parseCacheLock.AcquireLock(fun ltok -> + options.SourceFiles + |> Array.iter (fun sourceFile -> + let key = (sourceFile, 0L, options) + checkFileInProjectCache.RemoveAnySimilar(ltok, key) + ) + ) + return! createAndGetBuilder (options, userOpName) + } + | _ -> + createAndGetBuilder (options, userOpName) + + let getSimilarOrCreateBuilder (options, userOpName) = + match tryGetSimilarBuilder options with + | Some res -> res + // The builder does not exist at all. Create it. + | None -> getOrCreateBuilder (options, userOpName) + + let getOrCreateBuilderWithInvalidationFlag (options, canInvalidateProject, userOpName) = + if canInvalidateProject then + getOrCreateBuilder (options, userOpName) + else + getSimilarOrCreateBuilder (options, userOpName) + + let getAnyBuilder (options, userOpName) = + match tryGetAnyBuilder options with + | Some getBuilder -> + Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache + getBuilder + | _ -> + getOrCreateBuilder (options, userOpName) + + /// Should be a fast operation. Ensures that we have only one async lazy object per file and its hash. + let getCheckFileNode (parseResults, + sourceText, + fileName, + options, + _fileVersion, + builder, + tcPrior, + tcInfo, + creationDiags) onComplete = + + // Here we lock for the creation of the node, not its execution + parseCacheLock.AcquireLock (fun ltok -> + let key = (fileName, sourceText.GetHashCode() |> int64, options) + match checkFileInProjectCache.TryGet(ltok, key) with + | Some res -> res + | _ -> + let res = + GraphNode(node { + let! res = + self.CheckOneFileImplAux( + parseResults, + sourceText, + fileName, + options, + builder, + tcPrior, + tcInfo, + creationDiags) + onComplete() + return res + }) + checkFileInProjectCache.Set(ltok, key, res) + res + ) - member bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) = - if implicitlyStartBackgroundWork then - bc.CheckProjectInBackground(options, userOpName + ".ImplicitlyStartCheckProjectInBackground") + static let mutable actualParseFileCount = 0 - member __.ParseFile(filename: string, sourceText: ISourceText, options: FSharpParsingOptions, userOpName: string) = + static let mutable actualCheckFileCount = 0 + + member _.ParseFile(filename: string, sourceText: ISourceText, options: FSharpParsingOptions, cache: bool, userOpName: string) = async { - let hash = sourceText.GetHashCode() + if cache then + let hash = sourceText.GetHashCode() |> int64 match parseCacheLock.AcquireLock(fun ltok -> parseFileCache.TryGet(ltok, (filename, hash, options))) with | Some res -> return res | None -> - foregroundParseCount <- foregroundParseCount + 1 - let parseErrors, parseTreeOpt, anyErrors = ParseAndCheckFile.parseFile(sourceText, filename, options, userOpName, suggestNamesForErrors) - let res = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, options.SourceFiles) + Interlocked.Increment(&actualParseFileCount) |> ignore + let parseDiags, parseTree, anyErrors = ParseAndCheckFile.parseFile(sourceText, filename, options, userOpName, suggestNamesForErrors) + let res = FSharpParseFileResults(parseDiags, parseTree, anyErrors, options.SourceFiles) parseCacheLock.AcquireLock(fun ltok -> parseFileCache.Set(ltok, (filename, hash, options), res)) return res + else + let parseDiags, parseTree, anyErrors = ParseAndCheckFile.parseFile(sourceText, filename, options, userOpName, false) + return FSharpParseFileResults(parseDiags, parseTree, anyErrors, options.SourceFiles) } - member bc.ParseFileNoCache(filename, sourceText, options, userOpName) = - async { - let parseErrors, parseTreeOpt, anyErrors = ParseAndCheckFile.parseFile(sourceText, filename, options, userOpName, false) - return FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, options.SourceFiles) + /// Fetch the parse information from the background compiler (which checks w.r.t. the FileSystem API) + member _.GetBackgroundParseResultsForFileInProject(filename, options, userOpName) = + node { + let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName) + match builderOpt with + | None -> + let parseTree = EmptyParsedInput(filename, (false, false)) + return FSharpParseFileResults(creationDiags, parseTree, true, [| |]) + | Some builder -> + let parseTree,_,_,parseDiags = builder.GetParseResultsForFile filename + let diagnostics = [| yield! creationDiags; yield! DiagnosticHelpers.CreateDiagnostics (builder.TcConfig.errorSeverityOptions, false, filename, parseDiags, suggestNamesForErrors) |] + return FSharpParseFileResults(diagnostics = diagnostics, input = parseTree, parseHadErrors = false, dependencyFiles = builder.AllDependenciesDeprecated) } - /// Fetch the parse information from the background compiler (which checks w.r.t. the FileSystem API) - member __.GetBackgroundParseResultsForFileInProject(filename, options, userOpName) = - reactor.EnqueueAndAwaitOpAsync(userOpName, "GetBackgroundParseResultsForFileInProject ", filename, fun ctok -> - cancellable { - let! builderOpt, creationErrors = getOrCreateBuilder (ctok, options, userOpName) - match builderOpt with - | None -> return FSharpParseFileResults(creationErrors, None, true, [| |]) - | Some builder -> - let! parseTreeOpt,_,_,parseErrors = builder.GetParseResultsForFile (ctok, filename) - let errors = [| yield! creationErrors; yield! ErrorHelpers.CreateErrorInfos (builder.TcConfig.errorSeverityOptions, false, filename, parseErrors, suggestNamesForErrors) |] - return FSharpParseFileResults(errors = errors, input = parseTreeOpt, parseHadErrors = false, dependencyFiles = builder.AllDependenciesDeprecated) - } - ) + member _.GetCachedCheckFileResult(builder: IncrementalBuilder, filename, sourceText: ISourceText, options) = + node { + let hash = sourceText.GetHashCode() |> int64 + let key = (filename, hash, options) + let cachedResultsOpt = parseCacheLock.AcquireLock(fun ltok -> checkFileInProjectCache.TryGet(ltok, key)) + + match cachedResultsOpt with + | Some cachedResults -> + match! cachedResults.GetOrComputeValue() with + | parseResults, checkResults,_,priorTimeStamp + when + (match builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename with + | None -> false + | Some(tcPrior) -> + tcPrior.TimeStamp = priorTimeStamp && + builder.AreCheckResultsBeforeFileInProjectReady(filename)) -> + return Some (parseResults,checkResults) + | _ -> + parseCacheLock.AcquireLock(fun ltok -> checkFileInProjectCache.RemoveAnySimilar(ltok, key)) + return None + | _ -> + return None + } + + member private bc.CheckOneFileImplAux + (parseResults: FSharpParseFileResults, + sourceText: ISourceText, + fileName: string, + options: FSharpProjectOptions, + builder: IncrementalBuilder, + tcPrior: PartialCheckResults, + tcInfo: TcInfo, + creationDiags: FSharpDiagnostic[]) : NodeCode = + + node { + // Get additional script #load closure information if applicable. + // For scripts, this will have been recorded by GetProjectOptionsFromScript. + let tcConfig = tcPrior.TcConfig + let loadClosure = scriptClosureCache.TryGet(AnyCallerThread, options) + + let! checkAnswer = + FSharpCheckFileResults.CheckOneFile + (parseResults, + sourceText, + fileName, + options.ProjectFileName, + tcConfig, + tcPrior.TcGlobals, + tcPrior.TcImports, + tcInfo.tcState, + tcInfo.moduleNamesDict, + loadClosure, + tcInfo.TcErrors, + options.IsIncompleteTypeCheckEnvironment, + options, + builder, + Array.ofList tcInfo.tcDependencyFiles, + creationDiags, + parseResults.Diagnostics, + keepAssemblyContents, + suggestNamesForErrors) |> NodeCode.FromCancellable + GraphNode.SetPreferredUILang tcConfig.preferredUiLang + return (parseResults, checkAnswer, sourceText.GetHashCode() |> int64, tcPrior.TimeStamp) + } + - member __.GetCachedCheckFileResult(builder: IncrementalBuilder, filename, sourceText: ISourceText, options) = - // Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date - let cachedResults = parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCache.TryGet(ltok, (filename, sourceText.GetHashCode(), options))) - - match cachedResults with -// | Some (parseResults, checkResults, _, _) when builder.AreCheckResultsBeforeFileInProjectReady(filename) -> - | Some (parseResults, checkResults,_,priorTimeStamp) - when - (match builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename with - | None -> false - | Some(tcPrior) -> - tcPrior.TimeStamp = priorTimeStamp && - builder.AreCheckResultsBeforeFileInProjectReady(filename)) -> - Some (parseResults,checkResults) - | _ -> None - - /// 1. Repeatedly try to get cached file check results or get file "lock". - /// - /// 2. If it've got cached results, returns them. - /// - /// 3. If it've not got the lock for 1 minute, returns `FSharpCheckFileAnswer.Aborted`. - /// - /// 4. Type checks the file. - /// - /// 5. Records results in `BackgroundCompiler` caches. - /// - /// 6. Starts whole project background compilation. - /// - /// 7. Releases the file "lock". member private bc.CheckOneFileImpl (parseResults: FSharpParseFileResults, sourceText: ISourceText, fileName: string, options: FSharpProjectOptions, - textSnapshotInfo: obj option, fileVersion: int, builder: IncrementalBuilder, tcPrior: PartialCheckResults, - creationErrors: FSharpErrorInfo[], - userOpName: string) = - - async { - let beingCheckedFileKey = fileName, options, fileVersion - let stopwatch = Stopwatch.StartNew() - let rec loop() = - async { - // results may appear while we were waiting for the lock, let's recheck if it's the case - let cachedResults = bc.GetCachedCheckFileResult(builder, fileName, sourceText, options) - - match cachedResults with - | Some (_, checkResults) -> return FSharpCheckFileAnswer.Succeeded checkResults - | None -> - if beingCheckedFileTable.TryAdd(beingCheckedFileKey, ()) then - try - // Get additional script #load closure information if applicable. - // For scripts, this will have been recorded by GetProjectOptionsFromScript. - let loadClosure = scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.TryGet (ltok, options)) - let! checkAnswer = - FSharpCheckFileResults.CheckOneFile - (parseResults, - sourceText, - fileName, - options.ProjectFileName, - tcPrior.TcConfig, - tcPrior.TcGlobals, - tcPrior.TcImports, - tcPrior.TcState, - tcPrior.ModuleNamesDict, - loadClosure, - tcPrior.TcErrors, - reactorOps, - textSnapshotInfo, - userOpName, - options.IsIncompleteTypeCheckEnvironment, - builder, - Array.ofList tcPrior.TcDependencyFiles, - creationErrors, - parseResults.Errors, - keepAssemblyContents, - suggestNamesForErrors) - let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules) - reactor.SetPreferredUILang tcPrior.TcConfig.preferredUiLang - bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, sourceText.GetHashCode()) - return checkAnswer - finally - let dummy = ref () - beingCheckedFileTable.TryRemove(beingCheckedFileKey, dummy) |> ignore - else - do! Async.Sleep 100 - if stopwatch.Elapsed > TimeSpan.FromMinutes 1. then - return FSharpCheckFileAnswer.Aborted - else - return! loop() - } - return! loop() - } + tcInfo: TcInfo, + creationDiags: FSharpDiagnostic[]) = + + node { + match! bc.GetCachedCheckFileResult(builder, fileName, sourceText, options) with + | Some (_, results) -> return FSharpCheckFileAnswer.Succeeded results + | _ -> + let lazyCheckFile = + getCheckFileNode + (parseResults, sourceText, fileName, options, fileVersion, builder, tcPrior, tcInfo, creationDiags) + (fun () -> + Interlocked.Increment(&actualCheckFileCount) |> ignore + ) + + let! _, results, _, _ = lazyCheckFile.GetOrComputeValue() + return FSharpCheckFileAnswer.Succeeded results + } /// Type-check the result obtained by parsing, but only if the antecedent type checking context is available. - member bc.CheckFileInProjectAllowingStaleCachedResults(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, textSnapshotInfo: obj option, userOpName) = - let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "CheckFileInProjectAllowingStaleCachedResults ", filename, action) - async { - try - if implicitlyStartBackgroundWork then - reactor.CancelBackgroundOp() // cancel the background work, since we will start new work after we're done - - let! cachedResults = - execWithReactorAsync <| fun ctok -> - cancellable { - let! _builderOpt,_creationErrors = getOrCreateBuilder (ctok, options, userOpName) - - match incrementalBuildersCache.TryGetAny (ctok, options) with - | Some (Some builder, creationErrors) -> - match bc.GetCachedCheckFileResult(builder, filename, sourceText, options) with - | Some (_, checkResults) -> return Some (builder, creationErrors, Some (FSharpCheckFileAnswer.Succeeded checkResults)) - | _ -> return Some (builder, creationErrors, None) + member bc.CheckFileInProjectAllowingStaleCachedResults(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, userOpName) = + node { + let! cachedResults = + node { + let! builderOpt, creationDiags = getAnyBuilder (options, userOpName) + + match builderOpt with + | Some builder -> + match! bc.GetCachedCheckFileResult(builder, filename, sourceText, options) with + | Some (_, checkResults) -> return Some (builder, creationDiags, Some (FSharpCheckFileAnswer.Succeeded checkResults)) + | _ -> return Some (builder, creationDiags, None) | _ -> return None // the builder wasn't ready - } + } - match cachedResults with - | None -> return None - | Some (_, _, Some x) -> return Some x - | Some (builder, creationErrors, None) -> - Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CheckFileInProjectAllowingStaleCachedResults.CacheMiss", filename) - let! tcPrior = - execWithReactorAsync <| fun ctok -> - cancellable { - DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok - return builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename - } - - match tcPrior with - | Some tcPrior -> - let! checkResults = bc.CheckOneFileImpl(parseResults, sourceText, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) + match cachedResults with + | None -> return None + | Some (_, _, Some x) -> return Some x + | Some (builder, creationDiags, None) -> + Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CheckFileInProjectAllowingStaleCachedResults.CacheMiss", filename) + match builder.GetCheckResultsBeforeFileInProjectEvenIfStale filename with + | Some tcPrior -> + match tcPrior.TryPeekTcInfo() with + | Some tcInfo -> + let! checkResults = bc.CheckOneFileImpl(parseResults, sourceText, filename, options, fileVersion, builder, tcPrior, tcInfo, creationDiags) return Some checkResults - | None -> return None // the incremental builder was not up to date - finally - bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) + | None -> + return None + | None -> return None // the incremental builder was not up to date } /// Type-check the result obtained by parsing. Force the evaluation of the antecedent type checking context if needed. - member bc.CheckFileInProject(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, textSnapshotInfo, userOpName) = - let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "CheckFileInProject", filename, action) - async { - try - if implicitlyStartBackgroundWork then - reactor.CancelBackgroundOp() // cancel the background work, since we will start new work after we're done - let! builderOpt,creationErrors = execWithReactorAsync (fun ctok -> getOrCreateBuilder (ctok, options, userOpName)) - match builderOpt with - | None -> return FSharpCheckFileAnswer.Succeeded (FSharpCheckFileResults.MakeEmpty(filename, creationErrors, reactorOps, keepAssemblyContents)) - | Some builder -> - // Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date - let cachedResults = bc.GetCachedCheckFileResult(builder, filename, sourceText, options) - - match cachedResults with - | Some (_, checkResults) -> return FSharpCheckFileAnswer.Succeeded checkResults - | _ -> - Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CheckFileInProject.CacheMiss", filename) - let! tcPrior = execWithReactorAsync <| fun ctok -> builder.GetCheckResultsBeforeFileInProject (ctok, filename) - let! checkAnswer = bc.CheckOneFileImpl(parseResults, sourceText, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) - return checkAnswer - finally - bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) + member bc.CheckFileInProject(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, userOpName) = + node { + let! builderOpt,creationDiags = getOrCreateBuilder (options, userOpName) + match builderOpt with + | None -> return FSharpCheckFileAnswer.Succeeded (FSharpCheckFileResults.MakeEmpty(filename, creationDiags, keepAssemblyContents)) + | Some builder -> + // Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date + let! cachedResults = bc.GetCachedCheckFileResult(builder, filename, sourceText, options) + + match cachedResults with + | Some (_, checkResults) -> return FSharpCheckFileAnswer.Succeeded checkResults + | _ -> + let! tcPrior = builder.GetCheckResultsBeforeFileInProject filename + let! tcInfo = tcPrior.GetOrComputeTcInfo() + return! bc.CheckOneFileImpl(parseResults, sourceText, filename, options, fileVersion, builder, tcPrior, tcInfo, creationDiags) } /// Parses and checks the source file and returns untyped AST and check results. - member bc.ParseAndCheckFileInProject (filename:string, fileVersion, sourceText: ISourceText, options:FSharpProjectOptions, textSnapshotInfo, userOpName) = - let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "ParseAndCheckFileInProject", filename, action) - async { - try - let strGuid = "_ProjectId=" + (options.ProjectId |> Option.defaultValue "null") - Logger.LogBlockMessageStart (filename + strGuid) LogCompilerFunctionId.Service_ParseAndCheckFileInProject - - if implicitlyStartBackgroundWork then - Logger.LogMessage (filename + strGuid + "-Cancelling background work") LogCompilerFunctionId.Service_ParseAndCheckFileInProject - reactor.CancelBackgroundOp() // cancel the background work, since we will start new work after we're done - - let! builderOpt,creationErrors = execWithReactorAsync (fun ctok -> getOrCreateBuilder (ctok, options, userOpName)) - match builderOpt with - | None -> - Logger.LogBlockMessageStop (filename + strGuid + "-Failed_Aborted") LogCompilerFunctionId.Service_ParseAndCheckFileInProject - - let parseResults = FSharpParseFileResults(creationErrors, None, true, [| |]) - return (parseResults, FSharpCheckFileAnswer.Aborted) - - | Some builder -> - let cachedResults = bc.GetCachedCheckFileResult(builder, filename, sourceText, options) - - match cachedResults with - | Some (parseResults, checkResults) -> - Logger.LogBlockMessageStop (filename + strGuid + "-Successful_Cached") LogCompilerFunctionId.Service_ParseAndCheckFileInProject - - return parseResults, FSharpCheckFileAnswer.Succeeded checkResults - | _ -> - // todo this blocks the Reactor queue until all files up to the current are type checked. It's OK while editing the file, - // but results with non cooperative blocking when a firts file from a project opened. - let! tcPrior = execWithReactorAsync <| fun ctok -> builder.GetCheckResultsBeforeFileInProject (ctok, filename) - - // Do the parsing. - let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList (builder.SourceFiles), options.UseScriptResolutionRules) - reactor.SetPreferredUILang tcPrior.TcConfig.preferredUiLang - let parseErrors, parseTreeOpt, anyErrors = ParseAndCheckFile.parseFile (sourceText, filename, parsingOptions, userOpName, suggestNamesForErrors) - let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, builder.AllDependenciesDeprecated) - let! checkResults = bc.CheckOneFileImpl(parseResults, sourceText, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) - - Logger.LogBlockMessageStop (filename + strGuid + "-Successful") LogCompilerFunctionId.Service_ParseAndCheckFileInProject - - return parseResults, checkResults - finally - bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) + member bc.ParseAndCheckFileInProject (filename:string, fileVersion, sourceText: ISourceText, options:FSharpProjectOptions, userOpName) = + node { + let strGuid = "_ProjectId=" + (options.ProjectId |> Option.defaultValue "null") + Logger.LogBlockMessageStart (filename + strGuid) LogCompilerFunctionId.Service_ParseAndCheckFileInProject + + let! builderOpt,creationDiags = getOrCreateBuilder (options, userOpName) + match builderOpt with + | None -> + Logger.LogBlockMessageStop (filename + strGuid + "-Failed_Aborted") LogCompilerFunctionId.Service_ParseAndCheckFileInProject + + let parseTree = EmptyParsedInput(filename, (false, false)) + let parseResults = FSharpParseFileResults(creationDiags, parseTree, true, [| |]) + return (parseResults, FSharpCheckFileAnswer.Aborted) + + | Some builder -> + let! cachedResults = bc.GetCachedCheckFileResult(builder, filename, sourceText, options) + + match cachedResults with + | Some (parseResults, checkResults) -> + Logger.LogBlockMessageStop (filename + strGuid + "-Successful_Cached") LogCompilerFunctionId.Service_ParseAndCheckFileInProject + + return (parseResults, FSharpCheckFileAnswer.Succeeded checkResults) + | _ -> + let! tcPrior = builder.GetCheckResultsBeforeFileInProject filename + let! tcInfo = tcPrior.GetOrComputeTcInfo() + // Do the parsing. + let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules) + GraphNode.SetPreferredUILang tcPrior.TcConfig.preferredUiLang + let parseDiags, parseTree, anyErrors = ParseAndCheckFile.parseFile (sourceText, filename, parsingOptions, userOpName, suggestNamesForErrors) + let parseResults = FSharpParseFileResults(parseDiags, parseTree, anyErrors, builder.AllDependenciesDeprecated) + let! checkResults = bc.CheckOneFileImpl(parseResults, sourceText, filename, options, fileVersion, builder, tcPrior, tcInfo, creationDiags) + + Logger.LogBlockMessageStop (filename + strGuid + "-Successful") LogCompilerFunctionId.Service_ParseAndCheckFileInProject + + return (parseResults, checkResults) } /// Fetch the check information from the background compiler (which checks w.r.t. the FileSystem API) - member __.GetBackgroundCheckResultsForFileInProject(filename, options, userOpName) = - reactor.EnqueueAndAwaitOpAsync(userOpName, "GetBackgroundCheckResultsForFileInProject", filename, fun ctok -> - cancellable { - let! builderOpt, creationErrors = getOrCreateBuilder (ctok, options, userOpName) + member _.GetBackgroundCheckResultsForFileInProject(filename, options, userOpName) = + node { + let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName) match builderOpt with - | None -> - let parseResults = FSharpParseFileResults(creationErrors, None, true, [| |]) - let typedResults = FSharpCheckFileResults.MakeEmpty(filename, creationErrors, reactorOps, keepAssemblyContents) + | None -> + let parseTree = EmptyParsedInput(filename, (false, false)) + let parseResults = FSharpParseFileResults(creationDiags, parseTree, true, [| |]) + let typedResults = FSharpCheckFileResults.MakeEmpty(filename, creationDiags, true) return (parseResults, typedResults) | Some builder -> - let! (parseTreeOpt, _, _, untypedErrors) = builder.GetParseResultsForFile (ctok, filename) - let! tcProj = builder.GetCheckResultsAfterFileInProject (ctok, filename) + let parseTree, _, _, parseDiags = builder.GetParseResultsForFile filename + let! tcProj = builder.GetFullCheckResultsAfterFileInProject filename + + let! tcInfo, tcInfoExtras = tcProj.GetOrComputeTcInfoWithExtras() + + let tcResolutions = tcInfoExtras.tcResolutions + let tcSymbolUses = tcInfoExtras.tcSymbolUses + let tcOpenDeclarations = tcInfoExtras.tcOpenDeclarations + let latestCcuSigForFile = tcInfo.latestCcuSigForFile + let tcState = tcInfo.tcState + let tcEnvAtEnd = tcInfo.tcEnvAtEndOfFile + let latestImplementationFile = tcInfoExtras.latestImplFile + let tcDependencyFiles = tcInfo.tcDependencyFiles + let tcErrors = tcInfo.TcErrors let errorOptions = builder.TcConfig.errorSeverityOptions - let untypedErrors = [| yield! creationErrors; yield! ErrorHelpers.CreateErrorInfos (errorOptions, false, filename, untypedErrors, suggestNamesForErrors) |] - let tcErrors = [| yield! creationErrors; yield! ErrorHelpers.CreateErrorInfos (errorOptions, false, filename, tcProj.TcErrors, suggestNamesForErrors) |] - let parseResults = FSharpParseFileResults(errors = untypedErrors, input = parseTreeOpt, parseHadErrors = false, dependencyFiles = builder.AllDependenciesDeprecated) - let loadClosure = scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.TryGet (ltok, options) ) + let parseDiags = [| yield! creationDiags; yield! DiagnosticHelpers.CreateDiagnostics (errorOptions, false, filename, parseDiags, suggestNamesForErrors) |] + let tcErrors = [| yield! creationDiags; yield! DiagnosticHelpers.CreateDiagnostics (errorOptions, false, filename, tcErrors, suggestNamesForErrors) |] + let parseResults = FSharpParseFileResults(diagnostics=parseDiags, input=parseTree, parseHadErrors=false, dependencyFiles=builder.AllDependenciesDeprecated) + let loadClosure = scriptClosureCache.TryGet(AnyCallerThread, options) let typedResults = FSharpCheckFileResults.Make (filename, - options.ProjectFileName, - tcProj.TcConfig, - tcProj.TcGlobals, - options.IsIncompleteTypeCheckEnvironment, - builder, - Array.ofList tcProj.TcDependencyFiles, - creationErrors, - parseResults.Errors, - tcErrors, - reactorOps, - keepAssemblyContents, - Option.get tcProj.LatestCcuSigForFile, - tcProj.TcState.Ccu, - tcProj.TcImports, - tcProj.TcEnvAtEnd.AccessRights, - List.head tcProj.TcResolutionsRev, - List.head tcProj.TcSymbolUsesRev, - tcProj.TcEnvAtEnd.NameEnv, - loadClosure, - tcProj.LatestImplementationFile, - List.head tcProj.TcOpenDeclarationsRev) + options.ProjectFileName, + tcProj.TcConfig, + tcProj.TcGlobals, + options.IsIncompleteTypeCheckEnvironment, + builder, + options, + Array.ofList tcDependencyFiles, + creationDiags, + parseResults.Diagnostics, + tcErrors, + keepAssemblyContents, + Option.get latestCcuSigForFile, + tcState.Ccu, + tcProj.TcImports, + tcEnvAtEnd.AccessRights, + tcResolutions, + tcSymbolUses, + tcEnvAtEnd.NameEnv, + loadClosure, + latestImplementationFile, + tcOpenDeclarations) return (parseResults, typedResults) - }) + } + member _.FindReferencesInFile(filename: string, options: FSharpProjectOptions, symbol: FSharpSymbol, canInvalidateProject: bool, userOpName: string) = + node { + let! builderOpt, _ = getOrCreateBuilderWithInvalidationFlag (options, canInvalidateProject, userOpName) + match builderOpt with + | None -> return Seq.empty + | Some builder -> + if builder.ContainsFile filename then + let! checkResults = builder.GetFullCheckResultsAfterFileInProject filename + let! keyStoreOpt = checkResults.GetOrComputeItemKeyStoreIfEnabled() + match keyStoreOpt with + | None -> return Seq.empty + | Some reader -> return reader.FindAll symbol.Item + else + return Seq.empty + } + + + member _.GetSemanticClassificationForFile(filename: string, options: FSharpProjectOptions, userOpName: string) = + node { + let! builderOpt, _ = getOrCreateBuilder (options, userOpName) + match builderOpt with + | None -> return None + | Some builder -> + let! checkResults = builder.GetFullCheckResultsAfterFileInProject filename + let! scopt = checkResults.GetOrComputeSemanticClassificationIfEnabled() + match scopt with + | None -> return None + | Some sc -> return Some (sc.GetView ()) + } /// Try to get recent approximate type check results for a file. - member __.TryGetRecentCheckResultsForFile(filename: string, options:FSharpProjectOptions, sourceText: ISourceText option, _userOpName: string) = + member _.TryGetRecentCheckResultsForFile(filename: string, options:FSharpProjectOptions, sourceText: ISourceText option, _userOpName: string) = match sourceText with | Some sourceText -> - parseCacheLock.AcquireLock (fun ltok -> - match checkFileInProjectCache.TryGet(ltok,(filename,sourceText.GetHashCode(),options)) with - | Some (a,b,c,_) -> Some (a,b,c) - | None -> parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options)))) - | None -> parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options))) + let hash = sourceText.GetHashCode() |> int64 + let resOpt = parseCacheLock.AcquireLock(fun ltok -> checkFileInProjectCache.TryGet(ltok,(filename,hash,options))) + match resOpt with + | Some res -> + match res.TryPeekValue() with + | ValueSome(a,b,c,_) -> + Some(a,b,c) + | ValueNone -> + None + | None -> + None + | None -> + None /// Parse and typecheck the whole project (the implementation, called recursively as project graph is evaluated) - member private __.ParseAndCheckProjectImpl(options, ctok, userOpName) : Cancellable = - cancellable { - let! builderOpt,creationErrors = getOrCreateBuilder (ctok, options, userOpName) + member private _.ParseAndCheckProjectImpl(options, userOpName) = + node { + let! builderOpt,creationDiags = getOrCreateBuilder (options, userOpName) match builderOpt with | None -> - return FSharpCheckProjectResults (options.ProjectFileName, None, keepAssemblyContents, creationErrors, None) + return FSharpCheckProjectResults (options.ProjectFileName, None, keepAssemblyContents, creationDiags, None) | Some builder -> - let! (tcProj, ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt) = builder.GetCheckResultsAndImplementationsForProject(ctok) + let! tcProj, ilAssemRef, _, tcAssemblyExprOpt = builder.GetFullCheckResultsAndImplementationsForProject() let errorOptions = tcProj.TcConfig.errorSeverityOptions - let fileName = TcGlobals.DummyFileNameForRangesWithoutASpecificLocation - let errors = [| yield! creationErrors; yield! ErrorHelpers.CreateErrorInfos (errorOptions, true, fileName, tcProj.TcErrors, suggestNamesForErrors) |] - return FSharpCheckProjectResults (options.ProjectFileName, Some tcProj.TcConfig, keepAssemblyContents, errors, - Some(tcProj.TcGlobals, tcProj.TcImports, tcProj.TcState.Ccu, tcProj.TcState.CcuSig, - tcProj.TcSymbolUses, tcProj.TopAttribs, tcAssemblyDataOpt, ilAssemRef, - tcProj.TcEnvAtEnd.AccessRights, tcAssemblyExprOpt, Array.ofList tcProj.TcDependencyFiles)) + let fileName = DummyFileNameForRangesWithoutASpecificLocation + + // Although we do not use 'tcInfoExtras', computing it will make sure we get an extra info. + let! tcInfo, _tcInfoExtras = tcProj.GetOrComputeTcInfoWithExtras() + + let topAttribs = tcInfo.topAttribs + let tcState = tcInfo.tcState + let tcEnvAtEnd = tcInfo.tcEnvAtEndOfFile + let tcErrors = tcInfo.TcErrors + let tcDependencyFiles = tcInfo.tcDependencyFiles + let diagnostics = + [| yield! creationDiags; + yield! DiagnosticHelpers.CreateDiagnostics (errorOptions, true, fileName, tcErrors, suggestNamesForErrors) |] + let results = + FSharpCheckProjectResults + (options.ProjectFileName, + Some tcProj.TcConfig, + keepAssemblyContents, + diagnostics, + Some(tcProj.TcGlobals, tcProj.TcImports, tcState.Ccu, tcState.CcuSig, + (Choice1Of2 builder), topAttribs, ilAssemRef, + tcEnvAtEnd.AccessRights, tcAssemblyExprOpt, + Array.ofList tcDependencyFiles, + options)) + return results } - /// Get the timestamp that would be on the output if fully built immediately - member private __.TryGetLogicalTimeStampForProject(cache, ctok, options, userOpName: string) = + member _.GetAssemblyData(options, userOpName) = + node { + let! builderOpt,_ = getOrCreateBuilder (options, userOpName) + match builderOpt with + | None -> + return ProjectAssemblyDataResult.Unavailable true + | Some builder -> + let! _, _, tcAssemblyDataOpt, _ = builder.GetCheckResultsAndImplementationsForProject() + return tcAssemblyDataOpt + } - // NOTE: This creation of the background builder is currently run as uncancellable. Creating background builders is generally - // cheap though the timestamp computations look suspicious for transitive project references. - let builderOpt,_creationErrors = getOrCreateBuilder (ctok, options, userOpName + ".TryGetLogicalTimeStampForProject") |> Cancellable.runWithoutCancellation - match builderOpt with - | None -> None - | Some builder -> Some (builder.GetLogicalTimeStampForProject(cache, ctok)) + /// Get the timestamp that would be on the output if fully built immediately + member private _.TryGetLogicalTimeStampForProject(cache, options) = + match tryGetBuilderNode options with + | Some lazyWork -> + match lazyWork.TryPeekValue() with + | ValueSome (Some builder, _) -> + Some(builder.GetLogicalTimeStampForProject(cache)) + | _ -> + None + | _ -> + None /// Parse and typecheck the whole project. member bc.ParseAndCheckProject(options, userOpName) = - reactor.EnqueueAndAwaitOpAsync(userOpName, "ParseAndCheckProject", options.ProjectFileName, fun ctok -> bc.ParseAndCheckProjectImpl(options, ctok, userOpName)) + bc.ParseAndCheckProjectImpl(options, userOpName) - member __.GetProjectOptionsFromScript(filename, sourceText, loadedTimeStamp, otherFlags, useFsiAuxLib: bool option, useSdkRefs: bool option, assumeDotNetFramework: bool option, extraProjectInfo: obj option, optionsStamp: int64 option, userOpName) = - reactor.EnqueueAndAwaitOpAsync (userOpName, "GetProjectOptionsFromScript", filename, fun ctok -> + member _.GetProjectOptionsFromScript(filename, sourceText, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib: bool option, useSdkRefs: bool option, sdkDirOverride: string option, assumeDotNetFramework: bool option, optionsStamp: int64 option, _userOpName) = cancellable { use errors = new ErrorScope() @@ -751,10 +873,16 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC let useFsiAuxLib = defaultArg useFsiAuxLib true let useSdkRefs = defaultArg useSdkRefs true let reduceMemoryUsage = ReduceMemoryFlag.Yes + let previewEnabled = defaultArg previewEnabled false // Do we assume .NET Framework references for scripts? let assumeDotNetFramework = defaultArg assumeDotNetFramework true - let otherFlags = defaultArg otherFlags [| |] + let extraFlags = + if previewEnabled then + [| "--langversion:preview" |] + else + [||] + let otherFlags = defaultArg otherFlags extraFlags let useSimpleResolution = #if ENABLE_MONO_SUPPORT runningOnMono || otherFlags |> Array.exists (fun x -> x = "--simpleresolution") @@ -763,22 +891,21 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC #endif let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading let applyCompilerOptions tcConfigB = - let fsiCompilerOptions = CompileOptions.GetCoreFsiCompilerOptions tcConfigB - CompileOptions.ParseCompilerOptions (ignore, fsiCompilerOptions, Array.toList otherFlags) + let fsiCompilerOptions = GetCoreFsiCompilerOptions tcConfigB + ParseCompilerOptions (ignore, fsiCompilerOptions, Array.toList otherFlags) - let loadClosure = - LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, + let loadClosure = + LoadClosure.ComputeClosureOfScriptText(legacyReferenceResolver, FSharpCheckerResultsSettings.defaultFSharpBinariesDir, filename, sourceText, - CodeContext.Editing, useSimpleResolution, useFsiAuxLib, useSdkRefs, new Lexhelp.LexResourceManager(), + CodeContext.Editing, useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDirOverride, Lexhelp.LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, - tryGetMetadataSnapshot=tryGetMetadataSnapshot, - reduceMemoryUsage=reduceMemoryUsage) + tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProviderForScripts) let otherFlags = - [| yield "--noframework"; yield "--warn:3"; + [| yield "--noframework"; yield "--warn:3"; yield! otherFlags for r in loadClosure.References do yield "-r:" + fst r - for (code,_) in loadClosure.NoWarns do yield "--nowarn:" + code + for code,_ in loadClosure.NoWarns do yield "--nowarn:" + code |] let options = @@ -791,111 +918,71 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC IsIncompleteTypeCheckEnvironment = false UseScriptResolutionRules = true LoadTime = loadedTimeStamp - UnresolvedReferences = Some (UnresolvedReferencesSet(loadClosure.UnresolvedReferences)) + UnresolvedReferences = Some (FSharpUnresolvedReferencesSet(loadClosure.UnresolvedReferences)) OriginalLoadReferences = loadClosure.OriginalLoadReferences - ExtraProjectInfo=extraProjectInfo Stamp = optionsStamp } - scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.Set(ltok, options, loadClosure)) // Save the full load closure for later correlation. - return options, errors.Diagnostics - }) + scriptClosureCache.Set(AnyCallerThread, options, loadClosure) // Save the full load closure for later correlation. + let diags = loadClosure.LoadClosureRootFileDiagnostics |> List.map (fun (exn, isError) -> FSharpDiagnostic.CreateFromException(exn, isError, range.Zero, false)) + return options, (diags @ errors.Diagnostics) + } + |> Cancellable.toAsync - member bc.InvalidateConfiguration(options : FSharpProjectOptions, startBackgroundCompileIfAlreadySeen, userOpName) = - let startBackgroundCompileIfAlreadySeen = defaultArg startBackgroundCompileIfAlreadySeen implicitlyStartBackgroundWork - // This operation can't currently be cancelled nor awaited - reactor.EnqueueOp(userOpName, "InvalidateConfiguration: Stamp(" + (options.Stamp |> Option.defaultValue 0L).ToString() + ")", options.ProjectFileName, fun ctok -> - // If there was a similar entry then re-establish an empty builder . This is a somewhat arbitrary choice - it - // will have the effect of releasing memory associated with the previous builder, but costs some time. - if incrementalBuildersCache.ContainsSimilarKey (ctok, options) then - - // We do not need to decrement here - the onDiscard function is called each time an entry is pushed out of the build cache, - // including by incrementalBuildersCache.Set. - let newBuilderInfo = CreateOneIncrementalBuilder (ctok, options, userOpName) |> Cancellable.runWithoutCancellation - incrementalBuildersCache.Set(ctok, options, newBuilderInfo) - - // Start working on the project. Also a somewhat arbitrary choice - if startBackgroundCompileIfAlreadySeen then - bc.CheckProjectInBackground(options, userOpName + ".StartBackgroundCompile")) - - member __.NotifyProjectCleaned (options : FSharpProjectOptions, userOpName) = - reactor.EnqueueAndAwaitOpAsync(userOpName, "NotifyProjectCleaned", options.ProjectFileName, fun ctok -> - cancellable { + member bc.InvalidateConfiguration(options: FSharpProjectOptions, userOpName) = + if incrementalBuildersCache.ContainsSimilarKey (AnyCallerThread, options) then + let _ = createBuilderNode (options, userOpName, CancellationToken.None) + () + + member bc.ClearCache(options: seq, _userOpName) = + lock gate (fun () -> + options + |> Seq.iter (fun options -> incrementalBuildersCache.RemoveAnySimilar(AnyCallerThread, options)) + ) + + member _.NotifyProjectCleaned (options: FSharpProjectOptions, userOpName) = + async { + let! ct = Async.CancellationToken // If there was a similar entry (as there normally will have been) then re-establish an empty builder . This // is a somewhat arbitrary choice - it will have the effect of releasing memory associated with the previous // builder, but costs some time. - if incrementalBuildersCache.ContainsSimilarKey (ctok, options) then - // We do not need to decrement here - the onDiscard function is called each time an entry is pushed out of the build cache, - // including by incrementalBuildersCache.Set. - let! newBuilderInfo = CreateOneIncrementalBuilder (ctok, options, userOpName) - incrementalBuildersCache.Set(ctok, options, newBuilderInfo) - }) - - member __.CheckProjectInBackground (options, userOpName) = - reactor.SetBackgroundOp (Some (userOpName, "CheckProjectInBackground", options.ProjectFileName, (fun ctok ct -> - // The creation of the background builder can't currently be cancelled - match getOrCreateBuilder (ctok, options, userOpName) |> Cancellable.run ct with - | ValueOrCancelled.Cancelled _ -> false - | ValueOrCancelled.Value (builderOpt,_) -> - match builderOpt with - | None -> false - | Some builder -> - // The individual steps of the background build - match builder.Step(ctok) |> Cancellable.run ct with - | ValueOrCancelled.Value v -> v - | ValueOrCancelled.Cancelled _ -> false))) - - member __.StopBackgroundCompile () = - reactor.SetBackgroundOp(None) - - member __.WaitForBackgroundCompile() = - reactor.WaitForBackgroundOpCompletion() - - member __.CompleteAllQueuedOps() = - reactor.CompleteAllQueuedOps() - - member __.Reactor = reactor - - member __.ReactorOps = reactorOps - - member __.BeforeBackgroundFileCheck = beforeFileChecked.Publish + if incrementalBuildersCache.ContainsSimilarKey (AnyCallerThread, options) then + let _ = createBuilderNode (options, userOpName, ct) + () + } - member __.FileParsed = fileParsed.Publish + member _.BeforeBackgroundFileCheck = beforeFileChecked.Publish - member __.FileChecked = fileChecked.Publish + member _.FileParsed = fileParsed.Publish - member __.ProjectChecked = projectChecked.Publish + member _.FileChecked = fileChecked.Publish - member __.CurrentQueueLength = reactor.CurrentQueueLength + member _.ProjectChecked = projectChecked.Publish - member __.ClearCachesAsync (userOpName) = - reactor.EnqueueAndAwaitOpAsync (userOpName, "ClearCachesAsync", "", fun ctok -> + member _.ClearCaches() = + lock gate (fun () -> parseCacheLock.AcquireLock (fun ltok -> - checkFileInProjectCachePossiblyStale.Clear ltok - checkFileInProjectCache.Clear ltok + checkFileInProjectCache.Clear(ltok) parseFileCache.Clear(ltok)) - incrementalBuildersCache.Clear ctok - frameworkTcImportsCache.Clear ctok - scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.Clear ltok) - cancellable.Return ()) + incrementalBuildersCache.Clear(AnyCallerThread) + frameworkTcImportsCache.Clear() + scriptClosureCache.Clear AnyCallerThread + ) - member __.DownsizeCaches(userOpName) = - reactor.EnqueueAndAwaitOpAsync (userOpName, "DownsizeCaches", "", fun ctok -> + member _.DownsizeCaches() = + lock gate (fun () -> parseCacheLock.AcquireLock (fun ltok -> - checkFileInProjectCachePossiblyStale.Resize(ltok, keepStrongly=1) - checkFileInProjectCache.Resize(ltok, keepStrongly=1) - parseFileCache.Resize(ltok, keepStrongly=1)) - incrementalBuildersCache.Resize(ctok, keepStrongly=1, keepMax=1) - frameworkTcImportsCache.Downsize(ctok) - scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.Resize(ltok,keepStrongly=1, keepMax=1)) - cancellable.Return ()) + checkFileInProjectCache.Resize(ltok, newKeepStrongly=1) + parseFileCache.Resize(ltok, newKeepStrongly=1)) + incrementalBuildersCache.Resize(AnyCallerThread, newKeepStrongly=1, newKeepMax=1) + frameworkTcImportsCache.Downsize() + scriptClosureCache.Resize(AnyCallerThread,newKeepStrongly=1, newKeepMax=1) + ) - member __.FrameworkImportsCache = frameworkTcImportsCache + member _.FrameworkImportsCache = frameworkTcImportsCache - member __.ImplicitlyStartBackgroundWork with get() = implicitlyStartBackgroundWork and set v = implicitlyStartBackgroundWork <- v + static member ActualParseFileCount = actualParseFileCount - static member GlobalForegroundParseCountStatistic = foregroundParseCount - - static member GlobalForegroundTypeCheckCountStatistic = foregroundTypeCheckCount + static member ActualCheckFileCount = actualCheckFileCount [] @@ -905,26 +992,48 @@ type FSharpChecker(legacyReferenceResolver, keepAssemblyContents, keepAllBackgroundResolutions, tryGetMetadataSnapshot, - suggestNamesForErrors) = - - let backgroundCompiler = BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyContents, keepAllBackgroundResolutions, tryGetMetadataSnapshot, suggestNamesForErrors) + suggestNamesForErrors, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking) = + + let backgroundCompiler = + BackgroundCompiler( + legacyReferenceResolver, + projectCacheSize, + keepAssemblyContents, + keepAllBackgroundResolutions, + tryGetMetadataSnapshot, + suggestNamesForErrors, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking) static let globalInstance = lazy FSharpChecker.Create() // STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.braceMatchCache. Most recently used cache for brace matching. Accessed on the // background UI thread, not on the compiler thread. // - // This cache is safe for concurrent access because there is no onDiscard action for the items in the cache. + // This cache is safe for concurrent access. let braceMatchCache = MruCache(braceMatchCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing) let mutable maxMemoryReached = false let mutable maxMB = maxMBDefault - let maxMemEvent = new Event() + let maxMemEvent = Event() /// Instantiate an interactive checker. - static member Create(?projectCacheSize, ?keepAssemblyContents, ?keepAllBackgroundResolutions, ?legacyReferenceResolver, ?tryGetMetadataSnapshot, ?suggestNamesForErrors) = + static member Create( + ?projectCacheSize, + ?keepAssemblyContents, + ?keepAllBackgroundResolutions, + ?legacyReferenceResolver, + ?tryGetMetadataSnapshot, + ?suggestNamesForErrors, + ?keepAllBackgroundSymbolUses, + ?enableBackgroundItemKeyStoreAndSemanticClassification, + ?enablePartialTypeChecking) = let legacyReferenceResolver = match legacyReferenceResolver with @@ -936,19 +1045,34 @@ type FSharpChecker(legacyReferenceResolver, let projectCacheSizeReal = defaultArg projectCacheSize projectCacheSizeDefault let tryGetMetadataSnapshot = defaultArg tryGetMetadataSnapshot (fun _ -> None) let suggestNamesForErrors = defaultArg suggestNamesForErrors false - new FSharpChecker(legacyReferenceResolver, projectCacheSizeReal,keepAssemblyContents, keepAllBackgroundResolutions, tryGetMetadataSnapshot, suggestNamesForErrors) - - member __.ReferenceResolver = legacyReferenceResolver - - member __.MatchBraces(filename, sourceText: ISourceText, options: FSharpParsingOptions, ?userOpName: string) = + let keepAllBackgroundSymbolUses = defaultArg keepAllBackgroundSymbolUses true + let enableBackgroundItemKeyStoreAndSemanticClassification = defaultArg enableBackgroundItemKeyStoreAndSemanticClassification false + let enablePartialTypeChecking = defaultArg enablePartialTypeChecking false + + if keepAssemblyContents && enablePartialTypeChecking then + invalidArg "enablePartialTypeChecking" "'keepAssemblyContents' and 'enablePartialTypeChecking' cannot be both enabled." + + FSharpChecker(legacyReferenceResolver, + projectCacheSizeReal, + keepAssemblyContents, + keepAllBackgroundResolutions, + tryGetMetadataSnapshot, + suggestNamesForErrors, + keepAllBackgroundSymbolUses, + enableBackgroundItemKeyStoreAndSemanticClassification, + enablePartialTypeChecking) + + member _.ReferenceResolver = legacyReferenceResolver + + member _.MatchBraces(filename, sourceText: ISourceText, options: FSharpParsingOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - let hash = sourceText.GetHashCode() + let hash = sourceText.GetHashCode() |> int64 async { - match braceMatchCache.TryGet(AssumeAnyCallerThreadWithoutEvidence(), (filename, hash, options)) with + match braceMatchCache.TryGet(AnyCallerThread, (filename, hash, options)) with | Some res -> return res | None -> let res = ParseAndCheckFile.matchBraces(sourceText, filename, options, userOpName, suggestNamesForErrors) - braceMatchCache.Set(AssumeAnyCallerThreadWithoutEvidence(), (filename, hash, options), res) + braceMatchCache.Set(AnyCallerThread, (filename, hash, options), res) return res } @@ -962,64 +1086,60 @@ type FSharpChecker(legacyReferenceResolver, let argv = List.ofArray options.OtherOptions ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv, options.UseScriptResolutionRules) - member ic.ParseFile(filename, sourceText, options, ?userOpName: string) = + member ic.ParseFile(filename, sourceText, options, ?cache, ?userOpName: string) = + let cache = defaultArg cache true let userOpName = defaultArg userOpName "Unknown" ic.CheckMaxMemoryReached() - backgroundCompiler.ParseFile(filename, sourceText, options, userOpName) + backgroundCompiler.ParseFile(filename, sourceText, options, cache, userOpName) - member ic.ParseFileNoCache(filename, sourceText, options, ?userOpName) = - let userOpName = defaultArg userOpName "Unknown" - ic.CheckMaxMemoryReached() - backgroundCompiler.ParseFileNoCache(filename, sourceText, options, userOpName) - - member ic.ParseFileInProject(filename, source: string, options, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" + member ic.ParseFileInProject(filename, source: string, options, ?cache: bool, ?userOpName: string) = let parsingOptions, _ = ic.GetParsingOptionsFromProjectOptions(options) - ic.ParseFile(filename, SourceText.ofString source, parsingOptions, userOpName) + ic.ParseFile(filename, SourceText.ofString source, parsingOptions, ?cache=cache, ?userOpName=userOpName) - member __.GetBackgroundParseResultsForFileInProject (filename,options, ?userOpName: string) = + member _.GetBackgroundParseResultsForFileInProject (filename,options, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" backgroundCompiler.GetBackgroundParseResultsForFileInProject(filename, options, userOpName) + |> Async.AwaitNodeCode - member __.GetBackgroundCheckResultsForFileInProject (filename,options, ?userOpName: string) = + member _.GetBackgroundCheckResultsForFileInProject (filename,options, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" backgroundCompiler.GetBackgroundCheckResultsForFileInProject(filename,options, userOpName) + |> Async.AwaitNodeCode /// Try to get recent approximate type check results for a file. - member __.TryGetRecentCheckResultsForFile(filename: string, options:FSharpProjectOptions, ?sourceText, ?userOpName: string) = + member _.TryGetRecentCheckResultsForFile(filename: string, options:FSharpProjectOptions, ?sourceText, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.TryGetRecentCheckResultsForFile(filename,options,sourceText, userOpName) + backgroundCompiler.TryGetRecentCheckResultsForFile(filename,options,sourceText,userOpName) - member __.Compile(argv: string[], ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.Reactor.EnqueueAndAwaitOpAsync (userOpName, "Compile", "", fun ctok -> - cancellable { - return CompileHelpers.compileFromArgs (ctok, argv, legacyReferenceResolver, None, None) - }) - - member __.Compile (ast:ParsedInput list, assemblyName:string, outFile:string, dependencies:string list, ?pdbFile:string, ?executable:bool, ?noframework:bool, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.Reactor.EnqueueAndAwaitOpAsync (userOpName, "Compile", assemblyName, fun ctok -> - cancellable { - let noframework = defaultArg noframework false - return CompileHelpers.compileFromAsts (ctok, legacyReferenceResolver, ast, assemblyName, outFile, dependencies, noframework, pdbFile, executable, None, None) - } - ) - - member __.CompileToDynamicAssembly (otherFlags: string[], execute: (TextWriter * TextWriter) option, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.Reactor.EnqueueAndAwaitOpAsync (userOpName, "CompileToDynamicAssembly", "", fun ctok -> - cancellable { + member _.Compile(argv: string[], ?userOpName: string) = + let _userOpName = defaultArg userOpName "Unknown" + async { + let ctok = CompilationThreadToken() + return CompileHelpers.compileFromArgs (ctok, argv, legacyReferenceResolver, None, None) + } + + member _.Compile (ast:ParsedInput list, assemblyName:string, outFile:string, dependencies:string list, ?pdbFile:string, ?executable:bool, ?noframework:bool, ?userOpName: string) = + let _userOpName = defaultArg userOpName "Unknown" + async { + let ctok = CompilationThreadToken() + let noframework = defaultArg noframework false + return CompileHelpers.compileFromAsts (ctok, legacyReferenceResolver, ast, assemblyName, outFile, dependencies, noframework, pdbFile, executable, None, None) + } + + member _.CompileToDynamicAssembly (otherFlags: string[], execute: (TextWriter * TextWriter) option, ?userOpName: string) = + let _userOpName = defaultArg userOpName "Unknown" + async { + let ctok = CompilationThreadToken() CompileHelpers.setOutputStreams execute // References used to capture the results of compilation let tcImportsRef = ref None let assemblyBuilderRef = ref None - let tcImportsCapture = Some (fun tcImports -> tcImportsRef := Some tcImports) + let tcImportsCapture = Some (fun tcImports -> tcImportsRef.Value <- Some tcImports) // Function to generate and store the results of compilation let debugInfo = otherFlags |> Array.exists (fun arg -> arg = "-g" || arg = "--debug:+" || arg = "/debug:+") - let dynamicAssemblyCreator = Some (CompileHelpers.createDynamicAssembly (ctok, debugInfo, tcImportsRef, execute.IsSome, assemblyBuilderRef)) + let dynamicAssemblyCreator = Some (CompileHelpers.createDynamicAssembly (debugInfo, tcImportsRef, execute.IsSome, assemblyBuilderRef)) // Perform the compilation, given the above capturing function. let errorsAndWarnings, result = CompileHelpers.compileFromArgs (ctok, otherFlags, legacyReferenceResolver, tcImportsCapture, dynamicAssemblyCreator) @@ -1028,124 +1148,144 @@ type FSharpChecker(legacyReferenceResolver, let assemblyOpt = match assemblyBuilderRef.Value with | None -> None - | Some a -> Some (a :> System.Reflection.Assembly) + | Some a -> Some (a :> Assembly) return errorsAndWarnings, result, assemblyOpt - } - ) + } - member __.CompileToDynamicAssembly (asts:ParsedInput list, assemblyName:string, dependencies:string list, execute: (TextWriter * TextWriter) option, ?debug:bool, ?noframework:bool, ?userOpName: string) = - let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.Reactor.EnqueueAndAwaitOpAsync (userOpName, "CompileToDynamicAssembly", assemblyName, fun ctok -> - cancellable { + member _.CompileToDynamicAssembly (ast:ParsedInput list, assemblyName:string, dependencies:string list, execute: (TextWriter * TextWriter) option, ?debug:bool, ?noframework:bool, ?userOpName: string) = + let _userOpName = defaultArg userOpName "Unknown" + async { + let ctok = CompilationThreadToken() CompileHelpers.setOutputStreams execute // References used to capture the results of compilation let tcImportsRef = ref (None: TcImports option) let assemblyBuilderRef = ref None - let tcImportsCapture = Some (fun tcImports -> tcImportsRef := Some tcImports) + let tcImportsCapture = Some (fun tcImports -> tcImportsRef.Value <- Some tcImports) let debugInfo = defaultArg debug false let noframework = defaultArg noframework false - let location = Path.Combine(Path.GetTempPath(),"test"+string(hash assemblyName)) + let location = Path.Combine(FileSystem.GetTempPathShim(),"test"+string(hash assemblyName)) try Directory.CreateDirectory(location) |> ignore with _ -> () let outFile = Path.Combine(location, assemblyName + ".dll") // Function to generate and store the results of compilation - let dynamicAssemblyCreator = Some (CompileHelpers.createDynamicAssembly (ctok, debugInfo, tcImportsRef, execute.IsSome, assemblyBuilderRef)) + let dynamicAssemblyCreator = Some (CompileHelpers.createDynamicAssembly (debugInfo, tcImportsRef, execute.IsSome, assemblyBuilderRef)) // Perform the compilation, given the above capturing function. let errorsAndWarnings, result = - CompileHelpers.compileFromAsts (ctok, legacyReferenceResolver, asts, assemblyName, outFile, dependencies, noframework, None, Some execute.IsSome, tcImportsCapture, dynamicAssemblyCreator) + CompileHelpers.compileFromAsts (ctok, legacyReferenceResolver, ast, assemblyName, outFile, dependencies, noframework, None, Some execute.IsSome, tcImportsCapture, dynamicAssemblyCreator) // Retrieve and return the results let assemblyOpt = match assemblyBuilderRef.Value with | None -> None - | Some a -> Some (a :> System.Reflection.Assembly) + | Some a -> Some (a :> Assembly) return errorsAndWarnings, result, assemblyOpt - } - ) + } /// This function is called when the entire environment is known to have changed for reasons not encoded in the ProjectOptions of any project/compilation. /// For example, the type provider approvals file may have changed. member ic.InvalidateAll() = ic.ClearCaches() - member __.ClearCachesAsync(?userOpName: string) = - let utok = AssumeAnyCallerThreadWithoutEvidence() - let userOpName = defaultArg userOpName "Unknown" + member ic.ClearCaches() = + let utok = AnyCallerThread braceMatchCache.Clear(utok) - backgroundCompiler.ClearCachesAsync(userOpName) - - member ic.ClearCaches(?userOpName) = - ic.ClearCachesAsync(?userOpName=userOpName) |> Async.Start // this cache clearance is not synchronous, it will happen when the background op gets run + backgroundCompiler.ClearCaches() - member __.CheckMaxMemoryReached() = - if not maxMemoryReached && System.GC.GetTotalMemory(false) > int64 maxMB * 1024L * 1024L then + member _.CheckMaxMemoryReached() = + if not maxMemoryReached && GC.GetTotalMemory(false) > int64 maxMB * 1024L * 1024L then Trace.TraceWarning("!!!!!!!! MAX MEMORY REACHED, DOWNSIZING F# COMPILER CACHES !!!!!!!!!!!!!!!") // If the maxMB limit is reached, drastic action is taken // - reduce strong cache sizes to a minimum - let userOpName = "MaxMemoryReached" - backgroundCompiler.CompleteAllQueuedOps() maxMemoryReached <- true - braceMatchCache.Resize(AssumeAnyCallerThreadWithoutEvidence(), keepStrongly=10) - backgroundCompiler.DownsizeCaches(userOpName) |> Async.RunSynchronously + braceMatchCache.Resize(AnyCallerThread, newKeepStrongly=10) + backgroundCompiler.DownsizeCaches() maxMemEvent.Trigger( () ) // This is for unit testing only member ic.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() = - backgroundCompiler.CompleteAllQueuedOps() // flush AsyncOp - ic.ClearCachesAsync() |> Async.RunSynchronously - System.GC.Collect() - System.GC.WaitForPendingFinalizers() - backgroundCompiler.CompleteAllQueuedOps() // flush AsyncOp + ic.ClearCaches() + GC.Collect() + GC.WaitForPendingFinalizers() + FxResolver.ClearStaticCaches() /// This function is called when the configuration is known to have changed for reasons not encoded in the ProjectOptions. /// For example, dependent references may have been deleted or created. - member __.InvalidateConfiguration(options: FSharpProjectOptions, ?startBackgroundCompile, ?userOpName: string) = + member _.InvalidateConfiguration(options: FSharpProjectOptions, ?userOpName: string) = + let userOpName = defaultArg userOpName "Unknown" + backgroundCompiler.InvalidateConfiguration(options, userOpName) + + /// Clear the internal cache of the given projects. + member _.ClearCache(options: seq, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.InvalidateConfiguration(options, startBackgroundCompile, userOpName) + backgroundCompiler.ClearCache(options, userOpName) /// This function is called when a project has been cleaned, and thus type providers should be refreshed. - member __.NotifyProjectCleaned(options: FSharpProjectOptions, ?userOpName: string) = + member _.NotifyProjectCleaned(options: FSharpProjectOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" backgroundCompiler.NotifyProjectCleaned (options, userOpName) /// Typecheck a source code file, returning a handle to the results of the /// parse including the reconstructed types in the file. - member __.CheckFileInProjectAllowingStaleCachedResults(parseResults:FSharpParseFileResults, filename:string, fileVersion:int, source:string, options:FSharpProjectOptions, ?textSnapshotInfo:obj, ?userOpName: string) = + member _.CheckFileInProjectAllowingStaleCachedResults(parseResults:FSharpParseFileResults, filename:string, fileVersion:int, source:string, options:FSharpProjectOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.CheckFileInProjectAllowingStaleCachedResults(parseResults,filename,fileVersion,SourceText.ofString source,options,textSnapshotInfo, userOpName) + backgroundCompiler.CheckFileInProjectAllowingStaleCachedResults(parseResults,filename,fileVersion,SourceText.ofString source,options,userOpName) + |> Async.AwaitNodeCode /// Typecheck a source code file, returning a handle to the results of the /// parse including the reconstructed types in the file. - member ic.CheckFileInProject(parseResults:FSharpParseFileResults, filename:string, fileVersion:int, sourceText:ISourceText, options:FSharpProjectOptions, ?textSnapshotInfo:obj, ?userOpName: string) = + member ic.CheckFileInProject(parseResults:FSharpParseFileResults, filename:string, fileVersion:int, sourceText:ISourceText, options:FSharpProjectOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" ic.CheckMaxMemoryReached() - backgroundCompiler.CheckFileInProject(parseResults,filename,fileVersion,sourceText,options,textSnapshotInfo, userOpName) + backgroundCompiler.CheckFileInProject(parseResults,filename,fileVersion,sourceText,options,userOpName) + |> Async.AwaitNodeCode /// Typecheck a source code file, returning a handle to the results of the /// parse including the reconstructed types in the file. - member ic.ParseAndCheckFileInProject(filename:string, fileVersion:int, sourceText:ISourceText, options:FSharpProjectOptions, ?textSnapshotInfo:obj, ?userOpName: string) = + member ic.ParseAndCheckFileInProject(filename:string, fileVersion:int, sourceText:ISourceText, options:FSharpProjectOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" ic.CheckMaxMemoryReached() - backgroundCompiler.ParseAndCheckFileInProject(filename, fileVersion, sourceText, options, textSnapshotInfo, userOpName) + backgroundCompiler.ParseAndCheckFileInProject(filename, fileVersion, sourceText, options, userOpName) + |> Async.AwaitNodeCode member ic.ParseAndCheckProject(options, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" ic.CheckMaxMemoryReached() backgroundCompiler.ParseAndCheckProject(options, userOpName) + |> Async.AwaitNodeCode + + member ic.FindBackgroundReferencesInFile(filename:string, options: FSharpProjectOptions, symbol: FSharpSymbol, ?canInvalidateProject: bool, ?userOpName: string) = + let canInvalidateProject = defaultArg canInvalidateProject true + let userOpName = defaultArg userOpName "Unknown" + ic.CheckMaxMemoryReached() + backgroundCompiler.FindReferencesInFile(filename, options, symbol, canInvalidateProject, userOpName) + |> Async.AwaitNodeCode + + member ic.GetBackgroundSemanticClassificationForFile(filename:string, options: FSharpProjectOptions, ?userOpName) = + let userOpName = defaultArg userOpName "Unknown" + ic.CheckMaxMemoryReached() + backgroundCompiler.GetSemanticClassificationForFile(filename, options, userOpName) + |> Async.AwaitNodeCode /// For a given script file, get the ProjectOptions implied by the #load closure - member __.GetProjectOptionsFromScript(filename, source, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?useSdkRefs, ?assumeDotNetFramework, ?extraProjectInfo: obj, ?optionsStamp: int64, ?userOpName: string) = + member _.GetProjectOptionsFromScript(filename, source, ?previewEnabled, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?useSdkRefs, ?assumeDotNetFramework, ?sdkDirOverride, ?optionsStamp: int64, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.GetProjectOptionsFromScript(filename, source, loadedTimeStamp, otherFlags, useFsiAuxLib, useSdkRefs, assumeDotNetFramework, extraProjectInfo, optionsStamp, userOpName) + backgroundCompiler.GetProjectOptionsFromScript(filename, source, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib, useSdkRefs, sdkDirOverride, assumeDotNetFramework, optionsStamp, userOpName) - member __.GetProjectOptionsFromCommandLineArgs(projectFileName, argv, ?loadedTimeStamp, ?extraProjectInfo: obj) = + member _.GetProjectOptionsFromCommandLineArgs(projectFileName, argv, ?loadedTimeStamp, ?isInteractive, ?isEditing) = + let isEditing = defaultArg isEditing false + let isInteractive = defaultArg isInteractive false let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading + let argv = + let define = if isInteractive then "--define:INTERACTIVE" else "--define:COMPILED" + Array.append argv [| define |] + let argv = + if isEditing then Array.append argv [| "--define:EDITING" |] else argv { ProjectFileName = projectFileName ProjectId = None SourceFiles = [| |] // the project file names will be inferred from the ProjectOptions @@ -1156,70 +1296,60 @@ type FSharpChecker(legacyReferenceResolver, LoadTime = loadedTimeStamp UnresolvedReferences = None OriginalLoadReferences=[] - ExtraProjectInfo=extraProjectInfo Stamp = None } - member __.GetParsingOptionsFromCommandLineArgs(initialSourceFiles, argv, ?isInteractive) = + member _.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv, ?isInteractive, ?isEditing) = + let isEditing = defaultArg isEditing false let isInteractive = defaultArg isInteractive false use errorScope = new ErrorScope() - let tcConfigBuilder = TcConfigBuilder.Initial + let tcConfigB = + TcConfigBuilder.CreateNew(legacyReferenceResolver, + defaultFSharpBinariesDir=FSharpCheckerResultsSettings.defaultFSharpBinariesDir, + reduceMemoryUsage=ReduceMemoryFlag.Yes, + implicitIncludeDir="", + isInteractive=isInteractive, + isInvalidationSupported=false, + defaultCopyFSharpCore=CopyFSharpCoreFlag.No, + tryGetMetadataSnapshot=tryGetMetadataSnapshot, + sdkDirOverride=None, + rangeForErrors=range0) + + // These defines are implied by the F# compiler + tcConfigB.conditionalCompilationDefines <- + let define = if isInteractive then "INTERACTIVE" else "COMPILED" + define :: tcConfigB.conditionalCompilationDefines + if isEditing then + tcConfigB.conditionalCompilationDefines <- "EDITING":: tcConfigB.conditionalCompilationDefines // Apply command-line arguments and collect more source files if they are in the arguments - let sourceFilesNew = ApplyCommandLineArgs(tcConfigBuilder, initialSourceFiles, argv) - FSharpParsingOptions.FromTcConfigBuilder(tcConfigBuilder, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics + let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv) + FSharpParsingOptions.FromTcConfigBuilder(tcConfigB, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics - member ic.GetParsingOptionsFromCommandLineArgs(argv, ?isInteractive: bool) = - ic.GetParsingOptionsFromCommandLineArgs([], argv, ?isInteractive=isInteractive) + member ic.GetParsingOptionsFromCommandLineArgs(argv, ?isInteractive: bool, ?isEditing) = + ic.GetParsingOptionsFromCommandLineArgs([], argv, ?isInteractive=isInteractive, ?isEditing=isEditing) - /// Begin background parsing the given project. - member __.StartBackgroundCompile(options, ?userOpName) = - let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.CheckProjectInBackground(options, userOpName) + member _.BeforeBackgroundFileCheck = backgroundCompiler.BeforeBackgroundFileCheck - /// Begin background parsing the given project. - member ic.CheckProjectInBackground(options, ?userOpName) = - ic.StartBackgroundCompile(options, ?userOpName=userOpName) + member _.FileParsed = backgroundCompiler.FileParsed - /// Stop the background compile. - member __.StopBackgroundCompile() = - backgroundCompiler.StopBackgroundCompile() + member _.FileChecked = backgroundCompiler.FileChecked - /// Block until the background compile finishes. - // - // This is for unit testing only - member __.WaitForBackgroundCompile() = backgroundCompiler.WaitForBackgroundCompile() - - // Publish the ReactorOps from the background compiler for internal use - member ic.ReactorOps = backgroundCompiler.ReactorOps - - member __.CurrentQueueLength = backgroundCompiler.CurrentQueueLength - - member __.BeforeBackgroundFileCheck = backgroundCompiler.BeforeBackgroundFileCheck - - member __.FileParsed = backgroundCompiler.FileParsed + member _.ProjectChecked = backgroundCompiler.ProjectChecked - member __.FileChecked = backgroundCompiler.FileChecked + static member ActualParseFileCount = BackgroundCompiler.ActualParseFileCount - member __.ProjectChecked = backgroundCompiler.ProjectChecked - - member __.ImplicitlyStartBackgroundWork with get() = backgroundCompiler.ImplicitlyStartBackgroundWork and set v = backgroundCompiler.ImplicitlyStartBackgroundWork <- v - - member __.PauseBeforeBackgroundWork with get() = Reactor.Singleton.PauseBeforeBackgroundWork and set v = Reactor.Singleton.PauseBeforeBackgroundWork <- v - - static member GlobalForegroundParseCountStatistic = BackgroundCompiler.GlobalForegroundParseCountStatistic - - static member GlobalForegroundTypeCheckCountStatistic = BackgroundCompiler.GlobalForegroundTypeCheckCountStatistic + static member ActualCheckFileCount = BackgroundCompiler.ActualCheckFileCount - member __.MaxMemoryReached = maxMemEvent.Publish + member _.MaxMemoryReached = maxMemEvent.Publish - member __.MaxMemory with get() = maxMB and set v = maxMB <- v + member _.MaxMemory with get() = maxMB and set v = maxMB <- v static member Instance with get() = globalInstance.Force() - member internal __.FrameworkImportsCache = backgroundCompiler.FrameworkImportsCache + member internal _.FrameworkImportsCache = backgroundCompiler.FrameworkImportsCache /// Tokenize a single line, returning token information and a tokenization state represented by an integer - member __.TokenizeLine (line: string, state: FSharpTokenizerLexState) = + member _.TokenizeLine (line: string, state: FSharpTokenizerLexState) = let tokenizer = FSharpSourceTokenizer([], None) let lineTokenizer = tokenizer.CreateLineTokenizer line let mutable state = (None, state) @@ -1239,42 +1369,58 @@ type FSharpChecker(legacyReferenceResolver, yield tokens |] tokens -type CompilerEnvironment = - static member BinFolderOfDefaultFSharpCompiler(?probePoint) = - FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(probePoint) +namespace FSharp.Compiler -/// Information about the compilation environment -[] -module CompilerEnvironment = - /// These are the names of assemblies that should be referenced for .fs, .ml, .fsi, .mli files that - /// are not associated with a project - let DefaultReferencesForOrphanSources assumeDotNetFramework = DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework +open System +open System.IO +open Internal.Utilities +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text.Range +open FSharp.Compiler.ErrorLogger + +type CompilerEnvironment() = + /// Source file extensions + static let compilableExtensions = FSharpSigFileSuffixes @ FSharpImplFileSuffixes @ FSharpScriptFileSuffixes + + /// Single file projects extensions + static let singleFileProjectExtensions = FSharpScriptFileSuffixes + + static member BinFolderOfDefaultFSharpCompiler(?probePoint) = + FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(probePoint) + + // Legacy entry point, no longer used by FSharp.Editor + static member DefaultReferencesForOrphanSources assumeDotNetFramework = + let currentDirectory = Directory.GetCurrentDirectory() + let fxResolver = FxResolver(assumeDotNetFramework, currentDirectory, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let references, _ = fxResolver.GetDefaultReferences (useFsiAuxLib=false) + references /// Publish compiler-flags parsing logic. Must be fast because its used by the colorizer. - let GetCompilationDefinesForEditing (parsingOptions: FSharpParsingOptions) = + static member GetCompilationDefinesForEditing (parsingOptions: FSharpParsingOptions) = SourceFileImpl.AdditionalDefinesForUseInEditor(parsingOptions.IsInteractive) @ parsingOptions.ConditionalCompilationDefines /// Return true if this is a subcategory of error or warning message that the language service can emit - let IsCheckerSupportedSubcategory(subcategory:string) = + static member IsCheckerSupportedSubcategory(subcategory:string) = // Beware: This code logic is duplicated in DocumentTask.cs in the language service PhasedDiagnostic.IsSubcategoryOfCompile(subcategory) -/// Information about the debugging environment -module DebuggerEnvironment = /// Return the language ID, which is the expression evaluator id that the /// debugger will use. - let GetLanguageID() = - System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) + static member GetDebuggerLanguageID() = + Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) -module PrettyNaming = - let IsIdentifierPartCharacter x = FSharp.Compiler.PrettyNaming.IsIdentifierPartCharacter x - let IsLongIdentifierPartCharacter x = FSharp.Compiler.PrettyNaming.IsLongIdentifierPartCharacter x - let IsOperatorName x = FSharp.Compiler.PrettyNaming.IsOperatorName x - let GetLongNameFromString x = FSharp.Compiler.PrettyNaming.SplitNamesForILPath x - let FormatAndOtherOverloadsString remainingOverloads = FSComp.SR.typeInfoOtherOverloads(remainingOverloads) - let QuoteIdentifierIfNeeded id = Lexhelp.Keywords.QuoteIdentifierIfNeeded id - let KeywordNames = Lexhelp.Keywords.keywordNames - -module FSharpFileUtilities = - let isScriptFile (fileName: string) = CompileOps.IsScript fileName \ No newline at end of file + static member IsScriptFile (fileName: string) = ParseAndCheckInputs.IsScript fileName + + /// Whether or not this file is compilable + static member IsCompilable file = + let ext = Path.GetExtension file + compilableExtensions |> List.exists(fun e->0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) + + /// Whether or not this file should be a single-file project + static member MustBeSingleFileProject file = + let ext = Path.GetExtension file + singleFileProjectExtensions |> List.exists(fun e-> 0 = String.Compare(e, ext, StringComparison.OrdinalIgnoreCase)) + diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi old mode 100755 new mode 100644 index 182714e8d64..97b6f9f7983 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -1,69 +1,19 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//---------------------------------------------------------------------------- -// SourceCodeServices API to the compiler as an incremental service for parsing, -// type checking and intellisense-like environment-reporting. -//---------------------------------------------------------------------------- +/// SourceCodeServices API to the compiler as an incremental service for parsing, +/// type checking and intellisense-like environment-reporting. +namespace FSharp.Compiler.CodeAnalysis -namespace FSharp.Compiler.SourceCodeServices open System open System.IO - open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax open FSharp.Compiler.Text - -/// Unused in this API -type public UnresolvedReferencesSet - -/// A set of information describing a project or script build configuration. -type public FSharpProjectOptions = - { - // Note that this may not reduce to just the project directory, because there may be two projects in the same directory. - ProjectFileName: string - - /// This is the unique identifier for the project, it is case sensitive. If it's None, will key off of ProjectFileName in our caching. - ProjectId: string option - - /// The files in the project - SourceFiles: string[] - - /// Additional command line argument options for the project. These can include additional files and references. - OtherOptions: string[] - - /// The command line arguments for the other projects referenced by this project, indexed by the - /// exact text used in the "-r:" reference in FSharpProjectOptions. - ReferencedProjects: (string * FSharpProjectOptions)[] - - /// When true, the typechecking environment is known a priori to be incomplete, for - /// example when a .fs file is opened outside of a project. In this case, the number of error - /// messages reported is reduced. - IsIncompleteTypeCheckEnvironment : bool - - /// When true, use the reference resolution rules for scripts rather than the rules for compiler. - UseScriptResolutionRules : bool - - /// Timestamp of project/script load, used to differentiate between different instances of a project load. - /// This ensures that a complete reload of the project or script type checking - /// context occurs on project or script unload/reload. - LoadTime : DateTime - - /// Unused in this API and should be 'None' when used as user-specified input - UnresolvedReferences : UnresolvedReferencesSet option - - /// Unused in this API and should be '[]' when used as user-specified input - OriginalLoadReferences: (range * string * string) list - - /// Extra information passed back on event trigger - ExtraProjectInfo : obj option - - /// An optional stamp to uniquely identify this set of options - /// If two sets of options both have stamps, then they are considered equal - /// if and only if the stamps are equal - Stamp: int64 option - } +open FSharp.Compiler.Tokenization [] /// Used to parse and check F# source code. @@ -75,9 +25,17 @@ type public FSharpChecker = /// The optional size of the project checking cache. /// Keep the checked contents of projects. /// If false, do not keep full intermediate checking results from background checking suitable for returning from GetBackgroundCheckResultsForFileInProject. This reduces memory usage. - /// An optional resolver for non-file references, for legacy purposes + /// An optional resolver for legacy MSBuild references /// An optional resolver to access the contents of .NET binaries in a memory-efficient way - static member Create : ?projectCacheSize: int * ?keepAssemblyContents: bool * ?keepAllBackgroundResolutions: bool * ?legacyReferenceResolver: ReferenceResolver.Resolver * ?tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * ?suggestNamesForErrors: bool -> FSharpChecker + /// Indicate whether name suggestion should be enabled + /// Indicate whether all symbol uses should be kept in background checking + /// Indicates whether a table of symbol keys should be kept for background compilation + /// Indicates whether to perform partial type checking. Cannot be set to true if keepAssmeblyContents is true. If set to true, can cause duplicate type-checks when richer information on a file is needed, but can skip background type-checking entirely on implementation files with signature files. + static member Create: + ?projectCacheSize: int * ?keepAssemblyContents: bool * ?keepAllBackgroundResolutions: bool * + ?legacyReferenceResolver: LegacyReferenceResolver * ?tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot * + ?suggestNamesForErrors: bool * ?keepAllBackgroundSymbolUses: bool * ?enableBackgroundItemKeyStoreAndSemanticClassification: bool * ?enablePartialTypeChecking: bool + -> FSharpChecker /// /// Parse a source code file, returning information about brace matching in the file. @@ -109,29 +67,21 @@ type public FSharpChecker = /// The path for the file. The file name is used as a module name for implicit top level modules (e.g. in scripts). /// The source to be parsed. /// Parsing options for the project or script. + /// Store the parse in a size-limited cache assocaited with the FSharpChecker. Default: true /// An optional string used for tracing compiler operations associated with this request. - member ParseFile: filename: string * sourceText: ISourceText * options: FSharpParsingOptions * ?userOpName: string -> Async + member ParseFile: filename: string * sourceText: ISourceText * options: FSharpParsingOptions * ?cache: bool * ?userOpName: string -> Async /// /// Parses a source code for a file. Returns an AST that can be traversed for various features. /// /// /// The path for the file. The file name is also as a module name for implicit top level modules (e.g. in scripts). - /// The source to be parsed. - /// Parsing options for the project or script. - /// An optional string used for tracing compiler operations associated with this request. - member ParseFileNoCache: filename: string * sourceText: ISourceText * options: FSharpParsingOptions * ?userOpName: string -> Async - - /// - /// Parses a source code for a file. Returns an AST that can be traversed for various features. - /// - /// - /// The path for the file. The file name is also as a module name for implicit top level modules (e.g. in scripts). - /// The source to be parsed. + /// The source to be parsed. /// Parsing options for the project or script. + /// Store the parse in a size-limited cache assocaited with the FSharpChecker. Default: true /// An optional string used for tracing compiler operations associated with this request. [] - member ParseFileInProject: filename: string * source: string * options: FSharpProjectOptions * ?userOpName: string -> Async + member ParseFileInProject: filename: string * source: string * options: FSharpProjectOptions * ?cache: bool * ?userOpName: string -> Async /// /// Check a source code file, returning a handle to the results of the parse including @@ -144,19 +94,14 @@ type public FSharpChecker = /// /// /// - /// The results of ParseFile for this file. + /// The results of ParseFile for this file. /// The name of the file in the project whose source is being checked. - /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. + /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. /// The full source for the file. /// The options for the project or script. - /// - /// An item passed back to 'hasTextChangedSinceLastTypecheck' (from some calls made on 'FSharpCheckFileResults') to help determine if - /// an approximate intellisense resolution is inaccurate because a range of text has changed. This - /// can be used to marginally increase accuracy of intellisense results in some situations. - /// /// An optional string used for tracing compiler operations associated with this request. [] - member CheckFileInProjectAllowingStaleCachedResults : parsed: FSharpParseFileResults * filename: string * fileversion: int * source: string * options: FSharpProjectOptions * ?textSnapshotInfo: obj * ?userOpName: string -> Async + member CheckFileInProjectAllowingStaleCachedResults: parseResults: FSharpParseFileResults * filename: string * fileVersion: int * source: string * options: FSharpProjectOptions * ?userOpName: string -> Async /// /// @@ -170,18 +115,13 @@ type public FSharpChecker = /// /// /// - /// The results of ParseFile for this file. + /// The results of ParseFile for this file. /// The name of the file in the project whose source is being checked. - /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. + /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. /// The full source for the file. /// The options for the project or script. - /// - /// An item passed back to 'hasTextChangedSinceLastTypecheck' (from some calls made on 'FSharpCheckFileResults') to help determine if - /// an approximate intellisense resolution is inaccurate because a range of text has changed. This - /// can be used to marginally increase accuracy of intellisense results in some situations. - /// /// An optional string used for tracing compiler operations associated with this request. - member CheckFileInProject : parsed: FSharpParseFileResults * filename: string * fileversion: int * sourceText: ISourceText * options: FSharpProjectOptions * ?textSnapshotInfo: obj * ?userOpName: string -> Async + member CheckFileInProject: parseResults: FSharpParseFileResults * filename: string * fileVersion: int * sourceText: ISourceText * options: FSharpProjectOptions * ?userOpName: string -> Async /// /// @@ -196,50 +136,70 @@ type public FSharpChecker = /// /// /// The name of the file in the project whose source is being checked. - /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. - /// The full source for the file. + /// An integer that can be used to indicate the version of the file. This will be returned by TryGetRecentCheckResultsForFile when looking up the file. + /// The source for the file. /// The options for the project or script. - /// - /// An item passed back to 'hasTextChangedSinceLastTypecheck' (from some calls made on 'FSharpCheckFileResults') to help determine if - /// an approximate intellisense resolution is inaccurate because a range of text has changed. This - /// can be used to marginally increase accuracy of intellisense results in some situations. - /// /// An optional string used for tracing compiler operations associated with this request. - member ParseAndCheckFileInProject : filename: string * fileversion: int * sourceText: ISourceText * options: FSharpProjectOptions * ?textSnapshotInfo: obj * ?userOpName: string -> Async + member ParseAndCheckFileInProject: filename: string * fileVersion: int * sourceText: ISourceText * options: FSharpProjectOptions * ?userOpName: string -> Async /// /// Parse and typecheck all files in a project. /// All files are read from the FileSystem API + /// Can cause a second type-check on the entire project when `enablePartialTypeChecking` is true on the FSharpChecker. /// /// /// The options for the project or script. /// An optional string used for tracing compiler operations associated with this request. - member ParseAndCheckProject : options: FSharpProjectOptions * ?userOpName: string -> Async + member ParseAndCheckProject: options: FSharpProjectOptions * ?userOpName: string -> Async /// /// For a given script file, get the FSharpProjectOptions implied by the #load closure. /// All files are read from the FileSystem API, except the file being checked. /// /// - /// Used to differentiate between scripts, to consider each script a separate project. - /// Also used in formatted error messages. - /// + /// Used to differentiate between scripts, to consider each script a separate project. Also used in formatted error messages. + /// The source for the file. + /// Is the preview compiler enabled. /// Indicates when the script was loaded into the editing environment, /// so that an 'unload' and 'reload' action will cause the script to be considered as a new project, /// so that references are re-resolved. + /// Other flags for compilation. + /// Add a default reference to the FSharp.Compiler.Interactive.Settings library. + /// Use the implicit references from the .NET SDK. + /// Set up compilation and analysis for .NET Framework scripts. + /// Override the .NET SDK used for default references. + /// An optional unique stamp for the options. /// An optional string used for tracing compiler operations associated with this request. - member GetProjectOptionsFromScript : filename: string * sourceText: ISourceText * ?loadedTimeStamp: DateTime * ?otherFlags: string[] * ?useFsiAuxLib: bool * ?useSdkRefs: bool * ?assumeDotNetFramework: bool * ?extraProjectInfo: obj * ?optionsStamp: int64 * ?userOpName: string -> Async - - /// - /// Get the FSharpProjectOptions implied by a set of command line arguments. - /// + member GetProjectOptionsFromScript: + filename: string * + source: ISourceText * + ?previewEnabled:bool * + ?loadedTimeStamp: DateTime * + ?otherFlags: string[] * + ?useFsiAuxLib: bool * + ?useSdkRefs: bool * + ?assumeDotNetFramework: bool * + ?sdkDirOverride: string * + ?optionsStamp: int64 * + ?userOpName: string + -> Async + + /// Get the FSharpProjectOptions implied by a set of command line arguments. /// /// Used to differentiate between projects and for the base directory of the project. /// The command line arguments for the project build. /// Indicates when the script was loaded into the editing environment, + /// Indicates that compilation should assume the EDITING define and related settings + /// Indicates that compilation should assume the INTERACTIVE define and related settings /// so that an 'unload' and 'reload' action will cause the script to be considered as a new project, /// so that references are re-resolved. - member GetProjectOptionsFromCommandLineArgs : projectFileName: string * argv: string[] * ?loadedTimeStamp: DateTime * ?extraProjectInfo: obj -> FSharpProjectOptions + member GetProjectOptionsFromCommandLineArgs: + projectFileName: string * + argv: string[] * + ?loadedTimeStamp: DateTime * + ?isInteractive: bool * + ?isEditing: bool + -> FSharpProjectOptions /// /// Get the FSharpParsingOptions implied by a set of command line arguments and list of source files. @@ -247,21 +207,36 @@ type public FSharpChecker = /// /// Initial source files list. Additional files may be added during argv evaluation. /// The command line arguments for the project build. - member GetParsingOptionsFromCommandLineArgs: sourceFiles: string list * argv: string list * ?isInteractive: bool -> FSharpParsingOptions * FSharpErrorInfo list + /// Indicates that parsing should assume the INTERACTIVE define and related settings + /// Indicates that compilation should assume the EDITING define and related settings + member GetParsingOptionsFromCommandLineArgs: + sourceFiles: string list * + argv: string list * + ?isInteractive: bool * + ?isEditing: bool + -> FSharpParsingOptions * FSharpDiagnostic list /// /// Get the FSharpParsingOptions implied by a set of command line arguments. /// /// /// The command line arguments for the project build. - member GetParsingOptionsFromCommandLineArgs: argv: string list * ?isInteractive: bool -> FSharpParsingOptions * FSharpErrorInfo list + /// Indicates that parsing should assume the INTERACTIVE define and related settings + /// Indicates that compilation should assume the EDITING define and related settings + member GetParsingOptionsFromCommandLineArgs: + argv: string list * + ?isInteractive: bool * + ?isEditing: bool + -> FSharpParsingOptions * FSharpDiagnostic list /// /// Get the FSharpParsingOptions implied by a FSharpProjectOptions. /// /// - /// The command line arguments for the project build. - member GetParsingOptionsFromProjectOptions: FSharpProjectOptions -> FSharpParsingOptions * FSharpErrorInfo list + /// The overall options. + member GetParsingOptionsFromProjectOptions: + options: FSharpProjectOptions + -> FSharpParsingOptions * FSharpDiagnostic list /// /// Like ParseFile, but uses results from the background builder. @@ -271,31 +246,66 @@ type public FSharpChecker = /// The filename for the file. /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. /// An optional string used for tracing compiler operations associated with this request. - member GetBackgroundParseResultsForFileInProject : filename : string * options : FSharpProjectOptions * ?userOpName: string -> Async + member GetBackgroundParseResultsForFileInProject: filename: string * options: FSharpProjectOptions * ?userOpName: string -> Async /// /// Like CheckFileInProject, but uses the existing results from the background builder. /// All files are read from the FileSystem API, including the file being checked. + /// Can cause a second type-check when `enablePartialTypeChecking` is true on the FSharpChecker. + /// + /// + /// The filename for the file. + /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. + /// An optional string used for tracing compiler operations associated with this request. + member GetBackgroundCheckResultsForFileInProject: filename: string * options: FSharpProjectOptions * ?userOpName: string -> Async + + /// + /// Optimized find references for a given symbol in a file of project. + /// All files are read from the FileSystem API, including the file being checked. + /// Can cause a second type-check when `enablePartialTypeChecking` is true on the FSharpChecker. + /// + /// + /// The filename for the file. + /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. + /// The symbol to find all uses in the file. + /// Default: true. If true, this call can invalidate the current state of project if the options have changed. If false, the current state of the project will be used. + /// An optional string used for tracing compiler operations associated with this request. + member FindBackgroundReferencesInFile: filename: string * options: FSharpProjectOptions * symbol: FSharpSymbol * ?canInvalidateProject: bool * ?userOpName: string -> Async + + /// + /// Get semantic classification for a file. + /// All files are read from the FileSystem API, including the file being checked. + /// Can cause a second type-check when `enablePartialTypeChecking` is true on the FSharpChecker. /// /// /// The filename for the file. /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. /// An optional string used for tracing compiler operations associated with this request. - member GetBackgroundCheckResultsForFileInProject : filename : string * options : FSharpProjectOptions * ?userOpName: string -> Async + member GetBackgroundSemanticClassificationForFile : filename : string * options : FSharpProjectOptions * ?userOpName: string -> Async /// /// Compile using the given flags. Source files names are resolved via the FileSystem API. /// The output file must be given by a -o flag. /// The first argument is ignored and can just be "fsc.exe". /// + /// + /// The command line arguments for the project build. /// An optional string used for tracing compiler operations associated with this request. - member Compile: argv:string[] * ?userOpName: string -> Async + member Compile: argv:string[] * ?userOpName: string -> Async /// /// TypeCheck and compile provided AST /// + /// + /// The syntax tree for the build. + /// The assembly name for the compiled output. + /// The output file for the compialtion. + /// The list of dependencies for the compialtion. + /// The output PDB file, if any. + /// Indicates if an executable is being produced. + /// Enables the /noframework flag. /// An optional string used for tracing compiler operations associated with this request. - member Compile: ast:ParsedInput list * assemblyName:string * outFile:string * dependencies:string list * ?pdbFile:string * ?executable:bool * ?noframework:bool * ?userOpName: string -> Async + member Compile: ast:ParsedInput list * assemblyName:string * outFile:string * dependencies:string list * ?pdbFile:string * ?executable:bool * ?noframework:bool * ?userOpName: string -> Async /// /// Compiles to a dynamic assembly using the given flags. @@ -309,14 +319,24 @@ type public FSharpChecker = /// the given TextWriters are used for the stdout and stderr streams respectively. In this /// case, a global setting is modified during the execution. /// + /// + /// Other flags for compilation. + /// An optional pair of output streams, enabling execution of the result. /// An optional string used for tracing compiler operations associated with this request. - member CompileToDynamicAssembly: otherFlags:string [] * execute:(TextWriter * TextWriter) option * ?userOpName: string -> Async + member CompileToDynamicAssembly: otherFlags:string [] * execute:(TextWriter * TextWriter) option * ?userOpName: string -> Async /// /// TypeCheck and compile provided AST /// + /// + /// The syntax tree for the build. + /// The assembly name for the compiled output. + /// The list of dependencies for the compialtion. + /// An optional pair of output streams, enabling execution of the result. + /// Enabled debug symbols + /// Enables the /noframework flag. /// An optional string used for tracing compiler operations associated with this request. - member CompileToDynamicAssembly: ast:ParsedInput list * assemblyName:string * dependencies:string list * execute:(TextWriter * TextWriter) option * ?debug:bool * ?noframework:bool * ?userOpName: string -> Async + member CompileToDynamicAssembly: ast:ParsedInput list * assemblyName:string * dependencies:string list * execute:(TextWriter * TextWriter) option * ?debug:bool * ?noframework:bool * ?userOpName: string -> Async /// /// Try to get type check results for a file. This looks up the results of recent type checks of the @@ -324,96 +344,81 @@ type public FSharpChecker = /// If the source of the file has changed the results returned by this function may be out of date, though may /// still be usable for generating intellisense menus and information. /// + /// /// The filename for the file. /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. /// Optionally, specify source that must match the previous parse precisely. /// An optional string used for tracing compiler operations associated with this request. - member TryGetRecentCheckResultsForFile : filename: string * options:FSharpProjectOptions * ?sourceText: ISourceText * ?userOpName: string -> (FSharpParseFileResults * FSharpCheckFileResults * (*version*)int) option + member TryGetRecentCheckResultsForFile: filename: string * options:FSharpProjectOptions * ?sourceText: ISourceText * ?userOpName: string -> (FSharpParseFileResults * FSharpCheckFileResults * (* hash *)int64) option /// This function is called when the entire environment is known to have changed for reasons not encoded in the ProjectOptions of any project/compilation. - member InvalidateAll : unit -> unit + member InvalidateAll: unit -> unit - /// This function is called when the configuration is known to have changed for reasons not encoded in the ProjectOptions. - /// For example, dependent references may have been deleted or created. - /// Start a background compile of the project if a project with the same name has already been seen before. + /// + /// This function is called when the configuration is known to have changed for reasons not encoded in the ProjectOptions. + /// For example, dependent references may have been deleted or created. + /// + /// The options for the project or script, used to determine active --define conditionals and other options relevant to parsing. /// An optional string used for tracing compiler operations associated with this request. - member InvalidateConfiguration: options: FSharpProjectOptions * ?startBackgroundCompileIfAlreadySeen: bool * ?userOpName: string -> unit - - /// Set the project to be checked in the background. Overrides any previous call to CheckProjectInBackground - member CheckProjectInBackground: options: FSharpProjectOptions * ?userOpName: string -> unit - - /// Stop the background compile. - //[] - member StopBackgroundCompile : unit -> unit + member InvalidateConfiguration: options: FSharpProjectOptions * ?userOpName: string -> unit - /// Block until the background compile finishes. - //[] - member WaitForBackgroundCompile : unit -> unit + /// Clear the internal cache of the given projects. + /// The given project options. + /// An optional string used for tracing compiler operations associated with this request. + member ClearCache: options: FSharpProjectOptions seq * ?userOpName: string -> unit /// Report a statistic for testability - static member GlobalForegroundParseCountStatistic : int + static member ActualParseFileCount: int /// Report a statistic for testability - static member GlobalForegroundTypeCheckCountStatistic : int + static member ActualCheckFileCount: int /// Flush all caches and garbage collect - member ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : unit -> unit - - /// Current queue length of the service, for debug purposes. - /// In addition, a single async operation or a step of a background build - /// may be in progress - such an operation is not counted in the queue length. - member CurrentQueueLength : int + member ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients: unit -> unit /// /// This function is called when a project has been cleaned/rebuilt, and thus any live type providers should be refreshed. /// + /// + /// The options describing the project that has been cleaned. /// An optional string used for tracing compiler operations associated with this request. + [] member NotifyProjectCleaned: options: FSharpProjectOptions * ?userOpName: string -> Async + /// /// Notify the host that the logical type checking context for a file has now been updated internally /// and that the file has become eligible to be re-typechecked for errors. - /// /// The event will be raised on a background thread. - member BeforeBackgroundFileCheck : IEvent + /// + member BeforeBackgroundFileCheck: IEvent /// Raised after a parse of a file in the background analysis. /// /// The event will be raised on a background thread. - member FileParsed : IEvent + member FileParsed: IEvent /// Raised after a check of a file in the background analysis. /// /// The event will be raised on a background thread. - member FileChecked : IEvent + member FileChecked: IEvent /// Raised after the maxMB memory threshold limit is reached - member MaxMemoryReached : IEvent - - /// A maximum number of megabytes of allocated memory. If the figure reported by System.GC.GetTotalMemory(false) goes over this limit, the FSharpChecker object will attempt to free memory and reduce cache sizes to a minimum. - member MaxMemory : int with get, set + member MaxMemoryReached: IEvent - /// Get or set a flag which controls if background work is started implicitly. - /// - /// If true, calls to CheckFileInProject implicitly start a background check of that project, replacing - /// any other background checks in progress. This is useful in IDE applications with spare CPU cycles as - /// it prepares the project analysis results for use. The default is 'true'. - member ImplicitlyStartBackgroundWork: bool with get, set - - /// Get or set the pause time in milliseconds before background work is started. - member PauseBeforeBackgroundWork: int with get, set + /// + /// A maximum number of megabytes of allocated memory. If the figure reported by System.GC.GetTotalMemory(false) goes over this limit, the FSharpChecker object will attempt to free memory and reduce cache sizes to a minimum. + /// + member MaxMemory: int with get, set /// Notify the host that a project has been fully checked in the background (using file contents provided by the file system API) /// /// The event may be raised on a background thread. - member ProjectChecked : IEvent - - // For internal use only - member internal ReactorOps : IReactorOperations + member ProjectChecked: IEvent [] - static member Instance : FSharpChecker - member internal FrameworkImportsCache : FrameworkImportsCache - member internal ReferenceResolver : ReferenceResolver.Resolver + static member Instance: FSharpChecker + member internal FrameworkImportsCache: FrameworkImportsCache + member internal ReferenceResolver: LegacyReferenceResolver /// Tokenize a single line, returning token information and a tokenization state represented by an integer member TokenizeLine: line:string * state:FSharpTokenizerLexState-> FSharpTokenInfo [] * FSharpTokenizerLexState @@ -421,46 +426,36 @@ type public FSharpChecker = /// Tokenize an entire file, line by line member TokenizeFile: source:string -> FSharpTokenInfo [] [] +namespace FSharp.Compiler + +open System +open FSharp.Compiler.CodeAnalysis + /// Information about the compilation environment [] type public CompilerEnvironment = /// The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running - static member BinFolderOfDefaultFSharpCompiler : ?probePoint: string -> string option + static member BinFolderOfDefaultFSharpCompiler: ?probePoint: string -> string option -/// Information about the compilation environment -[] -module public CompilerEnvironment = /// These are the names of assemblies that should be referenced for .fs or .fsi files that /// are not associated with a project. - val DefaultReferencesForOrphanSources: assumeDotNetFramework: bool -> string list - /// Return the compilation defines that should be used when editing the given file. - val GetCompilationDefinesForEditing: parsingOptions: FSharpParsingOptions -> string list - /// Return true if this is a subcategory of error or warning message that the language service can emit - val IsCheckerSupportedSubcategory: string -> bool - -/// Information about the debugging environment -module public DebuggerEnvironment = - /// Return the language ID, which is the expression evaluator id that the - /// debugger will use. - val GetLanguageID : unit -> Guid + static member DefaultReferencesForOrphanSources: assumeDotNetFramework: bool -> string list + /// Return the compilation defines that should be used when editing the given file. + static member GetCompilationDefinesForEditing: parsingOptions: FSharpParsingOptions -> string list -/// A set of helpers related to naming of identifiers -module public PrettyNaming = + /// Return true if this is a subcategory of error or warning message that the language service can emit + static member IsCheckerSupportedSubcategory: string -> bool - val IsIdentifierPartCharacter : char -> bool - val IsLongIdentifierPartCharacter : char -> bool - val IsOperatorName : string -> bool - val GetLongNameFromString : string -> string list + /// Return the language ID, which is the expression evaluator id that the debugger will use. + static member GetDebuggerLanguageID: unit -> Guid - val FormatAndOtherOverloadsString : int -> string + /// A helpers for dealing with F# files. + static member IsScriptFile: string -> bool - /// A utility to help determine if an identifier needs to be quoted - val QuoteIdentifierIfNeeded : string -> string + /// Whether or not this file is compilable + static member IsCompilable: string -> bool - /// All the keywords in the F# language - val KeywordNames : string list + /// Whether or not this file should be a single-file project + static member MustBeSingleFileProject: string -> bool -/// A set of helpers for dealing with F# files. -module FSharpFileUtilities = - val isScriptFile : string -> bool \ No newline at end of file diff --git a/src/fsharp/sr.fs b/src/fsharp/sr.fs index ae81bb6abcf..03d0c415e5e 100644 --- a/src/fsharp/sr.fs +++ b/src/fsharp/sr.fs @@ -6,7 +6,7 @@ namespace FSharp.Compiler open Microsoft.FSharp.Reflection module internal SR = - let private resources = lazy (new System.Resources.ResourceManager("fsstrings", System.Reflection.Assembly.GetExecutingAssembly())) + let private resources = lazy (System.Resources.ResourceManager("fsstrings", System.Reflection.Assembly.GetExecutingAssembly())) let GetString(name:string) = let s = resources.Force().GetString(name, System.Globalization.CultureInfo.CurrentUICulture) @@ -23,7 +23,7 @@ namespace FSharp.Compiler let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl) - let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition() + let funTyC = typeof obj>.GetGenericTypeDefinition() let mkFunTy a b = funTyC.MakeGenericType([| a;b |]) let isNamedType(ty:System.Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer) @@ -64,7 +64,7 @@ namespace FSharp.Compiler /// Function to capture the arguments and then run. let rec capture args ty i = if i >= len || (fmt.[i] = '%' && i+1 >= len) then - let b = new System.Text.StringBuilder() + let b = System.Text.StringBuilder() b.AppendFormat(messageString, (Array.ofList (List.rev args))) |> ignore box(b.ToString()) // REVIEW: For these purposes, this should be a nop, but I'm leaving it @@ -80,13 +80,13 @@ namespace FSharp.Compiler | _ -> capture args ty (i+1) - (unbox (capture [] (typeof<'T>) 0) : 'T) + (unbox (capture [] typeof<'T> 0) : 'T) type ResourceString<'T>(fmtString : string, fmt : Printf.StringFormat<'T>) = member a.Format = createMessageString fmtString fmt - let DeclareResourceString ((messageID : string),(fmt : Printf.StringFormat<'T>)) = + let DeclareResourceString (messageID : string,fmt : Printf.StringFormat<'T>) = let mutable messageString = SR.GetString(messageID) #if DEBUG // validate that the message string exists @@ -112,7 +112,7 @@ namespace FSharp.Compiler pos' <- pos' + 1 if pos' > pos+1 && s.[pos'] = '}' then nHoles <- nHoles + 1 - let ordern = (int) (s.[(pos+1) .. (pos'-1)]) + let ordern = int s.[(pos+1) .. (pos'-1)] order <- order.Add(ordern) pos <- pos' pos <- pos + 1 diff --git a/src/fsharp/symbols/Exprs.fs b/src/fsharp/symbols/Exprs.fs index 16ada4ec575..84da9a9be1f 100644 --- a/src/fsharp/symbols/Exprs.fs +++ b/src/fsharp/symbols/Exprs.fs @@ -1,16 +1,18 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Symbols open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library +open Internal.Utilities.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.Lib +open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Infos -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops open FSharp.Compiler.QuotationTranslator +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.TypeRelations [] @@ -33,13 +35,26 @@ module ExprTranslationImpl = isinstVals: ValMap substVals: ValMap + + /// Indicates that we disable generation of witnesses + suppressWitnesses: bool + + /// All witnesses in scope and their mapping to lambda variables. + // + // Note: this uses an immutable HashMap/Dictionary with an IEqualityComparer that captures TcGlobals, see + // the point where the empty initial object is created. + witnessesInScope: TraitWitnessInfoHashMap + } - static member Empty = + static member Empty g = { vs=ValMap<_>.Empty - tyvs = Map.empty ; + tyvs = Map.empty isinstVals = ValMap<_>.Empty - substVals = ValMap<_>.Empty } + substVals = ValMap<_>.Empty + suppressWitnesses = false + witnessesInScope = EmptyTraitWitnessInfoHashMap g + } member env.BindTypar (v: Typar, gp) = { env with tyvs = env.tyvs.Add(v.Stamp, gp ) } @@ -62,7 +77,7 @@ module ExprTranslationImpl = member env.BindCurriedVals vsl = (env, vsl) ||> List.fold (fun env vs -> env.BindVals vs) - exception IgnoringPartOfQuotedTermWarning of string * Range.range + exception IgnoringPartOfQuotedTermWarning of string * range let wfail (msg, m: range) = failwith (msg + sprintf " at %s" (m.ToString())) @@ -79,7 +94,7 @@ type E = | IfThenElse of FSharpExpr * FSharpExpr * FSharpExpr | DecisionTree of FSharpExpr * (FSharpMemberOrFunctionOrValue list * FSharpExpr) list | DecisionTreeSuccess of int * FSharpExpr list - | Call of FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list + | Call of FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list * FSharpExpr list | NewObject of FSharpMemberOrFunctionOrValue * FSharpType list * FSharpExpr list | LetRec of ( FSharpMemberOrFunctionOrValue * FSharpExpr) list * FSharpExpr | Let of (FSharpMemberOrFunctionOrValue * FSharpExpr) * FSharpExpr @@ -94,7 +109,7 @@ type E = | UnionCaseSet of FSharpExpr * FSharpType * FSharpUnionCase * FSharpField * FSharpExpr | UnionCaseTag of FSharpExpr * FSharpType | UnionCaseTest of FSharpExpr * FSharpType * FSharpUnionCase - | TraitCall of FSharpType list * string * Ast.MemberFlags * FSharpType list * FSharpType list * FSharpExpr list + | TraitCall of FSharpType list * string * SynMemberFlags * FSharpType list * FSharpType list * FSharpExpr list | NewTuple of FSharpType * FSharpExpr list | TupleGet of FSharpType * int * FSharpExpr | Coerce of FSharpType * FSharpExpr @@ -115,21 +130,23 @@ type E = | ILFieldGet of FSharpExpr option * FSharpType * string | ILFieldSet of FSharpExpr option * FSharpType * string * FSharpExpr | ILAsm of string * FSharpType list * FSharpExpr list + | WitnessArg of int /// Used to represent the information at an object expression member and [] FSharpObjectExprOverride(sgn: FSharpAbstractSignature, gps: FSharpGenericParameter list, args: FSharpMemberOrFunctionOrValue list list, body: FSharpExpr) = - member __.Signature = sgn - member __.GenericParameters = gps - member __.CurriedParameterGroups = args - member __.Body = body + member _.Signature = sgn + member _.GenericParameters = gps + member _.CurriedParameterGroups = args + member _.Body = body /// The type of expressions provided through the compiler API. and [] FSharpExpr (cenv, f: (unit -> FSharpExpr) option, e: E, m: range, ty) = + let mutable e = match f with None -> e | Some _ -> Unchecked.defaultof member x.Range = m member x.Type = FSharpType(cenv, ty) member x.cenv = cenv - member x.E = match f with None -> e | Some f -> f().E + member x.E = match box e with null -> e <- f.Value().E; e | _ -> e override x.ToString() = sprintf "%+A" x.E member x.ImmediateSubExpressions = @@ -148,7 +165,7 @@ and [] FSharpExpr (cenv, f: (unit -> FSharpExpr) option, e: E, m: range, | E.NewUnionCase (_unionType, _unionCase, es) -> es | E.NewTuple (_tupleType, es) -> es | E.TupleGet (_tupleType, _itemIndex, tupleExpr) -> [tupleExpr] - | E.Call (objOpt, _b, _c, _d, es) -> (match objOpt with None -> es | Some x -> x :: es) + | E.Call (objOpt, _b, _c, _d, ws, es) -> (match objOpt with None -> ws @ es | Some x -> x :: ws @ es) | E.NewObject (_a, _b, c) -> c | E.FSharpFieldGet (objOpt, _b, _c) -> (match objOpt with None -> [] | Some x -> [x]) | E.FSharpFieldSet (objOpt, _b, _c, d) -> (match objOpt with None -> [d] | Some x -> [x;d]) @@ -177,15 +194,15 @@ and [] FSharpExpr (cenv, f: (unit -> FSharpExpr) option, e: E, m: range, | E.ObjectExpr (_ty, basecall, overrides, interfaceImpls) -> [ yield basecall for m in overrides do yield m.Body - for (_, ms) in interfaceImpls do for m in ms do yield m.Body ] + for _, ms in interfaceImpls do for m in ms do yield m.Body ] | E.DecisionTree (inputExpr, targetCases) -> [ yield inputExpr - for (_targetVars, targetExpr) in targetCases do yield targetExpr ] + for _targetVars, targetExpr in targetCases do yield targetExpr ] | E.DecisionTreeSuccess (_targetNumber, targetArgs) -> targetArgs | E.UnionCaseSet (obj, _unionType, _unionCase, _unionField, valueExpr) -> [ yield obj; yield valueExpr ] | E.TraitCall (_sourceTypes, _traitName, _memberFlags, _paramTypes, _retTypes, args) -> args | E.Unused -> [] // unexpected - + | E.WitnessArg _n -> [] /// The implementation of the conversion operation module FSharpExprConvert = @@ -194,12 +211,12 @@ module FSharpExprConvert = rfref.RecdField.IsCompilerGenerated && rfref.RecdField.IsStatic && rfref.RecdField.IsMutable && - rfref.RecdField.Name.StartsWithOrdinal("init") + rfref.RecdField.LogicalName.StartsWithOrdinal("init") // Match "if [AI_clt](init@41, 6) then IntrinsicFunctions.FailStaticInit () else ()" let (|StaticInitializationCheck|_|) e = match e with - | Expr.Match (_, _, TDSwitch(Expr.Op (TOp.ILAsm ([ AI_clt ], _), _, [Expr.Op (TOp.ValFieldGet rfref, _, _, _) ;_], _), _, _, _), _, _, _) when IsStaticInitializationField rfref -> Some () + | Expr.Match (_, _, TDSwitch(_, Expr.Op (TOp.ILAsm ([ AI_clt ], _), _, [Expr.Op (TOp.ValFieldGet rfref, _, _, _) ;_], _), _, _, _), _, _, _) when IsStaticInitializationField rfref -> Some () | _ -> None // Match "init@41 <- 6" @@ -214,6 +231,15 @@ module FSharpExprConvert = | AI_not -> Some mkCallUnaryNotOperator | _ -> None + let (|ILMulDivOp|_|) e = + match e with + | AI_mul -> Some (mkCallMultiplyOperator, true) + | AI_mul_ovf + | AI_mul_ovf_un -> Some (mkCallMultiplyChecked, true) + | AI_div + | AI_div_un -> Some (mkCallDivisionOperator, false) + | _ -> None + let (|ILBinaryOp|_|) e = match e with | AI_add -> Some mkCallAdditionOperator @@ -222,11 +248,6 @@ module FSharpExprConvert = | AI_sub -> Some mkCallSubtractionOperator | AI_sub_ovf | AI_sub_ovf_un -> Some mkCallSubtractionChecked - | AI_mul -> Some mkCallMultiplyOperator - | AI_mul_ovf - | AI_mul_ovf_un -> Some mkCallMultiplyChecked - | AI_div - | AI_div_un -> Some mkCallDivisionOperator | AI_rem | AI_rem_un -> Some mkCallModulusOperator | AI_ceq -> Some mkCallEqualsOperator @@ -317,9 +338,9 @@ module FSharpExprConvert = | TOp.ValFieldGetAddr (rfref, _), [], _ -> mkStaticRecdFieldGet (rfref, tyargs, m) | TOp.ValFieldGetAddr (rfref, _), [arg], _ -> mkRecdFieldGetViaExprAddr (exprOfExprAddr cenv arg, rfref, tyargs, m) | TOp.UnionCaseFieldGetAddr (uref, n, _), [arg], _ -> mkUnionCaseFieldGetProvenViaExprAddr (exprOfExprAddr cenv arg, uref, tyargs, n, m) - | TOp.ILAsm ([ I_ldflda fspec ], rtys), [arg], _ -> mkAsmExpr ([ mkNormalLdfld fspec ], tyargs, [exprOfExprAddr cenv arg], rtys, m) - | TOp.ILAsm ([ I_ldsflda fspec ], rtys), _, _ -> mkAsmExpr ([ mkNormalLdsfld fspec ], tyargs, args, rtys, m) - | TOp.ILAsm (([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ] ), _), (arr :: idxs), [elemty] -> + | TOp.ILAsm ([ I_ldflda fspec ], retTypes), [arg], _ -> mkAsmExpr ([ mkNormalLdfld fspec ], tyargs, [exprOfExprAddr cenv arg], retTypes, m) + | TOp.ILAsm ([ I_ldsflda fspec ], retTypes), _, _ -> mkAsmExpr ([ mkNormalLdsfld fspec ], tyargs, args, retTypes, m) + | TOp.ILAsm ([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ], _), arr :: idxs, [elemty] -> match shape.Rank, idxs with | 1, [idx1] -> mkCallArrayGet cenv.g m elemty arr idx1 | 2, [idx1; idx2] -> mkCallArray2DGet cenv.g m elemty arr idx1 idx2 @@ -380,7 +401,8 @@ module FSharpExprConvert = // tail recursive ConvExprLinear cenv env e2 (contF << (fun e2R -> E.Sequential(e1R, e2R))) - | Expr.Sequential (x0, x1, ThenDoSeq, _, _) -> E.Sequential(ConvExpr cenv env x0, ConvExpr cenv env x1) + | Expr.Sequential (x0, x1, ThenDoSeq, _, _) -> + E.Sequential(ConvExpr cenv env x0, ConvExpr cenv env x1) |> contF | ModuleValueOrMemberUse cenv.g (vref, vFlags, _f, _fty, tyargs, curriedArgs) when (nonNil tyargs || nonNil curriedArgs) && vref.IsMemberOrModuleBinding -> ConvModuleValueOrMemberUseLinear cenv env (expr, vref, vFlags, tyargs, curriedArgs) contF @@ -404,29 +426,29 @@ module FSharpExprConvert = and ConvModuleValueOrMemberUseLinear (cenv: SymbolEnv) env (expr: Expr, vref, vFlags, tyargs, curriedArgs) contF = let m = expr.Range - let (numEnclTypeArgs, _, isNewObj, _valUseFlags, _isSelfInit, takesInstanceArg, _isPropGet, _isPropSet) = + let numEnclTypeArgs, _, isNewObj, _valUseFlags, _isSelfInit, takesInstanceArg, _isPropGet, _isPropSet = GetMemberCallInfo cenv.g (vref, vFlags) - let isMember, curriedArgInfos = + let isMember, tps, curriedArgInfos = match vref.MemberInfo with | Some _ when not vref.IsExtensionMember -> // This is an application of a member method // We only count one argument block for these. - let _tps, curriedArgInfos, _, _ = GetTypeOfMemberInFSharpForm cenv.g vref - true, curriedArgInfos + let tps, curriedArgInfos, _, _ = GetTypeOfMemberInFSharpForm cenv.g vref + true, tps, curriedArgInfos | _ -> // This is an application of a module value or extension member let arities = arityOfVal vref.Deref - let _tps, curriedArgInfos, _, _ = GetTopValTypeInFSharpForm cenv.g arities vref.Type m - false, curriedArgInfos + let tps, curriedArgInfos, _, _ = GetTopValTypeInFSharpForm cenv.g arities vref.Type m + false, tps, curriedArgInfos // Compute the object arguments as they appear in a compiled call // Strip off the object argument, if any. The curriedArgInfos are already adjusted to compiled member form let objArgs, curriedArgs = match takesInstanceArg, curriedArgs with | false, curriedArgs -> [], curriedArgs - | true, (objArg :: curriedArgs) -> [objArg], curriedArgs + | true, objArg :: curriedArgs -> [objArg], curriedArgs | true, [] -> failwith ("warning: unexpected missing object argument when generating quotation for call to F# object member "+vref.LogicalName) // Check to see if there aren't enough arguments or if there is a tuple-arity mismatch @@ -465,12 +487,35 @@ module FSharpExprConvert = if isMember then let callArgs = (objArgs :: untupledCurriedArgs) |> List.concat let enclTyArgs, methTyArgs = List.splitAfter numEnclTypeArgs tyargs + let witnessArgsR = GetWitnessArgs cenv env vref m tps tyargs // tailcall - ConvObjectModelCallLinear cenv env (isNewObj, FSharpMemberOrFunctionOrValue(cenv, vref), enclTyArgs, methTyArgs, callArgs) contf2 + ConvObjectModelCallLinear cenv env (isNewObj, FSharpMemberOrFunctionOrValue(cenv, vref), enclTyArgs, methTyArgs, witnessArgsR, callArgs) contf2 else let v = FSharpMemberOrFunctionOrValue(cenv, vref) + let witnessArgsR = GetWitnessArgs cenv env vref m vref.Typars tyargs // tailcall - ConvObjectModelCallLinear cenv env (false, v, [], tyargs, List.concat untupledCurriedArgs) contf2 + ConvObjectModelCallLinear cenv env (false, v, [], tyargs, witnessArgsR, List.concat untupledCurriedArgs) contf2 + + and GetWitnessArgs cenv (env: ExprTranslationEnv) (vref: ValRef) m tps tyargs : FSharpExpr list = + let g = cenv.g + if cenv.g.langVersion.SupportsFeature(Features.LanguageFeature.WitnessPassing) && not env.suppressWitnesses then + let witnessExprs = + match ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcValF g cenv.amap m tps tyargs with + // There is a case where optimized code makes expressions that do a shift-left on the 'char' + // type. There is no witness for this case. This is due to the code + // let inline HashChar (x:char) = (# "or" (# "shl" x 16 : int #) x : int #) + // in FSharp.Core. + | ErrorResult _ when vref.LogicalName = "op_LeftShift" && tyargs.Length = 1 -> [] + | res -> CommitOperationResult res + let env = { env with suppressWitnesses = true } + witnessExprs |> List.map (fun arg -> + match arg with + | Choice1Of2 traitInfo -> + ConvWitnessInfo cenv env m traitInfo + | Choice2Of2 arg -> + ConvExpr cenv env arg) + else + [] and ConvExprPrim (cenv: SymbolEnv) (env: ExprTranslationEnv) expr = // Eliminate integer 'for' loops @@ -495,11 +540,11 @@ module FSharpExprConvert = | Expr.Let _ // big linear sequences of 'let' | Expr.Match _ // big linear sequences of 'match ... -> ....' | Expr.Sequential _ -> - ConvExprPrimLinear cenv env expr (fun e -> e) + ConvExprPrimLinear cenv env expr id | ModuleValueOrMemberUse cenv.g (vref, vFlags, _f, _fty, tyargs, curriedArgs) when (* (nonNil tyargs || nonNil curriedArgs) && *) vref.IsMemberOrModuleBinding -> // Process applications of top-level values in a tail-recursive way - ConvModuleValueOrMemberUseLinear cenv env (expr, vref, vFlags, tyargs, curriedArgs) (fun e -> e) + ConvModuleValueOrMemberUseLinear cenv env (expr, vref, vFlags, tyargs, curriedArgs) id | Expr.Val (vref, _vFlags, m) -> ConvValRef cenv env m vref @@ -548,11 +593,11 @@ module FSharpExprConvert = | Expr.Obj (_lambdaId, ty, _basev, basecall, overrides, iimpls, _m) -> let basecallR = ConvExpr cenv env basecall let ConvertMethods methods = - [ for (TObjExprMethod(slotsig, _, tps, tmvs, body, _)) in methods -> + [ for TObjExprMethod(slotsig, _, tps, tmvs, body, _) in methods -> let vslR = List.map (List.map (ConvVal cenv)) tmvs let sgn = FSharpAbstractSignature(cenv, slotsig) let tpsR = [ for tp in tps -> FSharpGenericParameter(cenv, tp) ] - let env = ExprTranslationEnv.Empty.BindTypars (Seq.zip tps tpsR |> Seq.toList) + let env = env.BindTypars (Seq.zip tps tpsR |> Seq.toList) let env = env.BindCurriedVals tmvs let bodyR = ConvExpr cenv env body FSharpObjectExprOverride(sgn, tpsR, vslR, bodyR) ] @@ -668,9 +713,9 @@ module FSharpExprConvert = let op = mkCallHash cenv.g m ty arg ConvExprPrim cenv env op - | TOp.ILCall (_, _, _, _, _, _, _, mref, _, _, _), [], + | TOp.ILCall (_, _, _, _, _, _, _, ilMethRef, _, _, _), [], [Expr.Op (TOp.ILAsm ([ I_ldtoken (ILToken.ILType _) ], _), [ty], _, _)] - when mref.DeclaringTypeRef.Name = "System.Type" && mref.Name = "GetTypeFromHandle" -> + when ilMethRef.DeclaringTypeRef.Name = "System.Type" && ilMethRef.Name = "GetTypeFromHandle" -> let op = mkCallTypeOf cenv.g m ty ConvExprPrim cenv env op @@ -681,12 +726,14 @@ module FSharpExprConvert = let elemTy = tyOfExpr cenv.g arg let nullVal = mkNull m elemTy let op = mkCallNotEqualsOperator cenv.g m elemTy arg nullVal + let env = { env with suppressWitnesses=true } ConvExprPrim cenv env op | TOp.ILAsm ([ I_ldlen; AI_conv DT_I4 ], _), _, [arr] -> let arrayTy = tyOfExpr cenv.g arr let elemTy = destArrayTy cenv.g arrayTy let op = mkCallArrayLength cenv.g m elemTy arr + let env = { env with suppressWitnesses=true } ConvExprPrim cenv env op | TOp.ILAsm ([ I_newarr (ILArrayShape [(Some 0, None)], _)], _), [elemTy], xa -> @@ -710,6 +757,19 @@ module FSharpExprConvert = let op = binaryOp cenv.g m ty arg1 arg2 ConvExprPrim cenv env op + // For units of measure some binary operators change their return type, e.g. a * b where each is int gives int + | TOp.ILAsm ([ ILMulDivOp (binaryOp, isMul) ], _), _, [arg1;arg2] -> + let argty1 = tyOfExpr cenv.g arg1 + let argty2 = tyOfExpr cenv.g arg2 + let rty = + match getMeasureOfType cenv.g argty1, getMeasureOfType cenv.g argty2 with + | Some (tcref, ms1), Some (_tcref2, ms2) -> mkAppTy tcref [TType_measure (Measure.Prod(ms1, if isMul then ms2 else Measure.Inv ms2))] + | Some _, None -> argty1 + | None, Some _ -> argty2 + | None, None -> argty1 + let op = binaryOp cenv.g m argty1 argty2 rty arg1 arg2 + ConvExprPrim cenv env op + | TOp.ILAsm ([ ILConvertOp convertOp1; ILConvertOp convertOp2 ], _), _, [arg] -> let ty1 = tyOfExpr cenv.g arg let op1 = convertOp1 cenv.g m ty1 arg @@ -720,8 +780,8 @@ module FSharpExprConvert = | TOp.ILAsm ([ ILConvertOp convertOp ], [TType_app (tcref,_)]), _, [arg] -> let ty = tyOfExpr cenv.g arg let op = - if tyconRefEq cenv.g tcref cenv.g.char_tcr - then mkCallToCharOperator cenv.g m ty arg + if tyconRefEq cenv.g tcref cenv.g.char_tcr then + mkCallToCharOperator cenv.g m ty arg else convertOp cenv.g m ty arg ConvExprPrim cenv env op @@ -729,8 +789,8 @@ module FSharpExprConvert = let raiseExpr = mkCallRaise cenv.g m (tyOfExpr cenv.g expr) arg1 ConvExprPrim cenv env raiseExpr - | TOp.ILAsm (il, _), tyargs, args -> - E.ILAsm(sprintf "%+A" il, ConvTypes cenv tyargs, ConvExprs cenv env args) + | TOp.ILAsm (instrs, _), tyargs, args -> + E.ILAsm(sprintf "%+A" instrs, ConvTypes cenv tyargs, ConvExprs cenv env args) | TOp.ExnConstr tcref, tyargs, args -> E.NewRecord(ConvType cenv (mkAppTy tcref tyargs), ConvExprs cenv env args) @@ -751,7 +811,7 @@ module FSharpExprConvert = | TOp.ExnFieldGet (tcref, i), [], [obj] -> let exnc = stripExnEqns tcref let fspec = exnc.TrueInstanceFieldsAsList.[i] - let fref = mkRecdFieldRef tcref fspec.Name + let fref = mkRecdFieldRef tcref fspec.LogicalName let typR = ConvType cenv (mkAppTy tcref tyargs) let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkAppTy tcref [], m, cenv.g.exn_ty)) E.FSharpFieldGet(Some objR, typR, ConvRecdFieldRef cenv fref) @@ -759,7 +819,7 @@ module FSharpExprConvert = | TOp.ExnFieldSet (tcref, i), [], [obj;e2] -> let exnc = stripExnEqns tcref let fspec = exnc.TrueInstanceFieldsAsList.[i] - let fref = mkRecdFieldRef tcref fspec.Name + let fref = mkRecdFieldRef tcref fspec.LogicalName let typR = ConvType cenv (mkAppTy tcref tyargs) let objR = ConvExpr cenv env (mkCoerceExpr (obj, mkAppTy tcref [], m, cenv.g.exn_ty)) E.FSharpFieldSet(Some objR, typR, ConvRecdFieldRef cenv fref, ConvExpr cenv env e2) @@ -805,13 +865,13 @@ module FSharpExprConvert = else lim1 E.FastIntegerForLoop(ConvExpr cenv env lim0, ConvExpr cenv env lim1, ConvExpr cenv env body, dir <> FSharpForLoopDown) - | TOp.ILCall (_, _, _, isNewObj, valUseFlags, _isProp, _, ilMethRef, enclTypeArgs, methTypeArgs, _tys), [], callArgs -> - ConvILCall cenv env (isNewObj, valUseFlags, ilMethRef, enclTypeArgs, methTypeArgs, callArgs, m) + | TOp.ILCall (_, _, _, isCtor, valUseFlag, _, _, ilMethRef, enclTypeInst, methInst, _), [], callArgs -> + ConvILCall cenv env (isCtor, valUseFlag, ilMethRef, enclTypeInst, methInst, callArgs, m) | TOp.TryFinally _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [_], e2, _, _)] -> E.TryFinally(ConvExpr cenv env e1, ConvExpr cenv env e2) - | TOp.TryCatch _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> + | TOp.TryWith _, [_resty], [Expr.Lambda (_, _, _, [_], e1, _, _); Expr.Lambda (_, _, _, [vf], ef, _, _); Expr.Lambda (_, _, _, [vh], eh, _, _)] -> let vfR = ConvVal cenv vf let envf = env.BindVal vf let vhR = ConvVal cenv vh @@ -839,9 +899,29 @@ module FSharpExprConvert = ConvExprPrim cenv env replExpr | _ -> wfail (sprintf "unhandled construct in AST", m) + | Expr.WitnessArg (traitInfo, _m) -> + ConvWitnessInfoPrim cenv env traitInfo | _ -> wfail (sprintf "unhandled construct in AST", expr.Range) + and ConvWitnessInfoPrim _cenv env traitInfo : E = + let witnessInfo = traitInfo.TraitKey + let env = { env with suppressWitnesses = true } + // First check if this is a witness in ReflectedDefinition code + if env.witnessesInScope.ContainsKey witnessInfo then + let witnessArgIdx = env.witnessesInScope.[witnessInfo] + E.WitnessArg(witnessArgIdx) + // Otherwise it is a witness in a quotation literal + else + //failwith "witness not found" + E.WitnessArg(-1) + + and ConvWitnessInfo cenv env m traitInfo : FSharpExpr = + let g = cenv.g + let witnessInfo = traitInfo.TraitKey + let witnessTy = GenWitnessTy g witnessInfo + let traitInfoR = ConvWitnessInfoPrim cenv env traitInfo + Mk cenv m witnessTy traitInfoR and ConvLetBind cenv env (bind : Binding) = match bind.Expr with @@ -893,7 +973,7 @@ module FSharpExprConvert = let enclosingType = generalizedTyconRef tcref let makeCall minfo = - ConvObjectModelCallLinear cenv env (isNewObj, minfo, enclTypeArgs, methTypeArgs, callArgs) id + ConvObjectModelCallLinear cenv env (isNewObj, minfo, enclTypeArgs, methTypeArgs, [], callArgs) id let makeFSCall isMember (vr: ValRef) = let memOrVal = @@ -911,7 +991,7 @@ module FSharpExprConvert = try nlr.EnclosingEntity.Deref with _ -> - failwithf "Failed to resolve type '%s'" (nlr.EnclosingEntity.CompiledName) + failwithf "Failed to resolve type '%s'" nlr.EnclosingEntity.CompiledName let ccu = nlr.EnclosingEntity.nlr.Ccu let vName = nlr.ItemKey.PartialKey.LogicalName // this is actually compiled name let findByName = @@ -959,7 +1039,7 @@ module FSharpExprConvert = elif enclosingEntity.IsRecordTycon then if isProp then let name = PrettyNaming.ChopPropertyName vName - let projR = ConvRecdFieldRef cenv (RFRef(tcref, name)) + let projR = ConvRecdFieldRef cenv (RecdFieldRef(tcref, name)) let objR = ConvLValueExpr cenv env callArgs.Head if isPropGet then E.FSharpFieldGet(Some objR, typR, projR) @@ -977,18 +1057,18 @@ module FSharpExprConvert = E.UnionCaseTag(objR, typR) elif vName.StartsWithOrdinal("New") then let name = vName.Substring 3 - let mkR = ConvUnionCaseRef cenv (UCRef(tcref, name)) + let mkR = ConvUnionCaseRef cenv (UnionCaseRef(tcref, name)) let argsR = ConvExprs cenv env callArgs E.NewUnionCase(typR, mkR, argsR) elif vName.StartsWithOrdinal("Is") then let name = vName.Substring 2 - let mkR = ConvUnionCaseRef cenv (UCRef(tcref, name)) + let mkR = ConvUnionCaseRef cenv (UnionCaseRef(tcref, name)) let objR = ConvExpr cenv env callArgs.Head E.UnionCaseTest(objR, typR, mkR) else match subClass with | Some name -> - let ucref = UCRef(tcref, name) + let ucref = UnionCaseRef(tcref, name) let mkR = ConvUnionCaseRef cenv ucref let objR = ConvLValueExpr cenv env callArgs.Head let projR = FSharpField(cenv, ucref, ucref.Index) @@ -1044,7 +1124,7 @@ module FSharpExprConvert = let isStatic = isCtor || ilMethRef.CallingConv.IsStatic let scoref = ilMethRef.DeclaringTypeRef.Scope let typars1 = tcref.Typars m - let typars2 = [ 1 .. ilMethRef.GenericArity ] |> List.map (fun _ -> NewRigidTypar "T" m) + let typars2 = [ 1 .. ilMethRef.GenericArity ] |> List.map (fun _ -> Construct.NewRigidTypar "T" m) let tinst1 = typars1 |> generalizeTypars let tinst2 = typars2 |> generalizeTypars // TODO: this will not work for curried methods in F# classes. @@ -1077,7 +1157,7 @@ module FSharpExprConvert = with e -> failwithf "An IL call to '%s' could not be resolved: %s" (ilMethRef.ToString()) e.Message - and ConvObjectModelCallLinear cenv env (isNewObj, v: FSharpMemberOrFunctionOrValue, enclTyArgs, methTyArgs, callArgs) contF = + and ConvObjectModelCallLinear cenv env (isNewObj, v: FSharpMemberOrFunctionOrValue, enclTyArgs, methTyArgs, witnessArgsR: FSharpExpr list, callArgs) contF = let enclTyArgsR = ConvTypes cenv enclTyArgs let methTyArgsR = ConvTypes cenv methTyArgs let obj, callArgs = @@ -1093,8 +1173,7 @@ module FSharpExprConvert = if isNewObj then E.NewObject(v, enclTyArgsR, callArgsR) else - E.Call(objR, v, enclTyArgsR, methTyArgsR, callArgsR)) - + E.Call(objR, v, enclTyArgsR, methTyArgsR, witnessArgsR, callArgsR)) and ConvExprs cenv env args = List.map (ConvExpr cenv env) args @@ -1108,7 +1187,7 @@ module FSharpExprConvert = and ConvTargetsLinear cenv env tgs contF = match tgs with | [] -> contF [] - | TTarget(vars, rhs, _) :: rest -> + | TTarget(vars, rhs, _, _) :: rest -> let varsR = (List.rev vars) |> List.map (ConvVal cenv) ConvExprLinear cenv env rhs (fun targetR -> ConvTargetsLinear cenv env rest (fun restR -> @@ -1117,14 +1196,14 @@ module FSharpExprConvert = and ConvValRef cenv env m (vref: ValRef) = let v = vref.Deref if env.isinstVals.ContainsVal v then - let (ty, e) = env.isinstVals.[v] + let ty, e = env.isinstVals.[v] ConvExprPrim cenv env (mkCallUnbox cenv.g m ty e) elif env.substVals.ContainsVal v then let e = env.substVals.[v] ConvExprPrim cenv env e - elif v.BaseOrThisInfo = CtorThisVal then + elif v.IsCtorThisVal then E.ThisValue(ConvType cenv v.Type) - elif v.BaseOrThisInfo = BaseVal then + elif v.IsBaseVal then E.BaseValue(ConvType cenv v.Type) else E.Value(FSharpMemberOrFunctionOrValue(cenv, vref)) @@ -1163,7 +1242,7 @@ module FSharpExprConvert = and ConvDecisionTreePrim cenv env dtreeRetTy x = match x with - | TDSwitch(e1, csl, dfltOpt, m) -> + | TDSwitch(_, e1, csl, dfltOpt, m) -> let acc = match dfltOpt with | Some d -> ConvDecisionTreePrim cenv env dtreeRetTy d @@ -1192,21 +1271,24 @@ module FSharpExprConvert = // Decompile cached isinst tests match e1 with | Expr.Val (vref, _, _) when env.isinstVals.ContainsVal vref.Deref -> - let (ty, e) = env.isinstVals.[vref.Deref] + let ty, e = env.isinstVals.[vref.Deref] let tyR = ConvType cenv ty let eR = ConvExpr cenv env e // note: reverse the branches - a null test is a failure of an isinst test E.IfThenElse (E.TypeTest (tyR, eR) |> Mk cenv m cenv.g.bool_ty, acc, ConvDecisionTree cenv env dtreeRetTy dtree m) | _ -> let ty = tyOfExpr cenv.g e1 - let eq = mkCallEqualsOperator cenv.g m ty e1 (Expr.Const (Const.Zero, m, ty)) - let eqR = ConvExpr cenv env eq + let eqR = + let eq = mkCallEqualsOperator cenv.g m ty e1 (Expr.Const (Const.Zero, m, ty)) + let env = { env with suppressWitnesses = true } + ConvExpr cenv env eq E.IfThenElse (eqR, ConvDecisionTree cenv env dtreeRetTy dtree m, acc) | DecisionTreeTest.IsInst (_srcty, tgty) -> let e1R = ConvExpr cenv env e1 E.IfThenElse (E.TypeTest (ConvType cenv tgty, e1R) |> Mk cenv m cenv.g.bool_ty, ConvDecisionTree cenv env dtreeRetTy dtree m, acc) | DecisionTreeTest.ActivePatternCase _ -> wfail("unexpected Test.ActivePatternCase test in quoted expression", m) - | DecisionTreeTest.ArrayLength _ -> wfail("FSharp.Compiler.Service cannot yet return array pattern matching", m)) + | DecisionTreeTest.ArrayLength _ -> wfail("FSharp.Compiler.Service cannot yet return array pattern matching", m) + | DecisionTreeTest.Error m -> wfail("error recovery", m)) | TDSuccess (args, n) -> // TAST stores pattern bindings in reverse order for some reason @@ -1231,15 +1313,15 @@ module FSharpExprConvert = /// The contents of the F# assembly as provided through the compiler API type FSharpAssemblyContents(cenv: SymbolEnv, mimpls: TypedImplFile list) = - new (g, thisCcu, thisCcuType, tcImports, mimpls) = FSharpAssemblyContents(SymbolEnv(g, thisCcu, thisCcuType, tcImports), mimpls) + new (tcGlobals, thisCcu, thisCcuType, tcImports, mimpls) = FSharpAssemblyContents(SymbolEnv(tcGlobals, thisCcu, thisCcuType, tcImports), mimpls) - member __.ImplementationFiles = + member _.ImplementationFiles = [ for mimpl in mimpls -> FSharpImplementationFileContents(cenv, mimpl)] and FSharpImplementationFileDeclaration = - | Entity of FSharpEntity * FSharpImplementationFileDeclaration list - | MemberOrFunctionOrValue of FSharpMemberOrFunctionOrValue * FSharpMemberOrFunctionOrValue list list * FSharpExpr - | InitAction of FSharpExpr + | Entity of entity: FSharpEntity * declarations: FSharpImplementationFileDeclaration list + | MemberOrFunctionOrValue of value: FSharpMemberOrFunctionOrValue * curriedArgs: FSharpMemberOrFunctionOrValue list list * body: FSharpExpr + | InitAction of action: FSharpExpr and FSharpImplementationFileContents(cenv, mimpl) = let (TImplFile (qname, _pragmas, ModuleOrNamespaceExprWithSig(_, mdef, _), hasExplicitEntryPoint, isScript, _anonRecdTypes)) = mimpl @@ -1252,14 +1334,14 @@ and FSharpImplementationFileContents(cenv, mimpl) = let v = FSharpMemberOrFunctionOrValue(cenv, mkLocalValRef v) let gps = v.GenericParameters let vslR = List.map (List.map (FSharpExprConvert.ConvVal cenv)) vsl - let env = ExprTranslationEnv.Empty.BindTypars (Seq.zip tps gps |> Seq.toList) + let env = ExprTranslationEnv.Empty(cenv.g).BindTypars (Seq.zip tps gps |> Seq.toList) let env = env.BindCurriedVals vsl let e = FSharpExprConvert.ConvExprOnDemand cenv env body FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vslR, e) and getDecls mdef = match mdef with - | TMDefRec(_isRec, tycons, mbinds, _m) -> + | TMDefRec(_isRec, _opens, tycons, mbinds, _m) -> [ for tycon in tycons do let entity = FSharpEntity(cenv, mkLocalEntityRef tycon) yield FSharpImplementationFileDeclaration.Entity(entity, []) @@ -1273,63 +1355,113 @@ and FSharpImplementationFileContents(cenv, mimpl) = | TMAbstract mexpr -> getDecls2 mexpr | TMDefLet(bind, _m) -> [ yield getBind bind ] + | TMDefOpens _ -> + [ ] | TMDefDo(expr, _m) -> - [ let expr = FSharpExprConvert.ConvExprOnDemand cenv ExprTranslationEnv.Empty expr + [ let expr = FSharpExprConvert.ConvExprOnDemand cenv (ExprTranslationEnv.Empty(cenv.g)) expr yield FSharpImplementationFileDeclaration.InitAction expr ] | TMDefs mdefs -> [ for mdef in mdefs do yield! getDecls mdef ] - member __.QualifiedName = qname.Text - member __.FileName = qname.Range.FileName - member __.Declarations = getDecls mdef - member __.HasExplicitEntryPoint = hasExplicitEntryPoint - member __.IsScript = isScript + member _.QualifiedName = qname.Text + member _.FileName = qname.Range.FileName + member _.Declarations = getDecls mdef + member _.HasExplicitEntryPoint = hasExplicitEntryPoint + member _.IsScript = isScript -module BasicPatterns = +module FSharpExprPatterns = let (|Value|_|) (e: FSharpExpr) = match e.E with E.Value v -> Some v | _ -> None + let (|Const|_|) (e: FSharpExpr) = match e.E with E.Const (v, ty) -> Some (v, ty) | _ -> None + let (|TypeLambda|_|) (e: FSharpExpr) = match e.E with E.TypeLambda (v, e) -> Some (v, e) | _ -> None + let (|Lambda|_|) (e: FSharpExpr) = match e.E with E.Lambda (v, e) -> Some (v, e) | _ -> None + let (|Application|_|) (e: FSharpExpr) = match e.E with E.Application (f, tys, e) -> Some (f, tys, e) | _ -> None + let (|IfThenElse|_|) (e: FSharpExpr) = match e.E with E.IfThenElse (e1, e2, e3) -> Some (e1, e2, e3) | _ -> None + let (|Let|_|) (e: FSharpExpr) = match e.E with E.Let ((v, e), b) -> Some ((v, e), b) | _ -> None + let (|LetRec|_|) (e: FSharpExpr) = match e.E with E.LetRec (ves, b) -> Some (ves, b) | _ -> None + let (|NewRecord|_|) (e: FSharpExpr) = match e.E with E.NewRecord (ty, es) -> Some (ty, es) | _ -> None + let (|NewAnonRecord|_|) (e: FSharpExpr) = match e.E with E.NewAnonRecord (ty, es) -> Some (ty, es) | _ -> None + let (|NewUnionCase|_|) (e: FSharpExpr) = match e.E with E.NewUnionCase (e, tys, es) -> Some (e, tys, es) | _ -> None + let (|NewTuple|_|) (e: FSharpExpr) = match e.E with E.NewTuple (ty, es) -> Some (ty, es) | _ -> None + let (|TupleGet|_|) (e: FSharpExpr) = match e.E with E.TupleGet (ty, n, es) -> Some (ty, n, es) | _ -> None - let (|Call|_|) (e: FSharpExpr) = match e.E with E.Call (a, b, c, d, e) -> Some (a, b, c, d, e) | _ -> None + + let (|Call|_|) (e: FSharpExpr) = match e.E with E.Call (a, b, c, d, _e, f) -> Some (a, b, c, d, f) | _ -> None + + let (|CallWithWitnesses|_|) (e: FSharpExpr) = match e.E with E.Call (a, b, c, d, e, f) -> Some (a, b, c, d, e, f) | _ -> None + let (|NewObject|_|) (e: FSharpExpr) = match e.E with E.NewObject (a, b, c) -> Some (a, b, c) | _ -> None + let (|FSharpFieldGet|_|) (e: FSharpExpr) = match e.E with E.FSharpFieldGet (a, b, c) -> Some (a, b, c) | _ -> None + let (|AnonRecordGet|_|) (e: FSharpExpr) = match e.E with E.AnonRecordGet (a, b, c) -> Some (a, b, c) | _ -> None + let (|FSharpFieldSet|_|) (e: FSharpExpr) = match e.E with E.FSharpFieldSet (a, b, c, d) -> Some (a, b, c, d) | _ -> None + let (|UnionCaseGet|_|) (e: FSharpExpr) = match e.E with E.UnionCaseGet (a, b, c, d) -> Some (a, b, c, d) | _ -> None + let (|UnionCaseTag|_|) (e: FSharpExpr) = match e.E with E.UnionCaseTag (a, b) -> Some (a, b) | _ -> None + let (|UnionCaseTest|_|) (e: FSharpExpr) = match e.E with E.UnionCaseTest (a, b, c) -> Some (a, b, c) | _ -> None + let (|NewArray|_|) (e: FSharpExpr) = match e.E with E.NewArray (a, b) -> Some (a, b) | _ -> None + let (|Coerce|_|) (e: FSharpExpr) = match e.E with E.Coerce (a, b) -> Some (a, b) | _ -> None + let (|Quote|_|) (e: FSharpExpr) = match e.E with E.Quote a -> Some a | _ -> None + let (|TypeTest|_|) (e: FSharpExpr) = match e.E with E.TypeTest (a, b) -> Some (a, b) | _ -> None + let (|Sequential|_|) (e: FSharpExpr) = match e.E with E.Sequential (a, b) -> Some (a, b) | _ -> None + let (|FastIntegerForLoop|_|) (e: FSharpExpr) = match e.E with E.FastIntegerForLoop (a, b, c, d) -> Some (a, b, c, d) | _ -> None + let (|WhileLoop|_|) (e: FSharpExpr) = match e.E with E.WhileLoop (a, b) -> Some (a, b) | _ -> None + let (|TryFinally|_|) (e: FSharpExpr) = match e.E with E.TryFinally (a, b) -> Some (a, b) | _ -> None + let (|TryWith|_|) (e: FSharpExpr) = match e.E with E.TryWith (a, b, c, d, e) -> Some (a, b, c, d, e) | _ -> None + let (|NewDelegate|_|) (e: FSharpExpr) = match e.E with E.NewDelegate (ty, e) -> Some (ty, e) | _ -> None + let (|DefaultValue|_|) (e: FSharpExpr) = match e.E with E.DefaultValue ty -> Some ty | _ -> None + let (|AddressSet|_|) (e: FSharpExpr) = match e.E with E.AddressSet (a, b) -> Some (a, b) | _ -> None + let (|ValueSet|_|) (e: FSharpExpr) = match e.E with E.ValueSet (a, b) -> Some (a, b) | _ -> None + let (|AddressOf|_|) (e: FSharpExpr) = match e.E with E.AddressOf a -> Some a | _ -> None + let (|ThisValue|_|) (e: FSharpExpr) = match e.E with E.ThisValue a -> Some a | _ -> None + let (|BaseValue|_|) (e: FSharpExpr) = match e.E with E.BaseValue a -> Some a | _ -> None + let (|ILAsm|_|) (e: FSharpExpr) = match e.E with E.ILAsm (a, b, c) -> Some (a, b, c) | _ -> None + let (|ILFieldGet|_|) (e: FSharpExpr) = match e.E with E.ILFieldGet (a, b, c) -> Some (a, b, c) | _ -> None + let (|ILFieldSet|_|) (e: FSharpExpr) = match e.E with E.ILFieldSet (a, b, c, d) -> Some (a, b, c, d) | _ -> None + let (|ObjectExpr|_|) (e: FSharpExpr) = match e.E with E.ObjectExpr (a, b, c, d) -> Some (a, b, c, d) | _ -> None + let (|DecisionTree|_|) (e: FSharpExpr) = match e.E with E.DecisionTree (a, b) -> Some (a, b) | _ -> None + let (|DecisionTreeSuccess|_|) (e: FSharpExpr) = match e.E with E.DecisionTreeSuccess (a, b) -> Some (a, b) | _ -> None + let (|UnionCaseSet|_|) (e: FSharpExpr) = match e.E with E.UnionCaseSet (a, b, c, d, e) -> Some (a, b, c, d, e) | _ -> None + let (|TraitCall|_|) (e: FSharpExpr) = match e.E with E.TraitCall (a, b, c, d, e, f) -> Some (a, b, c, d, e, f) | _ -> None + let (|WitnessArg|_|) (e: FSharpExpr) = match e.E with E.WitnessArg n -> Some n | _ -> None + diff --git a/src/fsharp/symbols/Exprs.fsi b/src/fsharp/symbols/Exprs.fsi index 96c12024cc8..30e1ecad8d9 100644 --- a/src/fsharp/symbols/Exprs.fsi +++ b/src/fsharp/symbols/Exprs.fsi @@ -1,25 +1,24 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace rec FSharp.Compiler.Symbols -open FSharp.Compiler +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.Syntax open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Tast -open FSharp.Compiler.Range -open FSharp.Compiler.CompileOps - +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree /// Represents the definitional contents of an assembly, as seen by the F# language type public FSharpAssemblyContents = - internal new : tcGlobals: TcGlobals * thisCcu: CcuThunk * thisCcuType: ModuleOrNamespaceType option * tcImports: TcImports * mimpls: TypedImplFile list -> FSharpAssemblyContents + internal new: tcGlobals: TcGlobals * thisCcu: CcuThunk * thisCcuType: ModuleOrNamespaceType option * tcImports: TcImports * mimpls: TypedImplFile list -> FSharpAssemblyContents /// The contents of the implementation files in the assembly member ImplementationFiles: FSharpImplementationFileContents list /// Represents the definitional contents of a single file or fragment in an assembly, as seen by the F# language -and [] public FSharpImplementationFileContents = - internal new : cenv: SymbolEnv * mimpl: TypedImplFile -> FSharpImplementationFileContents +type public FSharpImplementationFileContents = + internal new: cenv: SymbolEnv * mimpl: TypedImplFile -> FSharpImplementationFileContents /// The qualified name acts to fully-qualify module specifications and implementations member QualifiedName: string @@ -28,7 +27,7 @@ and [] public FSharpImplementationFileContents = member FileName: string /// Get the declarations that make up this implementation file - member Declarations : FSharpImplementationFileDeclaration list + member Declarations: FSharpImplementationFileDeclaration list /// Indicates if the implementation file is a script member IsScript: bool @@ -37,185 +36,193 @@ and [] public FSharpImplementationFileContents = member HasExplicitEntryPoint: bool /// Represents a declaration in an implementation file, as seen by the F# language -and public FSharpImplementationFileDeclaration = +[] +type public FSharpImplementationFileDeclaration = /// Represents the declaration of a type - | Entity of FSharpEntity * FSharpImplementationFileDeclaration list + | Entity of entity: FSharpEntity * declarations: FSharpImplementationFileDeclaration list /// Represents the declaration of a member, function or value, including the parameters and body of the member - | MemberOrFunctionOrValue of FSharpMemberOrFunctionOrValue * FSharpMemberOrFunctionOrValue list list * FSharpExpr + | MemberOrFunctionOrValue of value: FSharpMemberOrFunctionOrValue * curriedArgs: FSharpMemberOrFunctionOrValue list list * body: FSharpExpr /// Represents the declaration of a static initialization action - | InitAction of FSharpExpr + | InitAction of action: FSharpExpr /// Represents a checked and reduced expression, as seen by the F# language. The active patterns /// in 'FSharp.Compiler.SourceCodeServices' can be used to analyze information about the expression. /// /// Pattern matching is reduced to decision trees and conditional tests. Some other /// constructs may be represented in reduced form. -and [] public FSharpExpr = +[] +type public FSharpExpr = /// The range of the expression - member Range : range + member Range: range /// The type of the expression - member Type : FSharpType + member Type: FSharpType /// The immediate sub-expressions of the expression. - member ImmediateSubExpressions : FSharpExpr list + member ImmediateSubExpressions: FSharpExpr list /// Represents a checked method in an object expression, as seen by the F# language. -and [] public FSharpObjectExprOverride = +[] +type public FSharpObjectExprOverride = /// The signature of the implemented abstract slot - member Signature : FSharpAbstractSignature + member Signature: FSharpAbstractSignature /// The generic parameters of the method - member GenericParameters : FSharpGenericParameter list + member GenericParameters: FSharpGenericParameter list /// The parameters of the method - member CurriedParameterGroups : FSharpMemberOrFunctionOrValue list list + member CurriedParameterGroups: FSharpMemberOrFunctionOrValue list list /// The expression that forms the body of the method - member Body : FSharpExpr + member Body: FSharpExpr /// A collection of active patterns to analyze expressions -module public BasicPatterns = +module public FSharpExprPatterns = /// Matches expressions which are uses of values - val (|Value|_|) : FSharpExpr -> FSharpMemberOrFunctionOrValue option + val (|Value|_|): FSharpExpr -> FSharpMemberOrFunctionOrValue option /// Matches expressions which are the application of function values - val (|Application|_|) : FSharpExpr -> (FSharpExpr * FSharpType list * FSharpExpr list) option + val (|Application|_|): FSharpExpr -> (FSharpExpr * FSharpType list * FSharpExpr list) option /// Matches expressions which are type abstractions - val (|TypeLambda|_|) : FSharpExpr -> (FSharpGenericParameter list * FSharpExpr) option + val (|TypeLambda|_|): FSharpExpr -> (FSharpGenericParameter list * FSharpExpr) option /// Matches expressions with a decision expression, each branch of which ends in DecisionTreeSuccess passing control and values to one of the targets. - val (|DecisionTree|_|) : FSharpExpr -> (FSharpExpr * (FSharpMemberOrFunctionOrValue list * FSharpExpr) list) option + val (|DecisionTree|_|): FSharpExpr -> (FSharpExpr * (FSharpMemberOrFunctionOrValue list * FSharpExpr) list) option /// Special expressions at the end of a conditional decision structure in the decision expression node of a DecisionTree . /// The given expressions are passed as values to the decision tree target. - val (|DecisionTreeSuccess|_|) : FSharpExpr -> (int * FSharpExpr list) option + val (|DecisionTreeSuccess|_|): FSharpExpr -> (int * FSharpExpr list) option /// Matches expressions which are lambda abstractions - val (|Lambda|_|) : FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option + val (|Lambda|_|): FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option /// Matches expressions which are conditionals - val (|IfThenElse|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr) option + val (|IfThenElse|_|): FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr) option /// Matches expressions which are let definitions - val (|Let|_|) : FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr) * FSharpExpr) option + val (|Let|_|): FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr) * FSharpExpr) option /// Matches expressions which are calls to members or module-defined functions. When calling curried functions and members the /// arguments are collapsed to a single collection of arguments, as done in the compiled version of these. - val (|Call|_|) : FSharpExpr -> (FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list) option + val (|Call|_|): FSharpExpr -> (FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list) option + + /// Like Call but also indicates witness arguments + val (|CallWithWitnesses|_|): FSharpExpr -> (FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list * FSharpExpr list) option /// Matches expressions which are calls to object constructors - val (|NewObject|_|) : FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpType list * FSharpExpr list) option + val (|NewObject|_|): FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpType list * FSharpExpr list) option /// Matches expressions which are uses of the 'this' value - val (|ThisValue|_|) : FSharpExpr -> FSharpType option + val (|ThisValue|_|): FSharpExpr -> FSharpType option /// Matches expressions which are uses of the 'base' value - val (|BaseValue|_|) : FSharpExpr -> FSharpType option + val (|BaseValue|_|): FSharpExpr -> FSharpType option /// Matches expressions which are quotation literals - val (|Quote|_|) : FSharpExpr -> FSharpExpr option + val (|Quote|_|): FSharpExpr -> FSharpExpr option /// Matches expressions which are let-rec definitions - val (|LetRec|_|) : FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr) list * FSharpExpr) option + val (|LetRec|_|): FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr) list * FSharpExpr) option /// Matches record expressions - val (|NewRecord|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option + val (|NewRecord|_|): FSharpExpr -> (FSharpType * FSharpExpr list) option /// Matches anonymous record expressions - val (|NewAnonRecord|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option + val (|NewAnonRecord|_|): FSharpExpr -> (FSharpType * FSharpExpr list) option /// Matches expressions getting a field from an anonymous record. The integer represents the /// index into the sorted fields of the anonymous record. - val (|AnonRecordGet|_|) : FSharpExpr -> (FSharpExpr * FSharpType * int) option + val (|AnonRecordGet|_|): FSharpExpr -> (FSharpExpr * FSharpType * int) option /// Matches expressions which get a field from a record or class - val (|FSharpFieldGet|_|) : FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField) option + val (|FSharpFieldGet|_|): FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField) option /// Matches expressions which set a field in a record or class - val (|FSharpFieldSet|_|) : FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField * FSharpExpr) option + val (|FSharpFieldSet|_|): FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField * FSharpExpr) option /// Matches expressions which create an object corresponding to a union case - val (|NewUnionCase|_|) : FSharpExpr -> (FSharpType * FSharpUnionCase * FSharpExpr list) option + val (|NewUnionCase|_|): FSharpExpr -> (FSharpType * FSharpUnionCase * FSharpExpr list) option /// Matches expressions which get a field from a union case - val (|UnionCaseGet|_|) : FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField) option + val (|UnionCaseGet|_|): FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField) option /// Matches expressions which set a field from a union case (only used in FSharp.Core itself) - val (|UnionCaseSet|_|) : FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField * FSharpExpr) option + val (|UnionCaseSet|_|): FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField * FSharpExpr) option /// Matches expressions which gets the tag for a union case - val (|UnionCaseTag|_|) : FSharpExpr -> (FSharpExpr * FSharpType) option + val (|UnionCaseTag|_|): FSharpExpr -> (FSharpExpr * FSharpType) option /// Matches expressions which test if an expression corresponds to a particular union case - val (|UnionCaseTest|_|) : FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase) option + val (|UnionCaseTest|_|): FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase) option /// Matches tuple expressions - val (|NewTuple|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option + val (|NewTuple|_|): FSharpExpr -> (FSharpType * FSharpExpr list) option /// Matches expressions which get a value from a tuple - val (|TupleGet|_|) : FSharpExpr -> (FSharpType * int * FSharpExpr) option + val (|TupleGet|_|): FSharpExpr -> (FSharpType * int * FSharpExpr) option /// Matches expressions which coerce the type of a value - val (|Coerce|_|) : FSharpExpr -> (FSharpType * FSharpExpr) option + val (|Coerce|_|): FSharpExpr -> (FSharpType * FSharpExpr) option /// Matches array expressions - val (|NewArray|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option + val (|NewArray|_|): FSharpExpr -> (FSharpType * FSharpExpr list) option /// Matches expressions which test the runtime type of a value - val (|TypeTest|_|) : FSharpExpr -> (FSharpType * FSharpExpr) option + val (|TypeTest|_|): FSharpExpr -> (FSharpType * FSharpExpr) option /// Matches expressions which set the contents of an address - val (|AddressSet|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr) option + val (|AddressSet|_|): FSharpExpr -> (FSharpExpr * FSharpExpr) option /// Matches expressions which set the contents of a mutable variable - val (|ValueSet|_|) : FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option + val (|ValueSet|_|): FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option /// Matches default-value expressions, including null expressions - val (|DefaultValue|_|) : FSharpExpr -> FSharpType option + val (|DefaultValue|_|): FSharpExpr -> FSharpType option /// Matches constant expressions, including signed and unsigned integers, strings, characters, booleans, arrays /// of bytes and arrays of unit16. - val (|Const|_|) : FSharpExpr -> (obj * FSharpType) option + val (|Const|_|): FSharpExpr -> (obj * FSharpType) option /// Matches expressions which take the address of a location - val (|AddressOf|_|) : FSharpExpr -> FSharpExpr option + val (|AddressOf|_|): FSharpExpr -> FSharpExpr option /// Matches sequential expressions - val (|Sequential|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr) option + val (|Sequential|_|): FSharpExpr -> (FSharpExpr * FSharpExpr) option /// Matches fast-integer loops (up or down) - val (|FastIntegerForLoop|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr * bool) option + val (|FastIntegerForLoop|_|): FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr * bool) option /// Matches while loops - val (|WhileLoop|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr) option + val (|WhileLoop|_|): FSharpExpr -> (FSharpExpr * FSharpExpr) option /// Matches try/finally expressions - val (|TryFinally|_|) : FSharpExpr -> (FSharpExpr * FSharpExpr) option + val (|TryFinally|_|): FSharpExpr -> (FSharpExpr * FSharpExpr) option /// Matches try/with expressions - val (|TryWith|_|) : FSharpExpr -> (FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr) option + val (|TryWith|_|): FSharpExpr -> (FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr) option /// Matches expressions which create an instance of a delegate type - val (|NewDelegate|_|) : FSharpExpr -> (FSharpType * FSharpExpr) option + val (|NewDelegate|_|): FSharpExpr -> (FSharpType * FSharpExpr) option /// Matches expressions which are IL assembly code - val (|ILAsm|_|) : FSharpExpr -> (string * FSharpType list * FSharpExpr list) option + val (|ILAsm|_|): FSharpExpr -> (string * FSharpType list * FSharpExpr list) option /// Matches expressions which fetch a field from a .NET type - val (|ILFieldGet|_|) : FSharpExpr -> (FSharpExpr option * FSharpType * string) option + val (|ILFieldGet|_|): FSharpExpr -> (FSharpExpr option * FSharpType * string) option /// Matches expressions which set a field in a .NET type - val (|ILFieldSet|_|) : FSharpExpr -> (FSharpExpr option * FSharpType * string * FSharpExpr) option + val (|ILFieldSet|_|): FSharpExpr -> (FSharpExpr option * FSharpType * string * FSharpExpr) option /// Matches object expressions, returning the base type, the base call, the overrides and the interface implementations - val (|ObjectExpr|_|) : FSharpExpr -> (FSharpType * FSharpExpr * FSharpObjectExprOverride list * (FSharpType * FSharpObjectExprOverride list) list) option + val (|ObjectExpr|_|): FSharpExpr -> (FSharpType * FSharpExpr * FSharpObjectExprOverride list * (FSharpType * FSharpObjectExprOverride list) list) option /// Matches expressions for an unresolved call to a trait - val (|TraitCall|_|) : FSharpExpr -> (FSharpType list * string * Ast.MemberFlags * FSharpType list * FSharpType list * FSharpExpr list) option + val (|TraitCall|_|): FSharpExpr -> (FSharpType list * string * SynMemberFlags * FSharpType list * FSharpType list * FSharpExpr list) option + /// Indicates a witness argument index from the witness arguments supplied to the enclosing method + val (|WitnessArg|_|): FSharpExpr -> int option diff --git a/src/fsharp/symbols/SymbolHelpers.fs b/src/fsharp/symbols/SymbolHelpers.fs index cec9bfaf52f..9a269a67a40 100644 --- a/src/fsharp/symbols/SymbolHelpers.fs +++ b/src/fsharp/symbols/SymbolHelpers.fs @@ -5,99 +5,120 @@ // type checking and intellisense-like environment-reporting. //-------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Diagnostics open System -open System.IO -open Microsoft.FSharp.Core.Printf -open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Diagnostics +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras -open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast +open FSharp.Core.Printf +open FSharp.Compiler +open FSharp.Compiler.CompilerDiagnostics +open FSharp.Compiler.Diagnostics open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Range -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Infos -open FSharp.Compiler.NameResolution -open FSharp.Compiler.InfoReader -open FSharp.Compiler.CompileOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range -module EnvMisc2 = - let maxMembers = GetEnvInteger "FCS_MaxMembersInQuickInfo" 10 +type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: string, subcategory: string, errorNum: int, numberPrefix: string) = + member _.Range = m -//---------------------------------------------------------------------------- -// Object model for diagnostics + member _.Severity = severity + + member _.Message = message + + member _.Subcategory = subcategory + + member _.ErrorNumber = errorNum + + member _.ErrorNumberPrefix = numberPrefix + + member _.ErrorNumberText = numberPrefix + errorNum.ToString("0000") + + member _.Start = m.Start + + member _.End = m.End + + member _.StartLine = m.Start.Line + + member _.EndLine = m.End.Line + + member _.StartColumn = m.Start.Column + + member _.EndColumn = m.End.Column + + member _.FileName = m.FileName + + member _.WithStart newStart = + let m = mkFileIndexRange m.FileIndex newStart m.End + FSharpDiagnostic(m, severity, message, subcategory, errorNum, numberPrefix) + + member _.WithEnd newEnd = + let m = mkFileIndexRange m.FileIndex m.Start newEnd + FSharpDiagnostic(m, severity, message, subcategory, errorNum, numberPrefix) + + override _.ToString() = + let fileName = m.FileName + let s = m.Start + let e = m.End + let severity = + match severity with + | FSharpDiagnosticSeverity.Warning -> "warning" + | FSharpDiagnosticSeverity.Error -> "error" + | FSharpDiagnosticSeverity.Info -> "info" + | FSharpDiagnosticSeverity.Hidden -> "hidden" + sprintf "%s (%d,%d)-(%d,%d) %s %s %s" fileName s.Line (s.Column + 1) e.Line (e.Column + 1) subcategory severity message -[] -type FSharpErrorSeverity = - | Warning - | Error - -type FSharpErrorInfo(fileName, s: pos, e: pos, severity: FSharpErrorSeverity, message: string, subcategory: string, errorNum: int) = - member __.StartLine = Line.toZ s.Line - member __.StartLineAlternate = s.Line - member __.EndLine = Line.toZ e.Line - member __.EndLineAlternate = e.Line - member __.StartColumn = s.Column - member __.EndColumn = e.Column - member __.Severity = severity - member __.Message = message - member __.Subcategory = subcategory - member __.FileName = fileName - member __.ErrorNumber = errorNum - member __.WithStart newStart = FSharpErrorInfo(fileName, newStart, e, severity, message, subcategory, errorNum) - member __.WithEnd newEnd = FSharpErrorInfo(fileName, s, newEnd, severity, message, subcategory, errorNum) - override __.ToString()= sprintf "%s (%d,%d)-(%d,%d) %s %s %s" fileName (int s.Line) (s.Column + 1) (int e.Line) (e.Column + 1) subcategory (if severity=FSharpErrorSeverity.Warning then "warning" else "error") message - /// Decompose a warning or error into parts: position, severity, message, error number - static member CreateFromException(exn, isError, fallbackRange: range, suggestNames: bool) = + static member CreateFromException(exn, severity, fallbackRange: range, suggestNames: bool) = let m = match GetRangeOfDiagnostic exn with Some m -> m | None -> fallbackRange let msg = bufs (fun buf -> OutputPhasedDiagnostic buf exn false suggestNames) let errorNum = GetDiagnosticNumber exn - FSharpErrorInfo(m.FileName, m.Start, m.End, (if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning), msg, exn.Subcategory(), errorNum) - + FSharpDiagnostic(m, severity, msg, exn.Subcategory(), errorNum, "FS") + /// Decompose a warning or error into parts: position, severity, message, error number - static member CreateFromExceptionAndAdjustEof(exn, isError, fallbackRange: range, (linesCount: int, lastLength: int), suggestNames: bool) = - let r = FSharpErrorInfo.CreateFromException(exn, isError, fallbackRange, suggestNames) + static member CreateFromExceptionAndAdjustEof(exn, severity, fallbackRange: range, (linesCount: int, lastLength: int), suggestNames: bool) = + let r = FSharpDiagnostic.CreateFromException(exn, severity, fallbackRange, suggestNames) // Adjust to make sure that errors reported at Eof are shown at the linesCount - let startline, schange = min (r.StartLineAlternate, false) (linesCount, true) - let endline, echange = min (r.EndLineAlternate, false) (linesCount, true) + let startline, schange = min (Line.toZ r.Range.StartLine, false) (linesCount, true) + let endline, echange = min (Line.toZ r.Range.EndLine, false) (linesCount, true) if not (schange || echange) then r else let r = if schange then r.WithStart(mkPos startline lastLength) else r - if echange then r.WithEnd(mkPos endline (1 + lastLength)) else r + if echange then r.WithEnd(mkPos endline (1 + lastLength)) else r + static member NewlineifyErrorString(message) = NewlineifyErrorString(message) + + static member NormalizeErrorString(text) = NormalizeErrorString(text) + static member Create(severity: FSharpDiagnosticSeverity, message: string, number: int, range: range, ?numberPrefix: string, ?subcategory: string) = + let subcategory = defaultArg subcategory BuildPhaseSubcategory.TypeCheck + let numberPrefix = defaultArg numberPrefix "FS" + FSharpDiagnostic(range, severity, message, subcategory, number, numberPrefix) + /// Use to reset error and warning handlers [] type ErrorScope() = - let mutable errors = [] + let mutable diags = [] let mutable firstError = None let unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.TypeCheck let unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _oldLogger -> { new ErrorLogger("ErrorScope") with - member x.DiagnosticSink(exn, isError) = - let err = FSharpErrorInfo.CreateFromException(exn, isError, range.Zero, false) - errors <- err :: errors - if isError && firstError.IsNone then + member x.DiagnosticSink(exn, severity) = + let err = FSharpDiagnostic.CreateFromException(exn, severity, range.Zero, false) + diags <- err :: diags + if severity = FSharpDiagnosticSeverity.Error && firstError.IsNone then firstError <- Some err.Message - member x.ErrorCount = errors.Length }) + member x.ErrorCount = diags.Length }) - member x.Errors = errors |> List.filter (fun error -> error.Severity = FSharpErrorSeverity.Error) - member x.Warnings = errors |> List.filter (fun error -> error.Severity = FSharpErrorSeverity.Warning) - member x.Diagnostics = errors + member x.Errors = diags |> List.filter (fun error -> error.Severity = FSharpDiagnosticSeverity.Error) + + member x.Diagnostics = diags + member x.TryGetFirstErrorText() = match x.Errors with | error :: _ -> Some error.Message @@ -141,46 +162,38 @@ type ErrorScope() = | None -> err "" /// An error logger that capture errors, filtering them according to warning levels etc. -type internal CompilationErrorLogger (debugName: string, options: FSharpErrorSeverityOptions) = +type internal CompilationErrorLogger (debugName: string, options: FSharpDiagnosticOptions) = inherit ErrorLogger("CompilationErrorLogger("+debugName+")") let mutable errorCount = 0 - let diagnostics = new ResizeArray<_>() + let diagnostics = ResizeArray<_>() - override x.DiagnosticSink(exn, isError) = - if isError || ReportWarningAsError options exn then - diagnostics.Add(exn, FSharpErrorSeverity.Error) + override x.DiagnosticSink(err, severity) = + if ReportDiagnosticAsError options (err, severity) then + diagnostics.Add(err, FSharpDiagnosticSeverity.Error) errorCount <- errorCount + 1 - else if ReportWarning options exn then - diagnostics.Add(exn, FSharpErrorSeverity.Warning) - + elif ReportDiagnosticAsWarning options (err, severity) then + diagnostics.Add(err, FSharpDiagnosticSeverity.Warning) + elif ReportDiagnosticAsInfo options (err, severity) then + diagnostics.Add(err, severity) override x.ErrorCount = errorCount - member x.GetErrors() = diagnostics.ToArray() + member x.GetDiagnostics() = diagnostics.ToArray() +module DiagnosticHelpers = -/// This represents the global state established as each task function runs as part of the build. -/// -/// Use to reset error and warning handlers. -type CompilationGlobalsScope(errorLogger: ErrorLogger, phase: BuildPhase) = - let unwindEL = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) - let unwindBP = PushThreadBuildPhaseUntilUnwind phase - // Return the disposable object that cleans up - interface IDisposable with - member d.Dispose() = - unwindBP.Dispose() - unwindEL.Dispose() - -module ErrorHelpers = - let ReportError (options, allErrors, mainInputFileName, fileInfo, (exn, sev), suggestNames) = - [ let isError = (sev = FSharpErrorSeverity.Error) || ReportWarningAsError options exn - if (isError || ReportWarning options exn) then + let ReportDiagnostic (options: FSharpDiagnosticOptions, allErrors, mainInputFileName, fileInfo, (exn, severity), suggestNames) = + [ let severity = + if ReportDiagnosticAsError options (exn, severity) then FSharpDiagnosticSeverity.Error + else severity + if (severity = FSharpDiagnosticSeverity.Error || ReportDiagnosticAsWarning options (exn, severity) || ReportDiagnosticAsInfo options (exn, severity)) then let oneError exn = [ // We use the first line of the file as a fallbackRange for reporting unexpected errors. // Not ideal, but it's hard to see what else to do. let fallbackRange = rangeN mainInputFileName 1 - let ei = FSharpErrorInfo.CreateFromExceptionAndAdjustEof (exn, isError, fallbackRange, fileInfo, suggestNames) - if allErrors || (ei.FileName = mainInputFileName) || (ei.FileName = TcGlobals.DummyFileNameForRangesWithoutASpecificLocation) then + let ei = FSharpDiagnostic.CreateFromExceptionAndAdjustEof (exn, severity, fallbackRange, fileInfo, suggestNames) + let fileName = ei.Range.FileName + if allErrors || fileName = mainInputFileName || fileName = TcGlobals.DummyFileNameForRangesWithoutASpecificLocation then yield ei ] let mainError, relatedErrors = SplitRelatedDiagnostics exn @@ -188,125 +201,50 @@ module ErrorHelpers = for e in relatedErrors do yield! oneError e ] - let CreateErrorInfos (options, allErrors, mainInputFileName, errors, suggestNames) = + let CreateDiagnostics (options, allErrors, mainInputFileName, errors, suggestNames) = let fileInfo = (Int32.MaxValue, Int32.MaxValue) - [| for (exn, isError) in errors do - yield! ReportError (options, allErrors, mainInputFileName, fileInfo, (exn, isError), suggestNames) |] + [| for exn, severity in errors do + yield! ReportDiagnostic (options, allErrors, mainInputFileName, fileInfo, (exn, severity), suggestNames) |] -//---------------------------------------------------------------------------- -// Object model for tooltips and helpers for their generation from items +namespace FSharp.Compiler.Symbols + +open System.IO -type public Layout = Internal.Utilities.StructuredFormat.Layout +open Internal.Utilities.Library +open Internal.Utilities.Library.Extras +open FSharp.Core.Printf +open FSharp.Compiler +open FSharp.Compiler.AbstractIL.Diagnostics +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Infos +open FSharp.Compiler.IO +open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text.Layout +open FSharp.Compiler.Text.TaggedText +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals /// Describe a comment as either a block of text or a file+signature reference into an intellidoc file. [] type FSharpXmlDoc = | None - | Text of string - | XmlDocFileSignature of (*File and Signature*) string * string - -/// A single data tip display element -[] -type FSharpToolTipElementData<'T> = - { MainDescription: 'T - XmlDoc: FSharpXmlDoc - /// typar instantiation text, to go after xml - TypeMapping: 'T list - Remarks: 'T option - ParamName : string option } - static member Create(layout:'T, xml, ?typeMapping, ?paramName, ?remarks) = - { MainDescription=layout; XmlDoc=xml; TypeMapping=defaultArg typeMapping []; ParamName=paramName; Remarks=remarks } - -/// A single data tip display element -[] -type FSharpToolTipElement<'T> = - | None - - /// A single type, method, etc with comment. May represent a method overload group. - | Group of FSharpToolTipElementData<'T> list - - /// An error occurred formatting this element - | CompositionError of string - - static member Single(layout, xml, ?typeMapping, ?paramName, ?remarks) = - Group [ FSharpToolTipElementData<'T>.Create(layout, xml, ?typeMapping=typeMapping, ?paramName=paramName, ?remarks=remarks) ] - -/// A single data tip display element with where text is expressed as string -type public FSharpToolTipElement = FSharpToolTipElement + | FromXmlText of XmlDoc + | FromXmlFile of dllName: string * xmlSig: string - -/// A single data tip display element with where text is expressed as -type public FSharpStructuredToolTipElement = FSharpToolTipElement - -/// Information for building a data tip box. -type FSharpToolTipText<'T> = - /// A list of data tip elements to display. - | FSharpToolTipText of FSharpToolTipElement<'T> list - -type public FSharpToolTipText = FSharpToolTipText -type public FSharpStructuredToolTipText = FSharpToolTipText - -module Tooltips = - let ToFSharpToolTipElement tooltip = - match tooltip with - | FSharpStructuredToolTipElement.None -> - FSharpToolTipElement.None - | FSharpStructuredToolTipElement.Group l -> - FSharpToolTipElement.Group(l |> List.map(fun x -> - { MainDescription=showL x.MainDescription - XmlDoc=x.XmlDoc - TypeMapping=List.map showL x.TypeMapping - ParamName=x.ParamName - Remarks= Option.map showL x.Remarks })) - | FSharpStructuredToolTipElement.CompositionError text -> - FSharpToolTipElement.CompositionError text - - let ToFSharpToolTipText (FSharpStructuredToolTipText.FSharpToolTipText text) = - FSharpToolTipText(List.map ToFSharpToolTipElement text) - - let Map f a = async.Bind(a, f >> async.Return) - -[] -type CompletionItemKind = - | Field - | Property - | Method of isExtension : bool - | Event - | Argument - | CustomOperation - | Other - -type UnresolvedSymbol = - { FullName: string - DisplayName: string - Namespace: string[] } - -type CompletionItem = - { ItemWithInst: ItemWithInst - Kind: CompletionItemKind - IsOwnMember: bool - MinorPriority: int - Type: TyconRef option - Unresolved: UnresolvedSymbol option } - member x.Item = x.ItemWithInst.Item - +module EnvMisc2 = + let maxMembers = GetEnvInteger "FCS_MaxMembersInQuickInfo" 10 [] module internal SymbolHelpers = - let isFunction g ty = - let _, tau = tryDestForallTy g ty - isFunTy g tau - - let OutputFullName isListItem ppF fnF r = - // Only display full names in quick info, not declaration lists or method lists - if not isListItem then - match ppF r with - | None -> emptyL - | Some _ -> wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r) - else emptyL - let rangeOfValRef preferFlag (vref: ValRef) = match preferFlag with | None -> vref.Range @@ -318,19 +256,18 @@ module internal SymbolHelpers = | None -> eref.Range | Some false -> eref.DefinitionRange | Some true -> eref.SigRange - let rangeOfPropInfo preferFlag (pinfo: PropInfo) = match pinfo with #if !NO_EXTENSIONTYPING - | ProvidedProp(_, pi, _) -> ComputeDefinitionLocationOfProvidedItem pi + | ProvidedProp(_, pi, _) -> Construct.ComputeDefinitionLocationOfProvidedItem pi #endif | _ -> pinfo.ArbitraryValRef |> Option.map (rangeOfValRef preferFlag) let rangeOfMethInfo (g: TcGlobals) preferFlag (minfo: MethInfo) = match minfo with #if !NO_EXTENSIONTYPING - | ProvidedMeth(_, mi, _, _) -> ComputeDefinitionLocationOfProvidedItem mi + | ProvidedMeth(_, mi, _, _) -> Construct.ComputeDefinitionLocationOfProvidedItem mi #endif | DefaultStructCtor(_, AppTy g (tcref, _)) -> Some(rangeOfEntityRef preferFlag tcref) | _ -> minfo.ArbitraryValRef |> Option.map (rangeOfValRef preferFlag) @@ -338,7 +275,7 @@ module internal SymbolHelpers = let rangeOfEventInfo preferFlag (einfo: EventInfo) = match einfo with #if !NO_EXTENSIONTYPING - | ProvidedEvent (_, ei, _) -> ComputeDefinitionLocationOfProvidedItem ei + | ProvidedEvent (_, ei, _) -> Construct.ComputeDefinitionLocationOfProvidedItem ei #endif | _ -> einfo.ArbitraryValRef |> Option.map (rangeOfValRef preferFlag) @@ -348,11 +285,14 @@ module internal SymbolHelpers = | Some false -> ucinfo.UnionCase.DefinitionRange | Some true -> ucinfo.UnionCase.SigRange - let rangeOfRecdFieldInfo preferFlag (rfinfo: RecdFieldInfo) = - match preferFlag with - | None -> rfinfo.RecdField.Range - | Some false -> rfinfo.RecdField.DefinitionRange - | Some true -> rfinfo.RecdField.SigRange + let rangeOfRecdField preferFlag (rField: RecdField) = + match preferFlag with + | None -> rField.Range + | Some false -> rField.DefinitionRange + | Some true -> rField.SigRange + + let rangeOfRecdFieldInfo preferFlag (rfinfo: RecdFieldInfo) = + rangeOfRecdField preferFlag rfinfo.RecdField let rec rangeOfItem (g: TcGlobals) preferFlag d = match d with @@ -362,6 +302,7 @@ module internal SymbolHelpers = | Item.ExnCase tcref -> Some tcref.Range | Item.AnonRecdField (_,_,_,m) -> Some m | Item.RecdField rfinfo -> Some (rangeOfRecdFieldInfo preferFlag rfinfo) + | Item.UnionCaseField (UnionCaseInfo (_, ucref), fieldIndex) -> Some (rangeOfRecdField preferFlag (ucref.FieldByIndex(fieldIndex))) | Item.Event einfo -> rangeOfEventInfo preferFlag einfo | Item.ILField _ -> None | Item.Property(_, pinfos) -> rangeOfPropInfo preferFlag pinfos.Head @@ -397,7 +338,6 @@ module internal SymbolHelpers = |> Option.bind ccuOfValRef |> Option.orElseWith (fun () -> minfo.DeclaringTyconRef |> computeCcuOfTyconRef) - let rec ccuOfItem (g: TcGlobals) d = match d with | Item.Value vref | Item.CustomBuilder (_, vref) -> ccuOfValRef vref @@ -405,6 +345,7 @@ module internal SymbolHelpers = | Item.ActivePatternCase apref -> ccuOfValRef apref.ActivePatternVal | Item.ExnCase tcref -> computeCcuOfTyconRef tcref | Item.RecdField rfinfo -> computeCcuOfTyconRef rfinfo.RecdFieldRef.TyconRef + | Item.UnionCaseField (ucinfo, _) -> computeCcuOfTyconRef ucinfo.TyconRef | Item.Event einfo -> einfo.DeclaringTyconRef |> computeCcuOfTyconRef | Item.ILField finfo -> finfo.DeclaringTyconRef |> computeCcuOfTyconRef | Item.Property(_, pinfos) -> @@ -459,165 +400,45 @@ module internal SymbolHelpers = let argInfos = ArgInfosOfMember g vref |> List.concat // Drop the first 'seq' argument representing the computation space let argInfos = if argInfos.IsEmpty then [] else argInfos.Tail - [ for (ty, argInfo) in argInfos do + [ for ty, argInfo in argInfos do let isPP = HasFSharpAttribute g g.attrib_ProjectionParameterAttribute argInfo.Attribs // Strip the tuple space type of the type of projection parameters let ty = if isPP && isFunTy g ty then rangeOfFunTy g ty else ty yield ParamNameAndType(argInfo.Name, ty) ] | _ -> [] - // Find the name of the metadata file for this external definition - let metaInfoOfEntityRef (infoReader: InfoReader) m tcref = - let g = infoReader.g - match tcref with - | ERefLocal _ -> None - | ERefNonLocal nlref -> - // Generalize to get a formal signature - let formalTypars = tcref.Typars m - let formalTypeInst = generalizeTypars formalTypars - let ty = TType_app(tcref, formalTypeInst) - if isILAppTy g ty then - let formalTypeInfo = ILTypeInfo.FromType g ty - Some(nlref.Ccu.FileName, formalTypars, formalTypeInfo) - else None - let mkXmlComment thing = match thing with - | Some (Some fileName, xmlDocSig) -> FSharpXmlDoc.XmlDocFileSignature(fileName, xmlDocSig) + | Some (Some fileName, xmlDocSig) -> FSharpXmlDoc.FromXmlFile(fileName, xmlDocSig) | _ -> FSharpXmlDoc.None - let GetXmlDocSigOfEntityRef infoReader m (eref: EntityRef) = - if eref.IsILTycon then - match metaInfoOfEntityRef infoReader m eref with - | None -> None - | Some (ccuFileName, _, formalTypeInfo) -> Some(ccuFileName, "T:"+formalTypeInfo.ILTypeRef.FullName) - else - let ccuFileName = libFileOfEntityRef eref - let m = eref.Deref - if m.XmlDocSig = "" then - m.XmlDocSig <- XmlDocSigOfEntity eref - Some (ccuFileName, m.XmlDocSig) - - let GetXmlDocSigOfScopedValRef g (tcref: TyconRef) (vref: ValRef) = - let ccuFileName = libFileOfEntityRef tcref - let v = vref.Deref - if v.XmlDocSig = "" && v.HasDeclaringEntity then - let ap = buildAccessPath vref.TopValDeclaringEntity.CompilationPathOpt - let path = - if vref.TopValDeclaringEntity.IsModule then - let sep = if ap.Length > 0 then "." else "" - ap + sep + vref.TopValDeclaringEntity.CompiledName - else - ap - v.XmlDocSig <- XmlDocSigOfVal g path v - Some (ccuFileName, v.XmlDocSig) - - let GetXmlDocSigOfRecdFieldInfo (rfinfo: RecdFieldInfo) = - let tcref = rfinfo.TyconRef - let ccuFileName = libFileOfEntityRef tcref - if rfinfo.RecdField.XmlDocSig = "" then - rfinfo.RecdField.XmlDocSig <- XmlDocSigOfProperty [tcref.CompiledRepresentationForNamedType.FullName; rfinfo.Name] - Some (ccuFileName, rfinfo.RecdField.XmlDocSig) - - let GetXmlDocSigOfUnionCaseInfo (ucinfo: UnionCaseInfo) = - let tcref = ucinfo.TyconRef - let ccuFileName = libFileOfEntityRef tcref - if ucinfo.UnionCase.XmlDocSig = "" then - ucinfo.UnionCase.XmlDocSig <- XmlDocSigOfUnionCase [tcref.CompiledRepresentationForNamedType.FullName; ucinfo.Name] - Some (ccuFileName, ucinfo.UnionCase.XmlDocSig) - - let GetXmlDocSigOfMethInfo (infoReader: InfoReader) m (minfo: MethInfo) = - let amap = infoReader.amap - match minfo with - | FSMeth (g, _, vref, _) -> - GetXmlDocSigOfScopedValRef g minfo.DeclaringTyconRef vref - | ILMeth (g, ilminfo, _) -> - let actualTypeName = ilminfo.DeclaringTyconRef.CompiledRepresentationForNamedType.FullName - let fmtps = ilminfo.FormalMethodTypars - let genArity = if fmtps.Length=0 then "" else sprintf "``%d" fmtps.Length - - match metaInfoOfEntityRef infoReader m ilminfo.DeclaringTyconRef with - | None -> None - | Some (ccuFileName, formalTypars, formalTypeInfo) -> - let filminfo = ILMethInfo(g, formalTypeInfo.ToType, None, ilminfo.RawMetadata, fmtps) - let args = - match ilminfo.IsILExtensionMethod with - | true -> filminfo.GetRawArgTypes(amap, m, minfo.FormalMethodInst) - | false -> filminfo.GetParamTypes(amap, m, minfo.FormalMethodInst) - - // http://msdn.microsoft.com/en-us/library/fsbx0t7x.aspx - // If the name of the item itself has periods, they are replaced by the hash-sign ('#'). - // It is assumed that no item has a hash-sign directly in its name. For example, the fully - // qualified name of the String constructor would be "System.String.#ctor". - let normalizedName = ilminfo.ILName.Replace(".", "#") - - Some (ccuFileName, "M:"+actualTypeName+"."+normalizedName+genArity+XmlDocArgsEnc g (formalTypars, fmtps) args) - | DefaultStructCtor _ -> None -#if !NO_EXTENSIONTYPING - | ProvidedMeth _ -> None -#endif - - let GetXmlDocSigOfValRef g (vref: ValRef) = - if not vref.IsLocalRef then - let ccuFileName = vref.nlr.Ccu.FileName - let v = vref.Deref - if v.XmlDocSig = "" && v.HasDeclaringEntity then - v.XmlDocSig <- XmlDocSigOfVal g vref.TopValDeclaringEntity.CompiledRepresentationForNamedType.Name v - Some (ccuFileName, v.XmlDocSig) - else - None - - let GetXmlDocSigOfProp infoReader m (pinfo: PropInfo) = - let g = pinfo.TcGlobals - match pinfo with -#if !NO_EXTENSIONTYPING - | ProvidedProp _ -> None // No signature is possible. If an xml comment existed it would have been returned by PropInfo.XmlDoc in infos.fs -#endif - | FSProp _ as fspinfo -> - match fspinfo.ArbitraryValRef with - | None -> None - | Some vref -> GetXmlDocSigOfScopedValRef g pinfo.DeclaringTyconRef vref - | ILProp(ILPropInfo(_, pdef)) -> - match metaInfoOfEntityRef infoReader m pinfo.DeclaringTyconRef with - | Some (ccuFileName, formalTypars, formalTypeInfo) -> - let filpinfo = ILPropInfo(formalTypeInfo, pdef) - Some (ccuFileName, "P:"+formalTypeInfo.ILTypeRef.FullName+"."+pdef.Name+XmlDocArgsEnc g (formalTypars, []) (filpinfo.GetParamTypes(infoReader.amap, m))) - | _ -> None - - let GetXmlDocSigOfEvent infoReader m (einfo: EventInfo) = - match einfo with - | ILEvent _ -> - match metaInfoOfEntityRef infoReader m einfo.DeclaringTyconRef with - | Some (ccuFileName, _, formalTypeInfo) -> - Some(ccuFileName, "E:"+formalTypeInfo.ILTypeRef.FullName+"."+einfo.EventName) - | _ -> None - | _ -> None - - let GetXmlDocSigOfILFieldInfo infoReader m (finfo: ILFieldInfo) = - match metaInfoOfEntityRef infoReader m finfo.DeclaringTyconRef with - | Some (ccuFileName, _, formalTypeInfo) -> - Some(ccuFileName, "F:"+formalTypeInfo.ILTypeRef.FullName+"."+finfo.FieldName) - | _ -> None + let GetXmlDocFromLoader (infoReader: InfoReader) xmlDoc = + match xmlDoc with + | FSharpXmlDoc.None + | FSharpXmlDoc.FromXmlText _ -> xmlDoc + | FSharpXmlDoc.FromXmlFile(dllName, xmlSig) -> + TryFindXmlDocByAssemblyNameAndSig infoReader (Path.GetFileNameWithoutExtension dllName) xmlSig + |> Option.map FSharpXmlDoc.FromXmlText + |> Option.defaultValue xmlDoc /// This function gets the signature to pass to Visual Studio to use its lookup functions for .NET stuff. let GetXmlDocHelpSigOfItemForLookup (infoReader: InfoReader) m d = let g = infoReader.g - match d with - | Item.ActivePatternCase (APElemRef(_, vref, _)) + | Item.ActivePatternCase (APElemRef(_, vref, _, _)) | Item.Value vref | Item.CustomBuilder (_, vref) -> mkXmlComment (GetXmlDocSigOfValRef g vref) - | Item.UnionCase (ucinfo, _) -> mkXmlComment (GetXmlDocSigOfUnionCaseInfo ucinfo) + | Item.UnionCase (ucinfo, _) -> mkXmlComment (GetXmlDocSigOfUnionCaseRef ucinfo.UnionCaseRef) | Item.ExnCase tcref -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref) - | Item.RecdField rfinfo -> mkXmlComment (GetXmlDocSigOfRecdFieldInfo rfinfo) + | Item.RecdField rfinfo -> mkXmlComment (GetXmlDocSigOfRecdFieldRef rfinfo.RecdFieldRef) | Item.NewDef _ -> FSharpXmlDoc.None | Item.ILField finfo -> mkXmlComment (GetXmlDocSigOfILFieldInfo infoReader m finfo) - | Item.Types(_, ((TType_app(tcref, _)) :: _)) -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref) + | Item.Types(_, TType_app(tcref, _) :: _) -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref) | Item.CustomOperation (_, _, Some minfo) -> mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo) | Item.TypeVar _ -> FSharpXmlDoc.None | Item.ModuleOrNamespaces(modref :: _) -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m modref) - | Item.Property(_, (pinfo :: _)) -> mkXmlComment (GetXmlDocSigOfProp infoReader m pinfo) + | Item.Property(_, pinfo :: _) -> mkXmlComment (GetXmlDocSigOfProp infoReader m pinfo) | Item.Event einfo -> mkXmlComment (GetXmlDocSigOfEvent infoReader m einfo) | Item.MethodGroup(_, minfo :: _, _) -> mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo) @@ -626,28 +447,18 @@ module internal SymbolHelpers = match argContainer with | ArgumentContainer.Method minfo -> mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo) | ArgumentContainer.Type tcref -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref) - | ArgumentContainer.UnionCase ucinfo -> mkXmlComment (GetXmlDocSigOfUnionCaseInfo ucinfo) + | Item.UnionCaseField (ucinfo, _) -> mkXmlComment (GetXmlDocSigOfUnionCaseRef ucinfo.UnionCaseRef) | _ -> FSharpXmlDoc.None + |> GetXmlDocFromLoader infoReader + /// Produce an XmlComment with a signature or raw text, given the F# comment and the item let GetXmlCommentForItemAux (xmlDoc: XmlDoc option) (infoReader: InfoReader) m d = - let result = - match xmlDoc with - | None | Some (XmlDoc [| |]) -> "" - | Some (XmlDoc l) -> - bufs (fun os -> - bprintf os "\n" - l |> Array.iter (fun (s: string) -> - // Note: this code runs for local/within-project xmldoc tooltips, but not for cross-project or .XML - bprintf os "\n%s" s)) - - if String.IsNullOrEmpty result then - GetXmlDocHelpSigOfItemForLookup infoReader m d - else - FSharpXmlDoc.Text result + match xmlDoc with + | Some xmlDoc when not xmlDoc.IsEmpty -> + FSharpXmlDoc.FromXmlText xmlDoc + | _ -> GetXmlDocHelpSigOfItemForLookup infoReader m d - let mutable ToolTipFault = None - let GetXmlCommentForMethInfoItem infoReader m d (minfo: MethInfo) = if minfo.HasDirectXmlComment || minfo.XmlDoc.NonEmpty then GetXmlCommentForItemAux (Some minfo.XmlDoc) infoReader m d @@ -655,30 +466,9 @@ module internal SymbolHelpers = mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo) let FormatTyparMapping denv (prettyTyparInst: TyparInst) = - [ for (tp, ty) in prettyTyparInst -> + [ for tp, ty in prettyTyparInst -> wordL (tagTypeParameter ("'" + tp.DisplayName)) ^^ wordL (tagText (FSComp.SR.descriptionWordIs())) ^^ NicePrint.layoutType denv ty ] - /// Generate the structured tooltip for a method info - let FormatOverloadsToList (infoReader: InfoReader) m denv (item: ItemWithInst) minfos : FSharpStructuredToolTipElement = - ToolTipFault |> Option.iter (fun msg -> - let exn = Error((0, msg), range.Zero) - let ph = PhasedDiagnostic.Create(exn, BuildPhase.TypeCheck) - simulateError ph) - - let layouts = - [ for minfo in minfos -> - let prettyTyparInst, layout = NicePrint.prettyLayoutOfMethInfoFreeStyle infoReader.amap m denv item.TyparInst minfo - let xml = GetXmlCommentForMethInfoItem infoReader m item.Item minfo - let tpsL = FormatTyparMapping denv prettyTyparInst - FSharpToolTipElementData<_>.Create(layout, xml, tpsL) ] - - FSharpStructuredToolTipElement.Group layouts - - - let pubpathOfValRef (v: ValRef) = v.PublicPath - let pubpathOfTyconRef (x: TyconRef) = x.PublicPath - - let (|ItemWhereTypIsPreferred|_|) item = match item with | Item.DelegateCtor ty @@ -719,9 +509,9 @@ module internal SymbolHelpers = // In this case just bail out and assume items are not equal protectAssemblyExploration false (fun () -> let equalHeadTypes(ty1, ty2) = - match tryDestAppTy g ty1 with + match tryTcrefOfAppTy g ty1 with | ValueSome tcref1 -> - match tryDestAppTy g ty2 with + match tryTcrefOfAppTy g ty2 with | ValueSome tcref2 -> tyconRefEq g tcref1 tcref2 | _ -> typeEquiv g ty1 ty2 | _ -> typeEquiv g ty1 ty2 @@ -752,24 +542,24 @@ module internal SymbolHelpers = MethInfo.MethInfosUseIdenticalDefinitions minfo1 minfo2) | (Item.Value vref1 | Item.CustomBuilder (_, vref1)), (Item.Value vref2 | Item.CustomBuilder (_, vref2)) -> valRefEq g vref1 vref2 - | Item.ActivePatternCase(APElemRef(_apinfo1, vref1, idx1)), Item.ActivePatternCase(APElemRef(_apinfo2, vref2, idx2)) -> + | Item.ActivePatternCase(APElemRef(_apinfo1, vref1, idx1, _)), Item.ActivePatternCase(APElemRef(_apinfo2, vref2, idx2, _)) -> idx1 = idx2 && valRefEq g vref1 vref2 | Item.UnionCase(UnionCaseInfo(_, ur1), _), Item.UnionCase(UnionCaseInfo(_, ur2), _) -> g.unionCaseRefEq ur1 ur2 - | Item.RecdField(RecdFieldInfo(_, RFRef(tcref1, n1))), Item.RecdField(RecdFieldInfo(_, RFRef(tcref2, n2))) -> + | Item.RecdField(RecdFieldInfo(_, RecdFieldRef(tcref1, n1))), Item.RecdField(RecdFieldInfo(_, RecdFieldRef(tcref2, n2))) -> (tyconRefEq g tcref1 tcref2) && (n1 = n2) // there is no direct function as in the previous case | Item.Property(_, pi1s), Item.Property(_, pi2s) -> - List.zip pi1s pi2s |> List.forall(fun (pi1, pi2) -> PropInfo.PropInfosUseIdenticalDefinitions pi1 pi2) + (pi1s, pi2s) ||> List.forall2 (fun pi1 pi2 -> PropInfo.PropInfosUseIdenticalDefinitions pi1 pi2) | Item.Event evt1, Item.Event evt2 -> EventInfo.EventInfosUseIdenticalDefinitions evt1 evt2 | Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> - Tastops.anonInfoEquiv anon1 anon2 && i1 = i2 + anonInfoEquiv anon1 anon2 && i1 = i2 | Item.CtorGroup(_, meths1), Item.CtorGroup(_, meths2) -> - List.zip meths1 meths2 - |> List.forall (fun (minfo1, minfo2) -> MethInfo.MethInfosUseIdenticalDefinitions minfo1 minfo2) + (meths1, meths2) + ||> List.forall2 (fun minfo1 minfo2 -> MethInfo.MethInfosUseIdenticalDefinitions minfo1 minfo2) | Item.UnqualifiedType tcRefs1, Item.UnqualifiedType tcRefs2 -> - List.zip tcRefs1 tcRefs2 - |> List.forall (fun (tcRef1, tcRef2) -> tyconRefEq g tcRef1 tcRef2) + (tcRefs1, tcRefs2) + ||> List.forall2 (fun tcRef1 tcRef2 -> tyconRefEq g tcRef1 tcRef2) | Item.Types(_, [TType.TType_app(tcRef1, _)]), Item.UnqualifiedType([tcRef2]) -> tyconRefEq g tcRef1 tcRef2 | Item.UnqualifiedType([tcRef1]), Item.Types(_, [TType.TType_app(tcRef2, _)]) -> tyconRefEq g tcRef1 tcRef2 | _ -> false) @@ -780,7 +570,7 @@ module internal SymbolHelpers = protectAssemblyExploration 1027 (fun () -> match item with | ItemWhereTypIsPreferred ty -> - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref -> hash tcref.LogicalName | _ -> 1010 | Item.ILField(ILFieldInfo(_, fld)) -> @@ -792,25 +582,17 @@ module internal SymbolHelpers = | Item.SetterArg(id, _) -> hash (id.idRange, id.idText) | Item.MethodGroup(_, meths, _) -> meths |> List.fold (fun st a -> st + a.ComputeHashCode()) 0 | Item.CtorGroup(name, meths) -> name.GetHashCode() + (meths |> List.fold (fun st a -> st + a.ComputeHashCode()) 0) - | (Item.Value vref | Item.CustomBuilder (_, vref)) -> hash vref.LogicalName - | Item.ActivePatternCase(APElemRef(_apinfo, vref, idx)) -> hash (vref.LogicalName, idx) + | Item.Value vref | Item.CustomBuilder (_, vref) -> hash vref.LogicalName + | Item.ActivePatternCase(APElemRef(_apinfo, vref, idx, _)) -> hash (vref.LogicalName, idx) | Item.ExnCase tcref -> hash tcref.LogicalName - | Item.UnionCase(UnionCaseInfo(_, UCRef(tcref, n)), _) -> hash(tcref.Stamp, n) - | Item.RecdField(RecdFieldInfo(_, RFRef(tcref, n))) -> hash(tcref.Stamp, n) + | Item.UnionCase(UnionCaseInfo(_, UnionCaseRef(tcref, n)), _) -> hash(tcref.Stamp, n) + | Item.RecdField(RecdFieldInfo(_, RecdFieldRef(tcref, n))) -> hash(tcref.Stamp, n) | Item.AnonRecdField(anon, _, i, _) -> hash anon.SortedNames.[i] | Item.Event evt -> evt.ComputeHashCode() | Item.Property(_name, pis) -> hash (pis |> List.map (fun pi -> pi.ComputeHashCode())) | Item.UnqualifiedType(tcref :: _) -> hash tcref.LogicalName | _ -> failwith "unreachable") } - let CompletionItemDisplayPartialEquality g = - let itemComparer = ItemDisplayPartialEquality g - - { new IPartialEqualityComparer with - member x.InEqualityRelation item = itemComparer.InEqualityRelation item.Item - member x.Equals(item1, item2) = itemComparer.Equals(item1.Item, item2.Item) - member x.GetHashCode item = itemComparer.GetHashCode(item.Item) } - let ItemWithTypeDisplayPartialEquality g = let itemComparer = ItemDisplayPartialEquality g @@ -819,51 +601,38 @@ module internal SymbolHelpers = member x.Equals((item1, _), (item2, _)) = itemComparer.Equals(item1, item2) member x.GetHashCode ((item, _)) = itemComparer.GetHashCode item } - // Remove items containing the same module references - let RemoveDuplicateModuleRefs modrefs = - modrefs |> IPartialEqualityComparer.partialDistinctBy - { new IPartialEqualityComparer with - member x.InEqualityRelation _ = true - member x.Equals(item1, item2) = (fullDisplayTextOfModRef item1 = fullDisplayTextOfModRef item2) - member x.GetHashCode item = hash item.Stamp } - /// Remove all duplicate items - let RemoveDuplicateItems g (items: ItemWithInst list) = + let RemoveDuplicateItems g (items: ItemWithInst list) = + if isNil items then items else items |> IPartialEqualityComparer.partialDistinctBy (IPartialEqualityComparer.On (fun item -> item.Item) (ItemDisplayPartialEquality g)) - /// Remove all duplicate items - let RemoveDuplicateCompletionItems g items = - items |> IPartialEqualityComparer.partialDistinctBy (CompletionItemDisplayPartialEquality g) - let IsExplicitlySuppressed (g: TcGlobals) (item: Item) = // This may explore assemblies that are not in the reference set. // In this case just assume the item is not suppressed. protectAssemblyExploration true (fun () -> - match item with - | Item.Types(it, [ty]) -> - isAppTy g ty && - g.suppressed_types - |> List.exists (fun supp -> - let generalizedSupp = generalizedTyconRef supp - // check the display name is precisely the one we're suppressing - isAppTy g generalizedSupp && it = supp.DisplayName && - // check if they are the same logical type (after removing all abbreviations) - let tcr1 = tcrefOfAppTy g ty - let tcr2 = tcrefOfAppTy g generalizedSupp - tyconRefEq g tcr1 tcr2) - | _ -> false) - - /// Filter types that are explicitly suppressed from the IntelliSense (such as uppercase "FSharpList", "Option", etc.) - let RemoveExplicitlySuppressed (g: TcGlobals) (items: ItemWithInst list) = - items |> List.filter (fun item -> not (IsExplicitlySuppressed g item.Item)) + match item with + | Item.Types(it, [ty]) -> + match tryTcrefOfAppTy g ty with + | ValueSome tcr1 -> + g.suppressed_types + |> List.exists (fun supp -> + let generalizedSupp = generalizedTyconRef supp + // check the display name is precisely the one we're suppressing + match tryTcrefOfAppTy g generalizedSupp with + | ValueSome tcr2 -> + it = supp.DisplayName && + // check if they are the same logical type (after removing all abbreviations) + tyconRefEq g tcr1 tcr2 + | _ -> false) + | _ -> false + | _ -> false) /// Filter types that are explicitly suppressed from the IntelliSense (such as uppercase "FSharpList", "Option", etc.) - let RemoveExplicitlySuppressedCompletionItems (g: TcGlobals) (items: CompletionItem list) = - items |> List.filter (fun item -> not (IsExplicitlySuppressed g item.Item)) + let RemoveExplicitlySuppressed (g: TcGlobals) (items: ItemWithInst list) = + items |> List.filter (fun item -> not (IsExplicitlySuppressed g item.Item)) let SimplerDisplayEnv denv = - { denv with suppressInlineKeyword=true - shortConstraints=true + { denv with shortConstraints=true showConstraintTyparAnnotations=false abbreviateAdditionalConstraints=false suppressNestedTypes=true @@ -881,9 +650,9 @@ module internal SymbolHelpers = | Item.AnonRecdField(anon, _argTys, i, _) -> anon.SortedNames.[i] | Item.RecdField rfinfo -> fullDisplayTextOfRecdFieldRef rfinfo.RecdFieldRef | Item.NewDef id -> id.idText - | Item.ILField finfo -> bufs (fun os -> NicePrint.outputILTypeRef denv os finfo.ILTypeRef; bprintf os ".%s" finfo.FieldName) + | Item.ILField finfo -> bufs (fun os -> NicePrint.outputType denv os finfo.ApparentEnclosingType; bprintf os ".%s" finfo.FieldName) | Item.Event einfo -> bufs (fun os -> NicePrint.outputTyconRef denv os einfo.DeclaringTyconRef; bprintf os ".%s" einfo.EventName) - | Item.Property(_, (pinfo :: _)) -> bufs (fun os -> NicePrint.outputTyconRef denv os pinfo.DeclaringTyconRef; bprintf os ".%s" pinfo.PropertyName) + | Item.Property(_, pinfo :: _) -> bufs (fun os -> NicePrint.outputTyconRef denv os pinfo.DeclaringTyconRef; bprintf os ".%s" pinfo.PropertyName) | Item.CustomOperation (customOpName, _, _) -> customOpName | Item.CtorGroup(_, minfo :: _) -> bufs (fun os -> NicePrint.outputTyconRef denv os minfo.DeclaringTyconRef) | Item.MethodGroup(_, _, Some minfo) -> bufs (fun os -> NicePrint.outputTyconRef denv os minfo.DeclaringTyconRef; bprintf os ".%s" minfo.DisplayName) @@ -892,16 +661,17 @@ module internal SymbolHelpers = | Item.FakeInterfaceCtor ty | Item.DelegateCtor ty | Item.Types(_, ty :: _) -> - match tryDestAppTy g ty with + match tryTcrefOfAppTy g ty with | ValueSome tcref -> bufs (fun os -> NicePrint.outputTyconRef denv os tcref) | _ -> "" - | Item.ModuleOrNamespaces((modref :: _) as modrefs) -> + | Item.ModuleOrNamespaces(modref :: _ as modrefs) -> let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace) - if definiteNamespace then fullDisplayTextOfModRef modref else modref.DemangledModuleOrNamespaceName + if definiteNamespace then fullDisplayTextOfModRef modref else modref.DisplayName | Item.TypeVar (id, _) -> id | Item.ArgName (id, _, _) -> id.idText | Item.SetterArg (_, item) -> FullNameOfItem g item | Item.ImplicitOp(id, _) -> id.idText + | Item.UnionCaseField (UnionCaseInfo (_, ucref), fieldIndex) -> ucref.FieldByIndex(fieldIndex).DisplayName // unreachable | Item.UnqualifiedType([]) | Item.Types(_, []) @@ -930,7 +700,16 @@ module internal SymbolHelpers = GetXmlCommentForItemAux (if tyconRefUsesLocalXmlDoc g.compilingFslib ecref || ecref.XmlDoc.NonEmpty then Some ecref.XmlDoc else None) infoReader m item | Item.RecdField rfinfo -> - GetXmlCommentForItemAux (if tyconRefUsesLocalXmlDoc g.compilingFslib rfinfo.TyconRef || rfinfo.TyconRef.XmlDoc.NonEmpty then Some rfinfo.RecdField.XmlDoc else None) infoReader m item + let tcref = rfinfo.TyconRef + let xmldoc = + if tyconRefUsesLocalXmlDoc g.compilingFslib tcref || tcref.XmlDoc.NonEmpty then + if tcref.IsExceptionDecl then + Some tcref.XmlDoc + else + Some rfinfo.RecdField.XmlDoc + else + None + GetXmlCommentForItemAux xmldoc infoReader m item | Item.Event einfo -> GetXmlCommentForItemAux (if einfo.HasDirectXmlComment || einfo.XmlDoc.NonEmpty then Some einfo.XmlDoc else None) infoReader m item @@ -944,10 +723,10 @@ module internal SymbolHelpers = | Item.MethodGroup(_, minfo :: _, _) -> GetXmlCommentForMethInfoItem infoReader m item minfo - | Item.Types(_, ((TType_app(tcref, _)) :: _)) -> + | Item.Types(_, TType_app(tcref, _) :: _) -> GetXmlCommentForItemAux (if tyconRefUsesLocalXmlDoc g.compilingFslib tcref || tcref.XmlDoc.NonEmpty then Some tcref.XmlDoc else None) infoReader m item - | Item.ModuleOrNamespaces((modref :: _) as modrefs) -> + | Item.ModuleOrNamespaces(modref :: _ as modrefs) -> let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace) if not definiteNamespace then GetXmlCommentForItemAux (if entityRefInThisAssembly g.compilingFslib modref || modref.XmlDoc.NonEmpty then Some modref.XmlDoc else None) infoReader m item @@ -961,11 +740,14 @@ module internal SymbolHelpers = if minfo.HasDirectXmlComment || minfo.XmlDoc.NonEmpty then Some minfo.XmlDoc else None | Some(ArgumentContainer.Type tcref) -> if tyconRefUsesLocalXmlDoc g.compilingFslib tcref || tcref.XmlDoc.NonEmpty then Some tcref.XmlDoc else None - | Some(ArgumentContainer.UnionCase ucinfo) -> - if tyconRefUsesLocalXmlDoc g.compilingFslib ucinfo.TyconRef || ucinfo.UnionCase.XmlDoc.NonEmpty then Some ucinfo.UnionCase.XmlDoc else None | _ -> None GetXmlCommentForItemAux xmldoc infoReader m item + | Item.UnionCaseField (ucinfo, _) -> + let xmldoc = + if tyconRefUsesLocalXmlDoc g.compilingFslib ucinfo.TyconRef || ucinfo.UnionCase.XmlDoc.NonEmpty then Some ucinfo.UnionCase.XmlDoc else None + GetXmlCommentForItemAux xmldoc infoReader m item + | Item.SetterArg (_, item) -> GetXmlCommentForItem infoReader m item @@ -978,271 +760,20 @@ module internal SymbolHelpers = | _ -> GetXmlCommentForItemAux None infoReader m item + |> GetXmlDocFromLoader infoReader + let IsAttribute (infoReader: InfoReader) item = try let g = infoReader.g let amap = infoReader.amap match item with - | Item.Types(_, ((TType_app(tcref, _)) :: _)) + | Item.Types(_, TType_app(tcref, _) :: _) | Item.UnqualifiedType(tcref :: _) -> let ty = generalizedTyconRef tcref - Infos.ExistsHeadTypeInEntireHierarchy g amap range0 ty g.tcref_System_Attribute + ExistsHeadTypeInEntireHierarchy g amap range0 ty g.tcref_System_Attribute | _ -> false with _ -> false - /// Output the quick info information of a language item - let rec FormatItemDescriptionToToolTipElement isListItem (infoReader: InfoReader) m denv (item: ItemWithInst) = - let g = infoReader.g - let amap = infoReader.amap - let denv = SimplerDisplayEnv denv - let xml = GetXmlCommentForItem infoReader m item.Item - match item.Item with - | Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(_, vref, _)) }) -> - // operator with solution - FormatItemDescriptionToToolTipElement isListItem infoReader m denv { item with Item = Item.Value vref } - - | Item.Value vref | Item.CustomBuilder (_, vref) -> - let prettyTyparInst, resL = NicePrint.layoutQualifiedValOrMember denv item.TyparInst vref.Deref - let remarks = OutputFullName isListItem pubpathOfValRef fullDisplayTextOfValRefAsLayout vref - let tpsL = FormatTyparMapping denv prettyTyparInst - FSharpStructuredToolTipElement.Single(resL, xml, tpsL, remarks=remarks) - - // Union tags (constructors) - | Item.UnionCase(ucinfo, _) -> - let uc = ucinfo.UnionCase - let rty = generalizedTyconRef ucinfo.TyconRef - let recd = uc.RecdFields - let layout = - wordL (tagText (FSComp.SR.typeInfoUnionCase())) ^^ - NicePrint.layoutTyconRef denv ucinfo.TyconRef ^^ - sepL (tagPunctuation ".") ^^ - wordL (tagUnionCase (DecompileOpName uc.Id.idText) |> mkNav uc.DefinitionRange) ^^ - RightL.colon ^^ - (if List.isEmpty recd then emptyL else NicePrint.layoutUnionCases denv recd ^^ WordL.arrow) ^^ - NicePrint.layoutType denv rty - FSharpStructuredToolTipElement.Single (layout, xml) - - // Active pattern tag inside the declaration (result) - | Item.ActivePatternResult(apinfo, ty, idx, _) -> - let items = apinfo.ActiveTags - let layout = - wordL (tagText ((FSComp.SR.typeInfoActivePatternResult()))) ^^ - wordL (tagActivePatternResult (List.item idx items) |> mkNav apinfo.Range) ^^ - RightL.colon ^^ - NicePrint.layoutType denv ty - FSharpStructuredToolTipElement.Single (layout, xml) - - // Active pattern tags - | Item.ActivePatternCase apref -> - let v = apref.ActivePatternVal - // Format the type parameters to get e.g. ('a -> 'a) rather than ('?1234 -> '?1234) - let tau = v.TauType - // REVIEW: use _cxs here - let (prettyTyparInst, ptau), _cxs = PrettyTypes.PrettifyInstAndType denv.g (item.TyparInst, tau) - let remarks = OutputFullName isListItem pubpathOfValRef fullDisplayTextOfValRefAsLayout v - let layout = - wordL (tagText (FSComp.SR.typeInfoActiveRecognizer())) ^^ - wordL (tagActivePatternCase apref.Name |> mkNav v.DefinitionRange) ^^ - RightL.colon ^^ - NicePrint.layoutType denv ptau - - let tpsL = FormatTyparMapping denv prettyTyparInst - - FSharpStructuredToolTipElement.Single (layout, xml, tpsL, remarks=remarks) - - // F# exception names - | Item.ExnCase ecref -> - let layout = NicePrint.layoutExnDef denv ecref.Deref - let remarks= OutputFullName isListItem pubpathOfTyconRef fullDisplayTextOfExnRefAsLayout ecref - FSharpStructuredToolTipElement.Single (layout, xml, remarks=remarks) - - // F# record field names - | Item.RecdField rfinfo -> - let rfield = rfinfo.RecdField - let ty, _cxs = PrettyTypes.PrettifyType g rfinfo.FieldType - let layout = - NicePrint.layoutTyconRef denv rfinfo.TyconRef ^^ - SepL.dot ^^ - wordL (tagRecordField (DecompileOpName rfield.Name) |> mkNav rfield.DefinitionRange) ^^ - RightL.colon ^^ - NicePrint.layoutType denv ty ^^ - ( - match rfinfo.LiteralValue with - | None -> emptyL - | Some lit -> try WordL.equals ^^ NicePrint.layoutConst denv.g ty lit with _ -> emptyL - ) - FSharpStructuredToolTipElement.Single (layout, xml) - - // Not used - | Item.NewDef id -> - let layout = - wordL (tagText (FSComp.SR.typeInfoPatternVariable())) ^^ - wordL (tagUnknownEntity id.idText) - FSharpStructuredToolTipElement.Single (layout, xml) - - // .NET fields - | Item.ILField finfo -> - let layout = - wordL (tagText (FSComp.SR.typeInfoField())) ^^ - NicePrint.layoutILTypeRef denv finfo.ILTypeRef ^^ - SepL.dot ^^ - wordL (tagField finfo.FieldName) ^^ - RightL.colon ^^ - NicePrint.layoutType denv (finfo.FieldType(amap, m)) ^^ - ( - match finfo.LiteralValue with - | None -> emptyL - | Some v -> - WordL.equals ^^ - try NicePrint.layoutConst denv.g (finfo.FieldType(infoReader.amap, m)) (TypeChecker.TcFieldInit m v) with _ -> emptyL - ) - FSharpStructuredToolTipElement.Single (layout, xml) - - // .NET events - | Item.Event einfo -> - let rty = PropTypOfEventInfo infoReader m AccessibleFromSomewhere einfo - let rty, _cxs = PrettyTypes.PrettifyType g rty - let layout = - wordL (tagText (FSComp.SR.typeInfoEvent())) ^^ - NicePrint.layoutTyconRef denv einfo.ApparentEnclosingTyconRef ^^ - SepL.dot ^^ - wordL (tagEvent einfo.EventName) ^^ - RightL.colon ^^ - NicePrint.layoutType denv rty - FSharpStructuredToolTipElement.Single (layout, xml) - - // F# and .NET properties - | Item.Property(_, pinfo :: _) -> - let layout = NicePrint.prettyLayoutOfPropInfoFreeStyle g amap m denv pinfo - FSharpStructuredToolTipElement.Single (layout, xml) - - // Custom operations in queries - | Item.CustomOperation (customOpName, usageText, Some minfo) -> - - // Build 'custom operation: where (bool) - // - // Calls QueryBuilder.Where' - let layout = - wordL (tagText (FSComp.SR.typeInfoCustomOperation())) ^^ - RightL.colon ^^ - ( - match usageText() with - | Some t -> wordL (tagText t) - | None -> - let argTys = ParamNameAndTypesOfUnaryCustomOperation g minfo |> List.map (fun (ParamNameAndType(_, ty)) -> ty) - let argTys, _ = PrettyTypes.PrettifyTypes g argTys - wordL (tagMethod customOpName) ^^ sepListL SepL.space (List.map (fun ty -> LeftL.leftParen ^^ NicePrint.layoutType denv ty ^^ SepL.rightParen) argTys) - ) ^^ - SepL.lineBreak ^^ SepL.lineBreak ^^ - wordL (tagText (FSComp.SR.typeInfoCallsWord())) ^^ - NicePrint.layoutTyconRef denv minfo.ApparentEnclosingTyconRef ^^ - SepL.dot ^^ - wordL (tagMethod minfo.DisplayName) - - FSharpStructuredToolTipElement.Single (layout, xml) - - // F# constructors and methods - | Item.CtorGroup(_, minfos) - | Item.MethodGroup(_, minfos, _) -> - FormatOverloadsToList infoReader m denv item minfos - - // The 'fake' zero-argument constructors of .NET interfaces. - // This ideally should never appear in intellisense, but we do get here in repros like: - // type IFoo = abstract F : int - // type II = IFoo // remove 'type II = ' and quickly hover over IFoo before it gets squiggled for 'invalid use of interface type' - // and in that case we'll just show the interface type name. - | Item.FakeInterfaceCtor ty -> - let ty, _ = PrettyTypes.PrettifyType g ty - let layout = NicePrint.layoutTyconRef denv (tcrefOfAppTy g ty) - FSharpStructuredToolTipElement.Single(layout, xml) - - // The 'fake' representation of constructors of .NET delegate types - | Item.DelegateCtor delty -> - let delty, _cxs = PrettyTypes.PrettifyType g delty - let (SigOfFunctionForDelegate(_, _, _, fty)) = GetSigOfFunctionForDelegate infoReader delty m AccessibleFromSomewhere - let layout = - NicePrint.layoutTyconRef denv (tcrefOfAppTy g delty) ^^ - LeftL.leftParen ^^ - NicePrint.layoutType denv fty ^^ - RightL.rightParen - FSharpStructuredToolTipElement.Single(layout, xml) - - // Types. - | Item.Types(_, ((TType_app(tcref, _)) :: _)) - | Item.UnqualifiedType (tcref :: _) -> - let denv = { denv with shortTypeNames = true } - let layout = NicePrint.layoutTycon denv infoReader AccessibleFromSomewhere m (* width *) tcref.Deref - let remarks = OutputFullName isListItem pubpathOfTyconRef fullDisplayTextOfTyconRefAsLayout tcref - FSharpStructuredToolTipElement.Single (layout, xml, remarks=remarks) - - // F# Modules and namespaces - | Item.ModuleOrNamespaces((modref :: _) as modrefs) -> - //let os = StringBuilder() - let modrefs = modrefs |> RemoveDuplicateModuleRefs - let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace) - let kind = - if definiteNamespace then FSComp.SR.typeInfoNamespace() - elif modrefs |> List.forall (fun modref -> modref.IsModule) then FSComp.SR.typeInfoModule() - else FSComp.SR.typeInfoNamespaceOrModule() - - let layout = - wordL (tagKeyword kind) ^^ - (if definiteNamespace then tagNamespace (fullDisplayTextOfModRef modref) else (tagModule modref.DemangledModuleOrNamespaceName) - |> mkNav modref.DefinitionRange - |> wordL) - if not definiteNamespace then - let namesToAdd = - ([], modrefs) - ||> Seq.fold (fun st modref -> - match fullDisplayTextOfParentOfModRef modref with - | ValueSome txt -> txt :: st - | _ -> st) - |> Seq.mapi (fun i x -> i, x) - |> Seq.toList - let layout = - layout ^^ - ( - if not (List.isEmpty namesToAdd) then - SepL.lineBreak ^^ - List.fold ( fun s (i, txt) -> - s ^^ - SepL.lineBreak ^^ - wordL (tagText ((if i = 0 then FSComp.SR.typeInfoFromFirst else FSComp.SR.typeInfoFromNext) txt)) - ) emptyL namesToAdd - else - emptyL - ) - FSharpStructuredToolTipElement.Single (layout, xml) - else - FSharpStructuredToolTipElement.Single (layout, xml) - - | Item.AnonRecdField(anon, argTys, i, _) -> - let argTy = argTys.[i] - let nm = anon.SortedNames.[i] - let argTy, _ = PrettyTypes.PrettifyType g argTy - let layout = - wordL (tagText (FSComp.SR.typeInfoAnonRecdField())) ^^ - wordL (tagRecordField nm) ^^ - RightL.colon ^^ - NicePrint.layoutType denv argTy - FSharpStructuredToolTipElement.Single (layout, FSharpXmlDoc.None) - - // Named parameters - | Item.ArgName (id, argTy, _) -> - let argTy, _ = PrettyTypes.PrettifyType g argTy - let layout = - wordL (tagText (FSComp.SR.typeInfoArgument())) ^^ - wordL (tagParameter id.idText) ^^ - RightL.colon ^^ - NicePrint.layoutType denv argTy - FSharpStructuredToolTipElement.Single (layout, xml, paramName = id.idText) - - | Item.SetterArg (_, item) -> - FormatItemDescriptionToToolTipElement isListItem infoReader m denv (ItemWithNoInst item) - - | _ -> - FSharpStructuredToolTipElement.None - #if !NO_EXTENSIONTYPING /// Determine if an item is a provided type @@ -1267,7 +798,7 @@ module internal SymbolHelpers = if tyconRef.IsProvidedErasedTycon || tyconRef.IsProvidedGeneratedTycon then let typeBeforeArguments = match tyconRef.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.ProvidedType + | TProvidedTypeRepr info -> info.ProvidedType | _ -> failwith "unreachable" let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.GetStaticParameters provider), range=m) let staticParameters = staticParameters.PApplyArray(id, "GetStaticParameters", m) @@ -1277,7 +808,6 @@ module internal SymbolHelpers = | _ -> None | _ -> None - let (|ItemIsProvidedMethodWithStaticArguments|_|) item = match item with // Prefer the static parameters from the uninstantiated method info @@ -1341,10 +871,10 @@ module internal SymbolHelpers = GetF1Keyword g (Item.Value apref.ActivePatternVal) | Item.UnionCase(ucinfo, _) -> - (ucinfo.TyconRef |> ticksAndArgCountTextOfTyconRef) + "."+ucinfo.Name |> Some + (ucinfo.TyconRef |> ticksAndArgCountTextOfTyconRef) + "."+ucinfo.DisplayName |> Some | Item.RecdField rfi -> - (rfi.TyconRef |> ticksAndArgCountTextOfTyconRef) + "." + rfi.Name |> Some + (rfi.TyconRef |> ticksAndArgCountTextOfTyconRef) + "." + rfi.DisplayName |> Some | Item.AnonRecdField _ -> None @@ -1355,7 +885,7 @@ module internal SymbolHelpers = #if !NO_EXTENSIONTYPING | ProvidedField _ -> None #endif - | Item.Types(_, ((AppTy g (tcref, _)) :: _)) + | Item.Types(_, AppTy g (tcref, _) :: _) | Item.DelegateCtor(AppTy g (tcref, _)) | Item.FakeInterfaceCtor(AppTy g (tcref, _)) | Item.UnqualifiedType (tcref :: _) @@ -1379,7 +909,7 @@ module internal SymbolHelpers = // otherwise we'll fail at tast.fs match modref.Deref.TypeReprInfo with #if !NO_EXTENSIONTYPING - | TProvidedNamespaceExtensionPoint _ -> + | TProvidedNamespaceRepr _ -> modref.CompilationPathOpt |> Option.bind (fun path -> // works similar to generation of xml-docs at tastops.fs, probably too similar @@ -1392,7 +922,7 @@ module internal SymbolHelpers = | _ -> modref.Deref.CompiledRepresentationForNamedType.FullName |> Some | [] -> None // Pathological case of the above - | Item.Property(_, (pinfo :: _)) -> + | Item.Property(_, pinfo :: _) -> match pinfo with | FSProp(_, _, Some vref, _) | FSProp(_, _, _, Some vref) -> @@ -1448,30 +978,27 @@ module internal SymbolHelpers = | Item.CustomOperation (_, _, None) // "into" | Item.NewDef _ // "let x$yz = ..." - no keyword | Item.ArgName _ // no keyword on named parameters + | Item.UnionCaseField _ | Item.TypeVar _ | Item.ImplicitOp _ | Item.ActivePatternResult _ // "let (|Foo|Bar|) = .. Fo$o ..." - no keyword -> None - - /// Format the structured version of a tooltip for an item - let FormatStructuredDescriptionOfItem isListItem infoReader m denv item = - ErrorScope.Protect m - (fun () -> FormatItemDescriptionToToolTipElement isListItem infoReader m denv item) - (fun err -> FSharpStructuredToolTipElement.CompositionError err) - /// Get rid of groups of overloads an replace them with single items. - let FlattenItems g (m: range) item = - match item with - | Item.MethodGroup(nm, minfos, orig) -> minfos |> List.map (fun minfo -> Item.MethodGroup(nm, [minfo], orig)) - | Item.CtorGroup(nm, cinfos) -> cinfos |> List.map (fun minfo -> Item.CtorGroup(nm, [minfo])) + let FlattenItems g (m: range) (item: ItemWithInst) : ItemWithInst list = + ignore m + match item.Item with + | Item.MethodGroup(nm, minfos, orig) -> + minfos |> List.map (fun minfo -> { Item = Item.MethodGroup(nm, [minfo], orig); TyparInst = item.TyparInst }) + | Item.CtorGroup(nm, cinfos) -> + cinfos |> List.map (fun minfo -> { Item = Item.CtorGroup(nm, [minfo]); TyparInst = item.TyparInst }) | Item.FakeInterfaceCtor _ | Item.DelegateCtor _ -> [item] | Item.NewDef _ | Item.ILField _ -> [] | Item.Event _ -> [] - | Item.RecdField rfinfo -> if isFunction g rfinfo.FieldType then [item] else [] - | Item.Value v -> if isFunction g v.Type then [item] else [] + | Item.RecdField rfinfo -> if isForallFunctionTy g rfinfo.FieldType then [item] else [] + | Item.Value v -> if isForallFunctionTy g v.Type then [item] else [] | Item.UnionCase(ucr, _) -> if not ucr.UnionCase.IsNullary then [item] else [] | Item.ExnCase ecr -> if isNil (recdFieldsOfExnDefRef ecr) then [] else [item] | Item.Property(_, pinfos) -> diff --git a/src/fsharp/symbols/SymbolHelpers.fsi b/src/fsharp/symbols/SymbolHelpers.fsi index e6ece6fa2ca..a900aac4dbb 100755 --- a/src/fsharp/symbols/SymbolHelpers.fsi +++ b/src/fsharp/symbols/SymbolHelpers.fsi @@ -4,201 +4,166 @@ // Helpers for quick info and information about items //---------------------------------------------------------------------------- -namespace FSharp.Compiler.SourceCodeServices - -open System -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Infos -open FSharp.Compiler.NameResolution -open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.ErrorLogger +namespace FSharp.Compiler.Diagnostics -//---------------------------------------------------------------------------- -// Object model for diagnostics - - -[] -type public FSharpErrorSeverity = -| Warning - | Error - -[] -type public FSharpErrorInfo = - member FileName: string - member StartLineAlternate:int - member EndLineAlternate:int - member StartColumn:int - member EndColumn:int - member Severity:FSharpErrorSeverity - member Message:string - member Subcategory:string - member ErrorNumber:int - static member internal CreateFromExceptionAndAdjustEof : PhasedDiagnostic * isError: bool * range * lastPosInFile:(int*int) * suggestNames: bool -> FSharpErrorInfo - static member internal CreateFromException : PhasedDiagnostic * isError: bool * range * suggestNames: bool -> FSharpErrorInfo + open System + open FSharp.Compiler.Text + open FSharp.Compiler.ErrorLogger -//---------------------------------------------------------------------------- -// Object model for quick info - -/// Describe a comment as either a block of text or a file+signature reference into an intellidoc file. -// -// Note: instances of this type do not hold any references to any compiler resources. -[] -type public FSharpXmlDoc = - /// No documentation is available - | None - - /// The text for documentation - | Text of string - - /// Indicates that the text for the documentation can be found in a .xml documentation file, using the given signature key - | XmlDocFileSignature of (*File:*) string * (*Signature:*)string - -type public Layout = Internal.Utilities.StructuredFormat.Layout - -/// A single data tip display element -[] -type public FSharpToolTipElementData<'T> = - { MainDescription: 'T - XmlDoc: FSharpXmlDoc - /// typar instantiation text, to go after xml - TypeMapping: 'T list - /// Extra text, goes at the end - Remarks: 'T option - /// Parameter name - ParamName : string option } - -/// A single tool tip display element -// -// Note: instances of this type do not hold any references to any compiler resources. -[] -type public FSharpToolTipElement<'T> = - | None - - /// A single type, method, etc with comment. May represent a method overload group. - | Group of FSharpToolTipElementData<'T> list - - /// An error occurred formatting this element - | CompositionError of string - static member Single : 'T * FSharpXmlDoc * ?typeMapping: 'T list * ?paramName: string * ?remarks : 'T -> FSharpToolTipElement<'T> - -/// A single data tip display element with where text is expressed as string -type public FSharpToolTipElement = FSharpToolTipElement - - -/// A single data tip display element with where text is expressed as -type public FSharpStructuredToolTipElement = FSharpToolTipElement - -/// Information for building a tool tip box. -// -// Note: instances of this type do not hold any references to any compiler resources. -type public FSharpToolTipText<'T> = - /// A list of data tip elements to display. - | FSharpToolTipText of FSharpToolTipElement<'T> list - -type public FSharpToolTipText = FSharpToolTipText -type public FSharpStructuredToolTipText = FSharpToolTipText + /// Represents a diagnostic produced by the F# compiler + [] + type public FSharpDiagnostic = + + /// Gets the file name for the diagnostic + member FileName: string + + /// Gets the start position for the diagnostic + member Start: Position + + /// Gets the end position for the diagnostic + member End: Position + + /// Gets the start column for the diagnostic + member StartColumn: int + + /// Gets the end column for the diagnostic + member EndColumn: int + + /// Gets the start line for the diagnostic + member StartLine: int + + /// Gets the end line for the diagnostic + member EndLine: int + + /// Gets the range for the diagnostic + member Range: range + + /// Gets the severity for the diagnostic + member Severity: FSharpDiagnosticSeverity + + /// Gets the message for the diagnostic + member Message: string + + /// Gets the sub-category for the diagnostic + member Subcategory: string + + /// Gets the number for the diagnostic + member ErrorNumber: int + + /// Gets the number prefix for the diagnostic, usually "FS" but may differ for analyzers + member ErrorNumberPrefix: string + + /// Gets the full error number text e.g "FS0031" + member ErrorNumberText: string + + /// Creates a diagnostic, e.g. for reporting from an analyzer + static member Create: severity: FSharpDiagnosticSeverity * message: string * number: int * range: range * ?numberPrefix: string * ?subcategory: string -> FSharpDiagnostic + + static member internal CreateFromExceptionAndAdjustEof: PhasedDiagnostic * severity: FSharpDiagnosticSeverity * range * lastPosInFile: (int*int) * suggestNames: bool -> FSharpDiagnostic + + static member internal CreateFromException: PhasedDiagnostic * severity: FSharpDiagnosticSeverity * range * suggestNames: bool -> FSharpDiagnostic + + /// Newlines are recognized and replaced with (ASCII 29, the 'group separator'), + /// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo + static member NewlineifyErrorString: message:string -> string + + /// Newlines are recognized and replaced with (ASCII 29, the 'group separator'), + /// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo + static member NormalizeErrorString: text:string -> string + + //---------------------------------------------------------------------------- + // Internal only + + // Implementation details used by other code in the compiler + [] + type internal ErrorScope = + interface IDisposable + new : unit -> ErrorScope + member Diagnostics : FSharpDiagnostic list + static member Protect<'a> : range -> (unit->'a) -> (string->'a) -> 'a + + /// An error logger that capture errors, filtering them according to warning levels etc. + type internal CompilationErrorLogger = + inherit ErrorLogger + + /// Create the diagnostics logger + new: debugName:string * options: FSharpDiagnosticOptions -> CompilationErrorLogger + + /// Get the captured diagnostics + member GetDiagnostics: unit -> (PhasedDiagnostic * FSharpDiagnosticSeverity)[] + + module internal DiagnosticHelpers = + val ReportDiagnostic: FSharpDiagnosticOptions * allErrors: bool * mainInputFileName: string * fileInfo: (int * int) * (PhasedDiagnostic * FSharpDiagnosticSeverity) * suggestNames: bool -> FSharpDiagnostic list + + val CreateDiagnostics: FSharpDiagnosticOptions * allErrors: bool * mainInputFileName: string * seq * suggestNames: bool -> FSharpDiagnostic[] + +namespace FSharp.Compiler.Symbols + + open Internal.Utilities.Library + open FSharp.Compiler + open FSharp.Compiler.TcGlobals + open FSharp.Compiler.Infos + open FSharp.Compiler.NameResolution + open FSharp.Compiler.InfoReader + open FSharp.Compiler.Text + open FSharp.Compiler.Xml + open FSharp.Compiler.TypedTree + open FSharp.Compiler.TypedTreeOps + + /// Describe a comment as either a block of text or a file+signature reference into an intellidoc file. + // + // Note: instances of this type do not hold any references to any compiler resources. + [] + type public FSharpXmlDoc = + /// No documentation is available + | None + + /// The text for documentation for in-memory references. + | FromXmlText of XmlDoc + + /// Indicates that the XML for the documentation can be found in a .xml documentation file for the given DLL, using the given signature key + | FromXmlFile of dllName: string * xmlSig: string + + + // Implementation details used by other code in the compiler + module internal SymbolHelpers = + val ParamNameAndTypesOfUnaryCustomOperation : TcGlobals -> MethInfo -> ParamNameAndType list + + val GetXmlCommentForItem : InfoReader -> range -> Item -> FSharpXmlDoc + + val RemoveDuplicateItems : TcGlobals -> ItemWithInst list -> ItemWithInst list + + val RemoveExplicitlySuppressed : TcGlobals -> ItemWithInst list -> ItemWithInst list + + val GetF1Keyword : TcGlobals -> Item -> string option + + val rangeOfItem : TcGlobals -> bool option -> Item -> range option + + val fileNameOfItem : TcGlobals -> string option -> range -> Item -> string + + val FullNameOfItem : TcGlobals -> Item -> string + + val ccuOfItem : TcGlobals -> Item -> CcuThunk option + + val IsAttribute : InfoReader -> Item -> bool + + val IsExplicitlySuppressed : TcGlobals -> Item -> bool + + val FlattenItems : TcGlobals -> range -> ItemWithInst -> ItemWithInst list -//---------------------------------------------------------------------------- -// Object model for completion list entries (one of several in the API...) - - -[] -type public CompletionItemKind = - | Field - | Property - | Method of isExtension : bool - | Event - | Argument - | CustomOperation - | Other - -type UnresolvedSymbol = - { FullName: string - DisplayName: string - Namespace: string[] } - -type internal CompletionItem = - { ItemWithInst: ItemWithInst - Kind: CompletionItemKind - IsOwnMember: bool - MinorPriority: int - Type: TyconRef option - Unresolved: UnresolvedSymbol option } - member Item : Item - -module public Tooltips = - val ToFSharpToolTipElement: FSharpStructuredToolTipElement -> FSharpToolTipElement - val ToFSharpToolTipText: FSharpStructuredToolTipText -> FSharpToolTipText - val Map: f: ('T1 -> 'T2) -> a: Async<'T1> -> Async<'T2> - -// Implementation details used by other code in the compiler -module internal SymbolHelpers = - val isFunction : TcGlobals -> TType -> bool - val ParamNameAndTypesOfUnaryCustomOperation : TcGlobals -> MethInfo -> ParamNameAndType list - - val GetXmlDocSigOfEntityRef : InfoReader -> range -> EntityRef -> (string option * string) option - val GetXmlDocSigOfScopedValRef : TcGlobals -> TyconRef -> ValRef -> (string option * string) option - val GetXmlDocSigOfILFieldInfo : InfoReader -> range -> ILFieldInfo -> (string option * string) option - val GetXmlDocSigOfRecdFieldInfo : RecdFieldInfo -> (string option * string) option - val GetXmlDocSigOfUnionCaseInfo : UnionCaseInfo -> (string option * string) option - val GetXmlDocSigOfMethInfo : InfoReader -> range -> MethInfo -> (string option * string) option - val GetXmlDocSigOfValRef : TcGlobals -> ValRef -> (string option * string) option - val GetXmlDocSigOfProp : InfoReader -> range -> PropInfo -> (string option * string) option - val GetXmlDocSigOfEvent : InfoReader -> range -> EventInfo -> (string option * string) option - val GetXmlCommentForItem : InfoReader -> range -> Item -> FSharpXmlDoc - val FormatStructuredDescriptionOfItem : isDecl:bool -> InfoReader -> range -> DisplayEnv -> ItemWithInst -> FSharpStructuredToolTipElement - val RemoveDuplicateItems : TcGlobals -> ItemWithInst list -> ItemWithInst list - val RemoveExplicitlySuppressed : TcGlobals -> ItemWithInst list -> ItemWithInst list - val RemoveDuplicateCompletionItems : TcGlobals -> CompletionItem list -> CompletionItem list - val RemoveExplicitlySuppressedCompletionItems : TcGlobals -> CompletionItem list -> CompletionItem list - val GetF1Keyword : TcGlobals -> Item -> string option - val rangeOfItem : TcGlobals -> bool option -> Item -> range option - val fileNameOfItem : TcGlobals -> string option -> range -> Item -> string - val FullNameOfItem : TcGlobals -> Item -> string - val ccuOfItem : TcGlobals -> Item -> CcuThunk option - val mutable ToolTipFault : string option - val IsAttribute : InfoReader -> Item -> bool - val IsExplicitlySuppressed : TcGlobals -> Item -> bool - val FlattenItems : TcGlobals -> range -> Item -> Item list #if !NO_EXTENSIONTYPING - val (|ItemIsProvidedType|_|) : TcGlobals -> Item -> TyconRef option - val (|ItemIsWithStaticArguments|_|): range -> TcGlobals -> Item -> Tainted[] option - val (|ItemIsProvidedTypeWithStaticArguments|_|): range -> TcGlobals -> Item -> Tainted[] option + val (|ItemIsProvidedType|_|) : TcGlobals -> Item -> TyconRef option + + val (|ItemIsWithStaticArguments|_|): range -> TcGlobals -> Item -> Tainted[] option + + val (|ItemIsProvidedTypeWithStaticArguments|_|): range -> TcGlobals -> Item -> Tainted[] option #endif - val SimplerDisplayEnv : DisplayEnv -> DisplayEnv -//---------------------------------------------------------------------------- -// Internal only - -// Implementation details used by other code in the compiler -[] -type internal ErrorScope = - interface IDisposable - new : unit -> ErrorScope - member Diagnostics : FSharpErrorInfo list - static member Protect<'a> : range -> (unit->'a) -> (string->'a) -> 'a - -/// An error logger that capture errors, filtering them according to warning levels etc. -type internal CompilationErrorLogger = - inherit ErrorLogger - - /// Create the error logger - new: debugName:string * options: FSharpErrorSeverityOptions -> CompilationErrorLogger - - /// Get the captured errors - member GetErrors: unit -> (PhasedDiagnostic * FSharpErrorSeverity)[] - -/// This represents the global state established as each task function runs as part of the build. -/// -/// Use to reset error and warning handlers. -type internal CompilationGlobalsScope = - new : ErrorLogger * BuildPhase -> CompilationGlobalsScope - interface IDisposable - -module internal ErrorHelpers = - val ReportError: FSharpErrorSeverityOptions * allErrors: bool * mainInputFileName: string * fileInfo: (int * int) * (PhasedDiagnostic * FSharpErrorSeverity) * suggestNames: bool -> FSharpErrorInfo list - val CreateErrorInfos: FSharpErrorSeverityOptions * allErrors: bool * mainInputFileName: string * seq<(PhasedDiagnostic * FSharpErrorSeverity)> * suggestNames: bool -> FSharpErrorInfo[] + val SimplerDisplayEnv : DisplayEnv -> DisplayEnv + + val ItemDisplayPartialEquality: g:TcGlobals -> IPartialEqualityComparer + + val GetXmlCommentForMethInfoItem: infoReader:InfoReader -> m:range -> d:Item -> minfo:MethInfo -> FSharpXmlDoc + + val FormatTyparMapping: denv:DisplayEnv -> prettyTyparInst:TyparInst -> Layout list + diff --git a/src/fsharp/symbols/SymbolPatterns.fs b/src/fsharp/symbols/SymbolPatterns.fs index 6c2286b4095..bd24f85c4e6 100644 --- a/src/fsharp/symbols/SymbolPatterns.fs +++ b/src/fsharp/symbols/SymbolPatterns.fs @@ -1,27 +1,20 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Symbols + +open System.Text.RegularExpressions +open Internal.Utilities.Library +open FSharp.Compiler.Syntax /// Patterns over FSharpSymbol and derivatives. [] -module Symbol = - open System - open System.Text.RegularExpressions - open FSharp.Compiler.AbstractIL.Internal.Library - - let isAttribute<'T> (attribute: FSharpAttribute) = - // CompiledName throws exception on DataContractAttribute generated by SQLProvider - try attribute.AttributeType.CompiledName = typeof<'T>.Name with _ -> false - - let tryGetAttribute<'T> (attributes: seq) = - attributes |> Seq.tryFind isAttribute<'T> +module FSharpSymbolPatterns = module Option = let attempt f = try Some(f()) with _ -> None let hasModuleSuffixAttribute (entity: FSharpEntity) = - entity.Attributes - |> tryGetAttribute + entity.TryGetAttribute() |> Option.bind (fun a -> Option.attempt (fun _ -> a.ConstructorArguments) |> Option.bind (fun args -> args |> Seq.tryPick (fun (_, arg) -> @@ -36,15 +29,8 @@ module Symbol = res))) |> Option.isSome - let isOperator (name: string) = - name.StartsWithOrdinal("( ") && name.EndsWithOrdinal(" )") && name.Length > 4 - && name.Substring (2, name.Length - 4) - |> String.forall (fun c -> c <> ' ' && not (Char.IsLetter c)) - let UnnamedUnionFieldRegex = Regex("^Item(\d+)?$", RegexOptions.Compiled) - let isUnnamedUnionCaseField (field: FSharpField) = UnnamedUnionFieldRegex.IsMatch(field.Name) - let (|AbbreviatedType|_|) (entity: FSharpEntity) = if entity.IsFSharpAbbreviation then Some entity.AbbreviatedType else None @@ -60,11 +46,6 @@ module Symbol = | abbreviatedType -> entity, Some abbreviatedType else entity, None - let rec getAbbreviatedType (fsharpType: FSharpType) = - if fsharpType.IsAbbreviation then - getAbbreviatedType fsharpType.AbbreviatedType - else fsharpType - let (|Attribute|_|) (entity: FSharpEntity) = let isAttribute (entity: FSharpEntity) = let getBaseType (entity: FSharpEntity) = @@ -83,11 +64,8 @@ module Symbol = isAttributeType (Some entity) if isAttribute entity then Some() else None - let hasAttribute<'T> (attributes: seq) = - attributes |> Seq.exists isAttribute<'T> - let (|ValueType|_|) (e: FSharpEntity) = - if e.IsEnum || e.IsValueType || hasAttribute e.Attributes then Some() + if e.IsEnum || e.IsValueType || e.HasAttribute() then Some() else None #if !NO_EXTENSIONTYPING @@ -102,12 +80,17 @@ module Symbol = #endif let (|Record|_|) (e: FSharpEntity) = if e.IsFSharpRecord then Some() else None + let (|UnionType|_|) (e: FSharpEntity) = if e.IsFSharpUnion then Some() else None + let (|Delegate|_|) (e: FSharpEntity) = if e.IsDelegate then Some() else None + let (|FSharpException|_|) (e: FSharpEntity) = if e.IsFSharpExceptionDeclaration then Some() else None + let (|Interface|_|) (e: FSharpEntity) = if e.IsInterface then Some() else None + let (|AbstractClass|_|) (e: FSharpEntity) = - if hasAttribute e.Attributes then Some() else None + if e.HasAttribute() then Some() else None let (|FSharpType|_|) (e: FSharpEntity) = if e.IsDelegate || e.IsFSharpExceptionDeclaration || e.IsFSharpRecord || e.IsFSharpUnion @@ -123,20 +106,24 @@ module Symbol = #endif let (|ByRef|_|) (e: FSharpEntity) = if e.IsByRef then Some() else None + let (|Array|_|) (e: FSharpEntity) = if e.IsArrayType then Some() else None + let (|FSharpModule|_|) (entity: FSharpEntity) = if entity.IsFSharpModule then Some() else None let (|Namespace|_|) (entity: FSharpEntity) = if entity.IsNamespace then Some() else None + #if !NO_EXTENSIONTYPING let (|ProvidedAndErasedType|_|) (entity: FSharpEntity) = if entity.IsProvidedAndErased then Some() else None #endif + let (|Enum|_|) (entity: FSharpEntity) = if entity.IsEnum then Some() else None let (|Tuple|_|) (ty: FSharpType) = if ty.IsTupleType then Some() else None let (|RefCell|_|) (ty: FSharpType) = - match getAbbreviatedType ty with + match ty.StripAbbreviations() with | TypeWithDefinition def when def.IsFSharpRecord && def.FullName = "Microsoft.FSharp.Core.FSharpRef`1" -> Some() | _ -> None @@ -151,10 +138,9 @@ module Symbol = | :? FSharpActivePatternCase -> Some() | _ -> None - /// Field (field, fieldAbbreviatedType) let (|Field|_|) (symbol: FSharpSymbol) = match symbol with - | :? FSharpField as field -> Some (field, getAbbreviatedType field.FieldType) + | :? FSharpField as field -> Some (field, field.FieldType.StripAbbreviations()) | _ -> None let (|MutableVar|_|) (symbol: FSharpSymbol) = @@ -209,12 +195,12 @@ module Symbol = | _ -> None let (|Function|_|) excluded (func: FSharpMemberOrFunctionOrValue) = - try let ty = func.FullType |> getAbbreviatedType + try let ty = func.FullType.StripAbbreviations() if ty.IsFunctionType && not func.IsPropertyGetterMethod && not func.IsPropertySetterMethod && not excluded - && not (isOperator func.DisplayName) then Some() + && not (PrettyNaming.IsOperatorDisplayName func.DisplayName) then Some() else None with _ -> None diff --git a/src/fsharp/symbols/SymbolPatterns.fsi b/src/fsharp/symbols/SymbolPatterns.fsi index ca3659f34d6..2687ff47eef 100644 --- a/src/fsharp/symbols/SymbolPatterns.fsi +++ b/src/fsharp/symbols/SymbolPatterns.fsi @@ -1,55 +1,85 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace FSharp.Compiler.Symbols -[] /// Patterns over FSharpSymbol and derivatives. -module public Symbol = - - val isAttribute<'T> : FSharpAttribute -> bool - val tryGetAttribute<'T> : seq -> FSharpAttribute option - val hasModuleSuffixAttribute : FSharpEntity -> bool - val isOperator : name: string -> bool - val isUnnamedUnionCaseField : FSharpField -> bool - val (|AbbreviatedType|_|) : FSharpEntity -> FSharpType option - val (|TypeWithDefinition|_|) : FSharpType -> FSharpEntity option - val getEntityAbbreviatedType : FSharpEntity -> (FSharpEntity * FSharpType option) - val getAbbreviatedType : FSharpType -> FSharpType - val (|Attribute|_|) : FSharpEntity -> unit option - val hasAttribute<'T> : seq -> bool - val (|ValueType|_|) : FSharpEntity -> unit option - val (|Class|_|) : original: FSharpEntity * abbreviated: FSharpEntity * 'a -> unit option - val (|Record|_|) : FSharpEntity -> unit option - val (|UnionType|_|) : FSharpEntity -> unit option - val (|Delegate|_|) : FSharpEntity -> unit option - val (|FSharpException|_|) : FSharpEntity -> unit option - val (|Interface|_|) : FSharpEntity -> unit option - val (|AbstractClass|_|) : FSharpEntity -> unit option - val (|FSharpType|_|) : FSharpEntity -> unit option +[] +module public FSharpSymbolPatterns = + + val (|AbbreviatedType|_|): FSharpEntity -> FSharpType option + + val (|TypeWithDefinition|_|): FSharpType -> FSharpEntity option + + val (|Attribute|_|): FSharpEntity -> unit option + + val (|ValueType|_|): FSharpEntity -> unit option + + val (|Class|_|): original: FSharpEntity * abbreviated: FSharpEntity * 'a -> unit option + + val (|Record|_|): FSharpEntity -> unit option + + val (|UnionType|_|): FSharpEntity -> unit option + + val (|Delegate|_|): FSharpEntity -> unit option + + val (|FSharpException|_|): FSharpEntity -> unit option + + val (|Interface|_|): FSharpEntity -> unit option + + val (|AbstractClass|_|): FSharpEntity -> unit option + + val (|FSharpType|_|): FSharpEntity -> unit option + #if !NO_EXTENSIONTYPING - val (|ProvidedType|_|) : FSharpEntity -> unit option + val (|ProvidedType|_|): FSharpEntity -> unit option #endif - val (|ByRef|_|) : FSharpEntity -> unit option - val (|Array|_|) : FSharpEntity -> unit option - val (|FSharpModule|_|) : FSharpEntity -> unit option - val (|Namespace|_|) : FSharpEntity -> unit option + + val (|ByRef|_|): FSharpEntity -> unit option + + val (|Array|_|): FSharpEntity -> unit option + + val (|FSharpModule|_|): FSharpEntity -> unit option + + val (|Namespace|_|): FSharpEntity -> unit option + #if !NO_EXTENSIONTYPING - val (|ProvidedAndErasedType|_|) : FSharpEntity -> unit option + val (|ProvidedAndErasedType|_|): FSharpEntity -> unit option #endif - val (|Enum|_|) : FSharpEntity -> unit option - val (|Tuple|_|) : FSharpType -> unit option - val (|RefCell|_|) : FSharpType -> unit option - val (|FunctionType|_|) : FSharpType -> unit option - val (|Pattern|_|) : FSharpSymbol -> unit option - val (|Field|_|) : FSharpSymbol -> (FSharpField * FSharpType) option - val (|MutableVar|_|) : FSharpSymbol -> unit option - val (|FSharpEntity|_|) : FSharpSymbol -> (FSharpEntity * FSharpEntity * FSharpType option) option - val (|Parameter|_|) : FSharpSymbol -> unit option - val (|UnionCase|_|) : FSharpSymbol -> FSharpUnionCase option - val (|RecordField|_|) : FSharpSymbol -> FSharpField option - val (|ActivePatternCase|_|) : FSharpSymbol -> FSharpActivePatternCase option - val (|MemberFunctionOrValue|_|) : FSharpSymbol -> FSharpMemberOrFunctionOrValue option - val (|Constructor|_|) : FSharpMemberOrFunctionOrValue -> FSharpEntity option - val (|Function|_|) : excluded: bool -> FSharpMemberOrFunctionOrValue -> unit option - val (|ExtensionMember|_|) : FSharpMemberOrFunctionOrValue -> unit option - val (|Event|_|) : FSharpMemberOrFunctionOrValue -> unit option \ No newline at end of file + + val (|Enum|_|): FSharpEntity -> unit option + + val (|Tuple|_|): FSharpType -> unit option + + val (|RefCell|_|): FSharpType -> unit option + + val (|FunctionType|_|): FSharpType -> unit option + + val (|Pattern|_|): FSharpSymbol -> unit option + + val (|Field|_|): FSharpSymbol -> (FSharpField * FSharpType) option + + val (|MutableVar|_|): FSharpSymbol -> unit option + + /// Returns (originalEntity, abbreviatedEntity, abbreviatedType) + val (|FSharpEntity|_|): FSharpSymbol -> (FSharpEntity * FSharpEntity * FSharpType option) option + + val (|Parameter|_|): FSharpSymbol -> unit option + + val (|UnionCase|_|): FSharpSymbol -> FSharpUnionCase option + + val (|RecordField|_|): FSharpSymbol -> FSharpField option + + val (|ActivePatternCase|_|): FSharpSymbol -> FSharpActivePatternCase option + + val (|MemberFunctionOrValue|_|): FSharpSymbol -> FSharpMemberOrFunctionOrValue option + + val (|Constructor|_|): FSharpMemberOrFunctionOrValue -> FSharpEntity option + + val (|Function|_|): excluded: bool -> FSharpMemberOrFunctionOrValue -> unit option + + val (|ExtensionMember|_|): FSharpMemberOrFunctionOrValue -> unit option + + val (|Event|_|): FSharpMemberOrFunctionOrValue -> unit option + + val internal hasModuleSuffixAttribute: FSharpEntity -> bool + diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index 295e42b02cb..2e1817407dd 100644 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -1,24 +1,30 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace rec FSharp.Compiler.Symbols +open System open System.Collections.Generic +open Internal.Utilities.Collections +open Internal.Utilities.Library open FSharp.Compiler -open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.Infos open FSharp.Compiler.AttributeChecking open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerImports +open FSharp.Compiler.Infos open FSharp.Compiler.InfoReader -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.CompileOps -open FSharp.Compiler.Tast open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTreeOps +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Xml +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics open FSharp.Compiler.TcGlobals -open FSharp.Compiler.Lib -open FSharp.Compiler.Tastops -open Internal.Utilities +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.Syntax.PrettyNaming type FSharpAccessibility(a:Accessibility, ?isProtected) = let isProtected = defaultArg isProtected false @@ -34,34 +40,37 @@ type FSharpAccessibility(a:Accessibility, ?isProtected) = | _ when List.forall isInternalCompPath p -> Internal | _ -> Private - member __.IsPublic = not isProtected && match a with TAccess [] -> true | _ -> false + member _.IsPublic = not isProtected && match a with TAccess [] -> true | _ -> false - member __.IsPrivate = not isProtected && match a with Private -> true | _ -> false + member _.IsPrivate = not isProtected && match a with Private -> true | _ -> false - member __.IsInternal = not isProtected && match a with Internal -> true | _ -> false + member _.IsInternal = not isProtected && match a with Internal -> true | _ -> false - member __.IsProtected = isProtected + member _.IsProtected = isProtected - member internal __.Contents = a + member internal _.Contents = a - override __.ToString() = + override _.ToString() = let (TAccess paths) = a let mangledTextOfCompPath (CompPath(scoref, path)) = getNameOfScopeRef scoref + "/" + textOfPath (List.map fst path) String.concat ";" (List.map mangledTextOfCompPath paths) -type SymbolEnv(g: TcGlobals, thisCcu: CcuThunk, thisCcuTy: ModuleOrNamespaceType option, tcImports: TcImports, amapV: Import.ImportMap, infoReaderV: InfoReader) = +type SymbolEnv(g: TcGlobals, thisCcu: CcuThunk, thisCcuTyp: ModuleOrNamespaceType option, tcImports: TcImports, amap: Import.ImportMap, infoReader: InfoReader) = - new(g: TcGlobals, thisCcu: CcuThunk, thisCcuTy: ModuleOrNamespaceType option, tcImports: TcImports) = + let tcVal = CheckExpressions.LightweightTcValForUsingInBuildMethodCall g + + new(g: TcGlobals, thisCcu: CcuThunk, thisCcuTyp: ModuleOrNamespaceType option, tcImports: TcImports) = let amap = tcImports.GetImportMap() let infoReader = InfoReader(g, amap) - SymbolEnv(g, thisCcu, thisCcuTy, tcImports, amap, infoReader) + SymbolEnv(g, thisCcu, thisCcuTyp, tcImports, amap, infoReader) - member __.g = g - member __.amap = amapV - member __.thisCcu = thisCcu - member __.thisCcuTy = thisCcuTy - member __.infoReader = infoReaderV - member __.tcImports = tcImports + member _.g = g + member _.amap = amap + member _.thisCcu = thisCcu + member _.thisCcuTy = thisCcuTyp + member _.infoReader = infoReader + member _.tcImports = tcImports + member _.tcValF = tcVal [] module Impl = @@ -73,7 +82,11 @@ module Impl = let makeReadOnlyCollection (arr: seq<'T>) = System.Collections.ObjectModel.ReadOnlyCollection<_>(Seq.toArray arr) :> IList<_> - let makeXmlDoc (XmlDoc x) = makeReadOnlyCollection x + let makeXmlDoc (doc: XmlDoc) = + FSharpXmlDoc.FromXmlText doc + + let makeElaboratedXmlDoc (doc: XmlDoc) = + makeReadOnlyCollection (doc.GetElaboratedXmlLines()) let rescopeEntity optViewedCcu (entity: Entity) = match optViewedCcu with @@ -183,7 +196,7 @@ module Impl = let getXmlDocSigForEntity (cenv: SymbolEnv) (ent:EntityRef)= - match SymbolHelpers.GetXmlDocSigOfEntityRef cenv.infoReader ent.Range ent with + match GetXmlDocSigOfEntityRef cenv.infoReader ent.Range ent with | Some (_, docsig) -> docsig | _ -> "" @@ -195,9 +208,14 @@ type FSharpDisplayContext(denv: TcGlobals -> DisplayEnv) = member x.WithShortTypeNames shortNames = FSharpDisplayContext(fun g -> { denv g with shortTypeNames = shortNames }) + member x.WithPrefixGenericParameters () = + FSharpDisplayContext(fun g -> { denv g with genericParameterStyle = GenericParameterStyle.Prefix } ) + + member x.WithSuffixGenericParameters () = + FSharpDisplayContext(fun g -> { denv g with genericParameterStyle = GenericParameterStyle.Suffix } ) // delay the realization of 'item' in case it is unresolved -type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol -> CcuThunk -> AccessorDomain -> bool)) = +type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> CcuThunk -> AccessorDomain -> bool) = member x.Assembly = let ccu = defaultArg (SymbolHelpers.ccuOfItem cenv.g x.Item) cenv.thisCcu @@ -215,14 +233,18 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - member x.SignatureLocation = SymbolHelpers.rangeOfItem cenv.g (Some true) x.Item - member x.IsEffectivelySameAs(y:FSharpSymbol) = - x.Equals y || ItemsAreEffectivelyEqual cenv.g x.Item y.Item + member x.IsEffectivelySameAs(other:FSharpSymbol) = + x.Equals other || ItemsAreEffectivelyEqual cenv.g x.Item other.Item member x.GetEffectivelySameAsHash() = ItemsAreEffectivelyEqualHash cenv.g x.Item - member internal x.Item = item() + member internal _.SymbolEnv = cenv + + member internal _.Item = item() + + member _.DisplayNameCore = item().DisplayNameCore - member x.DisplayName = item().DisplayName + member _.DisplayName = item().DisplayName // This is actually overridden in all cases below. However some symbols are still just of type FSharpSymbol, // see 'FSharpSymbol.Create' further below. @@ -234,12 +256,12 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - override x.GetHashCode() = hash x.ImplementationLocation - override x.ToString() = "symbol " + (try item().DisplayName with _ -> "?") + override x.ToString() = "symbol " + (try item().DisplayNameCore with _ -> "?") // TODO: there are several cases where we may need to report more interesting // symbol information below. By default we return a vanilla symbol. - static member Create(g, thisCcu, thisCcuTye, tcImports, item): FSharpSymbol = - FSharpSymbol.Create(SymbolEnv(g, thisCcu, Some thisCcuTye, tcImports), item) + static member Create(g, thisCcu, thisCcuTyp, tcImports, item): FSharpSymbol = + FSharpSymbol.Create(SymbolEnv(g, thisCcu, Some thisCcuTyp, tcImports), item) static member Create(cenv, item): FSharpSymbol = let dflt() = FSharpSymbol(cenv, (fun () -> item), (fun _ _ _ -> true)) @@ -248,6 +270,7 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - | Item.UnionCase (uinfo, _) -> FSharpUnionCase(cenv, uinfo.UnionCaseRef) :> _ | Item.ExnCase tcref -> FSharpEntity(cenv, tcref) :>_ | Item.RecdField rfinfo -> FSharpField(cenv, RecdOrClass rfinfo.RecdFieldRef) :> _ + | Item.UnionCaseField (UnionCaseInfo (_, ucref), index) -> FSharpField (cenv, Union (ucref, index)) :> _ | Item.ILField finfo -> FSharpField(cenv, ILField finfo) :> _ @@ -292,8 +315,8 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - | Item.ActivePatternResult (apinfo, ty, n, _) -> FSharpActivePatternCase(cenv, apinfo, ty, n, None, item) :> _ - | Item.ArgName(id, ty, _) -> - FSharpParameter(cenv, ty, {Attribs=[]; Name=Some id}, Some id.idRange, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) :> _ + | Item.ArgName(id, ty, argOwner) -> + FSharpParameter(cenv, id, ty, argOwner) :> _ | Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(_, vref, _)) }) -> FSharpMemberOrFunctionOrValue(cenv, V vref, item) :> _ @@ -314,15 +337,19 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - | Item.Types _ | Item.DelegateCtor _ -> dflt() - static member GetAccessibility (symbol: FSharpSymbol) = - match symbol with - | :? FSharpEntity as x -> Some x.Accessibility - | :? FSharpField as x -> Some x.Accessibility - | :? FSharpUnionCase as x -> Some x.Accessibility - | :? FSharpMemberFunctionOrValue as x -> Some x.Accessibility - | _ -> None + abstract Accessibility: FSharpAccessibility + default _.Accessibility = FSharpAccessibility(taccessPublic) -and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = + abstract Attributes: IList + default _.Attributes = makeReadOnlyCollection [] + + member sym.HasAttribute<'T> () = + sym.Attributes |> Seq.exists (fun attr -> attr.IsAttribute<'T>()) + + member sym.TryGetAttribute<'T>() = + sym.Attributes |> Seq.tryFind (fun attr -> attr.IsAttribute<'T>()) + +type FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = inherit FSharpSymbol(cenv, (fun () -> checkEntityIsResolved entity @@ -350,22 +377,25 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | None -> false | Some ccu -> ccuEq ccu cenv.g.fslibCcu - member __.Entity = entity + member _.Entity = entity - member __.LogicalName = + member _.LogicalName = checkIsResolved() entity.LogicalName - member __.CompiledName = + member _.CompiledName = checkIsResolved() entity.CompiledName - member __.DisplayName = + member _.DisplayNameCore = checkIsResolved() - if entity.IsModuleOrNamespace then entity.DemangledModuleOrNamespaceName - else entity.DisplayName + entity.DisplayNameCore - member __.AccessPath = + member _.DisplayName = + checkIsResolved() + entity.DisplayName + + member _.AccessPath = checkIsResolved() match entity.CompilationPathOpt with | None -> "global" @@ -387,12 +417,12 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = s.FindEntityByPath cp.MangledPath | None -> None - member __.Namespace = + member _.Namespace = checkIsResolved() match entity.CompilationPathOpt with | None -> None | Some (CompPath(_, [])) -> None - | Some cp when cp.AccessPath |> List.forall (function (_, ModuleOrNamespaceKind.Namespace) -> true | _ -> false) -> + | Some cp when cp.AccessPath |> List.forall (function _, ModuleOrNamespaceKind.Namespace -> true | _ -> false) -> Some (buildAccessPath (Some cp)) | Some _ -> None @@ -427,7 +457,7 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> Some tref.FullName | CompiledTypeRepr.ILAsmOpen _ -> None - member __.DeclarationLocation = + member _.DeclarationLocation = checkIsResolved() entity.Range @@ -435,18 +465,21 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = checkIsResolved() entity.TyparsNoRange |> List.map (fun tp -> FSharpGenericParameter(cenv, tp)) |> makeReadOnlyCollection - member __.IsMeasure = + member _.IsMeasure = isResolvedAndFSharp() && (entity.TypeOrMeasureKind = TyparKind.Measure) - member __.IsFSharpModule = + member x.IsAbstractClass = + isResolved() && isAbstractTycon entity.Deref + + member _.IsFSharpModule = isResolvedAndFSharp() && entity.IsModule - member __.HasFSharpModuleSuffix = + member _.HasFSharpModuleSuffix = isResolvedAndFSharp() && entity.IsModule && (entity.ModuleOrNamespaceType.ModuleOrNamespaceKind = ModuleOrNamespaceKind.FSharpModuleWithSuffix) - member __.IsValueType = + member _.IsValueType = isResolved() && entity.IsStructOrEnumTycon @@ -454,27 +487,31 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = isResolved() && isArrayTyconRef cenv.g entity - member __.ArrayRank = + member _.ArrayRank = checkIsResolved() - rankOfArrayTyconRef cenv.g entity + if isArrayTyconRef cenv.g entity then + rankOfArrayTyconRef cenv.g entity + else + 0 + #if !NO_EXTENSIONTYPING - member __.IsProvided = + member _.IsProvided = isResolved() && entity.IsProvided - member __.IsProvidedAndErased = + member _.IsProvidedAndErased = isResolved() && entity.IsProvidedErasedTycon - member __.IsStaticInstantiation = + member _.IsStaticInstantiation = isResolved() && entity.IsStaticInstantiationTycon - member __.IsProvidedAndGenerated = + member _.IsProvidedAndGenerated = isResolved() && entity.IsProvidedGeneratedTycon #endif - member __.IsClass = + member _.IsClass = isResolved() && match metadataOfTycon entity.Deref with #if !NO_EXTENSIONTYPING @@ -483,19 +520,19 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsClass | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> entity.Deref.IsFSharpClassTycon - member __.IsByRef = + member _.IsByRef = isResolved() && isByrefTyconRef cenv.g entity - member __.IsOpaque = + member _.IsOpaque = isResolved() && entity.IsHiddenReprTycon - member __.IsInterface = + member _.IsInterface = isResolved() && isInterfaceTyconRef entity - member __.IsDelegate = + member _.IsDelegate = isResolved() && match metadataOfTycon entity.Deref with #if !NO_EXTENSIONTYPING @@ -504,46 +541,45 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsDelegate | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> entity.IsFSharpDelegateTycon - member __.IsEnum = + member _.IsEnum = isResolved() && entity.IsEnumTycon - member __.IsFSharpExceptionDeclaration = + member _.IsFSharpExceptionDeclaration = isResolvedAndFSharp() && entity.IsExceptionDecl - member __.IsUnresolved = + member _.IsUnresolved = isUnresolved() - member __.IsFSharp = + member _.IsFSharp = isResolvedAndFSharp() - member __.IsFSharpAbbreviation = + member _.IsFSharpAbbreviation = isResolvedAndFSharp() && entity.IsTypeAbbrev - member __.IsFSharpRecord = + member _.IsFSharpRecord = isResolvedAndFSharp() && entity.IsRecordTycon - member __.IsFSharpUnion = + member _.IsFSharpUnion = isResolvedAndFSharp() && entity.IsUnionTycon - member __.HasAssemblyCodeRepresentation = + member _.HasAssemblyCodeRepresentation = isResolvedAndFSharp() && (entity.IsAsmReprTycon || entity.IsMeasureableReprTycon) - member __.FSharpDelegateSignature = + member _.FSharpDelegateSignature = checkIsResolved() match entity.TypeReprInfo with | TFSharpObjectRepr r when entity.IsFSharpDelegateTycon -> match r.fsobjmodel_kind with - | TTyconDelegate ss -> FSharpDelegateSignature(cenv, ss) + | TFSharpDelegate ss -> FSharpDelegateSignature(cenv, ss) | _ -> invalidOp "not a delegate type" | _ -> invalidOp "not a delegate type" - - member __.Accessibility = + override _.Accessibility = if isUnresolved() then FSharpAccessibility taccessPublic else FSharpAccessibility(getApproxFSharpAccessibilityOfEntity entity) - member __.RepresentationAccessibility = + member _.RepresentationAccessibility = if isUnresolved() then FSharpAccessibility taccessPublic else FSharpAccessibility(entity.TypeReprAccessibility) @@ -565,29 +601,27 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = if isUnresolved() then false else let ty = generalizedTyconRef entity ErrorLogger.protectAssemblyExploration false <| fun () -> - Infos.ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap range0 ty cenv.g.tcref_System_Attribute + ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap range0 ty cenv.g.tcref_System_Attribute member x.IsDisposableType = if isUnresolved() then false else let ty = generalizedTyconRef entity ErrorLogger.protectAssemblyExploration false <| fun () -> - Infos.ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap range0 ty cenv.g.tcref_System_IDisposable + ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap range0 ty cenv.g.tcref_System_IDisposable member x.BaseType = checkIsResolved() GetSuperTypeOfType cenv.g cenv.amap range0 (generalizedTyconRef entity) |> Option.map (fun ty -> FSharpType(cenv, ty)) - member __.UsesPrefixDisplay = + member _.UsesPrefixDisplay = if isUnresolved() then true else not (isResolvedAndFSharp()) || entity.Deref.IsPrefixDisplay member x.IsNamespace = entity.IsNamespace - member x.MembersOrValues = x.MembersFunctionsAndValues - member x.MembersFunctionsAndValues = - if isUnresolved() then makeReadOnlyCollection[] else + if isUnresolved() then makeReadOnlyCollection [] else protect <| fun () -> ([ let _, entityTy = generalizeTyconRef entity let createMember (minfo: MethInfo) = @@ -619,10 +653,10 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = let vref = mkNestedValRef entity v yield FSharpMemberOrFunctionOrValue(cenv, V vref, Item.Value vref) match v.MemberInfo.Value.MemberFlags.MemberKind, v.ApparentEnclosingEntity with - | MemberKind.PropertyGet, Parent p -> + | SynMemberKind.PropertyGet, Parent p -> let pinfo = FSProp(cenv.g, generalizedTyconRef p, Some vref, None) yield FSharpMemberOrFunctionOrValue(cenv, P pinfo, Item.Property (pinfo.PropertyName, [pinfo])) - | MemberKind.PropertySet, Parent p -> + | SynMemberKind.PropertySet, Parent p -> let pinfo = FSProp(cenv.g, generalizedTyconRef p, None, Some vref) yield FSharpMemberOrFunctionOrValue(cenv, P pinfo, Item.Property (pinfo.PropertyName, [pinfo])) | _ -> () @@ -632,18 +666,22 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = yield FSharpMemberOrFunctionOrValue(cenv, V vref, Item.Value vref) ] |> makeReadOnlyCollection) - member __.XmlDocSig = + member _.XmlDocSig = checkIsResolved() getXmlDocSigForEntity cenv entity - member __.XmlDoc = + member _.XmlDoc = if isUnresolved() then XmlDoc.Empty |> makeXmlDoc else entity.XmlDoc |> makeXmlDoc + member _.ElaboratedXmlDoc = + if isUnresolved() then XmlDoc.Empty |> makeElaboratedXmlDoc else + entity.XmlDoc |> makeElaboratedXmlDoc + member x.StaticParameters = match entity.TypeReprInfo with #if !NO_EXTENSIONTYPING - | TProvidedTypeExtensionPoint info -> + | TProvidedTypeRepr info -> let m = x.DeclarationLocation let typeBeforeArguments = info.ProvidedType let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.GetStaticParameters provider), range=m) @@ -653,23 +691,21 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | _ -> [| |] |> makeReadOnlyCollection - member __.NestedEntities = - if isUnresolved() then makeReadOnlyCollection[] else + member _.NestedEntities = + if isUnresolved() then makeReadOnlyCollection [] else entity.ModuleOrNamespaceType.AllEntities |> QueueList.toList |> List.map (fun x -> FSharpEntity(cenv, entity.NestedTyconRef x)) |> makeReadOnlyCollection member x.UnionCases = - if isUnresolved() then makeReadOnlyCollection[] else + if isUnresolved() then makeReadOnlyCollection [] else entity.UnionCasesAsRefList |> List.map (fun x -> FSharpUnionCase(cenv, x)) |> makeReadOnlyCollection - member x.RecordFields = x.FSharpFields - member x.FSharpFields = - if isUnresolved() then makeReadOnlyCollection[] else + if isUnresolved() then makeReadOnlyCollection [] else if entity.IsILEnumTycon then let (TILObjectReprData(_scoref, _enc, tdef)) = entity.ILTyconInfo @@ -684,7 +720,7 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = else entity.AllFieldsAsList - |> List.map (fun x -> FSharpField(cenv, mkRecdFieldRef entity x.Name)) + |> List.map (fun x -> FSharpField(cenv, mkRecdFieldRef entity x.LogicalName)) |> makeReadOnlyCollection member x.AbbreviatedType = @@ -694,13 +730,13 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = | None -> invalidOp "not a type abbreviation" | Some ty -> FSharpType(cenv, ty) - member __.Attributes = - if isUnresolved() then makeReadOnlyCollection[] else + override _.Attributes = + if isUnresolved() then makeReadOnlyCollection [] else GetAttribInfosOfEntity cenv.g cenv.amap range0 entity |> List.map (fun a -> FSharpAttribute(cenv, a)) |> makeReadOnlyCollection - member __.AllCompilationPaths = + member _.AllCompilationPaths = checkIsResolved() let (CompPath(_, parts)) = entity.CompilationPath let partsList = @@ -722,7 +758,7 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = match kind with | ModuleOrNamespaceKind.FSharpModuleWithSuffix -> [ yield! loop (mapEachCurrentPath currentPaths name) rest - yield! loop (mapEachCurrentPath currentPaths (name.[..name.Length - 7])) rest ] + yield! loop (mapEachCurrentPath currentPaths name.[..name.Length - 7]) rest ] | _ -> loop (mapEachCurrentPath currentPaths name) rest loop [] parts |> List.map (List.rev >> String.concat ".") @@ -734,12 +770,138 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = member x.ActivePatternCases = protect <| fun () -> - ActivePatternElemsOfModuleOrNamespace x.Entity + ActivePatternElemsOfModuleOrNamespace cenv.g x.Entity |> Map.toList |> List.map (fun (_, apref) -> let item = Item.ActivePatternCase apref FSharpActivePatternCase(cenv, apref.ActivePatternInfo, apref.ActivePatternVal.Type, apref.CaseIndex, Some apref.ActivePatternVal, item)) + member x.TryGetFullName() = + try x.TryFullName + with _ -> + try Some(String.Join(".", x.AccessPath, x.DisplayName)) + with _ -> None + + member x.TryGetFullDisplayName() = + let fullName = x.TryGetFullName() |> Option.map (fun fullName -> fullName.Split '.') + let res = + match fullName with + | Some fullName -> + match Option.attempt (fun _ -> x.DisplayName) with + | Some shortDisplayName when not (shortDisplayName.Contains ".") -> + Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) + | _ -> Some fullName + | None -> None + |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) + //debug "GetFullDisplayName: FullName = %A, Result = %A" fullName res + res + + member x.TryGetFullCompiledName() = + let fullName = x.TryGetFullName() |> Option.map (fun fullName -> fullName.Split '.') + let res = + match fullName with + | Some fullName -> + match Option.attempt (fun _ -> x.CompiledName) with + | Some shortCompiledName when not (shortCompiledName.Contains ".") -> + Some (fullName |> Array.replace (fullName.Length - 1) shortCompiledName) + | _ -> Some fullName + | None -> None + |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) + //debug "GetFullCompiledName: FullName = %A, Result = %A" fullName res + res + + member x.GetPublicNestedEntities() = + x.NestedEntities |> Seq.filter (fun entity -> entity.Accessibility.IsPublic) + + member x.TryGetMembersFunctionsAndValues() = + try x.MembersFunctionsAndValues with _ -> [||] :> _ + + member this.TryGetMetadataText() = + match entity.TryDeref with + | ValueSome _ -> + if entity.IsNamespace then None + else + + let denv = DisplayEnv.InitialForSigFileGeneration cenv.g + + let extraOpenPath = + match entity.CompilationPathOpt with + | Some cpath -> + let rec getOpenPath accessPath acc = + match accessPath with + | [] -> acc + | (name, ModuleOrNamespaceKind.ModuleOrType) :: accessPath -> + getOpenPath accessPath (name :: acc) + | (name, ModuleOrNamespaceKind.Namespace) :: accessPath -> + getOpenPath accessPath (name :: acc) + | (name, ModuleOrNamespaceKind.FSharpModuleWithSuffix) :: accessPath -> + getOpenPath accessPath (name :: acc) + + getOpenPath cpath.AccessPath [] + | _ -> + [] + |> List.rev + + let needOpenType = + match entity.CompilationPathOpt with + | Some cpath -> + match cpath.AccessPath with + | (_, ModuleOrNamespaceKind.ModuleOrType) :: _ -> + match this.DeclaringEntity with + | Some (declaringEntity: FSharpEntity) -> not declaringEntity.IsFSharpModule + | _ -> false + | _ -> false + | _ -> + false + + let denv = denv.AddOpenPath extraOpenPath + + let infoReader = cenv.infoReader + + let openPathL = + extraOpenPath + |> List.map (fun x -> Layout.wordL (TaggedText.tagUnknownEntity x)) + + let pathL = + if List.isEmpty extraOpenPath then + Layout.emptyL + else + Layout.sepListL (Layout.sepL TaggedText.dot) openPathL + + let headerL = + if List.isEmpty extraOpenPath then + Layout.emptyL + else + Layout.(^^) + (Layout.wordL (TaggedText.tagKeyword "namespace")) + pathL + + let openL = + if List.isEmpty openPathL then Layout.emptyL + else + let openKeywordL = + if needOpenType then + Layout.(^^) + (Layout.wordL (TaggedText.tagKeyword "open")) + (Layout.wordL TaggedText.keywordType) + else + Layout.wordL (TaggedText.tagKeyword "open") + Layout.(^^) + openKeywordL + pathL + + Layout.aboveListL + [ + (Layout.(^^) headerL (Layout.sepL TaggedText.lineBreak)) + (Layout.(^^) openL (Layout.sepL TaggedText.lineBreak)) + (NicePrint.layoutEntityDefn denv infoReader AccessibleFromSomewhere range0 entity) + ] + |> LayoutRender.showL + |> SourceText.ofString + |> Some + | _ -> + None + override x.Equals(other: obj) = box x === other || match other with @@ -752,7 +914,7 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = override x.ToString() = x.CompiledName -and FSharpUnionCase(cenv, v: UnionCaseRef) = +type FSharpUnionCase(cenv, v: UnionCaseRef) = inherit FSharpSymbol (cenv, (fun () -> checkEntityIsResolved v.TyconRef @@ -771,49 +933,53 @@ and FSharpUnionCase(cenv, v: UnionCaseRef) = if v.TryUnionCase.IsNone then invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) - member __.IsUnresolved = + member _.IsUnresolved = isUnresolved() - member __.Name = + member _.Name = checkIsResolved() - v.UnionCase.DisplayName + v.UnionCase.LogicalName - member __.DeclarationLocation = + member _.DeclarationLocation = checkIsResolved() v.Range - member __.HasFields = + member _.HasFields = if isUnresolved() then false else v.UnionCase.RecdFieldsArray.Length <> 0 - member __.UnionCaseFields = + member _.Fields = if isUnresolved() then makeReadOnlyCollection [] else v.UnionCase.RecdFieldsArray |> Array.mapi (fun i _ -> FSharpField(cenv, FSharpFieldData.Union (v, i))) |> makeReadOnlyCollection - member __.ReturnType = + member _.ReturnType = checkIsResolved() FSharpType(cenv, v.ReturnType) - member __.CompiledName = + member _.CompiledName = checkIsResolved() v.UnionCase.CompiledName - member __.XmlDocSig = + member _.XmlDocSig = checkIsResolved() let unionCase = UnionCaseInfo(generalizeTypars v.TyconRef.TyparsNoRange, v) - match SymbolHelpers.GetXmlDocSigOfUnionCaseInfo unionCase with + match GetXmlDocSigOfUnionCaseRef unionCase.UnionCaseRef with | Some (_, docsig) -> docsig | _ -> "" - member __.XmlDoc = + member _.XmlDoc = if isUnresolved() then XmlDoc.Empty |> makeXmlDoc else v.UnionCase.XmlDoc |> makeXmlDoc - member __.Attributes = + member _.ElaboratedXmlDoc = + if isUnresolved() then XmlDoc.Empty |> makeElaboratedXmlDoc else + v.UnionCase.XmlDoc |> makeElaboratedXmlDoc + + override _.Attributes = if isUnresolved() then makeReadOnlyCollection [] else v.Attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection - member __.Accessibility = + override _.Accessibility = if isUnresolved() then FSharpAccessibility taccessPublic else FSharpAccessibility(v.UnionCase.Accessibility) @@ -828,7 +994,7 @@ and FSharpUnionCase(cenv, v: UnionCaseRef) = override x.ToString() = x.CompiledName -and FSharpFieldData = +type FSharpFieldData = | AnonField of AnonRecdTypeInfo * TTypes * int * range | ILField of ILFieldInfo | RecdOrClass of RecdFieldRef @@ -843,24 +1009,23 @@ and FSharpFieldData = member x.TryDeclaringTyconRef = match x with - | AnonField _ -> None | RecdOrClass v -> Some v.TyconRef - | Union (v, _) -> Some v.TyconRef | ILField f -> Some f.DeclaringTyconRef + | _ -> None -and FSharpAnonRecordTypeDetails(cenv: SymbolEnv, anonInfo: AnonRecdTypeInfo) = - member __.Assembly = FSharpAssembly (cenv, anonInfo.Assembly) +type FSharpAnonRecordTypeDetails(cenv: SymbolEnv, anonInfo: AnonRecdTypeInfo) = + member _.Assembly = FSharpAssembly (cenv, anonInfo.Assembly) /// Names of any enclosing types of the compiled form of the anonymous type (if the anonymous type was defined as a nested type) - member __.EnclosingCompiledTypeNames = anonInfo.ILTypeRef.Enclosing + member _.EnclosingCompiledTypeNames = anonInfo.ILTypeRef.Enclosing /// The name of the compiled form of the anonymous type - member __.CompiledName = anonInfo.ILTypeRef.Name + member _.CompiledName = anonInfo.ILTypeRef.Name /// The sorted labels of the anonymous type - member __.SortedFieldNames = anonInfo.SortedNames + member _.SortedFieldNames = anonInfo.SortedNames -and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = +type FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = inherit FSharpSymbol (cenv, (fun () -> match d with @@ -869,9 +1034,9 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = | RecdOrClass v -> checkEntityIsResolved v.TyconRef Item.RecdField(RecdFieldInfo(generalizeTypars v.TyconRef.TyparsNoRange, v)) - | Union (v, _) -> - // This is not correct: there is no "Item" for a named union case field - Item.UnionCase(UnionCaseInfo(generalizeTypars v.TyconRef.TyparsNoRange, v), false) + | Union (v, fieldIndex) -> + checkEntityIsResolved v.TyconRef + Item.UnionCaseField (UnionCaseInfo (generalizeTypars v.TyconRef.TyparsNoRange, v), fieldIndex) | ILField f -> Item.ILField f), (fun this thisCcu2 ad -> @@ -902,79 +1067,89 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) | ILField _ -> () - new (cenv, ucref, n) = FSharpField(cenv, FSharpFieldData.Union(ucref, n)) + new (cenv, ucref: UnionCaseRef, n) = FSharpField(cenv, FSharpFieldData.Union(ucref, n)) - new (cenv, rfref) = FSharpField(cenv, FSharpFieldData.RecdOrClass rfref) + new (cenv, rfref: RecdFieldRef) = FSharpField(cenv, FSharpFieldData.RecdOrClass rfref) - member __.DeclaringEntity = + member _.DeclaringEntity = d.TryDeclaringTyconRef |> Option.map (fun tcref -> FSharpEntity(cenv, tcref)) - member __.IsUnresolved = + member _.IsUnresolved = isUnresolved() - member __.IsMutable = + member _.IsMutable = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.IsMutable | Choice2Of3 f -> not f.IsInitOnly && f.LiteralValue.IsNone | Choice3Of3 _ -> false - member __.IsLiteral = + member _.IsLiteral = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.LiteralValue.IsSome | Choice2Of3 f -> f.LiteralValue.IsSome | Choice3Of3 _ -> false - member __.LiteralValue = + member _.LiteralValue = if isUnresolved() then None else match d.TryRecdField with | Choice1Of3 r -> getLiteralValue r.LiteralValue - | Choice2Of3 f -> f.LiteralValue |> Option.map AbstractIL.ILRuntimeWriter.convFieldInit + | Choice2Of3 f -> f.LiteralValue |> Option.map (fun v -> v.AsObject()) | Choice3Of3 _ -> None - member __.IsVolatile = + member _.IsVolatile = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.IsVolatile | Choice2Of3 _ -> false // F# doesn't actually respect "volatile" from other assemblies in any case | Choice3Of3 _ -> false - member __.IsDefaultValue = + member _.IsDefaultValue = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.IsZeroInit | Choice2Of3 _ -> false | Choice3Of3 _ -> false - member __.IsAnonRecordField = + member _.IsAnonRecordField = match d with | AnonField _ -> true | _ -> false - member __.AnonRecordFieldDetails = + member _.AnonRecordFieldDetails = match d with | AnonField (anonInfo, types, n, _) -> FSharpAnonRecordTypeDetails(cenv, anonInfo), [| for ty in types -> FSharpType(cenv, ty) |], n | _ -> invalidOp "not an anonymous record field" - member __.XmlDocSig = + member _.IsUnionCaseField = + match d with + | Union _ -> true + | _ -> false + + member _.DeclaringUnionCase = + match d with + | Union (v, _) -> Some (FSharpUnionCase (cenv, v)) + | _ -> None + + member _.XmlDocSig = checkIsResolved() let xmlsig = match d with | RecdOrClass v -> let recd = RecdFieldInfo(generalizeTypars v.TyconRef.TyparsNoRange, v) - SymbolHelpers.GetXmlDocSigOfRecdFieldInfo recd + GetXmlDocSigOfRecdFieldRef recd.RecdFieldRef | Union (v, _) -> let unionCase = UnionCaseInfo(generalizeTypars v.TyconRef.TyparsNoRange, v) - SymbolHelpers.GetXmlDocSigOfUnionCaseInfo unionCase + GetXmlDocSigOfUnionCaseRef unionCase.UnionCaseRef | ILField f -> - SymbolHelpers.GetXmlDocSigOfILFieldInfo cenv.infoReader range0 f + GetXmlDocSigOfILFieldInfo cenv.infoReader range0 f | AnonField _ -> None match xmlsig with | Some (_, docsig) -> docsig | _ -> "" - member __.XmlDoc = + member _.XmlDoc = if isUnresolved() then XmlDoc.Empty |> makeXmlDoc else match d.TryRecdField with | Choice1Of3 r -> r.XmlDoc @@ -982,7 +1157,15 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = | Choice3Of3 _ -> XmlDoc.Empty |> makeXmlDoc - member __.FieldType = + member _.ElaboratedXmlDoc = + if isUnresolved() then XmlDoc.Empty |> makeElaboratedXmlDoc else + match d.TryRecdField with + | Choice1Of3 r -> r.XmlDoc + | Choice2Of3 _ -> XmlDoc.Empty + | Choice3Of3 _ -> XmlDoc.Empty + |> makeElaboratedXmlDoc + + member _.FieldType = checkIsResolved() let fty = match d.TryRecdField with @@ -991,41 +1174,41 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = | Choice3Of3 (_,tinst,n,_) -> tinst.[n] FSharpType(cenv, fty) - member __.IsStatic = + member _.IsStatic = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.IsStatic | Choice2Of3 f -> f.IsStatic | Choice3Of3 _ -> false - member __.Name = + member _.Name = checkIsResolved() match d.TryRecdField with - | Choice1Of3 r -> r.Name + | Choice1Of3 r -> r.LogicalName | Choice2Of3 f -> f.FieldName | Choice3Of3 (anonInfo, _tinst, n, _) -> anonInfo.SortedNames.[n] - member __.IsCompilerGenerated = + member _.IsCompilerGenerated = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.IsCompilerGenerated | Choice2Of3 _ -> false | Choice3Of3 _ -> false - member __.IsNameGenerated = + member _.IsNameGenerated = if isUnresolved() then false else match d.TryRecdField with | Choice1Of3 r -> r.rfield_name_generated | _ -> false - member __.DeclarationLocation = + member _.DeclarationLocation = checkIsResolved() match d.TryRecdField with | Choice1Of3 r -> r.Range | Choice2Of3 _ -> range0 | Choice3Of3 (_anonInfo, _tinst, _n, m) -> m - member __.FieldAttributes = + member _.FieldAttributes = if isUnresolved() then makeReadOnlyCollection [] else match d.TryRecdField with | Choice1Of3 r -> r.FieldAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) @@ -1033,7 +1216,7 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = | Choice3Of3 _ -> [] |> makeReadOnlyCollection - member __.PropertyAttributes = + member _.PropertyAttributes = if isUnresolved() then makeReadOnlyCollection [] else match d.TryRecdField with | Choice1Of3 r -> r.PropertyAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) @@ -1041,7 +1224,7 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = | Choice3Of3 _ -> [] |> makeReadOnlyCollection - member __.Accessibility: FSharpAccessibility = + override _.Accessibility: FSharpAccessibility = if isUnresolved() then FSharpAccessibility taccessPublic else let access = match d.TryRecdField with @@ -1067,80 +1250,87 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = override x.ToString() = "field " + x.Name -and [] FSharpRecordField = FSharpField +type [] FSharpAccessibilityRights(thisCcu: CcuThunk, ad:AccessorDomain) = + member internal _.ThisCcu = thisCcu -and [] FSharpAccessibilityRights(thisCcu: CcuThunk, ad:AccessorDomain) = - member internal __.ThisCcu = thisCcu + member internal _.Contents = ad - member internal __.Contents = ad - -and FSharpActivePatternCase(cenv, apinfo: PrettyNaming.ActivePatternInfo, ty, n, valOpt: ValRef option, item) = +type FSharpActivePatternCase(cenv, apinfo: ActivePatternInfo, ty, n, valOpt: ValRef option, item) = inherit FSharpSymbol (cenv, (fun () -> item), (fun _ _ _ -> true)) - member __.Name = apinfo.ActiveTags.[n] + member _.Name = apinfo.ActiveTags.[n] - member __.Index = n + member _.Index = n - member __.DeclarationLocation = snd apinfo.ActiveTagsWithRanges.[n] + member _.DeclarationLocation = snd apinfo.ActiveTagsWithRanges.[n] - member __.Group = FSharpActivePatternGroup(cenv, apinfo, ty, valOpt) + member _.Group = FSharpActivePatternGroup(cenv, apinfo, ty, valOpt) - member __.XmlDoc = + member _.XmlDoc = defaultArg (valOpt |> Option.map (fun vref -> vref.XmlDoc)) XmlDoc.Empty |> makeXmlDoc - member __.XmlDocSig = + member _.ElaboratedXmlDoc = + defaultArg (valOpt |> Option.map (fun vref -> vref.XmlDoc)) XmlDoc.Empty + |> makeElaboratedXmlDoc + + member _.XmlDocSig = let xmlsig = match valOpt with - | Some valref -> SymbolHelpers.GetXmlDocSigOfValRef cenv.g valref + | Some valref -> GetXmlDocSigOfValRef cenv.g valref | None -> None match xmlsig with | Some (_, docsig) -> docsig | _ -> "" -and FSharpActivePatternGroup(cenv, apinfo:PrettyNaming.ActivePatternInfo, ty, valOpt) = +type FSharpActivePatternGroup(cenv, apinfo:ActivePatternInfo, ty, valOpt) = - member __.Name = valOpt |> Option.map (fun vref -> vref.LogicalName) + member _.Name = valOpt |> Option.map (fun vref -> vref.LogicalName) - member __.Names = makeReadOnlyCollection apinfo.Names + member _.Names = makeReadOnlyCollection apinfo.Names - member __.IsTotal = apinfo.IsTotal + member _.IsTotal = apinfo.IsTotal - member __.OverallType = FSharpType(cenv, ty) + member _.OverallType = FSharpType(cenv, ty) - member __.DeclaringEntity = + member _.DeclaringEntity = valOpt |> Option.bind (fun vref -> match vref.DeclaringEntity with | ParentNone -> None | Parent p -> Some (FSharpEntity(cenv, p))) -and FSharpGenericParameter(cenv, v:Typar) = +type FSharpGenericParameter(cenv, v:Typar) = inherit FSharpSymbol (cenv, (fun () -> Item.TypeVar(v.Name, v)), (fun _ _ _ad -> true)) - member __.Name = v.DisplayName + member _.Range = v.Range + + member _.Name = v.DisplayName - member __.DeclarationLocation = v.Range + member _.DeclarationLocation = v.Range - member __.IsCompilerGenerated = v.IsCompilerGenerated + member _.IsCompilerGenerated = v.IsCompilerGenerated - member __.IsMeasure = (v.Kind = TyparKind.Measure) - member __.XmlDoc = v.XmlDoc |> makeXmlDoc + member _.IsMeasure = (v.Kind = TyparKind.Measure) - member __.IsSolveAtCompileTime = (v.StaticReq = TyparStaticReq.HeadTypeStaticReq) + member _.XmlDoc = v.XmlDoc |> makeXmlDoc - member __.Attributes = + member _.ElaboratedXmlDoc = v.XmlDoc |> makeElaboratedXmlDoc + + member _.IsSolveAtCompileTime = (v.StaticReq = TyparStaticReq.HeadType) + + override _.Attributes = // INCOMPLETENESS: If the type parameter comes from .NET then the .NET metadata for the type parameter // has been lost (it is not accessible via Typar). So we can't easily report the attributes in this // case. v.Attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection - member __.Constraints = v.Constraints |> List.map (fun a -> FSharpGenericParameterConstraint(cenv, a)) |> makeReadOnlyCollection + member _.Constraints = v.Constraints |> List.map (fun a -> FSharpGenericParameterConstraint(cenv, a)) |> makeReadOnlyCollection member internal x.V = v @@ -1154,80 +1344,80 @@ and FSharpGenericParameter(cenv, v:Typar) = override x.ToString() = "generic parameter " + x.Name -and FSharpDelegateSignature(cenv, info: SlotSig) = +type FSharpDelegateSignature(cenv, info: SlotSig) = - member __.DelegateArguments = + member _.DelegateArguments = info.FormalParams.Head |> List.map (fun (TSlotParam(nm, ty, _, _, _, _)) -> nm, FSharpType(cenv, ty)) |> makeReadOnlyCollection - member __.DelegateReturnType = + member _.DelegateReturnType = match info.FormalReturnType with | None -> FSharpType(cenv, cenv.g.unit_ty) | Some ty -> FSharpType(cenv, ty) override x.ToString() = "" -and FSharpAbstractParameter(cenv, info: SlotParam) = +type FSharpAbstractParameter(cenv, info: SlotParam) = - member __.Name = + member _.Name = let (TSlotParam(name, _, _, _, _, _)) = info name - member __.Type = FSharpType(cenv, info.Type) + member _.Type = FSharpType(cenv, info.Type) - member __.IsInArg = + member _.IsInArg = let (TSlotParam(_, _, isIn, _, _, _)) = info isIn - member __.IsOutArg = + member _.IsOutArg = let (TSlotParam(_, _, _, isOut, _, _)) = info isOut - member __.IsOptionalArg = + member _.IsOptionalArg = let (TSlotParam(_, _, _, _, isOptional, _)) = info isOptional - member __.Attributes = + member _.Attributes = let (TSlotParam(_, _, _, _, _, attribs)) = info attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection -and FSharpAbstractSignature(cenv, info: SlotSig) = +type FSharpAbstractSignature(cenv, info: SlotSig) = - member __.AbstractArguments = + member _.AbstractArguments = info.FormalParams |> List.map (List.map (fun p -> FSharpAbstractParameter(cenv, p)) >> makeReadOnlyCollection) |> makeReadOnlyCollection - member __.AbstractReturnType = + member _.AbstractReturnType = match info.FormalReturnType with | None -> FSharpType(cenv, cenv.g.unit_ty) | Some ty -> FSharpType(cenv, ty) - member __.DeclaringTypeGenericParameters = + member _.DeclaringTypeGenericParameters = info.ClassTypars |> List.map (fun t -> FSharpGenericParameter(cenv, t)) |> makeReadOnlyCollection - member __.MethodGenericParameters = + member _.MethodGenericParameters = info.MethodTypars |> List.map (fun t -> FSharpGenericParameter(cenv, t)) |> makeReadOnlyCollection - member __.Name = info.Name + member _.Name = info.Name - member __.DeclaringType = FSharpType(cenv, info.ImplementedType) + member _.DeclaringType = FSharpType(cenv, info.ImplementedType) -and FSharpGenericParameterMemberConstraint(cenv, info: TraitConstraintInfo) = +type FSharpGenericParameterMemberConstraint(cenv, info: TraitConstraintInfo) = let (TTrait(tys, nm, flags, atys, rty, _)) = info - member __.MemberSources = + member _.MemberSources = tys |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection - member __.MemberName = nm + member _.MemberName = nm - member __.MemberIsStatic = not flags.IsInstance + member _.MemberIsStatic = not flags.IsInstance - member __.MemberArgumentTypes = atys |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection + member _.MemberArgumentTypes = atys |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection member x.MemberReturnType = match rty with @@ -1236,132 +1426,131 @@ and FSharpGenericParameterMemberConstraint(cenv, info: TraitConstraintInfo) = override x.ToString() = "" -and FSharpGenericParameterDelegateConstraint(cenv, tupledArgTy: TType, rty: TType) = - member __.DelegateTupledArgumentType = FSharpType(cenv, tupledArgTy) - member __.DelegateReturnType = FSharpType(cenv, rty) +type FSharpGenericParameterDelegateConstraint(cenv, tupledArgTy: TType, rty: TType) = + member _.DelegateTupledArgumentType = FSharpType(cenv, tupledArgTy) + member _.DelegateReturnType = FSharpType(cenv, rty) override x.ToString() = "" -and FSharpGenericParameterDefaultsToConstraint(cenv, pri:int, ty:TType) = - member __.DefaultsToPriority = pri - member __.DefaultsToTarget = FSharpType(cenv, ty) +type FSharpGenericParameterDefaultsToConstraint(cenv, pri:int, ty:TType) = + member _.DefaultsToPriority = pri + member _.DefaultsToTarget = FSharpType(cenv, ty) override x.ToString() = "" -and FSharpGenericParameterConstraint(cenv, cx: TyparConstraint) = +type FSharpGenericParameterConstraint(cenv, cx: TyparConstraint) = - member __.IsCoercesToConstraint = + member _.IsCoercesToConstraint = match cx with | TyparConstraint.CoercesTo _ -> true | _ -> false - member __.CoercesToTarget = + member _.CoercesToTarget = match cx with | TyparConstraint.CoercesTo(ty, _) -> FSharpType(cenv, ty) | _ -> invalidOp "not a coerces-to constraint" - member __.IsDefaultsToConstraint = + member _.IsDefaultsToConstraint = match cx with | TyparConstraint.DefaultsTo _ -> true | _ -> false - member __.DefaultsToConstraintData = + member _.DefaultsToConstraintData = match cx with | TyparConstraint.DefaultsTo(pri, ty, _) -> FSharpGenericParameterDefaultsToConstraint(cenv, pri, ty) | _ -> invalidOp "not a 'defaults-to' constraint" - member __.IsSupportsNullConstraint = match cx with TyparConstraint.SupportsNull _ -> true | _ -> false + member _.IsSupportsNullConstraint = match cx with TyparConstraint.SupportsNull _ -> true | _ -> false - member __.IsMemberConstraint = + member _.IsMemberConstraint = match cx with | TyparConstraint.MayResolveMember _ -> true | _ -> false - member __.MemberConstraintData = + member _.MemberConstraintData = match cx with | TyparConstraint.MayResolveMember(info, _) -> FSharpGenericParameterMemberConstraint(cenv, info) | _ -> invalidOp "not a member constraint" - member __.IsNonNullableValueTypeConstraint = + member _.IsNonNullableValueTypeConstraint = match cx with | TyparConstraint.IsNonNullableStruct _ -> true | _ -> false - member __.IsReferenceTypeConstraint = + member _.IsReferenceTypeConstraint = match cx with | TyparConstraint.IsReferenceType _ -> true | _ -> false - member __.IsSimpleChoiceConstraint = + member _.IsSimpleChoiceConstraint = match cx with | TyparConstraint.SimpleChoice _ -> true | _ -> false - member __.SimpleChoices = + member _.SimpleChoices = match cx with | TyparConstraint.SimpleChoice (tys, _) -> tys |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection | _ -> invalidOp "incorrect constraint kind" - member __.IsRequiresDefaultConstructorConstraint = + member _.IsRequiresDefaultConstructorConstraint = match cx with | TyparConstraint.RequiresDefaultConstructor _ -> true | _ -> false - member __.IsEnumConstraint = + member _.IsEnumConstraint = match cx with | TyparConstraint.IsEnum _ -> true | _ -> false - member __.EnumConstraintTarget = + member _.EnumConstraintTarget = match cx with | TyparConstraint.IsEnum(ty, _) -> FSharpType(cenv, ty) | _ -> invalidOp "incorrect constraint kind" - member __.IsComparisonConstraint = + member _.IsComparisonConstraint = match cx with | TyparConstraint.SupportsComparison _ -> true | _ -> false - member __.IsEqualityConstraint = + member _.IsEqualityConstraint = match cx with | TyparConstraint.SupportsEquality _ -> true | _ -> false - member __.IsUnmanagedConstraint = + member _.IsUnmanagedConstraint = match cx with | TyparConstraint.IsUnmanaged _ -> true | _ -> false - member __.IsDelegateConstraint = + member _.IsDelegateConstraint = match cx with | TyparConstraint.IsDelegate _ -> true | _ -> false - member __.DelegateConstraintData = + member _.DelegateConstraintData = match cx with | TyparConstraint.IsDelegate(ty1, ty2, _) -> FSharpGenericParameterDelegateConstraint(cenv, ty1, ty2) | _ -> invalidOp "not a delegate constraint" override x.ToString() = "" -and FSharpInlineAnnotation = - | PseudoValue +type FSharpInlineAnnotation = | AlwaysInline | OptionalInline | NeverInline | AggressiveInline -and FSharpMemberOrValData = +type FSharpMemberOrValData = | E of EventInfo | P of PropInfo | M of MethInfo | C of MethInfo | V of ValRef -and FSharpMemberOrVal = FSharpMemberOrFunctionOrValue +type FSharpMemberOrVal = FSharpMemberOrFunctionOrValue -and FSharpMemberFunctionOrValue = FSharpMemberOrFunctionOrValue +type FSharpMemberFunctionOrValue = FSharpMemberOrFunctionOrValue -and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = +type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = inherit FSharpSymbol(cenv, (fun () -> item), @@ -1409,16 +1598,16 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = else FSharpMemberFunctionOrValue(cenv, M minfo, Item.MethodGroup(minfo.LogicalName, [minfo], None)) - member __.IsUnresolved = + member _.IsUnresolved = isUnresolved() - member __.DeclarationLocationOpt = + member _.DeclarationLocationOpt = checkIsResolved() match fsharpInfo() with | Some v -> Some v.Range | None -> base.DeclarationLocation - member x.Overloads matchParameterNumber = + member x.GetOverloads matchParameterNumber = checkIsResolved() match d with | M m | C m -> @@ -1448,7 +1637,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | Some v -> v | None -> failwith "DeclarationLocation property not available" - member __.DeclaringEntity = + member _.DeclaringEntity = checkIsResolved() match d with | E e -> FSharpEntity(cenv, e.DeclaringTyconRef) |> Some @@ -1459,7 +1648,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | ParentNone -> None | Parent p -> FSharpEntity(cenv, p) |> Some - member __.ApparentEnclosingEntity = + member _.ApparentEnclosingEntity = checkIsResolved() match d with | E e -> FSharpEntity(cenv, e.ApparentEnclosingTyconRef) @@ -1493,7 +1682,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | V v -> v.TauType FSharpType(cenv, ty) - member __.HasGetterMethod = + member _.HasGetterMethod = if isUnresolved() then false else match d with @@ -1503,13 +1692,13 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | C _ | V _ -> false - member __.GetterMethod = + member _.GetterMethod = checkIsResolved() match d with | P p -> mkMethSym p.GetterMethod | E _ | M _ | C _ | V _ -> invalidOp "the value or member doesn't have an associated getter method" - member __.HasSetterMethod = + member _.HasSetterMethod = if isUnresolved() then false else match d with @@ -1519,31 +1708,31 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | C _ | V _ -> false - member __.SetterMethod = + member _.SetterMethod = checkIsResolved() match d with | P p -> mkMethSym p.SetterMethod | E _ | M _ | C _ | V _ -> invalidOp "the value or member doesn't have an associated setter method" - member __.EventAddMethod = + member _.EventAddMethod = checkIsResolved() match d with | E e -> mkMethSym e.AddMethod | P _ | M _ | C _ | V _ -> invalidOp "the value or member doesn't have an associated add method" - member __.EventRemoveMethod = + member _.EventRemoveMethod = checkIsResolved() match d with | E e -> mkMethSym e.RemoveMethod | P _ | M _ | C _ | V _ -> invalidOp "the value or member doesn't have an associated remove method" - member __.EventDelegateType = + member _.EventDelegateType = checkIsResolved() match d with | E e -> FSharpType(cenv, e.GetDelegateType(cenv.amap, range0)) | P _ | M _ | C _ | V _ -> invalidOp "the value or member doesn't have an associated event delegate type" - member __.EventIsStandard = + member _.EventIsStandard = checkIsResolved() match d with | E e -> @@ -1551,43 +1740,42 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = TryDestStandardDelegateType cenv.infoReader range0 AccessibleFromSomewhere dty |> Option.isSome | P _ | M _ | C _ | V _ -> invalidOp "the value or member is not an event" - member __.IsCompilerGenerated = + member _.IsCompilerGenerated = if isUnresolved() then false else match fsharpInfo() with | None -> false | Some v -> v.IsCompilerGenerated - member __.InlineAnnotation = + member _.InlineAnnotation = if isUnresolved() then FSharpInlineAnnotation.OptionalInline else match fsharpInfo() with | None -> FSharpInlineAnnotation.OptionalInline | Some v -> match v.InlineInfo with - | ValInline.PseudoVal -> FSharpInlineAnnotation.PseudoValue | ValInline.Always -> FSharpInlineAnnotation.AlwaysInline | ValInline.Optional -> FSharpInlineAnnotation.OptionalInline | ValInline.Never -> FSharpInlineAnnotation.NeverInline - member __.IsMutable = + member _.IsMutable = if isUnresolved() then false else match d with | M _ | C _ | P _ | E _ -> false | V v -> v.IsMutable - member __.IsModuleValueOrMember = + member _.IsModuleValueOrMember = if isUnresolved() then false else match d with | M _ | C _ | P _ | E _ -> true | V v -> v.IsMember || v.IsModuleBinding - member __.IsMember = + member _.IsMember = if isUnresolved() then false else match d with | M _ | C _ | P _ | E _ -> true | V v -> v.IsMember - member __.IsDispatchSlot = + member _.IsDispatchSlot = if isUnresolved() then false else match d with | E e -> e.AddMethod.IsDispatchSlot @@ -1618,11 +1806,14 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | _ -> None | _ -> None - member __.IsEventAddMethod = + member _.IsEventAddMethod = if isUnresolved() then false else match d with - | M m when m.LogicalName.StartsWithOrdinal("add_") -> - let eventName = m.LogicalName.[4..] + | M m -> + let logicalName = m.LogicalName + logicalName.Length > 4 && logicalName.StartsWithOrdinal("add_") && + + let eventName = logicalName.[4..] let entityTy = generalizedTyconRef m.DeclaringTyconRef not (isNil (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy))) || let declaringTy = generalizedTyconRef m.DeclaringTyconRef @@ -1632,11 +1823,14 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | _ -> false - member __.IsEventRemoveMethod = + member _.IsEventRemoveMethod = if isUnresolved() then false else match d with - | M m when m.LogicalName.StartsWithOrdinal("remove_") -> - let eventName = m.LogicalName.[7..] + | M m -> + let logicalName = m.LogicalName + logicalName.Length > 4 && logicalName.StartsWithOrdinal("remove_") && + + let eventName = logicalName.[7..] let entityTy = generalizedTyconRef m.DeclaringTyconRef not (isNil (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy))) || let declaringTy = generalizedTyconRef m.DeclaringTyconRef @@ -1645,42 +1839,33 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | _ -> false | _ -> false - member x.IsGetterMethod = - if isUnresolved() then false else - x.IsPropertyGetterMethod || - match fsharpInfo() with - | None -> false - | Some v -> v.IsPropertyGetterMethod - - member x.IsSetterMethod = - if isUnresolved() then false else - x.IsPropertySetterMethod || - match fsharpInfo() with - | None -> false - | Some v -> v.IsPropertySetterMethod - - member __.IsPropertyGetterMethod = + member _.IsPropertyGetterMethod = if isUnresolved() then false else match d with - | M m when m.LogicalName.StartsWithOrdinal("get_") -> - let propName = PrettyNaming.ChopPropertyName(m.LogicalName) + | M m -> + let logicalName = m.LogicalName + logicalName.Length > 4 && logicalName.StartsWithOrdinal("get_") && + + let propName = ChopPropertyName(logicalName) let declaringTy = generalizedTyconRef m.DeclaringTyconRef not (isNil (GetImmediateIntrinsicPropInfosOfType (Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 declaringTy)) | V v -> v.IsPropertyGetterMethod | _ -> false - member __.IsPropertySetterMethod = + member _.IsPropertySetterMethod = if isUnresolved() then false else match d with - // Look for a matching property with the right name. - | M m when m.LogicalName.StartsWithOrdinal("set_") -> - let propName = PrettyNaming.ChopPropertyName(m.LogicalName) + | M m -> + let logicalName = m.LogicalName + logicalName.Length > 4 && logicalName.StartsWithOrdinal("set_") && + + let propName = ChopPropertyName(logicalName) let declaringTy = generalizedTyconRef m.DeclaringTyconRef not (isNil (GetImmediateIntrinsicPropInfosOfType (Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 declaringTy)) | V v -> v.IsPropertySetterMethod | _ -> false - member __.IsInstanceMember = + member _.IsInstanceMember = if isUnresolved() then false else match d with | E e -> not e.IsStatic @@ -1697,7 +1882,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m | C m -> match m.ArbitraryValRef with Some vref -> ValRefIsCompiledAsInstanceMember cenv.g vref | None -> true | V vref -> ValRefIsCompiledAsInstanceMember cenv.g vref - member __.IsExtensionMember = + member _.IsExtensionMember = if isUnresolved() then false else match d with | E e -> e.AddMethod.IsExtensionMember @@ -1706,9 +1891,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | V v -> v.IsExtensionMember | C _ -> false - member x.IsOverrideOrExplicitMember = x.IsOverrideOrExplicitInterfaceImplementation - - member __.IsOverrideOrExplicitInterfaceImplementation = + member _.IsOverrideOrExplicitInterfaceImplementation = if isUnresolved() then false else match d with | E e -> e.AddMethod.IsDefiniteFSharpOverride @@ -1718,7 +1901,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = v.MemberInfo.IsSome && v.IsDefiniteFSharpOverrideMember | C _ -> false - member __.IsExplicitInterfaceImplementation = + member _.IsExplicitInterfaceImplementation = if isUnresolved() then false else match d with | E e -> e.AddMethod.IsFSharpExplicitInterfaceImplementation @@ -1727,7 +1910,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | V v -> v.IsFSharpExplicitInterfaceImplementation cenv.g | C _ -> false - member __.ImplementedAbstractSignatures = + member _.ImplementedAbstractSignatures = checkIsResolved() let sigs = match d with @@ -1738,22 +1921,22 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = sigs |> List.map (fun s -> FSharpAbstractSignature (cenv, s)) |> makeReadOnlyCollection - member __.IsImplicitConstructor = + member _.IsImplicitConstructor = if isUnresolved() then false else match fsharpInfo() with | None -> false | Some v -> v.IsIncrClassConstructor - member __.IsTypeFunction = + member _.IsTypeFunction = if isUnresolved() then false else match fsharpInfo() with | None -> false | Some v -> v.IsTypeFunction - member __.IsActivePattern = + member _.IsActivePattern = if isUnresolved() then false else match fsharpInfo() with - | Some v -> PrettyNaming.ActivePatternInfoOfValName v.CoreDisplayName v.Range |> Option.isSome + | Some v -> ActivePatternInfoOfValName v.DisplayNameCoreMangled v.Range |> Option.isSome | None -> false member x.CompiledName = @@ -1762,7 +1945,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | Some v -> v.CompiledName cenv.g.CompilerGlobalState | None -> x.LogicalName - member __.LogicalName = + member _.LogicalName = checkIsResolved() match d with | E e -> e.EventName @@ -1770,7 +1953,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m | C m -> m.LogicalName | V v -> v.LogicalName - member __.DisplayName = + member _.DisplayName = checkIsResolved() match d with | E e -> e.EventName @@ -1778,34 +1961,34 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m | C m -> m.DisplayName | V v -> v.DisplayName - member __.XmlDocSig = + member sym.XmlDocSig = checkIsResolved() match d with | E e -> - let range = defaultArg __.DeclarationLocationOpt range0 - match SymbolHelpers.GetXmlDocSigOfEvent cenv.infoReader range e with + let range = defaultArg sym.DeclarationLocationOpt range0 + match GetXmlDocSigOfEvent cenv.infoReader range e with | Some (_, docsig) -> docsig | _ -> "" | P p -> - let range = defaultArg __.DeclarationLocationOpt range0 - match SymbolHelpers.GetXmlDocSigOfProp cenv.infoReader range p with + let range = defaultArg sym.DeclarationLocationOpt range0 + match GetXmlDocSigOfProp cenv.infoReader range p with | Some (_, docsig) -> docsig | _ -> "" | M m | C m -> - let range = defaultArg __.DeclarationLocationOpt range0 - match SymbolHelpers.GetXmlDocSigOfMethInfo cenv.infoReader range m with + let range = defaultArg sym.DeclarationLocationOpt range0 + match GetXmlDocSigOfMethInfo cenv.infoReader range m with | Some (_, docsig) -> docsig | _ -> "" | V v -> match v.DeclaringEntity with | Parent entityRef -> - match SymbolHelpers.GetXmlDocSigOfScopedValRef cenv.g entityRef v with + match GetXmlDocSigOfScopedValRef cenv.g entityRef v with | Some (_, docsig) -> docsig | _ -> "" | ParentNone -> "" - member __.XmlDoc = + member _.XmlDoc = if isUnresolved() then XmlDoc.Empty |> makeXmlDoc else match d with | E e -> e.XmlDoc |> makeXmlDoc @@ -1813,28 +1996,35 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m | C m -> m.XmlDoc |> makeXmlDoc | V v -> v.XmlDoc |> makeXmlDoc + member _.ElaboratedXmlDoc = + if isUnresolved() then XmlDoc.Empty |> makeElaboratedXmlDoc else + match d with + | E e -> e.XmlDoc |> makeElaboratedXmlDoc + | P p -> p.XmlDoc |> makeElaboratedXmlDoc + | M m | C m -> m.XmlDoc |> makeElaboratedXmlDoc + | V v -> v.XmlDoc |> makeElaboratedXmlDoc + member x.CurriedParameterGroups = checkIsResolved() match d with | P p -> - - [ [ for (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty)) in p.GetParamDatas(cenv.amap, range0) do - // INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for - // either .NET or F# parameters - let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] } - yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional) ] - |> makeReadOnlyCollection ] + [ [ for ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty) in p.GetParamDatas(cenv.amap, range0) do + // INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for + // either .NET or F# parameters + let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] } + yield FSharpParameter(cenv, pty, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ] + |> makeReadOnlyCollection ] |> makeReadOnlyCollection | E _ -> [] |> makeReadOnlyCollection | M m | C m -> [ for argtys in m.GetParamDatas(cenv.amap, range0, m.FormalMethodInst) do yield - [ for (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty)) in argtys do + [ for ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfo, nmOpt, _reflArgInfo, pty) in argtys do // INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for // either .NET or F# parameters let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] } - yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional) ] + yield FSharpParameter(cenv, pty, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ] |> makeReadOnlyCollection ] |> makeReadOnlyCollection @@ -1851,7 +2041,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = else [ty] yield allArguments - |> List.map (fun arg -> FSharpParameter(cenv, arg, { Name=None; Attribs= [] }, x.DeclarationLocationOpt, false, false, false, false)) + |> List.map (fun arg -> FSharpParameter(cenv, arg, ValReprInfo.unnamedTopArg1, x.DeclarationLocationOpt)) |> makeReadOnlyCollection ] |> makeReadOnlyCollection else makeReadOnlyCollection [] @@ -1866,7 +2056,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let isInArg = HasFSharpAttribute cenv.g cenv.g.attrib_InAttribute argInfo.Attribs && isByrefTy cenv.g argty let isOutArg = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute argInfo.Attribs && isByrefTy cenv.g argty let isOptionalArg = HasFSharpAttribute cenv.g cenv.g.attrib_OptionalArgumentAttribute argInfo.Attribs - yield FSharpParameter(cenv, argty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg) ] + yield FSharpParameter(cenv, argty, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, false) ] |> makeReadOnlyCollection ] |> makeReadOnlyCollection @@ -1874,40 +2064,35 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = checkIsResolved() match d with | E e -> - // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods - let retInfo: ArgReprInfo = { Name=None; Attribs= [] } + // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods let rty = try PropTypOfEventInfo cenv.infoReader range0 AccessibleFromSomewhere e with _ -> // For non-standard events, just use the delegate type as the ReturnParameter type e.GetDelegateType(cenv.amap, range0) - - FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) + FSharpParameter(cenv, rty, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt) | P p -> - // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods - let retInfo: ArgReprInfo = { Name=None; Attribs= [] } + // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods let rty = p.GetPropertyType(cenv.amap, range0) - FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) + FSharpParameter(cenv, rty, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt) | M m | C m -> - // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods - let retInfo: ArgReprInfo = { Name=None; Attribs= [] } + // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods let rty = m.GetFSharpReturnTy(cenv.amap, range0, m.FormalMethodInst) - FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) + FSharpParameter(cenv, rty, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt) | V v -> match v.ValReprInfo with | None -> let _, tau = v.TypeScheme let _argtysl, rty = stripFunTy cenv.g tau - let empty: ArgReprInfo = { Name=None; Attribs= [] } - FSharpParameter(cenv, rty, empty, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) + FSharpParameter(cenv, rty, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt) | Some (ValReprInfo(_typars, argInfos, retInfo)) -> let tau = v.TauType let _c, rty = GetTopTauTypeInFSharpForm cenv.g argInfos tau range0 - FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) + FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt) - member __.Attributes = + override _.Attributes = if isUnresolved() then makeReadOnlyCollection [] else let m = range0 match d with @@ -1922,35 +2107,35 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = |> makeReadOnlyCollection /// Is this "base" in "base.M(...)" - member __.IsBaseValue = + member _.IsBaseValue = if isUnresolved() then false else match d with | M _ | C _ | P _ | E _ -> false - | V v -> v.BaseOrThisInfo = BaseVal + | V v -> v.IsBaseVal /// Is this the "x" in "type C() as x = ..." - member __.IsConstructorThisValue = + member _.IsConstructorThisValue = if isUnresolved() then false else match d with | M _ | C _| P _ | E _ -> false - | V v -> v.BaseOrThisInfo = CtorThisVal + | V v -> v.IsCtorThisVal /// Is this the "x" in "member x.M = ..." - member __.IsMemberThisValue = + member _.IsMemberThisValue = if isUnresolved() then false else match d with | M _ | C _ | P _ | E _ -> false - | V v -> v.BaseOrThisInfo = MemberThisVal + | V v -> v.IsMemberThisVal /// Is this a [] value, and if so what value? (may be null) - member __.LiteralValue = + member _.LiteralValue = if isUnresolved() then None else match d with | M _ | C _ | P _ | E _ -> None | V v -> getLiteralValue v.LiteralValue /// How visible is this? - member this.Accessibility: FSharpAccessibility = + override this.Accessibility: FSharpAccessibility = if isUnresolved() then FSharpAccessibility taccessPublic else match fsharpInfo() with | Some v -> FSharpAccessibility(v.Accessibility) @@ -1963,7 +2148,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let access = match e with | ILEvent ileinfo -> - let ilAccess = AccessibilityLogic.GetILAccessOfILEventInfo ileinfo + let ilAccess = GetILAccessOfILEventInfo ileinfo getApproxFSharpAccessibilityOfMember this.DeclaringEntity.Value.Entity ilAccess | _ -> taccessPublic @@ -1974,7 +2159,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let access = match p with | ILProp ilpinfo -> - let ilAccess = AccessibilityLogic.GetILAccessOfILPropInfo ilpinfo + let ilAccess = GetILAccessOfILPropInfo ilpinfo getApproxFSharpAccessibilityOfMember this.DeclaringEntity.Value.Entity ilAccess | _ -> taccessPublic @@ -2007,7 +2192,12 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = member x.IsValue = match d with - | V valRef -> not (SymbolHelpers.isFunction cenv.g valRef.Type) + | V valRef -> not (isForallFunctionTy cenv.g valRef.Type) + | _ -> false + + member x.IsFunction = + match d with + | V valRef -> isForallFunctionTy cenv.g valRef.Type | _ -> false override x.Equals(other: obj) = @@ -2030,10 +2220,11 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = prefix + x.LogicalName with _ -> "??" - member x.FormatLayout (denv:FSharpDisplayContext) = + member x.FormatLayout (context:FSharpDisplayContext) = match x.IsMember, d with | true, V v -> - NicePrint.prettyLayoutOfValOrMemberNoInst { (denv.Contents cenv.g) with showMemberContainers=true } v.Deref + NicePrint.prettyLayoutOfMemberNoInstShort { (context.Contents cenv.g) with showMemberContainers=true } v.Deref + |> LayoutRender.toArray | _,_ -> checkIsResolved() let ty = @@ -2045,10 +2236,61 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let argtysl = m.GetParamTypes(cenv.amap, range0, m.FormalMethodInst) mkIteratedFunTy (List.map (mkRefTupledTy cenv.g) argtysl) rty | V v -> v.TauType - NicePrint.prettyLayoutOfTypeNoCx (denv.Contents cenv.g) ty + NicePrint.prettyLayoutOfTypeNoCx (context.Contents cenv.g) ty + |> LayoutRender.toArray + + member x.GetWitnessPassingInfo() = + let witnessInfos = + match d with + | M (FSMeth(_, _, vref, _)) -> + let _tps, witnessInfos, _curriedArgInfos, _retTy, _ = GetTypeOfMemberInMemberForm cenv.g vref + witnessInfos + | V vref -> + let arities = arityOfVal vref.Deref + let numEnclosingTypars = CountEnclosingTyparsOfActualParentOfVal vref.Deref + let _tps, witnessInfos, _curriedArgInfos, _retTy, _ = GetTopValTypeInCompiledForm cenv.g arities numEnclosingTypars vref.Type vref.DefinitionRange + witnessInfos + | E _ | P _ | M _ | C _ -> [] + match witnessInfos with + | [] -> None + | _ when not (cenv.g.langVersion.SupportsFeature(Features.LanguageFeature.WitnessPassing)) -> None + | _ -> + let witnessParams = + ((Set.empty, 0), witnessInfos) ||> List.mapFold (fun (used,i) witnessInfo -> + let paramTy = GenWitnessTy cenv.g witnessInfo + let nm = String.uncapitalize witnessInfo.MemberName + let nm = if used.Contains nm then nm + string i else nm + let argReprInfo : ArgReprInfo = { Attribs=[]; Name=Some (mkSynId x.DeclarationLocation nm) } + let p = FSharpParameter(cenv, paramTy, argReprInfo, None, None, false, false, false, false, true) + p, (used.Add nm, i + 1)) + |> fst + let witnessMethName = ExtraWitnessMethodName x.CompiledName + Some (witnessMethName, makeReadOnlyCollection witnessParams) + + // FullType may raise exceptions (see https://github.com/fsharp/fsharp/issues/307). + member x.FullTypeSafe = Option.attempt (fun _ -> x.FullType) + + member x.TryGetFullDisplayName() = + let fullName = Option.attempt (fun _ -> x.FullName.Split '.') + match fullName with + | Some fullName -> + match Option.attempt (fun _ -> x.DisplayName) with + | Some shortDisplayName when not (shortDisplayName.Contains ".") -> + Some (fullName |> Array.replace (fullName.Length - 1) shortDisplayName) + | _ -> Some fullName + | None -> None + |> Option.map (fun fullDisplayName -> String.Join (".", fullDisplayName)) + member x.TryGetFullCompiledOperatorNameIdents() : string[] option = + // For operator ++ displayName is ( ++ ) compiledName is op_PlusPlus + if IsOperatorDisplayName x.DisplayName && x.DisplayName <> x.CompiledName then + x.DeclaringEntity + |> Option.bind (fun e -> e.TryGetFullName()) + |> Option.map (fun enclosingEntityFullName -> + Array.append (enclosingEntityFullName.Split '.') [| x.CompiledName |]) + else None -and FSharpType(cenv, ty:TType) = +type FSharpType(cenv, ty:TType) = let isUnresolved() = ErrorLogger.protectAssemblyExploration true <| fun () -> @@ -2062,35 +2304,32 @@ and FSharpType(cenv, ty:TType) = let isResolved() = not (isUnresolved()) - new (g, thisCcu, thisCcuTy, tcImports, ty) = FSharpType(SymbolEnv(g, thisCcu, Some thisCcuTy, tcImports), ty) + new (g, thisCcu, thisCcuTyp, tcImports, ty) = FSharpType(SymbolEnv(g, thisCcu, Some thisCcuTyp, tcImports), ty) - member __.IsUnresolved = isUnresolved() + member _.IsUnresolved = isUnresolved() - member __.HasTypeDefinition = + member _.HasTypeDefinition = isResolved() && protect <| fun () -> match stripTyparEqns ty with | TType_app _ | TType_measure (Measure.Con _ | Measure.Prod _ | Measure.Inv _ | Measure.One _) -> true | _ -> false - member __.IsTupleType = + member _.IsTupleType = isResolved() && protect <| fun () -> match stripTyparEqns ty with | TType_tuple _ -> true | _ -> false - member __.IsStructTupleType = + member _.IsStructTupleType = isResolved() && protect <| fun () -> match stripTyparEqns ty with | TType_tuple (tupInfo, _) -> evalTupInfoIsStruct tupInfo | _ -> false - member x.IsNamedType = x.HasTypeDefinition - member x.NamedEntity = x.TypeDefinition - - member __.TypeDefinition = + member _.TypeDefinition = protect <| fun () -> match stripTyparEqns ty with | TType_app (tcref, _) -> FSharpEntity(cenv, tcref) @@ -2100,7 +2339,7 @@ and FSharpType(cenv, ty:TType) = | TType_measure (Measure.Inv _) -> FSharpEntity(cenv, cenv.g.measureinverse_tcr) | _ -> invalidOp "not a named type" - member __.GenericArguments = + member _.GenericArguments = protect <| fun () -> match stripTyparEqns ty with | TType_anon (_, tyargs) @@ -2114,7 +2353,7 @@ and FSharpType(cenv, ty:TType) = | _ -> invalidOp "not a named type" (* - member __.ProvidedArguments = + member _.ProvidedArguments = let typeName, argNamesAndValues = try PrettyNaming.demangleProvidedTypeName typeLogicalName @@ -2125,37 +2364,37 @@ and FSharpType(cenv, ty:TType) = member ty.IsAbbreviation = isResolved() && ty.HasTypeDefinition && ty.TypeDefinition.IsFSharpAbbreviation - member __.AbbreviatedType = + member _.AbbreviatedType = protect <| fun () -> FSharpType(cenv, stripTyEqns cenv.g ty) - member __.IsFunctionType = + member _.IsFunctionType = isResolved() && protect <| fun () -> match stripTyparEqns ty with | TType_fun _ -> true | _ -> false - member __.IsAnonRecordType = + member _.IsAnonRecordType = isResolved() && protect <| fun () -> match stripTyparEqns ty with | TType_anon _ -> true | _ -> false - member __.AnonRecordTypeDetails = + member _.AnonRecordTypeDetails = protect <| fun () -> match stripTyparEqns ty with | TType_anon (anonInfo, _) -> FSharpAnonRecordTypeDetails(cenv, anonInfo) | _ -> invalidOp "not an anonymous record type" - member __.IsGenericParameter = + member _.IsGenericParameter = protect <| fun () -> match stripTyparEqns ty with | TType_var _ -> true | TType_measure (Measure.Var _) -> true | _ -> false - member __.GenericParameter = + member _.GenericParameter = protect <| fun () -> match stripTyparEqns ty with | TType_var tp @@ -2163,17 +2402,17 @@ and FSharpType(cenv, ty:TType) = FSharpGenericParameter (cenv, tp) | _ -> invalidOp "not a generic parameter type" - member x.AllInterfaces = + member _.AllInterfaces = if isUnresolved() then makeReadOnlyCollection [] else [ for ty in AllInterfacesOfType cenv.g cenv.amap range0 AllowMultiIntfInstantiations.Yes ty do yield FSharpType(cenv, ty) ] |> makeReadOnlyCollection - member x.BaseType = + member _.BaseType = GetSuperTypeOfType cenv.g cenv.amap range0 ty |> Option.map (fun ty -> FSharpType(cenv, ty)) - member x.Instantiate(instantiation:(FSharpGenericParameter * FSharpType) list) = + member _.Instantiate(instantiation:(FSharpGenericParameter * FSharpType) list) = let typI = instType (instantiation |> List.map (fun (tyv, ty) -> tyv.V, ty.V)) ty FSharpType(cenv, typI) @@ -2191,7 +2430,7 @@ and FSharpType(cenv, ty:TType) = | _ -> false // Note: This equivalence relation is modulo type abbreviations. The hash is less than perfect. - override x.GetHashCode() = + override _.GetHashCode() = let rec hashType ty = let ty = stripTyEqnsWrtErasure EraseNone cenv.g ty match ty with @@ -2205,15 +2444,25 @@ and FSharpType(cenv, ty:TType) = | TType_anon (_,l1) -> 10800 + List.sumBy hashType l1 hashType ty - member x.Format(denv: FSharpDisplayContext) = + member _.Format(context: FSharpDisplayContext) = protect <| fun () -> - NicePrint.prettyStringOfTyNoCx (denv.Contents cenv.g) ty + NicePrint.prettyStringOfTyNoCx (context.Contents cenv.g) ty - member x.FormatLayout(denv: FSharpDisplayContext) = + member _.FormatWithConstraints(context: FSharpDisplayContext) = + protect <| fun () -> + NicePrint.prettyStringOfTy (context.Contents cenv.g) ty + + member _.FormatLayout(context: FSharpDisplayContext) = protect <| fun () -> - NicePrint.prettyLayoutOfTypeNoCx (denv.Contents cenv.g) ty + NicePrint.prettyLayoutOfTypeNoCx (context.Contents cenv.g) ty + |> LayoutRender.toArray - override x.ToString() = + member _.FormatLayoutWithConstraints(context: FSharpDisplayContext) = + protect <| fun () -> + NicePrint.prettyLayoutOfType (context.Contents cenv.g) ty + |> LayoutRender.toArray + + override _.ToString() = protect <| fun () -> "type " + NicePrint.prettyStringOfTyNoCx (DisplayEnv.Empty(cenv.g)) ty @@ -2221,8 +2470,8 @@ and FSharpType(cenv, ty:TType) = let prettyTy = PrettyTypes.PrettifyType ty.cenv.g ty.V |> fst ty.AdjustType prettyTy - static member Prettify(tys: IList) = - let xs = tys |> List.ofSeq + static member Prettify(types: IList) = + let xs = types |> List.ofSeq match xs with | [] -> [] | h :: _ -> @@ -2263,7 +2512,12 @@ and FSharpType(cenv, ty:TType) = let ps = (xs, prettyTys) ||> List.map2 (List.map2 (fun p pty -> p.AdjustType pty)) |> List.map makeReadOnlyCollection |> makeReadOnlyCollection ps, returnParameter.AdjustType prettyRetTy -and FSharpAttribute(cenv: SymbolEnv, attrib: AttribInfo) = + member x.StripAbbreviations() = + if x.IsAbbreviation then + x.AbbreviatedType.StripAbbreviations() + else x + +type FSharpAttribute(cenv: SymbolEnv, attrib: AttribInfo) = let rec resolveArgObj (arg: obj) = match arg with @@ -2271,34 +2525,41 @@ and FSharpAttribute(cenv: SymbolEnv, attrib: AttribInfo) = | :? (obj[]) as a -> a |> Array.map resolveArgObj |> box | _ -> arg - member __.AttributeType = + member _.AttributeType = FSharpEntity(cenv, attrib.TyconRef) - member __.IsUnresolved = entityIsUnresolved(attrib.TyconRef) + member _.IsUnresolved = entityIsUnresolved(attrib.TyconRef) - member __.ConstructorArguments = + member _.ConstructorArguments = attrib.ConstructorArguments |> List.map (fun (ty, obj) -> FSharpType(cenv, ty), resolveArgObj obj) |> makeReadOnlyCollection - member __.NamedArguments = + member _.NamedArguments = attrib.NamedArguments |> List.map (fun (ty, nm, isField, obj) -> FSharpType(cenv, ty), nm, isField, resolveArgObj obj) |> makeReadOnlyCollection - member __.Format(denv: FSharpDisplayContext) = + member _.Format(context: FSharpDisplayContext) = protect <| fun () -> match attrib with | AttribInfo.FSAttribInfo(g, attrib) -> - NicePrint.stringOfFSAttrib (denv.Contents g) attrib + NicePrint.stringOfFSAttrib (context.Contents g) attrib | AttribInfo.ILAttribInfo (g, _, _scoref, cattr, _) -> - let parms, _args = decodeILAttribData g.ilg cattr - NicePrint.stringOfILAttrib (denv.Contents g) (cattr.Method.DeclaringType, parms) + let parms, _args = decodeILAttribData cattr + NicePrint.stringOfILAttrib (context.Contents g) (cattr.Method.DeclaringType, parms) + + member _.Range = attrib.Range - override __.ToString() = + override _.ToString() = if entityIsUnresolved attrib.TyconRef then "attribute ???" else "attribute " + attrib.TyconRef.CompiledName + "(...)" + + member attr.IsAttribute<'T> () = + // CompiledName throws exception on DataContractAttribute generated by SQLProvider + try attr.AttributeType.CompiledName = typeof<'T>.Name with _ -> false + #if !NO_EXTENSIONTYPING -and FSharpStaticParameter(cenv, sp: Tainted< ExtensionTyping.ProvidedParameterInfo >, m) = +type FSharpStaticParameter(cenv, sp: Tainted< ExtensionTyping.ProvidedParameterInfo >, m) = inherit FSharpSymbol(cenv, (fun () -> protect <| fun () -> @@ -2307,75 +2568,97 @@ and FSharpStaticParameter(cenv, sp: Tainted< ExtensionTyping.ProvidedParameterIn Item.ArgName((mkSynId m nm, spKind, None))), (fun _ _ _ -> true)) - member __.Name = + member _.Name = protect <| fun () -> sp.PUntaint((fun p -> p.Name), m) - member __.DeclarationLocation = m + member _.DeclarationLocation = m - member __.Kind = + member _.Kind = protect <| fun () -> let ty = Import.ImportProvidedType cenv.amap m (sp.PApply((fun x -> x.ParameterType), m)) FSharpType(cenv, ty) - member __.IsOptional = + member _.IsOptional = protect <| fun () -> sp.PUntaint((fun x -> x.IsOptional), m) - member __.HasDefaultValue = + member _.HasDefaultValue = protect <| fun () -> sp.PUntaint((fun x -> x.HasDefaultValue), m) - member __.DefaultValue = + member _.DefaultValue = protect <| fun () -> sp.PUntaint((fun x -> x.RawDefaultValue), m) + member _.Range = m + override x.Equals(other: obj) = box x === other || match other with - | :? FSharpStaticParameter as p -> x.Name = p.Name && Range.equals x.DeclarationLocation p.DeclarationLocation + | :? FSharpStaticParameter as p -> x.Name = p.Name && equals x.DeclarationLocation p.DeclarationLocation | _ -> false override x.GetHashCode() = hash x.Name override x.ToString() = "static parameter " + x.Name #endif -and FSharpParameter(cenv, paramTy:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg) = + +type FSharpParameter(cenv, paramTy: TType, topArgInfo: ArgReprInfo, ownerOpt, ownerRangeOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg) = inherit FSharpSymbol(cenv, (fun () -> - let m = match mOpt with Some m -> m | None -> range0 - Item.ArgName((match topArgInfo.Name with None -> mkSynId m "" | Some v -> v), paramTy, None)), + let m = defaultArg ownerRangeOpt range0 + let id = match topArgInfo.Name with | Some id -> id | None -> mkSynId m "" + Item.ArgName(id, paramTy, ownerOpt)), (fun _ _ _ -> true)) - let attribs = topArgInfo.Attribs - let idOpt = topArgInfo.Name - let m = match mOpt with Some m -> m | None -> range0 - member __.Name = match idOpt with None -> None | Some v -> Some v.idText + new (cenv, id, ty, container) = + let argInfo: ArgReprInfo = { Name = Some id; Attribs = [] } + FSharpParameter(cenv, ty, argInfo, container, None, false, false, false, false, false) + + new (cenv, ty, argInfo: ArgReprInfo, ownerRangeOpt) = + FSharpParameter(cenv, ty, argInfo, None, ownerRangeOpt, false, false, false, false, false) + + member _.Name = match topArgInfo.Name with None -> None | Some v -> Some v.idText + + member _.cenv: SymbolEnv = cenv - member __.cenv: SymbolEnv = cenv + member _.AdjustType ty = FSharpParameter(cenv, ty, topArgInfo, ownerOpt, ownerRangeOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg) - member __.AdjustType t = FSharpParameter(cenv, t, topArgInfo, mOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg) + member _.Type: FSharpType = FSharpType(cenv, paramTy) - member __.Type: FSharpType = FSharpType(cenv, paramTy) + member _.V = paramTy - member __.V = paramTy + member _.DeclarationLocation = + match topArgInfo.Name with + | Some v -> v.idRange + | None -> + + match ownerRangeOpt with + | Some m -> m + | None -> range0 - member __.DeclarationLocation = match idOpt with None -> m | Some v -> v.idRange + member _.Owner = + match ownerOpt with + | Some (ArgumentContainer.Method minfo) -> Some (FSharpMemberOrFunctionOrValue (cenv, minfo) :> FSharpSymbol) + | _ -> None - member __.Attributes = - attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection + override _.Attributes = + topArgInfo.Attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection - member __.IsParamArrayArg = isParamArrayArg + member _.IsParamArrayArg = isParamArrayArg - member __.IsInArg = isInArg + member _.IsInArg = isInArg - member __.IsOutArg = isOutArg + member _.IsOutArg = isOutArg - member __.IsOptionalArg = isOptionalArg + member _.IsOptionalArg = isOptionalArg + + member _.IsWitnessArg = isWitnessArg member private x.ValReprInfo = topArgInfo override x.Equals(other: obj) = box x === other || match other with - | :? FSharpParameter as p -> x.Name = p.Name && Range.equals x.DeclarationLocation p.DeclarationLocation + | :? FSharpParameter as p -> x.Name = p.Name && equals x.DeclarationLocation p.DeclarationLocation | _ -> false override x.GetHashCode() = hash (box topArgInfo) @@ -2383,7 +2666,7 @@ and FSharpParameter(cenv, paramTy:TType, topArgInfo:ArgReprInfo, mOpt, isParamAr override x.ToString() = "parameter " + (match x.Name with None -> " s) -and FSharpAssemblySignature (cenv, topAttribs: TypeChecker.TopAttribs option, optViewedCcu: CcuThunk option, mtyp: ModuleOrNamespaceType) = +type FSharpAssemblySignature (cenv, topAttribs: TopAttribs option, optViewedCcu: CcuThunk option, mtyp: ModuleOrNamespaceType) = // Assembly signature for a referenced/linked assembly new (cenv: SymbolEnv, ccu: CcuThunk) = @@ -2391,10 +2674,10 @@ and FSharpAssemblySignature (cenv, topAttribs: TypeChecker.TopAttribs option, op FSharpAssemblySignature(cenv, None, Some ccu, ccu.Contents.ModuleOrNamespaceType) // Assembly signature for an assembly produced via type-checking. - new (g, thisCcu, thisCcuTy, tcImports, topAttribs, mtyp) = - FSharpAssemblySignature(SymbolEnv(g, thisCcu, Some thisCcuTy, tcImports), topAttribs, None, mtyp) + new (tcGlobals, thisCcu, thisCcuTyp, tcImports, topAttribs, contents) = + FSharpAssemblySignature(SymbolEnv(tcGlobals, thisCcu, Some thisCcuTyp, tcImports), topAttribs, None, contents) - member __.Entities = + member _.Entities = let rec loop (rmtyp: ModuleOrNamespaceType) = [| for entity in rmtyp.AllEntities do @@ -2406,7 +2689,7 @@ and FSharpAssemblySignature (cenv, topAttribs: TypeChecker.TopAttribs option, op loop mtyp |> makeReadOnlyCollection - member __.Attributes = + member _.Attributes = [ match optViewedCcu with | Some ccu -> match ccu.TryGetILModuleDef() with @@ -2427,7 +2710,7 @@ and FSharpAssemblySignature (cenv, topAttribs: TypeChecker.TopAttribs option, op | Some tA -> for a in tA.assemblyAttrs do yield FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a)) ] |> makeReadOnlyCollection - member __.FindEntityByPath path = + member _.FindEntityByPath path = let findNested name entity = match entity with | Some (e: Entity) ->e.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind name @@ -2440,28 +2723,28 @@ and FSharpAssemblySignature (cenv, topAttribs: TypeChecker.TopAttribs option, op |> Option.map (fun e -> FSharpEntity(cenv, rescopeEntity optViewedCcu e)) | _ -> None - override x.ToString() = "" + member x.TryGetEntities() = try x.Entities :> _ seq with _ -> Seq.empty -and FSharpAssembly internal (cenv, ccu: CcuThunk) = + override x.ToString() = "" - new (g, tcImports, ccu: CcuThunk) = - FSharpAssembly(SymbolEnv(g, ccu, None, tcImports), ccu) +type FSharpAssembly internal (cenv, ccu: CcuThunk) = - member __.RawCcuThunk = ccu + new (tcGlobals, tcImports, ccu: CcuThunk) = + FSharpAssembly(SymbolEnv(tcGlobals, ccu, None, tcImports), ccu) - member __.QualifiedName = match ccu.QualifiedName with None -> "" | Some s -> s + member _.RawCcuThunk = ccu - member __.CodeLocation = ccu.SourceCodeDirectory + member _.QualifiedName = match ccu.QualifiedName with None -> "" | Some s -> s - member __.FileName = ccu.FileName + member _.FileName = ccu.FileName - member __.SimpleName = ccu.AssemblyName + member _.SimpleName = ccu.AssemblyName #if !NO_EXTENSIONTYPING - member __.IsProviderGenerated = ccu.IsProviderGenerated + member _.IsProviderGenerated = ccu.IsProviderGenerated #endif - member __.Contents : FSharpAssemblySignature = FSharpAssemblySignature(cenv, ccu) + member _.Contents : FSharpAssemblySignature = FSharpAssemblySignature(cenv, ccu) override x.ToString() = match ccu.ILScopeRef with @@ -2472,51 +2755,30 @@ and FSharpAssembly internal (cenv, ccu: CcuThunk) = /// Represents open declaration in F# code. [] -type FSharpOpenDeclaration(longId: Ident list, range: range option, modules: FSharpEntity list, appliedScope: range, isOwnNamespace: bool) = - - member __.LongId = longId +type FSharpOpenDeclaration(target: SynOpenDeclTarget, range: range option, modules: FSharpEntity list, types: FSharpType list, appliedScope: range, isOwnNamespace: bool) = - member __.Range = range + member _.Target = target - member __.Modules = modules + member _.LongId = + match target with + | SynOpenDeclTarget.ModuleOrNamespace(longId, _) -> longId + | SynOpenDeclTarget.Type(synType, _) -> + let rec get ty = + match ty with + | SynType.LongIdent (LongIdentWithDots(lid, _)) -> lid + | SynType.App (ty2, _, _, _, _, _, _) -> get ty2 + | SynType.LongIdentApp (ty2, _, _, _, _, _, _) -> get ty2 + | SynType.Paren (ty2, _) -> get ty2 + | _ -> [] + get synType - member __.AppliedScope = appliedScope - - member __.IsOwnNamespace = isOwnNamespace - -[] -type FSharpSymbolUse(g:TcGlobals, denv: DisplayEnv, symbol:FSharpSymbol, itemOcc, range: range) = - - member __.Symbol = symbol - - member __.DisplayContext = FSharpDisplayContext(fun _ -> denv) - - member x.IsDefinition = x.IsFromDefinition - - member __.IsFromDefinition = itemOcc = ItemOccurence.Binding - - member __.IsFromPattern = itemOcc = ItemOccurence.Pattern - - member __.IsFromType = itemOcc = ItemOccurence.UseInType - - member __.IsFromAttribute = itemOcc = ItemOccurence.UseInAttribute - - member __.IsFromDispatchSlotImplementation = itemOcc = ItemOccurence.Implemented - - member __.IsFromComputationExpression = - match symbol.Item, itemOcc with - // 'seq' in 'seq { ... }' gets colored as keywords - | (Item.Value vref), ItemOccurence.Use when valRefEq g g.seq_vref vref -> true - // custom builders, custom operations get colored as keywords - | (Item.CustomBuilder _ | Item.CustomOperation _), ItemOccurence.Use -> true - | _ -> false + member _.Range = range - member __.IsFromOpenStatement = itemOcc = ItemOccurence.Open + member _.Types = types - member __.FileName = range.FileName + member _.Modules = modules - member __.Range = Range.toZ range + member _.AppliedScope = appliedScope - member __.RangeAlternate = range + member _.IsOwnNamespace = isOwnNamespace - override __.ToString() = sprintf "%O, %O, %O" symbol itemOcc range diff --git a/src/fsharp/symbols/Symbols.fsi b/src/fsharp/symbols/Symbols.fsi index 6893097ed94..99a7a4a53b6 100644 --- a/src/fsharp/symbols/Symbols.fsi +++ b/src/fsharp/symbols/Symbols.fsi @@ -1,28 +1,36 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.SourceCodeServices +namespace rec FSharp.Compiler.Symbols open System.Collections.Generic + open FSharp.Compiler open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CheckDeclarations +open FSharp.Compiler.CompilerImports open FSharp.Compiler.Import open FSharp.Compiler.InfoReader -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.Tast -open FSharp.Compiler.TcGlobals open FSharp.Compiler.NameResolution +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeOps +open FSharp.Compiler.TcGlobals // Implementation details used by other code in the compiler type internal SymbolEnv = - new: TcGlobals * thisCcu:CcuThunk * thisCcuTyp: ModuleOrNamespaceType option * tcImports: TcImports -> SymbolEnv - new: TcGlobals * thisCcu:CcuThunk * thisCcuTyp: ModuleOrNamespaceType option * tcImports: TcImports * amap: ImportMap * infoReader: InfoReader -> SymbolEnv + new: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType option * tcImports: TcImports -> SymbolEnv + + new: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType option * tcImports: TcImports * amap: ImportMap * infoReader: InfoReader -> SymbolEnv + member amap: ImportMap + member g: TcGlobals + member tcValF: ConstraintSolver.TcValF + /// Indicates the accessibility of a symbol, as seen by the F# language -type public FSharpAccessibility = +type FSharpAccessibility = internal new: Accessibility * ?isProtected: bool -> FSharpAccessibility /// Indicates the symbol has public accessibility. @@ -40,31 +48,40 @@ type public FSharpAccessibility = /// The underlying Accessibility member internal Contents: Accessibility - /// Represents the information needed to format types and other information in a style /// suitable for use in F# source text at a particular source location. /// /// Acquired via GetDisplayEnvAtLocationAlternate and similar methods. May be passed /// to the Format method on FSharpType and other methods. -type [] public FSharpDisplayContext = - internal new : denv: (TcGlobals -> Tastops.DisplayEnv) -> FSharpDisplayContext +type FSharpDisplayContext = + internal new: denv: (TcGlobals -> DisplayEnv) -> FSharpDisplayContext static member Empty: FSharpDisplayContext member WithShortTypeNames: bool -> FSharpDisplayContext -/// Represents a symbol in checked F# source code or a compiled .NET component. + /// Causes type signatures to be formatted with prefix-style generic parameters, + /// for example `list`. + member WithPrefixGenericParameters: unit -> FSharpDisplayContext + + /// Causes type signatures to be formatted with suffix-style generic parameters, + /// for example `int list` + member WithSuffixGenericParameters: unit -> FSharpDisplayContext + +/// Represents a symbol in checked F# source code or a compiled .NET component. /// /// The subtype of the symbol may reveal further information and can be one of FSharpEntity, FSharpUnionCase /// FSharpField, FSharpGenericParameter, FSharpStaticParameter, FSharpMemberOrFunctionOrValue, FSharpParameter, /// or FSharpActivePatternCase. -type [] public FSharpSymbol = - static member internal Create: g: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * item: NameResolution.Item -> FSharpSymbol - static member internal Create: cenv: SymbolEnv * item: NameResolution.Item -> FSharpSymbol +[] +type FSharpSymbol = + static member internal Create: g: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * item: Item -> FSharpSymbol + static member internal Create: cenv: SymbolEnv * item: Item -> FSharpSymbol /// Computes if the symbol is accessible for the given accessibility rights member IsAccessible: FSharpAccessibilityRights -> bool - member internal Item: NameResolution.Item + member internal SymbolEnv: SymbolEnv + member internal Item: Item /// Get the assembly declaring this symbol member Assembly: FSharpAssembly @@ -76,7 +93,10 @@ type [] public FSharpSymbol = /// Get the declaration location for the symbol member DeclarationLocation: range option - /// Gets the short display name for the symbol + /// Gets the display name for the symbol where double backticks are not added for non-identifiers + member DisplayNameCore: string + + /// Gets the display name for the symbol. Double backticks are added if the name is not a valid identifier. member DisplayName: string /// Get the implementation location for the symbol if it was declared in a signature that has an implementation @@ -92,43 +112,50 @@ type [] public FSharpSymbol = /// are considered to be effectively the same symbol as the corresponding type definition. /// /// This is the relation used by GetUsesOfSymbol and GetUsesOfSymbolInFile. - member IsEffectivelySameAs : other: FSharpSymbol -> bool + member IsEffectivelySameAs: other: FSharpSymbol -> bool /// A hash compatible with the IsEffectivelySameAs relation - member GetEffectivelySameAsHash : unit -> int + member GetEffectivelySameAsHash: unit -> int + + member IsExplicitlySuppressed: bool - member IsExplicitlySuppressed : bool + /// Get the declared accessibility of the symbol, if any + abstract Accessibility: FSharpAccessibility - static member GetAccessibility : FSharpSymbol -> FSharpAccessibility option + /// Get the attributes for the symbol, if any + abstract Attributes: IList + + /// Try to get an attribute matching the full name of the given type parameter + member TryGetAttribute<'T> : unit -> FSharpAttribute option + + /// Indicates if this symbol has an attribute matching the full name of the given type parameter + member HasAttribute<'T> : unit -> bool /// Represents an assembly as seen by the F# language -and [] public FSharpAssembly = +type FSharpAssembly = - internal new : tcGlobals: TcGlobals * tcImports: TcImports * ccu: CcuThunk -> FSharpAssembly + internal new: tcGlobals: TcGlobals * tcImports: TcImports * ccu: CcuThunk -> FSharpAssembly /// The qualified name of the assembly member QualifiedName: string - [] - member CodeLocation: string - /// The contents of the this assembly member Contents: FSharpAssemblySignature /// The file name for the assembly, if any - member FileName : string option + member FileName: string option /// The simple name for the assembly - member SimpleName : string + member SimpleName: string #if !NO_EXTENSIONTYPING /// Indicates if the assembly was generated by a type provider and is due for static linking - member IsProviderGenerated : bool + member IsProviderGenerated: bool #endif /// Represents an inferred signature of part of an assembly as seen by the F# language -and [] public FSharpAssemblySignature = +type FSharpAssemblySignature = - internal new : tcGlobals: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * topAttribs: TypeChecker.TopAttribs option * contents: ModuleOrNamespaceType -> FSharpAssemblySignature + internal new: tcGlobals: TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * topAttribs: TopAttribs option * contents: ModuleOrNamespaceType -> FSharpAssemblySignature /// The (non-nested) module and type definitions in this signature member Entities: IList @@ -140,15 +167,17 @@ and [] public FSharpAssemblySignature = /// Find entity using compiled names member FindEntityByPath: string list -> FSharpEntity option + /// Safe version of `Entities`. + member TryGetEntities : unit -> seq /// A subtype of FSharpSymbol that represents a type definition or module as seen by the F# language -and [] public FSharpEntity = +type FSharpEntity = inherit FSharpSymbol - internal new : SymbolEnv * EntityRef -> FSharpEntity + internal new: SymbolEnv * EntityRef -> FSharpEntity /// Get the enclosing entity for the definition - member DeclaringEntity : FSharpEntity option + member DeclaringEntity: FSharpEntity option /// Get the name of the type or module, possibly with `n mangling member LogicalName: string @@ -180,34 +209,34 @@ and [] public FSharpEntity = member DeclarationLocation: range /// Indicates if the entity is a measure, type or exception abbreviation - member IsFSharpAbbreviation : bool + member IsFSharpAbbreviation: bool /// Indicates if the entity is record type - member IsFSharpRecord : bool + member IsFSharpRecord: bool /// Indicates if the entity is union type - member IsFSharpUnion : bool + member IsFSharpUnion: bool /// Indicates if the entity is a struct or enum - member IsValueType : bool + member IsValueType: bool /// Indicates if the entity is an array type - member IsArrayType : bool + member IsArrayType: bool /// Get the rank of an array type - member ArrayRank : int + member ArrayRank: int #if !NO_EXTENSIONTYPING /// Indicates if the entity is a 'fake' symbol related to a static instantiation of a type provider - member IsStaticInstantiation : bool + member IsStaticInstantiation: bool /// Indicates if the entity is a provided type - member IsProvided : bool + member IsProvided: bool /// Indicates if the entity is an erased provided type - member IsProvidedAndErased : bool + member IsProvidedAndErased: bool /// Indicates if the entity is a generated provided type - member IsProvidedAndGenerated : bool + member IsProvidedAndGenerated: bool #endif /// Indicates if the entity is an F# module definition member IsFSharpModule: bool @@ -219,43 +248,46 @@ and [] public FSharpEntity = member StaticParameters: IList #endif /// Indicates that a module is compiled to a class with the given mangled name. The mangling is reversed during lookup - member HasFSharpModuleSuffix : bool + member HasFSharpModuleSuffix: bool /// Indicates if the entity is a measure definition member IsMeasure: bool + /// Indicates if the entity is an abstract class + member IsAbstractClass: bool + /// Indicates an F# exception declaration member IsFSharpExceptionDeclaration: bool /// Indicates if this is a reference to something in an F#-compiled assembly - member IsFSharp : bool + member IsFSharp: bool /// Indicates if the entity is in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// Indicates if the entity is a class type definition - member IsClass : bool + member IsClass: bool /// Indicates if is the 'byref<_>' type definition used for byref types in F#-compiled assemblies - member IsByRef : bool + member IsByRef: bool /// Indicates if the entity is a type definition for a reference type where the implementation details are hidden by a signature - member IsOpaque : bool + member IsOpaque: bool /// Indicates if the entity is an enum type definition - member IsEnum : bool + member IsEnum: bool /// Indicates if the entity is a delegate type definition - member IsDelegate : bool + member IsDelegate: bool /// Indicates if the entity is an interface type definition - member IsInterface : bool + member IsInterface: bool /// Indicates if the entity is a part of a namespace path - member IsNamespace : bool + member IsNamespace: bool - /// Get the in-memory XML documentation for the entity, used when code is checked in-memory - member XmlDoc: IList + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc /// Get the XML documentation signature for the entity, used for .xml file lookup for compiled code member XmlDocSig: string @@ -268,125 +300,141 @@ and [] public FSharpEntity = member UsesPrefixDisplay: bool /// Get the declared attributes for the type - member Attributes: IList + override Attributes: IList /// Get the declared interface implementations - member DeclaredInterfaces : IList + member DeclaredInterfaces: IList /// Get all the interface implementations, by walking the type hierarchy - member AllInterfaces : IList + member AllInterfaces: IList /// Check if the entity inherits from System.Attribute in its type hierarchy - member IsAttributeType : bool + member IsAttributeType: bool /// Get the base type, if any - member BaseType : FSharpType option + member BaseType: FSharpType option /// Get the properties, events and methods of a type definitions, or the functions and values of a module - member MembersFunctionsAndValues : IList - - [] - member MembersOrValues : IList + member MembersFunctionsAndValues: IList /// Get the modules and types defined in a module, or the nested types of a type - member NestedEntities : IList + member NestedEntities: IList /// Get the fields of a record, class, struct or enum from the perspective of the F# language. /// This includes static fields, the 'val' bindings in classes and structs, and the value definitions in enums. /// For classes, the list may include compiler generated fields implied by the use of primary constructors. - member FSharpFields : IList - - [] - member RecordFields : IList + member FSharpFields: IList /// Get the type abbreviated by an F# type abbreviation - member AbbreviatedType : FSharpType + member AbbreviatedType: FSharpType /// Get the cases of a union type - member UnionCases : IList + member UnionCases: IList /// Indicates if the type is a delegate with the given Invoke signature - member FSharpDelegateSignature : FSharpDelegateSignature + member FSharpDelegateSignature: FSharpDelegateSignature /// Get the declared accessibility of the type - member Accessibility: FSharpAccessibility + override Accessibility: FSharpAccessibility /// Get the declared accessibility of the representation, not taking signatures into account member RepresentationAccessibility: FSharpAccessibility /// Get all compilation paths, taking `Module` suffixes into account. - member AllCompilationPaths : string list + member AllCompilationPaths: string list /// Get all active pattern cases defined in all active patterns in the module. - member ActivePatternCases : FSharpActivePatternCase list + member ActivePatternCases: FSharpActivePatternCase list + + /// Safe version of `FullName`. + member TryGetFullName: unit -> string option + + /// Safe version of `DisplayName`. + member TryGetFullDisplayName: unit -> string option + + /// Safe version of `CompiledName`. + member TryGetFullCompiledName: unit -> string option + + /// Public nested entities (methods, functions, values, nested modules). + member GetPublicNestedEntities: unit -> seq + + /// Safe version of `GetMembersFunctionsAndValues`. + member TryGetMembersFunctionsAndValues: unit -> IList + + /// Get the source text of the entity's signature to be used as metadata. + member TryGetMetadataText: unit -> ISourceText option /// Represents a delegate signature in an F# symbol -and [] public FSharpDelegateSignature = +[] +type FSharpDelegateSignature = /// Get the argument types of the delegate signature - member DelegateArguments : IList + member DelegateArguments: IList /// Get the return type of the delegate signature - member DelegateReturnType : FSharpType + member DelegateReturnType: FSharpType /// Represents a parameter in an abstract method of a class or interface -and [] public FSharpAbstractParameter = +[] +type FSharpAbstractParameter = /// The optional name of the parameter - member Name : string option + member Name: string option /// The declared or inferred type of the parameter - member Type : FSharpType + member Type: FSharpType /// Indicate this is an in argument - member IsInArg : bool + member IsInArg: bool /// Indicate this is an out argument - member IsOutArg : bool + member IsOutArg: bool /// Indicate this is an optional argument - member IsOptionalArg : bool + member IsOptionalArg: bool /// The declared attributes of the parameter - member Attributes : IList + member Attributes: IList /// Represents the signature of an abstract slot of a class or interface -and [] public FSharpAbstractSignature = - internal new : SymbolEnv * SlotSig -> FSharpAbstractSignature +[] +type FSharpAbstractSignature = + internal new: SymbolEnv * SlotSig -> FSharpAbstractSignature /// Get the arguments of the abstract slot - member AbstractArguments : IList> + member AbstractArguments: IList> /// Get the return type of the abstract slot - member AbstractReturnType : FSharpType + member AbstractReturnType: FSharpType /// Get the generic arguments of the type defining the abstract slot - member DeclaringTypeGenericParameters : IList + member DeclaringTypeGenericParameters: IList /// Get the generic arguments of the abstract slot - member MethodGenericParameters : IList + member MethodGenericParameters: IList /// Get the name of the abstract slot - member Name : string + member Name: string /// Get the declaring type of the abstract slot - member DeclaringType : FSharpType + member DeclaringType: FSharpType /// A subtype of FSharpSymbol that represents a union case as seen by the F# language -and [] public FSharpUnionCase = +[] +type FSharpUnionCase = inherit FSharpSymbol - internal new : SymbolEnv * UnionCaseRef -> FSharpUnionCase + internal new: SymbolEnv * UnionCaseRef -> FSharpUnionCase /// Get the name of the union case member Name: string /// Get the range of the name of the case - member DeclarationLocation : range + member DeclarationLocation: range /// Indicates if the union case has field definitions member HasFields: bool /// Get the data carried by the case. - member UnionCaseFields: IList + member Fields: IList /// Get the type constructed by the case. Normally exactly the type of the enclosing type, sometimes an abbreviation of it member ReturnType: FSharpType @@ -394,42 +442,44 @@ and [] public FSharpUnionCase = /// Get the name of the case in generated IL code member CompiledName: string - /// Get the in-memory XML documentation for the union case, used when code is checked in-memory - member XmlDoc: IList + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc /// Get the XML documentation signature for .xml file lookup for the union case, used for .xml file lookup for compiled code member XmlDocSig: string /// Indicates if the declared visibility of the union constructor, not taking signatures into account - member Accessibility: FSharpAccessibility + override Accessibility: FSharpAccessibility /// Get the attributes for the case, attached to the generated static method to make instances of the case - member Attributes: IList + override Attributes: IList /// Indicates if the union case is for a type in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// A subtype of FSharpSymbol that represents a record or union case field as seen by the F# language -and [] public FSharpAnonRecordTypeDetails = +[] +type FSharpAnonRecordTypeDetails = /// The assembly where the compiled form of the anonymous type is defined - member Assembly : FSharpAssembly + member Assembly: FSharpAssembly /// Names of any enclosing types of the compiled form of the anonymous type (if the anonymous type was defined as a nested type) - member EnclosingCompiledTypeNames : string list + member EnclosingCompiledTypeNames: string list /// The name of the compiled form of the anonymous type - member CompiledName : string + member CompiledName: string /// The sorted labels of the anonymous type - member SortedFieldNames : string[] + member SortedFieldNames: string[] /// A subtype of FSharpSymbol that represents a record or union case field as seen by the F# language -and [] public FSharpField = +[] +type FSharpField = inherit FSharpSymbol - internal new : SymbolEnv * RecdFieldRef -> FSharpField - internal new : SymbolEnv * UnionCaseRef * int -> FSharpField + internal new: SymbolEnv * RecdFieldRef -> FSharpField + internal new: SymbolEnv * UnionCaseRef * int -> FSharpField /// Get the declaring entity of this field, if any. Fields from anonymous types do not have a declaring entity member DeclaringEntity: FSharpEntity option @@ -440,6 +490,12 @@ and [] public FSharpField = /// If the field is from an anonymous record type then get the details of the field including the index in the sorted array of fields member AnonRecordFieldDetails: FSharpAnonRecordTypeDetails * FSharpType[] * int + /// Indicates if the field is declared in a union case + member IsUnionCaseField: bool + + /// Returns the declaring union case symbol + member DeclaringUnionCase: FSharpUnionCase option + /// Indicates if the field is declared 'static' member IsMutable: bool @@ -462,8 +518,8 @@ and [] public FSharpField = /// This API returns true for source defined symbols only. member IsNameGenerated: bool - /// Get the in-memory XML documentation for the field, used when code is checked in-memory - member XmlDoc: IList + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc /// Get the XML documentation signature for .xml file lookup for the field, used for .xml file lookup for compiled code member XmlDocSig: string @@ -481,48 +537,50 @@ and [] public FSharpField = member FieldAttributes: IList /// Get the name of the field - member Name : string + member Name: string /// Get the default initialization info, for static literals member LiteralValue: obj option /// Indicates if the declared visibility of the field, not taking signatures into account - member Accessibility: FSharpAccessibility + override Accessibility: FSharpAccessibility /// Indicates if the record field is for a type in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// Represents the rights of a compilation to access symbols -and [] public FSharpAccessibilityRights = - internal new : CcuThunk * AccessorDomain -> FSharpAccessibilityRights - member internal Contents : AccessorDomain +[] +type FSharpAccessibilityRights = + internal new: CcuThunk * AccessorDomain -> FSharpAccessibilityRights + member internal Contents: AccessorDomain /// A subtype of FSharpSymbol that represents a generic parameter for an FSharpSymbol -and [] public FSharpGenericParameter = +[] +type FSharpGenericParameter = inherit FSharpSymbol - internal new : SymbolEnv * Typar -> FSharpGenericParameter + internal new: SymbolEnv * Typar -> FSharpGenericParameter /// Get the name of the generic parameter member Name: string /// Get the range of the generic parameter - member DeclarationLocation : range + member DeclarationLocation: range /// Indicates if this is a measure variable - member IsMeasure : bool + member IsMeasure: bool + + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc - /// Get the in-memory XML documentation for the type parameter, used when code is checked in-memory - member XmlDoc : IList - /// Indicates if this is a statically resolved type variable - member IsSolveAtCompileTime : bool + member IsSolveAtCompileTime: bool /// Indicates if this is a compiler generated type parameter - member IsCompilerGenerated : bool + member IsCompilerGenerated: bool /// Get the declared attributes of the type parameter. - member Attributes: IList + override Attributes: IList /// Get the declared or inferred constraints for the type parameter member Constraints: IList @@ -530,7 +588,8 @@ and [] public FSharpGenericParameter = #if !NO_EXTENSIONTYPING /// A subtype of FSharpSymbol that represents a static parameter to an F# type provider -and [] public FSharpStaticParameter = +[] +type FSharpStaticParameter = inherit FSharpSymbol @@ -538,124 +597,128 @@ and [] public FSharpStaticParameter = member Name: string /// Get the declaration location of the static parameter - member DeclarationLocation : range + member DeclarationLocation: range /// Get the kind of the static parameter - member Kind : FSharpType + member Kind: FSharpType /// Get the default value for the static parameter - member DefaultValue : obj + member DefaultValue: obj /// Indicates if the static parameter is optional - member IsOptional : bool + member IsOptional: bool - [] - member HasDefaultValue : bool + [] + member HasDefaultValue: bool #endif + /// Get the range of the construct + member Range: range + /// Represents further information about a member constraint on a generic type parameter -and [] public FSharpGenericParameterMemberConstraint = +[] +type FSharpGenericParameterMemberConstraint = /// Get the types that may be used to satisfy the constraint - member MemberSources : IList + member MemberSources: IList /// Get the name of the method required by the constraint - member MemberName : string + member MemberName: string /// Indicates if the the method required by the constraint must be static - member MemberIsStatic : bool + member MemberIsStatic: bool /// Get the argument types of the method required by the constraint - member MemberArgumentTypes : IList + member MemberArgumentTypes: IList /// Get the return type of the method required by the constraint - member MemberReturnType : FSharpType + member MemberReturnType: FSharpType /// Represents further information about a delegate constraint on a generic type parameter -and [] public FSharpGenericParameterDelegateConstraint = +[] +type FSharpGenericParameterDelegateConstraint = /// Get the tupled argument type required by the constraint - member DelegateTupledArgumentType : FSharpType + member DelegateTupledArgumentType: FSharpType /// Get the return type required by the constraint - member DelegateReturnType : FSharpType + member DelegateReturnType: FSharpType /// Represents further information about a 'defaults to' constraint on a generic type parameter -and [] public FSharpGenericParameterDefaultsToConstraint = +[] +type FSharpGenericParameterDefaultsToConstraint = /// Get the priority off the 'defaults to' constraint - member DefaultsToPriority : int + member DefaultsToPriority: int /// Get the default type associated with the 'defaults to' constraint - member DefaultsToTarget : FSharpType + member DefaultsToTarget: FSharpType /// Represents a constraint on a generic type parameter -and [] public FSharpGenericParameterConstraint = +[] +type FSharpGenericParameterConstraint = /// Indicates a constraint that a type is a subtype of the given type - member IsCoercesToConstraint : bool + member IsCoercesToConstraint: bool /// Gets further information about a coerces-to constraint - member CoercesToTarget : FSharpType + member CoercesToTarget: FSharpType /// Indicates a default value for an inference type variable should it be neither generalized nor solved - member IsDefaultsToConstraint : bool + member IsDefaultsToConstraint: bool /// Gets further information about a defaults-to constraint - member DefaultsToConstraintData : FSharpGenericParameterDefaultsToConstraint + member DefaultsToConstraintData: FSharpGenericParameterDefaultsToConstraint /// Indicates a constraint that a type has a 'null' value - member IsSupportsNullConstraint : bool + member IsSupportsNullConstraint: bool /// Indicates a constraint that a type supports F# generic comparison - member IsComparisonConstraint : bool + member IsComparisonConstraint: bool /// Indicates a constraint that a type supports F# generic equality - member IsEqualityConstraint : bool + member IsEqualityConstraint: bool /// Indicates a constraint that a type is an unmanaged type - member IsUnmanagedConstraint : bool + member IsUnmanagedConstraint: bool /// Indicates a constraint that a type has a member with the given signature - member IsMemberConstraint : bool + member IsMemberConstraint: bool /// Gets further information about a member constraint - member MemberConstraintData : FSharpGenericParameterMemberConstraint + member MemberConstraintData: FSharpGenericParameterMemberConstraint /// Indicates a constraint that a type is a non-Nullable value type - member IsNonNullableValueTypeConstraint : bool + member IsNonNullableValueTypeConstraint: bool /// Indicates a constraint that a type is a reference type - member IsReferenceTypeConstraint : bool + member IsReferenceTypeConstraint: bool /// Indicates a constraint that is a type is a simple choice between one of the given ground types. Used by printf format strings. - member IsSimpleChoiceConstraint : bool + member IsSimpleChoiceConstraint: bool /// Gets further information about a choice constraint - member SimpleChoices : IList + member SimpleChoices: IList /// Indicates a constraint that a type has a parameterless constructor - member IsRequiresDefaultConstructorConstraint : bool + member IsRequiresDefaultConstructorConstraint: bool /// Indicates a constraint that a type is an enum with the given underlying - member IsEnumConstraint : bool + member IsEnumConstraint: bool /// Gets further information about an enumeration constraint - member EnumConstraintTarget : FSharpType + member EnumConstraintTarget: FSharpType /// Indicates a constraint that a type is a delegate from the given tuple of args to the given return type - member IsDelegateConstraint : bool + member IsDelegateConstraint: bool /// Gets further information about a delegate constraint - member DelegateConstraintData : FSharpGenericParameterDelegateConstraint - - -and [] public FSharpInlineAnnotation = + member DelegateConstraintData: FSharpGenericParameterDelegateConstraint - /// Indicates the value is inlined and compiled code for the function does not exist - | PseudoValue +[] +type FSharpInlineAnnotation = - /// Indicates the value is inlined but compiled code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined + /// Indicates the value is always inlined in statically compiled code | AlwaysInline /// Indicates the value is optionally inlined @@ -668,17 +731,18 @@ and [] public FSharpInlineAnnotation = | AggressiveInline /// A subtype of F# symbol that represents an F# method, property, event, function or value, including extension members. -and [] public FSharpMemberOrFunctionOrValue = +[] +type FSharpMemberOrFunctionOrValue = inherit FSharpSymbol - internal new : SymbolEnv * ValRef -> FSharpMemberOrFunctionOrValue - internal new : SymbolEnv * Infos.MethInfo -> FSharpMemberOrFunctionOrValue + internal new: SymbolEnv * ValRef -> FSharpMemberOrFunctionOrValue + internal new: SymbolEnv * Infos.MethInfo -> FSharpMemberOrFunctionOrValue /// Indicates if the member, function or value is in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// Get the enclosing entity for the definition - member DeclaringEntity : FSharpEntity option + member DeclaringEntity: FSharpEntity option /// Get the logical enclosing entity, which for an extension member is type being extended member ApparentEnclosingEntity: FSharpEntity @@ -693,58 +757,55 @@ and [] public FSharpMemberOrFunctionOrValue = member FullType: FSharpType /// Indicates if this is a compiler generated value - member IsCompilerGenerated : bool + member IsCompilerGenerated: bool /// Get a result indicating if this is a must-inline value - member InlineAnnotation : FSharpInlineAnnotation + member InlineAnnotation: FSharpInlineAnnotation /// Indicates if this is a mutable value - member IsMutable : bool + member IsMutable: bool /// Indicates if this is a module or member value - member IsModuleValueOrMember : bool + member IsModuleValueOrMember: bool /// Indicates if this is an extension member? - member IsExtensionMember : bool - - [] - member IsOverrideOrExplicitMember : bool + member IsExtensionMember: bool /// Indicates if this is an 'override', 'default' or an explicit implementation of an interface member - member IsOverrideOrExplicitInterfaceImplementation : bool + member IsOverrideOrExplicitInterfaceImplementation: bool /// Indicates if this is an explicit implementation of an interface member - member IsExplicitInterfaceImplementation : bool + member IsExplicitInterfaceImplementation: bool /// Gets the list of the abstract slot signatures implemented by the member - member ImplementedAbstractSignatures : IList + member ImplementedAbstractSignatures: IList /// Indicates if this is a member, including extension members? - member IsMember : bool + member IsMember: bool /// Indicates if this is a property member - member IsProperty : bool + member IsProperty: bool /// Indicates if this is a property and there exists an associated getter method - member HasGetterMethod : bool + member HasGetterMethod: bool /// Get an associated getter method of the property - member GetterMethod : FSharpMemberOrFunctionOrValue + member GetterMethod: FSharpMemberOrFunctionOrValue /// Indicates if this is a property and there exists an associated setter method - member HasSetterMethod : bool + member HasSetterMethod: bool /// Get an associated setter method of the property - member SetterMethod : FSharpMemberOrFunctionOrValue + member SetterMethod: FSharpMemberOrFunctionOrValue /// Get an associated add method of an event - member EventAddMethod : FSharpMemberOrFunctionOrValue + member EventAddMethod: FSharpMemberOrFunctionOrValue /// Get an associated remove method of an event - member EventRemoveMethod : FSharpMemberOrFunctionOrValue + member EventRemoveMethod: FSharpMemberOrFunctionOrValue /// Get an associated delegate type of an event - member EventDelegateType : FSharpType + member EventDelegateType: FSharpType /// Indicate if an event can be considered to be a property for the F# type system of type IEvent or IDelegateEvent. /// In this case ReturnParameter will have a type corresponding to the property type. For @@ -752,25 +813,17 @@ and [] public FSharpMemberOrFunctionOrValue = member EventIsStandard: bool /// Indicates if this is an event member - member IsEvent : bool + member IsEvent: bool /// Gets the event symbol implied by the use of a property, /// for the case where the property is actually an F#-declared CLIEvent. /// /// Uses of F#-declared events are considered to be properties as far as the language specification /// and this API are concerned. - member EventForFSharpProperty : FSharpMemberOrFunctionOrValue option + member EventForFSharpProperty: FSharpMemberOrFunctionOrValue option /// Indicates if this is an abstract member? - member IsDispatchSlot : bool - - /// Indicates if this is a getter method for a property, or a use of a property in getter mode - [] - member IsGetterMethod: bool - - /// Indicates if this is a setter method for a property, or a use of a property in setter mode - [] - member IsSetterMethod: bool + member IsDispatchSlot: bool /// Indicates if this is a getter method for a property, or a use of a property in getter mode member IsPropertyGetterMethod: bool @@ -785,22 +838,22 @@ and [] public FSharpMemberOrFunctionOrValue = member IsEventRemoveMethod: bool /// Indicates if this is an instance member, when seen from F#? - member IsInstanceMember : bool + member IsInstanceMember: bool /// Indicates if this is an instance member in compiled code. /// /// Explanatory note: some members such as IsNone and IsSome on types with UseNullAsTrueValue appear /// as instance members in F# code but are compiled as static members. - member IsInstanceMemberInCompiledCode : bool + member IsInstanceMemberInCompiledCode: bool /// Indicates if this is an implicit constructor? - member IsImplicitConstructor : bool + member IsImplicitConstructor: bool /// Indicates if this is an F# type function - member IsTypeFunction : bool + member IsTypeFunction: bool /// Indicates if this value or member is an F# active pattern - member IsActivePattern : bool + member IsActivePattern: bool /// Get the member name in compiled code member CompiledName: string @@ -809,56 +862,75 @@ and [] public FSharpMemberOrFunctionOrValue = member LogicalName: string /// Get the name as presented in F# error messages and documentation - member DisplayName : string + member DisplayName: string - member CurriedParameterGroups : IList> + member CurriedParameterGroups: IList> - /// Gets the overloads for the current method - /// matchParameterNumber indicates whether to filter the overloads to match the number of parameters in the current symbol - member Overloads : bool -> IList option + /// Gets the overloads for the current method. + /// + /// + /// Indicates whether to filter the overloads to match the number of parameters in the current symbol + /// + member GetOverloads: matchParameterNumber: bool -> IList option - member ReturnParameter : FSharpParameter + member ReturnParameter: FSharpParameter /// Custom attributes attached to the value. These contain references to other values (i.e. constructors in types). Mutable to fixup /// these value references after copying a collection of values. - member Attributes: IList + override Attributes: IList - /// Get the in-memory XML documentation for the value, used when code is checked in-memory - member XmlDoc: IList + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc /// XML documentation signature for the value, used for .xml file lookup for compiled code member XmlDocSig: string /// Indicates if this is "base" in "base.M(...)" - member IsBaseValue : bool + member IsBaseValue: bool /// Indicates if this is the "x" in "type C() as x = ..." - member IsConstructorThisValue : bool + member IsConstructorThisValue: bool /// Indicates if this is the "x" in "member x.M = ..." - member IsMemberThisValue : bool + member IsMemberThisValue: bool /// Indicates if this is a [] value, and if so what value? (may be null) - member LiteralValue : obj option + member LiteralValue: obj option /// Get the accessibility information for the member, function or value - member Accessibility : FSharpAccessibility + override Accessibility: FSharpAccessibility /// Indicated if this is a value compiled to a method - member IsValCompiledAsMethod : bool + member IsValCompiledAsMethod: bool + + /// Indicates if this is a function + member IsFunction: bool /// Indicated if this is a value - member IsValue : bool + member IsValue: bool /// Indicates if this is a constructor. - member IsConstructor : bool + member IsConstructor: bool /// Format the type using the rules of the given display context - member FormatLayout : context: FSharpDisplayContext -> Layout + member FormatLayout: context: FSharpDisplayContext -> TaggedText[] + + /// Check if this method has an entrpoint that accepts witness arguments and if so return + /// the name of that entrypoint and information about the additional witness arguments + member GetWitnessPassingInfo: unit -> (string * IList) option + /// Safe version of `FullType`. + member FullTypeSafe : FSharpType option + + /// Full name with last part replaced with display name. + member TryGetFullDisplayName : unit -> string option + + /// Full operator compiled name. + member TryGetFullCompiledOperatorNameIdents : unit -> string[] option /// A subtype of FSharpSymbol that represents a parameter -and [] public FSharpParameter = +[] +type FSharpParameter = inherit FSharpSymbol @@ -866,13 +938,13 @@ and [] public FSharpParameter = member Name: string option /// The declaration location of the parameter - member DeclarationLocation : range + member DeclarationLocation: range /// The declared or inferred type of the parameter - member Type : FSharpType + member Type: FSharpType /// The declared attributes of the parameter - member Attributes: IList + override Attributes: IList /// Indicate this is a param array argument member IsParamArrayArg: bool @@ -888,7 +960,8 @@ and [] public FSharpParameter = /// A subtype of FSharpSymbol that represents a single case within an active pattern -and [] public FSharpActivePatternCase = +[] +type FSharpActivePatternCase = inherit FSharpSymbol @@ -899,19 +972,20 @@ and [] public FSharpActivePatternCase = member Index: int /// The location of declaration of the active pattern case - member DeclarationLocation : range + member DeclarationLocation: range /// The group of active pattern cases this belongs to - member Group : FSharpActivePatternGroup + member Group: FSharpActivePatternGroup - /// Get the in-memory XML documentation for the active pattern case, used when code is checked in-memory - member XmlDoc: IList + /// Get the XML documentation for the entity + member XmlDoc: FSharpXmlDoc /// XML documentation signature for the active pattern case, used for .xml file lookup for compiled code member XmlDocSig: string /// Represents all cases within an active pattern -and [] public FSharpActivePatternGroup = +[] +type FSharpActivePatternGroup = /// The whole group name member Name: string option @@ -920,46 +994,47 @@ and [] public FSharpActivePatternGroup = member Names: IList /// Indicate this is a total active pattern - member IsTotal : bool + member IsTotal: bool /// Get the type indicating signature of the active pattern - member OverallType : FSharpType + member OverallType: FSharpType /// Try to get the entity in which the active pattern is declared - member DeclaringEntity : FSharpEntity option + member DeclaringEntity: FSharpEntity option -and [] public FSharpType = +[] +type FSharpType = /// Internal use only. Create a ground type. - internal new : g:TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * ty:TType -> FSharpType - internal new : SymbolEnv * ty:TType -> FSharpType + internal new: g:TcGlobals * thisCcu: CcuThunk * thisCcuTyp: ModuleOrNamespaceType * tcImports: TcImports * ty:TType -> FSharpType + internal new: SymbolEnv * ty:TType -> FSharpType /// Indicates this is a named type in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// Indicates this is an abbreviation for another type - member IsAbbreviation : bool + member IsAbbreviation: bool /// Get the type for which this is an abbreviation - member AbbreviatedType : FSharpType + member AbbreviatedType: FSharpType /// Indicates if the type is constructed using a named entity, including array and byref types - member HasTypeDefinition : bool + member HasTypeDefinition: bool /// Get the type definition for a type - member TypeDefinition : FSharpEntity + member TypeDefinition: FSharpEntity /// Get the generic arguments for a tuple type, a function type or a type constructed using a named entity - member GenericArguments : IList + member GenericArguments: IList /// Indicates if the type is a tuple type (reference or struct). The GenericArguments property returns the elements of the tuple type. - member IsTupleType : bool + member IsTupleType: bool /// Indicates if the type is a struct tuple type. The GenericArguments property returns the elements of the tuple type. - member IsStructTupleType : bool + member IsStructTupleType: bool /// Indicates if the type is a function type. The GenericArguments property returns the domain and range of the function type. - member IsFunctionType : bool + member IsFunctionType: bool /// Indicates if the type is an anonymous record type. The GenericArguments property returns the type instantiation of the anonymous record type member IsAnonRecordType: bool @@ -968,85 +1043,97 @@ and [] public FSharpType = member AnonRecordTypeDetails: FSharpAnonRecordTypeDetails /// Indicates if the type is a variable type, whether declared, generalized or an inference type parameter - member IsGenericParameter : bool + member IsGenericParameter: bool /// Get the generic parameter data for a generic parameter type - member GenericParameter : FSharpGenericParameter + member GenericParameter: FSharpGenericParameter - /// Format the type using the rules of the given display context - member Format : context: FSharpDisplayContext -> string + /// Format the type using the rules of the given display context, skipping type constraints + member Format: context: FSharpDisplayContext -> string + + /// Format the type using the rules of the given display context + member FormatWithConstraints: context: FSharpDisplayContext -> string /// Format the type using the rules of the given display context - member FormatLayout : context: FSharpDisplayContext -> Layout + member FormatLayout: context: FSharpDisplayContext -> TaggedText[] + + /// Format the type - with constraints - using the rules of the given display context + member FormatLayoutWithConstraints: context: FSharpDisplayContext -> TaggedText[] /// Instantiate generic type parameters in a type - member Instantiate : (FSharpGenericParameter * FSharpType) list -> FSharpType + member Instantiate: (FSharpGenericParameter * FSharpType) list -> FSharpType /// Get all the interface implementations, by walking the type hierarchy, taking into account the instantiation of this type /// if it is an instantiation of a generic type. - member AllInterfaces : IList + member AllInterfaces: IList /// Get the base type, if any, taking into account the instantiation of this type /// if it is an instantiation of a generic type. - member BaseType : FSharpType option + member BaseType: FSharpType option /// Adjust the type by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : ty:FSharpType -> FSharpType + static member Prettify: ty:FSharpType -> FSharpType /// Adjust a group of types by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : types: IList -> IList + static member Prettify: types: IList -> IList /// Adjust the type in a single parameter by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : parameter: FSharpParameter -> FSharpParameter + static member Prettify: parameter: FSharpParameter -> FSharpParameter /// Adjust the types in a group of parameters by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : parameters: IList -> IList + static member Prettify: parameters: IList -> IList /// Adjust the types in a group of curried parameters by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : parameters: IList> -> IList> + static member Prettify: parameters: IList> -> IList> /// Adjust the types in a group of curried parameters and return type by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. - static member Prettify : parameters: IList> * returnParameter: FSharpParameter -> IList> * FSharpParameter - - [] - member IsNamedType : bool - - [] - member NamedEntity : FSharpEntity + static member Prettify: parameters: IList> * returnParameter: FSharpParameter -> IList> * FSharpParameter + /// Strip any outer abbreviations from the type + member StripAbbreviations: unit -> FSharpType /// Represents a custom attribute attached to F# source code or a compiler .NET component -and [] public FSharpAttribute = +[] +type FSharpAttribute = /// The type of the attribute - member AttributeType : FSharpEntity + member AttributeType: FSharpEntity /// The arguments to the constructor for the attribute - member ConstructorArguments : IList + member ConstructorArguments: IList /// The named arguments for the attribute - member NamedArguments : IList + member NamedArguments: IList /// Indicates if the attribute type is in an unresolved assembly - member IsUnresolved : bool + member IsUnresolved: bool /// Format the attribute using the rules of the given display context - member Format : context: FSharpDisplayContext -> string + member Format: context: FSharpDisplayContext -> string + + /// Get the range of the name of the attribute + member Range: range + + /// Indicates if attribute matchies the full name of the given type parameter + member IsAttribute<'T> : unit -> bool /// Represents open declaration in F# code. [] -type public FSharpOpenDeclaration = +type FSharpOpenDeclaration = + + internal new: target: SynOpenDeclTarget * range: range option * modules: FSharpEntity list * types: FSharpType list * appliedScope: range * isOwnNamespace: bool -> FSharpOpenDeclaration - internal new : longId: Ident list * range: range option * modules: FSharpEntity list * appliedScope: range * isOwnNamespace: bool -> FSharpOpenDeclaration + /// The syntactic target of the declaration + member LongId: Ident list - /// Idents. - member LongId: Ident list + /// The syntactic target of the declaration + member Target: SynOpenDeclTarget /// Range of the open declaration. member Range: range option @@ -1054,50 +1141,11 @@ type public FSharpOpenDeclaration = /// Modules or namespaces which is opened with this declaration. member Modules: FSharpEntity list + /// Types whose static members and nested types is opened with this declaration. + member Types: FSharpType list + /// Scope in which open declaration is visible. member AppliedScope: range /// If it's `namespace Xxx.Yyy` declaration. member IsOwnNamespace: bool - -/// Represents the use of an F# symbol from F# source code -[] -type public FSharpSymbolUse = - - // For internal use only - internal new : g:TcGlobals * denv: Tastops.DisplayEnv * symbol:FSharpSymbol * itemOcc:ItemOccurence * range: range -> FSharpSymbolUse - - /// The symbol referenced - member Symbol : FSharpSymbol - - /// The display context active at the point where the symbol is used. Can be passed to FSharpType.Format - /// and other methods to format items in a way that is suitable for a specific source code location. - member DisplayContext : FSharpDisplayContext - - /// Indicates if the reference is a definition for the symbol, either in a signature or implementation - member IsFromDefinition : bool - - /// Indicates if the reference is in a pattern - member IsFromPattern : bool - - /// Indicates if the reference is in a syntactic type - member IsFromType : bool - - /// Indicates if the reference is in an attribute - member IsFromAttribute : bool - - /// Indicates if the reference is via the member being implemented in a class or object expression - member IsFromDispatchSlotImplementation : bool - - /// Indicates if the reference is either a builder or a custom operation in a computation expression - member IsFromComputationExpression : bool - - /// Indicates if the reference is in open statement - member IsFromOpenStatement : bool - - /// The file name the reference occurs in - member FileName: string - - /// The range of text representing the reference to the symbol - member RangeAlternate: range - diff --git a/src/fsharp/tainted.fs b/src/fsharp/tainted.fs index 15d2378b3fb..eb9cf01522c 100644 --- a/src/fsharp/tainted.fs +++ b/src/fsharp/tainted.fs @@ -5,33 +5,41 @@ namespace FSharp.Compiler #if !NO_EXTENSIONTYPING open System -open FSharp.Compiler.Range -open Microsoft.FSharp.Core.CompilerServices +open Internal.Utilities.Library +open FSharp.Core.CompilerServices open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range -type internal TypeProviderError +[] +type internal TypeProviderToken() = interface LockToken + +[] +type internal TypeProviderLock() = + inherit Lock() + +type TypeProviderError ( - errNum : int, - tpDesignation : string, - m:FSharp.Compiler.Range.range, - errors : string list, - typeNameContext : string option, - methodNameContext : string option + errNum: int, + tpDesignation: string, + m: range, + errors: string list, + typeNameContext: string option, + methodNameContext: string option ) = - inherit System.Exception() + inherit Exception() - new((errNum, msg : string), tpDesignation,m) = + new((errNum, msg: string), tpDesignation,m) = TypeProviderError(errNum, tpDesignation, m, [msg]) - new(errNum, tpDesignation, m, messages : seq) = + new(errNum, tpDesignation, m, messages: seq) = TypeProviderError(errNum, tpDesignation, m, List.ofSeq messages, None, None) - member this.Number = errNum - member this.Range = m + member _.Number = errNum + member _.Range = m - override this.Message = + override _.Message = match errors with | [text] -> text | inner -> @@ -40,12 +48,12 @@ type internal TypeProviderError inner |> String.concat Environment.NewLine - member this.MapText(f, tpDesignation, m) = - let (errNum : int), _ = f "" - new TypeProviderError(errNum, tpDesignation, m, (Seq.map (f >> snd) errors)) + member _.MapText(f, tpDesignation, m) = + let (errNum: int), _ = f "" + TypeProviderError(errNum, tpDesignation, m, (Seq.map (f >> snd) errors)) - member this.WithContext(typeNameContext:string, methodNameContext:string) = - new TypeProviderError(errNum, tpDesignation, m, errors, Some typeNameContext, Some methodNameContext) + member _.WithContext(typeNameContext:string, methodNameContext:string) = + TypeProviderError(errNum, tpDesignation, m, errors, Some typeNameContext, Some methodNameContext) // .Message is just the error, whereas .ContextualErrorMessage has contextual prefix information // for example if InvokeCode in provided method is not set or has value that cannot be translated -then initial TPE will be wrapped in @@ -67,12 +75,16 @@ type internal TypeProviderError | [_] -> f this | errors -> for msg in errors do - f (new TypeProviderError(errNum, tpDesignation, m, [msg], typeNameContext, methodNameContext)) + f (TypeProviderError(errNum, tpDesignation, m, [msg], typeNameContext, methodNameContext)) -type TaintedContext = { TypeProvider : ITypeProvider; TypeProviderAssemblyRef : ILScopeRef } +type TaintedContext = + { TypeProvider: ITypeProvider + TypeProviderAssemblyRef: ILScopeRef + Lock: TypeProviderLock + TypeProviderDesignation: string } [][] -type internal Tainted<'T> (context : TaintedContext, value : 'T) = +type internal Tainted<'T> (context: TaintedContext, value: 'T) = do match box context.TypeProvider with | null -> @@ -80,15 +92,15 @@ type internal Tainted<'T> (context : TaintedContext, value : 'T) = failwith "null ITypeProvider in Tainted constructor" | _ -> () - member this.TypeProviderDesignation = - context.TypeProvider.GetType().FullName + member _.TypeProviderDesignation = + context.TypeProviderDesignation - member this.TypeProviderAssemblyRef = + member _.TypeProviderAssemblyRef = context.TypeProviderAssemblyRef member this.Protect f (range:range) = try - f value + context.Lock.AcquireLock(fun _ -> f value) with | :? TypeProviderError -> reraise() | :? AggregateException as ae -> @@ -129,7 +141,6 @@ type internal Tainted<'T> (context : TaintedContext, value : 'T) = | null -> raise <| TypeProviderError(FSComp.SR.etProviderReturnedNull(methodName), this.TypeProviderDesignation, range) | _ -> a |> Array.map (fun u -> Tainted(context,u)) - member this.PApplyOption(f,range:range) = let a = this.Protect f range match a with @@ -141,9 +152,9 @@ type internal Tainted<'T> (context : TaintedContext, value : 'T) = /// Access the target object directly. Use with extreme caution. member this.AccessObjectDirectly = value - static member CreateAll(providerSpecs : (ITypeProvider * ILScopeRef) list) = - [for (tp,nm) in providerSpecs do - yield Tainted<_>({ TypeProvider=tp; TypeProviderAssemblyRef=nm },tp) ] + static member CreateAll(providerSpecs: (ITypeProvider * ILScopeRef * string) list) = + [for (tp,nm, tpd) in providerSpecs do + yield Tainted<_>({ TypeProvider = tp; TypeProviderAssemblyRef = nm; Lock=TypeProviderLock(); TypeProviderDesignation = tpd },tp) ] member this.OfType<'U> () = match box value with @@ -157,7 +168,7 @@ module internal Tainted = let (|Null|_|) (p:Tainted<'T>) = if p.PUntaintNoFailure(fun p -> match p with null -> true | _ -> false) then Some() else None - let Eq (p:Tainted<'T>) (v:'T) = p.PUntaintNoFailure((fun pv -> pv = v)) + let Eq (p:Tainted<'T>) (v:'T) = p.PUntaintNoFailure (fun pv -> pv = v) let EqTainted (t1:Tainted<'T>) (t2:Tainted<'T>) = t1.PUntaintNoFailure(fun t1 -> t1 === t2.AccessObjectDirectly) diff --git a/src/fsharp/tainted.fsi b/src/fsharp/tainted.fsi index c5220feb6cf..c1a0a3b7c8b 100644 --- a/src/fsharp/tainted.fsi +++ b/src/fsharp/tainted.fsi @@ -4,15 +4,21 @@ namespace FSharp.Compiler #if !NO_EXTENSIONTYPING - -open System -open System.Reflection -open Microsoft.FSharp.Core.CompilerServices -open FSharp.Compiler.Range +open Internal.Utilities.Library +open FSharp.Core.CompilerServices open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.Text + +[] +type internal TypeProviderToken = + interface LockToken + +[] +type internal TypeProviderLock = + inherit Lock /// Stores and transports aggregated list of errors reported by the type provider -type internal TypeProviderError = +type TypeProviderError = inherit System.Exception /// creates new instance of TypeProviderError that represents one error @@ -42,7 +48,7 @@ type internal TypeProviderError = type internal Tainted<'T> = /// Create an initial tainted value - static member CreateAll : (ITypeProvider * ILScopeRef) list -> Tainted list + static member CreateAll : (ITypeProvider * ILScopeRef * string) list -> Tainted list /// A type provider that produced the value member TypeProvider : Tainted @@ -91,7 +97,6 @@ type internal Tainted<'T> = /// If coercion fails, the failure will be blamed on a type provider member Coerce<'U> : range:range -> Tainted<'U> - [] module internal Tainted = diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs deleted file mode 100644 index a6d5ae499ad..00000000000 --- a/src/fsharp/tast.fs +++ /dev/null @@ -1,5927 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -//------------------------------------------------------------------------- -// Defines the typed abstract syntax trees used throughout the F# compiler. -//------------------------------------------------------------------------- - -module internal FSharp.Compiler.Tast - -open System -open System.Collections.Generic -open System.Diagnostics -open System.Reflection -open Internal.Utilities -open FSharp.Compiler.AbstractIL -open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.AbstractIL.Internal -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.AbstractIL.Extensions.ILX.Types - -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.Ast -open FSharp.Compiler.ErrorLogger -open FSharp.Compiler.Lib -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.QuotationPickler -open Microsoft.FSharp.Core.Printf -open FSharp.Compiler.Rational - -#if !NO_EXTENSIONTYPING -open FSharp.Compiler.ExtensionTyping -open Microsoft.FSharp.Core.CompilerServices -#endif - -/// Unique name generator for stamps attached to lambdas and object expressions -type Unique = int64 - -//++GLOBAL MUTABLE STATE (concurrency-safe) -let newUnique = let i = ref 0L in fun () -> System.Threading.Interlocked.Increment i - -type Stamp = int64 - -/// Unique name generator for stamps attached to to val_specs, tycon_specs etc. -//++GLOBAL MUTABLE STATE (concurrency-safe) -let newStamp = let i = ref 0L in fun () -> System.Threading.Interlocked.Increment i - -type StampMap<'T> = Map - -//------------------------------------------------------------------------- -// Flags - -[] -type ValInline = - - /// Indicates the value must always be inlined and no .NET IL code is generated for the value/function - | PseudoVal - - /// Indicates the value is inlined but the .NET IL code for the function still exists, e.g. to satisfy interfaces on objects, but that it is also always inlined - | Always - - /// Indicates the value may optionally be inlined by the optimizer - | Optional - - /// Indicates the value must never be inlined by the optimizer - | Never - - /// Returns true if the implementation of a value must always be inlined - member x.MustInline = - match x with - | ValInline.PseudoVal | ValInline.Always -> true - | ValInline.Optional | ValInline.Never -> false - -/// A flag associated with values that indicates whether the recursive scope of the value is currently being processed, and -/// if the value has been generalized or not as yet. -type ValRecursiveScopeInfo = - - /// Set while the value is within its recursive scope. The flag indicates if the value has been eagerly generalized and accepts generic-recursive calls - | ValInRecScope of bool - - /// The normal value for this flag when the value is not within its recursive scope - | ValNotInRecScope - -type ValMutability = - | Immutable - | Mutable - -[] -/// Indicates if a type parameter is needed at runtime and may not be eliminated -type TyparDynamicReq = - - /// Indicates the type parameter is not needed at runtime and may be eliminated - | No - - /// Indicates the type parameter is needed at runtime and may not be eliminated - | Yes - -type ValBaseOrThisInfo = - - /// Indicates a ref-cell holding 'this' or the implicit 'this' used throughout an - /// implicit constructor to access and set values - | CtorThisVal - - /// Indicates the value called 'base' available for calling base class members - | BaseVal - - /// Indicates a normal value - | NormalVal - - /// Indicates the 'this' value specified in a memberm e.g. 'x' in 'member x.M() = 1' - | MemberThisVal - -[] -/// Flags on values -type ValFlags(flags: int64) = - - new (recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal) = - let flags = - (match baseOrThis with - | BaseVal -> 0b00000000000000000000L - | CtorThisVal -> 0b00000000000000000010L - | NormalVal -> 0b00000000000000000100L - | MemberThisVal -> 0b00000000000000000110L) ||| - (if isCompGen then 0b00000000000000001000L - else 0b000000000000000000000L) ||| - (match inlineInfo with - | ValInline.PseudoVal -> 0b00000000000000000000L - | ValInline.Always -> 0b00000000000000010000L - | ValInline.Optional -> 0b00000000000000100000L - | ValInline.Never -> 0b00000000000000110000L) ||| - (match isMutable with - | Immutable -> 0b00000000000000000000L - | Mutable -> 0b00000000000001000000L) ||| - - (match isModuleOrMemberBinding with - | false -> 0b00000000000000000000L - | true -> 0b00000000000010000000L) ||| - (match isExtensionMember with - | false -> 0b00000000000000000000L - | true -> 0b00000000000100000000L) ||| - (match isIncrClassSpecialMember with - | false -> 0b00000000000000000000L - | true -> 0b00000000001000000000L) ||| - (match isTyFunc with - | false -> 0b00000000000000000000L - | true -> 0b00000000010000000000L) ||| - - (match recValInfo with - | ValNotInRecScope -> 0b00000000000000000000L - | ValInRecScope true -> 0b00000000100000000000L - | ValInRecScope false -> 0b00000001000000000000L) ||| - - (match allowTypeInst with - | false -> 0b00000000000000000000L - | true -> 0b00000100000000000000L) ||| - - (match isGeneratedEventVal with - | false -> 0b00000000000000000000L - | true -> 0b00100000000000000000L) - - ValFlags flags - - member x.BaseOrThisInfo = - match (flags &&& 0b00000000000000000110L) with - | 0b00000000000000000000L -> BaseVal - | 0b00000000000000000010L -> CtorThisVal - | 0b00000000000000000100L -> NormalVal - | 0b00000000000000000110L -> MemberThisVal - | _ -> failwith "unreachable" - - - - member x.IsCompilerGenerated = (flags &&& 0b00000000000000001000L) <> 0x0L - - member x.SetIsCompilerGenerated isCompGen = - let flags = (flags &&& ~~~0b00000000000000001000L) ||| - (match isCompGen with - | false -> 0b00000000000000000000L - | true -> 0b00000000000000001000L) - ValFlags flags - - member x.InlineInfo = - match (flags &&& 0b00000000000000110000L) with - | 0b00000000000000000000L -> ValInline.PseudoVal - | 0b00000000000000010000L -> ValInline.Always - | 0b00000000000000100000L -> ValInline.Optional - | 0b00000000000000110000L -> ValInline.Never - | _ -> failwith "unreachable" - - member x.MutabilityInfo = - match (flags &&& 0b00000000000001000000L) with - | 0b00000000000000000000L -> Immutable - | 0b00000000000001000000L -> Mutable - | _ -> failwith "unreachable" - - - member x.IsMemberOrModuleBinding = - match (flags &&& 0b00000000000010000000L) with - | 0b00000000000000000000L -> false - | 0b00000000000010000000L -> true - | _ -> failwith "unreachable" - - - member x.WithIsMemberOrModuleBinding = ValFlags(flags ||| 0b00000000000010000000L) - - - member x.IsExtensionMember = (flags &&& 0b00000000000100000000L) <> 0L - - member x.IsIncrClassSpecialMember = (flags &&& 0b00000000001000000000L) <> 0L - - member x.IsTypeFunction = (flags &&& 0b00000000010000000000L) <> 0L - - member x.RecursiveValInfo = match (flags &&& 0b00000001100000000000L) with - | 0b00000000000000000000L -> ValNotInRecScope - | 0b00000000100000000000L -> ValInRecScope true - | 0b00000001000000000000L -> ValInRecScope false - | _ -> failwith "unreachable" - - member x.WithRecursiveValInfo recValInfo = - let flags = - (flags &&& ~~~0b00000001100000000000L) ||| - (match recValInfo with - | ValNotInRecScope -> 0b00000000000000000000L - | ValInRecScope true -> 0b00000000100000000000L - | ValInRecScope false -> 0b00000001000000000000L) - ValFlags flags - - member x.MakesNoCriticalTailcalls = (flags &&& 0b00000010000000000000L) <> 0L - - member x.WithMakesNoCriticalTailcalls = ValFlags(flags ||| 0b00000010000000000000L) - - member x.PermitsExplicitTypeInstantiation = (flags &&& 0b00000100000000000000L) <> 0L - - member x.HasBeenReferenced = (flags &&& 0b00001000000000000000L) <> 0L - - member x.WithHasBeenReferenced = ValFlags(flags ||| 0b00001000000000000000L) - - member x.IsCompiledAsStaticPropertyWithoutField = (flags &&& 0b00010000000000000000L) <> 0L - - member x.WithIsCompiledAsStaticPropertyWithoutField = ValFlags(flags ||| 0b00010000000000000000L) - - member x.IsGeneratedEventVal = (flags &&& 0b00100000000000000000L) <> 0L - - member x.IsFixed = (flags &&& 0b01000000000000000000L) <> 0L - - member x.WithIsFixed = ValFlags(flags ||| 0b01000000000000000000L) - - member x.IgnoresByrefScope = (flags &&& 0b10000000000000000000L) <> 0L - - member x.WithIgnoresByrefScope = ValFlags(flags ||| 0b10000000000000000000L) - - /// Get the flags as included in the F# binary metadata - member x.PickledBits = - // Clear the RecursiveValInfo, only used during inference and irrelevant across assembly boundaries - // Clear the IsCompiledAsStaticPropertyWithoutField, only used to determine whether to use a true field for a value, and to eliminate the optimization info for observable bindings - // Clear the HasBeenReferenced, only used to report "unreferenced variable" warnings and to help collect 'it' values in FSI.EXE - // Clear the IsGeneratedEventVal, since there's no use in propagating specialname information for generated add/remove event vals - (flags &&& ~~~0b10011001100000000000L) - -/// Represents the kind of a type parameter -[] -type TyparKind = - - | Type - - | Measure - - member x.AttrName = - match x with - | TyparKind.Type -> ValueNone - | TyparKind.Measure -> ValueSome "Measure" - - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = - match x with - | TyparKind.Type -> "type" - | TyparKind.Measure -> "measure" - -[] -/// Indicates if the type variable can be solved or given new constraints. The status of a type variable -/// evolves towards being either rigid or solved. -type TyparRigidity = - - /// Indicates the type parameter can't be solved - | Rigid - - /// Indicates the type parameter can't be solved, but the variable is not set to "rigid" until after inference is complete - | WillBeRigid - - /// Indicates we give a warning if the type parameter is ever solved - | WarnIfNotRigid - - /// Indicates the type parameter is an inference variable may be solved - | Flexible - - /// Indicates the type parameter derives from an '_' anonymous type - /// For units-of-measure, we give a warning if this gets solved to '1' - | Anon - - member x.ErrorIfUnified = match x with TyparRigidity.Rigid -> true | _ -> false - - member x.WarnIfUnified = match x with TyparRigidity.WillBeRigid | TyparRigidity.WarnIfNotRigid -> true | _ -> false - - member x.WarnIfMissingConstraint = match x with TyparRigidity.WillBeRigid -> true | _ -> false - - -/// Encode typar flags into a bit field -[] -type TyparFlags(flags: int32) = - - new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool) = - TyparFlags((if isFromError then 0b00000000000000010 else 0) ||| - (if isCompGen then 0b00000000000000100 else 0) ||| - (match staticReq with - | NoStaticReq -> 0b00000000000000000 - | HeadTypeStaticReq -> 0b00000000000001000) ||| - (match rigidity with - | TyparRigidity.Rigid -> 0b00000000000000000 - | TyparRigidity.WillBeRigid -> 0b00000000000100000 - | TyparRigidity.WarnIfNotRigid -> 0b00000000001000000 - | TyparRigidity.Flexible -> 0b00000000001100000 - | TyparRigidity.Anon -> 0b00000000010000000) ||| - (match kind with - | TyparKind.Type -> 0b00000000000000000 - | TyparKind.Measure -> 0b00000000100000000) ||| - (if comparisonDependsOn then - 0b00000001000000000 else 0) ||| - (match dynamicReq with - | TyparDynamicReq.No -> 0b00000000000000000 - | TyparDynamicReq.Yes -> 0b00000010000000000) ||| - (if equalityDependsOn then - 0b00000100000000000 else 0)) - - /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns - member x.IsFromError = (flags &&& 0b00000000000000010) <> 0x0 - - /// Indicates if the type variable is compiler generated, i.e. is an implicit type inference variable - member x.IsCompilerGenerated = (flags &&& 0b00000000000000100) <> 0x0 - - /// Indicates if the type variable has a static "head type" requirement, i.e. ^a variables used in FSharp.Core and member constraints. - member x.StaticReq = - match (flags &&& 0b00000000000001000) with - | 0b00000000000000000 -> NoStaticReq - | 0b00000000000001000 -> HeadTypeStaticReq - | _ -> failwith "unreachable" - - /// Indicates if the type variable can be solved or given new constraints. The status of a type variable - /// generally always evolves towards being either rigid or solved. - member x.Rigidity = - match (flags &&& 0b00000000011100000) with - | 0b00000000000000000 -> TyparRigidity.Rigid - | 0b00000000000100000 -> TyparRigidity.WillBeRigid - | 0b00000000001000000 -> TyparRigidity.WarnIfNotRigid - | 0b00000000001100000 -> TyparRigidity.Flexible - | 0b00000000010000000 -> TyparRigidity.Anon - | _ -> failwith "unreachable" - - /// Indicates whether a type variable can be instantiated by types or units-of-measure. - member x.Kind = - match (flags &&& 0b00001000100000000) with - | 0b00000000000000000 -> TyparKind.Type - | 0b00000000100000000 -> TyparKind.Measure - | _ -> failwith "unreachable" - - - /// Indicates that whether or not a generic type definition satisfies the comparison constraint is dependent on whether this type variable satisfies the comparison constraint. - member x.ComparisonConditionalOn = - (flags &&& 0b00000001000000000) <> 0x0 - - /// Indicates if a type parameter is needed at runtime and may not be eliminated - member x.DynamicReq = - match (flags &&& 0b00000010000000000) with - | 0b00000000000000000 -> TyparDynamicReq.No - | 0b00000010000000000 -> TyparDynamicReq.Yes - | _ -> failwith "unreachable" - - /// Indicates that whether or not a generic type definition satisfies the equality constraint is dependent on whether this type variable satisfies the equality constraint. - member x.EqualityConditionalOn = - (flags &&& 0b00000100000000000) <> 0x0 - - /// Indicates that whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) - member x.IsCompatFlex = - (flags &&& 0b00010000000000000) <> 0x0 - - member x.WithCompatFlex b = - if b then - TyparFlags(flags ||| 0b00010000000000000) - else - TyparFlags(flags &&& ~~~0b00010000000000000) - - /// Get the flags as included in the F# binary metadata. We pickle this as int64 to allow for future expansion - member x.PickledBits = flags - -/// Encode entity flags into a bit field. We leave lots of space to allow for future expansion. -[] -type EntityFlags(flags: int64) = - - new (usesPrefixDisplay, isModuleOrNamespace, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isStructRecordOrUnionType) = - EntityFlags((if isModuleOrNamespace then 0b000000000000001L else 0L) ||| - (if usesPrefixDisplay then 0b000000000000010L else 0L) ||| - (if preEstablishedHasDefaultCtor then 0b000000000000100L else 0L) ||| - (if hasSelfReferentialCtor then 0b000000000001000L else 0L) ||| - (if isStructRecordOrUnionType then 0b000000000100000L else 0L)) - - /// Indicates the Entity is actually a module or namespace, not a type definition - member x.IsModuleOrNamespace = (flags &&& 0b000000000000001L) <> 0x0L - - /// Indicates the type prefers the "tycon" syntax for display etc. - member x.IsPrefixDisplay = (flags &&& 0b000000000000010L) <> 0x0L - - // This bit is not pickled, only used while establishing a type constructor. It is needed because the type constructor - // is known to satisfy the default constructor constraint even before any of its members have been established. - member x.PreEstablishedHasDefaultConstructor = (flags &&& 0b000000000000100L) <> 0x0L - - // This bit represents an F# specific condition where a type has at least one constructor that may access - // the 'this' pointer prior to successful initialization of the partial contents of the object. In this - // case sub-classes must protect themselves against early access to their contents. - member x.HasSelfReferentialConstructor = (flags &&& 0b000000000001000L) <> 0x0L - - /// This bit is reserved for us in the pickle format, see pickle.fs, it's being listed here to stop it ever being used for anything else - static member ReservedBitForPickleFormatTyconReprFlag = 0b000000000010000L - - /// This bit represents a F# record that is a value type, or a struct record. - member x.IsStructRecordOrUnionType = (flags &&& 0b000000000100000L) <> 0x0L - - /// These two bits represents the on-demand analysis about whether the entity has the IsByRefLike attribute - member x.TryIsByRefLike = (flags &&& 0b000000011000000L) - |> function - | 0b000000011000000L -> ValueSome true - | 0b000000010000000L -> ValueSome false - | _ -> ValueNone - - /// Adjust the on-demand analysis about whether the entity has the IsByRefLike attribute - member x.WithIsByRefLike flag = - let flags = - (flags &&& ~~~0b000000011000000L) ||| - (match flag with - | true -> 0b000000011000000L - | false -> 0b000000010000000L) - EntityFlags flags - - /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute - member x.TryIsReadOnly = (flags &&& 0b000001100000000L) - |> function - | 0b000001100000000L -> ValueSome true - | 0b000001000000000L -> ValueSome false - | _ -> ValueNone - - /// Adjust the on-demand analysis about whether the entity has the IsReadOnly attribute - member x.WithIsReadOnly flag = - let flags = - (flags &&& ~~~0b000001100000000L) ||| - (match flag with - | true -> 0b000001100000000L - | false -> 0b000001000000000L) - EntityFlags flags - - /// These two bits represents the on-demand analysis about whether the entity is assumed to be a readonly struct - member x.TryIsAssumedReadOnly = (flags &&& 0b000110000000000L) - |> function - | 0b000110000000000L -> ValueSome true - | 0b000100000000000L -> ValueSome false - | _ -> ValueNone - - /// Adjust the on-demand analysis about whether the entity is assumed to be a readonly struct - member x.WithIsAssumedReadOnly flag = - let flags = - (flags &&& ~~~0b000110000000000L) ||| - (match flag with - | true -> 0b000110000000000L - | false -> 0b000100000000000L) - EntityFlags flags - - /// Get the flags as included in the F# binary metadata - member x.PickledBits = (flags &&& ~~~0b000111111000100L) - - -#if DEBUG -assert (sizeof = 8) -assert (sizeof = 8) -assert (sizeof = 4) -#endif - -let unassignedTyparName = "?" - -exception UndefinedName of int * (* error func that expects identifier name *)(string -> string) * Ident * ErrorLogger.Suggestions -exception InternalUndefinedItemRef of (string * string * string -> int * string) * string * string * string - -let KeyTyconByDemangledNameAndArity nm (typars: _ list) x = - KeyValuePair(NameArityPair(DemangleGenericTypeName nm, typars.Length), x) - -/// Generic types can be accessed either by 'List' or 'List`1'. This lists both keys. The second form should really be deprecated. -let KeyTyconByAccessNames nm x = - match TryDemangleGenericNameAndPos nm with - | ValueSome pos -> - let dnm = DemangleGenericTypeNameWithPos pos nm - [| KeyValuePair(nm, x); KeyValuePair(dnm, x) |] - | _ -> - [| KeyValuePair(nm, x) |] - -type ModuleOrNamespaceKind = - - /// Indicates that a module is compiled to a class with the "Module" suffix added. - | FSharpModuleWithSuffix - - /// Indicates that a module is compiled to a class with the same name as the original module - | ModuleOrType - - /// Indicates that a 'module' is really a namespace - | Namespace - -let getNameOfScopeRef sref = - match sref with - | ILScopeRef.Local -> "" - | ILScopeRef.Module mref -> mref.Name - | ILScopeRef.Assembly aref -> aref.Name - | ILScopeRef.PrimaryAssembly -> "" - -#if !NO_EXTENSIONTYPING -let ComputeDefinitionLocationOfProvidedItem (p: Tainted<#IProvidedCustomAttributeProvider>) = - let attrs = p.PUntaintNoFailure(fun x -> x.GetDefinitionLocationAttribute(p.TypeProvider.PUntaintNoFailure id)) - match attrs with - | None | Some (null, _, _) -> None - | Some (filePath, line, column) -> - // Coordinates from type provider are 1-based for lines and columns - // Coordinates internally in the F# compiler are 1-based for lines and 0-based for columns - let pos = Range.mkPos line (max 0 (column - 1)) - Range.mkRange filePath pos pos |> Some - -#endif - -/// A public path records where a construct lives within the global namespace -/// of a CCU. -type PublicPath = - | PubPath of string[] - member x.EnclosingPath = - let (PubPath pp) = x - assert (pp.Length >= 1) - pp.[0..pp.Length-2] - - -/// The information ILXGEN needs about the location of an item -type CompilationPath = - | CompPath of ILScopeRef * (string * ModuleOrNamespaceKind) list - - member x.ILScopeRef = (let (CompPath(scoref, _)) = x in scoref) - - member x.AccessPath = (let (CompPath(_, p)) = x in p) - - member x.MangledPath = List.map fst x.AccessPath - - member x.NestedPublicPath (id: Ident) = PubPath(Array.append (Array.ofList x.MangledPath) [| id.idText |]) - - member x.ParentCompPath = - let a, _ = List.frontAndBack x.AccessPath - CompPath(x.ILScopeRef, a) - - member x.NestedCompPath n modKind = CompPath(x.ILScopeRef, x.AccessPath@[(n, modKind)]) - - member x.DemangledPath = - x.AccessPath |> List.map (fun (nm, k) -> CompilationPath.DemangleEntityName nm k) - - /// String 'Module' off an F# module name, if FSharpModuleWithSuffix is used - static member DemangleEntityName nm k = - match k with - | FSharpModuleWithSuffix -> String.dropSuffix nm FSharpModuleSuffix - | _ -> nm - - - -[] -type EntityOptionalData = - { - /// The name of the type, possibly with `n mangling - // MUTABILITY; used only when establishing tycons. - mutable entity_compiled_name: string option - - // MUTABILITY: the signature is adjusted when it is checked - /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is - /// the signature range for an item in an implementation - mutable entity_other_range: (range * bool) option - - // MUTABILITY; used only when establishing tycons. - mutable entity_kind: TyparKind - - /// The declared documentation for the type or module - // MUTABILITY: only for unpickle linkage - mutable entity_xmldoc: XmlDoc - - /// The XML document signature for this entity - mutable entity_xmldocsig: string - - /// If non-None, indicates the type is an abbreviation for another type. - // - // MUTABILITY; used only during creation and remapping of tycons - mutable entity_tycon_abbrev: TType option - - /// The declared accessibility of the representation, not taking signatures into account - mutable entity_tycon_repr_accessibility: Accessibility - - /// Indicates how visible is the entity is. - // MUTABILITY: only for unpickle linkage - mutable entity_accessibility: Accessibility - - /// Field used when the 'tycon' is really an exception definition - // - // MUTABILITY; used only during creation and remapping of tycons - mutable entity_exn_info: ExceptionInfo - } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "EntityOptionalData(...)" - -and /// Represents a type definition, exception definition, module definition or namespace definition. - [] - Entity = - { /// The declared type parameters of the type - // MUTABILITY; used only during creation and remapping of tycons - mutable entity_typars: LazyWithContext - - mutable entity_flags: EntityFlags - - /// The unique stamp of the "tycon blob". Note the same tycon in signature and implementation get different stamps - // MUTABILITY: only for unpickle linkage - mutable entity_stamp: Stamp - - /// The name of the type, possibly with `n mangling - // MUTABILITY: only for unpickle linkage - mutable entity_logical_name: string - - /// The declaration location for the type constructor - mutable entity_range: range - - /// The declared attributes for the type - // MUTABILITY; used during creation and remapping of tycons - // MUTABILITY; used when propagating signature attributes into the implementation. - mutable entity_attribs: Attribs - - /// The declared representation of the type, i.e. record, union, class etc. - // - // MUTABILITY; used only during creation and remapping of tycons - mutable entity_tycon_repr: TyconRepresentation - - /// The methods and properties of the type - // - // MUTABILITY; used only during creation and remapping of tycons - mutable entity_tycon_tcaug: TyconAugmentation - - /// This field is used when the 'tycon' is really a module definition. It holds statically nested type definitions and nested modules - // - // MUTABILITY: only used during creation and remapping of tycons and - // when compiling fslib to fixup compiler forward references to internal items - mutable entity_modul_contents: MaybeLazy - - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 - // REVIEW: it looks like entity_cpath subsumes this - // MUTABILITY: only for unpickle linkage - mutable entity_pubpath: PublicPath option - - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 - // MUTABILITY: only for unpickle linkage - mutable entity_cpath: CompilationPath option - - /// Used during codegen to hold the ILX representation indicating how to access the type - // MUTABILITY: only for unpickle linkage and caching - mutable entity_il_repr_cache: CompiledTypeRepr cache - - mutable entity_opt_data: EntityOptionalData option - } - - static member NewEmptyEntityOptData() = - { entity_compiled_name = None - entity_other_range = None - entity_kind = TyparKind.Type - entity_xmldoc = XmlDoc.Empty - entity_xmldocsig = "" - entity_tycon_abbrev = None - entity_tycon_repr_accessibility = TAccess [] - entity_accessibility = TAccess [] - entity_exn_info = TExnNone } - - /// The name of the namespace, module or type, possibly with mangling, e.g. List`1, List or FailureException - member x.LogicalName = x.entity_logical_name - - /// The compiled name of the namespace, module or type, e.g. FSharpList`1, ListModule or FailureException - member x.CompiledName = - match x.entity_opt_data with - | Some { entity_compiled_name = Some s } -> s - | _ -> x.LogicalName - - member x.EntityCompiledName = - match x.entity_opt_data with - | Some optData -> optData.entity_compiled_name - | _ -> None - - member x.SetCompiledName name = - match x.entity_opt_data with - | Some optData -> optData.entity_compiled_name <- name - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_compiled_name = name } - - /// The display name of the namespace, module or type, e.g. List instead of List`1, and no static parameters - member x.DisplayName = x.GetDisplayName(false, false) - - /// The display name of the namespace, module or type with <_, _, _> added for generic types, plus static parameters if any - member x.DisplayNameWithStaticParametersAndUnderscoreTypars = x.GetDisplayName(true, true) - - /// The display name of the namespace, module or type, e.g. List instead of List`1, including static parameters if any - member x.DisplayNameWithStaticParameters = x.GetDisplayName(true, false) - -#if !NO_EXTENSIONTYPING - member x.IsStaticInstantiationTycon = - x.IsProvidedErasedTycon && - let _nm, args = PrettyNaming.demangleProvidedTypeName x.LogicalName - args.Length > 0 -#endif - - member x.GetDisplayName(withStaticParameters, withUnderscoreTypars) = - let nm = x.LogicalName - let getName () = - match x.TyparsNoRange with - | [] -> nm - | tps -> - let nm = DemangleGenericTypeName nm - if withUnderscoreTypars && not (List.isEmpty tps) then - nm + "<" + String.concat "," (Array.create tps.Length "_") + ">" - else - nm - -#if !NO_EXTENSIONTYPING - if x.IsProvidedErasedTycon then - let nm, args = PrettyNaming.demangleProvidedTypeName nm - if withStaticParameters && args.Length > 0 then - nm + "<" + String.concat "," (Array.map snd args) + ">" - else - nm - else - getName () -#else - ignore withStaticParameters - getName () -#endif - - - /// The code location where the module, namespace or type is defined. - member x.Range = -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> - match ComputeDefinitionLocationOfProvidedItem info.ProvidedType with - | Some range -> range - | None -> x.entity_range - | _ -> -#endif - x.entity_range - - /// The range in the implementation, adjusted for an item in a signature - member x.DefinitionRange = - match x.entity_opt_data with - | Some { entity_other_range = Some (r, true) } -> r - | _ -> x.Range - - member x.SigRange = - match x.entity_opt_data with - | Some { entity_other_range = Some (r, false) } -> r - | _ -> x.Range - - member x.SetOtherRange m = - match x.entity_opt_data with - | Some optData -> optData.entity_other_range <- Some m - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_other_range = Some m } - - /// A unique stamp for this module, namespace or type definition within the context of this compilation. - /// Note that because of signatures, there are situations where in a single compilation the "same" - /// module, namespace or type may have two distinct Entity objects that have distinct stamps. - member x.Stamp = x.entity_stamp - - /// The F#-defined custom attributes of the entity, if any. If the entity is backed by Abstract IL or provided metadata - /// then this does not include any attributes from those sources. - member x.Attribs = x.entity_attribs - - /// The XML documentation of the entity, if any. If the entity is backed by provided metadata - /// then this _does_ include this documentation. If the entity is backed by Abstract IL metadata - /// or comes from another F# assembly then it does not (because the documentation will get read from - /// an XML file). - member x.XmlDoc = -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> XmlDoc (info.ProvidedType.PUntaintNoFailure(fun st -> (st :> IProvidedCustomAttributeProvider).GetXmlDocAttributes(info.ProvidedType.TypeProvider.PUntaintNoFailure id))) - | _ -> -#endif - match x.entity_opt_data with - | Some optData -> optData.entity_xmldoc - | _ -> XmlDoc.Empty - - /// The XML documentation sig-string of the entity, if any, to use to lookup an .xml doc file. This also acts - /// as a cache for this sig-string computation. - member x.XmlDocSig - with get() = - match x.entity_opt_data with - | Some optData -> optData.entity_xmldocsig - | _ -> "" - and set v = - match x.entity_opt_data with - | Some optData -> optData.entity_xmldocsig <- v - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_xmldocsig = v } - - /// The logical contents of the entity when it is a module or namespace fragment. - member x.ModuleOrNamespaceType = x.entity_modul_contents.Force() - - /// The logical contents of the entity when it is a type definition. - member x.TypeContents = x.entity_tycon_tcaug - - /// The kind of the type definition - is it a measure definition or a type definition? - member x.TypeOrMeasureKind = - match x.entity_opt_data with - | Some optData -> optData.entity_kind - | _ -> TyparKind.Type - - member x.SetTypeOrMeasureKind kind = - match x.entity_opt_data with - | Some optData -> optData.entity_kind <- kind - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_kind = kind } - - /// The identifier at the point of declaration of the type definition. - member x.Id = ident(x.LogicalName, x.Range) - - /// The information about the r.h.s. of a type definition, if any. For example, the r.h.s. of a union or record type. - member x.TypeReprInfo = x.entity_tycon_repr - - /// The information about the r.h.s. of an F# exception definition, if any. - member x.ExceptionInfo = - match x.entity_opt_data with - | Some optData -> optData.entity_exn_info - | _ -> TExnNone - - member x.SetExceptionInfo exn_info = - match x.entity_opt_data with - | Some optData -> optData.entity_exn_info <- exn_info - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_exn_info = exn_info } - - /// Indicates if the entity represents an F# exception declaration. - member x.IsExceptionDecl = match x.ExceptionInfo with TExnNone -> false | _ -> true - - /// Demangle the module name, if FSharpModuleWithSuffix is used - member x.DemangledModuleOrNamespaceName = - CompilationPath.DemangleEntityName x.LogicalName x.ModuleOrNamespaceType.ModuleOrNamespaceKind - - /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. - /// - /// Lazy because it may read metadata, must provide a context "range" in case error occurs reading metadata. - member x.Typars m = x.entity_typars.Force m - - /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. - member x.TyparsNoRange = x.Typars x.Range - - /// Get the type abbreviated by this type definition, if it is an F# type abbreviation definition - member x.TypeAbbrev = - match x.entity_opt_data with - | Some optData -> optData.entity_tycon_abbrev - | _ -> None - - member x.SetTypeAbbrev tycon_abbrev = - match x.entity_opt_data with - | Some optData -> optData.entity_tycon_abbrev <- tycon_abbrev - | _ -> x.entity_opt_data <- Some { Entity.NewEmptyEntityOptData() with entity_tycon_abbrev = tycon_abbrev } - - /// Indicates if this entity is an F# type abbreviation definition - member x.IsTypeAbbrev = x.TypeAbbrev.IsSome - - /// Get the value representing the accessibility of the r.h.s. of an F# type definition. - member x.TypeReprAccessibility = - match x.entity_opt_data with - | Some optData -> optData.entity_tycon_repr_accessibility - | _ -> TAccess [] - - /// Get the cache of the compiled ILTypeRef representation of this module or type. - member x.CompiledReprCache = x.entity_il_repr_cache - - /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member x.PublicPath = x.entity_pubpath - - /// Get the value representing the accessibility of an F# type definition or module. - member x.Accessibility = - match x.entity_opt_data with - | Some optData -> optData.entity_accessibility - | _ -> TAccess [] - - /// Indicates the type prefers the "tycon" syntax for display etc. - member x.IsPrefixDisplay = x.entity_flags.IsPrefixDisplay - - /// Indicates the Entity is actually a module or namespace, not a type definition - member x.IsModuleOrNamespace = x.entity_flags.IsModuleOrNamespace - - /// Indicates if the entity is a namespace - member x.IsNamespace = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> true | _ -> false) - - /// Indicates if the entity is an F# module definition - member x.IsModule = x.IsModuleOrNamespace && (match x.ModuleOrNamespaceType.ModuleOrNamespaceKind with Namespace -> false | _ -> true) -#if !NO_EXTENSIONTYPING - - /// Indicates if the entity is a provided type or namespace definition - member x.IsProvided = - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint _ -> true - | TProvidedNamespaceExtensionPoint _ -> true - | _ -> false - - /// Indicates if the entity is a provided namespace fragment - member x.IsProvidedNamespace = - match x.TypeReprInfo with - | TProvidedNamespaceExtensionPoint _ -> true - | _ -> false - - /// Indicates if the entity is an erased provided type definition - member x.IsProvidedErasedTycon = - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.IsErased - | _ -> false - - /// Indicates if the entity is a generated provided type definition, i.e. not erased. - member x.IsProvidedGeneratedTycon = - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.IsGenerated - | _ -> false -#endif - - /// Indicates if the entity is erased, either a measure definition, or an erased provided type definition - member x.IsErased = - x.IsMeasureableReprTycon -#if !NO_EXTENSIONTYPING - || x.IsProvidedErasedTycon -#endif - - /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. - member x.CompilationPathOpt = x.entity_cpath - - /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. - member x.CompilationPath = - match x.CompilationPathOpt with - | Some cpath -> cpath - | None -> error(Error(FSComp.SR.tastTypeOrModuleNotConcrete(x.LogicalName), x.Range)) - - /// Get a table of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldTable = - match x.TypeReprInfo with - | TRecdRepr x | TFSharpObjectRepr {fsobjmodel_rfields=x} -> x - | _ -> - match x.ExceptionInfo with - | TExnFresh x -> x - | _ -> - { FieldsByIndex = [| |] - FieldsByName = NameMap.empty } - - /// Get an array of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldsArray = x.AllFieldTable.FieldsByIndex - - /// Get a list of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldsAsList = x.AllFieldsArray |> Array.toList - - /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition. - /// including hidden fields from the compilation of implicit class constructions. - // NOTE: This method doesn't perform particularly well, and is over-used, but doesn't seem to appear on performance traces - member x.AllInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic) - - /// Get a list of all fields for F#-defined record, struct and class fields in this type definition, - /// including static fields, but excluding compiler-generate fields. - member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated) - - /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition, - /// excluding compiler-generate fields. - member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated) - - /// Get a field by index in definition order - member x.GetFieldByIndex n = x.AllFieldTable.FieldByIndex n - - /// Get a field by name. - member x.GetFieldByName n = x.AllFieldTable.FieldByName n - - /// Indicate if this is a type whose r.h.s. is known to be a union type definition. - member x.IsUnionTycon = match x.TypeReprInfo with | TUnionRepr _ -> true | _ -> false - - /// Get the union cases and other union-type information for a type, if any - member x.UnionTypeInfo = - match x.TypeReprInfo with - | TUnionRepr x -> ValueSome x - | _ -> ValueNone - - /// Get the union cases for a type, if any - member x.UnionCasesArray = - match x.UnionTypeInfo with - | ValueSome x -> x.CasesTable.CasesByIndex - | ValueNone -> [| |] - - /// Get the union cases for a type, if any, as a list - member x.UnionCasesAsList = x.UnionCasesArray |> Array.toList - - /// Get a union case of a type by name - member x.GetUnionCaseByName n = - match x.UnionTypeInfo with - | ValueSome x -> NameMap.tryFind n x.CasesTable.CasesByName - | ValueNone -> None - - - /// Create a new entity with empty, unlinked data. Only used during unpickling of F# metadata. - static member NewUnlinked() : Entity = - { entity_typars = Unchecked.defaultof<_> - entity_flags = Unchecked.defaultof<_> - entity_stamp = Unchecked.defaultof<_> - entity_logical_name = Unchecked.defaultof<_> - entity_range = Unchecked.defaultof<_> - entity_attribs = Unchecked.defaultof<_> - entity_tycon_repr= Unchecked.defaultof<_> - entity_tycon_tcaug= Unchecked.defaultof<_> - entity_modul_contents= Unchecked.defaultof<_> - entity_pubpath = Unchecked.defaultof<_> - entity_cpath = Unchecked.defaultof<_> - entity_il_repr_cache = Unchecked.defaultof<_> - entity_opt_data = Unchecked.defaultof<_>} - - /// Create a new entity with the given backing data. Only used during unpickling of F# metadata. - static member New _reason (data: Entity) : Entity = data - - /// Link an entity based on empty, unlinked data to the given data. Only used during unpickling of F# metadata. - member x.Link (tg: EntityData) = - x.entity_typars <- tg.entity_typars - x.entity_flags <- tg.entity_flags - x.entity_stamp <- tg.entity_stamp - x.entity_logical_name <- tg.entity_logical_name - x.entity_range <- tg.entity_range - x.entity_attribs <- tg.entity_attribs - x.entity_tycon_repr <- tg.entity_tycon_repr - x.entity_tycon_tcaug <- tg.entity_tycon_tcaug - x.entity_modul_contents <- tg.entity_modul_contents - x.entity_pubpath <- tg.entity_pubpath - x.entity_cpath <- tg.entity_cpath - x.entity_il_repr_cache <- tg.entity_il_repr_cache - match tg.entity_opt_data with - | Some tg -> - x.entity_opt_data <- - Some { entity_compiled_name = tg.entity_compiled_name - entity_other_range = tg.entity_other_range - entity_kind = tg.entity_kind - entity_xmldoc = tg.entity_xmldoc - entity_xmldocsig = tg.entity_xmldocsig - entity_tycon_abbrev = tg.entity_tycon_abbrev - entity_tycon_repr_accessibility = tg.entity_tycon_repr_accessibility - entity_accessibility = tg.entity_accessibility - entity_exn_info = tg.entity_exn_info } - | None -> () - - - /// Indicates if the entity is linked to backing data. Only used during unpickling of F# metadata. - member x.IsLinked = match box x.entity_attribs with null -> false | _ -> true - - /// Get the blob of information associated with an F# object-model type definition, i.e. class, interface, struct etc. - member x.FSharpObjectModelTypeInfo = - match x.TypeReprInfo with - | TFSharpObjectRepr x -> x - | _ -> failwith "not an F# object model type definition" - - /// Indicate if this is a type definition backed by Abstract IL metadata. - member x.IsILTycon = match x.TypeReprInfo with | TILObjectRepr _ -> true | _ -> false - - /// Get the Abstract IL scope, nesting and metadata for this - /// type definition, assuming it is backed by Abstract IL metadata. - member x.ILTyconInfo = match x.TypeReprInfo with | TILObjectRepr data -> data | _ -> failwith "not a .NET type definition" - - /// Get the Abstract IL metadata for this type definition, assuming it is backed by Abstract IL metadata. - member x.ILTyconRawMetadata = let (TILObjectReprData(_, _, td)) = x.ILTyconInfo in td - - /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition. - member x.IsRecordTycon = match x.TypeReprInfo with | TRecdRepr _ -> true | _ -> false - - /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition that is a value type. - member x.IsStructRecordOrUnionTycon = match x.TypeReprInfo with TRecdRepr _ | TUnionRepr _ -> x.entity_flags.IsStructRecordOrUnionType | _ -> false - - /// The on-demand analysis about whether the entity has the IsByRefLike attribute - member x.TryIsByRefLike = x.entity_flags.TryIsByRefLike - - /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute - member x.SetIsByRefLike b = x.entity_flags <- x.entity_flags.WithIsByRefLike b - - /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute - member x.TryIsReadOnly = x.entity_flags.TryIsReadOnly - - /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute - member x.SetIsReadOnly b = x.entity_flags <- x.entity_flags.WithIsReadOnly b - - /// These two bits represents the on-demand analysis about whether the entity is assumed to be a readonly struct - member x.TryIsAssumedReadOnly = x.entity_flags.TryIsAssumedReadOnly - - /// Set the on-demand analysis about whether the entity is assumed to be a readonly struct - member x.SetIsAssumedReadOnly b = x.entity_flags <- x.entity_flags.WithIsAssumedReadOnly b - - /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition - member x.IsFSharpObjectModelTycon = match x.TypeReprInfo with | TFSharpObjectRepr _ -> true | _ -> false - - /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll which uses - /// an assembly-code representation for the type, e.g. the primitive array type constructor. - member x.IsAsmReprTycon = match x.TypeReprInfo with | TAsmRepr _ -> true | _ -> false - - /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll like 'float<_>' which - /// defines a measure type with a relation to an existing non-measure type as a representation. - member x.IsMeasureableReprTycon = match x.TypeReprInfo with | TMeasureableRepr _ -> true | _ -> false - - /// Indicates if this is an F# type definition whose r.h.s. definition is unknown (i.e. a traditional ML 'abstract' type in a signature, - /// which in F# is called a 'unknown representation' type). - member x.IsHiddenReprTycon = match x.TypeAbbrev, x.TypeReprInfo with | None, TNoRepr -> true | _ -> false - - /// Indicates if this is an F#-defined interface type definition - member x.IsFSharpInterfaceTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconInterface -> true | _ -> false - - /// Indicates if this is an F#-defined delegate type definition - member x.IsFSharpDelegateTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconDelegate _ -> true | _ -> false - - /// Indicates if this is an F#-defined enum type definition - member x.IsFSharpEnumTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconEnum -> true | _ -> false - - /// Indicates if this is an F#-defined class type definition - member x.IsFSharpClassTycon = x.IsFSharpObjectModelTycon && match x.FSharpObjectModelTypeInfo.fsobjmodel_kind with TTyconClass -> true | _ -> false - - /// Indicates if this is a .NET-defined enum type definition - member x.IsILEnumTycon = x.IsILTycon && x.ILTyconRawMetadata.IsEnum - - /// Indicates if this is an enum type definition - member x.IsEnumTycon = -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.IsEnum - | TProvidedNamespaceExtensionPoint _ -> false - | _ -> -#endif - x.IsILEnumTycon || x.IsFSharpEnumTycon - - - /// Indicates if this is an F#-defined struct or enum type definition, i.e. a value type definition - member x.IsFSharpStructOrEnumTycon = - match x.TypeReprInfo with - | TRecdRepr _ -> x.IsStructRecordOrUnionTycon - | TUnionRepr _ -> x.IsStructRecordOrUnionTycon - | TFSharpObjectRepr info -> - match info.fsobjmodel_kind with - | TTyconClass | TTyconInterface | TTyconDelegate _ -> false - | TTyconStruct | TTyconEnum -> true - | _ -> false - - /// Indicates if this is a .NET-defined struct or enum type definition, i.e. a value type definition - member x.IsILStructOrEnumTycon = - x.IsILTycon && - x.ILTyconRawMetadata.IsStructOrEnum - - /// Indicates if this is a struct or enum type definition, i.e. a value type definition - member x.IsStructOrEnumTycon = -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> info.IsStructOrEnum - | TProvidedNamespaceExtensionPoint _ -> false - | _ -> -#endif - x.IsILStructOrEnumTycon || x.IsFSharpStructOrEnumTycon - - /// Gets the immediate interface definitions of an F# type definition. Further interfaces may be supported through class and interface inheritance. - member x.ImmediateInterfacesOfFSharpTycon = - x.TypeContents.tcaug_interfaces - - /// Gets the immediate interface types of an F# type definition. Further interfaces may be supported through class and interface inheritance. - member x.ImmediateInterfaceTypesOfFSharpTycon = - x.ImmediateInterfacesOfFSharpTycon |> List.map (fun (x, _, _) -> x) - - /// Gets the immediate members of an F# type definition, excluding compiler-generated ones. - /// Note: result is alphabetically sorted, then for each name the results are in declaration order - member x.MembersOfFSharpTyconSorted = - x.TypeContents.tcaug_adhoc - |> NameMultiMap.rangeReversingEachBucket - |> List.filter (fun v -> not v.IsCompilerGenerated) - - /// Gets all immediate members of an F# type definition keyed by name, including compiler-generated ones. - /// Note: result is a indexed table, and for each name the results are in reverse declaration order - member x.MembersOfFSharpTyconByName = - x.TypeContents.tcaug_adhoc - - /// Gets any implicit hash/equals (with comparer argument) methods added to an F# record, union or struct type definition. - member x.GeneratedHashAndEqualsWithComparerValues = x.TypeContents.tcaug_hash_and_equals_withc - - /// Gets any implicit CompareTo (with comparer argument) methods added to an F# record, union or struct type definition. - member x.GeneratedCompareToWithComparerValues = x.TypeContents.tcaug_compare_withc - - /// Gets any implicit CompareTo methods added to an F# record, union or struct type definition. - member x.GeneratedCompareToValues = x.TypeContents.tcaug_compare - - /// Gets any implicit hash/equals methods added to an F# record, union or struct type definition. - member x.GeneratedHashAndEqualsValues = x.TypeContents.tcaug_equals - - /// Gets all implicit hash/equals/compare methods added to an F# record, union or struct type definition. - member x.AllGeneratedValues = - [ match x.GeneratedCompareToValues with - | None -> () - | Some (v1, v2) -> yield v1; yield v2 - match x.GeneratedCompareToWithComparerValues with - | None -> () - | Some v -> yield v - match x.GeneratedHashAndEqualsValues with - | None -> () - | Some (v1, v2) -> yield v1; yield v2 - match x.GeneratedHashAndEqualsWithComparerValues with - | None -> () - | Some (v1, v2, v3) -> yield v1; yield v2; yield v3 ] - - - /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. - member x.CompiledRepresentation = -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - // We should never be computing this property for erased types - | TProvidedTypeExtensionPoint info when info.IsErased -> - failwith "No compiled representation for provided erased type" - - // Generated types that are not relocated just point straight to the generated backing assembly, computed from "st". - // These are used when running F# Interactive, which does not use static linking of provider-generated assemblies, - // and also for types with relocation suppressed. - | TProvidedTypeExtensionPoint info when info.IsGenerated && info.IsSuppressRelocate -> - let st = info.ProvidedType - let tref = ExtensionTyping.GetILTypeRefOfProvidedType (st, x.Range) - let boxity = if x.IsStructOrEnumTycon then AsValue else AsObject - CompiledTypeRepr.ILAsmNamed(tref, boxity, None) - | TProvidedNamespaceExtensionPoint _ -> failwith "No compiled representation for provided namespace" - | _ -> -#endif - let ilTypeRefForCompilationPath (CompPath(sref, p)) item = - let rec top racc p = - match p with - | [] -> ILTypeRef.Create(sref, [], textOfPath (List.rev (item :: racc))) - | (h, isType) :: t -> - match isType with - | FSharpModuleWithSuffix | ModuleOrType -> - let outerTypeName = (textOfPath (List.rev (h :: racc))) - ILTypeRef.Create(sref, (outerTypeName :: List.map (fun (nm, _) -> nm) t), item) - | _ -> - top (h :: racc) t - top [] p - - - cached x.CompiledReprCache (fun () -> - match x.ExceptionInfo with - | TExnAbbrevRepr ecref2 -> ecref2.CompiledRepresentation - | TExnAsmRepr tref -> CompiledTypeRepr.ILAsmNamed(tref, AsObject, Some (mkILTy AsObject (mkILTySpec (tref, [])))) - | _ -> - match x.TypeReprInfo with - | TAsmRepr ty -> CompiledTypeRepr.ILAsmOpen ty - | _ -> - let boxity = if x.IsStructOrEnumTycon then AsValue else AsObject - let ilTypeRef = - match x.TypeReprInfo with - | TILObjectRepr (TILObjectReprData(ilScopeRef, ilEnclosingTypeDefs, ilTypeDef)) -> IL.mkRefForNestedILTypeDef ilScopeRef (ilEnclosingTypeDefs, ilTypeDef) - | _ -> ilTypeRefForCompilationPath x.CompilationPath x.CompiledName - // Pre-allocate a ILType for monomorphic types, to reduce memory usage from Abstract IL nodes - let ilTypeOpt = - match x.TyparsNoRange with - | [] -> Some (mkILTy boxity (mkILTySpec (ilTypeRef, []))) - | _ -> None - CompiledTypeRepr.ILAsmNamed (ilTypeRef, boxity, ilTypeOpt)) - - /// Gets the data indicating the compiled representation of a named type or module in terms of Abstract IL data structures. - member x.CompiledRepresentationForNamedType = - match x.CompiledRepresentation with - | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> tref - | CompiledTypeRepr.ILAsmOpen _ -> invalidOp (FSComp.SR.tastTypeHasAssemblyCodeRepresentation(x.DisplayNameWithStaticParametersAndUnderscoreTypars)) - - - /// Indicates if we have pre-determined that a type definition has a default constructor. - member x.PreEstablishedHasDefaultConstructor = x.entity_flags.PreEstablishedHasDefaultConstructor - - /// Indicates if we have pre-determined that a type definition has a self-referential constructor using 'as x' - member x.HasSelfReferentialConstructor = x.entity_flags.HasSelfReferentialConstructor - - /// Set the custom attributes on an F# type definition. - member x.SetAttribs attribs = x.entity_attribs <- attribs - - /// Sets the structness of a record or union type definition - member x.SetIsStructRecordOrUnion b = let flags = x.entity_flags in x.entity_flags <- EntityFlags(flags.IsPrefixDisplay, flags.IsModuleOrNamespace, flags.PreEstablishedHasDefaultConstructor, flags.HasSelfReferentialConstructor, b) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.LogicalName - -and [] MaybeLazy<'T> = - | Strict of 'T - | Lazy of Lazy<'T> - - member this.Value: 'T = - match this with - | Strict x -> x - | Lazy x -> x.Value - - member this.Force() : 'T = - match this with - | Strict x -> x - | Lazy x -> x.Force() - -and EntityData = Entity - -and ParentRef = - | Parent of EntityRef - | ParentNone - -and - [] - TyconAugmentation = - { /// This is the value implementing the auto-generated comparison - /// semantics if any. It is not present if the type defines its own implementation - /// of IComparable or if the type doesn't implement IComparable implicitly. - mutable tcaug_compare: (ValRef * ValRef) option - - /// This is the value implementing the auto-generated comparison - /// semantics if any. It is not present if the type defines its own implementation - /// of IStructuralComparable or if the type doesn't implement IComparable implicitly. - mutable tcaug_compare_withc: ValRef option - - /// This is the value implementing the auto-generated equality - /// semantics if any. It is not present if the type defines its own implementation - /// of Object.Equals or if the type doesn't override Object.Equals implicitly. - mutable tcaug_equals: (ValRef * ValRef) option - - /// This is the value implementing the auto-generated comparison - /// semantics if any. It is not present if the type defines its own implementation - /// of IStructuralEquatable or if the type doesn't implement IComparable implicitly. - mutable tcaug_hash_and_equals_withc: (ValRef * ValRef * ValRef) option - - /// True if the type defined an Object.GetHashCode method. In this - /// case we give a warning if we auto-generate a hash method since the semantics may not match up - mutable tcaug_hasObjectGetHashCode: bool - - /// Properties, methods etc. in declaration order. The boolean flag for each indicates if the - /// member is known to be an explicit interface implementation. This must be computed and - /// saved prior to remapping assembly information. - tcaug_adhoc_list: ResizeArray - - /// Properties, methods etc. as lookup table - mutable tcaug_adhoc: NameMultiMap - - /// Interface implementations - boolean indicates compiler-generated - mutable tcaug_interfaces: (TType * bool * range) list - - /// Super type, if any - mutable tcaug_super: TType option - - /// Set to true at the end of the scope where proper augmentations are allowed - mutable tcaug_closed: bool - - /// Set to true if the type is determined to be abstract - mutable tcaug_abstract: bool - } - - member tcaug.SetCompare x = tcaug.tcaug_compare <- Some x - - member tcaug.SetCompareWith x = tcaug.tcaug_compare_withc <- Some x - - member tcaug.SetEquals x = tcaug.tcaug_equals <- Some x - - member tcaug.SetHashAndEqualsWith x = tcaug.tcaug_hash_and_equals_withc <- Some x - - member tcaug.SetHasObjectGetHashCode b = tcaug.tcaug_hasObjectGetHashCode <- b - - static member Create() = - { tcaug_compare=None - tcaug_compare_withc=None - tcaug_equals=None - tcaug_hash_and_equals_withc=None - tcaug_hasObjectGetHashCode=false - tcaug_adhoc=NameMultiMap.empty - tcaug_adhoc_list=new ResizeArray<_>() - tcaug_super=None - tcaug_interfaces=[] - tcaug_closed=false - tcaug_abstract=false } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TyconAugmentation(...)" - -and - [] - /// The information for the contents of a type. Also used for a provided namespace. - TyconRepresentation = - - /// Indicates the type is a class, struct, enum, delegate or interface - | TFSharpObjectRepr of TyconObjModelData - - /// Indicates the type is a record - | TRecdRepr of TyconRecdFields - - /// Indicates the type is a discriminated union - | TUnionRepr of TyconUnionData - - /// Indicates the type is a type from a .NET assembly without F# metadata. - | TILObjectRepr of TILObjectReprData - - /// Indicates the type is implemented as IL assembly code using the given closed Abstract IL type - | TAsmRepr of ILType - - /// Indicates the type is parameterized on a measure (e.g. float<_>) but erases to some other type (e.g. float) - | TMeasureableRepr of TType - -#if !NO_EXTENSIONTYPING - /// TProvidedTypeExtensionPoint - /// - /// Indicates the representation information for a provided type. - | TProvidedTypeExtensionPoint of TProvidedTypeInfo - - /// Indicates the representation information for a provided namespace. - // - // Note, the list could probably be a list of IProvidedNamespace rather than ITypeProvider - | TProvidedNamespaceExtensionPoint of ExtensionTyping.ResolutionEnvironment * Tainted list -#endif - - /// The 'NoRepr' value here has four meanings: - /// (1) it indicates 'not yet known' during the first 2 phases of establishing type definitions - /// (2) it indicates 'no representation', i.e. 'type X' in signatures - /// (3) it is the setting used for exception definitions (!) - /// (4) it is the setting used for modules and namespaces. - /// - /// It would be better to separate the "not yet known" and other cases out. - /// The information for exception definitions should be folded into here. - | TNoRepr - - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -and - [] - /// TILObjectReprData(scope, nesting, definition) - TILObjectReprData = - | TILObjectReprData of ILScopeRef * ILTypeDef list * ILTypeDef - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TILObjectReprData(...)" - - -#if !NO_EXTENSIONTYPING -and - [] - - /// The information kept about a provided type - TProvidedTypeInfo = - { /// The parameters given to the provider that provided to this type. - ResolutionEnvironment: ExtensionTyping.ResolutionEnvironment - - /// The underlying System.Type (wrapped as a ProvidedType to make sure we don't call random things on - /// System.Type, and wrapped as Tainted to make sure we track which provider this came from, for reporting - /// error messages) - ProvidedType: Tainted - - /// The base type of the type. We use it to compute the compiled representation of the type for erased types. - /// Reading is delayed, since it does an import on the underlying type - LazyBaseType: LazyWithContext - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsClass: bool - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsSealed: bool - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsAbstract: bool - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsInterface: bool - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsStructOrEnum: bool - - /// A flag read eagerly from the provided type and used to compute basic properties of the type definition. - IsEnum: bool - - /// A type read from the provided type and used to compute basic properties of the type definition. - /// Reading is delayed, since it does an import on the underlying type - UnderlyingTypeOfEnum: (unit -> TType) - - /// A flag read from the provided type and used to compute basic properties of the type definition. - /// Reading is delayed, since it looks at the .BaseType - IsDelegate: (unit -> bool) - - /// Indicates the type is erased - IsErased: bool - - /// Indicates the type is generated, but type-relocation is suppressed - IsSuppressRelocate: bool } - - member info.IsGenerated = not info.IsErased - - member info.BaseTypeForErased (m, objTy) = - if info.IsErased then info.LazyBaseType.Force (m, objTy) - else failwith "expect erased type" - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TProvidedTypeInfo(...)" - -#endif - -and - TyconObjModelKind = - /// Indicates the type is a class (also used for units-of-measure) - | TTyconClass - - /// Indicates the type is an interface - | TTyconInterface - - /// Indicates the type is a struct - | TTyconStruct - - /// Indicates the type is a delegate with the given Invoke signature - | TTyconDelegate of SlotSig - - /// Indicates the type is an enumeration - | TTyconEnum - - member x.IsValueType = - match x with - | TTyconClass | TTyconInterface | TTyconDelegate _ -> false - | TTyconStruct | TTyconEnum -> true - -and - [] - TyconObjModelData = - { /// Indicates whether the type declaration is a class, interface, enum, delegate or struct - fsobjmodel_kind: TyconObjModelKind - - /// The declared abstract slots of the class, interface or struct - fsobjmodel_vslots: ValRef list - - /// The fields of the class, struct or enum - fsobjmodel_rfields: TyconRecdFields } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TyconObjModelData(...)" - -and - [] - TyconRecdFields = - { /// The fields of the record, in declaration order. - FieldsByIndex: RecdField[] - - /// The fields of the record, indexed by name. - FieldsByName: NameMap } - - member x.FieldByIndex n = - if n >= 0 && n < x.FieldsByIndex.Length then x.FieldsByIndex.[n] - else failwith "FieldByIndex" - - member x.FieldByName n = x.FieldsByName.TryFind n - - member x.AllFieldsAsList = x.FieldsByIndex |> Array.toList - - member x.TrueFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsCompilerGenerated) - - member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TyconRecdFields(...)" - -and - [] - TyconUnionCases = - { /// The cases of the discriminated union, in declaration order. - CasesByIndex: UnionCase[] - /// The cases of the discriminated union, indexed by name. - CasesByName: NameMap - } - member x.GetUnionCaseByIndex n = - if n >= 0 && n < x.CasesByIndex.Length then x.CasesByIndex.[n] - else invalidArg "n" "GetUnionCaseByIndex" - - member x.UnionCasesAsList = x.CasesByIndex |> Array.toList - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TyconUnionCases(...)" - -and - [] - TyconUnionData = - { /// The cases contained in the discriminated union. - CasesTable: TyconUnionCases - /// The ILX data structure representing the discriminated union. - CompiledRepresentation: IlxUnionRef cache - } - - member x.UnionCasesAsList = x.CasesTable.CasesByIndex |> Array.toList - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TyconUnionData(...)" - -and - [] - UnionCase = - { /// Data carried by the case. - FieldTable: TyconRecdFields - - /// Return type constructed by the case. Normally exactly the type of the enclosing type, sometimes an abbreviation of it - ReturnType: TType - - /// Documentation for the case - XmlDoc: XmlDoc - - /// XML documentation signature for the case - mutable XmlDocSig: string - - /// Name/range of the case - Id: Ident - - /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is - /// the signature range for an item in an implementation - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable OtherRangeOpt: (range * bool) option - - /// Indicates the declared visibility of the union constructor, not taking signatures into account - Accessibility: Accessibility - - /// Attributes, attached to the generated static method to make instances of the case - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable Attribs: Attribs } - - member uc.Range = uc.Id.idRange - - member uc.DefinitionRange = - match uc.OtherRangeOpt with - | Some (m, true) -> m - | _ -> uc.Range - - member uc.SigRange = - match uc.OtherRangeOpt with - | Some (m, false) -> m - | _ -> uc.Range - - member uc.DisplayName = uc.Id.idText - - /// Name of the case in generated IL code. - member uc.CompiledName = - let idText = uc.Id.idText - if idText = opNameCons then "Cons" - elif idText = opNameNil then "Empty" - else idText - - member uc.RecdFieldsArray = uc.FieldTable.FieldsByIndex - - member uc.RecdFields = uc.FieldTable.FieldsByIndex |> Array.toList - - member uc.GetFieldByName nm = uc.FieldTable.FieldByName nm - - member uc.IsNullary = (uc.FieldTable.FieldsByIndex.Length = 0) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "UnionCase(" + x.DisplayName + ")" - -and - /// This may represent a "field" in either a struct, class, record or union - /// It is normally compiled to a property. - [] - RecdField = - { /// Is the field declared mutable in F#? - rfield_mutable: bool - - /// Documentation for the field - rfield_xmldoc: XmlDoc - - /// XML Documentation signature for the field - mutable rfield_xmldocsig: string - - /// The type of the field, w.r.t. the generic parameters of the enclosing type constructor - rfield_type: TType - - /// Indicates a static field - rfield_static: bool - - /// Indicates a volatile field - rfield_volatile: bool - - /// Indicates a compiler generated field, not visible to Intellisense or name resolution - rfield_secret: bool - - /// The default initialization info, for static literals - rfield_const: Const option - - /// Indicates the declared visibility of the field, not taking signatures into account - rfield_access: Accessibility - - /// Attributes attached to generated property - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable rfield_pattribs: Attribs - - /// Attributes attached to generated field - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable rfield_fattribs: Attribs - - /// Name/declaration-location of the field - rfield_id: Ident - - rfield_name_generated: bool - - /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is - /// the signature range for an item in an implementation - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable rfield_other_range: (range * bool) option } - - /// Indicates the declared visibility of the field, not taking signatures into account - member v.Accessibility = v.rfield_access - - /// Attributes attached to generated property - member v.PropertyAttribs = v.rfield_pattribs - - /// Attributes attached to generated field - member v.FieldAttribs = v.rfield_fattribs - - /// Declaration-location of the field - member v.Range = v.rfield_id.idRange - - member v.DefinitionRange = - match v.rfield_other_range with - | Some (m, true) -> m - | _ -> v.Range - - member v.SigRange = - match v.rfield_other_range with - | Some (m, false) -> m - | _ -> v.Range - - /// Name/declaration-location of the field - member v.Id = v.rfield_id - - /// Name of the field - member v.Name = v.rfield_id.idText - - /// Indicates a compiler generated field, not visible to Intellisense or name resolution - member v.IsCompilerGenerated = v.rfield_secret - - /// Is the field declared mutable in F#? - member v.IsMutable = v.rfield_mutable - - /// Indicates a static field - member v.IsStatic = v.rfield_static - - /// Indicates a volatile field - member v.IsVolatile = v.rfield_volatile - - /// The type of the field, w.r.t. the generic parameters of the enclosing type constructor - member v.FormalType = v.rfield_type - - /// XML Documentation signature for the field - member v.XmlDoc = v.rfield_xmldoc - - /// Get or set the XML documentation signature for the field - member v.XmlDocSig - with get() = v.rfield_xmldocsig - and set x = v.rfield_xmldocsig <- x - - /// The default initialization info, for static literals - member v.LiteralValue = - match v.rfield_const with - | None -> None - | Some Const.Zero -> None - | Some k -> Some k - - /// Indicates if the field is zero-initialized - member v.IsZeroInit = - match v.rfield_const with - | None -> false - | Some Const.Zero -> true - | _ -> false - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.Name - -and - [] - ExceptionInfo = - /// Indicates that an exception is an abbreviation for the given exception - | TExnAbbrevRepr of TyconRef - - /// Indicates that an exception is shorthand for the given .NET exception type - | TExnAsmRepr of ILTypeRef - - /// Indicates that an exception carries the given record of values - | TExnFresh of TyconRecdFields - - /// Indicates that an exception is abstract, i.e. is in a signature file, and we do not know the representation - | TExnNone - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -and [] - ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, entities: QueueList) = - - /// Mutation used during compilation of FSharp.Core.dll - let mutable entities = entities - - // Lookup tables keyed the way various clients expect them to be keyed. - // We attach them here so we don't need to store lookup tables via any other technique. - // - // The type option ref is used because there are a few functions that treat these as first class values. - // We should probably change to 'mutable'. - // - // We do not need to lock this mutable state this it is only ever accessed from the compiler thread. - let activePatternElemRefCache: NameMap option ref = ref None - - let mutable modulesByDemangledNameCache: NameMap option = None - - let mutable exconsByDemangledNameCache: NameMap option = None - - let mutable tyconsByDemangledNameAndArityCache: LayeredMap option = None - - let mutable tyconsByAccessNamesCache: LayeredMultiMap option = None - - let mutable tyconsByMangledNameCache: NameMap option = None - - let mutable allEntitiesByMangledNameCache: NameMap option = None - - let mutable allValsAndMembersByPartialLinkageKeyCache: MultiMap option = None - - let mutable allValsByLogicalNameCache: NameMap option = None - - /// Namespace or module-compiled-as-type? - member mtyp.ModuleOrNamespaceKind = kind - - /// Values, including members in F# types in this module-or-namespace-fragment. - member mtyp.AllValsAndMembers = vals - - /// Type, mapping mangled name to Tycon, e.g. - //// "Dictionary`2" --> Tycon - //// "ListModule" --> Tycon with module info - //// "FooException" --> Tycon with exception info - member mtyp.AllEntities = entities - - /// Mutation used during compilation of FSharp.Core.dll - member mtyp.AddModuleOrNamespaceByMutation(modul: ModuleOrNamespace) = - entities <- QueueList.appendOne entities modul - modulesByDemangledNameCache <- None - allEntitiesByMangledNameCache <- None - -#if !NO_EXTENSIONTYPING - /// Mutation used in hosting scenarios to hold the hosted types in this module or namespace - member mtyp.AddProvidedTypeEntity(entity: Entity) = - entities <- QueueList.appendOne entities entity - tyconsByMangledNameCache <- None - tyconsByDemangledNameAndArityCache <- None - tyconsByAccessNamesCache <- None - allEntitiesByMangledNameCache <- None -#endif - - /// Return a new module or namespace type with an entity added. - member mtyp.AddEntity(tycon: Tycon) = - ModuleOrNamespaceType(kind, vals, entities.AppendOne tycon) - - /// Return a new module or namespace type with a value added. - member mtyp.AddVal(vspec: Val) = - ModuleOrNamespaceType(kind, vals.AppendOne vspec, entities) - - /// Get a table of the active patterns defined in this module. - member mtyp.ActivePatternElemRefLookupTable = activePatternElemRefCache - - /// Get a list of types defined within this module, namespace or type. - member mtyp.TypeDefinitions = entities |> Seq.filter (fun x -> not x.IsExceptionDecl && not x.IsModuleOrNamespace) |> Seq.toList - - /// Get a list of F# exception definitions defined within this module, namespace or type. - member mtyp.ExceptionDefinitions = entities |> Seq.filter (fun x -> x.IsExceptionDecl) |> Seq.toList - - /// Get a list of module and namespace definitions defined within this module, namespace or type. - member mtyp.ModuleAndNamespaceDefinitions = entities |> Seq.filter (fun x -> x.IsModuleOrNamespace) |> Seq.toList - - /// Get a list of type and exception definitions defined within this module, namespace or type. - member mtyp.TypeAndExceptionDefinitions = entities |> Seq.filter (fun x -> not x.IsModuleOrNamespace) |> Seq.toList - - /// Get a table of types defined within this module, namespace or type. The - /// table is indexed by both name and generic arity. This means that for generic - /// types "List`1", the entry (List, 1) will be present. - member mtyp.TypesByDemangledNameAndArity m = - cacheOptByref &tyconsByDemangledNameAndArityCache (fun () -> - LayeredMap.Empty.AddAndMarkAsCollapsible( mtyp.TypeAndExceptionDefinitions |> List.map (fun (tc: Tycon) -> KeyTyconByDemangledNameAndArity tc.LogicalName (tc.Typars m) tc) |> List.toArray)) - - /// Get a table of types defined within this module, namespace or type. The - /// table is indexed by both name and, for generic types, also by mangled name. - member mtyp.TypesByAccessNames = - cacheOptByref &tyconsByAccessNamesCache (fun () -> - LayeredMultiMap.Empty.AddAndMarkAsCollapsible (mtyp.TypeAndExceptionDefinitions |> List.toArray |> Array.collect (fun (tc: Tycon) -> KeyTyconByAccessNames tc.LogicalName tc))) - - // REVIEW: we can remove this lookup and use AllEntitiesByMangledName instead? - member mtyp.TypesByMangledName = - let addTyconByMangledName (x: Tycon) tab = NameMap.add x.LogicalName x tab - cacheOptByref &tyconsByMangledNameCache (fun () -> - List.foldBack addTyconByMangledName mtyp.TypeAndExceptionDefinitions Map.empty) - - /// Get a table of entities indexed by both logical and compiled names - member mtyp.AllEntitiesByCompiledAndLogicalMangledNames: NameMap = - let addEntityByMangledName (x: Entity) tab = - let name1 = x.LogicalName - let name2 = x.CompiledName - let tab = NameMap.add name1 x tab - if name1 = name2 then tab - else NameMap.add name2 x tab - - cacheOptByref &allEntitiesByMangledNameCache (fun () -> - QueueList.foldBack addEntityByMangledName entities Map.empty) - - /// Get a table of entities indexed by both logical name - member mtyp.AllEntitiesByLogicalMangledName: NameMap = - let addEntityByMangledName (x: Entity) tab = NameMap.add x.LogicalName x tab - QueueList.foldBack addEntityByMangledName entities Map.empty - - /// Get a table of values and members indexed by partial linkage key, which includes name, the mangled name of the parent type (if any), - /// and the method argument count (if any). - member mtyp.AllValsAndMembersByPartialLinkageKey = - let addValByMangledName (x: Val) tab = - if x.IsCompiledAsTopLevel then - let key = x.GetLinkagePartialKey() - MultiMap.add key x tab - else - tab - cacheOptByref &allValsAndMembersByPartialLinkageKeyCache (fun () -> - QueueList.foldBack addValByMangledName vals MultiMap.empty) - - /// Try to find the member with the given linkage key in the given module. - member mtyp.TryLinkVal(ccu: CcuThunk, key: ValLinkageFullKey) = - mtyp.AllValsAndMembersByPartialLinkageKey - |> MultiMap.find key.PartialKey - |> List.tryFind (fun v -> match key.TypeForLinkage with - | None -> true - | Some keyTy -> ccu.MemberSignatureEquality(keyTy, v.Type)) - |> ValueOptionInternal.ofOption - - /// Get a table of values indexed by logical name - member mtyp.AllValsByLogicalName = - let addValByName (x: Val) tab = - // Note: names may occur twice prior to raising errors about this in PostTypeCheckSemanticChecks - // Earlier ones take precedence since we report errors about the later ones - if not x.IsMember && not x.IsCompilerGenerated then - NameMap.add x.LogicalName x tab - else - tab - cacheOptByref &allValsByLogicalNameCache (fun () -> - QueueList.foldBack addValByName vals Map.empty) - - /// Compute a table of values and members indexed by logical name. - member mtyp.AllValsAndMembersByLogicalNameUncached = - let addValByName (x: Val) tab = - if not x.IsCompilerGenerated then - MultiMap.add x.LogicalName x tab - else - tab - QueueList.foldBack addValByName vals MultiMap.empty - - /// Get a table of F# exception definitions indexed by demangled name, so 'FailureException' is indexed by 'Failure' - member mtyp.ExceptionDefinitionsByDemangledName = - let add (tycon: Tycon) acc = NameMap.add tycon.LogicalName tycon acc - cacheOptByref &exconsByDemangledNameCache (fun () -> - List.foldBack add mtyp.ExceptionDefinitions Map.empty) - - /// Get a table of nested module and namespace fragments indexed by demangled name (so 'ListModule' becomes 'List') - member mtyp.ModulesAndNamespacesByDemangledName = - let add (entity: Entity) acc = - if entity.IsModuleOrNamespace then - NameMap.add entity.DemangledModuleOrNamespaceName entity acc - else acc - cacheOptByref &modulesByDemangledNameCache (fun () -> - QueueList.foldBack add entities Map.empty) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ModuleOrNamespaceType(...)" - -and ModuleOrNamespace = Entity -and Tycon = Entity - -/// A set of static methods for constructing types. -and Construct = - - static member NewModuleOrNamespaceType mkind tycons vals = - ModuleOrNamespaceType(mkind, QueueList.ofList vals, QueueList.ofList tycons) - - static member NewEmptyModuleOrNamespaceType mkind = - Construct.NewModuleOrNamespaceType mkind [] [] - -#if !NO_EXTENSIONTYPING - - static member NewProvidedTyconRepr(resolutionEnvironment, st: Tainted, importProvidedType, isSuppressRelocate, m) = - - let isErased = st.PUntaint((fun st -> st.IsErased), m) - - let lazyBaseTy = - LazyWithContext.Create - ((fun (m, objTy) -> - let baseSystemTy = st.PApplyOption((fun st -> match st.BaseType with null -> None | ty -> Some ty), m) - match baseSystemTy with - | None -> objTy - | Some t -> importProvidedType t), - ErrorLogger.findOriginalException) - - TProvidedTypeExtensionPoint - { ResolutionEnvironment=resolutionEnvironment - ProvidedType=st - LazyBaseType=lazyBaseTy - UnderlyingTypeOfEnum = (fun () -> importProvidedType (st.PApply((fun st -> st.GetEnumUnderlyingType()), m))) - IsDelegate = (fun () -> st.PUntaint((fun st -> - let baseType = st.BaseType - match baseType with - | null -> false - | x when x.IsGenericType -> false - | x when x.DeclaringType <> null -> false - | x -> x.FullName = "System.Delegate" || x.FullName = "System.MulticastDelegate"), m)) - IsEnum = st.PUntaint((fun st -> st.IsEnum), m) - IsStructOrEnum = st.PUntaint((fun st -> st.IsValueType || st.IsEnum), m) - IsInterface = st.PUntaint((fun st -> st.IsInterface), m) - IsSealed = st.PUntaint((fun st -> st.IsSealed), m) - IsAbstract = st.PUntaint((fun st -> st.IsAbstract), m) - IsClass = st.PUntaint((fun st -> st.IsClass), m) - IsErased = isErased - IsSuppressRelocate = isSuppressRelocate } - - static member NewProvidedTycon(resolutionEnvironment, st: Tainted, importProvidedType, isSuppressRelocate, m, ?access, ?cpath) = - let stamp = newStamp() - let name = st.PUntaint((fun st -> st.Name), m) - let id = ident (name, m) - let kind = - let isMeasure = - st.PApplyWithProvider((fun (st, provider) -> - let findAttrib (ty: System.Type) (a: CustomAttributeData) = (a.Constructor.DeclaringType.FullName = ty.FullName) - let ty = st.RawSystemType - ignore provider - ty.CustomAttributes - |> Seq.exists (findAttrib typeof)), m) - .PUntaintNoFailure(fun x -> x) - if isMeasure then TyparKind.Measure else TyparKind.Type - - let access = - match access with - | Some a -> a - | None -> TAccess [] - let cpath = - match cpath with - | None -> - let ilScopeRef = st.TypeProviderAssemblyRef - let enclosingName = ExtensionTyping.GetFSharpPathToProvidedType(st, m) - CompPath(ilScopeRef, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace)) - | Some p -> p - let pubpath = cpath.NestedPublicPath id - - let repr = Construct.NewProvidedTyconRepr(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) - - Tycon.New "tycon" - { entity_stamp=stamp - entity_logical_name=name - entity_range=m - entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) - entity_attribs=[] // fetched on demand via est.fs API - entity_typars= LazyWithContext.NotLazy [] - entity_tycon_repr = repr - entity_tycon_tcaug=TyconAugmentation.Create() - entity_modul_contents = MaybeLazy.Lazy (lazy new ModuleOrNamespaceType(Namespace, QueueList.ofList [], QueueList.ofList [])) - // Generated types get internal accessibility - entity_pubpath = Some pubpath - entity_cpath = Some cpath - entity_il_repr_cache = newCache() - entity_opt_data = - match kind, access with - | TyparKind.Type, TAccess [] -> None - | _ -> Some { Entity.NewEmptyEntityOptData() with entity_kind = kind; entity_accessibility = access } } -#endif - - static member NewModuleOrNamespace cpath access (id: Ident) xml attribs mtype = - let stamp = newStamp() - // Put the module suffix on if needed - Tycon.New "mspec" - { entity_logical_name=id.idText - entity_range = id.idRange - entity_stamp=stamp - entity_modul_contents = mtype - entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=true, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) - entity_typars=LazyWithContext.NotLazy [] - entity_tycon_repr = TNoRepr - entity_tycon_tcaug=TyconAugmentation.Create() - entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) - entity_cpath=cpath - entity_attribs=attribs - entity_il_repr_cache = newCache() - entity_opt_data = - match xml, access with - | XmlDoc [||], TAccess [] -> None - | _ -> Some { Entity.NewEmptyEntityOptData() with entity_xmldoc = xml; entity_tycon_repr_accessibility = access; entity_accessibility = access } } - -and - [] - Accessibility = - /// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope. - | TAccess of CompilationPath list - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "Accessibility(...)" - -and - [] - TyparOptionalData = - { - /// MUTABILITY: we set the names of generalized inference type parameters to make the look nice for IL code generation - mutable typar_il_name: string option - - /// The documentation for the type parameter. Empty for type inference variables. - /// MUTABILITY: for linking when unpickling - mutable typar_xmldoc: XmlDoc - - /// The inferred constraints for the type inference variable - mutable typar_constraints: TyparConstraint list - - /// The declared attributes of the type parameter. Empty for type inference variables. - mutable typar_attribs: Attribs - } - - [] - member x.DebugText = x.ToString() - - override __.ToString() = sprintf "TyparOptionalData(...)" - -and TyparData = Typar - -and - [] - /// A declared generic type/measure parameter, or a type/measure inference variable. - Typar = - // Backing data for type parameters and type inference variables - // - // where the "common" settings are - // kind=TyparKind.Type, rigid=TyparRigidity.Flexible, id=compgen_id, staticReq=NoStaticReq, isCompGen=true, isFromError=false, - // dynamicReq=TyparDynamicReq.No, attribs=[], eqDep=false, compDep=false - - { /// MUTABILITY: we set the names of generalized inference type parameters to make the look nice for IL code generation - mutable typar_id: Ident - - mutable typar_flags: TyparFlags - - /// The unique stamp of the typar blob. - /// MUTABILITY: for linking when unpickling - mutable typar_stamp: Stamp - - /// An inferred equivalence for a type inference variable. - mutable typar_solution: TType option - - /// A cached TAST type used when this type variable is used as type. - mutable typar_astype: TType - - mutable typar_opt_data: TyparOptionalData option } - - /// The name of the type parameter - member x.Name = x.typar_id.idText - - /// The range of the identifier for the type parameter definition - member x.Range = x.typar_id.idRange - - /// The identifier for a type parameter definition - member x.Id = x.typar_id - - /// The unique stamp of the type parameter - member x.Stamp = x.typar_stamp - - /// The inferred equivalence for the type inference variable, if any. - member x.Solution = x.typar_solution - - /// The inferred constraints for the type inference variable, if any - member x.Constraints = - match x.typar_opt_data with - | Some optData -> optData.typar_constraints - | _ -> [] - - /// Indicates if the type variable is compiler generated, i.e. is an implicit type inference variable - member x.IsCompilerGenerated = x.typar_flags.IsCompilerGenerated - - /// Indicates if the type variable can be solved or given new constraints. The status of a type variable - /// generally always evolves towards being either rigid or solved. - member x.Rigidity = x.typar_flags.Rigidity - - /// Indicates if a type parameter is needed at runtime and may not be eliminated - member x.DynamicReq = x.typar_flags.DynamicReq - - /// Indicates that whether or not a generic type definition satisfies the equality constraint is dependent on whether this type variable satisfies the equality constraint. - member x.EqualityConditionalOn = x.typar_flags.EqualityConditionalOn - - /// Indicates that whether or not a generic type definition satisfies the comparison constraint is dependent on whether this type variable satisfies the comparison constraint. - member x.ComparisonConditionalOn = x.typar_flags.ComparisonConditionalOn - - /// Indicates if the type variable has a static "head type" requirement, i.e. ^a variables used in FSharp.Core and member constraints. - member x.StaticReq = x.typar_flags.StaticReq - - /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns - member x.IsFromError = x.typar_flags.IsFromError - - /// Indicates that whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) - member x.IsCompatFlex = x.typar_flags.IsCompatFlex - - /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) - member x.SetIsCompatFlex b = x.typar_flags <- x.typar_flags.WithCompatFlex b - - /// Indicates whether a type variable can be instantiated by types or units-of-measure. - member x.Kind = x.typar_flags.Kind - - /// Indicates whether a type variable is erased in compiled .NET IL code, i.e. whether it is a unit-of-measure variable - member x.IsErased = match x.Kind with TyparKind.Type -> false | _ -> true - - /// The declared attributes of the type parameter. Empty for type inference variables and parameters from .NET - member x.Attribs = - match x.typar_opt_data with - | Some optData -> optData.typar_attribs - | _ -> [] - - member x.SetAttribs attribs = - match attribs, x.typar_opt_data with - | [], None -> () - | [], Some { typar_il_name = None; typar_xmldoc = XmlDoc [||]; typar_constraints = [] } -> - x.typar_opt_data <- None - | _, Some optData -> optData.typar_attribs <- attribs - | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } - - member x.XmlDoc = - match x.typar_opt_data with - | Some optData -> optData.typar_xmldoc - | _ -> XmlDoc.Empty - - member x.ILName = - match x.typar_opt_data with - | Some optData -> optData.typar_il_name - | _ -> None - - member x.SetILName il_name = - match x.typar_opt_data with - | Some optData -> optData.typar_il_name <- il_name - | _ -> x.typar_opt_data <- Some { typar_il_name = il_name; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = [] } - - /// Indicates the display name of a type variable - member x.DisplayName = if x.Name = "?" then "?"+string x.Stamp else x.Name - - /// Adjusts the constraints associated with a type variable - member x.SetConstraints cs = - match cs, x.typar_opt_data with - | [], None -> () - | [], Some { typar_il_name = None; typar_xmldoc = XmlDoc [||]; typar_attribs = [] } -> - x.typar_opt_data <- None - | _, Some optData -> optData.typar_constraints <- cs - | _ -> x.typar_opt_data <- Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = cs; typar_attribs = [] } - - - /// Creates a type variable that contains empty data, and is not yet linked. Only used during unpickling of F# metadata. - static member NewUnlinked() : Typar = - { typar_id = Unchecked.defaultof<_> - typar_flags = Unchecked.defaultof<_> - typar_stamp = -1L - typar_solution = Unchecked.defaultof<_> - typar_astype = Unchecked.defaultof<_> - typar_opt_data = Unchecked.defaultof<_> } - - /// Creates a type variable based on the given data. Only used during unpickling of F# metadata. - static member New (data: TyparData) : Typar = data - - /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. - member x.Link (tg: TyparData) = - x.typar_id <- tg.typar_id - x.typar_flags <- tg.typar_flags - x.typar_stamp <- tg.typar_stamp - x.typar_solution <- tg.typar_solution - match tg.typar_opt_data with - | Some tg -> - let optData = { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs } - x.typar_opt_data <- Some optData - | None -> () - - /// Links a previously unlinked type variable to the given data. Only used during unpickling of F# metadata. - member x.AsType = - let ty = x.typar_astype - match box ty with - | null -> - let ty2 = TType_var x - x.typar_astype <- ty2 - ty2 - | _ -> ty - - /// Indicates if a type variable has been linked. Only used during unpickling of F# metadata. - member x.IsLinked = x.typar_stamp <> -1L - - /// Indicates if a type variable has been solved. - member x.IsSolved = - match x.Solution with - | None -> false - | _ -> true - - /// Sets the identifier associated with a type variable - member x.SetIdent id = x.typar_id <- id - - /// Sets the rigidity of a type variable - member x.SetRigidity b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) - - /// Sets whether a type variable is compiler generated - member x.SetCompilerGenerated b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) - - /// Sets whether a type variable has a static requirement - member x.SetStaticReq b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, b, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) - - /// Sets whether a type variable is required at runtime - member x.SetDynamicReq b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) - - /// Sets whether the equality constraint of a type definition depends on this type variable - member x.SetEqualityDependsOn b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn) - - /// Sets whether the comparison constraint of a type definition depends on this type variable - member x.SetComparisonDependsOn b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.Name - -and - [] - TyparConstraint = - /// Indicates a constraint that a type is a subtype of the given type - | CoercesTo of TType * range - - /// Indicates a default value for an inference type variable should it be neither generalized nor solved - | DefaultsTo of int * TType * range - - /// Indicates a constraint that a type has a 'null' value - | SupportsNull of range - - /// Indicates a constraint that a type has a member with the given signature - | MayResolveMember of TraitConstraintInfo * range - - /// Indicates a constraint that a type is a non-Nullable value type - /// These are part of .NET's model of generic constraints, and in order to - /// generate verifiable code we must attach them to F# generalized type variables as well. - | IsNonNullableStruct of range - - /// Indicates a constraint that a type is a reference type - | IsReferenceType of range - - /// Indicates a constraint that a type is a simple choice between one of the given ground types. Only arises from 'printf' format strings. See format.fs - | SimpleChoice of TTypes * range - - /// Indicates a constraint that a type has a parameterless constructor - | RequiresDefaultConstructor of range - - /// Indicates a constraint that a type is an enum with the given underlying - | IsEnum of TType * range - - /// Indicates a constraint that a type implements IComparable, with special rules for some known structural container types - | SupportsComparison of range - - /// Indicates a constraint that a type does not have the Equality(false) attribute, or is not a structural type with this attribute, with special rules for some known structural container types - | SupportsEquality of range - - /// Indicates a constraint that a type is a delegate from the given tuple of args to the given return type - | IsDelegate of TType * TType * range - - /// Indicates a constraint that a type is .NET unmanaged type - | IsUnmanaged of range - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// The specification of a member constraint that must be solved -and - [] - TraitConstraintInfo = - - /// TTrait(tys, nm, memFlags, argtys, rty, solution) - /// - /// Indicates the signature of a member constraint. Contains a mutable solution cell - /// to store the inferred solution of the constraint. - | TTrait of TTypes * string * MemberFlags * TTypes * TType option * TraitConstraintSln option ref - - /// Get the member name associated with the member constraint. - member x.MemberName = (let (TTrait(_, nm, _, _, _, _)) = x in nm) - - /// Get the return type recorded in the member constraint. - member x.ReturnType = (let (TTrait(_, _, _, _, ty, _)) = x in ty) - - /// Get or set the solution of the member constraint during inference - member x.Solution - with get() = (let (TTrait(_, _, _, _, _, sln)) = x in sln.Value) - and set v = (let (TTrait(_, _, _, _, _, sln)) = x in sln.Value <- v) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TTrait(" + x.MemberName + ")" - -and - [] - /// Indicates the solution of a member constraint during inference. - TraitConstraintSln = - - /// FSMethSln(ty, vref, minst) - /// - /// Indicates a trait is solved by an F# method. - /// ty -- the type and its instantiation - /// vref -- the method that solves the trait constraint - /// minst -- the generic method instantiation - | FSMethSln of TType * ValRef * TypeInst - - /// FSRecdFieldSln(tinst, rfref, isSetProp) - /// - /// Indicates a trait is solved by an F# record field. - /// tinst -- the instantiation of the declaring type - /// rfref -- the reference to the record field - /// isSetProp -- indicates if this is a set of a record field - | FSRecdFieldSln of TypeInst * RecdFieldRef * bool - - /// Indicates a trait is solved by an F# anonymous record field. - | FSAnonRecdFieldSln of AnonRecdTypeInfo * TypeInst * int - - /// ILMethSln(ty, extOpt, ilMethodRef, minst) - /// - /// Indicates a trait is solved by a .NET method. - /// ty -- the type and its instantiation - /// extOpt -- information about an extension member, if any - /// ilMethodRef -- the method that solves the trait constraint - /// minst -- the generic method instantiation - | ILMethSln of TType * ILTypeRef option * ILMethodRef * TypeInst - - /// ClosedExprSln expr - /// - /// Indicates a trait is solved by an erased provided expression - | ClosedExprSln of Expr - - /// Indicates a trait is solved by a 'fake' instance of an operator, like '+' on integers - | BuiltInSln - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// The partial information used to index the methods of all those in a ModuleOrNamespace. -and [] - ValLinkagePartialKey = - { /// The name of the type with which the member is associated. None for non-member values. - MemberParentMangledName: string option - - /// Indicates if the member is an override. - MemberIsOverride: bool - - /// Indicates the logical name of the member. - LogicalName: string - - /// Indicates the total argument count of the member. - TotalArgCount: int } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ValLinkagePartialKey(" + x.LogicalName + ")" - -/// The full information used to identify a specific overloaded method -/// amongst all those in a ModuleOrNamespace. -and - [< (* NoEquality; NoComparison; *) StructuredFormatDisplay("{DebugText}")>] - ValLinkageFullKey(partialKey: ValLinkagePartialKey, typeForLinkage: TType option) = - - /// The partial information used to index the value in a ModuleOrNamespace. - member x.PartialKey = partialKey - - /// The full type of the value for the purposes of linking. May be None for non-members, since they can't be overloaded. - member x.TypeForLinkage = typeForLinkage - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ValLinkageFullKey(" + partialKey.LogicalName + ")" - -and - [] - ValOptionalData = - { - /// MUTABILITY: for unpickle linkage - mutable val_compiled_name: string option - - /// If this field is populated, this is the implementation range for an item in a signature, otherwise it is - /// the signature range for an item in an implementation - mutable val_other_range: (range * bool) option - - mutable val_const: Const option - - /// What is the original, unoptimized, closed-term definition, if any? - /// Used to implement [] - mutable val_defn: Expr option - - // MUTABILITY CLEANUP: mutability of this field is used by - // -- adjustAllUsesOfRecValue - // -- TLR optimizations - // -- LinearizeTopMatch - // - // For example, we use mutability to replace the empty arity initially assumed with an arity garnered from the - // type-checked expression. - mutable val_repr_info: ValReprInfo option - - /// How visible is this? - /// MUTABILITY: for unpickle linkage - mutable val_access: Accessibility - - /// XML documentation attached to a value. - /// MUTABILITY: for unpickle linkage - mutable val_xmldoc: XmlDoc - - /// Is the value actually an instance method/property/event that augments - /// a type, and if so what name does it take in the IL? - /// MUTABILITY: for unpickle linkage - mutable val_member_info: ValMemberInfo option - - // MUTABILITY CLEANUP: mutability of this field is used by - // -- LinearizeTopMatch - // - // The fresh temporary should just be created with the right parent - mutable val_declaring_entity: ParentRef - - /// XML documentation signature for the value - mutable val_xmldocsig: string - - /// Custom attributes attached to the value. These contain references to other values (i.e. constructors in types). Mutable to fixup - /// these value references after copying a collection of values. - mutable val_attribs: Attribs - } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ValOptionalData(...)" - -and ValData = Val -and [] - Val = - { /// Mutable for unpickle linkage - mutable val_logical_name: string - - /// Mutable for unpickle linkage - mutable val_range: range - - mutable val_type: TType - - /// Mutable for unpickle linkage - mutable val_stamp: Stamp - - /// See vflags section further below for encoding/decodings here - mutable val_flags: ValFlags - - mutable val_opt_data: ValOptionalData option } - - static member NewEmptyValOptData() = - { val_compiled_name = None - val_other_range = None - val_const = None - val_defn = None - val_repr_info = None - val_access = TAccess [] - val_xmldoc = XmlDoc.Empty - val_member_info = None - val_declaring_entity = ParentNone - val_xmldocsig = String.Empty - val_attribs = [] } - - /// Range of the definition (implementation) of the value, used by Visual Studio - member x.DefinitionRange = - match x.val_opt_data with - | Some { val_other_range = Some(m, true) } -> m - | _ -> x.val_range - - /// Range of the definition (signature) of the value, used by Visual Studio - member x.SigRange = - match x.val_opt_data with - | Some { val_other_range = Some(m, false) } -> m - | _ -> x.val_range - - /// The place where the value was defined. - member x.Range = x.val_range - - /// A unique stamp within the context of this invocation of the compiler process - member x.Stamp = x.val_stamp - - /// The type of the value. - /// May be a TType_forall for a generic value. - /// May be a type variable or type containing type variables during type inference. - // - // Note: this data is mutated during inference by adjustAllUsesOfRecValue when we replace the inferred type with a schema. - member x.Type = x.val_type - - /// How visible is this value, function or member? - member x.Accessibility = - match x.val_opt_data with - | Some optData -> optData.val_access - | _ -> TAccess [] - - /// The value of a value or member marked with [] - member x.LiteralValue = - match x.val_opt_data with - | Some optData -> optData.val_const - | _ -> None - - /// Records the "extra information" for a value compiled as a method. - /// - /// This indicates the number of arguments in each position for a curried - /// functions, and relates to the F# spec for arity analysis. - /// For module-defined values, the currying is based - /// on the number of lambdas, and in each position the elements are - /// based on attempting to deconstruct the type of the argument as a - /// tuple-type. - /// - /// The field is mutable because arities for recursive - /// values are only inferred after the r.h.s. is analyzed, but the - /// value itself is created before the r.h.s. is analyzed. - /// - /// TLR also sets this for inner bindings that it wants to - /// represent as "top level" bindings. - member x.ValReprInfo: ValReprInfo option = - match x.val_opt_data with - | Some optData -> optData.val_repr_info - | _ -> None - - member x.Id = ident(x.LogicalName, x.Range) - - /// Is this represented as a "top level" static binding (i.e. a static field, static member, - /// instance member), rather than an "inner" binding that may result in a closure. - /// - /// This is implied by IsMemberOrModuleBinding, however not vice versa, for two reasons. - /// Some optimizations mutate this value when they decide to change the representation of a - /// binding to be IsCompiledAsTopLevel. Second, even immediately after type checking we expect - /// some non-module, non-member bindings to be marked IsCompiledAsTopLevel, e.g. 'y' in - /// 'let x = let y = 1 in y + y' (NOTE: check this, don't take it as gospel) - member x.IsCompiledAsTopLevel = x.ValReprInfo.IsSome - - /// The partial information used to index the methods of all those in a ModuleOrNamespace. - member x.GetLinkagePartialKey() : ValLinkagePartialKey = - assert x.IsCompiledAsTopLevel - { LogicalName = x.LogicalName - MemberParentMangledName = (if x.IsMember then Some x.MemberApparentEntity.LogicalName else None) - MemberIsOverride = x.IsOverrideOrExplicitImpl - TotalArgCount = if x.IsMember then x.ValReprInfo.Value.TotalArgCount else 0 } - - /// The full information used to identify a specific overloaded method amongst all those in a ModuleOrNamespace. - member x.GetLinkageFullKey() : ValLinkageFullKey = - assert x.IsCompiledAsTopLevel - let key = x.GetLinkagePartialKey() - ValLinkageFullKey(key, (if x.IsMember then Some x.Type else None)) - - /// Is this a member definition or module definition? - member x.IsMemberOrModuleBinding = x.val_flags.IsMemberOrModuleBinding - - /// Indicates if this is an F#-defined extension member - member x.IsExtensionMember = x.val_flags.IsExtensionMember - - /// The quotation expression associated with a value given the [] tag - member x.ReflectedDefinition = - match x.val_opt_data with - | Some optData -> optData.val_defn - | _ -> None - - /// Is this a member, if so some more data about the member. - /// - /// Note, the value may still be (a) an extension member or (b) and abstract slot without - /// a true body. These cases are often causes of bugs in the compiler. - member x.MemberInfo = - match x.val_opt_data with - | Some optData -> optData.val_member_info - | _ -> None - - /// Indicates if this is a member - member x.IsMember = x.MemberInfo.IsSome - - /// Indicates if this is a member, excluding extension members - member x.IsIntrinsicMember = x.IsMember && not x.IsExtensionMember - - /// Indicates if this is an F#-defined value in a module, or an extension member, but excluding compiler generated bindings from optimizations - member x.IsModuleBinding = x.IsMemberOrModuleBinding && not x.IsMember - - /// Indicates if this is something compiled into a module, i.e. a user-defined value, an extension member or a compiler-generated value - member x.IsCompiledIntoModule = x.IsExtensionMember || x.IsModuleBinding - - /// Indicates if this is an F#-defined instance member. - /// - /// Note, the value may still be (a) an extension member or (b) and abstract slot without - /// a true body. These cases are often causes of bugs in the compiler. - member x.IsInstanceMember = x.IsMember && x.MemberInfo.Value.MemberFlags.IsInstance - - /// Indicates if this is an F#-defined 'new' constructor member - member x.IsConstructor = - match x.MemberInfo with - | Some memberInfo when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = MemberKind.Constructor) -> true - | _ -> false - - /// Indicates if this is a compiler-generated class constructor member - member x.IsClassConstructor = - match x.MemberInfo with - | Some memberInfo when not x.IsExtensionMember && (memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor) -> true - | _ -> false - - /// Indicates if this value was a member declared 'override' or an implementation of an interface slot - member x.IsOverrideOrExplicitImpl = - match x.MemberInfo with - | Some memberInfo when memberInfo.MemberFlags.IsOverrideOrExplicitImpl -> true - | _ -> false - - /// Indicates if this is declared 'mutable' - member x.IsMutable = (match x.val_flags.MutabilityInfo with Immutable -> false | Mutable -> true) - - /// Indicates if this is inferred to be a method or function that definitely makes no critical tailcalls? - member x.MakesNoCriticalTailcalls = x.val_flags.MakesNoCriticalTailcalls - - /// Indicates if this is ever referenced? - member x.HasBeenReferenced = x.val_flags.HasBeenReferenced - - /// Indicates if the backing field for a static value is suppressed. - member x.IsCompiledAsStaticPropertyWithoutField = - let hasValueAsStaticProperty = x.Attribs |> List.exists(fun (Attrib(tc, _, _, _, _, _, _)) -> tc.CompiledName = "ValueAsStaticPropertyAttribute") - x.val_flags.IsCompiledAsStaticPropertyWithoutField || hasValueAsStaticProperty - - /// Indicates if the value is pinned/fixed - member x.IsFixed = x.val_flags.IsFixed - - /// Indicates if the value will ignore byref scoping rules - member x.IgnoresByrefScope = x.val_flags.IgnoresByrefScope - - /// Indicates if this value allows the use of an explicit type instantiation (i.e. does it itself have explicit type arguments, - /// or does it have a signature?) - member x.PermitsExplicitTypeInstantiation = x.val_flags.PermitsExplicitTypeInstantiation - - /// Indicates if this is a member generated from the de-sugaring of 'let' function bindings in the implicit class syntax? - member x.IsIncrClassGeneratedMember = x.IsCompilerGenerated && x.val_flags.IsIncrClassSpecialMember - - /// Indicates if this is a constructor member generated from the de-sugaring of implicit constructor for a class type? - member x.IsIncrClassConstructor = x.IsConstructor && x.val_flags.IsIncrClassSpecialMember - - /// Get the information about the value used during type inference - member x.RecursiveValInfo = x.val_flags.RecursiveValInfo - - /// Indicates if this is a 'base' or 'this' value? - member x.BaseOrThisInfo = x.val_flags.BaseOrThisInfo - - // Indicates if this value was declared to be a type function, e.g. "let f<'a> = typeof<'a>" - member x.IsTypeFunction = x.val_flags.IsTypeFunction - - /// Get the inline declaration on the value - member x.InlineInfo = x.val_flags.InlineInfo - - /// Indicates whether the inline declaration for the value indicate that the value must be inlined? - member x.MustInline = x.InlineInfo.MustInline - - /// Indicates whether this value was generated by the compiler. - /// - /// Note: this is true for the overrides generated by hash/compare augmentations - member x.IsCompilerGenerated = x.val_flags.IsCompilerGenerated - - /// Get the declared attributes for the value - member x.Attribs = - match x.val_opt_data with - | Some optData -> optData.val_attribs - | _ -> [] - - /// Get the declared documentation for the value - member x.XmlDoc = - match x.val_opt_data with - | Some optData -> optData.val_xmldoc - | _ -> XmlDoc.Empty - - ///Get the signature for the value's XML documentation - member x.XmlDocSig - with get() = - match x.val_opt_data with - | Some optData -> optData.val_xmldocsig - | _ -> String.Empty - and set v = - match x.val_opt_data with - | Some optData -> optData.val_xmldocsig <- v - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_xmldocsig = v } - - /// The parent type or module, if any (None for expression bindings and parameters) - member x.DeclaringEntity = - match x.val_opt_data with - | Some optData -> optData.val_declaring_entity - | _ -> ParentNone - - /// Get the actual parent entity for the value (a module or a type), i.e. the entity under which the - /// value will appear in compiled code. For extension members this is the module where the extension member - /// is declared. - member x.TopValDeclaringEntity = - match x.DeclaringEntity with - | Parent tcref -> tcref - | ParentNone -> error(InternalError("TopValDeclaringEntity: does not have a parent", x.Range)) - - member x.HasDeclaringEntity = - match x.DeclaringEntity with - | Parent _ -> true - | ParentNone -> false - - /// Get the apparent parent entity for a member - member x.MemberApparentEntity: TyconRef = - match x.MemberInfo with - | Some membInfo -> membInfo.ApparentEnclosingEntity - | None -> error(InternalError("MemberApparentEntity", x.Range)) - - /// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'. - member v.NumObjArgs = - match v.MemberInfo with - | Some membInfo -> if membInfo.MemberFlags.IsInstance then 1 else 0 - | None -> 0 - - /// Get the apparent parent entity for the value, i.e. the entity under with which the - /// value is associated. For extension members this is the nominal type the member extends. - /// For other values it is just the actual parent. - member x.ApparentEnclosingEntity = - match x.MemberInfo with - | Some membInfo -> Parent(membInfo.ApparentEnclosingEntity) - | None -> x.DeclaringEntity - - /// Get the public path to the value, if any? Should be set if and only if - /// IsMemberOrModuleBinding is set. - // - // We use it here: - // - in opt.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) - // - in ilxgen.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) - // - in opt.fs: (fullDebugTextOfValRef) for error reporting of non-inlinable values - // - in service.fs (boutput_item_description): to display the full text of a value's binding location - // - in check.fs: as a boolean to detect public values for saving quotations - // - in ilxgen.fs: as a boolean to detect public values for saving quotations - // - in MakeExportRemapping, to build non-local references for values - member x.PublicPath = - match x.DeclaringEntity with - | Parent eref -> - match eref.PublicPath with - | None -> None - | Some p -> Some(ValPubPath(p, x.GetLinkageFullKey())) - | ParentNone -> - None - - /// Indicates if this member is an F#-defined dispatch slot. - member x.IsDispatchSlot = - match x.MemberInfo with - | Some membInfo -> membInfo.MemberFlags.IsDispatchSlot - | _ -> false - - /// Get the type of the value including any generic type parameters - member x.TypeScheme = - match x.Type with - | TType_forall(tps, tau) -> tps, tau - | ty -> [], ty - - /// Get the type of the value after removing any generic type parameters - member x.TauType = - match x.Type with - | TType_forall(_, tau) -> tau - | ty -> ty - - /// Get the generic type parameters for the value - member x.Typars = - match x.Type with - | TType_forall(tps, _) -> tps - | _ -> [] - - /// The name of the method. - /// - If this is a property then this is 'get_Foo' or 'set_Foo' - /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot - /// - If this is an extension member then this will be the simple name - member x.LogicalName = - match x.MemberInfo with - | None -> x.val_logical_name - | Some membInfo -> - match membInfo.ImplementedSlotSigs with - | slotsig :: _ -> slotsig.Name - | _ -> x.val_logical_name - - member x.ValCompiledName = - match x.val_opt_data with - | Some optData -> optData.val_compiled_name - | _ -> None - - /// The name of the method in compiled code (with some exceptions where ilxgen.fs decides not to use a method impl) - /// - If this is a property then this is 'get_Foo' or 'set_Foo' - /// - If this is an implementation of an abstract slot then this may be a mangled name - /// - If this is an extension member then this will be a mangled name - /// - If this is an operator then this is 'op_Addition' - member x.CompiledName (compilerGlobalState:CompilerGlobalState option) = - let givenName = - match x.val_opt_data with - | Some { val_compiled_name = Some n } -> n - | _ -> x.LogicalName - // These cases must get stable unique names for their static field & static property. This name - // must be stable across quotation generation and IL code generation (quotations can refer to the - // properties implicit in these) - // - // Variable 'x' here, which is compiled as a top level static: - // do let x = expr in ... // IsMemberOrModuleBinding = false, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=false - // - // The implicit 'patternInput' variable here: - // let [x] = expr in ... // IsMemberOrModuleBinding = true, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=true - // - // The implicit 'copyOfStruct' variables here: - // let dt = System.DateTime.Now - System.DateTime.Now // IsMemberOrModuleBinding = false, IsCompiledAsTopLevel = true, IsMember = false, CompilerGenerated=true - // - // However we don't need this for CompilerGenerated members such as the implementations of IComparable - match compilerGlobalState with - | Some state when x.IsCompiledAsTopLevel && not x.IsMember && (x.IsCompilerGenerated || not x.IsMemberOrModuleBinding) -> - state.StableNameGenerator.GetUniqueCompilerGeneratedName(givenName, x.Range, x.Stamp) - | _ -> givenName - - /// The name of the property. - /// - If this is a property then this is 'Foo' - /// - If this is an implementation of an abstract slot then this is the name of the property implemented by the abstract slot - member x.PropertyName = - let logicalName = x.LogicalName - ChopPropertyName logicalName - - /// The name of the method. - /// - If this is a property then this is 'Foo' - /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot - /// - If this is an operator then this is 'op_Addition' - member x.CoreDisplayName = - match x.MemberInfo with - | Some membInfo -> - match membInfo.MemberFlags.MemberKind with - | MemberKind.ClassConstructor - | MemberKind.Constructor - | MemberKind.Member -> x.LogicalName - | MemberKind.PropertyGetSet - | MemberKind.PropertySet - | MemberKind.PropertyGet -> x.PropertyName - | None -> x.LogicalName - - /// - If this is a property then this is 'Foo' - /// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot - /// - If this is an operator then this is '(+)' - member x.DisplayName = - DemangleOperatorName x.CoreDisplayName - - member x.SetValRec b = x.val_flags <- x.val_flags.WithRecursiveValInfo b - - member x.SetIsMemberOrModuleBinding() = x.val_flags <- x.val_flags.WithIsMemberOrModuleBinding - - member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.WithMakesNoCriticalTailcalls - - member x.SetHasBeenReferenced() = x.val_flags <- x.val_flags.WithHasBeenReferenced - - member x.SetIsCompiledAsStaticPropertyWithoutField() = x.val_flags <- x.val_flags.WithIsCompiledAsStaticPropertyWithoutField - - member x.SetIsFixed() = x.val_flags <- x.val_flags.WithIsFixed - - member x.SetIgnoresByrefScope() = x.val_flags <- x.val_flags.WithIgnoresByrefScope - - member x.SetValReprInfo info = - match x.val_opt_data with - | Some optData -> optData.val_repr_info <- info - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_repr_info = info } - - member x.SetType ty = x.val_type <- ty - - member x.SetOtherRange m = - match x.val_opt_data with - | Some optData -> optData.val_other_range <- Some m - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_other_range = Some m } - - member x.SetDeclaringEntity parent = - match x.val_opt_data with - | Some optData -> optData.val_declaring_entity <- parent - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_declaring_entity = parent } - - member x.SetAttribs attribs = - match x.val_opt_data with - | Some optData -> optData.val_attribs <- attribs - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_attribs = attribs } - - member x.SetMemberInfo member_info = - match x.val_opt_data with - | Some optData -> optData.val_member_info <- Some member_info - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_member_info = Some member_info } - - member x.SetValDefn val_defn = - match x.val_opt_data with - | Some optData -> optData.val_defn <- Some val_defn - | _ -> x.val_opt_data <- Some { Val.NewEmptyValOptData() with val_defn = Some val_defn } - - /// Create a new value with empty, unlinked data. Only used during unpickling of F# metadata. - static member NewUnlinked() : Val = - { val_logical_name = Unchecked.defaultof<_> - val_range = Unchecked.defaultof<_> - val_type = Unchecked.defaultof<_> - val_stamp = Unchecked.defaultof<_> - val_flags = Unchecked.defaultof<_> - val_opt_data = Unchecked.defaultof<_> } - - - /// Create a new value with the given backing data. Only used during unpickling of F# metadata. - static member New data: Val = data - - /// Link a value based on empty, unlinked data to the given data. Only used during unpickling of F# metadata. - member x.Link (tg: ValData) = x.SetData tg - - /// Set all the data on a value - member x.SetData (tg: ValData) = - x.val_logical_name <- tg.val_logical_name - x.val_range <- tg.val_range - x.val_type <- tg.val_type - x.val_stamp <- tg.val_stamp - x.val_flags <- tg.val_flags - match tg.val_opt_data with - | Some tg -> - x.val_opt_data <- - Some { val_compiled_name = tg.val_compiled_name - val_other_range = tg.val_other_range - val_const = tg.val_const - val_defn = tg.val_defn - val_repr_info = tg.val_repr_info - val_access = tg.val_access - val_xmldoc = tg.val_xmldoc - val_member_info = tg.val_member_info - val_declaring_entity = tg.val_declaring_entity - val_xmldocsig = tg.val_xmldocsig - val_attribs = tg.val_attribs } - | None -> () - - /// Indicates if a value is linked to backing data yet. Only used during unpickling of F# metadata. - member x.IsLinked = match box x.val_logical_name with null -> false | _ -> true - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.LogicalName - - -and - /// Represents the extra information stored for a member - [] - ValMemberInfo = - { /// The parent type. For an extension member this is the type being extended - ApparentEnclosingEntity: TyconRef - - /// Updated with the full implemented slotsig after interface implementation relation is checked - mutable ImplementedSlotSigs: SlotSig list - - /// Gets updated with 'true' if an abstract slot is implemented in the file being typechecked. Internal only. - mutable IsImplemented: bool - - MemberFlags: MemberFlags } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ValMemberInfo(...)" - -and - [] - NonLocalValOrMemberRef = - { /// A reference to the entity containing the value or member. This will always be a non-local reference - EnclosingEntity: EntityRef - - /// The name of the value, or the full signature of the member - ItemKey: ValLinkageFullKey } - - /// Get the thunk for the assembly referred to - member x.Ccu = x.EnclosingEntity.nlr.Ccu - - /// Get the name of the assembly referred to - member x.AssemblyName = x.EnclosingEntity.nlr.AssemblyName - - /// For debugging - [] - member x.DebugText = x.ToString() - - /// For debugging - override x.ToString() = x.EnclosingEntity.nlr.ToString() + "::" + x.ItemKey.PartialKey.LogicalName - -and - [] - ValPublicPath = - | ValPubPath of PublicPath * ValLinkageFullKey - - [] - member x.DebugText = x.ToString() - - override __.ToString() = sprintf "ValPubPath(...)" - -/// Index into the namespace/module structure of a particular CCU -and - [] - NonLocalEntityRef = - | NonLocalEntityRef of CcuThunk * string[] - - /// Try to find the entity corresponding to the given path in the given CCU - static member TryDerefEntityPath(ccu: CcuThunk, path: string[], i: int, entity: Entity) = - if i >= path.Length then ValueSome entity - else - match entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryGetValue path.[i] with - | true, res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res) -#if !NO_EXTENSIONTYPING - | _ -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity) -#else - | _ -> ValueNone -#endif - -#if !NO_EXTENSIONTYPING - /// Try to find the entity corresponding to the given path, using type-providers to link the data - static member TryDerefEntityPathViaProvidedType(ccu: CcuThunk, path: string[], i: int, entity: Entity) = - // Errors during linking are not necessarily given good ranges. This has always been the case in F# 2.0, but also applies to - // type provider type linking errors in F# 3.0. - let m = range0 - match entity.TypeReprInfo with - | TProvidedTypeExtensionPoint info -> - let resolutionEnvironment = info.ResolutionEnvironment - let st = info.ProvidedType - - // In this case, we're safely in the realm of types. Just iterate through the nested - // types until i = path.Length-1. Create the Tycon's as needed - let rec tryResolveNestedTypeOf(parentEntity: Entity, resolutionEnvironment, st: Tainted, i) = - match st.PApply((fun st -> st.GetNestedType path.[i]), m) with - | Tainted.Null -> ValueNone - | st -> - let newEntity = Construct.NewProvidedTycon(resolutionEnvironment, st, ccu.ImportProvidedType, false, m) - parentEntity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity - if i = path.Length-1 then ValueSome newEntity - else tryResolveNestedTypeOf(newEntity, resolutionEnvironment, st, i+1) - - tryResolveNestedTypeOf(entity, resolutionEnvironment, st, i) - - | TProvidedNamespaceExtensionPoint(resolutionEnvironment, resolvers) -> - - // In this case, we're still in the realm of extensible namespaces. - // <----entity--> - // 0 .........i-1..i .......... j ..... path.Length-1 - // - // <----entity--> <---resolver----> - // 0 .........i-1..i ............. j ..... path.Length-1 - // - // <----entity--> <---resolver----> <--loop---> - // 0 .........i-1..i ............. j ..... path.Length-1 - // - // We now query the resolvers with - // moduleOrNamespace = path.[0..j-1] - // typeName = path.[j] - // starting with j = i and then progressively increasing j - - // This function queries at 'j' - let tryResolvePrefix j = - assert (j >= 0) - assert (j <= path.Length - 1) - let matched = - [ for resolver in resolvers do - let moduleOrNamespace = if j = 0 then null else path.[0..j-1] - let typename = path.[j] - let resolution = ExtensionTyping.TryLinkProvidedType(resolver, moduleOrNamespace, typename, m) - match resolution with - | None | Some (Tainted.Null) -> () - | Some st -> yield (resolver, st) ] - match matched with - | [(_, st)] -> - // 'entity' is at position i in the dereference chain. We resolved to position 'j'. - // Inject namespaces until we're an position j, and then inject the type. - // Note: this is similar to code in CompileOps.fs - let rec injectNamespacesFromIToJ (entity: Entity) k = - if k = j then - let newEntity = Construct.NewProvidedTycon(resolutionEnvironment, st, ccu.ImportProvidedType, false, m) - entity.ModuleOrNamespaceType.AddProvidedTypeEntity newEntity - newEntity - else - let cpath = entity.CompilationPath.NestedCompPath entity.LogicalName ModuleOrNamespaceKind.Namespace - let newEntity = - Construct.NewModuleOrNamespace - (Some cpath) - (TAccess []) (ident(path.[k], m)) XmlDoc.Empty [] - (MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType Namespace)) - entity.ModuleOrNamespaceType.AddModuleOrNamespaceByMutation newEntity - injectNamespacesFromIToJ newEntity (k+1) - let newEntity = injectNamespacesFromIToJ entity i - - // newEntity is at 'j' - NonLocalEntityRef.TryDerefEntityPath(ccu, path, (j+1), newEntity) - - | [] -> ValueNone - | _ -> failwith "Unexpected" - - let rec tryResolvePrefixes j = - if j >= path.Length then ValueNone - else match tryResolvePrefix j with - | ValueNone -> tryResolvePrefixes (j+1) - | ValueSome res -> ValueSome res - - tryResolvePrefixes i - - | _ -> ValueNone -#endif - - /// Try to link a non-local entity reference to an actual entity - member nleref.TryDeref canError = - let (NonLocalEntityRef(ccu, path)) = nleref - if canError then - ccu.EnsureDerefable path - - if ccu.IsUnresolvedReference then ValueNone else - - match NonLocalEntityRef.TryDerefEntityPath(ccu, path, 0, ccu.Contents) with - | ValueSome _ as r -> r - | ValueNone -> - // OK, the lookup failed. Check if we can redirect through a type forwarder on this assembly. - // Look for a forwarder for each prefix-path - let rec tryForwardPrefixPath i = - if i < path.Length then - match ccu.TryForward(path.[0..i-1], path.[i]) with - // OK, found a forwarder, now continue with the lookup to find the nested type - | Some tcref -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), tcref.Deref) - | None -> tryForwardPrefixPath (i+1) - else - ValueNone - tryForwardPrefixPath 0 - - /// Get the CCU referenced by the nonlocal reference. - member nleref.Ccu = - let (NonLocalEntityRef(ccu, _)) = nleref - ccu - - /// Get the path into the CCU referenced by the nonlocal reference. - member nleref.Path = - let (NonLocalEntityRef(_, p)) = nleref - p - - member nleref.DisplayName = - String.concat "." nleref.Path - - /// Get the mangled name of the last item in the path of the nonlocal reference. - member nleref.LastItemMangledName = - let p = nleref.Path - p.[p.Length-1] - - /// Get the all-but-last names of the path of the nonlocal reference. - member nleref.EnclosingMangledPath = - let p = nleref.Path - p.[0..p.Length-2] - - /// Get the name of the assembly referenced by the nonlocal reference. - member nleref.AssemblyName = nleref.Ccu.AssemblyName - - /// Dereference the nonlocal reference, and raise an error if this fails. - member nleref.Deref = - match nleref.TryDeref(canError=true) with - | ValueSome res -> res - | ValueNone -> - errorR (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespace, nleref.DisplayName, nleref.AssemblyName, "")) - raise (KeyNotFoundException()) - - /// Get the details of the module or namespace fragment for the entity referred to by this non-local reference. - member nleref.ModuleOrNamespaceType = - nleref.Deref.ModuleOrNamespaceType - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.DisplayName - -and - [] - EntityRef = - { /// Indicates a reference to something bound in this CCU - mutable binding: NonNullSlot - /// Indicates a reference to something bound in another CCU - nlr: NonLocalEntityRef } - - member x.IsLocalRef = match box x.nlr with null -> true | _ -> false - - member x.IsResolved = match box x.binding with null -> false | _ -> true - - member x.PrivateTarget = x.binding - - member x.ResolvedTarget = x.binding - - member private tcr.Resolve canError = - let res = tcr.nlr.TryDeref canError - match res with - | ValueSome r -> - tcr.binding <- nullableSlotFull r - | ValueNone -> - () - - /// Dereference the TyconRef to a Tycon. Amortize the cost of doing this. - /// This path should not allocate in the amortized case - member tcr.Deref = - match box tcr.binding with - | null -> - tcr.Resolve(canError=true) - match box tcr.binding with - | null -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefModuleNamespaceType, String.concat "." tcr.nlr.EnclosingMangledPath, tcr.nlr.AssemblyName, tcr.nlr.LastItemMangledName)) - | _ -> tcr.binding - | _ -> - tcr.binding - - /// Dereference the TyconRef to a Tycon option. - member tcr.TryDeref = - match box tcr.binding with - | null -> - tcr.Resolve(canError=false) - match box tcr.binding with - | null -> ValueNone - | _ -> ValueSome tcr.binding - - | _ -> - ValueSome tcr.binding - - /// Is the destination assembly available? - member tcr.CanDeref = tcr.TryDeref.IsSome - - /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. - member x.CompiledRepresentation = x.Deref.CompiledRepresentation - - /// Gets the data indicating the compiled representation of a named type or module in terms of Abstract IL data structures. - member x.CompiledRepresentationForNamedType = x.Deref.CompiledRepresentationForNamedType - - /// The implementation definition location of the namespace, module or type - member x.DefinitionRange = x.Deref.DefinitionRange - - /// The signature definition location of the namespace, module or type - member x.SigRange = x.Deref.SigRange - - /// The name of the namespace, module or type, possibly with mangling, e.g. List`1, List or FailureException - member x.LogicalName = x.Deref.LogicalName - - /// The compiled name of the namespace, module or type, e.g. FSharpList`1, ListModule or FailureException - member x.CompiledName = x.Deref.CompiledName - - /// The display name of the namespace, module or type, e.g. List instead of List`1, not including static parameters - member x.DisplayName = x.Deref.DisplayName - - /// The display name of the namespace, module or type with <_, _, _> added for generic types, including static parameters - member x.DisplayNameWithStaticParametersAndUnderscoreTypars = x.Deref.DisplayNameWithStaticParametersAndUnderscoreTypars - - /// The display name of the namespace, module or type, e.g. List instead of List`1, including static parameters - member x.DisplayNameWithStaticParameters = x.Deref.DisplayNameWithStaticParameters - - /// The code location where the module, namespace or type is defined. - member x.Range = x.Deref.Range - - /// A unique stamp for this module, namespace or type definition within the context of this compilation. - /// Note that because of signatures, there are situations where in a single compilation the "same" - /// module, namespace or type may have two distinct Entity objects that have distinct stamps. - member x.Stamp = x.Deref.Stamp - - /// The F#-defined custom attributes of the entity, if any. If the entity is backed by Abstract IL or provided metadata - /// then this does not include any attributes from those sources. - member x.Attribs = x.Deref.Attribs - - /// The XML documentation of the entity, if any. If the entity is backed by provided metadata - /// then this _does_ include this documentation. If the entity is backed by Abstract IL metadata - /// or comes from another F# assembly then it does not (because the documentation will get read from - /// an XML file). - member x.XmlDoc = x.Deref.XmlDoc - - /// The XML documentation sig-string of the entity, if any, to use to lookup an .xml doc file. This also acts - /// as a cache for this sig-string computation. - member x.XmlDocSig = x.Deref.XmlDocSig - - /// The logical contents of the entity when it is a module or namespace fragment. - member x.ModuleOrNamespaceType = x.Deref.ModuleOrNamespaceType - - /// Demangle the module name, if FSharpModuleWithSuffix is used - member x.DemangledModuleOrNamespaceName = x.Deref.DemangledModuleOrNamespaceName - - /// The logical contents of the entity when it is a type definition. - member x.TypeContents = x.Deref.TypeContents - - /// The kind of the type definition - is it a measure definition or a type definition? - member x.TypeOrMeasureKind = x.Deref.TypeOrMeasureKind - - /// The identifier at the point of declaration of the type definition. - member x.Id = x.Deref.Id - - /// The information about the r.h.s. of a type definition, if any. For example, the r.h.s. of a union or record type. - member x.TypeReprInfo = x.Deref.TypeReprInfo - - /// The information about the r.h.s. of an F# exception definition, if any. - member x.ExceptionInfo = x.Deref.ExceptionInfo - - /// Indicates if the entity represents an F# exception declaration. - member x.IsExceptionDecl = x.Deref.IsExceptionDecl - - /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. - /// - /// Lazy because it may read metadata, must provide a context "range" in case error occurs reading metadata. - member x.Typars m = x.Deref.Typars m - - /// Get the type parameters for an entity that is a type declaration, otherwise return the empty list. - member x.TyparsNoRange = x.Deref.TyparsNoRange - - /// Indicates if this entity is an F# type abbreviation definition - member x.TypeAbbrev = x.Deref.TypeAbbrev - - /// Indicates if this entity is an F# type abbreviation definition - member x.IsTypeAbbrev = x.Deref.IsTypeAbbrev - - /// Get the value representing the accessibility of the r.h.s. of an F# type definition. - member x.TypeReprAccessibility = x.Deref.TypeReprAccessibility - - /// Get the cache of the compiled ILTypeRef representation of this module or type. - member x.CompiledReprCache = x.Deref.CompiledReprCache - - /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member x.PublicPath: PublicPath option = x.Deref.PublicPath - - /// Get the value representing the accessibility of an F# type definition or module. - member x.Accessibility = x.Deref.Accessibility - - /// Indicates the type prefers the "tycon" syntax for display etc. - member x.IsPrefixDisplay = x.Deref.IsPrefixDisplay - - /// Indicates the "tycon blob" is actually a module - member x.IsModuleOrNamespace = x.Deref.IsModuleOrNamespace - - /// Indicates if the entity is a namespace - member x.IsNamespace = x.Deref.IsNamespace - - /// Indicates if the entity is an F# module definition - member x.IsModule = x.Deref.IsModule - - /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. - member x.CompilationPathOpt = x.Deref.CompilationPathOpt - -#if !NO_EXTENSIONTYPING - /// Indicates if the entity is a provided namespace fragment - member x.IsProvided = x.Deref.IsProvided - - /// Indicates if the entity is a provided namespace fragment - member x.IsProvidedNamespace = x.Deref.IsProvidedNamespace - - /// Indicates if the entity is an erased provided type definition - member x.IsProvidedErasedTycon = x.Deref.IsProvidedErasedTycon - - /// Indicates if the entity is an erased provided type definition that incorporates a static instantiation (and therefore in some sense compiler generated) - member x.IsStaticInstantiationTycon = x.Deref.IsStaticInstantiationTycon - - /// Indicates if the entity is a generated provided type definition, i.e. not erased. - member x.IsProvidedGeneratedTycon = x.Deref.IsProvidedGeneratedTycon -#endif - - /// Get a blob of data indicating how this type is nested inside other namespaces, modules and types. - member x.CompilationPath = x.Deref.CompilationPath - - /// Get a table of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldTable = x.Deref.AllFieldTable - - /// Get an array of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldsArray = x.Deref.AllFieldsArray - - /// Get a list of fields for all the F#-defined record, struct and class fields in this type definition, including - /// static fields, 'val' declarations and hidden fields from the compilation of implicit class constructions. - member x.AllFieldsAsList = x.Deref.AllFieldsAsList - - /// Get a list of all fields for F#-defined record, struct and class fields in this type definition, - /// including static fields, but excluding compiler-generate fields. - member x.TrueFieldsAsList = x.Deref.TrueFieldsAsList - - /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition, - /// excluding compiler-generate fields. - member x.TrueInstanceFieldsAsList = x.Deref.TrueInstanceFieldsAsList - - /// Get a list of all instance fields for F#-defined record, struct and class fields in this type definition. - /// including hidden fields from the compilation of implicit class constructions. - // NOTE: This method doesn't perform particularly well, and is over-used, but doesn't seem to appear on performance traces - member x.AllInstanceFieldsAsList = x.Deref.AllInstanceFieldsAsList - - /// Get a field by index in definition order - member x.GetFieldByIndex n = x.Deref.GetFieldByIndex n - - /// Get a field by name. - member x.GetFieldByName n = x.Deref.GetFieldByName n - - /// Get the union cases and other union-type information for a type, if any - member x.UnionTypeInfo = x.Deref.UnionTypeInfo - - /// Get the union cases for a type, if any - member x.UnionCasesArray = x.Deref.UnionCasesArray - - /// Get the union cases for a type, if any, as a list - member x.UnionCasesAsList = x.Deref.UnionCasesAsList - - /// Get a union case of a type by name - member x.GetUnionCaseByName n = x.Deref.GetUnionCaseByName n - - /// Get the blob of information associated with an F# object-model type definition, i.e. class, interface, struct etc. - member x.FSharpObjectModelTypeInfo = x.Deref.FSharpObjectModelTypeInfo - - /// Gets the immediate interface definitions of an F# type definition. Further interfaces may be supported through class and interface inheritance. - member x.ImmediateInterfacesOfFSharpTycon = x.Deref.ImmediateInterfacesOfFSharpTycon - - /// Gets the immediate interface types of an F# type definition. Further interfaces may be supported through class and interface inheritance. - member x.ImmediateInterfaceTypesOfFSharpTycon = x.Deref.ImmediateInterfaceTypesOfFSharpTycon - - /// Gets the immediate members of an F# type definition, excluding compiler-generated ones. - /// Note: result is alphabetically sorted, then for each name the results are in declaration order - member x.MembersOfFSharpTyconSorted = x.Deref.MembersOfFSharpTyconSorted - - /// Gets all immediate members of an F# type definition keyed by name, including compiler-generated ones. - /// Note: result is a indexed table, and for each name the results are in reverse declaration order - member x.MembersOfFSharpTyconByName = x.Deref.MembersOfFSharpTyconByName - - /// Indicates if this is a struct or enum type definition, i.e. a value type definition - member x.IsStructOrEnumTycon = x.Deref.IsStructOrEnumTycon - - /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll which uses - /// an assembly-code representation for the type, e.g. the primitive array type constructor. - member x.IsAsmReprTycon = x.Deref.IsAsmReprTycon - - /// Indicates if this is an F# type definition which is one of the special types in FSharp.Core.dll like 'float<_>' which - /// defines a measure type with a relation to an existing non-measure type as a representation. - member x.IsMeasureableReprTycon = x.Deref.IsMeasureableReprTycon - - /// Indicates if the entity is erased, either a measure definition, or an erased provided type definition - member x.IsErased = x.Deref.IsErased - - /// Gets any implicit hash/equals (with comparer argument) methods added to an F# record, union or struct type definition. - member x.GeneratedHashAndEqualsWithComparerValues = x.Deref.GeneratedHashAndEqualsWithComparerValues - - /// Gets any implicit CompareTo (with comparer argument) methods added to an F# record, union or struct type definition. - member x.GeneratedCompareToWithComparerValues = x.Deref.GeneratedCompareToWithComparerValues - - /// Gets any implicit CompareTo methods added to an F# record, union or struct type definition. - member x.GeneratedCompareToValues = x.Deref.GeneratedCompareToValues - - /// Gets any implicit hash/equals methods added to an F# record, union or struct type definition. - member x.GeneratedHashAndEqualsValues = x.Deref.GeneratedHashAndEqualsValues - - /// Indicate if this is a type definition backed by Abstract IL metadata. - member x.IsILTycon = x.Deref.IsILTycon - - /// Get the Abstract IL scope, nesting and metadata for this - /// type definition, assuming it is backed by Abstract IL metadata. - member x.ILTyconInfo = x.Deref.ILTyconInfo - - /// Get the Abstract IL metadata for this type definition, assuming it is backed by Abstract IL metadata. - member x.ILTyconRawMetadata = x.Deref.ILTyconRawMetadata - - /// Indicate if this is a type whose r.h.s. is known to be a union type definition. - member x.IsUnionTycon = x.Deref.IsUnionTycon - - /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition. - member x.IsRecordTycon = x.Deref.IsRecordTycon - - /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition - member x.IsFSharpObjectModelTycon = x.Deref.IsFSharpObjectModelTycon - - /// The on-demand analysis about whether the entity has the IsByRefLike attribute - member x.TryIsByRefLike = x.Deref.TryIsByRefLike - - /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute - member x.SetIsByRefLike b = x.Deref.SetIsByRefLike b - - /// The on-demand analysis about whether the entity has the IsReadOnly attribute - member x.TryIsReadOnly = x.Deref.TryIsReadOnly - - /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute - member x.SetIsReadOnly b = x.Deref.SetIsReadOnly b - - /// The on-demand analysis about whether the entity is assumed to be a readonly struct - member x.TryIsAssumedReadOnly = x.Deref.TryIsAssumedReadOnly - - /// Set the on-demand analysis about whether the entity is assumed to be a readonly struct - member x.SetIsAssumedReadOnly b = x.Deref.SetIsAssumedReadOnly b - - /// Indicates if this is an F# type definition whose r.h.s. definition is unknown (i.e. a traditional ML 'abstract' type in a signature, - /// which in F# is called a 'unknown representation' type). - member x.IsHiddenReprTycon = x.Deref.IsHiddenReprTycon - - /// Indicates if this is an F#-defined interface type definition - member x.IsFSharpInterfaceTycon = x.Deref.IsFSharpInterfaceTycon - - /// Indicates if this is an F#-defined delegate type definition - member x.IsFSharpDelegateTycon = x.Deref.IsFSharpDelegateTycon - - /// Indicates if this is an F#-defined enum type definition - member x.IsFSharpEnumTycon = x.Deref.IsFSharpEnumTycon - - /// Indicates if this is a .NET-defined enum type definition - member x.IsILEnumTycon = x.Deref.IsILEnumTycon - - /// Indicates if this is an enum type definition - member x.IsEnumTycon = x.Deref.IsEnumTycon - - /// Indicates if this is an F#-defined struct or enum type definition, i.e. a value type definition - member x.IsFSharpStructOrEnumTycon = x.Deref.IsFSharpStructOrEnumTycon - - /// Indicates if this is a .NET-defined struct or enum type definition, i.e. a value type definition - member x.IsILStructOrEnumTycon = x.Deref.IsILStructOrEnumTycon - - /// Indicates if we have pre-determined that a type definition has a default constructor. - member x.PreEstablishedHasDefaultConstructor = x.Deref.PreEstablishedHasDefaultConstructor - - /// Indicates if we have pre-determined that a type definition has a self-referential constructor using 'as x' - member x.HasSelfReferentialConstructor = x.Deref.HasSelfReferentialConstructor - - member x.UnionCasesAsRefList = x.UnionCasesAsList |> List.map x.MakeNestedUnionCaseRef - - member x.TrueInstanceFieldsAsRefList = x.TrueInstanceFieldsAsList |> List.map x.MakeNestedRecdFieldRef - - member x.AllFieldAsRefList = x.AllFieldsAsList |> List.map x.MakeNestedRecdFieldRef - - member x.MakeNestedRecdFieldRef (rf: RecdField) = RFRef (x, rf.Name) - - member x.MakeNestedUnionCaseRef (uc: UnionCase) = UCRef (x, uc.Id.idText) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = - if x.IsLocalRef then - x.ResolvedTarget.DisplayName - else - x.nlr.DisplayName - - -/// note: ModuleOrNamespaceRef and TyconRef are type equivalent -and ModuleOrNamespaceRef = EntityRef - -and TyconRef = EntityRef - -/// References are either local or nonlocal -and - [] - ValRef = - { /// Indicates a reference to something bound in this CCU - mutable binding: NonNullSlot - /// Indicates a reference to something bound in another CCU - nlr: NonLocalValOrMemberRef } - - member x.IsLocalRef = obj.ReferenceEquals(x.nlr, null) - - member x.IsResolved = not (obj.ReferenceEquals(x.binding, null)) - - member x.PrivateTarget = x.binding - - member x.ResolvedTarget = x.binding - - /// Dereference the ValRef to a Val. - member vr.Deref = - if obj.ReferenceEquals(vr.binding, null) then - let res = - let nlr = vr.nlr - let e = nlr.EnclosingEntity.Deref - let possible = e.ModuleOrNamespaceType.TryLinkVal(nlr.EnclosingEntity.nlr.Ccu, nlr.ItemKey) - match possible with - | ValueNone -> error (InternalUndefinedItemRef (FSComp.SR.tastUndefinedItemRefVal, e.DisplayNameWithStaticParameters, nlr.AssemblyName, sprintf "%+A" nlr.ItemKey.PartialKey)) - | ValueSome h -> h - vr.binding <- nullableSlotFull res - res - else vr.binding - - /// Dereference the ValRef to a Val option. - member vr.TryDeref = - if obj.ReferenceEquals(vr.binding, null) then - let resOpt = - match vr.nlr.EnclosingEntity.TryDeref with - | ValueNone -> ValueNone - | ValueSome e -> e.ModuleOrNamespaceType.TryLinkVal(vr.nlr.EnclosingEntity.nlr.Ccu, vr.nlr.ItemKey) - match resOpt with - | ValueNone -> () - | ValueSome res -> - vr.binding <- nullableSlotFull res - resOpt - else ValueSome vr.binding - - /// The type of the value. May be a TType_forall for a generic value. - /// May be a type variable or type containing type variables during type inference. - member x.Type = x.Deref.Type - - /// Get the type of the value including any generic type parameters - member x.TypeScheme = x.Deref.TypeScheme - - /// Get the type of the value after removing any generic type parameters - member x.TauType = x.Deref.TauType - - member x.Typars = x.Deref.Typars - - member x.LogicalName = x.Deref.LogicalName - - member x.DisplayName = x.Deref.DisplayName - - member x.CoreDisplayName = x.Deref.CoreDisplayName - - member x.Range = x.Deref.Range - - /// Get the value representing the accessibility of an F# type definition or module. - member x.Accessibility = x.Deref.Accessibility - - /// The parent type or module, if any (None for expression bindings and parameters) - member x.DeclaringEntity = x.Deref.DeclaringEntity - - /// Get the apparent parent entity for the value, i.e. the entity under with which the - /// value is associated. For extension members this is the nominal type the member extends. - /// For other values it is just the actual parent. - member x.ApparentEnclosingEntity = x.Deref.ApparentEnclosingEntity - - member x.DefinitionRange = x.Deref.DefinitionRange - - member x.SigRange = x.Deref.SigRange - - /// The value of a value or member marked with [] - member x.LiteralValue = x.Deref.LiteralValue - - member x.Id = x.Deref.Id - - /// Get the name of the value, assuming it is compiled as a property. - /// - If this is a property then this is 'Foo' - /// - If this is an implementation of an abstract slot then this is the name of the property implemented by the abstract slot - member x.PropertyName = x.Deref.PropertyName - - /// Indicates whether this value represents a property getter. - member x.IsPropertyGetterMethod = - match x.MemberInfo with - | None -> false - | Some (memInfo: ValMemberInfo) -> memInfo.MemberFlags.MemberKind = MemberKind.PropertyGet || memInfo.MemberFlags.MemberKind = MemberKind.PropertyGetSet - - /// Indicates whether this value represents a property setter. - member x.IsPropertySetterMethod = - match x.MemberInfo with - | None -> false - | Some (memInfo: ValMemberInfo) -> memInfo.MemberFlags.MemberKind = MemberKind.PropertySet || memInfo.MemberFlags.MemberKind = MemberKind.PropertyGetSet - - /// A unique stamp within the context of this invocation of the compiler process - member x.Stamp = x.Deref.Stamp - - /// Is this represented as a "top level" static binding (i.e. a static field, static member, - /// instance member), rather than an "inner" binding that may result in a closure. - member x.IsCompiledAsTopLevel = x.Deref.IsCompiledAsTopLevel - - /// Indicates if this member is an F#-defined dispatch slot. - member x.IsDispatchSlot = x.Deref.IsDispatchSlot - - /// The name of the method in compiled code (with some exceptions where ilxgen.fs decides not to use a method impl) - member x.CompiledName = x.Deref.CompiledName - - /// Get the public path to the value, if any? Should be set if and only if - /// IsMemberOrModuleBinding is set. - member x.PublicPath = x.Deref.PublicPath - - /// The quotation expression associated with a value given the [] tag - member x.ReflectedDefinition = x.Deref.ReflectedDefinition - - /// Indicates if this is an F#-defined 'new' constructor member - member x.IsConstructor = x.Deref.IsConstructor - - /// Indicates if this value was a member declared 'override' or an implementation of an interface slot - member x.IsOverrideOrExplicitImpl = x.Deref.IsOverrideOrExplicitImpl - - /// Is this a member, if so some more data about the member. - member x.MemberInfo = x.Deref.MemberInfo - - /// Indicates if this is a member - member x.IsMember = x.Deref.IsMember - - /// Indicates if this is an F#-defined value in a module, or an extension member, but excluding compiler generated bindings from optimizations - member x.IsModuleBinding = x.Deref.IsModuleBinding - - /// Indicates if this is an F#-defined instance member. - /// - /// Note, the value may still be (a) an extension member or (b) and abstract slot without - /// a true body. These cases are often causes of bugs in the compiler. - member x.IsInstanceMember = x.Deref.IsInstanceMember - - /// Indicates if this value is declared 'mutable' - member x.IsMutable = x.Deref.IsMutable - - /// Indicates if this value allows the use of an explicit type instantiation (i.e. does it itself have explicit type arguments, - /// or does it have a signature?) - member x.PermitsExplicitTypeInstantiation = x.Deref.PermitsExplicitTypeInstantiation - - /// Indicates if this is inferred to be a method or function that definitely makes no critical tailcalls? - member x.MakesNoCriticalTailcalls = x.Deref.MakesNoCriticalTailcalls - - /// Is this a member definition or module definition? - member x.IsMemberOrModuleBinding = x.Deref.IsMemberOrModuleBinding - - /// Indicates if this is an F#-defined extension member - member x.IsExtensionMember = x.Deref.IsExtensionMember - - /// Indicates if this is a constructor member generated from the de-sugaring of implicit constructor for a class type? - member x.IsIncrClassConstructor = x.Deref.IsIncrClassConstructor - - /// Indicates if this is a member generated from the de-sugaring of 'let' function bindings in the implicit class syntax? - member x.IsIncrClassGeneratedMember = x.Deref.IsIncrClassGeneratedMember - - /// Get the information about a recursive value used during type inference - member x.RecursiveValInfo = x.Deref.RecursiveValInfo - - /// Indicates if this is a 'base' or 'this' value? - member x.BaseOrThisInfo = x.Deref.BaseOrThisInfo - - // Indicates if this value was declared to be a type function, e.g. "let f<'a> = typeof<'a>" - member x.IsTypeFunction = x.Deref.IsTypeFunction - - /// Records the "extra information" for a value compiled as a method. - /// - /// This indicates the number of arguments in each position for a curried function. - member x.ValReprInfo = x.Deref.ValReprInfo - - /// Get the inline declaration on the value - member x.InlineInfo = x.Deref.InlineInfo - - /// Indicates whether the inline declaration for the value indicate that the value must be inlined? - member x.MustInline = x.Deref.MustInline - - /// Indicates whether this value was generated by the compiler. - /// - /// Note: this is true for the overrides generated by hash/compare augmentations - member x.IsCompilerGenerated = x.Deref.IsCompilerGenerated - - /// Get the declared attributes for the value - member x.Attribs = x.Deref.Attribs - - /// Get the declared documentation for the value - member x.XmlDoc = x.Deref.XmlDoc - - /// Get or set the signature for the value's XML documentation - member x.XmlDocSig = x.Deref.XmlDocSig - - /// Get the actual parent entity for the value (a module or a type), i.e. the entity under which the - /// value will appear in compiled code. For extension members this is the module where the extension member - /// is declared. - member x.TopValDeclaringEntity = x.Deref.TopValDeclaringEntity - - // Can be false for members after error recovery - member x.HasDeclaringEntity = x.Deref.HasDeclaringEntity - - /// Get the apparent parent entity for a member - member x.MemberApparentEntity = x.Deref.MemberApparentEntity - - /// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'. - member x.NumObjArgs = x.Deref.NumObjArgs - - [] - member x.DebugText = x.ToString() - - override x.ToString() = - if x.IsLocalRef then x.ResolvedTarget.DisplayName - else x.nlr.ToString() - -/// Represents a reference to a case of a union type -and - [] - UnionCaseRef = - | UCRef of TyconRef * string - - /// Get a reference to the type containing this union case - member x.TyconRef = let (UCRef(tcref, _)) = x in tcref - - /// Get the name of this union case - member x.CaseName = let (UCRef(_, nm)) = x in nm - - /// Get the Entity for the type containing this union case - member x.Tycon = x.TyconRef.Deref - - /// Dereference the reference to the union case - member x.UnionCase = - match x.TyconRef.GetUnionCaseByName x.CaseName with - | Some res -> res - | None -> error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) - - /// Try to dereference the reference - member x.TryUnionCase = - x.TyconRef.TryDeref - |> ValueOptionInternal.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOptionInternal.ofOption) - - /// Get the attributes associated with the union case - member x.Attribs = x.UnionCase.Attribs - - /// Get the range of the union case - member x.Range = x.UnionCase.Range - - /// Get the definition range of the union case - member x.DefinitionRange = x.UnionCase.DefinitionRange - - /// Get the signature range of the union case - member x.SigRange = x.UnionCase.SigRange - - /// Get the index of the union case amongst the cases - member x.Index = - try - // REVIEW: this could be faster, e.g. by storing the index in the NameMap - x.TyconRef.UnionCasesArray |> Array.findIndex (fun ucspec -> ucspec.DisplayName = x.CaseName) - with :? KeyNotFoundException -> - error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) - - /// Get the fields of the union case - member x.AllFieldsAsList = x.UnionCase.FieldTable.AllFieldsAsList - - /// Get the resulting type of the union case - member x.ReturnType = x.UnionCase.ReturnType - - /// Get a field of the union case by index - member x.FieldByIndex n = x.UnionCase.FieldTable.FieldByIndex n - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.CaseName - -/// Represents a reference to a field in a record, class or struct -and - [] - RecdFieldRef = - | RFRef of TyconRef * string - - /// Get a reference to the type containing this union case - member x.TyconRef = let (RFRef(tcref, _)) = x in tcref - - /// Get the name off the field - member x.FieldName = let (RFRef(_, id)) = x in id - - /// Get the Entity for the type containing this union case - member x.Tycon = x.TyconRef.Deref - - /// Dereference the reference - member x.RecdField = - let (RFRef(tcref, id)) = x - match tcref.GetFieldByName id with - | Some res -> res - | None -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) - - /// Try to dereference the reference - member x.TryRecdField = - x.TyconRef.TryDeref - |> ValueOptionInternal.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) - - /// Get the attributes associated with the compiled property of the record field - member x.PropertyAttribs = x.RecdField.PropertyAttribs - - /// Get the declaration range of the record field - member x.Range = x.RecdField.Range - - /// Get the definition range of the record field - member x.DefinitionRange = x.RecdField.DefinitionRange - - /// Get the signature range of the record field - member x.SigRange = x.RecdField.SigRange - - member x.Index = - let (RFRef(tcref, id)) = x - try - // REVIEW: this could be faster, e.g. by storing the index in the NameMap - tcref.AllFieldsArray |> Array.findIndex (fun rfspec -> rfspec.Name = id) - with :? KeyNotFoundException -> - error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = x.FieldName - -and - /// The algebra of types - [] - TType = - - /// TType_forall(typars, bodyTy). - /// - /// Indicates the type is a universal type, only used for types of values and members - | TType_forall of Typars * TType - - /// TType_app(tyconRef, typeInstantiation). - /// - /// Indicates the type is built from a named type and a number of type arguments - | TType_app of TyconRef * TypeInst - - /// TType_anon - /// - /// Indicates the type is an anonymous record type whose compiled representation is located in the given assembly - | TType_anon of AnonRecdTypeInfo * TType list - - /// TType_tuple(elementTypes). - /// - /// Indicates the type is a tuple type. elementTypes must be of length 2 or greater. - | TType_tuple of TupInfo * TTypes - - /// TType_fun(domainType, rangeType). - /// - /// Indicates the type is a function type - | TType_fun of TType * TType - - /// TType_ucase(unionCaseRef, typeInstantiation) - /// - /// Indicates the type is a non-F#-visible type representing a "proof" that a union value belongs to a particular union case - /// These types are not user-visible and will never appear as an inferred type. They are the types given to - /// the temporaries arising out of pattern matching on union values. - | TType_ucase of UnionCaseRef * TypeInst - - /// Indicates the type is a variable type, whether declared, generalized or an inference type parameter - | TType_var of Typar - - /// Indicates the type is a unit-of-measure expression being used as an argument to a type or member - | TType_measure of Measure - - /// For now, used only as a discriminant in error message. - /// See https://github.com/Microsoft/visualfsharp/issues/2561 - member x.GetAssemblyName() = - match x with - | TType_forall (_tps, ty) -> ty.GetAssemblyName() - | TType_app (tcref, _tinst) -> tcref.CompilationPath.ILScopeRef.QualifiedName - | TType_tuple (_tupInfo, _tinst) -> "" - | TType_anon (anonInfo, _tinst) -> defaultArg anonInfo.Assembly.QualifiedName "" - | TType_fun (_d, _r) -> "" - | TType_measure _ms -> "" - | TType_var tp -> tp.Solution |> function Some sln -> sln.GetAssemblyName() | None -> "" - | TType_ucase (_uc, _tinst) -> - let (TILObjectReprData(scope, _nesting, _definition)) = _uc.Tycon.ILTyconInfo - scope.QualifiedName - - [] - member x.DebugText = x.ToString() - - override x.ToString() = - match x with - | TType_forall (_tps, ty) -> "forall ... " + ty.ToString() - | TType_app (tcref, tinst) -> tcref.DisplayName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") - | TType_tuple (tupInfo, tinst) -> - (match tupInfo with - | TupInfo.Const false -> "" - | TupInfo.Const true -> "struct ") - + String.concat "," (List.map string tinst) - | TType_anon (anonInfo, tinst) -> - (match anonInfo.TupInfo with - | TupInfo.Const false -> "" - | TupInfo.Const true -> "struct ") - + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + ")" + "|}" - | TType_fun (d, r) -> "(" + string d + " -> " + string r + ")" - | TType_ucase (uc, tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") - | TType_var tp -> - match tp.Solution with - | None -> tp.DisplayName - | Some _ -> tp.DisplayName + " (solved)" - | TType_measure ms -> ms.ToString() - -and TypeInst = TType list - -and TTypes = TType list -and [] AnonRecdTypeInfo = - // Mutability for pickling/unpickling only - { mutable Assembly: CcuThunk - mutable TupInfo: TupInfo - mutable SortedIds: Ident[] - mutable Stamp: Stamp - mutable SortedNames: string[] } - - /// Create an AnonRecdTypeInfo from the basic data - static member Create(ccu: CcuThunk, tupInfo, ids: Ident[]) = - let sortedIds = ids |> Array.sortBy (fun id -> id.idText) - // Hash all the data to form a unique stamp - let stamp = - sha1HashInt64 - [| for c in ccu.AssemblyName do yield byte c; yield byte (int32 c >>> 8) - match tupInfo with - | TupInfo.Const b -> yield (if b then 0uy else 1uy) - for id in sortedIds do - for c in id.idText do yield byte c; yield byte (int32 c >>> 8) |] - let sortedNames = Array.map textOfId sortedIds - { Assembly = ccu; TupInfo = tupInfo; SortedIds = sortedIds; Stamp = stamp; SortedNames = sortedNames } - - /// Get the ILTypeRef for the generated type implied by the anonymous type - member x.ILTypeRef = - let ilTypeName = sprintf "<>f__AnonymousType%s%u`%d" (match x.TupInfo with TupInfo.Const b -> if b then "1000" else "") (uint32 x.Stamp) x.SortedIds.Length - mkILTyRef(x.Assembly.ILScopeRef, ilTypeName) - - static member NewUnlinked() : AnonRecdTypeInfo = - { Assembly = Unchecked.defaultof<_> - TupInfo = Unchecked.defaultof<_> - SortedIds = Unchecked.defaultof<_> - Stamp = Unchecked.defaultof<_> - SortedNames = Unchecked.defaultof<_> } - - member x.Link d = - let sortedNames = Array.map textOfId d.SortedIds - x.Assembly <- d.Assembly - x.TupInfo <- d.TupInfo - x.SortedIds <- d.SortedIds - x.Stamp <- d.Stamp - x.SortedNames <- sortedNames - - member x.IsLinked = (match x.SortedIds with null -> true | _ -> false) - -and [] TupInfo = - /// Some constant, e.g. true or false for tupInfo - | Const of bool - -and - [] - Measure = - /// A variable unit-of-measure - | Var of Typar - - /// A constant, leaf unit-of-measure such as 'kg' or 'm' - | Con of TyconRef - - /// A product of two units of measure - | Prod of Measure*Measure - - /// An inverse of a units of measure expression - | Inv of Measure - - /// The unit of measure '1', e.g. float = float<1> - | One - - /// Raising a measure to a rational power - | RationalPower of Measure * Rational - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -and - [] - CcuData = - { /// Holds the filename for the DLL, if any - FileName: string option - - /// Holds the data indicating how this assembly/module is referenced from the code being compiled. - ILScopeRef: ILScopeRef - - /// A unique stamp for this DLL - Stamp: Stamp - - /// The fully qualified assembly reference string to refer to this assembly. This is persisted in quotations - QualifiedName: string option - - /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) - SourceCodeDirectory: string - - /// Indicates that this DLL was compiled using the F# compiler and has F# metadata - IsFSharp: bool - -#if !NO_EXTENSIONTYPING - /// Is the CCu an assembly injected by a type provider - IsProviderGenerated: bool - - /// Triggered when the contents of the CCU are invalidated - InvalidateEvent: IEvent - - /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality - /// logic in tastops.fs - ImportProvidedType: Tainted -> TType - -#endif - /// Indicates that this DLL uses pre-F#-4.0 quotation literals somewhere. This is used to implement a restriction on static linking - mutable UsesFSharp20PlusQuotations: bool - - /// A handle to the full specification of the contents of the module contained in this ccu - // NOTE: may contain transient state during typechecking - mutable Contents: ModuleOrNamespace - - /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality - /// logic in tastops.fs - TryGetILModuleDef: (unit -> ILModuleDef option) - - /// A helper function used to link method signatures using type equality. This is effectively a forward call to the type equality - /// logic in tastops.fs - MemberSignatureEquality: (TType -> TType -> bool) - - /// The table of .NET CLI type forwarders for this assembly - TypeForwarders: CcuTypeForwarderTable } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "CcuData(%A)" x.FileName - -/// Represents a table of .NET CLI type forwarders for an assembly -and CcuTypeForwarderTable = Map> - -and CcuReference = string // ILAssemblyRef - - -/// A relinkable handle to the contents of a compilation unit. Relinking is performed by mutation. -// -/// A compilation unit is, more or less, the new material created in one -/// invocation of the compiler. Due to static linking assemblies may hold more -/// than one compilation unit (i.e. when two assemblies are merged into a compilation -/// the resulting assembly will contain 3 CUs). Compilation units are also created for referenced -/// .NET assemblies. -/// -/// References to items such as type constructors are via -/// cross-compilation-unit thunks, which directly reference the data structures that define -/// these modules. Thus, when saving out values to disk we only wish -/// to save out the "current" part of the term graph. When reading values -/// back in we "fixup" the links to previously referenced modules. -/// -/// All non-local accesses to the data structures are mediated -/// by ccu-thunks. Ultimately, a ccu-thunk is either a (named) element of -/// the data structure, or it is a delayed fixup, i.e. an invalid dangling -/// reference that has not had an appropriate fixup applied. -and - [] - CcuThunk = - { mutable target: CcuData - - /// ccu.orphanfixup is true when a reference is missing in the transitive closure of static references that - /// may potentially be required for the metadata of referenced DLLs. It is set to true if the "loader" - /// used in the F# metadata-deserializer or the .NET metadata reader returns a failing value (e.g. None). - /// Note: When used from Visual Studio, the loader will not automatically chase down transitively referenced DLLs - they - /// must be in the explicit references in the project. - mutable orphanfixup: bool - - name: CcuReference } - - member ccu.Deref = - if isNull (ccu.target :> obj) || ccu.orphanfixup then - raise(UnresolvedReferenceNoRange ccu.name) - ccu.target - - member ccu.IsUnresolvedReference = isNull (ccu.target :> obj) || ccu.orphanfixup - - /// Ensure the ccu is derefable in advance. Supply a path to attach to any resulting error message. - member ccu.EnsureDerefable(requiringPath: string[]) = - if ccu.IsUnresolvedReference then - let path = System.String.Join(".", requiringPath) - raise(UnresolvedPathReferenceNoRange(ccu.name, path)) - - /// Indicates that this DLL uses F# 2.0+ quotation literals somewhere. This is used to implement a restriction on static linking. - member ccu.UsesFSharp20PlusQuotations - with get() = ccu.Deref.UsesFSharp20PlusQuotations - and set v = ccu.Deref.UsesFSharp20PlusQuotations <- v - - member ccu.AssemblyName = ccu.name - - /// Holds the data indicating how this assembly/module is referenced from the code being compiled. - member ccu.ILScopeRef = ccu.Deref.ILScopeRef - - /// A unique stamp for this DLL - member ccu.Stamp = ccu.Deref.Stamp - - /// Holds the filename for the DLL, if any - member ccu.FileName = ccu.Deref.FileName - - /// Try to get the .NET Assembly, if known. May not be present for `IsFSharp` for in-memory cross-project references - member ccu.TryGetILModuleDef() = ccu.Deref.TryGetILModuleDef() - -#if !NO_EXTENSIONTYPING - /// Is the CCu an EST injected assembly - member ccu.IsProviderGenerated = ccu.Deref.IsProviderGenerated - - /// Used to make 'forward' calls into the loader during linking - member ccu.ImportProvidedType ty: TType = ccu.Deref.ImportProvidedType ty - -#endif - - /// The fully qualified assembly reference string to refer to this assembly. This is persisted in quotations - member ccu.QualifiedName = ccu.Deref.QualifiedName - - /// A hint as to where does the code for the CCU live (e.g what was the tcConfig.implicitIncludeDir at compilation time for this DLL?) - member ccu.SourceCodeDirectory = ccu.Deref.SourceCodeDirectory - - /// Indicates that this DLL was compiled using the F# compiler and has F# metadata - member ccu.IsFSharp = ccu.Deref.IsFSharp - - /// A handle to the full specification of the contents of the module contained in this ccu - // NOTE: may contain transient state during typechecking - member ccu.Contents = ccu.Deref.Contents - - /// The table of type forwarders for this assembly - member ccu.TypeForwarders: Map> = ccu.Deref.TypeForwarders - - /// The table of modules and namespaces at the "root" of the assembly - member ccu.RootModulesAndNamespaces = ccu.Contents.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions - - /// The table of type definitions at the "root" of the assembly - member ccu.RootTypeAndExceptionDefinitions = ccu.Contents.ModuleOrNamespaceType.TypeAndExceptionDefinitions - - /// Create a CCU with the given name and contents - static member Create(nm, x) = - { target = x - orphanfixup = false - name = nm } - - /// Create a CCU with the given name but where the contents have not yet been specified - static member CreateDelayed nm = - { target = Unchecked.defaultof<_> - orphanfixup = false - name = nm } - - /// Fixup a CCU to have the given contents - member x.Fixup(avail: CcuThunk) = - - match box x.target with - | null -> () - | _ -> - // In the IDE we tolerate a double-fixup of FSHarp.Core when editing the FSharp.Core project itself - if x.AssemblyName <> "FSharp.Core" then - errorR(Failure("internal error: Fixup: the ccu thunk for assembly "+x.AssemblyName+" not delayed!")) - - assert (avail.AssemblyName = x.AssemblyName) - x.target <- - match box avail.target with - | null -> error(Failure("internal error: ccu thunk '"+avail.name+"' not fixed up!")) - | _ -> avail.target - - /// Fixup a CCU to record it as "orphaned", i.e. not available - member x.FixupOrphaned() = - match box x.target with - | null -> x.orphanfixup<-true - | _ -> errorR(Failure("internal error: FixupOrphaned: the ccu thunk for assembly "+x.AssemblyName+" not delayed!")) - - /// Try to resolve a path into the CCU by referencing the .NET/CLI type forwarder table of the CCU - member ccu.TryForward(nlpath: string[], item: string) : EntityRef option = - ccu.EnsureDerefable nlpath - let key = nlpath, item - match ccu.TypeForwarders.TryGetValue key with - | true, entity -> Some(entity.Force()) - | _ -> None - //printfn "trying to forward %A :: %s from ccu '%s', res = '%A'" p n ccu.AssemblyName res.IsSome - - /// Used to make forward calls into the type/assembly loader when comparing member signatures during linking - member ccu.MemberSignatureEquality(ty1: TType, ty2: TType) = - ccu.Deref.MemberSignatureEquality ty1 ty2 - - [] - member x.DebugText = x.ToString() - - override ccu.ToString() = ccu.AssemblyName - -/// The result of attempting to resolve an assembly name to a full ccu. -/// UnresolvedCcu will contain the name of the assembly that could not be resolved. -and - [] - CcuResolutionResult = - - | ResolvedCcu of CcuThunk - - | UnresolvedCcu of string - - [] - member x.DebugText = x.ToString() - - override x.ToString() = match x with ResolvedCcu ccu -> ccu.ToString() | UnresolvedCcu s -> "unresolved " + s - -/// Represents the information saved in the assembly signature data resource for an F# assembly -and - [] - PickledCcuInfo = - { mspec: ModuleOrNamespace - - compileTimeWorkingDir: string - - usesQuotations: bool } - - [] - member x.DebugText = x.ToString() - - override __.ToString() = "PickledCcuInfo(...)" - - - -//--------------------------------------------------------------------------- -// Attributes -//--------------------------------------------------------------------------- - -and Attribs = Attrib list - -and - [] - AttribKind = - - /// Indicates an attribute refers to a type defined in an imported .NET assembly - | ILAttrib of ILMethodRef - - /// Indicates an attribute refers to a type defined in an imported F# assembly - | FSAttrib of ValRef - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// Attrib(kind, unnamedArgs, propVal, appliedToAGetterOrSetter, targetsOpt, range) -and - [] - Attrib = - - | Attrib of TyconRef * AttribKind * AttribExpr list * AttribNamedArg list * bool * AttributeTargets option * range - - [] - member x.DebugText = x.ToString() - - member x.TyconRef = (let (Attrib(tcref, _, _, _, _, _, _)) = x in tcref) - - override x.ToString() = "attrib" + x.TyconRef.ToString() - -/// We keep both source expression and evaluated expression around to help intellisense and signature printing -and - [] - AttribExpr = - - /// AttribExpr(source, evaluated) - | AttribExpr of Expr * Expr - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "AttribExpr(...)" - -/// AttribNamedArg(name, type, isField, value) -and - [] - AttribNamedArg = - | AttribNamedArg of (string*TType*bool*AttribExpr) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "AttribNamedArg(...)" - -/// Constants in expressions -and [] - Const = - | Bool of bool - | SByte of sbyte - | Byte of byte - | Int16 of int16 - | UInt16 of uint16 - | Int32 of int32 - | UInt32 of uint32 - | Int64 of int64 - | UInt64 of uint64 - | IntPtr of int64 - | UIntPtr of uint64 - | Single of single - | Double of double - | Char of char - | String of string - | Decimal of Decimal - | Unit - | Zero // null/zero-bit-pattern - -/// Decision trees. Pattern matching has been compiled down to -/// a decision tree by this point. The right-hand-sides (actions) of -/// a decision tree by this point. The right-hand-sides (actions) of -/// the decision tree are labelled by integers that are unique for that -/// particular tree. -and - [] - DecisionTree = - - /// TDSwitch(input, cases, default, range) - /// - /// Indicates a decision point in a decision tree. - /// input -- The expression being tested. If switching over a struct union this - /// must be the address of the expression being tested. - /// cases -- The list of tests and their subsequent decision trees - /// default -- The default decision tree, if any - /// range -- (precise documentation needed) - | TDSwitch of Expr * DecisionTreeCase list * DecisionTree option * range - - /// TDSuccess(results, targets) - /// - /// Indicates the decision tree has terminated with success, transferring control to the given target with the given parameters. - /// results -- the expressions to be bound to the variables at the target - /// target -- the target number for the continuation - | TDSuccess of Exprs * int - - /// TDBind(binding, body) - /// - /// Bind the given value through the remaining cases of the dtree. - /// These arise from active patterns and some optimizations to prevent - /// repeated computations in decision trees. - /// binding -- the value and the expression it is bound to - /// body -- the rest of the decision tree - | TDBind of Binding * DecisionTree - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// Represents a test and a subsequent decision tree -and - [] - DecisionTreeCase = - | TCase of DecisionTreeTest * DecisionTree - - /// Get the discriminator associated with the case - member x.Discriminator = let (TCase(d, _)) = x in d - - /// Get the decision tree or a successful test - member x.CaseTree = let (TCase(_, d)) = x in d - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "DecisionTreeCase(...)" - -and - [] - DecisionTreeTest = - /// Test if the input to a decision tree matches the given union case - | UnionCase of UnionCaseRef * TypeInst - - /// Test if the input to a decision tree is an array of the given length - | ArrayLength of int * TType - - /// Test if the input to a decision tree is the given constant value - | Const of Const - - /// Test if the input to a decision tree is null - | IsNull - - /// IsInst(source, target) - /// - /// Test if the input to a decision tree is an instance of the given type - | IsInst of TType * TType - - /// Test.ActivePatternCase(activePatExpr, activePatResTys, activePatIdentity, idx, activePatInfo) - /// - /// Run the active pattern and bind a successful result to a - /// variable in the remaining tree. - /// activePatExpr -- The active pattern function being called, perhaps applied to some active pattern parameters. - /// activePatResTys -- The result types (case types) of the active pattern. - /// activePatIdentity -- The value and the types it is applied to. If there are any active pattern parameters then this is empty. - /// idx -- The case number of the active pattern which the test relates to. - /// activePatternInfo -- The extracted info for the active pattern. - | ActivePatternCase of Expr * TTypes * (ValRef * TypeInst) option * int * ActivePatternInfo - - // %+A formatting is used, so this is not needed - //[] - //member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. -and - [] - DecisionTreeTarget = - | TTarget of Vals * Expr * SequencePointInfoForTarget - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "DecisionTreeTarget(...)" - -/// A collection of simultaneous bindings -and Bindings = Binding list - -/// A binding of a variable to an expression, as in a `let` binding or similar -and - [] - Binding = - | TBind of Val * Expr * SequencePointInfoForBinding - - /// The value being bound - member x.Var = (let (TBind(v, _, _)) = x in v) - - /// The expression the value is being bound to - member x.Expr = (let (TBind(_, e, _)) = x in e) - - /// The information about whether to emit a sequence point for the binding - member x.SequencePointInfo = (let (TBind(_, _, sp)) = x in sp) - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "TBind(%s, ...)" (x.Var.CompiledName None) - -/// Represents a reference to an active pattern element. The -/// integer indicates which choice in the target set is being selected by this item. -and - [] - ActivePatternElemRef = - | APElemRef of ActivePatternInfo * ValRef * int - - /// Get the full information about the active pattern being referred to - member x.ActivePatternInfo = (let (APElemRef(info, _, _)) = x in info) - - /// Get a reference to the value for the active pattern being referred to - member x.ActivePatternVal = (let (APElemRef(_, vref, _)) = x in vref) - - /// Get the index of the active pattern element within the overall active pattern - member x.CaseIndex = (let (APElemRef(_, _, n)) = x in n) - - [] - member x.DebugText = x.ToString() - - override __.ToString() = "ActivePatternElemRef(...)" - -/// Records the "extra information" for a value compiled as a method (rather -/// than a closure or a local), including argument names, attributes etc. -and - [] - ValReprInfo = - /// ValReprInfo (numTypars, args, result) - | ValReprInfo of TyparReprInfo list * ArgReprInfo list list * ArgReprInfo - - /// Get the extra information about the arguments for the value - member x.ArgInfos = (let (ValReprInfo(_, args, _)) = x in args) - - /// Get the number of curried arguments of the value - member x.NumCurriedArgs = (let (ValReprInfo(_, args, _)) = x in args.Length) - - /// Get the number of type parameters of the value - member x.NumTypars = (let (ValReprInfo(n, _, _)) = x in n.Length) - - /// Indicates if the value has no arguments - neither type parameters nor value arguments - member x.HasNoArgs = (let (ValReprInfo(n, args, _)) = x in n.IsEmpty && args.IsEmpty) - - /// Get the number of tupled arguments in each curried argument position - member x.AritiesOfArgs = (let (ValReprInfo(_, args, _)) = x in List.map List.length args) - - /// Get the kind of each type parameter - member x.KindsOfTypars = (let (ValReprInfo(n, _, _)) = x in n |> List.map (fun (TyparReprInfo(_, k)) -> k)) - - /// Get the total number of arguments - member x.TotalArgCount = - let (ValReprInfo(_, args, _)) = x - // This is List.sumBy List.length args - // We write this by hand as it can be a performance bottleneck in LinkagePartialKey - let rec loop (args: ArgReprInfo list list) acc = - match args with - | [] -> acc - | [] :: t -> loop t acc - | [_] :: t -> loop t (acc+1) - | (_ :: _ :: h) :: t -> loop t (acc + h.Length + 2) - loop args 0 - - [] - member x.DebugText = x.ToString() - - override __.ToString() = "ValReprInfo(...)" - -/// Records the "extra information" for an argument compiled as a real -/// method argument, specifically the argument name and attributes. -and - [] - ArgReprInfo = - { - // MUTABILITY: used when propagating signature attributes into the implementation. - mutable Attribs: Attribs - - // MUTABILITY: used when propagating names of parameters from signature into the implementation. - mutable Name: Ident option } - - [] - member x.DebugText = x.ToString() - - override __.ToString() = "ArgReprInfo(...)" - -/// Records the extra metadata stored about typars for type parameters -/// compiled as "real" IL type parameters, specifically for values with -/// ValReprInfo. Any information here is propagated from signature through -/// to the compiled code. -and TyparReprInfo = TyparReprInfo of Ident * TyparKind - -and Typars = Typar list - -and Exprs = Expr list - -and Vals = Val list - -/// The big type of expressions. -and - [] - Expr = - /// A constant expression. - | Const of Const * range * TType - - /// Reference a value. The flag is only relevant if the value is an object model member - /// and indicates base calls and special uses of object constructors. - | Val of ValRef * ValUseFlag * range - - /// Sequence expressions, used for "a;b", "let a = e in b;a" and "a then b" (the last an OO constructor). - | Sequential of Expr * Expr * SequentialOpKind * SequencePointInfoForSeq * range - - /// Lambda expressions. - - /// Why multiple vspecs? A Expr.Lambda taking multiple arguments really accepts a tuple. - /// But it is in a convenient form to be compile accepting multiple - /// arguments, e.g. if compiled as a toplevel static method. - | Lambda of Unique * Val option * Val option * Val list * Expr * range * TType - - /// Type lambdas. These are used for the r.h.s. of polymorphic 'let' bindings and - /// for expressions that implement first-class polymorphic values. - | TyLambda of Unique * Typars * Expr * range * TType - - /// Applications. - /// Applications combine type and term applications, and are normalized so - /// that sequential applications are combined, so "(f x y)" becomes "f [[x];[y]]". - /// The type attached to the function is the formal function type, used to ensure we don't build application - /// nodes that over-apply when instantiating at function types. - | App of Expr * TType * TypeInst * Exprs * range - - /// Bind a recursive set of values. - | LetRec of Bindings * Expr * range * FreeVarsCache - - /// Bind a value. - | Let of Binding * Expr * range * FreeVarsCache - - // Object expressions: A closure that implements an interface or a base type. - // The base object type might be a delegate type. - | Obj of - unique: Unique * - objTy: TType * (* <-- NOTE: specifies type parameters for base type *) - baseVal: Val option * - ctorCall: Expr * - overrides: ObjExprMethod list * - interfaceImpls: (TType * ObjExprMethod list) list * - range: range - - /// Matches are a more complicated form of "let" with multiple possible destinations - /// and possibly multiple ways to get to each destination. - /// The first mark is that of the expression being matched, which is used - /// as the mark for all the decision making and binding that happens during the match. - | Match of SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget array * range * TType - - /// If we statically know some information then in many cases we can use a more optimized expression - /// This is primarily used by terms in the standard library, particularly those implementing overloaded - /// operators. - | StaticOptimization of StaticOptimization list * Expr * Expr * range - - /// An intrinsic applied to some (strictly evaluated) arguments - /// A few of intrinsics (TOp_try, TOp.While, TOp.For) expect arguments kept in a normal form involving lambdas - | Op of TOp * TypeInst * Exprs * range - - /// Expr.Quote (quotedExpr, (referencedTypes, spliceTypes, spliceExprs, data) option ref, isFromQueryExpression, fullRange, quotedType) - /// - /// Indicates the expression is a quoted expression tree. - /// - // MUTABILITY: this use of mutability is awkward and perhaps should be removed - | Quote of Expr * (ILTypeRef list * TTypes * Exprs * ExprData) option ref * bool * range * TType - - /// Typechecking residue: Indicates a free choice of typars that arises due to - /// minimization of polymorphism at let-rec bindings. These are - /// resolved to a concrete instantiation on subsequent rewrites. - | TyChoose of Typars * Expr * range - - /// Typechecking residue: A Expr.Link occurs for every use of a recursively bound variable. While type-checking - /// the recursive bindings a dummy expression is stored in the mutable reference cell. - /// After type checking the bindings this is replaced by a use of the variable, perhaps at an - /// appropriate type instantiation. These are immediately eliminated on subsequent rewrites. - | Link of Expr ref - - // Prefer to use the default formatting of this union type - //[] - //member x.DebugText = x.ToString() - // - //override __.ToString() = "Expr(...)" - -and - [] - TOp = - - /// An operation representing the creation of a union value of the particular union case - | UnionCase of UnionCaseRef - - /// An operation representing the creation of an exception value using an F# exception declaration - | ExnConstr of TyconRef - - /// An operation representing the creation of a tuple value - | Tuple of TupInfo - - /// An operation representing the creation of an anonymous record - | AnonRecd of AnonRecdTypeInfo - - /// An operation representing the get of a property from an anonymous record - | AnonRecdGet of AnonRecdTypeInfo * int - - /// An operation representing the creation of an array value - | Array - - /// Constant byte arrays (used for parser tables and other embedded data) - | Bytes of byte[] - - /// Constant uint16 arrays (used for parser tables) - | UInt16s of uint16[] - - /// An operation representing a lambda-encoded while loop. The special while loop marker is used to mark compilations of 'foreach' expressions - | While of SequencePointInfoForWhileLoop * SpecialWhileLoopMarker - - /// An operation representing a lambda-encoded for loop - | For of SequencePointInfoForForLoop * ForLoopStyle (* count up or down? *) - - /// An operation representing a lambda-encoded try/catch - | TryCatch of SequencePointInfoForTry * SequencePointInfoForWith - - /// An operation representing a lambda-encoded try/finally - | TryFinally of SequencePointInfoForTry * SequencePointInfoForFinally - - /// Construct a record or object-model value. The ValRef is for self-referential class constructors, otherwise - /// it indicates that we're in a constructor and the purpose of the expression is to - /// fill in the fields of a pre-created but uninitialized object, and to assign the initialized - /// version of the object into the optional mutable cell pointed to be the given value. - | Recd of RecordConstructionInfo * TyconRef - - /// An operation representing setting a record or class field - | ValFieldSet of RecdFieldRef - - /// An operation representing getting a record or class field - | ValFieldGet of RecdFieldRef - - /// An operation representing getting the address of a record field - | ValFieldGetAddr of RecdFieldRef * readonly: bool - - /// An operation representing getting an integer tag for a union value representing the union case number - | UnionCaseTagGet of TyconRef - - /// An operation representing a coercion that proves a union value is of a particular union case. This is not a test, its - /// simply added proof to enable us to generate verifiable code for field access on union types - | UnionCaseProof of UnionCaseRef - - /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case. - | UnionCaseFieldGet of UnionCaseRef * int - - /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case. - | UnionCaseFieldGetAddr of UnionCaseRef * int * readonly: bool - - /// An operation representing a field-get from a union value. The value is not assumed to have been proven to be of the corresponding union case. - | UnionCaseFieldSet of UnionCaseRef * int - - /// An operation representing a field-get from an F# exception value. - | ExnFieldGet of TyconRef * int - - /// An operation representing a field-set on an F# exception value. - | ExnFieldSet of TyconRef * int - - /// An operation representing a field-get from an F# tuple value. - | TupleFieldGet of TupInfo * int - - /// IL assembly code - type list are the types pushed on the stack - | ILAsm of ILInstr list * TTypes - - /// Generate a ldflda on an 'a ref. - | RefAddrGet of bool - - /// Conversion node, compiled via type-directed translation or to box/unbox - | Coerce - - /// Represents a "rethrow" operation. May not be rebound, or used outside of try-finally, expecting a unit argument - | Reraise - - /// Used for state machine compilation - | Return - - /// Used for state machine compilation - | Goto of ILCodeLabel - - /// Used for state machine compilation - | Label of ILCodeLabel - - /// Pseudo method calls. This is used for overloaded operations like op_Addition. - | TraitCall of TraitConstraintInfo - - /// Operation nodes representing C-style operations on byrefs and mutable vals (l-values) - | LValueOp of LValueOperation * ValRef - - /// ILCall(useCallvirt, isProtected, valu, newobj, valUseFlags, isProp, noTailCall, mref, actualTypeInst, actualMethInst, retTy) - /// - /// IL method calls. - /// value -- is the object a value type? - /// isProp -- used for quotation reflection. - /// noTailCall - DllImport? if so don't tailcall - /// actualTypeInst -- instantiation of the enclosing type - /// actualMethInst -- instantiation of the method - /// retTy -- the types of pushed values, if any - | ILCall of bool * bool * bool * bool * ValUseFlag * bool * bool * ILMethodRef * TypeInst * TypeInst * TTypes - - // Prefer to use the default formatting of this union type - //[] - //member x.DebugText = x.ToString() - // - //override __.ToString() = "TOp(...)" - -/// Indicates the kind of record construction operation. -and RecordConstructionInfo = - /// We're in an explicit constructor. The purpose of the record expression is to - /// fill in the fields of a pre-created but uninitialized object - | RecdExprIsObjInit - - /// Normal record construction - | RecdExpr - -/// If this is Some ty then it indicates that a .NET 2.0 constrained call is required, with the given type as the -/// static type of the object argument. -and ConstrainedCallInfo = TType option - -/// Indicates the kind of looping operation. -and SpecialWhileLoopMarker = - - | NoSpecialWhileLoopMarker - - /// Marks the compiled form of a 'for ... in ... do ' expression - | WhileLoopForCompiledForEachExprMarker - -/// Indicates the kind of looping operation. -and ForLoopStyle = - /// Evaluate start and end once, loop up - | FSharpForLoopUp - - /// Evaluate start and end once, loop down - | FSharpForLoopDown - - /// Evaluate start once and end multiple times, loop up - | CSharpForLoopUp - -/// Indicates what kind of pointer operation this is. -and LValueOperation = - /// In C syntax this is: &localv - | LAddrOf of readonly: bool - - /// In C syntax this is: *localv_ptr - | LByrefGet - - /// In C syntax this is: localv = e, note == *(&localv) = e == LAddrOf; LByrefSet - | LSet - - /// In C syntax this is: *localv_ptr = e - | LByrefSet - -/// Indicates the kind of sequential operation, i.e. "normal" or "to a before returning b" -and SequentialOpKind = - /// a ; b - | NormalSeq - - /// let res = a in b;res - | ThenDoSeq - -/// Indicates how a value, function or member is being used at a particular usage point. -and ValUseFlag = - /// Indicates a use of a value represents a call to a method that may require - /// a .NET 2.0 constrained call. A constrained call is only used for calls where - // the object argument is a value type or generic type, and the call is to a method - // on System.Object, System.ValueType, System.Enum or an interface methods. - | PossibleConstrainedCall of TType - - /// A normal use of a value - | NormalValUse - - /// A call to a constructor, e.g. 'inherit C()' - | CtorValUsedAsSuperInit - - /// A call to a constructor, e.g. 'new C() = new C(3)' - | CtorValUsedAsSelfInit - - /// A call to a base method, e.g. 'base.OnPaint(args)' - | VSlotDirectCall - -/// Indicates the kind of an F# core library static optimization construct -and StaticOptimization = - - | TTyconEqualsTycon of TType * TType - - | TTyconIsStruct of TType - -/// A representation of a method in an object expression. -/// -/// TObjExprMethod(slotsig, attribs, methTyparsOfOverridingMethod, methodParams, methodBodyExpr, m) -and - [] - ObjExprMethod = - - | TObjExprMethod of SlotSig * Attribs * Typars * Val list list * Expr * range - - member x.Id = let (TObjExprMethod(slotsig, _, _, _, _, m)) = x in mkSynId m slotsig.Name - - [] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "TObjExprMethod(%s, ...)" x.Id.idText - -/// Represents an abstract method slot, or delegate signature. -/// -/// TSlotSig(methodName, declaringType, declaringTypeParameters, methodTypeParameters, slotParameters, returnTy) -and - [] - SlotSig = - - | TSlotSig of string * TType * Typars * Typars * SlotParam list list * TType option - - member ss.Name = let (TSlotSig(nm, _, _, _, _, _)) = ss in nm - - member ss.ImplementedType = let (TSlotSig(_, ty, _, _, _, _)) = ss in ty - - member ss.ClassTypars = let (TSlotSig(_, _, ctps, _, _, _)) = ss in ctps - - member ss.MethodTypars = let (TSlotSig(_, _, _, mtps, _, _)) = ss in mtps - - member ss.FormalParams = let (TSlotSig(_, _, _, _, ps, _)) = ss in ps - - member ss.FormalReturnType = let (TSlotSig(_, _, _, _, _, rt)) = ss in rt - - [] - member x.DebugText = x.ToString() - - override ss.ToString() = sprintf "TSlotSig(%s, ...)" ss.Name - -/// Represents a parameter to an abstract method slot. -/// -/// TSlotParam(nm, ty, inFlag, outFlag, optionalFlag, attribs) -and - [] - SlotParam = - | TSlotParam of string option * TType * bool (* in *) * bool (* out *) * bool (* optional *) * Attribs - - member x.Type = let (TSlotParam(_, ty, _, _, _, _)) = x in ty - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TSlotParam(...)" - -/// A type for a module-or-namespace-fragment and the actual definition of the module-or-namespace-fragment -/// The first ModuleOrNamespaceType is the signature and is a binder. However the bindings are not used in the ModuleOrNamespaceExpr: it is only referenced from the 'outside' -/// is for use by FCS only to report the "hidden" contents of the assembly prior to applying the signature. -and - [] - ModuleOrNamespaceExprWithSig = - | ModuleOrNamespaceExprWithSig of - ModuleOrNamespaceType - * ModuleOrNamespaceExpr - * range - - member x.Type = let (ModuleOrNamespaceExprWithSig(mtyp, _, _)) = x in mtyp - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "ModuleOrNamespaceExprWithSig(...)" - -/// The contents of a module-or-namespace-fragment definition -and - [] - ModuleOrNamespaceExpr = - /// Indicates the module is a module with a signature - | TMAbstract of ModuleOrNamespaceExprWithSig - - /// Indicates the module fragment is made of several module fragments in succession - | TMDefs of ModuleOrNamespaceExpr list - - /// Indicates the module fragment is a 'let' definition - | TMDefLet of Binding * range - - /// Indicates the module fragment is an evaluation of expression for side-effects - | TMDefDo of Expr * range - - /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules - | TMDefRec of isRec: bool * Tycon list * ModuleOrNamespaceBinding list * range - - // %+A formatting is used, so this is not needed - //[] - member x.DebugText = x.ToString() - - override x.ToString() = sprintf "%+A" x - -/// A named module-or-namespace-fragment definition -and - [] - ModuleOrNamespaceBinding = - - | Binding of Binding - - | Module of - /// This ModuleOrNamespace that represents the compilation of a module as a class. - /// The same set of tycons etc. are bound in the ModuleOrNamespace as in the ModuleOrNamespaceExpr - ModuleOrNamespace * - /// This is the body of the module/namespace - ModuleOrNamespaceExpr - - [] - member x.DebugText = x.ToString() - - override __.ToString() = "ModuleOrNamespaceBinding(...)" - -/// Represents a complete typechecked implementation file, including its typechecked signature if any. -/// -/// TImplFile (qualifiedNameOfFile, pragmas, implementationExpressionWithSignature, hasExplicitEntryPoint, isScript) -and - [] - TypedImplFile = - | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool * StampMap - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TImplFile (...)" - -/// Represents a complete typechecked assembly, made up of multiple implementation files. -/// -and - [] - TypedAssemblyAfterOptimization = - | TypedAssemblyAfterOptimization of (TypedImplFile * (* optimizeDuringCodeGen: *) (Expr -> Expr)) list - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "TypedAssemblyAfterOptimization(...)" - -//--------------------------------------------------------------------------- -// Freevars. Computed and cached by later phases (never computed type checking). Cached in terms. Not pickled. -//--------------------------------------------------------------------------- - -/// Represents a set of free local values. -and FreeLocals = Zset - -/// Represents a set of free type parameters -and FreeTypars = Zset - -/// Represents a set of 'free' named type definitions. Used to collect the named type definitions referred to -/// from a type or expression. -and FreeTycons = Zset - -/// Represents a set of 'free' record field definitions. Used to collect the record field definitions referred to -/// from an expression. -and FreeRecdFields = Zset - -/// Represents a set of 'free' union cases. Used to collect the union cases referred to from an expression. -and FreeUnionCases = Zset - -/// Represents a set of 'free' type-related elements, including named types, trait solutions, union cases and -/// record fields. -and - [] - FreeTyvars = - { /// The summary of locally defined type definitions used in the expression. These may be made private by a signature - /// and we have to check various conditions associated with that. - FreeTycons: FreeTycons - - /// The summary of values used as trait solutions - FreeTraitSolutions: FreeLocals - - /// The summary of type parameters used in the expression. These may not escape the enclosing generic construct - /// and we have to check various conditions associated with that. - FreeTypars: FreeTypars } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "FreeTyvars(...)" - -/// Represents an amortized computation of the free variables in an expression -and FreeVarsCache = FreeVars cache - -/// Represents the set of free variables in an expression -and - [] - FreeVars = - { /// The summary of locally defined variables used in the expression. These may be hidden at let bindings etc. - /// or made private by a signature or marked 'internal' or 'private', and we have to check various conditions associated with that. - FreeLocals: FreeLocals - - /// Indicates if the expression contains a call to a protected member or a base call. - /// Calls to protected members and direct calls to super classes can't escape, also code can't be inlined - UsesMethodLocalConstructs: bool - - /// Indicates if the expression contains a call to rethrow that is not bound under a (try-)with branch. - /// Rethrow may only occur in such locations. - UsesUnboundRethrow: bool - - /// The summary of locally defined tycon representations used in the expression. These may be made private by a signature - /// or marked 'internal' or 'private' and we have to check various conditions associated with that. - FreeLocalTyconReprs: FreeTycons - - /// The summary of fields used in the expression. These may be made private by a signature - /// or marked 'internal' or 'private' and we have to check various conditions associated with that. - FreeRecdFields: FreeRecdFields - - /// The summary of union constructors used in the expression. These may be - /// marked 'internal' or 'private' and we have to check various conditions associated with that. - FreeUnionCases: FreeUnionCases - - /// See FreeTyvars above. - FreeTyvars: FreeTyvars } - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "FreeVars(...)" - -/// Specifies the compiled representations of type and exception definitions. Basically -/// just an ILTypeRef. Computed and cached by later phases. Stored in -/// type and exception definitions. Not pickled. Store an optional ILType object for -/// non-generic types. -and - [] - CompiledTypeRepr = - - /// An AbstractIL type representation that is just the name of a type. - /// - /// CompiledTypeRepr.ILAsmNamed (ilTypeRef, ilBoxity, ilTypeOpt) - /// - /// The ilTypeOpt is present for non-generic types. It is an ILType corresponding to the first two elements of the case. This - /// prevents reallocation of the ILType each time we need to generate it. For generic types, it is None. - | ILAsmNamed of - ILTypeRef * - ILBoxity * - ILType option - - /// An AbstractIL type representation that may include type variables - // This case is only used for types defined in the F# library by their translation to ILASM types, e.g. - // type ``[]``<'T> = (# "!0[]" #) - // type ``[, ]``<'T> = (# "!0[0 ..., 0 ...]" #) - // type ``[, , ]``<'T> = (# "!0[0 ..., 0 ..., 0 ...]" #) - // type byref<'T> = (# "!0&" #) - // type nativeptr<'T when 'T: unmanaged> = (# "native int" #) - // type ilsigptr<'T> = (# "!0*" #) - | ILAsmOpen of ILType - - [] - member x.DebugText = x.ToString() - - override x.ToString() = "CompiledTypeRepr(...)" - -//--------------------------------------------------------------------------- -// Basic properties on type definitions -//--------------------------------------------------------------------------- - - -/// Metadata on values (names of arguments etc. -[] -module ValReprInfo = - - let unnamedTopArg1: ArgReprInfo = { Attribs=[]; Name=None } - - let unnamedTopArg = [unnamedTopArg1] - - let unitArgData: ArgReprInfo list list = [[]] - - let unnamedRetVal: ArgReprInfo = { Attribs = []; Name=None } - - let selfMetadata = unnamedTopArg - - let emptyValData = ValReprInfo([], [], unnamedRetVal) - - let InferTyparInfo (tps: Typar list) = tps |> List.map (fun tp -> TyparReprInfo(tp.Id, tp.Kind)) - - let InferArgReprInfo (v: Val) : ArgReprInfo = { Attribs = []; Name= Some v.Id } - - let InferArgReprInfos (vs: Val list list) = ValReprInfo([], List.mapSquared InferArgReprInfo vs, unnamedRetVal) - - let HasNoArgs (ValReprInfo(n, args, _)) = n.IsEmpty && args.IsEmpty - -//--------------------------------------------------------------------------- -// Basic properties via functions (old style) -//--------------------------------------------------------------------------- - -let typeOfVal (v: Val) = v.Type -let typesOfVals (v: Val list) = v |> List.map (fun v -> v.Type) -let nameOfVal (v: Val) = v.LogicalName -let arityOfVal (v: Val) = (match v.ValReprInfo with None -> ValReprInfo.emptyValData | Some arities -> arities) - -let tupInfoRef = TupInfo.Const false -let tupInfoStruct = TupInfo.Const true -let mkTupInfo b = if b then tupInfoStruct else tupInfoRef -let structnessDefault = false -let mkRawRefTupleTy tys = TType_tuple (tupInfoRef, tys) -let mkRawStructTupleTy tys = TType_tuple (tupInfoStruct, tys) - -//--------------------------------------------------------------------------- -// Aggregate operations to help transform the components that -// make up the entire compilation unit -//--------------------------------------------------------------------------- - -let mapTImplFile f (TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = TImplFile (fragName, pragmas, f moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes) -let mapAccImplFile f z (TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = let moduleExpr, z = f z moduleExpr in TImplFile (fragName, pragmas, moduleExpr, hasExplicitEntryPoint, isScript, anonRecdTypes), z -let foldTImplFile f z (TImplFile (_, _, moduleExpr, _, _, _)) = f z moduleExpr - -//--------------------------------------------------------------------------- -// Equality relations on locally defined things -//--------------------------------------------------------------------------- - -let typarEq (lv1: Typar) (lv2: Typar) = (lv1.Stamp = lv2.Stamp) - -/// Equality on type variables, implemented as reference equality. This should be equivalent to using typarEq. -let typarRefEq (tp1: Typar) (tp2: Typar) = (tp1 === tp2) - - -/// Equality on value specs, implemented as reference equality -let valEq (lv1: Val) (lv2: Val) = (lv1 === lv2) - -/// Equality on CCU references, implemented as reference equality except when unresolved -let ccuEq (mv1: CcuThunk) (mv2: CcuThunk) = - (mv1 === mv2) || - (if mv1.IsUnresolvedReference || mv2.IsUnresolvedReference then - mv1.AssemblyName = mv2.AssemblyName - else - mv1.Contents === mv2.Contents) - -/// For dereferencing in the middle of a pattern -let (|ValDeref|) (vr: ValRef) = vr.Deref - - -//-------------------------------------------------------------------------- -// Make references to TAST items -//-------------------------------------------------------------------------- - -let mkRecdFieldRef tcref f = RFRef(tcref, f) -let mkUnionCaseRef tcref c = UCRef(tcref, c) - - -let ERefLocal x: EntityRef = { binding=x; nlr=Unchecked.defaultof<_> } -let ERefNonLocal x: EntityRef = { binding=Unchecked.defaultof<_>; nlr=x } -let ERefNonLocalPreResolved x xref: EntityRef = { binding=x; nlr=xref } -let (|ERefLocal|ERefNonLocal|) (x: EntityRef) = - match box x.nlr with - | null -> ERefLocal x.binding - | _ -> ERefNonLocal x.nlr - -//-------------------------------------------------------------------------- -// Construct local references -//-------------------------------------------------------------------------- - - -let mkLocalTyconRef x = ERefLocal x -let mkNonLocalEntityRef ccu mp = NonLocalEntityRef(ccu, mp) -let mkNestedNonLocalEntityRef (nleref: NonLocalEntityRef) id = mkNonLocalEntityRef nleref.Ccu (Array.append nleref.Path [| id |]) -let mkNonLocalTyconRef nleref id = ERefNonLocal (mkNestedNonLocalEntityRef nleref id) -let mkNonLocalTyconRefPreResolved x nleref id = ERefNonLocalPreResolved x (mkNestedNonLocalEntityRef nleref id) - -type EntityRef with - - member tcref.NestedTyconRef (x: Entity) = - match tcref with - | ERefLocal _ -> mkLocalTyconRef x - | ERefNonLocal nlr -> mkNonLocalTyconRefPreResolved x nlr x.LogicalName - - member tcref.RecdFieldRefInNestedTycon tycon (id: Ident) = RFRef (tcref.NestedTyconRef tycon, id.idText) - -/// Make a reference to a union case for type in a module or namespace -let mkModuleUnionCaseRef (modref: ModuleOrNamespaceRef) tycon uc = - (modref.NestedTyconRef tycon).MakeNestedUnionCaseRef uc - -let VRefLocal x: ValRef = { binding=x; nlr=Unchecked.defaultof<_> } - -let VRefNonLocal x: ValRef = { binding=Unchecked.defaultof<_>; nlr=x } - -let VRefNonLocalPreResolved x xref: ValRef = { binding=x; nlr=xref } - -let (|VRefLocal|VRefNonLocal|) (x: ValRef) = - match box x.nlr with - | null -> VRefLocal x.binding - | _ -> VRefNonLocal x.nlr - -let mkNonLocalValRef mp id = VRefNonLocal {EnclosingEntity = ERefNonLocal mp; ItemKey=id } -let mkNonLocalValRefPreResolved x mp id = VRefNonLocalPreResolved x {EnclosingEntity = ERefNonLocal mp; ItemKey=id } - -let ccuOfValRef vref = - match vref with - | VRefLocal _ -> None - | VRefNonLocal nlr -> Some nlr.Ccu - -let ccuOfTyconRef eref = - match eref with - | ERefLocal _ -> None - | ERefNonLocal nlr -> Some nlr.Ccu - -//-------------------------------------------------------------------------- -// Type parameters and inference unknowns -//------------------------------------------------------------------------- - -let mkTyparTy (tp: Typar) = - match tp.Kind with - | TyparKind.Type -> tp.AsType - | TyparKind.Measure -> TType_measure (Measure.Var tp) - -let copyTypar (tp: Typar) = - let optData = tp.typar_opt_data |> Option.map (fun tg -> { typar_il_name = tg.typar_il_name; typar_xmldoc = tg.typar_xmldoc; typar_constraints = tg.typar_constraints; typar_attribs = tg.typar_attribs }) - Typar.New { typar_id = tp.typar_id - typar_flags = tp.typar_flags - typar_stamp = newStamp() - typar_solution = tp.typar_solution - typar_astype = Unchecked.defaultof<_> - // Be careful to clone the mutable optional data too - typar_opt_data = optData } - -let copyTypars tps = List.map copyTypar tps - -//-------------------------------------------------------------------------- -// Inference variables -//-------------------------------------------------------------------------- - -let tryShortcutSolvedUnitPar canShortcut (r: Typar) = - if r.Kind = TyparKind.Type then failwith "tryShortcutSolvedUnitPar: kind=type" - match r.Solution with - | Some (TType_measure unt) -> - if canShortcut then - match unt with - | Measure.Var r2 -> - match r2.Solution with - | None -> () - | Some _ as soln -> - r.typar_solution <- soln - | _ -> () - unt - | _ -> - failwith "tryShortcutSolvedUnitPar: unsolved" - -let rec stripUnitEqnsAux canShortcut unt = - match unt with - | Measure.Var r when r.IsSolved -> stripUnitEqnsAux canShortcut (tryShortcutSolvedUnitPar canShortcut r) - | _ -> unt - -let rec stripTyparEqnsAux canShortcut ty = - match ty with - | TType_var r -> - match r.Solution with - | Some soln -> - if canShortcut then - match soln with - // We avoid shortcutting when there are additional constraints on the type variable we're trying to cut out - // This is only because IterType likes to walk _all_ the constraints _everywhere_ in a type, including - // those attached to _solved_ type variables. In an ideal world this would never be needed - see the notes - // on IterType. - | TType_var r2 when r2.Constraints.IsEmpty -> - match r2.Solution with - | None -> () - | Some _ as soln2 -> - r.typar_solution <- soln2 - | _ -> () - stripTyparEqnsAux canShortcut soln - | None -> - ty - | TType_measure unt -> - TType_measure (stripUnitEqnsAux canShortcut unt) - | _ -> ty - -let stripTyparEqns ty = stripTyparEqnsAux false ty -let stripUnitEqns unt = stripUnitEqnsAux false unt - -//--------------------------------------------------------------------------- -// These make local/non-local references to values according to whether -// the item is globally stable ("published") or not. -//--------------------------------------------------------------------------- - -let mkLocalValRef (v: Val) = VRefLocal v -let mkLocalModRef (v: ModuleOrNamespace) = ERefLocal v -let mkLocalEntityRef (v: Entity) = ERefLocal v - -let mkNonLocalCcuRootEntityRef ccu (x: Entity) = mkNonLocalTyconRefPreResolved x (mkNonLocalEntityRef ccu [| |]) x.LogicalName - -let mkNestedValRef (cref: EntityRef) (v: Val) : ValRef = - match cref with - | ERefLocal _ -> mkLocalValRef v - | ERefNonLocal nlr -> - let key = v.GetLinkageFullKey() - mkNonLocalValRefPreResolved v nlr key - -/// From Ref_private to Ref_nonlocal when exporting data. -let rescopePubPathToParent viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p.[0..p.Length-2]) - -/// From Ref_private to Ref_nonlocal when exporting data. -let rescopePubPath viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p) - -//--------------------------------------------------------------------------- -// Equality between TAST items. -//--------------------------------------------------------------------------- - -let valRefInThisAssembly compilingFslib (x: ValRef) = - match x with - | VRefLocal _ -> true - | VRefNonLocal _ -> compilingFslib - -let tyconRefUsesLocalXmlDoc compilingFslib (x: TyconRef) = - match x with - | ERefLocal _ -> true - | ERefNonLocal _ -> -#if !NO_EXTENSIONTYPING - match x.TypeReprInfo with - | TProvidedTypeExtensionPoint _ -> true - | _ -> -#endif - compilingFslib - -let entityRefInThisAssembly compilingFslib (x: EntityRef) = - match x with - | ERefLocal _ -> true - | ERefNonLocal _ -> compilingFslib - -let arrayPathEq (y1: string[]) (y2: string[]) = - let len1 = y1.Length - let len2 = y2.Length - (len1 = len2) && - (let rec loop i = (i >= len1) || (y1.[i] = y2.[i] && loop (i+1)) - loop 0) - -let nonLocalRefEq (NonLocalEntityRef(x1, y1) as smr1) (NonLocalEntityRef(x2, y2) as smr2) = - smr1 === smr2 || (ccuEq x1 x2 && arrayPathEq y1 y2) - -/// This predicate tests if non-local resolution paths are definitely known to resolve -/// to different entities. All references with different named paths always resolve to -/// different entities. Two references with the same named paths may resolve to the same -/// entities even if they reference through different CCUs, because one reference -/// may be forwarded to another via a .NET TypeForwarder. -let nonLocalRefDefinitelyNotEq (NonLocalEntityRef(_, y1)) (NonLocalEntityRef(_, y2)) = - not (arrayPathEq y1 y2) - -let pubPathEq (PubPath path1) (PubPath path2) = arrayPathEq path1 path2 - -let fslibRefEq (nlr1: NonLocalEntityRef) (PubPath path2) = - arrayPathEq nlr1.Path path2 - -// Compare two EntityRef's for equality when compiling fslib (FSharp.Core.dll) -// -// Compiler-internal references to items in fslib are Ref_nonlocals even when compiling fslib. -// This breaks certain invariants that hold elsewhere, because they dereference to point to -// Entity's from signatures rather than Entity's from implementations. This means backup, alternative -// equality comparison techniques are needed when compiling fslib itself. -let fslibEntityRefEq fslibCcu (eref1: EntityRef) (eref2: EntityRef) = - match eref1, eref2 with - | (ERefNonLocal nlr1, ERefLocal x2) - | (ERefLocal x2, ERefNonLocal nlr1) -> - ccuEq nlr1.Ccu fslibCcu && - match x2.PublicPath with - | Some pp2 -> fslibRefEq nlr1 pp2 - | None -> false - | (ERefLocal e1, ERefLocal e2) -> - match e1.PublicPath, e2.PublicPath with - | Some pp1, Some pp2 -> pubPathEq pp1 pp2 - | _ -> false - | _ -> false - - -// Compare two ValRef's for equality when compiling fslib (FSharp.Core.dll) -// -// Compiler-internal references to items in fslib are Ref_nonlocals even when compiling fslib. -// This breaks certain invariants that hold elsewhere, because they dereference to point to -// Val's from signatures rather than Val's from implementations. This means backup, alternative -// equality comparison techniques are needed when compiling fslib itself. -let fslibValRefEq fslibCcu vref1 vref2 = - match vref1, vref2 with - | (VRefNonLocal nlr1, VRefLocal x2) - | (VRefLocal x2, VRefNonLocal nlr1) -> - ccuEq nlr1.Ccu fslibCcu && - match x2.PublicPath with - | Some (ValPubPath(pp2, nm2)) -> - // Note: this next line is just comparing the values by name, and not even the partial linkage data - // This relies on the fact that the compiler doesn't use any references to - // entities in fslib that are overloaded, or, if they are overloaded, then value identity - // is not significant - nlr1.ItemKey.PartialKey = nm2.PartialKey && - fslibRefEq nlr1.EnclosingEntity.nlr pp2 - | _ -> - false - // Note: I suspect this private-to-private reference comparison is not needed - | (VRefLocal e1, VRefLocal e2) -> - match e1.PublicPath, e2.PublicPath with - | Some (ValPubPath(pp1, nm1)), Some (ValPubPath(pp2, nm2)) -> - pubPathEq pp1 pp2 && - (nm1 = nm2) - | _ -> false - | _ -> false - -/// Primitive routine to compare two EntityRef's for equality -/// This takes into account the possibility that they may have type forwarders -let primEntityRefEq compilingFslib fslibCcu (x: EntityRef) (y: EntityRef) = - x === y || - - if x.IsResolved && y.IsResolved && not compilingFslib then - x.ResolvedTarget === y.ResolvedTarget - elif not x.IsLocalRef && not y.IsLocalRef && - (// Two tcrefs with identical paths are always equal - nonLocalRefEq x.nlr y.nlr || - // The tcrefs may have forwarders. If they may possibly be equal then resolve them to get their canonical references - // and compare those using pointer equality. - (not (nonLocalRefDefinitelyNotEq x.nlr y.nlr) && - match x.TryDeref with - | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false - | _ -> match y.TryDeref with ValueNone -> true | _ -> false)) then - true - else - compilingFslib && fslibEntityRefEq fslibCcu x y - -/// Primitive routine to compare two UnionCaseRef's for equality -let primUnionCaseRefEq compilingFslib fslibCcu (UCRef(tcr1, c1) as uc1) (UCRef(tcr2, c2) as uc2) = - uc1 === uc2 || (primEntityRefEq compilingFslib fslibCcu tcr1 tcr2 && c1 = c2) - -/// Primitive routine to compare two ValRef's for equality. On the whole value identity is not particularly -/// significant in F#. However it is significant for -/// (a) Active Patterns -/// (b) detecting uses of "special known values" from FSharp.Core.dll, such as 'seq' -/// and quotation splicing -/// -/// Note this routine doesn't take type forwarding into account -let primValRefEq compilingFslib fslibCcu (x: ValRef) (y: ValRef) = - x === y || - if (x.IsResolved && y.IsResolved && x.ResolvedTarget === y.ResolvedTarget) || - (x.IsLocalRef && y.IsLocalRef && valEq x.PrivateTarget y.PrivateTarget) then - true - else - (// Use TryDeref to guard against the platforms/times when certain F# language features aren't available, - // e.g. CompactFramework doesn't have support for quotations. - match x.TryDeref with - | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false - | _ -> match y.TryDeref with ValueNone -> true | _ -> false) - || (if compilingFslib then fslibValRefEq fslibCcu x y else false) - -//--------------------------------------------------------------------------- -// pubpath/cpath mess -//--------------------------------------------------------------------------- - -let fullCompPathOfModuleOrNamespace (m: ModuleOrNamespace) = - let (CompPath(scoref, cpath)) = m.CompilationPath - CompPath(scoref, cpath@[(m.LogicalName, m.ModuleOrNamespaceType.ModuleOrNamespaceKind)]) - -// Can cpath2 be accessed given a right to access cpath1. That is, is cpath2 a nested type or namespace of cpath1. Note order of arguments. -let inline canAccessCompPathFrom (CompPath(scoref1, cpath1)) (CompPath(scoref2, cpath2)) = - let rec loop p1 p2 = - match p1, p2 with - | (a1, k1) :: rest1, (a2, k2) :: rest2 -> (a1=a2) && (k1=k2) && loop rest1 rest2 - | [], _ -> true - | _ -> false // cpath1 is longer - loop cpath1 cpath2 && - (scoref1 = scoref2) - -let canAccessFromOneOf cpaths cpathTest = - cpaths |> List.exists (fun cpath -> canAccessCompPathFrom cpath cpathTest) - -let canAccessFrom (TAccess x) cpath = - x |> List.forall (fun cpath1 -> canAccessCompPathFrom cpath1 cpath) - -let canAccessFromEverywhere (TAccess x) = x.IsEmpty -let canAccessFromSomewhere (TAccess _) = true -let isLessAccessible (TAccess aa) (TAccess bb) = - not (aa |> List.forall(fun a -> bb |> List.exists (fun b -> canAccessCompPathFrom a b))) - -/// Given (newPath, oldPath) replace oldPath by newPath in the TAccess. -let accessSubstPaths (newPath, oldPath) (TAccess paths) = - let subst cpath = if cpath=oldPath then newPath else cpath - TAccess (List.map subst paths) - -let compPathOfCcu (ccu: CcuThunk) = CompPath(ccu.ILScopeRef, []) -let taccessPublic = TAccess [] -let taccessPrivate accessPath = TAccess [accessPath] -let compPathInternal = CompPath(ILScopeRef.Local, []) -let taccessInternal = TAccess [compPathInternal] -let combineAccess (TAccess a1) (TAccess a2) = TAccess(a1@a2) - -//--------------------------------------------------------------------------- -// Construct TAST nodes -//--------------------------------------------------------------------------- - -let NewFreeVarsCache() = newCache () - -let MakeUnionCasesTable ucs: TyconUnionCases = - { CasesByIndex = Array.ofList ucs - CasesByName = NameMap.ofKeyedList (fun uc -> uc.DisplayName) ucs } - -let MakeRecdFieldsTable ucs: TyconRecdFields = - { FieldsByIndex = Array.ofList ucs - FieldsByName = ucs |> NameMap.ofKeyedList (fun rfld -> rfld.Name) } - - -let MakeUnionCases ucs: TyconUnionData = - { CasesTable=MakeUnionCasesTable ucs - CompiledRepresentation=newCache() } - -let MakeUnionRepr ucs = TUnionRepr (MakeUnionCases ucs) - -let NewTypar (kind, rigid, Typar(id, staticReq, isCompGen), isFromError, dynamicReq, attribs, eqDep, compDep) = - Typar.New - { typar_id = id - typar_stamp = newStamp() - typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep) - typar_solution = None - typar_astype = Unchecked.defaultof<_> - typar_opt_data = - match attribs with - | [] -> None - | _ -> Some { typar_il_name = None; typar_xmldoc = XmlDoc.Empty; typar_constraints = []; typar_attribs = attribs } } - -let NewRigidTypar nm m = NewTypar (TyparKind.Type, TyparRigidity.Rigid, Typar(mkSynId m nm, NoStaticReq, true), false, TyparDynamicReq.Yes, [], false, false) - -let NewUnionCase id tys rty attribs docOption access: UnionCase = - { Id=id - XmlDoc=docOption - XmlDocSig="" - Accessibility=access - FieldTable = MakeRecdFieldsTable tys - ReturnType = rty - Attribs=attribs - OtherRangeOpt = None } - -let NewModuleOrNamespaceType mkind tycons vals = - ModuleOrNamespaceType(mkind, QueueList.ofList vals, QueueList.ofList tycons) - -let NewEmptyModuleOrNamespaceType mkind = NewModuleOrNamespaceType mkind [] [] - -/// Create a new TAST Entity node for an F# exception definition -let NewExn cpath (id: Ident) access repr attribs doc = - Tycon.New "exnc" - { entity_stamp=newStamp() - entity_attribs=attribs - entity_logical_name=id.idText - entity_range=id.idRange - entity_tycon_tcaug=TyconAugmentation.Create() - entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) - entity_modul_contents = MaybeLazy.Strict (NewEmptyModuleOrNamespaceType ModuleOrType) - entity_cpath= cpath - entity_typars=LazyWithContext.NotLazy [] - entity_tycon_repr = TNoRepr - entity_flags=EntityFlags(usesPrefixDisplay=false, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=false, hasSelfReferentialCtor=false, isStructRecordOrUnionType=false) - entity_il_repr_cache= newCache() - entity_opt_data = - match doc, access, repr with - | XmlDoc [||], TAccess [], TExnNone -> None - | _ -> Some { Entity.NewEmptyEntityOptData() with entity_xmldoc = doc; entity_accessibility = access; entity_tycon_repr_accessibility = access; entity_exn_info = repr } } - -/// Create a new TAST RecdField node for an F# class, struct or record field -let NewRecdField stat konst id nameGenerated ty isMutable isVolatile pattribs fattribs docOption access secret = - { rfield_mutable=isMutable - rfield_pattribs=pattribs - rfield_fattribs=fattribs - rfield_type=ty - rfield_static=stat - rfield_volatile=isVolatile - rfield_const=konst - rfield_access = access - rfield_secret = secret - rfield_xmldoc = docOption - rfield_xmldocsig = "" - rfield_id=id - rfield_name_generated = nameGenerated - rfield_other_range = None } - - -let NewTycon (cpath, nm, m, access, reprAccess, kind, typars, docOption, usesPrefixDisplay, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, mtyp) = - let stamp = newStamp() - Tycon.New "tycon" - { entity_stamp=stamp - entity_logical_name=nm - entity_range=m - entity_flags=EntityFlags(usesPrefixDisplay=usesPrefixDisplay, isModuleOrNamespace=false, preEstablishedHasDefaultCtor=preEstablishedHasDefaultCtor, hasSelfReferentialCtor=hasSelfReferentialCtor, isStructRecordOrUnionType=false) - entity_attribs=[] // fixed up after - entity_typars=typars - entity_tycon_repr = TNoRepr - entity_tycon_tcaug=TyconAugmentation.Create() - entity_modul_contents = mtyp - entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath (mkSynId m nm)) - entity_cpath = cpath - entity_il_repr_cache = newCache() - entity_opt_data = - match kind, docOption, reprAccess, access with - | TyparKind.Type, XmlDoc [||], TAccess [], TAccess [] -> None - | _ -> Some { Entity.NewEmptyEntityOptData() with entity_kind = kind; entity_xmldoc = docOption; entity_tycon_repr_accessibility = reprAccess; entity_accessibility=access } } - - -let NewILTycon nlpath (nm, m) tps (scoref: ILScopeRef, enc, tdef: ILTypeDef) mtyp = - let tycon = NewTycon(nlpath, nm, m, taccessPublic, taccessPublic, TyparKind.Type, tps, XmlDoc.Empty, true, false, false, mtyp) - - tycon.entity_tycon_repr <- TILObjectRepr (TILObjectReprData (scoref, enc, tdef)) - tycon.TypeContents.tcaug_closed <- true - tycon - -exception Duplicate of string * string * range -exception NameClash of string * string * string * range * string * string * range -exception FullAbstraction of string * range - -let NewModuleOrNamespace cpath access (id: Ident) xml attribs mtype = - Construct.NewModuleOrNamespace cpath access id xml attribs mtype - -/// Create a new Val object -let NewVal - (logicalName: string, m: range, compiledName, ty, isMutable, isCompGen, arity, access, - recValInfo, specialRepr, baseOrThis, attribs, inlineInfo, doc, isModuleOrMemberBinding, - isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal, - konst, actualParent) : Val = - - let stamp = newStamp() - Val.New { - val_stamp = stamp - val_logical_name = logicalName - val_range = m - val_flags = ValFlags(recValInfo, baseOrThis, isCompGen, inlineInfo, isMutable, isModuleOrMemberBinding, isExtensionMember, isIncrClassSpecialMember, isTyFunc, allowTypeInst, isGeneratedEventVal) - val_type = ty - val_opt_data = - match compiledName, arity, konst, access, doc, specialRepr, actualParent, attribs with - | None, None, None, TAccess [], XmlDoc [||], None, ParentNone, [] -> None - | _ -> - Some { Val.NewEmptyValOptData() with - val_compiled_name = (match compiledName with Some v when v <> logicalName -> compiledName | _ -> None) - val_repr_info = arity - val_const = konst - val_access = access - val_xmldoc = doc - val_member_info = specialRepr - val_declaring_entity = actualParent - val_attribs = attribs } - } - -/// Create the new contents of an overall assembly -let NewCcuContents sref m nm mty = - NewModuleOrNamespace (Some(CompPath(sref, []))) taccessPublic (ident(nm, m)) XmlDoc.Empty [] (MaybeLazy.Strict mty) - -//-------------------------------------------------------------------------- -// Cloning and adjusting -//-------------------------------------------------------------------------- - -/// Create a tycon based on an existing one using the function 'f'. -/// We require that we be given the new parent for the new tycon. -/// We pass the new tycon to 'f' in case it needs to reparent the -/// contents of the tycon. -let NewModifiedTycon f (orig: Tycon) = - let data = { orig with entity_stamp = newStamp() } - Tycon.New "NewModifiedTycon" (f data) - -/// Create a module Tycon based on an existing one using the function 'f'. -/// We require that we be given the parent for the new module. -/// We pass the new module to 'f' in case it needs to reparent the -/// contents of the module. -let NewModifiedModuleOrNamespace f orig = - orig |> NewModifiedTycon (fun d -> - { d with entity_modul_contents = MaybeLazy.Strict (f (d.entity_modul_contents.Force())) }) - -/// Create a Val based on an existing one using the function 'f'. -/// We require that we be given the parent for the new Val. -let NewModifiedVal f (orig: Val) = - let stamp = newStamp() - let data' = f { orig with val_stamp=stamp } - Val.New data' - -let NewClonedModuleOrNamespace orig = NewModifiedModuleOrNamespace (fun mty -> mty) orig -let NewClonedTycon orig = NewModifiedTycon (fun d -> d) orig - -//------------------------------------------------------------------------------ - -/// Combine a list of ModuleOrNamespaceType's making up the description of a CCU. checking there are now -/// duplicate modules etc. -let CombineCcuContentFragments m l = - - /// Combine module types when multiple namespace fragments contribute to the - /// same namespace, making new module specs as we go. - let rec CombineModuleOrNamespaceTypes path m (mty1: ModuleOrNamespaceType) (mty2: ModuleOrNamespaceType) = - match mty1.ModuleOrNamespaceKind, mty2.ModuleOrNamespaceKind with - | Namespace, Namespace -> - let kind = mty1.ModuleOrNamespaceKind - let tab1 = mty1.AllEntitiesByLogicalMangledName - let tab2 = mty2.AllEntitiesByLogicalMangledName - let entities = - [ for e1 in mty1.AllEntities do - match tab2.TryGetValue e1.LogicalName with - | true, e2 -> yield CombineEntities path e1 e2 - | _ -> yield e1 - for e2 in mty2.AllEntities do - match tab1.TryGetValue e2.LogicalName with - | true, _ -> () - | _ -> yield e2 ] - - let vals = QueueList.append mty1.AllValsAndMembers mty2.AllValsAndMembers - - ModuleOrNamespaceType(kind, vals, QueueList.ofList entities) - - | Namespace, _ | _, Namespace -> - error(Error(FSComp.SR.tastNamespaceAndModuleWithSameNameInAssembly(textOfPath path), m)) - - | _-> - error(Error(FSComp.SR.tastTwoModulesWithSameNameInAssembly(textOfPath path), m)) - - and CombineEntities path (entity1: Entity) (entity2: Entity) = - - match entity1.IsModuleOrNamespace, entity2.IsModuleOrNamespace with - | true, true -> - entity1 |> NewModifiedTycon (fun data1 -> - let xml = XmlDoc.Merge entity1.XmlDoc entity2.XmlDoc - { data1 with - entity_attribs = entity1.Attribs @ entity2.Attribs - entity_modul_contents = MaybeLazy.Lazy (lazy (CombineModuleOrNamespaceTypes (path@[entity2.DemangledModuleOrNamespaceName]) entity2.Range entity1.ModuleOrNamespaceType entity2.ModuleOrNamespaceType)) - entity_opt_data = - match data1.entity_opt_data with - | Some optData -> Some { optData with entity_xmldoc = xml } - | _ -> Some { Entity.NewEmptyEntityOptData() with entity_xmldoc = xml } }) - | false, false -> - error(Error(FSComp.SR.tastDuplicateTypeDefinitionInAssembly(entity2.LogicalName, textOfPath path), entity2.Range)) - | _, _ -> - error(Error(FSComp.SR.tastConflictingModuleAndTypeDefinitionInAssembly(entity2.LogicalName, textOfPath path), entity2.Range)) - - and CombineModuleOrNamespaceTypeList path m l = - match l with - | h :: t -> List.fold (CombineModuleOrNamespaceTypes path m) h t - | _ -> failwith "CombineModuleOrNamespaceTypeList" - - CombineModuleOrNamespaceTypeList [] m l - -//-------------------------------------------------------------------------- -// Resource format for pickled data -//-------------------------------------------------------------------------- - -let FSharpOptimizationDataResourceName = "FSharpOptimizationData." -let FSharpSignatureDataResourceName = "FSharpSignatureData." -// For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers -// don't complain when they see the resource. The prefix of these names must not be 'FSharpOptimizationData' -// or 'FSharpSignatureData' -let FSharpOptimizationDataResourceName2 = "FSharpOptimizationInfo." -let FSharpSignatureDataResourceName2 = "FSharpSignatureInfo." - - - diff --git a/src/fsharp/utils/CompilerLocationUtils.fs b/src/fsharp/utils/CompilerLocationUtils.fs new file mode 100644 index 00000000000..803e5d25e02 --- /dev/null +++ b/src/fsharp/utils/CompilerLocationUtils.fs @@ -0,0 +1,453 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Internal.Utilities + +open System +open System.Diagnostics +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open Microsoft.FSharp.Core + +#if !FX_NO_WIN_REGISTRY +open Microsoft.Win32 +#endif + +#nowarn "44" // ConfigurationSettings is obsolete but the new stuff is horribly complicated. + +module internal FSharpEnvironment = + + type private TypeInThisAssembly = class end + + /// The F# version reported in the banner + let FSharpBannerVersion = UtilsStrings.SR.fSharpBannerVersion(FSharp.BuildProperties.fsProductVersion, FSharp.BuildProperties.fsLanguageVersion) + + let FSharpProductName = UtilsStrings.SR.buildProductName(FSharpBannerVersion) + + let versionOf<'t> = + typeof<'t>.Assembly.GetName().Version.ToString() + + let FSharpCoreLibRunningVersion = + try match versionOf with + | null -> None + | "" -> None + | s -> Some(s) + with _ -> None + + // The F# binary format revision number. The first three digits of this form the significant part of the + // format revision number for F# binary signature and optimization metadata. The last digit is not significant. + // + // WARNING: Do not change this revision number unless you absolutely know what you're doing. + let FSharpBinaryMetadataFormatRevision = "2.0.0.0" + + let isRunningOnCoreClr = typeof.Assembly.FullName.StartsWith("System.Private.CoreLib", StringComparison.InvariantCultureIgnoreCase) + + +#if !FX_NO_WIN_REGISTRY + [] + extern uint32 RegOpenKeyExW(UIntPtr _hKey, string _lpSubKey, uint32 _ulOptions, int _samDesired, UIntPtr & _phkResult); + + [] + extern uint32 RegQueryValueExW(UIntPtr _hKey, string _lpValueName, uint32 _lpReserved, uint32 & _lpType, IntPtr _lpData, int & _lpchData); + + [] + extern uint32 RegCloseKey(UIntPtr _hKey) +#endif + module Option = + /// Convert string into Option string where null and String.Empty result in None + let ofString s = + if String.IsNullOrEmpty(s) then None + else Some(s) + + // MaxPath accounts for the null-terminating character, for example, the maximum path on the D drive is "D:\<256 chars>\0". + // See: ndp\clr\src\BCL\System\IO\Path.cs + let maxPath = 260; + let maxDataLength = (System.Text.UTF32Encoding()).GetMaxByteCount(maxPath) + +#if !FX_NO_WIN_REGISTRY + let KEY_WOW64_DEFAULT = 0x0000 + let KEY_WOW64_32KEY = 0x0200 + let HKEY_LOCAL_MACHINE = UIntPtr(0x80000002u) + let KEY_QUERY_VALUE = 0x1 + let REG_SZ = 1u + + let GetDefaultRegistryStringValueViaDotNet(subKey: string) = + Option.ofString + (try + downcast Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\"+subKey,null,null) + with e-> +#if DEBUG + Debug.Assert(false, sprintf "Failed in GetDefaultRegistryStringValueViaDotNet: %s" (e.ToString())) +#endif + null) + + let Get32BitRegistryStringValueViaPInvoke(subKey:string) = + Option.ofString + (try + // 64 bit flag is not available <= Win2k + let options = + let hasWow6432Node = + use x = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node") + x <> null + try + match hasWow6432Node with + | true -> KEY_WOW64_32KEY + | false -> KEY_WOW64_DEFAULT + with + | _ -> KEY_WOW64_DEFAULT + + let mutable hkey = UIntPtr.Zero; + let pathResult = Marshal.AllocCoTaskMem(maxDataLength); + + try + let res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,subKey, 0u, KEY_QUERY_VALUE ||| options, & hkey) + if res = 0u then + let mutable uType = REG_SZ; + let mutable cbData = maxDataLength; + + let res = RegQueryValueExW(hkey, null, 0u, &uType, pathResult, &cbData); + + if (res = 0u && cbData > 0 && cbData <= maxDataLength) then + Marshal.PtrToStringUni(pathResult, (cbData - 2)/2); + else + null + else + null + finally + if hkey <> UIntPtr.Zero then + RegCloseKey(hkey) |> ignore + + if pathResult <> IntPtr.Zero then + Marshal.FreeCoTaskMem(pathResult) + with e-> +#if DEBUG + Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaPInvoke: %s" (e.ToString())) +#endif + null) + + let is32Bit = IntPtr.Size = 4 + + let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e-> false + + let tryRegKey(subKey:string) = + + //if we are running on mono simply return None + // GetDefaultRegistryStringValueViaDotNet will result in an access denied by default, + // and Get32BitRegistryStringValueViaPInvoke will fail due to Advapi32.dll not existing + if runningOnMono then None else + if is32Bit then + let s = GetDefaultRegistryStringValueViaDotNet(subKey) + // If we got here AND we're on a 32-bit OS then we can validate that Get32BitRegistryStringValueViaPInvoke(...) works + // by comparing against the result from GetDefaultRegistryStringValueViaDotNet(...) +#if DEBUG + let viaPinvoke = Get32BitRegistryStringValueViaPInvoke(subKey) + Debug.Assert((s = viaPinvoke), sprintf "32bit path: pi=%A def=%A" viaPinvoke s) +#endif + s + else + Get32BitRegistryStringValueViaPInvoke(subKey) +#endif + + let internal tryCurrentDomain() = + let pathFromCurrentDomain = + AppDomain.CurrentDomain.BaseDirectory + if not(String.IsNullOrEmpty(pathFromCurrentDomain)) then + Some pathFromCurrentDomain + else + None + +#if FX_NO_SYSTEM_CONFIGURATION + let internal tryAppConfig (_appConfigKey:string) = None +#else + let internal tryAppConfig (_appConfigKey:string) = + let locationFromAppConfig = System.Configuration.ConfigurationSettings.AppSettings.[_appConfigKey] +#if DEBUG + Debug.Print(sprintf "Considering _appConfigKey %s which has value '%s'" _appConfigKey locationFromAppConfig) +#endif + if String.IsNullOrEmpty(locationFromAppConfig) then + None + else + let exeAssemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + let locationFromAppConfig = locationFromAppConfig.Replace("{exepath}", exeAssemblyFolder) +#if DEBUG + Debug.Print(sprintf "Using path %s" locationFromAppConfig) +#endif + Some locationFromAppConfig +#endif + + // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running + // Used for + // - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts + // - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks, but note a probe location is given) + // - default F# binaries directory in service.fs (REVIEW: check this) + // - default location of fsi.exe in FSharp.VS.FSI.dll (REVIEW: check this) + // - default F# binaries directory in (project system) Project.fs + let BinFolderOfDefaultFSharpCompiler(probePoint:string option) = + // Check for an app.config setting to redirect the default compiler location + // Like fsharp-compiler-location + try + // We let you set FSHARP_COMPILER_BIN. I've rarely seen this used and its not documented in the install instructions. + match Environment.GetEnvironmentVariable("FSHARP_COMPILER_BIN") with + | result when not (String.IsNullOrWhiteSpace result) -> Some result + |_-> + // FSharp.Compiler support setting an appKey for compiler location. I've never seen this used. + let result = tryAppConfig "fsharp-compiler-location" + match result with + | Some _ -> result + | None -> + + let safeExists f = (try File.Exists(f) with _ -> false) + + // Look in the probePoint if given, e.g. look for a compiler alongside of FSharp.Build.dll + match probePoint with + | Some p when safeExists (Path.Combine(p,"FSharp.Core.dll")) -> Some p + | _ -> + let fallback() = + let d = Assembly.GetExecutingAssembly() + Some (Path.GetDirectoryName d.Location) + match tryCurrentDomain() with + | None -> fallback() + | Some path -> Some path + with e -> None + +#if !FX_NO_WIN_REGISTRY + // Apply the given function to the registry entry corresponding to the subKey. + // The reg key is disposed at the end of the scope. + let useKey subKey f = + let key = Registry.LocalMachine.OpenSubKey subKey + try f key + finally + match key with + | null -> () + | _ -> key.Dispose() + + // Check if the framework version 4.5 or above is installed at the given key entry + let IsNetFx45OrAboveInstalledAt subKey = + try + useKey subKey (fun regKey -> + match regKey with + | null -> false + | _ -> regKey.GetValue("Release", 0) :?> int |> (fun s -> s >= 0x50000)) // 0x50000 implies 4.5.0 + with _ -> false + + // Check if the framework version 4.5 or above is installed + let IsNetFx45OrAboveInstalled = + IsNetFx45OrAboveInstalledAt @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client" || + IsNetFx45OrAboveInstalledAt @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" || + runningOnMono + + // Check if the running framework version is 4.5 or above. + // Use the presence of v4.5.x in the registry to distinguish between 4.0 and 4.5 + let IsRunningOnNetFx45OrAbove = + let version = new Version(versionOf) + let major = version.Major + major > 4 || (major = 4 && IsNetFx45OrAboveInstalled) + +#endif + + // Specify the tooling-compatible fragments of a path such as: + // typeproviders/fsharp41/net461/MyProvider.DesignTime.dll + // tools/fsharp41/net461/MyProvider.DesignTime.dll + // See https://github.com/Microsoft/visualfsharp/issues/3736 + + // Represents the F#-compiler <-> type provider protocol. + // When the API or protocol updates, add a new version moniker to the front of the list here. + let toolingCompatibleTypeProviderProtocolMonikers() = + [ "fsharp41" ] + + // Detect the host tooling context + let toolingCompatibleVersions = + if typeof.Assembly.GetName().Name = "mscorlib" then + [| "net48"; "net472"; "net471";"net47";"net462";"net461"; "net452"; "net451"; "net45"; "netstandard2.0" |] + elif typeof.Assembly.GetName().Name = "System.Private.CoreLib" then + [| "net5.0"; "netcoreapp3.1"; "netcoreapp3.0"; "netstandard2.1"; "netcoreapp2.2"; "netcoreapp2.1"; "netcoreapp2.0"; "netstandard2.0" |] + else + Debug.Assert(false, "Couldn't determine runtime tooling context, assuming it supports at least .NET Standard 2.0") + [| "netstandard2.0" |] + + let toolPaths = [| "tools"; "typeproviders" |] + + let toolingCompatiblePaths() = [ + for toolPath in toolPaths do + for protocol in toolingCompatibleTypeProviderProtocolMonikers() do + for netRuntime in toolingCompatibleVersions do + yield Path.Combine(toolPath, protocol, netRuntime) + ] + + let searchToolPath compilerToolPath = + seq { + yield compilerToolPath + for toolPath in toolingCompatiblePaths() do + yield Path.Combine (compilerToolPath, toolPath) + } + + let rec searchToolPaths path compilerToolPaths = + seq { + for toolPath in compilerToolPaths do + yield! searchToolPath toolPath + + match path with + | None -> () + | Some path -> yield! searchToolPath path + } + + let getTypeProviderAssembly (runTimeAssemblyFileName: string, designTimeAssemblyName: string, compilerToolPaths: string list, raiseError) = + // Find and load the designer assembly for the type provider component. + // We look in the directories stepping up from the location of the runtime assembly. + let loadFromLocation designTimeAssemblyPath = + try + Some (Assembly.UnsafeLoadFrom designTimeAssemblyPath) + with e -> + raiseError (Some designTimeAssemblyPath) e + + let rec searchParentDirChain path assemblyName = + seq { + match path with + | None -> () + | Some (p:string) -> + match Path.GetDirectoryName(p) with + | s when s = "" || s = null || Path.GetFileName(p) = "packages" || s = p -> () + | parentDir -> yield! searchParentDirChain (Some parentDir) assemblyName + + for p in searchToolPaths path compilerToolPaths do + let fileName = Path.Combine (p, assemblyName) + if File.Exists fileName then yield fileName + } + + let loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName = + let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName + let paths = searchParentDirChain (Some runTimeAssemblyPath) designTimeAssemblyName + paths + |> Seq.tryHead + |> function + | Some res -> loadFromLocation res + | None -> + // The search failed, just load from the first location and report an error + let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName + loadFromLocation (Path.Combine (runTimeAssemblyPath, designTimeAssemblyName)) + + if designTimeAssemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then + loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName + else + // Cover the case where the ".dll" extension has been left off and no version etc. has been used in the assembly + // string specification. The Name=FullName comparison is particularly strange, and was there to support + // design-time DLLs specified using "x.DesignTIme, Version= ..." long assembly names and GAC loads. + // These kind of design-time assembly specifications are no longer used to our knowledge so that comparison is basically legacy + // and will always succeed. + let name = AssemblyName (Path.GetFileNameWithoutExtension designTimeAssemblyName) + if name.Name.Equals(name.FullName, StringComparison.OrdinalIgnoreCase) then + let designTimeFileName = designTimeAssemblyName + ".dll" + loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeFileName + else + // Load from the GAC using Assembly.Load. This is legacy since type provider design-time components are + // never in the GAC these days and "x.DesignTIme, Version= ..." specifications are never used. + try + let name = AssemblyName designTimeAssemblyName + Some (Assembly.Load name) + with e -> + raiseError None e + + let getCompilerToolsDesignTimeAssemblyPaths compilerToolPaths = + searchToolPaths None compilerToolPaths + + let getFSharpCoreLibraryName = "FSharp.Core" + let fsiLibraryName = "FSharp.Compiler.Interactive.Settings" + + let getFSharpCompilerLocation() = + let location = Path.GetDirectoryName(typeof.Assembly.Location) + match BinFolderOfDefaultFSharpCompiler (Some location) with + | Some path -> path + | None -> + #if DEBUG + Debug.Print(sprintf """FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some '%s') returned None Location + customized incorrectly: algorithm here: https://github.com/dotnet/fsharp/blob/03f3f1c35f82af26593d025dabca57a6ef3ea9a1/src/utils/CompilerLocationUtils.fs#L171""" + location) + #endif + // Use the location of this dll + location + + let getDefaultFSharpCoreLocation() = Path.Combine(getFSharpCompilerLocation(), getFSharpCoreLibraryName + ".dll") + let getDefaultFsiLibraryLocation() = Path.Combine(getFSharpCompilerLocation(), fsiLibraryName + ".dll") + + // Path to the directory containing the fsharp compilers + let fsharpCompilerPath = Path.Combine(Path.GetDirectoryName(typeof.GetTypeInfo().Assembly.Location), "Tools") + + let isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + + let dotnet = if isWindows then "dotnet.exe" else "dotnet" + + let fileExists pathToFile = + try + File.Exists(pathToFile) + with | _ -> false + + // Look for global install of dotnet sdk + let getDotnetGlobalHostPath() = + let pf = Environment.GetEnvironmentVariable("ProgramW6432") + let pf = if String.IsNullOrEmpty(pf) then Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) else pf + let candidate = Path.Combine(pf, "dotnet", dotnet) + if fileExists candidate then + Some candidate + else + // Can't find it --- give up + None + + let getDotnetHostPath() = + // How to find dotnet.exe --- woe is me; probing rules make me sad. + // Algorithm: + // 1. Look for DOTNET_HOST_PATH environment variable + // this is the main user programable override .. provided by user to find a specific dotnet.exe + // 2. Probe for are we part of an .NetSDK install + // In an sdk install we are always installed in: sdk\3.0.100-rc2-014234\FSharp + // dotnet or dotnet.exe will be found in the directory that contains the sdk directory + // 3. We are loaded in-process to some other application ... Eg. try .net + // See if the host is dotnet.exe ... from net5.0 on this is fairly unlikely + // 4. If it's none of the above we are going to have to rely on the path containing the way to find dotnet.exe + // Use the path to search for dotnet.exe + let probePathForDotnetHost() = + let paths = + let p = Environment.GetEnvironmentVariable("PATH") + if not(isNull p) then p.Split(Path.PathSeparator) + else [||] + paths |> Array.tryFind (fun f -> fileExists (Path.Combine(f, dotnet))) + + match (Environment.GetEnvironmentVariable("DOTNET_HOST_PATH")) with + // Value set externally + | value when not (String.IsNullOrEmpty(value)) && fileExists value -> Some value + | _ -> + // Probe for netsdk install, dotnet. and dotnet.exe is a constant offset from the location of System.Int32 + let candidate = + let assemblyLocation = Path.GetDirectoryName(typeof.GetTypeInfo().Assembly.Location) + Path.GetFullPath(Path.Combine(assemblyLocation, "..", "..", "..", dotnet)) + if fileExists candidate then + Some candidate + else + match probePathForDotnetHost () with + | Some f -> Some (Path.Combine(f, dotnet)) + | None -> getDotnetGlobalHostPath() + + let getDotnetHostDirectories() = + let isDotnetMultilevelLookup = (Int32.TryParse(Environment.GetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP")) |> snd) <> 0 + [| + match getDotnetHostPath(), getDotnetGlobalHostPath() with + | Some hostPath, Some globalHostPath -> + yield Path.GetDirectoryName(hostPath) + if isDotnetMultilevelLookup && hostPath <> globalHostPath then + yield Path.GetDirectoryName(globalHostPath) + | Some hostPath, None -> + yield Path.GetDirectoryName(hostPath) + | None, Some globalHostPath -> + yield Path.GetDirectoryName(globalHostPath) + | None, None -> + () + |] + + let getDotnetHostDirectory() = getDotnetHostDirectories() |> Array.tryHead + + let getDotnetHostSubDirectories(path: string) = + [| + for directory in getDotnetHostDirectories() do + let subdirectory = Path.Combine(directory, path) + if Directory.Exists(subdirectory) then + yield! DirectoryInfo(subdirectory).GetDirectories() + |] diff --git a/src/fsharp/utils/CompilerLocationUtils.fsi b/src/fsharp/utils/CompilerLocationUtils.fsi new file mode 100644 index 00000000000..539c2a6e225 --- /dev/null +++ b/src/fsharp/utils/CompilerLocationUtils.fsi @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Internal.Utilities + +open Microsoft.FSharp.Core +open System.IO + +module internal FSharpEnvironment = + + val FSharpBannerVersion: string + + val FSharpProductName: string + + val FSharpCoreLibRunningVersion: string option + + val FSharpBinaryMetadataFormatRevision: string + + val isRunningOnCoreClr: bool + + val tryCurrentDomain: unit -> string option + + // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running + // Used for + // - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts + // - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks, but note a probe location is given) + // - default F# binaries directory in service.fs (REVIEW: check this) + // - default location of fsi.exe in FSharp.VS.FSI.dll (REVIEW: check this) + // - default F# binaries directory in (project system) Project.fs + val BinFolderOfDefaultFSharpCompiler: probePoint:string option -> string option + + val toolingCompatiblePaths: unit -> string list + + val searchToolPaths: path:string option -> compilerToolPaths:seq -> seq + + val getTypeProviderAssembly: + runTimeAssemblyFileName:string * + designTimeAssemblyName:string * + compilerToolPaths:string list * + raiseError:(string option -> exn -> System.Reflection.Assembly option) + -> System.Reflection.Assembly option + + val getFSharpCompilerLocation: unit -> string + + val getDefaultFSharpCoreLocation: unit -> string + + val getDefaultFsiLibraryLocation: unit -> string + + val getCompilerToolsDesignTimeAssemblyPaths: compilerToolPaths:seq -> seq + + val fsiLibraryName: string + + val getFSharpCoreLibraryName: string + + val isWindows: bool + + val dotnet: string + + val getDotnetHostPath: unit -> string option + + val getDotnetHostDirectories: unit -> string [] + + val getDotnetHostDirectory: unit -> string option + + val getDotnetHostSubDirectories: string -> DirectoryInfo [] diff --git a/src/utils/EditDistance.fs b/src/fsharp/utils/EditDistance.fs similarity index 100% rename from src/utils/EditDistance.fs rename to src/fsharp/utils/EditDistance.fs diff --git a/src/fsharp/utils/EditDistance.fsi b/src/fsharp/utils/EditDistance.fsi new file mode 100644 index 00000000000..83f9c650973 --- /dev/null +++ b/src/fsharp/utils/EditDistance.fsi @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal Internal.Utilities.EditDistance + +/// Calculates the Jaro-Winkler edit distance between two strings. +/// The edit distance is a metric that allows to measure the amount of similarity between two strings. +val JaroWinklerDistance : s1:string -> s2:string -> float + +/// Calculates the edit distance between two strings. +/// The edit distance is a metric that allows to measure the amount of difference between two strings +/// and shows how many edit operations (insert, delete, substitution) are needed to transform one string into the other. +val CalcEditDistance : a:string * b:string -> int diff --git a/src/fsharp/utils/FileSystem.fs b/src/fsharp/utils/FileSystem.fs new file mode 100644 index 00000000000..61ee255a639 --- /dev/null +++ b/src/fsharp/utils/FileSystem.fs @@ -0,0 +1,954 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.IO +open System +open System.IO +open System.IO.MemoryMappedFiles +open System.Buffers +open System.Reflection +open System.Threading +open System.Runtime.InteropServices +open FSharp.NativeInterop +open Internal.Utilities.Library + +open System.Text + +exception IllegalFileNameChar of string * char + +#nowarn "9" +module internal Bytes = + let b0 n = (n &&& 0xFF) + let b1 n = ((n >>> 8) &&& 0xFF) + let b2 n = ((n >>> 16) &&& 0xFF) + let b3 n = ((n >>> 24) &&& 0xFF) + + let dWw1 n = int32 ((n >>> 32) &&& 0xFFFFFFFFL) + let dWw0 n = int32 (n &&& 0xFFFFFFFFL) + + let get (b:byte[]) n = int32 (Array.get b n) + let zeroCreate n : byte[] = Array.zeroCreate n + + let sub ( b:byte[]) s l = Array.sub b s l + let blit (a:byte[]) b c d e = Array.blit a b c d e + + let ofInt32Array (arr:int[]) = Array.init arr.Length (fun i -> byte arr.[i]) + + let stringAsUtf8NullTerminated (s:string) = + Array.append (Encoding.UTF8.GetBytes s) (ofInt32Array [| 0x0 |]) + + let stringAsUnicodeNullTerminated (s:string) = + Array.append (Encoding.Unicode.GetBytes s) (ofInt32Array [| 0x0;0x0 |]) + +[] +[] +type ByteMemory() = + abstract Item: int -> byte with get, set + abstract Length: int + abstract ReadAllBytes: unit -> byte[] + abstract ReadBytes: pos: int * count: int -> byte[] + abstract ReadInt32: pos: int -> int + abstract ReadUInt16: pos: int -> uint16 + abstract ReadUtf8String: pos: int * count: int -> string + abstract Slice: pos: int * count: int -> ByteMemory + abstract CopyTo: Stream -> unit + abstract Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit + abstract ToArray: unit -> byte[] + abstract AsStream: unit -> Stream + abstract AsReadOnlyStream: unit -> Stream + +[] +[] +type ByteArrayMemory(bytes: byte[], offset, length) = + inherit ByteMemory() + + let checkCount count = + if count < 0 then + raise (ArgumentOutOfRangeException("count", "Count is less than zero.")) + + do + if length < 0 || length > bytes.Length then + raise (ArgumentOutOfRangeException("length")) + + if offset < 0 || (offset + length) > bytes.Length then + raise (ArgumentOutOfRangeException("offset")) + + override _.Item + with get i = bytes.[offset + i] + and set i v = bytes.[offset + i] <- v + + override _.Length = length + + override _.ReadAllBytes () = bytes + + override _.ReadBytes(pos, count) = + checkCount count + if count > 0 then + Array.sub bytes (offset + pos) count + else + Array.empty + + override _.ReadInt32 pos = + let finalOffset = offset + pos + (uint32 bytes.[finalOffset]) ||| + ((uint32 bytes.[finalOffset + 1]) <<< 8) ||| + ((uint32 bytes.[finalOffset + 2]) <<< 16) ||| + ((uint32 bytes.[finalOffset + 3]) <<< 24) + |> int + + override _.ReadUInt16 pos = + let finalOffset = offset + pos + (uint16 bytes.[finalOffset]) ||| + ((uint16 bytes.[finalOffset + 1]) <<< 8) + + override _.ReadUtf8String(pos, count) = + checkCount count + if count > 0 then + Encoding.UTF8.GetString(bytes, offset + pos, count) + else + String.Empty + + override _.Slice(pos, count) = + checkCount count + if count > 0 then + ByteArrayMemory(bytes, offset + pos, count) :> ByteMemory + else + ByteArrayMemory(Array.empty, 0, 0) :> ByteMemory + + override _.CopyTo stream = + if length > 0 then + stream.Write(bytes, offset, length) + + override _.Copy(srcOffset, dest, destOffset, count) = + checkCount count + if count > 0 then + Array.blit bytes (offset + srcOffset) dest destOffset count + + override _.ToArray() = + if length > 0 then + Array.sub bytes offset length + else + Array.empty + + override _.AsStream() = + if length > 0 then + new MemoryStream(bytes, offset, length) :> Stream + else + new MemoryStream([||], 0, 0, false) :> Stream + + override _.AsReadOnlyStream() = + if length > 0 then + new MemoryStream(bytes, offset, length, false) :> Stream + else + new MemoryStream([||], 0, 0, false) :> Stream + +[] +[] +type SafeUnmanagedMemoryStream = + inherit UnmanagedMemoryStream + + val mutable private holder: obj + val mutable private isDisposed: bool + + new (addr, length, holder) = + { + inherit UnmanagedMemoryStream(addr, length) + holder = holder + isDisposed = false + } + + new (addr: nativeptr, length: int64, capacity: int64, access: FileAccess, holder) = + { + inherit UnmanagedMemoryStream(addr, length, capacity, access) + holder = holder + isDisposed = false + } + + override x.Dispose disposing = + base.Dispose disposing + x.holder <- null // Null out so it can be collected. + +type internal MemoryMappedStream(mmf: MemoryMappedFile, length: int64) = + inherit Stream() + + let viewStream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.Read) + + member _.ViewStream = viewStream + + override x.CanRead = viewStream.CanRead + override x.CanWrite = viewStream.CanWrite + override x.CanSeek = viewStream.CanSeek + override x.Position with get() = viewStream.Position and set v = viewStream.Position <- v + override x.Length = viewStream.Length + override x.Flush() = viewStream.Flush() + override x.Seek(offset, origin) = viewStream.Seek(offset, origin) + override x.SetLength(value) = viewStream.SetLength(value) + override x.Write(buffer, offset, count) = viewStream.Write(buffer, offset, count) + override x.Read(buffer, offset, count) = viewStream.Read(buffer, offset, count) + + override x.Finalize() = + x.Dispose() + + interface IDisposable with + override x.Dispose() = + GC.SuppressFinalize x + mmf.Dispose() + viewStream.Dispose() + + +[] +type RawByteMemory(addr: nativeptr, length: int, holder: obj) = + inherit ByteMemory () + + let check i = + if i < 0 || i >= length then + raise (ArgumentOutOfRangeException(nameof i)) + + let checkCount count = + if count < 0 then + raise (ArgumentOutOfRangeException(nameof count, "Count is less than zero.")) + + do + if length < 0 then + raise (ArgumentOutOfRangeException(nameof length)) + + override _.Item + with get i = + check i + NativePtr.add addr i + |> NativePtr.read + and set i v = + check i + NativePtr.set addr i v + + override _.Length = length + + override this.ReadAllBytes() = + this.ReadBytes(0, length) + + override _.ReadBytes(pos, count) = + checkCount count + if count > 0 then + check pos + check (pos + count - 1) + let res = Bytes.zeroCreate count + Marshal.Copy(NativePtr.toNativeInt addr + nativeint pos, res, 0, count) + res + else + Array.empty + + override _.ReadInt32 pos = + check pos + check (pos + 3) + let finalAddr = NativePtr.toNativeInt addr + nativeint pos + uint32(Marshal.ReadByte(finalAddr, 0)) ||| + (uint32(Marshal.ReadByte(finalAddr, 1)) <<< 8) ||| + (uint32(Marshal.ReadByte(finalAddr, 2)) <<< 16) ||| + (uint32(Marshal.ReadByte(finalAddr, 3)) <<< 24) + |> int + + override _.ReadUInt16 pos = + check pos + check (pos + 1) + let finalAddr = NativePtr.toNativeInt addr + nativeint pos + uint16(Marshal.ReadByte(finalAddr, 0)) ||| + (uint16(Marshal.ReadByte(finalAddr, 1)) <<< 8) + + override _.ReadUtf8String(pos, count) = + checkCount count + if count > 0 then + check pos + check (pos + count - 1) + Encoding.UTF8.GetString(NativePtr.add addr pos, count) + else + String.Empty + + override _.Slice(pos, count) = + checkCount count + if count > 0 then + check pos + check (pos + count - 1) + RawByteMemory(NativePtr.add addr pos, count, holder) :> ByteMemory + else + ByteArrayMemory(Array.empty, 0, 0) :> ByteMemory + + override x.CopyTo stream = + if length > 0 then + use stream2 = x.AsStream() + stream2.CopyTo stream + + override _.Copy(srcOffset, dest, destOffset, count) = + checkCount count + if count > 0 then + check srcOffset + Marshal.Copy(NativePtr.toNativeInt addr + nativeint srcOffset, dest, destOffset, count) + + override _.ToArray() = + if length > 0 then + let res = Array.zeroCreate length + Marshal.Copy(NativePtr.toNativeInt addr, res, 0, res.Length) + res + else + Array.empty + + override _.AsStream() = + if length > 0 then + new SafeUnmanagedMemoryStream(addr, int64 length, holder) :> Stream + else + new MemoryStream([||], 0, 0, false) :> Stream + + override _.AsReadOnlyStream() = + if length > 0 then + new SafeUnmanagedMemoryStream(addr, int64 length, int64 length, FileAccess.Read, holder) :> Stream + else + new MemoryStream([||], 0, 0, false) :> Stream + +[] +type ReadOnlyByteMemory(bytes: ByteMemory) = + member _.Item with get i = bytes.[i] + member _.Length with get () = bytes.Length + member _.ReadAllBytes() = bytes.ReadAllBytes() + member _.ReadBytes(pos, count) = bytes.ReadBytes(pos, count) + member _.ReadInt32 pos = bytes.ReadInt32 pos + member _.ReadUInt16 pos = bytes.ReadUInt16 pos + member _.ReadUtf8String(pos, count) = bytes.ReadUtf8String(pos, count) + member _.Slice(pos, count) = bytes.Slice(pos, count) |> ReadOnlyByteMemory + member _.CopyTo stream = bytes.CopyTo stream + member _.Copy(srcOffset, dest, destOffset, count) = bytes.Copy(srcOffset, dest, destOffset, count) + member _.ToArray() = bytes.ToArray() + member _.AsStream() = bytes.AsReadOnlyStream() + member _.Underlying = bytes + +[] +module MemoryMappedFileExtensions = + + let private trymmf length copyTo = + let length = int64 length + if length = 0L then + None + else + if runningOnMono then + // mono's MemoryMappedFile implementation throws with null `mapName`, so we use byte arrays instead: https://github.com/mono/mono/issues/1024 + None + else + // Try to create a memory mapped file and copy the contents of the given bytes to it. + // If this fails, then we clean up and return None. + try + let mmf = MemoryMappedFile.CreateNew(null, length, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None) + try + use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite) + copyTo stream + Some mmf + with + | _ -> + mmf.Dispose() + None + with + | _ -> + None + + type MemoryMappedFile with + static member TryFromByteMemory(bytes: ReadOnlyByteMemory) = + trymmf (int64 bytes.Length) bytes.CopyTo + + static member TryFromMemory(bytes: ReadOnlyMemory) = + let length = int64 bytes.Length + trymmf length + (fun stream -> + let span = Span(stream.PositionPointer |> NativePtr.toVoidPtr, int length) + bytes.Span.CopyTo(span) + stream.Position <- stream.Position + length + ) + +[] +module internal FileSystemUtils = + let checkPathForIllegalChars = + let chars = System.Collections.Generic.HashSet<_>(Path.GetInvalidPathChars()) + (fun (path:string) -> + for c in path do + if chars.Contains c then raise(IllegalFileNameChar(path, c))) + + let checkSuffix (x:string) (y:string) = x.EndsWithOrdinal(y) + + let hasExtensionWithValidate (validate:bool) (s:string) = + if validate then (checkPathForIllegalChars s) + let sLen = s.Length + (sLen >= 1 && s.[sLen - 1] = '.' && s <> ".." && s <> ".") + || Path.HasExtension(s) + + let hasExtension (s:string) = hasExtensionWithValidate true s + + let chopExtension (s:string) = + checkPathForIllegalChars s + if s = "." then "" else // for OCaml compatibility + if not (hasExtensionWithValidate false s) then + raise (ArgumentException("chopExtension")) // message has to be precisely this, for OCaml compatibility, and no argument name can be set + Path.Combine (Path.GetDirectoryName s, Path.GetFileNameWithoutExtension(s)) + + let fileNameOfPath s = + checkPathForIllegalChars s + Path.GetFileName(s) + + let fileNameWithoutExtensionWithValidate (validate:bool) s = + if validate then checkPathForIllegalChars s + Path.GetFileNameWithoutExtension(s) + + let fileNameWithoutExtension s = fileNameWithoutExtensionWithValidate true s + + let trimQuotes (s:string) = + s.Trim( [|' '; '\"'|] ) + + let hasSuffixCaseInsensitive suffix filename = (* case-insensitive *) + checkSuffix (String.lowercase filename) (String.lowercase suffix) + + let isDll file = hasSuffixCaseInsensitive ".dll" file + +[] +type IAssemblyLoader = + abstract AssemblyLoadFrom: fileName: string -> Assembly + abstract AssemblyLoad: assemblyName: AssemblyName -> Assembly + +[] +type DefaultAssemblyLoader() = + interface IAssemblyLoader with + member _.AssemblyLoadFrom(fileName: string) = Assembly.UnsafeLoadFrom fileName + member _.AssemblyLoad(assemblyName: AssemblyName) = Assembly.Load assemblyName + +[] +type IFileSystem = + // note: do not add members if you can put generic implementation under StreamExtensions below. + abstract AssemblyLoader: IAssemblyLoader + abstract OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream + abstract OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream + abstract GetFullPathShim: fileName: string -> string + abstract GetFullFilePathInDirectoryShim: dir: string -> fileName: string -> string + abstract IsPathRootedShim: path: string -> bool + abstract NormalizePathShim: path: string -> string + abstract IsInvalidPathShim: path: string -> bool + abstract GetTempPathShim: unit -> string + abstract GetDirectoryNameShim: path: string -> string + abstract GetLastWriteTimeShim: fileName: string -> DateTime + abstract GetCreationTimeShim: path: string -> DateTime + abstract CopyShim: src: string * dest: string * overwrite: bool -> unit + abstract FileExistsShim: fileName: string -> bool + abstract FileDeleteShim: fileName: string -> unit + abstract DirectoryCreateShim: path: string -> DirectoryInfo + abstract DirectoryExistsShim: path: string -> bool + abstract DirectoryDeleteShim: path: string -> unit + abstract EnumerateFilesShim: path: string * pattern: string -> string seq + abstract EnumerateDirectoriesShim: path: string -> string seq + abstract IsStableFileHeuristic: fileName: string -> bool + // note: do not add members if you can put generic implementation under StreamExtensions below. + +[] +type DefaultFileSystem() as this = + abstract AssemblyLoader : IAssemblyLoader + default _.AssemblyLoader = DefaultAssemblyLoader() :> IAssemblyLoader + + abstract OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream + default _.OpenFileForReadShim(filePath: string, ?useMemoryMappedFile: bool, ?shouldShadowCopy: bool) : Stream = + let fileMode = FileMode.Open + let fileAccess = FileAccess.Read + let fileShare = FileShare.Delete ||| FileShare.ReadWrite + let shouldShadowCopy = defaultArg shouldShadowCopy false + let useMemoryMappedFile = defaultArg useMemoryMappedFile false + let fileStream = new FileStream(filePath, fileMode, fileAccess, fileShare) + let length = fileStream.Length + + // We want to use mmaped files only when: + // - Opening large binary files (no need to use for source or resource files really) + // - Running on mono, since its MemoryMappedFile implementation throws when "mapName" is not provided (is null). + // (See: https://github.com/mono/mono/issues/10245) + + if runningOnMono || (not useMemoryMappedFile) then + fileStream :> Stream + else + let mmf = + if shouldShadowCopy then + let mmf = + MemoryMappedFile.CreateNew( + null, + length, + MemoryMappedFileAccess.Read, + MemoryMappedFileOptions.None, + HandleInheritability.None) + use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.Read) + fileStream.CopyTo(stream) + fileStream.Dispose() + mmf + else + MemoryMappedFile.CreateFromFile( + fileStream, + null, + length, + MemoryMappedFileAccess.Read, + HandleInheritability.None, + leaveOpen=false) + + let stream = new MemoryMappedStream(mmf, length) + + if not stream.CanRead then + invalidOp "Cannot read file" + stream :> Stream + + + abstract OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream + default _.OpenFileForWriteShim(filePath: string, ?fileMode: FileMode, ?fileAccess: FileAccess, ?fileShare: FileShare) : Stream = + let fileMode = defaultArg fileMode FileMode.OpenOrCreate + let fileAccess = defaultArg fileAccess FileAccess.ReadWrite + let fileShare = defaultArg fileShare FileShare.Delete ||| FileShare.ReadWrite + + new FileStream(filePath, fileMode, fileAccess, fileShare) :> Stream + + abstract GetFullPathShim: fileName: string -> string + default _.GetFullPathShim (fileName: string) = Path.GetFullPath fileName + + abstract GetFullFilePathInDirectoryShim: dir: string -> fileName: string -> string + default this.GetFullFilePathInDirectoryShim (dir: string) (fileName: string) = + let p = if (this :> IFileSystem).IsPathRootedShim(fileName) then fileName else Path.Combine(dir, fileName) + try (this :> IFileSystem).GetFullPathShim(p) with + | :? ArgumentException + | :? ArgumentNullException + | :? NotSupportedException + | :? PathTooLongException + | :? System.Security.SecurityException -> p + + abstract IsPathRootedShim: path: string -> bool + default _.IsPathRootedShim (path: string) = Path.IsPathRooted path + + abstract NormalizePathShim: path: string -> string + default _.NormalizePathShim (path: string) = + try + let ifs = this :> IFileSystem + if ifs.IsPathRootedShim path then + ifs.GetFullPathShim path + else + path + with _ -> path + + abstract IsInvalidPathShim: path: string -> bool + default _.IsInvalidPathShim(path: string) = + let isInvalidPath(p: string) = + String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidPathChars()) <> -1 + + let isInvalidFilename(p: string) = + String.IsNullOrEmpty p || p.IndexOfAny(Path.GetInvalidFileNameChars()) <> -1 + + let isInvalidDirectory(d: string) = + d=null || d.IndexOfAny(Path.GetInvalidPathChars()) <> -1 + + isInvalidPath path || + let directory = Path.GetDirectoryName path + let filename = Path.GetFileName path + isInvalidDirectory directory || isInvalidFilename filename + + abstract GetTempPathShim: unit -> string + default _.GetTempPathShim() = Path.GetTempPath() + + abstract GetDirectoryNameShim: path: string -> string + default _.GetDirectoryNameShim(path:string) = + FileSystemUtils.checkPathForIllegalChars path + if path = "" then "." + else + match Path.GetDirectoryName(path) with + | null -> if (this :> IFileSystem).IsPathRootedShim(path) then path else "." + | res -> if res = "" then "." else res + + abstract GetLastWriteTimeShim: fileName: string -> DateTime + default _.GetLastWriteTimeShim (fileName: string) = File.GetLastWriteTimeUtc fileName + + abstract GetCreationTimeShim: path: string -> DateTime + default _.GetCreationTimeShim (path: string) = File.GetCreationTimeUtc path + + abstract CopyShim: src: string * dest: string * overwrite: bool -> unit + default _.CopyShim (src: string, dest: string, overwrite: bool) = File.Copy(src, dest, overwrite) + + abstract FileExistsShim: fileName: string -> bool + default _.FileExistsShim (fileName: string) = File.Exists fileName + + abstract FileDeleteShim: fileName: string -> unit + default _.FileDeleteShim (fileName: string) = File.Delete fileName + + abstract DirectoryCreateShim: path: string -> DirectoryInfo + default _.DirectoryCreateShim (path: string) = Directory.CreateDirectory path + + abstract DirectoryExistsShim: path: string -> bool + default _.DirectoryExistsShim (path: string) = Directory.Exists path + + abstract DirectoryDeleteShim: path: string -> unit + default _.DirectoryDeleteShim (path: string) = Directory.Delete path + + abstract EnumerateFilesShim: path: string * pattern: string -> string seq + default _.EnumerateFilesShim(path: string, pattern: string) = Directory.EnumerateFiles(path, pattern) + + abstract EnumerateDirectoriesShim: path: string -> string seq + default _.EnumerateDirectoriesShim(path: string) = Directory.EnumerateDirectories(path) + + abstract IsStableFileHeuristic: fileName: string -> bool + default _.IsStableFileHeuristic (fileName: string) = + let directory = Path.GetDirectoryName fileName + directory.Contains("Reference Assemblies/") || + directory.Contains("Reference Assemblies\\") || + directory.Contains("packages/") || + directory.Contains("packages\\") || + directory.Contains("lib/mono/") + + interface IFileSystem with + member _.AssemblyLoader = this.AssemblyLoader + + member _.OpenFileForReadShim(filePath: string, ?useMemoryMappedFile: bool, ?shouldShadowCopy: bool) : Stream = + let shouldShadowCopy = defaultArg shouldShadowCopy false + let useMemoryMappedFile = defaultArg useMemoryMappedFile false + this.OpenFileForReadShim(filePath, useMemoryMappedFile, shouldShadowCopy) + + member _.OpenFileForWriteShim(filePath: string, ?fileMode: FileMode, ?fileAccess: FileAccess, ?fileShare: FileShare) : Stream = + let fileMode = defaultArg fileMode FileMode.OpenOrCreate + let fileAccess = defaultArg fileAccess FileAccess.ReadWrite + let fileShare = defaultArg fileShare FileShare.Delete ||| FileShare.ReadWrite + this.OpenFileForWriteShim(filePath, fileMode, fileAccess, fileShare) + + member _.GetFullPathShim (fileName: string) = this.GetFullPathShim fileName + member _.GetFullFilePathInDirectoryShim (dir: string) (fileName: string) = this.GetFullFilePathInDirectoryShim dir fileName + member _.IsPathRootedShim (path: string) = this.IsPathRootedShim path + member _.NormalizePathShim (path: string) = this.NormalizePathShim path + member _.IsInvalidPathShim(path: string) = this.IsInvalidPathShim path + member _.GetTempPathShim() = this.GetTempPathShim() + member _.GetDirectoryNameShim(s:string) = this.GetDirectoryNameShim s + member _.GetLastWriteTimeShim (fileName: string) = this.GetLastWriteTimeShim fileName + member _.GetCreationTimeShim (path: string) = this.GetCreationTimeShim path + member _.CopyShim (src: string, dest: string, overwrite: bool) = this.CopyShim(src, dest, overwrite) + member _.FileExistsShim (fileName: string) = this.FileExistsShim fileName + member _.FileDeleteShim (fileName: string) = this.FileDeleteShim fileName + member _.DirectoryCreateShim (path: string) = this.DirectoryCreateShim path + member _.DirectoryExistsShim (path: string) = this.DirectoryExistsShim path + member _.DirectoryDeleteShim (path: string) = this.DirectoryDeleteShim path + member _.EnumerateFilesShim(path: string, pattern: string) = this.EnumerateFilesShim(path, pattern) + member _.EnumerateDirectoriesShim(path: string) = this.EnumerateDirectoriesShim path + member _.IsStableFileHeuristic (fileName: string) = this.IsStableFileHeuristic fileName + +[] +module public StreamExtensions = + let utf8noBOM = UTF8Encoding(false, true) :> Encoding + type Stream with + member s.GetWriter(?encoding: Encoding) : TextWriter = + let encoding = defaultArg encoding utf8noBOM + new StreamWriter(s, encoding) :> TextWriter + + member s.WriteAllLines(contents: string seq, ?encoding: Encoding) = + let encoding = defaultArg encoding utf8noBOM + use writer = s.GetWriter(encoding) + for l in contents do + writer.WriteLine(l) + + member s.Write (data: 'a) : unit = + use sw = s.GetWriter() + sw.Write(data) + + member s.GetReader(codePage: int option, ?retryLocked: bool) = + let retryLocked = defaultArg retryLocked false + let retryDelayMilliseconds = 50 + let numRetries = 60 + let rec getSource retryNumber = + try + // Use the .NET functionality to auto-detect the unicode encoding + match codePage with + | None -> new StreamReader(s, true) + | Some n -> new StreamReader(s, Encoding.GetEncoding(n)) + with + // We can get here if the file is locked--like when VS is saving a file--we don't have direct + // access to the HRESULT to see that this is EONOACCESS. + | :? IOException as err when retryLocked && err.GetType() = typeof -> + // This second check is to make sure the exception is exactly IOException and none of these for example: + // DirectoryNotFoundException + // EndOfStreamException + // FileNotFoundException + // FileLoadException + // PathTooLongException + if retryNumber < numRetries then + Thread.Sleep retryDelayMilliseconds + getSource (retryNumber + 1) + else + reraise() + getSource 0 + + member s.ReadBytes (start, len) = + s.Seek(int64 start, SeekOrigin.Begin) |> ignore + let buffer = Array.zeroCreate len + let mutable n = 0 + while n < len do + n <- n + s.Read(buffer, n, len-n) + buffer + + member s.ReadAllBytes() = + use reader = new BinaryReader(s) + let count = (int s.Length) + reader.ReadBytes(count) + + member s.ReadAllText(?encoding: Encoding) = + let encoding = defaultArg encoding Encoding.UTF8 + use sr = new StreamReader(s, encoding, true) + sr.ReadToEnd() + + member s.ReadLines(?encoding: Encoding) : string seq = + let encoding = defaultArg encoding Encoding.UTF8 + seq { + use sr = new StreamReader(s, encoding, true) + while not <| sr.EndOfStream do + yield sr.ReadLine() + } + member s.ReadAllLines(?encoding: Encoding) : string array = + let encoding = defaultArg encoding Encoding.UTF8 + s.ReadLines(encoding) |> Seq.toArray + + member s.WriteAllText(text: string) = + use writer = new StreamWriter(s) + writer.Write text + + /// If we are working with the view stream from mmf, we wrap it in RawByteMemory (which does zero copy, bu just using handle from the views stream). + /// However, when we use any other stream (FileStream, MemoryStream, etc) - we just read everything from it and expose via ByteArrayMemory. + member s.AsByteMemory() : ByteMemory = + match s with + | :? MemoryMappedStream as mmfs -> + let length = mmfs.Length + RawByteMemory( + NativePtr.ofNativeInt (mmfs.ViewStream.SafeMemoryMappedViewHandle.DangerousGetHandle()), + int length, + mmfs) :> ByteMemory + + | _ -> + let bytes = s.ReadAllBytes() + let byteArrayMemory = if bytes.Length = 0 then ByteArrayMemory([||], 0, 0) else ByteArrayMemory(bytes, 0, bytes.Length) + byteArrayMemory :> ByteMemory + +[] +module public FileSystemAutoOpens = + /// The global hook into the file system + let mutable FileSystem: IFileSystem = DefaultFileSystem() :> IFileSystem + +type ByteMemory with + + member x.AsReadOnly() = ReadOnlyByteMemory x + + static member Empty = ByteArrayMemory([||], 0, 0) :> ByteMemory + + static member FromMemoryMappedFile(mmf: MemoryMappedFile) = + let accessor = mmf.CreateViewAccessor() + RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int accessor.Capacity, (mmf, accessor)) + + static member FromUnsafePointer(addr, length, holder: obj) = + RawByteMemory(NativePtr.ofNativeInt addr, length, holder) :> ByteMemory + + static member FromArray(bytes, offset, length) = + ByteArrayMemory(bytes, offset, length) :> ByteMemory + + static member FromArray (bytes: byte array) = + if bytes.Length = 0 then + ByteMemory.Empty + else + ByteArrayMemory.FromArray(bytes, 0, bytes.Length) + +type internal ByteStream = + { bytes: ReadOnlyByteMemory + mutable pos: int + max: int } + member b.ReadByte() = + if b.pos >= b.max then failwith "end of stream" + let res = b.bytes.[b.pos] + b.pos <- b.pos + 1 + res + member b.ReadUtf8String n = + let res = b.bytes.ReadUtf8String(b.pos,n) + b.pos <- b.pos + n; res + + static member FromBytes (b: ReadOnlyByteMemory,start,length) = + if start < 0 || (start+length) > b.Length then failwith "FromBytes" + { bytes = b; pos = start; max = start+length } + + member b.ReadBytes n = + if b.pos + n > b.max then failwith "ReadBytes: end of stream" + let res = b.bytes.Slice(b.pos, n) + b.pos <- b.pos + n + res + + member b.Position = b.pos +#if LAZY_UNPICKLE + member b.CloneAndSeek = { bytes=b.bytes; pos=pos; max=b.max } + member b.Skip = b.pos <- b.pos + n +#endif + + +type internal ByteBuffer = + { useArrayPool: bool + mutable isDisposed: bool + mutable bbArray: byte[] + mutable bbCurrent: int } + + member inline private buf.CheckDisposed() = + if buf.isDisposed then + raise(ObjectDisposedException(nameof(ByteBuffer))) + + member private buf.Ensure newSize = + let oldBufSize = buf.bbArray.Length + if newSize > oldBufSize then + let old = buf.bbArray + buf.bbArray <- + if buf.useArrayPool then + ArrayPool.Shared.Rent (max newSize (oldBufSize * 2)) + else + Bytes.zeroCreate (max newSize (oldBufSize * 2)) + Bytes.blit old 0 buf.bbArray 0 buf.bbCurrent + if buf.useArrayPool then + ArrayPool.Shared.Return old + + member buf.AsMemory() = + buf.CheckDisposed() + ReadOnlyMemory(buf.bbArray, 0, buf.bbCurrent) + + member buf.EmitIntAsByte (i:int) = + buf.CheckDisposed() + let newSize = buf.bbCurrent + 1 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- byte i + buf.bbCurrent <- newSize + + member buf.EmitByte (b:byte) = + buf.CheckDisposed() + buf.EmitIntAsByte (int b) + + member buf.EmitIntsAsBytes (arr:int[]) = + buf.CheckDisposed() + let n = arr.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + let bbArr = buf.bbArray + let bbBase = buf.bbCurrent + for i = 0 to n - 1 do + bbArr.[bbBase + i] <- byte arr.[i] + buf.bbCurrent <- newSize + + member bb.FixupInt32 pos value = + bb.CheckDisposed() + bb.bbArray.[pos] <- (Bytes.b0 value |> byte) + bb.bbArray.[pos + 1] <- (Bytes.b1 value |> byte) + bb.bbArray.[pos + 2] <- (Bytes.b2 value |> byte) + bb.bbArray.[pos + 3] <- (Bytes.b3 value |> byte) + + member buf.EmitInt32 n = + buf.CheckDisposed() + let newSize = buf.bbCurrent + 4 + buf.Ensure newSize + buf.FixupInt32 buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitBytes (i:byte[]) = + buf.CheckDisposed() + let n = i.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + Bytes.blit i 0 buf.bbArray buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitMemory (i:ReadOnlyMemory) = + buf.CheckDisposed() + let n = i.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + i.CopyTo(Memory(buf.bbArray, buf.bbCurrent, n)) + buf.bbCurrent <- newSize + + member buf.EmitByteMemory (i:ReadOnlyByteMemory) = + buf.CheckDisposed() + let n = i.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + i.Copy(0, buf.bbArray, buf.bbCurrent, n) + buf.bbCurrent <- newSize + + member buf.EmitInt32AsUInt16 n = + buf.CheckDisposed() + let newSize = buf.bbCurrent + 2 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- (Bytes.b0 n |> byte) + buf.bbArray.[buf.bbCurrent + 1] <- (Bytes.b1 n |> byte) + buf.bbCurrent <- newSize + + member buf.EmitBoolAsByte (b:bool) = + buf.CheckDisposed() + buf.EmitIntAsByte (if b then 1 else 0) + + member buf.EmitUInt16 (x:uint16) = + buf.CheckDisposed() + buf.EmitInt32AsUInt16 (int32 x) + + member buf.EmitInt64 x = + buf.CheckDisposed() + buf.EmitInt32 (Bytes.dWw0 x) + buf.EmitInt32 (Bytes.dWw1 x) + + member buf.Position = + buf.CheckDisposed() + buf.bbCurrent + + static member Create(capacity, useArrayPool) = + let useArrayPool = defaultArg useArrayPool false + { useArrayPool = useArrayPool + isDisposed = false + bbArray = if useArrayPool then ArrayPool.Shared.Rent capacity else Bytes.zeroCreate capacity + bbCurrent = 0 } + + interface IDisposable with + + member this.Dispose() = + if not this.isDisposed then + this.isDisposed <- true + if this.useArrayPool then + ArrayPool.Shared.Return this.bbArray + +[] +type ByteStorage(getByteMemory: unit -> ReadOnlyByteMemory) = + + let mutable cached = Unchecked.defaultof> + + let getAndCache () = + let byteMemory = getByteMemory () + cached <- WeakReference(byteMemory.Underlying) + byteMemory + + member _.GetByteMemory() = + match cached with + | null -> getAndCache () + | _ -> + match cached.TryGetTarget() with + | true, byteMemory -> byteMemory.AsReadOnly() + | _ -> getAndCache () + + static member FromByteArray(bytes: byte []) = + ByteStorage.FromByteMemory(ByteMemory.FromArray(bytes).AsReadOnly()) + + static member FromByteMemory(bytes: ReadOnlyByteMemory) = + ByteStorage(fun () -> bytes) + + static member FromByteMemoryAndCopy(bytes: ReadOnlyByteMemory, useBackingMemoryMappedFile: bool) = + if useBackingMemoryMappedFile then + match MemoryMappedFile.TryFromByteMemory(bytes) with + | Some mmf -> + ByteStorage(fun () -> ByteMemory.FromMemoryMappedFile(mmf).AsReadOnly()) + | _ -> + let copiedBytes = ByteMemory.FromArray(bytes.ToArray()).AsReadOnly() + ByteStorage.FromByteMemory(copiedBytes) + else + let copiedBytes = ByteMemory.FromArray(bytes.ToArray()).AsReadOnly() + ByteStorage.FromByteMemory(copiedBytes) + + static member FromMemoryAndCopy(bytes: ReadOnlyMemory, useBackingMemoryMappedFile: bool) = + if useBackingMemoryMappedFile then + match MemoryMappedFile.TryFromMemory(bytes) with + | Some mmf -> + ByteStorage(fun () -> ByteMemory.FromMemoryMappedFile(mmf).AsReadOnly()) + | _ -> + let copiedBytes = ByteMemory.FromArray(bytes.ToArray()).AsReadOnly() + ByteStorage.FromByteMemory(copiedBytes) + else + let copiedBytes = ByteMemory.FromArray(bytes.ToArray()).AsReadOnly() + ByteStorage.FromByteMemory(copiedBytes) + + static member FromByteArrayAndCopy(bytes: byte [], useBackingMemoryMappedFile: bool) = + ByteStorage.FromByteMemoryAndCopy(ByteMemory.FromArray(bytes).AsReadOnly(), useBackingMemoryMappedFile) diff --git a/src/fsharp/utils/FileSystem.fsi b/src/fsharp/utils/FileSystem.fsi new file mode 100644 index 00000000000..53dd6e7e548 --- /dev/null +++ b/src/fsharp/utils/FileSystem.fsi @@ -0,0 +1,401 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// This file contains public types related to the "file system hook" of the FCS API which are used throughout the F# compiler. +namespace FSharp.Compiler.IO + +open System +open System.IO +open System.IO.MemoryMappedFiles +open System.Reflection +open System.Text +open System.Runtime.CompilerServices + +exception IllegalFileNameChar of string * char + +module internal Bytes = + /// returned int will be 0 <= x <= 255 + val get: byte[] -> int -> int + val zeroCreate: int -> byte[] + /// each int must be 0 <= x <= 255 + val ofInt32Array: int[] -> byte[] + /// each int will be 0 <= x <= 255 + val blit: byte[] -> int -> byte[] -> int -> int -> unit + + val stringAsUnicodeNullTerminated: string -> byte[] + val stringAsUtf8NullTerminated: string -> byte[] + +/// A view over bytes. +/// May be backed by managed or unmanaged memory, or memory mapped file. +[] +type public ByteMemory = + + abstract Item: int -> byte with get + + abstract Length: int + + abstract ReadAllBytes: unit -> byte[] + + abstract ReadBytes: pos: int * count: int -> byte[] + + abstract ReadInt32: pos: int -> int + + abstract ReadUInt16: pos: int -> uint16 + + abstract ReadUtf8String: pos: int * count: int -> string + + abstract Slice: pos: int * count: int -> ByteMemory + + abstract CopyTo: Stream -> unit + + abstract Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit + + abstract ToArray: unit -> byte[] + + /// Get a stream representation of the backing memory. + /// Disposing this will not free up any of the backing memory. + abstract AsStream: unit -> Stream + + /// Get a stream representation of the backing memory. + /// Disposing this will not free up any of the backing memory. + /// Stream cannot be written to. + abstract AsReadOnlyStream: unit -> Stream + +[] +type internal ReadOnlyByteMemory = + + new: ByteMemory -> ReadOnlyByteMemory + + member Item: int -> byte with get + + member Length: int + + member ReadAllBytes: unit -> byte[] + + member ReadBytes: pos: int * count: int -> byte[] + + member ReadInt32: pos: int -> int + + member ReadUInt16: pos: int -> uint16 + + member ReadUtf8String: pos: int * count: int -> string + + member Slice: pos: int * count: int -> ReadOnlyByteMemory + + member CopyTo: Stream -> unit + + member Copy: srcOffset: int * dest: byte[] * destOffset: int * count: int -> unit + + member ToArray: unit -> byte[] + + member AsStream: unit -> Stream + +/// MemoryMapped extensions +module internal MemoryMappedFileExtensions = + type MemoryMappedFile with + static member TryFromByteMemory : bytes: ReadOnlyByteMemory -> MemoryMappedFile option + static member TryFromMemory : bytes: ReadOnlyMemory -> MemoryMappedFile option + +/// Filesystem helpers +module internal FileSystemUtils = + val checkPathForIllegalChars: (string -> unit) + + /// checkSuffix f s returns True if filename "f" ends in suffix "s", + /// e.g. checkSuffix "abc.fs" ".fs" returns true. + val checkSuffix: string -> string -> bool + + /// chopExtension f removes the extension from the given + /// filename. Raises ArgumentException if no extension is present. + val chopExtension: string -> string + + /// Return True if the filename has a "." extension. + val hasExtension: string -> bool + + /// Get the filename of the given path. + val fileNameOfPath: string -> string + + /// Get the filename without extension of the given path. + val fileNameWithoutExtensionWithValidate: bool -> string -> string + val fileNameWithoutExtension: string -> string + + /// Trim the quotes and spaces from either end of a string + val trimQuotes: string -> string + + /// Checks whether filename ends in suffix, ignoring case. + val hasSuffixCaseInsensitive: string -> string -> bool + + /// Checks whether file is dll (ends in .dll) + val isDll: string -> bool + +/// Type which we use to load assemblies. +type public IAssemblyLoader = + /// Used to load a dependency for F# Interactive and in an unused corner-case of type provider loading + abstract AssemblyLoad: assemblyName:AssemblyName -> Assembly + + /// Used to load type providers and located assemblies in F# Interactive + abstract AssemblyLoadFrom: fileName:string -> Assembly + +/// Default implementation for IAssemblyLoader +type DefaultAssemblyLoader = + new: unit -> DefaultAssemblyLoader + interface IAssemblyLoader + +/// Represents a shim for the file system +type public IFileSystem = + + // Assembly loader. + abstract AssemblyLoader : IAssemblyLoader + + /// Open the file for read, returns ByteMemory, uses either FileStream (for smaller files) or MemoryMappedFile (for potentially big files, such as dlls). + abstract OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream + + /// Open the file for writing. Returns a Stream. + abstract OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream + + /// Take in a filename with an absolute path, and return the same filename + /// but canonicalized with respect to extra path separators (e.g. C:\\\\foo.txt) + /// and '..' portions + abstract GetFullPathShim: fileName:string -> string + + /// Take in a directory, filename, and return canonicalized path to the filename in directory. + /// If filename path is rooted, ignores directory and returns filename path. + /// Otherwise, combines directory with filename and gets full path via GetFullPathShim(string). + abstract GetFullFilePathInDirectoryShim: dir: string -> fileName: string -> string + + /// A shim over Path.IsPathRooted + abstract IsPathRootedShim: path:string -> bool + + /// Removes relative parts from any full paths + abstract NormalizePathShim: path: string -> string + + /// A shim over Path.IsInvalidPath + abstract IsInvalidPathShim: path:string -> bool + + /// A shim over Path.GetTempPath + abstract GetTempPathShim: unit -> string + + /// A shim for getting directory name from path + abstract GetDirectoryNameShim: path: string -> string + + /// Utc time of the last modification + abstract GetLastWriteTimeShim: fileName:string -> DateTime + + // Utc time of creation + abstract GetCreationTimeShim: path: string -> DateTime + + // A shim over file copying. + abstract CopyShim: src: string * dest: string * overwrite: bool -> unit + + /// A shim over File.Exists + abstract FileExistsShim: fileName: string -> bool + + /// A shim over File.Delete + abstract FileDeleteShim: fileName: string -> unit + + /// A shim over Directory.Exists + abstract DirectoryCreateShim: path: string -> DirectoryInfo + + /// A shim over Directory.Exists + abstract DirectoryExistsShim: path: string -> bool + + /// A shim over Directory.Delete + abstract DirectoryDeleteShim: path: string -> unit + + /// A shim over Directory.EnumerateFiles + abstract EnumerateFilesShim: path: string * pattern: string -> string seq + + /// A shim over Directory.EnumerateDirectories + abstract EnumerateDirectoriesShim: path: string -> string seq + + /// Used to determine if a file will not be subject to deletion during the lifetime of a typical client process. + abstract IsStableFileHeuristic: fileName:string -> bool + + +/// Represents a default (memory-mapped) implementation of the file system +type DefaultFileSystem = + /// Create a default implementation of the file system + new: unit -> DefaultFileSystem + abstract AssemblyLoader: IAssemblyLoader + override AssemblyLoader: IAssemblyLoader + + abstract OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream + override OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream + + abstract OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream + override OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream + + abstract GetFullPathShim: fileName: string -> string + override GetFullPathShim: fileName: string -> string + + abstract GetFullFilePathInDirectoryShim: dir: string -> fileName: string -> string + override GetFullFilePathInDirectoryShim: dir: string -> fileName: string -> string + + abstract IsPathRootedShim: path: string -> bool + override IsPathRootedShim: path: string -> bool + + abstract NormalizePathShim: path: string -> string + override NormalizePathShim: path: string -> string + + abstract IsInvalidPathShim: path: string -> bool + override IsInvalidPathShim: path: string -> bool + + abstract GetTempPathShim: unit -> string + override GetTempPathShim: unit -> string + + abstract GetDirectoryNameShim: path: string -> string + override GetDirectoryNameShim: path: string -> string + + abstract GetLastWriteTimeShim: fileName: string -> DateTime + override GetLastWriteTimeShim: fileName: string -> DateTime + + abstract GetCreationTimeShim: path: string -> DateTime + override GetCreationTimeShim: path: string -> DateTime + + abstract CopyShim: src: string * dest: string * overwrite: bool -> unit + override CopyShim: src: string * dest: string * overwrite: bool -> unit + + abstract FileExistsShim: fileName: string -> bool + override FileExistsShim: fileName: string -> bool + + abstract FileDeleteShim: fileName: string -> unit + override FileDeleteShim: fileName: string -> unit + + abstract DirectoryCreateShim: path: string -> DirectoryInfo + override DirectoryCreateShim: path: string -> DirectoryInfo + + abstract DirectoryExistsShim: path: string -> bool + override DirectoryExistsShim: path: string -> bool + + abstract DirectoryDeleteShim: path: string -> unit + override DirectoryDeleteShim: path: string -> unit + + abstract EnumerateFilesShim: path: string * pattern: string -> string seq + override EnumerateFilesShim: path: string * pattern: string -> string seq + + abstract EnumerateDirectoriesShim: path: string -> string seq + override EnumerateDirectoriesShim: path: string -> string seq + + abstract IsStableFileHeuristic: fileName: string -> bool + override IsStableFileHeuristic: fileName: string -> bool + + interface IFileSystem + +[] +module public StreamExtensions = + + type System.IO.Stream with + member GetWriter : ?encoding: Encoding -> TextWriter + member WriteAllLines : contents: string seq * ?encoding: Encoding -> unit + member Write<'a> : data:'a -> unit + member GetReader : codePage: int option * ?retryLocked: bool -> StreamReader + member ReadBytes : start: int * len: int -> byte[] + member ReadAllBytes : unit -> byte[] + member ReadAllText : ?encoding: Encoding -> string + member ReadLines : ?encoding: Encoding -> string seq + member ReadAllLines : ?encoding: Encoding -> string array + member WriteAllText : text: string -> unit + member AsByteMemory : unit -> ByteMemory + +[] +module public FileSystemAutoOpens = + /// The global hook into the file system + val mutable FileSystem: IFileSystem + +type internal ByteMemory with + + member AsReadOnly: unit -> ReadOnlyByteMemory + + /// Empty byte memory. + static member Empty: ByteMemory + + /// Create a ByteMemory object that has a backing memory mapped file. + static member FromMemoryMappedFile: MemoryMappedFile -> ByteMemory + + /// Creates a ByteMemory object that is backed by a raw pointer. + /// Use with care. + static member FromUnsafePointer: addr: nativeint * length: int * holder: obj -> ByteMemory + + /// Creates a ByteMemory object that is backed by a byte array with the specified offset and length. + static member FromArray: bytes: byte[] * offset: int * length: int -> ByteMemory + + /// Creates a ByteMemory object that is backed by a byte array. + static member FromArray: bytes: byte[] -> ByteMemory + +[] +type internal ByteStream = + member ReadByte : unit -> byte + member ReadBytes : int -> ReadOnlyByteMemory + member ReadUtf8String : int -> string + member Position : int + static member FromBytes : ReadOnlyByteMemory * start:int * length:int -> ByteStream + +#if LAZY_UNPICKLE + member CloneAndSeek : int -> ByteStream + member Skip : int -> unit +#endif + +/// Imperative buffers and streams of byte[] +/// Not thread safe. +[] +type internal ByteBuffer = + interface IDisposable + + [] + member AsMemory : unit -> ReadOnlyMemory + + [] + member EmitIntAsByte : int -> unit + + [] + member EmitIntsAsBytes : int[] -> unit + + [] + member EmitByte : byte -> unit + + [] + member EmitBytes : byte[] -> unit + + [] + member EmitMemory : ReadOnlyMemory -> unit + + [] + member EmitByteMemory : ReadOnlyByteMemory -> unit + + [] + member EmitInt32 : int32 -> unit + + [] + member EmitInt64 : int64 -> unit + + [] + member FixupInt32 : pos: int -> value: int32 -> unit + + [] + member EmitInt32AsUInt16 : int32 -> unit + + [] + member EmitBoolAsByte : bool -> unit + + [] + member EmitUInt16 : uint16 -> unit + + member Position : int + static member Create : capacity: int * ?useArrayPool: bool -> ByteBuffer + +[] +type internal ByteStorage = + + member GetByteMemory : unit -> ReadOnlyByteMemory + + /// Creates a ByteStorage whose backing bytes are the given ByteMemory. Does not make a copy. + static member FromByteMemory : ReadOnlyByteMemory -> ByteStorage + + /// Creates a ByteStorage whose backing bytes are the given byte array. Does not make a copy. + static member FromByteArray : byte [] -> ByteStorage + + /// Creates a ByteStorage that has a copy of the given ByteMemory. + static member FromByteMemoryAndCopy : ReadOnlyByteMemory * useBackingMemoryMappedFile: bool -> ByteStorage + + /// Creates a ByteStorage that has a copy of the given Memory. + static member FromMemoryAndCopy : ReadOnlyMemory * useBackingMemoryMappedFile: bool -> ByteStorage + + /// Creates a ByteStorage that has a copy of the given byte array. + static member FromByteArrayAndCopy : byte [] * useBackingMemoryMappedFile: bool -> ByteStorage diff --git a/src/utils/HashMultiMap.fs b/src/fsharp/utils/HashMultiMap.fs similarity index 90% rename from src/utils/HashMultiMap.fs rename to src/fsharp/utils/HashMultiMap.fs index be3740f55d1..70b8238c488 100644 --- a/src/utils/HashMultiMap.fs +++ b/src/fsharp/utils/HashMultiMap.fs @@ -3,22 +3,21 @@ namespace Internal.Utilities.Collections open System.Collections.Generic -open Microsoft.FSharp.Collections // Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_ // one entry. So use two hash tables: one for the main entries and one for the overflow. [] -type internal HashMultiMap<'Key,'Value>(n: int, hashEq: IEqualityComparer<'Key>) = +type internal HashMultiMap<'Key,'Value>(size: int, comparer: IEqualityComparer<'Key>) = - let firstEntries = Dictionary<_,_>(n,hashEq) + let firstEntries = Dictionary<_,_>(size,comparer) - let rest = Dictionary<_,_>(3,hashEq) + let rest = Dictionary<_,_>(3,comparer) - new (hashEq : IEqualityComparer<'Key>) = HashMultiMap<'Key,'Value>(11, hashEq) + new (comparer : IEqualityComparer<'Key>) = HashMultiMap<'Key,'Value>(11, comparer) - new (seq : seq<'Key * 'Value>, hashEq : IEqualityComparer<'Key>) as x = - new HashMultiMap<'Key,'Value>(11, hashEq) - then seq |> Seq.iter (fun (k,v) -> x.Add(k,v)) + new (entries : seq<'Key * 'Value>, comparer : IEqualityComparer<'Key>) as x = + new HashMultiMap<'Key,'Value>(11, comparer) + then entries |> Seq.iter (fun (k,v) -> x.Add(k,v)) member x.GetRest(k) = match rest.TryGetValue k with @@ -97,7 +96,7 @@ type internal HashMultiMap<'Key,'Value>(n: int, hashEq: IEqualityComparer<'Key>) | [h] -> firstEntries.[y] <- h; rest.Remove(y) |> ignore - | (h :: t) -> + | h :: t -> firstEntries.[y] <- h rest.[y] <- t | _ -> diff --git a/src/utils/HashMultiMap.fsi b/src/fsharp/utils/HashMultiMap.fsi similarity index 99% rename from src/utils/HashMultiMap.fsi rename to src/fsharp/utils/HashMultiMap.fsi index bd05cfc1d7a..0d2738f955f 100644 --- a/src/utils/HashMultiMap.fsi +++ b/src/fsharp/utils/HashMultiMap.fsi @@ -2,10 +2,8 @@ namespace Internal.Utilities.Collections -open System open System.Collections.Generic - /// Hash tables, by default based on F# structural "hash" and (=) functions. /// The table may map a single key to multiple bindings. [] diff --git a/src/utils/PathMap.fs b/src/fsharp/utils/PathMap.fs similarity index 96% rename from src/utils/PathMap.fs rename to src/fsharp/utils/PathMap.fs index 3e4f6fad96c..906c3831e6d 100644 --- a/src/utils/PathMap.fs +++ b/src/fsharp/utils/PathMap.fs @@ -6,6 +6,8 @@ namespace Internal.Utilities open System open System.IO +open FSharp.Compiler.IO + type PathMap = PathMap of Map [] @@ -17,7 +19,7 @@ module internal PathMap = let addMapping (src : string) (dst : string) (PathMap map) : PathMap = // Normalise the path - let normalSrc = Path.GetFullPath src + let normalSrc = FileSystem.GetFullPathShim src let oldPrefix = if normalSrc.EndsWith dirSepStr then normalSrc diff --git a/src/utils/PathMap.fsi b/src/fsharp/utils/PathMap.fsi similarity index 96% rename from src/utils/PathMap.fsi rename to src/fsharp/utils/PathMap.fsi index 8cf4e2f2485..061b623c53d 100644 --- a/src/utils/PathMap.fsi +++ b/src/fsharp/utils/PathMap.fsi @@ -3,7 +3,7 @@ /// Functions to map real paths to paths to be written to PDB/IL namespace Internal.Utilities -type PathMap +type internal PathMap [] module internal PathMap = diff --git a/src/utils/ResizeArray.fs b/src/fsharp/utils/ResizeArray.fs similarity index 89% rename from src/utils/ResizeArray.fs rename to src/fsharp/utils/ResizeArray.fs index 597f37d16b1..2525f707f45 100644 --- a/src/utils/ResizeArray.fs +++ b/src/fsharp/utils/ResizeArray.fs @@ -2,9 +2,7 @@ namespace Internal.Utilities -open Microsoft.FSharp.Core -open Microsoft.FSharp.Core.OptimizedClosures - +open FSharp.Core.OptimizedClosures [] module internal ResizeArray = @@ -15,9 +13,9 @@ module internal ResizeArray = let set (arr: ResizeArray<'T>) (n: int) (x:'T) = arr.[n] <- x - let create (n: int) x = new ResizeArray<_> (seq { for _ in 1 .. n -> x }) + let create (n: int) x = ResizeArray<_>(seq { for _ in 1 .. n -> x }) - let init (n: int) (f: int -> 'T) = new ResizeArray<_> (seq { for i in 0 .. n-1 -> f i }) + let init (n: int) (f: int -> 'T) = ResizeArray<_>(seq { for i in 0 .. n-1 -> f i }) let blit (arr1: ResizeArray<'T>) start1 (arr2: ResizeArray<'T>) start2 len = if start1 < 0 then invalidArg "start1" "index must be positive" @@ -28,7 +26,7 @@ module internal ResizeArray = for i = 0 to len - 1 do arr2.[start2+i] <- arr1.[start1 + i] - let concat (arrs: ResizeArray<'T> list) = new ResizeArray<_> (seq { for arr in arrs do for x in arr do yield x }) + let concat (arrs: ResizeArray<'T> list) = ResizeArray<_>(seq { for arr in arrs do for x in arr do yield x }) let append (arr1: ResizeArray<'T>) (arr2: ResizeArray<'T>) = concat [arr1; arr2] @@ -36,7 +34,7 @@ module internal ResizeArray = if start < 0 then invalidArg "start" "index must be positive" if len < 0 then invalidArg "len" "length must be positive" if start + len > length arr then invalidArg "len" "length must be positive" - new ResizeArray<_> (seq { for i in start .. start+len-1 -> arr.[i] }) + ResizeArray<_>(seq { for i in start .. start+len-1 -> arr.[i] }) let fill (arr: ResizeArray<'T>) (start: int) (len: int) (x:'T) = if start < 0 then invalidArg "start" "index must be positive" @@ -45,7 +43,7 @@ module internal ResizeArray = for i = start to start + len - 1 do arr.[i] <- x - let copy (arr: ResizeArray<'T>) = new ResizeArray<_>(arr) + let copy (arr: ResizeArray<'T>) = ResizeArray<_>(arr) let toList (arr: ResizeArray<_>) = let mutable res = [] @@ -55,7 +53,7 @@ module internal ResizeArray = let ofList (l: _ list) = let len = l.Length - let res = new ResizeArray<_>(len) + let res = ResizeArray<_>(len) let rec add = function | [] -> () | e :: l -> res.Add(e); add l @@ -68,7 +66,7 @@ module internal ResizeArray = let map f (arr: ResizeArray<_>) = let len = length arr - let res = new ResizeArray<_>(len) + let res = ResizeArray<_>(len) for i = 0 to len - 1 do res.Add(f arr.[i]) res @@ -76,7 +74,7 @@ module internal ResizeArray = let mapi f (arr: ResizeArray<_>) = let f = FSharpFunc<_,_,_>.Adapt(f) let len = length arr - let res = new ResizeArray<_>(len) + let res = ResizeArray<_>(len) for i = 0 to len - 1 do res.Add(f.Invoke(i, arr.[i])) res @@ -96,7 +94,7 @@ module internal ResizeArray = let rec loop i = i >= len || (f arr.[i] && loop (i+1)) loop 0 - let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection")) + let indexNotFound() = raise (System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection")) let find f (arr: ResizeArray<_>) = let rec loop i = @@ -131,13 +129,13 @@ module internal ResizeArray = let f = FSharpFunc<_,_,_>.Adapt(f) let len1 = length arr1 if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths" - let res = new ResizeArray<_>(len1) + let res = ResizeArray<_>(len1) for i = 0 to len1 - 1 do res.Add(f.Invoke(arr1.[i], arr2.[i])) res let choose f (arr: ResizeArray<_>) = - let res = new ResizeArray<_>() + let res = ResizeArray<_>() for i = 0 to length arr - 1 do match f arr.[i] with | None -> () @@ -145,15 +143,15 @@ module internal ResizeArray = res let filter f (arr: ResizeArray<_>) = - let res = new ResizeArray<_>() + let res = ResizeArray<_>() for i = 0 to length arr - 1 do let x = arr.[i] if f x then res.Add(x) res let partition f (arr: ResizeArray<_>) = - let res1 = new ResizeArray<_>() - let res2 = new ResizeArray<_>() + let res1 = ResizeArray<_>() + let res2 = ResizeArray<_>() for i = 0 to length arr - 1 do let x = arr.[i] if f x then res1.Add(x) else res2.Add(x) @@ -161,7 +159,7 @@ module internal ResizeArray = let rev (arr: ResizeArray<_>) = let len = length arr - let res = new ResizeArray<_>(len) + let res = ResizeArray<_>(len) for i = len - 1 downto 0 do res.Add(arr.[i]) res @@ -182,7 +180,7 @@ module internal ResizeArray = let toArray (arr: ResizeArray<'T>) = arr.ToArray() - let ofArray (arr: 'T[]) = new ResizeArray<_>(arr) + let ofArray (arr: 'T[]) = ResizeArray<_>(arr) let toSeq (arr: ResizeArray<'T>) = Seq.readonly arr @@ -293,7 +291,7 @@ module internal ResizeArray = scanBackSub f arr 0 (arrn - 1) acc let singleton x = - let res = new ResizeArray<_>(1) + let res = ResizeArray<_>(1) res.Add(x) res @@ -312,8 +310,8 @@ module internal ResizeArray = let unzip (arr: ResizeArray<_>) = let len = length arr - let res1 = new ResizeArray<_>(len) - let res2 = new ResizeArray<_>(len) + let res1 = ResizeArray<_>(len) + let res2 = ResizeArray<_>(len) for i = 0 to len - 1 do let x,y = arr.[i] res1.Add(x) diff --git a/src/utils/ResizeArray.fsi b/src/fsharp/utils/ResizeArray.fsi similarity index 99% rename from src/utils/ResizeArray.fsi rename to src/fsharp/utils/ResizeArray.fsi index 55eb7afddc5..cdc216aaab9 100644 --- a/src/utils/ResizeArray.fsi +++ b/src/fsharp/utils/ResizeArray.fsi @@ -2,12 +2,6 @@ namespace Internal.Utilities - -open System -open System.Collections.Generic -open Microsoft.FSharp.Core -open Microsoft.FSharp.Collections - [] /// Generic operations on the type System.Collections.Generic.List, which is called ResizeArray in the F# libraries. module internal ResizeArray = diff --git a/src/fsharp/utils/RidHelpers.fs b/src/fsharp/utils/RidHelpers.fs new file mode 100644 index 00000000000..3101bc5d960 --- /dev/null +++ b/src/fsharp/utils/RidHelpers.fs @@ -0,0 +1,23 @@ +namespace Internal.Utilities + +open System.Runtime.InteropServices + +module internal RidHelpers = + + // Computer valid dotnet-rids for this environment: + // https://docs.microsoft.com/en-us/dotnet/core/rid-catalog + // + // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... + let probingRids, baseRid, platformRid = + let processArchitecture = RuntimeInformation.ProcessArchitecture + let baseRid = + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then "win" + elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then "osx" + else "linux" + let platformRid = + match processArchitecture with + | Architecture.X64 -> baseRid + "-x64" + | Architecture.X86 -> baseRid + "-x86" + | Architecture.Arm64 -> baseRid + "-arm64" + | _ -> baseRid + "-arm" + [| "any"; baseRid; platformRid |], baseRid, platformRid diff --git a/src/fsharp/utils/TaggedCollections.fs b/src/fsharp/utils/TaggedCollections.fs new file mode 100644 index 00000000000..fc3d601a552 --- /dev/null +++ b/src/fsharp/utils/TaggedCollections.fs @@ -0,0 +1,1081 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Internal.Utilities.Collections.Tagged + + #nowarn "51" + #nowarn "69" // interface implementations in augmentations + #nowarn "60" // override implementations in augmentations + + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open System.Collections.Generic + + [] + [] + type internal SetTree<'T>(k: 'T) = + member _.Key = k + + [] + [] + [] + type internal SetTreeNode<'T>(v:'T, left:SetTree<'T>, right: SetTree<'T>, h: int) = + inherit SetTree<'T>(v) + + member _.Left = left + member _.Right = right + member _.Height = h + + [] + module SetTree = + let empty = null + + let inline isEmpty (t:SetTree<'T>) = isNull t + + let rec countAux (t:SetTree<'T>) acc = + if isEmpty t then + acc + else + match t with + | :? SetTreeNode<'T> as tn -> countAux tn.Left (countAux tn.Right (acc+1)) + | _ -> acc+1 + + let count s = countAux s 0 + + let inline height (t:SetTree<'T>) = + if isEmpty t then 0 + else + match t with + | :? SetTreeNode<'T> as tn -> tn.Height + | _ -> 1 + + [] + let tolerance = 2 + + let mk l k r : SetTree<'T> = + let hl = height l + let hr = height r + let m = if hl < hr then hr else hl + if m = 0 then // m=0 ~ isEmpty l && isEmpty r + SetTree k + else + SetTreeNode (k, l, r, m+1) :> SetTree<'T> + + let inline private asNode(value:SetTree<'T>) : SetTreeNode<'T> = + value :?> SetTreeNode<'T> + + let rebalance t1 v t2 = + let t1h = height t1 + let t2h = height t2 + if t2h > t1h + tolerance then // right is heavier than left + let t2' = asNode(t2) + // one of the nodes must have height > height t1 + 1 + if height t2'.Left > t1h + 1 then // balance left: combination + let t2l = asNode(t2'.Left) + mk (mk t1 v t2l.Left) t2l.Key (mk t2l.Right t2'.Key t2'.Right) + else // rotate left + mk (mk t1 v t2'.Left) t2.Key t2'.Right + else + if t1h > t2h + tolerance then // left is heavier than right + let t1' = asNode(t1) + // one of the nodes must have height > height t2 + 1 + if height t1'.Right > t2h + 1 then + // balance right: combination + let t1r = asNode(t1'.Right) + mk (mk t1'.Left t1.Key t1r.Left) t1r.Key (mk t1r.Right v t2) + else + mk t1'.Left t1'.Key (mk t1'.Right v t2) + else mk t1 v t2 + + let rec add (comparer: IComparer<'T>) k (t:SetTree<'T>) : SetTree<'T> = + if isEmpty t then SetTree k + else + let c = comparer.Compare(k, t.Key) + match t with + | :? SetTreeNode<'T> as tn -> + if c < 0 then rebalance (add comparer k tn.Left) tn.Key tn.Right + elif c = 0 then t + else rebalance tn.Left tn.Key (add comparer k tn.Right) + | _ -> + // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated + let c = comparer.Compare(k, t.Key) + if c < 0 then SetTreeNode (k, empty, t, 2) :> SetTree<'T> + elif c = 0 then t + else SetTreeNode (k, t, empty, 2) :> SetTree<'T> + + let rec balance comparer (t1:SetTree<'T>) k (t2:SetTree<'T>) = + // Given t1 < k < t2 where t1 and t2 are "balanced", + // return a balanced tree for . + // Recall: balance means subtrees heights differ by at most "tolerance" + if isEmpty t1 then add comparer k t2 // drop t1 = empty + elif isEmpty t2 then add comparer k t1 // drop t2 = empty + else + match t1 with + | :? SetTreeNode<'T> as t1n -> + match t2 with + | :? SetTreeNode<'T> as t2n -> + // Have: (t1l < k1 < t1r) < k < (t2l < k2 < t2r) + // Either (a) h1, h2 differ by at most 2 - no rebalance needed. + // (b) h1 too small, i.e. h1+2 < h2 + // (c) h2 too small, i.e. h2+2 < h1 + if t1n.Height + tolerance < t2n.Height then + // case: b, h1 too small + // push t1 into low side of t2, may increase height by 1 so rebalance + rebalance (balance comparer t1 k t2n.Left) t2n.Key t2n.Right + elif t2n.Height + tolerance < t1n.Height then + // case: c, h2 too small + // push t2 into high side of t1, may increase height by 1 so rebalance + rebalance t1n.Left t1n.Key (balance comparer t1n.Right k t2) + else + // case: a, h1 and h2 meet balance requirement + mk t1 k t2 + | _ -> add comparer k (add comparer t2.Key t1) + | _ -> add comparer k (add comparer t1.Key t2) + + let rec split (comparer: IComparer<'T>) pivot (t:SetTree<'T>) = + // Given a pivot and a set t + // Return { x in t s.t. x < pivot }, pivot in t?, { x in t s.t. x > pivot } + if isEmpty t then empty, false, empty + else + match t with + | :? SetTreeNode<'T> as tn -> + let c = comparer.Compare(pivot, tn.Key) + if c < 0 then // pivot t1 + let t11Lo, havePivot, t11Hi = split comparer pivot tn.Left + t11Lo, havePivot, balance comparer t11Hi tn.Key tn.Right + elif c = 0 then // pivot is k1 + tn.Left, true, tn.Right + else // pivot t2 + let t12Lo, havePivot, t12Hi = split comparer pivot tn.Right + balance comparer tn.Left tn.Key t12Lo, havePivot, t12Hi + | _ -> + let c = comparer.Compare(t.Key, pivot) + if c < 0 then t, false, empty // singleton under pivot + elif c = 0 then empty, true, empty // singleton is pivot + else empty, false, t // singleton over pivot + + let rec spliceOutSuccessor (t:SetTree<'T>) = + if isEmpty t then failwith "internal error: Set.spliceOutSuccessor" + else + match t with + | :? SetTreeNode<'T> as tn -> + if isEmpty tn.Left then tn.Key, tn.Right + else let k3, l' = spliceOutSuccessor tn.Left in k3, mk l' tn.Key tn.Right + | _ -> t.Key, empty + + let rec remove (comparer: IComparer<'T>) k (t:SetTree<'T>) = + if isEmpty t then t + else + let c = comparer.Compare(k, t.Key) + match t with + | :? SetTreeNode<'T> as tn -> + if c < 0 then rebalance (remove comparer k tn.Left) tn.Key tn.Right + elif c = 0 then + if isEmpty tn.Left then tn.Right + elif isEmpty tn.Right then tn.Left + else + let sk, r' = spliceOutSuccessor tn.Right + mk tn.Left sk r' + else rebalance tn.Left tn.Key (remove comparer k tn.Right) + | _ -> + if c = 0 then empty + else t + + let rec contains (comparer: IComparer<'T>) k (t:SetTree<'T>) = + if isEmpty t then false + else + let c = comparer.Compare(k, t.Key) + match t with + | :? SetTreeNode<'T> as tn -> + if c < 0 then contains comparer k tn.Left + elif c = 0 then true + else contains comparer k tn.Right + | _ -> (c = 0) + + let rec iter f (t:SetTree<'T>) = + if isEmpty t then () + else + match t with + | :? SetTreeNode<'T> as tn -> iter f tn.Left; f tn.Key; iter f tn.Right + | _ -> f t.Key + + // Fold, left-to-right. + // + // NOTE: This differs from the behaviour of Map.fold which folds right-to-left. + let rec fold f (t:SetTree<'T>) x = + if isEmpty t then x + else + match t with + | :? SetTreeNode<'T> as tn -> fold f tn.Right (f tn.Key (fold f tn.Left x)) + | _ -> f t.Key x + + let rec forall f (t:SetTree<'T>) = + if isEmpty t then true + else + match t with + | :? SetTreeNode<'T> as tn -> f tn.Key && forall f tn.Left && forall f tn.Right + | _ -> f t.Key + + let rec exists f (t:SetTree<'T>) = + if isEmpty t then false + else + match t with + | :? SetTreeNode<'T> as tn -> f tn.Key || exists f tn.Left || exists f tn.Right + | _ -> f t.Key + + let subset comparer a b = + forall (fun x -> contains comparer x b) a + + let rec filterAux comparer f (t:SetTree<'T>) acc = + if isEmpty t then acc + else + match t with + | :? SetTreeNode<'T> as tn -> + let acc = if f tn.Key then add comparer tn.Key acc else acc + filterAux comparer f tn.Left (filterAux comparer f tn.Right acc) + | _ -> if f t.Key then add comparer t.Key acc else acc + + let filter comparer f s = filterAux comparer f s empty + + let rec diffAux comparer (t:SetTree<'T>) acc = + if isEmpty acc then acc + else + if isEmpty t then acc + else + match t with + | :? SetTreeNode<'T> as tn -> diffAux comparer tn.Left (diffAux comparer tn.Right (remove comparer tn.Key acc)) + | _ -> remove comparer t.Key acc + + let diff comparer a b = diffAux comparer b a + + let rec union comparer (t1:SetTree<'T>) (t2:SetTree<'T>) = + // Perf: tried bruteForce for low heights, but nothing significant + if isEmpty t1 then t2 + elif isEmpty t2 then t1 + else + match t1 with + | :? SetTreeNode<'T> as t1n -> + match t2 with + | :? SetTreeNode<'T> as t2n -> // (t1l < k < t1r) AND (t2l < k2 < t2r) + // Divide and Conquer: + // Suppose t1 is largest. + // Split t2 using pivot k1 into lo and hi. + // Union disjoint subproblems and then combine. + if t1n.Height > t2n.Height then + let lo, _, hi = split comparer t1n.Key t2 in + balance comparer (union comparer t1n.Left lo) t1n.Key (union comparer t1n.Right hi) + else + let lo, _, hi = split comparer t2n.Key t1 in + balance comparer (union comparer t2n.Left lo) t2n.Key (union comparer t2n.Right hi) + | _ -> add comparer t2.Key t1 + | _ -> add comparer t1.Key t2 + + let rec intersectionAux comparer b (t:SetTree<'T>) acc = + if isEmpty t then acc + else + match t with + | :? SetTreeNode<'T> as tn -> + let acc = intersectionAux comparer b tn.Right acc + let acc = if contains comparer tn.Key b then add comparer tn.Key acc else acc + intersectionAux comparer b tn.Left acc + | _ -> + if contains comparer t.Key b then add comparer t.Key acc else acc + + let intersection comparer a b = intersectionAux comparer b a empty + + let partition1 comparer f k (acc1, acc2) = if f k then (add comparer k acc1, acc2) else (acc1, add comparer k acc2) + + let rec partitionAux comparer f (t:SetTree<'T>) acc = + if isEmpty t then acc + else + match t with + | :? SetTreeNode<'T> as tn -> + let acc = partitionAux comparer f tn.Right acc + let acc = partition1 comparer f tn.Key acc + partitionAux comparer f tn.Left acc + | _ -> partition1 comparer f t.Key acc + + let partition comparer f s = partitionAux comparer f s (empty, empty) + + let rec minimumElementAux (t:SetTree<'T>) n = + if isEmpty t then n + else + match t with + | :? SetTreeNode<'T> as tn -> minimumElementAux tn.Left tn.Key + | _ -> t.Key + + and minimumElementOpt (t:SetTree<'T>) = + if isEmpty t then None + else + match t with + | :? SetTreeNode<'T> as tn -> Some(minimumElementAux tn.Left tn.Key) + | _ -> Some t.Key + + and maximumElementAux (t:SetTree<'T>) n = + if isEmpty t then n + else + match t with + | :? SetTreeNode<'T> as tn -> maximumElementAux tn.Right tn.Key + | _ -> t.Key + + and maximumElementOpt (t:SetTree<'T>) = + if isEmpty t then None + else + match t with + | :? SetTreeNode<'T> as tn -> Some(maximumElementAux tn.Right tn.Key) + | _ -> Some t.Key + + let minimumElement s = + match minimumElementOpt s with + | Some(k) -> k + | None -> failwith "minimumElement" + + let maximumElement s = + match maximumElementOpt s with + | Some(k) -> k + | None -> failwith "maximumElement" + + //-------------------------------------------------------------------------- + // Imperative left-to-right iterators. + //-------------------------------------------------------------------------- + + type SetIterator<'T>(s:SetTree<'T>) = + + // collapseLHS: + // a) Always returns either [] or a list starting with SetOne. + // b) The "fringe" of the set stack is unchanged. + let rec collapseLHS (stack: SetTree<'T> list) = + match stack with + | [] -> [] + | x :: rest -> + if isEmpty x then collapseLHS rest + else + match x with + | :? SetTreeNode<'T> as xn-> collapseLHS (xn.Left :: SetTree xn.Key :: xn.Right :: rest) + | _ -> stack + + // invariant: always collapseLHS result + let mutable stack = collapseLHS [s] + // true when MoveNext has been called + let mutable started = false + + let notStarted() = raise (System.InvalidOperationException("Enumeration has not started. Call MoveNext.")) + let alreadyFinished() = raise (System.InvalidOperationException("Enumeration already finished.")) + + member _.Current = + if started then + match stack with + | k :: _ -> k.Key + | [] -> alreadyFinished() + else + notStarted() + + member _.MoveNext() = + if started then + match stack with + | [] -> false + | t :: rest -> + match t with + | :? SetTreeNode<'T> -> failwith "Please report error: Set iterator, unexpected stack for moveNext" + | _ -> + stack <- collapseLHS rest + not stack.IsEmpty + else + started <- true; // The first call to MoveNext "starts" the enumeration. + not stack.IsEmpty + + let toSeq s = + let mutable i = SetIterator s + { new IEnumerator<_> with + member _.Current = i.Current + interface System.Collections.IEnumerator with + member _.Current = box i.Current + member _.MoveNext() = i.MoveNext() + member _.Reset() = i <- SetIterator s + interface System.IDisposable with + member _.Dispose() = () } + + //-------------------------------------------------------------------------- + // Set comparison. This can be expensive. + //-------------------------------------------------------------------------- + + let rec compareStacks (comparer: IComparer<'T>) (l1:SetTree<'T> list) (l2:SetTree<'T> list) : int = + let cont() = + match l1, l2 with + | x1 :: t1, _ when not (isEmpty x1) -> + match x1 with + | :? SetTreeNode<'T> as x1n -> + compareStacks comparer (x1n.Left :: (SetTreeNode (x1n.Key, empty, x1n.Right, 0) :> SetTree<'T>) :: t1) l2 + | _ -> compareStacks comparer (empty :: SetTree x1.Key :: t1) l2 + | _, x2 :: t2 when not (isEmpty x2) -> + match x2 with + | :? SetTreeNode<'T> as x2n -> + compareStacks comparer l1 (x2n.Left :: (SetTreeNode (x2n.Key, empty, x2n.Right, 0) :> SetTree<'T> ) :: t2) + | _ -> compareStacks comparer l1 (empty :: SetTree x2.Key :: t2) + | _ -> failwith "unexpected state in SetTree.compareStacks" + + match l1, l2 with + | [], [] -> 0 + | [], _ -> -1 + | _, [] -> 1 + | x1 :: t1, x2 :: t2 -> + if isEmpty x1 then + if isEmpty x2 then compareStacks comparer t1 t2 + else cont() + elif isEmpty x2 then cont() + else + match x1 with + | :? SetTreeNode<'T> as x1n -> + if isEmpty x1n.Left then + match x2 with + | :? SetTreeNode<'T> as x2n -> + if isEmpty x2n.Left then + let c = comparer.Compare(x1n.Key, x2n.Key) + if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (x2n.Right :: t2) + else cont() + | _ -> + let c = comparer.Compare(x1n.Key, x2.Key) + if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (empty :: t2) + else cont() + | _ -> + match x2 with + | :? SetTreeNode<'T> as x2n -> + if isEmpty x2n.Left then + let c = comparer.Compare(x1.Key, x2n.Key) + if c <> 0 then c else compareStacks comparer (empty :: t1) (x2n.Right :: t2) + else cont() + | _ -> + let c = comparer.Compare(x1.Key, x2.Key) + if c <> 0 then c else compareStacks comparer t1 t2 + + let compare comparer (t1:SetTree<'T>) (t2:SetTree<'T>) = + if isEmpty t1 then + if isEmpty t2 then 0 + else -1 + else + if isEmpty t2 then 1 + else compareStacks comparer [t1] [t2] + + let choose s = minimumElement s + + let toList (t:SetTree<'T>) = + let rec loop (t':SetTree<'T>) acc = + if isEmpty t' then acc + else + match t' with + | :? SetTreeNode<'T> as tn -> loop tn.Left (tn.Key :: loop tn.Right acc) + | _ -> t'.Key :: acc + loop t [] + + let copyToArray s (arr: _[]) i = + let mutable j = i + iter (fun x -> arr.[j] <- x; j <- j + 1) s + + let toArray s = + let n = (count s) + let res = Array.zeroCreate n + copyToArray s res 0; + res + + let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = + if e.MoveNext() then + mkFromEnumerator comparer (add comparer e.Current acc) e + else acc + + let ofSeq comparer (c : IEnumerable<_>) = + use ie = c.GetEnumerator() + mkFromEnumerator comparer empty ie + + let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) empty l + + + [] + [] + type internal Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T>(comparer: IComparer<'T>, tree: SetTree<'T>) = + + static let refresh (s:Set<_,_>) t = Set<_,_>(comparer=s.Comparer, tree=t) + + member s.Tree = tree + member s.Comparer : IComparer<'T> = comparer + + static member Empty(comparer: 'ComparerTag) : Set<'T,'ComparerTag> = + Set<_,_>(comparer=comparer, tree=SetTree.empty) + + + member s.Add(x) : Set<'T,'ComparerTag> = refresh s (SetTree.add comparer x tree) + member s.Remove(x) : Set<'T,'ComparerTag> = refresh s (SetTree.remove comparer x tree) + member s.Count = SetTree.count tree + member s.Contains(x) = SetTree.contains comparer x tree + member s.Iterate(x) = SetTree.iter x tree + member s.Fold f x = SetTree.fold f tree x + member s.IsEmpty = SetTree.isEmpty tree + + member s.Partition predicate : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> = + if SetTree.isEmpty s.Tree then s,s + else + let t1, t2 = SetTree.partition s.Comparer predicate s.Tree + refresh s t1, refresh s t2 + + member s.Filter predicate : Set<'T,'ComparerTag> = + if SetTree.isEmpty s.Tree then s + else + SetTree.filter comparer predicate tree |> refresh s + + member s.Exists predicate = SetTree.exists predicate tree + + member s.ForAll predicate = SetTree.forall predicate tree + + static member (-) (a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = Set<_,_>.Difference(a,b) + + static member (+) (a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = Set<_,_>.Union(a,b) + + static member Intersection(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag> = + if SetTree.isEmpty b.Tree then b (* A INTER 0 = 0 *) + else + if SetTree.isEmpty a.Tree then a (* 0 INTER B = 0 *) + else SetTree.intersection a.Comparer a.Tree b.Tree |> refresh a + + static member Union(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag> = + if SetTree.isEmpty b.Tree then a (* A U 0 = A *) + else + if SetTree.isEmpty a.Tree then b (* 0 U B = B *) + else SetTree.union a.Comparer a.Tree b.Tree |> refresh a + + static member Difference(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag> = + if SetTree.isEmpty a.Tree then a (* 0 - B = 0 *) + else + if SetTree.isEmpty b.Tree then a (* A - 0 = A *) + else SetTree.diff a.Comparer a.Tree b.Tree |> refresh a + + static member Equality(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = + (SetTree.compare a.Comparer a.Tree b.Tree = 0) + + static member Compare(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = + SetTree.compare a.Comparer a.Tree b.Tree + + member s.Choose = SetTree.choose tree + + member s.MinimumElement = SetTree.minimumElement tree + + member s.MaximumElement = SetTree.maximumElement tree + + member s.IsSubsetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer tree y.Tree + + member s.IsSupersetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer y.Tree tree + + member s.ToList () = SetTree.toList tree + + member s.ToArray () = SetTree.toArray tree + + override this.Equals(that) = + match that with + // Cast to the exact same type as this, otherwise not equal. + | :? Set<'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0) + | _ -> false + + interface System.IComparable with + // Cast s2 to the exact same type as s1, see 4884. + // It is not OK to cast s2 to seq<'T>, since different compares could permute the elements. + member s1.CompareTo(s2: obj) = SetTree.compare s1.Comparer s1.Tree (s2 :?> Set<'T,'ComparerTag>).Tree + + member this.ComputeHashCode() = + let combineHash x y = (x <<< 1) + y + 631 + let mutable res = 0 + for x in this do + res <- combineHash res (Unchecked.hash x) + res + + override this.GetHashCode() = this.ComputeHashCode() + + interface ICollection<'T> with + member s.Add _ = raise (System.NotSupportedException("ReadOnlyCollection")) + member s.Clear() = raise (System.NotSupportedException("ReadOnlyCollection")) + member s.Remove _ = raise (System.NotSupportedException("ReadOnlyCollection")) + member s.Contains(x) = SetTree.contains comparer x tree + member s.CopyTo(arr,i) = SetTree.copyToArray tree arr i + member s.IsReadOnly = true + member s.Count = SetTree.count tree + + interface IEnumerable<'T> with + member s.GetEnumerator() = SetTree.toSeq tree + + interface System.Collections.IEnumerable with + override s.GetEnumerator() = (SetTree.toSeq tree :> System.Collections.IEnumerator) + + static member Singleton(comparer,x) : Set<'T,'ComparerTag> = + Set<_,_>.Empty(comparer).Add(x) + + static member Create(comparer : 'ComparerTag,l : seq<'T>) : Set<'T,'ComparerTag> = + Set<_,_>(comparer=comparer, tree=SetTree.ofSeq comparer l) + + + [] + [] + type internal MapTree<'Key, 'Value>(k: 'Key, v: 'Value) = + member _.Key = k + member _.Value = v + + [] + [] + [] + type internal MapTreeNode<'Key, 'Value>(k:'Key, v:'Value, left:MapTree<'Key, 'Value>, right: MapTree<'Key, 'Value>, h: int) = + inherit MapTree<'Key,'Value>(k, v) + + member _.Left = left + member _.Right = right + member _.Height = h + + + [] + module MapTree = + + let empty = null + + let inline isEmpty (m:MapTree<'Key, 'Value>) = isNull m + + let rec sizeAux acc (m:MapTree<'Key, 'Value>) = + if isEmpty m then + acc + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> sizeAux (sizeAux (acc+1) mn.Left) mn.Right + | _ -> acc + 1 + + let size x = sizeAux 0 x + + let inline height (m: MapTree<'Key, 'Value>) = + if isEmpty m then 0 + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> mn.Height + | _ -> 1 + + let mk l k v r : MapTree<'Key, 'Value> = + let hl = height l + let hr = height r + let m = max hl hr + if m = 0 then // m=0 ~ isEmpty l && isEmpty r + MapTree(k,v) + else + MapTreeNode(k,v,l,r,m+1) :> MapTree<'Key, 'Value> + + let inline private asNode(value:MapTree<'Key,'Value>) : MapTreeNode<'Key,'Value> = + value :?> MapTreeNode<'Key,'Value> + + let rebalance t1 (k: 'Key) (v: 'Value) t2 : MapTree<'Key, 'Value> = + let t1h = height t1 + let t2h = height t2 + if t2h > t1h + 2 then (* right is heavier than left *) + let t2' = asNode(t2) + (* one of the nodes must have height > height t1 + 1 *) + if height t2'.Left > t1h + 1 then (* balance left: combination *) + let t2l = asNode(t2'.Left) + mk (mk t1 k v t2l.Left) t2l.Key t2l.Value (mk t2l.Right t2'.Key t2'.Value t2'.Right) + else (* rotate left *) + mk (mk t1 k v t2'.Left) t2'.Key t2'.Value t2'.Right + else + if t1h > t2h + 2 then (* left is heavier than right *) + let t1' = asNode(t1) + (* one of the nodes must have height > height t2 + 1 *) + if height t1'.Right > t2h + 1 then + (* balance right: combination *) + let t1r = asNode(t1'.Right) + mk (mk t1'.Left t1'.Key t1'.Value t1r.Left) t1r.Key t1r.Value (mk t1r.Right k v t2) + else + mk t1'.Left t1'.Key t1'.Value (mk t1'.Right k v t2) + else mk t1 k v t2 + + + let rec add (comparer: IComparer<'Key>) k (v: 'Value) (m: MapTree<'Key, 'Value>) : MapTree<'Key, 'Value> = + if isEmpty m then MapTree(k,v) + else + let c = comparer.Compare(k,m.Key) + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + if c < 0 then rebalance (add comparer k v mn.Left) mn.Key mn.Value mn.Right + elif c = 0 then MapTreeNode(k,v,mn.Left,mn.Right,mn.Height) :> MapTree<'Key, 'Value> + else rebalance mn.Left mn.Key mn.Value (add comparer k v mn.Right) + | _ -> + if c < 0 then MapTreeNode (k,v,empty,m,2) :> MapTree<'Key, 'Value> + elif c = 0 then MapTree(k,v) + else MapTreeNode (k,v,m,empty,2) :> MapTree<'Key, 'Value> + + let indexNotFound() = raise (KeyNotFoundException("An index satisfying the predicate was not found in the collection")) + + let rec tryGetValue (comparer: IComparer<'Key>) k (v: byref<'Value>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then false + else + let c = comparer.Compare(k, m.Key) + if c = 0 then v <- m.Value; true + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + tryGetValue comparer k &v (if c < 0 then mn.Left else mn.Right) + | _ -> false + + let find (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + let mutable v = Unchecked.defaultof<'Value> + if tryGetValue comparer k &v m then + v + else + indexNotFound() + + let tryFind (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + let mutable v = Unchecked.defaultof<'Value> + if tryGetValue comparer k &v m then + Some v + else + None + + let partition1 (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) k v (acc1, acc2) = + if f.Invoke (k, v) then (add comparer k v acc1, acc2) else (acc1, add comparer k v acc2) + + let rec partitionAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) acc = + if isEmpty m then acc + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let acc = partitionAux comparer f mn.Right acc + let acc = partition1 comparer f mn.Key mn.Value acc + partitionAux comparer f mn.Left acc + | _ -> partition1 comparer f m.Key m.Value acc + + let partition (comparer: IComparer<'Key>) f m = + partitionAux comparer (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m (empty, empty) + + let filter1 (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) k v acc = + if f.Invoke (k, v) then add comparer k v acc else acc + + let rec filterAux (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) acc = + if isEmpty m then acc + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let acc = filterAux comparer f mn.Left acc + let acc = filter1 comparer f mn.Key mn.Value acc + filterAux comparer f mn.Right acc + | _ -> filter1 comparer f m.Key m.Value acc + + let filter (comparer: IComparer<'Key>) f m = + filterAux comparer (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m empty + + let rec spliceOutSuccessor (m: MapTree<'Key, 'Value>) = + if isEmpty m then failwith "internal error: Map.spliceOutSuccessor" + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + if isEmpty mn.Left then mn.Key, mn.Value, mn.Right + else let k3, v3, l' = spliceOutSuccessor mn.Left in k3, v3, mk l' mn.Key mn.Value mn.Right + | _ -> m.Key, m.Value, empty + + let rec remove (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + if isEmpty m then empty + else + let c = comparer.Compare(k, m.Key) + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + if c < 0 then rebalance (remove comparer k mn.Left) mn.Key mn.Value mn.Right + elif c = 0 then + if isEmpty mn.Left then mn.Right + elif isEmpty mn.Right then mn.Left + else + let sk, sv, r' = spliceOutSuccessor mn.Right + mk mn.Left sk sv r' + else rebalance mn.Left mn.Key mn.Value (remove comparer k mn.Right) + | _ -> + if c = 0 then empty else m + + let rec mem (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + if isEmpty m then false + else + let c = comparer.Compare(k, m.Key) + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + if c < 0 then mem comparer k mn.Left + else (c = 0 || mem comparer k mn.Right) + | _ -> c = 0 + + let rec iterOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then () + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> iterOpt f mn.Left; f.Invoke (mn.Key, mn.Value); iterOpt f mn.Right + | _ -> f.Invoke (m.Key, m.Value) + + let iter f m = + iterOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m + + let rec tryPickOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then None + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + match tryPickOpt f mn.Left with + | Some _ as res -> res + | None -> + match f.Invoke (mn.Key, mn.Value) with + | Some _ as res -> res + | None -> + tryPickOpt f mn.Right + | _ -> f.Invoke (m.Key, m.Value) + + let tryPick f m = + tryPickOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m + + let rec existsOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then false + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> existsOpt f mn.Left || f.Invoke (mn.Key, mn.Value) || existsOpt f mn.Right + | _ -> f.Invoke (m.Key, m.Value) + + let exists f m = + existsOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m + + let rec forallOpt (f: OptimizedClosures.FSharpFunc<_, _, _>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then true + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> forallOpt f mn.Left && f.Invoke (mn.Key, mn.Value) && forallOpt f mn.Right + | _ -> f.Invoke (m.Key, m.Value) + + + let forall f m = + forallOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m + + let rec map (f:'Value -> 'Result) (m: MapTree<'Key, 'Value>) : MapTree<'Key, 'Result> = + if isEmpty m then empty + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let l2 = map f mn.Left + let v2 = f mn.Value + let r2 = map f mn.Right + MapTreeNode (mn.Key, v2, l2, r2, mn.Height) :> MapTree<'Key, 'Result> + | _ -> MapTree (m.Key, f m.Value) + + let rec mapiOpt (f: OptimizedClosures.FSharpFunc<'Key, 'Value, 'Result>) (m: MapTree<'Key, 'Value>) = + if isEmpty m then empty + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let l2 = mapiOpt f mn.Left + let v2 = f.Invoke (mn.Key, mn.Value) + let r2 = mapiOpt f mn.Right + MapTreeNode (mn.Key, v2, l2, r2, mn.Height) :> MapTree<'Key, 'Result> + | _ -> MapTree (m.Key, f.Invoke (m.Key, m.Value)) + + let mapi f m = + mapiOpt (OptimizedClosures.FSharpFunc<_, _, _>.Adapt f) m + + // Fold, right-to-left. + // + // NOTE: This differs from the behaviour of Set.fold which folds left-to-right. + + let rec foldBackOpt (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + if isEmpty m then x + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let x = foldBackOpt f mn.Right x + let x = f.Invoke (mn.Key, mn.Value, x) + foldBackOpt f mn.Left x + | _ -> f.Invoke (m.Key, m.Value, x) + + let foldBack f m x = + foldBackOpt (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m x + + let foldSectionOpt (comparer: IComparer<'Key>) lo hi (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + let rec foldFromTo (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + if isEmpty m then x + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let cLoKey = comparer.Compare(lo, mn.Key) + let cKeyHi = comparer.Compare(mn.Key, hi) + let x = if cLoKey < 0 then foldFromTo f mn.Left x else x + let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (mn.Key, mn.Value, x) else x + let x = if cKeyHi < 0 then foldFromTo f mn.Right x else x + x + | _ -> + let cLoKey = comparer.Compare(lo, m.Key) + let cKeyHi = comparer.Compare(m.Key, hi) + let x = if cLoKey <= 0 && cKeyHi <= 0 then f.Invoke (m.Key, m.Value, x) else x + x + + if comparer.Compare(lo, hi) = 1 then x else foldFromTo f m x + + let foldSection (comparer: IComparer<'Key>) lo hi f m x = + foldSectionOpt comparer lo hi (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m x + + let rec foldMapOpt (comparer: IComparer<'Key>) (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) z acc = + if isEmpty m then acc,z + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> + let acc,z = foldMapOpt comparer f mn.Right z acc + let v',z = f.Invoke(mn.Key, mn.Value, z) + let acc = add comparer mn.Key v' acc + foldMapOpt comparer f mn.Left z acc + | _ -> + let v',z = f.Invoke(m.Key, m.Value, z) + add comparer m.Key v' acc,z + + let foldMap (comparer: IComparer<'Key>) f (m: MapTree<'Key, 'Value>) z acc = + foldMapOpt comparer (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m z acc + + let toList m = foldBack (fun k v acc -> (k,v) :: acc) m [] + let toArray m = m |> toList |> Array.ofList + let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l + + let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = + if e.MoveNext() then + let x,y = e.Current + mkFromEnumerator comparer (add comparer x y acc) e + else acc + + let ofSeq comparer (c : seq<_>) = + use ie = c.GetEnumerator() + mkFromEnumerator comparer empty ie + + let copyToArray s (arr: _[]) i = + let mutable j = i + s |> iter (fun x y -> arr.[j] <- KeyValuePair(x,y); j <- j + 1) + + + /// Imperative left-to-right iterators. + type MapIterator<'Key,'Value>(s:MapTree<'Key,'Value>) = + // collapseLHS: + // a) Always returns either [] or a list starting with SetOne. + // b) The "fringe" of the set stack is unchanged. + let rec collapseLHS (stack:MapTree<'Key, 'Value> list) = + match stack with + | [] -> [] + | m :: rest -> + if isEmpty m then collapseLHS rest + else + match m with + | :? MapTreeNode<'Key, 'Value> as mn -> collapseLHS (mn.Left :: MapTree (mn.Key, mn.Value) :: mn.Right :: rest) + | _ -> stack + + /// invariant: always collapseLHS result + let mutable stack = collapseLHS [s] + /// true when MoveNext has been called + let mutable started = false + + let notStarted() = raise (System.InvalidOperationException("Enumeration has not started. Call MoveNext.")) + let alreadyFinished() = raise (System.InvalidOperationException("Enumeration already finished.")) + + member _.Current = + if started then + match stack with + | [] -> alreadyFinished() + | m :: _ -> + match m with + | :? MapTreeNode<'Key, 'Value> -> failwith "Please report error: Map iterator, unexpected stack for current" + | _ -> KeyValuePair<_, _>(m.Key, m.Value) + else + notStarted() + + member _.MoveNext() = + if started then + match stack with + | [] -> false + | m :: rest -> + match m with + | :? MapTreeNode<'Key, 'Value> -> failwith "Please report error: Map iterator, unexpected stack for moveNext" + | _ -> + stack <- collapseLHS rest + not stack.IsEmpty + else + started <- true (* The first call to MoveNext "starts" the enumeration. *) + not stack.IsEmpty + + let toSeq s = + let mutable i = MapIterator(s) + { new IEnumerator<_> with + member self.Current = i.Current + interface System.Collections.IEnumerator with + member self.Current = box i.Current + member self.MoveNext() = i.MoveNext() + member self.Reset() = i <- MapIterator(s) + interface System.IDisposable with + member self.Dispose() = ()} + + + [] + [] + type internal Map<'Key,'T,'ComparerTag> when 'ComparerTag :> IComparer<'Key>( comparer: IComparer<'Key>, tree: MapTree<'Key,'T>) = + + static let refresh (m:Map<_,_,'ComparerTag>) t = + Map<_,_,'ComparerTag>(comparer=m.Comparer, tree=t) + + member s.Tree = tree + member s.Comparer : IComparer<'Key> = comparer + + static member Empty(comparer : 'ComparerTag) = Map<'Key,'T,'ComparerTag>(comparer=comparer, tree=MapTree.empty) + member m.Add(k,v) = refresh m (MapTree.add comparer k v tree) + member m.IsEmpty = MapTree.isEmpty tree + member m.Item with get(k : 'Key) = MapTree.find comparer k tree + member m.First(f) = MapTree.tryPick f tree + member m.Exists(f) = MapTree.exists f tree + member m.Filter(f) = MapTree.filter comparer f tree |> refresh m + member m.ForAll(f) = MapTree.forall f tree + member m.Fold folder acc = MapTree.foldBack folder tree acc + member m.FoldSection lo hi f acc = MapTree.foldSection comparer lo hi f tree acc + member m.FoldAndMap f z = + let tree,z = MapTree.foldMap comparer f tree z MapTree.empty + refresh m tree, z + member m.Iterate action = MapTree.iter action tree + member m.MapRange mapping = refresh m (MapTree.map mapping tree) + member m.Map mapping = refresh m (MapTree.mapi mapping tree) + member m.Partition(f) = + let r1,r2 = MapTree.partition comparer f tree + refresh m r1, refresh m r2 + member m.Count = MapTree.size tree + member m.ContainsKey(k) = MapTree.mem comparer k tree + member m.Remove(k) = refresh m (MapTree.remove comparer k tree) + member m.TryFind(k) = MapTree.tryFind comparer k tree + member m.ToList() = MapTree.toList tree + member m.ToArray() = MapTree.toArray tree + + static member FromList(comparer : 'ComparerTag,l) : Map<'Key,'T,'ComparerTag> = + Map<_,_,_>(comparer=comparer, tree=MapTree.ofList comparer l) + + static member Create(comparer : 'ComparerTag, ie : seq<_>) : Map<'Key,'T,'ComparerTag> = + Map<_,_,_>(comparer=comparer, tree=MapTree.ofSeq comparer ie) + + interface IEnumerable> with + member s.GetEnumerator() = MapTree.toSeq tree + + interface System.Collections.IEnumerable with + override s.GetEnumerator() = (MapTree.toSeq tree :> System.Collections.IEnumerator) + + override this.Equals(that) = + match that with + // Cast to the exact same type as this, otherwise not equal. + | :? Map<'Key,'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0) + | _ -> false + + interface System.IComparable with + member m1.CompareTo(m2: obj) = + Seq.compareWith + (fun (kvp1 : KeyValuePair<_,_>) (kvp2 : KeyValuePair<_,_>)-> + let c = m1.Comparer.Compare(kvp1.Key,kvp2.Key) in + if c <> 0 then c else Unchecked.compare kvp1.Value kvp2.Value) + // Cast m2 to the exact same type as m1, see 4884. + // It is not OK to cast m2 to seq>, since different compares could permute the KVPs. + m1 (m2 :?> Map<'Key,'T,'ComparerTag>) + + member this.ComputeHashCode() = + let combineHash x y = (x <<< 1) + y + 631 + let mutable res = 0 + for KeyValue(x,y) in this do + res <- combineHash res (Unchecked.hash x) + res <- combineHash res (Unchecked.hash y) + res + + override this.GetHashCode() = this.ComputeHashCode() + + + type internal Map<'Key,'T> = Map<'Key, 'T, IComparer<'Key>> + type internal Set<'T> = Set<'T, IComparer<'T>> diff --git a/src/utils/TaggedCollections.fsi b/src/fsharp/utils/TaggedCollections.fsi similarity index 99% rename from src/utils/TaggedCollections.fsi rename to src/fsharp/utils/TaggedCollections.fsi index c877cbe7eb5..323324c719d 100644 --- a/src/utils/TaggedCollections.fsi +++ b/src/fsharp/utils/TaggedCollections.fsi @@ -112,7 +112,7 @@ namespace Internal.Utilities.Collections.Tagged interface System.Collections.IEnumerable - interface System.IComparable + interface IComparable override Equals : obj -> bool @@ -216,7 +216,7 @@ namespace Internal.Utilities.Collections.Tagged interface System.Collections.IEnumerable - interface System.IComparable + interface IComparable override Equals : obj -> bool diff --git a/src/fsharp/utils/UtilsStrings.txt b/src/fsharp/utils/UtilsStrings.txt new file mode 100644 index 00000000000..7c6971436b7 --- /dev/null +++ b/src/fsharp/utils/UtilsStrings.txt @@ -0,0 +1,2 @@ +buildProductName,"Microsoft (R) F# Compiler version %s" +fSharpBannerVersion,"%s for F# %s" \ No newline at end of file diff --git a/src/utils/prim-lexing.fs b/src/fsharp/utils/prim-lexing.fs similarity index 79% rename from src/utils/prim-lexing.fs rename to src/fsharp/utils/prim-lexing.fs index 1f772d6e87e..1451d514e36 100644 --- a/src/utils/prim-lexing.fs +++ b/src/fsharp/utils/prim-lexing.fs @@ -6,26 +6,27 @@ namespace FSharp.Compiler.Text open System open System.IO +open FSharp.Compiler type ISourceText = - abstract Item : int -> char with get + abstract Item: index: int -> char with get - abstract GetLineString : lineIndex: int -> string + abstract GetLineString: lineIndex: int -> string - abstract GetLineCount : unit -> int + abstract GetLineCount: unit -> int - abstract GetLastCharacterPosition : unit -> int * int + abstract GetLastCharacterPosition: unit -> int * int - abstract GetSubTextString : start: int * length: int -> string + abstract GetSubTextString: start: int * length: int -> string - abstract SubTextEquals : target: string * startIndex: int -> bool + abstract SubTextEquals: target: string * startIndex: int -> bool - abstract Length : int + abstract Length: int - abstract ContentEquals : sourceText: ISourceText -> bool + abstract ContentEquals: sourceText: ISourceText -> bool - abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit + abstract CopyTo: sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit [] type StringText(str: string) = @@ -49,31 +50,36 @@ type StringText(str: string) = // So, it's ok that we do this for now. lazy getLines str - member __.String = str + member _.String = str - override __.GetHashCode() = str.GetHashCode() - override __.Equals(obj: obj) = str.Equals(obj) + override _.GetHashCode() = str.GetHashCode() + override _.Equals(obj: obj) = + match obj with + | :? StringText as other -> other.String.Equals(str) + | :? string as other -> other.Equals(str) + | _ -> false + override _.ToString() = str interface ISourceText with - member __.Item with get index = str.[index] + member _.Item with get index = str.[index] - member __.GetLastCharacterPosition() = + member _.GetLastCharacterPosition() = let lines = getLines.Value if lines.Length > 0 then (lines.Length, lines.[lines.Length - 1].Length) else (0, 0) - member __.GetLineString(lineIndex) = + member _.GetLineString(lineIndex) = getLines.Value.[lineIndex] - member __.GetLineCount() = getLines.Value.Length + member _.GetLineCount() = getLines.Value.Length - member __.GetSubTextString(start, length) = + member _.GetSubTextString(start, length) = str.Substring(start, length) - member __.SubTextEquals(target, startIndex) = + member _.SubTextEquals(target, startIndex) = if startIndex < 0 || startIndex >= str.Length then invalidArg "startIndex" "Out of range." @@ -86,14 +92,14 @@ type StringText(str: string) = str.IndexOf(target, startIndex, target.Length) <> -1 - member __.Length = str.Length + member _.Length = str.Length member this.ContentEquals(sourceText) = match sourceText with | :? StringText as sourceText when sourceText = this || sourceText.String = str -> true | _ -> false - member __.CopyTo(sourceIndex, destination, destinationIndex, count) = + member _.CopyTo(sourceIndex, destination, destinationIndex, count) = str.CopyTo(sourceIndex, destination, destinationIndex, count) module SourceText = @@ -169,11 +175,11 @@ namespace Internal.Utilities.Text.Lexing 0, 0) - type internal LexBufferFiller<'Char> = (LexBuffer<'Char> -> unit) + type internal LexBufferFiller<'Char> = LexBuffer<'Char> -> unit and [] - internal LexBuffer<'Char>(filler: LexBufferFiller<'Char>, supportsFeature:LanguageFeature -> bool) = - let context = new Dictionary(1) + internal LexBuffer<'Char>(filler: LexBufferFiller<'Char>, reportLibraryOnlyFeatures: bool, langVersion:LanguageVersion) = + let context = Dictionary(1) let mutable buffer = [||] /// number of valid characters beyond bufferScanStart. let mutable bufferMaxScanLength = 0 @@ -189,13 +195,11 @@ namespace Internal.Utilities.Text.Lexing let mutable startPos = Position.Empty let mutable endPos = Position.Empty - // Throw away all the input besides the lexeme + // Throw away all the input besides the lexeme, which is placed at start of buffer let discardInput () = - let keep = Array.sub buffer bufferScanStart bufferScanLength - let nkeep = keep.Length - Array.blit keep 0 buffer 0 nkeep + Array.blit buffer bufferScanStart buffer 0 bufferScanLength bufferScanStart <- 0 - bufferMaxScanLength <- nkeep + bufferMaxScanLength <- bufferScanLength member lexbuf.EndOfScan () : int = //Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength; @@ -216,7 +220,9 @@ namespace Internal.Utilities.Text.Lexing with get() = endPos and set b = endPos <- b - member lexbuf.Lexeme = Array.sub buffer bufferScanStart lexemeLength + member lexbuf.LexemeView = System.ReadOnlySpan<'Char>(buffer, bufferScanStart, lexemeLength) + member lexbuf.LexemeChar n = buffer.[n+bufferScanStart] + member lexbuf.LexemeContains (c:'Char) = array.IndexOf(buffer, c, bufferScanStart, lexemeLength) >= 0 member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>) member lexbuf.LexemeLength with get() : int = lexemeLength and set v = lexemeLength <- v member lexbuf.Buffer with get() : 'Char[] = buffer and set v = buffer <- v @@ -226,11 +232,11 @@ namespace Internal.Utilities.Text.Lexing member lexbuf.BufferAcceptAction with get() = bufferAcceptAction and set v = bufferAcceptAction <- v member lexbuf.RefillBuffer () = filler lexbuf static member LexemeString(lexbuf:LexBuffer) = - new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength) + System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength) member lexbuf.IsPastEndOfStream with get() = eof - and set(b) = eof <- b + and set b = eof <- b member lexbuf.DiscardInput () = discardInput () @@ -242,35 +248,43 @@ namespace Internal.Utilities.Text.Lexing Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength buffer <- repl - member __.SupportsFeature featureId = supportsFeature featureId + member _.ReportLibraryOnlyFeatures = reportLibraryOnlyFeatures - static member FromFunction (supportsFeature:LanguageFeature -> bool, f : 'Char[] * int * int -> int) : LexBuffer<'Char> = + member _.LanguageVersion = langVersion + + member _.SupportsFeature featureId = langVersion.SupportsFeature featureId + + member _.CheckLanguageFeatureErrorRecover featureId range = + FSharp.Compiler.ErrorLogger.checkLanguageFeatureErrorRecover langVersion featureId range + + static member FromFunction (reportLibraryOnlyFeatures, langVersion, f : 'Char[] * int * int -> int) : LexBuffer<'Char> = let extension= Array.zeroCreate 4096 let filler (lexBuffer: LexBuffer<'Char>) = let n = f (extension,0,extension.Length) lexBuffer.EnsureBufferSize n Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n - new LexBuffer<'Char>(filler, supportsFeature) + new LexBuffer<'Char>(filler, reportLibraryOnlyFeatures, langVersion) // Important: This method takes ownership of the array - static member FromArrayNoCopy (supportsFeature:LanguageFeature -> bool, buffer: 'Char[]) : LexBuffer<'Char> = - let lexBuffer = new LexBuffer<'Char>((fun _ -> ()), supportsFeature) + static member FromArrayNoCopy (reportLibraryOnlyFeatures, langVersion, buffer: 'Char[]) : LexBuffer<'Char> = + let lexBuffer = new LexBuffer<'Char>((fun _ -> ()), reportLibraryOnlyFeatures, langVersion) lexBuffer.Buffer <- buffer lexBuffer.BufferMaxScanLength <- buffer.Length lexBuffer // Important: this method does copy the array - static member FromArray (supportsFeature: LanguageFeature -> bool, s: 'Char[]) : LexBuffer<'Char> = + static member FromArray (reportLibraryOnlyFeatures, langVersion, s: 'Char[]) : LexBuffer<'Char> = let buffer = Array.copy s - LexBuffer<'Char>.FromArrayNoCopy(supportsFeature, buffer) + LexBuffer<'Char>.FromArrayNoCopy(reportLibraryOnlyFeatures, langVersion, buffer) // Important: This method takes ownership of the array - static member FromChars (supportsFeature:LanguageFeature -> bool, arr:char[]) = LexBuffer.FromArrayNoCopy (supportsFeature, arr) + static member FromChars (reportLibraryOnlyFeatures, langVersion, arr:char[]) = + LexBuffer.FromArrayNoCopy (reportLibraryOnlyFeatures, langVersion, arr) - static member FromSourceText (supportsFeature: LanguageFeature -> bool, sourceText: ISourceText) = + static member FromSourceText (reportLibraryOnlyFeatures, langVersion, sourceText: ISourceText) = let mutable currentSourceIndex = 0 - LexBuffer.FromFunction(supportsFeature, fun (chars, start, length) -> + LexBuffer.FromFunction(reportLibraryOnlyFeatures, langVersion, fun (chars, start, length) -> let lengthToCopy = if currentSourceIndex + length <= sourceText.Length then length @@ -382,4 +396,4 @@ namespace Internal.Utilities.Text.Lexing startInterpret(lexBuffer) scanUntilSentinel lexBuffer initialState - static member Create(trans,accept) = new UnicodeTables(trans,accept) + static member Create(trans,accept) = UnicodeTables(trans,accept) diff --git a/src/fsharp/utils/prim-lexing.fsi b/src/fsharp/utils/prim-lexing.fsi new file mode 100644 index 00000000000..23ad8cbefa6 --- /dev/null +++ b/src/fsharp/utils/prim-lexing.fsi @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// LexBuffers are for use with automatically generated lexical analyzers, +// in particular those produced by 'fslex'. + +namespace FSharp.Compiler.Text + +/// Represents an input to the F# compiler +type ISourceText = + + /// Gets a character in an input based on an index of characters from the start of the file + abstract Item: index: int -> char with get + + /// Gets a line of an input by index + abstract GetLineString: lineIndex: int -> string + + /// Gets the count of lines in the input + abstract GetLineCount: unit -> int + + /// Gets the last character position in the input, returning line and column + abstract GetLastCharacterPosition: unit -> int * int + + /// Gets a section of the input + abstract GetSubTextString: start: int * length: int -> string + + /// Checks if a section of the input is equal to the given string + abstract SubTextEquals: target: string * startIndex: int -> bool + + /// Gets the total length of the input in characters + abstract Length: int + + /// Checks if one input is equal to another + abstract ContentEquals: sourceText: ISourceText -> bool + + /// Copies a section of the input to the given destination ad the given index + abstract CopyTo: sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit + +/// Functions related to ISourceText objects +module SourceText = + + /// Creates an ISourceText object from the given string + val ofString: string -> ISourceText + +// +// NOTE: the code in this file is a drop-in replacement runtime for Lexing.fsi from the FsLexYacc repository +// and is referenced by generated code for the three FsLex generated lexers in the F# compiler. +// The underlying table format interpreted must precisely match the format generated by FsLex. +namespace Internal.Utilities.Text.Lexing + +open System.Collections.Generic +open FSharp.Compiler.Text +open FSharp.Compiler.Features + +/// Position information stored for lexing tokens +[] +type internal Position = + /// The file index for the file associated with the input stream, use fileOfFileIndex to decode + val FileIndex: int + + /// The line number in the input stream, assuming fresh positions have been updated + /// for the new line by modifying the EndPos property of the LexBuffer. + val Line: int + + /// The line number for the position in the input stream, assuming fresh positions have been updated + /// using for the new line. + val OriginalLine: int + + /// The character number in the input stream. + val AbsoluteOffset: int + + /// Return absolute offset of the start of the line marked by the position. + val StartOfLineAbsoluteOffset: int + + /// Return the column number marked by the position, + /// i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset + member Column: int + + /// Given a position just beyond the end of a line, return a position at the start of the next line. + member NextLine: Position + + /// Given a position at the start of a token of length n, return a position just beyond the end of the token. + member EndOfToken: n:int -> Position + + /// Gives a position shifted by specified number of characters. + member ShiftColumnBy: by:int -> Position + + /// Same line, column -1. + member ColumnMinusOne: Position + + /// Apply a #line directive. + member ApplyLineDirective: fileIdx:int * line:int -> Position + + /// Get an arbitrary position, with the empty string as filename. + static member Empty: Position + + static member FirstLine: fileIdx:int -> Position + +[] +/// Input buffers consumed by lexers generated by fslex.exe. +/// The type must be generic to match the code generated by FsLex and FsYacc (if you would like to +/// fix this, please submit a PR to the FsLexYacc repository allowing for optional emit of a non-generic type reference). +type internal LexBuffer<'Char> = + /// The start position for the lexeme. + member StartPos: Position with get,set + + /// The end position for the lexeme. + member EndPos: Position with get,set + + /// The currently matched text as a Span, it is only valid until the lexer is advanced + member LexemeView: System.ReadOnlySpan<'Char> + + /// Get single character of matched string + member LexemeChar: int -> 'Char + + /// Determine if Lexeme contains a specific character + member LexemeContains: 'Char -> bool + + /// Fast helper to turn the matched characters into a string, avoiding an intermediate array. + static member LexemeString: LexBuffer -> string + + /// Dynamically typed, non-lexically scoped parameter table. + member BufferLocalStore: IDictionary + + /// True if the refill of the buffer ever failed , or if explicitly set to True. + member IsPastEndOfStream: bool with get,set + + /// Determines if the parser can report FSharpCore library-only features. + member ReportLibraryOnlyFeatures: bool + + /// Get the language version being supported + member LanguageVersion: LanguageVersion + + /// True if the specified language feature is supported. + member SupportsFeature: LanguageFeature -> bool + + /// Logs a recoverable error if a language feature is unsupported, at the specified range. + member CheckLanguageFeatureErrorRecover: LanguageFeature -> range -> unit + + /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array. + /// Important: does take ownership of the array. + static member FromChars: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * char[] -> LexBuffer + + /// Create a lex buffer that reads character or byte inputs by using the given function. + static member FromFunction: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * ('Char[] * int * int -> int) -> LexBuffer<'Char> + + /// Create a lex buffer backed by source text. + static member FromSourceText: reportLibraryOnlyFeatures: bool * langVersion: LanguageVersion * ISourceText -> LexBuffer + +/// The type of tables for an unicode lexer generated by fslex.exe. +[] +type internal UnicodeTables = + + /// Create the tables from raw data + static member Create: uint16[][] * uint16[] -> UnicodeTables + + /// Interpret tables for a unicode lexer generated by fslex.exe. + member Interpret: initialState:int * LexBuffer -> int + diff --git a/src/utils/prim-parsing.fs b/src/fsharp/utils/prim-parsing.fs similarity index 89% rename from src/utils/prim-parsing.fs rename to src/fsharp/utils/prim-parsing.fs index b58e592278d..444113f939b 100644 --- a/src/utils/prim-parsing.fs +++ b/src/fsharp/utils/prim-parsing.fs @@ -7,6 +7,7 @@ namespace Internal.Utilities.Text.Parsing open Internal.Utilities.Text.Lexing open System +open System.Buffers exception RecoverableParseError exception Accept of obj @@ -15,17 +16,17 @@ exception Accept of obj type internal IParseState(ruleStartPoss:Position[], ruleEndPoss:Position[], lhsPos:Position[], ruleValues:obj[], lexbuf:LexBuffer) = member p.LexBuffer = lexbuf - member p.InputRange n = ruleStartPoss.[n-1], ruleEndPoss.[n-1] + member p.InputRange index = ruleStartPoss.[index-1], ruleEndPoss.[index-1] - member p.InputStartPosition n = ruleStartPoss.[n-1] + member p.InputStartPosition index = ruleStartPoss.[index-1] - member p.InputEndPosition n = ruleEndPoss.[n-1] + member p.InputEndPosition index = ruleEndPoss.[index-1] member p.ResultStartPosition = lhsPos.[0] member p.ResultEndPosition = lhsPos.[1] - member p.GetInput n = ruleValues.[n-1] + member p.GetInput index = ruleValues.[index-1] member p.ResultRange = (lhsPos.[0], lhsPos.[1]) @@ -107,7 +108,7 @@ type Stack<'a>(n) = member buf.IsEmpty = (count = 0) member buf.PrintStack() = for i = 0 to (count - 1) do - System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") + Console.Write("{0}{1}",contents.[i],if i=count-1 then ":" else "-") #if DEBUG @@ -131,11 +132,7 @@ module internal Implementation = //------------------------------------------------------------------------- // Read the tables written by FSYACC. - type AssocTable(elemTab:uint16[], offsetTab:uint16[]) = - let cacheSize = 7919 // the 1000'th prime - // Use a simpler hash table with faster lookup, but only one - // hash bucket per key. - let cache = Array.zeroCreate (cacheSize * 2) + type AssocTable(elemTab: uint16[], offsetTab: uint16[], cache: int[], cacheSize: int) = member t.ReadAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) = // do a binary chop on the table @@ -206,11 +203,11 @@ module internal Implementation = let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState = #if DEBUG - if Flags.debug then System.Console.WriteLine("\nParser: interpret tables") + if Flags.debug then Console.WriteLine("\nParser: interpret tables") #endif - let stateStack : Stack = new Stack<_>(100) + let stateStack : Stack = Stack<_>(100) stateStack.Push(initialState) - let valueStack = new Stack(100) + let valueStack = Stack(100) let mutable haveLookahead = false let mutable lookaheadToken = Unchecked.defaultof<'tok> let mutable lookaheadEndPos = Unchecked.defaultof @@ -234,12 +231,25 @@ module internal Implementation = let ruleValues = (Array.zeroCreate 100 : obj[]) let lhsPos = (Array.zeroCreate 2 : Position[]) let reductions = tables.reductions - let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets) - let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets) - let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets) + let cacheSize = 7919 // the 1000'th prime + // Use a simpler hash table with faster lookup, but only one + // hash bucket per key. + let actionTableCache = ArrayPool.Shared.Rent(cacheSize * 2) + let gotoTableCache = ArrayPool.Shared.Rent(cacheSize * 2) + // Clear the arrays since ArrayPool does not + Array.Clear(actionTableCache, 0, actionTableCache.Length) + Array.Clear(gotoTableCache, 0, gotoTableCache.Length) + use _cacheDisposal = + { new IDisposable with + member _.Dispose() = + ArrayPool.Shared.Return actionTableCache + ArrayPool.Shared.Return gotoTableCache } + let actionTable = AssocTable(tables.actionTableElements, tables.actionTableRowOffsets, actionTableCache, cacheSize) + let gotoTable = AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets, gotoTableCache, cacheSize) + let stateToProdIdxsTable = IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets) let parseState = - new IParseState(ruleStartPoss,ruleEndPoss,lhsPos,ruleValues,lexbuf) + IParseState(ruleStartPoss,ruleEndPoss,lhsPos,ruleValues,lexbuf) #if DEBUG let report haveLookahead lookaheadToken = @@ -250,22 +260,22 @@ module internal Implementation = // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'. // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token. - let rec popStackUntilErrorShifted(tokenOpt) = + let rec popStackUntilErrorShifted tokenOpt = // Keep popping the stack until the "error" terminal is shifted #if DEBUG - if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted") + if Flags.debug then Console.WriteLine("popStackUntilErrorShifted") #endif if stateStack.IsEmpty then #if DEBUG if Flags.debug then - System.Console.WriteLine("state stack empty during error recovery - generating parse error") + Console.WriteLine("state stack empty during error recovery - generating parse error") #endif failwith "parse error" let currState = stateStack.Peep() #if DEBUG if Flags.debug then - System.Console.WriteLine("In state {0} during error recovery", currState) + Console.WriteLine("In state {0} during error recovery", currState) #endif let action = actionTable.Read(currState, tables.tagOfErrorTerminal) @@ -278,7 +288,7 @@ module internal Implementation = actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then #if DEBUG - if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery") + if Flags.debug then Console.WriteLine("shifting error, continuing with error recovery") #endif let nextState = actionValue action // The "error" non terminal needs position information, though it tends to be unreliable. @@ -290,7 +300,7 @@ module internal Implementation = failwith "parse error" #if DEBUG if Flags.debug then - System.Console.WriteLine("popping stack during error recovery") + Console.WriteLine("popping stack during error recovery") #endif valueStack.Pop() stateStack.Pop() @@ -444,10 +454,10 @@ module internal Implementation = let currentToken = if haveLookahead then Some(lookaheadToken) else None let actions,defaultAction = actionTable.ReadAll(state) - let explicit = Set.ofList [ for (tag,_action) in actions -> tag ] + let explicit = Set.ofList [ for tag,_action in actions -> tag ] let shiftableTokens = - [ for (tag,action) in actions do + [ for tag,action in actions do if (actionKind action) = shiftFlag then yield tag if actionKind defaultAction = shiftFlag then @@ -461,7 +471,7 @@ module internal Implementation = yield stateToProdIdxsTable.ReadAll(state) ] let reduceTokens = - [ for (tag,action) in actions do + [ for tag,action in actions do if actionKind(action) = reduceFlag then yield tag if actionKind(defaultAction) = reduceFlag then @@ -474,14 +484,14 @@ module internal Implementation = popStackUntilErrorShifted(None) errorSuppressionCountDown <- 3 #if DEBUG - if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead) + if Flags.debug then Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead) #endif ) ) elif kind = acceptFlag then finished <- true #if DEBUG else - if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser") + if Flags.debug then Console.WriteLine("ALARM!!! drop through case in parser") #endif done // OK, we're done - read off the overall generated value diff --git a/src/utils/prim-parsing.fsi b/src/fsharp/utils/prim-parsing.fsi similarity index 95% rename from src/utils/prim-parsing.fsi rename to src/fsharp/utils/prim-parsing.fsi index 7ec3e7a0a80..c4d5475273e 100644 --- a/src/utils/prim-parsing.fsi +++ b/src/fsharp/utils/prim-parsing.fsi @@ -4,11 +4,8 @@ namespace Internal.Utilities.Text.Parsing -open Internal.Utilities open Internal.Utilities.Text.Lexing -open System.Collections.Generic - [] type internal IParseState = @@ -16,10 +13,10 @@ type internal IParseState = member InputRange: index:int -> Position * Position /// Get the end position for the terminal or non-terminal at a given index matched by the production. - member InputEndPosition: int -> Position + member InputEndPosition: index:int -> Position /// Get the start position for the terminal or non-terminal at a given index matched by the production. - member InputStartPosition: int -> Position + member InputStartPosition: index:int -> Position /// Get the start of the range of positions matched by the production. member ResultStartPosition: Position @@ -31,7 +28,7 @@ type internal IParseState = member ResultRange: Position * Position /// Get the value produced by the terminal or non-terminal at the given position. - member GetInput : int -> obj + member GetInput : index:int -> obj /// Raise an error in this parse context. member RaiseError<'b> : unit -> 'b @@ -118,7 +115,7 @@ type internal Tables<'tok> = /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state. /// Returns an object indicating the final synthesized value for the parse. - member Interpret : lexer:(LexBuffer -> 'tok) * lexbuf:LexBuffer * startState:int -> obj + member Interpret : lexer:(LexBuffer -> 'tok) * lexbuf:LexBuffer * initialState:int -> obj /// Indicates an accept action has occurred. exception internal Accept of obj diff --git a/src/fsharp/utils/sformat.fs b/src/fsharp/utils/sformat.fs new file mode 100644 index 00000000000..d8ee767e1f9 --- /dev/null +++ b/src/fsharp/utils/sformat.fs @@ -0,0 +1,1378 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// This file is compiled twice in the codebase +// - as the internal implementation of printf '%A' formatting in FSharp.Core +// - as the implementation of structured formatting in the compiler, F# Interactive and FSharp.Compiler.Service. +// +// The one implementation file is used because we keep the implementations of +// structured formatting the same for fsi.exe and '%A' printing. However F# Interactive has +// a richer feature set. + +#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation + +#if COMPILER +namespace FSharp.Compiler.Text +#else +// FSharp.Core.dll: +namespace Microsoft.FSharp.Text.StructuredPrintfImpl +#endif + +// Breakable block layout implementation. +// This is a fresh implementation of pre-existing ideas. + +open System +open System.IO +open System.Reflection +open System.Globalization +open System.Collections.Generic +open Microsoft.FSharp.Core +open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators +open Microsoft.FSharp.Reflection +open Microsoft.FSharp.Collections + +[] +type TextTag = + | ActivePatternCase + | ActivePatternResult + | Alias + | Class + | Union + | UnionCase + | Delegate + | Enum + | Event + | Field + | Interface + | Keyword + | LineBreak + | Local + | Record + | RecordField + | Method + | Member + | ModuleBinding + | Function + | Module + | Namespace + | NumericLiteral + | Operator + | Parameter + | Property + | Space + | StringLiteral + | Struct + | TypeParameter + | Text + | Punctuation + | UnknownType + | UnknownEntity + +type TaggedText(tag: TextTag, text: string) = + member x.Tag = tag + member x.Text = text + override x.ToString() = text + "(tag: " + tag.ToString() + ")" + +type TaggedTextWriter = + abstract Write: t: TaggedText -> unit + abstract WriteLine: unit -> unit + +/// A joint, between 2 layouts, is either: +/// - unbreakable, or +/// - breakable, and if broken the second block has a given indentation. +[] +type Joint = + | Unbreakable + | Breakable of indentation: int + | Broken of indentation: int + +/// If either juxtaposition flag is true, then no space between words. +[] +type Layout = + | ObjLeaf of juxtLeft: bool * object: obj * juxtRight: bool + | Leaf of juxtLeft: bool * text: TaggedText * juxtRight: bool + | Node of leftLayout: Layout * rightLayout: Layout * joint: Joint + | Attr of text: string * attributes: (string * string) list * layout: Layout + + member layout.JuxtapositionLeft = + match layout with + | ObjLeaf (jl, _, _) -> jl + | Leaf (jl, _, _) -> jl + | Node (left, _, _) -> left.JuxtapositionLeft + | Attr (_, _, subLayout) -> subLayout.JuxtapositionLeft + + static member JuxtapositionMiddle (left: Layout, right: Layout) = + left.JuxtapositionRight || right.JuxtapositionLeft + + member layout.JuxtapositionRight = + match layout with + | ObjLeaf (_, _, jr) -> jr + | Leaf (_, _, jr) -> jr + | Node (_, right, _) -> right.JuxtapositionRight + | Attr (_, _, subLayout) -> subLayout.JuxtapositionRight + +[] +type IEnvironment = + abstract GetLayout: obj -> Layout + abstract MaxColumns: int + abstract MaxRows: int + +[] +module TaggedText = + let mkTag tag text = TaggedText(tag, text) + + let length (tt: TaggedText) = tt.Text.Length + let toText (tt: TaggedText) = tt.Text + let tagClass name = mkTag TextTag.Class name + let tagUnionCase t = mkTag TextTag.UnionCase t + let tagField t = mkTag TextTag.Field t + let tagNumericLiteral t = mkTag TextTag.NumericLiteral t + let tagKeyword t = mkTag TextTag.Keyword t + let tagStringLiteral t = mkTag TextTag.StringLiteral t + let tagLocal t = mkTag TextTag.Local t + let tagText t = mkTag TextTag.Text t + let tagRecordField t = mkTag TextTag.RecordField t + let tagProperty t = mkTag TextTag.Property t + let tagMethod t = mkTag TextTag.Method t + let tagPunctuation t = mkTag TextTag.Punctuation t + let tagOperator t = mkTag TextTag.Operator t + let tagSpace t = mkTag TextTag.Space t + + let leftParen = tagPunctuation "(" + let rightParen = tagPunctuation ")" + let comma = tagPunctuation "," + let semicolon = tagPunctuation ";" + let questionMark = tagPunctuation "?" + let leftBracket = tagPunctuation "[" + let rightBracket = tagPunctuation "]" + let leftBrace= tagPunctuation "{" + let rightBrace = tagPunctuation "}" + let space = tagSpace " " + let equals = tagOperator "=" + +#if COMPILER + let tagAlias t = mkTag TextTag.Alias t + let keywordFunctions = + [ + "raise" + "reraise" + "typeof" + "typedefof" + "sizeof" + "nameof" + "char" + "decimal" + "double" + "float" + "float32" + "int" + "int8" + "int16" + "int32" + "int64" + "sbyte" + "seq" // 'seq x' when 'x' is a string works, strangely enough + "single" + "string" + "unit" + "uint" + "uint8" + "uint16" + "uint32" + "uint64" + "unativeint" + ] + |> Set.ofList + let tagDelegate t = mkTag TextTag.Delegate t + let tagEnum t = mkTag TextTag.Enum t + let tagEvent t = mkTag TextTag.Event t + let tagInterface t = mkTag TextTag.Interface t + let tagLineBreak t = mkTag TextTag.LineBreak t + let tagRecord t = mkTag TextTag.Record t + let tagModule t = mkTag TextTag.Module t + let tagModuleBinding name = if keywordFunctions.Contains name then mkTag TextTag.Keyword name else mkTag TextTag.ModuleBinding name + let tagFunction t = mkTag TextTag.Function t + let tagNamespace t = mkTag TextTag.Namespace t + let tagParameter t = mkTag TextTag.Parameter t + let tagStruct t = mkTag TextTag.Struct t + let tagTypeParameter t = mkTag TextTag.TypeParameter t + let tagActivePatternCase t = mkTag TextTag.ActivePatternCase t + let tagActivePatternResult t = mkTag TextTag.ActivePatternResult t + let tagUnion t = mkTag TextTag.Union t + let tagMember t = mkTag TextTag.Member t + let tagUnknownEntity t = mkTag TextTag.UnknownEntity t + let tagUnknownType t = mkTag TextTag.UnknownType t + + // common tagged literals + let lineBreak = tagLineBreak "\n" + let leftBraceBar = tagPunctuation "{|" + let rightBraceBar = tagPunctuation "|}" + let arrow = tagPunctuation "->" + let dot = tagPunctuation "." + let leftAngle = tagPunctuation "<" + let rightAngle = tagPunctuation ">" + let colon = tagPunctuation ":" + let minus = tagPunctuation "-" + let keywordTrue = tagKeyword "true" + let keywordFalse = tagKeyword "false" + let structUnit = tagStruct "unit" + let keywordStatic = tagKeyword "static" + let keywordMember = tagKeyword "member" + let keywordVal = tagKeyword "val" + let keywordEvent = tagKeyword "event" + let keywordWith = tagKeyword "with" + let keywordSet = tagKeyword "set" + let keywordGet = tagKeyword "get" + let bar = tagPunctuation "|" + let keywordStruct = tagKeyword "struct" + let keywordInherit = tagKeyword "inherit" + let keywordEnd = tagKeyword "end" + let keywordBegin = tagKeyword "begin" + let keywordNested = tagKeyword "nested" + let keywordType = tagKeyword "type" + let keywordDelegate = tagKeyword "delegate" + let keywordOf = tagKeyword "of" + let keywordInternal = tagKeyword "internal" + let keywordPrivate = tagKeyword "private" + let keywordAbstract = tagKeyword "abstract" + let keywordOverride = tagKeyword "override" + let keywordEnum = tagKeyword "enum" + let leftBracketBar = tagPunctuation "[|" + let rightBracketBar = tagPunctuation "|]" + let keywordTypeof = tagKeyword "typeof" + let keywordTypedefof = tagKeyword "typedefof" + let leftBracketAngle = tagPunctuation "[<" + let rightBracketAngle = tagPunctuation ">]" + let star = tagOperator "*" + let keywordNew = tagKeyword "new" +#endif + +[] +module Layout = + + // constructors + let objL (value:obj) = + match value with + | :? string as s -> Leaf (false, mkTag TextTag.Text s, false) + | o -> ObjLeaf (false, o, false) + + let wordL text = Leaf (false, text, false) + + let sepL text = Leaf (true , text, true) + + let rightL text = Leaf (true , text, false) + + let leftL text = Leaf (false, text, true) + + let emptyL = Leaf (true, mkTag TextTag.Text "", true) + + let isEmptyL layout = + match layout with + | Leaf(true, s, true) -> s.Text = "" + | _ -> false + +#if COMPILER + let rec endsWithL (text: string) layout = + match layout with + | Leaf(_, s, _) -> s.Text.EndsWith(text) + | Node(_, r, _) -> endsWithL text r + | Attr(_, _, l) -> endsWithL text l + | ObjLeaf _ -> false +#endif + + let mkNode l r joint = + if isEmptyL l then r else + if isEmptyL r then l else + Node(l, r, joint) + + let aboveL layout1 layout2 = mkNode layout1 layout2 (Broken 0) + + let tagAttrL text maps layout = Attr(text, maps, layout) + + let apply2 f l r = + if isEmptyL l then r + elif isEmptyL r then l + else f l r + + let (^^) layout1 layout2 = mkNode layout1 layout2 Unbreakable + + let (++) layout1 layout2 = mkNode layout1 layout2 (Breakable 0) + + let (--) layout1 layout2 = mkNode layout1 layout2 (Breakable 1) + + let (---) layout1 layout2 = mkNode layout1 layout2 (Breakable 2) + + let (----) layout1 layout2 = mkNode layout1 layout2 (Breakable 3) + + let (-----) layout1 layout2 = mkNode layout1 layout2 (Breakable 4) + + let (@@) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 0)) layout1 layout2 + + let (@@-) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 1)) layout1 layout2 + + let (@@--) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 2)) layout1 layout2 + + let (@@---) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 3)) layout1 layout2 + + let (@@----) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 4)) layout1 layout2 + + let tagListL tagger els = + match els with + | [] -> emptyL + | [x] -> x + | x :: xs -> + let rec process' prefixL yl = + match yl with + | [] -> prefixL + | y :: ys -> process' (tagger prefixL ++ y) ys + process' x xs + + let commaListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL comma) layouts + + let semiListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL semicolon) layouts + + let spaceListL layouts = tagListL id layouts + + let sepListL layout1 layouts = tagListL (fun prefixL -> prefixL ^^ layout1) layouts + + let bracketL layout = leftL leftParen ^^ layout ^^ rightL rightParen + + let tupleL layouts = bracketL (sepListL (sepL comma) layouts) + + let aboveListL layouts = + match layouts with + | [] -> emptyL + | [x] -> x + | x :: ys -> List.fold (fun pre y -> pre @@ y) x ys + + let optionL selector value = + match value with + | None -> wordL (tagUnionCase "None") + | Some x -> wordL (tagUnionCase "Some") -- (selector x) + + let listL selector value = + leftL leftBracket ^^ sepListL (sepL semicolon) (List.map selector value) ^^ rightL rightBracket + + let squareBracketL layout = + leftL leftBracket ^^ layout ^^ rightL rightBracket + + let braceL layout = + leftL leftBrace ^^ layout ^^ rightL rightBrace + + let boundedUnfoldL + (itemL: 'a -> Layout) + (project: 'z -> ('a * 'z) option) + (stopShort: 'z -> bool) + (z: 'z) + maxLength = + + let rec consume n z = + if stopShort z then [wordL (tagPunctuation "...")] else + match project z with + | None -> [] // exhausted input + | Some (x, z) -> if n<=0 then [wordL (tagPunctuation "...")] // hit print_length limit + else itemL x :: consume (n-1) z // cons recursive... + consume maxLength z + + let unfoldL selector folder state count = + boundedUnfoldL selector folder (fun _ -> false) state count + +/// These are a typical set of options used to control structured formatting. +[] +type FormatOptions = + { FloatingPointFormat: string + AttributeProcessor: string -> (string * string) list -> bool -> unit +#if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter + PrintIntercepts: (IEnvironment -> obj -> Layout option) list + StringLimit: int +#endif + FormatProvider: IFormatProvider + BindingFlags: BindingFlags + PrintWidth: int + PrintDepth: int + PrintLength: int + PrintSize: int + ShowProperties: bool + ShowIEnumerable: bool + } + + static member Default = + { FormatProvider = (CultureInfo.InvariantCulture :> IFormatProvider) +#if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter + PrintIntercepts = [] + StringLimit = Int32.MaxValue +#endif + AttributeProcessor= (fun _ _ _ -> ()) + BindingFlags = BindingFlags.Public + FloatingPointFormat = "g10" + PrintWidth = 80 + PrintDepth = 100 + PrintLength = 100 + PrintSize = 10000 + ShowProperties = false + ShowIEnumerable = true + } + +module ReflectUtils = + + [] + type TypeInfo = + | TupleType of Type list + | FunctionType of Type * Type + | RecordType of (string * Type) list + | SumType of (string * (string * Type) list) list + | UnitType + | ObjectType of Type + + let isNamedType (ty:Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer) + + let equivHeadTypes (ty1:Type) (ty2:Type) = + isNamedType(ty1) && + if ty1.IsGenericType then + ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition()) + else + ty1.Equals(ty2) + + let option = typedefof + + let func = typedefof obj> + + let isOptionTy ty = equivHeadTypes ty typeof + + let isUnitType ty = equivHeadTypes ty typeof + + let isListType ty = + FSharpType.IsUnion ty && + (let cases = FSharpType.GetUnionCases ty + cases.Length > 0 && equivHeadTypes typedefof> cases.[0].DeclaringType) + + [] + type TupleType = + | Value + | Reference + + [] + type ValueInfo = + | TupleValue of TupleType * (obj * Type)[] + | FunctionClosureValue of Type + | RecordValue of (string * obj * Type)[] + | UnionCaseValue of string * (string * (obj * Type))[] + | ExceptionValue of Type * (string * (obj * Type))[] + | NullValue + | UnitValue + | ObjectValue of obj + + module Value = + // Analyze an object to see if it the representation + // of an F# value. + let GetValueInfoOfObject (bindingFlags: BindingFlags) (obj: obj) = + match obj with + | null -> NullValue + | _ -> + let reprty = obj.GetType() + + // First a bunch of special rules for tuples + // Because of the way F# currently compiles tuple values + // of size > 7 we can only reliably reflect on sizes up + // to 7. + + if FSharpType.IsTuple reprty then + let tyArgs = FSharpType.GetTupleElements(reprty) + let fields = FSharpValue.GetTupleFields obj |> Array.mapi (fun i v -> (v, tyArgs.[i])) + let tupleType = + if reprty.Name.StartsWith "ValueTuple" then TupleType.Value + else TupleType.Reference + TupleValue (tupleType, fields) + + elif FSharpType.IsFunction reprty then + FunctionClosureValue reprty + + // It must be exception, abstract, record or union. + // Either way we assume the only properties defined on + // the type are the actual fields of the type. Again, + // we should be reading attributes here that indicate the + // true structure of the type, e.g. the order of the fields. + elif FSharpType.IsUnion(reprty, bindingFlags) then + let tag, vals = FSharpValue.GetUnionFields (obj, reprty, bindingFlags) + let props = tag.GetFields() + let pvals = (props, vals) ||> Array.map2 (fun prop v -> prop.Name, (v, prop.PropertyType)) + UnionCaseValue(tag.Name, pvals) + + elif FSharpType.IsExceptionRepresentation(reprty, bindingFlags) then + let props = FSharpType.GetExceptionFields(reprty, bindingFlags) + let vals = FSharpValue.GetExceptionFields(obj, bindingFlags) + let pvals = (props, vals) ||> Array.map2 (fun prop v -> prop.Name, (v, prop.PropertyType)) + ExceptionValue(reprty, pvals) + + elif FSharpType.IsRecord(reprty, bindingFlags) then + let props = FSharpType.GetRecordFields(reprty, bindingFlags) + RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue (obj, null), prop.PropertyType)) + else + ObjectValue(obj) + + // This one is like the above but can make use of additional + // statically-known type information to aid in the + // analysis of null values. + + let GetValueInfo bindingFlags (x: 'a, ty: Type) (* x could be null *) = + let obj = (box x) + match obj with + | null -> + let isNullaryUnion = + match ty.GetCustomAttributes(typeof, false) with + | [|:? CompilationRepresentationAttribute as attr|] -> + (attr.Flags &&& CompilationRepresentationFlags.UseNullAsTrueValue) = CompilationRepresentationFlags.UseNullAsTrueValue + | _ -> false + if isNullaryUnion then + let nullaryCase = FSharpType.GetUnionCases ty |> Array.filter (fun uc -> uc.GetFields().Length = 0) |> Array.item 0 + UnionCaseValue(nullaryCase.Name, [| |]) + elif isUnitType ty then UnitValue + else NullValue + | _ -> + GetValueInfoOfObject bindingFlags obj + +module Display = + open ReflectUtils + + let string_of_int (i:int) = i.ToString() + + let typeUsesSystemObjectToString (ty:Type) = + try + let methInfo = ty.GetMethod("ToString", BindingFlags.Public ||| BindingFlags.Instance, null, [| |], null) + methInfo.DeclaringType = typeof + with _e -> false + + let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e + + // An implementation of break stack. + // Uses mutable state, relying on linear threading of the state. + + [] + type Breaks = + Breaks of + /// pos of next free slot + nextFreeSlot: int * + /// pos of next possible "outer" break - OR - outer=next if none possible + nextOuterBreak: int * + /// stack of savings, -ve means it has been broken + savingsStack: int[] + + // next is next slot to push into - aka size of current occupied stack. + // outer counts up from 0, and is next slot to break if break forced. + // - if all breaks forced, then outer=next. + // - popping under these conditions needs to reduce outer and next. + + let chunkN = 400 + let breaks0 () = Breaks(0, 0, Array.create chunkN 0) + + let pushBreak saving (Breaks(next, outer, stack)) = + let stack = + if next = stack.Length then + Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full + else + stack + + stack.[next] <- saving; + Breaks(next+1, outer, stack) + + let popBreak (Breaks(next, outer, stack)) = + if next=0 then raise (Failure "popBreak: underflow"); + let topBroke = stack.[next-1] < 0 + let outer = if outer=next then outer-1 else outer // if all broken, unwind + let next = next - 1 + Breaks(next, outer, stack), topBroke + + let forceBreak (Breaks(next, outer, stack)) = + if outer=next then + // all broken + None + else + let saving = stack.[outer] + stack.[outer] <- -stack.[outer]; + let outer = outer+1 + Some (Breaks(next, outer, stack), saving) + + /// fitting + let squashToAux (maxWidth, leafFormatter: _ -> TaggedText) layout = + let (|ObjToTaggedText|) = leafFormatter + if maxWidth <= 0 then layout else + let rec fit breaks (pos, layout) = + // breaks = break context, can force to get indentation savings. + // pos = current position in line + // layout = to fit + //------ + // returns: + // breaks + // layout - with breaks put in to fit it. + // pos - current pos in line = rightmost position of last line of block. + // offset - width of last line of block + // NOTE: offset <= pos -- depending on tabbing of last block + + let breaks, layout, pos, offset = + match layout with + | Attr (tag, attrs, l) -> + let breaks, layout, pos, offset = fit breaks (pos, l) + let layout = Attr (tag, attrs, layout) + breaks, layout, pos, offset + + | Leaf (jl, text, jr) + | ObjLeaf (jl, ObjToTaggedText text, jr) -> + // save the formatted text from the squash + let layout = Leaf(jl, text, jr) + let textWidth = length text + let rec fitLeaf breaks pos = + if pos + textWidth <= maxWidth then + breaks, layout, pos + textWidth, textWidth // great, it fits + else + match forceBreak breaks with + | None -> + breaks, layout, pos + textWidth, textWidth // tough, no more breaks + | Some (breaks, saving) -> + let pos = pos - saving + fitLeaf breaks pos + + fitLeaf breaks pos + + | Node (l, r, joint) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let mid = if jm then 0 else 1 + match joint with + | Unbreakable -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + let pos = pos + mid // fit space if juxt says so + let breaks, r, pos, offsetr = fit breaks (pos, r) // fit right + breaks, Node (l, r, Unbreakable), pos, offsetl + mid + offsetr + + | Broken indent -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + let pos = pos - offsetl + indent // broken so - offset left + ident + let breaks, r, pos, offsetr = fit breaks (pos, r) // fit right + breaks, Node (l, r, Broken indent), pos, indent + offsetr + + | Breakable indent -> + let breaks, l, pos, offsetl = fit breaks (pos, l) // fit left + // have a break possibility, with saving + let saving = offsetl + mid - indent + let pos = pos + mid + if saving>0 then + let breaks = pushBreak saving breaks + let breaks, r, pos, offsetr = fit breaks (pos, r) + let breaks, broken = popBreak breaks + if broken then + breaks, Node (l, r, Broken indent) , pos, indent + offsetr + else + breaks, Node (l, r, Breakable indent), pos, offsetl + mid + offsetr + else + // actually no saving so no break + let breaks, r, pos, offsetr = fit breaks (pos, r) + breaks, Node (l, r, Breakable indent) , pos, offsetl + mid + offsetr + + //printf "\nDone: pos=%d offset=%d" pos offset; + breaks, layout, pos, offset + + let breaks = breaks0 () + let pos = 0 + let _, layout, _, _ = fit breaks (pos, layout) + layout + + let combine (strs: string list) = String.Concat strs + + let showL opts leafFormatter layout = + let push x rstrs = x :: rstrs + let z0 = [], 0 + let addText (rstrs, i) (text:string) = push text rstrs, i + text.Length + let index (_, i) = i + let extract rstrs = combine(List.rev rstrs) + let newLine (rstrs, _) n = // \n then spaces... + let indent = String(' ', n) + let rstrs = push "\n" rstrs + let rstrs = push indent rstrs + rstrs, n + + // addL: pos is tab level + let rec addL z pos layout = + match layout with + | ObjLeaf (_, obj, _) -> + let text = leafFormatter obj + addText z text + + | Leaf (_, obj, _) -> + addText z obj.Text + + | Node (l, r, Broken indent) + // Print width = 0 implies 1D layout, no squash + when not (opts.PrintWidth = 0) -> + let z = addL z pos l + let z = newLine z (pos+indent) + let z = addL z (pos+indent) r + z + + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let z = addL z pos l + let z = if jm then z else addText z " " + let pos = index z + let z = addL z pos r + z + + | Attr (_, _, l) -> + addL z pos l + + let rstrs, _ = addL z0 0 layout + extract rstrs + + let outL outAttribute leafFormatter (chan: TaggedTextWriter) layout = + // write layout to output chan directly + let write s = chan.Write(s) + // z is just current indent + let z0 = 0 + let index i = i + let addText z text = write text; (z + length text) + let newLine _ n = // \n then spaces... + let indent = String(' ', n) + chan.WriteLine(); + write (tagText indent); + n + + // addL: pos is tab level + let rec addL z pos layout = + match layout with + | ObjLeaf (_, obj, _) -> + let text = leafFormatter obj + addText z text + | Leaf (_, obj, _) -> + addText z obj + | Node (l, r, Broken indent) -> + let z = addL z pos l + let z = newLine z (pos+indent) + let z = addL z (pos+indent) r + z + | Node (l, r, _) -> + let jm = Layout.JuxtapositionMiddle (l, r) + let z = addL z pos l + let z = if jm then z else addText z space + let pos = index z + let z = addL z pos r + z + | Attr (tag, attrs, l) -> + let _ = outAttribute tag attrs true + let z = addL z pos l + let _ = outAttribute tag attrs false + z + + let _ = addL z0 0 layout + () + + let unpackCons recd = + match recd with + | [|(_, h);(_, t)|] -> (h, t) + | _ -> failwith "unpackCons" + + let getListValueInfo bindingFlags (x:obj, ty:Type) = + match x with + | null -> None + | _ -> + match Value.GetValueInfo bindingFlags (x, ty) with + | UnionCaseValue ("Cons", recd) -> Some (unpackCons recd) + | UnionCaseValue ("Empty", [| |]) -> None + | _ -> failwith "List value had unexpected ValueInfo" + + let structL = wordL (tagKeyword "struct") + + let nullL = wordL (tagKeyword "null") + + let unitL = wordL (tagPunctuation "()") + + let makeRecordL nameXs = + let itemL (name, xL) = (wordL name ^^ wordL equals) -- xL + let braceL xs = (wordL leftBrace) ^^ xs ^^ (wordL rightBrace) + + nameXs + |> List.map itemL + |> aboveListL + |> braceL + + let makePropertiesL nameXs = + let itemL (name, v) = + let labelL = wordL name + (labelL ^^ wordL equals) + ^^ (match v with + | None -> wordL questionMark + | Some xL -> xL) + ^^ (rightL semicolon) + let braceL xs = (leftL leftBrace) ^^ xs ^^ (rightL rightBrace) + braceL (aboveListL (List.map itemL nameXs)) + + let makeListL itemLs = + (leftL leftBracket) + ^^ sepListL (rightL semicolon) itemLs + ^^ (rightL rightBracket) + + let makeArrayL xs = + (leftL (tagPunctuation "[|")) + ^^ sepListL (rightL semicolon) xs + ^^ (rightL (tagPunctuation "|]")) + + let makeArray2L xs = leftL leftBracket ^^ aboveListL xs ^^ rightL rightBracket + + let getProperty (ty: Type) (obj: obj) name = + ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture) + + let getField obj (fieldInfo: FieldInfo) = + fieldInfo.GetValue(obj) + + let formatChar isChar c = + match c with + | '\'' when isChar -> "\\\'" + | '\"' when not isChar -> "\\\"" + | '\\' -> "\\\\" + | '\b' -> "\\b" + | _ when Char.IsControl(c) -> + let d1 = (int c / 100) % 10 + let d2 = (int c / 10) % 10 + let d3 = int c % 10 + "\\" + d1.ToString() + d2.ToString() + d3.ToString() + | _ -> c.ToString() + + let formatString (s:string) = + let rec check i = i < s.Length && not (Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) + let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc) + "\"" + s + "\"" + + // Return a truncated version of the string, e.g. + // "This is the initial text, which has been truncated"+[12 chars] + // + // Note: The layout code forces breaks based on leaf size and possible break points. + // It does not force leaf size based on width. + // So long leaf-string width can not depend on their printing context... + // + // The suffix like "+[dd chars]" is 11 chars. + // 12345678901 + let formatStringInWidth (width:int) (str:string) = + let suffixLength = 11 // turning point suffix length + let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings... + let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength + "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]" + + type Precedence = + | BracketIfTupleOrNotAtomic = 2 + | BracketIfTuple = 3 + | NeverBracket = 4 + + // In fsi.exe, certain objects are not printed for top-level bindings. + [] + type ShowMode = + | ShowAll + | ShowTopLevelBinding + + let isSetOrMapType (ty:Type) = + ty.IsGenericType && + (ty.GetGenericTypeDefinition() = typedefof> + || ty.GetGenericTypeDefinition() = typedefof>) + + // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe, + // This allows certain outputs, e.g. objects that would print as to be suppressed, etc. See 4343. + // Calls to layout proper sub-objects should pass showMode = ShowAll. + // + // Precedences to ensure we add brackets in the right places + type ObjectGraphFormatter(opts: FormatOptions, bindingFlags) = + + // Keep a record of objects encountered along the way + let path = Dictionary(10,HashIdentity.Reference) + + // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma. + let mutable size = opts.PrintSize + let exceededPrintSize() = size<=0 + let countNodes n = if size > 0 then size <- size - n else () // no need to keep decrementing (and avoid wrap around) + let stopShort _ = exceededPrintSize() // for unfoldL + + // Recursive descent + let rec nestedObjL depthLim prec (x:obj, ty:Type) = + objL ShowAll depthLim prec (x, ty) + + and objL showMode depthLim prec (x:obj, ty:Type) = + let info = Value.GetValueInfo bindingFlags (x, ty) + try + if depthLim<=0 || exceededPrintSize() then wordL (tagPunctuation "...") else + match x with + | null -> + reprL showMode (depthLim-1) prec info x + | _ -> + if (path.ContainsKey(x)) then + wordL (tagPunctuation "...") + else + path.Add(x,0) + + let res = + // Lazy values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case. + let ty = x.GetType() + if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof> then + Some (wordL (tagText(x.ToString()))) + else + // Try the StructuredFormatDisplayAttribute extensibility attribute + match ty.GetCustomAttributes (typeof, true) with + | null | [| |] -> None + | res -> + structuredFormatObjectL showMode ty depthLim (res.[0] :?> StructuredFormatDisplayAttribute) x + +#if COMPILER + // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter + let res = + match res with + | Some _ -> res + | None -> + let env = + { new IEnvironment with + member _.GetLayout(y) = nestedObjL (depthLim-1) Precedence.BracketIfTuple (y, y.GetType()) + member _.MaxColumns = opts.PrintLength + member _.MaxRows = opts.PrintLength } + opts.PrintIntercepts |> List.tryPick (fun intercept -> intercept env x) +#endif + let res = + match res with + | Some res -> res + | None -> reprL showMode (depthLim-1) prec info x + + path.Remove(x) |> ignore + res + with + e -> + countNodes 1 + wordL (tagText("Error: " + e.Message)) + + // Format an object that has a layout specified by StructuredFormatAttribute + and structuredFormatObjectL showMode ty depthLim (attr: StructuredFormatDisplayAttribute) (obj: obj) = + let txt = attr.Value + if isNull txt || txt.Length <= 1 then + None + else + let messageRegexPattern = @"^(?
.*?)(?.*?)(?.*)$"
+            let illFormedBracketPattern = @"(? 1 then Some (spaceListL (List.rev (wordL (tagText(replaceEscapedBrackets(txt))) :: layouts)))
+                    else Some (wordL (tagText(replaceEscapedBrackets(txt))))
+                else
+                    // we have a hit on a property reference
+                    let preText = replaceEscapedBrackets(m.Groups.["pre"].Value) // everything before the first opening bracket
+                    let postText = m.Groups.["post"].Value // Everything after the closing bracket
+                    let prop = replaceEscapedBrackets(m.Groups.["prop"].Value) // Unescape everything between the opening and closing brackets
+
+                    match catchExn (fun () -> getProperty ty obj prop) with
+                    | Choice2Of2 e -> Some (wordL (tagText("")))
+                    | Choice1Of2 alternativeObj ->
+                        try 
+                            let alternativeObjL = 
+                                match alternativeObj with 
+                                // A particular rule is that if the alternative property
+                                // returns a string, we turn off auto-quoting and escaping of
+                                // the string, i.e. just treat the string as display text.
+                                // This allows simple implementations of 
+                                // such as
+                                //
+                                //    []
+                                //    type BigInt(signInt:int, v: BigNat) =
+                                //        member x.StructuredDisplayString = x.ToString()
+                                //
+                                | :? string as s -> sepL (tagText s)
+                                | _ -> 
+                                    // recursing like this can be expensive, so let's throttle it severely
+                                    objL showMode (depthLim/10) Precedence.BracketIfTuple (alternativeObj, alternativeObj.GetType())
+                            countNodes 0 // 0 means we do not count the preText and postText 
+
+                            let postTextMatch = System.Text.RegularExpressions.Regex.Match(postText, messageRegexPattern)
+                            // the postText for this node will be everything up to the next occurrence of an opening brace, if one exists
+                            let currentPostText =
+                                match postTextMatch.Success with
+                                | false -> postText 
+                                | true -> postTextMatch.Groups.["pre"].Value
+
+                            let newLayouts = (sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText currentPostText)) :: layouts
+                            match postText with
+                            | "" ->
+                                //We are done, build a space-delimited layout from the collection of layouts we've accumulated
+                                Some (spaceListL (List.rev newLayouts))
+
+                            | remainingPropertyText when postTextMatch.Success ->
+                                                      
+                                // look for stray brackets in the text before the next opening bracket
+                                let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(postTextMatch.Groups.["pre"].Value, illFormedBracketPattern)
+                                if strayClosingMatch then
+                                    None
+                                else 
+                                    // More to process, keep going, using the postText starting at the next instance of a '{'
+                                    let openingBracketIndex = postTextMatch.Groups.["prop"].Index-1
+                                    buildObjMessageL remainingPropertyText.[openingBracketIndex..] newLayouts
+
+                            | remaingPropertyText ->
+                                // make sure we don't have any stray brackets
+                                let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(remaingPropertyText, illFormedBracketPattern)
+                                if strayClosingMatch then
+                                    None
+                                else
+                                    // We are done, there's more text but it doesn't contain any more properties, we need to remove escaped brackets now though
+                                    // since that wasn't done when creating currentPostText
+                                    Some (spaceListL (List.rev ((sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText(replaceEscapedBrackets(remaingPropertyText)))) :: layouts)))
+                        with _ -> 
+                            None
+
+            // Seed with an empty layout with a space to the left for formatting purposes
+            buildObjMessageL txt [leftL (tagText "")] 
+
+        and recdAtomicTupleL depthLim recd =
+            // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
+            match recd with 
+            | [(_,x)] -> nestedObjL depthLim Precedence.BracketIfTupleOrNotAtomic x 
+            | txs -> leftL leftParen ^^ commaListL (List.map (snd >> nestedObjL depthLim Precedence.BracketIfTuple) txs) ^^ rightL rightParen
+
+        and bracketIfL flag basicL =
+            if flag then (leftL leftParen) ^^ basicL ^^ (rightL rightParen) else basicL
+
+        and tupleValueL depthLim prec vals tupleType =
+            let basicL = sepListL (rightL comma) (List.map (nestedObjL depthLim Precedence.BracketIfTuple ) (Array.toList vals))
+            let fields = bracketIfL (prec <= Precedence.BracketIfTuple) basicL
+            match tupleType with
+            | TupleType.Value -> structL ^^ fields
+            | TupleType.Reference -> fields
+
+        and recordValueL depthLim items =
+            let itemL (name, x, ty) =
+                countNodes 1
+                tagRecordField name,nestedObjL depthLim Precedence.BracketIfTuple (x, ty)
+            makeRecordL (List.map itemL items)
+
+        and listValueL depthLim constr recd =
+            match constr with 
+            | "Cons" -> 
+                let x,xs = unpackCons recd
+                let project xs = getListValueInfo bindingFlags xs
+                let itemLs = nestedObjL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
+                makeListL itemLs
+            | _ ->
+                countNodes 1
+                wordL (tagPunctuation "[]")
+
+        and unionCaseValueL depthLim prec unionCaseName recd =
+            countNodes 1
+            let caseName = wordL (tagMethod unionCaseName)
+            match recd with
+            | [] -> caseName
+            | recd -> (caseName --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+        and fsharpExceptionL depthLim prec (exceptionType: Type) recd =
+            countNodes 1
+            let name = exceptionType.Name 
+            match recd with
+            | [] -> (wordL (tagClass name))
+            | recd -> (wordL (tagClass name) --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+        and showModeFilter showMode layout =
+            match showMode with
+            | ShowAll -> layout
+            | ShowTopLevelBinding -> emptyL                                                             
+
+        and functionClosureL showMode (closureType: Type) =
+            // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
+            countNodes 1
+            wordL (tagText("")) |> showModeFilter showMode
+
+        and stringValueL (s: string) =
+            countNodes 1
+#if COMPILER  
+            if s.Length + 2(*quotes*) <= opts.StringLimit then
+                // With the quotes, it fits within the limit.
+                wordL (tagStringLiteral(formatString s))
+            else
+                // When a string is considered too long to print, there is a choice: what to print?
+                // a)             -- follows 
+                // b)      -- follows  and gives just the length
+                // c) "abcdefg"+[n chars] -- gives a prefix and the remaining chars
+                wordL (tagStringLiteral(formatStringInWidth opts.StringLimit s))
+#else
+            wordL (tagStringLiteral (formatString s))  
+#endif                   
+
+        and arrayValueL depthLim (arr: Array) =
+            let ty = arr.GetType().GetElementType()
+            match arr.Rank with
+            | 1 -> 
+                let n = arr.Length
+                let b1 = arr.GetLowerBound(0) 
+                let project depthLim = if depthLim=(b1+n) then None else Some ((box (arr.GetValue(depthLim)), ty),depthLim+1)
+                let itemLs = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
+                makeArrayL (if b1 = 0 then itemLs else wordL (tagText("bound1="+string_of_int b1)) :: itemLs)
+            | 2 -> 
+                let n1 = arr.GetLength(0)
+                let n2 = arr.GetLength(1)
+                let b1 = arr.GetLowerBound(0) 
+                let b2 = arr.GetLowerBound(1) 
+                let project2 x y =
+                    if x>=(b1+n1) || y>=(b2+n2) then None
+                    else Some ((box (arr.GetValue(x,y)), ty),y+1)
+                let rowL x = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
+                let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
+                let rowsL = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
+                makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL (tagText("bound1=" + string_of_int b1)) :: wordL(tagText("bound2=" + string_of_int b2)) :: rowsL)
+            | n -> 
+                makeArrayL [wordL (tagText("rank=" + string_of_int n))]
+                        
+        and mapSetValueL depthLim prec (ty: Type) (obj: obj) =
+            let word = if ty.GetGenericTypeDefinition() = typedefof> then "map" else "set"
+            let possibleKeyValueL v = 
+                let tyv = v.GetType()
+                if word = "map" &&
+                    (match v with null -> false | _ -> true) && 
+                    tyv.IsGenericType && 
+                    tyv.GetGenericTypeDefinition() = typedefof> then
+                    nestedObjL depthLim Precedence.BracketIfTuple ((tyv.GetProperty("Key").GetValue(v, [| |]), 
+                                                                    tyv.GetProperty("Value").GetValue(v, [| |])), tyv)
+                else
+                    nestedObjL depthLim Precedence.BracketIfTuple (v, tyv)
+            let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
+            try 
+                let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
+                (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+            finally 
+                match it with 
+                | :? IDisposable as e -> e.Dispose()
+                | _ -> ()
+
+        and sequenceValueL showMode depthLim prec (ie: System.Collections.IEnumerable) =
+            let showContent = 
+                // do not display content of IQueryable since its execution may take significant time
+                opts.ShowIEnumerable && (ie.GetType().GetInterfaces() |> Array.exists(fun ty -> ty.FullName = "System.Linq.IQueryable") |> not)
+
+            if showContent then
+                let word = "seq"
+                let it = ie.GetEnumerator() 
+                let ty = ie.GetType().GetInterfaces() |> Array.filter (fun ty -> ty.IsGenericType && ty.Name = "IEnumerable`1") |> Array.tryItem 0
+                let ty = Option.map (fun (ty:Type) -> ty.GetGenericArguments().[0]) ty
+                try 
+                    let itemLs = boundedUnfoldL (nestedObjL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some((it.Current, match ty with | None -> it.Current.GetType() | Some ty -> ty),()) else None) stopShort () (1+opts.PrintLength/30)
+                    (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                finally 
+                    match it with 
+                    | :? IDisposable as e -> e.Dispose()
+                    | _ -> ()
+                             
+            else
+                // Sequence printing is turned off for declared-values, and maybe be disabled to users.
+                // There is choice here, what to print?  or ... or ?
+                // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
+                wordL (tagText "") |> showModeFilter showMode
+
+        and objectValueWithPropertiesL depthLim (ty: Type) (obj: obj) =
+
+            // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+            let basicL = Layout.objL obj
+            let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
+            let fields = ty.GetFields(BindingFlags.Instance ||| BindingFlags.Public) |> Array.map (fun i -> i :> MemberInfo)
+            let propsAndFields = 
+                props |> Array.map (fun i -> i :> MemberInfo)
+                        |> Array.append fields
+                        |> Array.filter (fun pi ->
+                    // check if property is annotated with System.Diagnostics.DebuggerBrowsable(Never). 
+                    // Its evaluation may have unexpected side effects and\or block printing.
+                    match Seq.toArray (pi.GetCustomAttributes(typeof, false)) with
+                    | [|:? System.Diagnostics.DebuggerBrowsableAttribute as attr |] -> attr.State <> System.Diagnostics.DebuggerBrowsableState.Never
+                    | _ -> true
+                )
+
+            // massively reign in deep printing of properties 
+            let nDepth = depthLim/10
+#if NETSTANDARD
+            Array.Sort(propsAndFields,{ new IComparer with member this.Compare(p1,p2) = compare p1.Name p2.Name } )
+#else
+            Array.Sort((propsAndFields :> Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> MemberInfo).Name) ((p2 :?> MemberInfo).Name) } )
+#endif
+
+            if propsAndFields.Length = 0 || (nDepth <= 0) then basicL 
+            else basicL --- 
+                    (propsAndFields 
+                    |> Array.map 
+                    (fun m -> 
+                        ((if m :? FieldInfo then tagField m.Name else tagProperty m.Name),
+                            (try Some (nestedObjL nDepth Precedence.BracketIfTuple ((getProperty ty obj m.Name), ty)) 
+                                with _ -> 
+                                try Some (nestedObjL nDepth Precedence.BracketIfTuple ((getField obj (m :?> FieldInfo)), ty)) 
+                                with _ -> None)))
+                    |> Array.toList 
+                    |> makePropertiesL)
+
+        and reprL showMode depthLim prec repr x (* x could be null *) =
+            match repr with
+            | TupleValue (tupleType, vals) ->
+                tupleValueL depthLim prec vals tupleType
+
+            | RecordValue items -> 
+                recordValueL depthLim (Array.toList items)
+
+            | UnionCaseValue (constr,recd) when // x is List. Note: "null" is never a valid list value. 
+                                                    x<>null && isListType (x.GetType()) ->
+                listValueL depthLim constr recd
+
+            | UnionCaseValue(unionCaseName, recd) ->
+                unionCaseValueL depthLim prec unionCaseName (Array.toList recd)
+
+            | ExceptionValue(exceptionType, recd) ->
+                fsharpExceptionL depthLim prec exceptionType (Array.toList recd)
+
+            | FunctionClosureValue closureType ->
+                functionClosureL showMode closureType
+
+            | UnitValue ->
+                countNodes 1
+                unitL
+
+            | NullValue ->
+                countNodes 1
+                // If this is the root element, wrap the null with angle brackets
+                if depthLim = opts.PrintDepth - 1 then
+                    wordL (tagText "")
+                else nullL
+
+            | ObjectValue obj ->
+                let ty = obj.GetType()
+                match obj with 
+                | :? string as s ->
+                    stringValueL s
+
+                | :? Array as arr ->
+                    arrayValueL depthLim arr
+
+                | _ when isSetOrMapType ty ->
+                    mapSetValueL depthLim prec ty obj
+
+                | :? System.Collections.IEnumerable as ie ->
+                    sequenceValueL showMode depthLim prec ie
+
+                | _ when showMode = ShowTopLevelBinding && typeUsesSystemObjectToString ty ->
+                    emptyL 
+
+                | _ when opts.ShowProperties -> 
+                    countNodes 1
+                    objectValueWithPropertiesL depthLim (ty: Type) (obj: obj)
+
+                | _ ->
+                    countNodes 1
+                    // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+                    Layout.objL obj
+
+        member _.Format(showMode, x:'a, xty:Type) =
+            objL showMode opts.PrintDepth  Precedence.BracketIfTuple (x, xty)
+
+    let leafFormatter (opts:FormatOptions) (obj :obj) =
+        match obj with 
+        | null -> tagKeyword "null"
+        | :? double as d -> 
+            let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
+            let t = 
+                if Double.IsNaN(d) then "nan"
+                elif Double.IsNegativeInfinity(d) then "-infinity"
+                elif Double.IsPositiveInfinity(d) then "infinity"
+                elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> Char.IsDigit(c) || c = '-')  s
+                then s + ".0" 
+                else s
+            tagNumericLiteral t
+
+        | :? single as d -> 
+            let t =
+                (if Single.IsNaN(d) then "nan"
+                    elif Single.IsNegativeInfinity(d) then "-infinity"
+                    elif Single.IsPositiveInfinity(d) then "infinity"
+                    elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
+                    && float32(Int32.MinValue) < d && d < float32(Int32.MaxValue) 
+                    && float32(int32(d)) = d 
+                    then (Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
+                    else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
+                + "f"
+            tagNumericLiteral t
+
+        | :? decimal as d -> d.ToString("g",opts.FormatProvider) + "M" |> tagNumericLiteral
+        | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL" |> tagNumericLiteral
+        | :? int64  as d -> d.ToString(opts.FormatProvider) + "L" |> tagNumericLiteral
+        | :? int32  as d -> d.ToString(opts.FormatProvider) |> tagNumericLiteral
+        | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u" |> tagNumericLiteral
+        | :? int16  as d -> d.ToString(opts.FormatProvider) + "s" |> tagNumericLiteral
+        | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us" |> tagNumericLiteral
+        | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y" |> tagNumericLiteral
+        | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy" |> tagNumericLiteral
+        | :? nativeint as d -> d.ToString() + "n" |> tagNumericLiteral
+        | :? unativeint  as d -> d.ToString() + "un" |> tagNumericLiteral
+        | :? bool   as b -> (if b then "true" else "false") |> tagKeyword
+        | :? char   as c -> "\'" + formatChar true c + "\'" |> tagStringLiteral
+
+        | _ -> 
+            let t = 
+                try 
+                    let text = obj.ToString()
+                    match text with
+                    | null -> ""
+                    | _ -> text
+                with e ->
+                    // If a .ToString() call throws an exception, catch it and use the message as the result.
+                    // This may be informative, e.g. division by zero etc...
+                    "" 
+            tagText t
+
+    let any_to_layout options (value, typValue) =
+        let formatter = ObjectGraphFormatter(options, BindingFlags.Public) 
+        formatter.Format(ShowAll, value, typValue)
+
+    let squashTo width layout = 
+       layout |> squashToAux (width, leafFormatter FormatOptions.Default)
+
+    let squash_layout options layout = 
+        // Print width = 0 implies 1D layout, no squash
+        if options.PrintWidth = 0 then 
+            layout 
+        else 
+            layout |> squashToAux (options.PrintWidth,leafFormatter options)
+
+    let asTaggedTextWriter (writer: TextWriter) =
+        { new TaggedTextWriter with
+            member _.Write(t) = writer.Write t.Text
+            member _.WriteLine() = writer.WriteLine() }
+
+    let output_layout_tagged options writer layout = 
+        layout |> squash_layout options 
+            |> outL options.AttributeProcessor (leafFormatter options) writer
+
+    let output_layout options writer layout = 
+        output_layout_tagged options (asTaggedTextWriter writer) layout
+
+    let layout_to_string options layout = 
+        layout |> squash_layout options 
+            |> showL options ((leafFormatter options) >> toText)
+
+    let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
+
+    let output_any writer x = output_any_ex FormatOptions.Default writer x
+
+    let layout_as_string options x = x |> any_to_layout options |> layout_to_string options
+
+    let any_to_string x = layout_as_string FormatOptions.Default x
+
+#if COMPILER
+    let fsi_any_to_layout options (value, typValue) =
+        let formatter = ObjectGraphFormatter(options, BindingFlags.Public) 
+        formatter.Format (ShowTopLevelBinding, value, typValue)
+#else
+    let internal anyToStringForPrintf options (bindingFlags:BindingFlags) (value, typValue) = 
+        let formatter = ObjectGraphFormatter(options, bindingFlags) 
+        formatter.Format (ShowAll, value, typValue) |> layout_to_string options
+#endif
+
diff --git a/src/fsharp/utils/sformat.fsi b/src/fsharp/utils/sformat.fsi
new file mode 100644
index 00000000000..31de2b6b39a
--- /dev/null
+++ b/src/fsharp/utils/sformat.fsi
@@ -0,0 +1,403 @@
+// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
+
+// This file is compiled twice in the codebase
+//    - as the internal implementation of printf '%A' formatting 
+//    - as the internal implementation of structured formatting in FSharp.Compiler.Service/Private.dll 
+//           defines: COMPILER 
+//           NOTE: this implementation is used by fsi.exe. 
+//
+// The one implementation file is used to keep the implementations of
+// structured formatting the same for fsi.exe and '%A' printing. However fsi.exe may have
+// a richer feature set.
+//
+// Note no layout objects are ever transferred between the above implementations.
+
+#if COMPILER
+namespace FSharp.Compiler.Text
+#else
+namespace Microsoft.FSharp.Text.StructuredPrintfImpl
+#endif
+
+    open System
+    open System.IO
+    open Microsoft.FSharp.Core
+    open Microsoft.FSharp.Collections
+
+#if COMPILER
+
+    /// Data representing joints in structured layouts of terms.  The representation
+    /// of this data type is only for the consumption of formatting engines.
+    []
+    type internal Joint =
+        | Unbreakable
+        | Breakable of indentation: int
+        | Broken of indentation: int
+    
+    /// Represents the tag of some tagged text
+    []
+    type TextTag =
+        | ActivePatternCase
+        | ActivePatternResult
+        | Alias
+        | Class
+        | Union
+        | UnionCase
+        | Delegate
+        | Enum
+        | Event
+        | Field
+        | Interface
+        | Keyword
+        | LineBreak
+        | Local
+        | Record
+        | RecordField
+        | Method
+        | Member
+        | ModuleBinding
+        | Function
+        | Module
+        | Namespace
+        | NumericLiteral
+        | Operator
+        | Parameter
+        | Property
+        | Space
+        | StringLiteral
+        | Struct
+        | TypeParameter
+        | Text
+        | Punctuation
+        | UnknownType
+        | UnknownEntity
+
+    /// Represents text with a tag
+    type public TaggedText =
+        /// Creates text with a tag
+        new: tag: TextTag * text: string -> TaggedText
+
+        /// Gets the tag
+        member Tag: TextTag
+
+        /// Gets the text
+        member Text: string
+    
+    type internal TaggedTextWriter =
+        abstract Write: t: TaggedText -> unit
+        abstract WriteLine: unit -> unit
+
+    /// Data representing structured layouts of terms.
+    []
+    type internal Layout =
+        | ObjLeaf of juxtLeft: bool * object: obj * juxtRight: bool
+        | Leaf of juxtLeft: bool * text: TaggedText * juxtRight: bool
+        | Node of leftLayout: Layout * rightLayout: Layout * joint: Joint
+        | Attr of text: string * attributes: (string * string) list * layout: Layout
+
+        static member internal JuxtapositionMiddle: left: Layout * right: Layout -> bool
+
+#else  // FSharp.Compiler.Service.dll, fsc.exe
+    /// Data representing structured layouts of terms.  
+    // FSharp.Core.dll makes things internal and hides representations
+    type internal Layout
+
+    type internal TextTag
+
+    []
+    type internal TaggedText =
+        member Tag: TextTag
+        member Text: string
+#endif
+
+#if COMPILER
+    module public TaggedText =
+#else
+    module internal TaggedText =
+#endif
+        val tagText: string -> TaggedText
+        val tagClass: string -> TaggedText
+        val internal tagField: string -> TaggedText
+        val internal tagKeyword: string -> TaggedText
+        val internal tagLocal: string -> TaggedText
+        val internal tagProperty: string -> TaggedText
+        val internal tagMethod: string -> TaggedText
+        val internal tagUnionCase: string -> TaggedText
+
+        val comma: TaggedText
+
+#if COMPILER
+        val tagNamespace: string -> TaggedText
+        val tagParameter: string -> TaggedText
+        val tagSpace: string -> TaggedText
+
+        // common tagged literals
+        val dot: TaggedText
+        val colon: TaggedText
+        val minus: TaggedText
+        val lineBreak: TaggedText
+        val space: TaggedText
+
+        val internal mkTag: TextTag -> string -> TaggedText
+        val internal keywordFunctions: Set
+        val internal tagAlias: string -> TaggedText
+        val internal tagDelegate: string -> TaggedText
+        val internal tagEnum: string -> TaggedText
+        val internal tagEvent: string -> TaggedText
+        val internal tagInterface: string -> TaggedText
+        val internal tagLineBreak: string -> TaggedText
+        val internal tagModuleBinding: string -> TaggedText
+        val internal tagFunction: string -> TaggedText
+        val internal tagRecord: string -> TaggedText
+        val internal tagRecordField: string -> TaggedText
+        val internal tagModule: string -> TaggedText
+        val internal tagNumericLiteral: string -> TaggedText
+        val internal tagOperator: string -> TaggedText
+        val internal tagStringLiteral: string -> TaggedText
+        val internal tagStruct: string -> TaggedText
+        val internal tagTypeParameter: string -> TaggedText
+        val internal tagPunctuation: string -> TaggedText
+        val internal tagActivePatternCase: string -> TaggedText
+        val internal tagActivePatternResult: string -> TaggedText
+        val internal tagUnion: string -> TaggedText
+        val internal tagMember: string -> TaggedText
+        val internal tagUnknownEntity: string -> TaggedText
+        val internal tagUnknownType: string -> TaggedText
+
+        val internal leftAngle: TaggedText
+        val internal rightAngle: TaggedText
+        val internal keywordTrue: TaggedText
+        val internal keywordFalse: TaggedText
+        val internal semicolon: TaggedText
+        val internal leftParen: TaggedText
+        val internal rightParen: TaggedText
+        val internal leftBracket: TaggedText
+        val internal rightBracket: TaggedText
+        val internal leftBrace: TaggedText
+        val internal rightBrace: TaggedText
+        val internal leftBraceBar: TaggedText
+        val internal rightBraceBar: TaggedText
+        val internal equals: TaggedText
+        val internal arrow: TaggedText
+        val internal questionMark: TaggedText
+        val internal structUnit: TaggedText
+        val internal keywordStatic: TaggedText
+        val internal keywordMember: TaggedText
+        val internal keywordVal: TaggedText
+        val internal keywordEvent: TaggedText
+        val internal keywordWith: TaggedText
+        val internal keywordSet: TaggedText
+        val internal keywordGet: TaggedText
+        val internal bar: TaggedText
+        val internal keywordStruct: TaggedText
+        val internal keywordInherit: TaggedText
+        val internal keywordBegin: TaggedText
+        val internal keywordEnd: TaggedText
+        val internal keywordNested: TaggedText
+        val internal keywordType: TaggedText
+        val internal keywordDelegate: TaggedText
+        val internal keywordOf: TaggedText
+        val internal keywordInternal: TaggedText
+        val internal keywordPrivate: TaggedText
+        val internal keywordAbstract: TaggedText
+        val internal keywordOverride: TaggedText
+        val internal keywordEnum: TaggedText
+        val internal leftBracketBar: TaggedText
+        val internal rightBracketBar: TaggedText
+        val internal keywordTypeof: TaggedText
+        val internal keywordTypedefof: TaggedText
+        val internal leftBracketAngle: TaggedText
+        val internal rightBracketAngle: TaggedText
+        val internal star: TaggedText
+        val internal keywordNew: TaggedText
+
+    type internal IEnvironment = 
+        /// Return to the layout-generation 
+        /// environment to layout any otherwise uninterpreted object
+        abstract GetLayout: obj -> Layout
+
+        /// The maximum number of elements for which to generate layout for 
+        /// list-like structures, or columns in table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxColumns: int
+
+        /// The maximum number of rows for which to generate layout for table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxRows: int
+#endif
+      
+    /// A layout is a sequence of strings which have been joined together.
+    /// The strings are classified as words, separators and left and right parenthesis.
+    /// This classification determines where spaces are inserted.
+    /// A joint is either unbreakable, breakable or broken.
+    /// If a joint is broken the RHS layout occurs on the next line with optional indentation.
+    /// A layout can be squashed to for given width which forces breaks as required.
+    module internal Layout =
+        /// The empty layout
+        val emptyL: Layout
+
+        /// Is it the empty layout?
+        val isEmptyL: layout:Layout -> bool
+
+#if COMPILER
+        /// Check if the last character in the layout is the given character
+        val endsWithL: text: string -> layout: Layout -> bool
+#endif
+
+        /// An uninterpreted leaf, to be interpreted into a string
+        /// by the layout engine. This allows leaf layouts for numbers, strings and
+        /// other atoms to be customized according to culture.
+        val objL  : value:obj -> Layout
+
+        /// An string leaf 
+        val wordL : text:TaggedText -> Layout
+
+        /// An string which requires no spaces either side.
+        val sepL  : text:TaggedText -> Layout
+
+        /// An string which is right parenthesis (no space on the left).
+        val rightL: text:TaggedText -> Layout
+
+        /// An string which is left  parenthesis (no space on the right).
+        val leftL : text:TaggedText -> Layout
+
+        /// Join, unbreakable. 
+        val ( ^^ ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join, possible break with indent=0
+        val ( ++ ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join, possible break with indent=1
+        val ( -- ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join, possible break with indent=2 
+        val ( --- ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// optional break, indent=3
+        val internal ( ---- )              : Layout -> Layout -> Layout
+
+        /// optional break, indent=4
+        val internal ( ----- )             : Layout -> Layout -> Layout
+
+        /// Join broken with ident=0
+        val ( @@ ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join broken with ident=1 
+        val ( @@- ): layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join broken with ident=2 
+        val ( @@-- ): layout1:Layout -> layout2:Layout -> Layout   
+        
+        /// Join broken with ident=3 
+        val (@@---): layout1:Layout -> layout2:Layout -> Layout  
+            
+            /// Join broken with ident=4
+        val (@@----): layout1:Layout -> layout2:Layout -> Layout  
+
+        /// Join layouts into a comma separated list.
+        val commaListL: layouts:Layout list -> Layout
+          
+        /// Join layouts into a space separated list.    
+        val spaceListL: layouts:Layout list -> Layout
+          
+        /// Join layouts into a semi-colon separated list.
+        val semiListL: layouts:Layout list -> Layout
+
+        /// Join layouts into a list separated using the given Layout.
+        val sepListL: layout1:Layout -> layouts:Layout list -> Layout
+
+        /// Wrap round brackets around Layout.
+        val bracketL: layout:Layout -> Layout
+
+        /// Wrap square brackets around layout.    
+        val squareBracketL: layout:Layout -> Layout
+
+        /// Wrap braces around layout.        
+        val braceL: layout:Layout -> Layout
+
+        /// Form tuple of layouts.            
+        val tupleL: layouts:Layout list -> Layout
+
+        /// Layout two vertically.
+        val aboveL: layout1:Layout -> layout2:Layout -> Layout
+
+        /// Layout list vertically.    
+        val aboveListL: layouts:Layout list -> Layout
+
+        /// Layout like an F# option.
+        val optionL: selector:('T -> Layout) -> value:'T option -> Layout
+
+        /// Layout like an F# list.    
+        val listL : selector:('T -> Layout) -> value:'T list   -> Layout
+
+        /// See tagL
+        val tagAttrL: text:string -> maps:(string * string) list -> layout:Layout -> Layout
+
+        /// For limiting layout of list-like sequences (lists,arrays,etc).
+        /// unfold a list of items using (project and z) making layout list via itemL.
+        /// If reach maxLength (before exhausting) then truncate.
+        val unfoldL: selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
+
+    /// A record of options to control structural formatting.
+    /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
+    /// value.
+    /// 
+    /// Floating Point format given in the same format accepted by System.Double.ToString,
+    /// e.g. f6 or g15.
+    ///
+    /// If ShowProperties is set the printing process will evaluate properties of the values being
+    /// displayed.  This may cause additional computation.  
+    ///
+    /// The ShowIEnumerable is set the printing process will force the evaluation of IEnumerable objects
+    /// to a small, finite depth, as determined by the printing parameters.
+    /// This may lead to additional computation being performed during printing.
+    []
+    type internal FormatOptions =
+        { FloatingPointFormat: string
+          AttributeProcessor: string -> (string * string) list -> bool -> unit
+#if COMPILER  // FSharp.Core.dll: PrintIntercepts aren't used there
+          PrintIntercepts: (IEnvironment -> obj -> Layout option) list
+          StringLimit: int
+#endif
+          FormatProvider: IFormatProvider
+          BindingFlags: System.Reflection.BindingFlags
+          PrintWidth: int 
+          PrintDepth: int 
+          PrintLength: int
+          PrintSize: int  
+          ShowProperties: bool
+          ShowIEnumerable: bool  }
+
+        static member Default: FormatOptions
+
+    module internal Display =
+
+#if COMPILER
+
+        val asTaggedTextWriter: writer: TextWriter -> TaggedTextWriter
+
+        val any_to_layout: options:FormatOptions -> value:'T * typValue:Type -> Layout
+
+        val squashTo: width: int -> layout: Layout -> Layout
+
+        val squash_layout: options:FormatOptions -> layout:Layout -> Layout
+
+        val output_layout_tagged: options:FormatOptions -> writer:TaggedTextWriter -> layout:Layout -> unit
+
+        val output_layout: options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
+
+        val layout_as_string: options:FormatOptions -> value:'T * typValue:Type -> string
+#else
+
+        // Most functions aren't needed in FSharp.Core.dll, but we add one inernal entry for printf
+        val anyToStringForPrintf: options:FormatOptions -> bindingFlags:System.Reflection.BindingFlags -> value:'T * Type -> string
+#endif
+
+        /// Convert any value to a layout using the given formatting options.  The
+        /// layout can then be processed using formatting display engines such as
+        /// those in the Layout module.  any_to_string and output_any are
+        /// built using any_to_layout with default format options.
+        val layout_to_string: options:FormatOptions -> layout:Layout -> string
+
+#if COMPILER
+        val fsi_any_to_layout: options:FormatOptions -> value:'T * typValue:Type -> Layout
+#endif  
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.cs.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.cs.xlf
new file mode 100644
index 00000000000..4d08c4dbc05
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.cs.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Compiler verze {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} pro F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.de.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.de.xlf
new file mode 100644
index 00000000000..d262ecedaff
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.de.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Compiler, Version {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} für F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.es.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.es.xlf
new file mode 100644
index 00000000000..ef9159513d8
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.es.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Compilador de Microsoft (R) F#, versión {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} para F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.fr.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.fr.xlf
new file mode 100644
index 00000000000..ccc62a60566
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.fr.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Compilateur F# Microsoft (R) version {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} pour F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.it.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.it.xlf
new file mode 100644
index 00000000000..709490f32dd
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.it.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Compilatore Microsoft (R) F# versione {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} per F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.ja.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.ja.xlf
new file mode 100644
index 00000000000..c3a9c660431
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.ja.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Compiler バージョン {0}
+        
+      
+      
+        {0} for F# {1}
+        F# {1} のための {0}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.ko.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.ko.xlf
new file mode 100644
index 00000000000..344ff0ae99a
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.ko.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Compiler 버전 {0}
+        
+      
+      
+        {0} for F# {1}
+        F# {1}용 {0}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.pl.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.pl.xlf
new file mode 100644
index 00000000000..2d42cd40a68
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.pl.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Wersja {0} kompilatora języka Microsoft (R) F#
+        
+      
+      
+        {0} for F# {1}
+        {0} dla języka F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.pt-BR.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.pt-BR.xlf
new file mode 100644
index 00000000000..a1e5ec15e2d
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.pt-BR.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Compilador Microsoft (R) F# versão {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} para F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.ru.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.ru.xlf
new file mode 100644
index 00000000000..cc91dff8078
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.ru.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Compiler, версия {0}
+        
+      
+      
+        {0} for F# {1}
+        {0} для F# {1}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.tr.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.tr.xlf
new file mode 100644
index 00000000000..79c67aa0193
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.tr.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# Derleyicisi sürümü {0}
+        
+      
+      
+        {0} for F# {1}
+        F# {1} için {0}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hans.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hans.xlf
new file mode 100644
index 00000000000..693d5e51974
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hans.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft(R) F# 编译器版本 {0}
+        
+      
+      
+        {0} for F# {1}
+        F# {1} 的 {0}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hant.xlf b/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hant.xlf
new file mode 100644
index 00000000000..45a328e38c1
--- /dev/null
+++ b/src/fsharp/utils/xlf/UtilsStrings.txt.zh-Hant.xlf
@@ -0,0 +1,17 @@
+
+
+  
+    
+      
+        Microsoft (R) F# Compiler version {0}
+        Microsoft (R) F# 編譯器版本 {0}
+        
+      
+      
+        {0} for F# {1}
+        F # {1} 的 {0}
+        
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf
index a2e4bf20810..abaa63bc021 100644
--- a/src/fsharp/xlf/FSComp.txt.cs.xlf
+++ b/src/fsharp/xlf/FSComp.txt.cs.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} pro F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        Funkce {0} není v jazyce F# {1} dostupná. Použijte prosím jazyk verze {2} nebo vyšší.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        Cílový modul runtime nepodporuje funkci {0}.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        Funkce {0} vyžaduje knihovnu F# pro verzi jazyka {1} nebo novější.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        Použití := z knihovny F# je zastaralé. Více informací: https://aka.ms/fsharp-refcell-ops. Změňte prosím například cell := expr na cell.Value <- expr.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        Použití decr z knihovny F# je zastaralé. Více informací: https://aka.ms/fsharp-refcell-ops. Změňte prosím například decr cell na cell.Value <- cell.Value - 1.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        Použití ! z knihovny F# je zastaralé. Více informací: https://aka.ms/fsharp-refcell-ops. Změňte prosím například ! cell na cell.Value.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        Použití incr z knihovny F# je zastaralé. Více informací: https://aka.ms/fsharp-refcell-ops. Změňte prosím například incr cell na cell.Value <- cell.Value + 1.
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        Atribut AssemblyKeyNameAttribute je zastaralý. Použijte místo něj AssemblyKeyFileAttribute.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Podepisování kontejneru klíčů se na této platformě nepodporuje.
+        
+      
+      
+        Available overloads:\n{0}
+        Dostupná přetížení:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Obecná konstrukce vyžaduje, aby byl parametr obecného typu známý jako typ struct nebo reference. Zvažte možnost přidat anotaci typu.
+        
+      
+      
+        Known types of arguments: {0}
+        Známé typy argumentů: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Známý typ argumentu: {0}
+        
+      
+      
+        Known return type: {0}
+        Známý návratový typ: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Známé parametry typů: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Známý typ parametru: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        Argument na indexu {0} neodpovídá
+        
+      
+      
+        Argument '{0}' doesn't match
+        Argument {0} neodpovídá
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Navržené sestavení poskytovatele typu {0} nešlo načíst ze složky {1}, protože chyběla závislost nebo ji nešlo načíst. Všechny závislosti tohoto sestavení se musí nacházet ve stejné složce jako toto sestavení. Ohlášená výjimka: {2} – {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Navržené sestavení poskytovatele typu {0} nešlo načíst ze složky {1}. Ohlášená výjimka: {2} – {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst nebo neexistuje. Ohlášená výjimka: {2} – {3}
+        
+      
+      
+        additional type-directed conversions
+        další převody orientované na typ
+        
+      
+      
+        applicative computation expressions
+        aplikativní výpočetní výrazy
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        atributy napravo od klíčového slova Module
+        
+      
+      
+        default interface member consumption
+        využití člena výchozího rozhraní
+        
+      
+      
+        discard pattern in use binding
+        vzor discard ve vazbě použití
+        
+      
+      
+        dotless float32 literal
+        literál float32 bez tečky
+        
+      
+      
+        more types support units of measure
+        více typů podporuje měrné jednotky
+        
+      
+      
+        fixed-index slice 3d/4d
+        řez 3d/4d s pevným indexem
+        
+      
+      
+        from-end slicing
+        řez od konce
+        
+      
+      
+        implicit yield
+        implicitní yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        Notace expr[idx] pro indexování a vytváření řezů
+        
+      
+      
+        interfaces with multiple generic instantiation
+        rozhraní s vícenásobným obecným vytvářením instancí
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        neproměnné vzory napravo od vzorů typu „jako“
+        
+      
+      
+        nullable optional interop
+        nepovinný zprostředkovatel komunikace s možnou hodnotou null
+        
+      
+      
+        open type declaration
+        Otevřít deklaraci typu
+        
+      
+      
+        overloads for custom operations
+        přetížení pro vlastní operace
+        
+      
+      
+        package management
+        správa balíčků
+        
+      
+      
+        binary formatting for integers
+        formátování typu binary pro integery
+        
+      
+      
+        informational messages related to reference cells
+        informační zprávy související s referenčními buňkami
+        
+      
+      
+        whitespace relexation
+        uvolnění prázdných znaků
+        
+      
+      
+        whitespace relaxation v2
+        relaxace whitespace v2
+        
+      
+      
+        resumable state machines
+        obnovitelné stavové stroje
+        
+      
+      
+        single underscore pattern
+        vzor s jedním podtržítkem
+        
+      
+      
+        string interpolation
+        interpolace řetězce
+        
+      
+      
+        struct representation for active patterns
+        reprezentace struktury aktivních vzorů
+        
+      
+      
+        wild card in for loop
+        zástupný znak ve smyčce for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Předávání kopie clusteru pro omezení vlastností v uvozovkách v jazyce F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Interpolované řetězce nemůžou používat specifikátory formátu %, pokud se každému z nich nezadá nějaký výraz, např. %d{{1+1}}.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Specifikátory formátu ve stylu .NET, třeba {{x,3}} nebo {{x:N5}}, se nedají kombinovat se specifikátory formátu %.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Specifikátor %P se nedá použít explicitně.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Interpolované řetězce, které se používají jako typ IFormattable nebo FormattableString, nemůžou používat specifikátory %. Použít je možné jen interpolované výrazy ve stylu .NET, třeba {{expr}}, {{expr,3}} nebo {{expr:N5}}.
+        
+      
+      
+         - {0}
+         – {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Vytváření průřezů od konce vyžaduje jazykovou verzi 5.0, použijte /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Neplatná direktiva #{0} {1}
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Konstruktor obnovitelného kódu {0} se dá použít jenom ve vloženém kódu chráněném příkazem if __useResumableCode then ... a celkové složení musí tvořit platný obnovitelný kód.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        Atribut InlineIfLambda se nachází v signatuře, ale ne v implementaci.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Klíčové slovo, které specifikuje konstantní literál jako argument parametru typu v poskytovatelích typů
+        
+      
+      
+        a byte string may not be interpolated
+        Bajtový řetězec se nedá interpolovat.
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Znak }} musí být v interpolovaném řetězci uvozený (zdvojeným znakem).
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Neplatný interpolovaný řetězec. Literály s jednoduchou uvozovkou nebo doslovné řetězcové literály se nedají použít v interpolovaných výrazech v řetězcích s jednoduchou uvozovkou nebo v doslovných řetězcích. Zvažte možnost použít pro výraz interpolace explicitní vazbu let nebo řetězec s trojitými uvozovkami jako vnější řetězcový literál.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Neplatný interpolovaný řetězec. V interpolovaných výrazech se nedají použít řetězcové literály s trojitými uvozovkami. Zvažte možnost použít pro interpolovaný výraz explicitní vazbu let.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         Hlavička zdroje začínající na posunu {0} má chybný formát.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Tento výraz není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes expr[index]?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Tato hodnota není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes {0}[index]?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        Hodnota {0} byla označena jako InlineIfLambda, ale nemá hodnotu lambda. Toto upozornění slouží pouze pro informační účely.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Vytiskněte odvozená rozhraní všech kompilovaných souborů do přidružených souborů podpisu.
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Zobrazte si povolené hodnoty verze jazyka a pak zadejte požadovanou verzi, například latest nebo preview.
@@ -37,9 +417,49 @@
         Nerozpoznaná hodnota {0} pro parametr --langversion; seznam možností zobrazíte zadáním --langversion:?
         
       
+      
+        Display compiler version banner and exit
+        Zobrazit banner verze kompilátoru a ukončit
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Zadejte soubor ikony Win32 (.ico).
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Funkce správy balíčků vyžaduje jazykovou verzi 5.0, použijte /langversion:preview.
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Neplatný interpolovaný řetězec. Vyplnění výrazu interpolovaného řetězce je prázdné, očekával se výraz.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Tady nebo před tímto místem začal neúplný interpolovaný řetězec.
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Tady nebo před tímto místem začalo vyplňování výrazu neúplného interpolovaného řetězce.
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Tady nebo před tímto místem začal neúplný interpolovaný řetězec s trojitými uvozovkami.
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Tady nebo před tímto místem začal neúplný interpolovaný doslovný řetězec.
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Neočekávaný token v definici typu. Za typem {0} se očekává =.
         
       
       
@@ -57,19 +477,109 @@
         Algoritmus {0} není podporovaný.
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Cílový popisek pro __resumeAt nebyl staticky určen. __resumeAt s nestatickým cílovým popiskem se může objevit jenom na začátku metody obnovitelného kódu.
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Rychlý integer pro smyčku nesmí obsahovat body obnovení.
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        Ve specifikaci obnovitelného kódu došlo k „let rec“.
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Blok „with“ try/with nesmí obsahovat body obnovení.
+        
+      
+      
+        A try/finally may not contain resumption points
+        try/finally nesmí obsahovat body obnovení.
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Delegát nebo funkce vytvářející obnovitelný kód ve stavovém stroji má parametry typu
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Nepovedlo se snížit vyvolání obnovitelného kódu v {0}.
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        Hodnoty obnovitelného kódu {0} nemají definici.
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        Registrovaní správci PackageManagers nepodporují #i.
+        
+      
+      
+        The state machine has an unexpected form
+        Stavový stroj má neočekávaný tvar.
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Tento stavový stroj není staticky kompilovatelný. {0}. Použije se alternativní dynamická implementace, která může být pomalejší. Zvažte úpravu kódu tak, aby byl stavový stroj staticky kompilovatelný, nebo toto upozornění potlačte.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Tento stavový stroj není staticky kompilovatelný a není k dispozici žádná alternativa. {0}. Pokud chcete zadat alternativu, použijte „if __useResumableCode“ then <state-machine> else <alternative>“.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Sadu .NET SDK pro tento skript nešlo určit. Pokud se skript nachází v adresáři používajícím global.json, zkontrolujte, jestli je nainstalovaná odpovídající sada .NET SDK. Výstup ze zadání {0} --version v adresáři {1} byl {2} a ukončovací kód byl {3}.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Sada .NET SDK pro tento skript nedá určit. dotnet.exe se nepovedlo najít, ujistěte se, že je sada .NET SDK nainstalovaná.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Sadu .NET SDK pro tento skript nešlo určit. Pokud se skript nachází v adresáři používajícím global.json, zkontrolujte, jestli je nainstalovaná odpovídající sada .NET SDK. Neočekávaná chyba {0}.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Tento výraz má typ {0} a je kompatibilní pouze s typem {1} prostřednictvím nejednoznačného implicitního převodu. Zvažte použití explicitního volání op_Implicit. Použitelnými implicitními převody jsou: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Tato funkce se v této verzi jazyka F# nepodporuje. Abyste mohli tuto funkci používat, možná bude nutné přidat /langversion:preview.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Toto je nesprávný anonymní záznam. Měl by mít pole {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Tento anonymní záznam nemá dost polí. Přidejte chybějící pole {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Tento anonymní záznam má příliš mnoho polí. Odeberte nadbytečná pole {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Neplatná deklarace typu anonymního záznamu
         
       
       
@@ -77,6 +587,206 @@
         Atributy nejde použít pro rozšíření typů.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        Syntaxe expr1[expr2] se používá pro indexování. Pokud chcete povolit indexování, zvažte možnost přidat anotaci typu, nebo pokud voláte funkci, přidejte mezeru, třeba expr1 [expr2].
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        Syntaxe expr1[expr2] je teď vyhrazena pro indexování. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci, přidejte mezi funkci a argument mezeru, třeba someFunction [expr].
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Typy Byref nejsou v deklaraci otevřeného typu povolené.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        Syntaxe arr.[idx] je teď revidována na arr[idx]. Aktualizujte prosím svůj kód.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Tento výraz používá integrovaný implicitní převod pro převod typu {0} na typ {1}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Tento výraz používá implicitní převod {0} pro převod typu {1} na typ {2}.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Tento výraz používá implicitní převod {0} pro převod typu {1} na typ {2}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs. Toto upozornění může být vypnuté pomocí '#nowarn \"3391\".
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        Atribut InlineIfLambda je možné použít pouze u parametrů vložených funkcí metod s typem funkce nebo typem delegáta F#.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Neshoda v interpolovaném řetězci. Interpolované řetězce nemůžou používat specifikátory formátu %, pokud se každému z nich nezadá nějaký výraz, např. %d{{1+1}}.
+        
+      
+      
+        Invalid alignment in interpolated string
+        Neplatné zarovnání v interpolovaném řetězci
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        Konstruktor {0} je možné použít jenom v platném obnovitelném kódu.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        Použití [<Struct>] u hodnot, funkcí a metod je povolené jenom u částečných aktivních definic vzorů.
+        
+      
+      
+        use! may not be combined with and!
+        use! se nedá kombinovat s and!.
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Neplatné použití zpětného indexu ve výrazu seznamu.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Syntaxe [expr1][expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít (expr1).[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction [expr1] [expr2].
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Syntaxe [expr1][expr2] je teď vyhrazena pro indexování a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction [expr1] [expr2].
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Deklarace [<Literal>] nemůže používat aktivní vzor jako svůj identifikátor.
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Hodnota se nedá přiřadit k jiné hodnotě, která je označená jako literál.
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        K hodnotě označené jako literál se {0} nedá přiřadit.
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Tento výraz podporuje indexování, třeba expr.[index]. Syntaxe expr[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Tato hodnota podporuje indexování, třeba {0}.[index]. Syntaxe {1}[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Tento výraz není funkce a nepodporuje zápis indexu.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        Hodnota {0} není funkce a nepodporuje zápis indexu.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Syntaxe expr1[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít expr1.[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2].
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Syntaxe expr1[expr2] je teď vyhrazena pro indexování a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2].
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Syntaxe (expr1)[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít (expr1).[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2].
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Syntaxe (expr1)[expr2] je teď pro indexování vyhrazená a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2].
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        Konstrukt let! ... and! ... se dá použít jen v případě, že tvůrce výpočetních výrazů definuje buď metodu {0}, nebo vhodné metody MergeSource a Bind.
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Neplatný obnovitelný kód. Parametr obnovitelného kódu musí být typu delegát nebo funkce.
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Neplatný obnovitelný kód. Parametr obnovitelného kódu musí mít název, která začíná na „__expand“.
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Neplatný obnovitelný kód. Ve specifikaci obnovitelného kódu došlo k „let rec“.
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Neplatný obnovitelný kód. Jakákoli metoda funkce, která přijímá nebo vrací obnovitelný kód, musí být označena jako „inline“.
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Vyvolání obnovitelného kódu. Toto upozornění potlačte, pokud definujete nový obnovitelný kód nižší úrovně v rámci existujícího obnovitelného kódu.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Použití obnovitelného kódu nebo obnovitelných stavových strojů vyžaduje /langversion:preview.
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Tento výraz implicitně převede typ {0} na typ {1}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Neplatný interpolovaný řetězec. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Člen rozhraní {0} nemá nejvíce specifickou implementaci.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        {0} nemůže implementovat rozhraní {1} se dvěma instancemi {2} a {3}, protože by se mohly sjednotit.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Rozhraní {0} nemůžete implementovat se dvěma instancemi {1} a {2}, protože by se mohly sjednotit.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Typ {0} nedefinuje pole, konstruktor ani člen {1}.
+        
+      
       
         The namespace '{0}' is not defined.
         Není definovaný obor názvů {0}.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Všechny elementy výrazu konstruktoru seznamu musí mít stejný typ. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Všechny elementy výrazu konstruktoru seznamu musí být implicitně převoditelné na typ prvního elementu. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Všechny elementy výrazu konstruktoru pole musí mít stejný typ. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Všechny elementy výrazu konstruktoru pole musí být implicitně převoditelné na typ prvního elementu. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Všechny větve výrazu if musí mít stejný typ. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Všechny větve výrazu if musí vracet hodnoty implicitně převoditelné na typ první větve. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Všechny větve výrazu porovnání vzorů musí vracet hodnoty stejného typu. První větev vrátila hodnotu typu {0}, ale tato větev vrátila hodnotu typu {1}.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Všechny větve výrazu porovnání vzorů musí vracet hodnoty implicitně převoditelné na typ první větve. Očekávalo se, že tento výraz bude mít typ {0}, ale tady je typu {1}.
         
       
       
@@ -212,11 +922,51 @@
         Zvažte použití parametru return! namísto return.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Kompilátor F# aktuálně nepodporuje tento atribut. Jeho použití nebude mít zamýšlený účinek.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Pro odkazy na rozhraní .NET používejte referenční sestavení, pokud jsou k dispozici (ve výchozím nastavení povolené).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Tento komentář XML není platný: {0}
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Tento komentář XML není platný: několik položek dokumentace pro parametr {0}
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Tento komentář XML není platný: neznámý parametr {0}
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Tento komentář XML není platný: chybí atribut cref pro křížový odkaz
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Tento komentář XML není úplný: žádná dokumentace pro parametr {0}
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Tento komentář XML není platný: chybí atribut name pro parametr nebo odkaz na parametr
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Tento komentář XML není platný: nepřeložený křížový odkaz {0}
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Zvažte použití parametru yield! namísto yield.
@@ -242,16 +992,6 @@
         Neplatný soubor verze {0}
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Compiler verze {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Kompilátor jazyka F# pro F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problém s názvem souboru {0}: {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Pojmenovaný argument má přiřazenou víc než jednu hodnotu.
+        The named argument '{0}' has been assigned more than one value
+        Pojmenovaný argument {0} má přiřazenou víc než jednu hodnotu.
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Kandidáti: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Dostupná přetížení jsou zobrazena níže.
+        Candidates:\n{0}
+        Kandidáti:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Měrné jednotky se podporují jenom u typů float, float32, decimal a signed integer.
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Měrné jednotky se podporují jen u typů float, float32, decimal a integer.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet se očekává jenom ve stromech pro analýzu.
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet se očekává jen ve stromech analýzy.
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Neplatný výraz indexeru
+        Incomplete expression or invalid use of indexer syntax
+        Neúplný výraz nebo neplatné použití syntaxe indexeru
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Označení mutable můžou mít jenom pole záznamu a jednoduché, nerekurzivní vazby let.
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Proměnlivé vazby let nemůžou být rekurzivní ani definované v rekurzivních modulech nebo oborech názvů.
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Pokud se definuje také hodnota konstanty, třeba val x : int = 1, může být deklarací jenom atribut [<Literal>].
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Toto není platný číselný literál. Mezi platné číselné literály patří 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Toto není platný číselný literál. Mezi platné číselné literály patří 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst nebo neexistuje. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst z cesty {2}. Ohlášená výjimka: {3} – {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        {0} proměnná v kolekci
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Tato hodnota není funkcí a nedá se použít. Nechtěli jste místo toho získat k indexeru přístup přes {0}.[index]?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Tato hodnota není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes {0}.[index]?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Tento výraz není funkcí a nedá se použít. Nechtěli jste místo toho získat k indexeru přístup přes expr.[index]?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Tento výraz není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes expr.[index]?
         
       
       
@@ -7064,7 +7799,7 @@
       
       
         A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
-        K ukazateli byref vrácenému funkcí nebo metodou se od F# 4.5 implicitně přistupuje přes ukazatel. Pokud chcete návratovou hodnotu získat jako ukazatel, použijte operátor adresy, například &f(x) nebo &obj.Metoda(arg1, arg2).
+        K ukazateli byref vrácenému funkcí nebo metodou se od F# 4.5 implicitně přistupuje přes ukazatel. Pokud chcete návratovou hodnotu získat jako ukazatel, použijte operátor adresy, například &f(x) nebo &obj.Method(arg1, arg2).
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Dva typy anonymních záznamů mají odlišné sady názvů polí: {0} a {1}
+        Tento anonymní záznam neodpovídá přesně očekávanému tvaru. Přidejte chybějící pole {0} a odeberte nadbytečná pole {1}.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Odkaz na sestavení nebo adresář obsahující nástroj pro dobu návrhu (krátký tvar: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        Klíč správce balíčků {0} nebyl zaregistrován v {1}. Aktuálně registrováno: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Rozšíření správce závislostí {0} nešlo načíst. Zpráva: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf
index baf48ce914b..88583fec151 100644
--- a/src/fsharp/xlf/FSComp.txt.de.xlf
+++ b/src/fsharp/xlf/FSComp.txt.de.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} für F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        Das Feature "{0}" ist in F# {1} nicht verfügbar. Verwenden Sie Sprachversion {2} oder höher.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        Das Feature "{0}" wird von der Zielruntime nicht unterstützt.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        Für das Feature "{0}" ist die F#-Bibliothek für die Sprachversion {1} oder höher erforderlich.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        Die Verwendung von ":=" aus der F#-Bibliothek ist veraltet. Siehe https://aka.ms/fsharp-refcell-ops. Ändern Sie z. B. "cell := expr" in "cell.Value <- expr".
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        Die Verwendung von "decr" aus der F#-Bibliothek ist veraltet. Siehe https://aka.ms/fsharp-refcell-ops. Ändern Sie z. B. "decr cell" in "cell.Value <- cell.Value - 1".
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        Die Verwendung von "!" aus der F#-Bibliothek ist veraltet. Siehe https://aka.ms/fsharp-refcell-ops. Ändern Sie z. B. "!cell" in "cell.Value".
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        Die Verwendung von "incr" aus der F#-Bibliothek ist veraltet. Siehe https://aka.ms/fsharp-refcell-ops. Ändern Sie z. B. "incr cell" in "cell.Value <- cell.Value + 1".
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        "AssemblyKeyNameAttribute" gilt als veraltet. Verwenden Sie stattdessen "AssemblyKeyFileAttribute".
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Das Signieren von Schlüsselcontainern wird auf dieser Plattform nicht unterstützt.
+        
+      
+      
+        Available overloads:\n{0}
+        Verfügbare Überladungen:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Für ein generisches Konstrukt muss ein generischer Typparameter als Struktur- oder Verweistyp bekannt sein. Erwägen Sie das Hinzufügen einer Typanmerkung.
+        
+      
+      
+        Known types of arguments: {0}
+        Bekannte Argumenttypen: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Bekannter Argumenttyp: {0}
+        
+      
+      
+        Known return type: {0}
+        Bekannter Rückgabetyp: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Bekannte Typparameter: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Bekannter Typparameter: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        Das Argument bei Index {0} stimmt nicht überein.
+        
+      
+      
+        Argument '{0}' doesn't match
+        Das Argument "{0}" stimmt nicht überein.
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Die Typanbieter-Designerassembly "{0}" konnte aus dem Ordner "{1}" nicht geladen werden, weil eine Abhängigkeit fehlte oder nicht geladen werden konnte. Alle Abhängigkeiten der Typanbieter-Designerassembly müssen sich in demselben Ordner wie die Assembly befinden. Gemeldete Ausnahme: {2} – {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Die Typanbieter-Designerassembly "{0}" konnte aus dem Ordner "{1}" nicht geladen werden. Gemeldete Ausnahme: {2} – {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        Das Assemblyattribut "{0}" verweist auf eine Designerassembly "{1}", die entweder nicht geladen werden kann oder nicht vorhanden ist. Gemeldete Ausnahme: {2} – {3}
+        
+      
+      
+        additional type-directed conversions
+        zusätzliche typgesteuerte Konvertierungen
+        
+      
+      
+        applicative computation expressions
+        applikative Berechnungsausdrücke
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        Attribute rechts vom "Module"-Schlüsselwort
+        
+      
+      
+        default interface member consumption
+        standardmäßige Schnittstellenmembernutzung
+        
+      
+      
+        discard pattern in use binding
+        Das Verwerfen des verwendeten Musters ist verbindlich.
+        
+      
+      
+        dotless float32 literal
+        punktloses float32-Literal
+        
+      
+      
+        more types support units of measure
+        Maßeinheitenunterstützung durch weitere Typen
+        
+      
+      
+        fixed-index slice 3d/4d
+        Segment 3D/4D mit feststehendem Index
+        
+      
+      
+        from-end slicing
+        Segmentierung ab Ende
+        
+      
+      
+        implicit yield
+        implizite yield-Anweisung
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        expr[idx]-Notation zum Indizieren und Aufteilen
+        
+      
+      
+        interfaces with multiple generic instantiation
+        Schnittstellen mit mehrfacher generischer Instanziierung
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        Nicht-Variablenmuster rechts neben as-Mustern
+        
+      
+      
+        nullable optional interop
+        Interop, NULL-Werte zulassend, optional
+        
+      
+      
+        open type declaration
+        Deklaration für offene Typen
+        
+      
+      
+        overloads for custom operations
+        Überladungen für benutzerdefinierte Vorgänge
+        
+      
+      
+        package management
+        Paketverwaltung
+        
+      
+      
+        binary formatting for integers
+        binäre Formatierung für ganze Zahlen
+        
+      
+      
+        informational messages related to reference cells
+        Informationsmeldungen im Zusammenhang mit Bezugszellen
+        
+      
+      
+        whitespace relexation
+        Lockerung für Leerraum
+        
+      
+      
+        whitespace relaxation v2
+        whitespace relaxation v2
+        
+      
+      
+        resumable state machines
+        Fortsetzbarer Zustand-Maschinen
+        
+      
+      
+        single underscore pattern
+        Muster mit einzelnem Unterstrich
+        
+      
+      
+        string interpolation
+        Zeichenfolgeninterpolation
+        
+      
+      
+        struct representation for active patterns
+        Strukturdarstellung für aktive Muster
+        
+      
+      
+        wild card in for loop
+        Platzhalter in for-Schleife
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Zeugenübergabe für Merkmalseinschränkungen in F#-Zitaten
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Interpolierte Zeichenfolgen dürfen keine Formatbezeichner vom Typ "%" verwenden, es sei denn, jeder erhält einen Ausdruck, z. B. "%d{{1+1}}".
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Formatbezeichner im .NET-Format, z. B. "{{x,3}}" oder "{{x:N5}}", dürfen nicht mit Formatbezeichnern vom Typ "%" gemischt werden.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Der Bezeichner "%P" darf nicht explizit verwendet werden.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Interpolierte Zeichenfolgen, die als Typ "IFormattable" oder "FormattableString" verwendet werden, dürfen keine Spezifizierer vom Typ "%" verwenden. Es dürfen nur Interpolanten im .NET-Format wie "{{expr}}", "{{expr,3}}" oder "{{expr:N5}}" verwendet werden.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Für das vom Ende ausgehende Slicing ist Sprachversion 5.0 erforderlich. Verwenden Sie /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Ungültige Direktive "#{0} {1}"
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Das fortsetzbare Codekonstrukt "{0}" darf nur in Inlinecode verwendet werden, der durch "if __useResumableCode then..." geschützt wird. Die Gesamtkomposition muss einen gültigen fortsetzbaren Code bilden.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        Das Attribut "InlineIfLambda" ist in der Signatur vorhanden, jedoch nicht in der Implementierung.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Schlüsselwort, um ein konstantes Literal als Typparameterargument in Typanbietern anzugeben.
+        
+      
+      
+        a byte string may not be interpolated
+        Eine Bytezeichenfolge darf nicht interpoliert werden.
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Ein }}-Zeichen muss in einer interpolierten Zeichenfolge (durch Verdoppeln) mit Escapezeichen versehen werden.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Ungültige interpolierte Zeichenfolge. Literale mit einzelnen Anführungszeichen oder ausführliche Zeichenfolgenliterale dürfen nicht in interpolierten Ausdrücken in Zeichenfolgen mit einfachen Anführungszeichen oder ausführlichen Zeichenfolgen verwendet werden. Erwägen Sie die Verwendung einer expliziten let-Bindung für den Interpolationsausdruck, oder verwenden Sie eine Zeichenfolge mit dreifachen Anführungszeichen als äußeres Zeichenfolgenliteral.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Ungültige interpolierte Zeichenfolge. Zeichenfolgenliterale mit dreifachen Anführungszeichen dürfen in interpolierten Ausdrücken nicht verwendet werden. Erwägen Sie die Verwendung einer expliziten let-Bindung für den Interpolationsausdruck.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         Der Ressourcenheader, der am Offset {0} beginnt, ist fehlerhaft formatiert.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Dieser Ausdruck ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer stattdessen über "expr[index]" zugreifen?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Dieser Wert ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer stattdessen über "{0}[index]" zugreifen?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        Der Wert "{0}" wurde als "InlineIfLambda" markiert, jedoch nicht als Lambdawert festgelegt. Diese Warnung dient nur zu Informationszwecken.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Drucken der abgeleiteten Schnittstellen aller Dateien an zugehörige Signaturdateien
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Zeigen Sie die zulässigen Werte für die Sprachversion an. Geben Sie die Sprachversion als "latest" oder "preview" an.
@@ -37,9 +417,49 @@
         Unbekannter Wert "{0}" für "--langversion". Verwenden Sie "--langversion:?", um die vollständige Liste anzuzeigen.
         
       
+      
+        Display compiler version banner and exit
+        Banner zur Compilerversion anzeigen und beenden
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Win32-Symboldatei (ICO) angeben
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Für das Paketverwaltungsfeature ist Sprachversion 5.0 erforderlich. Verwenden Sie /langversion:preview.
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Ungültige interpolierte Zeichenfolge. Die Ausdrucksfüllung der interpolierten Zeichenfolge ist leer. Es wurde ein Ausdruck erwartet.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Unvollständige interpolierte Zeichenfolge, die an oder vor dieser Stelle begonnen wurde
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Unvollständige interpolierte Zeichenfolgen-Ausdrucksauffüllung, die an oder vor dieser Stelle begonnen wurde.
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Unvollständige interpolierte Zeichenfolge mit dreifachen Anführungszeichen, die an oder vor dieser Stelle begonnen wurde.
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Unvollständige interpolierte ausführliche Zeichenfolge, die an oder vor dieser Stelle begonnen wurde.
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Unerwartetes Token in Typdefinition. Nach Typ "{0}" wurde "=" erwartet.
         
       
       
@@ -57,19 +477,109 @@
         Algorithmus "{0}" wird nicht unterstützt
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Eine Zielbezeichnung für __resumeAt wurde nicht statisch bestimmt. Ein __resumeAt mit einer nicht statischen Zielbezeichnung darf nur am Anfang einer fortsetzbaren Codemethode stehen
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Eine schnelle ganze Zahl für eine Schleife darf keine Wiederaufnahmepunkte enthalten
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten.
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Der "with"-Block eines try/with darf keine Wiederaufnahmepunkte enthalten
+        
+      
+      
+        A try/finally may not contain resumption points
+        Ein try/finally darf keine Wiederaufnahmepunkte enthalten.
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Ein Delegat oder eine Funktion, die fortsetzbaren Code in einem Zustandsautomaten erzeugt, weist Typparameter auf
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Ein fortsetzbarer Codeaufruf bei "{0}" konnte nicht reduziert werden
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        Der fortsetzbare Codewert "{0}" weist keine Definition auf
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i wird von den registrierten PackageManagers nicht unterstützt.
+        
+      
+      
+        The state machine has an unexpected form
+        Der Zustandsautomat weist ein unerwartetes Formular auf
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Dieser Statuscomputer ist nicht statisch kompilierbar. {0}. Es wird eine Alternative dynamische Implementierung verwendet, die möglicherweise langsamer ist. Erwägen Sie die Anpassung Ihres Codes, um sicherzustellen, dass dieser Zustandsautomat statisch kompiliert werden kann oder unterbinden Sie diese Warnung.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Dieser Statuscomputer ist nicht statisch kompilierbar und es ist keine Alternative verfügbar. {0}. Verwenden Sie "if __useResumableCode then <state-machine> else <alternative>", um eine Alternative zu geben.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Das .NET SDK für dieses Skript konnte nicht ermittelt werden. Wenn sich das Skript in einem Verzeichnis mit "global.json" befindet, stellen Sie sicher, dass das entsprechende .NET SDK installiert ist. Ausgabe von "{0} --version" im Verzeichnis "{1}": {2}. Exitcode: {3}.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Das .NET SDK für dieses Skript konnte nicht bestimmt werden. "dotnet.exe" konnte nicht gefunden werden, um sicherzustellen, dass ein .NET SDK installiert ist.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Das .NET SDK für dieses Skript konnte nicht ermittelt werden. Wenn sich das Skript in einem Verzeichnis mit "global.json" befindet, stellen Sie sicher, dass das entsprechende .NET SDK installiert ist. Unerwarteter Fehler: {0}.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Dieser Ausdruck weist den Typ "{0}" auf und wird nur durch eine mehrdeutige implizite Konvertierung mit dem Typ "{1}" kompatibel gemacht. Erwägen Sie die Verwendung eines expliziten Aufrufs an "op_Implicit". Die anwendbaren impliziten Konvertierungen sind: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Dieses Feature wird in dieser Version von F# nicht unterstützt. Möglicherweise müssen Sie "/langversion:preview" hinzufügen, um dieses Feature zu verwenden.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Dies ist der falsche anonyme Datensatz. Er muss folgende Felder umfassen: {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Dieser anonyme Datensatz weist nicht genügend Felder auf. Fügen Sie die fehlenden Felder ({0}) hinzu.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Dieser anonyme Datensatz enthält zu viele Felder. Entfernen Sie die zusätzlichen Felder ({0}).
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Ungültige Deklaration für anonymen Datensatztyp.
         
       
       
@@ -77,6 +587,206 @@
         Attribute können nicht auf Typerweiterungen angewendet werden.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        Die Syntax "expr1[expr2]" wird für die Indizierung verwendet. Fügen Sie ggf. eine Typanmerkung hinzu, um die Indizierung zu aktivieren, oder fügen Sie beim Aufrufen einer Funktion ein Leerzeichen hinzu, z. B. "expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        Die Syntax "expr1[expr2]" ist jetzt für die Indizierung reserviert. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion aufrufen, fügen Sie ein Leerzeichen zwischen der Funktion und dem Argument hinzu, z. B. "someFunction [expr]".
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Byref-Typen sind in einer Deklaration für offene Typen nicht zulässig.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        Die Syntax "arr.[idx]" wurde jetzt in "arr[idx]" überarbeitet. Bitte aktualisieren Sie Ihren Code.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Dieser Ausdruck verwendet eine integrierte implizite Konvertierung, um den Typ "{0}" in den Typ "{1}" zu konvertieren. Siehe https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Dieser Ausdruck verwendet die implizite Konvertierung "{0}", um den Typ "{1}" in den Typ "{2}" zu konvertieren.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Dieser Ausdruck verwendet die implizite Konvertierung "{0}", um den Typ "{1}" in den Typ "{2}" zu konvertieren. Siehe https://aka.ms/fsharp-implicit-convs. Diese Warnung kann durch "#nowarn \" 3391 \ " deaktiviert werden.
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        Das "InlineIfLambda-Attribut" darf nur für Parameter von Inlinefunktionen von Methoden verwendet werden, deren Typ ein Funktions-oder F #-Delegattyp ist.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Konflikt in interpolierter Zeichenfolge. Interpolierte Zeichenfolgen dürfen keine Formatbezeichner vom Typ "%" verwenden, es sei denn, jeder erhält einen Ausdruck, z. B. "%d{{1+1}}"
+        
+      
+      
+        Invalid alignment in interpolated string
+        Ungültige Ausrichtung in interpolierter Zeichenfolge.
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        Das Konstrukt "{0}" darf nur in einem gültigen fortsetzbaren Code verwendet werden.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        Die Verwendung von "[<Struct>]" für Werte, Funktionen und Methoden ist nur für partielle aktive Musterdefinitionen zulässig.
+        
+      
+      
+        use! may not be combined with and!
+        "use!" darf nicht mit "and!" kombiniert werden.
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Ungültige Verwendung des umgekehrten Indexes im Listenausdruck.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Die Syntax "[expr1][expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "(expr1).[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction [expr1] [expr2]".
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Die Syntax "[expr1][expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction [expr1] [expr2]".
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Eine [<Literal>]-Deklaration kann kein aktives Muster für ihren Bezeichner verwenden.
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Ein Wert kann keinem anderen als Literal markierten Wert zugewiesen werden.
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        "{0}" kann keinem als Literal markierten Wert zugewiesen werden.
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Dieser Ausdruck unterstützt die Indizierung, z. B. "expr.[index]". Die Syntax "expr[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Dieser Wert unterstützt die Indizierung, z. B. "{0}.[index]". Die Syntax "{1}[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Dieser Ausdruck ist keine Funktion und unterstützt keine Indexnotation.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        Der Wert "{0}" ist keine Funktion und unterstützt keine Indexnotation.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Die Syntax "expr1[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "expr1.[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Die Syntax "expr1[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Die Syntax "(expr1)[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "(expr1).[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Die Syntax "(expr1)[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]".
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        Das Konstrukt "let! ... and! ..." kann nur verwendet werden, wenn der Berechnungsausdrucks-Generator entweder eine {0}-Methode oder geeignete MergeSource- und Bind-Methoden definiert.
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Ungültiger fortsetzbarer Code. Ein fortsetzbarer Codeparameter muss einen Delegat-oder Funktionstyp aufweisen
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Ungültiger fortsetzbarer Code. Der Parameter für den fortsetzbaren Code muss mit dem Namen "__expand" beginnen
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Ungültiger fortsetzbarer Code. "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Ungültiger fortsetzbarer Code. Jede Methode der Funktion, die fortsetzbaren Code akzeptiert oder zurückgibt, muss als "Inline" gekennzeichnet sein
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Fortsetzbarer Codeaufruf. Unterdrücken Sie diese Warnung, wenn Sie einen neuen fortsetzbaren Code auf niedriger Ebene in Bezug auf bereits vorhandenen fortsetzbaren Code definieren.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Die Verwendung von Fortsetzbarem Code oder fortsetzbaren Zustandscomputern erfordert /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Dieser Ausdruck konvertiert den Typ "{0}" implizit in den Typ "{1}". Siehe https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Ungültige interpolierte Zeichenfolge. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Der Schnittstellenmember "{0}" weist keine spezifischste Implementierung auf.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        "{0}" kann die Schnittstelle "{1}" mit den beiden Instanziierungen "{2}" und "{3}" nicht implementieren, weil sie möglicherweise zusammengeführt werden.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Sie können die Schnittstelle "{0}" mit den beiden Instanziierungen "{1}" und "{2}" nicht implementieren, weil sie möglicherweise zusammengeführt werden.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Der Typ "{0}" definiert nicht das Feld, den Konstruktor oder den Member "{1}".
+        
+      
       
         The namespace '{0}' is not defined.
         Der Namespace "{0}" ist nicht definiert.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Alle Elemente eines Listenkonstruktorausdrucks müssen den gleichen Typ aufweisen. Es wurde erwartet, dass dieser Ausdruck den Typ "{0}" aufweist, hier liegt aber der Typ "{1}" vor.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Alle Elemente einer Liste müssen implizit in den Typ des ersten Elements konvertierbar sein, der hier "{0}" genannt wird. Dieses Element hat den Typ "{1}".
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Alle Elemente eines Arraykonstruktorausdrucks müssen den gleichen Typ aufweisen. Es wurde erwartet, dass dieser Ausdruck den Typ "{0}" aufweist, hier liegt aber der Typ "{1}" vor.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Alle Elemente eines Arrays müssen implizit in den Typ des ersten Elements konvertierbar sein, der hier "{0}" genannt ist. Dieses Element weist den Typ "{1}" auf.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Alle Branches eines if-Ausdrucks müssen den gleichen Typ aufweisen. Es wurde erwartet, dass dieser Ausdruck den Typ "{0}" aufweist, hier liegt aber der Typ "{1}" vor.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Alle Verzweigungen eines „If-Ausdrucks“ müssen Werte zurückgeben, die implizit in den Typ der ersten Verzweigung konvertierbar sind, welcher hier "{0}" genannt wird. Diese Verzweigung gibt einen Wert vom Typ "{1}" zurück.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Alle Branches eines Musterübereinstimmungsausdrucks müssen Werte des gleichen Typs zurückgeben. Der erste Branch hat einen Wert vom Typ "{0}" zurückgegeben, aber dieser Branch gab einen Wert vom Typ "{1}" zurück.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Alle Verzweigungen eines Musterübereinstimmungsausdrucks müssen Werte zurückgeben, die implizit zu dem Typen der ersten Verzweigung konvertiert werden können, welche hier „{0}“ genannt wird. Diese Verzweigung gibt einen Wert des Typs „{1}“ zurück.
         
       
       
@@ -212,11 +922,51 @@
         Verwenden Sie ggf. "return!" anstelle von "return".
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Dieses Attribut wird derzeit vom F#-Compiler nicht unterstützt. Durch seine Anwendung wird die beabsichtigte Wirkung nicht erreicht.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Verweisassemblys für .NET Framework-Verweise verwenden, wenn verfügbar (standardmäßig aktiviert).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Dieser XML-Kommentar ist ungültig: "{0}"
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Dieser XML-Kommentar ist ungültig: mehrere Dokumentationseinträge für Parameter "{0}".
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Dieser XML-Kommentar ist ungültig: unbekannter Parameter "{0}".
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Dieser XML-Kommentar ist ungültig: Attribut "cref" für Querverweis fehlt.
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Dieser XML-Kommentar ist unvollständig: keine Dokumentation für Parameter "{0}".
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Dieser XML-Kommentar ist ungültig: Attribut "name" für Parameter oder Parameterverweis fehlt.
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Dieser XML-Kommentar ist ungültig: nicht aufgelöster Querverweis "{0}".
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Verwenden Sie ggf. "yield!" anstelle von "yield".
@@ -242,16 +992,6 @@
         Ungültige Versionsdatei "{0}".
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Compiler, Version {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        F# Compiler für F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problem mit Dateinamen "{0}": {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Einem benannten Argument wurde mehr als ein Wert zugewiesen.
+        The named argument '{0}' has been assigned more than one value
+        Dem benannten Argument "{0}" wurden mehrere Werte zugewiesen.
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Kandidaten: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Die verfügbaren Überladungen werden unten angezeigt.
+        Candidates:\n{0}
+        Kandidaten:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Maßeinheiten werden nur für die Typen "float", "float32", "decimal" und "signed integer" unterstützt.
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Maßeinheiten werden nur für die Typen "float", "float32", "decimal" und "integer" unterstützt.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet wird nur in Analysestrukturen erwartet.
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        "SynMemberKind.PropertyGetSet" wird nur in Analysestrukturen erwartet.
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Ungültiger Indexerausdruck.
+        Incomplete expression or invalid use of indexer syntax
+        Unvollständiger Ausdruck oder ungültige Verwendung der Indexer-Syntax
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Nur Datensatzfelder und einfache, nicht rekursive let-Bindungen dürfen als "mutable" markiert werden.
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Änderbare let-Bindungen können nicht rekursiv sein oder in rekursiven Modulen oder Namespaces definiert werden.
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Eine Deklaration kann nur dem [<Literal>]-Attribut entsprechen, wenn auch ein konstanter Wert angegeben ist, z.B. "val x : int =1".
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -4239,32 +4974,32 @@
       
       
         Embed all source files in the portable PDB file
-        Alle Quelldateien in der portablen PDB-Datei einbetten
+        Alle Quelldateien in der portierbaren PDB-Datei einbetten
         
       
       
         Embed specific source files in the portable PDB file
-        Bestimmte Quelldateien in der portablen PDB-Datei einbetten
+        Bestimmte Quelldateien in der portierbaren PDB-Datei einbetten
         
       
       
         Source link information file to embed in the portable PDB file
-        Die Datei mit Quelllinkinformationen, die in die portable PDB-Datei eingebettet werden soll
+        Die Datei mit Quelllinkinformationen, die in die portierbare PDB-Datei eingebettet werden soll
         
       
       
         --embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
-        Die Option "--embed" wird nur bei der Ausgabe einer portablen PDB unterstützt (--debug:portable oder --debug:embedded).
+        Die Option "--embed" wird nur bei der Ausgabe einer portierbaren PDB unterstützt (--debug:portable oder --debug:embedded).
         
       
       
         --sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
-        Die Option "--sourcelink" wird nur bei der Ausgabe einer portablen PDB unterstützt (--debug:portable oder --debug:embedded).
+        Die Option "--sourcelink" wird nur bei der Ausgabe einer portierbaren PDB unterstützt (--debug:portable oder --debug:embedded).
         
       
       
         Source file is too large to embed in a portable PDB
-        Die Quelldatei ist zu groß, um in eine portable PDB eingebettet zu werden.
+        Die Quelldatei ist zu groß, um in eine portierbare PDB eingebettet zu werden.
         
       
       
@@ -4284,7 +5019,7 @@
       
       
         Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file).
-        Geben Sie den Debugtyp an: vollständig, portabel, eingebettet, pdbonly. ("{0}" ist der Standardwert, wenn kein Debugtyp angegeben wird, und ermöglicht das Anfügen eines Debuggers an ein aktuell ausgeführtes Programm. "Portabel" ist ein plattformübergreifendes Format, "eingebettet" ein plattformübergreifendes, in die Ausgabedatei eingebettetes Format).
+        Geben Sie den Debugtyp an: full, portable, embedded, pdbonly. ("{0}" ist der Standardwert, wenn kein Debugtyp angegeben wird, und ermöglicht das Anfügen eines Debuggers an ein aktuell ausgeführtes Programm. "portable" ist ein plattformübergreifendes Format, "embedded" ein plattformübergreifendes, in die Ausgabedatei eingebettetes Format).
         
       
       
@@ -4454,7 +5189,7 @@
       
       
         - INPUT FILES -
-        – EINGABEDATEIEN –
+        - EINGABEDATEIEN -
         
       
       
@@ -4474,17 +5209,17 @@
       
       
         - MISCELLANEOUS -
-        – VERSCHIEDENES –
+        - VERSCHIEDENES -
         
       
       
         - LANGUAGE -
-        – SPRACHE –
+        - SPRACHE -
         
       
       
         - ERRORS AND WARNINGS -
-        – FEHLER UND WARNUNGEN –
+        - FEHLER UND WARNUNGEN -
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Dies ist kein gültiges numerisches Literal. Die folgenden numerischen Literale sind z.B. gültig: 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Dies ist kein gültiges numerisches Literal. Unter anderem sind die folgenden numerischen Literale gültig: 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        Das Assemblyattribut '{0}' bezieht sich auf eine Designerassembly '{1}', die entweder nicht geladen werden kann oder nicht vorhanden ist. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        Das Assemblyattribut "{0}" verweist auf eine Designerassembly "{1}", die nicht aus dem Pfad "{2}" geladen werden kann. Gemeldete Ausnahme: {3} – {4}
         
       
       
@@ -5769,7 +6504,7 @@
       
       
         Unexpected 'null' return value from provided type '{0}' member '{1}'
-        Unerwarteter NULL-Rückgabewert vom angegebenen Typ '{0}' Member '{1}':
+        Unerwarteter NULL-Rückgabewert vom angegebenen Typ '{0}' Member '{1}'
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        {0}-Variable in der Sammlung
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Dieser Wert ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer stattdessen über "{0}.[index]" zugreifen?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Dieser Wert ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer über "{0}.[index]" zugreifen?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Dieser Ausdruck ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer stattdessen über "expr.[index]" zugreifen?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Dieser Ausdruck ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer über "expr.[index]" zugreifen?
         
       
       
@@ -7064,7 +7799,7 @@
       
       
         A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
-        Ein byref-Zeiger, der von einer Funktion oder Methode zurückgegeben wird, wird explizit als von F# 4.5 stammend dereferenziert. Verwenden Sie den &-Operator (z.B. "&f(x)" oder "&obj.Method(arg1, arg2)"), um den Rückgabewert als Zeiger abzurufen.
+        Ein byref-Zeiger, der von einer Funktion oder Methode zurückgegeben wird, wird explizit als von F# 4.5 stammend dereferenziert. Verwenden Sie den Operator (z.B. "&f(x)" oder "&obj.Method(arg1, arg2)"), um den Rückgabewert als Zeiger abzurufen.
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Zwei anonyme Datensatztypen weisen die nicht übereinstimmenden Feldnamen "{0}" und "{1}" auf.
+        Dieser anonyme Datensatz stimmt nicht genau mit der erwarteten Form überein. Fügen Sie die fehlenden Felder ({0}) hinzu, und entfernen Sie die zusätzlichen Felder ({1}).
         
       
       
@@ -7239,7 +7974,7 @@
       
       
         --pathmap can only be used with portable PDBs (--debug:portable or --debug:embedded)
-        --pathmap kann nur mit portablen PDB-Dateien verwendet werden (--debug:portable oder --debug:embedded)
+        --pathmap kann nur mit portierbaren PDB-Dateien verwendet werden (--debug:portable oder --debug:embedded)
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Verweisen Sie auf eine Assembly oder ein Verzeichnis mit einem Entwurfszeittool (Kurzform: -t).
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        Der Paket-Manager-Schlüssel "{0}" wurde in "{1}" nicht registriert. Aktuell registriert: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Die Abhängigkeits-Manager-Erweiterung "{0}" konnte nicht geladen werden. Meldung: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf
index 1d82a7a42cf..ed44397fe0f 100644
--- a/src/fsharp/xlf/FSComp.txt.es.xlf
+++ b/src/fsharp/xlf/FSComp.txt.es.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} para F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        La característica "{0}" no está disponible en F# {1}. Use la versión {2} del lenguaje o una posterior.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        El entorno de ejecución de destino no admite la característica "{0}".
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        La característica "{0}" requiere la biblioteca de F# para la versión de lenguaje {1} o superior.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        El uso de ":=" de la biblioteca de F# está en desuso. Vea https://aka.ms/fsharp-refcell-ops. Por ejemplo, cambie "cell := expr" a "cell.Value <- expr".
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        El uso de "decr" de la biblioteca de F# está en desuso. Vea https://aka.ms/fsharp-refcell-ops. Por ejemplo, cambie "decr cell" a "cell.Value <- cell.Value - 1".
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        El uso de "!" de la biblioteca de F# está en desuso. Vea https://aka.ms/fsharp-refcell-ops. Por ejemplo, cambie "!cell" a "cell.Value".
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        El uso de "incr" de la biblioteca de F# está en desuso. Vea https://aka.ms/fsharp-refcell-ops. Por ejemplo, cambie "incr cell" a "cell.Value <- cell.Value + 1".
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        El elemento "AssemblyKeyNameAttribute" está en desuso. Use "AssemblyKeyFileAttribute" en su lugar.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        La firma del contenedor de claves no se admite en esta plataforma.
+        
+      
+      
+        Available overloads:\n{0}
+        Sobrecargas disponibles:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Una construcción genérica requiere que un parámetro de tipo genérico se conozca como tipo de referencia o estructura. Puede agregar una anotación de tipo.
+        
+      
+      
+        Known types of arguments: {0}
+        Tipos de argumentos conocidos: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Tipo de argumento conocido: {0}
+        
+      
+      
+        Known return type: {0}
+        Tipo de valor devuelto conocido: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Parámetros de tipo conocidos: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Parámetro de tipo conocido: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        El argumento del índice {0} no coincide.
+        
+      
+      
+        Argument '{0}' doesn't match
+        El argumento "{0}" no coincide.
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        No se pudo cargar el ensamblado del diseñador de proveedores de tipos "{0}" desde la carpeta "{1}" porque falta una dependencia o no se pudo cargar. Todas las dependencias del ensamblado del diseñador de proveedores de tipos deben encontrarse en la misma carpeta que el ensamblado. Se notificó la excepción: {2} - {3}.
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        No se pudo cargar el ensamblado del diseñador de proveedores de tipos "{0}" desde la carpeta "{1}". Se notificó la excepción: {2} - {3}.
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        El atributo de ensamblado "{0}" hace referencia a un ensamblado de diseñador "{1}" que no se puede cargar o no existe. Se notificó la excepción: {2} - {3}.
+        
+      
+      
+        additional type-directed conversions
+        conversiones adicionales dirigidas a tipos
+        
+      
+      
+        applicative computation expressions
+        expresiones de cálculo aplicativas
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        atributos a la derecha de la palabra clave “módulo”
+        
+      
+      
+        default interface member consumption
+        consumo de miembros de interfaz predeterminados
+        
+      
+      
+        discard pattern in use binding
+        descartar enlace de patrón en uso
+        
+      
+      
+        dotless float32 literal
+        literal float32 sin punto
+        
+      
+      
+        more types support units of measure
+        más tipos admiten las unidades de medida
+        
+      
+      
+        fixed-index slice 3d/4d
+        segmento de índice fijo 3d/4d
+        
+      
+      
+        from-end slicing
+        segmentación desde el final
+        
+      
+      
+        implicit yield
+        elemento yield implícito
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        Notación para indexación y segmentación expr[idx]
+        
+      
+      
+        interfaces with multiple generic instantiation
+        interfaces con creación de instancias genéricas múltiples
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        patrones no variables a la derecha de los patrones "as"
+        
+      
+      
+        nullable optional interop
+        interoperabilidad opcional que admite valores NULL
+        
+      
+      
+        open type declaration
+        declaración de tipo abierto
+        
+      
+      
+        overloads for custom operations
+        sobrecargas para operaciones personalizadas
+        
+      
+      
+        package management
+        administración de paquetes
+        
+      
+      
+        binary formatting for integers
+        formato binario para enteros
+        
+      
+      
+        informational messages related to reference cells
+        mensajes informativos relacionados con las celdas de referencia
+        
+      
+      
+        whitespace relexation
+        relajación de espacio en blanco
+        
+      
+      
+        whitespace relaxation v2
+        relajación de espacios en blanco v2
+        
+      
+      
+        resumable state machines
+        máquinas de estado reanudables
+        
+      
+      
+        single underscore pattern
+        patrón de subrayado simple
+        
+      
+      
+        string interpolation
+        interpolación de cadena
+        
+      
+      
+        struct representation for active patterns
+        representación de struct para modelos activos
+        
+      
+      
+        wild card in for loop
+        carácter comodín en bucle for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Paso de testigo para las restricciones de rasgos en las expresiones de código delimitadas de F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Las cadenas interpoladas no pueden usar los especificadores de formato "%", a menos que se les proporcione una expresión individualmente; por ejemplo, "%d{{1+1}}".
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Los especificadores de formato de estilo .NET, como "{{x,3}}" o "{{x:N5}}", no se pueden mezclar con los especificadores de formato "%".
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        El especificador "%P" no se puede usar de forma explícita.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Las cadenas interpoladas que se usan como tipo IFormattable o FormattableString no pueden usar los especificadores "%"; solo pueden utilizar operandos de interpolación de estilo .NET, como "{{expr}}", "{{expr,3}}" o "{{expr:N5}}".
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        La segmentación desde el final requiere la versión de lenguaje 5.0, use /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Directiva '#{0} {1}' no válida.
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        La construcción de código reanudable "{0}" solo se puede usar en el código insertado protegido por "if __useResumableCode then ..." y la composición general debe formar un código reanudable válido.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        El atributo "InlineIfLambda" está presente en la firma, pero no en la implementación.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Palabra clave para especificar un literal de constante como argumento de parámetro de tipo en los proveedores de tipo.
+        
+      
+      
+        a byte string may not be interpolated
+        no se puede interpolar una cadena de bytes
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        El carácter "}}" se debe escapar (duplicándose) en las cadenas interpoladas.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Cadena interpolada no válida. No se pueden usar literales de cadena textual o de comillas simples en expresiones interpoladas en cadenas textuales o de comillas simples. Puede usar un enlace "let" explícito para la expresión de interpolación o utilizar una cadena de comillas triples como literal de cadena externo.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Cadena interpolada no válida. No se pueden usar literales de cadena de comillas triples en las expresiones interpoladas. Puede usar un enlace "let" explícito para la expresión de interpolación.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         El encabezado de los recursos que comienza en el desplazamiento {0} está mal formado.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Esta expresión no es una función y no se puede aplicar. ¿Quería acceder al indexador a través de "expr[index]"?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Este valor no es una función y no se puede aplicar. ¿Quería acceder al indexador a través de "{0}[index]"?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        El valor "{0}" estaba marcado como "InlineIfLambda", pero no se ha determinado que tenga un valor lambda. Esta advertencia solo tiene fines informativos.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Imprimir las interfaces deducidas de todos los archivos de compilación en los archivos de signatura asociados
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Mostrar los valores permitidos para la versión de idioma, especificar la versión de idioma como "latest" "preview"
@@ -37,9 +417,49 @@
         Valor no reconocido "{0}" para --langversion, use --langversion:? para una lista completa
         
       
+      
+        Display compiler version banner and exit
+        Mostrar el banner de versión del compilador y salir
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Especificar un archivo de icono Win32 (.ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        La característica de administración de paquetes requiere la versión de lenguaje 5.0; use /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Cadena interpolada no válida. Este relleno de expresión de cadena interpolada está vacío; se esperaba una expresión.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        La cadena interpolada incompleta comenzaba aquí o antes.
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        El relleno de expresión de la cadena interpolada incompleta comenzaba aquí o antes.
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        La cadena de comillas triples interpolada incompleta comenzaba aquí o antes.
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        La cadena textual interpolada incompleta comenzaba aquí o antes.
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Token inesperado en la definición de tipo. Se esperaba "=" después del tipo "{0}".
         
       
       
@@ -57,19 +477,109 @@
         No se admite el algoritmo '{0}'
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        No se determinó estáticamente una etiqueta de destino para __resumeAt. Si __resumeAt tiene una etiqueta de destino no estática, solo podrá aparecer al principio de un método de código reanudable
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Un bucle for con enteros rápidos no puede contener puntos de reanudación
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        Se ha producido "let rec" en la especificación de código reanudable
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        El bloque "with" de try/with no puede contener puntos de reanudación
+        
+      
+      
+        A try/finally may not contain resumption points
+        Try/finally puede no contener puntos de reanudación
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Un delegado o una función que produce código reanudable en un equipo de estado tiene parámetros de tipo
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        No se pudo reducir una invocación de código reanudable en "{0}"
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        Los valores de código reanudables "{0}" no tienen una definición
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        Los elementos PackageManager registrados no admiten #i
+        
+      
+      
+        The state machine has an unexpected form
+        El equipo de estado tiene un formato inesperado
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Esta máquina de estado no se compila estáticamente. {0}. Se usará una implementación dinámica alternativa, que puede ser más lenta. Considere la posibilidad de ajustar el código para asegurarse de que esta máquina de estado se pueda compilar estáticamente, o bien suprima esta advertencia.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Esta máquina de estado no se puede compilar estáticamente y no hay ninguna alternativa disponible. {0}. Utilice "if __useResumableCode then <state-machine> else <alternative>" para dar una alternativa.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        No se pudo determinar el SDK de .NET para este script. Si el script está en un directorio que usa una instancia de "global.json", asegúrese de que el SDK de .NET pertinente esté instalado. La salida de "{0} --version" en el directorio "{1}" era "{2}", con el código de salida "{3}".
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        No se pudo determinar el SDK de .NET para este script. No se encontró dotnet.exe. Asegúrese de tener instalado un SDK de .NET.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        No se pudo determinar el SDK de .NET para este script. Si el script está en un directorio que usa una instancia de "global.json", asegúrese de que el SDK de .NET pertinente esté instalado. Error inesperado: "{0}".
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Esta expresión tiene el tipo "{0}" y solo se hace compatible con el tipo "{1}" mediante una conversión implícita ambigua. Considere la posibilidad de usar una llamada explícita a 'op_Implicit'. Las conversiones implícitas aplicables son:{2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Esta versión de F# no admite esta característica. Es posible que tenga que agregar /langversion:preview para usarla.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Este es un registro anónimo incorrecto. Debe tener los campos {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Este registro anónimo no tiene suficientes campos. Agregue los campos que faltan {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Este registro anónimo tiene demasiados campos. Quite los campos adicionales {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Declaración de tipo de registro anónimo no válido.
         
       
       
@@ -77,6 +587,206 @@
         Los atributos no se pueden aplicar a las extensiones de tipo.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        La sintaxis "expr1[expr2]" se usa para la indexación. Considere la posibilidad de agregar una anotación de tipo para habilitar la indexación, si se llama a una función, agregue un espacio, por ejemplo, "expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        La sintaxis "expr1[expr2]" está ahora reservada para la indexación. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función, agregue un espacio entre la función y el argumento; por ejemplo, "unaFunción [expr]".
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        No se permiten tipos byref en una declaración de tipo abierto.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        La sintaxis "arr.[idx]" se ha revisado y ahora es "arr[idx]". Actualice el código.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Esta expresión usa una conversión implícita integrada para convertir el tipo '{0}' al tipo '{1}'. Vea https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Esta expresión usa la conversión implícita '{0}' para convertir el tipo '{1}' al tipo '{2}'.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Esta expresión usa la conversión implícita '{0}' para convertir el tipo '{1}' al tipo '{2}'. Consulte https://aka.ms/fsharp-implicit-convs. Esta advertencia se puede deshabilitar mediante '#nowarn \"3391\".
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        El atributo "InlineIfLambda" solo se puede usar en los parámetros de funciones insertadas de métodos cuyo tipo es una función o un tipo de delegado F#.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        La cadena interpolada no coincide. Las cadenas interpoladas no pueden usar los especificadores de formato "%", a menos que se les proporcione una expresión individualmente; por ejemplo, "%d{{1+1}}".
+        
+      
+      
+        Invalid alignment in interpolated string
+        Alineación no válida en la cadena interpolada
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        La construcción "{0}" solo se puede usar en un código reanudable válido.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        El uso de «[<Struct>]» en valores, funciones y métodos solo se permite en definiciones de modelos activos parciales.
+        
+      
+      
+        use! may not be combined with and!
+        No se puede combinar use! con and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Uso no válido de índice inverso en la expresión de lista.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La sintaxis "[expr1][expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "(expr1).[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción [expr1] [expr2]".
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La sintaxis "[expr1][expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]".
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Una declaración [<Literal>] no puede usar un modelo activo para su identificador
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        No se puede asignar un valor a otro marcado como literal
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        No se puede asignar "{0}" a un valor marcado como literal
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Esta expresión admite indexación, por ejemplo "expr.[index]". La sintaxis "expr[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Este valor admite indexación, por ejemplo "{0}.[index]". La sintaxis "{1}[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Esta expresión no es una función y no admite la notación de índices.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        El valor "{0}" no es una función y no admite la notación de índices.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La sintaxis "expr1[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "expr1.[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La sintaxis "expr1[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La sintaxis "(expr1)[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "(expr1).[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La sintaxis "(expr1)[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]".
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        La construcción "let! ... and! ..." solo se puede usar si el generador de expresiones de cálculo define un método "{0}" o bien los métodos "MergeSource" y "Bind" adecuados.
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Código reanudable no válido. Un parámetro de código reanudable debe ser un delegado o un tipo de función
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Código reanudable no válido. El parámetro de código reanudable debe tener un nombre que comience por "__expand"
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Código reanudable no válido. Se ha producido "let rec" en la especificación de código reanudable
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Código reanudable no válido. Cualquier método de la función que acepte o devuelva código reanudable debe marcarse como "inline".
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Invocación de código reanudable. Suprima esta advertencia si va a definir un nuevo código reanudable de bajo nivel en términos del código reanudable existente.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        El uso de código reanudable o de máquinas de estado reanudables requiere /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Esta expresión convierte implícitamente el tipo '{0}' al tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Cadena interpolada no válida. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        El miembro de interfaz "{0}" no tiene una implementación más específica.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        "{0}" no puede implementar la interfaz "{1}" con ambas creaciones de instancias, "{2}" y "{3}", porque pueden unificarse.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        No se puede implementar la interfaz "{0}" con ambas creaciones de instancias, "{1}" y "{2}", porque pueden unificarse.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        El tipo "{0}" no define el campo, constructor o miembro "{1}".
+        
+      
       
         The namespace '{0}' is not defined.
         El espacio de nombres "{0}" no está definido.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Todas las ramas de una expresión de constructor de lista deben tener el mismo tipo. Se esperaba que esta expresión tuviera el tipo "{0}", pero aquí tiene el tipo "{1}".
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Todos los elementos de una lista deben poder convertirse implícitamente al tipo del primer elemento, que aquí es '{0}'. Este elemento tiene el tipo '{1}'.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Todos los elementos de una expresión de constructor de matriz deben tener el mismo tipo. Se esperaba que esta expresión tuviera el tipo "{0}", pero aquí tiene el tipo "{1}".
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Todos los elementos de una matriz deben poder convertirse implícitamente al tipo del primer elemento, que aquí es '{0}'. Este elemento tiene el tipo '{1}'.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Todas las ramas de una expresión "if" deben devolver el mismo tipo. Se esperaba que esta expresión tuviera el tipo "{0}", pero aquí tiene el tipo "{1}".
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Todas las ramas de una expresión "IF" deben devolver valores implícitamente convertibles al mismo tipo de la primera rama, el cual es "{0}" aquí. Esta rama devuelve el valor de tipo "{1}".
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Todas las ramas de una expresión de coincidencia de patrón deben devolver valores implícitamente convertibles al mismo tipo de la primera rama, el cual es "{0}" aquí. Esta rama devolvió un valor de tipo "{1}".
         
       
       
@@ -212,11 +922,51 @@
         Considere la posibilidad de usar "return!" en lugar de "return".
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Este atributo no es compatible actualmente con el compilador de F#. Si se aplica, no se obtendrá el efecto deseado.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Use ensamblados de referencia para las referencias de .NET Framework cuando estén disponibles (habilitado de forma predeterminada).
         
       
+      
+        This XML comment is invalid: '{0}'
+        El comentario XML no es válido: "{0}"
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        El comentario XML no es válido: hay varias entradas de documentación para el parámetro "{0}"
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        El comentario XML no es válido: parámetro "{0}" desconocido
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        El comentario XML no es válido: falta el atributo "cref" para la referencia cruzada
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        El comentario XML está incompleto: no hay documentación para el parámetro "{0}"
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        El comentario XML no es válido: falta el atributo "name" para el parámetro o la referencia de parámetro
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        El comentario XML no es válido: la referencia cruzada "{0}" no se ha resuelto
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Considere la posibilidad de usar "yield!" en lugar de "yield".
@@ -242,16 +992,6 @@
         Archivo de versión '{0}' no válido.
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Compilador de Microsoft (R) F#, versión {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Compilador F# para F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problema con el nombre de archivo '{0}': {1}.
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Se ha asignado más de un valor a un argumento con nombre.
+        The named argument '{0}' has been assigned more than one value
+        Se ha asignado más de un valor al argumento con nombre "{0}".
         
       
       
@@ -1114,7 +1854,7 @@
       
       
         A type with attribute 'CustomEquality' must have an explicit implementation of at least one of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable'
-        Un tipo con atributo "CustomEquality" debe tener una implementación explícita de al menos uno de "Object.Equals (obj)", "System.IEquatable<_&gt"' o "System.Collections.IStructuralEquatable"
+        Un tipo con atributo "CustomEquality" debe tener una implementación explícita de al menos uno de "Object.Equals (obj)", "System.IEquatable<_>"' o "System.Collections.IStructuralEquatable"
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Candidatos: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Las sobrecargas disponibles se muestran a continuación.
+        Candidates:\n{0}
+        Candidatos:\n{0}
         
       
       
@@ -2194,7 +2929,7 @@
       
       
         Incomplete conditional. Expected 'if <expr> then <expr>' or 'if <expr> then <expr> else <expr>'.
-        Condicional incompleta. Se esperaba "if <expr> then <expr>" o "if <expr> then <expr> else <expr&gt".
+        Condicional incompleta. Se esperaba "if <expr> then <expr>" o "if <expr> then <expr> else <expr>".
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Solo se admiten unidades de medida en los tipos float, float32, decimal y de entero firmado.
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Las unidades de medida solo se admiten en los tipos float, float32, decimal y de entero.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet se espera solo en árboles de análisis.
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet se espera solo en árboles de análisis.
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Expresión de indizador no válido.
+        Incomplete expression or invalid use of indexer syntax
+        Expresión incompleta o uso no válido de la sintaxis de indexador
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Solo los campos de registro y los enlaces 'let' sencillos no recursivos se pueden marcar como mutables
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Los enlaces "let" mutables no pueden ser recursivos ni estar definidos en espacios de nombres o módulos recursivos
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Una declaración solo puede ser el atributo [<Literal>] si también se proporciona un valor constante, por ejemplo, "val x: int = 1"
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -4239,17 +4974,17 @@
       
       
         Embed all source files in the portable PDB file
-        Inserta todos los archivos de código fuente en el archivo PDB portátil.
+        Inserta todos los archivos de código fuente en el archivo PDB portable.
         
       
       
         Embed specific source files in the portable PDB file
-        Inserta archivos de código fuente específicos en el archivo PDB portátil
+        Inserta archivos de código fuente específicos en el archivo PDB portable
         
       
       
         Source link information file to embed in the portable PDB file
-        Archivo de información de vínculos de origen para insertar en el archivo PDB portátil
+        Archivo de información de vínculos de origen para insertar en el archivo PDB portable
         
       
       
@@ -4264,7 +4999,7 @@
       
       
         Source file is too large to embed in a portable PDB
-        El archivo de código fuente es demasiado grande para insertarlo en un archivo PDB portátil
+        El archivo de código fuente es demasiado grande para insertarlo en un archivo PDB portable
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Este literal numérico no es válido. Entre los literales numéricos válidos se incluyen 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal) y 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Este literal numérico no es válido. Entre los literales numéricos válidos se incluyen 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal) y 1I (BigInteger).
         
       
       
@@ -5404,7 +6139,7 @@
       
       
         Unexpected quotation operator '<@' in type definition. If you intend to pass a verbatim string as a static argument to a type provider, put a space between the '<' and '@' characters.
-        Operador de cita inesperada "<@" en definición de tipo. Si desea pasar una cadena textual como un argumento estático a un proveedor de tipos, ponga un espacio entre los caracteres "&lt" y "@".
+        Operador de cita inesperada "<@" en definición de tipo. Si desea pasar una cadena textual como un argumento estático a un proveedor de tipos, ponga un espacio entre los caracteres "<" y "@".
         
       
       
@@ -5599,7 +6334,7 @@
       
       
         Static linking may not be used on an assembly referencing mscorlib (e.g. a .NET Framework assembly) when generating an assembly that references System.Runtime (e.g. a .NET Core or Portable assembly).
-        No se puede usar la vinculación estática en un ensamblado que haga referencia a mscorlib (por ejemplo, un ensamblado de .NET Framework) al generar un ensamblado que haga referencia a System.Runtime (por ejemplo, un ensamblado portátil o de .NET Core).
+        No se puede usar la vinculación estática en un ensamblado que haga referencia a mscorlib (por ejemplo, un ensamblado de .NET Framework) al generar un ensamblado que haga referencia a System.Runtime (por ejemplo, un ensamblado portable o de .NET Core).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        El atributo de ensamblado '{0}' hace referencia a un ensamblado de diseñador '{1}' que no se puede cargar o no existe. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        El atributo de ensamblado "{0}" hace referencia a un ensamblado de diseñador "{1}" que no se puede cargar desde la ruta de acceso "{2}". Se notificó la excepción: {3} - {4}.
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        Variable {0} de la colección
+        {0} var in collection
         
       
       
@@ -6199,7 +6934,7 @@
       
       
         Type '{0}' is illegal because in byref<T>, T cannot contain byref types.
-        El tipo "{0}" no es válido porque en  byref<T>, T no puede contener tipos byref.
+        El tipo "{0}" no es válido porque en byref<T>, T no puede contener tipos byref.
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Este valor no es una función y no se puede aplicar. ¿Pretendía tener acceso al indexador a través de {0}.[index] en su lugar?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Este valor no es una función y no se puede aplicar. ¿Quería tener acceso al indexador a través de "{0}.[index]"?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Esta expresión no es una función y no se puede aplicar. ¿Pretendía tener acceso al indexador a través de expr.[index] en su lugar?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Esta expresión no es una función y no se puede aplicar. ¿Quería acceder al indexador a través de "expr.[index]"?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Dos tipos de registros anónimos tienen conjuntos de nombres de campo que no coinciden "{0}" y "{1}"
+        Este registro anónimo no coincide exactamente con la forma esperada. Agregue los campos que faltan {0} y quite los campos adicionales {1}.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Referencia a un ensamblado o directorio que contiene una herramienta de tiempo de diseño (forma corta: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        La clave del administrador de paquetes "{0}" no se registró en {1}. Registrada actualmente: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        No se pudo cargar la extensión del administrador de dependencias {0}. Mensaje: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf
index 54296abddfd..2168a116c88 100644
--- a/src/fsharp/xlf/FSComp.txt.fr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.fr.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} pour F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        La fonctionnalité '{0}' n'est pas disponible en F# {1}. Utilisez la version de langage {2} ou une version ultérieure.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        La fonctionnalité '{0}' n'est pas prise en charge par le runtime cible.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        La fonctionnalité '{0}' nécessite la bibliothèque F# pour le langage version {1} ou ultérieure.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        L’utilisation de « := » à partir de la bibliothèque F# est déconseillée. Voir https://aka.ms/fsharp-refcell-ops. Par exemple, veuillez remplacer « cell := expr » par « cell.Value <- expr ».
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        L’utilisation de « decr » à partir de la bibliothèque F# est déconseillée. Voir https://aka.ms/fsharp-refcell-ops. Par exemple, veuillez remplacer « decr cell » par « cell.Value <- cell.Value - 1 ».
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        L’utilisation de « ! » à partir de la bibliothèque F# est déconseillée. Voir https://aka.ms/fsharp-refcell-ops. Par exemple, veuillez remplacer « !cell » par « cell.Value ».
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        L’utilisation de « incr » à partir de la bibliothèque F# est déconseillée. Voir https://aka.ms/fsharp-refcell-ops. Par exemple, veuillez remplacer « incr cell » par « cell.Value <- cell.Value + 1 ».
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        'AssemblyKeyNameAttribute' a été déprécié. Utilisez 'AssemblyKeyFileAttribute' à la place.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        La signature de conteneurs de clés n'est pas prise en charge sur cette plateforme.
+        
+      
+      
+        Available overloads:\n{0}
+        Surcharges disponibles :\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        L'utilisation d'une construction générique est possible uniquement si un paramètre de type générique est connu en tant que type struct ou type référence. Ajoutez une annotation de type.
+        
+      
+      
+        Known types of arguments: {0}
+        Types d'argument connus : {0}
+        
+      
+      
+        Known type of argument: {0}
+        Type d'argument connu : {0}
+        
+      
+      
+        Known return type: {0}
+        Type de retour connu : {0}
+        
+      
+      
+        Known type parameters: {0}
+        Paramètres de type connus : {0}
+        
+      
+      
+        Known type parameter: {0}
+        Paramètre de type connu : {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        L'argument à l'index {0} ne correspond pas
+        
+      
+      
+        Argument '{0}' doesn't match
+        L'argument '{0}' ne correspond pas
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Impossible de charger l'assembly de concepteur de fournisseur de type '{0}' à partir du dossier '{1}', car une dépendance est manquante ou n'a pas pu être chargée. Toutes les dépendances de l'assembly de concepteur de fournisseur de type doivent se trouver dans le même dossier que cet assembly. Exception signalée : {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Impossible de charger l'assembly de concepteur de fournisseur de type '{0}' à partir du dossier '{1}'. Exception signalée : {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        L'attribut d'assembly '{0}' fait référence à un assembly de concepteur '{1}' qui ne peut pas être chargé ou qui n'existe pas. Exception signalée : {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        conversions supplémentaires dirigées vers le type
+        
+      
+      
+        applicative computation expressions
+        expressions de calcul applicatives
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        attributs à droite du mot clé 'module'
+        
+      
+      
+        default interface member consumption
+        consommation par défaut des membres d'interface
+        
+      
+      
+        discard pattern in use binding
+        annuler le modèle dans la liaison d’utilisation
+        
+      
+      
+        dotless float32 literal
+        littéral float32 sans point
+        
+      
+      
+        more types support units of measure
+        d'autres types prennent en charge les unités de mesure
+        
+      
+      
+        fixed-index slice 3d/4d
+        section à index fixe 3D/4D
+        
+      
+      
+        from-end slicing
+        découpage depuis la fin
+        
+      
+      
+        implicit yield
+        yield implicite
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        Notation expr[idx] pour l’indexation et le découpage
+        
+      
+      
+        interfaces with multiple generic instantiation
+        interfaces avec plusieurs instanciations génériques
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        modèles non variables à droite de modèles « as »
+        
+      
+      
+        nullable optional interop
+        interopérabilité facultative pouvant accepter une valeur null
+        
+      
+      
+        open type declaration
+        déclaration de type ouverte
+        
+      
+      
+        overloads for custom operations
+        surcharges pour les opérations personnalisées
+        
+      
+      
+        package management
+        Package Management
+        
+      
+      
+        binary formatting for integers
+        mise en forme binaire pour les entiers
+        
+      
+      
+        informational messages related to reference cells
+        messages d’information liés aux cellules de référence
+        
+      
+      
+        whitespace relexation
+        assouplissement de la mise en retrait avec des espaces blancs
+        
+      
+      
+        whitespace relaxation v2
+        relaxation des espaces blancs v2
+        
+      
+      
+        resumable state machines
+        ordinateurs d’état pouvant être repris
+        
+      
+      
+        single underscore pattern
+        modèle de trait de soulignement unique
+        
+      
+      
+        string interpolation
+        interpolation de chaîne
+        
+      
+      
+        struct representation for active patterns
+        représentation de structure pour les modèles actifs
+        
+      
+      
+        wild card in for loop
+        caractère générique dans une boucle for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Passage de témoin pour les contraintes de trait dans les quotations F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Les chaînes interpolées ne peuvent pas utiliser les spécificateurs de format '%' à moins de recevoir une expression, par exemple '%d{{1+1}}'.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Les spécificateurs de format de style .NET tels que '{{x,3}}' et '{{x:N5}}' ne peuvent pas être combinés avec les spécificateurs de format '%'.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Le spécificateur '%P' ne peut pas être utilisé explicitement.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Les chaînes interpolées utilisées en tant que type IFormattable ou FormattableString ne peuvent pas utiliser les spécificateurs '%'. Seuls les spécificateurs de style .NET tels que '{{expr}}', '{{expr,3}}' et '{{expr:N5}}' peuvent être utilisés.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        L'extraction à partir de la fin nécessite la version 5.0 du langage. Utilisez /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Directive non valide '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        La construction de code pouvant être repris «{0}» ne peut être utilisée que dans du code inlined protégé par «if __useResumableCode then ...» et la composition globale doit former un code pouvant être repris valide.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        L’attribut « InlineIfLambda » est présent dans la signature, mais pas dans l’implémentation.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Mot clé permettant de spécifier une constante littérale en tant qu'argument de paramètre de type dans les fournisseurs de types.
+        
+      
+      
+        a byte string may not be interpolated
+        une chaîne d'octets ne peut pas être interpolée
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Un caractère '}}' doit faire l'objet d'une séquence d'échappement (par doublement) dans une chaîne interpolée.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Chaîne interpolée non valide. Les littéraux de chaîne verbatim ou à guillemet simple ne peuvent pas être utilisés dans les expressions interpolées dans des chaînes verbatim ou à guillemet simple. Utilisez une liaison 'let' explicite pour l'expression d'interpolation ou une chaîne à guillemets triples comme littéral de chaîne externe.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Chaîne interpolée non valide. Les littéraux de chaîne à guillemets triples ne peuvent pas être utilisés dans des expressions interpolées. Utilisez une liaison 'let' explicite pour l'expression d'interpolation.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         L'en-tête de ressource commençant au décalage {0} est mal formé.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Cette expression n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « expr[index] »?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Cette valeur n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « {0}[index] » ?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        La valeur «{0} » a été marquée comme « InlineIfLambda », mais elle n’a pas été déterminée comme ayant une valeur lambda. Cet avertissement est à titre d’information uniquement.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Imprimer les interfaces inférées de tous les fichiers de compilation sur les fichiers de signature associés
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Afficher les valeurs autorisées pour la version du langage, spécifier la version du langage comme 'dernière' ou 'préversion'
@@ -37,9 +417,49 @@
         Valeur non reconnue '{0}' pour --langversion use --langversion:? pour la liste complète
         
       
+      
+        Display compiler version banner and exit
+        Afficher la bannière de la version du compilateur et quitter
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Spécifier un fichier icône (.ico) Win32
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        La fonctionnalité de gestion des packages nécessite la version 5.0 du langage. Utilisez /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Chaîne interpolée non valide. Le remplissage de cette expression de chaîne interpolée est vide. Une expression est attendue.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Chaîne interpolée incomplète ayant débuté à cet emplacement ou avant
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Remplissage d'expression de chaîne interpolée incomplet ayant débuté à cet emplacement ou avant
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Chaîne à guillemets triples interpolée incomplète ayant débuté à cet emplacement ou avant
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Chaîne verbatim interpolée incomplète ayant débuté à cet emplacement ou avant
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Jeton inattendu dans la définition de type. Signe '=' attendu après le type '{0}'.
         
       
       
@@ -57,19 +477,109 @@
         Algorithme '{0}' non pris en charge
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Une étiquette cible pour __resumeAt n’a pas été déterminée de manière statique. Un __resumeAt avec une étiquette cible non statique ne peut apparaître qu’au début d’une méthode de code repris
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Un entier rapide pour la boucle peut ne pas contenir de points de reprise
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        Un «let rec» s’est produit dans la spécification de code pouvant être repris
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Le bloc « with » d’un bloc try/with ne peut pas contenir de points de reprise
+        
+      
+      
+        A try/finally may not contain resumption points
+        Un try/finally peut ne pas contenir de points de reprise
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Un délégué ou une fonction produisant du code pouvant être reprise dans un ordinateur d’état a des paramètres de type
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Un appel de code pouvant être repris à «{0}» n’a pas pu être réduit
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        La ou les valeurs de code pouvant être repris «{0}» n’ont pas de définition
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i n'est pas pris en charge par les PackageManagers inscrits
+        
+      
+      
+        The state machine has an unexpected form
+        La machine d’état présente une forme inattendue
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Cet ordinateur d’état n’est pas compilable statiquement. {0}. Une autre implémentation dynamique sera utilisée, ce qui peut être plus lent. Envisagez d’ajuster votre code pour vous assurer que cet ordinateur d’état est compilable statiquement, ou supprimez cet avertissement.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Cet ordinateur d’état n’est pas compilable statiquement et aucune alternative n’est disponible. {0}. Utilisez un «if __useResumableCode puis <state-machine>else <alternative>» pour donner une alternative.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Le kit SDK .NET de ce script n'a pas pu être déterminé. Si le script se trouve dans un répertoire utilisant un fichier 'global.json', vérifiez que le kit SDK .NET approprié est installé. La sortie de '{0} --version' dans le répertoire '{1}' était '{2}', et le code de sortie était '{3}'.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Impossible de déterminer le Kit de développement logiciel (SDK) .NET pour ce script. dotnet.exe est introuvable pour garantir l’installation d’un kit SDK .NET.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Le kit SDK .NET de ce script n'a pas pu être déterminé. Si le script se trouve dans un répertoire utilisant un fichier 'global.json', vérifiez que le kit SDK .NET approprié est installé. Erreur inattendue '{0}'.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Cette expression a le type « {0} » et est uniquement compatible avec le type « {1} » via une conversion implicite ambiguë. Envisagez d’utiliser un appel explicite à’op_Implicit'. Les conversions implicites applicables sont : {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Cette fonctionnalité n'est pas prise en charge dans cette version de F#. Vous devrez peut-être ajouter /langversion:preview pour pouvoir utiliser cette fonctionnalité.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Il s'agit de l'enregistrement anonyme incorrect. Il doit contenir les champs {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Cet enregistrement anonyme ne contient pas suffisamment de champs. Ajoutez les champs manquants {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Cet enregistrement anonyme a trop de champs. Supprimez les champs supplémentaires {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Déclaration de type d'enregistrement anonyme non valide.
         
       
       
@@ -77,6 +587,206 @@
         Impossible d'appliquer des attributs aux extensions de type.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        La syntaxe « expr1[expr2] » est utilisée pour l’indexation. Envisagez d’ajouter une annotation de type pour activer l’indexation, ou si vous appelez une fonction, ajoutez un espace, par exemple « expr1 [expr2] ».
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        La syntaxe « expr1[expr2] » est désormais réservée à l’indexation. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction, ajoutez un espace entre la fonction et l’argument, par exemple « someFunction [expr] ».
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Les types Byref ne sont pas autorisés dans une déclaration de type ouverte.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        La syntaxe « arr.[idx] » est maintenant remplacée par « arr[idx] ». Veuillez mettre à jour votre code.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Cette expression utilise une conversion implicite intégrée pour convertir le type « {0} » en type « {1} ». Voir https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Cette expression utilise la conversion implicite « {0} » pour convertir le type « {1} » en type « {2} ».
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Cette expression utilise la conversion implicite « {0}<» pour convertir le type « {1} » en type « {2} ». Voir https://aka.ms/fsharp-implicit-convs. Cet avertissement peut être désactivé à l’aide de '#nowarn \"3391\".
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        L’attribut « InlineIfLambda » ne peut être utilisé que sur les paramètres des fonctions incorporées des méthodes dont le type est une fonction ou un type délégué F#.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Incompatibilité dans la chaîne interpolée. Les chaînes interpolées ne peuvent pas utiliser les spécificateurs de format '%' à moins de recevoir une expression, par exemple '%d{{1+1}}'
+        
+      
+      
+        Invalid alignment in interpolated string
+        Alignement non valide dans la chaîne interpolée
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        La construction «{0}» ne peut être utilisée que dans un code pouvant être repris valide.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        L’utilisation de' [<Struct>] 'sur les valeurs, les fonctions et les méthodes n’est autorisée que sur les définitions de modèle actif partiel
+        
+      
+      
+        use! may not be combined with and!
+        use! ne peut pas être combiné avec and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Utilisation non valide de l’index inverse dans l’expression de liste.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La syntaxe « [expr1][expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « (expr1).[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction [expr1] [expr2] ».
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La syntaxe « [expr1][expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction [expr1] [expr2] ».
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Une déclaration [<Literal>] ne peut pas utiliser un modèle actif en tant qu'identificateur
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Impossible d'affecter une valeur à une autre valeur marquée comme littérale
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Impossible d'affecter '{0}' à une valeur marquée comme littérale
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Cette expression prend en charge l’indexation, par exemple « expr.[index] ». La syntaxe « expr[index] » requiert /langversion:preview. Voir https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Cette valeur prend en charge l’indexation, par exemple « {0}.[index] ». La syntaxe « {1}[index] » nécessite /langversion:preview. Voir https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Cette expression n’est pas une fonction et ne prend pas en charge la notation d’index.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        La valeur « {0} » n’est pas une fonction et ne prend pas en charge la notation d’index.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La syntaxe « expr1[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « expr1.[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ».
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La syntaxe « expr1[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ».
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La syntaxe « (expr1)[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « (expr1).[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ».
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La syntaxe « (expr1)[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ».
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        La construction 'let! ... and! ...' peut uniquement être utilisée si le générateur d'expressions de calcul définit une méthode '{0}' ou les méthodes 'MergeSource' et 'Bind' appropriées
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Code pouvant être repris non valide. Un paramètre de code pouvant être repris doit être de type délégué ou de fonction
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Code pouvant être reprise non valide. Le paramètre de code pouvant être repris doit avoir un nom commençant par « __expand »
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Code pouvant être reprise non valide. Un «let rec» s’est produit dans la spécification de code pouvant être repris
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Code pouvant être repris non valide. Toute méthode de fonction acceptant ou retournant du code pouvant être repris doit être marquée «inline»
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Appel de code pouvant être repris. Supprimez cet avertissement si vous définissez un nouveau code pouvant être repris de bas niveau en termes de code pouvant être repris existant.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        L’utilisation de code pouvant être repris ou de machines d’état pouvant être reprises nécessite /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Cette expression convertit implicitement le type « {0} » en type « {1} ». Voir https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Chaîne interpolée non valide. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Le membre d'interface '{0}' n'a pas l'implémentation la plus spécifique.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        '{0}' ne peut pas implémenter l'interface '{1}' avec les deux instanciations '{2}' et '{3}', car elles peuvent s'unifier.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Vous ne pouvez pas implémenter l'interface '{0}' avec les deux instanciations '{1}' et '{2}', car elles peuvent s'unifier.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Le type '{0}' ne définit pas le champ, le constructeur ou le membre '{1}'.
+        
+      
       
         The namespace '{0}' is not defined.
         L'espace de noms '{0}' n'est pas défini.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Tous les éléments d'une expression comportant un constructeur de liste doivent avoir le même type. Cette expression était censée avoir le type '{0}', mais elle a ici le type '{1}'.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Tous les éléments d'une liste doivent être implicitement convertibles dans le type du premier élément, qui est ici '{0}'. Cet élément a le type '{1}'.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Tous les éléments d'une expression comportant un constructeur de tableau doivent avoir le même type. Cette expression était censée avoir le type '{0}', mais elle a ici le type '{1}'.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Tous les éléments d'un tableau doivent être implicitement convertibles dans le type du premier élément, qui est ici '{0}'. Cet élément a le type '{1}'.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Toutes les branches d'une expression 'if' doivent avoir le même type. Cette expression était censée avoir le type '{0}', mais elle a ici le type '{1}'.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Toutes les branches d'une expression 'if' doivent retourner des valeurs implicitement convertibles au type de la première branche, qui est ici '{0}'. Cette branche renvoie une valeur de type '{1}'.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Toutes les branches d'une expression comportant des critères spéciaux doivent retourner des valeurs du même type. La première branche a retourné une valeur de type '{0}', mais cette branche a retourné une valeur de type '{1}'.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Toutes les branches d'une expression de correspondance de modèle doivent retourner des valeurs implicitement convertibles au type de la première branche, qui est ici '{0}'. Cette branche renvoie une valeur de type '{1}'.
         
       
       
@@ -212,11 +922,51 @@
         Utilisez 'return!' à la place de 'return'.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Cet attribut n’est actuellement pas pris en charge par le compilateur F #. L’application de celui-ci n’obtiendra pas l’effet souhaité.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Utilisez des assemblys de référence pour les références .NET Framework quand ils sont disponibles (activé par défaut).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Ce commentaire XML est non valide : '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Ce commentaire XML est non valide : il existe plusieurs entrées de documentation pour le paramètre '{0}'
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Ce commentaire XML est non valide : paramètre inconnu '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Ce commentaire XML est non valide : attribut 'cref' manquant pour la référence croisée
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Ce commentaire XML est incomplet : il n'existe aucune documentation pour le paramètre '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Ce commentaire XML est non valide : attribut 'name' manquant pour le paramètre ou la référence de paramètre
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Ce commentaire XML est non valide : référence croisée non résolue '{0}'
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Utilisez 'yield!' à la place de 'yield'.
@@ -242,16 +992,6 @@
         Fichier de version non valide '{0}'
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Compilateur F# Microsoft (R) version {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Compilateur F# pour F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problème avec le nom de fichier '{0}' : {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Plusieurs valeurs ont été assignées à un argument nommé
+        The named argument '{0}' has been assigned more than one value
+        Plusieurs valeurs ont été affectées à l'argument nommé '{0}'
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Candidats : {0}
-        
-      
-      
-        The available overloads are shown below.
-        Les surcharges disponibles sont affichées ci-dessous.
+        Candidates:\n{0}
+        Candidats :\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Unités de mesure prises en charge uniquement pour les types float, float32, decimal et integer signés
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Les unités de mesure sont seulement prises en charge pour les types float, float32, decimal et integer.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet attendu uniquement dans les arborescences d'analyse
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet attendu uniquement dans les arborescences d'analyse
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Expression d'indexeur non valide
+        Incomplete expression or invalid use of indexer syntax
+        Expression incomplète ou utilisation non valide de la syntaxe de l’indexeur
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Seuls les champs d'enregistrement et les liaisons 'let' simples non récursives peuvent être marqués comme mutables
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Les liaisons 'let' mutables ne peuvent pas être récursives ou définies dans des modules ou espaces de noms récursifs
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Une déclaration peut seulement être l'attribut [<Literal>] si une valeur constante est aussi donnée, par ex. 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Littéral numérique non valide. Littéraux numériques valides : 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Littéral numérique non valide. Littéraux numériques valides : 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        L'attribut d'assembly '{0}' fait référence à un assembly de concepteur '{1}' qui ne peut pas être chargé ou qui n'existe pas. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        L'attribut d'assembly '{0}' fait référence à un assembly de concepteur '{1}' qui ne peut pas être chargé à partir du chemin '{2}'. Exception signalée : {3} - {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        var {0} dans la collection
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Cette valeur n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via {0}.[index] ?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Cette valeur n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « {0}.[index] » ?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Cette expression n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via expr.[index] ?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Cette expression n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « expr.[index] » ?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Deux types d'enregistrement anonyme ont des ensembles de noms de champ incompatibles '{0}' et '{1}'
+        Cet enregistrement anonyme ne correspond pas exactement à la forme attendue. Ajoutez les champs manquants {0} et supprimez les champs supplémentaires {1}.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Référence un assembly ou un répertoire contenant un outil design-time (forme courte : -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        La clé '{0}' du gestionnaire de packages n'était pas inscrite dans {1}. L'inscription a été effectuée : {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Impossible de charger l'extension du gestionnaire de dépendances {0}. Message : {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf
index 850e1233e6a..efe83d5e100 100644
--- a/src/fsharp/xlf/FSComp.txt.it.xlf
+++ b/src/fsharp/xlf/FSComp.txt.it.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} per F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        La funzionalità '{0}' non è disponibile in F# {1}. Usare la versione {2} o versioni successive del linguaggio.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        La funzionalità '{0}' non è supportata dal runtime di destinazione.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        Con la funzionalità '{0}' è richiesta la libreria F# per la versione {1} o successiva del linguaggio.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        L'uso di ':=' dalla libreria F # è deprecato. Vedere https://aka.ms/fsharp-refcell-ops. Ad esempio, modificare 'cell:= expr' in 'cell.Value <- expr'.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        L'uso di 'decr' dalla libreria F # è deprecato. Vedere https://aka.ms/fsharp-refcell-ops. Ad esempio, modificare 'decr cell' in 'cell.Value <- cell.Value - 1'.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        L'uso di '!' dalla libreria F # è deprecato. Vedere https://aka.ms/fsharp-refcell-ops. Ad esempio, modificare '!cell' in 'cell.Value'.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        L'uso di 'incr' dalla libreria F # è deprecato. Vedere https://aka.ms/fsharp-refcell-ops. Ad esempio, modificare 'incr cell' in 'cell.Value <- cell.Value + 1'.
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        L'attributo 'AssemblyKeyNameAttribute' è deprecato. In alternativa, usare 'AssemblyKeyFileAttribute'.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        La firma del contenitore di chiavi non è supportata in questa piattaforma.
+        
+      
+      
+        Available overloads:\n{0}
+        Overload disponibili:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Un costrutto generico richiede che un parametro di tipo generico sia noto come tipo riferimento o struct. Provare ad aggiungere un'annotazione di tipo.
+        
+      
+      
+        Known types of arguments: {0}
+        Tipi di argomenti noti: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Tipo di argomento noto: {0}
+        
+      
+      
+        Known return type: {0}
+        Tipo restituito noto: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Parametri di tipo noti: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Parametro di tipo noto: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        L'argomento alla posizione di indice {0} non corrisponde
+        
+      
+      
+        Argument '{0}' doesn't match
+        L'argomento '{0}' non corrisponde
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Non è stato possibile caricare l'assembly '{0}' della finestra di progettazione del provider di tipi dalla cartella '{1}' perché una dipendenza non è presente o non è stato possibile caricarla. Tutte le dipendenze dell'assembly della finestra di progettazione del provider di tipi devono trovarsi nella stessa cartella dell'assembly. L'eccezione restituita è {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Non è stato possibile caricare l'assembly '{0}' della finestra di progettazione del provider di tipi dalla cartella '{1}'. L'eccezione restituita è {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        L'attributo di assembly '{0}' fa riferimento a un assembly '{1}' della finestra di progettazione che non è stato caricato o non esiste. L'eccezione restituita è {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        conversioni aggiuntive dirette ai tipi
+        
+      
+      
+        applicative computation expressions
+        espressioni di calcolo applicativo
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        attributi a destra della parola chiave 'module'
+        
+      
+      
+        default interface member consumption
+        utilizzo predefinito dei membri di interfaccia
+        
+      
+      
+        discard pattern in use binding
+        rimuovi criterio nell'utilizzo dell'associazione
+        
+      
+      
+        dotless float32 literal
+        valore letterale float32 senza punti
+        
+      
+      
+        more types support units of measure
+        più tipi supportano le unità di misura
+        
+      
+      
+        fixed-index slice 3d/4d
+        sezione a indice fisso 3D/4D
+        
+      
+      
+        from-end slicing
+        sezionamento dalla fine
+        
+      
+      
+        implicit yield
+        istruzione yield implicita
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        Notazione expr[idx] per l'indicizzazione e il sezionamento
+        
+      
+      
+        interfaces with multiple generic instantiation
+        interfacce con più creazioni di istanze generiche
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        modelli non variabili a destra dei modelli 'as'
+        
+      
+      
+        nullable optional interop
+        Interop facoltativo nullable
+        
+      
+      
+        open type declaration
+        dichiarazione di tipo aperto
+        
+      
+      
+        overloads for custom operations
+        overload per le operazioni personalizzate
+        
+      
+      
+        package management
+        gestione pacchetti
+        
+      
+      
+        binary formatting for integers
+        formattazione binaria per interi
+        
+      
+      
+        informational messages related to reference cells
+        messaggi informativi relativi alle celle di riferimento
+        
+      
+      
+        whitespace relexation
+        uso meno restrittivo degli spazi vuoti
+        
+      
+      
+        whitespace relaxation v2
+        uso meno restrittivo degli spazi vuoti v2
+        
+      
+      
+        resumable state machines
+        macchine a stati ripristinabili
+        
+      
+      
+        single underscore pattern
+        criterio per carattere di sottolineatura singolo
+        
+      
+      
+        string interpolation
+        interpolazione di stringhe
+        
+      
+      
+        struct representation for active patterns
+        rappresentazione struct per criteri attivi
+        
+      
+      
+        wild card in for loop
+        carattere jolly nel ciclo for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Passaggio del testimone per vincoli di tratto in quotation F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Nelle stringhe interpolate non è possibile usare gli identificatori di formato '%' a meno che non si indichi un'espressione per ognuno di essi, ad esempio '%d{{1+1}}'.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Non è possibile combinare gli identificatori di formato di tipo .NET, come '{{x,3}}' o '{{x:N5}}', con gli identificatori di formato '%'.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Non è possibile usare in modo esplicito l'identificatore '%P'.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Nelle stringhe interpolate usate come tipo IFormattable o FormattableString non è possibile usare gli identificatori '%', ma è possibile usare solo interpolanti di tipo .NET, come '{{expr}}', '{{expr,3}}' o '{{expr:N5}}'.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Con il sezionamento dalla fine è richiesta la versione 5.0 del linguaggio. Usare /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Direttiva '#{0} {1}' non valida
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Il costrutto di codice ripristinabile '{0}' può essere usato solo nel codice impostato come inline e protetto da 'if __useResumableCode then...' e l'intera composizione deve formare codice ripristinabile valido.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        L'attributo 'InlineIfLambda' è presente nella firma, ma non nell'implementazione.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Parola chiave per specificare un valore letterale di costante come argomento del parametro di tipo in Provider di tipi.
+        
+      
+      
+        a byte string may not be interpolated
+        non è possibile interpolare una stringa di byte
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        In una stringa interpolata è necessario specificare il carattere di escape di un carattere '}}' raddoppiandolo.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        La stringa interpolata non è valida. Non è possibile usare valori letterali stringa tra virgolette singole o verbatim in espressioni interpolate in stringhe verbatim o tra virgolette singole. Provare a usare un binding 'let' esplicito per l'espressione di interpolazione oppure usare una stringa tra virgolette triple come valore letterale stringa esterno.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        La stringa interpolata non è valida. Non è possibile usare valori letterali stringa tra virgolette triple in espressioni interpolate. Provare a usare un binding 'let' esplicito per l'espressione di interpolazione.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         L'intestazione di risorsa che inizia a partire dall'offset {0} non è valida.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Questa espressione non è una funzione e non può essere applicata. Si intendeva accedere all'indicizzatore tramite la sintassi 'expr[index]'?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Questo valore non è una funzione e non può essere applicato. Si intendeva accedere all'indicizzatore tramite la sintassi '{0}[index]'?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        Il valore '{0}' è stato contrassegnato come 'InlineIfLambda', ma è stato determinato che non include un valore lambda. Questo avviso viene visualizzato solo a scopo informativo.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Stampare le interfacce derivate di tutti i file di compilazione nei file di firma associati
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Visualizza i valori consentiti per la versione del linguaggio. Specificare la versione del linguaggio, ad esempio 'latest' o 'preview'
@@ -37,9 +417,49 @@
         Valore '{0}' non riconosciuto per --langversion. Per l'elenco completo usare --langversion:?
         
       
+      
+        Display compiler version banner and exit
+        Visualizza il banner della versione del compilatore ed esce
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Specifica un file icona Win32 (.ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Con la funzionalità di gestione pacchetti è richiesta la versione 5.0 del linguaggio. Usare /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        La stringa interpolata non è valida. Il riempimento espressione di questa stringa interpolata è vuoto, mentre era prevista un'espressione.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        La stringa interpolata incompleta inizia in questa posizione o prima di essa
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Il riempimento espressione della stringa interpolata incompleta inizia in questa posizione o prima di essa
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        La stringa interpolata incompleta tra virgolette triple inizia in questa posizione o prima di essa
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        La stringa verbatim interpolata incompleta inizia in questa posizione o prima di essa
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Token imprevisto nella definizione del tipo. Dopo il tipo '{0}' è previsto '='.
         
       
       
@@ -57,19 +477,109 @@
         L'algoritmo '{0}' non è supportato
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Un'etichetta di destinazione per __resumeAt non è stata determinata in modo statico. Un elemento __resumeAt con un'etichetta di destinazione non statica può essere presente solo all'inizio di un metodo di codice ripristinabile
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Un ciclo fast integer for non può contenere punti di ripresa
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        È stata rilevata una funzione 'let rec' nella specifica del codice ripristinabile
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Il blocco 'with' di un'espressione try/with non può contenere punti di consumo
+        
+      
+      
+        A try/finally may not contain resumption points
+        Un'espressione try/finally non può contenere punti di ripresa
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Un delegato o una funzione che produce codice ripristinabile in una macchina a stati include parametri di tipo
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Non è stato possibile ridurre la chiamata del codice ripristinabile alla posizione '{0}'
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        Non esiste alcuna definizione per il valore o i valori '{0}' del codice ripristinabile
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i non è supportato dagli elementi PackageManager registrati
+        
+      
+      
+        The state machine has an unexpected form
+        La macchina a stati presenta un formato imprevisto
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Questa macchina a stati non è compilabile in modo statico. {0}. Verrà usata un'implementazione dinamica alternativa, che potrebbe essere più lenta. Provare a modificare il codice per assicurarsi che la macchina a stati sia compilabile in modo statico oppure disabilitare questo avviso.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Questa macchina a stati non è compilabile in modo statico e non è disponibile alcuna alternativa. {0}. Usare 'if __useResumableCode then <macchina-a-stati> else <alternativa>' per fornire un'alternativa.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Non è stato possibile determinare la versione di .NET SDK per questo script. Se lo script si trova in una directory che usa un file 'global.json', assicurarsi che sia installata la versione pertinente di .NET SDK. L'output di '{0} --version' nella directory '{1}' è '{2}' e il codice di uscita è '{3}'.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Non e stato possibile determinare il Software Development Kit .NET per questo script. Non è stato possibile trovare dotnet.exe; assicurarsi che sia installato un Software Development Kit .NET.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Non è stato possibile determinare la versione di .NET SDK per questo script. Se lo script si trova in una directory che usa un file 'global.json', assicurarsi che sia installata la versione pertinente di .NET SDK. Errore imprevisto: '{0}'.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Questa espressione di tipo '{0}' è resa compatibile con il tipo '{1}' solo tramite una conversione implicita ambigua. Provare a usare una chiamata esplicita a 'op_Implicit'. Le conversioni implicite applicabili sono: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Questa funzionalità non è supportata in questa versione di F#. Per usare questa funzionalità, potrebbe essere necessario aggiungere /langversion:preview.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Si tratta del record anonimo errato. Deve includere i campi {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Questo record anonimo non contiene un numero sufficiente di campi. Aggiungere i campi mancanti {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Questo record anonimo contiene troppi campi. Rimuovere i campi aggiuntivi {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        La dichiarazione di tipo Record anonimo non è valida.
         
       
       
@@ -77,6 +587,206 @@
         Gli attributi non possono essere applicati a estensioni di tipo.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        La sintassi 'expr1[expr2]' viene usata per l'indicizzazione. Provare ad aggiungere un'annotazione di tipo per abilitare l'indicizzazione oppure se la chiamata a una funzione aggiunge uno spazio, ad esempio 'expr1 [expr2]'.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        La sintassi 'expr1[expr2]' è ora riservata per l'indicizzazione. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione, aggiungere uno spazio tra la funzione e l'argomento, ad esempio 'someFunction [expr]'.
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        I tipi byref non sono consentiti in una dichiarazione di tipo aperto.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        La sintassi 'arr.[idx]' è ora modificata in 'arr[idx]'. Aggiornare il codice.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Questa espressione usa una conversione implicita predefinita per convertire il tipo '{0}' nel tipo '{1}'. Vedere https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Questa espressione usa la conversione implicita '{0}' per convertire il tipo '{1}' nel tipo '{2}'.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Questa espressione usa la conversione implicita '{0}' per convertire il tipo '{1}' nel tipo '{2}'. Vedere https://aka.ms/fsharp-implicit-convs. Per disabilitare questo avviso, usare '#nowarn \"3391\"'.
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        L'attributo 'InlineIfLambda' può essere usato solo in parametri di funzioni impostate come inline di metodi il cui tipo è un tipo di funzione o delegato F#.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Mancata corrispondenza nella stringa interpolata. Nelle stringhe interpolate non è possibile usare gli identificatori di formato '%' a meno che non si indichi un'espressione per ognuno di essi, ad esempio '%d{{1+1}}'
+        
+      
+      
+        Invalid alignment in interpolated string
+        Allineamento non valido nella stringa interpolata
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        Il costrutto '{0}' può essere usato solo in codice ripristinabile valido.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        L'utilizzo di '[<Struct>]' su valori, funzioni e metodi è consentito solo per definizioni di criteri attivi parziali
+        
+      
+      
+        use! may not be combined with and!
+        Non è possibile combinare use! con and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Utilizzo non valido dell'indice inverso nell'espressione di elenco.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La sintassi '[expr1][expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare '(expr1). [expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction [expr1] [expr2]'.
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        La sintassi '[expr1][expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction [expr1] [expr2]'.
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Una dichiarazione [<Literal>] non può usare un criterio attivo per il relativo identificatore
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Non è possibile assegnare un valore a un altro valore contrassegnato come letterale
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Non è possibile assegnare '{0}' a un valore contrassegnato come letterale
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Questa espressione supporta l'indicizzazione, ad esempio 'expr.[index]'. La sintassi 'expr[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation..
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Questo valore supporta l'indicizzazione, ad esempio '{0}.[index]'. La sintassi '{1}[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Questa espressione non è una funzione e non supporta la notazione degli indici.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        Questo valore '{0}' non è una funzione e non supporta la notazione degli indici.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La sintassi 'expr1[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare 'expr1.[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        La sintassi 'expr1[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La sintassi '(expr1)[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare '(expr1).[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        La sintassi '(expr1)[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'.
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        È possibile usare il costrutto 'let! ... and! ...' solo se il generatore di espressioni di calcolo definisce un metodo '{0}' o metodi 'MergeSource' e 'Bind' appropriati
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Codice ripristinabile non valido. Un parametro del codice ripristinabile deve essere di tipo delegato o funzione
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Codice ripristinabile non valido. Il nome del parametro del codice ripristinabile deve iniziare con '__expand'
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Codice ripristinabile non valido. È stato rilevata una funzione 'let rec' nella specifica del codice ripristinabile
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Codice ripristinabile non valido. Qualsiasi metodo della funzione che accetta o restituisce codice ripristinabile deve essere contrassegnato come 'inline'
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Chiamata del codice ripristinabile. Disabilitare questo avviso se si intende definire nuovo codice ripristinabile di basso livello in termini di codice ripristinabile esistente.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Per l'uso del codice ripristinabile o delle macchine a stati ripristinabili è richiesto /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Questa espressione converte in modo implicito il tipo '{0}' nel tipo '{1}'. Vedere https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        La stringa interpolata non è valida. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Il membro di interfaccia '{0}' non contiene un'implementazione più specifica.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        '{0}' non può implementare l'interfaccia '{1}' con le due creazioni di istanze '{2}' e '{3}' perché possono essere unificate.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Non è possibile implementare l'interfaccia '{0}' con le due creazioni di istanze '{1}' e '{2}' perché possono essere unificate.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Il tipo '{0}' non definisce il campo, il costruttore o il membro '{1}'.
+        
+      
       
         The namespace '{0}' is not defined.
         Lo spazio dei nomi '{0}' non è definito.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Il tipo di tutti gli elementi di un'espressione di costruttore di elenco deve essere lo stesso. Il tipo previsto di questa espressione è '{0}', ma quello effettivo è '{1}'.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Tutti gli elementi di un elenco devono essere implicitamente convertibili nel tipo del primo elemento, che in questo caso è '{0}'. Il tipo di questo elemento è '{1}'.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Il tipo di tutti gli elementi di un'espressione di costruttore di matrice deve essere lo stesso. Il tipo previsto di questa espressione è '{0}', ma quello effettivo è '{1}'.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Tutti gli elementi di una matrice devono essere implicitamente convertibili nel tipo del primo elemento, che in questo caso è '{0}'. Il tipo di questo elemento è '{1}'.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Il tipo di tutti i rami di un'espressione 'if' deve essere lo stesso. Il tipo previsto di questa espressione è '{0}', ma quello effettivo è '{1}'.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Tutti i rami di un'espressione 'if' devono restituire valori implicitamente convertibili nel tipo del primo ramo, che in questo caso è '{0}'. Questo ramo restituisce un valore di tipo '{1}'.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Tutti i rami di un'espressione di criteri di ricerca devono restituire valori dello stesso tipo. Il primo ramo ha restituito un valore di tipo '{0}', ma questo ramo ha restituito un valore di tipo '{1}'.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Tutti i rami di un'espressione di criteri di ricerca devono restituire valori implicitamente convertibili nel tipo del primo ramo, che in questo caso è '{0}'. Questo ramo restituisce un valore di tipo '{1}'.
         
       
       
@@ -212,11 +922,51 @@
         Provare a usare 'return!' invece di 'return'.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Questo attributo non è attualmente supportato dal compilatore F #. L'applicazione non riuscirà a ottenere l'effetto previsto.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Usa gli assembly di riferimento per i riferimenti a .NET Framework quando disponibili (abilitato per impostazione predefinita).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Questo commento XML non è valido: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Questo commento XML non è valido: sono presenti più voci della documentazione per il parametro '{0}'
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Questo commento XML non è valido: il parametro '{0}' è sconosciuto
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Questo commento XML non è valido: manca l'attributo 'cref' per il riferimento incrociato
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Questo commento XML è incompleto: non è presente la documentazione per il parametro '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Questo commento XML non è valido: manca l'attributo 'name' per il parametro o il riferimento a parametro
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Questo commento XML non è valido: il riferimento incrociato '{0}' non è stato risolto
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Provare a usare 'yield!' invece di 'yield'.
@@ -242,16 +992,6 @@
         File di versione '{0}' non valido
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Compilatore Microsoft (R) F# versione {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Compilatore F# per F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problema con il nome di file '{0}': {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        A un argomento denominato sono stati assegnati più valori
+        The named argument '{0}' has been assigned more than one value
+        All'argomento denominato '{0}' sono stati assegnati più valori
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Candidati: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Gli overload disponibili sono indicati di seguito.
+        Candidates:\n{0}
+        Candidati:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Unità di misura supportata solo in tipi float, float32, decimal e Integer con segno
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Le unità di misura sono supportate solo in tipi float, float32, decimal e Integer.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet previsto solo in strutture ad albero di analisi
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet previsto solo in strutture ad albero di analisi
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Espressione di indicizzatore non valida
+        Incomplete expression or invalid use of indexer syntax
+        Espressione incompleta o uso non valido della sintassi dell'indicizzatore
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Solo i campi di record e i binding 'let' semplici non ricorsivi possono essere contrassegnati come mutable
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        I binding 'let' modificabili non possono essere ricorsivi o definiti in moduli o spazi dei nomi ricorsivi
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Una dichiarazione può essere solo l'attributo [<Literal>] se è specificato anche un valore costante, ad esempio 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -4239,22 +4974,22 @@
       
       
         Embed all source files in the portable PDB file
-        Incorpora tutti i file di origine nel file PDB portatile
+        Incorpora tutti i file di origine nel file PDB portabile
         
       
       
         Embed specific source files in the portable PDB file
-        Incorpora file di origine specifici nel file PDB portatile
+        Incorpora file di origine specifici nel file PDB portabile
         
       
       
         Source link information file to embed in the portable PDB file
-        File di informazioni sul collegamento all'origine da incorporare nel file PDB portatile
+        File di informazioni sul collegamento all'origine da incorporare nel file PDB portabile
         
       
       
         --embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
-        Opzione --embed supportata solo quando si crea un file PDB portatile (--debug:portable o --debug:embedded)
+        Opzione --embed supportata solo quando si crea un file PDB portabile (--debug:portable o --debug:embedded)
         
       
       
@@ -4264,7 +4999,7 @@
       
       
         Source file is too large to embed in a portable PDB
-        Le dimensioni del file di origine sono eccessive per consentirne l'incorporamento in un PDB portatile
+        Le dimensioni del file di origine sono eccessive per consentirne l'incorporamento in un PDB portabile
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Questo non è un valore letterale numerico valido. I valori letterali numerici validi includono 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Questo non è un valore letterale numerico valido. I valori letterali numerici validi includono 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5609,7 +6344,7 @@
       
       
         Deterministic builds only support portable PDBs (--debug:portable or --debug:embedded)
-        Le compilazioni deterministiche supportano solo file PDB portatili (--debug:portable o --debug:embedded)
+        Le compilazioni deterministiche supportano solo file PDB portabili (--debug:portable o --debug:embedded)
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        L'attributo di assembly '{0}' fa riferimento a un assembly della finestra di progettazione '{1}' che non è stato caricato o non esiste. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        L'attributo di assembly '{0}' fa riferimento a un assembly '{1}' della finestra di progettazione che non può essere caricato dal percorso '{2}'. L'eccezione restituita è {3} - {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        {0} var nella raccolta
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Questo valore non è una funzione e non può essere applicato. Si intendeva accedere all'indicizzatore tramite la sintassi {0}.[indice]?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Questo valore non è una funzione e non può essere applicato. Si intendeva accedere all'indicizzatore tramite la sintassi '{0}.[index]'?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Questa espressione non è una funzione e non può essere applicata. Si intendeva accedere all'indicizzatore tramite la sintassi espressione.[indice]?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Questa espressione non è una funzione e non può essere applicata. Si intendeva accedere all'indicizzatore tramite la sintassi 'expr.[index]'?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Due tipi di record anonimo contengono set di nomi di campo '{0}' e '{1}' non corrispondenti
+        Questo record anonimo non corrisponde esattamente alla forma prevista. Aggiungere i campi mancanti {0} e rimuovere i campi aggiuntivi {1}.
         
       
       
@@ -7239,7 +7974,7 @@
       
       
         --pathmap can only be used with portable PDBs (--debug:portable or --debug:embedded)
-        --pathmap può essere usato solo con file PDB portatili (--debug:portable o --debug:embedded)
+        --pathmap può essere usato solo con file PDB portabili (--debug:portable o --debug:embedded)
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Fa riferimento a un assembly o una directory contenente uno strumento della fase di progettazione. Forma breve: -t
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        La chiave di gestione pacchetti '{0}' non è stata registrata in {1}. Attualmente registrata: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Non è stato possibile caricare l'estensione {0} di gestione delle dipendenze. Messaggio: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf
index 9267524fe89..f0700683139 100644
--- a/src/fsharp/xlf/FSComp.txt.ja.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ja.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        F# {1} のための {0}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        機能 '{0}' は F# {1} では使用できません。{2} 以上の言語バージョンをお使いください。
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        機能 '{0}' は、ターゲット ランタイムではサポートされていません。
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        機能 '{0}' を使用するには、言語バージョン {1} 以上の F# ライブラリが必要です。
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        F# ライブラリからの ':=' の使用は非推奨です。https://aka.ms/fsharp-refcell-ops を参照してください。たとえば、'cell : = expr' を 'cell.Value <- expr' に変えてください。
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        F# ライブラリからの 'decr' の使用は非推奨とされます。https://aka.ms/fsharp-refcell-ops を参照してください。たとえば、'decr cell' を 'cell.Value <- cell.Value - 1' に変更してください。
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        F# ライブラリからの '!' の使用は非推奨です。「https://aka.ms/fsharp-refcell-ops」を参照してください。たとえば、'!cell' を 'cell.Value' に変えてください。
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        F# ライブラリからの 'incr' の使用は非推奨です。https://aka.ms/fsharp-refcell-ops を参照してください。たとえば、'incr cell' を 'cell.Value <- cell.Value +1' に変えてください。
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        'AssemblyKeyNameAttribute' は非推奨になりました。代わりに 'AssemblyKeyFileAttribute' を使用してください。
+        
+      
+      
+        Key container signing is not supported on this platform.
+        キー コンテナーの署名は、このプラットフォームではサポートされていません。
+        
+      
+      
+        Available overloads:\n{0}
+        使用可能なオーバーロード:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        ジェネリック コンストラクトでは、ジェネリック型パラメーターが構造体または参照型として認識されている必要があります。型の注釈の追加を検討してください。
+        
+      
+      
+        Known types of arguments: {0}
+        既知の型の引数: {0}
+        
+      
+      
+        Known type of argument: {0}
+        既知の型の引数: {0}
+        
+      
+      
+        Known return type: {0}
+        既知の戻り値の型: {0}
+        
+      
+      
+        Known type parameters: {0}
+        既知の型パラメーター: {0}
+        
+      
+      
+        Known type parameter: {0}
+        既知の型パラメーター: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        インデックス {0} の引数が一致しません
+        
+      
+      
+        Argument '{0}' doesn't match
+        引数 '{0}' が一致しません
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        依存関係がないか、または読み込めなかったため、型プロバイダーのデザイナー アセンブリ '{0}' をフォルダー '{1}' から読み込めませんでした。型プロバイダーのデザイナー アセンブリのすべての依存関係は、そのアセンブリと同じフォルダーに配置されている必要があります。次の例外が報告されました: {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        型プロバイダーのデザイナー アセンブリ '{0}' をフォルダー '{1}' から読み込めませんでした。次の例外が報告されました: {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        アセンブリ属性 '{0}' は、デザイナー アセンブリ '{1}' を参照していますが、これは読み込むことができないか、存在していません。報告された例外: {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        その他の型指定された変換
+        
+      
+      
+        applicative computation expressions
+        適用できる計算式
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        'module' キーワードの右側の属性
+        
+      
+      
+        default interface member consumption
+        既定のインターフェイス メンバーの消費
+        
+      
+      
+        discard pattern in use binding
+        使用バインドでパターンを破棄する
+        
+      
+      
+        dotless float32 literal
+        ドットなしの float32 リテラル
+        
+      
+      
+        more types support units of measure
+        単位をサポートするその他の型
+        
+      
+      
+        fixed-index slice 3d/4d
+        固定インデックス スライス 3d/4d
+        
+      
+      
+        from-end slicing
+        開始と終了を指定したスライス
+        
+      
+      
+        implicit yield
+        暗黙的な yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        インデックス作成とスライス用の expr[idx] 表記
+        
+      
+      
+        interfaces with multiple generic instantiation
+        複数のジェネリックのインスタンス化を含むインターフェイス
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        'as' パターンの右側の非変数パターン
+        
+      
+      
+        nullable optional interop
+        Null 許容のオプションの相互運用
+        
+      
+      
+        open type declaration
+        オープン型宣言
+        
+      
+      
+        overloads for custom operations
+        カスタム操作のオーバーロード
+        
+      
+      
+        package management
+        パッケージの管理
+        
+      
+      
+        binary formatting for integers
+        整数のバイナリ形式
+        
+      
+      
+        informational messages related to reference cells
+        参照セルに関連する情報メッセージ
+        
+      
+      
+        whitespace relexation
+        空白の緩和
+        
+      
+      
+        whitespace relaxation v2
+        whitespace relaxation v2
+        
+      
+      
+        resumable state machines
+        再開可能なステート マシン
+        
+      
+      
+        single underscore pattern
+        単一のアンダースコア パターン
+        
+      
+      
+        string interpolation
+        文字列の補間
+        
+      
+      
+        struct representation for active patterns
+        アクティブなパターンの構造体表現
+        
+      
+      
+        wild card in for loop
+        for ループのワイルド カード
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        F# 引用での特性制約に対する監視の引き渡し
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        '%d{{1+1}}' などの式が指定されている場合を除き、補間された文字列では '%' 書式指定子を使用できません。
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        '{{x,3}}' や '{{x:N5}}' などの .NET 形式の書式指定子は、'%' 書式指定子と混在させることはできません。
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        '%P' 指定子は、明示的に使用できません。
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        IFormattable 型または FormattableString 型として使用される補間された文字列では、'%' 指定子を使用できません。'{{expr}}'、'{{expr,3}}'、'{{expr:N5}}' などの .NET 形式の補間のみ使用できます。
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        言語バージョン 5.0 が必要な最後からのスライスで、/langversion:preview を使用してください。
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        無効なディレクティブ '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        再開可能なコード コンストラクト '{0}' は、 'if __useResumableCode then ...' によって保護されているインライン コードでのみ使用でき、コンポジション全体は有効な再開可能コードを形成する必要があります。
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        'InlineIfLambda' 属性はシグネチャに存在しますが、実装はありません。
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        定数リテラルを型プロバイダーの型パラメーター引数として指定するキーワード。
+        
+      
+      
+        a byte string may not be interpolated
+        バイト文字列は補間されていない可能性があります
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        文字 '}}' は、補間された文字列内で (二重にすることで) エスケープする必要があります。
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        補間された文字列が無効です。単一引用符または逐語的文字列リテラルは、単一引用符または逐語的文字列内の補間された式では使用できません。補間式に対して明示的な 'let' バインドを使用するか、外部文字列リテラルとして三重引用符文字列を使用することをご検討ください。
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        補間された文字列が無効です。三重引用符文字列リテラルは、補間された式では使用できません。補間式に対して明示的な 'let' バインドを使用することをご検討ください。
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         オフセット {0} で始まるリソース ヘッダーの形式に誤りがあります。
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        この式は関数ではないため、適用できません。'expr[index]' によってインデクサーにアクセスしようとしましたか?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        この値は関数ではないため、適用できません。'{0}[index]' によってインデクサーにアクセスしようとしましたか?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        値 '{0}' が ' InlineIfLambda ' とマークされましたが、ラムダ値があると判断されませんでした。この警告は、情報提供のみを目的としています。
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        すべてのコンパイル ファイルの推定されたインターフェイスを関連する署名ファイルに印刷します
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         言語バージョンで許可された値を表示し、'最新' や 'プレビュー' などの言語バージョンを指定する
@@ -37,9 +417,49 @@
         --langversion の値 '{0}' が認識されません。完全なリストについては、--langversion:? を使用してください
         
       
+      
+        Display compiler version banner and exit
+        コンパイラ バージョンのバナーを表示して終了する
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Win32 アイコン ファイル (.ico) を指定する
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        パッケージ管理機能では、言語バージョン 5.0 で /langversion:preview を使用する必要があります
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        補間された文字列が無効です。この補間された文字列式の塗りつぶしが空です。式が必要です。
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        この位置以前に始まった補間された文字列が不完全です
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        この位置以前に始まった補間された文字列式の入力が不完全です
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        この位置以前に始まった補間された三重引用符文字列が不完全です
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        この位置以前に始まった補間された逐語的文字列が不完全です
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        型定義に予期しないトークンがあります。型 '{0}' の後には '=' が必要です。
         
       
       
@@ -57,19 +477,109 @@
         アルゴリズム '{0}' はサポートされていません
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        __resumeAt のターゲット ラベルが静的に決定されませんでした。非静的のターゲット ラベルの __resumeAt は、再開可能なコード メソッドの始めにのみ表示される可能性があります
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        ループの高速な整数に再開ポイントを含めることはできません
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        再開可能なコード仕様で 'let rec' が発生しました
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Try/with の 'with' ブロックに再開ポイントが含まれていない可能性があります
+        
+      
+      
+        A try/finally may not contain resumption points
+        Try/finally には再開ポイントを含めることはできません
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        ステート マシンで再開可能なコードを生成するデリゲートまたは関数には型パラメーターがあります
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        '{0}' での再開可能なコードの呼び出しを減らすことができませんでした
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        再開可能なコード値 '{0}' には定義がありません
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        登録された PackageManager によって、#i はサポートされていません
+        
+      
+      
+        The state machine has an unexpected form
+        ステート マシンに予期しない形式があります
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        このステート マシンは静的にコンパイル可能ではありません。{0}。代替の動的実装が使用されますが、これはより遅い可能性があります。このステート マシンが静的にコンパイル可能であることを確認するためにコードを調整するか、この警告を表示しないようにします。
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        このステート マシンは静的にコンパイル可能ではないため、代替手段はありません。{0}。代替手段を用意するには、 '__useResumableCode である場合、<state-machine> または <alternative>' を使用してください。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        このスクリプトの .NET SDK を特定できませんでした。このスクリプトが、'global.json' が使用されているディレクトリにある場合は、関連する .NET SDK がインストールされていることを確認してください。ディレクトリ '{1}' の '{0} --version' からの出力は '{2}' で、終了コードは '{3}' でした。
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        このスクリプトの .NET SDK を特定できませんでした。dotnet.exe が見つかりませんでした。 .NET SDK がインストールされていることをご確認ください。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        このスクリプトの .NET SDK を特定できませんでした。このスクリプトが、'global.json' が使用されているディレクトリにある場合は、関連する .NET SDK がインストールされていることを確認してください。予期しないエラー '{0}'。
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        この式の型は '{0}' であり、あいまいで暗黙的な変換によってのみ、型 '{1}' と互換性を持たせることが可能です。' op_Implicit' の明示的な呼び出しを使用することを検討してください。該当する暗黙的な変換は次のとおりです: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        この機能は、このバージョンの F# ではサポートされていません。この機能を使用するには、/langversion:preview の追加が必要な場合があります。
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        この匿名レコードは正しくありません。フィールド {0} を含んでいる必要があります。
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        この匿名レコードには十分なフィールドがありません。不足しているフィールド {0} を追加してください。
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        この匿名レコードはフィールドが多すぎます。不要なフィールド {0} を削除してください。
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        匿名レコードの型宣言が無効です。
         
       
       
@@ -77,6 +587,206 @@
         属性を型拡張に適用することはできません。
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        構文 'expr1[expr2]' はインデックス作成に使用されます。インデックスを有効にするために型の注釈を追加するか、関数を呼び出す場合には、'expr1 [expr2]' のようにスペースを入れます。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        構文 'expr1[expr2]' はインデックス作成用に予約されています。https://aka.ms/fsharp-index-notation を参照してください。関数を呼び出す場合は、'someFunction [expr]' のように関数と引数の間にスペースを追加します。
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Byref 型は、オープン型宣言では使用できません。
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        'arr[idx]' という構文の '[idx]' が更新されました。コードを更新してください。
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        この式では、型 '{0}' を型 '{1}' に変換するために組み込みの暗黙的な変換を使用しています。https://aka.ms/fsharp-implicit-convs を参照してください。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        この式では、暗黙的な変換 '{0}' を使用して、型 '{1}' を型 '{2}' に変換しています。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        この式では、暗黙的な変換 '{0}' を使用して、型 '{1}' を型 '{2}' に変換しています。https://aka.ms/fsharp-implicit-convs をご確認ください。'#nowarn\"3391\" を使用して、この警告を無効にできる可能性があります。
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        'InlineIfLambda' 属性を使用できるのは、型が関数または F# デリゲート型であるメソッドのインライン関数のパラメーターに対してのみです。
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        補間された文字列が一致しません。'%d{{1+1}}' などの式が指定されている場合を除き、補間された文字列では '%' 書式指定子を使用できません
+        
+      
+      
+        Invalid alignment in interpolated string
+        補間された文字列内の配置が無効です
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        コンストラクト '{0}' は、有効な再開可能コードでのみ使用できます。
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        値、関数、およびメソッドでの '[<Struct>]' は、部分的なアクティブ パターンの定義でのみ使うことができます
+        
+      
+      
+        use! may not be combined with and!
+        use! を and! と組み合わせて使用することはできません
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        リスト式の逆方向インデックスの使い方が正しくありません。
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        構文 '[expr1][expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'(expr1).[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'[expr1] [expr2]' のように間にスペースを追加します。
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        構文 '[expr1][expr2]' はインデックス作成用に予約され、引数として使用するとあいまいになります。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合は、それらの間にスペースを追加します (例: 'someFunction [expr1] [expr2]')。
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        [<Literal>] 宣言では、その識別子に対してアクティブ パターンを使用することはできません
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        リテラルとしてマークされた別の値に値を割り当てることはできません
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        リテラルとしてマークされた値に '{0}' を割り当てることはできません
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        この式は、'expr. [index]' などのインデックスをサポートしています。構文 'expr[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        この式は、 '{0}.[index]' などのインデックスをサポートしています。構文 '{1}[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        この式は関数ではなく、インデックス表記をサポートしていません。
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        値 '{0}' は関数ではなく、インデックス表記をサポートしていません。
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'expr1.[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'expr1 [expr2]' のように間にスペースを追加します。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction expr1 [expr2]' のように間にスペースを追加します。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        構文 '(expr1)[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'(expr1).[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'someFunction (expr1) [expr2]' のように間にスペースを追加します。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        構文 '(expr1)[expr2]' はインデックス作成に予約されているので、引数として使うとあいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction (expr1) [expr2]' のように間にスペースを追加します。
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        'let! ... and! ...' コンストラクトは、コンピュテーション式ビルダーが '{0}' メソッドまたは適切な 'MergeSource' および 'Bind' メソッドのいずれかを定義している場合にのみ使用できます
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        再開可能なコードが無効です。再開可能なコード パラメーターは、デリゲートまたは関数型である必要があります
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        再開可能なコードが無効です。再開可能なコード パラメーターは、'__expand' で始まる名前でなければなりません
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        再開可能なコードが無効です。再開可能なコード仕様で 'let rec' が発生しました
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        再開可能なコードが無効です。再開可能コードを受け入れるか戻す関数のメソッドは、'inline' とマークする必要があります
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        再開可能なコード呼び出しです。既存の再開可能なコードに関して、新しい低レベルの再開可能なコードを定義する場合は、この警告を表示しないようにします。
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        再開可能なコードまたは再開可能なステート マシンを使用するには、/langversion:preview が必要です
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        この式は、型 '{0}' を型 '{1}' に暗黙的に変換します。https://aka.ms/fsharp-implicit-convs を参照してください。
+        
+      
+      
+        Invalid interpolated string. {0}
+        補間された文字列が無効です。{0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        インターフェイス メンバー '{0}' には最も固有な実装がありません。
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        統合している可能性があるため、'{0}' は、'{2}' と '{3}' の 2 つのインスタンス化を含むインターフェイス '{1}' を実装できません。
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        統合している可能性があるため、'{1}' と '{2}' の 2 つのインスタンス化を含むインターフェイス '{0}' を実装することはできません。
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        型 '{0}' は、フィールド、コンストラクター、またはメンバー '{1}' を定義していません。
+        
+      
       
         The namespace '{0}' is not defined.
         名前空間 '{0}' が定義されていません。
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        リスト コンストラクター式のすべての要素は同じ型である必要があります。この式に必要な型は '{0}' ですが、ここでは型 '{1}' になっています。
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        リストのすべての要素は、最初の要素の型 (ここでは '{0}') に暗黙的に変換可能である必要があります。 この要素の型は '{1}' です。
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        配列コンストラクター式の要素はすべて同じ型である必要があります。この式に必要な型は '{0}' ですが、ここでは型 '{1}' になっています。
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        配列のすべての要素は、最初の要素の型 (ここでは '{0}') に暗黙的に変換可能である必要があります。 この要素の型は '{1}' です。
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        if' 式のすべてのブランチは同じ型である必要があります。この式に必要な型は '{0}' ですが、ここでは型 '{1}' になっています。
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        if' 式のすべてのブランチは、最初のブランチの型 (ここでは '{0}') に暗黙的に変換可能な値を返す必要があります。このブランチの返す値の型は '{1}' です。
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        パターン マッチ式のすべてのブランチは、同じ型の値を返す必要があります。最初のブランチが返した値の型は '{0}' ですが、このブランチが返した値の型は '{1}' です。
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        パターン マッチ式のすべてのブランチは、最初のブランチの型 (ここでは '{0}') に暗黙的に変換可能な値を返す必要があります。このブランチが返す値の型は '{1}' です。
         
       
       
@@ -212,11 +922,51 @@
         'return' の代わりに 'return!' を使うことを検討してください。
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        この属性は現在、F # コンパイラのサポート外です。これを適用しても、意図した効果は得られません。
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         使用可能な場合は、.NET Framework リファレンスの参照アセンブリを使用します (既定で有効)。
         
       
+      
+        This XML comment is invalid: '{0}'
+        この XML コメントは無効です: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        この XML コメントは無効です: パラメーター '{0}' に複数のドキュメント エントリがあります
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        この XML コメントは無効です: パラメーター '{0}' が不明です
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        この XML コメントは無効です: 相互参照に 'cref' 属性がありません
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        この XML コメントは不完全です: パラメーター '{0}' にドキュメントがありません
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        この XML コメントは無効です: パラメーターまたはパラメーター参照に 'name' 属性がありません
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        この XML コメントは無効です: 相互参照 '{0}' が未解決です
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         'yield' の代わりに 'yield!' を使うことを検討してください。
@@ -242,16 +992,6 @@
         バージョン ファイル '{0}' が無効です
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Compiler バージョン {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        F# {0} の F# コンパイラ
-        
-      
       
         Problem with filename '{0}': {1}
         ファイル名 '{0}' に問題があります: {1}
@@ -449,12 +1189,12 @@
       
       
         Two type definitions named '{0}' occur in namespace '{1}' in two parts of this assembly
-        {0}' という 2 つの型の定義が、このアセンブリの 2 か所の名前空間 '{1}' で発生しています
+        '{0}' という 2 つの型の定義が、このアセンブリの 2 か所の名前空間 '{1}' で発生しています
         
       
       
         A module and a type definition named '{0}' occur in namespace '{1}' in two parts of this assembly
-        {0}' というモジュールおよび型の定義が、このアセンブリの 2 か所の名前空間 '{1}' で発生しています
+        '{0}' というモジュールおよび型の定義が、このアセンブリの 2 か所の名前空間 '{1}' で発生しています
         
       
       
@@ -479,7 +1219,7 @@
       
       
         Unexpected use of a byref-typed variable
-        byref 型変数の予期しない使用方法です:
+        byref 型変数の予期しない使用方法です
         
       
       
@@ -509,17 +1249,17 @@
       
       
         Unexpected decode of AutoOpenAttribute
-        AutoOpenAttribute の予期しないデコードです:
+        AutoOpenAttribute の予期しないデコードです
         
       
       
         Unexpected decode of InternalsVisibleToAttribute
-        InternalsVisibleToAttribute の予期しないデコードです:
+        InternalsVisibleToAttribute の予期しないデコードです
         
       
       
         Unexpected decode of InterfaceDataVersionAttribute
-        InterfaceDataVersionAttribute の予期しないデコードです:
+        InterfaceDataVersionAttribute の予期しないデコードです
         
       
       
@@ -934,42 +1674,42 @@
       
       
         The exception definitions are not compatible because a CLI exception mapping is being hidden by a signature. The exception mapping must be visible to other modules. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}
-        CLI の例外のマッピングがシグネチャによって隠ぺいされているため、例外の定義に互換性がありません。例外のマッピングは他のモジュールから参照できるようにする必要があります。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}\nを指定しています。
+        CLI の例外のマッピングがシグネチャによって隠ぺいされているため、例外の定義に互換性がありません。例外のマッピングは他のモジュールから参照できるようにする必要があります。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}を指定しています
         
       
       
         The exception definitions are not compatible because the CLI representations differ. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}
-        CLI 表現が異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}\nを指定しています。
+        CLI 表現が異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}を指定しています
         
       
       
         The exception definitions are not compatible because the exception abbreviation is being hidden by the signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}.
-        例外の省略形がシグネチャによって隠ぺいされているため、例外の定義に互換性がありません。省略形は他の CLI 言語から参照できるようにする必要があります。シグネチャ内の省略形を参照できるようにしてください。モジュールには例外の定義\n    {0}    \nがありますが、シグネチャでは\n\t{1}\nを指定しています。
+        例外の省略形がシグネチャによって隠ぺいされているため、例外の定義に互換性がありません。省略形は他の CLI 言語から参照できるようにする必要があります。シグネチャ内の省略形を参照できるようにしてください。モジュールには例外の定義\n    {0}    \nがありますが、シグネチャでは\n\t{1}を指定しています。
         
       
       
         The exception definitions are not compatible because the exception abbreviations in the signature and implementation differ. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}.
-        例外の省略形がシグネチャと実装とで異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}\nを指定しています。
+        例外の省略形がシグネチャと実装とで異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}を指定しています。
         
       
       
         The exception definitions are not compatible because the exception declarations differ. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}.
-        例外の宣言が異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}\nを指定しています。
+        例外の宣言が異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}を指定しています。
         
       
       
         The exception definitions are not compatible because the field '{0}' was required by the signature but was not specified by the implementation. The module contains the exception definition\n    {1}    \nbut its signature specifies\n\t{2}.
-        シグネチャにはフィールド '{0}' が必要ですが、実装では指定されなかったため、例外の定義に互換性がありません。モジュールには例外の定義\n    {1}    \nが含まれますが、シグネチャでは\n\t{2}\nを指定しています。
+        シグネチャにはフィールド '{0}' が必要ですが、実装では指定されなかったため、例外の定義に互換性がありません。モジュールには例外の定義\n    {1}    \nが含まれますが、シグネチャでは\n\t{2}を指定しています。
         
       
       
         The exception definitions are not compatible because the field '{0}' was present in the implementation but not in the signature. The module contains the exception definition\n    {1}    \nbut its signature specifies\n\t{2}.
-        実装にはフィールド '{0}' がありますが、シグネチャにはないため、例外の定義に互換性がありません。モジュールには例外の定義\n    {1}    \nが含まれますが、シグネチャでは\n\t{2}\nを指定しています。
+        実装にはフィールド '{0}' がありますが、シグネチャにはないため、例外の定義に互換性がありません。モジュールには例外の定義\n    {1}    \nが含まれますが、シグネチャでは\n\t{2}を指定しています。
         
       
       
         The exception definitions are not compatible because the order of the fields is different in the signature and implementation. The module contains the exception definition\n    {0}    \nbut its signature specifies\n\t{1}.
-        フィールドの順序がシグネチャと実装とで異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}\nを指定しています。
+        フィールドの順序がシグネチャと実装とで異なるため、例外の定義に互換性がありません。モジュールには例外の定義\n    {0}    \nが含まれますが、シグネチャでは\n\t{1}を指定しています。
         
       
       
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        名前付き引数に複数の値が割り当てられました
+        The named argument '{0}' has been assigned more than one value
+        名前付き引数 '{0}' に複数の値が割り当てられました
         
       
       
@@ -1339,7 +2079,7 @@
       
       
         The member '{0}' is used in an invalid way. A use of '{1}' has been inferred prior to its definition at or near '{2}'. This is an invalid forward reference.
-        メンバー '{0}' の使用方法に誤りがあります。'{2}' または '{2}' 付近の定義の前に '{1}' の使用が推論されました。これは無効な前方参照です。
+        メンバー '{0}' の使用方法に誤りがあります。'{2}' またはその付近の定義の前に '{1}' の使用が推論されました。これは無効な前方参照です。
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        候補: {0}
-        
-      
-      
-        The available overloads are shown below.
-        使用できるオーバーロードを以下に示します。
+        Candidates:\n{0}
+        候補:\n{0}
         
       
       
@@ -1944,7 +2679,7 @@
       
       
         Unexpected end of input
-        予期しない入力の終わりです:
+        予期しない入力の終わりです
         
       
       
@@ -1984,7 +2719,7 @@
       
       
         The '{0}' visibility attribute is not allowed on module abbreviation. Module abbreviations are always private.
-        モジュールの省略形には '{0}' 可視属性を使用できません。モジュールの省略形は常にプライベートです。
+        モジュールの省略形には '{0}' 表示範囲属性を使用できません。モジュールの省略形は常にプライベートです。
         
       
       
@@ -2004,7 +2739,7 @@
       
       
         Unexpected empty type moduleDefn list
-        予期しない空の型の moduleDefn リストです:
+        予期しない空の型の moduleDefn リストです
         
       
       
@@ -2089,12 +2824,12 @@
       
       
         Interfaces always have the same visibility as the enclosing type
-        インターフェイスは、それを囲む型と常に同じ可視性を持ちます
+        インターフェイスは、それを囲む型と常に同じ表示範囲を持ちます
         
       
       
         Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type.
-        アクセシビリティ修飾子はこのメンバーでは許可されていません。抽象スロットには、それを囲む型と常に同じ可視性があります。
+        アクセシビリティ修飾子はこのメンバーでは許可されていません。抽象スロットには、それを囲む型と常に同じ表示範囲があります。
         
       
       
@@ -2139,7 +2874,7 @@
       
       
         Unexpected identifier: '{0}'
-        予期しない識別子: '{0}':
+        予期しない識別子: '{0}'
         
       
       
@@ -2279,7 +3014,7 @@
       
       
         Unexpected infix operator in type expression
-        型式に予期しない挿入演算子が見つかりました:
+        型式に予期しない挿入演算子が見つかりました
         
       
       
@@ -2299,7 +3034,7 @@
       
       
         Unexpected integer literal in unit-of-measure expression
-        単位式に予期しない整数リテラルが見つかりました:
+        単位式に予期しない整数リテラルが見つかりました
         
       
       
@@ -2359,7 +3094,7 @@
       
       
         Unexpected SynMeasure.Anon
-        予期しない SynMeasure.Anon です:
+        予期しない SynMeasure.Anon です
         
       
       
@@ -2374,22 +3109,22 @@
       
       
         Unexpected big rational constant
-        有理定数が大きすぎます:
+        有理定数が大きすぎます
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        float 型、float32 型、decimal 型、および符号付き整数型でのみサポートされる単位です
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        単位は、float、float32、decimal、整数型でのみサポートされます。
         
       
       
         Unexpected Const_uint16array
-        予期しない Const_uint16array です:
+        予期しない Const_uint16array です
         
       
       
         Unexpected Const_bytearray
-        予期しない Const_bytearray です:
+        予期しない Const_bytearray です
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        解析ツリーに使用できるのは MemberKind.PropertyGetSet のみです
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        解析ツリーに使用できるのは SynMemberKind.PropertyGetSet のみです
         
       
       
@@ -2419,12 +3154,12 @@
       
       
         Multiple visibility attributes have been specified for this identifier
-        この識別子に複数の可視属性が指定されました
+        この識別子に複数の表示範囲属性が指定されました
         
       
       
         Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions.
-        この識別子に複数の可視属性が指定されました。式内のすべての 'let' 束縛と同様に、クラス内の 'let' 束縛は常にプライベートです。
+        この識別子に複数の表示範囲属性が指定されました。式内のすべての 'let' 束縛と同様に、クラス内の 'let' 束縛は常にプライベートです。
         
       
       
@@ -2504,7 +3239,7 @@
       
       
         Unexpected expression at recursive inference point
-        再帰的推論ポイントに予期しない式があります:
+        再帰的推論ポイントに予期しない式があります
         
       
       
@@ -2579,7 +3314,7 @@
       
       
         Unexpected source-level property specification in syntax tree
-        構文ツリーに予期しないソースレベルのプロパティの指定があります:
+        構文ツリーに予期しないソースレベルのプロパティの指定があります
         
       
       
@@ -2609,7 +3344,7 @@
       
       
         Unexpected source-level property specification
-        予期しないソースレベルのプロパティの指定があります:
+        予期しないソースレベルのプロパティの指定があります
         
       
       
@@ -2754,7 +3489,7 @@
       
       
         Unexpected {0} in type expression
-        型式に予期しない {0} があります:
+        型式に予期しない {0} があります
         
       
       
@@ -2779,12 +3514,12 @@
       
       
         Unexpected / in type
-        型に予期しない / があります:
+        型に予期しない / があります
         
       
       
         Unexpected type arguments
-        予期しない型引数です:
+        予期しない型引数です
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        インデクサー式が無効です
+        Incomplete expression or invalid use of indexer syntax
+        式が不完全であるか、インデクサー構文の使用法が正しくありません。
         
       
       
@@ -3389,7 +4124,7 @@
       
       
         Unexpected condition in imported assembly: failed to decode AttributeUsage attribute
-        インポートされたアセンブリに予期しない条件があります。AttributeUsage 属性のデコードに失敗しました:
+        インポートされたアセンブリに予期しない条件があります。AttributeUsage 属性のデコードに失敗しました
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        'mutable' とマークできるのはレコード フィールドと単純で非再帰的な 'let' バインディングのみです
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        変更可能な 'let' バインドは、再帰的にしたり、再帰的なモジュールまたは名前空間で定義したりすることはできません
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        定数値も指定する場合には宣言を [<Literal>] 属性のみにできます。例: 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -3609,7 +4344,7 @@
       
       
         Explicit type declarations for constructors must be of the form 'ty1 * ... * tyN -> resTy'. Parentheses may be required around 'resTy'
-        コンストラクタ―の明示的な型宣言の形式は 'ty1 * ... * tyN -> resTy' でなければなりません。'resTy' をかっこで囲まなければならない場合があります
+        コンストラクターの明示的な型宣言の形式は 'ty1 * ... * tyN -> resTy' でなければなりません。'resTy' をかっこで囲まなければならない場合があります
         
       
       
@@ -3644,7 +4379,7 @@
       
       
         This declaration opens the module '{0}', which is marked as 'RequireQualifiedAccess'. Adjust your code to use qualified references to the elements of the module instead, e.g. 'List.map' instead of 'map'. This change will ensure that your code is robust as new constructs are added to libraries.
-        この宣言はモジュール '{0}' を開きます。'{0}' は 'RequireQualifiedAccess' とマークされています。代わりにモジュールの要素に対する限定参照を使用するようにコードを変更してください (たとえば、'map' の代わりに 'List.map')。この変更によってコードが堅牢になり、新しいコンストラクターがライブラリに追加された場合にも対応できます。
+        この宣言は 'RequireQualifiedAccess' とマークされているモジュール '{0}' を開きます。代わりにモジュールの要素に対する限定参照を使用するようにコードを変更してください (たとえば、'map' の代わりに 'List.map')。この変更によってコードが堅牢になり、新しいコンストラクターがライブラリに追加された場合にも対応できます。
         
       
       
@@ -4109,7 +4844,7 @@
       
       
         Unexpected GetSet annotation on a property
-        プロパティに予期しない GetSet 注釈がありました:
+        プロパティに予期しない GetSet 注釈がありました
         
       
       
@@ -4239,32 +4974,32 @@
       
       
         Embed all source files in the portable PDB file
-        ポータブル PDB ファイル内にすべてのソース ファイルを埋め込む
+        移植可能な PDB ファイル内にすべてのソース ファイルを埋め込む
         
       
       
         Embed specific source files in the portable PDB file
-        ポータブル PDB ファイル内に特定のソース ファイルを埋め込む
+        移植可能な PDB ファイル内に特定のソース ファイルを埋め込む
         
       
       
         Source link information file to embed in the portable PDB file
-        ポータブル PDB ファイルに埋め込むソース リンク情報ファイル
+        移植可能な PDB ファイルに埋め込むソース リンク情報ファイル
         
       
       
         --embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
-        --embed スイッチは、ポータブル PDB の生成時にのみサポートされます (--debug:portable または --debug:embedded)
+        --embed スイッチは、移植可能な PDB の生成時にのみサポートされます (--debug:portable または --debug:embedded)
         
       
       
         --sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded)
-        --sourcelink スイッチは、ポータブル PDB の生成時にのみサポートされます (--debug:portable または --debug:embedded)
+        --sourcelink スイッチは、移植可能な PDB の生成時にのみサポートされます (--debug:portable または --debug:embedded)
         
       
       
         Source file is too large to embed in a portable PDB
-        ソース ファイルが大きすぎるので、ポータブル PDB 内に埋め込めません
+        ソース ファイルが大きすぎるので、移植可能な PDB 内に埋め込めません
         
       
       
@@ -4744,7 +5479,7 @@
       
       
         Unexpected Expr.TyChoose
-        予期しない Expr.TyChoose です:
+        予期しない Expr.TyChoose です
         
       
       
@@ -4874,7 +5609,7 @@
       
       
         Unexpected empty long identifier
-        予期しない空の長識別子:
+        予期しない空の長識別子
         
       
       
@@ -4909,7 +5644,7 @@
       
       
         Unexpected error creating debug information file '{0}'
-        デバッグ情報ファイル '{0}' の作成中に予期しないエラーが発生しました:
+        デバッグ情報ファイル '{0}' の作成中に予期しないエラーが発生しました
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        これは有効な数値リテラルではありません。有効な数値リテラルの例には、1、0x1、0b0001 (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger) などがあります。
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        これは有効な数値リテラルではありません。有効な数値リテラルの例には、1、0x1、0o1、0b1、1l (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger) などがあります。
         
       
       
@@ -5599,7 +6334,7 @@
       
       
         Static linking may not be used on an assembly referencing mscorlib (e.g. a .NET Framework assembly) when generating an assembly that references System.Runtime (e.g. a .NET Core or Portable assembly).
-        静的リンクは、System.Runtime (.NET Core またはポータブル アセンブリなど) を参照するアセンブリを生成する場合、mscorlib (.NET Framework アセンブリなど) を参照するアセンブリには使用できません。
+        静的リンクは、System.Runtime (.NET Core または移植可能なアセンブリなど) を参照するアセンブリを生成する場合、mscorlib (.NET Framework アセンブリなど) を参照するアセンブリには使用できません。
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        アセンブリ属性 '{0}' はデザイナー アセンブリ '{1}' を参照していますが、このアセンブリは読み込めないか、存在していません。{2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        アセンブリ属性 '{0}' は、デザイナー アセンブリ '{1}' を参照していますが、これはパス '{2}' から読み込むことができません。報告された例外: {3} - {4}
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        この値は関数ではないため、適用できません。そうではなく、{0}.[index] によってインデクサーにアクセスしようとしましたか?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        この値は関数ではないため、適用できません。{0}.[index] によってインデクサーにアクセスしようとしましたか?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        この式は関数ではないため、適用できません。そうではなく、expr.[index] によってインデクサーにアクセスしようとしましたか?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        この式は関数ではないため、適用できません。expr.[index] によってインデクサーにアクセスしようとしましたか?
         
       
       
@@ -7064,7 +7799,7 @@
       
       
         A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
-        関数またはメソッドによって返される byref ポインターが F# 4.5 の時点では暗黙的に逆参照されています。ポインターとして返り値を取得するには、address-of  演算子を使用して '&f(x)' または '&obj.Method(arg1, arg2)' などとします。
+        関数またはメソッドによって返される byref ポインターが F# 4.5 の時点では暗黙的に逆参照されています。ポインターとして返り値を取得するには、address-of 演算子を使用して '&f(x)' または '&obj.Method(arg1, arg2)' などとします。
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        2 種類の匿名レコードのフィールド名 '{0}' と '{1}' が一致しません
+        この匿名レコードは、予期された形状と完全には一致していません。不足しているフィールド {0} を追加し、不要なフィールド {1} を削除してください。
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        デザイン時ツールを含むアセンブリまたはディレクトリを参照します (短い形式: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        パッケージ マネージャー キー '{0}' は {1} に登録されていませんでした。現在登録済み: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        依存関係マネージャーの拡張機能 {0} を読み込むことができませんでした。メッセージ: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf
index 9aab61aa0f9..4785f3dd3f1 100644
--- a/src/fsharp/xlf/FSComp.txt.ko.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ko.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        F# {1}용 {0}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        '{0}' 기능은 F# {1}에서 사용할 수 없습니다. {2} 이상의 언어 버전을 사용하세요.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        '{0}' 기능은 대상 런타임에서 지원되지 않습니다.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        언어 버전 {1} 이상에서 '{0}' 기능을 사용하려면 F# 라이브러리가 필요합니다.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        F# 라이브러리의 ':=' 사용은 더 이상 사용되지 않습니다. https://aka.ms/fsharp-refcell-ops를 참조하세요. 예를 들어 'cell := expr'을 'cell.Value <- expr'로 변경하세요.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        F# 라이브러리의 'decr' 사용은 더 이상 사용되지 않습니다. https://aka.ms/fsharp-refcell-ops를 참조하세요. 예를 들어 'decr cell'을 'cell.Value <- cell.Value - 1'로 변경하세요.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        F# 라이브러리의 '!'의 사용은 더 이상 사용되지 않습니다. https://aka.ms/fsharp-refcell-ops를 참조하세요. 예를 들어 '!cell'을 'cell.Value'로 변경하세요.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        F# 라이브러리의 'incr' 사용은 더 이상 사용되지 않습니다. https://aka.ms/fsharp-refcell-ops를 참조하세요. 예를 들어 'incr cell'을 'cell.Value <- cell.Value + 1'로 변경하세요.
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        'AssemblyKeyNameAttribute'는 사용되지 않습니다. 대신 'AssemblyKeyFileAttribute'를 사용하세요.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        키 컨테이너 서명은 이 플랫폼에서 지원되지 않습니다.
+        
+      
+      
+        Available overloads:\n{0}
+        사용 가능한 오버로드:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        제네릭 구문을 사용하려면 구조체 또는 참조 형식의 제네릭 형식 매개 변수가 필요합니다. 형식 주석을 추가하세요.
+        
+      
+      
+        Known types of arguments: {0}
+        알려진 인수 형식: {0}
+        
+      
+      
+        Known type of argument: {0}
+        알려진 인수 형식: {0}
+        
+      
+      
+        Known return type: {0}
+        알려진 반환 형식: {0}
+        
+      
+      
+        Known type parameters: {0}
+        알려진 형식 매개 변수: {0}
+        
+      
+      
+        Known type parameter: {0}
+        알려진 형식 매개 변수: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        인덱스 {0}의 인수가 일치하지 않습니다.
+        
+      
+      
+        Argument '{0}' doesn't match
+        '{0}' 인수가 일치하지 않습니다.
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        종속성이 없거나 로드되지 않았으므로 '{0}' 형식 공급자 디자이너 어셈블리를 '{1}' 폴더에서 로드할 수 없습니다. 형식 공급자 디자이너 어셈블리의 모든 종속성은 해당 어셈블리와 동일한 폴더에 있어야 합니다. 보고된 예외: {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        '{0}' 형식 공급자 디자이너 어셈블리를 '{1}' 폴더에서 로드할 수 없습니다. 보고된 예외: {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        '{0}' 어셈블리 특성이 로드할 수 없거나 존재하지 않는 디자이너 어셈블리'{1}'을(를) 참조합니다. 보고된 예외: {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        추가 형식-디렉션 변환
+        
+      
+      
+        applicative computation expressions
+        적용 가능한 계산 식
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        'module' 키워드 오른쪽에 있는 특성
+        
+      
+      
+        default interface member consumption
+        기본 인터페이스 멤버 사용
+        
+      
+      
+        discard pattern in use binding
+        사용 중인 패턴 바인딩 무시
+        
+      
+      
+        dotless float32 literal
+        점이 없는 float32 리터럴
+        
+      
+      
+        more types support units of measure
+        더 많은 형식이 측정 단위를 지원함
+        
+      
+      
+        fixed-index slice 3d/4d
+        고정 인덱스 슬라이스 3d/4d
+        
+      
+      
+        from-end slicing
+        끝에서부터 조각화
+        
+      
+      
+        implicit yield
+        암시적 yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        인덱싱 및 슬라이싱을 위한 expr[idx] 표기법
+        
+      
+      
+        interfaces with multiple generic instantiation
+        여러 제네릭 인스턴스화가 포함된 인터페이스
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        'as' 패턴의 오른쪽에 있는 변수가 아닌 패턴
+        
+      
+      
+        nullable optional interop
+        nullable 선택적 interop
+        
+      
+      
+        open type declaration
+        개방형 형식 선언
+        
+      
+      
+        overloads for custom operations
+        사용자 지정 작업의 오버로드
+        
+      
+      
+        package management
+        패키지 관리
+        
+      
+      
+        binary formatting for integers
+        정수에 대한 이진 서식 지정
+        
+      
+      
+        informational messages related to reference cells
+        참조 셀과 관련된 정보 메시지
+        
+      
+      
+        whitespace relexation
+        공백 완화
+        
+      
+      
+        whitespace relaxation v2
+        공백 relaxation v2
+        
+      
+      
+        resumable state machines
+        다시 시작 가능한 상태 시스템
+        
+      
+      
+        single underscore pattern
+        단일 밑줄 패턴
+        
+      
+      
+        string interpolation
+        문자열 보간
+        
+      
+      
+        struct representation for active patterns
+        활성 패턴에 대한 구조체 표현
+        
+      
+      
+        wild card in for loop
+        for 루프의 와일드카드
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        F# 인용의 특성 제약 조건에 대한 감시 전달
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        각 보간 문자열에 식(예: '%d{{1+1}}')이 지정되지 않는 한 '%' 형식 지정자를 사용할 수 없습니다.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        '{{x,3}}' 또는 '{{x:N5}}' 등의 .NET 스타일 형식 지정자를 '%' 형식 지정자와 혼합할 수 없습니다.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        '%P' 지정자를 명시적으로 사용할 수 없습니다.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        형식 IFormattable 또는 형식 FormattableString으로 사용된 보간 문자열은 '%' 지정자를 사용할 수 없으며 '{{expr}}', '{{expr,3}}' 또는 '{{expr:N5}}' 등의 .NET 스타일 인터폴란드를 사용할 수 있습니다.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        언어 버전 5.0이 필요한 끝 조각화에서는 /langversion:preview를 사용하세요.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        잘못된 지시문 '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        다시 시작 가능한 코드 구문 '{0}'은 'if __useResumableCode then ...'로 보호되는 인라인 코드에서만 사용할 수 있습니다. 전반적인 구성은 유효한 다시 시작 가능한 코드를 형성해야 합니다.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        'InlineIfLambda' 특성이 서명에 있지만 구현에는 없습니다.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        상수 리터럴을 형식 공급자의 형식 매개 변수 인수로 지정하는 키워드입니다.
+        
+      
+      
+        a byte string may not be interpolated
+        바이트 문자열을 보간하지 못할 수 있습니다.
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        '}}' 문자는 보간된 문자열에서 이중으로 사용하여 이스케이프해야 합니다.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        잘못된 보간 문자열. 작은 따옴표 또는 축자 문자열 리터럴은 작은 따옴표 또는 축자 문자열의 보간 식에 사용할 수 없습니다. 보간 식에 명시적 'let' 바인딩을 사용하거나 삼중 따옴표 문자열을 외부 문자열 리터럴로 사용해 보세요.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        잘못된 보간 문자열. 삼중 따옴표 문자열 리터럴은 보간 식에 사용할 수 없습니다. 보간 식에 명시적 'let' 바인딩을 사용해 보세요.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         오프셋 {0}에서 시작하는 리소스 헤더의 형식이 잘못되었습니다.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        이 식은 함수가 아니며 적용할 수 없습니다. 'expr[index]'를 통해 인덱서에 액세스하려고 했습니까?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        이 값은 함수가 아니며 적용할 수 없습니다. '{0}[index]'를 통해 인덱서에 액세스하려고 했습니까?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        '{0}' 값이 'InlineIfLambda'로 표시되었지만 람다 값이 없는 것으로 확인되지 않았습니다. 이 경고는 정보 제공용입니다.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        모든 컴파일 파일의 유추된 인터페이스를 관련 서명 파일로 인쇄합니다.
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         언어 버전의 허용된 값을 표시하고 '최신' 또는 '미리 보기'와 같은 언어 버전을 지정합니다.
@@ -37,9 +417,49 @@
         전체 목록에 대한 --langversion use --langversion:?의 인식할 수 없는 값 '{0}'입니다.
         
       
+      
+        Display compiler version banner and exit
+        컴파일러 버전 배너를 표시하고 종료
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Win32 아이콘 파일(.ico) 지정
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        패키지 관리 기능을 사용하려면 언어 버전 5.0이 필요합니다. /langversion:preview를 사용하세요.
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        보간된 문자열이 잘못되었습니다. 이 보간된 문자열 식 채우기가 비어 있는데, 식이 필요합니다.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        불완전한 보간 문자열이 여기 또는 이전에서 시작되었습니다.
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        불완전한 보간 문자열 식 채우기가 여기 또는 이전에서 시작되었습니다.
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        불완전한 보간 삼중 따옴표 문자열이 여기 또는 이전에서 시작되었습니다.
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        불완전한 보간 축자 문자열이 여기 또는 이전에서 시작되었습니다.
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        형식 정의에 예기치 않은 토큰이 있습니다. '{0}' 형식 뒤에 '='가 필요합니다.
         
       
       
@@ -57,19 +477,109 @@
         {0}' 알고리즘은 지원되지 않습니다.
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        __resumeAt 대한 대상 레이블이 정적으로 결정되지 않았습니다. 비정적 대상 레이블이 있는 __resumeAt은 다시 시작 가능한 코드 메서드의 시작 부분에만 나타날 수 있습니다.
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        루프의 빠른 정수에는 다시 시작 지점이 포함될 수 없습니다.
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다.
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        try/with의 'with' 블록에 다시 시작 포인트가 포함될 수 없습니다.
+        
+      
+      
+        A try/finally may not contain resumption points
+        try/finally에는 다시 시작 지점이 포함될 수 없습니다.
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        상태 시스템에서 다시 시작 가능한 코드를 생성하는 대리자 또는 함수에 형식 매개 변수가 있습니다.
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        '{0}'에서 다시 시작 가능한 코드 호출을 줄일 수 없습니다.
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        다시 시작 가능한 코드 값 '{0}'에 정의가 없습니다.
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i는 등록된 PackageManagers에서 지원하지 않습니다.
+        
+      
+      
+        The state machine has an unexpected form
+        상태 시스템에 예기치 않은 형식이 있습니다.
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        이 상태 시스템은 정적으로 컴파일할 수 없습니다. {0}. 대체 동적 구현이 사용되며 속도가 느려질 수 있습니다. 이 상태 시스템을 정적으로 컴파일할 수 있도록 코드를 조정하거나 이 경고를 표시하지 않는 것이 좋습니다.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        이 상태 시스템은 정적으로 컴파일할 수 없으며 다른 대안을 사용할 수 없습니다. {0}. 대안을 제공하려면 'if __useResumableCode then <state-machine> else <alternative>'를 사용하세요.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        이 스크립트에 대한 .NET SDK를 확인할 수 없습니다. 스크립트가 'global.json'을 사용하는 디렉터리에 있는 경우 관련 .NET SDK가 설치되어 있는지 확인하세요. '{1}' 디렉터리에 있는 '{0} --version'의 출력은 '{2}'이고 종료 코드는 '{3}'입니다.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        이 스크립트의 .NET SDK를 확인할 수 없습니다. dotnet.exe를 찾을 수 없습니다. .NET SDK가 설치되어 있는지 확인하세요.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        이 스크립트에 대한 .NET SDK를 확인할 수 없습니다. 스크립트가 'global.json'을 사용하는 디렉터리에 있는 경우 관련 .NET SDK가 설치되어 있는지 확인하세요. 예기치 않은 오류 '{0}'.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        이 식은 ‘{0}’ 형식이며 모호한 암시적 변환을 통해 ‘{1}’ 형식하고만 호환됩니다. ‘op_Implicit’에 대한 명시적 호출을 사용하십시오. 해당하는 암시적 변환은 ‘{2}’입니다.
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        이 기능은 이 F# 버전에서 지원되지 않습니다. 이 기능을 사용하기 위해 /langversion:preview를 추가해야 할 수도 있습니다.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        잘못된 익명 레코드입니다. {0} 필드가 있어야 합니다.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        이 익명 레코드에 필드가 부족합니다. 누락된 필드 {0}을(를) 추가하세요.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        이 익명 레코드에 필드가 너무 많습니다. 추가 필드 {0}을(를) 제거하세요.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        익명 레코드 형식 선언이 잘못되었습니다.
         
       
       
@@ -77,6 +587,206 @@
         형식 확장에 특성을 적용할 수 없습니다.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        인덱싱에는 'expr1[expr2]' 구문이 사용됩니다. 인덱싱을 사용하도록 설정하기 위해 형식 주석을 추가하는 것을 고려하거나 함수를 호출하는 경우 공백을 추가하세요(예: 'expr1 [expr2]').
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        'expr1[expr2]' 구문은 이제 인덱싱용으로 예약되어 있습니다. https://aka.ms/fsharp-index-notation을 참조하세요. 함수를 호출하는 경우 함수와 인수 사이에 공백을 추가하세요(예: 'someFunction [expr]').
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Byref 형식은 개방형 형식 선언에서 허용되지 않습니다.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        구문 'arr.[idx]'는 이제 'arr[idx]'로 수정되었습니다. 코드를 업데이트하세요.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        이 식은 기본 제공 암시적 변환을 사용하여 ‘{0}’ 형식을 '{1}' 형식으로 변환합니다. https://aka.ms/fsharp-implicit-convs 참조
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        이 식은 암시적 변환 ‘{0}’을 사용하여 ‘{1}’ 형식을 ‘{2}’ 형식으로 변환합니다.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        이 식은 암시적 변환 '{0}'을 사용하여 '{1}' 형식을 '{2}' 형식으로 변환 합니다. https://aka.ms/fsharp-implicit-convs 참조. ’#Nowarn \ "3391\"을 (를) 사용하여 이 경고를 사용 하지 않도록 설정할 수 있습니다.
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        'InlineIfLambda' 특성은 형식이 함수 또는 F# 대리자 형식인 메서드의 인라인 함수 매개 변수에만 사용할 수 있습니다.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        보간 문자열의 불일치. 각 보간 문자열에 식(예: '%d{{1+1}}')이 지정되지 않는 한 '%' 형식 지정자를 사용할 수 없습니다.
+        
+      
+      
+        Invalid alignment in interpolated string
+        보간 문자열의 잘못된 정렬
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        '{0}' 구문은 유효한 다시 시작 가능한 코드에서만 사용할 수 있습니다.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        값, 함수 및 메서드에 '[<Struct>]'을(를) 사용하는 것은 부분 활성 패턴 정의에서만 허용됩니다.
+        
+      
+      
+        use! may not be combined with and!
+        use!는 and!와 함께 사용할 수 없습니다.
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        목록 식에서 역방향 인덱스를 잘못 사용했습니다.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        '[expr1][expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 '(expr1).[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction [expr1] [expr2]').
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        구문 '[expr1][expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction [expr1] [expr2]').
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        [<Literal>] 선언은 해당 식별자에 대한 활성 패턴을 사용할 수 없습니다.
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        리터럴로 표시된 다른 값에 값을 할당할 수 없습니다.
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        리터럴로 표시된 값에 '{0}'을(를) 할당할 수 없습니다.
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        이 식은 인덱싱을 지원합니다. 'expr.[index]'. 'expr[index]' 구문에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        이 값은 인덱싱을 지원합니다. '{0}.[index]'. 구문 '{1}[index]'에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        이 식은 함수가 아니며 인덱스 표기법을 지원하지 않습니다.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        '{0}' 값은 함수가 아니며 인덱스 표기법을 지원하지 않습니다.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        'expr1[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 'expr1.[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]').
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        구문 'expr1[expr2]'은 이제 인덱싱용으로 예약되어 있으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]').
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        '(expr1)[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 '(expr1).[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]').
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        구문 '(expr1)[expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]').
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        'let! ... and! ...' 구문은 계산 식 작성기에서 '{0}' 메서드 또는 적절한 'MergeSource' 및 'Bind' 메서드를 정의한 경우에만 사용할 수 있습니다.
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 매개 변수는 대리자 또는 함수 형식이어야 합니다.
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 매개 변수의 이름은 '__expand'로 시작해야 합니다.
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다.
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드를 수락하거나 반환하는 함수 메서드는 'inline'으로 표시되어야 합니다.
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        다시 시작 가능한 코드 호출입니다. 기존 다시 시작 가능한 코드와 관련하여 하위 수준의 새 다시 시작 가능 코드를 정의하는 경우 이 경고를 표시하지 않습니다.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        다시 시작 가능한 코드 또는 다시 시작 가능한 상태 시스템을 사용하려면 /langversion:preview가 필요합니다.
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        이 식은 암시적으로 '{0}' 형식을 '{1}' 형식으로 변환 합니다. https://aka.ms/fsharp-implicit-convs 참조
+        
+      
+      
+        Invalid interpolated string. {0}
+        잘못된 보간 문자열. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        인터페이스 멤버 '{0}'에 가장 한정적인 구현이 없습니다.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        '{0}'이(가) '{2}' 및 '{3}' 인스턴스화가 포함된 '{1}' 인터페이스를 구현할 수 없습니다. 이 두 인스턴스화가 통합될 수 있기 때문입니다.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        '{1}' 및 '{2}' 인스턴스화가 포함된 '{0}' 인터페이스를 구현할 수 없습니다. 이 두 인스턴스화가 통합될 수 있기 때문입니다.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        '{0}' 형식은 '{1}' 필드, 생성자 또는 멤버를 정의하지 않습니다.
+        
+      
       
         The namespace '{0}' is not defined.
         '{0}' 네임스페이스가 정의되지 않았습니다.
@@ -134,7 +844,7 @@
       
       
         Maybe you want one of the following:
-        다음 중 하나가 필요할 수 있습니다.
+        다음 중 하나가 필요할 수 있습니다:
         
       
       
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        목록 생성자의 모든 요소는 동일한 형식이어야 합니다. 이 식에는 '{0}' 형식이 필요하지만 여기에서는 '{1}' 형식이 지정되었습니다.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        목록의 모든 요소는 암시적으로 ‘{0}’ 형식의 첫 번째 요소 형식으로 변환되어야 합니다. 이 요소는 형식 ‘{1}’입니다.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        배열 생성자의 모든 요소는 동일한 형식이어야 합니다. 이 식에는 '{0}' 형식이 필요하지만 여기에서는 '{1}' 형식이 지정되었습니다.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        배열의 모든 요소는 암시적으로 ‘{0}’ 형식의 첫 번째 요소 형식으로 변환되어야 합니다. 이 요소는 형식 ‘{1}’입니다.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        if' 식의 모든 분기는 동일한 형식이어야 합니다. 이 식에는 '{0}' 형식이 필요하지만 여기에서는 '{1}' 형식이 지정되었습니다.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        “If” 식의 모든 분기는 암시적으로 ‘{0}’ 형식의 첫 번째 분기로 변환되어 값을 반환해야 합니다. 이 분기는 ‘{1}’ 형식 값을 반환합니다.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        패턴 일치 식의 모든 분기는 동일한 형식의 값을 반환해야 합니다. 첫 번째 분기는 '{0}' 형식의 값을 반환했지만 이 분기는 '{1}' 형식의 값을 반환했습니다.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        패턴 일치 식의 모든 분기는 암시적으로 ‘{0}’ 형식의 첫 번째 분기로 변환되어 값을 반환해야 합니다. 이 분기는 ‘{1}’ 형식 값을 반환합니다.
         
       
       
@@ -212,11 +922,51 @@
         'return'이 아니라 'return!'를 사용하세요.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        이 특성은 현재 F# 컴파일러에서 지원되지 않습니다. 이 특성을 적용해도 의도한 효과를 얻을 수 없습니다.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         기본적으로 활성화되는 참조 어셈블리를 .NET Framework 참조에 사용합니다(사용 가능한 경우).
         
       
+      
+        This XML comment is invalid: '{0}'
+        이 XML 주석이 잘못됨: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        이 XML 주석이 잘못됨: 매개 변수 '{0}'에 대한 여러 설명서 항목이 있음
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        이 XML 주석이 잘못됨: 알 수 없는 매개 변수 '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        이 XML 주석이 잘못됨: 상호 참조에 'cref' 특성이 없음
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        이 XML 주석이 불완전함: 매개 변수 '{0}'에 대한 설명서가 없음
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        이 XML 주석이 잘못됨: 매개 변수 또는 매개 변수 참조에 'name' 특성이 없음
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        이 XML 주석이 잘못됨: 확인되지 않은 상호 참조 '{0}'
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         'yield'가 아닌 'yield!'를 사용하세요.
@@ -242,16 +992,6 @@
         버전 파일 '{0}'이(가) 잘못되었습니다.
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Compiler 버전 {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        F# {0}에 대한 F# 컴파일러
-        
-      
       
         Problem with filename '{0}': {1}
         파일 이름 '{0}'에 문제가 있습니다. {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        명명된 인수에 둘 이상의 값이 할당되었습니다.
+        The named argument '{0}' has been assigned more than one value
+        명명된 인수 '{0}'에 둘 이상의 값이 할당되었습니다.
         
       
       
@@ -1189,17 +1929,17 @@
       
       
         Bad format specifier (after l or L): Expected ld,li,lo,lu,lx or lX. In F# code you can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
-        l 또는 L 뒤에서 서식 지정자가 잘못되었습니다. ld, li, lo, lu, lx 또는 lX가 필요합니다. F# 코드에서는 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u를 대신 사용할 수 있습니다.
+        l 또는 L 뒤에서 서식 지정자가 잘못되었습니다. ld, li, lo, lu, lx 또는 lX가 필요합니다. F# 코드에서는 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u을(를) 대신 사용할 수 있습니다.
         
       
       
         The 'l' or 'L' in this format specifier is unnecessary. In F# code you can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
-        이 서식 지정자에서 'l' 또는 'L'은 불필요합니다. F# 코드에서는 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u를 대신 사용할 수 있습니다.
+        이 서식 지정자에서 'l' 또는 'L'은 불필요합니다. F# 코드에서는 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u을(를) 대신 사용할 수 있습니다.
         
       
       
         The 'h' or 'H' in this format specifier is unnecessary. You can use %d, %x, %o or %u instead, which are overloaded to work with all basic integer types.
-        이 서식 지정자에서 'h' 또는 'H'는 불필요합니다. 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u를 대신 사용할 수 있습니다.
+        이 서식 지정자에서 'h' 또는 'H'는 불필요합니다. 모든 기본 정수 형식과 함께 사용할 수 있도록 오버로드되는 %d, %x, %o 또는 %u을(를) 대신 사용할 수 있습니다.
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        후보: {0}
-        
-      
-      
-        The available overloads are shown below.
-        사용 가능한 오버로드가 아래에 표시됩니다.
+        Candidates:\n{0}
+        후보:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        측정 단위는 float, float32, decimal 및 부호 있는 정수 형식에 대해서만 지원됩니다.
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        측정 단위는 float, float32, 10진 및 정수 형식에 대해서만 지원됩니다.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet은 구문 분석 트리에만 필요합니다.
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet은 구문 분석 트리에만 필요합니다.
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        인덱서 식이 잘못되었습니다.
+        Incomplete expression or invalid use of indexer syntax
+        불완전한 식 또는 잘못된 인덱서 구문 사용
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        레코드 필드 및 단순, 비재귀적 'let' 바인딩만 mutable로 표시할 수 있습니다.
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        변경이 가능한 'let' 바인딩을 반복하거나 재귀 모듈 또는 네임스페이스에서 정의할 수 없습니다.
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        상수 값도 지정된 경우(예: 'val x : int = 1')에만 선언은 [<Literal>] 특성일 수 있습니다.
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        유효한 숫자 리터럴이 아닙니다. 유효한 숫자 리터럴로는 1, 0x1, 0b0001(int), 1u(uint32), 1L(int64), 1UL(uint64), 1s(int16), 1y(sbyte), 1uy(byte), 1.0(float), 1.0f(float32), 1.0m(decimal), 1I(BigInteger) 등이 있습니다.
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        유효한 숫자 리터럴이 아닙니다. 유효한 숫자 리터럴로는 1, 0x1, 0o1, 0b1, 1l(int), 1u(uint32), 1L(int64), 1UL(uint64), 1s(int16), 1y(sbyte), 1uy(byte), 1.0(float), 1.0f(float32), 1.0m(decimal), 1I(BigInteger) 등이 있습니다.
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        {0}' 어셈블리 특성이 로드할 수 없거나 존재하지 않는 디자이너 어셈블리'{1}'을(를) 참조합니다. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        어셈블리 특성 '{0}'은(는) '{2}' 경로에서 로드할 수 없는 디자이너 어셈블리 '{1}'을(를) 참조합니다. 보고된 예외: {3} - {4}
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        이 식은 함수가 아니며 적용할 수 없습니다. 대신 {0}.[index]를 통해 인덱서에 액세스하려고 했나요?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        이 값은 함수가 아니며 적용할 수 없습니다. '{0}.[index]'를 통해 인덱서에 액세스하려고 했습니까?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        이 식은 함수가 아니며 적용할 수 없습니다. 대신 expr.[index]를 통해 인덱서에 액세스하려고 했나요?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        이 표현식은 함수가 아니며 적용할 수 없습니다. 'expr.[index]'를 통해 인덱서에 액세스하려고 했습니까?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        두 무명 레코드 형식의 필드 이름 '{0}' 및 '{1}' 집합이 일치하지 않습니다.
+        이 익명 레코드는 필요한 도형과 정확하게 일치하지 않습니다. 누락된 필드 {0}을(를) 추가하고 추가 필드 {1}을(를) 제거하세요.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        디자인 타임 도구를 포함하는 어셈블리 또는 디렉터리를 참조합니다(약식: -t).
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        패키지 관리자 키 '{0}'이(가) {1}에 등록되지 않았습니다. 현재 {2}이(가) 등록되었습니다.
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        종속성 관리자 확장 {0}을(를) 로드할 수 없습니다. 메시지: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf
index 07c155e3203..5b2074d0bea 100644
--- a/src/fsharp/xlf/FSComp.txt.pl.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pl.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} dla języka F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        Funkcja „{0}” nie jest dostępna w języku F# {1}. Użyj języka w wersji {2} lub nowszej.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        Funkcja „{0}” nie jest obsługiwana przez docelowe środowisko uruchomieniowe.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        Funkcja „{0}” wymaga biblioteki języka F# dla wersji językowej {1} lub nowszej.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        Użycie elementu „:=" z biblioteki języka F# jest przestarzałe. Zobacz https://aka.ms/fsharp-refcell-ops. Na przykład zmień wyrażenie „cell := expr” na „cell.Value <- expr”.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        Użycie elementu „decr" z biblioteki języka F# jest przestarzałe. Zobacz https://aka.ms/fsharp-refcell-ops. Na przykład zmień wyrażenie „decr cell” na „cell.Value <- cell.Value - 1”.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        Użycie elementu „!" z biblioteki języka F# jest przestarzałe. Zobacz https://aka.ms/fsharp-refcell-ops. Na przykład zmień wyrażenie „!cell” na „cell.Value”.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        Użycie elementu „incr" z biblioteki języka F# jest przestarzałe. Zobacz https://aka.ms/fsharp-refcell-ops. Na przykład zmień wyrażenie „incr cell” na „cell.Value <- cell.Value + 1”.
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        Element „AssemblyKeyNameAttribute” jest przestarzały. Zamiast niego użyj elementu „AssemblyKeyFileAttribute”.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Podpisywanie kontenerów kluczy nie jest obsługiwane na tej platformie.
+        
+      
+      
+        Available overloads:\n{0}
+        Dostępne przeciążenia:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Konstrukcja ogólna wymaga, aby parametr typu ogólnego był znany jako struktura lub typ referencyjny. Rozważ dodanie adnotacji typu.
+        
+      
+      
+        Known types of arguments: {0}
+        Znane typy argumentów: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Znany typ argumentu: {0}
+        
+      
+      
+        Known return type: {0}
+        Znany zwracany typ: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Parametry znanego typu: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Parametr znanego typu: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        Argument pod indeksem {0} nie jest zgodny
+        
+      
+      
+        Argument '{0}' doesn't match
+        Argument „{0}” nie jest zgodny
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Nie można załadować zestawu projektanta dostawców typów „{0}” z folderu „{1}”, ponieważ brakuje zależności lub nie można jej załadować. Wszystkie zależności zestawu projektanta dostawców typów muszą znajdować się w tym samym folderze co ten zestaw. Zgłoszony wyjątek: {2} — {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Nie można załadować zestawu projektanta dostawców typów „{0}” z folderu „{1}”. Zgłoszony wyjątek: {2} — {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        Atrybut zestawu „{0}” odwołuje się do zestawu projektanta „{1}”, którego nie można załadować lub który nie istnieje. Zgłoszony wyjątek: {2} — {3}
+        
+      
+      
+        additional type-directed conversions
+        dodatkowe konwersje ukierunkowane na typ
+        
+      
+      
+        applicative computation expressions
+        praktyczne wyrażenia obliczeniowe
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        atrybuty po prawej stronie słowa kluczowego "module"
+        
+      
+      
+        default interface member consumption
+        domyślne użycie składowej interfejsu
+        
+      
+      
+        discard pattern in use binding
+        odrzuć wzorzec w powiązaniu użycia
+        
+      
+      
+        dotless float32 literal
+        bezkropkowy literał float32
+        
+      
+      
+        more types support units of measure
+        więcej typów obsługuje jednostki miary
+        
+      
+      
+        fixed-index slice 3d/4d
+        część o stałym indeksie 3d/4d
+        
+      
+      
+        from-end slicing
+        wycinanie od końca
+        
+      
+      
+        implicit yield
+        niejawne słowo kluczowe yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        notacja wyrażenia expr[idx] do indeksowania i fragmentowania
+        
+      
+      
+        interfaces with multiple generic instantiation
+        interfejsy z wieloma ogólnymi wystąpieniami
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        stałe wzorce po prawej stronie wzorców typu „as”
+        
+      
+      
+        nullable optional interop
+        opcjonalna międzyoperacyjność dopuszczająca wartość null
+        
+      
+      
+        open type declaration
+        deklaracja typu otwartego
+        
+      
+      
+        overloads for custom operations
+        przeciążenia dla operacji niestandardowych
+        
+      
+      
+        package management
+        zarządzanie pakietami
+        
+      
+      
+        binary formatting for integers
+        formatowanie danych binarnych dla liczb całkowitych
+        
+      
+      
+        informational messages related to reference cells
+        komunikaty informacyjne związane z odwołaniami do komórek
+        
+      
+      
+        whitespace relexation
+        rozluźnianie reguł dotyczących odstępów
+        
+      
+      
+        whitespace relaxation v2
+        łagodzenie odstępów wer 2
+        
+      
+      
+        resumable state machines
+        automaty stanów z możliwością wznowienia
+        
+      
+      
+        single underscore pattern
+        wzorzec z pojedynczym podkreśleniem
+        
+      
+      
+        string interpolation
+        interpolacja ciągu
+        
+      
+      
+        struct representation for active patterns
+        reprezentacja struktury aktywnych wzorców
+        
+      
+      
+        wild card in for loop
+        symbol wieloznaczny w pętli for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        monitor, który przekazuje ograniczenia cech języka F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        W interpolowanych ciągach nie można używać specyfikatorów formatu „%”, chyba że każdemu z nich odpowiada wyrażenie, na przykład „%d{{1+1}}”.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Specyfikatory formatu w stylu platformy .NET, takie jak „{{x,3}}” lub „{{x:N5}}”, nie mogą być mieszane ze specyfikatorami formatu „%”.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Specyfikator „%P” nie może być używany jawnie.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        W interpolowanych ciągach używanych jako typ IFormattable lub FormattableString nie można używać specyfikatorów „%”. Można używać tylko operatorów interpolacji, takich jak „{{expr}}”, „{{expr,3}}” lub „{{expr:N5}}”.
+        
+      
+      
+         - {0}
+         — {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Wycinanie od końca wymaga języka w wersji 5.0, użyj parametru /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Nieprawidłowa dyrektywa „#{0} {1}”
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Konstrukcja kodu z możliwością wznowienia "{0}" może być używana tylko w nieliniowym kodzie chronionym przez "If __useResumableCode then..." i ogólna kompozycja musi być w formacie prawidłowego kodu z możliwością wznowienia.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        Atrybut "InlineIfLambda" jest obecny w sygnaturze, ale nie w implementacji.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Słowo kluczowe na potrzeby określania literału stałej jako argumentu parametru typu w przypadku dostawców typów.
+        
+      
+      
+        a byte string may not be interpolated
+        ciąg bajtowy nie może być interpolowany
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        W przypadku znaku „}}” należy zastosować ucieczkę (przez wpisanie dwóch takich znaków) w ciągu interpolowanym.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Nieprawidłowy ciąg interpolowany. Literały z pojedynczymi cudzysłowami lub literały ciągów dosłownych nie mogą być używane w wyrażeniach interpolowanych w ciągach z pojedynczymi cudzysłowami lub ciągach dosłownych. Rozważ użycie jawnego powiązania „let” dla wyrażenia interpolacji lub użycie ciągu z potrójnymi cudzysłowami jako zewnętrznego literału ciągu.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Nieprawidłowy ciąg interpolowany. Literały ciągów z potrójnymi cudzysłowami nie mogą być używane w wyrażeniach interpolowanych. Rozważ użycie jawnego powiązania „let” dla wyrażenia interpolacji.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         Nagłówek zasobu rozpoczynający się od przesunięcia {0} jest nieprawidłowo sformułowany.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „expr[index]”?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „{0}[index]”?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        Wartość "{0}" została oznaczona jako "InlineIfLambda", ale nie została określona jako mająca wartość lambda. To ostrzeżenie jest przeznaczone tylko do celów informacyjnych.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Drukowanie wywnioskowanych interfejsów wszystkich plików kompilacji do skojarzonych plików sygnatur
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Wyświetl dozwolone wartości dla wersji językowej; określ wersję językową, np. „latest” lub „preview”
@@ -37,9 +417,49 @@
         Nierozpoznana wartość „{0}” dla parametru –langversion; podaj parametr –langversion:?, aby uzyskać pełną listę
         
       
+      
+        Display compiler version banner and exit
+        Wyświetl baner wersji kompilatora i zakończ
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Określ plik ikony systemu Win32 (ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Funkcja zarządzania pakietami wymaga języka w wersji 5.0, użyj parametru /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Nieprawidłowy ciąg interpolowany. Wyrażenie ciągu interpolowanego nie jest wypełnione, a jest oczekiwane.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Niekompletny ciąg interpolowany rozpoczęty w tym miejscu lub wcześniej
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Niekompletne wypełnienie wyrażenia interpolowanego ciągu rozpoczęte w tym miejscu lub wcześniej
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Niekompletny interpolowany ciąg z potrójnym cudzysłowem rozpoczęty w tym miejscu lub wcześniej
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Niekompletny interpolowany dosłowny ciąg rozpoczęty w tym miejscu lub wcześniej
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Nieoczekiwany token w definicji typu. Oczekiwano znaku „=” po typie „{0}”.
         
       
       
@@ -57,19 +477,109 @@
         Algorytm „{0}” nie jest obsługiwany
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Etykieta docelowa __resumeAt nie została statycznie określona. __resumeAt z niestatyczną etykietą docelową może występować tylko na początku metody kodu z możliwością wznawiania
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Szybka liczba całkowita dla pętli nie może zawierać punktów wznowienia
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        W specyfikacji kodu z możliwością wznowienia, wystąpił błąd "let rec"
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Blok "with" elementu try/with nie może zawierać punktów wznowienia
+        
+      
+      
+        A try/finally may not contain resumption points
+        Try/finally nie może zawierać punktów wznowienia
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Delegat lub funkcja wytwarzająca kod z możliwością wznowienia na automacie stanów ma parametry typu ogólnego
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Nie można zmniejszyć wywołania kodu z możliwością wznowienia w "{0}"
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        Wartości kodu z możliwością wznowienia "{0}" nie mają definicji
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        Element #i nie jest obsługiwany przez zarejestrowanych menedżerów pakietów
+        
+      
+      
+        The state machine has an unexpected form
+        Automat stanów ma nieoczekiwany formularz
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Ten automat stanów nie jest statycznie kompilowalny. {0}. Zostanie użyta alternatywna implementacja dynamiczna, która może być wolniejsza. Rozważ dostosowanie kodu, aby upewnić się, że ten automat stanów jest statycznie kompilowalny, lub w przeciwnym razie pomiń to ostrzeżenie.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Ten automat stanów nie jest statycznie kompilowalny i nie jest dostępna żadna alternatywa. {0}. Użyj instrukcji "if __useResumableCode, a następnie <state-machine>else <alternative>", aby podać alternatywę.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Nie można określić zestawu .NET SDK dla tego skryptu. Jeśli skrypt znajduje się w katalogu korzystającym z pliku „global.json”, upewnij się, że zainstalowano odpowiedni zestaw .NET SDK. Dane wyjściowe polecenia „{0} --version” w katalogu „{1}” to „{2}”, a kod zakończenia to „{3}”.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Nie można określić zestawu .NET SDK dla tego skryptu. Nie można odnaleźć pliku dotnet.exe. Upewnij się, że zestaw .NET SDK jest zainstalowany.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Nie można określić zestawu .NET SDK dla tego skryptu. Jeśli skrypt znajduje się w katalogu korzystającym z pliku „global.json”, upewnij się, że zainstalowano odpowiedni zestaw .NET SDK. Nieoczekiwany błąd: „{0}”.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        To wyrażenie ma typ "{0}" i jest zgodne tylko z typem "{1}" za pośrednictwem niejednoznacznie bezwarunkowej konwersji. Rozważ użycie jednoznacznego wywołania elementu "op_Implicit". Odpowiednimi jednoznacznymi konwersjami są: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Ta funkcja nie jest obsługiwana w tej wersji języka F#. Aby korzystać z tej funkcji, może być konieczne dodanie parametru /langversion:preview.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        To jest nieprawidłowy rekord anonimowy. Powinien zawierać pola {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Ten rekord anonimowy nie ma wystarczającej liczby pól. Dodaj brakujące pola {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Ten rekord anonimowy ma za dużo pól. Usuń dodatkowe pola {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Nieprawidłowa deklaracja typu rekordu anonimowego.
         
       
       
@@ -77,6 +587,206 @@
         Atrybutów nie można stosować do rozszerzeń typu.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        Do indeksowania używana jest składnia „expr1[expr2]”. Rozważ dodanie adnotacji typu, aby umożliwić indeksowanie, lub jeśli wywołujesz funkcję dodaj spację, np. „expr1 [expr2]”.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        Składnia wyrażenia „expr1[expr2]” jest teraz zarezerwowana dla indeksowania. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję, dodaj spację między funkcją a argumentem, np. „someFunction [expr]”.
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Typy ByRef są niedozwolone w deklaracji typu otwartego.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        Składnia argumentu „arr.[idx]” została zmieniona na „arr[idx]”. Aktualizuj kod.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        W tym wyrażeniu jest używana wbudowana bezwzględna konwersja w celu przekonwertowania typu "{0}" na typ "{1}". Zobacz https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        W tym wyrażeniu jest używana bezwzględna konwersja "{0}" w celu przekonwertowania typu "{1}" na typ "{2}".
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        W tym wyrażeniu jest używana bezwzględna konwersja "{0}" w celu przekonwertowania typu "{1}" na typ "{2}". Zobacz https://aka.ms/fsharp-implicit-convs. To ostrzeżenie można wyłączyć przy użyciu polecenia "#nowarn \" 3391 \ ".
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        Atrybut "InlineIfLambda" może być używany tylko w przypadku parametrów funkcji z podkreśleniem metod, których typ to funkcja lub typ delegata języka F #.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Niezgodność w interpolowanym ciągu. W interpolowanych ciągach nie można używać specyfikatorów formatu „%”, chyba że każdemu z nich odpowiada wyrażenie, na przykład „%d{{1+1}}”.
+        
+      
+      
+        Invalid alignment in interpolated string
+        Nieprawidłowe wyrównanie w ciągu interpolowanym
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        Konstrukcji "{0}" można używać tylko w prawidłowym kodzie z możliwością wznowienia.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        Używanie elementu "[<Struct>]" na wartościach, funkcjach i metodach jest dozwolone tylko w definicjach częściowo aktywnego wzorca
+        
+      
+      
+        use! may not be combined with and!
+        Elementu use! nie można łączyć z elementem and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Nieprawidłowe użycie indeksu odwrotnego w wyrażeniu listy.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Składnia wyrażenia „[expr1][expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „(expr1).[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction [expr1] [expr2]”.
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Składnia wyrażenia „[expr1][expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction [expr1] [expr2]”.
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Deklaracja [<Literal>] nie może używać aktywnego wzorca dla swojego identyfikatora
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Nie można przypisać wartości do innej wartości oznaczonej jako literał
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Nie można przypisać elementu „{0}” do wartości oznaczonej jako literał
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        To wyrażenie obsługuje indeksowanie, np. „expr.[index]”. Składnia wyrażenia „expr[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Ta wartość obsługuje indeksowanie, m.in. „{0}.[index]”. Składnia wyrażenia „{1}[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        To wyrażenie nie jest funkcją i nie obsługuje notacji indeksowej.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        Wartość elementu „{0}” nie jest funkcją i nie obsługuje notacji indeksowej.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Składnia wyrażenia „expr1[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „expr1.[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Składnia wyrażenia „expr1[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Składnia wyrażenia „(expr1)[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „(expr1).[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Składnia wyrażenia „(expr1)[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”.
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        Konstrukcji „let! ... and! ...” można użyć tylko wtedy, gdy konstruktor wyrażeń obliczeniowych definiuje metodę „{0}” lub odpowiednie metody „MergeSource” i „Bind”
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Nieprawidłowy kod z możliwością wznowienia. Parametr kodu z możliwością wznowienia musi być obiektem delegowanym lub typem funkcji
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Nieprawidłowy kod z możliwością wznowienia. Parametr kodu z możliwością wznowienia musi mieć nazwę zaczynającą się od "__expand"
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Nieprawidłowy kod z możliwością wznowienia. W specyfikacji kodu z możliwością wznowienia wystąpił element "let rec"
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Nieprawidłowy kod z możliwością wznowienia. Każda metoda akceptująca lub zwracająca kod z możliwością wznowienia musi być oznaczona jako "inline"
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Wywołanie kodu z możliwością wznowienia. Pomiń to ostrzeżenie, jeśli definiujesz nowy kod z możliwością wznowienia niskiego poziomu w terminologii istniejącego kodu z możliwością wznowienia.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Używanie kodu z możliwością wznowienia lub automatów stanów z możliwością wznowienia wymaga parametru /langversion: wersja zapoznawcza
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        To wyrażenie bezwzględnie konwertuje typ "{0}" na typ "{1}". Zobacz https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Nieprawidłowy ciąg interpolowany. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Składowa interfejsu „{0}” nie ma najbardziej specyficznej implementacji.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        Element „{0}” nie może implementować interfejsu „{1}” z dwoma wystąpieniami „{2}” i „{3}”, ponieważ mogą one się ujednolicić.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Nie możesz zaimplementować interfejsu „{0}” przy użyciu dwóch wystąpień „{1}” i „{2}”, ponieważ mogą one się ujednolicić.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Typ „{0}” nie definiuje pola, konstruktora lub składowej „{1}”.
+        
+      
       
         The namespace '{0}' is not defined.
         Nie zdefiniowano przestrzeni nazw „{0}”.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Wszystkie elementy wyrażenia konstruktora listy muszą mieć ten sam typ. Oczekiwano, że to wyrażenie będzie miało typ „{0}”, ale tutaj ma typ „{1}”.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Wszystkie elementy listy muszą być bezwarunkowo konwertowalne na typ pierwszego elementu, którym w tym przypadku jest "{0}". Ten element ma typ "{1}".
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Wszystkie elementy wyrażenia konstruktora tablicy muszą mieć ten sam typ. Oczekiwano, że to wyrażenie będzie miało typ „{0}”, ale tutaj ma typ „{1}”.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Wszystkie elementy tablicy muszą być bezwarunkowo konwertowalne na typ pierwszego elementu, którym w tym przypadku jest "{0}". Ten element ma typ "{1}".
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Wszystkie gałęzie wyrażenia „if” muszą mieć ten sam typ. Oczekiwano, że to wyrażenie będzie miało typ „{0}”, ale tutaj ma typ „{1}”.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Wszystkie gałęzie wyrażenia "if" muszą zwracać wartości bezwarunkowo konwertowalne na typ pierwszej gałęzi, którą w tym przypadku jest "{0}". Ta gałąź zwraca wartość typu "{1}".
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Wszystkie gałęzie wyrażenia dopasowania do wzorca muszą zwracać wartości tego samego typu. Pierwsza gałąź zwróciła wartość typu „{0}”, ale ta gałąź zwróciła wartość typu „{1}”
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Wszystkie gałęzie wyrażenia pasującego do wzorca muszą zwracać wartości bezwarunkowo konwertowalne na typ pierwszej gałęzi, którą w tym przypadku jest "{0}". Ta gałąź zwraca wartość typu "{1}".
         
       
       
@@ -212,11 +922,51 @@
         Rozważ użycie polecenia „return!” zamiast „return”.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Ten atrybut jest obecnie nieobsługiwany przez kompilator języka F#. Zastosowanie go nie spowoduje osiągnięcie zamierzonego skutku.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Użyj zestawów odwołań dla odwołań do programu .NET Framework, gdy są dostępne (domyślnie włączone).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Ten komentarz XML jest nieprawidłowy: „{0}”
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Ten komentarz XML jest nieprawidłowy: wiele wpisów dokumentacji dla parametru „{0}”
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Ten komentarz XML jest nieprawidłowy: nieznany parametr „{0}”
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Ten komentarz XML jest nieprawidłowy: brak atrybutu „cref” dla odsyłacza
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Ten komentarz XML jest niekompletny: brak dokumentacji dla parametru „{0}”
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Ten komentarz XML jest nieprawidłowy: brak atrybutu „name” dla parametru lub odwołania parametru
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Ten komentarz XML jest nieprawidłowy: nierozpoznany odsyłacz „{0}”
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Rozważ użycie polecenia „yield!” zamiast „yield”.
@@ -242,16 +992,6 @@
         Nieprawidłowy plik wersji „{0}”
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Wersja {0} kompilatora języka Microsoft (R) F#
-        
-      
-      
-        F# Compiler for F# {0}
-        Kompilator języka F# dla języka F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problem z nazwą pliku „{0}”: {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Do nazwanego argumentu przypisano więcej niż jedną wartość
+        The named argument '{0}' has been assigned more than one value
+        Do nazwanego argumentu „{0}” przypisano więcej niż jedną wartość
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Kandydujący: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Dostępne przeciążenia są pokazane poniżej.
+        Candidates:\n{0}
+        Kandydaci:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Jednostki miary są obsługiwane tylko w przypadku typów float, float32, decimal i signed integer
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Jednostki miary są obsługiwane tylko w przypadku typów float, float32, decimal i integer.
         
       
       
@@ -2403,7 +3138,7 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet only expected in parse trees
         Element MemberKind.PropertyGetSet jest oczekiwany tylko w drzewach analizy
         
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Nieprawidłowe wyrażenie indeksatora
+        Incomplete expression or invalid use of indexer syntax
+        Niekompletne wyrażenie lub nieprawidłowe użycie składni indeksatora
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Tylko pola rekordów i proste, niecykliczne powiązania „let” mogą być oznaczone jako modyfikowalne
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Modyfikowalne powiązania „let” nie mogą być rekurencyjne ani definiowane w modułach rekurencyjnych lub przestrzeniach nazw
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Deklaracja może być atrybutem [<Literal>] tylko wtedy, gdy zostanie również podana wartość stała, np. „val x : int = 1”
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Jest to nieprawidłowy literał liczbowy. Do prawidłowych literałów liczbowych należą: 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1ui (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal) oraz 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Jest to nieprawidłowy literał liczbowy. Do prawidłowych literałów liczbowych należą: 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        Atrybut zestawu „{0}” odwołuje się do zestawu projektanta „{1}”, którego nie można załadować lub który nie istnieje. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        Atrybut zestawu „{0}” odwołuje się do zestawu projektanta „{1}”, którego nie można załadować ze ścieżki „{2}”. Zgłoszony wyjątek: {3} — {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        {0} zmienna in kolekcja
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Ta wartość nie jest funkcją i nie można jej zastosować. Czy zamiast tego zamierzano uzyskać dostęp do indeksatora przy użyciu formatu {0}.[indeks]?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „{0}.[index]”?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        To wyrażenie nie jest funkcją i nie można go zastosować. Czy zamiast tego zamierzano uzyskać dostęp do indeksatora przy użyciu formatu wyrażenie.[indeks]?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „expr.[index]”?
         
       
       
@@ -7064,7 +7799,7 @@
       
       
         A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
-        Wskaźnik byref zwracany przez funkcję lub metodę jest niejawnie wyłuskiwany w języku F# 4.5 i nowszych. Aby uzyskać wartość zwracaną jako wskaźnik, użyj operatora address-of, np. „&f(x)” lub „&obj.Method(argument1, argument2)”.
+        Wskaźnik byref zwracany przez funkcję lub metodę jest niejawnie wyłuskiwany w języku F# 4.5 i nowszych. Aby uzyskać wartość zwracaną jako wskaźnik, użyj operatora address-of, np. „&f(x)” lub „&obj.Method(arg1, arg2)”.
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Dwa typy rekordów anonimowych mają niezgodne zestawy nazw pól „{0}” i „{1}”
+        Ten rekord anonimowy nie jest dokładnie zgodny z oczekiwanym kształtem. Dodaj brakujące pola {0} i usuń dodatkowe pola {1}.
         
       
       
@@ -7239,7 +7974,7 @@
       
       
         --pathmap can only be used with portable PDBs (--debug:portable or --debug:embedded)
-        Argumentu --pathmap można używać tylko z przenośnymi plikami PDB  (--debug:portable lub --debug:embedded)
+        Argumentu --pathmap można używać tylko z przenośnymi plikami PDB (--debug:portable lub --debug:embedded)
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Odwołuje się do zestawu lub katalogu zawierającego narzędzie czasu projektowania (krótka wersja: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        Klucz menedżera pakietów „{0}” nie został zarejestrowany w elemencie {1}. Obecnie zarejestrowane: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Nie można załadować rozszerzenia menedżera zależności {0}. Komunikat: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
index d6a95f10f37..40820727c14 100644
--- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} para F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        O recurso '{0}' não está disponível no F# {1}. Use a versão da linguagem {2} ou superior.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        O recurso '{0}' não é compatível com o runtime de destino.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        O recurso '{0}' exige a biblioteca F# para a versão da linguagem {1} ou posterior.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        O uso de ':=' da biblioteca F# foi preterido. Consulte https://aka.ms/fsharp-refcell-ops. Por exemplo, altere 'cell := expr' para 'cell.Value <- expr'.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        O uso de 'decr' da biblioteca F# foi preterido. Consulte https://aka.ms/fsharp-refcell-ops. Por exemplo, altere a célula 'decr célula' para 'cell.Value <- cell.Value - 1'.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        O uso de '!' da biblioteca F# foi preterido. Consulte https://aka.ms/fsharp-refcell-ops. Por exemplo, altere '!cell' para 'cell.Value'.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        O uso de 'incr' da biblioteca F# foi preterido. Consulte https://aka.ms/fsharp-refcell-ops. Por exemplo, altere a célula 'incr célula' para 'cell.Value <- cell.Value + 1'.
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        O 'AssemblyKeyNameAttribute' foi preterido. Use o 'AssemblyKeyFileAttribute'.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Não há suporte para a assinatura do contêiner de chave nesta plataforma.
+        
+      
+      
+        Available overloads:\n{0}
+        Sobrecargas disponíveis:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Um constructo genérico exige que um parâmetro de tipo genérico seja conhecido como um tipo de referência ou struct. Considere adicionar uma anotação de tipo.
+        
+      
+      
+        Known types of arguments: {0}
+        Tipos de argumentos conhecidos: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Tipo de argumento conhecido: {0}
+        
+      
+      
+        Known return type: {0}
+        Tipo de retorno conhecido: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Parâmetros de tipo conhecidos: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Parâmetro de tipo conhecido: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        O argumento no índice {0} não corresponde
+        
+      
+      
+        Argument '{0}' doesn't match
+        O argumento '{0}' não corresponde
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Não foi possível carregar o assembly do designer do provedor de tipos '{0}' da pasta '{1}' porque uma dependência estava ausente ou não pôde ser carregada. Todas as dependências do assembly do designer do provedor de tipos precisam estar localizadas na mesma pasta que esse assembly. A exceção relatada foi: {2} – {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Não foi possível carregar o assembly do designer do provedor de tipos '{0}' da pasta '{1}'. A exceção relatada foi: {2} – {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        O atributo de assembly '{0}' refere-se a um assembly de designer '{1}' que não pode ser carregado ou que não existe. A exceção relatada foi {2} – {3}
+        
+      
+      
+        additional type-directed conversions
+        conversões direcionadas por tipos adicionais
+        
+      
+      
+        applicative computation expressions
+        expressões de computação aplicáveis
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        atributos à direita da palavra-chave 'módulo'
+        
+      
+      
+        default interface member consumption
+        consumo de membro da interface padrão
+        
+      
+      
+        discard pattern in use binding
+        descartar o padrão em uso de associação
+        
+      
+      
+        dotless float32 literal
+        literal float32 sem ponto
+        
+      
+      
+        more types support units of measure
+        mais tipos dão suporte para unidades de medida
+        
+      
+      
+        fixed-index slice 3d/4d
+        fatia de índice fixo 3d/4d
+        
+      
+      
+        from-end slicing
+        divisão começando no final
+        
+      
+      
+        implicit yield
+        yield implícito
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        notação expr[idx] para indexação e fatia
+        
+      
+      
+        interfaces with multiple generic instantiation
+        interfaces com várias instanciações genéricas
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        padrões não-variáveis à direita dos padrões 'as'.
+        
+      
+      
+        nullable optional interop
+        interoperabilidade opcional anulável
+        
+      
+      
+        open type declaration
+        declaração de tipo aberto
+        
+      
+      
+        overloads for custom operations
+        sobrecargas para operações personalizadas
+        
+      
+      
+        package management
+        gerenciamento de pacotes
+        
+      
+      
+        binary formatting for integers
+        formatação binária para números inteiros
+        
+      
+      
+        informational messages related to reference cells
+        mensagens informativas relacionadas a células de referência
+        
+      
+      
+        whitespace relexation
+        atenuação de espaço em branco
+        
+      
+      
+        whitespace relaxation v2
+        relaxamento de espaço em branco v2
+        
+      
+      
+        resumable state machines
+        máquinas de estado retomável
+        
+      
+      
+        single underscore pattern
+        padrão de sublinhado simples
+        
+      
+      
+        string interpolation
+        interpolação da cadeia de caracteres
+        
+      
+      
+        struct representation for active patterns
+        representação estrutural para padrões ativos
+        
+      
+      
+        wild card in for loop
+        curinga para loop
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Passagem de testemunha para restrições de característica nas citações do F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        As cadeias de caracteres interpoladas não podem usar especificadores de formato '%', a menos que cada um receba uma expressão, por exemplo, '%d{{1+1}}'.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Especificadores de formato do estilo .NET, como '{{x,3}}' ou '{{x:N5}}', não podem ser misturados com especificadores de formato '%'.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Não é possível usar o especificador '%P' explicitamente.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        As cadeias de caracteres interpoladas usadas como tipo IFormattable ou tipo FormattableString não podem usar especificadores '%'. Apenas interpoladores de estilo .NET, como '{{expr}}', '{{expr,3}}' ou '{{expr:N5}}' podem ser usados.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        A opção 'Divisão começando no final' requer a versão de idioma 5.0. Use /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Diretriz inválida '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        A construção de código retomável '{0}' só pode ser usada em código delimitado protegido por 'se __useResumableCode então ...' e a composição geral deve formar um código retomável válido.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        O atributo 'InlineIfLambda' está presente na assinatura, mas não na implementação.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Palavra-chave para especificar um literal constante como um argumento de parâmetro de tipo nos Provedores de Tipo.
+        
+      
+      
+        a byte string may not be interpolated
+        uma cadeia de caracteres de byte não pode ser interpolada
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Um caractere ''}}' precisa ser de escape (ao duplicar) em uma cadeia de caracteres interpolada.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Cadeia de caracteres interpolada inválida. Literais de cadeia de caracteres verbatim ou com aspas simples não podem ser usados em expressões interpoladas em cadeias de caracteres verbatim ou com aspas simples. Considere usar uma associação 'let' explícita para a expressão de interpolação ou use uma cadeia de caracteres de aspas triplas como o literal da cadeia de caracteres externa.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Cadeia de caracteres interpolada inválida. Literais de cadeia de caracteres de aspas triplas não podem ser usados em expressões interpoladas. Considere usar uma associação 'let' explícita para a expressão de interpolação.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         O cabeçalho do recurso que começa no deslocamento {0} está malformado.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Essa expressão não é uma função e não pode ser aplicada. Você pretendia acessar o indexador por meio do 'expr[index]'?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Esse valor não é uma função e não pode ser aplicado. Você pretendia acessar o indexador por meio do '{0}[index]'?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        O valor '{0}' foi marcado como 'InlineIfLambda' mas não foi determinado como tendo um valor lambda. Este aviso é apenas para fins informativos.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Imprimir as interfaces inferidas de todos os arquivos de compilação para os arquivos de assinatura associados
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Exibe os valores permitidos para a versão do idioma, especifica a versão do idioma, como 'mais recente ' ou 'prévia'
@@ -37,9 +417,49 @@
         Valor não reconhecido '{0}' para --langversion use --langversion:? para a lista completa
         
       
+      
+        Display compiler version banner and exit
+        Exibir a faixa de versão do compilador e sair
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Especificar um arquivo de ícone do Win32 (.ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        O recurso de gerenciamento de pacotes requer a versão de idioma 5.0. Use /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Cadeia de caracteres interpolada inválida. O preenchimento dessa expressão de cadeia de caracteres interpolada está vazio. Era esperada uma expressão.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        A cadeia de caracteres interpolada incompleta foi iniciada aqui ou anteriormente
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        O preenchimento da expressão de cadeia de caracteres interpolada incompleta foi iniciado aqui ou anteriormente
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        A cadeia de caracteres de aspas triplas interpolada incompleta foi iniciada aqui ou anteriormente
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        A cadeia de caracteres verbatim interpolada incompleta foi iniciada aqui ou anteriormente
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Token inesperado na definição de tipo. Esperava-se '=' após o tipo '{0}'.
         
       
       
@@ -57,19 +477,109 @@
         Algoritmo '{0}' sem suporte
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Uma etiqueta de destino para __resumeAt não foi estaticamente determinada. Um __resumeAt com uma etiqueta de destino não estática só pode aparecer no início de um método de código retomável.
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Um inteiro rápido para loop pode não conter pontos de retomada
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        Ocorreu um "let rec" na especificação do código retomável
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        O bloco "com" de uma try/with não pode conter pontos de retomada
+        
+      
+      
+        A try/finally may not contain resumption points
+        Uma try/finally pode não conter pontos de retomada
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Um delegado ou função que produz código retomável em uma máquina de estado tem parâmetros de tipo
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Uma invocação de código retomável em '{0}' não pôde ser reduzida
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        O valor(es) de código retomável '{0}' não tem uma definição
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        O PackageManagers registrado não dá suporte a #i
+        
+      
+      
+        The state machine has an unexpected form
+        A máquina estato tem uma forma inesperada
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Esta máquina de estado não é estaticamente compilável. {0}. Será usada uma implementação dinâmica alternativa, que poderá ser mais lenta. Considere ajustar seu código para garantir que esta máquina de estado seja compilável estaticamente, ou então suprima este aviso.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Esta máquina de estado não é estaticamente compilável e não há nenhuma alternativa disponível. {0}. Usar um 'se __useResumableCode então <estado-máquina>outra <alternative>' para dar uma alternativa.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Não foi possível determinar o SDK do .NET para esse script. Se o script estiver em um diretório usando um 'global.json', verifique se o SDK relevante do .NET está instalado. A saída de '{0} --version' no diretório '{1}' foi: '{2}' e o código de saída foi '{3}'.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Não foi possível determinar o .NET SDK para este script. Não foi possível encontrar dotnet.exe e certifique-se de que o SDK do .NET esteja instalado.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Não foi possível determinar o SDK do .NET deste script. Se o script estiver em um diretório que usa um 'global.json', verifique se o SDK do .NET relevante está instalado. Erro inesperado '{0}'.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Essa expressão possui o tipo '{0}' e só é compatível com o tipo '{1}' por uma conversão implícita ambígua. Considere usar uma chamada explícita para 'op_Implicit'. As conversões implícitas aplicáveis são:{2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Este recurso não tem suporte nesta versão do F#. Talvez seja necessário adicionar /langversion:preview para usar este recurso.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Este é o registro anônimo errado. Ele deve ter os campos {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Este registro anônimo não tem campos suficientes. Adicione os campos ausentes {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Este registro anônimo tem muitos campos. Remova os campos extras {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Declaração inválida de tipo de Registro Anônimo.
         
       
       
@@ -77,6 +587,206 @@
         Os atributos não podem ser aplicados às extensões de tipo.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        A sintaxe 'expr1[expr2]' é usada para indexação. Considere adicionar uma anotação de tipo para habilitar a indexação ou, se chamar uma função, adicione um espaço, por exemplo, 'expr1 [expr2]'.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        A sintaxe ' expr1[expr2] ' agora está reservada para indexação. Consulte https://aka.ms/fsharp-index-notation. Se estiver chamando uma função, adicione um espaço entre a função e o argumento, por exemplo, 'someFunction [expr]'.
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Os tipos Byref não são permitidos em uma declaração de tipo aberto.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        A sintaxe 'arr. [idx]' agora é revisada para 'arr[idx]'. Atualize seu código.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Essa expressão usa uma conversão implícita interna para converter o tipo '{0}' ao tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Essa expressão usa a conversão implícita '{0}' para converter o tipo '{1}' ao tipo '{2}'.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Essa expressão usa a conversão implícita '{0}' para converter o tipo '{1}' ao tipo '{2}'. Consulte https://aka.ms/fsharp-implicit-convs. Este aviso pode ser desabilitado usando '#nowarn\"3391\".
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        O atributo 'InlineIfLambda' só pode ser usado em parâmetros de funções de métodos em linha cujo tipo seja uma função ou F# tipo delegado.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Incompatibilidade na cadeia de caracteres interpolada. As cadeias de caracteres interpoladas não podem usar especificadores de formato '%', a menos que cada um receba uma expressão, por exemplo, '%d{{1+1}}'
+        
+      
+      
+        Invalid alignment in interpolated string
+        Alinhamento inválido na cadeia de caracteres interpolada
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        A construção '{0}' só pode ser usada em código válido e retomável.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        O uso de '[<Struct>]' em valores, funções e métodos somente é permitido em definições de padrões ativos parciais
+        
+      
+      
+        use! may not be combined with and!
+        use! não pode ser combinado com and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Uso inválido de índice reverso na expressão da lista.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        A sintaxe ' [expr1][expr2] ' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. se você pretende indexar ou colocar em fatias e, em seguida, deve usar '(expr1). [expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'.
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'.
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Uma declaração [<Literal>] não pode usar um padrão ativo para seu identificador
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Não é possível atribuir um valor a outro valor marcado como literal
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Não é possível atribuir '{0}' a um valor marcado como literal
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Essa expressão oferece suporte à indexação, por exemplo, 'expr. [index]'. A sintaxe 'expr[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Esse valor dá suporte à indexação, por exemplo, '{0}.[index]'. A sintaxe '{1}[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Essa expressão não é uma função e não dá suporte à notação de índice.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        O valor '{0}' não é uma função e não dá suporte à notação de índice.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'.
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        O constructo 'let! ... and! ...' só pode ser usado se o construtor de expressões de computação definir um método '{0}' ou um método 'MergeSource' ou 'Bind' apropriado
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Código inválido retomável. O parâmetro de um código retomável deve ser do tipo delegado ou função
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Código inválido retomável. O parâmetro de código resumível deve ter nome começando com '__expandir'.
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Código inválido retomável. Ocorreu um "let rec" na especificação do código retomável
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Código inválido retomável. Qualquer método de função que aceite ou retorne um código de retomável deve ser marcado "embutido".
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Invocação de código retomável. Suprima esta aviso se você estiver definindo um novo código de baixo nível de código retomável em termos de código retomável existente.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Usar código retomável ou máquinas de estado retomável requer /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Essa expressão converte implicitamente o tipo '{0}' ao tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Cadeia de caracteres interpolada inválida. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        O membro de interface '{0}' não tem uma implementação mais específica.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        '{0}' não pode implementar a interface '{1}' com as duas instanciações '{2}' e '{3}' porque talvez elas sejam unificadas.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Não é possível implementar a interface '{0}' com as duas instanciações '{1}' e '{2}' porque talvez elas sejam unificadas.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        O tipo '{0}' não define o campo, o construtor ou o membro '{1}'.
+        
+      
       
         The namespace '{0}' is not defined.
         O namespace '{0}' não está definido.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Todos os elementos de uma expressão do construtor de lista devem ter o mesmo tipo. Essa expressão deveria ter o tipo '{0}', mas aqui tem o tipo '{1}'.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Todos os elementos de uma matriz devem ser implicitamente conversíveis ao tipo do primeiro elemento, que aqui é '{0}'. Esse elemento possui o tipo '{1}'.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Todos os elementos de uma expressão do construtor de matriz devem ter o mesmo tipo. Essa expressão deveria ter o tipo '{0}', mas aqui tem o tipo '{1}'.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Todos os elementos de uma matriz devem ser implicitamente conversíveis ao tipo do primeiro elemento, que aqui é '{0}'. Esse elemento tem o tipo '{1}'.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Todas as ramificações de uma expressão 'if' devem ter o mesmo tipo. Essa expressão deveria ter o tipo '{0}', mas aqui tem o tipo '{1}'.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Todas as ramificações de uma expressão 'se' devem retornar valores implicitamente conversíveis ao tipo da primeira ramificação, que aqui é '{0}'. Essa ramificação retorna um valor do tipo '{1}'.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Todos os branches de uma expressão correspondente ao padrão precisam retornar valores do mesmo tipo. O primeiro branch retornou um valor do tipo '{0}', mas este branch retornou um valor do tipo '{1}'.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Todas as ramificações de uma expressão de correspondência de padrão devem retornar valores implicitamente conversíveis ao tipo da primeira ramificação, que aqui é '{0}'. Essa ramificação retorna um valor do tipo '{1}'.
         
       
       
@@ -212,11 +922,51 @@
         Considere usar 'return!' em vez de 'return'.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Este atributo atualmente não é suportado pelo compilador F#. A sua aplicação não alcançará o efeito pretendido.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Use assemblies de referência para referências do .NET Framework quando disponível (habilitado por padrão).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Este comentário XML é inválido: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Este comentário XML é inválido: várias entradas de documentação para o parâmetro '{0}'
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Este comentário XML é inválido: parâmetro desconhecido '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Este comentário XML é inválido: atributo 'cref' ausente para referência cruzada
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Este comentário XML está incompleto: nenhuma documentação para o parâmetro '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Este comentário XML é inválido: atributo 'name' ausente para parâmetro ou referência de parâmetro
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Este comentário XML é inválido: referência cruzada não resolvida '{0}'
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Considere usar 'yield!' em vez de 'yield'.
@@ -242,16 +992,6 @@
         Arquivo de versão inválida '{0}'
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Compilador Microsoft (R) F# versão {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Compilador F# para F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Problema com nome de arquivo '{0}': {1}
@@ -554,7 +1294,7 @@
       
       
         Module '{0}' contains\n    {1}    \nbut its signature specifies\n    {2}    \nThe accessibility specified in the signature is more than that specified in the implementation
-        O módulo '{0}' contém\n    {1}    \ n, mas sua assinatura especifica\n    {2}    \nA acessibilidade especificada na assinatura é maior que a especificada na implementação
+        O módulo '{0}' contém\n    {1}    \n, mas sua assinatura especifica\n    {2}    \nA acessibilidade especificada na assinatura é maior que a especificada na implementação
         
       
       
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Foi atribuído mais de um valor a um argumento nomeado
+        The named argument '{0}' has been assigned more than one value
+        Foi atribuído mais de um valor a um argumento nomeado '{0}'
         
       
       
@@ -1459,7 +2199,7 @@
       
       
         Quotations cannot contain object expressions
-        Cotações não podem conter expressões de objeto 
+        Cotações não podem conter expressões de objeto
         
       
       
@@ -1469,7 +2209,7 @@
       
       
         Quotations cannot contain expressions that fetch static fields
-        Cotações não podem conter expressões que buscam campos estáticos 
+        Cotações não podem conter expressões que buscam campos estáticos
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Candidatos: {0}
-        
-      
-      
-        The available overloads are shown below.
-        As sobrecargas disponíveis são mostradas abaixo.
+        Candidates:\n{0}
+        Candidatos:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Unidades de medida só são suportadas em tipos float, float32, decimal e inteiro com sinal
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Há suporte para unidades de medida somente nos tipos float, float32, decimal e inteiro.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet só é esperado em árvores de análise
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet só é esperado em árvores de análise
         
       
       
@@ -2774,7 +3509,7 @@
       
       
         Anonymous type variables are not permitted in this declaration
-        Variáveis de tipos anônimos não são permitidas nesta declaração 
+        Variáveis de tipos anônimos não são permitidas nesta declaração
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Expressão de indexador inválida
+        Incomplete expression or invalid use of indexer syntax
+        Expressão incompleta ou uso inválido da sintaxe do indexador
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Apenas campos de registro e associações 'let' simples e não recursivas podem ser marcados como mutáveis
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Associações 'let' mutáveis não podem ser recursivas ou definidas em módulos recursivos ou namespaces
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Uma declaração só pode ser o atributo [<Literal>] se um valor constante também é dado, ex.:' val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -4144,7 +4879,7 @@
       
       
         Freely distributed under the MIT Open Source License.  https://github.com/Microsoft/visualfsharp/blob/master/License.txt
-        Distribuído gratuitamente sob a Licença de Software Livre do MIT.  https://github.com/Microsoft/visualfsharp/blob/master/License.txt
+        Distribuído gratuitamente sob a Licença de Código Aberto do MIT.  https://github.com/Microsoft/visualfsharp/blob/master/License.txt
         
       
       
@@ -4829,7 +5564,7 @@
       
       
         Recursive ValValue {0}
-        ValValue {0} recursivo 
+        ValValue {0} recursivo
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Este não é um literal numérico válido. Literais numéricos válidos incluem 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Este não é um literal numérico válido. Literais numéricos válidos incluem 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        O atributo '{0}' do assembly refere-se a um assembly de designer '{1}' que não pode ser carregado ou não existe. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        O atributo de assembly '{0}' se refere a um assembly de designer '{1}' que não pode ser carregado do caminho '{2}'. A exceção relatada foi: {3} – {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        {0} var na coleção
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Este valor não é uma função e não pode ser aplicado. Você pretendia acessar o indexador por meio do {0}.[index] como alternativa?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Esse valor não é uma função e não pode ser aplicado. Você pretendia acessar o indexador por meio do '{0}.[index]'?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Esta expressão não é uma função e não pode ser aplicada. Você pretendia acessar o indexador por meio do expr.[index] como alternativa?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Essa expressão não é uma função e não pode ser aplicada. Você pretendia acessar o indexador por meio do 'expr.[index]'?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Dois tipos de registro anônimos têm conjuntos incompatíveis de nomes de campos '{0}' e '{1}'
+        Este registro anônimo não corresponde exatamente à forma esperada. Adicione os campos ausentes {0} e remova os campos extras {1}.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Referenciar um assembly ou um diretório contendo uma ferramenta de tempo de design (forma abreviada: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        A chave '{0}' do gerenciador de pacotes não foi registrada em {1}. Registrada no momento: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Não foi possível carregar a extensão do gerenciador de dependências {0}. Mensagem: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf
index d364e6e039c..d17847bea59 100644
--- a/src/fsharp/xlf/FSComp.txt.ru.xlf
+++ b/src/fsharp/xlf/FSComp.txt.ru.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        {0} для F# {1}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        Компонент "{0}" недоступен в F# {1}. Используйте версию языка {2} или выше.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        Компонент "{0}" не поддерживается целевой средой выполнения.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        Компоненту "{0}" требуется библиотека F# для языка версии {1} или более поздней.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        Использование ":=" из библиотеки F# не рекомендуется. См. https://aka.ms/fsharp-refcell-ops. Например, замените "cell := expr" на "cell.Value <- expr".
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        Использование "decr" из библиотеки F# не рекомендуется. См. https://aka.ms/fsharp-refcell-ops. Например, замените "decr cell" на "cell.Value <- cell.Value - 1".
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        Использование "!" из библиотеки F# не рекомендуется. См. https://aka.ms/fsharp-refcell-ops. Например, замените "!cell" на "cell.Value".
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        Использование "incr" из библиотеки F# не рекомендуется. См. https://aka.ms/fsharp-refcell-ops. Например, замените "incr cell" на "cell.Value <- cell.Value + 1".
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        Атрибут "AssemblyKeyNameAttribute" является устаревшим. Используйте вместо него атрибут "AssemblyKeyFileAttribute".
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Подписывание контейнера ключей не поддерживается на этой платформе.
+        
+      
+      
+        Available overloads:\n{0}
+        Доступные перегрузки:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        В универсальной конструкции требуется использовать параметр универсального типа, известный как структура или ссылочный тип. Рекомендуется добавить заметку с типом.
+        
+      
+      
+        Known types of arguments: {0}
+        Известные типы аргументов: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Известный тип аргумента: {0}
+        
+      
+      
+        Known return type: {0}
+        Известный тип возвращаемого значения: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Известные параметры типа: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Известный параметр типа: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        Аргумент в индексе {0} не соответствует
+        
+      
+      
+        Argument '{0}' doesn't match
+        Аргумент "{0}" не соответствует
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        Не удалось загрузить сборку конструктора поставщика типа "{0}" из папки "{1}", так как зависимость отсутствует или не может быть загружена. Все зависимости для сборки конструктора поставщика типа должны находиться в папке сборки. Получено исключение: {2} — {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        Не удалось загрузить сборку конструктора поставщика типа "{0}" из папки "{1}". Получено исключение: {2} — {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена или не существует. Получено исключение: {2} — {3}
+        
+      
+      
+        additional type-directed conversions
+        дополнительные преобразования на основе типа
+        
+      
+      
+        applicative computation expressions
+        применимые вычислительные выражения
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        атрибуты справа от ключевого слова "module"
+        
+      
+      
+        default interface member consumption
+        использование элемента интерфейса по умолчанию
+        
+      
+      
+        discard pattern in use binding
+        шаблон отмены в привязке использования
+        
+      
+      
+        dotless float32 literal
+        литерал float32 без точки
+        
+      
+      
+        more types support units of measure
+        другие типы поддерживают единицы измерения
+        
+      
+      
+        fixed-index slice 3d/4d
+        срез с фиксированным индексом 3d/4d
+        
+      
+      
+        from-end slicing
+        срезы от конца
+        
+      
+      
+        implicit yield
+        неявное использование yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        expr[idx] для индексации и среза
+        
+      
+      
+        interfaces with multiple generic instantiation
+        интерфейсы с множественным универсальным созданием экземпляра
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        шаблоны без переменных справа от шаблонов "as"
+        
+      
+      
+        nullable optional interop
+        необязательное взаимодействие, допускающее значение NULL
+        
+      
+      
+        open type declaration
+        объявление открытого типа
+        
+      
+      
+        overloads for custom operations
+        перегрузки для настраиваемых операций
+        
+      
+      
+        package management
+        управление пакетами
+        
+      
+      
+        binary formatting for integers
+        двоичное форматирование для целых чисел
+        
+      
+      
+        informational messages related to reference cells
+        информационные сообщения, связанные с ссылочными ячейками
+        
+      
+      
+        whitespace relexation
+        уменьшение строгости для пробелов
+        
+      
+      
+        whitespace relaxation v2
+        смягчение требований по использованию пробелов, версия 2
+        
+      
+      
+        resumable state machines
+        возобновляемые конечные автоматы
+        
+      
+      
+        single underscore pattern
+        шаблон с одним подчеркиванием
+        
+      
+      
+        string interpolation
+        интерполяция строк
+        
+      
+      
+        struct representation for active patterns
+        представление структуры для активных шаблонов
+        
+      
+      
+        wild card in for loop
+        подстановочный знак в цикле for
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        Передача свидетеля для ограничений признаков в цитированиях F#
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        В интерполированных строках запрещено использовать описатели формата "%", если только каждому из них не назначено выражение, например "'%d{{1+1}}".
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        Описатели формата в стиле .NET, такие как "{{x,3}}" или "{{x:N5}}", запрещено смешивать с описателями формата "%".
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        Описатель "%P" запрещено использовать явно.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        Интерполированные строки, используемые в качестве типа IFormattable или FormattableString, не могут использовать описатели "%". Можно использовать только описатели в стиле .NET, такие как "{{expr}}", "{{expr,3}}" или "{{expr:N5}}".
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Для конечного среза, для которого требуется версия языка 5.0, используйте параметр /langversion:preview.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Недопустимая директива "#{0} {1}"
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Конструкцию возобновляемого кода "{0}" можно использовать только во встроенном коде, защищенном с помощью "if __useResumableCode then ...", а общая композиция должна представлять собой допустимый возобновляемый код.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        Атрибут "InlineIfLambda" присутствует в сигнатуре, но отсутствует в реализации.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Ключевое слово для указания константного литерала в качестве аргумента параметра типа в поставщиках типов.
+        
+      
+      
+        a byte string may not be interpolated
+        невозможно выполнить интерполяцию для строки байтов
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Символ "}}" необходимо экранировать (путем дублирования) в интерполированной строке.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Недопустимая интерполированная строка. Строковые литералы с одинарными кавычками или буквальные строковые литералы запрещено использовать в интерполированных выражениях в строках с одинарными кавычками или буквальных строках. Рекомендуется использовать явную привязку "let" для выражения интерполяции или использовать строку с тройными кавычками как внешний строковый литерал.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Недопустимая интерполированная строка. Строковые литералы с тройными кавычками запрещено использовать в интерполированных выражениях. Рекомендуется использовать явную привязку "let" для выражения интерполяции.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         Заголовок ресурса некорректен начиная со смещения {0}.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Это выражение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "expr[index]"?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Это значение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "{0}[index]"?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        Значение "{0}" было помечено "InlineIfLambda", но не определено как содержащее значение лямбда-выражения. Это предупреждение приводится исключительно для информации.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Печать определяемых интерфейсов всех файлов компиляции в связанные файлы подписей
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Отображение допустимых значений для версии языка. Укажите версию языка, например, "latest" или "preview".
@@ -37,9 +417,49 @@
         Не удалось распознать значение "{0}" для параметра --langversion. Для получения полного списка допустимых значений выполните команду use --langversion:?
         
       
+      
+        Display compiler version banner and exit
+        Отобразить окно с версией компилятора и выйти
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Укажите файл значка Win32 (ICO)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Для функции управления пакетами требуется версия языка 5.0, используйте параметр /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Недопустимая интерполированная строка. Выражение этой интерполированной строки является пустым. Ожидается выражение.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Неполная интерполированная строка, начатая в этой позиции или до нее
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Заполнение выражения неполной интерполированной строки, начатое в этой позиции или до нее
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Неполная интерполированная строка с тройными кавычками, начатая в этой позиции или до нее
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Неполная интерполированная буквальная строка, начатая в этой позиции или до нее
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Неожиданный токен в определении типа. После типа "{0}" ожидается "=".
         
       
       
@@ -57,19 +477,109 @@
         Алгоритм "{0}" не поддерживается
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        Целевая метка для __resumeAt не была статически определена, при этом __resumeAt с нестатической целевой меткой может находиться только в начале метода возобновляемого кода
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        Быстрый целочисленный цикл for не может содержать точки возобновления
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        В спецификации возобновляемого кода возникла ошибка "let rec"
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Блок "with" конструкции try/with не может содержать точки возобновления
+        
+      
+      
+        A try/finally may not contain resumption points
+        Токи возобновления не должны содержаться в try/finally
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Делегат или функция, производящие возобновляемый код в конечном автомате, содержит параметры типа
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        Не удалось редуцировать вызов возобновляемого кода в "{0}"
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        У значений "{0}" возобновляемого кода нет определения
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i не поддерживается зарегистрированными диспетчерами пакетов
+        
+      
+      
+        The state machine has an unexpected form
+        У этого конечного автомата непредвиденная форма
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Этот конечный автомат не является статически компилируемым. {0}. Будет использована альтернативная динамическая реализация, которая может работать медленнее. Рекомендуем изменить код, чтобы обеспечить статическую компилируемость этого конечного автомата. В противном случае подавите это предупреждение.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Этот конечный автомат не является статически компилируемым, альтернативы недоступны. {0}. Чтобы предоставить альтернативу, используйте "if __useResumableCode then <конечный автомат> else <альтернатива>".
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Не удалось определить пакет SDK .NET для этого сценария. Если сценарий находится в каталоге с использованием "global.json", убедитесь, что установлен соответствующий пакет SDK .NET. Выходные данные команды "{0} --version" в каталоге "{1}" — "{2}", а код выхода — "{3}".
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Не удалось определить пакет SDK .NET для этого сценария. Не удалось найти dotnet.exe. Убедитесь, что пакет SDK .NET установлен.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Не удалось определить пакет SDK .NET для этого скрипта. Если сценарий находится в каталоге с использованием файла "global.json", убедитесь, что установлен соответствующий пакет SDK .NET. Непредвиденная ошибка "{0}".
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Это выражение имеет тип "{0}" и совместимо только с типом "{1}" посредством неоднозначного неявного преобразования. Рассмотрите возможность использования явного вызова "op_Implicit". Применимые неявные преобразования: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Эта функция не поддерживается в данной версии F#. Возможно, потребуется добавить/langversion:preview, чтобы использовать эту функцию.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Неправильная анонимная запись. Она должна содержать поля {0}.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        В этой анонимной записи недостаточно полей. Добавьте недостающие поля {0}.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Эта анонимная запись содержит слишком много полей. Удалите лишние поля {0}.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Недопустимое объявление типа анонимной записи.
         
       
       
@@ -77,6 +587,206 @@
         Атрибуты не могут быть применены к расширениям типа.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        Для индексирования используется синтаксис "expr1[expr2]". Рассмотрите возможность добавления аннотации типа для включения индексации или при вызове функции добавьте пробел, например "expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        Синтаксис "expr1[expr2]" сейчас зарезервирован для индексирования. См. https://aka.ms/fsharp-index-notation. При вызове функции добавьте пробел между функцией и аргументом, например "someFunction [expr]".
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Типы ByRef запрещены в объявлении открытого типа.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        Синтаксис "arr.[idx]" в настоящее время изменен на "arr[idx]". Обновите код.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Это выражение использует встроенное неявное преобразование, чтобы преобразовать тип "{0}" в тип "{1}". См. сведения на странице https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Это выражение использует неявное преобразование "{0}" для преобразования типа "{1}" в тип "{2}".
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Это выражение использует неявное преобразование "{0}" для преобразования типа "{1}" в тип "{2}". См. сведения на странице https://aka.ms/fsharp-implicit-convs. Это предупреждение можно отключить, используя параметр '#nowarn \"3391\"
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        Атрибут "InlineIfLambda" может использоваться только в параметрах встраиваемых функций методов, типом которых является функция или делегат F#.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Несоответствие в интерполированной строке. В интерполированных строках запрещено использовать описатели формата "%", если только каждому из них не назначено выражение, например "'%d{{1+1}}".
+        
+      
+      
+        Invalid alignment in interpolated string
+        Недопустимое выравнивание в интерполированной строке
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        Конструкция "{0}" может использоваться только в допустимом возобновляемом коде.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        Использование "[<Struct>]" для значений, функций и методов разрешено только для определений частичных активных шаблонов
+        
+      
+      
+        use! may not be combined with and!
+        use! запрещено сочетать с and!
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Недопустимое использование обратного индекса в выражении списка.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Синтаксис "[expr1][expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "(expr1).[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction [expr1] [expr2]".
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Синтаксис "[expr1][expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction [expr1] [expr2]".
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        Объявление [<Literal>] не может использовать активный шаблон для своего идентификатора.
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Невозможно присвоить значение другому значению, помеченному как литерал
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Невозможно присвоить "{0}" значению, помеченному как литерал
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Это выражение поддерживает индексирование, например, "expr. [index]". Для синтаксиса "expr[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Это значение поддерживает индексирование, например, "{0}.[index]". Для синтаксиса "{1}[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Это выражение не является функцией и не поддерживает нотацию индекса.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        Значение {0} не является функцией и не поддерживает нотацию индекса.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Синтаксис "expr1[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "expr1.[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction expr1 [expr2]".
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Синтаксис "expr1[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction expr1 [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Синтаксис "(expr1)[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "(expr1).[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction (expr1) [expr2]".
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Синтаксис "(expr1)[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction (expr1) [expr2]".
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        Конструкцию "let! ... and! ..." можно использовать только в том случае, если построитель выражений с вычислениями определяет либо метод "{0}", либо соответствующие методы "MergeSource" и "Bind"
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Недопустимый возобновляемый код. Параметр возобновляемого кода должен быть типа делегата или функции.
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Недопустимый возобновляемый код. Имя параметра возобновляемого кода должно начинаться с "__expand"
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Недопустимый возобновляемый код. В спецификации возобновляемого кода возникла ошибка "let rec"
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Недопустимый возобновляемый код. Любой метод или функция, принимающие или возвращающие возобновляемый код, должны иметь пометку "inline"
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Вызов возобновляемого кода. Подавите это предупреждение, если вы определяете новый низкоуровневый возобновляемый код в рамках существующего возобновляемого кода.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Для использования возобновляемого кода или возобновляемых конечных автоматов требуется /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Это выражение неявно преобразует тип "{0}" в тип "{1}". См. сведения на странице https://aka.ms/fsharp-implicit-convs.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Недопустимая интерполированная строка. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        Элемент интерфейса "{0}" не имеет наиболее конкретной реализации.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        "{0}" не может реализовать интерфейс "{1}" с двумя созданиями экземпляра "{2}" и "{3}", так как они могут быть объединены.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        Невозможно реализовать интерфейс "{0}" с двумя созданиями экземпляра "{1}" и "{2}", так как они могут быть объединены.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        Тип "{0}" не определяет поле, конструктор или член "{1}".
+        
+      
       
         The namespace '{0}' is not defined.
         Пространство имен "{0}" не определено.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Все элементы выражения конструктора списка должны иметь один и тот же тип. В этом выражении ожидалось использование типа "{0}", но используется тип "{1}".
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Все элементы списка должны поддерживать неявное преобразование в тип первого элемента, которым здесь является "{0}". Тип этого элемента: "{1}".
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Все элементы выражения конструктора массива должны иметь один и тот же тип. В этом выражении ожидалось использование типа "{0}", но используется тип "{1}".
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Все элементы массива должны поддерживать неявное преобразование в тип первого элемента, которым здесь является "{0}". Тип этого элемента: "{1}".
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Все ветви выражения "if" должны иметь один и тот же тип. В этом выражении ожидалось использование типа "{0}", но используется тип "{1}".
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Все ветви выражения "if" должны возвращать значения, поддерживающие неявное преобразование в тип первой ветви, которым здесь является "{0}". Эта ветвь возвращает значение типа "{1}".
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Все ветви выражения сопоставления шаблонов должны возвращать значения одного типа. Первая ветвь возвратила значение типа "{0}", а эта ветвь — типа "{1}".
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Все ветви выражения соответствия шаблону должны возвращать значения, поддерживающие неявное преобразование в тип первой ветви, которым здесь является "{0}". Эта ветвь возвращает значение типа "{1}".
         
       
       
@@ -212,11 +922,51 @@
         Рекомендуется использовать "return!" вместо "return".
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Сейчас этот атрибут не поддерживается компилятором F#. Его применение не приведет к желаемому результату.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Использовать базовые сборки для ссылок на платформу .NET, если базовые сборки доступны (включено по умолчанию).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Недопустимый XML-комментарий: "{0}"
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Недопустимый XML-комментарий: несколько записей документации для параметра "{0}"
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Недопустимый XML-комментарий: неизвестный параметр "{0}"
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Недопустимый XML-комментарий: отсутствует атрибут "cref" для перекрестной ссылки
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Неполный XML-комментарий: отсутствует документация для параметра "{0}"
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Недопустимый XML-комментарий: отсутствует атрибут "name" для параметра или ссылки на параметр
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Недопустимый XML-комментарий: неразрешенная перекрестная ссылка "{0}"
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         Рекомендуется использовать "yield!" вместо "yield".
@@ -242,16 +992,6 @@
         Недопустимый файл версии "{0}"
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Compiler, версия {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        Компилятор F# для F# {0}
-        
-      
       
         Problem with filename '{0}': {1}
         Ошибка в имени файла "{0}": {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Именованному аргументу было назначено более одного значения
+        The named argument '{0}' has been assigned more than one value
+        Именованному аргументу "{0}" было присвоено несколько значений
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Кандидаты: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Доступные перегрузки показаны ниже.
+        Candidates:\n{0}
+        Кандидаты:\n{0}
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Единицы измерения поддерживаются только с типами float, float32, decimal и signed integer
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Единицы измерения поддерживаются только с типами float, float32, decimal и integer.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet требуется только в деревьях синтаксического анализа
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet используется только в деревьях синтаксического анализа
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Недопустимое выражение индексатора
+        Incomplete expression or invalid use of indexer syntax
+        Неполное выражение или недопустимое использование синтаксиса индексатора
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Только поля записей и простые нерекурсивные привязки "let" могут быть помечены как изменяемые
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Изменяемые привязки "let" не могут быть рекурсивными или определенными в рекурсивных модулях или пространствах имен
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Объявление может представлять собой только атрибут [<Literal>], если указано значение константы, например, 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Не является допустимым числовым литералом. Допустимые числовые литералы: 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Это не является допустимым числовым литералом. Допустимые числовые литералы: 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена или не существует. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена по пути "{2}". Получено исключение: {3} — {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        Переменная {0} в коллекции
+        {0} var in collection
         
       
       
@@ -6004,7 +6739,7 @@
       
       
         '{0}' must come after a 'for' selection clause and be followed by the rest of the query. Syntax: ... {1} ...
-        Перед "{0}" должно идти предложение выбора "for", а после — оставшаяся часть запроса. Синтаксис: … {1} …
+        Перед "{0}" должно идти предложение выбора "for", а после — оставшаяся часть запроса. Синтаксис: ... {1} ...
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Это значение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью {0}.[индекс]?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Это значение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "{0}.[index]"?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Это выражение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью <выражение>.[индекс]?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Это выражение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "expr.[index]"?
         
       
       
@@ -7029,12 +7764,12 @@
       
       
         This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'.
-        Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат> = <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield".
+        Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат>= <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield".
         
       
       
         This expression returns a value of type '{0}' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'.
-        Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат> = <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield!".
+        Это выражение возвращает значение типа "{0}", но оно неявно отбрасывается. Чтобы привязать результат к какому-то имени, используйте "let", например: "let <результат>= <выражение>". Если вы собирались использовать выражение как значение в последовательности, используйте в явном виде "yield!".
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        Два анонимных типа записей содержат несоответствующие наборы имен полей '{0}' и '{1}'
+        Эта анонимная запись не соответствует ожидаемой форме. Добавьте недостающие поля {0} и удалите лишние поля {1}.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Ссылка на сборку или каталог, содержащие инструмент времени разработки (краткая форма: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        Ключ "{0}" диспетчера пакетов не был зарегистрирован в {1}. Текущий зарегистрированный ключ: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        Не удалось загрузить расширение диспетчера зависимостей {0}. Сообщение: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf
index 2f05dd2afee..e4ff88cd5e0 100644
--- a/src/fsharp/xlf/FSComp.txt.tr.xlf
+++ b/src/fsharp/xlf/FSComp.txt.tr.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        F# {1} için {0}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        '{0}' özelliği F# {1} sürümünde kullanılamıyor. Lütfen {2} veya daha yüksek bir dil sürümünü kullanın.
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        '{0}' özelliği hedef çalışma zamanı tarafından desteklenmiyor.
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        '{0}' özelliği için F# kitaplığının {1} veya üstü dil sürümü gerekir.
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        F# kitaplığından gelen “:=” kullanımı kullanım dışı. https://aka.ms/fsharp-refcell-ops'a bakın. Örneğin, lütfen “cell := expr” ifadesini “cell.Value <- expr” olarak değiştirin.
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        F# kitaplığından gelen “decr” kullanımı kullanım dışı. https://aka.ms/fsharp-refcell-ops'a bakın. Örneğin, lütfen “decr cell”i “cell.Value <- cell.Value - 1” olarak değiştirin.
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        F# kitaplığından gelen “!” kullanımı kullanım dışı. https://aka.ms/fsharp-refcell-ops'a bakın. Örneğin, lütfen “cell”i “cell.Value” olarak değiştirin.
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        F# kitaplığından “incr” kullanımı kullanım dışı. https://aka.ms/fsharp-refcell-ops’a bakın. Örneğin, lütfen “incr cell”i “cell.Value <- cell.Value + 1” olarak değiştirin
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        'AssemblyKeyNameAttribute' kullanım dışı bırakıldı. Bunun yerine 'AssemblyKeyFileAttribute' kullanın.
+        
+      
+      
+        Key container signing is not supported on this platform.
+        Anahtar kapsayıcısı imzalama bu platformda desteklenmiyor.
+        
+      
+      
+        Available overloads:\n{0}
+        Kullanılabilir aşırı yüklemeler:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        Genel yapı, genel bir tür parametresinin yapı veya başvuru türü olarak bilinmesini gerektirir. Tür ek açıklaması eklemeyi düşünün.
+        
+      
+      
+        Known types of arguments: {0}
+        Bilinen bağımsız değişken türleri: {0}
+        
+      
+      
+        Known type of argument: {0}
+        Bilinen bağımsız değişken türü: {0}
+        
+      
+      
+        Known return type: {0}
+        Bilinen dönüş türü: {0}
+        
+      
+      
+        Known type parameters: {0}
+        Bilinen tür parametreleri: {0}
+        
+      
+      
+        Known type parameter: {0}
+        Bilinen tür parametresi: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        {0} dizinindeki bağımsız değişken eşleşmiyor
+        
+      
+      
+        Argument '{0}' doesn't match
+        '{0}' bağımsız değişkeni eşleşmiyor
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        '{0}' tür sağlayıcısı tasarımcı bütünleştirilmiş kodu, bir bağımlılık eksik olduğundan veya yüklenemediğinden '{1}' klasöründen yüklenemedi. Tür sağlayıcısı tasarımcısı bütünleştirilmiş kodunun tüm bağımlılıkları, ilgili bütünleştirilmiş kodun bulunduğu klasörde bulunmalıdır. Bildirilen özel durum: {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        '{0}' tür sağlayıcısı tasarımcı bütünleştirilmiş kodu '{1}' klasöründen yüklenemedi. Bildirilen özel durum: {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        '{0}' bütünleştirilmiş kod özniteliği, yüklenemeyen veya mevcut olmayan '{1}' tasarımcı bütünleştirilmiş koduna başvuruyor. Bildirilen özel durum: {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        ek tür ile yönlendirilen dönüştürmeler
+        
+      
+      
+        applicative computation expressions
+        uygulama hesaplama ifadeleri
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        'modül' anahtar sözcüğünün sağındaki öznitelikler
+        
+      
+      
+        default interface member consumption
+        varsayılan arabirim üyesi tüketimi
+        
+      
+      
+        discard pattern in use binding
+        kullanım bağlamasında deseni at
+        
+      
+      
+        dotless float32 literal
+        noktasız float32 sabit değeri
+        
+      
+      
+        more types support units of measure
+        tür daha ölçü birimlerini destekler
+        
+      
+      
+        fixed-index slice 3d/4d
+        sabit dizinli dilim 3d/4d
+        
+      
+      
+        from-end slicing
+        uçtan dilimleme
+        
+      
+      
+        implicit yield
+        örtük yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        Dizin oluşturma ve dilimleme için expr[idx] gösterimi
+        
+      
+      
+        interfaces with multiple generic instantiation
+        birden çok genel örnek oluşturma içeren arabirimler
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        'as' desenlerinin sağındaki değişken olmayan desenler
+        
+      
+      
+        nullable optional interop
+        null atanabilir isteğe bağlı birlikte çalışma
+        
+      
+      
+        open type declaration
+        açık tür bildirimi
+        
+      
+      
+        overloads for custom operations
+        özel işlemler için aşırı yüklemeler
+        
+      
+      
+        package management
+        paket yönetimi
+        
+      
+      
+        binary formatting for integers
+        tamsayılar için ikili biçim
+        
+      
+      
+        informational messages related to reference cells
+        başvuru hücreleriyle ilgili bilgi mesajları
+        
+      
+      
+        whitespace relexation
+        boşluk genişlemesi
+        
+      
+      
+        whitespace relaxation v2
+        boşluk ilişkilendirme v2
+        
+      
+      
+        resumable state machines
+        sürdürülebilir durum makineleri
+        
+      
+      
+        single underscore pattern
+        tek alt çizgi deseni
+        
+      
+      
+        string interpolation
+        dizede düz metin arasına kod ekleme
+        
+      
+      
+        struct representation for active patterns
+        etkin desenler için yapı gösterimi
+        
+      
+      
+        wild card in for loop
+        for döngüsünde joker karakter
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        F# alıntılarındaki nitelik kısıtlamaları için tanık geçirme
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        Düz metin arasına kod eklenmiş dizeler, her birine '%d{{1+1}}' gibi bir ifade verilmedikçe '%' biçim belirticilerini kullanamaz.
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        '{{X,3}}' ya da '{{x:N5}}' gibi .NET stili biçim belirticileri '%' biçim belirticileriyle karışık kullanılamaz.
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        '%P' belirticisi açık olarak kullanılamaz.
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        IFormattable veya FormattableString türü olarak kullanılan düz metin arasına kod eklenmiş dizeler '%' belirticilerini kullanamaz. Yalnızca '{{expr}}', '{{expr,3}}' veya '{{expr:N5}}' gibi .NET stili düz metin arasına kod ekleme işlemleri kullanılabilir.
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        Sondan dilimleme, 5.0 dil sürümünü gerektirir, /langversion:preview kullanın.
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        Geçersiz yönerge '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        Sürdürülebilir kod yapısı '{0}' yalnızca 'if__useResumableCode then ...' tarafından korunan satır içine alınmış kodda kullanılabilir ve genel birleştirme geçerli sürdürülebilir kod biçiminde olmalıdır.
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        'InlineIfLambda' özniteliği imzada var ama uygulamada yok.
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        Tür Sağlayıcılarında tür parametresi bağımsız değişkeni olarak sabit değişmez değeri belirtmek için anahtar sözcük.
+        
+      
+      
+        a byte string may not be interpolated
+        bir bayt dizesi, düz metin arasına kod eklenerek kullanılamaz
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        Bir '}}' karakteri, düz metin arasına kod eklenmiş bir dizede kaçış dizisi ile (yineleme yapılarak) belirtilir.
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        Geçersiz düz metin arasına kod eklenmiş dize. Tek tırnaklı veya düz metin dizesi sabitleri, tek tırnaklı veya düz metin dizelerinde düz metin arasına kod eklenmiş ifadelerde kullanılamaz. Düz metin arasına kod ekleme ifadesi için açık bir 'let' bağlaması kullanmayı düşünün veya dış dize sabiti olarak üç tırnaklı bir dize kullanın.
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        Geçersiz düz metin arasına kod eklenmiş dize. Üç tırnaklı dize sabitleri, düz metin arasına kod eklenmiş ifadelerde kullanılamaz. Düz metin arasına kod ekleme ifadesi için açık bir 'let' bağlaması kullanmayı düşünün.
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         {0} uzaklığında başlayan kaynak üst bilgisi hatalı biçimlendirilmiş.
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        Bu ifade bir fonksiyon değildir ve uygulanamaz. Dizin oluşturucuya “expr[index]” aracılığıyla mı erişmeyi düşündünüz?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        Bu değer, bir işlev değil ve uygulanamaz. Dizin oluşturucuya bunun yerine “{0}[index]” üzerinden erişmeye mi çalışıyordunuz?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        '{0}' değeri 'InlineIfLambda' olarak işaretlenmiş ancak bir lambda değerine sahip olmak üzere belirlenmemiş. Bu uyarı yalnızca bilgilendirme amaçlıdır.
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        Tüm derleme dosyalarının çıkarsanan arabirimlerini ilişkili imza dosyalarına yazdır
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         Dil sürümü için izin verilen değerleri görüntüleyin, dil sürümünü 'en son' veya 'önizleme' örneklerindeki gibi belirtin
@@ -37,9 +417,49 @@
         --langversion için '{0}' değeri tanınmıyor. Tam liste için --langversion:? kullanın
         
       
+      
+        Display compiler version banner and exit
+        Derleyici sürümü başlığını görüntüle ve çık
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        Win32 simge dosyası (.ico) belirtin
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        Paket yönetimi özelliği dil sürümü 5.0 gerektiriyor, /langversion:preview kullanın
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        Düz metin arasına kod eklenmiş dize geçersiz. Bu düz metin arasına kod eklenmiş dize ifade dolgusu boş. İfade bekleniyordu.
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        Tamamlanmamış düz metin arasına kod eklenmiş dize, burada veya daha önce başlıyordu
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        Tamamlanmamış düz metin arasına kod eklenmiş dize ifadesi dolgusu, burada veya daha önce başlıyordu
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        Tamamlanmamış düz metin arasına kod eklenmiş üç tırnaklı dize, burada veya daha önce başlıyordu
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        Tamamlanmamış düz metin arasına kod eklenmiş düz metin dizesi, burada veya daha önce başlıyordu
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        Tür tanımında beklenmeyen belirteç var. '{0}' türünden sonra '=' bekleniyordu.
         
       
       
@@ -57,19 +477,109 @@
         {0}' algoritması desteklenmiyor
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        __resumeAt için olan hedef etiket statik olarak belirlenmedi. Statik olmayan hedef etiketine sahip bir __resumeAt yalnızca sürdürülebilir kod yönteminin başında yer alabilir
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        For döngüsü için fast tamsayısı, sürdürme noktası içeremez
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        Sürdürülebilir kod belirtiminde 'let rec' oluştu
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        Try/with’in 'with' bloğu, sürdürme noktaları içeremez
+        
+      
+      
+        A try/finally may not contain resumption points
+        Try/finally sürdürme noktaları içeremez
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        Durum makinesinde sürdürülebilir kod üreten bir temsilci veya işlevin tür parametreleri var
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        '{0}' konumunda sürdürülebilir kod çağrısı azaltılamadı
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        '{0}' sürdürülebilir kod değeri bir tanıma sahip değil
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        #i, kayıtlı PackageManagers tarafından desteklenmiyor
+        
+      
+      
+        The state machine has an unexpected form
+        Durum makinesi beklenmeyen bir biçime sahip
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        Bu makine statik uyumlu değil. {0}. Alternatif bir dinamik uygulama kullanılacak ve bu daha yavaş olabilir. Bu durum makinesinin statik uyumlu olduğundan emin olmak için kodunuzu ayarlayın ya da bu uyarıyı gizleyin.
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        Bu durum makinesi statik uyumlu değil ve kullanılabilir alternatif yok. {0}. Bir alternatif sağlamak için 'if__useResumableCode then <state-machine> else <alternative>' kullanın.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        Bu betik için .NET SDK belirlenemedi. Betik 'global.json' kullanan bir dizindeyse, ilgili .NET SDK'nın yüklü olduğundan emin olun. '{1}' dizinindeki '{0} --version' çıkışı: '{2}' ve çıkış kodu: '{3}'.
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        Bu betik için .NET SDK belirlenemedi. dotnet.exe bulunamadı, bir .NET SDK'nın yüklü olduğundan emin olun.
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        Bu betik için .NET SDK belirlenemedi. Betik 'global.json' kullanan bir dizindeyse, ilgili .NET SDK'nın yüklü olduğundan emin olun. Beklenmeyen hata '{0}'.
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        Bu ifade '{0}' türüne sahip ve yalnızca belirsiz bir örtük dönüştürme aracılığıyla ’{1}' türüyle uyumlu hale getirilir. 'op_Implicit' için açık bir çağrı kullanmayı düşünün. Uygulanabilir örtük dönüştürmeler şunlardır: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        Bu özellik, bu F# sürümünde desteklenmiyor. Bu özelliği kullanabilmeniz için /langversion:preview eklemeniz gerekebilir.
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        Bu anonim kayıt yanlış. Kayıt, {0} alanlarını içermelidir.
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        Bu anonim kayıtta yeterli sayıda alan yok. Eksik {0} alanlarını ekleyin.
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        Bu anonim kayıtta çok fazla alan var. Ek {0} alanlarını kaldırın.
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        Anonim Kayıt türü bildirimi geçersiz.
         
       
       
@@ -77,6 +587,206 @@
         Öznitelikler tür uzantılarına uygulanamaz.
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        Söz dizimi “expr1[expr2]” dizin oluşturma için kullanılıyor. Dizin oluşturmayı etkinleştirmek için bir tür ek açıklama eklemeyi düşünün veya bir işlev çağırıyorsanız bir boşluk ekleyin, örn. “expr1 [expr2]”.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        Söz dizimi “expr1[expr2]” artık dizin oluşturmak için ayrılmıştır. https://aka.ms/fsharp-index-notation'a bakın. Bir işlev çağırıyorsanız, işlev ile bağımsız değişken arasına bir boşluk ekleyin, örn. “someFunction [expr]”.
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        Açık tür bildiriminde Byref türlerine izin verilmez.
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        Söz dizimi “arr.[idx]” artık “arr[idx]” olarak yeniden düzenlendi. Lütfen kodunuzu güncelleştirin.
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Bu ifade, '{0}' türünü '{1}' türüne dönüştürmek için yerleşik örtük dönüştürme kullanır. https://aka.ms/fsharp-implicit-convs adresine bakın.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        Bu ifade '{1}' türünü '{2}' türüne dönüştürmek için '{0}' örtük dönüştürmesini kullanır.
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        Bu ifade '{1}' türünü '{2}' türüne dönüştürmek için '{0}' örtük dönüştürmesini kullanır. https://aka.ms/fsharp-implicit-convs adresine bakın. Bu uyarı '#nowarn \"3391\" kullanılarak devre dışı bırakılabilir.
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        'InlineIfLambda' özniteliği yalnızca işlev veya F# temsilci türündeki yöntemlerin satır içine alınmış işlev parametrelerinde kullanılabilir.
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        Düz metin arasına kod eklenmiş dizede uyuşmazlık. Düz metin arasına kod eklenmiş dizeler, her birine '%d{{1+1}}' gibi bir ifade verilmedikçe '%' biçim belirticilerini kullanamaz
+        
+      
+      
+        Invalid alignment in interpolated string
+        Düz metin arasına kod eklenmiş dizede geçersiz hizalama
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        '{0}' yapısı yalnızca geçerli sürdürülebilir kodda kullanılabilir.
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        Değerlerde, işlevlerde ve yöntemlerde '[<Struct>]' kullanımına yalnızca kısmi etkin desen tanımlarında izin veriliyor
+        
+      
+      
+        use! may not be combined with and!
+        use!, and! ile birleştirilemez
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        Liste ifadesinde geçersiz ters dizin kullanımı.
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Söz dizimi “[expr1][expr2]”, bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “(expr1).[expr2]” kullanmanız gerekir. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction [expr1] [expr2]” gibi bir boşluk ekleyin.
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        Söz dizimi “[expr1][expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction [expr1] [expr2]”.
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        [<Literal>] bildirimi, tanımlayıcısı için etkin desen kullanamaz
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        Sabit değer olarak işaretlenen bir değere başka bir değer atanamaz
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        Sabit değer olarak işaretlenen bir değere '{0}' atanamaz
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Bu ifade dizin oluşturmayı destekler, örn. “expr.[index]”. Söz dizimi “expr.[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın.
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        Bu değer dizin oluşturmayı destekler, örn. “{0}.[index]”. Söz dizimi “{1}[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın.
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        Bu ifade bir işlev değildir ve dizin gösterimini desteklemez.
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        “{0}” değeri bir işlev değildir ve dizin gösterimini desteklemez.
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “expr1.[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”.
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Söz dizimi “(expr1)[expr2]” bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “(expr1).[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”.
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        Söz dizimi “(expr1)[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”.
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        'let! ... and! ...' yapısı, yalnızca hesaplama ifadesi oluşturucu bir '{0}' metodunu ya da uygun 'MergeSource' ve 'Bind' metotlarını tanımlarsa kullanılabilir
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        Geçersiz sürdürülebilir kod. Bir sürdürülebilir kod parametresi temsilci veya işlev türünde olmalıdır
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        Geçersiz sürdürülebilir kod. Sürdürülebilir kod parametresi '__expand' ile başlayan bir ada sahip olmalıdır
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        Geçersiz sürdürülebilir kod. Sürdürülebilir kod belirtiminde bir 'let rec' oluştu
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        Geçersiz sürdürülebilir kod. Sürdürülebilir kodu kabul eden veya döndüren her işlev yöntemi 'inline' olarak işaretlenmelidir
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        Sürdürülebilir kod çağrısı. Mevcut sürdürülebilir kod bakımından yeni alt düzey sürdürülebilir kod tanımlıyorsanız bu uyarıyı gizleyin.
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        Sürdürülebilir kod veya sürdürülebilir durum makinelerini kullanmak için /langversion:preview gerekir
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        Bu ifade '{0}' türünü örtülü olarak '{1}' türüne dönüştürür. https://aka.ms/fsharp-implicit-convs adresine bakın.
+        
+      
+      
+        Invalid interpolated string. {0}
+        Geçersiz düz metin arasına kod eklenmiş dize. {0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        '{0}' arabirim üyesinin en belirgin uygulaması yok.
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        '{0}', '{2}' ve '{3}' örnek oluşturmaları birleşebileceğinden '{1}' arabirimini bunlarla birlikte uygulayamaz.
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        '{1}' ve '{2}' örnek oluşturmaları birleşebileceğinden '{0}' arabirimini bunlarla birlikte uygulayamazsınız.
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        '{0}' türü; alanı, oluşturucuyu veya '{1}' üyesini tanımlamıyor.
+        
+      
       
         The namespace '{0}' is not defined.
         '{0}' ad alanı tanımlı değil.
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Bir list constructor ifadesinin tüm öğeleri aynı türe sahip olmalıdır. Bu ifadenin '{0}' türünde olması bekleniyordu ancak burada '{1}' türünde.
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Listenin tüm öğeleri ilk öğenin türüne örtük şekilde dönüştürülebilmelidir. Bu öğenin '{0}' türünde olması bekleniyordu ancak burada '{1}' türünde.
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        Bir array constructor ifadesinin tüm öğeleri aynı türe sahip olmalıdır. Bu ifadenin '{0}' türünde olması bekleniyordu ancak burada '{1}' türünde.
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        Dizinin tüm öğeleri ilk öğenin türüne örtük şekilde dönüştürülebilmelidir. Bu öğenin '{0}' türünde olması bekleniyordu ancak burada '{1}' türünde.
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Bir 'if' ifadesinin tüm dalları aynı türe sahip olmalıdır. Bu ifadenin '{0}' türünde olması bekleniyordu ancak burada '{1}' türünde.
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        'if' ifadesinin tüm dalları, örtük şekilde ilk dalın türüne dönüştürülebilir değerler döndürmelidir. Bu değerlerin '{0}' türünde olması bekleniyordu ancak bu dal '{1}' türünde bir değer döndürdü.
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        Bir desen eşleştirme ifadesinin tüm dalları aynı türdeki değerleri döndürmelidir. Birinci dal '{0}' türünde bir değer döndürdü ancak bu dal '{1}' türünde bir değer döndürdü.
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        Desenin tüm dalları, örtük şekilde ilk dalın türüne dönüştürülebilir değerler döndürmelidir. '{0}' türünde değerler bekleniyordu ancak bu dal '{1}' türünde bir değer döndürdü.
         
       
       
@@ -212,11 +922,51 @@
         'return' yerine 'return!' kullanmayı deneyin.
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        Bu öznitelik şu anda F# derleyici tarafından desteklenmiyor. Özniteliğin uygulanması istenen etkiyi sağlamaz.
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         Kullanılabilir olduğunda, .NET Framework başvuruları için başvuru bütünleştirilmiş kodlarını kullanın (Varsayılan olarak etkindir).
         
       
+      
+        This XML comment is invalid: '{0}'
+        Bu XML açıklaması geçersiz: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        Bu XML açıklaması geçersiz: '{0}' parametresi için birden çok belge girişi var
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        Bu XML açıklaması geçersiz: '{0}' parametresi bilinmiyor
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        Bu XML açıklaması geçersiz. Çapraz başvuru için 'cref' özniteliği eksik
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        Bu XML açıklaması eksik: '{0}' parametresi için belge yok
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        Bu XML açıklaması geçersiz: Parametre veya parametre başvurusu için 'name' özniteliği eksik
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        Bu XML açıklaması geçersiz: '{0}' çapraz başvurusu çözümlenmemiş
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         'yield' yerine 'yield!' kullanmayı deneyin.
@@ -242,16 +992,6 @@
         Geçersiz dosya sürümü '{0}'
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# Derleyicisi sürümü {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        F# {0} için F# Derleyicisi
-        
-      
       
         Problem with filename '{0}': {1}
         Dosya adında hata: '{0}': {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        Adlandırılmış bir bağımsız değişken birden fazla değere atanmış
+        The named argument '{0}' has been assigned more than one value
+        '{0}' adlandırılmış bağımsız değişkeni birden fazla değere atanmış
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        Adaylar: {0}
-        
-      
-      
-        The available overloads are shown below.
-        Kullanılabilen aşırı yüklemeler aşağıda gösterilmiştir.
+        Candidates:\n{0}
+        Adaylar:\n{0}
         
       
       
@@ -2284,7 +3019,7 @@
       
       
         The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead
-        F# kodunda '(typ,...,typ) ident' söz dizimi kullanılmaz . Bunun yerine 'ident<typ,...,typ>' söz dizimini kullanmayı göz önünde bulundurun
+        F# kodunda '(typ,...,typ) ident' söz dizimi kullanılmaz. Bunun yerine 'ident<typ,...,typ>' söz dizimini kullanmayı göz önünde bulundurun
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        Ölçü birimleri yalnızca kayan, float32, ondalık ve işaretli tamsayı türlerinde desteklenir
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        Ölçü birimleri yalnızca kayan, float32, ondalık ve tamsayı türlerinde desteklenir.
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        MemberKind.PropertyGetSet yalnızca ayrıştırma ağaçlarında beklenir
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        SynMemberKind.PropertyGetSet yalnızca ayrıştırma ağaçlarında beklenir
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        Geçersiz dizin erişimcisi ifadesi
+        Incomplete expression or invalid use of indexer syntax
+        Eksik ifade veya dizin oluşturucu sözdiziminin geçersiz kullanımı
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        Yalnızca kayıt alanları ve basit, özyinelemeli olmayan 'let' bağlamaları değişebilir olarak işaretlenebilir
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        Değişebilir 'let' bağlamaları özyinelemeli olamaz veya özyinelemeli modüllerde ya da ad alanlarında tanımlanamaz
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        Bir sabit değer de sağlanmışsa bildirim yalnızca [<Literal>] özniteliği olabilir, ör. 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        Bu geçerli bir sayısal sabit değer değil. Geçerli sayısal sabit değerler şunları içerir: 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        Bu geçerli bir sayısal sabit değer değil. Geçerli sayısal sabit değerler şunları içerir: 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
         
       
       
@@ -5199,7 +5934,7 @@
       
       
         Remove spaces between the type name and type parameter, e.g. \"C<'T>\", not \"C <'T>\". Type parameters must be placed directly adjacent to the type name.
-        Tür adı ile tür parametresi arasındaki boşlukları kaldırın (ör. \"C <'T>\" değil \"C<'T>\". Tür parametreleri doğrudan tür adına bitişik olarak yerleştirilmelidir.
+        Tür adı ile tür parametresi arasındaki boşlukları kaldırın, ör. \"C <'T>\" değil \"C<'T>\". Tür parametreleri doğrudan tür adına bitişik olarak yerleştirilmelidir.
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        Bütünleştirilmiş kod özniteliği '{0}', yüklenemeyen veya var olmayan '{1}' tasarımcı bütünleştirilmiş koduna başvuruyor. {2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        '{0}' bütünleştirilmiş kod özniteliği, '{2}' yolundan yüklenemeyen '{1}' tasarımcı bütünleştirilmiş koduna başvuruyor. Bildirilen özel durum: {3} - {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        Koleksiyonda {0} değişkeni
+        {0} var in collection
         
       
       
@@ -6299,7 +7034,7 @@
       
       
         Erased to
-        Silindiği öğe:
+        Silindiği öğe
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        Bu değer, bir işlev değil ve uygulanamaz. Dizin oluşturucuya bunun yerine {0}.[index] üzerinden erişmeye mi çalışıyordunuz?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        Bu değer, bir işlev değil ve uygulanamaz. Dizin oluşturucuya bunun yerine “{0}.[index]” üzerinden erişmeye mi çalışıyordunuz?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        Bu ifade, bir işlev değil ve uygulanamaz. Dizin oluşturucuya bunun yerine expr.[index] üzerinden erişmeye mi çalışıyordunuz?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        Bu ifade bir fonksiyon değildir ve uygulanamaz. Dizin oluşturucuya “expr.[index]” aracılığıyla mı erişmeyi düşündünüz?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        İki anonim kayıt türünün eşleşmeyen '{0}' ve '{1}' alan adı kümeleri var
+        Bu anonim kayıt, beklenen şekille tam olarak eşleşmiyor. Eksik {0} alanlarını ekleyin ve ek {1} alanlarını kaldırın.
         
       
       
@@ -7209,7 +7944,7 @@
       
       
         No implementation was given for those members: {0}Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.
-        Bu üyelere uygulama verilmedi: {0}Tüm arabirim üyelerinin uygulanması ve uygun bir "arabirim" bildirimi (ör. "arabirim ... ile üye ..." kapsamında listelenmesi gerektiğini unutmayın.
+        Bu üyelere uygulama verilmedi: {0}Tüm arabirim üyelerinin uygulanması ve uygun bir "arabirim" bildirimi (ör. "arabirim ... ile üye ...") kapsamında listelenmesi gerektiğini unutmayın.
         
       
       
@@ -7219,7 +7954,7 @@
       
       
         No implementation was given for those members (some results omitted): {0}Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.
-        Bu üyelere uygulama verilmedi (bazı sonuçlar atlandı): {0}Tüm arabirim üyelerinin uygulanması ve uygun bir "arabirim" bildirimi (ör. "arabirim ... ile üye ..." kapsamında listelenmesi gerektiğini unutmayın.
+        Bu üyelere uygulama verilmedi (bazı sonuçlar atlandı): {0}Tüm arabirim üyelerinin uygulanması ve uygun bir "arabirim" bildirimi (ör. "arabirim ... ile üye ...") kapsamında listelenmesi gerektiğini unutmayın.
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        Tasarım zamanı aracı içeren bir bütünleştirilmiş koda veya dizine başvurun (Kısa biçim: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        '{0}' paket yöneticisi anahtarı {1} içinde kayıtlı değil. Şu anda kayıtlı: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        {0} bağımlılık yöneticisi uzantısı yüklenemedi. İleti: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
index 9ee2a500ffe..4d79bd47456 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        F# {1} 的 {0}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        功能“{0}”在 F# {1} 中不可用。请使用 {2} 或更高的语言版本。
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        目标运行时不支持功能“{0}”。
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        功能“{0}”需要 {1} 或更高语言版本的 F# 库。
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        已弃用 F# 库中的“:=”。请参阅 https://aka.ms/fsharp-refcell-ops。 例如,请将“cell := expr”更改为“cell.Value <- expr”。
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        已弃用 F# 库中的“decr”。请参阅 https://aka.ms/fsharp-refcell-ops。 例如,请将“decr cell”更改为“cell.Value <- cell.Value - 1”。
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        已弃用 F# 库中的“!”。请参阅 https://aka.ms/fsharp-refcell-ops。 例如,请将“!cell”更改为“cell.Value”。
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        已弃用 F# 库中的“incr”。请参阅 https://aka.ms/fsharp-refcell-ops。 例如,请将“incr cell”更改为“cell.Value <- cell.Value + 1”。
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        "AssemblyKeyNameAttribute" 已被弃用。请改为使用 "AssemblyKeyFileAttribute"。
+        
+      
+      
+        Key container signing is not supported on this platform.
+        此平台上不支持密钥容器签名。
+        
+      
+      
+        Available overloads:\n{0}
+        可用重载:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        泛型构造要求泛型类型参数被视为结构或引用类型。请考虑添加类型注释。
+        
+      
+      
+        Known types of arguments: {0}
+        已知参数类型: {0}
+        
+      
+      
+        Known type of argument: {0}
+        已知参数类型: {0}
+        
+      
+      
+        Known return type: {0}
+        已知返回类型: {0}
+        
+      
+      
+        Known type parameters: {0}
+        已知类型参数: {0}
+        
+      
+      
+        Known type parameter: {0}
+        已知类型参数: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        索引 {0} 处的参数不匹配
+        
+      
+      
+        Argument '{0}' doesn't match
+        参数 "{0}" 不匹配
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        无法从文件夹“{1}”加载类型提供程序设计器程序集“{0}”,因为依赖项缺失或无法加载。类型提供程序设计器程序集的所有依赖项必须与该程序集位于同一文件夹中。报告的异常是: {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        未能从文件夹“{1}”加载类型提供程序设计器程序集“{0}”。报告的异常是: {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        程序集属性“{0}”引用了无法加载或不存在的设计器程序集“{1}”。报告的异常是: {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        附加类型定向转换
+        
+      
+      
+        applicative computation expressions
+        适用的计算表达式
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        "module" 关键字右侧的属性
+        
+      
+      
+        default interface member consumption
+        默认接口成员消耗
+        
+      
+      
+        discard pattern in use binding
+        放弃使用绑定模式
+        
+      
+      
+        dotless float32 literal
+        无点 float32 文本
+        
+      
+      
+        more types support units of measure
+        更多类型支持度量单位
+        
+      
+      
+        fixed-index slice 3d/4d
+        固定索引切片 3d/4d
+        
+      
+      
+        from-end slicing
+        从端切片
+        
+      
+      
+        implicit yield
+        隐式 yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        用于索引和切片的 expr[idx] 表示法
+        
+      
+      
+        interfaces with multiple generic instantiation
+        具有多个泛型实例化的接口
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        "as" 模式右侧的非变量模式
+        
+      
+      
+        nullable optional interop
+        可以为 null 的可选互操作
+        
+      
+      
+        open type declaration
+        开放类型声明
+        
+      
+      
+        overloads for custom operations
+        自定义操作的重载
+        
+      
+      
+        package management
+        包管理
+        
+      
+      
+        binary formatting for integers
+        整数的二进制格式设置
+        
+      
+      
+        informational messages related to reference cells
+        与引用单元格相关的信息性消息
+        
+      
+      
+        whitespace relexation
+        空格松弛法
+        
+      
+      
+        whitespace relaxation v2
+        空格放空 v2
+        
+      
+      
+        resumable state machines
+        可恢复状态机
+        
+      
+      
+        single underscore pattern
+        单下划线模式
+        
+      
+      
+        string interpolation
+        字符串内插
+        
+      
+      
+        struct representation for active patterns
+        活动模式的结构表示形式
+        
+      
+      
+        wild card in for loop
+        for 循环中的通配符
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        F# 引号中特征约束的见证传递
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        内插字符串不会使用 "%" 格式说明符,除非为每个字符串提供诸如 "%d{{1+1}}" 之类的表达式。
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        .NET 样式的格式说明符(如 "{{x,3}}" 或 "{{x:N5}}")不能与 "%" 格式说明符混合使用。
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        不能显式使用 "%P" 说明符。
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        作为类型 IFormattable 或类型 FormattableString 使用的内插字符串不能使用 "%" 说明符,只能使用 .NET 样式的插植,如 "{{expr}}"、"{{expr,3}}" 或 "{{expr:N5}}"。
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        需要语言版本 5.0 才能从末尾切片,请使用 /langversion:preview。
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        无效的指令“#{0} {1}”
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        可恢复的代码构造 "{0}" 只能用于受 "if __useResumableCode then..." 保护的内联代码,且整体组合必须构成有效的可恢复代码。
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        "InlineIfLambda" 属性存在于签名中,但实现中不存在。
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        用于将常量文本指定为类型提供程序中的类型形参实参的关键字。
+        
+      
+      
+        a byte string may not be interpolated
+        不能内插字节字符串
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        在内插字符串中,必需对 "}}" 字符进行转义(通过加倍)。
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        内插字符串无效。在单引号字符串或逐字字符串的内插表达式中不能使用单引号或逐字字符串文本。请考虑对内插表达式使用显式 "let" 绑定,或使用三重引号字符串作为外部字符串文本。
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        内插字符串无效。在内插表达式中不能使用三重引号字符串文字。请考虑对内插表达式使用显式的 "let" 绑定。
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         以偏移量 {0} 开始的资源标头格式不正确。
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        此表达式不是函数,无法应用。是否曾打算通过 expr[index] 访问索引器?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        此值不是一个函数,无法应用。是否曾打算通过 '{0}[index]' 访问索引器?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        值 "{0}" 标记为 "InlineIfLambda",但未确定其具有 lambda 值。此警告仅供参考。
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        将所有编译文件的推断接口打印到关联的签名文件
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         显示语言版本的允许值,指定语言版本,如“最新”或“预览”
@@ -37,9 +417,49 @@
         --langversion 的值“{0}”无法识别,使用 --langversion:? 获取完整列表。
         
       
+      
+        Display compiler version banner and exit
+        显示编译器版本横幅并退出
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        指定 Win32 图标文件(.ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        包管理功能需要语言版本 5.0,请使用 /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        内插字符串无效。此内插字符串表达式填充为空,应为表达式。
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        在此处或之前开始的内插字符串不完整
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        在此处或之前开始的内插字符串表达式不完整
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        在此处或之前开始的内插三重引号字符串不完整
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        在此处或之前开始的内插逐字字符串不完整
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        类型定义中出现意外标记。类型“{0}”后应为 "="。
         
       
       
@@ -57,19 +477,109 @@
         不支持算法“{0}”
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        未静态确定 __resumeAt 的目标标签。具有非静态目标标签的 __resumeAt 只能出现在可恢复代码方法的开头
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        循环的快速整数不能包含恢复点
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        可恢复代码规范中出现 "let rec"
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        try/with 的 "with" 块可能不包含恢复点
+        
+      
+      
+        A try/finally may not contain resumption points
+        try/finally 不能包含恢复点
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        在状态机中生成可恢复代码的委托或函数具有类型参数
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        无法减少位于 "{0}" 的可恢复代码调用
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        可恢复的代码值 "{0}" 没有定义
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        注册的 PackageManager 不支持 #i
+        
+      
+      
+        The state machine has an unexpected form
+        状态机具有意外的窗体
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        此状态机不可静态编译。{0}。将使用另一种动态实现,可能速度较慢。请考虑调整代码以确保此状态机是可静态编译的,或者禁止显示此警告。
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        此状态机不可静态编译,并且没有可用的替代方法。{0}。 请使用 "if __useResumableCode 然后 <state-machine> else <alternative>' 以提供替代方法。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        无法确定此脚本的 .NET SDK。如果脚本在使用 "global.json" 的目录中,请确保已安装相关的 .NET SDK。目录“{1}”中 "{0} --version" 的输出为“{2}”,退出代码为“{3}”。
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        无法确定此脚本的 .NET SDK。找不到 dotnet.exe,请确保安装了 .NET SDK。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        无法确定此脚本的 .NET SDK。如果脚本在使用 "global.json" 的目录中,请确保已安装相关的 .NET SDK。出现意外错误“{0}”。
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        此表达式的类型为“{0}”,仅可通过不明确的隐式转换使其与类型“{1}”兼容。请考虑使用显式调用“op_Implicit”。适用的隐式转换为: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        此版本的 F# 不支持此功能。你可能需要添加 /langversion:preview 才可使用此功能。
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        此匿名记录不正确。它应具有字段 {0}。
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        此匿名记录没有足够的字段。请添加缺少的字段 {0}。
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        此匿名记录的字段太多。请删除额外的字段 {0}。
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        匿名记录类型声明无效。
         
       
       
@@ -77,6 +587,206 @@
         属性不可应用于类型扩展。
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        语法“expr1[expr2]”用于索引。考虑添加类型批注来启用索引,或者在调用函数添加空格,例如“expr1 [expr2]”。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        语法“expr1[expr2]”现在保留用于索引。请参阅 https://aka.ms/fsharp-index-notation。如果调用函数,请在函数和参数之间添加空格,例如“someFunction [expr]”。
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        在开放类型声明中不允许使用 Byref 类型。
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        语法“arr.[idx]”现在修改为“arr[idx]”。请更新代码。
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        此表达式使用内置隐式转换将类型“{0}”转换为类型“{1}”。请参阅 https://aka.ms/fsharp-implicit-convs。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        此表达式使用隐式转换“{0}”将类型“{1}”转换为类型“{2}”。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        此表达式使用隐式转换“{0}”将类型“{1}”转换为类型“{2}”。请参阅 https://aka.ms/fsharp-implicit-convs。可使用 '#nowarn \"3391\" 禁用此警告。
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        "InlineIfLambda" 特性只能用于类型为函数或 F# 委托类型的方法的内联函数的参数。
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        在内插字符串中不匹配。内插字符串不会使用 "%" 格式说明符,除非为每个字符串提供像 "'%d{{1+1}}" 这样的表达式
+        
+      
+      
+        Invalid alignment in interpolated string
+        内插字符串中的对齐无效
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        构造 "{0}" 只能在有效的可恢复代码中使用。
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        只允许在部分活动模式定义中对值、函数和方法使用 "[<Struct>]"
+        
+      
+      
+        use! may not be combined with and!
+        use! 不得与 and! 结合使用
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        列表表达式中反向索引的使用无效。
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        语法“[expr1][expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“(expr1).[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction [expr1] [expr2]”。
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        语法“[expr1][expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction [expr1] [expr2]”。
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        [<Literal>] 声明不能对其标识符使用活动模式
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        无法将值分配给标记为文本的其他值
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        无法将“{0}”分配给标记为文本的值
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        此表达式支持索引,例如“expr.[index]”。语法“expr[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        此值支持索引,例如“{0}.[index]”。语法“{1}[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        此表达式不是函数,不支持索引表示法。
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        值 '{0}' 不是函数,不支持索引表示法。
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        语法“expr1[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“expr1.[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction expr1 [expr2]”。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        语法“expr1[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction expr1 [expr2]”。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        语法“(expr1)[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“(expr1)[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction (expr1)[expr2]”。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        语法“(expr1)[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction (expr1) [expr2]”。
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        仅当计算表达式生成器定义了 "{0}" 方法或适当的 "MergeSource" 和 "Bind" 方法时,才可以使用 "let! ... and! ..." 构造
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        可恢复代码无效。可恢复的代码参数必须为委托或函数类型
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        可恢复代码无效。可恢复代码参数的名称必须以 "__expand" 开头
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        可恢复代码无效。可恢复代码规范中出现 "let rec"
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        可恢复代码无效。接受或返回可恢复代码的任何函数方法都必须标记为 "inline"
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        可恢复的代码调用。如果要根据现有可恢复代码定义新的低级别可恢复代码,请取消显示此警告。
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        使用可恢复代码或可恢复状态机需要 /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        此表达式将类型“{0}”隐式转换为类型“{1}”。请参阅 https://aka.ms/fsharp-implicit-convs。
+        
+      
+      
+        Invalid interpolated string. {0}
+        内插字符串无效。{0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        接口成员“{0}”没有最具体的实现。
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        “{0}”无法实现具有两个实例化“{2}”和“{3}”的接口“{1}”,因为它们可能会统一。
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        你无法实现具有两个实例化“{1}”和“{2}”的接口“{0}”,因为它们可能会统一。
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        类型“{0}”未定义字段、构造函数或成员“{1}”。
+        
+      
       
         The namespace '{0}' is not defined.
         未定义命名空间“{0}”。
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        列表构造函数表达式的所有元素必须具有同一类型。此表达式的类型应为“{0}”,但此处类型为“{1}”。
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        列表构造函数表达式的所有元素都必须可隐式转换为同一类型,此表达式的类型应为“{0}”。但此处类型为“{1}”。
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        数组构造函数表达式的所有元素必须具有同一类型。此表达式的类型应为“{0}”,但此处类型为“{1}”。
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        数组构造函数表达式的所有元素都必须可隐式转换为同一类型,此表达式的类型应为“{0}”。但此处类型为“{1}”。
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        if 表达式的所有分支必须具有同一类型。此表达式的类型应为“{0}”,但此处类型为“{1}”。
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        if 表达式的所有分支都必须返回可隐式转换为同一类型的值。此表达式的类型应为“{0}”,但此处类型为“{1}”。
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        模式匹配表达式的所有分支必须返回相同类型的值。第一个分支返回“{0}”类型的值,但此分支返回“{1}”类型的值。
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        模式匹配表达式的所有分支都必须返回可隐式转换为同一类型的值。此表达式的类型应为“{0}”,但此处类型为“{1}”。
         
       
       
@@ -212,11 +922,51 @@
         考虑使用 "return!",而非 "return"。
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        F# 编译器当前不支持此属性。应用它不会达到预期效果。
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         如果可用,请对 .NET Framework 引用使用引用程序集(默认启用)。
         
       
+      
+        This XML comment is invalid: '{0}'
+        此 XML 注释无效:“{0}”
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        此 XML 注释无效: 参数“{0}”有多个文档条目
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        此 XML 注释无效: 未知参数“{0}”
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        此 XML 注释无效: 交叉引用缺少 "cref" 属性
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        此 XML 注释不完整: 参数“{0}”没有文档
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        此 XML 注释无效: 参数或参数引用缺少 "name" 属性
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        此 XML 注释无效: 交叉引用“{0}”无法解析
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         考虑使用 "yield!",而非 "yield"。
@@ -242,16 +992,6 @@
         版本文件“{0}”无效
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft(R) F# 编译器版本 {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        适用于 F# {0} 的 F# 编译器
-        
-      
       
         Problem with filename '{0}': {1}
         文件名“{0}”存在问题: {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        已为一个命名参数分配多个值
+        The named argument '{0}' has been assigned more than one value
+        已向命名参数“{0}”分配多个值
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        候选项: {0}
-        
-      
-      
-        The available overloads are shown below.
-        下方显示了可用重载。
+        Candidates:\n{0}
+        候选项:\n{0}
         
       
       
@@ -2364,7 +3099,7 @@
       
       
         Non-zero constants cannot have generic units. For generic zero, write 0.0<_>.
-        非零常量不能具有泛型单位。对于泛型零,请编写  0.0<_>。
+        非零常量不能具有泛型单位。对于泛型零,请编写 0.0<_>。
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        仅 float、float32、decimal 和带符号整数类型支持度量单位
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        仅 float、float32、decimal 和整数类型支持度量单位。
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        仅分析树中需要 MemberKind.PropertyGetSet
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        分析树中只应有 SynMemberKind.PropertyGetSet
         
       
       
@@ -2899,7 +3634,7 @@
       
       
         Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq {{ ... }}'
-        记录、序列或计算表达式无效。序列表达式的格式应为“seq {{ ... }}”}}'
+        记录、序列或计算表达式无效。序列表达式的格式应为“seq {{ ... }}”
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        索引器表达式无效
+        Incomplete expression or invalid use of indexer syntax
+        表达式不完整或无效索引器语法使用
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        只有记录字段和简单的非递归 "let" 绑定可能会被标记为“可变”
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        可变 "let" 绑定不能在递归模块或命名空间中递归或定义
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        如果还给定了常量值,则声明只能是 [<Literal>] 属性,例如 "val x : int = 1"
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        这不是有效的数字文本。有效的数字文本包括 1、0x1、0b0001 (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger)。
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        这不是有效的数字文本。有效的数字文本包括 1、0x1、0o1、0b1、1l (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger)。
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        程序集特性“{0}”引用的设计器程序集“{1}”无法加载或不存在。{2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        程序集属性“{0}”引用了无法从路径“{2}”加载的设计器程序集“{1}”。报告的异常是: {3} - {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        集合中的 {0} var
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        此值不是一个函数,无法应用。是否曾打算改为通过 {0}.[index] 访问索引器?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        此值不是一个函数,无法应用。是否曾打算通过 '{0}.[index]' 访问索引器?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        此值不是一个函数,无法应用。是否曾打算改为通过 expr.[index] 访问索引器?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        此表达式不是函数,无法应用。是否曾打算通过 expr.[index] 访问索引器?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        两个匿名记录类型具有一组不匹配的字段名称“{0}”和“{1}”
+        此匿名记录与预期的形状不完全匹配。请添加缺少的字段 {0} 并删除额外的字段 {1}。
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        引用包含设计时工具的程序集或目录(短格式: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        未在 {1} 中注册包管理器密钥“{0}”。当前注册: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        无法加载依赖项管理器扩展 {0}。消息: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
index ce66cb1b949..713c545b21e 100644
--- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
@@ -2,14 +2,374 @@
 
   
     
-      
-        {0} for F# {1}
-        F # {1} 的 {0}
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript
+        
+      
+      
+        Feature '{0}' is not available in F# {1}. Please use language version {2} or greater.
+        F# {1} 中無法使用 '{0}' 功能。請使用語言版本 {2} 或更新的版本。
+        
+      
+      
+        Feature '{0}' is not supported by target runtime.
+        目標執行階段不支援功能 '{0}'。
+        
+      
+      
+        Feature '{0}' requires the F# library for language version {1} or greater.
+        功能 '{0}' 需要語言版本 {1} 或更高的 F# 程式庫。
+        
+      
+      
+        The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'.
+        透過 F# 程式庫使用 ':=' 的方式已淘汰。請參閱 https://aka.ms/fsharp-refcell-ops。舉例來說,請將 'cell := expr' 變更為 'cell.Value <- expr'。
+        
+      
+      
+        The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'.
+        透過 F# 程式庫使用 'decr' 的方式已淘汰。請參閱 https://aka.ms/fsharp-refcell-ops。舉例來說,請將 'decr cell' 變更為 'cell.Value <- cell.Value - 1'。
+        
+      
+      
+        The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'.
+        透過 F# 程式庫使用 '!' 的方式已淘汰。請參閱 https://aka.ms/fsharp-refcell-ops。舉例來說,請將 '!cell' 變更為 'cell.Value'。
+        
+      
+      
+        The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'.
+        透過 F# 程式庫使用 'incr' 的方式已淘汰。請參閱 https://aka.ms/fsharp-refcell-ops。舉例來說,請將 'incr cell' 變更為 'cell.Value <- cell.Value + 1'。
+        
+      
+      
+        The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead.
+        'AssemblyKeyNameAttribute' 已淘汰。請改用 'AssemblyKeyFileAttribute'。
+        
+      
+      
+        Key container signing is not supported on this platform.
+        此平台不支援金鑰容器簽署。
+        
+      
+      
+        Available overloads:\n{0}
+        可用的多載:\n{0}
+        
+      
+      
+        A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation.
+        泛型建構要求泛型型別參數必須指定為結構或參考型別。請考慮新增型別註解。
+        
+      
+      
+        Known types of arguments: {0}
+        已知的引數類型: {0}
+        
+      
+      
+        Known type of argument: {0}
+        已知的引數類型: {0}
+        
+      
+      
+        Known return type: {0}
+        已知的傳回型別: {0}
+        
+      
+      
+        Known type parameters: {0}
+        已知的類型參數: {0}
+        
+      
+      
+        Known type parameter: {0}
+        已知的型別參數: {0}
+        
+      
+      
+        Argument at index {0} doesn't match
+        位於索引 {0} 的引數不相符
+        
+      
+      
+        Argument '{0}' doesn't match
+        引數 '{0}' 不相符
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}' because a dependency was missing or could not loaded. All dependencies of the type provider designer assembly must be located in the same folder as that assembly. The exception reported was: {2} - {3}
+        因為缺少相依性或相依性無法載入,導致無法從資料夾 '{1}' 載入類型提供者設計工具組件 '{0}'。類型提供者設計工具組件的所有相依性都必須位於該組件所在的資料夾內。回報的例外狀況: {2} - {3}
+        
+      
+      
+        The type provider designer assembly '{0}' could not be loaded from folder '{1}'. The exception reported was: {2} - {3}
+        無法從資料夾 '{1}' 載入類型提供者設計工具組件 '{0}'。回報的例外狀況: {2} - {3}
+        
+      
+      
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. The exception reported was: {2} - {3}
+        無法載入組件屬性 '{0}' 參考的設計工具組件 '{1}' 或其不存在。回報的例外狀況: {2} - {3}
+        
+      
+      
+        additional type-directed conversions
+        其他類型導向轉換
+        
+      
+      
+        applicative computation expressions
+        適用的計算運算式
+        
+      
+      
+        attributes to the right of the 'module' keyword
+        'module' 關鍵字右邊的屬性
+        
+      
+      
+        default interface member consumption
+        預設介面成員使用
+        
+      
+      
+        discard pattern in use binding
+        捨棄使用繫結中的模式
+        
+      
+      
+        dotless float32 literal
+        無點號的 float32 常值
+        
+      
+      
+        more types support units of measure
+        更多支援測量單位的類型
+        
+      
+      
+        fixed-index slice 3d/4d
+        固定索引切割 3d/4d
+        
+      
+      
+        from-end slicing
+        從尾端切割
+        
+      
+      
+        implicit yield
+        隱含 yield
+        
+      
+      
+        expr[idx] notation for indexing and slicing
+        用於編製索引和分割的 expr[idx] 註釋
+        
+      
+      
+        interfaces with multiple generic instantiation
+        具有多個泛型具現化的介面
+        
+      
+      
+        ML compatibility revisions
+        ML compatibility revisions
+        
+      
+      
+        nameof
+        nameof
+        
+      
+      
+        non-variable patterns to the right of 'as' patterns
+        'as' 模式右邊的非變數模式
+        
+      
+      
+        nullable optional interop
+        可為 Null 的選擇性 Interop
+        
+      
+      
+        open type declaration
+        開放式類型宣告
+        
+      
+      
+        overloads for custom operations
+        為自訂作業多載
+        
+      
+      
+        package management
+        套件管理
+        
+      
+      
+        binary formatting for integers
+        整數的二進位格式化
+        
+      
+      
+        informational messages related to reference cells
+        與參考儲存格相關的資訊訊息
+        
+      
+      
+        whitespace relexation
+        空白字元放寬
+        
+      
+      
+        whitespace relaxation v2
+        空格鍵放鬆 v2
+        
+      
+      
+        resumable state machines
+        可繼續的狀態機器
+        
+      
+      
+        single underscore pattern
+        單一底線模式
+        
+      
+      
+        string interpolation
+        字串內插補點
+        
+      
+      
+        struct representation for active patterns
+        現用模式的結構表示法
+        
+      
+      
+        wild card in for loop
+        for 迴圈中的萬用字元
+        
+      
+      
+        witness passing for trait constraints in F# quotations
+        見證 F# 引號中特徵條件約束的傳遞
+        
+      
+      
+        Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'.
+        除非每個插補字串都有一個運算式,否則不可使用 '%' 格式指定名稱,例如 '%d{{1+1}}'。
+        
+      
+      
+        .NET-style format specifiers such as '{{x,3}}' or '{{x:N5}}' may not be mixed with '%' format specifiers.
+        .NET 樣式格式指定名稱 (如 '{{x,3}}' 或 '{{x:N5}}') 不可與 '%' 格式指定名稱混用。
+        
+      
+      
+        The '%P' specifier may not be used explicitly.
+        '%P' 指定名稱不可明確地使用。
+        
+      
+      
+        Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{{expr}}', '{{expr,3}}' or '{{expr:N5}}' may be used.
+        用作類型 IFormattable 或類型 FormattableString 的插補字串不能使用 '%' 指定名稱,只能使用 .NET 樣式的插補值,例如 '{{expr}}'、'{{expr,3}}' 或 '{{expr:N5}}'。
+        
+      
+      
+         - {0}
+         - {0}
         
       
       
         From the end slicing with requires language version 5.0, use /langversion:preview.
-        From the end slicing with requires language version 5.0, use /langversion:preview.
+        從結尾處切割需要語言版本 5.0,請使用 /langversion:preview。
+        
+      
+      
+        Invalid directive '#{0} {1}'
+        無效的指示詞 '#{0} {1}'
+        
+      
+      
+        The resumable code construct '{0}' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code.
+        可繼續的程式碼構造 '{0}' 只能用於 'if __useResumableCode then ...' 所保護的內嵌程式碼中,且整體組合必須形成有效的可繼續程式碼。
+        
+      
+      
+        The 'InlineIfLambda' attribute is present in the signature but not the implementation.
+        'InlineIfLambda' 屬性存在於簽章中,但不存在於實作中。
+        
+      
+      
+        Keyword to specify a constant literal as a type parameter argument in Type Providers.
+        用於在型別提供者中,將常數常值指定為型別參數引數的關鍵字。
+        
+      
+      
+        a byte string may not be interpolated
+        位元組字串不能是插補字串
+        
+      
+      
+        IF-FSHARP/IF-CAML regions are no longer supported
+        IF-FSHARP/IF-CAML regions are no longer supported
+        
+      
+      
+        A '}}' character must be escaped (by doubling) in an interpolated string.
+        在插補字串中,必須將 '}}' 字元逸出 (重複一次)。
+        
+      
+      
+        Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.
+        插補字串無效。單引號或逐字字串常值不能用於單引號或逐字字串的插補運算式中。請考慮為內插補點運算式使用明確的 'let' 繫結,或使用三引號字串作為外部字串常值。
+        
+      
+      
+        Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.
+        插補字串無效。三引號字串常值不可用於插補運算式。請考慮為內插補點運算式使用明確的 'let' 繫結。
+        
+      
+      
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        This construct is deprecated. {0}. You can enable this feature by using '--langversion:5.0' and '--mlcompatibility'.
+        
+      
+      
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        In previous versions of F# '{0}' was a reserved keyword but the use of this keyword is now deprecated
+        
+      
+      
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        The use of '#light \"off\"' or '#indent \"off\"' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        The use of multiple parenthesized type parameters before a generic type name such as '(int, int) Map' was deprecated in F# 2.0 and is no longer supported
+        
+      
+      
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M: sig ... end ' was deprecated in F# 2.0 and is no longer supported. Change the ':' to an '=' and remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        The use of 'module M = sig ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'sig' and 'end' and use indentation instead
+        
+      
+      
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
+        The use of 'module M = struct ... end ' was deprecated in F# 2.0 and is no longer supported. Remove the 'struct' and 'end' and use indentation instead
         
       
       
@@ -22,6 +382,26 @@
         從位移 {0} 開始的資源標頭格式錯誤。
         
       
+      
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?
+        此運算式並非函式,因而無法套用。您要用 'expr[index]' 存取索引子嗎?
+        
+      
+      
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}[index]'?
+        此值並非函式,因而無法套用。您要用 '{0}[index]' 存取索引子嗎?
+        
+      
+      
+        The value '{0}' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only.
+        值 '{0}' 已標示為 'InlineIfLambda',但並未判定為 Lambda 值。此警告僅供參考。
+        
+      
+      
+        Print the inferred interfaces of all compilation files to associated signature files
+        將所有編譯檔案的推斷介面列印至相關聯的簽章檔案
+        
+      
       
         Display the allowed values for language version, specify language version such as 'latest' or 'preview'
         顯示語言版本允許的值,指定 'latest' 或 'preview' 等語言版本
@@ -37,9 +417,49 @@
         對 --langversion 為無法識別的值 '{0}',對完整清單使用 --langversion:?
         
       
+      
+        Display compiler version banner and exit
+        顯示編譯器版本橫幅並結束
+        
+      
+      
+        Specify a Win32 icon file (.ico)
+        指定 Win32 圖示檔 (.ico)
+        
+      
       
         The package management feature requires language version 5.0 use /langversion:preview
-        The package management feature requires language version 5.0 use /langversion:preview
+        套件管理功能需要語言版本 5.0,請使用 /langversion:preview
+        
+      
+      
+        Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.
+        插補字串無效。此插補字串運算式填滿為空白,必須有運算式。
+        
+      
+      
+        Incomplete interpolated string begun at or before here
+        未完成的插補字串於此處或之前開始
+        
+      
+      
+        Incomplete interpolated string expression fill begun at or before here
+        未完成的插補字串運算式填滿於此處或之前開始
+        
+      
+      
+        Incomplete interpolated triple-quote string begun at or before here
+        未完成的插補三引號字串於此處或之前開始
+        
+      
+      
+        Incomplete interpolated verbatim string begun at or before here
+        未完成的插補逐字字串於此處或之前開始
+        
+      
+      
+        Unexpected token in type definition. Expected '=' after the type '{0}'.
+        型別定義中出現非預期的權杖。類型 '{0}' 之後應該要有 '='。
         
       
       
@@ -57,19 +477,109 @@
         不支援演算法 '{0}'
         
       
+      
+        A target label for __resumeAt was not statically determined. A __resumeAt with a non-static target label may only appear at the start of a resumable code method
+        未以靜態方式判斷 __resumeAt 的目標標籤。具有非靜態目標標籤的 __resumeAt 只能出現在可繼續程式碼方法的開頭
+        
+      
+      
+        A fast integer for loop may not contain resumption points
+        迴圈的快速整數可能不包含復原點
+        
+      
+      
+        A 'let rec' occured in the resumable code specification
+        可繼續的程式碼規格中發生 'let rec'
+        
+      
+      
+        The 'with' block of a try/with may not contain resumption points
+        try/with 的 'with' 區塊可能不包含復原點
+        
+      
+      
+        A try/finally may not contain resumption points
+        try/finally 可能不包含復原點
+        
+      
+      
+        A delegate or function producing resumable code in a state machine has type parameters
+        狀態機器中產生可繼續程式碼的委派或函式具有類型參數
+        
+      
+      
+        A resumable code invocation at '{0}' could not be reduced
+        無法減少在 '{0}' 的可繼續程式碼引動過程
+        
+      
+      
+        The resumable code value(s) '{0}' does not have a definition
+        可繼續的程式碼值 '{0}' 沒有定義
+        
+      
+      
+        #i is not supported by the registered PackageManagers
+        註冊的 PackageManagers 不支援 #i
+        
+      
+      
+        The state machine has an unexpected form
+        狀態機器有未預期的表單
+        
+      
+      
+        This state machine is not statically compilable. {0}. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
+        此狀態電腦並非靜態可編譯。{0}。將會使用替代的動態實作,其速度可能會較慢。請考慮調整您的程式碼,以確保此狀態電腦為靜態可編譯,否則請隱藏此警告。
+        
+      
+      
+        This state machine is not statically compilable and no alternative is available. {0}. Use an 'if __useResumableCode then <state-machine> else <alternative>' to give an alternative.
+        此狀態機器靜並非靜態可編譯,且沒有任何替代方法。{0}。請使用 if __useResumableCode then <state-machine> else <alternative>' 以提供替代項。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'.
+        無法判斷這個指令碼的 .NET SDK。如果指令碼位於使用 'global.json' 的目錄中,請確認已安裝相關的 .NET SDK。目錄 '{1}' 中 '{0} --version' 的輸出為: '{2}',結束代碼為 '{3}'。
+        
+      
+      
+        The .NET SDK for this script could not be determined. dotnet.exe could not be found ensure a .NET SDK is installed.
+        無法判斷此指令碼的 .NET SDK。找不到 dotnet.exe,請確保已安裝 .NET SDK。
+        
+      
+      
+        The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. Unexpected error '{0}'.
+        無法判斷這個指令碼的 .NET SDK。如果指令碼位於使用 'global.json' 的目錄中,請確認已安裝相關的 .NET SDK。未預期的錯誤 '{0}'。
+        
+      
+      
+        This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2}
+        此運算式的類型為 '{0}',僅可透過不明確的隱含轉換使其與類型 '{1}' 相容。請考慮使用明確呼叫 'op_Implicit'。適用的隱含轉換為: {2}
+        
+      
+      
+        This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature.
+        此版本的 F# 不支援此功能。您可能需要新增 /langversion:preview 才能使用此功能。
+        
+      
       
         This is the wrong anonymous record. It should have the fields {0}.
-        This is the wrong anonymous record. It should have the fields {0}.
+        此為錯誤的匿名記錄。其應有欄位 {0}。
         
       
       
         This anonymous record does not have enough fields. Add the missing fields {0}.
-        This anonymous record does not have enough fields. Add the missing fields {0}.
+        此匿名記錄沒有足夠的欄位。請新增缺少的欄位 {0}。
         
       
       
         This anonymous record has too many fields. Remove the extra fields {0}.
-        This anonymous record has too many fields. Remove the extra fields {0}.
+        此匿名記錄有太多欄位。請移除額外的欄位 {0}。
+        
+      
+      
+        Invalid Anonymous Record type declaration.
+        匿名記錄型別宣告無效。
         
       
       
@@ -77,6 +587,206 @@
         屬性無法套用到類型延伸模組。
         
       
+      
+        The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
+        語法 'expr1[expr2]' 已用於編製索引。請考慮新增類型註釋來啟用編製索引,或是呼叫函式並新增空格,例如 'expr1 [expr2]'。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'.
+        語法 'expr1[expr2]' 現已為編製索引保留。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫函式,請在函式與引數之間新增空格,例如 'someFunction [expr]'。
+        
+      
+      
+        Byref types are not allowed in an open type declaration.
+        開放式類型宣告中不允許 Byref 類型。
+        
+      
+      
+        The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code.
+        語法 'arr.[idx]' 現已修訂為 'arr[idx]'。請更新您的程式碼。
+        
+      
+      
+        This expression uses a built-in implicit conversion to convert type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        此運算式使用內建隱含轉換將類型 '{0}' 轉換為類型 '{1}'。請參閲 https://aka.ms/fsharp-implicit-convs。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'.
+        此運算式使用隱含轉換 '{0}' 將類型 '{1}' 轉換為類型 '{2}'.。
+        
+      
+      
+        This expression uses the implicit conversion '{0}' to convert type '{1}' to type '{2}'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn \"3391\".
+        此運算式使用隱含轉換 '{0}' 將類型 '{1}' 轉換為類型 '{2}'。請參閱 https://aka.ms/fsharp-implicit-convs。可使用 '#nowarn \"3391\" 停用此警告。
+        
+      
+      
+        The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type.
+        'InlineIfLambda' 屬性只能用於類型為函式或 F# 委派類型之方法的內嵌函式參數。
+        
+      
+      
+        Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{{1+1}}'
+        插補字串不相符。除非每個插補字串都有一個運算式,否則不可使用 '%' 格式指定名稱,例如 '%d{{1+1}}'
+        
+      
+      
+        Invalid alignment in interpolated string
+        插補字串中的對齊無效
+        
+      
+      
+        The construct '{0}' may only be used in valid resumable code.
+        建構 '{0}' 只能用於有效的可繼續程式碼。
+        
+      
+      
+        The use of '[<Struct>]' on values, functions and methods is only allowed on partial active pattern definitions
+        只允許在部分現用模式定義上對值、函式和方法使用 '[<Struct>]'
+        
+      
+      
+        use! may not be combined with and!
+        use! 不可與 and! 合併
+        
+      
+      
+        Invalid use of reverse index in list expression.
+        在清單運算式中使用反向索引無效。
+        
+      
+      
+        The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        語法 '[expr1][expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 '(expr1).[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction [expr1] [expr2]'。
+        
+      
+      
+        The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'.
+        語法 '[expr1][expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction [expr1] [expr2]'。
+        
+      
+      
+        A [<Literal>] declaration cannot use an active pattern for its identifier
+        [<Literal>] 宣告不能對其識別碼使用現用模式
+        
+      
+      
+        Cannot assign a value to another value marked literal
+        無法將值指派給標記為常值的其他值
+        
+      
+      
+        Cannot assign '{0}' to a value marked literal
+        無法將 '{0}' 指派給標記為常值的值
+        
+      
+      
+        This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        此運算式支援編製索引,例如 'expr.[index]'。語法 'expr[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。
+        
+      
+      
+        This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation.
+        此值支援編製索引,例如 '{0}.[index]'。語法 '{1}[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。
+        
+      
+      
+        This expression is not a function and does not support index notation.
+        此運算式並非函式,不支援索引標記法。
+        
+      
+      
+        The value '{0}' is not a function and does not support index notation.
+        值 '{0}' 並非函式,不支援索引標記法。
+        
+      
+      
+        The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        語法 'expr1[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 'expr1.[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。
+        
+      
+      
+        The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'.
+        語法 'expr1[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        語法 '(expr1)[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 '(expr1).[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。
+        
+      
+      
+        The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'.
+        語法 '(expr1)[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。
+        
+      
+      
+        The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a '{0}' method or appropriate 'MergeSource' and 'Bind' methods
+        只有在計算運算式產生器定義 '{0}' 方法或正確的 'MergeSource' 和 'Bind' 方法時,才可使用 'let! ... and! ...' 建構
+        
+      
+      
+        Invalid resumable code. A resumable code parameter must be of delegate or function type
+        可繼續的程式碼無效。可繼續的程式碼參數必須是委派或函式類型
+        
+      
+      
+        Invalid resumable code. Resumable code parameter must have name beginning with '__expand'
+        可繼續的程式碼無效。可繼續的程式碼參數的名稱必須以 '__expand' 開頭
+        
+      
+      
+        Invalid resumable code. A 'let rec' occured in the resumable code specification
+        可繼續的程式碼無效。可繼續的程式碼規格中發生 'let rec'
+        
+      
+      
+        Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'
+        可繼續的程式碼無效。接受或傳回可繼續程式碼的任何函式方法都必須標記為「內嵌」
+        
+      
+      
+        Resumable code invocation. Suppress this warning if you are defining new low-level resumable code in terms of existing resumable code.
+        可繼續的程式碼調用。若要以現有可繼續的程式碼定義新的低層級可繼續代碼,請隱藏此警告。
+        
+      
+      
+        Using resumable code or resumable state machines requires /langversion:preview
+        使用可繼續的程式碼或可繼續的狀態機器需要 /langversion:preview
+        
+      
+      
+        This expression implicitly converts type '{0}' to type '{1}'. See https://aka.ms/fsharp-implicit-convs.
+        此運算式將類型 '{0}' 隱含轉換為類型 '{1}'。請參閱 https://aka.ms/fsharp-implicit-convs。
+        
+      
+      
+        Invalid interpolated string. {0}
+        插補字串無效。{0}
+        
+      
+      
+        Interface member '{0}' does not have a most specific implementation.
+        介面成員 '{0}' 沒有最具體的實作。
+        
+      
+      
+        '{0}' cannot implement the interface '{1}' with the two instantiations '{2}' and '{3}' because they may unify.
+        因為 '{2}' 和 '{3}' 兩者的具現化可能整合,所以 '{0}' 無法將其用於實作介面 '{1}'。
+        
+      
+      
+        You cannot implement the interface '{0}' with the two instantiations '{1}' and '{2}' because they may unify.
+        因為 '{1}' 和 '{2}' 兩者的具現化可能整合,所以無法將其用於實作介面 '{0}'。
+        
+      
+      
+        The type '{0}' does not define the field, constructor or member '{1}'.
+        類型 '{0}' 未定義欄位、建構函式或成員 '{1}'。
+        
+      
       
         The namespace '{0}' is not defined.
         未定義命名空間 '{0}'。
@@ -158,13 +868,13 @@
         
       
       
-        All elements of a list must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        清單建構函式運算式的所有分支都必須是同一種類型。此運算式應具備類型 '{0}',但卻為類型 '{1}'。
+        All elements of a list must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        清單建構函式運算式的所有項目都必須可隱含轉換成同一種類型。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
         
       
       
-        All elements of an array must be of the same type as the first element, which here is '{0}'. This element has type '{1}'.
-        陣列建構函式運算式的所有項目都必須是同一種類型。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
+        All elements of an array must be implicitly convertible to the type of the first element, which here is '{0}'. This element has type '{1}'.
+        陣列建構函式運算式的所有項目都必須可隱含轉換成同一種類型。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
         
       
       
@@ -178,13 +888,13 @@
         
       
       
-        All branches of an 'if' expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        if' 運算式的所有分支都必須是同一種類型。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
+        All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        if 運算式的所有分支都傳回可隱含轉換為同一種類型的值。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
         
       
       
-        All branches of a pattern match expression must return values of the same type as the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
-        模式比對運算式的所有分支,都必須傳回相同類型的值。第一個分支傳回了類型 '{0}' 的值,但此分支卻傳回了類型 '{1}' 的值。
+        All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is '{0}'. This branch returns a value of type '{1}'.
+        模式比對運算式的所有分支都傳回可隱含轉換為同一種類型的值。此運算式應具備類型 '{0}',但卻是類型 '{1}'。
         
       
       
@@ -212,11 +922,51 @@
         請考慮使用 'return!',而不使用 'return'。
         
       
+      
+        This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect.
+        F# 編譯器目前不支援此屬性。套用此屬性並不會達到預期的效果。
+        
+      
       
         Use reference assemblies for .NET framework references when available (Enabled by default).
         請在可行的情況下使用適用於 .NET 架構參考的參考組件 (預設會啟用)。
         
       
+      
+        This XML comment is invalid: '{0}'
+        此 XML 註解無效: '{0}'
+        
+      
+      
+        This XML comment is invalid: multiple documentation entries for parameter '{0}'
+        此 XML 註解無效: '{0}' 參數有多項文件輸入
+        
+      
+      
+        This XML comment is invalid: unknown parameter '{0}'
+        此 XML 註解無效: 未知的參數 '{0}'
+        
+      
+      
+        This XML comment is invalid: missing 'cref' attribute for cross-reference
+        此 XML 註解無效: 沒有 'cref' 屬性可用於交互參照
+        
+      
+      
+        This XML comment is incomplete: no documentation for parameter '{0}'
+        此 XML 註解不完整: 參數 '{0}' 沒有文件
+        
+      
+      
+        This XML comment is invalid: missing 'name' attribute for parameter or parameter reference
+        此 XML 註解無效: 參數或參數參考沒有 'name' 屬性
+        
+      
+      
+        This XML comment is invalid: unresolved cross-reference '{0}'
+        此 XML 註解無效: 未解析的交互參照 '{0}'
+        
+      
       
         Consider using 'yield!' instead of 'yield'.
         請考慮使用 'yield!' 而不使用 'yield'。
@@ -242,16 +992,6 @@
         無效的版本檔案 '{0}'
         
       
-      
-        Microsoft (R) F# Compiler version {0}
-        Microsoft (R) F# 編譯器版本 {0}
-        
-      
-      
-        F# Compiler for F# {0}
-        適用於 F# {0} 的 F# 編譯器
-        
-      
       
         Problem with filename '{0}': {1}
         檔名 '{0}' 有問題: {1}
@@ -1018,8 +1758,8 @@
         
       
       
-        A named argument has been assigned more than one value
-        已經為具名引數指派多個值
+        The named argument '{0}' has been assigned more than one value
+        為具名引數 '{0}' 指派了多個值
         
       
       
@@ -1853,13 +2593,8 @@
         
       
       
-        Candidates: {0}
-        候選: {0}
-        
-      
-      
-        The available overloads are shown below.
-        可用的多載顯示如下。
+        Candidates:\n{0}
+        候選:\n{0}
         
       
       
@@ -1984,7 +2719,7 @@
       
       
         The '{0}' visibility attribute is not allowed on module abbreviation. Module abbreviations are always private.
-        模組縮寫不得包含 '{0}' 可視性屬性。模組縮寫一律為私用。
+        模組縮寫不得包含 '{0}' 可見度屬性。模組縮寫一律為私用。
         
       
       
@@ -2089,12 +2824,12 @@
       
       
         Interfaces always have the same visibility as the enclosing type
-        介面一定與封入類型採用相同的可見性
+        介面一定與封入類型採用相同的可見度
         
       
       
         Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type.
-        不允許在這個成員上使用存取範圍修飾詞。抽象位置一定與封入類型採用相同的可見性。
+        不允許在這個成員上使用存取範圍修飾詞。抽象位置一定與封入類型採用相同的可見度。
         
       
       
@@ -2378,8 +3113,8 @@
         
       
       
-        Units-of-measure supported only on float, float32, decimal and signed integer types
-        只有 float、float32、decimal 和有正負號的整數類型支援測量單位
+        Units-of-measure are only supported on float, float32, decimal, and integer types.
+        只有浮點數、float32、十進位和整數類型支援測量單位。
         
       
       
@@ -2403,8 +3138,8 @@
         
       
       
-        MemberKind.PropertyGetSet only expected in parse trees
-        只有剖析樹狀目錄中需要 MemberKind.PropertyGetSet
+        SynMemberKind.PropertyGetSet only expected in parse trees
+        只有剖析樹狀目錄中需要 SynMemberKind.PropertyGetSet
         
       
       
@@ -2419,12 +3154,12 @@
       
       
         Multiple visibility attributes have been specified for this identifier
-        已經為這個識別碼指定多個可見性屬性
+        已經為這個識別碼指定多個可見度屬性
         
       
       
         Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions.
-        已經為這個識別碼指定多個可見性屬性。類別中的 'let' 繫結一定是私用的,就如同運算式內的任何 'let' 繫結一樣。
+        已經為這個識別碼指定多個可見度屬性。類別中的 'let' 繫結一定是私用的,就如同運算式內的任何 'let' 繫結一樣。
         
       
       
@@ -2958,8 +3693,8 @@
         
       
       
-        Invalid indexer expression
-        無效的索引子運算式
+        Incomplete expression or invalid use of indexer syntax
+        運算式不完整,或使用的索引子語法無效
         
       
       
@@ -3558,8 +4293,8 @@
         
       
       
-        Only record fields and simple, non-recursive 'let' bindings may be marked mutable
-        只有記錄欄位及簡單的非遞迴 'let' 繫結可以標記為可變動
+        Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces
+        可變 'let' 繫結不能在遞迴模組或命名空間中遞迴或定義
         
       
       
@@ -3568,8 +4303,8 @@
         
       
       
-        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x : int = 1'
-        若也提供了常數值,宣告就只能是 [<Literal>] 屬性,例如 'val x : int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
+        A declaration may only be the [<Literal>] attribute if a constant value is also given, e.g. 'val x: int = 1'
         
       
       
@@ -5008,8 +5743,8 @@
         
       
       
-        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
-        這不是有效的數值常值。有效的數值常值包括 1、0x1、0b0001 (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger)。
+        This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).
+        這不是有效的數值常值。有效的數值常值包括 1、0x1、0o1、0b1、1l (int)、1u (uint32)、1L (int64)、1UL (uint64)、1s (int16)、1y (sbyte)、1uy (byte)、1.0 (float)、1.0f (float32)、1.0m (decimal)、1I (BigInteger)。
         
       
       
@@ -5728,8 +6463,8 @@
         
       
       
-        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded or doesn't exist. {2}
-        組件屬性 '{0}' 參考的設計工具組件 '{1}' 無法載入或不存在。{2}
+        Assembly attribute '{0}' refers to a designer assembly '{1}' which cannot be loaded from path '{2}'. The exception reported was: {3} - {4}
+        無法從路徑 '{2}' 載入組件屬性 '{0}' 參考的設計工具組件 '{1}'。回報告的例外狀況: {3} - {4}
         
       
       
@@ -5989,7 +6724,7 @@
       
       
         {0} var in collection
-        集合中的 {0} var
+        {0} var in collection
         
       
       
@@ -6998,13 +7733,13 @@
         
       
       
-        This value is not a function and cannot be applied. Did you intend to access the indexer via {0}.[index] instead?
-        此值並非函式,因而無法套用。您要改用 {0}.[index] 來存取索引子嗎?
+        This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'?
+        此值並非函式,因而無法套用。您要用 '{0}.[index]' 存取索引子嗎?
         
       
       
-        This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?
-        此運算式並非函式,因而無法套用。您要改用 expr.[index] 來存取索引子嗎?
+        This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?
+        此運算式並非函式,因而無法套用。您要用 'expr.[index]' 存取索引子嗎?
         
       
       
@@ -7154,7 +7889,7 @@
       
       
         This anonymous record does not exactly match the expected shape. Add the missing fields {0} and remove the extra fields {1}.
-        兩個匿名的記錄類型有兩組不相符的欄位名稱 '{0}' 和 '{1}'
+        此匿名記錄與預期的圖形未完全相符。請新增缺少的欄位 {0},並移除額外的欄位 {1}。
         
       
       
@@ -7249,22 +7984,22 @@
       
       
         Reference an assembly or directory containing a design time tool (Short form: -t)
-        Reference an assembly or directory containing a design time tool (Short form: -t)
+        參考包含設計階段工具的組件或目錄 (簡短形式: -t)
         
       
       
         Package manager key '{0}' was not registered in {1}. Currently registered: {2}
-        Package manager key '{0}' was not registered in {1}. Currently registered: {2}
+        套件管理員金鑰 '{0}' 未在 {1} 中註冊。目前已註冊: {2}
         
       
       
         {0}
-        {0}
+        {0}
         
       
       
         The dependency manager extension {0} could not be loaded. Message: {1}
-        The dependency manager extension {0} could not be loaded. Message: {1}
+        無法載入相依性管理員延伸模組 {0}。訊息: {1}
         
       
     
diff --git a/src/fsharp/xlf/FSStrings.cs.xlf b/src/fsharp/xlf/FSStrings.cs.xlf
index b998717df6e..924659eb22a 100644
--- a/src/fsharp/xlf/FSStrings.cs.xlf
+++ b/src/fsharp/xlf/FSStrings.cs.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Nejméně jedna informační zpráva v načteném souboru\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        symbol ..^
+        
+      
+      
+        interpolated string
+        interpolovaný řetězec
+        
+      
+      
+        interpolated string (first part)
+        interpolovaný řetězec (první část)
+        
+      
+      
+        interpolated string (final part)
+        interpolovaný řetězec (poslední část)
+        
+      
+      
+        interpolated string (part)
+        interpolovaný řetězec (část)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Identifikátory proměnných psané velkými písmeny se ve vzorech obecně nedoporučují. Můžou označovat špatně napsaný název vzoru.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Identifikátory proměnných psané velkými písmeny se ve vzorech obecně nedoporučují. Můžou označovat chybějící otevřenou deklaraci nebo špatně napsaný název vzoru.
         
       
       
@@ -77,11 +102,6 @@
         Rozlišené případy typu union a popisky výjimek musí být identifikátory, které jsou psané velkými písmeny.
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Možné přetížení: {0}. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Tato funkce přebírá příliš mnoho argumentů, nebo se používá v kontextu, ve kterém se funkce neočekává.
@@ -139,7 +159,7 @@
       
       
          A construct with this name was found in FSharp.PowerPack.dll, which contains some modules and types that were implicitly referenced in some previous versions of F#. You may need to add an explicit reference to this DLL in order to compile this code.
-        Konstruktor s tímto názvem se našel v knihovně FSharp.PowerPack.dll, která obsahuje určité moduly a typy implicitně odkazované v některých dřívějších verzích F#. Abyste tento kód mohli zkompilovat, bude možná potřeba přidat explicitní odkaz na tuto knihovnu DLL.
+         Konstruktor s tímto názvem se našel v knihovně FSharp.PowerPack.dll, která obsahuje určité moduly a typy implicitně odkazované v některých dřívějších verzích F#. Abyste tento kód mohli zkompilovat, bude možná potřeba přidat explicitní odkaz na tuto knihovnu DLL.
         
       
       
@@ -1627,6 +1647,11 @@
         symbol |}
         
       
+      
+        keyword 'and!'
+        klíčové slovo and!
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.de.xlf b/src/fsharp/xlf/FSStrings.de.xlf
index f1ee5ebd68c..9462806409e 100644
--- a/src/fsharp/xlf/FSStrings.de.xlf
+++ b/src/fsharp/xlf/FSStrings.de.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Mindestens eine Informationsmeldung in der geladenen Datei.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        Symbol "..^"
+        
+      
+      
+        interpolated string
+        Interpolierte Zeichenfolge
+        
+      
+      
+        interpolated string (first part)
+        Interpolierte Zeichenfolge (erster Teil)
+        
+      
+      
+        interpolated string (final part)
+        Interpolierte Zeichenfolge (letzter Teil)
+        
+      
+      
+        interpolated string (part)
+        Interpolierte Zeichenfolge (Teil)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Variablenbezeichner in Großbuchstaben sollten im Allgemeinen nicht in Mustern verwendet werden und können ein Hinweis auf einen falsch geschriebenen Musternamen sein.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Variablenbezeichner in Großbuchstaben sollten im Allgemeinen nicht in Mustern verwendet werden und können ein Hinweis auf eine fehlende open-Deklaration oder einen falsch geschriebenen Musternamen sein.
         
       
       
@@ -77,11 +102,6 @@
         Diskriminierte Union-Fälle und Ausnahmebezeichnungen müssen Bezeichner in Großbuchstaben sein.
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Mögliche Überladung: "{0}". {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Diese Funktion akzeptiert zu viele Argumente oder wird in einem Kontext verwendet, in dem keine Funktion erwartet wird.
@@ -1174,7 +1194,7 @@
       
       
         keyword 
-        Schlüsselwort
+        Schlüsselwort 
         
       
       
@@ -1627,6 +1647,11 @@
         Symbol "|}"
         
       
+      
+        keyword 'and!'
+        Schlüsselwort "and!"
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.es.xlf b/src/fsharp/xlf/FSStrings.es.xlf
index 00665ca3070..b4b8b4531e4 100644
--- a/src/fsharp/xlf/FSStrings.es.xlf
+++ b/src/fsharp/xlf/FSStrings.es.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Uno o más mensajes informativos en el archivo cargado.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        símbolo "..^"
+        
+      
+      
+        interpolated string
+        cadena interpolada
+        
+      
+      
+        interpolated string (first part)
+        cadena interpolada (primera parte)
+        
+      
+      
+        interpolated string (final part)
+        cadena interpolada (parte final)
+        
+      
+      
+        interpolated string (part)
+        cadena interpolada (parte)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        En general, los identificadores de variable en mayúscula no deben usarse en patrones y pueden indicar un nombre de patrón mal escrito.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        En general, los identificadores de variables en mayúscula no deben usarse en patrones y pueden indicar una declaración abierta que falta o un nombre de patrón mal escrito.
         
       
       
@@ -77,11 +102,6 @@
         Las etiquetas de casos de unión discriminada y de excepciones deben ser identificadores en mayúscula.
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Sobrecarga posible: '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Esta función toma demasiados argumentos o se usa en un contexto donde no se espera una función.
@@ -309,7 +329,7 @@
       
       
         symbol '&&'
-        símbolo "& &"
+        símbolo "&&"
         
       
       
@@ -1299,7 +1319,7 @@
       
       
         The result of this equality expression has type '{0}' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. '{1}.{2} <- expression'.
-        El resultado de esta expresión de igualdad tiene el tipo "{0}" y se descarta implícitamente. Considere el uso de "let" para enlazar el resultado a un nombre, por ejemplo, "let result = expression". Si pretende establecer un valor a una propiedad, utilice el  operador "<-"; por ejemplo, "{1}.{2} <- expression".
+        El resultado de esta expresión de igualdad tiene el tipo "{0}" y se descarta implícitamente. Considere el uso de "let" para enlazar el resultado a un nombre, por ejemplo, "let result = expression". Si pretende establecer un valor a una propiedad, utilice el operador "<-"; por ejemplo, "{1}.{2} <- expression".
         
       
       
@@ -1627,6 +1647,11 @@
         símbolo "|}"
         
       
+      
+        keyword 'and!'
+        palabra clave 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.fr.xlf b/src/fsharp/xlf/FSStrings.fr.xlf
index fc0e0f6e756..53e4eb6cff4 100644
--- a/src/fsharp/xlf/FSStrings.fr.xlf
+++ b/src/fsharp/xlf/FSStrings.fr.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Un ou plusieurs messages d’information dans le fichier chargé.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        symbole '..^'
+        
+      
+      
+        interpolated string
+        chaîne interpolée
+        
+      
+      
+        interpolated string (first part)
+        chaîne interpolée (première partie)
+        
+      
+      
+        interpolated string (final part)
+        chaîne interpolée (partie finale)
+        
+      
+      
+        interpolated string (part)
+        chaîne interpolée (partie)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        En règle générale, les identificateurs de variable en majuscules ne doivent pas être utilisés dans les modèles. En outre, ils peuvent indiquer une erreur d'orthographe dans le nom du modèle.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Les identificateurs de variables en majuscules ne doivent généralement pas être utilisés dans les modèles. Ils peuvent indiquer une absence de déclaration open ou un nom de modèle mal orthographié.
         
       
       
@@ -77,11 +102,6 @@
         Les cas d'union discriminés et les étiquettes d'exception doivent être des identificateurs en majuscules
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Surcharge possible : '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Cette fonction accepte trop d'arguments ou est utilisée dans un contexte où aucune fonction n'est attendue
@@ -1627,6 +1647,11 @@
         symbole '|}'
         
       
+      
+        keyword 'and!'
+        mot clé 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.it.xlf b/src/fsharp/xlf/FSStrings.it.xlf
index cd9a47d880a..d8cf6e9c21e 100644
--- a/src/fsharp/xlf/FSStrings.it.xlf
+++ b/src/fsharp/xlf/FSStrings.it.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Uno o più messaggi informativi nel file caricato.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        simbolo '..^'
+        
+      
+      
+        interpolated string
+        stringa interpolata
+        
+      
+      
+        interpolated string (first part)
+        stringa interpolata (prima parte)
+        
+      
+      
+        interpolated string (final part)
+        stringa interpolata (ultima parte)
+        
+      
+      
+        interpolated string (part)
+        stringa interpolata (parte)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        In genere non è consigliabile usare identificatori di variabili in lettere maiuscole nei criteri perché potrebbero indicare un nome di criterio con ortografia errata.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        In genere è consigliabile non usare identificatori di variabili scritti in maiuscolo nei criteri perché potrebbero indicare una dichiarazione OPEN mancante o un nome di criterio con ortografia errata.
         
       
       
@@ -77,11 +102,6 @@
         I case di unione discriminati e le etichette di eccezioni devono essere identificatori in lettere maiuscole
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Possibile overload: '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Questa funzione utilizza troppi argomenti oppure è utilizzata in un contesto in cui non è prevista una funzione
@@ -1627,6 +1647,11 @@
         simbolo '|}'
         
       
+      
+        keyword 'and!'
+        parola chiave 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.ja.xlf b/src/fsharp/xlf/FSStrings.ja.xlf
index 26a7e52ea19..ad32096733b 100644
--- a/src/fsharp/xlf/FSStrings.ja.xlf
+++ b/src/fsharp/xlf/FSStrings.ja.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        読み込まれたファイル内の 1 つ以上の情報メッセージ。\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        シンボル '..^'
+        
+      
+      
+        interpolated string
+        補間された文字列
+        
+      
+      
+        interpolated string (first part)
+        補間された文字列 (最初の部分)
+        
+      
+      
+        interpolated string (final part)
+        補間された文字列 (最後の部分)
+        
+      
+      
+        interpolated string (part)
+        補間された文字列 (部分)
         
       
       
@@ -54,7 +79,7 @@
       
       
         Type constraint mismatch when applying the default type '{0}' for a type inference variable. 
-        既定の型 '{0}' を型推論の変数に適用するときに、型の制約が一致しませんでした。
+        既定の型 '{0}' を型推論の変数に適用するときに、型の制約が一致しませんでした。 
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        通常、大文字の変数識別子はパターンに使用しません。また、つづりが間違っているパターン名を示す可能性があります。
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        通常、大文字の変数識別子はパターンに使用できません。また、欠落している open 宣言か、つづりが間違っているパターン名を示す可能性があります。
         
       
       
@@ -77,11 +102,6 @@
         判別された共用体ケースと例外のラベルは、大文字の識別子にする必要があります
         
       
-      
-        Possible overload: '{0}'. {1}.
-        使用できるオーバーロードは '{0}' です。{1}。
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         この関数の引数が多すぎるか、関数を使用できない場所で関数が使用されています
@@ -994,7 +1014,7 @@
       
       
         Unexpected end of input
-        予期しない入力の終わりです:
+        予期しない入力の終わりです
         
       
       
@@ -1174,7 +1194,7 @@
       
       
         keyword 
-        キーワード
+        キーワード 
         
       
       
@@ -1627,6 +1647,11 @@
         シンボル '|}'
         
       
+      
+        keyword 'and!'
+        キーワード 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.ko.xlf b/src/fsharp/xlf/FSStrings.ko.xlf
index d6921f25eb3..8e112d8d28c 100644
--- a/src/fsharp/xlf/FSStrings.ko.xlf
+++ b/src/fsharp/xlf/FSStrings.ko.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        로드된 파일에 하나 이상의 정보 메시지가 있습니다.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        기호 '..^'
+        
+      
+      
+        interpolated string
+        보간 문자열
+        
+      
+      
+        interpolated string (first part)
+        보간 문자열(첫 번째 부분)
+        
+      
+      
+        interpolated string (final part)
+        보간 문자열(마지막 부분)
+        
+      
+      
+        interpolated string (part)
+        보간 문자열(부분)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        일반적으로 대문자 변수 식별자는 패턴에 사용하지 말아야 합니다. 이러한 식별자는 철자가 잘못된 패턴 이름을 나타낼 수 있습니다.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        일반적으로 대문자 변수 식별자는 패턴에 사용하지 말아야 합니다. 이러한 식별자는 열려 있는 선언이 없거나 철자가 잘못된 패턴 이름을 나타낼 수 있습니다.
         
       
       
@@ -77,11 +102,6 @@
         구분된 공용 구조체 케이스 및 예외 레이블은 대문자로 된 식별자여야 합니다.
         
       
-      
-        Possible overload: '{0}'. {1}.
-        가능한 오버로드: '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         이 함수는 너무 많은 인수를 사용하거나 함수가 필요하지 않은 컨텍스트에서 사용되었습니다.
@@ -1627,6 +1647,11 @@
         기호 '|}'
         
       
+      
+        keyword 'and!'
+        키워드 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.pl.xlf b/src/fsharp/xlf/FSStrings.pl.xlf
index 1bb0d77df7b..fe6c8536f87 100644
--- a/src/fsharp/xlf/FSStrings.pl.xlf
+++ b/src/fsharp/xlf/FSStrings.pl.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Jeden lub więcej komunikatów informacyjnych w załadowanym pliku.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        symbol „..^”
+        
+      
+      
+        interpolated string
+        ciąg interpolowany
+        
+      
+      
+        interpolated string (first part)
+        ciąg interpolowany (pierwsza część)
+        
+      
+      
+        interpolated string (final part)
+        ciąg interpolowany (końcowa część)
+        
+      
+      
+        interpolated string (part)
+        ciąg interpolowany (część)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Identyfikatory zmiennych pisane wielkimi literami nie powinny być używane we wzorcach i mogą oznaczać nazwę wzorca z błędami pisowni.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Identyfikatory zmiennych pisane wielkimi literami nie powinny być na ogół używane we wzorcach i mogą oznaczać brak deklaracji otwierającej lub błąd pisowni w nazwie wzorca.
         
       
       
@@ -77,11 +102,6 @@
         Rozróżniane przypadki unii i etykiety wyjątków muszą mieć postać identyfikatorów pisanych wielkimi literami
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Możliwe przeciążenie: „{0}”. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Ta funkcja akceptuje za dużo argumentów lub jest używana w kontekście, w którym funkcja nie jest oczekiwana
@@ -1627,6 +1647,11 @@
         symbol „|}”
         
       
+      
+        keyword 'and!'
+        słowo kluczowe „and!”
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.pt-BR.xlf b/src/fsharp/xlf/FSStrings.pt-BR.xlf
index 180bd4449df..8dc8c546ffc 100644
--- a/src/fsharp/xlf/FSStrings.pt-BR.xlf
+++ b/src/fsharp/xlf/FSStrings.pt-BR.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Uma ou mais mensagens informativas no arquivo carregado.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        símbolo '..^'
+        
+      
+      
+        interpolated string
+        cadeia de caracteres interpolada
+        
+      
+      
+        interpolated string (first part)
+        cadeia de caracteres interpolada (primeira parte)
+        
+      
+      
+        interpolated string (final part)
+        cadeia de caracteres interpolada (parte final)
+        
+      
+      
+        interpolated string (part)
+        cadeia de caracteres interpolada (parte)
         
       
       
@@ -54,7 +79,7 @@
       
       
         Type constraint mismatch when applying the default type '{0}' for a type inference variable. 
-        Restrições de tipo incompatíveis ao aplicar o tipo padrão '{0}' para uma variável de inferência de tipo.
+        Restrições de tipo incompatíveis ao aplicar o tipo padrão '{0}' para uma variável de inferência de tipo. 
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Identificadores de variáveis maiúsculas geralmente não devem ser usados nos padrões, podendo indicar um nome de padrão escrito incorretamente.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Identificadores de variáveis em maiúsculas geralmente não devem ser usados em padrões, podendo indicar uma declaração aberta ausente ou um nome de padrão escrito incorretamente.
         
       
       
@@ -77,11 +102,6 @@
         Casos união discriminados e rótulos de exceção devem ser identificadores com maiúsculas
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Sobrecarga possível: '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Esta função obtém muitos argumentos, ou é usada em um contexto onde uma função não é esperada
@@ -364,7 +384,7 @@
       
       
         type application 
-        aplicação de tipo
+        aplicação de tipo 
         
       
       
@@ -1174,12 +1194,12 @@
       
       
         keyword 
-        Palavra-chave
+        Palavra-chave 
         
       
       
         symbol 
-        símbolo
+        símbolo 
         
       
       
@@ -1269,7 +1289,7 @@
       
       
         The use of native pointers may result in unverifiable .NET IL code
-        O uso de ponteiros nativos podem resultar em código .NET IL não verificável 
+        O uso de ponteiros nativos podem resultar em código .NET IL não verificável
         
       
       
@@ -1627,6 +1647,11 @@
         símbolo '|}'
         
       
+      
+        keyword 'and!'
+        palavra-chave 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.ru.xlf b/src/fsharp/xlf/FSStrings.ru.xlf
index 3951b3192b6..6979fe42d9f 100644
--- a/src/fsharp/xlf/FSStrings.ru.xlf
+++ b/src/fsharp/xlf/FSStrings.ru.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Одно или несколько информационных сообщений в загруженном файле.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        символ "..^"
+        
+      
+      
+        interpolated string
+        интерполированная строка
+        
+      
+      
+        interpolated string (first part)
+        интерполированная строка (первая часть)
+        
+      
+      
+        interpolated string (final part)
+        интерполированная строка (последняя часть)
+        
+      
+      
+        interpolated string (part)
+        интерполированная строка (часть)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Идентификаторы переменных в верхнем регистре обычно не должны использоваться в шаблонах, и могут указывать на неправильно написанное имя шаблона.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Идентификаторы переменных в верхнем регистре обычно не должны использоваться в шаблонах, и могут указывать на отсутствующую открытую декларацию или неправильно написанное имя шаблона.
         
       
       
@@ -77,11 +102,6 @@
         Дискриминированные случаи объединения и метки исключений должны являться идентификаторами верхнего регистра
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Возможная перегрузка: "{0}". {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Эта функция принимает слишком много аргументов либо используется в контексте, где функции не допускаются
@@ -364,7 +384,7 @@
       
       
         type application 
-        приложение типа
+        приложение типа 
         
       
       
@@ -1174,7 +1194,7 @@
       
       
         keyword 
-        Ключевое слово
+        Ключевое слово 
         
       
       
@@ -1627,6 +1647,11 @@
         Обозначение '|}'
         
       
+      
+        keyword 'and!'
+        ключевое слово "and!"
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.tr.xlf b/src/fsharp/xlf/FSStrings.tr.xlf
index f2acceada26..54328fdea3f 100644
--- a/src/fsharp/xlf/FSStrings.tr.xlf
+++ b/src/fsharp/xlf/FSStrings.tr.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        Yüklenen dosyada bir veya daha fazla bilgi mesajı.\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        '..^' sembolü
+        
+      
+      
+        interpolated string
+        düz metin arasına kod eklenmiş dize
+        
+      
+      
+        interpolated string (first part)
+        düz metin arasına kod eklenmiş dize (ilk parça)
+        
+      
+      
+        interpolated string (final part)
+        düz metin arasına kod eklenmiş dize (son parça)
+        
+      
+      
+        interpolated string (part)
+        düz metin arasına kod eklenmiş dize (parça)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        Büyük harfli değişken tanımlayıcıları desenlerde genel olarak kullanılmamalıdır, yanlış yazılmış bir desen adının göstergesi olabilirler.
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        Büyük harfli değişken tanımlayıcıları desenlerde genel olarak kullanılmamalıdır. Bunlar, eksik bir açık bildirimin veya yanlış yazılmış bir desen adının göstergesi olabilirler.
         
       
       
@@ -77,11 +102,6 @@
         Ayırt edici birleşim durumları ve özel durum etiketleri büyük harfli tanımlayıcılar olmalıdır
         
       
-      
-        Possible overload: '{0}'. {1}.
-        Olası aşırı yükleme: '{0}'. {1}.
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         Bu işlev çok fazla bağımsız değişken alıyor veya bir işlev beklenmeyen bağlamda kullanılıyor
@@ -139,7 +159,7 @@
       
       
          A construct with this name was found in FSharp.PowerPack.dll, which contains some modules and types that were implicitly referenced in some previous versions of F#. You may need to add an explicit reference to this DLL in order to compile this code.
-        Bu adlı bir yapı, F# dilinin önceki bazı sürümlerinde örtük olarak başvurulan bazı modül ve türleri içeren FSharp.PowerPack.dll dosyasında bulundu. Bu kodu derleyebilmek için bu DLL'ye açık başvuru eklemeniz gerekebilir.
+         Bu adlı bir yapı, F# dilinin önceki bazı sürümlerinde örtük olarak başvurulan bazı modül ve türleri içeren FSharp.PowerPack.dll dosyasında bulundu. Bu kodu derleyebilmek için bu DLL'ye açık başvuru eklemeniz gerekebilir.
         
       
       
@@ -364,7 +384,7 @@
       
       
         type application 
-        tür uygulaması
+        tür uygulaması 
         
       
       
@@ -1174,12 +1194,12 @@
       
       
         keyword 
-        anahtar sözcük
+        anahtar sözcük 
         
       
       
         symbol 
-        simge
+        simge 
         
       
       
@@ -1627,6 +1647,11 @@
         sembol '|}'
         
       
+      
+        keyword 'and!'
+        'and!' anahtar sözcüğü
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.zh-Hans.xlf b/src/fsharp/xlf/FSStrings.zh-Hans.xlf
index ab04ab42601..95130a6391f 100644
--- a/src/fsharp/xlf/FSStrings.zh-Hans.xlf
+++ b/src/fsharp/xlf/FSStrings.zh-Hans.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        加载文件 .\n 中有一条或多条信息性消息
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        符号 "..^"
+        
+      
+      
+        interpolated string
+        内插字符串
+        
+      
+      
+        interpolated string (first part)
+        内插字符串(第一部分)
+        
+      
+      
+        interpolated string (final part)
+        内插字符串(最终部分)
+        
+      
+      
+        interpolated string (part)
+        内插字符串(部分)
         
       
       
@@ -54,7 +79,7 @@
       
       
         Type constraint mismatch when applying the default type '{0}' for a type inference variable. 
-        在为类型推理变量应用默认类型“{0}”时,类型约束不匹配。
+        在为类型推理变量应用默认类型“{0}”时,类型约束不匹配。 
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        通常不应在模式中使用大写的变量标识符,这可能标明某个模式名称存在拼写错误。
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        通常不得在模式中使用大写的变量标识符,存在它们可能表示缺少某个开放声明或某个模式名称拼写错误。
         
       
       
@@ -77,11 +102,6 @@
         可区分的联合用例和异常标签必须是大写的标识符
         
       
-      
-        Possible overload: '{0}'. {1}.
-        可能的重载:“{0}”。{1}。
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         此函数采用的参数过多,或者用于不需要函数的上下文中
@@ -304,7 +324,7 @@
       
       
         symbol '&'
-        符号 "& amp;"
+        符号 "&"
         
       
       
@@ -364,7 +384,7 @@
       
       
         type application 
-        类型应用程序
+        类型应用程序 
         
       
       
@@ -1174,7 +1194,7 @@
       
       
         keyword 
-        关键字
+        关键字 
         
       
       
@@ -1627,6 +1647,11 @@
         符号 "|}"
         
       
+      
+        keyword 'and!'
+        关键字 "and!"
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/fsharp/xlf/FSStrings.zh-Hant.xlf b/src/fsharp/xlf/FSStrings.zh-Hant.xlf
index 3fd801411f3..5ff1442b5c3 100644
--- a/src/fsharp/xlf/FSStrings.zh-Hant.xlf
+++ b/src/fsharp/xlf/FSStrings.zh-Hant.xlf
@@ -2,9 +2,34 @@
 
   
     
+      
+        One or more informational messages in loaded file.\n
+        已載入檔案中的一或多個資訊訊息。\n
+        
+      
       
         symbol '..^'
-        symbol '..^'
+        符號 '..^'
+        
+      
+      
+        interpolated string
+        插補字串
+        
+      
+      
+        interpolated string (first part)
+        插補字串 (第一個部分)
+        
+      
+      
+        interpolated string (final part)
+        插補字串 (最後部分)
+        
+      
+      
+        interpolated string (part)
+        插補字串 (部分)
         
       
       
@@ -68,8 +93,8 @@
         
       
       
-        Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
-        模式中通常不應該使用大寫的變數識別項,這可能表示模式名稱拼字錯誤。
+        Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name.
+        通常不應在樣式中使用大寫的變數識別碼。這可能表示缺少公開宣告或樣式名稱拼字錯誤。
         
       
       
@@ -77,11 +102,6 @@
         差別聯集和例外狀況標籤必須是大寫的識別項
         
       
-      
-        Possible overload: '{0}'. {1}.
-        可能的多載: '{0}'。{1}。
-        
-      
       
         This function takes too many arguments, or is used in a context where a function is not expected
         這個函式接受太多引數,或是用在不需要函式的內容中
@@ -1174,7 +1194,7 @@
       
       
         keyword 
-        關鍵字
+        關鍵字 
         
       
       
@@ -1627,6 +1647,11 @@
         符號 '|}'
         
       
+      
+        keyword 'and!'
+        關鍵字 'and!'
+        
+      
     
   
 
\ No newline at end of file
diff --git a/src/ilx/ilxsettings.fs b/src/ilx/ilxsettings.fs
deleted file mode 100644
index 2355a6b1b6e..00000000000
--- a/src/ilx/ilxsettings.fs
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-module internal FSharp.Compiler.AbstractIL.Extensions.ILX.IlxSettings 
-
-open FSharp.Compiler.AbstractIL 
-open FSharp.Compiler.AbstractIL.IL 
-open FSharp.Compiler.AbstractIL.Internal 
-
-type IlxCallImplementation = 
-  | VirtEntriesVirtCode
-
-//++GLOBAL MUTABLE STATE (concurrency-safe because assigned only during F# library compilation)
-let mutable ilxCompilingFSharpCoreLib = false
-
-//++GLOBAL MUTABLE STATE (concurrency-safe because assigned only during F# library compilation)
-let mutable ilxFsharpCoreLibAssemRef = None : ILAssemblyRef option
-
-/// Scope references for FSharp.Core.dll
-let ilxFsharpCoreLibScopeRef () =
-    if ilxCompilingFSharpCoreLib then 
-        ILScopeRef.Local 
-    else 
-        let assemblyRef = 
-            match ilxFsharpCoreLibAssemRef with 
-            | Some o -> o
-            | None -> 
-                 // The exact public key token and version used here don't actually matter, or shouldn't.
-                 // ilxFsharpCoreLibAssemRef is only 'None' for startup code paths such as
-                 // IsSignatureDataVersionAttr, where matching is done by assembly name strings
-                 // rather then versions and tokens.
-                ILAssemblyRef.Create("FSharp.Core", None, 
-                                     Some (PublicKeyToken(Bytes.ofInt32Array [| 0xb0; 0x3f; 0x5f; 0x7f; 0x11; 0xd5; 0x0a; 0x3a |])),
-                                     false, 
-                                     Some (IL.parseILVersion "0.0.0.0"), None)
-        ILScopeRef.Assembly assemblyRef
-
-let ilxNamespace () =  "Microsoft.FSharp.Core"
\ No newline at end of file
diff --git a/src/scripts/scriptlib.fsx b/src/scripts/scriptlib.fsx
index f5f9276c492..1d0d368476a 100644
--- a/src/scripts/scriptlib.fsx
+++ b/src/scripts/scriptlib.fsx
@@ -77,7 +77,6 @@ module Scripting =
         if Directory.Exists output then 
             Directory.Delete(output, true) 
 
-
     let log format = printfn format
 
     type FilePath = string
@@ -104,6 +103,10 @@ module Scripting =
 
             let exePath = path |> processExePath workDir
             let processInfo = new ProcessStartInfo(exePath, arguments)
+            
+            processInfo.EnvironmentVariables.["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
+            processInfo.EnvironmentVariables.["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
+            
             processInfo.CreateNoWindow <- true
             processInfo.UseShellExecute <- false
             processInfo.WorkingDirectory <- workDir
@@ -159,20 +162,20 @@ module Scripting =
 
             match p.ExitCode with
             | 0 -> Success
-            | errCode -> 
+            | errCode ->
                 let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'.\n---- stdout below --- \n%s\n---- stderr below --- \n%s " exePath arguments workDir (out.ToString()) (err.ToString())
                 ErrorLevel (msg, errCode)
 
     type OutPipe (writer: TextWriter) =
         member x.Post (msg:string) = lock writer (fun () -> writer.WriteLine(msg))
         interface System.IDisposable with 
-           member __.Dispose() = writer.Flush()
+           member _.Dispose() = writer.Flush()
 
     let redirectTo (writer: TextWriter) = new OutPipe (writer)
 
     let redirectToLog () = redirectTo System.Console.Out
 
-#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS
+#if !NETCOREAPP
     let defaultPlatform = 
         match Environment.OSVersion.Platform, Environment.Is64BitOperatingSystem with 
         | PlatformID.MacOSX, true -> "osx.10.11-x64"
diff --git a/src/utils/CompilerLocationUtils.fs b/src/utils/CompilerLocationUtils.fs
deleted file mode 100644
index 923ab418436..00000000000
--- a/src/utils/CompilerLocationUtils.fs
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-namespace Internal.Utilities
-
-open System
-open System.Diagnostics
-open System.IO
-open System.Reflection
-open System.Runtime.InteropServices
-open Microsoft.Win32
-open Microsoft.FSharp.Core
-
-#nowarn "44" // ConfigurationSettings is obsolete but the new stuff is horribly complicated. 
-
-module internal FSharpEnvironment =
-
-    /// The F# version reported in the banner
-#if LOCALIZATION_FSBUILD
-    let FSharpBannerVersion = FSBuild.SR.fSharpBannerVersion(FSharp.BuildProperties.fsProductVersion, FSharp.BuildProperties.fsLanguageVersion)
-#else
-#if LOCALIZATION_FSCOMP
-    let FSharpBannerVersion = FSComp.SR.fSharpBannerVersion(FSharp.BuildProperties.fsProductVersion, FSharp.BuildProperties.fsLanguageVersion)
-#else
-    let FSharpBannerVersion = sprintf "%s for F# %s" (FSharp.BuildProperties.fsProductVersion) (FSharp.BuildProperties.fsLanguageVersion)
-#endif
-#endif
-
-    let versionOf<'t> =
-        typeof<'t>.Assembly.GetName().Version.ToString()
-
-    let FSharpCoreLibRunningVersion =
-        try match versionOf with
-            | null -> None
-            | "" -> None
-            | s  -> Some(s)
-        with _ -> None
-
-    // The F# binary format revision number. The first three digits of this form the significant part of the 
-    // format revision number for F# binary signature and optimization metadata. The last digit is not significant.
-    //
-    // WARNING: Do not change this revision number unless you absolutely know what you're doing.
-    let FSharpBinaryMetadataFormatRevision = "2.0.0.0"
-
-#if FX_NO_WIN_REGISTRY
-#else
-    []
-    extern uint32 RegOpenKeyExW(UIntPtr _hKey, string _lpSubKey, uint32 _ulOptions, int _samDesired, UIntPtr & _phkResult);
-
-    []
-    extern uint32 RegQueryValueExW(UIntPtr _hKey, string _lpValueName, uint32 _lpReserved, uint32 & _lpType, IntPtr _lpData, int & _lpchData);
-
-    []
-    extern uint32 RegCloseKey(UIntPtr _hKey)
-#endif
-    module Option = 
-        /// Convert string into Option string where null and String.Empty result in None
-        let ofString s = 
-            if String.IsNullOrEmpty(s) then None
-            else Some(s)
-
-    // MaxPath accounts for the null-terminating character, for example, the maximum path on the D drive is "D:\<256 chars>\0". 
-    // See: ndp\clr\src\BCL\System\IO\Path.cs
-    let maxPath = 260;
-    let maxDataLength = (new System.Text.UTF32Encoding()).GetMaxByteCount(maxPath)
-#if FX_NO_WIN_REGISTRY
-#else
-    let KEY_WOW64_DEFAULT = 0x0000
-    let KEY_WOW64_32KEY = 0x0200
-    let HKEY_LOCAL_MACHINE = UIntPtr(0x80000002u)
-    let KEY_QUERY_VALUE = 0x1
-    let REG_SZ = 1u
-
-    let GetDefaultRegistryStringValueViaDotNet(subKey: string)  =
-        Option.ofString
-            (try
-                downcast Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\"+subKey,null,null)
-             with e->
-#if DEBUG
-                Debug.Assert(false, sprintf "Failed in GetDefaultRegistryStringValueViaDotNet: %s" (e.ToString()))
-#endif
-                null)
-
-    let Get32BitRegistryStringValueViaPInvoke(subKey:string) = 
-        Option.ofString
-            (try 
-                // 64 bit flag is not available <= Win2k
-                let options = 
-                    let hasWow6432Node =
-                        use x = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node")
-                        x <> null
-                    try
-                        match hasWow6432Node with
-                        | true  -> KEY_WOW64_32KEY
-                        | false -> KEY_WOW64_DEFAULT
-                    with
-                    | _ -> KEY_WOW64_DEFAULT
-
-                let mutable hkey = UIntPtr.Zero;
-                let pathResult = Marshal.AllocCoTaskMem(maxDataLength);
-
-                try
-                    let res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,subKey, 0u, KEY_QUERY_VALUE ||| options, & hkey)
-                    if res = 0u then
-                        let mutable uType = REG_SZ;
-                        let mutable cbData = maxDataLength;
-
-                        let res = RegQueryValueExW(hkey, null, 0u, &uType, pathResult, &cbData);
-
-                        if (res = 0u && cbData > 0 && cbData <= maxDataLength) then
-                            Marshal.PtrToStringUni(pathResult, (cbData - 2)/2);
-                        else 
-                            null
-                    else
-                        null
-                finally
-                    if hkey <> UIntPtr.Zero then
-                        RegCloseKey(hkey) |> ignore
-                
-                    if pathResult <> IntPtr.Zero then
-                        Marshal.FreeCoTaskMem(pathResult)
-             with e->
-#if DEBUG
-                Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaPInvoke: %s" (e.ToString()))
-#endif
-                null)
-
-    let is32Bit = IntPtr.Size = 4
-
-    let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e-> false
-
-    let tryRegKey(subKey:string) = 
-
-        //if we are running on mono simply return None
-        // GetDefaultRegistryStringValueViaDotNet will result in an access denied by default, 
-        // and Get32BitRegistryStringValueViaPInvoke will fail due to Advapi32.dll not existing
-        if runningOnMono then None else
-        if is32Bit then
-            let s = GetDefaultRegistryStringValueViaDotNet(subKey)
-            // If we got here AND we're on a 32-bit OS then we can validate that Get32BitRegistryStringValueViaPInvoke(...) works
-            // by comparing against the result from GetDefaultRegistryStringValueViaDotNet(...)
-#if DEBUG
-            let viaPinvoke = Get32BitRegistryStringValueViaPInvoke(subKey)
-            Debug.Assert((s = viaPinvoke), sprintf "32bit path: pi=%A def=%A" viaPinvoke s)
-#endif
-            s
-        else
-            Get32BitRegistryStringValueViaPInvoke(subKey) 
-#endif
-
-    let internal tryCurrentDomain() =
-        let pathFromCurrentDomain =
-            AppDomain.CurrentDomain.BaseDirectory
-        if not(String.IsNullOrEmpty(pathFromCurrentDomain)) then
-            Some pathFromCurrentDomain
-        else
-            None
-
-#if FX_NO_SYSTEM_CONFIGURATION
-    let internal tryAppConfig (_appConfigKey:string) = None
-#else
-    let internal tryAppConfig (_appConfigKey:string) = 
-        let locationFromAppConfig = System.Configuration.ConfigurationSettings.AppSettings.[_appConfigKey]
-#if DEBUG
-        Debug.Print(sprintf "Considering _appConfigKey %s which has value '%s'" _appConfigKey locationFromAppConfig) 
-#endif
-        if String.IsNullOrEmpty(locationFromAppConfig) then 
-            None
-        else
-            let exeAssemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
-            let locationFromAppConfig = locationFromAppConfig.Replace("{exepath}", exeAssemblyFolder)
-#if DEBUG
-            Debug.Print(sprintf "Using path %s" locationFromAppConfig)
-#endif
-            Some locationFromAppConfig
-#endif
-
-    // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running
-    // Used for
-    //     - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts
-    //     - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks, but note a probe location is given)
-    //     - default F# binaries directory in service.fs (REVIEW: check this)
-    //     - default location of fsi.exe in FSharp.VS.FSI.dll (REVIEW: check this)
-    //     - default F# binaries directory in (project system) Project.fs
-    let BinFolderOfDefaultFSharpCompiler(probePoint:string option) =
-        // Check for an app.config setting to redirect the default compiler location
-        // Like fsharp-compiler-location
-        try
-            // FSharp.Compiler support setting an appKey for compiler location. I've never seen this used.
-            let result = tryAppConfig "fsharp-compiler-location"
-            match result with
-            | Some _ ->  result
-            | None ->
-
-            let safeExists f = (try File.Exists(f) with _ -> false)
-
-            // Look in the probePoint if given, e.g. look for a compiler alongside of FSharp.Build.dll
-            match probePoint with 
-            | Some p when safeExists (Path.Combine(p,"FSharp.Core.dll")) -> Some p 
-            | _ ->
-                // We let you set FSHARP_COMPILER_BIN. I've rarely seen this used and its not documented in the install instructions.
-                let result = Environment.GetEnvironmentVariable("FSHARP_COMPILER_BIN")
-                if not (String.IsNullOrEmpty(result)) then
-                    Some result
-                else
-                    // For the prototype compiler, we can just use the current domain
-                    tryCurrentDomain()
-        with e -> None
-
-#if !FX_NO_WIN_REGISTRY
-    // Apply the given function to the registry entry corresponding to the subKey.
-    // The reg key is disposed at the end of the scope.
-    let useKey subKey f =
-        let key = Registry.LocalMachine.OpenSubKey subKey
-        try f key 
-        finally 
-            match key with 
-            | null -> () 
-            | _ -> key.Dispose()
-
-    // Check if the framework version 4.5 or above is installed at the given key entry 
-    let IsNetFx45OrAboveInstalledAt subKey =
-      try
-        useKey subKey (fun regKey ->
-            match regKey with
-            | null -> false
-            | _ -> regKey.GetValue("Release", 0) :?> int |> (fun s -> s >= 0x50000)) // 0x50000 implies 4.5.0
-      with _ -> false
- 
-    // Check if the framework version 4.5 or above is installed
-    let IsNetFx45OrAboveInstalled =
-        IsNetFx45OrAboveInstalledAt @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client" ||
-        IsNetFx45OrAboveInstalledAt @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" ||
-        runningOnMono
-    
-    // Check if the running framework version is 4.5 or above.
-    // Use the presence of v4.5.x in the registry to distinguish between 4.0 and 4.5
-    let IsRunningOnNetFx45OrAbove =
-            let version = new Version(versionOf) 
-            let major = version.Major
-            major > 4 || (major = 4 && IsNetFx45OrAboveInstalled)
-
-#endif
-
-    // Specify the tooling-compatible fragments of a path such as:
-    //     typeproviders/fsharp41/net461/MyProvider.DesignTime.dll
-    //     tools/fsharp41/net461/MyProvider.DesignTime.dll
-    // See https://github.com/Microsoft/visualfsharp/issues/3736
-
-    // Represents the F#-compiler <-> type provider protocol.
-    // When the API or protocol updates, add a new version moniker to the front of the list here.
-    let toolingCompatibleTypeProviderProtocolMonikers() =
-        [ "fsharp41" ]
-
-    // Detect the host tooling context
-    let toolingCompatibleVersions =
-        if typeof.Assembly.GetName().Name = "mscorlib" then
-            [| "net48"; "net472"; "net471";"net47";"net462";"net461"; "net452"; "net451"; "net45"; "netstandard2.0" |]
-        elif typeof.Assembly.GetName().Name = "System.Private.CoreLib" then
-            [| "netcoreapp3.0"; "netstandard2.1"; "netcoreapp2.2"; "netcoreapp2.1"; "netstandard2.0" |]
-        else
-            System.Diagnostics.Debug.Assert(false, "Couldn't determine runtime tooling context, assuming it supports at least .NET Standard 2.0")
-            [| "netstandard2.0" |]
-
-    let toolPaths = [| "tools"; "typeproviders" |]
-
-    let toolingCompatiblePaths() = [
-        for toolPath in toolPaths do
-            for protocol in toolingCompatibleTypeProviderProtocolMonikers() do
-                for netRuntime in toolingCompatibleVersions do
-                    yield Path.Combine(toolPath, protocol, netRuntime)
-        ]
-
-    let rec searchToolPaths path compilerToolPaths =
-        seq {
-            let searchToolPath path =
-                seq {
-                    yield path
-                    for toolPath in toolingCompatiblePaths() do
-                        yield Path.Combine (path, toolPath)
-                }
-
-            for toolPath in compilerToolPaths do
-                yield! searchToolPath toolPath
-
-            match path with
-            | None -> ()
-            | Some path -> yield! searchToolPath path
-        }
-
-    let getTypeProviderAssembly (runTimeAssemblyFileName: string, designTimeAssemblyName: string, compilerToolPaths: string list, raiseError) =
-        // Find and load the designer assembly for the type provider component.
-        // We look in the directories stepping up from the location of the runtime assembly.
-        let loadFromLocation designTimeAssemblyPath =
-            try
-                printfn "Using: %s" designTimeAssemblyPath
-                Some (Assembly.UnsafeLoadFrom designTimeAssemblyPath)
-            with e ->
-                raiseError e
-
-        let rec searchParentDirChain path assemblyName =
-            seq {
-                match path with
-                | None -> ()
-                | Some (p:string) ->
-                    match Path.GetDirectoryName(p) with
-                    | s when s = "" || s = null || Path.GetFileName(p) = "packages" || s = p -> ()
-                    | parentDir -> yield! searchParentDirChain (Some parentDir) assemblyName
-
-                for p in searchToolPaths path compilerToolPaths do
-                    let fileName = Path.Combine (p, assemblyName)
-                    if File.Exists fileName then yield fileName
-            }
-
-        let loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName =
-            let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName
-            let paths = searchParentDirChain (Some runTimeAssemblyPath) designTimeAssemblyName
-            paths
-            |> Seq.iter(function res -> printfn ">>>> %s" res)
-            paths
-            |> Seq.tryHead
-            |> function
-               | Some res -> loadFromLocation res
-               | None ->
-                    // The search failed, just load from the first location and report an error
-                    let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName
-                    loadFromLocation (Path.Combine (runTimeAssemblyPath, designTimeAssemblyName))
-
-        printfn "=============== S T A R T =========================================="
-        if designTimeAssemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then
-            loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName
-        else
-            // Cover the case where the ".dll" extension has been left off and no version etc. has been used in the assembly
-            // string specification.  The Name=FullName comparison is particularly strange, and was there to support
-            // design-time DLLs specified using "x.DesignTIme, Version= ..." long assembly names and GAC loads.
-            // These kind of design-time assembly specifications are no longer used to our knowledge so that comparison is basically legacy
-            // and will always succeed.  
-            let name = AssemblyName (Path.GetFileNameWithoutExtension designTimeAssemblyName)
-            if name.Name.Equals(name.FullName, StringComparison.OrdinalIgnoreCase) then
-                let designTimeFileName = designTimeAssemblyName + ".dll"
-                loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeFileName
-            else
-                // Load from the GAC using Assembly.Load.  This is legacy since type provider design-time components are
-                // never in the GAC these days and  "x.DesignTIme, Version= ..." specifications are never used.
-                try
-                    let name = AssemblyName designTimeAssemblyName
-                    Some (Assembly.Load (name))
-                with e ->
-                    raiseError e
-
-    let getCompilerToolsDesignTimeAssemblyPaths compilerToolPaths = 
-        searchToolPaths None compilerToolPaths
diff --git a/src/utils/TaggedCollections.fs b/src/utils/TaggedCollections.fs
deleted file mode 100644
index 479b8def82b..00000000000
--- a/src/utils/TaggedCollections.fs
+++ /dev/null
@@ -1,1168 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-namespace Internal.Utilities.Collections.Tagged
-
-    #nowarn "51"
-    #nowarn "69" // interface implementations in augmentations
-    #nowarn "60" // override implementations in augmentations
-
-    open Microsoft.FSharp.Core
-    open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
-    open System.Collections.Generic
-
-
-    []
-    []
-    type SetTree<'T> = 
-        | SetEmpty                                          // height = 0   
-        | SetNode of 'T * SetTree<'T> *  SetTree<'T> * int    // height = int 
-#if ONE
-        | SetOne  of 'T                                     // height = 1   
-#endif
-        // OPTIMIZATION: store SetNode(k,SetEmpty,SetEmpty,1) --->  SetOne(k) 
-
-
-    // CONSIDER: SetTree<'T> = SetEmpty | SetNode of 'T  * SetTree<'T> *  SetTree<'T> * int
-    //  with SetOne = SetNode of (x,null,null,1)
-
-    []
-    module SetTree = 
-        let empty = SetEmpty
-
-        let height t = 
-            match t with 
-            | SetEmpty -> 0
-#if ONE
-            | SetOne _ -> 1
-#endif
-            | SetNode (_,_,_,h) -> h
-
-#if CHECKED
-        let rec checkInvariant t =
-            // A good sanity check, loss of balance can hit perf 
-            match t with 
-            | SetEmpty -> true
-            | SetOne _ -> true
-            | SetNode (k,t1,t2,h) ->
-                let h1 = height t1 in
-                let h2 = height t2 in
-                (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant t1 && checkInvariant t2
-#else
-        let inline SetOne(x) = SetNode(x,SetEmpty,SetEmpty,1)
-#endif
-
-        let tolerance = 2
-
-        let mk l hl k r hr = 
-#if ONE
-            if hl = 0 && hr = 0 then SetOne (k)
-            else
-#endif
-              let m = if hl < hr then hr else hl 
-              SetNode(k,l,r,m+1)
-
-        let rebalance t1 k t2 =
-            let t1h = height t1 
-            let t2h = height t2
-            if  t2h > t1h + tolerance then // right is heavier than left 
-                match t2 with 
-                | SetNode(t2k,t2l,t2r,_) -> 
-                    // one of the nodes must have height > height t1 + 1 
-                    let t2lh = height t2l
-                    if t2lh > t1h + 1 then  // balance left: combination 
-                        match t2l with 
-                        | SetNode(t2lk,t2ll,t2lr,_) ->
-                            let l = mk t1 t1h k t2ll (height t2ll)
-                            let r = mk t2lr (height t2lr) t2k t2r (height t2r)
-                            mk l (height l) t2lk r (height r)
-                        | _ -> failwith "rebalance"
-                    else // rotate left 
-                        let l = mk t1 t1h k t2l t2lh
-                        mk l (height l) t2k t2r (height t2r)
-                | _ -> failwith "rebalance"
-            else
-                if  t1h > t2h + tolerance then // left is heavier than right 
-                    match t1 with 
-                    | SetNode(t1k,t1l,t1r,_) -> 
-                        // one of the nodes must have height > height t2 + 1 
-                        let t1rh = height t1r
-                        if t1rh > t2h + 1 then 
-                            // balance right: combination 
-                            match t1r with 
-                            | SetNode(t1rk,t1rl,t1rr,_) ->
-                                let l = mk t1l (height t1l) t1k t1rl (height t1rl)
-                                let r = mk t1rr (height t1rr) k t2 t2h
-                                mk l (height l) t1rk r (height r)
-                            | _ -> failwith "rebalance"
-                        else
-                            let r = mk t1r t1rh k t2 t2h
-                            mk t1l (height t1l) t1k r (height r)
-                    | _ -> failwith "rebalance"
-                else mk t1 t1h k t2 t2h
-
-        let rec add (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetNode (k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then rebalance (add comparer k l) k2 r
-                elif c = 0 then t
-                else            rebalance l k2 (add comparer k r)
-#if ONE
-            | SetOne(k2) -> 
-                // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated 
-                let c = comparer.Compare(k,k2) 
-                if c < 0   then SetNode (k,SetEmpty,t,2)
-                elif c = 0 then t
-                else            SetNode (k,t,SetEmpty,2)                  
-#endif
-            | SetEmpty -> SetOne(k)
-
-        let rec balance comparer t1 k t2 =
-            // Given t1 < k < t2 where t1 and t2 are "balanced",
-            // return a balanced tree for .
-            // Recall: balance means subtrees heights differ by at most "tolerance"
-            match t1,t2 with
-            | SetEmpty,t2  -> add comparer k t2 // drop t1 = empty 
-            | t1,SetEmpty  -> add comparer k t1 // drop t2 = empty 
-#if ONE
-            | SetOne k1,t2 -> add comparer k (add comparer k1 t2)
-            | t1,SetOne k2 -> add comparer k (add comparer k2 t1)
-#endif
-            | SetNode(k1,t11,t12,t1h),SetNode(k2,t21,t22,t2h) ->
-                // Have:  (t11 < k1 < t12) < k < (t21 < k2 < t22)
-                // Either (a) h1,h2 differ by at most 2 - no rebalance needed.
-                //        (b) h1 too small, i.e. h1+2 < h2
-                //        (c) h2 too small, i.e. h2+2 < h1 
-                if   t1h+tolerance < t2h then
-                    // case: b, h1 too small 
-                    // push t1 into low side of t2, may increase height by 1 so rebalance 
-                    rebalance (balance comparer t1 k t21) k2 t22
-                elif t2h+tolerance < t1h then
-                    // case: c, h2 too small 
-                    // push t2 into high side of t1, may increase height by 1 so rebalance 
-                    rebalance t11 k1 (balance comparer t12 k t2)
-                else
-                    // case: a, h1 and h2 meet balance requirement 
-                    mk t1 t1h k t2 t2h
-
-        let rec split (comparer : IComparer<'T>) pivot t =
-            // Given a pivot and a set t
-            // Return { x in t s.t. x < pivot }, pivot in t? , { x in t s.t. x > pivot } 
-            match t with
-            | SetNode(k1,t11,t12,_) ->
-                let c = comparer.Compare(pivot,k1)
-                if   c < 0 then // pivot t1 
-                    let t11_lo,havePivot,t11_hi = split comparer pivot t11
-                    t11_lo,havePivot,balance comparer t11_hi k1 t12
-                elif c = 0 then // pivot is k1 
-                    t11,true,t12
-                else            // pivot t2 
-                    let t12_lo,havePivot,t12_hi = split comparer pivot t12
-                    balance comparer t11 k1 t12_lo,havePivot,t12_hi
-#if ONE
-            | SetOne k1 ->
-                let c = comparer.Compare(k1,pivot)
-                if   c < 0 then t       ,false,SetEmpty // singleton under pivot 
-                elif c = 0 then SetEmpty,true ,SetEmpty // singleton is    pivot 
-                else            SetEmpty,false,t        // singleton over  pivot 
-#endif
-            | SetEmpty  -> 
-                SetEmpty,false,SetEmpty
-        
-        let rec spliceOutSuccessor t = 
-            match t with 
-            | SetEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
-#if ONE
-            | SetOne (k2) -> k2,empty
-#endif
-            | SetNode (k2,l,r,_) ->
-                match l with 
-                | SetEmpty -> k2,r
-                | _ -> let k3,l' = spliceOutSuccessor l in k3,mk l' (height l') k2 r (height r)
-
-        let rec remove (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetEmpty -> t
-#if ONE
-            | SetOne (k2) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c = 0 then empty
-                else            t
-#endif
-            | SetNode (k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then rebalance (remove comparer k l) k2 r
-                elif c = 0 then 
-                  match l,r with 
-                  | SetEmpty,_ -> r
-                  | _,SetEmpty -> l
-                  | _ -> 
-                      let sk,r' = spliceOutSuccessor r 
-                      mk l (height l) sk r' (height r')
-                else rebalance l k2 (remove comparer k r) 
-
-        let rec contains (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetNode(k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then contains comparer k l
-                elif c = 0 then true
-                else contains comparer k r
-#if ONE
-            | SetOne(k2) -> (comparer.Compare(k,k2) = 0)
-#endif
-            | SetEmpty -> false
-
-        let rec iter f t = 
-            match t with 
-            | SetNode(k2,l,r,_) -> iter f l; f k2; iter f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> ()            
-
-        // Fold, left-to-right. 
-        //
-        // NOTE: This differs from the behaviour of Map.fold which folds right-to-left.
-        let rec fold f m x = 
-            match m with 
-            | SetNode(k,l,r,_) -> fold f r (f k (fold f l x))
-#if ONE
-            | SetOne(k) -> f k x
-#endif
-            | SetEmpty -> x                
-
-        let rec forAll f m = 
-            match m with 
-            | SetNode(k2,l,r,_) -> f k2 && forAll f l && forAll f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> true          
-
-        let rec exists f m = 
-            match m with 
-            | SetNode(k2,l,r,_) -> f k2 || exists f l || exists f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> false         
-
-        let isEmpty m = match m with  | SetEmpty -> true | _ -> false
-
-        let subset comparer a b  = forAll (fun x -> contains comparer x b) a
-
-        let rec elementsAux m acc = 
-            match m with 
-            | SetNode(k2,l,r,_) -> k2 :: (elementsAux l (elementsAux r acc))
-#if ONE
-            | SetOne(k2) -> k2 :: acc
-#endif
-            | SetEmpty -> acc                
-
-        let elements a  = elementsAux a []
-
-        let rec filterAux comparer f s acc = 
-            match s with 
-            | SetNode(k,l,r,_) -> 
-                let acc = if f k then add comparer k acc else acc 
-                filterAux comparer f l (filterAux comparer f r acc)
-#if ONE
-            | SetOne(k) -> if f k then add comparer k acc else acc
-#endif
-            | SetEmpty -> acc           
-
-        let filter comparer f s = filterAux comparer f s empty
-
-        let rec diffAux comparer m acc = 
-            match m with 
-            | SetNode(k,l,r,_) -> diffAux comparer l (diffAux comparer r (remove comparer k acc))
-#if ONE
-            | SetOne(k) -> remove comparer k acc
-#endif
-            | SetEmpty -> acc           
-
-        let diff comparer a b = diffAux comparer b a
-
-        let rec countAux s acc = 
-            match s with 
-            | SetNode(_,l,r,_) -> countAux l (countAux r (acc+1))
-#if ONE
-            | SetOne(k) -> acc+1
-#endif
-            | SetEmpty -> acc           
-
-        let count s = countAux s 0
-
-        let rec union comparer t1 t2 =
-            // Perf: tried bruteForce for low heights, but nothing significant 
-            match t1,t2 with               
-            | SetNode(k1,t11,t12,h1),SetNode(k2,t21,t22,h2) -> // (t11 < k < t12) AND (t21 < k2 < t22) 
-                // Divide and Conquer:
-                //   Suppose t1 is largest.
-                //   Split t2 using pivot k1 into lo and hi.
-                //   Union disjoint subproblems and then combine. 
-                if h1 > h2 then
-                  let lo,_,hi = split comparer k1 t2 in
-                  balance comparer (union comparer t11 lo) k1 (union comparer t12 hi)
-                else
-                  let lo,_,hi = split comparer k2 t1 in
-                  balance comparer (union comparer t21 lo) k2 (union comparer t22 hi)
-            | SetEmpty,t -> t
-            | t,SetEmpty -> t
-#if ONE
-            | SetOne k1,t2 -> add comparer k1 t2
-            | t1,SetOne k2 -> add comparer k2 t1
-#endif
-
-        let rec intersectionAux comparer b m acc = 
-            match m with 
-            | SetNode(k,l,r,_) -> 
-                let acc = intersectionAux comparer b r acc 
-                let acc = if contains comparer k b then add comparer k acc else acc 
-                intersectionAux comparer b l acc
-#if ONE
-            | SetOne(k) -> 
-                if contains comparer k b then add comparer k acc else acc
-#endif
-            | SetEmpty -> acc
-
-        let intersection comparer a b = intersectionAux comparer b a empty
-
-        let partition1 comparer f k (acc1,acc2) = 
-            if f k then (add comparer k acc1,acc2) 
-            else (acc1,add comparer k acc2) 
-        
-        let rec partitionAux comparer f s acc = 
-            match s with 
-            | SetNode(k,l,r,_) -> 
-                let acc = partitionAux comparer f r acc 
-                let acc = partition1 comparer f k acc
-                partitionAux comparer f l acc
-#if ONE
-            | SetOne(k) -> partition1 comparer f k acc
-#endif
-            | SetEmpty -> acc           
-
-        let partition comparer f s = partitionAux comparer f s (empty,empty)
-
-        // It's easier to get many less-important algorithms right using this active pattern
-        let (|MatchSetNode|MatchSetEmpty|) s = 
-            match s with 
-            | SetNode(k2,l,r,_) -> MatchSetNode(k2,l,r)
-#if ONE
-            | SetOne(k2) -> MatchSetNode(k2,SetEmpty,SetEmpty)
-#endif
-            | SetEmpty -> MatchSetEmpty
-        
-        let rec nextElemCont (comparer: IComparer<'T>) k s cont = 
-            match s with 
-            | MatchSetNode(k2,l,r) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then nextElemCont comparer k l (function None -> cont(Some(k2)) | res -> res)
-                elif c = 0 then cont(minimumElementOpt r) 
-                else nextElemCont comparer k r cont
-            | MatchSetEmpty -> cont(None)
-
-        and nextElem comparer k s = nextElemCont comparer k s (fun res -> res)
-        
-        and prevElemCont (comparer: IComparer<'T>) k s cont = 
-            match s with 
-            | MatchSetNode(k2,l,r) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c > 0 then prevElemCont comparer k r (function None -> cont(Some(k2)) | res -> res)
-                elif c = 0 then cont(maximumElementOpt r) 
-                else prevElemCont comparer k l cont
-            | MatchSetEmpty -> cont(None)
-
-        and prevElem comparer k s = prevElemCont comparer k s (fun res -> res)
-        
-        and minimumElementAux s n = 
-            match s with 
-            | SetNode(k,l,_,_) -> minimumElementAux l k
-#if ONE
-            | SetOne(k) -> k
-#endif
-            | SetEmpty -> n
-
-        and minimumElementOpt s = 
-            match s with 
-            | SetNode(k,l,_,_) -> Some(minimumElementAux l k)
-#if ONE
-            | SetOne(k) -> Some k
-#endif
-            | SetEmpty -> None
-
-        and maximumElementAux s n = 
-            match s with 
-            | SetNode(k,_,r,_) -> maximumElementAux r k
-#if ONE
-            | SetOne(k) -> k
-#endif
-            | SetEmpty -> n             
-
-        and maximumElementOpt s = 
-            match s with 
-            | SetNode(k,_,r,_) -> Some(maximumElementAux r k)
-#if ONE
-            | SetOne(k) -> Some(k)
-#endif
-            | SetEmpty -> None
-
-        let minimumElement s = 
-            match minimumElementOpt s with 
-            | Some(k) -> k
-            | None -> failwith "minimumElement"            
-
-        let maximumElement s = 
-            match maximumElementOpt s with 
-            | Some(k) -> k
-            | None -> failwith "maximumElement"
-
-
-        //--------------------------------------------------------------------------
-        // Imperative left-to-right iterators.
-        //--------------------------------------------------------------------------
-
-        type SetIterator<'T>(s:SetTree<'T>) = 
-
-            // collapseLHS:
-            // a) Always returns either [] or a list starting with SetOne.
-            // b) The "fringe" of the set stack is unchanged.
-            let rec collapseLHS stack =
-                match stack with
-                | []                       -> []
-                | SetEmpty         :: rest -> collapseLHS rest
-#if ONE
-                | SetOne k         :: rest -> stack
-#else
-                | SetNode(_,SetEmpty,SetEmpty,_) :: _ -> stack
-#endif
-                | SetNode(k,l,r,_) :: rest -> collapseLHS (l :: SetOne k :: r :: rest)
-
-            // invariant: always collapseLHS result 
-            let mutable stack = collapseLHS [s]
-            // true when MoveNext has been called   
-            let mutable started = false 
-
-            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
-            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
-
-            member i.Current =
-                if started then
-                    match stack with
-#if ONE
-                      | SetOne k :: _ -> k
-#else
-                      | SetNode( k,_,_,_) :: _ -> k
-#endif
-                      | []            -> alreadyFinished()
-                      | _             -> failwith "Please report error: Set iterator, unexpected stack for current"
-                else
-                    notStarted()
-
-            member i.MoveNext() = 
-                if started then
-                    match stack with
-#if ONE
-                      | SetOne _ :: rest -> 
-#else
-                      | SetNode _ :: rest -> 
-#endif
-                            stack <- collapseLHS rest;
-                            not stack.IsEmpty
-                      | [] -> false
-                      | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext"
-                else
-                    started <- true;  // The first call to MoveNext "starts" the enumeration.
-                    not stack.IsEmpty
-
-        let toSeq s = 
-            let mutable i = SetIterator s
-            { new IEnumerator<_> with 
-                  member _.Current = i.Current
-              interface System.Collections.IEnumerator with 
-                  member _.Current = box i.Current
-                  member _.MoveNext() = i.MoveNext()
-                  member _.Reset() = i <- SetIterator s
-              interface System.IDisposable with 
-                  member _.Dispose() = () }
-
-        //--------------------------------------------------------------------------
-        // Set comparison.  This can be expensive.
-        //--------------------------------------------------------------------------
-
-        let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
-            match l1,l2 with 
-            | [],[] ->  0
-            | [],_  -> -1
-            | _ ,[] ->  1
-            | (SetEmpty  _ :: t1),(SetEmpty    :: t2) -> compareStacks comparer t1 t2
-#if ONE
-            | (SetOne(n1k) :: t1),(SetOne(n2k) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer t1 t2
-            | (SetOne(n1k) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (empty :: t1) (n2r :: t2)
-            | (SetNode(n1k,(SetEmpty as emp),n1r,_) :: t1),(SetOne(n2k) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2)
-#endif
-            | (SetNode(n1k,SetEmpty,n1r,_) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2)
-#if ONE
-            | (SetOne(n1k) :: t1),_ -> 
-                compareStacks comparer (empty :: SetOne(n1k) :: t1) l2
-#endif
-            | (SetNode(n1k,n1l,n1r,_) :: t1),_ -> 
-                compareStacks comparer (n1l :: SetNode(n1k,empty,n1r,0) :: t1) l2
-#if ONE
-            | _,(SetOne(n2k) :: t2) -> 
-                compareStacks comparer l1 (empty :: SetOne(n2k) :: t2)
-#endif
-            | _,(SetNode(n2k,n2l,n2r,_) :: t2) -> 
-                compareStacks comparer l1 (n2l :: SetNode(n2k,empty,n2r,0) :: t2)
-                
-        let compare comparer s1 s2 = 
-            match s1,s2 with 
-            | SetEmpty,SetEmpty -> 0
-            | SetEmpty,_ -> -1
-            | _,SetEmpty -> 1
-            | _ -> compareStacks comparer [s1] [s2]
-
-        let choose s = minimumElement s
-
-        let toList s = 
-            let rec loop m x = 
-                match m with 
-                | SetNode(k,l,r,_) -> loop l (k :: (loop r x))
-#if ONE
-                | SetOne(k) -> k :: x
-#endif
-                | SetEmpty -> x
-            loop s []            
-
-        let copyToArray s (arr: _[]) i =
-            let mutable j = i 
-            iter (fun x -> arr.[j] <- x; j <- j + 1) s
-
-        let toArray s = 
-            let n = (count s) 
-            let res = Array.zeroCreate n 
-            copyToArray s res 0;
-            res
-
-        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
-            if e.MoveNext() then 
-              mkFromEnumerator comparer (add comparer e.Current acc) e
-            else acc
-          
-        let ofSeq comparer (c : IEnumerable<_>) =
-            use ie = c.GetEnumerator()
-            mkFromEnumerator comparer empty ie 
-
-        let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) empty l    
-
-
-    []
-    []
-    type internal Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T>(comparer: IComparer<'T>, tree: SetTree<'T>) =
-
-        static let refresh (s:Set<_,_>) t =    Set<_,_>(comparer=s.Comparer, tree=t)
-
-        member s.Tree = tree
-        member s.Comparer : IComparer<'T> = comparer
-
-        static member Empty(comparer: 'ComparerTag) : Set<'T,'ComparerTag> =  
-            Set<_,_>(comparer=comparer, tree=SetTree.empty)
-
-
-        member s.Add(x) : Set<'T,'ComparerTag> = refresh s (SetTree.add comparer x tree)
-        member s.Remove(x) : Set<'T,'ComparerTag> = refresh s (SetTree.remove comparer x tree)
-        member s.Count = SetTree.count tree
-        member s.Contains(x) = SetTree.contains comparer  x tree
-        member s.Iterate(x) = SetTree.iter  x tree
-        member s.Fold f x  = SetTree.fold f tree x
-
-#if CHECKED
-        member s.CheckBalanceInvariant = checkInvariant tree // diagnostics...
-#endif
-        member s.IsEmpty  = SetTree.isEmpty tree
-
-        member s.Partition f  : Set<'T,'ComparerTag> *  Set<'T,'ComparerTag> = 
-            match tree with 
-            | SetEmpty -> s,s
-            | _ -> 
-                let t1,t2 = SetTree.partition comparer f tree 
-                refresh s t1, refresh s t2
-
-        member s.Filter f  : Set<'T,'ComparerTag> = 
-            match tree with 
-            | SetEmpty -> s
-            | _ -> SetTree.filter comparer f tree |> refresh s
-
-        member s.Exists f = SetTree.exists f tree
-
-        member s.ForAll f = SetTree.forAll f tree
-
-        static member (-) ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Difference(a,b)
-
-        static member (+)  ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Union(a,b)
-
-        static member Intersection((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) : Set<'T,'ComparerTag>  = 
-            match b.Tree with 
-            | SetEmpty -> b  // A INTER 0 = 0 
-            | _ -> 
-               match a.Tree with 
-               | SetEmpty -> a // 0 INTER B = 0 
-               | _ -> SetTree.intersection a.Comparer  a.Tree b.Tree |> refresh a
-           
-        static member Union(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
-            match b.Tree with 
-            | SetEmpty -> a  // A U 0 = A 
-            | _ -> 
-               match a.Tree with 
-               | SetEmpty -> b  // 0 U B = B 
-               | _ -> SetTree.union a.Comparer  a.Tree b.Tree |> refresh a
-
-        static member Difference(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
-            match a.Tree with 
-            | SetEmpty -> a // 0 - B = 0 
-            | _ -> 
-                match b.Tree with 
-                | SetEmpty -> a // A - 0 = A 
-                | _ -> SetTree.diff a.Comparer  a.Tree b.Tree |> refresh a
-
-        static member Equality(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
-            (SetTree.compare a.Comparer  a.Tree b.Tree = 0)
-
-        static member Compare(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
-            SetTree.compare a.Comparer  a.Tree b.Tree
-
-        member s.Choose = SetTree.choose tree
-
-        member s.MinimumElement = SetTree.minimumElement tree
-
-        member s.MaximumElement = SetTree.maximumElement tree
-
-        member s.IsSubsetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer tree y.Tree 
-
-        member s.IsSupersetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer y.Tree tree
-
-        member s.ToList () = SetTree.toList tree
-
-        member s.ToArray () = SetTree.toArray tree
-
-        override this.Equals(that) = 
-            match that with
-            // Cast to the exact same type as this, otherwise not equal.
-            | :? Set<'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
-            | _ -> false
-
-        interface System.IComparable with
-            // Cast s2 to the exact same type as s1, see 4884.
-            // It is not OK to cast s2 to seq<'T>, since different compares could permute the elements.
-            member s1.CompareTo(s2: obj) = SetTree.compare s1.Comparer s1.Tree ((s2 :?> Set<'T,'ComparerTag>).Tree)
-
-        member this.ComputeHashCode() = 
-                let combineHash x y = (x <<< 1) + y + 631 
-                let mutable res = 0
-                for x in this do
-                    res <- combineHash res (Unchecked.hash x)
-                abs res
-
-        override this.GetHashCode() = this.ComputeHashCode()
-          
-        interface ICollection<'T> with 
-            member s.Add(_) = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Clear() = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Remove(_) = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Contains(x) = SetTree.contains comparer x tree
-            member s.CopyTo(arr,i) = SetTree.copyToArray tree arr i
-            member s.IsReadOnly = true
-            member s.Count = SetTree.count tree  
-
-        interface IEnumerable<'T> with
-            member s.GetEnumerator() = SetTree.toSeq tree
-
-        interface System.Collections.IEnumerable with
-            override s.GetEnumerator() = (SetTree.toSeq tree :> System.Collections.IEnumerator)
-
-        static member Singleton(comparer,x) : Set<'T,'ComparerTag>  = 
-            Set<_,_>.Empty(comparer).Add(x)
-
-        static member Create(comparer : 'ComparerTag,l : seq<'T>) : Set<'T,'ComparerTag> = 
-            Set<_,_>(comparer=comparer, tree=SetTree.ofSeq comparer l)
-
-
-    []
-    []
-    type MapTree<'Key,'T> = 
-        | MapEmpty 
-#if ONE 
-        | MapOne of 'Key * 'T
-#endif
-        | MapNode of 'Key * 'T * MapTree<'Key,'T> *  MapTree<'Key,'T> * int
-
-
-    []
-    module MapTree = 
-
-        let empty = MapEmpty 
-
-        let inline height x  = 
-          match x with 
-          | MapEmpty -> 0
-#if ONE 
-          | MapOne _ -> 1
-#endif
-          | MapNode(_,_,_,_,h) -> h
-
-        let inline isEmpty m = 
-            match m with 
-            | MapEmpty -> true
-            | _ -> false
-
-        let inline mk l k v r = 
-#if ONE 
-            match l,r with 
-            | MapEmpty,MapEmpty -> MapOne(k,v)
-            | _ -> 
-#endif
-                let hl = height l 
-                let hr = height r 
-                let m = if hl < hr then hr else hl 
-                MapNode(k,v,l,r,m+1)
-
-        let rebalance t1 k v t2 =
-            let t1h = height t1
-            let t2h = height t2
-            if t2h > t1h + 2 then // right is heavier than left 
-                match t2 with 
-                | MapNode(t2k,t2v,t2l,t2r,_) -> 
-                   // one of the nodes must have height > height t1 + 1 
-                   if height t2l > t1h + 1 then  // balance left: combination 
-                     match t2l with 
-                     | MapNode(t2lk,t2lv,t2ll,t2lr,_) ->
-                        mk (mk t1 k v t2ll) t2lk t2lv (mk t2lr t2k t2v t2r) 
-                     | _ -> failwith "rebalance"
-                   else // rotate left 
-                     mk (mk t1 k v t2l) t2k t2v t2r
-                | _ -> failwith "rebalance"
-            else
-                if t1h > t2h + 2 then // left is heavier than right 
-                  match t1 with 
-                  | MapNode(t1k,t1v,t1l,t1r,_) -> 
-                    // one of the nodes must have height > height t2 + 1 
-                      if height t1r > t2h + 1 then 
-                      // balance right: combination 
-                        match t1r with 
-                        | MapNode(t1rk,t1rv,t1rl,t1rr,_) ->
-                            mk (mk t1l t1k t1v t1rl) t1rk t1rv (mk t1rr k v t2)
-                        | _ -> failwith "rebalance"
-                      else
-                        mk t1l t1k t1v (mk t1r k v t2)
-                  | _ -> failwith "rebalance"
-                else mk t1 k v t2
-
-        let rec sizeAux acc m = 
-            match m with  
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne _ -> acc + 1
-#endif
-            | MapNode(_,_,l,r,_) -> sizeAux (sizeAux (acc+1) l) r 
-
-#if ONE 
-#else
-        let MapOne(k,v) = MapNode(k,v,MapEmpty,MapEmpty,1)
-#endif
-        
-        let count x = sizeAux 0 x
-
-        let rec add (comparer: IComparer<'T>) k v m = 
-            match m with 
-            | MapEmpty -> MapOne(k,v)
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0   then MapNode (k,v,MapEmpty,m,2)
-                elif c = 0 then MapOne(k,v)
-                else            MapNode (k,v,m,MapEmpty,2)
-#endif
-            | MapNode(k2,v2,l,r,h) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then rebalance (add comparer k v l) k2 v2 r
-                elif c = 0 then MapNode(k,v,l,r,h)
-                else rebalance l k2 v2 (add comparer k v r) 
-
-        let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
-
-        let rec find (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> indexNotFound()
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then v2
-                else indexNotFound()
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then find comparer k l
-                elif c = 0 then v2
-                else find comparer k r
-
-        let rec tryFind (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> None
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then Some v2
-                else None
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then tryFind comparer k l
-                elif c = 0 then Some v2
-                else tryFind comparer k r
-
-        let partition1 (comparer: IComparer<'T>) f k v (acc1,acc2) = 
-            if f k v then (add comparer k v acc1,acc2) else (acc1,add comparer k v acc2) 
-        
-        let rec partitionAux (comparer: IComparer<'T>) f s acc = 
-            match s with 
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne(k,v) -> partition1 comparer f k v acc
-#endif
-            | MapNode(k,v,l,r,_) -> 
-                let acc = partitionAux comparer f r acc 
-                let acc = partition1 comparer f k v acc
-                partitionAux comparer f l acc
-
-        let partition (comparer: IComparer<'T>) f s = partitionAux comparer f s (empty,empty)
-
-        let filter1 (comparer: IComparer<'T>) f k v acc = if f k v then add comparer k v acc else acc 
-
-        let rec filterAux (comparer: IComparer<'T>) f s acc = 
-            match s with 
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne(k,v) -> filter1 comparer f k v acc
-#endif
-            | MapNode(k,v,l,r,_) ->
-                let acc = filterAux comparer f l acc
-                let acc = filter1 comparer f k v acc
-                filterAux comparer f r acc
-
-        let filter (comparer: IComparer<'T>) f s = filterAux comparer f s empty
-
-        let rec spliceOutSuccessor m = 
-            match m with 
-            | MapEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
-#if ONE 
-            | MapOne(k2,v2) -> k2,v2,MapEmpty
-#endif
-            | MapNode(k2,v2,l,r,_) ->
-                match l with 
-                | MapEmpty -> k2,v2,r
-                | _ -> let k3,v3,l' = spliceOutSuccessor l in k3,v3,mk l' k2 v2 r
-
-        let rec remove (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then MapEmpty else m
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then rebalance (remove comparer k l) k2 v2 r
-                elif c = 0 then 
-                  match l,r with 
-                  | MapEmpty,_ -> r
-                  | _,MapEmpty -> l
-                  | _ -> 
-                      let sk,sv,r' = spliceOutSuccessor r 
-                      mk l sk sv r'
-                else rebalance l k2 v2 (remove comparer k r) 
-
-        let rec containsKey (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> false
-#if ONE 
-            | MapOne(k2,v2) -> (comparer.Compare(k,k2) = 0)
-#endif
-            | MapNode(k2,_,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then containsKey comparer k l
-                else (c = 0 || containsKey comparer k r)
-
-        let rec iter f m = 
-            match m with 
-            | MapEmpty -> ()
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> iter f l; f k2 v2; iter f r
-
-        let rec first f m = 
-            match m with 
-            | MapEmpty -> None
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2 
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                match first f l with 
-                | Some _ as res -> res 
-                | None -> 
-                match f k2 v2 with 
-                | Some _ as res -> res 
-                | None -> first f r
-
-        let rec exists f m = 
-            match m with 
-            | MapEmpty -> false
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> f k2 v2 || exists f l || exists f r
-
-        let rec forAll f m = 
-            match m with 
-            | MapEmpty -> true
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> f k2 v2 && forAll f l && forAll f r
-
-        let rec map f m = 
-            match m with 
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k,v) -> MapOne(k,f v)
-#endif
-            | MapNode(k,v,l,r,h) -> let v2 = f v in MapNode(k,v2,map f l, map f r,h)
-
-        let rec mapi f m = 
-            match m with
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k,v) -> MapOne(k,f k v)
-#endif
-            | MapNode(k,v,l,r,h) -> let v2 = f k v in MapNode(k,v2, mapi f l, mapi f r,h)
-
-        // Fold, right-to-left. 
-        //
-        // NOTE: This differs from the behaviour of Set.fold which folds left-to-right.
-        let rec fold f m x = 
-            match m with 
-            | MapEmpty -> x
-#if ONE 
-            | MapOne(k,v) -> f k v x
-#endif
-            | MapNode(k,v,l,r,_) -> fold f l (f k v (fold f r x))
-
-        let foldSection (comparer: IComparer<'T>) lo hi f m x =
-            let rec fold_from_to f m x = 
-                match m with 
-                | MapEmpty -> x
-#if ONE 
-                | MapOne(k,v) ->
-                    let clo_k = comparer.Compare(lo,k)
-                    let ck_hi = comparer.Compare(k,hi)
-                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x else x
-                    x
-#endif
-                | MapNode(k,v,l,r,_) ->
-                    let clo_k = comparer.Compare(lo,k)
-                    let ck_hi = comparer.Compare(k,hi)
-                    let x = if clo_k < 0                then fold_from_to f l x else x
-                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x                     else x
-                    let x = if ck_hi < 0                then fold_from_to f r x else x
-                    x
-           
-            if comparer.Compare(lo,hi) = 1 then x else fold_from_to f m x
-
-        let rec foldMap (comparer: IComparer<'T>) f m z acc = 
-            match m with 
-            | MapEmpty -> acc,z
-#if ONE 
-            | MapOne(k,v) -> 
-                let v',z = f k v z
-                add comparer k v' acc,z
-#endif
-            | MapNode(k,v,l,r,_) -> 
-                let acc,z = foldMap comparer f r z acc
-                let v',z = f k v z
-                let acc = add comparer k v' acc 
-                foldMap comparer f l z acc
-
-        let toList m = fold (fun k v acc -> (k,v) :: acc) m []
-        let toArray m = m |> toList |> Array.ofList
-        let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l
-
-        
-        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
-            if e.MoveNext() then 
-                let (x,y) = e.Current 
-                mkFromEnumerator comparer (add comparer x y acc) e
-            else acc
-          
-        let ofSeq comparer (c : seq<_>) =
-            use ie = c.GetEnumerator()
-            mkFromEnumerator comparer empty ie 
-          
-        let copyToArray s (arr: _[]) i =
-            let mutable j = i 
-            s |> iter (fun x y -> arr.[j] <- KeyValuePair(x,y); j <- j + 1)
-
-
-        /// Imperative left-to-right iterators.
-        type MapIterator<'Key,'T>(s:MapTree<'Key,'T>) = 
-            // collapseLHS:
-            // a) Always returns either [] or a list starting with SetOne.
-            // b) The "fringe" of the set stack is unchanged. 
-            let rec collapseLHS stack =
-                match stack with
-                | []                           -> []
-                | MapEmpty             :: rest -> collapseLHS rest
-#if ONE 
-                | MapOne _         :: _ -> stack
-#else
-                | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: _ -> stack
-#endif
-                | (MapNode(k,v,l,r,_)) :: rest -> collapseLHS (l :: MapOne (k,v) :: r :: rest)
-          
-              /// invariant: always collapseLHS result 
-            let mutable stack = collapseLHS [s]
-               /// true when MoveNext has been called   
-            let mutable started = false
-
-            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
-            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
-
-            member i.Current =
-                if started then
-                    match stack with
-#if ONE
-                      | MapOne (k,v) :: _ -> new KeyValuePair<_,_>(k,v)
-#else
-                      | (MapNode(k,v,MapEmpty,MapEmpty,_)) :: _ -> new KeyValuePair<_,_>(k,v)
-#endif
-                      | []            -> alreadyFinished()
-                      | _             -> failwith "Please report error: Map iterator, unexpected stack for current"
-                else
-                    notStarted()
-
-            member i.MoveNext() =
-              if started then
-                match stack with
-#if ONE
-                  | MapOne _ :: rest -> 
-#else
-                  | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: rest -> 
-#endif
-                      stack <- collapseLHS rest;
-                      not stack.IsEmpty
-                  | [] -> false
-                  | _ -> failwith "Please report error: Map iterator, unexpected stack for moveNext"
-              else
-                  // The first call to MoveNext "starts" the enumeration. 
-                  started <- true;  
-                  not stack.IsEmpty
-
-        let toSeq s = 
-            let mutable i = MapIterator(s)
-            { new IEnumerator<_> with 
-                  member self.Current = i.Current
-              interface System.Collections.IEnumerator with
-                  member self.Current = box i.Current
-                  member self.MoveNext() = i.MoveNext()
-                  member self.Reset() = i <-  MapIterator(s)
-              interface System.IDisposable with 
-                  member self.Dispose() = ()}
-
-
-    []
-    []
-    type internal Map<'Key,'T,'ComparerTag> when 'ComparerTag :> IComparer<'Key>( comparer: IComparer<'Key>, tree: MapTree<'Key,'T>) =
-
-        static let refresh (m:Map<_,_,'ComparerTag>) t = 
-            Map<_,_,'ComparerTag>(comparer=m.Comparer, tree=t)
-
-        member s.Tree = tree
-        member s.Comparer : IComparer<'Key> = comparer
-
-        static member Empty(comparer : 'ComparerTag) = Map<'Key,'T,'ComparerTag>(comparer=comparer, tree=MapTree.empty)
-        member m.Add(k,v) = refresh m (MapTree.add comparer k v tree)
-        member m.IsEmpty = MapTree.isEmpty tree
-        member m.Item with get(k : 'Key) = MapTree.find comparer k tree
-        member m.First(f) = MapTree.first f tree 
-        member m.Exists(f) = MapTree.exists f tree 
-        member m.Filter(f) = MapTree.filter comparer f tree |> refresh m 
-        member m.ForAll(f) = MapTree.forAll f tree 
-        member m.Fold f acc = MapTree.fold f tree acc
-        member m.FoldSection lo hi f acc = MapTree.foldSection comparer lo hi f tree acc 
-        member m.FoldAndMap f z  = 
-            let tree,z = MapTree.foldMap comparer f tree z MapTree.empty 
-            refresh m tree, z
-        member m.Iterate f = MapTree.iter f tree
-        member m.MapRange f  = refresh m (MapTree.map f tree)
-        member m.Map f  = refresh m (MapTree.mapi f tree)
-        member m.Partition(f)  =
-            let r1,r2 = MapTree.partition comparer f tree  
-            refresh m r1, refresh m r2
-        member m.Count = MapTree.count tree
-        member m.ContainsKey(k) = MapTree.containsKey comparer k tree
-        member m.Remove(k)  = refresh m (MapTree.remove comparer k tree)
-        member m.TryFind(k) = MapTree.tryFind comparer k tree
-        member m.ToList() = MapTree.toList tree
-        member m.ToArray() = MapTree.toArray tree
-
-        static member FromList(comparer : 'ComparerTag,l) : Map<'Key,'T,'ComparerTag> = 
-            Map<_,_,_>(comparer=comparer, tree=MapTree.ofList comparer l)
-
-        static member Create(comparer : 'ComparerTag, ie : seq<_>) : Map<'Key,'T,'ComparerTag> = 
-            Map<_,_,_>(comparer=comparer, tree=MapTree.ofSeq comparer ie)
-    
-        interface IEnumerable> with
-            member s.GetEnumerator() = MapTree.toSeq tree
-
-        interface System.Collections.IEnumerable with
-            override s.GetEnumerator() = (MapTree.toSeq tree :> System.Collections.IEnumerator)
-
-        override this.Equals(that) = 
-            match that with
-            // Cast to the exact same type as this, otherwise not equal.
-            | :? Map<'Key,'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
-            | _ -> false
-
-        interface System.IComparable with 
-             member m1.CompareTo(m2: obj) = 
-                 Seq.compareWith 
-                   (fun (kvp1 : KeyValuePair<_,_>) (kvp2 : KeyValuePair<_,_>)-> 
-                       let c = m1.Comparer.Compare(kvp1.Key,kvp2.Key) in 
-                       if c <> 0 then c else Unchecked.compare kvp1.Value kvp2.Value)
-                   // Cast m2 to the exact same type as m1, see 4884.
-                   // It is not OK to cast m2 to seq>, since different compares could permute the KVPs.
-                   m1 (m2 :?> Map<'Key,'T,'ComparerTag>)
-
-        member this.ComputeHashCode() = 
-            let combineHash x y = (x <<< 1) + y + 631 
-            let mutable res = 0
-            for KeyValue(x,y) in this do
-                res <- combineHash res (Unchecked.hash x)
-                res <- combineHash res (Unchecked.hash y)
-            abs res
-
-        override this.GetHashCode() = this.ComputeHashCode()
-
-
-    type internal Map<'Key,'T> = Map<'Key, 'T, IComparer<'Key>>
-    type internal Set<'T> = Set<'T, IComparer<'T>>
diff --git a/src/utils/filename.fs b/src/utils/filename.fs
deleted file mode 100644
index 9dd20134da1..00000000000
--- a/src/utils/filename.fs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-module internal Internal.Utilities.Filename
-
-open System.IO
-open FSharp.Compiler.AbstractIL.Internal.Library 
-
-exception IllegalFileNameChar of string * char
-
-let checkPathForIllegalChars  =
-    let chars = new System.Collections.Generic.HashSet<_>(Path.GetInvalidPathChars())
-    (fun (path:string) -> 
-        for c in path do
-            if chars.Contains c then raise(IllegalFileNameChar(path, c)))
-
-// Case sensitive (original behaviour preserved).
-let checkSuffix (x:string) (y:string) = x.EndsWithOrdinal(y) 
-
-let hasExtensionWithValidate (validate:bool) (s:string) = 
-    if validate then (checkPathForIllegalChars s) |> ignore
-    let sLen = s.Length
-    (sLen >= 1 && s.[sLen - 1] = '.' && s <> ".." && s <> ".") 
-    || Path.HasExtension(s)
-
-let hasExtension (s:string) = hasExtensionWithValidate true s
-
-let chopExtension (s:string) =
-    checkPathForIllegalChars s
-    if s = "." then "" else // for OCaml compatibility
-    if not (hasExtensionWithValidate false s) then 
-        raise (System.ArgumentException("chopExtension")) // message has to be precisely this, for OCaml compatibility, and no argument name can be set
-    Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s))
-
-let directoryName (s:string) = 
-    checkPathForIllegalChars s
-    if s = "" then "."
-    else 
-      match Path.GetDirectoryName(s) with 
-      | null -> if FileSystem.IsPathRootedShim(s) then s else "."
-      | res -> if res = "" then "." else res
-
-let fileNameOfPath s = 
-    checkPathForIllegalChars s
-    Path.GetFileName(s)
-
-let fileNameWithoutExtensionWithValidate (validate:bool) s = 
-    if validate then checkPathForIllegalChars s |> ignore
-    Path.GetFileNameWithoutExtension(s)
-
-let fileNameWithoutExtension s = fileNameWithoutExtensionWithValidate true s
-
-let trimQuotes (s:string) =
-    s.Trim( [|' '; '\"'|] )
diff --git a/src/utils/filename.fsi b/src/utils/filename.fsi
deleted file mode 100644
index 6edc831b4f9..00000000000
--- a/src/utils/filename.fsi
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-/// Some filename operations.    
-module internal Internal.Utilities.Filename
-
-exception IllegalFileNameChar of string * char
-
-/// checkSuffix f s returns True if filename "f" ends in suffix "s",
-/// e.g. checkSuffix "abc.fs" ".fs" returns true.
-val checkSuffix: string -> string -> bool
-
-/// chopExtension f removes the extension from the given
-/// filename. Raises ArgumentException if no extension is present.
-val chopExtension: string -> string
-
-/// "directoryName" " decomposes a filename into a directory name.
-val directoryName: string -> string
-
-/// Return True if the filename has a "." extension.
-val hasExtension: string -> bool
-
-/// Get the filename of the given path.
-val fileNameOfPath: string -> string
-
-/// Get the filename without extension of the given path.
-val fileNameWithoutExtensionWithValidate: bool -> string -> string
-val fileNameWithoutExtension: string -> string
-
-/// Trim the quotes and spaces from either end of a string
-val trimQuotes: string -> string
diff --git a/src/utils/prim-lexing.fsi b/src/utils/prim-lexing.fsi
deleted file mode 100644
index b0579d71e2f..00000000000
--- a/src/utils/prim-lexing.fsi
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-// LexBuffers are for use with automatically generated lexical analyzers,
-// in particular those produced by 'fslex'.
-
-namespace FSharp.Compiler.Text
-
-type ISourceText =
-
-    abstract Item : int -> char with get
-
-    abstract GetLineString : lineIndex: int -> string
-
-    abstract GetLineCount : unit -> int
-
-    abstract GetLastCharacterPosition : unit -> int * int
-
-    abstract GetSubTextString : start: int * length: int -> string
-
-    abstract SubTextEquals : target: string * startIndex: int -> bool
-
-    abstract Length : int
-
-    abstract ContentEquals : sourceText: ISourceText -> bool
-
-    abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit
-
-module SourceText =
-
-    val ofString : string -> ISourceText
-
-//
-// NOTE: the code in this file is a drop-in replacement runtime for Lexing.fsi from the FsLexYacc repository
-// and is referenced by generated code for the three FsLex generated lexers in the F# compiler.
-// The underlying table format interpreted must precisely match the format generated by FsLex.
-namespace Internal.Utilities.Text.Lexing
-
-open System.Collections.Generic
-open FSharp.Compiler.Text
-open Microsoft.FSharp.Core
-open Microsoft.FSharp.Control
-open FSharp.Compiler.Features
-
-/// Position information stored for lexing tokens
-[]
-type internal Position = 
-     /// The file index for the file associated with the input stream, use fileOfFileIndex in range.fs to decode
-     val FileIndex : int
-
-     /// The line number in the input stream, assuming fresh positions have been updated 
-     /// for the new line by modifying the EndPos property of the LexBuffer.
-     val Line : int
-
-     /// The line number for the position in the input stream, assuming fresh positions have been updated 
-     /// using for the new line.
-     val OriginalLine : int
-
-     /// The character number in the input stream.
-     val AbsoluteOffset : int
-
-     /// Return absolute offset of the start of the line marked by the position.
-     val StartOfLineAbsoluteOffset : int
-
-     /// Return the column number marked by the position, 
-     /// i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset
-     member Column : int
-
-     /// Given a position just beyond the end of a line, return a position at the start of the next line.
-     member NextLine : Position     
-     
-     /// Given a position at the start of a token of length n, return a position just beyond the end of the token.
-     member EndOfToken: n:int -> Position
-
-     /// Gives a position shifted by specified number of characters.
-     member ShiftColumnBy: by:int -> Position
-
-     /// Same line, column -1.
-     member ColumnMinusOne : Position
-
-     /// Apply a #line directive.
-     member ApplyLineDirective : fileIdx:int * line:int -> Position
-
-     /// Get an arbitrary position, with the empty string as filename. 
-     static member Empty : Position
-
-     static member FirstLine : fileIdx:int -> Position
-
-[]
-/// Input buffers consumed by lexers generated by fslex.exe.
-/// The type must be generic to match the code generated by FsLex and FsYacc (if you would like to
-/// fix this, please submit a PR to the FsLexYacc repository allowing for optional emit of a non-generic type reference).
-type internal LexBuffer<'Char> =
-    /// The start position for the lexeme.
-    member StartPos: Position with get,set
-
-    /// The end position for the lexeme.
-    member EndPos: Position with get,set
-
-    /// The matched string.
-    member Lexeme: 'Char []
-
-    /// Fast helper to turn the matched characters into a string, avoiding an intermediate array.
-    static member LexemeString : LexBuffer -> string
-
-    /// Dynamically typed, non-lexically scoped parameter table.
-    member BufferLocalStore : IDictionary
-
-    /// True if the refill of the buffer ever failed , or if explicitly set to True.
-    member IsPastEndOfStream: bool with get,set
-
-    /// True if the refill of the buffer ever failed , or if explicitly set to True.
-    member SupportsFeature:LanguageFeature -> bool
-
-    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array.
-    /// Important: does take ownership of the array.
-    static member FromChars: (LanguageFeature -> bool) * char[] -> LexBuffer
-
-    /// Create a lex buffer that reads character or byte inputs by using the given function.
-    static member FromFunction: (LanguageFeature -> bool) * ('Char[] * int * int -> int) -> LexBuffer<'Char>
-
-    /// Create a lex buffer backed by source text.
-    static member FromSourceText : (LanguageFeature -> bool) * ISourceText -> LexBuffer
-
-/// The type of tables for an unicode lexer generated by fslex.exe. 
-[]
-type internal UnicodeTables =
-
-    /// Create the tables from raw data
-    static member Create : uint16[][] * uint16[] -> UnicodeTables
-
-    /// Interpret tables for a unicode lexer generated by fslex.exe. 
-    member Interpret:  initialState:int * LexBuffer -> int
-
diff --git a/src/utils/reshapedmsbuild.fs b/src/utils/reshapedmsbuild.fs
deleted file mode 100644
index 20b5cd6f961..00000000000
--- a/src/utils/reshapedmsbuild.fs
+++ /dev/null
@@ -1,886 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-namespace Microsoft.Build.Tasks
-namespace Microsoft.Build.Utilities
-namespace Microsoft.Build.Framework
-namespace Microsoft.Build.BuildEngine
-
-#if FX_RESHAPED_MSBUILD
-
-namespace Microsoft.Build.Framework
-open System.Collections
-
-type ITaskItem =
-    abstract member ItemSpec : string with get, set
-    abstract member MetadataNames : ICollection with get
-    abstract member MetadataCount : int with get
-
-    abstract member GetMetadata : string -> string
-    abstract member SetMetadata : string*string -> unit
-    abstract member RemoveMetadata : string -> unit
-    abstract member CopyMetadataTo : ITaskItem -> unit
-    abstract member CloneCustomMetadata : IDictionary
-
-module Utilities =
-    open Microsoft.Build.Framework
-    open System
-    open System.Collections
-    open System.Reflection
-
-    type System.Object with
-        member this.GetPropertyValue(propName) = this.GetType().GetProperty(propName, BindingFlags.Public).GetValue(this, null)
-        member this.SetPropertyValue(propName, propValue) = this.GetType().GetProperty(propName, BindingFlags.Public).SetValue(this, propValue, null)
-        member this.GetMethod(methodName, argTypes) = this.GetType().GetMethod(methodName, argTypes, [||])
-
-    type TaskItem (itemSpec:string) =
-        let assembly = Assembly.Load(new AssemblyName("Microsoft.Build.Utilities.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"))
-        let buildUtilitiesTaskType = assembly.GetType("Microsoft.Build.Utilities.Task")
-        let instance = Activator.CreateInstance(buildUtilitiesTaskType, [|itemSpec|])
-
-        interface ITaskItem with
-            member this.ItemSpec
-                with get () :string = (instance.GetPropertyValue("ItemSpec") :?> string)
-                and set (value:string) =  (instance.SetPropertyValue("ItemSpec", value)); ()
-            member this.MetadataNames
-                with get () :ICollection = (instance.GetPropertyValue("MetadataNames") :?> ICollection)
-            member this.MetadataCount
-                with get () :int = (instance.GetPropertyValue("MetadataCount") :?> int)
-            member this.CopyMetadataTo(iTaskItem) =
-                let m = buildUtilitiesTaskType.GetMethod("CopyMetadataTo", [| typeof |])
-                m.Invoke(instance, [|iTaskItem :>obj|]) |> ignore
-            member this.CloneCustomMetadata =
-                let m = buildUtilitiesTaskType.GetMethod("CloneCustomMetadata", [||])
-                (m.Invoke(instance,[||])) :?>IDictionary
-            member this.GetMetadata(metadataName) =
-                let m = buildUtilitiesTaskType.GetMethod("GetMetadata", [|typeof|])
-                (m.Invoke(instance,[|metadataName|])) :?>string
-            member this.RemoveMetadata(metadataName) =
-                let m = buildUtilitiesTaskType.GetMethod("RemoveMetadata", [|typeof|])
-                (m.Invoke(instance,[|metadataName|])) :?>string |>ignore
-            member this.SetMetadata(metadataName, metadataValue) =
-                let m = buildUtilitiesTaskType.GetMethod("SetMetadata", [|typeof;typeof|])
-                (m.Invoke(instance,[|metadataName; metadataValue|])) |>ignore
-
-namespace FSharp.Compiler
-open System
-open System.Collections
-open System.Collections.Concurrent
-open System.IO
-open System.Linq
-open System.Runtime.Versioning
-open FSComp
-open Microsoft.Win32
-open Microsoft.Build.Framework.Utilities
-
-module internal MsBuildAdapters = 
-
-    /// 
-    /// Used to specify the targeted version of the .NET Framework for some methods of ToolLocationHelper.  This is meant to mimic
-    /// the official version here: https://source.dot.net/#q=TargetDotNetFrameworkVersion.
-    /// 
-    type public TargetDotNetFrameworkVersion =
-    | Version11 = 0
-    | Version20 = 1
-    | Version30 = 2
-    | Version35 = 3
-    | Version40 = 4
-    | Version45 = 5
-    | Version451 = 6
-    | Version46 = 7
-    | Version461 = 8
-    | Version452 = 9
-    | Version462 = 10
-    | Version47 = 11
-    | Version471 = 12
-    | Version472 = 13
-    | VersionLatest = 13  //TargetDotNetFrameworkVersion.Version472
-
-    /// 
-    /// Used to specify the targeted bitness of the .NET Framework for some methods of ToolLocationHelper
-    /// 
-    type DotNetFrameworkArchitecture =
-    | Current = 0                                   // Indicates the .NET Framework that is currently being run under
-    | Bitness32 = 1                                 // Indicates the 32-bit .NET Framework
-    | Bitness64 = 2                                 // Indicates the 64-bit .NET Framework
-
-module internal ToolLocationHelper =
-    open Microsoft.Build.Framework
-    open System.Linq
-    open System.Reflection
-    open MsBuildAdapters
-
-    let dotNetFrameworkIdentifier = ".NETFramework"
-
-    // .net versions.
-    let dotNetFrameworkVersion11  = Version(1, 1)
-    let dotNetFrameworkVersion20  = Version(2, 0)
-    let dotNetFrameworkVersion30  = Version(3, 0)
-    let dotNetFrameworkVersion35  = Version(3, 5)
-    let dotNetFrameworkVersion40  = Version(4, 0)
-    let dotNetFrameworkVersion45  = Version(4, 5)
-    let dotNetFrameworkVersion451 = Version(4, 5, 1)
-    let dotNetFrameworkVersion452 = Version(4, 5, 2)
-    let dotNetFrameworkVersion46  = Version(4, 6)
-    let dotNetFrameworkVersion461 = Version(4, 6, 1)
-    let dotNetFrameworkVersion462 = Version(4, 6, 2)
-    let dotNetFrameworkVersion47  = Version(4, 7)
-    let dotNetFrameworkVersion471 = Version(4, 7, 1)
-    let dotNetFrameworkVersion472 = Version(4, 7, 2)
-
-    // visual studio versions.
-    let visualStudioVersion100 = new Version(10, 0);
-    let visualStudioVersion110 = new Version(11, 0);
-    let visualStudioVersion120 = new Version(12, 0);
-    let visualStudioVersion140 = new Version(14, 0);
-    let visualStudioVersion150 = new Version(15, 0);
-
-    // keep this up-to-date; always point to the latest visual studio version.
-    let visualStudioVersionLatest = visualStudioVersion150;
-
-    let dotNetFrameworkRegistryPath = "SOFTWARE\\Microsoft\\.NETFramework";
-    let dotNetFrameworkSetupRegistryPath = "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP";
-    let dotNetFrameworkSetupRegistryInstalledName = "Install";
-
-    let fullDotNetFrameworkRegistryKey = "HKEY_LOCAL_MACHINE\\" + dotNetFrameworkRegistryPath;
-    let dotNetFrameworkAssemblyFoldersRegistryPath = dotNetFrameworkRegistryPath + "\\AssemblyFolders";
-    let referenceAssembliesRegistryValueName = "All Assemblies In";
-
-    let dotNetFrameworkSdkInstallKeyValueV11 = "SDKInstallRootv1.1";
-    let dotNetFrameworkVersionFolderPrefixV11 = "v1.1"; // v1.1 is for Everett.
-    let dotNetFrameworkVersionV11 = "v1.1.4322";       // full Everett version to pass to NativeMethodsShared.GetRequestedRuntimeInfo().
-    let dotNetFrameworkRegistryKeyV11 = dotNetFrameworkSetupRegistryPath + "\\" + dotNetFrameworkVersionV11;
-
-    let dotNetFrameworkSdkInstallKeyValueV20 = "SDKInstallRootv2.0";
-    let dotNetFrameworkVersionFolderPrefixV20 = "v2.0"; // v2.0 is for Whidbey.
-    let dotNetFrameworkVersionV20 = "v2.0.50727"; // full Whidbey version to pass to NativeMethodsShared.GetRequestedRuntimeInfo().
-    let dotNetFrameworkRegistryKeyV20 = dotNetFrameworkSetupRegistryPath + "\\" + dotNetFrameworkVersionV20;
-
-    let dotNetFrameworkVersionFolderPrefixV30 = "v3.0"; // v3.0 is for WinFx.
-    let dotNetFrameworkVersionV30 = "v3.0"; // full WinFx version to pass to NativeMethodsShared.GetRequestedRuntimeInfo().
-    let dotNetFrameworkAssemblyFoldersRegistryKeyV30 = dotNetFrameworkAssemblyFoldersRegistryPath + "\\" + dotNetFrameworkVersionFolderPrefixV30;
-    let dotNetFrameworkRegistryKeyV30 = dotNetFrameworkSetupRegistryPath + "\\" + dotNetFrameworkVersionFolderPrefixV30 + "\\Setup";
-
-    let fallbackDotNetFrameworkSdkRegistryInstallPath = "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows";
-    let fallbackDotNetFrameworkSdkInstallKeyValue = "CurrentInstallFolder";
-
-    let dotNetFrameworkSdkRegistryPathForV35ToolsOnWinSDK70A = @"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx35Tools-x86";
-    let fullDotNetFrameworkSdkRegistryPathForV35ToolsOnWinSDK70A = "HKEY_LOCAL_MACHINE\\" + dotNetFrameworkSdkRegistryPathForV35ToolsOnWinSDK70A;
-
-    let dotNetFrameworkSdkRegistryPathForV35ToolsOnManagedToolsSDK80A = @"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx35Tools-x86";
-    let fullDotNetFrameworkSdkRegistryPathForV35ToolsOnManagedToolsSDK80A = "HKEY_LOCAL_MACHINE\\" + dotNetFrameworkSdkRegistryPathForV35ToolsOnManagedToolsSDK80A;
-
-    let dotNetFrameworkVersionFolderPrefixV35 = "v3.5"; // v3.5 is for Orcas.
-    let dotNetFrameworkRegistryKeyV35 = dotNetFrameworkSetupRegistryPath + "\\" + dotNetFrameworkVersionFolderPrefixV35;
-
-    let fullDotNetFrameworkSdkRegistryKeyV35OnVS10 = fullDotNetFrameworkSdkRegistryPathForV35ToolsOnWinSDK70A;
-    let fullDotNetFrameworkSdkRegistryKeyV35OnVS11 = fullDotNetFrameworkSdkRegistryPathForV35ToolsOnManagedToolsSDK80A;
-
-    let dotNetFrameworkVersionFolderPrefixV40 = "v4.0";
-    let ToolsVersionsRegistryPath = @"SOFTWARE\Microsoft\MSBuild\ToolsVersions";       // Path to the ToolsVersion definitions in the registry
-
-
-    let programFiles = Environment.GetEnvironmentVariable("ProgramFiles")
-
-    let programFiles32 =
-        // On a 64 bit machine we always want to use the program files x86.  If we are running as a 64 bit process then this variable will be set correctly
-        // If we are on a 32 bit machine or running as a 32 bit process then this variable will be null and the programFiles variable will be correct.
-        let programFilesX86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)")
-        if programFilesX86 = null then 
-            programFiles 
-        else 
-            programFilesX86
-
-    let programFilesX64 =
-        if String.Equals(programFiles, programFiles32) then
-            // either we're in a 32-bit window, or we're on a 32-bit machine.  
-            // if we're on a 32-bit machine, ProgramW6432 won't exist
-            // if we're on a 64-bit machine, ProgramW6432 will point to the correct Program Files. 
-            Environment.GetEnvironmentVariable("ProgramW6432");
-        else
-            // 64-bit window on a 64-bit machine; %ProgramFiles% points to the 64-bit 
-            // Program Files already. 
-            programFiles;
-
-    let getArgumentException version =
-        let _, msg = SR.toolLocationHelperUnsupportedFrameworkVersion(version.ToString())
-        new ArgumentException(msg)
-
-    let TargetDotNetFrameworkVersionToSystemVersion version =
-        match version with
-        | TargetDotNetFrameworkVersion.Version11 -> dotNetFrameworkVersion11
-        | TargetDotNetFrameworkVersion.Version20 -> dotNetFrameworkVersion20
-        | TargetDotNetFrameworkVersion.Version30 -> dotNetFrameworkVersion30
-        | TargetDotNetFrameworkVersion.Version35 -> dotNetFrameworkVersion35
-        | TargetDotNetFrameworkVersion.Version40 -> dotNetFrameworkVersion40
-        | TargetDotNetFrameworkVersion.Version45 -> dotNetFrameworkVersion45
-        | TargetDotNetFrameworkVersion.Version451 -> dotNetFrameworkVersion451
-        | TargetDotNetFrameworkVersion.Version452 -> dotNetFrameworkVersion452
-        | TargetDotNetFrameworkVersion.Version46 -> dotNetFrameworkVersion46
-        | TargetDotNetFrameworkVersion.Version461 -> dotNetFrameworkVersion461
-        | TargetDotNetFrameworkVersion.Version462 -> dotNetFrameworkVersion462
-        | TargetDotNetFrameworkVersion.Version47 -> dotNetFrameworkVersion47
-        | TargetDotNetFrameworkVersion.Version471 -> dotNetFrameworkVersion471
-        | TargetDotNetFrameworkVersion.Version472 -> dotNetFrameworkVersion472
-        | _ -> raise (getArgumentException version)
-
-    let complusInstallRoot = Environment.GetEnvironmentVariable("COMPLUS_INSTALLROOT")
-    let complusVersion = Environment.GetEnvironmentVariable("COMPLUS_VERSION")
-
-    type DotNetFrameworkSpec (version, dotNetFrameworkRegistryKey, dotNetFrameworkSetupRegistryInstalledName, dotNetFrameworkVersionFolderPrefix, dotNetFrameworkSdkRegistryToolsKey, dotNetFrameworkSdkRegistryInstallationFolderName, hasMSBuild, _vsVersion) =
-
-        let _HKLM = "HKEY_LOCAL_MACHINE"
-        let _microsoftSDKsRegistryKey = @"SOFTWARE\Microsoft\Microsoft SDKs"
-        let dotNetFrameworkFolderPrefix = dotNetFrameworkVersionFolderPrefix
-        let frameworkName = FrameworkName(dotNetFrameworkIdentifier, version)
-
-#if !FX_NO_WIN_REGISTRY
-        let findRegistryValueUnderKey registryBaseKeyName registryKeyName registryView =
-         try
-            use baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView)
-            use subKey = baseKey.OpenSubKey(registryBaseKeyName)
-            match subKey with
-            | null -> None
-            | _ as x -> 
-                let keyValue = x.GetValue(registryKeyName)
-                match keyValue with
-                | null -> None
-                | _ as x -> Some (x.ToString())
-         with _ -> None
-#endif
-
-        let findRegistryValueUnderKey registryBaseKeyName registryKeyName =
-#if FX_NO_WIN_REGISTRY
-            ignore registryBaseKeyName 
-            ignore registryKeyName 
-            None
-#else
-            findRegistryValueUnderKey registryBaseKeyName registryKeyName RegistryView.Default
-#endif
-        let CheckForFrameworkInstallation registryEntryToCheckInstall registryValueToCheckInstall =
-            // Complus is not set we need to make sure the framework we are targeting is installed. Check the registry key before trying to find the directory.
-            // If complus is set then we will return that directory as the framework directory, there is no need to check the registry value for the framework and it may not even be installed.
-
-            if (String.IsNullOrEmpty(complusInstallRoot) && String.IsNullOrEmpty(complusVersion)) then
-
-                // If the registry entry is 1 then the framework is installed. Go ahead and find the directory. If it is not 1 then the framework is not installed, return null
-
-                match findRegistryValueUnderKey registryEntryToCheckInstall registryValueToCheckInstall with
-                | None -> false
-                | Some x -> if String.Compare("1", x, StringComparison.OrdinalIgnoreCase) = 0 then true else false
-
-            else true
-
-        let PickDirectoryFromInstallRoot prefix (installRoot:string)  arch =
-            let searchPattern = prefix + "*"
-            let calculatePath =
-                let bitness s = if arch = DotNetFrameworkArchitecture.Bitness64 then s + @"64\" else s + @"\"
-                let trim = if installRoot.EndsWith(@"\") then installRoot.Substring(0, installRoot.Length - 1) else installRoot
-                let i64 = trim.IndexOf("Framework64", StringComparison.OrdinalIgnoreCase)
-                if i64 = -1 then bitness trim else bitness (trim.Substring(0, i64 + 9))
-
-            if Directory.Exists(calculatePath) then
-                let directories = Directory.GetDirectories(calculatePath, searchPattern) |> Array.sort
-                if directories.Length = 0 then None
-                else
-                    // We don't care which one we choose, but we want to be predictible.
-                    // The intention here is to choose the alphabetical maximum.
-                    let mutable max = directories |> Array.last
-                    Some max
-            else
-                None
-
-        let FindDotNetFrameworkPath prefix registryEntryToCheckInstall registryValueToCheckInstall arch =
-            // If the COMPLUS variables are set, they override everything -- that's the directory we want.
-            if String.IsNullOrEmpty(complusInstallRoot) || String.IsNullOrEmpty(complusVersion) then
-                // We haven't managed to use exact methods to locate the FX, Since we run on coreclr 
-                // we can't guess where by using the currently executing runtime
-                let installRootFromReg = findRegistryValueUnderKey registryEntryToCheckInstall registryValueToCheckInstall
-                match installRootFromReg with
-                | None -> None
-                | Some x -> PickDirectoryFromInstallRoot prefix x arch
-            else 
-                Some (Path.Combine(complusInstallRoot, complusVersion))
-
-
-        /// 
-        /// Take the parts of the Target framework moniker and formulate the reference assembly path based on the the following pattern:
-        /// For a framework and version:
-        ///     $(TargetFrameworkRootPath)\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)
-        /// For a subtype:
-        ///     $(TargetFrameworkRootPath)\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\SubType\$(TargetFrameworkSubType)
-        /// e.g.NET Framework v4.0 would locate its reference assemblies in:
-        ///     \Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0
-        /// e.g.Silverlight v2.0 would locate its reference assemblies in:
-        ///     \Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v2.0
-        /// e.g.NET Compact Framework v3.5, subtype PocketPC would locate its reference assemblies in:
-        ///     \Program Files\Reference Assemblies\Microsoft\Framework\.NETCompactFramework\v3.5\SubType\PocketPC
-        /// 
-        /// The path to the reference assembly location
-        let GenerateReferenceAssemblyPath targetFrameworkRootPath (frameworkName:FrameworkName) =
-            match targetFrameworkRootPath with
-            | Some x ->
-                try
-                    let basePath = Path.Combine(x, frameworkName.Identifier, "v" + frameworkName.Version.ToString())
-                    let withProfile root =
-                        if not (String.IsNullOrEmpty(frameworkName.Profile)) then
-                            Path.Combine(root, "Profile", frameworkName.Profile)
-                        else root
-                    Some (Path.GetFullPath(withProfile basePath) + @"\")
-                with _ ->
-                    // The compiler does not see the massage above an as exception;
-                    None
-            | _ -> None
-
-
-        /// 
-        /// Generate the path to the program files reference assembly location by taking in the program files special folder and then 
-        /// using that path to generate the path to the reference assemblies location.
-        /// 
-        let generateProgramFilesReferenceAssemblyRoot =
-            try
-                Some(Path.GetFullPath( Path.Combine(programFiles32, "Reference Assemblies\\Microsoft\\Framework") ))
-            with _ ->
-                None
-
-        let pathToDotNetFrameworkReferenceAssemblies =
-            match GenerateReferenceAssemblyPath generateProgramFilesReferenceAssemblyRoot frameworkName with
-            | Some x when Directory.Exists(x) -> x + @"\"
-            | _ -> ""
-
-
-        member this.Version = version
-        member this.dotNetFrameworkRegistryKey = dotNetFrameworkRegistryKey
-        member this.dotNetFrameworkSetupRegistryInstalledName = dotNetFrameworkSetupRegistryInstalledName
-        member this.dotNetFrameworkSdkRegistryToolsKey = dotNetFrameworkSdkRegistryToolsKey
-        member this.DotNetFrameworkSdkRegistryInstallationFolderName = dotNetFrameworkSdkRegistryInstallationFolderName
-        member this.HasMSBuild = hasMSBuild
-
-        member this.pathsToDotNetFramework = new ConcurrentDictionary()
-        member this.pathsToDotNetFrameworkSdkTools = new ConcurrentDictionary()
-        member this.pathToWindowsSdk = "Todo:   Review dow we really need this"
-
-//            /// 
-//            /// Gets the full registry key of this .net framework Sdk for the given visual studio version.
-//            /// i.e. "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools-x86" for .net v4.5 on VS11.
-//            /// 
-//            public virtual string GetDotNetFrameworkSdkRootRegistryKey(VisualStudioSpec visualStudioSpec)
-//            {
-//                return string.Join(@"\", HKLM, MicrosoftSDKsRegistryKey, visualStudioSpec.DotNetFrameworkSdkRegistryKey, this.dotNetFrameworkSdkRegistryToolsKey);
-//            }
-
-        // Doesn't need to be virtual @@@@@
-        abstract member GetPathToDotNetFramework: DotNetFrameworkArchitecture -> string
-        default this.GetPathToDotNetFramework arch =
-            match this.pathsToDotNetFramework.TryGetValue arch with
-            | true, x -> x
-            | _ ->
-                if not (CheckForFrameworkInstallation this.dotNetFrameworkRegistryKey this.dotNetFrameworkSetupRegistryInstalledName) then null
-                else
-                    // We're not installed and we haven't found this framework path yet -- so find it!
-                    let fwp:string option = (FindDotNetFrameworkPath dotNetFrameworkFolderPrefix dotNetFrameworkRegistryKey this.dotNetFrameworkSetupRegistryInstalledName arch)
-                    match fwp with
-                    | Some x ->
-                        // For .net frameworks that should have msbuild.exe is it there
-                        if hasMSBuild && not (File.Exists(Path.Combine(x, "msbuild.exe"))) then null
-                        else this.pathsToDotNetFramework.[arch] <- x; x
-                    | _ -> null
-
-        // Doesn't need to be virtual @@@@@
-        /// 
-        /// Gets the full path of reference assemblies folder.
-        /// i.e. "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\" for .net v4.5.
-        /// 
-        abstract member GetPathToDotNetFrameworkReferenceAssemblies: string
-        default this.GetPathToDotNetFrameworkReferenceAssemblies = pathToDotNetFrameworkReferenceAssemblies
-
-//            /// 
-//            /// Gets the full path of .net framework sdk tools for the given visual studio version.
-//            /// i.e. "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\" for .net v4.5 on VS11.
-//            /// 
-//            public virtual string GetPathToDotNetFrameworkSdkTools(VisualStudioSpec visualStudioSpec)
-//            {
-//                string cachedPath;
-//                if (this.pathsToDotNetFrameworkSdkTools.TryGetValue(visualStudioSpec.Version, out cachedPath))
-//                {
-//                    return cachedPath;
-//                }
-//
-//                string registryPath = string.Join(@"\", MicrosoftSDKsRegistryKey, visualStudioSpec.DotNetFrameworkSdkRegistryKey, this.dotNetFrameworkSdkRegistryToolsKey);
-//
-//                // For the Dev10 SDK, we check the registry that corresponds to the current process' bitness, rather than
-//                // always the 32-bit one the way we do for Dev11 and onward, since that's what we did in Dev10 as well.
-//                // As of Dev11, the SDK reg keys are installed in the 32-bit registry. 
-//                RegistryView registryView = visualStudioSpec.Version == visualStudioVersion100 ? RegistryView.Default : RegistryView.Registry32;
-//
-//                string generatedPathToDotNetFrameworkSdkTools = FindRegistryValueUnderKey(
-//                    registryPath,
-//                    this.dotNetFrameworkSdkRegistryInstallationFolderName,
-//                    registryView);
-//
-//                if (string.IsNullOrEmpty(generatedPathToDotNetFrameworkSdkTools))
-//                {
-//                    // Fallback mechanisms.
-//
-//                    // Try to find explicit fallback rule.
-//                    // i.e. v4.5.1 on VS12 fallbacks to v4.5 on VS12.
-//                    bool foundExplicitRule = false;
-//                    for (int i = 0; i < s_explicitFallbackRulesForPathToDotNetFrameworkSdkTools.GetLength(0); ++i)
-//                    {
-//                        var trigger = s_explicitFallbackRulesForPathToDotNetFrameworkSdkTools[i, 0];
-//                        if (trigger.Item1 == this.version && trigger.Item2 == visualStudioSpec.Version)
-//                        {
-//                            foundExplicitRule = true;
-//                            var fallback = s_explicitFallbackRulesForPathToDotNetFrameworkSdkTools[i, 1];
-//                            generatedPathToDotNetFrameworkSdkTools = FallbackToPathToDotNetFrameworkSdkToolsInPreviousVersion(fallback.Item1, fallback.Item2);
-//                            break;
-//                        }
-//                    }
-//
-//                    // Otherwise, fallback to previous VS.
-//                    // i.e. fallback to v110 if the current visual studio version is v120.
-//                    if (!foundExplicitRule)
-//                    {
-//                        int index = Array.IndexOf(s_visualStudioSpecs, visualStudioSpec);
-//                        if (index > 0)
-//                        {
-//                            // The items in the array "visualStudioSpecs" must be ordered by version. That would allow us to fallback to the previous visual studio version easily.
-//                            VisualStudioSpec fallbackVisualStudioSpec = s_visualStudioSpecs[index - 1];
-//                            generatedPathToDotNetFrameworkSdkTools = FallbackToPathToDotNetFrameworkSdkToolsInPreviousVersion(this.version, fallbackVisualStudioSpec.Version);
-//                        }
-//                    }
-//                }
-//
-//                if (string.IsNullOrEmpty(generatedPathToDotNetFrameworkSdkTools))
-//                {
-//                    // Fallback to "default" ultimately.
-//                    generatedPathToDotNetFrameworkSdkTools = FallbackToDefaultPathToDotNetFrameworkSdkTools(this.version);
-//                }
-//
-//                if (!string.IsNullOrEmpty(generatedPathToDotNetFrameworkSdkTools))
-//                {
-//                    this.pathsToDotNetFrameworkSdkTools[visualStudioSpec.Version] = generatedPathToDotNetFrameworkSdkTools;
-//                }
-//
-//                return generatedPathToDotNetFrameworkSdkTools;
-//            }
-//
-//            /// 
-//            /// Gets the full path of .net framework sdk.
-//            /// i.e. "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\" for .net v4.5 on VS11.
-//            /// 
-//            public virtual string GetPathToDotNetFrameworkSdk(VisualStudioSpec visualStudioSpec)
-//            {
-//                string pathToBinRoot = this.GetPathToDotNetFrameworkSdkTools(visualStudioSpec);
-//                pathToBinRoot = RemoveDirectories(pathToBinRoot, 2);
-//                return pathToBinRoot;
-//            }
-//
-//            /// 
-//            /// Gets the full path of reference assemblies folder.
-//            /// i.e. "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\" for .net v4.5.
-//            /// 
-//            public virtual string GetPathToDotNetFrameworkReferenceAssemblies()
-//            {
-//                if (this.pathToDotNetFrameworkReferenceAssemblies == null)
-//                {
-//                    // when a user requests the 40 reference assembly path we don't need to read the redist list because we will not be chaining so we may as well just
-//                    // generate the path and save us some time.
-//                    string referencePath = GenerateReferenceAssemblyPath(FrameworkLocationHelper.programFilesReferenceAssemblyLocation, this.FrameworkName);
-//                    if (Directory.Exists(referencePath))
-//                    {
-//                        this.pathToDotNetFrameworkReferenceAssemblies = FileUtilities.EnsureTrailingSlash(referencePath);
-//                    }//                }
-//
-//                return this.pathToDotNetFrameworkReferenceAssemblies;
-//            }
-//
-//            /// 
-//            /// Gets the full path of the corresponding windows sdk shipped with this .net framework.
-//            /// i.e. "C:\Program Files (x86)\Windows Kits\8.0\" for v8.0 (shipped with .net v4.5 and VS11).
-//            /// 
-//            public virtual string GetPathToWindowsSdk()
-//            {
-//                if (this.pathToWindowsSdk == null)
-//                {
-//                    ErrorUtilities.VerifyThrowArgument(this.visualStudioVersion != null, "FrameworkLocationHelper.UnsupportedFrameworkVersionForWindowsSdk", this.version);
-//
-//                    var visualStudioSpec = GetVisualStudioSpec(this.visualStudioVersion);
-//
-//                    if (string.IsNullOrEmpty(visualStudioSpec.WindowsSdkRegistryKey) || string.IsNullOrEmpty(visualStudioSpec.WindowsSdkRegistryInstallationFolderName))
-//                    {
-//                        ErrorUtilities.ThrowArgument("FrameworkLocationHelper.UnsupportedFrameworkVersionForWindowsSdk", this.version);
-//                    }
-//
-//                    string registryPath = string.Join(@"\", MicrosoftSDKsRegistryKey, "Windows", visualStudioSpec.WindowsSdkRegistryKey);
-//
-//                    // As of Dev11, the SDK reg keys are installed in the 32-bit registry. 
-//                    this.pathToWindowsSdk = FindRegistryValueUnderKey(
-//                        registryPath,
-//                        visualStudioSpec.WindowsSdkRegistryInstallationFolderName,
-//                        RegistryView.Registry32);
-//                }
-//
-//                return this.pathToWindowsSdk;
-//            }
-//
-//            protected static string FallbackToPathToDotNetFrameworkSdkToolsInPreviousVersion(Version dotNetFrameworkVersion, Version visualStudioVersion)
-//            {
-//                VisualStudioSpec visualStudioSpec;
-//                DotNetFrameworkSpec dotNetFrameworkSpec;
-//                if (s_visualStudioSpecDict.TryGetValue(visualStudioVersion, out visualStudioSpec)
-//                    && s_dotNetFrameworkSpecDict.TryGetValue(dotNetFrameworkVersion, out dotNetFrameworkSpec)
-//                    && visualStudioSpec.SupportedDotNetFrameworkVersions.Contains(dotNetFrameworkVersion))
-//                {
-//                    return dotNetFrameworkSpec.GetPathToDotNetFrameworkSdkTools(visualStudioSpec);
-//                }
-//
-//                return null;
-//            }
-//
-//            protected static string FallbackToDefaultPathToDotNetFrameworkSdkTools(Version dotNetFrameworkVersion)
-//            {
-//                if (dotNetFrameworkVersion.Major == 4)
-//                {
-//                    return FrameworkLocationHelper.PathToV4ToolsInFallbackDotNetFrameworkSdk;
-//                }
-//
-//                if (dotNetFrameworkVersion == dotNetFrameworkVersion35)
-//                {
-//                    return FrameworkLocationHelper.PathToV35ToolsInFallbackDotNetFrameworkSdk;
-//                }
-//
-//                return null;
-//            }
-//        }
-
-    type DotNetFrameworkSpecLegacy (version,
-                                    dotNetFrameworkRegistryKey,
-                                    dotNetFrameworkSetupRegistryInstalledName,
-                                    dotNetFrameworkVersionFolderPrefix,
-                                    dotNetFrameworkSdkRegistryToolsKey,
-                                    dotNetFrameworkSdkRegistryInstallationFolderName,
-                                    hasMSBuild, 
-                                    vsBuild) =
-        inherit DotNetFrameworkSpec (version,
-                                     dotNetFrameworkRegistryKey,
-                                     dotNetFrameworkSetupRegistryInstalledName,
-                                     dotNetFrameworkVersionFolderPrefix,
-                                     dotNetFrameworkSdkRegistryToolsKey,
-                                     dotNetFrameworkSdkRegistryInstallationFolderName,
-                                     hasMSBuild, 
-                                     vsBuild)
-
-    type DotNetFrameworkSpecV3 (version,
-                                dotNetFrameworkRegistryKey,
-                                dotNetFrameworkSetupRegistryInstalledName,
-                                dotNetFrameworkVersionFolderPrefix,
-                                dotNetFrameworkSdkRegistryToolsKey,
-                                dotNetFrameworkSdkRegistryInstallationFolderName,
-                                hasMSBuild, 
-                                vsBuild) =
-        inherit DotNetFrameworkSpec(version,
-                                    dotNetFrameworkRegistryKey,
-                                    dotNetFrameworkSetupRegistryInstalledName,
-                                    dotNetFrameworkVersionFolderPrefix,
-                                    dotNetFrameworkSdkRegistryToolsKey,
-                                    dotNetFrameworkSdkRegistryInstallationFolderName,
-                                    hasMSBuild, 
-                                    vsBuild)
-
-
-//        {
-//            private string _pathToDotNetFrameworkSdkTools;
-//
-//            public DotNetFrameworkSpecLegacy(
-//                Version version,
-//                string dotNetFrameworkRegistryKey,
-//                string dotNetFrameworkSetupRegistryInstalledName,
-//                string dotNetFrameworkVersionFolderPrefix,
-//                string dotNetFrameworkSdkRegistryInstallationFolderName,
-//                bool hasMSBuild)
-//                : base(version,
-//                      dotNetFrameworkRegistryKey,
-//                      dotNetFrameworkSetupRegistryInstalledName,
-//                      dotNetFrameworkVersionFolderPrefix,
-//                      null,
-//                      dotNetFrameworkSdkRegistryInstallationFolderName,
-//                      hasMSBuild)
-//            {
-//            }
-//
-//            /// 
-//            /// Gets the full registry key of this .net framework Sdk for the given visual studio version.
-//            /// i.e. "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework" for v1.1 and v2.0.
-//            /// 
-//            public override string GetDotNetFrameworkSdkRootRegistryKey(VisualStudioSpec visualStudioSpec)
-//            {
-//                return FrameworkLocationHelper.fullDotNetFrameworkRegistryKey;
-//            }
-//
-//            /// 
-//            /// Gets the full path of .net framework sdk tools for the given visual studio version.
-//            /// 
-//            public override string GetPathToDotNetFrameworkSdkTools(VisualStudioSpec visualStudioSpec)
-//            {
-//                if (_pathToDotNetFrameworkSdkTools == null)
-//                {
-//                    _pathToDotNetFrameworkSdkTools = FindRegistryValueUnderKey(
-//                        dotNetFrameworkRegistryPath,
-//                        this.dotNetFrameworkSdkRegistryInstallationFolderName);
-//                }
-//
-//                return _pathToDotNetFrameworkSdkTools;
-//            }
-//
-//            /// 
-//            /// Gets the full path of .net framework sdk, which is the full path of .net framework sdk tools for v1.1 and v2.0.
-//            /// 
-//            public override string GetPathToDotNetFrameworkSdk(VisualStudioSpec visualStudioSpec)
-//            {
-//                return this.GetPathToDotNetFrameworkSdkTools(visualStudioSpec);
-//            }
-//
-//            /// 
-//            /// Gets the full path of reference assemblies folder, which is the full path of .net framework for v1.1 and v2.0.
-//            /// 
-//            public override string GetPathToDotNetFrameworkReferenceAssemblies()
-//            {
-//                return this.GetPathToDotNetFramework(DotNetFrameworkArchitecture.Current);
-//            }
-//        }
-//
-//        /// 
-//        /// Specialized implementation for legacy .net framework v3.0 and v3.5.
-//        /// 
-//        private class DotNetFrameworkSpecV3 : DotNetFrameworkSpec
-//        {
-//            public DotNetFrameworkSpecV3(
-//                Version version,
-//                string dotNetFrameworkRegistryKey,
-//                string dotNetFrameworkSetupRegistryInstalledName,
-//                string dotNetFrameworkVersionFolderPrefix,
-//                string dotNetFrameworkSdkRegistryToolsKey,
-//                string dotNetFrameworkSdkRegistryInstallationFolderName,
-//                bool hasMSBuild)
-//                : base(version,
-//                      dotNetFrameworkRegistryKey,
-//                      dotNetFrameworkSetupRegistryInstalledName,
-//                      dotNetFrameworkVersionFolderPrefix,
-//                      dotNetFrameworkSdkRegistryToolsKey,
-//                      dotNetFrameworkSdkRegistryInstallationFolderName,
-//                      hasMSBuild)
-//            {
-//            }
-//
-//            /// 
-//            /// Gets the full path of .net framework sdk.
-//            /// i.e. "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\" for .net v3.5 on VS11.
-//            /// 
-//            public override string GetPathToDotNetFrameworkSdk(VisualStudioSpec visualStudioSpec)
-//            {
-//                string pathToBinRoot = this.GetPathToDotNetFrameworkSdkTools(visualStudioSpec);
-//                pathToBinRoot = RemoveDirectories(pathToBinRoot, 1);
-//                return pathToBinRoot;
-//            }
-//
-//            /// 
-//            /// Gets the full path of reference assemblies folder.
-//            /// i.e. "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\" for v3.5.
-//            /// 
-//            public override string GetPathToDotNetFrameworkReferenceAssemblies()
-//            {
-//                if (this.pathToDotNetFrameworkReferenceAssemblies == null)
-//                {
-//                    this.pathToDotNetFrameworkReferenceAssemblies = FindRegistryValueUnderKey(
-//                        dotNetFrameworkAssemblyFoldersRegistryPath + "\\" + this.dotNetFrameworkFolderPrefix,
-//                        referenceAssembliesRegistryValueName);
-//
-//                    if (this.pathToDotNetFrameworkReferenceAssemblies == null)
-//                    {
-//                        this.pathToDotNetFrameworkReferenceAssemblies = GenerateReferenceAssemblyDirectory(dotNetFrameworkFolderPrefix);
-//                    }
-//                }
-//
-//                return this.pathToDotNetFrameworkReferenceAssemblies;
-//            }
-//        }
-//
-
-    let CreateDotNetFrameworkSpecForV4 version visualStudioVersion =
-        new DotNetFrameworkSpec(
-            version,
-            dotNetFrameworkSetupRegistryPath + "\\v4\\Full",
-            "Install",
-            "v4.0",
-            "WinSDK-NetFx40Tools-x86",
-            "InstallationFolder",
-            true,
-            Some visualStudioVersion)
-
-    let dotNetFrameworkSpecDict = 
-        let array = [|
-            new DotNetFrameworkSpecLegacy(dotNetFrameworkVersion11,                             // v1.1
-                dotNetFrameworkRegistryKeyV11,
-                dotNetFrameworkSetupRegistryInstalledName,
-                dotNetFrameworkVersionFolderPrefixV11,
-                dotNetFrameworkSdkInstallKeyValueV11,
-                "",
-                false,
-                None) :> DotNetFrameworkSpec
-            new DotNetFrameworkSpecLegacy(                                                      // v2.0
-                dotNetFrameworkVersion20,
-                dotNetFrameworkRegistryKeyV20,
-                dotNetFrameworkSetupRegistryInstalledName,
-                dotNetFrameworkVersionFolderPrefixV20,
-                dotNetFrameworkSdkInstallKeyValueV20,
-                "",
-                true,
-                None) :> DotNetFrameworkSpec
-            new DotNetFrameworkSpecV3(                                                          // v3.0
-                dotNetFrameworkVersion30,
-                dotNetFrameworkRegistryKeyV30,
-                "InstallSuccess",
-                dotNetFrameworkVersionFolderPrefixV30,
-                "",
-                "",
-                false,
-                None) :> DotNetFrameworkSpec
-            new DotNetFrameworkSpecV3(                                                          // v3.5
-                dotNetFrameworkVersion35,
-                dotNetFrameworkRegistryKeyV35,
-                dotNetFrameworkSetupRegistryInstalledName,
-                dotNetFrameworkVersionFolderPrefixV35,
-                "WinSDK-NetFx35Tools-x86",
-                "InstallationFolder",
-                true,
-                None) :> DotNetFrameworkSpec
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion40  visualStudioVersion100     // v4.0
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion45  visualStudioVersion110     // v4.5
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion451 visualStudioVersion120     // v4.5.1
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion452 visualStudioVersion150     // v4.5.2
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion46  visualStudioVersion140     // v4.6
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion461 visualStudioVersion150     // v4.6.1
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion462 visualStudioVersion150     // v4.6.2
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion47  visualStudioVersion150     // v4.7
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion471 visualStudioVersion150     // v4.7.1
-            CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion472 visualStudioVersion150     // v4.7.2
-        |]
-        array.ToDictionary(fun spec -> spec.Version)
-
-    let getDotNetFrameworkSpec version =
-        match dotNetFrameworkSpecDict.TryGetValue version with
-        | true, x -> x
-        | _ -> raise (getArgumentException version)
-
-    // Get a fully qualified path to the framework's root directory. 
-//    let GetPathToDotNetFramework version architecture =
-//        let frameworkVersion = TargetDotNetFrameworkVersionToSystemVersion version
-//        (getDotNetFrameworkSpec frameworkVersion).GetPathToDotNetFramework(architecture)
-
-
-    // Get a fully qualified path to the frameworks root directory.
-    let GetPathToDotNetFramework version =
-//        GetPathToDotNetFramework version DotNetFrameworkArchitecture.Current
-        let frameworkVersion = TargetDotNetFrameworkVersionToSystemVersion version
-        (getDotNetFrameworkSpec frameworkVersion).GetPathToDotNetFramework(DotNetFrameworkArchitecture.Current)
-
-    /// 
-    /// Returns the path to the reference assemblies location for the given framework version.
-    /// 
-    /// Version of the targeted .NET Framework
-    /// Path string.
-    let GetPathToDotNetFrameworkReferenceAssemblies version =
-        let frameworkVersion = TargetDotNetFrameworkVersionToSystemVersion version
-        (getDotNetFrameworkSpec frameworkVersion).GetPathToDotNetFrameworkReferenceAssemblies
-
-    type IBuildEngine =
-        abstract member BuildProjectFile : string*string[]*IDictionary*IDictionary -> bool
-        abstract member LogCustomEvent : (*CustomBuildEventArgs*) obj -> unit
-        abstract member LogErrorEvent : (*BuildErrorEventArgs*) obj -> unit
-        abstract member LogMessageEvent : (*BuildMessageEventArgs*) obj -> unit
-        abstract member LogWarningEvent : (*BuildMessageEventArgs*) obj -> unit
-
-        // Properties
-        abstract member ColumnNumberOfTaskNode : int with get
-        abstract member ContinueOnError : bool with get
-        abstract member LineNumberOfTaskNode : int with get
-        abstract member ProjectFileOfTaskNode : string with get
-
-//    let getPropertyValue instance propName =
-//        instance.GetType().GetProperty(propName, BindingFlags.Public).GetValue(instance, null)
-//
-//    let setPropertyValue instance propName propValue=
-//        instance.GetType().GetPropserty(propName, BindingFlags.Public).SetValue(instance, propValue, null)
-
-    type ResolveAssemblyReference () =
-        let assembly = Assembly.Load(new AssemblyName("Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"))
-        let resolveAssemblyReferenceType = assembly.GetType("Microsoft.Build.Tasks.ResolveAssemblyReference")
-        let instance = Activator.CreateInstance(resolveAssemblyReferenceType)
-
-        member this.BuildEngine
-            with get ():IBuildEngine = (instance.GetPropertyValue("BuildEngine") :?> IBuildEngine)
-            and set (value:IBuildEngine) = (instance.SetPropertyValue("BuildEngine", value)); ()
-
-        member this.TargetFrameworkDirectories
-            with get ():string[] = (instance.GetPropertyValue("TargetFrameworkDirectories") :?> string[])
-            and set (value:string[]) = (instance.SetPropertyValue("TargetFrameworkDirectories", value)); ()
-
-        member this.FindRelatedFiles
-            with get () :bool = (instance.GetPropertyValue("FindRelatedFiles") :?> bool)
-            and set (value:bool) = (instance.SetPropertyValue("FindRelatedFiles", value)); ()
-
-        member this.FindDependencies
-            with get ():bool = (instance.GetPropertyValue("FindDependencies") :?> bool)
-            and set (value:bool) = (instance.SetPropertyValue("FindDependencies", value)); ()
-
-        member this.FindSatellites
-            with get ():bool = (instance.GetPropertyValue("FindSatellites") :?> bool)
-            and set (value:bool) = (instance.SetPropertyValue("FindSatellites", value)); ()
-
-        member this.FindSerializationAssemblies
-            with get ():bool = (instance.GetPropertyValue("FindSerializationAssemblies") :?> bool)
-            and set (value:bool) = (instance.SetPropertyValue("FindSerializationAssemblies", value)); ()
-
-        member this.TargetedRuntimeVersion
-            with get ():string = (instance.GetPropertyValue("TargetedRuntimeVersion") :?> string)
-            and set (value:string) = (instance.SetPropertyValue("TargetedRuntimeVersion", value)); ()
-
-        member this.TargetProcessorArchitecture
-            with get ():string = (instance.GetPropertyValue("TargetProcessorArchitecture") :?> string)
-            and set (value:string) = (instance.SetPropertyValue("TargetProcessorArchitecture", value)); ()
-
-        member this.CopyLocalDependenciesWhenParentReferenceInGac
-            with get ():bool = (instance.GetPropertyValue("CopyLocalDependenciesWhenParentReferenceInGac") :?> bool)
-            and set (value:bool) = (instance.SetPropertyValue("CopyLocalDependenciesWhenParentReferenceInGac", value)); ()
-
-        member this.AllowedAssemblyExtensions
-            with get () :string[] = (instance.GetPropertyValue("AllowedAssemblyExtensions") :?> string[])
-            and set (value:string[]) =  (instance.SetPropertyValue("AllowedAssemblyExtensions", value)); ()
-
-        member this.Assemblies
-            with get ():ITaskItem[] = (instance.GetPropertyValue("Assemblies") :?> ITaskItem[])
-            and set (value:ITaskItem[]) = (instance.SetPropertyValue("Assemblies", value)); ()
-
-        member this.CopyLocalFiles = (instance.GetPropertyValue("CopyLocalFiles") :?> ITaskItem[])
-
-        member this.RelatedFiles = (instance.GetPropertyValue("RelatedFiles") :?> ITaskItem[])
-
-        member this.ResolvedFiles = (instance.GetPropertyValue("ResolvedFiles") :?> ITaskItem[])
-
-        member this.ResolvedDependencyFiles = (instance.GetPropertyValue("ResolvedDependencyFiles") :?> ITaskItem[])
-
-        member this.SatelliteFiles = (instance.GetPropertyValue("SatelliteFiles") :?> ITaskItem[])
-
-        member this.ScatterFiles = (instance.GetPropertyValue("ScatterFiles") :?> ITaskItem[])
-
-        member this.SuggestedRedirects = (instance.GetPropertyValue("SuggestedRedirects") :?> ITaskItem[])
-
-        member this.SearchPaths
-            with get () :string[] = (instance.GetPropertyValue("SearchPaths") :?> string[])
-            and set (value:string[]) =  (instance.SetPropertyValue("SearchPaths", value)); ()
-
-        member this.Execute () =
-            let m = instance.GetType().GetMethod("Execute", [| |])
-            m.Invoke(instance, [||]) :?> bool
-
-#endif
diff --git a/src/utils/sformat.fs b/src/utils/sformat.fs
deleted file mode 100644
index 013e55626e5..00000000000
--- a/src/utils/sformat.fs
+++ /dev/null
@@ -1,1254 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-// This file is compiled 3(!) times in the codebase
-//    - as the internal implementation of printf '%A' formatting in FSharp.Core
-//    - as the internal implementation of structured formatting in the compiler and F# Interactive
-//           defines: COMPILER 
-//
-// The one implementation file is used because we very much want to keep the implementations of
-// structured formatting the same for fsi.exe and '%A' printing. However fsi.exe may have
-// a richer feature set.
-//
-// Note no layout objects are ever transferred between the above implementations, and in 
-// all 4 cases the layout types are really different types.
-
-#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
-
-#if COMPILER
-namespace Internal.Utilities.StructuredFormat
-#else
-// FSharp.Core.dll:
-namespace Microsoft.FSharp.Text.StructuredPrintfImpl
-#endif
-
-    // Breakable block layout implementation.
-    // This is a fresh implementation of pre-existing ideas.
-
-    open System
-    open System.IO
-    open System.Reflection
-    open System.Globalization
-    open System.Collections.Generic
-    open Microsoft.FSharp.Core
-    open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
-    open Microsoft.FSharp.Reflection
-    open Microsoft.FSharp.Collections
-
-    []
-    type LayoutTag =
-        | ActivePatternCase
-        | ActivePatternResult
-        | Alias
-        | Class
-        | Union
-        | UnionCase
-        | Delegate
-        | Enum
-        | Event
-        | Field
-        | Interface
-        | Keyword
-        | LineBreak
-        | Local
-        | Record
-        | RecordField
-        | Method
-        | Member
-        | ModuleBinding
-        | Module
-        | Namespace
-        | NumericLiteral
-        | Operator
-        | Parameter
-        | Property
-        | Space
-        | StringLiteral
-        | Struct
-        | TypeParameter
-        | Text
-        | Punctuation
-        | UnknownType
-        | UnknownEntity
-
-    type TaggedText =
-        abstract Tag: LayoutTag
-        abstract Text: string
-
-    type TaggedTextWriter =
-        abstract Write: t: TaggedText -> unit
-        abstract WriteLine: unit -> unit
-
-    /// A joint, between 2 layouts, is either:
-    ///  - unbreakable, or
-    ///  - breakable, and if broken the second block has a given indentation.
-    []
-    type Joint =
-     | Unbreakable
-     | Breakable of int
-     | Broken of int
-
-    /// Leaf juxt,data,juxt
-    /// Node juxt,left,juxt,right,juxt and joint
-    ///
-    /// If either juxt flag is true, then no space between words.
-    []
-    type Layout =
-     | ObjLeaf of bool * obj * bool
-     | Leaf of bool * TaggedText * bool
-     | Node of bool * layout * bool * layout * bool * joint
-     | Attr of string * (string * string) list * layout
-
-    and layout = Layout
-
-    and joint = Joint
-
-    []
-    type IEnvironment = 
-        abstract GetLayout : obj -> layout
-        abstract MaxColumns : int
-        abstract MaxRows : int
-
-    module TaggedTextOps =
-        let tag tag text = 
-          { new TaggedText with 
-            member x.Tag = tag
-            member x.Text = text }
-
-        let length (tt: TaggedText) = tt.Text.Length
-        let toText (tt: TaggedText) = tt.Text
-
-        let tagAlias t = tag LayoutTag.Alias t
-        let keywordFunctions = Set ["raise"; "reraise"; "typeof"; "typedefof"; "sizeof"; "nameof"]
-        let keywordTypes = 
-          [
-            "array"
-            "bigint"
-            "bool"
-            "byref"
-            "byte"
-            "char"
-            "decimal"
-            "double"
-            "float"
-            "float32"
-            "int"
-            "int8"
-            "int16"
-            "int32"
-            "int64"
-            "list"
-            "nativeint"
-            "obj"
-            "sbyte"
-            "seq"
-            "single"
-            "string"
-            "unit"
-            "uint"
-            "uint8"
-            "uint16"
-            "uint32"
-            "uint64"
-            "unativeint"
-          ] |> Set.ofList
-        let tagClass name = if Set.contains name keywordTypes then tag LayoutTag.Keyword name else tag LayoutTag.Class name
-        let tagUnionCase t = tag LayoutTag.UnionCase t
-        let tagDelegate t = tag LayoutTag.Delegate t
-        let tagEnum t = tag LayoutTag.Enum t
-        let tagEvent t = tag LayoutTag.Event t
-        let tagField t = tag LayoutTag.Field t
-        let tagInterface t = tag LayoutTag.Interface t
-        let tagKeyword t = tag LayoutTag.Keyword t
-        let tagLineBreak t = tag LayoutTag.LineBreak t
-        let tagLocal t = tag LayoutTag.Local t
-        let tagRecord t = tag LayoutTag.Record t
-        let tagRecordField t = tag LayoutTag.RecordField t
-        let tagMethod t = tag LayoutTag.Method t
-        let tagModule t = tag LayoutTag.Module t
-        let tagModuleBinding name = if keywordFunctions.Contains name then tag LayoutTag.Keyword name else tag LayoutTag.ModuleBinding name
-        let tagNamespace t = tag LayoutTag.Namespace t
-        let tagNumericLiteral t = tag LayoutTag.NumericLiteral t
-        let tagOperator t = tag LayoutTag.Operator t
-        let tagParameter t = tag LayoutTag.Parameter t
-        let tagProperty t = tag LayoutTag.Property t
-        let tagSpace t = tag LayoutTag.Space t
-        let tagStringLiteral t = tag LayoutTag.StringLiteral t
-        let tagStruct t = tag LayoutTag.Struct t
-        let tagTypeParameter t = tag LayoutTag.TypeParameter t
-        let tagText t = tag LayoutTag.Text t
-        let tagPunctuation t = tag LayoutTag.Punctuation t
-
-        module Literals =
-            // common tagged literals
-            let lineBreak = tagLineBreak "\n"
-            let space = tagSpace " "
-            let comma = tagPunctuation ","
-            let semicolon = tagPunctuation ";"
-            let leftParen = tagPunctuation "("
-            let rightParen = tagPunctuation ")"
-            let leftBracket = tagPunctuation "["
-            let rightBracket = tagPunctuation "]"
-            let leftBrace= tagPunctuation "{"
-            let rightBrace = tagPunctuation "}"
-            let leftBraceBar = tagPunctuation "{|"
-            let rightBraceBar = tagPunctuation "|}"
-            let equals = tagOperator "="
-            let arrow = tagPunctuation "->"
-            let questionMark = tagPunctuation "?"
-     
-    module LayoutOps = 
-        open TaggedTextOps
-
-        let rec juxtLeft = function
-          | ObjLeaf (jl,_,_)      -> jl
-          | Leaf (jl,_,_)         -> jl
-          | Node (jl,_,_,_,_,_) -> jl
-          | Attr (_,_,l)        -> juxtLeft l
-
-        let rec juxtRight = function
-          | ObjLeaf (_,_,jr)         -> jr
-          | Leaf (_,_,jr)         -> jr
-          | Node (_,_,_,_,jr,_) -> jr
-          | Attr (_,_,l)        -> juxtRight l
-
-        let mkNode l r joint =
-           let jl = juxtLeft  l 
-           let jm = juxtRight l || juxtLeft r 
-           let jr = juxtRight r 
-           Node(jl,l,jm,r,jr,joint)
-
-
-        // constructors
-
-
-        let objL (value:obj) = 
-            match value with 
-            | :? string as s -> Leaf (false, tag LayoutTag.Text s, false)
-            | o -> ObjLeaf (false, o, false)
-
-        let sLeaf  (l, t, r) = Leaf (l, t, r)
-
-        let wordL  text = sLeaf (false,text,false)
-        let sepL   text = sLeaf (true ,text,true)   
-        let rightL text = sLeaf (true ,text,false)   
-        let leftL  text = sLeaf (false,text,true)
-
-        let emptyL = sLeaf (true, tag LayoutTag.Text "",true)
-
-        let isEmptyL layout = 
-            match layout with 
-            | Leaf(true, s, true) -> s.Text = ""
-            | _ -> false
-
-        let aboveL  layout1 layout2 = mkNode layout1 layout2 (Broken 0)
-
-        let tagAttrL text maps layout = Attr(text,maps,layout)
-
-        let apply2 f l r = if isEmptyL l then r else
-                           if isEmptyL r then l else f l r
-
-        let (^^)  layout1 layout2  = mkNode layout1 layout2 (Unbreakable)
-        let (++)  layout1 layout2  = mkNode layout1 layout2 (Breakable 0)
-        let (--)  layout1 layout2  = mkNode layout1 layout2 (Breakable 1)
-        let (---) layout1 layout2  = mkNode layout1 layout2 (Breakable 2)
-        let (@@)   layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 0)) layout1 layout2
-        let (@@-)  layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 1)) layout1 layout2
-        let (@@--) layout1 layout2 = apply2 (fun l r -> mkNode l r (Broken 2)) layout1 layout2
-        let tagListL tagger = function
-            | []    -> emptyL
-            | [x]   -> x
-            | x :: xs ->
-                let rec process' prefixL = function
-                  | []    -> prefixL
-                  | y :: ys -> process' ((tagger prefixL) ++ y) ys
-                process' x xs
-            
-        let commaListL layouts = tagListL (fun prefixL -> prefixL ^^ rightL (Literals.comma)) layouts
-        let semiListL layouts  = tagListL (fun prefixL -> prefixL ^^ rightL (Literals.semicolon)) layouts
-        let spaceListL layouts = tagListL (fun prefixL -> prefixL) layouts
-        let sepListL layout1 layouts = tagListL (fun prefixL -> prefixL ^^ layout1) layouts
-        let bracketL layout = leftL Literals.leftParen ^^ layout ^^ rightL Literals.rightParen
-        let tupleL layouts = bracketL (sepListL (sepL Literals.comma) layouts)
-        let aboveListL layouts = 
-            match layouts with
-            | []    -> emptyL
-            | [x]   -> x
-            | x :: ys -> List.fold (fun pre y -> pre @@ y) x ys
-
-        let optionL selector value = 
-            match value with 
-            | None   -> wordL (tagUnionCase "None")
-            | Some x -> wordL (tagUnionCase "Some") -- (selector x)
-
-        let listL selector value = leftL Literals.leftBracket ^^ sepListL (sepL Literals.semicolon) (List.map selector value) ^^ rightL Literals.rightBracket
-
-        let squareBracketL layout = leftL Literals.leftBracket ^^ layout ^^ rightL Literals.rightBracket    
-
-        let braceL         layout = leftL Literals.leftBrace ^^ layout ^^ rightL Literals.rightBrace
-
-        let boundedUnfoldL
-                    (itemL     : 'a -> layout)
-                    (project   : 'z -> ('a * 'z) option)
-                    (stopShort : 'z -> bool)
-                    (z : 'z)
-                    maxLength =
-          let rec consume n z =
-            if stopShort z then [wordL (tagPunctuation "...")] else
-            match project z with
-              | None       -> []  // exhausted input 
-              | Some (x,z) -> if n<=0 then [wordL (tagPunctuation "...")]               // hit print_length limit 
-                                      else itemL x :: consume (n-1) z  // cons recursive... 
-          consume maxLength z  
-
-        let unfoldL selector folder state count = boundedUnfoldL  selector folder (fun _ -> false) state count
-          
-    /// These are a typical set of options used to control structured formatting.
-    []
-    type FormatOptions =
-        { FloatingPointFormat: string;
-          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
-#if COMPILER // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter
-          PrintIntercepts: (IEnvironment -> obj -> Layout option) list;
-          StringLimit : int;
-#endif
-          FormatProvider: System.IFormatProvider;
-          BindingFlags: System.Reflection.BindingFlags
-          PrintWidth : int; 
-          PrintDepth : int; 
-          PrintLength : int;
-          PrintSize : int;        
-          ShowProperties : bool;
-          ShowIEnumerable: bool; }
-        static member Default =
-            { FormatProvider = (System.Globalization.CultureInfo.InvariantCulture :> System.IFormatProvider);
-#if COMPILER    // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter
-              PrintIntercepts = [];
-              StringLimit = System.Int32.MaxValue;
-#endif
-              AttributeProcessor= (fun _ _ _ -> ());
-              BindingFlags = System.Reflection.BindingFlags.Public;
-              FloatingPointFormat = "g10";
-              PrintWidth = 80 ; 
-              PrintDepth = 100 ; 
-              PrintLength = 100;
-              PrintSize = 10000;
-              ShowProperties = false;
-              ShowIEnumerable = true; }
-
-
-
-    module ReflectUtils = 
-
-        []
-        type TypeInfo =
-          | TupleType of Type list
-          | FunctionType of Type * Type
-          | RecordType of (string * Type) list
-          | SumType of (string * (string * Type) list) list
-          | UnitType
-          | ObjectType of Type
-
-        let isNamedType (ty:Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer)
-        let equivHeadTypes (ty1:Type) (ty2:Type) = 
-            isNamedType(ty1) &&
-            if ty1.IsGenericType then 
-              ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
-            else 
-              ty1.Equals(ty2)
-
-        let option = typedefof
-        let func = typedefof<(obj -> obj)>
-
-        let isOptionTy ty = equivHeadTypes ty (typeof)
-        let isUnitType ty = equivHeadTypes ty (typeof)
-        let isListType ty = 
-            FSharpType.IsUnion ty && 
-            (let cases = FSharpType.GetUnionCases ty 
-             cases.Length > 0 && equivHeadTypes (typedefof>) cases.[0].DeclaringType)
-
-        []
-        type ValueInfo =
-          | TupleValue of (obj * Type) list
-          | FunctionClosureValue of System.Type 
-          | RecordValue of (string * obj * Type) list
-          | ConstructorValue of string * (string * (obj * Type)) list
-          | ExceptionValue of System.Type * (string * (obj * Type)) list
-          | UnitValue
-          | ObjectValue of obj
-
-        module Value = 
-
-            // Analyze an object to see if it the representation
-            // of an F# value.
-            let GetValueInfoOfObject (bindingFlags:BindingFlags) (obj : obj) =
-              match obj with 
-              | null -> ObjectValue(obj)
-              | _ -> 
-                let reprty = obj.GetType() 
-
-                // First a bunch of special rules for tuples
-                // Because of the way F# currently compiles tuple values 
-                // of size > 7 we can only reliably reflect on sizes up
-                // to 7.
-
-                if FSharpType.IsTuple reprty then 
-                    let tyArgs = FSharpType.GetTupleElements(reprty)
-                    TupleValue (FSharpValue.GetTupleFields obj |> Array.mapi (fun i v -> (v, tyArgs.[i])) |> Array.toList)
-                elif FSharpType.IsFunction reprty then 
-                    FunctionClosureValue reprty
-                    
-                // It must be exception, abstract, record or union.
-                // Either way we assume the only properties defined on
-                // the type are the actual fields of the type.  Again,
-                // we should be reading attributes here that indicate the
-                // true structure of the type, e.g. the order of the fields.   
-                elif FSharpType.IsUnion(reprty,bindingFlags) then 
-                    let tag,vals = FSharpValue.GetUnionFields (obj,reprty,bindingFlags) 
-                    let props = tag.GetFields()
-                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,(v, prop.PropertyType))
-                    ConstructorValue(tag.Name, Array.toList pvals)
-                elif FSharpType.IsExceptionRepresentation(reprty,bindingFlags) then 
-                    let props = FSharpType.GetExceptionFields(reprty,bindingFlags) 
-                    let vals = FSharpValue.GetExceptionFields(obj,bindingFlags) 
-                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,(v, prop.PropertyType))
-                    ExceptionValue(reprty, pvals |> Array.toList)
-                elif FSharpType.IsRecord(reprty,bindingFlags) then 
-                    let props = FSharpType.GetRecordFields(reprty,bindingFlags) 
-                    RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue(obj,null), prop.PropertyType) |> Array.toList)
-                else
-                    ObjectValue(obj)
-
-            // This one is like the above but can make use of additional
-            // statically-known type information to aid in the
-            // analysis of null values. 
-
-            let GetValueInfo bindingFlags (x : 'a, ty : Type)  (* x could be null *) = 
-                let obj = (box x)
-                match obj with 
-                | null ->
-                   let isNullaryUnion =
-                      match ty.GetCustomAttributes(typeof, false) with
-                      | [|:? CompilationRepresentationAttribute as attr|] -> 
-                          (attr.Flags &&& CompilationRepresentationFlags.UseNullAsTrueValue) = CompilationRepresentationFlags.UseNullAsTrueValue
-                      | _ -> false
-                   if isNullaryUnion then
-                     let nullaryCase = FSharpType.GetUnionCases ty |> Array.filter (fun uc -> uc.GetFields().Length = 0) |> Array.item 0
-                     ConstructorValue(nullaryCase.Name, [])
-                   elif isUnitType ty then UnitValue
-                   else ObjectValue(obj)
-                | _ -> 
-                  GetValueInfoOfObject bindingFlags (obj) 
-
-    module Display = 
-
-        open ReflectUtils
-        open LayoutOps
-        open TaggedTextOps
-
-        let string_of_int (i:int) = i.ToString()
-
-        let typeUsesSystemObjectToString (ty:System.Type) =
-            try
-                let methInfo = ty.GetMethod("ToString",BindingFlags.Public ||| BindingFlags.Instance,null,[| |],null)
-                methInfo.DeclaringType = typeof
-            with e -> false
-        /// If "str" ends with "ending" then remove it from "str", otherwise no change.
-        let trimEnding (ending:string) (str:string) =
-          if str.EndsWith(ending,StringComparison.Ordinal) then 
-              str.Substring(0,str.Length - ending.Length) 
-          else str
-
-        let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e
-
-        // An implementation of break stack.
-        // Uses mutable state, relying on linear threading of the state.
-
-        []
-        type Breaks = 
-            Breaks of
-                int *     // pos of next free slot 
-                int *     // pos of next possible "outer" break - OR - outer=next if none possible 
-                int array // stack of savings, -ve means it has been broken   
-
-        // next  is next slot to push into - aka size of current occupied stack.  
-        // outer counts up from 0, and is next slot to break if break forced.
-        // - if all breaks forced, then outer=next.
-        // - popping under these conditions needs to reduce outer and next.
-        
-
-        //let dumpBreaks prefix (Breaks(next,outer,stack)) = ()
-        //   printf "%s: next=%d outer=%d stack.Length=%d\n" prefix next outer stack.Length;
-        //   stdout.Flush() 
-             
-        let chunkN = 400      
-        let breaks0 () = Breaks(0,0,Array.create chunkN 0)
-
-        let pushBreak saving (Breaks(next,outer,stack)) =
-            //dumpBreaks "pushBreak" (next,outer,stack);
-            let stack = 
-                if next = stack.Length then
-                  Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full 
-                else
-                  stack
-           
-            stack.[next] <- saving;
-            Breaks(next+1,outer,stack)
-
-        let popBreak (Breaks(next,outer,stack)) =
-            //dumpBreaks "popBreak" (next,outer,stack);
-            if next=0 then raise (Failure "popBreak: underflow");
-            let topBroke = stack.[next-1] < 0
-            let outer = if outer=next then outer-1 else outer  // if all broken, unwind 
-            let next  = next - 1
-            Breaks(next,outer,stack),topBroke
-
-        let forceBreak (Breaks(next,outer,stack)) =
-            //dumpBreaks "forceBreak" (next,outer,stack);
-            if outer=next then
-              // all broken 
-                None
-            else
-                let saving = stack.[outer]
-                stack.[outer] <- -stack.[outer];    
-                let outer = outer+1
-                Some (Breaks(next,outer,stack),saving)
-
-        // -------------------------------------------------------------------------
-        // fitting
-        // ------------------------------------------------------------------------
-          
-        let squashTo (maxWidth,leafFormatter : _ -> TaggedText) layout =
-            let (|ObjToTaggedText|) = leafFormatter
-            if maxWidth <= 0 then layout else 
-            let rec fit breaks (pos,layout) =
-                // breaks = break context, can force to get indentation savings.
-                // pos    = current position in line
-                // layout = to fit
-                //------
-                // returns:
-                // breaks
-                // layout - with breaks put in to fit it.
-                // pos    - current pos in line = rightmost position of last line of block.
-                // offset - width of last line of block
-                // NOTE: offset <= pos -- depending on tabbing of last block
-               
-                let breaks,layout,pos,offset =
-                    match layout with
-                    | Attr (tag,attrs,l) ->
-                        let breaks,layout,pos,offset = fit breaks (pos,l) 
-                        let layout = Attr (tag,attrs,layout) 
-                        breaks,layout,pos,offset
-                    | Leaf (jl, text, jr)
-                    | ObjLeaf (jl, ObjToTaggedText text, jr) ->
-                        // save the formatted text from the squash
-                        let layout = Leaf(jl, text, jr) 
-                        let textWidth = length text
-                        let rec fitLeaf breaks pos =
-                          if pos + textWidth <= maxWidth then
-                              breaks,layout,pos + textWidth,textWidth // great, it fits 
-                          else
-                              match forceBreak breaks with
-                              | None                 -> 
-                                  breaks,layout,pos + textWidth,textWidth // tough, no more breaks 
-                              | Some (breaks,saving) -> 
-                                  let pos = pos - saving 
-                                  fitLeaf breaks pos
-                       
-                        fitLeaf breaks pos
-                    | Node (jl,l,jm,r,jr,joint) ->
-                        let mid = if jm then 0 else 1
-                        match joint with
-                        | Unbreakable    ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            let pos = pos + mid                              // fit space if juxt says so 
-                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
-                            breaks,Node (jl,l,jm,r,jr,Unbreakable),pos,offsetl + mid + offsetr
-                        | Broken indent ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            let pos = pos - offsetl + indent                 // broken so - offset left + ident 
-                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
-                            breaks,Node (jl,l,jm,r,jr,Broken indent),pos,indent + offsetr
-                        | Breakable indent ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            // have a break possibility, with saving 
-                            let saving = offsetl + mid - indent
-                            let pos = pos + mid
-                            if saving>0 then
-                                let breaks = pushBreak saving breaks
-                                let breaks,r,pos,offsetr = fit breaks (pos,r)
-                                let breaks,broken = popBreak breaks
-                                if broken then
-                                    breaks,Node (jl,l,jm,r,jr,Broken indent)   ,pos,indent + offsetr
-                                else
-                                    breaks,Node (jl,l,jm,r,jr,Breakable indent),pos,offsetl + mid + offsetr
-                            else
-                                // actually no saving so no break 
-                                let breaks,r,pos,offsetr = fit breaks (pos,r)
-                                breaks,Node (jl,l,jm,r,jr,Breakable indent)  ,pos,offsetl + mid + offsetr
-               
-               //printf "\nDone:     pos=%d offset=%d" pos offset;
-                breaks,layout,pos,offset
-           
-            let breaks = breaks0 ()
-            let pos = 0
-            let _,layout,_,_ = fit breaks (pos,layout)
-            layout
-
-        // -------------------------------------------------------------------------
-        // showL
-        // ------------------------------------------------------------------------
-
-        let combine (strs: string list) = System.String.Concat strs
-        let showL opts leafFormatter layout =
-            let push x rstrs = x :: rstrs
-            let z0 = [],0
-            let addText (rstrs,i) (text:string) = push text rstrs,i + text.Length
-            let index   (_,i)               = i
-            let extract rstrs = combine(List.rev rstrs) 
-            let newLine (rstrs,_) n     = // \n then spaces... 
-                let indent = new System.String(' ', n)
-                let rstrs = push "\n"   rstrs
-                let rstrs = push indent rstrs
-                rstrs,n
-
-            // addL: pos is tab level 
-            let rec addL z pos layout = 
-                match layout with 
-                | ObjLeaf (_,obj,_)                 -> 
-                    let text = leafFormatter obj
-                    addText z text                 
-                | Leaf (_,obj,_)                 -> 
-                    addText z obj.Text
-                | Node (_,l,_,r,_,Broken indent) 
-                     // Print width = 0 implies 1D layout, no squash
-                     when not (opts.PrintWidth = 0)  -> 
-                    let z = addL z pos l
-                    let z = newLine z (pos+indent)
-                    let z = addL z (pos+indent) r
-                    z
-                | Node (_,l,jm,r,_,_)             -> 
-                    let z = addL z pos l
-                    let z = if jm then z else addText z " "
-                    let pos = index z
-                    let z = addL z pos r
-                    z
-                | Attr (_,_,l) ->
-                    addL z pos l
-           
-            let rstrs,_ = addL z0 0 layout
-            extract rstrs
-
-
-        // -------------------------------------------------------------------------
-        // outL
-        // ------------------------------------------------------------------------
-
-        let outL outAttribute leafFormatter (chan : TaggedTextWriter) layout =
-            // write layout to output chan directly 
-            let write s = chan.Write(s)
-            // z is just current indent 
-            let z0 = 0
-            let index i = i
-            let addText z text  = write text;  (z + length text)
-            let newLine _ n     = // \n then spaces... 
-                let indent = new System.String(' ',n)
-                chan.WriteLine();
-                write (tagText indent);
-                n
-                
-            // addL: pos is tab level 
-            let rec addL z pos layout = 
-                match layout with 
-                | ObjLeaf (_,obj,_)                 -> 
-                    let text = leafFormatter obj 
-                    addText z text
-                | Leaf (_,obj,_)                 -> 
-                    addText z obj
-                | Node (_,l,_,r,_,Broken indent) -> 
-                    let z = addL z pos l
-                    let z = newLine z (pos+indent)
-                    let z = addL z (pos+indent) r
-                    z
-                | Node (_,l,jm,r,_,_)             -> 
-                    let z = addL z pos l
-                    let z = if jm then z else addText z Literals.space
-                    let pos = index z
-                    let z = addL z pos r
-                    z 
-                | Attr (tag,attrs,l) ->
-                let _ = outAttribute tag attrs true
-                let z = addL z pos l
-                let _ = outAttribute tag attrs false
-                z
-           
-            let _ = addL z0 0 layout
-            ()
-
-        // --------------------------------------------------------------------
-        // pprinter: using general-purpose reflection...
-        // -------------------------------------------------------------------- 
-          
-        let getValueInfo bindingFlags (x:'a, ty:Type) = Value.GetValueInfo bindingFlags (x, ty)
-
-        let unpackCons recd =
-            match recd with 
-            | [(_,h);(_,t)] -> (h,t)
-            | _             -> failwith "unpackCons"
-
-        let getListValueInfo bindingFlags (x:obj, ty:Type) =
-            match x with 
-            | null -> None 
-            | _ -> 
-                match getValueInfo bindingFlags (x, ty) with
-                | ConstructorValue ("Cons",recd) -> Some (unpackCons recd)
-                | ConstructorValue ("Empty",[]) -> None
-                | _ -> failwith "List value had unexpected ValueInfo"
-
-        let compactCommaListL xs = sepListL (sepL Literals.comma) xs // compact, no spaces around "," 
-        let nullL = wordL (tagKeyword "null")
-        let measureL = wordL (tagPunctuation "()")
-          
-        // --------------------------------------------------------------------
-        // pprinter: attributes
-        // -------------------------------------------------------------------- 
-
-        let makeRecordL nameXs =
-            let itemL (name,xL) = wordL name ^^ wordL Literals.equals -- xL
-            let braceL xs = (wordL Literals.leftBrace) ^^ xs ^^ (wordL Literals.rightBrace)
-            
-            nameXs
-            |> List.map itemL
-            |> aboveListL
-            |> braceL
-
-        let makePropertiesL nameXs =
-            let itemL (name,v) = 
-               let labelL = wordL name 
-               (labelL ^^ wordL Literals.equals)
-               ^^ (match v with 
-                   | None -> wordL Literals.questionMark
-                   | Some xL -> xL)
-               ^^ (rightL Literals.semicolon)
-            let braceL xs = (leftL Literals.leftBrace) ^^ xs ^^ (rightL Literals.rightBrace)
-            braceL (aboveListL (List.map itemL nameXs))
-
-        let makeListL itemLs =
-            (leftL Literals.leftBracket) 
-            ^^ sepListL (rightL Literals.semicolon) itemLs 
-            ^^ (rightL Literals.rightBracket)
-
-        let makeArrayL xs =
-            (leftL (tagPunctuation "[|")) 
-            ^^ sepListL (rightL Literals.semicolon) xs 
-            ^^ (rightL (tagPunctuation "|]"))
-
-        let makeArray2L xs = leftL Literals.leftBracket ^^ aboveListL xs ^^ rightL Literals.rightBracket  
-
-        // --------------------------------------------------------------------
-        // pprinter: anyL - support functions
-        // -------------------------------------------------------------------- 
-
-        let getProperty (ty: Type) (obj: obj) name =
-            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture)
-
-        let getField obj (fieldInfo: FieldInfo) =
-            fieldInfo.GetValue(obj)
-
-        let formatChar isChar c = 
-            match c with 
-            | '\'' when isChar -> "\\\'"
-            | '\"' when not isChar -> "\\\""
-            //| '\n' -> "\\n"
-            //| '\r' -> "\\r"
-            //| '\t' -> "\\t"
-            | '\\' -> "\\\\"
-            | '\b' -> "\\b"
-            | _ when System.Char.IsControl(c) -> 
-                 let d1 = (int c / 100) % 10 
-                 let d2 = (int c / 10) % 10 
-                 let d3 = int c % 10 
-                 "\\" + d1.ToString() + d2.ToString() + d3.ToString()
-            | _ -> c.ToString()
-            
-        let formatString (s:string) =
-            let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) 
-            let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc)  
-            "\"" + s + "\""
-            // REVIEW: should we check for the common case of no control characters? Reinstate the following?
-            //"\"" + (if check 0 then s else conv 0 []) + "\""
-
-        let formatStringInWidth (width:int) (str:string) =
-            // Return a truncated version of the string, e.g.
-            //   "This is the initial text, which has been truncated"+[12 chars]
-            //
-            // Note: The layout code forces breaks based on leaf size and possible break points.
-            //       It does not force leaf size based on width.
-            //       So long leaf-string width can not depend on their printing context...
-            //
-            // The suffix like "+[dd chars]" is 11 chars.
-            //                  12345678901
-            let suffixLength    = 11 // turning point suffix length
-            let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings...
-            let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength
-            "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]"
-
-        // --------------------------------------------------------------------
-        // pprinter: anyL
-        // -------------------------------------------------------------------- 
-                           
-        type Precedence = 
-            | BracketIfTupleOrNotAtomic = 2
-            | BracketIfTuple = 3
-            | NeverBracket = 4
-
-        // In fsi.exe, certain objects are not printed for top-level bindings.
-        []
-        type ShowMode = 
-            | ShowAll 
-            | ShowTopLevelBinding
-
-        // polymorphic and inner recursion limitations prevent us defining polyL in the recursive loop 
-        let polyL bindingFlags (objL: ShowMode -> int -> Precedence -> ValueInfo -> obj -> Layout) showMode i prec  (x:'a ,ty : Type) (* x could be null *) =
-            objL showMode i prec (getValueInfo bindingFlags (x, ty))  (box x) 
-
-        let anyL showMode bindingFlags (opts:FormatOptions) (x:'a, ty:Type) =
-            // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe,
-            // This allows certain outputs, e.g. objects that would print as  to be suppressed, etc. See 4343.
-            // Calls to layout proper sub-objects should pass showMode = ShowAll.
-
-            // Precedences to ensure we add brackets in the right places   
-            
-            // Keep a record of objects encountered along the way
-            let path = Dictionary(10,HashIdentity.Reference)
-
-            // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma.
-            let mutable  size = opts.PrintSize
-            let exceededPrintSize() = size<=0
-            let countNodes n = if size > 0 then size <- size - n else () // no need to keep decrementing (and avoid wrap around) 
-            let stopShort _ = exceededPrintSize() // for unfoldL
-
-            // Recursive descent
-            let rec objL depthLim prec (x:obj, ty:Type) = polyL bindingFlags objWithReprL ShowAll  depthLim prec (x, ty) // showMode for inner expr 
-            and sameObjL depthLim prec (x:obj, ty:Type) = polyL bindingFlags objWithReprL showMode depthLim prec (x, ty) // showMode preserved 
-
-            and objWithReprL showMode depthLim prec (info:ValueInfo) (x:obj) (* x could be null *) =
-                try
-                  if depthLim<=0 || exceededPrintSize() then wordL (tagPunctuation "...") else
-                  match x with 
-                  | null -> 
-                    reprL showMode (depthLim-1) prec info x
-                  | _    ->
-                    if (path.ContainsKey(x)) then 
-                       wordL (tagPunctuation "...")
-                    else 
-                        path.Add(x,0);
-                        let res = 
-                          // Lazy values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case.
-                          let ty = x.GetType()
-                          if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof> then
-                            Some (wordL (tagText(x.ToString())))
-                          else
-                            // Try the StructuredFormatDisplayAttribute extensibility attribute
-                            match ty.GetCustomAttributes (typeof, true) with
-                            | null | [| |] -> None
-                            | res -> 
-                               let attr = (res.[0] :?> StructuredFormatDisplayAttribute) 
-                               let txt = attr.Value
-                               if isNull txt || txt.Length <= 1 then  
-                                   None
-                               else
-                                  let messageRegexPattern = @"^(?
.*?)(?.*?)(?.*)$"
-                                  let illFormedBracketPattern = @"(?  
-                                        // there isn't a match on the regex looking for a property, so now let's make sure we don't have an ill-formed format string (i.e. mismatched/stray brackets)
-                                        let illFormedMatch = System.Text.RegularExpressions.Regex.IsMatch(txt, illFormedBracketPattern)
-                                        match illFormedMatch with
-                                        | true -> None // there are mismatched brackets, bail out
-                                        | false when layouts.Length > 1 -> Some (spaceListL (List.rev ((wordL (tagText(replaceEscapedBrackets(txt))) :: layouts))))
-                                        | false -> Some (wordL (tagText(replaceEscapedBrackets(txt))))
-                                      | true ->
-                                        // we have a hit on a property reference
-                                        let preText = replaceEscapedBrackets(m.Groups.["pre"].Value) // everything before the first opening bracket
-                                        let postText = m.Groups.["post"].Value // Everything after the closing bracket
-                                        let prop = replaceEscapedBrackets(m.Groups.["prop"].Value) // Unescape everything between the opening and closing brackets
-
-                                        match catchExn (fun () -> getProperty ty x prop) with
-                                          | Choice2Of2 e -> Some (wordL (tagText("")))
-                                          | Choice1Of2 alternativeObj ->
-                                              try 
-                                                  let alternativeObjL = 
-                                                    match alternativeObj with 
-                                                        // A particular rule is that if the alternative property
-                                                        // returns a string, we turn off auto-quoting and escaping of
-                                                        // the string, i.e. just treat the string as display text.
-                                                        // This allows simple implementations of 
-                                                        // such as
-                                                        //
-                                                        //    []
-                                                        //    type BigInt(signInt:int, v : BigNat) =
-                                                        //        member x.StructuredDisplayString = x.ToString()
-                                                        //
-                                                        | :? string as s -> sepL (tagText s)
-                                                        | _ -> 
-                                                          // recursing like this can be expensive, so let's throttle it severely
-                                                          sameObjL (depthLim/10) Precedence.BracketIfTuple (alternativeObj, alternativeObj.GetType())
-                                                  countNodes 0 // 0 means we do not count the preText and postText 
-
-                                                  let postTextMatch = System.Text.RegularExpressions.Regex.Match(postText, messageRegexPattern)
-                                                  // the postText for this node will be everything up to the next occurrence of an opening brace, if one exists
-                                                  let currentPostText =
-                                                    match postTextMatch.Success with
-                                                      | false -> postText 
-                                                      | true -> postTextMatch.Groups.["pre"].Value
-
-                                                  let newLayouts = (sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText currentPostText)) :: layouts
-                                                  match postText with
-                                                    | "" ->
-                                                      //We are done, build a space-delimited layout from the collection of layouts we've accumulated
-                                                      Some (spaceListL (List.rev newLayouts))
-                                                    | remainingPropertyText when postTextMatch.Success ->
-                                                      
-                                                      // look for stray brackets in the text before the next opening bracket
-                                                      let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(postTextMatch.Groups.["pre"].Value, illFormedBracketPattern)
-                                                      match strayClosingMatch with
-                                                      | true -> None
-                                                      | false -> 
-                                                        // More to process, keep going, using the postText starting at the next instance of a '{'
-                                                        let openingBracketIndex = postTextMatch.Groups.["prop"].Index-1
-                                                        buildObjMessageL remainingPropertyText.[openingBracketIndex..] newLayouts
-                                                    | remaingPropertyText ->
-                                                      // make sure we don't have any stray brackets
-                                                      let strayClosingMatch = System.Text.RegularExpressions.Regex.IsMatch(remaingPropertyText, illFormedBracketPattern)
-                                                      match strayClosingMatch with
-                                                      | true -> None
-                                                      | false ->
-                                                        // We are done, there's more text but it doesn't contain any more properties, we need to remove escaped brackets now though
-                                                        // since that wasn't done when creating currentPostText
-                                                        Some (spaceListL (List.rev ((sepL (tagText preText) ^^ alternativeObjL ^^ sepL (tagText(replaceEscapedBrackets(remaingPropertyText)))) :: layouts)))
-                                              with _ -> 
-                                                None
-                                  // Seed with an empty layout with a space to the left for formatting purposes
-                                  buildObjMessageL txt [leftL (tagText "")] 
-#if COMPILER    // This is the PrintIntercepts extensibility point currently revealed by fsi.exe's AddPrinter
-                        let res = 
-                            match res with 
-                            | Some _ -> res
-                            | None -> 
-                                let env = { new IEnvironment with
-                                                member env.GetLayout(y) = objL (depthLim-1) Precedence.BracketIfTuple (y, y.GetType()) 
-                                                member env.MaxColumns = opts.PrintLength
-                                                member env.MaxRows = opts.PrintLength }
-                                opts.PrintIntercepts |> List.tryPick (fun intercept -> intercept env x)
-#endif
-                        let res = 
-                            match res with 
-                            | Some res -> res
-                            | None     -> reprL showMode (depthLim-1) prec info x
-                        path .Remove(x) |> ignore;
-                        res
-                with
-                  e ->
-                    countNodes 1
-                    wordL (tagText("Error: " + e.Message))
-
-            and recdAtomicTupleL depthLim recd =
-                // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
-                match recd with 
-                | [(_,x)] -> objL depthLim Precedence.BracketIfTupleOrNotAtomic x 
-                | txs     -> leftL Literals.leftParen ^^ compactCommaListL (List.map (snd >> objL depthLim Precedence.BracketIfTuple) txs) ^^ rightL Literals.rightParen
-
-            and bracketIfL b basicL =
-                if b then (leftL Literals.leftParen) ^^ basicL ^^ (rightL Literals.rightParen) else basicL
-
-            and reprL showMode depthLim prec repr x (* x could be null *) =
-                let showModeFilter lay = match showMode with ShowAll -> lay | ShowTopLevelBinding -> emptyL                                                             
-                match repr with 
-                | TupleValue vals -> 
-                    let basicL = sepListL (rightL Literals.comma) (List.map (objL depthLim Precedence.BracketIfTuple ) vals)
-                    bracketIfL (prec <= Precedence.BracketIfTuple) basicL 
-
-                | RecordValue items -> 
-                    let itemL (name,x,ty) =
-                      countNodes 1 // record labels are counted as nodes. [REVIEW: discussion under 4090].
-                      (tagRecordField name,objL depthLim Precedence.BracketIfTuple (x, ty))
-                    makeRecordL (List.map itemL items)
-
-                | ConstructorValue (constr,recd) when // x is List. Note: "null" is never a valid list value. 
-                                                      x<>null && isListType (x.GetType()) ->
-                    match constr with 
-                    | "Cons" -> 
-                        let (x,xs) = unpackCons recd
-                        let project xs = getListValueInfo bindingFlags xs
-                        let itemLs = objL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
-                        makeListL itemLs
-                    | _ ->
-                        countNodes 1
-                        wordL (tagPunctuation "[]")
-
-                | ConstructorValue(nm,[])   ->
-                    countNodes 1
-                    (wordL (tagMethod nm))
-
-                | ConstructorValue(nm,recd) ->
-                    countNodes 1 // e.g. Some (Some (Some (Some 2))) should count for 5 
-                    (wordL (tagMethod nm) --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-
-                | ExceptionValue(ty,recd) ->
-                    countNodes 1
-                    let name = ty.Name 
-                    match recd with
-                      | []   -> (wordL (tagClass name))
-                      | recd -> (wordL (tagClass name) --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-
-                | FunctionClosureValue ty ->
-                    // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
-                    countNodes 1
-                    wordL (tagText("")) |> showModeFilter
-
-                | ObjectValue(obj)  ->
-                    match obj with 
-                    | null -> (countNodes 1; nullL)
-                    | _ -> 
-                    let ty = obj.GetType()
-                    match obj with 
-                    | :? string as s ->
-                        countNodes 1
-#if COMPILER  
-                        if s.Length + 2(*quotes*) <= opts.StringLimit then
-                           // With the quotes, it fits within the limit.
-                           wordL (tagStringLiteral(formatString s))
-                        else
-                           // When a string is considered too long to print, there is a choice: what to print?
-                           // a)             -- follows 
-                           // b)      -- follows  and gives just the length
-                           // c) "abcdefg"+[n chars] -- gives a prefix and the remaining chars
-                           wordL (tagStringLiteral(formatStringInWidth opts.StringLimit s))
-#else
-                        wordL (tagStringLiteral (formatString s))  
-#endif                        
-                    | :? Array as arr -> 
-                        let ty = arr.GetType().GetElementType()
-                        match arr.Rank with
-                        | 1 -> 
-                             let n = arr.Length
-                             let b1 = arr.GetLowerBound(0) 
-                             let project depthLim = if depthLim=(b1+n) then None else Some ((box (arr.GetValue(depthLim)), ty),depthLim+1)
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
-                             makeArrayL (if b1 = 0 then itemLs else wordL (tagText("bound1="+string_of_int b1)) :: itemLs)
-                        | 2 -> 
-                             let n1 = arr.GetLength(0)
-                             let n2 = arr.GetLength(1)
-                             let b1 = arr.GetLowerBound(0) 
-                             let b2 = arr.GetLowerBound(1) 
-                             let project2 x y =
-                               if x>=(b1+n1) || y>=(b2+n2) then None
-                               else Some ((box (arr.GetValue(x,y)), ty),y+1)
-                             let rowL x = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
-                             let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
-                             let rowsL  = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
-                             makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL (tagText("bound1=" + string_of_int b1)) :: wordL(tagText("bound2=" + string_of_int b2)) :: rowsL)
-                          | n -> 
-                             makeArrayL [wordL (tagText("rank=" + string_of_int n))]
-                        
-                    // Format 'set' and 'map' nicely
-                    | _ when  
-                          (ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof> 
-                                                || ty.GetGenericTypeDefinition() = typedefof>) ) ->
-                         let word = if ty.GetGenericTypeDefinition() = typedefof> then "map" else "set"
-                         let possibleKeyValueL v = 
-                             let tyv = v.GetType()
-                             if word = "map" &&
-                                (match v with null -> false | _ -> true) && 
-                                tyv.IsGenericType && 
-                                tyv.GetGenericTypeDefinition() = typedefof> then
-                                  objL depthLim Precedence.BracketIfTuple ((tyv.GetProperty("Key").GetValue(v, [| |]), 
-                                                                            tyv.GetProperty("Value").GetValue(v, [| |])), tyv)
-                             else
-                                  objL depthLim Precedence.BracketIfTuple (v, tyv)
-                         let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
-                         try 
-                           let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
-                           (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                         finally 
-                            match it with 
-                            | :? System.IDisposable as e -> e.Dispose()
-                            | _ -> ()
-
-                    | :? System.Collections.IEnumerable as ie ->
-                         let showContent = 
-                            // do not display content of IQueryable since its execution may take significant time
-                            opts.ShowIEnumerable && (ie.GetType().GetInterfaces() |> Array.exists(fun ty -> ty.FullName = "System.Linq.IQueryable") |> not)
-
-                         if showContent then
-                           let word = "seq"
-                           let it = ie.GetEnumerator() 
-                           let ty = ie.GetType().GetInterfaces() |> Array.filter (fun ty -> ty.IsGenericType && ty.Name = "IEnumerable`1") |> Array.tryItem 0
-                           let ty = Option.map (fun (ty:Type) -> ty.GetGenericArguments().[0]) ty
-                           try 
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some((it.Current, match ty with | None -> it.Current.GetType() | Some ty -> ty),()) else None) stopShort () (1+opts.PrintLength/30)
-                             (wordL (tagClass word) --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                           finally 
-                              match it with 
-                              | :? System.IDisposable as e -> e.Dispose()
-                              | _ -> ()
-                             
-                         else
-                           // Sequence printing is turned off for declared-values, and maybe be disabled to users.
-                           // There is choice here, what to print?  or ... or ?
-                           // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
-                           wordL (tagText "") |> showModeFilter
-                    | _ ->
-                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString ty then
-                           emptyL
-                         else
-                           countNodes 1
-                           let basicL = LayoutOps.objL obj  // This buries an obj in the layout, rendered at squash time via a leafFormatter.
-                                                            // If the leafFormatter was directly here, then layout leaves could store strings.
-                           match obj with 
-                           | _ when opts.ShowProperties ->
-                              let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
-                              let fields = ty.GetFields(BindingFlags.Instance ||| BindingFlags.Public) |> Array.map (fun i -> i :> MemberInfo)
-                              let propsAndFields = 
-                                props |> Array.map (fun i -> i :> MemberInfo)
-                                      |> Array.append fields
-                                      |> Array.filter (fun pi ->
-                                    // check if property is annotated with System.Diagnostics.DebuggerBrowsable(Never). 
-                                    // Its evaluation may have unexpected side effects and\or block printing.
-                                    match Seq.toArray (pi.GetCustomAttributes(typeof, false)) with
-                                    | [|:? System.Diagnostics.DebuggerBrowsableAttribute as attr |] -> attr.State <> System.Diagnostics.DebuggerBrowsableState.Never
-                                    | _ -> true
-                                )
-
-                              // massively reign in deep printing of properties 
-                              let nDepth = depthLim/10
-#if NETSTANDARD
-                              Array.Sort((propsAndFields),{ new IComparer with member this.Compare(p1,p2) = compare (p1.Name) (p2.Name) } )
-#else
-                              Array.Sort((propsAndFields :> Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> MemberInfo).Name) ((p2 :?> MemberInfo).Name) } )
-#endif
-
-                              if propsAndFields.Length = 0 || (nDepth <= 0) then basicL 
-                              else basicL --- 
-                                     (propsAndFields 
-                                      |> Array.map 
-                                        (fun m -> 
-                                            ((if m :? FieldInfo then tagField m.Name else tagProperty m.Name),
-                                                (try Some (objL nDepth Precedence.BracketIfTuple ((getProperty ty obj m.Name), ty)) 
-                                                 with _ -> try Some (objL nDepth Precedence.BracketIfTuple ((getField obj (m :?> FieldInfo)), ty)) 
-                                                           with _ -> None)))
-                                      |> Array.toList 
-                                      |> makePropertiesL)
-                           | _ -> basicL 
-                | UnitValue -> countNodes 1; measureL
-
-            polyL bindingFlags objWithReprL showMode opts.PrintDepth Precedence.BracketIfTuple (x, ty)
-
-        // --------------------------------------------------------------------
-        // pprinter: leafFormatter
-        // --------------------------------------------------------------------
-
-        let leafFormatter (opts:FormatOptions) (obj :obj) =
-            match obj with 
-            | null -> tagKeyword "null"
-            | :? double as d -> 
-                let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
-                let t = 
-                    if System.Double.IsNaN(d) then "nan"
-                    elif System.Double.IsNegativeInfinity(d) then "-infinity"
-                    elif System.Double.IsPositiveInfinity(d) then "infinity"
-                    elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
-                    then s + ".0" 
-                    else s
-                tagNumericLiteral t
-            | :? single as d -> 
-                let t =
-                    (if System.Single.IsNaN(d) then "nan"
-                     elif System.Single.IsNegativeInfinity(d) then "-infinity"
-                     elif System.Single.IsPositiveInfinity(d) then "infinity"
-                     elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
-                      && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
-                      && float32(int32(d)) = d 
-                     then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
-                     else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
-                    + "f"
-                tagNumericLiteral t
-            | :? System.Decimal as d -> d.ToString("g",opts.FormatProvider) + "M" |> tagNumericLiteral
-            | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL" |> tagNumericLiteral
-            | :? int64  as d -> d.ToString(opts.FormatProvider) + "L" |> tagNumericLiteral
-            | :? int32  as d -> d.ToString(opts.FormatProvider) |> tagNumericLiteral
-            | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u" |> tagNumericLiteral
-            | :? int16  as d -> d.ToString(opts.FormatProvider) + "s" |> tagNumericLiteral
-            | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us" |> tagNumericLiteral
-            | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y" |> tagNumericLiteral
-            | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy" |> tagNumericLiteral
-            | :? nativeint as d -> d.ToString() + "n" |> tagNumericLiteral
-            | :? unativeint  as d -> d.ToString() + "un" |> tagNumericLiteral
-            | :? bool   as b -> (if b then "true" else "false") |> tagKeyword
-            | :? char   as c -> "\'" + formatChar true c + "\'" |> tagStringLiteral
-            | _ -> 
-                let t = 
-                    try 
-                        let text = obj.ToString()
-                        match text with
-                        | null -> ""
-                        | _ -> text
-                    with e ->
-                     // If a .ToString() call throws an exception, catch it and use the message as the result.
-                     // This may be informative, e.g. division by zero etc...
-                     "" 
-                tagText t
-
-        let any_to_layout opts x = anyL ShowAll BindingFlags.Public opts x
-
-        let squash_layout opts l = 
-            // Print width = 0 implies 1D layout, no squash
-            if opts.PrintWidth = 0 then 
-                l 
-            else 
-                l |> squashTo (opts.PrintWidth,leafFormatter opts)
-
-        let asTaggedTextWriter (tw: TextWriter) =
-            { new TaggedTextWriter with
-                member __.Write(t) = tw.Write t.Text
-                member __.WriteLine() = tw.WriteLine() }
-
-        let output_layout_tagged opts oc l = 
-            l |> squash_layout opts 
-              |> outL opts.AttributeProcessor (leafFormatter opts) oc
-
-        let output_layout opts oc l = 
-            output_layout_tagged opts (asTaggedTextWriter oc) l
-
-        let layout_to_string options layout = 
-            layout |> squash_layout options 
-              |> showL options ((leafFormatter options) >> toText)
-
-        let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
-
-        let output_any writer x = output_any_ex FormatOptions.Default writer x
-
-        let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
-
-        let any_to_string x = layout_as_string FormatOptions.Default x
-
-#if COMPILER
-        /// Called 
-        let fsi_any_to_layout opts x = anyL ShowTopLevelBinding BindingFlags.Public opts x
-#else
-// FSharp.Core
-        let internal anyToStringForPrintf options (bindingFlags:BindingFlags) x = 
-            x |> anyL ShowAll bindingFlags options |> layout_to_string options
-#endif
-
diff --git a/src/utils/sformat.fsi b/src/utils/sformat.fsi
deleted file mode 100644
index e6ff9762bb5..00000000000
--- a/src/utils/sformat.fsi
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
-
-// This file is compiled 2(!) times in the codebase
-//    - as the internal implementation of printf '%A' formatting 
-//           defines: FSHARP_CORE
-//    - as the internal implementation of structured formatting in FSharp.Compiler.Service.dll 
-//           defines: COMPILER 
-//           NOTE: this implementation is used by fsi.exe. This is very important.
-//
-// The one implementation file is used because we very much want to keep the implementations of
-// structured formatting the same for fsi.exe and '%A' printing. However fsi.exe may have
-// a richer feature set.
-//
-// Note no layout objects are ever transferred between the above implementations, and in 
-// all 4 cases the layout types are really different types.
-
-#if COMPILER
-// fsc.exe:
-// FSharp.Compiler.Service.dll:
-namespace Internal.Utilities.StructuredFormat
-#else
-// FSharp.Core.dll:
-namespace Microsoft.FSharp.Text.StructuredPrintfImpl
-#endif
-
-    open System
-    open System.IO
-    open Microsoft.FSharp.Core
-    open Microsoft.FSharp.Collections
-    open Microsoft.FSharp.Primitives.Basics
-
-    /// Data representing structured layouts of terms.  
-#if FSHARP_CORE  // FSharp.Core.dll makes things internal and hides representations
-    type internal Layout
-    type internal LayoutTag
-    type internal TaggedText =
-        abstract Tag: LayoutTag
-        abstract Text: string
-#else  // FSharp.Compiler.Service.dll, fsc.exe
-
-    /// Data representing joints in structured layouts of terms.  The representation
-    /// of this data type is only for the consumption of formatting engines.
-    []
-    type public Joint =
-        | Unbreakable
-        | Breakable of int
-        | Broken of int
-    
-    []
-    type public LayoutTag =
-        | ActivePatternCase
-        | ActivePatternResult
-        | Alias
-        | Class
-        | Union
-        | UnionCase
-        | Delegate
-        | Enum
-        | Event
-        | Field
-        | Interface
-        | Keyword
-        | LineBreak
-        | Local
-        | Record
-        | RecordField
-        | Method
-        | Member
-        | ModuleBinding
-        | Module
-        | Namespace
-        | NumericLiteral
-        | Operator
-        | Parameter
-        | Property
-        | Space
-        | StringLiteral
-        | Struct
-        | TypeParameter
-        | Text
-        | Punctuation
-        | UnknownType
-        | UnknownEntity
-
-    type public TaggedText =
-        abstract Tag : LayoutTag
-        abstract Text : string
-
-    
-    type public TaggedTextWriter =
-        abstract Write: t: TaggedText -> unit
-        abstract WriteLine: unit -> unit
-
-    /// Data representing structured layouts of terms.  The representation
-    /// of this data type is only for the consumption of formatting engines.
-    []
-    type public Layout =
-     | ObjLeaf of bool * obj * bool
-     | Leaf of bool * TaggedText * bool
-     | Node of bool * Layout * bool * Layout * bool * Joint
-     | Attr of string * (string * string) list * Layout
-#endif
-
-#if COMPILER
-    module public TaggedTextOps =
-#else
-    module internal TaggedTextOps =
-#endif
-        val tag : LayoutTag -> string -> TaggedText
-        val keywordFunctions : Set
-        val tagAlias : string -> TaggedText
-        val tagClass : string -> TaggedText
-        val tagUnionCase : string -> TaggedText
-        val tagDelegate : string -> TaggedText
-        val tagEnum : string -> TaggedText
-        val tagEvent : string -> TaggedText
-        val tagField : string -> TaggedText
-        val tagInterface : string -> TaggedText
-        val tagKeyword : string -> TaggedText
-        val tagLineBreak : string -> TaggedText
-        val tagMethod : string -> TaggedText
-        val tagModuleBinding : string -> TaggedText
-        val tagLocal : string -> TaggedText
-        val tagRecord : string -> TaggedText
-        val tagRecordField : string -> TaggedText
-        val tagModule : string -> TaggedText
-        val tagNamespace : string -> TaggedText
-        val tagNumericLiteral : string -> TaggedText
-        val tagOperator : string -> TaggedText
-        val tagParameter : string -> TaggedText
-        val tagProperty : string -> TaggedText
-        val tagSpace : string -> TaggedText
-        val tagStringLiteral : string -> TaggedText
-        val tagStruct : string -> TaggedText
-        val tagTypeParameter : string -> TaggedText
-        val tagText : string -> TaggedText
-        val tagPunctuation : string -> TaggedText
-
-        module Literals =
-            // common tagged literals
-            val lineBreak : TaggedText
-            val space : TaggedText
-            val comma : TaggedText
-            val semicolon : TaggedText
-            val leftParen : TaggedText
-            val rightParen : TaggedText
-            val leftBracket : TaggedText
-            val rightBracket : TaggedText
-            val leftBrace: TaggedText
-            val rightBrace : TaggedText
-            val leftBraceBar: TaggedText
-            val rightBraceBar : TaggedText
-            val equals : TaggedText
-            val arrow : TaggedText
-            val questionMark : TaggedText
-
-#if COMPILER
-    type public IEnvironment = 
-        /// Return to the layout-generation 
-        /// environment to layout any otherwise uninterpreted object
-        abstract GetLayout : obj -> Layout
-        /// The maximum number of elements for which to generate layout for 
-        /// list-like structures, or columns in table-like 
-        /// structures.  -1 if no maximum.
-        abstract MaxColumns : int
-        /// The maximum number of rows for which to generate layout for table-like 
-        /// structures.  -1 if no maximum.
-        abstract MaxRows : int
-#endif
-      
-    /// A layout is a sequence of strings which have been joined together.
-    /// The strings are classified as words, separators and left and right parenthesis.
-    /// This classification determines where spaces are inserted.
-    /// A joint is either unbreakable, breakable or broken.
-    /// If a joint is broken the RHS layout occurs on the next line with optional indentation.
-    /// A layout can be squashed to for given width which forces breaks as required.
-#if COMPILER
-    module public LayoutOps =
-#else
-    module internal LayoutOps =
-#endif
-
-        /// The empty layout
-        val emptyL     : Layout
-
-        /// Is it the empty layout?
-        val isEmptyL   : layout:Layout -> bool
-
-        /// An uninterpreted leaf, to be interpreted into a string
-        /// by the layout engine. This allows leaf layouts for numbers, strings and
-        /// other atoms to be customized according to culture.
-        val objL       : value:obj -> Layout
-
-        /// An string leaf 
-        val wordL      : text:TaggedText -> Layout
-
-        /// An string which requires no spaces either side.
-        val sepL       : text:TaggedText -> Layout
-
-        /// An string which is right parenthesis (no space on the left).
-        val rightL     : text:TaggedText -> Layout
-
-        /// An string which is left  parenthesis (no space on the right).
-        val leftL      : text:TaggedText -> Layout
-
-        /// Join, unbreakable. 
-        val ( ^^ )     : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join, possible break with indent=0
-        val ( ++ )     : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join, possible break with indent=1
-        val ( -- )     : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join, possible break with indent=2 
-        val ( --- )    : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join broken with ident=0
-        val ( @@ )     : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join broken with ident=1 
-        val ( @@- )    : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join broken with ident=2 
-        val ( @@-- )   : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join layouts into a comma separated list.
-        val commaListL : layouts:Layout list -> Layout
-          
-        /// Join layouts into a space separated list.    
-        val spaceListL : layouts:Layout list -> Layout
-          
-        /// Join layouts into a semi-colon separated list.
-        val semiListL  : layouts:Layout list -> Layout
-
-        /// Join layouts into a list separated using the given Layout.
-        val sepListL   : layout1:Layout -> layouts:Layout list -> Layout
-
-        /// Wrap round brackets around Layout.
-        val bracketL   : layout:Layout -> Layout
-
-        /// Wrap square brackets around layout.    
-        val squareBracketL   : layout:Layout -> Layout
-
-        /// Wrap braces around layout.        
-        val braceL     : layout:Layout -> Layout
-
-        /// Form tuple of layouts.            
-        val tupleL     : layouts:Layout list -> Layout
-
-        /// Layout two vertically.
-        val aboveL     : layout1:Layout -> layout2:Layout -> Layout
-
-        /// Layout list vertically.    
-        val aboveListL : layouts:Layout list -> Layout
-
-        /// Layout like an F# option.
-        val optionL    : selector:('T -> Layout) -> value:'T option -> Layout
-
-        /// Layout like an F# list.    
-        val listL      : selector:('T -> Layout) -> value:'T list   -> Layout
-
-        /// See tagL
-        val tagAttrL : text:string -> maps:(string * string) list -> layout:Layout -> Layout
-
-        /// For limiting layout of list-like sequences (lists,arrays,etc).
-        /// unfold a list of items using (project and z) making layout list via itemL.
-        /// If reach maxLength (before exhausting) then truncate.
-        val unfoldL : selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
-
-    /// A record of options to control structural formatting.
-    /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
-    /// value.
-    /// 
-    /// Floating Point format given in the same format accepted by System.Double.ToString,
-    /// e.g. f6 or g15.
-    ///
-    /// If ShowProperties is set the printing process will evaluate properties of the values being
-    /// displayed.  This may cause additional computation.  
-    ///
-    /// The ShowIEnumerable is set the printing process will force the evaluation of IEnumerable objects
-    /// to a small, finite depth, as determined by the printing parameters.
-    /// This may lead to additional computation being performed during printing.
-    ///
-    /// 
-    /// From F# Interactive the default settings can be adjusted using, for example, 
-    /// 
-    ///   open FSharp.Compiler.Interactive.Settings;;
-    ///   setPrintWidth 120;;
-    /// 
- ///
- [] -#if COMPILER - type public FormatOptions = -#else - type internal FormatOptions = -#endif - { FloatingPointFormat: string - AttributeProcessor: (string -> (string * string) list -> bool -> unit); -#if COMPILER // FSharp.Core.dll: PrintIntercepts aren't used there - PrintIntercepts: (IEnvironment -> obj -> Layout option) list; - StringLimit: int; -#endif - FormatProvider: System.IFormatProvider - BindingFlags: System.Reflection.BindingFlags - PrintWidth : int - PrintDepth : int - PrintLength : int - PrintSize : int - ShowProperties : bool - ShowIEnumerable: bool } - static member Default : FormatOptions - -#if COMPILER - module public Display = -#else - module internal Display = -#endif - - /// Convert any value to a string using a standard formatter - /// Data is typically formatted in a structured format, e.g. - /// lists are formatted using the "[1;2]" notation. - /// The details of the format are not specified and may change - /// from version to version and according to the flags given - /// to the F# compiler. The format is intended to be human-readable, - /// not machine readable. If alternative generic formats are required - /// you should develop your own formatter, using the code in the - /// implementation of this file as a starting point. - /// - /// Data from other .NET languages is formatted using a virtual - /// call to Object.ToString() on the boxed version of the input. - val any_to_string: value:'T * Type -> string - - /// Output any value to a channel using the same set of formatting rules - /// as any_to_string - val output_any: writer:TextWriter -> value:'T * Type -> unit - -#if FSHARP_CORE // FSharp.Core.dll: Most functions aren't needed in FSharp.Core.dll, but we add one entry for printf - - val anyToStringForPrintf: options:FormatOptions -> bindingFlags:System.Reflection.BindingFlags -> value:'T * Type -> string -#else - val asTaggedTextWriter: writer: TextWriter -> TaggedTextWriter - val any_to_layout : options:FormatOptions -> value:'T * Type -> Layout - val squash_layout : options:FormatOptions -> layout:Layout -> Layout - val output_layout_tagged : options:FormatOptions -> writer:TaggedTextWriter -> layout:Layout -> unit - val output_layout : options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit - val layout_as_string: options:FormatOptions -> value:'T * Type -> string -#endif - - /// Convert any value to a layout using the given formatting options. The - /// layout can then be processed using formatting display engines such as - /// those in the LayoutOps module. any_to_string and output_any are - /// built using any_to_layout with default format options. - val layout_to_string: options:FormatOptions -> layout:Layout -> string - - -#if COMPILER - val fsi_any_to_layout : options:FormatOptions -> value:'T * Type -> Layout -#endif diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index e28338a5d44..14437118703 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -1,12 +1,3 @@ - - - - - - - - - diff --git a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.DesignTime/BasicProvider.DesignTime.fsproj b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.DesignTime/BasicProvider.DesignTime.fsproj index 6168ff5fec7..2c4b50ebfe1 100644 --- a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.DesignTime/BasicProvider.DesignTime.fsproj +++ b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.DesignTime/BasicProvider.DesignTime.fsproj @@ -2,10 +2,11 @@ Library - netcoreapp3.0;net461 + net5.0;net472 typeproviders NO_GENERATIVE IS_DESIGNTIME + $(FSharpCoreShippedPackageVersionProperty) diff --git a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj index 409bc2e0649..9cdc0f0871f 100644 --- a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj +++ b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/BasicProvider.Tests.fsproj @@ -2,11 +2,11 @@ Library - netcoreapp3.0 + net5.0 $(TestTargetFramework) false NO_GENERATIVE - None + $(FSharpCoreShippedPackageVersionProperty) @@ -20,7 +20,7 @@ content\myfiles\ - + diff --git a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/NuGet.config b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/NuGet.config index 82abc6e8d3e..261d597dfa2 100644 --- a/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/NuGet.config +++ b/tests/EndToEndBuildTests/BasicProvider/BasicProvider.Tests/NuGet.config @@ -3,6 +3,6 @@ - + diff --git a/tests/EndToEndBuildTests/BasicProvider/BasicProvider/BasicProvider.fsproj b/tests/EndToEndBuildTests/BasicProvider/BasicProvider/BasicProvider.fsproj index 2e1f52d9819..0a913ce47fa 100644 --- a/tests/EndToEndBuildTests/BasicProvider/BasicProvider/BasicProvider.fsproj +++ b/tests/EndToEndBuildTests/BasicProvider/BasicProvider/BasicProvider.fsproj @@ -2,8 +2,9 @@ Library - netcoreapp3.0;net461 + net5.0;net472 typeproviders + $(FSharpCoreShippedPackageVersionProperty) typeproviders diff --git a/tests/EndToEndBuildTests/BasicProvider/TestBasicProvider.cmd b/tests/EndToEndBuildTests/BasicProvider/TestBasicProvider.cmd index 64e5613683b..2abd059cc48 100644 --- a/tests/EndToEndBuildTests/BasicProvider/TestBasicProvider.cmd +++ b/tests/EndToEndBuildTests/BasicProvider/TestBasicProvider.cmd @@ -8,6 +8,22 @@ rem setlocal set __scriptpath=%~dp0 +set configuration=Debug + +:parseargs +if "%1" == "" goto argsdone +if /i "%1" == "-c" goto set_configuration + +echo Unsupported argument: %1 +goto failure + +:set_configuration +set configuration=%2 +shift +shift +goto parseargs + +:argsdone pushd %__scriptpath% rem @@ -18,17 +34,17 @@ rem if not '%NUGET_PACKAGES%' == '' rd %NUGET_PACKAGES%\BasicProvider /s /q taskkill /F /IM dotnet.exe -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=net40 + dotnet pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 + dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr + dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure rem rem Build typeprovider package with coreclr compiler @@ -36,17 +52,17 @@ rem Test it with both desktop and coreclr compilers rem if not '%NUGET_PACKAGES%' == '' rd %NUGET_PACKAGES%\BasicProvider /s /q -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=coreclr + dotnet pack BasicProvider\BasicProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure -@echo%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 + dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test BasicProvider.Tests\BasicProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr + dotnet test BasicProvider.Tests\BasicProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure :success endlocal diff --git a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj index b39eb58e569..67465332994 100644 --- a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj +++ b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/ComboProvider.Tests.fsproj @@ -2,11 +2,11 @@ Library - netcoreapp3.0 + net5.0 $(TestTargetFramework) false + $(FSharpCoreShippedPackageVersionProperty) NO_GENERATIVE - None @@ -17,7 +17,7 @@ - + diff --git a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/NuGet.config b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/NuGet.config index 82abc6e8d3e..261d597dfa2 100644 --- a/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/NuGet.config +++ b/tests/EndToEndBuildTests/ComboProvider/ComboProvider.Tests/NuGet.config @@ -3,6 +3,6 @@ - + diff --git a/tests/EndToEndBuildTests/ComboProvider/ComboProvider/ComboProvider.fsproj b/tests/EndToEndBuildTests/ComboProvider/ComboProvider/ComboProvider.fsproj index 35f42604b1d..6651e9b5a5f 100644 --- a/tests/EndToEndBuildTests/ComboProvider/ComboProvider/ComboProvider.fsproj +++ b/tests/EndToEndBuildTests/ComboProvider/ComboProvider/ComboProvider.fsproj @@ -2,7 +2,9 @@ Library - netcoreapp3.0;net461 + net5.0;net472 + $(FSharpCoreShippedPackageVersionProperty) + net5.0;net472 diff --git a/tests/EndToEndBuildTests/ComboProvider/TestComboProvider.cmd b/tests/EndToEndBuildTests/ComboProvider/TestComboProvider.cmd index a08c72c1dfc..f14f2685652 100644 --- a/tests/EndToEndBuildTests/ComboProvider/TestComboProvider.cmd +++ b/tests/EndToEndBuildTests/ComboProvider/TestComboProvider.cmd @@ -8,7 +8,24 @@ rem setlocal set __scriptpath=%~dp0 +set configuration=Debug +:parseargs +if "%1" == "" goto argsdone +if /i "%1" == "-c" goto set_configuration + +echo Unsupported argument: %1 +goto failure + +:set_configuration +set configuration=%2 +shift +shift +goto parseargs + +:argsdone + +pushd %__scriptpath% rem rem Build typeprovider package with desktop compiler rem Test it with both desktop and coreclr compilers @@ -17,17 +34,17 @@ rem if not '%NUGET_PACKAGES%' == '' rd %NUGET_PACKAGES%\ComboProvider /s /q taskkill /F /IM dotnet.exe -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack ComboProvider\ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack ComboProvider\ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: ComboProvider failed && goto :failure +echo dotnet pack ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=net40 + dotnet pack ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: ComboProvider failed && goto :failure +echo dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 + dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: ComboProviderProvider failed && goto :failure +echo dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr + dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure rem rem Build typeprovider package with coreclr compiler @@ -35,24 +52,26 @@ rem Test it with both desktop and coreclr compilers rem if not '%NUGET_PACKAGES%' == '' rd %NUGET_PACKAGES%\ComboProvider /s /q -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack ComboProvider\ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe pack ComboProvider\ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c release -v minimal -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: ComboProviderProvider failed && goto :failure +echo dotnet pack ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=coreclr + dotnet pack ComboProvider\ComboProvider.fsproj -o %~dp0artifacts -c %configuration% -v minimal -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure -@echo%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=net461 -p:FSharpTestCompilerVersion=net40 -nr=false -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +echo dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 + dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net472 -p:FSharpTestCompilerVersion=net40 +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure -@echo %__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -%__scriptpath%..\..\..\artifacts\toolset\dotnet\dotnet.exe test ComboProvider\ComboProvider.Tests\ComboProvider.Tests.fsproj -c release -v minimal -p:TestTargetFramework=netcoreapp3.0 -p:FSharpTestCompilerVersion=coreclr -nr=false -@if ERRORLEVEL 1 echo Error: ComboProvider failed && goto :failure +echo dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -v %configuration% -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr + dotnet test ComboProvider.Tests\ComboProvider.Tests.fsproj -c %configuration% -v minimal -p:TestTargetFramework=net5.0 -p:FSharpTestCompilerVersion=coreclr +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure :success endlocal echo Succeeded +popd exit /b 0 :failure endlocal echo Failed +popd exit /b 1 diff --git a/tests/EndToEndBuildTests/EndToEndBuildTests.cmd b/tests/EndToEndBuildTests/EndToEndBuildTests.cmd index f1cb22c49ea..7613f487e35 100644 --- a/tests/EndToEndBuildTests/EndToEndBuildTests.cmd +++ b/tests/EndToEndBuildTests/EndToEndBuildTests.cmd @@ -6,21 +6,36 @@ rem setlocal set __scriptpath=%~dp0 +set configuration=Debug -@echo %__scriptpath%BasicProvider\TestBasicProvider.cmd -call %__scriptpath%BasicProvider\TestBasicProvider.cmd -@if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure +:parseargs +if "%1" == "" goto argsdone +if /i "%1" == "-c" goto set_configuration -@echo %__scriptpath%ComboProvider\TestComboProvider.cmd -call %__scriptpath%ComboProvider\TestComboProvider.cmd -@if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure +echo Unsupported argument: %1 +goto failure + +:set_configuration +set configuration=%2 +shift +shift +goto parseargs + +:argsdone + +echo %__scriptpath%BasicProvider\TestBasicProvider.cmd -c %configuration% +call %__scriptpath%BasicProvider\TestBasicProvider.cmd -c %configuration% +if ERRORLEVEL 1 echo Error: TestBasicProvider failed && goto :failure + +echo %__scriptpath%ComboProvider\TestComboProvider.cmd -c %configuration% +call %__scriptpath%ComboProvider\TestComboProvider.cmd -c %configuration% +if ERRORLEVEL 1 echo Error: TestComboProvider failed && goto :failure :success endlocal echo Succeeded exit /b 0 - :failure endlocal echo Failed diff --git a/tests/EndToEndBuildTests/ProvidedTypes/ProvidedTypes.fs b/tests/EndToEndBuildTests/ProvidedTypes/ProvidedTypes.fs index be1521a56ac..f1393038a0a 100644 --- a/tests/EndToEndBuildTests/ProvidedTypes/ProvidedTypes.fs +++ b/tests/EndToEndBuildTests/ProvidedTypes/ProvidedTypes.fs @@ -12373,7 +12373,7 @@ namespace ProviderImplementation.ProvidedTypes let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk, 0, chunk.Length) - let writeBinaryAndReportMappings (outfile, + let writeBinaryAndReportMappings (outfile: string, ilg: ILGlobals, pdbfile: string option, (* signer: ILStrongNameSigner option, *) portablePDB, embeddedPDB, embedAllSource, embedSourceList, sourceLink, emitTailcalls, deterministic, showTimes, dumpDebugInfo ) modul = let isDll = modul.IsDLL diff --git a/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj b/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj index 37b5c713e9a..2572d28cc62 100644 --- a/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj +++ b/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj @@ -3,8 +3,8 @@ - net472;netcoreapp3.0 - netcoreapp3.0 + net472;net5.0 + net5.0 Library true nunit @@ -12,6 +12,7 @@ + @@ -19,10 +20,6 @@ - - - - diff --git a/tests/FSharp.Build.UnitTests/MapSourceRootsTests.fs b/tests/FSharp.Build.UnitTests/MapSourceRootsTests.fs new file mode 100644 index 00000000000..a5d852b2625 --- /dev/null +++ b/tests/FSharp.Build.UnitTests/MapSourceRootsTests.fs @@ -0,0 +1,419 @@ + +namespace FSharp.Build.UnitTests + +open Microsoft.Build.Framework +open Microsoft.Build.Utilities +open FSharp.Build +open NUnit.Framework +open System.Collections.Generic + +type MockEngine() = + member val Errors = ResizeArray() with get + member val Warnings = ResizeArray() with get + member val Custom = ResizeArray() with get + member val Messages = ResizeArray() with get + + interface IBuildEngine with + member this.BuildProjectFile(projectFileName: string, targetNames: string [], globalProperties: System.Collections.IDictionary, targetOutputs: System.Collections.IDictionary): bool = + failwith "Not Implemented" + member this.ColumnNumberOfTaskNode: int = 0 + member this.ContinueOnError: bool = true + member this.LineNumberOfTaskNode: int = 0 + member this.LogCustomEvent(e: CustomBuildEventArgs): unit = + this.Custom.Add e + failwith "Not Implemented" + member this.LogErrorEvent(e: BuildErrorEventArgs): unit = + this.Errors.Add e + member this.LogMessageEvent(e: BuildMessageEventArgs): unit = + this.Messages.Add e + member this.LogWarningEvent(e: BuildWarningEventArgs): unit = + this.Warnings.Add e + member this.ProjectFileOfTaskNode: string = "" + +type SourceRoot = + SourceRoot of + path: string * + props: list * + expectedProps: list + + +/// these tests are ported from https://github.com/dotnet/roslyn/blob/093ea477717001c58be6231cf2a793f4245cbf72/src/Compilers/Core/MSBuildTaskTests/MapSourceRootTests.cs +/// Same scenarios, slightly different setup/teardown +[] +type MapSourceRootsTests() = + + let assertNoErrors (t: MapSourceRoots) = + let engine = t.BuildEngine :?> MockEngine + let errors = engine.Errors + Assert.AreEqual(0, errors.Count, sprintf "Expected no errors, but found the following: %A" errors) + let newTask () = + MapSourceRoots(BuildEngine = MockEngine()) + let toTaskItem (SourceRoot(path, props, _)) = + let dict = Dictionary() + for (k, v) in props do dict.Add(k, v) + TaskItem(path, dict) :> ITaskItem + let checkExpectations position (SourceRoot(path, _, expectedProps), mapping: ITaskItem) = + Assert.AreEqual(Utilities.FixFilePath path, mapping.ItemSpec, sprintf "expected paths to be the same while checking position %d" position) + for (key, value) in expectedProps do + Assert.AreEqual(value, mapping.GetMetadata(key), sprintf "expected values for metadata key %s to be the same while checking position %d" key position) + + let successfulTest items = + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) true + + assertNoErrors task + + match outputs with + | None -> + Assert.Fail("Expected to get some mappings back from this scenario") + | Some mappings -> + Array.zip items mappings + |> Array.iteri checkExpectations + + [] + member this.``basic deterministic scenarios`` () = + let items = + [| + SourceRoot(@"c:\packages\SourcePackage1\", [], ["MappedPath", @"/_1/"]) + SourceRoot(@"/packages/SourcePackage2/", [], ["MappedPath", @"/_2/"]) + SourceRoot(@"c:\MyProjects\MyProject\", ["SourceControl", "Git"], [ + "SourceControl", "Git" + "MappedPath", @"/_/" + ]) + SourceRoot(@"c:\MyProjects\MyProject\a\b\", [ + "SourceControl", "Git" + "NestedRoot", "a/b" + "ContainingRoot", @"c:\MyProjects\MyProject\" + "some metadata", "some value" + ], [ + "SourceControl", "Git" + "some metadata", "some value" + "MappedPath", @"/_/a/b/" + ]) + |] + + successfulTest items + + + [] + member this.``invalid chars`` () = + let items = + [| + SourceRoot(@"!@#:;$%^&*()_+|{}\", [], ["MappedPath", @"/_1/"]) + SourceRoot(@"****/", ["SourceControl", "Git"], [ + "MappedPath", @"/_/" + "SourceControl", "Git" + ]) + SourceRoot(@"****\|||:;\", [ + "SourceControl", "Git" + "NestedRoot","|||:;" + "ContainingRoot", @"****/" + ], [ + "MappedPath", @"/_/|||:;/" + "SourceControl", "Git" + ]) + |] + successfulTest items + + [] + member this.``input paths must end with separator`` () = + let items = + [| + SourceRoot(@"C:\", [], []) + SourceRoot(@"C:/", [], []) + SourceRoot(@"C:", [], []) + SourceRoot(@"C", [], []) + |] + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) true + + match outputs with + | None -> + let errors = (task.BuildEngine :?> MockEngine).Errors + Assert.AreEqual(2, errors.Count, "Should have had some errors with path mappings") + let expectedErrors = ["'C:'"; "'C'"] + let errorMessages = errors |> Seq.map (fun e -> e.Message) + + Assert.IsTrue(errorMessages |> Seq.forall (fun error -> error.Contains("end with a slash or backslash"))) + + expectedErrors + |> Seq.iter (fun expectedErrorPath -> + Assert.IsTrue(errorMessages |> Seq.exists (fun err -> err.EndsWith expectedErrorPath), + sprintf "expected an error to end with '%s', none did.\nMessages were:\n%A" expectedErrorPath errorMessages) + ) + | Some mappings -> + Assert.Fail("Expected to fail on the inputs") + + [] + member this.``nested roots separators`` () = + let items = + [| + SourceRoot(@"c:\MyProjects\MyProject\", [], [ + "MappedPath", @"/_/" + ]) + SourceRoot(@"c:\MyProjects\MyProject\a\a\", [ + "NestedRoot", @"a/a/" + "ContainingRoot", @"c:\MyProjects\MyProject\" + ], [ + "MappedPath", @"/_/a/a/" + ]) + SourceRoot(@"c:\MyProjects\MyProject\a\b\", [ + "NestedRoot", @"a/b\" + "ContainingRoot", @"c:\MyProjects\MyProject\" + ],[ + "MappedPath", @"/_/a/b/" + ]) + SourceRoot(@"c:\MyProjects\MyProject\a\c\", [ + "NestedRoot", @"a\c" + "ContainingRoot", @"c:\MyProjects\MyProject\" + ], [ + "MappedPath", @"/_/a/c/" + ]) + |] + + successfulTest items + + [] + member this.``sourceroot case sensitivity``() = + let items = [| + SourceRoot(@"c:\packages\SourcePackage1\", [], ["MappedPath", @"/_/"]) + SourceRoot(@"C:\packages\SourcePackage1\", [], ["MappedPath", @"/_1/"]) + SourceRoot(@"c:\packages\SourcePackage2\", [], ["MappedPath", @"/_2/"]) + |] + + successfulTest items + + [] + member this.``recursion error`` () = + let path1 = Utilities.FixFilePath @"c:\MyProjects\MyProject\a\1\" + let path2 = Utilities.FixFilePath @"c:\MyProjects\MyProject\a\2\" + let path3 = Utilities.FixFilePath @"c:\MyProjects\MyProject\" + let items = + [| + SourceRoot(path1, [ + "ContainingRoot", path2 + "NestedRoot", "a/1" + ], []) + SourceRoot(path2, [ + "ContainingRoot", path1 + "NestedRoot", "a/2" + ], []) + SourceRoot(path3, [], []) + |] + + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) true + + match outputs with + | None -> + let errors = (task.BuildEngine :?> MockEngine).Errors + Assert.AreEqual(2, errors.Count, "Should have had some errors with path mappings") + let expectedErrors = [path2; path1] |> List.map (sprintf "'%s'") + let errorMessages = errors |> Seq.map (fun e -> e.Message) + + Assert.IsTrue(errorMessages |> Seq.forall (fun error -> error.Contains("ContainingRoot was not found in SourceRoot items")), + sprintf "Expected to have the same type of errors but had %A" errorMessages + ) + + expectedErrors + |> Seq.iter (fun expectedErrorPath -> + Assert.IsTrue(errorMessages |> Seq.exists (fun err -> err.EndsWith expectedErrorPath), sprintf "expected an error to end with '%s', none did.\nMessages were:\n%A" expectedErrorPath errorMessages) + ) + | Some mappings -> + Assert.Fail("Expected to fail on the inputs") + + [] + [] + [] + member this.``metadata merge 1`` (deterministic: bool) = + let path1 = Utilities.FixFilePath @"c:\packages\SourcePackage1\" + let path2 = Utilities.FixFilePath @"c:\packages\SourcePackage2\" + let path3 = Utilities.FixFilePath @"c:\packages\SourcePackage3\" + + let items = [| + SourceRoot(path1, [ + "NestedRoot", @"NR1A" + "ContainingRoot", path3 + "RevisionId", "RevId1" + "SourceControl", "git" + "MappedPath", "MP1" + "SourceLinkUrl", "URL1" + ], []) + SourceRoot(path1, [ + "NestedRoot", @"NR1B" + "ContainingRoot", @"CR" + "RevisionId", "RevId2" + "SourceControl", "tfvc" + "MappedPath", "MP2" + "SourceLinkUrl", "URL2" + ], []) + SourceRoot(path2, [ + "NestedRoot", @"NR2" + "SourceControl", "git" + ], []) + SourceRoot(path2, [ + "ContainingRoot", path3 + "SourceControl", "git" + ], []) + SourceRoot(path3, [], []) + |] + + /// because this test isn't one to one we have to put the expecations in another structure + let actualExpectations = [| + SourceRoot(path1, [], [ + "SourceControl", "git" + "RevisionId", "RevId1" + "NestedRoot", "NR1A" + "ContainingRoot", path3 + "MappedPath", if deterministic then "/_/NR1A/" else path1 + "SourceLinkUrl", "URL1" + ]) + SourceRoot(path2, [], [ + "SourceControl", "git" + "RevisionId", "" + "NestedRoot", "NR2" + "ContainingRoot", path3 + "MappedPath", if deterministic then "/_/NR2/" else path2 + "SourceLinkUrl", "" + ]) + SourceRoot(path3, [], [ + "SourceControl", "" + "RevisionId", "" + "NestedRoot", "" + "ContainingRoot", "" + "MappedPath", if deterministic then "/_/" else path3 + "SourceLinkUrl", "" + ]) + |] + + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) deterministic + + assertNoErrors task + + match outputs with + | None -> + Assert.Fail("Expected to get some mappings back from this scenario") + | Some mappings -> + let warnings = (task.BuildEngine :?> MockEngine).Warnings |> Seq.map (fun w -> w.Message) + + Assert.AreEqual(6, Seq.length warnings) + Assert.IsTrue(warnings |> Seq.forall (fun w -> w.Contains "duplicate items")) + + [ + "SourceControl", "git", "tfvc" + "RevisionId", "RevId1", "RevId2" + "NestedRoot", "NR1A", "NR1B" + "ContainingRoot", path3, "CR" + "MappedPath", "MP1", "MP2" + "SourceLinkUrl", "URL1", "URL2" + ] + |> List.iter (fun (key, lval, rval) -> + Assert.IsTrue( + (warnings |> Seq.exists (fun warn -> warn.Contains(sprintf "SourceRoot contains duplicate items '%s' with conflicting metadata '%s': '%s' and '%s'" path1 key lval rval))), + sprintf "Expected to find an error message for %s comparing %s and %s, but got %A" key lval rval warnings + ) + ) + + Array.zip actualExpectations mappings + |> Array.iteri checkExpectations + + [] + member this.``missing containing root`` () = + let items = [| + SourceRoot(@"c:\MyProjects\MYPROJECT\", [], []) + SourceRoot(@"c:\MyProjects\MyProject\a\b\", [ + "SourceControl", "Git" + "NestedRoot", "a/b" + "ContainingRoot", @"c:\MyProjects\MyProject\" + ], [] + ) + |] + + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) true + + match outputs with + | None -> + let errors = (task.BuildEngine :?> MockEngine).Errors + Assert.AreEqual(1, errors.Count, "Should have had some errors with path mappings") + let expectedErrors = [@"c:\MyProjects\MyProject\"] |> List.map (sprintf "'%s'") + let errorMessages = errors |> Seq.map (fun e -> e.Message) + + Assert.IsTrue(errorMessages |> Seq.forall (fun error -> error.Contains("corresponding item is not a top-level source root")), + sprintf "Expected to have the same type of errors but had %A" errorMessages + ) + + expectedErrors + |> Seq.iter (fun expectedErrorPath -> + Assert.IsTrue(errorMessages |> Seq.exists (fun err -> err.EndsWith expectedErrorPath), sprintf "expected an error to end with '%s', none did.\nMessages were:\n%A" expectedErrorPath errorMessages) + ) + | Some mappings -> + Assert.Fail("Expected to fail on the inputs") + + [] + member this.``no containing root`` () = + let items = [| + SourceRoot(@"c:\MyProjects\MyProject\", [], []) + SourceRoot(@"c:\MyProjects\MyProject\a\b\", [ + "SourceControl", "Git" + "NestedRoot", "a/b" + ], []) + |] + + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) true + + match outputs with + | None -> + let errors = (task.BuildEngine :?> MockEngine).Errors + Assert.AreEqual(1, errors.Count, "Should have had some errors with path mappings") + let expectedErrors = [@""] |> List.map (sprintf "'%s'") + let errorMessages = errors |> Seq.map (fun e -> e.Message) + + Assert.IsTrue(errorMessages |> Seq.forall (fun error -> error.Contains("corresponding item is not a top-level source root")), + sprintf "Expected to have the same type of errors but had %A" errorMessages + ) + + expectedErrors + |> Seq.iter (fun expectedErrorPath -> + Assert.IsTrue(errorMessages |> Seq.exists (fun err -> err.EndsWith expectedErrorPath), sprintf "expected an error to end with '%s', none did.\nMessages were:\n%A" expectedErrorPath errorMessages) + ) + | Some mappings -> + Assert.Fail("Expected to fail on the inputs") + + [] + [] + [] + member this.``no top level source root`` (deterministic: bool) = + let path1 = Utilities.FixFilePath @"c:\MyProjects\MyProject\a\b\" + let items = [| + SourceRoot(path1, [ + "ContainingRoot", path1 + "NestedRoot", "a/b" + ], [ + "SourceControl", "" + "RevisionId", "" + "NestedRoot", "a/b" + "ContainingRoot", path1 + "MappedPath", path1 + "SourceLinkUrl", "" + ]) + |] + + let task = newTask() + let outputs = MapSourceRoots.PerformMapping task.Log (items |> Array.map toTaskItem) deterministic + + match outputs, deterministic with + | Some _, true -> + Assert.Fail "Expected to fail when deterministic" + | None, true -> + let errors = (task.BuildEngine :?> MockEngine).Errors + Assert.AreEqual(1, errors.Count, "Should have had some errors with path mappings") + let error = errors.[0].Message + Assert.IsTrue(error.Contains "when DeterministicSourcePaths is true") + | None, false -> + Assert.Fail (sprintf "Expected to succeed when not deterministic") + | Some mappings, false -> + Array.zip items mappings + |> Array.iteri checkExpectations diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/noframework.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/noframework.fs new file mode 100644 index 00000000000..6896ac69cf8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/noframework.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module noframework = + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/noframework) + // + [] + let ``noframework - noframework02.fs - --noframework`` compilation = + compilation + |> asFsx + |> withOptions ["--noframework"] + |> compile + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/platform.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/platform.fs new file mode 100644 index 00000000000..3b5950cf382 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/platform.fs @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module platform = + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //The 'anycpu32bitpreferred' platform can only be used with EXE targets\. You must use 'anycpu' instead\. + [] + let ``platform - error_16.fs - --target:library --platform:anycpu32bitpreferred`` compilation = + compilation + |> asFs + |> withOptions ["--target:library"; "--platform:anycpu32bitpreferred"] + |> compile + |> shouldFail + |> withErrorCode 3150 + |> withDiagnosticMessageMatches "The 'anycpu32bitpreferred' platform can only be used with EXE targets\. You must use 'anycpu' instead\." + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized option: '--PLATFORM' + [] + let ``platform - error_01.fs - --PLATFORM:anycpu`` compilation = + compilation + |> asFsx + |> withOptions ["--PLATFORM:anycpu"] + |> compile + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--PLATFORM'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized option: '--PlatForm' + [] + let ``platform - error_02.fs - --PlatForm:anycpu`` compilation = + compilation + |> asFsx + |> withOptions ["--PlatForm:anycpu"] + |> compile + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--PlatForm'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'ITANIUM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_03.fs - --platform:ITANIUM`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:ITANIUM"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'ITANIUM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'ANYCPU', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_04.fs - --platform:ANYCPU`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:ANYCPU"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'ANYCPU', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'X86', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_05.fs - --platform:X86`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:X86"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'X86', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'X64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_06.fs - --platform:X64`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:X64"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'X64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'IA64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_07.fs - --platform:IA64`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:IA64"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'IA64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'i386', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_08.fs - --platform:i386`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:i386"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'i386', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'AMD64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_09.fs - --platform:AMD64`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:AMD64"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'AMD64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'PPC', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_10.fs - --platform:PPC`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:PPC"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'PPC', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized platform 'ARM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + [] + let ``platform - error_15.fs - --platform:ARM`` compilation = + compilation + |> asFsx + |> withOptions ["--platform:ARM"] + |> compile + |> shouldFail + |> withErrorCode 1064 + |> withDiagnosticMessageMatches "Unrecognized platform 'ARM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized option: '--platform-' + [] + let ``platform - error_11.fs - --platform-:anycpu`` compilation = + compilation + |> asFsx + |> withOptions ["--platform-:anycpu"] + |> compile + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--platform-'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized option: '--PLATFORM\+' + [] + let ``platform - error_12.fs - --PLATFORM+:anycpu`` compilation = + compilation + |> asFsx + |> withOptions ["--PLATFORM+:anycpu"] + |> compile + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--PLATFORM\+'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/platform) + //Unrecognized option: '---platform' + [] + let ``platform - error_13.fs - ---platform:anycpu`` compilation = + compilation + |> asFsx + |> withOptions ["---platform:anycpu"] + |> compile + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '---platform'" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/times.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/times.fs new file mode 100644 index 00000000000..37d7ac658ef --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/times.fs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module times = + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/times) + //Unrecognized option: '--Times' + [] + let ``times - error_01.fs - --Times`` compilation = + compilation + |> asFsx + |> withOptions ["--Times"] + |> typecheck + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--Times'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/times) + //Unrecognized option: '--times-' + [] + let ``times - error_02.fs - --times-`` compilation = + compilation + |> asFsx + |> withOptions ["--times-"] + |> typecheck + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--times-'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/times) + //Unrecognized option: '--times\+' + [] + let ``times - error_03.fs - --times+`` compilation = + compilation + |> asFsx + |> withOptions ["--times+"] + |> typecheck + |> shouldFail + |> withErrorCode 0243 + |> withDiagnosticMessageMatches "Unrecognized option: '--times\+'" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs new file mode 100644 index 00000000000..48061544e8b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module warn = + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/warn) + //The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$ + [] + let ``warn - warn5_level5w.fs - --warn:5`` compilation = + compilation + |> asFsx + |> withOptions ["--warn:5"] + |> compile + |> shouldFail + |> withWarningCode 0052 + |> withDiagnosticMessageMatches "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warnon.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warnon.fs new file mode 100644 index 00000000000..194c2036e07 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warnon.fs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module warnon = + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/warnon) + //The value 'n' is unused$ + [] + let ``warnon - warnon01.fs - --warnon:1182 --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--warnon:1182"; "--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 1182 + |> withDiagnosticMessageMatches "The value 'n' is unused$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - CompilerOptions/fsc/warnon) + //The value 'n' is unused$ + [] + let ``warnon - warnon01.fs - --warnon:NU0001;FS1182;NU0001 --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--warnon:NU0001;FS1182;NU0001"; "--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 1182 + |> withDiagnosticMessageMatches "The value 'n' is unused$" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes.fs new file mode 100644 index 00000000000..ec1f6a722c7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes.fs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.BasicTypeAndModuleDefinitions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module RecordTypes = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/RecordTypes) + [] + let ``RecordTypes - Overload_Equals.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/RecordTypes) + [] + let ``RecordTypes - Overload_GetHashCode.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/RecordTypes) + [] + let ``RecordTypes - Overload_ToString.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/RecordTypes) + // + [] + let ``RecordTypes - UnitType01.fsx - -a`` compilation = + compilation + |> asFsx + |> withOptions ["-a"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes.fs new file mode 100644 index 00000000000..d2ee6687619 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.BasicTypeAndModuleDefinitions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module UnionTypes = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/UnionTypes) + [] + let ``UnionTypes - Overload_Equals.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/UnionTypes) + [] + let ``UnionTypes - Overload_GetHashCode.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/BasicTypeAndModuleDefinitions/UnionTypes) + [] + let ``UnionTypes - Overload_ToString.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/TypeFunctions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/TypeFunctions.fs new file mode 100644 index 00000000000..d21051f8613 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/TypeFunctions.fs @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.DeclarationElements.LetBindings + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module TypeFunctions = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + // + [] + let ``TypeFunctions - typeofInCustomAttributes001.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + //Expected type, not unit-of-measure + [] + let ``TypeFunctions - E_typeof_measure_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withErrorCode 0704 + |> withDiagnosticMessageMatches "Expected type, not unit-of-measure" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + //This type requires a definition + [] + let ``TypeFunctions - E_typeof_undefined_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withErrorCode 0929 + |> withDiagnosticMessageMatches "This type requires a definition" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + // + [] + let ``TypeFunctions - typeof_anonymous_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + [] + let ``TypeFunctions - typeof_class_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + [] + let ``TypeFunctions - typeof_interface_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/DeclarationElements/LetBindings/TypeFunctions) + [] + let ``TypeFunctions - typeof_struct_01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/UseBindings.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/UseBindings.fs new file mode 100644 index 00000000000..05aebe01310 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/UseBindings.fs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.DeclarationElements.LetBindings + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module UseBindings = + + [] + let ``UseBindings - UseBindingDiscard01.fs - Compiles`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:preview"] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``UseBindings - UseBindingDiscard01.fs - Bad LangVersion`` compilation = + compilation + |> asFsx + |> withOptions ["--langversion:5.0"] + |> compile + |> shouldFail + |> withErrorCode 3350 + |> withDiagnosticMessageMatches "Feature 'discard pattern in use binding' is not available.*" + + [] + let ``Dispose called for discarded value of use binding`` () = + Fsx """ +type private Disposable() = + [] static val mutable private disposedTimes: int + [] static val mutable private constructedTimes: int + + do Disposable.constructedTimes <- Disposable.constructedTimes + 1 + + static member DisposeCallCount() = Disposable.disposedTimes + static member ConsturctorCallCount() = Disposable.constructedTimes + + interface System.IDisposable with + member _.Dispose() = + Disposable.disposedTimes <- Disposable.disposedTimes + 1 + +let _scope = + use _ = new Disposable() + () + +let disposeCalls = Disposable.DisposeCallCount() +if disposeCalls <> 1 then + failwith "was not disposed or disposed too many times" + +let ctorCalls = Disposable.ConsturctorCallCount() +if ctorCalls <> 1 then + failwithf "unexpected constructor call count: %i" ctorCalls + + """ + |> asExe + |> withLangVersionPreview + |> compileAndRun + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication.fs new file mode 100644 index 00000000000..e6b97128784 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication.fs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.Expressions.ApplicationExpressions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module BasicApplication = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ApplicationExpressions/BasicApplication) + // + [] + let ``BasicApplication - PostfixType02.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ApplicationExpressions/BasicApplication) + //Unexpected identifier in expression$ + [] + let ``BasicApplication - E_PostfixType01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected identifier in expression$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ApplicationExpressions/BasicApplication) + //Unexpected identifier in member definition$ + [] + let ``BasicApplication - E_PostfixType03.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected identifier in member definition$" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/PatternMatching.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/PatternMatching.fs new file mode 100644 index 00000000000..aac0747b6f2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/PatternMatching.fs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.Expressions.ControlFlowExpressions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module PatternMatching = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ControlFlowExpressions/PatternMatching) + //'Some \(\(_,true\)\)' + [] + let ``PatternMatching - W_PatternMatchingCounterExample01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withWarningCode 0025 + |> withDiagnosticMessageMatches "'Some \(\(_,true\)\)'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ControlFlowExpressions/PatternMatching) + //Incomplete pattern matches on this expression\. For example, the value '\[_;true\]' may indicate a case not covered by the pattern\(s\) + [] + let ``PatternMatching - W_PatternMatchingCounterExample02.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withWarningCode 0025 + |> withDiagnosticMessageMatches "Incomplete pattern matches on this expression\. For example, the value '\[_;true\]' may indicate a case not covered by the pattern\(s\)" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ControlFlowExpressions/PatternMatching) + //Incomplete pattern matches on this expression + [] + let ``PatternMatching - W_PatternMatchingCounterExample03.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0025 + |> withDiagnosticMessageMatches "Incomplete pattern matches on this expression" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/SequenceIteration.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/SequenceIteration.fs new file mode 100644 index 00000000000..6c02b2e15c3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ControlFlowExpressions/SequenceIteration.fs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.Expressions.ControlFlowExpressions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module SequenceIteration = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ControlFlowExpressions/SequenceIteration) + //Incomplete pattern matches on this expression\. For example, the value 'None' may indicate a case not covered by the pattern\(s\)\.$ + [] + let ``SequenceIteration - W_IncompleteMatchFor01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0025 + |> withDiagnosticMessageMatches "Incomplete pattern matches on this expression\. For example, the value 'None' may indicate a case not covered by the pattern\(s\)\.$" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs new file mode 100644 index 00000000000..374e6b49797 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.Expressions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module TyperelatedExpressions = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/Type-relatedExpressions) + [] + let ``TyperelatedExpressions - rigidtypeannotation01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis.fs new file mode 100644 index 00000000000..8a3c6ca0924 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis.fs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.InferenceProcedures + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module RecursiveSafetyAnalysis = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/InferenceProcedures/RecursiveSafetyAnalysis) + //Failed to inline the value 'test' marked 'inline', perhaps because a recursive value was marked 'inline' + [] + let ``RecursiveSafetyAnalysis - E_RecursiveInline.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 1118 + |> withDiagnosticMessageMatches "Failed to inline the value 'test' marked 'inline', perhaps because a recursive value was marked 'inline'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/InferenceProcedures/RecursiveSafetyAnalysis) + [] + let ``RecursiveSafetyAnalysis - InfiniteRecursiveExplicitConstructor.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/InferenceProcedures/RecursiveSafetyAnalysis) + //Type constraint mismatch + [] + let ``RecursiveSafetyAnalysis - E_TypeDeclaration02.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 0193 + |> withDiagnosticMessageMatches "Type constraint mismatch" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Comments.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Comments.fs new file mode 100644 index 00000000000..e378a70aaeb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Comments.fs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalAnalysis + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Comments = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/Comments) + // + [] + let ``Comments - star01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/Comments) + + [] + let ``Comments - E_star02.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches @"Unexpected symbol '\)' in implementation file$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/Comments) + // + [] + let ``Comments - star03.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/NumericLiterals.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/NumericLiterals.fs new file mode 100644 index 00000000000..6d654432ec5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/NumericLiterals.fs @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalAnalysis + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module NumericLiterals = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + [] + let ``NumericLiterals - enumNegativeLiterals001.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals001.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals002.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals003.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals004.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals005.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals006.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Unexpected symbol '-' in union case$ + [] + let ``NumericLiterals - E_enumNegativeLiterals007.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 0010 + |> withDiagnosticMessageMatches "Unexpected symbol '-' in union case$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char + [] + let ``NumericLiterals - E_enumNegativeLiterals008.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldFail + |> withErrorCode 0951 + |> withDiagnosticMessageMatches "Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/NumericLiterals) + //Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char + [] + let ``NumericLiterals - E_enumNegativeLiterals009.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withErrorCode 0951 + |> withDiagnosticMessageMatches "Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Shift/Generics.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Shift/Generics.fs new file mode 100644 index 00000000000..1196518ca07 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/Shift/Generics.fs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalAnalysis.Shift + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Generics = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/Shift/Generics) + // + [] + let ``Generics - RightShift001.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/Shift/Generics) + // + [] + let ``Generics - RightShift002.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicKeywords.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicKeywords.fs new file mode 100644 index 00000000000..0c4095e15fa --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicKeywords.fs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalAnalysis + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module SymbolicKeywords = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedCurly01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedCurly02.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedCurly03.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedCurly04.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedCurly05.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicKeywords) + // + [] + let ``SymbolicKeywords - GreaterThanClosedSquare01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicOperators.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicOperators.fs new file mode 100644 index 00000000000..1c9eccdf010 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalAnalysis/SymbolicOperators.fs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalAnalysis + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module SymbolicOperators = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicOperators) + [] + let ``SymbolicOperators - GreaterThanDotParen01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicOperators) + //Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$ + [] + let ``SymbolicOperators - E_GreaterThanDotParen01.fs - `` compilation = + compilation + |> asFsx + |> compile + |> shouldFail + |> withErrorCode 1208 + |> withDiagnosticMessageMatches "Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicOperators) + //This code is not sufficiently generic\. The type variable \^T when \^T : \(static member \( \+ \) : \^T \* \^T -> \^a\) could not be generalized because it would escape its scope + [] + let ``SymbolicOperators - E_LessThanDotOpenParen001.fs - --flaterrors`` compilation = + compilation + |> asFsx + |> withOptions ["--flaterrors"] + |> compile + |> shouldFail + |> withErrorCode 0670 + |> withDiagnosticMessageMatches " \^a\) could not be generalized because it would escape its scope" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicOperators) + // + [] + let ``SymbolicOperators - GreaterThanColon001.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalAnalysis/SymbolicOperators) + // + [] + let ``SymbolicOperators - E_GreaterThanColon002.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs new file mode 100644 index 00000000000..ace90804bc1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/Basic/OffsideExceptions.fs @@ -0,0 +1,5169 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalFiltering.Basic + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module OffsideExceptions = + type FileAttribute(file) = + inherit DirectoryAttribute(__SOURCE_DIRECTORY__ + "/../../../resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions", Includes=[|file|]) + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalFiltering/Basic/OffsideExceptions) + // + [] + let InfixTokenPlusOne compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> shouldSucceed + |> ignore + + [] + let RelaxWhitespace2 compilation = + compilation + |> asFsx + |> withLangVersionPreview + |> withOptions ["--nowarn:25"] // Incomplete pattern matches on this expression. + |> typecheck + |> shouldSucceed + |> ignore + + [] + let RelaxWhitespace2_Warning25 compilation = + compilation + |> asFsx + |> withLangVersionPreview + |> verifyBaseline + |> ignore + + [] + let RelaxWhitespace2_Indentation() = + Fsx """ +match +1 +with 2 -> () +let ( +1 +) = 2 +type J( +x:int +) = class end +for i in [ +1 +] do () +while ( +true +) do () + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withResults [ + { Error = Error 10 + Range = { StartLine = 2 + StartColumn = 7 + EndLine = 3 + EndColumn = 1 } + Message = + "Incomplete structured construct at or before this point in expression" } + { Error = Warning 58 + Range = { StartLine = 6 + StartColumn = 1 + EndLine = 6 + EndColumn = 2 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (5:1). Try indenting this token further or using standard formatting conventions." } + ] + |> ignore + + [] + let RelaxWhitespace2_AllowedBefore1() = + Fsx """ +module A + let a = ( + 1 +) + """ + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore2() = + Fsx """ +module A + let a = id {| x = 1; + y = 1 +|} + """ + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore3() = + Fsx """ +module A + let a = {| + y = 1 +|} + """ + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore4() = + Fsx """ +module A + let a = {| y = + 1 +|} + """ + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore5() = + Fsx """ + let a = ( + fun () -> seq { + 1 + }, 2 = 3 + ) + let b : (unit -> int seq) * bool = id a + """ + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore6() = + Fsx """ + let a = ( + function () -> seq { + 1 + }, 2 = 3 + ) + let b : (unit -> int seq) * bool = id a + """ + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore7() = + Fsx """module M = begin type K = member _.G = 3 end;; module M2 = do begin end;; module M3 = do ()""" + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore8() = + Fsx """ +module M = begin + type K = member _.G = 3 +end module M2 = do ignore begin 1 +end module M3 = do () + """ + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore9() = + Fsx """ +type __() = + let a = + fun () -> ( + 1 + ), 2 + |> printfn "%O" + in let () = ignore<(unit -> int) * unit> a + let a' = + fun () -> seq { + 1 + }, 2 + |> printfn "%O" + in let () = ignore<(unit -> seq) * unit> a' + let b = + fun () -> ( + 1 + ), 2 + |> printfn "%O" + in do ignore<(unit -> int) * unit> b + let b' = + fun () -> seq { + 1 + }, 2 + |> printfn "%O" + in do ignore<(unit -> seq) * unit> b' + let c = + do ignore ( + 1 + ), 2 |> printfn "%O" + in do ignore c + let c' = + do ignore <| seq { + 1 + }, 2 |> printfn "%O" + in do ignore c' + member _.d() = seq { + 1 + }; static member e() = [ + 1 + ] + """ + |> typecheck + |> shouldSucceed + |> ignore + [] + let RelaxWhitespace2_AllowedBefore10() = + Fsx """ +module [< + Experimental "a" + >] A = type [< + Experimental "b" + >] B() = let [< + Experimental "c" + >] c = 1 + """ + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore + [] + // https://github.com/dotnet/fsharp/pull/11772#issuecomment-888637013 + let RelaxWhitespace2_AllowedBefore11() = + Fsx """ +let f() = () + +begin match 1 with +| 1 -> () +| 2 -> + f() +| _ -> printfn ":)" +end + """ + |> typecheck + |> shouldSucceed + |> ignore + + [] + let RelaxWhitespace2_Neg1() = + Fsx """ +module A + let a = {| + y = 1 +|} + """ + |> typecheck + |> shouldFail + |> withResult { + Error = Warning 58 + Range = { StartLine = 4 + StartColumn = 5 + EndLine = 4 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3:5). Try indenting this token further or using standard formatting conventions." + } |> ignore + [] + let RelaxWhitespace2_Neg2() = + Fsx """ +module A + let a = id {| + y = 1 +|} + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withResult { + Error = Warning 58 + Range = { StartLine = 4 + StartColumn = 5 + EndLine = 4 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3:5). Try indenting this token further or using standard formatting conventions." + } |> ignore + [] + let RelaxWhitespace2_Neg3() = + Fsx """ +module A + let a = if {| x = 1; + y = 1 +|} |> isNull then () + """ + |> typecheck + |> shouldFail + |> withResults [ + { Error = Error 10 + Range = { StartLine = 5 + StartColumn = 1 + EndLine = 5 + EndColumn = 3 } + Message = + "Incomplete structured construct at or before this point in expression" }; + { Error = Error 589 + Range = { StartLine = 3 + StartColumn = 13 + EndLine = 3 + EndColumn = 15 } + Message = + "Incomplete conditional. Expected 'if then ' or 'if then else '." }; + { Error = Error 10 + Range = { StartLine = 5 + StartColumn = 31 + EndLine = 5 + EndColumn = 33 } + Message = "Unexpected infix operator in implementation file" } + ] |> ignore + [] + let RelaxWhitespace2_Neg4() = + Fsx """ +module A + let a = {| x = + 1 +|} + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withResult { + Error = Warning 58 + Range = { StartLine = 4 + StartColumn = 5 + EndLine = 4 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3:5). Try indenting this token further or using standard formatting conventions." + } |> ignore + [] + let RelaxWhitespace2_Neg5() = + Fsx """ +module A + let a = {| x = + 1 +|} + """ + |> withLangVersion50 + |> compile + |> shouldFail + |> withResult { + Error = Warning 58 + Range = { StartLine = 4 + StartColumn = 15 + EndLine = 4 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3:16). Try indenting this token further or using standard formatting conventions." + } |> ignore + [] + let RelaxWhitespace2_Neg6() = + Fsx """ +match + 1 +with 2 -> () + """ + |> withLangVersion50 + |> compile + |> shouldFail + |> withResult { + Error = Error 10 + Range = { StartLine = 4 + StartColumn = 6 + EndLine = 4 + EndColumn = 7 } + Message = + "Unexpected start of structured construct in expression" + } |> ignore + [] + let RelaxWhitespace2_Neg7() = + Fsx """ +type R = { x : int +} +function +| { + x = 1 +} -> () + """ + |> typecheck + |> shouldFail + |> withResult { + Error = Error 10 + Range = { StartLine = 7 + StartColumn = 1 + EndLine = 7 + EndColumn = 2 } + Message = + "Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token." + } |> ignore + [] + let RelaxWhitespace2_Neg8() = + Fsx """ +type R = { x : int } +function +{ + x = 1 +} -> () + """ + |> typecheck + |> shouldFail + |> withResults [ + { Error = Warning 25 + Range = { StartLine = 3 + StartColumn = 1 + EndLine = 3 + EndColumn = 9 } + Message = + "Incomplete pattern matches on this expression. For example, the value '{ x=0 }' may indicate a case not covered by the pattern(s)." }; + { Error = Warning 193 + Range = { StartLine = 3 + StartColumn = 1 + EndLine = 6 + EndColumn = 8 } + Message = + "This expression is a function value, i.e. is missing arguments. Its type is R -> unit." } + ] |> ignore + [] + let RelaxWhitespace2_Neg9() = + Fsx """ +let _ = <@ type Foo(x : int) = + member this.Length = x @> + +exit 1 + + """ + |> compile + |> shouldFail + |> withResults [ + { Error = Error 10 + Range = { StartLine = 2 + StartColumn = 12 + EndLine = 2 + EndColumn = 16 } + Message = + "Incomplete structured construct at or before this point in quotation literal" }; + { Error = Error 602 + Range = { StartLine = 2 + StartColumn = 9 + EndLine = 2 + EndColumn = 11 } + Message = "Unmatched '<@ @>'" }; + { Error = Error 10 + Range = { StartLine = 2 + StartColumn = 12 + EndLine = 2 + EndColumn = 16 } + Message = + "Unexpected keyword 'type' in binding. Expected incomplete structured construct at or before this point or other token." }; + { Error = Error 3118 + Range = { StartLine = 2 + StartColumn = 1 + EndLine = 2 + EndColumn = 4 } + Message = + "Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword." }; + { Error = Error 10 + Range = { StartLine = 3 + StartColumn = 38 + EndLine = 3 + EndColumn = 40 } + Message = + "Unexpected end of quotation in expression. Expected incomplete structured construct at or before this point or other token." } + ] |> ignore + + [] + let RelaxWhitespace2_Fs50 compilation = + compilation + |> asFsx + |> withLangVersion50 + |> compile + |> shouldFail + |> (Array.toList >> withResults) [| + { Error = Warning 58 + Range = { StartLine = 14 + StartColumn = 9 + EndLine = 14 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (13:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 18 + StartColumn = 13 + EndLine = 18 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (17:22). Try indenting this token further or using standard formatting conventions." } + { Error = Error 10 + Range = { StartLine = 37 + StartColumn = 5 + EndLine = 37 + EndColumn = 6 } + Message = + "Incomplete structured construct at or before this point in binding. Expected '=' or other token." } + { Error = Error 10 + Range = { StartLine = 46 + StartColumn = 5 + EndLine = 46 + EndColumn = 8 } + Message = + "Incomplete structured construct at or before this point in implementation file" } + { Error = Warning 58 + Range = { StartLine = 48 + StartColumn = 13 + EndLine = 48 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (47:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 95 + StartColumn = 9 + EndLine = 95 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (94:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 98 + StartColumn = 9 + EndLine = 98 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (97:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 102 + StartColumn = 13 + EndLine = 102 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (101:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 106 + StartColumn = 13 + EndLine = 106 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (105:45). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 110 + StartColumn = 13 + EndLine = 110 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (109:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 112 + StartColumn = 13 + EndLine = 112 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (111:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 117 + StartColumn = 9 + EndLine = 117 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (116:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 132 + StartColumn = 13 + EndLine = 132 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (131:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 144 + StartColumn = 9 + EndLine = 144 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (143:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 148 + StartColumn = 13 + EndLine = 148 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (147:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 201 + StartColumn = 9 + EndLine = 201 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (200:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 204 + StartColumn = 9 + EndLine = 204 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (203:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 208 + StartColumn = 13 + EndLine = 208 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (207:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 212 + StartColumn = 13 + EndLine = 212 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (211:39). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 216 + StartColumn = 13 + EndLine = 216 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (215:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 218 + StartColumn = 13 + EndLine = 218 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (217:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 223 + StartColumn = 9 + EndLine = 223 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (222:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 332 + StartColumn = 9 + EndLine = 332 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (331:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 423 + StartColumn = 9 + EndLine = 423 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (422:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 490 + StartColumn = 9 + EndLine = 490 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (489:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 505 + StartColumn = 13 + EndLine = 505 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (504:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 507 + StartColumn = 13 + EndLine = 507 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (506:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 544 + StartColumn = 9 + EndLine = 544 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (543:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 560 + StartColumn = 9 + EndLine = 560 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (559:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 564 + StartColumn = 13 + EndLine = 564 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (563:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 574 + StartColumn = 13 + EndLine = 574 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (573:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 577 + StartColumn = 9 + EndLine = 577 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (576:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 582 + StartColumn = 9 + EndLine = 582 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (581:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 584 + StartColumn = 9 + EndLine = 584 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (583:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 587 + StartColumn = 9 + EndLine = 587 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (586:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 590 + StartColumn = 9 + EndLine = 590 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (589:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 594 + StartColumn = 13 + EndLine = 594 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (593:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 598 + StartColumn = 13 + EndLine = 598 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (597:46). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 602 + StartColumn = 13 + EndLine = 602 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (601:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 604 + StartColumn = 13 + EndLine = 604 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (603:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 609 + StartColumn = 9 + EndLine = 609 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (608:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 647 + StartColumn = 5 + EndLine = 647 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (646:38). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 651 + StartColumn = 9 + EndLine = 651 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (650:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 654 + StartColumn = 9 + EndLine = 654 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (653:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 658 + StartColumn = 13 + EndLine = 658 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (657:36). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 662 + StartColumn = 13 + EndLine = 662 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (661:53). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 666 + StartColumn = 13 + EndLine = 666 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (665:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 668 + StartColumn = 13 + EndLine = 668 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (667:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 671 + StartColumn = 9 + EndLine = 671 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (670:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 673 + StartColumn = 9 + EndLine = 673 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (672:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 676 + StartColumn = 9 + EndLine = 676 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (675:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 678 + StartColumn = 9 + EndLine = 678 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (677:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 681 + StartColumn = 9 + EndLine = 681 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (680:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 684 + StartColumn = 9 + EndLine = 684 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (683:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 688 + StartColumn = 13 + EndLine = 688 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (687:39). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 692 + StartColumn = 13 + EndLine = 692 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (691:56). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 696 + StartColumn = 13 + EndLine = 696 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (695:32). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 698 + StartColumn = 13 + EndLine = 698 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (697:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 703 + StartColumn = 9 + EndLine = 703 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (702:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 742 + StartColumn = 9 + EndLine = 742 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (741:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 745 + StartColumn = 9 + EndLine = 745 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (744:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 749 + StartColumn = 13 + EndLine = 749 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (748:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 753 + StartColumn = 13 + EndLine = 753 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (752:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 757 + StartColumn = 13 + EndLine = 757 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (756:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 759 + StartColumn = 13 + EndLine = 759 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (758:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 764 + StartColumn = 9 + EndLine = 764 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (763:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 769 + StartColumn = 9 + EndLine = 769 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (768:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 802 + StartColumn = 9 + EndLine = 802 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (801:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 805 + StartColumn = 9 + EndLine = 805 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (804:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 809 + StartColumn = 13 + EndLine = 809 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (808:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 813 + StartColumn = 13 + EndLine = 813 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (812:46). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 817 + StartColumn = 13 + EndLine = 817 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (816:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 819 + StartColumn = 13 + EndLine = 819 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (818:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 822 + StartColumn = 9 + EndLine = 822 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (821:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 824 + StartColumn = 9 + EndLine = 824 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (823:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 827 + StartColumn = 9 + EndLine = 827 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (826:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 829 + StartColumn = 9 + EndLine = 829 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (828:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 833 + StartColumn = 9 + EndLine = 833 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (832:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 836 + StartColumn = 9 + EndLine = 836 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (835:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 840 + StartColumn = 13 + EndLine = 840 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (839:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 844 + StartColumn = 13 + EndLine = 844 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (843:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 848 + StartColumn = 13 + EndLine = 848 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (847:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 850 + StartColumn = 13 + EndLine = 850 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (849:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 855 + StartColumn = 9 + EndLine = 855 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (854:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 860 + StartColumn = 9 + EndLine = 860 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (859:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 893 + StartColumn = 9 + EndLine = 893 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (892:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 896 + StartColumn = 9 + EndLine = 896 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (895:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 900 + StartColumn = 13 + EndLine = 900 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (899:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 904 + StartColumn = 13 + EndLine = 904 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (903:49). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 908 + StartColumn = 13 + EndLine = 908 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (907:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 910 + StartColumn = 13 + EndLine = 910 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (909:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 913 + StartColumn = 9 + EndLine = 913 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (912:31). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 915 + StartColumn = 9 + EndLine = 915 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (914:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 918 + StartColumn = 9 + EndLine = 918 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (917:31). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 920 + StartColumn = 9 + EndLine = 920 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (919:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 930 + StartColumn = 9 + EndLine = 930 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (929:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 935 + StartColumn = 9 + EndLine = 935 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (934:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 939 + StartColumn = 13 + EndLine = 939 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (938:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 943 + StartColumn = 13 + EndLine = 943 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (942:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 947 + StartColumn = 13 + EndLine = 947 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (946:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 949 + StartColumn = 13 + EndLine = 949 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (948:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 952 + StartColumn = 9 + EndLine = 952 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (951:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 957 + StartColumn = 9 + EndLine = 957 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (956:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 959 + StartColumn = 9 + EndLine = 959 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (958:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 962 + StartColumn = 9 + EndLine = 962 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (961:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 966 + StartColumn = 13 + EndLine = 966 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (965:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 970 + StartColumn = 13 + EndLine = 970 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (969:48). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 974 + StartColumn = 13 + EndLine = 974 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (973:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 976 + StartColumn = 13 + EndLine = 976 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (975:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 979 + StartColumn = 9 + EndLine = 979 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (978:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 981 + StartColumn = 9 + EndLine = 981 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (980:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 984 + StartColumn = 9 + EndLine = 984 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (983:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 986 + StartColumn = 9 + EndLine = 986 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (985:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 989 + StartColumn = 9 + EndLine = 989 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (988:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 993 + StartColumn = 13 + EndLine = 993 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (992:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 997 + StartColumn = 13 + EndLine = 997 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (996:49). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1001 + StartColumn = 13 + EndLine = 1001 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1000:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1003 + StartColumn = 13 + EndLine = 1003 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1002:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1006 + StartColumn = 9 + EndLine = 1006 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1005:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1008 + StartColumn = 9 + EndLine = 1008 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1007:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1011 + StartColumn = 5 + EndLine = 1011 + EndColumn = 7 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1010:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1016 + StartColumn = 5 + EndLine = 1016 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1013:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1017 + StartColumn = 9 + EndLine = 1017 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1016:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1019 + StartColumn = 5 + EndLine = 1019 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1016:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1021 + StartColumn = 13 + EndLine = 1021 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1020:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1023 + StartColumn = 5 + EndLine = 1023 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1019:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1027 + StartColumn = 5 + EndLine = 1027 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1023:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1033 + StartColumn = 5 + EndLine = 1033 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1027:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1038 + StartColumn = 5 + EndLine = 1038 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1033:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1043 + StartColumn = 5 + EndLine = 1043 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1043 + StartColumn = 12 + EndLine = 1043 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1046 + StartColumn = 5 + EndLine = 1046 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1046 + StartColumn = 12 + EndLine = 1046 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1047 + StartColumn = 9 + EndLine = 1047 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1046:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1049 + StartColumn = 5 + EndLine = 1049 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1049 + StartColumn = 12 + EndLine = 1049 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1051 + StartColumn = 13 + EndLine = 1051 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1050:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1053 + StartColumn = 5 + EndLine = 1053 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1053 + StartColumn = 12 + EndLine = 1053 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1057 + StartColumn = 5 + EndLine = 1057 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1057 + StartColumn = 12 + EndLine = 1057 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1063 + StartColumn = 5 + EndLine = 1063 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1063 + StartColumn = 12 + EndLine = 1063 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1064 + StartColumn = 9 + EndLine = 1064 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1063:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1068 + StartColumn = 5 + EndLine = 1068 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1068 + StartColumn = 12 + EndLine = 1068 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1069 + StartColumn = 9 + EndLine = 1069 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1068:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1073 + StartColumn = 5 + EndLine = 1073 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1073 + StartColumn = 21 + EndLine = 1073 + EndColumn = 22 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1076 + StartColumn = 5 + EndLine = 1076 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1076 + StartColumn = 21 + EndLine = 1076 + EndColumn = 22 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1077 + StartColumn = 9 + EndLine = 1077 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1076:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1079 + StartColumn = 5 + EndLine = 1079 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1079 + StartColumn = 21 + EndLine = 1079 + EndColumn = 22 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1081 + StartColumn = 13 + EndLine = 1081 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1080:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1083 + StartColumn = 5 + EndLine = 1083 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1083 + StartColumn = 21 + EndLine = 1083 + EndColumn = 22 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1087 + StartColumn = 5 + EndLine = 1087 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1087 + StartColumn = 21 + EndLine = 1087 + EndColumn = 22 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1093 + StartColumn = 5 + EndLine = 1093 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1094 + StartColumn = 9 + EndLine = 1094 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1093:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1095 + StartColumn = 8 + EndLine = 1095 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1098 + StartColumn = 5 + EndLine = 1098 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1099 + StartColumn = 9 + EndLine = 1099 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1098:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1103 + StartColumn = 5 + EndLine = 1103 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1103 + StartColumn = 17 + EndLine = 1103 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1106 + StartColumn = 5 + EndLine = 1106 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1106 + StartColumn = 17 + EndLine = 1106 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1107 + StartColumn = 9 + EndLine = 1107 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1106:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1109 + StartColumn = 5 + EndLine = 1109 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1109 + StartColumn = 17 + EndLine = 1109 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1111 + StartColumn = 13 + EndLine = 1111 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1110:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1113 + StartColumn = 5 + EndLine = 1113 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1113 + StartColumn = 17 + EndLine = 1113 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1117 + StartColumn = 5 + EndLine = 1117 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1117 + StartColumn = 17 + EndLine = 1117 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1123 + StartColumn = 5 + EndLine = 1123 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1124 + StartColumn = 9 + EndLine = 1124 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1123:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1125 + StartColumn = 8 + EndLine = 1125 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1128 + StartColumn = 5 + EndLine = 1128 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1129 + StartColumn = 9 + EndLine = 1129 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1128:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1133 + StartColumn = 1 + EndLine = 1133 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1134 + StartColumn = 5 + EndLine = 1134 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1133:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1140 + StartColumn = 9 + EndLine = 1140 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1139:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1144 + StartColumn = 13 + EndLine = 1144 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1143:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1170 + StartColumn = 9 + EndLine = 1170 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1169:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1174 + StartColumn = 13 + EndLine = 1174 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1173:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1187 + StartColumn = 9 + EndLine = 1187 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1186:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1192 + StartColumn = 9 + EndLine = 1192 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1191:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1200 + StartColumn = 9 + EndLine = 1200 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1199:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1204 + StartColumn = 13 + EndLine = 1204 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1203:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1217 + StartColumn = 9 + EndLine = 1217 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1216:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1222 + StartColumn = 9 + EndLine = 1222 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1221:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1230 + StartColumn = 9 + EndLine = 1230 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1229:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1234 + StartColumn = 13 + EndLine = 1234 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1233:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1247 + StartColumn = 9 + EndLine = 1247 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1246:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1252 + StartColumn = 9 + EndLine = 1252 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1251:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1257 + StartColumn = 1 + EndLine = 1257 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1418 + StartColumn = 1 + EndLine = 1418 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1470 + StartColumn = 9 + EndLine = 1470 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1469:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1475 + StartColumn = 9 + EndLine = 1475 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1474:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1500 + StartColumn = 9 + EndLine = 1500 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1499:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1505 + StartColumn = 9 + EndLine = 1505 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1504:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1530 + StartColumn = 9 + EndLine = 1530 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1529:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1535 + StartColumn = 9 + EndLine = 1535 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1534:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1539 + StartColumn = 1 + EndLine = 1539 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1591 + StartColumn = 9 + EndLine = 1591 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1590:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1596 + StartColumn = 9 + EndLine = 1596 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1595:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1621 + StartColumn = 9 + EndLine = 1621 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1620:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1626 + StartColumn = 9 + EndLine = 1626 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1625:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1651 + StartColumn = 9 + EndLine = 1651 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1650:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1656 + StartColumn = 9 + EndLine = 1656 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1655:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1660 + StartColumn = 1 + EndLine = 1660 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1661 + StartColumn = 5 + EndLine = 1661 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1660:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1714 + StartColumn = 9 + EndLine = 1714 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1713:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1719 + StartColumn = 9 + EndLine = 1719 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1718:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1744 + StartColumn = 9 + EndLine = 1744 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1743:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1749 + StartColumn = 9 + EndLine = 1749 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1748:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1774 + StartColumn = 9 + EndLine = 1774 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1773:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1779 + StartColumn = 9 + EndLine = 1779 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1778:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1783 + StartColumn = 1 + EndLine = 1783 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1784 + StartColumn = 5 + EndLine = 1784 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1783:25). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1790 + StartColumn = 9 + EndLine = 1790 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1789:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1794 + StartColumn = 13 + EndLine = 1794 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1793:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1804 + StartColumn = 13 + EndLine = 1804 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1803:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1807 + StartColumn = 9 + EndLine = 1807 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1806:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1812 + StartColumn = 9 + EndLine = 1812 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1811:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1814 + StartColumn = 9 + EndLine = 1814 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1813:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1820 + StartColumn = 9 + EndLine = 1820 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1819:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1824 + StartColumn = 13 + EndLine = 1824 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1823:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1834 + StartColumn = 13 + EndLine = 1834 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1833:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1837 + StartColumn = 9 + EndLine = 1837 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1836:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1842 + StartColumn = 9 + EndLine = 1842 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1841:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1844 + StartColumn = 9 + EndLine = 1844 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1843:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1850 + StartColumn = 9 + EndLine = 1850 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1849:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1854 + StartColumn = 13 + EndLine = 1854 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1853:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1864 + StartColumn = 13 + EndLine = 1864 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1863:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1867 + StartColumn = 9 + EndLine = 1867 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1866:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1872 + StartColumn = 9 + EndLine = 1872 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1871:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1874 + StartColumn = 9 + EndLine = 1874 + EndColumn = 25 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1873:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1880 + StartColumn = 9 + EndLine = 1880 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1879:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1884 + StartColumn = 13 + EndLine = 1884 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1883:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1894 + StartColumn = 13 + EndLine = 1894 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1893:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1897 + StartColumn = 9 + EndLine = 1897 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1896:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1902 + StartColumn = 9 + EndLine = 1902 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1901:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1904 + StartColumn = 9 + EndLine = 1904 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1903:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1906 + StartColumn = 1 + EndLine = 1906 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1907 + StartColumn = 5 + EndLine = 1907 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1906:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1910 + StartColumn = 9 + EndLine = 1910 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1909:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1913 + StartColumn = 9 + EndLine = 1913 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1912:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1917 + StartColumn = 13 + EndLine = 1917 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1916:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1921 + StartColumn = 13 + EndLine = 1921 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1920:51). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1925 + StartColumn = 13 + EndLine = 1925 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1924:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1927 + StartColumn = 13 + EndLine = 1927 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1926:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1930 + StartColumn = 9 + EndLine = 1930 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1929:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1932 + StartColumn = 9 + EndLine = 1932 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1931:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1935 + StartColumn = 9 + EndLine = 1935 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1934:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1937 + StartColumn = 9 + EndLine = 1937 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1936:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1940 + StartColumn = 9 + EndLine = 1940 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1939:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1943 + StartColumn = 9 + EndLine = 1943 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1942:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1947 + StartColumn = 13 + EndLine = 1947 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1946:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1951 + StartColumn = 13 + EndLine = 1951 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1950:51). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1955 + StartColumn = 13 + EndLine = 1955 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1954:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1957 + StartColumn = 13 + EndLine = 1957 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1956:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1960 + StartColumn = 9 + EndLine = 1960 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1959:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1962 + StartColumn = 9 + EndLine = 1962 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1961:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1965 + StartColumn = 9 + EndLine = 1965 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1964:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1967 + StartColumn = 9 + EndLine = 1967 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1966:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1970 + StartColumn = 9 + EndLine = 1970 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1969:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1973 + StartColumn = 9 + EndLine = 1973 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1972:32). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1977 + StartColumn = 13 + EndLine = 1977 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1976:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1981 + StartColumn = 13 + EndLine = 1981 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1980:51). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1985 + StartColumn = 13 + EndLine = 1985 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1984:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1987 + StartColumn = 13 + EndLine = 1987 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1986:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1990 + StartColumn = 9 + EndLine = 1990 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1989:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1992 + StartColumn = 9 + EndLine = 1992 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1991:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1995 + StartColumn = 9 + EndLine = 1995 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1994:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 1997 + StartColumn = 9 + EndLine = 1997 + EndColumn = 25 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1996:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2000 + StartColumn = 9 + EndLine = 2000 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1999:25). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2003 + StartColumn = 9 + EndLine = 2003 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2002:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2007 + StartColumn = 13 + EndLine = 2007 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2006:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2011 + StartColumn = 13 + EndLine = 2011 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2010:51). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2015 + StartColumn = 13 + EndLine = 2015 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2014:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2017 + StartColumn = 13 + EndLine = 2017 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2016:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2020 + StartColumn = 9 + EndLine = 2020 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2019:25). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2022 + StartColumn = 9 + EndLine = 2022 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2021:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2025 + StartColumn = 9 + EndLine = 2025 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2024:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2027 + StartColumn = 9 + EndLine = 2027 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2026:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2029 + StartColumn = 1 + EndLine = 2029 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2032 + StartColumn = 9 + EndLine = 2032 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2031:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2035 + StartColumn = 9 + EndLine = 2035 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2034:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2039 + StartColumn = 13 + EndLine = 2039 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2038:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2043 + StartColumn = 13 + EndLine = 2043 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2042:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2047 + StartColumn = 13 + EndLine = 2047 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2046:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2049 + StartColumn = 13 + EndLine = 2049 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2048:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2052 + StartColumn = 9 + EndLine = 2052 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2051:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2054 + StartColumn = 9 + EndLine = 2054 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2053:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2057 + StartColumn = 9 + EndLine = 2057 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2056:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2059 + StartColumn = 9 + EndLine = 2059 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2058:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2062 + StartColumn = 9 + EndLine = 2062 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2061:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2065 + StartColumn = 9 + EndLine = 2065 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2064:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2069 + StartColumn = 13 + EndLine = 2069 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2068:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2073 + StartColumn = 13 + EndLine = 2073 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2072:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2077 + StartColumn = 13 + EndLine = 2077 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2076:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2079 + StartColumn = 13 + EndLine = 2079 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2078:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2082 + StartColumn = 9 + EndLine = 2082 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2081:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2084 + StartColumn = 9 + EndLine = 2084 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2083:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2087 + StartColumn = 9 + EndLine = 2087 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2086:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2089 + StartColumn = 9 + EndLine = 2089 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2088:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2092 + StartColumn = 9 + EndLine = 2092 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2091:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2095 + StartColumn = 9 + EndLine = 2095 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2094:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2099 + StartColumn = 13 + EndLine = 2099 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2098:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2103 + StartColumn = 13 + EndLine = 2103 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2102:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2107 + StartColumn = 13 + EndLine = 2107 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2106:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2109 + StartColumn = 13 + EndLine = 2109 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2108:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2112 + StartColumn = 9 + EndLine = 2112 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2111:38). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2114 + StartColumn = 9 + EndLine = 2114 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2113:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2117 + StartColumn = 9 + EndLine = 2117 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2116:38). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2119 + StartColumn = 9 + EndLine = 2119 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2118:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2122 + StartColumn = 9 + EndLine = 2122 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2121:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2125 + StartColumn = 9 + EndLine = 2125 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2124:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2129 + StartColumn = 13 + EndLine = 2129 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2128:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2133 + StartColumn = 13 + EndLine = 2133 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2132:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2137 + StartColumn = 13 + EndLine = 2137 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2136:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2139 + StartColumn = 13 + EndLine = 2139 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2138:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2142 + StartColumn = 9 + EndLine = 2142 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2141:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2144 + StartColumn = 9 + EndLine = 2144 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2143:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2147 + StartColumn = 9 + EndLine = 2147 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2146:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2149 + StartColumn = 9 + EndLine = 2149 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2148:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2151 + StartColumn = 1 + EndLine = 2151 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2154 + StartColumn = 9 + EndLine = 2154 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2153:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2157 + StartColumn = 9 + EndLine = 2157 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2156:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2161 + StartColumn = 13 + EndLine = 2161 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2160:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2165 + StartColumn = 13 + EndLine = 2165 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2164:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2169 + StartColumn = 13 + EndLine = 2169 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2168:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2171 + StartColumn = 13 + EndLine = 2171 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2170:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2174 + StartColumn = 9 + EndLine = 2174 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2173:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2176 + StartColumn = 9 + EndLine = 2176 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2175:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2179 + StartColumn = 9 + EndLine = 2179 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2178:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2181 + StartColumn = 9 + EndLine = 2181 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2180:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2184 + StartColumn = 9 + EndLine = 2184 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2183:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2187 + StartColumn = 9 + EndLine = 2187 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2186:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2191 + StartColumn = 13 + EndLine = 2191 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2190:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2195 + StartColumn = 13 + EndLine = 2195 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2194:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2199 + StartColumn = 13 + EndLine = 2199 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2198:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2201 + StartColumn = 13 + EndLine = 2201 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2200:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2204 + StartColumn = 9 + EndLine = 2204 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2203:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2206 + StartColumn = 9 + EndLine = 2206 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2205:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2209 + StartColumn = 9 + EndLine = 2209 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2208:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2211 + StartColumn = 9 + EndLine = 2211 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2210:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2214 + StartColumn = 9 + EndLine = 2214 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2213:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2217 + StartColumn = 9 + EndLine = 2217 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2216:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2221 + StartColumn = 13 + EndLine = 2221 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2220:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2225 + StartColumn = 13 + EndLine = 2225 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2224:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2229 + StartColumn = 13 + EndLine = 2229 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2228:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2231 + StartColumn = 13 + EndLine = 2231 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2230:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2234 + StartColumn = 9 + EndLine = 2234 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2233:38). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2236 + StartColumn = 9 + EndLine = 2236 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2235:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2239 + StartColumn = 9 + EndLine = 2239 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2238:38). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2241 + StartColumn = 9 + EndLine = 2241 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2240:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2244 + StartColumn = 9 + EndLine = 2244 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2243:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2247 + StartColumn = 9 + EndLine = 2247 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2246:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2251 + StartColumn = 13 + EndLine = 2251 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2250:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2255 + StartColumn = 13 + EndLine = 2255 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2254:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2259 + StartColumn = 13 + EndLine = 2259 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2258:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2261 + StartColumn = 13 + EndLine = 2261 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2260:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2264 + StartColumn = 9 + EndLine = 2264 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2263:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2266 + StartColumn = 9 + EndLine = 2266 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2265:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2269 + StartColumn = 9 + EndLine = 2269 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2268:34). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2271 + StartColumn = 9 + EndLine = 2271 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2270:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2273 + StartColumn = 1 + EndLine = 2273 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2274 + StartColumn = 5 + EndLine = 2274 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2273:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2277 + StartColumn = 9 + EndLine = 2277 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2276:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2282 + StartColumn = 9 + EndLine = 2282 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2281:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2286 + StartColumn = 13 + EndLine = 2286 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2285:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2290 + StartColumn = 13 + EndLine = 2290 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2289:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2294 + StartColumn = 13 + EndLine = 2294 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2293:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2296 + StartColumn = 13 + EndLine = 2296 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2295:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2299 + StartColumn = 9 + EndLine = 2299 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2298:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2304 + StartColumn = 9 + EndLine = 2304 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2303:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2308 + StartColumn = 13 + EndLine = 2308 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2307:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2312 + StartColumn = 13 + EndLine = 2312 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2311:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2316 + StartColumn = 13 + EndLine = 2316 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2315:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2318 + StartColumn = 13 + EndLine = 2318 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2317:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2321 + StartColumn = 9 + EndLine = 2321 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2320:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2326 + StartColumn = 9 + EndLine = 2326 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2325:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2330 + StartColumn = 13 + EndLine = 2330 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2329:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2334 + StartColumn = 13 + EndLine = 2334 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2333:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2338 + StartColumn = 13 + EndLine = 2338 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2337:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2340 + StartColumn = 13 + EndLine = 2340 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2339:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2343 + StartColumn = 9 + EndLine = 2343 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2342:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2348 + StartColumn = 9 + EndLine = 2348 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2347:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2352 + StartColumn = 13 + EndLine = 2352 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2351:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2356 + StartColumn = 13 + EndLine = 2356 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2355:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2360 + StartColumn = 13 + EndLine = 2360 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2359:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2362 + StartColumn = 13 + EndLine = 2362 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2361:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2364 + StartColumn = 1 + EndLine = 2364 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (1038:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2369 + StartColumn = 9 + EndLine = 2369 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2368:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2373 + StartColumn = 13 + EndLine = 2373 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2372:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2403 + StartColumn = 13 + EndLine = 2403 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2402:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2450 + StartColumn = 9 + EndLine = 2450 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2449:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2453 + StartColumn = 9 + EndLine = 2453 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2452:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2457 + StartColumn = 13 + EndLine = 2457 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2456:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2461 + StartColumn = 13 + EndLine = 2461 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2460:45). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2465 + StartColumn = 13 + EndLine = 2465 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2464:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2467 + StartColumn = 13 + EndLine = 2467 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2466:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2472 + StartColumn = 9 + EndLine = 2472 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2471:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2487 + StartColumn = 13 + EndLine = 2487 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2486:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2493 + StartColumn = 1 + EndLine = 2493 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2364:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2498 + StartColumn = 9 + EndLine = 2498 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2497:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2502 + StartColumn = 13 + EndLine = 2502 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2501:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2555 + StartColumn = 9 + EndLine = 2555 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2554:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2558 + StartColumn = 9 + EndLine = 2558 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2557:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2562 + StartColumn = 13 + EndLine = 2562 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2561:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2566 + StartColumn = 13 + EndLine = 2566 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2565:39). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2570 + StartColumn = 13 + EndLine = 2570 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2569:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2572 + StartColumn = 13 + EndLine = 2572 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2571:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2577 + StartColumn = 9 + EndLine = 2577 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2576:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2587 + StartColumn = 1 + EndLine = 2587 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2493:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2628 + StartColumn = 1 + EndLine = 2628 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2587:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2690 + StartColumn = 9 + EndLine = 2690 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2689:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2721 + StartColumn = 1 + EndLine = 2721 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2628:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2783 + StartColumn = 9 + EndLine = 2783 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2782:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2814 + StartColumn = 1 + EndLine = 2814 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2721:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2846 + StartColumn = 9 + EndLine = 2846 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2845:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2861 + StartColumn = 13 + EndLine = 2861 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2860:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2863 + StartColumn = 13 + EndLine = 2863 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2862:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2900 + StartColumn = 9 + EndLine = 2900 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2899:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2910 + StartColumn = 1 + EndLine = 2910 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2814:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2915 + StartColumn = 9 + EndLine = 2915 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2914:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2919 + StartColumn = 13 + EndLine = 2919 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2918:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2929 + StartColumn = 13 + EndLine = 2929 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2928:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2932 + StartColumn = 9 + EndLine = 2932 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2931:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2937 + StartColumn = 9 + EndLine = 2937 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2936:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2939 + StartColumn = 9 + EndLine = 2939 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2938:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2942 + StartColumn = 9 + EndLine = 2942 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2941:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2945 + StartColumn = 9 + EndLine = 2945 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2944:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2949 + StartColumn = 13 + EndLine = 2949 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2948:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2953 + StartColumn = 13 + EndLine = 2953 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2952:46). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2957 + StartColumn = 13 + EndLine = 2957 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2956:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2959 + StartColumn = 13 + EndLine = 2959 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2958:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 2964 + StartColumn = 9 + EndLine = 2964 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2963:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3003 + StartColumn = 1 + EndLine = 3003 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (2910:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3005 + StartColumn = 9 + EndLine = 3005 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3004:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3008 + StartColumn = 9 + EndLine = 3008 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3007:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3012 + StartColumn = 13 + EndLine = 3012 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3011:36). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3016 + StartColumn = 13 + EndLine = 3016 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3015:53). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3020 + StartColumn = 13 + EndLine = 3020 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3019:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3022 + StartColumn = 13 + EndLine = 3022 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3021:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3025 + StartColumn = 9 + EndLine = 3025 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3024:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3027 + StartColumn = 9 + EndLine = 3027 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3026:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3030 + StartColumn = 9 + EndLine = 3030 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3029:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3032 + StartColumn = 9 + EndLine = 3032 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3031:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3035 + StartColumn = 9 + EndLine = 3035 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3034:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3038 + StartColumn = 9 + EndLine = 3038 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3037:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3042 + StartColumn = 13 + EndLine = 3042 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3041:39). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3046 + StartColumn = 13 + EndLine = 3046 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3045:56). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3050 + StartColumn = 13 + EndLine = 3050 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3049:32). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3052 + StartColumn = 13 + EndLine = 3052 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3051:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3057 + StartColumn = 9 + EndLine = 3057 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3056:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3096 + StartColumn = 1 + EndLine = 3096 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3003:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3098 + StartColumn = 9 + EndLine = 3098 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3097:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3101 + StartColumn = 9 + EndLine = 3101 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3100:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3105 + StartColumn = 13 + EndLine = 3105 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3104:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3109 + StartColumn = 13 + EndLine = 3109 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3108:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3113 + StartColumn = 13 + EndLine = 3113 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3112:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3115 + StartColumn = 13 + EndLine = 3115 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3114:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3120 + StartColumn = 9 + EndLine = 3120 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3119:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3125 + StartColumn = 9 + EndLine = 3125 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3124:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3158 + StartColumn = 9 + EndLine = 3158 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3157:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3161 + StartColumn = 9 + EndLine = 3161 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3160:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3165 + StartColumn = 13 + EndLine = 3165 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3164:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3169 + StartColumn = 13 + EndLine = 3169 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3168:46). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3173 + StartColumn = 13 + EndLine = 3173 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3172:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3175 + StartColumn = 13 + EndLine = 3175 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3174:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3178 + StartColumn = 9 + EndLine = 3178 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3177:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3180 + StartColumn = 9 + EndLine = 3180 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3179:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3183 + StartColumn = 9 + EndLine = 3183 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3182:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3185 + StartColumn = 9 + EndLine = 3185 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3184:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3189 + StartColumn = 1 + EndLine = 3189 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3096:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3191 + StartColumn = 9 + EndLine = 3191 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3190:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3194 + StartColumn = 9 + EndLine = 3194 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3193:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3198 + StartColumn = 13 + EndLine = 3198 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3197:29). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3202 + StartColumn = 13 + EndLine = 3202 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3201:37). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3206 + StartColumn = 13 + EndLine = 3206 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3205:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3208 + StartColumn = 13 + EndLine = 3208 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3207:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3213 + StartColumn = 9 + EndLine = 3213 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3212:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3218 + StartColumn = 9 + EndLine = 3218 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3217:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3251 + StartColumn = 9 + EndLine = 3251 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3250:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3254 + StartColumn = 9 + EndLine = 3254 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3253:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3258 + StartColumn = 13 + EndLine = 3258 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3257:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3262 + StartColumn = 13 + EndLine = 3262 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3261:49). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3266 + StartColumn = 13 + EndLine = 3266 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3265:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3268 + StartColumn = 13 + EndLine = 3268 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3267:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3271 + StartColumn = 9 + EndLine = 3271 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3270:31). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3273 + StartColumn = 9 + EndLine = 3273 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3272:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3276 + StartColumn = 9 + EndLine = 3276 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3275:31). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3278 + StartColumn = 9 + EndLine = 3278 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3277:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3282 + StartColumn = 1 + EndLine = 3282 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3189:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3287 + StartColumn = 9 + EndLine = 3287 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3286:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3292 + StartColumn = 9 + EndLine = 3292 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3291:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3296 + StartColumn = 13 + EndLine = 3296 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3295:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3300 + StartColumn = 13 + EndLine = 3300 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3299:35). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3304 + StartColumn = 13 + EndLine = 3304 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3303:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3306 + StartColumn = 13 + EndLine = 3306 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3305:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3313 + StartColumn = 9 + EndLine = 3313 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3312:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3315 + StartColumn = 9 + EndLine = 3315 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3314:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3318 + StartColumn = 9 + EndLine = 3318 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3317:19). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3322 + StartColumn = 13 + EndLine = 3322 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3321:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3326 + StartColumn = 13 + EndLine = 3326 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3325:48). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3330 + StartColumn = 13 + EndLine = 3330 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3329:27). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3332 + StartColumn = 13 + EndLine = 3332 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3331:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3335 + StartColumn = 9 + EndLine = 3335 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3334:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3337 + StartColumn = 9 + EndLine = 3337 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3336:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3340 + StartColumn = 9 + EndLine = 3340 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3339:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3342 + StartColumn = 9 + EndLine = 3342 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3341:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3345 + StartColumn = 9 + EndLine = 3345 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3344:20). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3349 + StartColumn = 13 + EndLine = 3349 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3348:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3353 + StartColumn = 13 + EndLine = 3353 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3352:49). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3357 + StartColumn = 13 + EndLine = 3357 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3356:28). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3359 + StartColumn = 13 + EndLine = 3359 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3358:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3362 + StartColumn = 9 + EndLine = 3362 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3361:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3364 + StartColumn = 9 + EndLine = 3364 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3363:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3369 + StartColumn = 1 + EndLine = 3369 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3282:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3370 + StartColumn = 5 + EndLine = 3370 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3369:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3375 + StartColumn = 9 + EndLine = 3375 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3374:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3376 + StartColumn = 9 + EndLine = 3376 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3374:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3380 + StartColumn = 9 + EndLine = 3380 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3379:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3384 + StartColumn = 13 + EndLine = 3384 + EndColumn = 17 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3385 + StartColumn = 13 + EndLine = 3385 + EndColumn = 18 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:17). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3390 + StartColumn = 9 + EndLine = 3390 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3392 + StartColumn = 9 + EndLine = 3392 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3393 + StartColumn = 9 + EndLine = 3393 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3395 + StartColumn = 9 + EndLine = 3395 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3396 + StartColumn = 9 + EndLine = 3396 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3398 + StartColumn = 9 + EndLine = 3398 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3399 + StartColumn = 9 + EndLine = 3399 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3400 + StartColumn = 9 + EndLine = 3400 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3408 + StartColumn = 9 + EndLine = 3408 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3409 + StartColumn = 9 + EndLine = 3409 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3417 + StartColumn = 9 + EndLine = 3417 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3418 + StartColumn = 5 + EndLine = 3418 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3419 + StartColumn = 9 + EndLine = 3419 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3418:22). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3420 + StartColumn = 9 + EndLine = 3420 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3423 + StartColumn = 1 + EndLine = 3423 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3383:9). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3424 + StartColumn = 1 + EndLine = 3424 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3423:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3427 + StartColumn = 1 + EndLine = 3427 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3424:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3430 + StartColumn = 1 + EndLine = 3430 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3427:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3431 + StartColumn = 1 + EndLine = 3431 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3427:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3434 + StartColumn = 1 + EndLine = 3434 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3431:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3435 + StartColumn = 5 + EndLine = 3435 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3434:12). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3439 + StartColumn = 1 + EndLine = 3439 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3434:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3445 + StartColumn = 1 + EndLine = 3445 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3439:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3450 + StartColumn = 1 + EndLine = 3450 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3439:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3451 + StartColumn = 5 + EndLine = 3451 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3450:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3456 + StartColumn = 1 + EndLine = 3456 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3439:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3457 + StartColumn = 5 + EndLine = 3457 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3456:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3467 + StartColumn = 1 + EndLine = 3467 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3439:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3471 + StartColumn = 1 + EndLine = 3471 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3439:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3491 + StartColumn = 1 + EndLine = 3491 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3471:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3503 + StartColumn = 1 + EndLine = 3503 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3491:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3524 + StartColumn = 1 + EndLine = 3524 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3503:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3525 + StartColumn = 1 + EndLine = 3525 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3524:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3527 + StartColumn = 1 + EndLine = 3527 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3525:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3529 + StartColumn = 1 + EndLine = 3529 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3527:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3530 + StartColumn = 1 + EndLine = 3530 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3529:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3533 + StartColumn = 5 + EndLine = 3533 + EndColumn = 142 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3532:7). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3537 + StartColumn = 1 + EndLine = 3537 + EndColumn = 2 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3530:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3538 + StartColumn = 5 + EndLine = 3538 + EndColumn = 142 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3537:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3544 + StartColumn = 1 + EndLine = 3544 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3530:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3545 + StartColumn = 5 + EndLine = 3545 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3546 + StartColumn = 5 + EndLine = 3546 + EndColumn = 34 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3549 + StartColumn = 1 + EndLine = 3549 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3550 + StartColumn = 5 + EndLine = 3550 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3549:48). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3556 + StartColumn = 1 + EndLine = 3556 + EndColumn = 7 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3556 + StartColumn = 8 + EndLine = 3556 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3556 + StartColumn = 10 + EndLine = 3556 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3573 + StartColumn = 1 + EndLine = 3573 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3574 + StartColumn = 13 + EndLine = 3574 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3573:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3575 + StartColumn = 13 + EndLine = 3575 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3573:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3576 + StartColumn = 13 + EndLine = 3576 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3573:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3577 + StartColumn = 13 + EndLine = 3577 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3573:23). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3580 + StartColumn = 1 + EndLine = 3580 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3581 + StartColumn = 23 + EndLine = 3581 + EndColumn = 24 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3580:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3582 + StartColumn = 23 + EndLine = 3582 + EndColumn = 24 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3580:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3583 + StartColumn = 23 + EndLine = 3583 + EndColumn = 24 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3580:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3584 + StartColumn = 23 + EndLine = 3584 + EndColumn = 24 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3580:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3586 + StartColumn = 1 + EndLine = 3586 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3588 + StartColumn = 10 + EndLine = 3588 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3586:24). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3594 + StartColumn = 1 + EndLine = 3594 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3600 + StartColumn = 1 + EndLine = 3600 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3603 + StartColumn = 1 + EndLine = 3603 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3604 + StartColumn = 1 + EndLine = 3604 + EndColumn = 7 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3604 + StartColumn = 8 + EndLine = 3604 + EndColumn = 13 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3604 + StartColumn = 14 + EndLine = 3604 + EndColumn = 15 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3607 + StartColumn = 9 + EndLine = 3607 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3606:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3609 + StartColumn = 1 + EndLine = 3609 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3544:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3610 + StartColumn = 2 + EndLine = 3610 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3609:5). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3612 + StartColumn = 1 + EndLine = 3612 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3609:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3617 + StartColumn = 17 + EndLine = 3617 + EndColumn = 39 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3616:26). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3624 + StartColumn = 1 + EndLine = 3624 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3612:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3627 + StartColumn = 1 + EndLine = 3627 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3624:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3649 + StartColumn = 5 + EndLine = 3649 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3648:30). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3670 + StartColumn = 1 + EndLine = 3670 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3627:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3680 + StartColumn = 1 + EndLine = 3680 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3670:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3691 + StartColumn = 1 + EndLine = 3691 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3680:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3696 + StartColumn = 1 + EndLine = 3696 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3691:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3703 + StartColumn = 1 + EndLine = 3703 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3704 + StartColumn = 5 + EndLine = 3704 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3703:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3706 + StartColumn = 1 + EndLine = 3706 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3707 + StartColumn = 5 + EndLine = 3707 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3706:7). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3709 + StartColumn = 1 + EndLine = 3709 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3710 + StartColumn = 5 + EndLine = 3710 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3709:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3713 + StartColumn = 1 + EndLine = 3713 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3714 + StartColumn = 1 + EndLine = 3714 + EndColumn = 2 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3720 + StartColumn = 1 + EndLine = 3720 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3721 + StartColumn = 1 + EndLine = 3721 + EndColumn = 2 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3724 + StartColumn = 5 + EndLine = 3724 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3723:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3726 + StartColumn = 5 + EndLine = 3726 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3725:7). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3731 + StartColumn = 1 + EndLine = 3731 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3734 + StartColumn = 10 + EndLine = 3734 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3733:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3736 + StartColumn = 10 + EndLine = 3736 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3735:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3742 + StartColumn = 1 + EndLine = 3742 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3743 + StartColumn = 5 + EndLine = 3743 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3742:16). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3748 + StartColumn = 1 + EndLine = 3748 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3751 + StartColumn = 1 + EndLine = 3751 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3754 + StartColumn = 1 + EndLine = 3754 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3755 + StartColumn = 5 + EndLine = 3755 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3754:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3757 + StartColumn = 1 + EndLine = 3757 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3758 + StartColumn = 5 + EndLine = 3758 + EndColumn = 8 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3757:21). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3761 + StartColumn = 9 + EndLine = 3761 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3760:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3766 + StartColumn = 1 + EndLine = 3766 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3768 + StartColumn = 9 + EndLine = 3768 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3767:15). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3773 + StartColumn = 1 + EndLine = 3773 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3774 + StartColumn = 5 + EndLine = 3774 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3773:10). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3776 + StartColumn = 1 + EndLine = 3776 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3777 + StartColumn = 5 + EndLine = 3777 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3776:14). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3779 + StartColumn = 1 + EndLine = 3779 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3780 + StartColumn = 5 + EndLine = 3780 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3779:7). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3782 + StartColumn = 1 + EndLine = 3782 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3783 + StartColumn = 5 + EndLine = 3783 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3782:11). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3785 + StartColumn = 1 + EndLine = 3785 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3789 + StartColumn = 1 + EndLine = 3789 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3793 + StartColumn = 1 + EndLine = 3793 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3796 + StartColumn = 1 + EndLine = 3796 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3797 + StartColumn = 5 + EndLine = 3797 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3796:8). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3799 + StartColumn = 1 + EndLine = 3799 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3802 + StartColumn = 1 + EndLine = 3802 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3803 + StartColumn = 5 + EndLine = 3803 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3802:57). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3805 + StartColumn = 1 + EndLine = 3805 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3808 + StartColumn = 1 + EndLine = 3808 + EndColumn = 3 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3809 + StartColumn = 5 + EndLine = 3809 + EndColumn = 6 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3808:64). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3811 + StartColumn = 1 + EndLine = 3811 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3814 + StartColumn = 1 + EndLine = 3814 + EndColumn = 9 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3820 + StartColumn = 1 + EndLine = 3820 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3821 + StartColumn = 1 + EndLine = 3821 + EndColumn = 5 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3822 + StartColumn = 1 + EndLine = 3822 + EndColumn = 7 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3822 + StartColumn = 8 + EndLine = 3822 + EndColumn = 11 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3822 + StartColumn = 12 + EndLine = 3822 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3822 + StartColumn = 15 + EndLine = 3822 + EndColumn = 16 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3829 + StartColumn = 1 + EndLine = 3829 + EndColumn = 7 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3829 + StartColumn = 8 + EndLine = 3829 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3829 + StartColumn = 11 + EndLine = 3829 + EndColumn = 12 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3837 + StartColumn = 1 + EndLine = 3837 + EndColumn = 4 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3696:1). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3843 + StartColumn = 9 + EndLine = 3843 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3842:13). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3862 + StartColumn = 9 + EndLine = 3862 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3861:31). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3871 + StartColumn = 13 + EndLine = 3871 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3870:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3888 + StartColumn = 9 + EndLine = 3888 + EndColumn = 10 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3887:18). Try indenting this token further or using standard formatting conventions." } + { Error = Warning 58 + Range = { StartLine = 3902 + StartColumn = 13 + EndLine = 3902 + EndColumn = 14 } + Message = + "Possible incorrect indentation: this token is offside of context started at position (3901:16). Try indenting this token further or using standard formatting conventions." } + |] diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HashLight.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HashLight.fs new file mode 100644 index 00000000000..1d1b1b0c821 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HashLight.fs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalFiltering + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module HashLight = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalFiltering/HashLight) + [] + let ``HashLight - IndentationWithComputationExpression01.fs - --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HighPrecedenceApplication.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HighPrecedenceApplication.fs new file mode 100644 index 00000000000..738aa01e10c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/LexicalFiltering/HighPrecedenceApplication.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.LexicalFiltering + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module HighPrecedenceApplication = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/LexicalFiltering/HighPrecedenceApplication) + // + [] + let ``HighPrecedenceApplication - RangeOperator01.fs - -a`` compilation = + compilation + |> asFs + |> withOptions ["-a"] + |> compile + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors.fs new file mode 100644 index 00000000000..72cc5fdf664 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors.fs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.ObjectOrientedTypeDefinitions.ClassTypes + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module ExplicitObjectConstructors = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors) + [] + let ``ExplicitObjectConstructors - new_while_01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors) + //Message2 + [] + let ``ExplicitObjectConstructors - WithAttribute01.fs - -a --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["-a"; "--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0044 + |> withDiagnosticMessageMatches "Message2" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors) + //Message1 + [] + let ``ExplicitObjectConstructors - WithAttribute02.fs - -a --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["-a"; "--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0044 + |> withDiagnosticMessageMatches "Message1" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors.fs new file mode 100644 index 00000000000..a8e9cd50045 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors.fs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.ObjectOrientedTypeDefinitions.ClassTypes + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module ImplicitObjectConstructors = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors) + //Message1 + [] + let ``ImplicitObjectConstructors - WithAttribute.fs - -a --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["-a"; "--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0044 + |> withDiagnosticMessageMatches "Message1" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction.fs new file mode 100644 index 00000000000..de513935d5c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction.fs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.ObjectOrientedTypeDefinitions.ClassTypes + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module ValueRestriction = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - TypeArgs01.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - MemberOrFunction01.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - MemberOrFunction01Gen.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - MemberOrFunction02.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - MemberOrFunction02Gen.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction) + // + [] + let ``ValueRestriction - TypeFunction01.fsx - -a --test:ErrorRanges --warnaserror+`` compilation = + compilation + |> asFsx + |> withOptions ["-a"; "--test:ErrorRanges"; "--warnaserror+"] + |> compile + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/StructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/StructTypes.fs new file mode 100644 index 00000000000..03b071572ef --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/StructTypes.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.ObjectOrientedTypeDefinitions + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module StructTypes = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/StructTypes) + [] + let ``StructTypes - Overload_Equals.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/StructTypes) + [] + let ``StructTypes - Overload_GetHashCode.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/ObjectOrientedTypeDefinitions/StructTypes) + [] + let ``StructTypes - Overload_ToString.fs - --warnaserror+ --nowarn:988`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Simple.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Simple.fs new file mode 100644 index 00000000000..1f98b0a96dd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/Simple.fs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.PatternMatching + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Simple = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Simple) + //Incomplete pattern matches on this expression. For example, the value 'Result \(_\)' may indicate a case not covered by the pattern\(s\) + [] + let ``Simple - W_Incomplete01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withWarningCode 0025 + |> withDiagnosticMessageMatches "Incomplete pattern matches on this expression. For example, the value 'Result \(_\)' may indicate a case not covered by the pattern\(s\)" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Simple) + //This rule will never be matched + [] + let ``Simple - W_Incomplete02.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0026 + |> withDiagnosticMessageMatches "This rule will never be matched" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/PatternMatching/Simple) + //Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name + [] + let ``Simple - W_BindCaptialIdent.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0049 + |> withDiagnosticMessageMatches "Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name" + |> ignore + + [] + let ``As patterns``() = + Fsx """ + let (|Id|) = id + let a = [1..4] + match a with + | 1 | 1 as b::(Id 2 as c as c2)::[d as 3; Id e & Id _ as Id 4] as Id f when b = 1 && c = 2 && c2 = 2 && d = 3 && e = 4 && a = f -> () + | _ -> failwith "Match failed" + """ + |> asExe + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes.fs new file mode 100644 index 00000000000..e6813ecf1b6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes.fs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.TypesAndTypeConstraints + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module CheckingSyntacticTypes = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes) + //This member, function or value declaration may not be declared 'inline' + [] + let ``CheckingSyntacticTypes - E_CannotInlineVirtualMethods1.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 3151 + |> withDiagnosticMessageMatches "This member, function or value declaration may not be declared 'inline'" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes) + //This member, function or value declaration may not be declared 'inline' + [] + let ``CheckingSyntacticTypes - E_CannotInlineVirtualMethod2.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withErrorCode 3151 + |> withDiagnosticMessageMatches "This member, function or value declaration may not be declared 'inline'" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes.fs new file mode 100644 index 00000000000..ddf8f623d94 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes.fs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.TypesAndTypeConstraints + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module LogicalPropertiesOfTypes = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes) + [] + let ``LogicalPropertiesOfTypes - TypeWithNullLiteral_NetRef.fsx - -a`` compilation = + compilation + |> asFsx + |> withOptions ["-a"] + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Basic.fs new file mode 100644 index 00000000000..a926fc8f133 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Basic.fs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.UnitsOfMeasure + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Basic = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - Misc01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - Misc03.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - Stats.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - SI.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - RationalExponents01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Basic) + [] + let ``Basic - Quotation04_hidden.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Diagnostics.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Diagnostics.fs new file mode 100644 index 00000000000..e0ae16cf126 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Diagnostics.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.UnitsOfMeasure + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Diagnostics = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Diagnostics) + // + [] + let ``Diagnostics - RangeExpression01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Parsing.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Parsing.fs new file mode 100644 index 00000000000..c4a4596685b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/Parsing.fs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.UnitsOfMeasure + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Parsing = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Parsing) + [] + let ``Parsing - GreaterBarRBrack01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Parsing) + [] + let ``Parsing - Reciprocal01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Parsing) + [] + let ``Parsing - QuotientAssoc.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Parsing) + [] + let ``Parsing - Quotient.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/Parsing) + [] + let ``Parsing - PowerSynonym.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/TypeChecker.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/TypeChecker.fs new file mode 100644 index 00000000000..8b3d372a796 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnitsOfMeasure/TypeChecker.fs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Conformance.UnitsOfMeasure + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module TypeChecker = + + // This test was automatically generated (moved from FSharpQA suite - Conformance/UnitsOfMeasure/TypeChecker) + [] + let ``TypeChecker - GenericSubType01.fs - `` compilation = + compilation + |> asFsx + |> typecheck + |> shouldSucceed + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs new file mode 100644 index 00000000000..91fe1591534 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ConstraintSolver + +open Xunit +open FSharp.Test.Compiler + +module MemberConstraints = + + [] + let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262 + FSharp """ + let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ())) + """ + |> withErrorRanges + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 697, Line 2, Col 43, Line 2, Col 76, "Invalid constraint") + + [] + let ``We can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() = + + FSharp """ +type Foo(x : int) = + member this.Val = x + + static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val) + static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target) + + static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val) + static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target) + +let x = Foo(3) --> 4 +let y = Foo(3) --> Foo(4) +let x2 = Foo(3) + 4 +let y2 = Foo(3) + Foo(4) + +if x.Val <> 7 then failwith "x.Val <> 7" +elif y.Val <> 7 then failwith "y.Val <> 7" +elif x2.Val <> 7 then failwith "x2.Val <> 7" +elif y2.Val <> 7 then failwith "x.Val <> 7" +else () +""" + |> asExe + |> compile + |> run + |> shouldSucceed + |> withExitCode 0 diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/PrimitiveConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/PrimitiveConstraints.fs new file mode 100644 index 00000000000..cf1a6723694 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/PrimitiveConstraints.fs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ConstraintSolver + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module PrimitiveConstraints = + + /// Title: Type checking oddity + /// + /// This suggestion was resolved as by design, + /// so the test makes sure, we're emitting error message about 'not being a valid object construction expression' + + [] + let ``Invalid object constructor`` compilation = // Regression test for FSharp1.0:4189 + compilation + |> verifyBaseline + + [] + let ``Test primitive : constraints``() = + FSharp""" +#light + +type Foo(x : int) = + member this.Value = x + override this.ToString() = "Foo" + +type Bar(x : int) = + inherit Foo(-1) + member this.Value2 = x + override this.ToString() = "Bar" + +let test1 (x : Foo) = x.Value +let test2 (x : Bar) = (x.Value, x.Value2) + +let f = new Foo(128) +let b = new Bar(256) + +if test1 f <> 128 then failwith "test1 f <> 128" +elif test2 b <> (-1, 256) then failwith "test2 b <> (-1, 256)" +else () + """ + |> compileExeAndRun + + [] + let ``Test primitive :> constraints``() = + FSharp""" +#light +type Foo(x : int) = + member this.Value = x + override this.ToString() = "Foo" + +type Bar(x : int) = + inherit Foo(-1) + member this.Value2 = x + override this.ToString() = "Bar" + +type Ram(x : int) = + inherit Foo(10) + member this.ValueA = x + override this.ToString() = "Ram" + +let test (x : Foo) = (x.Value, x.ToString()) + +let f = new Foo(128) +let b = new Bar(256) +let r = new Ram(314) + +if test f <> (128, "Foo") then failwith "test f <> (128, 'Foo')" +elif test b <> (-1, "Bar") then failwith "test b <> (-1, 'Bar')" +elif test r <> (10, "Ram") then failwith "test r <> (10, 'Ram')" +else () + """ + |> compileExeAndRun + + [] + let ``Test primitive : null constraint``() = + FSharp""" +let inline isNull<'a when 'a : null> (x : 'a) = + match x with + | null -> "is null" + | _ -> (x :> obj).ToString() + +let runTest = + // Wrapping in try block to work around FSB 1989 + try + if isNull null <> "is null" then failwith "isNull null <> is null" + if isNull "F#" <> "F#" then failwith "isNull F# <> F#" + () + with _ -> reraise() + +runTest + """ + |> compileExeAndRun diff --git a/tests/FSharp.Compiler.ComponentTests/Diagnostics/General.fs b/tests/FSharp.Compiler.ComponentTests/Diagnostics/General.fs new file mode 100644 index 00000000000..295204c1cea --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Diagnostics/General.fs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Diagnostics + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module General = + + // This test was automatically generated (moved from FSharpQA suite - Diagnostics/General) + //\(18,22-18,30\).+warning FS0046: The keyword 'tailcall' is reserved for future use by F# + [] + let ``General - W_Keyword_tailcall01.fs - --test:ErrorRanges`` compilation = + compilation + |> asFs + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Diagnostics/async.fs b/tests/FSharp.Compiler.ComponentTests/Diagnostics/async.fs new file mode 100644 index 00000000000..d868564e980 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Diagnostics/async.fs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Diagnostics + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module async = + + // This test was automatically generated (moved from FSharpQA suite - Diagnostics/async) + //Type mismatch\. Expecting a.+''a'.+but given a.+'Async<'a>'.*The types ''a' and 'Async<'a>' cannot be unified. + [] + let ``async - MissingBangForLoop01.fs - --warnaserror+ --test:ErrorRanges --flaterrors`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--test:ErrorRanges"; "--flaterrors"] + |> compile + |> shouldFail + |> withErrorCode 0001 + |> withDiagnosticMessageMatches "' cannot be unified." + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Diagnostics/async) + //Type mismatch\. Expecting a. ''a' .but given a. 'Async<'a>' .The types ''a' and 'Async<'a>' cannot be unified. + [] + let ``async - MissingBangForLoop02.fs - --warnaserror+ --test:ErrorRanges --flaterrors`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--test:ErrorRanges"; "--flaterrors"] + |> compile + |> shouldFail + |> withErrorCode 0001 + |> withDiagnosticMessageMatches "' cannot be unified." + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Diagnostics/async) + //All branches of an 'if' expression must return values implicitly convertible to the type of the first branch + [] + let ``async - ReturnBangNonAsync_IfThenElse.fs - --warnaserror+ --test:ErrorRanges --flaterrors`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--test:ErrorRanges"; "--flaterrors"] + |> compile + |> shouldFail + |> withErrorCode 0001 + |> withDiagnosticMessageMatches "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch" + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - Diagnostics/async) + //'use!' bindings must be of the form 'use! = '$ + [] + let ``async - UseBindingWrongForm01.fs - --warnaserror+ --test:ErrorRanges --flaterrors`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--test:ErrorRanges"; "--flaterrors"] + |> compile + |> shouldFail + |> withErrorCode 1228 + |> withDiagnosticMessageMatches "'$" + |> ignore + diff --git a/src/fsharp/FSharp.Compiler.Private.Scripting/Directory.Build.props b/tests/FSharp.Compiler.ComponentTests/Directory.Build.props similarity index 100% rename from src/fsharp/FSharp.Compiler.Private.Scripting/Directory.Build.props rename to tests/FSharp.Compiler.ComponentTests/Directory.Build.props diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs new file mode 100644 index 00000000000..40092066b38 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module ``Literals`` = + + [] + let ``Literal attribute generates literal static field``() = + FSharp """ +module LiteralValue + +[] +let x = 7 + +[] +let main _ = + 0 + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +.field public static literal int32 x = int32(0x00000007) +.custom instance void [FSharp.Core]Microsoft.FSharp.Core.LiteralAttribute::.ctor() = ( 01 00 00 00 )"""] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc.fs new file mode 100644 index 00000000000..e54703e961d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Misc.fs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module ``Misc`` = + [] + let ``Empty array construct compiles to System.Array.Empty<_>()``() = + FSharp """ +module Misc + +let zInt (): int[] = [||] + +let zString (): string[] = [||] + +let zGeneric<'a> (): 'a[] = [||] + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +IL_0000: call !!0[] [runtime]System.Array::Empty() +IL_0005: ret""" + """ + +IL_0000: call !!0[] [runtime]System.Array::Empty() +IL_0005: ret""" + + """ +IL_0000: call !!0[] [runtime]System.Array::Empty() +IL_0005: ret""" ] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Operators.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Operators.fs new file mode 100644 index 00000000000..a0224fad564 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Operators.fs @@ -0,0 +1,15 @@ + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module Operators = + + [] + let ``Validate that non generic (fast) code is emmitted for comparison involving decimals`` compilation = + compilation + |> ignoreWarnings + |> verifyBaseline + |> verifyILBaseline \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/SkipLocalsInit.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SkipLocalsInit.fs new file mode 100644 index 00000000000..8b69fa73281 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/SkipLocalsInit.fs @@ -0,0 +1,184 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +#if NETCOREAPP +module ``SkipLocalsInit`` = + [] + let ``Init in function and closure not emitted when applied on function``() = + FSharp """ +module SkipLocalsInit + +[] +let x () = + [||] |> Array.filter (fun x -> let y = "".Length in y + y = x) |> ignore +""" + |> compile + |> shouldSucceed + |> verifyIL [""" +.method public static void x() cil managed +{ + .custom instance void [runtime]System.Runtime.CompilerServices.SkipLocalsInitAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals (int32[] V_0) +""" + + """ +.method public strict virtual instance bool + Invoke(int32 x) cil managed +{ + + .maxstack 6 + .locals (int32 V_0)"""] + + [] + let ``Init in static method not emitted when applied on class``() = + FSharp """ +module SkipLocalsInit + +[] +type X () = + static member Y () = + let x = "ssa".Length + x + x + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +.custom instance void [runtime]System.Runtime.CompilerServices.SkipLocalsInitAttribute::.ctor() = ( 01 00 00 00 ) +.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) +""" + + """ +.method public static int32 Y() cil managed +{ + + .maxstack 4 + .locals (int32 V_0)"""] + + [] + let ``Init in static method and function not emitted when applied on module``() = + FSharp """ +[] +module SkipLocalsInit + +let x () = + let x = "ssa".Length + x + x + +type X () = + static member Y () = + let x = "ssa".Length + x + x + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +.custom instance void [runtime]System.Runtime.CompilerServices.SkipLocalsInitAttribute::.ctor() = ( 01 00 00 00 ) +.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) +""" + + """ +.method public static int32 x() cil managed +{ + + .maxstack 4 + .locals (int32 V_0) +""" + + """ +.method public static int32 Y() cil managed +{ + + .maxstack 4 + .locals (int32 V_0)"""] + + [] + let ``Init in method and closure not emitted when applied on method``() = + FSharp """ +module SkipLocalsInit + +type X () = + [] + member _.Y () = + [||] |> Array.filter (fun x -> let y = "".Length in y + y = x) |> ignore + let x = "ssa".Length + x + x + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +.method public hidebysig instance int32 + Y() cil managed +{ + .custom instance void [runtime]System.Runtime.CompilerServices.SkipLocalsInitAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals (int32[] V_0, + int32 V_1) +""" + + """ +.method public strict virtual instance bool + Invoke(int32 x) cil managed +{ + + .maxstack 6 + .locals (int32 V_0) +""" ] + + [] + let ``Zero init performed to get defaults despite the attribute``() = + FSharp """ +module SkipLocalsInit +open System + +[] +let z () = + let mutable a = Unchecked.defaultof + a + +[] +let x f = + let a = if 1 / 1 = 1 then Nullable () else Nullable 5L + f a |> ignore + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +.locals (valuetype [runtime]System.DateTime V_0) +IL_0000: ldloca.s V_0 +IL_0002: initobj [runtime]System.DateTime +IL_0008: ldloc.0 +IL_0009: ret + """ + + """ +.locals (valuetype [runtime]System.Nullable`1 V_0, + valuetype [runtime]System.Nullable`1 V_1, + !!a V_2) +IL_0000: ldc.i4.1 +IL_0001: ldc.i4.1 +IL_0002: div +IL_0003: ldc.i4.1 +IL_0004: bne.un.s IL_0011 + +IL_0006: ldloca.s V_1 +IL_0008: initobj valuetype [runtime]System.Nullable`1 +IL_000e: ldloc.1 +IL_000f: br.s IL_0018 + +IL_0011: ldc.i4.5 +IL_0012: conv.i8 +IL_0013: newobj instance void valuetype [runtime]System.Nullable`1::.ctor(!0) +IL_0018: stloc.0 +IL_0019: ldarg.0 +IL_001a: ldloc.0 +IL_001b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!a>::Invoke(!0) +IL_0020: stloc.2 +IL_0021: ret"""] +#endif \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs new file mode 100644 index 00000000000..9734e06935b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StringFormatAndInterpolation.fs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module ``StringFormatAndInterpolation`` = + [] + let ``Interpolated string with no holes is reduced to a string or simple format when used in printf``() = + FSharp """ +module StringFormatAndInterpolation + +let stringOnly () = $"no hole" + +let printed () = printf $"printed no hole" + """ + |> compile + |> shouldSucceed + |> verifyIL [""" +IL_0000: ldstr "no hole" +IL_0005: ret""" + """ +IL_0000: ldstr "printed no hole" +IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) +IL_000a: stloc.0 +IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() +IL_0010: ldloc.0 +IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) +IL_0016: pop +IL_0017: ret"""] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TailCalls.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TailCalls.fs new file mode 100644 index 00000000000..cbe51a7a381 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TailCalls.fs @@ -0,0 +1,237 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module ``Tail Calls`` = + // Regression test for DevDiv:72571 + + let private compileWithTailCalls opts = + opts |> ignoreWarnings |> withOptions ["-g"; "--optimize-"; "--tailcalls+"] |> compile + + [] + let ``TailCall 01``() = + FSharp """ +module TailCall01 +let foo(x:int, y) = printfn "%d" x +let run() = let x = 0 in foo(x,5) + """ + |> compileWithTailCalls + |> shouldSucceed + |> verifyIL [ + """ + .method public static void foo(int32 x, + !!a y) cil managed + { + + .maxstack 8 + IL_0000: ldstr "%d" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: pop + IL_0016: ret + } + """ + """ + .method public static void run() cil managed + { + + .maxstack 4 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldc.i4.5 + IL_0004: tail. + IL_0006: call void TailCall01::foo(int32, + !!0) + IL_000b: ret + } + """] + + + [] + let ``TailCall 02``() = + FSharp """ +module TailCall02 +let foo(x:int byref) = x +let run() = let mutable x = 0 in foo(&x) + """ + |> compileWithTailCalls + |> shouldSucceed + |> verifyIL [ + """ + .method public static int32 foo(int32& x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldobj [runtime]System.Int32 + IL_0006: ret + } + """ + """ + .method public static int32 run() cil managed + { + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call int32 TailCall02::foo(int32&) + IL_0009: ret + } + """ + ] + + [] + let ``TailCall 03``() = + FSharp """ +module TailCall03 +let foo (x:int byref) (y:int byref) z = printfn "%d" (x+y) +let run() = let mutable x = 0 in foo &x &x 5 + """ + |> compileWithTailCalls + |> shouldSucceed + |> verifyIL [ + """ + .method public static void foo(int32& x, + int32& y, + !!a z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldstr "%d" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj [runtime]System.Int32 + IL_0015: ldarg.1 + IL_0016: ldobj [runtime]System.Int32 + IL_001b: add + IL_001c: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0021: pop + IL_0022: ret + } + """ + """ + .method public static void run() cil managed + { + + .maxstack 5 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: ldloca.s V_0 + IL_0006: ldc.i4.5 + IL_0007: call void TailCall03::foo(int32&, + int32&, + !!0) + IL_000c: nop + IL_000d: ret + } + """ + ] + + [] + let ``TailCall 04``() = + FSharp """ +module TailCall04 +let foo(x:int byref, y) = printfn "%d" x +let run() = let mutable x = 0 in foo(&x,5) + """ + |> compileWithTailCalls + |> shouldSucceed + |> verifyIL [ + """ + .method public static void foo(int32& x, + !!a y) cil managed + { + + .maxstack 8 + IL_0000: ldstr "%d" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj [runtime]System.Int32 + IL_0015: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001a: pop + IL_001b: ret + } + """ + """ + .method public static void run() cil managed + { + + .maxstack 4 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: ldc.i4.5 + IL_0005: call void TailCall04::foo(int32&, + !!0) + IL_000a: nop + IL_000b: ret + + """ + ] + + [] + let ``TailCall 05``() = + FSharp """ +module TailCall05 +let foo(x:int byref, y:int byref, z) = printfn "%d" (x+y) +let run() = let mutable x = 0 in foo(&x,&x,5) + """ + |> compileWithTailCalls + |> shouldSucceed + |> verifyIL [ + """ + .method public static void foo(int32& x, + int32& y, + !!a z) cil managed + { + + .maxstack 8 + IL_0000: ldstr "%d" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: ldobj [runtime]System.Int32 + IL_0015: ldarg.1 + IL_0016: ldobj [runtime]System.Int32 + IL_001b: add + IL_001c: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0021: pop + IL_0022: ret + } + """ + """ + .method public static void run() cil managed + { + + .maxstack 5 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: ldloca.s V_0 + IL_0006: ldc.i4.5 + IL_0007: call void TailCall05::foo(int32&, + int32&, + !!0) + IL_000c: nop + IL_000d: ret + } + """ + ] + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs new file mode 100644 index 00000000000..38a86274de6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TupleElimination.fs @@ -0,0 +1,799 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.EmittedIL + +open Xunit +open FSharp.Test.Compiler + +module ``TupleElimination`` = + + [] + let ``Sequence expressions with potential side effects do not prevent tuple elimination``() = + FSharp """ +module TupleElimination +open System.Runtime.CompilerServices + +[] +let f () = 3 + +[] +let sideEffect () = () + +type Test = + [] + static member test(x: int32 * int32) = x + +let v () = + let a, b = + "".ToString () |> ignore + System.DateTime.Now |> ignore + "3".ToString () |> ignore + 2L, f () + System.DateTime.Now |> ignore + a, b + +let w () = + let (a, b) as t = + "".ToString () |> ignore + System.DateTime.Now |> ignore + "3".ToString () |> ignore + 2, f () + System.DateTime.Now |> ignore + let _ = Test.test(t) + a + b + +let x () = + let a, b = + "".ToString () |> ignore + System.DateTime.Now |> ignore + "3".ToString () |> ignore + 2, f () + System.DateTime.Now |> ignore + a + b + +let y () = + let a, b, c = + let a = f () + sideEffect () + a, f (), f () + a + b + c + +let z () = + let a, b, c = + let u, v = 3, 4 + sideEffect () + f (), f () + u, f () + v + a + b + c + """ + |> compile + |> shouldSucceed + |> verifyIL [ + +(* +public static Tuple v() +{ + string text = "".ToString(); + DateTime now = DateTime.Now; + text = "3".ToString(); + int item = TupleElimination.f(); + now = DateTime.Now; + return new Tuple(2L, item); +} +*) + """ +.method public static class [runtime]System.Tuple`2 + v() cil managed +{ + + .maxstack 4 + .locals init (string V_0, + valuetype [runtime]System.DateTime V_1, + int32 V_2) + IL_0000: ldstr "" + IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_000a: stloc.0 + IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0010: stloc.1 + IL_0011: ldstr "3" + IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_001b: stloc.0 + IL_001c: call int32 TupleElimination::f() + IL_0021: stloc.2 + IL_0022: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0027: stloc.1 + IL_0028: ldc.i4.2 + IL_0029: conv.i8 + IL_002a: ldloc.2 + IL_002b: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0030: ret +} +""" + +(* +public static int w() +{ + string text = "".ToString(); + DateTime now = DateTime.Now; + text = "3".ToString(); + int num = TupleElimination.f(); + Tuple x = new Tuple(2, num); + now = DateTime.Now; + TupleElimination.Test.test(x); + return 2 + num; +} +*) + """ +.method public static int32 w() cil managed +{ + + .maxstack 4 + .locals init (string V_0, + valuetype [runtime]System.DateTime V_1, + int32 V_2, + class [runtime]System.Tuple`2 V_3) + IL_0000: ldstr "" + IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_000a: stloc.0 + IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0010: stloc.1 + IL_0011: ldstr "3" + IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_001b: stloc.0 + IL_001c: call int32 TupleElimination::f() + IL_0021: stloc.2 + IL_0022: ldc.i4.2 + IL_0023: ldloc.2 + IL_0024: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0029: stloc.3 + IL_002a: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_002f: stloc.1 + IL_0030: ldloc.3 + IL_0031: call class [runtime]System.Tuple`2 TupleElimination/Test::test(class [runtime]System.Tuple`2) + IL_0036: pop + IL_0037: ldc.i4.2 + IL_0038: ldloc.2 + IL_0039: add + IL_003a: ret +} +""" + +(* +public static int x() +{ + string text = "".ToString(); + DateTime now = DateTime.Now; + text = "3".ToString(); + int num = TupleElimination.f(); + now = DateTime.Now; + return 2 + num; +} +*) + """ +.method public static int32 x() cil managed +{ + + .maxstack 4 + .locals init (string V_0, + valuetype [runtime]System.DateTime V_1, + int32 V_2) + IL_0000: ldstr "" + IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_000a: stloc.0 + IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0010: stloc.1 + IL_0011: ldstr "3" + IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_001b: stloc.0 + IL_001c: call int32 TupleElimination::f() + IL_0021: stloc.2 + IL_0022: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0027: stloc.1 + IL_0028: ldc.i4.2 + IL_0029: ldloc.2 + IL_002a: add + IL_002b: ret +} +""" + +(* +public static int y() +{ + int num = TupleElimination.f(); + TupleElimination.sideEffect(); + return num + TupleElimination.f() + TupleElimination.f(); +} +*) + """ +.method public static int32 y() cil managed +{ + + .maxstack 4 + .locals init (int32 V_0) + IL_0000: call int32 TupleElimination::f() + IL_0005: stloc.0 + IL_0006: call void TupleElimination::sideEffect() + IL_000b: ldloc.0 + IL_000c: call int32 TupleElimination::f() + IL_0011: add + IL_0012: call int32 TupleElimination::f() + IL_0017: add + IL_0018: ret +} +""" + +(* +public static int z() +{ + TupleElimination.sideEffect(); + return TupleElimination.f() + (TupleElimination.f() + 3) + (TupleElimination.f() + 4); +} +*) + """ +.method public static int32 z() cil managed +{ + + .maxstack 8 + IL_0000: call void TupleElimination::sideEffect() + IL_0005: call int32 TupleElimination::f() + IL_000a: call int32 TupleElimination::f() + IL_000f: ldc.i4.3 + IL_0010: add + IL_0011: add + IL_0012: call int32 TupleElimination::f() + IL_0017: ldc.i4.4 + IL_0018: add + IL_0019: add + IL_001a: ret +} +""" ] + + [] + let ``First class use of tuple prevents elimination``() = + FSharp """ +module TupleElimination +open System.Runtime.CompilerServices + +[] +let f () = 3 + +[] +let cond () = true + +type Test = + [] + static member test(x: int32 * int32) = x + +let y () = + let a, b = + if cond () then + 1, 2 + else + Test.test(3, 4) + a + b + +let z () = + let a, b = + "".ToString () |> ignore + System.DateTime.Now |> ignore + "3".ToString () |> ignore + Test.test(2, f ()) + System.DateTime.Now |> ignore + a + b + """ + |> compile + |> shouldSucceed + |> verifyIL [ + +(* +public static int y() +{ + Tuple tuple = (!TupleElimination.cond()) ? TupleElimination.Test.test(new Tuple(3, 4)) : new Tuple(1, 2); + return tuple.Item1 + tuple.Item2; +} +*) + """ +.method public static int32 y() cil managed +{ + + .maxstack 4 + .locals init (class [runtime]System.Tuple`2 V_0) + IL_0000: call bool TupleElimination::cond() + IL_0005: brfalse.s IL_0010 + + IL_0007: ldc.i4.1 + IL_0008: ldc.i4.2 + IL_0009: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_000e: br.s IL_001c + + IL_0010: ldc.i4.3 + IL_0011: ldc.i4.4 + IL_0012: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0017: call class [runtime]System.Tuple`2 TupleElimination/Test::test(class [runtime]System.Tuple`2) + IL_001c: stloc.0 + IL_001d: ldloc.0 + IL_001e: call instance !0 class [runtime]System.Tuple`2::get_Item1() + IL_0023: ldloc.0 + IL_0024: call instance !1 class [runtime]System.Tuple`2::get_Item2() + IL_0029: add + IL_002a: ret +} +""" + +(* +public static int z() +{ + string text = "".ToString(); + DateTime now = DateTime.Now; + text = "3".ToString(); + Tuple tuple = TupleElimination.Test.test(new Tuple(2, TupleElimination.f())); + int item = tuple.Item2; + int item2 = tuple.Item1; + now = DateTime.Now; + return item2 + item; +} +*) + """ +.method public static int32 z() cil managed +{ + + .maxstack 4 + .locals init (class [runtime]System.Tuple`2 V_0, + string V_1, + valuetype [runtime]System.DateTime V_2, + int32 V_3, + int32 V_4) + IL_0000: ldstr "" + IL_0005: callvirt instance string [runtime]System.Object::ToString() + IL_000a: stloc.1 + IL_000b: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0010: stloc.2 + IL_0011: ldstr "3" + IL_0016: callvirt instance string [runtime]System.Object::ToString() + IL_001b: stloc.1 + IL_001c: ldc.i4.2 + IL_001d: call int32 TupleElimination::f() + IL_0022: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0027: call class [runtime]System.Tuple`2 TupleElimination/Test::test(class [runtime]System.Tuple`2) + IL_002c: stloc.0 + IL_002d: ldloc.0 + IL_002e: call instance !1 class [runtime]System.Tuple`2::get_Item2() + IL_0033: stloc.3 + IL_0034: ldloc.0 + IL_0035: call instance !0 class [runtime]System.Tuple`2::get_Item1() + IL_003a: stloc.s V_4 + IL_003c: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0041: stloc.2 + IL_0042: ldloc.s V_4 + IL_0044: ldloc.3 + IL_0045: add + IL_0046: ret +}""" ] + + [] + let ``Branching let binding rhs does not prevent tuple elimination``() = + FSharp """ +module TupleElimination +open System.Runtime.CompilerServices + +[] +let f () = 3 + +[] +let sideEffect () = () + +[] +let cond () = true + +type Test = + [] + static member test(x: int32 * int32) = x + +let x () = + let a, b = + sideEffect () + if cond () then + let v = "yep" + let v2 = if cond () then 1 else 3 + v, v2 + else + "", f () + a, b + +let rec y () = + let a, b, c = + if cond () then + "".ToString () |> ignore + 1, f (), 3 + else + if cond () then + 2, 2, 3 + else + match 1 / 0 with + | 1 -> + if 2 / 3 = 1 then + 5, 6, 7 + else + "".ToString () |> ignore + 6, 5, 4 + | 2 -> 6, 6, 6 + | 3 -> f (), 7, f () + | _ -> 8, y (), y () + + a + b + (2 * c) + +let z () = + let a, b = + if cond () then + 1, 3 + else + 3, 4 + a + b + """ + |> compile + |> shouldSucceed + |> verifyIL [ + +(* +public static Tuple x() +{ + TupleElimination.sideEffect(); + string item; + int item2; + if (TupleElimination.cond()) + { + int num = (!TupleElimination.cond()) ? 3 : 1; + item = "yep"; + item2 = num; + } + else + { + item = ""; + item2 = TupleElimination.f(); + } + return new Tuple(item, item2); +} +*) + """ +.method public static class [runtime]System.Tuple`2 + x() cil managed +{ + + .maxstack 4 + .locals init (string V_0, + int32 V_1, + int32 V_2) + IL_0000: call void TupleElimination::sideEffect() + IL_0005: call bool TupleElimination::cond() + IL_000a: brfalse.s IL_0022 + + IL_000c: call bool TupleElimination::cond() + IL_0011: brfalse.s IL_0016 + + IL_0013: ldc.i4.1 + IL_0014: br.s IL_0017 + + IL_0016: ldc.i4.3 + IL_0017: stloc.2 + IL_0018: ldstr "yep" + IL_001d: stloc.0 + IL_001e: ldloc.2 + IL_001f: stloc.1 + IL_0020: br.s IL_002e + + IL_0022: ldstr "" + IL_0027: stloc.0 + IL_0028: call int32 TupleElimination::f() + IL_002d: stloc.1 + IL_002e: ldloc.0 + IL_002f: ldloc.1 + IL_0030: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, + !1) + IL_0035: ret +} +""" + +(* +public static int y() +{ + int num; + int num2; + int num3; + if (TupleElimination.cond()) + { + string text = "".ToString(); + num = 1; + num2 = TupleElimination.f(); + num3 = 3; + } + else if (TupleElimination.cond()) + { + num = 2; + num2 = 2; + num3 = 3; + } + else + { + switch (1 / 0) + { + case 1: + if (2 / 3 == 1) + { + num = 5; + num2 = 6; + num3 = 7; + } + else + { + string text = "".ToString(); + num = 6; + num2 = 5; + num3 = 4; + } + break; + case 2: + num = 6; + num2 = 6; + num3 = 6; + break; + case 3: + num = TupleElimination.f(); + num2 = 7; + num3 = TupleElimination.f(); + break; + default: + num = 8; + num2 = TupleElimination.y(); + num3 = TupleElimination.y(); + break; + } + } + return num + num2 + 2 * num3; +} +*) + """ +.method public static int32 y() cil managed +{ + + .maxstack 5 + .locals init (int32 V_0, + int32 V_1, + int32 V_2, + string V_3) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: stloc.1 + IL_0004: ldc.i4.0 + IL_0005: stloc.2 + IL_0006: call bool TupleElimination::cond() + IL_000b: brfalse.s IL_0027 + + IL_000d: ldstr "" + IL_0012: callvirt instance string [runtime]System.Object::ToString() + IL_0017: stloc.3 + IL_0018: ldc.i4.1 + IL_0019: stloc.0 + IL_001a: call int32 TupleElimination::f() + IL_001f: stloc.1 + IL_0020: ldc.i4.3 + IL_0021: stloc.2 + IL_0022: br IL_0095 + + IL_0027: call bool TupleElimination::cond() + IL_002c: brfalse.s IL_0036 + + IL_002e: ldc.i4.2 + IL_002f: stloc.0 + IL_0030: ldc.i4.2 + IL_0031: stloc.1 + IL_0032: ldc.i4.3 + IL_0033: stloc.2 + IL_0034: br.s IL_0095 + + IL_0036: ldc.i4.1 + IL_0037: ldc.i4.0 + IL_0038: div + IL_0039: ldc.i4.1 + IL_003a: sub + IL_003b: switch ( + IL_004e, + IL_006f, + IL_0077) + IL_004c: br.s IL_0087 + + IL_004e: ldc.i4.2 + IL_004f: ldc.i4.3 + IL_0050: div + IL_0051: ldc.i4.1 + IL_0052: bne.un.s IL_005c + + IL_0054: ldc.i4.5 + IL_0055: stloc.0 + IL_0056: ldc.i4.6 + IL_0057: stloc.1 + IL_0058: ldc.i4.7 + IL_0059: stloc.2 + IL_005a: br.s IL_0095 + + IL_005c: ldstr "" + IL_0061: callvirt instance string [runtime]System.Object::ToString() + IL_0066: stloc.3 + IL_0067: ldc.i4.6 + IL_0068: stloc.0 + IL_0069: ldc.i4.5 + IL_006a: stloc.1 + IL_006b: ldc.i4.4 + IL_006c: stloc.2 + IL_006d: br.s IL_0095 + + IL_006f: ldc.i4.6 + IL_0070: stloc.0 + IL_0071: ldc.i4.6 + IL_0072: stloc.1 + IL_0073: ldc.i4.6 + IL_0074: stloc.2 + IL_0075: br.s IL_0095 + + IL_0077: call int32 TupleElimination::f() + IL_007c: stloc.0 + IL_007d: ldc.i4.7 + IL_007e: stloc.1 + IL_007f: call int32 TupleElimination::f() + IL_0084: stloc.2 + IL_0085: br.s IL_0095 + + IL_0087: ldc.i4.8 + IL_0088: stloc.0 + IL_0089: call int32 TupleElimination::y() + IL_008e: stloc.1 + IL_008f: call int32 TupleElimination::y() + IL_0094: stloc.2 + IL_0095: ldloc.0 + IL_0096: ldloc.1 + IL_0097: add + IL_0098: ldc.i4.2 + IL_0099: ldloc.2 + IL_009a: mul + IL_009b: add + IL_009c: ret +} +""" + +(* +public static int z() +{ + int num; + int num2; + if (TupleElimination.cond()) + { + num = 1; + num2 = 3; + } + else + { + num = 3; + num2 = 4; + } + return num + num2; +} +*) + """ +.method public static int32 z() cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + int32 V_1) + IL_0000: call bool TupleElimination::cond() + IL_0005: brfalse.s IL_000d + + IL_0007: ldc.i4.1 + IL_0008: stloc.0 + IL_0009: ldc.i4.3 + IL_000a: stloc.1 + IL_000b: br.s IL_0011 + + IL_000d: ldc.i4.3 + IL_000e: stloc.0 + IL_000f: ldc.i4.4 + IL_0010: stloc.1 + IL_0011: ldloc.0 + IL_0012: ldloc.1 + IL_0013: add + IL_0014: ret +}""" ] + + + + + [] + let ``Branching let binding of tuple with capture doesn't promote``() = + FSharp """ +module TupleElimination +open System.Runtime.CompilerServices + +let testFunction(a,b) = + let x,y = printfn "hello"; b*a,a*b + (fun () -> x + y) + """ + |> compile + |> shouldSucceed + |> verifyIL [ + // Checks the captured 'x' and 'y' are not promoted onto the heap + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 + testFunction(int32 a, + int32 b) cil managed +{ + + .maxstack 4 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0, + int32 V_1, + int32 V_2) + IL_0000: ldstr "hello" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldarg.1 + IL_0018: ldarg.0 + IL_0019: mul + IL_001a: stloc.1 + IL_001b: ldarg.0 + IL_001c: ldarg.1 + IL_001d: mul + IL_001e: stloc.2 + IL_001f: ldloc.1 + IL_0020: ldloc.2 + IL_0021: newobj instance void TupleElimination/testFunction@7::.ctor(int32, + int32) + IL_0026: ret +} + +""" ] + + + + + [] + let ``Branching let binding of tuple gives good names in closure``() = + FSharp """ +module TupleElimination +open System.Runtime.CompilerServices + +let testFunction(a,b) = + let x,y = printfn "hello"; b*a,a*b + (fun () -> x + y) + """ + |> compile + |> shouldSucceed + |> verifyIL [ + + // Checks the names of captured 'x' and 'y'. + """ + + .method public strict virtual instance int32 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar0) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 TupleElimination/testFunction@7::x + IL_0006: ldarg.0 + IL_0007: ldfld int32 TupleElimination/testFunction@7::y + IL_000c: add + IL_000d: ret + } +""" ] + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs new file mode 100644 index 00000000000..758ef242087 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AccessOfTypeAbbreviationTests.fs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler +open FSharp.Compiler.Diagnostics + +module ``Access Of Type Abbreviation`` = + + let warning44Message = "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in." + System.Environment.NewLine + "As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." + + [] + let ``Private type produces warning when trying to export``() = + FSharp """ +module Library = + type private Hidden = Hidden of unit + type Exported = Hidden + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 44, Line 4, Col 8, Line 4, Col 16, warning44Message) + + [] + let ``Internal type passes when abbrev is internal``() = + FSharp """ +module Library = + type internal Hidden = Hidden of unit + type internal Exported = Hidden + """ + |> typecheck + |> shouldSucceed + + [] + let ``Internal type produces warning when trying to export``() = + FSharp """ +module Library = + type internal Hidden = Hidden of unit + type Exported = Hidden + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 44, Line 4, Col 8, Line 4, Col 16, warning44Message) + + [] + let ``Private type produces warning when abbrev is internal``() = + FSharp """ +module Library = + type private Hidden = Hidden of unit + type internal Exported = Hidden + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 44, Line 4, Col 17, Line 4, Col 25, warning44Message) + + [] + let ``Private type passes when abbrev is private``() = + FSharp """ +module Library = + type private Hidden = Hidden of unit + type private Exported = Hidden + """ + |> typecheck + |> shouldSucceed + + [] + let ``Default access type passes when abbrev is default``() = + FSharp """ +module Library = + type Hidden = Hidden of unit + type Exported = Hidden + """ + |> typecheck + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs new file mode 100644 index 00000000000..cd7265df829 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/AssignmentErrorTests.fs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Errors assigning to mutable objects`` = + + [] + let ``Assign to immutable error``() = + FSharp """ +let x = 10 +x <- 20 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 27, Line 3, Col 1, Line 3, Col 8, + "This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs new file mode 100644 index 00000000000..621307f4e66 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs @@ -0,0 +1,123 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Classes`` = + + [] + let ``Tuple In Abstract Method``() = + FSharp """ +type IInterface = + abstract Function : (int32 * int32) -> unit + +let x = + { new IInterface with + member this.Function (i, j) = () + } + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 768, Line 7, Col 16, Line 7, Col 36, "The member 'Function' does not accept the correct number of arguments. 1 argument(s) are expected, but 2 were given. The required signature is 'IInterface.Function: (int32 * int32) -> unit'.\nA tuple type is required for one or more arguments. Consider wrapping the given arguments in additional parentheses or review the definition of the interface.") + (Error 17, Line 7, Col 21, Line 7, Col 29, "The member 'Function: 'a * 'b -> unit' does not have the correct type to override the corresponding abstract method. The required signature is 'Function: (int32 * int32) -> unit'.") + (Error 783, Line 6, Col 9, Line 6, Col 19, "At least one override did not correctly implement its corresponding abstract member")] + + [] + let ``Wrong Arity``() = + FSharp """ +type MyType() = + static member MyMember(arg1, arg2:int ) = () + static member MyMember(arg1, arg2:byte) = () + + +MyType.MyMember("", 0, 0) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 503, Line 7, Col 1, Line 7, Col 26, + "A member or object constructor 'MyMember' taking 3 arguments is not accessible from this code location. All accessible versions of method 'MyMember' take 2 arguments.") + + [] + let ``Method Is Not Static``() = + FSharp """ +type Class1() = + member this.X() = "F#" + +let x = Class1.X() + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 3214, Line 5, Col 9, Line 5, Col 17, "Method or object constructor 'X' is not static") + + [] + let ``Matching Method With Same Name Is Not Abstract``() = + FSharp """ +type Foo(x : int) = + member v.MyX() = x + +let foo = + { new Foo(3) + with + member v.MyX() = 4 } + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 767, Line 8, Col 16, Line 8, Col 23, "The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement.") + (Error 17, Line 8, Col 18, Line 8, Col 21, "The member 'MyX: unit -> int' does not have the correct type to override any given virtual method") + (Error 783, Line 6, Col 11, Line 6, Col 14, "At least one override did not correctly implement its corresponding abstract member")] + + [] + let ``No Matching Abstract Method With Same Name``() = + FSharp """ +type IInterface = + abstract MyFunction : int32 * int32 -> unit + abstract SomeOtherFunction : int32 * int32 -> unit + +let x = + { new IInterface with + member this.Function (i, j) = () + } + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 767, Line 8, Col 14, Line 8, Col 34, "The member 'Function' does not correspond to any abstract or virtual method available to override or implement. Maybe you want one of the following:" + System.Environment.NewLine + " MyFunction") + (Error 17, Line 8, Col 19, Line 8, Col 27, "The member 'Function: 'a * 'b -> unit' does not have the correct type to override any given virtual method") + (Error 366, Line 7, Col 3, Line 9, Col 4, "No implementation was given for those members: " + System.Environment.NewLine + "\t'abstract IInterface.MyFunction: int32 * int32 -> unit'" + System.Environment.NewLine + "\t'abstract IInterface.SomeOtherFunction: int32 * int32 -> unit'" + System.Environment.NewLine + "Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (Error 783, Line 7, Col 9, Line 7, Col 19, "At least one override did not correctly implement its corresponding abstract member")] + + [] + let ``Member Has Multiple Possible Dispatch Slots``() = + FSharp """ +type IOverload = + abstract member Bar : int -> int + abstract member Bar : double -> int + +type Overload = + interface IOverload with + override __.Bar _ = 1 + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 366, Line 7, Col 15, Line 7, Col 24, "No implementation was given for those members: " + System.Environment.NewLine + "\t'abstract IOverload.Bar: double -> int'" + System.Environment.NewLine + "\t'abstract IOverload.Bar: int -> int'" + System.Environment.NewLine + "Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (Error 3213, Line 8, Col 21, Line 8, Col 24, "The member 'Bar<'a0> : 'a0 -> int' matches multiple overloads of the same method.\nPlease restrict it to one of the following:" + System.Environment.NewLine + " Bar: double -> int" + System.Environment.NewLine + " Bar: int -> int.")] + + [] + let ``Do Cannot Have Visibility Declarations``() = + FSharp """ +type X() = + do () + private do () + static member Y() = 1 + """ + |> parse + |> shouldFail + |> withDiagnostics [ + (Error 531, Line 4, Col 5, Line 4, Col 12, "Accessibility modifiers should come immediately prior to the identifier naming a construct") + (Error 512, Line 4, Col 13, Line 4, Col 18, "Accessibility modifiers are not permitted on 'do' bindings, but 'Private' was given.") + (Error 222, Line 2, Col 1, Line 3, Col 1, "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.")] diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs new file mode 100644 index 00000000000..3bdd41b9795 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConfusingTypeName.fs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Confusing Type Name`` = + + [] + let ``Expected types with multiple references`` () = + + let csLibA = + CSharp """ +public class A { } +public class B { } + """ |> withName "libA" + + let csLibB = + csLibA |> withName "libB" + + let fsLibC = + FSharp """ +module AMaker +let makeA () : A = A() +let makeB () = B<_>() + """ |> withName "libC" |> withReferences [csLibA] + + let fsLibD = + FSharp """ +module OtherAMaker +let makeOtherA () : A = A() +let makeOtherB () = B<_>() + """ |> withName "libD" |> withReferences [csLibB] + + let app = + FSharp """ +module ConfusingTypeName +let a = AMaker.makeA() +let otherA = OtherAMaker.makeOtherA() +printfn "%A %A" (a.GetType().AssemblyQualifiedName) (otherA.GetType().AssemblyQualifiedName) +printfn "%A" (a = otherA) + +let b = AMaker.makeB() +let otherB = OtherAMaker.makeOtherB() +printfn "%A %A" (b.GetType().AssemblyQualifiedName) (otherB.GetType().AssemblyQualifiedName) +printfn "%A" (b = otherB) + """ |> withReferences [csLibA; csLibB; fsLibC; fsLibD] + + app + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 686, Line 8, Col 9, Line 8, Col 21, "The method or function 'makeB' should not be given explicit type argument(s) because it does not declare its type parameters explicitly") + (Warning 686, Line 9, Col 14, Line 9, Col 36, "The method or function 'makeOtherB' should not be given explicit type argument(s) because it does not declare its type parameters explicitly") + (Error 1, Line 6, Col 19, Line 6, Col 25, "This expression was expected to have type\n 'A (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'A (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ") + (Error 1, Line 11, Col 19, Line 11, Col 25, "This expression was expected to have type\n 'B (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'B (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ") + ] diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs new file mode 100644 index 00000000000..71ec6524a92 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ConstructorTests.fs @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Constructor`` = + + [] + let ``Invalid Record``() = + FSharp """ +type Record = {field1:int; field2:int} +let doSomething (xs) = List.map (fun {field1=x} -> x) xs +doSomething {Record.field1=0; field2=0} + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 13, Line 4, Col 40, "This expression was expected to have type\n 'Record list' \nbut here has type\n 'Record' ") + (Warning 20, Line 4, Col 1, Line 4, Col 40, "The result of this expression has type 'int list' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")] + + [] + let ``Comma In Rec Ctor``() = + FSharp """ +type Person = { Name : string; Age : int; City : string } +let x = { Name = "Isaac", Age = 21, City = "London" } + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 3, Col 18, Line 3, Col 52, "This expression was expected to have type\n 'string' \nbut here has type\n ''a * 'b * 'c' " + System.Environment.NewLine + "A ';' is used to separate field values in records. Consider replacing ',' with ';'.") + (Error 764, Line 3, Col 9, Line 3, Col 54, "No assignment given for field 'Age' of type 'Test.Person'")] + + [] + let ``Missing Comma In Ctor``() = + FSharp """ +type Person() = + member val Name = "" with get,set + member val Age = 0 with get,set + +let p = + Person(Name = "Fred" + Age = 18) + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 39, Line 7, Col 12, Line 7, Col 16, "The value or constructor 'Name' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " nameof" + System.Environment.NewLine + " nan") + (Warning 20, Line 7, Col 12, Line 7, Col 25, "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'.") + (Error 39, Line 8, Col 12, Line 8, Col 15, "The value or constructor 'Age' is not defined.") + (Error 501, Line 7, Col 5, Line 8, Col 21, "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> Person'. If some of the arguments are meant to assign values to properties, consider separating those arguments with a comma (',').")] + + [] + let ``Missing Ctor Value``() = + FSharp """ +type Person(x:int) = + member val Name = "" with get,set + member val Age = x with get,set + +let p = + Person(Name = "Fred", + Age = 18) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 496, Line 7, Col 5, Line 8, Col 21, "The member or object constructor 'Person' requires 1 argument(s). The required signature is 'new: x: int -> Person'.") + + [] + let ``Extra Argument In Ctor``() = + FSharp """ +type Person() = + member val Name = "" with get,set + member val Age = 0 with get,set + +let p = + Person(1) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 501, Line 7, Col 5, Line 7, Col 14, + "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> Person'.") + + [] + let ``Extra Argument In Ctor2``() = + FSharp """ +type Person() = + member val Name = "" with get,set + member val Age = 0 with get,set + +let b = 1 + +let p = + Person(1=b) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 501, Line 9, Col 5, Line 9, Col 16, + "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> Person'.") + + [] + let ``Valid Comma In Rec Ctor``() = + FSharp """ +type Person = { Name : string * bool * bool } +let Age = 22 +let City = "London" +let x = { Name = "Isaac", Age = 21, City = "London" } + """ |> typecheck |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs new file mode 100644 index 00000000000..c65b02db61f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DontSuggestTests.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Don't Suggest`` = + + [] + let ``Dont Suggest Completely Wrong Stuff``() = + FSharp """ +let _ = Path.GetFullPath "images" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 9, Line 2, Col 13, + "The value, namespace, type or module 'Path' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Math") + + [] + let ``Dont Suggest When Things Are Open``() = + FSharp """ +module N = + let name = "hallo" + +type T = + static member myMember = 1 + +let x = N. + """ + |> parse + |> shouldFail + |> withDiagnostics [ + (Error 599, Line 8, Col 10, Line 8, Col 11, "Missing qualification after '.'") + (Error 222, Line 2, Col 1, Line 3, Col 1, "Files in libraries or multiple-file applications must begin with a namespace or module declaration. When using a module declaration at the start of a file the '=' sign is not allowed. If this is a top-level module, consider removing the = to resolve this error.")] + + [] + let ``Dont Suggest Intentionally Unused Variables``() = + FSharp """ +let hober xy _xyz = xyz + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 21, Line 2, Col 24, "The value or constructor 'xyz' is not defined.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs new file mode 100644 index 00000000000..250fc8f674b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ElseBranchHasWrongTypeTests.fs @@ -0,0 +1,171 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Else branch has wrong type`` = + + [] + let ``Else branch is int while if branch is string``() = + FSharp """ +let test = 100 +let y = + if test > 10 then "test" + else 123 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 5, Col 10, Line 5, Col 13, + "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'string'. This branch returns a value of type 'int'.") + + [] + let ``Else branch is a function that returns int while if branch is string``() = + FSharp """ +let test = 100 +let f x = test +let y = + if test > 10 then "test" + else f 10 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 6, Col 10, Line 6, Col 14, + "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'string'. This branch returns a value of type 'int'.") + + + [] + let ``Else branch is a sequence of expressions that returns int while if branch is string``() = + FSharp """ +let f x = x + 4 + +let y = + if true then + "" + else + "" |> ignore + (f 5) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 9, Col 10, Line 9, Col 13, + "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'string'. This branch returns a value of type 'int'.") + + + [] + let ``Else branch is a longer sequence of expressions that returns int while if branch is string``() = + FSharp """ +let f x = x + 4 + +let y = + if true then + "" + else + "" |> ignore + let z = f 4 + let a = 3 * z + (f a) + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 11, Col 10, Line 11, Col 13, + "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'string'. This branch returns a value of type 'int'.") + + + [] + let ``Else branch context doesn't propagate into function application``() = + FSharp """ +let test = 100 +let f x : string = x +let y = + if test > 10 then "test" + else + f 123 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 7, Col 11, Line 7, Col 14, + "This expression was expected to have type\n 'string' \nbut here has type\n 'int' ") + + [] + let ``Else branch context doesn't propagate into function application even if not last expr``() = + FSharp """ +let test = 100 +let f x = printfn "%s" x +let y = + if test > 10 then "test" + else + f 123 + "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 7, Col 11, Line 7, Col 14, + "This expression was expected to have type\n 'string' \nbut here has type\n 'int' ") + + [] + let ``Else branch context doesn't propagate into for loop``() = + FSharp """ +let test = 100 +let list = [1..10] +let y = + if test > 10 then "test" + else + for (x:string) in list do + printfn "%s" x + + "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 7, Col 14, Line 7, Col 22, + "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") + + [] + let ``Else branch context doesn't propagate to lines before last line``() = + FSharp """ +let test = 100 +let list = [1..10] +let y = + if test > 10 then "test" + else + printfn "%s" 1 + + "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 7, Col 22, Line 7, Col 23, + "This expression was expected to have type\n 'string' \nbut here has type\n 'int' ") + + [] + let ``Else branch should not have wrong context type``() = + FSharp """ +let x = 1 +let y : bool = + if x = 2 then "A" + else "B" + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 19, Line 4, Col 22, "The 'if' expression needs to have type 'bool' to satisfy context type requirements. It currently has type 'string'.") + (Error 1, Line 5, Col 10, Line 5, Col 13, "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'bool'. This branch returns a value of type 'string'.")] + + + [] + let ``Else branch has wrong type in nested if``() = + FSharp """ +let x = 1 +if x = 1 then true +else + if x = 2 then "A" + else "B" + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 5, Col 19, Line 5, Col 22, "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'bool'. This branch returns a value of type 'string'.") + (Error 1, Line 6, Col 10, Line 6, Col 13, "All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'bool'. This branch returns a value of type 'string'.") + (Warning 20, Line 3, Col 1, Line 6, Col 13, "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")] diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs new file mode 100644 index 00000000000..bf6630b4313 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Invalid literals`` = + + [] + let ``Using Active Pattern``() = + FSharp """ +let (|A|) x = x + 1 +let [] (A x) = 1 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 3391, Line 3, Col 5, Line 3, Col 22, "A [] declaration cannot use an active pattern for its identifier") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs new file mode 100644 index 00000000000..90cf5dd9db1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidNumericLiteralTests.fs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.AbstractIL + +module ``Numeric Literals`` = + + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + let ``Invalid Numeric Literals`` literal = + FSharp ("let x = " + literal) + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1156, Line 1, Col 9, Line 1, Col (9 + (String.length literal)), + "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).") + + [] + let ``3_(dot)1415F is invalid numeric literal``() = + FSharp "let x = 3_.1415F" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1156, Line 1, Col 9, Line 1, Col 11, "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger).";) + (Error 599, Line 1, Col 11, Line 1, Col 12,"Missing qualification after '.'")] + + [] + let ``_52 is invalid numeric literal``() = + FSharp "let x = _52" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 1, Col 9, Line 1, Col 12, "The value or constructor '_52' is not defined.") + + + [] + let ``1N is invalid numeric literal``() = + FSharp "let x = 1N" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 0784, Line 1, Col 9, Line 1, Col 11, + "This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope") + + [] + let ``1N is invalid numeric literal in FSI``() = + CompilerAssert.RunScriptWithOptions [| "--langversion:5.0"; "--test:ErrorRanges" |] + """ +let x = 1N + """ + [ + "This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope"; + "Operation could not be completed due to earlier error" + ] + + // Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents + [] + [] + [] + let ``Valid Numeric Literals`` literal = + FSharp ("let x = " + literal) + |> typecheck |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs new file mode 100644 index 00000000000..ca414c212b5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingElseBranch.fs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Else branch is missing`` = + + [] + let ``Fail if else branch is missing``() = + FSharp """ +let x = 10 +let y = + if x > 10 then "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 4, Col 19, Line 4, Col 25, + "This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'string'.") + + [] + let ``Fail on type error in condition``() = + FSharp """ +let x = 10 +let y = + if x > 10 then + if x <> "test" then printfn "test" + () + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 5, Col 14, Line 5, Col 20, + "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") + + [] + let ``Fail if else branch is missing in nesting``() = + FSharp """ +let x = 10 +let y = + if x > 10 then ("test") + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 4, Col 20, Line 4, Col 26, + "This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'string'.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs new file mode 100644 index 00000000000..ec18fb6152d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/MissingExpressionTests.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + + +module ``Missing Expression`` = + + [] + let ``Missing Expression after let``() = + FSharp """ +let sum = 0 +for x in 0 .. 10 do + let sum = sum + x + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 588, Line 4, Col 5, Line 4, Col 8, + "The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs new file mode 100644 index 00000000000..7d4c130ab54 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ModuleTests.fs @@ -0,0 +1,210 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + + +module Modules = + + [] + let ``Public Module Abbreviation``() = + FSharp "module public L1 = List" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7, + "The 'Public' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.") + + [] + let ``Private Module Abbreviation``() = + FSharp "module private L1 = List" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7, + "The 'Private' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.") + + [] + let ``Internal Module Abbreviation``() = + FSharp "module internal L1 = List" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 536, Line 1, Col 1, Line 1, Col 7, + "The 'Internal' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private.") + [] + let ``Rec Module Abbreviation``() = + FSharp "module rec L1 = List" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 3203, Line 1, Col 1, Line 1, Col 14, + "Invalid use of 'rec' keyword") + + [] + let ``Left Attribute Module Abbreviation``() = + FSharp """[] module L1 = List""" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 32, + "Ignoring attributes on module abbreviation") + + [] + let ``Right Attribute Module Abbreviation``() = + FSharp """module [] L1 = List""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 35, + "Ignoring attributes on module abbreviation") + + [] + let ``Right Attribute Module Abbreviation without preview (typecheck)``() = + FSharp """module [] L1 = List""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 3350, Line 1, Col 33, Line 1, Col 35, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater." + Error 535, Line 1, Col 1, Line 1, Col 35, "Ignoring attributes on module abbreviation" + ] + + [] + let ``Right Attribute Module Abbreviation without preview (compile)``() = + FSharp """module [] L1 = List""" + |> compile + |> shouldFail + |> withDiagnostics [ + Error 3350, Line 1, Col 33, Line 1, Col 35, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater." + Error 535, Line 1, Col 1, Line 1, Col 35, "Ignoring attributes on module abbreviation" + Error 222, Line 1, Col 1, Line 1, Col 42, "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration." + ] + + [] + let ``Attribute Module Abbreviation``() = + FSharp """[] module [] internal L1 = List""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 535, Line 1, Col 1, Line 1, Col 32, + "Ignoring attributes on module abbreviation") + + [] + let ``Attributes applied successfully``() = + Fsx """ +[] module [] rec L1 = type L2() = do () +match typeof.DeclaringType.GetCustomAttributes false with +| [|:? AutoOpenAttribute; :? ExperimentalAttribute as experimental; :? CompilationMappingAttribute as compilationMapping|] -> + if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %A" compilationMapping.SourceConstructFlags + if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message +| t -> failwithf "Attribute array is not of length 3 and correct types: %A" t + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + [] + let ``Attributes applied successfully 2``() = + Fsx """ +open System +open System.ComponentModel +[] [] module [][] private rec L1 = type L2() = do () +match typeof.DeclaringType.GetCustomAttributes false with +| [|:? ObsoleteAttribute as obsolete + :? BrowsableAttribute as browsable + :? BindableAttribute as bindable + :? AmbientValueAttribute as ambientValue + :? ExperimentalAttribute as experimental + :? CategoryAttribute as category + :? DefaultValueAttribute as defaultValue + :? AutoOpenAttribute + :? CompilationMappingAttribute as compilationMapping|] -> + if obsolete.Message <> "Hi" then failwithf "Obsolete attribute did not contain the correct message: %s" obsolete.Message + if browsable.Browsable <> false then failwithf "Browsable attribute did not contain the correct flag: %b" browsable.Browsable + if bindable.Bindable <> true then failwithf "Bindable attribute did not contain the correct flag: %b" bindable.Bindable + if ambientValue.Value <> box false then failwithf "AmbientValue attribute did not contain the correct value: %O" ambientValue.Value + if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message + if category.Category <> "Oi" then failwithf "Category attribute did not contain the correct category: %s" category.Category + if defaultValue.Value <> box "Howdy" then failwithf "DefaultValue attribute did not contain the correct value: %O" defaultValue.Value + if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %O" compilationMapping.SourceConstructFlags +| t -> failwithf "Attribute array is not of length 9 and correct types: %A" t + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + [] + let ``Fun attribute indentation``() = + Fsx """ +open System +open System.ComponentModel +[][] module + [] + [] + private + rec + L1 + = + type + [] + [] + L2 + () + = + let + [] + [] + a + = + 1 + member _.A = a +match typeof.DeclaringType.GetCustomAttributes false with +| [|:? ObsoleteAttribute as obsolete + :? BrowsableAttribute as browsable + :? BindableAttribute as bindable + :? AmbientValueAttribute as ambientValue + :? ExperimentalAttribute as experimental + :? CategoryAttribute as category + :? DefaultValueAttribute as defaultValue + :? AutoOpenAttribute + :? CompilationMappingAttribute as compilationMapping|] -> + if obsolete.Message <> "Hi" then failwithf "Obsolete attribute did not contain the correct message: %s" obsolete.Message + if browsable.Browsable <> false then failwithf "Browsable attribute did not contain the correct flag: %b" browsable.Browsable + if bindable.Bindable <> true then failwithf "Bindable attribute did not contain the correct flag: %b" bindable.Bindable + if ambientValue.Value <> box false then failwithf "AmbientValue attribute did not contain the correct value: %O" ambientValue.Value + if experimental.Message <> "Hello" then failwithf "Experimental attribute did not contain the correct message: %s" experimental.Message + if category.Category <> "Oi" then failwithf "Category attribute did not contain the correct category: %s" category.Category + if defaultValue.Value <> box "Howdy" then failwithf "DefaultValue attribute did not contain the correct value: %O" defaultValue.Value + if compilationMapping.SourceConstructFlags <> SourceConstructFlags.Module then failwithf "CompilationMapping attribute did not contain the correct SourceConstructFlags: %O" compilationMapping.SourceConstructFlags +| t -> failwithf "Attribute array is not of length 9 and correct types: %A" t + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + + [] + let ``Offside rule works for attributes inside module declarations``() = + Fsx """ +module [< +AutoOpen>] L1 = do () + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 10, Line 3, Col 1, Line 3, Col 9, "Unexpected start of structured construct in attribute list" + Error 3350, Line 3, Col 1, Line 3, Col 9, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater." + ] + + [] + let ``Offside rule works for attributes inside module declarations without preview``() = + Fsx """ +module [< +AutoOpen>] L1 = do () + """ + |> compile + |> shouldFail + |> withDiagnostics [ + Error 10, Line 3, Col 1, Line 3, Col 9, "Unexpected start of structured construct in attribute list" + Error 3350, Line 3, Col 1, Line 3, Col 9, "Feature 'attributes to the right of the 'module' keyword' is not available in F# 5.0. Please use language version 'preview' or greater." + ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs new file mode 100644 index 00000000000..74f62a1c3be --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module NameResolutionTests = + + [] + let FieldNotInRecord () = + FSharp """ +type A = { Hello:string; World:string } +type B = { Size:int; Height:int } +type C = { Wheels:int } +type D = { Size:int; Height:int; Walls:int } +type E = { Unknown:string } +type F = { Wallis:int; Size:int; Height:int; } + +let r:F = { Size=3; Height=4; Wall=1 } + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1129, Line 9, Col 31, Line 9, Col 35, + ("The record type 'F' does not contain a label 'Wall'. Maybe you want one of the following:" + System.Environment.NewLine + " Wallis")) + + [] + let RecordFieldProposal () = + FSharp """ +type A = { Hello:string; World:string } +type B = { Size:int; Height:int } +type C = { Wheels:int } +type D = { Size:int; Height:int; Walls:int } +type E = { Unknown:string } +type F = { Wallis:int; Size:int; Height:int; } + +let r = { Size=3; Height=4; Wall=1 } + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 9, Col 29, Line 9, Col 33, + ("The record label 'Wall' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Walls" + System.Environment.NewLine + " Wallis")) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs new file mode 100644 index 00000000000..7d86ada35e8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/SuggestionsTests.fs @@ -0,0 +1,261 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open System +open Xunit +open FSharp.Test.Compiler + +module Suggestions = + + [] + let ``Field Suggestion`` () = + FSharp """ +type Person = { Name : string; } + +let x = { Person.Names = "Isaac" } + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 4, Col 18, Line 4, Col 23, + ("The type 'Person' does not define the field, constructor or member 'Names'. Maybe you want one of the following:" + Environment.NewLine + " Name")) + + [] + let ``Suggest Array Module Functions`` () = + FSharp "let f = Array.blt" + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 1, Col 15, Line 1, Col 18, + ("The value, constructor, namespace or type 'blt' is not defined. Maybe you want one of the following:" + Environment.NewLine + " blit")) + + [] + let ``Suggest Async Module`` () = + FSharp "let f = Asnc.Sleep 1000" + |> typecheck + |> shouldFail + |> withSingleDiagnostic( Error 39, Line 1, Col 9, Line 1, Col 13, + ("The value, namespace, type or module 'Asnc' is not defined. Maybe you want one of the following:" + Environment.NewLine + " Async" + Environment.NewLine + " async" + Environment.NewLine + " asin" + Environment.NewLine + " snd")) + + [] + let ``Suggest Attribute`` () = + FSharp """ +[] +type MyClass<'Bar>() = + abstract M<'T> : 'T -> 'T + abstract M2<'T> : 'T -> 'Bar + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 3, Line 2, Col 15, + ("The type 'AbstractClas' is not defined. Maybe you want one of the following:" + Environment.NewLine + " AbstractClass" + Environment.NewLine + " AbstractClassAttribute")) + + [] + let ``Suggest Double Backtick Identifiers`` () = + FSharp """ +module N = + let ``longer name`` = "hallo" + +let x = N.``longe name`` + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 5, Col 11, Line 5, Col 25, + ("The value, constructor, namespace or type 'longe name' is not defined. Maybe you want one of the following:" + Environment.NewLine + " ``longer name``")) + + [] + let ``Suggest Double Backtick Unions`` () = + FSharp """ +module N = + type MyUnion = + | ``My Case1`` + | Case2 + +open N + +let x = N.MyUnion.``My Case2`` + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 9, Col 19, Line 9,Col 31, + ("The type 'MyUnion' does not define the field, constructor or member 'My Case2'. Maybe you want one of the following:" + Environment.NewLine + " Case2" + Environment.NewLine + " ``My Case1``")) + + + [] + let ``Suggest Fields In Constructor`` () = + FSharp """ +type MyClass() = + member val MyProperty = "" with get, set + member val MyProperty2 = "" with get, set + member val ABigProperty = "" with get, set + +let c = MyClass(Property = "") + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 495, Line 7, Col 17, Line 7, Col 25, + ("The object constructor 'MyClass' has no argument or settable return property 'Property'. The required signature is new: unit -> MyClass. Maybe you want one of the following:" + Environment.NewLine + " MyProperty" + Environment.NewLine + " MyProperty2" + Environment.NewLine + " ABigProperty")) + + [] + let ``Suggest Generic Type`` () = + FSharp """ +type T = System.Collections.Generic.Dictionary + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 48, Line 2, Col 53, + ("The type 'int11' is not defined. Maybe you want one of the following:" + Environment.NewLine + " int16" + Environment.NewLine + " int8" + Environment.NewLine + " uint16" + Environment.NewLine + " int" + Environment.NewLine + " int32")) + + [] + let ``Suggest Methods`` () = + FSharp """ +module Test2 = + type D() = + + static let x = 1 + + member x.Method1() = 10 + + D.Method2() + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 9, Col 7, Line 9, Col 14, + ("The type 'D' does not define the field, constructor or member 'Method2'. Maybe you want one of the following:" + Environment.NewLine + " Method1")) + + [] + let ``Suggest Modules`` () = + FSharp """ +module Collections = + + let f () = printfn "%s" "Hello" + +open Collectons + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 6, Col 6, Line 6, Col 16, + ("The namespace or module 'Collectons' is not defined. Maybe you want one of the following:" + Environment.NewLine + " Collections")) + + [] + let ``Suggest Namespaces`` () = + FSharp """ +open System.Collectons + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 13, Line 2, Col 23, + "The namespace 'Collectons' is not defined.") + + [] + let ``Suggest Record Labels`` () = + FSharp """ +type MyRecord = { Hello: int; World: bool} + +let r = { Hello = 2 ; World = true} + +let x = r.ello + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 6, Col 11, Line 6, Col 15, + ("The type 'MyRecord' does not define the field, constructor or member 'ello'. Maybe you want one of the following:" + Environment.NewLine + " Hello")) + + [] + let ``Suggest Record Type for RequireQualifiedAccess Records`` () = + FSharp """ +[] +type MyRecord = { + Field1: string + Field2: int +} + +let r = { Field1 = "hallo"; Field2 = 1 } + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 8, Col 11, Line 8, Col 17, + ("The record label 'Field1' is not defined. Maybe you want one of the following:" + Environment.NewLine + " MyRecord.Field1")) + + [] + let ``Suggest Type Parameters`` () = + FSharp """ +[] +type MyClass<'Bar>() = + abstract M<'T> : 'T -> 'T + abstract M2<'T> : 'T -> 'Bar + abstract M3<'T> : 'T -> 'B + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 6, Col 28, Line 6, Col 30, + "The type parameter 'B is not defined.") + + + [] + let ``Suggest Types in Module`` () = + FSharp """ +let x : System.Collections.Generic.Lst = ResizeArray() + """ |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 36, Line 2, Col 39, + ("The type 'Lst' is not defined in 'System.Collections.Generic'. Maybe you want one of the following:" + Environment.NewLine + " List" + Environment.NewLine + " IList")) + + [] + let ``Suggest Types in Namespace`` () = + FSharp """ +let x = System.DateTie.MaxValue + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 2, Col 16, Line 2, Col 23, + ("The value, constructor, namespace or type 'DateTie' is not defined. Maybe you want one of the following:" + Environment.NewLine + " DateTime" + Environment.NewLine + " DateTimeKind" + Environment.NewLine + " DateTimeOffset" + Environment.NewLine + " Data")) + + [] + let ``Suggest Union Cases`` () = + FSharp """ +type MyUnion = +| ASimpleCase +| AnotherCase of int + +let u = MyUnion.AntherCase + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 6, Col 17, Line 6, Col 27, + ("The type 'MyUnion' does not define the field, constructor or member 'AntherCase'. Maybe you want one of the following:" + Environment.NewLine + " AnotherCase")) + + [] + let ``Suggest Union Type for RequireQualifiedAccess Unions`` () = + FSharp """ +[] +type MyUnion = +| MyCase1 +| MyCase2 of string + +let x : MyUnion = MyCase1 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 7, Col 19, Line 7, Col 26, + ("The value or constructor 'MyCase1' is not defined. Maybe you want one of the following:" + Environment.NewLine + " MyUnion.MyCase1")) + + + [] + let ``Suggest Unions in PatternMatch`` () = + FSharp """ +[] +type MyUnion = +| Case1 +| Case2 + +let y = MyUnion.Case1 + +let x = + match y with + | MyUnion.Cas1 -> 1 + | _ -> 2 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 11, Col 15, Line 11, Col 19, + ("The type 'MyUnion' does not define the field, constructor or member 'Cas1'. Maybe you want one of the following:" + Environment.NewLine + " Case1" + Environment.NewLine + " Case2")) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs new file mode 100644 index 00000000000..3dacfbfde6e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeEqualsMissingTests.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test +open FSharp.Compiler.Diagnostics + + +module ``Type definition missing equals`` = + + [] + let ``Missing equals in DU``() = + CompilerAssert.TypeCheckSingleError + """ +type X | A | B + """ + FSharpDiagnosticSeverity.Error + 3360 + (2, 8, 2, 9) + "Unexpected token in type definition. Expected '=' after the type 'X'." diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs new file mode 100644 index 00000000000..24adc58d391 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Type Mismatch`` = + + [] + let ``return Instead Of return!``() = + FSharp """ +let rec foo() = async { return foo() } + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 2, Col 32, Line 2, Col 37, + "Type mismatch. Expecting a\n ''a' \nbut given a\n 'Async<'a>' \nThe types ''a' and 'Async<'a>' cannot be unified. Consider using 'return!' instead of 'return'.") + + [] + let ``yield Instead Of yield!``() = + FSharp """ +type Foo() = + member this.Yield(x) = [x] + +let rec f () = Foo() { yield f ()} + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 5, Col 30, Line 5, Col 34, + "Type mismatch. Expecting a\n ''a' \nbut given a\n ''a list' \nThe types ''a' and ''a list' cannot be unified. Consider using 'yield!' instead of 'yield'.") + + [] + let ``Ref Cell Instead Of Not``() = + FSharp """ +let x = true +if !x then + printfn "hello" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 3, Col 5, Line 3, Col 6, + ("This expression was expected to have type\n 'bool ref' \nbut here has type\n 'bool' " + System.Environment.NewLine + "The '!' operator is used to dereference a ref cell. Consider using 'not expr' here.")) + + [] + let ``Ref Cell Instead Of Not 2``() = + FSharp """ +let x = true +let y = !x + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 3, Col 10, Line 3, Col 11, + ("This expression was expected to have type\n ''a ref' \nbut here has type\n 'bool' " + System.Environment.NewLine + "The '!' operator is used to dereference a ref cell. Consider using 'not expr' here.")) + + [] + let ``Guard Has Wrong Type``() = + FSharp """ +let x = 1 +match x with +| 1 when "s" -> true +| _ -> false + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 4, Col 10, Line 4, Col 13, "A pattern match guard must be of type 'bool', but this 'when' expression is of type 'string'.") + (Warning 20, Line 3, Col 1, Line 5, Col 13, "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")] + + [] + let ``Runtime Type Test In Pattern``() = + FSharp """ +open System.Collections.Generic + +let orig = Dictionary() + +let c = + match orig with + | :? IDictionary -> "yes" + | _ -> "no" + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 67, Line 8, Col 5, Line 8, Col 28, "This type test or downcast will always hold") + (Error 193, Line 8, Col 5, Line 8, Col 28, "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n")] + + [] + let ``Runtime Type Test In Pattern 2``() = + FSharp """ +open System.Collections.Generic + +let orig = Dictionary() + +let c = + match orig with + | :? IDictionary as y -> "yes" + y.ToString() + | _ -> "no" + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 67, Line 8, Col 5, Line 8, Col 28, "This type test or downcast will always hold") + (Error 193, Line 8, Col 5, Line 8, Col 28, "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n")] + + [] + let ``Override Errors``() = + FSharp """ +type Base() = + abstract member Member: int * string -> string + default x.Member (i, s) = s + +type Derived1() = + inherit Base() + override x.Member() = 5 + +type Derived2() = + inherit Base() + override x.Member (i : int) = "Hello" + +type Derived3() = + inherit Base() + override x.Member (s : string, i : int) = sprintf "Hello %s" s + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 856, Line 8, Col 16, Line 8, Col 22, "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:" + System.Environment.NewLine + " abstract Base.Member: int * string -> string") + (Error 856, Line 12, Col 16, Line 12, Col 22, "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:" + System.Environment.NewLine + " abstract Base.Member: int * string -> string") + (Error 1, Line 16, Col 24, Line 16, Col 34, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ")] diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs new file mode 100644 index 00000000000..d5674beff82 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitGenericAbstactType.fs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + + +module ``Unit generic abstract Type`` = + + [] + let ``Unit can not be used as return type of abstract method paramete on return type``() = + FSharp """ +type EDF<'S> = + abstract member Apply : int -> 'S +type SomeEDF () = + interface EDF with + member this.Apply d = + // [ERROR] The member 'Apply' does not have the correct type to override the corresponding abstract method. + () + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 17, Line 6, Col 21, Line 6, Col 26, + "The member 'Apply: int -> unit' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs new file mode 100644 index 00000000000..439b0bd7bdb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +#if NETCOREAPP +open Xunit +open FSharp.Test.Compiler + +module ``Unsupported Attributes`` = + + [] + let ``Warn successfully`` () = + """ +open System.Runtime.CompilerServices +let f (w, [] x : string) = () +let [] g () = () +type C() = + member _.F (w, [] x : string) = () + [] + member _.G() = () + """ + |> FSharp + |> typecheck + |> shouldFail + |> withResults [ + { Error = Warning 202 + Range = { StartLine = 3 + StartColumn = 13 + EndLine = 3 + EndColumn = 37 } + Message = + "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." } + { Error = Warning 202 + Range = { StartLine = 4 + StartColumn = 7 + EndLine = 4 + EndColumn = 24 } + Message = + "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." } + { Error = Warning 202 + Range = { StartLine = 6 + StartColumn = 22 + EndLine = 6 + EndColumn = 78 } + Message = + "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." } + { Error = Warning 202 + Range = { StartLine = 7 + StartColumn = 7 + EndLine = 7 + EndColumn = 56 } + Message = + "This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." } + ] +#endif \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs new file mode 100644 index 00000000000..e336d7b10aa --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UpcastDowncastTests.fs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Upcast and Downcast`` = + + [] + let ``Downcast Instead Of Upcast``() = + FSharp """ +open System.Collections.Generic + +let orig = Dictionary() :> IDictionary +let c = orig :> Dictionary + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 193, Line 5, Col 9, Line 5, Col 36, + "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n") + + [] + let ``Upcast Instead Of Downcast``() = + FSharp """ +open System.Collections.Generic + +let orig = Dictionary() +let c = orig :?> IDictionary + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 67, Line 5, Col 9, Line 5, Col 38, "This type test or downcast will always hold") + (Error 3198, Line 5, Col 9, Line 5, Col 38, "The conversion from Dictionary to IDictionary is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator.")] + + [] + let ``Upcast Function Instead Of Downcast``() = + FSharp """ +open System.Collections.Generic + +let orig = Dictionary() +let c : IDictionary = downcast orig + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 67, Line 5, Col 32, Line 5, Col 45, "This type test or downcast will always hold") + (Error 3198, Line 5, Col 32, Line 5, Col 45, "The conversion from Dictionary to IDictionary is a compile-time safe upcast, not a downcast. Consider using 'upcast' instead of 'downcast'.")] diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs new file mode 100644 index 00000000000..3e7768efb94 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs @@ -0,0 +1,227 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + + +module ``Warn Expression`` = + + [] + let ``Warn If Expression Result Unused``() = + FSharp """ +1 + 2 +printfn "%d" 3 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 2, Col 1, Line 2, Col 6, + "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + [] + let ``Warn If Possible Assignment``() = + FSharp """ +let x = 10 +let y = "hello" + +let changeX() = + x = 20 + y = "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 11, + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'.") + + [] + let ``Warn If Possible Assignment To Mutable``() = + FSharp """ +let mutable x = 10 +let y = "hello" + +let changeX() = + x = 20 + y = "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 11, + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'.") + + [] + let ``Warn If Possible dotnet Property Setter``() = + FSharp """ +open System + +let z = System.Timers.Timer() +let y = "hello" + +let changeProperty() = + z.Enabled = true + y = "test" + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 760, Line 4, Col 9, Line 4, Col 30, "It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value") + (Warning 20, Line 8, Col 5, Line 8, Col 21, "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'.")] + + [] + let ``Don't Warn If Property Without Setter``() = + FSharp """ +type MyClass(property1 : int) = + member val Property2 = "" with get + +let x = MyClass(1) +let y = "hello" + +let changeProperty() = + x.Property2 = "22" + y = "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 9, Col 5, Line 9, Col 23, + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'.") + + [] + let ``Warn If Implicitly Discarded``() = + FSharp """ +let x = 10 +let y = 20 + +let changeX() = + y * x = 20 + y = 30 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 15, + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'.") + + [] + let ``Warn If Discarded In List``() = + FSharp """ +let div _ _ = 1 +let subView _ _ = [1; 2] + +// elmish view +let view model dispatch = + [ + yield! subView model dispatch + div [] [] + ] + """ + |> withLangVersion46 + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 3221, Line 9, Col 8, Line 9, Col 17, + "This expression returns a value of type 'int' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'.") + + [] + let ``Warn If Discarded In List 2``() = + FSharp """ +// stupid things to make the sample compile +let div _ _ = 1 +let subView _ _ = [1; 2] +let y = 1 + +// elmish view +let view model dispatch = + [ + div [] [ + match y with + | 1 -> yield! subView model dispatch + | _ -> subView model dispatch + ] + ] + """ + |> withLangVersion46 + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 3222, Line 13, Col 19, Line 13, Col 41, + "This expression returns a value of type 'int list' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'.") + + [] + let ``Warn If Discarded In List 3``() = + FSharp """ +// stupid things to make the sample compile +let div _ _ = 1 +let subView _ _ = true +let y = 1 + +// elmish view +let view model dispatch = + [ + div [] [ + match y with + | 1 -> () + | _ -> subView model dispatch + ] + ] + """ + |> withLangVersion46 + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 13, Col 19, Line 13, Col 41, + "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + [] + let ``Warn Only On Last Expression``() = + FSharp """ +let mutable x = 0 +while x < 1 do + printfn "unneeded" + x <- x + 1 + true + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 9, + "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + [] + let ``Warn If Possible Property Setter``() = + FSharp """ +type MyClass(property1 : int) = + member val Property1 = property1 + member val Property2 = "" with get, set + +let x = MyClass(1) +let y = "hello" + +let changeProperty() = + x.Property2 = "20" + y = "test" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 10, Col 5, Line 10, Col 23, + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'.") + + + [] + let ``Dont warn external function as unused``() = + FSharp """ +open System +open System.Runtime.InteropServices + +module Test = + + [] + extern int32 ExtractIconEx(string szFileName, int nIconIndex,IntPtr[] phiconLarge, IntPtr[] phiconSmall,uint32 nIcons) + + [] + extern int DestroyIcon(IntPtr hIcon) + +[] +let main _argv = + let _ = Test.DestroyIcon IntPtr.Zero + + let _ = Test.ExtractIconEx("", 0, [| |], [| |], 0u) + + 0 + """ + |> typecheck + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs new file mode 100644 index 00000000000..774ac1fda65 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WrongSyntaxInForLoop.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.ErrorMessages + +open Xunit +open FSharp.Test.Compiler + + +module ``Wrong syntax in for loop`` = + + [] + let ``Equals instead of in``() = + FSharp """ +module X +for i = 0 .. 100 do + () + """ + |> parse + |> shouldFail + |> withSingleDiagnostic (Error 3215, Line 3, Col 7, Line 3, Col 8, + "Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead?") diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj new file mode 100644 index 00000000000..48044317cdf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -0,0 +1,107 @@ + + + + + net472;net5.0 + net5.0 + Library + true + false + false + $(OtherFlags) --warnon:1182 + xunit + $(NoWarn);FS0988 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs new file mode 100644 index 00000000000..a2a018a64bb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Interop + +open Xunit +open FSharp.Test.Compiler + +module ``Simple interop verification`` = + + [] + let ``Instantiate C# type from F#`` () = + + let CSLib = + CSharp """ +public class A { } + """ |> withName "CSLib" + + let FSLib = + FSharp """ +module AMaker +let makeA () : A = A() + """ |> withName "FSLib" |> withReferences [CSLib] + + let app = + FSharp """ +module ReferenceCSfromFS +let a = AMaker.makeA() + """ |> withReferences [CSLib; FSLib] + + app + |> compile + |> shouldSucceed + + + [] + let ``Instantiate F# type from C#`` () = + let FSLib = + FSharp """ +namespace Interop.FS +type Bicycle(manufacturer: string) = + member this.Manufactirer = manufacturer + """ |> withName "FSLib" + + let app = + CSharp """ +using Interop.FS; +public class BicycleShop { + public Bicycle[] cycles; +} + """ |> withReferences [FSLib] + + app + |> compile + |> shouldSucceed + + [] + let ``Instantiate F# type from C# fails without import`` () = + let FSLib = + FSharp """ +namespace Interop.FS +type Bicycle(manufacturer: string) = + member this.Manufactirer = manufacturer + """ |> withName "FSLib" + + let app = + CSharp """ +public class BicycleShop { + public Bicycle[] cycles; +} + """ |> withReferences [FSLib] + + app + |> compile + |> shouldFail + + [] + let ``can't mutably set a C#-const field in F#`` () = + let csLib = + CSharp """ +public static class Holder { + public const string Label = "label"; +} + """ + |> withName "CsharpConst" + + let fsLib = + FSharp """ +module CannotSetCSharpConst +Holder.Label <- "nope" + """ + |> withReferences [csLib] + + fsLib + |> compile + |> shouldFail + + [] + let ``can't mutably set a C#-readonly field in F#`` () = + let csLib = + CSharp """ +public static class Holder { + public static readonly string Label = "label"; +} + """ + |> withName "CsharpReadonly" + + let fsLib = + FSharp """ +module CannotSetCSharpReadonly +Holder.Label <- "nope" + """ + |> withReferences [csLib] + + fsLib + |> compile + |> shouldFail diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/VisibilityTests.fs b/tests/FSharp.Compiler.ComponentTests/Interop/VisibilityTests.fs new file mode 100644 index 00000000000..ab6425d2052 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Interop/VisibilityTests.fs @@ -0,0 +1,195 @@ +namespace FSharp.Compiler.ComponentTests.Interop + +open Xunit +open FSharp.Test.Compiler + +module ``Verify visibility of properties`` = + + let csharpBaseClass = """ +namespace ExhaustiveCombinations +{ + public class CSharpBaseClass + { + public string GetPublicSetInternal { get; internal set; } + public string GetPublicSetProtected { get; protected set; } + public string GetPublicSetPrivateProtected { get; private protected set; } + public string GetPublicSetProtectedInternal { get; protected internal set; } + public string GetPublicSetPrivate { get; private set; } + + public string SetPublicGetInternal { internal get; set; } + public string SetPublicGetProtected { protected get; set; } + public string SetPublicGetPrivateProtected { private protected get; set; } + public string SetPublicGetProtectedInternal { protected internal get; set; } + public string SetPublicGetPrivate { private get; set; } + } +}""" + + let fsharpBaseClass = """ +namespace ExhaustiveCombinations + +open System + +type FSharpBaseClass () = + member this.GetPublicSetInternal with public get() = "" and internal set (parameter:string) = ignore parameter + member this.GetPublicSetPrivate with public get() = "" and private set (parameter:string) = ignore parameter + member this.SetPublicGetInternal with internal get() = "" and public set (parameter:string) = ignore parameter + member this.SetPublicGetPrivate with private get() = "" and public set (parameter:string) = ignore parameter""" + + [] + let ``C# class F# derived class - access public`` () = + + let csharpLib = CSharp csharpBaseClass |> withName "csLib" + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + inherit CSharpBaseClass() + + member this.AccessPublicStuff() = + + this.GetPublicSetInternal <- "1" // Inaccessible + let _ = this.GetPublicSetInternal // Accessible + + this.GetPublicSetPrivateProtected <- "1" // Accessible + let _ = this.GetPublicSetPrivateProtected // Accessible + + this.GetPublicSetProtectedInternal <- "1" // Accessible + let _ = this.GetPublicSetProtectedInternal // Accessible + + this.GetPublicSetProtected <- "1" // Accessible + let _ = this.GetPublicSetProtected // Accessible + + this.GetPublicSetPrivate <- "1" // Inaccessible + let _ = this.GetPublicSetPrivate // Accessible + () +""" + Fsx fsharpSource + |> withLangVersion50 + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 491, Line 19, Col 9, Line 19, Col 41, + "The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 22, Col 9, Line 22, Col 49, + "The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 31, Col 9, Line 31, Col 40, + "The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")] + + [] + let ``C# class F# non-derived class - access public`` () = + + let csharpLib = CSharp csharpBaseClass |> withName "csLib" + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + + member _.AccessPublicStuff() = + let bc = new CSharpBaseClass() + + bc.GetPublicSetInternal <- "1" // Inaccessible + let _ = bc.GetPublicSetInternal // Accessible + + bc.GetPublicSetPrivateProtected <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivateProtected // Accessible + + bc.GetPublicSetProtectedInternal <- "1" // Accessible + let _ = bc.GetPublicSetProtectedInternal // Inaccessible + + bc.GetPublicSetProtected <- "1" // Inaccessible + let _ = bc.SetPublicGetProtected // Accessible + + bc.GetPublicSetPrivate <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivate // Accessible + () +""" + + Fsx fsharpSource + |> withLangVersion50 + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 491, Line 19, Col 9, Line 19, Col 39, + "The member or object constructor 'GetPublicSetInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 22, Col 9, Line 22, Col 47, + "The member or object constructor 'GetPublicSetPrivateProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 25, Col 9, Line 25, Col 48, + "The member or object constructor 'GetPublicSetProtectedInternal' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 28, Col 9, Line 28, Col 40, + "The member or object constructor 'GetPublicSetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (Error 491, Line 29, Col 17, Line 29, Col 41, + "The member or object constructor 'SetPublicGetProtected' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions."); + (Error 491, Line 31, Col 9, Line 31, Col 38, + "The member or object constructor 'GetPublicSetPrivate' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.")] + + [] + let ``F# base F# derived class - access public`` () = + + let csharpLib = CSharp csharpBaseClass |> withName "csLib" + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + inherit FSharpBaseClass() + member this.AccessPublicStuff() = + + this.GetPublicSetInternal <- "1" // Inaccessible + let _ = this.GetPublicSetInternal // Accessible + + this.GetPublicSetPrivate <- "1" // Inaccessible + let _ = this.GetPublicSetPrivate // Accessible + + this.SetPublicGetInternal <- "1" // Accessible + let _ = this.SetPublicGetInternal // Inaccessible + + this.SetPublicGetPrivate <- "1" // Accessible + let _ = this.SetPublicGetPrivate // accessible + + ()""" + Fsx fsharpSource + |> withLangVersion50 + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 810, Line 21, Col 9, Line 21, Col 33, "Property 'GetPublicSetPrivate' cannot be set") + (Error 807, Line 28, Col 17, Line 28, Col 41, "Property 'SetPublicGetPrivate' is not readable")] + + [] + let ``F# class F# non-derived class - access public`` () = + + let csharpLib = CSharp csharpBaseClass |> withName "csLib" + + let fsharpSource = + fsharpBaseClass + """ +open System +open ExhaustiveCombinations + +type MyFSharpClass () = + member _.AccessPublicStuff() = + let bc = new FSharpBaseClass() + + bc.GetPublicSetInternal <- "1" // Inaccessible + let _ = bc.GetPublicSetInternal // Accessible + + bc.GetPublicSetPrivate <- "1" // Inaccessible + let _ = bc.GetPublicSetPrivate // Accessible + ()""" + + Fsx fsharpSource + |> withLangVersion50 + |> withReferences [csharpLib] + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 810, Line 21, Col 9, Line 21, Col 31, "Property 'GetPublicSetPrivate' cannot be set") diff --git a/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs new file mode 100644 index 00000000000..7b94f335e58 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/AttributeCheckingTests.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.AttributeChecking + +open Xunit +open FSharp.Test.Compiler + +module AttributeCheckingTests = + + [] + let ``attributes check inherited AllowMultiple`` () = + Fsx """ +open System + +[] +type HttpMethodAttribute() = inherit Attribute() +type HttpGetAttribute() = inherit HttpMethodAttribute() + +[] // this shouldn't error like +[] // this doesn't +type C() = + member _.M() = () + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``AllowMultiple=false allows adding attribute to both property and getter/setter`` () = + Fsx """ +open System + +[] +type FooAttribute() = inherit Attribute() + +type C() = + [] + member _.Foo + with [] get () = "bar" + and [] set (v: string) = () + """ + |> ignoreWarnings + |> compile + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CastingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CastingTests.fs new file mode 100644 index 00000000000..c85c571d0fe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/CastingTests.fs @@ -0,0 +1,113 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests + +open Xunit +open FSharp.Test.Compiler + +module CastingTests = + + [] + let ``Compile: ValueTuple.Create(1,1) :> IComparable>`` () = + FSharp """ +module One +open System + +let y = ValueTuple.Create(1,1) :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Compile: struct (1,2) :> IComparable>`` () = + FSharp """ +module One +open System + +let y = struct (1,2) :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Compile: let x = struct (1,3); x :> IComparable>`` () = + FSharp """ +module One +open System + +let y = struct (1,3) :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Script: ValueTuple.Create(0,0) :> IComparable>`` () = + Fsx """ +module One +open System + +let y = ValueTuple.Create(1,1) :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Script: struct (1,2) :> IComparable>`` () = + Fsx """ +module One +open System + +let y = struct (0,0) :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Script: let x = struct (1,3); x :> IComparable>`` () = + Fsx """ +module One +open System + +let x = struct (1,3) +let y = x :> IComparable> +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Compile: (box (System.ValueTuple.Create(1,2)) :?> System.IComparable>)`` () = + FSharp """ +module One +open System + +let y = (box (System.ValueTuple.Create(1,2)) :?> System.IComparable>) +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed + + [] + let ``Script: (box (System.ValueTuple.Create(1,2)) :?> System.IComparable>)`` () = + FSharp """ +module One +open System + +let y = (box (System.ValueTuple.Create(1,2)) :?> System.IComparable>) +printfn "%A" y + """ + |> ignoreWarnings + |> compile + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs new file mode 100644 index 00000000000..45ab0678529 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler +open FSharp.Quotations.Patterns + +module CodeQuotationsTests = + + [] + let ``Quotation on op_UnaryPlus(~+) compiles and runs`` () = + Fsx """ +open FSharp.Linq.RuntimeHelpers +open FSharp.Quotations.Patterns +open FSharp.Quotations.DerivedPatterns + +let eval q = LeafExpressionConverter.EvaluateQuotation q + +let inline f x = <@ (~+) x @> +let x = <@ f 1 @> +let y : unit = + match f 1 with + | Call(_, methInfo, _) when methInfo.Name = "op_UnaryPlus" -> + () + | e -> + failwithf "did not expect expression for 'y': %A" e +let z : unit = + match f 5 with + | (CallWithWitnesses(_, methInfo, methInfoW, _, _) as e) when methInfo.Name = "op_UnaryPlus" && methInfoW.Name = "op_UnaryPlus$W" -> + if ((eval e) :?> int) = 5 then + () + else + failwith "did not expect evaluation false" + | e -> + failwithf "did not expect expression for 'z': %A" e + """ + |> asExe + |> withLangVersion50 + |> compileAndRun + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs new file mode 100644 index 00000000000..362e6f06c6c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/CompilerDirectiveTests.fs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler + +module ``Test Compiler Directives`` = + + [] + let ``r# "" is invalid`` () = + Fsx""" +#r "" + """ |> ignoreWarnings + |> compile + |> shouldSucceed + |> withSingleDiagnostic (Warning 213, Line 2, Col 1, Line 2, Col 6, "'' is not a valid assembly name") + + [] + let ``#r " " is invalid`` () = + Fsx""" +#r " " + """ |> compile + |> shouldFail + |> withSingleDiagnostic (Warning 213, Line 2, Col 1, Line 2, Col 10, "'' is not a valid assembly name") + +module ``Test compiler directives in FSI`` = + [] + let ``r# "" is invalid`` () = + Fsx""" +#r "" + """ |> ignoreWarnings + |> eval + |> shouldFail + |> withSingleDiagnostic (Error 2301, Line 2, Col 1, Line 2, Col 6, "'' is not a valid assembly name") \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs new file mode 100644 index 00000000000..52a4ccabe4c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler + +module ComputationExpressionTests = + [] + let ``A CE not using Zero does not require Zero``() = + FSharp """ +module ComputationExpressionTests +type ListBuilder () = + member _.Combine (a: List<'T>, b) = a @ b + member _.Yield x = List.singleton x + member _.Delay expr = expr () : List<'T> + +let lb = ListBuilder () + +let x = lb {1; 2;} + """ + |> compile + |> shouldSucceed + |> ignore + + [] + let ``A CE explicitly using Zero fails without a defined Zero``() = + FSharp """ +module ComputationExpressionTests +type ListBuilder () = + member _.Combine (a: List<'T>, b) = a @ b + member _.Yield x = List.singleton x + member _.Delay expr = expr () : List<'T> + +let lb = ListBuilder () + +let x = lb {1; 2;()} + """ + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 39, Line 10, Col 18, Line 10, Col 20, "The type 'ListBuilder' does not define the field, constructor or member 'Zero'.") + |> ignore + + [] + let ``A CE explicitly using Zero succeeds with a defined Zero``() = + FSharp """ +module ComputationExpressionTests +type ListBuilder () = + member _.Zero () = [] + member _.Combine (a: List<'T>, b) = a @ b + member _.Yield x = List.singleton x + member _.Delay expr = expr () : List<'T> + +let lb = ListBuilder () + +let x = lb {1; 2;()} + """ + |> compile + |> shouldSucceed + |> ignore + + [] + let ``A CE with a complete if-then expression does not require Zero``() = + FSharp """ +module ComputationExpressionTests +type ListBuilder () = + member _.Combine (a: List<'T>, b) = a @ b + member _.Yield x = List.singleton x + member _.Delay expr = expr () : List<'T> + +let lb = ListBuilder () + +let x = lb {1; 2; if true then 3 else 4;} + """ + |> compile + |> shouldSucceed + |> ignore + + [] + let ``A CE with a missing/empty else branch implicitly requires Zero``() = + FSharp """ +module ComputationExpressionTests +type ListBuilder () = + member _.Combine (a: List<'T>, b) = a @ b + member _.Yield x = List.singleton x + member _.Delay expr = expr () : List<'T> + +let lb = ListBuilder () + +let x = lb {1; 2; if true then 3;} + """ + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 708, Line 10, Col 19, Line 10, Col 31, "This control construct may only be used if the computation expression builder defines a 'Zero' method") + |> ignore \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/IndexerSetterParamArray.fs b/tests/FSharp.Compiler.ComponentTests/Language/IndexerSetterParamArray.fs new file mode 100644 index 00000000000..f7e85ebccce --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/IndexerSetterParamArray.fs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests + +open Xunit +open FSharp.Test.Compiler + +#if NETCOREAPP +// Test cases for https://github.com/dotnet/fsharp/issues/9369 +module IndexerSetterParamArray = + + [] + let ``Indexer setter can use ParamArray`` () = + FSharp """ +module One +open System + +type T() = + let mutable v = "" + member this.Item + with get ([] indices: int[]) = + $"{v}; get(%A{indices})" + + and set ([] indices: int[]) (value: string) = + v <- $"set(%A{indices}, {value})" + +let t = T() + +// Using an explicit array is allowed +t.[[| 2 |] ] <- "7" +let v2 = t.[[| 2 |]] +printfn $"v2 = {v2}" +if v2 <> "set([|2|], 7); get([|2|])" then failwith "not right value B" + + +t.[1] <- "7" +let v3 = t.[1] +printfn $"v3 = {v3}" +if v3 <> "set([|1|], 7); get([|1|])" then failwith "not right value C" + +t.[1, 0] <- "7" +let v4 = t.[1, 0] +printfn $"v4 = {v4}" +if v4 <> "set([|1; 0|], 7); get([|1; 0|])" then failwith "not right value D" + +// Inference defaults to the array in absense of other information +let f idxs = + t.[ idxs ] <- "7" + +f ([| 2 |] ) +let v5 = t.[ [| 2 |] ] +printfn $"v5 = {v5}" +if v5 <> "set([|2|], 7); get([|2|])" then failwith "not right value" + + """ + |> ignoreWarnings + |> compileExeAndRun + |> shouldSucceed + + + // In this case the indexers take one initial arg then a ParamArray + [] + let ``Indexer setter can use ParamArray with one initial arg`` () = + FSharp """ +module One +open System + +type T() = + let mutable v = "" + member this.Item + with get (idx1: int) = + $"{v}; get({idx1})" + and set (idx1: int) (value: string) = + v <- $"set({idx1}, {value})" + + member this.Item + with get (idx1: int, [] indices: int[]) = + $"{v}; get({idx1}, %A{indices})" + + and set (idx1: int, [] indices: int[]) (value: string) = + v <- $"set({idx1}, %A{indices}, {value})" + +let t = T() + +t.[2] <- "7" +let v1 = t.[2] +printfn $"v1 = {v1}" +if v1 <> "set(2, 7); get(2)" then failwith "not right value A" + + +// Using an explicit array is allowed +t.[1, [| 2 |] ] <- "7" +let v2 = t.[1, [| 2 |]] +printfn $"v2 = {v2}" +if v2 <> "set(1, [|2|], 7); get(1, [|2|])" then failwith "not right value B" + + +t.[2, 1] <- "7" +let v3 = t.[2, 1] +printfn $"v3 = {v3}" +if v3 <> "set(2, [|1|], 7); get(2, [|1|])" then failwith "not right value C" + +t.[2, 1, 0] <- "7" +let v4 = t.[2, 1, 0] +printfn $"v4 = {v4}" +if v4 <> "set(2, [|1; 0|], 7); get(2, [|1; 0|])" then failwith "not right value D" + +// Inference defaults to the array in absense of other information +let f idxs = + t.[ 1, idxs ] <- "7" + +f ([| 2 |] ) +let v5 = t.[ 1, [| 2 |] ] +printfn $"v5 = {v5}" +if v5 <> "set(1, [|2|], 7); get(1, [|2|])" then failwith "not right value" + """ + |> ignoreWarnings + |> compileExeAndRun + |> shouldSucceed + + [] + let ``Indexer setter via extension can use ParamArray`` () = + FSharp """ +module One +open System + +type T() = + member val v : string = "" with get, set + +[] +module M = + type T with + member this.Item + with get ([] indices: int[]) = + $"{this.v}; get(%A{indices})" + + and set ([] indices: int[]) (value: string) = + this.v <- $"set(%A{indices}, {value})" + +let t = T() + +// Using an explicit array is allowed +t.[[| 2 |] ] <- "7" +let v2 = t.[[| 2 |]] +printfn $"v2 = {v2}" +if v2 <> "set([|2|], 7); get([|2|])" then failwith "not right value B" + + +t.[1] <- "7" +let v3 = t.[1] +printfn $"v3 = {v3}" +if v3 <> "set([|1|], 7); get([|1|])" then failwith "not right value C" + +t.[1, 0] <- "7" +let v4 = t.[1, 0] +printfn $"v4 = {v4}" +if v4 <> "set([|1; 0|], 7); get([|1; 0|])" then failwith "not right value D" + +// Inference defaults to the array in absense of other information +let f idxs = + t.[ idxs ] <- "7" + +f ([| 2 |] ) +let v5 = t.[ [| 2 |] ] +printfn $"v5 = {v5}" +if v5 <> "set([|2|], 7); get([|2|])" then failwith "not right value" + + + """ + |> ignoreWarnings + |> compileExeAndRun + |> shouldSucceed + +#endif \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs new file mode 100644 index 00000000000..81e55158788 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler + +module RegressionTests = + + [] + let ``No internal errors should be raised``() = + FSharp """ +namespace FSharpBug + +type TestItemSeq = + static member Test1 item = item + static member Test2 item = match item with Typo2 x -> x + """ + |> compile + |> withErrorCodes [39] + |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/Language/XmlComments.fs b/tests/FSharp.Compiler.ComponentTests/Language/XmlComments.fs new file mode 100644 index 00000000000..fc554d1fcc9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/XmlComments.fs @@ -0,0 +1,209 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.XmlComments + +open Xunit +open FSharp.Test.Compiler + +module XmlCommentChecking = + + [] + let ``invalid XML is reported`` () = + Fsx""" +/// +let x = 1 + +/// +/// Yo +/// Yo +module M = + /// < + let y = 1 + + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics + [ (Warning 3390, Line 2, Col 1, Line 2, Col 14, + "This XML comment is invalid: 'The 'summary' start tag on line 2 position 3 does not match the end tag of 'doc'. Line 3, position 3.'"); + (Warning 3390, Line 5, Col 1, Line 7, Col 21, + """This XML comment is invalid: 'The 'remark' start tag on line 3 position 3 does not match the end tag of 'rem'. Line 3, position 14.'"""); + (Warning 3390, Line 9, Col 5, Line 9, Col 20, + "This XML comment is invalid: 'Name cannot begin with the '\n' character, hexadecimal value 0x0A. Line 2, position 13.'") + ] + [] + let ``unknown parameter is reported`` () = + Fsx""" + /// Return + /// the parameter + let f a = a + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics + [ (Warning 3390, Line 2, Col 5, Line 3, Col 48, + "This XML comment is invalid: unknown parameter 'b'"); + ] + + [] + let ``invalid parameter name is reported`` () = + Fsx""" + /// Return + /// the parameter + let f a = a + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics + [ (Warning 3390, Line 2, Col 5, Line 3, Col 48, + "This XML comment is invalid: unknown parameter 'b'"); + (Warning 3390, Line 2, Col 5, Line 3, Col 48, + "This XML comment is incomplete: no documentation for parameter 'a'"); + ] + + [] + let ``duplicate parameter docs are reported`` () = + Fsx""" + /// Return + /// the parameter + /// the parameter + let f a = a + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics + [ (Warning 3390, Line 2, Col 5, Line 4, Col 48, + "This XML comment is invalid: multiple documentation entries for parameter 'a'"); + ] + + [] + let ``missing parameter name is reported`` () = + Fsx""" + /// Return + /// the parameter + let f a = a + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics + [ (Warning 3390, Line 2, Col 5, Line 3, Col 39, + "This XML comment is invalid: missing 'name' attribute for parameter or parameter reference"); + ] + + [] + let ``valid parameter names are not reported`` () = + Fsx""" + /// Return + /// the parameter + let f a = a + + /// The type + type C(x1: string, x2: string) = + let _unused = (x1, x2) + /// The instance method + /// the parameter + /// the other parameter + member x.M(p1: string, p2: string) = (p1, p2) + + /// The instance method + /// the other parameter + member x.OtherM((a,b): (string * string), p2: string) = ((a,b), p2) + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] + + [] + let ``valid parameter names are not reported for documented implicit constructor`` () = + Fsx""" + /// The type with an implicit constructor + type C + /// The constructor + /// the parameter + /// the other parameter + (x1: string, x2: string) = + let _unused = (x1, x2) + + member x.M(p1: string, p2: string) = (p1, p2) + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] + + [] + let ``valid parameter names are not reported for documented implicit constructor with visibility`` () = + Fsx""" + /// The type with an implicit constructor with visibility + type C + /// The constructor + /// the parameter + /// the other parameter + public (x1: string, x2: string) = + let _unused = (x1, x2) + + member x.M(p1: string, p2: string) = (p1, p2) + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] + + [] + let ``valid parameter names are reported for documented implicit constructor`` () = + Fsx""" + /// The type with an implicit constructor with visibility + /// the first parameter + /// the second parameter + type C (x1: string, x2: string) = + let _unused = (x1, x2) + + member x.M(p1: string, p2: string) = (p1, p2) + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] + + [] + let ``delegates can have param docs`` () = + Fsx""" + /// The type with an implicit constructor with visibility + /// The sender + /// The args + type C = delegate of sender: obj * args: int -> C + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] + + [] + let ``function parameters use names from as patterns`` () = + Fsx""" + type Thing = Inner of s: string + /// A function with an extracted inner value + /// The innver value to unwrap + let doer ((Inner s) as inner) = ignore s; ignore inner + """ + |> withXmlCommentChecking + |> ignoreWarnings + |> compile + |> shouldSucceed + |> withDiagnostics [ ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/OCamlCompat/OCamlCompat.fs b/tests/FSharp.Compiler.ComponentTests/OCamlCompat/OCamlCompat.fs new file mode 100644 index 00000000000..86c45c9556e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/OCamlCompat/OCamlCompat.fs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.OCamlCompat + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module OCamlCompat = + + // This test was automatically generated (moved from FSharpQA suite - OCamlCompat) + [] + let ``OCamlCompat - IndentOff02.fs - --warnaserror --mlcompatibility`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror"; "--mlcompatibility"] + |> typecheck + |> shouldSucceed + |> ignore + + // This test was automatically generated (moved from FSharpQA suite - OCamlCompat) + //This construct is for ML compatibility\. Consider using a file with extension '\.ml' or '\.mli' instead\. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'\.$ + [] + let ``OCamlCompat - W_IndentOff03.fs - --test:ErrorRanges`` compilation = + compilation + |> asFsx + |> withOptions ["--test:ErrorRanges"] + |> compile + |> shouldFail + |> withWarningCode 0062 + |> withDiagnosticMessageMatches "This construct is for ML compatibility\. Consider using a file with extension '\.ml' or '\.mli' instead\. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'\.$" + |> ignore + diff --git a/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs b/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs new file mode 100644 index 00000000000..efdd5918cb4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Scripting/Interactive.fs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Scripting + +open Xunit +open FSharp.Test.Compiler + +module ``Interactive tests`` = + [] + let ``Eval object value``() = + Fsx "1+1" + |> eval + |> shouldSucceed + |> withEvalTypeEquals typeof + |> withEvalValueEquals 2 + + +module ``External FSI tests`` = + [] + let ``Eval object value``() = + Fsx "1+1" + |> runFsi + |> shouldSucceed + + [] + let ``Invalid expression should fail``() = + Fsx "1+a" + |> runFsi + |> shouldFail \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs new file mode 100644 index 00000000000..636c9d31ddd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.CheckDeclarationsTests + +open Xunit +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module CheckDeclarationsTests = + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Tuple`` () = + FSharp """ +namespace FSharpTest + + [] + type Tree = + | Empty + | Children of Tree * Tree +""" + |> compile + |> shouldFail + |> withErrorCode 954 + |> ignore + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Struct Tuple`` () = + FSharp """ +namespace FSharpTest + + [] + type Tree = + | Empty + | Children of struct (Tree * Tree) +""" + |> compile + |> shouldFail + |> withErrorCode 954 + |> ignore + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Struct Tuple of int, Tree`` () = + FSharp """ +namespace FSharpTest + + [] + type Tree = + | Empty + | Children of struct (int * Tree) +""" + |> compile + |> shouldFail + |> withErrorCode 954 + |> ignore + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Tree`` () = + FSharp """ +namespace FSharpTest + + [] + type Tree = + | Empty + | Children of Tree +""" + |> compile + |> shouldFail + |> withErrorCode 954 + |> ignore + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Non-cyclic Struct Tuple`` () = + FSharp """ +namespace FSharpTest + + [] + type NotATree = + | Empty + | Children of struct (int * string) +""" + |> compile + |> shouldSucceed + |> ignore + + [] + let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Non-Struct DU Tree Cyclic Tree`` () = + FSharp """ +namespace FSharpTest + + type Tree = + | Empty + | Children of Tree +""" + |> compile + |> shouldSucceed + |> ignore diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/noframework/noframework02.fs similarity index 100% rename from tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework02.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/noframework/noframework02.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_01.fs new file mode 100644 index 00000000000..a0165cd572a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_01.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--PLATFORM' +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_02.fs new file mode 100644 index 00000000000..c0e1e8abdf4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_02.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--PlatForm' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_03.fs new file mode 100644 index 00000000000..203dab06451 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_03.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'ITANIUM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_04.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_04.fs new file mode 100644 index 00000000000..2f433848fc4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_04.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'ANYCPU', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_05.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_05.fs new file mode 100644 index 00000000000..5b3fc2ac0ce --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_05.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'X86', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_06.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_06.fs new file mode 100644 index 00000000000..5a4683cb78a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_06.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'X64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_07.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_07.fs new file mode 100644 index 00000000000..995f326bdc2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_07.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'IA64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_08.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_08.fs new file mode 100644 index 00000000000..1e3a5c3348b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_08.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'i386', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_09.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_09.fs new file mode 100644 index 00000000000..2c0bd250e8c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_09.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'AMD64', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_10.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_10.fs new file mode 100644 index 00000000000..d52ef7fe3bb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_10.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'PPC', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_11.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_11.fs new file mode 100644 index 00000000000..d5eeb8029a8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_11.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--platform-' + +exit 1 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_12.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_12.fs new file mode 100644 index 00000000000..5289830ee63 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_12.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--PLATFORM\+' + +exit 1 diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/platform/error_13.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_13.fs similarity index 100% rename from tests/fsharpqa/Source/CompilerOptions/fsc/platform/error_13.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_13.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_15.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_15.fs new file mode 100644 index 00000000000..250df9000f6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_15.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized platform 'ARM', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' + +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_16.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_16.fs new file mode 100644 index 00000000000..0d21e217709 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/platform/error_16.fs @@ -0,0 +1,5 @@ +// #Regression #NoMT #CompilerOptions +//The 'anycpu32bitpreferred' platform can only be used with EXE targets\. You must use 'anycpu' instead\. +module M +exit 1 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_01.fs new file mode 100644 index 00000000000..3df58150e86 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_01.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--Times' +#light +exit 0 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_02.fs new file mode 100644 index 00000000000..7232ba1d293 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_02.fs @@ -0,0 +1,4 @@ +// #Regression #NoMT #CompilerOptions +//Unrecognized option: '--times-' +#light +exit 0 diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/times/error_03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_03.fs similarity index 100% rename from tests/fsharpqa/Source/CompilerOptions/fsc/times/error_03.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/error_03.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/times01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/times01.fs new file mode 100644 index 00000000000..b01b7a501da --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/times/times01.fs @@ -0,0 +1,51 @@ +// #NoMT #CompilerOptions +#light + +namespace N + module M = + let f x = () + f 10 + +namespace N2 + module M2 = + let f2 x = () + f2 10 + + module M3 = + exit 0 + +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Import mscorlib and FSharp.Core.dll\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Parse inputs\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Import non-system references\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Typecheck\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Typechecked\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Write XML docs\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Write HTML docs\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Encode Interface Data\] +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[TAST -> IL\] +//ilwrite: TIME.+Write Started +//ilwrite: TIME.+Module Generation Preparation +//ilwrite: TIME.+Module Generation Pass 1 +//ilwrite: TIME.+Module Generation Pass 2 +//ilwrite: TIME.+Module Generation Pass 3 +//ilwrite: TIME.+Module Generation Pass 4 +//ilwrite: TIME.+Finalize Module Generation Results +//ilwrite: TIME.+Generated Tables and Code +//ilwrite: TIME.+Layout Header of Tables +//ilwrite: TIME.+Build String/Blob Address Tables +//ilwrite: TIME.+Sort Tables +//ilwrite: TIME.+Write Header of tablebuf +//ilwrite: TIME.+Write Tables to tablebuf +//ilwrite: TIME.+Layout Metadata +//ilwrite: TIME.+Write Metadata Header +//ilwrite: TIME.+Write Metadata Tables +//ilwrite: TIME.+Write Metadata Strings +//ilwrite: TIME.+Write Metadata User Strings +//ilwrite: TIME.+Write Blob Stream +//ilwrite: TIME.+Fixup Metadata +//ilwrite: TIME.+Generated IL and metadata +//ilwrite: TIME.+Layout image +//ilwrite: TIME.+Writing Image +//ilwrite: TIME.+Finalize PDB +//ilwrite: TIME.+Signing Image +//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Write .NET Binary\] diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror01.fs new file mode 100644 index 00000000000..5dc5695eaa3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror01.fs @@ -0,0 +1,6 @@ +// #Regression #NoMT #CompilerOptions +// Regression test for FSHARP1.0:4867 +// nowarn has no effect if "Warning level = 4" and "Warnings as errors" +//This and other recursive references to the object\(s\) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference\. This is because you are defining one or more recursive objects, rather than recursive functions\. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'\.$ + +let rec f = new System.EventHandler(fun _ _ -> f.Invoke(null,null)) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror02.fs new file mode 100644 index 00000000000..0c562f06251 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror02.fs @@ -0,0 +1,7 @@ +// #Regression #NoMT #CompilerOptions +// Regression test for FSHARP1.0:4867 +// nowarn has no effect if "Warning level = 4" and "Warnings as errors" +//This and other recursive references to the object\(s\) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference\. This is because you are defining one or more recursive objects, rather than recursive functions\. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40' +#nowarn "21" + +let rec f = new System.EventHandler(fun _ _ -> f.Invoke(null,null)) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs new file mode 100644 index 00000000000..475d86a7456 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs @@ -0,0 +1,9 @@ +// #Regression #NoMT #CompilerOptions +// Regression test for FSHARP1.0:4867 +// nowarn has no effect if "Warning level = 4" and "Warnings as errors" +//FS0040 +//FS0021 + +#nowarn "21" +#nowarn "40" +let rec f = new System.EventHandler(fun _ _ -> f.Invoke(null,null)) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn0_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn0_level5.fs new file mode 100644 index 00000000000..8d8e176f6d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn0_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// +// + +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn1_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn1_level5.fs new file mode 100644 index 00000000000..8d8e176f6d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn1_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// +// + +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn2_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn2_level5.fs new file mode 100644 index 00000000000..8d8e176f6d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn2_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// +// + +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn3_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn3_level5.fs new file mode 100644 index 00000000000..8d8e176f6d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn3_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// +// + +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn4_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn4_level5.fs new file mode 100644 index 00000000000..8d8e176f6d0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn4_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// +// + +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn5_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn5_level5.fs new file mode 100644 index 00000000000..cfbb9722f2d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn5_level5.fs @@ -0,0 +1,11 @@ +// #Regression #NoMT #CompilerOptions +// See DevDiv:364238 +//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$ +//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$ +open System.Collections.Generic + +let x : IEnumerator> = failwith "" +printfn "%A" x.Current.Key // defensive copy + +let y : list> = failwith "" +printfn "%A" y.[0].Key // defensive copy diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn5_level5w.fs similarity index 100% rename from tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn5_level5w.fs diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warnon/warnon01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warnon/warnon01.fs similarity index 100% rename from tests/fsharpqa/Source/CompilerOptions/fsc/warnon/warnon01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warnon/warnon01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_Equals.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_Equals.fs new file mode 100644 index 00000000000..5749edc7ef8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_Equals.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #TypesAndModules #Records #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of Equals() + +type R = + { x: int } + member this.Equals(s:char) = true + // member this.Equals(s:R) = 1. + member this.Equals(?s:char) = true + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_GetHashCode.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_GetHashCode.fs new file mode 100644 index 00000000000..25aa07cd456 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_GetHashCode.fs @@ -0,0 +1,12 @@ +// #Regression #Conformance #TypesAndModules #Records #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of GetHashCode() +type R = + { x: int } + member this.GetHashCode(s:char) = 1 + //member this.GetHashCode() = 1. + member this.GetHashCode(?s:char) = 1 + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_ToString.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_ToString.fs new file mode 100644 index 00000000000..2e651f776dd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/Overload_ToString.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #TypesAndModules #Records #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of ToString() + +type R = + { x: int } + member this.ToString(s:char) = true + member this.ToString() = true + member this.ToString(?s:char) = true + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/UnitType01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/UnitType01.fsx similarity index 100% rename from tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/UnitType01.fsx rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/UnitType01.fsx diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_Equals.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_Equals.fs new file mode 100644 index 00000000000..0e289605e5a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_Equals.fs @@ -0,0 +1,12 @@ +// #Regression #Conformance #TypesAndModules #Unions #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of Equals() + +type DU = | A + member this.Equals(s:char) = true + //member this.Equals(s:DU) = 1. + member this.Equals(?s:char) = true + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_GetHashCode.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_GetHashCode.fs new file mode 100644 index 00000000000..f85e1c1dbd1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_GetHashCode.fs @@ -0,0 +1,12 @@ +// #Regression #Conformance #TypesAndModules #Unions #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of GetHashCode() + +type DU = | A + member this.GetHashCode(s:char) = 1 + //member this.GetHashCode() = 1. + member this.GetHashCode(?s:char) = 1 + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_ToString.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_ToString.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_ToString.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/Overload_ToString.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_measure_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_measure_01.fs new file mode 100644 index 00000000000..ab442fc8a9b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_measure_01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:2320 +// A is a measure +//Expected type, not unit-of-measure +#light +[] +type A + +let _ = typeof diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_undefined_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_undefined_01.fs new file mode 100644 index 00000000000..61684c8730e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/E_typeof_undefined_01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:2320 +// A is an not defined +//This type requires a definition +#light + +type A + +let _ = typeof diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeofInCustomAttributes001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeofInCustomAttributes001.fs new file mode 100644 index 00000000000..c315468d874 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeofInCustomAttributes001.fs @@ -0,0 +1,15 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:1490 +// can't use typeof in attributes +// + +[)>] +type TestTypeOnType() = + class + member x.P = 1 + end + +and TestTypeOnTypeView() = + class + member x.P = 1 + end diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_anonymous_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_anonymous_01.fs new file mode 100644 index 00000000000..e0b29ab5585 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_anonymous_01.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:2320 +// Type passed to typeof<> is _ +// +#light + +let _ = typeof<_> diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_class_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_class_01.fs new file mode 100644 index 00000000000..5f4f3bb13c0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_class_01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:2320 +// A is a class +#light + +type A = class + end + +let _ = typeof diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_interface_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_interface_01.fs new file mode 100644 index 00000000000..5a4feb88567 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_interface_01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #DeclarationElements #LetBindings #TypeTests +// Regression test for FSHARP1.0:2320 +// A is an interface +#light + +type A = interface + end + +let _ = typeof diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_struct_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_struct_01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_struct_01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/TypeFunctions/typeof_struct_01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/UseBindingDiscard01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/UseBindingDiscard01.fs new file mode 100644 index 00000000000..28a6d38806f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/DeclarationElements/LetBindings/UseBindingDiscard01.fs @@ -0,0 +1,6 @@ +// #DeclarationElements #LetBindings +// + +let answer = + use _ = new System.IO.MemoryStream() + 42 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType01.fs new file mode 100644 index 00000000000..3fe7bda3e32 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType01.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #ApplicationExpressions +// Regression test for FSHARP1.0:5525 +// Deprecate postfix type application in "new" and "inherit" constructs +//Unexpected identifier in expression$ + +type T<'t> = System.Collections.Generic.List<'t> +let o = new int T () diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType03.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType03.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/E_PostfixType03.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/PostfixType02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/PostfixType02.fs new file mode 100644 index 00000000000..e76e7348ce3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ApplicationExpressions/BasicApplication/PostfixType02.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #ApplicationExpressions +// Regression test for FSHARP1.0:5525 +// Deprecate postfix type application in "new" and "inherit" constructs +// + +type I<'i> = interface + end + +type CC<'t> () = class + interface int I // nothing wrong here + end diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in01.fs new file mode 100644 index 00000000000..7ff3e6a7bb0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in01.fs @@ -0,0 +1,12 @@ +// #in #BindingExpressions +// +// These are pretty pathological cases related to ";;" and "in" +// I'm adding these cases to make sure we do not accidentally change the behavior from version to version +// Eventually, we will deprecated them - and the specs will be updated. +// +//The value or constructor 'a' is not defined +//The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +module A = + let a = 3 in a + 1 |> ignore;; + a > 4;; + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in02.fs new file mode 100644 index 00000000000..088eba8f3f4 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in02.fs @@ -0,0 +1,13 @@ +// #in #BindingExpressions +// +// These are pretty pathological cases related to ";;" and "in" +// I'm adding these cases to make sure we do not accidentally change the behavior from version to version +// Eventually, we will deprecated them - and the specs will be updated. +// +//The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +// + +module B = + let a = 3 in a + 1 |> ignore + a > 4 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in03.fs new file mode 100644 index 00000000000..e1bc60f8100 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in03.fs @@ -0,0 +1,12 @@ +// #in #BindingExpressions +// +// These are pretty pathological cases related to ";;" and "in" +// I'm adding these cases to make sure we do not accidentally change the behavior from version to version +// Eventually, we will deprecated them - and the specs will be updated. +// +//The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +// +module C = + let a = 3 + a + 1 |> ignore + a > 4 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in04.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in04.fs new file mode 100644 index 00000000000..1f4ddad6348 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in04.fs @@ -0,0 +1,14 @@ +// #in #BindingExpressions +// +// These are pretty pathological cases related to ";;" and "in" +// I'm adding these cases to make sure we do not accidentally change the behavior from version to version +// Eventually, we will deprecated them - and the specs will be updated. +// +//The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +// + +module D = + let a = 3 in + a + 1 |> ignore + a > 4 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in05.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in05.fs new file mode 100644 index 00000000000..eaefd989c14 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/BindingExpressions/Binding/in05.fs @@ -0,0 +1,13 @@ +// #in #BindingExpressions +// +// These are pretty pathological cases related to ";;" and "in" +// I'm adding these cases to make sure we do not accidentally change the behavior from version to version +// Eventually, we will deprecated them - and the specs will be updated. +//The type 'int' does not match the type 'unit'$ +//Type mismatch\. Expecting a. ''a -> 'b' .but given a. ''a -> unit' .The type 'int' does not match the type 'unit'$ +//The result of this expression has type 'bool' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +module E = + let a = 3 in + a + 1 |> ignore + a + 1 |> ignore + a > 4 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample01.fs new file mode 100644 index 00000000000..85e14dd2b4e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample01.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #ControlFlow +// Regression test for FSHARP1.0:1986 (conter example in complex pattern matching) +//'Some \(\(_,true\)\)' + +#light + +let f = function + // Incomplete pattern matches on this expression. For example, the value 'Some ((_,true))' will not be matched + | Some (true,false) -> 1 + | Some (false, _) -> 2 + | None -> 3 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample02.fs new file mode 100644 index 00000000000..e377c113fa6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample02.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #ControlFlow +// Regression test for FSHARP1.0:1986 (conter example in complex pattern matching) +//Incomplete pattern matches on this expression\. For example, the value '\[_;true\]' may indicate a case not covered by the pattern\(s\) + +#light + +let g = function + | [] -> 0 + | [_] -> 1 + | [_; false] -> 3 + | e1::e2::e3::_ -> 2 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample03.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample03.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/PatternMatching/W_PatternMatchingCounterExample03.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/W_IncompleteMatchFor01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/W_IncompleteMatchFor01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/W_IncompleteMatchFor01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/W_IncompleteMatchFor01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02b.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02b.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02b.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/E_rigidtypeannotation02b.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/rigidtypeannotation01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/rigidtypeannotation01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/rigidtypeannotation01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/rigidtypeannotation01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01.fs new file mode 100644 index 00000000000..73c3f24fff2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01.fs @@ -0,0 +1,7 @@ +// #Conformance #TypeRelatedExpressions #TypeAnnotations +#light + +(1 :> obj) +("Hello" :> obj) +([1;2;3] :> seq).GetEnumerator() +(upcast 1 : obj) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01b.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01b.fs new file mode 100644 index 00000000000..ae2709d03ee --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/Expressions/Type-relatedExpressions/staticcoercion01b.fs @@ -0,0 +1,9 @@ +// #Conformance #TypeRelatedExpressions #TypeAnnotations +#light + +[] type s + +(1.0 :> obj) +("Hello" :> obj) +([1.0;2.0;3.0] :> seq<_>).GetEnumerator() +(upcast 1.0 : obj) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_RecursiveInline.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_RecursiveInline.fs new file mode 100644 index 00000000000..947bfc49e0a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_RecursiveInline.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #TypeInference #Recursion +// Regression test for FSharp1.0:3475 - ICE on rec inline function +//The value 'E_RecursiveInline.test' was marked inline but was not bound in the optimization environment +//The value 'test' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible$ +//A value marked as 'inline' has an unexpected value +//Failed to inline the value 'test' marked 'inline', perhaps because a recursive value was marked 'inline' +let rec inline test x = + if x then test false + else 0 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration01.fs new file mode 100644 index 00000000000..4572923e75e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration01.fs @@ -0,0 +1,16 @@ +// #Regression #Conformance #TypeInference #Recursion +// Regression test for FSharp1.0:3187 +// Title: better inference for mutually recursrive generic classes +// Descr: Verify types are inferred correctly for generic classes + +//This expression was expected to have type + +// In the negative case, this tests that eager generalization is based on a transitive (greatest-fixed-point) computation +module OO_Example_GreatestFixedPoint = + type C() = + member x.M1() = x.M2() |> fst + member x.M2() = failwith "", x.M3() + member x.Mbbb() = + (x.M1() : int) |> ignore + (x.M2() : string) |> ignore // M1 should not be generalized at this point + member x.M3() = 1 diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration02.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration02.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/E_TypeDeclaration02.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/InfiniteRecursiveExplicitConstructor.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/InfiniteRecursiveExplicitConstructor.fs new file mode 100644 index 00000000000..3e211b55ba7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/InfiniteRecursiveExplicitConstructor.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #TypeInference #Recursion +// Regression test for FSHARP1.0:3541 +// PEVerification failure with infinite recursion in explict constructor +// Note: as per Don's comment in 3541, we shoudl NOT disallow recursive call of own constructor +#light +open System + +type A() = + new (x : string) = new A(x) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/E_star02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/E_star02.fs new file mode 100644 index 00000000000..b8e58e34d4f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/E_star02.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:5444 +// (*) in comments +//Unexpected symbol '\*' in implementation file$ + +(* +let a2 = (*) +*)*) +let b2 = () diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/star01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/star01.fs new file mode 100644 index 00000000000..dac4bbddea8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/star01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:5444 +// (*) in comments +// + +(* +let a1 = ( * ) +*) +let b1 = () diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/star03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/star03.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/star03.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Comments/star03.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals001.fs new file mode 100644 index 00000000000..d87a07bb097 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals001.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumInt8s = | A1 = - 10y diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals002.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals002.fs new file mode 100644 index 00000000000..ac5cca4f23c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals002.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumInt16s = | A1 = - 10s diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals003.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals003.fs new file mode 100644 index 00000000000..0a811e240c0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals003.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumInt32s = | A1 = - 10 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals004.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals004.fs new file mode 100644 index 00000000000..0bdbde6f172 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals004.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumInt64s = | A1 = - 10L diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals005.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals005.fs new file mode 100644 index 00000000000..bc034b63565 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals005.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumNativeInts = | A1 = - 10n diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals006.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals006.fs new file mode 100644 index 00000000000..49b4b8ecbb8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals006.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumDoubles = | A1 = - 1.2 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals007.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals007.fs new file mode 100644 index 00000000000..bf0ceb30c52 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals007.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Unexpected symbol '-' in union case$ + + +type EnumSingles = | A1 = - 1.2f diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals008.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals008.fs new file mode 100644 index 00000000000..0f59aad7cad --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals008.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with space +//Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char + +#light +type EnumNativeInt = | A1 = -10n // enum on this type are not supported, -ve or +ve diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals009.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals009.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals009.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/E_enumNegativeLiterals009.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/enumNegativeLiterals001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/enumNegativeLiterals001.fs new file mode 100644 index 00000000000..5306a4073ad --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/NumericLiterals/enumNegativeLiterals001.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #LexicalAnalysis #Constants +// Regression test for FSHARP1.0:1284 +// Enum type definitions do not support negative literals +// Negative literal with no space +// See FSHARP1.0:3714 +#light + +type EnumInt8 = | A1 = -10y +type EnumInt16 = | A1 = -10s +type EnumInt32 = | A1 = -10 +type EnumInt64 = | A1 = -10L +// type EnumDouble = | A1 = -1.2 -- moved to a negative test since they are now illegal +// type EnumSingle = | A1 = -1.2f -- moved to a negative test since they are now illegal diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Shift/Generics/RightShift001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Shift/Generics/RightShift001.fs new file mode 100644 index 00000000000..251673d2e07 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Shift/Generics/RightShift001.fs @@ -0,0 +1,12 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSharp1.0#1076 +// Usage of >> and . +// No spaces between >> and . +// + +#light + +type ID<'T> = + static member id (x:'T) = x + +let f x = ID>.id (* ok *) diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/RightShift002.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Shift/Generics/RightShift002.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/RightShift002.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/Shift/Generics/RightShift002.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly01.fs new file mode 100644 index 00000000000..12a6671e882 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly01.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:1077 +// closing brace following generic type bracket is syntax error without whitespace (lexed into symbolic token). +// + +#light + +type a1 = { x:list } diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly02.fs new file mode 100644 index 00000000000..5af95e05e46 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly02.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:1077 +// closing brace following generic type bracket is syntax error without whitespace (lexed into symbolic token). +// + +#light + +type a2 = {x:list} diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly03.fs new file mode 100644 index 00000000000..ed3f5860e8a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly03.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:1077 +// closing brace following generic type bracket is syntax error without whitespace (lexed into symbolic token). +// + +#light + +type a3 = {x:list>} diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly04.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly04.fs new file mode 100644 index 00000000000..0065830c2a9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly04.fs @@ -0,0 +1,10 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:1077 +// closing brace following generic type bracket is syntax error without whitespace (lexed into symbolic token). +// + +#light + +[] type Kg +type Y = {mass_at_rest:float} +let y = {mass_at_rest=10.0} diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly05.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly05.fs new file mode 100644 index 00000000000..6aff7f10196 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedCurly05.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:1077 +// closing brace following generic type bracket is syntax error without whitespace (lexed into symbolic token). +// + +#light + +type A<'t> = interface + end + +let x = {new A} diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedParenthesis01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedParenthesis01.fs new file mode 100644 index 00000000000..7f23ee0d1e3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedParenthesis01.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:2464 +// closing square bracket following closing generic type angle bracket is syntax error without whitespace +// + +#light + +let id x = x + +let r6a = (id ) +let r6b = (id) diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare02.fs new file mode 100644 index 00000000000..76e31e183ca --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicKeywords/GreaterThanClosedSquare02.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #LexicalAnalysis +// Regression test for FSHARP1.0:2464 +// closing square bracket following closing generic type angle bracket is syntax error without whitespace +// + +#light + +let id x = x +let r6a = [id ] +let r6b = [id] + diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanColon002.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanColon002.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanColon002.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanColon002.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanDotParen01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanDotParen01.fs new file mode 100644 index 00000000000..8edab7d166f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_GreaterThanDotParen01.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #LexicalAnalysis #Operators +// Regression test for FSHARP1.0:4994 +// We could not define operator >. +//Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$ +//Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$ +//Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$ +//Invalid operator definition\. Prefix operator definitions must use a valid prefix operator name\.$ + +let ( ~>. ) x y = x + y +let ( ~<. ) x y = x + y + +let ( ~!>. ) x y = x + y +let ( ~!<. ) x y = x + y diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs new file mode 100644 index 00000000000..a8cf50ea24b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs @@ -0,0 +1,31 @@ +// #Regression #Conformance #LexicalAnalysis #Operators +// Regression test for FSHARP1.0:4805 +// We are not really after the actual error messages here (some of them have been omitted), rather we +// want to verify we do not crash! +//This construct causes code to be less generic than indicated by the type annotations\. The type variable 'S has been constrained to be type 'int' +//This code is not sufficiently generic\. The type variable \^T when \^T : \(static member \( \+ \) : \^T \* \^T -> \^a\) could not be generalized because it would escape its scope + +type public TestType<'T,'S>() = + + member public s.Value with get() = Unchecked.defaultof<'T> + static member public (+++) (a : TestType<'T,'S>, b : TestType<'T,'S>) = a.Value + static member public (+++) (a : TestType<'T,'S>, b : 'T) = b + static member public (+++) (a : 'T, b : TestType<'T,'S>) = a + static member public (+++) (a : TestType<'T,'S>, b : 'T -> 'S) = a.Value + static member public (+++) (a : 'S -> 'T, b : TestType<'T,'S>) = (a 17) + b.Value + +let inline (+++) (a : ^a) (b : ^b) = ((^a or ^b): (static member (+++): ^a * ^b -> ^c) (a,b) ) + +let tt0 = TestType() +let tt1 = TestType() + +let f (x : string) = 18 + +let a0 = tt0 +++ tt1 +let a1 = tt0 +++ 11 +let a2 = 12 +++ tt1 +let a3 = tt0 +++ (fun x -> "18") +let a4 = f +++ tt0 + +let a5 = TestType.(+++)(f, tt0) +let a6 = TestType.(+++)((fun (x : string) -> 18), tt0) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanColon001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanColon001.fs new file mode 100644 index 00000000000..e90463c36ca --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanColon001.fs @@ -0,0 +1,10 @@ +// #Regression #Conformance #LexicalAnalysis #Operators +// Regression test for FSHARP1.0:1392 +// Space should not be required between : and > +// + +#light + +type Ix = interface + abstract A<'t> : 't->'t // space between > and : + end diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanDotParen01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanDotParen01.fs new file mode 100644 index 00000000000..a069d6c8e3f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/GreaterThanDotParen01.fs @@ -0,0 +1,19 @@ +// #Regression #Conformance #LexicalAnalysis #Operators +// Regression test for FSHARP1.0:4994 +// We could not define operator >. + +let ( >. ) x y = x + y +let ( <. ) x y = x + y + +let ( !>. ) x y = x + y +let ( !<. ) x y = x + y + +let ( |>. ) x y = x + y +let ( |<. ) x y = x + y + +let ( >>. ) x y = x + y +let ( <<. ) x y = x + y + +let ( >.. ) x y = x + y +let ( |>.. ) x y = x + y + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/LessThanDotOpenParen001.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/LessThanDotOpenParen001.fs new file mode 100644 index 00000000000..eaba7fbdb62 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalAnalysis/SymbolicOperators/LessThanDotOpenParen001.fs @@ -0,0 +1,28 @@ +// #Regression #Conformance #LexicalAnalysis #Operators +// Regression test for FSHARP1.0:4805 +// + +type public TestType<'T,'S>() = + + member public s.Value with get() = Unchecked.defaultof<'T> + static member public (+++) (a : TestType<'T,'S>, b : TestType<'T,'S>) = a.Value + static member public (+++) (a : TestType<'T,'S>, b : 'T) = b + static member public (+++) (a : 'T, b : TestType<'T,'S>) = a + static member public (+++) (a : TestType<'T,'S>, b : 'T -> 'S) = a.Value + //static member public (+++) (a : 'S -> 'T, b : TestType<'T,'S>) = (a 17) + b.Value + +let inline (+++) (a : ^a) (b : ^b) = ((^a or ^b): (static member (+++): ^a * ^b -> ^c) (a,b) ) + +let tt0 = TestType() +let tt1 = TestType() + +let f (x : string) = 18 + +let a0 = tt0 +++ tt1 +let a1 = tt0 +++ 11 +let a2 = 12 +++ tt1 +let a3 = tt0 +++ (fun x -> "18") +//let a4 = f +++ tt0 + +//let a5 = TestType.(+++)(f, tt0) +//let a6 = TestType.(+++)((fun (x : string) -> 18), tt0) diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/InfixTokenPlusOne.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/InfixTokenPlusOne.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/InfixTokenPlusOne.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/InfixTokenPlusOne.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs new file mode 100644 index 00000000000..97f97e8331e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs @@ -0,0 +1,3904 @@ +// #Conformance #LexFilter #Exceptions +#light + +[] +type IProvideTestFunctionX = + static member x (y: obj, ?z: obj) = () + static member x'<'T> (y: 'T, ?z: obj) = y + +module BeginEnd = + let a = begin + 2 + end + let b = id begin + 2 + end + let c = + if true then ignore begin + 2 + end + let d = + if true then begin 1 end else begin + 2 + end + let e = + if true then begin + 1 + end else begin + 2 + end + let ( + _ + ) as f = begin + 2 + end + let ( + _ + ) = begin + 3 + end + let h = + if begin + true + end + then begin + end + let i = + if x' begin + false + end + then begin + end + let a0 = begin 2 = + 2 + end + let b0 = x begin y = + 2 + end + let c0 = + if true then x begin y = + 2 + end + let d0 = + if true then x begin y = 1 end else x begin y = + 2 + end + let e0 = + if true then x begin y = + 1 + end else x begin y = + 2 + end + let ( + _ + ) as f0 = x begin y = + 2 + end + let ( + _ + ) = begin 2 = + 3 + end + let h0 = + if begin 2 = + 2 + end + then begin + end + let i0 = + if x' begin y = + true + end + then begin + end + let a1 = begin 2 = 2, + 3 = 2 + end + let b1 = x begin y = 2, + z = 2 + end + let c1 = + if true then x begin y = 2, + z = 3 + end + let d1 = + if true then x begin y = 1 end else x begin y = 2, + z = 3 + end + let e1 = + if true then x begin y = 1, + z = 3 + end else x begin y = 2, + z = 3 + end + let ( + _ + ) as f1 = x begin y = 2, + z = 3 + end + let ( + _ + ) = begin 2 = 3, + 3 = 3 + end + let h1 = + if begin 2 = 2 |> ignore; + 3 = 3 + end + then begin + end + let i1 = + if x' begin y = true, + z = false + end + then begin + end +type Paren = ( + int +) +module Parens = + let a = ( + 2 + ) + let b = id ( + 2 + ) + let c = + if true then ignore ( + 2 + ) + let d = + if true then ( 1 ) else ( + 2 + ) + let e = + if true then ( + 1 + ) else ( + 2 + ) + let ( + _ + ) as f = ( + 2 + ) + let ( + _ + ) = ( + 3 + ) + let a0 = (2 = + 2 + ) + let b0 = x (y = + 2 + ) + let c0 = + if true then x (y = + 2 + ) + let d0 = + if true then x ( y = 1 ) else x (y = + 2 + ) + let e0 = + if true then x (y = + 1 + ) else x (y = + 2 + ) + let ( + _ + ) as f0 = x (y = + 2 + ) + let ( + _ + ) = (2 = + 3 + ) + let a1 = (2 = 2, + 3 = 3 + ) + let b1 = x (y = 2, + z = 3 + ) + let c1 = + if true then x (y = 2, + z = 3 + ) + let d1 = + if true then x ( y = 1 ) else x (y = 2, + z = 3 + ) + let e1 = + if true then x (y = 1, + z = 3 + ) else x (y = 2, + z = 3 + ) + let ( + _ + ) as f1 = x (y = 2, + z = 3 + ) + let ( + _ + ) = (2 = 3, + 3 = 3 + ) +// These are lexed differently but it's visually appealing to still include +module ActivePatterns = + let (| + A + |) = id + let (| + B + |) _ = (| + A + |) + let (|C|) = + if true then ignore (| + A + |) + let d<'a, 'b> = + if true then (| A |) else (| + A + |) + let e<'a, 'b> = + if true then (| + A + |) else (| + A + |) + let (| + F + | + _ + |) as f = Some (| + C + |) + let (| + G + | + _ + |) = (| + F + | + _ + |) +module Lists = + let a = [ + 2 + ] + let b = id [ + 2 + ] + let c = + if true then ignore [ + 2 + ] + let d = + if true then [ 1 ] else [ + 2 + ] + let e = + if true then [ + 1 + ] else [ + 2 + ] + let [ + _ + ] as f = [ + 2 + ] + let [ + _ + ] = [ + 3 + ] + let a0 = [ 2 = + 2 + ] + let b0 = x [ 2 = + 2 + ] + let c0 = + if true then x [ 2 = + 2 + ] + let d0 = + if true then x [ 2 = 1 ] else x [ 2 = + 2 + ] + let e0 = + if true then x [ 2 = + 1 + ] else x [ 2 = + 2 + ] + let [ + _ + ] as f0 = x' [ 2 = + 2 + ] + let [ + _ + ] = [ 2 = + 3 + ] + let a1 = [ 2 = 2, + 3 = 3 + ] + let b1 = x [ 2 = 2, + 3 = 3 + ] + let c1 = + if true then x [ 2 = 2, + 3 = 3 + ] + let d1 = + if true then x [ 2 = 1 ] else x [ 2 = 2, + 3 = 3 + ] + let e1 = + if true then x [ 2 = 1, + 3 = 3 + ] else x [ 2 = 2, + 3 = 3 + ] + let [ + _ + ] as f1 = x' [ 2 = 2, + 3 = 3 + ] + let [ + _ + ] = [ 2 = 3, + 3 = 3 + ] +module Arrays = + let a = [| + 2 + |] + let b = id [| + 2 + |] + let c = + if true then ignore [| + 2 + |] + let d = + if true then [| 1 |] else [| + 2 + |] + let e = + if true then [| + 1 + |] else [| + 2 + |] + let [| + _ + |] as f = [| + 2 + |] + let [| + _ + |] = [| + 3 + |] + let a0 = [| 2 = + 2 + |] + let b0 = x [| 2 = + 2 + |] + let c0 = + if true then x [| 2 = + 2 + |] + let d0 = + if true then x [| 2 = 1 |] else x [| 2 = + 2 + |] + let e0 = + if true then x [| 2 = + 1 + |] else x [| 2 = + 2 + |] + let [| + _ + |] as f0 = x' [| 2 = + 2 + |] + let [| + _ + |] = [| 2 = + 3 + |] + let a1 = [| 2 = 2, + 3 = 3 + |] + let b1 = x [| 2 = 2, + 3 = 3 + |] + let c1 = + if true then x [| 2 = 2, + 3 = 3 + |] + let d1 = + if true then x [| 2 = 1 |] else x [| 2 = 2, + 3 = 3 + |] + let e1 = + if true then x [| 2 = 1, + 3 = 3 + |] else x [| 2 = 2, + 3 = 3 + |] + let [| + _ + |] as f1 = x' [| 2 = 2, + 3 = 3 + |] + let [| + _ + |] = [| 2 = 3, + 3 = 3 + |] +type Record = { + y : int +} +type Record2 = { + x : int; z : Record +} +module Records = + let a = { + y = 2 + } + let b = id { + y = 2 + } + let c = + if true then ignore { + y = 2 + } + let d = + if true then { y = 1 } else { + y = 2 + } + let e = + if true then { + y = 1 + } else { + y = 2 + } + let { + y = _ + } as f = { + y = 2 + } + let { + y = _ + } = { + f with y = 3 + } + let a0 = { y = + 2 + } + let b0 = x { y = + 2 + } + let c0 = + if true then x { y = + 2 + } + let d0 = + if true then x { y = 1 } else x { y = + 2 + } + let e0 = + if true then { y = + 1 + } else { y = + 2 + } + let { z = { + y = _ + }} as f0 = { z = { + y = 2 + }; x = 1} + let { z = { + y = _ + }} = { f0 with z = { + y = 3 + } + } + let a1 = { x = 2; + z = { y = 3 } + } + let b1 = x { x = 2; + z = { y = 3 } + } + let c1 = + if true then x { x = 2; + z = { y = 3 } + } + let d1 = + if true then x { y = 1 } else x { x = 2; + z = { y = 3 } + } + let e1 = + if true then { x = 1; + z = { y = 3 } + } else { x = 2; + z = { y = 3 } + } + let { z = { + y = _ + }} as f1 = { x = 1; + z = { + y = 2 + } } + let { x = _; z = { + y = _ + }} = { f1 with x = 2; z = { + y = 3 + } + } +type AnonymousRecord = {| + y : int +|} +module AnonymousRecords = + let a = {| + y = 2 + |} + let b = id {| + y = 2 + |} + let c = + if true then ignore {| + y = 2 + |} + let d = + if true then {| y = 1 |} else {| + y = 2 + |} + let e = + if true then {| + y = 1 + |} else {| + y = 2 + |} + let f : {| + y : int + |} = {| + y = 2 + |} + let g : {| + y : int + |} = {| + f with y = 3 + |} + let a0 = {| y = + 2 + |} + let b0 = x {| y = + 2 + |} + let c0 = + if true then x {| y = + 2 + |} + let d0 = + if true then x {| y = 1 |} else x {| y = + 2 + |} + let e0 = + if true then x {| y = + 1 + |} else x {| y = + 2 + |} + let f0 : {| y : + int + |} = x' {| y = + 2 + |} + let g0 : {| x : int; + y : int; z : int + |} = {| f0 with x = 1 + z = 3 + |} + let a1 = {| y = 2; + z = 3 + |} + let b1 = x {| y = 2; + z = 3 + |} + let c1 = + if true then x {| y = 2; + z = 3 + |} + let d1 = + if true then x {| y = 1 |} else x {| y = 2; + z = 3 + |} + let e1 = + if true then x {| y = 1; + z = 3 + |} else x {| y = 2; + z = 3 + |} + let f1 : {| y : int; + z : int + |} = x' {| y = 2; + z = 3 + |} + let g1 : {| x : int; + y : int; z : int + |} = {| f1 with x = 1; + z = 3 + |} +type StructAnonymousRecord = (struct {| // Parentheses required to disambiguate from struct ... end + y : int +|}) +module StructAnonymousRecords = + let a = struct {| + y = 2 + |} + let b = id struct {| + y = 2 + |} + let c = + if true then ignore struct {| + y = 2 + |} + let d = + if true then struct {| y = 1 |} else struct {| + y = 2 + |} + let e = + if true then struct {| + y = 1 + |} else struct {| + y = 2 + |} + let f : struct {| + y : int + |} = struct {| + y = 2 + |} + let g : struct {| + y : int + |} = struct {| + f with y = 3 + |} + let a0 = struct {| y = + 2 + |} + let b0 = id struct {| y = + 2 + |} + let c0 = + if true then ignore struct {| y = + 2 + |} + let d0 = + if true then struct {| y = 1 |} else struct {| y = + 2 + |} + let e0 = + if true then struct {| y = + 1 + |} else struct {| y = + 2 + |} + let f0 : struct {| y : + int + |} = x' struct {| y = + 2 + |} + let g0 : struct {| x : int; + y : int; z : int + |} = struct {| f with x = 1 + z = 3 + |} + let a1 = struct {| y = 2; + z = 3 + |} + let b1 = x struct {| y = 2; + z = 3 + |} + let c1 = + if true then x struct {| y = 2; + z = 3 + |} + let d1 = + if true then x struct {| y = 1 |} else x struct {| y = 2; + z = 3 + |} + let e1 = + if true then x struct {| y = 1; + z = 3 + |} else x struct {| y = 2; + z = 3 + |} + let f1 : struct {| y : int; + z : int + |} = x' struct {| y = 2; + z = 3 + |} + let g1 : struct {| x : int; + y : int; z : int + |} = struct {| f1 with x = 1; + z = 3 + |} +module TypedQuotations = + let a = <@ + 2 + @> + let b = id <@ + 2 + @> + let c = + if true then ignore <@ + 2 + @> + let d = + if true then <@ 1 @> else <@ + 2 + @> + let e = + if true then <@ + 1 + @> else <@ + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> f) = <@ + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> _) = <@ + 2 + @> + let a0 = <@ 2 = + 2 + @> + let b0 = x <@ 2 = + 2 + @> + let c0 = + if true then x <@ 2 = + 2 + @> + let d0 = + if true then x <@ 2 = 1 @> else x <@ 2 = + 2 + @> + let e0 = + if true then x <@ 2 = + 1 + @> else x <@ 2 = + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> f0) = x' <@ 2 = + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> _) = <@ 2 = + 2 + @> + let a1 = <@ 2 = 2, + 3 = 3 + @> + let b1 = x <@ 2 = 2, + 3 = 3 + @> + let c1 = + if true then x <@ 2 = 2, + 3 = 3 + @> + let d1 = + if true then x <@ 2 = 1 @> else x <@ 2 = 2, + 3 = 3 + @> + let e1 = + if true then x <@ 2 = 1, + 3 = 3 + @> else x <@ 2 = 2, + 3 = 3 + @> + let (ActivePatterns.B <@ 2 = 2, + 3 = 3 + @> f1) = x' <@ 2 = 2, + 3 = 3 + @> + let (ActivePatterns.B <@ 2 = 2, + 3 = 3 + @> _) = <@ 2 = 2, + 3 = 3 + @> +module UntypedQuotations = + let a = <@@ + 2 + @@> + let b = id <@@ + 2 + @@> + let c = + if true then ignore <@@ + 2 + @@> + let d = + if true then <@@ 1 @@> else <@@ + 2 + @@> + let e = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> f) = <@@ + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> _) = <@@ + 2 + @@> + let a0 = <@@ 2 = + 2 + @@> + let b0 = x <@@ 2 = + 2 + @@> + let c0 = + if true then x <@@ 2 = + 2 + @@> + let d0 = + if true then x <@@ 2 = 1 @@> else x <@@ 2 = + 2 + @@> + let e0 = + if true then x <@@ 2 = + 1 + @@> else x <@@ 2 = + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> f0) = x' <@@ 2 = + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> _) = <@@ 2 = + 2 + @@> + let a1 = <@@ 2 = 2, + 3 = 3 + @@> + let b1 = x <@@ 2 = 2, + 3 = 3 + @@> + let c1 = + if true then x <@@ 2 = 2, + 3 = 3 + @@> + let d1 = + if true then x <@@ 2 = 1 @@> else x <@@ 2 = 2, + 3 = 3 + @@> + let e1 = + if true then x <@@ 2 = 1, + 3 = 3 + @@> else x <@@ 2 = 2, + 3 = 3 + @@> + let (ActivePatterns.B <@@ 2 = 2, + 3 = 3 + @@> f1) = x' <@@ 2 = 2, + 3 = 3 + @@> + let (ActivePatterns.B <@@ 2 = 2, + 3 = 3 + @@> _) = <@@ 2 = 2, + 3 = 3 + @@> +type Id<'T> = 'T -> 'T +type Id2<'T, 'U> = 'T * 'U -> 'T * 'U +let [] id2<'T, 'U> = id<'T * 'U> +module Generics = + // Unlike 'end' / ')' / '|)' / ']' / '|]' / '}' / '|}', + // '>' terminates the declaration automatically, + // so you must indent non-terminating '>'s by at least one space + let a : Id< + 'T + > = id< + 'T + > + let b = id< + int + > + let c = + if true then ignore id< + int + > + let d = + if true then id else id< + int + > + let e = + if true then id< + int + > else id< + int + > + let f< + 'T + > = id< + 'T + > + let a0 : Id<'T * ( + 'T + )> = id<'T * + 'T + > + let b0 = x id + let c0 = + if true then x id + let d0 = + if true then x id else x id + let e0 = + if true then x id else x id + let f0 : Id< + int + > = id |> x'> + let a1 : Id2<'T, + 'T + > = id2<'T, + 'T + > + let b1 = x id2 + let c1 = + if true then x id2 + let d1 = + if true then x id2 else x id2 + let e1 = + if true then x id2 else x id2 + let f1 : Id2 = id2 |> x'> +type BeginEnd( + __ +) = + let a = begin + 2 + end + let b = id begin + 2 + end + let c = + if true then ignore begin + 2 + end + let d = + if true then begin 1 end else begin + 2 + end + let e = + if true then begin + 1 + end else begin + 2 + end + let ( + _ + ) as f = begin + 2 + end + let ( + _ + ) = begin + 3 + end + static let a' = begin + 2 + end + static let b' = id begin + 2 + end + static let c' = + if true then ignore begin + 2 + end + static let d' = + if true then begin 1 end else begin + 2 + end + static let e' = + if true then begin + 1 + end else begin + 2 + end + static let ( + _ + ) as f' = begin + 2 + end + static let ( + _ + ) = begin + 3 + end + static member A = begin + 2 + end + static member B = id begin + 2 + end + static member C = + if true then ignore begin + 2 + end + static member D = + if true then begin 1 end else begin + 2 + end + static member E = + if true then begin + 1 + end else begin + 2 + end + static member F ( + _ + ) = begin + 2 + end + static member G ( + _ + ) = begin + 3 + end + member _.A' = begin + 2 + end + member _.B' = id begin + 2 + end + member _.C' = + if true then ignore begin + 2 + end + member _.D' = + if true then begin 1 end else begin + 2 + end + member _.E' = + if true then begin + 1 + end else begin + 2 + end + member _.F' ( + _ + ) = begin + 2 + end + member _.G' ( + _ + ) = begin + 3 + end +type Parens(__:( + obj +)) = + let a = ( + 2 + ) + let b = id ( + 2 + ) + let c = + if true then ignore ( + 2 + ) + let d = + if true then ( 1 ) else ( + 2 + ) + let e = + if true then ( + 1 + ) else ( + 2 + ) + let ( + _ + ) as f = ( + 2 + ) + let ( + _ + ) = ( + 3 + ) + static let a' = ( + 2 + ) + static let b' = id ( + 2 + ) + static let c' = + if true then ignore ( + 2 + ) + static let d' = + if true then ( 1 ) else ( + 2 + ) + static let e' = + if true then ( + 1 + ) else ( + 2 + ) + static let ( + _ + ) as f' = ( + 2 + ) + static let ( + _ + ) = ( + 3 + ) + static member A = ( + 2 + ) + static member B = id ( + 2 + ) + static member C = + if true then ignore ( + 2 + ) + static member D = + if true then ( 1 ) else ( + 2 + ) + static member E = + if true then ( + 1 + ) else ( + 2 + ) + static member F( + _ + ) = ( + 2 + ) + static member G( + _ + ) = ( + 3 + ) + member _.A' = ( + 2 + ) + member _.B' = id ( + 2 + ) + member _.C' = + if true then ignore ( + 2 + ) + member _.D' = + if true then ( 1 ) else ( + 2 + ) + member _.E' = + if true then ( + 1 + ) else ( + 2 + ) + member _.F'( + _ + ) = ( + 2 + ) + member _.G'( + _ + ) = ( + 3 + ) +// These are lexed differently but it's visually appealing to still include +type ActivePatterns() = + let (| + A + |) = (| + Lazy + |) + let (| + B + |) = (| + A + |) + let (|C|) = + if true then ignore (| + A + |) + let d = + if true then (| A |) else (| + B + |) + let e = + if true then (| + A + |) else (| + B + |) + let (| + F + | + _ + |) as f = Some (| + C + |) + let (| + G + | + _ + |) = (| + F + | + _ + |) + static let (| + A_ + |) = (| + Lazy + |) + static let (| + B_ + |) = (| + A_ + |) + static let (|C_|) = + if true then ignore (| + A_ + |) + static let d_ = + if true then (| A_ |) else (| + B_ + |) + static let e_ = + if true then (| + A_ + |) else (| + B_ + |) + static let (| + F_ + | + _ + |) as f_ = Some (| + C_ + |) + static let (| + G_ + | + _ + |) = (| + F_ + | + _ + |) + static member (| + AA + |) = (| + Lazy + |) + static member (| + BB + |) = ActivePatterns.(| + AA + |) + static member (|CC|) = + if true then ignore ActivePatterns.(| + AA + |) + static member D = + if true then ActivePatterns.(| AA |) else ActivePatterns.(| + BB + |) + static member E = + if true then ActivePatterns.(| + AA + |) else ActivePatterns.(| + BB + |) + static member (| + FF + | + _ + |) = Some ActivePatterns.(| + CC + |) + static member (| + GG + | + _ + |) = ActivePatterns.(| + FF + | + _ + |) + member _.(| + A' + |) = (| + Lazy + |) + member this.(| + B' + |) = this.(| + A' + |) + member this.(|C'|) = + if true then ignore this.(| + A' + |) + member this.D' = + if true then this.(| A' |) else this.(| + B' + |) + member this.E' = + if true then this.(| + A' + |) else this.(| + B' + |) + member this.(| + F' + | + _ + |) = Some this.(| + C' + |) + member this.(| + G' + | + _ + |) = this.(| + F' + | + _ + |) +type Lists() = + let a = [ + 2 + ] + let b = id [ + 2 + ] + let c = + if true then ignore [ + 2 + ] + let d = + if true then [ 1 ] else [ + 2 + ] + let e = + if true then [ + 1 + ] else [ + 2 + ] + let [ + _ + ] as f = [ + 2 + ] + let [ + _ + ] = [ + 3 + ] + static let a' = [ + 2 + ] + static let b' = id [ + 2 + ] + static let c' = + if true then ignore [ + 2 + ] + static let d' = + if true then [ 1 ] else [ + 2 + ] + static let e' = + if true then [ + 1 + ] else [ + 2 + ] + static let [ + _ + ] as f' = [ + 2 + ] + static let [ + _ + ] = [ + 3 + ] + static member A = [ + 2 + ] + static member B = id [ + 2 + ] + static member C = + if true then ignore [ + 2 + ] + static member D = + if true then [ 1 ] else [ + 2 + ] + static member E = + if true then [ + 1 + ] else [ + 2 + ] + static member F[ + _ + ] = [ + 2 + ] + static member G[ + _ + ] = [ + 3 + ] + member _.A' = [ + 2 + ] + member _.B' = id [ + 2 + ] + member _.C' = + if true then ignore [ + 2 + ] + member _.D' = + if true then [ 1 ] else [ + 2 + ] + member _.E' = + if true then [ + 1 + ] else [ + 2 + ] + member _.F'[ + _ + ] = [ + 2 + ] + member _.G'[ + _ + ] = [ + 3 + ] +type Arrays() = + let a = [| + 2 + |] + let b = id [| + 2 + |] + let c = + if true then ignore [| + 2 + |] + let d = + if true then [| 1 |] else [| + 2 + |] + let e = + if true then [| + 1 + |] else [| + 2 + |] + let [| + _ + |] as f = [| + 2 + |] + let [| + _ + |] = [| + 3 + |] + static let a' = [| + 2 + |] + static let b' = id [| + 2 + |] + static let c' = + if true then ignore [| + 2 + |] + static let d' = + if true then [| 1 |] else [| + 2 + |] + static let e' = + if true then [| + 1 + |] else [| + 2 + |] + static let [| + _ + |] as f' = [| + 2 + |] + static let [| + _ + |] = [| + 3 + |] + static member A = [| + 2 + |] + static member B = id [| + 2 + |] + static member C = + if true then ignore [| + 2 + |] + static member D = + if true then [| 1 |] else [| + 2 + |] + static member E = + if true then [| + 1 + |] else [| + 2 + |] + static member F[| + _ + |] = [| + 2 + |] + static member G[| + _ + |] = [| + 3 + |] + member _.A' = [| + 2 + |] + member _.B' = id [| + 2 + |] + member _.C' = + if true then ignore [| + 2 + |] + member _.D' = + if true then [| 1 |] else [| + 2 + |] + member _.E' = + if true then [| + 1 + |] else [| + 2 + |] + member _.F'[| + _ + |] = [| + 2 + |] + member _.G'[| + _ + |] = [| + 3 + |] +type Records(__:struct {| + x : unit +|}) = + let a = { + y = 2 + } + let b = id { + y = 2 + } + let c = + if true then ignore { + y = 2 + } + let d = + if true then { y = 1 } else { + y = 2 + } + let e = + if true then { + y = 1 + } else { + y = 2 + } + let { + y = _ + } as f = { + y = 2 + } + let { + y = _ + } = { + f with y = 3 + } + static let a' = { + y = 2 + } + static let b' = id { + y = 2 + } + static let c' = + if true then ignore { + y = 2 + } + static let d' = + if true then { y = 1 } else { + y = 2 + } + static let e' = + if true then { + y = 1 + } else { + y = 2 + } + static let { + y = _ + } as f' = { + y = 2 + } + static let { + y = _ + } = { + f' with y = 3 + } + static member A = { + y = 2 + } + static member B = id { + y = 2 + } + static member C = + if true then ignore { + y = 2 + } + static member D = + if true then { y = 1 } else { + y = 2 + } + static member E = + if true then { + y = 1 + } else { + y = 2 + } + static member F{ + y = _ + } = { + y = 2 + } + static member G{ + y = _ + } = { + Records.F { y = 1 } with y = 3 + } + member _.A' = { + y = 2 + } + member _.B' = id { + y = 2 + } + member _.C' = + if true then ignore { + y = 2 + } + member _.D' = + if true then { y = 1 } else { + y = 2 + } + member _.E' = + if true then { + y = 1 + } else { + y = 2 + } + member _.F'{ + y = _ + } = { + y = 2 + } + member this.G'{ + y = _ + } = { + this.F' { y = 1 } with y = 3 + } +type AnonymousRecords(x:{| + x : bool +|}) = + let a = {| + y = 2 + |} + let b = id {| + y = 2 + |} + let c = + if true then ignore {| + y = 2 + |} + let d = + if true then {| y = 1 |} else {| + y = 2 + |} + let e = + if true then {| + y = 1 + |} else {| + y = 2 + |} + let f : {| + y : int + |} = {| + y = 2 + |} + let g : {| + y : int + |} = {| + f with y = 3 + |} + static let a' = {| + y = 2 + |} + static let b' = id {| + y = 2 + |} + static let c' = + if true then ignore {| + y = 2 + |} + static let d' = + if true then {| y = 1 |} else {| + y = 2 + |} + static let e' = + if true then {| + y = 1 + |} else {| + y = 2 + |} + static let f' : {| + y : int + |} = {| + y = 2 + |} + static let g' : {| + y : int + |} = {| + f' with y = 3 + |} + static member A = {| + y = 2 + |} + static member B = id {| + y = 2 + |} + static member C = + if true then ignore {| + y = 2 + |} + static member D = + if true then {| y = 1 |} else {| + y = 2 + |} + static member E = + if true then {| + y = 1 + |} else {| + y = 2 + |} + static member F : {| + y : int + |} = {| + y = 2 + |} + static member G : {| + y : int + |} = {| + AnonymousRecords.F with y = 3 + |} + member _.A' = {| + y = 2 + |} + member _.B' = id {| + y = 2 + |} + member _.C' = + if true then ignore {| + y = 2 + |} + member _.D' = + if true then {| y = 1 |} else {| + y = 2 + |} + member _.E' = + if true then {| + y = 1 + |} else {| + y = 2 + |} + member _.F' : {| + y : int + |} = {| + y = 2 + |} + member this.G' : {| + y : int + |} = {| + this.F' with y = 3 + |} +type StructAnonymousRecords(x:struct{| + x : bool +|}) = + let a = struct{| + y = 2 + |} + let b = id struct{| + y = 2 + |} + let c = + if true then ignore struct{| + y = 2 + |} + let d = + if true then struct{| y = 1 |} else struct{| + y = 2 + |} + let e = + if true then struct{| + y = 1 + |} else struct{| + y = 2 + |} + let f : struct{| + y : int + |} = struct{| + y = 2 + |} + let g : struct{| + y : int + |} = struct{| + f with y = 3 + |} + static let a' = struct{| + y = 2 + |} + static let b' = id struct{| + y = 2 + |} + static let c' = + if true then ignore struct{| + y = 2 + |} + static let d' = + if true then struct{| y = 1 |} else struct{| + y = 2 + |} + static let e' = + if true then struct{| + y = 1 + |} else struct{| + y = 2 + |} + static let f' : struct{| + y : int + |} = struct{| + y = 2 + |} + static let g' : struct{| + y : int + |} = struct{| + f' with y = 3 + |} + static member A = struct{| + y = 2 + |} + static member B = id struct{| + y = 2 + |} + static member C = + if true then ignore struct{| + y = 2 + |} + static member D = + if true then struct{| y = 1 |} else struct{| + y = 2 + |} + static member E = + if true then struct{| + y = 1 + |} else struct{| + y = 2 + |} + static member F : struct{| + y : int + |} = struct{| + y = 2 + |} + static member G : struct{| + y : int + |} = struct{| + AnonymousRecords.F with y = 3 + |} + member _.A' = struct{| + y = 2 + |} + member _.B' = id struct{| + y = 2 + |} + member _.C' = + if true then ignore struct{| + y = 2 + |} + member _.D' = + if true then struct{| y = 1 |} else struct{| + y = 2 + |} + member _.E' = + if true then struct{| + y = 1 + |} else struct{| + y = 2 + |} + member _.F' : struct{| + y : int + |} = struct{| + y = 2 + |} + member this.G' : struct{| + y : int + |} = struct{| + this.F' with y = 3 + |} +type TypedQuotations(x: +int Quotations.Expr) = + let a = <@ + 2 + @> + let b = id <@ + 2 + @> + let c = + if true then ignore <@ + 2 + @> + let d = + if true then <@ 1 @> else <@ + 2 + @> + let e = + if true then <@ + 1 + @> else <@ + 2 + @> + let (ActivePatterns.B <@ + 2 + @> _) as f = <@ + 2 + @> + let (ActivePatterns.B <@ + 2 + @> _) = <@ + 3 + @> + static let a' = <@ + 2 + @> + static let b' = id <@ + 2 + @> + static let c' = + if true then ignore <@ + 2 + @> + static let d' = + if true then <@ 1 @> else <@ + 2 + @> + static let e' = + if true then <@ + 1 + @> else <@ + 2 + @> + static let (ActivePatterns.B <@ + 2 + @> _) as f' = <@ + 2 + @> + static let (ActivePatterns.B <@ + 2 + @> _) = <@ + 3 + @> + static member A = <@ + 2 + @> + static member B = id <@ + 2 + @> + static member C = + if true then ignore <@ + 2 + @> + static member D = + if true then <@ 1 @> else <@ + 2 + @> + static member E = + if true then <@ + 1 + @> else <@ + 2 + @> + static member F(ActivePatterns.B <@ + 2 + @> _) = <@ + 2 + @> + static member G(ActivePatterns.B <@ + 2 + @> _) = <@ + 3 + @> + member _.A' = <@ + 2 + @> + member _.B' = id <@ + 2 + @> + member _.C' = + if true then ignore <@ + 2 + @> + member _.D' = + if true then <@ 1 @> else <@ + 2 + @> + member _.E' = + if true then <@ + 1 + @> else <@ + 2 + @> + member _.F'(ActivePatterns.B <@ + 2 + @> _) = <@ + 2 + @> + member _.G'(ActivePatterns.B <@ + 2 + @> _) = <@ + 3 + @> +type UntypedQuotations(x: +Quotations.Expr) = + let a = <@@ + 2 + @@> + let b = id <@@ + 2 + @@> + let c = + if true then ignore <@@ + 2 + @@> + let d = + if true then <@@ 1 @@> else <@@ + 2 + @@> + let e = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + let (ActivePatterns.B <@@ + 2 + @@> _) as f = <@@ + 2 + @@> + let (ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 3 + @@> + static let a' = <@@ + 2 + @@> + static let b' = id <@@ + 2 + @@> + static let c' = + if true then ignore <@@ + 2 + @@> + static let d' = + if true then <@@ 1 @@> else <@@ + 2 + @@> + static let e' = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + static let (ActivePatterns.B <@@ + 2 + @@> _) as f' = <@@ + 2 + @@> + static let (ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 3 + @@> + static member A = <@@ + 2 + @@> + static member B = id <@@ + 2 + @@> + static member C = + if true then ignore <@@ + 2 + @@> + static member D = + if true then <@@ 1 @@> else <@@ + 2 + @@> + static member E = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + static member F(ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 2 + @@> + static member G(ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 3 + @@> + member _.A' = <@@ + 2 + @@> + member _.B' = id <@@ + 2 + @@> + member _.C' = + if true then ignore <@@ + 2 + @@> + member _.D' = + if true then <@@ 1 @@> else <@@ + 2 + @@> + member _.E' = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + member _.F'(ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 2 + @@> + member _.G'(ActivePatterns.B <@@ + 2 + @@> _) = <@@ + 3 + @@> +type Generics(__:Id< + obj +>) = + let a : Id< + 'T + > = id< + 'T + > + let b = id< + int + > + let c = + if true then ignore id< + int + > + let d = + if true then id else id< + int + > + let e = + if true then id< + int + > else id< + int + > + static let a' : Id< + 'T + > = id< + 'T + > + static let b' = id< + int + > + static let c' = + if true then ignore id< + int + > + static let d' = + if true then id else id< + int + > + static let e' = + if true then id< + int + > else id< + int + > + static member A< + 'T + >() = id< + 'T + > + static member B = id< + int + > + static member C = + if true then ignore id< + int + > + static member D = + if true then id else id< + int + > + static member E = + if true then id< + int + > else id< + int + > + member _.A'< + 'T + >() = id< + 'T + > + member _.B' = id< + int + > + member _.C' = + if true then ignore id< + int + > + member _.D' = + if true then id else id< + int + > + member _.E' = + if true then id< + int + > else id< + int + > +let BeginEnd = + let a = begin + 2 + end + let b = id begin + 2 + end + let c = + if true then ignore begin + 2 + end + let d = + if true then begin 1 end else begin + 2 + end + let e = + if true then begin + 1 + end else begin + 2 + end + let ( + _ + ) as f = begin + 2 + end + let ( + _ + ) = begin + 3 + end + let h = + if begin + true + end + then begin + end + let i = + if x' begin + false + end + then begin + end + let a0 = begin 2 = + 2 + end + let b0 = x begin y = + 2 + end + let c0 = + if true then x begin y = + 2 + end + let d0 = + if true then x begin y = 1 end else x begin y = + 2 + end + let e0 = + if true then x begin y = + 1 + end else x begin y = + 2 + end + let ( + _ + ) as f0 = x begin y = + 2 + end + let ( + _ + ) = begin 2 = + 3 + end + let h0 = + if begin 2 = + 2 + end + then begin + end + let i0 = + if x' begin y = + true + end + then begin + end + let a1 = begin 2 = 2, + 3 = 2 + end + let b1 = x begin y = 2, + z = 2 + end + let c1 = + if true then x begin y = 2, + z = 3 + end + let d1 = + if true then x begin y = 1 end else x begin y = 2, + z = 3 + end + let e1 = + if true then x begin y = 1, + z = 3 + end else x begin y = 2, + z = 3 + end + let ( + _ + ) as f1 = x begin y = 2, + z = 3 + end + let ( + _ + ) = begin 2 = 3, + 3 = 3 + end + let h1 = + if begin 2 = 2 |> ignore; + 3 = 3 + end + then begin + end + let i1 = + if x' begin y = true, + z = false + end + then begin + end + begin 1 + end +let Parens = + let a = ( + 2 + ) + let b = id ( + 2 + ) + let c = + if true then ignore ( + 2 + ) + let d = + if true then ( 1 ) else ( + 2 + ) + let e = + if true then ( + 1 + ) else ( + 2 + ) + let ( + _ + ) as f = ( + 2 + ) + let ( + _ + ) = ( + 3 + ) + let a0 = (2 = + 2 + ) + let b0 = x (y = + 2 + ) + let c0 = + if true then x (y = + 2 + ) + let d0 = + if true then x ( y = 1 ) else x (y = + 2 + ) + let e0 = + if true then x (y = + 1 + ) else x (y = + 2 + ) + let ( + _ + ) as f0 = x (y = + 2 + ) + let ( + _ + ) = (2 = + 3 + ) + let a1 = (2 = 2, + 3 = 3 + ) + let b1 = x (y = 2, + z = 3 + ) + let c1 = + if true then x (y = 2, + z = 3 + ) + let d1 = + if true then x ( y = 1 ) else x (y = 2, + z = 3 + ) + let e1 = + if true then x (y = 1, + z = 3 + ) else x (y = 2, + z = 3 + ) + let ( + _ + ) as f1 = x (y = 2, + z = 3 + ) + let ( + _ + ) = (2 = 3, + 3 = 3 + ) + ( 1 + ) +// These are lexed differently but it's visually appealing to still include +let ActivePatterns<'a> = + let (| + A + |) = id + let (| + B + |) _ = (| + A + |) + let (|C|) = + if true then ignore (| + A + |) + let d = + if true then (| A |) else (| + A + |) + let e = + if true then (| + A + |) else (| + A + |) + let (| + F + | + _ + |) as f = Some (| + C + |) + let (| + G + | + _ + |) = (| + F + | + _ + |) + (| A + |) +let Lists = + let a = [ + 2 + ] + let b = id [ + 2 + ] + let c = + if true then ignore [ + 2 + ] + let d = + if true then [ 1 ] else [ + 2 + ] + let e = + if true then [ + 1 + ] else [ + 2 + ] + let [ + _ + ] as f = [ + 2 + ] + let [ + _ + ] = [ + 3 + ] + let a0 = [ 2 = + 2 + ] + let b0 = x [ 2 = + 2 + ] + let c0 = + if true then x [ 2 = + 2 + ] + let d0 = + if true then x [ 2 = 1 ] else x [ 2 = + 2 + ] + let e0 = + if true then x [ 2 = + 1 + ] else x [ 2 = + 2 + ] + let [ + _ + ] as f0 = x' [ 2 = + 2 + ] + let [ + _ + ] = [ 2 = + 3 + ] + let a1 = [ 2 = 2, + 3 = 3 + ] + let b1 = x [ 2 = 2, + 3 = 3 + ] + let c1 = + if true then x [ 2 = 2, + 3 = 3 + ] + let d1 = + if true then x [ 2 = 1 ] else x [ 2 = 2, + 3 = 3 + ] + let e1 = + if true then x [ 2 = 1, + 3 = 3 + ] else x [ 2 = 2, + 3 = 3 + ] + let [ + _ + ] as f1 = x' [ 2 = 2, + 3 = 3 + ] + let [ + _ + ] = [ 2 = 3, + 3 = 3 + ] + [ 1 + ] +let Arrays = + let a = [| + 2 + |] + let b = id [| + 2 + |] + let c = + if true then ignore [| + 2 + |] + let d = + if true then [| 1 |] else [| + 2 + |] + let e = + if true then [| + 1 + |] else [| + 2 + |] + let [| + _ + |] as f = [| + 2 + |] + let [| + _ + |] = [| + 3 + |] + let a0 = [| 2 = + 2 + |] + let b0 = x [| 2 = + 2 + |] + let c0 = + if true then x [| 2 = + 2 + |] + let d0 = + if true then x [| 2 = 1 |] else x [| 2 = + 2 + |] + let e0 = + if true then x [| 2 = + 1 + |] else x [| 2 = + 2 + |] + let [| + _ + |] as f0 = x' [| 2 = + 2 + |] + let [| + _ + |] = [| 2 = + 3 + |] + let a1 = [| 2 = 2, + 3 = 3 + |] + let b1 = x [| 2 = 2, + 3 = 3 + |] + let c1 = + if true then x [| 2 = 2, + 3 = 3 + |] + let d1 = + if true then x [| 2 = 1 |] else x [| 2 = 2, + 3 = 3 + |] + let e1 = + if true then x [| 2 = 1, + 3 = 3 + |] else x [| 2 = 2, + 3 = 3 + |] + let [| + _ + |] as f1 = x' [| 2 = 2, + 3 = 3 + |] + let [| + _ + |] = [| 2 = 3, + 3 = 3 + |] + [| 1 + |] +let Records = + let a = { + y = 2 + } + let b = id { + y = 2 + } + let c = + if true then ignore { + y = 2 + } + let d = + if true then { y = 1 } else { + y = 2 + } + let e = + if true then { + y = 1 + } else { + y = 2 + } + let { + y = _ + } as f = { + y = 2 + } + let { + y = _ + } = { + f with y = 3 + } + let a0 = { y = + 2 + } + let b0 = x { y = + 2 + } + let c0 = + if true then x { y = + 2 + } + let d0 = + if true then x { y = 1 } else x { y = + 2 + } + let e0 = + if true then { y = + 1 + } else { y = + 2 + } + let { z = { + y = _ + }} as f0 = { z = { + y = 2 + }; x = 1} + let { z = { + y = _ + }} = { f0 with z = { + y = 3 + } + } + let a1 = { x = 2; + z = { y = 3 } + } + let b1 = x { x = 2; + z = { y = 3 } + } + let c1 = + if true then x { x = 2; + z = { y = 3 } + } + let d1 = + if true then x { y = 1 } else x { x = 2; + z = { y = 3 } + } + let e1 = + if true then { x = 1; + z = { y = 3 } + } else { x = 2; + z = { y = 3 } + } + let { z = { + y = _ + }} as f1 = { x = 1; + z = { + y = 2 + } } + let { x = _; z = { + y = _ + }} = { f1 with x = 2; z = { + y = 3 + } + } + { y = 1 + } +let AnonymousRecords = + let a = {| + y = 2 + |} + let b = id {| + y = 2 + |} + let c = + if true then ignore {| + y = 2 + |} + let d = + if true then {| y = 1 |} else {| + y = 2 + |} + let e = + if true then {| + y = 1 + |} else {| + y = 2 + |} + let f : {| + y : int + |} = {| + y = 2 + |} + let g : {| + y : int + |} = {| + f with y = 3 + |} + let a0 = {| y = + 2 + |} + let b0 = x {| y = + 2 + |} + let c0 = + if true then x {| y = + 2 + |} + let d0 = + if true then x {| y = 1 |} else x {| y = + 2 + |} + let e0 = + if true then x {| y = + 1 + |} else x {| y = + 2 + |} + let f0 : {| y : + int + |} = x' {| y = + 2 + |} + let g0 : {| x : int; + y : int; z : int + |} = {| f0 with x = 1 + z = 3 + |} + let a1 = {| y = 2; + z = 3 + |} + let b1 = x {| y = 2; + z = 3 + |} + let c1 = + if true then x {| y = 2; + z = 3 + |} + let d1 = + if true then x {| y = 1 |} else x {| y = 2; + z = 3 + |} + let e1 = + if true then x {| y = 1; + z = 3 + |} else x {| y = 2; + z = 3 + |} + let f1 : {| y : int; + z : int + |} = x' {| y = 2; + z = 3 + |} + let g1 : {| x : int; + y : int; z : int + |} = {| f1 with x = 1; + z = 3 + |} + {| y = 1 + |} +let StructAnonymousRecords = + let a = struct {| + y = 2 + |} + let b = id struct {| + y = 2 + |} + let c = + if true then ignore struct {| + y = 2 + |} + let d = + if true then struct {| y = 1 |} else struct {| + y = 2 + |} + let e = + if true then struct {| + y = 1 + |} else struct {| + y = 2 + |} + let f : struct {| + y : int + |} = struct {| + y = 2 + |} + let g : struct {| + y : int + |} = struct {| + f with y = 3 + |} + let a0 = struct {| y = + 2 + |} + let b0 = id struct {| y = + 2 + |} + let c0 = + if true then ignore struct {| y = + 2 + |} + let d0 = + if true then struct {| y = 1 |} else struct {| y = + 2 + |} + let e0 = + if true then struct {| y = + 1 + |} else struct {| y = + 2 + |} + let f0 : struct {| y : + int + |} = x' struct {| y = + 2 + |} + let g0 : struct {| x : int; + y : int; z : int + |} = struct {| f with x = 1 + z = 3 + |} + let a1 = struct {| y = 2; + z = 3 + |} + let b1 = x struct {| y = 2; + z = 3 + |} + let c1 = + if true then x struct {| y = 2; + z = 3 + |} + let d1 = + if true then x struct {| y = 1 |} else x struct {| y = 2; + z = 3 + |} + let e1 = + if true then x struct {| y = 1; + z = 3 + |} else x struct {| y = 2; + z = 3 + |} + let f1 : struct {| y : int; + z : int + |} = x' struct {| y = 2; + z = 3 + |} + let g1 : struct {| x : int; + y : int; z : int + |} = struct {| f1 with x = 1; + z = 3 + |} + struct {| y = 1 + |} +let TypedQuotations = + let a = <@ + 2 + @> + let b = id <@ + 2 + @> + let c = + if true then ignore <@ + 2 + @> + let d = + if true then <@ 1 @> else <@ + 2 + @> + let e = + if true then <@ + 1 + @> else <@ + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> f) = <@ + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> _) = <@ + 2 + @> + let a0 = <@ 2 = + 2 + @> + let b0 = x <@ 2 = + 2 + @> + let c0 = + if true then x <@ 2 = + 2 + @> + let d0 = + if true then x <@ 2 = 1 @> else x <@ 2 = + 2 + @> + let e0 = + if true then x <@ 2 = + 1 + @> else x <@ 2 = + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> f0) = x' <@ 2 = + 2 + @> + let (ActivePatterns.B <@ 2 = + 2 + @> _) = <@ 2 = + 2 + @> + let a1 = <@ 2 = 2, + 3 = 3 + @> + let b1 = x <@ 2 = 2, + 3 = 3 + @> + let c1 = + if true then x <@ 2 = 2, + 3 = 3 + @> + let d1 = + if true then x <@ 2 = 1 @> else x <@ 2 = 2, + 3 = 3 + @> + let e1 = + if true then x <@ 2 = 1, + 3 = 3 + @> else x <@ 2 = 2, + 3 = 3 + @> + let (ActivePatterns.B <@ 2 = 2, + 3 = 3 + @> f1) = x' <@ 2 = 2, + 3 = 3 + @> + let (ActivePatterns.B <@ 2 = 2, + 3 = 3 + @> _) = <@ 2 = 2, + 3 = 3 + @> + <@ 1 + @> +let UntypedQuotations = + let a = <@@ + 2 + @@> + let b = id <@@ + 2 + @@> + let c = + if true then ignore <@@ + 2 + @@> + let d = + if true then <@@ 1 @@> else <@@ + 2 + @@> + let e = + if true then <@@ + 1 + @@> else <@@ + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> f) = <@@ + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> _) = <@@ + 2 + @@> + let a0 = <@@ 2 = + 2 + @@> + let b0 = x <@@ 2 = + 2 + @@> + let c0 = + if true then x <@@ 2 = + 2 + @@> + let d0 = + if true then x <@@ 2 = 1 @@> else x <@@ 2 = + 2 + @@> + let e0 = + if true then x <@@ 2 = + 1 + @@> else x <@@ 2 = + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> f0) = x' <@@ 2 = + 2 + @@> + let (ActivePatterns.B <@@ 2 = + 2 + @@> _) = <@@ 2 = + 2 + @@> + let a1 = <@@ 2 = 2, + 3 = 3 + @@> + let b1 = x <@@ 2 = 2, + 3 = 3 + @@> + let c1 = + if true then x <@@ 2 = 2, + 3 = 3 + @@> + let d1 = + if true then x <@@ 2 = 1 @@> else x <@@ 2 = 2, + 3 = 3 + @@> + let e1 = + if true then x <@@ 2 = 1, + 3 = 3 + @@> else x <@@ 2 = 2, + 3 = 3 + @@> + let (ActivePatterns.B <@@ 2 = 2, + 3 = 3 + @@> f1) = x' <@@ 2 = 2, + 3 = 3 + @@> + let (ActivePatterns.B <@@ 2 = 2, + 3 = 3 + @@> _) = <@@ 2 = 2, + 3 = 3 + @@> + <@@ 1 + @@> +let Generics = + // Unlike 'end' / ')' / '|)' / ']' / '|]' / '}' / '|}', + // '>' terminates the declaration automatically, + // so you must indent non-terminating '>'s by at least one space + let a : Id< + 'T + > = id< + 'T + > + let b = id< + int + > + let c = + if true then ignore id< + int + > + let d = + if true then id else id< + int + > + let e = + if true then id< + int + > else id< + int + > + let f : Id<'T + > = id< + 'T + > + let a0 : Id<'T * ( + 'T + )> = id<'T * + 'T + > + let b0 = x id + let c0 = + if true then x id + let d0 = + if true then x id else x id + let e0 = + if true then x id else x id + let f0 : Id< + int + > = id |> x'> + let a1 : Id2<'T, + 'T + > = id2<'T, + 'T + > + let b1 = x id2 + let c1 = + if true then x id2 + let d1 = + if true then x id2 else x id2 + let e1 = + if true then x id2 else x id2 + let f1 : Id2 = id2 |> x'> + id + +type Foo ( + y: int, + x: int +) = + // https://github.com/fsharp/fslang-suggestions/issues/931 + let g = System.DateTime( + year = 2020, + month = 12, + day = 1 + ) + member _.Bar( + a: int, + b: int + ) = + let g = System.DateTime( + year = 2020, + month = 12, + day = 1 + ) + + // https://github.com/fsharp/fslang-suggestions/issues/833 + match + 2 + with 2 -> () + match + 2 + with | 2 -> () + match + 2 + with + | 2 -> () + match + match + match + 1 + with _ -> 2 + with + | _ -> 3 + with + | 4 -> () + match + try + match + 1 + with | _ -> 2 + with + _ -> 3 + with + 4 -> g + static member Baz( + _ + ) = () + +// https://github.com/fsharp/fslang-suggestions/issues/786 +let f' x = x +let a = f' [ + 2 // List: OK +] +let b = [| + 2 // Array: OK +|] +type X = { X : int } +let c = f' { + X = 2 // Record: OK +} +let d = f' {| + X = 2 (* FS0058 Possible incorrect indentation: +this token is offside of context started at position (12:11). +Try indenting this token further or using standard formatting conventions. *) +|} +let e = f' {| + X = 2 // Indenting further is needed + |} + +open System +// https://github.com/fsharp/fslang-suggestions/issues/724 +type SixAccessViolations(a:AccessViolationException, + b:AccessViolationException, c:AccessViolationException, + d:AccessViolationException, e:AccessViolationException, + f:AccessViolationException) = + class end +type SixAccessViolations2( + a:AccessViolationException, + b:AccessViolationException, c:AccessViolationException, + d:AccessViolationException, e:AccessViolationException, + f:AccessViolationException) = + class end +type SixAccessViolations3( + a:AccessViolationException, + b:AccessViolationException, c:AccessViolationException, + d:AccessViolationException, e:AccessViolationException, + f:AccessViolationException +) = class end + +// https://github.com/dotnet/fsharp/issues/3326 +// https://github.com/fsharp/fslang-suggestions/issues/868 +open System.IO + +type message = +| HeatUp +| CoolDown + +let climateControl1 = MailboxProcessor.Start( fun inbox -> + // NOTE compiles + let rec heating() = async { + printfn "Heating" + let! msg = inbox.Receive() + match msg with + | CoolDown -> return! cooling() + | _ -> return! heating() + } // NOTE placement of } + and cooling() = async { + printfn "Cooling" + let! msg = inbox.Receive() + match msg with + | HeatUp -> return! heating() + | _ -> return! cooling() + } // NOTE placement of } + + heating() +) + +let climateControl2 = MailboxProcessor.Start(fun inbox -> + // NOTE compiles + let rec heating() = async { + printfn "Heating" + let! msg = inbox.Receive() + match msg with + | CoolDown -> return () + | _ -> return! heating() + } // NOTE placement of } + heating() +) + +let climateControl3 = MailboxProcessor.Start(fun inbox -> + // NOTE does not compile + let rec heating() = async { + printfn "Heating" + let! msg = inbox.Receive() + match msg with + | CoolDown -> return! cooling() + | _ -> return! heating() + } // NOTE placement of } + and cooling() = async { + printfn "Cooling" + let! msg = inbox.Receive() + match msg with + | HeatUp -> return! heating() + | _ -> return! cooling() + } // NOTE placement of } + + heating() +) + +// https://github.com/dotnet/fsharp/issues/10852 +let f _ b = b +let g _ b = b + +let aaaaa<'t> = f >> g + +let bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = 42 +let cc = 43 + +aaaaa ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cc +) () + +(f >> g) ( + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cc +) begin end + +// https://github.com/dotnet/fsharp/issues/10929 + +let a' = System.Text.RegularExpressions.Regex.IsMatch( + "myInput", + """^[a-zA-Z][a-zA-Z0-9']+$""" +) + +if System.Text.RegularExpressions.Regex.IsMatch( + "myInput", + """^[a-zA-Z][a-zA-Z0-9']+$""" + ) then + () + +// https://github.com/fsharp/fslang-suggestions/issues/504 +module Q = + module Z = + type Alpha< ^b, ^a + when ^ a : (member Name:string) +and ^a: (member Zip + : ^b when +^b : struct ) +and ^a +: (static member(+) + : 'a * 'a +-> 'a +) + > () = + member inline __.X = () + with + static member inline Y = () + +type TypeWithALongName< ^a + when ^a:(static member(+):'a * 'a -> 'a ) + and ^a:(static member(-):'a * 'a -> 'a ) + and ^a:(static member(*):'a * 'a -> 'a ) + and ^a:(static member(/):'a * 'a -> 'a ) +> = + static member inline X = 2 +type TypeWithALongName2< ^a + when ^a:(static member(+):'a * 'a -> 'a ) + and ^a:(static member(-):'a * 'a -> 'a ) + and ^a:(static member(*):'a * 'a -> 'a ) + and ^a:(static member(/):'a * 'a -> 'a ) + > = static member inline X = () +type TypeWithALongName3< 'a + when 'a: not struct + and ^a:(static member(-):'a * 'a -> 'a ) + and 'a:> System.IDisposable + and ^a:> System.Object +> = static member inline X = () +// https://github.com/fsharp/fslang-suggestions/issues/470 + +type ColorAxis(values : int[], + colors: string[] +) = struct + member _.Values = values + member _.Colors = colors +end +type Options(colorAxis: ColorAxis) = class + member _.ColorAxis = colorAxis +end +type Geo = Geo +module Chart = + let Geo _ = Geo + let WithOptions ( + _: Options + ) Geo = () +let ( + => + ) _ = id +let wb = {| + Countries = [| + {| + Name = "" + Indicators = {| + ``CO2 emissions (kt)`` = dict [ + 2010, () + ] + |} + |} + |] +|} +let ( + series +) = ignore +let ( + growth +) = ignore + +(* +Currently, the general rules for indentation in F# is that the code on +the next line should be indented further than the thing that determines +its starting point on the previous line. + +There are a number of cases where this quite annoyingly means that you +have to indent things very far (or, to avoid that, add lots of +unnecessary line breaks). One example is when you have nesting in a +method call. For example: +*) +Chart.Geo(growth) +|> Chart.WithOptions(Options(colorAxis=ColorAxis(values=[| -100;0;100;200;1000 |], colors=[| "#77D53D";"#D1C855";"#E8A958";"#EA4C41";"#930700" |]))) +(* +Now, there is almost no way to make this code snippet look decent. I would +want to write something like this: +*) +Chart.Geo(growth) +|> Chart.WithOptions(Options(colorAxis=ColorAxis(values=[| -100;0;100;200;1000 |], + colors=[| "#77D53D";"#D1C855";"#E8A958";"#EA4C41";"#930700" |]))) +(* +But this is not allowed, because "colors" should start after the opening +parenthesis of ColorAxis, so I would need 50 spaces! To make the number of +spaces smaller, you can add additional newline (to get the "ColorAxis" more to +the left), but this looks pretty bad: +*) +Chart.Geo(growth) +|> Chart.WithOptions + (Options + (colorAxis = + ColorAxis + (values=[| -100;0;100;200;1000 |], + colors=[| "#77D53D";"#D1C855";"#E8A958";"#EA4C41";"#930700" |]))) +(* +Another example is very similar, but with list expressions. +I want to write: +*) +// let pop2010 = series [ for c in wb.Countries -> +// c.Name => c.Indicators.``CO2 emissions (kt)``.[2010]] +// NOTE: That is probably is too much of an undentation. Try this instead: +let pop2010 = series [ + for c in wb.Countries -> + c.Name => c.Indicators.``CO2 emissions (kt)``.[2010]] + +(* +This actually works, but it gives warning. Again, it wants me to indent the +second line so that it is after "for", but then I'm not saving pretty much +anything by the newline. Or, I can introduce lots of additional newlines +and write: +*) +let pop2011 = + series + [ for c in wb.Countries -> + c.Name => c.Indicators.``CO2 emissions (kt)``.[2010]] +(* +I think that in situations like these, the rules should be relaxed. +In particular, we should not require new line to be intended further +than the "starting thing" on the previous line. Just further than the +previous line. +*) + +let foo = ([| + 1 + 2 +|]) + +let bar = [| + 1 + 2 +|] + +// Some random cases + +for i in <@ + 1 +@> |> box |> unbox do () +while <@@ + 1 +@@> |> box |> unbox do () +do ignore <| <@@ + 1 +@@> + +function +| { + y = 6 + } -> () +<| { + y = 7 +} +function +| { + y = 6 + } when { + y = 2 + } = { + y = 3 + } -> () +<| { + y = 7 +} +function { + y = 6 + } when { + y = 2 + } = { + y = 3 + } -> () +<| { + y = 7 +} + +exception J of {| + r : int +|} + +// Individual testing of special-cased contexts + +do ( + () +) +do ignore ( + 1 +) +exception J'' of {| + r : int +|} +exception J' of r : ( + int +) with + member _.A( + _ + ) = () + member _.A'(_: + _ + ) = () +type System.Int32 with + member _.A( + _ + ) = () + member _.A'(_: + _ + ) = () +for i in <@ + 1 + @> |> box |> unbox do () +for i in seq { + 1 +} |> box |> unbox do () +while <@ + 1 +@> |> box |> unbox do () +while seq { + 1 + } |> box |> unbox do () +try seq { + 1 +} with _ -> seq { 2 } +|> ignore +try <@@ + 1 +@@> with _ -> <@@ 2 @@> +|> ignore +if <@ + 1 +@> |> box |> unbox then () +if seq { + 1 + } |> box |> unbox then () +if true then Seq.head <| seq { + () +} |> id +if true then (box >> unbox) <@ + () +@> |> id +if true then () else (box >> unbox) <| seq { + 1 +} |> id +if true then () else (box >> unbox) <@ + 1 +@> |> id +fun () -> Seq.head <| seq { + () +} |> ignore unit> +function () -> Seq.head <| seq { + () +} |> ignore unit> + +// Examples in the RFC + +type R = { a : int } +type [] H = static member h a = () +module rec M1 = + let messageLoop (state:int) = async { + return! someOther(state) + } // Sure + let someOther(state:int) = async { + return! messageLoop(state) + } +module M2 = + let rec messageLoop (state:int) = async { + return! someOther(state) + } + // error FS0010: Unexpected keyword 'and' in definition. Expected incomplete structured construct at or before this point or other token. + and someOther(state:int) = async { + return! messageLoop(state) + } +let RFC = + + let a = id [ + 1 // No longer produces warning FS0058 after [RFC FS-1054] less strict indentation on common DSL pattern + ] + let b = id ( + 1 // warning FS0058: Possible incorrect indentation + ) + let c = ( + 1 // But this is ok + ) + try + 1 + with _ -> 2 // Totally fine + |> ignore + + match + 1 + with _ -> 2 // error FS0010: Unexpected start of structured construct in expression + |> ignore + if true then [ 0 ] else [ + 1 // This is fine + ] + |> ignore + if true then <@ 0 @> else <@ + 1 // warning FS0058: Possible incorrect indentation + @> + |> ignore + let d = + if [ + 2 // Fine + ] = [3] then () + let e = + if [3] = [ + 2 // warning FS0058: Possible incorrect indentation + ] then () + + let f = { + a = 1 // Ok + } + let { + a = g + } = f // error FS0010: Incomplete structured construct at or before this point in binding. Expected '=' or other token. + + let _ = h { a = + 2 // Ok + } + let _ = h ( a = + 2 // Also ok + ) + let _ = h {| a = + 2 // warning FS0058: Possible incorrect indentation + |} + + let i = + if true then ignore [ + 1 // Ok + ] else ignore [ 2 ] + let j = + if true then ignore [ 1 ] else ignore [ + 2 // Ok + ] + let k = + let tru _ = true + if tru [ + 1 // warning FS0058: Possible incorrect indentation + ] then () + () \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs.bsl b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs.bsl new file mode 100644 index 00000000000..bd04ab2edd9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/Basic/OffsideExceptions/RelaxWhitespace2.fs.bsl @@ -0,0 +1,48 @@ +RelaxWhitespace2.fs (291,9)-(293,12) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (296,9)-(298,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (321,9)-(323,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (326,9)-(328,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (351,9)-(353,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (356,9)-(358,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (382,9)-(384,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (387,9)-(389,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (412,9)-(414,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (417,9)-(419,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (442,9)-(444,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (447,9)-(449,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1439,9)-(1441,12) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1444,9)-(1446,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1469,16)-(1471,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1474,16)-(1476,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1499,20)-(1501,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1504,20)-(1506,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1529,16)-(1531,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1534,16)-(1536,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1560,9)-(1562,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1565,9)-(1567,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1590,16)-(1592,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1595,16)-(1597,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1620,20)-(1622,8) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1625,20)-(1627,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1650,16)-(1652,8) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (1655,16)-(1657,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2714,9)-(2716,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2709,9)-(2711,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2684,9)-(2686,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2679,9)-(2681,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2654,9)-(2656,6) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2649,9)-(2651,12) typecheck warning Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2807,9)-(2809,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2802,9)-(2804,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2777,9)-(2779,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2772,9)-(2774,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2747,9)-(2749,7) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (2742,9)-(2744,13) typecheck warning Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3391,13)-(3391,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3394,13)-(3394,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3397,13)-(3397,14) typecheck warning Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3403,21)-(3403,22) typecheck warning Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3410,13)-(3415,20) typecheck warning Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3713,1)-(3713,9) typecheck warning Incomplete pattern matches on this expression. For example, the value '{ y=0 }' may indicate a case not covered by the pattern(s). +RelaxWhitespace2.fs (3720,1)-(3720,9) typecheck warning Incomplete pattern matches on this expression. +RelaxWhitespace2.fs (3731,1)-(3731,9) typecheck warning Incomplete pattern matches on this expression. \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/IndentationWithComputationExpression01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/HashLight/IndentationWithComputationExpression01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/IndentationWithComputationExpression01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/HashLight/IndentationWithComputationExpression01.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/RangeOperator01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/HighPrecedenceApplication/RangeOperator01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/RangeOperator01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/LexicalFiltering/HighPrecedenceApplication/RangeOperator01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute01.fs new file mode 100644 index 00000000000..18e93d2a9e0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute01.fs @@ -0,0 +1,14 @@ +// #Regression #Conformance #ObjectOrientedTypes #Classes #ObjectConstructors +// Regression test for FSHARP1.0:4212 +// Attribute is placed on both the explicit and the implicit constructors +//Message2 +//Message3 +//Message2 +module M +// explicit syntax +type Foo [] (x:int) = + [] + new() = Foo(1) + +let _ = Foo() +let _ = Foo(3) diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute02.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute02.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/WithAttribute02.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/new_while_01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/new_while_01.fs new file mode 100644 index 00000000000..f9ac5061b21 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/new_while_01.fs @@ -0,0 +1,12 @@ +// #Regression #Conformance #ObjectOrientedTypes #Classes #ObjectConstructors +// Regression test for FSHARP1.0:3217 +// Use misc constructs in explicit object constructor +// construct: while ... do ... done +#light + +type T = + new () = + while true do + () + done + new T() diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/WithAttribute.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/WithAttribute.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/WithAttribute.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/WithAttribute.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx new file mode 100644 index 00000000000..182fb04be48 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx @@ -0,0 +1,11 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +//Value restriction\. The value 'x1' has been inferred to have generic type. val x1: \('_a -> unit\) .Either make the arguments to 'x1' explicit or, if you do not intend for it to be generic, add a type annotation\.$ + +// We expect a value restriction here. The inferred signature is: +// val x1: (?1 -> unit) +// Here 'x1' is not a member/function. Further, looking at the signature alone, the type inference +// variable could have feasibly be genrealized at 'x1' (c.f. the case above, where it +// was generalized). +let f1 (x:obj) = () +let x1 = ((); f1) \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01.fsx new file mode 100644 index 00000000000..52f4b7e5b69 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01.fsx @@ -0,0 +1,13 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +// + +// We expect no value restriciton here. The inferred signature is: +// type C0 = +// new : unit -> C0 +// member ToList : unit -> ?1 +// These are both members/functions, hence the value restriction is not applied to either. +// The type inference variable represents hidden state with no possible generalization point in the signature. +type C0() = + let mutable x = [] + member q.ToList() = x \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01Gen.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01Gen.fsx new file mode 100644 index 00000000000..7bc094a5bd0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction01Gen.fsx @@ -0,0 +1,13 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +// + +// We expect no value restriciton here. The inferred signature is: +// type C1<'T> = +// new : unit -> C1<'T> +// member ToList : unit -> ?1 +// These are both members/functions, hence the value restriction is not applied to either. +// The type inference variable represents hidden state with no possible generalization point in the signature. +type C1<'T>() = + let mutable x = [] + member q.ToList() = x \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02.fsx new file mode 100644 index 00000000000..e7b378265d3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02.fsx @@ -0,0 +1,13 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +// + +// We expect no value restriciton here. The inferred signature is: +// type SC0 = +// new : unit -> SC0 +// static member ToList : unit -> ?1 +// These are both members/functions, hence the value restriction is not applied to either. +// The type inference variable represents hidden state with no possible generalization point in the signature. +type SC0() = + static let mutable x = [] + static member ToList() = x \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02Gen.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02Gen.fsx new file mode 100644 index 00000000000..746d46c8697 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/MemberOrFunction02Gen.fsx @@ -0,0 +1,13 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +// + +// We expect no value restriciton here. The inferred signature is: +// type SC1<'T> = +// new : unit -> SC0 +// static member ToList : unit -> ?1 +// These are both members/functions, hence the value restriction is not applied to either. +// The type inference variable represents hidden state with no possible generalization point in the signature. +type SC1<'T>() = + static let mutable x = [] + static member ToList() = x \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeArgs01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeArgs01.fsx new file mode 100644 index 00000000000..2d8be1616b1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeArgs01.fsx @@ -0,0 +1,12 @@ +// #Regression #Conformance #ObjectOrientedTypes #Classes # ValueRestriction + +// + +// This was originally regression test for FSHARP1.0:877 - "implicit class members typars are not the typars of the enclosing class" +// After discussions on 'fsbugs' it was confirmed that the right behavior is to accept this code, i.e. 'xs' is a "obj list" + + +type 'a fifo() = class + let mutable xs = [] + member q.ToList() = xs +end diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeFunction01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeFunction01.fsx similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeFunction01.fsx rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeFunction01.fsx diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx new file mode 100644 index 00000000000..56b49d2466d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx @@ -0,0 +1,9 @@ +// #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction + +// + +// We expect no value restriction here. The inferred signature is: +// val x0: ('T -> unit) +// Here the type inference variable is generalized at 'x0'. +let f0 (x:obj) = () +let x0 = f0 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_Equals.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_Equals.fs new file mode 100644 index 00000000000..398f407add6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_Equals.fs @@ -0,0 +1,14 @@ +// #Regression #Conformance #ObjectOrientedTypes #Structs #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of Equals() + +[] +type S3 = + member this.Equals(s:char) = true + //member this.Equals(s:S3) = 1. + member this.Equals(?s:char) = true + +#if INTERACTIVE +;; +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_GetHashCode.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_GetHashCode.fs new file mode 100644 index 00000000000..aca1cc87f7b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_GetHashCode.fs @@ -0,0 +1,14 @@ +// #Regression #Conformance #ObjectOrientedTypes #Structs #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of GetHashCode() + +[] +type S2 = + member this.GetHashCode(s:char) = 1 + //member this.GetHashCode() = 1. + member this.GetHashCode(?s:char) = 1 + +#if INTERACTIVE +;; +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_ToString.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_ToString.fs new file mode 100644 index 00000000000..8a5ad46511f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/ObjectOrientedTypeDefinitions/StructTypes/Overload_ToString.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #ObjectOrientedTypes #Structs #ReqNOMT +// Regression test for FSHARP1.0:5223 +// Overloading of ToString() + +[] +type S1 = + member this.ToString(s:char) = true + member this.ToString() = true + member this.ToString(?s:char) = true + +#if INTERACTIVE +exit 0;; +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs new file mode 100644 index 00000000000..1866794890f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #PatternMatching +// Verify warning when capturing values with captial identifier +// FSB 3954 + +//Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name +//Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name + +let test x = function + | Foo :: [] -> 1 + | Bar :: _ :: [] -> 2 + | _ -> 3 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete01.fs new file mode 100644 index 00000000000..61db9b4e83c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete01.fs @@ -0,0 +1,109 @@ +// #Regression #Conformance #PatternMatching +#light + +// Regression testcase for FSharp 1.0:2070 +// Warning on incomplete match + +//Incomplete pattern matches on this expression. For example, the value 'Result \(_\)' may indicate a case not covered by the pattern\(s\) + +module M = + + type Id = string + + type Field = { + Name:string; + mutable Type:Type; + mutable Parent:TypeDecl; + IsSpec:bool; + } + + and TypeDecl = + | Struct of Id * list + | Union of Id * list + | MathType of Id + + and Type = + | Void + | Integer + | Bool + | Ptr of Type + | Ref of TypeDecl + | Array of Type * int + | TypeIdT + | Tptr + | Map of Type * Type + + + type VarKind = + | Parameter + | Local + | Global + | QuantBound + + type Variable = { + Name:Id; + Type:Type; + Kind:VarKind; + } + + type Token = { + File: string; + Line:int; + Column:int; + Remarks:string; + } + + type ExprCommon = { + Token:Token; + Type:Type; + } + + type Function = { + Token:Token; + IsSpec:bool; + RetType:Type; + Name:Id; + Parameters:list; + Requires:list; + Ensures:list; + Invariants:list; + Writes:list; + Reads:list; + } + + and Expr = + | Ref of ExprCommon * Variable + | Prim of ExprCommon * string * list + | Call of ExprCommon * Function * list + | IntLiteral of ExprCommon * string + | BoolLiteral of ExprCommon * bool + | Deref of ExprCommon * Expr + | Addr of ExprCommon * Variable + | Dot of ExprCommon * Expr * Field // computes address of the field + | Index of ExprCommon * Expr * Expr // computes address of an array element + | Cast of ExprCommon * Expr // take the type from ExprCommon + | Result of ExprCommon + | VolatileRead of ExprCommon * Expr * Expr + | Old of ExprCommon * Expr + | Macro of ExprCommon * string * list + + type Expr with + member x.Common = + match x with + | Ref (e, _) + | Prim (e, _, _) + | Call (e, _, _) + | IntLiteral (e, _) + | BoolLiteral (e, _) + | Deref (e, _) + | Addr (e, _) + | Dot (e, _, _) + | Index (e, _, _) + | Cast (e, _) + //| Result (e) + | VolatileRead (e, _, _) + | Old (e, _) + | Macro (e, _, _) + -> e + +exit 0 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete02.fs new file mode 100644 index 00000000000..32fec0c6c5d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/PatternMatching/Simple/W_Incomplete02.fs @@ -0,0 +1,35 @@ +// #Regression #Conformance #PatternMatching +// Regression test for FSharp1.0:4920 +// Title: Can't have a quotation with an incomplete pattern match +// Regression test for FSharp1.0:4904 +// Title: Incomplete pattern in quotation causes error. +// Descr: Make sure quotations compile (even with warning) when having incomplete pattern match inside + +//Incomplete pattern matches on this expression\. +//Incomplete pattern matches on this expression\. +//This rule will never be matched +//This rule will never be matched +let foo x = + <@@ + match x with + | 1 -> 1 + | 2 -> 2 + @@> + +let g = + <@ + let f ( int : int ) = function + | 1 -> 0 + | 2 -> 1 + f + @> + +let h = + <@@ + match 10 with + | x -> x + | 1 -> 20 + | 10 -> 10 + @@> + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethod2.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethod2.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethod2.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethod2.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethods1.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethods1.fs new file mode 100644 index 00000000000..08febca56c1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_CannotInlineVirtualMethods1.fs @@ -0,0 +1,12 @@ +// #inline #FSharpQA #Conformance #TypeConstraints +//This member, function or value declaration may not be declared 'inline' +//This member, function or value declaration may not be declared 'inline' + +[] +type Bad10 = + abstract inline X : int + + +[] +type Bad11 = + abstract inline X : int -> int \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullLiteral_NetRef.fsx b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullLiteral_NetRef.fsx similarity index 100% rename from tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullLiteral_NetRef.fsx rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullLiteral_NetRef.fsx diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Calculus.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Calculus.fs new file mode 100644 index 00000000000..0263135fc55 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Calculus.fs @@ -0,0 +1,31 @@ +// #Conformance #UnitsOfMeasure +#light + +let diff (h:float<_>) (f :_ -> float<_>) = fun x -> (f (x+h) - f (x-h)) / (2.0*h) + +let integrate (f:float<_> -> float<_>) (a:float<_>) (b:float<_>) n = + let h = (b-a) / (float n) + let rec iter x i = + if i=0 then 0.0<_> + else f x + iter (x+h) (i-1) + h * (f a / 2.0 + iter (a+h) (n-1) + f b / 2.0) + +let rec newton (f:float<_> -> float<_>) f' x xacc = + let dx = f x / f' x + let x' = x - dx + if abs dx / x' < xacc + then x' + else newton f f' x' xacc + +// Non-regular datatype: a list of derivatives of a function +type derivs<[] 'u, [] 'v> = + Nil +| Cons of (float<'u> -> float<'v>) * derivs<'u,'v/'u> + +// Essential use of polymorphic recursion! +// Given a step h, function f, and integer n, compute a list of n derivatives +// [f; f'; f''; ...] +// where f is the function itself, f' is the first derivative, f'' is the second, etc. + +let rec makeDerivs<[] 'u, [] 'v> (h:float<'u>, f:float<'u> -> float<'v>, n:int) : derivs<'u,'v> = + if n=0 then Nil else Cons(f, makeDerivs(h, diff h f, n-1)) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc01.fs new file mode 100644 index 00000000000..a48edb12d9d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc01.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #UnitsOfMeasure +// Regression test for FSHARP1.0:2869 +#light + +// Polymorphic recursion +let rec prodlists<[] 'u,[] 'v>(xs:float<'u> list,ys:float<'v> list) : float<'u 'v> list = + match xs,ys with + | x::xs,y::ys -> x*y :: prodlists<'v,'u>(ys,xs) + | _ -> [] diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc03.fs new file mode 100644 index 00000000000..4f6b5a4429b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Misc03.fs @@ -0,0 +1,25 @@ +// #Conformance #UnitsOfMeasure +let recip1 x = 1.0/x +let recip2 (x:float<_>) = 1.0/x + +let zero1 = 0.0 +let zero2 = 0.0<_> + +let halvelist0 xs = List.map ( (/) 2.0 : float -> float ) xs +let halvelist1 xs = List.map ( (/) 2.0 : float<_> -> float<_> ) xs +let halvelist2 (xs:float<_> list) = List.map ( (/) 2.0) xs +let halvelist3 xs = List.map ( (/) 2.0) xs + +let pr x y = printf "%f %s" x y +let pr2 (x:float<_>) = printf "%f" x + +// From thesis +let abs x = if x < 0.0<_> then 0.0<_> - x else x +let sqr (x:float<_>) = x*x +let cube x = x*sqr x +let powers x y z = sqr x + cube y + sqr z * cube z + +// Now let's test some explicit types +let sqr2< [] 'u>(x:float<'u>) = x*x +let cube2<[] 'v>(x) = sqr2<'v> x * x +let rec reccube1(x) = if x < 0.0<_> then x else - reccube1(x) diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/Quotation04_hidden.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Quotation04_hidden.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/Quotation04_hidden.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Quotation04_hidden.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/RationalExponents01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/RationalExponents01.fs new file mode 100644 index 00000000000..79c649e564e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/RationalExponents01.fs @@ -0,0 +1,35 @@ +// #Conformance #UnitsOfMeasure +// Rational exponents feature + +[] +type kg + +[] +type s + +[] +type m + +// Simple fractions +let test01() = 1.0 +let test02() = 2.0 +let test03() = sqrt (test01()) + test02() + +// Negative fractions +let test04() = 4.0 +let test05() = 5.0 +let test06() = 1.0 / (test04() * test05()) + 3.0 + +// More complex expressions +let test07() = 2.0 +let test08() = 4.0<(s^6 kg^3)^(1/4)> +let test09() = test07() * test08() + 3.0 + +// Generics +let test10(x:float<'u>) (y:float<'u^(1/2)>) = sqrt x + y +let test11(x:float<'u^-(1/4)>) (y:float<'u^(3/4)>) : float = (x*x*x + 1.0/y) * x +let test12(x:float<'u^(1/2)>) (y:float<'v^2>) :float<'u 'v> = x*x*sqrt y +let test13() = test12 4.0 2.0 + 3.0<(kg s)^(1/2)> + +exit 0 + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/SI.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/SI.fs new file mode 100644 index 00000000000..582f849d974 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/SI.fs @@ -0,0 +1,32 @@ +// #Conformance #UnitsOfMeasure +#light + +[] type kg // kilogram +[] type m // metre +[] type s // second +[] type A // ampere +[] type mol // mole +[] type K // kelvin +[] type cd // candela + +[] type rad = m/m // radian +[] type sr = m^2/m^2 // steradian +[] type Hz = s^-1 // hertz +[] type N = kg m / s^2 // newton +[] type Pa = N / m^2 // pascal +[] type J = N m // joule +[] type W = J / s // watt +[] type C = s A // coulomb +[] type V = W/A // watt +[] type F = C/V // farad +[] type ohm = V/A // ohm +[] type S = A/V // siemens +[] type Wb = V s // weber +[] type T = Wb/m^2 // tesla +[] type H = Wb/A // henry +[] type lm = cd sr // lumen +[] type lx = lm/m^2 // lux +[] type Bq = s^-1 // becquerel +[] type Gy = J/kg // gray +[] type Sv = J/kg // sievert +[] type kat = mol/s // katal diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Stats.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Stats.fs new file mode 100644 index 00000000000..8bdb04c9dc1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Basic/Stats.fs @@ -0,0 +1,32 @@ +// #Conformance #UnitsOfMeasure +#light + +let rec sum xs = match xs with [] -> 0.0<_> | (x::xs) -> x + sum xs + +let rec sumMap f xs = match xs with [] -> 0.0<_> | (x::xs) -> f x + sumMap f xs +let rec sumMap2 f xs ys = match xs,ys with (x::xs,y::ys) -> f x y + sumMap2 f xs ys | _ -> 0.0<_> + +let mean xs = sum xs / float (List.length xs) + +let meanMap f xs = sumMap f xs / float (List.length xs) + +let sqr (x:float<_>) = x*x + +let cube x = x*sqr x + +let variance xs = let m = mean xs in meanMap (fun x -> sqr (x-m)) xs +let sdeviation xs = sqrt (variance xs) + +let skewness xs = + let n = float (List.length xs) + let m = mean xs + let s = sdeviation xs + meanMap (fun x -> cube(x-m)) xs / (cube s) + +let covariance xs ys = + let m = mean xs + let n = mean ys + sumMap2 (fun x y -> (x-m)*(y-n)) xs ys / (float n) + +let correlation xs ys = + covariance xs ys / (mean xs * mean ys) diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/RangeExpression01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Diagnostics/RangeExpression01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/RangeExpression01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Diagnostics/RangeExpression01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/GreaterBarRBrack01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/GreaterBarRBrack01.fs new file mode 100644 index 00000000000..60114b4c66c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/GreaterBarRBrack01.fs @@ -0,0 +1,18 @@ +// #Regression #Conformance #UnitsOfMeasure +// Regression test for FSHARP1.0:2791 +// Make sure we can parse arrays of dimensioned numbers without needing a a space between > and |] +// +#light + +[] +type m + +let l1 = [|10.0|] // ok +let l2 = [|10.0 |] // ok + +// This was not really specific to Units of Measure, we while we are here +// we check that care too. +let p1 = [|Array.empty|] // ok +let p2 = [|Array.empty |] // ok + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/PowerSynonym.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/PowerSynonym.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/PowerSynonym.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/PowerSynonym.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Quotient.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Quotient.fs new file mode 100644 index 00000000000..4c8458ed935 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Quotient.fs @@ -0,0 +1,19 @@ +// #Regression #Conformance #UnitsOfMeasure +// Regression test for FSHARP1.0:6157 - Units of measure containing "/" get rejected in arguments to method invocation + +[] type m +[] type s + +let sqr<[] 'u>(x:float<'u>) = x*x + +type T() = + member this.sqr<[] 'u>(x:float<'u>) = x*x + + +let t = new T() +let a = sqr(5.0) +let b = sqr(2.0) +let c = sqr(3.0) +let d = t.sqr(5.0) +let e = t.sqr(2.0) +let f = t.sqr(3.0) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/QuotientAssoc.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/QuotientAssoc.fs new file mode 100644 index 00000000000..fe3aecf7e94 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/QuotientAssoc.fs @@ -0,0 +1,24 @@ +// #Regression #Conformance #UnitsOfMeasure +// Regression test for FSHARP1.0:4124 - Units of measure: division should be left-associative in both types and constants +// Regression test for FSHARP1.0:4188 - Type parameters for units of measure parsed inconsistently. + +#light + +[] type s +[] type m +[] type A = m / s / s +[] type AA = m / s^2 +[] type B = m^2 / m s / s^2 / s^-1 +[] type B' = m / s / s / s / s / s / s / s / s^-5 +[] type C = m / s * s / s * s / s / s + +let (x : float) = 1.0 +let y = 2.0 +let z = x+y +let a = 1.0 +let aa = 2.0 +let (b : float) = 3.0 +let b' = 4.0 +let (c : float) = 5.0 + +let res = a + aa + b + b' + c diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Reciprocal01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Reciprocal01.fs new file mode 100644 index 00000000000..dcac1cb1c50 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/Parsing/Reciprocal01.fs @@ -0,0 +1,17 @@ +// #Regression #Conformance #UnitsOfMeasure +// Regression test for FSHARP1.0:2748 +// Units or measures: we should not require a space between < and \ when using a reciprocal of a unit + +// Regression test for FSHARP1.0:4195 +// Reciprocals parsed incorrectly for Measure definitions. + +#light + +[] type s // [] type s +[] type s' = / s / s // [] type s' = /s ^ 2 +let oneHertz = 1.0 // OK +let twoHertz = 2.0f< /s> // OK + +if (1.0 + 2.0 <> 3.0) then exit 1 + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/GenericSubType01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/TypeChecker/GenericSubType01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/GenericSubType01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Conformance/UnitsOfMeasure/TypeChecker/GenericSubType01.fs diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_Keyword_tailcall01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/General/W_Keyword_tailcall01.fs similarity index 100% rename from tests/fsharpqa/Source/Diagnostics/General/W_Keyword_tailcall01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/General/W_Keyword_tailcall01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/LetBangNonAsync.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/LetBangNonAsync.fs new file mode 100644 index 00000000000..61977d09ccb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/LetBangNonAsync.fs @@ -0,0 +1,4 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'Async<'a>' .but here has type. 'int' +async { let! x = 1 in return 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop01.fs new file mode 100644 index 00000000000..4a76753f582 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop01.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the ! for a loop +//Type mismatch\. Expecting a.+''a'.+but given a.+'Async<'a>'.*The types ''a' and 'Async<'a>' cannot be unified. +let rec loop() = async { let x = 1 + return loop() + } diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop02.fs new file mode 100644 index 00000000000..ad5f28403ea --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingBangForLoop02.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the ! for a loop +// Note: Desugared form of MissingBangForLoop01.fs +//Type mismatch\. Expecting a. ''a' .but given a. 'Async<'a>' .The types ''a' and 'Async<'a>' cannot be unified. + +let rec loop2() = async.Delay(fun () -> async.Return(loop2())) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingIgnore.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingIgnore.fs new file mode 100644 index 00000000000..85381cea43e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingIgnore.fs @@ -0,0 +1,5 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//The result of this expression has type 'int' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +async { 1; + return 2 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop01.fs new file mode 100644 index 00000000000..22ebb43bd2a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop01.fs @@ -0,0 +1,5 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the return! For a loop +//The result of this expression has type 'Async<'a>' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +let rec loop() = async { let x = 1 in loop() } diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop02.fs new file mode 100644 index 00000000000..a7c5b2b1468 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop02.fs @@ -0,0 +1,5 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the return! For a loop +//The result of this expression has type 'Async<'a>' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +let rec loop() = async { loop() } diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop03.fs new file mode 100644 index 00000000000..277028e9bbf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop03.fs @@ -0,0 +1,6 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the return! For a loop +//The result of this expression has type 'Async<'a>' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +//This expression was expected to have type. 'Async<'a>' .but here has type. 'unit' +let rec loop2() = async.Delay(fun () -> loop2(); ()); diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop04.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop04.fs new file mode 100644 index 00000000000..761020c2ec1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/MissingReturnBangForLoop04.fs @@ -0,0 +1,8 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// common mistake: forgetting the return! For a loop +//The result of this expression has type 'Async<'a>' and is implicitly ignored\. Consider using 'ignore' to discard this value explicitly, e\.g\. 'expr \|> ignore', or 'let' to bind the result to a name, e\.g\. 'let result = expr'.$ +//This expression was expected to have type. 'Async<'a>' .but here has type. 'unit' +// Note: interestingly, this looks much better if a method call is not used +let delay x = async.Delay x +let rec loop3() = delay(fun () -> loop3(); ()); diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync01.fs new file mode 100644 index 00000000000..6abb635fd0d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync01.fs @@ -0,0 +1,4 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'Async<'a>' .but here has type. 'int' +async { return! 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync02.fs new file mode 100644 index 00000000000..1c16b389e2e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync02.fs @@ -0,0 +1,5 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'Async<'a>' .but here has type. 'int' +async { let x = 1 + return! 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_For.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_For.fs new file mode 100644 index 00000000000..04307c671ec --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_For.fs @@ -0,0 +1,5 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'unit' .but here has type. 'int' +async { for x in [1;2] do + return 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs new file mode 100644 index 00000000000..ecc1175241d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//All branches of an 'if' expression must return values implicitly convertible to the type of the first branch +async { if true then + return () + else + return 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryFinally.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryFinally.fs new file mode 100644 index 00000000000..c3e5c3541bc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryFinally.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'unit' .but here has type. 'int' +async { try + return 1 + finally + 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryWith.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryWith.fs new file mode 100644 index 00000000000..29c6d8729b0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_TryWith.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'int' .but here has type. 'unit' +async { try + return 1 + with _ -> + return () } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_While.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_While.fs new file mode 100644 index 00000000000..8cdda726f3e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/ReturnBangNonAsync_While.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +//This expression was expected to have type. 'Async' .but here has type. 'int' +async { while true do + let x = 1 + return! 1 } |> ignore + diff --git a/tests/fsharpqa/Source/Diagnostics/async/UseBindingWrongForm01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UseBindingWrongForm01.fs similarity index 100% rename from tests/fsharpqa/Source/Diagnostics/async/UseBindingWrongForm01.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UseBindingWrongForm01.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInAWhileLoop.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInAWhileLoop.fs new file mode 100644 index 00000000000..5b69d8c6d49 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInAWhileLoop.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// less common mistake: using "return" in a while loop +//This expression was expected to have type. 'unit' .but here has type. 'int' + +async { while true do + return 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInIfThenElse.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInIfThenElse.fs new file mode 100644 index 00000000000..52a2932b003 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/Diagnostics/async/UsingReturnInIfThenElse.fs @@ -0,0 +1,7 @@ +// #Regression #Diagnostics #Async +// Regression tests for FSHARP1.0:4394 +// less common mistake: using "return" in an if/then/else +//Type mismatch\. Expecting a. 'Async' .but given a. 'Async' .The type 'int' does not match the type 'unit'$ +// +async { if true then + return 1 } |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/InteractiveSession/Misc/lib.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/InteractiveSession/Misc/lib.fs new file mode 100644 index 00000000000..b73bc61fb99 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/InteractiveSession/Misc/lib.fs @@ -0,0 +1,2 @@ +module Lib +let X () = 42 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/E_IndentOff01.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/E_IndentOff01.fs new file mode 100644 index 00000000000..b30973aa948 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/E_IndentOff01.fs @@ -0,0 +1,5 @@ +// #Regression #OCaml +// Regression test for FSHARP1.0:5984 +//This construct is for ML compatibility\. Consider using a file with extension '\.ml' or '\.mli' instead\. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'\.$ +#indent "off" +exit 0 diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/IndentOff02.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/IndentOff02.fs new file mode 100644 index 00000000000..6b09cde831c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/IndentOff02.fs @@ -0,0 +1,5 @@ +// #Regression #OCaml +// Regression test for FSHARP1.0:5984 +// +#indent "off" +exit 0 diff --git a/tests/fsharpqa/Source/OCamlCompat/W_IndentOff03.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/W_IndentOff03.fs similarity index 100% rename from tests/fsharpqa/Source/OCamlCompat/W_IndentOff03.fs rename to tests/FSharp.Compiler.ComponentTests/resources/tests/OCamlCompat/W_IndentOff03.fs diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs new file mode 100644 index 00000000000..1097b688029 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs @@ -0,0 +1,11 @@ +// #NoMono #NoMT #CodeGen #EmittedIL +// Validate we emit non-generic (=fast) code for comparison involving decimals +// See DevDiv:217807 (1.0M < 2.0M should be fast, not go through generic comparison code path) +let _ = 1.0M < 2.0M +let _ = 1.0M <= 2.0M +let _ = 1.0M > 2.0M +let _ = 1.0M >= 2.0M +let _ = 1.0M = 2.0M +let _ = 1.0M <> 2.0M +let _ = 1.0M = 2.0M +let _ = compare 1.0M 2.0M diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs.il b/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs.il new file mode 100644 index 00000000000..edf711ad4b6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/codegen/operators/decimal_comparison.fs.il @@ -0,0 +1,189 @@ + .maxstack 8 + IL_0000: ldc.i4.s 10 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.0 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.1 + IL_0006: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_000b: ldc.i4.s 20 + IL_000d: ldc.i4.0 + IL_000e: ldc.i4.0 + IL_000f: ldc.i4.0 + IL_0010: ldc.i4.1 + IL_0011: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0016: call bool [netstandard]System.Decimal::op_LessThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_001b: pop + IL_001c: ldc.i4.s 10 + IL_001e: ldc.i4.0 + IL_001f: ldc.i4.0 + IL_0020: ldc.i4.0 + IL_0021: ldc.i4.1 + IL_0022: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0027: ldc.i4.s 20 + IL_0029: ldc.i4.0 + IL_002a: ldc.i4.0 + IL_002b: ldc.i4.0 + IL_002c: ldc.i4.1 + IL_002d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0032: call bool [netstandard]System.Decimal::op_LessThanOrEqual(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_0037: pop + IL_0038: ldc.i4.s 10 + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.0 + IL_003c: ldc.i4.0 + IL_003d: ldc.i4.1 + IL_003e: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0043: ldc.i4.s 20 + IL_0045: ldc.i4.0 + IL_0046: ldc.i4.0 + IL_0047: ldc.i4.0 + IL_0048: ldc.i4.1 + IL_0049: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_004e: call bool [netstandard]System.Decimal::op_GreaterThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_0053: pop + IL_0054: ldc.i4.s 10 + IL_0056: ldc.i4.0 + IL_0057: ldc.i4.0 + IL_0058: ldc.i4.0 + IL_0059: ldc.i4.1 + IL_005a: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_005f: ldc.i4.s 20 + IL_0061: ldc.i4.0 + IL_0062: ldc.i4.0 + IL_0063: ldc.i4.0 + IL_0064: ldc.i4.1 + IL_0065: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_006a: call bool [netstandard]System.Decimal::op_GreaterThanOrEqual(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_006f: pop + IL_0070: ldc.i4.s 10 + IL_0072: ldc.i4.0 + IL_0073: ldc.i4.0 + IL_0074: ldc.i4.0 + IL_0075: ldc.i4.1 + IL_0076: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_007b: ldc.i4.s 20 + IL_007d: ldc.i4.0 + IL_007e: ldc.i4.0 + IL_007f: ldc.i4.0 + IL_0080: ldc.i4.1 + IL_0081: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0086: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_008b: pop + IL_008c: ldc.i4.s 10 + IL_008e: ldc.i4.0 + IL_008f: ldc.i4.0 + IL_0090: ldc.i4.0 + IL_0091: ldc.i4.1 + IL_0092: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0097: ldc.i4.s 20 + IL_0099: ldc.i4.0 + IL_009a: ldc.i4.0 + IL_009b: ldc.i4.0 + IL_009c: ldc.i4.1 + IL_009d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00a2: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_00a7: ldc.i4.0 + IL_00a8: ceq + IL_00aa: pop + IL_00ab: ldc.i4.s 10 + IL_00ad: ldc.i4.0 + IL_00ae: ldc.i4.0 + IL_00af: ldc.i4.0 + IL_00b0: ldc.i4.1 + IL_00b1: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00b6: ldc.i4.s 20 + IL_00b8: ldc.i4.0 + IL_00b9: ldc.i4.0 + IL_00ba: ldc.i4.0 + IL_00bb: ldc.i4.1 + IL_00bc: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00c1: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_00c6: pop + IL_00c7: ldc.i4.s 10 + IL_00c9: ldc.i4.0 + IL_00ca: ldc.i4.0 + IL_00cb: ldc.i4.0 + IL_00cc: ldc.i4.1 + IL_00cd: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00d2: ldc.i4.s 20 + IL_00d4: ldc.i4.0 + IL_00d5: ldc.i4.0 + IL_00d6: ldc.i4.0 + IL_00d7: ldc.i4.1 + IL_00d8: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00dd: call int32 [netstandard]System.Decimal::Compare(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_00e2: pop + IL_00e3: ret + diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs new file mode 100644 index 00000000000..02be510295d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs @@ -0,0 +1,7 @@ +type ImmutableStack<'a> private(items: 'a list) = + + member this.Push item = ImmutableStack(item::items) + member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs) + + // Notice type annotation is commented out, which results in an error + new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col) diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs.bsl b/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs.bsl new file mode 100644 index 00000000000..6d456b36851 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/typecheck/constructors/neg_invalid_constructor.fs.bsl @@ -0,0 +1,22 @@ +neg_invalid_constructor.fs (3,29)-(3,56) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new: col: 'b -> ImmutableStack<'a> + - private new: items: 'a list -> ImmutableStack<'a> +neg_invalid_constructor.fs (4,93)-(4,111) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new: col: 'b -> ImmutableStack<'a> + - private new: items: 'a list -> ImmutableStack<'a> +neg_invalid_constructor.fs (7,30)-(7,60) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new: col: 'b -> ImmutableStack<'a> when 'b :> seq<'c> + - private new: items: 'a list -> ImmutableStack<'a> +neg_invalid_constructor.fs (7,30)-(7,60) typecheck error This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/xunit.runner.json b/tests/FSharp.Compiler.ComponentTests/xunit.runner.json new file mode 100644 index 00000000000..e53c283f137 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/xunit.runner.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "appDomain": "denied", + "shadowCopy": false, + "parallelizeTestCollections": false, + "maxParallelThreads": 1 +} diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/DiagnosticsTests.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/DiagnosticsTests.fs deleted file mode 100644 index aaadff258e9..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/DiagnosticsTests.fs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System -open System.IO -open System.Linq -open System.Threading.Tasks -open FSharp.Compiler.LanguageServer -open Nerdbank.Streams -open NUnit.Framework - -[] -type DiagnosticsTests() = - - let createTestableProject (tfm: string) (sourceFiles: (string * string) list) = - let testDir = new TemporaryDirectory() - let directoryBuildText = "" - File.WriteAllText(Path.Combine(testDir.Directory, "Directory.Build.props"), directoryBuildText) - File.WriteAllText(Path.Combine(testDir.Directory, "Directory.Build.targets"), directoryBuildText) - for name, contents in sourceFiles do - File.WriteAllText(Path.Combine(testDir.Directory, name), contents) - let compileItems = - sourceFiles - |> List.map fst - |> List.map (sprintf " ") - |> List.fold (fun content line -> content + "\n" + line) "" - let replacements = - [ "{{COMPILE}}", compileItems - "{{TARGETFRAMEWORK}}", tfm ] - let projectTemplate = - @" - - - Library - {{TARGETFRAMEWORK}} - - -{{COMPILE}} - -" - let projectFile = - replacements - |> List.fold (fun (content: string) (find, replace) -> content.Replace(find, replace)) projectTemplate - File.WriteAllText(Path.Combine(testDir.Directory, "test.fsproj"), projectFile) - testDir - - let createRpcClient (tempDir: TemporaryDirectory) = - let clientStream, serverStream = FullDuplexStream.CreatePair().ToTuple() - let server = new Server(serverStream, serverStream) - server.StartListening() - let client = new TestClient(tempDir, clientStream, clientStream, server) - client - - let createClientTest (tfm: string) (sourceFiles: (string * string) list) = - let testDir = createTestableProject tfm sourceFiles - let client = createRpcClient testDir - client - - let getDiagnostics (content: string) = - async { - use client = createClientTest "netstandard2.0" [ "lib.fs", content ] - let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"] - return diagnostics.["lib.fs"] - } - - [] - member __.``No diagnostics for correct code``() = - async { - let! diagnostics = getDiagnostics @" -namespace Test - -module Numbers = - let one: int = 1 -" - Assert.AreEqual(0, diagnostics.Length) - } |> Async.StartAsTask :> Task - - [] - member __.``Diagnostics for incorrect code``() = - async { - let! diagnostics = getDiagnostics @" -namespace Test - -module Numbers = - let one: int = false -" - let diag = diagnostics.Single() - Assert.AreEqual("FS0001", diag.code) - Assert.AreEqual(Some 1, diag.severity) - Assert.AreEqual(4, diag.range.start.line) - Assert.AreEqual(19, diag.range.start.character) - Assert.AreEqual(4, diag.range.``end``.line) - Assert.AreEqual(24, diag.range.``end``.character) - Assert.AreEqual("This expression was expected to have type\n 'int' \nbut here has type\n 'bool'", diag.message.Trim()) - Assert.IsTrue(diag.source.Value.EndsWith("lib.fs")) - } |> Async.StartAsTask :> Task - - [] - member __.``Diagnostics added for updated incorrect code``() = - async { - let correct = @" -namespace Test - -module Numbers = - let one: int = 1 -" - let incorrect = @" -namespace Test - -module Numbers = - let one: int = false -" - - // verify initial state - use client = createClientTest "netstandard2.0" [ "lib.fs", correct ] - let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"] - Assert.AreEqual(0, diagnostics.["lib.fs"].Length) - - // touch file with incorrect data - let touch () = File.WriteAllText(Path.Combine(client.RootPath, "lib.fs"), incorrect) - let! diagnostics = client.WaitForDiagnostics touch ["lib.fs"] - let diag = diagnostics.["lib.fs"].Single() - Assert.AreEqual("FS0001", diag.code) - } |> Async.StartAsTask :> Task - - [] - member __.``Diagnostics removed for updated correct code``() = - async { - let incorrect = @" -namespace Test - -module Numbers = - let one: int = false -" - let correct = @" -namespace Test - -module Numbers = - let one: int = 1 -" - - // verify initial state - use client = createClientTest "netstandard2.0" [ "lib.fs", incorrect ] - let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"] - let diag = diagnostics.["lib.fs"].Single() - Assert.AreEqual("FS0001", diag.code) - - // touch file with correct data - let touch () = File.WriteAllText(Path.Combine(client.RootPath, "lib.fs"), correct) - let! diagnostics = client.WaitForDiagnostics touch ["lib.fs"] - let libActualContents = File.ReadAllText(Path.Combine(client.RootPath, "lib.fs")) - Assert.AreEqual(0, diagnostics.["lib.fs"].Length, "Actual on-disk contents of lib.fs:\n" + libActualContents) - } |> Async.StartAsTask :> Task diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/Directory.Build.props b/tests/FSharp.Compiler.LanguageServer.UnitTests/Directory.Build.props deleted file mode 100644 index 7cd41381b5d..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - true - - - - - diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj b/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj deleted file mode 100644 index 4e061f5575a..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - net472;netcoreapp3.0 - netcoreapp3.0 - Library - true - nunit - true - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/MiscTests.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/MiscTests.fs deleted file mode 100644 index 02104be2e69..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/MiscTests.fs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System.IO -open FSharp.Compiler.LanguageServer -open NUnit.Framework - -[] -type MiscTests() = - - [] - member __.``Find F# projects in a .sln file``() = - let slnContent = @" -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29201.188 -MinimumVisualStudioVersion = 10.0.40219.1 -Project(""{F2A71F9B-5D33-465A-A702-920D77279786}"") = ""ConsoleApp1"", ""ConsoleApp1\ConsoleApp1.fsproj"", ""{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}"" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {80902CFC-54E6-4485-AC17-4516930C8B2B} - EndGlobalSection -EndGlobal -" - let testDir = @"C:\Dir\With\Solution" // don't care about the potentially improper directory separators here, it's really just a dumb string - let foundProjects = Solution.getProjectPaths slnContent testDir - let expected = Path.Combine(testDir, "ConsoleApp1", "ConsoleApp1.fsproj") // proper directory separator characters will be used at runtime - Assert.AreEqual([| expected |], foundProjects) diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/ProtocolTests.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/ProtocolTests.fs deleted file mode 100644 index 8b262e2ceb2..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/ProtocolTests.fs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System.Diagnostics -open System.Threading.Tasks -open FSharp.Compiler.LanguageServer -open NUnit.Framework -open StreamJsonRpc - -[] -type ProtocolTests() = - -#if !NETCOREAPP - // The `netcoreapp` version of `FSharp.Compiler.LanguageServer.exe` can't be run without a `publish` step so - // we're artificially restricting this test to the full framework. - [] -#endif - member __.``Server consuming stdin and stdout``() = - async { - // start server as a console app - let serverAssemblyPath = typeof.Assembly.Location - let startInfo = ProcessStartInfo(serverAssemblyPath) - startInfo.UseShellExecute <- false - startInfo.RedirectStandardInput <- true - startInfo.RedirectStandardOutput <- true - let proc = Process.Start(startInfo) - - // create a fake client over stdin/stdout - let client = new JsonRpc(proc.StandardInput.BaseStream, proc.StandardOutput.BaseStream) - client.StartListening() - - // initialize - let capabilities: ClientCapabilities = - { workspace = None - textDocument = None - experimental = None - supportsVisualStudioExtensions = None } - let! result = - client.InvokeWithParameterObjectAsync( - "initialize", - {| processId = Process.GetCurrentProcess().Id - capabilities = capabilities |} - ) |> Async.AwaitTask - Assert.True(result.capabilities.hoverProvider) - do! client.NotifyAsync("initialized") |> Async.AwaitTask - - // shutdown - let! shutdownResponse = client.InvokeAsync("shutdown") |> Async.AwaitTask - Assert.IsNull(shutdownResponse) - - // exit - do! client.NotifyAsync("exit") |> Async.AwaitTask - if not (proc.WaitForExit(5000)) then failwith "Expected server process to exit." - } |> Async.StartAsTask :> Task diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/SerializationTests.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/SerializationTests.fs deleted file mode 100644 index 5d8457c4e5d..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/SerializationTests.fs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System -open FSharp.Compiler.LanguageServer -open NUnit.Framework -open Newtonsoft.Json - -[] -type SerializationTests() = - - let verifyRoundTrip (str: string) (typ: Type) = - let deserialized = JsonConvert.DeserializeObject(str, typ) - let roundTripped = JsonConvert.SerializeObject(deserialized) - Assert.AreEqual(str, roundTripped) - - let verifyRoundTripWithConverter (str: string) (typ: Type) (converter: JsonConverter) = - let deserialized = JsonConvert.DeserializeObject(str, typ, converter) - let roundTripped = JsonConvert.SerializeObject(deserialized, converter) - Assert.AreEqual(str, roundTripped) - - [] - member __.``Discriminated union as lower-case string``() = - verifyRoundTrip "\"plaintext\"" typeof - verifyRoundTrip "\"markdown\"" typeof - - [] - member __.``Option<'T> as obj/null``() = - verifyRoundTripWithConverter "1" typeof> (JsonOptionConverter()) - verifyRoundTripWithConverter "null" typeof> (JsonOptionConverter()) - verifyRoundTripWithConverter "{\"contents\":{\"kind\":\"plaintext\",\"value\":\"v\"},\"range\":{\"start\":{\"line\":1,\"character\":2},\"end\":{\"line\":3,\"character\":4}}}" typeof> (JsonOptionConverter()) - verifyRoundTripWithConverter "null" typeof> (JsonOptionConverter()) diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/TemporaryDirectory.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/TemporaryDirectory.fs deleted file mode 100644 index ef3953d7816..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/TemporaryDirectory.fs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System -open System.IO - -type TemporaryDirectory() = - - let directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()) - do Directory.CreateDirectory(directory) |> ignore - - member __.Directory = directory - - interface IDisposable with - member __.Dispose() = - try - Directory.Delete(directory, true) - with - | _ -> () diff --git a/tests/FSharp.Compiler.LanguageServer.UnitTests/TestClient.fs b/tests/FSharp.Compiler.LanguageServer.UnitTests/TestClient.fs deleted file mode 100644 index 0baaaf40ebd..00000000000 --- a/tests/FSharp.Compiler.LanguageServer.UnitTests/TestClient.fs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.LanguageServer.UnitTests - -open System -open System.Collections.Generic -open System.Diagnostics -open System.IO -open System.Threading -open FSharp.Compiler.LanguageServer -open Newtonsoft.Json.Linq -open StreamJsonRpc - -type TestClient(tempDir: TemporaryDirectory, sendingStream: Stream, receivingStream: Stream, server: Server) = - - let rootPath = tempDir.Directory - let rootPath = if rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) then rootPath else rootPath + Path.DirectorySeparatorChar.ToString() - let diagnosticsEvent = Event<_>() - - let formatter = JsonMessageFormatter() - let converter = JsonOptionConverter() // special handler to convert between `Option<'T>` and `obj/null`. - do formatter.JsonSerializer.Converters.Add(converter) - let handler = new HeaderDelimitedMessageHandler(sendingStream, receivingStream, formatter) - let client = new JsonRpc(handler) - let handler (functionName: string) (args: JToken): JToken = - match functionName with - | TextDocumentPublishDiagnostics -> - let args = args.ToObject(formatter.JsonSerializer) - let fullPath = Uri(args.uri).LocalPath - let shortPath = if fullPath.StartsWith(rootPath) then fullPath.Substring(rootPath.Length) else fullPath - diagnosticsEvent.Trigger((shortPath, args.diagnostics)) - null - | _ -> null - let addHandler (name: string) = - client.AddLocalRpcMethod(name, new Func(handler name)) - do addHandler TextDocumentPublishDiagnostics - do client.StartListening() - - member __.RootPath = rootPath - - member __.Server = server - - [] - member __.PublishDiagnostics = diagnosticsEvent.Publish - - member __.Initialize () = - async { - do! client.NotifyWithParameterObjectAsync(OptionsSet, {| options = Options.AllOn() |}) |> Async.AwaitTask - let capabilities: ClientCapabilities = - { workspace = None - textDocument = None - experimental = None - supportsVisualStudioExtensions = None } - let! _result = - client.InvokeWithParameterObjectAsync( - "initialize", // method - {| processId = Process.GetCurrentProcess().Id - rootPath = rootPath - capabilities = capabilities |} - ) |> Async.AwaitTask - return () - } - - member this.WaitForDiagnostics (triggerAction: unit -> unit) (fileNames: string list) = - async { - // prepare file diagnostic triggers - let diagnosticTriggers = Dictionary() - fileNames |> List.iter (fun f -> diagnosticTriggers.[f] <- new ManualResetEvent(false)) - - // prepare callback handler - let diagnosticsMap = Dictionary() - let handler (fileName: string, diagnostics: Diagnostic[]) = - diagnosticsMap.[fileName] <- diagnostics - // auto-generated files (e.g., AssemblyInfo.fs) won't be in the trigger map - if diagnosticTriggers.ContainsKey(fileName) then - diagnosticTriggers.[fileName].Set() |> ignore - - // subscribe to the event - let wrappedHandler = new Handler(fun _sender args -> handler args) - this.PublishDiagnostics.AddHandler(wrappedHandler) - triggerAction () - - // wait for all triggers to hit - let! results = - diagnosticTriggers - |> Seq.map (fun entry -> - async { - let! result = Async.AwaitWaitHandle(entry.Value, millisecondsTimeout = int (TimeSpan.FromSeconds(10.0).TotalMilliseconds)) - return if result then None - else - let filePath = Path.Combine(rootPath, entry.Key) - let actualContents = File.ReadAllText(filePath) - Some <| sprintf "No diagnostics received for file '%s'. Contents:\n%s\n" entry.Key actualContents - }) - |> Async.Parallel - let results = results |> Array.choose (fun x -> x) - if results.Length > 0 then - let combinedErrors = String.Join("-----\n", results) - let allDiagnosticsEvents = - diagnosticsMap - |> Seq.map (fun entry -> - sprintf "File '%s' reported %d diagnostics." entry.Key entry.Value.Length) - |> (fun s -> String.Join("\n", s)) - failwith <| sprintf "Error waiting for diagnostics:\n%s\n-----\n%s" combinedErrors allDiagnosticsEvents - - // clean up event - this.PublishDiagnostics.RemoveHandler(wrappedHandler) - - // done - return diagnosticsMap - } - - member this.WaitForDiagnosticsAsync (triggerAction: unit -> Async) (fileNames: string list) = - this.WaitForDiagnostics (fun () -> triggerAction () |> Async.RunSynchronously) fileNames - - interface IDisposable with - member __.Dispose() = - try - (tempDir :> IDisposable).Dispose() - with - | _ -> () diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs index cd7da3c7d3a..74062d0b028 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/CompletionTests.fs @@ -4,13 +4,12 @@ namespace FSharp.Compiler.Scripting.UnitTests open System open System.Threading.Tasks -open FSharp.Compiler.Scripting -open NUnit.Framework +open FSharp.Test.ScriptHelpers +open Xunit -[] type CompletionTests() = - [] + [] member _.``Instance completions in the same submission``() = async { use script = new FSharpScript() @@ -18,47 +17,58 @@ type CompletionTests() = "x." ] let! completions = script.GetCompletionItems(String.Join("\n", lines), 2, 2) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo") - Assert.AreEqual(1, matchingCompletions.Length) + Assert.Equal(1, matchingCompletions.Length) } |> Async.StartAsTask :> Task - [] + [] member _.``Instance completions from a previous submission``() = async { use script = new FSharpScript() script.Eval("let x = 1") |> ignoreValue let! completions = script.GetCompletionItems("x.", 1, 2) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo") - Assert.AreEqual(1, matchingCompletions.Length) + Assert.Equal(1, matchingCompletions.Length) } |> Async.StartAsTask :> Task - [] + [] + member _.``Completions from types that try to pull in Windows runtime extensions``() = + async { + use script = new FSharpScript() + script.Eval("open System") |> ignoreValue + script.Eval("let t = TimeSpan.FromHours(1.0)") |> ignoreValue + let! completions = script.GetCompletionItems("t.", 1, 2) + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "TotalHours") + Assert.Equal(1, matchingCompletions.Length) + } |> Async.StartAsTask :> Task + + [] member _.``Static member completions``() = async { use script = new FSharpScript() let! completions = script.GetCompletionItems("System.String.", 1, 14) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Join") - Assert.GreaterOrEqual(matchingCompletions.Length, 1) + Assert.True(matchingCompletions.Length >= 1) } |> Async.StartAsTask :> Task - [] + [] member _.``Type completions from namespace``() = async { use script = new FSharpScript() let! completions = script.GetCompletionItems("System.", 1, 7) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "String") - Assert.GreaterOrEqual(matchingCompletions.Length, 1) + Assert.True(matchingCompletions.Length >= 1) } |> Async.StartAsTask :> Task - [] + [] member _.``Namespace completions``() = async { use script = new FSharpScript() let! completions = script.GetCompletionItems("System.", 1, 7) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Collections") - Assert.AreEqual(1, matchingCompletions.Length) + Assert.Equal(1, matchingCompletions.Length) } |> Async.StartAsTask :> Task - [] + [] member _.``Extension method completions``() = async { use script = new FSharpScript() @@ -67,5 +77,84 @@ type CompletionTests() = "list." ] let! completions = script.GetCompletionItems(String.Join("\n", lines), 3, 5) let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Select") - Assert.AreEqual(1, matchingCompletions.Length) + Assert.Equal(1, matchingCompletions.Length) } |> Async.StartAsTask :> Task + + [] + member _.``Completions with strange names for static members``() = + use script = new FSharpScript() + let lines = [ "type C() =" + " static member ``Long Name`` = 1" + " static member ``-``(a:C, b:C) = C()" + " static member op_Addition(a:C, b:C) = C()" + " static member ``base``(a:C, b:C) = C()" + " static member ``|A|_|``(a:C, b:C) = C()" + "C." ] + let completions = script.GetCompletionItems(String.Join("\n", lines), 7, 2) |> Async.RunSynchronously + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Long Name") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``Long Name``", matchingCompletions.[0].NameInCode) + + // Things with names like op_Addition are suppressed from completion by FCS + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "+") + Assert.Equal(0, matchingCompletions.Length) + + // Strange names like ``+`` and ``-`` are just normal text and not operators + // and are present in competion lists + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "-") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``-``", matchingCompletions.[0].NameInCode) + + // ``base`` is a strange name but is still present. In this case the inserted + // text NameInCode is ``base`` because the thing is not a base value mapping to + // the base keyword + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "base") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``base``", matchingCompletions.[0].NameInCode) + + // ``|A|_|`` is a strange name like the name of an active pattern but is still present. + // In this case the inserted is (|A|_|) + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "|A|_|") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("(|A|_|)", matchingCompletions.[0].NameInCode) + + + [] + member _.``Completions with strange names for module``() = + use script = new FSharpScript() + let lines = [ "module M =" + " let ``Long Name`` = 1" + " let ``-``(a:int, b:int) = 1" + " let op_Addition(a:int, b:int) = 1" + " let ``base``(a:int, b:int) = 1" + " let (|A|_|)(a:int, b:int) = None" + "M." ] + let completions = script.GetCompletionItems(String.Join("\n", lines), 7, 2) |> Async.RunSynchronously + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Long Name") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``Long Name``", matchingCompletions.[0].NameInCode) + + // Things with names like op_Addition are suppressed from completion by FCS + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "+") + Assert.Equal(0, matchingCompletions.Length) + + // Strange names like ``+`` and ``-`` are just normal text and not operators + // and are present in competion lists + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "-") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``-``", matchingCompletions.[0].NameInCode) + + // ``base`` is a strange name but is still present. In this case the inserted + // text NameInCode is ``base`` because the thing is not a base value mapping to + // the base keyword + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "base") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("``base``", matchingCompletions.[0].NameInCode) + + // (|A|_|) is an active pattern and the completion item is the + // active pattern case A. In this case the inserted is A + let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "A") + Assert.Equal(1, matchingCompletions.Length) + Assert.Equal("A", matchingCompletions.[0].NameInCode) + + diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/ConsoleHelpers.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/ConsoleHelpers.fs deleted file mode 100644 index 6df77c83b38..00000000000 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/ConsoleHelpers.fs +++ /dev/null @@ -1,64 +0,0 @@ -namespace FSharp.Compiler.Scripting.UnitTests - -open System -open System.Collections.Generic -open System.IO -open System.Text - -type internal CapturedTextReader() = - inherit TextReader() - let queue = Queue() - member _.ProvideInput(text: string) = - for c in text.ToCharArray() do - queue.Enqueue(c) - override _.Peek() = - if queue.Count > 0 then queue.Peek() |> int else -1 - override _.Read() = - if queue.Count > 0 then queue.Dequeue() |> int else -1 - -type internal RedirectConsoleInput() = - let oldStdIn = Console.In - let newStdIn = new CapturedTextReader() - do Console.SetIn(newStdIn) - member _.ProvideInput(text: string) = - newStdIn.ProvideInput(text) - interface IDisposable with - member __.Dispose() = - Console.SetIn(oldStdIn) - newStdIn.Dispose() - -type internal EventedTextWriter() = - inherit TextWriter() - let sb = StringBuilder() - let lineWritten = Event() - member _.LineWritten = lineWritten.Publish - override _.Encoding = Encoding.UTF8 - override _.Write(c: char) = - if c = '\n' then - let line = - let v = sb.ToString() - if v.EndsWith("\r") then v.Substring(0, v.Length - 1) - else v - sb.Clear() |> ignore - lineWritten.Trigger(line) - else sb.Append(c) |> ignore - -type internal RedirectConsoleOutput() = - let outputProduced = Event() - let errorProduced = Event() - let oldStdOut = Console.Out - let oldStdErr = Console.Error - let newStdOut = new EventedTextWriter() - let newStdErr = new EventedTextWriter() - do newStdOut.LineWritten.Add outputProduced.Trigger - do newStdErr.LineWritten.Add errorProduced.Trigger - do Console.SetOut(newStdOut) - do Console.SetError(newStdErr) - member _.OutputProduced = outputProduced.Publish - member _.ErrorProduced = errorProduced.Publish - interface IDisposable with - member __.Dispose() = - Console.SetOut(oldStdOut) - Console.SetError(oldStdErr) - newStdOut.Dispose() - newStdErr.Dispose() diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs new file mode 100644 index 00000000000..ade8a343b41 --- /dev/null +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerInteractiveTests.fs @@ -0,0 +1,874 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.Scripting.DependencyManager.UnitTests + +open System +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open System.Threading + +open FSharp.Compiler.Interactive.Shell +open FSharp.Compiler.DependencyManager +open FSharp.Compiler.Diagnostics +open FSharp.Test.ScriptHelpers +open FSharp.DependencyManager.Nuget + +open Internal.Utilities + +open Xunit + +module Native = + [] + extern int NoneSuch() + +type scriptHost (?langVersion: LangVersion) = inherit FSharpScript(langVersion=defaultArg langVersion LangVersion.Preview) + +type DependencyManagerInteractiveTests() = + + let getValue ((value: Result), (errors: FSharpDiagnostic[])) = + if errors.Length > 0 then + failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors)) + match value with + | Ok(value) -> value + | Error ex -> raise ex + + let getErrors ((_value: Result), (errors: FSharpDiagnostic[])) = + errors + + let ignoreValue = getValue >> ignore + + [] + member _.``SmokeTest - #r nuget``() = + let text = """ +#r @"nuget:Newtonsoft.Json, Version=9.0.1" +0""" + use script = new scriptHost() + let opt = script.Eval(text) |> getValue + let value = opt.Value + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal(0, value.ReflectionValue :?> int) + + [] + member _.``SmokeTest - #r nuget package not found``() = + let text = """ +#r @"nuget:System.Collections.Immutable.DoesNotExist, version=1.5.0" +0""" + use script = new scriptHost() + let opt, errors = script.Eval(text) + Assert.Equal(errors.Length, 1) + +(* + [] + [] + member _.``syntax produces error messages in FSharp 4.7``(code:string, message: string) = + use script = new scriptHost() + let errors = script.Eval(code) |> getErrors + Assert.Contains(message, errors |> Array.map(fun e -> e.Message)) +*) + [] + member _.``Use Dependency Manager to resolve dependency FSharp.Data``() = + + let nativeProbingRoots () = Seq.empty + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net472") + Assert.Equal(true, result.Success) + Assert.Equal(1, result.Resolutions |> Seq.length) + Assert.Equal(1, result.SourceFiles |> Seq.length) + Assert.Equal(2, result.Roots |> Seq.length) + + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net5.0") + Assert.Equal(true, result.Success) + Assert.Equal(1, result.Resolutions |> Seq.length) + Assert.Equal(1, result.SourceFiles |> Seq.length) + Assert.Equal(1, result.Roots |> Seq.length) + () + + [] + member _.``Dependency Manager Reports package root for nuget package with no build artifacts``() = + + let nativeProbingRoots () = Seq.empty + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + let result = dp.Resolve(idm, ".fsx", [|"r", "Microsoft.Data.Sqlite, 3.1.8"|], reportError, "net5.0") + Assert.Equal(true, result.Success) + Assert.True((result.Resolutions |> Seq.length) > 1) + Assert.Equal(1, result.SourceFiles |> Seq.length) + Assert.True(Option.isSome(result.Roots |> Seq.tryFind(fun root -> root.EndsWith("microsoft.data.sqlite/3.1.8/")))) + () + + + [] + member _.``Dependency add with nonexistent package should fail``() = + + let nativeProbingRoots () = Seq.empty + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result = dp.Resolve(idm, ".fsx", [|"r", "System.Collections.Immutable.DoesNotExist"|], reportError, "net472") + Assert.Equal(false, result.Success) + Assert.Equal(0, result.Resolutions |> Seq.length) + Assert.Equal(0, result.SourceFiles |> Seq.length) + Assert.Equal(0, result.Roots |> Seq.length) + + let result = dp.Resolve(idm, ".fsx", [|"r", "System.Collections.Immutable.DoesNotExist"|], reportError, "net5.0") + Assert.Equal(false, result.Success) + Assert.Equal(0, result.Resolutions |> Seq.length) + Assert.Equal(0, result.SourceFiles |> Seq.length) + Assert.Equal(0, result.Roots |> Seq.length) + () + + + [] + member _.``Multiple Instances of DependencyProvider should be isolated``() = + + let assemblyProbingPaths () = Seq.empty + let nativeProbingRoots () = Seq.empty + + use dp1 = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm1 = dp1.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result1 = dp1.Resolve(idm1, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net472") + Assert.Equal(true, result1.Success) + Assert.Equal(1, result1.Resolutions |> Seq.length) + Assert.True((result1.Resolutions |> Seq.head).Contains("/net45/")) + Assert.Equal(1, result1.SourceFiles |> Seq.length) + Assert.Equal(2, result1.Roots |> Seq.length) + Assert.True((result1.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/")) + Assert.True((result1.Roots |> Seq.last).EndsWith("/microsoft.netframework.referenceassemblies/1.0.0/")) + + let result2 = dp1.Resolve(idm1, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net5.0") + Assert.Equal(true, result2.Success) + Assert.Equal(1, result2.Resolutions |> Seq.length) + let expected2 = "/netstandard2.0/" + Assert.True((result2.Resolutions |> Seq.head).Contains(expected2)) + Assert.Equal(1, result2.SourceFiles |> Seq.length) + Assert.Equal(1, result2.Roots |> Seq.length) + Assert.True((result2.Roots |> Seq.head).EndsWith("/fsharp.data/3.3.3/")) + + use dp2 = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm2 = dp2.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result3 = dp2.Resolve(idm2, ".fsx", [|"r", "System.Json, Version=4.6.0"|], reportError, "net472") + Assert.Equal(true, result3.Success) + Assert.Equal(1, result3.Resolutions |> Seq.length) + Assert.True((result3.Resolutions |> Seq.head).Contains("/netstandard2.0/")) + Assert.Equal(1, result3.SourceFiles |> Seq.length) + Assert.Equal(1, result3.SourceFiles |> Seq.length) + Assert.True((result3.Roots |> Seq.head).EndsWith("/system.json/4.6.0/")) + + let result4 = dp2.Resolve(idm2, ".fsx", [|"r", "System.Json, Version=4.6.0"|], reportError, "net5.0") + Assert.Equal(true, result4.Success) + Assert.Equal(1, result4.Resolutions |> Seq.length) + let expected4 = "/netstandard2.0/" + Assert.True((result4.Resolutions |> Seq.head).Contains(expected4)) + Assert.Equal(1, result4.SourceFiles |> Seq.length) + Assert.Equal(1, result4.Roots |> Seq.length) + Assert.True((result4.Roots |> Seq.head).EndsWith("/system.json/4.6.0/")) + () + + [] + member _.``Nuget Reference package with dependencies we should get package roots and dependent references``() = + + let nativeProbingRoots () = Seq.empty + + use dp1 = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm1 = dp1.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result1 = dp1.Resolve(idm1, ".fsx", [|"r", "Microsoft.Extensions.Configuration.Abstractions, 3.1.1"|], reportError, "net472") + Assert.Equal(true, result1.Success) + Assert.Equal(6, result1.Resolutions |> Seq.length) + Assert.True((result1.Resolutions |> Seq.head).Contains("/netstandard2.0/")) + Assert.Equal(1, result1.SourceFiles |> Seq.length) + Assert.Equal(7, result1.Roots |> Seq.length) + Assert.True((result1.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/")) + + // Netstandard gets fewer dependencies than desktop, because desktop framework doesn't contain assemblies like System.Memory + // Those assemblies must be delivered by nuget for desktop apps + let result2 = dp1.Resolve(idm1, ".fsx", [|"r", "Microsoft.Extensions.Configuration.Abstractions, 3.1.1"|], reportError, "net5.0") + Assert.Equal(true, result2.Success) + Assert.Equal(2, result2.Resolutions |> Seq.length) + let expected = "/netcoreapp3.1/" + Assert.True((result2.Resolutions |> Seq.head).Contains(expected)) + Assert.Equal(1, result2.SourceFiles |> Seq.length) + Assert.Equal(2, result2.Roots |> Seq.length) + Assert.True((result2.Roots |> Seq.head).EndsWith("/microsoft.extensions.configuration.abstractions/3.1.1/")) + () + +/// Native dll resolution is not implemented on desktop +#if NETCOREAPP + [] + member _.``Script using TorchSharp``() = + let text = """ +#r "nuget:RestoreSources=https://donsyme.pkgs.visualstudio.com/TorchSharp/_packaging/packages2/nuget/v3/index.json" +#r "nuget:libtorch-cpu,0.3.52118" +#r "nuget:TorchSharp,0.3.52118" + +TorchSharp.Tensor.LongTensor.From([| 0L .. 100L |]).Device +""" + + if RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + use script = new scriptHost() + let opt = script.Eval(text) |> getValue + let value = opt.Value + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal("cpu", value.ReflectionValue :?> string) + () + + + [] + member _.``Use Dependency Manager to restore packages with native dependencies, build and run script that depends on the results``() = + let packagemanagerlines = [| + "r", "Microsoft.ML,version=1.4.0-preview" + "r", "Microsoft.ML.AutoML,version=0.16.0-preview" + "r", "Microsoft.Data.Analysis,version=0.4.0" + |] + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable resolverPackageRoots = Seq.empty + let mutable resolverPackageRoots = Seq.empty + let mutable resolverReferences = Seq.empty + + let nativeProbingRoots () = resolverPackageRoots + let assemblyProbingPaths () = resolverReferences + + // Restore packages, Get Reference dll paths and package roots + let result = + use dp = new DependencyProvider(AssemblyResolutionProbe(assemblyProbingPaths), NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "net5.0") + + Assert.True(result.Success, "resolve failed") + + resolverPackageRoots <- result.Roots + resolverReferences <- result.Resolutions + +// Build and execute reference + let referenceText = +#if DISABLED_DUE_TO_ISSUE_8588 +// +// https://github.com/dotnet/fsharp/issues/8588 + // For this test case use Assembly Qualified References + ("", result.Resolutions) + ||> Seq.fold(fun acc r -> + let assemblyName = AssemblyName.GetAssemblyName(r) + acc + "#r @\"" + assemblyName.FullName + "\"" + Environment.NewLine) +#else + // use standard #r for now + ("", result.Resolutions) + ||> Seq.fold(fun acc r -> + acc + "#r @\"" + r + "\"" + Environment.NewLine) +#endif + + let code = @" +$(REFERENCES) + +open System +open System.IO +open System.Linq +open Microsoft.Data.Analysis + +let Shuffle (arr:int[]) = + let rnd = Random() + for i in 0 .. arr.Length - 1 do + let r = i + rnd.Next(arr.Length - i) + let temp = arr.[r] + arr.[r] <- arr.[i] + arr.[i] <- temp + arr + +let housingPath = ""housing.csv"" +let housingData = DataFrame.LoadCsv(housingPath) +let randomIndices = (Shuffle(Enumerable.Range(0, (int (housingData.Rows.Count) - 1)).ToArray())) +let testSize = int (float (housingData.Rows.Count) * 0.1) +let trainRows = randomIndices.[testSize..] +let testRows = randomIndices.[..testSize] +let housing_train = housingData.[trainRows] + +open Microsoft.ML +open Microsoft.ML.Data +open Microsoft.ML.AutoML + +let mlContext = MLContext() +let experiment = mlContext.Auto().CreateRegressionExperiment(maxExperimentTimeInSeconds = 15u) +let result = experiment.Execute(housing_train, labelColumnName = ""median_house_value"") +let details = result.RunDetails +printfn ""%A"" result +123 +" + let scriptText = code.Replace("$(REFERENCES)", referenceText) + + // Use the dependency manager to resolve assemblies and native paths + use dp = new DependencyProvider(AssemblyResolutionProbe(assemblyProbingPaths), NativeResolutionProbe(nativeProbingRoots)) + + use script = new FSharpScript() + let opt = script.Eval(scriptText) |> getValue + let value = opt.Value + Assert.Equal(123, value.ReflectionValue :?> int32) + + [] + member _.``Use NativeResolver to resolve native dlls.``() = + let packagemanagerlines = [| + "r", "Microsoft.ML,version=1.4.0-preview" + "r", "Microsoft.ML.AutoML,version=0.16.0-preview" + "r", "Microsoft.Data.Analysis,version=0.4.0" + |] + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable resolverPackageRoots = Seq.empty + let mutable resolverPackageRoots = Seq.empty + + let mutable resolverReferences = Seq.empty + let nativeProbingRoots () = resolverPackageRoots + let assemblyPaths () = resolverReferences + + // Restore packages, Get Reference dll paths and package roots + let result = + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "net5.0") + + Assert.True(result.Success, "resolve failed") + + resolverPackageRoots <- result.Roots + resolverReferences <- result.Resolutions + + use _nativeDepencyResolver = new NativeDllResolveHandler(NativeResolutionProbe(nativeProbingRoots)) + + // Build and execute script + let referenceText = + ("", result.Resolutions) ||> Seq.fold(fun acc r -> acc + @"#r @""" + r + "\"" + Environment.NewLine) + + let code = @" +$(REFERENCES) + +open System +open System.IO +open System.Linq +open Microsoft.Data.Analysis + +let Shuffle (arr:int[]) = + let rnd = Random() + for i in 0 .. arr.Length - 1 do + let r = i + rnd.Next(arr.Length - i) + let temp = arr.[r] + arr.[r] <- arr.[i] + arr.[i] <- temp + arr + +let housingPath = ""housing.csv"" +let housingData = DataFrame.LoadCsv(housingPath) +let randomIndices = (Shuffle(Enumerable.Range(0, (int (housingData.Rows.Count) - 1)).ToArray())) +let testSize = int (float (housingData.Rows.Count) * 0.1) +let trainRows = randomIndices.[testSize..] +let testRows = randomIndices.[..testSize] +let housing_train = housingData.[trainRows] + +open Microsoft.ML +open Microsoft.ML.Data +open Microsoft.ML.AutoML + +let mlContext = MLContext() +let experiment = mlContext.Auto().CreateRegressionExperiment(maxExperimentTimeInSeconds = 15u) +let result = experiment.Execute(housing_train, labelColumnName = ""median_house_value"") +let details = result.RunDetails +printfn ""%A"" result +123 +" + let scriptText = code.Replace("$(REFERENCES)", referenceText) + + use script = new FSharpScript() + let opt = script.Eval(scriptText) |> getValue + let value = opt.Value + Assert.Equal(123, value.ReflectionValue :?> int32) + + [] + member _.``Use AssemblyResolver to resolve assemblies``() = + let packagemanagerlines = [| + "r", "Microsoft.ML,version=1.4.0-preview" + "r", "Microsoft.ML.AutoML,version=0.16.0-preview" + "r", "Microsoft.Data.Analysis,version=0.4.0" + |] + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable resolverPackageRoots = Seq.empty + let mutable resolverReferences = Seq.empty + + let nativeProbingRoots () = resolverPackageRoots + let assemblyProbingPaths () = resolverReferences + + // Restore packages, Get Reference dll paths and package roots + let result = + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "net5.0") + + Assert.True(result.Success, "resolve failed") + + resolverPackageRoots <- result.Roots + resolverReferences <- result.Resolutions + + use _assemblyResolver = new AssemblyResolveHandler(AssemblyResolutionProbe(assemblyProbingPaths)) + + // Build and execute script + let referenceText = + ("", result.Resolutions) + ||> Seq.fold(fun acc r -> + acc + " @\"" + r + "\";" + Environment.NewLine) + + let code = """ +open System.Reflection + +let x = [| +$(REFERENCES) + |] + +x |> Seq.iter(fun r -> + let name = AssemblyName.GetAssemblyName(r) + let asm = Assembly.Load(name) + printfn "%A" (asm.FullName) + ) +123 +""" + let scriptText = code.Replace("$(REFERENCES)", referenceText) + + use script = new FSharpScript() + let opt = script.Eval(scriptText) |> getValue + let value = opt.Value + Assert.Equal(123, value.ReflectionValue :?> int32) + + [] + member _.``Verify that referencing FSharp.Core fails with FSharp Scripts``() = + let packagemanagerlines = [| "r", "FSharp.Core,version=4.7.1" |] + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable resolverPackageRoots = Seq.empty + let mutable resolverReferences = Seq.empty + + let nativeProbingRoots () = resolverPackageRoots + let assemblyProbingPaths () = resolverReferences + + // Restore packages, Get Reference dll paths and package roots + let result = + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + dp.Resolve(idm, ".fsx", packagemanagerlines, reportError, "net5.0") + + // Expected: error FS3217: PackageManager can not reference the System Package 'FSharp.Core' + Assert.False(result.Success, "resolve succeeded but should have failed") + + [] + member _.``Verify that referencing FSharp.Core succeeds with CSharp Scripts``() = + let packagemanagerlines = [| "r", "FSharp.Core,version=4.7.1" |] + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable resolverPackageRoots = Seq.empty + let mutable resolverReferences = Seq.empty + + let nativeProbingRoots () = resolverPackageRoots + let assemblyProbingPaths () = resolverReferences + + // Restore packages, Get Reference dll paths and package roots + let result = + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + dp.Resolve(idm, ".csx", packagemanagerlines, reportError, "net5.0") + + Assert.True(result.Success, "resolve failed but should have succeeded") + + + [] + member _.``Verify that Dispose on DependencyProvider unhooks ResolvingUnmanagedDll event handler``() = + + let mutable found = false + let nativeProbingRoots () = + found <- true + Seq.empty + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + // Set up native resolver to resolve dll's + do + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + + // Invoking a non-existent dll via pinvoke cause a probe. which should invoke the call back + try Native.NoneSuch() |> ignore with _ -> () + Assert.True (found, "Failed to invoke the nativeProbingRoots callback") + + // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler + found <- false + try Native.NoneSuch() |> ignore with _ -> () + Assert.False (found, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ") + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net472") + Assert.Equal(true, result.Success) + Assert.Equal(1, result.Resolutions |> Seq.length) + Assert.Equal(1, result.SourceFiles |> Seq.length) + Assert.Equal(2, result.Roots |> Seq.length) + + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net5.0") + Assert.Equal(true, result.Success) + Assert.Equal(1, result.Resolutions |> Seq.length) + Assert.Equal(1, result.SourceFiles |> Seq.length) + Assert.Equal(1, result.Roots |> Seq.length) + () + + + [] + member _.``Verify that Dispose on DependencyProvider unhooks ResolvingUnmanagedDll and AssemblyResolver event handler``() = + + let mutable assemblyFound = false + let assemblyProbingPaths () = + assemblyFound <- true + Seq.empty + + let mutable nativeFound = false + let nativeProbingRoots () = + nativeFound <- true + Seq.empty + + // Set up native resolver to resolve dll's + do + use dp = new DependencyProvider(AssemblyResolutionProbe(assemblyProbingPaths), NativeResolutionProbe(nativeProbingRoots)) + + // Invoking a non-existent dll via pinvoke cause a probe. which should invoke the call back + try Native.NoneSuch() |> ignore with _ -> () + Assert.True (nativeFound, "Failed to invoke the nativeProbingRoots callback") + + // Invoking a non-existent assembly causes a probe. which should invoke the call back + try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> () + Assert.True (assemblyFound, "Failed to invoke the AssemblyResolve handler") + + // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler + nativeFound <- false + assemblyFound <- false + + try Native.NoneSuch() |> ignore with _ -> () + Assert.False (nativeFound, "Invoke the nativeProbingRoots callback -- Error the ResolvingUnmanagedDll still fired ") + + try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> () + Assert.False (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ") +#endif + + [] + member _.``Verify that Dispose on AssemblyResolveHandler unhooks AssemblyResolve event handler``() = + + let mutable assemblyFound = false + let assemblyProbingPaths () = + assemblyFound <- true + Seq.empty + + // Set up AssemblyResolver to resolve dll's + do + use dp = new AssemblyResolveHandler(AssemblyResolutionProbe(assemblyProbingPaths)) + + // Invoking a non-existent assembly causes a probe. which should invoke the call back + try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> () + Assert.True (assemblyFound, "Failed to invoke the AssemblyResolve handler") + + // Here the dispose was invoked which should clear the ResolvingUnmanagedDll handler + assemblyFound <- false + + try Assembly.Load("NoneSuchAssembly") |> ignore with _ -> () + Assert.False (assemblyFound, "Invoke the assemblyProbingRoots callback -- Error the AssemblyResolve still fired ") + + [] + member _.``Verify that Dispose cleans up the native paths added``() = + let nativeProbingRoots () = Seq.empty + + let appendSemiColon (p:string) = + if not(p.EndsWith(";", StringComparison.OrdinalIgnoreCase)) then + p + ";" + else + p + + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> printfn "PackageManagementError %d : %s" code message + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let mutable initialPath:string = null + let mutable currentPath:string = null + let mutable finalPath:string = null + do + initialPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + let mutable currentPath:string = null + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + let result = dp.Resolve(idm, ".fsx", [|"r", "Microsoft.Data.Sqlite,3.1.7"|], reportError, "netstandard2.0") + Assert.Equal(true, result.Success) + currentPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + finalPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + Assert.True(currentPath <> initialPath) // The path was modified by #r "nuget: ..." + Assert.Equal(finalPath, initialPath) // IDispose correctly cleaned up the path + + initialPath <- null + currentPath <- null + finalPath <- null + do + initialPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + let mutable currentPath:string = null + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + let result = dp.Resolve(idm, ".fsx", [|"r", "Microsoft.Data.Sqlite,3.1.7"|], reportError, "net5.0") + Assert.Equal(true, result.Success) + currentPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + finalPath <- appendSemiColon (Environment.GetEnvironmentVariable("PATH")) + Assert.True(currentPath <> initialPath) // The path was modified by #r "nuget: ..." + Assert.Equal(finalPath, initialPath) // IDispose correctly cleaned up the path + + () + + [] + member _.``Verify that #help produces help text for fsi + dependency manager``() = + let expected = [| + """ F# Interactive directives:""" + """""" + """ #r "file.dll";; // Reference (dynamically load) the given DLL""" + """ #i "package source uri";; // Include package source uri when searching for packages""" + """ #I "path";; // Add the given search path for referenced DLLs""" + """ #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced""" + """ #time ["on"|"off"];; // Toggle timing on/off""" + """ #help;; // Display help""" + """ #quit;; // Exit""" + """""" + """ F# Interactive command line options:""" + """""" + + // this is the end of the line each different platform has a different mechanism for starting fsi + // Actual output looks similar to: """ See 'testhost --help' for options""" + """--help' for options""" + + """""" + """""" + |] + + let mutable found = 0 + let lines = System.Collections.Generic.List() + use sawExpectedOutput = new ManualResetEvent(false) + let verifyOutput (line: string) = + let compareLine (s: string) = + if s = "" then line = "" + else line.EndsWith(s) + lines.Add(line) + match expected |> Array.tryFind(compareLine) with + | None -> () + | Some t -> + found <- found + 1 + if found = expected.Length then sawExpectedOutput.Set() |> ignore + + let text = "#help" + use output = new RedirectConsoleOutput() + use script = new FSharpScript(quiet = false, langVersion = LangVersion.V47) + let mutable found = 0 + output.OutputProduced.Add (fun line -> verifyOutput line) + let opt = script.Eval(text) |> getValue + Assert.True(sawExpectedOutput.WaitOne(TimeSpan.FromSeconds(5.0)), sprintf "Expected to see error sentinel value written\nexpected:%A\nactual:%A" expected lines) + + + [] + member _.``Verify that #help produces help text for fsi + dependency manager language version preview``() = + let expected = [| + """ F# Interactive directives:""" + """""" + """ #r "file.dll";; // Reference (dynamically load) the given DLL""" + """ #i "package source uri";; // Include package source uri when searching for packages""" + """ #I "path";; // Add the given search path for referenced DLLs""" + """ #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced""" + """ #time ["on"|"off"];; // Toggle timing on/off""" + """ #help;; // Display help""" + """ #r "nuget:FSharp.Data, 3.1.2";; // Load Nuget Package 'FSharp.Data' version '3.1.2'""" + """ #r "nuget:FSharp.Data";; // Load Nuget Package 'FSharp.Data' with the highest version""" + """ #quit;; // Exit""" + """""" + """ F# Interactive command line options:""" + """""" + + // this is the end of the line each different platform has a different mechanism for starting fsi + // Actual output looks similar to: """ See 'testhost --help' for options""" + """--help' for options""" + + """""" + """""" + |] + + let mutable found = 0 + let lines = System.Collections.Generic.List() + use sawExpectedOutput = new ManualResetEvent(false) + let verifyOutput (line: string) = + let compareLine (s: string) = + if s = "" then line = "" + else line.EndsWith(s) + lines.Add(line) + match expected |> Array.tryFind(compareLine) with + | None -> () + | Some t -> + found <- found + 1 + if found = expected.Length then sawExpectedOutput.Set() |> ignore + + let text = "#help" + use output = new RedirectConsoleOutput() + use script = new FSharpScript(quiet = false, langVersion = LangVersion.Preview) + let mutable found = 0 + output.OutputProduced.Add (fun line -> verifyOutput line) + let opt = script.Eval(text) |> getValue + Assert.True(sawExpectedOutput.WaitOne(TimeSpan.FromSeconds(5.0)), sprintf "Expected to see error sentinel value written\nexpected:%A\nactual:%A" expected lines) + + + [] + member _.``Verify that timeout --- times out and fails``() = + let nativeProbingRoots () = Seq.empty + let mutable foundCorrectError = false + let mutable foundWrongError = false + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> + if code = 3217 then foundCorrectError <- true + else foundWrongError <- true + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"|], reportError, "net5.0", timeout=0) // Fail in 0 milliseconds + Assert.Equal(false, result.Success) + Assert.Equal(foundCorrectError, true) + Assert.Equal(foundWrongError, false) + () + + [] + member _.``Verify that script based timeout overrides api based - timeout on script``() = + let nativeProbingRoots () = Seq.empty + let mutable foundCorrectError = false + let mutable foundWrongError = false + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> + if code = 3217 then foundCorrectError <- true + else foundWrongError <- true + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"; "r", "timeout=0"|], reportError, "net5.0", null, "", "", "", -1) // Wait forever + Assert.Equal(false, result.Success) + Assert.Equal(foundCorrectError, true) + Assert.Equal(foundWrongError, false) + () + + [] + member _.``Verify that script based timeout overrides api based - timeout on api , forever on script``() = + let nativeProbingRoots () = Seq.empty + let mutable foundCorrectError = false + let mutable foundWrongError = false + + use dp = new DependencyProvider(NativeResolutionProbe(nativeProbingRoots)) + let reportError = + let report errorType code message = + match errorType with + | ErrorReportType.Error -> + if code = 3401 then foundCorrectError <- true + else foundWrongError <- true + | ErrorReportType.Warning -> printfn "PackageManagementWarning %d : %s" code message + ResolvingErrorReport (report) + + let idm = dp.TryFindDependencyManagerByKey(Seq.empty, "", reportError, "nuget") + let result = dp.Resolve(idm, ".fsx", [|"r", "FSharp.Data,3.3.3"; "r", "timeout=none"|], reportError, "net5.0", null, "", "", "", -1) // Wait forever + Assert.Equal(true, result.Success) + Assert.Equal(foundCorrectError, false) + Assert.Equal(foundWrongError, false) + () + + diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs new file mode 100644 index 00000000000..780fc0d5e44 --- /dev/null +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/DependencyManagerLineParserTests.fs @@ -0,0 +1,200 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.DependencyManager.UnitTests + + +open System +open System.Linq +open FSharp.DependencyManager.Nuget + +open Xunit + +type DependencyManagerLineParserTests() = + + let parseBinLogPath text = + let _, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" [text] + binLogPath + + let parseSingleReference text = + let packageReferences, _, _ = FSharpDependencyManager.parsePackageReference ".fsx" [text] + packageReferences.Single() + + [] + member _.``Binary logging defaults to disabled``() = + let _, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" [] + Assert.Equal(None, binLogPath) + + [] + member _.``Binary logging can be set to default path``() = + let binLogPath = parseBinLogPath "bl=true" + Assert.Equal(Some (None: string option), binLogPath) + + [] + member _.``Binary logging can be disabled``() = + let binLogPath = parseBinLogPath "bl=false" + Assert.Equal(None, binLogPath) + + [] + member _.``Binary logging can be set to specific location``() = + let binLogPath = parseBinLogPath "bl=path/to/file.binlog" + Assert.Equal(Some(Some "path/to/file.binlog"), binLogPath) + + [] + member _.``Bare binary log argument isn't parsed as a package name: before``() = + let packageReferences, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" ["bl, MyPackage"] + Assert.Equal("MyPackage", packageReferences.Single().Include) + Assert.Equal(Some (None: string option), binLogPath) + + [] + member _.``Bare binary log argument isn't parsed as a package name: middle``() = + let packageReferences, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" ["MyPackage, bl, 1.2.3.4"] + Assert.Equal("MyPackage", packageReferences.Single().Include) + Assert.Equal("1.2.3.4", packageReferences.Single().Version) + Assert.Equal(Some (None: string option), binLogPath) + + [] + member _.``Bare binary log argument isn't parsed as a package name: after``() = + let packageReferences, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" ["MyPackage, bl"] + Assert.Equal("MyPackage", packageReferences.Single().Include) + Assert.Equal(Some (None: string option), binLogPath) + + [] + member _.``Package named 'bl' can be explicitly referenced``() = + let packageReferences, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" ["Include=bl"] + Assert.Equal("bl", packageReferences.Single().Include) + Assert.Equal(None, binLogPath) + + [] + member _.``Package named 'bl' can be explicitly referenced with binary logging``() = + let packageReferences, binLogPath, _ = FSharpDependencyManager.parsePackageReference ".fsx" ["Include=bl,bl"] + Assert.Equal("bl", packageReferences.Single().Include) + Assert.Equal(Some (None: string option), binLogPath) + + [] + member _.``Parse explicitly specified package name``() = + let pr = parseSingleReference "Include=MyPackage" + Assert.Equal("MyPackage", pr.Include) + + [] + member _.``Parse implicitly specified package name``() = + let pr = parseSingleReference "MyPackage" + Assert.Equal("MyPackage", pr.Include) + + [] + member _.``Parse version number``() = + let pr = parseSingleReference "MyPackage, Version=1.2.3.4" + Assert.Equal("1.2.3.4", pr.Version) + + [] + member _.``Parse implicitly specified package name and implicitly specified version number``() = + let pr = parseSingleReference "MyPackage, 1.2.3.4" + Assert.Equal("MyPackage", pr.Include) + Assert.Equal("1.2.3.4", pr.Version) + + [] + member _.``Parse single restore source``() = + let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource" + Assert.Equal("MyRestoreSource", pr.RestoreSources) + + [] + member _.``Parse multiple restore sources``() = + let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource1, RestoreSources=MyRestoreSource2" + Assert.Equal("MyRestoreSource1;MyRestoreSource2", pr.RestoreSources) + + [] + member _.``Parse script``() = + let pr = parseSingleReference "MyPackage, Script=SomeScript" + Assert.Equal("SomeScript", pr.Script) + + [] + member _.``Include strings that look different but parse the same are reduced to a single item``() = + let prs, _, _ = + [ "MyPackage, Version=1.2.3.4" + "Include=MyPackage, Version=1.2.3.4" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + let pr = prs.Single() + Assert.Equal("MyPackage", pr.Include) + + [] + member _.``Timeout none is -1``() = + let _, _, timeout = + [ "timeout=none" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + Assert.Equal(timeout, Some -1) + + [] + member _.``Timeout 1000 is 1000``() = + let _, _, timeout = + [ "timeout=1000" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + Assert.Equal(timeout, Some 1000) + + [] + member _.``Timeout 0 is 0``() = + let _, _, timeout = + [ "timeout=0" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + Assert.Equal(timeout, Some 0) + + [] + member _.``Timeout for many values is the last specified ascending``() = + let _, _, timeout = + [ "timeout=none" + "timeout=1" + "timeout=10" + "timeout=100" + ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + Assert.Equal(timeout, Some 100) + + [] + member _.``Timeout for many values is the last specified descending``() = + let _, _, timeout = + [ "timeout=10000" + "timeout=1000" + "timeout=100" + "timeout=10" + ] + |> FSharpDependencyManager.parsePackageReference ".fsx" + Assert.Equal(timeout, Some 10) + + [] + member _.``Timeout invalid : timeout``() = + try + [ "timeout" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" |> ignore + Assert.True(false, "ArgumentException expected") //Assert.Fail + with + | :? ArgumentException -> () + | _ -> Assert.True(false, "ArgumentException expected") //Assert.Fail + + [] + member _.``Timeout invalid timeout=``() = + try + [ "timeout=" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" |> ignore + Assert.True(false, "ArgumentException expected") //Assert.Fail + with + | :? ArgumentException -> () + | _ -> Assert.True(false, "ArgumentException expected") //Assert.Fail + + [] + member _.``Timeout invalid timeout=nonesuch``() = + try + [ "timeout=nonesuch" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" |> ignore + Assert.True(false, "ArgumentException expected") //Assert.Fail + with + | :? ArgumentException -> () + | _ -> Assert.True(false, "ArgumentException expected") //Assert.Fail + + + [] + member _.``Timeout invalid timeout=-20``() = + try + [ "timeout=-20" ] + |> FSharpDependencyManager.parsePackageReference ".fsx" |> ignore + Assert.True(false, "ArgumentException expected") //Assert.Fail + with + | :? ArgumentException -> () + | _ -> Assert.True(false, "ArgumentException expected") //Assert.Fail diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj index a16969af734..d30dd32729c 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj @@ -2,26 +2,31 @@ - net472;netcoreapp3.0 - netcoreapp3.0 + net472;net5.0 + net5.0 Library true - nunit + xunit true - - + + + - + + + + + + - - + diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs index 3046c3a76f5..431ac983ec4 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs @@ -6,43 +6,44 @@ open System open System.Diagnostics open System.IO open System.Reflection +open System.Runtime.InteropServices open System.Threading open System.Threading.Tasks open FSharp.Compiler.Interactive.Shell -open FSharp.Compiler.Scripting -open NUnit.Framework +open FSharp.Test.ScriptHelpers + +open Xunit -[] type InteractiveTests() = - [] - member __.``Eval object value``() = + [] + member _.``Eval object value``() = use script = new FSharpScript() let opt = script.Eval("1+1") |> getValue let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual(2, value.ReflectionValue :?> int) + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal(2, value.ReflectionValue :?> int) - [] - member __.``Declare and eval object value``() = + [] + member _.``Declare and eval object value``() = use script = new FSharpScript() let opt = script.Eval("let x = 1 + 2\r\nx") |> getValue let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual(3, value.ReflectionValue :?> int) + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal(3, value.ReflectionValue :?> int) - [] - member __.``Capture console input``() = + [] + member _.``Capture console input``() = use input = new RedirectConsoleInput() use script = new FSharpScript() input.ProvideInput "stdin:1234\r\n" let opt = script.Eval("System.Console.ReadLine()") |> getValue let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual("stdin:1234", value.ReflectionValue) + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal("stdin:1234", downcast value.ReflectionValue) - [] - member __.``Capture console output/error``() = + [] + member _.``Capture console output/error``() = use output = new RedirectConsoleOutput() use script = new FSharpScript() use sawOutputSentinel = new ManualResetEvent(false) @@ -53,106 +54,159 @@ type InteractiveTests() = Assert.True(sawOutputSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see output sentinel value written") Assert.True(sawErrorSentinel.WaitOne(TimeSpan.FromSeconds(5.0)), "Expected to see error sentinel value written") - [] - member __.``Maintain state between submissions``() = + [] + member _.``Maintain state between submissions``() = use script = new FSharpScript() script.Eval("let add x y = x + y") |> ignoreValue let opt = script.Eval("add 2 3") |> getValue let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual(5, value.ReflectionValue :?> int) + Assert.Equal(typeof, value.ReflectionType) + Assert.Equal(5, downcast value.ReflectionValue) - [] - member __.``Assembly reference event successful``() = + [] + member _.``Assembly reference event successful``() = use script = new FSharpScript() - let testAssembly = "System.dll" - let mutable assemblyResolveEventCount = 0 - let mutable foundAssemblyReference = false - Event.add (fun (assembly: string) -> - assemblyResolveEventCount <- assemblyResolveEventCount + 1 - foundAssemblyReference <- String.Compare(testAssembly, Path.GetFileName(assembly), StringComparison.OrdinalIgnoreCase) = 0) - script.AssemblyReferenceAdded - script.Eval(sprintf "#r \"%s\"" testAssembly) |> ignoreValue - Assert.AreEqual(1, assemblyResolveEventCount) - Assert.True(foundAssemblyReference) - - [] - member __.``Assembly reference event unsuccessful``() = + let testCode = """ +#r "System.dll" +let stacktype= typeof +stacktype.Name = "Stack" +""" + let opt = script.Eval(testCode) |> getValue + let value = opt.Value + Assert.Equal(true, downcast value.ReflectionValue) + + [] + member _.``Assembly reference unsuccessful``() = use script = new FSharpScript() let testAssembly = "not-an-assembly-that-can-be-found.dll" - let mutable foundAssemblyReference = false - Event.add (fun _ -> foundAssemblyReference <- true) script.AssemblyReferenceAdded let _result, errors = script.Eval(sprintf "#r \"%s\"" testAssembly) - Assert.AreEqual(1, errors.Length) - Assert.False(foundAssemblyReference) + Assert.Equal(1, errors.Length) - [] - member __.``Add include path event successful``() = - use script = new FSharpScript() - let includePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) - let mutable includePathEventCount = 0 - let mutable foundIncludePath = false - Event.add (fun (inc: string) -> - includePathEventCount <- includePathEventCount + 1 - foundIncludePath <- foundIncludePath || String.Compare(includePath, inc, StringComparison.OrdinalIgnoreCase) = 0) - script.IncludePathAdded - script.Eval(sprintf "#I @\"%s\"" includePath) |> ignoreValue - Assert.AreEqual(1, includePathEventCount) - Assert.True(foundIncludePath) - - [] - member __.``Add include path event unsuccessful``() = - use script = new FSharpScript() - let includePath = Path.Combine("a", "path", "that", "can't", "be", "found") - let mutable foundIncludePath = false - Event.add (fun _ -> foundIncludePath <- true) script.IncludePathAdded - let _result, errors = script.Eval(sprintf "#I @\"%s\"" includePath) - Assert.AreEqual(1, errors.Length) - Assert.False(foundIncludePath) - - [] + [] member _.``Compilation errors report a specific exception``() = use script = new FSharpScript() let result, _errors = script.Eval("abc") match result with - | Ok(_) -> Assert.Fail("expected a failure") - | Error(ex) -> Assert.IsInstanceOf(ex) + | Ok(_) -> Assert.False(true, "expected a failure") + | Error(ex) -> Assert.IsAssignableFrom(typeof, ex) - [] + [] member _.``Runtime exceptions are propagated``() = use script = new FSharpScript() let result, errors = script.Eval("System.IO.File.ReadAllText(\"not-a-file-path-that-can-be-found-on-disk.txt\")") - Assert.IsEmpty(errors) + Assert.Empty(errors) match result with - | Ok(_) -> Assert.Fail("expected a failure") - | Error(ex) -> Assert.IsInstanceOf(ex) + | Ok(_) -> Assert.True(false, "expected a failure") + | Error(ex) -> Assert.IsAssignableFrom(typeof, ex) - [] - member __.``Nuget reference fires multiple events``() = - use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) - let mutable assemblyRefCount = 0 - let mutable includeAddCount = 0 - Event.add (fun _ -> assemblyRefCount <- assemblyRefCount + 1) script.AssemblyReferenceAdded - Event.add (fun _ -> includeAddCount <- includeAddCount + 1) script.IncludePathAdded - script.Eval("#r \"nuget:include=NUnitLite, version=3.11.0\"") |> ignoreValue - script.Eval("0") |> ignoreValue - Assert.GreaterOrEqual(assemblyRefCount, 2) - Assert.GreaterOrEqual(includeAddCount, 1) + [] + member _.``Script with #r "" errors``() = + use script = new FSharpScript() + let result, errors = script.Eval("#r \"\"") + Assert.NotEmpty(errors) + match result with + | Ok(_) -> Assert.False(true, "expected a failure") + | Error(ex) -> Assert.IsAssignableFrom(typeof, ex) + + [] + member _.``Script with #r " " errors``() = + use script = new FSharpScript() + let result, errors = script.Eval("#r \" \"") + Assert.NotEmpty(errors) + match result with + | Ok(_) -> Assert.False(true, "expected a failure") + | Error(ex) -> Assert.IsAssignableFrom(typeof, ex) + + + [] + member _.``Script using System.Configuration succeeds``() = + use script = new FSharpScript() + let result, errors = script.Eval(""" +#r "nuget:System.Configuration.ConfigurationManager,5.0.0" +open System.Configuration +System.Configuration.ConfigurationManager.AppSettings.Item "Environment" <- "LOCAL" """) + Assert.Empty(errors) + match result with + | Ok(_) -> () + | Error(ex) -> Assert.True(true, "expected no failures") + + [] + [] // No argument + [] // empty argument + [] // whitespace only argument + member _.``Script with #i syntax errors fail``(code, error0) = + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.NotEmpty(errors) + Assert.Equal(errors.[0].ToString(), error0) + + [] + [] + member _.``Script with more #i syntax errors fail``(code, error0, error1) = + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.NotEmpty(errors) + Assert.Equal(errors.Length, 2) + Assert.Equal(error0, errors.[0].ToString()) + Assert.Equal(error1, errors.[1].ToString()) + + [] + [] + member _.``Script with #i and no package manager specified``(code, error0) = + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.NotEmpty(errors) + Assert.Equal(errors.Length, 1) + Assert.Equal(errors.[0].ToString(), error0) + + [] + [] + member _.``Script with #i and forgot to add quotes``(code, error) = + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.NotEmpty(errors) + Assert.Equal(1, errors.Length) + Assert.Equal(error, errors.[0].ToString()) + + [] + member _.``#i to a directory that exists``() = + let path = Path.GetTempPath() + let code = sprintf "#i @\"nuget:%s\" " path + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.Empty(errors) + Assert.Equal(0, errors.Length) + + [] + member _.``#i to a directory that doesn't exist``() = + let path = + let newGuid() = Guid.NewGuid().ToString().Replace("{", "").Replace("}", "") + Path.Combine(Path.GetTempPath(), newGuid(), newGuid()) + let code = sprintf "#i @\"nuget:%s\"" path + let error = sprintf "interactive error The source directory '%s' not found" path + use script = new FSharpScript() + let result, errors = script.Eval(code) + Assert.NotEmpty(errors) + Assert.Equal(1, errors.Length) + Assert.True(errors.[0].ToString().EndsWith(error)) /// Native dll resolution is not implemented on desktop #if NETSTANDARD - [] - member __.``ML - use assembly with native dependencies``() = + [] + member _.``ML - use assembly with native dependencies``() = let code = @" -#r ""nuget:RestoreSources=https://dotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json"" #r ""nuget:Microsoft.ML,version=1.4.0-preview"" #r ""nuget:Microsoft.ML.AutoML,version=0.16.0-preview"" -#r ""nuget:Microsoft.Data.DataFrame,version=0.1.1-e191008-1"" +#r ""nuget:Microsoft.Data.Analysis,version=0.4.0"" open System open System.IO open System.Linq -open Microsoft.Data +open Microsoft.Data.Analysis let Shuffle (arr:int[]) = let rnd = Random() @@ -164,9 +218,9 @@ let Shuffle (arr:int[]) = arr let housingPath = ""housing.csv"" -let housingData = DataFrame.ReadCsv(housingPath) -let randomIndices = (Shuffle(Enumerable.Range(0, (int (housingData.RowCount) - 1)).ToArray())) -let testSize = int (float (housingData.RowCount) * 0.1) +let housingData = DataFrame.LoadCsv(housingPath) +let randomIndices = (Shuffle(Enumerable.Range(0, (int (housingData.Rows.Count) - 1)).ToArray())) +let testSize = int (float (housingData.Rows.Count) * 0.1) let trainRows = randomIndices.[testSize..] let testRows = randomIndices.[..testSize] let housing_train = housingData.[trainRows] @@ -183,15 +237,101 @@ printfn ""%A"" result 123 " use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) - let mutable assemblyRefCount = 0; - Event.add (fun _ -> assemblyRefCount <- assemblyRefCount + 1) script.AssemblyReferenceAdded let opt = script.Eval(code) |> getValue let value = opt.Value - Assert.AreEqual(123, value.ReflectionValue :?> int32) + Assert.Equal(123, value.ReflectionValue :?> int32) #endif - [] - member __.``Simple pinvoke should not be impacted by native resolver``() = + [] + member _.``Eval script with package manager invalid key``() = + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let result, _errors = script.Eval(@"#r ""nugt:FSharp.Data""") + match result with + | Ok(_) -> Assert.False(true, "expected a failure") + | Error(ex) -> Assert.IsAssignableFrom(typeof, ex) + + [] + member _.``Eval script with invalid PackageName should fail immediately``() = + use output = new RedirectConsoleOutput() + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let mutable found = 0 + let outp = System.Collections.Generic.List() + output.OutputProduced.Add( + fun line -> + if line.Contains("error NU1101:") && line.Contains("FSharp.Really.Not.A.Package") then + found <- found + 1 + outp.Add(line)) + let result, errors = script.Eval("""#r "nuget:FSharp.Really.Not.A.Package" """) + Assert.True( (found = 0), "Did not expect to see output contains 'error NU1101:' and 'FSharp.Really.Not.A.Package'") + Assert.True( errors |> Seq.exists (fun error -> error.Message.Contains("error NU1101:")), "Expect to error containing 'error NU1101:'") + Assert.True( errors |> Seq.exists (fun error -> error.Message.Contains("FSharp.Really.Not.A.Package")), "Expect to error containing 'FSharp.Really.Not.A.Package'") + + [] + member _.``Eval script with invalid PackageName should fail immediately and resolve one time only``() = + use output = new RedirectConsoleOutput() + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let mutable foundResolve = 0 + output.OutputProduced.Add (fun line -> if line.Contains("error NU1101:") then foundResolve <- foundResolve + 1) + let result, errors = + script.Eval(""" +#r "nuget:FSharp.Really.Not.A.Package" +#r "nuget:FSharp.Really.Not.Another.Package" + """) + Assert.True( (foundResolve = 0), (sprintf "Did not expected to see 'error NU1101:' in output" )) + Assert.Equal(2, (errors |> Seq.filter (fun error -> error.Message.Contains("error NU1101:")) |> Seq.length)) + Assert.Equal(1, (errors |> Seq.filter (fun error -> error.Message.Contains("FSharp.Really.Not.A.Package")) |> Seq.length)) + Assert.Equal(1, (errors |> Seq.filter (fun error -> error.Message.Contains("FSharp.Really.Not.Another.Package")) |> Seq.length)) + + [] + member _.``ML - use assembly with ref dependencies``() = + let code = """ +#r "nuget:Microsoft.ML.OnnxTransformer,1.4.0" +#r "nuget:System.Memory,4.5.4" + +open System +open System.Numerics.Tensors +let inputValues = [| 12.0; 10.0; 17.0; 5.0 |] +let tInput = new DenseTensor(inputValues.AsMemory(), new ReadOnlySpan([|4|])) +tInput.Length +""" + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let opt = script.Eval(code) |> getValue + let value = opt.Value + Assert.Equal(4L, downcast value.ReflectionValue) + + [] + member _.``System.Device.Gpio - Ensure we reference the runtime version of the assembly``() = + let code = """ +#r "nuget:System.Device.Gpio, 1.0.0" +typeof.Assembly.Location +""" + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let opt = script.Eval(code) |> getValue + let value = opt.Value + + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then + Assert.True( (value.ReflectionValue :?> string).EndsWith(@"runtimes\win\lib\netstandard2.0\System.Device.Gpio.dll") ) + else if RuntimeInformation.IsOSPlatform(OSPlatform.Linux) then + Assert.True( (value.ReflectionValue :?> string).EndsWith(@"runtimes/linux/lib/netstandard2.0/System.Device.Gpio.dll") ) + else + // Only Windows/Linux supported. + () + + [] + member _.``Reference -- Azure.ResourceManager.Resources``() = + let code = """ +#r "nuget: Azure.Identity, 1.3.0" +#r "nuget: Azure.ResourceManager.Resources, 1.0.0-preview.2" +let creds = Azure.Identity.DefaultAzureCredential() +let client = Azure.ResourceManager.Resources.ResourcesManagementClient("mySubscriptionId", creds) +true""" + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let opt = script.Eval(code) |> getValue + let value = opt.Value + Assert.True(true = downcast value.ReflectionValue) + + [] + member _.``Simple pinvoke should not be impacted by native resolver``() = let code = @" open System open System.Runtime.InteropServices @@ -211,15 +351,14 @@ else 123 " use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) - let mutable assemblyRefCount = 0; let opt = script.Eval(code) |> getValue let value = opt.Value - Assert.AreEqual(123, value.ReflectionValue :?> int32) + Assert.Equal(123, value.ReflectionValue :?> int32) - [] + [] member _.``Evaluation can be cancelled``() = use script = new FSharpScript() - let sleepTime = 10000 + let sleepTime = 10000L let mutable result = None let mutable wasCancelled = false use tokenSource = new CancellationTokenSource() @@ -236,10 +375,10 @@ else evalTask.GetAwaiter().GetResult() // ensure we cancelled and didn't complete the sleep or evaluation Assert.True(wasCancelled) - Assert.LessOrEqual(sw.ElapsedMilliseconds, sleepTime) - Assert.AreEqual(None, result) + Assert.Equal(sw.ElapsedMilliseconds, sleepTime) + Assert.Equal(None, result) - [] + [] member _.``Values bound at the root trigger an event``() = let mutable foundX = false let mutable foundY = false @@ -257,9 +396,9 @@ let y = 2 script.Eval(code) |> ignoreValue Assert.True(foundX) Assert.True(foundY) - Assert.AreEqual(2, foundCount) + Assert.Equal(2, foundCount) - [] + [] member _.``Values re-bound trigger an event``() = let mutable foundXCount = 0 use script = new FSharpScript() @@ -268,9 +407,9 @@ let y = 2 if name = "x" && typ = typeof then foundXCount <- foundXCount + 1) script.Eval("let x = 1") |> ignoreValue script.Eval("let x = 2") |> ignoreValue - Assert.AreEqual(2, foundXCount) + Assert.Equal(2, foundXCount) - [] + [] member _.``Nested let bindings don't trigger event``() = let mutable foundInner = false use script = new FSharpScript() @@ -284,3 +423,26 @@ let x = " script.Eval(code) |> ignoreValue Assert.False(foundInner) + + [] + member _.``Script with nuget package that yields out of order dependencies works correctly``() = + // regression test for: https://github.com/dotnet/fsharp/issues/9217 + let code = """ +#r "nuget: FParsec,1.1.1" + +open FParsec + +let test p str = + match run p str with + | Success(result, _, _) -> + printfn "Success: %A" result + true + | Failure(errorMsg, _, _) -> + printfn "Failure: %s" errorMsg + false +test pfloat "1.234" +""" + use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) + let opt = script.Eval(code) |> getValue + let value = opt.Value + Assert.True(true = downcast value.ReflectionValue) diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/TestHelpers.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/TestHelpers.fs deleted file mode 100644 index 9238ff490a8..00000000000 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/TestHelpers.fs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.Scripting.UnitTests - -open System -open FSharp.Compiler.Interactive.Shell -open FSharp.Compiler.SourceCodeServices - -[] -module TestHelpers = - - let getValue ((value: Result), (errors: FSharpErrorInfo[])) = - if errors.Length > 0 then - failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors)) - match value with - | Ok(value) -> value - | Error ex -> raise ex - - let ignoreValue = getValue >> ignore diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json b/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json new file mode 100644 index 00000000000..ff6ac3098c1 --- /dev/null +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/xunit.runner.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "appDomain": "denied", + "shadowCopy": false, + "parallelizeTestCollections": false, + "maxParallelThreads": 1 +} diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj new file mode 100644 index 00000000000..1b2fb76922e --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -0,0 +1,90 @@ + + + + Exe + net472;net5.0 + net5.0 + $(NoWarn);44;75; + true + false + true + nunit + + + + + + + + FsUnit.fs + + + Common.fs + + + AssemblyReaderShim.fs + + + ExtensionTypingProviderTests.fs + + + EditorTests.fs + + + Symbols.fs + + + FileSystemTests.fs + + + ProjectAnalysisTests.fs + + + MultiProjectAnalysisTests.fs + + + PerfTests.fs + + + InteractiveCheckerTests.fs + + + ExprTests.fs + + + CSharpProjectAnalysis.fs + + + StructureTests.fs + + + TokenizerTests.fs + + + ServiceUntypedParseTests.fs + + + TreeVisitorTests.fs + + + PatternMatchCompilationTests.fs + + + ScriptOptionsTests.fs + + + ParserTests.fs + + + Program.fs + + + + + + + + + + + diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected new file mode 100644 index 00000000000..3f21857e440 --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -0,0 +1,10998 @@ +FSharp.Compiler.AbstractIL.IL +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 CDecl +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 Default +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 FastCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 StdCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 ThisCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags: Int32 VarArg +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean Equals(ILArgConvention) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsCDecl +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsDefault +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsFastCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsStdCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsThisCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean IsVarArg +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsCDecl() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsDefault() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsFastCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsStdCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsThisCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Boolean get_IsVarArg() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: FSharp.Compiler.AbstractIL.IL+ILArgConvention+Tags +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention CDecl +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention Default +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention FastCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention StdCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention ThisCall +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention VarArg +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_CDecl() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_Default() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_FastCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_StdCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_ThisCall() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: ILArgConvention get_VarArg() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 CompareTo(ILArgConvention) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILArgConvention: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILArgConvention: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Boolean Equals(ILArrayShape) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: ILArrayShape FromRank(Int32) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: ILArrayShape SingleDimensional +FSharp.Compiler.AbstractIL.IL+ILArrayShape: ILArrayShape get_SingleDimensional() +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 CompareTo(ILArrayShape) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 Rank +FSharp.Compiler.AbstractIL.IL+ILArrayShape: Int32 get_Rank() +FSharp.Compiler.AbstractIL.IL+ILArrayShape: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Boolean Equals(ILAssemblyLongevity) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: ILAssemblyLongevity Default +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: ILAssemblyLongevity get_Default() +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Int32 CompareTo(ILAssemblyLongevity) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean DisableJitOptimizations +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean IgnoreSymbolStoreSequencePoints +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean JitTracking +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean Retargetable +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean get_DisableJitOptimizations() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean get_IgnoreSymbolStoreSequencePoints() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean get_JitTracking() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Boolean get_Retargetable() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAssemblyLongevity AssemblyLongevity +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAssemblyLongevity get_AssemblyLongevity() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILExportedTypesAndForwarders ExportedTypes +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILExportedTypesAndForwarders get_ExportedTypes() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILSecurityDecls SecurityDecls +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILSecurityDecls get_SecurityDecls() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILSecurityDeclsStored SecurityDeclsStored +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: ILSecurityDeclsStored get_SecurityDeclsStored() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Int32 AuxModuleHashAlgorithm +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Int32 get_AuxModuleHashAlgorithm() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILModuleRef] EntrypointElsewhere +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILModuleRef] get_EntrypointElsewhere() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo] Version +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo] get_Version() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] PublicKey +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_PublicKey() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[System.String] Locale +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Locale() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: System.String Name +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest: Void .ctor(System.String, Int32, ILSecurityDeclsStored, Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo], Microsoft.FSharp.Core.FSharpOption`1[System.String], ILAttributesStored, ILAssemblyLongevity, Boolean, Boolean, Boolean, Boolean, ILExportedTypesAndForwarders, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILModuleRef], Int32) +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Boolean EqualsIgnoringVersion(ILAssemblyRef) +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Boolean Retargetable +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Boolean get_Retargetable() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: ILAssemblyRef Create(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+PublicKey], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: ILAssemblyRef FromAssemblyName(System.Reflection.AssemblyName) +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo] Version +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILVersionInfo] get_Version() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+PublicKey] PublicKey +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+PublicKey] get_PublicKey() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] Hash +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_Hash() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[System.String] Locale +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Locale() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: System.String QualifiedName +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILAssemblyRef: System.String get_QualifiedName() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Array: ILType Item1 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Array: ILType get_Item1() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Array: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] Item2 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Array: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] get_Item2() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Bool: Boolean Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Bool: Boolean get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Byte: Byte Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Byte: Byte get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Char: Char Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Char: Char get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Double: Double Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Double: Double get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int16: Int16 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int16: Int16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int32: Int32 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int32: Int32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int64: Int64 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int64: Int64 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+SByte: SByte Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+SByte: SByte get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Single: Single Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Single: Single get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+String: Microsoft.FSharp.Core.FSharpOption`1[System.String] Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+String: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Array +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Bool +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Byte +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Char +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Double +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Int16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Int32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Int64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Null +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 SByte +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Single +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 String +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 Type +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 TypeRef +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 UInt16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 UInt32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags: Int32 UInt64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Type: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+Type: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+TypeRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeRef] Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+TypeRef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeRef] get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt16: UInt16 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt16: UInt16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt32: UInt32 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt32: UInt32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt64: UInt64 Item +FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt64: UInt64 get_Item() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean Equals(ILAttribElem) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsArray +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsBool +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsByte +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsChar +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsDouble +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsInt16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsInt32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsInt64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsNull +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsSByte +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsSingle +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsString +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsType +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsTypeRef +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsUInt16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsUInt32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean IsUInt64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsArray() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsBool() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsByte() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsChar() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsDouble() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsInt16() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsInt32() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsInt64() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsNull() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsSByte() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsSingle() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsString() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsType() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsTypeRef() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsUInt16() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsUInt32() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Boolean get_IsUInt64() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Array +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Bool +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Byte +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Char +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Double +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Int64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+SByte +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Single +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+String +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Tags +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+Type +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+TypeRef +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt16 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt32 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: FSharp.Compiler.AbstractIL.IL+ILAttribElem+UInt64 +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewArray(ILType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem]) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewBool(Boolean) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewByte(Byte) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewChar(Char) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewDouble(Double) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewInt16(Int16) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewInt32(Int32) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewInt64(Int64) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewSByte(SByte) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewSingle(Single) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewString(Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewType(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewTypeRef(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeRef]) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewUInt16(UInt16) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewUInt32(UInt32) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem NewUInt64(UInt64) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem Null +FSharp.Compiler.AbstractIL.IL+ILAttribElem: ILAttribElem get_Null() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 CompareTo(ILAttribElem) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILAttribElem: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILAttribElem: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: ILMethodSpec get_method() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: ILMethodSpec method +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] fixedArgs +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] get_fixedArgs() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`4[System.String,FSharp.Compiler.AbstractIL.IL+ILType,System.Boolean,FSharp.Compiler.AbstractIL.IL+ILAttribElem]] get_namedArgs() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`4[System.String,FSharp.Compiler.AbstractIL.IL+ILType,System.Boolean,FSharp.Compiler.AbstractIL.IL+ILAttribElem]] namedArgs +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: Byte[] data +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: Byte[] get_data() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: ILMethodSpec get_method() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: ILMethodSpec method +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] elements +FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem] get_elements() +FSharp.Compiler.AbstractIL.IL+ILAttribute+Tags: Int32 Decoded +FSharp.Compiler.AbstractIL.IL+ILAttribute+Tags: Int32 Encoded +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean Equals(ILAttribute) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean IsDecoded +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean IsEncoded +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean get_IsDecoded() +FSharp.Compiler.AbstractIL.IL+ILAttribute: Boolean get_IsEncoded() +FSharp.Compiler.AbstractIL.IL+ILAttribute: FSharp.Compiler.AbstractIL.IL+ILAttribute+Decoded +FSharp.Compiler.AbstractIL.IL+ILAttribute: FSharp.Compiler.AbstractIL.IL+ILAttribute+Encoded +FSharp.Compiler.AbstractIL.IL+ILAttribute: FSharp.Compiler.AbstractIL.IL+ILAttribute+Tags +FSharp.Compiler.AbstractIL.IL+ILAttribute: ILAttribute NewDecoded(ILMethodSpec, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem], Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`4[System.String,FSharp.Compiler.AbstractIL.IL+ILType,System.Boolean,FSharp.Compiler.AbstractIL.IL+ILAttribElem]]) +FSharp.Compiler.AbstractIL.IL+ILAttribute: ILAttribute NewEncoded(ILMethodSpec, Byte[], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribElem]) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 CompareTo(ILAttribute) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILAttribute: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILAttribute: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILAttributes: ILAttribute[] AsArray +FSharp.Compiler.AbstractIL.IL+ILAttributes: ILAttribute[] get_AsArray() +FSharp.Compiler.AbstractIL.IL+ILAttributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribute] AsList +FSharp.Compiler.AbstractIL.IL+ILAttributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribute] get_AsList() +FSharp.Compiler.AbstractIL.IL+ILAttributesStored: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(ILCallingConv) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILArgConvention Item2 +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILArgConvention get_Item2() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILCallingConv Instance +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILCallingConv NewCallconv(ILThisConvention, ILArgConvention) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILCallingConv Static +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILCallingConv get_Instance() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILCallingConv get_Static() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILThisConvention Item1 +FSharp.Compiler.AbstractIL.IL+ILCallingConv: ILThisConvention get_Item1() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 CompareTo(ILCallingConv) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILCallingConv: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILCallingConv: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Boolean Equals(ILCallingSignature) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: ILCallingConv CallingConv +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: ILCallingConv get_CallingConv() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: ILType ReturnType +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: ILType get_ReturnType() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Int32 CompareTo(ILCallingSignature) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] ArgTypes +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_ArgTypes() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILCallingSignature: Void .ctor(ILCallingConv, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], ILType) +FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportNamespace: System.String get_targetNamespace() +FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportNamespace: System.String targetNamespace +FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportType: ILType get_targetType() +FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportType: ILType targetType +FSharp.Compiler.AbstractIL.IL+ILDebugImport+Tags: Int32 ImportNamespace +FSharp.Compiler.AbstractIL.IL+ILDebugImport+Tags: Int32 ImportType +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Boolean IsImportNamespace +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Boolean IsImportType +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Boolean get_IsImportNamespace() +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Boolean get_IsImportType() +FSharp.Compiler.AbstractIL.IL+ILDebugImport: FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportNamespace +FSharp.Compiler.AbstractIL.IL+ILDebugImport: FSharp.Compiler.AbstractIL.IL+ILDebugImport+ImportType +FSharp.Compiler.AbstractIL.IL+ILDebugImport: FSharp.Compiler.AbstractIL.IL+ILDebugImport+Tags +FSharp.Compiler.AbstractIL.IL+ILDebugImport: ILDebugImport NewImportNamespace(System.String) +FSharp.Compiler.AbstractIL.IL+ILDebugImport: ILDebugImport NewImportType(ILType) +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILDebugImport: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILDebugImport: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILDebugImports: ILDebugImport[] Imports +FSharp.Compiler.AbstractIL.IL+ILDebugImports: ILDebugImport[] get_Imports() +FSharp.Compiler.AbstractIL.IL+ILDebugImports: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILDebugImports] Parent +FSharp.Compiler.AbstractIL.IL+ILDebugImports: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILDebugImports] get_Parent() +FSharp.Compiler.AbstractIL.IL+ILDebugImports: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILDebugImports: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILDebugImports], ILDebugImport[]) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding+Tags: Int32 Ansi +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding+Tags: Int32 Auto +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding+Tags: Int32 Unicode +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean Equals(ILDefaultPInvokeEncoding) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean IsAnsi +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean IsAuto +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean IsUnicode +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean get_IsAnsi() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean get_IsAuto() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Boolean get_IsUnicode() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding+Tags +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding Ansi +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding Auto +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding Unicode +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding get_Ansi() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding get_Auto() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: ILDefaultPInvokeEncoding get_Unicode() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 CompareTo(ILDefaultPInvokeEncoding) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean IsRTSpecialName +FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean IsSpecialName +FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsRTSpecialName() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Boolean get_IsSpecialName() +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef AddMethod +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef RemoveMethod +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_AddMethod() +FSharp.Compiler.AbstractIL.IL+ILEventDef: ILMethodRef get_RemoveMethod() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] OtherMethods +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_OtherMethods() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] FireMethod +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_FireMethod() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] EventType +FSharp.Compiler.AbstractIL.IL+ILEventDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] get_EventType() +FSharp.Compiler.AbstractIL.IL+ILEventDef: System.Reflection.EventAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILEventDef: System.Reflection.EventAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILEventDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILEventDef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILEventDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILEventDef: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], System.String, System.Reflection.EventAttributes, ILMethodRef, ILMethodRef, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef], ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILEventDefs: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: Boolean IsForwarder +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: Boolean get_IsForwarder() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILNestedExportedTypes Nested +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILNestedExportedTypes get_Nested() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILScopeRef ScopeRef +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILScopeRef get_ScopeRef() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILTypeDefAccess Access +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: ILTypeDefAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: System.Reflection.TypeAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: System.Reflection.TypeAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: System.String Name +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder: Void .ctor(ILScopeRef, System.String, System.Reflection.TypeAttributes, ILNestedExportedTypes, ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: Boolean Equals(ILExportedTypesAndForwarders) +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean IsInitOnly +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean IsLiteral +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean IsSpecialName +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean IsStatic +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean NotSerialized +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsInitOnly() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsLiteral() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsSpecialName() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_IsStatic() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Boolean get_NotSerialized() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess Access +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILMemberAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType FieldType +FSharp.Compiler.AbstractIL.IL+ILFieldDef: ILType get_FieldType() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] LiteralValue +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] get_LiteralValue() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Marshal +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] get_Marshal() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] Data +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_Data() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] Offset +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_Offset() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: System.Reflection.FieldAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILFieldDef: System.Reflection.FieldAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILFieldDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILFieldDef: Void .ctor(System.String, ILType, System.Reflection.FieldAttributes, Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType], ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: Boolean Equals(ILFieldDefs) +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldDefs: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Bool: Boolean Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Bool: Boolean get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Char: UInt16 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Char: UInt16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Double: Double Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Double: Double get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int16: Int16 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int16: Int16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int32: Int32 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int32: Int32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int64: Int64 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int64: Int64 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int8: SByte Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int8: SByte get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Single: Single Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Single: Single get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+String: System.String Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+String: System.String get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Bool +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Char +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Double +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Int16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Int32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Int64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Int8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Null +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 Single +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 String +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 UInt16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 UInt32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 UInt64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags: Int32 UInt8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt16: UInt16 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt16: UInt16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt32: UInt32 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt32: UInt32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt64: UInt64 Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt64: UInt64 get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt8: Byte Item +FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt8: Byte get_Item() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean Equals(ILFieldInit) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsBool +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsChar +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsDouble +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsInt16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsInt32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsInt64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsInt8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsNull +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsSingle +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsString +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsUInt16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsUInt32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsUInt64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean IsUInt8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsBool() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsChar() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsDouble() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsInt16() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsInt32() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsInt64() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsInt8() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsNull() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsSingle() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsString() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsUInt16() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsUInt32() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsUInt64() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Boolean get_IsUInt8() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Bool +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Char +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Double +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Int8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Single +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+String +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+Tags +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt16 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt32 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt64 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: FSharp.Compiler.AbstractIL.IL+ILFieldInit+UInt8 +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewBool(Boolean) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewChar(UInt16) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewDouble(Double) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewInt16(Int16) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewInt32(Int32) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewInt64(Int64) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewInt8(SByte) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewSingle(Single) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewString(System.String) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewUInt16(UInt16) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewUInt32(UInt32) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewUInt64(UInt64) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit NewUInt8(Byte) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit Null +FSharp.Compiler.AbstractIL.IL+ILFieldInit: ILFieldInit get_Null() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 CompareTo(ILFieldInit) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILFieldInit: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: System.Object AsObject() +FSharp.Compiler.AbstractIL.IL+ILFieldInit: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Boolean Equals(ILFieldRef) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: ILType Type +FSharp.Compiler.AbstractIL.IL+ILFieldRef: ILType get_Type() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: ILTypeRef DeclaringTypeRef +FSharp.Compiler.AbstractIL.IL+ILFieldRef: ILTypeRef get_DeclaringTypeRef() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Int32 CompareTo(ILFieldRef) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldRef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILFieldRef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILFieldRef: Void .ctor(ILTypeRef, System.String, ILType) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Boolean Equals(ILFieldSpec) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILFieldRef FieldRef +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILFieldRef get_FieldRef() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType ActualType +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType DeclaringType +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType FormalType +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType get_ActualType() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType get_DeclaringType() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILType get_FormalType() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILTypeRef DeclaringTypeRef +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: ILTypeRef get_DeclaringTypeRef() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Int32 CompareTo(ILFieldSpec) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: System.String Name +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILFieldSpec: Void .ctor(ILFieldRef, ILType) +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean HasDefaultConstructorConstraint +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean HasNotNullableValueTypeConstraint +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean HasReferenceTypeConstraint +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean get_HasDefaultConstructorConstraint() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean get_HasNotNullableValueTypeConstraint() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Boolean get_HasReferenceTypeConstraint() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILGenericVariance Variance +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: ILGenericVariance get_Variance() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Constraints +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Constraints() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef: Void .ctor(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], ILGenericVariance, Boolean, Boolean, Boolean, ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance+Tags: Int32 CoVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance+Tags: Int32 ContraVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance+Tags: Int32 NonVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean Equals(ILGenericVariance) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean IsCoVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean IsContraVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean IsNonVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean get_IsCoVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean get_IsContraVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Boolean get_IsNonVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: FSharp.Compiler.AbstractIL.IL+ILGenericVariance+Tags +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance CoVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance ContraVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance NonVariant +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance get_CoVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance get_ContraVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: ILGenericVariance get_NonVariant() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 CompareTo(ILGenericVariance) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILGenericVariance: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 Assembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 CompilerControlled +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 Family +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 FamilyAndAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 FamilyOrAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 Private +FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags: Int32 Public +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean Equals(ILMemberAccess) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsCompilerControlled +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsFamily +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsFamilyAndAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsFamilyOrAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsPrivate +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean IsPublic +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsAssembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsCompilerControlled() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsFamily() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsFamilyAndAssembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsFamilyOrAssembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsPrivate() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Boolean get_IsPublic() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: FSharp.Compiler.AbstractIL.IL+ILMemberAccess+Tags +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess Assembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess CompilerControlled +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess Family +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess FamilyAndAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess FamilyOrAssembly +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess Private +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess Public +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_Assembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_CompilerControlled() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_Family() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_FamilyAndAssembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_FamilyOrAssembly() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_Private() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: ILMemberAccess get_Public() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 CompareTo(ILMemberAccess) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILMemberAccess: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean HasSecurity +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsAbstract +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsAggressiveInline +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsCheckAccessOnOverride +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsClassInitializer +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsConstructor +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsEntryPoint +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsFinal +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsForwardRef +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsHideBySig +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsIL +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsInternalCall +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsManaged +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsMustRun +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsNewSlot +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsNoInline +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsNonVirtualInstance +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsPreserveSig +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsReqSecObj +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsSpecialName +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsStatic +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsSynchronized +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsUnmanagedExport +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsVirtual +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean IsZeroInit +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_HasSecurity() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsAbstract() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsAggressiveInline() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsCheckAccessOnOverride() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsClassInitializer() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsConstructor() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsEntryPoint() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsFinal() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsForwardRef() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsHideBySig() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsIL() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsInternalCall() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsManaged() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsMustRun() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsNewSlot() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsNoInline() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsNonVirtualInstance() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsPreserveSig() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsReqSecObj() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsSpecialName() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsStatic() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsSynchronized() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsUnmanagedExport() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsVirtual() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Boolean get_IsZeroInit() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv CallingConv +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingConv get_CallingConv() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingSignature CallingSignature +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILCallingSignature get_CallingSignature() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILMemberAccess Access +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILMemberAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILMethodBody MethodBody +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILMethodBody get_MethodBody() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILReturn Return +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILReturn get_Return() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls SecurityDecls +FSharp.Compiler.AbstractIL.IL+ILMethodDef: ILSecurityDecls get_SecurityDecls() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 MaxStack +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Int32 get_MaxStack() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody Body +FSharp.Compiler.AbstractIL.IL+ILMethodDef: MethodBody get_Body() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] get_GenericParams() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILLocal] Locals +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILLocal] get_Locals() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILParameter] Parameters +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILParameter] get_Parameters() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] ParameterTypes +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_ParameterTypes() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILCode] Code +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILCode] get_Code() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.Reflection.MethodAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.Reflection.MethodAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.Reflection.MethodImplAttributes ImplAttributes +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.Reflection.MethodImplAttributes get_ImplAttributes() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILMethodDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILMethodDef: Void .ctor(System.String, System.Reflection.MethodAttributes, System.Reflection.MethodImplAttributes, ILCallingConv, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILParameter], ILReturn, System.Lazy`1[FSharp.Compiler.AbstractIL.IL+MethodBody], Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], ILSecurityDecls, ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: ILMethodDef[] AsArray +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: ILMethodDef[] get_AsArray() +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] AsList +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] FindByName(System.String) +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] get_AsList() +FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] TryFindInstanceByNameAndCallingSignature(System.String, ILCallingSignature) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: ILMethodSpec OverrideBy +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: ILMethodSpec get_OverrideBy() +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: ILOverridesSpec Overrides +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: ILOverridesSpec get_Overrides() +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Int32 CompareTo(ILMethodImplDef) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Void .ctor(ILOverridesSpec, ILMethodSpec) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: Boolean Equals(ILMethodImplDefs) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Boolean Equals(ILMethodRef) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILCallingConv CallingConv +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILCallingConv get_CallingConv() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILCallingSignature CallingSignature +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILCallingSignature get_CallingSignature() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILMethodRef Create(ILTypeRef, ILCallingConv, System.String, Int32, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], ILType) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILType ReturnType +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILType get_ReturnType() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILTypeRef DeclaringTypeRef +FSharp.Compiler.AbstractIL.IL+ILMethodRef: ILTypeRef get_DeclaringTypeRef() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 ArgCount +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 CompareTo(ILMethodRef) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 GenericArity +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 get_ArgCount() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Int32 get_GenericArity() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] ArgTypes +FSharp.Compiler.AbstractIL.IL+ILMethodRef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_ArgTypes() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILMethodRef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMethodRef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Boolean Equals(ILMethodSpec) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILCallingConv CallingConv +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILCallingConv get_CallingConv() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILMethodRef MethodRef +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILMethodRef get_MethodRef() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILMethodSpec Create(ILType, ILMethodRef, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILType DeclaringType +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILType FormalReturnType +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILType get_DeclaringType() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: ILType get_FormalReturnType() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 CompareTo(ILMethodSpec) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 GenericArity +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Int32 get_GenericArity() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] FormalArgTypes +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] GenericArgs +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_FormalArgTypes() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_GenericArgs() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: System.String Name +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILMethodSpec: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean HasManifest +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean Is32Bit +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean Is32BitPreferred +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean Is64Bit +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean IsDLL +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean IsILOnly +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean UseHighEntropyVA +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_HasManifest() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_Is32Bit() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_Is32BitPreferred() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_Is64Bit() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_IsDLL() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_IsILOnly() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Boolean get_UseHighEntropyVA() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAssemblyManifest ManifestOfAssembly +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAssemblyManifest get_ManifestOfAssembly() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILResources Resources +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILResources get_Resources() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILTypeDefs TypeDefs +FSharp.Compiler.AbstractIL.IL+ILModuleDef: ILTypeDefs get_TypeDefs() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 ImageBase +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 PhysicalAlignment +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 SubSystemFlags +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 VirtualAlignment +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 get_ImageBase() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 get_PhysicalAlignment() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 get_SubSystemFlags() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Int32 get_VirtualAlignment() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILNativeResource] NativeResources +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILNativeResource] get_NativeResources() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest] Manifest +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest] get_Manifest() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPlatform] Platform +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPlatform] get_Platform() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] StackReserveSize +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_StackReserveSize() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.String MetadataVersion +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.String get_MetadataVersion() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.Tuple`2[System.Int32,System.Int32] SubsystemVersion +FSharp.Compiler.AbstractIL.IL+ILModuleDef: System.Tuple`2[System.Int32,System.Int32] get_SubsystemVersion() +FSharp.Compiler.AbstractIL.IL+ILModuleDef: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest], System.String, ILTypeDefs, System.Tuple`2[System.Int32,System.Int32], Boolean, Int32, Boolean, Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPlatform], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Boolean, Boolean, Boolean, Int32, Int32, Int32, System.String, ILResources, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILNativeResource], ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Boolean Equals(ILModuleRef) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Boolean HasMetadata +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Boolean get_HasMetadata() +FSharp.Compiler.AbstractIL.IL+ILModuleRef: ILModuleRef Create(System.String, Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]]) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Int32 CompareTo(ILModuleRef) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] Hash +FSharp.Compiler.AbstractIL.IL+ILModuleRef: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_Hash() +FSharp.Compiler.AbstractIL.IL+ILModuleRef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILModuleRef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILModuleRef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Boolean Equals(ILNativeResource) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Int32 CompareTo(ILNativeResource) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILNativeResource: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeResource: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Array: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Item1 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Array: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] get_Item1() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Array: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Int32]]] Item2 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Array: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Int32]]] get_Item2() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: Byte[] Item1 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: Byte[] cookieString +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: Byte[] get_Item1() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: Byte[] get_cookieString() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: System.String custMarshallerName +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: System.String get_custMarshallerName() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: System.String get_nativeTypeName() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom: System.String nativeTypeName +FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedArray: Int32 Item +FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedArray: Int32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedSysString: Int32 Item +FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedSysString: Int32 get_Item() +FSharp.Compiler.AbstractIL.IL+ILNativeType+SafeArray: ILNativeVariant Item1 +FSharp.Compiler.AbstractIL.IL+ILNativeType+SafeArray: ILNativeVariant get_Item1() +FSharp.Compiler.AbstractIL.IL+ILNativeType+SafeArray: Microsoft.FSharp.Core.FSharpOption`1[System.String] Item2 +FSharp.Compiler.AbstractIL.IL+ILNativeType+SafeArray: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Item2() +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 ANSIBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Array +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 AsAny +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 BSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Bool +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 ByValStr +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Byte +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Currency +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Custom +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Double +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Empty +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Error +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 FixedArray +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 FixedSysString +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 IDispatch +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 IUnknown +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Int +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Int16 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Int32 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Int64 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Int8 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Interface +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 LPSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 LPSTRUCT +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 LPTSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 LPUTF8STR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 LPWSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Method +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 SafeArray +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Single +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Struct +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 TBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 UInt +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 UInt16 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 UInt32 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 UInt64 +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 VariantBool +FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags: Int32 Void +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean Equals(ILNativeType) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsANSIBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsArray +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsAsAny +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsBool +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsByValStr +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsByte +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsCurrency +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsCustom +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsDouble +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsEmpty +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsError +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsFixedArray +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsFixedSysString +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsIDispatch +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsIUnknown +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInt +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInt16 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInt32 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInt64 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInt8 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsInterface +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsLPSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsLPSTRUCT +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsLPTSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsLPUTF8STR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsLPWSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsMethod +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsSafeArray +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsSingle +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsStruct +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsTBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsUInt +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsUInt16 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsUInt32 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsUInt64 +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsVariantBool +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean IsVoid +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsANSIBSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsArray() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsAsAny() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsBSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsBool() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsByValStr() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsByte() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsCurrency() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsCustom() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsDouble() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsEmpty() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsError() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsFixedArray() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsFixedSysString() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsIDispatch() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsIUnknown() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInt() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInt16() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInt32() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInt64() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInt8() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsInterface() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsLPSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsLPSTRUCT() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsLPTSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsLPUTF8STR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsLPWSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsMethod() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsSafeArray() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsSingle() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsStruct() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsTBSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsUInt() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsUInt16() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsUInt32() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsUInt64() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsVariantBool() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Boolean get_IsVoid() +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+Array +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+Custom +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedArray +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+FixedSysString +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+SafeArray +FSharp.Compiler.AbstractIL.IL+ILNativeType: FSharp.Compiler.AbstractIL.IL+ILNativeType+Tags +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType ANSIBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType AsAny +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType BSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Bool +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType ByValStr +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Byte +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Currency +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Double +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Empty +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Error +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType IDispatch +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType IUnknown +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Int +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Int16 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Int32 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Int64 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Int8 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Interface +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType LPSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType LPSTRUCT +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType LPTSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType LPUTF8STR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType LPWSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Method +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType NewArray(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Int32]]]) +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType NewCustom(Byte[], System.String, System.String, Byte[]) +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType NewFixedArray(Int32) +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType NewFixedSysString(Int32) +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType NewSafeArray(ILNativeVariant, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Single +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Struct +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType TBSTR +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType UInt +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType UInt16 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType UInt32 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType UInt64 +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType VariantBool +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType Void +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_ANSIBSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_AsAny() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_BSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Bool() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_ByValStr() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Byte() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Currency() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Double() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Empty() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Error() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_IDispatch() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_IUnknown() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Int() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Int16() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Int32() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Int64() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Int8() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Interface() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_LPSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_LPSTRUCT() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_LPTSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_LPUTF8STR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_LPWSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Method() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Single() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Struct() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_TBSTR() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_UInt() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_UInt16() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_UInt32() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_UInt64() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_VariantBool() +FSharp.Compiler.AbstractIL.IL+ILNativeType: ILNativeType get_Void() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 CompareTo(ILNativeType) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILNativeType: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILNativeType: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILMemberAccess Access +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILMemberAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILNestedExportedTypes Nested +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: ILNestedExportedTypes get_Nested() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: System.String Name +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedType: Void .ctor(System.String, ILMemberAccess, ILNestedExportedTypes, ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: Boolean Equals(ILNestedExportedTypes) +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean IsIn +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean IsOptional +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean IsOut +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean get_IsIn() +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean get_IsOptional() +FSharp.Compiler.AbstractIL.IL+ILParameter: Boolean get_IsOut() +FSharp.Compiler.AbstractIL.IL+ILParameter: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILParameter: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILParameter: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILParameter: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILParameter: ILType Type +FSharp.Compiler.AbstractIL.IL+ILParameter: ILType get_Type() +FSharp.Compiler.AbstractIL.IL+ILParameter: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILParameter: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] Default +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] get_Default() +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Marshal +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] get_Marshal() +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] Name +FSharp.Compiler.AbstractIL.IL+ILParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Name() +FSharp.Compiler.AbstractIL.IL+ILParameter: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILParameter: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[System.String], ILType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType], Boolean, Boolean, Boolean, ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Boolean Equals(ILPlatform) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Int32 CompareTo(ILPlatform) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILPlatform: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILPlatform: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILPlatform: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILPreTypeDef: ILTypeDef GetTypeDef() +FSharp.Compiler.AbstractIL.IL+ILPreTypeDef: Microsoft.FSharp.Collections.FSharpList`1[System.String] Namespace +FSharp.Compiler.AbstractIL.IL+ILPreTypeDef: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_Namespace() +FSharp.Compiler.AbstractIL.IL+ILPreTypeDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILPreTypeDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean IsRTSpecialName +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean IsSpecialName +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsRTSpecialName() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Boolean get_IsSpecialName() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention CallingConv +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILThisConvention get_CallingConv() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType PropertyType +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: ILType get_PropertyType() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Args +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Args() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] Init +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit] get_Init() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] GetMethod +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] SetMethod +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_GetMethod() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef] get_SetMethod() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: System.Reflection.PropertyAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: System.Reflection.PropertyAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILPropertyDef: Void .ctor(System.String, System.Reflection.PropertyAttributes, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodRef], ILThisConvention, ILType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldInit], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILPropertyDefs: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILResources: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILReturn: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILReturn: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILReturn: ILAttributesStored CustomAttrsStored +FSharp.Compiler.AbstractIL.IL+ILReturn: ILAttributesStored get_CustomAttrsStored() +FSharp.Compiler.AbstractIL.IL+ILReturn: ILReturn WithCustomAttrs(ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILReturn: ILType Type +FSharp.Compiler.AbstractIL.IL+ILReturn: ILType get_Type() +FSharp.Compiler.AbstractIL.IL+ILReturn: Int32 MetadataIndex +FSharp.Compiler.AbstractIL.IL+ILReturn: Int32 get_MetadataIndex() +FSharp.Compiler.AbstractIL.IL+ILReturn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] Marshal +FSharp.Compiler.AbstractIL.IL+ILReturn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType] get_Marshal() +FSharp.Compiler.AbstractIL.IL+ILReturn: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILReturn: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILNativeType], ILType, ILAttributesStored, Int32) +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Assembly: ILAssemblyRef Item +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Assembly: ILAssemblyRef get_Item() +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Module: ILModuleRef Item +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Module: ILModuleRef get_Item() +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Tags: Int32 Assembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Tags: Int32 Local +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Tags: Int32 Module +FSharp.Compiler.AbstractIL.IL+ILScopeRef+Tags: Int32 PrimaryAssembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean Equals(ILScopeRef) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean IsAssembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean IsLocal +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean IsLocalRef +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean IsModule +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean IsPrimaryAssembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean get_IsAssembly() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean get_IsLocal() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean get_IsLocalRef() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean get_IsModule() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Boolean get_IsPrimaryAssembly() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: FSharp.Compiler.AbstractIL.IL+ILScopeRef+Assembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef: FSharp.Compiler.AbstractIL.IL+ILScopeRef+Module +FSharp.Compiler.AbstractIL.IL+ILScopeRef: FSharp.Compiler.AbstractIL.IL+ILScopeRef+Tags +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef Local +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef NewAssembly(ILAssemblyRef) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef NewModule(ILModuleRef) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef PrimaryAssembly +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef get_Local() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: ILScopeRef get_PrimaryAssembly() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 CompareTo(ILScopeRef) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILScopeRef: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: System.String QualifiedName +FSharp.Compiler.AbstractIL.IL+ILScopeRef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILScopeRef: System.String get_QualifiedName() +FSharp.Compiler.AbstractIL.IL+ILSecurityDeclsStored: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Boolean Equals(ILSourceDocument) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: ILSourceDocument Create(Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]], System.String) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Int32 CompareTo(ILSourceDocument) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] DocumentType +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] Language +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] Vendor +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_DocumentType() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_Language() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: Microsoft.FSharp.Core.FSharpOption`1[System.Byte[]] get_Vendor() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: System.String File +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILSourceDocument: System.String get_File() +FSharp.Compiler.AbstractIL.IL+ILThisConvention+Tags: Int32 Instance +FSharp.Compiler.AbstractIL.IL+ILThisConvention+Tags: Int32 InstanceExplicit +FSharp.Compiler.AbstractIL.IL+ILThisConvention+Tags: Int32 Static +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean Equals(ILThisConvention) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean IsInstance +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean IsInstanceExplicit +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean IsStatic +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean get_IsInstance() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean get_IsInstanceExplicit() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Boolean get_IsStatic() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: FSharp.Compiler.AbstractIL.IL+ILThisConvention+Tags +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention Instance +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention InstanceExplicit +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention Static +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention get_Instance() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention get_InstanceExplicit() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: ILThisConvention get_Static() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 CompareTo(ILThisConvention) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILThisConvention: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILThisConvention: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILType+Array: ILArrayShape Item1 +FSharp.Compiler.AbstractIL.IL+ILType+Array: ILArrayShape get_Item1() +FSharp.Compiler.AbstractIL.IL+ILType+Array: ILType Item2 +FSharp.Compiler.AbstractIL.IL+ILType+Array: ILType get_Item2() +FSharp.Compiler.AbstractIL.IL+ILType+Boxed: ILTypeSpec Item +FSharp.Compiler.AbstractIL.IL+ILType+Boxed: ILTypeSpec get_Item() +FSharp.Compiler.AbstractIL.IL+ILType+Byref: ILType Item +FSharp.Compiler.AbstractIL.IL+ILType+Byref: ILType get_Item() +FSharp.Compiler.AbstractIL.IL+ILType+FunctionPointer: ILCallingSignature Item +FSharp.Compiler.AbstractIL.IL+ILType+FunctionPointer: ILCallingSignature get_Item() +FSharp.Compiler.AbstractIL.IL+ILType+Modified: Boolean Item1 +FSharp.Compiler.AbstractIL.IL+ILType+Modified: Boolean get_Item1() +FSharp.Compiler.AbstractIL.IL+ILType+Modified: ILType Item3 +FSharp.Compiler.AbstractIL.IL+ILType+Modified: ILType get_Item3() +FSharp.Compiler.AbstractIL.IL+ILType+Modified: ILTypeRef Item2 +FSharp.Compiler.AbstractIL.IL+ILType+Modified: ILTypeRef get_Item2() +FSharp.Compiler.AbstractIL.IL+ILType+Ptr: ILType Item +FSharp.Compiler.AbstractIL.IL+ILType+Ptr: ILType get_Item() +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Array +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Boxed +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Byref +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 FunctionPointer +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Modified +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Ptr +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 TypeVar +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Value +FSharp.Compiler.AbstractIL.IL+ILType+Tags: Int32 Void +FSharp.Compiler.AbstractIL.IL+ILType+TypeVar: UInt16 Item +FSharp.Compiler.AbstractIL.IL+ILType+TypeVar: UInt16 get_Item() +FSharp.Compiler.AbstractIL.IL+ILType+Value: ILTypeSpec Item +FSharp.Compiler.AbstractIL.IL+ILType+Value: ILTypeSpec get_Item() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean Equals(ILType) +FSharp.Compiler.AbstractIL.IL+ILType: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsArray +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsBoxed +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsByref +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsFunctionPointer +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsModified +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsNominal +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsPtr +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsTypeVar +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsTyvar +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsValue +FSharp.Compiler.AbstractIL.IL+ILType: Boolean IsVoid +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsArray() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsBoxed() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsByref() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsFunctionPointer() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsModified() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsNominal() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsPtr() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsTypeVar() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsTyvar() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsValue() +FSharp.Compiler.AbstractIL.IL+ILType: Boolean get_IsVoid() +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Array +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Boxed +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Byref +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+FunctionPointer +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Modified +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Ptr +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Tags +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+TypeVar +FSharp.Compiler.AbstractIL.IL+ILType: FSharp.Compiler.AbstractIL.IL+ILType+Value +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewArray(ILArrayShape, ILType) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewBoxed(ILTypeSpec) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewByref(ILType) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewFunctionPointer(ILCallingSignature) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewModified(Boolean, ILTypeRef, ILType) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewPtr(ILType) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewTypeVar(UInt16) +FSharp.Compiler.AbstractIL.IL+ILType: ILType NewValue(ILTypeSpec) +FSharp.Compiler.AbstractIL.IL+ILType: ILType Void +FSharp.Compiler.AbstractIL.IL+ILType: ILType get_Void() +FSharp.Compiler.AbstractIL.IL+ILType: ILTypeRef TypeRef +FSharp.Compiler.AbstractIL.IL+ILType: ILTypeRef get_TypeRef() +FSharp.Compiler.AbstractIL.IL+ILType: ILTypeSpec TypeSpec +FSharp.Compiler.AbstractIL.IL+ILType: ILTypeSpec get_TypeSpec() +FSharp.Compiler.AbstractIL.IL+ILType: Int32 CompareTo(ILType) +FSharp.Compiler.AbstractIL.IL+ILType: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILType: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILType: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILType: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILType: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] GenericArgs +FSharp.Compiler.AbstractIL.IL+ILType: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_GenericArgs() +FSharp.Compiler.AbstractIL.IL+ILType: System.String BasicQualifiedName +FSharp.Compiler.AbstractIL.IL+ILType: System.String QualifiedName +FSharp.Compiler.AbstractIL.IL+ILType: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILType: System.String get_BasicQualifiedName() +FSharp.Compiler.AbstractIL.IL+ILType: System.String get_QualifiedName() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean HasSecurity +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsAbstract +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsClass +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsComInterop +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsDelegate +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsEnum +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsInterface +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsSealed +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsSerializable +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsSpecialName +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsStruct +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean IsStructOrEnum +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_HasSecurity() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsAbstract() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsClass() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsComInterop() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsDelegate() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsEnum() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsInterface() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsSealed() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsSerializable() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsSpecialName() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStruct() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Boolean get_IsStructOrEnum() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes CustomAttrs +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILAttributes get_CustomAttrs() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding Encoding +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILDefaultPInvokeEncoding get_Encoding() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILEventDefs Events +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILEventDefs get_Events() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILFieldDefs Fields +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILFieldDefs get_Fields() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILMethodDefs Methods +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILMethodDefs get_Methods() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILMethodImplDefs MethodImpls +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILMethodImplDefs get_MethodImpls() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs Properties +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILPropertyDefs get_Properties() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls SecurityDecls +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILSecurityDecls get_SecurityDecls() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDef With(Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.TypeAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef]], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILFieldDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILEventDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDefs], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILAttributes], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecls]) +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess Access +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefAccess get_Access() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout Layout +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefLayout get_Layout() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs NestedTypes +FSharp.Compiler.AbstractIL.IL+ILTypeDef: ILTypeDefs get_NestedTypes() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] GenericParams +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef] get_GenericParams() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] Implements +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Implements() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] Extends +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType] get_Extends() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes Attributes +FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.Reflection.TypeAttributes get_Attributes() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILTypeDef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILTypeDef: Void .ctor(System.String, System.Reflection.TypeAttributes, ILTypeDefLayout, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILType], ILMethodDefs, ILTypeDefs, ILFieldDefs, ILMethodImplDefs, ILEventDefs, ILPropertyDefs, ILSecurityDecls, ILAttributes) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess Item +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested: ILMemberAccess get_Item() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags: Int32 Nested +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags: Int32 Private +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags: Int32 Public +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean Equals(ILTypeDefAccess) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean IsNested +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean IsPrivate +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean IsPublic +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean get_IsNested() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean get_IsPrivate() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Boolean get_IsPublic() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Nested +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess+Tags +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: ILTypeDefAccess NewNested(ILMemberAccess) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: ILTypeDefAccess Private +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: ILTypeDefAccess Public +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: ILTypeDefAccess get_Private() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: ILTypeDefAccess get_Public() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 CompareTo(ILTypeDefAccess) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags: Int32 Class +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags: Int32 Delegate +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags: Int32 Enum +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags: Int32 Interface +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags: Int32 ValueType +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean Equals(ILTypeDefKind) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean IsClass +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean IsDelegate +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean IsEnum +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean IsInterface +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean IsValueType +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean get_IsClass() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean get_IsDelegate() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean get_IsEnum() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean get_IsInterface() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Boolean get_IsValueType() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: FSharp.Compiler.AbstractIL.IL+ILTypeDefKind+Tags +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind Class +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind Delegate +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind Enum +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind Interface +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind ValueType +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind get_Class() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind get_Delegate() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind get_Enum() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind get_Interface() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: ILTypeDefKind get_ValueType() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 CompareTo(ILTypeDefKind) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILTypeDefKind: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Explicit: ILTypeDefLayoutInfo Item +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Explicit: ILTypeDefLayoutInfo get_Item() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential: ILTypeDefLayoutInfo Item +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential: ILTypeDefLayoutInfo get_Item() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Auto +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Explicit +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags: Int32 Sequential +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(ILTypeDefLayout) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsAuto +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsExplicit +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean IsSequential +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsAuto() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsExplicit() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Boolean get_IsSequential() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Explicit +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Sequential +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout+Tags +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout Auto +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout NewExplicit(ILTypeDefLayoutInfo) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout NewSequential(ILTypeDefLayoutInfo) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: ILTypeDefLayout get_Auto() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(ILTypeDefLayout) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 BeforeField +FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 OnAny +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean Equals(ILTypeInit) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean IsBeforeField +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean IsOnAny +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean get_IsBeforeField() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean get_IsOnAny() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags +FSharp.Compiler.AbstractIL.IL+ILTypeInit: ILTypeInit BeforeField +FSharp.Compiler.AbstractIL.IL+ILTypeInit: ILTypeInit OnAny +FSharp.Compiler.AbstractIL.IL+ILTypeInit: ILTypeInit get_BeforeField() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: ILTypeInit get_OnAny() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 CompareTo(ILTypeInit) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 Tag +FSharp.Compiler.AbstractIL.IL+ILTypeInit: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+ILTypeInit: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeRef: ILScopeRef Scope +FSharp.Compiler.AbstractIL.IL+ILTypeRef: ILScopeRef get_Scope() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: ILTypeRef Create(ILScopeRef, Microsoft.FSharp.Collections.FSharpList`1[System.String], System.String) +FSharp.Compiler.AbstractIL.IL+ILTypeRef: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: Microsoft.FSharp.Collections.FSharpList`1[System.String] Enclosing +FSharp.Compiler.AbstractIL.IL+ILTypeRef: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_Enclosing() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String BasicQualifiedName +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String FullName +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String Name +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String QualifiedName +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String get_BasicQualifiedName() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String get_FullName() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILTypeRef: System.String get_QualifiedName() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Boolean Equals(ILTypeSpec) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: ILScopeRef Scope +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: ILScopeRef get_Scope() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: ILTypeRef TypeRef +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: ILTypeRef get_TypeRef() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: ILTypeSpec Create(ILTypeRef, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType]) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Int32 CompareTo(ILTypeSpec) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] GenericArgs +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILType] get_GenericArgs() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Microsoft.FSharp.Collections.FSharpList`1[System.String] Enclosing +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_Enclosing() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: System.String FullName +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: System.String Name +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: System.String get_FullName() +FSharp.Compiler.AbstractIL.IL+ILTypeSpec: System.String get_Name() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Boolean Equals(ILVersionInfo) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Int32 CompareTo(ILVersionInfo) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: System.String ToString() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 Build +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 Major +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 Minor +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 Revision +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 get_Build() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 get_Major() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 get_Minor() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: UInt16 get_Revision() +FSharp.Compiler.AbstractIL.IL+ILVersionInfo: Void .ctor(UInt16, UInt16, UInt16, UInt16) +FSharp.Compiler.AbstractIL.IL+MethodBody+IL: System.Lazy`1[FSharp.Compiler.AbstractIL.IL+ILMethodBody] Item +FSharp.Compiler.AbstractIL.IL+MethodBody+IL: System.Lazy`1[FSharp.Compiler.AbstractIL.IL+ILMethodBody] get_Item() +FSharp.Compiler.AbstractIL.IL+MethodBody+PInvoke: System.Lazy`1[FSharp.Compiler.AbstractIL.IL+PInvokeMethod] Item +FSharp.Compiler.AbstractIL.IL+MethodBody+PInvoke: System.Lazy`1[FSharp.Compiler.AbstractIL.IL+PInvokeMethod] get_Item() +FSharp.Compiler.AbstractIL.IL+MethodBody+Tags: Int32 Abstract +FSharp.Compiler.AbstractIL.IL+MethodBody+Tags: Int32 IL +FSharp.Compiler.AbstractIL.IL+MethodBody+Tags: Int32 Native +FSharp.Compiler.AbstractIL.IL+MethodBody+Tags: Int32 NotAvailable +FSharp.Compiler.AbstractIL.IL+MethodBody+Tags: Int32 PInvoke +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean Equals(MethodBody) +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean IsAbstract +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean IsIL +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean IsNative +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean IsNotAvailable +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean IsPInvoke +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean get_IsAbstract() +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean get_IsIL() +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean get_IsNative() +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean get_IsNotAvailable() +FSharp.Compiler.AbstractIL.IL+MethodBody: Boolean get_IsPInvoke() +FSharp.Compiler.AbstractIL.IL+MethodBody: FSharp.Compiler.AbstractIL.IL+MethodBody+IL +FSharp.Compiler.AbstractIL.IL+MethodBody: FSharp.Compiler.AbstractIL.IL+MethodBody+PInvoke +FSharp.Compiler.AbstractIL.IL+MethodBody: FSharp.Compiler.AbstractIL.IL+MethodBody+Tags +FSharp.Compiler.AbstractIL.IL+MethodBody: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+MethodBody: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+MethodBody: Int32 Tag +FSharp.Compiler.AbstractIL.IL+MethodBody: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody Abstract +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody Native +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody NewIL(System.Lazy`1[FSharp.Compiler.AbstractIL.IL+ILMethodBody]) +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody NewPInvoke(System.Lazy`1[FSharp.Compiler.AbstractIL.IL+PInvokeMethod]) +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody NotAvailable +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody get_Abstract() +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody get_Native() +FSharp.Compiler.AbstractIL.IL+MethodBody: MethodBody get_NotAvailable() +FSharp.Compiler.AbstractIL.IL+MethodBody: System.String ToString() +FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKey: Byte[] Item +FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKey: Byte[] get_Item() +FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKeyToken: Byte[] Item +FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKeyToken: Byte[] get_Item() +FSharp.Compiler.AbstractIL.IL+PublicKey+Tags: Int32 PublicKey +FSharp.Compiler.AbstractIL.IL+PublicKey+Tags: Int32 PublicKeyToken +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean Equals(PublicKey) +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean IsKey +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean IsKeyToken +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean IsPublicKey +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean IsPublicKeyToken +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean get_IsKey() +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean get_IsKeyToken() +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean get_IsPublicKey() +FSharp.Compiler.AbstractIL.IL+PublicKey: Boolean get_IsPublicKeyToken() +FSharp.Compiler.AbstractIL.IL+PublicKey: Byte[] Key +FSharp.Compiler.AbstractIL.IL+PublicKey: Byte[] KeyToken +FSharp.Compiler.AbstractIL.IL+PublicKey: Byte[] get_Key() +FSharp.Compiler.AbstractIL.IL+PublicKey: Byte[] get_KeyToken() +FSharp.Compiler.AbstractIL.IL+PublicKey: FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKey +FSharp.Compiler.AbstractIL.IL+PublicKey: FSharp.Compiler.AbstractIL.IL+PublicKey+PublicKeyToken +FSharp.Compiler.AbstractIL.IL+PublicKey: FSharp.Compiler.AbstractIL.IL+PublicKey+Tags +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 CompareTo(PublicKey) +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 Tag +FSharp.Compiler.AbstractIL.IL+PublicKey: Int32 get_Tag() +FSharp.Compiler.AbstractIL.IL+PublicKey: PublicKey KeyAsToken(Byte[]) +FSharp.Compiler.AbstractIL.IL+PublicKey: PublicKey NewPublicKey(Byte[]) +FSharp.Compiler.AbstractIL.IL+PublicKey: PublicKey NewPublicKeyToken(Byte[]) +FSharp.Compiler.AbstractIL.IL+PublicKey: System.String ToString() +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILArgConvention +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILArrayShape +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAssemblyLongevity +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAssemblyManifest +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAssemblyRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAttribElem +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAttribute +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAttributes +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILAttributesStored +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILCallingConv +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILCallingSignature +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILDebugImport +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILDebugImports +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILDefaultPInvokeEncoding +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILEventDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILEventDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILExportedTypesAndForwarders +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILFieldDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILFieldDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILFieldInit +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILFieldRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILFieldSpec +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILGenericParameterDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILGenericVariance +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMemberAccess +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodImplDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodImplDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILMethodSpec +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILModuleDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILModuleRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILNativeResource +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILNativeType +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILNestedExportedType +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILNestedExportedTypes +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILParameter +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILPlatform +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILPreTypeDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILPropertyDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILPropertyDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILResources +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILReturn +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILScopeRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILSecurityDeclsStored +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILSourceDocument +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILThisConvention +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILType +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeDef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeDefAccess +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeDefKind +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeDefs +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeInit +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeRef +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILTypeSpec +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+ILVersionInfo +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+MethodBody +FSharp.Compiler.AbstractIL.IL: FSharp.Compiler.AbstractIL.IL+PublicKey +FSharp.Compiler.AbstractIL.IL: ILAttributes emptyILCustomAttrs +FSharp.Compiler.AbstractIL.IL: ILAttributes get_emptyILCustomAttrs() +FSharp.Compiler.AbstractIL.IL: ILAttributes mkILCustomAttrs(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAttribute]) +FSharp.Compiler.AbstractIL.IL: ILAttributes mkILCustomAttrsFromArray(ILAttribute[]) +FSharp.Compiler.AbstractIL.IL: ILAttributesStored storeILCustomAttrs(ILAttributes) +FSharp.Compiler.AbstractIL.IL: ILEventDefs emptyILEvents +FSharp.Compiler.AbstractIL.IL: ILEventDefs get_emptyILEvents() +FSharp.Compiler.AbstractIL.IL: ILEventDefs mkILEvents(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILEventDef]) +FSharp.Compiler.AbstractIL.IL: ILEventDefs mkILEventsLazy(System.Lazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILEventDef]]) +FSharp.Compiler.AbstractIL.IL: ILExportedTypesAndForwarders mkILExportedTypes(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILExportedTypeOrForwarder]) +FSharp.Compiler.AbstractIL.IL: ILFieldDefs emptyILFields +FSharp.Compiler.AbstractIL.IL: ILFieldDefs get_emptyILFields() +FSharp.Compiler.AbstractIL.IL: ILFieldDefs mkILFields(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILFieldDef]) +FSharp.Compiler.AbstractIL.IL: ILFieldDefs mkILFieldsLazy(System.Lazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILFieldDef]]) +FSharp.Compiler.AbstractIL.IL: ILMethodDefs emptyILMethods +FSharp.Compiler.AbstractIL.IL: ILMethodDefs get_emptyILMethods() +FSharp.Compiler.AbstractIL.IL: ILMethodDefs mkILMethods(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef]) +FSharp.Compiler.AbstractIL.IL: ILMethodDefs mkILMethodsComputed(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,FSharp.Compiler.AbstractIL.IL+ILMethodDef[]]) +FSharp.Compiler.AbstractIL.IL: ILMethodDefs mkILMethodsFromArray(ILMethodDef[]) +FSharp.Compiler.AbstractIL.IL: ILMethodImplDefs emptyILMethodImpls +FSharp.Compiler.AbstractIL.IL: ILMethodImplDefs get_emptyILMethodImpls() +FSharp.Compiler.AbstractIL.IL: ILMethodImplDefs mkILMethodImpls(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDef]) +FSharp.Compiler.AbstractIL.IL: ILMethodImplDefs mkILMethodImplsLazy(System.Lazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodImplDef]]) +FSharp.Compiler.AbstractIL.IL: ILModuleDef mkILSimpleModule(System.String, System.String, Boolean, System.Tuple`2[System.Int32,System.Int32], Boolean, ILTypeDefs, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.String], Int32, ILExportedTypesAndForwarders, System.String) +FSharp.Compiler.AbstractIL.IL: ILNestedExportedTypes mkILNestedExportedTypes(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILNestedExportedType]) +FSharp.Compiler.AbstractIL.IL: ILPropertyDefs emptyILProperties +FSharp.Compiler.AbstractIL.IL: ILPropertyDefs get_emptyILProperties() +FSharp.Compiler.AbstractIL.IL: ILPropertyDefs mkILProperties(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDef]) +FSharp.Compiler.AbstractIL.IL: ILPropertyDefs mkILPropertiesLazy(System.Lazy`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILPropertyDef]]) +FSharp.Compiler.AbstractIL.IL: ILResources emptyILResources +FSharp.Compiler.AbstractIL.IL: ILResources get_emptyILResources() +FSharp.Compiler.AbstractIL.IL: ILReturn mkILReturn(ILType) +FSharp.Compiler.AbstractIL.IL: ILSecurityDecls emptyILSecurityDecls +FSharp.Compiler.AbstractIL.IL: ILSecurityDecls get_emptyILSecurityDecls() +FSharp.Compiler.AbstractIL.IL: ILSecurityDecls mkILSecurityDecls(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILSecurityDecl]) +FSharp.Compiler.AbstractIL.IL: ILSecurityDeclsStored storeILSecurityDecls(ILSecurityDecls) +FSharp.Compiler.AbstractIL.IL: ILTypeDefs emptyILTypeDefs +FSharp.Compiler.AbstractIL.IL: ILTypeDefs get_emptyILTypeDefs() +FSharp.Compiler.AbstractIL.IL: ILTypeDefs mkILTypeDefs(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILTypeDef]) +FSharp.Compiler.AbstractIL.IL: ILTypeDefs mkILTypeDefsComputed(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,FSharp.Compiler.AbstractIL.IL+ILPreTypeDef[]]) +FSharp.Compiler.AbstractIL.IL: ILTypeDefs mkILTypeDefsFromArray(ILTypeDef[]) +FSharp.Compiler.AbstractIL.IL: Int32 NoMetadataIdx +FSharp.Compiler.AbstractIL.IL: Int32 get_NoMetadataIdx() +FSharp.Compiler.AbstractIL.ILBinaryReader +FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader: ILModuleDef ILModuleDef +FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader: ILModuleDef get_ILModuleDef() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAssemblyRef] ILAssemblyRefs +FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILAssemblyRef] get_ILAssemblyRefs() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: MetadataOnlyFlag get_metadataOnly() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: MetadataOnlyFlag metadataOnly +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.String,System.DateTime],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.IntPtr,System.Int32]]] get_tryGetMetadataSnapshot() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.String,System.DateTime],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.IntPtr,System.Int32]]] tryGetMetadataSnapshot +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_pdbDirPath() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: Microsoft.FSharp.Core.FSharpOption`1[System.String] pdbDirPath +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: ReduceMemoryFlag get_reduceMemoryUsage() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: ReduceMemoryFlag reduceMemoryUsage +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: System.String ToString() +FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[System.String], ReduceMemoryFlag, MetadataOnlyFlag, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.String,System.DateTime],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.IntPtr,System.Int32]]]) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag+Tags: Int32 No +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag+Tags: Int32 Yes +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean Equals(MetadataOnlyFlag) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean IsNo +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean IsYes +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean get_IsNo() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Boolean get_IsYes() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag+Tags +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 CompareTo(MetadataOnlyFlag) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 Tag +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: Int32 get_Tag() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: MetadataOnlyFlag No +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: MetadataOnlyFlag Yes +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: MetadataOnlyFlag get_No() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: MetadataOnlyFlag get_Yes() +FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag: System.String ToString() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag+Tags: Int32 No +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag+Tags: Int32 Yes +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean Equals(ReduceMemoryFlag) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean Equals(System.Object) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean IsNo +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean IsYes +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean get_IsNo() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Boolean get_IsYes() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag+Tags +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 CompareTo(ReduceMemoryFlag) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 CompareTo(System.Object) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 GetHashCode() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 Tag +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: Int32 get_Tag() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: ReduceMemoryFlag No +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: ReduceMemoryFlag Yes +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: ReduceMemoryFlag get_No() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: ReduceMemoryFlag get_Yes() +FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag: System.String ToString() +FSharp.Compiler.AbstractIL.ILBinaryReader+Shim+IAssemblyReader: ILModuleReader GetILModuleReader(System.String, ILReaderOptions) +FSharp.Compiler.AbstractIL.ILBinaryReader+Shim: FSharp.Compiler.AbstractIL.ILBinaryReader+Shim+IAssemblyReader +FSharp.Compiler.AbstractIL.ILBinaryReader+Shim: IAssemblyReader AssemblyReader +FSharp.Compiler.AbstractIL.ILBinaryReader+Shim: IAssemblyReader get_AssemblyReader() +FSharp.Compiler.AbstractIL.ILBinaryReader+Shim: Void set_AssemblyReader(IAssemblyReader) +FSharp.Compiler.AbstractIL.ILBinaryReader: FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader +FSharp.Compiler.AbstractIL.ILBinaryReader: FSharp.Compiler.AbstractIL.ILBinaryReader+ILReaderOptions +FSharp.Compiler.AbstractIL.ILBinaryReader: FSharp.Compiler.AbstractIL.ILBinaryReader+MetadataOnlyFlag +FSharp.Compiler.AbstractIL.ILBinaryReader: FSharp.Compiler.AbstractIL.ILBinaryReader+ReduceMemoryFlag +FSharp.Compiler.AbstractIL.ILBinaryReader: FSharp.Compiler.AbstractIL.ILBinaryReader+Shim +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Succeeded: FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults Item +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Succeeded: FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults get_Item() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Tags: Int32 Aborted +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Tags: Int32 Succeeded +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean Equals(FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean Equals(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean IsAborted +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean IsSucceeded +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean get_IsAborted() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Boolean get_IsSucceeded() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer Aborted +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer NewSucceeded(FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer get_Aborted() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Succeeded +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer+Tags +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 GetHashCode() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 Tag +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: Int32 get_Tag() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean HasFullTypeCheckInfo +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean IsRelativeNameResolvableFromSymbol(FSharp.Compiler.Text.Position, Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Boolean get_HasFullTypeCheckInfo() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext ProjectContext +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext get_ProjectContext() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.CodeAnalysis.FSharpSymbolUse[] GetUsesOfSymbolInFile(FSharp.Compiler.Symbols.FSharpSymbol, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] Diagnostics +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] get_Diagnostics() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.EditorServices.DeclarationListInfo GetDeclarationListInfo(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.EditorServices.FindDeclResult GetDeclarationLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.EditorServices.MethodGroup GetMethods(Int32, Int32, System.String, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.EditorServices.SemanticClassificationItem[] GetSemanticClassification(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.EditorServices.ToolTipText GetToolTip(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Int32) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpAssemblySignature PartialAssemblySignature +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpAssemblySignature get_PartialAssemblySignature() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] OpenDeclarations +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] get_OpenDeclarations() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Text.Range[] GetFormatSpecifierLocations() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetDeclarationListSymbols(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUseAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFile +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFile() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetMethodsAsSymbols(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetF1Keyword(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetAllUsesOfAllSymbolsInFile(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.String[] DependencyFiles +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.String[] get_DependencyFiles() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.Tuple`2[FSharp.Compiler.Text.Range,System.Int32][] GetFormatSpecifierLocationsAndArity() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: Boolean HasCriticalErrors +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: Boolean get_HasCriticalErrors() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext ProjectContext +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.CodeAnalysis.FSharpProjectContext get_ProjectContext() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.CodeAnalysis.FSharpSymbolUse[] GetAllUsesOfAllSymbols(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.CodeAnalysis.FSharpSymbolUse[] GetUsesOfSymbol(FSharp.Compiler.Symbols.FSharpSymbol, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] Diagnostics +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] get_Diagnostics() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Symbols.FSharpAssemblyContents AssemblyContents +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Symbols.FSharpAssemblyContents GetOptimizedAssemblyContents() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Symbols.FSharpAssemblyContents get_AssemblyContents() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Symbols.FSharpAssemblySignature AssemblySignature +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: FSharp.Compiler.Symbols.FSharpAssemblySignature get_AssemblySignature() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: System.String[] DependencyFiles +FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults: System.String[] get_DependencyFiles() +FSharp.Compiler.CodeAnalysis.FSharpChecker +FSharp.Compiler.CodeAnalysis.FSharpChecker: FSharp.Compiler.CodeAnalysis.FSharpChecker Create(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.String,System.DateTime],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.IntPtr,System.Int32]]]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: FSharp.Compiler.CodeAnalysis.FSharpChecker Instance +FSharp.Compiler.CodeAnalysis.FSharpChecker: FSharp.Compiler.CodeAnalysis.FSharpChecker get_Instance() +FSharp.Compiler.CodeAnalysis.FSharpChecker: FSharp.Compiler.CodeAnalysis.FSharpProjectOptions GetProjectOptionsFromCommandLineArgs(System.String, System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: FSharp.Compiler.Tokenization.FSharpTokenInfo[][] TokenizeFile(System.String) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 ActualCheckFileCount +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 ActualParseFileCount +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 MaxMemory +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 get_ActualCheckFileCount() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 get_ActualParseFileCount() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Int32 get_MaxMemory() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer] CheckFileInProject(FSharp.Compiler.CodeAnalysis.FSharpParseFileResults, System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults] ParseAndCheckProject(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults] GetBackgroundParseResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults] ParseFile(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults] ParseFileInProject(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer]] CheckFileInProjectAllowingStaleCachedResults(FSharp.Compiler.CodeAnalysis.FSharpParseFileResults, System.String, Int32, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.SemanticClassificationView]] GetBackgroundSemanticClassificationForFile(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] NotifyProjectCleaned(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Text.Range]] FindBackgroundReferencesInFile(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, FSharp.Compiler.Symbols.FSharpSymbol, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileAnswer]] ParseAndCheckFileInProject(System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedInput], System.String, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`3[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.Assembly]]] CompileToDynamicAssembly(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedInput], System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.IO.TextWriter,System.IO.TextWriter]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`3[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.Assembly]]] CompileToDynamicAssembly(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.IO.TextWriter,System.IO.TextWriter]], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] get_ProjectChecked() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.Unit] MaxMemoryReached +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.Unit] get_MaxMemoryReached() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] BeforeBackgroundFileCheck +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] FileChecked +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] FileParsed +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] get_BeforeBackgroundFileCheck() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] get_FileChecked() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]],System.Tuple`2[System.String,FSharp.Compiler.CodeAnalysis.FSharpProjectOptions]] get_FileParsed() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults,System.Int64]] TryGetRecentCheckResultsForFile(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParsingOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]] GetParsingOptionsFromCommandLineArgs(Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParsingOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]] GetParsingOptionsFromCommandLineArgs(Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParsingOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]] GetParsingOptionsFromProjectOptions(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions) +FSharp.Compiler.CodeAnalysis.FSharpChecker: System.Tuple`2[FSharp.Compiler.Tokenization.FSharpTokenInfo[],FSharp.Compiler.Tokenization.FSharpTokenizerLexState] TokenizeLine(System.String, FSharp.Compiler.Tokenization.FSharpTokenizerLexState) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Void ClearCache(System.Collections.Generic.IEnumerable`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Void ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Void InvalidateAll() +FSharp.Compiler.CodeAnalysis.FSharpChecker: Void InvalidateConfiguration(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CodeAnalysis.FSharpChecker: Void set_MaxMemory(Int32) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean IsBindingALambdaAtPosition(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean IsPosContainedInApplication(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean IsPositionContainedInACurriedParameter(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean IsTypeAnnotationGivenAtPosition(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean ParseHadErrors +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Boolean get_ParseHadErrors() +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] Diagnostics +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: FSharp.Compiler.Diagnostics.FSharpDiagnostic[] get_Diagnostics() +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: FSharp.Compiler.EditorServices.NavigationItems GetNavigationItems() +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: FSharp.Compiler.Syntax.ParsedInput ParseTree +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: FSharp.Compiler.Syntax.ParsedInput get_ParseTree() +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.ParameterLocations] FindParameterLocations(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfExprInYieldOrReturn(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfExpressionBeingDereferencedContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfFunctionOrMethodBeingApplied(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfNameOfNearestOuterBindingContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRecordExpressionContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRefCellDereferenceContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ValidateBreakpointLocation(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] GetAllArgumentsForFunctionApplicationAtPostion(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,System.Int32]] TryIdentOfPipelineContainingPosAndNumArgsApplied(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range]] TryRangeOfParenEnclosingOpEqualsGreaterUsage(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: System.String FileName +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: System.String get_FileName() +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: System.String[] DependencyFiles +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: System.String[] get_DependencyFiles() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean CompilingFsLib +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean Equals(FSharp.Compiler.CodeAnalysis.FSharpParsingOptions) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean Equals(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean IsExe +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean IsInteractive +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean get_CompilingFsLib() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean get_IsExe() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Boolean get_IsInteractive() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: FSharp.Compiler.CodeAnalysis.FSharpParsingOptions Default +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: FSharp.Compiler.CodeAnalysis.FSharpParsingOptions get_Default() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions ErrorSeverityOptions +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions get_ErrorSeverityOptions() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Int32 CompareTo(FSharp.Compiler.CodeAnalysis.FSharpParsingOptions) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Int32 CompareTo(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Int32 GetHashCode() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Microsoft.FSharp.Collections.FSharpList`1[System.String] ConditionalCompilationDefines +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_ConditionalCompilationDefines() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Microsoft.FSharp.Core.FSharpOption`1[System.Boolean] LightSyntax +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Microsoft.FSharp.Core.FSharpOption`1[System.Boolean] get_LightSyntax() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: System.String LangVersionText +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: System.String get_LangVersionText() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: System.String[] SourceFiles +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: System.String[] get_SourceFiles() +FSharp.Compiler.CodeAnalysis.FSharpParsingOptions: Void .ctor(System.String[], Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions, System.String, Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Boolean, Boolean) +FSharp.Compiler.CodeAnalysis.FSharpProjectContext +FSharp.Compiler.CodeAnalysis.FSharpProjectContext: FSharp.Compiler.CodeAnalysis.FSharpProjectOptions ProjectOptions +FSharp.Compiler.CodeAnalysis.FSharpProjectContext: FSharp.Compiler.CodeAnalysis.FSharpProjectOptions get_ProjectOptions() +FSharp.Compiler.CodeAnalysis.FSharpProjectContext: FSharp.Compiler.Symbols.FSharpAccessibilityRights AccessibilityRights +FSharp.Compiler.CodeAnalysis.FSharpProjectContext: FSharp.Compiler.Symbols.FSharpAccessibilityRights get_AccessibilityRights() +FSharp.Compiler.CodeAnalysis.FSharpProjectContext: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpAssembly] GetReferencedAssemblies() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean Equals(FSharp.Compiler.CodeAnalysis.FSharpProjectOptions) +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean Equals(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean IsIncompleteTypeCheckEnvironment +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean UseScriptResolutionRules +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean get_IsIncompleteTypeCheckEnvironment() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Boolean get_UseScriptResolutionRules() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: FSharp.Compiler.CodeAnalysis.FSharpReferencedProject[] ReferencedProjects +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: FSharp.Compiler.CodeAnalysis.FSharpReferencedProject[] get_ReferencedProjects() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Int32 GetHashCode() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Text.Range,System.String,System.String]] OriginalLoadReferences +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Text.Range,System.String,System.String]] get_OriginalLoadReferences() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet] UnresolvedReferences +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet] get_UnresolvedReferences() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[System.Int64] Stamp +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[System.Int64] get_Stamp() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[System.String] ProjectId +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_ProjectId() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.DateTime LoadTime +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.DateTime get_LoadTime() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String ProjectFileName +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String get_ProjectFileName() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String[] OtherOptions +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String[] SourceFiles +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String[] get_OtherOptions() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: System.String[] get_SourceFiles() +FSharp.Compiler.CodeAnalysis.FSharpProjectOptions: Void .ctor(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.String], System.String[], System.String[], FSharp.Compiler.CodeAnalysis.FSharpReferencedProject[], Boolean, Boolean, System.DateTime, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet], Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Text.Range,System.String,System.String]], Microsoft.FSharp.Core.FSharpOption`1[System.Int64]) +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: Boolean Equals(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: FSharp.Compiler.CodeAnalysis.FSharpReferencedProject CreateFSharp(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions) +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: FSharp.Compiler.CodeAnalysis.FSharpReferencedProject CreateFromILModuleReader(System.String, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.DateTime], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,FSharp.Compiler.AbstractIL.ILBinaryReader+ILModuleReader]) +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: FSharp.Compiler.CodeAnalysis.FSharpReferencedProject CreatePortableExecutable(System.String, System.DateTime, Microsoft.FSharp.Core.FSharpFunc`2[System.Threading.CancellationToken,Microsoft.FSharp.Core.FSharpOption`1[System.IO.Stream]]) +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: Int32 GetHashCode() +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: System.String FileName +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpReferencedProject: System.String get_FileName() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromAttribute +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromComputationExpression +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromDefinition +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromDispatchSlotImplementation +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromOpenStatement +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromPattern +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromType +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsPrivateToFile +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromAttribute() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromComputationExpression() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromDefinition() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromDispatchSlotImplementation() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromOpenStatement() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromPattern() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromType() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsPrivateToFile() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext get_DisplayContext() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpSymbol Symbol +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpSymbol get_Symbol() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Text.Range Range +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpGenericParameter,FSharp.Compiler.Symbols.FSharpType]] GenericArguments +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpGenericParameter,FSharp.Compiler.Symbols.FSharpType]] get_GenericArguments() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: System.String FileName +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: System.String ToString() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: System.String get_FileName() +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: Boolean Equals(FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet) +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: Boolean Equals(System.Object) +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: Int32 GetHashCode() +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.CodeAnalysis.FSharpUnresolvedReferencesSet: System.String ToString() +FSharp.Compiler.CodeAnalysis.LegacyMSBuildReferenceResolver +FSharp.Compiler.CodeAnalysis.LegacyMSBuildReferenceResolver: FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver getResolver() +FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver +FSharp.Compiler.CompilerEnvironment +FSharp.Compiler.CompilerEnvironment: Boolean IsCheckerSupportedSubcategory(System.String) +FSharp.Compiler.CompilerEnvironment: Boolean IsCompilable(System.String) +FSharp.Compiler.CompilerEnvironment: Boolean IsScriptFile(System.String) +FSharp.Compiler.CompilerEnvironment: Boolean MustBeSingleFileProject(System.String) +FSharp.Compiler.CompilerEnvironment: Microsoft.FSharp.Collections.FSharpList`1[System.String] DefaultReferencesForOrphanSources(Boolean) +FSharp.Compiler.CompilerEnvironment: Microsoft.FSharp.Collections.FSharpList`1[System.String] GetCompilationDefinesForEditing(FSharp.Compiler.CodeAnalysis.FSharpParsingOptions) +FSharp.Compiler.CompilerEnvironment: Microsoft.FSharp.Core.FSharpOption`1[System.String] BinFolderOfDefaultFSharpCompiler(Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.CompilerEnvironment: System.Guid GetDebuggerLanguageID() +FSharp.Compiler.DependencyManager.AssemblyResolutionProbe +FSharp.Compiler.DependencyManager.AssemblyResolutionProbe: System.Collections.Generic.IEnumerable`1[System.String] EndInvoke(System.IAsyncResult) +FSharp.Compiler.DependencyManager.AssemblyResolutionProbe: System.Collections.Generic.IEnumerable`1[System.String] Invoke() +FSharp.Compiler.DependencyManager.AssemblyResolutionProbe: System.IAsyncResult BeginInvoke(System.AsyncCallback, System.Object) +FSharp.Compiler.DependencyManager.AssemblyResolutionProbe: Void .ctor(System.Object, IntPtr) +FSharp.Compiler.DependencyManager.AssemblyResolveHandler +FSharp.Compiler.DependencyManager.AssemblyResolveHandler: Void .ctor(FSharp.Compiler.DependencyManager.AssemblyResolutionProbe) +FSharp.Compiler.DependencyManager.DependencyProvider +FSharp.Compiler.DependencyManager.DependencyProvider: FSharp.Compiler.DependencyManager.IDependencyManagerProvider TryFindDependencyManagerByKey(System.Collections.Generic.IEnumerable`1[System.String], System.String, FSharp.Compiler.DependencyManager.ResolvingErrorReport, System.String) +FSharp.Compiler.DependencyManager.DependencyProvider: FSharp.Compiler.DependencyManager.IResolveDependenciesResult Resolve(FSharp.Compiler.DependencyManager.IDependencyManagerProvider, System.String, System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.String,System.String]], FSharp.Compiler.DependencyManager.ResolvingErrorReport, System.String, System.String, System.String, System.String, System.String, Int32) +FSharp.Compiler.DependencyManager.DependencyProvider: System.String[] GetRegisteredDependencyManagerHelpText(System.Collections.Generic.IEnumerable`1[System.String], System.String, FSharp.Compiler.DependencyManager.ResolvingErrorReport) +FSharp.Compiler.DependencyManager.DependencyProvider: System.Tuple`2[System.Int32,System.String] CreatePackageManagerUnknownError(System.Collections.Generic.IEnumerable`1[System.String], System.String, System.String, FSharp.Compiler.DependencyManager.ResolvingErrorReport) +FSharp.Compiler.DependencyManager.DependencyProvider: System.Tuple`2[System.String,FSharp.Compiler.DependencyManager.IDependencyManagerProvider] TryFindDependencyManagerInPath(System.Collections.Generic.IEnumerable`1[System.String], System.String, FSharp.Compiler.DependencyManager.ResolvingErrorReport, System.String) +FSharp.Compiler.DependencyManager.DependencyProvider: Void .ctor() +FSharp.Compiler.DependencyManager.DependencyProvider: Void .ctor(FSharp.Compiler.DependencyManager.AssemblyResolutionProbe, FSharp.Compiler.DependencyManager.NativeResolutionProbe) +FSharp.Compiler.DependencyManager.DependencyProvider: Void .ctor(FSharp.Compiler.DependencyManager.NativeResolutionProbe) +FSharp.Compiler.DependencyManager.ErrorReportType +FSharp.Compiler.DependencyManager.ErrorReportType+Tags: Int32 Error +FSharp.Compiler.DependencyManager.ErrorReportType+Tags: Int32 Warning +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean Equals(FSharp.Compiler.DependencyManager.ErrorReportType) +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean Equals(System.Object) +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean IsError +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean IsWarning +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean get_IsError() +FSharp.Compiler.DependencyManager.ErrorReportType: Boolean get_IsWarning() +FSharp.Compiler.DependencyManager.ErrorReportType: FSharp.Compiler.DependencyManager.ErrorReportType Error +FSharp.Compiler.DependencyManager.ErrorReportType: FSharp.Compiler.DependencyManager.ErrorReportType Warning +FSharp.Compiler.DependencyManager.ErrorReportType: FSharp.Compiler.DependencyManager.ErrorReportType get_Error() +FSharp.Compiler.DependencyManager.ErrorReportType: FSharp.Compiler.DependencyManager.ErrorReportType get_Warning() +FSharp.Compiler.DependencyManager.ErrorReportType: FSharp.Compiler.DependencyManager.ErrorReportType+Tags +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 CompareTo(FSharp.Compiler.DependencyManager.ErrorReportType) +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 CompareTo(System.Object) +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 GetHashCode() +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 Tag +FSharp.Compiler.DependencyManager.ErrorReportType: Int32 get_Tag() +FSharp.Compiler.DependencyManager.ErrorReportType: System.String ToString() +FSharp.Compiler.DependencyManager.IDependencyManagerProvider +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: FSharp.Compiler.DependencyManager.IResolveDependenciesResult ResolveDependencies(System.String, System.String, System.String, System.String, System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.String,System.String]], System.String, System.String, Int32) +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String Key +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String Name +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String get_Key() +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String get_Name() +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String[] HelpMessages +FSharp.Compiler.DependencyManager.IDependencyManagerProvider: System.String[] get_HelpMessages() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: Boolean Success +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: Boolean get_Success() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] Resolutions +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] Roots +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] SourceFiles +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] get_Resolutions() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] get_Roots() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.Collections.Generic.IEnumerable`1[System.String] get_SourceFiles() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.String[] StdError +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.String[] StdOut +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.String[] get_StdError() +FSharp.Compiler.DependencyManager.IResolveDependenciesResult: System.String[] get_StdOut() +FSharp.Compiler.DependencyManager.NativeDllResolveHandler +FSharp.Compiler.DependencyManager.NativeDllResolveHandler: Void .ctor(FSharp.Compiler.DependencyManager.NativeResolutionProbe) +FSharp.Compiler.DependencyManager.NativeResolutionProbe +FSharp.Compiler.DependencyManager.NativeResolutionProbe: System.Collections.Generic.IEnumerable`1[System.String] EndInvoke(System.IAsyncResult) +FSharp.Compiler.DependencyManager.NativeResolutionProbe: System.Collections.Generic.IEnumerable`1[System.String] Invoke() +FSharp.Compiler.DependencyManager.NativeResolutionProbe: System.IAsyncResult BeginInvoke(System.AsyncCallback, System.Object) +FSharp.Compiler.DependencyManager.NativeResolutionProbe: Void .ctor(System.Object, IntPtr) +FSharp.Compiler.DependencyManager.ResolvingErrorReport +FSharp.Compiler.DependencyManager.ResolvingErrorReport: System.IAsyncResult BeginInvoke(FSharp.Compiler.DependencyManager.ErrorReportType, Int32, System.String, System.AsyncCallback, System.Object) +FSharp.Compiler.DependencyManager.ResolvingErrorReport: Void .ctor(System.Object, IntPtr) +FSharp.Compiler.DependencyManager.ResolvingErrorReport: Void EndInvoke(System.IAsyncResult) +FSharp.Compiler.DependencyManager.ResolvingErrorReport: Void Invoke(FSharp.Compiler.DependencyManager.ErrorReportType, Int32, System.String) +FSharp.Compiler.Diagnostics.CompilerDiagnostics +FSharp.Compiler.Diagnostics.CompilerDiagnostics: System.Collections.Generic.IEnumerable`1[System.String] GetSuggestedNames(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[System.String,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.Unit], System.String) +FSharp.Compiler.Diagnostics.CompilerDiagnostics: System.String GetErrorMessage(FSharp.Compiler.Diagnostics.FSharpDiagnosticKind) +FSharp.Compiler.Diagnostics.FSharpDiagnostic +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position End +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position Start +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position get_End() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Position get_Start() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 EndColumn +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 EndLine +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 ErrorNumber +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 StartColumn +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 StartLine +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 get_EndColumn() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 get_EndLine() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 get_ErrorNumber() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 get_StartColumn() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: Int32 get_StartLine() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String ErrorNumberPrefix +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String ErrorNumberText +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String FileName +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String Message +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String NewlineifyErrorString(System.String) +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String NormalizeErrorString(System.String) +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String Subcategory +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String ToString() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String get_ErrorNumberPrefix() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String get_ErrorNumberText() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String get_FileName() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String get_Message() +FSharp.Compiler.Diagnostics.FSharpDiagnostic: System.String get_Subcategory() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+ReplaceWithSuggestion: System.String get_suggestion() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+ReplaceWithSuggestion: System.String suggestion +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+Tags: Int32 AddIndexerDot +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+Tags: Int32 ReplaceWithSuggestion +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean Equals(FSharp.Compiler.Diagnostics.FSharpDiagnosticKind) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean Equals(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean IsAddIndexerDot +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean IsReplaceWithSuggestion +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean get_IsAddIndexerDot() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Boolean get_IsReplaceWithSuggestion() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: FSharp.Compiler.Diagnostics.FSharpDiagnosticKind AddIndexerDot +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: FSharp.Compiler.Diagnostics.FSharpDiagnosticKind NewReplaceWithSuggestion(System.String) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: FSharp.Compiler.Diagnostics.FSharpDiagnosticKind get_AddIndexerDot() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+ReplaceWithSuggestion +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: FSharp.Compiler.Diagnostics.FSharpDiagnosticKind+Tags +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 CompareTo(FSharp.Compiler.Diagnostics.FSharpDiagnosticKind) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 GetHashCode() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 Tag +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: Int32 get_Tag() +FSharp.Compiler.Diagnostics.FSharpDiagnosticKind: System.String ToString() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Boolean Equals(FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Boolean Equals(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Boolean GlobalWarnAsError +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Boolean get_GlobalWarnAsError() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions Default +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions get_Default() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 CompareTo(FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 CompareTo(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 GetHashCode() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 WarnLevel +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Int32 get_WarnLevel() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] WarnAsError +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] WarnAsWarn +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] WarnOff +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] WarnOn +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_WarnAsError() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_WarnAsWarn() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_WarnOff() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_WarnOn() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: System.String ToString() +FSharp.Compiler.Diagnostics.FSharpDiagnosticOptions: Void .ctor(Int32, Boolean, Microsoft.FSharp.Collections.FSharpList`1[System.Int32], Microsoft.FSharp.Collections.FSharpList`1[System.Int32], Microsoft.FSharp.Collections.FSharpList`1[System.Int32], Microsoft.FSharp.Collections.FSharpList`1[System.Int32]) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity+Tags: Int32 Error +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity+Tags: Int32 Hidden +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity+Tags: Int32 Info +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity+Tags: Int32 Warning +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean Equals(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean Equals(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean IsError +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean IsHidden +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean IsInfo +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean IsWarning +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean get_IsError() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean get_IsHidden() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean get_IsInfo() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Boolean get_IsWarning() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Error +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Hidden +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Info +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Warning +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Error() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Hidden() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Info() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Warning() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity+Tags +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 CompareTo(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 CompareTo(System.Object) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 GetHashCode() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 Tag +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: Int32 get_Tag() +FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity: System.String ToString() +FSharp.Compiler.EditorServices.AssemblyContent +FSharp.Compiler.EditorServices.AssemblyContent: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol] GetAssemblyContent(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.IAssemblyContentCache,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]], FSharp.Compiler.EditorServices.AssemblyContentType, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpAssembly]) +FSharp.Compiler.EditorServices.AssemblyContent: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol] GetAssemblySignatureContent(FSharp.Compiler.EditorServices.AssemblyContentType, FSharp.Compiler.Symbols.FSharpAssemblySignature) +FSharp.Compiler.EditorServices.AssemblyContentType +FSharp.Compiler.EditorServices.AssemblyContentType+Tags: Int32 Full +FSharp.Compiler.EditorServices.AssemblyContentType+Tags: Int32 Public +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean Equals(FSharp.Compiler.EditorServices.AssemblyContentType) +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean IsFull +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean IsPublic +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean get_IsFull() +FSharp.Compiler.EditorServices.AssemblyContentType: Boolean get_IsPublic() +FSharp.Compiler.EditorServices.AssemblyContentType: FSharp.Compiler.EditorServices.AssemblyContentType Full +FSharp.Compiler.EditorServices.AssemblyContentType: FSharp.Compiler.EditorServices.AssemblyContentType Public +FSharp.Compiler.EditorServices.AssemblyContentType: FSharp.Compiler.EditorServices.AssemblyContentType get_Full() +FSharp.Compiler.EditorServices.AssemblyContentType: FSharp.Compiler.EditorServices.AssemblyContentType get_Public() +FSharp.Compiler.EditorServices.AssemblyContentType: FSharp.Compiler.EditorServices.AssemblyContentType+Tags +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 CompareTo(FSharp.Compiler.EditorServices.AssemblyContentType) +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 GetHashCode() +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 Tag +FSharp.Compiler.EditorServices.AssemblyContentType: Int32 get_Tag() +FSharp.Compiler.EditorServices.AssemblyContentType: System.String ToString() +FSharp.Compiler.EditorServices.AssemblySymbol +FSharp.Compiler.EditorServices.AssemblySymbol: FSharp.Compiler.EditorServices.UnresolvedSymbol UnresolvedSymbol +FSharp.Compiler.EditorServices.AssemblySymbol: FSharp.Compiler.EditorServices.UnresolvedSymbol get_UnresolvedSymbol() +FSharp.Compiler.EditorServices.AssemblySymbol: FSharp.Compiler.Symbols.FSharpSymbol Symbol +FSharp.Compiler.EditorServices.AssemblySymbol: FSharp.Compiler.Symbols.FSharpSymbol get_Symbol() +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.LookupType,FSharp.Compiler.EditorServices.EntityKind] Kind +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.LookupType,FSharp.Compiler.EditorServices.EntityKind] get_Kind() +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] AutoOpenParent +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] Namespace +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] NearestRequireQualifiedAccessParent +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] TopRequireQualifiedAccessParent +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] get_AutoOpenParent() +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] get_Namespace() +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] get_NearestRequireQualifiedAccessParent() +FSharp.Compiler.EditorServices.AssemblySymbol: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] get_TopRequireQualifiedAccessParent() +FSharp.Compiler.EditorServices.AssemblySymbol: System.String FullName +FSharp.Compiler.EditorServices.AssemblySymbol: System.String ToString() +FSharp.Compiler.EditorServices.AssemblySymbol: System.String get_FullName() +FSharp.Compiler.EditorServices.AssemblySymbol: System.String[] CleanedIdents +FSharp.Compiler.EditorServices.AssemblySymbol: System.String[] get_CleanedIdents() +FSharp.Compiler.EditorServices.AssemblySymbol: Void .ctor(System.String, System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], FSharp.Compiler.Symbols.FSharpSymbol, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.LookupType,FSharp.Compiler.EditorServices.EntityKind], FSharp.Compiler.EditorServices.UnresolvedSymbol) +FSharp.Compiler.EditorServices.CompletionContext +FSharp.Compiler.EditorServices.CompletionContext+Inherit: FSharp.Compiler.EditorServices.InheritanceContext context +FSharp.Compiler.EditorServices.CompletionContext+Inherit: FSharp.Compiler.EditorServices.InheritanceContext get_context() +FSharp.Compiler.EditorServices.CompletionContext+Inherit: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] get_path() +FSharp.Compiler.EditorServices.CompletionContext+Inherit: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] path +FSharp.Compiler.EditorServices.CompletionContext+OpenDeclaration: Boolean get_isOpenType() +FSharp.Compiler.EditorServices.CompletionContext+OpenDeclaration: Boolean isOpenType +FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler.Text.Position Item1 +FSharp.Compiler.EditorServices.CompletionContext+ParameterList: FSharp.Compiler.Text.Position get_Item1() +FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] Item2 +FSharp.Compiler.EditorServices.CompletionContext+ParameterList: System.Collections.Generic.HashSet`1[System.String] get_Item2() +FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext context +FSharp.Compiler.EditorServices.CompletionContext+RecordField: FSharp.Compiler.EditorServices.RecordContext get_context() +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 AttributeApplication +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Inherit +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 Invalid +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 OpenDeclaration +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 ParameterList +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 PatternType +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RangeOperator +FSharp.Compiler.EditorServices.CompletionContext+Tags: Int32 RecordField +FSharp.Compiler.EditorServices.CompletionContext: Boolean Equals(FSharp.Compiler.EditorServices.CompletionContext) +FSharp.Compiler.EditorServices.CompletionContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.CompletionContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsAttributeApplication +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInherit +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsInvalid +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsOpenDeclaration +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsParameterList +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsPatternType +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRangeOperator +FSharp.Compiler.EditorServices.CompletionContext: Boolean IsRecordField +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsAttributeApplication() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInherit() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsInvalid() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsOpenDeclaration() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsParameterList() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsPatternType() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRangeOperator() +FSharp.Compiler.EditorServices.CompletionContext: Boolean get_IsRecordField() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext AttributeApplication +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext Invalid +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewInherit(FSharp.Compiler.EditorServices.InheritanceContext, System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]]) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewOpenDeclaration(Boolean) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewParameterList(FSharp.Compiler.Text.Position, System.Collections.Generic.HashSet`1[System.String]) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext NewRecordField(FSharp.Compiler.EditorServices.RecordContext) +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext PatternType +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext RangeOperator +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_AttributeApplication() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_Invalid() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_PatternType() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext get_RangeOperator() +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Inherit +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+OpenDeclaration +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+ParameterList +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+RecordField +FSharp.Compiler.EditorServices.CompletionContext: FSharp.Compiler.EditorServices.CompletionContext+Tags +FSharp.Compiler.EditorServices.CompletionContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.CompletionContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.CompletionContext: Int32 Tag +FSharp.Compiler.EditorServices.CompletionContext: Int32 get_Tag() +FSharp.Compiler.EditorServices.CompletionContext: System.String ToString() +FSharp.Compiler.EditorServices.CompletionItemKind +FSharp.Compiler.EditorServices.CompletionItemKind+Method: Boolean get_isExtension() +FSharp.Compiler.EditorServices.CompletionItemKind+Method: Boolean isExtension +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Argument +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 CustomOperation +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Event +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Field +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Method +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Other +FSharp.Compiler.EditorServices.CompletionItemKind+Tags: Int32 Property +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(FSharp.Compiler.EditorServices.CompletionItemKind) +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsArgument +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsCustomOperation +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsEvent +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsField +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsMethod +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsOther +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean IsProperty +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsArgument() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsCustomOperation() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsEvent() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsField() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsMethod() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsOther() +FSharp.Compiler.EditorServices.CompletionItemKind: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Argument +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind CustomOperation +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Event +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Field +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind NewMethod(Boolean) +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Other +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind Property +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Argument() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_CustomOperation() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Event() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Field() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Other() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind get_Property() +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Method +FSharp.Compiler.EditorServices.CompletionItemKind: FSharp.Compiler.EditorServices.CompletionItemKind+Tags +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 CompareTo(FSharp.Compiler.EditorServices.CompletionItemKind) +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 Tag +FSharp.Compiler.EditorServices.CompletionItemKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.CompletionItemKind: System.String ToString() +FSharp.Compiler.EditorServices.DeclarationListInfo +FSharp.Compiler.EditorServices.DeclarationListInfo: Boolean IsError +FSharp.Compiler.EditorServices.DeclarationListInfo: Boolean IsForType +FSharp.Compiler.EditorServices.DeclarationListInfo: Boolean get_IsError() +FSharp.Compiler.EditorServices.DeclarationListInfo: Boolean get_IsForType() +FSharp.Compiler.EditorServices.DeclarationListInfo: FSharp.Compiler.EditorServices.DeclarationListInfo Empty +FSharp.Compiler.EditorServices.DeclarationListInfo: FSharp.Compiler.EditorServices.DeclarationListInfo get_Empty() +FSharp.Compiler.EditorServices.DeclarationListInfo: FSharp.Compiler.EditorServices.DeclarationListItem[] Items +FSharp.Compiler.EditorServices.DeclarationListInfo: FSharp.Compiler.EditorServices.DeclarationListItem[] get_Items() +FSharp.Compiler.EditorServices.DeclarationListItem +FSharp.Compiler.EditorServices.DeclarationListItem: Boolean IsOwnMember +FSharp.Compiler.EditorServices.DeclarationListItem: Boolean IsResolved +FSharp.Compiler.EditorServices.DeclarationListItem: Boolean get_IsOwnMember() +FSharp.Compiler.EditorServices.DeclarationListItem: Boolean get_IsResolved() +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.CompletionItemKind Kind +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.CompletionItemKind get_Kind() +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.FSharpGlyph Glyph +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.FSharpGlyph get_Glyph() +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.ToolTipText Description +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.EditorServices.ToolTipText get_Description() +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.EditorServices.DeclarationListItem: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.EditorServices.DeclarationListItem: Int32 MinorPriority +FSharp.Compiler.EditorServices.DeclarationListItem: Int32 get_MinorPriority() +FSharp.Compiler.EditorServices.DeclarationListItem: Microsoft.FSharp.Core.FSharpOption`1[System.String] NamespaceToOpen +FSharp.Compiler.EditorServices.DeclarationListItem: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_NamespaceToOpen() +FSharp.Compiler.EditorServices.DeclarationListItem: System.String FullName +FSharp.Compiler.EditorServices.DeclarationListItem: System.String Name +FSharp.Compiler.EditorServices.DeclarationListItem: System.String NameInCode +FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_FullName() +FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_Name() +FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_NameInCode() +FSharp.Compiler.EditorServices.EntityCache +FSharp.Compiler.EditorServices.EntityCache: T Locking[T](Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.IAssemblyContentCache,T]) +FSharp.Compiler.EditorServices.EntityCache: Void .ctor() +FSharp.Compiler.EditorServices.EntityCache: Void Clear() +FSharp.Compiler.EditorServices.EntityKind +FSharp.Compiler.EditorServices.EntityKind+FunctionOrValue: Boolean get_isActivePattern() +FSharp.Compiler.EditorServices.EntityKind+FunctionOrValue: Boolean isActivePattern +FSharp.Compiler.EditorServices.EntityKind+Module: FSharp.Compiler.EditorServices.ModuleKind Item +FSharp.Compiler.EditorServices.EntityKind+Module: FSharp.Compiler.EditorServices.ModuleKind get_Item() +FSharp.Compiler.EditorServices.EntityKind+Tags: Int32 Attribute +FSharp.Compiler.EditorServices.EntityKind+Tags: Int32 FunctionOrValue +FSharp.Compiler.EditorServices.EntityKind+Tags: Int32 Module +FSharp.Compiler.EditorServices.EntityKind+Tags: Int32 Type +FSharp.Compiler.EditorServices.EntityKind: Boolean Equals(FSharp.Compiler.EditorServices.EntityKind) +FSharp.Compiler.EditorServices.EntityKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.EntityKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.EntityKind: Boolean IsAttribute +FSharp.Compiler.EditorServices.EntityKind: Boolean IsFunctionOrValue +FSharp.Compiler.EditorServices.EntityKind: Boolean IsModule +FSharp.Compiler.EditorServices.EntityKind: Boolean IsType +FSharp.Compiler.EditorServices.EntityKind: Boolean get_IsAttribute() +FSharp.Compiler.EditorServices.EntityKind: Boolean get_IsFunctionOrValue() +FSharp.Compiler.EditorServices.EntityKind: Boolean get_IsModule() +FSharp.Compiler.EditorServices.EntityKind: Boolean get_IsType() +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind Attribute +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind NewFunctionOrValue(Boolean) +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind NewModule(FSharp.Compiler.EditorServices.ModuleKind) +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind Type +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind get_Attribute() +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind get_Type() +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind+FunctionOrValue +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind+Module +FSharp.Compiler.EditorServices.EntityKind: FSharp.Compiler.EditorServices.EntityKind+Tags +FSharp.Compiler.EditorServices.EntityKind: Int32 CompareTo(FSharp.Compiler.EditorServices.EntityKind) +FSharp.Compiler.EditorServices.EntityKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.EntityKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.EntityKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.EntityKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.EntityKind: Int32 Tag +FSharp.Compiler.EditorServices.EntityKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.EntityKind: System.String ToString() +FSharp.Compiler.EditorServices.FSharpGlyph +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Class +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Constant +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Delegate +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Enum +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 EnumMember +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Error +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Event +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Exception +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 ExtensionMethod +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Field +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Interface +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Method +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Module +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 NameSpace +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 OverridenMethod +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Property +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Struct +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Type +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Typedef +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Union +FSharp.Compiler.EditorServices.FSharpGlyph+Tags: Int32 Variable +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean Equals(FSharp.Compiler.EditorServices.FSharpGlyph) +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsClass +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsConstant +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsDelegate +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsEnum +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsEnumMember +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsError +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsEvent +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsException +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsExtensionMethod +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsField +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsInterface +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsMethod +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsModule +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsNameSpace +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsOverridenMethod +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsProperty +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsStruct +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsType +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsTypedef +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsUnion +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean IsVariable +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsClass() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsConstant() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsDelegate() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsEnum() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsEnumMember() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsError() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsEvent() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsException() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsExtensionMethod() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsField() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsInterface() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsMethod() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsModule() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsNameSpace() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsOverridenMethod() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsStruct() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsType() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsTypedef() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsUnion() +FSharp.Compiler.EditorServices.FSharpGlyph: Boolean get_IsVariable() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Class +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Constant +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Delegate +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Enum +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph EnumMember +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Error +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Event +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Exception +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph ExtensionMethod +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Field +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Interface +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Method +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Module +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph NameSpace +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph OverridenMethod +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Property +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Struct +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Type +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Typedef +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Union +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph Variable +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Class() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Constant() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Delegate() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Enum() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_EnumMember() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Error() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Event() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Exception() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_ExtensionMethod() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Field() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Interface() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Method() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Module() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_NameSpace() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_OverridenMethod() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Property() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Struct() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Type() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Typedef() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Union() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph get_Variable() +FSharp.Compiler.EditorServices.FSharpGlyph: FSharp.Compiler.EditorServices.FSharpGlyph+Tags +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 CompareTo(FSharp.Compiler.EditorServices.FSharpGlyph) +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 Tag +FSharp.Compiler.EditorServices.FSharpGlyph: Int32 get_Tag() +FSharp.Compiler.EditorServices.FSharpGlyph: System.String ToString() +FSharp.Compiler.EditorServices.FindDeclExternalParam +FSharp.Compiler.EditorServices.FindDeclExternalParam: Boolean Equals(FSharp.Compiler.EditorServices.FindDeclExternalParam) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Boolean IsByRef +FSharp.Compiler.EditorServices.FindDeclExternalParam: Boolean get_IsByRef() +FSharp.Compiler.EditorServices.FindDeclExternalParam: FSharp.Compiler.EditorServices.FindDeclExternalParam Create(FSharp.Compiler.EditorServices.FindDeclExternalType, Boolean) +FSharp.Compiler.EditorServices.FindDeclExternalParam: FSharp.Compiler.EditorServices.FindDeclExternalType ParameterType +FSharp.Compiler.EditorServices.FindDeclExternalParam: FSharp.Compiler.EditorServices.FindDeclExternalType get_ParameterType() +FSharp.Compiler.EditorServices.FindDeclExternalParam: Int32 CompareTo(FSharp.Compiler.EditorServices.FindDeclExternalParam) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.FindDeclExternalParam: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FindDeclExternalParam: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalParam: System.String ToString() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Constructor: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam] args +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Constructor: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam] get_args() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Constructor: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Constructor: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Event: System.String get_name() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Event: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Event: System.String name +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Event: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Field: System.String get_name() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Field: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Field: System.String name +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Field: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: Int32 genericArity +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: Int32 get_genericArity() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam] get_paramSyms() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam] paramSyms +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: System.String get_name() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: System.String name +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Property: System.String get_name() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Property: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Property: System.String name +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Property: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Constructor +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Event +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Field +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Method +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Property +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags: Int32 Type +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Type: System.String fullName +FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Type: System.String get_fullName() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean Equals(FSharp.Compiler.EditorServices.FindDeclExternalSymbol) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsConstructor +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsEvent +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsField +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsMethod +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsProperty +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean IsType +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsConstructor() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsEvent() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsField() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsMethod() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Boolean get_IsType() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewConstructor(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam]) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewEvent(System.String, System.String) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewField(System.String, System.String) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewMethod(System.String, System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalParam], Int32) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewProperty(System.String, System.String) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol NewType(System.String) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Constructor +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Event +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Field +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Method +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Property +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Tags +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: FSharp.Compiler.EditorServices.FindDeclExternalSymbol+Type +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 CompareTo(FSharp.Compiler.EditorServices.FindDeclExternalSymbol) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 Tag +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: Int32 get_Tag() +FSharp.Compiler.EditorServices.FindDeclExternalSymbol: System.String ToString() +FSharp.Compiler.EditorServices.FindDeclExternalType +FSharp.Compiler.EditorServices.FindDeclExternalType+Array: FSharp.Compiler.EditorServices.FindDeclExternalType get_inner() +FSharp.Compiler.EditorServices.FindDeclExternalType+Array: FSharp.Compiler.EditorServices.FindDeclExternalType inner +FSharp.Compiler.EditorServices.FindDeclExternalType+Pointer: FSharp.Compiler.EditorServices.FindDeclExternalType get_inner() +FSharp.Compiler.EditorServices.FindDeclExternalType+Pointer: FSharp.Compiler.EditorServices.FindDeclExternalType inner +FSharp.Compiler.EditorServices.FindDeclExternalType+Tags: Int32 Array +FSharp.Compiler.EditorServices.FindDeclExternalType+Tags: Int32 Pointer +FSharp.Compiler.EditorServices.FindDeclExternalType+Tags: Int32 Type +FSharp.Compiler.EditorServices.FindDeclExternalType+Tags: Int32 TypeVar +FSharp.Compiler.EditorServices.FindDeclExternalType+Type: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalType] genericArgs +FSharp.Compiler.EditorServices.FindDeclExternalType+Type: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalType] get_genericArgs() +FSharp.Compiler.EditorServices.FindDeclExternalType+Type: System.String fullName +FSharp.Compiler.EditorServices.FindDeclExternalType+Type: System.String get_fullName() +FSharp.Compiler.EditorServices.FindDeclExternalType+TypeVar: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclExternalType+TypeVar: System.String typeName +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean Equals(FSharp.Compiler.EditorServices.FindDeclExternalType) +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean IsArray +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean IsPointer +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean IsType +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean IsTypeVar +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean get_IsArray() +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean get_IsPointer() +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean get_IsType() +FSharp.Compiler.EditorServices.FindDeclExternalType: Boolean get_IsTypeVar() +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType NewArray(FSharp.Compiler.EditorServices.FindDeclExternalType) +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType NewPointer(FSharp.Compiler.EditorServices.FindDeclExternalType) +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType NewType(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.FindDeclExternalType]) +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType NewTypeVar(System.String) +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType+Array +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType+Pointer +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType+Tags +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType+Type +FSharp.Compiler.EditorServices.FindDeclExternalType: FSharp.Compiler.EditorServices.FindDeclExternalType+TypeVar +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 CompareTo(FSharp.Compiler.EditorServices.FindDeclExternalType) +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 Tag +FSharp.Compiler.EditorServices.FindDeclExternalType: Int32 get_Tag() +FSharp.Compiler.EditorServices.FindDeclExternalType: System.String ToString() +FSharp.Compiler.EditorServices.FindDeclFailureReason +FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedMember: System.String get_memberName() +FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedMember: System.String memberName +FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedType: System.String get_typeName() +FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedType: System.String typeName +FSharp.Compiler.EditorServices.FindDeclFailureReason+Tags: Int32 NoSourceCode +FSharp.Compiler.EditorServices.FindDeclFailureReason+Tags: Int32 ProvidedMember +FSharp.Compiler.EditorServices.FindDeclFailureReason+Tags: Int32 ProvidedType +FSharp.Compiler.EditorServices.FindDeclFailureReason+Tags: Int32 Unknown +FSharp.Compiler.EditorServices.FindDeclFailureReason+Unknown: System.String get_message() +FSharp.Compiler.EditorServices.FindDeclFailureReason+Unknown: System.String message +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean Equals(FSharp.Compiler.EditorServices.FindDeclFailureReason) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean IsNoSourceCode +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean IsProvidedMember +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean IsProvidedType +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean IsUnknown +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean get_IsNoSourceCode() +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean get_IsProvidedMember() +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean get_IsProvidedType() +FSharp.Compiler.EditorServices.FindDeclFailureReason: Boolean get_IsUnknown() +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason NewProvidedMember(System.String) +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason NewProvidedType(System.String) +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason NewUnknown(System.String) +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason NoSourceCode +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason get_NoSourceCode() +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedMember +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason+ProvidedType +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason+Tags +FSharp.Compiler.EditorServices.FindDeclFailureReason: FSharp.Compiler.EditorServices.FindDeclFailureReason+Unknown +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 CompareTo(FSharp.Compiler.EditorServices.FindDeclFailureReason) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 Tag +FSharp.Compiler.EditorServices.FindDeclFailureReason: Int32 get_Tag() +FSharp.Compiler.EditorServices.FindDeclFailureReason: System.String ToString() +FSharp.Compiler.EditorServices.FindDeclResult +FSharp.Compiler.EditorServices.FindDeclResult+DeclFound: FSharp.Compiler.Text.Range get_location() +FSharp.Compiler.EditorServices.FindDeclResult+DeclFound: FSharp.Compiler.Text.Range location +FSharp.Compiler.EditorServices.FindDeclResult+DeclNotFound: FSharp.Compiler.EditorServices.FindDeclFailureReason Item +FSharp.Compiler.EditorServices.FindDeclResult+DeclNotFound: FSharp.Compiler.EditorServices.FindDeclFailureReason get_Item() +FSharp.Compiler.EditorServices.FindDeclResult+ExternalDecl: FSharp.Compiler.EditorServices.FindDeclExternalSymbol externalSym +FSharp.Compiler.EditorServices.FindDeclResult+ExternalDecl: FSharp.Compiler.EditorServices.FindDeclExternalSymbol get_externalSym() +FSharp.Compiler.EditorServices.FindDeclResult+ExternalDecl: System.String assembly +FSharp.Compiler.EditorServices.FindDeclResult+ExternalDecl: System.String get_assembly() +FSharp.Compiler.EditorServices.FindDeclResult+Tags: Int32 DeclFound +FSharp.Compiler.EditorServices.FindDeclResult+Tags: Int32 DeclNotFound +FSharp.Compiler.EditorServices.FindDeclResult+Tags: Int32 ExternalDecl +FSharp.Compiler.EditorServices.FindDeclResult: Boolean Equals(FSharp.Compiler.EditorServices.FindDeclResult) +FSharp.Compiler.EditorServices.FindDeclResult: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.FindDeclResult: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclResult: Boolean IsDeclFound +FSharp.Compiler.EditorServices.FindDeclResult: Boolean IsDeclNotFound +FSharp.Compiler.EditorServices.FindDeclResult: Boolean IsExternalDecl +FSharp.Compiler.EditorServices.FindDeclResult: Boolean get_IsDeclFound() +FSharp.Compiler.EditorServices.FindDeclResult: Boolean get_IsDeclNotFound() +FSharp.Compiler.EditorServices.FindDeclResult: Boolean get_IsExternalDecl() +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult NewDeclFound(FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult NewDeclNotFound(FSharp.Compiler.EditorServices.FindDeclFailureReason) +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult NewExternalDecl(System.String, FSharp.Compiler.EditorServices.FindDeclExternalSymbol) +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult+DeclFound +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult+DeclNotFound +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult+ExternalDecl +FSharp.Compiler.EditorServices.FindDeclResult: FSharp.Compiler.EditorServices.FindDeclResult+Tags +FSharp.Compiler.EditorServices.FindDeclResult: Int32 GetHashCode() +FSharp.Compiler.EditorServices.FindDeclResult: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.FindDeclResult: Int32 Tag +FSharp.Compiler.EditorServices.FindDeclResult: Int32 get_Tag() +FSharp.Compiler.EditorServices.FindDeclResult: System.String ToString() +FSharp.Compiler.EditorServices.IAssemblyContentCache +FSharp.Compiler.EditorServices.IAssemblyContentCache: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.AssemblyContentCacheEntry] TryGet(System.String) +FSharp.Compiler.EditorServices.IAssemblyContentCache: Void Set(System.String, FSharp.Compiler.EditorServices.AssemblyContentCacheEntry) +FSharp.Compiler.EditorServices.InheritanceContext +FSharp.Compiler.EditorServices.InheritanceContext+Tags: Int32 Class +FSharp.Compiler.EditorServices.InheritanceContext+Tags: Int32 Interface +FSharp.Compiler.EditorServices.InheritanceContext+Tags: Int32 Unknown +FSharp.Compiler.EditorServices.InheritanceContext: Boolean Equals(FSharp.Compiler.EditorServices.InheritanceContext) +FSharp.Compiler.EditorServices.InheritanceContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.InheritanceContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InheritanceContext: Boolean IsClass +FSharp.Compiler.EditorServices.InheritanceContext: Boolean IsInterface +FSharp.Compiler.EditorServices.InheritanceContext: Boolean IsUnknown +FSharp.Compiler.EditorServices.InheritanceContext: Boolean get_IsClass() +FSharp.Compiler.EditorServices.InheritanceContext: Boolean get_IsInterface() +FSharp.Compiler.EditorServices.InheritanceContext: Boolean get_IsUnknown() +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext Class +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext Interface +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext Unknown +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext get_Class() +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext get_Interface() +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext get_Unknown() +FSharp.Compiler.EditorServices.InheritanceContext: FSharp.Compiler.EditorServices.InheritanceContext+Tags +FSharp.Compiler.EditorServices.InheritanceContext: Int32 CompareTo(FSharp.Compiler.EditorServices.InheritanceContext) +FSharp.Compiler.EditorServices.InheritanceContext: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.InheritanceContext: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.InheritanceContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.InheritanceContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InheritanceContext: Int32 Tag +FSharp.Compiler.EditorServices.InheritanceContext: Int32 get_Tag() +FSharp.Compiler.EditorServices.InheritanceContext: System.String ToString() +FSharp.Compiler.EditorServices.InsertionContext +FSharp.Compiler.EditorServices.InsertionContext: Boolean Equals(FSharp.Compiler.EditorServices.InsertionContext) +FSharp.Compiler.EditorServices.InsertionContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.InsertionContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InsertionContext: FSharp.Compiler.EditorServices.ScopeKind ScopeKind +FSharp.Compiler.EditorServices.InsertionContext: FSharp.Compiler.EditorServices.ScopeKind get_ScopeKind() +FSharp.Compiler.EditorServices.InsertionContext: FSharp.Compiler.Text.Position Pos +FSharp.Compiler.EditorServices.InsertionContext: FSharp.Compiler.Text.Position get_Pos() +FSharp.Compiler.EditorServices.InsertionContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.InsertionContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InsertionContext: System.String ToString() +FSharp.Compiler.EditorServices.InsertionContext: Void .ctor(FSharp.Compiler.EditorServices.ScopeKind, FSharp.Compiler.Text.Position) +FSharp.Compiler.EditorServices.InsertionContextEntity +FSharp.Compiler.EditorServices.InsertionContextEntity: Boolean Equals(FSharp.Compiler.EditorServices.InsertionContextEntity) +FSharp.Compiler.EditorServices.InsertionContextEntity: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.InsertionContextEntity: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InsertionContextEntity: Int32 CompareTo(FSharp.Compiler.EditorServices.InsertionContextEntity) +FSharp.Compiler.EditorServices.InsertionContextEntity: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.InsertionContextEntity: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.InsertionContextEntity: Int32 GetHashCode() +FSharp.Compiler.EditorServices.InsertionContextEntity: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.InsertionContextEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] Namespace +FSharp.Compiler.EditorServices.InsertionContextEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Namespace() +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String FullDisplayName +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String FullRelativeName +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String LastIdent +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String Qualifier +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String ToString() +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String get_FullDisplayName() +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String get_FullRelativeName() +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String get_LastIdent() +FSharp.Compiler.EditorServices.InsertionContextEntity: System.String get_Qualifier() +FSharp.Compiler.EditorServices.InsertionContextEntity: Void .ctor(System.String, System.String, Microsoft.FSharp.Core.FSharpOption`1[System.String], System.String, System.String) +FSharp.Compiler.EditorServices.InterfaceData +FSharp.Compiler.EditorServices.InterfaceData+Interface: FSharp.Compiler.Syntax.SynType get_interfaceType() +FSharp.Compiler.EditorServices.InterfaceData+Interface: FSharp.Compiler.Syntax.SynType interfaceType +FSharp.Compiler.EditorServices.InterfaceData+Interface: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]] get_memberDefns() +FSharp.Compiler.EditorServices.InterfaceData+Interface: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]] memberDefns +FSharp.Compiler.EditorServices.InterfaceData+ObjExpr: FSharp.Compiler.Syntax.SynType get_objType() +FSharp.Compiler.EditorServices.InterfaceData+ObjExpr: FSharp.Compiler.Syntax.SynType objType +FSharp.Compiler.EditorServices.InterfaceData+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.EditorServices.InterfaceData+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.EditorServices.InterfaceData+Tags: Int32 Interface +FSharp.Compiler.EditorServices.InterfaceData+Tags: Int32 ObjExpr +FSharp.Compiler.EditorServices.InterfaceData: Boolean IsInterface +FSharp.Compiler.EditorServices.InterfaceData: Boolean IsObjExpr +FSharp.Compiler.EditorServices.InterfaceData: Boolean get_IsInterface() +FSharp.Compiler.EditorServices.InterfaceData: Boolean get_IsObjExpr() +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.EditorServices.InterfaceData NewInterface(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]]) +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.EditorServices.InterfaceData NewObjExpr(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding]) +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.EditorServices.InterfaceData+Interface +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.EditorServices.InterfaceData+ObjExpr +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.EditorServices.InterfaceData+Tags +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.InterfaceData: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.InterfaceData: Int32 Tag +FSharp.Compiler.EditorServices.InterfaceData: Int32 get_Tag() +FSharp.Compiler.EditorServices.InterfaceData: System.String ToString() +FSharp.Compiler.EditorServices.InterfaceData: System.String[] TypeParameters +FSharp.Compiler.EditorServices.InterfaceData: System.String[] get_TypeParameters() +FSharp.Compiler.EditorServices.InterfaceStubGenerator +FSharp.Compiler.EditorServices.InterfaceStubGenerator: Boolean HasNoInterfaceMember(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: Boolean IsInterface(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]] GetMemberNameAndRanges(FSharp.Compiler.EditorServices.InterfaceData) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Collections.FSharpSet`1[System.String]] GetImplementedMemberSignatures(Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.String,FSharp.Compiler.Text.Range],Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]], FSharp.Compiler.Symbols.FSharpDisplayContext, FSharp.Compiler.EditorServices.InterfaceData) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.InterfaceData] TryFindInterfaceDeclaration(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: System.Collections.Generic.IEnumerable`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,System.Collections.Generic.IEnumerable`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpGenericParameter,FSharp.Compiler.Symbols.FSharpType]]]] GetInterfaceMembers(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.EditorServices.InterfaceStubGenerator: System.String FormatInterface(Int32, Int32, System.String[], System.String, System.String, FSharp.Compiler.Symbols.FSharpDisplayContext, Microsoft.FSharp.Collections.FSharpSet`1[System.String], FSharp.Compiler.Symbols.FSharpEntity, Boolean) +FSharp.Compiler.EditorServices.LookupType +FSharp.Compiler.EditorServices.LookupType+Tags: Int32 Fuzzy +FSharp.Compiler.EditorServices.LookupType+Tags: Int32 Precise +FSharp.Compiler.EditorServices.LookupType: Boolean Equals(FSharp.Compiler.EditorServices.LookupType) +FSharp.Compiler.EditorServices.LookupType: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.LookupType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.LookupType: Boolean IsFuzzy +FSharp.Compiler.EditorServices.LookupType: Boolean IsPrecise +FSharp.Compiler.EditorServices.LookupType: Boolean get_IsFuzzy() +FSharp.Compiler.EditorServices.LookupType: Boolean get_IsPrecise() +FSharp.Compiler.EditorServices.LookupType: FSharp.Compiler.EditorServices.LookupType Fuzzy +FSharp.Compiler.EditorServices.LookupType: FSharp.Compiler.EditorServices.LookupType Precise +FSharp.Compiler.EditorServices.LookupType: FSharp.Compiler.EditorServices.LookupType get_Fuzzy() +FSharp.Compiler.EditorServices.LookupType: FSharp.Compiler.EditorServices.LookupType get_Precise() +FSharp.Compiler.EditorServices.LookupType: FSharp.Compiler.EditorServices.LookupType+Tags +FSharp.Compiler.EditorServices.LookupType: Int32 CompareTo(FSharp.Compiler.EditorServices.LookupType) +FSharp.Compiler.EditorServices.LookupType: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.LookupType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.LookupType: Int32 GetHashCode() +FSharp.Compiler.EditorServices.LookupType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.LookupType: Int32 Tag +FSharp.Compiler.EditorServices.LookupType: Int32 get_Tag() +FSharp.Compiler.EditorServices.LookupType: System.String ToString() +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Boolean Equals(FSharp.Compiler.EditorServices.MaybeUnresolvedIdent) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Boolean Resolved +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Boolean get_Resolved() +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Int32 CompareTo(FSharp.Compiler.EditorServices.MaybeUnresolvedIdent) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Int32 GetHashCode() +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: System.String Ident +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: System.String ToString() +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: System.String get_Ident() +FSharp.Compiler.EditorServices.MaybeUnresolvedIdent: Void .ctor(System.String, Boolean) +FSharp.Compiler.EditorServices.MethodGroup +FSharp.Compiler.EditorServices.MethodGroup: FSharp.Compiler.EditorServices.MethodGroupItem[] Methods +FSharp.Compiler.EditorServices.MethodGroup: FSharp.Compiler.EditorServices.MethodGroupItem[] get_Methods() +FSharp.Compiler.EditorServices.MethodGroup: System.String MethodName +FSharp.Compiler.EditorServices.MethodGroup: System.String get_MethodName() +FSharp.Compiler.EditorServices.MethodGroupItem +FSharp.Compiler.EditorServices.MethodGroupItem: Boolean HasParamArrayArg +FSharp.Compiler.EditorServices.MethodGroupItem: Boolean HasParameters +FSharp.Compiler.EditorServices.MethodGroupItem: Boolean get_HasParamArrayArg() +FSharp.Compiler.EditorServices.MethodGroupItem: Boolean get_HasParameters() +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.MethodGroupItemParameter[] Parameters +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.MethodGroupItemParameter[] StaticParameters +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.MethodGroupItemParameter[] get_Parameters() +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.MethodGroupItemParameter[] get_StaticParameters() +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.ToolTipText Description +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.EditorServices.ToolTipText get_Description() +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.Text.TaggedText[] ReturnTypeText +FSharp.Compiler.EditorServices.MethodGroupItem: FSharp.Compiler.Text.TaggedText[] get_ReturnTypeText() +FSharp.Compiler.EditorServices.MethodGroupItemParameter +FSharp.Compiler.EditorServices.MethodGroupItemParameter: Boolean IsOptional +FSharp.Compiler.EditorServices.MethodGroupItemParameter: Boolean get_IsOptional() +FSharp.Compiler.EditorServices.MethodGroupItemParameter: FSharp.Compiler.Text.TaggedText[] Display +FSharp.Compiler.EditorServices.MethodGroupItemParameter: FSharp.Compiler.Text.TaggedText[] get_Display() +FSharp.Compiler.EditorServices.MethodGroupItemParameter: System.String CanonicalTypeTextForSorting +FSharp.Compiler.EditorServices.MethodGroupItemParameter: System.String ParameterName +FSharp.Compiler.EditorServices.MethodGroupItemParameter: System.String get_CanonicalTypeTextForSorting() +FSharp.Compiler.EditorServices.MethodGroupItemParameter: System.String get_ParameterName() +FSharp.Compiler.EditorServices.ModuleKind +FSharp.Compiler.EditorServices.ModuleKind: Boolean Equals(FSharp.Compiler.EditorServices.ModuleKind) +FSharp.Compiler.EditorServices.ModuleKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.ModuleKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ModuleKind: Boolean HasModuleSuffix +FSharp.Compiler.EditorServices.ModuleKind: Boolean IsAutoOpen +FSharp.Compiler.EditorServices.ModuleKind: Boolean get_HasModuleSuffix() +FSharp.Compiler.EditorServices.ModuleKind: Boolean get_IsAutoOpen() +FSharp.Compiler.EditorServices.ModuleKind: Int32 CompareTo(FSharp.Compiler.EditorServices.ModuleKind) +FSharp.Compiler.EditorServices.ModuleKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.ModuleKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.ModuleKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.ModuleKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ModuleKind: System.String ToString() +FSharp.Compiler.EditorServices.ModuleKind: Void .ctor(Boolean, Boolean) +FSharp.Compiler.EditorServices.NavigableContainer +FSharp.Compiler.EditorServices.NavigableContainer: Boolean Equals(FSharp.Compiler.EditorServices.NavigableContainer) +FSharp.Compiler.EditorServices.NavigableContainer: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigableContainer: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableContainer: FSharp.Compiler.EditorServices.NavigableContainerType Type +FSharp.Compiler.EditorServices.NavigableContainer: FSharp.Compiler.EditorServices.NavigableContainerType get_Type() +FSharp.Compiler.EditorServices.NavigableContainer: Int32 CompareTo(FSharp.Compiler.EditorServices.NavigableContainer) +FSharp.Compiler.EditorServices.NavigableContainer: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.NavigableContainer: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.NavigableContainer: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigableContainer: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableContainer: System.String Name +FSharp.Compiler.EditorServices.NavigableContainer: System.String ToString() +FSharp.Compiler.EditorServices.NavigableContainer: System.String get_Name() +FSharp.Compiler.EditorServices.NavigableContainer: Void .ctor(FSharp.Compiler.EditorServices.NavigableContainerType, System.String) +FSharp.Compiler.EditorServices.NavigableContainerType +FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 Exception +FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 File +FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 Module +FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 Namespace +FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 Type +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean Equals(FSharp.Compiler.EditorServices.NavigableContainerType) +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean IsException +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean IsFile +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean IsModule +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean IsNamespace +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean IsType +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean get_IsException() +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean get_IsFile() +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean get_IsModule() +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean get_IsNamespace() +FSharp.Compiler.EditorServices.NavigableContainerType: Boolean get_IsType() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType Exception +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType File +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType Module +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType Namespace +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType Type +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType get_Exception() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType get_File() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType get_Module() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType get_Namespace() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType get_Type() +FSharp.Compiler.EditorServices.NavigableContainerType: FSharp.Compiler.EditorServices.NavigableContainerType+Tags +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 CompareTo(FSharp.Compiler.EditorServices.NavigableContainerType) +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 Tag +FSharp.Compiler.EditorServices.NavigableContainerType: Int32 get_Tag() +FSharp.Compiler.EditorServices.NavigableContainerType: System.String ToString() +FSharp.Compiler.EditorServices.NavigableItem +FSharp.Compiler.EditorServices.NavigableItem: Boolean Equals(FSharp.Compiler.EditorServices.NavigableItem) +FSharp.Compiler.EditorServices.NavigableItem: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigableItem: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableItem: Boolean IsSignature +FSharp.Compiler.EditorServices.NavigableItem: Boolean get_IsSignature() +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.EditorServices.NavigableContainer Container +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.EditorServices.NavigableContainer get_Container() +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.EditorServices.NavigableItemKind Kind +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.EditorServices.NavigableItemKind get_Kind() +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableItem: System.String Name +FSharp.Compiler.EditorServices.NavigableItem: System.String ToString() +FSharp.Compiler.EditorServices.NavigableItem: System.String get_Name() +FSharp.Compiler.EditorServices.NavigableItem: Void .ctor(System.String, FSharp.Compiler.Text.Range, Boolean, FSharp.Compiler.EditorServices.NavigableItemKind, FSharp.Compiler.EditorServices.NavigableContainer) +FSharp.Compiler.EditorServices.NavigableItemKind +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Constructor +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 EnumCase +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Exception +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Field +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Member +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Module +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 ModuleAbbreviation +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 ModuleValue +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Property +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Type +FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 UnionCase +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean Equals(FSharp.Compiler.EditorServices.NavigableItemKind) +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsConstructor +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsEnumCase +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsException +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsField +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsMember +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsModule +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsModuleAbbreviation +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsModuleValue +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsProperty +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsType +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean IsUnionCase +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsConstructor() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsEnumCase() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsException() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsField() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsMember() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsModule() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsModuleAbbreviation() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsModuleValue() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsType() +FSharp.Compiler.EditorServices.NavigableItemKind: Boolean get_IsUnionCase() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Constructor +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind EnumCase +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Exception +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Field +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Member +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Module +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind ModuleAbbreviation +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind ModuleValue +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Property +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind Type +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind UnionCase +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Constructor() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_EnumCase() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Exception() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Field() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Member() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Module() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_ModuleAbbreviation() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_ModuleValue() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Property() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_Type() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind get_UnionCase() +FSharp.Compiler.EditorServices.NavigableItemKind: FSharp.Compiler.EditorServices.NavigableItemKind+Tags +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 CompareTo(FSharp.Compiler.EditorServices.NavigableItemKind) +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 Tag +FSharp.Compiler.EditorServices.NavigableItemKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.NavigableItemKind: System.String ToString() +FSharp.Compiler.EditorServices.NavigateTo +FSharp.Compiler.EditorServices.NavigateTo: FSharp.Compiler.EditorServices.NavigableItem[] GetNavigableItems(FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.Navigation +FSharp.Compiler.EditorServices.Navigation: FSharp.Compiler.EditorServices.NavigationItems getNavigation(FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.NavigationEntityKind +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Class +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Enum +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Exception +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Interface +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Module +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Namespace +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Record +FSharp.Compiler.EditorServices.NavigationEntityKind+Tags: Int32 Union +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean Equals(FSharp.Compiler.EditorServices.NavigationEntityKind) +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsClass +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsEnum +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsException +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsInterface +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsModule +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsNamespace +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsRecord +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean IsUnion +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsClass() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsEnum() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsException() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsInterface() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsModule() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsNamespace() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsRecord() +FSharp.Compiler.EditorServices.NavigationEntityKind: Boolean get_IsUnion() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Class +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Enum +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Exception +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Interface +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Module +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Namespace +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Record +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind Union +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Class() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Enum() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Exception() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Interface() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Module() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Namespace() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Record() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind get_Union() +FSharp.Compiler.EditorServices.NavigationEntityKind: FSharp.Compiler.EditorServices.NavigationEntityKind+Tags +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 CompareTo(FSharp.Compiler.EditorServices.NavigationEntityKind) +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 Tag +FSharp.Compiler.EditorServices.NavigationEntityKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.NavigationEntityKind: System.String ToString() +FSharp.Compiler.EditorServices.NavigationItem +FSharp.Compiler.EditorServices.NavigationItem: Boolean IsAbstract +FSharp.Compiler.EditorServices.NavigationItem: Boolean IsSingleTopLevel +FSharp.Compiler.EditorServices.NavigationItem: Boolean get_IsAbstract() +FSharp.Compiler.EditorServices.NavigationItem: Boolean get_IsSingleTopLevel() +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.FSharpGlyph Glyph +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.FSharpGlyph get_Glyph() +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.NavigationEntityKind EnclosingEntityKind +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.NavigationEntityKind get_EnclosingEntityKind() +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.NavigationItemKind Kind +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.EditorServices.NavigationItemKind get_Kind() +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range BodyRange +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range get_BodyRange() +FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.NavigationItem: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] Access +FSharp.Compiler.EditorServices.NavigationItem: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_Access() +FSharp.Compiler.EditorServices.NavigationItem: System.String Name +FSharp.Compiler.EditorServices.NavigationItem: System.String UniqueName +FSharp.Compiler.EditorServices.NavigationItem: System.String get_Name() +FSharp.Compiler.EditorServices.NavigationItem: System.String get_UniqueName() +FSharp.Compiler.EditorServices.NavigationItemKind +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Exception +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Field +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Method +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Module +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 ModuleFile +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Namespace +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Other +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Property +FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Type +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean Equals(FSharp.Compiler.EditorServices.NavigationItemKind) +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsException +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsField +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsMethod +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsModule +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsModuleFile +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsNamespace +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsOther +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsProperty +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean IsType +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsException() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsField() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsMethod() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsModule() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsModuleFile() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsNamespace() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsOther() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsProperty() +FSharp.Compiler.EditorServices.NavigationItemKind: Boolean get_IsType() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Exception +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Field +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Method +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Module +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind ModuleFile +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Namespace +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Other +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Property +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind Type +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Exception() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Field() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Method() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Module() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_ModuleFile() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Namespace() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Other() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Property() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind get_Type() +FSharp.Compiler.EditorServices.NavigationItemKind: FSharp.Compiler.EditorServices.NavigationItemKind+Tags +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 CompareTo(FSharp.Compiler.EditorServices.NavigationItemKind) +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 Tag +FSharp.Compiler.EditorServices.NavigationItemKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.NavigationItemKind: System.String ToString() +FSharp.Compiler.EditorServices.NavigationItems +FSharp.Compiler.EditorServices.NavigationItems: FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration[] Declarations +FSharp.Compiler.EditorServices.NavigationItems: FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration[] get_Declarations() +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: FSharp.Compiler.EditorServices.NavigationItem Declaration +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: FSharp.Compiler.EditorServices.NavigationItem get_Declaration() +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: FSharp.Compiler.EditorServices.NavigationItem[] Nested +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: FSharp.Compiler.EditorServices.NavigationItem[] get_Nested() +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: System.String ToString() +FSharp.Compiler.EditorServices.NavigationTopLevelDeclaration: Void .ctor(FSharp.Compiler.EditorServices.NavigationItem, FSharp.Compiler.EditorServices.NavigationItem[]) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint+Tags: Int32 Nearest +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint+Tags: Int32 TopLevel +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean Equals(FSharp.Compiler.EditorServices.OpenStatementInsertionPoint) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean IsNearest +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean IsTopLevel +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean get_IsNearest() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Boolean get_IsTopLevel() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: FSharp.Compiler.EditorServices.OpenStatementInsertionPoint Nearest +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: FSharp.Compiler.EditorServices.OpenStatementInsertionPoint TopLevel +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: FSharp.Compiler.EditorServices.OpenStatementInsertionPoint get_Nearest() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: FSharp.Compiler.EditorServices.OpenStatementInsertionPoint get_TopLevel() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: FSharp.Compiler.EditorServices.OpenStatementInsertionPoint+Tags +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 CompareTo(FSharp.Compiler.EditorServices.OpenStatementInsertionPoint) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 GetHashCode() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 Tag +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: Int32 get_Tag() +FSharp.Compiler.EditorServices.OpenStatementInsertionPoint: System.String ToString() +FSharp.Compiler.EditorServices.ParameterLocations +FSharp.Compiler.EditorServices.ParameterLocations: Boolean IsThereACloseParen +FSharp.Compiler.EditorServices.ParameterLocations: Boolean get_IsThereACloseParen() +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position LongIdEndLocation +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position LongIdStartLocation +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position OpenParenLocation +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position get_LongIdEndLocation() +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position get_LongIdStartLocation() +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position get_OpenParenLocation() +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position[] TupleEndLocations +FSharp.Compiler.EditorServices.ParameterLocations: FSharp.Compiler.Text.Position[] get_TupleEndLocations() +FSharp.Compiler.EditorServices.ParameterLocations: Microsoft.FSharp.Collections.FSharpList`1[System.String] LongId +FSharp.Compiler.EditorServices.ParameterLocations: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_LongId() +FSharp.Compiler.EditorServices.ParameterLocations: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.ParameterLocations] Find(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ParameterLocations: Microsoft.FSharp.Core.FSharpOption`1[System.String][] NamedParamNames +FSharp.Compiler.EditorServices.ParameterLocations: Microsoft.FSharp.Core.FSharpOption`1[System.String][] get_NamedParamNames() +FSharp.Compiler.EditorServices.ParsedInput +FSharp.Compiler.EditorServices.ParsedInput: FSharp.Compiler.EditorServices.InsertionContext FindNearestPointToInsertOpenDeclaration(Int32, FSharp.Compiler.Syntax.ParsedInput, System.String[], FSharp.Compiler.EditorServices.OpenStatementInsertionPoint) +FSharp.Compiler.EditorServices.ParsedInput: FSharp.Compiler.Text.Position AdjustInsertionPoint(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String], FSharp.Compiler.EditorServices.InsertionContext) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[System.String[]],Microsoft.FSharp.Core.FSharpOption`1[System.String[]],Microsoft.FSharp.Core.FSharpOption`1[System.String[]],System.String[]],System.Tuple`2[FSharp.Compiler.EditorServices.InsertionContextEntity,FSharp.Compiler.EditorServices.InsertionContext][]] TryFindInsertionContext(Int32, FSharp.Compiler.Syntax.ParsedInput, FSharp.Compiler.EditorServices.MaybeUnresolvedIdent[], FSharp.Compiler.EditorServices.OpenStatementInsertionPoint) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.CompletionContext] TryGetCompletionContext(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput, System.String) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.EditorServices.EntityKind] GetEntityKind(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] GetRangeOfExprLeftOfDot(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident]] GetLongIdentAt(FSharp.Compiler.Syntax.ParsedInput, FSharp.Compiler.Text.Position) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryFindExpressionIslandInPosition(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ParsedInput: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Position,System.Boolean]] TryFindExpressionASTLeftOfDotLeftOfCursor(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ParsedInput: System.String[] GetFullNameOfSmallestModuleOrNamespaceAtPoint(FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.PartialLongName +FSharp.Compiler.EditorServices.PartialLongName: Boolean Equals(FSharp.Compiler.EditorServices.PartialLongName) +FSharp.Compiler.EditorServices.PartialLongName: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.PartialLongName: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PartialLongName: FSharp.Compiler.EditorServices.PartialLongName Empty(Int32) +FSharp.Compiler.EditorServices.PartialLongName: Int32 CompareTo(FSharp.Compiler.EditorServices.PartialLongName) +FSharp.Compiler.EditorServices.PartialLongName: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.PartialLongName: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.PartialLongName: Int32 EndColumn +FSharp.Compiler.EditorServices.PartialLongName: Int32 GetHashCode() +FSharp.Compiler.EditorServices.PartialLongName: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.PartialLongName: Int32 get_EndColumn() +FSharp.Compiler.EditorServices.PartialLongName: Microsoft.FSharp.Collections.FSharpList`1[System.String] QualifyingIdents +FSharp.Compiler.EditorServices.PartialLongName: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_QualifyingIdents() +FSharp.Compiler.EditorServices.PartialLongName: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] LastDotPos +FSharp.Compiler.EditorServices.PartialLongName: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_LastDotPos() +FSharp.Compiler.EditorServices.PartialLongName: System.String PartialIdent +FSharp.Compiler.EditorServices.PartialLongName: System.String ToString() +FSharp.Compiler.EditorServices.PartialLongName: System.String get_PartialIdent() +FSharp.Compiler.EditorServices.PartialLongName: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[System.String], System.String, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +FSharp.Compiler.EditorServices.QuickParse +FSharp.Compiler.EditorServices.QuickParse: Boolean TestMemberOrOverrideDeclaration(FSharp.Compiler.Tokenization.FSharpTokenInfo[]) +FSharp.Compiler.EditorServices.QuickParse: FSharp.Compiler.EditorServices.PartialLongName GetPartialLongNameEx(System.String, Int32) +FSharp.Compiler.EditorServices.QuickParse: Int32 CorrectIdentifierToken(System.String, Int32) +FSharp.Compiler.EditorServices.QuickParse: Int32 MagicalAdjustmentConstant +FSharp.Compiler.EditorServices.QuickParse: Int32 get_MagicalAdjustmentConstant() +FSharp.Compiler.EditorServices.QuickParse: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.String,System.Int32,System.Boolean]] GetCompleteIdentifierIsland(Boolean, System.String, Int32) +FSharp.Compiler.EditorServices.QuickParse: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],System.String] GetPartialLongName(System.String, Int32) +FSharp.Compiler.EditorServices.RecordContext +FSharp.Compiler.EditorServices.RecordContext+Constructor: System.String get_typeName() +FSharp.Compiler.EditorServices.RecordContext+Constructor: System.String typeName +FSharp.Compiler.EditorServices.RecordContext+CopyOnUpdate: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.EditorServices.RecordContext+CopyOnUpdate: FSharp.Compiler.Text.Range range +FSharp.Compiler.EditorServices.RecordContext+CopyOnUpdate: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] get_path() +FSharp.Compiler.EditorServices.RecordContext+CopyOnUpdate: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] path +FSharp.Compiler.EditorServices.RecordContext+New: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] get_path() +FSharp.Compiler.EditorServices.RecordContext+New: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]] path +FSharp.Compiler.EditorServices.RecordContext+Tags: Int32 Constructor +FSharp.Compiler.EditorServices.RecordContext+Tags: Int32 CopyOnUpdate +FSharp.Compiler.EditorServices.RecordContext+Tags: Int32 New +FSharp.Compiler.EditorServices.RecordContext: Boolean Equals(FSharp.Compiler.EditorServices.RecordContext) +FSharp.Compiler.EditorServices.RecordContext: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.RecordContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.RecordContext: Boolean IsConstructor +FSharp.Compiler.EditorServices.RecordContext: Boolean IsCopyOnUpdate +FSharp.Compiler.EditorServices.RecordContext: Boolean IsNew +FSharp.Compiler.EditorServices.RecordContext: Boolean get_IsConstructor() +FSharp.Compiler.EditorServices.RecordContext: Boolean get_IsCopyOnUpdate() +FSharp.Compiler.EditorServices.RecordContext: Boolean get_IsNew() +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext NewConstructor(System.String) +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext NewCopyOnUpdate(FSharp.Compiler.Text.Range, System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]]) +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext NewNew(System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],Microsoft.FSharp.Core.FSharpOption`1[System.String]]) +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext+Constructor +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext+CopyOnUpdate +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext+New +FSharp.Compiler.EditorServices.RecordContext: FSharp.Compiler.EditorServices.RecordContext+Tags +FSharp.Compiler.EditorServices.RecordContext: Int32 GetHashCode() +FSharp.Compiler.EditorServices.RecordContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.RecordContext: Int32 Tag +FSharp.Compiler.EditorServices.RecordContext: Int32 get_Tag() +FSharp.Compiler.EditorServices.RecordContext: System.String ToString() +FSharp.Compiler.EditorServices.ScopeKind +FSharp.Compiler.EditorServices.ScopeKind+Tags: Int32 HashDirective +FSharp.Compiler.EditorServices.ScopeKind+Tags: Int32 Namespace +FSharp.Compiler.EditorServices.ScopeKind+Tags: Int32 NestedModule +FSharp.Compiler.EditorServices.ScopeKind+Tags: Int32 OpenDeclaration +FSharp.Compiler.EditorServices.ScopeKind+Tags: Int32 TopModule +FSharp.Compiler.EditorServices.ScopeKind: Boolean Equals(FSharp.Compiler.EditorServices.ScopeKind) +FSharp.Compiler.EditorServices.ScopeKind: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.ScopeKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ScopeKind: Boolean IsHashDirective +FSharp.Compiler.EditorServices.ScopeKind: Boolean IsNamespace +FSharp.Compiler.EditorServices.ScopeKind: Boolean IsNestedModule +FSharp.Compiler.EditorServices.ScopeKind: Boolean IsOpenDeclaration +FSharp.Compiler.EditorServices.ScopeKind: Boolean IsTopModule +FSharp.Compiler.EditorServices.ScopeKind: Boolean get_IsHashDirective() +FSharp.Compiler.EditorServices.ScopeKind: Boolean get_IsNamespace() +FSharp.Compiler.EditorServices.ScopeKind: Boolean get_IsNestedModule() +FSharp.Compiler.EditorServices.ScopeKind: Boolean get_IsOpenDeclaration() +FSharp.Compiler.EditorServices.ScopeKind: Boolean get_IsTopModule() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind HashDirective +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind Namespace +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind NestedModule +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind OpenDeclaration +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind TopModule +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind get_HashDirective() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind get_Namespace() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind get_NestedModule() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind get_OpenDeclaration() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind get_TopModule() +FSharp.Compiler.EditorServices.ScopeKind: FSharp.Compiler.EditorServices.ScopeKind+Tags +FSharp.Compiler.EditorServices.ScopeKind: Int32 CompareTo(FSharp.Compiler.EditorServices.ScopeKind) +FSharp.Compiler.EditorServices.ScopeKind: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.ScopeKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.ScopeKind: Int32 GetHashCode() +FSharp.Compiler.EditorServices.ScopeKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ScopeKind: Int32 Tag +FSharp.Compiler.EditorServices.ScopeKind: Int32 get_Tag() +FSharp.Compiler.EditorServices.ScopeKind: System.String ToString() +FSharp.Compiler.EditorServices.SemanticClassificationItem +FSharp.Compiler.EditorServices.SemanticClassificationItem: Boolean Equals(FSharp.Compiler.EditorServices.SemanticClassificationItem) +FSharp.Compiler.EditorServices.SemanticClassificationItem: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.SemanticClassificationItem: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.SemanticClassificationItem: FSharp.Compiler.EditorServices.SemanticClassificationType Type +FSharp.Compiler.EditorServices.SemanticClassificationItem: FSharp.Compiler.EditorServices.SemanticClassificationType get_Type() +FSharp.Compiler.EditorServices.SemanticClassificationItem: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.SemanticClassificationItem: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.SemanticClassificationItem: Int32 GetHashCode() +FSharp.Compiler.EditorServices.SemanticClassificationItem: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.SemanticClassificationItem: Void .ctor(System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.EditorServices.SemanticClassificationType]) +FSharp.Compiler.EditorServices.SemanticClassificationType +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ComputationExpression +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ConstructorForReferenceType +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ConstructorForValueType +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Delegate +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType DisposableLocalValue +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType DisposableTopLevelValue +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType DisposableType +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Enumeration +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Event +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Exception +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ExtensionMethod +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Field +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Function +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Interface +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType IntrinsicFunction +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Literal +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType LocalValue +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Method +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Module +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType MutableRecordField +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType MutableVar +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType NamedArgument +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Namespace +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Operator +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Plaintext +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Printf +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Property +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType RecordField +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType RecordFieldAsFunction +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ReferenceType +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Type +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType TypeArgument +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType TypeDef +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType UnionCase +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType UnionCaseField +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType Value +FSharp.Compiler.EditorServices.SemanticClassificationType: FSharp.Compiler.EditorServices.SemanticClassificationType ValueType +FSharp.Compiler.EditorServices.SemanticClassificationType: Int32 value__ +FSharp.Compiler.EditorServices.SemanticClassificationView +FSharp.Compiler.EditorServices.SemanticClassificationView: Void ForEach(Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.SemanticClassificationItem,Microsoft.FSharp.Core.Unit]) +FSharp.Compiler.EditorServices.SimplifyNames +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Boolean Equals(SimplifiableRange) +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Int32 GetHashCode() +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: System.String RelativeName +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: System.String ToString() +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: System.String get_RelativeName() +FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange: Void .ctor(FSharp.Compiler.Text.Range, System.String) +FSharp.Compiler.EditorServices.SimplifyNames: FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange +FSharp.Compiler.EditorServices.SimplifyNames: Microsoft.FSharp.Control.FSharpAsync`1[System.Collections.Generic.IEnumerable`1[FSharp.Compiler.EditorServices.SimplifyNames+SimplifiableRange]] getSimplifiableNames(FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String]) +FSharp.Compiler.EditorServices.Structure +FSharp.Compiler.EditorServices.Structure+Collapse+Tags: Int32 Below +FSharp.Compiler.EditorServices.Structure+Collapse+Tags: Int32 Same +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean Equals(Collapse) +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean IsBelow +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean IsSame +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean get_IsBelow() +FSharp.Compiler.EditorServices.Structure+Collapse: Boolean get_IsSame() +FSharp.Compiler.EditorServices.Structure+Collapse: Collapse Below +FSharp.Compiler.EditorServices.Structure+Collapse: Collapse Same +FSharp.Compiler.EditorServices.Structure+Collapse: Collapse get_Below() +FSharp.Compiler.EditorServices.Structure+Collapse: Collapse get_Same() +FSharp.Compiler.EditorServices.Structure+Collapse: FSharp.Compiler.EditorServices.Structure+Collapse+Tags +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 CompareTo(Collapse) +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 GetHashCode() +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 Tag +FSharp.Compiler.EditorServices.Structure+Collapse: Int32 get_Tag() +FSharp.Compiler.EditorServices.Structure+Collapse: System.String ToString() +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 ArrayOrList +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Attribute +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Comment +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 ComputationExpr +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Do +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 ElseInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 EnumCase +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 FinallyInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 For +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 HashDirective +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 IfThenElse +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Interface +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Lambda +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 LetOrUse +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 LetOrUseBang +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Match +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 MatchBang +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 MatchClause +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 MatchLambda +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Member +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Module +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Namespace +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 New +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 ObjExpr +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Open +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Quote +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Record +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 RecordDefn +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 RecordField +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 SpecialFunc +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 ThenInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 TryFinally +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 TryInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 TryInTryWith +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 TryWith +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Tuple +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Type +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 TypeExtension +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 UnionCase +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 UnionDefn +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 Val +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 While +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 WithInTryWith +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 XmlDocComment +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 YieldOrReturn +FSharp.Compiler.EditorServices.Structure+Scope+Tags: Int32 YieldOrReturnBang +FSharp.Compiler.EditorServices.Structure+Scope: Boolean Equals(Scope) +FSharp.Compiler.EditorServices.Structure+Scope: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.Structure+Scope: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsArrayOrList +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsAttribute +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsComment +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsComputationExpr +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsDo +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsElseInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsEnumCase +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsFinallyInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsFor +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsHashDirective +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsInterface +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsLambda +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsLetOrUse +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsLetOrUseBang +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsMatch +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsMatchBang +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsMatchClause +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsMatchLambda +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsMember +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsModule +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsNamespace +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsNew +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsObjExpr +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsOpen +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsQuote +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsRecord +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsRecordDefn +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsRecordField +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsSpecialFunc +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsThenInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTryInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTryInTryWith +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTryWith +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTuple +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsType +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsTypeExtension +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsUnionCase +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsUnionDefn +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsVal +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsWhile +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsWithInTryWith +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsXmlDocComment +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsYieldOrReturn +FSharp.Compiler.EditorServices.Structure+Scope: Boolean IsYieldOrReturnBang +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsArrayOrList() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsAttribute() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsComment() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsComputationExpr() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsDo() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsElseInIfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsEnumCase() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsFinallyInTryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsFor() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsHashDirective() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsIfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsInterface() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsLambda() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsLetOrUse() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsLetOrUseBang() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsMatch() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsMatchBang() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsMatchClause() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsMatchLambda() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsMember() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsModule() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsNamespace() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsNew() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsObjExpr() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsOpen() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsQuote() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsRecord() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsRecordDefn() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsRecordField() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsSpecialFunc() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsThenInIfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTryInTryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTryInTryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTuple() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsType() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsTypeExtension() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsUnionCase() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsUnionDefn() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsVal() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsWhile() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsWithInTryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsXmlDocComment() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsYieldOrReturn() +FSharp.Compiler.EditorServices.Structure+Scope: Boolean get_IsYieldOrReturnBang() +FSharp.Compiler.EditorServices.Structure+Scope: FSharp.Compiler.EditorServices.Structure+Scope+Tags +FSharp.Compiler.EditorServices.Structure+Scope: Int32 CompareTo(Scope) +FSharp.Compiler.EditorServices.Structure+Scope: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.Structure+Scope: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.Structure+Scope: Int32 GetHashCode() +FSharp.Compiler.EditorServices.Structure+Scope: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+Scope: Int32 Tag +FSharp.Compiler.EditorServices.Structure+Scope: Int32 get_Tag() +FSharp.Compiler.EditorServices.Structure+Scope: Scope ArrayOrList +FSharp.Compiler.EditorServices.Structure+Scope: Scope Attribute +FSharp.Compiler.EditorServices.Structure+Scope: Scope Comment +FSharp.Compiler.EditorServices.Structure+Scope: Scope ComputationExpr +FSharp.Compiler.EditorServices.Structure+Scope: Scope Do +FSharp.Compiler.EditorServices.Structure+Scope: Scope ElseInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Scope EnumCase +FSharp.Compiler.EditorServices.Structure+Scope: Scope FinallyInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Scope For +FSharp.Compiler.EditorServices.Structure+Scope: Scope HashDirective +FSharp.Compiler.EditorServices.Structure+Scope: Scope IfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Scope Interface +FSharp.Compiler.EditorServices.Structure+Scope: Scope Lambda +FSharp.Compiler.EditorServices.Structure+Scope: Scope LetOrUse +FSharp.Compiler.EditorServices.Structure+Scope: Scope LetOrUseBang +FSharp.Compiler.EditorServices.Structure+Scope: Scope Match +FSharp.Compiler.EditorServices.Structure+Scope: Scope MatchBang +FSharp.Compiler.EditorServices.Structure+Scope: Scope MatchClause +FSharp.Compiler.EditorServices.Structure+Scope: Scope MatchLambda +FSharp.Compiler.EditorServices.Structure+Scope: Scope Member +FSharp.Compiler.EditorServices.Structure+Scope: Scope Module +FSharp.Compiler.EditorServices.Structure+Scope: Scope Namespace +FSharp.Compiler.EditorServices.Structure+Scope: Scope New +FSharp.Compiler.EditorServices.Structure+Scope: Scope ObjExpr +FSharp.Compiler.EditorServices.Structure+Scope: Scope Open +FSharp.Compiler.EditorServices.Structure+Scope: Scope Quote +FSharp.Compiler.EditorServices.Structure+Scope: Scope Record +FSharp.Compiler.EditorServices.Structure+Scope: Scope RecordDefn +FSharp.Compiler.EditorServices.Structure+Scope: Scope RecordField +FSharp.Compiler.EditorServices.Structure+Scope: Scope SpecialFunc +FSharp.Compiler.EditorServices.Structure+Scope: Scope ThenInIfThenElse +FSharp.Compiler.EditorServices.Structure+Scope: Scope TryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Scope TryInTryFinally +FSharp.Compiler.EditorServices.Structure+Scope: Scope TryInTryWith +FSharp.Compiler.EditorServices.Structure+Scope: Scope TryWith +FSharp.Compiler.EditorServices.Structure+Scope: Scope Tuple +FSharp.Compiler.EditorServices.Structure+Scope: Scope Type +FSharp.Compiler.EditorServices.Structure+Scope: Scope TypeExtension +FSharp.Compiler.EditorServices.Structure+Scope: Scope UnionCase +FSharp.Compiler.EditorServices.Structure+Scope: Scope UnionDefn +FSharp.Compiler.EditorServices.Structure+Scope: Scope Val +FSharp.Compiler.EditorServices.Structure+Scope: Scope While +FSharp.Compiler.EditorServices.Structure+Scope: Scope WithInTryWith +FSharp.Compiler.EditorServices.Structure+Scope: Scope XmlDocComment +FSharp.Compiler.EditorServices.Structure+Scope: Scope YieldOrReturn +FSharp.Compiler.EditorServices.Structure+Scope: Scope YieldOrReturnBang +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_ArrayOrList() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Attribute() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Comment() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_ComputationExpr() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Do() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_ElseInIfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_EnumCase() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_FinallyInTryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_For() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_HashDirective() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_IfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Interface() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Lambda() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_LetOrUse() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_LetOrUseBang() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Match() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_MatchBang() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_MatchClause() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_MatchLambda() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Member() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Module() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Namespace() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_New() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_ObjExpr() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Open() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Quote() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Record() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_RecordDefn() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_RecordField() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_SpecialFunc() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_ThenInIfThenElse() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_TryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_TryInTryFinally() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_TryInTryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_TryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Tuple() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Type() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_TypeExtension() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_UnionCase() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_UnionDefn() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_Val() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_While() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_WithInTryWith() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_XmlDocComment() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_YieldOrReturn() +FSharp.Compiler.EditorServices.Structure+Scope: Scope get_YieldOrReturnBang() +FSharp.Compiler.EditorServices.Structure+Scope: System.String ToString() +FSharp.Compiler.EditorServices.Structure+ScopeRange: Boolean Equals(ScopeRange) +FSharp.Compiler.EditorServices.Structure+ScopeRange: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.Structure+ScopeRange: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+ScopeRange: Collapse Collapse +FSharp.Compiler.EditorServices.Structure+ScopeRange: Collapse get_Collapse() +FSharp.Compiler.EditorServices.Structure+ScopeRange: FSharp.Compiler.Text.Range CollapseRange +FSharp.Compiler.EditorServices.Structure+ScopeRange: FSharp.Compiler.Text.Range Range +FSharp.Compiler.EditorServices.Structure+ScopeRange: FSharp.Compiler.Text.Range get_CollapseRange() +FSharp.Compiler.EditorServices.Structure+ScopeRange: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.EditorServices.Structure+ScopeRange: Int32 GetHashCode() +FSharp.Compiler.EditorServices.Structure+ScopeRange: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.Structure+ScopeRange: Scope Scope +FSharp.Compiler.EditorServices.Structure+ScopeRange: Scope get_Scope() +FSharp.Compiler.EditorServices.Structure+ScopeRange: System.String ToString() +FSharp.Compiler.EditorServices.Structure+ScopeRange: Void .ctor(Scope, Collapse, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.EditorServices.Structure: FSharp.Compiler.EditorServices.Structure+Collapse +FSharp.Compiler.EditorServices.Structure: FSharp.Compiler.EditorServices.Structure+Scope +FSharp.Compiler.EditorServices.Structure: FSharp.Compiler.EditorServices.Structure+ScopeRange +FSharp.Compiler.EditorServices.Structure: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.EditorServices.Structure+ScopeRange] getOutliningRanges(System.String[], FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.ToolTipElement +FSharp.Compiler.EditorServices.ToolTipElement+CompositionError: System.String errorText +FSharp.Compiler.EditorServices.ToolTipElement+CompositionError: System.String get_errorText() +FSharp.Compiler.EditorServices.ToolTipElement+Group: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElementData] elements +FSharp.Compiler.EditorServices.ToolTipElement+Group: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElementData] get_elements() +FSharp.Compiler.EditorServices.ToolTipElement+Tags: Int32 CompositionError +FSharp.Compiler.EditorServices.ToolTipElement+Tags: Int32 Group +FSharp.Compiler.EditorServices.ToolTipElement+Tags: Int32 None +FSharp.Compiler.EditorServices.ToolTipElement: Boolean Equals(FSharp.Compiler.EditorServices.ToolTipElement) +FSharp.Compiler.EditorServices.ToolTipElement: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.ToolTipElement: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipElement: Boolean IsCompositionError +FSharp.Compiler.EditorServices.ToolTipElement: Boolean IsGroup +FSharp.Compiler.EditorServices.ToolTipElement: Boolean IsNone +FSharp.Compiler.EditorServices.ToolTipElement: Boolean get_IsCompositionError() +FSharp.Compiler.EditorServices.ToolTipElement: Boolean get_IsGroup() +FSharp.Compiler.EditorServices.ToolTipElement: Boolean get_IsNone() +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement NewCompositionError(System.String) +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement NewGroup(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElementData]) +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement None +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement Single(FSharp.Compiler.Text.TaggedText[], FSharp.Compiler.Symbols.FSharpXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.TaggedText[]]], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.TaggedText[]]) +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement get_None() +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement+CompositionError +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement+Group +FSharp.Compiler.EditorServices.ToolTipElement: FSharp.Compiler.EditorServices.ToolTipElement+Tags +FSharp.Compiler.EditorServices.ToolTipElement: Int32 GetHashCode() +FSharp.Compiler.EditorServices.ToolTipElement: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipElement: Int32 Tag +FSharp.Compiler.EditorServices.ToolTipElement: Int32 get_Tag() +FSharp.Compiler.EditorServices.ToolTipElement: System.String ToString() +FSharp.Compiler.EditorServices.ToolTipElementData +FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(FSharp.Compiler.EditorServices.ToolTipElementData) +FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Text.TaggedText[] MainDescription +FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Text.TaggedText[] get_MainDescription() +FSharp.Compiler.EditorServices.ToolTipElementData: Int32 GetHashCode() +FSharp.Compiler.EditorServices.ToolTipElementData: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.TaggedText[]] TypeMapping +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.TaggedText[]] get_TypeMapping() +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.TaggedText[]] Remarks +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.TaggedText[]] get_Remarks() +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Core.FSharpOption`1[System.String] ParamName +FSharp.Compiler.EditorServices.ToolTipElementData: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_ParamName() +FSharp.Compiler.EditorServices.ToolTipElementData: System.String ToString() +FSharp.Compiler.EditorServices.ToolTipElementData: Void .ctor(FSharp.Compiler.Text.TaggedText[], FSharp.Compiler.Symbols.FSharpXmlDoc, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.TaggedText[]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.TaggedText[]], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.EditorServices.ToolTipText +FSharp.Compiler.EditorServices.ToolTipText: Boolean Equals(FSharp.Compiler.EditorServices.ToolTipText) +FSharp.Compiler.EditorServices.ToolTipText: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.ToolTipText: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipText: FSharp.Compiler.EditorServices.ToolTipText NewToolTipText(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElement]) +FSharp.Compiler.EditorServices.ToolTipText: Int32 GetHashCode() +FSharp.Compiler.EditorServices.ToolTipText: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.ToolTipText: Int32 Tag +FSharp.Compiler.EditorServices.ToolTipText: Int32 get_Tag() +FSharp.Compiler.EditorServices.ToolTipText: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElement] Item +FSharp.Compiler.EditorServices.ToolTipText: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.ToolTipElement] get_Item() +FSharp.Compiler.EditorServices.ToolTipText: System.String ToString() +FSharp.Compiler.EditorServices.UnresolvedSymbol +FSharp.Compiler.EditorServices.UnresolvedSymbol: Boolean Equals(FSharp.Compiler.EditorServices.UnresolvedSymbol) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Int32 CompareTo(FSharp.Compiler.EditorServices.UnresolvedSymbol) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.UnresolvedSymbol: Int32 GetHashCode() +FSharp.Compiler.EditorServices.UnresolvedSymbol: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String DisplayName +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String FullName +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String ToString() +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String get_DisplayName() +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String get_FullName() +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String[] Namespace +FSharp.Compiler.EditorServices.UnresolvedSymbol: System.String[] get_Namespace() +FSharp.Compiler.EditorServices.UnresolvedSymbol: Void .ctor(System.String, System.String, System.String[]) +FSharp.Compiler.EditorServices.UnusedDeclarations +FSharp.Compiler.EditorServices.UnusedDeclarations: Microsoft.FSharp.Control.FSharpAsync`1[System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Text.Range]] getUnusedDeclarations(FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults, Boolean) +FSharp.Compiler.EditorServices.UnusedOpens +FSharp.Compiler.EditorServices.UnusedOpens: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] getUnusedOpens(FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String]) +FSharp.Compiler.EditorServices.XmlDocComment +FSharp.Compiler.EditorServices.XmlDocComment: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] IsBlank(System.String) +FSharp.Compiler.EditorServices.XmlDocParser +FSharp.Compiler.EditorServices.XmlDocParser: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.XmlDocable] GetXmlDocables(FSharp.Compiler.Text.ISourceText, FSharp.Compiler.Syntax.ParsedInput) +FSharp.Compiler.EditorServices.XmlDocable +FSharp.Compiler.EditorServices.XmlDocable: Boolean Equals(FSharp.Compiler.EditorServices.XmlDocable) +FSharp.Compiler.EditorServices.XmlDocable: Boolean Equals(System.Object) +FSharp.Compiler.EditorServices.XmlDocable: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.XmlDocable: FSharp.Compiler.EditorServices.XmlDocable NewXmlDocable(Int32, Int32, Microsoft.FSharp.Collections.FSharpList`1[System.String]) +FSharp.Compiler.EditorServices.XmlDocable: Int32 CompareTo(FSharp.Compiler.EditorServices.XmlDocable) +FSharp.Compiler.EditorServices.XmlDocable: Int32 CompareTo(System.Object) +FSharp.Compiler.EditorServices.XmlDocable: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.EditorServices.XmlDocable: Int32 GetHashCode() +FSharp.Compiler.EditorServices.XmlDocable: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.XmlDocable: Int32 Tag +FSharp.Compiler.EditorServices.XmlDocable: Int32 get_Tag() +FSharp.Compiler.EditorServices.XmlDocable: Int32 get_indent() +FSharp.Compiler.EditorServices.XmlDocable: Int32 get_line() +FSharp.Compiler.EditorServices.XmlDocable: Int32 indent +FSharp.Compiler.EditorServices.XmlDocable: Int32 line +FSharp.Compiler.EditorServices.XmlDocable: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_paramNames() +FSharp.Compiler.EditorServices.XmlDocable: Microsoft.FSharp.Collections.FSharpList`1[System.String] paramNames +FSharp.Compiler.EditorServices.XmlDocable: System.String ToString() +FSharp.Compiler.ExtensionTyping +FSharp.Compiler.ExtensionTyping+IProvidedCustomAttributeProvider: Boolean GetHasTypeProviderEditorHideMethodsAttribute(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+IProvidedCustomAttributeProvider: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Core.FSharpOption`1[System.Object]],Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,Microsoft.FSharp.Core.FSharpOption`1[System.Object]]]]] GetAttributeConstructorArgs(Microsoft.FSharp.Core.CompilerServices.ITypeProvider, System.String) +FSharp.Compiler.ExtensionTyping+IProvidedCustomAttributeProvider: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.String,System.Int32,System.Int32]] GetDefinitionLocationAttribute(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+IProvidedCustomAttributeProvider: System.String[] GetXmlDocAttributes(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: Byte[] GetManifestModuleContents(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: System.Reflection.Assembly Handle +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: System.Reflection.Assembly get_Handle() +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: System.Reflection.AssemblyName GetName() +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: System.String FullName +FSharp.Compiler.ExtensionTyping+ProvidedAssembly: System.String get_FullName() +FSharp.Compiler.ExtensionTyping+ProvidedConstructorInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedConstructorInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: ProvidedMethodInfo GetAddMethod() +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: ProvidedMethodInfo GetRemoveMethod() +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: ProvidedType EventHandlerType +FSharp.Compiler.ExtensionTyping+ProvidedEventInfo: ProvidedType get_EventHandlerType() +FSharp.Compiler.ExtensionTyping+ProvidedExpr: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedExpr: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.ExtensionTyping+ProvidedExprType] GetExprType() +FSharp.Compiler.ExtensionTyping+ProvidedExpr: ProvidedType Type +FSharp.Compiler.ExtensionTyping+ProvidedExpr: ProvidedType get_Type() +FSharp.Compiler.ExtensionTyping+ProvidedExpr: System.String UnderlyingExpressionString +FSharp.Compiler.ExtensionTyping+ProvidedExpr: System.String get_UnderlyingExpressionString() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.ExtensionTyping+ProvidedExpr] Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.ExtensionTyping+ProvidedExpr] get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: ProvidedExpr[] Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: ProvidedExpr[] get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: ProvidedMethodInfo Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr: ProvidedMethodInfo get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedConstantExpr: ProvidedType Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedConstantExpr: ProvidedType get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedConstantExpr: System.Object Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedConstantExpr: System.Object get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedDefaultExpr: ProvidedType Item +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedDefaultExpr: ProvidedType get_Item() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr Item4 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedExpr get_Item4() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedVar Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr: ProvidedVar get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr: ProvidedExpr get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLambdaExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLambdaExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLambdaExpr: ProvidedVar Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLambdaExpr: ProvidedVar get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedExpr Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedExpr get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedVar Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr: ProvidedVar get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewArrayExpr: ProvidedExpr[] Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewArrayExpr: ProvidedExpr[] get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewArrayExpr: ProvidedType Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewArrayExpr: ProvidedType get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedExpr Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedExpr get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedType Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedType get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedVar[] Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr: ProvidedVar[] get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewObjectExpr: ProvidedConstructorInfo Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewObjectExpr: ProvidedConstructorInfo get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewObjectExpr: ProvidedExpr[] Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewObjectExpr: ProvidedExpr[] get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewTupleExpr: ProvidedExpr[] Item +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewTupleExpr: ProvidedExpr[] get_Item() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedSequentialExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedSequentialExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedSequentialExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedSequentialExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryFinallyExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryFinallyExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryFinallyExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryFinallyExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr Item3 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr Item5 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr get_Item3() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedExpr get_Item5() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedVar Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedVar Item4 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedVar get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr: ProvidedVar get_Item4() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTupleGetExpr: Int32 Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTupleGetExpr: Int32 get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTupleGetExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTupleGetExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeAsExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeAsExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeAsExpr: ProvidedType Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeAsExpr: ProvidedType get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeTestExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeTestExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeTestExpr: ProvidedType Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeTestExpr: ProvidedType get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarExpr: ProvidedVar Item +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarExpr: ProvidedVar get_Item() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarSetExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarSetExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarSetExpr: ProvidedVar Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarSetExpr: ProvidedVar get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedWhileLoopExpr: ProvidedExpr Item1 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedWhileLoopExpr: ProvidedExpr Item2 +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedWhileLoopExpr: ProvidedExpr get_Item1() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedWhileLoopExpr: ProvidedExpr get_Item2() +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedCallExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedConstantExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedDefaultExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedForIntegerRangeLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedIfThenElseExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedLambdaExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedLetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedNewArrayExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedNewDelegateExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedNewObjectExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedNewTupleExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedSequentialExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedTryFinallyExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedTryWithExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedTupleGetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedTypeAsExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedTypeTestExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedVarExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedVarSetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags: Int32 ProvidedWhileLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean Equals(ProvidedExprType) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedCallExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedConstantExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedDefaultExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedForIntegerRangeLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedIfThenElseExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedLambdaExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedLetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedNewArrayExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedNewDelegateExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedNewObjectExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedNewTupleExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedSequentialExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedTryFinallyExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedTryWithExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedTupleGetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedTypeAsExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedTypeTestExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedVarExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedVarSetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean IsProvidedWhileLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedCallExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedConstantExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedDefaultExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedForIntegerRangeLoopExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedIfThenElseExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedLambdaExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedLetExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedNewArrayExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedNewDelegateExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedNewObjectExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedNewTupleExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedSequentialExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedTryFinallyExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedTryWithExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedTupleGetExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedTypeAsExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedTypeTestExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedVarExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedVarSetExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Boolean get_IsProvidedWhileLoopExpr() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedCallExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedConstantExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedDefaultExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedForIntegerRangeLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedIfThenElseExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLambdaExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedLetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewArrayExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewDelegateExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewObjectExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedNewTupleExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedSequentialExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryFinallyExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTryWithExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTupleGetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeAsExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedTypeTestExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedVarSetExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+ProvidedWhileLoopExpr +FSharp.Compiler.ExtensionTyping+ProvidedExprType: FSharp.Compiler.ExtensionTyping+ProvidedExprType+Tags +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Int32 Tag +FSharp.Compiler.ExtensionTyping+ProvidedExprType: Int32 get_Tag() +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedCallExpr(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.ExtensionTyping+ProvidedExpr], ProvidedMethodInfo, ProvidedExpr[]) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedConstantExpr(System.Object, ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedDefaultExpr(ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedForIntegerRangeLoopExpr(ProvidedVar, ProvidedExpr, ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedIfThenElseExpr(ProvidedExpr, ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedLambdaExpr(ProvidedVar, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedLetExpr(ProvidedVar, ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedNewArrayExpr(ProvidedType, ProvidedExpr[]) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedNewDelegateExpr(ProvidedType, ProvidedVar[], ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedNewObjectExpr(ProvidedConstructorInfo, ProvidedExpr[]) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedNewTupleExpr(ProvidedExpr[]) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedSequentialExpr(ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedTryFinallyExpr(ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedTryWithExpr(ProvidedExpr, ProvidedVar, ProvidedExpr, ProvidedVar, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedTupleGetExpr(ProvidedExpr, Int32) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedTypeAsExpr(ProvidedExpr, ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedTypeTestExpr(ProvidedExpr, ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedVarExpr(ProvidedVar) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedVarSetExpr(ProvidedVar, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: ProvidedExprType NewProvidedWhileLoopExpr(ProvidedExpr, ProvidedExpr) +FSharp.Compiler.ExtensionTyping+ProvidedExprType: System.String ToString() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsFamily +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsFamilyAndAssembly +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsFamilyOrAssembly +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsInitOnly +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsLiteral +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsPrivate +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsPublic +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsSpecialName +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean IsStatic +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsFamily() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsFamilyAndAssembly() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsFamilyOrAssembly() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsInitOnly() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsLiteral() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsPrivate() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsPublic() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsSpecialName() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Boolean get_IsStatic() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: ProvidedType FieldType +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: ProvidedType get_FieldType() +FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo: System.Object GetRawConstantValue() +FSharp.Compiler.ExtensionTyping+ProvidedMemberInfo: ProvidedType DeclaringType +FSharp.Compiler.ExtensionTyping+ProvidedMemberInfo: ProvidedType get_DeclaringType() +FSharp.Compiler.ExtensionTyping+ProvidedMemberInfo: System.String Name +FSharp.Compiler.ExtensionTyping+ProvidedMemberInfo: System.String get_Name() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsAbstract +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsConstructor +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsFamily +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsFamilyAndAssembly +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsFamilyOrAssembly +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsFinal +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsGenericMethod +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsHideBySig +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsPublic +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsStatic +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean IsVirtual +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsAbstract() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsConstructor() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsFamily() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsFamilyAndAssembly() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsFamilyOrAssembly() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsFinal() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsGenericMethod() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsHideBySig() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsPublic() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsStatic() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: Boolean get_IsVirtual() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: ProvidedParameterInfo[] GetParameters() +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: ProvidedParameterInfo[] GetStaticParametersForMethod(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+ProvidedMethodBase: ProvidedType[] GetGenericArguments() +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: Int32 MetadataToken +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: Int32 get_MetadataToken() +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: ProvidedType ReturnType +FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo: ProvidedType get_ReturnType() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean HasDefaultValue +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean IsIn +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean IsOptional +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean IsOut +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean get_HasDefaultValue() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean get_IsIn() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean get_IsOptional() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Boolean get_IsOut() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: ProvidedType ParameterType +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: ProvidedType get_ParameterType() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: System.Object RawDefaultValue +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: System.Object get_RawDefaultValue() +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: System.String Name +FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo: System.String get_Name() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Boolean CanRead +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Boolean CanWrite +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Boolean get_CanRead() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Boolean get_CanWrite() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: ProvidedMethodInfo GetGetMethod() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: ProvidedMethodInfo GetSetMethod() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: ProvidedParameterInfo[] GetIndexParameters() +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: ProvidedType PropertyType +FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo: ProvidedType get_PropertyType() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsAbstract +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsArray +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsByRef +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsClass +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsEnum +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsErased +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsGenericParameter +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsGenericType +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsInterface +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsMeasure +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsNestedPublic +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsPointer +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsPublic +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsSealed +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsSuppressRelocate +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsValueType +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean IsVoid +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsAbstract() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsArray() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsByRef() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsClass() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsEnum() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsErased() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsGenericParameter() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsGenericType() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsInterface() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsMeasure() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsNestedPublic() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsPointer() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsPublic() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsSealed() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsSuppressRelocate() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsValueType() +FSharp.Compiler.ExtensionTyping+ProvidedType: Boolean get_IsVoid() +FSharp.Compiler.ExtensionTyping+ProvidedType: Int32 GenericParameterPosition +FSharp.Compiler.ExtensionTyping+ProvidedType: Int32 GetArrayRank() +FSharp.Compiler.ExtensionTyping+ProvidedType: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedType: Int32 get_GenericParameterPosition() +FSharp.Compiler.ExtensionTyping+ProvidedType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeRef] TryGetILTypeRef() +FSharp.Compiler.ExtensionTyping+ProvidedType: Microsoft.FSharp.Core.FSharpOption`1[System.Object] TryGetTyconRef() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedAssembly Assembly +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedAssembly get_Assembly() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedConstructorInfo[] GetConstructors() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedEventInfo GetEvent(System.String) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedEventInfo[] GetEvents() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedFieldInfo GetField(System.String) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedFieldInfo[] GetFields() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedMethodInfo[] GetMethods() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedParameterInfo[] GetStaticParameters(Microsoft.FSharp.Core.CompilerServices.ITypeProvider) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedPropertyInfo GetProperty(System.String) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedPropertyInfo[] GetProperties() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType ApplyContext(ProvidedType, ProvidedTypeContext) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType BaseType +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType CreateNoContext(System.Type) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType GetElementType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType GetEnumUnderlyingType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType GetGenericTypeDefinition() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType GetNestedType(System.String) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType MakeArrayType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType MakeArrayType(Int32) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType MakeByRefType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType MakeGenericType(ProvidedType[]) +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType MakePointerType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType Void +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType get_BaseType() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType get_Void() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedTypeContext Context +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedTypeContext get_Context() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType[] GetAllNestedTypes() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType[] GetGenericArguments() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType[] GetInterfaces() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedType[] GetNestedTypes() +FSharp.Compiler.ExtensionTyping+ProvidedType: ProvidedVar AsProvidedVar(System.String) +FSharp.Compiler.ExtensionTyping+ProvidedType: System.String FullName +FSharp.Compiler.ExtensionTyping+ProvidedType: System.String Namespace +FSharp.Compiler.ExtensionTyping+ProvidedType: System.String get_FullName() +FSharp.Compiler.ExtensionTyping+ProvidedType: System.String get_Namespace() +FSharp.Compiler.ExtensionTyping+ProvidedType: System.Type RawSystemType +FSharp.Compiler.ExtensionTyping+ProvidedType: System.Type get_RawSystemType() +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Boolean Equals(ProvidedTypeContext) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILTypeRef] TryGetILTypeRef(ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: Microsoft.FSharp.Core.FSharpOption`1[System.Object] TryGetTyconRef(ProvidedType) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: ProvidedTypeContext Create(System.Collections.Concurrent.ConcurrentDictionary`2[FSharp.Compiler.ExtensionTyping+ProvidedType,FSharp.Compiler.AbstractIL.IL+ILTypeRef], System.Collections.Concurrent.ConcurrentDictionary`2[FSharp.Compiler.ExtensionTyping+ProvidedType,System.Object]) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: ProvidedTypeContext Empty +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: ProvidedTypeContext RemapTyconRefs(Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]) +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: ProvidedTypeContext get_Empty() +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: System.String ToString() +FSharp.Compiler.ExtensionTyping+ProvidedTypeContext: System.Tuple`2[System.Collections.Concurrent.ConcurrentDictionary`2[FSharp.Compiler.ExtensionTyping+ProvidedType,FSharp.Compiler.AbstractIL.IL+ILTypeRef],System.Collections.Concurrent.ConcurrentDictionary`2[FSharp.Compiler.ExtensionTyping+ProvidedType,System.Object]] GetDictionaries() +FSharp.Compiler.ExtensionTyping+ProvidedVar: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ProvidedVar: Boolean IsMutable +FSharp.Compiler.ExtensionTyping+ProvidedVar: Boolean get_IsMutable() +FSharp.Compiler.ExtensionTyping+ProvidedVar: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ProvidedVar: ProvidedType Type +FSharp.Compiler.ExtensionTyping+ProvidedVar: ProvidedType get_Type() +FSharp.Compiler.ExtensionTyping+ProvidedVar: System.String Name +FSharp.Compiler.ExtensionTyping+ProvidedVar: System.String get_Name() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Boolean Equals(ResolutionEnvironment) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Boolean Equals(System.Object) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Boolean get_showResolutionMessages() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Boolean showResolutionMessages +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Int32 CompareTo(ResolutionEnvironment) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Int32 CompareTo(System.Object) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Int32 GetHashCode() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_outputFile() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Microsoft.FSharp.Core.FSharpOption`1[System.String] outputFile +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String ToString() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String get_resolutionFolder() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String get_temporaryFolder() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String resolutionFolder +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String temporaryFolder +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String[] get_referencedAssemblies() +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: System.String[] referencedAssemblies +FSharp.Compiler.ExtensionTyping+ResolutionEnvironment: Void .ctor(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.String], Boolean, System.String[], System.String) +FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Core.CompilerServices.ITypeProvider] InstantiateTypeProvidersOfAssembly(TypeProvidersInstantiationContext) +FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider: ProvidedExpr GetInvokerExpression(Microsoft.FSharp.Core.CompilerServices.ITypeProvider, ProvidedMethodBase, ProvidedVar[]) +FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider: ProvidedType ResolveTypeName(Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace, System.String) +FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider: ProvidedType[] GetProvidedTypes(Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace) +FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider: System.String DisplayNameOfTypeProvider(Microsoft.FSharp.Core.CompilerServices.ITypeProvider, Boolean) +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Boolean IsInteractive +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Boolean IsInvalidationSupported +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Boolean get_IsInteractive() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Boolean get_IsInvalidationSupported() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: FSharp.Compiler.Text.Range Range +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Collections.FSharpList`1[System.String] CompilerToolsPath +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_CompilerToolsPath() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.TypeProviderError,Microsoft.FSharp.Core.Unit] LogError +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.TypeProviderError,Microsoft.FSharp.Core.Unit] get_LogError() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean] SystemRuntimeContainsType +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean] get_SystemRuntimeContainsType() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: ResolutionEnvironment ResolutionEnvironment +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: ResolutionEnvironment get_ResolutionEnvironment() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.String DesignerAssemblyName +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.String RuntimeAssemblyFilename +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.String ToString() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.String get_DesignerAssemblyName() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.String get_RuntimeAssemblyFilename() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.Version SystemRuntimeAssemblyVersion +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: System.Version get_SystemRuntimeAssemblyVersion() +FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext: Void .ctor(System.String, System.String, ResolutionEnvironment, Boolean, Boolean, Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean], System.Version, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.TypeProviderError,Microsoft.FSharp.Core.Unit], FSharp.Compiler.Text.Range) +FSharp.Compiler.ExtensionTyping+Shim: FSharp.Compiler.ExtensionTyping+Shim+DefaultExtensionTypingProvider +FSharp.Compiler.ExtensionTyping+Shim: FSharp.Compiler.ExtensionTyping+Shim+IExtensionTypingProvider +FSharp.Compiler.ExtensionTyping+Shim: FSharp.Compiler.ExtensionTyping+Shim+TypeProvidersInstantiationContext +FSharp.Compiler.ExtensionTyping+Shim: IExtensionTypingProvider ExtensionTypingProvider +FSharp.Compiler.ExtensionTyping+Shim: IExtensionTypingProvider get_ExtensionTypingProvider() +FSharp.Compiler.ExtensionTyping+Shim: Void set_ExtensionTypingProvider(IExtensionTypingProvider) +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+IProvidedCustomAttributeProvider +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedAssembly +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedConstructorInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedEventInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedExpr +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedExprType +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedFieldInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedMemberInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedMethodBase +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedMethodInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedParameterInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedPropertyInfo +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedType +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedTypeContext +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ProvidedVar +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+ResolutionEnvironment +FSharp.Compiler.ExtensionTyping: FSharp.Compiler.ExtensionTyping+Shim +FSharp.Compiler.IO.ByteMemory +FSharp.Compiler.IO.ByteMemory: Byte Item [Int32] +FSharp.Compiler.IO.ByteMemory: Byte get_Item(Int32) +FSharp.Compiler.IO.ByteMemory: Byte[] ReadAllBytes() +FSharp.Compiler.IO.ByteMemory: Byte[] ReadBytes(Int32, Int32) +FSharp.Compiler.IO.ByteMemory: Byte[] ToArray() +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory Empty +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory FromArray(Byte[]) +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory FromArray(Byte[], Int32, Int32) +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory FromMemoryMappedFile(System.IO.MemoryMappedFiles.MemoryMappedFile) +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory FromUnsafePointer(IntPtr, Int32, System.Object) +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory Slice(Int32, Int32) +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ByteMemory get_Empty() +FSharp.Compiler.IO.ByteMemory: FSharp.Compiler.IO.ReadOnlyByteMemory AsReadOnly() +FSharp.Compiler.IO.ByteMemory: Int32 Length +FSharp.Compiler.IO.ByteMemory: Int32 ReadInt32(Int32) +FSharp.Compiler.IO.ByteMemory: Int32 get_Length() +FSharp.Compiler.IO.ByteMemory: System.IO.Stream AsReadOnlyStream() +FSharp.Compiler.IO.ByteMemory: System.IO.Stream AsStream() +FSharp.Compiler.IO.ByteMemory: System.String ReadUtf8String(Int32, Int32) +FSharp.Compiler.IO.ByteMemory: UInt16 ReadUInt16(Int32) +FSharp.Compiler.IO.ByteMemory: Void Copy(Int32, Byte[], Int32, Int32) +FSharp.Compiler.IO.ByteMemory: Void CopyTo(System.IO.Stream) +FSharp.Compiler.IO.ByteMemory: Void set_Item(Int32, Byte) +FSharp.Compiler.IO.DefaultAssemblyLoader +FSharp.Compiler.IO.DefaultAssemblyLoader: Void .ctor() +FSharp.Compiler.IO.DefaultFileSystem +FSharp.Compiler.IO.DefaultFileSystem: Boolean DirectoryExistsShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Boolean FileExistsShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Boolean IsInvalidPathShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Boolean IsPathRootedShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Boolean IsStableFileHeuristic(System.String) +FSharp.Compiler.IO.DefaultFileSystem: FSharp.Compiler.IO.IAssemblyLoader AssemblyLoader +FSharp.Compiler.IO.DefaultFileSystem: FSharp.Compiler.IO.IAssemblyLoader get_AssemblyLoader() +FSharp.Compiler.IO.DefaultFileSystem: System.Collections.Generic.IEnumerable`1[System.String] EnumerateDirectoriesShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.Collections.Generic.IEnumerable`1[System.String] EnumerateFilesShim(System.String, System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.DateTime GetCreationTimeShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.DateTime GetLastWriteTimeShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.IO.DirectoryInfo DirectoryCreateShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.IO.Stream OpenFileForReadShim(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.IO.DefaultFileSystem: System.IO.Stream OpenFileForWriteShim(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileMode], Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileAccess], Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileShare]) +FSharp.Compiler.IO.DefaultFileSystem: System.String GetDirectoryNameShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.String GetFullFilePathInDirectoryShim(System.String, System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.String GetFullPathShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: System.String GetTempPathShim() +FSharp.Compiler.IO.DefaultFileSystem: System.String NormalizePathShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Void .ctor() +FSharp.Compiler.IO.DefaultFileSystem: Void CopyShim(System.String, System.String, Boolean) +FSharp.Compiler.IO.DefaultFileSystem: Void DirectoryDeleteShim(System.String) +FSharp.Compiler.IO.DefaultFileSystem: Void FileDeleteShim(System.String) +FSharp.Compiler.IO.FileSystemAutoOpens +FSharp.Compiler.IO.FileSystemAutoOpens: FSharp.Compiler.IO.IFileSystem FileSystem +FSharp.Compiler.IO.FileSystemAutoOpens: FSharp.Compiler.IO.IFileSystem get_FileSystem() +FSharp.Compiler.IO.FileSystemAutoOpens: Void set_FileSystem(FSharp.Compiler.IO.IFileSystem) +FSharp.Compiler.IO.IAssemblyLoader +FSharp.Compiler.IO.IAssemblyLoader: System.Reflection.Assembly AssemblyLoad(System.Reflection.AssemblyName) +FSharp.Compiler.IO.IAssemblyLoader: System.Reflection.Assembly AssemblyLoadFrom(System.String) +FSharp.Compiler.IO.IFileSystem +FSharp.Compiler.IO.IFileSystem: Boolean DirectoryExistsShim(System.String) +FSharp.Compiler.IO.IFileSystem: Boolean FileExistsShim(System.String) +FSharp.Compiler.IO.IFileSystem: Boolean IsInvalidPathShim(System.String) +FSharp.Compiler.IO.IFileSystem: Boolean IsPathRootedShim(System.String) +FSharp.Compiler.IO.IFileSystem: Boolean IsStableFileHeuristic(System.String) +FSharp.Compiler.IO.IFileSystem: FSharp.Compiler.IO.IAssemblyLoader AssemblyLoader +FSharp.Compiler.IO.IFileSystem: FSharp.Compiler.IO.IAssemblyLoader get_AssemblyLoader() +FSharp.Compiler.IO.IFileSystem: System.Collections.Generic.IEnumerable`1[System.String] EnumerateDirectoriesShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.Collections.Generic.IEnumerable`1[System.String] EnumerateFilesShim(System.String, System.String) +FSharp.Compiler.IO.IFileSystem: System.DateTime GetCreationTimeShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.DateTime GetLastWriteTimeShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.IO.DirectoryInfo DirectoryCreateShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.IO.Stream OpenFileForReadShim(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.IO.IFileSystem: System.IO.Stream OpenFileForWriteShim(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileMode], Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileAccess], Microsoft.FSharp.Core.FSharpOption`1[System.IO.FileShare]) +FSharp.Compiler.IO.IFileSystem: System.String GetDirectoryNameShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.String GetFullFilePathInDirectoryShim(System.String, System.String) +FSharp.Compiler.IO.IFileSystem: System.String GetFullPathShim(System.String) +FSharp.Compiler.IO.IFileSystem: System.String GetTempPathShim() +FSharp.Compiler.IO.IFileSystem: System.String NormalizePathShim(System.String) +FSharp.Compiler.IO.IFileSystem: Void CopyShim(System.String, System.String, Boolean) +FSharp.Compiler.IO.IFileSystem: Void DirectoryDeleteShim(System.String) +FSharp.Compiler.IO.IFileSystem: Void FileDeleteShim(System.String) +FSharp.Compiler.IO.IllegalFileNameChar +FSharp.Compiler.IO.IllegalFileNameChar: Boolean Equals(System.Object) +FSharp.Compiler.IO.IllegalFileNameChar: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.IO.IllegalFileNameChar: Char Data1 +FSharp.Compiler.IO.IllegalFileNameChar: Char get_Data1() +FSharp.Compiler.IO.IllegalFileNameChar: Int32 GetHashCode() +FSharp.Compiler.IO.IllegalFileNameChar: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.IO.IllegalFileNameChar: System.String Data0 +FSharp.Compiler.IO.IllegalFileNameChar: System.String get_Data0() +FSharp.Compiler.IO.IllegalFileNameChar: Void .ctor() +FSharp.Compiler.IO.IllegalFileNameChar: Void .ctor(System.String, Char) +FSharp.Compiler.IO.StreamExtensions +FSharp.Compiler.IO.StreamExtensions: Byte[] Stream.ReadAllBytes(System.IO.Stream) +FSharp.Compiler.IO.StreamExtensions: Byte[] Stream.ReadBytes(System.IO.Stream, Int32, Int32) +FSharp.Compiler.IO.StreamExtensions: FSharp.Compiler.IO.ByteMemory Stream.AsByteMemory(System.IO.Stream) +FSharp.Compiler.IO.StreamExtensions: System.Collections.Generic.IEnumerable`1[System.String] Stream.ReadLines(System.IO.Stream, Microsoft.FSharp.Core.FSharpOption`1[System.Text.Encoding]) +FSharp.Compiler.IO.StreamExtensions: System.IO.StreamReader Stream.GetReader(System.IO.Stream, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +FSharp.Compiler.IO.StreamExtensions: System.IO.TextWriter Stream.GetWriter(System.IO.Stream, Microsoft.FSharp.Core.FSharpOption`1[System.Text.Encoding]) +FSharp.Compiler.IO.StreamExtensions: System.String Stream.ReadAllText(System.IO.Stream, Microsoft.FSharp.Core.FSharpOption`1[System.Text.Encoding]) +FSharp.Compiler.IO.StreamExtensions: System.String[] Stream.ReadAllLines(System.IO.Stream, Microsoft.FSharp.Core.FSharpOption`1[System.Text.Encoding]) +FSharp.Compiler.IO.StreamExtensions: Void Stream.WriteAllLines(System.IO.Stream, System.Collections.Generic.IEnumerable`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Text.Encoding]) +FSharp.Compiler.IO.StreamExtensions: Void Stream.WriteAllText(System.IO.Stream, System.String) +FSharp.Compiler.IO.StreamExtensions: Void Stream.Write[a](System.IO.Stream, a) +FSharp.Compiler.Interactive.Shell +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean CanRead +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean CanSeek +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean CanWrite +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean get_CanRead() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean get_CanSeek() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Boolean get_CanWrite() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int32 Read(Byte[], Int32, Int32) +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int64 Length +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int64 Position +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int64 Seek(Int64, System.IO.SeekOrigin) +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int64 get_Length() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Int64 get_Position() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void .ctor() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void Add(System.String) +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void Flush() +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void SetLength(Int64) +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void Write(Byte[], Int32, Int32) +FSharp.Compiler.Interactive.Shell+CompilerInputStream: Void set_Position(Int64) +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean CanRead +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean CanSeek +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean CanWrite +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean get_CanRead() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean get_CanSeek() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Boolean get_CanWrite() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int32 Read(Byte[], Int32, Int32) +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int64 Length +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int64 Position +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int64 Seek(Int64, System.IO.SeekOrigin) +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int64 get_Length() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Int64 get_Position() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: System.String Read() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Void .ctor() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Void Flush() +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Void SetLength(Int64) +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Void Write(Byte[], Int32, Int32) +FSharp.Compiler.Interactive.Shell+CompilerOutputStream: Void set_Position(Int64) +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.CodeAnalysis.FSharpSymbolUse SymbolUse +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.CodeAnalysis.FSharpSymbolUse get_SymbolUse() +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration ImplementationDeclaration +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration get_ImplementationDeclaration() +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.Symbols.FSharpSymbol Symbol +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: FSharp.Compiler.Symbols.FSharpSymbol get_Symbol() +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiValue] FsiValue +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiValue] get_FsiValue() +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: System.String Name +FSharp.Compiler.Interactive.Shell+EvaluationEventArgs: System.String get_Name() +FSharp.Compiler.Interactive.Shell+FsiBoundValue: FsiValue Value +FSharp.Compiler.Interactive.Shell+FsiBoundValue: FsiValue get_Value() +FSharp.Compiler.Interactive.Shell+FsiBoundValue: System.String Name +FSharp.Compiler.Interactive.Shell+FsiBoundValue: System.String get_Name() +FSharp.Compiler.Interactive.Shell+FsiCompilationException: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic[]] ErrorInfos +FSharp.Compiler.Interactive.Shell+FsiCompilationException: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic[]] get_ErrorInfos() +FSharp.Compiler.Interactive.Shell+FsiCompilationException: Void .ctor(System.String, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic[]]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Boolean IsGui +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Boolean get_IsGui() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FSharp.Compiler.CodeAnalysis.FSharpChecker InteractiveChecker +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FSharp.Compiler.CodeAnalysis.FSharpChecker get_InteractiveChecker() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FSharp.Compiler.Symbols.FSharpAssemblySignature CurrentPartialAssemblySignature +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FSharp.Compiler.Symbols.FSharpAssemblySignature get_CurrentPartialAssemblySignature() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FsiEvaluationSession Create(FsiEvaluationSessionHostConfig, System.String[], System.IO.TextReader, System.IO.TextWriter, System.IO.TextWriter, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FsiEvaluationSessionHostConfig GetDefaultConfiguration() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FsiEvaluationSessionHostConfig GetDefaultConfiguration(System.Object) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: FsiEvaluationSessionHostConfig GetDefaultConfiguration(System.Object, Boolean) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Interactive.Shell+FsiBoundValue] GetBoundValues() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.Unit] PartialAssemblySignatureUpdated +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.Unit] get_PartialAssemblySignatureUpdated() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`3[System.Object,System.Type,System.String]],System.Tuple`3[System.Object,System.Type,System.String]] ValueBound +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`3[System.Object,System.Type,System.String]],System.Tuple`3[System.Object,System.Type,System.String]] get_ValueBound() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiBoundValue] TryFindBoundValue(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiValue] EvalExpression(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] LCID +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_LCID() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Collections.Generic.IEnumerable`1[System.String] GetCompletions(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Reflection.Assembly DynamicAssembly +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Reflection.Assembly get_DynamicAssembly() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.String FormatValue(System.Object, System.Type) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Tuple`2[Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiValue],System.Exception],FSharp.Compiler.Diagnostics.FSharpDiagnostic[]] EvalExpressionNonThrowing(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Tuple`2[Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Interactive.Shell+FsiValue],System.Exception],FSharp.Compiler.Diagnostics.FSharpDiagnostic[]] EvalInteractionNonThrowing(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Tuple`2[Microsoft.FSharp.Core.FSharpChoice`2[Microsoft.FSharp.Core.Unit,System.Exception],FSharp.Compiler.Diagnostics.FSharpDiagnostic[]] EvalScriptNonThrowing(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: System.Tuple`3[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults] ParseAndCheckInteraction(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void AddBoundValue(System.String, System.Object) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void EvalInteraction(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void EvalScript(System.String) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void Interrupt() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void ReportUnhandledException(System.Exception) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSession: Void Run() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean EventLoopRun() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean ShowDeclarationValues +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean ShowIEnumerable +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean ShowProperties +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean UseFsiAuxLib +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean get_ShowDeclarationValues() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean get_ShowIEnumerable() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean get_ShowProperties() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Boolean get_UseFsiAuxLib() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 PrintDepth +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 PrintLength +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 PrintSize +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 PrintWidth +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 get_PrintDepth() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 get_PrintLength() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 get_PrintSize() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Int32 get_PrintWidth() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Core.FSharpChoice`2[System.Tuple`2[System.Type,Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.String]],System.Tuple`2[System.Type,Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]]]] AddedPrinters +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Core.FSharpChoice`2[System.Tuple`2[System.Type,Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.String]],System.Tuple`2[System.Type,Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]]]] get_AddedPrinters() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.Interactive.Shell+EvaluationEventArgs],FSharp.Compiler.Interactive.Shell+EvaluationEventArgs] OnEvaluation +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.Interactive.Shell+EvaluationEventArgs],FSharp.Compiler.Interactive.Shell+EvaluationEventArgs] get_OnEvaluation() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.String]] GetOptionalConsoleReadLine(Boolean) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: System.IFormatProvider FormatProvider +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: System.IFormatProvider get_FormatProvider() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: System.String FloatingPointFormat +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: System.String get_FloatingPointFormat() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: T EventLoopInvoke[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Void .ctor() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Void EventLoopScheduleRestart() +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Void ReportUserCommandLineArgs(System.String[]) +FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig: Void StartServer(System.String) +FSharp.Compiler.Interactive.Shell+FsiValue: FSharp.Compiler.Symbols.FSharpType FSharpType +FSharp.Compiler.Interactive.Shell+FsiValue: FSharp.Compiler.Symbols.FSharpType get_FSharpType() +FSharp.Compiler.Interactive.Shell+FsiValue: System.Object ReflectionValue +FSharp.Compiler.Interactive.Shell+FsiValue: System.Object get_ReflectionValue() +FSharp.Compiler.Interactive.Shell+FsiValue: System.Type ReflectionType +FSharp.Compiler.Interactive.Shell+FsiValue: System.Type get_ReflectionType() +FSharp.Compiler.Interactive.Shell+Settings+IEventLoop: Boolean Run() +FSharp.Compiler.Interactive.Shell+Settings+IEventLoop: T Invoke[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +FSharp.Compiler.Interactive.Shell+Settings+IEventLoop: Void ScheduleRestart() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean ShowDeclarationValues +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean ShowIEnumerable +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean ShowProperties +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean get_ShowDeclarationValues() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean get_ShowIEnumerable() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Boolean get_ShowProperties() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: IEventLoop EventLoop +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: IEventLoop get_EventLoop() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 PrintDepth +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 PrintLength +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 PrintSize +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 PrintWidth +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 get_PrintDepth() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 get_PrintLength() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 get_PrintSize() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Int32 get_PrintWidth() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.IFormatProvider FormatProvider +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.IFormatProvider get_FormatProvider() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.String FloatingPointFormat +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.String get_FloatingPointFormat() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.String[] CommandLineArgs +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: System.String[] get_CommandLineArgs() +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void AddPrintTransformer[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Object]) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void AddPrinter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.String]) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_CommandLineArgs(System.String[]) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_EventLoop(IEventLoop) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_FloatingPointFormat(System.String) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_FormatProvider(System.IFormatProvider) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_PrintDepth(Int32) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_PrintLength(Int32) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_PrintSize(Int32) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_PrintWidth(Int32) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_ShowDeclarationValues(Boolean) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_ShowIEnumerable(Boolean) +FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings: Void set_ShowProperties(Boolean) +FSharp.Compiler.Interactive.Shell+Settings: FSharp.Compiler.Interactive.Shell+Settings+IEventLoop +FSharp.Compiler.Interactive.Shell+Settings: FSharp.Compiler.Interactive.Shell+Settings+InteractiveSettings +FSharp.Compiler.Interactive.Shell+Settings: InteractiveSettings fsi +FSharp.Compiler.Interactive.Shell+Settings: InteractiveSettings get_fsi() +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+CompilerInputStream +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+CompilerOutputStream +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+EvaluationEventArgs +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+FsiBoundValue +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+FsiCompilationException +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+FsiEvaluationSession +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+FsiEvaluationSessionHostConfig +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+FsiValue +FSharp.Compiler.Interactive.Shell: FSharp.Compiler.Interactive.Shell+Settings +FSharp.Compiler.Symbols.FSharpAbstractParameter +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean IsInArg +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean IsOptionalArg +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean IsOutArg +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean get_IsInArg() +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean get_IsOptionalArg() +FSharp.Compiler.Symbols.FSharpAbstractParameter: Boolean get_IsOutArg() +FSharp.Compiler.Symbols.FSharpAbstractParameter: FSharp.Compiler.Symbols.FSharpType Type +FSharp.Compiler.Symbols.FSharpAbstractParameter: FSharp.Compiler.Symbols.FSharpType get_Type() +FSharp.Compiler.Symbols.FSharpAbstractParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] Name +FSharp.Compiler.Symbols.FSharpAbstractParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Name() +FSharp.Compiler.Symbols.FSharpAbstractParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpAbstractParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpAbstractSignature +FSharp.Compiler.Symbols.FSharpAbstractSignature: FSharp.Compiler.Symbols.FSharpType AbstractReturnType +FSharp.Compiler.Symbols.FSharpAbstractSignature: FSharp.Compiler.Symbols.FSharpType DeclaringType +FSharp.Compiler.Symbols.FSharpAbstractSignature: FSharp.Compiler.Symbols.FSharpType get_AbstractReturnType() +FSharp.Compiler.Symbols.FSharpAbstractSignature: FSharp.Compiler.Symbols.FSharpType get_DeclaringType() +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] DeclaringTypeGenericParameters +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] MethodGenericParameters +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] get_DeclaringTypeGenericParameters() +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] get_MethodGenericParameters() +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractParameter]] AbstractArguments +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractParameter]] get_AbstractArguments() +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.String Name +FSharp.Compiler.Symbols.FSharpAbstractSignature: System.String get_Name() +FSharp.Compiler.Symbols.FSharpAccessibility +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean IsInternal +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean IsPrivate +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean IsProtected +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean IsPublic +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean get_IsInternal() +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean get_IsPrivate() +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean get_IsProtected() +FSharp.Compiler.Symbols.FSharpAccessibility: Boolean get_IsPublic() +FSharp.Compiler.Symbols.FSharpAccessibility: System.String ToString() +FSharp.Compiler.Symbols.FSharpAccessibilityRights +FSharp.Compiler.Symbols.FSharpActivePatternCase +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Symbols.FSharpActivePatternGroup Group +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Symbols.FSharpActivePatternGroup get_Group() +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpActivePatternCase: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpActivePatternCase: Int32 Index +FSharp.Compiler.Symbols.FSharpActivePatternCase: Int32 get_Index() +FSharp.Compiler.Symbols.FSharpActivePatternCase: System.String Name +FSharp.Compiler.Symbols.FSharpActivePatternCase: System.String XmlDocSig +FSharp.Compiler.Symbols.FSharpActivePatternCase: System.String get_Name() +FSharp.Compiler.Symbols.FSharpActivePatternCase: System.String get_XmlDocSig() +FSharp.Compiler.Symbols.FSharpActivePatternGroup +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Boolean IsTotal +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Boolean get_IsTotal() +FSharp.Compiler.Symbols.FSharpActivePatternGroup: FSharp.Compiler.Symbols.FSharpType OverallType +FSharp.Compiler.Symbols.FSharpActivePatternGroup: FSharp.Compiler.Symbols.FSharpType get_OverallType() +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] DeclaringEntity +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_DeclaringEntity() +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Microsoft.FSharp.Core.FSharpOption`1[System.String] Name +FSharp.Compiler.Symbols.FSharpActivePatternGroup: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Name() +FSharp.Compiler.Symbols.FSharpActivePatternGroup: System.Collections.Generic.IList`1[System.String] Names +FSharp.Compiler.Symbols.FSharpActivePatternGroup: System.Collections.Generic.IList`1[System.String] get_Names() +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: FSharp.Compiler.Symbols.FSharpAssembly Assembly +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: FSharp.Compiler.Symbols.FSharpAssembly get_Assembly() +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: Microsoft.FSharp.Collections.FSharpList`1[System.String] EnclosingCompiledTypeNames +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_EnclosingCompiledTypeNames() +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: System.String CompiledName +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: System.String get_CompiledName() +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: System.String[] SortedFieldNames +FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails: System.String[] get_SortedFieldNames() +FSharp.Compiler.Symbols.FSharpAssembly +FSharp.Compiler.Symbols.FSharpAssembly: Boolean IsProviderGenerated +FSharp.Compiler.Symbols.FSharpAssembly: Boolean get_IsProviderGenerated() +FSharp.Compiler.Symbols.FSharpAssembly: FSharp.Compiler.Symbols.FSharpAssemblySignature Contents +FSharp.Compiler.Symbols.FSharpAssembly: FSharp.Compiler.Symbols.FSharpAssemblySignature get_Contents() +FSharp.Compiler.Symbols.FSharpAssembly: Microsoft.FSharp.Core.FSharpOption`1[System.String] FileName +FSharp.Compiler.Symbols.FSharpAssembly: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_FileName() +FSharp.Compiler.Symbols.FSharpAssembly: System.String QualifiedName +FSharp.Compiler.Symbols.FSharpAssembly: System.String SimpleName +FSharp.Compiler.Symbols.FSharpAssembly: System.String ToString() +FSharp.Compiler.Symbols.FSharpAssembly: System.String get_QualifiedName() +FSharp.Compiler.Symbols.FSharpAssembly: System.String get_SimpleName() +FSharp.Compiler.Symbols.FSharpAssemblyContents +FSharp.Compiler.Symbols.FSharpAssemblyContents: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFiles +FSharp.Compiler.Symbols.FSharpAssemblyContents: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFiles() +FSharp.Compiler.Symbols.FSharpAssemblySignature +FSharp.Compiler.Symbols.FSharpAssemblySignature: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] FindEntityByPath(Microsoft.FSharp.Collections.FSharpList`1[System.String]) +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Symbols.FSharpEntity] TryGetEntities() +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpEntity] Entities +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpEntity] get_Entities() +FSharp.Compiler.Symbols.FSharpAssemblySignature: System.String ToString() +FSharp.Compiler.Symbols.FSharpAttribute +FSharp.Compiler.Symbols.FSharpAttribute: Boolean IsAttribute[T]() +FSharp.Compiler.Symbols.FSharpAttribute: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpAttribute: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpAttribute: FSharp.Compiler.Symbols.FSharpEntity AttributeType +FSharp.Compiler.Symbols.FSharpAttribute: FSharp.Compiler.Symbols.FSharpEntity get_AttributeType() +FSharp.Compiler.Symbols.FSharpAttribute: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Symbols.FSharpAttribute: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Symbols.FSharpAttribute: System.Collections.Generic.IList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,System.Object]] ConstructorArguments +FSharp.Compiler.Symbols.FSharpAttribute: System.Collections.Generic.IList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,System.Object]] get_ConstructorArguments() +FSharp.Compiler.Symbols.FSharpAttribute: System.Collections.Generic.IList`1[System.Tuple`4[FSharp.Compiler.Symbols.FSharpType,System.String,System.Boolean,System.Object]] NamedArguments +FSharp.Compiler.Symbols.FSharpAttribute: System.Collections.Generic.IList`1[System.Tuple`4[FSharp.Compiler.Symbols.FSharpType,System.String,System.Boolean,System.Object]] get_NamedArguments() +FSharp.Compiler.Symbols.FSharpAttribute: System.String Format(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpAttribute: System.String ToString() +FSharp.Compiler.Symbols.FSharpDelegateSignature +FSharp.Compiler.Symbols.FSharpDelegateSignature: FSharp.Compiler.Symbols.FSharpType DelegateReturnType +FSharp.Compiler.Symbols.FSharpDelegateSignature: FSharp.Compiler.Symbols.FSharpType get_DelegateReturnType() +FSharp.Compiler.Symbols.FSharpDelegateSignature: System.Collections.Generic.IList`1[System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[System.String],FSharp.Compiler.Symbols.FSharpType]] DelegateArguments +FSharp.Compiler.Symbols.FSharpDelegateSignature: System.Collections.Generic.IList`1[System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[System.String],FSharp.Compiler.Symbols.FSharpType]] get_DelegateArguments() +FSharp.Compiler.Symbols.FSharpDelegateSignature: System.String ToString() +FSharp.Compiler.Symbols.FSharpDisplayContext +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext Empty +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithPrefixGenericParameters() +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithShortTypeNames(Boolean) +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithSuffixGenericParameters() +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext get_Empty() +FSharp.Compiler.Symbols.FSharpEntity +FSharp.Compiler.Symbols.FSharpEntity: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpEntity: Boolean HasAssemblyCodeRepresentation +FSharp.Compiler.Symbols.FSharpEntity: Boolean HasFSharpModuleSuffix +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsAbstractClass +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsArrayType +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsAttributeType +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsByRef +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsClass +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsDelegate +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsEnum +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharp +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharpAbbreviation +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharpExceptionDeclaration +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharpModule +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharpRecord +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsFSharpUnion +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsInterface +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsMeasure +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsNamespace +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsOpaque +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsProvided +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsProvidedAndErased +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsProvidedAndGenerated +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsStaticInstantiation +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpEntity: Boolean IsValueType +FSharp.Compiler.Symbols.FSharpEntity: Boolean UsesPrefixDisplay +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_HasAssemblyCodeRepresentation() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_HasFSharpModuleSuffix() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsAbstractClass() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsArrayType() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsAttributeType() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsByRef() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsClass() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsDelegate() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsEnum() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharp() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharpAbbreviation() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharpExceptionDeclaration() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharpModule() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharpRecord() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsFSharpUnion() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsInterface() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsMeasure() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsNamespace() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsOpaque() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsProvided() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsProvidedAndErased() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsProvidedAndGenerated() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsStaticInstantiation() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_IsValueType() +FSharp.Compiler.Symbols.FSharpEntity: Boolean get_UsesPrefixDisplay() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpAccessibility RepresentationAccessibility +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpAccessibility get_RepresentationAccessibility() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpDelegateSignature FSharpDelegateSignature +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpDelegateSignature get_FSharpDelegateSignature() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpType AbbreviatedType +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpType get_AbbreviatedType() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpEntity: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpEntity: Int32 ArrayRank +FSharp.Compiler.Symbols.FSharpEntity: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpEntity: Int32 get_ArrayRank() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpActivePatternCase] ActivePatternCases +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpActivePatternCase] get_ActivePatternCases() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Collections.FSharpList`1[System.String] AllCompilationPaths +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_AllCompilationPaths() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] DeclaringEntity +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_DeclaringEntity() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] BaseType +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] get_BaseType() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] TryGetMetadataText() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] Namespace +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryFullName +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullCompiledName() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullDisplayName() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullName() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Namespace() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_TryFullName() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Symbols.FSharpEntity] GetPublicNestedEntities() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpEntity] NestedEntities +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpEntity] get_NestedEntities() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpField] FSharpFields +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpField] get_FSharpFields() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] GenericParameters +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] get_GenericParameters() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] MembersFunctionsAndValues +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] TryGetMembersFunctionsAndValues() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] get_MembersFunctionsAndValues() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpStaticParameter] StaticParameters +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpStaticParameter] get_StaticParameters() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] AllInterfaces +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] DeclaredInterfaces +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_AllInterfaces() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_DeclaredInterfaces() +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] UnionCases +FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] get_UnionCases() +FSharp.Compiler.Symbols.FSharpEntity: System.String AccessPath +FSharp.Compiler.Symbols.FSharpEntity: System.String CompiledName +FSharp.Compiler.Symbols.FSharpEntity: System.String DisplayName +FSharp.Compiler.Symbols.FSharpEntity: System.String FullName +FSharp.Compiler.Symbols.FSharpEntity: System.String LogicalName +FSharp.Compiler.Symbols.FSharpEntity: System.String QualifiedName +FSharp.Compiler.Symbols.FSharpEntity: System.String ToString() +FSharp.Compiler.Symbols.FSharpEntity: System.String XmlDocSig +FSharp.Compiler.Symbols.FSharpEntity: System.String get_AccessPath() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_CompiledName() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_DisplayName() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_FullName() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_LogicalName() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_QualifiedName() +FSharp.Compiler.Symbols.FSharpEntity: System.String get_XmlDocSig() +FSharp.Compiler.Symbols.FSharpExpr +FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Symbols.FSharpType Type +FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Symbols.FSharpType get_Type() +FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Symbols.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr] ImmediateSubExpressions +FSharp.Compiler.Symbols.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr] get_ImmediateSubExpressions() +FSharp.Compiler.Symbols.FSharpExpr: System.String ToString() +FSharp.Compiler.Symbols.FSharpExprPatterns +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr] |AddressOf|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr] |Quote|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] |Value|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] |BaseValue|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] |DefaultValue|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] |ThisValue|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] |WitnessArg|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr]] |AddressSet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr]] |Sequential|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr]] |TryFinally|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr]] |WhileLoop|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpType]] |UnionCaseTag|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue],FSharp.Compiler.Symbols.FSharpExpr]]]] |DecisionTree|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr]] |Lambda|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr]] |ValueSet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpExpr]] |Coerce|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpExpr]] |NewDelegate|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpExpr]] |TypeTest|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewAnonRecord|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewArray|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewRecord|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewTuple|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpGenericParameter],FSharp.Compiler.Symbols.FSharpExpr]] |TypeLambda|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr]],FSharp.Compiler.Symbols.FSharpExpr]] |LetRec|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Int32,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |DecisionTreeSuccess|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Object,FSharp.Compiler.Symbols.FSharpType]] |Const|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Tuple`2[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpExpr]] |Let|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr]] |IfThenElse|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpUnionCase]] |UnionCaseTest|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpType,System.Int32]] |AnonRecordGet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |Application|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewObject|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpUnionCase,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |NewUnionCase|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpType,System.Int32,FSharp.Compiler.Symbols.FSharpExpr]] |TupleGet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpField]] |FSharpFieldGet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpType,System.String]] |ILFieldGet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.String,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |ILAsm|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpExpr,System.Boolean]] |FastIntegerForLoop|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpUnionCase,FSharp.Compiler.Symbols.FSharpField]] |UnionCaseGet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpObjectExprOverride],Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpType,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpObjectExprOverride]]]]] |ObjectExpr|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpField,FSharp.Compiler.Symbols.FSharpExpr]] |FSharpFieldSet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpType,System.String,FSharp.Compiler.Symbols.FSharpExpr]] |ILFieldSet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,FSharp.Compiler.Symbols.FSharpExpr]] |TryWith|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Symbols.FSharpExpr,FSharp.Compiler.Symbols.FSharpType,FSharp.Compiler.Symbols.FSharpUnionCase,FSharp.Compiler.Symbols.FSharpField,FSharp.Compiler.Symbols.FSharpExpr]] |UnionCaseSet|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |Call|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`6[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],System.String,FSharp.Compiler.Syntax.SynMemberFlags,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |TraitCall|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpExprPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`6[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpExpr],FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpExpr]]] |CallWithWitnesses|_|(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpField +FSharp.Compiler.Symbols.FSharpField: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpField: Boolean IsAnonRecordField +FSharp.Compiler.Symbols.FSharpField: Boolean IsCompilerGenerated +FSharp.Compiler.Symbols.FSharpField: Boolean IsDefaultValue +FSharp.Compiler.Symbols.FSharpField: Boolean IsLiteral +FSharp.Compiler.Symbols.FSharpField: Boolean IsMutable +FSharp.Compiler.Symbols.FSharpField: Boolean IsNameGenerated +FSharp.Compiler.Symbols.FSharpField: Boolean IsStatic +FSharp.Compiler.Symbols.FSharpField: Boolean IsUnionCaseField +FSharp.Compiler.Symbols.FSharpField: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpField: Boolean IsVolatile +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsAnonRecordField() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsCompilerGenerated() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsDefaultValue() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsLiteral() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsMutable() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsNameGenerated() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsStatic() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsUnionCaseField() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpField: Boolean get_IsVolatile() +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpType FieldType +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpType get_FieldType() +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpField: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpField: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] DeclaringEntity +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_DeclaringEntity() +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpUnionCase] DeclaringUnionCase +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpUnionCase] get_DeclaringUnionCase() +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[System.Object] LiteralValue +FSharp.Compiler.Symbols.FSharpField: Microsoft.FSharp.Core.FSharpOption`1[System.Object] get_LiteralValue() +FSharp.Compiler.Symbols.FSharpField: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] FieldAttributes +FSharp.Compiler.Symbols.FSharpField: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] PropertyAttributes +FSharp.Compiler.Symbols.FSharpField: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_FieldAttributes() +FSharp.Compiler.Symbols.FSharpField: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_PropertyAttributes() +FSharp.Compiler.Symbols.FSharpField: System.String Name +FSharp.Compiler.Symbols.FSharpField: System.String ToString() +FSharp.Compiler.Symbols.FSharpField: System.String XmlDocSig +FSharp.Compiler.Symbols.FSharpField: System.String get_Name() +FSharp.Compiler.Symbols.FSharpField: System.String get_XmlDocSig() +FSharp.Compiler.Symbols.FSharpField: System.Tuple`3[FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails,FSharp.Compiler.Symbols.FSharpType[],System.Int32] AnonRecordFieldDetails +FSharp.Compiler.Symbols.FSharpField: System.Tuple`3[FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails,FSharp.Compiler.Symbols.FSharpType[],System.Int32] get_AnonRecordFieldDetails() +FSharp.Compiler.Symbols.FSharpGenericParameter +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean IsCompilerGenerated +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean IsMeasure +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean IsSolveAtCompileTime +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean get_IsCompilerGenerated() +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean get_IsMeasure() +FSharp.Compiler.Symbols.FSharpGenericParameter: Boolean get_IsSolveAtCompileTime() +FSharp.Compiler.Symbols.FSharpGenericParameter: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpGenericParameter: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpGenericParameter: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpGenericParameter: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpGenericParameter: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpGenericParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpGenericParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpGenericParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameterConstraint] Constraints +FSharp.Compiler.Symbols.FSharpGenericParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameterConstraint] get_Constraints() +FSharp.Compiler.Symbols.FSharpGenericParameter: System.String Name +FSharp.Compiler.Symbols.FSharpGenericParameter: System.String ToString() +FSharp.Compiler.Symbols.FSharpGenericParameter: System.String get_Name() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsCoercesToConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsComparisonConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsDefaultsToConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsDelegateConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsEnumConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsEqualityConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsMemberConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNonNullableValueTypeConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsReferenceTypeConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsRequiresDefaultConstructorConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSimpleChoiceConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSupportsNullConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsUnmanagedConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsCoercesToConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsComparisonConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsDefaultsToConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsDelegateConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsEnumConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsEqualityConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsMemberConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNonNullableValueTypeConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsReferenceTypeConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsRequiresDefaultConstructorConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSimpleChoiceConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSupportsNullConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsUnmanagedConstraint() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint DefaultsToConstraintData +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint get_DefaultsToConstraintData() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint DelegateConstraintData +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint get_DelegateConstraintData() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint MemberConstraintData +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint get_MemberConstraintData() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpType CoercesToTarget +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpType EnumConstraintTarget +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpType get_CoercesToTarget() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpType get_EnumConstraintTarget() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] SimpleChoices +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_SimpleChoices() +FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: System.String ToString() +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint: FSharp.Compiler.Symbols.FSharpType DefaultsToTarget +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint: FSharp.Compiler.Symbols.FSharpType get_DefaultsToTarget() +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint: Int32 DefaultsToPriority +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint: Int32 get_DefaultsToPriority() +FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint: System.String ToString() +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint: FSharp.Compiler.Symbols.FSharpType DelegateReturnType +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint: FSharp.Compiler.Symbols.FSharpType DelegateTupledArgumentType +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint: FSharp.Compiler.Symbols.FSharpType get_DelegateReturnType() +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint: FSharp.Compiler.Symbols.FSharpType get_DelegateTupledArgumentType() +FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint: System.String ToString() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: Boolean MemberIsStatic +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: Boolean get_MemberIsStatic() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: FSharp.Compiler.Symbols.FSharpType MemberReturnType +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: FSharp.Compiler.Symbols.FSharpType get_MemberReturnType() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] MemberArgumentTypes +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] MemberSources +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_MemberArgumentTypes() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_MemberSources() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.String MemberName +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.String ToString() +FSharp.Compiler.Symbols.FSharpGenericParameterMemberConstraint: System.String get_MemberName() +FSharp.Compiler.Symbols.FSharpImplementationFileContents +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Boolean HasExplicitEntryPoint +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Boolean IsScript +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Boolean get_HasExplicitEntryPoint() +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Boolean get_IsScript() +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration] Declarations +FSharp.Compiler.Symbols.FSharpImplementationFileContents: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration] get_Declarations() +FSharp.Compiler.Symbols.FSharpImplementationFileContents: System.String FileName +FSharp.Compiler.Symbols.FSharpImplementationFileContents: System.String QualifiedName +FSharp.Compiler.Symbols.FSharpImplementationFileContents: System.String get_FileName() +FSharp.Compiler.Symbols.FSharpImplementationFileContents: System.String get_QualifiedName() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Entity: FSharp.Compiler.Symbols.FSharpEntity entity +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Entity: FSharp.Compiler.Symbols.FSharpEntity get_entity() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Entity: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration] declarations +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Entity: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration] get_declarations() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+InitAction: FSharp.Compiler.Symbols.FSharpExpr action +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+InitAction: FSharp.Compiler.Symbols.FSharpExpr get_action() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpExpr body +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpExpr get_body() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_value() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue value +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]] curriedArgs +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]] get_curriedArgs() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Tags: Int32 Entity +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Tags: Int32 InitAction +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Tags: Int32 MemberOrFunctionOrValue +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean Equals(FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean IsEntity +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean IsInitAction +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean IsMemberOrFunctionOrValue +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean get_IsEntity() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean get_IsInitAction() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Boolean get_IsMemberOrFunctionOrValue() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration NewEntity(FSharp.Compiler.Symbols.FSharpEntity, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration]) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration NewInitAction(FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration NewMemberOrFunctionOrValue(FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]], FSharp.Compiler.Symbols.FSharpExpr) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Entity +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+InitAction +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+MemberOrFunctionOrValue +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration+Tags +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Int32 Tag +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: Int32 get_Tag() +FSharp.Compiler.Symbols.FSharpImplementationFileDeclaration: System.String ToString() +FSharp.Compiler.Symbols.FSharpInlineAnnotation +FSharp.Compiler.Symbols.FSharpInlineAnnotation+Tags: Int32 AggressiveInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation+Tags: Int32 AlwaysInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation+Tags: Int32 NeverInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation+Tags: Int32 OptionalInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean Equals(FSharp.Compiler.Symbols.FSharpInlineAnnotation) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean IsAggressiveInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean IsAlwaysInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean IsNeverInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean IsOptionalInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean get_IsAggressiveInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean get_IsAlwaysInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean get_IsNeverInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Boolean get_IsOptionalInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation AggressiveInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation AlwaysInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation NeverInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation OptionalInline +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_AggressiveInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_AlwaysInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_NeverInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_OptionalInline() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: FSharp.Compiler.Symbols.FSharpInlineAnnotation+Tags +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 CompareTo(FSharp.Compiler.Symbols.FSharpInlineAnnotation) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 CompareTo(System.Object) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 Tag +FSharp.Compiler.Symbols.FSharpInlineAnnotation: Int32 get_Tag() +FSharp.Compiler.Symbols.FSharpInlineAnnotation: System.String ToString() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean EventIsStandard +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean HasGetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean HasSetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsActivePattern +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsBaseValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsCompilerGenerated +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsConstructor +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsConstructorThisValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsDispatchSlot +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsEvent +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsEventAddMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsEventRemoveMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsExplicitInterfaceImplementation +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsExtensionMember +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsFunction +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsImplicitConstructor +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsInstanceMember +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsInstanceMemberInCompiledCode +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsMember +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsMemberThisValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsModuleValueOrMember +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsMutable +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsOverrideOrExplicitInterfaceImplementation +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsProperty +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsPropertyGetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsPropertySetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsTypeFunction +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsValCompiledAsMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean IsValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_EventIsStandard() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_HasGetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_HasSetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsActivePattern() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsBaseValue() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsCompilerGenerated() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsConstructor() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsConstructorThisValue() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsDispatchSlot() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsEvent() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsEventAddMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsEventRemoveMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsExplicitInterfaceImplementation() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsExtensionMember() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsFunction() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsImplicitConstructor() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsInstanceMember() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsInstanceMemberInCompiledCode() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsMember() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsMemberThisValue() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsModuleValueOrMember() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsMutable() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsOverrideOrExplicitInterfaceImplementation() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsProperty() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsPropertyGetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsPropertySetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsTypeFunction() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsValCompiledAsMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsValue() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpEntity ApparentEnclosingEntity +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpEntity get_ApparentEnclosingEntity() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpInlineAnnotation InlineAnnotation +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_InlineAnnotation() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue EventAddMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue EventRemoveMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue GetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue SetterMethod +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_EventAddMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_EventRemoveMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_GetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_SetterMethod() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpParameter ReturnParameter +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpParameter get_ReturnParameter() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType EventDelegateType +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType FullType +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType get_EventDelegateType() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType get_FullType() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.TaggedText[] FormatLayout(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] DeclaringEntity +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_DeclaringEntity() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] EventForFSharpProperty +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] get_EventForFSharpProperty() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] FullTypeSafe +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] get_FullTypeSafe() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]] GetOverloads(Boolean) +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] LiteralValue +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] get_LiteralValue() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] TryGetFullCompiledOperatorNameIdents() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullDisplayName() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.String,System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]]] GetWitnessPassingInfo() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractSignature] ImplementedAbstractSignatures +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractSignature] get_ImplementedAbstractSignatures() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] GenericParameters +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] get_GenericParameters() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]] CurriedParameterGroups +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]] get_CurriedParameterGroups() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String CompiledName +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String DisplayName +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String LogicalName +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String ToString() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String XmlDocSig +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String get_CompiledName() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String get_DisplayName() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String get_LogicalName() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.String get_XmlDocSig() +FSharp.Compiler.Symbols.FSharpObjectExprOverride +FSharp.Compiler.Symbols.FSharpObjectExprOverride: FSharp.Compiler.Symbols.FSharpAbstractSignature Signature +FSharp.Compiler.Symbols.FSharpObjectExprOverride: FSharp.Compiler.Symbols.FSharpAbstractSignature get_Signature() +FSharp.Compiler.Symbols.FSharpObjectExprOverride: FSharp.Compiler.Symbols.FSharpExpr Body +FSharp.Compiler.Symbols.FSharpObjectExprOverride: FSharp.Compiler.Symbols.FSharpExpr get_Body() +FSharp.Compiler.Symbols.FSharpObjectExprOverride: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] GenericParameters +FSharp.Compiler.Symbols.FSharpObjectExprOverride: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpGenericParameter] get_GenericParameters() +FSharp.Compiler.Symbols.FSharpObjectExprOverride: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]] CurriedParameterGroups +FSharp.Compiler.Symbols.FSharpObjectExprOverride: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue]] get_CurriedParameterGroups() +FSharp.Compiler.Symbols.FSharpOpenDeclaration +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Boolean IsOwnNamespace +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Boolean get_IsOwnNamespace() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: FSharp.Compiler.Syntax.SynOpenDeclTarget Target +FSharp.Compiler.Symbols.FSharpOpenDeclaration: FSharp.Compiler.Syntax.SynOpenDeclTarget get_Target() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: FSharp.Compiler.Text.Range AppliedScope +FSharp.Compiler.Symbols.FSharpOpenDeclaration: FSharp.Compiler.Text.Range get_AppliedScope() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpEntity] Modules +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpEntity] get_Modules() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType] Types +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Symbols.FSharpType] get_Types() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] LongId +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_LongId() +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] Range +FSharp.Compiler.Symbols.FSharpOpenDeclaration: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_Range() +FSharp.Compiler.Symbols.FSharpParameter +FSharp.Compiler.Symbols.FSharpParameter: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpParameter: Boolean IsInArg +FSharp.Compiler.Symbols.FSharpParameter: Boolean IsOptionalArg +FSharp.Compiler.Symbols.FSharpParameter: Boolean IsOutArg +FSharp.Compiler.Symbols.FSharpParameter: Boolean IsParamArrayArg +FSharp.Compiler.Symbols.FSharpParameter: Boolean get_IsInArg() +FSharp.Compiler.Symbols.FSharpParameter: Boolean get_IsOptionalArg() +FSharp.Compiler.Symbols.FSharpParameter: Boolean get_IsOutArg() +FSharp.Compiler.Symbols.FSharpParameter: Boolean get_IsParamArrayArg() +FSharp.Compiler.Symbols.FSharpParameter: FSharp.Compiler.Symbols.FSharpType Type +FSharp.Compiler.Symbols.FSharpParameter: FSharp.Compiler.Symbols.FSharpType get_Type() +FSharp.Compiler.Symbols.FSharpParameter: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpParameter: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpParameter: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] Name +FSharp.Compiler.Symbols.FSharpParameter: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Name() +FSharp.Compiler.Symbols.FSharpParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpParameter: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpParameter: System.String ToString() +FSharp.Compiler.Symbols.FSharpStaticParameter +FSharp.Compiler.Symbols.FSharpStaticParameter: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpStaticParameter: Boolean HasDefaultValue +FSharp.Compiler.Symbols.FSharpStaticParameter: Boolean IsOptional +FSharp.Compiler.Symbols.FSharpStaticParameter: Boolean get_HasDefaultValue() +FSharp.Compiler.Symbols.FSharpStaticParameter: Boolean get_IsOptional() +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Symbols.FSharpType Kind +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Symbols.FSharpType get_Kind() +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpStaticParameter: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Symbols.FSharpStaticParameter: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpStaticParameter: System.Object DefaultValue +FSharp.Compiler.Symbols.FSharpStaticParameter: System.Object get_DefaultValue() +FSharp.Compiler.Symbols.FSharpStaticParameter: System.String Name +FSharp.Compiler.Symbols.FSharpStaticParameter: System.String ToString() +FSharp.Compiler.Symbols.FSharpStaticParameter: System.String get_Name() +FSharp.Compiler.Symbols.FSharpSymbol +FSharp.Compiler.Symbols.FSharpSymbol: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpSymbol: Boolean HasAttribute[T]() +FSharp.Compiler.Symbols.FSharpSymbol: Boolean IsAccessible(FSharp.Compiler.Symbols.FSharpAccessibilityRights) +FSharp.Compiler.Symbols.FSharpSymbol: Boolean IsEffectivelySameAs(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbol: Boolean IsExplicitlySuppressed +FSharp.Compiler.Symbols.FSharpSymbol: Boolean get_IsExplicitlySuppressed() +FSharp.Compiler.Symbols.FSharpSymbol: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.Symbols.FSharpSymbol: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpSymbol: FSharp.Compiler.Symbols.FSharpAssembly Assembly +FSharp.Compiler.Symbols.FSharpSymbol: FSharp.Compiler.Symbols.FSharpAssembly get_Assembly() +FSharp.Compiler.Symbols.FSharpSymbol: Int32 GetEffectivelySameAsHash() +FSharp.Compiler.Symbols.FSharpSymbol: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpAttribute] TryGetAttribute[T]() +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] DeclarationLocation +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ImplementationLocation +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] SignatureLocation +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_ImplementationLocation() +FSharp.Compiler.Symbols.FSharpSymbol: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_SignatureLocation() +FSharp.Compiler.Symbols.FSharpSymbol: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpSymbol: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpSymbol: System.String DisplayName +FSharp.Compiler.Symbols.FSharpSymbol: System.String DisplayNameCore +FSharp.Compiler.Symbols.FSharpSymbol: System.String FullName +FSharp.Compiler.Symbols.FSharpSymbol: System.String ToString() +FSharp.Compiler.Symbols.FSharpSymbol: System.String get_DisplayName() +FSharp.Compiler.Symbols.FSharpSymbol: System.String get_DisplayNameCore() +FSharp.Compiler.Symbols.FSharpSymbol: System.String get_FullName() +FSharp.Compiler.Symbols.FSharpSymbolPatterns +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpActivePatternCase] |ActivePatternCase|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] |Constructor|_|(FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] |TypeWithDefinition|_|(FSharp.Compiler.Symbols.FSharpType) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpField] |RecordField|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] |MemberFunctionOrValue|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] |AbbreviatedType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpUnionCase] |UnionCase|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |AbstractClass|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Array|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Attribute|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |ByRef|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Class|_|[a](FSharp.Compiler.Symbols.FSharpEntity, FSharp.Compiler.Symbols.FSharpEntity, a) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Delegate|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Enum|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Event|_|(FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |ExtensionMember|_|(FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |FSharpException|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |FSharpModule|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |FSharpType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |FunctionType|_|(FSharp.Compiler.Symbols.FSharpType) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Function|_|(Boolean, FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Interface|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |MutableVar|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Namespace|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Parameter|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Pattern|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |ProvidedAndErasedType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |ProvidedType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Record|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |RefCell|_|(FSharp.Compiler.Symbols.FSharpType) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |Tuple|_|(FSharp.Compiler.Symbols.FSharpType) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |UnionType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] |ValueType|_|(FSharp.Compiler.Symbols.FSharpEntity) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpField,FSharp.Compiler.Symbols.FSharpType]] |Field|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpSymbolPatterns: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[FSharp.Compiler.Symbols.FSharpEntity,FSharp.Compiler.Symbols.FSharpEntity,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType]]] |FSharpEntity|_|(FSharp.Compiler.Symbols.FSharpSymbol) +FSharp.Compiler.Symbols.FSharpType +FSharp.Compiler.Symbols.FSharpType: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpType: Boolean HasTypeDefinition +FSharp.Compiler.Symbols.FSharpType: Boolean IsAbbreviation +FSharp.Compiler.Symbols.FSharpType: Boolean IsAnonRecordType +FSharp.Compiler.Symbols.FSharpType: Boolean IsFunctionType +FSharp.Compiler.Symbols.FSharpType: Boolean IsGenericParameter +FSharp.Compiler.Symbols.FSharpType: Boolean IsStructTupleType +FSharp.Compiler.Symbols.FSharpType: Boolean IsTupleType +FSharp.Compiler.Symbols.FSharpType: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpType: Boolean get_HasTypeDefinition() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAbbreviation() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsAnonRecordType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsFunctionType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsGenericParameter() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsStructTupleType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsTupleType() +FSharp.Compiler.Symbols.FSharpType: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails AnonRecordTypeDetails +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpAnonRecordTypeDetails get_AnonRecordTypeDetails() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpEntity TypeDefinition +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpEntity get_TypeDefinition() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpGenericParameter GenericParameter +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpGenericParameter get_GenericParameter() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpParameter Prettify(FSharp.Compiler.Symbols.FSharpParameter) +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType AbbreviatedType +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType Instantiate(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpGenericParameter,FSharp.Compiler.Symbols.FSharpType]]) +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType Prettify(FSharp.Compiler.Symbols.FSharpType) +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType StripAbbreviations() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType get_AbbreviatedType() +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Text.TaggedText[] FormatLayout(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Text.TaggedText[] FormatLayoutWithConstraints(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpType: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] BaseType +FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] get_BaseType() +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter] Prettify(System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]) +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] AllInterfaces +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] GenericArguments +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] Prettify(System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType]) +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_AllInterfaces() +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_GenericArguments() +FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]] Prettify(System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]]) +FSharp.Compiler.Symbols.FSharpType: System.String Format(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpType: System.String FormatWithConstraints(FSharp.Compiler.Symbols.FSharpDisplayContext) +FSharp.Compiler.Symbols.FSharpType: System.String ToString() +FSharp.Compiler.Symbols.FSharpType: System.Tuple`2[System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]],FSharp.Compiler.Symbols.FSharpParameter] Prettify(System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]], FSharp.Compiler.Symbols.FSharpParameter) +FSharp.Compiler.Symbols.FSharpUnionCase +FSharp.Compiler.Symbols.FSharpUnionCase: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpUnionCase: Boolean HasFields +FSharp.Compiler.Symbols.FSharpUnionCase: Boolean IsUnresolved +FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_HasFields() +FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_IsUnresolved() +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType ReturnType +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType get_ReturnType() +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range DeclarationLocation +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range get_DeclarationLocation() +FSharp.Compiler.Symbols.FSharpUnionCase: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes +FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() +FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpField] Fields +FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpField] get_Fields() +FSharp.Compiler.Symbols.FSharpUnionCase: System.String CompiledName +FSharp.Compiler.Symbols.FSharpUnionCase: System.String Name +FSharp.Compiler.Symbols.FSharpUnionCase: System.String ToString() +FSharp.Compiler.Symbols.FSharpUnionCase: System.String XmlDocSig +FSharp.Compiler.Symbols.FSharpUnionCase: System.String get_CompiledName() +FSharp.Compiler.Symbols.FSharpUnionCase: System.String get_Name() +FSharp.Compiler.Symbols.FSharpUnionCase: System.String get_XmlDocSig() +FSharp.Compiler.Symbols.FSharpXmlDoc +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlFile: System.String dllName +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlFile: System.String get_dllName() +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlFile: System.String get_xmlSig() +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlFile: System.String xmlSig +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlText: FSharp.Compiler.Xml.XmlDoc Item +FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlText: FSharp.Compiler.Xml.XmlDoc get_Item() +FSharp.Compiler.Symbols.FSharpXmlDoc+Tags: Int32 FromXmlFile +FSharp.Compiler.Symbols.FSharpXmlDoc+Tags: Int32 FromXmlText +FSharp.Compiler.Symbols.FSharpXmlDoc+Tags: Int32 None +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean Equals(FSharp.Compiler.Symbols.FSharpXmlDoc) +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean Equals(System.Object) +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean IsFromXmlFile +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean IsFromXmlText +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean IsNone +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean get_IsFromXmlFile() +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean get_IsFromXmlText() +FSharp.Compiler.Symbols.FSharpXmlDoc: Boolean get_IsNone() +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc NewFromXmlFile(System.String, System.String) +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc NewFromXmlText(FSharp.Compiler.Xml.XmlDoc) +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc None +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc get_None() +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlFile +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc+FromXmlText +FSharp.Compiler.Symbols.FSharpXmlDoc: FSharp.Compiler.Symbols.FSharpXmlDoc+Tags +FSharp.Compiler.Symbols.FSharpXmlDoc: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpXmlDoc: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Symbols.FSharpXmlDoc: Int32 Tag +FSharp.Compiler.Symbols.FSharpXmlDoc: Int32 get_Tag() +FSharp.Compiler.Symbols.FSharpXmlDoc: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtBinding +FSharp.Compiler.Syntax.DebugPointAtBinding+Tags: Int32 NoneAtDo +FSharp.Compiler.Syntax.DebugPointAtBinding+Tags: Int32 NoneAtInvisible +FSharp.Compiler.Syntax.DebugPointAtBinding+Tags: Int32 NoneAtLet +FSharp.Compiler.Syntax.DebugPointAtBinding+Tags: Int32 NoneAtSticky +FSharp.Compiler.Syntax.DebugPointAtBinding+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtBinding+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtBinding+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtBinding) +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean IsNoneAtDo +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean IsNoneAtInvisible +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean IsNoneAtLet +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean IsNoneAtSticky +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean get_IsNoneAtDo() +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean get_IsNoneAtInvisible() +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean get_IsNoneAtLet() +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean get_IsNoneAtSticky() +FSharp.Compiler.Syntax.DebugPointAtBinding: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding Combine(FSharp.Compiler.Syntax.DebugPointAtBinding) +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding NoneAtDo +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding NoneAtInvisible +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding NoneAtLet +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding NoneAtSticky +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding get_NoneAtDo() +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding get_NoneAtInvisible() +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding get_NoneAtLet() +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding get_NoneAtSticky() +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding+Tags +FSharp.Compiler.Syntax.DebugPointAtBinding: FSharp.Compiler.Syntax.DebugPointAtBinding+Yes +FSharp.Compiler.Syntax.DebugPointAtBinding: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtBinding: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtBinding: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtBinding: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtBinding: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtFinally +FSharp.Compiler.Syntax.DebugPointAtFinally+Tags: Int32 Body +FSharp.Compiler.Syntax.DebugPointAtFinally+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtFinally+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtFinally+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtFinally+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtFinally) +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean IsBody +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean get_IsBody() +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtFinally: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally Body +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally No +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally get_Body() +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally get_No() +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally+Tags +FSharp.Compiler.Syntax.DebugPointAtFinally: FSharp.Compiler.Syntax.DebugPointAtFinally+Yes +FSharp.Compiler.Syntax.DebugPointAtFinally: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtFinally: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtFinally: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtFinally: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtFinally: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtFor +FSharp.Compiler.Syntax.DebugPointAtFor+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtFor+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtFor+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtFor+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtFor) +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtFor: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtFor: FSharp.Compiler.Syntax.DebugPointAtFor NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtFor: FSharp.Compiler.Syntax.DebugPointAtFor No +FSharp.Compiler.Syntax.DebugPointAtFor: FSharp.Compiler.Syntax.DebugPointAtFor get_No() +FSharp.Compiler.Syntax.DebugPointAtFor: FSharp.Compiler.Syntax.DebugPointAtFor+Tags +FSharp.Compiler.Syntax.DebugPointAtFor: FSharp.Compiler.Syntax.DebugPointAtFor+Yes +FSharp.Compiler.Syntax.DebugPointAtFor: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtFor: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtFor: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtFor: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtFor: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtSequential +FSharp.Compiler.Syntax.DebugPointAtSequential+Tags: Int32 SuppressBoth +FSharp.Compiler.Syntax.DebugPointAtSequential+Tags: Int32 SuppressExpr +FSharp.Compiler.Syntax.DebugPointAtSequential+Tags: Int32 SuppressNeither +FSharp.Compiler.Syntax.DebugPointAtSequential+Tags: Int32 SuppressStmt +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtSequential) +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean IsSuppressBoth +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean IsSuppressExpr +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean IsSuppressNeither +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean IsSuppressStmt +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean get_IsSuppressBoth() +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean get_IsSuppressExpr() +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean get_IsSuppressNeither() +FSharp.Compiler.Syntax.DebugPointAtSequential: Boolean get_IsSuppressStmt() +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential SuppressBoth +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential SuppressExpr +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential SuppressNeither +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential SuppressStmt +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential get_SuppressBoth() +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential get_SuppressExpr() +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential get_SuppressNeither() +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential get_SuppressStmt() +FSharp.Compiler.Syntax.DebugPointAtSequential: FSharp.Compiler.Syntax.DebugPointAtSequential+Tags +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 CompareTo(FSharp.Compiler.Syntax.DebugPointAtSequential) +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtSequential: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtSequential: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtSwitch +FSharp.Compiler.Syntax.DebugPointAtSwitch+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtSwitch+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtSwitch+Yes: FSharp.Compiler.Text.Range Item +FSharp.Compiler.Syntax.DebugPointAtSwitch+Yes: FSharp.Compiler.Text.Range get_Item() +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtSwitch) +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtSwitch: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtSwitch: FSharp.Compiler.Syntax.DebugPointAtSwitch NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtSwitch: FSharp.Compiler.Syntax.DebugPointAtSwitch No +FSharp.Compiler.Syntax.DebugPointAtSwitch: FSharp.Compiler.Syntax.DebugPointAtSwitch get_No() +FSharp.Compiler.Syntax.DebugPointAtSwitch: FSharp.Compiler.Syntax.DebugPointAtSwitch+Tags +FSharp.Compiler.Syntax.DebugPointAtSwitch: FSharp.Compiler.Syntax.DebugPointAtSwitch+Yes +FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtSwitch: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtSwitch: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtTarget +FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtTarget+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtTarget) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtTarget: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget No +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget Yes +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_No() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget get_Yes() +FSharp.Compiler.Syntax.DebugPointAtTarget: FSharp.Compiler.Syntax.DebugPointAtTarget+Tags +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(FSharp.Compiler.Syntax.DebugPointAtTarget) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtTarget: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtTarget: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtTry +FSharp.Compiler.Syntax.DebugPointAtTry+Tags: Int32 Body +FSharp.Compiler.Syntax.DebugPointAtTry+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtTry+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtTry+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtTry+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtTry) +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean IsBody +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean get_IsBody() +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtTry: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry Body +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry No +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry get_Body() +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry get_No() +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry+Tags +FSharp.Compiler.Syntax.DebugPointAtTry: FSharp.Compiler.Syntax.DebugPointAtTry+Yes +FSharp.Compiler.Syntax.DebugPointAtTry: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtTry: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtTry: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtTry: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtTry: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtWhile +FSharp.Compiler.Syntax.DebugPointAtWhile+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtWhile+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtWhile+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtWhile+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtWhile) +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtWhile: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtWhile: FSharp.Compiler.Syntax.DebugPointAtWhile NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtWhile: FSharp.Compiler.Syntax.DebugPointAtWhile No +FSharp.Compiler.Syntax.DebugPointAtWhile: FSharp.Compiler.Syntax.DebugPointAtWhile get_No() +FSharp.Compiler.Syntax.DebugPointAtWhile: FSharp.Compiler.Syntax.DebugPointAtWhile+Tags +FSharp.Compiler.Syntax.DebugPointAtWhile: FSharp.Compiler.Syntax.DebugPointAtWhile+Yes +FSharp.Compiler.Syntax.DebugPointAtWhile: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtWhile: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtWhile: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtWhile: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtWhile: System.String ToString() +FSharp.Compiler.Syntax.DebugPointAtWith +FSharp.Compiler.Syntax.DebugPointAtWith+Tags: Int32 No +FSharp.Compiler.Syntax.DebugPointAtWith+Tags: Int32 Yes +FSharp.Compiler.Syntax.DebugPointAtWith+Yes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.DebugPointAtWith+Yes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean Equals(FSharp.Compiler.Syntax.DebugPointAtWith) +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean IsNo +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean IsYes +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean get_IsNo() +FSharp.Compiler.Syntax.DebugPointAtWith: Boolean get_IsYes() +FSharp.Compiler.Syntax.DebugPointAtWith: FSharp.Compiler.Syntax.DebugPointAtWith NewYes(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.DebugPointAtWith: FSharp.Compiler.Syntax.DebugPointAtWith No +FSharp.Compiler.Syntax.DebugPointAtWith: FSharp.Compiler.Syntax.DebugPointAtWith get_No() +FSharp.Compiler.Syntax.DebugPointAtWith: FSharp.Compiler.Syntax.DebugPointAtWith+Tags +FSharp.Compiler.Syntax.DebugPointAtWith: FSharp.Compiler.Syntax.DebugPointAtWith+Yes +FSharp.Compiler.Syntax.DebugPointAtWith: Int32 GetHashCode() +FSharp.Compiler.Syntax.DebugPointAtWith: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.DebugPointAtWith: Int32 Tag +FSharp.Compiler.Syntax.DebugPointAtWith: Int32 get_Tag() +FSharp.Compiler.Syntax.DebugPointAtWith: System.String ToString() +FSharp.Compiler.Syntax.ExprAtomicFlag +FSharp.Compiler.Syntax.ExprAtomicFlag: FSharp.Compiler.Syntax.ExprAtomicFlag Atomic +FSharp.Compiler.Syntax.ExprAtomicFlag: FSharp.Compiler.Syntax.ExprAtomicFlag NonAtomic +FSharp.Compiler.Syntax.ExprAtomicFlag: Int32 value__ +FSharp.Compiler.Syntax.Ident +FSharp.Compiler.Syntax.Ident: FSharp.Compiler.Text.Range get_idRange() +FSharp.Compiler.Syntax.Ident: FSharp.Compiler.Text.Range idRange +FSharp.Compiler.Syntax.Ident: System.String ToString() +FSharp.Compiler.Syntax.Ident: System.String get_idText() +FSharp.Compiler.Syntax.Ident: System.String idText +FSharp.Compiler.Syntax.Ident: Void .ctor(System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.LongIdentWithDots +FSharp.Compiler.Syntax.LongIdentWithDots: Boolean ThereIsAnExtraDotAtTheEnd +FSharp.Compiler.Syntax.LongIdentWithDots: Boolean get_ThereIsAnExtraDotAtTheEnd() +FSharp.Compiler.Syntax.LongIdentWithDots: FSharp.Compiler.Syntax.LongIdentWithDots NewLongIdentWithDots(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.Syntax.LongIdentWithDots: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.LongIdentWithDots: FSharp.Compiler.Text.Range RangeWithoutAnyExtraDot +FSharp.Compiler.Syntax.LongIdentWithDots: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.LongIdentWithDots: FSharp.Compiler.Text.Range get_RangeWithoutAnyExtraDot() +FSharp.Compiler.Syntax.LongIdentWithDots: Int32 Tag +FSharp.Compiler.Syntax.LongIdentWithDots: Int32 get_Tag() +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] Lid +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_Lid() +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_id() +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] id +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] dotRanges +FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_dotRanges() +FSharp.Compiler.Syntax.LongIdentWithDots: System.String ToString() +FSharp.Compiler.Syntax.ParsedHashDirective +FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Syntax.ParsedHashDirective NewParsedHashDirective(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedHashDirective: Int32 Tag +FSharp.Compiler.Syntax.ParsedHashDirective: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] args +FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] get_args() +FSharp.Compiler.Syntax.ParsedHashDirective: System.String ToString() +FSharp.Compiler.Syntax.ParsedHashDirective: System.String get_ident() +FSharp.Compiler.Syntax.ParsedHashDirective: System.String ident +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String constant +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_constant() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_value() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind get_stringKind() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind stringKind +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String get_value() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String value +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 SourceIdentifier +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 String +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsSourceIdentifier +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsString +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsSourceIdentifier() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsString() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewSourceIdentifier(System.String, System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewString(System.String, FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 Tag +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: System.String ToString() +FSharp.Compiler.Syntax.ParsedImplFile +FSharp.Compiler.Syntax.ParsedImplFile: FSharp.Compiler.Syntax.ParsedImplFile NewParsedImplFile(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedImplFileFragment]) +FSharp.Compiler.Syntax.ParsedImplFile: Int32 Tag +FSharp.Compiler.Syntax.ParsedImplFile: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedImplFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] get_hashDirectives() +FSharp.Compiler.Syntax.ParsedImplFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] hashDirectives +FSharp.Compiler.Syntax.ParsedImplFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedImplFileFragment] fragments +FSharp.Compiler.Syntax.ParsedImplFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedImplFileFragment] get_fragments() +FSharp.Compiler.Syntax.ParsedImplFile: System.String ToString() +FSharp.Compiler.Syntax.ParsedImplFileFragment +FSharp.Compiler.Syntax.ParsedImplFileFragment+AnonModule: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedImplFileFragment+AnonModule: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedImplFileFragment+AnonModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] decls +FSharp.Compiler.Syntax.ParsedImplFileFragment+AnonModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] get_decls() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamedModule: FSharp.Compiler.Syntax.SynModuleOrNamespace get_namedModule() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamedModule: FSharp.Compiler.Syntax.SynModuleOrNamespace namedModule +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Boolean get_isRecursive() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Boolean isRecursive +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_kind() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind kind +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] decls +FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] get_decls() +FSharp.Compiler.Syntax.ParsedImplFileFragment+Tags: Int32 AnonModule +FSharp.Compiler.Syntax.ParsedImplFileFragment+Tags: Int32 NamedModule +FSharp.Compiler.Syntax.ParsedImplFileFragment+Tags: Int32 NamespaceFragment +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean IsAnonModule +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean IsNamedModule +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean IsNamespaceFragment +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean get_IsAnonModule() +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean get_IsNamedModule() +FSharp.Compiler.Syntax.ParsedImplFileFragment: Boolean get_IsNamespaceFragment() +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment NewAnonModule(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment NewNamedModule(FSharp.Compiler.Syntax.SynModuleOrNamespace) +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment NewNamespaceFragment(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Boolean, FSharp.Compiler.Syntax.SynModuleOrNamespaceKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment+AnonModule +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment+NamedModule +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment+NamespaceFragment +FSharp.Compiler.Syntax.ParsedImplFileFragment: FSharp.Compiler.Syntax.ParsedImplFileFragment+Tags +FSharp.Compiler.Syntax.ParsedImplFileFragment: Int32 Tag +FSharp.Compiler.Syntax.ParsedImplFileFragment: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedImplFileFragment: System.String ToString() +FSharp.Compiler.Syntax.ParsedImplFileInput +FSharp.Compiler.Syntax.ParsedImplFileInput: Boolean get_isScript() +FSharp.Compiler.Syntax.ParsedImplFileInput: Boolean isScript +FSharp.Compiler.Syntax.ParsedImplFileInput: FSharp.Compiler.Syntax.ParsedImplFileInput NewParsedImplFileInput(System.String, Boolean, FSharp.Compiler.Syntax.QualifiedNameOfFile, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespace], System.Tuple`2[System.Boolean,System.Boolean]) +FSharp.Compiler.Syntax.ParsedImplFileInput: FSharp.Compiler.Syntax.QualifiedNameOfFile get_qualifiedNameOfFile() +FSharp.Compiler.Syntax.ParsedImplFileInput: FSharp.Compiler.Syntax.QualifiedNameOfFile qualifiedNameOfFile +FSharp.Compiler.Syntax.ParsedImplFileInput: Int32 Tag +FSharp.Compiler.Syntax.ParsedImplFileInput: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] get_hashDirectives() +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] hashDirectives +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma] get_scopedPragmas() +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma] scopedPragmas +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespace] get_modules() +FSharp.Compiler.Syntax.ParsedImplFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespace] modules +FSharp.Compiler.Syntax.ParsedImplFileInput: System.String ToString() +FSharp.Compiler.Syntax.ParsedImplFileInput: System.String fileName +FSharp.Compiler.Syntax.ParsedImplFileInput: System.String get_fileName() +FSharp.Compiler.Syntax.ParsedImplFileInput: System.Tuple`2[System.Boolean,System.Boolean] get_isLastCompiland() +FSharp.Compiler.Syntax.ParsedImplFileInput: System.Tuple`2[System.Boolean,System.Boolean] isLastCompiland +FSharp.Compiler.Syntax.ParsedInput +FSharp.Compiler.Syntax.ParsedInput+ImplFile: FSharp.Compiler.Syntax.ParsedImplFileInput Item +FSharp.Compiler.Syntax.ParsedInput+ImplFile: FSharp.Compiler.Syntax.ParsedImplFileInput get_Item() +FSharp.Compiler.Syntax.ParsedInput+SigFile: FSharp.Compiler.Syntax.ParsedSigFileInput Item +FSharp.Compiler.Syntax.ParsedInput+SigFile: FSharp.Compiler.Syntax.ParsedSigFileInput get_Item() +FSharp.Compiler.Syntax.ParsedInput+Tags: Int32 ImplFile +FSharp.Compiler.Syntax.ParsedInput+Tags: Int32 SigFile +FSharp.Compiler.Syntax.ParsedInput: Boolean IsImplFile +FSharp.Compiler.Syntax.ParsedInput: Boolean IsSigFile +FSharp.Compiler.Syntax.ParsedInput: Boolean get_IsImplFile() +FSharp.Compiler.Syntax.ParsedInput: Boolean get_IsSigFile() +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Syntax.ParsedInput NewImplFile(FSharp.Compiler.Syntax.ParsedImplFileInput) +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Syntax.ParsedInput NewSigFile(FSharp.Compiler.Syntax.ParsedSigFileInput) +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Syntax.ParsedInput+ImplFile +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Syntax.ParsedInput+SigFile +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Syntax.ParsedInput+Tags +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.ParsedInput: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.ParsedInput: Int32 Tag +FSharp.Compiler.Syntax.ParsedInput: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedInput: System.String FileName +FSharp.Compiler.Syntax.ParsedInput: System.String ToString() +FSharp.Compiler.Syntax.ParsedInput: System.String get_FileName() +FSharp.Compiler.Syntax.ParsedScriptInteraction +FSharp.Compiler.Syntax.ParsedScriptInteraction+Definitions: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedScriptInteraction+Definitions: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedScriptInteraction+Definitions: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] defns +FSharp.Compiler.Syntax.ParsedScriptInteraction+Definitions: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] get_defns() +FSharp.Compiler.Syntax.ParsedScriptInteraction+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective get_hashDirective() +FSharp.Compiler.Syntax.ParsedScriptInteraction+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective hashDirective +FSharp.Compiler.Syntax.ParsedScriptInteraction+HashDirective: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedScriptInteraction+HashDirective: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedScriptInteraction+Tags: Int32 Definitions +FSharp.Compiler.Syntax.ParsedScriptInteraction+Tags: Int32 HashDirective +FSharp.Compiler.Syntax.ParsedScriptInteraction: Boolean IsDefinitions +FSharp.Compiler.Syntax.ParsedScriptInteraction: Boolean IsHashDirective +FSharp.Compiler.Syntax.ParsedScriptInteraction: Boolean get_IsDefinitions() +FSharp.Compiler.Syntax.ParsedScriptInteraction: Boolean get_IsHashDirective() +FSharp.Compiler.Syntax.ParsedScriptInteraction: FSharp.Compiler.Syntax.ParsedScriptInteraction NewDefinitions(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedScriptInteraction: FSharp.Compiler.Syntax.ParsedScriptInteraction NewHashDirective(FSharp.Compiler.Syntax.ParsedHashDirective, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedScriptInteraction: FSharp.Compiler.Syntax.ParsedScriptInteraction+Definitions +FSharp.Compiler.Syntax.ParsedScriptInteraction: FSharp.Compiler.Syntax.ParsedScriptInteraction+HashDirective +FSharp.Compiler.Syntax.ParsedScriptInteraction: FSharp.Compiler.Syntax.ParsedScriptInteraction+Tags +FSharp.Compiler.Syntax.ParsedScriptInteraction: Int32 Tag +FSharp.Compiler.Syntax.ParsedScriptInteraction: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedScriptInteraction: System.String ToString() +FSharp.Compiler.Syntax.ParsedSigFile +FSharp.Compiler.Syntax.ParsedSigFile: FSharp.Compiler.Syntax.ParsedSigFile NewParsedSigFile(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedSigFileFragment]) +FSharp.Compiler.Syntax.ParsedSigFile: Int32 Tag +FSharp.Compiler.Syntax.ParsedSigFile: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedSigFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] get_hashDirectives() +FSharp.Compiler.Syntax.ParsedSigFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] hashDirectives +FSharp.Compiler.Syntax.ParsedSigFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedSigFileFragment] fragments +FSharp.Compiler.Syntax.ParsedSigFile: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedSigFileFragment] get_fragments() +FSharp.Compiler.Syntax.ParsedSigFile: System.String ToString() +FSharp.Compiler.Syntax.ParsedSigFileFragment +FSharp.Compiler.Syntax.ParsedSigFileFragment+AnonModule: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedSigFileFragment+AnonModule: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedSigFileFragment+AnonModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] decls +FSharp.Compiler.Syntax.ParsedSigFileFragment+AnonModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] get_decls() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamedModule: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig get_namedModule() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamedModule: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig namedModule +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Boolean get_isRecursive() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Boolean isRecursive +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_kind() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind kind +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] decls +FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] get_decls() +FSharp.Compiler.Syntax.ParsedSigFileFragment+Tags: Int32 AnonModule +FSharp.Compiler.Syntax.ParsedSigFileFragment+Tags: Int32 NamedModule +FSharp.Compiler.Syntax.ParsedSigFileFragment+Tags: Int32 NamespaceFragment +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean IsAnonModule +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean IsNamedModule +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean IsNamespaceFragment +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean get_IsAnonModule() +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean get_IsNamedModule() +FSharp.Compiler.Syntax.ParsedSigFileFragment: Boolean get_IsNamespaceFragment() +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment NewAnonModule(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment NewNamedModule(FSharp.Compiler.Syntax.SynModuleOrNamespaceSig) +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment NewNamespaceFragment(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Boolean, FSharp.Compiler.Syntax.SynModuleOrNamespaceKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment+AnonModule +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment+NamedModule +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment+NamespaceFragment +FSharp.Compiler.Syntax.ParsedSigFileFragment: FSharp.Compiler.Syntax.ParsedSigFileFragment+Tags +FSharp.Compiler.Syntax.ParsedSigFileFragment: Int32 Tag +FSharp.Compiler.Syntax.ParsedSigFileFragment: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedSigFileFragment: System.String ToString() +FSharp.Compiler.Syntax.ParsedSigFileInput +FSharp.Compiler.Syntax.ParsedSigFileInput: FSharp.Compiler.Syntax.ParsedSigFileInput NewParsedSigFileInput(System.String, FSharp.Compiler.Syntax.QualifiedNameOfFile, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespaceSig]) +FSharp.Compiler.Syntax.ParsedSigFileInput: FSharp.Compiler.Syntax.QualifiedNameOfFile get_qualifiedNameOfFile() +FSharp.Compiler.Syntax.ParsedSigFileInput: FSharp.Compiler.Syntax.QualifiedNameOfFile qualifiedNameOfFile +FSharp.Compiler.Syntax.ParsedSigFileInput: Int32 Tag +FSharp.Compiler.Syntax.ParsedSigFileInput: Int32 get_Tag() +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] get_hashDirectives() +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective] hashDirectives +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma] get_scopedPragmas() +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ScopedPragma] scopedPragmas +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespaceSig] get_modules() +FSharp.Compiler.Syntax.ParsedSigFileInput: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleOrNamespaceSig] modules +FSharp.Compiler.Syntax.ParsedSigFileInput: System.String ToString() +FSharp.Compiler.Syntax.ParsedSigFileInput: System.String fileName +FSharp.Compiler.Syntax.ParsedSigFileInput: System.String get_fileName() +FSharp.Compiler.Syntax.ParserDetail +FSharp.Compiler.Syntax.ParserDetail+Tags: Int32 ErrorRecovery +FSharp.Compiler.Syntax.ParserDetail+Tags: Int32 Ok +FSharp.Compiler.Syntax.ParserDetail: Boolean Equals(FSharp.Compiler.Syntax.ParserDetail) +FSharp.Compiler.Syntax.ParserDetail: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.ParserDetail: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.ParserDetail: Boolean IsErrorRecovery +FSharp.Compiler.Syntax.ParserDetail: Boolean IsOk +FSharp.Compiler.Syntax.ParserDetail: Boolean get_IsErrorRecovery() +FSharp.Compiler.Syntax.ParserDetail: Boolean get_IsOk() +FSharp.Compiler.Syntax.ParserDetail: FSharp.Compiler.Syntax.ParserDetail ErrorRecovery +FSharp.Compiler.Syntax.ParserDetail: FSharp.Compiler.Syntax.ParserDetail Ok +FSharp.Compiler.Syntax.ParserDetail: FSharp.Compiler.Syntax.ParserDetail get_ErrorRecovery() +FSharp.Compiler.Syntax.ParserDetail: FSharp.Compiler.Syntax.ParserDetail get_Ok() +FSharp.Compiler.Syntax.ParserDetail: FSharp.Compiler.Syntax.ParserDetail+Tags +FSharp.Compiler.Syntax.ParserDetail: Int32 CompareTo(FSharp.Compiler.Syntax.ParserDetail) +FSharp.Compiler.Syntax.ParserDetail: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.ParserDetail: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.ParserDetail: Int32 GetHashCode() +FSharp.Compiler.Syntax.ParserDetail: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.ParserDetail: Int32 Tag +FSharp.Compiler.Syntax.ParserDetail: Int32 get_Tag() +FSharp.Compiler.Syntax.ParserDetail: System.String ToString() +FSharp.Compiler.Syntax.PrettyNaming +FSharp.Compiler.Syntax.PrettyNaming: Boolean DoesIdentifierNeedBackticks(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsActivePatternName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsCompilerGeneratedName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierFirstCharacter(Char) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierPartCharacter(Char) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsInfixOperator(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLongIdentifierPartCharacter(Char) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsMangledOpName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsOperatorDisplayName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsPrefixOperator(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsPunctuation(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Boolean IsTernaryOperator(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Microsoft.FSharp.Collections.FSharpList`1[System.String] GetLongNameFromString(System.String) +FSharp.Compiler.Syntax.PrettyNaming: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryChopPropertyName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: System.String AddBackticksToIdentifierIfNeeded(System.String) +FSharp.Compiler.Syntax.PrettyNaming: System.String CompileOpName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: System.String DecompileOpName(System.String) +FSharp.Compiler.Syntax.PrettyNaming: System.String FormatAndOtherOverloadsString(Int32) +FSharp.Compiler.Syntax.PrettyNaming: System.String FsiDynamicModulePrefix +FSharp.Compiler.Syntax.PrettyNaming: System.String NormalizeIdentifierBackticks(System.String) +FSharp.Compiler.Syntax.PrettyNaming: System.String get_FsiDynamicModulePrefix() +FSharp.Compiler.Syntax.QualifiedNameOfFile +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Syntax.Ident Id +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Syntax.Ident Item +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Syntax.Ident get_Id() +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Syntax.Ident get_Item() +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Syntax.QualifiedNameOfFile NewQualifiedNameOfFile(FSharp.Compiler.Syntax.Ident) +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.QualifiedNameOfFile: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.QualifiedNameOfFile: Int32 Tag +FSharp.Compiler.Syntax.QualifiedNameOfFile: Int32 get_Tag() +FSharp.Compiler.Syntax.QualifiedNameOfFile: System.String Text +FSharp.Compiler.Syntax.QualifiedNameOfFile: System.String ToString() +FSharp.Compiler.Syntax.QualifiedNameOfFile: System.String get_Text() +FSharp.Compiler.Syntax.ScopedPragma +FSharp.Compiler.Syntax.ScopedPragma: Boolean Equals(FSharp.Compiler.Syntax.ScopedPragma) +FSharp.Compiler.Syntax.ScopedPragma: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.ScopedPragma: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.ScopedPragma: FSharp.Compiler.Syntax.ScopedPragma NewWarningOff(FSharp.Compiler.Text.Range, Int32) +FSharp.Compiler.Syntax.ScopedPragma: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.ScopedPragma: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.ScopedPragma: Int32 GetHashCode() +FSharp.Compiler.Syntax.ScopedPragma: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.ScopedPragma: Int32 Tag +FSharp.Compiler.Syntax.ScopedPragma: Int32 get_Tag() +FSharp.Compiler.Syntax.ScopedPragma: Int32 get_warningNumber() +FSharp.Compiler.Syntax.ScopedPragma: Int32 warningNumber +FSharp.Compiler.Syntax.ScopedPragma: System.String ToString() +FSharp.Compiler.Syntax.SeqExprOnly +FSharp.Compiler.Syntax.SeqExprOnly: Boolean Equals(FSharp.Compiler.Syntax.SeqExprOnly) +FSharp.Compiler.Syntax.SeqExprOnly: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SeqExprOnly: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SeqExprOnly: Boolean Item +FSharp.Compiler.Syntax.SeqExprOnly: Boolean get_Item() +FSharp.Compiler.Syntax.SeqExprOnly: FSharp.Compiler.Syntax.SeqExprOnly NewSeqExprOnly(Boolean) +FSharp.Compiler.Syntax.SeqExprOnly: Int32 CompareTo(FSharp.Compiler.Syntax.SeqExprOnly) +FSharp.Compiler.Syntax.SeqExprOnly: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SeqExprOnly: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SeqExprOnly: Int32 GetHashCode() +FSharp.Compiler.Syntax.SeqExprOnly: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SeqExprOnly: Int32 Tag +FSharp.Compiler.Syntax.SeqExprOnly: Int32 get_Tag() +FSharp.Compiler.Syntax.SeqExprOnly: System.String ToString() +FSharp.Compiler.Syntax.SynAccess +FSharp.Compiler.Syntax.SynAccess+Tags: Int32 Internal +FSharp.Compiler.Syntax.SynAccess+Tags: Int32 Private +FSharp.Compiler.Syntax.SynAccess+Tags: Int32 Public +FSharp.Compiler.Syntax.SynAccess: Boolean Equals(FSharp.Compiler.Syntax.SynAccess) +FSharp.Compiler.Syntax.SynAccess: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynAccess: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynAccess: Boolean IsInternal +FSharp.Compiler.Syntax.SynAccess: Boolean IsPrivate +FSharp.Compiler.Syntax.SynAccess: Boolean IsPublic +FSharp.Compiler.Syntax.SynAccess: Boolean get_IsInternal() +FSharp.Compiler.Syntax.SynAccess: Boolean get_IsPrivate() +FSharp.Compiler.Syntax.SynAccess: Boolean get_IsPublic() +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess Internal +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess Private +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess Public +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess get_Internal() +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess get_Private() +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess get_Public() +FSharp.Compiler.Syntax.SynAccess: FSharp.Compiler.Syntax.SynAccess+Tags +FSharp.Compiler.Syntax.SynAccess: Int32 CompareTo(FSharp.Compiler.Syntax.SynAccess) +FSharp.Compiler.Syntax.SynAccess: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SynAccess: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SynAccess: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynAccess: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynAccess: Int32 Tag +FSharp.Compiler.Syntax.SynAccess: Int32 get_Tag() +FSharp.Compiler.Syntax.SynAccess: System.String ToString() +FSharp.Compiler.Syntax.SynArgInfo +FSharp.Compiler.Syntax.SynArgInfo: Boolean get_optional() +FSharp.Compiler.Syntax.SynArgInfo: Boolean optional +FSharp.Compiler.Syntax.SynArgInfo: FSharp.Compiler.Syntax.SynArgInfo NewSynArgInfo(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]) +FSharp.Compiler.Syntax.SynArgInfo: Int32 Tag +FSharp.Compiler.Syntax.SynArgInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] Attributes +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_Attributes() +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] Ident +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_Ident() +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_ident() +FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] ident +FSharp.Compiler.Syntax.SynArgInfo: System.String ToString() +FSharp.Compiler.Syntax.SynArgPats +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynPat]] get_pats() +FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynPat]] pats +FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_pats() +FSharp.Compiler.Syntax.SynArgPats+Pats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] pats +FSharp.Compiler.Syntax.SynArgPats+Tags: Int32 NamePatPairs +FSharp.Compiler.Syntax.SynArgPats+Tags: Int32 Pats +FSharp.Compiler.Syntax.SynArgPats: Boolean IsNamePatPairs +FSharp.Compiler.Syntax.SynArgPats: Boolean IsPats +FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsNamePatPairs() +FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsPats() +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewPats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat]) +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+NamePatPairs +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Pats +FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Tags +FSharp.Compiler.Syntax.SynArgPats: Int32 Tag +FSharp.Compiler.Syntax.SynArgPats: Int32 get_Tag() +FSharp.Compiler.Syntax.SynArgPats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] Patterns +FSharp.Compiler.Syntax.SynArgPats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_Patterns() +FSharp.Compiler.Syntax.SynArgPats: System.String ToString() +FSharp.Compiler.Syntax.SynAttribute +FSharp.Compiler.Syntax.SynAttribute: Boolean AppliesToGetterAndSetter +FSharp.Compiler.Syntax.SynAttribute: Boolean get_AppliesToGetterAndSetter() +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Syntax.LongIdentWithDots TypeName +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Syntax.LongIdentWithDots get_TypeName() +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Syntax.SynExpr ArgExpr +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Syntax.SynExpr get_ArgExpr() +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynAttribute: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynAttribute: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] Target +FSharp.Compiler.Syntax.SynAttribute: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_Target() +FSharp.Compiler.Syntax.SynAttribute: System.String ToString() +FSharp.Compiler.Syntax.SynAttribute: Void .ctor(FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynAttributeList +FSharp.Compiler.Syntax.SynAttributeList: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynAttributeList: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynAttributeList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttribute] Attributes +FSharp.Compiler.Syntax.SynAttributeList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttribute] get_Attributes() +FSharp.Compiler.Syntax.SynAttributeList: System.String ToString() +FSharp.Compiler.Syntax.SynAttributeList: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttribute], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynBinding +FSharp.Compiler.Syntax.SynBinding: Boolean get_isInline() +FSharp.Compiler.Syntax.SynBinding: Boolean get_isMutable() +FSharp.Compiler.Syntax.SynBinding: Boolean isInline +FSharp.Compiler.Syntax.SynBinding: Boolean isMutable +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.DebugPointAtBinding debugPoint +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.DebugPointAtBinding get_debugPoint() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynBinding NewSynBinding(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Syntax.SynBindingKind, Boolean, Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Xml.PreXmlDoc, FSharp.Compiler.Syntax.SynValData, FSharp.Compiler.Syntax.SynPat, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynBindingReturnInfo], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.DebugPointAtBinding) +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynBindingKind get_kind() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynBindingKind kind +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynPat get_headPat() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynPat headPat +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynValData get_valData() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Syntax.SynValData valData +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range RangeOfBindingWithRhs +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range RangeOfBindingWithoutRhs +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range RangeOfHeadPattern +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range get_RangeOfBindingWithRhs() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range get_RangeOfBindingWithoutRhs() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range get_RangeOfHeadPattern() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynBinding: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynBinding: Int32 Tag +FSharp.Compiler.Syntax.SynBinding: Int32 get_Tag() +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynBindingReturnInfo] get_returnInfo() +FSharp.Compiler.Syntax.SynBinding: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynBindingReturnInfo] returnInfo +FSharp.Compiler.Syntax.SynBinding: System.String ToString() +FSharp.Compiler.Syntax.SynBindingKind +FSharp.Compiler.Syntax.SynBindingKind+Tags: Int32 Do +FSharp.Compiler.Syntax.SynBindingKind+Tags: Int32 Normal +FSharp.Compiler.Syntax.SynBindingKind+Tags: Int32 StandaloneExpression +FSharp.Compiler.Syntax.SynBindingKind: Boolean Equals(FSharp.Compiler.Syntax.SynBindingKind) +FSharp.Compiler.Syntax.SynBindingKind: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynBindingKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynBindingKind: Boolean IsDo +FSharp.Compiler.Syntax.SynBindingKind: Boolean IsNormal +FSharp.Compiler.Syntax.SynBindingKind: Boolean IsStandaloneExpression +FSharp.Compiler.Syntax.SynBindingKind: Boolean get_IsDo() +FSharp.Compiler.Syntax.SynBindingKind: Boolean get_IsNormal() +FSharp.Compiler.Syntax.SynBindingKind: Boolean get_IsStandaloneExpression() +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind Do +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind Normal +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind StandaloneExpression +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind get_Do() +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind get_Normal() +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind get_StandaloneExpression() +FSharp.Compiler.Syntax.SynBindingKind: FSharp.Compiler.Syntax.SynBindingKind+Tags +FSharp.Compiler.Syntax.SynBindingKind: Int32 CompareTo(FSharp.Compiler.Syntax.SynBindingKind) +FSharp.Compiler.Syntax.SynBindingKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SynBindingKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SynBindingKind: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynBindingKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynBindingKind: Int32 Tag +FSharp.Compiler.Syntax.SynBindingKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynBindingKind: System.String ToString() +FSharp.Compiler.Syntax.SynBindingReturnInfo +FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynBindingReturnInfo NewSynBindingReturnInfo(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList]) +FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynBindingReturnInfo: Int32 Tag +FSharp.Compiler.Syntax.SynBindingReturnInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynBindingReturnInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynBindingReturnInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynBindingReturnInfo: System.String ToString() +FSharp.Compiler.Syntax.SynByteStringKind +FSharp.Compiler.Syntax.SynByteStringKind+Tags: Int32 Regular +FSharp.Compiler.Syntax.SynByteStringKind+Tags: Int32 Verbatim +FSharp.Compiler.Syntax.SynByteStringKind: Boolean Equals(FSharp.Compiler.Syntax.SynByteStringKind) +FSharp.Compiler.Syntax.SynByteStringKind: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynByteStringKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynByteStringKind: Boolean IsRegular +FSharp.Compiler.Syntax.SynByteStringKind: Boolean IsVerbatim +FSharp.Compiler.Syntax.SynByteStringKind: Boolean get_IsRegular() +FSharp.Compiler.Syntax.SynByteStringKind: Boolean get_IsVerbatim() +FSharp.Compiler.Syntax.SynByteStringKind: FSharp.Compiler.Syntax.SynByteStringKind Regular +FSharp.Compiler.Syntax.SynByteStringKind: FSharp.Compiler.Syntax.SynByteStringKind Verbatim +FSharp.Compiler.Syntax.SynByteStringKind: FSharp.Compiler.Syntax.SynByteStringKind get_Regular() +FSharp.Compiler.Syntax.SynByteStringKind: FSharp.Compiler.Syntax.SynByteStringKind get_Verbatim() +FSharp.Compiler.Syntax.SynByteStringKind: FSharp.Compiler.Syntax.SynByteStringKind+Tags +FSharp.Compiler.Syntax.SynByteStringKind: Int32 CompareTo(FSharp.Compiler.Syntax.SynByteStringKind) +FSharp.Compiler.Syntax.SynByteStringKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SynByteStringKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SynByteStringKind: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynByteStringKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynByteStringKind: Int32 Tag +FSharp.Compiler.Syntax.SynByteStringKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynByteStringKind: System.String ToString() +FSharp.Compiler.Syntax.SynComponentInfo +FSharp.Compiler.Syntax.SynComponentInfo: Boolean get_preferPostfix() +FSharp.Compiler.Syntax.SynComponentInfo: Boolean preferPostfix +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Syntax.SynComponentInfo NewSynComponentInfo(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Xml.PreXmlDoc, Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynComponentInfo: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynComponentInfo: Int32 Tag +FSharp.Compiler.Syntax.SynComponentInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] constraints +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_constraints() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls] get_typeParams() +FSharp.Compiler.Syntax.SynComponentInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls] typeParams +FSharp.Compiler.Syntax.SynComponentInfo: System.String ToString() +FSharp.Compiler.Syntax.SynConst +FSharp.Compiler.Syntax.SynConst+Bool: Boolean Item +FSharp.Compiler.Syntax.SynConst+Bool: Boolean get_Item() +FSharp.Compiler.Syntax.SynConst+Byte: Byte Item +FSharp.Compiler.Syntax.SynConst+Byte: Byte get_Item() +FSharp.Compiler.Syntax.SynConst+Bytes: Byte[] bytes +FSharp.Compiler.Syntax.SynConst+Bytes: Byte[] get_bytes() +FSharp.Compiler.Syntax.SynConst+Bytes: FSharp.Compiler.Syntax.SynByteStringKind get_synByteStringKind() +FSharp.Compiler.Syntax.SynConst+Bytes: FSharp.Compiler.Syntax.SynByteStringKind synByteStringKind +FSharp.Compiler.Syntax.SynConst+Bytes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynConst+Bytes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynConst+Char: Char Item +FSharp.Compiler.Syntax.SynConst+Char: Char get_Item() +FSharp.Compiler.Syntax.SynConst+Decimal: System.Decimal Item +FSharp.Compiler.Syntax.SynConst+Decimal: System.Decimal get_Item() +FSharp.Compiler.Syntax.SynConst+Double: Double Item +FSharp.Compiler.Syntax.SynConst+Double: Double get_Item() +FSharp.Compiler.Syntax.SynConst+Int16: Int16 Item +FSharp.Compiler.Syntax.SynConst+Int16: Int16 get_Item() +FSharp.Compiler.Syntax.SynConst+Int32: Int32 Item +FSharp.Compiler.Syntax.SynConst+Int32: Int32 get_Item() +FSharp.Compiler.Syntax.SynConst+Int64: Int64 Item +FSharp.Compiler.Syntax.SynConst+Int64: Int64 get_Item() +FSharp.Compiler.Syntax.SynConst+IntPtr: Int64 Item +FSharp.Compiler.Syntax.SynConst+IntPtr: Int64 get_Item() +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Syntax.SynConst constant +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Syntax.SynConst get_constant() +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Syntax.SynMeasure Item3 +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Syntax.SynMeasure get_Item3() +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Text.Range constantRange +FSharp.Compiler.Syntax.SynConst+Measure: FSharp.Compiler.Text.Range get_constantRange() +FSharp.Compiler.Syntax.SynConst+SByte: SByte Item +FSharp.Compiler.Syntax.SynConst+SByte: SByte get_Item() +FSharp.Compiler.Syntax.SynConst+Single: Single Item +FSharp.Compiler.Syntax.SynConst+Single: Single get_Item() +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: System.String constant +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: System.String get_constant() +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: System.String get_value() +FSharp.Compiler.Syntax.SynConst+SourceIdentifier: System.String value +FSharp.Compiler.Syntax.SynConst+String: FSharp.Compiler.Syntax.SynStringKind get_synStringKind() +FSharp.Compiler.Syntax.SynConst+String: FSharp.Compiler.Syntax.SynStringKind synStringKind +FSharp.Compiler.Syntax.SynConst+String: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynConst+String: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynConst+String: System.String get_text() +FSharp.Compiler.Syntax.SynConst+String: System.String text +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Bool +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Byte +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Bytes +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Char +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Decimal +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Double +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Int16 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Int32 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Int64 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 IntPtr +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Measure +FSharp.Compiler.Syntax.SynConst+Tags: Int32 SByte +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Single +FSharp.Compiler.Syntax.SynConst+Tags: Int32 SourceIdentifier +FSharp.Compiler.Syntax.SynConst+Tags: Int32 String +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UInt16 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UInt16s +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UInt32 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UInt64 +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UIntPtr +FSharp.Compiler.Syntax.SynConst+Tags: Int32 Unit +FSharp.Compiler.Syntax.SynConst+Tags: Int32 UserNum +FSharp.Compiler.Syntax.SynConst+UInt16: UInt16 Item +FSharp.Compiler.Syntax.SynConst+UInt16: UInt16 get_Item() +FSharp.Compiler.Syntax.SynConst+UInt16s: UInt16[] Item +FSharp.Compiler.Syntax.SynConst+UInt16s: UInt16[] get_Item() +FSharp.Compiler.Syntax.SynConst+UInt32: UInt32 Item +FSharp.Compiler.Syntax.SynConst+UInt32: UInt32 get_Item() +FSharp.Compiler.Syntax.SynConst+UInt64: UInt64 Item +FSharp.Compiler.Syntax.SynConst+UInt64: UInt64 get_Item() +FSharp.Compiler.Syntax.SynConst+UIntPtr: UInt64 Item +FSharp.Compiler.Syntax.SynConst+UIntPtr: UInt64 get_Item() +FSharp.Compiler.Syntax.SynConst+UserNum: System.String get_suffix() +FSharp.Compiler.Syntax.SynConst+UserNum: System.String get_value() +FSharp.Compiler.Syntax.SynConst+UserNum: System.String suffix +FSharp.Compiler.Syntax.SynConst+UserNum: System.String value +FSharp.Compiler.Syntax.SynConst: Boolean IsBool +FSharp.Compiler.Syntax.SynConst: Boolean IsByte +FSharp.Compiler.Syntax.SynConst: Boolean IsBytes +FSharp.Compiler.Syntax.SynConst: Boolean IsChar +FSharp.Compiler.Syntax.SynConst: Boolean IsDecimal +FSharp.Compiler.Syntax.SynConst: Boolean IsDouble +FSharp.Compiler.Syntax.SynConst: Boolean IsInt16 +FSharp.Compiler.Syntax.SynConst: Boolean IsInt32 +FSharp.Compiler.Syntax.SynConst: Boolean IsInt64 +FSharp.Compiler.Syntax.SynConst: Boolean IsIntPtr +FSharp.Compiler.Syntax.SynConst: Boolean IsMeasure +FSharp.Compiler.Syntax.SynConst: Boolean IsSByte +FSharp.Compiler.Syntax.SynConst: Boolean IsSingle +FSharp.Compiler.Syntax.SynConst: Boolean IsSourceIdentifier +FSharp.Compiler.Syntax.SynConst: Boolean IsString +FSharp.Compiler.Syntax.SynConst: Boolean IsUInt16 +FSharp.Compiler.Syntax.SynConst: Boolean IsUInt16s +FSharp.Compiler.Syntax.SynConst: Boolean IsUInt32 +FSharp.Compiler.Syntax.SynConst: Boolean IsUInt64 +FSharp.Compiler.Syntax.SynConst: Boolean IsUIntPtr +FSharp.Compiler.Syntax.SynConst: Boolean IsUnit +FSharp.Compiler.Syntax.SynConst: Boolean IsUserNum +FSharp.Compiler.Syntax.SynConst: Boolean get_IsBool() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsByte() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsBytes() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsChar() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsDecimal() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsDouble() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsInt16() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsInt32() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsInt64() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsIntPtr() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsMeasure() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsSByte() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsSingle() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsSourceIdentifier() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsString() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUInt16() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUInt16s() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUInt32() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUInt64() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUIntPtr() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUnit() +FSharp.Compiler.Syntax.SynConst: Boolean get_IsUserNum() +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewBool(Boolean) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewByte(Byte) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewBytes(Byte[], FSharp.Compiler.Syntax.SynByteStringKind, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewChar(Char) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewDecimal(System.Decimal) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewDouble(Double) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewInt16(Int16) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewInt32(Int32) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewInt64(Int64) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewIntPtr(Int64) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewMeasure(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynMeasure) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewSByte(SByte) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewSingle(Single) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewSourceIdentifier(System.String, System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewString(System.String, FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUInt16(UInt16) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUInt16s(UInt16[]) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUInt32(UInt32) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUInt64(UInt64) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUIntPtr(UInt64) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst NewUserNum(System.String, System.String) +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst Unit +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst get_Unit() +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Bool +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Byte +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Bytes +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Char +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Decimal +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Double +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Int16 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Int32 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Int64 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+IntPtr +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Measure +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+SByte +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Single +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+SourceIdentifier +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+String +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+Tags +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UInt16 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UInt16s +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UInt32 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UInt64 +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UIntPtr +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Syntax.SynConst+UserNum +FSharp.Compiler.Syntax.SynConst: FSharp.Compiler.Text.Range Range(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynConst: Int32 Tag +FSharp.Compiler.Syntax.SynConst: Int32 get_Tag() +FSharp.Compiler.Syntax.SynConst: System.String ToString() +FSharp.Compiler.Syntax.SynEnumCase +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Syntax.SynConst get_value() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Syntax.SynConst value +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Syntax.SynEnumCase NewSynEnumCase(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range, FSharp.Compiler.Xml.PreXmlDoc, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range get_valueRange() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Text.Range valueRange +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynEnumCase: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynEnumCase: Int32 Tag +FSharp.Compiler.Syntax.SynEnumCase: Int32 get_Tag() +FSharp.Compiler.Syntax.SynEnumCase: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynEnumCase: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynEnumCase: System.String ToString() +FSharp.Compiler.Syntax.SynExceptionDefn +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Syntax.SynExceptionDefn NewSynExceptionDefn(FSharp.Compiler.Syntax.SynExceptionDefnRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Syntax.SynExceptionDefnRepr exnRepr +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Syntax.SynExceptionDefnRepr get_exnRepr() +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExceptionDefn: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExceptionDefn: Int32 Tag +FSharp.Compiler.Syntax.SynExceptionDefn: Int32 get_Tag() +FSharp.Compiler.Syntax.SynExceptionDefn: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] get_members() +FSharp.Compiler.Syntax.SynExceptionDefn: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] members +FSharp.Compiler.Syntax.SynExceptionDefn: System.String ToString() +FSharp.Compiler.Syntax.SynExceptionDefnRepr +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Syntax.SynExceptionDefnRepr NewSynExceptionDefnRepr(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.SynUnionCase, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident]], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Syntax.SynUnionCase caseName +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Syntax.SynUnionCase get_caseName() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Int32 Tag +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Int32 get_Tag() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident]] get_longId() +FSharp.Compiler.Syntax.SynExceptionDefnRepr: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident]] longId +FSharp.Compiler.Syntax.SynExceptionDefnRepr: System.String ToString() +FSharp.Compiler.Syntax.SynExceptionSig +FSharp.Compiler.Syntax.SynExceptionSig: FSharp.Compiler.Syntax.SynExceptionDefnRepr exnRepr +FSharp.Compiler.Syntax.SynExceptionSig: FSharp.Compiler.Syntax.SynExceptionDefnRepr get_exnRepr() +FSharp.Compiler.Syntax.SynExceptionSig: FSharp.Compiler.Syntax.SynExceptionSig NewSynExceptionSig(FSharp.Compiler.Syntax.SynExceptionDefnRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExceptionSig: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExceptionSig: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExceptionSig: Int32 Tag +FSharp.Compiler.Syntax.SynExceptionSig: Int32 get_Tag() +FSharp.Compiler.Syntax.SynExceptionSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] get_members() +FSharp.Compiler.Syntax.SynExceptionSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] members +FSharp.Compiler.Syntax.SynExceptionSig: System.String ToString() +FSharp.Compiler.Syntax.SynExpr +FSharp.Compiler.Syntax.SynExpr+AddressOf: Boolean get_isByref() +FSharp.Compiler.Syntax.SynExpr+AddressOf: Boolean isByref +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Text.Range get_opRange() +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Text.Range opRange +FSharp.Compiler.Syntax.SynExpr+AddressOf: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Boolean get_isStruct() +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Boolean isStruct +FSharp.Compiler.Syntax.SynExpr+AnonRecd: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+AnonRecd: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynExpr]] get_recordFields() +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynExpr]] recordFields +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]] copyInfo +FSharp.Compiler.Syntax.SynExpr+AnonRecd: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]] get_copyInfo() +FSharp.Compiler.Syntax.SynExpr+App: Boolean get_isInfix() +FSharp.Compiler.Syntax.SynExpr+App: Boolean isInfix +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.ExprAtomicFlag flag +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.ExprAtomicFlag get_flag() +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.SynExpr argExpr +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.SynExpr funcExpr +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.SynExpr get_argExpr() +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Syntax.SynExpr get_funcExpr() +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+App: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ArbitraryAfterError: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ArbitraryAfterError: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ArbitraryAfterError: System.String debugStr +FSharp.Compiler.Syntax.SynExpr+ArbitraryAfterError: System.String get_debugStr() +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: Boolean get_isArray() +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: Boolean isArray +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] exprs +FSharp.Compiler.Syntax.SynExpr+ArrayOrList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] get_exprs() +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: Boolean get_isArray() +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: Boolean isArray +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Assert: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Assert: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Assert: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Assert: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: Boolean get_hasSeqBuilder() +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: Boolean hasSeqBuilder +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ComputationExpr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Const: FSharp.Compiler.Syntax.SynConst constant +FSharp.Compiler.Syntax.SynExpr+Const: FSharp.Compiler.Syntax.SynConst get_constant() +FSharp.Compiler.Syntax.SynExpr+Const: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Const: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DiscardAfterMissingQualificationAfterDot: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DiscardAfterMissingQualificationAfterDot: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DiscardAfterMissingQualificationAfterDot: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DiscardAfterMissingQualificationAfterDot: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Do: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Do: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Do: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Do: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Text.Range get_rangeOfDot() +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotGet: FSharp.Compiler.Text.Range rangeOfDot +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Syntax.SynExpr get_indexArgs() +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Syntax.SynExpr get_objectExpr() +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Syntax.SynExpr indexArgs +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Syntax.SynExpr objectExpr +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Text.Range dotRange +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Text.Range get_dotRange() +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotIndexedGet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr get_indexArgs() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr get_objectExpr() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr get_valueExpr() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr indexArgs +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr objectExpr +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Syntax.SynExpr valueExpr +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range dotRange +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_dotRange() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_leftOfSetRange() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfSetRange +FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_argExpr() +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_targetExpr() +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr rhsExpr +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr targetExpr +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.SynExpr get_targetExpr() +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.SynExpr rhsExpr +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Syntax.SynExpr targetExpr +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Downcast: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Fixed: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Fixed: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Fixed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Fixed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+For: Boolean direction +FSharp.Compiler.Syntax.SynExpr+For: Boolean get_direction() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.DebugPointAtFor forDebugPoint +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.DebugPointAtFor get_forDebugPoint() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr doBody +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr get_doBody() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr get_identBody() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr get_toBody() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr identBody +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Syntax.SynExpr toBody +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+For: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ForEach: Boolean get_isFromSource() +FSharp.Compiler.Syntax.SynExpr+ForEach: Boolean isFromSource +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.DebugPointAtFor forDebugPoint +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.DebugPointAtFor get_forDebugPoint() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SeqExprOnly get_seqExprOnly() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SeqExprOnly seqExprOnly +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynExpr bodyExpr +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynExpr enumExpr +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynExpr get_bodyExpr() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynExpr get_enumExpr() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ForEach: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+FromParseError: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+FromParseError: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+FromParseError: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+FromParseError: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Ident: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynExpr+Ident: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Boolean get_isElif() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Boolean get_isFromErrorRecovery() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Boolean isElif +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Boolean isFromErrorRecovery +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.DebugPointAtBinding get_spIfToThen() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.DebugPointAtBinding spIfToThen +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.SynExpr get_ifExpr() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.SynExpr get_thenExpr() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.SynExpr ifExpr +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Syntax.SynExpr thenExpr +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range get_ifKeyword() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range get_ifToThenRange() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range get_thenKeyword() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range ifKeyword +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range ifToThenRange +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+IfThenElse: FSharp.Compiler.Text.Range thenKeyword +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] elseExpr +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] get_elseExpr() +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] elseKeyword +FSharp.Compiler.Syntax.SynExpr+IfThenElse: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_elseKeyword() +FSharp.Compiler.Syntax.SynExpr+ImplicitZero: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ImplicitZero: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+IndexFromEnd: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+IndexFromEnd: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+IndexFromEnd: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+IndexFromEnd: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range get_opm() +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range get_range1() +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range get_range2() +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range opm +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range range1 +FSharp.Compiler.Syntax.SynExpr+IndexRange: FSharp.Compiler.Text.Range range2 +FSharp.Compiler.Syntax.SynExpr+IndexRange: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] expr1 +FSharp.Compiler.Syntax.SynExpr+IndexRange: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] expr2 +FSharp.Compiler.Syntax.SynExpr+IndexRange: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] get_expr1() +FSharp.Compiler.Syntax.SynExpr+IndexRange: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] get_expr2() +FSharp.Compiler.Syntax.SynExpr+InferredDowncast: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+InferredDowncast: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+InferredDowncast: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+InferredDowncast: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+InferredUpcast: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+InferredUpcast: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+InferredUpcast: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+InferredUpcast: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: FSharp.Compiler.Syntax.SynStringKind get_synStringKind() +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: FSharp.Compiler.Syntax.SynStringKind synStringKind +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterpolatedStringPart] contents +FSharp.Compiler.Syntax.SynExpr+InterpolatedString: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterpolatedStringPart] get_contents() +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Syntax.SynExpr get_lhsExpr() +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Syntax.SynExpr lhsExpr +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Syntax.SynExpr rhsExpr +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Text.Range get_lhsRange() +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Text.Range lhsRange +FSharp.Compiler.Syntax.SynExpr+JoinIn: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Lambda: Boolean fromMethod +FSharp.Compiler.Syntax.SynExpr+Lambda: Boolean get_fromMethod() +FSharp.Compiler.Syntax.SynExpr+Lambda: Boolean get_inLambdaSeq() +FSharp.Compiler.Syntax.SynExpr+Lambda: Boolean inLambdaSeq +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Syntax.SynExpr body +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Syntax.SynExpr get_body() +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Syntax.SynSimplePats args +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Syntax.SynSimplePats get_args() +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Lambda: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Lambda: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] arrow +FSharp.Compiler.Syntax.SynExpr+Lambda: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_arrow() +FSharp.Compiler.Syntax.SynExpr+Lambda: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat],FSharp.Compiler.Syntax.SynExpr]] get_parsedData() +FSharp.Compiler.Syntax.SynExpr+Lambda: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat],FSharp.Compiler.Syntax.SynExpr]] parsedData +FSharp.Compiler.Syntax.SynExpr+Lazy: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Lazy: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Lazy: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Lazy: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Boolean get_isUse() +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Boolean isRecursive +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Boolean isUse +FSharp.Compiler.Syntax.SynExpr+LetOrUse: FSharp.Compiler.Syntax.SynExpr body +FSharp.Compiler.Syntax.SynExpr+LetOrUse: FSharp.Compiler.Syntax.SynExpr get_body() +FSharp.Compiler.Syntax.SynExpr+LetOrUse: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LetOrUse: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.Syntax.SynExpr+LetOrUse: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Boolean get_isFromSource() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Boolean get_isUse() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Boolean isFromSource +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Boolean isUse +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.DebugPointAtBinding bindDebugPoint +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.DebugPointAtBinding get_bindDebugPoint() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynExpr body +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynExpr get_body() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynExpr get_rhs() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynExpr rhs +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`6[FSharp.Compiler.Syntax.DebugPointAtBinding,System.Boolean,System.Boolean,FSharp.Compiler.Syntax.SynPat,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range]] andBangs +FSharp.Compiler.Syntax.SynExpr+LetOrUseBang: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`6[FSharp.Compiler.Syntax.DebugPointAtBinding,System.Boolean,System.Boolean,FSharp.Compiler.Syntax.SynPat,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range]] get_andBangs() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] args +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] get_args() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_retTy() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] retTy +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: System.Object get_ilCode() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly: System.Object ilCode +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Syntax.SynExpr get_optimizedExpr() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Syntax.SynExpr optimizedExpr +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynStaticOptimizationConstraint] constraints +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynStaticOptimizationConstraint] get_constraints() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: Int32 fieldNum +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: Int32 get_fieldNum() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Syntax.SynExpr rhsExpr +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: Int32 fieldNum +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: Int32 get_fieldNum() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynExpr+LongIdent: Boolean get_isOptional() +FSharp.Compiler.Syntax.SynExpr+LongIdent: Boolean isOptional +FSharp.Compiler.Syntax.SynExpr+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+LongIdent: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LongIdent: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]] altNameRefCell +FSharp.Compiler.Syntax.SynExpr+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]] get_altNameRefCell() +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+LongIdentSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Syntax.DebugPointAtBinding get_matchDebugPoint() +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Syntax.DebugPointAtBinding matchDebugPoint +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Match: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Match: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] clauses +FSharp.Compiler.Syntax.SynExpr+Match: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] get_clauses() +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Syntax.DebugPointAtBinding get_matchDebugPoint() +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Syntax.DebugPointAtBinding matchDebugPoint +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+MatchBang: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+MatchBang: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] clauses +FSharp.Compiler.Syntax.SynExpr+MatchBang: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] get_clauses() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: Boolean get_isExnMatch() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: Boolean isExnMatch +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Syntax.DebugPointAtBinding get_matchDebugPoint() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Syntax.DebugPointAtBinding matchDebugPoint +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Text.Range get_keywordRange() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Text.Range keywordRange +FSharp.Compiler.Syntax.SynExpr+MatchLambda: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+MatchLambda: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] get_matchClauses() +FSharp.Compiler.Syntax.SynExpr+MatchLambda: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] matchClauses +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr expr1 +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr expr2 +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_expr1() +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_expr2() +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+New: Boolean get_isProtected() +FSharp.Compiler.Syntax.SynExpr+New: Boolean isProtected +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+New: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Null: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Null: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Syntax.SynType get_objType() +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Syntax.SynType objType +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Text.Range get_newExprRange() +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Text.Range newExprRange +FSharp.Compiler.Syntax.SynExpr+ObjExpr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterfaceImpl] extraImpls +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterfaceImpl] get_extraImpls() +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] argOptions +FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] get_argOptions() +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Text.Range get_leftParenRange() +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Text.Range leftParenRange +FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Paren: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_rightParenRange() +FSharp.Compiler.Syntax.SynExpr+Paren: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] rightParenRange +FSharp.Compiler.Syntax.SynExpr+Quote: Boolean get_isFromQueryExpression() +FSharp.Compiler.Syntax.SynExpr+Quote: Boolean get_isRaw() +FSharp.Compiler.Syntax.SynExpr+Quote: Boolean isFromQueryExpression +FSharp.Compiler.Syntax.SynExpr+Quote: Boolean isRaw +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Syntax.SynExpr get_operator() +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Syntax.SynExpr get_quotedExpr() +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Syntax.SynExpr operator +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Syntax.SynExpr quotedExpr +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Quote: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Record: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Record: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[System.Tuple`2[FSharp.Compiler.Syntax.LongIdentWithDots,System.Boolean],Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]]] get_recordFields() +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[System.Tuple`2[FSharp.Compiler.Syntax.LongIdentWithDots,System.Boolean],Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]]] recordFields +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]] copyInfo +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]] get_copyInfo() +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]],FSharp.Compiler.Text.Range]] baseInfo +FSharp.Compiler.Syntax.SynExpr+Record: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]],FSharp.Compiler.Text.Range]] get_baseInfo() +FSharp.Compiler.Syntax.SynExpr+Sequential: Boolean get_isTrueSeq() +FSharp.Compiler.Syntax.SynExpr+Sequential: Boolean isTrueSeq +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.DebugPointAtSequential debugPoint +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.DebugPointAtSequential get_debugPoint() +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.SynExpr expr1 +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.SynExpr expr2 +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.SynExpr get_expr1() +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Syntax.SynExpr get_expr2() +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Sequential: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.DebugPointAtSequential debugPoint +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.DebugPointAtSequential get_debugPoint() +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr expr1 +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr expr2 +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr get_expr1() +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr get_expr2() +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr get_ifNotStmt() +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Syntax.SynExpr ifNotStmt +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Syntax.SynExpr get_targetExpr() +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Syntax.SynExpr rhsExpr +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Syntax.SynExpr targetExpr +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Set: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 AddressOf +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 AnonRecd +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 App +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ArbitraryAfterError +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ArrayOrList +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ArrayOrListComputed +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Assert +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ComputationExpr +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Const +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DiscardAfterMissingQualificationAfterDot +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Do +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DoBang +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotGet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedGet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotNamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Downcast +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Fixed +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 For +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ForEach +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 FromParseError +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Ident +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 IfThenElse +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ImplicitZero +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 IndexFromEnd +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 IndexRange +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 InferredDowncast +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 InferredUpcast +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 InterpolatedString +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 JoinIn +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Lambda +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Lazy +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LetOrUse +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LetOrUseBang +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LibraryOnlyStaticOptimization +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LibraryOnlyUnionCaseFieldGet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LibraryOnlyUnionCaseFieldSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LongIdent +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 LongIdentSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Match +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 MatchBang +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 MatchLambda +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 NamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 New +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Null +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ObjExpr +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Paren +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Quote +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Record +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Sequential +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 SequentialOrImplicitYield +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Set +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TraitCall +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TryFinally +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TryWith +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Tuple +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeApp +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeTest +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Typed +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Upcast +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 While +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 YieldOrReturn +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 YieldOrReturnFrom +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Syntax.SynExpr argExpr +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Syntax.SynExpr get_argExpr() +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Syntax.SynMemberSig get_traitSig() +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Syntax.SynMemberSig traitSig +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+TraitCall: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+TraitCall: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypar] get_supportTys() +FSharp.Compiler.Syntax.SynExpr+TraitCall: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypar] supportTys +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.DebugPointAtFinally finallyDebugPoint +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.DebugPointAtFinally get_finallyDebugPoint() +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.DebugPointAtTry get_tryDebugPoint() +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.DebugPointAtTry tryDebugPoint +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.SynExpr finallyExpr +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.SynExpr get_finallyExpr() +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.SynExpr get_tryExpr() +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Syntax.SynExpr tryExpr +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+TryFinally: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.DebugPointAtTry get_tryDebugPoint() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.DebugPointAtTry tryDebugPoint +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.DebugPointAtWith get_withDebugPoint() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.DebugPointAtWith withDebugPoint +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.SynExpr get_tryExpr() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Syntax.SynExpr tryExpr +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range get_tryRange() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range get_withRange() +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range tryRange +FSharp.Compiler.Syntax.SynExpr+TryWith: FSharp.Compiler.Text.Range withRange +FSharp.Compiler.Syntax.SynExpr+TryWith: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] get_withCases() +FSharp.Compiler.Syntax.SynExpr+TryWith: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause] withCases +FSharp.Compiler.Syntax.SynExpr+Tuple: Boolean get_isStruct() +FSharp.Compiler.Syntax.SynExpr+Tuple: Boolean isStruct +FSharp.Compiler.Syntax.SynExpr+Tuple: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Tuple: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] exprs +FSharp.Compiler.Syntax.SynExpr+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr] get_exprs() +FSharp.Compiler.Syntax.SynExpr+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] commaRanges +FSharp.Compiler.Syntax.SynExpr+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_commaRanges() +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range get_lessRange() +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range get_typeArgsRange() +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range lessRange +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+TypeApp: FSharp.Compiler.Text.Range typeArgsRange +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] commaRanges +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_commaRanges() +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_greaterRange() +FSharp.Compiler.Syntax.SynExpr+TypeApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] greaterRange +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+TypeTest: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.DebugPointAtWhile get_whileDebugPoint() +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.DebugPointAtWhile whileDebugPoint +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.SynExpr doExpr +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.SynExpr get_doExpr() +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.SynExpr get_whileExpr() +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Syntax.SynExpr whileExpr +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+While: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: System.Tuple`2[System.Boolean,System.Boolean] flags +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: System.Tuple`2[System.Boolean,System.Boolean] get_flags() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: System.Tuple`2[System.Boolean,System.Boolean] flags +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: System.Tuple`2[System.Boolean,System.Boolean] get_flags() +FSharp.Compiler.Syntax.SynExpr: Boolean IsAddressOf +FSharp.Compiler.Syntax.SynExpr: Boolean IsAnonRecd +FSharp.Compiler.Syntax.SynExpr: Boolean IsApp +FSharp.Compiler.Syntax.SynExpr: Boolean IsArbExprAndThusAlreadyReportedError +FSharp.Compiler.Syntax.SynExpr: Boolean IsArbitraryAfterError +FSharp.Compiler.Syntax.SynExpr: Boolean IsArrayOrList +FSharp.Compiler.Syntax.SynExpr: Boolean IsArrayOrListComputed +FSharp.Compiler.Syntax.SynExpr: Boolean IsAssert +FSharp.Compiler.Syntax.SynExpr: Boolean IsComputationExpr +FSharp.Compiler.Syntax.SynExpr: Boolean IsConst +FSharp.Compiler.Syntax.SynExpr: Boolean IsDiscardAfterMissingQualificationAfterDot +FSharp.Compiler.Syntax.SynExpr: Boolean IsDo +FSharp.Compiler.Syntax.SynExpr: Boolean IsDoBang +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotGet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedGet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotNamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDowncast +FSharp.Compiler.Syntax.SynExpr: Boolean IsFixed +FSharp.Compiler.Syntax.SynExpr: Boolean IsFor +FSharp.Compiler.Syntax.SynExpr: Boolean IsForEach +FSharp.Compiler.Syntax.SynExpr: Boolean IsFromParseError +FSharp.Compiler.Syntax.SynExpr: Boolean IsIdent +FSharp.Compiler.Syntax.SynExpr: Boolean IsIfThenElse +FSharp.Compiler.Syntax.SynExpr: Boolean IsImplicitZero +FSharp.Compiler.Syntax.SynExpr: Boolean IsIndexFromEnd +FSharp.Compiler.Syntax.SynExpr: Boolean IsIndexRange +FSharp.Compiler.Syntax.SynExpr: Boolean IsInferredDowncast +FSharp.Compiler.Syntax.SynExpr: Boolean IsInferredUpcast +FSharp.Compiler.Syntax.SynExpr: Boolean IsInterpolatedString +FSharp.Compiler.Syntax.SynExpr: Boolean IsJoinIn +FSharp.Compiler.Syntax.SynExpr: Boolean IsLambda +FSharp.Compiler.Syntax.SynExpr: Boolean IsLazy +FSharp.Compiler.Syntax.SynExpr: Boolean IsLetOrUse +FSharp.Compiler.Syntax.SynExpr: Boolean IsLetOrUseBang +FSharp.Compiler.Syntax.SynExpr: Boolean IsLibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynExpr: Boolean IsLibraryOnlyStaticOptimization +FSharp.Compiler.Syntax.SynExpr: Boolean IsLibraryOnlyUnionCaseFieldGet +FSharp.Compiler.Syntax.SynExpr: Boolean IsLibraryOnlyUnionCaseFieldSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsLongIdent +FSharp.Compiler.Syntax.SynExpr: Boolean IsLongIdentSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsMatch +FSharp.Compiler.Syntax.SynExpr: Boolean IsMatchBang +FSharp.Compiler.Syntax.SynExpr: Boolean IsMatchLambda +FSharp.Compiler.Syntax.SynExpr: Boolean IsNamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr: Boolean IsNew +FSharp.Compiler.Syntax.SynExpr: Boolean IsNull +FSharp.Compiler.Syntax.SynExpr: Boolean IsObjExpr +FSharp.Compiler.Syntax.SynExpr: Boolean IsParen +FSharp.Compiler.Syntax.SynExpr: Boolean IsQuote +FSharp.Compiler.Syntax.SynExpr: Boolean IsRecord +FSharp.Compiler.Syntax.SynExpr: Boolean IsSequential +FSharp.Compiler.Syntax.SynExpr: Boolean IsSequentialOrImplicitYield +FSharp.Compiler.Syntax.SynExpr: Boolean IsSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsTraitCall +FSharp.Compiler.Syntax.SynExpr: Boolean IsTryFinally +FSharp.Compiler.Syntax.SynExpr: Boolean IsTryWith +FSharp.Compiler.Syntax.SynExpr: Boolean IsTuple +FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeApp +FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeTest +FSharp.Compiler.Syntax.SynExpr: Boolean IsTyped +FSharp.Compiler.Syntax.SynExpr: Boolean IsUpcast +FSharp.Compiler.Syntax.SynExpr: Boolean IsWhile +FSharp.Compiler.Syntax.SynExpr: Boolean IsYieldOrReturn +FSharp.Compiler.Syntax.SynExpr: Boolean IsYieldOrReturnFrom +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsAddressOf() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsAnonRecd() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsApp() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsArbExprAndThusAlreadyReportedError() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsArbitraryAfterError() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsArrayOrList() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsArrayOrListComputed() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsAssert() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsComputationExpr() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsConst() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDiscardAfterMissingQualificationAfterDot() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDo() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDoBang() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotGet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedGet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotNamedIndexedPropertySet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDowncast() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsFixed() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsFor() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsForEach() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsFromParseError() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsIdent() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsIfThenElse() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsImplicitZero() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsIndexFromEnd() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsIndexRange() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsInferredDowncast() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsInferredUpcast() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsInterpolatedString() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsJoinIn() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLambda() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLazy() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLetOrUse() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLetOrUseBang() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLibraryOnlyILAssembly() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLibraryOnlyStaticOptimization() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLibraryOnlyUnionCaseFieldGet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLibraryOnlyUnionCaseFieldSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLongIdent() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsLongIdentSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsMatch() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsMatchBang() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsMatchLambda() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNamedIndexedPropertySet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNew() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNull() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsObjExpr() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsParen() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsQuote() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsRecord() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsSequential() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsSequentialOrImplicitYield() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTraitCall() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTryFinally() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTryWith() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTuple() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeApp() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeTest() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTyped() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsUpcast() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsWhile() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsYieldOrReturn() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsYieldOrReturnFrom() +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewAddressOf(Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewAnonRecd(Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]], Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynExpr]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewApp(FSharp.Compiler.Syntax.ExprAtomicFlag, Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewArbitraryAfterError(System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewArrayOrList(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewArrayOrListComputed(Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewAssert(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewComputationExpr(Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewConst(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDiscardAfterMissingQualificationAfterDot(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDo(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewFixed(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewFor(FSharp.Compiler.Syntax.DebugPointAtFor, FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.SynExpr, Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewForEach(FSharp.Compiler.Syntax.DebugPointAtFor, FSharp.Compiler.Syntax.SeqExprOnly, Boolean, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewFromParseError(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewIdent(FSharp.Compiler.Syntax.Ident) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewIfThenElse(FSharp.Compiler.Text.Range, Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Syntax.DebugPointAtBinding, Boolean, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewImplicitZero(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewIndexFromEnd(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewIndexRange(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewInferredDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewInferredUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewInterpolatedString(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterpolatedStringPart], FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewJoinIn(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLambda(Boolean, Boolean, FSharp.Compiler.Syntax.SynSimplePats, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat],FSharp.Compiler.Syntax.SynExpr]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLazy(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLetOrUse(Boolean, Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLetOrUseBang(FSharp.Compiler.Syntax.DebugPointAtBinding, Boolean, Boolean, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`6[FSharp.Compiler.Syntax.DebugPointAtBinding,System.Boolean,System.Boolean,FSharp.Compiler.Syntax.SynPat,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range]], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLibraryOnlyILAssembly(System.Object, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLibraryOnlyStaticOptimization(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynStaticOptimizationConstraint], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLibraryOnlyUnionCaseFieldGet(FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Int32, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLibraryOnlyUnionCaseFieldSet(FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Int32, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLongIdent(Boolean, FSharp.Compiler.Syntax.LongIdentWithDots, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewLongIdentSet(FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewMatch(FSharp.Compiler.Syntax.DebugPointAtBinding, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewMatchBang(FSharp.Compiler.Syntax.DebugPointAtBinding, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewMatchLambda(Boolean, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause], FSharp.Compiler.Syntax.DebugPointAtBinding, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNamedIndexedPropertySet(FSharp.Compiler.Syntax.LongIdentWithDots, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNew(Boolean, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNull(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewObjExpr(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterfaceImpl], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewParen(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewQuote(FSharp.Compiler.Syntax.SynExpr, Boolean, FSharp.Compiler.Syntax.SynExpr, Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewRecord(Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]],FSharp.Compiler.Text.Range]], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]], Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[System.Tuple`2[FSharp.Compiler.Syntax.LongIdentWithDots,System.Boolean],Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr],Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewSequential(FSharp.Compiler.Syntax.DebugPointAtSequential, Boolean, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewSequentialOrImplicitYield(FSharp.Compiler.Syntax.DebugPointAtSequential, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTraitCall(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypar], FSharp.Compiler.Syntax.SynMemberSig, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTryFinally(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.DebugPointAtTry, FSharp.Compiler.Syntax.DebugPointAtFinally) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTryWith(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMatchClause], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.DebugPointAtTry, FSharp.Compiler.Syntax.DebugPointAtWith) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTuple(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeApp(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeTest(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AddressOf +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AnonRecd +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+App +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ArbitraryAfterError +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ArrayOrList +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ArrayOrListComputed +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Assert +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ComputationExpr +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Const +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DiscardAfterMissingQualificationAfterDot +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Do +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DoBang +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotGet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedGet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Downcast +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Fixed +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+For +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ForEach +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+FromParseError +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Ident +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+IfThenElse +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ImplicitZero +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+IndexFromEnd +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+IndexRange +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+InferredDowncast +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+InferredUpcast +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+InterpolatedString +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+JoinIn +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Lambda +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Lazy +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LetOrUse +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LetOrUseBang +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LibraryOnlyStaticOptimization +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldGet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LibraryOnlyUnionCaseFieldSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LongIdent +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+LongIdentSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Match +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+MatchBang +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+MatchLambda +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+NamedIndexedPropertySet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+New +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Null +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ObjExpr +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Paren +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Quote +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Record +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Sequential +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+SequentialOrImplicitYield +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Set +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Tags +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TraitCall +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TryFinally +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TryWith +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Tuple +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeApp +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeTest +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Typed +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Upcast +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+While +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+YieldOrReturn +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range RangeOfFirstPortion +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range RangeWithoutAnyExtraDot +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range get_RangeOfFirstPortion() +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Text.Range get_RangeWithoutAnyExtraDot() +FSharp.Compiler.Syntax.SynExpr: Int32 Tag +FSharp.Compiler.Syntax.SynExpr: Int32 get_Tag() +FSharp.Compiler.Syntax.SynExpr: System.String ToString() +FSharp.Compiler.Syntax.SynField +FSharp.Compiler.Syntax.SynField: Boolean get_isMutable() +FSharp.Compiler.Syntax.SynField: Boolean get_isStatic() +FSharp.Compiler.Syntax.SynField: Boolean isMutable +FSharp.Compiler.Syntax.SynField: Boolean isStatic +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Syntax.SynField NewSynField(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Syntax.SynType, Boolean, FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Syntax.SynType fieldType +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Syntax.SynType get_fieldType() +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynField: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynField: Int32 Tag +FSharp.Compiler.Syntax.SynField: Int32 get_Tag() +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_idOpt() +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] idOpt +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynField: System.String ToString() +FSharp.Compiler.Syntax.SynInterfaceImpl +FSharp.Compiler.Syntax.SynInterfaceImpl: FSharp.Compiler.Syntax.SynInterfaceImpl NewSynInterfaceImpl(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynInterfaceImpl: FSharp.Compiler.Syntax.SynType get_interfaceTy() +FSharp.Compiler.Syntax.SynInterfaceImpl: FSharp.Compiler.Syntax.SynType interfaceTy +FSharp.Compiler.Syntax.SynInterfaceImpl: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynInterfaceImpl: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynInterfaceImpl: Int32 Tag +FSharp.Compiler.Syntax.SynInterfaceImpl: Int32 get_Tag() +FSharp.Compiler.Syntax.SynInterfaceImpl: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.Syntax.SynInterfaceImpl: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.Syntax.SynInterfaceImpl: System.String ToString() +FSharp.Compiler.Syntax.SynInterpolatedStringPart +FSharp.Compiler.Syntax.SynInterpolatedStringPart+FillExpr: FSharp.Compiler.Syntax.SynExpr fillExpr +FSharp.Compiler.Syntax.SynInterpolatedStringPart+FillExpr: FSharp.Compiler.Syntax.SynExpr get_fillExpr() +FSharp.Compiler.Syntax.SynInterpolatedStringPart+FillExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_qualifiers() +FSharp.Compiler.Syntax.SynInterpolatedStringPart+FillExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] qualifiers +FSharp.Compiler.Syntax.SynInterpolatedStringPart+String: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynInterpolatedStringPart+String: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynInterpolatedStringPart+String: System.String get_value() +FSharp.Compiler.Syntax.SynInterpolatedStringPart+String: System.String value +FSharp.Compiler.Syntax.SynInterpolatedStringPart+Tags: Int32 FillExpr +FSharp.Compiler.Syntax.SynInterpolatedStringPart+Tags: Int32 String +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Boolean IsFillExpr +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Boolean IsString +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Boolean get_IsFillExpr() +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Boolean get_IsString() +FSharp.Compiler.Syntax.SynInterpolatedStringPart: FSharp.Compiler.Syntax.SynInterpolatedStringPart NewFillExpr(FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]) +FSharp.Compiler.Syntax.SynInterpolatedStringPart: FSharp.Compiler.Syntax.SynInterpolatedStringPart NewString(System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynInterpolatedStringPart: FSharp.Compiler.Syntax.SynInterpolatedStringPart+FillExpr +FSharp.Compiler.Syntax.SynInterpolatedStringPart: FSharp.Compiler.Syntax.SynInterpolatedStringPart+String +FSharp.Compiler.Syntax.SynInterpolatedStringPart: FSharp.Compiler.Syntax.SynInterpolatedStringPart+Tags +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Int32 Tag +FSharp.Compiler.Syntax.SynInterpolatedStringPart: Int32 get_Tag() +FSharp.Compiler.Syntax.SynInterpolatedStringPart: System.String ToString() +FSharp.Compiler.Syntax.SynMatchClause +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.DebugPointAtTarget debugPoint +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.DebugPointAtTarget get_debugPoint() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.SynExpr get_resultExpr() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.SynExpr resultExpr +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.SynMatchClause NewSynMatchClause(FSharp.Compiler.Syntax.SynPat, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.DebugPointAtTarget) +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range RangeOfGuardAndRhs +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range get_RangeOfGuardAndRhs() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMatchClause: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMatchClause: Int32 Tag +FSharp.Compiler.Syntax.SynMatchClause: Int32 get_Tag() +FSharp.Compiler.Syntax.SynMatchClause: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] get_whenExpr() +FSharp.Compiler.Syntax.SynMatchClause: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] whenExpr +FSharp.Compiler.Syntax.SynMatchClause: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] arrow +FSharp.Compiler.Syntax.SynMatchClause: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_arrow() +FSharp.Compiler.Syntax.SynMatchClause: System.String ToString() +FSharp.Compiler.Syntax.SynMeasure +FSharp.Compiler.Syntax.SynMeasure+Anon: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Anon: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Syntax.SynMeasure get_measure1() +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Syntax.SynMeasure get_measure2() +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Syntax.SynMeasure measure1 +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Syntax.SynMeasure measure2 +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Divide: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Named: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Named: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Named: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynMeasure+Named: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Syntax.SynMeasure get_measure() +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Syntax.SynMeasure measure +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Syntax.SynRationalConst get_power() +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Syntax.SynRationalConst power +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Power: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Syntax.SynMeasure get_measure1() +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Syntax.SynMeasure get_measure2() +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Syntax.SynMeasure measure1 +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Syntax.SynMeasure measure2 +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Product: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Seq: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Seq: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure+Seq: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMeasure] get_measures() +FSharp.Compiler.Syntax.SynMeasure+Seq: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMeasure] measures +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Anon +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Divide +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Named +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 One +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Power +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Product +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Seq +FSharp.Compiler.Syntax.SynMeasure+Tags: Int32 Var +FSharp.Compiler.Syntax.SynMeasure+Var: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynMeasure+Var: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynMeasure+Var: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMeasure+Var: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMeasure: Boolean IsAnon +FSharp.Compiler.Syntax.SynMeasure: Boolean IsDivide +FSharp.Compiler.Syntax.SynMeasure: Boolean IsNamed +FSharp.Compiler.Syntax.SynMeasure: Boolean IsOne +FSharp.Compiler.Syntax.SynMeasure: Boolean IsPower +FSharp.Compiler.Syntax.SynMeasure: Boolean IsProduct +FSharp.Compiler.Syntax.SynMeasure: Boolean IsSeq +FSharp.Compiler.Syntax.SynMeasure: Boolean IsVar +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsAnon() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsDivide() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsNamed() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsOne() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsPower() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsProduct() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsSeq() +FSharp.Compiler.Syntax.SynMeasure: Boolean get_IsVar() +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewAnon(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewDivide(FSharp.Compiler.Syntax.SynMeasure, FSharp.Compiler.Syntax.SynMeasure, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewNamed(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewPower(FSharp.Compiler.Syntax.SynMeasure, FSharp.Compiler.Syntax.SynRationalConst, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewProduct(FSharp.Compiler.Syntax.SynMeasure, FSharp.Compiler.Syntax.SynMeasure, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewSeq(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMeasure], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure NewVar(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure One +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure get_One() +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Anon +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Divide +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Named +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Power +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Product +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Seq +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Tags +FSharp.Compiler.Syntax.SynMeasure: FSharp.Compiler.Syntax.SynMeasure+Var +FSharp.Compiler.Syntax.SynMeasure: Int32 Tag +FSharp.Compiler.Syntax.SynMeasure: Int32 get_Tag() +FSharp.Compiler.Syntax.SynMeasure: System.String ToString() +FSharp.Compiler.Syntax.SynMemberDefn +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Syntax.SynMemberFlags flags +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Syntax.SynMemberFlags get_flags() +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Syntax.SynValSig get_slotSig() +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Syntax.SynValSig slotSig +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Boolean get_isStatic() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Boolean isStatic +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.SynExpr get_synExpr() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.SynExpr synExpr +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.SynMemberKind get_propKind() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Syntax.SynMemberKind propKind +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynMemberKind,FSharp.Compiler.Syntax.SynMemberFlags] get_memberFlags() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynMemberKind,FSharp.Compiler.Syntax.SynMemberFlags] memberFlags +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynType] get_typeOpt() +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynType] typeOpt +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] getSetRange +FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_getSetRange() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Syntax.SynSimplePats ctorArgs +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Syntax.SynSimplePats get_ctorArgs() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_selfIdentifier() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] selfIdentifier +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Syntax.SynExpr get_inheritArgs() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Syntax.SynExpr inheritArgs +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Syntax.SynType get_inheritType() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Syntax.SynType inheritType +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_inheritAlias() +FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] inheritAlias +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: FSharp.Compiler.Syntax.SynType baseType +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: FSharp.Compiler.Syntax.SynType get_baseType() +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] asIdent +FSharp.Compiler.Syntax.SynMemberDefn+Inherit: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_asIdent() +FSharp.Compiler.Syntax.SynMemberDefn+Interface: FSharp.Compiler.Syntax.SynType get_interfaceType() +FSharp.Compiler.Syntax.SynMemberDefn+Interface: FSharp.Compiler.Syntax.SynType interfaceType +FSharp.Compiler.Syntax.SynMemberDefn+Interface: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+Interface: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+Interface: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]] get_members() +FSharp.Compiler.Syntax.SynMemberDefn+Interface: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]] members +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Boolean get_isStatic() +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Boolean isRecursive +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Boolean isStatic +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.Syntax.SynMemberDefn+LetBindings: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.Syntax.SynMemberDefn+Member: FSharp.Compiler.Syntax.SynBinding get_memberDefn() +FSharp.Compiler.Syntax.SynMemberDefn+Member: FSharp.Compiler.Syntax.SynBinding memberDefn +FSharp.Compiler.Syntax.SynMemberDefn+Member: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+Member: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: FSharp.Compiler.Syntax.SynTypeDefn get_typeDefn() +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: FSharp.Compiler.Syntax.SynTypeDefn typeDefn +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynMemberDefn+NestedType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynMemberDefn+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget get_target() +FSharp.Compiler.Syntax.SynMemberDefn+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget target +FSharp.Compiler.Syntax.SynMemberDefn+Open: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+Open: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 AbstractSlot +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 AutoProperty +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 ImplicitCtor +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 ImplicitInherit +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 Inherit +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 Interface +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 LetBindings +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 Member +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 NestedType +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 Open +FSharp.Compiler.Syntax.SynMemberDefn+Tags: Int32 ValField +FSharp.Compiler.Syntax.SynMemberDefn+ValField: FSharp.Compiler.Syntax.SynField fieldInfo +FSharp.Compiler.Syntax.SynMemberDefn+ValField: FSharp.Compiler.Syntax.SynField get_fieldInfo() +FSharp.Compiler.Syntax.SynMemberDefn+ValField: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberDefn+ValField: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsAbstractSlot +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsAutoProperty +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsImplicitCtor +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsImplicitInherit +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsInherit +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsInterface +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsLetBindings +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsMember +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsNestedType +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsOpen +FSharp.Compiler.Syntax.SynMemberDefn: Boolean IsValField +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsAbstractSlot() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsAutoProperty() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsImplicitCtor() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsImplicitInherit() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsInherit() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsInterface() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsLetBindings() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsMember() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsNestedType() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsOpen() +FSharp.Compiler.Syntax.SynMemberDefn: Boolean get_IsValField() +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewAbstractSlot(FSharp.Compiler.Syntax.SynValSig, FSharp.Compiler.Syntax.SynMemberFlags, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewAutoProperty(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynType], FSharp.Compiler.Syntax.SynMemberKind, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynMemberKind,FSharp.Compiler.Syntax.SynMemberFlags], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewImplicitCtor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.SynSimplePats, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Xml.PreXmlDoc, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewImplicitInherit(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynExpr, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewInherit(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewInterface(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewLetBindings(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], Boolean, Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewMember(FSharp.Compiler.Syntax.SynBinding, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewNestedType(FSharp.Compiler.Syntax.SynTypeDefn, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewOpen(FSharp.Compiler.Syntax.SynOpenDeclTarget, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn NewValField(FSharp.Compiler.Syntax.SynField, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+AbstractSlot +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+AutoProperty +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+ImplicitCtor +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+ImplicitInherit +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+Inherit +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+Interface +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+LetBindings +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+Member +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+NestedType +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+Open +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+Tags +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn+ValField +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynMemberDefn: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynMemberDefn: Int32 Tag +FSharp.Compiler.Syntax.SynMemberDefn: Int32 get_Tag() +FSharp.Compiler.Syntax.SynMemberDefn: System.String ToString() +FSharp.Compiler.Syntax.SynMemberFlags +FSharp.Compiler.Syntax.SynMemberFlags: Boolean Equals(FSharp.Compiler.Syntax.SynMemberFlags) +FSharp.Compiler.Syntax.SynMemberFlags: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynMemberFlags: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynMemberFlags: Boolean IsDispatchSlot +FSharp.Compiler.Syntax.SynMemberFlags: Boolean IsFinal +FSharp.Compiler.Syntax.SynMemberFlags: Boolean IsInstance +FSharp.Compiler.Syntax.SynMemberFlags: Boolean IsOverrideOrExplicitImpl +FSharp.Compiler.Syntax.SynMemberFlags: Boolean get_IsDispatchSlot() +FSharp.Compiler.Syntax.SynMemberFlags: Boolean get_IsFinal() +FSharp.Compiler.Syntax.SynMemberFlags: Boolean get_IsInstance() +FSharp.Compiler.Syntax.SynMemberFlags: Boolean get_IsOverrideOrExplicitImpl() +FSharp.Compiler.Syntax.SynMemberFlags: FSharp.Compiler.Syntax.SynMemberKind MemberKind +FSharp.Compiler.Syntax.SynMemberFlags: FSharp.Compiler.Syntax.SynMemberKind get_MemberKind() +FSharp.Compiler.Syntax.SynMemberFlags: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynMemberFlags: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynMemberFlags: System.String ToString() +FSharp.Compiler.Syntax.SynMemberFlags: Void .ctor(Boolean, Boolean, Boolean, Boolean, FSharp.Compiler.Syntax.SynMemberKind) +FSharp.Compiler.Syntax.SynMemberKind +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 ClassConstructor +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 Constructor +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 Member +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 PropertyGet +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 PropertyGetSet +FSharp.Compiler.Syntax.SynMemberKind+Tags: Int32 PropertySet +FSharp.Compiler.Syntax.SynMemberKind: Boolean Equals(FSharp.Compiler.Syntax.SynMemberKind) +FSharp.Compiler.Syntax.SynMemberKind: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynMemberKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsClassConstructor +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsConstructor +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsMember +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsPropertyGet +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsPropertyGetSet +FSharp.Compiler.Syntax.SynMemberKind: Boolean IsPropertySet +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsClassConstructor() +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsConstructor() +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsMember() +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsPropertyGet() +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsPropertyGetSet() +FSharp.Compiler.Syntax.SynMemberKind: Boolean get_IsPropertySet() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind ClassConstructor +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind Constructor +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind Member +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind PropertyGet +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind PropertyGetSet +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind PropertySet +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_ClassConstructor() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_Constructor() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_Member() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_PropertyGet() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_PropertyGetSet() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind get_PropertySet() +FSharp.Compiler.Syntax.SynMemberKind: FSharp.Compiler.Syntax.SynMemberKind+Tags +FSharp.Compiler.Syntax.SynMemberKind: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynMemberKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynMemberKind: Int32 Tag +FSharp.Compiler.Syntax.SynMemberKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynMemberKind: System.String ToString() +FSharp.Compiler.Syntax.SynMemberSig +FSharp.Compiler.Syntax.SynMemberSig+Inherit: FSharp.Compiler.Syntax.SynType get_inheritedType() +FSharp.Compiler.Syntax.SynMemberSig+Inherit: FSharp.Compiler.Syntax.SynType inheritedType +FSharp.Compiler.Syntax.SynMemberSig+Inherit: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberSig+Inherit: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberSig+Interface: FSharp.Compiler.Syntax.SynType get_interfaceType() +FSharp.Compiler.Syntax.SynMemberSig+Interface: FSharp.Compiler.Syntax.SynType interfaceType +FSharp.Compiler.Syntax.SynMemberSig+Interface: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberSig+Interface: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Syntax.SynMemberFlags flags +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Syntax.SynMemberFlags get_flags() +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Syntax.SynValSig get_memberSig() +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Syntax.SynValSig memberSig +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberSig+Member: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberSig+NestedType: FSharp.Compiler.Syntax.SynTypeDefnSig get_nestedType() +FSharp.Compiler.Syntax.SynMemberSig+NestedType: FSharp.Compiler.Syntax.SynTypeDefnSig nestedType +FSharp.Compiler.Syntax.SynMemberSig+NestedType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberSig+NestedType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberSig+Tags: Int32 Inherit +FSharp.Compiler.Syntax.SynMemberSig+Tags: Int32 Interface +FSharp.Compiler.Syntax.SynMemberSig+Tags: Int32 Member +FSharp.Compiler.Syntax.SynMemberSig+Tags: Int32 NestedType +FSharp.Compiler.Syntax.SynMemberSig+Tags: Int32 ValField +FSharp.Compiler.Syntax.SynMemberSig+ValField: FSharp.Compiler.Syntax.SynField field +FSharp.Compiler.Syntax.SynMemberSig+ValField: FSharp.Compiler.Syntax.SynField get_field() +FSharp.Compiler.Syntax.SynMemberSig+ValField: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynMemberSig+ValField: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynMemberSig: Boolean IsInherit +FSharp.Compiler.Syntax.SynMemberSig: Boolean IsInterface +FSharp.Compiler.Syntax.SynMemberSig: Boolean IsMember +FSharp.Compiler.Syntax.SynMemberSig: Boolean IsNestedType +FSharp.Compiler.Syntax.SynMemberSig: Boolean IsValField +FSharp.Compiler.Syntax.SynMemberSig: Boolean get_IsInherit() +FSharp.Compiler.Syntax.SynMemberSig: Boolean get_IsInterface() +FSharp.Compiler.Syntax.SynMemberSig: Boolean get_IsMember() +FSharp.Compiler.Syntax.SynMemberSig: Boolean get_IsNestedType() +FSharp.Compiler.Syntax.SynMemberSig: Boolean get_IsValField() +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig NewInherit(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig NewInterface(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig NewMember(FSharp.Compiler.Syntax.SynValSig, FSharp.Compiler.Syntax.SynMemberFlags, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig NewNestedType(FSharp.Compiler.Syntax.SynTypeDefnSig, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig NewValField(FSharp.Compiler.Syntax.SynField, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Inherit +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Interface +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Member +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+NestedType +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Tags +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+ValField +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynMemberSig: Int32 Tag +FSharp.Compiler.Syntax.SynMemberSig: Int32 get_Tag() +FSharp.Compiler.Syntax.SynMemberSig: System.String ToString() +FSharp.Compiler.Syntax.SynModuleDecl +FSharp.Compiler.Syntax.SynModuleDecl+Attributes: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+Attributes: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Attributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynModuleDecl+Attributes: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Syntax.DebugPointAtBinding debugPoint +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Syntax.DebugPointAtBinding get_debugPoint() +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+DoExpr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Exception: FSharp.Compiler.Syntax.SynExceptionDefn exnDefn +FSharp.Compiler.Syntax.SynModuleDecl+Exception: FSharp.Compiler.Syntax.SynExceptionDefn get_exnDefn() +FSharp.Compiler.Syntax.SynModuleDecl+Exception: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+Exception: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective get_hashDirective() +FSharp.Compiler.Syntax.SynModuleDecl+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective hashDirective +FSharp.Compiler.Syntax.SynModuleDecl+HashDirective: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+HashDirective: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Let: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynModuleDecl+Let: Boolean isRecursive +FSharp.Compiler.Syntax.SynModuleDecl+Let: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+Let: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Let: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] bindings +FSharp.Compiler.Syntax.SynModuleDecl+Let: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding] get_bindings() +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynModuleDecl+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespace fragment +FSharp.Compiler.Syntax.SynModuleDecl+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespace get_fragment() +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Boolean get_isContinuing() +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Boolean isContinuing +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Boolean isRecursive +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: FSharp.Compiler.Syntax.SynComponentInfo get_moduleInfo() +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: FSharp.Compiler.Syntax.SynComponentInfo moduleInfo +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] decls +FSharp.Compiler.Syntax.SynModuleDecl+NestedModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] get_decls() +FSharp.Compiler.Syntax.SynModuleDecl+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget get_target() +FSharp.Compiler.Syntax.SynModuleDecl+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget target +FSharp.Compiler.Syntax.SynModuleDecl+Open: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+Open: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 Attributes +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 DoExpr +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 Exception +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 HashDirective +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 Let +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 ModuleAbbrev +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 NamespaceFragment +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 NestedModule +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 Open +FSharp.Compiler.Syntax.SynModuleDecl+Tags: Int32 Types +FSharp.Compiler.Syntax.SynModuleDecl+Types: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleDecl+Types: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleDecl+Types: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefn] get_typeDefns() +FSharp.Compiler.Syntax.SynModuleDecl+Types: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefn] typeDefns +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsAttributes +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsDoExpr +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsException +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsHashDirective +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsLet +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsModuleAbbrev +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsNamespaceFragment +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsNestedModule +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsOpen +FSharp.Compiler.Syntax.SynModuleDecl: Boolean IsTypes +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsAttributes() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsDoExpr() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsException() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsHashDirective() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsLet() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsModuleAbbrev() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsNamespaceFragment() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsNestedModule() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsOpen() +FSharp.Compiler.Syntax.SynModuleDecl: Boolean get_IsTypes() +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewAttributes(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewDoExpr(FSharp.Compiler.Syntax.DebugPointAtBinding, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewException(FSharp.Compiler.Syntax.SynExceptionDefn, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewHashDirective(FSharp.Compiler.Syntax.ParsedHashDirective, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewLet(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewModuleAbbrev(FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewNamespaceFragment(FSharp.Compiler.Syntax.SynModuleOrNamespace) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewNestedModule(FSharp.Compiler.Syntax.SynComponentInfo, Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl], Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewOpen(FSharp.Compiler.Syntax.SynOpenDeclTarget, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl NewTypes(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefn], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Attributes +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+DoExpr +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Exception +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+HashDirective +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Let +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+ModuleAbbrev +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+NamespaceFragment +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+NestedModule +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Open +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Tags +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Syntax.SynModuleDecl+Types +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynModuleDecl: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynModuleDecl: Int32 Tag +FSharp.Compiler.Syntax.SynModuleDecl: Int32 get_Tag() +FSharp.Compiler.Syntax.SynModuleDecl: System.String ToString() +FSharp.Compiler.Syntax.SynModuleOrNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespace: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynModuleOrNamespace: Boolean isRecursive +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Syntax.SynModuleOrNamespace NewSynModuleOrNamespace(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Boolean, FSharp.Compiler.Syntax.SynModuleOrNamespaceKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_kind() +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind kind +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynModuleOrNamespace: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynModuleOrNamespace: Int32 Tag +FSharp.Compiler.Syntax.SynModuleOrNamespace: Int32 get_Tag() +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attribs +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attribs() +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] decls +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleDecl] get_decls() +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynModuleOrNamespace: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynModuleOrNamespace: System.String ToString() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind+Tags: Int32 AnonModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind+Tags: Int32 DeclaredNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind+Tags: Int32 GlobalNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind+Tags: Int32 NamedModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean Equals(FSharp.Compiler.Syntax.SynModuleOrNamespaceKind) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean IsAnonModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean IsDeclaredNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean IsGlobalNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean IsModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean IsNamedModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean get_IsAnonModule() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean get_IsDeclaredNamespace() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean get_IsGlobalNamespace() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean get_IsModule() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Boolean get_IsNamedModule() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind AnonModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind DeclaredNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind GlobalNamespace +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind NamedModule +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_AnonModule() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_DeclaredNamespace() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_GlobalNamespace() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_NamedModule() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind+Tags +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 CompareTo(FSharp.Compiler.Syntax.SynModuleOrNamespaceKind) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 Tag +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynModuleOrNamespaceKind: System.String ToString() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Boolean isRecursive +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind get_kind() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Syntax.SynModuleOrNamespaceKind kind +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig NewSynModuleOrNamespaceSig(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], Boolean, FSharp.Compiler.Syntax.SynModuleOrNamespaceKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl], FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Int32 Tag +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Int32 get_Tag() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attribs +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attribs() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] decls +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] get_decls() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynModuleOrNamespaceSig: System.String ToString() +FSharp.Compiler.Syntax.SynModuleSigDecl +FSharp.Compiler.Syntax.SynModuleSigDecl+Exception: FSharp.Compiler.Syntax.SynExceptionSig exnSig +FSharp.Compiler.Syntax.SynModuleSigDecl+Exception: FSharp.Compiler.Syntax.SynExceptionSig get_exnSig() +FSharp.Compiler.Syntax.SynModuleSigDecl+Exception: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+Exception: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective get_hashDirective() +FSharp.Compiler.Syntax.SynModuleSigDecl+HashDirective: FSharp.Compiler.Syntax.ParsedHashDirective hashDirective +FSharp.Compiler.Syntax.SynModuleSigDecl+HashDirective: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+HashDirective: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynModuleSigDecl+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig Item +FSharp.Compiler.Syntax.SynModuleSigDecl+NamespaceFragment: FSharp.Compiler.Syntax.SynModuleOrNamespaceSig get_Item() +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: Boolean get_isRecursive() +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: Boolean isRecursive +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: FSharp.Compiler.Syntax.SynComponentInfo get_moduleInfo() +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: FSharp.Compiler.Syntax.SynComponentInfo moduleInfo +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] get_moduleDecls() +FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl] moduleDecls +FSharp.Compiler.Syntax.SynModuleSigDecl+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget get_target() +FSharp.Compiler.Syntax.SynModuleSigDecl+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget target +FSharp.Compiler.Syntax.SynModuleSigDecl+Open: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+Open: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 Exception +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 HashDirective +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 ModuleAbbrev +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 NamespaceFragment +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 NestedModule +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 Open +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 Types +FSharp.Compiler.Syntax.SynModuleSigDecl+Tags: Int32 Val +FSharp.Compiler.Syntax.SynModuleSigDecl+Types: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+Types: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl+Types: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefnSig] get_types() +FSharp.Compiler.Syntax.SynModuleSigDecl+Types: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefnSig] types +FSharp.Compiler.Syntax.SynModuleSigDecl+Val: FSharp.Compiler.Syntax.SynValSig get_valSig() +FSharp.Compiler.Syntax.SynModuleSigDecl+Val: FSharp.Compiler.Syntax.SynValSig valSig +FSharp.Compiler.Syntax.SynModuleSigDecl+Val: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynModuleSigDecl+Val: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsException +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsHashDirective +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsModuleAbbrev +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsNamespaceFragment +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsNestedModule +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsOpen +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsTypes +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean IsVal +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsException() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsHashDirective() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsModuleAbbrev() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsNamespaceFragment() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsNestedModule() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsOpen() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsTypes() +FSharp.Compiler.Syntax.SynModuleSigDecl: Boolean get_IsVal() +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewException(FSharp.Compiler.Syntax.SynExceptionSig, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewHashDirective(FSharp.Compiler.Syntax.ParsedHashDirective, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewModuleAbbrev(FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewNamespaceFragment(FSharp.Compiler.Syntax.SynModuleOrNamespaceSig) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewNestedModule(FSharp.Compiler.Syntax.SynComponentInfo, Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynModuleSigDecl], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewOpen(FSharp.Compiler.Syntax.SynOpenDeclTarget, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewTypes(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeDefnSig], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl NewVal(FSharp.Compiler.Syntax.SynValSig, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+Exception +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+HashDirective +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+ModuleAbbrev +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+NamespaceFragment +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+NestedModule +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+Open +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+Tags +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+Types +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Syntax.SynModuleSigDecl+Val +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynModuleSigDecl: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynModuleSigDecl: Int32 Tag +FSharp.Compiler.Syntax.SynModuleSigDecl: Int32 get_Tag() +FSharp.Compiler.Syntax.SynModuleSigDecl: System.String ToString() +FSharp.Compiler.Syntax.SynOpenDeclTarget +FSharp.Compiler.Syntax.SynOpenDeclTarget+ModuleOrNamespace: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynOpenDeclTarget+ModuleOrNamespace: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynOpenDeclTarget+ModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] get_longId() +FSharp.Compiler.Syntax.SynOpenDeclTarget+ModuleOrNamespace: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident] longId +FSharp.Compiler.Syntax.SynOpenDeclTarget+Tags: Int32 ModuleOrNamespace +FSharp.Compiler.Syntax.SynOpenDeclTarget+Tags: Int32 Type +FSharp.Compiler.Syntax.SynOpenDeclTarget+Type: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynOpenDeclTarget+Type: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynOpenDeclTarget+Type: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynOpenDeclTarget+Type: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynOpenDeclTarget: Boolean IsModuleOrNamespace +FSharp.Compiler.Syntax.SynOpenDeclTarget: Boolean IsType +FSharp.Compiler.Syntax.SynOpenDeclTarget: Boolean get_IsModuleOrNamespace() +FSharp.Compiler.Syntax.SynOpenDeclTarget: Boolean get_IsType() +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Syntax.SynOpenDeclTarget NewModuleOrNamespace(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Syntax.SynOpenDeclTarget NewType(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Syntax.SynOpenDeclTarget+ModuleOrNamespace +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Syntax.SynOpenDeclTarget+Tags +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Syntax.SynOpenDeclTarget+Type +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynOpenDeclTarget: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynOpenDeclTarget: Int32 Tag +FSharp.Compiler.Syntax.SynOpenDeclTarget: Int32 get_Tag() +FSharp.Compiler.Syntax.SynOpenDeclTarget: System.String ToString() +FSharp.Compiler.Syntax.SynPat +FSharp.Compiler.Syntax.SynPat+Ands: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Ands: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Ands: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_pats() +FSharp.Compiler.Syntax.SynPat+Ands: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] pats +FSharp.Compiler.Syntax.SynPat+ArrayOrList: Boolean get_isArray() +FSharp.Compiler.Syntax.SynPat+ArrayOrList: Boolean isArray +FSharp.Compiler.Syntax.SynPat+ArrayOrList: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+ArrayOrList: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+ArrayOrList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] elementPats +FSharp.Compiler.Syntax.SynPat+ArrayOrList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_elementPats() +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Syntax.SynPat get_lhsPat() +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Syntax.SynPat get_rhsPat() +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Syntax.SynPat lhsPat +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Syntax.SynPat rhsPat +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+As: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Attrib: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynPat+Attrib: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynPat+Attrib: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Attrib: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Attrib: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynPat+Attrib: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynPat+Const: FSharp.Compiler.Syntax.SynConst constant +FSharp.Compiler.Syntax.SynPat+Const: FSharp.Compiler.Syntax.SynConst get_constant() +FSharp.Compiler.Syntax.SynPat+Const: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Const: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: Char endChar +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: Char get_endChar() +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: Char get_startChar() +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: Char startChar +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+FromParseError: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynPat+FromParseError: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynPat+FromParseError: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+FromParseError: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Syntax.Ident get_memberId() +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Syntax.Ident get_thisId() +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Syntax.Ident memberId +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Syntax.Ident thisId +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+InstanceMember: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+InstanceMember: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_toolingId() +FSharp.Compiler.Syntax.SynPat+InstanceMember: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] toolingId +FSharp.Compiler.Syntax.SynPat+InstanceMember: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynPat+InstanceMember: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Syntax.SynType get_pat() +FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Syntax.SynType pat +FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.SynArgPats argPats +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.SynArgPats get_argPats() +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] extraId +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_extraId() +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynValTyparDecls] get_typarDecls() +FSharp.Compiler.Syntax.SynPat+LongIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynValTyparDecls] typarDecls +FSharp.Compiler.Syntax.SynPat+Named: Boolean get_isThisVal() +FSharp.Compiler.Syntax.SynPat+Named: Boolean isThisVal +FSharp.Compiler.Syntax.SynPat+Named: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynPat+Named: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynPat+Named: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Named: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Named: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynPat+Named: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynPat+Null: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Null: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+OptionalVal: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynPat+OptionalVal: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynPat+OptionalVal: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+OptionalVal: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Syntax.SynPat get_lhsPat() +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Syntax.SynPat get_rhsPat() +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Syntax.SynPat lhsPat +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Syntax.SynPat rhsPat +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Or: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Paren: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynPat+Paren: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynPat+Paren: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Paren: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+QuoteExpr: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynPat+QuoteExpr: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynPat+QuoteExpr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+QuoteExpr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Record: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Record: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Record: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.SynPat]] fieldPats +FSharp.Compiler.Syntax.SynPat+Record: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.SynPat]] get_fieldPats() +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Ands +FSharp.Compiler.Syntax.SynPat+Tags: Int32 ArrayOrList +FSharp.Compiler.Syntax.SynPat+Tags: Int32 As +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Attrib +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Const +FSharp.Compiler.Syntax.SynPat+Tags: Int32 DeprecatedCharRange +FSharp.Compiler.Syntax.SynPat+Tags: Int32 FromParseError +FSharp.Compiler.Syntax.SynPat+Tags: Int32 InstanceMember +FSharp.Compiler.Syntax.SynPat+Tags: Int32 IsInst +FSharp.Compiler.Syntax.SynPat+Tags: Int32 LongIdent +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Named +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Null +FSharp.Compiler.Syntax.SynPat+Tags: Int32 OptionalVal +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Or +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Paren +FSharp.Compiler.Syntax.SynPat+Tags: Int32 QuoteExpr +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Record +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Tuple +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Typed +FSharp.Compiler.Syntax.SynPat+Tags: Int32 Wild +FSharp.Compiler.Syntax.SynPat+Tuple: Boolean get_isStruct() +FSharp.Compiler.Syntax.SynPat+Tuple: Boolean isStruct +FSharp.Compiler.Syntax.SynPat+Tuple: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Tuple: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] elementPats +FSharp.Compiler.Syntax.SynPat+Tuple: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat] get_elementPats() +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Syntax.SynPat get_pat() +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Syntax.SynPat pat +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Typed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat+Wild: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynPat+Wild: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynPat: Boolean IsAnds +FSharp.Compiler.Syntax.SynPat: Boolean IsArrayOrList +FSharp.Compiler.Syntax.SynPat: Boolean IsAs +FSharp.Compiler.Syntax.SynPat: Boolean IsAttrib +FSharp.Compiler.Syntax.SynPat: Boolean IsConst +FSharp.Compiler.Syntax.SynPat: Boolean IsDeprecatedCharRange +FSharp.Compiler.Syntax.SynPat: Boolean IsFromParseError +FSharp.Compiler.Syntax.SynPat: Boolean IsInstanceMember +FSharp.Compiler.Syntax.SynPat: Boolean IsIsInst +FSharp.Compiler.Syntax.SynPat: Boolean IsLongIdent +FSharp.Compiler.Syntax.SynPat: Boolean IsNamed +FSharp.Compiler.Syntax.SynPat: Boolean IsNull +FSharp.Compiler.Syntax.SynPat: Boolean IsOptionalVal +FSharp.Compiler.Syntax.SynPat: Boolean IsOr +FSharp.Compiler.Syntax.SynPat: Boolean IsParen +FSharp.Compiler.Syntax.SynPat: Boolean IsQuoteExpr +FSharp.Compiler.Syntax.SynPat: Boolean IsRecord +FSharp.Compiler.Syntax.SynPat: Boolean IsTuple +FSharp.Compiler.Syntax.SynPat: Boolean IsTyped +FSharp.Compiler.Syntax.SynPat: Boolean IsWild +FSharp.Compiler.Syntax.SynPat: Boolean get_IsAnds() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsArrayOrList() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsAs() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsAttrib() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsConst() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsDeprecatedCharRange() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsFromParseError() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsInstanceMember() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsIsInst() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsLongIdent() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsNamed() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsNull() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsOptionalVal() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsOr() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsParen() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsQuoteExpr() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsRecord() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsTuple() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsTyped() +FSharp.Compiler.Syntax.SynPat: Boolean get_IsWild() +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewAnds(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewArrayOrList(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewAs(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewAttrib(FSharp.Compiler.Syntax.SynPat, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewConst(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewDeprecatedCharRange(Char, Char, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewFromParseError(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewInstanceMember(FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewIsInst(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewLongIdent(FSharp.Compiler.Syntax.LongIdentWithDots, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynValTyparDecls], FSharp.Compiler.Syntax.SynArgPats, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewNamed(FSharp.Compiler.Syntax.Ident, Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewNull(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewOptionalVal(FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewOr(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewParen(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewQuoteExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewRecord(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.Ident],FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewTuple(Boolean, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewTyped(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewWild(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Ands +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+ArrayOrList +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+As +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Attrib +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Const +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+FromParseError +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+InstanceMember +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+IsInst +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+LongIdent +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Named +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Null +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+OptionalVal +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Or +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Paren +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+QuoteExpr +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Record +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Tags +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Tuple +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Typed +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Wild +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynPat: Int32 Tag +FSharp.Compiler.Syntax.SynPat: Int32 get_Tag() +FSharp.Compiler.Syntax.SynPat: System.String ToString() +FSharp.Compiler.Syntax.SynRationalConst +FSharp.Compiler.Syntax.SynRationalConst+Integer: Int32 get_value() +FSharp.Compiler.Syntax.SynRationalConst+Integer: Int32 value +FSharp.Compiler.Syntax.SynRationalConst+Negate: FSharp.Compiler.Syntax.SynRationalConst Item +FSharp.Compiler.Syntax.SynRationalConst+Negate: FSharp.Compiler.Syntax.SynRationalConst get_Item() +FSharp.Compiler.Syntax.SynRationalConst+Rational: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynRationalConst+Rational: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynRationalConst+Rational: Int32 denominator +FSharp.Compiler.Syntax.SynRationalConst+Rational: Int32 get_denominator() +FSharp.Compiler.Syntax.SynRationalConst+Rational: Int32 get_numerator() +FSharp.Compiler.Syntax.SynRationalConst+Rational: Int32 numerator +FSharp.Compiler.Syntax.SynRationalConst+Tags: Int32 Integer +FSharp.Compiler.Syntax.SynRationalConst+Tags: Int32 Negate +FSharp.Compiler.Syntax.SynRationalConst+Tags: Int32 Rational +FSharp.Compiler.Syntax.SynRationalConst: Boolean IsInteger +FSharp.Compiler.Syntax.SynRationalConst: Boolean IsNegate +FSharp.Compiler.Syntax.SynRationalConst: Boolean IsRational +FSharp.Compiler.Syntax.SynRationalConst: Boolean get_IsInteger() +FSharp.Compiler.Syntax.SynRationalConst: Boolean get_IsNegate() +FSharp.Compiler.Syntax.SynRationalConst: Boolean get_IsRational() +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst NewInteger(Int32) +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst NewNegate(FSharp.Compiler.Syntax.SynRationalConst) +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst NewRational(Int32, Int32, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst+Integer +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst+Negate +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst+Rational +FSharp.Compiler.Syntax.SynRationalConst: FSharp.Compiler.Syntax.SynRationalConst+Tags +FSharp.Compiler.Syntax.SynRationalConst: Int32 Tag +FSharp.Compiler.Syntax.SynRationalConst: Int32 get_Tag() +FSharp.Compiler.Syntax.SynRationalConst: System.String ToString() +FSharp.Compiler.Syntax.SynReturnInfo +FSharp.Compiler.Syntax.SynReturnInfo: FSharp.Compiler.Syntax.SynReturnInfo NewSynReturnInfo(System.Tuple`2[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynArgInfo], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynReturnInfo: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynReturnInfo: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynReturnInfo: Int32 Tag +FSharp.Compiler.Syntax.SynReturnInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynReturnInfo: System.String ToString() +FSharp.Compiler.Syntax.SynReturnInfo: System.Tuple`2[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynArgInfo] get_returnType() +FSharp.Compiler.Syntax.SynReturnInfo: System.Tuple`2[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynArgInfo] returnType +FSharp.Compiler.Syntax.SynSimplePat +FSharp.Compiler.Syntax.SynSimplePat+Attrib: FSharp.Compiler.Syntax.SynSimplePat get_pat() +FSharp.Compiler.Syntax.SynSimplePat+Attrib: FSharp.Compiler.Syntax.SynSimplePat pat +FSharp.Compiler.Syntax.SynSimplePat+Attrib: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynSimplePat+Attrib: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynSimplePat+Attrib: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynSimplePat+Attrib: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean get_isCompilerGenerated() +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean get_isOptional() +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean get_isThisVal() +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean isCompilerGenerated +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean isOptional +FSharp.Compiler.Syntax.SynSimplePat+Id: Boolean isThisVal +FSharp.Compiler.Syntax.SynSimplePat+Id: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynSimplePat+Id: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynSimplePat+Id: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynSimplePat+Id: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynSimplePat+Id: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]] altNameRefCell +FSharp.Compiler.Syntax.SynSimplePat+Id: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]] get_altNameRefCell() +FSharp.Compiler.Syntax.SynSimplePat+Tags: Int32 Attrib +FSharp.Compiler.Syntax.SynSimplePat+Tags: Int32 Id +FSharp.Compiler.Syntax.SynSimplePat+Tags: Int32 Typed +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Syntax.SynSimplePat get_pat() +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Syntax.SynSimplePat pat +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynSimplePat+Typed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynSimplePat: Boolean IsAttrib +FSharp.Compiler.Syntax.SynSimplePat: Boolean IsId +FSharp.Compiler.Syntax.SynSimplePat: Boolean IsTyped +FSharp.Compiler.Syntax.SynSimplePat: Boolean get_IsAttrib() +FSharp.Compiler.Syntax.SynSimplePat: Boolean get_IsId() +FSharp.Compiler.Syntax.SynSimplePat: Boolean get_IsTyped() +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat NewAttrib(FSharp.Compiler.Syntax.SynSimplePat, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat NewId(FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpRef`1[FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo]], Boolean, Boolean, Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat NewTyped(FSharp.Compiler.Syntax.SynSimplePat, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat+Attrib +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat+Id +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat+Tags +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Syntax.SynSimplePat+Typed +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynSimplePat: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynSimplePat: Int32 Tag +FSharp.Compiler.Syntax.SynSimplePat: Int32 get_Tag() +FSharp.Compiler.Syntax.SynSimplePat: System.String ToString() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Decided: FSharp.Compiler.Syntax.Ident Item +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Decided: FSharp.Compiler.Syntax.Ident get_Item() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Tags: Int32 Decided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Tags: Int32 Undecided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Undecided: FSharp.Compiler.Syntax.Ident Item +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Undecided: FSharp.Compiler.Syntax.Ident get_Item() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Boolean IsDecided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Boolean IsUndecided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Boolean get_IsDecided() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Boolean get_IsUndecided() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo NewDecided(FSharp.Compiler.Syntax.Ident) +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo NewUndecided(FSharp.Compiler.Syntax.Ident) +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Decided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Tags +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo+Undecided +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Int32 Tag +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynSimplePatAlternativeIdInfo: System.String ToString() +FSharp.Compiler.Syntax.SynSimplePats +FSharp.Compiler.Syntax.SynSimplePats+SimplePats: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynSimplePats+SimplePats: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynSimplePats+SimplePats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynSimplePat] get_pats() +FSharp.Compiler.Syntax.SynSimplePats+SimplePats: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynSimplePat] pats +FSharp.Compiler.Syntax.SynSimplePats+Tags: Int32 SimplePats +FSharp.Compiler.Syntax.SynSimplePats+Tags: Int32 Typed +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Syntax.SynSimplePats get_pats() +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Syntax.SynSimplePats pats +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Syntax.SynType get_targetType() +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Syntax.SynType targetType +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynSimplePats+Typed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynSimplePats: Boolean IsSimplePats +FSharp.Compiler.Syntax.SynSimplePats: Boolean IsTyped +FSharp.Compiler.Syntax.SynSimplePats: Boolean get_IsSimplePats() +FSharp.Compiler.Syntax.SynSimplePats: Boolean get_IsTyped() +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Syntax.SynSimplePats NewSimplePats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynSimplePat], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Syntax.SynSimplePats NewTyped(FSharp.Compiler.Syntax.SynSimplePats, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Syntax.SynSimplePats+SimplePats +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Syntax.SynSimplePats+Tags +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Syntax.SynSimplePats+Typed +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynSimplePats: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynSimplePats: Int32 Tag +FSharp.Compiler.Syntax.SynSimplePats: Int32 get_Tag() +FSharp.Compiler.Syntax.SynSimplePats: System.String ToString() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+Tags: Int32 WhenTyparIsStruct +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+Tags: Int32 WhenTyparTyconEqualsTycon +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparIsStruct: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparIsStruct: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparIsStruct: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparIsStruct: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Syntax.SynType get_rhsType() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Syntax.SynType rhsType +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Boolean IsWhenTyparIsStruct +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Boolean IsWhenTyparTyconEqualsTycon +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Boolean get_IsWhenTyparIsStruct() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Boolean get_IsWhenTyparTyconEqualsTycon() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: FSharp.Compiler.Syntax.SynStaticOptimizationConstraint NewWhenTyparIsStruct(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: FSharp.Compiler.Syntax.SynStaticOptimizationConstraint NewWhenTyparTyconEqualsTycon(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+Tags +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparIsStruct +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: FSharp.Compiler.Syntax.SynStaticOptimizationConstraint+WhenTyparTyconEqualsTycon +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Int32 Tag +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: Int32 get_Tag() +FSharp.Compiler.Syntax.SynStaticOptimizationConstraint: System.String ToString() +FSharp.Compiler.Syntax.SynStringKind +FSharp.Compiler.Syntax.SynStringKind+Tags: Int32 Regular +FSharp.Compiler.Syntax.SynStringKind+Tags: Int32 TripleQuote +FSharp.Compiler.Syntax.SynStringKind+Tags: Int32 Verbatim +FSharp.Compiler.Syntax.SynStringKind: Boolean Equals(FSharp.Compiler.Syntax.SynStringKind) +FSharp.Compiler.Syntax.SynStringKind: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.SynStringKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynStringKind: Boolean IsRegular +FSharp.Compiler.Syntax.SynStringKind: Boolean IsTripleQuote +FSharp.Compiler.Syntax.SynStringKind: Boolean IsVerbatim +FSharp.Compiler.Syntax.SynStringKind: Boolean get_IsRegular() +FSharp.Compiler.Syntax.SynStringKind: Boolean get_IsTripleQuote() +FSharp.Compiler.Syntax.SynStringKind: Boolean get_IsVerbatim() +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind Regular +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind TripleQuote +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind Verbatim +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind get_Regular() +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind get_TripleQuote() +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind get_Verbatim() +FSharp.Compiler.Syntax.SynStringKind: FSharp.Compiler.Syntax.SynStringKind+Tags +FSharp.Compiler.Syntax.SynStringKind: Int32 CompareTo(FSharp.Compiler.Syntax.SynStringKind) +FSharp.Compiler.Syntax.SynStringKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.SynStringKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.SynStringKind: Int32 GetHashCode() +FSharp.Compiler.Syntax.SynStringKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.SynStringKind: Int32 Tag +FSharp.Compiler.Syntax.SynStringKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynStringKind: System.String ToString() +FSharp.Compiler.Syntax.SynTypar +FSharp.Compiler.Syntax.SynTypar: Boolean get_isCompGen() +FSharp.Compiler.Syntax.SynTypar: Boolean isCompGen +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Syntax.SynTypar NewSynTypar(FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.TyparStaticReq, Boolean) +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Syntax.TyparStaticReq get_staticReq() +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Syntax.TyparStaticReq staticReq +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypar: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypar: Int32 Tag +FSharp.Compiler.Syntax.SynTypar: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypar: System.String ToString() +FSharp.Compiler.Syntax.SynTyparDecl +FSharp.Compiler.Syntax.SynTyparDecl: FSharp.Compiler.Syntax.SynTypar Item2 +FSharp.Compiler.Syntax.SynTyparDecl: FSharp.Compiler.Syntax.SynTypar get_Item2() +FSharp.Compiler.Syntax.SynTyparDecl: FSharp.Compiler.Syntax.SynTyparDecl NewSynTyparDecl(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.SynTypar) +FSharp.Compiler.Syntax.SynTyparDecl: Int32 Tag +FSharp.Compiler.Syntax.SynTyparDecl: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTyparDecl: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynTyparDecl: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynTyparDecl: System.String ToString() +FSharp.Compiler.Syntax.SynTyparDecls +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] decls +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] get_decls() +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] constraints +FSharp.Compiler.Syntax.SynTyparDecls+PostfixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_constraints() +FSharp.Compiler.Syntax.SynTyparDecls+PrefixList: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTyparDecls+PrefixList: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTyparDecls+PrefixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] decls +FSharp.Compiler.Syntax.SynTyparDecls+PrefixList: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] get_decls() +FSharp.Compiler.Syntax.SynTyparDecls+SinglePrefix: FSharp.Compiler.Syntax.SynTyparDecl decl +FSharp.Compiler.Syntax.SynTyparDecls+SinglePrefix: FSharp.Compiler.Syntax.SynTyparDecl get_decl() +FSharp.Compiler.Syntax.SynTyparDecls+SinglePrefix: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTyparDecls+SinglePrefix: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTyparDecls+Tags: Int32 PostfixList +FSharp.Compiler.Syntax.SynTyparDecls+Tags: Int32 PrefixList +FSharp.Compiler.Syntax.SynTyparDecls+Tags: Int32 SinglePrefix +FSharp.Compiler.Syntax.SynTyparDecls: Boolean IsPostfixList +FSharp.Compiler.Syntax.SynTyparDecls: Boolean IsPrefixList +FSharp.Compiler.Syntax.SynTyparDecls: Boolean IsSinglePrefix +FSharp.Compiler.Syntax.SynTyparDecls: Boolean get_IsPostfixList() +FSharp.Compiler.Syntax.SynTyparDecls: Boolean get_IsPrefixList() +FSharp.Compiler.Syntax.SynTyparDecls: Boolean get_IsSinglePrefix() +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls NewPostfixList(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls NewPrefixList(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls NewSinglePrefix(FSharp.Compiler.Syntax.SynTyparDecl, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls+PostfixList +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls+PrefixList +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls+SinglePrefix +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Syntax.SynTyparDecls+Tags +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTyparDecls: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTyparDecls: Int32 Tag +FSharp.Compiler.Syntax.SynTyparDecls: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTyparDecls: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] TyparDecls +FSharp.Compiler.Syntax.SynTyparDecls: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTyparDecl] get_TyparDecls() +FSharp.Compiler.Syntax.SynTyparDecls: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] Constraints +FSharp.Compiler.Syntax.SynTyparDecls: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_Constraints() +FSharp.Compiler.Syntax.SynTyparDecls: System.String ToString() +FSharp.Compiler.Syntax.SynType +FSharp.Compiler.Syntax.SynType+Anon: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Anon: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+AnonRecd: Boolean get_isStruct() +FSharp.Compiler.Syntax.SynType+AnonRecd: Boolean isStruct +FSharp.Compiler.Syntax.SynType+AnonRecd: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+AnonRecd: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+AnonRecd: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynType]] fields +FSharp.Compiler.Syntax.SynType+AnonRecd: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynType]] get_fields() +FSharp.Compiler.Syntax.SynType+App: Boolean get_isPostfix() +FSharp.Compiler.Syntax.SynType+App: Boolean isPostfix +FSharp.Compiler.Syntax.SynType+App: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynType+App: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynType+App: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+App: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] commaRanges +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_commaRanges() +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_greaterRange() +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_lessRange() +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] greaterRange +FSharp.Compiler.Syntax.SynType+App: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] lessRange +FSharp.Compiler.Syntax.SynType+Array: FSharp.Compiler.Syntax.SynType elementType +FSharp.Compiler.Syntax.SynType+Array: FSharp.Compiler.Syntax.SynType get_elementType() +FSharp.Compiler.Syntax.SynType+Array: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Array: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+Array: Int32 get_rank() +FSharp.Compiler.Syntax.SynType+Array: Int32 rank +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Syntax.SynType argType +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Syntax.SynType get_argType() +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Syntax.SynType get_returnType() +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Syntax.SynType returnType +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Fun: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+HashConstraint: FSharp.Compiler.Syntax.SynType get_innerType() +FSharp.Compiler.Syntax.SynType+HashConstraint: FSharp.Compiler.Syntax.SynType innerType +FSharp.Compiler.Syntax.SynType+HashConstraint: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+HashConstraint: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynType+LongIdent: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Syntax.LongIdentWithDots get_longDotId() +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Syntax.LongIdentWithDots longDotId +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+LongIdentApp: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] commaRanges +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_commaRanges() +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_greaterRange() +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_lessRange() +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] greaterRange +FSharp.Compiler.Syntax.SynType+LongIdentApp: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] lessRange +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Syntax.SynType dividend +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Syntax.SynType divisor +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Syntax.SynType get_dividend() +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Syntax.SynType get_divisor() +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+MeasureDivide: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Syntax.SynRationalConst exponent +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Syntax.SynRationalConst get_exponent() +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Syntax.SynType baseMeasure +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Syntax.SynType get_baseMeasure() +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+MeasurePower: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType get_innerType() +FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType innerType +FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst constant +FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst get_constant() +FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+StaticConstantExpr: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynType+StaticConstantExpr: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynType+StaticConstantExpr: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+StaticConstantExpr: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType get_ident() +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType get_value() +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType ident +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Syntax.SynType value +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+StaticConstantNamed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+Tags: Int32 Anon +FSharp.Compiler.Syntax.SynType+Tags: Int32 AnonRecd +FSharp.Compiler.Syntax.SynType+Tags: Int32 App +FSharp.Compiler.Syntax.SynType+Tags: Int32 Array +FSharp.Compiler.Syntax.SynType+Tags: Int32 Fun +FSharp.Compiler.Syntax.SynType+Tags: Int32 HashConstraint +FSharp.Compiler.Syntax.SynType+Tags: Int32 LongIdent +FSharp.Compiler.Syntax.SynType+Tags: Int32 LongIdentApp +FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasureDivide +FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasurePower +FSharp.Compiler.Syntax.SynType+Tags: Int32 Paren +FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant +FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr +FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed +FSharp.Compiler.Syntax.SynType+Tags: Int32 Tuple +FSharp.Compiler.Syntax.SynType+Tags: Int32 Var +FSharp.Compiler.Syntax.SynType+Tags: Int32 WithGlobalConstraints +FSharp.Compiler.Syntax.SynType+Tuple: Boolean get_isStruct() +FSharp.Compiler.Syntax.SynType+Tuple: Boolean isStruct +FSharp.Compiler.Syntax.SynType+Tuple: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Tuple: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+Tuple: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Boolean,FSharp.Compiler.Syntax.SynType]] elementTypes +FSharp.Compiler.Syntax.SynType+Tuple: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Boolean,FSharp.Compiler.Syntax.SynType]] get_elementTypes() +FSharp.Compiler.Syntax.SynType+Var: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynType+Var: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynType+Var: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+Var: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] constraints +FSharp.Compiler.Syntax.SynType+WithGlobalConstraints: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint] get_constraints() +FSharp.Compiler.Syntax.SynType: Boolean IsAnon +FSharp.Compiler.Syntax.SynType: Boolean IsAnonRecd +FSharp.Compiler.Syntax.SynType: Boolean IsApp +FSharp.Compiler.Syntax.SynType: Boolean IsArray +FSharp.Compiler.Syntax.SynType: Boolean IsFun +FSharp.Compiler.Syntax.SynType: Boolean IsHashConstraint +FSharp.Compiler.Syntax.SynType: Boolean IsLongIdent +FSharp.Compiler.Syntax.SynType: Boolean IsLongIdentApp +FSharp.Compiler.Syntax.SynType: Boolean IsMeasureDivide +FSharp.Compiler.Syntax.SynType: Boolean IsMeasurePower +FSharp.Compiler.Syntax.SynType: Boolean IsParen +FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant +FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr +FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed +FSharp.Compiler.Syntax.SynType: Boolean IsTuple +FSharp.Compiler.Syntax.SynType: Boolean IsVar +FSharp.Compiler.Syntax.SynType: Boolean IsWithGlobalConstraints +FSharp.Compiler.Syntax.SynType: Boolean get_IsAnon() +FSharp.Compiler.Syntax.SynType: Boolean get_IsAnonRecd() +FSharp.Compiler.Syntax.SynType: Boolean get_IsApp() +FSharp.Compiler.Syntax.SynType: Boolean get_IsArray() +FSharp.Compiler.Syntax.SynType: Boolean get_IsFun() +FSharp.Compiler.Syntax.SynType: Boolean get_IsHashConstraint() +FSharp.Compiler.Syntax.SynType: Boolean get_IsLongIdent() +FSharp.Compiler.Syntax.SynType: Boolean get_IsLongIdentApp() +FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasureDivide() +FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasurePower() +FSharp.Compiler.Syntax.SynType: Boolean get_IsParen() +FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant() +FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr() +FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed() +FSharp.Compiler.Syntax.SynType: Boolean get_IsTuple() +FSharp.Compiler.Syntax.SynType: Boolean get_IsVar() +FSharp.Compiler.Syntax.SynType: Boolean get_IsWithGlobalConstraints() +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnon(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewAnonRecd(Boolean, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Syntax.SynType]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewApp(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Boolean, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewArray(Int32, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewFun(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewHashConstraint(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewLongIdent(FSharp.Compiler.Syntax.LongIdentWithDots) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewLongIdentApp(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.LongIdentWithDots, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasureDivide(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasurePower(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynRationalConst, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewParen(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewTuple(Boolean, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Boolean,FSharp.Compiler.Syntax.SynType]], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewVar(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewWithGlobalConstraints(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynTypeConstraint], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Anon +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+AnonRecd +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+App +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Array +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Fun +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+HashConstraint +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+LongIdent +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+LongIdentApp +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasureDivide +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasurePower +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Paren +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tags +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Tuple +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Var +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+WithGlobalConstraints +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynType: Int32 Tag +FSharp.Compiler.Syntax.SynType: Int32 get_Tag() +FSharp.Compiler.Syntax.SynType: System.String ToString() +FSharp.Compiler.Syntax.SynTypeConstraint +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparDefaultsToType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsComparable +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsDelegate +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsEnum +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsEquatable +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsReferenceType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsUnmanaged +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSubtypeOfType +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsMember +FSharp.Compiler.Syntax.SynTypeConstraint+Tags: Int32 WhereTyparSupportsNull +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsComparable: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsComparable: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsComparable: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsComparable: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typeArgs() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typeArgs +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEquatable: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEquatable: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEquatable: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEquatable: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynType get_typeName() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Syntax.SynType typeName +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: FSharp.Compiler.Syntax.SynMemberSig get_memberSig() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: FSharp.Compiler.Syntax.SynMemberSig memberSig +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] get_typars() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType] typars +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull: FSharp.Compiler.Syntax.SynTypar get_typar() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull: FSharp.Compiler.Syntax.SynTypar typar +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparDefaultsToType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsComparable +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsDelegate +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsEnum +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsEquatable +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsReferenceType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsUnmanaged +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSubtypeOfType +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsMember +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean IsWhereTyparSupportsNull +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparDefaultsToType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsComparable() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsDelegate() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsEnum() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsEquatable() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsReferenceType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsUnmanaged() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparIsValueType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSubtypeOfType() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsMember() +FSharp.Compiler.Syntax.SynTypeConstraint: Boolean get_IsWhereTyparSupportsNull() +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparDefaultsToType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsComparable(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsDelegate(FSharp.Compiler.Syntax.SynTypar, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsEnum(FSharp.Compiler.Syntax.SynTypar, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsEquatable(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsReferenceType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsUnmanaged(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparIsValueType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSubtypeOfType(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsMember(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], FSharp.Compiler.Syntax.SynMemberSig, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint NewWhereTyparSupportsNull(FSharp.Compiler.Syntax.SynTypar, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+Tags +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparDefaultsToType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsComparable +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsDelegate +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEnum +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsEquatable +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsReferenceType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsUnmanaged +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparIsValueType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSubtypeOfType +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsMember +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Syntax.SynTypeConstraint+WhereTyparSupportsNull +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeConstraint: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeConstraint: Int32 Tag +FSharp.Compiler.Syntax.SynTypeConstraint: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeConstraint: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefn +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Syntax.SynComponentInfo get_typeInfo() +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Syntax.SynComponentInfo typeInfo +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Syntax.SynTypeDefn NewSynTypeDefn(FSharp.Compiler.Syntax.SynComponentInfo, FSharp.Compiler.Syntax.SynTypeDefnRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberDefn], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Syntax.SynTypeDefnRepr get_typeRepr() +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Syntax.SynTypeDefnRepr typeRepr +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefn: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefn: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefn: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefn: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] get_members() +FSharp.Compiler.Syntax.SynTypeDefn: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] members +FSharp.Compiler.Syntax.SynTypeDefn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberDefn] get_implicitConstructor() +FSharp.Compiler.Syntax.SynTypeDefn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberDefn] implicitConstructor +FSharp.Compiler.Syntax.SynTypeDefn: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefnKind +FSharp.Compiler.Syntax.SynTypeDefnKind+Delegate: FSharp.Compiler.Syntax.SynType get_signature() +FSharp.Compiler.Syntax.SynTypeDefnKind+Delegate: FSharp.Compiler.Syntax.SynType signature +FSharp.Compiler.Syntax.SynTypeDefnKind+Delegate: FSharp.Compiler.Syntax.SynValInfo get_signatureInfo() +FSharp.Compiler.Syntax.SynTypeDefnKind+Delegate: FSharp.Compiler.Syntax.SynValInfo signatureInfo +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Abbrev +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Augmentation +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Class +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Delegate +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 IL +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Interface +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Opaque +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Record +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Struct +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Union +FSharp.Compiler.Syntax.SynTypeDefnKind+Tags: Int32 Unspecified +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsAbbrev +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsAugmentation +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsClass +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsDelegate +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsIL +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsInterface +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsOpaque +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsRecord +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsStruct +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsUnion +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean IsUnspecified +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsAbbrev() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsAugmentation() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsClass() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsDelegate() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsIL() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsInterface() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsOpaque() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsRecord() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsStruct() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsUnion() +FSharp.Compiler.Syntax.SynTypeDefnKind: Boolean get_IsUnspecified() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Abbrev +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Augmentation +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Class +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind IL +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Interface +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind NewDelegate(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynValInfo) +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Opaque +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Record +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Struct +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Union +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind Unspecified +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Abbrev() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Augmentation() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Class() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_IL() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Interface() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Opaque() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Record() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Struct() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Union() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind get_Unspecified() +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind+Delegate +FSharp.Compiler.Syntax.SynTypeDefnKind: FSharp.Compiler.Syntax.SynTypeDefnKind+Tags +FSharp.Compiler.Syntax.SynTypeDefnKind: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefnKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefnKind: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefnRepr +FSharp.Compiler.Syntax.SynTypeDefnRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr exnRepr +FSharp.Compiler.Syntax.SynTypeDefnRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr get_exnRepr() +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: FSharp.Compiler.Syntax.SynTypeDefnKind get_kind() +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: FSharp.Compiler.Syntax.SynTypeDefnKind kind +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] get_members() +FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn] members +FSharp.Compiler.Syntax.SynTypeDefnRepr+Simple: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr get_simpleRepr() +FSharp.Compiler.Syntax.SynTypeDefnRepr+Simple: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr simpleRepr +FSharp.Compiler.Syntax.SynTypeDefnRepr+Simple: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnRepr+Simple: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnRepr+Tags: Int32 Exception +FSharp.Compiler.Syntax.SynTypeDefnRepr+Tags: Int32 ObjectModel +FSharp.Compiler.Syntax.SynTypeDefnRepr+Tags: Int32 Simple +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean IsException +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean IsObjectModel +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean IsSimple +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean get_IsException() +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean get_IsObjectModel() +FSharp.Compiler.Syntax.SynTypeDefnRepr: Boolean get_IsSimple() +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr NewException(FSharp.Compiler.Syntax.SynExceptionDefnRepr) +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr NewObjectModel(FSharp.Compiler.Syntax.SynTypeDefnKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr NewSimple(FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr+Exception +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr+ObjectModel +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr+Simple +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Syntax.SynTypeDefnRepr+Tags +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeDefnRepr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeDefnRepr: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefnRepr: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefnRepr: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefnSig +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Syntax.SynComponentInfo get_typeInfo() +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Syntax.SynComponentInfo typeInfo +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Syntax.SynTypeDefnSig NewSynTypeDefnSig(FSharp.Compiler.Syntax.SynComponentInfo, FSharp.Compiler.Syntax.SynTypeDefnSigRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Syntax.SynTypeDefnSigRepr get_typeRepr() +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Syntax.SynTypeDefnSigRepr typeRepr +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSig: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSig: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefnSig: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefnSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] get_members() +FSharp.Compiler.Syntax.SynTypeDefnSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] members +FSharp.Compiler.Syntax.SynTypeDefnSig: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr get_repr() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr repr +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: FSharp.Compiler.Syntax.SynTypeDefnKind get_kind() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: FSharp.Compiler.Syntax.SynTypeDefnKind kind +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] get_memberSigs() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig] memberSigs +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Simple: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr get_repr() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Simple: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr repr +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Simple: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Simple: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Tags: Int32 Exception +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Tags: Int32 ObjectModel +FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Tags: Int32 Simple +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean IsException +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean IsObjectModel +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean IsSimple +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean get_IsException() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean get_IsObjectModel() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Boolean get_IsSimple() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr NewException(FSharp.Compiler.Syntax.SynExceptionDefnRepr) +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr NewObjectModel(FSharp.Compiler.Syntax.SynTypeDefnKind, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberSig], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr NewSimple(FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Exception +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr+ObjectModel +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Simple +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Syntax.SynTypeDefnSigRepr+Tags +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefnSigRepr: System.String ToString() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Enum: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Enum: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Enum: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynEnumCase] cases +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Enum: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynEnumCase] get_cases() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr exnRepr +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Exception: FSharp.Compiler.Syntax.SynExceptionDefnRepr get_exnRepr() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Boolean get_isConcrete() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Boolean get_isIncrClass() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Boolean isConcrete +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Boolean isIncrClass +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: FSharp.Compiler.Syntax.SynTypeDefnKind get_kind() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: FSharp.Compiler.Syntax.SynTypeDefnKind kind +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] fields +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] get_fields() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.SynValSig,FSharp.Compiler.Syntax.SynMemberFlags]] get_slotsigs() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.SynValSig,FSharp.Compiler.Syntax.SynMemberFlags]] slotsigs +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] get_inherits() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] inherits +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynSimplePats] get_implicitCtorSynPats() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynSimplePats] implicitCtorSynPats +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+LibraryOnlyILAssembly: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+LibraryOnlyILAssembly: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+LibraryOnlyILAssembly: System.Object get_ilType() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+LibraryOnlyILAssembly: System.Object ilType +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+None: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+None: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] get_recordFields() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] recordFields +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 Enum +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 Exception +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 General +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 LibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 None +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 Record +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 TypeAbbrev +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags: Int32 Union +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Syntax.ParserDetail detail +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Syntax.ParserDetail get_detail() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Syntax.SynType get_rhsType() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Syntax.SynType rhsType +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynUnionCase] get_unionCases() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynUnionCase] unionCases +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsEnum +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsException +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsGeneral +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsLibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsNone +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsRecord +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsTypeAbbrev +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean IsUnion +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsEnum() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsException() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsGeneral() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsLibraryOnlyILAssembly() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsNone() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsRecord() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsTypeAbbrev() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Boolean get_IsUnion() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewEnum(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynEnumCase], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewException(FSharp.Compiler.Syntax.SynExceptionDefnRepr) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewGeneral(FSharp.Compiler.Syntax.SynTypeDefnKind, Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]], Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Syntax.SynValSig,FSharp.Compiler.Syntax.SynMemberFlags]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField], Boolean, Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynSimplePats], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewLibraryOnlyILAssembly(System.Object, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewNone(FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewRecord(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewTypeAbbrev(FSharp.Compiler.Syntax.ParserDetail, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr NewUnion(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynUnionCase], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Enum +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Exception +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+General +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+LibraryOnlyILAssembly +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+None +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Record +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Tags +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+TypeAbbrev +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr+Union +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Int32 Tag +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: Int32 get_Tag() +FSharp.Compiler.Syntax.SynTypeDefnSimpleRepr: System.String ToString() +FSharp.Compiler.Syntax.SynUnionCase +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Syntax.SynUnionCase NewSynUnionCase(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.SynUnionCaseKind, FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Syntax.SynUnionCaseKind caseType +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Syntax.SynUnionCaseKind get_caseType() +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynUnionCase: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynUnionCase: Int32 Tag +FSharp.Compiler.Syntax.SynUnionCase: Int32 get_Tag() +FSharp.Compiler.Syntax.SynUnionCase: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynUnionCase: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynUnionCase: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynUnionCase: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynUnionCase: System.String ToString() +FSharp.Compiler.Syntax.SynUnionCaseKind +FSharp.Compiler.Syntax.SynUnionCaseKind+Fields: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] cases +FSharp.Compiler.Syntax.SynUnionCaseKind+Fields: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField] get_cases() +FSharp.Compiler.Syntax.SynUnionCaseKind+FullType: FSharp.Compiler.Syntax.SynType fullType +FSharp.Compiler.Syntax.SynUnionCaseKind+FullType: FSharp.Compiler.Syntax.SynType get_fullType() +FSharp.Compiler.Syntax.SynUnionCaseKind+FullType: FSharp.Compiler.Syntax.SynValInfo fullTypeInfo +FSharp.Compiler.Syntax.SynUnionCaseKind+FullType: FSharp.Compiler.Syntax.SynValInfo get_fullTypeInfo() +FSharp.Compiler.Syntax.SynUnionCaseKind+Tags: Int32 Fields +FSharp.Compiler.Syntax.SynUnionCaseKind+Tags: Int32 FullType +FSharp.Compiler.Syntax.SynUnionCaseKind: Boolean IsFields +FSharp.Compiler.Syntax.SynUnionCaseKind: Boolean IsFullType +FSharp.Compiler.Syntax.SynUnionCaseKind: Boolean get_IsFields() +FSharp.Compiler.Syntax.SynUnionCaseKind: Boolean get_IsFullType() +FSharp.Compiler.Syntax.SynUnionCaseKind: FSharp.Compiler.Syntax.SynUnionCaseKind NewFields(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynField]) +FSharp.Compiler.Syntax.SynUnionCaseKind: FSharp.Compiler.Syntax.SynUnionCaseKind NewFullType(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynValInfo) +FSharp.Compiler.Syntax.SynUnionCaseKind: FSharp.Compiler.Syntax.SynUnionCaseKind+Fields +FSharp.Compiler.Syntax.SynUnionCaseKind: FSharp.Compiler.Syntax.SynUnionCaseKind+FullType +FSharp.Compiler.Syntax.SynUnionCaseKind: FSharp.Compiler.Syntax.SynUnionCaseKind+Tags +FSharp.Compiler.Syntax.SynUnionCaseKind: Int32 Tag +FSharp.Compiler.Syntax.SynUnionCaseKind: Int32 get_Tag() +FSharp.Compiler.Syntax.SynUnionCaseKind: System.String ToString() +FSharp.Compiler.Syntax.SynValData +FSharp.Compiler.Syntax.SynValData: FSharp.Compiler.Syntax.SynValData NewSynValData(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberFlags], FSharp.Compiler.Syntax.SynValInfo, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]) +FSharp.Compiler.Syntax.SynValData: FSharp.Compiler.Syntax.SynValInfo SynValInfo +FSharp.Compiler.Syntax.SynValData: FSharp.Compiler.Syntax.SynValInfo get_SynValInfo() +FSharp.Compiler.Syntax.SynValData: FSharp.Compiler.Syntax.SynValInfo get_valInfo() +FSharp.Compiler.Syntax.SynValData: FSharp.Compiler.Syntax.SynValInfo valInfo +FSharp.Compiler.Syntax.SynValData: Int32 Tag +FSharp.Compiler.Syntax.SynValData: Int32 get_Tag() +FSharp.Compiler.Syntax.SynValData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_thisIdOpt() +FSharp.Compiler.Syntax.SynValData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] thisIdOpt +FSharp.Compiler.Syntax.SynValData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberFlags] get_memberFlags() +FSharp.Compiler.Syntax.SynValData: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynMemberFlags] memberFlags +FSharp.Compiler.Syntax.SynValData: System.String ToString() +FSharp.Compiler.Syntax.SynValInfo +FSharp.Compiler.Syntax.SynValInfo: FSharp.Compiler.Syntax.SynArgInfo get_returnInfo() +FSharp.Compiler.Syntax.SynValInfo: FSharp.Compiler.Syntax.SynArgInfo returnInfo +FSharp.Compiler.Syntax.SynValInfo: FSharp.Compiler.Syntax.SynValInfo NewSynValInfo(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynArgInfo]], FSharp.Compiler.Syntax.SynArgInfo) +FSharp.Compiler.Syntax.SynValInfo: Int32 Tag +FSharp.Compiler.Syntax.SynValInfo: Int32 get_Tag() +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynArgInfo]] CurriedArgInfos +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynArgInfo]] curriedArgInfos +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynArgInfo]] get_CurriedArgInfos() +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynArgInfo]] get_curriedArgInfos() +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[System.String] ArgNames +FSharp.Compiler.Syntax.SynValInfo: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_ArgNames() +FSharp.Compiler.Syntax.SynValInfo: System.String ToString() +FSharp.Compiler.Syntax.SynValSig +FSharp.Compiler.Syntax.SynValSig: Boolean get_isInline() +FSharp.Compiler.Syntax.SynValSig: Boolean get_isMutable() +FSharp.Compiler.Syntax.SynValSig: Boolean isInline +FSharp.Compiler.Syntax.SynValSig: Boolean isMutable +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.Ident get_ident() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.Ident ident +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynType SynType +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynType get_SynType() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynType get_synType() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynType synType +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValInfo SynInfo +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValInfo arity +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValInfo get_SynInfo() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValInfo get_arity() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValSig NewSynValSig(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.SynValTyparDecls, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynValInfo, Boolean, Boolean, FSharp.Compiler.Xml.PreXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValTyparDecls explicitValDecls +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Syntax.SynValTyparDecls get_explicitValDecls() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Text.Range RangeOfId +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Text.Range get_RangeOfId() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Xml.PreXmlDoc get_xmlDoc() +FSharp.Compiler.Syntax.SynValSig: FSharp.Compiler.Xml.PreXmlDoc xmlDoc +FSharp.Compiler.Syntax.SynValSig: Int32 Tag +FSharp.Compiler.Syntax.SynValSig: Int32 get_Tag() +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] accessibility +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_accessibility() +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] get_synExpr() +FSharp.Compiler.Syntax.SynValSig: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] synExpr +FSharp.Compiler.Syntax.SynValSig: System.String ToString() +FSharp.Compiler.Syntax.SynValTyparDecls +FSharp.Compiler.Syntax.SynValTyparDecls: Boolean canInfer +FSharp.Compiler.Syntax.SynValTyparDecls: Boolean get_canInfer() +FSharp.Compiler.Syntax.SynValTyparDecls: FSharp.Compiler.Syntax.SynValTyparDecls NewSynValTyparDecls(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls], Boolean) +FSharp.Compiler.Syntax.SynValTyparDecls: Int32 Tag +FSharp.Compiler.Syntax.SynValTyparDecls: Int32 get_Tag() +FSharp.Compiler.Syntax.SynValTyparDecls: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls] get_typars() +FSharp.Compiler.Syntax.SynValTyparDecls: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynTyparDecls] typars +FSharp.Compiler.Syntax.SynValTyparDecls: System.String ToString() +FSharp.Compiler.Syntax.SyntaxNode +FSharp.Compiler.Syntax.SyntaxNode+SynBinding: FSharp.Compiler.Syntax.SynBinding Item +FSharp.Compiler.Syntax.SyntaxNode+SynBinding: FSharp.Compiler.Syntax.SynBinding get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynExpr: FSharp.Compiler.Syntax.SynExpr Item +FSharp.Compiler.Syntax.SyntaxNode+SynExpr: FSharp.Compiler.Syntax.SynExpr get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynMatchClause: FSharp.Compiler.Syntax.SynMatchClause Item +FSharp.Compiler.Syntax.SyntaxNode+SynMatchClause: FSharp.Compiler.Syntax.SynMatchClause get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn Item +FSharp.Compiler.Syntax.SyntaxNode+SynMemberDefn: FSharp.Compiler.Syntax.SynMemberDefn get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynModule: FSharp.Compiler.Syntax.SynModuleDecl Item +FSharp.Compiler.Syntax.SyntaxNode+SynModule: FSharp.Compiler.Syntax.SynModuleDecl get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynModuleOrNamespace: FSharp.Compiler.Syntax.SynModuleOrNamespace Item +FSharp.Compiler.Syntax.SyntaxNode+SynModuleOrNamespace: FSharp.Compiler.Syntax.SynModuleOrNamespace get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynPat: FSharp.Compiler.Syntax.SynPat Item +FSharp.Compiler.Syntax.SyntaxNode+SynPat: FSharp.Compiler.Syntax.SynPat get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynType: FSharp.Compiler.Syntax.SynType Item +FSharp.Compiler.Syntax.SyntaxNode+SynType: FSharp.Compiler.Syntax.SynType get_Item() +FSharp.Compiler.Syntax.SyntaxNode+SynTypeDefn: FSharp.Compiler.Syntax.SynTypeDefn Item +FSharp.Compiler.Syntax.SyntaxNode+SynTypeDefn: FSharp.Compiler.Syntax.SynTypeDefn get_Item() +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynBinding +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynExpr +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynMatchClause +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynMemberDefn +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynModule +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynModuleOrNamespace +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynPat +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynType +FSharp.Compiler.Syntax.SyntaxNode+Tags: Int32 SynTypeDefn +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynBinding +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynExpr +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynMatchClause +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynMemberDefn +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynModule +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynModuleOrNamespace +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynPat +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynType +FSharp.Compiler.Syntax.SyntaxNode: Boolean IsSynTypeDefn +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynBinding() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynExpr() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynMatchClause() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynMemberDefn() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynModule() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynModuleOrNamespace() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynPat() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynType() +FSharp.Compiler.Syntax.SyntaxNode: Boolean get_IsSynTypeDefn() +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynBinding(FSharp.Compiler.Syntax.SynBinding) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynExpr(FSharp.Compiler.Syntax.SynExpr) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynMatchClause(FSharp.Compiler.Syntax.SynMatchClause) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynMemberDefn(FSharp.Compiler.Syntax.SynMemberDefn) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynModule(FSharp.Compiler.Syntax.SynModuleDecl) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynModuleOrNamespace(FSharp.Compiler.Syntax.SynModuleOrNamespace) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynPat(FSharp.Compiler.Syntax.SynPat) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynType(FSharp.Compiler.Syntax.SynType) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode NewSynTypeDefn(FSharp.Compiler.Syntax.SynTypeDefn) +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynBinding +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynExpr +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynMatchClause +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynMemberDefn +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynModule +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynModuleOrNamespace +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynPat +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynType +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+SynTypeDefn +FSharp.Compiler.Syntax.SyntaxNode: FSharp.Compiler.Syntax.SyntaxNode+Tags +FSharp.Compiler.Syntax.SyntaxNode: Int32 Tag +FSharp.Compiler.Syntax.SyntaxNode: Int32 get_Tag() +FSharp.Compiler.Syntax.SyntaxNode: System.String ToString() +FSharp.Compiler.Syntax.SyntaxTraversal +FSharp.Compiler.Syntax.SyntaxTraversal: Microsoft.FSharp.Core.FSharpOption`1[T] Traverse[T](FSharp.Compiler.Text.Position, FSharp.Compiler.Syntax.ParsedInput, FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T] +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitBinding(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynBinding,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynBinding) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitComponentInfo(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynComponentInfo) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitExpr(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynExpr) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitHashDirective(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.ParsedHashDirective, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitImplicitInherit(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitInheritSynMemberDefn(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynComponentInfo, FSharp.Compiler.Syntax.SynTypeDefnKind, FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitInterfaceSynMemberDefnType(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynType) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitLetOrUse(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Boolean, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynBinding,Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitMatchClause(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynMatchClause,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynMatchClause) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitModuleDecl(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynModuleDecl,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynModuleDecl) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitModuleOrNamespace(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynModuleOrNamespace) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitPat(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynPat,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynPat) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitRecordField(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.LongIdentWithDots]) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitSimplePats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynSimplePat]) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitType(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Syntax.SynType,Microsoft.FSharp.Core.FSharpOption`1[T]], FSharp.Compiler.Syntax.SynType) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] VisitTypeAbbrev(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SyntaxVisitorBase`1[T]: Void .ctor() +FSharp.Compiler.Syntax.TyparStaticReq +FSharp.Compiler.Syntax.TyparStaticReq+Tags: Int32 HeadType +FSharp.Compiler.Syntax.TyparStaticReq+Tags: Int32 None +FSharp.Compiler.Syntax.TyparStaticReq: Boolean Equals(FSharp.Compiler.Syntax.TyparStaticReq) +FSharp.Compiler.Syntax.TyparStaticReq: Boolean Equals(System.Object) +FSharp.Compiler.Syntax.TyparStaticReq: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.TyparStaticReq: Boolean IsHeadType +FSharp.Compiler.Syntax.TyparStaticReq: Boolean IsNone +FSharp.Compiler.Syntax.TyparStaticReq: Boolean get_IsHeadType() +FSharp.Compiler.Syntax.TyparStaticReq: Boolean get_IsNone() +FSharp.Compiler.Syntax.TyparStaticReq: FSharp.Compiler.Syntax.TyparStaticReq HeadType +FSharp.Compiler.Syntax.TyparStaticReq: FSharp.Compiler.Syntax.TyparStaticReq None +FSharp.Compiler.Syntax.TyparStaticReq: FSharp.Compiler.Syntax.TyparStaticReq get_HeadType() +FSharp.Compiler.Syntax.TyparStaticReq: FSharp.Compiler.Syntax.TyparStaticReq get_None() +FSharp.Compiler.Syntax.TyparStaticReq: FSharp.Compiler.Syntax.TyparStaticReq+Tags +FSharp.Compiler.Syntax.TyparStaticReq: Int32 CompareTo(FSharp.Compiler.Syntax.TyparStaticReq) +FSharp.Compiler.Syntax.TyparStaticReq: Int32 CompareTo(System.Object) +FSharp.Compiler.Syntax.TyparStaticReq: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Syntax.TyparStaticReq: Int32 GetHashCode() +FSharp.Compiler.Syntax.TyparStaticReq: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Syntax.TyparStaticReq: Int32 Tag +FSharp.Compiler.Syntax.TyparStaticReq: Int32 get_Tag() +FSharp.Compiler.Syntax.TyparStaticReq: System.String ToString() +FSharp.Compiler.Text.ISourceText +FSharp.Compiler.Text.ISourceText: Boolean ContentEquals(FSharp.Compiler.Text.ISourceText) +FSharp.Compiler.Text.ISourceText: Boolean SubTextEquals(System.String, Int32) +FSharp.Compiler.Text.ISourceText: Char Item [Int32] +FSharp.Compiler.Text.ISourceText: Char get_Item(Int32) +FSharp.Compiler.Text.ISourceText: Int32 GetLineCount() +FSharp.Compiler.Text.ISourceText: Int32 Length +FSharp.Compiler.Text.ISourceText: Int32 get_Length() +FSharp.Compiler.Text.ISourceText: System.String GetLineString(Int32) +FSharp.Compiler.Text.ISourceText: System.String GetSubTextString(Int32, Int32) +FSharp.Compiler.Text.ISourceText: System.Tuple`2[System.Int32,System.Int32] GetLastCharacterPosition() +FSharp.Compiler.Text.ISourceText: Void CopyTo(Int32, Char[], Int32, Int32) +FSharp.Compiler.Text.Line +FSharp.Compiler.Text.Line: Int32 fromZ(Int32) +FSharp.Compiler.Text.Line: Int32 toZ(Int32) +FSharp.Compiler.Text.NavigableTaggedText +FSharp.Compiler.Text.NavigableTaggedText: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Text.NavigableTaggedText: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Text.Position +FSharp.Compiler.Text.Position: Boolean Equals(System.Object) +FSharp.Compiler.Text.Position: Int32 Column +FSharp.Compiler.Text.Position: Int32 GetHashCode() +FSharp.Compiler.Text.Position: Int32 Line +FSharp.Compiler.Text.Position: Int32 get_Column() +FSharp.Compiler.Text.Position: Int32 get_Line() +FSharp.Compiler.Text.Position: System.String ToString() +FSharp.Compiler.Text.PositionModule +FSharp.Compiler.Text.PositionModule: Boolean posEq(FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: Boolean posGeq(FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: Boolean posGt(FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: Boolean posLt(FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: FSharp.Compiler.Text.Position fromZ(Int32, Int32) +FSharp.Compiler.Text.PositionModule: FSharp.Compiler.Text.Position get_pos0() +FSharp.Compiler.Text.PositionModule: FSharp.Compiler.Text.Position mkPos(Int32, Int32) +FSharp.Compiler.Text.PositionModule: FSharp.Compiler.Text.Position pos0 +FSharp.Compiler.Text.PositionModule: System.String stringOfPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: System.Tuple`2[System.Int32,System.Int32] toZ(FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.PositionModule: Void outputPos(System.IO.TextWriter, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.Range +FSharp.Compiler.Text.Range: Boolean Equals(System.Object) +FSharp.Compiler.Text.Range: Boolean IsSynthetic +FSharp.Compiler.Text.Range: Boolean get_IsSynthetic() +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position End +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position Start +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_End() +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Position get_Start() +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range EndRange +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range StartRange +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range Zero +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_EndRange() +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_StartRange() +FSharp.Compiler.Text.Range: FSharp.Compiler.Text.Range get_Zero() +FSharp.Compiler.Text.Range: Int32 EndColumn +FSharp.Compiler.Text.Range: Int32 EndLine +FSharp.Compiler.Text.Range: Int32 GetHashCode() +FSharp.Compiler.Text.Range: Int32 StartColumn +FSharp.Compiler.Text.Range: Int32 StartLine +FSharp.Compiler.Text.Range: Int32 get_EndColumn() +FSharp.Compiler.Text.Range: Int32 get_EndLine() +FSharp.Compiler.Text.Range: Int32 get_StartColumn() +FSharp.Compiler.Text.Range: Int32 get_StartLine() +FSharp.Compiler.Text.Range: System.String FileName +FSharp.Compiler.Text.Range: System.String ToString() +FSharp.Compiler.Text.Range: System.String get_FileName() +FSharp.Compiler.Text.RangeModule +FSharp.Compiler.Text.RangeModule: Boolean equals(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: Boolean rangeBeforePos(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.RangeModule: Boolean rangeContainsPos(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.RangeModule: Boolean rangeContainsRange(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_range0() +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeCmdArgs() +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range get_rangeStartup() +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFileIndexRange(Int32, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkFirstLineOfFile(System.String) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range mkRange(System.String, FSharp.Compiler.Text.Position, FSharp.Compiler.Text.Position) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range range0 +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range rangeCmdArgs +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range rangeN(System.String, Int32) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range rangeStartup +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range trimRangeToLine(FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: FSharp.Compiler.Text.Range unionRanges(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IComparer`1[FSharp.Compiler.Text.Position] get_posOrder() +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IComparer`1[FSharp.Compiler.Text.Position] posOrder +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IComparer`1[FSharp.Compiler.Text.Range] get_rangeOrder() +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IComparer`1[FSharp.Compiler.Text.Range] rangeOrder +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IEqualityComparer`1[FSharp.Compiler.Text.Range] comparer +FSharp.Compiler.Text.RangeModule: System.Collections.Generic.IEqualityComparer`1[FSharp.Compiler.Text.Range] get_comparer() +FSharp.Compiler.Text.RangeModule: System.String stringOfRange(FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: System.Tuple`2[System.String,System.Tuple`2[System.Tuple`2[System.Int32,System.Int32],System.Tuple`2[System.Int32,System.Int32]]] toFileZ(FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: System.Tuple`2[System.Tuple`2[System.Int32,System.Int32],System.Tuple`2[System.Int32,System.Int32]] toZ(FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.RangeModule: Void outputRange(System.IO.TextWriter, FSharp.Compiler.Text.Range) +FSharp.Compiler.Text.SourceText +FSharp.Compiler.Text.SourceText: FSharp.Compiler.Text.ISourceText ofString(System.String) +FSharp.Compiler.Text.TaggedText +FSharp.Compiler.Text.TaggedText: FSharp.Compiler.Text.TextTag Tag +FSharp.Compiler.Text.TaggedText: FSharp.Compiler.Text.TextTag get_Tag() +FSharp.Compiler.Text.TaggedText: System.String Text +FSharp.Compiler.Text.TaggedText: System.String ToString() +FSharp.Compiler.Text.TaggedText: System.String get_Text() +FSharp.Compiler.Text.TaggedText: Void .ctor(FSharp.Compiler.Text.TextTag, System.String) +FSharp.Compiler.Text.TaggedTextModule +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText colon +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText comma +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText dot +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_colon() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_comma() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_dot() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_lineBreak() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_minus() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText get_space() +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText lineBreak +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText minus +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText space +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText tagClass(System.String) +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText tagNamespace(System.String) +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText tagParameter(System.String) +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText tagSpace(System.String) +FSharp.Compiler.Text.TaggedTextModule: FSharp.Compiler.Text.TaggedText tagText(System.String) +FSharp.Compiler.Text.TextTag +FSharp.Compiler.Text.TextTag+Tags: Int32 ActivePatternCase +FSharp.Compiler.Text.TextTag+Tags: Int32 ActivePatternResult +FSharp.Compiler.Text.TextTag+Tags: Int32 Alias +FSharp.Compiler.Text.TextTag+Tags: Int32 Class +FSharp.Compiler.Text.TextTag+Tags: Int32 Delegate +FSharp.Compiler.Text.TextTag+Tags: Int32 Enum +FSharp.Compiler.Text.TextTag+Tags: Int32 Event +FSharp.Compiler.Text.TextTag+Tags: Int32 Field +FSharp.Compiler.Text.TextTag+Tags: Int32 Function +FSharp.Compiler.Text.TextTag+Tags: Int32 Interface +FSharp.Compiler.Text.TextTag+Tags: Int32 Keyword +FSharp.Compiler.Text.TextTag+Tags: Int32 LineBreak +FSharp.Compiler.Text.TextTag+Tags: Int32 Local +FSharp.Compiler.Text.TextTag+Tags: Int32 Member +FSharp.Compiler.Text.TextTag+Tags: Int32 Method +FSharp.Compiler.Text.TextTag+Tags: Int32 Module +FSharp.Compiler.Text.TextTag+Tags: Int32 ModuleBinding +FSharp.Compiler.Text.TextTag+Tags: Int32 Namespace +FSharp.Compiler.Text.TextTag+Tags: Int32 NumericLiteral +FSharp.Compiler.Text.TextTag+Tags: Int32 Operator +FSharp.Compiler.Text.TextTag+Tags: Int32 Parameter +FSharp.Compiler.Text.TextTag+Tags: Int32 Property +FSharp.Compiler.Text.TextTag+Tags: Int32 Punctuation +FSharp.Compiler.Text.TextTag+Tags: Int32 Record +FSharp.Compiler.Text.TextTag+Tags: Int32 RecordField +FSharp.Compiler.Text.TextTag+Tags: Int32 Space +FSharp.Compiler.Text.TextTag+Tags: Int32 StringLiteral +FSharp.Compiler.Text.TextTag+Tags: Int32 Struct +FSharp.Compiler.Text.TextTag+Tags: Int32 Text +FSharp.Compiler.Text.TextTag+Tags: Int32 TypeParameter +FSharp.Compiler.Text.TextTag+Tags: Int32 Union +FSharp.Compiler.Text.TextTag+Tags: Int32 UnionCase +FSharp.Compiler.Text.TextTag+Tags: Int32 UnknownEntity +FSharp.Compiler.Text.TextTag+Tags: Int32 UnknownType +FSharp.Compiler.Text.TextTag: Boolean Equals(FSharp.Compiler.Text.TextTag) +FSharp.Compiler.Text.TextTag: Boolean Equals(System.Object) +FSharp.Compiler.Text.TextTag: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Text.TextTag: Boolean IsActivePatternCase +FSharp.Compiler.Text.TextTag: Boolean IsActivePatternResult +FSharp.Compiler.Text.TextTag: Boolean IsAlias +FSharp.Compiler.Text.TextTag: Boolean IsClass +FSharp.Compiler.Text.TextTag: Boolean IsDelegate +FSharp.Compiler.Text.TextTag: Boolean IsEnum +FSharp.Compiler.Text.TextTag: Boolean IsEvent +FSharp.Compiler.Text.TextTag: Boolean IsField +FSharp.Compiler.Text.TextTag: Boolean IsFunction +FSharp.Compiler.Text.TextTag: Boolean IsInterface +FSharp.Compiler.Text.TextTag: Boolean IsKeyword +FSharp.Compiler.Text.TextTag: Boolean IsLineBreak +FSharp.Compiler.Text.TextTag: Boolean IsLocal +FSharp.Compiler.Text.TextTag: Boolean IsMember +FSharp.Compiler.Text.TextTag: Boolean IsMethod +FSharp.Compiler.Text.TextTag: Boolean IsModule +FSharp.Compiler.Text.TextTag: Boolean IsModuleBinding +FSharp.Compiler.Text.TextTag: Boolean IsNamespace +FSharp.Compiler.Text.TextTag: Boolean IsNumericLiteral +FSharp.Compiler.Text.TextTag: Boolean IsOperator +FSharp.Compiler.Text.TextTag: Boolean IsParameter +FSharp.Compiler.Text.TextTag: Boolean IsProperty +FSharp.Compiler.Text.TextTag: Boolean IsPunctuation +FSharp.Compiler.Text.TextTag: Boolean IsRecord +FSharp.Compiler.Text.TextTag: Boolean IsRecordField +FSharp.Compiler.Text.TextTag: Boolean IsSpace +FSharp.Compiler.Text.TextTag: Boolean IsStringLiteral +FSharp.Compiler.Text.TextTag: Boolean IsStruct +FSharp.Compiler.Text.TextTag: Boolean IsText +FSharp.Compiler.Text.TextTag: Boolean IsTypeParameter +FSharp.Compiler.Text.TextTag: Boolean IsUnion +FSharp.Compiler.Text.TextTag: Boolean IsUnionCase +FSharp.Compiler.Text.TextTag: Boolean IsUnknownEntity +FSharp.Compiler.Text.TextTag: Boolean IsUnknownType +FSharp.Compiler.Text.TextTag: Boolean get_IsActivePatternCase() +FSharp.Compiler.Text.TextTag: Boolean get_IsActivePatternResult() +FSharp.Compiler.Text.TextTag: Boolean get_IsAlias() +FSharp.Compiler.Text.TextTag: Boolean get_IsClass() +FSharp.Compiler.Text.TextTag: Boolean get_IsDelegate() +FSharp.Compiler.Text.TextTag: Boolean get_IsEnum() +FSharp.Compiler.Text.TextTag: Boolean get_IsEvent() +FSharp.Compiler.Text.TextTag: Boolean get_IsField() +FSharp.Compiler.Text.TextTag: Boolean get_IsFunction() +FSharp.Compiler.Text.TextTag: Boolean get_IsInterface() +FSharp.Compiler.Text.TextTag: Boolean get_IsKeyword() +FSharp.Compiler.Text.TextTag: Boolean get_IsLineBreak() +FSharp.Compiler.Text.TextTag: Boolean get_IsLocal() +FSharp.Compiler.Text.TextTag: Boolean get_IsMember() +FSharp.Compiler.Text.TextTag: Boolean get_IsMethod() +FSharp.Compiler.Text.TextTag: Boolean get_IsModule() +FSharp.Compiler.Text.TextTag: Boolean get_IsModuleBinding() +FSharp.Compiler.Text.TextTag: Boolean get_IsNamespace() +FSharp.Compiler.Text.TextTag: Boolean get_IsNumericLiteral() +FSharp.Compiler.Text.TextTag: Boolean get_IsOperator() +FSharp.Compiler.Text.TextTag: Boolean get_IsParameter() +FSharp.Compiler.Text.TextTag: Boolean get_IsProperty() +FSharp.Compiler.Text.TextTag: Boolean get_IsPunctuation() +FSharp.Compiler.Text.TextTag: Boolean get_IsRecord() +FSharp.Compiler.Text.TextTag: Boolean get_IsRecordField() +FSharp.Compiler.Text.TextTag: Boolean get_IsSpace() +FSharp.Compiler.Text.TextTag: Boolean get_IsStringLiteral() +FSharp.Compiler.Text.TextTag: Boolean get_IsStruct() +FSharp.Compiler.Text.TextTag: Boolean get_IsText() +FSharp.Compiler.Text.TextTag: Boolean get_IsTypeParameter() +FSharp.Compiler.Text.TextTag: Boolean get_IsUnion() +FSharp.Compiler.Text.TextTag: Boolean get_IsUnionCase() +FSharp.Compiler.Text.TextTag: Boolean get_IsUnknownEntity() +FSharp.Compiler.Text.TextTag: Boolean get_IsUnknownType() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag ActivePatternCase +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag ActivePatternResult +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Alias +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Class +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Delegate +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Enum +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Event +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Field +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Function +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Interface +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Keyword +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag LineBreak +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Local +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Member +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Method +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Module +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag ModuleBinding +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Namespace +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag NumericLiteral +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Operator +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Parameter +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Property +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Punctuation +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Record +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag RecordField +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Space +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag StringLiteral +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Struct +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Text +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag TypeParameter +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag Union +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag UnionCase +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag UnknownEntity +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag UnknownType +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_ActivePatternCase() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_ActivePatternResult() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Alias() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Class() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Delegate() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Enum() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Event() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Field() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Function() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Interface() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Keyword() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_LineBreak() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Local() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Member() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Method() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Module() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_ModuleBinding() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Namespace() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_NumericLiteral() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Operator() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Parameter() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Property() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Punctuation() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Record() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_RecordField() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Space() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_StringLiteral() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Struct() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Text() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_TypeParameter() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_Union() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_UnionCase() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_UnknownEntity() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag get_UnknownType() +FSharp.Compiler.Text.TextTag: FSharp.Compiler.Text.TextTag+Tags +FSharp.Compiler.Text.TextTag: Int32 GetHashCode() +FSharp.Compiler.Text.TextTag: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Text.TextTag: Int32 Tag +FSharp.Compiler.Text.TextTag: Int32 get_Tag() +FSharp.Compiler.Text.TextTag: System.String ToString() +FSharp.Compiler.Tokenization.FSharpKeywords +FSharp.Compiler.Tokenization.FSharpKeywords: Boolean DoesIdentifierNeedBackticks(System.String) +FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.String] KeywordNames +FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_KeywordNames() +FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] KeywordsWithDescription +FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] get_KeywordsWithDescription() +FSharp.Compiler.Tokenization.FSharpKeywords: System.String AddBackticksToIdentifierIfNeeded(System.String) +FSharp.Compiler.Tokenization.FSharpKeywords: System.String NormalizeIdentifierBackticks(System.String) +FSharp.Compiler.Tokenization.FSharpLexer +FSharp.Compiler.Tokenization.FSharpLexer: Void Tokenize(FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Tokenization.FSharpToken,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Tokenization.FSharpLexerFlags], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpMap`2[System.String,System.String]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +FSharp.Compiler.Tokenization.FSharpLexerFlags +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags Compiling +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags CompilingFSharpCore +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags Default +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags LightSyntaxOn +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags SkipTrivia +FSharp.Compiler.Tokenization.FSharpLexerFlags: FSharp.Compiler.Tokenization.FSharpLexerFlags UseLexFilter +FSharp.Compiler.Tokenization.FSharpLexerFlags: Int32 value__ +FSharp.Compiler.Tokenization.FSharpLineTokenizer +FSharp.Compiler.Tokenization.FSharpLineTokenizer: FSharp.Compiler.Tokenization.FSharpTokenizerColorState ColorStateOfLexState(FSharp.Compiler.Tokenization.FSharpTokenizerLexState) +FSharp.Compiler.Tokenization.FSharpLineTokenizer: FSharp.Compiler.Tokenization.FSharpTokenizerLexState LexStateOfColorState(FSharp.Compiler.Tokenization.FSharpTokenizerColorState) +FSharp.Compiler.Tokenization.FSharpLineTokenizer: System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Tokenization.FSharpTokenInfo],FSharp.Compiler.Tokenization.FSharpTokenizerLexState] ScanToken(FSharp.Compiler.Tokenization.FSharpTokenizerLexState) +FSharp.Compiler.Tokenization.FSharpSourceTokenizer +FSharp.Compiler.Tokenization.FSharpSourceTokenizer: FSharp.Compiler.Tokenization.FSharpLineTokenizer CreateBufferTokenizer(Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[System.Char[],System.Int32,System.Int32],System.Int32]) +FSharp.Compiler.Tokenization.FSharpSourceTokenizer: FSharp.Compiler.Tokenization.FSharpLineTokenizer CreateLineTokenizer(System.String) +FSharp.Compiler.Tokenization.FSharpSourceTokenizer: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.Tokenization.FSharpToken +FSharp.Compiler.Tokenization.FSharpToken: Boolean IsCommentTrivia +FSharp.Compiler.Tokenization.FSharpToken: Boolean IsIdentifier +FSharp.Compiler.Tokenization.FSharpToken: Boolean IsKeyword +FSharp.Compiler.Tokenization.FSharpToken: Boolean IsNumericLiteral +FSharp.Compiler.Tokenization.FSharpToken: Boolean IsStringLiteral +FSharp.Compiler.Tokenization.FSharpToken: Boolean get_IsCommentTrivia() +FSharp.Compiler.Tokenization.FSharpToken: Boolean get_IsIdentifier() +FSharp.Compiler.Tokenization.FSharpToken: Boolean get_IsKeyword() +FSharp.Compiler.Tokenization.FSharpToken: Boolean get_IsNumericLiteral() +FSharp.Compiler.Tokenization.FSharpToken: Boolean get_IsStringLiteral() +FSharp.Compiler.Tokenization.FSharpToken: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Tokenization.FSharpToken: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Tokenization.FSharpToken: FSharp.Compiler.Tokenization.FSharpTokenKind Kind +FSharp.Compiler.Tokenization.FSharpToken: FSharp.Compiler.Tokenization.FSharpTokenKind get_Kind() +FSharp.Compiler.Tokenization.FSharpTokenCharKind +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Comment +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Default +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Delimiter +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Identifier +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Keyword +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind LineComment +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Literal +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Operator +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind String +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind Text +FSharp.Compiler.Tokenization.FSharpTokenCharKind: FSharp.Compiler.Tokenization.FSharpTokenCharKind WhiteSpace +FSharp.Compiler.Tokenization.FSharpTokenCharKind: Int32 value__ +FSharp.Compiler.Tokenization.FSharpTokenColorKind +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Comment +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Default +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Identifier +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind InactiveCode +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Keyword +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Number +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Operator +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind PreprocessorKeyword +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Punctuation +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind String +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind Text +FSharp.Compiler.Tokenization.FSharpTokenColorKind: FSharp.Compiler.Tokenization.FSharpTokenColorKind UpperIdentifier +FSharp.Compiler.Tokenization.FSharpTokenColorKind: Int32 value__ +FSharp.Compiler.Tokenization.FSharpTokenInfo +FSharp.Compiler.Tokenization.FSharpTokenInfo: Boolean Equals(FSharp.Compiler.Tokenization.FSharpTokenInfo) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Boolean Equals(System.Object) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenCharKind CharClass +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenCharKind get_CharClass() +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenColorKind ColorClass +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenColorKind get_ColorClass() +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass FSharpTokenTriggerClass +FSharp.Compiler.Tokenization.FSharpTokenInfo: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass get_FSharpTokenTriggerClass() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 CompareTo(FSharp.Compiler.Tokenization.FSharpTokenInfo) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 CompareTo(System.Object) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 FullMatchedLength +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 GetHashCode() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 LeftColumn +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 RightColumn +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 Tag +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 get_FullMatchedLength() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 get_LeftColumn() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 get_RightColumn() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Int32 get_Tag() +FSharp.Compiler.Tokenization.FSharpTokenInfo: System.String ToString() +FSharp.Compiler.Tokenization.FSharpTokenInfo: System.String TokenName +FSharp.Compiler.Tokenization.FSharpTokenInfo: System.String get_TokenName() +FSharp.Compiler.Tokenization.FSharpTokenInfo: Void .ctor(Int32, Int32, FSharp.Compiler.Tokenization.FSharpTokenColorKind, FSharp.Compiler.Tokenization.FSharpTokenCharKind, FSharp.Compiler.Tokenization.FSharpTokenTriggerClass, Int32, System.String, Int32) +FSharp.Compiler.Tokenization.FSharpTokenKind +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Abstract +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 AdjacentPrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Ampersand +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 AmpersandAmpersand +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 And +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 As +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Asr +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Assert +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Bar +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 BarBar +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 BarRightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 BarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Base +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Begin +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 BigNumber +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Binder +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ByteArray +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Char +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Class +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Colon +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ColonColon +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ColonEquals +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ColonGreater +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ColonQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 ColonQuestionMarkGreater +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Comma +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 CommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Const +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Constraint +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Constructor +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Decimal +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Default +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Delegate +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Do +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 DoBang +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Dollar +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Done +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Dot +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 DotDot +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 DotDotHat +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 DownTo +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Downcast +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Elif +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Else +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 End +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Equals +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Exception +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Extern +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 False +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Finally +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Fixed +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 For +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Fun +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Function +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 FunkyOperatorName +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Global +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Greater +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 GreaterBarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 GreaterRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Hash +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HashElse +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HashEndIf +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HashIf +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HashLight +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HashLine +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HighPrecedenceBracketApp +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HighPrecedenceParenthesisApp +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 HighPrecedenceTypeApp +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Identifier +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Ieee32 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Ieee64 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 If +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 In +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InactiveCode +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixAmpersandOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixAsr +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixAtHatOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixBarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixCompareOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixLand +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixLor +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixLsl +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixLsr +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixLxor +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixMod +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixStarDivideModuloOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 InfixStarStarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Inherit +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Inline +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Instance +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Int16 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Int32 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Int32DotDot +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Int64 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Int8 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Interface +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Internal +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 JoinIn +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 KeywordString +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Lazy +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftArrow +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftBrace +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftBraceBar +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftBracket +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftBracketBar +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftBracketLess +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftParenthesisStarRightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LeftQuote +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Less +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Let +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 LineCommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Match +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 MatchBang +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Member +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Minus +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Module +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Mutable +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Namespace +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 NativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 New +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 None +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Null +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Of +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideAssert +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideBinder +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideBlockBegin +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideBlockSep +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideDeclEnd +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideDo +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideDoBang +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideElse +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideEnd +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideFun +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideFunction +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideInterfaceMember +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideLazy +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideLet +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideReset +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideRightBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideThen +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 OffsideWith +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Open +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Or +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Override +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 PercentOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 PlusMinusOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 PrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Private +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Public +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 QuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 QuestionMarkQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Quote +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Rec +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Reserved +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightArrow +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightQuote +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 RightQuoteDot +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Semicolon +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 SemicolonSemicolon +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Sig +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Star +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Static +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 String +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 StringText +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Struct +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Then +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 To +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 True +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Try +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Type +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 UInt16 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 UInt32 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 UInt64 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 UInt8 +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 UNativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Underscore +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Upcast +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Val +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Void +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 When +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 While +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 WhitespaceTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 With +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 Yield +FSharp.Compiler.Tokenization.FSharpTokenKind+Tags: Int32 YieldBang +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean Equals(FSharp.Compiler.Tokenization.FSharpTokenKind) +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean Equals(System.Object) +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAbstract +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAdjacentPrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAmpersand +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAmpersandAmpersand +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAs +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAsr +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsAssert +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBarBar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBarRightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBase +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBegin +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBigNumber +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsBinder +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsByteArray +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsChar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsClass +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColon +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColonColon +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColonEquals +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColonGreater +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColonQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsColonQuestionMarkGreater +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsComma +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsCommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsConst +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsConstraint +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsConstructor +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDecimal +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDefault +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDelegate +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDo +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDoBang +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDollar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDone +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDot +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDotDot +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDotDotHat +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDownTo +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsDowncast +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsElif +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsElse +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsEquals +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsException +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsExtern +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFalse +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFinally +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFixed +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFor +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFun +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFunction +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsFunkyOperatorName +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsGlobal +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsGreater +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsGreaterBarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsGreaterRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHash +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHashElse +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHashEndIf +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHashIf +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHashLight +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHashLine +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHighPrecedenceBracketApp +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHighPrecedenceParenthesisApp +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsHighPrecedenceTypeApp +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsIdentifier +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsIeee32 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsIeee64 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsIf +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsIn +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInactiveCode +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixAmpersandOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixAsr +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixAtHatOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixBarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixCompareOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixLand +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixLor +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixLsl +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixLsr +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixLxor +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixMod +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixStarDivideModuloOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInfixStarStarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInherit +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInline +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInstance +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInt16 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInt32 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInt32DotDot +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInt64 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInt8 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInterface +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsInternal +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsJoinIn +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsKeywordString +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLazy +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftArrow +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftBraceBar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftBracketBar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftBracketLess +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftParenthesisStarRightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLeftQuote +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLess +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLet +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsLineCommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsMatch +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsMatchBang +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsMember +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsMinus +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsModule +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsMutable +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsNamespace +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsNativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsNew +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsNone +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsNull +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOf +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideAssert +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideBinder +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideBlockBegin +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideBlockSep +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideDeclEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideDo +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideDoBang +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideElse +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideFun +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideFunction +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideInterfaceMember +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideLazy +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideLet +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideReset +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideRightBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideThen +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOffsideWith +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOpen +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOr +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsOverride +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsPercentOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsPlusMinusOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsPrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsPrivate +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsPublic +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsQuestionMarkQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsQuote +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRec +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsReserved +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightArrow +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightQuote +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsRightQuoteDot +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsSemicolon +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsSemicolonSemicolon +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsSig +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsStar +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsStatic +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsString +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsStringText +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsStruct +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsThen +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsTo +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsTrue +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsTry +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsType +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUInt16 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUInt32 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUInt64 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUInt8 +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUNativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUnderscore +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsUpcast +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsVal +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsVoid +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsWhen +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsWhile +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsWhitespaceTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsWith +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsYield +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean IsYieldBang +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAbstract() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAdjacentPrefixOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAmpersand() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAmpersandAmpersand() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAs() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAsr() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsAssert() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBarBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBarRightBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBarRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBase() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBegin() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBigNumber() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsBinder() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsByteArray() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsChar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsClass() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColon() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColonColon() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColonEquals() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColonGreater() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColonQuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsColonQuestionMarkGreater() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsComma() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsCommentTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsConst() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsConstraint() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsConstructor() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDecimal() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDefault() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDelegate() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDo() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDoBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDollar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDone() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDotDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDotDotHat() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDownTo() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsDowncast() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsElif() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsElse() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsEquals() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsException() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsExtern() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFalse() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFinally() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFixed() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFor() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFun() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFunction() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsFunkyOperatorName() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsGlobal() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsGreater() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsGreaterBarRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsGreaterRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHash() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHashElse() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHashEndIf() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHashIf() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHashLight() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHashLine() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHighPrecedenceBracketApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHighPrecedenceParenthesisApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsHighPrecedenceTypeApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsIdentifier() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsIeee32() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsIeee64() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsIf() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsIn() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInactiveCode() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixAmpersandOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixAsr() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixAtHatOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixBarOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixCompareOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixLand() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixLor() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixLsl() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixLsr() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixLxor() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixMod() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixStarDivideModuloOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInfixStarStarOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInherit() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInline() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInstance() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInt16() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInt32() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInt32DotDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInt64() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInt8() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInterface() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsInternal() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsJoinIn() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsKeywordString() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLazy() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftArrow() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftBraceBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftBracketBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftBracketLess() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftParenthesisStarRightParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLeftQuote() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLess() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLet() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsLineCommentTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsMatch() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsMatchBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsMember() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsMinus() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsModule() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsMutable() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsNamespace() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsNativeInt() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsNew() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsNone() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsNull() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOf() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideAssert() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideBinder() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideBlockBegin() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideBlockEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideBlockSep() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideDeclEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideDo() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideDoBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideElse() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideFun() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideFunction() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideInterfaceMember() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideLazy() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideLet() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideReset() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideRightBlockEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideThen() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOffsideWith() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOpen() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOr() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsOverride() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsPercentOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsPlusMinusOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsPrefixOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsPrivate() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsPublic() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsQuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsQuestionMarkQuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsQuote() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRec() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsReserved() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightArrow() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightQuote() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsRightQuoteDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsSemicolon() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsSemicolonSemicolon() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsSig() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsStar() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsStatic() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsString() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsStringText() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsStruct() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsThen() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsTo() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsTrue() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsTry() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsType() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUInt16() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUInt32() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUInt64() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUInt8() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUNativeInt() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUnderscore() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsUpcast() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsVal() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsVoid() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsWhen() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsWhile() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsWhitespaceTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsWith() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsYield() +FSharp.Compiler.Tokenization.FSharpTokenKind: Boolean get_IsYieldBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Abstract +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind AdjacentPrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Ampersand +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind AmpersandAmpersand +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind And +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind As +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Asr +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Assert +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Bar +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind BarBar +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind BarRightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind BarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Base +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Begin +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind BigNumber +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Binder +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ByteArray +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Char +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Class +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Colon +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ColonColon +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ColonEquals +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ColonGreater +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ColonQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind ColonQuestionMarkGreater +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Comma +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind CommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Const +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Constraint +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Constructor +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Decimal +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Default +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Delegate +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Do +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind DoBang +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Dollar +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Done +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Dot +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind DotDot +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind DotDotHat +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind DownTo +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Downcast +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Elif +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Else +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind End +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Equals +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Exception +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Extern +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind False +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Finally +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Fixed +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind For +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Fun +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Function +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind FunkyOperatorName +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Global +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Greater +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind GreaterBarRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind GreaterRightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Hash +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HashElse +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HashEndIf +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HashIf +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HashLight +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HashLine +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HighPrecedenceBracketApp +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HighPrecedenceParenthesisApp +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind HighPrecedenceTypeApp +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Identifier +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Ieee32 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Ieee64 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind If +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind In +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InactiveCode +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixAmpersandOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixAsr +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixAtHatOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixBarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixCompareOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixLand +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixLor +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixLsl +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixLsr +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixLxor +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixMod +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixStarDivideModuloOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind InfixStarStarOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Inherit +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Inline +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Instance +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Int16 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Int32 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Int32DotDot +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Int64 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Int8 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Interface +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Internal +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind JoinIn +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind KeywordString +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Lazy +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftArrow +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftBraceBar +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftBracketBar +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftBracketLess +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftParenthesisStarRightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LeftQuote +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Less +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Let +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind LineCommentTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Match +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind MatchBang +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Member +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Minus +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Module +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Mutable +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Namespace +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind NativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind New +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind None +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Null +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Of +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideAssert +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideBinder +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideBlockBegin +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideBlockSep +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideDeclEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideDo +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideDoBang +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideElse +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideFun +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideFunction +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideInterfaceMember +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideLazy +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideLet +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideReset +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideRightBlockEnd +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideThen +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind OffsideWith +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Open +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Or +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Override +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind PercentOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind PlusMinusOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind PrefixOperator +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Private +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Public +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind QuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind QuestionMarkQuestionMark +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Quote +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Rec +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Reserved +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightArrow +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightBrace +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightBracket +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightParenthesis +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightQuote +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind RightQuoteDot +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Semicolon +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind SemicolonSemicolon +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Sig +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Star +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Static +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind String +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind StringText +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Struct +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Then +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind To +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind True +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Try +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Type +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind UInt16 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind UInt32 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind UInt64 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind UInt8 +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind UNativeInt +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Underscore +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Upcast +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Val +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Void +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind When +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind While +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind WhitespaceTrivia +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind With +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind Yield +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind YieldBang +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Abstract() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_AdjacentPrefixOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Ampersand() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_AmpersandAmpersand() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_And() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_As() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Asr() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Assert() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Bar() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_BarBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_BarRightBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_BarRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Base() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Begin() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_BigNumber() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Binder() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ByteArray() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Char() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Class() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Colon() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ColonColon() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ColonEquals() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ColonGreater() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ColonQuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_ColonQuestionMarkGreater() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Comma() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_CommentTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Const() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Constraint() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Constructor() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Decimal() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Default() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Delegate() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Do() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_DoBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Dollar() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Done() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Dot() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_DotDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_DotDotHat() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_DownTo() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Downcast() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Elif() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Else() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_End() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Equals() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Exception() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Extern() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_False() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Finally() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Fixed() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_For() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Fun() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Function() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_FunkyOperatorName() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Global() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Greater() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_GreaterBarRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_GreaterRightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Hash() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HashElse() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HashEndIf() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HashIf() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HashLight() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HashLine() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HighPrecedenceBracketApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HighPrecedenceParenthesisApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_HighPrecedenceTypeApp() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Identifier() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Ieee32() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Ieee64() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_If() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_In() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InactiveCode() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixAmpersandOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixAsr() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixAtHatOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixBarOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixCompareOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixLand() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixLor() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixLsl() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixLsr() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixLxor() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixMod() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixStarDivideModuloOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_InfixStarStarOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Inherit() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Inline() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Instance() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Int16() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Int32() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Int32DotDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Int64() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Int8() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Interface() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Internal() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_JoinIn() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_KeywordString() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Lazy() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftArrow() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftBraceBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftBracketBar() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftBracketLess() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftParenthesisStarRightParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LeftQuote() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Less() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Let() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_LineCommentTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Match() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_MatchBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Member() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Minus() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Module() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Mutable() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Namespace() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_NativeInt() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_New() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_None() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Null() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Of() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideAssert() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideBinder() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideBlockBegin() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideBlockEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideBlockSep() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideDeclEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideDo() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideDoBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideElse() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideFun() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideFunction() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideInterfaceMember() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideLazy() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideLet() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideReset() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideRightBlockEnd() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideThen() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_OffsideWith() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Open() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Or() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Override() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_PercentOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_PlusMinusOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_PrefixOperator() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Private() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Public() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_QuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_QuestionMarkQuestionMark() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Quote() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Rec() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Reserved() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightArrow() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightBrace() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightBracket() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightParenthesis() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightQuote() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_RightQuoteDot() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Semicolon() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_SemicolonSemicolon() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Sig() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Star() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Static() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_String() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_StringText() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Struct() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Then() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_To() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_True() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Try() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Type() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_UInt16() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_UInt32() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_UInt64() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_UInt8() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_UNativeInt() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Underscore() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Upcast() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Val() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Void() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_When() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_While() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_WhitespaceTrivia() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_With() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_Yield() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind get_YieldBang() +FSharp.Compiler.Tokenization.FSharpTokenKind: FSharp.Compiler.Tokenization.FSharpTokenKind+Tags +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 CompareTo(FSharp.Compiler.Tokenization.FSharpTokenKind) +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 CompareTo(System.Object) +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 CompareTo(System.Object, System.Collections.IComparer) +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 GetHashCode() +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 Tag +FSharp.Compiler.Tokenization.FSharpTokenKind: Int32 get_Tag() +FSharp.Compiler.Tokenization.FSharpTokenKind: System.String ToString() +FSharp.Compiler.Tokenization.FSharpTokenTag +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 AMP_AMP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 BAR +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 BAR_BAR +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 BAR_RBRACK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 BEGIN +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 CLASS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON_COLON +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON_EQUALS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON_GREATER +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON_QMARK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COLON_QMARK_GREATER +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COMMA +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 COMMENT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 DO +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 DOT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 DOT_DOT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 DOT_DOT_HAT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 ELSE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 EQUALS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 FUNCTION +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 GREATER +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 GREATER_RBRACK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 IDENT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INFIX_AT_HAT_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INFIX_BAR_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INFIX_COMPARE_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INFIX_STAR_DIV_MOD_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INT32_DOT_DOT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INTERP_STRING_BEGIN_END +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INTERP_STRING_BEGIN_PART +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INTERP_STRING_END +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 INTERP_STRING_PART +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 Identifier +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LARROW +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LBRACE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LBRACK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LBRACK_BAR +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LBRACK_LESS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LESS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LINE_COMMENT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 LPAREN +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 MINUS +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 NEW +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 OWITH +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 PERCENT_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 PLUS_MINUS_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 PREFIX_OP +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 QMARK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 QUOTE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 RARROW +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 RBRACE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 RBRACK +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 RPAREN +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 SEMICOLON +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 STAR +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 STRING +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 STRUCT +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 String +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 THEN +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 TRY +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 UNDERSCORE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 WHITESPACE +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 WITH +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_AMP_AMP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_BAR() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_BAR_BAR() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_BAR_RBRACK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_BEGIN() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_CLASS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON_COLON() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON_EQUALS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON_GREATER() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON_QMARK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COLON_QMARK_GREATER() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COMMA() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_COMMENT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_DO() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_DOT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_DOT_DOT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_DOT_DOT_HAT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_ELSE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_EQUALS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_FUNCTION() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_GREATER() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_GREATER_RBRACK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_IDENT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INFIX_AT_HAT_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INFIX_BAR_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INFIX_COMPARE_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INFIX_STAR_DIV_MOD_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INT32_DOT_DOT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INTERP_STRING_BEGIN_END() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INTERP_STRING_BEGIN_PART() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INTERP_STRING_END() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_INTERP_STRING_PART() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_Identifier() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LARROW() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LBRACE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LBRACK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LBRACK_BAR() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LBRACK_LESS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LESS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LINE_COMMENT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_LPAREN() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_MINUS() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_NEW() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_OWITH() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_PERCENT_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_PLUS_MINUS_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_PREFIX_OP() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_QMARK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_QUOTE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_RARROW() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_RBRACE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_RBRACK() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_RPAREN() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_SEMICOLON() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_STAR() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_STRING() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_STRUCT() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_String() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_THEN() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_TRY() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_UNDERSCORE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_WHITESPACE() +FSharp.Compiler.Tokenization.FSharpTokenTag: Int32 get_WITH() +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass ChoiceSelect +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass MatchBraces +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass MemberSelect +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass MethodTip +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass None +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass ParamEnd +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass ParamNext +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: FSharp.Compiler.Tokenization.FSharpTokenTriggerClass ParamStart +FSharp.Compiler.Tokenization.FSharpTokenTriggerClass: Int32 value__ +FSharp.Compiler.Tokenization.FSharpTokenizerColorState +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState CamlOnly +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState Comment +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState EndLineThenSkip +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState EndLineThenToken +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState IfDefSkip +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState InitialState +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState SingleLineComment +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState String +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState StringInComment +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState Token +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState TripleQuoteString +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState TripleQuoteStringInComment +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState VerbatimString +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: FSharp.Compiler.Tokenization.FSharpTokenizerColorState VerbatimStringInComment +FSharp.Compiler.Tokenization.FSharpTokenizerColorState: Int32 value__ +FSharp.Compiler.Tokenization.FSharpTokenizerLexState +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Boolean Equals(FSharp.Compiler.Tokenization.FSharpTokenizerLexState) +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Boolean Equals(System.Object) +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: FSharp.Compiler.Tokenization.FSharpTokenizerLexState Initial +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: FSharp.Compiler.Tokenization.FSharpTokenizerLexState get_Initial() +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Int32 GetHashCode() +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Int64 OtherBits +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Int64 PosBits +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Int64 get_OtherBits() +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Int64 get_PosBits() +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: System.String ToString() +FSharp.Compiler.Tokenization.FSharpTokenizerLexState: Void .ctor(Int64, Int64) +FSharp.Compiler.TypeProviderError +FSharp.Compiler.TypeProviderError: FSharp.Compiler.Text.Range Range +FSharp.Compiler.TypeProviderError: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.TypeProviderError: FSharp.Compiler.TypeProviderError MapText(Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Tuple`2[System.Int32,System.String]], System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.TypeProviderError: FSharp.Compiler.TypeProviderError WithContext(System.String, System.String) +FSharp.Compiler.TypeProviderError: Int32 Number +FSharp.Compiler.TypeProviderError: Int32 get_Number() +FSharp.Compiler.TypeProviderError: System.String ContextualErrorMessage +FSharp.Compiler.TypeProviderError: System.String Message +FSharp.Compiler.TypeProviderError: System.String get_ContextualErrorMessage() +FSharp.Compiler.TypeProviderError: System.String get_Message() +FSharp.Compiler.TypeProviderError: Void .ctor(Int32, System.String, FSharp.Compiler.Text.Range, System.Collections.Generic.IEnumerable`1[System.String]) +FSharp.Compiler.TypeProviderError: Void .ctor(System.Tuple`2[System.Int32,System.String], System.String, FSharp.Compiler.Text.Range) +FSharp.Compiler.TypeProviderError: Void Iter(Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.TypeProviderError,Microsoft.FSharp.Core.Unit]) +FSharp.Compiler.Xml.PreXmlDoc +FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(FSharp.Compiler.Xml.PreXmlDoc) +FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(System.Object) +FSharp.Compiler.Xml.PreXmlDoc: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Create(System.String[], FSharp.Compiler.Text.Range) +FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Empty +FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc Merge(FSharp.Compiler.Xml.PreXmlDoc, FSharp.Compiler.Xml.PreXmlDoc) +FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.PreXmlDoc get_Empty() +FSharp.Compiler.Xml.PreXmlDoc: FSharp.Compiler.Xml.XmlDoc ToXmlDoc(Boolean, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]]) +FSharp.Compiler.Xml.PreXmlDoc: Int32 GetHashCode() +FSharp.Compiler.Xml.PreXmlDoc: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.Xml.PreXmlDoc: System.String ToString() +FSharp.Compiler.Xml.XmlDoc +FSharp.Compiler.Xml.XmlDoc: Boolean IsEmpty +FSharp.Compiler.Xml.XmlDoc: Boolean NonEmpty +FSharp.Compiler.Xml.XmlDoc: Boolean get_IsEmpty() +FSharp.Compiler.Xml.XmlDoc: Boolean get_NonEmpty() +FSharp.Compiler.Xml.XmlDoc: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Xml.XmlDoc: FSharp.Compiler.Text.Range get_Range() +FSharp.Compiler.Xml.XmlDoc: FSharp.Compiler.Xml.XmlDoc Empty +FSharp.Compiler.Xml.XmlDoc: FSharp.Compiler.Xml.XmlDoc Merge(FSharp.Compiler.Xml.XmlDoc, FSharp.Compiler.Xml.XmlDoc) +FSharp.Compiler.Xml.XmlDoc: FSharp.Compiler.Xml.XmlDoc get_Empty() +FSharp.Compiler.Xml.XmlDoc: System.String GetXmlText() +FSharp.Compiler.Xml.XmlDoc: System.String[] GetElaboratedXmlLines() +FSharp.Compiler.Xml.XmlDoc: System.String[] UnprocessedLines +FSharp.Compiler.Xml.XmlDoc: System.String[] get_UnprocessedLines() +FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range) \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/LibraryTestFx.fs b/tests/FSharp.Compiler.Service.Tests/LibraryTestFx.fs new file mode 100644 index 00000000000..c20e8471597 --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/LibraryTestFx.fs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module Tests.Service.SurfaceArea.LibraryTestFx + +open System +open System.IO +open System.Reflection +open System.Text.RegularExpressions + +open FSharp.Compiler.IO + +open NUnit.Framework + +// Verifies two sequences are equal (same length, equiv elements) +let VerifySeqsEqual (seq1 : seq<'T>) (seq2 : seq<'T>) = + Assert.Equals(seq1, seq2) + +let sleep(n : int32) = + System.Threading.Thread.Sleep(n) + +module SurfaceArea = + + // gets string form of public surface area for FSharp.CompilerService + let private getActual () = + + // get local FSharp.CompilerService + let path = Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "FSharp.Compiler.Service.dll") + let name = AssemblyName.GetAssemblyName path + let asm = Assembly.Load(name) + + // public types only + let types = asm.ExportedTypes |> Seq.filter (fun ty -> let ti = ty.GetTypeInfo() in ti.IsPublic || ti.IsNestedPublic) |> Array.ofSeq + + // extract canonical string form for every public member of every type + let getTypeMemberStrings (t : Type) = + // for System.Runtime-based profiles, need to do lots of manual work + let getMembers (t : Type) = + let ti = t.GetTypeInfo() + let cast (info: #MemberInfo) = (t, info :> MemberInfo) + seq { + yield! ti.DeclaredEvents |> Seq.filter (fun m -> m.AddMethod.IsPublic) |> Seq.map cast + yield! ti.DeclaredProperties |> Seq.filter (fun m -> m.GetMethod.IsPublic) |> Seq.map cast + yield! ti.DeclaredMethods |> Seq.filter (fun m -> m.IsPublic) |> Seq.map cast + yield! ti.DeclaredFields |> Seq.filter (fun m -> m.IsPublic) |> Seq.map cast + yield! ti.DeclaredConstructors |> Seq.filter (fun m -> m.IsPublic) |> Seq.map cast + yield! ti.DeclaredNestedTypes |> Seq.filter (fun ty -> ty.IsNestedPublic) |> Seq.map cast + } |> Array.ofSeq + + [| for ty,m in getMembers t do + yield sprintf "%s: %s" (ty.ToString()) (m.ToString()) + if not t.IsNested then + yield t.ToString() + |] + + let actual = + types + |> Array.collect getTypeMemberStrings + |> Array.sort + |> String.concat Environment.NewLine + asm, actual + + // verify public surface area matches expected + let verify expectedFile actualFile = + let normalize text = Regex.Replace(text, "(\\r\\n|\\n|\\r)+", "\r\n").Trim() + let _asm, actual = getActual () + let actual = normalize actual + let expected = normalize (System.IO.File.ReadAllText expectedFile) + match Tests.TestHelpers.assembleDiffMessage actual expected with + | None -> () + | Some diff -> + FileSystem + .OpenFileForWriteShim(actualFile) + .WriteAllText(actual) + + failwith + $"surface area defined in\n\n{expectedFile}\n\ndoesn't match actual in\n\n{actualFile}\n\nCompare the files and adjust accordingly. + {diff}" \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs new file mode 100644 index 00000000000..d4a78ca1041 --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Tests.Service.SurfaceArea + +open Tests.Service.SurfaceArea.LibraryTestFx +open NUnit.Framework + +type SurfaceAreaTest() = + [] + member _.VerifyArea() = + let expectedFile = System.IO.Path.Combine(__SOURCE_DIRECTORY__,"FSharp.CompilerService.SurfaceArea.netstandard.expected") + let actualFile = System.IO.Path.Combine(__SOURCE_DIRECTORY__,"FSharp.CompilerService.SurfaceArea.netstandard.actual") + SurfaceArea.verify expectedFile actualFile diff --git a/fcs/FSharp.Compiler.Service.Tests/app.runsettings b/tests/FSharp.Compiler.Service.Tests/app.runsettings similarity index 100% rename from fcs/FSharp.Compiler.Service.Tests/app.runsettings rename to tests/FSharp.Compiler.Service.Tests/app.runsettings diff --git a/tests/FSharp.Compiler.UnitTests/AssemblySigningAttributes.fs b/tests/FSharp.Compiler.UnitTests/AssemblySigningAttributes.fs new file mode 100644 index 00000000000..333dd3c6a9a --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/AssemblySigningAttributes.fs @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Test.Xunit.Attributes + +module AssemblySigning = + +#if !NETCOREAPP + [] +#endif + let ``--keycontainer:name DESKTOP`` () = + FSharp """ +module SignMe + +open System +open System.Reflection + + """ + |> withOptions ["--keycontainer:myContainer"] + |> compile + |> shouldFail + |> withWarningCode 0075 + |> withDiagnosticMessageMatches "The command-line option '--keycontainer' has been deprecated. Use '--keyfile' instead." + |> ignore + +#if NETCOREAPP + [] +#endif + let ``--keycontainer:name NETCOREAPP`` () = + FSharp """ +module SignMe + +open System +open System.Reflection + + """ + |> withOptions ["--keycontainer:myContainer"] + |> compile + |> shouldFail + |> withErrorCode 3393 + |> withDiagnosticMessageMatches "Key container signing is not supported on this platform." + |> ignore + + //Expects: warning FS3392: The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. +#if !NETCOREAPP + [] +#endif + let ``AssemblyKeyNameAttribute DESKTOP`` () = + FSharp """ +module SignMe + +open System +open System.Reflection + +[] +do () + """ + |> asFs + |> compile + |> shouldFail + |> withWarningCode 3392 + |> withDiagnosticMessageMatches "The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead." + |> ignore + + //Expects: warning FS3392: The 'AssemblyKeyNameAttribute' has been deprecated. Use 'AssemblyKeyFileAttribute' instead. +#if NETCOREAPP + [] +#endif + let ``AssemblyKeyNameAttribute NETCOREAPP`` () = + FSharp """ +module SignMe + +open System +open System.Reflection + +[] +do () + """ + |> asFs + |> compile + |> shouldFail + |> withErrorCode 2014 + |> withDiagnosticMessageMatches "A call to StrongNameGetPublicKey failed" + |> ignore diff --git a/tests/FSharp.Compiler.UnitTests/BlockTests.fs b/tests/FSharp.Compiler.UnitTests/BlockTests.fs new file mode 100644 index 00000000000..08a718f5244 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/BlockTests.fs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.UnitTests + +open Xunit +open FSharp.Test +open Internal.Utilities.Library + +module BlockTests = + + [] + let ``Iter should work correctly``() = + let b = Block.init 5 id + + let results = ResizeArray() + b + |> Block.iter (fun x -> + results.Add(x) + ) + + Assert.Equal( + [ + 0 + 1 + 2 + 3 + 4 + ], + results + ) + + [] + let ``Map should work correctly``() = + let b = Block.init 5 id + + let b2 = b |> Block.map (fun x -> x + 1) + + Assert.Equal( + [ + 1 + 2 + 3 + 4 + 5 + ], + b2 + ) + + [] + let ``Fold should work correctly``() = + let b = Block.init 5 id + + let result = + (0, b) + ||> Block.fold (fun state n -> + state + n + ) + + Assert.Equal(10, result) \ No newline at end of file diff --git a/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs new file mode 100644 index 00000000000..ae2aeff2071 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs @@ -0,0 +1,274 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.UnitTests + +open System +open System.Threading +open System.Runtime.CompilerServices +open Xunit +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Compiler.BuildGraph +open Internal.Utilities.Library + +module BuildGraphTests = + + [] + let private createNode () = + let o = obj () + GraphNode(node { + Assert.shouldBeTrue (o <> null) + return 1 + }), WeakReference(o) + + [] + let ``Intialization of graph node should not have a computed value``() = + let node = GraphNode(node { return 1 }) + Assert.shouldBeTrue(node.TryPeekValue().IsNone) + Assert.shouldBeFalse(node.HasValue) + + [] + let ``Two requests to get a value asynchronously should be successful``() = + let resetEvent = new ManualResetEvent(false) + let resetEventInAsync = new ManualResetEvent(false) + + let graphNode = + GraphNode(node { + resetEventInAsync.Set() |> ignore + let! _ = NodeCode.AwaitWaitHandle_ForTesting(resetEvent) + return 1 + }) + + let task1 = + node { + let! _ = graphNode.GetOrComputeValue() + () + } |> NodeCode.StartAsTask_ForTesting + + let task2 = + node { + let! _ = graphNode.GetOrComputeValue() + () + } |> NodeCode.StartAsTask_ForTesting + + resetEventInAsync.WaitOne() |> ignore + resetEvent.Set() |> ignore + try + task1.Wait(1000) |> ignore + task2.Wait() |> ignore + with + | :? TimeoutException -> reraise() + | _ -> () + + [] + let ``Many requests to get a value asynchronously should only evaluate the computation once``() = + let requests = 10000 + let mutable computationCount = 0 + + let graphNode = + GraphNode(node { + computationCount <- computationCount + 1 + return 1 + }) + + let work = Async.Parallel(Array.init requests (fun _ -> graphNode.GetOrComputeValue() |> Async.AwaitNodeCode)) + + Async.RunImmediate(work) + |> ignore + + Assert.shouldBe 1 computationCount + + [] + let ``Many requests to get a value asynchronously should get the correct value``() = + let requests = 10000 + + let graphNode = GraphNode(node { return 1 }) + + let work = Async.Parallel(Array.init requests (fun _ -> graphNode.GetOrComputeValue() |> Async.AwaitNodeCode)) + + let result = Async.RunImmediate(work) + + Assert.shouldNotBeEmpty result + Assert.shouldBe requests result.Length + result + |> Seq.iter (Assert.shouldBe 1) + + [] + let ``A request to get a value asynchronously should have its computation cleaned up by the GC``() = + let graphNode, weak = createNode () + + GC.Collect(2, GCCollectionMode.Forced, true) + + Assert.shouldBeTrue weak.IsAlive + + NodeCode.RunImmediateWithoutCancellation(graphNode.GetOrComputeValue()) + |> ignore + + GC.Collect(2, GCCollectionMode.Forced, true) + + Assert.shouldBeFalse weak.IsAlive + + [] + let ``Many requests to get a value asynchronously should have its computation cleaned up by the GC``() = + let requests = 10000 + + let graphNode, weak = createNode () + + GC.Collect(2, GCCollectionMode.Forced, true) + + Assert.shouldBeTrue weak.IsAlive + + Async.RunImmediate(Async.Parallel(Array.init requests (fun _ -> graphNode.GetOrComputeValue() |> Async.AwaitNodeCode))) + |> ignore + + GC.Collect(2, GCCollectionMode.Forced, true) + + Assert.shouldBeFalse weak.IsAlive + + [] + let ``A request can cancel``() = + let graphNode = + GraphNode(node { + return 1 + }) + + use cts = new CancellationTokenSource() + + let work = + node { + cts.Cancel() + return! graphNode.GetOrComputeValue() + } + + let ex = + try + NodeCode.RunImmediate(work, ct = cts.Token) + |> ignore + failwith "Should have canceled" + with + | :? OperationCanceledException as ex -> + ex + + Assert.shouldBeTrue(ex <> null) + + [] + let ``A request can cancel 2``() = + let resetEvent = new ManualResetEvent(false) + + let graphNode = + GraphNode(node { + let! _ = NodeCode.AwaitWaitHandle_ForTesting(resetEvent) + return 1 + }) + + use cts = new CancellationTokenSource() + + let task = + node { + cts.Cancel() + resetEvent.Set() |> ignore + } + |> NodeCode.StartAsTask_ForTesting + + let ex = + try + NodeCode.RunImmediate(graphNode.GetOrComputeValue(), ct = cts.Token) + |> ignore + failwith "Should have canceled" + with + | :? OperationCanceledException as ex -> + ex + + Assert.shouldBeTrue(ex <> null) + try task.Wait(1000) |> ignore with | :? TimeoutException -> reraise() | _ -> () + + [] + let ``Many requests to get a value asynchronously might evaluate the computation more than once even when some requests get canceled``() = + let requests = 10000 + let resetEvent = new ManualResetEvent(false) + let mutable computationCountBeforeSleep = 0 + let mutable computationCount = 0 + + let graphNode = + GraphNode(node { + computationCountBeforeSleep <- computationCountBeforeSleep + 1 + let! _ = NodeCode.AwaitWaitHandle_ForTesting(resetEvent) + computationCount <- computationCount + 1 + return 1 + }) + + use cts = new CancellationTokenSource() + + let work = + node { + let! _ = graphNode.GetOrComputeValue() + () + } + + let tasks = ResizeArray() + + for i = 0 to requests - 1 do + if i % 10 = 0 then + NodeCode.StartAsTask_ForTesting(work, ct = cts.Token) + |> tasks.Add + else + NodeCode.StartAsTask_ForTesting(work) + |> tasks.Add + + cts.Cancel() + resetEvent.Set() |> ignore + NodeCode.RunImmediateWithoutCancellation(work) + |> ignore + + Assert.shouldBeTrue cts.IsCancellationRequested + Assert.shouldBeTrue(computationCountBeforeSleep > 0) + Assert.shouldBeTrue(computationCount >= 0) + + tasks + |> Seq.iter (fun x -> + try x.Wait(1000) |> ignore with | :? TimeoutException -> reraise() | _ -> ()) + + [] + let ``No-RetryCompute - Many requests to get a value asynchronously should only evaluate the computation once even when some requests get canceled``() = + let requests = 10000 + let resetEvent = new ManualResetEvent(false) + let mutable computationCountBeforeSleep = 0 + let mutable computationCount = 0 + + let graphNode = + GraphNode(false, node { + computationCountBeforeSleep <- computationCountBeforeSleep + 1 + let! _ = NodeCode.AwaitWaitHandle_ForTesting(resetEvent) + computationCount <- computationCount + 1 + return 1 + }) + + use cts = new CancellationTokenSource() + + let work = + node { + let! _ = graphNode.GetOrComputeValue() + () + } + + let tasks = ResizeArray() + + for i = 0 to requests - 1 do + if i % 10 = 0 then + NodeCode.StartAsTask_ForTesting(work, ct = cts.Token) + |> tasks.Add + else + NodeCode.StartAsTask_ForTesting(work) + |> tasks.Add + + cts.Cancel() + resetEvent.Set() |> ignore + NodeCode.RunImmediateWithoutCancellation(work) + |> ignore + + Assert.shouldBeTrue cts.IsCancellationRequested + Assert.shouldBe 1 computationCountBeforeSleep + Assert.shouldBe 1 computationCount + + tasks + |> Seq.iter (fun x -> + try x.Wait(1000) |> ignore with | :? TimeoutException -> reraise() | _ -> ()) diff --git a/tests/FSharp.Compiler.UnitTests/ByteMemoryTests.fs b/tests/FSharp.Compiler.UnitTests/ByteMemoryTests.fs new file mode 100644 index 00000000000..6a46f5ce74f --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/ByteMemoryTests.fs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.UnitTests + +open System +open System.Globalization +open Xunit +open FSharp.Test + +module ByteMemoryTests = + open FSharp.Compiler.IO + + [] + let ``ByteMemory.CreateMemoryMappedFile succeeds with byte length of zero``() = + let memory = ByteMemory.Empty.AsReadOnly() + let newMemory = ByteStorage.FromByteMemoryAndCopy(memory, useBackingMemoryMappedFile = true).GetByteMemory() + Assert.shouldBe(0, newMemory.Length) diff --git a/tests/FSharp.Compiler.UnitTests/CompilerTestHelpers.fs b/tests/FSharp.Compiler.UnitTests/CompilerTestHelpers.fs index 1ac573a84e2..bc4b3f9f0bc 100644 --- a/tests/FSharp.Compiler.UnitTests/CompilerTestHelpers.fs +++ b/tests/FSharp.Compiler.UnitTests/CompilerTestHelpers.fs @@ -6,5 +6,4 @@ module CompilerTestHelpers = let (|Warning|_|) (exn: System.Exception) = match exn with | :? FSharp.Compiler.ErrorLogger.Error as e -> let n,d = e.Data0 in Some (n,d) - | :? FSharp.Compiler.ErrorLogger.NumberedError as e -> let n,d = e.Data0 in Some (n,d) | _ -> None diff --git a/tests/FSharp.Compiler.UnitTests/EditDistance.fs b/tests/FSharp.Compiler.UnitTests/EditDistance.fs index ffcac4bc775..1e00cc05935 100644 --- a/tests/FSharp.Compiler.UnitTests/EditDistance.fs +++ b/tests/FSharp.Compiler.UnitTests/EditDistance.fs @@ -3,23 +3,25 @@ namespace FSharp.Compiler.UnitTests open System open System.Globalization -open NUnit.Framework +open Xunit +open FSharp.Test -[] module EditDistance = open Internal.Utilities.EditDistance - [] - [] - [] - [] - [] - let JaroWinklerTest (str1 : string, str2 : string) : string = + [] + [] + [] + [] + [] + let JaroWinklerTest (str1 : string, str2 : string, expected : string) : unit = String.Format(CultureInfo.InvariantCulture, "{0:0.000}", JaroWinklerDistance str1 str2) + |> Assert.shouldBe expected - [] - [] - [] - [] - let EditDistanceTest (str1 : string, str2 : string) : int = - CalcEditDistance(str1,str2) \ No newline at end of file + [] + [] + [] + [] + let EditDistanceTest (str1 : string, str2 : string, expected : int) : unit = + CalcEditDistance(str1,str2) + |> Assert.shouldBe expected diff --git a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj index 790fdc64317..ee836d5942f 100644 --- a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj +++ b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj @@ -3,26 +3,88 @@ - net472;netcoreapp3.0 - netcoreapp3.0 + net472;net5.0 + net5.0 Library true - nunit + $(DefineConstants);ASSUME_PREVIEW_FSHARP_CORE + xunit - - + + + + + + + + + + + + CompilerService\FsUnit.fs + + + CompilerService\Common.fs + + + CompilerService\Symbols.fs + + + CompilerService\EditorTests.fs + + + CompilerService\FileSystemTests.fs + + + CompilerService\ProjectAnalysisTests.fs + + + CompilerService\TokenizerTests.fs + + + + CompilerService\PerfTests.fs + + + CompilerService\InteractiveCheckerTests.fs + + + CompilerService\ExprTests.fs + + + CompilerService\CSharpProjectAnalysis.fs + + + CompilerService\StructureTests.fs + + + CompilerService\AssemblyContentProviderTests.fs + + + CompilerService\ServiceUntypedParseTests.fs + + + CompilerService\TreeVisitorTests.fs + - + + + + diff --git a/tests/FSharp.Compiler.UnitTests/FsiTests.fs b/tests/FSharp.Compiler.UnitTests/FsiTests.fs new file mode 100644 index 00000000000..68ea2fea182 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/FsiTests.fs @@ -0,0 +1,546 @@ +namespace FSharp.Compiler.UnitTests +open System +open System.IO +open FSharp.Compiler.Interactive.Shell +open Xunit +open FSharp.Test + +[] +module FsiTests = + + let createFsiSession () = + // Intialize output and input streams + let inStream = new StringReader("") + let outStream = new CompilerOutputStream() + let errStream = new CompilerOutputStream() + + // Build command line arguments & start FSI session + let argv = [| "C:\\fsi.exe" |] + let allArgs = Array.append argv [|"--noninteractive"|] + + let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() + FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, new StreamWriter(outStream), new StreamWriter(errStream), collectible = true) + + [] + let ``No bound values at the start of FSI session`` () = + use fsiSession = createFsiSession () + let values = fsiSession.GetBoundValues() + Assert.shouldBeEmpty values + + [] + let ``Bound value has correct name`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + + [] + let ``Bound value has correct value`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let y = 2") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe 2 boundValue.Value.ReflectionValue + + [] + let ``Bound value has correct type`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let z = 3") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Seven bound values are ordered and have their correct name`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let y = 2") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4") + fsiSession.EvalInteraction("let ccc = 5") + fsiSession.EvalInteraction("let b = 6") + fsiSession.EvalInteraction("let aa = 7") + + let names = fsiSession.GetBoundValues() |> List.map (fun x -> x.Name) + + Assert.shouldBe ["a";"aa";"b";"ccc";"x";"y";"z"] names + + [] + let ``Seven bound values are ordered and have their correct value`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let y = 2") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4") + fsiSession.EvalInteraction("let ccc = 5") + fsiSession.EvalInteraction("let b = 6") + fsiSession.EvalInteraction("let aa = 7") + + let values = fsiSession.GetBoundValues() |> List.map (fun x -> x.Value.ReflectionValue) + + Assert.shouldBeEquivalentTo [4;7;6;5;1;2;3] values + + [] + let ``Seven bound values are ordered and have their correct type`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let y = 2") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4.") + fsiSession.EvalInteraction("let ccc = 5") + fsiSession.EvalInteraction("let b = 6.f") + fsiSession.EvalInteraction("let aa = 7") + + let types = fsiSession.GetBoundValues() |> List.map (fun x -> x.Value.ReflectionType) + + Assert.shouldBe [typeof;typeof;typeof;typeof;typeof;typeof;typeof] types + + [] + let ``Able to find a bound value by the identifier`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let y = 2") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4") + fsiSession.EvalInteraction("let ccc = 5") + fsiSession.EvalInteraction("let b = 6") + fsiSession.EvalInteraction("let aa = 7") + + let boundValueOpt = fsiSession.TryFindBoundValue "ccc" + + Assert.shouldBeTrue boundValueOpt.IsSome + + [] + let ``Able to find a bound value by the identifier and has valid info`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1.") + fsiSession.EvalInteraction("let y = 2.") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4.") + fsiSession.EvalInteraction("let ccc = 5.") + fsiSession.EvalInteraction("let b = 6.") + fsiSession.EvalInteraction("let aa = 7.") + + let boundValue = (fsiSession.TryFindBoundValue "z").Value + + Assert.shouldBe "z" boundValue.Name + Assert.shouldBe 3 boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Not Able to find a bound value by the identifier`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let y = 2") + fsiSession.EvalInteraction("let z = 3") + fsiSession.EvalInteraction("let a = 4") + fsiSession.EvalInteraction("let ccc = 5") + fsiSession.EvalInteraction("let b = 6") + fsiSession.EvalInteraction("let aa = 7") + + let boundValueOpt = fsiSession.TryFindBoundValue "aaa" + + Assert.shouldBeTrue boundValueOpt.IsNone + + [] + let ``The 'it' value does not exist at the start of a FSI session`` () = + use fsiSession = createFsiSession () + + let boundValueOpt = fsiSession.TryFindBoundValue "it" + + Assert.shouldBeTrue boundValueOpt.IsNone + + [] + let ``The 'it' bound value does exists after a value is not explicitly bound`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("456") + + let boundValueOpt = fsiSession.TryFindBoundValue "it" + + Assert.shouldBeTrue boundValueOpt.IsSome + + [] + let ``The 'it' value does exists after a value is not explicitly bound and has valid info`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("456") + + let boundValue = (fsiSession.TryFindBoundValue "it").Value + + Assert.shouldBe "it" boundValue.Name + Assert.shouldBe 456 boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``The latest shadowed value is only available`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe 1 boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + fsiSession.EvalInteraction("let x = (1, 2)") + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe (1, 2) boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``The latest shadowed value is only available and can be found`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + let boundValue = (fsiSession.TryFindBoundValue "x").Value + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe 1 boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + fsiSession.EvalInteraction("let x = (1, 2)") + let boundValue = (fsiSession.TryFindBoundValue "x").Value + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe (1, 2) boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Values are successfully shadowed even with intermediate interactions`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("let x = 1") + fsiSession.EvalInteraction("let z = 100") + fsiSession.EvalInteraction("let x = (1, 2)") + fsiSession.EvalInteraction("let w = obj ()") + + let boundValues = fsiSession.GetBoundValues() + + Assert.shouldBe 3 boundValues.Length + + let boundValue = boundValues |> List.find (fun x -> x.Name = "x") + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe (1, 2) boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + let boundValue = (fsiSession.TryFindBoundValue "x").Value + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe (1, 2) boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Creation of a simple bound value succeeds`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("x", 1) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe typeof boundValue.Value.ReflectionType + Assert.shouldBe 1 boundValue.Value.ReflectionValue + + [] + let ``Creation of a bound value succeeds with underscores in the identifier`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("x_y_z", 1) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x_y_z" boundValue.Name + + [] + let ``Creation of a bound value succeeds with tildes in the identifier`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("``hello world``", 1) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "``hello world``" boundValue.Name + + [] + let ``Creation of a bound value succeeds with 'it' as the indentifier`` () = + use fsiSession = createFsiSession () + + fsiSession.EvalInteraction("\"test\"") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "it" boundValue.Name + Assert.shouldBe typeof boundValue.Value.ReflectionType + + fsiSession.AddBoundValue("it", 1) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "it" boundValue.Name + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value fails with tildes in the identifier and with 'at' but has warning`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("``hello @ world``", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name is not a valid identifier with 'at' in front`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("@x", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name is not a valid identifier with 'at' in back`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x@", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name is null`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue(null, 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name is empty`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name is whitespace`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue(" ", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name contains spaces`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x x", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name contains an operator at the end`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x+", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name contains an operator at the front`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("+x", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the name contains dots`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x.x", 1)) |> ignore + + [] + let ``Creation of a bound value fails if the value passed is null`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x", null) |> ignore) |> ignore + + type CustomType = { X: int } + + [] + let ``Creation of a bound value succeeds if the value contains types from assemblies that are not referenced in the session, due to implicit resolution`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("x", { X = 1 }) + + [] + let ``Creation of a bound value succeeds if the value contains types from assemblies that are not referenced in the session, due to implicit resolution, and then doing some evaluation`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("x", { X = 1 }) + fsiSession.EvalInteraction("let y = { x with X = 5 }") + + let boundValues = fsiSession.GetBoundValues() + Assert.shouldBe 2 boundValues.Length + + let v1 = boundValues.[0] + let v2 = boundValues.[1] + + Assert.shouldBe "x" v1.Name + Assert.shouldBe { X = 1 } v1.Value.ReflectionValue + Assert.shouldBe typeof v1.Value.ReflectionType + + Assert.shouldBe "y" v2.Name + Assert.shouldBe { X = 5 } v2.Value.ReflectionValue + Assert.shouldBe typeof v2.Value.ReflectionType + + [] + let ``Creation of a bound value, of type ResizeArray, succeeds`` () = + use fsiSession = createFsiSession () + + let xs = ResizeArray() + xs.Add("banana") + xs.Add("apple") + + fsiSession.AddBoundValue("xs", xs) + + let boundValues = fsiSession.GetBoundValues() + Assert.shouldBe 1 boundValues.Length + + let v1 = boundValues.[0] + + Assert.shouldBe "xs" v1.Name + Assert.shouldBe xs v1.Value.ReflectionValue + Assert.shouldBe typeof> v1.Value.ReflectionType + + type CustomType2() = + + member _.Message = "hello" + + [] + let ``Creation of a bound value succeeds if the value contains types from assemblies that are not referenced in the session, due to implicit resolution, and then use a member from it`` () = + use fsiSession = createFsiSession () + + let value = CustomType2() + fsiSession.AddBoundValue("x", value) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe value boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + fsiSession.EvalInteraction("let x = x.Message") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe "hello" boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value succeeds if the value contains generic types from assemblies that are not referenced in the session, due to implicit resolution, and then use a member from it`` () = + use fsiSession = createFsiSession () + + let value = ResizeArray() + value.Add(CustomType2()) + + fsiSession.AddBoundValue("x", value) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe value boundValue.Value.ReflectionValue + Assert.shouldBe typeof> boundValue.Value.ReflectionType + + fsiSession.EvalInteraction("let x = x.[0].Message") + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe "hello" boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value succeeds if the value contains two generic types from assemblies that are not referenced in the session, due to implicit resolution`` () = + use fsiSession = createFsiSession () + + let value = ({ X = 1 }, CustomType2()) + + fsiSession.AddBoundValue("x", value) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe "x" boundValue.Name + Assert.shouldBe value boundValue.Value.ReflectionValue + Assert.shouldBe typeof boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value fails if the value contains types from a dynamic assembly`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("fsiSession", fsiSession) + + let res, _ = fsiSession.EvalInteractionNonThrowing(""" + type TypeInDynamicAssembly() = class end + fsiSession.AddBoundValue("x", TypeInDynamicAssembly())""") + + match res with + | Choice2Of2 ex -> Assert.shouldBe typeof (ex.GetType()) + | _ -> failwith "Expected an exception" + + type internal NonPublicCustomType() = class end + + [] + let ``Creation of a bound value fails if the value's type is not public`` () = + use fsiSession = createFsiSession () + + Assert.Throws(fun () -> fsiSession.AddBoundValue("x", NonPublicCustomType())) |> ignore + + [] + let ``Creation of a bound value succeeds if the value is a partial application function type`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("createFsiSession", createFsiSession) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe typeof FsiEvaluationSession> boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value succeeds if the value is a partial application function type with four arguments`` () = + use fsiSession = createFsiSession () + + let addXYZW x y z w = x + y + z + w + let addYZW = addXYZW 1 + let addZW = addYZW 2 + + fsiSession.AddBoundValue("addZW", addZW) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe typeof int -> int> boundValue.Value.ReflectionType + + [] + let ``Creation of a bound value succeeds if the value is a lambda`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("addXYZ", fun x y z -> x + y + z) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe typeof int -> int -> int> boundValue.Value.ReflectionType + + type TestFSharpFunc() = + inherit FSharpFunc() + override _.Invoke x = x + + type Test2FSharpInheritFunc() = + inherit TestFSharpFunc() + + [] + let ``Creation of a bound value succeeds if the value is a type that inherits FSharpFunc`` () = + use fsiSession = createFsiSession () + + fsiSession.AddBoundValue("test", Test2FSharpInheritFunc()) + + let boundValue = fsiSession.GetBoundValues() |> List.exactlyOne + + Assert.shouldBe typeof boundValue.Value.ReflectionType diff --git a/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs b/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs index 3f91e0f1591..bf0d2d1a9e9 100644 --- a/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs +++ b/tests/FSharp.Compiler.UnitTests/HashIfExpression.fs @@ -5,20 +5,22 @@ namespace FSharp.Compiler.UnitTests open System open System.Text -open NUnit.Framework +open Xunit +open FSharp.Test +open Internal.Utilities open Internal.Utilities.Text.Lexing + open FSharp.Compiler +open FSharp.Compiler.Diagnostics open FSharp.Compiler.Lexer open FSharp.Compiler.Lexhelp open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features -open FSharp.Compiler.Ast -open Internal.Utilities - -[] -type HashIfExpression() = +open FSharp.Compiler.ParseHelpers +open FSharp.Compiler.Syntax +type public HashIfExpression() = let preludes = [|"#if "; "#elif "|] let epilogues = [|""; " // Testing"|] @@ -32,7 +34,6 @@ type HashIfExpression() = let (&&&) l r = IfdefAnd(l,r) let (|||) l r = IfdefOr(l,r) - let mutable tearDown = fun () -> () let exprAsString (e : LexerIfdefExpression) : string = let sb = StringBuilder() @@ -49,27 +50,26 @@ type HashIfExpression() = sb.ToString () let createParser () = - let errors = ResizeArray() - let warnings = ResizeArray() + let errors = ResizeArray() + let warnings = ResizeArray() - let errorLogger = + let errorLogger = { new ErrorLogger("TestErrorLogger") with - member x.DiagnosticSink(e, isError) = if isError then errors.Add e else warnings.Add e + member x.DiagnosticSink(e, sev) = if sev = FSharpDiagnosticSeverity.Error then errors.Add e else warnings.Add e member x.ErrorCount = errors.Count } - let lightSyntax = LightSyntaxStatus(true, false) + let lightSyntax = LightSyntaxStatus(true, false) let resourceManager = LexResourceManager () - let defines = [] - let startPos = Position.Empty - let args = mkLexargs ("dummy", defines, lightSyntax, resourceManager, [], errorLogger, PathMap.empty) + let defines= [] + let startPos = Position.Empty + let args = mkLexargs (defines, lightSyntax, resourceManager, [], errorLogger, PathMap.empty) CompileThreadStatic.ErrorLogger <- errorLogger let parser (s : string) = - let isFeatureSupported (_featureId:LanguageFeature) = true - let lexbuf = LexBuffer.FromChars (isFeatureSupported, s.ToCharArray ()) + let lexbuf = LexBuffer.FromChars (true, LanguageVersion.Default, s.ToCharArray ()) lexbuf.StartPos <- startPos lexbuf.EndPos <- startPos let tokenStream = PPLexer.tokenstream args @@ -78,21 +78,14 @@ type HashIfExpression() = errors, warnings, parser - [] - member this.Setup() = - let el = CompileThreadStatic.ErrorLogger - tearDown <- - fun () -> - CompileThreadStatic.BuildPhase <- BuildPhase.DefaultPhase - CompileThreadStatic.ErrorLogger <- el - + do // Setup CompileThreadStatic.BuildPhase <- BuildPhase.Compile + interface IDisposable with // Teardown + member _.Dispose() = + CompileThreadStatic.BuildPhase <- BuildPhase.DefaultPhase + CompileThreadStatic.ErrorLogger <- CompileThreadStatic.ErrorLogger - [] - member this.TearDown() = - tearDown () - - [] + [] member this.PositiveParserTestCases()= let errors, warnings, parser = createParser () @@ -149,11 +142,11 @@ type HashIfExpression() = let failure = String.Join ("\n", fs) - Assert.AreEqual("", failure) + Assert.shouldBe "" failure () - [] + [] member this.NegativeParserTestCases()= let errors, warnings, parser = createParser () @@ -212,9 +205,9 @@ type HashIfExpression() = let fails = String.Join ("\n", fs) - Assert.AreEqual("", fails) + Assert.shouldBe "" fails - [] + [] member this.LexerIfdefEvalTestCases()= let failures = ResizeArray () @@ -265,4 +258,4 @@ type HashIfExpression() = let fails = String.Join ("\n", fs) - Assert.AreEqual("", fails) + Assert.shouldBe "" fails diff --git a/tests/FSharp.Compiler.UnitTests/ManglingNameOfProvidedTypes.fs b/tests/FSharp.Compiler.UnitTests/ManglingNameOfProvidedTypes.fs index e422e5a499b..5ccac1bb871 100644 --- a/tests/FSharp.Compiler.UnitTests/ManglingNameOfProvidedTypes.fs +++ b/tests/FSharp.Compiler.UnitTests/ManglingNameOfProvidedTypes.fs @@ -3,66 +3,67 @@ namespace FSharp.Compiler.UnitTests open System open System.Text -open NUnit.Framework -open FSharp.Compiler +open Xunit +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Compiler.Syntax -[] type ManglingNamesOfProvidedTypesWithSingleParameter() = - [] + [] member this.MangleWithNonDefaultValue() = let mangled = PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "abc" |]) - Assert.AreEqual("MyNamespace.Test,Foo=\"xyz\"", mangled) + Assert.shouldBe "MyNamespace.Test,Foo=\"xyz\"" mangled - [] + [] member this.MangleWithDefaultValue() = let mangled = PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "xyz" |]) - Assert.AreEqual("MyNamespace.Test", mangled) + Assert.shouldBe "MyNamespace.Test" mangled - [] + [] member this.DemangleNonDefaultValue() = let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test,Foo=\"xyz\"" - Assert.AreEqual("MyNamespace.Test", name) - Assert.AreEqual([| "Foo", "xyz" |], parameters) + Assert.shouldBe "MyNamespace.Test" name + Assert.shouldBeEquivalentTo [| "Foo", "xyz" |] parameters - [] + [] member this.DemangleDefaultValue() = let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test," - Assert.AreEqual("MyNamespace.Test", name) - Assert.AreEqual([||], parameters) + Assert.shouldBe "MyNamespace.Test" name + Assert.shouldBeEquivalentTo [||] parameters - [] + [] member this.DemangleNewDefaultValue() = let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test" - Assert.AreEqual("MyNamespace.Test", name) - Assert.AreEqual([||], parameters) + Assert.shouldBe "MyNamespace.Test" name + Assert.shouldBeEquivalentTo [||] parameters + -[] type ManglingNamesOfProvidedTypesWithMultipleParameter() = - [] + [] member this.MangleWithNonDefaultValue() = let mangled = PrettyNaming.computeMangledNameWithoutDefaultArgValues ("MyNamespace.Test", [| "xyz"; "abc" |], [| "Foo", Some "foo" "Foo2", Some "foo2" |]) - Assert.AreEqual("MyNamespace.Test,Foo=\"xyz\",Foo2=\"abc\"", mangled) + Assert.shouldBe "MyNamespace.Test,Foo=\"xyz\",Foo2=\"abc\"" mangled - [] + [] member this.MangleWithDefaultValue() = let mangled = PrettyNaming.computeMangledNameWithoutDefaultArgValues ("MyNamespace.Test", [| "xyz"; "abc" |], [| "Foo", Some "xyz" "Foo2", Some "abc" |]) - Assert.AreEqual("MyNamespace.Test", mangled) + Assert.shouldBe "MyNamespace.Test" mangled - [] + [] member this.DemangleMultiParameter() = let name, parameters = PrettyNaming.demangleProvidedTypeName "TestType,Foo=\"xyz\",Foo2=\"abc\"" - Assert.AreEqual("TestType", name) - Assert.AreEqual([| "Foo", "xyz" - "Foo2", "abc" |], parameters) \ No newline at end of file + Assert.shouldBe "TestType" name + Assert.shouldBe([| "Foo", "xyz" + "Foo2", "abc" |], parameters) diff --git a/tests/FSharp.Compiler.UnitTests/NunitHelpers.fs b/tests/FSharp.Compiler.UnitTests/NunitHelpers.fs deleted file mode 100644 index 89fb1cfc5ba..00000000000 --- a/tests/FSharp.Compiler.UnitTests/NunitHelpers.fs +++ /dev/null @@ -1,14 +0,0 @@ -namespace NUnit.Framework - -module Assert = - - let inline fail message = Assert.Fail message - - let inline failf fmt = Printf.kprintf fail fmt - - let inline areEqual (expected: ^T) (actual: ^T) = - Assert.AreEqual(expected, actual) - -module StringAssert = - - let inline contains expected actual = StringAssert.Contains(expected, actual) diff --git a/tests/FSharp.Compiler.UnitTests/ProductVersion.fs b/tests/FSharp.Compiler.UnitTests/ProductVersion.fs index 1da55436d25..417f71a3fed 100644 --- a/tests/FSharp.Compiler.UnitTests/ProductVersion.fs +++ b/tests/FSharp.Compiler.UnitTests/ProductVersion.fs @@ -3,10 +3,11 @@ open System open System.IO open System.Text -open NUnit.Framework +open Xunit +open FSharp.Test open FSharp.Compiler.AbstractIL.IL -open FSharp.Compiler.Driver.MainModuleBuilder +open FSharp.Compiler.CreateILModule.MainModuleBuilder #nowarn "3180" @@ -14,66 +15,68 @@ module FileVersionTest = let fileVersionAttrName = typeof.FullName - [] + [] let parseILVersion () = - "0.0.0.0" |> parseILVersion |> Assert.areEqual (ILVersionInfo(0us,0us,0us,0us)) - "1.2.3.4" |> parseILVersion |> Assert.areEqual (ILVersionInfo(1us,2us,3us,4us)) + "0.0.0.0" |> parseILVersion |> Assert.shouldBe (ILVersionInfo(0us,0us,0us,0us)) + "1.2.3.4" |> parseILVersion |> Assert.shouldBe (ILVersionInfo(1us,2us,3us,4us)) - [] + [] let ``should use AssemblyFileVersionAttribute if set`` () = - let findStringAttr n = n |> Assert.areEqual fileVersionAttrName; Some "1.2.3.4" - fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,0us)) |> Assert.areEqual (ILVersionInfo(1us,2us,3us,4us)) + let findStringAttr n = n |> Assert.shouldBe fileVersionAttrName; Some "1.2.3.4" + fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,0us)) |> Assert.shouldBe (ILVersionInfo(1us,2us,3us,4us)) - [] + [] let ``should fallback if AssemblyFileVersionAttribute is not a valid version`` () = fileVersion (fun _ -> Some "1.2a.3.3") (ILVersionInfo(3us,7us,8us,6us)) - |> Assert.areEqual (ILVersionInfo(3us,7us,8us,6us)) + |> Assert.shouldBe (ILVersionInfo(3us,7us,8us,6us)) - [] + [] let ``should fallback to assemblyVersion if AssemblyFileVersionAttribute not set`` () = - let findStringAttr n = n |> Assert.areEqual fileVersionAttrName; None; - fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,4us)) |> Assert.areEqual (ILVersionInfo(1us,0us,0us,4us)) + let findStringAttr n = n |> Assert.shouldBe fileVersionAttrName; None; + fileVersion findStringAttr (ILVersionInfo(1us,0us,0us,4us)) |> Assert.shouldBe (ILVersionInfo(1us,0us,0us,4us)) module ProductVersionTest = let informationalVersionAttrName = typeof.FullName let fileVersionAttrName = typeof.FullName - [] + [] let ``should use AssemblyInformationalVersionAttribute if set`` () = let mutable args = [] let findStrAttr x = args <- List.append args [x]; Some "12.34.56.78" - productVersion findStrAttr (ILVersionInfo(1us,0us,0us,6us)) |> Assert.areEqual "12.34.56.78" - args |> Assert.areEqual [ informationalVersionAttrName ] + productVersion findStrAttr (ILVersionInfo(1us,0us,0us,6us)) |> Assert.shouldBe "12.34.56.78" + args |> Assert.shouldBe [ informationalVersionAttrName ] - [] + [] let ``should fallback if AssemblyInformationalVersionAttribute is not a valid version`` () = productVersion (fun _ -> Some "1.2.3-main (build #12)") (ILVersionInfo(1us,0us,0us,6us)) - |> Assert.areEqual "1.2.3-main (build #12)" + |> Assert.shouldBe "1.2.3-main (build #12)" - [] + [] let ``should fallback to fileVersion if AssemblyInformationalVersionAttribute not set or empty`` () = - productVersion (fun _ -> None) (ILVersionInfo(3us,2us,1us,0us)) |> Assert.areEqual "3.2.1.0" - productVersion (fun _ -> Some "") (ILVersionInfo(3us,2us,1us,0us)) |> Assert.areEqual "3.2.1.0" + productVersion (fun _ -> None) (ILVersionInfo(3us,2us,1us,0us)) |> Assert.shouldBe "3.2.1.0" + productVersion (fun _ -> Some "") (ILVersionInfo(3us,2us,1us,0us)) |> Assert.shouldBe "3.2.1.0" - let validValues () = + let internal validValues () = let max = System.UInt16.MaxValue [ "1.2.3.4", ILVersionInfo(1us,2us,3us,4us) + "1.0.3.4", ILVersionInfo(1us,0us,3us,4us) + "7.0.0.4-SomeExtraInformation", ILVersionInfo(7us,0us,0us,4us) "0.0.0.0", ILVersionInfo(0us,0us,0us,0us) "3213.57843.32382.59493", ILVersionInfo(3213us,57843us,32382us,59493us) (sprintf "%d.%d.%d.%d" max max max max), ILVersionInfo(max,max,max,max) ] - [] + [] let ``should use values if valid major.minor.revision.build version format`` () = for (v, expected) in validValues() do - v |> productVersionToILVersionInfo |> Assert.areEqual expected + v |> productVersionToILVersionInfo |> Assert.shouldBe expected - let invalidValues () = + let internal invalidValues () = [ "1.2.3.4", ILVersionInfo(1us,2us,3us,4us) - "1.2.3.4a", ILVersionInfo(1us,2us,3us,0us) - "1.2.c3.4", ILVersionInfo(1us,2us,0us,0us) - "1.2-d.3.4", ILVersionInfo(1us,0us,0us,0us) - "1dd.2.3.4", ILVersionInfo(0us,0us,0us,0us) + "1.2.3.4a", ILVersionInfo(1us,2us,3us,4us) + "1.2.c3.4", ILVersionInfo(1us,2us,0us,4us) + "1.2-d.3.4", ILVersionInfo(1us,0us,3us,4us) + "1dd.2.3.4", ILVersionInfo(0us,2us,3us,4us) "1dd.2da.d3hj.dd4ds", ILVersionInfo(0us,0us,0us,0us) "1.5.6.7.dasd", ILVersionInfo(1us,5us,6us,7us) "9.3", ILVersionInfo(9us,3us,0us,0us) @@ -81,7 +84,7 @@ module ProductVersionTest = "70000.80000.90000.100000", ILVersionInfo(0us,0us,0us,0us) (sprintf "%d.70000.80000.90000" System.UInt16.MaxValue), ILVersionInfo(System.UInt16.MaxValue,0us,0us,0us) ] - [] + [] let ``should zero starting from first invalid version part`` () = - for (v, expected) in invalidValues() do - v |> productVersionToILVersionInfo |> Assert.areEqual expected + for (v, expected) in invalidValues() do + v |> productVersionToILVersionInfo |> Assert.shouldBe expected diff --git a/tests/FSharp.Compiler.UnitTests/SuggestionBuffer.fs b/tests/FSharp.Compiler.UnitTests/SuggestionBuffer.fs index 0a0584088c9..7ecadd93209 100644 --- a/tests/FSharp.Compiler.UnitTests/SuggestionBuffer.fs +++ b/tests/FSharp.Compiler.UnitTests/SuggestionBuffer.fs @@ -1,20 +1,20 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace FSharp.Compiler.UnitTests -open NUnit.Framework +open Xunit +open FSharp.Test -[] module SuggestionBuffer = open FSharp.Compiler.ErrorResolutionHints - [] + [] let NewBufferShouldBeEmpty() = let buffer = SuggestionBuffer("abdef") - Assert.IsFalse buffer.Disabled - Assert.IsEmpty buffer + Assert.shouldBeFalse buffer.Disabled + Assert.shouldBeEmpty buffer - [] + [] let BufferShouldOnlyAcceptSimilarElements() = let buffer = SuggestionBuffer("abcd") buffer.Add("abce") @@ -22,13 +22,13 @@ module SuggestionBuffer = let results = Array.ofSeq buffer - Assert.areEqual [| "abce" |] results + Assert.shouldBeEquivalentTo [| "abce" |] results - [] + [] let SmallIdentifierShouldBeIgnored() = let buffer = SuggestionBuffer("ab") - Assert.IsTrue buffer.Disabled + Assert.shouldBeTrue buffer.Disabled buffer.Add("abce") buffer.Add("somethingcompletelyunrelated") @@ -40,10 +40,10 @@ module SuggestionBuffer = let results = Array.ofSeq buffer - Assert.IsTrue buffer.Disabled - Assert.areEqual [||] results + Assert.shouldBeTrue buffer.Disabled + Assert.shouldBeEquivalentTo [||] results - [] + [] let BufferShouldOnlyTakeTop5Elements() = let buffer = SuggestionBuffer("abcd") buffer.Add("abce") @@ -56,9 +56,9 @@ module SuggestionBuffer = let results = Array.ofSeq buffer - Assert.areEqual [| "abce"; "abcg"; "abch"; "abci"; "abcj"|] results + Assert.shouldBeEquivalentTo [| "abce"; "abcg"; "abch"; "abci"; "abcj"|] results - [] + [] let BufferShouldUseEarlierElementsIfTheyHaveSameScore() = let buffer = SuggestionBuffer("abcd") buffer.Add("abce") @@ -70,10 +70,10 @@ module SuggestionBuffer = let results = Array.ofSeq buffer - Assert.areEqual [| "abce"; "abcf"; "abcg"; "abch"; "abci"|] results + Assert.shouldBeEquivalentTo [| "abce"; "abcf"; "abcg"; "abch"; "abci"|] results - [] + [] let BufferShouldDisableItselfIfItSeesTheOriginalIdentifier() = let buffer = SuggestionBuffer("abcd") buffer.Add("abce") @@ -81,16 +81,16 @@ module SuggestionBuffer = buffer.Add("abcg") buffer.Add("abch") - Assert.IsFalse buffer.Disabled - Assert.IsNotEmpty buffer + Assert.shouldBeFalse buffer.Disabled + Assert.shouldNotBeEmpty buffer buffer.Add("abcd") // original Ident buffer.Add("abcj") - Assert.IsTrue buffer.Disabled - Assert.IsEmpty buffer + Assert.shouldBeTrue buffer.Disabled + Assert.shouldBeEmpty buffer - [] + [] let BufferShouldIgnoreSmallIdentifiers() = let buffer = SuggestionBuffer("abd") buffer.Add("abce") @@ -100,4 +100,4 @@ module SuggestionBuffer = let results = Array.ofSeq buffer - Assert.areEqual [| "abc"; "abce" |] results \ No newline at end of file + Assert.shouldBeEquivalentTo [| "abc"; "abce" |] results diff --git a/tests/FSharp.Compiler.UnitTests/xunit.runner.json b/tests/FSharp.Compiler.UnitTests/xunit.runner.json new file mode 100644 index 00000000000..aa4e627f2b8 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "shadowCopy": false +} diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index 055d30ee4fb..aa39265d2a0 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -3,8 +3,8 @@ - net472;netcoreapp3.0 - netcoreapp3.0 + net5.0;net472 + net5.0 Library FSharp.Core.UnitTests @@ -14,7 +14,7 @@ preview true - nunit + xunit true true MIT @@ -31,8 +31,17 @@ - + + + + + + + + + + @@ -59,10 +68,6 @@ - - - - @@ -71,9 +76,12 @@ + + + @@ -82,28 +90,16 @@ - - - + - + - + + - - - - - - - - - - - diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/ComparersRegression.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/ComparersRegression.fs index 43fc5b2343e..cb74c489da0 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/ComparersRegression.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/ComparersRegression.fs @@ -1,12 +1,12 @@ // A set of regression tests for equality/relational operators and the IComparer<> and IEqualityComparer<> // implementation provided by ComparisonIdentity.Structural and HashIdentity.Structural -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests open System open System.Numerics open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit module ComparersRegression = type RefWrap<'item> = { Item : 'item } @@ -1573,19 +1573,19 @@ module ComparersRegression = let toint b = if b then 1 else 0 type EqualityOperations<'a when 'a : equality>() = - member inline __.equals = { new IOperation<'a> with member __.Exec lhs rhs = toint (HashIdentity.Structural.Equals(lhs,rhs)) } - member inline __.equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs = rhs) } - member inline __.not_equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs <> rhs) } + member inline _.equals = { new IOperation<'a> with member _.Exec lhs rhs = toint (HashIdentity.Structural.Equals(lhs,rhs)) } + member inline _.equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs = rhs) } + member inline _.not_equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs <> rhs) } type ComparisonOperations<'a when 'a : comparison>() = - member inline __.equals = { new IOperation<'a> with member __.Exec lhs rhs = toint (HashIdentity.Structural.Equals(lhs,rhs)) } - member inline __.equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs = rhs) } - member inline __.not_equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs <> rhs) } - member inline __.compare = { new IOperation<'a> with member __.Exec lhs rhs = ComparisonIdentity.Structural.Compare(lhs,rhs) } - member inline __.less_than = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs < rhs) } - member inline __.less_or_equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs <= rhs) } - member inline __.greater_than = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs > rhs) } - member inline __.greater_or_equal = { new IOperation<'a> with member __.Exec lhs rhs = toint (lhs >= rhs) } + member inline _.equals = { new IOperation<'a> with member _.Exec lhs rhs = toint (HashIdentity.Structural.Equals(lhs,rhs)) } + member inline _.equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs = rhs) } + member inline _.not_equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs <> rhs) } + member inline _.compare = { new IOperation<'a> with member _.Exec lhs rhs = ComparisonIdentity.Structural.Compare(lhs,rhs) } + member inline _.less_than = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs < rhs) } + member inline _.less_or_equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs <= rhs) } + member inline _.greater_than = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs > rhs) } + member inline _.greater_or_equal = { new IOperation<'a> with member _.Exec lhs rhs = toint (lhs >= rhs) } type NoninlinableEqualityOperations<'a when 'a : equality>() = let operations = @@ -1594,9 +1594,9 @@ module ComparersRegression = | :? EqualityOperations<'a> as operations -> operations | _ -> failwith "" - member __.equals = operations.equals - member __.equal = operations.equal - member __.not_equal = operations.not_equal + member _.equals = operations.equals + member _.equal = operations.equal + member _.not_equal = operations.not_equal type NoninlinableComparisonOperations<'a when 'a : comparison>() = let operations = @@ -1605,14 +1605,14 @@ module ComparersRegression = | :? ComparisonOperations<'a> as operations -> operations | _ -> failwith "" - member __.equals = operations.equals - member __.equal = operations.equal - member __.not_equal = operations.not_equal - member __.compare = operations.compare - member __.less_than = operations.less_than - member __.less_or_equal = operations.less_or_equal - member __.greater_than = operations.greater_than - member __.greater_or_equal = operations.greater_or_equal + member _.equals = operations.equals + member _.equal = operations.equal + member _.not_equal = operations.not_equal + member _.compare = operations.compare + member _.less_than = operations.less_than + member _.less_or_equal = operations.less_or_equal + member _.greater_than = operations.greater_than + member _.greater_or_equal = operations.greater_or_equal type E<'a when 'a : equality>() = static let inlinable = EqualityOperations<'a> () @@ -1630,8 +1630,8 @@ module ComparersRegression = #if !NETSTANDARD1_6 && !NETCOREAPP let create<'a,'b when 'b : equality> name operation (f:IOperation<'a>) (items:array<'a>) = - printf """ [] - member __.``%s %s``() = + printf """ [] + member _.``%s %s``() = validate (%s) %s """ name operation name operation make_result_set f items None @@ -1745,399 +1745,399 @@ module ComparersRegression = failwith <| sprintf "args(%O, %O) Expected=%O. Received=%O." lhs rhs expected received open ComparersRegression +open Xunit -[] -type GeneratedTestSuite () = +type GeneratedTests () = let _ = () // ------------------------------------------------------------------------------ // -- The following should be generated by running CreateComparersRegression.fsx // ------------------------------------------------------------------------------ - [] - member __.``Bools.Collection.Array C.I.equals``() = + [] + member _.``Bools.Collection.Array C.I.equals``() = validate (Bools.Collection.Array) C.I.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.Array C.I.equal``() = + [] + member _.``Bools.Collection.Array C.I.equal``() = validate (Bools.Collection.Array) C.I.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.Array C.I.not_equal``() = + [] + member _.``Bools.Collection.Array C.I.not_equal``() = validate (Bools.Collection.Array) C.I.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.Array C.I.compare``() = + [] + member _.``Bools.Collection.Array C.I.compare``() = validate (Bools.Collection.Array) C.I.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.Array C.I.less_than``() = + [] + member _.``Bools.Collection.Array C.I.less_than``() = validate (Bools.Collection.Array) C.I.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.Array C.I.less_or_equal``() = + [] + member _.``Bools.Collection.Array C.I.less_or_equal``() = validate (Bools.Collection.Array) C.I.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.Array C.I.greater_than``() = + [] + member _.``Bools.Collection.Array C.I.greater_than``() = validate (Bools.Collection.Array) C.I.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.Array C.I.greater_or_equal``() = validate (Bools.Collection.Array) C.I.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.Array C.N.equals``() = + [] + member _.``Bools.Collection.Array C.N.equals``() = validate (Bools.Collection.Array) C.N.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.Array C.N.equal``() = + [] + member _.``Bools.Collection.Array C.N.equal``() = validate (Bools.Collection.Array) C.N.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.Array C.N.not_equal``() = + [] + member _.``Bools.Collection.Array C.N.not_equal``() = validate (Bools.Collection.Array) C.N.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.Array C.N.compare``() = + [] + member _.``Bools.Collection.Array C.N.compare``() = validate (Bools.Collection.Array) C.N.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.Array C.N.less_than``() = + [] + member _.``Bools.Collection.Array C.N.less_than``() = validate (Bools.Collection.Array) C.N.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.Array C.N.less_or_equal``() = + [] + member _.``Bools.Collection.Array C.N.less_or_equal``() = validate (Bools.Collection.Array) C.N.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.Array C.N.greater_than``() = + [] + member _.``Bools.Collection.Array C.N.greater_than``() = validate (Bools.Collection.Array) C.N.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.Array C.N.greater_or_equal``() = validate (Bools.Collection.Array) C.N.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.I.equals``() = + [] + member _.``Bools.Collection.OptionArray C.I.equals``() = validate (Bools.Collection.OptionArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.I.equal``() = + [] + member _.``Bools.Collection.OptionArray C.I.equal``() = validate (Bools.Collection.OptionArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Bools.Collection.OptionArray C.I.not_equal``() = validate (Bools.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``Bools.Collection.OptionArray C.I.compare``() = + [] + member _.``Bools.Collection.OptionArray C.I.compare``() = validate (Bools.Collection.OptionArray) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``Bools.Collection.OptionArray C.I.less_than``() = + [] + member _.``Bools.Collection.OptionArray C.I.less_than``() = validate (Bools.Collection.OptionArray) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``Bools.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.OptionArray C.I.less_or_equal``() = validate (Bools.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``Bools.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Bools.Collection.OptionArray C.I.greater_than``() = validate (Bools.Collection.OptionArray) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``Bools.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.OptionArray C.I.greater_or_equal``() = validate (Bools.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.N.equals``() = + [] + member _.``Bools.Collection.OptionArray C.N.equals``() = validate (Bools.Collection.OptionArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.N.equal``() = + [] + member _.``Bools.Collection.OptionArray C.N.equal``() = validate (Bools.Collection.OptionArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``Bools.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Bools.Collection.OptionArray C.N.not_equal``() = validate (Bools.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``Bools.Collection.OptionArray C.N.compare``() = + [] + member _.``Bools.Collection.OptionArray C.N.compare``() = validate (Bools.Collection.OptionArray) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``Bools.Collection.OptionArray C.N.less_than``() = + [] + member _.``Bools.Collection.OptionArray C.N.less_than``() = validate (Bools.Collection.OptionArray) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``Bools.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.OptionArray C.N.less_or_equal``() = validate (Bools.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``Bools.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Bools.Collection.OptionArray C.N.greater_than``() = validate (Bools.Collection.OptionArray) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``Bools.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.OptionArray C.N.greater_or_equal``() = validate (Bools.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``Bools.Collection.RefArray C.I.equals``() = + [] + member _.``Bools.Collection.RefArray C.I.equals``() = validate (Bools.Collection.RefArray) C.I.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefArray C.I.equal``() = + [] + member _.``Bools.Collection.RefArray C.I.equal``() = validate (Bools.Collection.RefArray) C.I.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefArray C.I.not_equal``() = + [] + member _.``Bools.Collection.RefArray C.I.not_equal``() = validate (Bools.Collection.RefArray) C.I.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.RefArray C.I.compare``() = + [] + member _.``Bools.Collection.RefArray C.I.compare``() = validate (Bools.Collection.RefArray) C.I.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.RefArray C.I.less_than``() = + [] + member _.``Bools.Collection.RefArray C.I.less_than``() = validate (Bools.Collection.RefArray) C.I.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.RefArray C.I.less_or_equal``() = validate (Bools.Collection.RefArray) C.I.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.RefArray C.I.greater_than``() = + [] + member _.``Bools.Collection.RefArray C.I.greater_than``() = validate (Bools.Collection.RefArray) C.I.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.RefArray C.I.greater_or_equal``() = validate (Bools.Collection.RefArray) C.I.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.RefArray C.N.equals``() = + [] + member _.``Bools.Collection.RefArray C.N.equals``() = validate (Bools.Collection.RefArray) C.N.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefArray C.N.equal``() = + [] + member _.``Bools.Collection.RefArray C.N.equal``() = validate (Bools.Collection.RefArray) C.N.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefArray C.N.not_equal``() = + [] + member _.``Bools.Collection.RefArray C.N.not_equal``() = validate (Bools.Collection.RefArray) C.N.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.RefArray C.N.compare``() = + [] + member _.``Bools.Collection.RefArray C.N.compare``() = validate (Bools.Collection.RefArray) C.N.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.RefArray C.N.less_than``() = + [] + member _.``Bools.Collection.RefArray C.N.less_than``() = validate (Bools.Collection.RefArray) C.N.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.RefArray C.N.less_or_equal``() = validate (Bools.Collection.RefArray) C.N.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.RefArray C.N.greater_than``() = + [] + member _.``Bools.Collection.RefArray C.N.greater_than``() = validate (Bools.Collection.RefArray) C.N.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.RefArray C.N.greater_or_equal``() = validate (Bools.Collection.RefArray) C.N.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.equals``() = validate (Bools.Collection.RefWrapArray) C.I.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.equal``() = validate (Bools.Collection.RefWrapArray) C.I.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.not_equal``() = validate (Bools.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.compare``() = validate (Bools.Collection.RefWrapArray) C.I.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.less_than``() = validate (Bools.Collection.RefWrapArray) C.I.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.less_or_equal``() = validate (Bools.Collection.RefWrapArray) C.I.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.greater_than``() = validate (Bools.Collection.RefWrapArray) C.I.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Bools.Collection.RefWrapArray) C.I.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.equals``() = validate (Bools.Collection.RefWrapArray) C.N.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.equal``() = validate (Bools.Collection.RefWrapArray) C.N.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.not_equal``() = validate (Bools.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.compare``() = validate (Bools.Collection.RefWrapArray) C.N.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.less_than``() = validate (Bools.Collection.RefWrapArray) C.N.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.less_or_equal``() = validate (Bools.Collection.RefWrapArray) C.N.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.greater_than``() = validate (Bools.Collection.RefWrapArray) C.N.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Bools.Collection.RefWrapArray) C.N.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.I.equals``() = + [] + member _.``Bools.Collection.UnionArray C.I.equals``() = validate (Bools.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2146,8 +2146,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.I.equal``() = + [] + member _.``Bools.Collection.UnionArray C.I.equal``() = validate (Bools.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2156,8 +2156,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Bools.Collection.UnionArray C.I.not_equal``() = validate (Bools.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -2166,8 +2166,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.I.compare``() = + [] + member _.``Bools.Collection.UnionArray C.I.compare``() = validate (Bools.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;1;-1;-1; -1;-1;3;2;1;0;-1;-2;-3;3;2;1;1;-1;-2;-3;3;2;1;1;0;-1;-2;3;2;1;1;1;-1;-2;3;2;1;2;1;0;-1;3;2;1; @@ -2176,8 +2176,8 @@ type GeneratedTestSuite () = -2;3;2;1;1;0;-1;-2;3;2;1;2;1;-1;-1;3;2;1;2;1;0;-1;3;2;1;3;2;1;-1;3;2;1;3;2;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.I.less_than``() = + [] + member _.``Bools.Collection.UnionArray C.I.less_than``() = validate (Bools.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0; @@ -2186,8 +2186,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0 |] - [] - member __.``Bools.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.UnionArray C.I.less_or_equal``() = validate (Bools.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;1;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0; @@ -2196,8 +2196,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Bools.Collection.UnionArray C.I.greater_than``() = validate (Bools.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; @@ -2206,8 +2206,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.UnionArray C.I.greater_or_equal``() = validate (Bools.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1; @@ -2216,8 +2216,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Bools.Collection.UnionArray C.N.equals``() = + [] + member _.``Bools.Collection.UnionArray C.N.equals``() = validate (Bools.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2226,8 +2226,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.N.equal``() = + [] + member _.``Bools.Collection.UnionArray C.N.equal``() = validate (Bools.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2236,8 +2236,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Bools.Collection.UnionArray C.N.not_equal``() = validate (Bools.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -2246,8 +2246,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.N.compare``() = + [] + member _.``Bools.Collection.UnionArray C.N.compare``() = validate (Bools.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;1;-1;-1; -1;-1;3;2;1;0;-1;-2;-3;3;2;1;1;-1;-2;-3;3;2;1;1;0;-1;-2;3;2;1;1;1;-1;-2;3;2;1;2;1;0;-1;3;2;1; @@ -2256,8 +2256,8 @@ type GeneratedTestSuite () = -2;3;2;1;1;0;-1;-2;3;2;1;2;1;-1;-1;3;2;1;2;1;0;-1;3;2;1;3;2;1;-1;3;2;1;3;2;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.N.less_than``() = + [] + member _.``Bools.Collection.UnionArray C.N.less_than``() = validate (Bools.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0; @@ -2266,8 +2266,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0 |] - [] - member __.``Bools.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.UnionArray C.N.less_or_equal``() = validate (Bools.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;1;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0; @@ -2276,8 +2276,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Bools.Collection.UnionArray C.N.greater_than``() = validate (Bools.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; @@ -2286,8 +2286,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.UnionArray C.N.greater_or_equal``() = validate (Bools.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1; @@ -2296,8 +2296,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.equals``() = validate (Bools.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2306,8 +2306,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.equal``() = validate (Bools.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2316,8 +2316,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.not_equal``() = validate (Bools.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -2326,8 +2326,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.compare``() = validate (Bools.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;1;-1;-1; -1;-1;3;2;1;0;-1;-2;-3;3;2;1;1;-1;-2;-3;3;2;1;1;0;-1;-2;3;2;1;1;1;-1;-2;3;2;1;2;1;0;-1;3;2;1; @@ -2336,8 +2336,8 @@ type GeneratedTestSuite () = -2;3;2;1;1;0;-1;-2;3;2;1;2;1;-1;-1;3;2;1;2;1;0;-1;3;2;1;3;2;1;-1;3;2;1;3;2;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.less_than``() = validate (Bools.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0; @@ -2346,8 +2346,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Bools.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;1;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0; @@ -2356,8 +2356,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.greater_than``() = validate (Bools.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; @@ -2366,8 +2366,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Bools.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1; @@ -2376,8 +2376,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.equals``() = validate (Bools.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2386,8 +2386,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.equal``() = validate (Bools.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -2396,8 +2396,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.not_equal``() = validate (Bools.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -2406,8 +2406,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.compare``() = validate (Bools.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;1;-1;-1; -1;-1;3;2;1;0;-1;-2;-3;3;2;1;1;-1;-2;-3;3;2;1;1;0;-1;-2;3;2;1;1;1;-1;-2;3;2;1;2;1;0;-1;3;2;1; @@ -2416,8 +2416,8 @@ type GeneratedTestSuite () = -2;3;2;1;1;0;-1;-2;3;2;1;2;1;-1;-1;3;2;1;2;1;0;-1;3;2;1;3;2;1;-1;3;2;1;3;2;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.less_than``() = validate (Bools.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0; @@ -2426,8 +2426,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Bools.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1; 1;1;0;0;0;1;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0; @@ -2436,8 +2436,8 @@ type GeneratedTestSuite () = 1;0;0;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.greater_than``() = validate (Bools.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; @@ -2446,8 +2446,8 @@ type GeneratedTestSuite () = 0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bools.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Bools.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0; 0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1; @@ -2456,632 +2456,632 @@ type GeneratedTestSuite () = 0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Bools.Collection.ValueArray C.I.equals``() = + [] + member _.``Bools.Collection.ValueArray C.I.equals``() = validate (Bools.Collection.ValueArray) C.I.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueArray C.I.equal``() = + [] + member _.``Bools.Collection.ValueArray C.I.equal``() = validate (Bools.Collection.ValueArray) C.I.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Bools.Collection.ValueArray C.I.not_equal``() = validate (Bools.Collection.ValueArray) C.I.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.ValueArray C.I.compare``() = + [] + member _.``Bools.Collection.ValueArray C.I.compare``() = validate (Bools.Collection.ValueArray) C.I.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.ValueArray C.I.less_than``() = + [] + member _.``Bools.Collection.ValueArray C.I.less_than``() = validate (Bools.Collection.ValueArray) C.I.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.ValueArray C.I.less_or_equal``() = validate (Bools.Collection.ValueArray) C.I.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Bools.Collection.ValueArray C.I.greater_than``() = validate (Bools.Collection.ValueArray) C.I.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.ValueArray C.I.greater_or_equal``() = validate (Bools.Collection.ValueArray) C.I.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.ValueArray C.N.equals``() = + [] + member _.``Bools.Collection.ValueArray C.N.equals``() = validate (Bools.Collection.ValueArray) C.N.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueArray C.N.equal``() = + [] + member _.``Bools.Collection.ValueArray C.N.equal``() = validate (Bools.Collection.ValueArray) C.N.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Bools.Collection.ValueArray C.N.not_equal``() = validate (Bools.Collection.ValueArray) C.N.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.ValueArray C.N.compare``() = + [] + member _.``Bools.Collection.ValueArray C.N.compare``() = validate (Bools.Collection.ValueArray) C.N.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.ValueArray C.N.less_than``() = + [] + member _.``Bools.Collection.ValueArray C.N.less_than``() = validate (Bools.Collection.ValueArray) C.N.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.ValueArray C.N.less_or_equal``() = validate (Bools.Collection.ValueArray) C.N.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Bools.Collection.ValueArray C.N.greater_than``() = validate (Bools.Collection.ValueArray) C.N.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.ValueArray C.N.greater_or_equal``() = validate (Bools.Collection.ValueArray) C.N.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.equals``() = validate (Bools.Collection.ValueWrapArray) C.I.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.equal``() = validate (Bools.Collection.ValueWrapArray) C.I.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.not_equal``() = validate (Bools.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.compare``() = validate (Bools.Collection.ValueWrapArray) C.I.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.less_than``() = validate (Bools.Collection.ValueWrapArray) C.I.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Bools.Collection.ValueWrapArray) C.I.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.greater_than``() = validate (Bools.Collection.ValueWrapArray) C.I.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Bools.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.equals``() = validate (Bools.Collection.ValueWrapArray) C.N.equals [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.equal``() = validate (Bools.Collection.ValueWrapArray) C.N.equal [| 1;0;0;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.not_equal``() = validate (Bools.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.compare``() = validate (Bools.Collection.ValueWrapArray) C.N.compare [| 0;1;-1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.less_than``() = validate (Bools.Collection.ValueWrapArray) C.N.less_than [| 0;0;1;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Bools.Collection.ValueWrapArray) C.N.less_or_equal [| 1;0;1;1 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.greater_than``() = validate (Bools.Collection.ValueWrapArray) C.N.greater_than [| 0;1;0;0 |] - [] - member __.``Bools.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Bools.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;1;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.I.equals``() = + [] + member _.``Bools.Collection.ArrayArray C.I.equals``() = validate (Bools.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.I.equal``() = + [] + member _.``Bools.Collection.ArrayArray C.I.equal``() = validate (Bools.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.I.not_equal``() = validate (Bools.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.I.compare``() = + [] + member _.``Bools.Collection.ArrayArray C.I.compare``() = validate (Bools.Collection.ArrayArray) C.I.compare [| 0;1;-1;-1;-1;0;-1;-1;1;1;0;1;1;1;-1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Bools.Collection.ArrayArray C.I.less_than``() = validate (Bools.Collection.ArrayArray) C.I.less_than [| 0;0;1;1;1;0;1;1;0;0;0;0;0;0;1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.I.less_or_equal``() = validate (Bools.Collection.ArrayArray) C.I.less_or_equal [| 1;0;1;1;1;1;1;1;0;0;1;0;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Bools.Collection.ArrayArray C.I.greater_than``() = validate (Bools.Collection.ArrayArray) C.I.greater_than [| 0;1;0;0;0;0;0;0;1;1;0;1;1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.I.greater_or_equal``() = validate (Bools.Collection.ArrayArray) C.I.greater_or_equal [| 1;1;0;0;0;1;0;0;1;1;1;1;1;1;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.N.equals``() = + [] + member _.``Bools.Collection.ArrayArray C.N.equals``() = validate (Bools.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.N.equal``() = + [] + member _.``Bools.Collection.ArrayArray C.N.equal``() = validate (Bools.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.N.not_equal``() = validate (Bools.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.N.compare``() = + [] + member _.``Bools.Collection.ArrayArray C.N.compare``() = validate (Bools.Collection.ArrayArray) C.N.compare [| 0;1;-1;-1;-1;0;-1;-1;1;1;0;1;1;1;-1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Bools.Collection.ArrayArray C.N.less_than``() = validate (Bools.Collection.ArrayArray) C.N.less_than [| 0;0;1;1;1;0;1;1;0;0;0;0;0;0;1;0 |] - [] - member __.``Bools.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.N.less_or_equal``() = validate (Bools.Collection.ArrayArray) C.N.less_or_equal [| 1;0;1;1;1;1;1;1;0;0;1;0;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Bools.Collection.ArrayArray C.N.greater_than``() = validate (Bools.Collection.ArrayArray) C.N.greater_than [| 0;1;0;0;0;0;0;0;1;1;0;1;1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray C.N.greater_or_equal``() = validate (Bools.Collection.ArrayArray) C.N.greater_or_equal [| 1;1;0;0;0;1;0;0;1;1;1;1;1;1;0;1 |] - [] - member __.``Bools.Collection.ListArray C.I.equals``() = + [] + member _.``Bools.Collection.ListArray C.I.equals``() = validate (Bools.Collection.ListArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ListArray C.I.equal``() = + [] + member _.``Bools.Collection.ListArray C.I.equal``() = validate (Bools.Collection.ListArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ListArray C.I.not_equal``() = + [] + member _.``Bools.Collection.ListArray C.I.not_equal``() = validate (Bools.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Bools.Collection.ListArray C.I.compare``() = + [] + member _.``Bools.Collection.ListArray C.I.compare``() = validate (Bools.Collection.ListArray) C.I.compare [| 0;1;-1;1;-1;0;-1;-1;1;1;0;1;-1;1;-1;0 |] - [] - member __.``Bools.Collection.ListArray C.I.less_than``() = + [] + member _.``Bools.Collection.ListArray C.I.less_than``() = validate (Bools.Collection.ListArray) C.I.less_than [| 0;0;1;0;1;0;1;1;0;0;0;0;1;0;1;0 |] - [] - member __.``Bools.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.ListArray C.I.less_or_equal``() = validate (Bools.Collection.ListArray) C.I.less_or_equal [| 1;0;1;0;1;1;1;1;0;0;1;0;1;0;1;1 |] - [] - member __.``Bools.Collection.ListArray C.I.greater_than``() = + [] + member _.``Bools.Collection.ListArray C.I.greater_than``() = validate (Bools.Collection.ListArray) C.I.greater_than [| 0;1;0;1;0;0;0;0;1;1;0;1;0;1;0;0 |] - [] - member __.``Bools.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.ListArray C.I.greater_or_equal``() = validate (Bools.Collection.ListArray) C.I.greater_or_equal [| 1;1;0;1;0;1;0;0;1;1;1;1;0;1;0;1 |] - [] - member __.``Bools.Collection.ListArray C.N.equals``() = + [] + member _.``Bools.Collection.ListArray C.N.equals``() = validate (Bools.Collection.ListArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ListArray C.N.equal``() = + [] + member _.``Bools.Collection.ListArray C.N.equal``() = validate (Bools.Collection.ListArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Bools.Collection.ListArray C.N.not_equal``() = + [] + member _.``Bools.Collection.ListArray C.N.not_equal``() = validate (Bools.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Bools.Collection.ListArray C.N.compare``() = + [] + member _.``Bools.Collection.ListArray C.N.compare``() = validate (Bools.Collection.ListArray) C.N.compare [| 0;1;-1;1;-1;0;-1;-1;1;1;0;1;-1;1;-1;0 |] - [] - member __.``Bools.Collection.ListArray C.N.less_than``() = + [] + member _.``Bools.Collection.ListArray C.N.less_than``() = validate (Bools.Collection.ListArray) C.N.less_than [| 0;0;1;0;1;0;1;1;0;0;0;0;1;0;1;0 |] - [] - member __.``Bools.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.ListArray C.N.less_or_equal``() = validate (Bools.Collection.ListArray) C.N.less_or_equal [| 1;0;1;0;1;1;1;1;0;0;1;0;1;0;1;1 |] - [] - member __.``Bools.Collection.ListArray C.N.greater_than``() = + [] + member _.``Bools.Collection.ListArray C.N.greater_than``() = validate (Bools.Collection.ListArray) C.N.greater_than [| 0;1;0;1;0;0;0;0;1;1;0;1;0;1;0;0 |] - [] - member __.``Bools.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.ListArray C.N.greater_or_equal``() = validate (Bools.Collection.ListArray) C.N.greater_or_equal [| 1;1;0;1;0;1;0;0;1;1;1;1;0;1;0;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;0;1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;1;1;1;-1;0;-1;-1;-1;1;0;0;-1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;0;0;0;1;0;1;1;1;0;0;0;1;0;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;0;0;0;1;1;1;1;1;0;1;1;1;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;1;1;1;0;0;0;0;0;1;0;0;0;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;1;1;1;0;1;0;0;0;1;1;1;0;1;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;0;1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;1;1;1;-1;0;-1;-1;-1;1;0;0;-1;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;0;0;0;1;0;1;1;1;0;0;0;1;0;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;0;0;0;1;1;1;1;1;0;1;1;1;0;1;1 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;1;1;1;0;0;0;0;0;1;0;0;0;1;0;0 |] - [] - member __.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Bools.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Bools.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;1;1;1;0;1;0;0;0;1;1;1;0;1;1;1 |] - [] - member __.``NullableBools.Collection.Array E.I.equals``() = + [] + member _.``NullableBools.Collection.Array E.I.equals``() = validate (NullableBools.Collection.Array) E.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.Array E.I.equal``() = + [] + member _.``NullableBools.Collection.Array E.I.equal``() = validate (NullableBools.Collection.Array) E.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.Array E.I.not_equal``() = + [] + member _.``NullableBools.Collection.Array E.I.not_equal``() = validate (NullableBools.Collection.Array) E.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.Array E.N.equals``() = + [] + member _.``NullableBools.Collection.Array E.N.equals``() = validate (NullableBools.Collection.Array) E.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.Array E.N.equal``() = + [] + member _.``NullableBools.Collection.Array E.N.equal``() = validate (NullableBools.Collection.Array) E.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.Array E.N.not_equal``() = + [] + member _.``NullableBools.Collection.Array E.N.not_equal``() = validate (NullableBools.Collection.Array) E.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableBools.Collection.OptionArray E.I.equals``() = validate (NullableBools.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableBools.Collection.OptionArray E.I.equal``() = validate (NullableBools.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.OptionArray E.I.not_equal``() = validate (NullableBools.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableBools.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableBools.Collection.OptionArray E.N.equals``() = validate (NullableBools.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableBools.Collection.OptionArray E.N.equal``() = validate (NullableBools.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.OptionArray E.N.not_equal``() = validate (NullableBools.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableBools.Collection.RefArray E.I.equals``() = + [] + member _.``NullableBools.Collection.RefArray E.I.equals``() = validate (NullableBools.Collection.RefArray) E.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefArray E.I.equal``() = + [] + member _.``NullableBools.Collection.RefArray E.I.equal``() = validate (NullableBools.Collection.RefArray) E.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.RefArray E.I.not_equal``() = validate (NullableBools.Collection.RefArray) E.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.RefArray E.N.equals``() = + [] + member _.``NullableBools.Collection.RefArray E.N.equals``() = validate (NullableBools.Collection.RefArray) E.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefArray E.N.equal``() = + [] + member _.``NullableBools.Collection.RefArray E.N.equal``() = validate (NullableBools.Collection.RefArray) E.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.RefArray E.N.not_equal``() = validate (NullableBools.Collection.RefArray) E.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.I.equals``() = validate (NullableBools.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.I.equal``() = validate (NullableBools.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.I.not_equal``() = validate (NullableBools.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.N.equals``() = validate (NullableBools.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.N.equal``() = validate (NullableBools.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.RefWrapArray E.N.not_equal``() = validate (NullableBools.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableBools.Collection.UnionArray E.I.equals``() = validate (NullableBools.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3097,8 +3097,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableBools.Collection.UnionArray E.I.equal``() = validate (NullableBools.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3114,8 +3114,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.UnionArray E.I.not_equal``() = validate (NullableBools.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -3131,8 +3131,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableBools.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableBools.Collection.UnionArray E.N.equals``() = validate (NullableBools.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3148,8 +3148,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableBools.Collection.UnionArray E.N.equal``() = validate (NullableBools.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3165,8 +3165,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.UnionArray E.N.not_equal``() = validate (NullableBools.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -3182,8 +3182,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.I.equals``() = validate (NullableBools.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3199,8 +3199,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.I.equal``() = validate (NullableBools.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3216,8 +3216,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableBools.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -3233,8 +3233,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.N.equals``() = validate (NullableBools.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3250,8 +3250,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.N.equal``() = validate (NullableBools.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -3267,8 +3267,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableBools.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableBools.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -3284,536 +3284,536 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableBools.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableBools.Collection.ValueArray E.I.equals``() = validate (NullableBools.Collection.ValueArray) E.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableBools.Collection.ValueArray E.I.equal``() = validate (NullableBools.Collection.ValueArray) E.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.ValueArray E.I.not_equal``() = validate (NullableBools.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableBools.Collection.ValueArray E.N.equals``() = validate (NullableBools.Collection.ValueArray) E.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableBools.Collection.ValueArray E.N.equal``() = validate (NullableBools.Collection.ValueArray) E.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.ValueArray E.N.not_equal``() = validate (NullableBools.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.I.equals``() = validate (NullableBools.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.I.equal``() = validate (NullableBools.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableBools.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.N.equals``() = validate (NullableBools.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.N.equal``() = validate (NullableBools.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableBools.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableBools.Collection.ArrayArray E.I.equals``() = validate (NullableBools.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableBools.Collection.ArrayArray E.I.equal``() = validate (NullableBools.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.ArrayArray E.I.not_equal``() = validate (NullableBools.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableBools.Collection.ArrayArray E.N.equals``() = validate (NullableBools.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableBools.Collection.ArrayArray E.N.equal``() = validate (NullableBools.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.ArrayArray E.N.not_equal``() = validate (NullableBools.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ListArray E.I.equals``() = + [] + member _.``NullableBools.Collection.ListArray E.I.equals``() = validate (NullableBools.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ListArray E.I.equal``() = + [] + member _.``NullableBools.Collection.ListArray E.I.equal``() = validate (NullableBools.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableBools.Collection.ListArray E.I.not_equal``() = validate (NullableBools.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBools.Collection.ListArray E.N.equals``() = + [] + member _.``NullableBools.Collection.ListArray E.N.equals``() = validate (NullableBools.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ListArray E.N.equal``() = + [] + member _.``NullableBools.Collection.ListArray E.N.equal``() = validate (NullableBools.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBools.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableBools.Collection.ListArray E.N.not_equal``() = validate (NullableBools.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.I.equals``() = + [] + member _.``SBytes.Collection.Array C.I.equals``() = validate (SBytes.Collection.Array) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.I.equal``() = + [] + member _.``SBytes.Collection.Array C.I.equal``() = validate (SBytes.Collection.Array) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.I.not_equal``() = + [] + member _.``SBytes.Collection.Array C.I.not_equal``() = validate (SBytes.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.I.compare``() = + [] + member _.``SBytes.Collection.Array C.I.compare``() = validate (SBytes.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.I.less_than``() = + [] + member _.``SBytes.Collection.Array C.I.less_than``() = validate (SBytes.Collection.Array) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.Array C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.Array C.I.less_or_equal``() = validate (SBytes.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.I.greater_than``() = + [] + member _.``SBytes.Collection.Array C.I.greater_than``() = validate (SBytes.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.Array C.I.greater_or_equal``() = validate (SBytes.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.Array C.N.equals``() = + [] + member _.``SBytes.Collection.Array C.N.equals``() = validate (SBytes.Collection.Array) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.N.equal``() = + [] + member _.``SBytes.Collection.Array C.N.equal``() = validate (SBytes.Collection.Array) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.N.not_equal``() = + [] + member _.``SBytes.Collection.Array C.N.not_equal``() = validate (SBytes.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.N.compare``() = + [] + member _.``SBytes.Collection.Array C.N.compare``() = validate (SBytes.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.N.less_than``() = + [] + member _.``SBytes.Collection.Array C.N.less_than``() = validate (SBytes.Collection.Array) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.Array C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.Array C.N.less_or_equal``() = validate (SBytes.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.Array C.N.greater_than``() = + [] + member _.``SBytes.Collection.Array C.N.greater_than``() = validate (SBytes.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.Array C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.Array C.N.greater_or_equal``() = validate (SBytes.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.OptionArray C.I.equals``() = + [] + member _.``SBytes.Collection.OptionArray C.I.equals``() = validate (SBytes.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.I.equal``() = + [] + member _.``SBytes.Collection.OptionArray C.I.equal``() = validate (SBytes.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.I.not_equal``() = validate (SBytes.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.I.compare``() = + [] + member _.``SBytes.Collection.OptionArray C.I.compare``() = validate (SBytes.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-255;-127;-128;-129;1;255;0;128;127;126;1;127;-128;0;-1;-2;1;128;-127;1;0;-1;1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.I.less_than``() = + [] + member _.``SBytes.Collection.OptionArray C.I.less_than``() = validate (SBytes.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.I.less_or_equal``() = validate (SBytes.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.OptionArray C.I.greater_than``() = validate (SBytes.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.I.greater_or_equal``() = validate (SBytes.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.OptionArray C.N.equals``() = + [] + member _.``SBytes.Collection.OptionArray C.N.equals``() = validate (SBytes.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.N.equal``() = + [] + member _.``SBytes.Collection.OptionArray C.N.equal``() = validate (SBytes.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.N.not_equal``() = validate (SBytes.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.N.compare``() = + [] + member _.``SBytes.Collection.OptionArray C.N.compare``() = validate (SBytes.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-255;-127;-128;-129;1;255;0;128;127;126;1;127;-128;0;-1;-2;1;128;-127;1;0;-1;1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.N.less_than``() = + [] + member _.``SBytes.Collection.OptionArray C.N.less_than``() = validate (SBytes.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.N.less_or_equal``() = validate (SBytes.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.OptionArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.OptionArray C.N.greater_than``() = validate (SBytes.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.OptionArray C.N.greater_or_equal``() = validate (SBytes.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.RefArray C.I.equals``() = + [] + member _.``SBytes.Collection.RefArray C.I.equals``() = validate (SBytes.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.I.equal``() = + [] + member _.``SBytes.Collection.RefArray C.I.equal``() = validate (SBytes.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.RefArray C.I.not_equal``() = validate (SBytes.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.I.compare``() = + [] + member _.``SBytes.Collection.RefArray C.I.compare``() = validate (SBytes.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.I.less_than``() = + [] + member _.``SBytes.Collection.RefArray C.I.less_than``() = validate (SBytes.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.RefArray C.I.less_or_equal``() = validate (SBytes.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.RefArray C.I.greater_than``() = validate (SBytes.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.RefArray C.I.greater_or_equal``() = validate (SBytes.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.RefArray C.N.equals``() = + [] + member _.``SBytes.Collection.RefArray C.N.equals``() = validate (SBytes.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.N.equal``() = + [] + member _.``SBytes.Collection.RefArray C.N.equal``() = validate (SBytes.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.RefArray C.N.not_equal``() = validate (SBytes.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.N.compare``() = + [] + member _.``SBytes.Collection.RefArray C.N.compare``() = validate (SBytes.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.N.less_than``() = + [] + member _.``SBytes.Collection.RefArray C.N.less_than``() = validate (SBytes.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.RefArray C.N.less_or_equal``() = validate (SBytes.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.RefArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.RefArray C.N.greater_than``() = validate (SBytes.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.RefArray C.N.greater_or_equal``() = validate (SBytes.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.equals``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.equals``() = validate (SBytes.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.equal``() = validate (SBytes.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.not_equal``() = validate (SBytes.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.compare``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.compare``() = validate (SBytes.Collection.RefWrapArray) C.I.compare [| 0;-255;-127;-128;-129;255;0;128;127;126;127;-128;0;-1;-2;128;-127;1;0;-1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.less_than``() = validate (SBytes.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.less_or_equal``() = validate (SBytes.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.greater_than``() = validate (SBytes.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.I.greater_or_equal``() = validate (SBytes.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.equals``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.equals``() = validate (SBytes.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.equal``() = validate (SBytes.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.not_equal``() = validate (SBytes.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.compare``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.compare``() = validate (SBytes.Collection.RefWrapArray) C.N.compare [| 0;-255;-127;-128;-129;255;0;128;127;126;127;-128;0;-1;-2;128;-127;1;0;-1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.less_than``() = validate (SBytes.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.less_or_equal``() = validate (SBytes.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.greater_than``() = validate (SBytes.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.RefWrapArray C.N.greater_or_equal``() = validate (SBytes.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.UnionArray C.I.equals``() = + [] + member _.``SBytes.Collection.UnionArray C.I.equals``() = validate (SBytes.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -3848,8 +3848,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.I.equal``() = + [] + member _.``SBytes.Collection.UnionArray C.I.equal``() = validate (SBytes.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -3884,8 +3884,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.I.not_equal``() = validate (SBytes.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -3920,8 +3920,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.I.compare``() = + [] + member _.``SBytes.Collection.UnionArray C.I.compare``() = validate (SBytes.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -3956,8 +3956,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.I.less_than``() = + [] + member _.``SBytes.Collection.UnionArray C.I.less_than``() = validate (SBytes.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -3992,8 +3992,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.I.less_or_equal``() = validate (SBytes.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -4028,8 +4028,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.UnionArray C.I.greater_than``() = validate (SBytes.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -4064,8 +4064,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.I.greater_or_equal``() = validate (SBytes.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -4100,8 +4100,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.UnionArray C.N.equals``() = + [] + member _.``SBytes.Collection.UnionArray C.N.equals``() = validate (SBytes.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4136,8 +4136,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.N.equal``() = + [] + member _.``SBytes.Collection.UnionArray C.N.equal``() = validate (SBytes.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4172,8 +4172,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.N.not_equal``() = validate (SBytes.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -4208,8 +4208,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.N.compare``() = + [] + member _.``SBytes.Collection.UnionArray C.N.compare``() = validate (SBytes.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -4244,8 +4244,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.N.less_than``() = + [] + member _.``SBytes.Collection.UnionArray C.N.less_than``() = validate (SBytes.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -4280,8 +4280,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.N.less_or_equal``() = validate (SBytes.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -4316,8 +4316,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.UnionArray C.N.greater_than``() = validate (SBytes.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -4352,8 +4352,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.UnionArray C.N.greater_or_equal``() = validate (SBytes.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -4388,8 +4388,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.equals``() = validate (SBytes.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4424,8 +4424,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.equal``() = validate (SBytes.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4460,8 +4460,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.not_equal``() = validate (SBytes.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -4496,8 +4496,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.compare``() = validate (SBytes.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-255;-1;-2;-3;-3;-3;-3;-127;-1;-2;-3;-3;-3;-3;-128;-1;-2;-3;-3;-3;-3;-129;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-255;-1;-2;-2;-2;-2;1;-127;-1;-2;-2;-2;-2;1;-128;-1;-2;-2;-2;-2;1;-129;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-255; @@ -4532,8 +4532,8 @@ type GeneratedTestSuite () = 3;2;1;-126;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.less_than``() = validate (SBytes.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -4568,8 +4568,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.less_or_equal``() = validate (SBytes.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -4604,8 +4604,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.greater_than``() = validate (SBytes.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -4640,8 +4640,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (SBytes.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -4676,8 +4676,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.equals``() = validate (SBytes.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4712,8 +4712,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.equal``() = validate (SBytes.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -4748,8 +4748,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.not_equal``() = validate (SBytes.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -4784,8 +4784,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.compare``() = validate (SBytes.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-255;-1;-2;-3;-3;-3;-3;-127;-1;-2;-3;-3;-3;-3;-128;-1;-2;-3;-3;-3;-3;-129;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-255;-1;-2;-2;-2;-2;1;-127;-1;-2;-2;-2;-2;1;-128;-1;-2;-2;-2;-2;1;-129;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-255; @@ -4820,8 +4820,8 @@ type GeneratedTestSuite () = 3;2;1;-126;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.less_than``() = validate (SBytes.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -4856,8 +4856,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.less_or_equal``() = validate (SBytes.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -4892,8 +4892,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.greater_than``() = validate (SBytes.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -4928,8 +4928,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (SBytes.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -4964,734 +4964,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.ValueArray C.I.equals``() = + [] + member _.``SBytes.Collection.ValueArray C.I.equals``() = validate (SBytes.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.I.equal``() = + [] + member _.``SBytes.Collection.ValueArray C.I.equal``() = validate (SBytes.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.I.not_equal``() = validate (SBytes.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.I.compare``() = + [] + member _.``SBytes.Collection.ValueArray C.I.compare``() = validate (SBytes.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.I.less_than``() = + [] + member _.``SBytes.Collection.ValueArray C.I.less_than``() = validate (SBytes.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.I.less_or_equal``() = validate (SBytes.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.ValueArray C.I.greater_than``() = validate (SBytes.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.I.greater_or_equal``() = validate (SBytes.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ValueArray C.N.equals``() = + [] + member _.``SBytes.Collection.ValueArray C.N.equals``() = validate (SBytes.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.N.equal``() = + [] + member _.``SBytes.Collection.ValueArray C.N.equal``() = validate (SBytes.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.N.not_equal``() = validate (SBytes.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.N.compare``() = + [] + member _.``SBytes.Collection.ValueArray C.N.compare``() = validate (SBytes.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.N.less_than``() = + [] + member _.``SBytes.Collection.ValueArray C.N.less_than``() = validate (SBytes.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.N.less_or_equal``() = validate (SBytes.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ValueArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.ValueArray C.N.greater_than``() = validate (SBytes.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.ValueArray C.N.greater_or_equal``() = validate (SBytes.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.equals``() = validate (SBytes.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.equal``() = validate (SBytes.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.not_equal``() = validate (SBytes.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.compare``() = validate (SBytes.Collection.ValueWrapArray) C.I.compare [| 0;-255;-127;-128;-129;255;0;128;127;126;127;-128;0;-1;-2;128;-127;1;0;-1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.less_than``() = validate (SBytes.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.less_or_equal``() = validate (SBytes.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.greater_than``() = validate (SBytes.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (SBytes.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.equals``() = validate (SBytes.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.equal``() = validate (SBytes.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.not_equal``() = validate (SBytes.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.compare``() = validate (SBytes.Collection.ValueWrapArray) C.N.compare [| 0;-255;-127;-128;-129;255;0;128;127;126;127;-128;0;-1;-2;128;-127;1;0;-1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.less_than``() = validate (SBytes.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.less_or_equal``() = validate (SBytes.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.greater_than``() = validate (SBytes.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (SBytes.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.equals``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.equals``() = validate (SBytes.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.equal``() = validate (SBytes.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.not_equal``() = validate (SBytes.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.compare``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.compare``() = validate (SBytes.Collection.ArrayArray) C.I.compare [| 0;1;-1;1;1;-1;-1;-1;-1;-1;-1;0;-1;1;1;-1;-1;-1;-1;-1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1; -1;-1;-1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;1;-1;1;1;1;1;1;1;1;-1;0;-1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;-1;-1;-1;0;-1;1;1;1;1;1;-1;-1;-1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.less_than``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.less_than``() = validate (SBytes.Collection.ArrayArray) C.I.less_than [| 0;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;0;0;0;0;1;1;1;0;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.less_or_equal``() = validate (SBytes.Collection.ArrayArray) C.I.less_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.greater_than``() = validate (SBytes.Collection.ArrayArray) C.I.greater_than [| 0;1;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.I.greater_or_equal``() = validate (SBytes.Collection.ArrayArray) C.I.greater_or_equal [| 1;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;0;0;1;0;1;1;1;1;1;0;0;0;1;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.equals``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.equals``() = validate (SBytes.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.equal``() = validate (SBytes.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.not_equal``() = validate (SBytes.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.compare``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.compare``() = validate (SBytes.Collection.ArrayArray) C.N.compare [| 0;1;-1;1;1;-1;-1;-1;-1;-1;-1;0;-1;1;1;-1;-1;-1;-1;-1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1; -1;-1;-1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;1;-1;1;1;1;1;1;1;1;-1;0;-1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;-1;-1;-1;0;-1;1;1;1;1;1;-1;-1;-1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.less_than``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.less_than``() = validate (SBytes.Collection.ArrayArray) C.N.less_than [| 0;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;0;0;0;0;1;1;1;0;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.less_or_equal``() = validate (SBytes.Collection.ArrayArray) C.N.less_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.greater_than``() = validate (SBytes.Collection.ArrayArray) C.N.greater_than [| 0;1;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray C.N.greater_or_equal``() = validate (SBytes.Collection.ArrayArray) C.N.greater_or_equal [| 1;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;0;0;0;1;0;1;1;1;1;1;0;0;0;1;1 |] - [] - member __.``SBytes.Collection.ListArray C.I.equals``() = + [] + member _.``SBytes.Collection.ListArray C.I.equals``() = validate (SBytes.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.I.equal``() = + [] + member _.``SBytes.Collection.ListArray C.I.equal``() = validate (SBytes.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.ListArray C.I.not_equal``() = validate (SBytes.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.I.compare``() = + [] + member _.``SBytes.Collection.ListArray C.I.compare``() = validate (SBytes.Collection.ListArray) C.I.compare [| 0;-255;-127;-128;-129;-1;-255;-127;-128;-129;255;0;128;127;126;255;-1;128;127;126;127;-128;0;-1;-2;127;-128;-1;-1;-2;128;-127;1;0;-1;128;-127;1;-1;-1; 129;-126;2;1;0;129;-126;2;1;-1;1;-255;-127;-128;-129;0;-255;-127;-128;-129;255;1;128;127;126;255;0;128;127;126;127;-128;1;-1;-2;127;-128;0;-1;-2; 128;-127;1;1;-1;128;-127;1;0;-1;129;-126;2;1;1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.I.less_than``() = + [] + member _.``SBytes.Collection.ListArray C.I.less_than``() = validate (SBytes.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.ListArray C.I.less_or_equal``() = validate (SBytes.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.ListArray C.I.greater_than``() = validate (SBytes.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.ListArray C.I.greater_or_equal``() = validate (SBytes.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ListArray C.N.equals``() = + [] + member _.``SBytes.Collection.ListArray C.N.equals``() = validate (SBytes.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.N.equal``() = + [] + member _.``SBytes.Collection.ListArray C.N.equal``() = validate (SBytes.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.ListArray C.N.not_equal``() = validate (SBytes.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.N.compare``() = + [] + member _.``SBytes.Collection.ListArray C.N.compare``() = validate (SBytes.Collection.ListArray) C.N.compare [| 0;-255;-127;-128;-129;-1;-255;-127;-128;-129;255;0;128;127;126;255;-1;128;127;126;127;-128;0;-1;-2;127;-128;-1;-1;-2;128;-127;1;0;-1;128;-127;1;-1;-1; 129;-126;2;1;0;129;-126;2;1;-1;1;-255;-127;-128;-129;0;-255;-127;-128;-129;255;1;128;127;126;255;0;128;127;126;127;-128;1;-1;-2;127;-128;0;-1;-2; 128;-127;1;1;-1;128;-127;1;0;-1;129;-126;2;1;1;129;-126;2;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.N.less_than``() = + [] + member _.``SBytes.Collection.ListArray C.N.less_than``() = validate (SBytes.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``SBytes.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.ListArray C.N.less_or_equal``() = validate (SBytes.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``SBytes.Collection.ListArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.ListArray C.N.greater_than``() = validate (SBytes.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``SBytes.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.ListArray C.N.greater_or_equal``() = validate (SBytes.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``SBytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (SBytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.Array E.I.equals``() = + [] + member _.``NullableSbytes.Collection.Array E.I.equals``() = validate (NullableSbytes.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.Array E.I.equal``() = + [] + member _.``NullableSbytes.Collection.Array E.I.equal``() = validate (NullableSbytes.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.Array E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.Array E.I.not_equal``() = validate (NullableSbytes.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.Array E.N.equals``() = + [] + member _.``NullableSbytes.Collection.Array E.N.equals``() = validate (NullableSbytes.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.Array E.N.equal``() = + [] + member _.``NullableSbytes.Collection.Array E.N.equal``() = validate (NullableSbytes.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.Array E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.Array E.N.not_equal``() = validate (NullableSbytes.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.I.equals``() = validate (NullableSbytes.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.I.equal``() = validate (NullableSbytes.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.I.not_equal``() = validate (NullableSbytes.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.N.equals``() = validate (NullableSbytes.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.N.equal``() = validate (NullableSbytes.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.OptionArray E.N.not_equal``() = validate (NullableSbytes.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.RefArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.RefArray E.I.equals``() = validate (NullableSbytes.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.RefArray E.I.equal``() = validate (NullableSbytes.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.RefArray E.I.not_equal``() = validate (NullableSbytes.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.RefArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.RefArray E.N.equals``() = validate (NullableSbytes.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.RefArray E.N.equal``() = validate (NullableSbytes.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.RefArray E.N.not_equal``() = validate (NullableSbytes.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.I.equals``() = validate (NullableSbytes.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.I.equal``() = validate (NullableSbytes.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.I.not_equal``() = validate (NullableSbytes.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.N.equals``() = validate (NullableSbytes.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.N.equal``() = validate (NullableSbytes.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.RefWrapArray E.N.not_equal``() = validate (NullableSbytes.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.I.equals``() = validate (NullableSbytes.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -5740,8 +5740,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.I.equal``() = validate (NullableSbytes.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -5790,8 +5790,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.I.not_equal``() = validate (NullableSbytes.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -5840,8 +5840,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.N.equals``() = validate (NullableSbytes.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -5890,8 +5890,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.N.equal``() = validate (NullableSbytes.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -5940,8 +5940,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.UnionArray E.N.not_equal``() = validate (NullableSbytes.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -5990,8 +5990,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.I.equals``() = validate (NullableSbytes.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -6040,8 +6040,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.I.equal``() = validate (NullableSbytes.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -6090,8 +6090,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableSbytes.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -6140,8 +6140,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.N.equals``() = validate (NullableSbytes.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -6190,8 +6190,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.N.equal``() = validate (NullableSbytes.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -6240,8 +6240,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableSbytes.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -6290,80 +6290,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.I.equals``() = validate (NullableSbytes.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.I.equal``() = validate (NullableSbytes.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.I.not_equal``() = validate (NullableSbytes.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.N.equals``() = validate (NullableSbytes.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.N.equal``() = validate (NullableSbytes.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.ValueArray E.N.not_equal``() = validate (NullableSbytes.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.I.equals``() = validate (NullableSbytes.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.I.equal``() = validate (NullableSbytes.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableSbytes.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.N.equals``() = validate (NullableSbytes.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.N.equal``() = validate (NullableSbytes.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableSbytes.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.I.equals``() = validate (NullableSbytes.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6371,8 +6371,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.I.equal``() = validate (NullableSbytes.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6380,8 +6380,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.I.not_equal``() = validate (NullableSbytes.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -6389,8 +6389,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.N.equals``() = validate (NullableSbytes.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6398,8 +6398,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.N.equal``() = validate (NullableSbytes.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6407,8 +6407,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.ArrayArray E.N.not_equal``() = validate (NullableSbytes.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -6416,8 +6416,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ListArray E.I.equals``() = + [] + member _.``NullableSbytes.Collection.ListArray E.I.equals``() = validate (NullableSbytes.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6425,8 +6425,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ListArray E.I.equal``() = + [] + member _.``NullableSbytes.Collection.ListArray E.I.equal``() = validate (NullableSbytes.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6434,8 +6434,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableSbytes.Collection.ListArray E.I.not_equal``() = validate (NullableSbytes.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -6443,8 +6443,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableSbytes.Collection.ListArray E.N.equals``() = + [] + member _.``NullableSbytes.Collection.ListArray E.N.equals``() = validate (NullableSbytes.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6452,8 +6452,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ListArray E.N.equal``() = + [] + member _.``NullableSbytes.Collection.ListArray E.N.equal``() = validate (NullableSbytes.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -6461,8 +6461,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableSbytes.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableSbytes.Collection.ListArray E.N.not_equal``() = validate (NullableSbytes.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -6470,392 +6470,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.I.equals``() = + [] + member _.``Int16s.Collection.Array C.I.equals``() = validate (Int16s.Collection.Array) C.I.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.I.equal``() = + [] + member _.``Int16s.Collection.Array C.I.equal``() = validate (Int16s.Collection.Array) C.I.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.I.not_equal``() = + [] + member _.``Int16s.Collection.Array C.I.not_equal``() = validate (Int16s.Collection.Array) C.I.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.I.compare``() = + [] + member _.``Int16s.Collection.Array C.I.compare``() = validate (Int16s.Collection.Array) C.I.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.I.less_than``() = + [] + member _.``Int16s.Collection.Array C.I.less_than``() = validate (Int16s.Collection.Array) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.Array C.I.less_or_equal``() = validate (Int16s.Collection.Array) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.I.greater_than``() = + [] + member _.``Int16s.Collection.Array C.I.greater_than``() = validate (Int16s.Collection.Array) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.Array C.I.greater_or_equal``() = validate (Int16s.Collection.Array) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.Array C.N.equals``() = + [] + member _.``Int16s.Collection.Array C.N.equals``() = validate (Int16s.Collection.Array) C.N.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.N.equal``() = + [] + member _.``Int16s.Collection.Array C.N.equal``() = validate (Int16s.Collection.Array) C.N.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.N.not_equal``() = + [] + member _.``Int16s.Collection.Array C.N.not_equal``() = validate (Int16s.Collection.Array) C.N.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.N.compare``() = + [] + member _.``Int16s.Collection.Array C.N.compare``() = validate (Int16s.Collection.Array) C.N.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.N.less_than``() = + [] + member _.``Int16s.Collection.Array C.N.less_than``() = validate (Int16s.Collection.Array) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.Array C.N.less_or_equal``() = validate (Int16s.Collection.Array) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.Array C.N.greater_than``() = + [] + member _.``Int16s.Collection.Array C.N.greater_than``() = validate (Int16s.Collection.Array) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.Array C.N.greater_or_equal``() = validate (Int16s.Collection.Array) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.OptionArray C.I.equals``() = + [] + member _.``Int16s.Collection.OptionArray C.I.equals``() = validate (Int16s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.I.equal``() = + [] + member _.``Int16s.Collection.OptionArray C.I.equal``() = validate (Int16s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.I.not_equal``() = validate (Int16s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.I.compare``() = + [] + member _.``Int16s.Collection.OptionArray C.I.compare``() = validate (Int16s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;0;32768;32767;32766;1;0;0;32768;32767;32766;1;-32768;-32768;0;-1;-2;1;-32767;-32767;1;0;-1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Int16s.Collection.OptionArray C.I.less_than``() = validate (Int16s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;0;1;1;0;0;1;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.I.less_or_equal``() = validate (Int16s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;0;1;1;0;1;1;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.OptionArray C.I.greater_than``() = validate (Int16s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;1;0;0;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.I.greater_or_equal``() = validate (Int16s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;1;0;0;1;1;0;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.OptionArray C.N.equals``() = + [] + member _.``Int16s.Collection.OptionArray C.N.equals``() = validate (Int16s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.N.equal``() = + [] + member _.``Int16s.Collection.OptionArray C.N.equal``() = validate (Int16s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.N.not_equal``() = validate (Int16s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.N.compare``() = + [] + member _.``Int16s.Collection.OptionArray C.N.compare``() = validate (Int16s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;0;32768;32767;32766;1;0;0;32768;32767;32766;1;-32768;-32768;0;-1;-2;1;-32767;-32767;1;0;-1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Int16s.Collection.OptionArray C.N.less_than``() = validate (Int16s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;0;1;1;0;0;1;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.N.less_or_equal``() = validate (Int16s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;0;1;1;0;1;1;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.OptionArray C.N.greater_than``() = validate (Int16s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;1;0;0;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.OptionArray C.N.greater_or_equal``() = validate (Int16s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;1;0;0;1;1;0;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.RefArray C.I.equals``() = + [] + member _.``Int16s.Collection.RefArray C.I.equals``() = validate (Int16s.Collection.RefArray) C.I.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.I.equal``() = + [] + member _.``Int16s.Collection.RefArray C.I.equal``() = validate (Int16s.Collection.RefArray) C.I.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.RefArray C.I.not_equal``() = validate (Int16s.Collection.RefArray) C.I.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.I.compare``() = + [] + member _.``Int16s.Collection.RefArray C.I.compare``() = validate (Int16s.Collection.RefArray) C.I.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.I.less_than``() = + [] + member _.``Int16s.Collection.RefArray C.I.less_than``() = validate (Int16s.Collection.RefArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.RefArray C.I.less_or_equal``() = validate (Int16s.Collection.RefArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.RefArray C.I.greater_than``() = validate (Int16s.Collection.RefArray) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.RefArray C.I.greater_or_equal``() = validate (Int16s.Collection.RefArray) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.RefArray C.N.equals``() = + [] + member _.``Int16s.Collection.RefArray C.N.equals``() = validate (Int16s.Collection.RefArray) C.N.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.N.equal``() = + [] + member _.``Int16s.Collection.RefArray C.N.equal``() = validate (Int16s.Collection.RefArray) C.N.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.RefArray C.N.not_equal``() = validate (Int16s.Collection.RefArray) C.N.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.N.compare``() = + [] + member _.``Int16s.Collection.RefArray C.N.compare``() = validate (Int16s.Collection.RefArray) C.N.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.N.less_than``() = + [] + member _.``Int16s.Collection.RefArray C.N.less_than``() = validate (Int16s.Collection.RefArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.RefArray C.N.less_or_equal``() = validate (Int16s.Collection.RefArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.RefArray C.N.greater_than``() = validate (Int16s.Collection.RefArray) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.RefArray C.N.greater_or_equal``() = validate (Int16s.Collection.RefArray) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.equals``() = validate (Int16s.Collection.RefWrapArray) C.I.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.equal``() = validate (Int16s.Collection.RefWrapArray) C.I.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.not_equal``() = validate (Int16s.Collection.RefWrapArray) C.I.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.compare``() = validate (Int16s.Collection.RefWrapArray) C.I.compare [| 0;0;32768;32767;32766;0;0;32768;32767;32766;-32768;-32768;0;-1;-2;-32767;-32767;1;0;-1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.less_than``() = validate (Int16s.Collection.RefWrapArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Int16s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.greater_than``() = validate (Int16s.Collection.RefWrapArray) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Int16s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.equals``() = validate (Int16s.Collection.RefWrapArray) C.N.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.equal``() = validate (Int16s.Collection.RefWrapArray) C.N.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.not_equal``() = validate (Int16s.Collection.RefWrapArray) C.N.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.compare``() = validate (Int16s.Collection.RefWrapArray) C.N.compare [| 0;0;32768;32767;32766;0;0;32768;32767;32766;-32768;-32768;0;-1;-2;-32767;-32767;1;0;-1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.less_than``() = validate (Int16s.Collection.RefWrapArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Int16s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.greater_than``() = validate (Int16s.Collection.RefWrapArray) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Int16s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.UnionArray C.I.equals``() = + [] + member _.``Int16s.Collection.UnionArray C.I.equals``() = validate (Int16s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -6890,8 +6890,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.I.equal``() = + [] + member _.``Int16s.Collection.UnionArray C.I.equal``() = validate (Int16s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -6926,8 +6926,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.I.not_equal``() = validate (Int16s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0; @@ -6962,8 +6962,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.I.compare``() = + [] + member _.``Int16s.Collection.UnionArray C.I.compare``() = validate (Int16s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;0; @@ -6998,8 +6998,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Int16s.Collection.UnionArray C.I.less_than``() = validate (Int16s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -7034,8 +7034,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int16s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.I.less_or_equal``() = validate (Int16s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -7070,8 +7070,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.UnionArray C.I.greater_than``() = validate (Int16s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -7106,8 +7106,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.I.greater_or_equal``() = validate (Int16s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -7142,8 +7142,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int16s.Collection.UnionArray C.N.equals``() = + [] + member _.``Int16s.Collection.UnionArray C.N.equals``() = validate (Int16s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7178,8 +7178,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.N.equal``() = + [] + member _.``Int16s.Collection.UnionArray C.N.equal``() = validate (Int16s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7214,8 +7214,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.N.not_equal``() = validate (Int16s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0; @@ -7250,8 +7250,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.N.compare``() = + [] + member _.``Int16s.Collection.UnionArray C.N.compare``() = validate (Int16s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;0;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;1;1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;0; @@ -7286,8 +7286,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Int16s.Collection.UnionArray C.N.less_than``() = validate (Int16s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -7322,8 +7322,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int16s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.N.less_or_equal``() = validate (Int16s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -7358,8 +7358,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.UnionArray C.N.greater_than``() = validate (Int16s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -7394,8 +7394,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.UnionArray C.N.greater_or_equal``() = validate (Int16s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -7430,8 +7430,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.equals``() = validate (Int16s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7466,8 +7466,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.equal``() = validate (Int16s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7502,8 +7502,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.not_equal``() = validate (Int16s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0; @@ -7538,8 +7538,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.compare``() = validate (Int16s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;32768;-1;-2;-3;-3;-3;-3;32767;-1;-2;-3;-3;-3;-3;32766;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;0;-1;-2;-2;-2;-2;1;32768;-1;-2;-2;-2;-2;1;32767;-1;-2;-2;-2;-2;1;32766;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;0; @@ -7574,8 +7574,8 @@ type GeneratedTestSuite () = 3;2;1;-32766;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.less_than``() = validate (Int16s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -7610,8 +7610,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Int16s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -7646,8 +7646,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.greater_than``() = validate (Int16s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -7682,8 +7682,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Int16s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -7718,8 +7718,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.equals``() = validate (Int16s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7754,8 +7754,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.equal``() = validate (Int16s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1; @@ -7790,8 +7790,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.not_equal``() = validate (Int16s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0; @@ -7826,8 +7826,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.compare``() = validate (Int16s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;32768;-1;-2;-3;-3;-3;-3;32767;-1;-2;-3;-3;-3;-3;32766;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;0;-1;-2;-2;-2;-2;1;32768;-1;-2;-2;-2;-2;1;32767;-1;-2;-2;-2;-2;1;32766;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;0; @@ -7862,8 +7862,8 @@ type GeneratedTestSuite () = 3;2;1;-32766;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.less_than``() = validate (Int16s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -7898,8 +7898,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Int16s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -7934,8 +7934,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.greater_than``() = validate (Int16s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -7970,8 +7970,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Int16s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -8006,734 +8006,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int16s.Collection.ValueArray C.I.equals``() = + [] + member _.``Int16s.Collection.ValueArray C.I.equals``() = validate (Int16s.Collection.ValueArray) C.I.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.I.equal``() = + [] + member _.``Int16s.Collection.ValueArray C.I.equal``() = validate (Int16s.Collection.ValueArray) C.I.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.I.not_equal``() = validate (Int16s.Collection.ValueArray) C.I.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.I.compare``() = + [] + member _.``Int16s.Collection.ValueArray C.I.compare``() = validate (Int16s.Collection.ValueArray) C.I.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Int16s.Collection.ValueArray C.I.less_than``() = validate (Int16s.Collection.ValueArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.I.less_or_equal``() = validate (Int16s.Collection.ValueArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.ValueArray C.I.greater_than``() = validate (Int16s.Collection.ValueArray) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.I.greater_or_equal``() = validate (Int16s.Collection.ValueArray) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ValueArray C.N.equals``() = + [] + member _.``Int16s.Collection.ValueArray C.N.equals``() = validate (Int16s.Collection.ValueArray) C.N.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.N.equal``() = + [] + member _.``Int16s.Collection.ValueArray C.N.equal``() = validate (Int16s.Collection.ValueArray) C.N.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.N.not_equal``() = validate (Int16s.Collection.ValueArray) C.N.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.N.compare``() = + [] + member _.``Int16s.Collection.ValueArray C.N.compare``() = validate (Int16s.Collection.ValueArray) C.N.compare [| 0;0;1;1;1;0;0;1;1;1;-1;-1;0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Int16s.Collection.ValueArray C.N.less_than``() = validate (Int16s.Collection.ValueArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.N.less_or_equal``() = validate (Int16s.Collection.ValueArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.ValueArray C.N.greater_than``() = validate (Int16s.Collection.ValueArray) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.ValueArray C.N.greater_or_equal``() = validate (Int16s.Collection.ValueArray) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.equals``() = validate (Int16s.Collection.ValueWrapArray) C.I.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.equal``() = validate (Int16s.Collection.ValueWrapArray) C.I.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.not_equal``() = validate (Int16s.Collection.ValueWrapArray) C.I.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.compare``() = validate (Int16s.Collection.ValueWrapArray) C.I.compare [| 0;0;32768;32767;32766;0;0;32768;32767;32766;-32768;-32768;0;-1;-2;-32767;-32767;1;0;-1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.less_than``() = validate (Int16s.Collection.ValueWrapArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Int16s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.greater_than``() = validate (Int16s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Int16s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.equals``() = validate (Int16s.Collection.ValueWrapArray) C.N.equals [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.equal``() = validate (Int16s.Collection.ValueWrapArray) C.N.equal [| 1;1;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.not_equal``() = validate (Int16s.Collection.ValueWrapArray) C.N.not_equal [| 0;0;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.compare``() = validate (Int16s.Collection.ValueWrapArray) C.N.compare [| 0;0;32768;32767;32766;0;0;32768;32767;32766;-32768;-32768;0;-1;-2;-32767;-32767;1;0;-1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.less_than``() = validate (Int16s.Collection.ValueWrapArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;0;0;1;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Int16s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.greater_than``() = validate (Int16s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Int16s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;1;1;0;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.equals``() = validate (Int16s.Collection.ArrayArray) C.I.equals [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.equal``() = validate (Int16s.Collection.ArrayArray) C.I.equal [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.not_equal``() = validate (Int16s.Collection.ArrayArray) C.I.not_equal [| 0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.compare``() = validate (Int16s.Collection.ArrayArray) C.I.compare [| 0;0;32768;32767;32766;-1;-1;-1;-1;-1;0;0;32768;32767;32766;-1;-1;-1;-1;-1;-32768;-32768;0;-1;-2;-1;-1;-1;-1;-1;-32767;-32767;1;0;-1;-1;-1;-1;-1;-1; -32766;-32766;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;32768;32768;32767;32766;1;1;1;1;1;-32768;0;32768;32767;32766;1;1;1;1;1;-32768;-32768;0;-1;-2; 1;1;1;1;1;-32767;-32767;1;0;-1;1;1;1;1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.less_than``() = validate (Int16s.Collection.ArrayArray) C.I.less_than [| 0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1; 1;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;1;1;0;0;1;0;0;0;0;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.less_or_equal``() = validate (Int16s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;1;1;1;1;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.greater_than``() = validate (Int16s.Collection.ArrayArray) C.I.greater_than [| 0;0;1;1;1;0;0;0;0;0;0;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Int16s.Collection.ArrayArray) C.I.greater_or_equal [| 1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0; 0;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;0;0;1;1;0;1;1;1;1;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.equals``() = validate (Int16s.Collection.ArrayArray) C.N.equals [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.equal``() = validate (Int16s.Collection.ArrayArray) C.N.equal [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.not_equal``() = validate (Int16s.Collection.ArrayArray) C.N.not_equal [| 0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.compare``() = validate (Int16s.Collection.ArrayArray) C.N.compare [| 0;0;32768;32767;32766;-1;-1;-1;-1;-1;0;0;32768;32767;32766;-1;-1;-1;-1;-1;-32768;-32768;0;-1;-2;-1;-1;-1;-1;-1;-32767;-32767;1;0;-1;-1;-1;-1;-1;-1; -32766;-32766;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;32768;32768;32767;32766;1;1;1;1;1;-32768;0;32768;32767;32766;1;1;1;1;1;-32768;-32768;0;-1;-2; 1;1;1;1;1;-32767;-32767;1;0;-1;1;1;1;1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.less_than``() = validate (Int16s.Collection.ArrayArray) C.N.less_than [| 0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1; 1;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;1;1;0;0;1;0;0;0;0;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.less_or_equal``() = validate (Int16s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;1;1;1;1;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.greater_than``() = validate (Int16s.Collection.ArrayArray) C.N.greater_than [| 0;0;1;1;1;0;0;0;0;0;0;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Int16s.Collection.ArrayArray) C.N.greater_or_equal [| 1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0; 0;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;0;0;1;1;0;1;1;1;1;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ListArray C.I.equals``() = + [] + member _.``Int16s.Collection.ListArray C.I.equals``() = validate (Int16s.Collection.ListArray) C.I.equals [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.I.equal``() = + [] + member _.``Int16s.Collection.ListArray C.I.equal``() = validate (Int16s.Collection.ListArray) C.I.equal [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.ListArray C.I.not_equal``() = validate (Int16s.Collection.ListArray) C.I.not_equal [| 0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.I.compare``() = + [] + member _.``Int16s.Collection.ListArray C.I.compare``() = validate (Int16s.Collection.ListArray) C.I.compare [| 0;0;32768;32767;32766;-1;-1;32768;32767;32766;0;0;32768;32767;32766;-1;-1;32768;32767;32766;-32768;-32768;0;-1;-2;-32768;-32768;-1;-1;-2;-32767;-32767;1;0;-1;-32767;-32767;1;-1;-1; -32766;-32766;2;1;0;-32766;-32766;2;1;-1;1;1;32768;32767;32766;0;32768;32768;32767;32766;1;1;32768;32767;32766;-32768;0;32768;32767;32766;-32768;-32768;1;-1;-2;-32768;-32768;0;-1;-2; -32767;-32767;1;1;-1;-32767;-32767;1;0;-1;-32766;-32766;2;1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.I.less_than``() = + [] + member _.``Int16s.Collection.ListArray C.I.less_than``() = validate (Int16s.Collection.ListArray) C.I.less_than [| 0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;0;1;1; 1;1;0;0;0;1;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;1;0;0;1;1;1;0;0;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.ListArray C.I.less_or_equal``() = validate (Int16s.Collection.ListArray) C.I.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;0;1;1;1;1;0;0;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.ListArray C.I.greater_than``() = validate (Int16s.Collection.ListArray) C.I.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.ListArray C.I.greater_or_equal``() = validate (Int16s.Collection.ListArray) C.I.greater_or_equal [| 1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0; 0;0;1;1;1;0;0;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;0;1;1;0;0;0;1;1;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ListArray C.N.equals``() = + [] + member _.``Int16s.Collection.ListArray C.N.equals``() = validate (Int16s.Collection.ListArray) C.N.equals [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.N.equal``() = + [] + member _.``Int16s.Collection.ListArray C.N.equal``() = validate (Int16s.Collection.ListArray) C.N.equal [| 1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.ListArray C.N.not_equal``() = validate (Int16s.Collection.ListArray) C.N.not_equal [| 0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.N.compare``() = + [] + member _.``Int16s.Collection.ListArray C.N.compare``() = validate (Int16s.Collection.ListArray) C.N.compare [| 0;0;32768;32767;32766;-1;-1;32768;32767;32766;0;0;32768;32767;32766;-1;-1;32768;32767;32766;-32768;-32768;0;-1;-2;-32768;-32768;-1;-1;-2;-32767;-32767;1;0;-1;-32767;-32767;1;-1;-1; -32766;-32766;2;1;0;-32766;-32766;2;1;-1;1;1;32768;32767;32766;0;32768;32768;32767;32766;1;1;32768;32767;32766;-32768;0;32768;32767;32766;-32768;-32768;1;-1;-2;-32768;-32768;0;-1;-2; -32767;-32767;1;1;-1;-32767;-32767;1;0;-1;-32766;-32766;2;1;1;-32766;-32766;2;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.N.less_than``() = + [] + member _.``Int16s.Collection.ListArray C.N.less_than``() = validate (Int16s.Collection.ListArray) C.N.less_than [| 0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;0;1;1; 1;1;0;0;0;1;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;1;0;0;1;1;1;0;0;0;1;1;0;0;0 |] - [] - member __.``Int16s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.ListArray C.N.less_or_equal``() = validate (Int16s.Collection.ListArray) C.N.less_or_equal [| 1;1;0;0;0;1;1;0;0;0;1;1;0;0;0;1;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;0;1;1;1;1;0;0;0;1;1;0;0;1 |] - [] - member __.``Int16s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.ListArray C.N.greater_than``() = validate (Int16s.Collection.ListArray) C.N.greater_than [| 0;0;1;1;1;0;0;1;1;1;0;0;1;1;1;0;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;0;1;1;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;0;0;1;1;0 |] - [] - member __.``Int16s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.ListArray C.N.greater_or_equal``() = validate (Int16s.Collection.ListArray) C.N.greater_or_equal [| 1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0; 0;0;1;1;1;0;0;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;0;1;1;0;0;0;1;1;1;0;0;1;1;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1; -1;-1;1;1;0;-1;1;1;1;-1;0;0;1;1;1;0;1;1;1;1;-1;-1;1;-1;-1;-1;0;1;-1;-1;-1;-1;1;-1;-1;-1;-1;0;-1;-1; -1;-1;1;1;-1;-1;1;1;0;-1;-1;-1;1;1;1;-1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1; 1;1;0;0;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;0;0;1;1;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;0;0;0;1;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1; 1;1;0;0;1;1;0;0;0;1;1;1;0;0;0;1;0;0;0;0;1;1;0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;1;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;1;0;0; 0;0;1;1;0;0;1;1;1;0;0;0;1;1;1;0;1;1;1;1;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;1;1;0;0;0;0;1;1;1;0;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;1;1;0;0; 0;0;1;1;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;1;1;0;0;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;1;1;1;0;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1; -1;-1;1;1;0;-1;1;1;1;-1;0;0;1;1;1;0;1;1;1;1;-1;-1;1;-1;-1;-1;0;1;-1;-1;-1;-1;1;-1;-1;-1;-1;0;-1;-1; -1;-1;1;1;-1;-1;1;1;0;-1;-1;-1;1;1;1;-1;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1; 1;1;0;0;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1;1;0;0;1;1;1;1;0;1;1;1;1;0;1;1; 1;1;0;0;1;1;0;0;0;1;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;0;0;0;1;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1; 1;1;0;0;1;1;0;0;0;1;1;1;0;0;0;1;0;0;0;0;1;1;0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;1;1;1; 1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;1;0;0;0;1 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;1;1;1;0;1;1;1;1;0;0;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;1;0;0; 0;0;1;1;0;0;1;1;1;0;0;0;1;1;1;0;1;1;1;1;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;0;0;0; 0;0;1;1;0;0;1;1;0;0;0;0;1;1;1;0;1;1;1;0 |] - [] - member __.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Int16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Int16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;0;0;1;1;0;0; 0;0;1;1;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0;0;1;1;0;0;0;0;1;0;0;0;0;1;0;0; 0;0;1;1;0;0;1;1;1;0;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``NullableInt16s.Collection.Array E.I.equals``() = + [] + member _.``NullableInt16s.Collection.Array E.I.equals``() = validate (NullableInt16s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.Array E.I.equal``() = + [] + member _.``NullableInt16s.Collection.Array E.I.equal``() = validate (NullableInt16s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.Array E.I.not_equal``() = validate (NullableInt16s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.Array E.N.equals``() = + [] + member _.``NullableInt16s.Collection.Array E.N.equals``() = validate (NullableInt16s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.Array E.N.equal``() = + [] + member _.``NullableInt16s.Collection.Array E.N.equal``() = validate (NullableInt16s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.Array E.N.not_equal``() = validate (NullableInt16s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.I.equals``() = validate (NullableInt16s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.I.equal``() = validate (NullableInt16s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.I.not_equal``() = validate (NullableInt16s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.N.equals``() = validate (NullableInt16s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.N.equal``() = validate (NullableInt16s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.OptionArray E.N.not_equal``() = validate (NullableInt16s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.RefArray E.I.equals``() = validate (NullableInt16s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.RefArray E.I.equal``() = validate (NullableInt16s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.RefArray E.I.not_equal``() = validate (NullableInt16s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.RefArray E.N.equals``() = validate (NullableInt16s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.RefArray E.N.equal``() = validate (NullableInt16s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.RefArray E.N.not_equal``() = validate (NullableInt16s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.I.equals``() = validate (NullableInt16s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.I.equal``() = validate (NullableInt16s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableInt16s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.N.equals``() = validate (NullableInt16s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.N.equal``() = validate (NullableInt16s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableInt16s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.I.equals``() = validate (NullableInt16s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -8782,8 +8782,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.I.equal``() = validate (NullableInt16s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -8832,8 +8832,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.I.not_equal``() = validate (NullableInt16s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -8882,8 +8882,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.N.equals``() = validate (NullableInt16s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -8932,8 +8932,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.N.equal``() = validate (NullableInt16s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -8982,8 +8982,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.UnionArray E.N.not_equal``() = validate (NullableInt16s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -9032,8 +9032,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.I.equals``() = validate (NullableInt16s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -9082,8 +9082,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.I.equal``() = validate (NullableInt16s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -9132,8 +9132,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableInt16s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -9182,8 +9182,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.N.equals``() = validate (NullableInt16s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -9232,8 +9232,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.N.equal``() = validate (NullableInt16s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -9282,8 +9282,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableInt16s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -9332,80 +9332,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.I.equals``() = validate (NullableInt16s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.I.equal``() = validate (NullableInt16s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.I.not_equal``() = validate (NullableInt16s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.N.equals``() = validate (NullableInt16s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.N.equal``() = validate (NullableInt16s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.ValueArray E.N.not_equal``() = validate (NullableInt16s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.I.equals``() = validate (NullableInt16s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.I.equal``() = validate (NullableInt16s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableInt16s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.N.equals``() = validate (NullableInt16s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.N.equal``() = validate (NullableInt16s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableInt16s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.I.equals``() = validate (NullableInt16s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9413,8 +9413,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.I.equal``() = validate (NullableInt16s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9422,8 +9422,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.I.not_equal``() = validate (NullableInt16s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -9431,8 +9431,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.N.equals``() = validate (NullableInt16s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9440,8 +9440,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.N.equal``() = validate (NullableInt16s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9449,8 +9449,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.ArrayArray E.N.not_equal``() = validate (NullableInt16s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -9458,8 +9458,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableInt16s.Collection.ListArray E.I.equals``() = validate (NullableInt16s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9467,8 +9467,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableInt16s.Collection.ListArray E.I.equal``() = validate (NullableInt16s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9476,8 +9476,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableInt16s.Collection.ListArray E.I.not_equal``() = validate (NullableInt16s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -9485,8 +9485,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt16s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableInt16s.Collection.ListArray E.N.equals``() = validate (NullableInt16s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9494,8 +9494,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableInt16s.Collection.ListArray E.N.equal``() = validate (NullableInt16s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -9503,8 +9503,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt16s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableInt16s.Collection.ListArray E.N.not_equal``() = validate (NullableInt16s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -9512,392 +9512,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.I.equals``() = + [] + member _.``Int32s.Collection.Array C.I.equals``() = validate (Int32s.Collection.Array) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.I.equal``() = + [] + member _.``Int32s.Collection.Array C.I.equal``() = validate (Int32s.Collection.Array) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.I.not_equal``() = + [] + member _.``Int32s.Collection.Array C.I.not_equal``() = validate (Int32s.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.I.compare``() = + [] + member _.``Int32s.Collection.Array C.I.compare``() = validate (Int32s.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.I.less_than``() = + [] + member _.``Int32s.Collection.Array C.I.less_than``() = validate (Int32s.Collection.Array) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.Array C.I.less_or_equal``() = validate (Int32s.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.I.greater_than``() = + [] + member _.``Int32s.Collection.Array C.I.greater_than``() = validate (Int32s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.Array C.I.greater_or_equal``() = validate (Int32s.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.Array C.N.equals``() = + [] + member _.``Int32s.Collection.Array C.N.equals``() = validate (Int32s.Collection.Array) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.N.equal``() = + [] + member _.``Int32s.Collection.Array C.N.equal``() = validate (Int32s.Collection.Array) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.N.not_equal``() = + [] + member _.``Int32s.Collection.Array C.N.not_equal``() = validate (Int32s.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.N.compare``() = + [] + member _.``Int32s.Collection.Array C.N.compare``() = validate (Int32s.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.N.less_than``() = + [] + member _.``Int32s.Collection.Array C.N.less_than``() = validate (Int32s.Collection.Array) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.Array C.N.less_or_equal``() = validate (Int32s.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.Array C.N.greater_than``() = + [] + member _.``Int32s.Collection.Array C.N.greater_than``() = validate (Int32s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.Array C.N.greater_or_equal``() = validate (Int32s.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.OptionArray C.I.equals``() = + [] + member _.``Int32s.Collection.OptionArray C.I.equals``() = validate (Int32s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.I.equal``() = + [] + member _.``Int32s.Collection.OptionArray C.I.equal``() = validate (Int32s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.I.not_equal``() = validate (Int32s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.I.compare``() = + [] + member _.``Int32s.Collection.OptionArray C.I.compare``() = validate (Int32s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Int32s.Collection.OptionArray C.I.less_than``() = validate (Int32s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.I.less_or_equal``() = validate (Int32s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.OptionArray C.I.greater_than``() = validate (Int32s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.I.greater_or_equal``() = validate (Int32s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.OptionArray C.N.equals``() = + [] + member _.``Int32s.Collection.OptionArray C.N.equals``() = validate (Int32s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.N.equal``() = + [] + member _.``Int32s.Collection.OptionArray C.N.equal``() = validate (Int32s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.N.not_equal``() = validate (Int32s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.N.compare``() = + [] + member _.``Int32s.Collection.OptionArray C.N.compare``() = validate (Int32s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Int32s.Collection.OptionArray C.N.less_than``() = validate (Int32s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.N.less_or_equal``() = validate (Int32s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.OptionArray C.N.greater_than``() = validate (Int32s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.OptionArray C.N.greater_or_equal``() = validate (Int32s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.RefArray C.I.equals``() = + [] + member _.``Int32s.Collection.RefArray C.I.equals``() = validate (Int32s.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.I.equal``() = + [] + member _.``Int32s.Collection.RefArray C.I.equal``() = validate (Int32s.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.RefArray C.I.not_equal``() = validate (Int32s.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.I.compare``() = + [] + member _.``Int32s.Collection.RefArray C.I.compare``() = validate (Int32s.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.I.less_than``() = + [] + member _.``Int32s.Collection.RefArray C.I.less_than``() = validate (Int32s.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.RefArray C.I.less_or_equal``() = validate (Int32s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.RefArray C.I.greater_than``() = validate (Int32s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.RefArray C.I.greater_or_equal``() = validate (Int32s.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.RefArray C.N.equals``() = + [] + member _.``Int32s.Collection.RefArray C.N.equals``() = validate (Int32s.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.N.equal``() = + [] + member _.``Int32s.Collection.RefArray C.N.equal``() = validate (Int32s.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.RefArray C.N.not_equal``() = validate (Int32s.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.N.compare``() = + [] + member _.``Int32s.Collection.RefArray C.N.compare``() = validate (Int32s.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.N.less_than``() = + [] + member _.``Int32s.Collection.RefArray C.N.less_than``() = validate (Int32s.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.RefArray C.N.less_or_equal``() = validate (Int32s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.RefArray C.N.greater_than``() = validate (Int32s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.RefArray C.N.greater_or_equal``() = validate (Int32s.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.equals``() = validate (Int32s.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.equal``() = validate (Int32s.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.not_equal``() = validate (Int32s.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.compare``() = validate (Int32s.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.less_than``() = validate (Int32s.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Int32s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.greater_than``() = validate (Int32s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Int32s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.equals``() = validate (Int32s.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.equal``() = validate (Int32s.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.not_equal``() = validate (Int32s.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.compare``() = validate (Int32s.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.less_than``() = validate (Int32s.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Int32s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.greater_than``() = validate (Int32s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Int32s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.UnionArray C.I.equals``() = + [] + member _.``Int32s.Collection.UnionArray C.I.equals``() = validate (Int32s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -9932,8 +9932,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.I.equal``() = + [] + member _.``Int32s.Collection.UnionArray C.I.equal``() = validate (Int32s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -9968,8 +9968,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.I.not_equal``() = validate (Int32s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -10004,8 +10004,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.I.compare``() = + [] + member _.``Int32s.Collection.UnionArray C.I.compare``() = validate (Int32s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -10040,8 +10040,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Int32s.Collection.UnionArray C.I.less_than``() = validate (Int32s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -10076,8 +10076,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.I.less_or_equal``() = validate (Int32s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -10112,8 +10112,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.UnionArray C.I.greater_than``() = validate (Int32s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -10148,8 +10148,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.I.greater_or_equal``() = validate (Int32s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -10184,8 +10184,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.UnionArray C.N.equals``() = + [] + member _.``Int32s.Collection.UnionArray C.N.equals``() = validate (Int32s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10220,8 +10220,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.N.equal``() = + [] + member _.``Int32s.Collection.UnionArray C.N.equal``() = validate (Int32s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10256,8 +10256,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.N.not_equal``() = validate (Int32s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -10292,8 +10292,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.N.compare``() = + [] + member _.``Int32s.Collection.UnionArray C.N.compare``() = validate (Int32s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -10328,8 +10328,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Int32s.Collection.UnionArray C.N.less_than``() = validate (Int32s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -10364,8 +10364,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.N.less_or_equal``() = validate (Int32s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -10400,8 +10400,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.UnionArray C.N.greater_than``() = validate (Int32s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -10436,8 +10436,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.UnionArray C.N.greater_or_equal``() = validate (Int32s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -10472,8 +10472,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.equals``() = validate (Int32s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10508,8 +10508,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.equal``() = validate (Int32s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10544,8 +10544,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.not_equal``() = validate (Int32s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -10580,8 +10580,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.compare``() = validate (Int32s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -10616,8 +10616,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.less_than``() = validate (Int32s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -10652,8 +10652,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Int32s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -10688,8 +10688,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.greater_than``() = validate (Int32s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -10724,8 +10724,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Int32s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -10760,8 +10760,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.equals``() = validate (Int32s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10796,8 +10796,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.equal``() = validate (Int32s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -10832,8 +10832,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.not_equal``() = validate (Int32s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -10868,8 +10868,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.compare``() = validate (Int32s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -10904,8 +10904,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.less_than``() = validate (Int32s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -10940,8 +10940,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Int32s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -10976,8 +10976,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.greater_than``() = validate (Int32s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -11012,8 +11012,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Int32s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -11048,734 +11048,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.ValueArray C.I.equals``() = + [] + member _.``Int32s.Collection.ValueArray C.I.equals``() = validate (Int32s.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.I.equal``() = + [] + member _.``Int32s.Collection.ValueArray C.I.equal``() = validate (Int32s.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.I.not_equal``() = validate (Int32s.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.I.compare``() = + [] + member _.``Int32s.Collection.ValueArray C.I.compare``() = validate (Int32s.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Int32s.Collection.ValueArray C.I.less_than``() = validate (Int32s.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.I.less_or_equal``() = validate (Int32s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.ValueArray C.I.greater_than``() = validate (Int32s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.I.greater_or_equal``() = validate (Int32s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ValueArray C.N.equals``() = + [] + member _.``Int32s.Collection.ValueArray C.N.equals``() = validate (Int32s.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.N.equal``() = + [] + member _.``Int32s.Collection.ValueArray C.N.equal``() = validate (Int32s.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.N.not_equal``() = validate (Int32s.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.N.compare``() = + [] + member _.``Int32s.Collection.ValueArray C.N.compare``() = validate (Int32s.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Int32s.Collection.ValueArray C.N.less_than``() = validate (Int32s.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.N.less_or_equal``() = validate (Int32s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.ValueArray C.N.greater_than``() = validate (Int32s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.ValueArray C.N.greater_or_equal``() = validate (Int32s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.equals``() = validate (Int32s.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.equal``() = validate (Int32s.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.not_equal``() = validate (Int32s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.compare``() = validate (Int32s.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.less_than``() = validate (Int32s.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Int32s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.greater_than``() = validate (Int32s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Int32s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.equals``() = validate (Int32s.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.equal``() = validate (Int32s.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.not_equal``() = validate (Int32s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.compare``() = validate (Int32s.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.less_than``() = validate (Int32s.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Int32s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.greater_than``() = validate (Int32s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Int32s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.equals``() = validate (Int32s.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.equal``() = validate (Int32s.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.not_equal``() = validate (Int32s.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.compare``() = validate (Int32s.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.less_than``() = validate (Int32s.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.less_or_equal``() = validate (Int32s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.greater_than``() = validate (Int32s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Int32s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.equals``() = validate (Int32s.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.equal``() = validate (Int32s.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.not_equal``() = validate (Int32s.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.compare``() = validate (Int32s.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.less_than``() = validate (Int32s.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.less_or_equal``() = validate (Int32s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.greater_than``() = validate (Int32s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Int32s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ListArray C.I.equals``() = + [] + member _.``Int32s.Collection.ListArray C.I.equals``() = validate (Int32s.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.I.equal``() = + [] + member _.``Int32s.Collection.ListArray C.I.equal``() = validate (Int32s.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.ListArray C.I.not_equal``() = validate (Int32s.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.I.compare``() = + [] + member _.``Int32s.Collection.ListArray C.I.compare``() = validate (Int32s.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.I.less_than``() = + [] + member _.``Int32s.Collection.ListArray C.I.less_than``() = validate (Int32s.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.ListArray C.I.less_or_equal``() = validate (Int32s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.ListArray C.I.greater_than``() = validate (Int32s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.ListArray C.I.greater_or_equal``() = validate (Int32s.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ListArray C.N.equals``() = + [] + member _.``Int32s.Collection.ListArray C.N.equals``() = validate (Int32s.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.N.equal``() = + [] + member _.``Int32s.Collection.ListArray C.N.equal``() = validate (Int32s.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.ListArray C.N.not_equal``() = validate (Int32s.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.N.compare``() = + [] + member _.``Int32s.Collection.ListArray C.N.compare``() = validate (Int32s.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.N.less_than``() = + [] + member _.``Int32s.Collection.ListArray C.N.less_than``() = validate (Int32s.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Int32s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.ListArray C.N.less_or_equal``() = validate (Int32s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Int32s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.ListArray C.N.greater_than``() = validate (Int32s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Int32s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.ListArray C.N.greater_or_equal``() = validate (Int32s.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Int32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Int32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.Array E.I.equals``() = + [] + member _.``NullableInt32s.Collection.Array E.I.equals``() = validate (NullableInt32s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.Array E.I.equal``() = + [] + member _.``NullableInt32s.Collection.Array E.I.equal``() = validate (NullableInt32s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.Array E.I.not_equal``() = validate (NullableInt32s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.Array E.N.equals``() = + [] + member _.``NullableInt32s.Collection.Array E.N.equals``() = validate (NullableInt32s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.Array E.N.equal``() = + [] + member _.``NullableInt32s.Collection.Array E.N.equal``() = validate (NullableInt32s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.Array E.N.not_equal``() = validate (NullableInt32s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.I.equals``() = validate (NullableInt32s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.I.equal``() = validate (NullableInt32s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.I.not_equal``() = validate (NullableInt32s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.N.equals``() = validate (NullableInt32s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.N.equal``() = validate (NullableInt32s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.OptionArray E.N.not_equal``() = validate (NullableInt32s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.RefArray E.I.equals``() = validate (NullableInt32s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.RefArray E.I.equal``() = validate (NullableInt32s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.RefArray E.I.not_equal``() = validate (NullableInt32s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.RefArray E.N.equals``() = validate (NullableInt32s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.RefArray E.N.equal``() = validate (NullableInt32s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.RefArray E.N.not_equal``() = validate (NullableInt32s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.I.equals``() = validate (NullableInt32s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.I.equal``() = validate (NullableInt32s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableInt32s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.N.equals``() = validate (NullableInt32s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.N.equal``() = validate (NullableInt32s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableInt32s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.I.equals``() = validate (NullableInt32s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -11824,8 +11824,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.I.equal``() = validate (NullableInt32s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -11874,8 +11874,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.I.not_equal``() = validate (NullableInt32s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -11924,8 +11924,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.N.equals``() = validate (NullableInt32s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -11974,8 +11974,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.N.equal``() = validate (NullableInt32s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -12024,8 +12024,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.UnionArray E.N.not_equal``() = validate (NullableInt32s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -12074,8 +12074,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.I.equals``() = validate (NullableInt32s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -12124,8 +12124,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.I.equal``() = validate (NullableInt32s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -12174,8 +12174,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableInt32s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -12224,8 +12224,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.N.equals``() = validate (NullableInt32s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -12274,8 +12274,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.N.equal``() = validate (NullableInt32s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -12324,8 +12324,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableInt32s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -12374,80 +12374,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.I.equals``() = validate (NullableInt32s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.I.equal``() = validate (NullableInt32s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.I.not_equal``() = validate (NullableInt32s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.N.equals``() = validate (NullableInt32s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.N.equal``() = validate (NullableInt32s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.ValueArray E.N.not_equal``() = validate (NullableInt32s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.I.equals``() = validate (NullableInt32s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.I.equal``() = validate (NullableInt32s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableInt32s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.N.equals``() = validate (NullableInt32s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.N.equal``() = validate (NullableInt32s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableInt32s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.I.equals``() = validate (NullableInt32s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12455,8 +12455,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.I.equal``() = validate (NullableInt32s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12464,8 +12464,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.I.not_equal``() = validate (NullableInt32s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -12473,8 +12473,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.N.equals``() = validate (NullableInt32s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12482,8 +12482,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.N.equal``() = validate (NullableInt32s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12491,8 +12491,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.ArrayArray E.N.not_equal``() = validate (NullableInt32s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -12500,8 +12500,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableInt32s.Collection.ListArray E.I.equals``() = validate (NullableInt32s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12509,8 +12509,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableInt32s.Collection.ListArray E.I.equal``() = validate (NullableInt32s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12518,8 +12518,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableInt32s.Collection.ListArray E.I.not_equal``() = validate (NullableInt32s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -12527,8 +12527,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt32s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableInt32s.Collection.ListArray E.N.equals``() = validate (NullableInt32s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12536,8 +12536,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableInt32s.Collection.ListArray E.N.equal``() = validate (NullableInt32s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -12545,8 +12545,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt32s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableInt32s.Collection.ListArray E.N.not_equal``() = validate (NullableInt32s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -12554,392 +12554,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.I.equals``() = + [] + member _.``Int64s.Collection.Array C.I.equals``() = validate (Int64s.Collection.Array) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.I.equal``() = + [] + member _.``Int64s.Collection.Array C.I.equal``() = validate (Int64s.Collection.Array) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.I.not_equal``() = + [] + member _.``Int64s.Collection.Array C.I.not_equal``() = validate (Int64s.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.I.compare``() = + [] + member _.``Int64s.Collection.Array C.I.compare``() = validate (Int64s.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.I.less_than``() = + [] + member _.``Int64s.Collection.Array C.I.less_than``() = validate (Int64s.Collection.Array) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.Array C.I.less_or_equal``() = validate (Int64s.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.I.greater_than``() = + [] + member _.``Int64s.Collection.Array C.I.greater_than``() = validate (Int64s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.Array C.I.greater_or_equal``() = validate (Int64s.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.Array C.N.equals``() = + [] + member _.``Int64s.Collection.Array C.N.equals``() = validate (Int64s.Collection.Array) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.N.equal``() = + [] + member _.``Int64s.Collection.Array C.N.equal``() = validate (Int64s.Collection.Array) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.N.not_equal``() = + [] + member _.``Int64s.Collection.Array C.N.not_equal``() = validate (Int64s.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.N.compare``() = + [] + member _.``Int64s.Collection.Array C.N.compare``() = validate (Int64s.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.N.less_than``() = + [] + member _.``Int64s.Collection.Array C.N.less_than``() = validate (Int64s.Collection.Array) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.Array C.N.less_or_equal``() = validate (Int64s.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.Array C.N.greater_than``() = + [] + member _.``Int64s.Collection.Array C.N.greater_than``() = validate (Int64s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.Array C.N.greater_or_equal``() = validate (Int64s.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.OptionArray C.I.equals``() = + [] + member _.``Int64s.Collection.OptionArray C.I.equals``() = validate (Int64s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.I.equal``() = + [] + member _.``Int64s.Collection.OptionArray C.I.equal``() = validate (Int64s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.I.not_equal``() = validate (Int64s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.I.compare``() = + [] + member _.``Int64s.Collection.OptionArray C.I.compare``() = validate (Int64s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Int64s.Collection.OptionArray C.I.less_than``() = validate (Int64s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.I.less_or_equal``() = validate (Int64s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.OptionArray C.I.greater_than``() = validate (Int64s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.I.greater_or_equal``() = validate (Int64s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.OptionArray C.N.equals``() = + [] + member _.``Int64s.Collection.OptionArray C.N.equals``() = validate (Int64s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.N.equal``() = + [] + member _.``Int64s.Collection.OptionArray C.N.equal``() = validate (Int64s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.N.not_equal``() = validate (Int64s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.N.compare``() = + [] + member _.``Int64s.Collection.OptionArray C.N.compare``() = validate (Int64s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Int64s.Collection.OptionArray C.N.less_than``() = validate (Int64s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.N.less_or_equal``() = validate (Int64s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.OptionArray C.N.greater_than``() = validate (Int64s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.OptionArray C.N.greater_or_equal``() = validate (Int64s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.RefArray C.I.equals``() = + [] + member _.``Int64s.Collection.RefArray C.I.equals``() = validate (Int64s.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.I.equal``() = + [] + member _.``Int64s.Collection.RefArray C.I.equal``() = validate (Int64s.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.RefArray C.I.not_equal``() = validate (Int64s.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.I.compare``() = + [] + member _.``Int64s.Collection.RefArray C.I.compare``() = validate (Int64s.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.I.less_than``() = + [] + member _.``Int64s.Collection.RefArray C.I.less_than``() = validate (Int64s.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.RefArray C.I.less_or_equal``() = validate (Int64s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.RefArray C.I.greater_than``() = validate (Int64s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.RefArray C.I.greater_or_equal``() = validate (Int64s.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.RefArray C.N.equals``() = + [] + member _.``Int64s.Collection.RefArray C.N.equals``() = validate (Int64s.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.N.equal``() = + [] + member _.``Int64s.Collection.RefArray C.N.equal``() = validate (Int64s.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.RefArray C.N.not_equal``() = validate (Int64s.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.N.compare``() = + [] + member _.``Int64s.Collection.RefArray C.N.compare``() = validate (Int64s.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.N.less_than``() = + [] + member _.``Int64s.Collection.RefArray C.N.less_than``() = validate (Int64s.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.RefArray C.N.less_or_equal``() = validate (Int64s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.RefArray C.N.greater_than``() = validate (Int64s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.RefArray C.N.greater_or_equal``() = validate (Int64s.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.equals``() = validate (Int64s.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.equal``() = validate (Int64s.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.not_equal``() = validate (Int64s.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.compare``() = validate (Int64s.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.less_than``() = validate (Int64s.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Int64s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.greater_than``() = validate (Int64s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Int64s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.equals``() = validate (Int64s.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.equal``() = validate (Int64s.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.not_equal``() = validate (Int64s.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.compare``() = validate (Int64s.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.less_than``() = validate (Int64s.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Int64s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.greater_than``() = validate (Int64s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Int64s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.UnionArray C.I.equals``() = + [] + member _.``Int64s.Collection.UnionArray C.I.equals``() = validate (Int64s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -12974,8 +12974,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.I.equal``() = + [] + member _.``Int64s.Collection.UnionArray C.I.equal``() = validate (Int64s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13010,8 +13010,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.I.not_equal``() = validate (Int64s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -13046,8 +13046,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.I.compare``() = + [] + member _.``Int64s.Collection.UnionArray C.I.compare``() = validate (Int64s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -13082,8 +13082,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Int64s.Collection.UnionArray C.I.less_than``() = validate (Int64s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -13118,8 +13118,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.I.less_or_equal``() = validate (Int64s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -13154,8 +13154,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.UnionArray C.I.greater_than``() = validate (Int64s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -13190,8 +13190,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.I.greater_or_equal``() = validate (Int64s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -13226,8 +13226,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.UnionArray C.N.equals``() = + [] + member _.``Int64s.Collection.UnionArray C.N.equals``() = validate (Int64s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13262,8 +13262,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.N.equal``() = + [] + member _.``Int64s.Collection.UnionArray C.N.equal``() = validate (Int64s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13298,8 +13298,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.N.not_equal``() = validate (Int64s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -13334,8 +13334,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.N.compare``() = + [] + member _.``Int64s.Collection.UnionArray C.N.compare``() = validate (Int64s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -13370,8 +13370,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Int64s.Collection.UnionArray C.N.less_than``() = validate (Int64s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -13406,8 +13406,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.N.less_or_equal``() = validate (Int64s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -13442,8 +13442,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.UnionArray C.N.greater_than``() = validate (Int64s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -13478,8 +13478,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.UnionArray C.N.greater_or_equal``() = validate (Int64s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -13514,8 +13514,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.equals``() = validate (Int64s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13550,8 +13550,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.equal``() = validate (Int64s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13586,8 +13586,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.not_equal``() = validate (Int64s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -13622,8 +13622,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.compare``() = validate (Int64s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -13658,8 +13658,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.less_than``() = validate (Int64s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -13694,8 +13694,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Int64s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -13730,8 +13730,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.greater_than``() = validate (Int64s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -13766,8 +13766,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Int64s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -13802,8 +13802,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.equals``() = validate (Int64s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13838,8 +13838,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.equal``() = validate (Int64s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -13874,8 +13874,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.not_equal``() = validate (Int64s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -13910,8 +13910,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.compare``() = validate (Int64s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -13946,8 +13946,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.less_than``() = validate (Int64s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -13982,8 +13982,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Int64s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -14018,8 +14018,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.greater_than``() = validate (Int64s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -14054,8 +14054,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Int64s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -14090,734 +14090,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.ValueArray C.I.equals``() = + [] + member _.``Int64s.Collection.ValueArray C.I.equals``() = validate (Int64s.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.I.equal``() = + [] + member _.``Int64s.Collection.ValueArray C.I.equal``() = validate (Int64s.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.I.not_equal``() = validate (Int64s.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.I.compare``() = + [] + member _.``Int64s.Collection.ValueArray C.I.compare``() = validate (Int64s.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Int64s.Collection.ValueArray C.I.less_than``() = validate (Int64s.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.I.less_or_equal``() = validate (Int64s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.ValueArray C.I.greater_than``() = validate (Int64s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.I.greater_or_equal``() = validate (Int64s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ValueArray C.N.equals``() = + [] + member _.``Int64s.Collection.ValueArray C.N.equals``() = validate (Int64s.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.N.equal``() = + [] + member _.``Int64s.Collection.ValueArray C.N.equal``() = validate (Int64s.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.N.not_equal``() = validate (Int64s.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.N.compare``() = + [] + member _.``Int64s.Collection.ValueArray C.N.compare``() = validate (Int64s.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Int64s.Collection.ValueArray C.N.less_than``() = validate (Int64s.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.N.less_or_equal``() = validate (Int64s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.ValueArray C.N.greater_than``() = validate (Int64s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.ValueArray C.N.greater_or_equal``() = validate (Int64s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.equals``() = validate (Int64s.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.equal``() = validate (Int64s.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.not_equal``() = validate (Int64s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.compare``() = validate (Int64s.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.less_than``() = validate (Int64s.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Int64s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.greater_than``() = validate (Int64s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Int64s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.equals``() = validate (Int64s.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.equal``() = validate (Int64s.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.not_equal``() = validate (Int64s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.compare``() = validate (Int64s.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.less_than``() = validate (Int64s.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Int64s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.greater_than``() = validate (Int64s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Int64s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.equals``() = validate (Int64s.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.equal``() = validate (Int64s.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.not_equal``() = validate (Int64s.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.compare``() = validate (Int64s.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.less_than``() = validate (Int64s.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.less_or_equal``() = validate (Int64s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.greater_than``() = validate (Int64s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Int64s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.equals``() = validate (Int64s.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.equal``() = validate (Int64s.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.not_equal``() = validate (Int64s.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.compare``() = validate (Int64s.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.less_than``() = validate (Int64s.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.less_or_equal``() = validate (Int64s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.greater_than``() = validate (Int64s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Int64s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ListArray C.I.equals``() = + [] + member _.``Int64s.Collection.ListArray C.I.equals``() = validate (Int64s.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.I.equal``() = + [] + member _.``Int64s.Collection.ListArray C.I.equal``() = validate (Int64s.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.ListArray C.I.not_equal``() = validate (Int64s.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.I.compare``() = + [] + member _.``Int64s.Collection.ListArray C.I.compare``() = validate (Int64s.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.I.less_than``() = + [] + member _.``Int64s.Collection.ListArray C.I.less_than``() = validate (Int64s.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.ListArray C.I.less_or_equal``() = validate (Int64s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.ListArray C.I.greater_than``() = validate (Int64s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.ListArray C.I.greater_or_equal``() = validate (Int64s.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ListArray C.N.equals``() = + [] + member _.``Int64s.Collection.ListArray C.N.equals``() = validate (Int64s.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.N.equal``() = + [] + member _.``Int64s.Collection.ListArray C.N.equal``() = validate (Int64s.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.ListArray C.N.not_equal``() = validate (Int64s.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.N.compare``() = + [] + member _.``Int64s.Collection.ListArray C.N.compare``() = validate (Int64s.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.N.less_than``() = + [] + member _.``Int64s.Collection.ListArray C.N.less_than``() = validate (Int64s.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Int64s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.ListArray C.N.less_or_equal``() = validate (Int64s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Int64s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.ListArray C.N.greater_than``() = validate (Int64s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Int64s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.ListArray C.N.greater_or_equal``() = validate (Int64s.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Int64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Int64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.Array E.I.equals``() = + [] + member _.``NullableInt64s.Collection.Array E.I.equals``() = validate (NullableInt64s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.Array E.I.equal``() = + [] + member _.``NullableInt64s.Collection.Array E.I.equal``() = validate (NullableInt64s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.Array E.I.not_equal``() = validate (NullableInt64s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.Array E.N.equals``() = + [] + member _.``NullableInt64s.Collection.Array E.N.equals``() = validate (NullableInt64s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.Array E.N.equal``() = + [] + member _.``NullableInt64s.Collection.Array E.N.equal``() = validate (NullableInt64s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.Array E.N.not_equal``() = validate (NullableInt64s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.I.equals``() = validate (NullableInt64s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.I.equal``() = validate (NullableInt64s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.I.not_equal``() = validate (NullableInt64s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.N.equals``() = validate (NullableInt64s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.N.equal``() = validate (NullableInt64s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.OptionArray E.N.not_equal``() = validate (NullableInt64s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.RefArray E.I.equals``() = validate (NullableInt64s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.RefArray E.I.equal``() = validate (NullableInt64s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.RefArray E.I.not_equal``() = validate (NullableInt64s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.RefArray E.N.equals``() = validate (NullableInt64s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.RefArray E.N.equal``() = validate (NullableInt64s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.RefArray E.N.not_equal``() = validate (NullableInt64s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.I.equals``() = validate (NullableInt64s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.I.equal``() = validate (NullableInt64s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableInt64s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.N.equals``() = validate (NullableInt64s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.N.equal``() = validate (NullableInt64s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableInt64s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.I.equals``() = validate (NullableInt64s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -14866,8 +14866,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.I.equal``() = validate (NullableInt64s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -14916,8 +14916,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.I.not_equal``() = validate (NullableInt64s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -14966,8 +14966,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.N.equals``() = validate (NullableInt64s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15016,8 +15016,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.N.equal``() = validate (NullableInt64s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15066,8 +15066,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.UnionArray E.N.not_equal``() = validate (NullableInt64s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -15116,8 +15116,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.I.equals``() = validate (NullableInt64s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15166,8 +15166,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.I.equal``() = validate (NullableInt64s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15216,8 +15216,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableInt64s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -15266,8 +15266,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.N.equals``() = validate (NullableInt64s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15316,8 +15316,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.N.equal``() = validate (NullableInt64s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15366,8 +15366,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableInt64s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -15416,80 +15416,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.I.equals``() = validate (NullableInt64s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.I.equal``() = validate (NullableInt64s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.I.not_equal``() = validate (NullableInt64s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.N.equals``() = validate (NullableInt64s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.N.equal``() = validate (NullableInt64s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.ValueArray E.N.not_equal``() = validate (NullableInt64s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.I.equals``() = validate (NullableInt64s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.I.equal``() = validate (NullableInt64s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableInt64s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.N.equals``() = validate (NullableInt64s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.N.equal``() = validate (NullableInt64s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableInt64s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.I.equals``() = validate (NullableInt64s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15497,8 +15497,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.I.equal``() = validate (NullableInt64s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15506,8 +15506,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.I.not_equal``() = validate (NullableInt64s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -15515,8 +15515,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.N.equals``() = validate (NullableInt64s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15524,8 +15524,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.N.equal``() = validate (NullableInt64s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15533,8 +15533,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.ArrayArray E.N.not_equal``() = validate (NullableInt64s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -15542,8 +15542,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableInt64s.Collection.ListArray E.I.equals``() = validate (NullableInt64s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15551,8 +15551,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableInt64s.Collection.ListArray E.I.equal``() = validate (NullableInt64s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15560,8 +15560,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableInt64s.Collection.ListArray E.I.not_equal``() = validate (NullableInt64s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -15569,8 +15569,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableInt64s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableInt64s.Collection.ListArray E.N.equals``() = validate (NullableInt64s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15578,8 +15578,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableInt64s.Collection.ListArray E.N.equal``() = validate (NullableInt64s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -15587,8 +15587,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableInt64s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableInt64s.Collection.ListArray E.N.not_equal``() = validate (NullableInt64s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -15596,392 +15596,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.I.equals``() = + [] + member _.``NativeInts.Collection.Array C.I.equals``() = validate (NativeInts.Collection.Array) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.I.equal``() = + [] + member _.``NativeInts.Collection.Array C.I.equal``() = validate (NativeInts.Collection.Array) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.I.not_equal``() = + [] + member _.``NativeInts.Collection.Array C.I.not_equal``() = validate (NativeInts.Collection.Array) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.I.compare``() = + [] + member _.``NativeInts.Collection.Array C.I.compare``() = validate (NativeInts.Collection.Array) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.I.less_than``() = + [] + member _.``NativeInts.Collection.Array C.I.less_than``() = validate (NativeInts.Collection.Array) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.Array C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.Array C.I.less_or_equal``() = validate (NativeInts.Collection.Array) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.I.greater_than``() = + [] + member _.``NativeInts.Collection.Array C.I.greater_than``() = validate (NativeInts.Collection.Array) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.Array C.I.greater_or_equal``() = validate (NativeInts.Collection.Array) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.Array C.N.equals``() = + [] + member _.``NativeInts.Collection.Array C.N.equals``() = validate (NativeInts.Collection.Array) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.N.equal``() = + [] + member _.``NativeInts.Collection.Array C.N.equal``() = validate (NativeInts.Collection.Array) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.N.not_equal``() = + [] + member _.``NativeInts.Collection.Array C.N.not_equal``() = validate (NativeInts.Collection.Array) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.N.compare``() = + [] + member _.``NativeInts.Collection.Array C.N.compare``() = validate (NativeInts.Collection.Array) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.N.less_than``() = + [] + member _.``NativeInts.Collection.Array C.N.less_than``() = validate (NativeInts.Collection.Array) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.Array C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.Array C.N.less_or_equal``() = validate (NativeInts.Collection.Array) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.Array C.N.greater_than``() = + [] + member _.``NativeInts.Collection.Array C.N.greater_than``() = validate (NativeInts.Collection.Array) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.Array C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.Array C.N.greater_or_equal``() = validate (NativeInts.Collection.Array) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.equals``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.equals``() = validate (NativeInts.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.equal``() = validate (NativeInts.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.not_equal``() = validate (NativeInts.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.compare``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.compare``() = validate (NativeInts.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.less_than``() = validate (NativeInts.Collection.OptionArray) C.I.less_than [| 0;1;1;1;0;0;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.less_or_equal``() = validate (NativeInts.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.greater_than``() = validate (NativeInts.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.I.greater_or_equal``() = validate (NativeInts.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.equals``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.equals``() = validate (NativeInts.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.equal``() = validate (NativeInts.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.not_equal``() = validate (NativeInts.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.compare``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.compare``() = validate (NativeInts.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.less_than``() = validate (NativeInts.Collection.OptionArray) C.N.less_than [| 0;1;1;1;0;0;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.less_or_equal``() = validate (NativeInts.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.greater_than``() = validate (NativeInts.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.OptionArray C.N.greater_or_equal``() = validate (NativeInts.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``NativeInts.Collection.RefArray C.I.equals``() = + [] + member _.``NativeInts.Collection.RefArray C.I.equals``() = validate (NativeInts.Collection.RefArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.I.equal``() = + [] + member _.``NativeInts.Collection.RefArray C.I.equal``() = validate (NativeInts.Collection.RefArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.I.not_equal``() = validate (NativeInts.Collection.RefArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.I.compare``() = + [] + member _.``NativeInts.Collection.RefArray C.I.compare``() = validate (NativeInts.Collection.RefArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.RefArray C.I.less_than``() = validate (NativeInts.Collection.RefArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.I.less_or_equal``() = validate (NativeInts.Collection.RefArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.RefArray C.I.greater_than``() = validate (NativeInts.Collection.RefArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.I.greater_or_equal``() = validate (NativeInts.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.RefArray C.N.equals``() = + [] + member _.``NativeInts.Collection.RefArray C.N.equals``() = validate (NativeInts.Collection.RefArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.N.equal``() = + [] + member _.``NativeInts.Collection.RefArray C.N.equal``() = validate (NativeInts.Collection.RefArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.N.not_equal``() = validate (NativeInts.Collection.RefArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.N.compare``() = + [] + member _.``NativeInts.Collection.RefArray C.N.compare``() = validate (NativeInts.Collection.RefArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.RefArray C.N.less_than``() = validate (NativeInts.Collection.RefArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.N.less_or_equal``() = validate (NativeInts.Collection.RefArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.RefArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.RefArray C.N.greater_than``() = validate (NativeInts.Collection.RefArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.RefArray C.N.greater_or_equal``() = validate (NativeInts.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.equals``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.equals``() = validate (NativeInts.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.equal``() = validate (NativeInts.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.not_equal``() = validate (NativeInts.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.compare``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.compare``() = validate (NativeInts.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.less_than``() = validate (NativeInts.Collection.RefWrapArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.less_or_equal``() = validate (NativeInts.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.greater_than``() = validate (NativeInts.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.I.greater_or_equal``() = validate (NativeInts.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.equals``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.equals``() = validate (NativeInts.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.equal``() = validate (NativeInts.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.not_equal``() = validate (NativeInts.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.compare``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.compare``() = validate (NativeInts.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.less_than``() = validate (NativeInts.Collection.RefWrapArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.less_or_equal``() = validate (NativeInts.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.greater_than``() = validate (NativeInts.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.RefWrapArray C.N.greater_or_equal``() = validate (NativeInts.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.equals``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.equals``() = validate (NativeInts.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -15997,8 +15997,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.equal``() = validate (NativeInts.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16014,8 +16014,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.not_equal``() = validate (NativeInts.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -16031,8 +16031,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.compare``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.compare``() = validate (NativeInts.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -16048,8 +16048,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.less_than``() = validate (NativeInts.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16065,8 +16065,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.less_or_equal``() = validate (NativeInts.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16082,8 +16082,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.greater_than``() = validate (NativeInts.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16099,8 +16099,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.I.greater_or_equal``() = validate (NativeInts.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16116,8 +16116,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.equals``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.equals``() = validate (NativeInts.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16133,8 +16133,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.equal``() = validate (NativeInts.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16150,8 +16150,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.not_equal``() = validate (NativeInts.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -16167,8 +16167,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.compare``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.compare``() = validate (NativeInts.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -16184,8 +16184,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.less_than``() = validate (NativeInts.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16201,8 +16201,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.less_or_equal``() = validate (NativeInts.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16218,8 +16218,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.greater_than``() = validate (NativeInts.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16235,8 +16235,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.UnionArray C.N.greater_or_equal``() = validate (NativeInts.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16252,8 +16252,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.equals``() = validate (NativeInts.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16269,8 +16269,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.equal``() = validate (NativeInts.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16286,8 +16286,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.not_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -16303,8 +16303,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.compare``() = validate (NativeInts.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -16320,8 +16320,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.less_than``() = validate (NativeInts.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16337,8 +16337,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.less_or_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16354,8 +16354,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.greater_than``() = validate (NativeInts.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16371,8 +16371,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16388,8 +16388,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.equals``() = validate (NativeInts.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16405,8 +16405,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.equal``() = validate (NativeInts.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -16422,8 +16422,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.not_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -16439,8 +16439,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.compare``() = validate (NativeInts.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -16456,8 +16456,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.less_than``() = validate (NativeInts.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16473,8 +16473,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.less_or_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -16490,8 +16490,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.greater_than``() = validate (NativeInts.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16507,8 +16507,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NativeInts.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (NativeInts.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -16524,632 +16524,632 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.equals``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.equals``() = validate (NativeInts.Collection.ValueArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.equal``() = validate (NativeInts.Collection.ValueArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.not_equal``() = validate (NativeInts.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.compare``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.compare``() = validate (NativeInts.Collection.ValueArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.less_than``() = validate (NativeInts.Collection.ValueArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.less_or_equal``() = validate (NativeInts.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.greater_than``() = validate (NativeInts.Collection.ValueArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.I.greater_or_equal``() = validate (NativeInts.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.equals``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.equals``() = validate (NativeInts.Collection.ValueArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.equal``() = validate (NativeInts.Collection.ValueArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.not_equal``() = validate (NativeInts.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.compare``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.compare``() = validate (NativeInts.Collection.ValueArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.less_than``() = validate (NativeInts.Collection.ValueArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.less_or_equal``() = validate (NativeInts.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.greater_than``() = validate (NativeInts.Collection.ValueArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ValueArray C.N.greater_or_equal``() = validate (NativeInts.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.equals``() = validate (NativeInts.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.equal``() = validate (NativeInts.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.not_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.compare``() = validate (NativeInts.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.less_than``() = validate (NativeInts.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.less_or_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.greater_than``() = validate (NativeInts.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.equals``() = validate (NativeInts.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.equal``() = validate (NativeInts.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.not_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.compare``() = validate (NativeInts.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.less_than``() = validate (NativeInts.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.less_or_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.greater_than``() = validate (NativeInts.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``NativeInts.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (NativeInts.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.equals``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.equals``() = validate (NativeInts.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.equal``() = validate (NativeInts.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.not_equal``() = validate (NativeInts.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.compare``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.compare``() = validate (NativeInts.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.less_than``() = validate (NativeInts.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.less_or_equal``() = validate (NativeInts.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.greater_than``() = validate (NativeInts.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.I.greater_or_equal``() = validate (NativeInts.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.equals``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.equals``() = validate (NativeInts.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.equal``() = validate (NativeInts.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.not_equal``() = validate (NativeInts.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.compare``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.compare``() = validate (NativeInts.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.less_than``() = validate (NativeInts.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.less_or_equal``() = validate (NativeInts.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.greater_than``() = validate (NativeInts.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray C.N.greater_or_equal``() = validate (NativeInts.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``NativeInts.Collection.ListArray C.I.equals``() = + [] + member _.``NativeInts.Collection.ListArray C.I.equals``() = validate (NativeInts.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.I.equal``() = + [] + member _.``NativeInts.Collection.ListArray C.I.equal``() = validate (NativeInts.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.I.not_equal``() = validate (NativeInts.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.I.compare``() = + [] + member _.``NativeInts.Collection.ListArray C.I.compare``() = validate (NativeInts.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;-1;1;1;0;1;1;-1;1;-1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.ListArray C.I.less_than``() = validate (NativeInts.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0 |] - [] - member __.``NativeInts.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.I.less_or_equal``() = validate (NativeInts.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.ListArray C.I.greater_than``() = validate (NativeInts.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.I.greater_or_equal``() = validate (NativeInts.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;1 |] - [] - member __.``NativeInts.Collection.ListArray C.N.equals``() = + [] + member _.``NativeInts.Collection.ListArray C.N.equals``() = validate (NativeInts.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.N.equal``() = + [] + member _.``NativeInts.Collection.ListArray C.N.equal``() = validate (NativeInts.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.N.not_equal``() = validate (NativeInts.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.N.compare``() = + [] + member _.``NativeInts.Collection.ListArray C.N.compare``() = validate (NativeInts.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;-1;1;1;0;1;1;-1;1;-1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.ListArray C.N.less_than``() = validate (NativeInts.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0 |] - [] - member __.``NativeInts.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.N.less_or_equal``() = validate (NativeInts.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ListArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.ListArray C.N.greater_than``() = validate (NativeInts.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ListArray C.N.greater_or_equal``() = validate (NativeInts.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;1;1;-1;1;0;1;1;-1;-1;1;-1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;0;0;0;0;0;0;0;0;1;1;0;1;1;0;0;1;0;0;0;0;1;1;0;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;0;0;1;1;0;1;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;1;1;0;0;1;0;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;1;1;1;1;1;1;1;1;0;0;1;0;0;1;1;0;1;1;1;1;0;0;1;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;1;1;-1;1;0;1;1;-1;-1;1;-1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;0;0;0;0;0;0;0;0;1;1;0;1;1;0;0;1;0;0;0;0;1;1;0;1;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;0;0;1;1;0;1;1 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;1;1;0;0;1;0;0 |] - [] - member __.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``NativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (NativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;1;1;1;1;1;1;1;1;0;0;1;0;0;1;1;0;1;1;1;1;0;0;1;0;1 |] - [] - member __.``NullableNativeInts.Collection.Array E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.Array E.I.equals``() = validate (NullableNativeInts.Collection.Array) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.Array E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.Array E.I.equal``() = validate (NullableNativeInts.Collection.Array) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.Array E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.Array E.I.not_equal``() = validate (NullableNativeInts.Collection.Array) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.Array E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.Array E.N.equals``() = validate (NullableNativeInts.Collection.Array) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.Array E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.Array E.N.equal``() = validate (NullableNativeInts.Collection.Array) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.Array E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.Array E.N.not_equal``() = validate (NullableNativeInts.Collection.Array) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.I.equals``() = validate (NullableNativeInts.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.I.equal``() = validate (NullableNativeInts.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.I.not_equal``() = validate (NullableNativeInts.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.N.equals``() = validate (NullableNativeInts.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.N.equal``() = validate (NullableNativeInts.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.OptionArray E.N.not_equal``() = validate (NullableNativeInts.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.I.equals``() = validate (NullableNativeInts.Collection.RefArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.I.equal``() = validate (NullableNativeInts.Collection.RefArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.I.not_equal``() = validate (NullableNativeInts.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.N.equals``() = validate (NullableNativeInts.Collection.RefArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.N.equal``() = validate (NullableNativeInts.Collection.RefArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.RefArray E.N.not_equal``() = validate (NullableNativeInts.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.I.equals``() = validate (NullableNativeInts.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.I.equal``() = validate (NullableNativeInts.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.I.not_equal``() = validate (NullableNativeInts.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.N.equals``() = validate (NullableNativeInts.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.N.equal``() = validate (NullableNativeInts.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.RefWrapArray E.N.not_equal``() = validate (NullableNativeInts.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.I.equals``() = validate (NullableNativeInts.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17173,8 +17173,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.I.equal``() = validate (NullableNativeInts.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17198,8 +17198,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.I.not_equal``() = validate (NullableNativeInts.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -17223,8 +17223,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.N.equals``() = validate (NullableNativeInts.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17248,8 +17248,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.N.equal``() = validate (NullableNativeInts.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17273,8 +17273,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.UnionArray E.N.not_equal``() = validate (NullableNativeInts.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -17298,8 +17298,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.I.equals``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17323,8 +17323,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.I.equal``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17348,8 +17348,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -17373,8 +17373,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.N.equals``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17398,8 +17398,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.N.equal``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -17423,8 +17423,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableNativeInts.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -17448,548 +17448,548 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.I.equals``() = validate (NullableNativeInts.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.I.equal``() = validate (NullableNativeInts.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.I.not_equal``() = validate (NullableNativeInts.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.N.equals``() = validate (NullableNativeInts.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.N.equal``() = validate (NullableNativeInts.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ValueArray E.N.not_equal``() = validate (NullableNativeInts.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.I.equals``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.I.equal``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.N.equals``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.N.equal``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableNativeInts.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.I.equals``() = validate (NullableNativeInts.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.I.equal``() = validate (NullableNativeInts.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.I.not_equal``() = validate (NullableNativeInts.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.N.equals``() = validate (NullableNativeInts.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.N.equal``() = validate (NullableNativeInts.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ArrayArray E.N.not_equal``() = validate (NullableNativeInts.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.I.equals``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.I.equals``() = validate (NullableNativeInts.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.I.equal``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.I.equal``() = validate (NullableNativeInts.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.I.not_equal``() = validate (NullableNativeInts.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.N.equals``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.N.equals``() = validate (NullableNativeInts.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.N.equal``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.N.equal``() = validate (NullableNativeInts.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableNativeInts.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableNativeInts.Collection.ListArray E.N.not_equal``() = validate (NullableNativeInts.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.I.equals``() = + [] + member _.``Bytes.Collection.Array C.I.equals``() = validate (Bytes.Collection.Array) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.I.equal``() = + [] + member _.``Bytes.Collection.Array C.I.equal``() = validate (Bytes.Collection.Array) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.I.not_equal``() = + [] + member _.``Bytes.Collection.Array C.I.not_equal``() = validate (Bytes.Collection.Array) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.I.compare``() = + [] + member _.``Bytes.Collection.Array C.I.compare``() = validate (Bytes.Collection.Array) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.I.less_than``() = + [] + member _.``Bytes.Collection.Array C.I.less_than``() = validate (Bytes.Collection.Array) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.Array C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.Array C.I.less_or_equal``() = validate (Bytes.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.I.greater_than``() = + [] + member _.``Bytes.Collection.Array C.I.greater_than``() = validate (Bytes.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.Array C.I.greater_or_equal``() = validate (Bytes.Collection.Array) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.Array C.N.equals``() = + [] + member _.``Bytes.Collection.Array C.N.equals``() = validate (Bytes.Collection.Array) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.N.equal``() = + [] + member _.``Bytes.Collection.Array C.N.equal``() = validate (Bytes.Collection.Array) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.N.not_equal``() = + [] + member _.``Bytes.Collection.Array C.N.not_equal``() = validate (Bytes.Collection.Array) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.N.compare``() = + [] + member _.``Bytes.Collection.Array C.N.compare``() = validate (Bytes.Collection.Array) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.N.less_than``() = + [] + member _.``Bytes.Collection.Array C.N.less_than``() = validate (Bytes.Collection.Array) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.Array C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.Array C.N.less_or_equal``() = validate (Bytes.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.Array C.N.greater_than``() = + [] + member _.``Bytes.Collection.Array C.N.greater_than``() = validate (Bytes.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.Array C.N.greater_or_equal``() = validate (Bytes.Collection.Array) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.OptionArray C.I.equals``() = + [] + member _.``Bytes.Collection.OptionArray C.I.equals``() = validate (Bytes.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.I.equal``() = + [] + member _.``Bytes.Collection.OptionArray C.I.equal``() = validate (Bytes.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.I.not_equal``() = validate (Bytes.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.I.compare``() = + [] + member _.``Bytes.Collection.OptionArray C.I.compare``() = validate (Bytes.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-255;0;-1;-2;1;255;0;255;254;253;1;0;-255;0;-1;-2;1;1;-254;1;0;-1;1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.I.less_than``() = + [] + member _.``Bytes.Collection.OptionArray C.I.less_than``() = validate (Bytes.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.I.less_or_equal``() = validate (Bytes.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.OptionArray C.I.greater_than``() = validate (Bytes.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.I.greater_or_equal``() = validate (Bytes.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.OptionArray C.N.equals``() = + [] + member _.``Bytes.Collection.OptionArray C.N.equals``() = validate (Bytes.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.N.equal``() = + [] + member _.``Bytes.Collection.OptionArray C.N.equal``() = validate (Bytes.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.N.not_equal``() = validate (Bytes.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.N.compare``() = + [] + member _.``Bytes.Collection.OptionArray C.N.compare``() = validate (Bytes.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-255;0;-1;-2;1;255;0;255;254;253;1;0;-255;0;-1;-2;1;1;-254;1;0;-1;1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.N.less_than``() = + [] + member _.``Bytes.Collection.OptionArray C.N.less_than``() = validate (Bytes.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.N.less_or_equal``() = validate (Bytes.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.OptionArray C.N.greater_than``() = validate (Bytes.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.OptionArray C.N.greater_or_equal``() = validate (Bytes.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.RefArray C.I.equals``() = + [] + member _.``Bytes.Collection.RefArray C.I.equals``() = validate (Bytes.Collection.RefArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.I.equal``() = + [] + member _.``Bytes.Collection.RefArray C.I.equal``() = validate (Bytes.Collection.RefArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.RefArray C.I.not_equal``() = validate (Bytes.Collection.RefArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.I.compare``() = + [] + member _.``Bytes.Collection.RefArray C.I.compare``() = validate (Bytes.Collection.RefArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.I.less_than``() = + [] + member _.``Bytes.Collection.RefArray C.I.less_than``() = validate (Bytes.Collection.RefArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.RefArray C.I.less_or_equal``() = validate (Bytes.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.RefArray C.I.greater_than``() = validate (Bytes.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.RefArray C.I.greater_or_equal``() = validate (Bytes.Collection.RefArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.RefArray C.N.equals``() = + [] + member _.``Bytes.Collection.RefArray C.N.equals``() = validate (Bytes.Collection.RefArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.N.equal``() = + [] + member _.``Bytes.Collection.RefArray C.N.equal``() = validate (Bytes.Collection.RefArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.RefArray C.N.not_equal``() = validate (Bytes.Collection.RefArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.N.compare``() = + [] + member _.``Bytes.Collection.RefArray C.N.compare``() = validate (Bytes.Collection.RefArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.N.less_than``() = + [] + member _.``Bytes.Collection.RefArray C.N.less_than``() = validate (Bytes.Collection.RefArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.RefArray C.N.less_or_equal``() = validate (Bytes.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.RefArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.RefArray C.N.greater_than``() = validate (Bytes.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.RefArray C.N.greater_or_equal``() = validate (Bytes.Collection.RefArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.equals``() = validate (Bytes.Collection.RefWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.equal``() = validate (Bytes.Collection.RefWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.not_equal``() = validate (Bytes.Collection.RefWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.compare``() = validate (Bytes.Collection.RefWrapArray) C.I.compare [| 0;-255;0;-1;-2;255;0;255;254;253;0;-255;0;-1;-2;1;-254;1;0;-1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.less_than``() = validate (Bytes.Collection.RefWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.less_or_equal``() = validate (Bytes.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.greater_than``() = validate (Bytes.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Bytes.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.equals``() = validate (Bytes.Collection.RefWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.equal``() = validate (Bytes.Collection.RefWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.not_equal``() = validate (Bytes.Collection.RefWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.compare``() = validate (Bytes.Collection.RefWrapArray) C.N.compare [| 0;-255;0;-1;-2;255;0;255;254;253;0;-255;0;-1;-2;1;-254;1;0;-1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.less_than``() = validate (Bytes.Collection.RefWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.less_or_equal``() = validate (Bytes.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.greater_than``() = validate (Bytes.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Bytes.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.UnionArray C.I.equals``() = + [] + member _.``Bytes.Collection.UnionArray C.I.equals``() = validate (Bytes.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18024,8 +18024,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.I.equal``() = + [] + member _.``Bytes.Collection.UnionArray C.I.equal``() = validate (Bytes.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18060,8 +18060,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.I.not_equal``() = validate (Bytes.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -18096,8 +18096,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.I.compare``() = + [] + member _.``Bytes.Collection.UnionArray C.I.compare``() = validate (Bytes.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -18132,8 +18132,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.I.less_than``() = + [] + member _.``Bytes.Collection.UnionArray C.I.less_than``() = validate (Bytes.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -18168,8 +18168,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Bytes.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.I.less_or_equal``() = validate (Bytes.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -18204,8 +18204,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.UnionArray C.I.greater_than``() = validate (Bytes.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -18240,8 +18240,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.I.greater_or_equal``() = validate (Bytes.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -18276,8 +18276,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Bytes.Collection.UnionArray C.N.equals``() = + [] + member _.``Bytes.Collection.UnionArray C.N.equals``() = validate (Bytes.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18312,8 +18312,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.N.equal``() = + [] + member _.``Bytes.Collection.UnionArray C.N.equal``() = validate (Bytes.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18348,8 +18348,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.N.not_equal``() = validate (Bytes.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -18384,8 +18384,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.N.compare``() = + [] + member _.``Bytes.Collection.UnionArray C.N.compare``() = validate (Bytes.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -18420,8 +18420,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.N.less_than``() = + [] + member _.``Bytes.Collection.UnionArray C.N.less_than``() = validate (Bytes.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -18456,8 +18456,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Bytes.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.N.less_or_equal``() = validate (Bytes.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -18492,8 +18492,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.UnionArray C.N.greater_than``() = validate (Bytes.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -18528,8 +18528,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.UnionArray C.N.greater_or_equal``() = validate (Bytes.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -18564,8 +18564,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.equals``() = validate (Bytes.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18600,8 +18600,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.equal``() = validate (Bytes.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18636,8 +18636,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.not_equal``() = validate (Bytes.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -18672,8 +18672,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.compare``() = validate (Bytes.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-255;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-2;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-255;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-2;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-255; @@ -18708,8 +18708,8 @@ type GeneratedTestSuite () = 3;2;1;-253;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.less_than``() = validate (Bytes.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -18744,8 +18744,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Bytes.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -18780,8 +18780,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.greater_than``() = validate (Bytes.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -18816,8 +18816,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Bytes.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -18852,8 +18852,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.equals``() = validate (Bytes.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18888,8 +18888,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.equal``() = validate (Bytes.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -18924,8 +18924,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.not_equal``() = validate (Bytes.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -18960,8 +18960,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.compare``() = validate (Bytes.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-255;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-2;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-255;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-2;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-255; @@ -18996,8 +18996,8 @@ type GeneratedTestSuite () = 3;2;1;-253;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.less_than``() = validate (Bytes.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -19032,8 +19032,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Bytes.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -19068,8 +19068,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.greater_than``() = validate (Bytes.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -19104,8 +19104,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Bytes.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -19140,734 +19140,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Bytes.Collection.ValueArray C.I.equals``() = + [] + member _.``Bytes.Collection.ValueArray C.I.equals``() = validate (Bytes.Collection.ValueArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.I.equal``() = + [] + member _.``Bytes.Collection.ValueArray C.I.equal``() = validate (Bytes.Collection.ValueArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.I.not_equal``() = validate (Bytes.Collection.ValueArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.I.compare``() = + [] + member _.``Bytes.Collection.ValueArray C.I.compare``() = validate (Bytes.Collection.ValueArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.I.less_than``() = + [] + member _.``Bytes.Collection.ValueArray C.I.less_than``() = validate (Bytes.Collection.ValueArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.I.less_or_equal``() = validate (Bytes.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.ValueArray C.I.greater_than``() = validate (Bytes.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.I.greater_or_equal``() = validate (Bytes.Collection.ValueArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ValueArray C.N.equals``() = + [] + member _.``Bytes.Collection.ValueArray C.N.equals``() = validate (Bytes.Collection.ValueArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.N.equal``() = + [] + member _.``Bytes.Collection.ValueArray C.N.equal``() = validate (Bytes.Collection.ValueArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.N.not_equal``() = validate (Bytes.Collection.ValueArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.N.compare``() = + [] + member _.``Bytes.Collection.ValueArray C.N.compare``() = validate (Bytes.Collection.ValueArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.N.less_than``() = + [] + member _.``Bytes.Collection.ValueArray C.N.less_than``() = validate (Bytes.Collection.ValueArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.N.less_or_equal``() = validate (Bytes.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.ValueArray C.N.greater_than``() = validate (Bytes.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.ValueArray C.N.greater_or_equal``() = validate (Bytes.Collection.ValueArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.equals``() = validate (Bytes.Collection.ValueWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.equal``() = validate (Bytes.Collection.ValueWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.not_equal``() = validate (Bytes.Collection.ValueWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.compare``() = validate (Bytes.Collection.ValueWrapArray) C.I.compare [| 0;-255;0;-1;-2;255;0;255;254;253;0;-255;0;-1;-2;1;-254;1;0;-1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.less_than``() = validate (Bytes.Collection.ValueWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Bytes.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.greater_than``() = validate (Bytes.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Bytes.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.equals``() = validate (Bytes.Collection.ValueWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.equal``() = validate (Bytes.Collection.ValueWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.not_equal``() = validate (Bytes.Collection.ValueWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.compare``() = validate (Bytes.Collection.ValueWrapArray) C.N.compare [| 0;-255;0;-1;-2;255;0;255;254;253;0;-255;0;-1;-2;1;-254;1;0;-1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.less_than``() = validate (Bytes.Collection.ValueWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Bytes.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.greater_than``() = validate (Bytes.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Bytes.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.equals``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.equals``() = validate (Bytes.Collection.ArrayArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.equal``() = validate (Bytes.Collection.ArrayArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.not_equal``() = validate (Bytes.Collection.ArrayArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.compare``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.compare``() = validate (Bytes.Collection.ArrayArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.less_than``() = validate (Bytes.Collection.ArrayArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.less_or_equal``() = validate (Bytes.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.greater_than``() = validate (Bytes.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.I.greater_or_equal``() = validate (Bytes.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.equals``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.equals``() = validate (Bytes.Collection.ArrayArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.equal``() = validate (Bytes.Collection.ArrayArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.not_equal``() = validate (Bytes.Collection.ArrayArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.compare``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.compare``() = validate (Bytes.Collection.ArrayArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.less_than``() = validate (Bytes.Collection.ArrayArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.less_or_equal``() = validate (Bytes.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.greater_than``() = validate (Bytes.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray C.N.greater_or_equal``() = validate (Bytes.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ListArray C.I.equals``() = + [] + member _.``Bytes.Collection.ListArray C.I.equals``() = validate (Bytes.Collection.ListArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.I.equal``() = + [] + member _.``Bytes.Collection.ListArray C.I.equal``() = validate (Bytes.Collection.ListArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.ListArray C.I.not_equal``() = validate (Bytes.Collection.ListArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.I.compare``() = + [] + member _.``Bytes.Collection.ListArray C.I.compare``() = validate (Bytes.Collection.ListArray) C.I.compare [| 0;-255;0;-1;-2;-1;-255;-1;-1;-2;255;0;255;254;253;255;-1;255;254;253;0;-255;0;-1;-2;-1;-255;-1;-1;-2;1;-254;1;0;-1;1;-254;1;-1;-1; 2;-253;2;1;0;2;-253;2;1;-1;1;-255;1;-1;-2;0;-255;254;-1;-2;255;1;255;254;253;255;0;255;254;253;1;-255;1;-1;-2;-254;-255;0;-1;-2; 1;-254;1;1;-1;1;-254;1;0;-1;2;-253;2;1;1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.I.less_than``() = + [] + member _.``Bytes.Collection.ListArray C.I.less_than``() = validate (Bytes.Collection.ListArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.ListArray C.I.less_or_equal``() = validate (Bytes.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.ListArray C.I.greater_than``() = validate (Bytes.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.ListArray C.I.greater_or_equal``() = validate (Bytes.Collection.ListArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ListArray C.N.equals``() = + [] + member _.``Bytes.Collection.ListArray C.N.equals``() = validate (Bytes.Collection.ListArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.N.equal``() = + [] + member _.``Bytes.Collection.ListArray C.N.equal``() = validate (Bytes.Collection.ListArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.ListArray C.N.not_equal``() = validate (Bytes.Collection.ListArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.N.compare``() = + [] + member _.``Bytes.Collection.ListArray C.N.compare``() = validate (Bytes.Collection.ListArray) C.N.compare [| 0;-255;0;-1;-2;-1;-255;-1;-1;-2;255;0;255;254;253;255;-1;255;254;253;0;-255;0;-1;-2;-1;-255;-1;-1;-2;1;-254;1;0;-1;1;-254;1;-1;-1; 2;-253;2;1;0;2;-253;2;1;-1;1;-255;1;-1;-2;0;-255;254;-1;-2;255;1;255;254;253;255;0;255;254;253;1;-255;1;-1;-2;-254;-255;0;-1;-2; 1;-254;1;1;-1;1;-254;1;0;-1;2;-253;2;1;1;2;-253;2;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.N.less_than``() = + [] + member _.``Bytes.Collection.ListArray C.N.less_than``() = validate (Bytes.Collection.ListArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Bytes.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.ListArray C.N.less_or_equal``() = validate (Bytes.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Bytes.Collection.ListArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.ListArray C.N.greater_than``() = validate (Bytes.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Bytes.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.ListArray C.N.greater_or_equal``() = validate (Bytes.Collection.ListArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Bytes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Bytes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``NullableBytes.Collection.Array E.I.equals``() = + [] + member _.``NullableBytes.Collection.Array E.I.equals``() = validate (NullableBytes.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.Array E.I.equal``() = + [] + member _.``NullableBytes.Collection.Array E.I.equal``() = validate (NullableBytes.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.Array E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.Array E.I.not_equal``() = validate (NullableBytes.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.Array E.N.equals``() = + [] + member _.``NullableBytes.Collection.Array E.N.equals``() = validate (NullableBytes.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.Array E.N.equal``() = + [] + member _.``NullableBytes.Collection.Array E.N.equal``() = validate (NullableBytes.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.Array E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.Array E.N.not_equal``() = validate (NullableBytes.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.OptionArray E.I.equals``() = validate (NullableBytes.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.OptionArray E.I.equal``() = validate (NullableBytes.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.OptionArray E.I.not_equal``() = validate (NullableBytes.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.OptionArray E.N.equals``() = validate (NullableBytes.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.OptionArray E.N.equal``() = validate (NullableBytes.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.OptionArray E.N.not_equal``() = validate (NullableBytes.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.RefArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.RefArray E.I.equals``() = validate (NullableBytes.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.RefArray E.I.equal``() = validate (NullableBytes.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.RefArray E.I.not_equal``() = validate (NullableBytes.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.RefArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.RefArray E.N.equals``() = validate (NullableBytes.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.RefArray E.N.equal``() = validate (NullableBytes.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.RefArray E.N.not_equal``() = validate (NullableBytes.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.I.equals``() = validate (NullableBytes.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.I.equal``() = validate (NullableBytes.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.I.not_equal``() = validate (NullableBytes.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.N.equals``() = validate (NullableBytes.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.N.equal``() = validate (NullableBytes.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.RefWrapArray E.N.not_equal``() = validate (NullableBytes.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.UnionArray E.I.equals``() = validate (NullableBytes.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -19916,8 +19916,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.UnionArray E.I.equal``() = validate (NullableBytes.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -19966,8 +19966,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.UnionArray E.I.not_equal``() = validate (NullableBytes.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -20016,8 +20016,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableBytes.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.UnionArray E.N.equals``() = validate (NullableBytes.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20066,8 +20066,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.UnionArray E.N.equal``() = validate (NullableBytes.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20116,8 +20116,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.UnionArray E.N.not_equal``() = validate (NullableBytes.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -20166,8 +20166,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.I.equals``() = validate (NullableBytes.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20216,8 +20216,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.I.equal``() = validate (NullableBytes.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20266,8 +20266,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableBytes.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -20316,8 +20316,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.N.equals``() = validate (NullableBytes.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20366,8 +20366,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.N.equal``() = validate (NullableBytes.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -20416,8 +20416,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableBytes.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableBytes.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -20466,80 +20466,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.ValueArray E.I.equals``() = validate (NullableBytes.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.ValueArray E.I.equal``() = validate (NullableBytes.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.ValueArray E.I.not_equal``() = validate (NullableBytes.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.ValueArray E.N.equals``() = validate (NullableBytes.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.ValueArray E.N.equal``() = validate (NullableBytes.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.ValueArray E.N.not_equal``() = validate (NullableBytes.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.I.equals``() = validate (NullableBytes.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.I.equal``() = validate (NullableBytes.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableBytes.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.N.equals``() = validate (NullableBytes.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.N.equal``() = validate (NullableBytes.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableBytes.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.I.equals``() = validate (NullableBytes.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20547,8 +20547,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.I.equal``() = validate (NullableBytes.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20556,8 +20556,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.I.not_equal``() = validate (NullableBytes.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -20565,8 +20565,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.N.equals``() = validate (NullableBytes.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20574,8 +20574,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.N.equal``() = validate (NullableBytes.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20583,8 +20583,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.ArrayArray E.N.not_equal``() = validate (NullableBytes.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -20592,8 +20592,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ListArray E.I.equals``() = + [] + member _.``NullableBytes.Collection.ListArray E.I.equals``() = validate (NullableBytes.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20601,8 +20601,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ListArray E.I.equal``() = + [] + member _.``NullableBytes.Collection.ListArray E.I.equal``() = validate (NullableBytes.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20610,8 +20610,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableBytes.Collection.ListArray E.I.not_equal``() = validate (NullableBytes.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -20619,8 +20619,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableBytes.Collection.ListArray E.N.equals``() = + [] + member _.``NullableBytes.Collection.ListArray E.N.equals``() = validate (NullableBytes.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20628,8 +20628,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ListArray E.N.equal``() = + [] + member _.``NullableBytes.Collection.ListArray E.N.equal``() = validate (NullableBytes.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -20637,8 +20637,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableBytes.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableBytes.Collection.ListArray E.N.not_equal``() = validate (NullableBytes.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -20646,392 +20646,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.I.equals``() = + [] + member _.``Uint16s.Collection.Array C.I.equals``() = validate (Uint16s.Collection.Array) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.I.equal``() = + [] + member _.``Uint16s.Collection.Array C.I.equal``() = validate (Uint16s.Collection.Array) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.I.not_equal``() = + [] + member _.``Uint16s.Collection.Array C.I.not_equal``() = validate (Uint16s.Collection.Array) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.I.compare``() = + [] + member _.``Uint16s.Collection.Array C.I.compare``() = validate (Uint16s.Collection.Array) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.I.less_than``() = + [] + member _.``Uint16s.Collection.Array C.I.less_than``() = validate (Uint16s.Collection.Array) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.Array C.I.less_or_equal``() = validate (Uint16s.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.I.greater_than``() = + [] + member _.``Uint16s.Collection.Array C.I.greater_than``() = validate (Uint16s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.Array C.I.greater_or_equal``() = validate (Uint16s.Collection.Array) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.Array C.N.equals``() = + [] + member _.``Uint16s.Collection.Array C.N.equals``() = validate (Uint16s.Collection.Array) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.N.equal``() = + [] + member _.``Uint16s.Collection.Array C.N.equal``() = validate (Uint16s.Collection.Array) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.N.not_equal``() = + [] + member _.``Uint16s.Collection.Array C.N.not_equal``() = validate (Uint16s.Collection.Array) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.N.compare``() = + [] + member _.``Uint16s.Collection.Array C.N.compare``() = validate (Uint16s.Collection.Array) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.N.less_than``() = + [] + member _.``Uint16s.Collection.Array C.N.less_than``() = validate (Uint16s.Collection.Array) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.Array C.N.less_or_equal``() = validate (Uint16s.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.Array C.N.greater_than``() = + [] + member _.``Uint16s.Collection.Array C.N.greater_than``() = validate (Uint16s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.Array C.N.greater_or_equal``() = validate (Uint16s.Collection.Array) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.equals``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.equals``() = validate (Uint16s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.equal``() = validate (Uint16s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.not_equal``() = validate (Uint16s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.compare``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.compare``() = validate (Uint16s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-65535;0;-1;-2;1;65535;0;65535;65534;65533;1;0;-65535;0;-1;-2;1;1;-65534;1;0;-1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.less_than``() = validate (Uint16s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.less_or_equal``() = validate (Uint16s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.greater_than``() = validate (Uint16s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.I.greater_or_equal``() = validate (Uint16s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.equals``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.equals``() = validate (Uint16s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.equal``() = validate (Uint16s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.not_equal``() = validate (Uint16s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.compare``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.compare``() = validate (Uint16s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-65535;0;-1;-2;1;65535;0;65535;65534;65533;1;0;-65535;0;-1;-2;1;1;-65534;1;0;-1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.less_than``() = validate (Uint16s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.less_or_equal``() = validate (Uint16s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.greater_than``() = validate (Uint16s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.OptionArray C.N.greater_or_equal``() = validate (Uint16s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.RefArray C.I.equals``() = + [] + member _.``Uint16s.Collection.RefArray C.I.equals``() = validate (Uint16s.Collection.RefArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.I.equal``() = + [] + member _.``Uint16s.Collection.RefArray C.I.equal``() = validate (Uint16s.Collection.RefArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.I.not_equal``() = validate (Uint16s.Collection.RefArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.I.compare``() = + [] + member _.``Uint16s.Collection.RefArray C.I.compare``() = validate (Uint16s.Collection.RefArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.RefArray C.I.less_than``() = validate (Uint16s.Collection.RefArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.I.less_or_equal``() = validate (Uint16s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.RefArray C.I.greater_than``() = validate (Uint16s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.I.greater_or_equal``() = validate (Uint16s.Collection.RefArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.RefArray C.N.equals``() = + [] + member _.``Uint16s.Collection.RefArray C.N.equals``() = validate (Uint16s.Collection.RefArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.N.equal``() = + [] + member _.``Uint16s.Collection.RefArray C.N.equal``() = validate (Uint16s.Collection.RefArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.N.not_equal``() = validate (Uint16s.Collection.RefArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.N.compare``() = + [] + member _.``Uint16s.Collection.RefArray C.N.compare``() = validate (Uint16s.Collection.RefArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.RefArray C.N.less_than``() = validate (Uint16s.Collection.RefArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.N.less_or_equal``() = validate (Uint16s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.RefArray C.N.greater_than``() = validate (Uint16s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.RefArray C.N.greater_or_equal``() = validate (Uint16s.Collection.RefArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.equals``() = validate (Uint16s.Collection.RefWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.equal``() = validate (Uint16s.Collection.RefWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.not_equal``() = validate (Uint16s.Collection.RefWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.compare``() = validate (Uint16s.Collection.RefWrapArray) C.I.compare [| 0;-65535;0;-1;-2;65535;0;65535;65534;65533;0;-65535;0;-1;-2;1;-65534;1;0;-1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.less_than``() = validate (Uint16s.Collection.RefWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Uint16s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.greater_than``() = validate (Uint16s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Uint16s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.equals``() = validate (Uint16s.Collection.RefWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.equal``() = validate (Uint16s.Collection.RefWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.not_equal``() = validate (Uint16s.Collection.RefWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.compare``() = validate (Uint16s.Collection.RefWrapArray) C.N.compare [| 0;-65535;0;-1;-2;65535;0;65535;65534;65533;0;-65535;0;-1;-2;1;-65534;1;0;-1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.less_than``() = validate (Uint16s.Collection.RefWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Uint16s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.greater_than``() = validate (Uint16s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Uint16s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.equals``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.equals``() = validate (Uint16s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21066,8 +21066,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.equal``() = validate (Uint16s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21102,8 +21102,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.not_equal``() = validate (Uint16s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -21138,8 +21138,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.compare``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.compare``() = validate (Uint16s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -21174,8 +21174,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.less_than``() = validate (Uint16s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -21210,8 +21210,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.less_or_equal``() = validate (Uint16s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -21246,8 +21246,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.greater_than``() = validate (Uint16s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -21282,8 +21282,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.I.greater_or_equal``() = validate (Uint16s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -21318,8 +21318,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.equals``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.equals``() = validate (Uint16s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21354,8 +21354,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.equal``() = validate (Uint16s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21390,8 +21390,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.not_equal``() = validate (Uint16s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -21426,8 +21426,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.compare``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.compare``() = validate (Uint16s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -21462,8 +21462,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.less_than``() = validate (Uint16s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -21498,8 +21498,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.less_or_equal``() = validate (Uint16s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -21534,8 +21534,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.greater_than``() = validate (Uint16s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -21570,8 +21570,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.UnionArray C.N.greater_or_equal``() = validate (Uint16s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -21606,8 +21606,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.equals``() = validate (Uint16s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21642,8 +21642,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.equal``() = validate (Uint16s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21678,8 +21678,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.not_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -21714,8 +21714,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.compare``() = validate (Uint16s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-65535;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-2;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-65535;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-2;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-65535; @@ -21750,8 +21750,8 @@ type GeneratedTestSuite () = 3;2;1;-65533;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.less_than``() = validate (Uint16s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -21786,8 +21786,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -21822,8 +21822,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.greater_than``() = validate (Uint16s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -21858,8 +21858,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -21894,8 +21894,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.equals``() = validate (Uint16s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21930,8 +21930,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.equal``() = validate (Uint16s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -21966,8 +21966,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.not_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -22002,8 +22002,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.compare``() = validate (Uint16s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-65535;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-2;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-65535;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-2;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-65535; @@ -22038,8 +22038,8 @@ type GeneratedTestSuite () = 3;2;1;-65533;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.less_than``() = validate (Uint16s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -22074,8 +22074,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -22110,8 +22110,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.greater_than``() = validate (Uint16s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -22146,8 +22146,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Uint16s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -22182,734 +22182,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.equals``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.equals``() = validate (Uint16s.Collection.ValueArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.equal``() = validate (Uint16s.Collection.ValueArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.not_equal``() = validate (Uint16s.Collection.ValueArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.compare``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.compare``() = validate (Uint16s.Collection.ValueArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.less_than``() = validate (Uint16s.Collection.ValueArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.less_or_equal``() = validate (Uint16s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.greater_than``() = validate (Uint16s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.I.greater_or_equal``() = validate (Uint16s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.equals``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.equals``() = validate (Uint16s.Collection.ValueArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.equal``() = validate (Uint16s.Collection.ValueArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.not_equal``() = validate (Uint16s.Collection.ValueArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.compare``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.compare``() = validate (Uint16s.Collection.ValueArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.less_than``() = validate (Uint16s.Collection.ValueArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.less_or_equal``() = validate (Uint16s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.greater_than``() = validate (Uint16s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ValueArray C.N.greater_or_equal``() = validate (Uint16s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.equals``() = validate (Uint16s.Collection.ValueWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.equal``() = validate (Uint16s.Collection.ValueWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.not_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.compare``() = validate (Uint16s.Collection.ValueWrapArray) C.I.compare [| 0;-65535;0;-1;-2;65535;0;65535;65534;65533;0;-65535;0;-1;-2;1;-65534;1;0;-1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.less_than``() = validate (Uint16s.Collection.ValueWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.greater_than``() = validate (Uint16s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.equals``() = validate (Uint16s.Collection.ValueWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.equal``() = validate (Uint16s.Collection.ValueWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.not_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.compare``() = validate (Uint16s.Collection.ValueWrapArray) C.N.compare [| 0;-65535;0;-1;-2;65535;0;65535;65534;65533;0;-65535;0;-1;-2;1;-65534;1;0;-1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.less_than``() = validate (Uint16s.Collection.ValueWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.greater_than``() = validate (Uint16s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Uint16s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.equals``() = validate (Uint16s.Collection.ArrayArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.equal``() = validate (Uint16s.Collection.ArrayArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.not_equal``() = validate (Uint16s.Collection.ArrayArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.compare``() = validate (Uint16s.Collection.ArrayArray) C.I.compare [| 0;-65535;0;-1;-2;-1;-1;-1;-1;-1;65535;0;65535;65534;65533;-1;-1;-1;-1;-1;0;-65535;0;-1;-2;-1;-1;-1;-1;-1;1;-65534;1;0;-1;-1;-1;-1;-1;-1; 2;-65533;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-65535;65534;-1;-2;1;1;1;1;1;65535;0;65535;65534;65533;1;1;1;1;1;-65534;-65535;0;-1;-2; 1;1;1;1;1;1;-65534;1;0;-1;1;1;1;1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.less_than``() = validate (Uint16s.Collection.ArrayArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.less_or_equal``() = validate (Uint16s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.greater_than``() = validate (Uint16s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Uint16s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.equals``() = validate (Uint16s.Collection.ArrayArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.equal``() = validate (Uint16s.Collection.ArrayArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.not_equal``() = validate (Uint16s.Collection.ArrayArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.compare``() = validate (Uint16s.Collection.ArrayArray) C.N.compare [| 0;-65535;0;-1;-2;-1;-1;-1;-1;-1;65535;0;65535;65534;65533;-1;-1;-1;-1;-1;0;-65535;0;-1;-2;-1;-1;-1;-1;-1;1;-65534;1;0;-1;-1;-1;-1;-1;-1; 2;-65533;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-65535;65534;-1;-2;1;1;1;1;1;65535;0;65535;65534;65533;1;1;1;1;1;-65534;-65535;0;-1;-2; 1;1;1;1;1;1;-65534;1;0;-1;1;1;1;1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.less_than``() = validate (Uint16s.Collection.ArrayArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.less_or_equal``() = validate (Uint16s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.greater_than``() = validate (Uint16s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Uint16s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ListArray C.I.equals``() = + [] + member _.``Uint16s.Collection.ListArray C.I.equals``() = validate (Uint16s.Collection.ListArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.I.equal``() = + [] + member _.``Uint16s.Collection.ListArray C.I.equal``() = validate (Uint16s.Collection.ListArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.I.not_equal``() = validate (Uint16s.Collection.ListArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.I.compare``() = + [] + member _.``Uint16s.Collection.ListArray C.I.compare``() = validate (Uint16s.Collection.ListArray) C.I.compare [| 0;-65535;0;-1;-2;-1;-65535;-1;-1;-2;65535;0;65535;65534;65533;65535;-1;65535;65534;65533;0;-65535;0;-1;-2;-1;-65535;-1;-1;-2;1;-65534;1;0;-1;1;-65534;1;-1;-1; 2;-65533;2;1;0;2;-65533;2;1;-1;1;-65535;1;-1;-2;0;-65535;65534;-1;-2;65535;1;65535;65534;65533;65535;0;65535;65534;65533;1;-65535;1;-1;-2;-65534;-65535;0;-1;-2; 1;-65534;1;1;-1;1;-65534;1;0;-1;2;-65533;2;1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.ListArray C.I.less_than``() = validate (Uint16s.Collection.ListArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.I.less_or_equal``() = validate (Uint16s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.ListArray C.I.greater_than``() = validate (Uint16s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.I.greater_or_equal``() = validate (Uint16s.Collection.ListArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ListArray C.N.equals``() = + [] + member _.``Uint16s.Collection.ListArray C.N.equals``() = validate (Uint16s.Collection.ListArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.N.equal``() = + [] + member _.``Uint16s.Collection.ListArray C.N.equal``() = validate (Uint16s.Collection.ListArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.N.not_equal``() = validate (Uint16s.Collection.ListArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.N.compare``() = + [] + member _.``Uint16s.Collection.ListArray C.N.compare``() = validate (Uint16s.Collection.ListArray) C.N.compare [| 0;-65535;0;-1;-2;-1;-65535;-1;-1;-2;65535;0;65535;65534;65533;65535;-1;65535;65534;65533;0;-65535;0;-1;-2;-1;-65535;-1;-1;-2;1;-65534;1;0;-1;1;-65534;1;-1;-1; 2;-65533;2;1;0;2;-65533;2;1;-1;1;-65535;1;-1;-2;0;-65535;65534;-1;-2;65535;1;65535;65534;65533;65535;0;65535;65534;65533;1;-65535;1;-1;-2;-65534;-65535;0;-1;-2; 1;-65534;1;1;-1;1;-65534;1;0;-1;2;-65533;2;1;1;2;-65533;2;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.ListArray C.N.less_than``() = validate (Uint16s.Collection.ListArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Uint16s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.N.less_or_equal``() = validate (Uint16s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Uint16s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.ListArray C.N.greater_than``() = validate (Uint16s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Uint16s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ListArray C.N.greater_or_equal``() = validate (Uint16s.Collection.ListArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Uint16s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Uint16s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``NullableUInt16s.Collection.Array E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.Array E.I.equals``() = validate (NullableUInt16s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.Array E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.Array E.I.equal``() = validate (NullableUInt16s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.Array E.I.not_equal``() = validate (NullableUInt16s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.Array E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.Array E.N.equals``() = validate (NullableUInt16s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.Array E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.Array E.N.equal``() = validate (NullableUInt16s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.Array E.N.not_equal``() = validate (NullableUInt16s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.I.equals``() = validate (NullableUInt16s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.I.equal``() = validate (NullableUInt16s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.I.not_equal``() = validate (NullableUInt16s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.N.equals``() = validate (NullableUInt16s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.N.equal``() = validate (NullableUInt16s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.OptionArray E.N.not_equal``() = validate (NullableUInt16s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.I.equals``() = validate (NullableUInt16s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.I.equal``() = validate (NullableUInt16s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.I.not_equal``() = validate (NullableUInt16s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.N.equals``() = validate (NullableUInt16s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.N.equal``() = validate (NullableUInt16s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.RefArray E.N.not_equal``() = validate (NullableUInt16s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.I.equals``() = validate (NullableUInt16s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.I.equal``() = validate (NullableUInt16s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableUInt16s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.N.equals``() = validate (NullableUInt16s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.N.equal``() = validate (NullableUInt16s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableUInt16s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.I.equals``() = validate (NullableUInt16s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -22958,8 +22958,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.I.equal``() = validate (NullableUInt16s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23008,8 +23008,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.I.not_equal``() = validate (NullableUInt16s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -23058,8 +23058,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.N.equals``() = validate (NullableUInt16s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23108,8 +23108,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.N.equal``() = validate (NullableUInt16s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23158,8 +23158,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.UnionArray E.N.not_equal``() = validate (NullableUInt16s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -23208,8 +23208,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.I.equals``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23258,8 +23258,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.I.equal``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23308,8 +23308,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -23358,8 +23358,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.N.equals``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23408,8 +23408,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.N.equal``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -23458,8 +23458,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableUInt16s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -23508,80 +23508,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.I.equals``() = validate (NullableUInt16s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.I.equal``() = validate (NullableUInt16s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.I.not_equal``() = validate (NullableUInt16s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.N.equals``() = validate (NullableUInt16s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.N.equal``() = validate (NullableUInt16s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ValueArray E.N.not_equal``() = validate (NullableUInt16s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.I.equals``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.I.equal``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.N.equals``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.N.equal``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableUInt16s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.I.equals``() = validate (NullableUInt16s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23589,8 +23589,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.I.equal``() = validate (NullableUInt16s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23598,8 +23598,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.I.not_equal``() = validate (NullableUInt16s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -23607,8 +23607,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.N.equals``() = validate (NullableUInt16s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23616,8 +23616,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.N.equal``() = validate (NullableUInt16s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23625,8 +23625,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ArrayArray E.N.not_equal``() = validate (NullableUInt16s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -23634,8 +23634,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.I.equals``() = validate (NullableUInt16s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23643,8 +23643,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.I.equal``() = validate (NullableUInt16s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23652,8 +23652,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.I.not_equal``() = validate (NullableUInt16s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -23661,8 +23661,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.N.equals``() = validate (NullableUInt16s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23670,8 +23670,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.N.equal``() = validate (NullableUInt16s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -23679,8 +23679,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt16s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableUInt16s.Collection.ListArray E.N.not_equal``() = validate (NullableUInt16s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -23688,392 +23688,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.I.equals``() = + [] + member _.``UInt32s.Collection.Array C.I.equals``() = validate (UInt32s.Collection.Array) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.I.equal``() = + [] + member _.``UInt32s.Collection.Array C.I.equal``() = validate (UInt32s.Collection.Array) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.I.not_equal``() = + [] + member _.``UInt32s.Collection.Array C.I.not_equal``() = validate (UInt32s.Collection.Array) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.I.compare``() = + [] + member _.``UInt32s.Collection.Array C.I.compare``() = validate (UInt32s.Collection.Array) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.I.less_than``() = + [] + member _.``UInt32s.Collection.Array C.I.less_than``() = validate (UInt32s.Collection.Array) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.Array C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.Array C.I.less_or_equal``() = validate (UInt32s.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.I.greater_than``() = + [] + member _.``UInt32s.Collection.Array C.I.greater_than``() = validate (UInt32s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.Array C.I.greater_or_equal``() = validate (UInt32s.Collection.Array) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.Array C.N.equals``() = + [] + member _.``UInt32s.Collection.Array C.N.equals``() = validate (UInt32s.Collection.Array) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.N.equal``() = + [] + member _.``UInt32s.Collection.Array C.N.equal``() = validate (UInt32s.Collection.Array) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.N.not_equal``() = + [] + member _.``UInt32s.Collection.Array C.N.not_equal``() = validate (UInt32s.Collection.Array) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.N.compare``() = + [] + member _.``UInt32s.Collection.Array C.N.compare``() = validate (UInt32s.Collection.Array) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.N.less_than``() = + [] + member _.``UInt32s.Collection.Array C.N.less_than``() = validate (UInt32s.Collection.Array) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.Array C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.Array C.N.less_or_equal``() = validate (UInt32s.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.Array C.N.greater_than``() = + [] + member _.``UInt32s.Collection.Array C.N.greater_than``() = validate (UInt32s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.Array C.N.greater_or_equal``() = validate (UInt32s.Collection.Array) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.equals``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.equals``() = validate (UInt32s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.equal``() = validate (UInt32s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.not_equal``() = validate (UInt32s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.compare``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.compare``() = validate (UInt32s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;0;-1;-1;1;1;0;1;1;1;1;0;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.less_than``() = validate (UInt32s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.less_or_equal``() = validate (UInt32s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.greater_than``() = validate (UInt32s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.I.greater_or_equal``() = validate (UInt32s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.equals``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.equals``() = validate (UInt32s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.equal``() = validate (UInt32s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.not_equal``() = validate (UInt32s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.compare``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.compare``() = validate (UInt32s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;0;-1;-1;1;1;0;1;1;1;1;0;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.less_than``() = validate (UInt32s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.less_or_equal``() = validate (UInt32s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.greater_than``() = validate (UInt32s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.OptionArray C.N.greater_or_equal``() = validate (UInt32s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.RefArray C.I.equals``() = + [] + member _.``UInt32s.Collection.RefArray C.I.equals``() = validate (UInt32s.Collection.RefArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.I.equal``() = + [] + member _.``UInt32s.Collection.RefArray C.I.equal``() = validate (UInt32s.Collection.RefArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.I.not_equal``() = validate (UInt32s.Collection.RefArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.I.compare``() = + [] + member _.``UInt32s.Collection.RefArray C.I.compare``() = validate (UInt32s.Collection.RefArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.RefArray C.I.less_than``() = validate (UInt32s.Collection.RefArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.I.less_or_equal``() = validate (UInt32s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.RefArray C.I.greater_than``() = validate (UInt32s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.I.greater_or_equal``() = validate (UInt32s.Collection.RefArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.RefArray C.N.equals``() = + [] + member _.``UInt32s.Collection.RefArray C.N.equals``() = validate (UInt32s.Collection.RefArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.N.equal``() = + [] + member _.``UInt32s.Collection.RefArray C.N.equal``() = validate (UInt32s.Collection.RefArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.N.not_equal``() = validate (UInt32s.Collection.RefArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.N.compare``() = + [] + member _.``UInt32s.Collection.RefArray C.N.compare``() = validate (UInt32s.Collection.RefArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.RefArray C.N.less_than``() = validate (UInt32s.Collection.RefArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.N.less_or_equal``() = validate (UInt32s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.RefArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.RefArray C.N.greater_than``() = validate (UInt32s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.RefArray C.N.greater_or_equal``() = validate (UInt32s.Collection.RefArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.equals``() = validate (UInt32s.Collection.RefWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.equal``() = validate (UInt32s.Collection.RefWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.not_equal``() = validate (UInt32s.Collection.RefWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.compare``() = validate (UInt32s.Collection.RefWrapArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.less_than``() = validate (UInt32s.Collection.RefWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.less_or_equal``() = validate (UInt32s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.greater_than``() = validate (UInt32s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (UInt32s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.equals``() = validate (UInt32s.Collection.RefWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.equal``() = validate (UInt32s.Collection.RefWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.not_equal``() = validate (UInt32s.Collection.RefWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.compare``() = validate (UInt32s.Collection.RefWrapArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.less_than``() = validate (UInt32s.Collection.RefWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.less_or_equal``() = validate (UInt32s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.greater_than``() = validate (UInt32s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (UInt32s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.equals``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.equals``() = validate (UInt32s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24108,8 +24108,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.equal``() = validate (UInt32s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24144,8 +24144,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.not_equal``() = validate (UInt32s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -24180,8 +24180,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.compare``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.compare``() = validate (UInt32s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -24216,8 +24216,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.less_than``() = validate (UInt32s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -24252,8 +24252,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.less_or_equal``() = validate (UInt32s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -24288,8 +24288,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.greater_than``() = validate (UInt32s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -24324,8 +24324,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.I.greater_or_equal``() = validate (UInt32s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -24360,8 +24360,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.equals``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.equals``() = validate (UInt32s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24396,8 +24396,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.equal``() = validate (UInt32s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24432,8 +24432,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.not_equal``() = validate (UInt32s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -24468,8 +24468,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.compare``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.compare``() = validate (UInt32s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -24504,8 +24504,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.less_than``() = validate (UInt32s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -24540,8 +24540,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.less_or_equal``() = validate (UInt32s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -24576,8 +24576,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.greater_than``() = validate (UInt32s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -24612,8 +24612,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.UnionArray C.N.greater_or_equal``() = validate (UInt32s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -24648,8 +24648,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.equals``() = validate (UInt32s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24684,8 +24684,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.equal``() = validate (UInt32s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24720,8 +24720,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.not_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -24756,8 +24756,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.compare``() = validate (UInt32s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -24792,8 +24792,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.less_than``() = validate (UInt32s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -24828,8 +24828,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -24864,8 +24864,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.greater_than``() = validate (UInt32s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -24900,8 +24900,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -24936,8 +24936,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.equals``() = validate (UInt32s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -24972,8 +24972,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.equal``() = validate (UInt32s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -25008,8 +25008,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.not_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -25044,8 +25044,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.compare``() = validate (UInt32s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -25080,8 +25080,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.less_than``() = validate (UInt32s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -25116,8 +25116,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -25152,8 +25152,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.greater_than``() = validate (UInt32s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -25188,8 +25188,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (UInt32s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -25224,734 +25224,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.equals``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.equals``() = validate (UInt32s.Collection.ValueArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.equal``() = validate (UInt32s.Collection.ValueArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.not_equal``() = validate (UInt32s.Collection.ValueArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.compare``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.compare``() = validate (UInt32s.Collection.ValueArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.less_than``() = validate (UInt32s.Collection.ValueArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.less_or_equal``() = validate (UInt32s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.greater_than``() = validate (UInt32s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.I.greater_or_equal``() = validate (UInt32s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.equals``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.equals``() = validate (UInt32s.Collection.ValueArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.equal``() = validate (UInt32s.Collection.ValueArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.not_equal``() = validate (UInt32s.Collection.ValueArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.compare``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.compare``() = validate (UInt32s.Collection.ValueArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.less_than``() = validate (UInt32s.Collection.ValueArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.less_or_equal``() = validate (UInt32s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.greater_than``() = validate (UInt32s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ValueArray C.N.greater_or_equal``() = validate (UInt32s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.equals``() = validate (UInt32s.Collection.ValueWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.equal``() = validate (UInt32s.Collection.ValueWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.not_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.compare``() = validate (UInt32s.Collection.ValueWrapArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.less_than``() = validate (UInt32s.Collection.ValueWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.greater_than``() = validate (UInt32s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.equals``() = validate (UInt32s.Collection.ValueWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.equal``() = validate (UInt32s.Collection.ValueWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.not_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.compare``() = validate (UInt32s.Collection.ValueWrapArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.less_than``() = validate (UInt32s.Collection.ValueWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.greater_than``() = validate (UInt32s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (UInt32s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.equals``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.equals``() = validate (UInt32s.Collection.ArrayArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.equal``() = validate (UInt32s.Collection.ArrayArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.not_equal``() = validate (UInt32s.Collection.ArrayArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.compare``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.compare``() = validate (UInt32s.Collection.ArrayArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.less_than``() = validate (UInt32s.Collection.ArrayArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.less_or_equal``() = validate (UInt32s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.greater_than``() = validate (UInt32s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.I.greater_or_equal``() = validate (UInt32s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.equals``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.equals``() = validate (UInt32s.Collection.ArrayArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.equal``() = validate (UInt32s.Collection.ArrayArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.not_equal``() = validate (UInt32s.Collection.ArrayArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.compare``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.compare``() = validate (UInt32s.Collection.ArrayArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.less_than``() = validate (UInt32s.Collection.ArrayArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.less_or_equal``() = validate (UInt32s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.greater_than``() = validate (UInt32s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray C.N.greater_or_equal``() = validate (UInt32s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ListArray C.I.equals``() = + [] + member _.``UInt32s.Collection.ListArray C.I.equals``() = validate (UInt32s.Collection.ListArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.I.equal``() = + [] + member _.``UInt32s.Collection.ListArray C.I.equal``() = validate (UInt32s.Collection.ListArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.I.not_equal``() = validate (UInt32s.Collection.ListArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.I.compare``() = + [] + member _.``UInt32s.Collection.ListArray C.I.compare``() = validate (UInt32s.Collection.ListArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;1;-1;-1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.ListArray C.I.less_than``() = validate (UInt32s.Collection.ListArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.I.less_or_equal``() = validate (UInt32s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.ListArray C.I.greater_than``() = validate (UInt32s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.I.greater_or_equal``() = validate (UInt32s.Collection.ListArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ListArray C.N.equals``() = + [] + member _.``UInt32s.Collection.ListArray C.N.equals``() = validate (UInt32s.Collection.ListArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.N.equal``() = + [] + member _.``UInt32s.Collection.ListArray C.N.equal``() = validate (UInt32s.Collection.ListArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.N.not_equal``() = validate (UInt32s.Collection.ListArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.N.compare``() = + [] + member _.``UInt32s.Collection.ListArray C.N.compare``() = validate (UInt32s.Collection.ListArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;1;-1;-1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.ListArray C.N.less_than``() = validate (UInt32s.Collection.ListArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt32s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.N.less_or_equal``() = validate (UInt32s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt32s.Collection.ListArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.ListArray C.N.greater_than``() = validate (UInt32s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt32s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ListArray C.N.greater_or_equal``() = validate (UInt32s.Collection.ListArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``UInt32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (UInt32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``NullableUInt32s.Collection.Array E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.Array E.I.equals``() = validate (NullableUInt32s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.Array E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.Array E.I.equal``() = validate (NullableUInt32s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.Array E.I.not_equal``() = validate (NullableUInt32s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.Array E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.Array E.N.equals``() = validate (NullableUInt32s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.Array E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.Array E.N.equal``() = validate (NullableUInt32s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.Array E.N.not_equal``() = validate (NullableUInt32s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.I.equals``() = validate (NullableUInt32s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.I.equal``() = validate (NullableUInt32s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.I.not_equal``() = validate (NullableUInt32s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.N.equals``() = validate (NullableUInt32s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.N.equal``() = validate (NullableUInt32s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.OptionArray E.N.not_equal``() = validate (NullableUInt32s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.I.equals``() = validate (NullableUInt32s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.I.equal``() = validate (NullableUInt32s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.I.not_equal``() = validate (NullableUInt32s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.N.equals``() = validate (NullableUInt32s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.N.equal``() = validate (NullableUInt32s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.RefArray E.N.not_equal``() = validate (NullableUInt32s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.I.equals``() = validate (NullableUInt32s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.I.equal``() = validate (NullableUInt32s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableUInt32s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.N.equals``() = validate (NullableUInt32s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.N.equal``() = validate (NullableUInt32s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableUInt32s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.I.equals``() = validate (NullableUInt32s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26000,8 +26000,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.I.equal``() = validate (NullableUInt32s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26050,8 +26050,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.I.not_equal``() = validate (NullableUInt32s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -26100,8 +26100,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.N.equals``() = validate (NullableUInt32s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26150,8 +26150,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.N.equal``() = validate (NullableUInt32s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26200,8 +26200,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.UnionArray E.N.not_equal``() = validate (NullableUInt32s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -26250,8 +26250,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.I.equals``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26300,8 +26300,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.I.equal``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26350,8 +26350,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -26400,8 +26400,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.N.equals``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26450,8 +26450,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.N.equal``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -26500,8 +26500,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableUInt32s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -26550,80 +26550,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.I.equals``() = validate (NullableUInt32s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.I.equal``() = validate (NullableUInt32s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.I.not_equal``() = validate (NullableUInt32s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.N.equals``() = validate (NullableUInt32s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.N.equal``() = validate (NullableUInt32s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ValueArray E.N.not_equal``() = validate (NullableUInt32s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.I.equals``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.I.equal``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.N.equals``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.N.equal``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableUInt32s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.I.equals``() = validate (NullableUInt32s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26631,8 +26631,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.I.equal``() = validate (NullableUInt32s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26640,8 +26640,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.I.not_equal``() = validate (NullableUInt32s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -26649,8 +26649,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.N.equals``() = validate (NullableUInt32s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26658,8 +26658,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.N.equal``() = validate (NullableUInt32s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26667,8 +26667,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ArrayArray E.N.not_equal``() = validate (NullableUInt32s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -26676,8 +26676,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.I.equals``() = validate (NullableUInt32s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26685,8 +26685,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.I.equal``() = validate (NullableUInt32s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26694,8 +26694,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.I.not_equal``() = validate (NullableUInt32s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -26703,8 +26703,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.N.equals``() = validate (NullableUInt32s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26712,8 +26712,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.N.equal``() = validate (NullableUInt32s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -26721,8 +26721,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt32s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableUInt32s.Collection.ListArray E.N.not_equal``() = validate (NullableUInt32s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -26730,392 +26730,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.I.equals``() = + [] + member _.``UInt64s.Collection.Array C.I.equals``() = validate (UInt64s.Collection.Array) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.I.equal``() = + [] + member _.``UInt64s.Collection.Array C.I.equal``() = validate (UInt64s.Collection.Array) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.I.not_equal``() = + [] + member _.``UInt64s.Collection.Array C.I.not_equal``() = validate (UInt64s.Collection.Array) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.I.compare``() = + [] + member _.``UInt64s.Collection.Array C.I.compare``() = validate (UInt64s.Collection.Array) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.I.less_than``() = + [] + member _.``UInt64s.Collection.Array C.I.less_than``() = validate (UInt64s.Collection.Array) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.Array C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.Array C.I.less_or_equal``() = validate (UInt64s.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.I.greater_than``() = + [] + member _.``UInt64s.Collection.Array C.I.greater_than``() = validate (UInt64s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.Array C.I.greater_or_equal``() = validate (UInt64s.Collection.Array) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.Array C.N.equals``() = + [] + member _.``UInt64s.Collection.Array C.N.equals``() = validate (UInt64s.Collection.Array) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.N.equal``() = + [] + member _.``UInt64s.Collection.Array C.N.equal``() = validate (UInt64s.Collection.Array) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.N.not_equal``() = + [] + member _.``UInt64s.Collection.Array C.N.not_equal``() = validate (UInt64s.Collection.Array) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.N.compare``() = + [] + member _.``UInt64s.Collection.Array C.N.compare``() = validate (UInt64s.Collection.Array) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.N.less_than``() = + [] + member _.``UInt64s.Collection.Array C.N.less_than``() = validate (UInt64s.Collection.Array) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.Array C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.Array C.N.less_or_equal``() = validate (UInt64s.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.Array C.N.greater_than``() = + [] + member _.``UInt64s.Collection.Array C.N.greater_than``() = validate (UInt64s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.Array C.N.greater_or_equal``() = validate (UInt64s.Collection.Array) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.equals``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.equals``() = validate (UInt64s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.equal``() = validate (UInt64s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.not_equal``() = validate (UInt64s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.compare``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.compare``() = validate (UInt64s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;0;-1;-1;1;1;0;1;1;1;1;0;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.less_than``() = validate (UInt64s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.less_or_equal``() = validate (UInt64s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.greater_than``() = validate (UInt64s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.I.greater_or_equal``() = validate (UInt64s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.equals``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.equals``() = validate (UInt64s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.equal``() = validate (UInt64s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.not_equal``() = validate (UInt64s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.compare``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.compare``() = validate (UInt64s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;0;-1;-1;1;1;0;1;1;1;1;0;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.less_than``() = validate (UInt64s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.less_or_equal``() = validate (UInt64s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.greater_than``() = validate (UInt64s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.OptionArray C.N.greater_or_equal``() = validate (UInt64s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.RefArray C.I.equals``() = + [] + member _.``UInt64s.Collection.RefArray C.I.equals``() = validate (UInt64s.Collection.RefArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.I.equal``() = + [] + member _.``UInt64s.Collection.RefArray C.I.equal``() = validate (UInt64s.Collection.RefArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.I.not_equal``() = validate (UInt64s.Collection.RefArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.I.compare``() = + [] + member _.``UInt64s.Collection.RefArray C.I.compare``() = validate (UInt64s.Collection.RefArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.RefArray C.I.less_than``() = validate (UInt64s.Collection.RefArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.I.less_or_equal``() = validate (UInt64s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.RefArray C.I.greater_than``() = validate (UInt64s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.I.greater_or_equal``() = validate (UInt64s.Collection.RefArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.RefArray C.N.equals``() = + [] + member _.``UInt64s.Collection.RefArray C.N.equals``() = validate (UInt64s.Collection.RefArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.N.equal``() = + [] + member _.``UInt64s.Collection.RefArray C.N.equal``() = validate (UInt64s.Collection.RefArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.N.not_equal``() = validate (UInt64s.Collection.RefArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.N.compare``() = + [] + member _.``UInt64s.Collection.RefArray C.N.compare``() = validate (UInt64s.Collection.RefArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.RefArray C.N.less_than``() = validate (UInt64s.Collection.RefArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.N.less_or_equal``() = validate (UInt64s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.RefArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.RefArray C.N.greater_than``() = validate (UInt64s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.RefArray C.N.greater_or_equal``() = validate (UInt64s.Collection.RefArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.equals``() = validate (UInt64s.Collection.RefWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.equal``() = validate (UInt64s.Collection.RefWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.not_equal``() = validate (UInt64s.Collection.RefWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.compare``() = validate (UInt64s.Collection.RefWrapArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.less_than``() = validate (UInt64s.Collection.RefWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.less_or_equal``() = validate (UInt64s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.greater_than``() = validate (UInt64s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (UInt64s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.equals``() = validate (UInt64s.Collection.RefWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.equal``() = validate (UInt64s.Collection.RefWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.not_equal``() = validate (UInt64s.Collection.RefWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.compare``() = validate (UInt64s.Collection.RefWrapArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.less_than``() = validate (UInt64s.Collection.RefWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.less_or_equal``() = validate (UInt64s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.greater_than``() = validate (UInt64s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (UInt64s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.equals``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.equals``() = validate (UInt64s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27150,8 +27150,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.equal``() = validate (UInt64s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27186,8 +27186,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.not_equal``() = validate (UInt64s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -27222,8 +27222,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.compare``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.compare``() = validate (UInt64s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -27258,8 +27258,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.less_than``() = validate (UInt64s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -27294,8 +27294,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.less_or_equal``() = validate (UInt64s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -27330,8 +27330,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.greater_than``() = validate (UInt64s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -27366,8 +27366,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.I.greater_or_equal``() = validate (UInt64s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -27402,8 +27402,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.equals``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.equals``() = validate (UInt64s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27438,8 +27438,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.equal``() = validate (UInt64s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27474,8 +27474,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.not_equal``() = validate (UInt64s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -27510,8 +27510,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.compare``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.compare``() = validate (UInt64s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -27546,8 +27546,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.less_than``() = validate (UInt64s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -27582,8 +27582,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.less_or_equal``() = validate (UInt64s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -27618,8 +27618,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.greater_than``() = validate (UInt64s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -27654,8 +27654,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.UnionArray C.N.greater_or_equal``() = validate (UInt64s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -27690,8 +27690,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.equals``() = validate (UInt64s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27726,8 +27726,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.equal``() = validate (UInt64s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -27762,8 +27762,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.not_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -27798,8 +27798,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.compare``() = validate (UInt64s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -27834,8 +27834,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.less_than``() = validate (UInt64s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -27870,8 +27870,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -27906,8 +27906,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.greater_than``() = validate (UInt64s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -27942,8 +27942,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -27978,8 +27978,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.equals``() = validate (UInt64s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -28014,8 +28014,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.equal``() = validate (UInt64s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -28050,8 +28050,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.not_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -28086,8 +28086,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.compare``() = validate (UInt64s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -28122,8 +28122,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.less_than``() = validate (UInt64s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -28158,8 +28158,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -28194,8 +28194,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.greater_than``() = validate (UInt64s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -28230,8 +28230,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (UInt64s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -28266,734 +28266,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.equals``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.equals``() = validate (UInt64s.Collection.ValueArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.equal``() = validate (UInt64s.Collection.ValueArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.not_equal``() = validate (UInt64s.Collection.ValueArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.compare``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.compare``() = validate (UInt64s.Collection.ValueArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.less_than``() = validate (UInt64s.Collection.ValueArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.less_or_equal``() = validate (UInt64s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.greater_than``() = validate (UInt64s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.I.greater_or_equal``() = validate (UInt64s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.equals``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.equals``() = validate (UInt64s.Collection.ValueArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.equal``() = validate (UInt64s.Collection.ValueArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.not_equal``() = validate (UInt64s.Collection.ValueArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.compare``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.compare``() = validate (UInt64s.Collection.ValueArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.less_than``() = validate (UInt64s.Collection.ValueArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.less_or_equal``() = validate (UInt64s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.greater_than``() = validate (UInt64s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ValueArray C.N.greater_or_equal``() = validate (UInt64s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.equals``() = validate (UInt64s.Collection.ValueWrapArray) C.I.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.equal``() = validate (UInt64s.Collection.ValueWrapArray) C.I.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.not_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.compare``() = validate (UInt64s.Collection.ValueWrapArray) C.I.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.less_than``() = validate (UInt64s.Collection.ValueWrapArray) C.I.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.greater_than``() = validate (UInt64s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.equals``() = validate (UInt64s.Collection.ValueWrapArray) C.N.equals [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.equal``() = validate (UInt64s.Collection.ValueWrapArray) C.N.equal [| 1;0;1;0;0;0;1;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.not_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;0;1;1;1;0;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.compare``() = validate (UInt64s.Collection.ValueWrapArray) C.N.compare [| 0;-1;0;-1;-1;1;0;1;1;1;0;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.less_than``() = validate (UInt64s.Collection.ValueWrapArray) C.N.less_than [| 0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.greater_than``() = validate (UInt64s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (UInt64s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;1;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.equals``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.equals``() = validate (UInt64s.Collection.ArrayArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.equal``() = validate (UInt64s.Collection.ArrayArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.not_equal``() = validate (UInt64s.Collection.ArrayArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.compare``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.compare``() = validate (UInt64s.Collection.ArrayArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.less_than``() = validate (UInt64s.Collection.ArrayArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.less_or_equal``() = validate (UInt64s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.greater_than``() = validate (UInt64s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.I.greater_or_equal``() = validate (UInt64s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.equals``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.equals``() = validate (UInt64s.Collection.ArrayArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.equal``() = validate (UInt64s.Collection.ArrayArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.not_equal``() = validate (UInt64s.Collection.ArrayArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.compare``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.compare``() = validate (UInt64s.Collection.ArrayArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;-1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.less_than``() = validate (UInt64s.Collection.ArrayArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.less_or_equal``() = validate (UInt64s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.greater_than``() = validate (UInt64s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray C.N.greater_or_equal``() = validate (UInt64s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ListArray C.I.equals``() = + [] + member _.``UInt64s.Collection.ListArray C.I.equals``() = validate (UInt64s.Collection.ListArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.I.equal``() = + [] + member _.``UInt64s.Collection.ListArray C.I.equal``() = validate (UInt64s.Collection.ListArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.I.not_equal``() = validate (UInt64s.Collection.ListArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.I.compare``() = + [] + member _.``UInt64s.Collection.ListArray C.I.compare``() = validate (UInt64s.Collection.ListArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;1;-1;-1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.ListArray C.I.less_than``() = validate (UInt64s.Collection.ListArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.I.less_or_equal``() = validate (UInt64s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.ListArray C.I.greater_than``() = validate (UInt64s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.I.greater_or_equal``() = validate (UInt64s.Collection.ListArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ListArray C.N.equals``() = + [] + member _.``UInt64s.Collection.ListArray C.N.equals``() = validate (UInt64s.Collection.ListArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.N.equal``() = + [] + member _.``UInt64s.Collection.ListArray C.N.equal``() = validate (UInt64s.Collection.ListArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.N.not_equal``() = validate (UInt64s.Collection.ListArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.N.compare``() = + [] + member _.``UInt64s.Collection.ListArray C.N.compare``() = validate (UInt64s.Collection.ListArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;1;-1;-1;0;-1;1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.ListArray C.N.less_than``() = validate (UInt64s.Collection.ListArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;0;1;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``UInt64s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.N.less_or_equal``() = validate (UInt64s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``UInt64s.Collection.ListArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.ListArray C.N.greater_than``() = validate (UInt64s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;0;0;0;0;1;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``UInt64s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ListArray C.N.greater_or_equal``() = validate (UInt64s.Collection.ListArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;1;0;0;1;0;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;0;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;0;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;1;-1;-1;-1;-1;1;-1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;0;1;0;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;1;0;1;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0 |] - [] - member __.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``UInt64s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (UInt64s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0; 1;0;1;1;0;1;1;1;1;1;1;0;1;0;0;0;0;1;0;1 |] - [] - member __.``NullableUInt64s.Collection.Array E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.Array E.I.equals``() = validate (NullableUInt64s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.Array E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.Array E.I.equal``() = validate (NullableUInt64s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.Array E.I.not_equal``() = validate (NullableUInt64s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.Array E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.Array E.N.equals``() = validate (NullableUInt64s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.Array E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.Array E.N.equal``() = validate (NullableUInt64s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.Array E.N.not_equal``() = validate (NullableUInt64s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.I.equals``() = validate (NullableUInt64s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.I.equal``() = validate (NullableUInt64s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.I.not_equal``() = validate (NullableUInt64s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.N.equals``() = validate (NullableUInt64s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.N.equal``() = validate (NullableUInt64s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.OptionArray E.N.not_equal``() = validate (NullableUInt64s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.I.equals``() = validate (NullableUInt64s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.I.equal``() = validate (NullableUInt64s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.I.not_equal``() = validate (NullableUInt64s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.N.equals``() = validate (NullableUInt64s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.N.equal``() = validate (NullableUInt64s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.RefArray E.N.not_equal``() = validate (NullableUInt64s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.I.equals``() = validate (NullableUInt64s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.I.equal``() = validate (NullableUInt64s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableUInt64s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.N.equals``() = validate (NullableUInt64s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.N.equal``() = validate (NullableUInt64s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableUInt64s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.I.equals``() = validate (NullableUInt64s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29042,8 +29042,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.I.equal``() = validate (NullableUInt64s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29092,8 +29092,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.I.not_equal``() = validate (NullableUInt64s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -29142,8 +29142,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.N.equals``() = validate (NullableUInt64s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29192,8 +29192,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.N.equal``() = validate (NullableUInt64s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29242,8 +29242,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.UnionArray E.N.not_equal``() = validate (NullableUInt64s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -29292,8 +29292,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.I.equals``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29342,8 +29342,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.I.equal``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29392,8 +29392,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -29442,8 +29442,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.N.equals``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29492,8 +29492,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.N.equal``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -29542,8 +29542,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableUInt64s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -29592,80 +29592,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.I.equals``() = validate (NullableUInt64s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.I.equal``() = validate (NullableUInt64s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.I.not_equal``() = validate (NullableUInt64s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.N.equals``() = validate (NullableUInt64s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.N.equal``() = validate (NullableUInt64s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ValueArray E.N.not_equal``() = validate (NullableUInt64s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.I.equals``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.I.equal``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.N.equals``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.N.equal``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableUInt64s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.I.equals``() = validate (NullableUInt64s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29673,8 +29673,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.I.equal``() = validate (NullableUInt64s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29682,8 +29682,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.I.not_equal``() = validate (NullableUInt64s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -29691,8 +29691,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.N.equals``() = validate (NullableUInt64s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29700,8 +29700,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.N.equal``() = validate (NullableUInt64s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29709,8 +29709,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ArrayArray E.N.not_equal``() = validate (NullableUInt64s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -29718,8 +29718,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.I.equals``() = validate (NullableUInt64s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29727,8 +29727,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.I.equal``() = validate (NullableUInt64s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29736,8 +29736,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.I.not_equal``() = validate (NullableUInt64s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -29745,8 +29745,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.N.equals``() = validate (NullableUInt64s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29754,8 +29754,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.N.equal``() = validate (NullableUInt64s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -29763,8 +29763,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUInt64s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableUInt64s.Collection.ListArray E.N.not_equal``() = validate (NullableUInt64s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -29772,392 +29772,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.I.equals``() = + [] + member _.``UNativeInts.Collection.Array C.I.equals``() = validate (UNativeInts.Collection.Array) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.I.equal``() = + [] + member _.``UNativeInts.Collection.Array C.I.equal``() = validate (UNativeInts.Collection.Array) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.Array C.I.not_equal``() = validate (UNativeInts.Collection.Array) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.I.compare``() = + [] + member _.``UNativeInts.Collection.Array C.I.compare``() = validate (UNativeInts.Collection.Array) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.I.less_than``() = + [] + member _.``UNativeInts.Collection.Array C.I.less_than``() = validate (UNativeInts.Collection.Array) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.Array C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.Array C.I.less_or_equal``() = validate (UNativeInts.Collection.Array) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.Array C.I.greater_than``() = validate (UNativeInts.Collection.Array) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.Array C.I.greater_or_equal``() = validate (UNativeInts.Collection.Array) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.Array C.N.equals``() = + [] + member _.``UNativeInts.Collection.Array C.N.equals``() = validate (UNativeInts.Collection.Array) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.N.equal``() = + [] + member _.``UNativeInts.Collection.Array C.N.equal``() = validate (UNativeInts.Collection.Array) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.Array C.N.not_equal``() = validate (UNativeInts.Collection.Array) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.N.compare``() = + [] + member _.``UNativeInts.Collection.Array C.N.compare``() = validate (UNativeInts.Collection.Array) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.N.less_than``() = + [] + member _.``UNativeInts.Collection.Array C.N.less_than``() = validate (UNativeInts.Collection.Array) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.Array C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.Array C.N.less_or_equal``() = validate (UNativeInts.Collection.Array) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.Array C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.Array C.N.greater_than``() = validate (UNativeInts.Collection.Array) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.Array C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.Array C.N.greater_or_equal``() = validate (UNativeInts.Collection.Array) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.equals``() = validate (UNativeInts.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.equal``() = validate (UNativeInts.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.not_equal``() = validate (UNativeInts.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.compare``() = validate (UNativeInts.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.less_than``() = validate (UNativeInts.Collection.OptionArray) C.I.less_than [| 0;1;1;1;0;0;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.less_or_equal``() = validate (UNativeInts.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.greater_than``() = validate (UNativeInts.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.equals``() = validate (UNativeInts.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.equal``() = validate (UNativeInts.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.not_equal``() = validate (UNativeInts.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.compare``() = validate (UNativeInts.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.less_than``() = validate (UNativeInts.Collection.OptionArray) C.N.less_than [| 0;1;1;1;0;0;1;1;0;0;0;1;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.less_or_equal``() = validate (UNativeInts.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.greater_than``() = validate (UNativeInts.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.OptionArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;0;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.equals``() = validate (UNativeInts.Collection.RefArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.equal``() = validate (UNativeInts.Collection.RefArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.not_equal``() = validate (UNativeInts.Collection.RefArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.compare``() = validate (UNativeInts.Collection.RefArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.less_than``() = validate (UNativeInts.Collection.RefArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.less_or_equal``() = validate (UNativeInts.Collection.RefArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.greater_than``() = validate (UNativeInts.Collection.RefArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.equals``() = validate (UNativeInts.Collection.RefArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.equal``() = validate (UNativeInts.Collection.RefArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.not_equal``() = validate (UNativeInts.Collection.RefArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.compare``() = validate (UNativeInts.Collection.RefArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.less_than``() = validate (UNativeInts.Collection.RefArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.less_or_equal``() = validate (UNativeInts.Collection.RefArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.greater_than``() = validate (UNativeInts.Collection.RefArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.RefArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.equals``() = validate (UNativeInts.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.equal``() = validate (UNativeInts.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.not_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.compare``() = validate (UNativeInts.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.less_than``() = validate (UNativeInts.Collection.RefWrapArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.less_or_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.greater_than``() = validate (UNativeInts.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.equals``() = validate (UNativeInts.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.equal``() = validate (UNativeInts.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.not_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.compare``() = validate (UNativeInts.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.less_than``() = validate (UNativeInts.Collection.RefWrapArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.less_or_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.greater_than``() = validate (UNativeInts.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.RefWrapArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.equals``() = validate (UNativeInts.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30173,8 +30173,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.equal``() = validate (UNativeInts.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30190,8 +30190,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.not_equal``() = validate (UNativeInts.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -30207,8 +30207,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.compare``() = validate (UNativeInts.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -30224,8 +30224,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.less_than``() = validate (UNativeInts.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30241,8 +30241,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.less_or_equal``() = validate (UNativeInts.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30258,8 +30258,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.greater_than``() = validate (UNativeInts.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30275,8 +30275,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30292,8 +30292,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.equals``() = validate (UNativeInts.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30309,8 +30309,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.equal``() = validate (UNativeInts.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30326,8 +30326,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.not_equal``() = validate (UNativeInts.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -30343,8 +30343,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.compare``() = validate (UNativeInts.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -30360,8 +30360,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.less_than``() = validate (UNativeInts.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30377,8 +30377,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.less_or_equal``() = validate (UNativeInts.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30394,8 +30394,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.greater_than``() = validate (UNativeInts.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30411,8 +30411,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30428,8 +30428,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.equals``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30445,8 +30445,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30462,8 +30462,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.not_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -30479,8 +30479,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.compare``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -30496,8 +30496,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.less_than``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30513,8 +30513,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.less_or_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30530,8 +30530,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.greater_than``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30547,8 +30547,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30564,8 +30564,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.equals``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30581,8 +30581,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -30598,8 +30598,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.not_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -30615,8 +30615,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.compare``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -30632,8 +30632,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.less_than``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30649,8 +30649,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.less_or_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -30666,8 +30666,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.greater_than``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30683,8 +30683,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``UNativeInts.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -30700,632 +30700,632 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.equals``() = validate (UNativeInts.Collection.ValueArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.equal``() = validate (UNativeInts.Collection.ValueArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.not_equal``() = validate (UNativeInts.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.compare``() = validate (UNativeInts.Collection.ValueArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.less_than``() = validate (UNativeInts.Collection.ValueArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.less_or_equal``() = validate (UNativeInts.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.greater_than``() = validate (UNativeInts.Collection.ValueArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.equals``() = validate (UNativeInts.Collection.ValueArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.equal``() = validate (UNativeInts.Collection.ValueArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.not_equal``() = validate (UNativeInts.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.compare``() = validate (UNativeInts.Collection.ValueArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.less_than``() = validate (UNativeInts.Collection.ValueArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.less_or_equal``() = validate (UNativeInts.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.greater_than``() = validate (UNativeInts.Collection.ValueArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.equals``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.not_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.compare``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.less_than``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.less_or_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.greater_than``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.equals``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.not_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.compare``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;1;0;-1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.less_than``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;0;0;1;0;0;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.less_or_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;0;1;1;0;0;1 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.greater_than``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;1;0;0;1;1;0 |] - [] - member __.``UNativeInts.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;0;1;1;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.equals``() = validate (UNativeInts.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.equal``() = validate (UNativeInts.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.not_equal``() = validate (UNativeInts.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.compare``() = validate (UNativeInts.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.less_than``() = validate (UNativeInts.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.less_or_equal``() = validate (UNativeInts.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.greater_than``() = validate (UNativeInts.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.equals``() = validate (UNativeInts.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.equal``() = validate (UNativeInts.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.not_equal``() = validate (UNativeInts.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.compare``() = validate (UNativeInts.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.less_than``() = validate (UNativeInts.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.less_or_equal``() = validate (UNativeInts.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.greater_than``() = validate (UNativeInts.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.equals``() = validate (UNativeInts.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.equal``() = validate (UNativeInts.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.not_equal``() = validate (UNativeInts.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.compare``() = validate (UNativeInts.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;-1;1;1;0;1;1;-1;1;-1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.less_than``() = validate (UNativeInts.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.less_or_equal``() = validate (UNativeInts.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.greater_than``() = validate (UNativeInts.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.equals``() = validate (UNativeInts.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.equal``() = validate (UNativeInts.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.not_equal``() = validate (UNativeInts.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.compare``() = validate (UNativeInts.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;-1;1;1;0;1;1;-1;1;-1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.less_than``() = validate (UNativeInts.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.less_or_equal``() = validate (UNativeInts.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.greater_than``() = validate (UNativeInts.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ListArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;1;1;-1;1;0;1;1;-1;-1;1;-1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;0;1;0;0;0;0;0;0;0;0;1;1;0;1;1;0;0;1;0;0;0;0;1;1;0;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;0;0;1;1;0;1;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;1;1;0;0;1;0;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;1;1;1;1;1;1;1;1;0;0;1;0;0;1;1;0;1;1;1;1;0;0;1;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;1;-1;1;1;1;0;1;1;1;1;-1;-1;0;-1;-1;1;1;-1;1;0;1;1;-1;-1;1;-1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;0;1;0;0;0;0;0;0;0;0;1;1;0;1;1;0;0;1;0;0;0;0;1;1;0;1;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;0;1;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;0;1;0;0;1;1;0;1;1 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;1;0;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;1;0;1;1;0;0;1;0;0 |] - [] - member __.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (UNativeInts.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;1;0;1;1;1;1;1;1;1;1;0;0;1;0;0;1;1;0;1;1;1;1;0;0;1;0;1 |] - [] - member __.``NullableUNativeInts.Collection.Array E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.Array E.I.equals``() = validate (NullableUNativeInts.Collection.Array) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.Array E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.Array E.I.equal``() = validate (NullableUNativeInts.Collection.Array) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.Array E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.Array E.I.not_equal``() = validate (NullableUNativeInts.Collection.Array) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.Array E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.Array E.N.equals``() = validate (NullableUNativeInts.Collection.Array) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.Array E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.Array E.N.equal``() = validate (NullableUNativeInts.Collection.Array) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.Array E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.Array E.N.not_equal``() = validate (NullableUNativeInts.Collection.Array) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.I.equals``() = validate (NullableUNativeInts.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.I.equal``() = validate (NullableUNativeInts.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.N.equals``() = validate (NullableUNativeInts.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.N.equal``() = validate (NullableUNativeInts.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.OptionArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.I.equals``() = validate (NullableUNativeInts.Collection.RefArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.I.equal``() = validate (NullableUNativeInts.Collection.RefArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.N.equals``() = validate (NullableUNativeInts.Collection.RefArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.N.equal``() = validate (NullableUNativeInts.Collection.RefArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.RefArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.I.equals``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.I.equal``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.N.equals``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.N.equal``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.RefWrapArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.I.equals``() = validate (NullableUNativeInts.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31349,8 +31349,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.I.equal``() = validate (NullableUNativeInts.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31374,8 +31374,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -31399,8 +31399,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.N.equals``() = validate (NullableUNativeInts.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31424,8 +31424,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.N.equal``() = validate (NullableUNativeInts.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31449,8 +31449,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -31474,8 +31474,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.I.equals``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31499,8 +31499,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.I.equal``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31524,8 +31524,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -31549,8 +31549,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.N.equals``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31574,8 +31574,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.N.equal``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -31599,8 +31599,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -31624,548 +31624,548 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.I.equals``() = validate (NullableUNativeInts.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.I.equal``() = validate (NullableUNativeInts.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.N.equals``() = validate (NullableUNativeInts.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.N.equal``() = validate (NullableUNativeInts.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.I.equals``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.I.equal``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.N.equals``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.N.equal``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.I.equals``() = validate (NullableUNativeInts.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.I.equal``() = validate (NullableUNativeInts.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.N.equals``() = validate (NullableUNativeInts.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.N.equal``() = validate (NullableUNativeInts.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ArrayArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.I.equals``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.I.equals``() = validate (NullableUNativeInts.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.I.equal``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.I.equal``() = validate (NullableUNativeInts.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.I.not_equal``() = validate (NullableUNativeInts.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.N.equals``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.N.equals``() = validate (NullableUNativeInts.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.N.equal``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.N.equal``() = validate (NullableUNativeInts.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableUNativeInts.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableUNativeInts.Collection.ListArray E.N.not_equal``() = validate (NullableUNativeInts.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.Array C.I.equals``() = + [] + member _.``Chars.Collection.Array C.I.equals``() = validate (Chars.Collection.Array) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.Array C.I.equal``() = + [] + member _.``Chars.Collection.Array C.I.equal``() = validate (Chars.Collection.Array) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.Array C.I.not_equal``() = + [] + member _.``Chars.Collection.Array C.I.not_equal``() = validate (Chars.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.Array C.I.compare``() = + [] + member _.``Chars.Collection.Array C.I.compare``() = validate (Chars.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.Array C.I.less_than``() = + [] + member _.``Chars.Collection.Array C.I.less_than``() = validate (Chars.Collection.Array) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.Array C.I.less_or_equal``() = + [] + member _.``Chars.Collection.Array C.I.less_or_equal``() = validate (Chars.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.Array C.I.greater_than``() = + [] + member _.``Chars.Collection.Array C.I.greater_than``() = validate (Chars.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.Array C.I.greater_or_equal``() = validate (Chars.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.Array C.N.equals``() = + [] + member _.``Chars.Collection.Array C.N.equals``() = validate (Chars.Collection.Array) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.Array C.N.equal``() = + [] + member _.``Chars.Collection.Array C.N.equal``() = validate (Chars.Collection.Array) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.Array C.N.not_equal``() = + [] + member _.``Chars.Collection.Array C.N.not_equal``() = validate (Chars.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.Array C.N.compare``() = + [] + member _.``Chars.Collection.Array C.N.compare``() = validate (Chars.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.Array C.N.less_than``() = + [] + member _.``Chars.Collection.Array C.N.less_than``() = validate (Chars.Collection.Array) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.Array C.N.less_or_equal``() = + [] + member _.``Chars.Collection.Array C.N.less_or_equal``() = validate (Chars.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.Array C.N.greater_than``() = + [] + member _.``Chars.Collection.Array C.N.greater_than``() = validate (Chars.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.Array C.N.greater_or_equal``() = validate (Chars.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.OptionArray C.I.equals``() = + [] + member _.``Chars.Collection.OptionArray C.I.equals``() = validate (Chars.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.I.equal``() = + [] + member _.``Chars.Collection.OptionArray C.I.equal``() = validate (Chars.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Chars.Collection.OptionArray C.I.not_equal``() = validate (Chars.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.I.compare``() = + [] + member _.``Chars.Collection.OptionArray C.I.compare``() = validate (Chars.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-65535;-48;-49;-50;1;65535;0;65487;65486;65485;1;48;-65487;0;-1;-2;1;49;-65486;1;0;-1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.I.less_than``() = + [] + member _.``Chars.Collection.OptionArray C.I.less_than``() = validate (Chars.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.OptionArray C.I.less_or_equal``() = validate (Chars.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Chars.Collection.OptionArray C.I.greater_than``() = validate (Chars.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.OptionArray C.I.greater_or_equal``() = validate (Chars.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.OptionArray C.N.equals``() = + [] + member _.``Chars.Collection.OptionArray C.N.equals``() = validate (Chars.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.N.equal``() = + [] + member _.``Chars.Collection.OptionArray C.N.equal``() = validate (Chars.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Chars.Collection.OptionArray C.N.not_equal``() = validate (Chars.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.N.compare``() = + [] + member _.``Chars.Collection.OptionArray C.N.compare``() = validate (Chars.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-65535;-48;-49;-50;1;65535;0;65487;65486;65485;1;48;-65487;0;-1;-2;1;49;-65486;1;0;-1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.N.less_than``() = + [] + member _.``Chars.Collection.OptionArray C.N.less_than``() = validate (Chars.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.OptionArray C.N.less_or_equal``() = validate (Chars.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Chars.Collection.OptionArray C.N.greater_than``() = validate (Chars.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.OptionArray C.N.greater_or_equal``() = validate (Chars.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.RefArray C.I.equals``() = + [] + member _.``Chars.Collection.RefArray C.I.equals``() = validate (Chars.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.I.equal``() = + [] + member _.``Chars.Collection.RefArray C.I.equal``() = validate (Chars.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.I.not_equal``() = + [] + member _.``Chars.Collection.RefArray C.I.not_equal``() = validate (Chars.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.I.compare``() = + [] + member _.``Chars.Collection.RefArray C.I.compare``() = validate (Chars.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.I.less_than``() = + [] + member _.``Chars.Collection.RefArray C.I.less_than``() = validate (Chars.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.RefArray C.I.less_or_equal``() = validate (Chars.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.I.greater_than``() = + [] + member _.``Chars.Collection.RefArray C.I.greater_than``() = validate (Chars.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.RefArray C.I.greater_or_equal``() = validate (Chars.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.RefArray C.N.equals``() = + [] + member _.``Chars.Collection.RefArray C.N.equals``() = validate (Chars.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.N.equal``() = + [] + member _.``Chars.Collection.RefArray C.N.equal``() = validate (Chars.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.N.not_equal``() = + [] + member _.``Chars.Collection.RefArray C.N.not_equal``() = validate (Chars.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.N.compare``() = + [] + member _.``Chars.Collection.RefArray C.N.compare``() = validate (Chars.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.N.less_than``() = + [] + member _.``Chars.Collection.RefArray C.N.less_than``() = validate (Chars.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.RefArray C.N.less_or_equal``() = validate (Chars.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.RefArray C.N.greater_than``() = + [] + member _.``Chars.Collection.RefArray C.N.greater_than``() = validate (Chars.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.RefArray C.N.greater_or_equal``() = validate (Chars.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.equals``() = validate (Chars.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.equal``() = validate (Chars.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.not_equal``() = validate (Chars.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.compare``() = validate (Chars.Collection.RefWrapArray) C.I.compare [| 0;-65535;-48;-49;-50;65535;0;65487;65486;65485;48;-65487;0;-1;-2;49;-65486;1;0;-1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.less_than``() = validate (Chars.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.less_or_equal``() = validate (Chars.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.greater_than``() = validate (Chars.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Chars.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.equals``() = validate (Chars.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.equal``() = validate (Chars.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.not_equal``() = validate (Chars.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.compare``() = validate (Chars.Collection.RefWrapArray) C.N.compare [| 0;-65535;-48;-49;-50;65535;0;65487;65486;65485;48;-65487;0;-1;-2;49;-65486;1;0;-1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.less_than``() = validate (Chars.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.less_or_equal``() = validate (Chars.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.greater_than``() = validate (Chars.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Chars.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.UnionArray C.I.equals``() = + [] + member _.``Chars.Collection.UnionArray C.I.equals``() = validate (Chars.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32200,8 +32200,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.I.equal``() = + [] + member _.``Chars.Collection.UnionArray C.I.equal``() = validate (Chars.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32236,8 +32236,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Chars.Collection.UnionArray C.I.not_equal``() = validate (Chars.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -32272,8 +32272,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.I.compare``() = + [] + member _.``Chars.Collection.UnionArray C.I.compare``() = validate (Chars.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -32308,8 +32308,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.I.less_than``() = + [] + member _.``Chars.Collection.UnionArray C.I.less_than``() = validate (Chars.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -32344,8 +32344,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.UnionArray C.I.less_or_equal``() = validate (Chars.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -32380,8 +32380,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Chars.Collection.UnionArray C.I.greater_than``() = validate (Chars.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -32416,8 +32416,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.UnionArray C.I.greater_or_equal``() = validate (Chars.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -32452,8 +32452,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.UnionArray C.N.equals``() = + [] + member _.``Chars.Collection.UnionArray C.N.equals``() = validate (Chars.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32488,8 +32488,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.N.equal``() = + [] + member _.``Chars.Collection.UnionArray C.N.equal``() = validate (Chars.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32524,8 +32524,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Chars.Collection.UnionArray C.N.not_equal``() = validate (Chars.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -32560,8 +32560,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.N.compare``() = + [] + member _.``Chars.Collection.UnionArray C.N.compare``() = validate (Chars.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -32596,8 +32596,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.N.less_than``() = + [] + member _.``Chars.Collection.UnionArray C.N.less_than``() = validate (Chars.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -32632,8 +32632,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.UnionArray C.N.less_or_equal``() = validate (Chars.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -32668,8 +32668,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Chars.Collection.UnionArray C.N.greater_than``() = validate (Chars.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -32704,8 +32704,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.UnionArray C.N.greater_or_equal``() = validate (Chars.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -32740,8 +32740,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.equals``() = validate (Chars.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32776,8 +32776,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.equal``() = validate (Chars.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -32812,8 +32812,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.not_equal``() = validate (Chars.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -32848,8 +32848,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.compare``() = validate (Chars.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-65535;-1;-2;-3;-3;-3;-3;-48;-1;-2;-3;-3;-3;-3;-49;-1;-2;-3;-3;-3;-3;-50;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-65535;-1;-2;-2;-2;-2;1;-48;-1;-2;-2;-2;-2;1;-49;-1;-2;-2;-2;-2;1;-50;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-65535; @@ -32884,8 +32884,8 @@ type GeneratedTestSuite () = 3;2;1;-65485;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.less_than``() = validate (Chars.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -32920,8 +32920,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Chars.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -32956,8 +32956,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.greater_than``() = validate (Chars.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -32992,8 +32992,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Chars.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -33028,8 +33028,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.equals``() = validate (Chars.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -33064,8 +33064,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.equal``() = validate (Chars.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -33100,8 +33100,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.not_equal``() = validate (Chars.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -33136,8 +33136,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.compare``() = validate (Chars.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-65535;-1;-2;-3;-3;-3;-3;-48;-1;-2;-3;-3;-3;-3;-49;-1;-2;-3;-3;-3;-3;-50;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-65535;-1;-2;-2;-2;-2;1;-48;-1;-2;-2;-2;-2;1;-49;-1;-2;-2;-2;-2;1;-50;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-65535; @@ -33172,8 +33172,8 @@ type GeneratedTestSuite () = 3;2;1;-65485;3;2;1;3;2;1;2;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.less_than``() = validate (Chars.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -33208,8 +33208,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Chars.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -33244,8 +33244,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.greater_than``() = validate (Chars.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -33280,8 +33280,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Chars.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -33316,734 +33316,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.ValueArray C.I.equals``() = + [] + member _.``Chars.Collection.ValueArray C.I.equals``() = validate (Chars.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.I.equal``() = + [] + member _.``Chars.Collection.ValueArray C.I.equal``() = validate (Chars.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Chars.Collection.ValueArray C.I.not_equal``() = validate (Chars.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.I.compare``() = + [] + member _.``Chars.Collection.ValueArray C.I.compare``() = validate (Chars.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.I.less_than``() = + [] + member _.``Chars.Collection.ValueArray C.I.less_than``() = validate (Chars.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.ValueArray C.I.less_or_equal``() = validate (Chars.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Chars.Collection.ValueArray C.I.greater_than``() = validate (Chars.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.ValueArray C.I.greater_or_equal``() = validate (Chars.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ValueArray C.N.equals``() = + [] + member _.``Chars.Collection.ValueArray C.N.equals``() = validate (Chars.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.N.equal``() = + [] + member _.``Chars.Collection.ValueArray C.N.equal``() = validate (Chars.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Chars.Collection.ValueArray C.N.not_equal``() = validate (Chars.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.N.compare``() = + [] + member _.``Chars.Collection.ValueArray C.N.compare``() = validate (Chars.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.N.less_than``() = + [] + member _.``Chars.Collection.ValueArray C.N.less_than``() = validate (Chars.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.ValueArray C.N.less_or_equal``() = validate (Chars.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Chars.Collection.ValueArray C.N.greater_than``() = validate (Chars.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.ValueArray C.N.greater_or_equal``() = validate (Chars.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.equals``() = validate (Chars.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.equal``() = validate (Chars.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.not_equal``() = validate (Chars.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.compare``() = validate (Chars.Collection.ValueWrapArray) C.I.compare [| 0;-65535;-48;-49;-50;65535;0;65487;65486;65485;48;-65487;0;-1;-2;49;-65486;1;0;-1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.less_than``() = validate (Chars.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Chars.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.greater_than``() = validate (Chars.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Chars.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.equals``() = validate (Chars.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.equal``() = validate (Chars.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.not_equal``() = validate (Chars.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.compare``() = validate (Chars.Collection.ValueWrapArray) C.N.compare [| 0;-65535;-48;-49;-50;65535;0;65487;65486;65485;48;-65487;0;-1;-2;49;-65486;1;0;-1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.less_than``() = validate (Chars.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Chars.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.greater_than``() = validate (Chars.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Chars.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ArrayArray C.I.equals``() = + [] + member _.``Chars.Collection.ArrayArray C.I.equals``() = validate (Chars.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.I.equal``() = + [] + member _.``Chars.Collection.ArrayArray C.I.equal``() = validate (Chars.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.I.not_equal``() = validate (Chars.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.I.compare``() = + [] + member _.``Chars.Collection.ArrayArray C.I.compare``() = validate (Chars.Collection.ArrayArray) C.I.compare [| 0;-65535;-48;-49;-50;-1;-1;-1;-1;-1;65535;0;65487;65486;65485;-1;-1;-1;-1;-1;48;-65487;0;-1;-2;-1;-1;-1;-1;-1;49;-65486;1;0;-1;-1;-1;-1;-1;-1; 50;-65485;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-65535;-48;-49;-50;1;1;1;1;1;65535;0;65487;65486;65485;1;1;1;1;1;48;-65487;0;-1;-2; 1;1;1;1;1;49;-65486;1;0;-1;1;1;1;1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Chars.Collection.ArrayArray C.I.less_than``() = validate (Chars.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.I.less_or_equal``() = validate (Chars.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Chars.Collection.ArrayArray C.I.greater_than``() = validate (Chars.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.I.greater_or_equal``() = validate (Chars.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ArrayArray C.N.equals``() = + [] + member _.``Chars.Collection.ArrayArray C.N.equals``() = validate (Chars.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.N.equal``() = + [] + member _.``Chars.Collection.ArrayArray C.N.equal``() = validate (Chars.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.N.not_equal``() = validate (Chars.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.N.compare``() = + [] + member _.``Chars.Collection.ArrayArray C.N.compare``() = validate (Chars.Collection.ArrayArray) C.N.compare [| 0;-65535;-48;-49;-50;-1;-1;-1;-1;-1;65535;0;65487;65486;65485;-1;-1;-1;-1;-1;48;-65487;0;-1;-2;-1;-1;-1;-1;-1;49;-65486;1;0;-1;-1;-1;-1;-1;-1; 50;-65485;2;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-65535;-48;-49;-50;1;1;1;1;1;65535;0;65487;65486;65485;1;1;1;1;1;48;-65487;0;-1;-2; 1;1;1;1;1;49;-65486;1;0;-1;1;1;1;1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Chars.Collection.ArrayArray C.N.less_than``() = validate (Chars.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.N.less_or_equal``() = validate (Chars.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Chars.Collection.ArrayArray C.N.greater_than``() = validate (Chars.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray C.N.greater_or_equal``() = validate (Chars.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ListArray C.I.equals``() = + [] + member _.``Chars.Collection.ListArray C.I.equals``() = validate (Chars.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.I.equal``() = + [] + member _.``Chars.Collection.ListArray C.I.equal``() = validate (Chars.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.I.not_equal``() = + [] + member _.``Chars.Collection.ListArray C.I.not_equal``() = validate (Chars.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ListArray C.I.compare``() = + [] + member _.``Chars.Collection.ListArray C.I.compare``() = validate (Chars.Collection.ListArray) C.I.compare [| 0;-65535;-48;-49;-50;-1;-65535;-48;-49;-50;65535;0;65487;65486;65485;65535;-1;65487;65486;65485;48;-65487;0;-1;-2;48;-65487;-1;-1;-2;49;-65486;1;0;-1;49;-65486;1;-1;-1; 50;-65485;2;1;0;50;-65485;2;1;-1;1;-65535;-48;-49;-50;0;-65535;-48;-49;-50;65535;1;65487;65486;65485;65535;0;65487;65486;65485;48;-65487;1;-1;-2;48;-65487;0;-1;-2; 49;-65486;1;1;-1;49;-65486;1;0;-1;50;-65485;2;1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ListArray C.I.less_than``() = + [] + member _.``Chars.Collection.ListArray C.I.less_than``() = validate (Chars.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.ListArray C.I.less_or_equal``() = validate (Chars.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.I.greater_than``() = + [] + member _.``Chars.Collection.ListArray C.I.greater_than``() = validate (Chars.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.ListArray C.I.greater_or_equal``() = validate (Chars.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ListArray C.N.equals``() = + [] + member _.``Chars.Collection.ListArray C.N.equals``() = validate (Chars.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.N.equal``() = + [] + member _.``Chars.Collection.ListArray C.N.equal``() = validate (Chars.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.N.not_equal``() = + [] + member _.``Chars.Collection.ListArray C.N.not_equal``() = validate (Chars.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ListArray C.N.compare``() = + [] + member _.``Chars.Collection.ListArray C.N.compare``() = validate (Chars.Collection.ListArray) C.N.compare [| 0;-65535;-48;-49;-50;-1;-65535;-48;-49;-50;65535;0;65487;65486;65485;65535;-1;65487;65486;65485;48;-65487;0;-1;-2;48;-65487;-1;-1;-2;49;-65486;1;0;-1;49;-65486;1;-1;-1; 50;-65485;2;1;0;50;-65485;2;1;-1;1;-65535;-48;-49;-50;0;-65535;-48;-49;-50;65535;1;65487;65486;65485;65535;0;65487;65486;65485;48;-65487;1;-1;-2;48;-65487;0;-1;-2; 49;-65486;1;1;-1;49;-65486;1;0;-1;50;-65485;2;1;1;50;-65485;2;1;0 |] - [] - member __.``Chars.Collection.ListArray C.N.less_than``() = + [] + member _.``Chars.Collection.ListArray C.N.less_than``() = validate (Chars.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Chars.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.ListArray C.N.less_or_equal``() = validate (Chars.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Chars.Collection.ListArray C.N.greater_than``() = + [] + member _.``Chars.Collection.ListArray C.N.greater_than``() = validate (Chars.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Chars.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.ListArray C.N.greater_or_equal``() = validate (Chars.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Chars.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Chars.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.Array E.I.equals``() = + [] + member _.``NullableChars.Collection.Array E.I.equals``() = validate (NullableChars.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.Array E.I.equal``() = + [] + member _.``NullableChars.Collection.Array E.I.equal``() = validate (NullableChars.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.Array E.I.not_equal``() = + [] + member _.``NullableChars.Collection.Array E.I.not_equal``() = validate (NullableChars.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.Array E.N.equals``() = + [] + member _.``NullableChars.Collection.Array E.N.equals``() = validate (NullableChars.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.Array E.N.equal``() = + [] + member _.``NullableChars.Collection.Array E.N.equal``() = validate (NullableChars.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.Array E.N.not_equal``() = + [] + member _.``NullableChars.Collection.Array E.N.not_equal``() = validate (NullableChars.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableChars.Collection.OptionArray E.I.equals``() = validate (NullableChars.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableChars.Collection.OptionArray E.I.equal``() = validate (NullableChars.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.OptionArray E.I.not_equal``() = validate (NullableChars.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableChars.Collection.OptionArray E.N.equals``() = validate (NullableChars.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableChars.Collection.OptionArray E.N.equal``() = validate (NullableChars.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.OptionArray E.N.not_equal``() = validate (NullableChars.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.RefArray E.I.equals``() = + [] + member _.``NullableChars.Collection.RefArray E.I.equals``() = validate (NullableChars.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefArray E.I.equal``() = + [] + member _.``NullableChars.Collection.RefArray E.I.equal``() = validate (NullableChars.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.RefArray E.I.not_equal``() = validate (NullableChars.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.RefArray E.N.equals``() = + [] + member _.``NullableChars.Collection.RefArray E.N.equals``() = validate (NullableChars.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefArray E.N.equal``() = + [] + member _.``NullableChars.Collection.RefArray E.N.equal``() = validate (NullableChars.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.RefArray E.N.not_equal``() = validate (NullableChars.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.I.equals``() = validate (NullableChars.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.I.equal``() = validate (NullableChars.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.I.not_equal``() = validate (NullableChars.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.N.equals``() = validate (NullableChars.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.N.equal``() = validate (NullableChars.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.RefWrapArray E.N.not_equal``() = validate (NullableChars.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableChars.Collection.UnionArray E.I.equals``() = validate (NullableChars.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34092,8 +34092,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableChars.Collection.UnionArray E.I.equal``() = validate (NullableChars.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34142,8 +34142,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.UnionArray E.I.not_equal``() = validate (NullableChars.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -34192,8 +34192,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableChars.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableChars.Collection.UnionArray E.N.equals``() = validate (NullableChars.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34242,8 +34242,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableChars.Collection.UnionArray E.N.equal``() = validate (NullableChars.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34292,8 +34292,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.UnionArray E.N.not_equal``() = validate (NullableChars.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -34342,8 +34342,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.I.equals``() = validate (NullableChars.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34392,8 +34392,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.I.equal``() = validate (NullableChars.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34442,8 +34442,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableChars.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -34492,8 +34492,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.N.equals``() = validate (NullableChars.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34542,8 +34542,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.N.equal``() = validate (NullableChars.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -34592,8 +34592,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableChars.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableChars.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -34642,80 +34642,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableChars.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableChars.Collection.ValueArray E.I.equals``() = validate (NullableChars.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableChars.Collection.ValueArray E.I.equal``() = validate (NullableChars.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.ValueArray E.I.not_equal``() = validate (NullableChars.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableChars.Collection.ValueArray E.N.equals``() = validate (NullableChars.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableChars.Collection.ValueArray E.N.equal``() = validate (NullableChars.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.ValueArray E.N.not_equal``() = validate (NullableChars.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.I.equals``() = validate (NullableChars.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.I.equal``() = validate (NullableChars.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableChars.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.N.equals``() = validate (NullableChars.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.N.equal``() = validate (NullableChars.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableChars.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableChars.Collection.ArrayArray E.I.equals``() = validate (NullableChars.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34723,8 +34723,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableChars.Collection.ArrayArray E.I.equal``() = validate (NullableChars.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34732,8 +34732,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.ArrayArray E.I.not_equal``() = validate (NullableChars.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -34741,8 +34741,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableChars.Collection.ArrayArray E.N.equals``() = validate (NullableChars.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34750,8 +34750,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableChars.Collection.ArrayArray E.N.equal``() = validate (NullableChars.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34759,8 +34759,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.ArrayArray E.N.not_equal``() = validate (NullableChars.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -34768,8 +34768,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ListArray E.I.equals``() = + [] + member _.``NullableChars.Collection.ListArray E.I.equals``() = validate (NullableChars.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34777,8 +34777,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ListArray E.I.equal``() = + [] + member _.``NullableChars.Collection.ListArray E.I.equal``() = validate (NullableChars.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34786,8 +34786,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableChars.Collection.ListArray E.I.not_equal``() = validate (NullableChars.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -34795,8 +34795,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableChars.Collection.ListArray E.N.equals``() = + [] + member _.``NullableChars.Collection.ListArray E.N.equals``() = validate (NullableChars.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34804,8 +34804,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ListArray E.N.equal``() = + [] + member _.``NullableChars.Collection.ListArray E.N.equal``() = validate (NullableChars.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -34813,8 +34813,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableChars.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableChars.Collection.ListArray E.N.not_equal``() = validate (NullableChars.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -34822,408 +34822,408 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.Array C.I.equals``() = + [] + member _.``Strings.Collection.Array C.I.equals``() = validate (Strings.Collection.Array) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.I.equal``() = + [] + member _.``Strings.Collection.Array C.I.equal``() = validate (Strings.Collection.Array) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.I.not_equal``() = + [] + member _.``Strings.Collection.Array C.I.not_equal``() = validate (Strings.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.Array C.I.compare``() = + [] + member _.``Strings.Collection.Array C.I.compare``() = validate (Strings.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.Array C.I.less_than``() = + [] + member _.``Strings.Collection.Array C.I.less_than``() = validate (Strings.Collection.Array) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.Array C.I.less_or_equal``() = + [] + member _.``Strings.Collection.Array C.I.less_or_equal``() = validate (Strings.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.I.greater_than``() = + [] + member _.``Strings.Collection.Array C.I.greater_than``() = validate (Strings.Collection.Array) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.Array C.I.greater_or_equal``() = validate (Strings.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.Array C.N.equals``() = + [] + member _.``Strings.Collection.Array C.N.equals``() = validate (Strings.Collection.Array) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.N.equal``() = + [] + member _.``Strings.Collection.Array C.N.equal``() = validate (Strings.Collection.Array) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.N.not_equal``() = + [] + member _.``Strings.Collection.Array C.N.not_equal``() = validate (Strings.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.Array C.N.compare``() = + [] + member _.``Strings.Collection.Array C.N.compare``() = validate (Strings.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.Array C.N.less_than``() = + [] + member _.``Strings.Collection.Array C.N.less_than``() = validate (Strings.Collection.Array) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.Array C.N.less_or_equal``() = + [] + member _.``Strings.Collection.Array C.N.less_or_equal``() = validate (Strings.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.Array C.N.greater_than``() = + [] + member _.``Strings.Collection.Array C.N.greater_than``() = validate (Strings.Collection.Array) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.Array C.N.greater_or_equal``() = validate (Strings.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.OptionArray C.I.equals``() = + [] + member _.``Strings.Collection.OptionArray C.I.equals``() = validate (Strings.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.I.equal``() = + [] + member _.``Strings.Collection.OptionArray C.I.equal``() = validate (Strings.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Strings.Collection.OptionArray C.I.not_equal``() = validate (Strings.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.OptionArray C.I.compare``() = + [] + member _.``Strings.Collection.OptionArray C.I.compare``() = validate (Strings.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;1;1;0;-72;-3;-97;-229;1;1;72;0;72;-25;-157;1;1;3;-72;0;-97;-229;1;1;97;25;97; 0;-132;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.OptionArray C.I.less_than``() = + [] + member _.``Strings.Collection.OptionArray C.I.less_than``() = validate (Strings.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;1;0;0;0;1;0;1;1;0;0;0;0;0; 0;1;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.OptionArray C.I.less_or_equal``() = validate (Strings.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;0;1;1;0;0;0;1;1;1;1;0;0;0;0;0; 1;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Strings.Collection.OptionArray C.I.greater_than``() = validate (Strings.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;1;0;0;1;1;1;0;0;0;0;1;1;1;1;1; 0;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.OptionArray C.I.greater_or_equal``() = validate (Strings.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;0;1;1;1;0;1;0;0;1;1;1;1;1; 1;0;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.OptionArray C.N.equals``() = + [] + member _.``Strings.Collection.OptionArray C.N.equals``() = validate (Strings.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.N.equal``() = + [] + member _.``Strings.Collection.OptionArray C.N.equal``() = validate (Strings.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Strings.Collection.OptionArray C.N.not_equal``() = validate (Strings.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.OptionArray C.N.compare``() = + [] + member _.``Strings.Collection.OptionArray C.N.compare``() = validate (Strings.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;1;1;0;-72;-3;-97;-229;1;1;72;0;72;-25;-157;1;1;3;-72;0;-97;-229;1;1;97;25;97; 0;-132;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.OptionArray C.N.less_than``() = + [] + member _.``Strings.Collection.OptionArray C.N.less_than``() = validate (Strings.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;1;0;0;0;1;0;1;1;0;0;0;0;0; 0;1;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.OptionArray C.N.less_or_equal``() = validate (Strings.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;0;1;1;0;0;0;1;1;1;1;0;0;0;0;0; 1;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Strings.Collection.OptionArray C.N.greater_than``() = validate (Strings.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;1;0;0;1;1;1;0;0;0;0;1;1;1;1;1; 0;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.OptionArray C.N.greater_or_equal``() = validate (Strings.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;0;1;1;1;0;1;0;0;1;1;1;1;1; 1;0;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.RefArray C.I.equals``() = + [] + member _.``Strings.Collection.RefArray C.I.equals``() = validate (Strings.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.I.equal``() = + [] + member _.``Strings.Collection.RefArray C.I.equal``() = validate (Strings.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.I.not_equal``() = + [] + member _.``Strings.Collection.RefArray C.I.not_equal``() = validate (Strings.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefArray C.I.compare``() = + [] + member _.``Strings.Collection.RefArray C.I.compare``() = validate (Strings.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.RefArray C.I.less_than``() = + [] + member _.``Strings.Collection.RefArray C.I.less_than``() = validate (Strings.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.RefArray C.I.less_or_equal``() = validate (Strings.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.I.greater_than``() = + [] + member _.``Strings.Collection.RefArray C.I.greater_than``() = validate (Strings.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.RefArray C.I.greater_or_equal``() = validate (Strings.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.RefArray C.N.equals``() = + [] + member _.``Strings.Collection.RefArray C.N.equals``() = validate (Strings.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.N.equal``() = + [] + member _.``Strings.Collection.RefArray C.N.equal``() = validate (Strings.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.N.not_equal``() = + [] + member _.``Strings.Collection.RefArray C.N.not_equal``() = validate (Strings.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefArray C.N.compare``() = + [] + member _.``Strings.Collection.RefArray C.N.compare``() = validate (Strings.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.RefArray C.N.less_than``() = + [] + member _.``Strings.Collection.RefArray C.N.less_than``() = validate (Strings.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.RefArray C.N.less_or_equal``() = validate (Strings.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefArray C.N.greater_than``() = + [] + member _.``Strings.Collection.RefArray C.N.greater_than``() = validate (Strings.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.RefArray C.N.greater_or_equal``() = validate (Strings.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.equals``() = validate (Strings.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.equal``() = validate (Strings.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.not_equal``() = validate (Strings.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.compare``() = validate (Strings.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.less_than``() = validate (Strings.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.less_or_equal``() = validate (Strings.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.greater_than``() = validate (Strings.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Strings.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.equals``() = validate (Strings.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.equal``() = validate (Strings.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.not_equal``() = validate (Strings.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.compare``() = validate (Strings.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.less_than``() = validate (Strings.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.less_or_equal``() = validate (Strings.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.greater_than``() = validate (Strings.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Strings.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.UnionArray C.I.equals``() = + [] + member _.``Strings.Collection.UnionArray C.I.equals``() = validate (Strings.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -35272,8 +35272,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.I.equal``() = + [] + member _.``Strings.Collection.UnionArray C.I.equal``() = validate (Strings.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -35322,8 +35322,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Strings.Collection.UnionArray C.I.not_equal``() = validate (Strings.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -35372,8 +35372,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.I.compare``() = + [] + member _.``Strings.Collection.UnionArray C.I.compare``() = validate (Strings.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -35422,8 +35422,8 @@ type GeneratedTestSuite () = 3;2;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.I.less_than``() = + [] + member _.``Strings.Collection.UnionArray C.I.less_than``() = validate (Strings.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -35472,8 +35472,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Strings.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.UnionArray C.I.less_or_equal``() = validate (Strings.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -35522,8 +35522,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Strings.Collection.UnionArray C.I.greater_than``() = validate (Strings.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -35572,8 +35572,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.UnionArray C.I.greater_or_equal``() = validate (Strings.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -35622,8 +35622,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Strings.Collection.UnionArray C.N.equals``() = + [] + member _.``Strings.Collection.UnionArray C.N.equals``() = validate (Strings.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -35672,8 +35672,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.N.equal``() = + [] + member _.``Strings.Collection.UnionArray C.N.equal``() = validate (Strings.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -35722,8 +35722,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Strings.Collection.UnionArray C.N.not_equal``() = validate (Strings.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -35772,8 +35772,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.N.compare``() = + [] + member _.``Strings.Collection.UnionArray C.N.compare``() = validate (Strings.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -35822,8 +35822,8 @@ type GeneratedTestSuite () = 3;2;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.N.less_than``() = + [] + member _.``Strings.Collection.UnionArray C.N.less_than``() = validate (Strings.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -35872,8 +35872,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Strings.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.UnionArray C.N.less_or_equal``() = validate (Strings.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -35922,8 +35922,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Strings.Collection.UnionArray C.N.greater_than``() = validate (Strings.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -35972,8 +35972,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.UnionArray C.N.greater_or_equal``() = validate (Strings.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -36022,8 +36022,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.equals``() = validate (Strings.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -36072,8 +36072,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.equal``() = validate (Strings.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -36122,8 +36122,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.not_equal``() = validate (Strings.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -36172,8 +36172,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.compare``() = validate (Strings.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -36222,8 +36222,8 @@ type GeneratedTestSuite () = 3;2;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.less_than``() = validate (Strings.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -36272,8 +36272,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Strings.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -36322,8 +36322,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.greater_than``() = validate (Strings.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -36372,8 +36372,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Strings.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -36422,8 +36422,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.equals``() = validate (Strings.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -36472,8 +36472,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.equal``() = validate (Strings.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -36522,8 +36522,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.not_equal``() = validate (Strings.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -36572,8 +36572,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.compare``() = validate (Strings.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -36622,8 +36622,8 @@ type GeneratedTestSuite () = 3;2;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.less_than``() = validate (Strings.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -36672,8 +36672,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Strings.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -36722,8 +36722,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.greater_than``() = validate (Strings.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -36772,8 +36772,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Strings.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Strings.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -36822,200 +36822,200 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Strings.Collection.ValueArray C.I.equals``() = + [] + member _.``Strings.Collection.ValueArray C.I.equals``() = validate (Strings.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.I.equal``() = + [] + member _.``Strings.Collection.ValueArray C.I.equal``() = validate (Strings.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Strings.Collection.ValueArray C.I.not_equal``() = validate (Strings.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueArray C.I.compare``() = + [] + member _.``Strings.Collection.ValueArray C.I.compare``() = validate (Strings.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ValueArray C.I.less_than``() = + [] + member _.``Strings.Collection.ValueArray C.I.less_than``() = validate (Strings.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.ValueArray C.I.less_or_equal``() = validate (Strings.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Strings.Collection.ValueArray C.I.greater_than``() = validate (Strings.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.ValueArray C.I.greater_or_equal``() = validate (Strings.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ValueArray C.N.equals``() = + [] + member _.``Strings.Collection.ValueArray C.N.equals``() = validate (Strings.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.N.equal``() = + [] + member _.``Strings.Collection.ValueArray C.N.equal``() = validate (Strings.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Strings.Collection.ValueArray C.N.not_equal``() = validate (Strings.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueArray C.N.compare``() = + [] + member _.``Strings.Collection.ValueArray C.N.compare``() = validate (Strings.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ValueArray C.N.less_than``() = + [] + member _.``Strings.Collection.ValueArray C.N.less_than``() = validate (Strings.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.ValueArray C.N.less_or_equal``() = validate (Strings.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Strings.Collection.ValueArray C.N.greater_than``() = validate (Strings.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.ValueArray C.N.greater_or_equal``() = validate (Strings.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.equals``() = validate (Strings.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.equal``() = validate (Strings.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.not_equal``() = validate (Strings.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.compare``() = validate (Strings.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.less_than``() = validate (Strings.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Strings.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.greater_than``() = validate (Strings.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Strings.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.equals``() = validate (Strings.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.equal``() = validate (Strings.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.not_equal``() = validate (Strings.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.compare``() = validate (Strings.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;72;0;72;-25;-157;1;3;-72;0;-97;-229;1;97;25;97;0;-132;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.less_than``() = validate (Strings.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Strings.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.greater_than``() = validate (Strings.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Strings.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ArrayArray C.I.equals``() = + [] + member _.``Strings.Collection.ArrayArray C.I.equals``() = validate (Strings.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37023,8 +37023,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.I.equal``() = + [] + member _.``Strings.Collection.ArrayArray C.I.equal``() = validate (Strings.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37032,8 +37032,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.I.not_equal``() = validate (Strings.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37041,8 +37041,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray C.I.compare``() = + [] + member _.``Strings.Collection.ArrayArray C.I.compare``() = validate (Strings.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;-1;-1;-1;-1;-1;-1;1;72;0;72;-25;-157;-1;-1;-1;-1;-1;-1;1;3;-72;0; -97;-229;-1;-1;-1;-1;-1;-1;1;97;25;97;0;-132;-1;-1;-1;-1;-1;-1;1;229;157;229;132;0;-1;-1;-1;-1;-1;-1;1;1;1;1;1;1;0;-1; @@ -37050,8 +37050,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;97;25;97;0;-132;1;1;1;1;1;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Strings.Collection.ArrayArray C.I.less_than``() = validate (Strings.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0; 1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;0;0;0;1; @@ -37059,8 +37059,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.I.less_or_equal``() = validate (Strings.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;1;1;1;1;0;0;1;1; 1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;1; @@ -37068,8 +37068,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Strings.Collection.ArrayArray C.I.greater_than``() = validate (Strings.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;0;0;0;0;0;0;0;0;1;1;0;0; 0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;0; @@ -37077,8 +37077,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.I.greater_or_equal``() = validate (Strings.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1; 0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;1;1;1;0; @@ -37086,8 +37086,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ArrayArray C.N.equals``() = + [] + member _.``Strings.Collection.ArrayArray C.N.equals``() = validate (Strings.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37095,8 +37095,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.N.equal``() = + [] + member _.``Strings.Collection.ArrayArray C.N.equal``() = validate (Strings.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37104,8 +37104,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.N.not_equal``() = validate (Strings.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37113,8 +37113,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray C.N.compare``() = + [] + member _.``Strings.Collection.ArrayArray C.N.compare``() = validate (Strings.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;-1;-1;-1;-1;-1;-1;1;72;0;72;-25;-157;-1;-1;-1;-1;-1;-1;1;3;-72;0; -97;-229;-1;-1;-1;-1;-1;-1;1;97;25;97;0;-132;-1;-1;-1;-1;-1;-1;1;229;157;229;132;0;-1;-1;-1;-1;-1;-1;1;1;1;1;1;1;0;-1; @@ -37122,8 +37122,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;97;25;97;0;-132;1;1;1;1;1;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Strings.Collection.ArrayArray C.N.less_than``() = validate (Strings.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0; 1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;0;0;0;1; @@ -37131,8 +37131,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.N.less_or_equal``() = validate (Strings.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;1;1;1;1;0;0;1;1; 1;1;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;1;0;0;0;0;0;0;1;1; @@ -37140,8 +37140,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Strings.Collection.ArrayArray C.N.greater_than``() = validate (Strings.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;1;0;0;0;0;0;0;0;0;1;1;0;0; 0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;0; @@ -37149,8 +37149,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray C.N.greater_or_equal``() = validate (Strings.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1; 0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;1;1;1;0; @@ -37158,8 +37158,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ListArray C.I.equals``() = + [] + member _.``Strings.Collection.ListArray C.I.equals``() = validate (Strings.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37167,8 +37167,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.I.equal``() = + [] + member _.``Strings.Collection.ListArray C.I.equal``() = validate (Strings.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37176,8 +37176,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.I.not_equal``() = + [] + member _.``Strings.Collection.ListArray C.I.not_equal``() = validate (Strings.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37185,8 +37185,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ListArray C.I.compare``() = + [] + member _.``Strings.Collection.ListArray C.I.compare``() = validate (Strings.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;-1;-72;-3;-97;-229;1;72;0;72;-25;-157;1;72;-1;72;-25;-157;1;3;-72;0; -97;-229;1;3;-72;-1;-97;-229;1;97;25;97;0;-132;1;97;25;97;-1;-132;1;229;157;229;132;0;1;229;157;229;132;-1;1;-1;-1;-1;-1;-1;0;-1; @@ -37194,8 +37194,8 @@ type GeneratedTestSuite () = 1;97;25;97;1;-132;1;97;25;97;0;-132;1;229;157;229;132;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ListArray C.I.less_than``() = + [] + member _.``Strings.Collection.ListArray C.I.less_than``() = validate (Strings.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;1;0; 1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;0;1; @@ -37203,8 +37203,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.ListArray C.I.less_or_equal``() = validate (Strings.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;1;1;0;0;1;1; 1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;1;1;1;1;1;1; @@ -37212,8 +37212,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.I.greater_than``() = + [] + member _.``Strings.Collection.ListArray C.I.greater_than``() = validate (Strings.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;0;0;1;1;0;0; 0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;0;0;0;0;0;0; @@ -37221,8 +37221,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.ListArray C.I.greater_or_equal``() = validate (Strings.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;0;1; 0;0;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;1;0; @@ -37230,8 +37230,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ListArray C.N.equals``() = + [] + member _.``Strings.Collection.ListArray C.N.equals``() = validate (Strings.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37239,8 +37239,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.N.equal``() = + [] + member _.``Strings.Collection.ListArray C.N.equal``() = validate (Strings.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37248,8 +37248,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.N.not_equal``() = + [] + member _.``Strings.Collection.ListArray C.N.not_equal``() = validate (Strings.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37257,8 +37257,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ListArray C.N.compare``() = + [] + member _.``Strings.Collection.ListArray C.N.compare``() = validate (Strings.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;-1;-72;-3;-97;-229;1;72;0;72;-25;-157;1;72;-1;72;-25;-157;1;3;-72;0; -97;-229;1;3;-72;-1;-97;-229;1;97;25;97;0;-132;1;97;25;97;-1;-132;1;229;157;229;132;0;1;229;157;229;132;-1;1;-1;-1;-1;-1;-1;0;-1; @@ -37266,8 +37266,8 @@ type GeneratedTestSuite () = 1;97;25;97;1;-132;1;97;25;97;0;-132;1;229;157;229;132;1;1;229;157;229;132;0 |] - [] - member __.``Strings.Collection.ListArray C.N.less_than``() = + [] + member _.``Strings.Collection.ListArray C.N.less_than``() = validate (Strings.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;0;1;0;1;1;0;0;1;0; 1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;0;1; @@ -37275,8 +37275,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.ListArray C.N.less_or_equal``() = validate (Strings.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;1;0;1;1;0;0;1;1; 1;1;0;0;1;1;1;1;0;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;1;0;1;1;1;1;1;1;1; @@ -37284,8 +37284,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ListArray C.N.greater_than``() = + [] + member _.``Strings.Collection.ListArray C.N.greater_than``() = validate (Strings.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;0;1;0;0;1;1;0;0; 0;0;1;1;0;0;0;0;1;1;1;1;0;0;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;0;1;0;0;0;0;0;0;0; @@ -37293,8 +37293,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.ListArray C.N.greater_or_equal``() = validate (Strings.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;1;0;1;0;0;1;1;0;1; 0;0;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;1;0; @@ -37302,8 +37302,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37311,8 +37311,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37320,8 +37320,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37329,8 +37329,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;-1;-3;-3;-97;1;1;72;0;72;-25;-157;1;72;72;72;-25;1;1;3;-72;0; -97;-229;1;3;-1;-1;-97;1;1;97;25;97;0;-132;1;97;97;97;-1;1;1;229;157;229;132;0;1;229;229;229;132;1;1;-1;-1;-1;-1;-1;0;-1; @@ -37338,8 +37338,8 @@ type GeneratedTestSuite () = 1;97;25;97;1;-132;1;97;97;97;0;1;1;-1;-1;-1;-1;-1;229;-1;-1;-1;-1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;1;0; 1;1;0;0;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;1; @@ -37347,8 +37347,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;1;0;0;0;1;1; 1;1;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1; @@ -37356,8 +37356,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;0;1;1;1;1;0;1;1;1;0;0; 0;0;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0; @@ -37365,8 +37365,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;0;1; 0;0;1;1;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0; @@ -37374,8 +37374,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37383,8 +37383,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -37392,8 +37392,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -37401,8 +37401,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-72;-3;-97;-229;1;-1;-3;-3;-97;1;1;72;0;72;-25;-157;1;72;72;72;-25;1;1;3;-72;0; -97;-229;1;3;-1;-1;-97;1;1;97;25;97;0;-132;1;97;97;97;-1;1;1;229;157;229;132;0;1;229;229;229;132;1;1;-1;-1;-1;-1;-1;0;-1; @@ -37410,8 +37410,8 @@ type GeneratedTestSuite () = 1;97;25;97;1;-132;1;97;97;97;0;1;1;-1;-1;-1;-1;-1;229;-1;-1;-1;-1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;1;0; 1;1;0;0;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;1; @@ -37419,8 +37419,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;1;0;0;0;1;1; 1;1;0;0;1;1;1;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1; @@ -37428,8 +37428,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;1;0;0;0;0;1;0;0;1;1;1;1;1;0;1;1;1;1;1 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;0;1;1;1;1;0;1;1;1;0;0; 0;0;1;1;0;0;0;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0; @@ -37437,8 +37437,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;0;1;1;0;0;0;0;0;1;0;0;0;0;0 |] - [] - member __.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Strings.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Strings.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;0;0;1;1;1;1;0;1;1;1;0;1; 0;0;1;1;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0; @@ -37446,392 +37446,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.I.equals``() = + [] + member _.``Decimals.Collection.Array C.I.equals``() = validate (Decimals.Collection.Array) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.I.equal``() = + [] + member _.``Decimals.Collection.Array C.I.equal``() = validate (Decimals.Collection.Array) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.I.not_equal``() = + [] + member _.``Decimals.Collection.Array C.I.not_equal``() = validate (Decimals.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.I.compare``() = + [] + member _.``Decimals.Collection.Array C.I.compare``() = validate (Decimals.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.I.less_than``() = + [] + member _.``Decimals.Collection.Array C.I.less_than``() = validate (Decimals.Collection.Array) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.Array C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.Array C.I.less_or_equal``() = validate (Decimals.Collection.Array) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.I.greater_than``() = + [] + member _.``Decimals.Collection.Array C.I.greater_than``() = validate (Decimals.Collection.Array) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.Array C.I.greater_or_equal``() = validate (Decimals.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.Array C.N.equals``() = + [] + member _.``Decimals.Collection.Array C.N.equals``() = validate (Decimals.Collection.Array) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.N.equal``() = + [] + member _.``Decimals.Collection.Array C.N.equal``() = validate (Decimals.Collection.Array) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.N.not_equal``() = + [] + member _.``Decimals.Collection.Array C.N.not_equal``() = validate (Decimals.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.N.compare``() = + [] + member _.``Decimals.Collection.Array C.N.compare``() = validate (Decimals.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.N.less_than``() = + [] + member _.``Decimals.Collection.Array C.N.less_than``() = validate (Decimals.Collection.Array) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.Array C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.Array C.N.less_or_equal``() = validate (Decimals.Collection.Array) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.Array C.N.greater_than``() = + [] + member _.``Decimals.Collection.Array C.N.greater_than``() = validate (Decimals.Collection.Array) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.Array C.N.greater_or_equal``() = validate (Decimals.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.OptionArray C.I.equals``() = + [] + member _.``Decimals.Collection.OptionArray C.I.equals``() = validate (Decimals.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.I.equal``() = + [] + member _.``Decimals.Collection.OptionArray C.I.equal``() = validate (Decimals.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.I.not_equal``() = validate (Decimals.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.I.compare``() = + [] + member _.``Decimals.Collection.OptionArray C.I.compare``() = validate (Decimals.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.I.less_than``() = + [] + member _.``Decimals.Collection.OptionArray C.I.less_than``() = validate (Decimals.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.I.less_or_equal``() = validate (Decimals.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.OptionArray C.I.greater_than``() = validate (Decimals.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.I.greater_or_equal``() = validate (Decimals.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.OptionArray C.N.equals``() = + [] + member _.``Decimals.Collection.OptionArray C.N.equals``() = validate (Decimals.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.N.equal``() = + [] + member _.``Decimals.Collection.OptionArray C.N.equal``() = validate (Decimals.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.N.not_equal``() = validate (Decimals.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.N.compare``() = + [] + member _.``Decimals.Collection.OptionArray C.N.compare``() = validate (Decimals.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;0;1;1;1;1;1;-1;0;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.N.less_than``() = + [] + member _.``Decimals.Collection.OptionArray C.N.less_than``() = validate (Decimals.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.N.less_or_equal``() = validate (Decimals.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;1;1;1;1;0;0;1;0;0;0;0;0;1;1;1;1;0;0;1;0;1;1;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.OptionArray C.N.greater_than``() = validate (Decimals.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;1;1;1;1;1;0;0;0;0;1;1;0;1;0;0;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.OptionArray C.N.greater_or_equal``() = validate (Decimals.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;0;0;0;0;1;1;1;1;1;1;1;1;0;1;0;0;1;1;0;1;1;0;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.RefArray C.I.equals``() = + [] + member _.``Decimals.Collection.RefArray C.I.equals``() = validate (Decimals.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.I.equal``() = + [] + member _.``Decimals.Collection.RefArray C.I.equal``() = validate (Decimals.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.RefArray C.I.not_equal``() = validate (Decimals.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.I.compare``() = + [] + member _.``Decimals.Collection.RefArray C.I.compare``() = validate (Decimals.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.I.less_than``() = + [] + member _.``Decimals.Collection.RefArray C.I.less_than``() = validate (Decimals.Collection.RefArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.RefArray C.I.less_or_equal``() = validate (Decimals.Collection.RefArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.RefArray C.I.greater_than``() = validate (Decimals.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.RefArray C.I.greater_or_equal``() = validate (Decimals.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.RefArray C.N.equals``() = + [] + member _.``Decimals.Collection.RefArray C.N.equals``() = validate (Decimals.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.N.equal``() = + [] + member _.``Decimals.Collection.RefArray C.N.equal``() = validate (Decimals.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.RefArray C.N.not_equal``() = validate (Decimals.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.N.compare``() = + [] + member _.``Decimals.Collection.RefArray C.N.compare``() = validate (Decimals.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.N.less_than``() = + [] + member _.``Decimals.Collection.RefArray C.N.less_than``() = validate (Decimals.Collection.RefArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.RefArray C.N.less_or_equal``() = validate (Decimals.Collection.RefArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.RefArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.RefArray C.N.greater_than``() = validate (Decimals.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.RefArray C.N.greater_or_equal``() = validate (Decimals.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.equals``() = validate (Decimals.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.equal``() = validate (Decimals.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.not_equal``() = validate (Decimals.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.compare``() = validate (Decimals.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.less_than``() = validate (Decimals.Collection.RefWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.less_or_equal``() = validate (Decimals.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.greater_than``() = validate (Decimals.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Decimals.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.equals``() = validate (Decimals.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.equal``() = validate (Decimals.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.not_equal``() = validate (Decimals.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.compare``() = validate (Decimals.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.less_than``() = validate (Decimals.Collection.RefWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.less_or_equal``() = validate (Decimals.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.greater_than``() = validate (Decimals.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Decimals.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.UnionArray C.I.equals``() = + [] + member _.``Decimals.Collection.UnionArray C.I.equals``() = validate (Decimals.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -37866,8 +37866,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.I.equal``() = + [] + member _.``Decimals.Collection.UnionArray C.I.equal``() = validate (Decimals.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -37902,8 +37902,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.I.not_equal``() = validate (Decimals.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -37938,8 +37938,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.I.compare``() = + [] + member _.``Decimals.Collection.UnionArray C.I.compare``() = validate (Decimals.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -37974,8 +37974,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.I.less_than``() = + [] + member _.``Decimals.Collection.UnionArray C.I.less_than``() = validate (Decimals.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -38010,8 +38010,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.I.less_or_equal``() = validate (Decimals.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -38046,8 +38046,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.UnionArray C.I.greater_than``() = validate (Decimals.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -38082,8 +38082,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.I.greater_or_equal``() = validate (Decimals.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -38118,8 +38118,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.UnionArray C.N.equals``() = + [] + member _.``Decimals.Collection.UnionArray C.N.equals``() = validate (Decimals.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38154,8 +38154,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.N.equal``() = + [] + member _.``Decimals.Collection.UnionArray C.N.equal``() = validate (Decimals.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38190,8 +38190,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.N.not_equal``() = validate (Decimals.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -38226,8 +38226,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.N.compare``() = + [] + member _.``Decimals.Collection.UnionArray C.N.compare``() = validate (Decimals.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -38262,8 +38262,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.N.less_than``() = + [] + member _.``Decimals.Collection.UnionArray C.N.less_than``() = validate (Decimals.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -38298,8 +38298,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.N.less_or_equal``() = validate (Decimals.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -38334,8 +38334,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.UnionArray C.N.greater_than``() = validate (Decimals.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -38370,8 +38370,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.UnionArray C.N.greater_or_equal``() = validate (Decimals.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -38406,8 +38406,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.equals``() = validate (Decimals.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38442,8 +38442,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.equal``() = validate (Decimals.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38478,8 +38478,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.not_equal``() = validate (Decimals.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -38514,8 +38514,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.compare``() = validate (Decimals.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -38550,8 +38550,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.less_than``() = validate (Decimals.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -38586,8 +38586,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Decimals.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -38622,8 +38622,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.greater_than``() = validate (Decimals.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -38658,8 +38658,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Decimals.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -38694,8 +38694,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.equals``() = validate (Decimals.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38730,8 +38730,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.equal``() = validate (Decimals.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -38766,8 +38766,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.not_equal``() = validate (Decimals.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -38802,8 +38802,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.compare``() = validate (Decimals.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1; @@ -38838,8 +38838,8 @@ type GeneratedTestSuite () = 3;2;1;-1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.less_than``() = validate (Decimals.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;1; @@ -38874,8 +38874,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Decimals.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1; @@ -38910,8 +38910,8 @@ type GeneratedTestSuite () = 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.greater_than``() = validate (Decimals.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -38946,8 +38946,8 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Decimals.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;0; @@ -38982,734 +38982,734 @@ type GeneratedTestSuite () = 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.ValueArray C.I.equals``() = + [] + member _.``Decimals.Collection.ValueArray C.I.equals``() = validate (Decimals.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.I.equal``() = + [] + member _.``Decimals.Collection.ValueArray C.I.equal``() = validate (Decimals.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.I.not_equal``() = validate (Decimals.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.I.compare``() = + [] + member _.``Decimals.Collection.ValueArray C.I.compare``() = validate (Decimals.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.I.less_than``() = + [] + member _.``Decimals.Collection.ValueArray C.I.less_than``() = validate (Decimals.Collection.ValueArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.I.less_or_equal``() = validate (Decimals.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.ValueArray C.I.greater_than``() = validate (Decimals.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.I.greater_or_equal``() = validate (Decimals.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ValueArray C.N.equals``() = + [] + member _.``Decimals.Collection.ValueArray C.N.equals``() = validate (Decimals.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.N.equal``() = + [] + member _.``Decimals.Collection.ValueArray C.N.equal``() = validate (Decimals.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.N.not_equal``() = validate (Decimals.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.N.compare``() = + [] + member _.``Decimals.Collection.ValueArray C.N.compare``() = validate (Decimals.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.N.less_than``() = + [] + member _.``Decimals.Collection.ValueArray C.N.less_than``() = validate (Decimals.Collection.ValueArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.N.less_or_equal``() = validate (Decimals.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.ValueArray C.N.greater_than``() = validate (Decimals.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.ValueArray C.N.greater_or_equal``() = validate (Decimals.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.equals``() = validate (Decimals.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.equal``() = validate (Decimals.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.not_equal``() = validate (Decimals.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.compare``() = validate (Decimals.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.less_than``() = validate (Decimals.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Decimals.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.greater_than``() = validate (Decimals.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Decimals.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.equals``() = validate (Decimals.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.equal``() = validate (Decimals.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.not_equal``() = validate (Decimals.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.compare``() = validate (Decimals.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;1;1;1;1;-1;0;-1;-1;1;-1;1;0;-1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.less_than``() = validate (Decimals.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;0;1;0;0;1;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Decimals.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.greater_than``() = validate (Decimals.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;0;0;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Decimals.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.equals``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.equals``() = validate (Decimals.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.equal``() = validate (Decimals.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.not_equal``() = validate (Decimals.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.compare``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.compare``() = validate (Decimals.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.less_than``() = validate (Decimals.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.less_or_equal``() = validate (Decimals.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.greater_than``() = validate (Decimals.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.I.greater_or_equal``() = validate (Decimals.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.equals``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.equals``() = validate (Decimals.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.equal``() = validate (Decimals.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.not_equal``() = validate (Decimals.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.compare``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.compare``() = validate (Decimals.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;-1;-1;-1;-1;1;-1;0;-1;-1;-1;-1;-1;-1;-1;1;-1;1;0;-1;-1;-1;-1;-1;-1; 1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1; 1;1;1;1;1;1;-1;1;0;-1;1;1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.less_than``() = validate (Decimals.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1; 0;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1; 0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.less_or_equal``() = validate (Decimals.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1; 0;1;0;0;1;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1; 0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.greater_than``() = validate (Decimals.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0; 1;0;1;1;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0; 1;1;1;1;1;1;0;1;0;0;1;1;1;1;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray C.N.greater_or_equal``() = validate (Decimals.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0;1;0;1;1;0;0;0;0;0;0; 1;0;1;1;1;0;0;0;0;0;1;1;1;1;1;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0; 1;1;1;1;1;1;0;1;1;0;1;1;1;1;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ListArray C.I.equals``() = + [] + member _.``Decimals.Collection.ListArray C.I.equals``() = validate (Decimals.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.I.equal``() = + [] + member _.``Decimals.Collection.ListArray C.I.equal``() = validate (Decimals.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.ListArray C.I.not_equal``() = validate (Decimals.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.I.compare``() = + [] + member _.``Decimals.Collection.ListArray C.I.compare``() = validate (Decimals.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.I.less_than``() = + [] + member _.``Decimals.Collection.ListArray C.I.less_than``() = validate (Decimals.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.ListArray C.I.less_or_equal``() = validate (Decimals.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.ListArray C.I.greater_than``() = validate (Decimals.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.ListArray C.I.greater_or_equal``() = validate (Decimals.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ListArray C.N.equals``() = + [] + member _.``Decimals.Collection.ListArray C.N.equals``() = validate (Decimals.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.N.equal``() = + [] + member _.``Decimals.Collection.ListArray C.N.equal``() = validate (Decimals.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.ListArray C.N.not_equal``() = validate (Decimals.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.N.compare``() = + [] + member _.``Decimals.Collection.ListArray C.N.compare``() = validate (Decimals.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;-1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;-1;1;-1;1;0;-1;1;-1;1;-1;-1; 1;-1;1;1;0;1;-1;1;1;-1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;-1;1;-1;-1;1;-1;0;-1;-1; 1;-1;1;1;-1;1;-1;1;0;-1;1;-1;1;1;1;1;-1;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.N.less_than``() = + [] + member _.``Decimals.Collection.ListArray C.N.less_than``() = validate (Decimals.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1;0;1;0;0;1;0;1;0;1;1; 0;1;0;0;0;0;1;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;0;0;0 |] - [] - member __.``Decimals.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.ListArray C.N.less_or_equal``() = validate (Decimals.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1; 0;1;0;0;1;0;1;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;1;0;1;1;0;1;1;1;1; 0;1;0;0;1;0;1;0;1;1;0;1;0;0;0;0;1;0;0;1 |] - [] - member __.``Decimals.Collection.ListArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.ListArray C.N.greater_than``() = validate (Decimals.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;0;1;1;1;1;0;0;0;0;1;0;0;0;0;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0; 1;0;1;1;0;1;0;1;0;0;1;0;1;1;1;1;0;1;1;0 |] - [] - member __.``Decimals.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.ListArray C.N.greater_or_equal``() = validate (Decimals.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;0;1;1;1;1;0;1;0;0;1;0;0;0;0;1;0;1;1;0;1;0;1;0;0; 1;0;1;1;1;1;0;1;1;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;0;0; 1;0;1;1;0;1;0;1;1;0;1;0;1;1;1;1;0;1;1;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;1;1;1;1;-1;0;-1;-1;1;-1;-1;-1;1;1;-1;1;0;-1;1;1;1;-1;1; 1;-1;1;1;0;1;1;1;1;1;1;-1;-1;-1;-1;0;-1;-1;-1;1;1;-1;1;-1;-1;1;0;1;-1;1;1;-1;1;-1;-1;1;-1;0;-1;1; 1;-1;1;1;-1;1;1;1;0;1;1;-1;-1;-1;-1;-1;-1;-1;-1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1;0;1;1;1;0;0;1;0;0;1;0;0;0;1;0; 0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0;0;1;0;1;1;0;1;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;0;0;1;0;1;1;0;0;0;1;0; 0;1;0;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;0;1;0;1;0;0;1;0;1;1;0;1;1;1;0; 0;1;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1;1;0;1;0;0;1;0;1;0;1;1;0;1;0;0;1;0;0;0;1; 1;0;1;1;0;1;1;1;0;1;1;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Decimals.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Decimals.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;1;0;1;1;1;0;1; 1;0;1;1;1;1;1;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;0;1; 1;0;1;1;0;1;1;1;1;1;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.Array E.I.equals``() = + [] + member _.``NullableDecimals.Collection.Array E.I.equals``() = validate (NullableDecimals.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.Array E.I.equal``() = + [] + member _.``NullableDecimals.Collection.Array E.I.equal``() = validate (NullableDecimals.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.Array E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.Array E.I.not_equal``() = validate (NullableDecimals.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.Array E.N.equals``() = + [] + member _.``NullableDecimals.Collection.Array E.N.equals``() = validate (NullableDecimals.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.Array E.N.equal``() = + [] + member _.``NullableDecimals.Collection.Array E.N.equal``() = validate (NullableDecimals.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.Array E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.Array E.N.not_equal``() = validate (NullableDecimals.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.I.equals``() = validate (NullableDecimals.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.I.equal``() = validate (NullableDecimals.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.I.not_equal``() = validate (NullableDecimals.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.N.equals``() = validate (NullableDecimals.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.N.equal``() = validate (NullableDecimals.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.OptionArray E.N.not_equal``() = validate (NullableDecimals.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.RefArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.RefArray E.I.equals``() = validate (NullableDecimals.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.RefArray E.I.equal``() = validate (NullableDecimals.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.RefArray E.I.not_equal``() = validate (NullableDecimals.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.RefArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.RefArray E.N.equals``() = validate (NullableDecimals.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.RefArray E.N.equal``() = validate (NullableDecimals.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.RefArray E.N.not_equal``() = validate (NullableDecimals.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.I.equals``() = validate (NullableDecimals.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.I.equal``() = validate (NullableDecimals.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.I.not_equal``() = validate (NullableDecimals.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.N.equals``() = validate (NullableDecimals.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.N.equal``() = validate (NullableDecimals.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.RefWrapArray E.N.not_equal``() = validate (NullableDecimals.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.I.equals``() = validate (NullableDecimals.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -39758,8 +39758,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.I.equal``() = validate (NullableDecimals.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -39808,8 +39808,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.I.not_equal``() = validate (NullableDecimals.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -39858,8 +39858,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.N.equals``() = validate (NullableDecimals.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -39908,8 +39908,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.N.equal``() = validate (NullableDecimals.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -39958,8 +39958,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.UnionArray E.N.not_equal``() = validate (NullableDecimals.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -40008,8 +40008,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.I.equals``() = validate (NullableDecimals.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -40058,8 +40058,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.I.equal``() = validate (NullableDecimals.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -40108,8 +40108,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableDecimals.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -40158,8 +40158,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.N.equals``() = validate (NullableDecimals.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -40208,8 +40208,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.N.equal``() = validate (NullableDecimals.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -40258,8 +40258,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableDecimals.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -40308,80 +40308,80 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.I.equals``() = validate (NullableDecimals.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.I.equal``() = validate (NullableDecimals.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.I.not_equal``() = validate (NullableDecimals.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.N.equals``() = validate (NullableDecimals.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.N.equal``() = validate (NullableDecimals.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.ValueArray E.N.not_equal``() = validate (NullableDecimals.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.I.equals``() = validate (NullableDecimals.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.I.equal``() = validate (NullableDecimals.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableDecimals.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.N.equals``() = validate (NullableDecimals.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.N.equal``() = validate (NullableDecimals.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableDecimals.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.I.equals``() = validate (NullableDecimals.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40389,8 +40389,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.I.equal``() = validate (NullableDecimals.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40398,8 +40398,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.I.not_equal``() = validate (NullableDecimals.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -40407,8 +40407,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.N.equals``() = validate (NullableDecimals.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40416,8 +40416,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.N.equal``() = validate (NullableDecimals.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40425,8 +40425,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.ArrayArray E.N.not_equal``() = validate (NullableDecimals.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -40434,8 +40434,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ListArray E.I.equals``() = + [] + member _.``NullableDecimals.Collection.ListArray E.I.equals``() = validate (NullableDecimals.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40443,8 +40443,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ListArray E.I.equal``() = + [] + member _.``NullableDecimals.Collection.ListArray E.I.equal``() = validate (NullableDecimals.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40452,8 +40452,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableDecimals.Collection.ListArray E.I.not_equal``() = validate (NullableDecimals.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -40461,8 +40461,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDecimals.Collection.ListArray E.N.equals``() = + [] + member _.``NullableDecimals.Collection.ListArray E.N.equals``() = validate (NullableDecimals.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40470,8 +40470,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ListArray E.N.equal``() = + [] + member _.``NullableDecimals.Collection.ListArray E.N.equal``() = validate (NullableDecimals.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1;0; @@ -40479,8 +40479,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDecimals.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableDecimals.Collection.ListArray E.N.not_equal``() = validate (NullableDecimals.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0; 1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1; @@ -40488,520 +40488,520 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.Array C.I.equals``() = + [] + member _.``Floats.Collection.Array C.I.equals``() = validate (Floats.Collection.Array) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.I.equal``() = + [] + member _.``Floats.Collection.Array C.I.equal``() = validate (Floats.Collection.Array) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.I.not_equal``() = + [] + member _.``Floats.Collection.Array C.I.not_equal``() = validate (Floats.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.I.compare``() = + [] + member _.``Floats.Collection.Array C.I.compare``() = validate (Floats.Collection.Array) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.I.less_than``() = + [] + member _.``Floats.Collection.Array C.I.less_than``() = validate (Floats.Collection.Array) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.Array C.I.less_or_equal``() = + [] + member _.``Floats.Collection.Array C.I.less_or_equal``() = validate (Floats.Collection.Array) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.I.greater_than``() = + [] + member _.``Floats.Collection.Array C.I.greater_than``() = validate (Floats.Collection.Array) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.Array C.I.greater_or_equal``() = validate (Floats.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.Array C.N.equals``() = + [] + member _.``Floats.Collection.Array C.N.equals``() = validate (Floats.Collection.Array) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.N.equal``() = + [] + member _.``Floats.Collection.Array C.N.equal``() = validate (Floats.Collection.Array) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.N.not_equal``() = + [] + member _.``Floats.Collection.Array C.N.not_equal``() = validate (Floats.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.N.compare``() = + [] + member _.``Floats.Collection.Array C.N.compare``() = validate (Floats.Collection.Array) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.N.less_than``() = + [] + member _.``Floats.Collection.Array C.N.less_than``() = validate (Floats.Collection.Array) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.Array C.N.less_or_equal``() = + [] + member _.``Floats.Collection.Array C.N.less_or_equal``() = validate (Floats.Collection.Array) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.Array C.N.greater_than``() = + [] + member _.``Floats.Collection.Array C.N.greater_than``() = validate (Floats.Collection.Array) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.Array C.N.greater_or_equal``() = validate (Floats.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.OptionArray C.I.equals``() = + [] + member _.``Floats.Collection.OptionArray C.I.equals``() = validate (Floats.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.I.equal``() = + [] + member _.``Floats.Collection.OptionArray C.I.equal``() = validate (Floats.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Floats.Collection.OptionArray C.I.not_equal``() = validate (Floats.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.I.compare``() = + [] + member _.``Floats.Collection.OptionArray C.I.compare``() = validate (Floats.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1;-1;-1;1;1;0;1;1;1;-1;1;1;1;1;1;-1;0;1;1;-1;1;1;-1; 1;-1;-1;-1;0;-1;-1;-1;-1;-1;1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;-1;-1;1;1;-1;0;-1;-1; 1;1;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;1;-1;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.I.less_than``() = + [] + member _.``Floats.Collection.OptionArray C.I.less_than``() = validate (Floats.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1; 0;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0;1;0;0;0 |] - [] - member __.``Floats.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.OptionArray C.I.less_or_equal``() = validate (Floats.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1;1;1;0;0;1;0;0;0;1;0;0;0;0;0;1;1;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;1;1;1;1; 0;0;1;1;0;0;1;0;1;1;0;0;1;0;0;0;1;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Floats.Collection.OptionArray C.I.greater_than``() = validate (Floats.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;0;1;0;1;0;1;1;1;1;1;0;0;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;0;0;1;0;0;0;0; 1;1;0;0;0;1;0;1;0;0;1;1;0;1;0;1;0;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.OptionArray C.I.greater_or_equal``() = validate (Floats.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;1;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;1;0;1;0;0; 1;1;0;0;0;1;0;1;1;0;1;1;0;1;0;1;0;1;1;1 |] - [] - member __.``Floats.Collection.OptionArray C.N.equals``() = + [] + member _.``Floats.Collection.OptionArray C.N.equals``() = validate (Floats.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.N.equal``() = + [] + member _.``Floats.Collection.OptionArray C.N.equal``() = validate (Floats.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Floats.Collection.OptionArray C.N.not_equal``() = validate (Floats.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.N.compare``() = + [] + member _.``Floats.Collection.OptionArray C.N.compare``() = validate (Floats.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1;-1;-1;1;1;0;1;1;1;-1;1;1;1;1;1;-1;0;1;1;-1;1;1;-1; 1;-1;-1;-1;0;-1;-1;-1;-1;-1;1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;-1;-1;1;1;-1;0;-1;-1; 1;1;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;1;-1;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.N.less_than``() = + [] + member _.``Floats.Collection.OptionArray C.N.less_than``() = validate (Floats.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1; 0;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0;1;0;0;0 |] - [] - member __.``Floats.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.OptionArray C.N.less_or_equal``() = validate (Floats.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1;1;1;0;0;1;0;0;0;1;0;0;0;0;0;1;1;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;1;1;1;1; 0;0;1;1;0;0;1;0;1;1;0;0;1;0;0;0;1;0;0;1 |] - [] - member __.``Floats.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Floats.Collection.OptionArray C.N.greater_than``() = validate (Floats.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;0;1;0;1;0;1;1;1;1;1;0;0;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;0;0;1;0;0;0;0; 1;1;0;0;0;1;0;1;0;0;1;1;0;1;0;1;0;1;1;0 |] - [] - member __.``Floats.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.OptionArray C.N.greater_or_equal``() = validate (Floats.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;1;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;1;0;1;0;0; 1;1;0;0;0;1;0;1;1;0;1;1;0;1;0;1;0;1;1;1 |] - [] - member __.``Floats.Collection.RefArray C.I.equals``() = + [] + member _.``Floats.Collection.RefArray C.I.equals``() = validate (Floats.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.I.equal``() = + [] + member _.``Floats.Collection.RefArray C.I.equal``() = validate (Floats.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.I.not_equal``() = + [] + member _.``Floats.Collection.RefArray C.I.not_equal``() = validate (Floats.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.I.compare``() = + [] + member _.``Floats.Collection.RefArray C.I.compare``() = validate (Floats.Collection.RefArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.I.less_than``() = + [] + member _.``Floats.Collection.RefArray C.I.less_than``() = validate (Floats.Collection.RefArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.RefArray C.I.less_or_equal``() = validate (Floats.Collection.RefArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.I.greater_than``() = + [] + member _.``Floats.Collection.RefArray C.I.greater_than``() = validate (Floats.Collection.RefArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.RefArray C.I.greater_or_equal``() = validate (Floats.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.RefArray C.N.equals``() = + [] + member _.``Floats.Collection.RefArray C.N.equals``() = validate (Floats.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.N.equal``() = + [] + member _.``Floats.Collection.RefArray C.N.equal``() = validate (Floats.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.N.not_equal``() = + [] + member _.``Floats.Collection.RefArray C.N.not_equal``() = validate (Floats.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.N.compare``() = + [] + member _.``Floats.Collection.RefArray C.N.compare``() = validate (Floats.Collection.RefArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.N.less_than``() = + [] + member _.``Floats.Collection.RefArray C.N.less_than``() = validate (Floats.Collection.RefArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.RefArray C.N.less_or_equal``() = validate (Floats.Collection.RefArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.RefArray C.N.greater_than``() = + [] + member _.``Floats.Collection.RefArray C.N.greater_than``() = validate (Floats.Collection.RefArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.RefArray C.N.greater_or_equal``() = validate (Floats.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.equals``() = validate (Floats.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.equal``() = validate (Floats.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.not_equal``() = validate (Floats.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.compare``() = validate (Floats.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.less_than``() = validate (Floats.Collection.RefWrapArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.less_or_equal``() = validate (Floats.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.greater_than``() = validate (Floats.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Floats.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.equals``() = validate (Floats.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.equal``() = validate (Floats.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.not_equal``() = validate (Floats.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.compare``() = validate (Floats.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.less_than``() = validate (Floats.Collection.RefWrapArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.less_or_equal``() = validate (Floats.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.greater_than``() = validate (Floats.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Floats.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.UnionArray C.I.equals``() = + [] + member _.``Floats.Collection.UnionArray C.I.equals``() = validate (Floats.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -41105,8 +41105,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.I.equal``() = + [] + member _.``Floats.Collection.UnionArray C.I.equal``() = validate (Floats.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -41210,8 +41210,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Floats.Collection.UnionArray C.I.not_equal``() = validate (Floats.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -41315,8 +41315,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.I.compare``() = + [] + member _.``Floats.Collection.UnionArray C.I.compare``() = validate (Floats.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -41420,8 +41420,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.I.less_than``() = + [] + member _.``Floats.Collection.UnionArray C.I.less_than``() = validate (Floats.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -41525,8 +41525,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Floats.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.UnionArray C.I.less_or_equal``() = validate (Floats.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -41630,8 +41630,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Floats.Collection.UnionArray C.I.greater_than``() = validate (Floats.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -41735,8 +41735,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.UnionArray C.I.greater_or_equal``() = validate (Floats.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -41840,8 +41840,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Floats.Collection.UnionArray C.N.equals``() = + [] + member _.``Floats.Collection.UnionArray C.N.equals``() = validate (Floats.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -41945,8 +41945,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.N.equal``() = + [] + member _.``Floats.Collection.UnionArray C.N.equal``() = validate (Floats.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -42050,8 +42050,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Floats.Collection.UnionArray C.N.not_equal``() = validate (Floats.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -42155,8 +42155,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.N.compare``() = + [] + member _.``Floats.Collection.UnionArray C.N.compare``() = validate (Floats.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -42260,8 +42260,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.N.less_than``() = + [] + member _.``Floats.Collection.UnionArray C.N.less_than``() = validate (Floats.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -42365,8 +42365,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Floats.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.UnionArray C.N.less_or_equal``() = validate (Floats.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -42470,8 +42470,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Floats.Collection.UnionArray C.N.greater_than``() = validate (Floats.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -42575,8 +42575,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.UnionArray C.N.greater_or_equal``() = validate (Floats.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -42680,8 +42680,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.equals``() = validate (Floats.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -42785,8 +42785,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.equal``() = validate (Floats.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -42890,8 +42890,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.not_equal``() = validate (Floats.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -42995,8 +42995,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.compare``() = validate (Floats.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -43100,8 +43100,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.less_than``() = validate (Floats.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -43205,8 +43205,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Floats.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -43310,8 +43310,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.greater_than``() = validate (Floats.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -43415,8 +43415,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Floats.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -43520,8 +43520,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.equals``() = validate (Floats.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -43625,8 +43625,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.equal``() = validate (Floats.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -43730,8 +43730,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.not_equal``() = validate (Floats.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -43835,8 +43835,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.compare``() = validate (Floats.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -43940,8 +43940,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.less_than``() = validate (Floats.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -44045,8 +44045,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Floats.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -44150,8 +44150,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.greater_than``() = validate (Floats.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -44255,8 +44255,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Floats.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Floats.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -44360,264 +44360,264 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Floats.Collection.ValueArray C.I.equals``() = + [] + member _.``Floats.Collection.ValueArray C.I.equals``() = validate (Floats.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.I.equal``() = + [] + member _.``Floats.Collection.ValueArray C.I.equal``() = validate (Floats.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Floats.Collection.ValueArray C.I.not_equal``() = validate (Floats.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.I.compare``() = + [] + member _.``Floats.Collection.ValueArray C.I.compare``() = validate (Floats.Collection.ValueArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.I.less_than``() = + [] + member _.``Floats.Collection.ValueArray C.I.less_than``() = validate (Floats.Collection.ValueArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.ValueArray C.I.less_or_equal``() = validate (Floats.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Floats.Collection.ValueArray C.I.greater_than``() = validate (Floats.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.ValueArray C.I.greater_or_equal``() = validate (Floats.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.ValueArray C.N.equals``() = + [] + member _.``Floats.Collection.ValueArray C.N.equals``() = validate (Floats.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.N.equal``() = + [] + member _.``Floats.Collection.ValueArray C.N.equal``() = validate (Floats.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Floats.Collection.ValueArray C.N.not_equal``() = validate (Floats.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.N.compare``() = + [] + member _.``Floats.Collection.ValueArray C.N.compare``() = validate (Floats.Collection.ValueArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.N.less_than``() = + [] + member _.``Floats.Collection.ValueArray C.N.less_than``() = validate (Floats.Collection.ValueArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.ValueArray C.N.less_or_equal``() = validate (Floats.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Floats.Collection.ValueArray C.N.greater_than``() = validate (Floats.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.ValueArray C.N.greater_or_equal``() = validate (Floats.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.equals``() = validate (Floats.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.equal``() = validate (Floats.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.not_equal``() = validate (Floats.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.compare``() = validate (Floats.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.less_than``() = validate (Floats.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Floats.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.greater_than``() = validate (Floats.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Floats.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.equals``() = validate (Floats.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.equal``() = validate (Floats.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.not_equal``() = validate (Floats.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.compare``() = validate (Floats.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.less_than``() = validate (Floats.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Floats.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.greater_than``() = validate (Floats.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Floats.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Floats.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Floats.Collection.ArrayArray C.I.equals``() = + [] + member _.``Floats.Collection.ArrayArray C.I.equals``() = validate (Floats.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44630,8 +44630,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.I.equal``() = + [] + member _.``Floats.Collection.ArrayArray C.I.equal``() = validate (Floats.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44644,8 +44644,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.I.not_equal``() = validate (Floats.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -44658,8 +44658,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.I.compare``() = + [] + member _.``Floats.Collection.ArrayArray C.I.compare``() = validate (Floats.Collection.ArrayArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;-1;0;1; 1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -44672,8 +44672,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Floats.Collection.ArrayArray C.I.less_than``() = validate (Floats.Collection.ArrayArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;0;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -44686,8 +44686,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Floats.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.I.less_or_equal``() = validate (Floats.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -44700,8 +44700,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Floats.Collection.ArrayArray C.I.greater_than``() = validate (Floats.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -44714,8 +44714,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.I.greater_or_equal``() = validate (Floats.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;1;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44728,8 +44728,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Floats.Collection.ArrayArray C.N.equals``() = + [] + member _.``Floats.Collection.ArrayArray C.N.equals``() = validate (Floats.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44742,8 +44742,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.N.equal``() = + [] + member _.``Floats.Collection.ArrayArray C.N.equal``() = validate (Floats.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44756,8 +44756,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.N.not_equal``() = validate (Floats.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -44770,8 +44770,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.N.compare``() = + [] + member _.``Floats.Collection.ArrayArray C.N.compare``() = validate (Floats.Collection.ArrayArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;-1;0;1; 1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -44784,8 +44784,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Floats.Collection.ArrayArray C.N.less_than``() = validate (Floats.Collection.ArrayArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;0;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -44798,8 +44798,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Floats.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.N.less_or_equal``() = validate (Floats.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -44812,8 +44812,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Floats.Collection.ArrayArray C.N.greater_than``() = validate (Floats.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -44826,8 +44826,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray C.N.greater_or_equal``() = validate (Floats.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;1;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44840,8 +44840,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Floats.Collection.ListArray C.I.equals``() = + [] + member _.``Floats.Collection.ListArray C.I.equals``() = validate (Floats.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44854,8 +44854,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.I.equal``() = + [] + member _.``Floats.Collection.ListArray C.I.equal``() = validate (Floats.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44868,8 +44868,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.I.not_equal``() = + [] + member _.``Floats.Collection.ListArray C.I.not_equal``() = validate (Floats.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -44882,8 +44882,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.I.compare``() = + [] + member _.``Floats.Collection.ListArray C.I.compare``() = validate (Floats.Collection.ListArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;1;1;1;-1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;-1;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -44896,8 +44896,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.I.less_than``() = + [] + member _.``Floats.Collection.ListArray C.I.less_than``() = validate (Floats.Collection.ListArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1; @@ -44910,8 +44910,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Floats.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.ListArray C.I.less_or_equal``() = validate (Floats.Collection.ListArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1; @@ -44924,8 +44924,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.I.greater_than``() = + [] + member _.``Floats.Collection.ListArray C.I.greater_than``() = validate (Floats.Collection.ListArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;0;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -44938,8 +44938,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.ListArray C.I.greater_or_equal``() = validate (Floats.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;1;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44952,8 +44952,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Floats.Collection.ListArray C.N.equals``() = + [] + member _.``Floats.Collection.ListArray C.N.equals``() = validate (Floats.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44966,8 +44966,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.N.equal``() = + [] + member _.``Floats.Collection.ListArray C.N.equal``() = validate (Floats.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -44980,8 +44980,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.N.not_equal``() = + [] + member _.``Floats.Collection.ListArray C.N.not_equal``() = validate (Floats.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -44994,8 +44994,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.N.compare``() = + [] + member _.``Floats.Collection.ListArray C.N.compare``() = validate (Floats.Collection.ListArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;1;1;1;-1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;-1;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -45008,8 +45008,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.N.less_than``() = + [] + member _.``Floats.Collection.ListArray C.N.less_than``() = validate (Floats.Collection.ListArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1; @@ -45022,8 +45022,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Floats.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.ListArray C.N.less_or_equal``() = validate (Floats.Collection.ListArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1; @@ -45036,8 +45036,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Floats.Collection.ListArray C.N.greater_than``() = + [] + member _.``Floats.Collection.ListArray C.N.greater_than``() = validate (Floats.Collection.ListArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;0;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -45050,8 +45050,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Floats.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.ListArray C.N.greater_or_equal``() = validate (Floats.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;1;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -45064,8 +45064,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -45078,8 +45078,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -45092,8 +45092,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -45106,8 +45106,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;1;1;1;1;1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;1;1;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -45120,8 +45120,8 @@ type GeneratedTestSuite () = -1;-1;-1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -45134,8 +45134,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -45148,8 +45148,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -45162,8 +45162,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; @@ -45176,8 +45176,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -45190,8 +45190,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -45204,8 +45204,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -45218,8 +45218,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;1;1;1;1;1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;1;1;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -45232,8 +45232,8 @@ type GeneratedTestSuite () = -1;-1;-1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -45246,8 +45246,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -45260,8 +45260,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -45274,8 +45274,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Floats.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Floats.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; @@ -45288,56 +45288,56 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableFloats.Collection.Array E.I.equals``() = + [] + member _.``NullableFloats.Collection.Array E.I.equals``() = validate (NullableFloats.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.Array E.I.equal``() = + [] + member _.``NullableFloats.Collection.Array E.I.equal``() = validate (NullableFloats.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.Array E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.Array E.I.not_equal``() = validate (NullableFloats.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.Array E.N.equals``() = + [] + member _.``NullableFloats.Collection.Array E.N.equals``() = validate (NullableFloats.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.Array E.N.equal``() = + [] + member _.``NullableFloats.Collection.Array E.N.equal``() = validate (NullableFloats.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.Array E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.Array E.N.not_equal``() = validate (NullableFloats.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.OptionArray E.I.equals``() = validate (NullableFloats.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -45345,8 +45345,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloats.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.OptionArray E.I.equal``() = validate (NullableFloats.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -45354,8 +45354,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloats.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.OptionArray E.I.not_equal``() = validate (NullableFloats.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -45363,8 +45363,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableFloats.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.OptionArray E.N.equals``() = validate (NullableFloats.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -45372,8 +45372,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloats.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.OptionArray E.N.equal``() = validate (NullableFloats.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -45381,8 +45381,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloats.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.OptionArray E.N.not_equal``() = validate (NullableFloats.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -45390,104 +45390,104 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableFloats.Collection.RefArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.RefArray E.I.equals``() = validate (NullableFloats.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.RefArray E.I.equal``() = validate (NullableFloats.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.RefArray E.I.not_equal``() = validate (NullableFloats.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.RefArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.RefArray E.N.equals``() = validate (NullableFloats.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.RefArray E.N.equal``() = validate (NullableFloats.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.RefArray E.N.not_equal``() = validate (NullableFloats.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.I.equals``() = validate (NullableFloats.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.I.equal``() = validate (NullableFloats.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.I.not_equal``() = validate (NullableFloats.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.N.equals``() = validate (NullableFloats.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.N.equal``() = validate (NullableFloats.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.RefWrapArray E.N.not_equal``() = validate (NullableFloats.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.UnionArray E.I.equals``() = validate (NullableFloats.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -45614,8 +45614,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.UnionArray E.I.equal``() = validate (NullableFloats.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -45742,8 +45742,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.UnionArray E.I.not_equal``() = validate (NullableFloats.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -45870,8 +45870,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.UnionArray E.N.equals``() = validate (NullableFloats.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -45998,8 +45998,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.UnionArray E.N.equal``() = validate (NullableFloats.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -46126,8 +46126,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.UnionArray E.N.not_equal``() = validate (NullableFloats.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -46254,8 +46254,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.I.equals``() = validate (NullableFloats.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -46382,8 +46382,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.I.equal``() = validate (NullableFloats.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -46510,8 +46510,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableFloats.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -46638,8 +46638,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.N.equals``() = validate (NullableFloats.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -46766,8 +46766,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.N.equal``() = validate (NullableFloats.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -46894,8 +46894,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableFloats.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -47022,104 +47022,104 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.ValueArray E.I.equals``() = validate (NullableFloats.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.ValueArray E.I.equal``() = validate (NullableFloats.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.ValueArray E.I.not_equal``() = validate (NullableFloats.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.ValueArray E.N.equals``() = validate (NullableFloats.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.ValueArray E.N.equal``() = validate (NullableFloats.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.ValueArray E.N.not_equal``() = validate (NullableFloats.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.I.equals``() = validate (NullableFloats.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.I.equal``() = validate (NullableFloats.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableFloats.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.N.equals``() = validate (NullableFloats.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.N.equal``() = validate (NullableFloats.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableFloats.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.I.equals``() = validate (NullableFloats.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47133,8 +47133,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.I.equal``() = validate (NullableFloats.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47148,8 +47148,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.I.not_equal``() = validate (NullableFloats.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -47163,8 +47163,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.N.equals``() = validate (NullableFloats.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47178,8 +47178,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.N.equal``() = validate (NullableFloats.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47193,8 +47193,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.ArrayArray E.N.not_equal``() = validate (NullableFloats.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -47208,8 +47208,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ListArray E.I.equals``() = + [] + member _.``NullableFloats.Collection.ListArray E.I.equals``() = validate (NullableFloats.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47223,8 +47223,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ListArray E.I.equal``() = + [] + member _.``NullableFloats.Collection.ListArray E.I.equal``() = validate (NullableFloats.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47238,8 +47238,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableFloats.Collection.ListArray E.I.not_equal``() = validate (NullableFloats.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -47253,8 +47253,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloats.Collection.ListArray E.N.equals``() = + [] + member _.``NullableFloats.Collection.ListArray E.N.equals``() = validate (NullableFloats.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47268,8 +47268,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ListArray E.N.equal``() = + [] + member _.``NullableFloats.Collection.ListArray E.N.equal``() = validate (NullableFloats.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47283,8 +47283,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloats.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableFloats.Collection.ListArray E.N.not_equal``() = validate (NullableFloats.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -47298,520 +47298,520 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.Array C.I.equals``() = + [] + member _.``Float32s.Collection.Array C.I.equals``() = validate (Float32s.Collection.Array) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.I.equal``() = + [] + member _.``Float32s.Collection.Array C.I.equal``() = validate (Float32s.Collection.Array) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.I.not_equal``() = + [] + member _.``Float32s.Collection.Array C.I.not_equal``() = validate (Float32s.Collection.Array) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.I.compare``() = + [] + member _.``Float32s.Collection.Array C.I.compare``() = validate (Float32s.Collection.Array) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.I.less_than``() = + [] + member _.``Float32s.Collection.Array C.I.less_than``() = validate (Float32s.Collection.Array) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.Array C.I.less_or_equal``() = validate (Float32s.Collection.Array) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.I.greater_than``() = + [] + member _.``Float32s.Collection.Array C.I.greater_than``() = validate (Float32s.Collection.Array) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.Array C.I.greater_or_equal``() = validate (Float32s.Collection.Array) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.Array C.N.equals``() = + [] + member _.``Float32s.Collection.Array C.N.equals``() = validate (Float32s.Collection.Array) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.N.equal``() = + [] + member _.``Float32s.Collection.Array C.N.equal``() = validate (Float32s.Collection.Array) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.N.not_equal``() = + [] + member _.``Float32s.Collection.Array C.N.not_equal``() = validate (Float32s.Collection.Array) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.N.compare``() = + [] + member _.``Float32s.Collection.Array C.N.compare``() = validate (Float32s.Collection.Array) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.N.less_than``() = + [] + member _.``Float32s.Collection.Array C.N.less_than``() = validate (Float32s.Collection.Array) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.Array C.N.less_or_equal``() = validate (Float32s.Collection.Array) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.Array C.N.greater_than``() = + [] + member _.``Float32s.Collection.Array C.N.greater_than``() = validate (Float32s.Collection.Array) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.Array C.N.greater_or_equal``() = validate (Float32s.Collection.Array) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.OptionArray C.I.equals``() = + [] + member _.``Float32s.Collection.OptionArray C.I.equals``() = validate (Float32s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.I.equal``() = + [] + member _.``Float32s.Collection.OptionArray C.I.equal``() = validate (Float32s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.I.not_equal``() = validate (Float32s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.I.compare``() = + [] + member _.``Float32s.Collection.OptionArray C.I.compare``() = validate (Float32s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1;-1;-1;1;1;0;1;1;1;-1;1;1;1;1;1;-1;0;1;1;-1;1;1;-1; 1;-1;-1;-1;0;-1;-1;-1;-1;-1;1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;-1;-1;1;1;-1;0;-1;-1; 1;1;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;1;-1;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Float32s.Collection.OptionArray C.I.less_than``() = validate (Float32s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1; 0;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0;1;0;0;0 |] - [] - member __.``Float32s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.I.less_or_equal``() = validate (Float32s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1;1;1;0;0;1;0;0;0;1;0;0;0;0;0;1;1;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;1;1;1;1; 0;0;1;1;0;0;1;0;1;1;0;0;1;0;0;0;1;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.OptionArray C.I.greater_than``() = validate (Float32s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;0;1;0;1;0;1;1;1;1;1;0;0;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;0;0;1;0;0;0;0; 1;1;0;0;0;1;0;1;0;0;1;1;0;1;0;1;0;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.I.greater_or_equal``() = validate (Float32s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;1;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;1;0;1;0;0; 1;1;0;0;0;1;0;1;1;0;1;1;0;1;0;1;0;1;1;1 |] - [] - member __.``Float32s.Collection.OptionArray C.N.equals``() = + [] + member _.``Float32s.Collection.OptionArray C.N.equals``() = validate (Float32s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.N.equal``() = + [] + member _.``Float32s.Collection.OptionArray C.N.equal``() = validate (Float32s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.N.not_equal``() = validate (Float32s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.N.compare``() = + [] + member _.``Float32s.Collection.OptionArray C.N.compare``() = validate (Float32s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;1;-1;-1;-1;-1;1;1;0;1;1;1;-1;1;1;1;1;1;-1;0;1;1;-1;1;1;-1; 1;-1;-1;-1;0;-1;-1;-1;-1;-1;1;-1;-1;-1;1;0;-1;-1;-1;-1;1;1;1;1;1;1;0;1;1;1;1;1;-1;-1;1;1;-1;0;-1;-1; 1;1;-1;-1;1;1;-1;1;0;-1;1;1;-1;1;1;1;-1;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Float32s.Collection.OptionArray C.N.less_than``() = validate (Float32s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1; 0;0;1;1;0;0;1;0;0;1;0;0;1;0;0;0;1;0;0;0 |] - [] - member __.``Float32s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.N.less_or_equal``() = validate (Float32s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;0;1;1;1;0;0;1;1;1;1;0;0;1;0;0;0;1;0;0;0;0;0;1;1;0;0;1;0;0;1; 0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;1;0;0;0;0;0;1;1;0;0;1;1;1;1; 0;0;1;1;0;0;1;0;1;1;0;0;1;0;0;0;1;0;0;1 |] - [] - member __.``Float32s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.OptionArray C.N.greater_than``() = validate (Float32s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;0;1;0;1;0;1;1;1;1;1;0;0;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;0;0;1;0;0;0;0; 1;1;0;0;0;1;0;1;0;0;1;1;0;1;0;1;0;1;1;0 |] - [] - member __.``Float32s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.OptionArray C.N.greater_or_equal``() = validate (Float32s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0;0;0;1;1;1;1;0;1;0;1;1;1;1;1;0;1;0;1;0;1;1;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;0;0;0;1;0;1;0;0; 1;1;0;0;0;1;0;1;1;0;1;1;0;1;0;1;0;1;1;1 |] - [] - member __.``Float32s.Collection.RefArray C.I.equals``() = + [] + member _.``Float32s.Collection.RefArray C.I.equals``() = validate (Float32s.Collection.RefArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.I.equal``() = + [] + member _.``Float32s.Collection.RefArray C.I.equal``() = validate (Float32s.Collection.RefArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.RefArray C.I.not_equal``() = validate (Float32s.Collection.RefArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.I.compare``() = + [] + member _.``Float32s.Collection.RefArray C.I.compare``() = validate (Float32s.Collection.RefArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.I.less_than``() = + [] + member _.``Float32s.Collection.RefArray C.I.less_than``() = validate (Float32s.Collection.RefArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.RefArray C.I.less_or_equal``() = validate (Float32s.Collection.RefArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.RefArray C.I.greater_than``() = validate (Float32s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.RefArray C.I.greater_or_equal``() = validate (Float32s.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.RefArray C.N.equals``() = + [] + member _.``Float32s.Collection.RefArray C.N.equals``() = validate (Float32s.Collection.RefArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.N.equal``() = + [] + member _.``Float32s.Collection.RefArray C.N.equal``() = validate (Float32s.Collection.RefArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.RefArray C.N.not_equal``() = validate (Float32s.Collection.RefArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.N.compare``() = + [] + member _.``Float32s.Collection.RefArray C.N.compare``() = validate (Float32s.Collection.RefArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.N.less_than``() = + [] + member _.``Float32s.Collection.RefArray C.N.less_than``() = validate (Float32s.Collection.RefArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.RefArray C.N.less_or_equal``() = validate (Float32s.Collection.RefArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.RefArray C.N.greater_than``() = validate (Float32s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.RefArray C.N.greater_or_equal``() = validate (Float32s.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.equals``() = validate (Float32s.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.equal``() = validate (Float32s.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.not_equal``() = validate (Float32s.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.compare``() = validate (Float32s.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.less_than``() = validate (Float32s.Collection.RefWrapArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Float32s.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.greater_than``() = validate (Float32s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Float32s.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.equals``() = validate (Float32s.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.equal``() = validate (Float32s.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.not_equal``() = validate (Float32s.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.compare``() = validate (Float32s.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.less_than``() = validate (Float32s.Collection.RefWrapArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Float32s.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.greater_than``() = validate (Float32s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Float32s.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.UnionArray C.I.equals``() = + [] + member _.``Float32s.Collection.UnionArray C.I.equals``() = validate (Float32s.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -47915,8 +47915,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.I.equal``() = + [] + member _.``Float32s.Collection.UnionArray C.I.equal``() = validate (Float32s.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -48020,8 +48020,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.I.not_equal``() = validate (Float32s.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -48125,8 +48125,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.I.compare``() = + [] + member _.``Float32s.Collection.UnionArray C.I.compare``() = validate (Float32s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -48230,8 +48230,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Float32s.Collection.UnionArray C.I.less_than``() = validate (Float32s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -48335,8 +48335,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Float32s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.I.less_or_equal``() = validate (Float32s.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -48440,8 +48440,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.UnionArray C.I.greater_than``() = validate (Float32s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -48545,8 +48545,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.I.greater_or_equal``() = validate (Float32s.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -48650,8 +48650,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Float32s.Collection.UnionArray C.N.equals``() = + [] + member _.``Float32s.Collection.UnionArray C.N.equals``() = validate (Float32s.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -48755,8 +48755,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.N.equal``() = + [] + member _.``Float32s.Collection.UnionArray C.N.equal``() = validate (Float32s.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -48860,8 +48860,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.N.not_equal``() = validate (Float32s.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -48965,8 +48965,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.N.compare``() = + [] + member _.``Float32s.Collection.UnionArray C.N.compare``() = validate (Float32s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -49070,8 +49070,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Float32s.Collection.UnionArray C.N.less_than``() = validate (Float32s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -49175,8 +49175,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Float32s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.N.less_or_equal``() = validate (Float32s.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -49280,8 +49280,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.UnionArray C.N.greater_than``() = validate (Float32s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -49385,8 +49385,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.UnionArray C.N.greater_or_equal``() = validate (Float32s.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -49490,8 +49490,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.equals``() = validate (Float32s.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -49595,8 +49595,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.equal``() = validate (Float32s.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -49700,8 +49700,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.not_equal``() = validate (Float32s.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -49805,8 +49805,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.compare``() = validate (Float32s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -49910,8 +49910,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.less_than``() = validate (Float32s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -50015,8 +50015,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Float32s.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -50120,8 +50120,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.greater_than``() = validate (Float32s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -50225,8 +50225,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Float32s.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -50330,8 +50330,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.equals``() = validate (Float32s.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -50435,8 +50435,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.equal``() = validate (Float32s.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -50540,8 +50540,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.not_equal``() = validate (Float32s.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -50645,8 +50645,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.compare``() = validate (Float32s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3; -3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1; @@ -50750,8 +50750,8 @@ type GeneratedTestSuite () = 1;1;3;2;1;3;2;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.less_than``() = validate (Float32s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -50855,8 +50855,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Float32s.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1; @@ -50960,8 +50960,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;1 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.greater_than``() = validate (Float32s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -51065,8 +51065,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;0 |] - [] - member __.``Float32s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Float32s.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0; @@ -51170,264 +51170,264 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1 |] - [] - member __.``Float32s.Collection.ValueArray C.I.equals``() = + [] + member _.``Float32s.Collection.ValueArray C.I.equals``() = validate (Float32s.Collection.ValueArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.I.equal``() = + [] + member _.``Float32s.Collection.ValueArray C.I.equal``() = validate (Float32s.Collection.ValueArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.I.not_equal``() = validate (Float32s.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.I.compare``() = + [] + member _.``Float32s.Collection.ValueArray C.I.compare``() = validate (Float32s.Collection.ValueArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Float32s.Collection.ValueArray C.I.less_than``() = validate (Float32s.Collection.ValueArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.I.less_or_equal``() = validate (Float32s.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.ValueArray C.I.greater_than``() = validate (Float32s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.I.greater_or_equal``() = validate (Float32s.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.N.equals``() = + [] + member _.``Float32s.Collection.ValueArray C.N.equals``() = validate (Float32s.Collection.ValueArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.N.equal``() = + [] + member _.``Float32s.Collection.ValueArray C.N.equal``() = validate (Float32s.Collection.ValueArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.N.not_equal``() = validate (Float32s.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.N.compare``() = + [] + member _.``Float32s.Collection.ValueArray C.N.compare``() = validate (Float32s.Collection.ValueArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Float32s.Collection.ValueArray C.N.less_than``() = validate (Float32s.Collection.ValueArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.N.less_or_equal``() = validate (Float32s.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.ValueArray C.N.greater_than``() = validate (Float32s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.ValueArray C.N.greater_or_equal``() = validate (Float32s.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.equals``() = validate (Float32s.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.equal``() = validate (Float32s.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.not_equal``() = validate (Float32s.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.compare``() = validate (Float32s.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.less_than``() = validate (Float32s.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Float32s.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.greater_than``() = validate (Float32s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Float32s.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.equals``() = validate (Float32s.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.equal``() = validate (Float32s.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.not_equal``() = validate (Float32s.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.compare``() = validate (Float32s.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;0;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;1; 0;-1;-1;-1;-1;1;1;1;1;1;0;1;1;1;1;-1;-1;1;1;-1;0;-1;-1;1;-1;-1;1;1;-1;1;0;-1;1;-1;1;1;1;-1;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.less_than``() = validate (Float32s.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;0;1;0;0; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Float32s.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;1;1;1;0; 1;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;1;0;1;0;0;0;1;0;0; 1 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.greater_than``() = validate (Float32s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;0;1;0;1;0;1;0;1;1; 0 |] - [] - member __.``Float32s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Float32s.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 1;0;0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;1;0;1;0;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;1;1; 1 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.equals``() = validate (Float32s.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51440,8 +51440,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.equal``() = validate (Float32s.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51454,8 +51454,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.not_equal``() = validate (Float32s.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -51468,8 +51468,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.compare``() = validate (Float32s.Collection.ArrayArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;-1;0;1; 1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -51482,8 +51482,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.less_than``() = validate (Float32s.Collection.ArrayArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;0;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -51496,8 +51496,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.less_or_equal``() = validate (Float32s.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -51510,8 +51510,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.greater_than``() = validate (Float32s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -51524,8 +51524,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Float32s.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;1;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51538,8 +51538,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.equals``() = validate (Float32s.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51552,8 +51552,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.equal``() = validate (Float32s.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51566,8 +51566,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.not_equal``() = validate (Float32s.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -51580,8 +51580,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.compare``() = validate (Float32s.Collection.ArrayArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;-1;0;1; 1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -51594,8 +51594,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.less_than``() = validate (Float32s.Collection.ArrayArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;0;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -51608,8 +51608,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.less_or_equal``() = validate (Float32s.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;0;0;1;0;0;0;1;1;1;1;1;1;1;1;1;0;1;1;0; 0;1;0;0;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -51622,8 +51622,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.greater_than``() = validate (Float32s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;0;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -51636,8 +51636,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Float32s.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;0;0;0;0;0;1;0;1;0; 1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51650,8 +51650,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Float32s.Collection.ListArray C.I.equals``() = + [] + member _.``Float32s.Collection.ListArray C.I.equals``() = validate (Float32s.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51664,8 +51664,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.I.equal``() = + [] + member _.``Float32s.Collection.ListArray C.I.equal``() = validate (Float32s.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51678,8 +51678,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.ListArray C.I.not_equal``() = validate (Float32s.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -51692,8 +51692,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.I.compare``() = + [] + member _.``Float32s.Collection.ListArray C.I.compare``() = validate (Float32s.Collection.ListArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;1;1;1;-1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;-1;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -51706,8 +51706,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.I.less_than``() = + [] + member _.``Float32s.Collection.ListArray C.I.less_than``() = validate (Float32s.Collection.ListArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1; @@ -51720,8 +51720,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Float32s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.ListArray C.I.less_or_equal``() = validate (Float32s.Collection.ListArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1; @@ -51734,8 +51734,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.ListArray C.I.greater_than``() = validate (Float32s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;0;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -51748,8 +51748,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.ListArray C.I.greater_or_equal``() = validate (Float32s.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;1;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51762,8 +51762,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Float32s.Collection.ListArray C.N.equals``() = + [] + member _.``Float32s.Collection.ListArray C.N.equals``() = validate (Float32s.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51776,8 +51776,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.N.equal``() = + [] + member _.``Float32s.Collection.ListArray C.N.equal``() = validate (Float32s.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51790,8 +51790,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.ListArray C.N.not_equal``() = validate (Float32s.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -51804,8 +51804,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.N.compare``() = + [] + member _.``Float32s.Collection.ListArray C.N.compare``() = validate (Float32s.Collection.ListArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;-1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;-1;1;1;1;-1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;-1;1;1;-1;1;1;-1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -51818,8 +51818,8 @@ type GeneratedTestSuite () = -1;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.N.less_than``() = + [] + member _.``Float32s.Collection.ListArray C.N.less_than``() = validate (Float32s.Collection.ListArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;0;1;1;1; @@ -51832,8 +51832,8 @@ type GeneratedTestSuite () = 1;0;0;0 |] - [] - member __.``Float32s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.ListArray C.N.less_or_equal``() = validate (Float32s.Collection.ListArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;1;0;0;0;1;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1; @@ -51846,8 +51846,8 @@ type GeneratedTestSuite () = 1;0;0;1 |] - [] - member __.``Float32s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.ListArray C.N.greater_than``() = validate (Float32s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;0;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -51860,8 +51860,8 @@ type GeneratedTestSuite () = 0;1;1;0 |] - [] - member __.``Float32s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.ListArray C.N.greater_or_equal``() = validate (Float32s.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;1;0; 1;0;1;1;0;1;0;0;0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51874,8 +51874,8 @@ type GeneratedTestSuite () = 0;1;1;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51888,8 +51888,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -51902,8 +51902,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -51916,8 +51916,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;1;1;1;1;1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;1;1;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -51930,8 +51930,8 @@ type GeneratedTestSuite () = -1;-1;-1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -51944,8 +51944,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -51958,8 +51958,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -51972,8 +51972,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; @@ -51986,8 +51986,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -52000,8 +52000,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; @@ -52014,8 +52014,8 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; @@ -52028,8 +52028,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;1;1;-1;-1;-1;-1;-1;-1;1;1;1;-1;-1;-1;-1;1;0;1;1;1;-1;1;1;1;1;1;1;1;1;1;1;1;1;1;-1;0;1; 1;-1;1;1;-1;1;-1;1;1;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1; @@ -52042,8 +52042,8 @@ type GeneratedTestSuite () = -1;-1;-1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1; @@ -52056,8 +52056,8 @@ type GeneratedTestSuite () = 1;1;1;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;0;0;1;1;1;1;1;1;0;0;0;1;1;1;1;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0; 0;1;0;0;1;0;1;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1; @@ -52070,8 +52070,8 @@ type GeneratedTestSuite () = 1;1;1;1 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;0;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0; @@ -52084,8 +52084,8 @@ type GeneratedTestSuite () = 0;0;0;0 |] - [] - member __.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Float32s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Float32s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;1;1;0;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;0;1;1;0;1;0;1;1;1;1;1;1;1;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0; @@ -52098,56 +52098,56 @@ type GeneratedTestSuite () = 0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.Array E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.Array E.I.equals``() = validate (NullableFloat32s.Collection.Array) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.Array E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.Array E.I.equal``() = validate (NullableFloat32s.Collection.Array) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.Array E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.Array E.I.not_equal``() = validate (NullableFloat32s.Collection.Array) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.Array E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.Array E.N.equals``() = validate (NullableFloat32s.Collection.Array) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.Array E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.Array E.N.equal``() = validate (NullableFloat32s.Collection.Array) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.Array E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.Array E.N.not_equal``() = validate (NullableFloat32s.Collection.Array) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.I.equals``() = validate (NullableFloat32s.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -52155,8 +52155,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.I.equal``() = validate (NullableFloat32s.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -52164,8 +52164,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.I.not_equal``() = validate (NullableFloat32s.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -52173,8 +52173,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.N.equals``() = validate (NullableFloat32s.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -52182,8 +52182,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.N.equal``() = validate (NullableFloat32s.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0; @@ -52191,8 +52191,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``NullableFloat32s.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.OptionArray E.N.not_equal``() = validate (NullableFloat32s.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1; @@ -52200,104 +52200,104 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.I.equals``() = validate (NullableFloat32s.Collection.RefArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.I.equal``() = validate (NullableFloat32s.Collection.RefArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.I.not_equal``() = validate (NullableFloat32s.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.N.equals``() = validate (NullableFloat32s.Collection.RefArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.N.equal``() = validate (NullableFloat32s.Collection.RefArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.RefArray E.N.not_equal``() = validate (NullableFloat32s.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.I.equals``() = validate (NullableFloat32s.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.I.equal``() = validate (NullableFloat32s.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.I.not_equal``() = validate (NullableFloat32s.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.N.equals``() = validate (NullableFloat32s.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.N.equal``() = validate (NullableFloat32s.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.RefWrapArray E.N.not_equal``() = validate (NullableFloat32s.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.I.equals``() = validate (NullableFloat32s.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -52424,8 +52424,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.I.equal``() = validate (NullableFloat32s.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -52552,8 +52552,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.I.not_equal``() = validate (NullableFloat32s.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -52680,8 +52680,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.N.equals``() = validate (NullableFloat32s.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -52808,8 +52808,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.N.equal``() = validate (NullableFloat32s.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -52936,8 +52936,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.UnionArray E.N.not_equal``() = validate (NullableFloat32s.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -53064,8 +53064,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.I.equals``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -53192,8 +53192,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.I.equal``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -53320,8 +53320,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -53448,8 +53448,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.N.equals``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -53576,8 +53576,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.N.equal``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; @@ -53704,8 +53704,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableFloat32s.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1; @@ -53832,104 +53832,104 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.I.equals``() = validate (NullableFloat32s.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.I.equal``() = validate (NullableFloat32s.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.I.not_equal``() = validate (NullableFloat32s.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.N.equals``() = validate (NullableFloat32s.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.N.equal``() = validate (NullableFloat32s.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ValueArray E.N.not_equal``() = validate (NullableFloat32s.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.I.equals``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.I.equal``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.N.equals``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.N.equal``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1;0;0; 0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableFloat32s.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0;1;1; 1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.I.equals``() = validate (NullableFloat32s.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -53943,8 +53943,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.I.equal``() = validate (NullableFloat32s.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -53958,8 +53958,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.I.not_equal``() = validate (NullableFloat32s.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -53973,8 +53973,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.N.equals``() = validate (NullableFloat32s.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -53988,8 +53988,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.N.equal``() = validate (NullableFloat32s.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54003,8 +54003,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ArrayArray E.N.not_equal``() = validate (NullableFloat32s.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54018,8 +54018,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.I.equals``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.I.equals``() = validate (NullableFloat32s.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54033,8 +54033,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.I.equal``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.I.equal``() = validate (NullableFloat32s.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54048,8 +54048,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.I.not_equal``() = validate (NullableFloat32s.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54063,8 +54063,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.N.equals``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.N.equals``() = validate (NullableFloat32s.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54078,8 +54078,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.N.equal``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.N.equal``() = validate (NullableFloat32s.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54093,8 +54093,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableFloat32s.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableFloat32s.Collection.ListArray E.N.not_equal``() = validate (NullableFloat32s.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54108,392 +54108,392 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.Array C.I.equals``() = + [] + member _.``DateTimes.Collection.Array C.I.equals``() = validate (DateTimes.Collection.Array) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.Array C.I.equal``() = + [] + member _.``DateTimes.Collection.Array C.I.equal``() = validate (DateTimes.Collection.Array) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.Array C.I.not_equal``() = + [] + member _.``DateTimes.Collection.Array C.I.not_equal``() = validate (DateTimes.Collection.Array) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.Array C.I.compare``() = + [] + member _.``DateTimes.Collection.Array C.I.compare``() = validate (DateTimes.Collection.Array) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.Array C.I.less_than``() = + [] + member _.``DateTimes.Collection.Array C.I.less_than``() = validate (DateTimes.Collection.Array) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.Array C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.Array C.I.less_or_equal``() = validate (DateTimes.Collection.Array) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.Array C.I.greater_than``() = + [] + member _.``DateTimes.Collection.Array C.I.greater_than``() = validate (DateTimes.Collection.Array) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.Array C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.Array C.I.greater_or_equal``() = validate (DateTimes.Collection.Array) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.Array C.N.equals``() = + [] + member _.``DateTimes.Collection.Array C.N.equals``() = validate (DateTimes.Collection.Array) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.Array C.N.equal``() = + [] + member _.``DateTimes.Collection.Array C.N.equal``() = validate (DateTimes.Collection.Array) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.Array C.N.not_equal``() = + [] + member _.``DateTimes.Collection.Array C.N.not_equal``() = validate (DateTimes.Collection.Array) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.Array C.N.compare``() = + [] + member _.``DateTimes.Collection.Array C.N.compare``() = validate (DateTimes.Collection.Array) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.Array C.N.less_than``() = + [] + member _.``DateTimes.Collection.Array C.N.less_than``() = validate (DateTimes.Collection.Array) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.Array C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.Array C.N.less_or_equal``() = validate (DateTimes.Collection.Array) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.Array C.N.greater_than``() = + [] + member _.``DateTimes.Collection.Array C.N.greater_than``() = validate (DateTimes.Collection.Array) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.Array C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.Array C.N.greater_or_equal``() = validate (DateTimes.Collection.Array) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.equals``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.equals``() = validate (DateTimes.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.equal``() = validate (DateTimes.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.not_equal``() = validate (DateTimes.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.compare``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.compare``() = validate (DateTimes.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.less_than``() = validate (DateTimes.Collection.OptionArray) C.I.less_than [| 0;1;1;1;0;0;1;1;0;0;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.less_or_equal``() = validate (DateTimes.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;0;0;0;1;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.greater_than``() = validate (DateTimes.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;1;1;1;0;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.I.greater_or_equal``() = validate (DateTimes.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.equals``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.equals``() = validate (DateTimes.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.equal``() = validate (DateTimes.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.not_equal``() = validate (DateTimes.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.compare``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.compare``() = validate (DateTimes.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.less_than``() = validate (DateTimes.Collection.OptionArray) C.N.less_than [| 0;1;1;1;0;0;1;1;0;0;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.less_or_equal``() = validate (DateTimes.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;0;1;1;1;0;0;1;0;0;0;1;1 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.greater_than``() = validate (DateTimes.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;1;0;0;0;1;1;0;1;1;1;0;0 |] - [] - member __.``DateTimes.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.OptionArray C.N.greater_or_equal``() = validate (DateTimes.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;1;1;0;0;1;1;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.I.equals``() = + [] + member _.``DateTimes.Collection.RefArray C.I.equals``() = validate (DateTimes.Collection.RefArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.I.equal``() = + [] + member _.``DateTimes.Collection.RefArray C.I.equal``() = validate (DateTimes.Collection.RefArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.I.not_equal``() = validate (DateTimes.Collection.RefArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.I.compare``() = + [] + member _.``DateTimes.Collection.RefArray C.I.compare``() = validate (DateTimes.Collection.RefArray) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.RefArray C.I.less_than``() = validate (DateTimes.Collection.RefArray) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.I.less_or_equal``() = validate (DateTimes.Collection.RefArray) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.RefArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.RefArray C.I.greater_than``() = validate (DateTimes.Collection.RefArray) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.I.greater_or_equal``() = validate (DateTimes.Collection.RefArray) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.N.equals``() = + [] + member _.``DateTimes.Collection.RefArray C.N.equals``() = validate (DateTimes.Collection.RefArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.N.equal``() = + [] + member _.``DateTimes.Collection.RefArray C.N.equal``() = validate (DateTimes.Collection.RefArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.N.not_equal``() = validate (DateTimes.Collection.RefArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.N.compare``() = + [] + member _.``DateTimes.Collection.RefArray C.N.compare``() = validate (DateTimes.Collection.RefArray) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.RefArray C.N.less_than``() = validate (DateTimes.Collection.RefArray) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.N.less_or_equal``() = validate (DateTimes.Collection.RefArray) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.RefArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.RefArray C.N.greater_than``() = validate (DateTimes.Collection.RefArray) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.RefArray C.N.greater_or_equal``() = validate (DateTimes.Collection.RefArray) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.equals``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.equals``() = validate (DateTimes.Collection.RefWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.equal``() = validate (DateTimes.Collection.RefWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.not_equal``() = validate (DateTimes.Collection.RefWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.compare``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.compare``() = validate (DateTimes.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.less_than``() = validate (DateTimes.Collection.RefWrapArray) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.less_or_equal``() = validate (DateTimes.Collection.RefWrapArray) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.greater_than``() = validate (DateTimes.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.I.greater_or_equal``() = validate (DateTimes.Collection.RefWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.equals``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.equals``() = validate (DateTimes.Collection.RefWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.equal``() = validate (DateTimes.Collection.RefWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.not_equal``() = validate (DateTimes.Collection.RefWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.compare``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.compare``() = validate (DateTimes.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.less_than``() = validate (DateTimes.Collection.RefWrapArray) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.less_or_equal``() = validate (DateTimes.Collection.RefWrapArray) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.greater_than``() = validate (DateTimes.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.RefWrapArray C.N.greater_or_equal``() = validate (DateTimes.Collection.RefWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.equals``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.equals``() = validate (DateTimes.Collection.UnionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54509,8 +54509,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.equal``() = validate (DateTimes.Collection.UnionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54526,8 +54526,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.not_equal``() = validate (DateTimes.Collection.UnionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54543,8 +54543,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.compare``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.compare``() = validate (DateTimes.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -54560,8 +54560,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.less_than``() = validate (DateTimes.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54577,8 +54577,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.less_or_equal``() = validate (DateTimes.Collection.UnionArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54594,8 +54594,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.greater_than``() = validate (DateTimes.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54611,8 +54611,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.I.greater_or_equal``() = validate (DateTimes.Collection.UnionArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54628,8 +54628,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.equals``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.equals``() = validate (DateTimes.Collection.UnionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54645,8 +54645,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.equal``() = validate (DateTimes.Collection.UnionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54662,8 +54662,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.not_equal``() = validate (DateTimes.Collection.UnionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54679,8 +54679,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.compare``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.compare``() = validate (DateTimes.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -54696,8 +54696,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.less_than``() = validate (DateTimes.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54713,8 +54713,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.less_or_equal``() = validate (DateTimes.Collection.UnionArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54730,8 +54730,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.greater_than``() = validate (DateTimes.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54747,8 +54747,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.UnionArray C.N.greater_or_equal``() = validate (DateTimes.Collection.UnionArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54764,8 +54764,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.equals``() = validate (DateTimes.Collection.UnionWrapArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54781,8 +54781,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.equal``() = validate (DateTimes.Collection.UnionWrapArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54798,8 +54798,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.not_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54815,8 +54815,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.compare``() = validate (DateTimes.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -54832,8 +54832,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.less_than``() = validate (DateTimes.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54849,8 +54849,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.less_or_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54866,8 +54866,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.greater_than``() = validate (DateTimes.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54883,8 +54883,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -54900,8 +54900,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.equals``() = validate (DateTimes.Collection.UnionWrapArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54917,8 +54917,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.equal``() = validate (DateTimes.Collection.UnionWrapArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -54934,8 +54934,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.not_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -54951,8 +54951,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.compare``() = validate (DateTimes.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;3;2;1;0;-1;-2;-3;3;2;1;-1;-1;-2;-3;3;2;1; @@ -54968,8 +54968,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.less_than``() = validate (DateTimes.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -54985,8 +54985,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.less_or_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -55002,8 +55002,8 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.greater_than``() = validate (DateTimes.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;0;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -55019,8 +55019,8 @@ type GeneratedTestSuite () = 0 |] - [] - member __.``DateTimes.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (DateTimes.Collection.UnionWrapArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;1;1; @@ -55036,632 +55036,632 @@ type GeneratedTestSuite () = 1 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.equals``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.equals``() = validate (DateTimes.Collection.ValueArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.equal``() = validate (DateTimes.Collection.ValueArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.not_equal``() = validate (DateTimes.Collection.ValueArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.compare``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.compare``() = validate (DateTimes.Collection.ValueArray) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.less_than``() = validate (DateTimes.Collection.ValueArray) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.less_or_equal``() = validate (DateTimes.Collection.ValueArray) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.greater_than``() = validate (DateTimes.Collection.ValueArray) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.I.greater_or_equal``() = validate (DateTimes.Collection.ValueArray) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.equals``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.equals``() = validate (DateTimes.Collection.ValueArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.equal``() = validate (DateTimes.Collection.ValueArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.not_equal``() = validate (DateTimes.Collection.ValueArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.compare``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.compare``() = validate (DateTimes.Collection.ValueArray) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.less_than``() = validate (DateTimes.Collection.ValueArray) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.less_or_equal``() = validate (DateTimes.Collection.ValueArray) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.greater_than``() = validate (DateTimes.Collection.ValueArray) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ValueArray C.N.greater_or_equal``() = validate (DateTimes.Collection.ValueArray) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.equals``() = validate (DateTimes.Collection.ValueWrapArray) C.I.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.equal``() = validate (DateTimes.Collection.ValueWrapArray) C.I.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.not_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.I.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.compare``() = validate (DateTimes.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.less_than``() = validate (DateTimes.Collection.ValueWrapArray) C.I.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.less_or_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.I.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.greater_than``() = validate (DateTimes.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.I.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.equals``() = validate (DateTimes.Collection.ValueWrapArray) C.N.equals [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.equal``() = validate (DateTimes.Collection.ValueWrapArray) C.N.equal [| 1;0;0;0;1;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.not_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.N.not_equal [| 0;1;1;1;0;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.compare``() = validate (DateTimes.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;1;0;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.less_than``() = validate (DateTimes.Collection.ValueWrapArray) C.N.less_than [| 0;1;1;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.less_or_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.N.less_or_equal [| 1;1;1;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.greater_than``() = validate (DateTimes.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (DateTimes.Collection.ValueWrapArray) C.N.greater_or_equal [| 1;0;0;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.equals``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.equals``() = validate (DateTimes.Collection.ArrayArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.equal``() = validate (DateTimes.Collection.ArrayArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.not_equal``() = validate (DateTimes.Collection.ArrayArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.compare``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.compare``() = validate (DateTimes.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;1;-1;-1;-1;1;-1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;1;1;1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.less_than``() = validate (DateTimes.Collection.ArrayArray) C.I.less_than [| 0;1;1;1;1;1;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.less_or_equal``() = validate (DateTimes.Collection.ArrayArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;0;1;1;1;0;1;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;0;0;0;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.greater_than``() = validate (DateTimes.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;1;0;0;0;1;0;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;1;1;1;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.I.greater_or_equal``() = validate (DateTimes.Collection.ArrayArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;1;0;0;0;1;0;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.equals``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.equals``() = validate (DateTimes.Collection.ArrayArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.equal``() = validate (DateTimes.Collection.ArrayArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.not_equal``() = validate (DateTimes.Collection.ArrayArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.compare``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.compare``() = validate (DateTimes.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;1;-1;-1;-1;1;-1;0;-1;-1;-1;1;1;1;0;-1;-1;1;1;1;1;0;1;1;1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.less_than``() = validate (DateTimes.Collection.ArrayArray) C.N.less_than [| 0;1;1;1;1;1;0;0;0;1;1;1;0;1;0;1;1;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.less_or_equal``() = validate (DateTimes.Collection.ArrayArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;0;1;1;1;0;1;1;1;1;1;0;0;0;1;1;1;0;0;0;0;1;0;0;0;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.greater_than``() = validate (DateTimes.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;1;0;0;0;1;0;0;0;0;0;1;1;1;0;0;0;1;1;1;1;0;1;1;1;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray C.N.greater_or_equal``() = validate (DateTimes.Collection.ArrayArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;1;0;0;0;1;0;1;0;0;0;1;1;1;1;0;0;1;1;1;1;1;1;1;1;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.I.equals``() = + [] + member _.``DateTimes.Collection.ListArray C.I.equals``() = validate (DateTimes.Collection.ListArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.I.equal``() = + [] + member _.``DateTimes.Collection.ListArray C.I.equal``() = validate (DateTimes.Collection.ListArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.I.not_equal``() = validate (DateTimes.Collection.ListArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.I.compare``() = + [] + member _.``DateTimes.Collection.ListArray C.I.compare``() = validate (DateTimes.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;1;1;-1;1;1;-1;0;1;-1;-1;1;-1;-1;0;-1;-1;1;1;1;1;0;1;1;-1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.ListArray C.I.less_than``() = validate (DateTimes.Collection.ListArray) C.I.less_than [| 0;1;1;1;1;1;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;0;0;0;0;0;0;0;1;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.I.less_or_equal``() = validate (DateTimes.Collection.ListArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;0;0;0;0;1;0;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ListArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.ListArray C.I.greater_than``() = validate (DateTimes.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;1;1;1;1;0;1;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.I.greater_or_equal``() = validate (DateTimes.Collection.ListArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;1;1;1;1;1;1;1;0;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.N.equals``() = + [] + member _.``DateTimes.Collection.ListArray C.N.equals``() = validate (DateTimes.Collection.ListArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.N.equal``() = + [] + member _.``DateTimes.Collection.ListArray C.N.equal``() = validate (DateTimes.Collection.ListArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ListArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.N.not_equal``() = validate (DateTimes.Collection.ListArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.N.compare``() = + [] + member _.``DateTimes.Collection.ListArray C.N.compare``() = validate (DateTimes.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;1;1;-1;1;1;-1;0;1;-1;-1;1;-1;-1;0;-1;-1;1;1;1;1;0;1;1;-1;1;1;-1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.ListArray C.N.less_than``() = validate (DateTimes.Collection.ListArray) C.N.less_than [| 0;1;1;1;1;1;0;0;0;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;0;0;0;0;0;0;0;1;0;0;1;0 |] - [] - member __.``DateTimes.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.N.less_or_equal``() = validate (DateTimes.Collection.ListArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;0;0;1;0;0;1;1;0;1;1;0;1;1;1;1;1;0;0;0;0;1;0;0;1;0;0;1;1 |] - [] - member __.``DateTimes.Collection.ListArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.ListArray C.N.greater_than``() = validate (DateTimes.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;0;0;0;1;1;1;1;0;1;1;0;1;1;0;0 |] - [] - member __.``DateTimes.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ListArray C.N.greater_or_equal``() = validate (DateTimes.Collection.ListArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;0;1;1;1;1;1;1;1;0;1;1;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;-1;0;1;-1;1;1;-1;-1;0;-1;1;1;-1;1;1;0;1;1;-1;-1;-1;-1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;0;0;1;0;0;0;0;0;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;0;0;1;0;0;1;0;0;1;1;1;1;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;1;1;0;1;1;0;1;1;0;0;0;0;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;1;1;0;1;1;1;1;1;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;1;0;1;1;1;1;1;-1;0;1;-1;1;1;-1;-1;0;-1;1;1;-1;1;1;0;1;1;-1;-1;-1;-1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;0;0;0;0;0;0;0;1;0;0;1;0;0;1;1;0;1;0;0;1;0;0;0;0;0;1;1;1;1;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;0;1;0;0;0;0;0;1;1;0;1;0;0;1;1;1;1;0;0;1;0;0;1;0;0;1;1;1;1;1 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;1;0;1;1;1;1;1;0;0;1;0;1;1;0;0;0;0;1;1;0;1;1;0;1;1;0;0;0;0;0 |] - [] - member __.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``DateTimes.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (DateTimes.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;0;1;1;0;0;1;0;1;1;0;1;1;1;1;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.Array E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.Array E.I.equals``() = validate (NullableDateTimes.Collection.Array) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.Array E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.Array E.I.equal``() = validate (NullableDateTimes.Collection.Array) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.Array E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.Array E.I.not_equal``() = validate (NullableDateTimes.Collection.Array) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.Array E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.Array E.N.equals``() = validate (NullableDateTimes.Collection.Array) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.Array E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.Array E.N.equal``() = validate (NullableDateTimes.Collection.Array) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.Array E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.Array E.N.not_equal``() = validate (NullableDateTimes.Collection.Array) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.I.equals``() = validate (NullableDateTimes.Collection.OptionArray) E.I.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.I.equal``() = validate (NullableDateTimes.Collection.OptionArray) E.I.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.I.not_equal``() = validate (NullableDateTimes.Collection.OptionArray) E.I.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.N.equals``() = validate (NullableDateTimes.Collection.OptionArray) E.N.equals [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.N.equal``() = validate (NullableDateTimes.Collection.OptionArray) E.N.equal [| 1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.OptionArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.OptionArray E.N.not_equal``() = validate (NullableDateTimes.Collection.OptionArray) E.N.not_equal [| 0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.I.equals``() = validate (NullableDateTimes.Collection.RefArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.I.equal``() = validate (NullableDateTimes.Collection.RefArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.I.not_equal``() = validate (NullableDateTimes.Collection.RefArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.N.equals``() = validate (NullableDateTimes.Collection.RefArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.N.equal``() = validate (NullableDateTimes.Collection.RefArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.RefArray E.N.not_equal``() = validate (NullableDateTimes.Collection.RefArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.I.equals``() = validate (NullableDateTimes.Collection.RefWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.I.equal``() = validate (NullableDateTimes.Collection.RefWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.I.not_equal``() = validate (NullableDateTimes.Collection.RefWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.N.equals``() = validate (NullableDateTimes.Collection.RefWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.N.equal``() = validate (NullableDateTimes.Collection.RefWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.RefWrapArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.RefWrapArray E.N.not_equal``() = validate (NullableDateTimes.Collection.RefWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.I.equals``() = validate (NullableDateTimes.Collection.UnionArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55685,8 +55685,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.I.equal``() = validate (NullableDateTimes.Collection.UnionArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55710,8 +55710,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.I.not_equal``() = validate (NullableDateTimes.Collection.UnionArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -55735,8 +55735,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.N.equals``() = validate (NullableDateTimes.Collection.UnionArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55760,8 +55760,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.N.equal``() = validate (NullableDateTimes.Collection.UnionArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55785,8 +55785,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.UnionArray E.N.not_equal``() = validate (NullableDateTimes.Collection.UnionArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -55810,8 +55810,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.I.equals``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55835,8 +55835,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.I.equal``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55860,8 +55860,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.I.not_equal``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -55885,8 +55885,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.N.equals``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55910,8 +55910,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.N.equal``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -55935,8 +55935,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.UnionWrapArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.UnionWrapArray E.N.not_equal``() = validate (NullableDateTimes.Collection.UnionWrapArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -55960,548 +55960,548 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.I.equals``() = validate (NullableDateTimes.Collection.ValueArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.I.equal``() = validate (NullableDateTimes.Collection.ValueArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.I.not_equal``() = validate (NullableDateTimes.Collection.ValueArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.N.equals``() = validate (NullableDateTimes.Collection.ValueArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.N.equal``() = validate (NullableDateTimes.Collection.ValueArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ValueArray E.N.not_equal``() = validate (NullableDateTimes.Collection.ValueArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.I.equals``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.I.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.I.equal``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.I.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.I.not_equal``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.I.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.N.equals``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.N.equals [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.N.equal``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.N.equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ValueWrapArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ValueWrapArray E.N.not_equal``() = validate (NullableDateTimes.Collection.ValueWrapArray) E.N.not_equal [| 0;1;1;1;1;0;1;1;1;1;0;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.I.equals``() = validate (NullableDateTimes.Collection.ArrayArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.I.equal``() = validate (NullableDateTimes.Collection.ArrayArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.I.not_equal``() = validate (NullableDateTimes.Collection.ArrayArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.N.equals``() = validate (NullableDateTimes.Collection.ArrayArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.N.equal``() = validate (NullableDateTimes.Collection.ArrayArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ArrayArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ArrayArray E.N.not_equal``() = validate (NullableDateTimes.Collection.ArrayArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.I.equals``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.I.equals``() = validate (NullableDateTimes.Collection.ListArray) E.I.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.I.equal``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.I.equal``() = validate (NullableDateTimes.Collection.ListArray) E.I.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.I.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.I.not_equal``() = validate (NullableDateTimes.Collection.ListArray) E.I.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.N.equals``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.N.equals``() = validate (NullableDateTimes.Collection.ListArray) E.N.equals [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.N.equal``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.N.equal``() = validate (NullableDateTimes.Collection.ListArray) E.N.equal [| 1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0; 0;0;0;0;0;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;1 |] - [] - member __.``NullableDateTimes.Collection.ListArray E.N.not_equal``() = + [] + member _.``NullableDateTimes.Collection.ListArray E.N.not_equal``() = validate (NullableDateTimes.Collection.ListArray) E.N.not_equal [| 0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1; 1;1;1;1;1;0;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.Array C.I.equals``() = + [] + member _.``Tuple2s.Collection.Array C.I.equals``() = validate (Tuple2s.Collection.Array) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.I.equal``() = + [] + member _.``Tuple2s.Collection.Array C.I.equal``() = validate (Tuple2s.Collection.Array) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.Array C.I.not_equal``() = validate (Tuple2s.Collection.Array) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.Array C.I.compare``() = + [] + member _.``Tuple2s.Collection.Array C.I.compare``() = validate (Tuple2s.Collection.Array) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.Array C.I.less_than``() = + [] + member _.``Tuple2s.Collection.Array C.I.less_than``() = validate (Tuple2s.Collection.Array) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.Array C.I.less_or_equal``() = validate (Tuple2s.Collection.Array) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.Array C.I.greater_than``() = validate (Tuple2s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.Array C.I.greater_or_equal``() = validate (Tuple2s.Collection.Array) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.N.equals``() = + [] + member _.``Tuple2s.Collection.Array C.N.equals``() = validate (Tuple2s.Collection.Array) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.N.equal``() = + [] + member _.``Tuple2s.Collection.Array C.N.equal``() = validate (Tuple2s.Collection.Array) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.Array C.N.not_equal``() = validate (Tuple2s.Collection.Array) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.Array C.N.compare``() = + [] + member _.``Tuple2s.Collection.Array C.N.compare``() = validate (Tuple2s.Collection.Array) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.Array C.N.less_than``() = + [] + member _.``Tuple2s.Collection.Array C.N.less_than``() = validate (Tuple2s.Collection.Array) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.Array C.N.less_or_equal``() = validate (Tuple2s.Collection.Array) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.Array C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.Array C.N.greater_than``() = validate (Tuple2s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.Array C.N.greater_or_equal``() = validate (Tuple2s.Collection.Array) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.equals``() = validate (Tuple2s.Collection.OptionArray) C.I.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.equal``() = validate (Tuple2s.Collection.OptionArray) C.I.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.not_equal``() = validate (Tuple2s.Collection.OptionArray) C.I.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.compare``() = validate (Tuple2s.Collection.OptionArray) C.I.compare [| 0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0;-1;-1;1;1;1;0;-1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.less_than``() = validate (Tuple2s.Collection.OptionArray) C.I.less_than [| 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.less_or_equal``() = validate (Tuple2s.Collection.OptionArray) C.I.less_or_equal [| 1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.greater_than``() = validate (Tuple2s.Collection.OptionArray) C.I.greater_than [| 0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.OptionArray) C.I.greater_or_equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.equals``() = validate (Tuple2s.Collection.OptionArray) C.N.equals [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.equal``() = validate (Tuple2s.Collection.OptionArray) C.N.equal [| 1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.not_equal``() = validate (Tuple2s.Collection.OptionArray) C.N.not_equal [| 0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.compare``() = validate (Tuple2s.Collection.OptionArray) C.N.compare [| 0;-1;-1;-1;-1;1;0;-1;-1;-1;1;1;0;-1;-1;1;1;1;0;-1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.less_than``() = validate (Tuple2s.Collection.OptionArray) C.N.less_than [| 0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.less_or_equal``() = validate (Tuple2s.Collection.OptionArray) C.N.less_or_equal [| 1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.greater_than``() = validate (Tuple2s.Collection.OptionArray) C.N.greater_than [| 0;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.OptionArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.OptionArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.OptionArray) C.N.greater_or_equal [| 1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.equals``() = validate (Tuple2s.Collection.RefArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.equal``() = validate (Tuple2s.Collection.RefArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.not_equal``() = validate (Tuple2s.Collection.RefArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.compare``() = validate (Tuple2s.Collection.RefArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.less_than``() = validate (Tuple2s.Collection.RefArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.less_or_equal``() = validate (Tuple2s.Collection.RefArray) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.greater_than``() = validate (Tuple2s.Collection.RefArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.RefArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.equals``() = validate (Tuple2s.Collection.RefArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.equal``() = validate (Tuple2s.Collection.RefArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.not_equal``() = validate (Tuple2s.Collection.RefArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.compare``() = validate (Tuple2s.Collection.RefArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.less_than``() = validate (Tuple2s.Collection.RefArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.less_or_equal``() = validate (Tuple2s.Collection.RefArray) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.greater_than``() = validate (Tuple2s.Collection.RefArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.RefArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.RefArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.equals``() = validate (Tuple2s.Collection.RefWrapArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.equal``() = validate (Tuple2s.Collection.RefWrapArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.not_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.compare``() = validate (Tuple2s.Collection.RefWrapArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.less_than``() = validate (Tuple2s.Collection.RefWrapArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.less_or_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.greater_than``() = validate (Tuple2s.Collection.RefWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.equals``() = validate (Tuple2s.Collection.RefWrapArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.equal``() = validate (Tuple2s.Collection.RefWrapArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.not_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.compare``() = validate (Tuple2s.Collection.RefWrapArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.less_than``() = validate (Tuple2s.Collection.RefWrapArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.less_or_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.greater_than``() = validate (Tuple2s.Collection.RefWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.RefWrapArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.RefWrapArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.RefWrapArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.equals``() = validate (Tuple2s.Collection.UnionArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56525,8 +56525,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.equal``() = validate (Tuple2s.Collection.UnionArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56550,8 +56550,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.not_equal``() = validate (Tuple2s.Collection.UnionArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -56575,8 +56575,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.compare``() = validate (Tuple2s.Collection.UnionArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1; @@ -56600,8 +56600,8 @@ type GeneratedTestSuite () = 2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.less_than``() = validate (Tuple2s.Collection.UnionArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -56625,8 +56625,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.less_or_equal``() = validate (Tuple2s.Collection.UnionArray) C.I.less_or_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -56650,8 +56650,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.greater_than``() = validate (Tuple2s.Collection.UnionArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -56675,8 +56675,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.UnionArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -56700,8 +56700,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.equals``() = validate (Tuple2s.Collection.UnionArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56725,8 +56725,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.equal``() = validate (Tuple2s.Collection.UnionArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56750,8 +56750,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.not_equal``() = validate (Tuple2s.Collection.UnionArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -56775,8 +56775,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.compare``() = validate (Tuple2s.Collection.UnionArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1; @@ -56800,8 +56800,8 @@ type GeneratedTestSuite () = 2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.less_than``() = validate (Tuple2s.Collection.UnionArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -56825,8 +56825,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.less_or_equal``() = validate (Tuple2s.Collection.UnionArray) C.N.less_or_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -56850,8 +56850,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.greater_than``() = validate (Tuple2s.Collection.UnionArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -56875,8 +56875,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.UnionArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -56900,8 +56900,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.equals``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56925,8 +56925,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -56950,8 +56950,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.not_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -56975,8 +56975,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.compare``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1; @@ -57000,8 +57000,8 @@ type GeneratedTestSuite () = 2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.less_than``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -57025,8 +57025,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.less_or_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.less_or_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -57050,8 +57050,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.greater_than``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -57075,8 +57075,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -57100,8 +57100,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.equals``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -57125,8 +57125,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -57150,8 +57150,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.not_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -57175,8 +57175,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.compare``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.compare [| 0;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;-1;-1;-2;-3;-3;-3;-3;1;0;-1;-2;-2;-2;-2;1;-1;-1;-2;-2; -2;-2;1;-1;-1;-2;-2;-2;-2;1;-1;-1;-2;-2;-2;-2;2;1;0;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1;-1;-1;-1;-1;2;1;-1; @@ -57200,8 +57200,8 @@ type GeneratedTestSuite () = 2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;1;3;2;1;3;2;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.less_than``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.less_than [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -57225,8 +57225,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.less_or_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.less_or_equal [| 0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;1;1;1; 1;1;0;0;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0;1;1;1;1;0;0;0; @@ -57250,8 +57250,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.greater_than``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -57275,8 +57275,8 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.UnionWrapArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.UnionWrapArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.UnionWrapArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;1;0;0;0;0; 0;0;1;0;0;0;0;0;0;1;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0;0;0;0;0;1;1;0; @@ -57300,648 +57300,648 @@ type GeneratedTestSuite () = 1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;0;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.equals``() = validate (Tuple2s.Collection.ValueArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.equal``() = validate (Tuple2s.Collection.ValueArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.not_equal``() = validate (Tuple2s.Collection.ValueArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.compare``() = validate (Tuple2s.Collection.ValueArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.less_than``() = validate (Tuple2s.Collection.ValueArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.less_or_equal``() = validate (Tuple2s.Collection.ValueArray) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.greater_than``() = validate (Tuple2s.Collection.ValueArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.ValueArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.equals``() = validate (Tuple2s.Collection.ValueArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.equal``() = validate (Tuple2s.Collection.ValueArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.not_equal``() = validate (Tuple2s.Collection.ValueArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.compare``() = validate (Tuple2s.Collection.ValueArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.less_than``() = validate (Tuple2s.Collection.ValueArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.less_or_equal``() = validate (Tuple2s.Collection.ValueArray) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.greater_than``() = validate (Tuple2s.Collection.ValueArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.ValueArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.equals``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.not_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.compare``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.less_than``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.less_or_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.greater_than``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.equals``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.not_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.compare``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.compare [| 0;-1;-1;-1;1;0;-1;-1;1;1;0;-1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.less_than``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.less_or_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.greater_than``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ValueWrapArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ValueWrapArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.ValueWrapArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.equals``() = validate (Tuple2s.Collection.ArrayArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.equal``() = validate (Tuple2s.Collection.ArrayArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.not_equal``() = validate (Tuple2s.Collection.ArrayArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.compare``() = validate (Tuple2s.Collection.ArrayArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1; 1;1;1;1;1;0;-1;-1;1;1;1;1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.less_than``() = validate (Tuple2s.Collection.ArrayArray) C.I.less_than [| 0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.less_or_equal``() = validate (Tuple2s.Collection.ArrayArray) C.I.less_or_equal [| 0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.greater_than``() = validate (Tuple2s.Collection.ArrayArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0; 1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.ArrayArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;1;0;0;0;0; 1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.equals``() = validate (Tuple2s.Collection.ArrayArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.equal``() = validate (Tuple2s.Collection.ArrayArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.not_equal``() = validate (Tuple2s.Collection.ArrayArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.compare``() = validate (Tuple2s.Collection.ArrayArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1; 1;1;1;1;1;0;-1;-1;1;1;1;1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.less_than``() = validate (Tuple2s.Collection.ArrayArray) C.N.less_than [| 0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.less_or_equal``() = validate (Tuple2s.Collection.ArrayArray) C.N.less_or_equal [| 0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;1;1;1;1;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.greater_than``() = validate (Tuple2s.Collection.ArrayArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;0;0;0;0; 1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.ArrayArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;1;1;1;0;0;0;0; 1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0;1;1;1;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.equals``() = validate (Tuple2s.Collection.ListArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.equal``() = validate (Tuple2s.Collection.ListArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.not_equal``() = validate (Tuple2s.Collection.ListArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.compare``() = validate (Tuple2s.Collection.ListArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;-1;-1;-1;1;1;0;-1;1;1;-1;-1;1;1;1;0;1;1;1;-1;1;-1;-1;-1;0;-1;-1;-1; 1;1;-1;-1;1;0;-1;-1;1;1;1;-1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.less_than``() = validate (Tuple2s.Collection.ListArray) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.less_or_equal``() = validate (Tuple2s.Collection.ListArray) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.greater_than``() = validate (Tuple2s.Collection.ListArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.ListArray) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.equals``() = validate (Tuple2s.Collection.ListArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.equal``() = validate (Tuple2s.Collection.ListArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.not_equal``() = validate (Tuple2s.Collection.ListArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.compare``() = validate (Tuple2s.Collection.ListArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;-1;-1;-1;1;1;0;-1;1;1;-1;-1;1;1;1;0;1;1;1;-1;1;-1;-1;-1;0;-1;-1;-1; 1;1;-1;-1;1;0;-1;-1;1;1;1;-1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.less_than``() = validate (Tuple2s.Collection.ListArray) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.less_or_equal``() = validate (Tuple2s.Collection.ListArray) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.greater_than``() = validate (Tuple2s.Collection.ListArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ListArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ListArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.ListArray) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equals``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.not_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.compare``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;-1;-1;1;1;1;0;-1;1;1;-1;1;1;1;1;0;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1; 1;1;-1;-1;1;0;-1;1;1;1;1;-1;1;1;0;1;1;-1;-1;-1;1;-1;-1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_than``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_than [| 0;1;1;1;1;1;1;1;0;0;1;1;0;1;1;0;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1; 0;0;1;1;0;0;1;0;0;0;0;1;0;0;0;0;0;1;1;1;0;1;1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.less_or_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.less_or_equal [| 1;1;1;1;1;1;1;1;0;1;1;1;0;1;1;0;0;0;1;1;0;0;1;0;0;0;0;1;0;0;0;0;0;1;1;1;1;1;1;1; 0;0;1;1;0;1;1;0;0;0;0;1;0;0;1;0;0;1;1;1;0;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_than``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_than [| 0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;1;1;1;0;0;1;1;0;1;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;0; 1;1;0;0;1;0;0;1;1;1;1;0;1;1;0;1;1;0;0;0;1;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.I.greater_or_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.I.greater_or_equal [| 1;0;0;0;0;0;0;0;1;1;0;0;1;0;0;1;1;1;1;0;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;0;1;0;0;0; 1;1;0;0;1;1;0;1;1;1;1;0;1;1;1;1;1;0;0;0;1;0;0;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equals``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.not_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.compare``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;1;-1;-1;1;1;1;0;-1;1;1;-1;1;1;1;1;0;1;1;1;1;1;-1;-1;-1;0;-1;-1;-1; 1;1;-1;-1;1;0;-1;1;1;1;1;-1;1;1;0;1;1;-1;-1;-1;1;-1;-1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_than``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_than [| 0;1;1;1;1;1;1;1;0;0;1;1;0;1;1;0;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1; 0;0;1;1;0;0;1;0;0;0;0;1;0;0;0;0;0;1;1;1;0;1;1;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.less_or_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.less_or_equal [| 1;1;1;1;1;1;1;1;0;1;1;1;0;1;1;0;0;0;1;1;0;0;1;0;0;0;0;1;0;0;0;0;0;1;1;1;1;1;1;1; 0;0;1;1;0;1;1;0;0;0;0;1;0;0;1;0;0;1;1;1;0;1;1;1 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_than``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_than [| 0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;1;1;1;0;0;1;1;0;1;1;1;1;0;1;1;1;1;1;0;0;0;0;0;0;0; 1;1;0;0;1;0;0;1;1;1;1;0;1;1;0;1;1;0;0;0;1;0;0;0 |] - [] - member __.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = + [] + member _.``Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray C.N.greater_or_equal``() = validate (Tuple2s.Collection.ArrayArray |> Array.map Set.ofArray) C.N.greater_or_equal [| 1;0;0;0;0;0;0;0;1;1;0;0;1;0;0;1;1;1;1;0;1;1;0;1;1;1;1;1;1;1;1;1;1;0;0;0;1;0;0;0; 1;1;0;0;1;1;0;1;1;1;1;0;1;1;1;1;1;0;0;0;1;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.I.equals``() = + [] + member _.``Tuple3s.Collection.Array C.I.equals``() = validate (Tuple3s.Collection.Array) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.I.equal``() = + [] + member _.``Tuple3s.Collection.Array C.I.equal``() = validate (Tuple3s.Collection.Array) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.I.not_equal``() = + [] + member _.``Tuple3s.Collection.Array C.I.not_equal``() = validate (Tuple3s.Collection.Array) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple3s.Collection.Array C.I.compare``() = + [] + member _.``Tuple3s.Collection.Array C.I.compare``() = validate (Tuple3s.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1; 1;1;1;1;1;0;-1;-1;1;1;1;1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple3s.Collection.Array C.I.less_than``() = + [] + member _.``Tuple3s.Collection.Array C.I.less_than``() = validate (Tuple3s.Collection.Array) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple3s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Tuple3s.Collection.Array C.I.less_or_equal``() = validate (Tuple3s.Collection.Array) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.I.greater_than``() = + [] + member _.``Tuple3s.Collection.Array C.I.greater_than``() = validate (Tuple3s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple3s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Tuple3s.Collection.Array C.I.greater_or_equal``() = validate (Tuple3s.Collection.Array) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.N.equals``() = + [] + member _.``Tuple3s.Collection.Array C.N.equals``() = validate (Tuple3s.Collection.Array) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.N.equal``() = + [] + member _.``Tuple3s.Collection.Array C.N.equal``() = validate (Tuple3s.Collection.Array) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.N.not_equal``() = + [] + member _.``Tuple3s.Collection.Array C.N.not_equal``() = validate (Tuple3s.Collection.Array) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple3s.Collection.Array C.N.compare``() = + [] + member _.``Tuple3s.Collection.Array C.N.compare``() = validate (Tuple3s.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1; 1;1;1;1;1;0;-1;-1;1;1;1;1;1;1;0;-1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple3s.Collection.Array C.N.less_than``() = + [] + member _.``Tuple3s.Collection.Array C.N.less_than``() = validate (Tuple3s.Collection.Array) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple3s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Tuple3s.Collection.Array C.N.less_or_equal``() = validate (Tuple3s.Collection.Array) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple3s.Collection.Array C.N.greater_than``() = + [] + member _.``Tuple3s.Collection.Array C.N.greater_than``() = validate (Tuple3s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple3s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Tuple3s.Collection.Array C.N.greater_or_equal``() = validate (Tuple3s.Collection.Array) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.I.equals``() = + [] + member _.``Tuple4s.Collection.Array C.I.equals``() = validate (Tuple4s.Collection.Array) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -57952,8 +57952,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.I.equal``() = + [] + member _.``Tuple4s.Collection.Array C.I.equal``() = validate (Tuple4s.Collection.Array) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -57964,8 +57964,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.I.not_equal``() = + [] + member _.``Tuple4s.Collection.Array C.I.not_equal``() = validate (Tuple4s.Collection.Array) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -57976,8 +57976,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple4s.Collection.Array C.I.compare``() = + [] + member _.``Tuple4s.Collection.Array C.I.compare``() = validate (Tuple4s.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1; -1;-1;-1;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1; @@ -57988,8 +57988,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple4s.Collection.Array C.I.less_than``() = + [] + member _.``Tuple4s.Collection.Array C.I.less_than``() = validate (Tuple4s.Collection.Array) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58000,8 +58000,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple4s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Tuple4s.Collection.Array C.I.less_or_equal``() = validate (Tuple4s.Collection.Array) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58012,8 +58012,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.I.greater_than``() = + [] + member _.``Tuple4s.Collection.Array C.I.greater_than``() = validate (Tuple4s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58024,8 +58024,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple4s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Tuple4s.Collection.Array C.I.greater_or_equal``() = validate (Tuple4s.Collection.Array) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58036,8 +58036,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.N.equals``() = + [] + member _.``Tuple4s.Collection.Array C.N.equals``() = validate (Tuple4s.Collection.Array) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58048,8 +58048,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.N.equal``() = + [] + member _.``Tuple4s.Collection.Array C.N.equal``() = validate (Tuple4s.Collection.Array) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58060,8 +58060,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.N.not_equal``() = + [] + member _.``Tuple4s.Collection.Array C.N.not_equal``() = validate (Tuple4s.Collection.Array) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -58072,8 +58072,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple4s.Collection.Array C.N.compare``() = + [] + member _.``Tuple4s.Collection.Array C.N.compare``() = validate (Tuple4s.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1; -1;-1;-1;-1;-1;-1;-1;-1;1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1; @@ -58084,8 +58084,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple4s.Collection.Array C.N.less_than``() = + [] + member _.``Tuple4s.Collection.Array C.N.less_than``() = validate (Tuple4s.Collection.Array) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58096,8 +58096,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple4s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Tuple4s.Collection.Array C.N.less_or_equal``() = validate (Tuple4s.Collection.Array) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58108,8 +58108,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple4s.Collection.Array C.N.greater_than``() = + [] + member _.``Tuple4s.Collection.Array C.N.greater_than``() = validate (Tuple4s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58120,8 +58120,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple4s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Tuple4s.Collection.Array C.N.greater_or_equal``() = validate (Tuple4s.Collection.Array) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58132,8 +58132,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.I.equals``() = + [] + member _.``Tuple5s.Collection.Array C.I.equals``() = validate (Tuple5s.Collection.Array) C.I.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58163,8 +58163,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.I.equal``() = + [] + member _.``Tuple5s.Collection.Array C.I.equal``() = validate (Tuple5s.Collection.Array) C.I.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58194,8 +58194,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.I.not_equal``() = + [] + member _.``Tuple5s.Collection.Array C.I.not_equal``() = validate (Tuple5s.Collection.Array) C.I.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -58225,8 +58225,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple5s.Collection.Array C.I.compare``() = + [] + member _.``Tuple5s.Collection.Array C.I.compare``() = validate (Tuple5s.Collection.Array) C.I.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1; -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1; @@ -58256,8 +58256,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple5s.Collection.Array C.I.less_than``() = + [] + member _.``Tuple5s.Collection.Array C.I.less_than``() = validate (Tuple5s.Collection.Array) C.I.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58287,8 +58287,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple5s.Collection.Array C.I.less_or_equal``() = + [] + member _.``Tuple5s.Collection.Array C.I.less_or_equal``() = validate (Tuple5s.Collection.Array) C.I.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58318,8 +58318,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.I.greater_than``() = + [] + member _.``Tuple5s.Collection.Array C.I.greater_than``() = validate (Tuple5s.Collection.Array) C.I.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58349,8 +58349,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple5s.Collection.Array C.I.greater_or_equal``() = + [] + member _.``Tuple5s.Collection.Array C.I.greater_or_equal``() = validate (Tuple5s.Collection.Array) C.I.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58380,8 +58380,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.N.equals``() = + [] + member _.``Tuple5s.Collection.Array C.N.equals``() = validate (Tuple5s.Collection.Array) C.N.equals [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58411,8 +58411,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.N.equal``() = + [] + member _.``Tuple5s.Collection.Array C.N.equal``() = validate (Tuple5s.Collection.Array) C.N.equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58442,8 +58442,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.N.not_equal``() = + [] + member _.``Tuple5s.Collection.Array C.N.not_equal``() = validate (Tuple5s.Collection.Array) C.N.not_equal [| 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; @@ -58473,8 +58473,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple5s.Collection.Array C.N.compare``() = + [] + member _.``Tuple5s.Collection.Array C.N.compare``() = validate (Tuple5s.Collection.Array) C.N.compare [| 0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;0;-1;-1;-1;-1;-1;-1; -1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;1;1;0;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1; @@ -58504,8 +58504,8 @@ type GeneratedTestSuite () = 1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0 |] - [] - member __.``Tuple5s.Collection.Array C.N.less_than``() = + [] + member _.``Tuple5s.Collection.Array C.N.less_than``() = validate (Tuple5s.Collection.Array) C.N.less_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58535,8 +58535,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple5s.Collection.Array C.N.less_or_equal``() = + [] + member _.``Tuple5s.Collection.Array C.N.less_or_equal``() = validate (Tuple5s.Collection.Array) C.N.less_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58566,8 +58566,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1 |] - [] - member __.``Tuple5s.Collection.Array C.N.greater_than``() = + [] + member _.``Tuple5s.Collection.Array C.N.greater_than``() = validate (Tuple5s.Collection.Array) C.N.greater_than [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; @@ -58597,8 +58597,8 @@ type GeneratedTestSuite () = 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0 |] - [] - member __.``Tuple5s.Collection.Array C.N.greater_or_equal``() = + [] + member _.``Tuple5s.Collection.Array C.N.greater_or_equal``() = validate (Tuple5s.Collection.Array) C.N.greater_or_equal [| 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; 0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0; diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/CreateComparersRegression.fsx b/tests/FSharp.Core.UnitTests/FSharp.Core/CreateComparersRegression.fsx index bbd68226a07..9066e2a19f6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/CreateComparersRegression.fsx +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/CreateComparersRegression.fsx @@ -3,4 +3,4 @@ #r @"..\..\..\..\Release\net40\bin\FSharp.Core.UnitTests.dll" -FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core.ComparersRegression.createData () \ No newline at end of file +FSharp.Core.UnitTests.ComparersRegression.createData () diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/DiscrimantedUnionType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/DiscrimantedUnionType.fs deleted file mode 100644 index e5a48ad3007..00000000000 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/DiscrimantedUnionType.fs +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core.DiscriminatedUnionTypes - -open System -open System.Numerics -open System.Reflection -open System.Runtime.InteropServices -open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework -open FsCheck -open FsCheck.PropOperators - -type EnumUnion = - | A - | B - -[] -type UseUnionsAsEnums() = - [] - member this.CanCompare() = - Assert.AreEqual(EnumUnion.B, EnumUnion.B) - Assert.AreNotEqual(EnumUnion.A, EnumUnion.B) - -[] -type FlagsUnion = - | One = 1 - | Two = 2 - | Four = 4 - -[] -type UseUnionsAsFlags() = - - [] - member this.CanCompareWithInts() = - Assert.AreEqual(int FlagsUnion.One, 1) - Assert.AreEqual(int FlagsUnion.Two, 2) - Assert.AreEqual(int FlagsUnion.Four, 4) - - [] - member this.CanCastFromInts() = - let four : FlagsUnion = enum 4 - Assert.AreEqual(four, FlagsUnion.Four) - - [] - member this.CanCreateValuesWithoutName() = - let unknown : FlagsUnion = enum 99 // strange, but valid - Assert.AreEqual(int unknown, 99) - - [] - member this.CanParseViaBCL() = - let values = System.Enum.GetValues(typeof) - let fourFromString = System.Enum.Parse(typeof, "Four", false) :?> FlagsUnion // downcast needed - Assert.AreEqual(fourFromString, FlagsUnion.Four) - - [] - member this.CanUseBinaryOr() = - Assert.AreEqual(int (FlagsUnion.One ||| FlagsUnion.Two), 3) - Assert.AreEqual(int (FlagsUnion.One ||| FlagsUnion.One), 1) - - [] - member this.CanCompareWithFlags() = - Assert.AreEqual(FlagsUnion.Two, FlagsUnion.Two) - Assert.AreNotEqual(FlagsUnion.Two, FlagsUnion.One) - -type UnionsWithData = - | Alpha of int - | Beta of string * float - -[] -type UseUnionsWithData() = - let a1 = Alpha 1 - let a2 = Alpha 2 - let b1 = Beta("win", 8.1) - - [] - member this.CanAccessTheData() = - match a1 with - | Alpha 1 -> () - | _ -> Assert.Fail() - match a2 with - | Alpha 2 -> () - | _ -> Assert.Fail() - match a2 with - | Alpha x -> Assert.AreEqual(x, 2) - | _ -> Assert.Fail() - match b1 with - | Beta("win", 8.1) -> () - | _ -> Assert.Fail() - match b1 with - | Beta(x, y) -> - Assert.AreEqual(x, "win") - Assert.AreEqual(y, 8.1) - | _ -> Assert.Fail() - - [] - member this.CanAccessTheDataInGuards() = - match a1 with - | Alpha x when x = 1 -> () - | _ -> Assert.Fail() - match a2 with - | Alpha x when x = 2 -> () - | _ -> Assert.Fail() - -[] -type StructUnion = SU of C : int * D : int - -let private hasAttribute<'T,'Attr>() = - typeof<'T>.GetTypeInfo().GetCustomAttributes() |> Seq.exists (fun x -> x.GetType() = typeof<'Attr>) - - -let [] ``struct unions hold [] metadata`` () = - Assert.IsTrue (hasAttribute()) - - -let [] ``struct unions are comparable`` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) -> - i1 <> i2 ==> - let sr1 = SU (i1, i2) - let sr2 = SU (i1, i2) - let sr3 = SU (i2, i1) - (sr1 = sr2) |@ "sr1 = sr2" .&. - (sr1 <> sr3) |@ "sr1 <> sr3" .&. - (sr1.Equals sr2) |@ "sr1.Equals sr2" - - -let [] ``struct unions support pattern matching`` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) -> - let sr1 = SU(i1, i2) - (match sr1 with - | SU(c,d) when c = i1 && d = i2 -> true - | _ -> false) - |@ "with pattern match on struct union" .&. - (sr1 |> function - | SU(c,d) when c = i1 && d = i2 -> true - | _ -> false) - |@ "function pattern match on struct union" - - -let [] ``struct unions support let binds using `` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) -> - let sr1 = SU(i1,i2) - let (SU (c1,d2)) as sr2 = sr1 - (sr1 = sr2) |@ "sr1 = sr2" .&. - (c1 = i1 && d2 = i2) |@ "c1 = i1 && d2 = i2" - - -let [] ``struct unions support function argument bindings`` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) -> - let sr1 = SU(i1,i2) - let test sr1 (SU (c1,d2) as sr2) = - sr1 = sr2 && c1 = i1 && d2 = i2 - test sr1 sr1 - - - -[] -[] -type ComparisonStructUnion = - | SU2 of int * int - member x.C1 = (match x with SU2(a,b) -> a) - member x.C2 = (match x with SU2(a,b) -> b) - override self.Equals other = - match other with - | :? ComparisonStructUnion as o -> (self.C1 + self.C2) = (o.C1 + o.C2) - | _ -> false - - override self.GetHashCode() = hash self - interface IComparable with - member self.CompareTo other = - match other with - | :? ComparisonStructUnion as o -> compare (self.C1 + self.C2) (o.C1 + o.C2) - | _ -> invalidArg "other" "cannot compare values of different types" - - -[] -let ``struct unions support []`` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) -> - let sr1 = SU2(i1,i2) - let sr2 = SU2(i1,i2) - (sr1.Equals sr2) - - -[] -let ``struct unions support []`` () = - Check.QuickThrowOnFailure <| - fun (i1:int) (i2:int) (k1:int) (k2:int) -> - let sr1 = SU2(i1,i2) - let sr2 = SU2(k1,k2) - if sr1 > sr2 then compare sr1 sr2 = 1 - elif sr1 < sr2 then compare sr1 sr2 = -1 - elif sr1 = sr2 then compare sr1 sr2 = 0 - else false - - -[] -let ``struct unions hold [] [] metadata`` () = - Assert.IsTrue (hasAttribute()) - Assert.IsTrue (hasAttribute()) - - -[] -[] -type NoComparisonStructUnion = - | SU3 of int * int - - - -[] -let ``struct unions hold [] [] metadata`` () = - Assert.IsTrue (hasAttribute()) - Assert.IsTrue (hasAttribute()) - - -let [] ``can properly construct a struct union using FSharpValue.MakeUnionCase, and we get the fields`` () = - let cases = Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof) - - Assert.AreEqual (1, cases.Length) - let case = cases.[0] - - Assert.AreEqual ("SU", case.Name) - - let structUnion = Microsoft.FSharp.Reflection.FSharpValue.MakeUnion (case, [|box 1234; box 3456|]) - - Assert.IsTrue (structUnion.GetType().IsValueType) - - let _uc, fieldVals = Microsoft.FSharp.Reflection.FSharpValue.GetUnionFields(structUnion, typeof) - - Assert.AreEqual (2, fieldVals.Length) - - let c = (fieldVals.[0] :?> int) - Assert.AreEqual (1234, c) - - let c2 = (fieldVals.[1] :?> int) - Assert.AreEqual (3456, c2) - -let [] ``struct unions does optimization correctly on pattern matching`` () = - let arr = ResizeArray() - match arr.Add(1); ValueSome () with - | ValueSome () -> () - | ValueNone -> () - - Assert.AreEqual(1, arr.Count) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/DiscriminatedUnionType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/DiscriminatedUnionType.fs new file mode 100644 index 00000000000..7e64d56f512 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/DiscriminatedUnionType.fs @@ -0,0 +1,242 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +module FSharp.Core.UnitTests.DiscriminatedUnionTypes + +open System +open System.Numerics +open System.Reflection +open System.Runtime.InteropServices +open FSharp.Core.UnitTests.LibraryTestFx + +open Xunit +open FsCheck +open FsCheck.PropOperators + +type EnumUnion = + | A + | B + +type UseUnionsAsEnums() = + [] + member this.CanCompare() = + Assert.AreEqual(EnumUnion.B, EnumUnion.B) + Assert.AreNotEqual(EnumUnion.A, EnumUnion.B) + +[] +type FlagsUnion = + | One = 1 + | Two = 2 + | Four = 4 + +type UseUnionsAsFlags() = + + [] + member this.CanCompareWithInts() = + Assert.AreEqual(int FlagsUnion.One, 1) + Assert.AreEqual(int FlagsUnion.Two, 2) + Assert.AreEqual(int FlagsUnion.Four, 4) + + [] + member this.CanCastFromInts() = + let four : FlagsUnion = enum 4 + Assert.AreEqual(four, FlagsUnion.Four) + + [] + member this.CanCreateValuesWithoutName() = + let unknown : FlagsUnion = enum 99 // strange, but valid + Assert.AreEqual(int unknown, 99) + + [] + member this.CanParseViaBCL() = + let values = System.Enum.GetValues(typeof) + let fourFromString = System.Enum.Parse(typeof, "Four", false) :?> FlagsUnion // downcast needed + Assert.AreEqual(fourFromString, FlagsUnion.Four) + + [] + member this.CanUseBinaryOr() = + Assert.AreEqual(int (FlagsUnion.One ||| FlagsUnion.Two), 3) + Assert.AreEqual(int (FlagsUnion.One ||| FlagsUnion.One), 1) + + [] + member this.CanCompareWithFlags() = + Assert.AreEqual(FlagsUnion.Two, FlagsUnion.Two) + Assert.AreNotEqual(FlagsUnion.Two, FlagsUnion.One) + +type UnionsWithData = + | Alpha of int + | Beta of string * float + +type UseUnionsWithData() = + let a1 = Alpha 1 + let a2 = Alpha 2 + let b1 = Beta("win", 8.1) + + [] + member this.CanAccessTheData() = + match a1 with + | Alpha 1 -> () + | _ -> Assert.Fail() + match a2 with + | Alpha 2 -> () + | _ -> Assert.Fail() + match a2 with + | Alpha x -> Assert.AreEqual(x, 2) + | _ -> Assert.Fail() + match b1 with + | Beta("win", 8.1) -> () + | _ -> Assert.Fail() + match b1 with + | Beta(x, y) -> + Assert.AreEqual(x, "win") + Assert.AreEqual(y, 8.1) + | _ -> Assert.Fail() + + [] + member this.CanAccessTheDataInGuards() = + match a1 with + | Alpha x when x = 1 -> () + | _ -> Assert.Fail() + match a2 with + | Alpha x when x = 2 -> () + | _ -> Assert.Fail() + +[] +type StructUnion = SU of C : int * D : int + +let private hasAttribute<'T,'Attr>() = + typeof<'T>.GetTypeInfo().GetCustomAttributes() |> Seq.exists (fun x -> x.GetType() = typeof<'Attr>) + + +let [] ``struct unions hold [] metadata`` () = + Assert.True (hasAttribute()) + + +let [] ``struct unions are comparable`` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) -> + i1 <> i2 ==> + let sr1 = SU (i1, i2) + let sr2 = SU (i1, i2) + let sr3 = SU (i2, i1) + (sr1 = sr2) |@ "sr1 = sr2" .&. + (sr1 <> sr3) |@ "sr1 <> sr3" .&. + (sr1.Equals sr2) |@ "sr1.Equals sr2" + + +let [] ``struct unions support pattern matching`` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) -> + let sr1 = SU(i1, i2) + (match sr1 with + | SU(c,d) when c = i1 && d = i2 -> true + | _ -> false) + |@ "with pattern match on struct union" .&. + (sr1 |> function + | SU(c,d) when c = i1 && d = i2 -> true + | _ -> false) + |@ "function pattern match on struct union" + + +let [] ``struct unions support let binds using `` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) -> + let sr1 = SU(i1,i2) + let (SU (c1,d2)) as sr2 = sr1 + (sr1 = sr2) |@ "sr1 = sr2" .&. + (c1 = i1 && d2 = i2) |@ "c1 = i1 && d2 = i2" + + +let [] ``struct unions support function argument bindings`` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) -> + let sr1 = SU(i1,i2) + let test sr1 (SU (c1,d2) as sr2) = + sr1 = sr2 && c1 = i1 && d2 = i2 + test sr1 sr1 + +[] +[] +type ComparisonStructUnion = + | SU2 of int * int + member x.C1 = (match x with SU2(a,b) -> a) + member x.C2 = (match x with SU2(a,b) -> b) + override self.Equals other = + match other with + | :? ComparisonStructUnion as o -> (self.C1 + self.C2) = (o.C1 + o.C2) + | _ -> false + + override self.GetHashCode() = hash self + interface IComparable with + member self.CompareTo other = + match other with + | :? ComparisonStructUnion as o -> compare (self.C1 + self.C2) (o.C1 + o.C2) + | _ -> invalidArg "other" "cannot compare values of different types" + + +[] +let ``struct unions support []`` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) -> + let sr1 = SU2(i1,i2) + let sr2 = SU2(i1,i2) + (sr1.Equals sr2) + +[] +let ``struct unions support []`` () = + Check.QuickThrowOnFailure <| + fun (i1:int) (i2:int) (k1:int) (k2:int) -> + let sr1 = SU2(i1,i2) + let sr2 = SU2(k1,k2) + if sr1 > sr2 then compare sr1 sr2 = 1 + elif sr1 < sr2 then compare sr1 sr2 = -1 + elif sr1 = sr2 then compare sr1 sr2 = 0 + else false + + +[] +let ``struct unions hold [] [] metadata`` () = + Assert.True (hasAttribute()) + Assert.True (hasAttribute()) + + +[] +[] +type NoComparisonStructUnion = + | SU3 of int * int + + + +[] +let ``struct unions hold [] [] metadata`` () = + Assert.True (hasAttribute()) + Assert.True (hasAttribute()) + + +let [] ``can properly construct a struct union using FSharpValue.MakeUnionCase, and we get the fields`` () = + let cases = Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof) + + Assert.AreEqual (1, cases.Length) + let case = cases.[0] + + Assert.AreEqual ("SU", case.Name) + + let structUnion = Microsoft.FSharp.Reflection.FSharpValue.MakeUnion (case, [|box 1234; box 3456|]) + + Assert.True (structUnion.GetType().IsValueType) + + let _uc, fieldVals = Microsoft.FSharp.Reflection.FSharpValue.GetUnionFields(structUnion, typeof) + + Assert.AreEqual (2, fieldVals.Length) + + let c = (fieldVals.[0] :?> int) + Assert.AreEqual (1234, c) + + let c2 = (fieldVals.[1] :?> int) + Assert.AreEqual (3456, c2) + +let [] ``struct unions does optimization correctly on pattern matching`` () = + let arr = ResizeArray() + match arr.Add(1); ValueSome () with + | ValueSome () -> () + | ValueNone -> () + + Assert.AreEqual(1, arr.Count) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array2Module.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array2Module.fs index cbe4acc0210..f602dfc0d7e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array2Module.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array2Module.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Array2D module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open Utils (* @@ -19,7 +19,6 @@ Make sure each method works on: * Null array (null) *) -[][][] type Array2Module() = let shouldBeEmpty arr = @@ -27,7 +26,7 @@ type Array2Module() = && Array2D.length1 arr <> 0 then Assert.Fail("Array2D is not empty.") - [] + [] member this.Base1() = // integer array let intArr = @@ -54,7 +53,7 @@ type Array2Module() = () - [] + [] member this.Base2() = // integer array let intArr = @@ -86,7 +85,7 @@ type Array2Module() = Assert.AreEqual(expected, actual) () - [] + [] member this.Blit() = // integer array let intArr = @@ -132,7 +131,7 @@ type Array2Module() = CheckThrowsArgumentException(fun () -> Array2D.blit intArr 0 0 intArr2 0 10 2 2 |> ignore) () - [] + [] member this.BlitWithNonZeroBase() = let a = Array2D.createBased 1 1 3 3 0 a.[1,1] <- 11 @@ -185,7 +184,7 @@ type Array2Module() = () - [] + [] member this.Copy() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -209,7 +208,7 @@ type Array2Module() = () - [] + [] member this.Create() = // integer array let intArr = Array2D.init 2 3 (fun i j -> 100) @@ -229,7 +228,7 @@ type Array2Module() = () - [] + [] member this.createBased() = // integer array let intArr = Array2D.create 2 3 100 @@ -248,7 +247,7 @@ type Array2Module() = if resultEpt <> eptArr then Assert.Fail() () - [] + [] member this.Get() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -266,7 +265,7 @@ type Array2Module() = CheckThrowsNullRefException (fun () -> nullArr.[2,2] |> ignore) () - [] + [] member this.GetAndSetAPI() = let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) let resultInt = Array2D.get intArr 1 1 @@ -276,7 +275,7 @@ type Array2Module() = Assert.AreEqual(1, resultInt) () - [] + [] member this.Init() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -287,7 +286,7 @@ type Array2Module() = if strArr.[1,1] <> "1-1" then Assert.Fail() () - [] + [] member this.Init_Based() = // integer array let intArr = Array2D.initBased 1 1 2 3 (fun i j -> i*100 + j) @@ -298,7 +297,7 @@ type Array2Module() = if strArr.[2,2] <> "2-2" then Assert.Fail() () - [] + [] member this.Iter() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -323,7 +322,7 @@ type Array2Module() = CheckThrowsArgumentNullException (fun () -> Array2D.iter funStr nullArr |> ignore) () - [] + [] member this.IterNonZeroBased() = let a = Array2D.createBased 1 5 10 10 1 let result = ref 0 @@ -334,7 +333,7 @@ type Array2Module() = if !result <> 1600 then Assert.Fail() () - [] + [] member this.Iteri() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -360,7 +359,7 @@ type Array2Module() = () - [] + [] member this.Length1() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -383,7 +382,7 @@ type Array2Module() = () - [] + [] member this.Length2() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -407,7 +406,7 @@ type Array2Module() = () - [] + [] member this.Map() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -433,7 +432,7 @@ type Array2Module() = () - [] + [] member this.Mapi() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -459,7 +458,7 @@ type Array2Module() = () - [] + [] member this.Rebase() = // integer array let intArr = Array2D.createBased 2 3 2 3 168 @@ -483,7 +482,7 @@ type Array2Module() = () - [] + [] member this.Set() = // integer array let intArr = Array2D.init 2 3 (fun i j -> i*100 + j) @@ -502,7 +501,7 @@ type Array2Module() = () - [] + [] member this.ZeroCreate() = // integer array let intArr = Array2D.zeroCreate 2 3 @@ -519,7 +518,7 @@ type Array2Module() = () // Note: This is a top level primitive, not in the Array2D module - [] + [] member this.array2D() = let m1 : int[,] = array2D [] @@ -579,31 +578,31 @@ type Array2Module() = let m16 :string[,] = array2D [[null]] if m16.[0,0] <> null then Assert.Fail() - [] + [] member this.``Slicing with reverse index in one slice expr behaves as expected``() = let arr = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] - Assert.That(arr.[*, ^1..^0], Is.EquivalentTo(arr.[*, 3..4])) + Assert.Equal(arr.[*, ^1..^0], arr.[*, 3..4]) - [] + [] member this.``Slicing with reverse index in both slice expr behaves as expected``() = let arr = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] - Assert.That(arr.[..^1, ^1..^0], Is.EquivalentTo(arr.[..0, 3..4])) + Assert.Equal(arr.[..^1, ^1..^0], arr.[..0, 3..4]) - [] + [] member this.``Slicing with reverse index in fixed index behaves as expected``() = let arr = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] - Assert.That(arr.[^1, ^1..^0], Is.EquivalentTo(arr.[0, 3..4])) + Assert.AreEqual(arr.[^1, ^1..^0], arr.[0, 3..4]) - [] + [] member this.``Slicing with reverse index and non reverse fixed index behaves as expected``() = let arr = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] - Assert.That(arr.[1, ^1..^0], Is.EquivalentTo(arr.[1, 3..4])) + Assert.AreEqual(arr.[1, ^1..^0], arr.[1, 3..4]) - [] + [] member this.``Set slice with reverse index in one slice expr behaves as expected``() = let arr1 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] let arr2 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] @@ -612,9 +611,9 @@ type Array2Module() = arr1.[*, ^1..^0] <- setArray arr2.[*, ^1..^0] <- setArray - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Set slice with reverse index in both slice expr behaves as expected``() = let arr1 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] let arr2 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] @@ -623,9 +622,9 @@ type Array2Module() = arr1.[0..^0, ^1..^0] <- setArray arr2.[0..^0, ^1..^0] <- setArray - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Set slice with reverse index in fixed index behaves as expected``() = let arr1 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] let arr2 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] @@ -634,9 +633,9 @@ type Array2Module() = arr1.[^1, ^1..^0] <- setArray arr2.[^1, ^1..^0] <- setArray - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Set slice with reverse index in and non reverse fixed index behaves as expected``() = let arr1 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] let arr2 = array2D [[ 1;2;3;4;5 ]; [ 5;4;3;2;1 ]] @@ -645,35 +644,35 @@ type Array2Module() = arr1.[1, ^1..^0] <- setArray arr2.[1, ^1..^0] <- setArray - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Set item with reverse index in one dim behaves as expected``() = let arr = array2D [[1;2;3]; [3;2;1]] arr.[^1, 0] <- 9 - Assert.That(arr.[0, 0], Is.EqualTo(9)) + Assert.AreEqual(arr.[0, 0], 9) - [] + [] member this.``Set item with reverse index in all dims behaves as expected``()= let arr = array2D [[1;2;3]; [3;2;1]] arr.[^0, ^0] <- 9 - Assert.That(arr.[1,2], Is.EqualTo(9)) + Assert.AreEqual(arr.[1,2], 9) - [] + [] member this.``Get item with reverse index in one dim behaves as expected``() = let arr = array2D [[1;2;3]; [4;5;6]] - Assert.That(arr.[^0, 0], Is.EqualTo(4)) + Assert.AreEqual(arr.[^0, 0], 4) - [] + [] member this.``Get item with reverse index in all dims behaves as expected``()= let arr = array2D [[1;2;3]; [4;5;6]] - Assert.That(arr.[^1, ^1], Is.EqualTo(2)) + Assert.AreEqual(arr.[^1, ^1], 2) - [] + [] member this.SlicingBoundedStartEnd() = let m1 = array2D [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; [| 10.0;20.0;30.0;40.0;50.0;60.0 |] |] @@ -709,7 +708,7 @@ type Array2Module() = shouldEqual m1.[0, ..3] [| 1.0;2.0;3.0;4.0 |] - [] + [] member this.SlicingUnboundedEnd() = let arr = array2D [ [1;2;3;4;5;6]; [6;5;4;3;2;1]] @@ -719,7 +718,7 @@ type Array2Module() = shouldBeEmpty arr.[2.., 6..] - [] + [] member this.SlicingUnboundedStart() = let arr = array2D [ [1;2;3;4;5;6]; [6;5;4;3;2;1]] @@ -729,7 +728,7 @@ type Array2Module() = shouldEqual arr.[..2, ..6] arr - [] + [] member this.SlicingOutOfBounds() = let arr = array2D [ [1;2;3;4;5;6]; [6;5;4;3;2;1]] @@ -754,7 +753,7 @@ type Array2Module() = shouldEqual arr.[1, .. -1] [| |] shouldEqual arr.[.. -1, 1] [| |] - [] + [] member this.SlicingMutation() = let arr2D1 = array2D [| [| 1.; 2.; 3.; 4. |]; [| 5.; 6.; 7.; 8. |]; diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array3Module.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array3Module.fs index 4f812d744e3..604fc67fe7b 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array3Module.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array3Module.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Array3D module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open Utils (* @@ -20,7 +20,6 @@ Make sure each method works on: *) -[][][] type Array3Module() = let array3d (arrs: 'a array array array ) = Array3D.init arrs.Length arrs.[0].Length arrs.[0].[0].Length (fun i j k -> arrs.[i].[j].[k]) @@ -43,7 +42,7 @@ type Array3Module() = [| [| 10.0;20.0;30.0;40.0;50.0;60.0 |]; [| 100.0;200.0;300.0;400.0;500.0;600.0 |] |] |]) - [] + [] member this.Create() = // integer array let intArr = Array3D.create 3 4 5 168 @@ -62,7 +61,7 @@ type Array3Module() = () - [] + [] member this.Init() = // integer array @@ -78,7 +77,7 @@ type Array3Module() = VerifyDimensions intArr 3 3 3 () - [] + [] member this.Get() = // integer array @@ -106,7 +105,7 @@ type Array3Module() = CheckThrowsNullRefException (fun () -> Array3D.get nullArr 1 1 1 |> ignore) () - [] + [] member this.Iter() = // integer array @@ -116,7 +115,7 @@ type Array3Module() = let addToTotal x = resultInt := !resultInt + x Array3D.iter addToTotal intArr - Assert.IsTrue(!resultInt = 726) + Assert.True(!resultInt = 726) // string array let strArr = Array3D.init 2 3 2 (fun i j k-> i.ToString() + "-" + j.ToString() + "-" + k.ToString()) @@ -125,7 +124,7 @@ type Array3Module() = let addElement (x:string) = resultStr := (!resultStr) + x + "," Array3D.iter addElement strArr - Assert.IsTrue(!resultStr = "0-0-0,0-0-1,0-1-0,0-1-1,0-2-0,0-2-1,1-0-0,1-0-1,1-1-0,1-1-1,1-2-0,1-2-1,") + Assert.True(!resultStr = "0-0-0,0-0-1,0-1-0,0-1-1,0-2-0,0-2-1,1-0-0,1-0-1,1-1-0,1-1-1,1-2-0,1-2-1,") // empty array let emptyArray = Array3D.create 0 0 0 0 @@ -136,7 +135,7 @@ type Array3Module() = CheckThrowsArgumentNullException(fun () -> Array3D.iter (fun x -> Assert.Fail("Souldn't be called")) nullArr) () - [] + [] member this.Iteri() = // integer array @@ -167,7 +166,7 @@ type Array3Module() = CheckThrowsArgumentNullException (fun () -> Array3D.iteri funStr nullArr |> ignore) () - [] + [] member this.Length1() = // integer array @@ -191,7 +190,7 @@ type Array3Module() = CheckThrowsNullRefException (fun () -> Array3D.length1 nullArr |> ignore) () - [] + [] member this.Length2() = // integer array @@ -215,7 +214,7 @@ type Array3Module() = CheckThrowsNullRefException (fun () -> Array3D.length2 nullArr |> ignore) () - [] + [] member this.Length3() = // integer array @@ -238,7 +237,7 @@ type Array3Module() = CheckThrowsNullRefException (fun () -> Array3D.length3 nullArr |> ignore) () - [] + [] member this.Map() = // integer array @@ -263,7 +262,7 @@ type Array3Module() = CheckThrowsArgumentNullException (fun () -> Array3D.map funStr nullArr |> ignore) () - [] + [] member this.Mapi() = // integer array @@ -291,22 +290,22 @@ type Array3Module() = () - [] + [] member this.Set() = // integer array let intArr = Array3D.init 2 3 2(fun i j k -> i*100 + j*10 + k) - Assert.IsFalse(intArr.[1,1,1] = -1) + Assert.False(intArr.[1,1,1] = -1) Array3D.set intArr 1 1 1 -1 - Assert.IsTrue(intArr.[1,1,1] = -1) + Assert.True(intArr.[1,1,1] = -1) // string array let strArr = Array3D.init 2 3 2 (fun i j k-> i.ToString() + "-" + j.ToString()+ "-" + k.ToString()) - Assert.IsFalse(strArr.[1,1,1] = "custom") + Assert.False(strArr.[1,1,1] = "custom") Array3D.set strArr 1 1 1 "custom" - Assert.IsTrue(strArr.[1,1,1] = "custom") + Assert.True(strArr.[1,1,1] = "custom") // Out of bounds checks CheckThrowsIndexOutRangException(fun () -> Array3D.set strArr 2 0 0 "out of bounds") @@ -322,7 +321,7 @@ type Array3Module() = CheckThrowsNullRefException (fun () -> Array3D.set nullArr 0 0 0 "") () - [] + [] member this.ZeroCreate() = let intArr : int[,,] = Array3D.zeroCreate 2 3 2 @@ -331,7 +330,7 @@ type Array3Module() = let structArray : DateTime[,,] = Array3D.zeroCreate 1 1 1 let defaultVal = new DateTime() - Assert.IsTrue(Array3D.get structArray 0 0 0 = defaultVal) + Assert.True(Array3D.get structArray 0 0 0 = defaultVal) let strArr : string[,,] = Array3D.zeroCreate 2 3 2 for i in 0 .. 1 do @@ -346,13 +345,13 @@ type Array3Module() = () - [] + [] member this.``Slicing with reverse index in all 3 slice expr behaves as expected``() = let arr = Array3D.init 5 5 5 (fun i j k -> i*100 + j*10 + k) - Assert.That(arr.[..^1, ^1..^0, ^2..], Is.EquivalentTo(arr.[..3, 3..4, 2..])) + Assert.Equal(arr.[..^1, ^1..^0, ^2..], arr.[..3, 3..4, 2..]) - [] + [] member this.``Set slice with reverse index in all 3 slice expr behaves as expected``() = let arr1 = Array3D.init 5 5 5 (fun i j k -> i*100 + j*10 + k) let arr2 = Array3D.init 5 5 5 (fun i j k -> i*100 + j*10 + k) @@ -362,28 +361,28 @@ type Array3Module() = arr1.[^1..^0, ^2..3, 1..^2] <- setSlice arr2.[3..4, 2..3, 1..2] <- setSlice - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Indexer with reverse index in one dim behaves as expected``() = let arr1 = Array3D.init 5 5 5 (fun i j k -> i*100 + j*10 + k) - Assert.That(arr1.[^1,0,0], Is.EqualTo(300)) + Assert.AreEqual(arr1.[^1,0,0], 300) - [] + [] member this.``Indexer with reverse index in all dim behaves as expected``() = let arr1 = Array3D.init 5 5 5 (fun i j k -> i*100 + j*10 + k) - Assert.That(arr1.[^0,^1,^0], Is.EqualTo(434)) + Assert.AreEqual(arr1.[^0,^1,^0], 434) - [] + [] member this.``Set item with reverse index in all dims behave as expected``() = let arr1 = Array3D.create 5 5 5 2 arr1.[^1,^0,^0] <- 9 - Assert.That(arr1.[3,4,4], Is.EqualTo(9)) + Assert.AreEqual(arr1.[3,4,4], 9) - [] + [] member this.SlicingBoundedStartEnd() = shouldEqual m1.[*,*,*] m1 shouldEqual m1.[0..,*,*] @@ -434,7 +433,7 @@ type Array3Module() = [| [| 10.0;20.0;30.0;40.0;50.0;60.0 |]; [| 100.0;200.0;300.0;400.0;500.0;600.0 |] |] |] ) - [] + [] member this.SlicingOutOfBounds() = shouldBeEmpty m1.[*,*,7..] shouldBeEmpty m1.[*,*,.. -1] @@ -457,7 +456,7 @@ type Array3Module() = Assert.AreEqual(m1.[1,0,0], 10.0) Assert.AreEqual(m1.[0,0,*], newSlice) - [] + [] member this.SlicingSingleFixed2() = let m1 = (array3d [| [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; @@ -470,7 +469,7 @@ type Array3Module() = Assert.AreEqual(m1.[0,0,1], 2.0) Assert.AreEqual(m1.[0,*,0], newSlice) - [] + [] member this.SlicingSingleFixed3() = let m1 = (array3d [| [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; @@ -483,7 +482,7 @@ type Array3Module() = Assert.AreEqual(m1.[0,0,1], 2.0) Assert.AreEqual(m1.[*,0,0], newSlice) - [] + [] member this.SlicingDoubleFixed1() = let m1 = (array3d [| [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; @@ -496,7 +495,7 @@ type Array3Module() = Assert.AreEqual(m1.[1,0,0], 10.0) shouldEqual m1.[0,*,*] newSlice - [] + [] member this.SlicingDoubleFixed2() = let m1 = (array3d [| [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; @@ -509,7 +508,7 @@ type Array3Module() = Assert.AreEqual(m1.[0,0,1], 2.0) shouldEqual m1.[*,*,0] newSlice - [] + [] member this.SlicingDoubleFixed3() = let m1 = (array3d [| [| [| 1.0;2.0;3.0;4.0;5.0;6.0 |]; diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array4Module.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array4Module.fs index ac2ba844301..1d6276e4259 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array4Module.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Array4Module.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Array4D module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open Utils (* @@ -20,7 +20,6 @@ Make sure each method works on: *) -[][][] type Array4Module() = let VerifyDimensions arr x y z u = @@ -55,7 +54,7 @@ type Array4Module() = [| 1009.0;2009.0;3009.0;4009.0;5009.0;6009.0 |] |] |] |] - [] + [] member this.Create() = // integer array let intArr = Array4D.create 3 4 5 6 168 @@ -73,7 +72,7 @@ type Array4Module() = if eptArr1 <> eptArr2 then Assert.Fail() () - [] + [] member this.Init() = // integer array @@ -89,7 +88,7 @@ type Array4Module() = VerifyDimensions intArr 3 3 3 3 () - [] + [] member this.Get() = // integer array @@ -119,7 +118,7 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.get nullArr 1 1 1 1 |> ignore) () - [] + [] member this.Length1() = // integer array @@ -143,7 +142,7 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.length1 nullArr |> ignore) () - [] + [] member this.Length2() = // integer array @@ -167,7 +166,7 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.length2 nullArr |> ignore) () - [] + [] member this.Length3() = // integer array @@ -190,7 +189,7 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.length3 nullArr |> ignore) () - [] + [] member this.Length4() = // integer array @@ -213,22 +212,22 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.length4 nullArr |> ignore) () - [] + [] member this.Set() = // integer array let intArr = Array4D.init 2 3 2 2 (fun i j k l -> i*1000 + j*100 + k*10 + l) - Assert.IsFalse(intArr.[1,1,1,1] = -1) + Assert.False(intArr.[1,1,1,1] = -1) Array4D.set intArr 1 1 1 1 -1 - Assert.IsTrue(intArr.[1,1,1,1] = -1) + Assert.True(intArr.[1,1,1,1] = -1) // string array let strArr = Array4D.init 2 3 2 2 (fun i j k l -> i.ToString() + "-" + j.ToString()+ "-" + k.ToString() + "-" + l.ToString()) - Assert.IsFalse(strArr.[1,1,1,1] = "custom") + Assert.False(strArr.[1,1,1,1] = "custom") Array4D.set strArr 1 1 1 1 "custom" - Assert.IsTrue(strArr.[1,1,1,1] = "custom") + Assert.True(strArr.[1,1,1,1] = "custom") // Out of bounds checks CheckThrowsIndexOutRangException(fun () -> Array4D.set strArr 2 0 0 0 "out of bounds") @@ -245,7 +244,7 @@ type Array4Module() = CheckThrowsNullRefException (fun () -> Array4D.set nullArr 0 0 0 0 "") () - [] + [] member this.ZeroCreate() = let intArr : int[,,,] = Array4D.zeroCreate 2 3 2 2 @@ -254,7 +253,7 @@ type Array4Module() = let structArray : DateTime[,,,] = Array4D.zeroCreate 1 1 1 1 let defaultVal = new DateTime() - Assert.IsTrue(Array4D.get structArray 0 0 0 0 = defaultVal) + Assert.True(Array4D.get structArray 0 0 0 0 = defaultVal) let strArr : string[,,,] = Array4D.zeroCreate 2 3 2 2 for i in 0 .. 1 do @@ -271,7 +270,7 @@ type Array4Module() = () - [] + [] member this.SlicingTripleFixed1() = let m1 = array4d [| [| @@ -291,7 +290,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,0,1,0], 11.0) Assert.AreEqual(m1.[0,0,0,*], newSlice) - [] + [] member this.SlicingTripleFixed2() = let m1 = array4d [| [| @@ -311,7 +310,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,0,0,1], 2.0) Assert.AreEqual(m1.[0,0,*,0], newSlice) - [] + [] member this.SlicingTripleFixed3() = let m1 = array4d [| [| @@ -331,7 +330,7 @@ type Array4Module() = Assert.AreEqual(m1.[1,0,0,0], 19.0) Assert.AreEqual(m1.[0,*,0,0], newSlice) - [] + [] member this.SlicingTripleFixed4() = let m1 = array4d [| [| @@ -351,7 +350,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,1,0,0], 10.0) Assert.AreEqual(m1.[*,0,0,0], newSlice) - [] + [] member this.SlicingDoubleFixed1() = let m1 = array4d [| [| @@ -374,7 +373,7 @@ type Array4Module() = Assert.AreEqual(m1.[1,1,0,0], 109.0) if m1.[0,0,*,*] <> newSlice then Assert.Fail() - [] + [] member this.SlicingDoubleFixed2() = let m1 = array4d [| [| @@ -397,7 +396,7 @@ type Array4Module() = Assert.AreEqual(m1.[1,0,1,0], 119.0) if m1.[0,*,0,*] <> newSlice then Assert.Fail() - [] + [] member this.SlicingDoubleFixed3() = let m1 = array4d [| [| @@ -420,7 +419,7 @@ type Array4Module() = Assert.AreEqual(m1.[1,0,0,1], 29.0) if m1.[0,*,*,0] <> newSlice then Assert.Fail() - [] + [] member this.SlicingDoubleFixed4() = let m1 = array4d [| [| @@ -445,7 +444,7 @@ type Array4Module() = if m1.[*,0,0,*] <> newSlice then Assert.Fail() - [] + [] member this.SlicingDoubleFixed5() = let m1 = array4d [| [| @@ -469,7 +468,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,1,0,1], 20.0) if m1.[*,0,*,0] <> newSlice then Assert.Fail() - [] + [] member this.SlicingDoubleFixed6() = let m1 = array4d [| [| @@ -493,7 +492,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,0,1,1], 21.0) if m1.[*,*,0,0] <> newSlice then Assert.Fail() - [] + [] member this.SlicingSingleFixed1() = let m1 = array4d [| [| @@ -519,7 +518,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,0,0,1], 2.0) if m1.[*,*,*,0] <> newSlice then Assert.Fail() - [] + [] member this.SlicingSingleFixed2() = let m1 = array4d [| [| @@ -546,7 +545,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,0,1,0], 11.0) if m1.[*,*,0,*] <> newSlice then Assert.Fail() - [] + [] member this.SlicingSingleFixed3() = let m1 = array4d [| [| @@ -573,7 +572,7 @@ type Array4Module() = Assert.AreEqual(m1.[0,1,0,0], 10.0) if m1.[*,0,*,*] <> newSlice then Assert.Fail() - [] + [] member this.SlicingSingleFixed4() = let m1 = array4d [| [| @@ -600,13 +599,13 @@ type Array4Module() = Assert.AreEqual(m1.[1,0,0,0], 19.0) if m1.[0,*,*,*] <> newSlice then Assert.Fail() - [] + [] member this.``Slicing with reverse index in all slice expr behaves as expected``() = let arr = Array4D.init 5 5 5 5 (fun i j k l -> i*1000 + j*100 + k*10 + l) - Assert.That(arr.[..^1, ^1..^0, ^2.., ^1..], Is.EquivalentTo(arr.[..3, 3..4, 2.., 3..])) + Assert.Equal(arr.[..^1, ^1..^0, ^2.., ^1..], arr.[..3, 3..4, 2.., 3..]) - [] + [] member this.``Set slice with reverse index in all slice expr behaves as expected``() = let arr1 = Array4D.init 5 5 5 5 (fun i j k l -> i*1000 + j*100 + k*10 + l) let arr2 = Array4D.init 5 5 5 5 (fun i j k l -> i*1000 + j*100 + k*10 + l) @@ -616,28 +615,28 @@ type Array4Module() = arr1.[^1..^0, ^2..3, 1..^2, ^2..^1] <- setSlice arr2.[3..4, 2..3, 1..2, 2..3] <- setSlice - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.Equal(arr1, arr2) - [] + [] member this.``Indexer with reverse index in one dim behaves as expected``() = let arr1 = Array4D.init 5 5 5 5 (fun i j k l -> i*1000 + j*100 + k*10 + l) - Assert.That(arr1.[^1,0,0,0], Is.EqualTo(3000)) + Assert.AreEqual(arr1.[^1,0,0,0], 3000) - [] + [] member this.``Indexer with reverse index in all dim behaves as expected``() = let arr1 = Array4D.init 5 5 5 5 (fun i j k l -> i*1000 + j*100 + k*10 + l) - Assert.That(arr1.[^0,^0,^1,^0], Is.EqualTo(4434)) + Assert.AreEqual(arr1.[^0,^0,^1,^0], 4434) - [] + [] member this.``Set item with reverse index in all dims behave as expected``() = let arr1 = Array4D.create 5 5 5 5 2 arr1.[^1,^0,^0,^0] <- 9 - Assert.That(arr1.[3,4,4,4], Is.EqualTo(9)) + Assert.AreEqual(arr1.[3,4,4,4], 9) - [] + [] member this.SlicingBoundedStartEnd() = shouldEqual m1.[*,*,*,*] m1 shouldEqual m1.[0..,*,*,*] m1 @@ -717,7 +716,7 @@ type Array4Module() = |]) - [] + [] member this.SlicingOutOfBounds() = shouldBeEmpty m1.[*,*,*,7..] shouldBeEmpty m1.[*,*,*,.. -1] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs index 053b481fdae..de85233a39b 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Array module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -18,23 +18,22 @@ Make sure each method works on: * Null array (null) *) -[][][] type ArrayModule() = - [] + [] member this.Empty() = let emptyArray = Array.empty if Array.length emptyArray <> 0 then Assert.Fail() let c : int[] = Array.empty - Assert.IsTrue( (c = [| |]) ) + Assert.True( (c = [| |]) ) let d : string[] = Array.empty - Assert.IsTrue( (d = [| |]) ) + Assert.True( (d = [| |]) ) () - [] + [] member this.AllPairs() = // integer array let resultInt = Array.allPairs [|1..3|] [|2..2..6|] @@ -62,15 +61,15 @@ type ArrayModule() = () - [] + [] member this.Append() = // integer array let intArray = Array.append [| 1; 2 |] [| 3; 4 |] - Assert.IsTrue( (intArray = [| 1; 2; 3; 4 |]) ) + Assert.True( (intArray = [| 1; 2; 3; 4 |]) ) // string array let strArray = Array.append [| "a"; "b" |] [| "C"; "D" |] - Assert.IsTrue( (strArray = [| "a"; "b"; "C"; "D" |]) ) + Assert.True( (strArray = [| "a"; "b"; "C"; "D" |]) ) // empty array let emptyArray : int[] = [| |] @@ -79,8 +78,8 @@ type ArrayModule() = let appEmptySingle = Array.append emptyArray singleArray let appSingleEmpty = Array.append singleArray emptyArray - Assert.IsTrue( (appEmptySingle = [| 1 |]) ) - Assert.IsTrue( (appSingleEmpty = [| 1 |]) ) + Assert.True( (appEmptySingle = [| 1 |]) ) + Assert.True( (appSingleEmpty = [| 1 |]) ) // null array let nullArray = null:int[] @@ -90,7 +89,7 @@ type ArrayModule() = () - [] + [] member this.Average() = // empty float32 array @@ -126,7 +125,7 @@ type ArrayModule() = () - [] + [] member this.AverageBy() = // empty double array @@ -162,21 +161,21 @@ type ArrayModule() = () - [] + [] member this.ChunkBySize() = // int Seq - Assert.IsTrue([| [|1..4|]; [|5..8|] |] = Array.chunkBySize 4 [|1..8|]) - Assert.IsTrue([| [|1..4|]; [|5..8|]; [|9..10|] |] = Array.chunkBySize 4 [|1..10|]) - Assert.IsTrue([| [|1|]; [|2|]; [|3|]; [|4|] |] = Array.chunkBySize 1 [|1..4|]) - Assert.IsTrue([| [|1..3|]; [|4|] |] = Array.chunkBySize 3 [|1..4|]) - Assert.IsTrue([| [|1..5|]; [|6..10|]; [|11..12|] |] = Array.chunkBySize 5 [|1..12|]) + Assert.True([| [|1..4|]; [|5..8|] |] = Array.chunkBySize 4 [|1..8|]) + Assert.True([| [|1..4|]; [|5..8|]; [|9..10|] |] = Array.chunkBySize 4 [|1..10|]) + Assert.True([| [|1|]; [|2|]; [|3|]; [|4|] |] = Array.chunkBySize 1 [|1..4|]) + Assert.True([| [|1..3|]; [|4|] |] = Array.chunkBySize 3 [|1..4|]) + Assert.True([| [|1..5|]; [|6..10|]; [|11..12|] |] = Array.chunkBySize 5 [|1..12|]) // string Seq - Assert.IsTrue([| [|"a"; "b"|]; [|"c";"d"|]; [|"e"|] |] = Array.chunkBySize 2 [|"a";"b";"c";"d";"e"|]) + Assert.True([| [|"a"; "b"|]; [|"c";"d"|]; [|"e"|] |] = Array.chunkBySize 2 [|"a";"b";"c";"d";"e"|]) // empty Seq - Assert.IsTrue([||] = Array.chunkBySize 3 [||]) + Assert.True([||] = Array.chunkBySize 3 [||]) // null Seq let nullArr:_[] = null @@ -188,22 +187,22 @@ type ArrayModule() = () - [] + [] member this.SplitInto() = // int array - Assert.IsTrue([| [|1..4|]; [|5..7|]; [|8..10|] |] = Array.splitInto 3 [|1..10|]) - Assert.IsTrue([| [|1..4|]; [|5..8|]; [|9..11|] |] = Array.splitInto 3 [|1..11|]) - Assert.IsTrue([| [|1..4|]; [|5..8|]; [|9..12|] |] = Array.splitInto 3 [|1..12|]) + Assert.True([| [|1..4|]; [|5..7|]; [|8..10|] |] = Array.splitInto 3 [|1..10|]) + Assert.True([| [|1..4|]; [|5..8|]; [|9..11|] |] = Array.splitInto 3 [|1..11|]) + Assert.True([| [|1..4|]; [|5..8|]; [|9..12|] |] = Array.splitInto 3 [|1..12|]) - Assert.IsTrue([| [|1..2|]; [|3|]; [|4|]; [|5|] |] = Array.splitInto 4 [|1..5|]) - Assert.IsTrue([| [|1|]; [|2|]; [|3|]; [|4|] |] = Array.splitInto 20 [|1..4|]) + Assert.True([| [|1..2|]; [|3|]; [|4|]; [|5|] |] = Array.splitInto 4 [|1..5|]) + Assert.True([| [|1|]; [|2|]; [|3|]; [|4|] |] = Array.splitInto 20 [|1..4|]) // string array - Assert.IsTrue([| [|"a"; "b"|]; [|"c";"d"|]; [|"e"|] |] = Array.splitInto 3 [|"a";"b";"c";"d";"e"|]) + Assert.True([| [|"a"; "b"|]; [|"c";"d"|]; [|"e"|] |] = Array.splitInto 3 [|"a";"b";"c";"d";"e"|]) // empty array - Assert.IsTrue([| |] = Array.splitInto 3 [| |]) + Assert.True([| |] = Array.splitInto 3 [| |]) // null array let nullArr:_[] = null @@ -215,7 +214,7 @@ type ArrayModule() = () - [] + [] member this.distinct() = // distinct should work on empty array Assert.AreEqual([||], Array.distinct [||]) @@ -235,7 +234,7 @@ type ArrayModule() = let list = new System.Collections.Generic.List() Assert.AreEqual([|null, list|], Array.distinct [|null, list|]) - [] + [] member this.distinctBy() = // distinctBy should work on empty array Assert.AreEqual([||], Array.distinctBy (fun _ -> failwith "should not be executed") [||]) @@ -257,7 +256,7 @@ type ArrayModule() = let list = new System.Collections.Generic.List() Assert.AreEqual([|null, list|], Array.distinctBy id [|null, list|]) - [] + [] member this.Except() = // integer array let intArr1 = [| yield! {1..100} @@ -289,7 +288,7 @@ type ArrayModule() = () - [] + [] member this.Take() = Assert.AreEqual([||],Array.take 0 [||]) Assert.AreEqual([||],Array.take 0 [|"str1";"str2";"str3";"str4"|]) @@ -302,7 +301,7 @@ type ArrayModule() = CheckThrowsInvalidOperationExn (fun () -> Array.take 5 [|"str1";"str2";"str3";"str4"|] |> ignore) CheckThrowsArgumentNullException (fun () -> Array.take 5 null |> ignore) - [] + [] member this.takeWhile() = Assert.AreEqual([||],Array.takeWhile (fun x -> failwith "should not be used") [||]) Assert.AreEqual([|1;2;4;5|],Array.takeWhile (fun x -> x < 6) [|1;2;4;5;6;7|]) @@ -315,7 +314,7 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> Array.takeWhile (fun _ -> failwith "should not be used") null |> ignore) - [] + [] member this.splitAt() = Assert.AreEqual([||], Array.splitAt 0 [||] |> fst) Assert.AreEqual([||], Array.splitAt 0 [||] |> snd) @@ -343,7 +342,7 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> Array.splitAt 0 null |> ignore) CheckThrowsArgumentNullException (fun () -> Array.splitAt 1 null |> ignore) - [] + [] member this.replicate() = // replicate should create multiple copies of the given value Assert.AreEqual([||],Array.replicate 0 null) @@ -353,7 +352,7 @@ type ArrayModule() = CheckThrowsArgumentException (fun () -> Array.replicate -1 null |> ignore) - [] + [] member this.Blit() = // int array let intSrc = [| 1..10 |] @@ -401,7 +400,7 @@ type ArrayModule() = // empty array let emptySrc :int[] = [| |] let emptyChoosed = chooseInt funcInt emptySrc - Assert.IsTrue( (emptyChoosed = [| |]) ) + Assert.True( (emptyChoosed = [| |]) ) // null array let nullArr = null:int[] @@ -409,11 +408,11 @@ type ArrayModule() = () - [] + [] member this.Choose() = this.ChooseTester Array.choose Array.choose - [] + [] member this.``Parallel.Choose`` () = this.ChooseTester Array.Parallel.choose Array.Parallel.choose @@ -442,11 +441,11 @@ type ArrayModule() = () - [] + [] member this.Collect () = this.CollectTester Array.collect Array.collect - [] + [] member this.CollectWithSideEffects () = let stamp = ref 0 let f x = stamp := !stamp + 1; [| x |] @@ -458,11 +457,11 @@ type ArrayModule() = Array.collect f [|1;2;3|] |> ignore Assert.AreEqual(3,!stamp) - [] + [] member this.``Parallel.Collect`` () = this.CollectTester Array.Parallel.collect Array.Parallel.collect - [] + [] member this.compareWith() = // compareWith should work on empty arrays Assert.AreEqual(0,Array.compareWith (fun _ -> failwith "should not be executed") [||] [||]) @@ -487,7 +486,7 @@ type ArrayModule() = Assert.AreEqual(1,Array.compareWith (fun x y -> 1) [|"1";"2"|] [|"1";"3"|]) Assert.AreEqual(-1,Array.compareWith (fun x y -> -1) [|"1";"2"|] [|"1";"3"|]) - [] + [] member this.Concat() = // integer array let seqInt = @@ -509,7 +508,7 @@ type ArrayModule() = // Empty array let emptyArrays = [| [| |]; [| 0 |]; [| 1 |]; [| |]; [| |] |] let result2 = Array.concat emptyArrays - Assert.IsTrue(result2.[0] = 0 && result2.[1] = 1) + Assert.True(result2.[0] = 0 && result2.[1] = 1) if result2.[0] <> 0 && result2.[1] <> 1 then Assert.Fail() // null array @@ -519,7 +518,7 @@ type ArrayModule() = () - [] + [] member this.countBy() = // countBy should work on empty array Assert.AreEqual(0,Array.countBy (fun _ -> failwith "should not be executed") [||] |> Array.length) @@ -531,7 +530,7 @@ type ArrayModule() = Assert.AreEqual([| 5,1; 2,2; 3,2 |],Array.countBy id [|5;2;2;3;3|]) Assert.AreEqual([| 3,3; 2,2; 1,3 |],Array.countBy (fun x -> if x < 3 then x else 3) [|5;2;1;2;3;3;1;1|]) - [] + [] member this.Copy() = // int array let intSrc:int [] = [| 3;5;7 |] @@ -555,7 +554,7 @@ type ArrayModule() = () - [] + [] member this.Create() = // int array let intArr = Array.create 3 8 @@ -563,7 +562,7 @@ type ArrayModule() = // string array let strArr = Array.create 3 "good" - Assert.IsTrue( (strArr = [|"good"; "good"; "good"|]) ) + Assert.True( (strArr = [|"good"; "good"; "good"|]) ) // empty array let emptyArr = Array.create 0 "empty" @@ -572,12 +571,12 @@ type ArrayModule() = // array with null elements let nullStr = null:string let nullArr = Array.create 3 nullStr - Assert.IsTrue( (nullArr = [|null; null; null|]) ) + Assert.True( (nullArr = [|null; null; null|]) ) () - [] + [] member this.TryHead() = // integer array let resultInt = Array.tryHead [|2..2..20|] @@ -596,7 +595,7 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> Array.tryHead nullArr |> ignore) () - [] + [] member this.Exists() = // integer array let intArr = [| 2;4;6;8 |] @@ -621,7 +620,7 @@ type ArrayModule() = () - [] + [] member this.Exists2() = // integer array let intFir = [| 2;4;6;8 |] @@ -654,7 +653,7 @@ type ArrayModule() = () - [] + [] member this.Fill() = // integer array let intArr = [|1..5|] @@ -685,7 +684,7 @@ type ArrayModule() = () - [] + [] member this.Filter() = // integer array let intArr = [| 1..20 |] @@ -710,7 +709,7 @@ type ArrayModule() = () - [] + [] member this.Filter2 () = // The Array.filter algorithm uses a bitmask as a temporary storage mechanism // for which elements to filter. This introduces some possible error conditions @@ -768,7 +767,7 @@ type ArrayModule() = - [] + [] member this.Where() = // integer array let intArr = [| 1..20 |] @@ -793,13 +792,13 @@ type ArrayModule() = () - [] + [] member this.``where should work like filter``() = Assert.AreEqual([||], Array.where (fun x -> x % 2 = 0) [||]) Assert.AreEqual([|0;2;4;6;8|], Array.where (fun x -> x % 2 = 0) [|0..9|]) Assert.AreEqual([|"a";"b";"c"|], Array.where (fun _ -> true) [|"a";"b";"c"|]) - [] + [] member this.Find() = // integer array let intArr = [| 1..20 |] @@ -826,7 +825,7 @@ type ArrayModule() = () - [] + [] member this.FindBack() = // integer array let funcInt x = if (x%5 = 0) then true else false @@ -852,7 +851,7 @@ type ArrayModule() = () - [] + [] member this.FindIndex() = // integer array let intArr = [| 1..20 |] @@ -879,7 +878,7 @@ type ArrayModule() = () - [] + [] member this.FindIndexBack() = // integer array let funcInt x = if (x%5 = 0) then true else false @@ -905,7 +904,7 @@ type ArrayModule() = () - [] + [] member this.Pick() = // integers let intArr = [| 1..10 |] @@ -918,7 +917,7 @@ type ArrayModule() = // make it not found CheckThrowsKeyNotFoundException (fun () -> Array.pick (fun n -> None) intArr |> ignore) - [] + [] member this.last() = // last should fail on empty array CheckThrowsArgumentException(fun () -> Array.last [||] |> ignore) @@ -931,7 +930,7 @@ type ArrayModule() = Assert.AreEqual("2", Array.last [|"1"; "3"; "2"|]) Assert.AreEqual(["4"], Array.last [|["1"; "3"]; []; ["4"]|]) - [] + [] member this.TryLast() = // integers array let IntSeq = [| 1..9 |] @@ -944,21 +943,21 @@ type ArrayModule() = // Empty array let emptyResult = Array.tryLast Array.empty - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) // null array let nullArr = null:string[] CheckThrowsArgumentNullException (fun () ->Array.tryLast nullArr |> ignore) () - [] + [] member this.ToSeq() = let intArr = [| 1..10 |] let seq = Array.toSeq intArr let sum = Seq.sum seq Assert.AreEqual(55, sum) - [] + [] member this.TryPick() = // integer array let intArr = [| 1..10 |] @@ -989,7 +988,7 @@ type ArrayModule() = () - [] + [] member this.Fold() = // integer array let intArr = [| 1..5 |] @@ -1015,7 +1014,7 @@ type ArrayModule() = () - [] + [] member this.Fold2() = // integer array let funcInt x y z = x + y.ToString() + z.ToString() @@ -1043,7 +1042,7 @@ type ArrayModule() = () - [] + [] member this.FoldBack() = // integer array let intArr = [| 1..5 |] @@ -1069,7 +1068,7 @@ type ArrayModule() = () - [] + [] member this.FoldBack2() = // integer array let funcInt x y z = x.ToString() + y.ToString() + z @@ -1097,7 +1096,7 @@ type ArrayModule() = () - [] + [] member this.ForAll() = // integer array let resultInt = Array.forall (fun x -> x > 2) [| 3..2..10 |] @@ -1117,7 +1116,7 @@ type ArrayModule() = () - [] + [] member this.ForAll2() = // integer array let resultInt = Array.forall2 (fun x y -> x < y) [| 1..10 |] [|2..2..20|] @@ -1142,7 +1141,7 @@ type ArrayModule() = () - [] + [] member this.Get() = // integer array let intArr = [| 3;4;7;8;10 |] @@ -1165,43 +1164,43 @@ type ArrayModule() = () - [] + [] member this.``exactlyOne should return the element from singleton arrays``() = Assert.AreEqual(1, Array.exactlyOne [|1|]) Assert.AreEqual("2", Array.exactlyOne [|"2"|]) () - [] + [] member this.``exactlyOne should fail on empty array``() = CheckThrowsArgumentException(fun () -> Array.exactlyOne [||] |> ignore) - [] + [] member this.``exactlyOne should fail on null array``() = CheckThrowsArgumentNullException(fun () -> Array.exactlyOne null |> ignore) - [] + [] member this.``exactlyOne should fail on arrays with more than one element``() = CheckThrowsArgumentException(fun () -> Array.exactlyOne [|"1"; "2"|] |> ignore) - [] + [] member this.``tryExactlyOne should return the element from singleton arrays``() = Assert.AreEqual(Some 1, Array.tryExactlyOne [|1|]) Assert.AreEqual(Some "2", Array.tryExactlyOne [|"2"|]) () - [] + [] member this.``tryExactlyOne should return None on empty array``() = Assert.AreEqual(None, Array.tryExactlyOne [||]) - [] + [] member this.``tryExactlyOne should return None for arrays with more than one element``() = Assert.AreEqual(None, Array.tryExactlyOne [|"1"; "2"|]) - [] + [] member this.``tryExactlyOne should fail on null array``() = CheckThrowsArgumentNullException(fun () -> Array.tryExactlyOne null |> ignore) - [] + [] member this.GroupBy() = let funcInt x = x%5 @@ -1259,7 +1258,7 @@ type ArrayModule() = () - [] + [] member this.Hd() = // integer array let resultInt = Array.head [|2..2..20|] @@ -1273,11 +1272,11 @@ type ArrayModule() = CheckThrowsArgumentNullException(fun () -> Array.head null |> ignore) () - [] + [] member this.Init() = this.InitTester Array.init Array.init - [] + [] member this.InitWithSideEffects () = let stamp = ref 0 let f i = @@ -1290,11 +1289,11 @@ type ArrayModule() = Array.init 10 f |> ignore Assert.AreEqual (10, !stamp) - [] + [] member this.``Parallel.Init``() = this.InitTester Array.Parallel.init Array.Parallel.init - [] + [] member this.IsEmpty() = // integer array let intArr = [| 3;4;7;8;10 |] @@ -1317,7 +1316,7 @@ type ArrayModule() = () - [] + [] member this.Iter() = // integer array let intArr = [| 1..10 |] @@ -1349,7 +1348,7 @@ type ArrayModule() = () - [] + [] member this.Iter2() = // integer array let resultInt = ref 0 @@ -1385,7 +1384,7 @@ type ArrayModule() = () - [] + [] member this.Iteri() = // integer array let intArr = [| 1..10 |] @@ -1417,7 +1416,7 @@ type ArrayModule() = () - [] + [] member this.Iteri2() = // integer array let resultInt = ref 0 @@ -1452,7 +1451,7 @@ type ArrayModule() = () - [] + [] member this.``pairwise should return pairs of the input array``() = Assert.AreEqual([||],Array.pairwise [||]) Assert.AreEqual([||],Array.pairwise [|1|]) @@ -1460,7 +1459,7 @@ type ArrayModule() = Assert.AreEqual([|1,2; 2,3|],Array.pairwise [|1;2;3|]) Assert.AreEqual([|"H","E"; "E","L"; "L","L"; "L","O"|],Array.pairwise [|"H";"E";"L";"L";"O"|]) - [] + [] member this.``pairwise should not work on null``() = CheckThrowsArgumentNullException(fun () -> Array.pairwise null |> ignore) @@ -1484,11 +1483,11 @@ type ArrayModule() = () - [] + [] member this.Map () = this.MapTester Array.map Array.map - [] + [] member this.MapWithSideEffects () = let stamp = ref 0 let f x = stamp := !stamp + 1; x + 1 @@ -1500,7 +1499,7 @@ type ArrayModule() = Array.map f [| 1..100 |] |> ignore Assert.AreEqual(100,!stamp) - [] + [] member this.``Parallel.Map`` () = this.MapTester Array.Parallel.map Array.Parallel.map @@ -1523,11 +1522,11 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> mapiInt f nullArg |> ignore) () - [] + [] member this.Mapi () = this.MapiTester Array.mapi Array.mapi - [] + [] member this.MapiWithSideEffects () = let stamp = ref 0 let f i x = stamp := !stamp + 1; (i, x + 1) @@ -1540,12 +1539,12 @@ type ArrayModule() = Assert.AreEqual(100,!stamp) () - [] + [] member this.``Parallel.Mapi`` () = this.MapiTester Array.Parallel.mapi Array.Parallel.mapi () - [] + [] member this.``Parallel.Iter``() = // integer array let intArr = [| 1..10 |] @@ -1577,7 +1576,7 @@ type ArrayModule() = () - [] + [] member this.``Parallel.Iteri``() = // integer array let intArr = [| 1..10 |] @@ -1642,75 +1641,75 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> partString funcString nullArr |> ignore) - [] + [] member this.Partition () = this.PartitionTester Array.partition Array.partition - [] + [] member this.Singleton() = Assert.AreEqual([|null|],Array.singleton null) Assert.AreEqual([|"1"|],Array.singleton "1") Assert.AreEqual([|[]|], Array.singleton []) - Assert.IsTrue([|[||]|] = Array.singleton [||]) + Assert.True([|[||]|] = Array.singleton [||]) - [] + [] member this.``Parallel.Partition`` () = this.PartitionTester Array.Parallel.partition Array.Parallel.partition - [] + [] member this.Contains() = // integer array let intArr = [| 2;4;6;8 |] let resultInt = Array.contains 6 intArr - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string array let strArr = [|"Lists"; "are"; "commonly"|] let resultStr = Array.contains "not" strArr - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty array let emptyArr:int[] = [| |] let resultEpt = Array.contains 4 emptyArr - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) // null array let nullArr = null:string[] CheckThrowsArgumentNullException (fun () -> Array.contains "empty" nullArr |> ignore) - [] + [] member this.``Slicing with first index reverse behaves as expected``() = let arr = [| 1;2;3;4;5 |] - Assert.That(arr.[^3..], Is.EquivalentTo(arr.[1..])) + Assert.AreEqual(arr.[^3..], arr.[1..]) - [] + [] member this.``Slicing with second index reverse behaves as expected``() = let arr = [| 1;2;3;4;5 |] - Assert.That(arr.[..^1], Is.EquivalentTo(arr.[..3])) + Assert.AreEqual(arr.[..^1], arr.[..3]) - [] + [] member this.``Slicing with both index reverse behaves as expected``() = let arr = [| 1;2;3;4;5 |] - Assert.That(arr.[^3..^1], Is.EquivalentTo(arr.[1..3])) + Assert.AreEqual(arr.[^3..^1], arr.[1..3]) - [] + [] member this.``Slicing with first index reverse and second index non reverse behaves as expected``()= let arr = [|1;2;3;4;5|] - Assert.That(arr.[^3..4], Is.EquivalentTo(arr.[1..4])) + Assert.AreEqual(arr.[^3..4], arr.[1..4]) - [] + [] member this.``Slicing with first index non reverse and second index reverse behaves as expected``()= let arr = [|1;2;3;4;5|] - Assert.That(arr.[3..^0], Is.EquivalentTo(arr.[3..4])) + Assert.AreEqual(arr.[3..^0], arr.[3..4]) - [] + [] member this.``Set slice with first index reverse behaves as expected``() = let arr1 = [| 1;2;3;4;5 |] let arr2 = [| 1;2;3;4;5 |] @@ -1718,10 +1717,9 @@ type ArrayModule() = arr1.[^3..] <- [| 9;8;7;6 |] arr2.[1..] <- [| 9;8;7;6 |] - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.AreEqual(arr1, arr2) - - [] + [] member this.``Set slice with second index reverse behaves as expected``() = let arr1 = [| 1;2;3;4;5 |] let arr2 = [| 1;2;3;4;5 |] @@ -1729,10 +1727,9 @@ type ArrayModule() = arr1.[..^1] <- [| 9;8;7;6 |] arr2.[..3] <- [| 9;8;7;6 |] - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.AreEqual(arr1, arr2) - - [] + [] member this.``Set slice with both index reverse behaves as expected``() = let arr1 = [| 1;2;3;4;5 |] let arr2 = [| 1;2;3;4;5 |] @@ -1740,22 +1737,21 @@ type ArrayModule() = arr1.[^3..^1] <- [| 8;7;6 |] arr2.[1..3] <- [| 8;7;6 |] - Assert.That(arr1, Is.EquivalentTo(arr2)) + Assert.AreEqual(arr1, arr2) - [] + [] member this.``Get item with reverse index behaves as expected``() = let arr = [|1;2;3;4;5|] + Assert.AreEqual(arr.[^1], 4) - Assert.That(arr.[^1], Is.EqualTo(4)) - - [] + [] member this.``Set item with reverse index behaves as expected``() = let arr = [|1;2;3;4;5|] arr.[^0] <- 9 - Assert.That(arr.[4], Is.EqualTo(9)) + Assert.AreEqual(arr.[4], 9) - [] + [] member this.SlicingUnboundedEnd() = let arr = [|1;2;3;4;5;6|] @@ -1768,7 +1764,7 @@ type ArrayModule() = Assert.AreEqual(arr.[7..], ([||]: int array)) - [] + [] member this.SlicingUnboundedStart() = let arr = [|1;2;3;4;5;6|] @@ -1783,7 +1779,7 @@ type ArrayModule() = Assert.AreEqual(arr.[..7], [|1;2;3;4;5;6|]) - [] + [] member this.SlicingBoundedStartEnd() = let arr = [|1;2;3;4;5;6|] @@ -1809,7 +1805,7 @@ type ArrayModule() = Assert.AreEqual(arr.[4..1], ([||]: int array)) - [] + [] member this.SlicingEmptyArray() = let empty : obj array = Array.empty @@ -1821,7 +1817,7 @@ type ArrayModule() = Assert.AreEqual(empty.[3..5], ([||]: obj array)) - [] + [] member this.SlicingOutOfBounds() = let arr = [|1;2;3;4;5;6|] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index 20a6a0d7af3..def67cd5713 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Array module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -26,10 +26,9 @@ type ArrayWindowedTestInput<'t> = Exception : Type option } -[][][] type ArrayModule2() = - [] + [] member this.Length() = // integer array let resultInt = Array.length [|1..8|] @@ -45,11 +44,17 @@ type ArrayModule2() = // null array let nullArr = null:string[] - CheckThrowsNullRefException (fun () -> Array.length nullArr |> ignore) + CheckThrowsArgumentNullException (fun () -> Array.length nullArr |> ignore) + // null array, argument name showing up + try + Array.length nullArr |> ignore + with + | :? ArgumentNullException as e -> Assert.Equal("array", e.ParamName) |> ignore + () - [] + [] member this.Indexed() = // integer array let resultInt = Array.indexed [|10..2..20|] @@ -71,7 +76,7 @@ type ArrayModule2() = () - [] + [] member this.Map() = // integer array let funcInt x = @@ -96,7 +101,7 @@ type ArrayModule2() = () - [] + [] member this.Map2() = // integer array let funcInt x y = x+y @@ -124,7 +129,7 @@ type ArrayModule2() = () - [] + [] member this.Map3() = // Integer array let funcInt a b c = (a + b) * c @@ -156,7 +161,7 @@ type ArrayModule2() = () - [] + [] member this.MapFold() = // integer array let funcInt acc x = if x % 2 = 0 then 10*x, acc + 1 else x, acc @@ -181,7 +186,7 @@ type ArrayModule2() = () - [] + [] member this.MapFoldBack() = // integer array let funcInt x acc = if acc < 105 then 10*x, acc + 2 else x, acc @@ -206,7 +211,7 @@ type ArrayModule2() = () - [] + [] member this.Mapi() = // integer array let funcInt x y = x+y @@ -229,7 +234,7 @@ type ArrayModule2() = () - [] + [] member this.mapi2() = // integer array let funcInt x y z = x+y+z @@ -257,7 +262,7 @@ type ArrayModule2() = () - [] + [] member this.Max() = // integer array let resultInt = Array.max [|2..2..20|] @@ -278,7 +283,7 @@ type ArrayModule2() = () - [] + [] member this.MaxBy()= // integer array let funcInt x = x%8 @@ -301,7 +306,7 @@ type ArrayModule2() = () - [] + [] member this.Min() = // integer array let resultInt = Array.min [|3;7;8;9;4;1;1;2|] @@ -322,7 +327,7 @@ type ArrayModule2() = () - [] + [] member this.MinBy()= // integer array let funcInt x = x%8 @@ -346,7 +351,7 @@ type ArrayModule2() = () - [] + [] member this.Of_List() = // integer array let resultInt = Array.ofList [1..10] @@ -364,7 +369,7 @@ type ArrayModule2() = () - [] + [] member this.Of_Seq() = // integer array let resultInt = Array.ofSeq {1..10} @@ -382,7 +387,7 @@ type ArrayModule2() = () - [] + [] member this.Partition() = // integer array let resultInt = Array.partition (fun x -> x%3 = 0) [|1..10|] @@ -402,7 +407,7 @@ type ArrayModule2() = () - [] + [] member this.Permute() = // integer array let resultInt = Array.permute (fun i -> (i+1) % 4) [|1;2;3;4|] @@ -422,7 +427,7 @@ type ArrayModule2() = () - [] + [] member this.Reduce() = // integer array let resultInt = Array.reduce (fun x y -> x/y) [|5*4*3*2; 4;3;2;1|] @@ -442,7 +447,7 @@ type ArrayModule2() = () - [] + [] member this.ReduceBack() = // integer array let resultInt = Array.reduceBack (fun x y -> x/y) [|5*4*3*2; 4;3;2;1|] @@ -462,7 +467,7 @@ type ArrayModule2() = () - [] + [] member this.Rev() = // integer array let resultInt = Array.rev [|1..10|] @@ -481,7 +486,7 @@ type ArrayModule2() = CheckThrowsArgumentNullException (fun () -> Array.rev nullArr |> ignore) () - [] + [] member this.Scan() = // integer array let funcInt x y = x+y @@ -503,7 +508,7 @@ type ArrayModule2() = () - [] + [] member this.ScanBack() = // integer array let funcInt x y = x+y @@ -525,7 +530,7 @@ type ArrayModule2() = () - [] + [] member this.Skip() = // integer array let resultInt = Array.skip 2 [|1..10|] @@ -551,7 +556,7 @@ type ArrayModule2() = CheckThrowsArgumentException (fun () -> Array.skip 1 [||] |> ignore) CheckThrowsArgumentException (fun () -> Array.skip 4 [|1; 2; 3|] |> ignore) - [] + [] member this.SkipWhile() = // integer array let funcInt x = (x < 4) @@ -582,7 +587,7 @@ type ArrayModule2() = () - [] + [] member this.Set() = // integer array let intArr = [|10;9;8;7|] @@ -602,7 +607,7 @@ type ArrayModule2() = () - [] + [] member this.sortInPlaceWith() = // integer array let intArr = [|3;5;7;2;4;8|] @@ -641,7 +646,7 @@ type ArrayModule2() = () - [] + [] member this.sortInPlaceBy() = // integer array let intArr = [|3;5;7;2;4;8|] @@ -671,7 +676,7 @@ type ArrayModule2() = () - [] + [] member this.SortDescending() = // integer array let intArr = [|3;5;7;2;4;8|] @@ -707,7 +712,7 @@ type ArrayModule2() = () - [] + [] member this.SortByDescending() = // integer array let intArr = [|3;5;7;2;4;8|] @@ -746,7 +751,7 @@ type ArrayModule2() = () - [] + [] member this.Sub() = // integer array let resultInt = Array.sub [|1..8|] 3 3 @@ -771,7 +776,7 @@ type ArrayModule2() = () - [] + [] member this.Sum() = // empty integer array let resultEptInt = Array.sum ([||]:int[]) @@ -817,7 +822,7 @@ type ArrayModule2() = CheckThrowsArgumentNullException (fun () -> Array.sum nullArr |> ignore) () - [] + [] member this.SumBy() = // empty integer array let resultEptInt = Array.sumBy int ([||]:int[]) @@ -845,7 +850,7 @@ type ArrayModule2() = // float32 array let floatArray: string[] = [| "1.2";"3.5";"6.7" |] let resultFloat = Array.sumBy float32 floatArray - if resultFloat <> 11.4f then Assert.Fail() + if abs (resultFloat - 11.4f) > 0.00000001f then Assert.Fail() // double array let doubleArray: System.Double[] = [| 1.0;8.0 |] @@ -862,7 +867,7 @@ type ArrayModule2() = CheckThrowsArgumentNullException (fun () -> Array.sumBy float32 nullArr |> ignore) () - [] + [] member this.Tl() = // integer array let resultInt = Array.tail [|1..10|] @@ -881,7 +886,7 @@ type ArrayModule2() = CheckThrowsArgumentNullException(fun () -> Array.tail null |> ignore) () - [] + [] member this.To_List() = // integer array let resultInt = Array.toList [|1..10|] @@ -901,7 +906,7 @@ type ArrayModule2() = () - [] + [] member this.To_Seq() = // integer array let resultInt = [|1..10|] |> Array.toSeq |> Array.ofSeq @@ -921,7 +926,7 @@ type ArrayModule2() = () - [] + [] member this.Transpose() = // integer array Assert.AreEqual([|[|1;4|]; [|2;5|]; [|3;6|]|], Array.transpose (seq [[|1..3|]; [|4..6|]])) @@ -946,7 +951,7 @@ type ArrayModule2() = CheckThrowsArgumentException (fun () -> Array.transpose [| [|1; 2|]; [|3|] |] |> ignore) CheckThrowsArgumentException (fun () -> Array.transpose [| [|1|]; [|2; 3|] |] |> ignore) - [] + [] member this.Truncate() = // integer array Assert.AreEqual([|1..3|], Array.truncate 3 [|1..5|]) @@ -969,7 +974,7 @@ type ArrayModule2() = () - [] + [] member this.TryFind() = // integer array let resultInt = [|1..10|] |> Array.tryFind (fun x -> x%7 = 0) @@ -989,7 +994,7 @@ type ArrayModule2() = () - [] + [] member this.TryFindBack() = // integer array let funcInt x = x%5 = 0 @@ -1013,7 +1018,7 @@ type ArrayModule2() = () - [] + [] member this.TryFindIndex() = // integer array let resultInt = [|1..10|] |> Array.tryFindIndex (fun x -> x%7 = 0) @@ -1033,7 +1038,7 @@ type ArrayModule2() = () - [] + [] member this.TryFindIndexBack() = // integer array let funcInt x = x%5 = 0 @@ -1057,7 +1062,7 @@ type ArrayModule2() = () - [] + [] member this.Unfold() = // integer Seq let resultInt = Array.unfold (fun x -> if x < 20 then Some (x+1,x*2) else None) 1 @@ -1073,7 +1078,7 @@ type ArrayModule2() = () - [] + [] member this.Unzip() = // integer array let resultInt = Array.unzip [|(1,2);(2,4);(3,6)|] @@ -1092,7 +1097,7 @@ type ArrayModule2() = () - [] + [] member this.Unzip3() = // integer array let resultInt = Array.unzip3 [|(1,2,3);(2,4,6);(3,6,9)|] @@ -1110,13 +1115,13 @@ type ArrayModule2() = () - [] + [] member this.Windowed() = let testWindowed config = try config.InputArray |> Array.windowed config.WindowSize - |> (fun actual -> Assert.IsTrue(config.ExpectedArray = actual)) + |> (fun actual -> Assert.True(config.ExpectedArray = actual)) with | _ when Option.isNone config.Exception -> Assert.Fail() | e when e.GetType() = (Option.get config.Exception) -> () @@ -1194,13 +1199,13 @@ type ArrayModule2() = if windowSize <= 0 then CheckThrowsArgumentException (fun () -> Array.windowed windowSize [|1..arraySize|] |> ignore) elif arraySize < windowSize then - Assert.IsTrue([||] = Array.windowed windowSize [|1..arraySize|]) + Assert.True([||] = Array.windowed windowSize [|1..arraySize|]) else - Assert.IsTrue(expectedArrays.[arraySize, windowSize] = Array.windowed windowSize [|1..arraySize|]) + Assert.True(expectedArrays.[arraySize, windowSize] = Array.windowed windowSize [|1..arraySize|]) () - [] + [] member this.Zero_Create() = // Check for bogus input @@ -1220,12 +1225,12 @@ type ArrayModule2() = () - [] + [] member this.BadCreateArguments() = // negative number CheckThrowsArgumentException (fun () -> Array.create -1 0 |> ignore) - [] + [] member this.Zip() = // integer array let resultInt = Array.zip [|1..3|] [|2..2..6|] @@ -1248,7 +1253,7 @@ type ArrayModule2() = () - [] + [] member this.Zip3() = // integer array let resultInt = Array.zip3 [|1..3|] [|2..2..6|] [|3;6;9|] @@ -1274,7 +1279,7 @@ type ArrayModule2() = () - [] + [] member this.Item() = // integer array let resultInt = Array.item 3 [|1..8|] @@ -1299,7 +1304,7 @@ type ArrayModule2() = for i = 11 to 20 do CheckThrowsIndexOutRangException (fun () -> Array.item i [|1..8|] |> ignore) - [] + [] member this.tryItem() = // integer array let intArr = [| 3;4;7;8;10 |] @@ -1327,3 +1332,88 @@ type ArrayModule2() = // Index greater than length let resultIndexGreater = Array.tryItem 14 [| 3;1;6;2 |] Assert.AreEqual(None, resultIndexGreater) + + [] + member this.RemoveAt() = + // integer list + Assert.AreEqual([|2; 3; 4; 5|], (Array.removeAt 0 [|1..5|])) + Assert.AreEqual([|1; 2; 4; 5|], (Array.removeAt 2 [|1..5|])) + Assert.AreEqual([|1; 2; 3; 4|], (Array.removeAt 4 [|1..5|])) + + //string list + Assert.AreEqual([|"2"; "3"; "4"; "5"|], (Array.removeAt 0 [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "4"; "5"|], (Array.removeAt 2 [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "3"; "4"|], (Array.removeAt 4 [|"1"; "2"; "3"; "4"; "5"|])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Array.removeAt 0 [||] |> ignore) + CheckThrowsArgumentException (fun () -> Array.removeAt -1 [|1|] |> ignore) + CheckThrowsArgumentException (fun () -> Array.removeAt 2 [|1|] |> ignore) + + [] + member this.RemoveManyAt() = + // integer list + Assert.AreEqual([|3; 4; 5|], (Array.removeManyAt 0 2 [|1..5|])) + Assert.AreEqual([|1; 2; 5|], (Array.removeManyAt 2 2 [|1..5|])) + Assert.AreEqual([|1; 2; 3|], (Array.removeManyAt 3 2 [|1..5|])) + + //string list + Assert.AreEqual([|"3"; "4"; "5"|], (Array.removeManyAt 0 2 [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "5"|], (Array.removeManyAt 2 2 [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "3"|], (Array.removeManyAt 3 2 [|"1"; "2"; "3"; "4"; "5"|])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Array.removeManyAt 0 2 [||] |> ignore) + CheckThrowsArgumentException (fun () -> Array.removeManyAt -1 2 [|1|] |> ignore) + CheckThrowsArgumentException (fun () -> Array.removeManyAt 2 2 [|1|] |> ignore) + + [] + member this.UpdateAt() = + // integer list + Assert.AreEqual([|0; 2; 3; 4; 5|], (Array.updateAt 0 0 [|1..5|])) + Assert.AreEqual([|1; 2; 0; 4; 5|], (Array.updateAt 2 0 [|1..5|])) + Assert.AreEqual([|1; 2; 3; 4; 0|], (Array.updateAt 4 0 [|1..5|])) + + //string list + Assert.AreEqual([|"0"; "2"; "3"; "4"; "5"|], (Array.updateAt 0 "0" [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "0"; "4"; "5"|], (Array.updateAt 2 "0" [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "3"; "4"; "0"|], (Array.updateAt 4 "0" [|"1"; "2"; "3"; "4"; "5"|])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Array.updateAt 0 0 [||] |> ignore) + CheckThrowsArgumentException (fun () -> Array.updateAt -1 0 [|1|] |> ignore) + CheckThrowsArgumentException (fun () -> Array.updateAt 2 0 [|1|] |> ignore) + + [] + member this.InsertAt() = + // integer list + Assert.AreEqual([|0; 1; 2; 3; 4; 5|], (Array.insertAt 0 0 [|1..5|])) + Assert.AreEqual([|1; 2; 0; 3; 4; 5|], (Array.insertAt 2 0 [|1..5|])) + Assert.AreEqual([|1; 2; 3; 4; 0; 5|], (Array.insertAt 4 0 [|1..5|])) + + //string list + Assert.AreEqual([|"0"; "1"; "2"; "3"; "4"; "5"|], (Array.insertAt 0 "0" [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "0"; "3"; "4"; "5"|], (Array.insertAt 2 "0" [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "3"; "4"; "0"; "5"|], (Array.insertAt 4 "0" [|"1"; "2"; "3"; "4"; "5"|])) + + // empty list & out of bounds + Assert.AreEqual([0], Array.insertAt 0 0 [||]) + CheckThrowsArgumentException (fun () -> Array.insertAt -1 0 [|1|] |> ignore) + CheckThrowsArgumentException (fun () -> Array.insertAt 2 0 [|1|] |> ignore) + + [] + member this.InsertManyAt() = + // integer list + Assert.AreEqual([|0; 0; 1; 2; 3; 4; 5|], (Array.insertManyAt 0 [0; 0] [|1..5|])) + Assert.AreEqual([|1; 2; 0; 0; 3; 4; 5|], (Array.insertManyAt 2 [0; 0] [|1..5|])) + Assert.AreEqual([|1; 2; 3; 4; 0; 0; 5|], (Array.insertManyAt 4 [0; 0] [|1..5|])) + + //string list + Assert.AreEqual([|"0"; "0"; "1"; "2"; "3"; "4"; "5"|], (Array.insertManyAt 0 ["0"; "0"] [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "0"; "0"; "3"; "4"; "5"|], (Array.insertManyAt 2 ["0"; "0"] [|"1"; "2"; "3"; "4"; "5"|])) + Assert.AreEqual([|"1"; "2"; "3"; "4"; "0"; "0"; "5"|], (Array.insertManyAt 4 ["0"; "0"] [|"1"; "2"; "3"; "4"; "5"|])) + + // empty list & out of bounds + Assert.AreEqual([0; 0], Array.insertManyAt 0 [0; 0] [||]) + CheckThrowsArgumentException (fun () -> Array.insertManyAt -1 [0; 0] [|1|] |> ignore) + CheckThrowsArgumentException (fun () -> Array.insertManyAt 2 [0; 0] [|1|] |> ignore) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayProperties.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayProperties.fs index 941cfc9de44..13afd8cc3c1 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayProperties.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayProperties.fs @@ -1,33 +1,33 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -[][] -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.ArrayProperties +module FSharp.Core.UnitTests.Collections.ArrayProperties open System open System.Collections.Generic -open NUnit.Framework + +open Xunit open FsCheck open Utils let isStable sorted = sorted |> Seq.pairwise |> Seq.forall (fun ((ia, a),(ib, b)) -> if a = b then ia < ib else true) - + let distinctByStable<'a when 'a : comparison> (xs : 'a []) = let indexed = xs |> Seq.indexed |> Seq.toArray let sorted = indexed |> Array.distinctBy snd isStable sorted - -[] + +[] let ``Array.distinctBy is stable`` () = Check.QuickThrowOnFailure distinctByStable Check.QuickThrowOnFailure distinctByStable - + let blitWorksLikeCopy<'a when 'a : comparison> (source : 'a [], sourceIndex, target : 'a [], targetIndex, count) = let target1 = Array.copy target let target2 = Array.copy target let a = runAndCheckIfAnyError (fun () -> Array.blit source sourceIndex target1 targetIndex count) let b = runAndCheckIfAnyError (fun () -> Array.Copy(source, sourceIndex, target2, targetIndex, count)) a = b && target1 = target2 - -[] + +[] let ``Array.blit works like Array.Copy`` () = Check.QuickThrowOnFailure blitWorksLikeCopy Check.QuickThrowOnFailure blitWorksLikeCopy diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs index 2e61ae920d0..951f9711d68 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs @@ -1,13 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -[] -[] -[] -[] -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.CollectionModulesConsistency +module FSharp.Core.UnitTests.Collections.CollectionModulesConsistency open System open System.Collections.Generic -open NUnit.Framework +open Xunit open FsCheck open Utils @@ -25,7 +21,7 @@ let allPairs<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) = let a = xs |> List.toArray |> Array.allPairs (List.toArray xs2) consistency "allPairs" s l a -[] +[] let ``allPairs is consistent`` () = smallerSizeCheck allPairs smallerSizeCheck allPairs @@ -38,7 +34,7 @@ let append<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) = consistency "append" s l a -[] +[] let ``append is consistent`` () = smallerSizeCheck append smallerSizeCheck append @@ -51,7 +47,7 @@ let averageFloat (xs : NormalFloat []) = let a = runAndCheckErrorType (fun () -> xs |> Array.average) consistency "average" s l a -[] +[] let ``average is consistent`` () = smallerSizeCheck averageFloat @@ -64,7 +60,7 @@ let averageBy (xs : float []) f = consistency "averageBy" s l a -[] +[] let ``averageBy is consistent`` () = smallerSizeCheck averageBy @@ -75,7 +71,7 @@ let contains<'a when 'a : equality> (xs : 'a []) x = consistency "contains" s l a -[] +[] let ``contains is consistent`` () = smallerSizeCheck contains smallerSizeCheck contains @@ -87,7 +83,7 @@ let choose<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.choose f consistency "contains" s l a -[] +[] let ``choose is consistent`` () = smallerSizeCheck choose smallerSizeCheck choose @@ -106,7 +102,7 @@ let chunkBySize<'a when 'a : equality> (xs : 'a []) size = consistency "chunkBySize" s l a -[] +[] let ``chunkBySize is consistent`` () = smallerSizeCheck chunkBySize smallerSizeCheck chunkBySize @@ -120,7 +116,7 @@ let collect<'a> (xs : 'a []) f = -[] +[] let ``collect is consistent`` () = smallerSizeCheck collect smallerSizeCheck collect @@ -134,7 +130,7 @@ let compareWith<'a>(xs : 'a []) (xs2 : 'a []) f = -[] +[] let ``compareWith is consistent`` () = smallerSizeCheck compareWith smallerSizeCheck compareWith @@ -146,7 +142,7 @@ let concat<'a when 'a : equality> (xs : 'a [][]) = let a = xs |> Array.concat consistency "concat" s l a -[] +[] let ``concat is consistent`` () = smallerSizeCheck concat smallerSizeCheck concat @@ -158,7 +154,7 @@ let countBy<'a> (xs : 'a []) f = let a = xs |> Array.countBy f consistency "countBy" s l a -[] +[] let ``countBy is consistent`` () = smallerSizeCheck countBy smallerSizeCheck countBy @@ -170,7 +166,7 @@ let distinct<'a when 'a : comparison> (xs : 'a []) = let a = xs |> Array.distinct consistency "distinct" s l a -[] +[] let ``distinct is consistent`` () = smallerSizeCheck distinct smallerSizeCheck distinct @@ -182,7 +178,7 @@ let distinctBy<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.distinctBy f consistency "distinctBy" s l a -[] +[] let ``distinctBy is consistent`` () = smallerSizeCheck distinctBy smallerSizeCheck distinctBy @@ -194,7 +190,7 @@ let exactlyOne<'a when 'a : comparison> (xs : 'a []) = let a = runAndCheckErrorType (fun () -> xs |> Array.exactlyOne) consistency "exactlyOne" s l a -[] +[] let ``exactlyOne is consistent`` () = smallerSizeCheck exactlyOne smallerSizeCheck exactlyOne @@ -206,7 +202,7 @@ let tryExactlyOne<'a when 'a : comparison> (xs : 'a []) = let a = runAndCheckErrorType (fun () -> xs |> Array.tryExactlyOne) consistency "tryExactlyOne" s l a -[] +[] let ``tryExactlyOne is consistent`` () = smallerSizeCheck tryExactlyOne smallerSizeCheck tryExactlyOne @@ -218,7 +214,7 @@ let except<'a when 'a : equality> (xs : 'a []) (itemsToExclude: 'a []) = let a = xs |> Array.except itemsToExclude consistency "except" s l a -[] +[] let ``except is consistent`` () = smallerSizeCheck except smallerSizeCheck except @@ -230,7 +226,7 @@ let exists<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.exists f consistency "exists" s l a -[] +[] let ``exists is consistent`` () = smallerSizeCheck exists smallerSizeCheck exists @@ -244,7 +240,7 @@ let exists2<'a when 'a : equality> (xs':('a*'a) []) f = let a = runAndCheckErrorType (fun () -> Array.exists2 f (Array.ofSeq xs) (Array.ofSeq xs2)) consistency "exists2" s l a -[] +[] let ``exists2 is consistent for collections with equal length`` () = smallerSizeCheck exists2 smallerSizeCheck exists2 @@ -256,7 +252,7 @@ let filter<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.filter predicate Seq.toArray s = a && List.toArray l = a -[] +[] let ``filter is consistent`` () = smallerSizeCheck filter smallerSizeCheck filter @@ -268,7 +264,7 @@ let find<'a when 'a : equality> (xs : 'a []) predicate = let a = run (fun () -> xs |> Array.find predicate) consistency "find" s l a -[] +[] let ``find is consistent`` () = smallerSizeCheck find smallerSizeCheck find @@ -280,7 +276,7 @@ let findBack<'a when 'a : equality> (xs : 'a []) predicate = let a = run (fun () -> xs |> Array.findBack predicate) consistency "findBack" s l a -[] +[] let ``findBack is consistent`` () = smallerSizeCheck findBack smallerSizeCheck findBack @@ -292,7 +288,7 @@ let findIndex<'a when 'a : equality> (xs : 'a []) predicate = let a = run (fun () -> xs |> Array.findIndex predicate) consistency "findIndex" s l a -[] +[] let ``findIndex is consistent`` () = smallerSizeCheck findIndex smallerSizeCheck findIndex @@ -304,7 +300,7 @@ let findIndexBack<'a when 'a : equality> (xs : 'a []) predicate = let a = run (fun () -> xs |> Array.findIndexBack predicate) consistency "findIndexBack" s l a -[] +[] let ``findIndexBack is consistent`` () = smallerSizeCheck findIndexBack smallerSizeCheck findIndexBack @@ -316,7 +312,7 @@ let fold<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let a = run (fun () -> xs |> Array.fold f start) consistency "fold" s l a -[] +[] let ``fold is consistent`` () = smallerSizeCheck fold smallerSizeCheck fold @@ -331,7 +327,7 @@ let fold2<'a,'b,'c when 'c : equality> (xs': ('a*'b)[]) f (start:'c) = let a = run (fun () -> Array.fold2 f start xs xs2) consistency "fold2" s l a -[] +[] let ``fold2 is consistent`` () = smallerSizeCheck fold2 smallerSizeCheck fold2 @@ -346,7 +342,7 @@ let foldBack<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let a = run (fun () -> Array.foldBack f xs start) consistency "foldBack" s l a -[] +[] let ``foldBack is consistent`` () = smallerSizeCheck foldBack smallerSizeCheck foldBack @@ -361,7 +357,7 @@ let foldBack2<'a,'b,'c when 'c : equality> (xs': ('a*'b)[]) f (start:'c) = let a = run (fun () -> Array.foldBack2 f xs xs2 start) consistency "foldBack2" s l a -[] +[] let ``foldBack2 is consistent`` () = smallerSizeCheck foldBack2 smallerSizeCheck foldBack2 @@ -376,7 +372,7 @@ let forall<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.forall f consistency "forall" s l a -[] +[] let ``forall is consistent`` () = smallerSizeCheck forall smallerSizeCheck forall @@ -390,7 +386,7 @@ let forall2<'a when 'a : equality> (xs':('a*'a) []) f = let a = runAndCheckErrorType (fun () -> Array.forall2 f (Array.ofSeq xs) (Array.ofSeq xs2)) consistency "forall2" s l a -[] +[] let ``forall2 is consistent for collections with equal length`` () = smallerSizeCheck forall2 smallerSizeCheck forall2 @@ -402,7 +398,7 @@ let groupBy<'a when 'a : equality> (xs : 'a []) f = let a = run (fun () -> xs |> Array.groupBy f |> Array.map (fun (x,xs) -> x,xs |> Seq.toArray)) consistency "groupBy" s l a -[] +[] let ``groupBy is consistent`` () = smallerSizeCheck groupBy smallerSizeCheck groupBy @@ -414,7 +410,7 @@ let head<'a when 'a : equality> (xs : 'a []) = let a = runAndCheckIfAnyError (fun () -> xs |> Array.head) consistency "head" s l a -[] +[] let ``head is consistent`` () = smallerSizeCheck head smallerSizeCheck head @@ -426,7 +422,7 @@ let indexed<'a when 'a : equality> (xs : 'a []) = let a = xs |> Array.indexed consistency "indexed" s l a -[] +[] let ``indexed is consistent`` () = smallerSizeCheck indexed smallerSizeCheck indexed @@ -438,7 +434,7 @@ let init<'a when 'a : equality> count f = let a = runAndCheckErrorType (fun () -> Array.init count f) consistency "init" s l a -[] +[] let ``init is consistent`` () = smallerSizeCheck init smallerSizeCheck init @@ -450,7 +446,7 @@ let isEmpty<'a when 'a : equality> (xs : 'a []) = let a = xs |> Array.isEmpty consistency "isEmpty" s l a -[] +[] let ``isEmpty is consistent`` () = smallerSizeCheck isEmpty smallerSizeCheck isEmpty @@ -462,7 +458,7 @@ let item<'a when 'a : equality> (xs : 'a []) index = let a = runAndCheckIfAnyError (fun () -> xs |> Array.item index) consistency "item" s l a -[] +[] let ``item is consistent`` () = smallerSizeCheck item smallerSizeCheck item @@ -481,7 +477,7 @@ let iter<'a when 'a : equality> (xs : 'a []) f' = let xs = Seq.toList xs list |> Seq.toList = (xs @ xs @ xs) -[] +[] let ``iter looks at every element exactly once and in order - consistenly over all collections`` () = smallerSizeCheck iter smallerSizeCheck iter @@ -502,7 +498,7 @@ let iter2<'a when 'a : equality> (xs' : ('a*'a) []) f' = let xs = Seq.toList xs' list |> Seq.toList = (xs @ xs @ xs) -[] +[] let ``iter2 looks at every element exactly once and in order - consistenly over all collections when size is equal`` () = smallerSizeCheck iter2 smallerSizeCheck iter2 @@ -524,7 +520,7 @@ let iteri<'a when 'a : equality> (xs : 'a []) f' = list |> Seq.toList = (xs @ xs @ xs) && indices |> Seq.toList = ([0..xs.Length-1] @ [0..xs.Length-1] @ [0..xs.Length-1]) -[] +[] let ``iteri looks at every element exactly once and in order - consistenly over all collections`` () = smallerSizeCheck iteri smallerSizeCheck iteri @@ -548,7 +544,7 @@ let iteri2<'a when 'a : equality> (xs' : ('a*'a) []) f' = list |> Seq.toList = (xs @ xs @ xs) && indices |> Seq.toList = ([0..xs.Length-1] @ [0..xs.Length-1] @ [0..xs.Length-1]) -[] +[] let ``iteri2 looks at every element exactly once and in order - consistenly over all collections when size is equal`` () = smallerSizeCheck iteri2 smallerSizeCheck iteri2 @@ -560,7 +556,7 @@ let last<'a when 'a : equality> (xs : 'a []) = let a = runAndCheckIfAnyError (fun () -> xs |> Array.last) consistency "last" s l a -[] +[] let ``last is consistent`` () = smallerSizeCheck last smallerSizeCheck last @@ -572,7 +568,7 @@ let length<'a when 'a : equality> (xs : 'a []) = let a = xs |> Array.length consistency "length" s l a -[] +[] let ``length is consistent`` () = smallerSizeCheck length smallerSizeCheck length @@ -584,7 +580,7 @@ let map<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.map f consistency "map" s l a -[] +[] let ``map is consistent`` () = smallerSizeCheck map smallerSizeCheck map @@ -606,7 +602,7 @@ let map2<'a when 'a : equality> (xs' : ('a*'a) []) f' = Seq.toArray s = a && List.toArray l = a && list |> Seq.toList = (xs @ xs @ xs) -[] +[] let ``map2 looks at every element exactly once and in order - consistenly over all collections when size is equal`` () = smallerSizeCheck map2 smallerSizeCheck map2 @@ -629,7 +625,7 @@ let map3<'a when 'a : equality> (xs' : ('a*'a*'a) []) f' = Seq.toArray s = a && List.toArray l = a && list |> Seq.toList = (xs @ xs @ xs) -[] +[] let ``map3 looks at every element exactly once and in order - consistenly over all collections when size is equal`` () = smallerSizeCheck map3 smallerSizeCheck map3 @@ -642,7 +638,7 @@ let mapFold<'a when 'a : equality> (xs : 'a []) f start = Seq.toArray s = a && List.toArray l = a && sr = lr && sr = ar -[] +[] let ``mapFold is consistent`` () = smallerSizeCheck mapFold smallerSizeCheck mapFold @@ -655,7 +651,7 @@ let mapFoldBack<'a when 'a : equality> (xs : 'a []) f start = Seq.toArray s = a && List.toArray l = a && sr = lr && sr = ar -[] +[] let ``mapFold2 is consistent`` () = smallerSizeCheck mapFoldBack smallerSizeCheck mapFoldBack @@ -667,7 +663,7 @@ let mapi<'a when 'a : equality> (xs : 'a []) f = let a = xs |> Array.mapi f Seq.toArray s = a && List.toArray l = a -[] +[] let ``mapi is consistent`` () = smallerSizeCheck mapi smallerSizeCheck mapi @@ -692,7 +688,7 @@ let mapi2<'a when 'a : equality> (xs' : ('a*'a) []) f' = list |> Seq.toList = (xs @ xs @ xs) && (Seq.toList indices = [0..xs.Length-1] @ [0..xs.Length-1] @ [0..xs.Length-1]) -[] +[] let ``mapi2 looks at every element exactly once and in order - consistenly over all collections when size is equal`` () = smallerSizeCheck mapi2 smallerSizeCheck mapi2 @@ -704,7 +700,7 @@ let max<'a when 'a : comparison> (xs : 'a []) = let a = runAndCheckIfAnyError (fun () -> xs |> Array.max) consistency "max" s l a -[] +[] let ``max is consistent`` () = smallerSizeCheck max smallerSizeCheck max @@ -716,7 +712,7 @@ let maxBy<'a when 'a : comparison> (xs : 'a []) f = let a = runAndCheckIfAnyError (fun () -> xs |> Array.maxBy f) consistency "maxBy" s l a -[] +[] let ``maxBy is consistent`` () = smallerSizeCheck maxBy smallerSizeCheck maxBy @@ -728,7 +724,7 @@ let min<'a when 'a : comparison> (xs : 'a []) = let a = runAndCheckIfAnyError (fun () -> xs |> Array.min) consistency "min" s l a -[] +[] let ``min is consistent`` () = smallerSizeCheck min smallerSizeCheck min @@ -740,7 +736,7 @@ let minBy<'a when 'a : comparison> (xs : 'a []) f = let a = runAndCheckIfAnyError (fun () -> xs |> Array.minBy f) consistency "minBy" s l a -[] +[] let ``minBy is consistent`` () = smallerSizeCheck minBy smallerSizeCheck minBy @@ -752,7 +748,7 @@ let pairwise<'a when 'a : comparison> (xs : 'a []) = let a = run (fun () -> xs |> Array.pairwise) consistency "pairwise" s l a -[] +[] let ``pairwise is consistent`` () = smallerSizeCheck pairwise smallerSizeCheck pairwise @@ -765,7 +761,7 @@ let partition<'a when 'a : comparison> (xs : 'a []) f = List.toArray l1 = a1 && List.toArray l2 = a2 -[] +[] let ``partition is consistent`` () = smallerSizeCheck partition smallerSizeCheck partition @@ -789,7 +785,7 @@ let permute<'a when 'a : comparison> (xs' : list) = let a = run (fun () -> xs |> Array.ofSeq |> Array.permute permutation) consistency "partition" s l a -[] +[] let ``permute is consistent`` () = smallerSizeCheck permute smallerSizeCheck permute @@ -801,7 +797,7 @@ let pick<'a when 'a : comparison> (xs : 'a []) f = let a = run (fun () -> xs |> Array.pick f) consistency "pick" s l a -[] +[] let ``pick is consistent`` () = smallerSizeCheck pick smallerSizeCheck pick @@ -813,7 +809,7 @@ let reduce<'a when 'a : equality> (xs : 'a []) f = let a = runAndCheckErrorType (fun () -> xs |> Array.reduce f) consistency "reduce" s l a -[] +[] let ``reduce is consistent`` () = smallerSizeCheck reduce smallerSizeCheck reduce @@ -825,7 +821,7 @@ let reduceBack<'a when 'a : equality> (xs : 'a []) f = let a = runAndCheckErrorType (fun () -> xs |> Array.reduceBack f) consistency "reduceBack" s l a -[] +[] let ``reduceBack is consistent`` () = smallerSizeCheck reduceBack smallerSizeCheck reduceBack @@ -837,7 +833,7 @@ let replicate<'a when 'a : equality> x count = let a = runAndCheckIfAnyError (fun () -> Array.replicate count x) consistency "replicate" s l a -[] +[] let ``replicate is consistent`` () = smallerSizeCheck replicate smallerSizeCheck replicate @@ -849,7 +845,7 @@ let rev<'a when 'a : equality> (xs : 'a []) = let a = Array.rev xs consistency "rev" s l a -[] +[] let ``rev is consistent`` () = smallerSizeCheck rev smallerSizeCheck rev @@ -861,7 +857,7 @@ let scan<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let a = run (fun () -> xs |> Array.scan f start) consistency "scan" s l a -[] +[] let ``scan is consistent`` () = smallerSizeCheck scan smallerSizeCheck scan @@ -874,7 +870,7 @@ let scanBack<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let a = run (fun () -> Array.scanBack f xs start) consistency "scanback" s l a -[] +[] let ``scanBack is consistent`` () = smallerSizeCheck scanBack smallerSizeCheck scanBack @@ -887,7 +883,7 @@ let singleton<'a when 'a : equality> (x : 'a) = let a = Array.singleton x consistency "singleton" s l a -[] +[] let ``singleton is consistent`` () = smallerSizeCheck singleton smallerSizeCheck singleton @@ -899,7 +895,7 @@ let skip<'a when 'a : equality> (xs : 'a []) count = let a = runAndCheckIfAnyError (fun () -> Array.skip count xs) consistency "skip" s l a -[] +[] let ``skip is consistent`` () = smallerSizeCheck skip smallerSizeCheck skip @@ -911,7 +907,7 @@ let skipWhile<'a when 'a : equality> (xs : 'a []) f = let a = runAndCheckIfAnyError (fun () -> Array.skipWhile f xs) consistency "skipWhile" s l a -[] +[] let ``skipWhile is consistent`` () = smallerSizeCheck skipWhile smallerSizeCheck skipWhile @@ -923,7 +919,7 @@ let sort<'a when 'a : comparison> (xs : 'a []) = let a = xs |> Array.sort consistency "sort" s l a -[] +[] let ``sort is consistent`` () = smallerSizeCheck sort smallerSizeCheck sort @@ -937,7 +933,7 @@ let sortBy<'a,'b when 'a : comparison and 'b : comparison> (xs : 'a []) (f:'a -> isSorted (Seq.map f s) && isSorted (Seq.map f l) && isSorted (Seq.map f a) && haveSameElements s xs && haveSameElements l xs && haveSameElements a xs -[] +[] let ``sortBy actually sorts (but is inconsistent in regards of stability)`` () = smallerSizeCheck sortBy smallerSizeCheck sortBy @@ -960,7 +956,7 @@ let sortWith<'a,'b when 'a : comparison and 'b : comparison> (xs : 'a []) = isSorted s && isSorted l && isSorted a && haveSameElements s xs && haveSameElements l xs && haveSameElements a xs -[] +[] let ``sortWith actually sorts (but is inconsistent in regards of stability)`` () = smallerSizeCheck sortWith smallerSizeCheck sortWith @@ -974,7 +970,7 @@ let sortDescending<'a when 'a : comparison> (xs : 'a []) = let a = xs |> Array.sortDescending consistency "sortDescending" s l a -[] +[] let ``sortDescending is consistent`` () = smallerSizeCheck sortDescending smallerSizeCheck sortDescending @@ -988,7 +984,7 @@ let sortByDescending<'a,'b when 'a : comparison and 'b : comparison> (xs : 'a [] isSorted (Seq.map f s |> Seq.rev) && isSorted (Seq.map f l |> Seq.rev) && isSorted (Seq.map f a |> Seq.rev) && haveSameElements s xs && haveSameElements l xs && haveSameElements a xs -[] +[] let ``sortByDescending actually sorts (but is inconsistent in regards of stability)`` () = smallerSizeCheck sortByDescending smallerSizeCheck sortByDescending @@ -1002,7 +998,7 @@ let sum (xs : int []) = let a = run (fun () -> xs |> Array.sum) consistency "sum" s l a -[] +[] let ``sum is consistent`` () = smallerSizeCheck sum @@ -1012,7 +1008,7 @@ let sumBy<'a> (xs : 'a []) (f:'a -> int) = let a = run (fun () -> xs |> Array.sumBy f) consistency "sumBy" s l a -[] +[] let ``sumBy is consistent`` () = smallerSizeCheck sumBy smallerSizeCheck sumBy @@ -1032,7 +1028,7 @@ let splitAt<'a when 'a : equality> (xs : 'a []) index = let a = run (fun () -> xs |> Array.splitAt index) (l = a) |@ "splitAt" -[] +[] let ``splitAt is consistent`` () = smallerSizeCheck splitAt smallerSizeCheck splitAt @@ -1050,7 +1046,7 @@ let splitInto<'a when 'a : equality> (xs : 'a []) count = let a = run (fun () -> xs |> Array.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) consistency "splitInto" s l a -[] +[] let ``splitInto is consistent`` () = smallerSizeCheck splitInto smallerSizeCheck splitInto @@ -1062,7 +1058,7 @@ let tail<'a when 'a : equality> (xs : 'a []) = let a = runAndCheckIfAnyError (fun () -> xs |> Array.tail) consistency "tail" s l a -[] +[] let ``tail is consistent`` () = smallerSizeCheck tail smallerSizeCheck tail @@ -1074,7 +1070,7 @@ let take<'a when 'a : equality> (xs : 'a []) count = let a = runAndCheckIfAnyError (fun () -> Array.take count xs) consistency "take" s l a -[] +[] let ``take is consistent`` () = smallerSizeCheck take smallerSizeCheck take @@ -1086,7 +1082,7 @@ let takeWhile<'a when 'a : equality> (xs : 'a []) f = let a = runAndCheckIfAnyError (fun () -> Array.takeWhile f xs) consistency "takeWhile" s l a -[] +[] let ``takeWhile is consistent`` () = smallerSizeCheck takeWhile smallerSizeCheck takeWhile @@ -1098,7 +1094,7 @@ let truncate<'a when 'a : equality> (xs : 'a []) count = let a = runAndCheckIfAnyError (fun () -> Array.truncate count xs) consistency "truncate" s l a -[] +[] let ``truncate is consistent`` () = smallerSizeCheck truncate smallerSizeCheck truncate @@ -1110,7 +1106,7 @@ let tryFind<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.tryFind predicate consistency "tryFind" s l a -[] +[] let ``tryFind is consistent`` () = smallerSizeCheck tryFind smallerSizeCheck tryFind @@ -1122,7 +1118,7 @@ let tryFindBack<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.tryFindBack predicate consistency "tryFindBack" s l a -[] +[] let ``tryFindBack is consistent`` () = smallerSizeCheck tryFindBack smallerSizeCheck tryFindBack @@ -1134,7 +1130,7 @@ let tryFindIndex<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.tryFindIndex predicate consistency "tryFindIndex" s l a -[] +[] let ``tryFindIndex is consistent`` () = smallerSizeCheck tryFindIndex smallerSizeCheck tryFindIndex @@ -1146,7 +1142,7 @@ let tryFindIndexBack<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.tryFindIndexBack predicate consistency "tryFindIndexBack" s l a -[] +[] let ``tryFindIndexBack is consistent`` () = smallerSizeCheck tryFindIndexBack smallerSizeCheck tryFindIndexBack @@ -1158,7 +1154,7 @@ let tryHead<'a when 'a : equality> (xs : 'a []) = let a = xs |> Array.tryHead consistency "tryHead" s l a -[] +[] let ``tryHead is consistent`` () = smallerSizeCheck tryHead smallerSizeCheck tryHead @@ -1170,7 +1166,7 @@ let tryItem<'a when 'a : equality> (xs : 'a []) index = let a = xs |> Array.tryItem index consistency "tryItem" s l a -[] +[] let ``tryItem is consistent`` () = smallerSizeCheck tryItem smallerSizeCheck tryItem @@ -1182,7 +1178,7 @@ let tryLast<'a when 'a : equality> (xs : 'a []) = let a = xs |> Array.tryLast consistency "tryLast" s l a -[] +[] let ``tryLast is consistent`` () = smallerSizeCheck tryLast smallerSizeCheck tryLast @@ -1194,7 +1190,7 @@ let tryPick<'a when 'a : comparison> (xs : 'a []) f = let a = xs |> Array.tryPick f consistency "tryPick" s l a -[] +[] let ``tryPick is consistent`` () = smallerSizeCheck tryPick smallerSizeCheck tryPick @@ -1213,7 +1209,7 @@ let unfold<'a,'b when 'b : equality> f (start:'a) = consistency "unfold" s l a -[] +[] let ``unfold is consistent`` () = smallerSizeCheck unfold @@ -1232,7 +1228,7 @@ let unzip<'a when 'a : equality> (xs:('a*'a) []) = let a = runAndCheckErrorType (fun () -> Array.unzip xs) l = a -[] +[] let ``unzip is consistent`` () = smallerSizeCheck unzip smallerSizeCheck unzip @@ -1244,7 +1240,7 @@ let unzip3<'a when 'a : equality> (xs:('a*'a*'a) []) = let a = runAndCheckErrorType (fun () -> Array.unzip3 xs) l = a -[] +[] let ``unzip3 is consistent`` () = smallerSizeCheck unzip3 smallerSizeCheck unzip3 @@ -1256,7 +1252,7 @@ let where<'a when 'a : equality> (xs : 'a []) predicate = let a = xs |> Array.where predicate consistency "where" s l a -[] +[] let ``where is consistent`` () = smallerSizeCheck where smallerSizeCheck where @@ -1274,7 +1270,7 @@ let windowed<'a when 'a : equality> (xs : 'a []) windowSize = let a = run (fun () -> xs |> Array.windowed windowSize) consistency "windowed" s l a -[] +[] let ``windowed is consistent`` () = smallerSizeCheck windowed smallerSizeCheck windowed @@ -1288,7 +1284,7 @@ let zip<'a when 'a : equality> (xs':('a*'a) []) = let a = runAndCheckErrorType (fun () -> Array.zip (Array.ofSeq xs) (Array.ofSeq xs2)) consistency "zip" s l a -[] +[] let ``zip is consistent for collections with equal length`` () = smallerSizeCheck zip smallerSizeCheck zip @@ -1303,7 +1299,7 @@ let zip3<'a when 'a : equality> (xs':('a*'a*'a) []) = let a = runAndCheckErrorType (fun () -> Array.zip3 (Array.ofSeq xs) (Array.ofSeq xs2) (Array.ofSeq xs3)) consistency "zip3" s l a -[] +[] let ``zip3 is consistent for collections with equal length`` () = smallerSizeCheck zip3 smallerSizeCheck zip3 diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ComparisonIdentityModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ComparisonIdentityModule.fs index f16f20a491b..582996516ad 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ComparisonIdentityModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ComparisonIdentityModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.ComparisonIdentity module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -18,9 +18,8 @@ Make sure each method works on: * (2 - 7 elements) *) -[] type ComparisonIdentityModule() = - [] + [] member this.FromFunction() = // integer array let intArr = [|1;5;8;2;6;3;7;4|] @@ -39,7 +38,7 @@ type ComparisonIdentityModule() = () - [] + [] member this.Structural() = // integer array let intArr = [|1;5;8;2;6;3;7;4|] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/HashIdentityModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/HashIdentityModule.fs index b6bbe392c53..c00a9a3af8b 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/HashIdentityModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/HashIdentityModule.fs @@ -3,63 +3,62 @@ // Various tests for the: // Microsoft.FSharp.Collections.HashIdentity module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open System.Collections.Generic -[] type HashIdentityModule() = - - [] + + [] member this.FromFunction() = - + // value type let valueDict = new Dictionary(HashIdentity.Structural) Assert.AreEqual(valueDict.Count,0) valueDict.Add(3,"C") Assert.AreEqual(1, valueDict.Count) - Assert.IsTrue(valueDict.ContainsValue("C")) + Assert.True(valueDict.ContainsValue("C")) // reference type let refDict = new Dictionary(HashIdentity.Structural) Assert.AreEqual(refDict.Count,0) refDict.Add("...",3) Assert.AreEqual(1, refDict.Count) - Assert.IsTrue(refDict.ContainsValue(3)) + Assert.True(refDict.ContainsValue(3)) - // empty type + // empty type let eptDict = new Dictionary(HashIdentity.Structural) Assert.AreEqual(0, eptDict.Count) - Assert.IsFalse(eptDict.ContainsKey(3)) - + Assert.False(eptDict.ContainsKey(3)) + () - - [] + + [] member this.Reference() = - - // reference type + + // reference type let refDict = new Dictionary(HashIdentity.Reference) Assert.AreEqual(refDict.Count,0) let obj1 = obj() let obj2 = obj() refDict.Add(obj1,3) Assert.AreEqual(1,refDict.Count) - Assert.IsTrue(refDict.ContainsKey(obj1)) - Assert.IsFalse(refDict.ContainsKey(obj2)) - Assert.IsTrue(refDict.ContainsValue(3)) + Assert.True(refDict.ContainsKey(obj1)) + Assert.False(refDict.ContainsKey(obj2)) + Assert.True(refDict.ContainsValue(3)) // empty table let eptDict = new Dictionary(HashIdentity.Reference) Assert.AreEqual(0,eptDict.Count) - Assert.IsFalse(eptDict.ContainsKey("3")) - + Assert.False(eptDict.ContainsKey("3")) + () - [] + [] member this.FromFunctions() = // value type @@ -67,18 +66,18 @@ type HashIdentityModule() = Assert.AreEqual(0,valueDict.Count) valueDict.Add(3,"C") Assert.AreEqual(1,valueDict.Count) - Assert.IsTrue(valueDict.ContainsValue("C")) + Assert.True(valueDict.ContainsValue("C")) // reference type let refDict = new Dictionary(HashIdentity.FromFunctions (fun x -> 1) (fun x y -> x > y)) Assert.AreEqual(0,refDict.Count) refDict.Add("...",3) Assert.AreEqual(1,refDict.Count) - Assert.IsTrue(refDict.ContainsValue(3)) + Assert.True(refDict.ContainsValue(3)) // empty type let eptDict = new Dictionary(HashIdentity.FromFunctions (fun x -> 1) (fun x y -> x > y)) Assert.AreEqual(0,eptDict.Count) - Assert.IsFalse(eptDict.ContainsKey(3)) + Assert.False(eptDict.ContainsKey(3)) () \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs index 8c8d1ad420e..eed54c3ad77 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.List module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -17,9 +17,8 @@ Make sure each method works on: * Empty List (0 elements) *) -[][][] type ListModule() = - [] + [] member this.Empty() = let emptyList = List.empty let resultEpt = List.length emptyList @@ -30,7 +29,7 @@ type ListModule() = () - [] + [] member this.AllPairs() = // integer List let resultInt = List.allPairs [1..3] [2..2..6] @@ -52,7 +51,7 @@ type ListModule() = () - [] + [] member this.Append() = // integer List let intList = List.append [ 1; 2 ] [ 3; 4 ] @@ -67,7 +66,7 @@ type ListModule() = Assert.AreEqual([],emptyList) () - [] + [] member this.Average() = // empty float32 List let emptyFloatList = List.empty @@ -99,7 +98,7 @@ type ListModule() = () - [] + [] member this.AverageBy() = // empty double List let emptyDouList = List.empty @@ -130,19 +129,19 @@ type ListModule() = () - [] + [] member this.ChunkBySize() = // int list - Assert.IsTrue([ [1..4]; [5..8] ] = List.chunkBySize 4 [1..8]) - Assert.IsTrue([ [1..4]; [5..8]; [9..10] ] = List.chunkBySize 4 [1..10]) - Assert.IsTrue([ [1]; [2]; [3]; [4] ] = List.chunkBySize 1 [1..4]) + Assert.True([ [1..4]; [5..8] ] = List.chunkBySize 4 [1..8]) + Assert.True([ [1..4]; [5..8]; [9..10] ] = List.chunkBySize 4 [1..10]) + Assert.True([ [1]; [2]; [3]; [4] ] = List.chunkBySize 1 [1..4]) // string list - Assert.IsTrue([ ["a"; "b"]; ["c";"d"]; ["e"] ] = List.chunkBySize 2 ["a";"b";"c";"d";"e"]) + Assert.True([ ["a"; "b"]; ["c";"d"]; ["e"] ] = List.chunkBySize 2 ["a";"b";"c";"d";"e"]) // empty list - Assert.IsTrue([] = List.chunkBySize 3 []) + Assert.True([] = List.chunkBySize 3 []) // invalidArg CheckThrowsArgumentException (fun () -> List.chunkBySize 0 [1..10] |> ignore) @@ -150,22 +149,22 @@ type ListModule() = () - [] + [] member this.SplitInto() = // int list - Assert.IsTrue([ [1..4]; [5..7]; [8..10] ] = List.splitInto 3 [1..10]) - Assert.IsTrue([ [1..4]; [5..8]; [9..11] ] = List.splitInto 3 [1..11]) - Assert.IsTrue([ [1..4]; [5..8]; [9..12] ] = List.splitInto 3 [1..12]) + Assert.True([ [1..4]; [5..7]; [8..10] ] = List.splitInto 3 [1..10]) + Assert.True([ [1..4]; [5..8]; [9..11] ] = List.splitInto 3 [1..11]) + Assert.True([ [1..4]; [5..8]; [9..12] ] = List.splitInto 3 [1..12]) - Assert.IsTrue([ [1..2]; [3]; [4]; [5] ] = List.splitInto 4 [1..5]) - Assert.IsTrue([ [1]; [2]; [3]; [4] ] = List.splitInto 20 [1..4]) + Assert.True([ [1..2]; [3]; [4]; [5] ] = List.splitInto 4 [1..5]) + Assert.True([ [1]; [2]; [3]; [4] ] = List.splitInto 20 [1..4]) // string list - Assert.IsTrue([ ["a"; "b"]; ["c";"d"]; ["e"] ] = List.splitInto 3 ["a";"b";"c";"d";"e"]) + Assert.True([ ["a"; "b"]; ["c";"d"]; ["e"] ] = List.splitInto 3 ["a";"b";"c";"d";"e"]) // empty list - Assert.IsTrue([] = List.splitInto 3 []) + Assert.True([] = List.splitInto 3 []) // invalidArg CheckThrowsArgumentException (fun () -> List.splitInto 0 [1..10] |> ignore) @@ -173,7 +172,7 @@ type ListModule() = () - [] + [] member this.distinct() = // distinct should work on empty list Assert.AreEqual([], List.distinct []) @@ -188,9 +187,9 @@ type ListModule() = Assert.AreEqual([null], List.distinct [null]) let list = new System.Collections.Generic.List() - Assert.IsTrue([null, list] = List.distinct [null, list]) + Assert.True([null, list] = List.distinct [null, list]) - [] + [] member this.distinctBy() = // distinctBy should work on empty list Assert.AreEqual([], List.distinctBy (fun _ -> failwith "should not be executed") []) @@ -207,9 +206,9 @@ type ListModule() = Assert.AreEqual([null], List.distinctBy id [null]) let list = new System.Collections.Generic.List() - Assert.IsTrue([null, list] = List.distinctBy id [null, list]) + Assert.True([null, list] = List.distinctBy id [null, list]) - [] + [] member this.Take() = Assert.AreEqual(([] : int list) ,List.take 0 ([] : int list)) Assert.AreEqual(([] : string list),List.take 0 ["str1";"str2";"str3";"str4"]) @@ -220,7 +219,7 @@ type ListModule() = CheckThrowsArgumentException (fun () -> List.take -1 [0;1] |> ignore) CheckThrowsInvalidOperationExn (fun () -> List.take 5 ["str1";"str2";"str3";"str4"] |> ignore) - [] + [] member this.Choose() = // int List let intSrc:int list = [ 1..100 ] @@ -252,7 +251,7 @@ type ListModule() = () - [] + [] member this.compareWith() = // compareWith should work on empty lists Assert.AreEqual(0,List.compareWith (fun _ -> failwith "should not be executed") [] []) @@ -273,7 +272,7 @@ type ListModule() = Assert.AreEqual(1,List.compareWith (fun x y -> 1) ["1";"2"] ["1";"3"]) Assert.AreEqual(-1,List.compareWith (fun x y -> -1) ["1";"2"] ["1";"3"]) - [] + [] member this.takeWhile() = Assert.AreEqual(([] : int list),List.takeWhile (fun x -> failwith "should not be used") ([] : int list)) Assert.AreEqual([1;2;4;5],List.takeWhile (fun x -> x < 6) [1;2;4;5;6;7]) @@ -284,7 +283,7 @@ type ListModule() = Assert.AreEqual(["a"],List.takeWhile (fun _ -> true) ["a"]) Assert.AreEqual(["a"],List.takeWhile (fun x -> x <> "ab") ["a"; "ab"; "abc"; "abcd"; "abcde"]) - [] + [] member this.Concat() = // integer List let seqInt = @@ -310,7 +309,7 @@ type ListModule() = Assert.AreEqual(1, result2.[1]) () - [] + [] member this.splitAt() = Assert.AreEqual((([] : int list),([] : int list)), List.splitAt 0 ([] : int list)) @@ -335,7 +334,7 @@ type ListModule() = CheckThrowsInvalidOperationExn (fun () -> List.splitAt 5 ["str1";"str2";"str3";"str4"] |> ignore) () - [] + [] member this.countBy() = // countBy should work on empty list Assert.AreEqual(0,List.countBy (fun _ -> failwith "should not be executed") [] |> List.length) @@ -344,7 +343,7 @@ type ListModule() = Assert.AreEqual([5,1; 2,2; 3,2],List.countBy id [5;2;2;3;3]) Assert.AreEqual([3,3; 2,2; 1,3],List.countBy (fun x -> if x < 3 then x else 3) [5;2;1;2;3;3;1;1]) - [] + [] member this.Except() = // integer list let intList1 = [ yield! {1..100} @@ -373,51 +372,51 @@ type ListModule() = CheckThrowsArgumentNullException(fun () -> List.except nullSeq emptyIntList |> ignore) () - [] + [] member this.Exists() = // integer List let intArr = [ 2;4;6;8 ] let funcInt x = if (x%2 = 0) then true else false let resultInt = List.exists funcInt intArr - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string List let strArr = ["."; ".."; "..."; "...."] let funcStr (x:string) = if (x.Length >15) then true else false let resultStr = List.exists funcStr strArr - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let emptyArr:int list = [ ] let resultEpt = List.exists funcInt emptyArr - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) () - [] + [] member this.Exists2() = // integer List let intFir = [ 2;4;6;8 ] let intSec = [ 1;2;3;4 ] let funcInt x y = if (x%y = 0) then true else false let resultInt = List.exists2 funcInt intFir intSec - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string List let strFir = ["Lists"; "are"; "commonly" ] let strSec = ["good"; "good"; "good" ] let funcStr (x:string) (y:string) = if (x = y) then true else false let resultStr = List.exists2 funcStr strFir strSec - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let eptFir:int list = [ ] let eptSec:int list = [ ] let resultEpt = List.exists2 funcInt eptFir eptSec - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) () - [] + [] member this.Filter() = // integer List let intArr = [ 1..20 ] @@ -438,7 +437,7 @@ type ListModule() = () - [] + [] member this.Where() = // integer List let intArr = [ 1..20 ] @@ -459,7 +458,7 @@ type ListModule() = () - [] + [] member this.``where should work like filter``() = Assert.AreEqual(([] : int list), List.where (fun x -> x % 2 = 0) []) Assert.AreEqual([0;2;4;6;8], List.where (fun x -> x % 2 = 0) [0..9]) @@ -467,7 +466,7 @@ type ListModule() = () - [] + [] member this.Find() = // integer List let intArr = [ 1..20 ] @@ -490,7 +489,7 @@ type ListModule() = () - [] + [] member this.replicate() = // replicate should create multiple copies of the given value Assert.AreEqual(0,List.replicate 0 null |> List.length) @@ -500,7 +499,7 @@ type ListModule() = CheckThrowsArgumentException (fun () -> List.replicate -1 null |> ignore) - [] + [] member this.FindBack() = // integer List let funcInt x = if (x%5 = 0) then true else false @@ -523,7 +522,7 @@ type ListModule() = () - [] + [] member this.FindIndex() = // integer List let intArr = [ 1..20 ] @@ -546,7 +545,7 @@ type ListModule() = () - [] + [] member this.FindIndexBack() = // integer List let funcInt x = if (x%5 = 0) then true else false @@ -568,7 +567,7 @@ type ListModule() = () - [] + [] member this.TryPick() = // integer List let intArr = [ 1..10 ] @@ -595,7 +594,7 @@ type ListModule() = () - [] + [] member this.Fold() = // integer List let intArr = [ 1..10 ] @@ -616,7 +615,7 @@ type ListModule() = () - [] + [] member this.Fold2() = // integer List let funcInt x y z = x + y + z @@ -635,7 +634,7 @@ type ListModule() = () - [] + [] member this.FoldBack() = // integer List let intArr = [ 1..10 ] @@ -673,7 +672,7 @@ type ListModule() = () - [] + [] member this.FoldBack2() = // integer List let funcInt x y z = x + y + z @@ -713,39 +712,39 @@ type ListModule() = () - [] + [] member this.ForAll() = // integer List let resultInt = List.forall (fun x -> x > 2) [ 3..2..10 ] - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string List let resultStr = List.forall (fun (x:string) -> x.Contains("a")) ["a";"b";"c";"d"] - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let resultEpt = List.forall (fun (x:string) -> x.Contains("a")) [] - Assert.IsTrue(resultEpt) + Assert.True(resultEpt) () - [] + [] member this.ForAll2() = // integer List let resultInt = List.forall2 (fun x y -> x < y) [ 1..10 ] [2..2..20] - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string List let resultStr = List.forall2 (fun (x:string) (y:string) -> x.Length > y.Length) ["a";"b";"c";"d"] ["A";"B";"C";"D"] - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let resultEpt = List.forall2 (fun x y -> x > y) [] [] - Assert.IsTrue(resultEpt) + Assert.True(resultEpt) () - [] + [] member this.GroupBy() = let funcInt x = x%5 @@ -781,7 +780,7 @@ type ListModule() = () - [] + [] member this.Hd() = // integer List let resultInt = List.head [2..2..20] @@ -794,35 +793,35 @@ type ListModule() = CheckThrowsArgumentException(fun () -> List.head [] |> ignore) () - [] + [] member this.``exactlyOne should return the element from singleton lists``() = Assert.AreEqual(1, List.exactlyOne [1]) Assert.AreEqual("2", List.exactlyOne ["2"]) () - [] + [] member this.``exactlyOne should fail on empty list``() = CheckThrowsArgumentException(fun () -> List.exactlyOne [] |> ignore) - [] + [] member this.``exactlyOne should fail on lists with more than one element``() = CheckThrowsArgumentException(fun () -> List.exactlyOne ["1"; "2"] |> ignore) - [] + [] member this.``tryExactlyOne should return the element from singleton lists``() = Assert.AreEqual(Some 1, List.tryExactlyOne [1]) Assert.AreEqual(Some "2", List.tryExactlyOne ["2"]) () - [] + [] member this.``tryExactlyOne should return None for empty list``() = Assert.AreEqual(None, List.tryExactlyOne []) - [] + [] member this.``tryExactlyOne should return None for lists with more than one element``() = Assert.AreEqual(None, List.tryExactlyOne ["1"; "2"]) - [] + [] member this.TryHead() = // integer List let resultInt = List.tryHead [2..2..20] @@ -835,7 +834,7 @@ type ListModule() = let resultNone = List.tryHead [] Assert.AreEqual(None, resultNone) - [] + [] member this.TryLast() = // integer List let intResult = List.tryLast [1..9] @@ -847,10 +846,10 @@ type ListModule() = // Empty List let emptyResult = List.tryLast List.empty - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) () - [] + [] member this.last() = // last should fail on empty list CheckThrowsArgumentException(fun () -> List.last [] |> ignore) @@ -860,7 +859,7 @@ type ListModule() = Assert.AreEqual("2", List.last ["1"; "3"; "2"]) Assert.AreEqual(["4"], List.last [["1"; "3"]; []; ["4"]]) - [] + [] member this.Init() = // integer List let resultInt = List.init 3 (fun x -> x + 3) @@ -883,25 +882,25 @@ type ListModule() = () - [] + [] member this.IsEmpty() = // integer List let intArr = [ 3;4;7;8;10 ] let resultInt = List.isEmpty intArr - Assert.IsFalse(resultInt) + Assert.False(resultInt) // string List let strArr = ["a";"b";"c";"d"] let resultStr = List.isEmpty strArr - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let emptyArr:int list = [ ] let resultEpt = List.isEmpty emptyArr - Assert.IsTrue(resultEpt) + Assert.True(resultEpt) () - [] + [] member this.Iter() = // integer List let intArr = [ 1..10 ] @@ -929,7 +928,7 @@ type ListModule() = () - [] + [] member this.Iter2() = // integer List let resultInt = ref 0 @@ -955,7 +954,7 @@ type ListModule() = () - [] + [] member this.Iteri() = // integer List let intArr = [ 1..10 ] @@ -983,7 +982,7 @@ type ListModule() = () - [] + [] member this.Iteri2() = // integer List let resultInt = ref 0 @@ -1009,24 +1008,24 @@ type ListModule() = () - [] + [] member this.Contains() = // integer List let intList = [ 2;4;6;8 ] let resultInt = List.contains 4 intList - Assert.IsTrue(resultInt) + Assert.True(resultInt) // string List let strList = ["."; ".."; "..."; "...."] let resultStr = List.contains "....." strList - Assert.IsFalse(resultStr) + Assert.False(resultStr) // empty List let emptyList:int list = [ ] let resultEpt = List.contains 4 emptyList - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) - [] + [] member this.Singleton() = Assert.AreEqual([null],List.singleton null) Assert.AreEqual(["1"],List.singleton "1") @@ -1034,46 +1033,45 @@ type ListModule() = Assert.AreEqual([[||]],List.singleton [||]) () - [] + [] member this.``pairwise should return pairs of the input list``() = Assert.AreEqual(([] : (int*int) list), List.pairwise [1]) Assert.AreEqual([1,2], List.pairwise [1;2]) Assert.AreEqual([1,2; 2,3], List.pairwise [1;2;3]) Assert.AreEqual(["H","E"; "E","L"; "L","L"; "L","O"], List.pairwise ["H";"E";"L";"L";"O"]) - [] + [] member this.``Slicing with first index reverse behaves as expected``() = let list = [ 1;2;3;4;5 ] - Assert.That(list.[^3..], Is.EquivalentTo(list.[1..])) + Assert.AreEqual(list.[^3..], list.[1..]) - [] + [] member this.``Slicing with second index reverse behaves as expected``() = let list = [ 1;2;3;4;5 ] - Assert.That(list.[..^1], Is.EquivalentTo(list.[..3])) + Assert.AreEqual(list.[..^1], list.[..3]) - - [] + [] member this.``Slicing with both index reverse behaves as expected``() = let list = [ 1;2;3;4;5 ] - Assert.That(list.[^3..^1], Is.EquivalentTo(list.[1..3])) + Assert.AreEqual(list.[^3..^1], list.[1..3]) - [] + [] member this.``Slicing with first index reverse and second index non reverse behaves as expected``()= let list = [1;2;3;4;5] - Assert.That(list.[^3..4], Is.EquivalentTo(list.[1..4])) + Assert.AreEqual(list.[^3..4], list.[1..4]) - [] + [] member this.``Slicing with first index non reverse and second index reverse behaves as expected``()= let list = [1;2;3;4;5] - Assert.That(list.[3..^0], Is.EquivalentTo(list.[3..4])) + Assert.AreEqual(list.[3..^0], list.[3..4]) - [] + [] member this.``Get item with reverse index behaves as expected``() = let list = [1;2;3;4;5] - Assert.That(list.[^1], Is.EqualTo(4)) \ No newline at end of file + Assert.AreEqual(list.[^1], 4) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs index 283cdbe5888..328574bdac0 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.List module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -25,9 +25,8 @@ type ListWindowedTestInput<'t> = Exception : Type option } -[][][] type ListModule02() = - [] + [] member this.Length() = // integer List let resultInt = List.length [1..8] @@ -43,7 +42,7 @@ type ListModule02() = () - [] + [] member this.Map() = // integer List let funcInt x = @@ -64,7 +63,7 @@ type ListModule02() = () - [] + [] member this.Map2() = // integer List let funcInt x y = x+y @@ -83,7 +82,7 @@ type ListModule02() = () - [] + [] member this.Map3 () = // integer List @@ -108,7 +107,7 @@ type ListModule02() = let resultEpt = List.map3 funcInt List.empty List.empty List.empty Assert.AreEqual(List.empty, resultEpt) - [] + [] member this.Collect() = // integer List let funcInt x = match x with @@ -132,7 +131,7 @@ type ListModule02() = () - [] + [] member this.Collect2() = // The collect implementation uses mutation to create the result list; this test // helps verify that lists created by the user are never mutated @@ -148,7 +147,7 @@ type ListModule02() = Assert.AreEqual( [1; 2; 3], lists.[2] ) () - [] + [] member this.Mapi() = // integer List let funcInt x y = x+y @@ -167,7 +166,7 @@ type ListModule02() = () - [] + [] member this.Mapi2() = // integer List let funcInt x y z = x + y + z @@ -192,7 +191,7 @@ type ListModule02() = () - [] + [] member this.Indexed() = // integer List Assert.AreEqual([(0,10);(1,12);(2,14);(3,16);(4,18);(5,20)], List.indexed [10..2..20]) @@ -209,7 +208,7 @@ type ListModule02() = () - [] + [] member this.MapFold() = // integer List let funcInt acc x = if x % 2 = 0 then 10*x, acc + 1 else x, acc @@ -236,7 +235,7 @@ type ListModule02() = () - [] + [] member this.MapFoldBack() = // integer List let funcInt x acc = if acc < 105 then 10*x, acc + 2 else x, acc @@ -262,7 +261,7 @@ type ListModule02() = () - [] + [] member this.Max() = // integer List let resultInt = List.max [2..2..20] @@ -277,7 +276,7 @@ type ListModule02() = () - [] + [] member this.MaxBy() = // integer List let funcInt x = x%8 @@ -294,7 +293,7 @@ type ListModule02() = () - [] + [] member this.Min() = // integer List let resultInt = List.min [3;7;8;9;4;1;1;2] @@ -309,7 +308,7 @@ type ListModule02() = () - [] + [] member this.MinBy() = // integer List let funcInt x = x%8 @@ -327,7 +326,7 @@ type ListModule02() = () - [] + [] member this.Item() = // integer List let resultInt = List.item 3 [3;7;9;4;8;1;1;2] @@ -349,7 +348,7 @@ type ListModule02() = CheckThrowsArgumentException (fun () -> List.item i [3;7;9;4;8;1;1;2] |> ignore) - [] + [] member this.Of_Array() = // integer List let resultInt = List.ofArray [|1..10|] @@ -365,7 +364,7 @@ type ListModule02() = () - [] + [] member this.Of_Seq() = // integer List let resultInt = List.ofSeq {1..10} @@ -381,7 +380,7 @@ type ListModule02() = () - [] + [] member this.Partition() = // integer List let resultInt = List.partition (fun x -> x % 3 = 0) [1..10] @@ -399,7 +398,7 @@ type ListModule02() = () - [] + [] member this.Permute() = // integer List let resultInt = List.permute (fun i -> (i+1) % 4) [1;2;3;4] @@ -415,7 +414,7 @@ type ListModule02() = () - [] + [] member this.Reduce() = // integer List let resultInt = List.reduce (fun x y -> x/y) [5*4*3*2; 4;3;2;1] @@ -431,7 +430,7 @@ type ListModule02() = () - [] + [] member this.ReduceBack() = // integer List let resultInt = List.reduceBack (fun x y -> x/y) [5*4*3*2; 4;3;2;1] @@ -446,7 +445,7 @@ type ListModule02() = () - [] + [] member this.Rev() = // integer List let resultInt = List.rev [1..10] @@ -462,7 +461,7 @@ type ListModule02() = () - [] + [] member this.Scan() = // integer List let funcInt x y = x+y @@ -479,7 +478,7 @@ type ListModule02() = Assert.AreEqual([5], resultEpt) () - [] + [] member this.ScanBack() = // integer List let funcInt x y = x+y @@ -497,7 +496,7 @@ type ListModule02() = () - [] + [] member this.Skip() = // integer List let resultInt = List.skip 2 [1..10] @@ -521,7 +520,7 @@ type ListModule02() = CheckThrowsArgumentException(fun () -> List.skip 1 [] |> ignore) CheckThrowsArgumentException(fun () -> List.skip 4 [1; 2; 3] |> ignore) - [] + [] member this.SkipWhile() = // integer list let funcInt x = (x < 4) @@ -549,7 +548,7 @@ type ListModule02() = () - [] + [] member this.Sort() = // integer List let intArr = [3;5;7;2;4;8] @@ -573,7 +572,7 @@ type ListModule02() = () - [] + [] member this.SortBy() = // integer List let intArr = [3;5;7;2;4;8] @@ -597,7 +596,7 @@ type ListModule02() = () - [] + [] member this.SortDescending() = // integer List let minInt,maxInt = System.Int32.MinValue,System.Int32.MaxValue @@ -629,7 +628,7 @@ type ListModule02() = () - [] + [] member this.SortByDescending() = // integer List let intArr = [3;5;7;2;4;8] @@ -660,7 +659,7 @@ type ListModule02() = () - [] + [] member this.SortWith() = // integer list @@ -678,7 +677,7 @@ type ListModule02() = () - [] + [] member this.Sum() = // empty integer List let resultEptInt = List.sum ([]:int list) @@ -721,7 +720,7 @@ type ListModule02() = () - [] + [] member this.SumBy() = // empty integer List let resultEptInt = List.sumBy int ([]:int list) @@ -764,7 +763,7 @@ type ListModule02() = () - [] + [] member this.Tl() = // integer List let resultInt = List.tail [1..10] @@ -777,7 +776,7 @@ type ListModule02() = CheckThrowsArgumentException(fun () -> List.tail [] |> ignore) () - [] + [] member this.To_Array() = // integer List let resultInt = List.toArray [1..10] @@ -793,7 +792,7 @@ type ListModule02() = () - [] + [] member this.To_Seq() = // integer List let resultInt = [1..10] |> List.toSeq |> List.ofSeq @@ -809,7 +808,7 @@ type ListModule02() = () - [] + [] member this.Transpose() = // integer list Assert.AreEqual([[1; 4]; [2; 5]; [3; 6]], List.transpose (seq [[1..3]; [4..6]])) @@ -833,7 +832,7 @@ type ListModule02() = CheckThrowsArgumentException (fun () -> List.transpose [[1; 2]; []; [3; 4]] |> ignore) CheckThrowsArgumentException (fun () -> List.transpose [[1; 2]; [3; 4]; []] |> ignore) - [] + [] member this.Truncate() = // integer list Assert.AreEqual([1..3], List.truncate 3 [1..5]) @@ -853,7 +852,7 @@ type ListModule02() = () - [] + [] member this.TryFind() = // integer List let resultInt = [1..10] |> List.tryFind (fun x -> x%7 = 0) @@ -873,7 +872,7 @@ type ListModule02() = () - [] + [] member this.TryFindBack() = // integer List Assert.AreEqual(Some 20, [1..20] |> List.tryFindBack (fun x -> x%5 = 0)) @@ -896,7 +895,7 @@ type ListModule02() = () - [] + [] member this.TryFindIndex() = // integer List let resultInt = [1..10] |> List.tryFindIndex (fun x -> x%7 = 0) @@ -911,7 +910,7 @@ type ListModule02() = Assert.AreEqual(None, resultEpt) () - [] + [] member this.TryFindIndexBack() = // integer List Assert.AreEqual(Some 19, [1..20] |> List.tryFindIndexBack (fun x -> x%5 = 0)) @@ -930,7 +929,7 @@ type ListModule02() = () - [] + [] member this.Unfold() = // integer Seq let resultInt = List.unfold (fun x -> if x < 20 then Some (x+1,x*2) else None) 1 @@ -947,7 +946,7 @@ type ListModule02() = () - [] + [] member this.Unzip() = // integer List let resultInt = List.unzip [(1,2);(2,4);(3,6)] @@ -966,7 +965,7 @@ type ListModule02() = () - [] + [] member this.Unzip3() = // integer List let resultInt = List.unzip3 [(1,2,3);(2,4,6);(3,6,9)] @@ -984,7 +983,7 @@ type ListModule02() = () - [] + [] member this.Windowed() = let testWindowed config = try @@ -1068,7 +1067,7 @@ type ListModule02() = () - [] + [] member this.Zip() = // integer List let resultInt = List.zip [1..3] [2..2..6] @@ -1085,14 +1084,14 @@ type ListModule02() = () - [] + [] member this.Zip3() = // integer List let resultInt = List.zip3 [1..3] [2..2..6] [3;6;9] Assert.AreEqual([(1,2,3); (2,4,6); (3,6,9)], resultInt) // string List - let resultStr = List.zip3[2;3;4;5] ["b";"c";"d";"e"] ["II"; "III"; "IV"; "V"] + let resultStr = List.zip3 [2;3;4;5] ["b";"c";"d";"e"] ["II"; "III"; "IV"; "V"] Assert.AreEqual([(2,"b","II");(3,"c","III");(4,"d","IV");(5,"e","V")], resultStr) // empty List @@ -1102,7 +1101,7 @@ type ListModule02() = () - [] + [] member this.tryItem() = // integer List let resultInt = List.tryItem 4 [3;7;9;4;8;1;1;2] @@ -1123,3 +1122,88 @@ type ListModule02() = // Index equals to length let resultIndexGreater = List.tryItem 4 [3;1;6;2] Assert.AreEqual(None, resultIndexGreater) + + [] + member this.RemoveAt() = + // integer list + Assert.AreEqual([2; 3; 4; 5], (List.removeAt 0 [1..5])) + Assert.AreEqual([1; 2; 4; 5], (List.removeAt 2 [1..5])) + Assert.AreEqual([1; 2; 3; 4], (List.removeAt 4 [1..5])) + + //string list + Assert.AreEqual(["2"; "3"; "4"; "5"], (List.removeAt 0 ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "4"; "5"], (List.removeAt 2 ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "3"; "4"], (List.removeAt 4 ["1"; "2"; "3"; "4"; "5"])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> List.removeAt 0 [] |> ignore) + CheckThrowsArgumentException (fun () -> List.removeAt -1 [1] |> ignore) + CheckThrowsArgumentException (fun () -> List.removeAt 2 [1] |> ignore) + + [] + member this.RemoveManyAt() = + // integer list + Assert.AreEqual([3; 4; 5], (List.removeManyAt 0 2 [1..5])) + Assert.AreEqual([1; 2; 5], (List.removeManyAt 2 2 [1..5])) + Assert.AreEqual([1; 2; 3], (List.removeManyAt 3 2 [1..5])) + + //string list + Assert.AreEqual(["3"; "4"; "5"], (List.removeManyAt 0 2 ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "5"], (List.removeManyAt 2 2 ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "3"], (List.removeManyAt 3 2 ["1"; "2"; "3"; "4"; "5"])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> List.removeManyAt 0 2 [] |> ignore) + CheckThrowsArgumentException (fun () -> List.removeManyAt -1 2 [1] |> ignore) + CheckThrowsArgumentException (fun () -> List.removeManyAt 2 2 [1] |> ignore) + + [] + member this.UpdateAt() = + // integer list + Assert.AreEqual([0; 2; 3; 4; 5], (List.updateAt 0 0 [1..5])) + Assert.AreEqual([1; 2; 0; 4; 5], (List.updateAt 2 0 [1..5])) + Assert.AreEqual([1; 2; 3; 4; 0], (List.updateAt 4 0 [1..5])) + + //string list + Assert.AreEqual(["0"; "2"; "3"; "4"; "5"], (List.updateAt 0 "0" ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "0"; "4"; "5"], (List.updateAt 2 "0" ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"], (List.updateAt 4 "0" ["1"; "2"; "3"; "4"; "5"])) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> List.updateAt 0 0 [] |> ignore) + CheckThrowsArgumentException (fun () -> List.updateAt -1 0 [1] |> ignore) + CheckThrowsArgumentException (fun () -> List.updateAt 2 0 [1] |> ignore) + + [] + member this.InsertAt() = + // integer list + Assert.AreEqual([0; 1; 2; 3; 4; 5], (List.insertAt 0 0 [1..5])) + Assert.AreEqual([1; 2; 0; 3; 4; 5], (List.insertAt 2 0 [1..5])) + Assert.AreEqual([1; 2; 3; 4; 0; 5], (List.insertAt 4 0 [1..5])) + + //string list + Assert.AreEqual(["0"; "1"; "2"; "3"; "4"; "5"], (List.insertAt 0 "0" ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "0"; "3"; "4"; "5"], (List.insertAt 2 "0" ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"; "5"], (List.insertAt 4 "0" ["1"; "2"; "3"; "4"; "5"])) + + // empty list & out of bounds + Assert.AreEqual([0], List.insertAt 0 0 []) + CheckThrowsArgumentException (fun () -> List.insertAt -1 0 [1] |> ignore) + CheckThrowsArgumentException (fun () -> List.insertAt 2 0 [1] |> ignore) + + [] + member this.InsertManyAt() = + // integer list + Assert.AreEqual([0; 0; 1; 2; 3; 4; 5], (List.insertManyAt 0 [0; 0] [1..5])) + Assert.AreEqual([1; 2; 0; 0; 3; 4; 5], (List.insertManyAt 2 [0; 0] [1..5])) + Assert.AreEqual([1; 2; 3; 4; 0; 0; 5], (List.insertManyAt 4 [0; 0] [1..5])) + + //string list + Assert.AreEqual(["0"; "0"; "1"; "2"; "3"; "4"; "5"], (List.insertManyAt 0 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "0"; "0"; "3"; "4"; "5"], (List.insertManyAt 2 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"])) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"; "0"; "5"], (List.insertManyAt 4 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"])) + + // empty list & out of bounds + Assert.AreEqual([0; 0], List.insertManyAt 0 [0; 0] []) + CheckThrowsArgumentException (fun () -> List.insertManyAt -1 [0; 0] [1] |> ignore) + CheckThrowsArgumentException (fun () -> List.insertManyAt 2 [0; 0] [1] |> ignore) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListProperties.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListProperties.fs index ae84d693f89..81a0fafc0fe 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListProperties.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListProperties.fs @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -[][] -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.ListProperties +module FSharp.Core.UnitTests.Collections.ListProperties open System open System.Collections.Generic -open NUnit.Framework +open Xunit open FsCheck open Utils @@ -14,7 +13,7 @@ let chunkBySize_and_collect<'a when 'a : equality> (xs : 'a list) size = let b = List.collect id a b = xs) -[] +[] let ``chunkBySize is reversable with collect`` () = Check.QuickThrowOnFailure chunkBySize_and_collect Check.QuickThrowOnFailure chunkBySize_and_collect @@ -26,7 +25,7 @@ let windowed_and_length<'a when 'a : equality> (xs : 'a list) size = |> List.forall (fun x -> x.Length = size)) -[] +[] let ``windowed returns list with correct length`` () = Check.QuickThrowOnFailure windowed_and_length Check.QuickThrowOnFailure windowed_and_length @@ -39,7 +38,7 @@ let windowed_and_order<'a when 'a : equality> (listsize:PositiveInt) size = List.windowed size xs |> List.forall (fun w -> w = List.sort w)) -[] +[] let ``windowed returns succeeding elements`` () = Check.QuickThrowOnFailure windowed_and_order Check.QuickThrowOnFailure windowed_and_order @@ -55,7 +54,7 @@ let partition_and_sort<'a when 'a : comparison> (xs : 'a list) = qsort xs = (List.sort xs) -[] +[] let ``partition can be used to sort`` () = Check.QuickThrowOnFailure partition_and_sort Check.QuickThrowOnFailure partition_and_sort @@ -67,13 +66,13 @@ let windowed_and_pairwise<'a when 'a : equality> (xs : 'a list) = a = b -[] +[] let ``windowed 2 is like pairwise`` () = Check.QuickThrowOnFailure windowed_and_pairwise Check.QuickThrowOnFailure windowed_and_pairwise Check.QuickThrowOnFailure windowed_and_pairwise -[] +[] let ``chunkBySize produces chunks exactly of size `chunkSize`, except the last one, which can be smaller, but not empty``() = let prop (a: _ list) (PositiveInt chunkSize) = match a |> List.chunkBySize chunkSize |> Seq.toList with @@ -97,7 +96,7 @@ let splitInto_and_collect<'a when 'a : equality> (xs : 'a list) count = let b = List.collect id a b = xs) -[] +[] let ``splitInto is reversable with collect`` () = Check.QuickThrowOnFailure splitInto_and_collect Check.QuickThrowOnFailure splitInto_and_collect @@ -109,7 +108,7 @@ let splitAt_and_append<'a when 'a : equality> (xs : 'a list) index = let b = List.append a1 a2 b = xs && a1.Length = index) -[] +[] let ``splitAt is reversable with append`` () = Check.QuickThrowOnFailure splitAt_and_append Check.QuickThrowOnFailure splitAt_and_append @@ -120,7 +119,7 @@ let indexed_and_zip<'a when 'a : equality> (xs : 'a list) = let b = List.indexed xs b = List.zip a xs -[] +[] let ``indexed is adding correct indexes`` () = Check.QuickThrowOnFailure indexed_and_zip Check.QuickThrowOnFailure indexed_and_zip @@ -135,7 +134,7 @@ let zip_and_zip3<'a when 'a : equality> (xs' : ('a*'a*'a) list) = let b = List.zip (List.zip xs xs2) xs3 |> List.map (fun ((a,b),c) -> a,b,c) a = b -[] +[] let ``two zips can be used for zip3`` () = Check.QuickThrowOnFailure zip_and_zip3 Check.QuickThrowOnFailure zip_and_zip3 @@ -145,7 +144,7 @@ let zip_and_unzip<'a when 'a : equality> (xs' : ('a*'a) list) = let xs,xs2 = List.unzip xs' List.zip xs xs2 = xs' -[] +[] let ``zip and unzip are dual`` () = Check.QuickThrowOnFailure zip_and_unzip Check.QuickThrowOnFailure zip_and_unzip @@ -155,13 +154,13 @@ let zip3_and_unzip3<'a when 'a : equality> (xs' : ('a*'a*'a) list) = let xs,xs2,xs3 = List.unzip3 xs' List.zip3 xs xs2 xs3 = xs' -[] +[] let ``zip3 and unzip3 are dual`` () = Check.QuickThrowOnFailure zip3_and_unzip3 Check.QuickThrowOnFailure zip3_and_unzip3 Check.QuickThrowOnFailure zip3_and_unzip3 -[] +[] let ``splitInto produces chunks exactly `count` chunks with equal size (+/- 1)``() = let prop (a: _ list) (PositiveInt count') = let count = min a.Length count' @@ -188,7 +187,7 @@ let sort_and_sortby (xs : list) (xs2 : list) = result := false !result -[] +[] let ``sort behaves like sortby id`` () = Check.QuickThrowOnFailure sort_and_sortby @@ -197,7 +196,7 @@ let filter_and_except<'a when 'a : comparison> (xs : list<'a>) (itemsToExclude let b = List.except itemsToExclude xs a = b -[] +[] let ``filter and except work similar`` () = Check.QuickThrowOnFailure filter_and_except Check.QuickThrowOnFailure filter_and_except @@ -208,7 +207,7 @@ let filter_and_where<'a when 'a : comparison> (xs : list<'a>) predicate = let b = List.where predicate xs a = b -[] +[] let ``filter and where work similar`` () = Check.QuickThrowOnFailure filter_and_where Check.QuickThrowOnFailure filter_and_where @@ -219,7 +218,7 @@ let find_and_pick<'a when 'a : comparison> (xs : list<'a>) predicate = let b = runAndCheckIfAnyError (fun () -> List.pick (fun x -> if predicate x then Some x else None) xs) a = b -[] +[] let ``pick works like find`` () = Check.QuickThrowOnFailure find_and_pick Check.QuickThrowOnFailure find_and_pick @@ -230,7 +229,7 @@ let choose_and_pick<'a when 'a : comparison> (xs : list<'a>) predicate = let b = runAndCheckIfAnyError (fun () -> List.pick predicate xs) a = b -[] +[] let ``pick works like choose + head`` () = Check.QuickThrowOnFailure choose_and_pick Check.QuickThrowOnFailure choose_and_pick @@ -242,7 +241,7 @@ let head_and_tail<'a when 'a : comparison> (xs : list<'a>) = let t = List.tail xs xs = h :: t) -[] +[] let ``head and tail gives the list`` () = Check.QuickThrowOnFailure head_and_tail Check.QuickThrowOnFailure head_and_tail @@ -256,7 +255,7 @@ let tryHead_and_tail<'a when 'a : comparison> (xs : list<'a>) = let t = List.tail xs xs = h :: t -[] +[] let ``tryHead and tail gives the list`` () = Check.QuickThrowOnFailure tryHead_and_tail Check.QuickThrowOnFailure tryHead_and_tail @@ -270,7 +269,7 @@ let skip_and_take<'a when 'a : comparison> (xs : list<'a>) (count:NonNegativeIn xs = t @ s else true -[] +[] let ``skip and take gives the list`` () = Check.QuickThrowOnFailure skip_and_take Check.QuickThrowOnFailure skip_and_take @@ -284,7 +283,7 @@ let truncate_and_take<'a when 'a : comparison> (xs : list<'a>) (count:NonNegati a = b else true -[] +[] let ``truncate and take work similar`` () = Check.QuickThrowOnFailure truncate_and_take Check.QuickThrowOnFailure truncate_and_take @@ -297,7 +296,7 @@ let skipWhile_and_takeWhile<'a when 'a : comparison> (xs : list<'a>) f = xs = t @ s else true -[] +[] let ``skipWhile and takeWhile gives the list`` () = Check.QuickThrowOnFailure skipWhile_and_takeWhile Check.QuickThrowOnFailure skipWhile_and_takeWhile @@ -313,7 +312,7 @@ let find_and_exists<'a when 'a : comparison> (xs : list<'a>) f = let b = List.exists f xs a = b -[] +[] let ``find and exists work similar`` () = Check.QuickThrowOnFailure find_and_exists Check.QuickThrowOnFailure find_and_exists @@ -324,7 +323,7 @@ let exists_and_forall<'a when 'a : comparison> (xs : list<'a>) (F (_, predicate let b = List.exists predicate xs a = not b -[] +[] let ``exists and forall are dual`` () = Check.QuickThrowOnFailure exists_and_forall Check.QuickThrowOnFailure exists_and_forall @@ -341,7 +340,7 @@ let head_and_isEmpty<'a when 'a : comparison> (xs : list<'a>) = a = not b -[] +[] let ``head fails when list isEmpty`` () = Check.QuickThrowOnFailure head_and_isEmpty Check.QuickThrowOnFailure head_and_isEmpty @@ -353,7 +352,7 @@ let head_and_last<'a when 'a : comparison> (xs : list<'a>) = a = b -[] +[] let ``head is the same as last of a reversed list`` () = Check.QuickThrowOnFailure head_and_last Check.QuickThrowOnFailure head_and_last @@ -365,7 +364,7 @@ let head_and_item<'a when 'a : comparison> (xs : list<'a>) = a = b -[] +[] let ``head is the same as item 0`` () = Check.QuickThrowOnFailure head_and_item Check.QuickThrowOnFailure head_and_item @@ -379,7 +378,7 @@ let item_and_tryItem<'a when 'a : comparison> (xs : list<'a>) pos = | Success a -> b.Value = a | _ -> b = None -[] +[] let ``tryItem is safe item`` () = Check.QuickThrowOnFailure item_and_tryItem Check.QuickThrowOnFailure item_and_tryItem @@ -393,7 +392,7 @@ let pick_and_tryPick<'a when 'a : comparison> (xs : list<'a>) f = | Success a -> b.Value = a | _ -> b = None -[] +[] let ``tryPick is safe pick`` () = Check.QuickThrowOnFailure pick_and_tryPick Check.QuickThrowOnFailure pick_and_tryPick @@ -407,7 +406,7 @@ let last_and_tryLast<'a when 'a : comparison> (xs : list<'a>) = | Success a -> b.Value = a | _ -> b = None -[] +[] let ``tryLast is safe last`` () = Check.QuickThrowOnFailure last_and_tryLast Check.QuickThrowOnFailure last_and_tryLast @@ -419,7 +418,7 @@ let length_and_isEmpty<'a when 'a : comparison> (xs : list<'a>) = a = b -[] +[] let ``list isEmpty if and only if length is 0`` () = Check.QuickThrowOnFailure length_and_isEmpty Check.QuickThrowOnFailure length_and_isEmpty @@ -431,7 +430,7 @@ let min_and_max (xs : list) = a = b -[] +[] let ``min is opposite of max`` () = Check.QuickThrowOnFailure min_and_max @@ -441,7 +440,7 @@ let minBy_and_maxBy (xs : list) f = a = b -[] +[] let ``minBy is opposite of maxBy`` () = Check.QuickThrowOnFailure minBy_and_maxBy @@ -451,7 +450,7 @@ let minBy_and_min (xs : list) = a = b -[] +[] let ``minBy id is same as min`` () = Check.QuickThrowOnFailure minBy_and_min @@ -461,7 +460,7 @@ let min_and_sort<'a when 'a : comparison> (xs : list<'a>) = a = b -[] +[] let ``head element after sort is min element`` () = Check.QuickThrowOnFailure min_and_sort Check.QuickThrowOnFailure min_and_sort @@ -481,7 +480,7 @@ let pairwise<'a when 'a : comparison> (xs : list<'a>) = f = (xs |> List.rev |> List.tail |> List.rev) && // all elements but last one s = (xs |> List.tail) // all elements but first one -[] +[] let ``pairwise works as expected`` () = Check.QuickThrowOnFailure pairwise Check.QuickThrowOnFailure pairwise @@ -512,7 +511,7 @@ let permute<'a when 'a : comparison> (xs' : list) = true | _ -> true -[] +[] let ``permute works as expected`` () = Check.QuickThrowOnFailure permute Check.QuickThrowOnFailure permute @@ -528,7 +527,7 @@ let mapi_and_map<'a when 'a : comparison> (xs : list<'a>) f = a = b && (Seq.toList indices = [0..xs.Length-1]) -[] +[] let ``mapi behaves like map with correct order`` () = Check.QuickThrowOnFailure mapi_and_map Check.QuickThrowOnFailure mapi_and_map @@ -542,7 +541,7 @@ let reduce_and_fold<'a when 'a : comparison> (xs : list<'a>) seed (F (_, f)) = let br = seed :: xs |> List.reduce f ar = br -[] +[] let ``reduce works like fold with given seed`` () = Check.QuickThrowOnFailure reduce_and_fold Check.QuickThrowOnFailure reduce_and_fold @@ -558,7 +557,7 @@ let scan_and_fold<'a when 'a : comparison> (xs : list<'a>) seed (F (_, f)) = ar = List.rev br -[] +[] let ``scan works like fold but returns intermediate values`` () = Check.QuickThrowOnFailure scan_and_fold Check.QuickThrowOnFailure scan_and_fold @@ -574,7 +573,7 @@ let scanBack_and_foldBack<'a when 'a : comparison> (xs : list<'a>) seed (F (_, f ar = br -[] +[] let ``scanBack works like foldBack but returns intermediate values`` () = Check.QuickThrowOnFailure scanBack_and_foldBack Check.QuickThrowOnFailure scanBack_and_foldBack @@ -588,7 +587,7 @@ let reduceBack_and_foldBack<'a when 'a : comparison> (xs : list<'a>) seed (F (_, let br = List.reduceBack f (xs @ [seed]) ar = br -[] +[] let ``reduceBack works like foldBack with given seed`` () = Check.QuickThrowOnFailure reduceBack_and_foldBack Check.QuickThrowOnFailure reduceBack_and_foldBack @@ -599,7 +598,7 @@ let replicate<'a when 'a : comparison> (x:'a) (count:NonNegativeInt) = let xs = List.replicate count x xs.Length = count && List.forall ((=) x) xs -[] +[] let ``replicate creates n instances of the given element`` () = Check.QuickThrowOnFailure replicate Check.QuickThrowOnFailure replicate @@ -611,7 +610,7 @@ let singleton_and_replicate<'a when 'a : comparison> (x:'a) (count:NonNegativeIn let ys = [for i in 1..count -> List.singleton x] |> List.concat xs = ys -[] +[] let ``singleton can be used to replicate`` () = Check.QuickThrowOnFailure singleton_and_replicate Check.QuickThrowOnFailure singleton_and_replicate @@ -628,7 +627,7 @@ let mapFold_and_map_and_fold<'a when 'a : comparison> (xs : list<'a>) mapF foldF let br = b |> List.fold foldF start a = b && ar = br -[] +[] let ``mapFold works like map + fold`` () = Check.QuickThrowOnFailure mapFold_and_map_and_fold Check.QuickThrowOnFailure mapFold_and_map_and_fold @@ -645,7 +644,7 @@ let mapFoldBack_and_map_and_foldBack<'a when 'a : comparison> (xs : list<'a>) ma let br = List.foldBack foldF b start a = b && ar = br -[] +[] let ``mapFoldBack works like map + foldBack`` () = Check.QuickThrowOnFailure mapFoldBack_and_map_and_foldBack Check.QuickThrowOnFailure mapFoldBack_and_map_and_foldBack @@ -661,7 +660,7 @@ let findBack_and_exists<'a when 'a : comparison> (xs : list<'a>) f = let b = List.exists f xs a = b -[] +[] let ``findBack and exists work similar`` () = Check.QuickThrowOnFailure findBack_and_exists Check.QuickThrowOnFailure findBack_and_exists @@ -672,7 +671,7 @@ let findBack_and_find<'a when 'a : comparison> (xs : list<'a>) predicate = let b = run (fun () -> xs |> List.rev |> List.find predicate) a = b -[] +[] let ``findBack and find work in reverse`` () = Check.QuickThrowOnFailure findBack_and_find Check.QuickThrowOnFailure findBack_and_find @@ -683,7 +682,7 @@ let tryFindBack_and_tryFind<'a when 'a : comparison> (xs : list<'a>) predicate let b = xs |> List.rev |> List.tryFind predicate a = b -[] +[] let ``tryFindBack and tryFind work in reverse`` () = Check.QuickThrowOnFailure tryFindBack_and_tryFind Check.QuickThrowOnFailure tryFindBack_and_tryFind @@ -696,7 +695,7 @@ let tryFindIndexBack_and_tryFindIndex<'a when 'a : comparison> (xs : list<'a>) | Some a, Some b -> a = (xs.Length - b - 1) | _ -> a = b -[] +[] let ``tryFindIndexBack and tryIndexFind work in reverse`` () = Check.QuickThrowOnFailure tryFindIndexBack_and_tryFindIndex Check.QuickThrowOnFailure tryFindIndexBack_and_tryFindIndex @@ -709,7 +708,7 @@ let rev<'a when 'a : comparison> (xs : list<'a>) = xs |> List.rev |> List.rev = xs && Seq.toList list = List.rev xs -[] +[] let ``rev reverses a list`` () = Check.QuickThrowOnFailure rev Check.QuickThrowOnFailure rev @@ -722,7 +721,7 @@ let findIndexBack_and_findIndex<'a when 'a : comparison> (xs : list<'a>) (F (_, | Success a, Success b -> a = (xs.Length - b - 1) | _ -> a = b -[] +[] let ``findIndexBack and findIndex work in reverse`` () = Check.QuickThrowOnFailure findIndexBack_and_findIndex Check.QuickThrowOnFailure findIndexBack_and_findIndex @@ -737,7 +736,7 @@ let skip_and_skipWhile<'a when 'a : comparison> (xs : list<'a>) (count:NonNegat a = b) -[] +[] let ``skip and skipWhile are consistent`` () = Check.QuickThrowOnFailure skip_and_skipWhile Check.QuickThrowOnFailure skip_and_skipWhile @@ -757,7 +756,7 @@ let distinct_works_like_set<'a when 'a : comparison> (xs : 'a list) = result := false !result -[] +[] let ``distinct creates same elements like a set`` () = Check.QuickThrowOnFailure distinct_works_like_set Check.QuickThrowOnFailure distinct_works_like_set @@ -768,7 +767,7 @@ let sort_and_sortDescending<'a when 'a : comparison> (xs : list<'a>) = let b = run (fun () -> xs |> List.sortDescending |> List.rev) a = b -[] +[] let ``sort and sortDescending work in reverse`` () = Check.QuickThrowOnFailure sort_and_sortDescending Check.QuickThrowOnFailure sort_and_sortDescending @@ -779,7 +778,7 @@ let sortByStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> List.sortBy snd isStable sorted -[] +[] let ``List.sortBy is stable`` () = Check.QuickThrowOnFailure sortByStable Check.QuickThrowOnFailure sortByStable @@ -789,7 +788,7 @@ let sortWithStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> List.sortWith (fun x y -> compare (snd x) (snd y)) isStable sorted -[] +[] let ``List.sortWithStable is stable`` () = Check.QuickThrowOnFailure sortWithStable Check.QuickThrowOnFailure sortWithStable @@ -799,12 +798,12 @@ let distinctByStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> List.distinctBy snd isStable sorted -[] +[] let ``List.distinctBy is stable`` () = Check.QuickThrowOnFailure distinctByStable Check.QuickThrowOnFailure distinctByStable -[] +[] let ``List.sum calculates the sum`` () = let sum (xs : int list) = let s = List.sum xs @@ -818,7 +817,7 @@ let sumBy<'a> (xs : 'a list) (f:'a -> int) = let r = List.sumBy f xs r = s -[] +[] let ``List.sumBy calculates the sum of the mapped list`` () = Check.QuickThrowOnFailure sumBy Check.QuickThrowOnFailure sumBy @@ -828,7 +827,7 @@ let allPairsCount<'a, 'b> (xs : 'a list) (ys : 'b list) = let pairs = List.allPairs xs ys pairs.Length = xs.Length * ys.Length -[] +[] let ``List.allPairs produces the correct number of pairs`` () = Check.QuickThrowOnFailure allPairsCount Check.QuickThrowOnFailure allPairsCount @@ -839,7 +838,7 @@ let allPairsFst<'a, 'b when 'a : equality> (xs : 'a list) (ys : 'b list) = let check = xs |> List.collect (List.replicate ys.Length) pairsFst = check -[] +[] let ``List.allPairs first elements are correct`` () = Check.QuickThrowOnFailure allPairsFst Check.QuickThrowOnFailure allPairsFst @@ -850,7 +849,7 @@ let allPairsSnd<'a, 'b when 'b : equality> (xs : 'a list) (ys : 'b list) = let check = [ for i in 1 .. xs.Length do yield! ys ] pairsSnd = check -[] +[] let ``List.allPairs second elements are correct`` () = Check.QuickThrowOnFailure allPairsFst Check.QuickThrowOnFailure allPairsFst diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListType.fs index bf70a8b4233..fd78d5298f5 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListType.fs @@ -3,13 +3,13 @@ // Various tests for the: // Microsoft.FSharp.Collections.List type -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open System.Collections open System.Collections.Generic open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -19,11 +19,10 @@ Make sure each method works on: * Empty List (0 elements) *) -[][][] type ListType() = - + // Interfaces - [] + [] member this.IEnumerable() = // Legit IE @@ -53,7 +52,7 @@ type ListType() = Assert.AreEqual(false, enum.MoveNext()) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IEnumerable_T() = // Legit IE @@ -83,7 +82,7 @@ type ListType() = Assert.AreEqual(false, enum.MoveNext()) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IReadOnlyCollection_T() = // Legit IReadOnlyCollection_T @@ -100,7 +99,7 @@ type ListType() = Assert.AreEqual(c.Count, 0) - [] + [] member this.IReadOnlyList_T() = let c = ['a'; 'b'; 'c'] :> IReadOnlyList @@ -116,48 +115,48 @@ type ListType() = CheckThrowsArgumentException(fun () -> c.[0] |> ignore) // Base class methods - [] + [] member this.ObjectToString() = Assert.AreEqual("[1; 2; 3]", [1; 2; 3].ToString()) Assert.AreEqual("[]", [].ToString()) Assert.AreEqual("[]", ([] : decimal list list).ToString()) - [] + [] member this.ObjectEquals() = // All three are different references, but equality has been // provided by the F# compiler. let a = [1; 2; 3] let b = [1 .. 3] let c = 1 :: [2; 3] - Assert.IsTrue( (a = b) ) - Assert.IsTrue( (b = c) ) - Assert.IsTrue( (c = a) ) - Assert.IsTrue( a.Equals(b) ); Assert.IsTrue( b.Equals(a) ) - Assert.IsTrue( b.Equals(c) ); Assert.IsTrue( c.Equals(b) ) - Assert.IsTrue( c.Equals(a) ); Assert.IsTrue( a.Equals(c) ) + Assert.True( (a = b) ) + Assert.True( (b = c) ) + Assert.True( (c = a) ) + Assert.True( a.Equals(b) ); Assert.True( b.Equals(a) ) + Assert.True( b.Equals(c) ); Assert.True( c.Equals(b) ) + Assert.True( c.Equals(a) ); Assert.True( a.Equals(c) ) // Equality between types let a = [] : int list let b = [] : string list - Assert.IsFalse( b.Equals(a) ) - Assert.IsFalse( a.Equals(b) ) + Assert.False( b.Equals(a) ) + Assert.False( a.Equals(b) ) // Co/contra variance not supported let a = [] : string list let b = [] : obj list - Assert.IsFalse(a.Equals(b)) - Assert.IsFalse(b.Equals(a)) + Assert.False(a.Equals(b)) + Assert.False(b.Equals(a)) // Self equality let a = [1] - Assert.IsTrue( (a = a) ) - Assert.IsTrue(a.Equals(a)) + Assert.True( (a = a) ) + Assert.True(a.Equals(a)) // Null - Assert.IsFalse(a.Equals(null)) + Assert.False(a.Equals(null)) // Instance methods - [] + [] member this.Length() = let l = [1 .. 10] @@ -166,18 +165,18 @@ type ListType() = let e : int list list = List.empty Assert.AreEqual(e.Length, 0) - [] + [] member this.IsEmpty() = let l = [1 .. 10] - Assert.IsFalse(l.IsEmpty) + Assert.False(l.IsEmpty) let e = Microsoft.FSharp.Collections.List.Empty : string list - Assert.IsTrue(e.IsEmpty) + Assert.True(e.IsEmpty) - Assert.IsTrue( ([] @ []).IsEmpty ) + Assert.True( ([] @ []).IsEmpty ) - [] + [] member this.Head() = let l = ['a'; 'e'; 'i'; 'o'; 'u'] @@ -185,7 +184,7 @@ type ListType() = CheckThrowsInvalidOperationExn(fun () -> ([] : string list).Head |> ignore) - [] + [] member this.Tail() = let l = ['a'; 'e'; 'i'; 'o'; 'u'] @@ -193,7 +192,7 @@ type ListType() = CheckThrowsInvalidOperationExn(fun () -> ([] : string list).Tail |> ignore) - [] + [] member this.Item() = let mutable l = [1] @@ -215,21 +214,21 @@ type ListType() = // Static methods - [] + [] member this.Empty() = let emptyList = Microsoft.FSharp.Collections.List.Empty if List.length emptyList <> 0 then Assert.Fail() let c : int list = Microsoft.FSharp.Collections.List.Empty - Assert.IsTrue( (c = []) ) + Assert.True( (c = []) ) let d : string list = Microsoft.FSharp.Collections.List.Empty - Assert.IsTrue( (d = []) ) + Assert.True( (d = []) ) () - [] + [] member this.Cons() = // integer List let intList = Microsoft.FSharp.Collections.List.Cons (1, [ 2;3; 4 ]) @@ -245,7 +244,7 @@ type ListType() = () - [] + [] member this.SlicingUnboundedEnd() = let lst = [1;2;3;4;5;6] @@ -257,7 +256,7 @@ type ListType() = Assert.AreEqual(lst.[6..], ([]: int list)) - [] + [] member this.SlicingUnboundedStart() = let lst = [1;2;3;4;5;6] @@ -270,7 +269,7 @@ type ListType() = Assert.AreEqual(lst.[..5], [1;2;3;4;5;6]) - [] + [] member this.SlicingBoundedStartEnd() = let lst = [1;2;3;4;5;6] @@ -296,7 +295,7 @@ type ListType() = Assert.AreEqual(lst.[4..1], ([]: int list)) - [] + [] member this.SlicingEmptyList() = let empty : obj list = List.empty @@ -308,7 +307,7 @@ type ListType() = Assert.AreEqual(empty.[3..5], ([]: obj list)) - [] + [] member this.SlicingOutOfBounds() = let lst = [1;2;3;4;5;6] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapModule.fs index 16145eb62f2..8884e32486a 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Map module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -20,20 +20,19 @@ Make sure each method works on: *) -[][][] type MapModule() = - [] + [] member this.Empty() = - let emptyMap = Map.empty - Assert.IsTrue(Map.isEmpty emptyMap) + let emptyMap = Map.empty + Assert.True(Map.isEmpty emptyMap) let a:Map = Map.empty let b : Map = Map.empty let c : Map = Map.empty - + () - - [] + + [] member this.Add() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -63,32 +62,66 @@ type MapModule() = () - [] + [] + member this.Change() = + + let a = (Map.ofArray [|(1,1);(2,4);(3,9)|]) + let b = Map.change 4 (fun current -> Assert.AreEqual(current, None); Some 16) a + Assert.AreEqual(b.[1], 1) + Assert.AreEqual(b.[2], 4) + Assert.AreEqual(b.[3], 9) + Assert.AreEqual(b.[4], 16) + let c = Map.change 4 (fun current -> Assert.AreEqual(current, Some 16); Some 25) b + Assert.AreEqual(b.[1], 1) + Assert.AreEqual(b.[2], 4) + Assert.AreEqual(b.[3], 9) + Assert.AreEqual(c.[4], 25) + + // empty Map + let eptMap = Map.empty + let resultEpt = Map.change 1 (fun current -> Assert.AreEqual(current, None); Some "a") eptMap + Assert.AreEqual(resultEpt.[1], "a") + + // One-element Map + let oeleMap = Map.ofSeq [(1, "one")] + let resultOele = Map.change 7 (fun current -> Assert.AreEqual(current, None); Some "seven") oeleMap + Assert.AreEqual(resultOele.[7], "seven") + + // Remove element + let resultRm = Map.change 1 (fun current -> Assert.AreEqual(current, Some 1); None) c + Assert.False(resultRm.ContainsKey 1) + Assert.AreEqual(resultRm.[2], 4) + Assert.AreEqual(resultRm.[3], 9) + Assert.AreEqual(resultRm.[4], 25) + + () + + [] member this.Exists() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] let resultValueMap = Map.exists (fun x y -> x > 3) valueKeyMap - Assert.IsTrue(resultValueMap) + Assert.True(resultValueMap) // reference keys let refMap = Map.ofSeq [for c in ["."; ".."; "..."; "...."] do yield (c, c.Length) ] let resultRefMap = refMap |> Map.exists (fun x y -> y>2 ) - Assert.IsTrue(resultRefMap) + Assert.True(resultRefMap) // One-element Map let oeleMap = Map.ofSeq [(1, "one")] let resultOele = oeleMap |> Map.exists (fun x y -> (x + y.Length) % 4 = 0 ) - Assert.IsTrue(resultOele) + Assert.True(resultOele) // empty Map let eptMap = Map.empty let resultEpt = Map.exists (fun x y -> false) eptMap - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) () - [] + [] member this.Filter() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -113,7 +146,7 @@ type MapModule() = () - [] + [] member this.Find() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -136,7 +169,7 @@ type MapModule() = () - [] + [] member this.FindIndex() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -159,7 +192,7 @@ type MapModule() = () - [] + [] member this.TryPick() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -184,7 +217,7 @@ type MapModule() = () - [] + [] member this.Pick() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -211,7 +244,7 @@ type MapModule() = () - [] + [] member this.Fold() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -235,7 +268,7 @@ type MapModule() = () - [] + [] member this.FoldBack() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -259,56 +292,56 @@ type MapModule() = () - [] + [] member this.ForAll() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] let resultValueMap = valueKeyMap |> Map.forall (fun x y -> x % 3 = 0) - Assert.IsFalse(resultValueMap) + Assert.False(resultValueMap) // reference keys let refMap = Map.ofSeq [for c in ["."; ".."; "..."; "...."] do yield (c, c.Length) ] let resultRefMap = refMap |> Map.forall (fun x y -> x.Length > 4 ) - Assert.IsFalse(resultRefMap) + Assert.False(resultRefMap) // One-element Map let oeleMap = Map.ofSeq [(1, "one")] let resultOele = oeleMap |> Map.forall (fun x y -> x<3 ) - Assert.IsTrue(resultOele) + Assert.True(resultOele) // empty Map let eptMap = Map.empty let resultEpt =eptMap |> Map.forall (fun x y -> true) - Assert.IsTrue(resultEpt) + Assert.True(resultEpt) () - [] + [] member this.IsEmpty() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] let resultValueMap = Map.isEmpty valueKeyMap - Assert.IsFalse(resultValueMap) + Assert.False(resultValueMap) // reference keys let refMap = Map.ofSeq [for c in ["."; ".."; "..."; "...."] do yield (c, c.Length) ] let resultRefMap = Map.isEmpty refMap - Assert.IsFalse(resultRefMap) + Assert.False(resultRefMap) // One-element Map let oeleMap = Map.ofSeq [(1, "one")] let resultOele = Map.isEmpty oeleMap - Assert.IsFalse(resultOele) + Assert.False(resultOele) // empty Map let eptMap = Map.empty let resultEpt = Map.isEmpty eptMap - Assert.IsTrue(resultEpt) + Assert.True(resultEpt) () - [] + [] member this.Iter() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -348,7 +381,7 @@ type MapModule() = () - [] + [] member this.Map() = // value keys @@ -373,31 +406,31 @@ type MapModule() = () - [] + [] member this.Contains() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] let resultValueMap = Map.containsKey 2 valueKeyMap - Assert.IsTrue(resultValueMap) + Assert.True(resultValueMap) // reference keys let refMap = Map.ofSeq [for c in ["."; ".."; "..."; "...."] do yield (c, c.Length) ] let resultRefMap = Map.containsKey ".." refMap - Assert.IsTrue(resultRefMap) + Assert.True(resultRefMap) // One-element Map let oeleMap = Map.ofSeq [(1, "one")] let resultOele = Map.containsKey 1 oeleMap - Assert.IsTrue(resultOele) + Assert.True(resultOele) // empty Map let eptMap = Map.empty let resultEpt = Map.containsKey 3 eptMap - Assert.IsFalse(resultEpt) + Assert.False(resultEpt) () - [] + [] member this.Of_Array_Of_List_Of_Seq() = // value keys let valueKeyMapOfArr = Map.ofArray [|(2,"b"); (3,"c"); (4,"d"); (5,"e")|] @@ -428,7 +461,7 @@ type MapModule() = () - [] + [] member this.Partition() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -459,7 +492,7 @@ type MapModule() = () - [] + [] member this.Remove() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -490,7 +523,7 @@ type MapModule() = () - [] + [] member this.To_Array() = // value keys let valueKeyMapOfArr = Map.ofArray [|(1,1);(2,4);(3,9)|] @@ -514,7 +547,7 @@ type MapModule() = () - [] + [] member this.To_List() = // value keys let valueKeyMapOfArr = Map.ofList [(1,1);(2,4);(3,9)] @@ -539,7 +572,7 @@ type MapModule() = () - [] + [] member this.To_Seq() = // value keys let valueKeyMapOfArr = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -564,7 +597,7 @@ type MapModule() = () - [] + [] member this.TryFind() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -588,7 +621,7 @@ type MapModule() = () - [] + [] member this.TryFindIndex() = // value keys let valueKeyMap = Map.ofSeq [(2,"b"); (3,"c"); (4,"d"); (5,"e")] @@ -611,3 +644,39 @@ type MapModule() = Assert.AreEqual(resultEpt,None) () + + [] + member this.Keys() = + // reference keys + let m = Map.ofArray [| ("1", "1"); ("2", "4"); ("3", "9") |] + Assert.AreEqual(["1"; "2"; "3"], Map.keys m |> Seq.toList) + + // value keys + let m = Map.ofArray [| (1, 1); (2, 4); (3, 9) |] + Assert.AreEqual([1; 2; 3], Map.keys m |> Seq.toList) + + // one element + let m = Map.ofArray [| (1, 1); |] + Assert.AreEqual([1], Map.keys m |> Seq.toList) + + // empty + let m = Map.ofArray [| |] + Assert.AreEqual([], Map.keys m |> Seq.toList) + + [] + member this.Values() = + // reference keys + let m = Map.ofArray [| ("1", "2"); ("3", "4"); ("5", "6") |] + Assert.AreEqual(["2"; "4"; "6"], Map.values m |> Seq.toList) + + // value keys, out of order, including duplicates + let m = Map.ofArray [| (1, 2); (5, 6); (3, 4); (1, 2) |] + Assert.AreEqual([2; 4; 6], Map.values m |> Seq.toList) + + // one element + let m = Map.ofArray [| (1, 1); |] + Assert.AreEqual([1], Map.values m |> Seq.toList) + + // empty + let m = Map.ofArray [| |] + Assert.AreEqual([], Map.values m |> Seq.toList) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapType.fs index c0f85ccf28c..fd582c6f2e6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/MapType.fs @@ -3,13 +3,13 @@ // Various tests for the: // Microsoft.FSharp.Collections.Map type -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open System.Collections open System.Collections.Generic open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -21,21 +21,21 @@ Make sure each method works on: * Multi-element maps (2 - 7 elements) *) -[][][] + type MapType() = - + // Interfaces - [] - member this.IEnumerable() = + [] + member this.IEnumerable() = // Legit IE let ie = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IEnumerable let enum = ie.GetEnumerator() - + let testStepping() = CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) Assert.AreEqual(enum.MoveNext(), true) Assert.AreEqual(enum.Current, new KeyValuePair(1,1)) - + Assert.AreEqual(enum.MoveNext(), true) Assert.AreEqual(enum.Current, new KeyValuePair(2,4)) Assert.AreEqual(enum.MoveNext(), true) @@ -55,7 +55,7 @@ type MapType() = Assert.AreEqual(enum.MoveNext(), false) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IEnumerable_T() = // Legit IE let ie = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IEnumerable> @@ -86,13 +86,13 @@ type MapType() = CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IDictionary() = // Legit ID let id = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IDictionary<_,_> - Assert.IsTrue(id.ContainsKey(1)) - Assert.IsFalse(id.ContainsKey(5)) + Assert.True(id.ContainsKey(1)) + Assert.False(id.ContainsKey(5)) Assert.AreEqual(id.[1], 1) Assert.AreEqual(id.[3], 9) Assert.AreEqual(id.Keys, [| 1; 2; 3|]) @@ -101,48 +101,48 @@ type MapType() = CheckThrowsNotSupportedException(fun () -> id.[2] <-88) CheckThrowsNotSupportedException(fun () -> id.Add(new KeyValuePair(4,16))) - Assert.IsTrue(id.TryGetValue(1, ref 1)) - Assert.IsFalse(id.TryGetValue(100, ref 1)) + Assert.True(id.TryGetValue(1, ref 1)) + Assert.False(id.TryGetValue(100, ref 1)) CheckThrowsNotSupportedException(fun () -> id.Remove(1) |> ignore) // Empty ID let id = Map.empty :> IDictionary // Note no type args - Assert.IsFalse(id.ContainsKey(5)) + Assert.False(id.ContainsKey(5)) CheckThrowsKeyNotFoundException(fun () -> id.[1] |> ignore) Assert.AreEqual(id.Keys, [| |] ) Assert.AreEqual(id.Values, [| |] ) - [] + [] member this.IReadOnlyDictionary() = let irod = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IReadOnlyDictionary<_,_> - Assert.IsTrue(irod.ContainsKey(1)) - Assert.IsFalse(irod.ContainsKey(5)) + Assert.True(irod.ContainsKey(1)) + Assert.False(irod.ContainsKey(5)) Assert.AreEqual(irod.[1], 1) Assert.AreEqual(irod.[3], 9) Assert.AreEqual(irod.Keys, [| 1; 2; 3|]) Assert.AreEqual(irod.Values, [| 1; 4; 9|]) - Assert.IsTrue(irod.TryGetValue(1, ref 1)) - Assert.IsFalse(irod.TryGetValue(100, ref 1)) + Assert.True(irod.TryGetValue(1, ref 1)) + Assert.False(irod.TryGetValue(100, ref 1)) // Empty IROD let irod = Map.empty :> IReadOnlyDictionary // Note no type args - Assert.IsFalse(irod.ContainsKey(5)) + Assert.False(irod.ContainsKey(5)) CheckThrowsKeyNotFoundException(fun () -> irod.[1] |> ignore) Assert.AreEqual(irod.Keys, [| |] ) Assert.AreEqual(irod.Values, [| |] ) - [] + [] member this.ICollection() = // Legit IC let ic = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> ICollection> Assert.AreEqual(ic.Count, 3) - Assert.IsTrue(ic.Contains(new KeyValuePair(3,9))) + Assert.True(ic.Contains(new KeyValuePair(3,9))) let newArr = Array.create 5 (new KeyValuePair(3,9)) ic.CopyTo(newArr,0) - Assert.IsTrue(ic.IsReadOnly) + Assert.True(ic.IsReadOnly) // raise ReadOnlyCollection exception @@ -153,11 +153,11 @@ type MapType() = // Empty IC let ic = Map.empty :> ICollection> - Assert.IsFalse(ic.Contains(new KeyValuePair(3,9))) + Assert.False(ic.Contains(new KeyValuePair(3,9))) let newArr = Array.create 5 (new KeyValuePair(0,0)) ic.CopyTo(newArr,0) - [] + [] member this.IReadOnlyCollection() = // Legit IROC let iroc = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IReadOnlyCollection> @@ -169,7 +169,7 @@ type MapType() = Assert.AreEqual(iroc.Count, 0) - [] + [] member this.IComparable() = // Legit IC let ic = (Map.ofArray [|(1,1);(2,4);(3,9)|]) :> IComparable @@ -185,7 +185,7 @@ type MapType() = // Base class methods - [] + [] member this.ObjectGetHashCode() = // Works on empty maps let e = Map.ofList (List.empty) @@ -197,45 +197,45 @@ type MapType() = let y = Map.ofList [(2, -2.0M); (1, -1.0M)] Assert.AreEqual(x.GetHashCode(), y.GetHashCode()) - [] + [] member this.ObjectToString() = Assert.AreEqual("map [(1, 1); (2, 4); (3, 9)]", (Map.ofArray [|(1,1);(2,4);(3,9)|]).ToString()) Assert.AreEqual("map []", ([] |> Map.ofList).ToString()) Assert.AreEqual("map []", (([] :(decimal*decimal)list) |> Map.ofList).ToString()) - [] + [] member this.ObjectEquals() = // All three are different references, but equality has been // provided by the F# compiler. let a = [(1,1);(2,4);(3,9)] |> Map.ofList let b = (1,1) :: [(2,4);(3,9)] |> Map.ofList - Assert.IsTrue( (a = b) ) + Assert.True( (a = b) ) - Assert.IsTrue( a.Equals(b) ); Assert.IsTrue( b.Equals(a) ) + Assert.True( a.Equals(b) ); Assert.True( b.Equals(a) ) // Equality between types let a = ([] : (int*int) list) |> Map.ofList let b = ([] : (string*string) list ) |> Map.ofList - Assert.IsFalse( b.Equals(a) ) - Assert.IsFalse( a.Equals(b) ) + Assert.False( b.Equals(a) ) + Assert.False( a.Equals(b) ) // Co/contra variance not supported let a = ([] : (string*string) list) |> Map.ofList let b = ([] : (System.IComparable*System.IComparable) list) |> Map.ofList - Assert.IsFalse(a.Equals(b)) - Assert.IsFalse(b.Equals(a)) + Assert.False(a.Equals(b)) + Assert.False(b.Equals(a)) // Self equality let a = [(1,1)] |> Map.ofList - Assert.IsTrue( (a = a) ) - Assert.IsTrue(a.Equals(a)) + Assert.True( (a = a) ) + Assert.True(a.Equals(a)) // Null - Assert.IsFalse(a.Equals(null)) + Assert.False(a.Equals(null)) // Instance methods - [] + [] member this.New() = let newMap = new Map([|(1,1);(2,4);(3,9)|]) let b = newMap.Add(4,16) @@ -246,6 +246,7 @@ type MapType() = let ae = e.Add(1,"Monday") Assert.AreEqual(ae.[1], "Monday") + [] member this.Add() = let a = (Map.ofArray [|(1,1);(2,4);(3,9)|]) @@ -256,18 +257,46 @@ type MapType() = let e = Map.empty let ae = e.Add(1,"Monday") Assert.AreEqual(ae.[1], "Monday") + + [] + member this.Change() = + + let a = (Map.ofArray [|(1,1);(2,4);(3,9)|]) + let b = a.Change(4, fun current -> Assert.AreEqual(current, None); Some 16) + Assert.AreEqual(b.[1], 1) + Assert.AreEqual(b.[2], 4) + Assert.AreEqual(b.[3], 9) + Assert.AreEqual(b.[4], 16) + let c = b.Change(4, fun current -> Assert.AreEqual(current, Some 16); Some 25) + Assert.AreEqual(b.[1], 1) + Assert.AreEqual(b.[2], 4) + Assert.AreEqual(b.[3], 9) + Assert.AreEqual(c.[4], 25) + + let e = Map.empty + let ue = e.Change(1, fun current -> Assert.AreEqual(current, None); Some "Monday") + Assert.AreEqual(ue.[1], "Monday") + + let uo = ue.Change(1, fun current -> Assert.AreEqual(current, Some "Monday"); Some "Tuesday") + Assert.AreEqual(uo.[1], "Tuesday") + + let resultRm = c.Change(1, fun current -> Assert.AreEqual(current, Some 1); None) + Assert.False(resultRm.ContainsKey 1) + Assert.AreEqual(resultRm.[2], 4) + Assert.AreEqual(resultRm.[3], 9) + Assert.AreEqual(resultRm.[4], 25) - [] + [] member this.ContainsKey() = let a = (Map.ofArray [|(1,1);(2,4);(3,9)|]) - Assert.IsTrue(a.ContainsKey(3)) + Assert.True(a.ContainsKey(3)) let e = Map.empty - Assert.IsFalse(e.ContainsKey(3)) + Assert.False(e.ContainsKey(3)) - [] + [] member this.Count() = let a = (Map.ofArray [|(1,1);(2,4);(3,9)|]) @@ -276,16 +305,16 @@ type MapType() = let e = Map.empty Assert.AreEqual(e.Count, 0) - [] + [] member this.IsEmpty() = let l = (Map.ofArray [|(1,1);(2,4);(3,9)|]) - Assert.IsFalse(l.IsEmpty) + Assert.False(l.IsEmpty) let e = Map.empty - Assert.IsTrue(e.IsEmpty) + Assert.True(e.IsEmpty) - [] + [] member this.Item() = let mutable l = [(1,1)] |> Map.ofList @@ -304,7 +333,7 @@ type MapType() = CheckThrowsKeyNotFoundException(fun () -> l.[ -1 ] |> ignore) CheckThrowsKeyNotFoundException(fun () -> l.[1000] |> ignore) - [] + [] member this.Remove() = let l = (Map.ofArray [|(1,1);(2,4);(3,9)|]) @@ -316,7 +345,7 @@ type MapType() = let ae = e.Remove(2) Assert.AreEqual(ae.Count, 0) - [] + [] member this.TryFind() = let l = (Map.ofArray [|(1,1);(2,4);(3,9)|]) @@ -325,7 +354,34 @@ type MapType() = let e = Map.empty - Assert.AreEqual(e.TryFind(2), None) - + Assert.AreEqual(e.TryFind(2), None) + [] + member this.Keys() = + // Keys are ordered + let m = Map.ofArray [| ("3", "9"); ("2", "4"); ("1", "3") |] + Assert.AreEqual(["1"; "2"; "3"], m.Keys |> Seq.toList) + let m = Map.ofArray [| (1, 1); (2, 4); (3, 9) |] + Assert.AreEqual([1; 2; 3], m.Keys |> Seq.toList) + + let m = Map.ofArray [| |] + Assert.AreEqual([], m.Keys |> Seq.toList) + + let m = Map.ofArray [| (1, 1); |] + Assert.AreEqual([1], m.Keys |> Seq.toList) + + [] + member this.Values() = + // values are ordered by the key + let m = Map.ofArray [| ("3", "9"); ("2", "4"); ("1", "3") |] + Assert.AreEqual(["3"; "4"; "9"], m.Values |> Seq.toList) + + let m = Map.ofArray [| (1, 1); (2, 4); (3, 9) |] + Assert.AreEqual([1; 4; 9], m.Values |> Seq.toList) + + let m = Map.ofArray [| |] + Assert.AreEqual([], m.Values |> Seq.toList) + + let m = Map.ofArray [| (1, 1); |] + Assert.AreEqual([1], m.Values |> Seq.toList) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteListFunctions.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteListFunctions.fs index 2a8027f32f1..47c58233964 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteListFunctions.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteListFunctions.fs @@ -1,24 +1,23 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. #nowarn "44" // This construct is deprecated. please use List.item -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit -[][][] -type ObsoleteListFunctions() = - [] +type ObsoleteListFunctions() = + [] member this.Nth() = // integer List - let resultInt = List.nth [3;7;9;4;8;1;1;2] 3 + let resultInt = List.nth [3;7;9;4;8;1;1;2] 3 Assert.AreEqual(4, resultInt) - + // string List - let resultStr = List.nth ["a";"b";"c";"d"] 3 + let resultStr = List.nth ["a";"b";"c";"d"] 3 Assert.AreEqual("d", resultStr) - + // empty List CheckThrowsArgumentException ( fun() -> List.nth List.empty 1) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteSeqFunctions.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteSeqFunctions.fs index 3d57f01aac1..3b8727fc538 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteSeqFunctions.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ObsoleteSeqFunctions.fs @@ -1,40 +1,39 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. #nowarn "44" // This construct is deprecated. please use Seq.item -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx -[][][] type ObsoleteSeqFunctions() = - [] + [] member this.Nth() = - + // Negative index for i = -1 downto -10 do CheckThrowsArgumentException (fun () -> Seq.nth i { 10 .. 20 } |> ignore) - + // Out of range for i = 11 to 20 do CheckThrowsArgumentException (fun () -> Seq.nth i { 10 .. 20 } |> ignore) - + // integer Seq let resultInt = Seq.nth 3 { 10..20 } Assert.AreEqual(13, resultInt) - + // string Seq let resultStr = Seq.nth 3 (seq ["Lists"; "Are"; "nthString" ; "List" ]) Assert.AreEqual("List",resultStr) - + // empty Seq CheckThrowsArgumentException(fun () -> Seq.nth 0 (Seq.empty : seq) |> ignore) - + // null Seq let nullSeq:seq<'a> = null CheckThrowsArgumentNullException (fun () ->Seq.nth 3 nullSeq |> ignore) - + () \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule.fs index 5e0346b152d..b6ea2986447 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule.fs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx @@ -19,10 +19,9 @@ Make sure each method works on: * Null Seq (null) *) -[][][] type SeqModule() = - [] + [] member this.AllPairs() = // integer Seq @@ -49,7 +48,7 @@ type SeqModule() = CheckThrowsArgumentNullException(fun() -> Seq.allPairs (seq [1..7]) null |> ignore) () - [] + [] member this.CachedSeq_Clear() = let evaluatedItems : int list ref = ref [] @@ -89,7 +88,7 @@ type SeqModule() = Assert.AreEqual(List.length !evaluatedItems, 20) () - [] + [] member this.Append() = // empty Seq @@ -134,18 +133,18 @@ type SeqModule() = () - [] + [] member this.replicate() = // replicate should create multiple copies of the given value - Assert.IsTrue(Seq.isEmpty <| Seq.replicate 0 null) - Assert.IsTrue(Seq.isEmpty <| Seq.replicate 0 1) + Assert.True(Seq.isEmpty <| Seq.replicate 0 null) + Assert.True(Seq.isEmpty <| Seq.replicate 0 1) Assert.AreEqual(null, Seq.head <| Seq.replicate 1 null) Assert.AreEqual(["1";"1"],Seq.replicate 2 "1" |> Seq.toList) CheckThrowsArgumentException (fun () -> Seq.replicate -1 null |> ignore) - [] + [] member this.Average() = // empty Seq let emptySeq:seq = Seq.empty @@ -158,21 +157,21 @@ type SeqModule() = let averageDouble = Seq.average doubleSeq - Assert.IsFalse( averageDouble <> 2.5) + Assert.False( averageDouble <> 2.5) // float32 Seq let floatSeq:seq = seq [ 2.0f;4.4f;5.0f;8.6f] let averageFloat = Seq.average floatSeq - Assert.IsFalse( averageFloat <> 5.0f) + Assert.False( averageFloat <> 5.0f) // decimal Seq let decimalSeq:seq = seq [ 0M;19M;19.03M] let averageDecimal = Seq.average decimalSeq - Assert.IsFalse( averageDecimal <> 12.676666666666666666666666667M ) + Assert.False( averageDecimal <> 12.676666666666666666666666667M ) // null Seq let nullSeq:seq = null @@ -181,7 +180,7 @@ type SeqModule() = () - [] + [] member this.AverageBy() = // empty Seq let emptySeq:seq = Seq.empty @@ -193,21 +192,21 @@ type SeqModule() = let averageDouble = Seq.averageBy (fun x -> x-2.0) doubleSeq - Assert.IsFalse( averageDouble <> 0.5 ) + Assert.False( averageDouble <> 0.5 ) // float32 Seq let floatSeq:seq = seq [ 2.0f;4.4f;5.0f;8.6f] let averageFloat = Seq.averageBy (fun x -> x*3.3f) floatSeq - Assert.IsFalse( averageFloat <> 16.5f ) + Assert.False( averageFloat <> 16.5f ) // decimal Seq let decimalSeq:seq = seq [ 0M;19M;19.03M] let averageDecimal = Seq.averageBy (fun x -> x/10.7M) decimalSeq - Assert.IsFalse( averageDecimal <> 1.1847352024922118380062305296M ) + Assert.False( averageDecimal <> 1.1847352024922118380062305296M ) // null Seq let nullSeq:seq = null @@ -215,7 +214,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.averageBy (fun (x:double)->x+4.0) nullSeq |> ignore) () - [] + [] member this.Cache() = // empty Seq let emptySeq:seq = Seq.empty @@ -256,7 +255,7 @@ type SeqModule() = VerifySeqsEqual nullSeq cacheNull () - [] + [] member this.Case() = // integer Seq @@ -271,7 +270,7 @@ type SeqModule() = let stringArray = [|"a";"b"|] let stringSeq = Seq.cast stringArray - let expectedStringSeq = seq["a";"b"] + let expectedStringSeq = seq ["a";"b"] VerifySeqsEqual expectedStringSeq stringSeq @@ -303,7 +302,7 @@ type SeqModule() = () - [] + [] member this.Choose() = // int Seq @@ -342,7 +341,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.choose funcInt nullSeq |> ignore) () - [] + [] member this.ChunkBySize() = let verify expected actual = @@ -378,7 +377,7 @@ type SeqModule() = () - [] + [] member this.SplitInto() = let verify expected actual = @@ -409,7 +408,7 @@ type SeqModule() = () - [] + [] member this.Compare() = // int Seq @@ -418,7 +417,7 @@ type SeqModule() = let funcInt x y = if (x>y) then x else 0 let intcompared = Seq.compareWith funcInt intSeq1 intSeq2 - Assert.IsFalse( intcompared <> 7 ) + Assert.False( intcompared <> 7 ) // string Seq let stringSeq1 = seq ["a"; "b"] @@ -428,13 +427,13 @@ type SeqModule() = | "b", "d" -> 1 |_ -> -1 let strcompared = Seq.compareWith funcString stringSeq1 stringSeq2 - Assert.IsFalse( strcompared <> 1 ) + Assert.False( strcompared <> 1 ) // empty Seq let emptySeq = Seq.empty let emptycompared = Seq.compareWith funcInt emptySeq emptySeq - Assert.IsFalse( emptycompared <> 0 ) + Assert.False( emptycompared <> 0 ) // null Seq let nullSeq:seq = null @@ -445,7 +444,7 @@ type SeqModule() = () - [] + [] member this.Concat() = // integer Seq let seqInt = @@ -468,7 +467,7 @@ type SeqModule() = VerifySeqsEqual expectedStrSeq conStrSeq // Empty Seq - let emptySeqs = seq [seq[ Seq.empty;Seq.empty];seq[ Seq.empty;Seq.empty]] + let emptySeqs = seq [seq [ Seq.empty;Seq.empty];seq [ Seq.empty;Seq.empty]] let conEmptySeq = Seq.concat emptySeqs let expectedEmptySeq =seq { for i in 1..4 do yield Seq.empty} @@ -481,7 +480,7 @@ type SeqModule() = () - [] + [] member this.CountBy() = // integer Seq let funcIntCount_by (x:int) = x%3 @@ -515,7 +514,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.countBy funcIntCount_by nullSeq |> ignore) () - [] + [] member this.Distinct() = // integer Seq @@ -549,7 +548,7 @@ type SeqModule() = CheckThrowsArgumentNullException(fun () -> Seq.distinct nullSeq |> ignore) () - [] + [] member this.DistinctBy () = // integer Seq let funcInt x = x % 3 @@ -584,7 +583,7 @@ type SeqModule() = CheckThrowsArgumentNullException(fun () -> Seq.distinctBy funcInt nullSeq |> ignore) () - [] + [] member this.Except() = // integer Seq let intSeq1 = seq { yield! {1..100} @@ -623,7 +622,7 @@ type SeqModule() = () - [] + [] member this.Exists() = // Integer Seq @@ -634,7 +633,7 @@ type SeqModule() = let ifExistInt = Seq.exists funcInt IntexistsSeq - Assert.IsTrue( ifExistInt) + Assert.True( ifExistInt) // String Seq let funcStr (s:string) = s.Contains("key") @@ -642,13 +641,13 @@ type SeqModule() = let ifExistStr = Seq.exists funcStr strSeq - Assert.IsTrue( ifExistStr) + Assert.True( ifExistStr) // Empty Seq let emptySeq = Seq.empty let ifExistsEmpty = Seq.exists funcInt emptySeq - Assert.IsFalse( ifExistsEmpty) + Assert.False( ifExistsEmpty) @@ -658,7 +657,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.exists funcInt nullSeq |> ignore) () - [] + [] member this.Exists2() = // Integer Seq let funcInt x y = (x+y)%3=0 @@ -666,19 +665,19 @@ type SeqModule() = let Intexists2Seq2 = seq [1;6;3] let ifExist2Int = Seq.exists2 funcInt Intexists2Seq1 Intexists2Seq2 - Assert.IsTrue( ifExist2Int) + Assert.True( ifExist2Int) // String Seq let funcStr s1 s2 = ((s1 + s2) = "CombinedString") let strSeq1 = seq [ "Combined"; "Not Combined"] let strSeq2 = seq ["String"; "Other String"] let ifexists2Str = Seq.exists2 funcStr strSeq1 strSeq2 - Assert.IsTrue(ifexists2Str) + Assert.True(ifexists2Str) // Empty Seq let emptySeq = Seq.empty let ifexists2Empty = Seq.exists2 funcInt emptySeq emptySeq - Assert.IsFalse( ifexists2Empty) + Assert.False( ifexists2Empty) // null Seq let nullSeq:seq<'a> = null @@ -686,7 +685,7 @@ type SeqModule() = () - [] + [] member this.Filter() = // integer Seq let funcInt x = if (x % 5 = 0) then true else false @@ -725,7 +724,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.filter funcInt nullSeq |> ignore) () - [] + [] member this.Find() = // integer Seq @@ -754,7 +753,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.find funcInt nullSeq |> ignore) () - [] + [] member this.FindBack() = // integer Seq let funcInt x = x % 5 = 0 @@ -781,7 +780,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.findBack funcInt nullSeq |> ignore) () - [] + [] member this.FindIndex() = // integer Seq @@ -796,7 +795,7 @@ type SeqModule() = CheckThrowsArgumentNullException(fun() -> Seq.findIndex (fun i -> true) null |> ignore) () - [] + [] member this.Permute() = let mapIndex i = (i + 1) % 4 @@ -822,7 +821,7 @@ type SeqModule() = CheckThrowsArgumentException (fun () -> Seq.permute (fun _ -> 0) [0..9] |> Seq.iter ignore) () - [] + [] member this.FindIndexBack() = // integer Seq let digits = seq { 1..100 } @@ -842,7 +841,7 @@ type SeqModule() = CheckThrowsArgumentNullException(fun() -> Seq.findIndexBack (fun i -> true) null |> ignore) () - [] + [] member this.Pick() = let digits = [| 1 .. 10 |] |> Seq.ofArray @@ -856,7 +855,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.pick (fun i -> Some(i + 0)) null |> ignore) () - [] + [] member this.Fold() = let funcInt x y = x+y @@ -888,7 +887,7 @@ type SeqModule() = - [] + [] member this.Fold2() = Assert.AreEqual([(3,5); (2,3); (1,1)],Seq.fold2 (fun acc x y -> (x,y)::acc) [] (seq [ 1..3 ]) (seq [1..2..6])) @@ -920,7 +919,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.fold2 funcInt 0 (seq [1]) nullSeq |> ignore) () - [] + [] member this.FoldBack() = // int Seq let funcInt x y = x-y @@ -956,7 +955,7 @@ type SeqModule() = () - [] + [] member this.foldBack2() = // int Seq let funcInt x y z = x + y + z @@ -995,7 +994,7 @@ type SeqModule() = () - [] + [] member this.ForAll() = let funcInt x = if x%2 = 0 then true else false @@ -1026,7 +1025,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.forall funcInt nullSeq |> ignore) () - [] + [] member this.ForAll2() = let funcInt x y = if (x+y)%2 = 0 then true else false @@ -1057,7 +1056,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.forall2 funcInt nullSeq nullSeq |> ignore) - [] + [] member this.GroupBy() = let funcInt x = x%5 @@ -1100,7 +1099,7 @@ type SeqModule() = CheckThrowsArgumentNullException (fun () -> Seq.iter (fun _ -> ()) group_byNull) () - [] + [] member this.DisposalOfUnstartedEnumerator() = let run = ref false let f() = seq { @@ -1111,9 +1110,9 @@ type SeqModule() = } f().GetEnumerator().Dispose() - Assert.IsFalse(!run) + Assert.False(!run) - [] + [] member this.WeirdLocalNames() = let f pc = seq { @@ -1134,7 +1133,7 @@ type SeqModule() = let l = f 3 |> Seq.toList Assert.AreEqual([6;7;8], l) - [] + [] member this.Contains() = // Integer Seq @@ -1142,20 +1141,20 @@ type SeqModule() = let ifContainsInt = Seq.contains 5 intSeq - Assert.IsTrue(ifContainsInt) + Assert.True(ifContainsInt) // String Seq let strSeq = seq ["key"; "blank key"] let ifContainsStr = Seq.contains "key" strSeq - Assert.IsTrue(ifContainsStr) + Assert.True(ifContainsStr) // Empty Seq let emptySeq = Seq.empty let ifContainsEmpty = Seq.contains 5 emptySeq - Assert.IsFalse(ifContainsEmpty) + Assert.False(ifContainsEmpty) // null Seq let nullSeq:seq<'a> = null diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs index 289062f8a10..5b993364c13 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx @@ -15,32 +15,31 @@ type SeqWindowedTestInput<'t> = Exception : Type option } -[][][] type SeqModule2() = - [] + [] member this.Hd() = - + let IntSeq = seq { for i in 0 .. 9 do yield i } - + if Seq.head IntSeq <> 0 then Assert.Fail() - + // string Seq let strSeq = seq ["first"; "second"; "third"] if Seq.head strSeq <> "first" then Assert.Fail() - + // Empty Seq let emptySeq = Seq.empty CheckThrowsArgumentException ( fun() -> Seq.head emptySeq) - + // null Seq let nullSeq:seq<'a> = null CheckThrowsArgumentNullException (fun () ->Seq.head nullSeq) () - [] + [] member this.TryHead() = // int Seq let IntSeq = @@ -61,7 +60,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () ->Seq.head nullSeq) () - [] + [] member this.Tl() = // integer seq let resultInt = Seq.tail <| seq { 1..10 } @@ -79,7 +78,7 @@ type SeqModule2() = CheckThrowsArgumentException(fun () -> Seq.tail Seq.empty |> Seq.iter (fun _ -> failwith "Should not be reached")) () - [] + [] member this.Last() = let IntSeq = @@ -151,7 +150,7 @@ type SeqModule2() = () - [] + [] member this.TryLast() = let IntSeq = @@ -166,7 +165,7 @@ type SeqModule2() = // Empty Seq let emptyResult = Seq.tryLast Seq.empty - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) // null Seq let nullSeq:seq<'a> = null @@ -183,7 +182,7 @@ type SeqModule2() = // Empty Array let emptyResult = Seq.tryLast Array.empty - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) // null Array let nullArr:array = null @@ -201,7 +200,7 @@ type SeqModule2() = // Empty IList let emptyResult = Seq.tryLast (ResizeArray()) - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) // null IList let nullRarr:ResizeArray = null @@ -219,7 +218,7 @@ type SeqModule2() = // Empty list let emptylist: list = [] let emptyResult = Seq.tryLast emptylist - Assert.IsTrue(emptyResult.IsNone) + Assert.True(emptyResult.IsNone) // null list let nullList: list = Unchecked.defaultof> @@ -228,7 +227,7 @@ type SeqModule2() = - [] + [] member this.ExactlyOne() = let IntSeq = @@ -254,7 +253,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.exactlyOne nullSeq) () - [] + [] member this.TryExactlyOne() = let IntSeq = seq { for i in 7 .. 7 do @@ -279,7 +278,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.tryExactlyOne nullSeq |> ignore) () - [] + [] member this.Init() = let funcInt x = x @@ -304,7 +303,7 @@ type SeqModule2() = VerifySeqsEqual expectedNullSeq init_finiteNull () - [] + [] member this.InitInfinite() = let funcInt x = x @@ -322,32 +321,32 @@ type SeqModule2() = Assert.AreEqual("100",resultstr) - [] + [] member this.IsEmpty() = //seq int let seqint = seq [1;2;3] let is_emptyInt = Seq.isEmpty seqint - Assert.IsFalse(is_emptyInt) + Assert.False(is_emptyInt) //seq str - let seqStr = seq["first";"second"] + let seqStr = seq ["first";"second"] let is_emptyStr = Seq.isEmpty seqStr - Assert.IsFalse(is_emptyInt) + Assert.False(is_emptyInt) //seq empty let seqEmpty = Seq.empty let is_emptyEmpty = Seq.isEmpty seqEmpty - Assert.IsTrue(is_emptyEmpty) + Assert.True(is_emptyEmpty) //seq null let seqnull:seq<'a> = null CheckThrowsArgumentNullException (fun () -> Seq.isEmpty seqnull |> ignore) () - [] + [] member this.Iter() = //seq int let seqint = seq [ 1..3] @@ -376,7 +375,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.iter funcint nullseq |> ignore) () - [] + [] member this.Iter2() = //seq int @@ -406,7 +405,7 @@ type SeqModule2() = () - [] + [] member this.Iteri() = // seq int @@ -436,7 +435,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.iteri funcint nullseq |> ignore) () - [] + [] member this.Iteri2() = //seq int @@ -479,7 +478,7 @@ type SeqModule2() = () - [] + [] member this.Length() = // integer seq @@ -500,7 +499,7 @@ type SeqModule2() = () - [] + [] member this.Map() = // integer Seq @@ -531,7 +530,7 @@ type SeqModule2() = () - [] + [] member this.Map2() = // integer Seq let funcInt x y = x+y @@ -542,7 +541,7 @@ type SeqModule2() = // string Seq let funcStr (x:int) (y:string) = x+y.Length - let resultStr = Seq.map2 funcStr (seq[3;6;9;11]) (seq ["Lists"; "Are"; "Commonly" ; "List" ]) + let resultStr = Seq.map2 funcStr (seq [3;6;9;11]) (seq ["Lists"; "Are"; "Commonly" ; "List" ]) let expectedSeq = seq [8;9;17;15] VerifySeqsEqual expectedSeq resultStr @@ -558,7 +557,7 @@ type SeqModule2() = () - [] + [] member this.Map3() = // Integer seq let funcInt a b c = (a + b) * c @@ -590,7 +589,7 @@ type SeqModule2() = () - [] + [] member this.MapFold() = // integer Seq let funcInt acc x = if x % 2 = 0 then 10*x, acc + 1 else x, acc @@ -615,7 +614,7 @@ type SeqModule2() = () - [] + [] member this.MapFoldBack() = // integer Seq let funcInt x acc = if acc < 105 then 10*x, acc + 2 else x, acc @@ -680,37 +679,37 @@ type SeqModule2() = member private this.MapWithExceptionTester (map : (int -> int) -> seq -> seq) = let raiser x = if x > 0 then raise(NotSupportedException()) else x let e = (map raiser [0; 1]).GetEnumerator() - Assert.IsTrue(e.MoveNext()) // should not throw + Assert.True(e.MoveNext()) // should not throw Assert.AreEqual(0, e.Current) CheckThrowsNotSupportedException(fun _ -> e.MoveNext() |> ignore) Assert.AreEqual(0, e.Current) // should not throw - [] + [] member this.MapWithSideEffects () = this.MapWithSideEffectsTester Seq.map true - [] + [] member this.MapWithException () = this.MapWithExceptionTester Seq.map - [] + [] member this.SingletonCollectWithSideEffects () = this.MapWithSideEffectsTester (fun f-> Seq.collect (f >> Seq.singleton)) true - [] + [] member this.SingletonCollectWithException () = this.MapWithExceptionTester (fun f-> Seq.collect (f >> Seq.singleton)) - [] + [] member this.SystemLinqSelectWithSideEffects () = this.MapWithSideEffectsTester (fun f s -> System.Linq.Enumerable.Select(s, Func<_,_>(f))) false - [] + [] member this.SystemLinqSelectWithException () = this.MapWithExceptionTester (fun f s -> System.Linq.Enumerable.Select(s, Func<_,_>(f))) - [] + [] member this.MapiWithSideEffects () = let i = ref 0 let f _ x = i := !i + 1; x*x @@ -744,7 +743,7 @@ type SeqModule2() = if e.MoveNext() then Assert.Fail() Assert.AreEqual(0,!i) - [] + [] member this.Map2WithSideEffects () = let i = ref 0 let f x y = i := !i + 1; x*x @@ -778,7 +777,7 @@ type SeqModule2() = if e.MoveNext() then Assert.Fail() Assert.AreEqual(0,!i) - [] + [] member this.Mapi2WithSideEffects () = let i = ref 0 let f _ x y = i := !i + 1; x*x @@ -812,7 +811,7 @@ type SeqModule2() = if e.MoveNext() then Assert.Fail() Assert.AreEqual(0,!i) - [] + [] member this.Collect() = // integer Seq let funcInt x = seq [x+1] @@ -842,7 +841,7 @@ type SeqModule2() = () - [] + [] member this.Mapi() = // integer Seq @@ -871,7 +870,7 @@ type SeqModule2() = () - [] + [] member this.Mapi2() = // integer Seq let funcInt x y z = x+y+z @@ -882,7 +881,7 @@ type SeqModule2() = // string Seq let funcStr (x:int) (y:int) (z:string) = x+y+z.Length - let resultStr = Seq.mapi2 funcStr (seq[3;6;9;11]) (seq ["Lists"; "Are"; "Commonly" ; "List" ]) + let resultStr = Seq.mapi2 funcStr (seq [3;6;9;11]) (seq ["Lists"; "Are"; "Commonly" ; "List" ]) let expectedSeq = seq [8;10;19;18] VerifySeqsEqual expectedSeq resultStr @@ -907,7 +906,7 @@ type SeqModule2() = VerifySeqsEqual (seq [3;6;9;12;15;18;21;24;27;30]) (testSeqLengths shorterSeq longerSeq) VerifySeqsEqual (seq [3;6;9;12;15;18;21;24;27;30]) (testSeqLengths longerSeq shorterSeq) - [] + [] member this.Indexed() = // integer Seq @@ -932,7 +931,7 @@ type SeqModule2() = () - [] + [] member this.Max() = // integer Seq let resultInt = Seq.max { 10..20 } @@ -953,7 +952,7 @@ type SeqModule2() = () - [] + [] member this.MaxBy() = // integer Seq @@ -975,7 +974,7 @@ type SeqModule2() = () - [] + [] member this.MinBy() = // integer Seq @@ -998,7 +997,7 @@ type SeqModule2() = () - [] + [] member this.Min() = // integer Seq @@ -1018,7 +1017,7 @@ type SeqModule2() = () - [] + [] member this.Item() = // integer Seq let resultInt = Seq.item 3 { 10..20 } @@ -1043,7 +1042,7 @@ type SeqModule2() = for i = 11 to 20 do CheckThrowsArgumentException (fun () -> Seq.item i { 10 .. 20 } |> ignore) - [] + [] member this.``item should fail with correct number of missing elements``() = try Seq.item 0 (Array.zeroCreate 0) |> ignore @@ -1057,7 +1056,7 @@ type SeqModule2() = with | exn when exn.Message.Contains("seq was short by 3 elements") -> () - [] + [] member this.Of_Array() = // integer Seq let resultInt = Seq.ofArray [|1..10|] @@ -1076,7 +1075,7 @@ type SeqModule2() = () - [] + [] member this.Of_List() = // integer Seq let resultInt = Seq.ofList [1..10] @@ -1096,7 +1095,7 @@ type SeqModule2() = () - [] + [] member this.Pairwise() = // integer Seq let resultInt = Seq.pairwise {1..3} @@ -1116,7 +1115,7 @@ type SeqModule2() = () - [] + [] member this.Reduce() = // integer Seq @@ -1135,7 +1134,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length)) nullSeq |> ignore) () - [] + [] member this.ReduceBack() = // int Seq let funcInt x y = x - y @@ -1164,15 +1163,15 @@ type SeqModule2() = () - [] + [] member this.Rev() = // integer Seq let resultInt = Seq.rev (seq [5;4;3;2;1]) - VerifySeqsEqual (seq[1;2;3;4;5]) resultInt + VerifySeqsEqual (seq [1;2;3;4;5]) resultInt // string Seq let resultStr = Seq.rev (seq ["A"; "B"; "C" ; "D" ]) - VerifySeqsEqual (seq["D";"C";"B";"A"]) resultStr + VerifySeqsEqual (seq ["D";"C";"B";"A"]) resultStr // empty Seq VerifySeqsEqual Seq.empty (Seq.rev Seq.empty) @@ -1182,7 +1181,7 @@ type SeqModule2() = CheckThrowsArgumentNullException (fun () -> Seq.rev nullSeq |> ignore) () - [] + [] member this.Scan() = // integer Seq let funcInt x y = x+y @@ -1207,7 +1206,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.scan funcInt 5 seqNull |> ignore) () - [] + [] member this.ScanBack() = // integer Seq let funcInt x y = x+y @@ -1247,7 +1246,7 @@ type SeqModule2() = () - [] + [] member this.Singleton() = // integer Seq let resultInt = Seq.singleton 1 @@ -1267,7 +1266,7 @@ type SeqModule2() = () - [] + [] member this.Skip() = // integer Seq @@ -1289,7 +1288,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.skip 1 null |> ignore) () - [] + [] member this.Skip_While() = // integer Seq @@ -1312,7 +1311,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.skipWhile funcInt null |> ignore) () - [] + [] member this.Sort() = // integer Seq @@ -1334,7 +1333,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.sort null |> ignore) () - [] + [] member this.SortBy() = // integer Seq @@ -1358,7 +1357,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.sortBy funcInt null |> ignore) () - [] + [] member this.SortDescending() = // integer Seq @@ -1381,9 +1380,9 @@ type SeqModule2() = VerifySeqsEqual resultEpt Seq.empty // tuple Seq - let tupSeq = (seq[(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) + let tupSeq = (seq [(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) let resultTup = Seq.sortDescending tupSeq - let expectedTup = (seq[(2,"x");(2,"b");(2,"a");(1,"x");(1,"d");(1,"b");(1,"a")]) + let expectedTup = (seq [(2,"x");(2,"b");(2,"a");(1,"x");(1,"d");(1,"b");(1,"a")]) VerifySeqsEqual expectedTup resultTup // float Seq @@ -1397,7 +1396,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.sort null |> ignore) () - [] + [] member this.SortByDescending() = // integer Seq @@ -1418,9 +1417,9 @@ type SeqModule2() = VerifySeqsEqual resultEpt Seq.empty // tuple Seq - let tupSeq = (seq[(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) + let tupSeq = (seq [(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) let resultTup = Seq.sortByDescending snd tupSeq - let expectedTup = (seq[(2,"x");(1,"x");(1,"d");(1,"b");(2,"b");(2,"a");(1,"a")]) + let expectedTup = (seq [(2,"x");(1,"x");(1,"d");(1,"b");(2,"b");(2,"a");(1,"a")]) VerifySeqsEqual expectedTup resultTup // float Seq @@ -1456,7 +1455,7 @@ type SeqModule2() = () - [] + [] member this.Sum() = // integer Seq @@ -1496,7 +1495,7 @@ type SeqModule2() = () - [] + [] member this.SumBy() = // integer Seq @@ -1535,7 +1534,7 @@ type SeqModule2() = () - [] + [] member this.Take() = // integer Seq @@ -1561,7 +1560,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.take 1 null |> ignore) () - [] + [] member this.takeWhile() = // integer Seq let funcInt x = (x < 6) @@ -1585,7 +1584,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.takeWhile funcInt null |> ignore) () - [] + [] member this.ToArray() = // integer Seq let resultInt = Seq.toArray(seq [1;2;4;5;7]) @@ -1607,32 +1606,32 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.toArray null |> ignore) () - [] + [] member this.ToArrayFromICollection() = let inputCollection = ResizeArray(seq [1;2;4;5;7]) let resultInt = Seq.toArray(inputCollection) let expectedInt = [|1;2;4;5;7|] Assert.AreEqual(expectedInt,resultInt) - [] + [] member this.ToArrayEmptyInput() = let resultInt = Seq.toArray(Seq.empty) let expectedInt = Array.empty Assert.AreEqual(expectedInt,resultInt) - [] + [] member this.ToArrayFromArray() = let resultInt = Seq.toArray([|1;2;4;5;7|]) let expectedInt = [|1;2;4;5;7|] Assert.AreEqual(expectedInt,resultInt) - [] + [] member this.ToArrayFromList() = let resultInt = Seq.toArray([1;2;4;5;7]) let expectedInt = [|1;2;4;5;7|] Assert.AreEqual(expectedInt,resultInt) - [] + [] member this.ToList() = // integer Seq let resultInt = Seq.toList (seq [1;2;4;5;7]) @@ -1652,7 +1651,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.toList null |> ignore) () - [] + [] member this.Transpose() = // integer seq VerifySeqsEqual [seq [1; 4]; seq [2; 5]; seq [3; 6]] <| Seq.transpose (seq [seq {1..3}; seq {4..6}]) @@ -1677,7 +1676,7 @@ type SeqModule2() = VerifySeqsEqual [seq ["a";"c"]; seq ["b";"d"]] <| Seq.transpose [["a";"b"]; ["c";"d"]] VerifySeqsEqual [seq ["a";"c"]; seq ["b";"d"]] <| Seq.transpose (seq { yield ["a";"b"]; yield ["c";"d"] }) - [] + [] member this.Truncate() = // integer Seq let resultInt = Seq.truncate 3 (seq [1;2;4;5;7]) @@ -1702,7 +1701,7 @@ type SeqModule2() = () - [] + [] member this.tryFind() = // integer Seq let resultInt = Seq.tryFind (fun x -> (x%2=0)) (seq [1;2;4;5;7]) @@ -1729,7 +1728,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.tryFind (fun x -> (x%2=0)) null |> ignore) () - [] + [] member this.TryFindBack() = // integer Seq let resultInt = Seq.tryFindBack (fun x -> (x%2=0)) (seq [1;2;4;5;7]) @@ -1755,7 +1754,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.tryFindBack (fun x -> (x%2=0)) null |> ignore) () - [] + [] member this.TryFindIndex() = // integer Seq @@ -1783,7 +1782,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.tryFindIndex (fun x -> (x % 2 = 0)) null |> ignore) () - [] + [] member this.TryFindIndexBack() = // integer Seq @@ -1810,7 +1809,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.tryFindIndexBack (fun x -> (x % 2 = 0)) null |> ignore) () - [] + [] member this.Unfold() = // integer Seq @@ -1824,7 +1823,7 @@ type SeqModule2() = () - [] + [] member this.Windowed() = let testWindowed config = @@ -1888,7 +1887,7 @@ type SeqModule2() = () - [] + [] member this.Zip() = // integer Seq @@ -1913,7 +1912,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.zip (seq [1..7]) null |> ignore) () - [] + [] member this.Zip3() = // integer Seq let resultInt = Seq.zip3 (seq [1..7]) (seq [11..17]) (seq [21..27]) @@ -1938,7 +1937,7 @@ type SeqModule2() = CheckThrowsArgumentNullException(fun() -> Seq.zip3 (seq [1..7]) (seq [1..7]) null |> ignore) () - [] + [] member this.tryPick() = // integer Seq let resultInt = Seq.tryPick (fun x-> if x = 1 then Some("got") else None) (seq [1..5]) @@ -1951,7 +1950,7 @@ type SeqModule2() = // empty Seq let resultEpt = Seq.tryPick (fun x-> if x = 1 then Some("got") else None) Seq.empty - Assert.IsNull(resultEpt) + Assert.Null(resultEpt) // null Seq let nullSeq : seq<'a> = null @@ -1961,7 +1960,7 @@ type SeqModule2() = () - [] + [] member this.tryItem() = // integer Seq let resultInt = Seq.tryItem 3 { 10..20 } @@ -1986,3 +1985,88 @@ type SeqModule2() = // Index greater than length let resultIndexGreater = Seq.tryItem 31 { 10..20 } Assert.AreEqual(None, resultIndexGreater) + + [] + member this.RemoveAt() = + // integer list + Assert.AreEqual([2; 3; 4; 5], (Seq.removeAt 0 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 4; 5], (Seq.removeAt 2 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 3; 4], (Seq.removeAt 4 [1..5] |> Seq.toList)) + + //string list + Assert.AreEqual(["2"; "3"; "4"; "5"], (Seq.removeAt 0 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "4"; "5"], (Seq.removeAt 2 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "3"; "4"], (Seq.removeAt 4 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Seq.removeAt 0 [] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.removeAt -1 [1] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.removeAt 2 [1] |> Seq.toList |> ignore) + + [] + member this.RemoveManyAt() = + // integer list + Assert.AreEqual([3; 4; 5], (Seq.removeManyAt 0 2 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 5], (Seq.removeManyAt 2 2 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 3], (Seq.removeManyAt 3 2 [1..5] |> Seq.toList)) + + //string list + Assert.AreEqual(["3"; "4"; "5"], (Seq.removeManyAt 0 2 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "5"], (Seq.removeManyAt 2 2 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "3"], (Seq.removeManyAt 3 2 ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Seq.removeManyAt 0 2 [] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.removeManyAt -1 2 [1] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.removeManyAt 2 2 [1] |> Seq.toList |> ignore) + + [] + member this.UpdateAt() = + // integer list + Assert.AreEqual([0; 2; 3; 4; 5], (Seq.updateAt 0 0 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 0; 4; 5], (Seq.updateAt 2 0 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 3; 4; 0], (Seq.updateAt 4 0 [1..5] |> Seq.toList)) + + //string list + Assert.AreEqual(["0"; "2"; "3"; "4"; "5"], (Seq.updateAt 0 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "0"; "4"; "5"], (Seq.updateAt 2 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"], (Seq.updateAt 4 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + + // empty list & out of bounds + CheckThrowsArgumentException (fun () -> Seq.updateAt 0 0 [] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.updateAt -1 0 [1] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.updateAt 2 0 [1] |> Seq.toList |> ignore) + + [] + member this.InsertAt() = + // integer list + Assert.AreEqual([0; 1; 2; 3; 4; 5], (Seq.insertAt 0 0 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 0; 3; 4; 5], (Seq.insertAt 2 0 [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 3; 4; 0; 5], (Seq.insertAt 4 0 [1..5] |> Seq.toList)) + + //string list + Assert.AreEqual(["0"; "1"; "2"; "3"; "4"; "5"], (List.insertAt 0 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "0"; "3"; "4"; "5"], (List.insertAt 2 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"; "5"], (List.insertAt 4 "0" ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + + // empty list & out of bounds + Assert.AreEqual([0], Seq.insertAt 0 0 [] |> Seq.toList) + CheckThrowsArgumentException (fun () -> Seq.insertAt -1 0 [1] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.insertAt 2 0 [1] |> Seq.toList |> ignore) + + [] + member this.InsertManyAt() = + // integer list + Assert.AreEqual([0; 0; 1; 2; 3; 4; 5], (Seq.insertManyAt 0 [0; 0] [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 0; 0; 3; 4; 5], (Seq.insertManyAt 2 [0; 0] [1..5] |> Seq.toList)) + Assert.AreEqual([1; 2; 3; 4; 0; 0; 5], (Seq.insertManyAt 4 [0; 0] [1..5] |> Seq.toList)) + + //string list + Assert.AreEqual(["0"; "0"; "1"; "2"; "3"; "4"; "5"], (Seq.insertManyAt 0 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "0"; "0"; "3"; "4"; "5"], (Seq.insertManyAt 2 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + Assert.AreEqual(["1"; "2"; "3"; "4"; "0"; "0"; "5"], (Seq.insertManyAt 4 ["0"; "0"] ["1"; "2"; "3"; "4"; "5"] |> Seq.toList)) + + // empty list & out of bounds + Assert.AreEqual([0; 0], Seq.insertManyAt 0 [0; 0] [] |> Seq.toList) + CheckThrowsArgumentException (fun () -> Seq.insertManyAt -1 [0; 0] [1] |> Seq.toList |> ignore) + CheckThrowsArgumentException (fun () -> Seq.insertManyAt 2 [0; 0] [1] |> Seq.toList |> ignore) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqMultipleIteration.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqMultipleIteration.fs index cc53b254676..906e5dab9de 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqMultipleIteration.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqMultipleIteration.fs @@ -1,8 +1,8 @@ -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections + +open Xunit -open NUnit.Framework -[] module SeqMultipleIteration = let makeNewSeq () = let haveCalled = false |> ref @@ -12,36 +12,36 @@ module SeqMultipleIteration = yield 3 }, haveCalled - [] + [] let ``Seq.distinct only evaluates the seq once`` () = let s, haveCalled = makeNewSeq () let distincts = Seq.distinct s - Assert.IsFalse !haveCalled + Assert.False !haveCalled CollectionAssert.AreEqual (distincts |> Seq.toList, [3]) - Assert.IsTrue !haveCalled + Assert.True !haveCalled - [] + [] let ``Seq.distinctBy only evaluates the seq once`` () = let s, haveCalled = makeNewSeq () let distincts = Seq.distinctBy id s - Assert.IsFalse !haveCalled + Assert.False !haveCalled CollectionAssert.AreEqual (distincts |> Seq.toList, [3]) - Assert.IsTrue !haveCalled + Assert.True !haveCalled - [] + [] let ``Seq.groupBy only evaluates the seq once`` () = let s, haveCalled = makeNewSeq () let groups : seq> = Seq.groupBy id s - Assert.IsFalse !haveCalled + Assert.False !haveCalled let groups : list> = Seq.toList groups // Seq.groupBy iterates the entire sequence as soon as it begins iteration. - Assert.IsTrue !haveCalled + Assert.True !haveCalled - [] + [] let ``Seq.countBy only evaluates the seq once`` () = let s, haveCalled = makeNewSeq () let counts : seq = Seq.countBy id s - Assert.IsFalse !haveCalled + Assert.False !haveCalled let counts : list = Seq.toList counts - Assert.IsTrue !haveCalled + Assert.True !haveCalled CollectionAssert.AreEqual (counts |> Seq.toList, [(3, 1)]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqProperties.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqProperties.fs index d962b6e3393..41bad16fac6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqProperties.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqProperties.fs @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -[][] -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.SeqProperties +module FSharp.Core.UnitTests.Collections.SeqProperties open System open System.Collections.Generic -open NUnit.Framework +open Xunit open FsCheck open Utils @@ -13,7 +12,7 @@ let sortByStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> Seq.sortBy snd isStable sorted -[] +[] let ``Seq.sortBy is stable`` () = Check.QuickThrowOnFailure sortByStable Check.QuickThrowOnFailure sortByStable @@ -23,7 +22,7 @@ let sortWithStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> Seq.sortWith (fun x y -> compare (snd x) (snd y)) isStable sorted -[] +[] let ``Seq.sortWithStable is stable`` () = Check.QuickThrowOnFailure sortWithStable Check.QuickThrowOnFailure sortWithStable @@ -33,7 +32,7 @@ let distinctByStable<'a when 'a : comparison> (xs : 'a []) = let sorted = indexed |> Seq.distinctBy snd isStable sorted -[] +[] let ``Seq.distinctBy is stable`` () = Check.QuickThrowOnFailure distinctByStable Check.QuickThrowOnFailure distinctByStable diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetModule.fs index 00b8b103ef0..4011d63a52f 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Collections.Set module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -17,10 +17,9 @@ Make sure each method works on: * Sets with 4 more more elements *) -[][][] type SetModule() = - [] + [] member this.Empty() = let emptySet = Set.empty if Set.count emptySet <> 0 then Assert.Fail() @@ -29,16 +28,16 @@ type SetModule() = let d : Set = Set.empty () - [] + [] member this.Singleton() = let intSingleton = Set.singleton 5 - Assert.IsTrue(intSingleton.Count = 1) - Assert.IsTrue(intSingleton.Contains(5)) + Assert.True(intSingleton.Count = 1) + Assert.True(intSingleton.Contains(5)) let stringSingleton = Set.singleton (null) - Assert.IsFalse(stringSingleton.Contains("")) + Assert.False(stringSingleton.Contains("")) - [] + [] member this.Add() = let empty = Set.empty let x = Set.add 'x' empty @@ -46,11 +45,11 @@ type SetModule() = let xyz = Set.add 'z' xy let wxyz = Set.add 'w' xyz - Assert.IsTrue(Set.count xy = 2) - Assert.IsTrue(Set.count xyz = 3) - Assert.IsTrue(Set.count wxyz = 4) + Assert.True(Set.count xy = 2) + Assert.True(Set.count xyz = 3) + Assert.True(Set.count wxyz = 4) - [] + [] member this.Contains() = // Empty set searching for null = false if Set.contains null (Set.empty) <> false then Assert.Fail() @@ -63,7 +62,7 @@ type SetModule() = if Set.contains 6 odds <> false then Assert.Fail() () - [] + [] member this.Count() = let empty = Set.empty if Set.count empty <> 0 then Assert.Fail() @@ -75,7 +74,7 @@ type SetModule() = if Set.count multi <> 26 then Assert.Fail() () - [] + [] member this.Diff() = // Given a large set and removing 0, 1, x elements... let alphabet = new Set([| 'a' .. 'z' |]) @@ -108,7 +107,7 @@ type SetModule() = if (evensSansOdds = evens) <> true then Assert.Fail() () - [] + [] member this.Equal() = let emptySet1 : Set = Set.empty let emptySet2 : Set = Set.empty @@ -123,7 +122,7 @@ type SetModule() = if (a = b) <> true then Assert.Fail() () - [] + [] member this.Compare() = // Comparing empty sets let emptyString1 = Set.empty : Set @@ -151,7 +150,7 @@ type SetModule() = if compare alphabet noVowelAlpa <> -1 then Assert.Fail() () - [] + [] member this.Exists() = let emptyInt = Set.empty : Set @@ -166,7 +165,7 @@ type SetModule() = if Set.exists (fun (text, num) -> text = "four") letNumPairs <> false then Assert.Fail() () - [] + [] member this.Filter() = let emptyComplex = Set.empty : Set> * Set> @@ -185,7 +184,7 @@ type SetModule() = () - [] + [] member this.Map() = let emptySet : Set = Set.empty @@ -198,7 +197,7 @@ type SetModule() = if Set.exists (fun c -> c = Char.ToLower(c)) capped then Assert.Fail() () - [] + [] member this.Fold() = let emptySet : Set = Set.empty @@ -216,7 +215,7 @@ type SetModule() = if !callOrder <> [(10, 5); (6, 4); (3, 3); (1, 2); (0, 1)] then Assert.Fail() () - [] + [] member this.FoldBack() = let emptySet : Set = Set.empty @@ -234,7 +233,7 @@ type SetModule() = if !callOrder <> [(14, 1); (12, 2); (9, 3); (5, 4); (0, 5)] then Assert.Fail() () - [] + [] member this.ForAll() = let emptySet : Set = Set.empty @@ -243,14 +242,14 @@ type SetModule() = let seta = new Set<_>( [1 .. 99] |> List.map (fun i -> i.ToString()) ) let result = seta |> Set.forall (fun str -> str.Length < 3) - Assert.IsTrue(result) + Assert.True(result) let setb = new Set<_>( [50 .. 150] |> List.map (fun i -> i.ToString()) ) let result = setb |> Set.forall (fun str -> str.Length < 3) - Assert.IsFalse(result) + Assert.False(result) () - [] + [] member this.Intersect() = let emptySet1 : Set = Set.empty @@ -258,26 +257,26 @@ type SetModule() = let four = Set.singleton 4 let emptyInterEmpty = Set.intersect emptySet1 emptySet2 - Assert.IsTrue( (emptyInterEmpty = emptySet1) ) + Assert.True( (emptyInterEmpty = emptySet1) ) let xInterEmpty = Set.intersect four emptySet1 - Assert.IsFalse( (four = xInterEmpty) ) + Assert.False( (four = xInterEmpty) ) let emptyInterX = Set.intersect emptySet1 four - Assert.IsFalse( (four = emptyInterX) ) + Assert.False( (four = emptyInterX) ) () - [] + [] member this.Intersect2() = let a = new Set([3; 4; 5; 6]) let b = new Set([5; 6; 7; 8]) let intersection = Set.intersect a b let expectedResult = new Set([5; 6]) - Assert.IsTrue( (intersection = expectedResult) ) + Assert.True( (intersection = expectedResult) ) - [] + [] member this.IntersectMany() = (* IntersectAll 1234567 @@ -293,61 +292,61 @@ type SetModule() = ] let result = Set.intersectMany setsToIntersect - Assert.IsTrue(result.Count = 2) + Assert.True(result.Count = 2) let contains x s = s |> Set.exists (fun i -> i = x) - Assert.IsTrue(contains 6 result) - Assert.IsTrue(contains 7 result) + Assert.True(contains 6 result) + Assert.True(contains 7 result) - [] + [] member this.IntersectMany2() = let all = new Set<_>([1 .. 10]) let odds = new Set<_>([1 .. 2 .. 10]) let evens = new Set<_>([2 .. 2 .. 10]) let result = Set.intersectMany [odds; evens; all] - Assert.IsTrue(Set.count result = 0) + Assert.True(Set.count result = 0) - [] + [] member this.IntersectMany3() = let all = new Set<_>([1 .. 10]) let empty = Set.empty : Set let result = Set.intersectMany [all; empty; all] - Assert.IsTrue(Set.count result = 0) + Assert.True(Set.count result = 0) - [] + [] member this.IntersectMany4() = CheckThrowsArgumentException (fun () -> Set.intersectMany (Seq.empty : seq>) |> ignore) () - [] + [] member this.Union() = let emptySet1 : Set = Set.empty let emptySet2 : Set = Set.empty let four = Set.singleton 4 let emptyUnionEmpty = Set.union emptySet1 emptySet2 - Assert.IsTrue( (emptyUnionEmpty = emptySet1) ) + Assert.True( (emptyUnionEmpty = emptySet1) ) let xUnionEmpty = Set.union four emptySet1 - Assert.IsTrue( (four = xUnionEmpty) ) + Assert.True( (four = xUnionEmpty) ) let emptyUnionX = Set.union emptySet1 four - Assert.IsTrue( (four = emptyUnionX) ) + Assert.True( (four = emptyUnionX) ) () - [] + [] member this.Union2() = let a = new Set([1; 2; 3; 4]) let b = new Set([5; 6; 7; 8]) let union = Set.union a b let expectedResult = new Set([1 .. 8]) - Assert.IsTrue( (union = expectedResult) ) + Assert.True( (union = expectedResult) ) - [] + [] member this.Union3() = let x = Set.singleton 1 @@ -355,9 +354,9 @@ type SetModule() = |> Set.union (Set.singleton 1) |> Set.union (Set.singleton 1) - Assert.IsTrue(x.Count = 1) + Assert.True(x.Count = 1) - [] + [] member this.UnionMany() = let odds = new Set([1 .. 2 .. 10]) let evens = new Set([2 .. 2 .. 10]) @@ -366,27 +365,27 @@ type SetModule() = let zero = Set.singleton 0 let result = Set.unionMany [odds; evens; empty; rest; zero] - Assert.IsTrue(result.Count = 20) + Assert.True(result.Count = 20) - [] + [] member this.UnionMany2() = let result = Set.unionMany (Seq.empty : seq>) - Assert.IsTrue(result.Count = 0) + Assert.True(result.Count = 0) - [] + [] member this.IsEmpty() = let zero = Set.empty : Set let zero2 = new Set([]) let one = Set.singleton "foo" let n = new Set<_>( [1 .. 10] ) - Assert.IsTrue(Set.isEmpty zero) - Assert.IsTrue(Set.isEmpty zero2) + Assert.True(Set.isEmpty zero) + Assert.True(Set.isEmpty zero2) - Assert.IsFalse(Set.isEmpty one) - Assert.IsFalse(Set.isEmpty n) + Assert.False(Set.isEmpty one) + Assert.False(Set.isEmpty n) - [] + [] member this.Iter() = // Empty set @@ -399,23 +398,23 @@ type SetModule() = Set.iter (fun c -> let i = int c - int '0' elements.[i] <- true) set - Assert.IsTrue (Array.forall ( (=) true ) elements) + Assert.True (Array.forall ( (=) true ) elements) - [] + [] member this.Parition() = // Empty let resulta, resultb = Set.partition (fun (x : int) -> Assert.Fail(); false) Set.empty - Assert.IsTrue(resulta.Count = 0 && resultb.Count = 0) + Assert.True(resulta.Count = 0 && resultb.Count = 0) // One let single = Set.singleton "foo" let resulta, resultb = Set.partition (fun (str : string) -> str.Length <> 3) single - Assert.IsTrue(resulta.Count = 0 && resultb.Count = 1) + Assert.True(resulta.Count = 0 && resultb.Count = 1) let resulta, resultb = Set.partition (fun (str : string) -> str.Length = 3) single - Assert.IsTrue(resulta.Count = 1 && resultb.Count = 0) + Assert.True(resulta.Count = 1 && resultb.Count = 0) // Multi let alphabet = Set.ofList ['a' .. 'z'] @@ -423,140 +422,140 @@ type SetModule() = | _ -> false let resulta, resultb = Set.partition isVowel alphabet - Assert.IsTrue(resulta.Count = 5 && resultb.Count = 21) + Assert.True(resulta.Count = 5 && resultb.Count = 21) - [] + [] member this.Remove() = let emptySet : Set = Set.empty let result = Set.remove 42 emptySet - Assert.IsTrue(result.Count = 0) + Assert.True(result.Count = 0) // One let single = Set.singleton 100I let resulta = Set.remove 100I single let resultb = Set.remove 1I single - Assert.IsTrue (resulta.Count = 0) - Assert.IsTrue (resultb.Count = 1) + Assert.True (resulta.Count = 0) + Assert.True (resultb.Count = 1) // Multi let a = new Set([1 .. 5]) - Assert.IsTrue(a.Count = 5) + Assert.True(a.Count = 5) let b = Set.remove 3 a - Assert.IsTrue(b.Count = 4) + Assert.True(b.Count = 4) // Call again, double delete let c = Set.remove 3 b - Assert.IsTrue(c.Count = 4) + Assert.True(c.Count = 4) - Assert.IsFalse(Set.exists ( (=) 3 ) c) + Assert.False(Set.exists ( (=) 3 ) c) - [] + [] member this.Of_List() = // Empty let emptySet = Set.ofList ([] : (string * int * Set) list) - Assert.IsTrue(Set.isEmpty emptySet) + Assert.True(Set.isEmpty emptySet) // Single let single = Set.ofList [1] - Assert.IsTrue(single.Count = 1) - Assert.IsTrue(Set.exists ( (=) 1 ) single) + Assert.True(single.Count = 1) + Assert.True(Set.exists ( (=) 1 ) single) // Multi let multi = Set.ofList ["mon"; "tue"; "wed"; "thu"; "fri"] - Assert.IsTrue(multi.Count = 5) + Assert.True(multi.Count = 5) let expected = new Set<_>(["mon"; "tue"; "wed"; "thu"; "fri"]) - Assert.IsTrue( (multi = expected) ) + Assert.True( (multi = expected) ) - [] + [] member this.To_List() = // Empty let emptySet : Set = Set.empty - Assert.IsTrue(Set.toList emptySet = []) + Assert.True(Set.toList emptySet = []) // Single let single = Set.singleton "stuff" - Assert.IsTrue(Set.toList single = ["stuff"]) + Assert.True(Set.toList single = ["stuff"]) // Multi let multi = new Set<_>([5; 2; 3; 1; 4]) - Assert.IsTrue(Set.toList multi = [1; 2; 3; 4; 5]) + Assert.True(Set.toList multi = [1; 2; 3; 4; 5]) - [] + [] member this.Of_Array() = // Empty let emptySet = Set.ofArray ([| |] : (string * int * Set) []) - Assert.IsTrue(Set.isEmpty emptySet) + Assert.True(Set.isEmpty emptySet) // Single let single = Set.ofArray [| 1 |] - Assert.IsTrue(single.Count = 1) - Assert.IsTrue(Set.exists ( (=) 1 ) single) + Assert.True(single.Count = 1) + Assert.True(Set.exists ( (=) 1 ) single) // Multi let multi = Set.ofArray [| "mon"; "tue"; "wed"; "thu"; "fri" |] - Assert.IsTrue(multi.Count = 5) + Assert.True(multi.Count = 5) let expected = new Set<_>(["mon"; "tue"; "wed"; "thu"; "fri"]) - Assert.IsTrue( (multi = expected) ) + Assert.True( (multi = expected) ) - [] + [] member this.To_Array() = // Empty let emptySet : Set = Set.empty - Assert.IsTrue(Set.toArray emptySet = [| |]) + Assert.True(Set.toArray emptySet = [| |]) // Single let single = Set.singleton "stuff" - Assert.IsTrue(Set.toArray single = [| "stuff" |]) + Assert.True(Set.toArray single = [| "stuff" |]) // Multi let multi = new Set<_>([5; 2; 3; 1; 4]) - Assert.IsTrue(Set.toArray multi = [| 1; 2; 3; 4; 5 |]) + Assert.True(Set.toArray multi = [| 1; 2; 3; 4; 5 |]) - [] + [] member this.Of_Seq() = // Empty let emptySet = Set.ofSeq ([| |] : (string * int * Set) []) - Assert.IsTrue(Set.isEmpty emptySet) + Assert.True(Set.isEmpty emptySet) // Single let single = Set.ofSeq [ 1 ] - Assert.IsTrue(single.Count = 1) - Assert.IsTrue(Set.exists ( (=) 1 ) single) + Assert.True(single.Count = 1) + Assert.True(Set.exists ( (=) 1 ) single) // Multi let multi = Set.ofSeq [| "mon"; "tue"; "wed"; "thu"; "fri" |] - Assert.IsTrue(multi.Count = 5) + Assert.True(multi.Count = 5) let expected = new Set<_>(["mon"; "tue"; "wed"; "thu"; "fri"]) - Assert.IsTrue( (multi = expected) ) + Assert.True( (multi = expected) ) - [] + [] member this.To_Seq() = // Empty let emptySet : Set = Set.empty let emptySeq = Set.toSeq emptySet - Assert.IsTrue (Seq.length emptySeq = 0) + Assert.True (Seq.length emptySeq = 0) // Single let single = Set.singleton "stuff" let singleSeq = Set.toSeq single - Assert.IsTrue(Seq.toList singleSeq = [ "stuff" ]) + Assert.True(Seq.toList singleSeq = [ "stuff" ]) // Multi let multi = new Set<_>([5; 2; 3; 1; 4]) let multiSeq = Set.toSeq multi - Assert.IsTrue(Seq.toList multiSeq = [ 1; 2; 3; 4; 5 ]) + Assert.True(Seq.toList multiSeq = [ 1; 2; 3; 4; 5 ]) - [] + [] member this.MinElement() = // Check for an argument exception "Set contains no members" @@ -568,7 +567,7 @@ type SetModule() = let set2 = Set.ofList ["abcd"; "a"; "abc"; "ab"] Assert.AreEqual(Set.minElement set2, "a") - [] + [] member this.MaxElement() = // Check for an argument exception "Set contains no members" @@ -581,30 +580,30 @@ type SetModule() = Assert.AreEqual(Set.maxElement set2, "abcd") - [] + [] member this.IsProperSubset() = let set1 = Set.ofList [10; 8; 100] let set2 = Set.ofList [100] - Assert.IsTrue(Set.isProperSubset set2 set1) - Assert.IsTrue(Set.isProperSubset Set.empty set2) - Assert.IsFalse(Set.isProperSubset Set.empty Set.empty) - Assert.IsFalse(Set.isProperSubset set1 set2) + Assert.True(Set.isProperSubset set2 set1) + Assert.True(Set.isProperSubset Set.empty set2) + Assert.False(Set.isProperSubset Set.empty Set.empty) + Assert.False(Set.isProperSubset set1 set2) - [] + [] member this.IsProperSuperset() = let set1 = Set.ofList [10; 8; 100] let set2 = Set.ofList [100; 8] - Assert.IsTrue(Set.isProperSuperset set1 set2) - Assert.IsTrue(Set.isProperSuperset set2 Set.empty) - Assert.IsFalse(Set.isProperSuperset Set.empty Set.empty) - Assert.IsFalse(Set.isProperSuperset set1 set1) - Assert.IsFalse(Set.isProperSuperset set2 set1) + Assert.True(Set.isProperSuperset set1 set2) + Assert.True(Set.isProperSuperset set2 Set.empty) + Assert.False(Set.isProperSuperset Set.empty Set.empty) + Assert.False(Set.isProperSuperset set1 set1) + Assert.False(Set.isProperSuperset set2 set1) // ----- Not associated with a module function ----- - [] + [] member this.GeneralTest1() = // Returns a random permutation of integers between the two bounds. @@ -628,14 +627,14 @@ type SetModule() = // Add permutation items to set in order Array.iter (fun i -> set := Set.add i !set) permutation // Check that the set equals the full list - Assert.IsTrue(Set.toList !set = [0 .. i]) + Assert.True(Set.toList !set = [0 .. i]) // Remove items in permutation order, ensuring set is delt with correctly Array.iteri (fun idx i -> set := Set.remove i !set // Verify all elements have been correctly removed let removedElements = Array.sub permutation 0 (idx + 1) |> Set.ofSeq let inter = Set.intersect !set removedElements - Assert.IsTrue(inter.Count = 0)) + Assert.True(inter.Count = 0)) permutation () diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetType.fs index 9b069902b16..ac3c213be80 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SetType.fs @@ -3,13 +3,13 @@ // Various tests for the: // Microsoft.FSharp.Collections.Set type -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System open System.Collections open System.Collections.Generic open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -19,17 +19,16 @@ Make sure each method works on: * Sets with 4 more more elements *) -[][][] type SetType() = // Interfaces - [] - member this.IEnumerable() = + [] + member this.IEnumerable() = // Legit IE let ie = (new Set(['a'; 'b'; 'c'])) :> IEnumerable //let alphabet = new Set([| 'a' .. 'z' |]) let enum = ie.GetEnumerator() - + let testStepping() = CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) Assert.AreEqual(enum.MoveNext(), true) @@ -53,7 +52,7 @@ type SetType() = Assert.AreEqual(enum.MoveNext(), false) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IEnumerable_T() = // Legit IE let ie =(new Set(['a'; 'b'; 'c'])) :> IEnumerable @@ -83,24 +82,24 @@ type SetType() = CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.ICollection() = // Legit IC let ic = (new Set([1;2;3;4])) :> ICollection let st = new Set([1;2;3;4]) - Assert.IsTrue(ic.Contains(3)) + Assert.True(ic.Contains(3)) let newArr = Array.create 5 0 ic.CopyTo(newArr,0) - Assert.IsTrue(ic.IsReadOnly) + Assert.True(ic.IsReadOnly) // Empty IC let ic = (new Set([])) :> ICollection - Assert.IsFalse(ic.Contains("A") ) + Assert.False(ic.Contains("A") ) let newArr = Array.create 5 "a" ic.CopyTo(newArr,0) - [] + [] member this.IReadOnlyCollection() = // Legit IROC let iroc = (new Set([1;2;3;4])) :> IReadOnlyCollection @@ -110,7 +109,7 @@ type SetType() = let iroc = (new Set([])) :> IReadOnlyCollection Assert.AreEqual(iroc.Count, 0) - [] + [] member this.IComparable() = // Legit IC let ic = (new Set([1;2;3;4])) :> IComparable @@ -122,82 +121,82 @@ type SetType() = // Base class methods - [] + [] member this.ObjectGetHashCode() = // Verify order added is independent let x = Set.ofList [1; 2; 3] let y = Set.ofList [3; 2; 1] Assert.AreEqual(x.GetHashCode(), y.GetHashCode()) - [] + [] member this.ObjectToString() = Assert.AreEqual("set [1; 2; 3; ... ]", (new Set([1;2;3;4])).ToString()) Assert.AreEqual("set []", (Set.empty).ToString()) Assert.AreEqual("set [1; 3]", (new Set([1M;3M])).ToString()) - [] + [] member this.ObjectEquals() = // All three are different references, but equality has been // provided by the F# compiler. let a = new Set([1;2;3]) let b = new Set([1..3]) let c = new Set(seq{1..3}) - Assert.IsTrue( (a = b) ) - Assert.IsTrue( (b = c) ) - Assert.IsTrue( (c = a) ) - Assert.IsTrue( a.Equals(b) ); Assert.IsTrue( b.Equals(a) ) - Assert.IsTrue( b.Equals(c) ); Assert.IsTrue( c.Equals(b) ) - Assert.IsTrue( c.Equals(a) ); Assert.IsTrue( a.Equals(c) ) + Assert.True( (a = b) ) + Assert.True( (b = c) ) + Assert.True( (c = a) ) + Assert.True( a.Equals(b) ); Assert.True( b.Equals(a) ) + Assert.True( b.Equals(c) ); Assert.True( c.Equals(b) ) + Assert.True( c.Equals(a) ); Assert.True( a.Equals(c) ) // Equality between types let a = Set.empty let b = Set.empty - Assert.IsFalse( b.Equals(a) ) - Assert.IsFalse( a.Equals(b) ) + Assert.False( b.Equals(a) ) + Assert.False( a.Equals(b) ) // Co/contra variance not supported let a = Set.empty let b = Set.empty - Assert.IsFalse(a.Equals(b)) - Assert.IsFalse(b.Equals(a)) + Assert.False(a.Equals(b)) + Assert.False(b.Equals(a)) // Self equality let a = new Set([1]) - Assert.IsTrue( (a = a) ) - Assert.IsTrue(a.Equals(a)) + Assert.True( (a = a) ) + Assert.True(a.Equals(a)) // Null - Assert.IsFalse(a.Equals(null)) + Assert.False(a.Equals(null)) // Instance methods - [] + [] member this.Add() = let l = new Set([1 .. 10]) let ad = l.Add 88 - Assert.IsTrue(ad.Contains(88)) + Assert.True(ad.Contains(88)) let e : Set = Set.empty let ade = e.Add "A" - Assert.IsTrue(ade.Contains("A")) + Assert.True(ade.Contains("A")) let s = Set.singleton 168 let ads = s.Add 100 - Assert.IsTrue(ads.Contains(100)) + Assert.True(ads.Contains(100)) - [] + [] member this.Contains() = let i = new Set([1 .. 10]) - Assert.IsTrue(i.Contains(8)) + Assert.True(i.Contains(8)) let e : Set = Set.empty - Assert.IsFalse(e.Contains("A")) + Assert.False(e.Contains("A")) let s = Set.singleton 168 - Assert.IsTrue(s.Contains(168)) + Assert.True(s.Contains(168)) - [] + [] member this.Count() = let l = new Set([1 .. 10]) Assert.AreEqual(l.Count, 10) @@ -208,63 +207,63 @@ type SetType() = let s = Set.singleton 'a' Assert.AreEqual(s.Count, 1) - [] + [] member this.IsEmpty() = let i = new Set([1 .. 10]) - Assert.IsFalse(i.IsEmpty) + Assert.False(i.IsEmpty) let e : Set = Set.empty - Assert.IsTrue(e.IsEmpty) + Assert.True(e.IsEmpty) let s = Set.singleton 168 - Assert.IsFalse(s.IsEmpty) + Assert.False(s.IsEmpty) - [] + [] member this.IsSubsetOf() = let fir = new Set([1 .. 20]) let sec = new Set([1 .. 10]) - Assert.IsTrue(sec.IsSubsetOf(fir)) - Assert.IsTrue(Set.isSubset sec fir) + Assert.True(sec.IsSubsetOf(fir)) + Assert.True(Set.isSubset sec fir) let e : Set = Set.empty - Assert.IsTrue(e.IsSubsetOf(fir)) - Assert.IsTrue(Set.isSubset e fir) + Assert.True(e.IsSubsetOf(fir)) + Assert.True(Set.isSubset e fir) let s = Set.singleton 8 - Assert.IsTrue(s.IsSubsetOf(fir)) - Assert.IsTrue(Set.isSubset s fir) + Assert.True(s.IsSubsetOf(fir)) + Assert.True(Set.isSubset s fir) let s100 = set [0..100] let s101 = set [0..101] for i = 0 to 100 do - Assert.IsFalse( (set [-1..i]).IsSubsetOf s100) - Assert.IsTrue( (set [0..i]).IsSubsetOf s100) - Assert.IsTrue( (set [0..i]).IsProperSubsetOf s101) + Assert.False( (set [-1..i]).IsSubsetOf s100) + Assert.True( (set [0..i]).IsSubsetOf s100) + Assert.True( (set [0..i]).IsProperSubsetOf s101) - [] + [] member this.IsSupersetOf() = let fir = new Set([1 .. 10]) let sec = new Set([1 .. 20]) - Assert.IsTrue(sec.IsSupersetOf(fir)) - Assert.IsTrue(Set.isSuperset sec fir) + Assert.True(sec.IsSupersetOf(fir)) + Assert.True(Set.isSuperset sec fir) let e : Set = Set.empty - Assert.IsFalse(e.IsSupersetOf(fir)) - Assert.IsFalse(Set.isSuperset e fir) + Assert.False(e.IsSupersetOf(fir)) + Assert.False(Set.isSuperset e fir) let s = Set.singleton 168 - Assert.IsFalse(s.IsSupersetOf(fir)) - Assert.IsFalse(Set.isSuperset s fir) + Assert.False(s.IsSupersetOf(fir)) + Assert.False(Set.isSuperset s fir) let s100 = set [0..100] let s101 = set [0..101] for i = 0 to 100 do - Assert.IsFalse( s100.IsSupersetOf (set [-1..i])) - Assert.IsTrue( s100.IsSupersetOf (set [0..i])) - Assert.IsTrue( s101.IsSupersetOf (set [0..i])) + Assert.False( s100.IsSupersetOf (set [-1..i])) + Assert.True( s100.IsSupersetOf (set [0..i])) + Assert.True( s101.IsSupersetOf (set [0..i])) - [] + [] member this.Remove() = let i = new Set([1;2;3;4]) Assert.AreEqual(i.Remove 3,(new Set([1;2;4]))) @@ -277,7 +276,7 @@ type SetType() = // Static methods - [] + [] member this.Addition() = let fir = new Set([1;3;5]) let sec = new Set([2;4;6]) @@ -294,7 +293,7 @@ type SetType() = Assert.AreEqual(Set.op_Addition(s1,s2), new Set([8;6])) - [] + [] member this.Subtraction() = let fir = new Set([1..6]) let sec = new Set([2;4;6]) @@ -314,7 +313,7 @@ type SetType() = Assert.AreEqual(Set.op_Subtraction(s1,s2), new Set([8])) - [] + [] member this.MinimumElement() = let fir = new Set([1..6]) let sec = new Set([2;4;6]) @@ -324,7 +323,7 @@ type SetType() = Assert.AreEqual(Set.minElement sec, 2) - [] + [] member this.MaximumElement() = let fir = new Set([1..6]) let sec = new Set([2;4;7]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs index 42cd133d6c8..67b0adee0aa 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/StringModule.fs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections +namespace FSharp.Core.UnitTests.Collections open System -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx @@ -18,38 +18,33 @@ Make sure each method works on: * Null string (null) *) -[] type StringModule() = - [] + [] member this.Concat() = - let e1 = String.concat null ["foo"] - Assert.AreEqual("foo", e1) - - let e2 = String.concat "" [] - Assert.AreEqual("", e2) - - let e3 = String.concat "foo" [] - Assert.AreEqual("", e3) - - let e4 = String.concat "" [null] - Assert.AreEqual("", e4) - - let e5 = String.concat "" [""] - Assert.AreEqual("", e5) - - let e6 = String.concat "foo" ["bar"] - Assert.AreEqual("bar", e6) - - let e7 = String.concat "foo" ["bav";"baz"] - Assert.AreEqual("bavfoobaz", e7) - - let e8 = String.concat "foo" [null;"baz";null;"bar"] - Assert.AreEqual("foobazfoofoobar", e8) - - CheckThrowsArgumentNullException(fun () -> String.concat "foo" null |> ignore) - - [] + /// This tests the three paths of String.concat w.r.t. array, list, seq + let execTest f expected arg = + let r1 = f (List.toSeq arg) + Assert.AreEqual(expected, r1) + + let r2 = f (List.toArray arg) + Assert.AreEqual(expected, r2) + + let r3 = f arg + Assert.AreEqual(expected, r3) + + do execTest (String.concat null) "world" ["world"] + do execTest (String.concat "") "" [] + do execTest (String.concat "|||") "" [] + do execTest (String.concat "") "" [null] + do execTest (String.concat "") "" [""] + do execTest (String.concat "|||") "apples" ["apples"] + do execTest (String.concat " ") "happy together" ["happy"; "together"] + do execTest (String.concat "Me! ") "Me! No, you. Me! Me! Oh, them." [null;"No, you. ";null;"Oh, them."] + + CheckThrowsArgumentNullException(fun () -> String.concat "%%%" null |> ignore) + + [] member this.Iter() = let result = ref 0 do String.iter (fun c -> result := !result + (int c)) "foo" @@ -59,7 +54,7 @@ type StringModule() = do String.iter (fun c -> result := !result + (int c)) null Assert.AreEqual(0, !result) - [] + [] member this.IterI() = let result = ref 0 do String.iteri(fun i c -> result := !result + (i*(int c))) "foo" @@ -69,37 +64,92 @@ type StringModule() = do String.iteri(fun i c -> result := !result + (i*(int c))) null Assert.AreEqual(0, !result) - [] + [] member this.Map() = - let e1 = String.map (fun c -> c) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.map id "xyz" + Assert.AreEqual("xyz", e1) - let e2 = String.map (fun c -> c) null - Assert.AreEqual("", e2) + let e2 = String.map (fun c -> c + char 1) "abcde" + Assert.AreEqual("bcdef", e2) - [] + let e3 = String.map (fun c -> c) null + Assert.AreEqual("", e3) + + let e4 = String.map (fun c -> c) String.Empty + Assert.AreEqual("", e4) + + let e5 = String.map (fun _ -> 'B') "A" + Assert.AreEqual("B", e5) + + let e6 = String.map (fun _ -> failwith "should not raise") null + Assert.AreEqual("", e6) + + // this tests makes sure mapping function is not called too many times + let mutable x = 0 + let e7 = String.map (fun _ -> if x > 2 then failwith "should not raise" else x <- x + 1; 'x') "abc" + Assert.AreEqual(x, 3) + Assert.AreEqual(e7, "xxx") + + // side-effect and "order of operation" test + let mutable x = 0 + let e8 = String.map (fun c -> x <- x + 1; c + char x) "abcde" + Assert.AreEqual(x, 5) + Assert.AreEqual(e8, "bdfhj") + + [] member this.MapI() = - let e1 = String.mapi (fun i c -> char(int c + i)) "foo" - Assert.AreEqual("fpq", e1) + let e1 = String.mapi (fun _ c -> c) "12345" + Assert.AreEqual("12345", e1) - let e2 = String.mapi (fun i c -> c) null - Assert.AreEqual("", e2) + let e2 = String.mapi (fun _ c -> c + char 1) "1" + Assert.AreEqual("2", e2) + + let e3 = String.mapi (fun _ c -> c + char 1) "AB" + Assert.AreEqual("BC", e3) - [] + let e4 = String.mapi (fun i c -> char(int c + i)) "hello" + Assert.AreEqual("hfnos", e4) + + let e5 = String.mapi (fun _ c -> c) null + Assert.AreEqual("", e5) + + let e6 = String.mapi (fun _ c -> c) String.Empty + Assert.AreEqual("", e6) + + let e7 = String.mapi (fun _ _ -> failwith "should not fail") null + Assert.AreEqual("", e7) + + let e8 = String.mapi (fun i _ -> if i = 1 then failwith "should not fail" else char i) "X" + Assert.AreEqual("\u0000", e8) + + // side-effect and "order of operation" test + let mutable x = 0 + let e9 = String.mapi (fun i c -> x <- x + i; c + char x) "abcde" + Assert.AreEqual(x, 10) + Assert.AreEqual(e9, "acfjo") + + [] member this.Filter() = - let e1 = String.filter (fun c -> true) "foo" - Assert.AreEqual("foo", e1) + let e1 = String.filter (fun c -> true) "Taradiddle" + Assert.AreEqual("Taradiddle", e1) let e2 = String.filter (fun c -> true) null Assert.AreEqual("", e2) - let e3 = String.filter (fun c -> c <> 'o') "foo bar" - Assert.AreEqual("f bar", e3) + let e3 = String.filter Char.IsUpper "How Vexingly Quick Daft Zebras Jump!" + Assert.AreEqual("HVQDZJ", e3) let e4 = String.filter (fun c -> c <> 'o') "" Assert.AreEqual("", e4) - [] + let e5 = String.filter (fun c -> c > 'B' ) "ABRACADABRA" + Assert.AreEqual("RCDR", e5) + + // LOH test with 55k string, which is 110k bytes + let e5 = String.filter (fun c -> c > 'B' ) (String.replicate 5_000 "ABRACADABRA") + Assert.AreEqual(String.replicate 5_000 "RCDR", e5) + + [] member this.Collect() = let e1 = String.collect (fun c -> "a"+string c) "foo" Assert.AreEqual("afaoao", e1) @@ -110,7 +160,7 @@ type StringModule() = let e3 = String.collect (fun c -> "") null Assert.AreEqual("", e3) - [] + [] member this.Init() = let e1 = String.init 0 (fun i -> "foo") Assert.AreEqual("", e1) @@ -123,20 +173,47 @@ type StringModule() = CheckThrowsArgumentException(fun () -> String.init -1 (fun c -> "") |> ignore) - [] + [] member this.Replicate() = - let e1 = String.replicate 0 "foo" + let e1 = String.replicate 0 "Snickersnee" Assert.AreEqual("", e1) - let e2 = String.replicate 2 "foo" - Assert.AreEqual("foofoo", e2) + let e2 = String.replicate 2 "Collywobbles, " + Assert.AreEqual("Collywobbles, Collywobbles, ", e2) let e3 = String.replicate 2 null Assert.AreEqual("", e3) + let e4 = String.replicate 300_000 "" + Assert.AreEqual("", e4) + + let e5 = String.replicate 23 "天地玄黃,宇宙洪荒。" + Assert.AreEqual(230 , e5.Length) + Assert.AreEqual("天地玄黃,宇宙洪荒。天地玄黃,宇宙洪荒。", e5.Substring(0, 20)) + + // This tests the cut-off point for the O(log(n)) algorithm with a prime number + let e6 = String.replicate 84673 "!!!" + Assert.AreEqual(84673 * 3, e6.Length) + + // This tests the cut-off point for the O(log(n)) algorithm with a 2^x number + let e7 = String.replicate 1024 "!!!" + Assert.AreEqual(1024 * 3, e7.Length) + + let e8 = String.replicate 1 "What a wonderful world" + Assert.AreEqual("What a wonderful world", e8) + + let e9 = String.replicate 3 "أضعت طريقي! أضعت طريقي" // means: I'm lost + Assert.AreEqual("أضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقيأضعت طريقي! أضعت طريقي", e9) + + let e10 = String.replicate 4 "㏖ ㏗ ℵ " + Assert.AreEqual("㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ㏖ ㏗ ℵ ", e10) + + let e11 = String.replicate 5 "5" + Assert.AreEqual("55555", e11) + CheckThrowsArgumentException(fun () -> String.replicate -1 "foo" |> ignore) - [] + [] member this.Forall() = let e1 = String.forall (fun c -> true) "" Assert.AreEqual(true, e1) @@ -156,7 +233,7 @@ type StringModule() = let e6 = String.forall (fun c -> false) null Assert.AreEqual(true, e6) - [] + [] member this.Exists() = let e1 = String.exists (fun c -> true) "" Assert.AreEqual(false, e1) @@ -173,7 +250,7 @@ type StringModule() = let e5 = String.exists (fun c -> false) (String.replicate 1000000 "x") Assert.AreEqual(false, e5) - [] + [] member this.Length() = let e1 = String.length "" Assert.AreEqual(0, e1) @@ -184,19 +261,19 @@ type StringModule() = let e3 = String.length null Assert.AreEqual(0, e3) - [] + [] member this.``Slicing with both index reverse behaves as expected``() = let str = "abcde" - Assert.That(str.[^3..^1], Is.EquivalentTo(str.[1..3])) + Assert.AreEqual(str.[^3..^1], str.[1..3]) - [] + [] member this.``Indexer with reverse index behaves as expected``() = let str = "abcde" - Assert.That(str.[^1], Is.EqualTo('d')) + Assert.AreEqual(str.[^1], 'd') - [] + [] member this.SlicingUnboundedEnd() = let str = "123456" @@ -209,7 +286,7 @@ type StringModule() = Assert.AreEqual(str.[7..], ("")) - [] + [] member this.SlicingUnboundedStart() = let str = "123456" @@ -224,7 +301,7 @@ type StringModule() = Assert.AreEqual(str.[..7], "123456") - [] + [] member this.SlicingBoundedStartEnd() = let str = "123456" @@ -250,7 +327,7 @@ type StringModule() = Assert.AreEqual(str.[4..1], ("")) - [] + [] member this.SlicingEmptyString() = let empty = "" @@ -262,7 +339,7 @@ type StringModule() = Assert.AreEqual(empty.[3..5], ("")) - [] + [] member this.SlicingOutOfBounds() = let str = "123456" diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Utils.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Utils.fs index 57ab6f58768..7d55fdcb142 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Utils.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/Utils.fs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.Utils +module FSharp.Core.UnitTests.Collections.Utils -open NUnit.Framework +open Xunit type Result<'a> = | Success of 'a diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs index 14c842e8c5c..c708da2e08b 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs @@ -3,12 +3,12 @@ // Various tests for the: // Microsoft.FSharp.Control.Async module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System open System.Threading open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open FsCheck module Utils = @@ -63,7 +63,7 @@ module ChoiceUtils = let runChoice (ChoiceWorkflow(ops, cancelAfter)) = // Step 1. build a choice workflow from the abstract representation let completed = ref 0 - let returnAfter time f = async { + let returnAfter (time: int) f = async { do! Async.Sleep time let _ = Interlocked.Increment completed return f () @@ -134,7 +134,7 @@ module ChoiceUtils = if not <| List.isEmpty ops then let minTimeout = getMinTime() let minTimeoutOps = ops |> Seq.filter (fun op -> op.Timeout <= minTimeout) |> Seq.length - Assert.IsTrue(!completed <= minTimeoutOps) + Assert.True(!completed <= minTimeoutOps) module LeakUtils = // when testing for liveness, the things that we want to observe must always be created in @@ -147,7 +147,6 @@ module LeakUtils = // --------------------------------------------------- -[] type AsyncModule() = /// Simple asynchronous task that delays 200ms and returns a list of the current tick count @@ -190,7 +189,7 @@ type AsyncModule() = |> ignore if !c = 2 then Assert.Fail("both error and cancel continuations were called") - [] + [] member this.AwaitIAsyncResult() = let beginOp, endOp, cancelOp = Async.AsBeginEnd(fun() -> getTicksTask) @@ -217,7 +216,7 @@ type AsyncModule() = | true -> Assert.Fail("Timeout expected") | false -> () - [] + [] member this.``AwaitWaitHandle.Timeout``() = use waitHandle = new System.Threading.ManualResetEvent(false) let startTime = DateTime.UtcNow @@ -226,13 +225,13 @@ type AsyncModule() = Async.AwaitWaitHandle(waitHandle, 500) |> Async.RunSynchronously - Assert.IsFalse(r, "Timeout expected") + Assert.False(r, "Timeout expected") let endTime = DateTime.UtcNow let delta = endTime - startTime - Assert.IsTrue(delta.TotalMilliseconds < 1100.0, sprintf "Expected faster timeout than %.0f ms" delta.TotalMilliseconds) + Assert.True(delta.TotalMilliseconds < 1100.0, sprintf "Expected faster timeout than %.0f ms" delta.TotalMilliseconds) - [] + [] member this.``AwaitWaitHandle.TimeoutWithCancellation``() = use barrier = new System.Threading.ManualResetEvent(false) use waitHandle = new System.Threading.ManualResetEvent(false) @@ -251,7 +250,7 @@ type AsyncModule() = // wait a bit then signal cancellation let timeout = wait barrier 500 - Assert.IsFalse(timeout, "timeout=true is not expected") + Assert.False(timeout, "timeout=true is not expected") cts.Cancel() @@ -259,7 +258,7 @@ type AsyncModule() = let ok = wait barrier 10000 if not ok then Assert.Fail("Async computation was not completed in given time") - [] + [] member this.``AwaitWaitHandle.DisposedWaitHandle1``() = let wh = new System.Threading.ManualResetEvent(false) @@ -273,8 +272,9 @@ type AsyncModule() = | e -> Assert.Fail(sprintf "Unexpected error %A" e) } Async.RunSynchronously test - - [] + + // test is flaky: https://github.com/dotnet/fsharp/issues/11586 + //[] member this.``OnCancel.RaceBetweenCancellationHandlerAndDisposingHandlerRegistration``() = let test() = use flag = new ManualResetEvent(false) @@ -289,15 +289,16 @@ type AsyncModule() = Async.Start (go, cancellationToken = cts.Token) //wait until we are sure the Async.OnCancel has run: - Assert.IsTrue(cancelHandlerRegistered.WaitOne(TimeSpan.FromSeconds 5.)) + Assert.True(cancelHandlerRegistered.WaitOne(TimeSpan.FromSeconds 5.)) //now cancel: cts.Cancel() //cancel handler should have run: - Assert.IsTrue(flag.WaitOne(TimeSpan.FromSeconds 5.)) + Assert.True(flag.WaitOne(TimeSpan.FromSeconds 5.)) for _i = 1 to 300 do test() - [] + // test is flaky: https://github.com/dotnet/fsharp/issues/11586 + //[] member this.``OnCancel.RaceBetweenCancellationAndDispose``() = let flag = ref 0 let cts = new System.Threading.CancellationTokenSource() @@ -305,7 +306,7 @@ type AsyncModule() = use disp = cts.Cancel() { new IDisposable with - override __.Dispose() = incr flag } + override _.Dispose() = incr flag } while true do do! Async.Sleep 50 } @@ -315,13 +316,13 @@ type AsyncModule() = :? System.OperationCanceledException -> () Assert.AreEqual(1, !flag) - [] + // test is flaky: https://github.com/dotnet/fsharp/issues/11586 + //[] member this.``OnCancel.CancelThatWasSignalledBeforeRunningTheComputation``() = let test() = let cts = new System.Threading.CancellationTokenSource() let go e (flag : bool ref) = async { let! _ = Async.AwaitWaitHandle e - sleep 500 use! _holder = Async.OnCancel(fun () -> flag := true) while true do do! Async.Sleep 100 @@ -331,13 +332,12 @@ type AsyncModule() = let finish = new System.Threading.ManualResetEvent(false) let cancelledWasCalled = ref false Async.StartWithContinuations(go evt cancelledWasCalled, ignore, ignore, (fun _ -> finish.Set() |> ignore), cancellationToken = cts.Token) - sleep 500 evt.Set() |> ignore cts.Cancel() let ok = wait finish 3000 - Assert.IsTrue(ok, "Computation should be completed") - Assert.IsFalse(!cancelledWasCalled, "Cancellation handler should not be called") + Assert.True(ok, "Computation should be completed") + Assert.False(!cancelledWasCalled, "Cancellation handler should not be called") for _i = 1 to 3 do test() @@ -363,7 +363,7 @@ type AsyncModule() = WeakReference(resource)) |> LeakUtils.run - Assert.IsTrue(resource.IsAlive) + Assert.True(resource.IsAlive) GC.Collect() GC.WaitForPendingFinalizers() @@ -371,33 +371,33 @@ type AsyncModule() = GC.WaitForPendingFinalizers() GC.Collect() - Assert.IsFalse(resource.IsAlive) + Assert.False(resource.IsAlive) // The leak hangs on a race condition which is really hard to trigger in F# 3.0, hence the 100000 runs... for _ in 1..10 do tryToLeak() #endif - [] + [] member this.``AwaitWaitHandle.DisposedWaitHandle2``() = let wh = new System.Threading.ManualResetEvent(false) let barrier = new System.Threading.ManualResetEvent(false) let test = async { let! timeout = Async.AwaitWaitHandle(wh, 10000) - Assert.IsFalse(timeout, "Timeout expected") + Assert.False(timeout, "Timeout expected") barrier.Set() |> ignore } Async.Start test // await 3 secs then dispose waithandle - nothing should happen let timeout = wait barrier 3000 - Assert.IsFalse(timeout, "Barrier was reached too early") + Assert.False(timeout, "Barrier was reached too early") dispose wh let ok = wait barrier 10000 if not ok then Assert.Fail("Async computation was not completed in given time") - [] + [] member this.``RunSynchronously.NoThreadJumpsAndTimeout``() = let longRunningTask = async { sleep(5000) } try @@ -406,7 +406,7 @@ type AsyncModule() = with :? System.TimeoutException -> () - [] + [] member this.``RunSynchronously.NoThreadJumpsAndTimeout.DifferentSyncContexts``() = let run syncContext = let old = System.Threading.SynchronizationContext.Current @@ -423,13 +423,13 @@ type AsyncModule() = run null run (System.Threading.SynchronizationContext()) - [] + [] member this.``RaceBetweenCancellationAndError.AwaitWaitHandle``() = let disposedEvent = new System.Threading.ManualResetEvent(false) dispose disposedEvent testErrorAndCancelRace "RaceBetweenCancellationAndError.AwaitWaitHandle" (Async.AwaitWaitHandle disposedEvent) - [] + [] member this.``RaceBetweenCancellationAndError.Sleep``() = testErrorAndCancelRace "RaceBetweenCancellationAndError.Sleep" (Async.Sleep (-5)) @@ -442,19 +442,19 @@ type AsyncModule() = #endif #endif - [] + [] member this.``dispose should not throw when called on null``() = let result = async { use x = null in return () } |> Async.RunSynchronously Assert.AreEqual((), result) - [] + [] member this.``dispose should not throw when called on null struct``() = let result = async { use x = new Dummy(1) in return () } |> Async.RunSynchronously Assert.AreEqual((), result) - [] + [] member this.``error on one workflow should cancel all others``() = let counter = async { @@ -473,7 +473,7 @@ type AsyncModule() = Assert.AreEqual(0, counter) - [] + [] member this.``AwaitWaitHandle.ExceptionsAfterTimeout``() = let wh = new System.Threading.ManualResetEvent(false) let test = async { @@ -487,7 +487,7 @@ type AsyncModule() = } Async.RunSynchronously(test) - [] + [] member this.``FromContinuationsCanTailCallCurrentThread``() = let cnt = ref 0 let origTid = System.Threading.Thread.CurrentThread.ManagedThreadId @@ -508,11 +508,11 @@ type AsyncModule() = Assert.AreEqual(origTid, !finalTid) Assert.AreEqual(5000, !cnt) - [] + [] member this.``AwaitWaitHandle With Cancellation``() = let run wh = async { let! r = Async.AwaitWaitHandle wh - Assert.IsTrue(r, "Timeout not expected") + Assert.True(r, "Timeout not expected") return() } let test () = @@ -533,7 +533,7 @@ type AsyncModule() = :? System.OperationCanceledException -> () // OK for _ in 1..1000 do test() - [] + [] member this.``StartWithContinuationsVersusDoBang``() = // worthwhile to note these three // case 1 @@ -588,7 +588,7 @@ type AsyncModule() = Assert.AreEqual(0, !errCount) #endif - [] + [] member this.``Async caching should work``() = let x = ref 0 let someSlowFunc _mykey = async { @@ -626,12 +626,12 @@ type AsyncModule() = Console.WriteLine "Checking result...." Assert.AreEqual(1, !x) - [] + [] member this.``Parallel with maxDegreeOfParallelism`` () = let mutable i = 1 let action j = async { do! Async.Sleep 1 - Assert.AreEqual(j, i) + Assert.Equal(j, i) i <- i + 1 } let computation = @@ -639,7 +639,7 @@ type AsyncModule() = |> fun cs -> Async.Parallel(cs, 1) Async.RunSynchronously(computation) |> ignore - [] + [] member this.``maxDegreeOfParallelism can not be 0`` () = try [| for i in 1 .. 10 -> async { return i } |] @@ -651,7 +651,7 @@ type AsyncModule() = Assert.AreEqual("maxDegreeOfParallelism", exc.ParamName) Assert.True(exc.Message.Contains("maxDegreeOfParallelism must be positive, was 0")) - [] + [] member this.``maxDegreeOfParallelism can not be negative`` () = try [| for i in 1 .. 10 -> async { return i } |] @@ -663,19 +663,19 @@ type AsyncModule() = Assert.AreEqual("maxDegreeOfParallelism", exc.ParamName) Assert.True(exc.Message.Contains("maxDegreeOfParallelism must be positive, was -1")) - [] + [] member this.``RaceBetweenCancellationAndError.Parallel(maxDegreeOfParallelism)``() = [| for i in 1 .. 1000 -> async { failwith "boom" } |] |> fun cs -> Async.Parallel(cs, 1) |> testErrorAndCancelRace "RaceBetweenCancellationAndError.Parallel(maxDegreeOfParallelism)" - [] + [] member this.``RaceBetweenCancellationAndError.Parallel``() = [| for i in 1 .. 1000 -> async { failwith "boom" } |] |> fun cs -> Async.Parallel(cs) |> testErrorAndCancelRace "RaceBetweenCancellationAndError.Parallel" - [] + [] member this.``error on one workflow should cancel all others with maxDegreeOfParallelism``() = let counter = async { @@ -691,3 +691,56 @@ type AsyncModule() = } |> Async.RunSynchronously Assert.AreEqual(54, counter) + + [] + member this.``async doesn't do cancel check between do! and try-finally``() = + let gate = obj() + for i in 0..10 do + let procCount = 3 + use semaphore = new SemaphoreSlim(procCount-1) + printfn "Semaphore count available: %i" semaphore.CurrentCount + let mutable acquiredCount = 0 + let mutable releaseCount = 0 + try + List.init procCount (fun index -> + async { + lock gate <| fun () -> printfn "[%i] Waiting to enter semaphore" index + let! cancellationToken = Async.CancellationToken + + // The semaphore lets two threads through at a time + do! semaphore.WaitAsync(cancellationToken) |> Async.AwaitTask + + // No implicit cancellation checks should take place between a do! and a try + // if there are no other async control constructs present. If there is synchronous code + // it runs without cancellation checks + // + // index 1 will enter the try/finally quickly, call failwith and cancel the other tasks + // One of index 2 and index 3 will be stuck here before the try/finally. But having got + // this far it should enter the try/finally before cancellation takes effect + do + lock gate <| fun () -> printfn "[%i] Acquired semaphore" index + Interlocked.Increment(&acquiredCount) |> ignore + if index <> 0 then + lock gate <| fun () -> printfn "[%i] Slowly entering try/finally" index + System.Threading.Thread.Sleep(100) + + try + lock gate <| fun () -> printfn "[%i] Within try-finally" index + if index = 0 then + lock gate <| fun () -> printfn "[%i] Error" index + // The failure will cause others to cancel + failwith "Something bad happened!" + finally + semaphore.Release() |> ignore + // This should always get executed + Interlocked.Increment(&releaseCount) |> ignore + lock gate <| fun () -> printfn "[%i] Semaphore released" index + }) + |> Async.Parallel + |> Async.Ignore + |> Async.RunSynchronously + with + | exn -> + lock gate <| fun () -> printfn "Unhandled exception: %s" exn.Message + lock gate <| fun () -> printfn "Semaphore count available: %i" semaphore.CurrentCount + Assert.AreEqual(acquiredCount, releaseCount) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs index 2966bf32d48..6247da500b7 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Control.Async type -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open System.Threading open System.Threading.Tasks @@ -16,15 +16,17 @@ type RunWithContinuationsTest_WhatToDo = | Cancel | Throw -[] type AsyncType() = let ignoreSynchCtx f = f () + let waitASec (t:Task) = + let result = t.Wait(TimeSpan(hours=0,minutes=0,seconds=1)) + Assert.True(result, "Task did not finish after waiting for a second.") - [] - member this.StartWithContinuations() = + [] + member _.StartWithContinuations() = let whatToDo = ref Exit @@ -46,7 +48,7 @@ type AsyncType() = let onSuccess x = match !whatToDo with - | Cancel | Throw + | Cancel | Throw -> Assert.Fail("Expected onSuccess but whatToDo was not Exit", [| whatToDo |]) | Exit -> () @@ -75,8 +77,8 @@ type AsyncType() = () - [] - member this.AsyncRunSynchronouslyReusesThreadPoolThread() = + [] + member _.AsyncRunSynchronouslyReusesThreadPoolThread() = let action = async { async { () } |> Async.RunSynchronously } let computation = [| for i in 1 .. 1000 -> action |] @@ -88,10 +90,16 @@ type AsyncType() = // (the number of threads in ThreadPool is adjusted slowly). Async.RunSynchronously(computation, timeout = 1000) |> ignore - [] - member this.AsyncSleepCancellation1() = + [] + [] + [] + member _.AsyncSleepCancellation1(sleepType) = ignoreSynchCtx (fun () -> - let computation = Async.Sleep(10000000) + let computation = + match sleepType with + | "int32" -> Async.Sleep(10000000) + | "timespan" -> Async.Sleep(10000000.0 |> TimeSpan.FromMilliseconds) + | unknown -> raise (NotImplementedException(unknown)) let result = ref "" use cts = new CancellationTokenSource() Async.StartWithContinuations(computation, @@ -104,10 +112,16 @@ type AsyncType() = Assert.AreEqual("Cancel", !result) ) - [] - member this.AsyncSleepCancellation2() = + [] + [] + [] + member _.AsyncSleepCancellation2(sleepType) = ignoreSynchCtx (fun () -> - let computation = Async.Sleep(10) + let computation = + match sleepType with + | "int32" -> Async.Sleep(10) + | "timespan" -> Async.Sleep(10.0 |> TimeSpan.FromMilliseconds) + | unknown -> raise (NotImplementedException(unknown)) for i in 1..100 do let result = ref "" use completedEvent = new ManualResetEvent(false) @@ -119,31 +133,51 @@ type AsyncType() = cts.Token) sleep(10) cts.Cancel() - completedEvent.WaitOne() |> Assert.IsTrue - Assert.IsTrue(!result = "Cancel" || !result = "Ok") + completedEvent.WaitOne() |> Assert.True + Assert.True(!result = "Cancel" || !result = "Ok") ) - member private this.WaitASec (t:Task) = - let result = t.Wait(TimeSpan(hours=0,minutes=0,seconds=1)) - Assert.IsTrue(result, "Task did not finish after waiting for a second.") - - - [] - member this.CreateTask () = + [] + [] + [] + member _.AsyncSleepThrowsOnNegativeDueTimes(sleepType) = + async { + try + do! match sleepType with + | "int32" -> Async.Sleep(-100) + | "timespan" -> Async.Sleep(-100.0 |> TimeSpan.FromMilliseconds) + | unknown -> raise (NotImplementedException(unknown)) + failwith "Expected ArgumentOutOfRangeException" + with + | :? ArgumentOutOfRangeException -> () + } |> Async.RunSynchronously + + [] + member _.AsyncSleepInfinitely() = + ignoreSynchCtx (fun () -> + let computation = Async.Sleep(System.Threading.Timeout.Infinite) + let result = TaskCompletionSource() + use cts = new CancellationTokenSource(TimeSpan.FromSeconds(1.0)) // there's a long way from 1 sec to infinity, but it'll have to do. + Async.StartWithContinuations(computation, + (fun _ -> result.TrySetResult("Ok") |> ignore), + (fun _ -> result.TrySetResult("Exception") |> ignore), + (fun _ -> result.TrySetResult("Cancel") |> ignore), + cts.Token) + let result = result.Task |> Async.AwaitTask |> Async.RunSynchronously + Assert.AreEqual("Cancel", result) + ) + + [] + member _.CreateTask () = let s = "Hello tasks!" let a = async { return s } -#if !NET46 - let t : Task = -#else - use t : Task = -#endif - Async.StartAsTask a - this.WaitASec t - Assert.IsTrue (t.IsCompleted) + use t : Task = Async.StartAsTask a + waitASec t + Assert.True (t.IsCompleted) Assert.AreEqual(s, t.Result) - [] - member this.StartAsTaskCancellation () = + [] + member _.StartAsTaskCancellation () = let cts = new CancellationTokenSource() let mutable spinloop = true let doSpinloop () = while spinloop do () @@ -151,31 +185,26 @@ type AsyncType() = cts.CancelAfter (100) doSpinloop() } -#if !NET46 - let t : Task = -#else - use t : Task = -#endif - Async.StartAsTask(a, cancellationToken = cts.Token) + use t : Task = Async.StartAsTask(a, cancellationToken = cts.Token) // Should not finish, we don't eagerly mark the task done just because it's been signaled to cancel. try let result = t.Wait(300) - Assert.IsFalse (result) + Assert.False (result) with :? AggregateException -> Assert.Fail "Task should not finish, yet" spinloop <- false - + try - this.WaitASec t + waitASec t with :? AggregateException as a -> match a.InnerException with | :? TaskCanceledException as t -> () | _ -> reraise() - Assert.IsTrue (t.IsCompleted, "Task is not completed") + Assert.True (t.IsCompleted, "Task is not completed") - [] - member this.``AwaitTask ignores Async cancellation`` () = + [] + member _.``AwaitTask ignores Async cancellation`` () = let cts = new CancellationTokenSource() let tcs = new TaskCompletionSource() let innerTcs = new TaskCompletionSource() @@ -186,21 +215,21 @@ type AsyncType() = cts.CancelAfter(100) try let result = tcs.Task.Wait(300) - Assert.IsFalse (result) + Assert.False (result) with :? AggregateException -> Assert.Fail "Should not finish, yet" innerTcs.SetResult () try - this.WaitASec tcs.Task + waitASec tcs.Task with :? AggregateException as a -> match a.InnerException with | :? TaskCanceledException -> () | _ -> reraise() - Assert.IsTrue (tcs.Task.IsCompleted, "Task is not completed") + Assert.True (tcs.Task.IsCompleted, "Task is not completed") - [] - member this.RunSynchronouslyCancellationWithDelayedResult () = + [] + member _.RunSynchronouslyCancellationWithDelayedResult () = let cts = new CancellationTokenSource() let tcs = TaskCompletionSource() let _ = cts.Token.Register(fun () -> tcs.SetResult 42) @@ -209,157 +238,126 @@ type AsyncType() = let! result = tcs.Task |> Async.AwaitTask return result } - try - Async.RunSynchronously(a, cancellationToken = cts.Token) - |> ignore - with :? OperationCanceledException as o -> () + let cancelled = + try + Async.RunSynchronously(a, cancellationToken = cts.Token) |> ignore + false + with :? OperationCanceledException as o -> true + | _ -> false + + Assert.True (cancelled, "Task is not cancelled") - [] - member this.ExceptionPropagatesToTask () = - let a = async { + [] + member _.ExceptionPropagatesToTask () = + let a = async { do raise (Exception ()) } -#if !NET46 - let t = -#else - use t = -#endif - Async.StartAsTask a + use t = Async.StartAsTask a let mutable exceptionThrown = false - try - this.WaitASec t - with + try + waitASec t + with e -> exceptionThrown <- true - Assert.IsTrue (t.IsFaulted) - Assert.IsTrue(exceptionThrown) - - [] - member this.CancellationPropagatesToTask () = + Assert.True (t.IsFaulted) + Assert.True(exceptionThrown) + + [] + member _.CancellationPropagatesToTask () = let a = async { while true do () } -#if !NET46 - let t = -#else - use t = -#endif - Async.StartAsTask a - Async.CancelDefaultToken () + use t = Async.StartAsTask a + Async.CancelDefaultToken () let mutable exceptionThrown = false try - this.WaitASec t + waitASec t with e -> exceptionThrown <- true - Assert.IsTrue (exceptionThrown) - Assert.IsTrue(t.IsCanceled) - - [] - member this.CancellationPropagatesToGroup () = + Assert.True (exceptionThrown) + Assert.True(t.IsCanceled) + + [] + member _.CancellationPropagatesToGroup () = let ewh = new ManualResetEvent(false) let cancelled = ref false - let a = async { + let a = async { use! holder = Async.OnCancel (fun _ -> cancelled := true) - ewh.Set() |> Assert.IsTrue + ewh.Set() |> Assert.True while true do () } let cts = new CancellationTokenSource() let token = cts.Token -#if !NET46 - let t = -#else - use t = -#endif - Async.StartAsTask(a, cancellationToken=token) + use t = Async.StartAsTask(a, cancellationToken=token) // printfn "%A" t.Status - ewh.WaitOne() |> Assert.IsTrue + ewh.WaitOne() |> Assert.True cts.Cancel() -// printfn "%A" t.Status +// printfn "%A" t.Status let mutable exceptionThrown = false try - this.WaitASec t + waitASec t with e -> exceptionThrown <- true - Assert.IsTrue (exceptionThrown) - Assert.IsTrue(t.IsCanceled) - Assert.IsTrue(!cancelled) + Assert.True (exceptionThrown) + Assert.True(t.IsCanceled) + Assert.True(!cancelled) - [] - member this.CreateImmediateAsTask () = + [] + member _.CreateImmediateAsTask () = let s = "Hello tasks!" let a = async { return s } -#if !NET46 - let t : Task = -#else - use t : Task = -#endif - Async.StartImmediateAsTask a - this.WaitASec t - Assert.IsTrue (t.IsCompleted) - Assert.AreEqual(s, t.Result) - - [] - member this.StartImmediateAsTask () = + use t : Task = Async.StartImmediateAsTask a + waitASec t + Assert.True (t.IsCompleted) + Assert.AreEqual(s, t.Result) + + [] + member _.StartImmediateAsTask () = let s = "Hello tasks!" let a = async { return s } -#if !NET46 - let t = -#else - use t = -#endif - Async.StartImmediateAsTask a - this.WaitASec t - Assert.IsTrue (t.IsCompleted) - Assert.AreEqual(s, t.Result) - - - [] - member this.ExceptionPropagatesToImmediateTask () = - let a = async { + use t = Async.StartImmediateAsTask a + waitASec t + Assert.True (t.IsCompleted) + Assert.AreEqual(s, t.Result) + + + [] + member _.ExceptionPropagatesToImmediateTask () = + let a = async { do raise (Exception ()) } -#if !NET46 - let t = -#else - use t = -#endif - Async.StartImmediateAsTask a + use t = Async.StartImmediateAsTask a let mutable exceptionThrown = false - try - this.WaitASec t - with + try + waitASec t + with e -> exceptionThrown <- true - Assert.IsTrue (t.IsFaulted) - Assert.IsTrue(exceptionThrown) + Assert.True (t.IsFaulted) + Assert.True(exceptionThrown) #if IGNORED - [] + [] [] - member this.CancellationPropagatesToImmediateTask () = + member _.CancellationPropagatesToImmediateTask () = let a = async { while true do () } -#if !NET46 - let t = -#else - use t = -#endif - Async.StartImmediateAsTask a - Async.CancelDefaultToken () + use t = Async.StartImmediateAsTask a + Async.CancelDefaultToken () let mutable exceptionThrown = false try - this.WaitASec t + waitASec t with e -> exceptionThrown <- true - Assert.IsTrue (exceptionThrown) - Assert.IsTrue(t.IsCanceled) + Assert.True (exceptionThrown) + Assert.True(t.IsCanceled) #endif #if IGNORED - [] + [] [] - member this.CancellationPropagatesToGroupImmediate () = + member _.CancellationPropagatesToGroupImmediate () = let ewh = new ManualResetEvent(false) let cancelled = ref false - let a = async { + let a = async { use! holder = Async.OnCancel (fun _ -> cancelled := true) - ewh.Set() |> Assert.IsTrue + ewh.Set() |> Assert.True while true do () } let cts = new CancellationTokenSource() @@ -367,146 +365,172 @@ type AsyncType() = use t = Async.StartImmediateAsTask(a, cancellationToken=token) // printfn "%A" t.Status - ewh.WaitOne() |> Assert.IsTrue + ewh.WaitOne() |> Assert.True cts.Cancel() -// printfn "%A" t.Status +// printfn "%A" t.Status let mutable exceptionThrown = false try - this.WaitASec t + waitASec t with e -> exceptionThrown <- true - Assert.IsTrue (exceptionThrown) - Assert.IsTrue(t.IsCanceled) - Assert.IsTrue(!cancelled) + Assert.True (exceptionThrown) + Assert.True(t.IsCanceled) + Assert.True(!cancelled) #endif - [] - member this.TaskAsyncValue () = + [] + member _.TaskAsyncValue () = let s = "Test" -#if !NET46 - let t = -#else - use t = -#endif - Task.Factory.StartNew(Func<_>(fun () -> s)) + use t = Task.Factory.StartNew(Func<_>(fun () -> s)) let a = async { let! s1 = Async.AwaitTask(t) return s = s1 } - Async.RunSynchronously(a, 1000) |> Assert.IsTrue + Async.RunSynchronously(a) |> Assert.True - [] - member this.AwaitTaskCancellation () = + [] + member _.AwaitTaskCancellation () = let test() = async { let tcs = new System.Threading.Tasks.TaskCompletionSource() tcs.SetCanceled() - try + try do! Async.AwaitTask tcs.Task return false with :? System.OperationCanceledException -> return true } - Async.RunSynchronously(test()) |> Assert.IsTrue - - [] - member this.AwaitTaskCancellationUntyped () = + Async.RunSynchronously(test()) |> Assert.True + + [] + member _.AwaitCompletedTask() = + let test() = async { + let threadIdBefore = Thread.CurrentThread.ManagedThreadId + do! Async.AwaitTask Task.CompletedTask + let threadIdAfter = Thread.CurrentThread.ManagedThreadId + return threadIdBefore = threadIdAfter + } + + Async.RunSynchronously(test()) |> Assert.True + + [] + member _.AwaitTaskCancellationUntyped () = let test() = async { let tcs = new System.Threading.Tasks.TaskCompletionSource() tcs.SetCanceled() - try + try do! Async.AwaitTask (tcs.Task :> Task) return false with :? System.OperationCanceledException -> return true } - Async.RunSynchronously(test()) |> Assert.IsTrue - - [] - member this.TaskAsyncValueException () = -#if !NET46 - let t = -#else - use t = -#endif - Task.Factory.StartNew(Func(fun () -> raise <| Exception())) + Async.RunSynchronously(test()) |> Assert.True + + [] + member _.TaskAsyncValueException () = + use t = Task.Factory.StartNew(Func(fun () -> raise <| Exception())) let a = async { try let! v = Async.AwaitTask(t) return false with e -> return true } - Async.RunSynchronously(a, 1000) |> Assert.IsTrue - - [] - member this.TaskAsyncValueCancellation () = - use ewh = new ManualResetEvent(false) + Async.RunSynchronously(a) |> Assert.True + + // test is flaky: https://github.com/dotnet/fsharp/issues/11586 + //[] + member _.TaskAsyncValueCancellation () = + use ewh = new ManualResetEvent(false) let cts = new CancellationTokenSource() let token = cts.Token -#if !NET46 - let t : Task= -#else - use t : Task= -#endif - Task.Factory.StartNew(Func(fun () -> while not token.IsCancellationRequested do ()), token) + use t : Task = Task.Factory.StartNew(Func(fun () -> while not token.IsCancellationRequested do ()), token) let cancelled = ref true - let a = async { + let a = + async { + try use! _holder = Async.OnCancel(fun _ -> ewh.Set() |> ignore) let! v = Async.AwaitTask(t) return v - } + // AwaitTask raises TaskCanceledException when it is canceled, it is a valid result of this test + with + :? TaskCanceledException -> + ewh.Set() |> ignore // this is ok + } Async.Start a cts.Cancel() - ewh.WaitOne(10000) |> ignore + ewh.WaitOne(10000) |> ignore - [] - member this.NonGenericTaskAsyncValue () = + [] + member _.NonGenericTaskAsyncValue () = let hasBeenCalled = ref false -#if !NET46 - let t = -#else - use t = -#endif - Task.Factory.StartNew(Action(fun () -> hasBeenCalled := true)) + use t = Task.Factory.StartNew(Action(fun () -> hasBeenCalled := true)) let a = async { do! Async.AwaitTask(t) return true } - let result =Async.RunSynchronously(a, 1000) - (!hasBeenCalled && result) |> Assert.IsTrue - - [] - member this.NonGenericTaskAsyncValueException () = -#if !NET46 - let t = -#else - use t = -#endif - Task.Factory.StartNew(Action(fun () -> raise <| Exception())) + let result =Async.RunSynchronously(a) + (!hasBeenCalled && result) |> Assert.True + + [] + member _.NonGenericTaskAsyncValueException () = + use t = Task.Factory.StartNew(Action(fun () -> raise <| Exception())) let a = async { try let! v = Async.AwaitTask(t) return false with e -> return true } - Async.RunSynchronously(a, 3000) |> Assert.IsTrue - - [] - member this.NonGenericTaskAsyncValueCancellation () = - use ewh = new ManualResetEvent(false) + Async.RunSynchronously(a) |> Assert.True + + [] + member _.NonGenericTaskAsyncValueCancellation () = + use ewh = new ManualResetEvent(false) let cts = new CancellationTokenSource() let token = cts.Token -#if !NET46 - let t = -#else - use t = -#endif - Task.Factory.StartNew(Action(fun () -> while not token.IsCancellationRequested do ()), token) - let cancelled = ref true - let a = async { + use t = Task.Factory.StartNew(Action(fun () -> while not token.IsCancellationRequested do ()), token) + let a = + async { + try use! _holder = Async.OnCancel(fun _ -> ewh.Set() |> ignore) let! v = Async.AwaitTask(t) return v - } + // AwaitTask raises TaskCanceledException when it is canceled, it is a valid result of this test + with + :? TaskCanceledException -> + ewh.Set() |> ignore // this is ok + } Async.Start a cts.Cancel() - ewh.WaitOne(10000) |> ignore + ewh.WaitOne(10000) |> ignore + [] + member _.CancellationExceptionThrown () = + use ewh = new ManualResetEventSlim(false) + let cts = new CancellationTokenSource() + let token = cts.Token + let mutable hasThrown = false + token.Register(fun () -> ewh.Set() |> ignore) |> ignore + let a = async { + try + while true do token.ThrowIfCancellationRequested() + with _ -> hasThrown <- true + } + Async.Start(a, token) + cts.Cancel() + ewh.Wait(10000) |> ignore + Assert.False hasThrown + + [] + member _.NoStackOverflowOnRecursion() = + + let mutable hasThrown = false + let rec loop (x: int) = async { + do! Task.CompletedTask |> Async.AwaitTask + Console.WriteLine (if x = 10000 then failwith "finish" else x) + return! loop(x+1) + } + + try + Async.RunSynchronously (loop 0) + hasThrown <- false + with Failure "finish" -> + hasThrown <- true + Assert.True hasThrown diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Cancellation.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Cancellation.fs index 5afff678472..63e5025f105 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Cancellation.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Cancellation.fs @@ -1,43 +1,42 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control #nowarn "52" open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open System.Threading -[] type CancellationType() = - [] + [] member this.CancellationNoCallbacks() = let _ : CancellationTokenSource = null // compilation test use cts1 = new CancellationTokenSource() let token1 = cts1.Token - Assert.IsFalse (token1.IsCancellationRequested) + Assert.False (token1.IsCancellationRequested) use cts2 = new CancellationTokenSource() let token2 = cts2.Token - Assert.IsFalse (token2.IsCancellationRequested) + Assert.False (token2.IsCancellationRequested) cts1.Cancel() - Assert.IsTrue(token1.IsCancellationRequested) - Assert.IsFalse (token2.IsCancellationRequested) + Assert.True(token1.IsCancellationRequested) + Assert.False (token2.IsCancellationRequested) cts2.Cancel() - Assert.IsTrue(token2.IsCancellationRequested) + Assert.True(token2.IsCancellationRequested) - [] + [] member this.CancellationRegistration() = let cts = new CancellationTokenSource() let token = cts.Token let called = ref false let r = token.Register(Action(fun _ -> called := true), null) - Assert.IsFalse(!called) + Assert.False(!called) r.Dispose() cts.Cancel() - Assert.IsFalse(!called) + Assert.False(!called) - [] + [] member this.CancellationWithCallbacks() = let cts1 = new CancellationTokenSource() let cts2 = new CancellationTokenSource() @@ -48,8 +47,8 @@ type CancellationType() = let r1 = cts1.Token.Register(Action(fun _ -> is1Called := true), null) let r2 = cts1.Token.Register(Action(fun _ -> is2Called := true), null) let r3 = cts2.Token.Register(Action(fun _ -> is3Called := true), null) - Assert.IsFalse(!is1Called) - Assert.IsFalse(!is2Called) + Assert.False(!is1Called) + Assert.False(!is2Called) r2.Dispose() // Cancelling cts1: r2 is disposed and r3 is for cts2, only r1 should be called @@ -57,7 +56,7 @@ type CancellationType() = assertAndOff true is1Called assertAndOff false is2Called assertAndOff false is3Called - Assert.IsTrue(cts1.Token.IsCancellationRequested) + Assert.True(cts1.Token.IsCancellationRequested) let isAnotherOneCalled = ref false let _ = cts1.Token.Register(Action(fun _ -> isAnotherOneCalled := true), null) @@ -68,7 +67,7 @@ type CancellationType() = assertAndOff false is1Called assertAndOff false is2Called assertAndOff true is3Called - Assert.IsTrue(cts2.Token.IsCancellationRequested) + Assert.True(cts2.Token.IsCancellationRequested) // Cancelling cts1 again: no one should be called @@ -80,14 +79,14 @@ type CancellationType() = // Disposing let token = cts2.Token cts2.Dispose() - Assert.IsTrue(token.IsCancellationRequested) + Assert.True(token.IsCancellationRequested) let () = let mutable odeThrown = false try r3.Dispose() with | :? ObjectDisposedException -> odeThrown <- true - Assert.IsFalse(odeThrown) + Assert.False(odeThrown) let () = let mutable odeThrown = false @@ -95,10 +94,10 @@ type CancellationType() = cts2.Token.Register(Action(fun _ -> ()), null) |> ignore with | :? ObjectDisposedException -> odeThrown <- true - Assert.IsTrue(odeThrown) + Assert.True(odeThrown) () - [] + [] member this.CallbackOrder() = use cts = new CancellationTokenSource() let current = ref 0 @@ -108,7 +107,7 @@ type CancellationType() = cts.Token.Register(Action(action), box 0) |> ignore cts.Cancel() - [] + [] member this.CallbackExceptions() = use cts = new CancellationTokenSource() let action (o:obj) = new InvalidOperationException(String.Format("{0}", o)) |> raise @@ -121,31 +120,31 @@ type CancellationType() = with | :? AggregateException as ae -> exnThrown <- true - ae.InnerExceptions |> Seq.iter (fun e -> (e :? InvalidOperationException) |> Assert.IsTrue) + ae.InnerExceptions |> Seq.iter (fun e -> (e :? InvalidOperationException) |> Assert.True) let msgs = ae.InnerExceptions |> Seq.map (fun e -> e.Message) |> Seq.toList Assert.AreEqual(["2";"1";"0"], msgs) - Assert.IsTrue exnThrown - Assert.IsTrue cts.Token.IsCancellationRequested + Assert.True exnThrown + Assert.True cts.Token.IsCancellationRequested - [] + [] member this.LinkedSources() = let () = use cts1 = new CancellationTokenSource() use cts2 = new CancellationTokenSource() use ctsLinked = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token) let linkedToken = ctsLinked.Token - Assert.IsFalse(linkedToken.IsCancellationRequested) + Assert.False(linkedToken.IsCancellationRequested) cts1.Cancel() - Assert.IsTrue(linkedToken.IsCancellationRequested) + Assert.True(linkedToken.IsCancellationRequested) let () = use cts1 = new CancellationTokenSource() use cts2 = new CancellationTokenSource() use ctsLinked = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token) let linkedToken = ctsLinked.Token - Assert.IsFalse(linkedToken.IsCancellationRequested) + Assert.False(linkedToken.IsCancellationRequested) cts2.Cancel() - Assert.IsTrue(linkedToken.IsCancellationRequested) + Assert.True(linkedToken.IsCancellationRequested) let () = use cts1 = new CancellationTokenSource() @@ -153,10 +152,10 @@ type CancellationType() = cts1.Cancel() use ctsLinked = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token) let linkedToken = ctsLinked.Token - Assert.IsTrue(linkedToken.IsCancellationRequested) + Assert.True(linkedToken.IsCancellationRequested) let doExec = ref false linkedToken.Register(Action(fun _ -> doExec := true), null) |> ignore - Assert.IsTrue(!doExec) + Assert.True(!doExec) let () = use cts1 = new CancellationTokenSource() @@ -165,9 +164,9 @@ type CancellationType() = let linkedToken = ctsLinked.Token let doExec = ref false linkedToken.Register(Action(fun _ -> doExec := true), null) |> ignore - Assert.IsFalse(!doExec) + Assert.False(!doExec) cts1.Cancel() - Assert.IsTrue(!doExec) + Assert.True(!doExec) let () = use cts1 = new CancellationTokenSource() @@ -176,31 +175,31 @@ type CancellationType() = let token2 = cts2.Token use ctsLinked = CancellationTokenSource.CreateLinkedTokenSource(token1, token2) let linkedToken = ctsLinked.Token - Assert.IsFalse(linkedToken.IsCancellationRequested) + Assert.False(linkedToken.IsCancellationRequested) ctsLinked.Cancel() - Assert.IsTrue(linkedToken.IsCancellationRequested) - Assert.IsFalse(token1.IsCancellationRequested) - Assert.IsFalse(token2.IsCancellationRequested) + Assert.True(linkedToken.IsCancellationRequested) + Assert.False(token1.IsCancellationRequested) + Assert.False(token2.IsCancellationRequested) () - [] + [] member this.TestCancellationRace() = use cts = new CancellationTokenSource() let token = cts.Token let callbackRun = ref false let reg = token.Register(Action(fun _ -> lock callbackRun (fun() -> - Assert.IsFalse(!callbackRun, "Callback should run only once") + Assert.False(!callbackRun, "Callback should run only once") callbackRun := true ) ), null) - Assert.IsFalse(!callbackRun) + Assert.False(!callbackRun) let asyncs = seq { for i in 1..1000 do yield async { cts.Cancel() } } asyncs |> Async.Parallel |> Async.RunSynchronously |> ignore - Assert.IsTrue(!callbackRun, "Callback should run at least once") + Assert.True(!callbackRun, "Callback should run at least once") - [] + [] member this.TestRegistrationRace() = let asyncs = seq { for _ in 1..1000 do @@ -208,14 +207,14 @@ type CancellationType() = let token = cts.Token yield async { cts.Cancel() } let callback (_:obj) = - Assert.IsTrue(token.IsCancellationRequested) + Assert.True(token.IsCancellationRequested) yield async { do token.Register(Action(callback), null) |> ignore } } (asyncs |> Async.Parallel |> Async.RunSynchronously |> ignore) - [] + [] member this.LinkedSourceCancellationRace() = let asyncs = seq { for _ in 1..1000 do @@ -229,7 +228,7 @@ type CancellationType() = } asyncs |> Async.Parallel |> Async.RunSynchronously |> ignore - [] + [] member this.AwaitTaskCancellationAfterAsyncTokenCancellation() = let StartCatchCancellation cancellationToken (work) = Async.FromContinuations(fun (cont, econt, _) -> @@ -284,28 +283,28 @@ type CancellationType() = Assert.Fail (msg) with :? AggregateException as agg -> () - [] + [] member this.Equality() = let cts1 = new CancellationTokenSource() let cts2 = new CancellationTokenSource() let t1a = cts1.Token let t1b = cts1.Token let t2 = cts2.Token - Assert.IsTrue((t1a = t1b)) - Assert.IsFalse(t1a <> t1b) - Assert.IsTrue(t1a <> t2) - Assert.IsFalse((t1a = t2)) + Assert.True((t1a = t1b)) + Assert.False(t1a <> t1b) + Assert.True(t1a <> t2) + Assert.False((t1a = t2)) let r1a = t1a.Register(Action(fun _ -> ()), null) let r1b = t1b.Register(Action(fun _ -> ()), null) let r2 = t2.Register(Action(fun _ -> ()), null) let r1a' = r1a - Assert.IsTrue((r1a = r1a')) - Assert.IsFalse((r1a = r1b)) - Assert.IsFalse((r1a = r2)) + Assert.True((r1a = r1a')) + Assert.False((r1a = r1b)) + Assert.False((r1a = r2)) - Assert.IsFalse((r1a <> r1a')) - Assert.IsTrue((r1a <> r1b)) - Assert.IsTrue((r1a <> r2)) + Assert.False((r1a <> r1a')) + Assert.True((r1a <> r1b)) + Assert.True((r1a <> r2)) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventModule.fs index 84ac5f34e6e..5f135ec22b6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Control.Event module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -30,10 +30,9 @@ type MultiArgDelegate4 = delegate of obj * int * string * bool * int -> unit type MultiArgDelegate5 = delegate of obj * int * string * bool * int * string -> unit type MultiArgDelegate6 = delegate of obj * int * string * bool * int * string * bool -> unit -[] type EventModule() = - [] + [] member this.Choose() = let coffeeCup = new EventfulCoffeeCup(10.0, 10.0) @@ -64,7 +63,7 @@ type EventModule() = () - [] + [] member this.Filter() = let kexp = new RadioStation(90.3, "KEXP") @@ -89,7 +88,7 @@ type EventModule() = "Flight of the Penguins - song 1"]) () - [] + [] member this.Listen() = let kqfc = new RadioStation(90.3, "KEXP") @@ -111,7 +110,7 @@ type EventModule() = () - [] + [] member this.Map() = let numEvent = new Event() @@ -131,7 +130,7 @@ type EventModule() = Assert.AreEqual(!results, "333221") () - [] + [] member this.Merge() = let evensEvent = new Event() @@ -151,7 +150,7 @@ type EventModule() = () - [] + [] member this.Pairwise() = let numEvent = new Event() @@ -173,7 +172,7 @@ type EventModule() = () - [] + [] member this.Partition() = let numEvent = new Event() @@ -196,7 +195,7 @@ type EventModule() = () - [] + [] member this.Scan() = let numEvent = new Event() @@ -219,7 +218,7 @@ type EventModule() = () - [] + [] member this.Split() = let numEvent = new Event() @@ -241,14 +240,14 @@ type EventModule() = () - [] + [] member this.InternalDelegate() = let event = new Event() let p = event.Publish use s = p.Subscribe(fun _ -> ()) event.Trigger(null, ()) - [] + [] member this.MultipleArguments() = let count = ref 0 let test (evt : Event<_, _>) arg = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventTypes.fs new file mode 100644 index 00000000000..69cb4d65143 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/EventTypes.fs @@ -0,0 +1,77 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the: +// Microsoft.FSharp.Control event types + +namespace FSharp.Core.UnitTests.Control + +open System +open System.Reflection +open Xunit + +module private EventTypes = + type MultiArgDelegate = delegate of obj * obj[] -> unit + + let getListeners event = + let eventType = event.GetType() + let multicastField = + eventType + .GetField("multicast", BindingFlags.NonPublic ||| BindingFlags.Instance) + .GetValue event + :?> System.Delegate + + if not (isNull multicastField) then + let multicastType = typeof + let listeners = + multicastType + .GetMethod("GetInvocationList") + .Invoke(multicastField, [||]) + :?> System.Delegate [] + Some listeners + else + None + +type EventTypes() = + + [] + let RunsCount = 100 + + let runAddRemoveHandlers (event: IDelegateEvent<_>) handlerInitializer = + seq { + for _ in 1 .. RunsCount do + async { + let h = handlerInitializer() + event.AddHandler(h) + event.RemoveHandler(h) + } + } |> Async.Parallel |> Async.RunSynchronously |> ignore + + [] + member this.``Adding/removing handlers to published Event<'T> is thread-safe``() = + let event = new Event() + let listenersBefore = EventTypes.getListeners event + runAddRemoveHandlers (event.Publish) (fun _ -> new Handler<_>(fun sender args -> ())) + let listenersAfter = EventTypes.getListeners event + + Assert.True(listenersBefore.IsNone) + Assert.True(listenersAfter.IsNone) + + [] + member this.``Adding/removing handlers to published DelegateEvent is thread-safe``() = + let event = new DelegateEvent<_>() + let listenersBefore = EventTypes.getListeners event + runAddRemoveHandlers (event.Publish) (fun _ -> EventTypes.MultiArgDelegate(fun sender args -> ())) + let listenersAfter = EventTypes.getListeners event + + Assert.True(listenersBefore.IsNone) + Assert.True(listenersAfter.IsNone) + + [] + member this.``Adding/removing handlers to published Event<'D,'A> is thread-safe``() = + let event = new Event<_, _>() + let listenersBefore = EventTypes.getListeners event + runAddRemoveHandlers (event.Publish) (fun _ -> EventTypes.MultiArgDelegate(fun sender args -> ())) + let listenersAfter = EventTypes.getListeners event + + Assert.True(listenersBefore.IsNone) + Assert.True(listenersAfter.IsNone) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs index 4e114adfa35..30643db5499 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/LazyType.fs @@ -1,17 +1,16 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System -open NUnit.Framework +open Xunit open Microsoft.FSharp.Collections open FSharp.Core.UnitTests.LibraryTestFx -[] type LazyType() = - [] + [] member this.Create() = // int @@ -26,7 +25,7 @@ type LazyType() = let nullLazy = Lazy<_>.Create(fun () -> ()) Assert.AreEqual(nullLazy.Value, null) - [] + [] member this.CreateFromValue() = // int @@ -42,7 +41,7 @@ type LazyType() = Assert.AreEqual(nullLazy.Value,null) - [] + [] member this.Force() = // int @@ -60,7 +59,7 @@ type LazyType() = let nullForce = nullLazy.Force() Assert.AreEqual(nullForce,null) - [] + [] member this.Value() = // int @@ -75,7 +74,7 @@ type LazyType() = let nullLazy = Lazy<_>.CreateFromValue(null) Assert.AreEqual(nullLazy.Value,null) - [] + [] member this.IsDelayed() = // int @@ -97,7 +96,7 @@ type LazyType() = let resultIsDelayed = nullLazy.Force() Assert.AreEqual(not nullLazy.IsValueCreated,false) - [] + [] member this.IsForced() = // int @@ -119,7 +118,7 @@ type LazyType() = let resultIsForced = nullLazy.Force() Assert.AreEqual( nullLazy.IsValueCreated,true) - [] + [] member this.Printing() = let n = lazy 12 Assert.AreEqual( n.IsValueCreated, false ) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 5dfafab8770..c887eb470c8 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -3,20 +3,17 @@ // Various tests for the: // Microsoft.FSharp.Control.MailboxProcessor type -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System -open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open System.Threading -open System.Collections.Generic type Message = | Increment of int | Fetch of AsyncReplyChannel | Reset -[] type MailboxProcessorType() = let getSimpleMailbox() = @@ -40,7 +37,7 @@ type MailboxProcessorType() = ) mailbox - [] + [] member this.DefaultTimeout() = let mailbox = getSimpleMailbox() @@ -69,18 +66,24 @@ type MailboxProcessorType() = () - [] + [] member this.``Receive handles cancellation token``() = - let result = ref None - + let mutable result = None + use mre1 = new ManualResetEventSlim(false) + use mre2 = new ManualResetEventSlim(false) + // https://github.com/Microsoft/visualfsharp/issues/3337 let cts = new CancellationTokenSource () - + let addMsg msg = - match !result with - | Some text -> result := Some(text + " " + msg) - | None -> result := Some msg - + match result with + | Some text -> + //printfn "Got some, adding %s" msg + result <- Some(text + " " + msg) + | None -> + //printfn "got none, setting %s" msg + result <- Some msg + let mb = MailboxProcessor.Start ( fun inbox -> async { @@ -88,32 +91,41 @@ type MailboxProcessorType() = { new IDisposable with member this.Dispose () = addMsg "Disposed" + mre2.Set() } - + while true do - let! (msg : int) = inbox.Receive () + let! (msg : int) = inbox.Receive() addMsg (sprintf "Received %i" msg) + mre1.Set() }, cancellationToken = cts.Token) + + mb.Post(1) + mre1.Wait() + + cts.Cancel() + mre2.Wait() - mb.Post 1 - Thread.Sleep 1000 - cts.Cancel () - Thread.Sleep 4000 - - Assert.AreEqual(Some("Received 1 Disposed"), !result) + Assert.AreEqual(Some("Received 1 Disposed"), result) - [] + [] member this.``Receive with timeout argument handles cancellation token``() = - let result = ref None - + let mutable result = None + use mre1 = new ManualResetEventSlim(false) + use mre2 = new ManualResetEventSlim(false) + // https://github.com/Microsoft/visualfsharp/issues/3337 let cts = new CancellationTokenSource () - + let addMsg msg = - match !result with - | Some text -> result := Some(text + " " + msg) - | None -> result := Some msg - + match result with + | Some text -> + //printfn "Got some, adding %s" msg + result <- Some(text + " " + msg) + | None -> + //printfn "got none, setting %s" msg + result <- Some msg + let mb = MailboxProcessor.Start ( fun inbox -> async { @@ -121,31 +133,40 @@ type MailboxProcessorType() = { new IDisposable with member this.Dispose () = addMsg "Disposed" + mre2.Set() } - + while true do - let! (msg : int) = inbox.Receive (100000) + let! (msg : int) = inbox.Receive(100000) addMsg (sprintf "Received %i" msg) + mre1.Set() }, cancellationToken = cts.Token) + + mb.Post(1) + mre1.Wait() + + cts.Cancel() + mre2.Wait() - mb.Post 1 - Thread.Sleep 1000 - cts.Cancel () - Thread.Sleep 4000 + Assert.AreEqual(Some("Received 1 Disposed"), result) - Assert.AreEqual(Some("Received 1 Disposed"),!result) - - [] + [] member this.``Scan handles cancellation token``() = - let result = ref None + let mutable result = None + use mre1 = new ManualResetEventSlim(false) + use mre2 = new ManualResetEventSlim(false) // https://github.com/Microsoft/visualfsharp/issues/3337 let cts = new CancellationTokenSource () let addMsg msg = - match !result with - | Some text -> result := Some(text + " " + msg) - | None -> result := Some msg + match result with + | Some text -> + //printfn "Got some, adding %s" msg + result <- Some(text + " " + msg) + | None -> + //printfn "got none, setting %s" msg + result <- Some msg let mb = MailboxProcessor.Start ( @@ -154,21 +175,24 @@ type MailboxProcessorType() = { new IDisposable with member this.Dispose () = addMsg "Disposed" + mre2.Set() } while true do let! (msg : int) = inbox.Scan (fun msg -> Some(async { return msg }) ) addMsg (sprintf "Scanned %i" msg) + mre1.Set() }, cancellationToken = cts.Token) - mb.Post 1 - Thread.Sleep 1000 - cts.Cancel () - Thread.Sleep 4000 + mb.Post(1) + mre1.Wait() + + cts.Cancel() + mre2.Wait() - Assert.AreEqual(Some("Scanned 1 Disposed"), !result) + Assert.AreEqual(Some("Scanned 1 Disposed"), result) - [] + [] member this.``Receive Races with Post``() = let receiveEv = new ManualResetEvent(false) let postEv = new ManualResetEvent(false) @@ -200,7 +224,7 @@ type MailboxProcessorType() = finishedEv.WaitOne() |> ignore finishedEv.Reset() |> ignore - [] + [] member this.``Receive Races with Post on timeout``() = let receiveEv = new ManualResetEvent(false) let postEv = new ManualResetEvent(false) @@ -239,7 +263,7 @@ type MailboxProcessorType() = finishedEv.Reset() |> ignore - [] + [] member this.``TryReceive Races with Post on timeout``() = let receiveEv = new ManualResetEvent(false) let postEv = new ManualResetEvent(false) @@ -278,7 +302,7 @@ type MailboxProcessorType() = finishedEv.Reset() |> ignore - [] + [] member this.Dispose() = // No unit test actually hit the Dispose method for the Mailbox... @@ -292,7 +316,7 @@ type MailboxProcessorType() = test() - //[] // need to re-visit this + [] member this.PostAndAsyncReply_Cancellation() = use cancel = new CancellationTokenSource(500) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/ObservableModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/ObservableModule.fs index 4562af90b7b..3280e565f32 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/ObservableModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/ObservableModule.fs @@ -3,11 +3,11 @@ // Various tests for the: // Microsoft.FSharp.Control.Observable module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control +namespace FSharp.Core.UnitTests.Control open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit (* [Test Strategy] @@ -77,11 +77,9 @@ type RadioStation(frequency, callsign) = member this.BroadcastSignal = m_broadcastEvent.Publish // --------------------------------------------------- - -[] type ObservableModule() = - [] + [] member this.Choose() = let coffeeCup = new EventfulCoffeeCup(10.0, 10.0) @@ -112,7 +110,7 @@ type ObservableModule() = () - [] + [] member this.Filter() = let kexp = new RadioStation(90.3, "KEXP") @@ -137,7 +135,7 @@ type ObservableModule() = "Flight of the Penguins - song 1"]) () - [] + [] member this.Listen() = let kqfc = new RadioStation(90.3, "KEXP") @@ -159,7 +157,7 @@ type ObservableModule() = () - [] + [] member this.Map() = let numEvent = new Event() @@ -179,7 +177,7 @@ type ObservableModule() = Assert.AreEqual(!results, "333221") () - [] + [] member this.Merge() = let evensEvent = new Event() @@ -199,7 +197,7 @@ type ObservableModule() = () - [] + [] member this.Pairwise() = let numEvent = new Event() @@ -221,7 +219,7 @@ type ObservableModule() = () - [] + [] member this.Partition() = let numEvent = new Event() @@ -244,7 +242,7 @@ type ObservableModule() = () - [] + [] member this.Scan() = let numEvent = new Event() @@ -267,7 +265,7 @@ type ObservableModule() = () - [] + [] member this.Split() = let numEvent = new Event() diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Tasks.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Tasks.fs new file mode 100644 index 00000000000..fec401e7082 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/Tasks.fs @@ -0,0 +1,1325 @@ +// Tests for TaskBuilder.fs +// +// Written in 2016 by Robert Peele (humbobst@gmail.com) +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights +// to this software to the public domain worldwide. This software is distributed without any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication along with this software. +// If not, see . + + +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the: +// Microsoft.FSharp.Control.Async type + +namespace FSharp.Core.UnitTests.Control.Tasks + +open System +open System.Collections +open System.Collections.Generic +open System.Diagnostics +open System.Threading +open System.Threading.Tasks +open Microsoft.FSharp.Control +#if STANDALONE +[] +type FactAttribute() = inherit Attribute() +#else +open Xunit +#endif + + +type ITaskThing = + abstract member Taskify : 'a option -> 'a Task + +#if NETCOREAPP +type SupportBothDisposables() = + let mutable called = false + interface IAsyncDisposable with + member __.DisposeAsync() = + task { + System.Console.WriteLine "incrementing" + called <- true } + |> ValueTask + interface IDisposable with + member __.Dispose() = failwith "dispose" + member x.Disposed = called +#endif +type SmokeTestsForCompilation() = + + [] + member __.tinyTask() = + task { + return 1 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tbind() = + task { + let! x = Task.FromResult(1) + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.tnested() = + task { + let! x = task { return 1 } + return x + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tcatch0() = + task { + try + return 1 + with e -> + return 2 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tcatch1() = + task { + try + let! x = Task.FromResult 1 + return x + with e -> + return 2 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + + [] + member __.t3() = + let t2() = + task { + System.Console.WriteLine("hello") + return 1 + } + task { + System.Console.WriteLine("hello") + let! x = t2() + System.Console.WriteLine("world") + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.t3b() = + task { + System.Console.WriteLine("hello") + let! x = Task.FromResult(1) + System.Console.WriteLine("world") + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.t3c() = + task { + System.Console.WriteLine("hello") + do! Task.Delay(100) + System.Console.WriteLine("world") + return 1 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + // This tests an exception match + member __.t67() = + task { + try + do! Task.Delay(0) + with + | :? ArgumentException -> + () + | _ -> + () + } + |> fun t -> + t.Wait() + if t.Result <> () then failwith "failed" + + [] + // This tests compiling an incomplete exception match + member __.t68() = + task { + try + do! Task.Delay(0) + with + | :? ArgumentException -> + () + } + |> fun t -> + t.Wait() + if t.Result <> () then failwith "failed" + + [] + member __.testCompileAsyncWhileLoop() = + task { + let mutable i = 0 + while i < 5 do + i <- i + 1 + do! Task.Yield() + return i + } + |> fun t -> + t.Wait() + if t.Result <> 5 then failwith "failed" + + +exception TestException of string + +[] +module Helpers = + let BIG = 10 + // let BIG = 10000 + let require x msg = if not x then failwith msg + let failtest str = raise (TestException str) + +type Basics() = + [] + member __.testShortCircuitResult() = + printfn "Running testShortCircuitResult..." + let t = + task { + let! x = Task.FromResult(1) + let! y = Task.FromResult(2) + return x + y + } + require t.IsCompleted "didn't short-circuit already completed tasks" + printfn "t.Result = %A" t.Result + require (t.Result = 3) "wrong result" + + [] + member __.testDelay() = + printfn "Running testDelay..." + let mutable x = 0 + let t = + task { + do! Task.Delay(50) + x <- x + 1 + } + printfn "task created and first step run...." + require (x = 0) "task already ran" + printfn "waiting...." + t.Wait() + + [] + member __.testNoDelay() = + printfn "Running testNoDelay..." + let mutable x = 0 + let t = + task { + x <- x + 1 + do! Task.Delay(5) + x <- x + 1 + } + require (x = 1) "first part didn't run yet" + t.Wait() + + [] + member __.testNonBlocking() = + printfn "Running testNonBlocking..." + let sw = Stopwatch() + sw.Start() + let t = + task { + do! Task.Yield() + Thread.Sleep(100) + } + sw.Stop() + require (sw.ElapsedMilliseconds < 50L) "sleep blocked caller" + t.Wait() + + [] + member __.testCatching1() = + printfn "Running testCatching1..." + let mutable x = 0 + let mutable y = 0 + let t = + task { + try + do! Task.Delay(0) + failtest "hello" + x <- 1 + do! Task.Delay(100) + with + | TestException msg -> + require (msg = "hello") "message tampered" + | _ -> + require false "other exn type" + require false "other exn type" + y <- 1 + } + t.Wait() + require (y = 1) "bailed after exn" + require (x = 0) "ran past failure" + + [] + member __.testCatching2() = + printfn "Running testCatching2..." + let mutable x = 0 + let mutable y = 0 + let t = + task { + try + do! Task.Yield() // can't skip through this + failtest "hello" + x <- 1 + do! Task.Delay(100) + with + | TestException msg -> + require (msg = "hello") "message tampered" + | _ -> + require false "other exn type" + y <- 1 + } + t.Wait() + require (y = 1) "bailed after exn" + require (x = 0) "ran past failure" + + [] + member __.testNestedCatching() = + printfn "Running testNestedCatching..." + let mutable counter = 1 + let mutable caughtInner = 0 + let mutable caughtOuter = 0 + let t1() = + task { + try + do! Task.Yield() + failtest "hello" + with + | TestException msg as exn -> + caughtInner <- counter + counter <- counter + 1 + raise exn + } + let t2 = + task { + try + do! t1() + with + | TestException msg as exn -> + caughtOuter <- counter + raise exn + | e -> + require false (sprintf "invalid msg type %s" e.Message) + } + try + t2.Wait() + require false "ran past failed task wait" + with + | :? AggregateException as exn -> + require (exn.InnerExceptions.Count = 1) "more than 1 exn" + require (caughtInner = 1) "didn't catch inner" + require (caughtOuter = 2) "didn't catch outer" + + [] + member __.testWhileLoopSync() = + printfn "Running testWhileLoopSync..." + let t = + task { + let mutable i = 0 + while i < 10 do + i <- i + 1 + return i + } + //t.Wait() no wait required for sync loop + require (t.IsCompleted) "didn't do sync while loop properly - not completed" + require (t.Result = 10) "didn't do sync while loop properly - wrong result" + + [] + member __.testWhileLoopAsyncZeroIteration() = + printfn "Running testWhileLoopAsyncZeroIteration..." + for i in 1 .. 5 do + let t = + task { + let mutable i = 0 + while i < 0 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 0) "didn't do while loop properly" + + [] + member __.testWhileLoopAsyncOneIteration() = + printfn "Running testWhileLoopAsyncOneIteration..." + for i in 1 .. 5 do + let t = + task { + let mutable i = 0 + while i < 1 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 1) "didn't do while loop properly" + + [] + member __.testWhileLoopAsync() = + printfn "Running testWhileLoopAsync..." + for i in 1 .. 5 do + let t = + task { + let mutable i = 0 + while i < 10 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 10) "didn't do while loop properly" + + [] + member __.testTryFinallyHappyPath() = + printfn "Running testTryFinallyHappyPath..." + for i in 1 .. 5 do + let mutable ran = false + let t = + task { + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + finally + ran <- true + } + t.Wait() + require ran "never ran" + [] + member __.testTryFinallySadPath() = + printfn "Running testTryFinallySadPath..." + for i in 1 .. 5 do + let mutable ran = false + let t = + task { + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + failtest "uhoh" + finally + ran <- true + } + try + t.Wait() + with + | _ -> () + require ran "never ran" + + [] + member __.testTryFinallyCaught() = + printfn "Running testTryFinallyCaught..." + for i in 1 .. 5 do + let mutable ran = false + let t = + task { + try + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + failtest "uhoh" + finally + ran <- true + return 1 + with + | _ -> return 2 + } + require (t.Result = 2) "wrong return" + require ran "never ran" + + [] + member __.testUsing() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = false + let t = + task { + use d = { new IDisposable with member __.Dispose() = disposed <- true } + require (not disposed) "disposed way early" + do! Task.Delay(100) + require (not disposed) "disposed kinda early" + } + t.Wait() + require disposed "never disposed B" + +#if NETCOREAPP + [] + member __.testUsingAsyncDisposableSync() = + printfn "Running testUsingAsyncDisposableSync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + System.Console.WriteLine "incrementing" + disposed <- disposed + 1 } + |> ValueTask + } + require (disposed = 0) "disposed way early" + System.Console.WriteLine "delaying" + do! Task.Delay(100) + System.Console.WriteLine "testing" + require (disposed = 0) "disposed kinda early" + } + t.Wait() + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableAsync() = + printfn "Running testUsingAsyncDisposableAsync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + do! Task.Delay(10) + disposed <- disposed + 1 + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + do! Task.Delay(100) + require (disposed = 0) "disposed kinda early" + } + t.Wait() + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableExnAsync() = + printfn "Running testUsingAsyncDisposableExnAsync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + do! Task.Delay(10) + disposed <- disposed + 1 + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableExnSync() = + printfn "Running testUsingAsyncDisposableExnSync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + disposed <- disposed + 1 + do! Task.Delay(10) + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableDelayExnSync() = + printfn "Running testUsingAsyncDisposableDelayExnSync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + disposed <- disposed + 1 + do! Task.Delay(10) + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + do! Task.Delay(10) + require (disposed = 0) "disposed kind of early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + // Test use! resolves + member __.testUsingBindAsyncDisposableSync() = + printfn "Running testUsingBindAsyncDisposableSync..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + task { + use! d = + task { + do! Task.Delay(10) + return + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + System.Console.WriteLine "incrementing" + disposed <- disposed + 1 } + |> ValueTask + } + } + require (disposed = 0) "disposed way early" + System.Console.WriteLine "delaying" + do! Task.Delay(100) + System.Console.WriteLine "testing" + require (disposed = 0) "disposed kinda early" + } + t.Wait() + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableSyncSupportingBothDisposables() = + printfn "Running testUsingAsyncDisposableSyncSupportingBothDisposables..." + for i in 1 .. 5 do + let disp = new SupportBothDisposables() + let t = + task { + use d = disp + require (not disp.Disposed) "disposed way early" + System.Console.WriteLine "delaying" + do! Task.Delay(100) + System.Console.WriteLine "testing" + require (not disp.Disposed) "disposed kinda early" + } + t.Wait() + require disp.Disposed "never disposed B" +#endif + + [] + member __.testUsingFromTask() = + printfn "Running testUsingFromTask..." + let mutable disposedInner = false + let mutable disposed = false + let t = + task { + use! d = + task { + do! Task.Delay(50) + use i = { new IDisposable with member __.Dispose() = disposedInner <- true } + require (not disposed && not disposedInner) "disposed inner early" + return { new IDisposable with member __.Dispose() = disposed <- true } + } + require disposedInner "did not dispose inner after task completion" + require (not disposed) "disposed way early" + do! Task.Delay(50) + require (not disposed) "disposed kinda early" + } + t.Wait() + require disposed "never disposed C" + + [] + member __.testUsingSadPath() = + printfn "Running testUsingSadPath..." + let mutable disposedInner = false + let mutable disposed = false + let t = + task { + try + use! d = + task { + do! Task.Delay(50) + use i = { new IDisposable with member __.Dispose() = disposedInner <- true } + failtest "uhoh" + require (not disposed && not disposedInner) "disposed inner early" + return { new IDisposable with member __.Dispose() = disposed <- true } + } + () + with + | TestException msg -> + printfn "caught TestException" + require disposedInner "did not dispose inner after task completion" + require (not disposed) "disposed way early" + do! Task.Delay(50) + printfn "resumed after delay" + require (not disposed) "disposed kinda early" + } + t.Wait() + require (not disposed) "disposed thing that never should've existed" + + [] + member __.testForLoopA() = + printfn "Running testForLoopA..." + let list = ["a"; "b"; "c"] |> Seq.ofList + let t = + task { + printfn "entering loop..." + let mutable x = Unchecked.defaultof<_> + let e = list.GetEnumerator() + while e.MoveNext() do + x <- e.Current + printfn "x = %A" x + do! Task.Yield() + printfn "x = %A" x + } + t.Wait() + + [] + member __.testForLoopComplex() = + printfn "Running testForLoopComplex..." + let mutable disposed = false + let wrapList = + let raw = ["a"; "b"; "c"] |> Seq.ofList + let getEnumerator() = + let raw = raw.GetEnumerator() + { new IEnumerator with + member __.MoveNext() = + require (not disposed) "moved next after disposal" + raw.MoveNext() + member __.Current = + require (not disposed) "accessed current after disposal" + raw.Current + member __.Current = + require (not disposed) "accessed current (boxed) after disposal" + box raw.Current + member __.Dispose() = + require (not disposed) "disposed twice" + disposed <- true + raw.Dispose() + member __.Reset() = + require (not disposed) "reset after disposal" + raw.Reset() + } + { new IEnumerable with + member __.GetEnumerator() : IEnumerator = getEnumerator() + member __.GetEnumerator() : IEnumerator = upcast getEnumerator() + } + let t = + task { + let mutable index = 0 + do! Task.Yield() + printfn "entering loop..." + for x in wrapList do + printfn "x = %A, index = %d" x index + do! Task.Yield() + printfn "back from yield" + do! Task.Yield() + printfn "back from yield" + match index with + | 0 -> require (x = "a") "wrong first value" + | 1 -> require (x = "b") "wrong second value" + | 2 -> require (x = "c") "wrong third value" + | _ -> require false "iterated too far!" + index <- index + 1 + printfn "yield again" + do! Task.Yield() + printfn "yield again again" + do! Task.Yield() + printfn "looping again..." + do! Task.Yield() + return 1 + } + t.Wait() + require disposed "never disposed D" + require (t.Result = 1) "wrong result" + + [] + member __.testForLoopSadPath() = + printfn "Running testForLoopSadPath..." + for i in 1 .. 5 do + let wrapList = ["a"; "b"; "c"] + let t = + task { + let mutable index = 0 + do! Task.Yield() + for x in wrapList do + do! Task.Yield() + index <- index + 1 + return 1 + } + require (t.Result = 1) "wrong result" + + [] + member __.testForLoopSadPathComplex() = + printfn "Running testForLoopSadPathComplex..." + for i in 1 .. 5 do + let mutable disposed = false + let wrapList = + let raw = ["a"; "b"; "c"] |> Seq.ofList + let getEnumerator() = + let raw = raw.GetEnumerator() + { new IEnumerator with + member __.MoveNext() = + require (not disposed) "moved next after disposal" + raw.MoveNext() + member __.Current = + require (not disposed) "accessed current after disposal" + raw.Current + member __.Current = + require (not disposed) "accessed current (boxed) after disposal" + box raw.Current + member __.Dispose() = + require (not disposed) "disposed twice" + disposed <- true + raw.Dispose() + member __.Reset() = + require (not disposed) "reset after disposal" + raw.Reset() + } + { new IEnumerable with + member __.GetEnumerator() : IEnumerator = getEnumerator() + member __.GetEnumerator() : IEnumerator = upcast getEnumerator() + } + let mutable caught = false + let t = + task { + try + let mutable index = 0 + do! Task.Yield() + for x in wrapList do + do! Task.Yield() + match index with + | 0 -> require (x = "a") "wrong first value" + | _ -> failtest "uhoh" + index <- index + 1 + do! Task.Yield() + do! Task.Yield() + return 1 + with + | TestException "uhoh" -> + caught <- true + return 2 + } + require (t.Result = 2) "wrong result" + require caught "didn't catch exception" + require disposed "never disposed A" + + [] + member __.testExceptionAttachedToTaskWithoutAwait() = + for i in 1 .. 5 do + let mutable ranA = false + let mutable ranB = false + let t = + task { + ranA <- true + failtest "uhoh" + ranB <- true + } + require ranA "didn't run immediately" + require (not ranB) "ran past exception" + require (not (isNull t.Exception)) "didn't capture exception" + require (t.Exception.InnerExceptions.Count = 1) "captured more exceptions" + require (t.Exception.InnerException = TestException "uhoh") "wrong exception" + let mutable caught = false + let mutable ranCatcher = false + let catcher = + task { + try + ranCatcher <- true + let! result = t + return false + with + | TestException "uhoh" -> + caught <- true + return true + } + require ranCatcher "didn't run" + require catcher.Result "didn't catch" + require caught "didn't catch" + + [] + member __.testExceptionAttachedToTaskWithAwait() = + printfn "running testExceptionAttachedToTaskWithAwait" + for i in 1 .. 5 do + let mutable ranA = false + let mutable ranB = false + let t = + task { + ranA <- true + failtest "uhoh" + do! Task.Delay(100) + ranB <- true + } + require ranA "didn't run immediately" + require (not ranB) "ran past exception" + require (not (isNull t.Exception)) "didn't capture exception" + require (t.Exception.InnerExceptions.Count = 1) "captured more exceptions" + require (t.Exception.InnerException = TestException "uhoh") "wrong exception" + let mutable caught = false + let mutable ranCatcher = false + let catcher = + task { + try + ranCatcher <- true + let! result = t + return false + with + | TestException "uhoh" -> + caught <- true + return true + } + require ranCatcher "didn't run" + require catcher.Result "didn't catch" + require caught "didn't catch" + + [] + member __.testExceptionThrownInFinally() = + printfn "running testExceptionThrownInFinally" + for i in 1 .. 5 do + let mutable ranInitial = false + let mutable ranNext = false + let mutable ranFinally = 0 + let t = + task { + try + ranInitial <- true + do! Task.Yield() + Thread.Sleep(100) // shouldn't be blocking so we should get through to requires before this finishes + ranNext <- true + finally + ranFinally <- ranFinally + 1 + failtest "finally exn!" + } + require ranInitial "didn't run initial" + require (not ranNext) "ran next too early" + try + t.Wait() + require false "shouldn't get here" + with + | _ -> () + require ranNext "didn't run next" + require (ranFinally = 1) "didn't run finally exactly once" + + [] + member __.test2ndExceptionThrownInFinally() = + printfn "running test2ndExceptionThrownInFinally" + for i in 1 .. 5 do + let mutable ranInitial = false + let mutable ranNext = false + let mutable ranFinally = 0 + let t = + task { + try + ranInitial <- true + do! Task.Yield() + Thread.Sleep(100) // shouldn't be blocking so we should get through to requires before this finishes + ranNext <- true + failtest "uhoh" + finally + ranFinally <- ranFinally + 1 + failtest "2nd exn!" + } + require ranInitial "didn't run initial" + require (not ranNext) "ran next too early" + try + t.Wait() + require false "shouldn't get here" + with + | _ -> () + require ranNext "didn't run next" + require (ranFinally = 1) "didn't run finally exactly once" + + [] + member __.testFixedStackWhileLoop() = + printfn "running testFixedStackWhileLoop" + for i in 1 .. 100 do + let t = + task { + let mutable maxDepth = Nullable() + let mutable i = 0 + while i < BIG do + i <- i + 1 + do! Task.Yield() + if i % 100 = 0 then + let stackDepth = StackTrace().FrameCount + if maxDepth.HasValue && stackDepth > maxDepth.Value then + failwith "Stack depth increased!" + maxDepth <- Nullable(stackDepth) + return i + } + t.Wait() + require (t.Result = BIG) "didn't get to big number" + + [] + member __.testFixedStackForLoop() = + for i in 1 .. 100 do + printfn "running testFixedStackForLoop" + let mutable ran = false + let t = + task { + let mutable maxDepth = Nullable() + for i in Seq.init BIG id do + do! Task.Yield() + if i % 100 = 0 then + let stackDepth = StackTrace().FrameCount + if maxDepth.HasValue && stackDepth > maxDepth.Value then + failwith "Stack depth increased!" + maxDepth <- Nullable(stackDepth) + ran <- true + return () + } + t.Wait() + require ran "didn't run all" + + [] + member __.testTypeInference() = + let t1 : string Task = + task { + return "hello" + } + let t2 = + task { + let! s = t1 + return s.Length + } + t2.Wait() + + [] + member __.testNoStackOverflowWithImmediateResult() = + printfn "running testNoStackOverflowWithImmediateResult" + let longLoop = + task { + let mutable n = 0 + while n < BIG do + n <- n + 1 + return! Task.FromResult(()) + } + longLoop.Wait() + + [] + member __.testNoStackOverflowWithYieldResult() = + printfn "running testNoStackOverflowWithYieldResult" + let longLoop = + task { + let mutable n = 0 + while n < BIG do + let! _ = + task { + do! Task.Yield() + let! _ = Task.FromResult(0) + n <- n + 1 + } + n <- n + 1 + } + longLoop.Wait() + + [] + member __.testSmallTailRecursion() = + printfn "running testSmallTailRecursion" + let rec loop n = + task { + if n < 100 then + do! Task.Yield() + let! _ = Task.FromResult(0) + return! loop (n + 1) + else + return () + } + let shortLoop = + task { + return! loop 0 + } + shortLoop.Wait() + + [] + member __.testTryOverReturnFrom() = + printfn "running testTryOverReturnFrom" + let inner() = + task { + do! Task.Yield() + failtest "inner" + return 1 + } + let t = + task { + try + do! Task.Yield() + return! inner() + with + | TestException "inner" -> return 2 + } + require (t.Result = 2) "didn't catch" + + [] + member __.testTryFinallyOverReturnFromWithException() = + printfn "running testTryFinallyOverReturnFromWithException" + let inner() = + task { + do! Task.Yield() + failtest "inner" + return 1 + } + let mutable m = 0 + let t = + task { + try + do! Task.Yield() + return! inner() + finally + m <- 1 + } + try + t.Wait() + with + | :? AggregateException -> () + require (m = 1) "didn't run finally" + + [] + member __.testTryFinallyOverReturnFromWithoutException() = + printfn "running testTryFinallyOverReturnFromWithoutException" + let inner() = + task { + do! Task.Yield() + return 1 + } + let mutable m = 0 + let t = + task { + try + do! Task.Yield() + return! inner() + finally + m <- 1 + } + try + t.Wait() + with + | :? AggregateException -> () + require (m = 1) "didn't run finally" + + // no need to call this, we just want to check that it compiles w/o warnings + member __.testTrivialReturnCompiles (x : 'a) : 'a Task = + task { + do! Task.Yield() + return x + } + + // no need to call this, we just want to check that it compiles w/o warnings + member __.testTrivialTransformedReturnCompiles (x : 'a) (f : 'a -> 'b) : 'b Task = + task { + do! Task.Yield() + return f x + } + + [] + member __.testAsyncsMixedWithTasks() = + let t = + task { + do! Task.Delay(1) + do! Async.Sleep(1) + let! x = + async { + do! Async.Sleep(1) + return 5 + } + return! async { return x + 3 } + } + let result = t.Result + require (result = 8) "something weird happened" + + [] + // no need to call this, we just want to check that it compiles w/o warnings + member __.testDefaultInferenceForReturnFrom() = + let t = task { return Some "x" } + task { + let! r = t + if r = None then + return! failwithf "Could not find x" + else + return r + } + |> ignore + + [] + // no need to call this, just check that it compiles + member __.testCompilerInfersArgumentOfReturnFrom() = + task { + if true then return 1 + else return! failwith "" + } + |> ignore + +[] +type BasicsNotInParallel() = + + [] + member __.testTaskUsesSyncContext() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let mutable posted = false + let oldSyncContext = SynchronizationContext.Current + let syncContext = { new SynchronizationContext() with member _.Post(d,state) = posted <- true; d.Invoke(state) } + try + SynchronizationContext.SetSynchronizationContext syncContext + let tid = System.Threading.Thread.CurrentThread.ManagedThreadId + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread A" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread A" + let t = + task { + let tid2 = System.Threading.Thread.CurrentThread.ManagedThreadId + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread B" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread B" + require (tid = tid2) "expected synchronous start for task B2" + do! Task.Yield() + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread C" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread C" + ran <- true + } + t.Wait() + require ran "never ran" + require posted "never posted" + finally + SynchronizationContext.SetSynchronizationContext oldSyncContext + + [] + member __.testBackgroundTaskEscapesSyncContext() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let mutable posted = false + let oldSyncContext = SynchronizationContext.Current + let syncContext = { new SynchronizationContext() with member _.Post(d,state) = posted <- true; d.Invoke(state) } + try + SynchronizationContext.SetSynchronizationContext syncContext + let t = + backgroundTask { + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expect to be on background thread" + ran <- true + } + t.Wait() + require ran "never ran" + require (not posted) "did not expect post to sync context" + finally + SynchronizationContext.SetSynchronizationContext oldSyncContext + + [] + member __.testBackgroundTaskStaysOnSameThreadIfAlreadyOnBackground() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let taskOuter = + Task.Run(fun () -> + let tid = System.Threading.Thread.CurrentThread.ManagedThreadId + // In case other thread pool activities have polluted this one, sigh + SynchronizationContext.SetSynchronizationContext null + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expected thread pool thread (1)" + let t = + backgroundTask { + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expected thread pool thread (2)" + let tid2 = System.Threading.Thread.CurrentThread.ManagedThreadId + require (tid = tid2) "expected synchronous starts when already on background thread" + do! Task.Delay(200) + ran <- true + } + t.Wait() + require ran "never ran") + taskOuter.Wait() + + +#if STANDALONE +module M = + [] + let main argv = + printfn "Running tests..." + try + Basics().testShortCircuitResult() + Basics().testDelay() + Basics().testNoDelay() + Basics().testNonBlocking() + + Basics().testCatching1() + Basics().testCatching2() + Basics().testNestedCatching() + Basics().testWhileLoopSync() + Basics().testWhileLoopAsyncZeroIteration() + Basics().testWhileLoopAsyncOneIteration() + Basics().testWhileLoopAsync() + Basics().testTryFinallyHappyPath() + Basics().testTryFinallySadPath() + Basics().testTryFinallyCaught() + Basics().testUsing() + Basics().testUsingFromTask() + Basics().testUsingSadPath() + Basics().testForLoopA() + Basics().testForLoopSadPath() + Basics().testForLoopSadPathComplex() + Basics().testExceptionAttachedToTaskWithoutAwait() + Basics().testExceptionAttachedToTaskWithAwait() + Basics().testExceptionThrownInFinally() + Basics().test2ndExceptionThrownInFinally() + Basics().testFixedStackWhileLoop() + Basics().testFixedStackForLoop() + Basics().testTypeInference() + Basics().testNoStackOverflowWithImmediateResult() + Basics().testNoStackOverflowWithYieldResult() + ////// we don't support TCO, so large tail recursions will stack overflow + ////// or at least use O(n) heap. but small ones should at least function OK. + //testSmallTailRecursion() + Basics().testTryOverReturnFrom() + Basics().testTryFinallyOverReturnFromWithException() + Basics().testTryFinallyOverReturnFromWithoutException() + Basics().testAsyncsMixedWithTasks() + printfn "Passed all tests!" + with exn -> + eprintfn "************************************" + eprintfn "Exception: %O" exn + printfn "Test failed... exiting..." + eprintfn "************************************" + exit 1 + + printfn "Tests passed ok..., sleeping a bit in case there are background delayed exceptions" + Thread.Sleep(500) + printfn "Exiting..." + //System.Console.ReadLine() + 0 +#endif diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/TasksDynamic.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/TasksDynamic.fs new file mode 100644 index 00000000000..72d62f1e567 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/TasksDynamic.fs @@ -0,0 +1,1399 @@ +// Tests for TaskBuilder.fs +// +// Written in 2016 by Robert Peele (humbobst@gmail.com) +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights +// to this software to the public domain worldwide. This software is distributed without any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication along with this software. +// If not, see . +// +// +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the 'dynamic' implementation of the task type when state machine +// compilation fails. + +namespace FSharp.Core.UnitTests.Control.TasksDynamic + +#nowarn "1204" // construct only for use in compiled code +#nowarn "3511" // state machine not staticlly compilable - the one in 'Run' +open System +open System.Collections +open System.Collections.Generic +open System.Diagnostics +open System.Threading +open System.Threading.Tasks +open Microsoft.FSharp.Control +#if STANDALONE +[] +type FactAttribute() = inherit Attribute() +#else +open Xunit +open System.Runtime.CompilerServices + +#endif + +// Delegates to task, except 'Run' which is deliberately not inlined, hence no chance +// of static compilation of state machines. +type TaskBuilderDynamic() = + + [] + member _.Run(code) = task.Run(code) // warning 3511 is generated here: state machine not compilable + + member inline _.Delay f = task.Delay(f) + [] + member inline _.Zero() = task.Zero() + member inline _.Return (value) = task.Return(value) + member inline _.Combine(task1, task2) = task.Combine(task1, task2) + member inline _.While ([] condition, body) = task.While(condition, body) + member inline _.TryWith (body, catch) = task.TryWith(body, catch) + member inline _.TryFinally (body, compensation ) = task.TryFinally(body, compensation) +#if NETCOREAPP + member inline _.Using<'Resource, 'TOverall, 'T when 'Resource :> IAsyncDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) = + task.Using(resource, body) +#endif + member inline _.For (sequence, body) = task.For(sequence, body) + member inline _.ReturnFrom (t: Task<'T>) = task.ReturnFrom(t) + +// Delegates to task, except 'Run' which is deliberately not inlined, hence no chance +// of static compilation of state machines. +type BackgroundTaskBuilderDynamic() = + + [] + member _.Run(code) = backgroundTask.Run(code) // warning 3511 is generated here: state machine not compilable + + member inline _.Delay f = backgroundTask.Delay(f) + [] + member inline _.Zero() = backgroundTask.Zero() + member inline _.Return (value) = backgroundTask.Return(value) + member inline _.Combine(task1, task2) = backgroundTask.Combine(task1, task2) + member inline _.While ([] condition, body) = backgroundTask.While(condition, body) + member inline _.TryWith (body, catch) = backgroundTask.TryWith(body, catch) + member inline _.TryFinally (body, compensation ) = backgroundTask.TryFinally(body, compensation) +#if NETCOREAPP + member inline _.Using<'Resource, 'TOverall, 'T when 'Resource :> IAsyncDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) = + backgroundTask.Using(resource, body) +#endif + member inline _.For (sequence, body) = backgroundTask.For(sequence, body) + member inline _.ReturnFrom (t: Task<'T>) = backgroundTask.ReturnFrom(t) + +[] +module TaskBuilderDynamicLowPriority = + + // Low priority extension method + type TaskBuilderDynamic with + member inline _.Using<'Resource, 'TOverall, 'T when 'Resource :> IDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) = + task.Using(resource, body) + + // Low priority extension method + type BackgroundTaskBuilderDynamic with + member inline _.Using<'Resource, 'TOverall, 'T when 'Resource :> IDisposable> (resource: 'Resource, body: 'Resource -> TaskCode<'TOverall, 'T>) = + backgroundTask.Using(resource, body) + +[] +module Value = + + [] + module TaskLowProrityExtensions = + + type TaskBuilderDynamic with + member inline _.ReturnFrom< ^TaskLike, ^Awaiter, ^T + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^T)> + (t: ^TaskLike) : TaskCode< ^T, ^T> = + task.ReturnFrom(t) + member inline _.Bind< ^TaskLike, ^TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^TResult1)> + (t: ^TaskLike, continuation: (^TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + task.Bind(t, continuation) + + type BackgroundTaskBuilderDynamic with + member inline _.ReturnFrom< ^TaskLike, ^Awaiter, ^T + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^T)> + (t: ^TaskLike) : TaskCode< ^T, ^T> = + backgroundTask.ReturnFrom(t) + member inline _.Bind< ^TaskLike, ^TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^TResult1)> + (t: ^TaskLike, continuation: (^TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + backgroundTask.Bind(t, continuation) + + + [] + module HighLowProrityExtensions = + + type TaskBuilderDynamic with + member inline _.Bind (t: Task<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + task.Bind(t, continuation) + + member inline _.Bind (computation: Async<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + task.Bind(computation, continuation) + + member inline _.ReturnFrom (t: Task<'T>) : TaskCode<'T, 'T> = + task.ReturnFrom(t) + + member inline _.ReturnFrom (computation: Async<'T>) : TaskCode<'T, 'T> = + task.ReturnFrom(computation) + + + type BackgroundTaskBuilderDynamic with + member inline _.Bind (t: Task<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + backgroundTask.Bind(t, continuation) + + member inline _.Bind (computation: Async<'TResult1>, continuation: ('TResult1 -> TaskCode<'TOverall, 'TResult2>)) : TaskCode<'TOverall, 'TResult2> = + backgroundTask.Bind(computation, continuation) + + member inline _.ReturnFrom (task: Task<'T>) : TaskCode<'T, 'T> = + backgroundTask.ReturnFrom(task) + + member inline _.ReturnFrom (computation: Async<'T>) : TaskCode<'T, 'T> = + backgroundTask.ReturnFrom(computation) + + let taskDynamic = TaskBuilderDynamic() + let backgroundTaskDynamic = BackgroundTaskBuilderDynamic() + type Do_no_use_task_in_this_file_use_taskDynamic_instead = | Nope + let task = Do_no_use_task_in_this_file_use_taskDynamic_instead.Nope + +type ITaskThing = + abstract member Taskify : 'a option -> 'a Task + +type SmokeTestsForCompilation() = + + [] + member __.tinyTask() = + taskDynamic { + return 1 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tbind() = + taskDynamic { + let! x = Task.FromResult(1) + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.tnested() = + taskDynamic { + let! x = taskDynamic { return 1 } + return x + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tcatch0() = + taskDynamic { + try + return 1 + with e -> + return 2 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + member __.tcatch1() = + taskDynamic { + try + let! x = Task.FromResult 1 + return x + with e -> + return 2 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + + [] + member __.t3() = + let t2() = + taskDynamic { + System.Console.WriteLine("hello") + return 1 + } + taskDynamic { + System.Console.WriteLine("hello") + let! x = t2() + System.Console.WriteLine("world") + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.t3b() = + taskDynamic { + System.Console.WriteLine("hello") + let! x = Task.FromResult(1) + System.Console.WriteLine("world") + return 1 + x + } + |> fun t -> + t.Wait() + if t.Result <> 2 then failwith "failed" + + [] + member __.t3c() = + taskDynamic { + System.Console.WriteLine("hello") + do! Task.Delay(100) + System.Console.WriteLine("world") + return 1 + } + |> fun t -> + t.Wait() + if t.Result <> 1 then failwith "failed" + + [] + // This tests an exception match + member __.t67() = + taskDynamic { + try + do! Task.Delay(0) + with + | :? ArgumentException -> + () + | _ -> + () + } + |> fun t -> + t.Wait() + if t.Result <> () then failwith "failed" + + [] + // This tests compiling an incomplete exception match + member __.t68() = + taskDynamic { + try + do! Task.Delay(0) + with + | :? ArgumentException -> + () + } + |> fun t -> + t.Wait() + if t.Result <> () then failwith "failed" + + [] + member __.testCompileAsyncWhileLoop() = + taskDynamic { + let mutable i = 0 + while i < 5 do + i <- i + 1 + do! Task.Yield() + return i + } + |> fun t -> + t.Wait() + if t.Result <> 5 then failwith "failed" + + +exception TestException of string + +[] +module Helpers = + let BIG = 10 + // let BIG = 10000 + let require x msg = if not x then failwith msg + let failtest str = raise (TestException str) + +type Basics() = + [] + member __.testShortCircuitResult() = + printfn "Running testShortCircuitResult..." + let t = + taskDynamic { + let! x = Task.FromResult(1) + let! y = Task.FromResult(2) + return x + y + } + require t.IsCompleted "didn't short-circuit already completed tasks" + printfn "t.Result = %A" t.Result + require (t.Result = 3) "wrong result" + + [] + member __.testDelay() = + printfn "Running testDelay..." + let mutable x = 0 + let t = + taskDynamic { + do! Task.Delay(50) + x <- x + 1 + } + printfn "task created and first step run...." + require (x = 0) "task already ran" + printfn "waiting...." + t.Wait() + + [] + member __.testNoDelay() = + printfn "Running testNoDelay..." + let mutable x = 0 + let t = + taskDynamic { + x <- x + 1 + do! Task.Delay(5) + x <- x + 1 + } + require (x = 1) "first part didn't run yet" + t.Wait() + + [] + member __.testNonBlocking() = + printfn "Running testNonBlocking..." + let sw = Stopwatch() + sw.Start() + let t = + taskDynamic { + do! Task.Yield() + Thread.Sleep(100) + } + sw.Stop() + require (sw.ElapsedMilliseconds < 50L) "sleep blocked caller" + t.Wait() + + [] + member __.testCatching1() = + printfn "Running testCatching1..." + let mutable x = 0 + let mutable y = 0 + let t = + taskDynamic { + try + do! Task.Delay(0) + failtest "hello" + x <- 1 + do! Task.Delay(100) + with + | TestException msg -> + require (msg = "hello") "message tampered" + | _ -> + require false "other exn type" + require false "other exn type" + y <- 1 + } + t.Wait() + require (y = 1) "bailed after exn" + require (x = 0) "ran past failure" + + [] + member __.testCatching2() = + printfn "Running testCatching2..." + let mutable x = 0 + let mutable y = 0 + let t = + taskDynamic { + try + do! Task.Yield() // can't skip through this + failtest "hello" + x <- 1 + do! Task.Delay(100) + with + | TestException msg -> + require (msg = "hello") "message tampered" + | _ -> + require false "other exn type" + y <- 1 + } + t.Wait() + require (y = 1) "bailed after exn" + require (x = 0) "ran past failure" + + [] + member __.testNestedCatching() = + printfn "Running testNestedCatching..." + let mutable counter = 1 + let mutable caughtInner = 0 + let mutable caughtOuter = 0 + let t1() = + taskDynamic { + try + do! Task.Yield() + failtest "hello" + with + | TestException msg as exn -> + caughtInner <- counter + counter <- counter + 1 + raise exn + } + let t2 = + taskDynamic { + try + do! t1() + with + | TestException msg as exn -> + caughtOuter <- counter + raise exn + | e -> + require false (sprintf "invalid msg type %s" e.Message) + } + try + t2.Wait() + require false "ran past failed task wait" + with + | :? AggregateException as exn -> + require (exn.InnerExceptions.Count = 1) "more than 1 exn" + require (caughtInner = 1) "didn't catch inner" + require (caughtOuter = 2) "didn't catch outer" + + [] + member __.testWhileLoopSync() = + printfn "Running testWhileLoopSync..." + let t = + taskDynamic { + let mutable i = 0 + while i < 10 do + i <- i + 1 + return i + } + //t.Wait() no wait required for sync loop + require (t.IsCompleted) "didn't do sync while loop properly - not completed" + require (t.Result = 10) "didn't do sync while loop properly - wrong result" + + [] + member __.testWhileLoopAsyncZeroIteration() = + printfn "Running testWhileLoopAsyncZeroIteration..." + for i in 1 .. 5 do + let t = + taskDynamic { + let mutable i = 0 + while i < 0 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 0) "didn't do while loop properly" + + [] + member __.testWhileLoopAsyncOneIteration() = + printfn "Running testWhileLoopAsyncOneIteration..." + for i in 1 .. 5 do + let t = + taskDynamic { + let mutable i = 0 + while i < 1 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 1) "didn't do while loop properly" + + [] + member __.testWhileLoopAsync() = + printfn "Running testWhileLoopAsync..." + for i in 1 .. 5 do + let t = + taskDynamic { + let mutable i = 0 + while i < 10 do + i <- i + 1 + do! Task.Yield() + return i + } + t.Wait() + require (t.Result = 10) "didn't do while loop properly" + + [] + member __.testTryFinallyHappyPath() = + printfn "Running testTryFinallyHappyPath..." + for i in 1 .. 5 do + let mutable ran = false + let t = + taskDynamic { + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + finally + ran <- true + } + t.Wait() + require ran "never ran" + [] + member __.testTryFinallySadPath() = + printfn "Running testTryFinallySadPath..." + for i in 1 .. 5 do + let mutable ran = false + let t = + taskDynamic { + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + failtest "uhoh" + finally + ran <- true + } + try + t.Wait() + with + | _ -> () + require ran "never ran" + + [] + member __.testTryFinallyCaught() = + printfn "Running testTryFinallyCaught..." + for i in 1 .. 5 do + let mutable ran = false + let t = + taskDynamic { + try + try + require (not ran) "ran way early" + do! Task.Delay(100) + require (not ran) "ran kinda early" + failtest "uhoh" + finally + ran <- true + return 1 + with + | _ -> return 2 + } + require (t.Result = 2) "wrong return" + require ran "never ran" + + [] + member __.testUsing() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = false + let t = + taskDynamic { + use d = { new IDisposable with member __.Dispose() = disposed <- true } + require (not disposed) "disposed way early" + do! Task.Delay(100) + require (not disposed) "disposed kinda early" + } + t.Wait() + require disposed "never disposed B" + +#if NETCOREAPP + [] + member __.testUsingAsyncDisposableSync() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + taskDynamic { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + taskDynamic { + System.Console.WriteLine "incrementing" + disposed <- disposed + 1 } + |> ValueTask + } + require (disposed = 0) "disposed way early" + System.Console.WriteLine "delaying" + do! Task.Delay(100) + System.Console.WriteLine "testing" + require (disposed = 0) "disposed kinda early" + } + t.Wait() + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableAsync() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + taskDynamic { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + taskDynamic { + do! Task.Delay(10) + disposed <- disposed + 1 + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + do! Task.Delay(100) + require (disposed = 0) "disposed kinda early" + } + t.Wait() + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableExnAsync() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + taskDynamic { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + taskDynamic { + do! Task.Delay(10) + disposed <- disposed + 1 + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableExnSync() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + taskDynamic { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + taskDynamic { + disposed <- disposed + 1 + do! Task.Delay(10) + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" + + [] + member __.testUsingAsyncDisposableDelayExnSync() = + printfn "Running testUsing..." + for i in 1 .. 5 do + let mutable disposed = 0 + let t = + taskDynamic { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + taskDynamic { + disposed <- disposed + 1 + do! Task.Delay(10) + } + |> ValueTask + } + require (disposed = 0) "disposed way early" + do! Task.Delay(10) + require (disposed = 0) "disposed kind of early" + failtest "oops" + + } + try t.Wait() + with | :? AggregateException -> + require (disposed >= 1) "never disposed B" + require (disposed <= 1) "too many dispose on B" +#endif + + [] + member __.testUsingFromTask() = + printfn "Running testUsingFromTask..." + let mutable disposedInner = false + let mutable disposed = false + let t = + taskDynamic { + use! d = + taskDynamic { + do! Task.Delay(50) + use i = { new IDisposable with member __.Dispose() = disposedInner <- true } + require (not disposed && not disposedInner) "disposed inner early" + return { new IDisposable with member __.Dispose() = disposed <- true } + } + require disposedInner "did not dispose inner after task completion" + require (not disposed) "disposed way early" + do! Task.Delay(50) + require (not disposed) "disposed kinda early" + } + t.Wait() + require disposed "never disposed C" + + [] + member __.testUsingSadPath() = + printfn "Running testUsingSadPath..." + let mutable disposedInner = false + let mutable disposed = false + let t = + taskDynamic { + try + use! d = + taskDynamic { + do! Task.Delay(50) + use i = { new IDisposable with member __.Dispose() = disposedInner <- true } + failtest "uhoh" + require (not disposed && not disposedInner) "disposed inner early" + return { new IDisposable with member __.Dispose() = disposed <- true } + } + () + with + | TestException msg -> + printfn "caught TestException" + require disposedInner "did not dispose inner after task completion" + require (not disposed) "disposed way early" + do! Task.Delay(50) + printfn "resumed after delay" + require (not disposed) "disposed kinda early" + } + t.Wait() + require (not disposed) "disposed thing that never should've existed" + + [] + member __.testForLoopA() = + printfn "Running testForLoopA..." + let list = ["a"; "b"; "c"] |> Seq.ofList + let t = + taskDynamic { + printfn "entering loop..." + let mutable x = Unchecked.defaultof<_> + let e = list.GetEnumerator() + while e.MoveNext() do + x <- e.Current + printfn "x = %A" x + do! Task.Yield() + printfn "x = %A" x + } + t.Wait() + + [] + member __.testForLoopComplex() = + printfn "Running testForLoopComplex..." + let mutable disposed = false + let wrapList = + let raw = ["a"; "b"; "c"] |> Seq.ofList + let getEnumerator() = + let raw = raw.GetEnumerator() + { new IEnumerator with + member __.MoveNext() = + require (not disposed) "moved next after disposal" + raw.MoveNext() + member __.Current = + require (not disposed) "accessed current after disposal" + raw.Current + member __.Current = + require (not disposed) "accessed current (boxed) after disposal" + box raw.Current + member __.Dispose() = + require (not disposed) "disposed twice" + disposed <- true + raw.Dispose() + member __.Reset() = + require (not disposed) "reset after disposal" + raw.Reset() + } + { new IEnumerable with + member __.GetEnumerator() : IEnumerator = getEnumerator() + member __.GetEnumerator() : IEnumerator = upcast getEnumerator() + } + let t = + taskDynamic { + let mutable index = 0 + do! Task.Yield() + printfn "entering loop..." + for x in wrapList do + printfn "x = %A, index = %d" x index + do! Task.Yield() + printfn "back from yield" + do! Task.Yield() + printfn "back from yield" + match index with + | 0 -> require (x = "a") "wrong first value" + | 1 -> require (x = "b") "wrong second value" + | 2 -> require (x = "c") "wrong third value" + | _ -> require false "iterated too far!" + index <- index + 1 + printfn "yield again" + do! Task.Yield() + printfn "yield again again" + do! Task.Yield() + printfn "looping again..." + do! Task.Yield() + return 1 + } + t.Wait() + require disposed "never disposed D" + require (t.Result = 1) "wrong result" + + [] + member __.testForLoopSadPath() = + printfn "Running testForLoopSadPath..." + for i in 1 .. 5 do + let wrapList = ["a"; "b"; "c"] + let t = + taskDynamic { + let mutable index = 0 + do! Task.Yield() + for x in wrapList do + do! Task.Yield() + index <- index + 1 + return 1 + } + require (t.Result = 1) "wrong result" + + [] + member __.testForLoopSadPathComplex() = + printfn "Running testForLoopSadPathComplex..." + for i in 1 .. 5 do + let mutable disposed = false + let wrapList = + let raw = ["a"; "b"; "c"] |> Seq.ofList + let getEnumerator() = + let raw = raw.GetEnumerator() + { new IEnumerator with + member __.MoveNext() = + require (not disposed) "moved next after disposal" + raw.MoveNext() + member __.Current = + require (not disposed) "accessed current after disposal" + raw.Current + member __.Current = + require (not disposed) "accessed current (boxed) after disposal" + box raw.Current + member __.Dispose() = + require (not disposed) "disposed twice" + disposed <- true + raw.Dispose() + member __.Reset() = + require (not disposed) "reset after disposal" + raw.Reset() + } + { new IEnumerable with + member __.GetEnumerator() : IEnumerator = getEnumerator() + member __.GetEnumerator() : IEnumerator = upcast getEnumerator() + } + let mutable caught = false + let t = + taskDynamic { + try + let mutable index = 0 + do! Task.Yield() + for x in wrapList do + do! Task.Yield() + match index with + | 0 -> require (x = "a") "wrong first value" + | _ -> failtest "uhoh" + index <- index + 1 + do! Task.Yield() + do! Task.Yield() + return 1 + with + | TestException "uhoh" -> + caught <- true + return 2 + } + require (t.Result = 2) "wrong result" + require caught "didn't catch exception" + require disposed "never disposed A" + + [] + member __.testExceptionAttachedToTaskWithoutAwait() = + for i in 1 .. 5 do + let mutable ranA = false + let mutable ranB = false + let t = + taskDynamic { + ranA <- true + failtest "uhoh" + ranB <- true + } + require ranA "didn't run immediately" + require (not ranB) "ran past exception" + require (not (isNull t.Exception)) "didn't capture exception" + require (t.Exception.InnerExceptions.Count = 1) "captured more exceptions" + require (t.Exception.InnerException = TestException "uhoh") "wrong exception" + let mutable caught = false + let mutable ranCatcher = false + let catcher = + taskDynamic { + try + ranCatcher <- true + let! result = t + return false + with + | TestException "uhoh" -> + caught <- true + return true + } + require ranCatcher "didn't run" + require catcher.Result "didn't catch" + require caught "didn't catch" + + [] + member __.testExceptionAttachedToTaskWithAwait() = + printfn "running testExceptionAttachedToTaskWithAwait" + for i in 1 .. 5 do + let mutable ranA = false + let mutable ranB = false + let t = + taskDynamic { + ranA <- true + failtest "uhoh" + do! Task.Delay(100) + ranB <- true + } + require ranA "didn't run immediately" + require (not ranB) "ran past exception" + require (not (isNull t.Exception)) "didn't capture exception" + require (t.Exception.InnerExceptions.Count = 1) "captured more exceptions" + require (t.Exception.InnerException = TestException "uhoh") "wrong exception" + let mutable caught = false + let mutable ranCatcher = false + let catcher = + taskDynamic { + try + ranCatcher <- true + let! result = t + return false + with + | TestException "uhoh" -> + caught <- true + return true + } + require ranCatcher "didn't run" + require catcher.Result "didn't catch" + require caught "didn't catch" + + [] + member __.testExceptionThrownInFinally() = + printfn "running testExceptionThrownInFinally" + for i in 1 .. 5 do + let mutable ranInitial = false + let mutable ranNext = false + let mutable ranFinally = 0 + let t = + taskDynamic { + try + ranInitial <- true + do! Task.Yield() + Thread.Sleep(100) // shouldn't be blocking so we should get through to requires before this finishes + ranNext <- true + finally + ranFinally <- ranFinally + 1 + failtest "finally exn!" + } + require ranInitial "didn't run initial" + require (not ranNext) "ran next too early" + try + t.Wait() + require false "shouldn't get here" + with + | _ -> () + require ranNext "didn't run next" + require (ranFinally = 1) "didn't run finally exactly once" + + [] + member __.test2ndExceptionThrownInFinally() = + printfn "running test2ndExceptionThrownInFinally" + for i in 1 .. 5 do + let mutable ranInitial = false + let mutable ranNext = false + let mutable ranFinally = 0 + let t = + taskDynamic { + try + ranInitial <- true + do! Task.Yield() + Thread.Sleep(100) // shouldn't be blocking so we should get through to requires before this finishes + ranNext <- true + failtest "uhoh" + finally + ranFinally <- ranFinally + 1 + failtest "2nd exn!" + } + require ranInitial "didn't run initial" + require (not ranNext) "ran next too early" + try + t.Wait() + require false "shouldn't get here" + with + | _ -> () + require ranNext "didn't run next" + require (ranFinally = 1) "didn't run finally exactly once" + + [] + member __.testFixedStackWhileLoop() = + printfn "running testFixedStackWhileLoop" + for i in 1 .. 100 do + let t = + taskDynamic { + let mutable maxDepth = Nullable() + let mutable i = 0 + while i < BIG do + i <- i + 1 + do! Task.Yield() + if i % 100 = 0 then + let stackDepth = StackTrace().FrameCount + if maxDepth.HasValue && stackDepth > maxDepth.Value then + failwith "Stack depth increased!" + maxDepth <- Nullable(stackDepth) + return i + } + t.Wait() + require (t.Result = BIG) "didn't get to big number" + + [] + member __.testFixedStackForLoop() = + for i in 1 .. 100 do + printfn "running testFixedStackForLoop" + let mutable ran = false + let t = + taskDynamic { + let mutable maxDepth = Nullable() + for i in Seq.init BIG id do + do! Task.Yield() + if i % 100 = 0 then + let stackDepth = StackTrace().FrameCount + if maxDepth.HasValue && stackDepth > maxDepth.Value then + failwith "Stack depth increased!" + maxDepth <- Nullable(stackDepth) + ran <- true + return () + } + t.Wait() + require ran "didn't run all" + + [] + member __.testTypeInference() = + let t1 : string Task = + taskDynamic { + return "hello" + } + let t2 = + taskDynamic { + let! s = t1 + return s.Length + } + t2.Wait() + + [] + member __.testNoStackOverflowWithImmediateResult() = + printfn "running testNoStackOverflowWithImmediateResult" + let longLoop = + taskDynamic { + let mutable n = 0 + while n < BIG do + n <- n + 1 + return! Task.FromResult(()) + } + longLoop.Wait() + + [] + member __.testNoStackOverflowWithYieldResult() = + printfn "running testNoStackOverflowWithYieldResult" + let longLoop = + taskDynamic { + let mutable n = 0 + while n < BIG do + let! _ = + taskDynamic { + do! Task.Yield() + let! _ = Task.FromResult(0) + n <- n + 1 + } + n <- n + 1 + } + longLoop.Wait() + + [] + member __.testSmallTailRecursion() = + printfn "running testSmallTailRecursion" + let rec loop n = + taskDynamic { + if n < 100 then + do! Task.Yield() + let! _ = Task.FromResult(0) + return! loop (n + 1) + else + return () + } + let shortLoop = + taskDynamic { + return! loop 0 + } + shortLoop.Wait() + + [] + member __.testTryOverReturnFrom() = + printfn "running testTryOverReturnFrom" + let inner() = + taskDynamic { + do! Task.Yield() + failtest "inner" + return 1 + } + let t = + taskDynamic { + try + do! Task.Yield() + return! inner() + with + | TestException "inner" -> return 2 + } + require (t.Result = 2) "didn't catch" + + [] + member __.testTryFinallyOverReturnFromWithException() = + printfn "running testTryFinallyOverReturnFromWithException" + let inner() = + taskDynamic { + do! Task.Yield() + failtest "inner" + return 1 + } + let mutable m = 0 + let t = + taskDynamic { + try + do! Task.Yield() + return! inner() + finally + m <- 1 + } + try + t.Wait() + with + | :? AggregateException -> () + require (m = 1) "didn't run finally" + + [] + member __.testTryFinallyOverReturnFromWithoutException() = + printfn "running testTryFinallyOverReturnFromWithoutException" + let inner() = + taskDynamic { + do! Task.Yield() + return 1 + } + let mutable m = 0 + let t = + taskDynamic { + try + do! Task.Yield() + return! inner() + finally + m <- 1 + } + try + t.Wait() + with + | :? AggregateException -> () + require (m = 1) "didn't run finally" + + // no need to call this, we just want to check that it compiles w/o warnings + member __.testTrivialReturnCompiles (x : 'a) : 'a Task = + taskDynamic { + do! Task.Yield() + return x + } + + // no need to call this, we just want to check that it compiles w/o warnings + member __.testTrivialTransformedReturnCompiles (x : 'a) (f : 'a -> 'b) : 'b Task = + taskDynamic { + do! Task.Yield() + return f x + } + + [] + member __.testAsyncsMixedWithTasks() = + let t = + taskDynamic { + do! Task.Delay(1) + do! Async.Sleep(1) + let! x = + async { + do! Async.Sleep(1) + return 5 + } + return! async { return x + 3 } + } + let result = t.Result + require (result = 8) "something weird happened" + + [] + // no need to call this, we just want to check that it compiles w/o warnings + member __.testDefaultInferenceForReturnFrom() = + let t = taskDynamic { return Some "x" } + taskDynamic { + let! r = t + if r = None then + return! failwithf "Could not find x" + else + return r + } + |> ignore + + [] + // no need to call this, just check that it compiles + member __.testCompilerInfersArgumentOfReturnFrom() = + taskDynamic { + if true then return 1 + else return! failwith "" + } + |> ignore + + +[] +type BasicsNotInParallel() = + + [] + member __.testTaskUsesSyncContext() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let mutable posted = false + let oldSyncContext = SynchronizationContext.Current + let syncContext = { new SynchronizationContext() with member _.Post(d,state) = posted <- true; d.Invoke(state) } + try + SynchronizationContext.SetSynchronizationContext syncContext + let tid = System.Threading.Thread.CurrentThread.ManagedThreadId + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread A" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread A" + let t = + taskDynamic { + let tid2 = System.Threading.Thread.CurrentThread.ManagedThreadId + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread B" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread B" + require (tid = tid2) "expected synchronous start for task B2" + do! Task.Yield() + require (not (isNull SynchronizationContext.Current)) "need sync context non null on foreground thread C" + require (SynchronizationContext.Current = syncContext) "need sync context known on foreground thread C" + ran <- true + } + t.Wait() + require ran "never ran" + require posted "never posted" + finally + SynchronizationContext.SetSynchronizationContext oldSyncContext + + [] + member __.testBackgroundTaskEscapesSyncContext() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let mutable posted = false + let oldSyncContext = SynchronizationContext.Current + let syncContext = { new SynchronizationContext() with member _.Post(d,state) = posted <- true; d.Invoke(state) } + try + SynchronizationContext.SetSynchronizationContext syncContext + let t = + backgroundTaskDynamic { + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expect to be on background thread" + ran <- true + } + t.Wait() + require ran "never ran" + require (not posted) "did not expect post to sync context" + finally + SynchronizationContext.SetSynchronizationContext oldSyncContext + + [] + member __.testBackgroundTaskStaysOnSameThreadIfAlreadyOnBackground() = + printfn "Running testBackgroundTask..." + for i in 1 .. 5 do + let mutable ran = false + let taskOuter = + Task.Run(fun () -> + let tid = System.Threading.Thread.CurrentThread.ManagedThreadId + // In case other thread pool activities have polluted this one, sigh + SynchronizationContext.SetSynchronizationContext null + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expected thread pool thread (1)" + let t = + backgroundTaskDynamic { + require (System.Threading.Thread.CurrentThread.IsThreadPoolThread) "expected thread pool thread (2)" + let tid2 = System.Threading.Thread.CurrentThread.ManagedThreadId + require (tid = tid2) "expected synchronous starts when already on thread pool thread with null sync context" + do! Task.Delay(200) + ran <- true + } + t.Wait() + require ran "never ran") + taskOuter.Wait() + +#if STANDALONE +module M = + [] + let main argv = + printfn "Running tests..." + try + Basics().testShortCircuitResult() + Basics().testDelay() + Basics().testNoDelay() + Basics().testNonBlocking() + + Basics().testCatching1() + Basics().testCatching2() + Basics().testNestedCatching() + Basics().testWhileLoopSync() + Basics().testWhileLoopAsyncZeroIteration() + Basics().testWhileLoopAsyncOneIteration() + Basics().testWhileLoopAsync() + Basics().testTryFinallyHappyPath() + Basics().testTryFinallySadPath() + Basics().testTryFinallyCaught() + Basics().testUsing() + Basics().testUsingFromTask() + Basics().testUsingSadPath() + Basics().testForLoopA() + Basics().testForLoopSadPath() + Basics().testForLoopSadPathComplex() + Basics().testExceptionAttachedToTaskWithoutAwait() + Basics().testExceptionAttachedToTaskWithAwait() + Basics().testExceptionThrownInFinally() + Basics().test2ndExceptionThrownInFinally() + Basics().testFixedStackWhileLoop() + Basics().testFixedStackForLoop() + Basics().testTypeInference() + Basics().testNoStackOverflowWithImmediateResult() + Basics().testNoStackOverflowWithYieldResult() + ////// we don't support TCO, so large tail recursions will stack overflow + ////// or at least use O(n) heap. but small ones should at least function OK. + //testSmallTailRecursion() + Basics().testTryOverReturnFrom() + Basics().testTryFinallyOverReturnFromWithException() + Basics().testTryFinallyOverReturnFromWithoutException() + Basics().testAsyncsMixedWithTasks() + printfn "Passed all tests!" + with exn -> + eprintfn "************************************" + eprintfn "Exception: %O" exn + printfn "Test failed... exiting..." + eprintfn "************************************" + exit 1 + + printfn "Tests passed ok..., sleeping a bit in case there are background delayed exceptions" + Thread.Sleep(500) + printfn "Exiting..." + //System.Console.ReadLine() + 0 +#endif diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs index 0434153fbb6..6a4eb596d14 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs @@ -3,13 +3,13 @@ // Various tests for the: // System.Numerics.BigInteger struct -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Math +namespace FSharp.Core.UnitTests.Math #nowarn "52" // error FS0052: The value has been copied to ensure the original is not mutated by this operation open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open Microsoft.FSharp.Math open System.Numerics @@ -22,7 +22,6 @@ Make sure each method works on: * large bigints *) -[] type BigIntType() = // global variables @@ -32,7 +31,7 @@ type BigIntType() = let bigNegativeB = -bigPositiveB // Interfaces - [] + [] member this.IComparable() = // Legit IC @@ -40,7 +39,7 @@ type BigIntType() = Assert.AreEqual(ic.CompareTo(bigPositiveA), 0) // Base class methods - [] + [] member this.ObjectToString() = Assert.AreEqual(bigPositiveA.ToString(), "12345678901234567890") @@ -54,7 +53,7 @@ type BigIntType() = #endif - [] + [] member this.ObjectEquals() = // All three are different constructor, but have equivalent value @@ -66,61 +65,61 @@ type BigIntType() = let z3 = BigInteger.Zero let z4 = BigInteger() - Assert.IsTrue( (a = b) ) - Assert.IsTrue( (b = c) ) - Assert.IsTrue( (c = a) ) - Assert.IsTrue( (z1 = z2) ) - Assert.IsTrue( (z2 = z3) ) + Assert.True( (a = b) ) + Assert.True( (b = c) ) + Assert.True( (c = a) ) + Assert.True( (z1 = z2) ) + Assert.True( (z2 = z3) ) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue( (z3 = z4) ) - Assert.IsTrue( (z4 = z1) ) + Assert.True( (z3 = z4) ) + Assert.True( (z4 = z1) ) #endif - Assert.IsTrue( (z1 = -z2) ) - Assert.IsTrue( (z2 = -z3) ) + Assert.True( (z1 = -z2) ) + Assert.True( (z2 = -z3) ) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue( (z3 = -z4) ) - Assert.IsTrue( (z4 = -z1) ) + Assert.True( (z3 = -z4) ) + Assert.True( (z4 = -z1) ) #endif - Assert.IsTrue( a.Equals(b) ); Assert.IsTrue( b.Equals(a) ) - Assert.IsTrue( b.Equals(c) ); Assert.IsTrue( c.Equals(b) ) - Assert.IsTrue( c.Equals(a) ); Assert.IsTrue( a.Equals(c) ) - Assert.IsTrue( z1.Equals(z2) ); Assert.IsTrue( z2.Equals(z3) ) + Assert.True( a.Equals(b) ); Assert.True( b.Equals(a) ) + Assert.True( b.Equals(c) ); Assert.True( c.Equals(b) ) + Assert.True( c.Equals(a) ); Assert.True( a.Equals(c) ) + Assert.True( z1.Equals(z2) ); Assert.True( z2.Equals(z3) ) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue( z3.Equals(z4) ); Assert.IsTrue( z4.Equals(z1) ) + Assert.True( z3.Equals(z4) ); Assert.True( z4.Equals(z1) ) #endif // Self equality let a = new BigInteger(168) - Assert.IsTrue( (a = a) ) - Assert.IsTrue( (z1 = z1) ) - Assert.IsTrue( (z2 = z2) ) - Assert.IsTrue( (z3 = z3) ) + Assert.True( (a = a) ) + Assert.True( (z1 = z1) ) + Assert.True( (z2 = z2) ) + Assert.True( (z3 = z3) ) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue( (z4 = z4) ) + Assert.True( (z4 = z4) ) #endif - Assert.IsTrue(a.Equals(a)) - Assert.IsTrue(z1.Equals(z1)) - Assert.IsTrue(z2.Equals(z2)) - Assert.IsTrue(z3.Equals(z3)) + Assert.True(a.Equals(a)) + Assert.True(z1.Equals(z1)) + Assert.True(z2.Equals(z2)) + Assert.True(z3.Equals(z3)) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue(z4.Equals(z4)) + Assert.True(z4.Equals(z4)) #endif // Null - Assert.IsFalse(a.Equals(null)) + Assert.False(a.Equals(null)) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue(0I.GetHashCode() = (BigInteger()).GetHashCode()) + Assert.True(0I.GetHashCode() = (BigInteger()).GetHashCode()) #endif // static methods - [] + [] member this.Abs() = Assert.AreEqual(BigInteger.Abs(bigPositiveA), bigPositiveA) @@ -138,7 +137,7 @@ type BigIntType() = () - [] + [] member this.DivRem() = let mutable r = BigInteger(0) let mutable q = BigInteger(0) @@ -178,7 +177,7 @@ type BigIntType() = () - [] + [] member this.GreatestCommonDivisor() = Assert.AreEqual(BigInteger.GreatestCommonDivisor(bigPositiveA, bigPositiveB), 900000000090I) Assert.AreEqual(BigInteger.GreatestCommonDivisor(bigNegativeA, bigNegativeB), 900000000090I) @@ -192,12 +191,12 @@ type BigIntType() = () - [] + [] member this.One() = Assert.AreEqual(BigInteger.One,1I) () - [] + [] member this.Parse() = Assert.AreEqual(BigInteger.Parse("12345678901234567890"), bigPositiveA) @@ -219,7 +218,7 @@ type BigIntType() = () - [] + [] member this.Pow() = Assert.AreEqual(BigInteger.Pow(2I, 3), 8I) Assert.AreEqual(BigInteger.Pow(0I, 100), 0I) @@ -235,7 +234,7 @@ type BigIntType() = CheckThrowsArgumentOutOfRangeException(fun() -> BigInteger.Pow(100I, -2) |> ignore) () - [] + [] member this.Sign() = Assert.AreEqual(0I.Sign, 0) Assert.AreEqual(BigInteger().Sign, 0) @@ -243,44 +242,44 @@ type BigIntType() = Assert.AreEqual(bigNegativeA.Sign, -1) () - [] + [] member this.IsZero() = - Assert.IsTrue(0I.IsZero) - Assert.IsTrue(-0I.IsZero) - Assert.IsTrue(BigInteger.Zero.IsZero) - Assert.IsTrue((-BigInteger.Zero).IsZero) + Assert.True(0I.IsZero) + Assert.True(-0I.IsZero) + Assert.True(BigInteger.Zero.IsZero) + Assert.True((-BigInteger.Zero).IsZero) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsTrue(BigInteger().IsZero) - Assert.IsTrue((-BigInteger()).IsZero) + Assert.True(BigInteger().IsZero) + Assert.True((-BigInteger()).IsZero) #endif - Assert.IsTrue(BigInteger(0).IsZero) - Assert.IsTrue((-BigInteger(0)).IsZero) - Assert.IsFalse(1I.IsZero) - Assert.IsFalse(BigInteger.One.IsZero) - Assert.IsFalse(-1I.IsZero) + Assert.True(BigInteger(0).IsZero) + Assert.True((-BigInteger(0)).IsZero) + Assert.False(1I.IsZero) + Assert.False(BigInteger.One.IsZero) + Assert.False(-1I.IsZero) () - [] + [] member this.IsOne() = - Assert.IsFalse(0I.IsOne) - Assert.IsFalse(-0I.IsOne) - Assert.IsFalse(BigInteger.Zero.IsOne) - Assert.IsFalse((-BigInteger.Zero).IsOne) + Assert.False(0I.IsOne) + Assert.False(-0I.IsOne) + Assert.False(BigInteger.Zero.IsOne) + Assert.False((-BigInteger.Zero).IsOne) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 #else - Assert.IsFalse(BigInteger().IsOne) - Assert.IsFalse((-BigInteger()).IsOne) + Assert.False(BigInteger().IsOne) + Assert.False((-BigInteger()).IsOne) #endif - Assert.IsFalse(BigInteger(0).IsOne) - Assert.IsFalse((-BigInteger(0)).IsOne) - Assert.IsTrue(1I.IsOne) - Assert.IsTrue(BigInteger.One.IsOne) - Assert.IsTrue(BigInteger(1).IsOne) - Assert.IsFalse(-1I.IsOne) + Assert.False(BigInteger(0).IsOne) + Assert.False((-BigInteger(0)).IsOne) + Assert.True(1I.IsOne) + Assert.True(BigInteger.One.IsOne) + Assert.True(BigInteger(1).IsOne) + Assert.False(-1I.IsOne) () - [] + [] member this.ToDouble() = Assert.AreEqual(double 0I, 0.0) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 @@ -291,7 +290,7 @@ type BigIntType() = Assert.AreEqual(double -123I, -123.0) () - [] + [] member this.ToInt32() = Assert.AreEqual(int32 0I, 0) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 @@ -302,7 +301,7 @@ type BigIntType() = Assert.AreEqual(int32 -123I, -123) () - [] + [] member this.ToInt64() = Assert.AreEqual(int64 0I, 0L) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 @@ -314,7 +313,7 @@ type BigIntType() = () - [] + [] member this.Zero() = Assert.AreEqual(BigInteger.Zero,0I) #if CROSS_PLATFORM_COMPILER // see https://bugzilla.xamarin.com/show_bug.cgi?id=22591 @@ -324,7 +323,7 @@ type BigIntType() = () // operators - [] + [] member this.Addition() = Assert.AreEqual((123I + 456I),579I) Assert.AreEqual((-123I + (-456I)),-579I) @@ -339,7 +338,7 @@ type BigIntType() = () - [] + [] member this.Division() = Assert.AreEqual((123I / 124I),0I) Assert.AreEqual((123I / (-124I)),0I) @@ -351,7 +350,7 @@ type BigIntType() = () - [] + [] member this.Equality() = Assert.AreEqual((bigPositiveA = bigPositiveA),true) Assert.AreEqual((bigPositiveA = bigNegativeA),false) @@ -365,7 +364,7 @@ type BigIntType() = () - [] + [] member this.GreaterThan() = Assert.AreEqual((bigPositiveA > bigPositiveB),false) Assert.AreEqual((bigNegativeA > bigPositiveB),false) @@ -381,7 +380,7 @@ type BigIntType() = () - [] + [] member this.GreaterThanOrEqual() = Assert.AreEqual((bigPositiveA >= bigPositiveB),false) Assert.AreEqual((bigPositiveA >= bigNegativeB),true) @@ -398,7 +397,7 @@ type BigIntType() = () - [] + [] member this.LessThan() = Assert.AreEqual((bigPositiveA < bigPositiveB),true) Assert.AreEqual((bigNegativeA < bigPositiveB),true) @@ -415,7 +414,7 @@ type BigIntType() = () - [] + [] member this.LessThanOrEqual() = Assert.AreEqual((bigPositiveA <= bigPositiveB),true) Assert.AreEqual((bigPositiveA <= bigNegativeB),false) @@ -432,7 +431,7 @@ type BigIntType() = () - [] + [] member this.Modulus() = Assert.AreEqual((bigPositiveA % bigPositiveB),bigPositiveA) Assert.AreEqual((bigNegativeA % bigNegativeB),bigNegativeA) @@ -446,7 +445,7 @@ type BigIntType() = () - [] + [] member this.Multiply() = Assert.AreEqual((123I * 100I),12300I) Assert.AreEqual((123I * (-100I)),-12300I) @@ -460,7 +459,7 @@ type BigIntType() = () - [] + [] member this.Range() = let resultPos = [123I..128I] let seqPos = @@ -499,7 +498,7 @@ type BigIntType() = () - [] + [] member this.RangeStep() = let resultPos = [100I .. 3I .. 109I] let seqPos = @@ -535,7 +534,7 @@ type BigIntType() = () - [] + [] member this.Subtraction() = Assert.AreEqual((100I - 123I),-23I) Assert.AreEqual((0I - bigPositiveB),bigNegativeB) @@ -551,7 +550,7 @@ type BigIntType() = () - [] + [] member this.UnaryNegation() = Assert.AreEqual(-bigPositiveA,bigNegativeA) Assert.AreEqual(-bigNegativeA,bigPositiveA) @@ -563,7 +562,7 @@ type BigIntType() = () - [] + [] member this.UnaryPlus() = Assert.AreEqual(+bigPositiveA,bigPositiveA) Assert.AreEqual(+bigNegativeA,bigNegativeA) @@ -576,7 +575,7 @@ type BigIntType() = () // instance methods - [] + [] member this.New_int32() = Assert.AreEqual(new BigInteger(0), 0I) Assert.AreEqual(new BigInteger(-10), -10I) @@ -584,7 +583,7 @@ type BigIntType() = () - [] + [] member this.New_int64() = Assert.AreEqual(new BigInteger(0L), 0I) Assert.AreEqual(new BigInteger(-100L), -100I) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ExtraTopLevelOperatorsTests.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ExtraTopLevelOperatorsTests.fs index f861189ae8f..147edbe1916 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ExtraTopLevelOperatorsTests.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ExtraTopLevelOperatorsTests.fs @@ -1,14 +1,13 @@ -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx open System.Collections open System.Collections.Generic -[] type DictTests () = - [] + [] member this.IEnumerable() = // Legit IE let ie = (dict [|(1,1);(2,4);(3,9)|]) :> IEnumerable @@ -38,7 +37,7 @@ type DictTests () = Assert.AreEqual(enum.MoveNext(), false) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IEnumerable_T() = // Legit IE let ie = (dict [|(1,1);(2,4);(3,9)|]) :> IEnumerable> @@ -69,13 +68,13 @@ type DictTests () = CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.IDictionary() = // Legit ID let id = (dict [|(1,1);(2,4);(3,9)|]) :> IDictionary<_,_> - Assert.IsTrue(id.ContainsKey(1)) - Assert.IsFalse(id.ContainsKey(5)) + Assert.True(id.ContainsKey(1)) + Assert.False(id.ContainsKey(5)) Assert.AreEqual(id.[1], 1) Assert.AreEqual(id.[3], 9) Assert.AreEqual(id.Keys, [| 1; 2; 3|]) @@ -85,56 +84,56 @@ type DictTests () = CheckThrowsNotSupportedException(fun () -> id.Add(new KeyValuePair(4,16))) let mutable value = 0 - Assert.IsTrue(id.TryGetValue(2, &value)) + Assert.True(id.TryGetValue(2, &value)) Assert.AreEqual(4, value) - Assert.IsFalse(id.TryGetValue(100, &value)) + Assert.False(id.TryGetValue(100, &value)) Assert.AreEqual(4, value) CheckThrowsNotSupportedException(fun () -> id.Remove(1) |> ignore) // Empty ID let id = dict [] :> IDictionary // Note no type args - Assert.IsFalse(id.ContainsKey(5)) + Assert.False(id.ContainsKey(5)) CheckThrowsKeyNotFoundException(fun () -> id.[1] |> ignore) Assert.AreEqual(id.Keys, [| |] ) Assert.AreEqual(id.Values, [| |] ) - [] + [] member this.``IReadOnlyDictionary on readOnlyDict``() = let irod = (readOnlyDict [|(1,1);(2,4);(3,9)|]) :> IReadOnlyDictionary<_,_> - Assert.IsTrue(irod.ContainsKey(1)) - Assert.IsFalse(irod.ContainsKey(5)) + Assert.True(irod.ContainsKey(1)) + Assert.False(irod.ContainsKey(5)) Assert.AreEqual(irod.[1], 1) Assert.AreEqual(irod.[3], 9) Assert.AreEqual(irod.Keys, [| 1; 2; 3|]) Assert.AreEqual(irod.Values, [| 1; 4; 9|]) let mutable value = 0 - Assert.IsTrue(irod.TryGetValue(2, &value)) + Assert.True(irod.TryGetValue(2, &value)) Assert.AreEqual(4, value) - Assert.IsFalse(irod.TryGetValue(100, &value)) + Assert.False(irod.TryGetValue(100, &value)) // value should not have been modified Assert.AreEqual(4, value) // Empty IROD let irod = readOnlyDict [] :> IReadOnlyDictionary // Note no type args - Assert.IsFalse(irod.ContainsKey(5)) + Assert.False(irod.ContainsKey(5)) CheckThrowsKeyNotFoundException(fun () -> irod.[1] |> ignore) Assert.AreEqual(irod.Keys, [| |] ) Assert.AreEqual(irod.Values, [| |] ) - [] + [] member this.ICollection() = // Legit IC let ic = (dict [|(1,1);(2,4);(3,9)|]) :> ICollection> Assert.AreEqual(ic.Count, 3) - Assert.IsTrue(ic.Contains(new KeyValuePair(3,9))) + Assert.True(ic.Contains(new KeyValuePair(3,9))) let newArr = Array.create 5 (new KeyValuePair(3,9)) ic.CopyTo(newArr,0) - Assert.IsTrue(ic.IsReadOnly) + Assert.True(ic.IsReadOnly) // raise ReadOnlyCollection exception @@ -145,11 +144,11 @@ type DictTests () = // Empty IC let ic = dict [] :> ICollection> - Assert.IsFalse(ic.Contains(new KeyValuePair(3,9))) + Assert.False(ic.Contains(new KeyValuePair(3,9))) let newArr = Array.create 5 (new KeyValuePair(0,0)) ic.CopyTo(newArr,0) - [] + [] member this.``IReadOnlyCollection on readOnlyDict``() = // Legit IROC let iroc = (readOnlyDict [|(1,1);(2,4);(3,9)|]) :> IReadOnlyCollection> @@ -161,7 +160,7 @@ type DictTests () = Assert.AreEqual(iroc.Count, 0) - [] + [] member this.``IEnumerable on readOnlyDict``() = // Legit IE let ie = (readOnlyDict [|(1,1);(2,4);(3,9)|]) :> IEnumerable @@ -191,7 +190,7 @@ type DictTests () = Assert.AreEqual(enum.MoveNext(), false) CheckThrowsInvalidOperationExn(fun () -> enum.Current |> ignore) - [] + [] member this.``IEnumerable_T on readOnlyDict``() = // Legit IE let ie = (readOnlyDict [|(1,1);(2,4);(3,9)|]) :> IEnumerable> diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversions.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversions.fs index 7aef9cc285d..da0bd19fb56 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversions.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversions.fs @@ -1,30 +1,29 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.FSharp.Core +namespace FSharp.Core.UnitTests open System -open NUnit.Framework +open Xunit open FSharp.Core.UnitTests.LibraryTestFx -[] type IntConversions() = - [] + [] member this.``Unchecked.SignedToUInt64`` () = let d = System.Int32.MinValue let e = uint64 d let f = uint64 (uint32 d) - Assert.IsTrue (e <> f) + Assert.True (e <> f) () - - [] + + [] member this.``Unchecked.SignedToUInt32`` () = let d = System.Int16.MinValue let e = uint32 d let f = uint32 (uint16 d) - Assert.IsTrue (e <> f) + Assert.True (e <> f) () - - [] + + [] member this.``Checked.UnsignedToSignedInt32``() = let d = System.UInt16.MaxValue CheckThrowsExn(fun() -> Checked.int16 d |> ignore) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsGenerated.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsGenerated.fs index 71eabe6e84e..b45edd17b6f 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsGenerated.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsGenerated.fs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. // This file is automatically generated by IntConversionsTestGenerator.fsx -namespace FSharp.Core.UnitTests.FSharp_Core.FSharp.Core -open System -open NUnit.Framework +namespace FSharp.Core.UnitTests +open System +open Xunit open FSharp.Core.UnitTests.LibraryTestFx module UInt8 = @@ -14,523 +14,522 @@ module Int8 = let MinValue = SByte.MinValue let MaxValue = SByte.MaxValue -[] type IntConversionsGenerated() = - [] + [] member this.``sbyte.m1.To.byte`` () = let i : sbyte = -1y Assert.AreEqual (Byte.MaxValue, byte i) - - [] + + [] member this.``int8.m1.To.byte`` () = let i : int8 = -1y Assert.AreEqual (Byte.MaxValue, byte i) - - [] + + [] member this.``int16.m1.To.byte`` () = let i : int16 = -1s Assert.AreEqual (Byte.MaxValue, byte i) - - [] + + [] member this.``int32.m1.To.byte`` () = let i : int32 = -1l Assert.AreEqual (Byte.MaxValue, byte i) - - [] + + [] member this.``int64.m1.To.byte`` () = let i : int64 = -1L Assert.AreEqual (Byte.MaxValue, byte i) - - [] + + [] member this.``sbyte.m1.To.uint8`` () = let i : sbyte = -1y Assert.AreEqual (UInt8.MaxValue, uint8 i) - - [] + + [] member this.``int8.m1.To.uint8`` () = let i : int8 = -1y Assert.AreEqual (UInt8.MaxValue, uint8 i) - - [] + + [] member this.``int16.m1.To.uint8`` () = let i : int16 = -1s Assert.AreEqual (UInt8.MaxValue, uint8 i) - [] + [] member this.``int32.m1.To.uint8`` () = let i : int32 = -1l Assert.AreEqual (UInt8.MaxValue, uint8 i) - [] + [] member this.``int64.m1.To.uint8`` () = let i : int64 = -1L Assert.AreEqual (UInt8.MaxValue, uint8 i) - [] + [] member this.``sbyte.m1.To.uint16`` () = let i : sbyte = -1y Assert.AreEqual (UInt16.MaxValue, uint16 i) - [] + [] member this.``int8.m1.To.uint16`` () = let i : int8 = -1y Assert.AreEqual (UInt16.MaxValue, uint16 i) - [] + [] member this.``int16.m1.To.uint16`` () = let i : int16 = -1s Assert.AreEqual (UInt16.MaxValue, uint16 i) - [] + [] member this.``int32.m1.To.uint16`` () = let i : int32 = -1l Assert.AreEqual (UInt16.MaxValue, uint16 i) - [] + [] member this.``int64.m1.To.uint16`` () = let i : int64 = -1L Assert.AreEqual (UInt16.MaxValue, uint16 i) - [] + [] member this.``sbyte.m1.To.uint32`` () = let i : sbyte = -1y Assert.AreEqual (UInt32.MaxValue, uint32 i) - [] + [] member this.``int8.m1.To.uint32`` () = let i : int8 = -1y Assert.AreEqual (UInt32.MaxValue, uint32 i) - [] + [] member this.``int16.m1.To.uint32`` () = let i : int16 = -1s Assert.AreEqual (UInt32.MaxValue, uint32 i) - [] + [] member this.``int32.m1.To.uint32`` () = let i : int32 = -1l Assert.AreEqual (UInt32.MaxValue, uint32 i) - [] + [] member this.``int64.m1.To.uint32`` () = let i : int64 = -1L Assert.AreEqual (UInt32.MaxValue, uint32 i) - [] + [] member this.``sbyte.m1.To.uint64`` () = let i : sbyte = -1y Assert.AreEqual (UInt64.MaxValue, uint64 i) - [] + [] member this.``int8.m1.To.uint64`` () = let i : int8 = -1y Assert.AreEqual (UInt64.MaxValue, uint64 i) - [] + [] member this.``int16.m1.To.uint64`` () = let i : int16 = -1s Assert.AreEqual (UInt64.MaxValue, uint64 i) - [] + [] member this.``int32.m1.To.uint64`` () = let i : int32 = -1l Assert.AreEqual (UInt64.MaxValue, uint64 i) - [] + [] member this.``int64.m1.To.uint64`` () = let i : int64 = -1L Assert.AreEqual (UInt64.MaxValue, uint64 i) - [] + [] member this.``sbyte.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : sbyte = -1y Assert.AreEqual (minus1, sbyte i) - [] + [] member this.``int8.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int8 = -1y Assert.AreEqual (minus1, sbyte i) - [] + [] member this.``int16.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int16 = -1s Assert.AreEqual (minus1, sbyte i) - [] + [] member this.``int32.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int32 = -1l Assert.AreEqual (minus1, sbyte i) - [] + [] member this.``int64.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int64 = -1L Assert.AreEqual (minus1, sbyte i) - [] + [] member this.``sbyte.m1.To.int8`` () = let minus1 : int8 = -1y let i : sbyte = -1y Assert.AreEqual (minus1, int8 i) - [] + [] member this.``int8.m1.To.int8`` () = let minus1 : int8 = -1y let i : int8 = -1y Assert.AreEqual (minus1, int8 i) - [] + [] member this.``int16.m1.To.int8`` () = let minus1 : int8 = -1y let i : int16 = -1s Assert.AreEqual (minus1, int8 i) - [] + [] member this.``int32.m1.To.int8`` () = let minus1 : int8 = -1y let i : int32 = -1l Assert.AreEqual (minus1, int8 i) - [] + [] member this.``int64.m1.To.int8`` () = let minus1 : int8 = -1y let i : int64 = -1L Assert.AreEqual (minus1, int8 i) - [] + [] member this.``sbyte.m1.To.int16`` () = let minus1 : int16 = -1s let i : sbyte = -1y Assert.AreEqual (minus1, int16 i) - [] + [] member this.``int8.m1.To.int16`` () = let minus1 : int16 = -1s let i : int8 = -1y Assert.AreEqual (minus1, int16 i) - [] + [] member this.``int16.m1.To.int16`` () = let minus1 : int16 = -1s let i : int16 = -1s Assert.AreEqual (minus1, int16 i) - [] + [] member this.``int32.m1.To.int16`` () = let minus1 : int16 = -1s let i : int32 = -1l Assert.AreEqual (minus1, int16 i) - [] + [] member this.``int64.m1.To.int16`` () = let minus1 : int16 = -1s let i : int64 = -1L Assert.AreEqual (minus1, int16 i) - [] + [] member this.``sbyte.m1.To.int32`` () = let minus1 : int32 = -1l let i : sbyte = -1y Assert.AreEqual (minus1, int32 i) - [] + [] member this.``int8.m1.To.int32`` () = let minus1 : int32 = -1l let i : int8 = -1y Assert.AreEqual (minus1, int32 i) - [] + [] member this.``int16.m1.To.int32`` () = let minus1 : int32 = -1l let i : int16 = -1s Assert.AreEqual (minus1, int32 i) - [] + [] member this.``int32.m1.To.int32`` () = let minus1 : int32 = -1l let i : int32 = -1l Assert.AreEqual (minus1, int32 i) - [] + [] member this.``int64.m1.To.int32`` () = let minus1 : int32 = -1l let i : int64 = -1L Assert.AreEqual (minus1, int32 i) - [] + [] member this.``sbyte.m1.To.int64`` () = let minus1 : int64 = -1L let i : sbyte = -1y Assert.AreEqual (minus1, int64 i) - [] + [] member this.``int8.m1.To.int64`` () = let minus1 : int64 = -1L let i : int8 = -1y Assert.AreEqual (minus1, int64 i) - [] + [] member this.``int16.m1.To.int64`` () = let minus1 : int64 = -1L let i : int16 = -1s Assert.AreEqual (minus1, int64 i) - [] + [] member this.``int32.m1.To.int64`` () = let minus1 : int64 = -1L let i : int32 = -1l Assert.AreEqual (minus1, int64 i) - [] + [] member this.``int64.m1.To.int64`` () = let minus1 : int64 = -1L let i : int64 = -1L Assert.AreEqual (minus1, int64 i) - [] + [] member this.``byte.MaxValue.To.int16`` () = let sourceMaxValue : int16 = 0xFFs Assert.AreEqual (sourceMaxValue, int16 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.int16`` () = let sourceMaxValue : int16 = 0xFFs Assert.AreEqual (sourceMaxValue, int16 UInt8.MaxValue) - [] + [] member this.``byte.MaxValue.To.uint16`` () = let sourceMaxValue : uint16 = 0xFFus Assert.AreEqual (sourceMaxValue, uint16 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.uint16`` () = let sourceMaxValue : uint16 = 0xFFus Assert.AreEqual (sourceMaxValue, uint16 UInt8.MaxValue) - [] + [] member this.``byte.MaxValue.To.int32`` () = let sourceMaxValue : int32 = 0xFFl Assert.AreEqual (sourceMaxValue, int32 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.int32`` () = let sourceMaxValue : int32 = 0xFFl Assert.AreEqual (sourceMaxValue, int32 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.int32`` () = let sourceMaxValue : int32 = 0xFFFFl Assert.AreEqual (sourceMaxValue, int32 UInt16.MaxValue) - [] + [] member this.``byte.MaxValue.To.uint32`` () = let sourceMaxValue : uint32 = 0xFFul Assert.AreEqual (sourceMaxValue, uint32 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.uint32`` () = let sourceMaxValue : uint32 = 0xFFul Assert.AreEqual (sourceMaxValue, uint32 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.uint32`` () = let sourceMaxValue : uint32 = 0xFFFFul Assert.AreEqual (sourceMaxValue, uint32 UInt16.MaxValue) - [] + [] member this.``byte.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFL Assert.AreEqual (sourceMaxValue, int64 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFL Assert.AreEqual (sourceMaxValue, int64 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFFFL Assert.AreEqual (sourceMaxValue, int64 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFFFFFFFL Assert.AreEqual (sourceMaxValue, int64 UInt32.MaxValue) - [] + [] member this.``byte.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFuL Assert.AreEqual (sourceMaxValue, uint64 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFuL Assert.AreEqual (sourceMaxValue, uint64 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFFFuL Assert.AreEqual (sourceMaxValue, uint64 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFFFFFFFuL Assert.AreEqual (sourceMaxValue, uint64 UInt32.MaxValue) - [] + [] member this.``byte.MaxValue.To.sbyte`` () = Assert.AreEqual (-1y, sbyte Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.sbyte`` () = Assert.AreEqual (-1y, sbyte UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.sbyte`` () = Assert.AreEqual (-1y, sbyte UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.sbyte`` () = Assert.AreEqual (-1y, sbyte UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.sbyte`` () = Assert.AreEqual (-1y, sbyte UInt64.MaxValue) - [] + [] member this.``byte.MaxValue.To.int8`` () = Assert.AreEqual (-1y, int8 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.int8`` () = Assert.AreEqual (-1y, int8 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.int8`` () = Assert.AreEqual (-1y, int8 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.int8`` () = Assert.AreEqual (-1y, int8 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.int8`` () = Assert.AreEqual (-1y, int8 UInt64.MaxValue) - [] + [] member this.``uint16.MaxValue.To.int16`` () = Assert.AreEqual (-1s, int16 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.int16`` () = Assert.AreEqual (-1s, int16 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.int16`` () = Assert.AreEqual (-1s, int16 UInt64.MaxValue) - [] + [] member this.``uint32.MaxValue.To.int32`` () = Assert.AreEqual (-1l, int32 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.int32`` () = Assert.AreEqual (-1l, int32 UInt64.MaxValue) - [] + [] member this.``uint64.MaxValue.To.int64`` () = Assert.AreEqual (-1L, int64 UInt64.MaxValue) - [] + [] member this.``byte.MaxValue.To.byte`` () = Assert.AreEqual (Byte.MaxValue, byte Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.byte`` () = Assert.AreEqual (Byte.MaxValue, byte UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.byte`` () = Assert.AreEqual (Byte.MaxValue, byte UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.byte`` () = Assert.AreEqual (Byte.MaxValue, byte UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.byte`` () = Assert.AreEqual (Byte.MaxValue, byte UInt64.MaxValue) - [] + [] member this.``byte.MaxValue.To.uint8`` () = Assert.AreEqual (UInt8.MaxValue, uint8 Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.uint8`` () = Assert.AreEqual (UInt8.MaxValue, uint8 UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.uint8`` () = Assert.AreEqual (UInt8.MaxValue, uint8 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.uint8`` () = Assert.AreEqual (UInt8.MaxValue, uint8 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.uint8`` () = Assert.AreEqual (UInt8.MaxValue, uint8 UInt64.MaxValue) - [] + [] member this.``uint16.MaxValue.To.uint16`` () = Assert.AreEqual (UInt16.MaxValue, uint16 UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.uint16`` () = Assert.AreEqual (UInt16.MaxValue, uint16 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.uint16`` () = Assert.AreEqual (UInt16.MaxValue, uint16 UInt64.MaxValue) - [] + [] member this.``uint32.MaxValue.To.uint32`` () = Assert.AreEqual (UInt32.MaxValue, uint32 UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.uint32`` () = Assert.AreEqual (UInt32.MaxValue, uint32 UInt64.MaxValue) - [] + [] member this.``uint64.MaxValue.To.uint64`` () = Assert.AreEqual (UInt64.MaxValue, uint64 UInt64.MaxValue) - [] + [] member this.``sbyte.m1.To.nativeint`` () = Assert.AreEqual (-1n, nativeint -1y) - [] + [] member this.``int8.m1.To.nativeint`` () = Assert.AreEqual (-1n, nativeint -1y) - [] + [] member this.``int16.m1.To.nativeint`` () = Assert.AreEqual (-1n, nativeint -1s) - [] + [] member this.``int32.m1.To.nativeint`` () = Assert.AreEqual (-1n, nativeint -1l) - [] + [] member this.``int64.m1.To.nativeint`` () = Assert.AreEqual (-1n, nativeint -1L) - [] + [] member this.``byte.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFn @@ -538,7 +537,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (-1n, nativeint Byte.MaxValue) - [] + [] member this.``uint8.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFn @@ -546,7 +545,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (-1n, nativeint UInt8.MaxValue) - [] + [] member this.``uint16.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFn @@ -554,7 +553,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (-1n, nativeint UInt16.MaxValue) - [] + [] member this.``uint32.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFFFFFn @@ -562,7 +561,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (-1n, nativeint UInt32.MaxValue) - [] + [] member this.``uint64.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFFFFFFFFFFFFFn @@ -576,27 +575,27 @@ type IntConversionsGenerated() = unativeintMaxValue <- (unativeintMaxValue <<< 8) ||| 0xFFun unativeintMaxValue - [] + [] member this.``sbyte.m1.To.unativeint`` () = Assert.AreEqual (this.UnativeintMaxValue, unativeint -1y) - [] + [] member this.``int8.m1.To.unativeint`` () = Assert.AreEqual (this.UnativeintMaxValue, unativeint -1y) - [] + [] member this.``int16.m1.To.unativeint`` () = Assert.AreEqual (this.UnativeintMaxValue, unativeint -1s) - [] + [] member this.``int32.m1.To.unativeint`` () = Assert.AreEqual (this.UnativeintMaxValue, unativeint -1l) - [] + [] member this.``int64.m1.To.unativeint`` () = Assert.AreEqual (this.UnativeintMaxValue, unativeint -1L) - [] + [] member this.``byte.m1.To.unativeint`` () = if sizeof > sizeof then let sourceMaxValue : unativeint = 0xFFun @@ -604,7 +603,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (this.UnativeintMaxValue, unativeint Byte.MaxValue) - [] + [] member this.``uint8.m1.To.unativeint`` () = if sizeof > sizeof then let sourceMaxValue : unativeint = 0xFFun @@ -612,7 +611,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (this.UnativeintMaxValue, unativeint UInt8.MaxValue) - [] + [] member this.``uint16.m1.To.unativeint`` () = if sizeof > sizeof then let sourceMaxValue : unativeint = 0xFFFFun @@ -620,7 +619,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (this.UnativeintMaxValue, unativeint UInt16.MaxValue) - [] + [] member this.``uint32.m1.To.unativeint`` () = if sizeof > sizeof then let sourceMaxValue : unativeint = 0xFFFFFFFFun @@ -628,7 +627,7 @@ type IntConversionsGenerated() = else Assert.AreEqual (this.UnativeintMaxValue, unativeint UInt32.MaxValue) - [] + [] member this.``uint64.m1.To.unativeint`` () = if sizeof > sizeof then let sourceMaxValue : unativeint = 0xFFFFFFFFFFFFFFFFun @@ -636,323 +635,323 @@ type IntConversionsGenerated() = else Assert.AreEqual (this.UnativeintMaxValue, unativeint UInt64.MaxValue) - [] + [] member this.``Checked.sbyte.m1.To.byte`` () = let i : sbyte = -1y CheckThrowsExn(fun () -> Checked.byte i |> ignore) - [] + [] member this.``Checked.int16.m1.To.byte`` () = let i : int16 = -1s CheckThrowsExn(fun () -> Checked.byte i |> ignore) - [] + [] member this.``Checked.int32.m1.To.byte`` () = let i : int32 = -1l CheckThrowsExn(fun () -> Checked.byte i |> ignore) - [] + [] member this.``Checked.int64.m1.To.byte`` () = let i : int64 = -1L CheckThrowsExn(fun () -> Checked.byte i |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.uint16`` () = let i : sbyte = -1y CheckThrowsExn(fun () -> Checked.uint16 i |> ignore) - [] + [] member this.``Checked.int16.m1.To.uint16`` () = let i : int16 = -1s CheckThrowsExn(fun () -> Checked.uint16 i |> ignore) - [] + [] member this.``Checked.int32.m1.To.uint16`` () = let i : int32 = -1l CheckThrowsExn(fun () -> Checked.uint16 i |> ignore) - [] + [] member this.``Checked.int64.m1.To.uint16`` () = let i : int64 = -1L CheckThrowsExn(fun () -> Checked.uint16 i |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.uint32`` () = let i : sbyte = -1y CheckThrowsExn(fun () -> Checked.uint32 i |> ignore) - [] + [] member this.``Checked.int16.m1.To.uint32`` () = let i : int16 = -1s CheckThrowsExn(fun () -> Checked.uint32 i |> ignore) - [] + [] member this.``Checked.int32.m1.To.uint32`` () = let i : int32 = -1l CheckThrowsExn(fun () -> Checked.uint32 i |> ignore) - [] + [] member this.``Checked.int64.m1.To.uint32`` () = let i : int64 = -1L CheckThrowsExn(fun () -> Checked.uint32 i |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.uint64`` () = let i : sbyte = -1y CheckThrowsExn(fun () -> Checked.uint64 i |> ignore) - [] + [] member this.``Checked.int16.m1.To.uint64`` () = let i : int16 = -1s CheckThrowsExn(fun () -> Checked.uint64 i |> ignore) - [] + [] member this.``Checked.int32.m1.To.uint64`` () = let i : int32 = -1l CheckThrowsExn(fun () -> Checked.uint64 i |> ignore) - [] + [] member this.``Checked.int64.m1.To.uint64`` () = let i : int64 = -1L CheckThrowsExn(fun () -> Checked.uint64 i |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : sbyte = -1y Assert.AreEqual (minus1, Checked.sbyte i) - [] + [] member this.``Checked.int16.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int16 = -1s Assert.AreEqual (minus1, Checked.sbyte i) - [] + [] member this.``Checked.int32.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int32 = -1l Assert.AreEqual (minus1, Checked.sbyte i) - [] + [] member this.``Checked.int64.m1.To.sbyte`` () = let minus1 : sbyte = -1y let i : int64 = -1L Assert.AreEqual (minus1, Checked.sbyte i) - [] + [] member this.``Checked.sbyte.m1.To.int16`` () = let minus1 : int16 = -1s let i : sbyte = -1y Assert.AreEqual (minus1, Checked.int16 i) - [] + [] member this.``Checked.int16.m1.To.int16`` () = let minus1 : int16 = -1s let i : int16 = -1s Assert.AreEqual (minus1, Checked.int16 i) - [] + [] member this.``Checked.int32.m1.To.int16`` () = let minus1 : int16 = -1s let i : int32 = -1l Assert.AreEqual (minus1, Checked.int16 i) - [] + [] member this.``Checked.int64.m1.To.int16`` () = let minus1 : int16 = -1s let i : int64 = -1L Assert.AreEqual (minus1, Checked.int16 i) - [] + [] member this.``Checked.sbyte.m1.To.int32`` () = let minus1 : int32 = -1l let i : sbyte = -1y Assert.AreEqual (minus1, Checked.int32 i) - [] + [] member this.``Checked.int16.m1.To.int32`` () = let minus1 : int32 = -1l let i : int16 = -1s Assert.AreEqual (minus1, Checked.int32 i) - [] + [] member this.``Checked.int32.m1.To.int32`` () = let minus1 : int32 = -1l let i : int32 = -1l Assert.AreEqual (minus1, Checked.int32 i) - [] + [] member this.``Checked.int64.m1.To.int32`` () = let minus1 : int32 = -1l let i : int64 = -1L Assert.AreEqual (minus1, Checked.int32 i) - [] + [] member this.``Checked.sbyte.m1.To.int64`` () = let minus1 : int64 = -1L let i : sbyte = -1y Assert.AreEqual (minus1, Checked.int64 i) - [] + [] member this.``Checked.int16.m1.To.int64`` () = let minus1 : int64 = -1L let i : int16 = -1s Assert.AreEqual (minus1, Checked.int64 i) - [] + [] member this.``Checked.int32.m1.To.int64`` () = let minus1 : int64 = -1L let i : int32 = -1l Assert.AreEqual (minus1, Checked.int64 i) - [] + [] member this.``Checked.int64.m1.To.int64`` () = let minus1 : int64 = -1L let i : int64 = -1L Assert.AreEqual (minus1, Checked.int64 i) - [] + [] member this.``Checked.byte.MaxValue.To.int16`` () = let sourceMaxValue : int16 = 0xFFs Assert.AreEqual (sourceMaxValue, Checked.int16 Byte.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.uint16`` () = let sourceMaxValue : uint16 = 0xFFus Assert.AreEqual (sourceMaxValue, Checked.uint16 Byte.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.int32`` () = let sourceMaxValue : int32 = 0xFFl Assert.AreEqual (sourceMaxValue, Checked.int32 Byte.MaxValue) - [] + [] member this.``Checked.uint16.MaxValue.To.int32`` () = let sourceMaxValue : int32 = 0xFFFFl Assert.AreEqual (sourceMaxValue, Checked.int32 UInt16.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.uint32`` () = let sourceMaxValue : uint32 = 0xFFul Assert.AreEqual (sourceMaxValue, Checked.uint32 Byte.MaxValue) - [] + [] member this.``Checked.uint16.MaxValue.To.uint32`` () = let sourceMaxValue : uint32 = 0xFFFFul Assert.AreEqual (sourceMaxValue, Checked.uint32 UInt16.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFL Assert.AreEqual (sourceMaxValue, Checked.int64 Byte.MaxValue) - [] + [] member this.``Checked.uint16.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFFFL Assert.AreEqual (sourceMaxValue, Checked.int64 UInt16.MaxValue) - [] + [] member this.``Checked.uint32.MaxValue.To.int64`` () = let sourceMaxValue : int64 = 0xFFFFFFFFL Assert.AreEqual (sourceMaxValue, Checked.int64 UInt32.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFuL Assert.AreEqual (sourceMaxValue, Checked.uint64 Byte.MaxValue) - [] + [] member this.``Checked.uint16.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFFFuL Assert.AreEqual (sourceMaxValue, Checked.uint64 UInt16.MaxValue) - [] + [] member this.``Checked.uint32.MaxValue.To.uint64`` () = let sourceMaxValue : uint64 = 0xFFFFFFFFuL Assert.AreEqual (sourceMaxValue, Checked.uint64 UInt32.MaxValue) - [] + [] member this.``Checked.byte.MaxValue.To.sbyte`` () = CheckThrowsExn (fun () -> Checked.sbyte Byte.MaxValue |> ignore) - [] + [] member this.``Checked.uint16.MaxValue.To.sbyte`` () = CheckThrowsExn (fun () -> Checked.sbyte UInt16.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.sbyte`` () = CheckThrowsExn (fun () -> Checked.sbyte UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.sbyte`` () = CheckThrowsExn (fun () -> Checked.sbyte UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint16.MaxValue.To.int16`` () = CheckThrowsExn (fun () -> Checked.int16 UInt16.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.int16`` () = CheckThrowsExn (fun () -> Checked.int16 UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.int16`` () = CheckThrowsExn (fun () -> Checked.int16 UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.int32`` () = CheckThrowsExn (fun () -> Checked.int32 UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.int32`` () = CheckThrowsExn (fun () -> Checked.int32 UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.int64`` () = CheckThrowsExn (fun () -> Checked.int64 UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint16.MaxValue.To.byte`` () = CheckThrowsExn (fun () -> Checked.byte UInt16.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.byte`` () = CheckThrowsExn (fun () -> Checked.byte UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.byte`` () = CheckThrowsExn (fun () -> Checked.byte UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.uint16`` () = CheckThrowsExn (fun () -> Checked.uint16 UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.uint16`` () = CheckThrowsExn (fun () -> Checked.uint16 UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.uint32`` () = CheckThrowsExn (fun () -> Checked.uint32 UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.nativeint`` () = Assert.AreEqual (-1n, Checked.nativeint -1y) - [] + [] member this.``Checked.int16.m1.To.nativeint`` () = Assert.AreEqual (-1n, Checked.nativeint -1s) - [] + [] member this.``Checked.int32.m1.To.nativeint`` () = Assert.AreEqual (-1n, Checked.nativeint -1l) - [] + [] member this.``Checked.int64.m1.To.nativeint`` () = Assert.AreEqual (-1n, Checked.nativeint -1L) - [] + [] member this.``Checked.byte.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFn @@ -960,7 +959,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.nativeint Byte.MaxValue |> ignore) - [] + [] member this.``Checked.uint16.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFn @@ -968,7 +967,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.nativeint UInt16.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFFFFFn @@ -976,7 +975,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.nativeint UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.nativeint`` () = if sizeof > sizeof then let sourceMaxValue : nativeint = 0xFFFFFFFFFFFFFFFFn @@ -984,23 +983,23 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.nativeint UInt64.MaxValue |> ignore) - [] + [] member this.``Checked.sbyte.m1.To.unativeint`` () = CheckThrowsExn (fun () -> Checked.unativeint -1y |> ignore) - [] + [] member this.``Checked.int16.m1.To.unativeint`` () = CheckThrowsExn (fun () -> Checked.unativeint -1s |> ignore) - [] + [] member this.``Checked.int32.m1.To.unativeint`` () = CheckThrowsExn (fun () -> Checked.unativeint -1l |> ignore) - [] + [] member this.``Checked.int64.m1.To.unativeint`` () = CheckThrowsExn (fun () -> Checked.unativeint -1L |> ignore) - [] + [] member this.``Checked.byte.MaxValue.To.unativeint`` () = if sizeof >= sizeof then let sourceMaxValue : unativeint = 0xFFun @@ -1008,7 +1007,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.unativeint Byte.MaxValue |> ignore) - [] + [] member this.``Checked.uint16.MaxValue.To.unativeint`` () = if sizeof >= sizeof then let sourceMaxValue : unativeint = 0xFFFFun @@ -1016,7 +1015,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.unativeint UInt16.MaxValue |> ignore) - [] + [] member this.``Checked.uint32.MaxValue.To.unativeint`` () = if sizeof >= sizeof then let sourceMaxValue : unativeint = 0xFFFFFFFFun @@ -1024,7 +1023,7 @@ type IntConversionsGenerated() = else CheckThrowsExn (fun () -> Checked.unativeint UInt32.MaxValue |> ignore) - [] + [] member this.``Checked.uint64.MaxValue.To.unativeint`` () = if sizeof >= sizeof then let sourceMaxValue : unativeint = 0xFFFFFFFFFFFFFFFFun diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsTestGenerator.fsx b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsTestGenerator.fsx index 3e6dd65d722..34ca62bcebd 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsTestGenerator.fsx +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/IntConversionsTestGenerator.fsx @@ -43,7 +43,7 @@ do let preamble = @" // This file is automatically generated by IntConversionsTestGenerator.fsx -namespace FSharp.Core.UnitTests.FSharp_Core.FSharp.Core +namespace FSharp.Core.UnitTests open System open NUnit.Framework open FSharp.Core.UnitTests.LibraryTestFx diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs index eaebc3df744..50e6b325d8e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests -open NUnit.Framework +open Xunit // Various tests for the: // Microsoft.FSharp.Core.Option module @@ -15,19 +15,18 @@ Make sure each method works on: * None (0 elements) *) -[] type OptionModule() = let assertWasNotCalledThunk () = raise (exn "Thunk should not have been called.") - [] + [] member this.Flatten () = Assert.AreEqual( Option.flatten None, None) Assert.AreEqual( Option.flatten (Some None), None) Assert.AreEqual( Option.flatten (Some <| Some 1), Some 1) Assert.AreEqual( Option.flatten (Some <| Some ""), Some "") - [] + [] member this.FilterSomeIntegerWhenPredicateReturnsTrue () = let test x = let actual = x |> Some |> Option.filter (fun _ -> true) @@ -36,7 +35,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [0;1;-1;42] |> List.iter test - [] + [] member this.FilterSomeStringWhenPredicateReturnsTrue () = let test x = let actual = x |> Some |> Option.filter (fun _ -> true) @@ -45,7 +44,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [""; " "; "Foo"; "Bar"] |> List.iter test - [] + [] member this.FilterSomeIntegerWhenPredicateReturnsFalse () = let test x = let actual = x |> Some |> Option.filter (fun _ -> false) @@ -54,7 +53,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [0; 1; -1; 1337] |> List.iter test - [] + [] member this.FilterSomeStringWhenPredicateReturnsFalse () = let test x = let actual = x |> Some |> Option.filter (fun _ -> false) @@ -63,7 +62,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [""; " "; "Ploeh"; "Fnaah"] |> List.iter test - [] + [] member this.FilterNoneReturnsCorrectResult () = let test x = let actual = None |> Option.filter (fun _ -> x) @@ -72,7 +71,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [false; true] |> List.iter test - [] + [] member this.FilterSomeIntegerWhenPredicateEqualsInput () = let test x = let actual = x |> Some |> Option.filter ((=) x) @@ -81,7 +80,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [0; 1; -1; -2001] |> List.iter test - [] + [] member this.FilterSomeStringWhenPredicateEqualsInput () = let test x = let actual = x |> Some |> Option.filter ((=) x) @@ -90,7 +89,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [""; " "; "Xyzz"; "Sgryt"] |> List.iter test - [] + [] member this.FilterSomeIntegerWhenPredicateDoesNotEqualsInput () = let test x = let actual = x |> Some |> Option.filter ((<>) x) @@ -99,7 +98,7 @@ type OptionModule() = Assert.AreEqual(expected, actual) [0; 1; -1; 927] |> List.iter test - [] + [] member this.FilterSomeStringWhenPredicateDoesNotEqualsInput () = let test x = let actual = x |> Some |> Option.filter ((<>) x) @@ -108,48 +107,48 @@ type OptionModule() = Assert.AreEqual(expected, actual) [""; " "; "Baz Quux"; "Corge grault"] |> List.iter test - [] + [] member this.Contains() = - Assert.IsFalse( Option.contains 1 None) - Assert.IsTrue( Option.contains 1 (Some 1)) + Assert.False( Option.contains 1 None) + Assert.True( Option.contains 1 (Some 1)) - Assert.IsFalse( Option.contains "" None) - Assert.IsTrue( Option.contains "" (Some "")) + Assert.False( Option.contains "" None) + Assert.True( Option.contains "" (Some "")) - Assert.IsFalse( Option.contains None None) - Assert.IsTrue( Option.contains None (Some None)) - [] + Assert.False( Option.contains None None) + Assert.True( Option.contains None (Some None)) + [] member this.OfToNullable() = - Assert.IsTrue( Option.ofNullable (System.Nullable()) = None) - Assert.IsTrue( Option.ofNullable (System.Nullable(3)) = Some 3) + Assert.True( Option.ofNullable (System.Nullable()) = None) + Assert.True( Option.ofNullable (System.Nullable(3)) = Some 3) - Assert.IsTrue( Option.toNullable (None : int option) = System.Nullable()) - Assert.IsTrue( Option.toNullable (None : System.DateTime option) = System.Nullable()) - Assert.IsTrue( Option.toNullable (Some 3) = System.Nullable(3)) + Assert.True( Option.toNullable (None : int option) = System.Nullable()) + Assert.True( Option.toNullable (None : System.DateTime option) = System.Nullable()) + Assert.True( Option.toNullable (Some 3) = System.Nullable(3)) - [] + [] member this.OfToObj() = - Assert.IsTrue( Option.toObj (Some "3") = "3") - Assert.IsTrue( Option.toObj (Some "") = "") - Assert.IsTrue( Option.toObj (Some null) = null) - Assert.IsTrue( Option.toObj None = null) + Assert.True( Option.toObj (Some "3") = "3") + Assert.True( Option.toObj (Some "") = "") + Assert.True( Option.toObj (Some null) = null) + Assert.True( Option.toObj None = null) - Assert.IsTrue( Option.ofObj "3" = Some "3") - Assert.IsTrue( Option.ofObj "" = Some "") - Assert.IsTrue( Option.ofObj [| "" |] = Some [| "" |]) - Assert.IsTrue( Option.ofObj (null : string array) = None) - Assert.IsTrue( Option.ofObj null = None) - Assert.IsTrue( Option.ofObj null = None) - Assert.IsTrue( Option.ofObj null = None) - - [] + Assert.True( Option.ofObj "3" = Some "3") + Assert.True( Option.ofObj "" = Some "") + Assert.True( Option.ofObj [| "" |] = Some [| "" |]) + Assert.True( Option.ofObj (null : string array) = None) + Assert.True( Option.ofObj null = None) + Assert.True( Option.ofObj null = None) + Assert.True( Option.ofObj null = None) + + [] member this.DefaultValue() = Assert.AreEqual( Option.defaultValue 3 None, 3) Assert.AreEqual( Option.defaultValue 3 (Some 42), 42) Assert.AreEqual( Option.defaultValue "" None, "") Assert.AreEqual( Option.defaultValue "" (Some "x"), "x") - [] + [] member this.DefaultWith() = Assert.AreEqual( Option.defaultWith (fun () -> 3) None, 3) Assert.AreEqual( Option.defaultWith (fun () -> "") None, "") @@ -157,7 +156,7 @@ type OptionModule() = Assert.AreEqual( Option.defaultWith assertWasNotCalledThunk (Some 42), 42) Assert.AreEqual( Option.defaultWith assertWasNotCalledThunk (Some ""), "") - [] + [] member this.OrElse() = Assert.AreEqual( Option.orElse None None, None) Assert.AreEqual( Option.orElse (Some 3) None, Some 3) @@ -168,7 +167,7 @@ type OptionModule() = Assert.AreEqual( Option.orElse None (Some "x"), Some "x") Assert.AreEqual( Option.orElse (Some "") (Some "x"), Some "x") - [] + [] member this.OrElseWith() = Assert.AreEqual( Option.orElseWith (fun () -> None) None, None) Assert.AreEqual( Option.orElseWith (fun () -> Some 3) None, Some 3) @@ -177,7 +176,7 @@ type OptionModule() = Assert.AreEqual( Option.orElseWith assertWasNotCalledThunk (Some 42), Some 42) Assert.AreEqual( Option.orElseWith assertWasNotCalledThunk (Some ""), Some "") - [] + [] member this.Map2() = Assert.AreEqual( Option.map2 (-) None None, None) Assert.AreEqual( Option.map2 (-) (Some 1) None, None) @@ -189,7 +188,7 @@ type OptionModule() = Assert.AreEqual( Option.map2 (+) None (Some "y"), None) Assert.AreEqual( Option.map2 (+) (Some "x") (Some "y"), Some "xy") - [] + [] member this.Map3() = let add3 x y z = string x + string y + string z Assert.AreEqual( Option.map3 add3 None None None, None) @@ -211,28 +210,27 @@ type OptionModule() = Assert.AreEqual( Option.map3 concat3 None (Some "y") (Some "z"), None) Assert.AreEqual( Option.map3 concat3 (Some "x") (Some "y") (Some "z"), Some "xyz") - [] + [] member this.MapBindEquivalenceProperties () = let fn x = x + 3 Assert.AreEqual(Option.map fn None, Option.bind (fn >> Some) None) Assert.AreEqual(Option.map fn (Some 5), Option.bind (fn >> Some) (Some 5)) -[] type ValueOptionTests() = let assertWasNotCalledThunk () = raise (exn "Thunk should not have been called.") - [] + [] member _.``ValueNone gives "ValueNone" when calling ToString`` () = Assert.AreEqual("ValueNone", ValueNone.ToString()) Assert.AreEqual("ValueNone", string ValueNone) - [] + [] member _.``ValueNone with sprintf`` () = Assert.AreEqual("ValueNone", sprintf "%O" (ValueNone.ToString())) Assert.AreEqual("ValueNone", sprintf "%A" ValueNone) - [] + [] member this.ValueOptionBasics () = Assert.AreEqual((ValueNone: int voption), (ValueNone: int voption)) Assert.True((ValueNone: int voption) <= (ValueNone: int voption)) @@ -259,14 +257,14 @@ type ValueOptionTests() = Assert.AreEqual(defaultValueArg ValueNone 1, 1) Assert.AreEqual(defaultValueArg (ValueSome 3) 1, 3) - [] + [] member this.Flatten () = Assert.AreEqual(ValueOption.flatten ValueNone, ValueNone) Assert.AreEqual(ValueOption.flatten (ValueSome ValueNone), ValueNone) Assert.AreEqual(ValueOption.flatten (ValueSome <| ValueSome 1), ValueSome 1) Assert.AreEqual(ValueOption.flatten (ValueSome <| ValueSome ""), ValueSome "") - [] + [] member this.FilterValueSomeIntegerWhenPredicateReturnsTrue () = let test x = let actual = x |> ValueSome |> ValueOption.filter (fun _ -> true) @@ -275,7 +273,7 @@ type ValueOptionTests() = |> Assert.True [0;1;-1;42] |> List.iter test - [] + [] member this.FilterValueSomeStringWhenPredicateReturnsTrue () = let test x = let actual = x |> ValueSome |> ValueOption.filter (fun _ -> true) @@ -284,7 +282,7 @@ type ValueOptionTests() = |> Assert.True [""; " "; "Foo"; "Bar"] |> List.iter test - [] + [] member this.FilterValueSomeIntegerWhenPredicateReturnsFalse () = let test x = let actual = x |> ValueSome |> ValueOption.filter (fun _ -> false) @@ -293,7 +291,7 @@ type ValueOptionTests() = |> Assert.True [0; 1; -1; 1337] |> List.iter test - [] + [] member this.FilterValueSomeStringWhenPredicateReturnsFalse () = let test x = let actual = x |> ValueSome |> ValueOption.filter (fun _ -> false) @@ -302,7 +300,7 @@ type ValueOptionTests() = |> Assert.True [""; " "; "Ploeh"; "Fnaah"] |> List.iter test - [] + [] member this.FilterValueNoneReturnsCorrectResult () = let test x = let actual = ValueNone |> ValueOption.filter (fun _ -> x) @@ -311,7 +309,7 @@ type ValueOptionTests() = |> Assert.True [false; true] |> List.iter test - [] + [] member this.FilterValueSomeIntegerWhenPredicateEqualsInput () = let test x = let actual = x |> ValueSome |> ValueOption.filter ((=) x) @@ -320,7 +318,7 @@ type ValueOptionTests() = |> Assert.True [0; 1; -1; -2001] |> List.iter test - [] + [] member this.FilterValueSomeStringWhenPredicateEqualsInput () = let test x = let actual = x |> ValueSome |> ValueOption.filter ((=) x) @@ -329,7 +327,7 @@ type ValueOptionTests() = |> Assert.True [""; " "; "Xyzz"; "Sgryt"] |> List.iter test - [] + [] member this.FilterValueSomeIntegerWhenPredicateDoesNotEqualsInput () = let test x = let actual = x |> ValueSome |> ValueOption.filter ((<>) x) @@ -338,7 +336,7 @@ type ValueOptionTests() = |> Assert.True [0; 1; -1; 927] |> List.iter test - [] + [] member this.FilterValueSomeStringWhenPredicateDoesNotEqualsInput () = let test x = let actual = x |> ValueSome |> ValueOption.filter ((<>) x) @@ -347,48 +345,48 @@ type ValueOptionTests() = |> Assert.True [""; " "; "Baz Quux"; "Corge grault"] |> List.iter test - [] + [] member this.Contains() = - Assert.IsFalse(ValueOption.contains 1 ValueNone) - Assert.IsTrue(ValueOption.contains 1 (ValueSome 1)) + Assert.False(ValueOption.contains 1 ValueNone) + Assert.True(ValueOption.contains 1 (ValueSome 1)) - Assert.IsFalse(ValueOption.contains "" ValueNone) - Assert.IsTrue(ValueOption.contains "" (ValueSome "")) + Assert.False(ValueOption.contains "" ValueNone) + Assert.True(ValueOption.contains "" (ValueSome "")) - Assert.IsFalse(ValueOption.contains ValueNone ValueNone) - Assert.IsTrue(ValueOption.contains ValueNone (ValueSome ValueNone)) - [] + Assert.False(ValueOption.contains ValueNone ValueNone) + Assert.True(ValueOption.contains ValueNone (ValueSome ValueNone)) + [] member this.OfToNullable() = - Assert.IsTrue(ValueOption.ofNullable (System.Nullable()) = ValueNone) - Assert.IsTrue(ValueOption.ofNullable (System.Nullable(3)) = ValueSome 3) + Assert.True(ValueOption.ofNullable (System.Nullable()) = ValueNone) + Assert.True(ValueOption.ofNullable (System.Nullable(3)) = ValueSome 3) - Assert.IsTrue(ValueOption.toNullable (ValueNone : int voption) = System.Nullable()) - Assert.IsTrue(ValueOption.toNullable (ValueNone : System.DateTime voption) = System.Nullable()) - Assert.IsTrue(ValueOption.toNullable (ValueSome 3) = System.Nullable(3)) + Assert.True(ValueOption.toNullable (ValueNone : int voption) = System.Nullable()) + Assert.True(ValueOption.toNullable (ValueNone : System.DateTime voption) = System.Nullable()) + Assert.True(ValueOption.toNullable (ValueSome 3) = System.Nullable(3)) - [] + [] member this.OfToObj() = - Assert.IsTrue(ValueOption.toObj (ValueSome "3") = "3") - Assert.IsTrue(ValueOption.toObj (ValueSome "") = "") - Assert.IsTrue(ValueOption.toObj (ValueSome null) = null) - Assert.IsTrue(ValueOption.toObj ValueNone = null) + Assert.True(ValueOption.toObj (ValueSome "3") = "3") + Assert.True(ValueOption.toObj (ValueSome "") = "") + Assert.True(ValueOption.toObj (ValueSome null) = null) + Assert.True(ValueOption.toObj ValueNone = null) - Assert.IsTrue(ValueOption.ofObj "3" = ValueSome "3") - Assert.IsTrue(ValueOption.ofObj "" = ValueSome "") - Assert.IsTrue(ValueOption.ofObj [| "" |] = ValueSome [| "" |]) - Assert.IsTrue(ValueOption.ofObj (null : string array) = ValueNone) - Assert.IsTrue(ValueOption.ofObj null = ValueNone) - Assert.IsTrue(ValueOption.ofObj null = ValueNone) - Assert.IsTrue(ValueOption.ofObj null = ValueNone) - - [] + Assert.True(ValueOption.ofObj "3" = ValueSome "3") + Assert.True(ValueOption.ofObj "" = ValueSome "") + Assert.True(ValueOption.ofObj [| "" |] = ValueSome [| "" |]) + Assert.True(ValueOption.ofObj (null : string array) = ValueNone) + Assert.True(ValueOption.ofObj null = ValueNone) + Assert.True(ValueOption.ofObj null = ValueNone) + Assert.True(ValueOption.ofObj null = ValueNone) + + [] member this.DefaultValue() = Assert.AreEqual(ValueOption.defaultValue 3 ValueNone, 3) Assert.AreEqual(ValueOption.defaultValue 3 (ValueSome 42), 42) Assert.AreEqual(ValueOption.defaultValue "" ValueNone, "") Assert.AreEqual(ValueOption.defaultValue "" (ValueSome "x"), "x") - [] + [] member this.DefaultWith() = Assert.AreEqual(ValueOption.defaultWith (fun () -> 3) ValueNone, 3) Assert.AreEqual(ValueOption.defaultWith (fun () -> "") ValueNone, "") @@ -396,7 +394,7 @@ type ValueOptionTests() = Assert.AreEqual(ValueOption.defaultWith assertWasNotCalledThunk (ValueSome 42), 42) Assert.AreEqual(ValueOption.defaultWith assertWasNotCalledThunk (ValueSome ""), "") - [] + [] member this.OrElse() = Assert.AreEqual(ValueOption.orElse ValueNone ValueNone, ValueNone) Assert.AreEqual(ValueOption.orElse (ValueSome 3) ValueNone, ValueSome 3) @@ -407,7 +405,7 @@ type ValueOptionTests() = Assert.AreEqual(ValueOption.orElse ValueNone (ValueSome "x"), ValueSome "x") Assert.AreEqual(ValueOption.orElse (ValueSome "") (ValueSome "x"), ValueSome "x") - [] + [] member this.OrElseWith() = Assert.AreEqual(ValueOption.orElseWith (fun () -> ValueNone) ValueNone, ValueNone) Assert.AreEqual(ValueOption.orElseWith (fun () -> ValueSome 3) ValueNone, ValueSome 3) @@ -416,7 +414,7 @@ type ValueOptionTests() = Assert.AreEqual(ValueOption.orElseWith assertWasNotCalledThunk (ValueSome 42), ValueSome 42) Assert.AreEqual(ValueOption.orElseWith assertWasNotCalledThunk (ValueSome ""), ValueSome "") - [] + [] member this.Map2() = Assert.True(ValueOption.map2 (-) ValueNone ValueNone = ValueNone) Assert.True(ValueOption.map2 (-) (ValueSome 1) ValueNone = ValueNone) @@ -428,7 +426,7 @@ type ValueOptionTests() = Assert.True(ValueOption.map2 (+) (ValueSome "x") (ValueSome "y") = ValueSome "xy") Assert.True(ValueOption.map2 (+) ValueNone (ValueSome "y") = ValueNone) - [] + [] member this.Map3() = let add3 x y z = string x + string y + string z Assert.True(ValueOption.map3 add3 ValueNone ValueNone ValueNone = ValueNone) @@ -450,7 +448,7 @@ type ValueOptionTests() = Assert.True(ValueOption.map3 concat3 ValueNone (ValueSome "y") (ValueSome "z") = ValueNone) Assert.True(ValueOption.map3 concat3 (ValueSome "x") (ValueSome "y") (ValueSome "z") = ValueSome "xyz") - [] + [] member this.MapBindEquivalenceProperties () = let fn x = x + 3 Assert.AreEqual(ValueOption.map fn ValueNone, ValueOption.bind (fn >> ValueSome) ValueNone) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/PrintfTests.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/PrintfTests.fs index 1454ea80e7e..187fa62c60e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/PrintfTests.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/PrintfTests.fs @@ -3,23 +3,120 @@ // Various tests for: // Microsoft.FSharp.Core.ExtraTopLevelOperators.printf -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests -open System -open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit + +type MyUnionType = + | CaseOne + | CaseTwo of myString : string + | CaseTwoOpt of myString : string option + | CaseThree of someNumber : int * myString : string + +[] +type SecondUnionType = + | Case1 + | Case2 of myString : string + | Case2Opt of myString : string option + | Case3 of someNumber : int * myString : string + +[] +type MyNullAsTrueUnionType = + | NullCase + | NonNull of int + +[] +[] +type RQANullAsTrueUnionType = + | NonNull of int + | NullCase -[] type PrintfTests() = let test fmt arg (expected:string) = let actual = sprintf fmt arg Assert.AreEqual(expected, actual) - [] + [] member this.FormatAndPrecisionSpecifiers() = test "%10s" "abc" " abc" test "%-10s" "abc" "abc " test "%10d" 123 " 123" test "%-10d" 123 "123 " test "%10c" 'a' " a" - test "%-10c" 'a' "a " \ No newline at end of file + test "%-10c" 'a' "a " + + [] + member this.NumbersInDifferentBases() = + test "%10u" 123 " 123" + test "%-10u" 123 "123 " + test "%10B" 123 " 1111011" + test "%-10B" 123 "1111011 " + test "%10o" 123 " 173" + test "%-10o" 123 "173 " + test "%10x" 123 " 7b" + test "%-10x" 123 "7b " + test "%10X" 123 " 7B" + test "%-10X" 123 "7B " + + [] + member this.VariableWidth() = + Assert.AreEqual(" a", sprintf "%*c" 8 'a' ) + Assert.AreEqual("a ", sprintf "%-*c" 8 'a' ) + Assert.AreEqual(" abc", sprintf "%*s" 8 "abc") + Assert.AreEqual("abc ", sprintf "%-*s" 8 "abc") + Assert.AreEqual(" 123", sprintf "%*u" 8 123 ) + Assert.AreEqual("123 ", sprintf "%-*u" 8 123 ) + Assert.AreEqual(" 1111011", sprintf "%*B" 8 123 ) + Assert.AreEqual("1111011 ", sprintf "%-*B" 8 123 ) + Assert.AreEqual(" 173", sprintf "%*o" 8 123 ) + Assert.AreEqual("173 ", sprintf "%-*o" 8 123 ) + Assert.AreEqual(" 7b", sprintf "%*x" 8 123 ) + Assert.AreEqual("7b ", sprintf "%-*x" 8 123 ) + Assert.AreEqual(" 7B", sprintf "%*X" 8 123 ) + Assert.AreEqual("7B ", sprintf "%-*X" 8 123 ) + + [] + member _.``union case formatting`` () = + Assert.AreEqual("CaseOne", sprintf "%A" CaseOne) + Assert.AreEqual("CaseTwo \"hello\"", sprintf "%A" (CaseTwo "hello")) + Assert.AreEqual("CaseTwoOpt None", sprintf "%A" (CaseTwoOpt None)) + Assert.AreEqual("CaseTwoOpt (Some \"hi\")", sprintf "%A" (CaseTwoOpt (Some "hi"))) + Assert.AreEqual("CaseThree (5, \"hello\")", sprintf "%A" (CaseThree (5, "hello"))) + + [] + member _.``union case formatting with RequireQualifiedAccess`` () = + Assert.AreEqual("Case1", sprintf "%A" SecondUnionType.Case1) + Assert.AreEqual("Case2 \"hello\"", sprintf "%A" (SecondUnionType.Case2 "hello")) + Assert.AreEqual("Case2Opt None", sprintf "%A" (SecondUnionType.Case2Opt None)) + Assert.AreEqual("Case2Opt (Some \"hi\")", sprintf "%A" (SecondUnionType.Case2Opt (Some "hi"))) + Assert.AreEqual("Case3 (5, \"hello\")", sprintf "%A" (SecondUnionType.Case3 (5, "hello"))) + + [] + member _.``union case formatting with UseNullAsTrueValue`` () = + Assert.AreEqual("NullCase", sprintf "%A" NullCase) + Assert.AreEqual("NullCase", sprintf "%A" RQANullAsTrueUnionType.NullCase) + + [] + member _.``F# option formatting`` () = + Assert.AreEqual("None", sprintf "%A" None) + Assert.AreEqual("Some 15", sprintf "%A" (Some 15)) + + [] + member _.``null formatting`` () = + Assert.AreEqual("", sprintf "%A" null) + Assert.AreEqual("CaseTwo null", sprintf "%A" (CaseTwo null)) + + [] + member _.``tuple formatting`` () = + Assert.AreEqual("""(1, "two", 3.4)""", sprintf "%A" (1,"two",3.4)) + Assert.AreEqual("""(1, "two", 3.4, 5, 6, 7, 8, 9, "ten", 11.12)""", sprintf "%A" (1,"two",3.4,5,6,7,8,9,"ten",11.12)) + + [] + member _.``value tuple formatting`` () = + Assert.AreEqual("""struct (1, "two", 3.4)""", sprintf "%A" (struct (1,"two",3.4))) + Assert.AreEqual("""struct (1, "two", 3.4, 5, 6, 7, 8, 9, "ten", 11.12)""", sprintf "%A" (struct (1,"two",3.4,5,6,7,8,9,"ten",11.12))) + + [] + member _.``list types`` () = + Assert.AreEqual("""[CaseTwo "hello"; CaseTwo "hi there!"]""", [CaseTwo "hello"; CaseTwo "hi there!"] |> sprintf "%A") + Assert.AreEqual("""[CaseTwoOpt (Some "hello"); CaseTwoOpt (Some "hi there!")]""", [CaseTwoOpt (Some "hello"); CaseTwoOpt (Some "hi there!")] |> sprintf "%A") diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs index 9b46df189e6..adc300ba498 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/ResultTests.fs @@ -3,11 +3,11 @@ // Various tests for: // Microsoft.FSharp.Core.Result -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit type EmailValidation= | Empty @@ -15,7 +15,6 @@ type EmailValidation= open Result -[] type ResultTests() = let fail_if_empty email= @@ -40,43 +39,43 @@ type ResultTests() = let addOneOk (v:int) = Ok (v+1) - [] + [] member this.CanChainTogetherSuccessiveValidations() = test_validate_email "" (Error Empty) test_validate_email "something_else" (Error NoAt) test_validate_email "some@email.com" (Ok "some@email.com") - [] + [] member this.MapWillTransformOkValues() = Ok "some@email.com" |> map toUpper |> shouldBeOkWithValue "SOME@EMAIL.COM" - [] + [] member this.MapWillNotTransformErrorValues() = Error "my error" |> map toUpper |> shouldBeErrorWithValue "my error" - [] + [] member this.MapErrorWillTransformErrorValues() = Error "my error" |> mapError toUpper |> shouldBeErrorWithValue "MY ERROR" - [] + [] member this.MapErrorWillNotTransformOkValues() = Ok "some@email.com" |> mapError toUpper |> shouldBeOkWithValue "some@email.com" - [] + [] member this.BindShouldModifyOkValue() = Ok 42 |> bind addOneOk |> shouldBeOkWithValue 43 - [] + [] member this.BindErrorShouldNotModifyError() = Error "Error" |> bind addOneOk diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Linq/NullableOperators.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Linq/NullableOperators.fs new file mode 100644 index 00000000000..ecc1da12ba3 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Linq/NullableOperators.fs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Core.UnitTests.FSharp_Core.Linq.NullableOperators + +open Xunit +open Microsoft.FSharp.Linq + +[] +type NullableOperators() = + [] + member _.CastingUint () = + let expected = Nullable(12u) + let actual = Nullable.uint (Nullable(12)) + Assert.AreEqual(expected, actual) \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs index 41c0cc19fba..02a3070d497 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs @@ -2,11 +2,11 @@ // Various tests for Microsoft.FSharp.Quotations -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Quotations +namespace FSharp.Core.UnitTests.Quotations open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open FSharp.Quotations open FSharp.Quotations.Patterns @@ -22,42 +22,42 @@ module Check = f () |> ignore with | :? System.ArgumentException-> ex <- true - Assert.IsTrue(ex, "InvalidOperationException expected") + Assert.True(ex, "InvalidOperationException expected") + -[] type FSharpQuotationsTests() = - [] + [] member x.MethodInfoNRE() = let f() = E.Call(null, []) |> ignore CheckThrowsArgumentNullException f - [] + [] member x.FieldInfoNRE() = let f() = E.FieldGet(null) |> ignore CheckThrowsArgumentNullException f - [] + [] member x.ConstructorNRE() = let f() = E.NewObject(null,[]) |> ignore CheckThrowsArgumentNullException f - [] + [] member x.PropertyInfoNRE() = let f() = E.PropertyGet(null,[]) |> ignore CheckThrowsArgumentNullException f - [] + [] member x.UnionCaseInfoNRE() = let f() = E.NewUnionCase(Unchecked.defaultof,[]) |> ignore CheckThrowsArgumentNullException f - [] + [] member x.ReShapeTypechecking_Let() = let q0 = <@ let a = 1 in a @> match q0 with @@ -72,7 +72,7 @@ type FSharpQuotationsTests() = Check.argumentException(fun () -> ExprShape.RebuildShapeCombination(shape, [wrongValue;lambda])) | _ -> Assert.Fail() - [] + [] member x.ReShapeStaticIndexedProperties() = let q0 = <@ StaticIndexedPropertyTest.IdxProp 5 @> match q0 with @@ -83,44 +83,44 @@ type FSharpQuotationsTests() = | _ -> Assert.Fail() | _ -> Assert.Fail() - [] + [] member x.GetConstructorFiltersOutStaticConstructor() = ignore <@ System.Exception() @> - [] + [] member x.``NewStructTuple literal should be recognized by NewStructTuple active pattern`` () = match <@ struct(1, "") @> with | NewStructTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () | _ -> Assert.Fail() - [] + [] member x.``NewStructTuple literal should be recognized by NewTuple active pattern`` () = match <@ struct(1, "") @> with | NewTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () | _ -> Assert.Fail() - [] + [] member x.``NewTuple literal should not be recognized by NewStructTuple active pattern`` () = match <@ (1, "") @> with | NewStructTuple _ -> Assert.Fail() | _ -> () - [] + [] member x.``NewStructTuple should be recognized by NewStructTuple active pattern`` () = let expr = Expr.NewStructTuple(typeof.Assembly, [ <@@ 1 @@>; <@@ "" @@> ]) match expr with | NewStructTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () | _ -> Assert.Fail() - [] + [] member x.``NewStructTuple should be recognized by NewTuple active pattern`` () = let expr = Expr.NewStructTuple(typeof.Assembly, [ <@@ 1 @@>; <@@ "" @@> ]) match expr with | NewTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () | _ -> Assert.Fail() - [] + [] member x.``NewTuple should not be recognized by NewStructTuple active pattern`` () = let expr = Expr.NewTuple [ <@@ 1 @@>; <@@ "" @@> ] match expr with diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs index 21df908745d..ff1223b482a 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs @@ -2,13 +2,13 @@ // Various tests for Microsoft.FSharp.Reflection -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Reflection +namespace FSharp.Core.UnitTests.Reflection open System open System.Reflection open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open Microsoft.FSharp.Reflection @@ -28,7 +28,7 @@ Make sure each method works on: module IsModule = type IsModuleType () = - member __.M = 1 + member _.M = 1 type FSharpDelegate = delegate of int -> string @@ -65,7 +65,7 @@ module FSharpModule = class end -[] + type FSharpValueTests() = // global variables @@ -103,6 +103,14 @@ type FSharpValueTests() = let discStructUnionCaseB = DiscStructUnionType.B(1) let discStructUnionCaseC = DiscStructUnionType.C(1.0, "stringparam") + let optionSome = Some(3) + let optionNone: int option = None + + let voptionSome = ValueSome("stringparam") + let voptionNone: string voption = ValueNone + + let list1 = [ 1; 2 ] + let list2: int list = [] let fsharpDelegate1 = new FSharpDelegate(fun (x:int) -> "delegate1") let fsharpDelegate2 = new FSharpDelegate(fun (x:int) -> "delegate2") @@ -110,10 +118,12 @@ type FSharpValueTests() = let tuple1 = ( 1, "tuple1") let tuple2 = ( 2, "tuple2", (fun x -> x + 1)) let tuple3 = ( 1, ( 2, "tuple")) + let longTuple = (("yup", 1s), 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, Some 12, 13, "nope", struct (15, 16), 17, 18, ValueSome 19) let structTuple1 = struct ( 1, "tuple1") let structTuple2 = struct ( 2, "tuple2", (fun x -> x + 1)) let structTuple3 = struct ( 1, struct ( 2, "tuple")) + let longStructTuple = struct (("yup", 1s), 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, Some 12, 13, "nope", struct (15, 16), 17, 18, ValueSome 19) let func1 param = param + 1 let func2 param = param + "" @@ -121,87 +131,87 @@ type FSharpValueTests() = let exInt = ExceptionInt(1) let exDataless = DatalessException - [] - member __.Equals1() = + [] + member _.Equals1() = // Record value - Assert.IsTrue(FSharpValue.Equals(record1, record1)) - Assert.IsFalse(FSharpValue.Equals(record1, record2)) + Assert.True(FSharpValue.Equals(record1, record1)) + Assert.False(FSharpValue.Equals(record1, record2)) - [] - member __.Equals2() = - Assert.IsTrue(FSharpValue.Equals(structRecord1, structRecord1)) - Assert.IsFalse(FSharpValue.Equals(structRecord1, structRecord2)) - Assert.IsFalse(FSharpValue.Equals(structRecord1, record2)) - Assert.IsFalse(FSharpValue.Equals(record1, structRecord1)) - Assert.IsFalse(FSharpValue.Equals(record2, structRecord2)) + [] + member _.Equals2() = + Assert.True(FSharpValue.Equals(structRecord1, structRecord1)) + Assert.False(FSharpValue.Equals(structRecord1, structRecord2)) + Assert.False(FSharpValue.Equals(structRecord1, record2)) + Assert.False(FSharpValue.Equals(record1, structRecord1)) + Assert.False(FSharpValue.Equals(record2, structRecord2)) - [] - member __.Equals3() = + [] + member _.Equals3() = // Generic Record value - Assert.IsTrue(FSharpValue.Equals(genericRecordType1, genericRecordType1)) - Assert.IsFalse(FSharpValue.Equals(genericRecordType1, genericRecordType2)) + Assert.True(FSharpValue.Equals(genericRecordType1, genericRecordType1)) + Assert.False(FSharpValue.Equals(genericRecordType1, genericRecordType2)) - [] - member __.Equals4() = + [] + member _.Equals4() = // null value - Assert.IsTrue(FSharpValue.Equals(nullValue, nullValue)) - Assert.IsFalse(FSharpValue.Equals(nullValue, 1)) + Assert.True(FSharpValue.Equals(nullValue, nullValue)) + Assert.False(FSharpValue.Equals(nullValue, 1)) - [] - member __.Equals5() = + [] + member _.Equals5() = // Single Case Union - Assert.IsTrue(FSharpValue.Equals(singleCaseUnion1, singleCaseUnion1)) - Assert.IsFalse(FSharpValue.Equals(singleCaseUnion1, singleCaseUnion2)) + Assert.True(FSharpValue.Equals(singleCaseUnion1, singleCaseUnion1)) + Assert.False(FSharpValue.Equals(singleCaseUnion1, singleCaseUnion2)) - [] - member __.Equals6() = + [] + member _.Equals6() = // Single Case Union - Assert.IsTrue(FSharpValue.Equals(singleCaseStructUnion1, singleCaseStructUnion1)) - Assert.IsFalse(FSharpValue.Equals(singleCaseStructUnion1, singleCaseStructUnion2)) + Assert.True(FSharpValue.Equals(singleCaseStructUnion1, singleCaseStructUnion1)) + Assert.False(FSharpValue.Equals(singleCaseStructUnion1, singleCaseStructUnion2)) - [] - member __.Equals7() = + [] + member _.Equals7() = // Discriminated Union - Assert.IsTrue(FSharpValue.Equals(discUnionCaseA, discUnionCaseA)) - Assert.IsFalse(FSharpValue.Equals(discUnionCaseB, discUnionCaseC)) + Assert.True(FSharpValue.Equals(discUnionCaseA, discUnionCaseA)) + Assert.False(FSharpValue.Equals(discUnionCaseB, discUnionCaseC)) - [] - member __.Equals8() = + [] + member _.Equals8() = // Discriminated Union - Assert.IsTrue(FSharpValue.Equals(discStructUnionCaseA, discStructUnionCaseA)) - Assert.IsFalse(FSharpValue.Equals(discStructUnionCaseB, discStructUnionCaseC)) + Assert.True(FSharpValue.Equals(discStructUnionCaseA, discStructUnionCaseA)) + Assert.False(FSharpValue.Equals(discStructUnionCaseB, discStructUnionCaseC)) - [] - member __.Equals9() = + [] + member _.Equals9() = // FSharpDelegate - Assert.IsTrue(FSharpValue.Equals(fsharpDelegate1, fsharpDelegate1)) - Assert.IsFalse(FSharpValue.Equals(fsharpDelegate1, fsharpDelegate2)) + Assert.True(FSharpValue.Equals(fsharpDelegate1, fsharpDelegate1)) + Assert.False(FSharpValue.Equals(fsharpDelegate1, fsharpDelegate2)) - [] - member __.Equals10() = + [] + member _.Equals10() = // Tuple - Assert.IsTrue(FSharpValue.Equals(tuple1, tuple1)) - Assert.IsFalse(FSharpValue.Equals( (1, 2, 3), (4, 5, 6) )) + Assert.True(FSharpValue.Equals(tuple1, tuple1)) + Assert.False(FSharpValue.Equals( (1, 2, 3), (4, 5, 6) )) - [] - member __.Equals10b() = + [] + member _.Equals10b() = // Tuple - Assert.IsTrue(FSharpValue.Equals(structTuple1, structTuple1)) - Assert.IsFalse(FSharpValue.Equals( struct (1, 2, 3), struct (4, 5, 6) )) + Assert.True(FSharpValue.Equals(structTuple1, structTuple1)) + Assert.False(FSharpValue.Equals( struct (1, 2, 3), struct (4, 5, 6) )) - [] - member __.Equals11() = + [] + member _.Equals11() = // Tuples of differing types - Assert.IsFalse(FSharpValue.Equals(tuple1, tuple2)) + Assert.False(FSharpValue.Equals(tuple1, tuple2)) - [] - member __.Equals12() = + [] + member _.Equals12() = // Exception - Assert.IsTrue(FSharpValue.Equals(exInt, exInt)) - Assert.IsFalse(FSharpValue.Equals(exInt, exDataless)) + Assert.True(FSharpValue.Equals(exInt, exInt)) + Assert.False(FSharpValue.Equals(exInt, exDataless)) - [] - member __.GetExceptionFields() = + [] + member _.GetExceptionFields() = // int Assert.AreEqual(FSharpValue.GetExceptionFields(exInt), ([|1|] : obj [])) @@ -219,8 +229,8 @@ type FSharpValueTests() = // null CheckThrowsArgumentException(fun () -> FSharpValue.GetExceptionFields(null) |> ignore) - [] - member __.GetRecordField() = + [] + member _.GetRecordField() = // Record let propertyinfo1 = (typeof).GetProperty("field1") @@ -241,8 +251,8 @@ type FSharpValueTests() = let propertyinfoint = (typeof).GetProperty("fieldstring") CheckThrowsArgumentException(fun () -> FSharpValue.GetRecordField("invalid", propertyinfoint) |> ignore) - [] - member __.GetStructRecordField() = + [] + member _.GetStructRecordField() = // Record let propertyinfo1 = (typeof).GetProperty("field1") @@ -259,8 +269,8 @@ type FSharpValueTests() = let propertyinfoint = (typeof).GetProperty("fieldstring") CheckThrowsArgumentException(fun () -> FSharpValue.GetRecordField("invalid", propertyinfoint) |> ignore) - [] - member __.GetRecordFields() = + [] + member _.GetRecordFields() = // Record let propertyinfo1 = (typeof).GetProperty("field1") Assert.AreEqual((FSharpValue.GetRecordFields(record1)).[0], "field1") @@ -276,13 +286,13 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.GetRecordFields("invalid") |> ignore) - [] - member __.GetStructRecordFields() = + [] + member _.GetStructRecordFields() = let propertyinfo1 = (typeof).GetProperty("field1") Assert.AreEqual((FSharpValue.GetRecordFields(structRecord1)).[0], "field1") - [] - member __.GetTupleField() = + [] + member _.GetTupleField() = // Tuple Assert.AreEqual((FSharpValue.GetTupleField(tuple1, 0)), 1) @@ -299,8 +309,8 @@ type FSharpValueTests() = // index out of range CheckThrowsArgumentException(fun () -> FSharpValue.GetTupleField(tuple2, 8)|> ignore) - [] - member __.GetStructTupleField() = + [] + member _.GetStructTupleField() = // Tuple Assert.AreEqual((FSharpValue.GetTupleField(structTuple1, 0)), 1) @@ -310,8 +320,8 @@ type FSharpValueTests() = // index out of range CheckThrowsArgumentException(fun () -> FSharpValue.GetTupleField(structTuple2, 8)|> ignore) - [] - member __.GetTupleFields() = + [] + member _.GetTupleFields() = // Tuple Assert.AreEqual(FSharpValue.GetTupleFields(tuple1).[0], 1) @@ -325,16 +335,16 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.GetTupleFields("Invalid")|> ignore) - [] - member __.GetStructTupleFields() = + [] + member _.GetStructTupleFields() = // Tuple Assert.AreEqual(FSharpValue.GetTupleFields(structTuple1).[0], 1) // Tuple with function element Assert.AreEqual( (FSharpValue.GetTupleFields(structTuple2)).[1], "tuple2") - [] - member __.GetUnionFields() = + [] + member _.GetUnionFields() = // single case union let (singlecaseinfo, singlevaluearray) = FSharpValue.GetUnionFields(singleCaseUnion1, typeof) Assert.AreEqual(singlevaluearray, ([|1.0;2.0;3.0|] : obj [])) @@ -347,8 +357,8 @@ type FSharpValueTests() = CheckThrowsArgumentException(fun () -> FSharpValue.GetUnionFields(null, null)|> ignore) CheckThrowsArgumentException(fun () -> FSharpValue.GetUnionFields( () , null)|> ignore) - [] - member __.GetStructUnionFields() = + [] + member _.GetStructUnionFields() = // single case union let (_singlecaseinfo, singlevaluearray) = FSharpValue.GetUnionFields(singleCaseStructUnion1, typeof) Assert.AreEqual(singlevaluearray, ([|1.0;2.0;3.0|] : obj [])) @@ -357,8 +367,8 @@ type FSharpValueTests() = let (_duCaseinfo, duValueArray) = FSharpValue.GetUnionFields(discStructUnionCaseB, typeof>) Assert.AreEqual(duValueArray.[0], 1) - [] - member __.MakeFunction() = + [] + member _.MakeFunction() = // Int function let implementationInt (x:obj) = box( unbox(x) + 1) @@ -372,8 +382,8 @@ type FSharpValueTests() = let resultFuncString = resultFuncStringObj :?> (string -> string) Assert.AreEqual(resultFuncString("parameter"), "parameter function") - [] - member __.MakeRecord() = + [] + member _.MakeRecord() = // Record let makeRecord = FSharpValue.MakeRecord(typeof, [| box"field1"; box(Some(record1)); box( fun () -> (record1, "")) |]) Assert.AreEqual(FSharpValue.GetRecordFields(makeRecord).[0], "field1") @@ -388,14 +398,14 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.MakeRecord(typeof>, [| box 1; box("invalid param"); box("invalid param") |])|> ignore) - [] - member __.MakeStructRecord() = + [] + member _.MakeStructRecord() = // Record let makeRecord = FSharpValue.MakeRecord(typeof, [| box"field1"; box(Some(structRecord1)); box( fun () -> (structRecord1, "")) |]) Assert.AreEqual(FSharpValue.GetRecordFields(makeRecord).[0], "field1") - [] - member __.MakeTuple() = + [] + member _.MakeTuple() = // Tuple let makeTuple = FSharpValue.MakeTuple([| box 1; box("tuple") |], typeof>) Assert.AreEqual(FSharpValue.GetTupleFields(makeTuple).[0], 1) @@ -410,8 +420,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.MakeTuple([| box"invalid param"; box"invalid param"|], typeof>) |> ignore) - [] - member __.MakeStructTuple() = + [] + member _.MakeStructTuple() = // Tuple let makeTuple = FSharpValue.MakeTuple([| box 1; box("tuple") |], typeof) Assert.AreEqual(FSharpValue.GetTupleFields(makeTuple).[0], 1) @@ -425,8 +435,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.MakeTuple([| box"invalid param"; box"invalid param"|], typeof) |> ignore) - [] - member __.MakeUnion() = + [] + member _.MakeUnion() = // single case union let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseUnion1, typeof) let resultSingleCaseUnion=FSharpValue.MakeUnion(singlecaseinfo, [| box 1.0; box 2.0; box 3.0|]) @@ -437,8 +447,8 @@ type FSharpValueTests() = let resultDiscUnion=FSharpValue.MakeUnion(duCaseinfo, [| box 1; box (Some discUnionCaseB) |]) Assert.AreEqual(resultDiscUnion, discUnionRecCaseB) - [] - member __.MakeStructUnion() = + [] + member _.MakeStructUnion() = // single case union let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseStructUnion1, typeof) let resultSingleCaseUnion=FSharpValue.MakeUnion(singlecaseinfo, [| box 1.0; box 2.0; box 3.0|]) @@ -448,8 +458,8 @@ type FSharpValueTests() = let (duCaseinfo, duValueArray) = FSharpValue.GetUnionFields(discStructUnionCaseB, typeof>) FSharpValue.MakeUnion(duCaseinfo, [| box 1|]) |> ignore - [] - member __.PreComputeRecordConstructor() = + [] + member _.PreComputeRecordConstructor() = // Record let recCtor = FSharpValue.PreComputeRecordConstructor(typeof) let resultRecordType = recCtor([| box("field1"); box(Some(record1)); box(fun () -> (record1, "")) |]) @@ -466,16 +476,16 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeRecordConstructor(typeof>) |> ignore) - [] - member __.PreComputeStructRecordConstructor() = + [] + member _.PreComputeStructRecordConstructor() = // Record let recCtor = FSharpValue.PreComputeRecordConstructor(typeof) let resultRecordType = recCtor([| box("field1"); box(Some(structRecord1)); box(fun () -> (structRecord1, "")) |]) Assert.AreEqual( (unbox(resultRecordType)).field1 , structRecord1.field1) - [] - member __.PreComputeRecordConstructorInfo() = + [] + member _.PreComputeRecordConstructorInfo() = // Record let recordCtorInfo = FSharpValue.PreComputeRecordConstructorInfo(typeof) Assert.AreEqual(recordCtorInfo.ReflectedType, typeof ) @@ -490,14 +500,14 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeRecordConstructorInfo(typeof>) |> ignore) - [] - member __.PreComputeStructRecordConstructorInfo() = + [] + member _.PreComputeStructRecordConstructorInfo() = // Record let recordCtorInfo = FSharpValue.PreComputeRecordConstructorInfo(typeof) Assert.AreEqual(recordCtorInfo.ReflectedType, typeof ) - [] - member __.PreComputeRecordFieldReader() = + [] + member _.PreComputeRecordFieldReader() = // Record let recordFieldReader = FSharpValue.PreComputeRecordFieldReader((typeof).GetProperty("field1")) Assert.AreEqual(recordFieldReader(record1), box("field1")) @@ -509,14 +519,14 @@ type FSharpValueTests() = // null value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeRecordFieldReader(null)|> ignore) - [] - member __.PreComputeStructRecordFieldReader() = + [] + member _.PreComputeStructRecordFieldReader() = // Record let recordFieldReader = FSharpValue.PreComputeRecordFieldReader((typeof).GetProperty("field1")) Assert.AreEqual(recordFieldReader(structRecord1), box("field1")) - [] - member __.PreComputeRecordReader() = + [] + member _.PreComputeRecordReader() = // Record let recordReader = FSharpValue.PreComputeRecordReader(typeof) Assert.AreEqual( (recordReader(record1)).[0], "field1") @@ -531,17 +541,20 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeRecordReader(typeof>) |> ignore) - [] - member __.PreComputeStructRecordReader() = + [] + member _.PreComputeStructRecordReader() = // Record let recordReader = FSharpValue.PreComputeRecordReader(typeof) Assert.AreEqual( (recordReader(structRecord1)).[0], "field1") - [] - member __.PreComputeTupleConstructor() = + [] + member _.PreComputeTupleConstructor() = // Tuple let tupleCtor = FSharpValue.PreComputeTupleConstructor(tuple1.GetType()) Assert.AreEqual( tupleCtor([| box 1; box "tuple1" |]) , box(tuple1)) + + let tupleCtor = FSharpValue.PreComputeTupleConstructor(longTuple.GetType()) + Assert.AreEqual( tupleCtor([| box ("yup", 1s); box 2; box 3; box 4; box 5; box 6; box 7; box 8; box 9; box 10; box 11; box (Some 12); box 13; box "nope"; box (struct (15, 16)); box 17; box 18; box (ValueSome 19) |]) , box(longTuple)) // Tuple with function member let tuplewithFuncCtor = FSharpValue.PreComputeTupleConstructor(tuple2.GetType()) @@ -559,12 +572,15 @@ type FSharpValueTests() = CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleConstructor(typeof>) |> ignore) CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleConstructor(typeof) |> ignore) - [] - member __.PreComputeStructTupleConstructor() = + [] + member _.PreComputeStructTupleConstructor() = // Tuple let tupleCtor = FSharpValue.PreComputeTupleConstructor(structTuple1.GetType()) Assert.AreEqual( tupleCtor([| box 1; box "tuple1" |]) , box(structTuple1)) + let tupleCtor = FSharpValue.PreComputeTupleConstructor(longStructTuple.GetType()) + Assert.AreEqual( tupleCtor([| box ("yup", 1s); box 2; box 3; box 4; box 5; box 6; box 7; box 8; box 9; box 10; box 11; box (Some 12); box 13; box "nope"; box (struct (15, 16)); box 17; box 18; box (ValueSome 19) |]) , box(longStructTuple)) + // Tuple with function member let tuplewithFuncCtor = FSharpValue.PreComputeTupleConstructor(structTuple2.GetType()) let resultTuplewithFunc = tuplewithFuncCtor([| box 2; box "tuple2"; box (fun x -> x + 1) |]) @@ -577,8 +593,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleConstructor(typeof>) |> ignore) - [] - member __.PreComputeTupleConstructorInfo() = + [] + member _.PreComputeTupleConstructorInfo() = // Tuple let (tupleCtorInfo, _tupleType) = FSharpValue.PreComputeTupleConstructorInfo(typeof>) Assert.AreEqual(tupleCtorInfo.ReflectedType, typeof> ) @@ -596,8 +612,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleConstructorInfo(typeof) |> ignore) - [] - member __.PreComputeStructTupleConstructorInfo() = + [] + member _.PreComputeStructTupleConstructorInfo() = // Tuple let (tupleCtorInfo, _tupleType) = FSharpValue.PreComputeTupleConstructorInfo(typeof) Assert.AreEqual(tupleCtorInfo.ReflectedType, typeof ) @@ -606,8 +622,8 @@ type FSharpValueTests() = let (nestedTupleCtorInfo, _nestedTupleType) = FSharpValue.PreComputeTupleConstructorInfo(typeof) Assert.AreEqual(nestedTupleCtorInfo.ReflectedType, typeof) - [] - member __.PreComputeTuplePropertyInfo() = + [] + member _.PreComputeTuplePropertyInfo() = // Tuple let (tuplePropInfo, _typeindex) = FSharpValue.PreComputeTuplePropertyInfo(typeof>, 0) @@ -628,8 +644,8 @@ type FSharpValueTests() = // This fails as no PropertyInfo's actually exist for struct tuple types. // - //[] - //member __.PreComputeStructTuplePropertyInfo() = + //[] + //member _.PreComputeStructTuplePropertyInfo() = // // // Tuple // let (tuplePropInfo, _typeindex) = FSharpValue.PreComputeTuplePropertyInfo(typeof, 0) @@ -639,8 +655,8 @@ type FSharpValueTests() = // let (tupleNestedPropInfo, _typeindex) = FSharpValue.PreComputeTuplePropertyInfo(typeof, 1) // Assert.AreEqual(tupleNestedPropInfo.PropertyType, typeof) - [] - member __.PreComputeTupleReader() = + [] + member _.PreComputeTupleReader() = // Tuple let tuplereader = FSharpValue.PreComputeTupleReader(typeof>) @@ -649,6 +665,9 @@ type FSharpValueTests() = // Nested let nestedtuplereader = FSharpValue.PreComputeTupleReader(typeof>>) Assert.AreEqual(nestedtuplereader(tuple3).[1], box(2, "tuple")) + + let longTupleReader = FSharpValue.PreComputeTupleReader (longTuple.GetType ()) + Assert.AreEqual (longTupleReader longTuple, [| box ("yup", 1s); box 2; box 3; box 4; box 5; box 6; box 7; box 8; box 9; box 10; box 11; box (Some 12); box 13; box "nope"; box (struct (15, 16)); box 17; box 18; box (ValueSome 19) |]) // null value CheckThrowsArgumentException(fun () ->FSharpValue.PreComputeTupleReader(null)|> ignore) @@ -656,8 +675,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleReader(typeof) |> ignore) - [] - member __.PreComputeStructTupleReader() = + [] + member _.PreComputeStructTupleReader() = // Tuple let tuplereader = FSharpValue.PreComputeTupleReader(typeof) @@ -667,11 +686,14 @@ type FSharpValueTests() = let nestedtuplereader = FSharpValue.PreComputeTupleReader(typeof) Assert.AreEqual(nestedtuplereader(structTuple3).[1], box (struct (2, "tuple"))) + let longTupleReader = FSharpValue.PreComputeTupleReader (longStructTuple.GetType ()) + Assert.AreEqual (longTupleReader longStructTuple, [| box ("yup", 1s); box 2; box 3; box 4; box 5; box 6; box 7; box 8; box 9; box 10; box 11; box (Some 12); box 13; box "nope"; box (struct (15, 16)); box 17; box 18; box (ValueSome 19) |]) + // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeTupleReader(typeof) |> ignore) - [] - member __.PreComputeUnionConstructor() = + [] + member _.PreComputeUnionConstructor() = // SingleCaseUnion let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseUnion1, typeof) @@ -685,8 +707,8 @@ type FSharpValueTests() = let resuleDiscUnionB = discUnionCtor([| box 1; box(Some(discUnionCaseB)) |]) Assert.AreEqual(resuleDiscUnionB, discUnionRecCaseB) - [] - member __.PreComputeStructUnionConstructor() = + [] + member _.PreComputeStructUnionConstructor() = // SingleCaseUnion let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseStructUnion1, typeof) @@ -700,8 +722,8 @@ type FSharpValueTests() = let resuleDiscUnionB = discUnionCtor([| box 1|]) Assert.AreEqual(resuleDiscUnionB, discStructUnionCaseB) - [] - member __.PreComputeUnionConstructorInfo() = + [] + member _.PreComputeUnionConstructorInfo() = // SingleCaseUnion let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseUnion1, typeof) @@ -713,8 +735,8 @@ type FSharpValueTests() = let discUnionMethodInfo = FSharpValue.PreComputeUnionConstructorInfo(discUnionInfo) Assert.AreEqual(discUnionMethodInfo.ReflectedType, typeof>) - [] - member __.PreComputeStructUnionConstructorInfo() = + [] + member _.PreComputeStructUnionConstructorInfo() = // SingleCaseUnion let (singlecaseinfo, _singlevaluearray) = FSharpValue.GetUnionFields(singleCaseStructUnion1, typeof) @@ -726,8 +748,8 @@ type FSharpValueTests() = let discUnionMethodInfo = FSharpValue.PreComputeUnionConstructorInfo(discUnionInfo) Assert.AreEqual(discUnionMethodInfo.ReflectedType, typeof>) - [] - member __.PreComputeUnionReader() = + [] + member _.PreComputeUnionReader() = // SingleCaseUnion let (singlecaseinfo, singlevaluearray) = FSharpValue.GetUnionFields(singleCaseUnion1, typeof) @@ -738,9 +760,27 @@ type FSharpValueTests() = let (discUnionInfo, discvaluearray) = FSharpValue.GetUnionFields(discUnionRecCaseB, typeof>) let discUnionReader = FSharpValue.PreComputeUnionReader(discUnionInfo) Assert.AreEqual(discUnionReader(box(discUnionRecCaseB)) , [| box 1; box(Some(discUnionCaseB)) |]) + + // Option + let (optionCaseInfo, _) = FSharpValue.GetUnionFields(optionSome, typeof) + let optionReader = FSharpValue.PreComputeUnionReader(optionCaseInfo) + Assert.AreEqual(optionReader(box(optionSome)), [| box 3 |]) + + let (optionCaseInfo, _) = FSharpValue.GetUnionFields(optionNone, typeof) + let optionReader = FSharpValue.PreComputeUnionReader(optionCaseInfo) + Assert.AreEqual(optionReader(box(optionNone)), [| |]) + + // List + let (listCaseInfo, _) = FSharpValue.GetUnionFields(list1, typeof) + let listReader = FSharpValue.PreComputeUnionReader(listCaseInfo) + Assert.AreEqual(listReader(box(list1)), [| box 1; box [ 2 ] |]) + + let (listCaseInfo, _) = FSharpValue.GetUnionFields(list2, typeof) + let listReader = FSharpValue.PreComputeUnionReader(listCaseInfo) + Assert.AreEqual(listReader(box(list2)), [| |]) - [] - member __.PreComputeStructUnionReader() = + [] + member _.PreComputeStructUnionReader() = // SingleCaseUnion let (singlecaseinfo, singlevaluearray) = FSharpValue.GetUnionFields(singleCaseStructUnion1, typeof) @@ -751,9 +791,18 @@ type FSharpValueTests() = let (discUnionInfo, discvaluearray) = FSharpValue.GetUnionFields(discStructUnionCaseB, typeof>) let discUnionReader = FSharpValue.PreComputeUnionReader(discUnionInfo) Assert.AreEqual(discUnionReader(box(discStructUnionCaseB)) , [| box 1|]) + + // Value Option + let (voptionCaseInfo, _) = FSharpValue.GetUnionFields(voptionSome, typeof) + let voptionReader = FSharpValue.PreComputeUnionReader(voptionCaseInfo) + Assert.AreEqual(voptionReader(box(voptionSome)), [| box "stringparam" |]) + + let (voptionCaseInfo, _) = FSharpValue.GetUnionFields(voptionNone, typeof) + let voptionReader = FSharpValue.PreComputeUnionReader(voptionCaseInfo) + Assert.AreEqual(voptionReader(box(voptionNone)), [| |]) - [] - member __.PreComputeUnionTagMemberInfo() = + [] + member _.PreComputeUnionTagMemberInfo() = // SingleCaseUnion let singlecaseUnionMemberInfo = FSharpValue.PreComputeUnionTagMemberInfo(typeof) @@ -769,8 +818,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeUnionTagMemberInfo(typeof) |> ignore) - [] - member __.PreComputeStructUnionTagMemberInfo() = + [] + member _.PreComputeStructUnionTagMemberInfo() = // SingleCaseUnion let singlecaseUnionMemberInfo = FSharpValue.PreComputeUnionTagMemberInfo(typeof) @@ -780,8 +829,8 @@ type FSharpValueTests() = let discUnionMemberInfo = FSharpValue.PreComputeUnionTagMemberInfo(typeof>) Assert.AreEqual(discUnionMemberInfo.ReflectedType, typeof>) - [] - member __.PreComputeUnionTagReader() = + [] + member _.PreComputeUnionTagReader() = // SingleCaseUnion let singlecaseUnionTagReader = FSharpValue.PreComputeUnionTagReader(typeof) @@ -790,6 +839,16 @@ type FSharpValueTests() = // DiscUnion let discUnionTagReader = FSharpValue.PreComputeUnionTagReader(typeof>) Assert.AreEqual(discUnionTagReader(box(discUnionCaseB)), 1) + + // Option + let optionTagReader = FSharpValue.PreComputeUnionTagReader(typeof) + Assert.AreEqual(optionTagReader(box(optionSome)), 1) + Assert.AreEqual(optionTagReader(box(optionNone)), 0) + + // Value Option + let voptionTagReader = FSharpValue.PreComputeUnionTagReader(typeof) + Assert.AreEqual(voptionTagReader(box(voptionSome)), 1) + Assert.AreEqual(voptionTagReader(box(voptionNone)), 0) // null value CheckThrowsArgumentException(fun () ->FSharpValue.PreComputeUnionTagReader(null)|> ignore) @@ -797,8 +856,8 @@ type FSharpValueTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpValue.PreComputeUnionTagReader(typeof) |> ignore) - [] - member __.PreComputeStructUnionTagReader() = + [] + member _.PreComputeStructUnionTagReader() = // SingleCaseUnion let singlecaseUnionTagReader = FSharpValue.PreComputeUnionTagReader(typeof) @@ -807,12 +866,11 @@ type FSharpValueTests() = // DiscUnion let discUnionTagReader = FSharpValue.PreComputeUnionTagReader(typeof>) Assert.AreEqual(discUnionTagReader(box(discStructUnionCaseB)), 1) - - -[] + + type FSharpTypeTests() = - // instance for member __.ObjectEquals + // instance for member _.ObjectEquals let rec recordtype1 : RecordType = { field1 = "field1"; field2 = Some(recordtype1); field3 = ( fun () -> (recordtype1, "") )} let recordtype2 : RecordType = { field1 = "field2"; field2 = Some(recordtype1); field3 = ( fun () -> (recordtype1, "") )} let rec genericRecordType1 : GenericRecordType = { field1 = "field1"; field2 = 1; field3 = ( fun () -> genericRecordType1 )} @@ -841,57 +899,57 @@ type FSharpTypeTests() = let exDataless = DatalessException // Base class methods - [] - member __.ObjectEquals() = + [] + member _.ObjectEquals() = // Record value - Assert.IsTrue(FSharpValue.Equals(recordtype1, recordtype1)) - Assert.IsFalse(FSharpValue.Equals(recordtype1, recordtype2)) + Assert.True(FSharpValue.Equals(recordtype1, recordtype1)) + Assert.False(FSharpValue.Equals(recordtype1, recordtype2)) // Generic Record value - Assert.IsTrue(FSharpValue.Equals(genericRecordType1, genericRecordType1)) - Assert.IsFalse(FSharpValue.Equals(genericRecordType1, genericRecordType2)) + Assert.True(FSharpValue.Equals(genericRecordType1, genericRecordType1)) + Assert.False(FSharpValue.Equals(genericRecordType1, genericRecordType2)) // null value - Assert.IsTrue(FSharpValue.Equals(nullValue, nullValue)) - Assert.IsFalse(FSharpValue.Equals(nullValue, 1)) + Assert.True(FSharpValue.Equals(nullValue, nullValue)) + Assert.False(FSharpValue.Equals(nullValue, 1)) // Single Case Union - Assert.IsTrue(FSharpValue.Equals(singlecaseunion1, singlecaseunion1)) - Assert.IsFalse(FSharpValue.Equals(singlecaseunion1, singlecaseunion2)) + Assert.True(FSharpValue.Equals(singlecaseunion1, singlecaseunion1)) + Assert.False(FSharpValue.Equals(singlecaseunion1, singlecaseunion2)) // Discriminated Union - Assert.IsTrue(FSharpValue.Equals(discUniontypeA, discUniontypeA)) - Assert.IsFalse(FSharpValue.Equals(discUniontypeB, discUniontypeC)) + Assert.True(FSharpValue.Equals(discUniontypeA, discUniontypeA)) + Assert.False(FSharpValue.Equals(discUniontypeB, discUniontypeC)) // FSharpDelegate - Assert.IsTrue(FSharpValue.Equals(fsharpdelegate1, fsharpdelegate1)) - Assert.IsFalse(FSharpValue.Equals(fsharpdelegate1, fsharpdelegate2)) + Assert.True(FSharpValue.Equals(fsharpdelegate1, fsharpdelegate1)) + Assert.False(FSharpValue.Equals(fsharpdelegate1, fsharpdelegate2)) // Tuple - Assert.IsTrue(FSharpValue.Equals(tuple1, tuple1)) - Assert.IsFalse(FSharpValue.Equals(tuple1, tuple2)) + Assert.True(FSharpValue.Equals(tuple1, tuple1)) + Assert.False(FSharpValue.Equals(tuple1, tuple2)) // Exception - Assert.IsTrue(FSharpValue.Equals(exInt, exInt)) - Assert.IsFalse(FSharpValue.Equals(exInt, exDataless)) + Assert.True(FSharpValue.Equals(exInt, exInt)) + Assert.False(FSharpValue.Equals(exInt, exDataless)) // Static methods - [] - member __.GetExceptionFields() = + [] + member _.GetExceptionFields() = // positive let forallexistedInt = FSharpType.GetExceptionFields(typeof) |> Array.forall (fun property -> (Array.IndexOf(typeof.GetProperties(), property) > -1)) - Assert.IsTrue(forallexistedInt) + Assert.True(forallexistedInt) let forallexistedDataless = FSharpType.GetExceptionFields(typeof) |> Array.forall (fun property -> (Array.IndexOf(typeof.GetProperties(), property) > -1)) - Assert.IsTrue(forallexistedDataless) + Assert.True(forallexistedDataless) // Argument Exception CheckThrowsArgumentException(fun () ->FSharpType.GetExceptionFields(typeof) |> ignore ) @@ -900,8 +958,8 @@ type FSharpTypeTests() = CheckThrowsArgumentNullException(fun () ->FSharpType.GetExceptionFields(null) |> ignore ) - [] - member __.GetFunctionElements() = + [] + member _.GetFunctionElements() = // positive Assert.AreEqual(FSharpType.GetFunctionElements(typeof string>), (typeof, typeof)) @@ -913,8 +971,8 @@ type FSharpTypeTests() = // null CheckThrowsArgumentNullException(fun () ->FSharpType.GetFunctionElements(null) |> ignore ) - [] - member __.GetRecordFields() = + [] + member _.GetRecordFields() = // positive Assert.AreEqual(FSharpType.GetRecordFields(typeof), (typeof.GetProperties())) @@ -927,8 +985,8 @@ type FSharpTypeTests() = CheckThrowsArgumentNullException(fun () ->FSharpType.GetRecordFields(null) |> ignore ) - [] - member __.GetTupleElements() = + [] + member _.GetTupleElements() = // positive Assert.AreEqual(FSharpType.GetTupleElements(typeof>), [|typeof; typeof|]) @@ -940,8 +998,8 @@ type FSharpTypeTests() = // null CheckThrowsArgumentNullException(fun () ->FSharpType.GetTupleElements(null) |> ignore ) - [] - member __.GetUnionCases() = + [] + member _.GetUnionCases() = // SingleCaseUnion let singlecaseUnionCaseInfoArray = FSharpType.GetUnionCases(typeof) let (expectedSinglecaseinfo, singlevaluearray) = FSharpValue.GetUnionFields(singlecaseunion1, typeof) @@ -958,35 +1016,35 @@ type FSharpTypeTests() = // invalid value CheckThrowsArgumentException(fun () -> FSharpType.GetUnionCases(typeof) |> ignore) - [] - member __.IsExceptionRepresentation() = + [] + member _.IsExceptionRepresentation() = // positive - Assert.IsTrue(FSharpType.IsExceptionRepresentation(typeof)) - Assert.IsTrue(FSharpType.IsExceptionRepresentation(typeof)) + Assert.True(FSharpType.IsExceptionRepresentation(typeof)) + Assert.True(FSharpType.IsExceptionRepresentation(typeof)) // negative - Assert.IsFalse(FSharpType.IsExceptionRepresentation(typeof)) - Assert.IsFalse(FSharpType.IsExceptionRepresentation(typeof)) + Assert.False(FSharpType.IsExceptionRepresentation(typeof)) + Assert.False(FSharpType.IsExceptionRepresentation(typeof)) // null CheckThrowsArgumentNullException(fun () -> FSharpType.IsExceptionRepresentation(null) |> ignore ) - [] - member __.IsFunction() = + [] + member _.IsFunction() = // positive - Assert.IsTrue(FSharpType.IsFunction(typeof int>)) - Assert.IsTrue(FSharpType.IsFunction(typeof int -> int>)) + Assert.True(FSharpType.IsFunction(typeof int>)) + Assert.True(FSharpType.IsFunction(typeof int -> int>)) // negative - Assert.IsFalse(FSharpType.IsFunction(typeof)) + Assert.False(FSharpType.IsFunction(typeof)) // null CheckThrowsArgumentNullException(fun () -> FSharpType.IsFunction(null) |> ignore ) - [] - member __.IsModule() = + [] + member _.IsModule() = let getasm (t : Type) = t.Assembly @@ -998,80 +1056,80 @@ type FSharpTypeTests() = |> Array.filter (fun ty -> ty.Name = "IsModule") |> (fun arr -> arr.[0]) - Assert.IsTrue(FSharpType.IsModule(moduleType)) //assemblyTypesPositive.[3] is Microsoft_FSharp_Reflection.FSharpModule which is module type + Assert.True(FSharpType.IsModule(moduleType)) //assemblyTypesPositive.[3] is Microsoft_FSharp_Reflection.FSharpModule which is module type // Negative Test // FSharp Assembly let asmCore = getasm (typeof>) - Assert.IsFalse(FSharpType.IsModule(asmCore.GetTypes().[0])) + Assert.False(FSharpType.IsModule(asmCore.GetTypes().[0])) // .Net Assembly let asmSystem = getasm (typeof) - Assert.IsFalse(FSharpType.IsModule(asmSystem.GetTypes().[0])) + Assert.False(FSharpType.IsModule(asmSystem.GetTypes().[0])) // custom Assembly let asmCustom = getasm (typeof) - Assert.IsFalse(FSharpType.IsModule(asmCustom.GetTypes().[0])) + Assert.False(FSharpType.IsModule(asmCustom.GetTypes().[0])) // null CheckThrowsArgumentNullException(fun () -> FSharpType.IsModule(null) |> ignore ) - [] - member __.IsRecord() = + [] + member _.IsRecord() = // positive - Assert.IsTrue(FSharpType.IsRecord(typeof)) - Assert.IsTrue(FSharpType.IsRecord(typeof)) - Assert.IsTrue(FSharpType.IsRecord(typeof>)) + Assert.True(FSharpType.IsRecord(typeof)) + Assert.True(FSharpType.IsRecord(typeof)) + Assert.True(FSharpType.IsRecord(typeof>)) // negative - Assert.IsFalse(FSharpType.IsRecord(typeof)) + Assert.False(FSharpType.IsRecord(typeof)) // null CheckThrowsArgumentNullException(fun () ->FSharpType.IsRecord(null) |> ignore ) // Regression for 5588, Reflection: unit is still treated as a record type, but only if you pass BindingFlags.NonPublic - [] - member __.``IsRecord.Regression5588``() = + [] + member _.``IsRecord.Regression5588``() = // negative - Assert.IsFalse(FSharpType.IsRecord(typeof)) - Assert.IsFalse( FSharpType.IsRecord(typeof, System.Reflection.BindingFlags.NonPublic) ) + Assert.False(FSharpType.IsRecord(typeof)) + Assert.False( FSharpType.IsRecord(typeof, System.Reflection.BindingFlags.NonPublic) ) () - [] - member __.IsTuple() = + [] + member _.IsTuple() = // positive - Assert.IsTrue(FSharpType.IsTuple(typeof>)) - Assert.IsTrue(FSharpType.IsTuple(typeof>)) + Assert.True(FSharpType.IsTuple(typeof>)) + Assert.True(FSharpType.IsTuple(typeof>)) - Assert.IsTrue(FSharpType.IsTuple(typeof)) - Assert.IsTrue(FSharpType.IsTuple(typeof)) + Assert.True(FSharpType.IsTuple(typeof)) + Assert.True(FSharpType.IsTuple(typeof)) // negative - Assert.IsFalse(FSharpType.IsTuple(typeof)) - Assert.IsFalse(FSharpType.IsTuple(typeof)) + Assert.False(FSharpType.IsTuple(typeof)) + Assert.False(FSharpType.IsTuple(typeof)) // null CheckThrowsArgumentNullException(fun () ->FSharpType.IsTuple(null) |> ignore ) - [] - member __.IsUnion() = + [] + member _.IsUnion() = // positive - Assert.IsTrue(FSharpType.IsUnion(typeof)) - Assert.IsTrue(FSharpType.IsUnion(typeof)) - Assert.IsTrue(FSharpType.IsUnion(typeof>)) - Assert.IsTrue(FSharpType.IsUnion(typeof>)) + Assert.True(FSharpType.IsUnion(typeof)) + Assert.True(FSharpType.IsUnion(typeof)) + Assert.True(FSharpType.IsUnion(typeof>)) + Assert.True(FSharpType.IsUnion(typeof>)) // negative - Assert.IsFalse(FSharpType.IsUnion(typeof)) - Assert.IsFalse(FSharpType.IsUnion(typeof)) + Assert.False(FSharpType.IsUnion(typeof)) + Assert.False(FSharpType.IsUnion(typeof)) // null CheckThrowsArgumentNullException(fun () ->FSharpType.IsUnion(null) |> ignore ) - [] - member __.MakeFunctionType() = + [] + member _.MakeFunctionType() = // positive Assert.AreEqual(FSharpType.MakeFunctionType(typeof, typeof), typeofstring>) @@ -1082,8 +1140,8 @@ type FSharpTypeTests() = // null CheckThrowsArgumentNullException(fun () ->FSharpType.MakeFunctionType(null, null) |> ignore ) - [] - member __.MakeTupleType() = + [] + member _.MakeTupleType() = // positive Assert.AreEqual(FSharpType.MakeTupleType([|typeof; typeof|]), typeof>) @@ -1094,8 +1152,8 @@ type FSharpTypeTests() = // null CheckThrowsArgumentException(fun () ->FSharpType.MakeTupleType([|null;null|]) |> ignore ) - [] - member __.MakeStructTupleType() = + [] + member _.MakeStructTupleType() = let asm = typeof.Assembly // positive Assert.AreEqual(FSharpType.MakeStructTupleType(asm, [|typeof; typeof|]), typeof) @@ -1106,8 +1164,6 @@ type FSharpTypeTests() = // null CheckThrowsArgumentException(fun () ->FSharpType.MakeStructTupleType(asm, [|null;null|]) |> ignore ) - -[] type UnionCaseInfoTests() = let singlenullarycaseunion = SingleNullaryCaseDiscUnion.SingleNullaryCaseTag @@ -1131,33 +1187,33 @@ type UnionCaseInfoTests() = let ((recDiscCaseinfo:UnionCaseInfo), recDiscCasevaluearray) = FSharpValue.GetUnionFields(recDiscUniontypeB, typeof>) - [] - member __.Equals() = + [] + member _.Equals() = //positive // single case - Assert.IsTrue(singlecaseinfo.Equals(singlecaseinfo)) + Assert.True(singlecaseinfo.Equals(singlecaseinfo)) // disc union - Assert.IsTrue(discUnionInfoA.Equals(discUnionInfoA)) + Assert.True(discUnionInfoA.Equals(discUnionInfoA)) // rec disc union - Assert.IsTrue(recDiscCaseinfo.Equals(recDiscCaseinfo)) + Assert.True(recDiscCaseinfo.Equals(recDiscCaseinfo)) // negative // single case - Assert.IsFalse(singlecaseinfo.Equals(discUnionInfoA)) + Assert.False(singlecaseinfo.Equals(discUnionInfoA)) // disc union - Assert.IsFalse(discUnionInfoA.Equals(discUnionInfoB)) + Assert.False(discUnionInfoA.Equals(discUnionInfoB)) // rec disc union - Assert.IsFalse(recDiscCaseinfo.Equals(discUnionInfoA)) + Assert.False(recDiscCaseinfo.Equals(discUnionInfoA)) // null - Assert.IsFalse(singlecaseinfo.Equals(null)) + Assert.False(singlecaseinfo.Equals(null)) - [] - member __.GetCustomAttributes() = + [] + member _.GetCustomAttributes() = // single case let singlecaseAttribute = (singlecaseinfo.GetCustomAttributes()).[0] :?> Attribute @@ -1174,8 +1230,8 @@ type UnionCaseInfoTests() = // null CheckThrowsArgumentNullException(fun () -> singlecaseinfo.GetCustomAttributes(null) |> ignore ) - [] - member __.GetFields() = + [] + member _.GetFields() = // single case let singlecaseFieldInfo = (singlecaseinfo.GetFields()).[0] @@ -1193,8 +1249,8 @@ type UnionCaseInfoTests() = let recdiscFieldInfo = (recDiscCaseinfo.GetFields()).[0] Assert.AreEqual(recdiscFieldInfo.PropertyType , typeof) - [] - member __.GetHashCode() = + [] + member _.GetHashCode() = // positive // single case @@ -1212,8 +1268,8 @@ type UnionCaseInfoTests() = // disc union Assert.AreNotEqual(discUnionInfoA.GetHashCode(), discUnionInfoB.GetHashCode()) - [] - member __.GetType() = + [] + member _.GetType() = // single case Assert.AreEqual(singlecaseinfo.GetType(), typeof ) @@ -1224,8 +1280,8 @@ type UnionCaseInfoTests() = // rec disc union Assert.AreEqual(recDiscCaseinfo.GetType(), typeof ) - [] - member __.ToString() = + [] + member _.ToString() = // single case Assert.AreEqual(singlenullarycaseinfo.ToString(), "SingleNullaryCaseDiscUnion.SingleNullaryCaseTag") @@ -1234,7 +1290,7 @@ type UnionCaseInfoTests() = Assert.AreEqual(singlecaseinfo.ToString(), "SingleCaseDiscUnion.SingleCaseTag") // disc union - Assert.IsTrue((discUnionInfoA.ToString()).Contains("DiscUnionType") ) + Assert.True((discUnionInfoA.ToString()).Contains("DiscUnionType") ) // rec disc union - Assert.IsTrue((recDiscCaseinfo.ToString()).Contains("DiscUnionType")) + Assert.True((recDiscCaseinfo.ToString()).Contains("DiscUnionType")) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/NativeInterop.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/NativeInterop.fs new file mode 100644 index 00000000000..98977c201b0 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/NativeInterop.fs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the NativeInterop namespace + +namespace FSharp.Core.UnitTests.NativeInterop + +open System +open FSharp.Core.UnitTests.LibraryTestFx +open Xunit +open Microsoft.FSharp.NativeInterop + +#nowarn "9" // FS0009 Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. + +type NativePtr() = + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + [] + member _.Test<'T when 'T : unmanaged>(n0 : 'T, nusual : 'T, nextreme : 'T, nhex11 : 'T) = + let size = sizeof<'T> |> nativeint + let a0 = NativePtr.stackalloc<'T> 4 + let a1 = NativePtr.add a0 1 + let a2 = NativePtr.add a0 2 + let a3 = NativePtr.add a0 3 + let i0 = NativePtr.toNativeInt a0 + let assertStack v0 v1 v2 v3 = + Assert.Equal(v0, NativePtr.get a0 0) + Assert.Equal(v1, NativePtr.get a0 1) + Assert.Equal(v2, NativePtr.get a0 2) + Assert.Equal(v3, NativePtr.get a0 3) + Assert.Equal(v0, NativePtr.read a0) + Assert.Equal(v1, NativePtr.read a1) + Assert.Equal(v2, NativePtr.read a2) + Assert.Equal(v3, NativePtr.read a3) + Assert.Equal(i0 + 1n * size, a1 |> NativePtr.toNativeInt) + Assert.Equal(i0 + 2n * size, a2 |> NativePtr.toNativeInt) + Assert.Equal(i0 + 3n * size, a3 |> NativePtr.toNativeInt) + Assert.Equal(i0 - 5n * size, NativePtr.add a0 -5 |> NativePtr.toNativeInt) + Assert.Equal(a2, + a2 + |> NativePtr.toVoidPtr + |> NativePtr.ofVoidPtr<'T> + |> NativePtr.toILSigPtr + |> NativePtr.ofILSigPtr + ) + NativePtr.set a0 3 nusual + Assert.Equal(nusual, NativePtr.get a0 3) + Assert.Equal(nusual, NativePtr.get a3 0) + NativePtr.copy a2 a3 + Assert.Equal(nusual, NativePtr.get a0 3) + Assert.Equal(nusual, NativePtr.get a0 2) + NativePtr.copyBlock a0 a2 2 + assertStack nusual nusual nusual nusual + NativePtr.clear a0 + assertStack n0 nusual nusual nusual + NativePtr.initBlock a1 0x11uy (2u * uint size) + assertStack n0 nhex11 nhex11 nusual + NativePtr.write a2 nextreme + assertStack n0 nhex11 nextreme nusual + let nullPtr = NativePtr.ofNativeInt<'T> 0n + Assert.Equal(NativePtr.nullPtr, nullPtr) + Assert.True(NativePtr.isNullPtr nullPtr) + let notNullPtr = NativePtr.ofNativeInt<'T> 1n + Assert.NotEqual(NativePtr.nullPtr, notNullPtr) + Assert.False(NativePtr.isNullPtr notNullPtr) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 5aacff670ab..62db48e2ec9 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -3,360 +3,56 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx -open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked +open FSharp.Core.UnitTests.LibraryTestFx +open Xunit -[] type OperatorsModule1() = - [] - member this.Checkedbyte() = - // int type - let intByte = Operators.Checked.byte 100 - Assert.AreEqual(intByte,(byte)100) - - // char type - let charByte = Operators.Checked.byte '0' - Assert.AreEqual(charByte,(byte)48) - - // boundary value - let boundByte = Operators.Checked.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) - - // overflow exception - try - let overflowByte = Operators.Checked.byte 256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - - - - [] - member this.Checkedchar() = - - // number - let numberChar = Operators.Checked.char 48 - Assert.AreEqual(numberChar,'0') - - // letter - let letterChar = Operators.Checked.char 65 - Assert.AreEqual(letterChar,'A') - - // boundary value - let boundchar = Operators.Checked.char 126 - Assert.AreEqual(boundchar, '~') - - // overflow exception - try - let overflowchar = Operators.Checked.char (System.Int64.MaxValue+(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - [] - member this.CheckedInt() = - - // char - let charInt = Operators.Checked.int '0' - Assert.AreEqual(charInt,48) - - // float - let floatInt = Operators.Checked.int 10.0 - Assert.AreEqual(floatInt,10) - - - // boundary value - let boundInt = Operators.Checked.int 32767.0 - Assert.AreEqual(boundInt, (int)32767) - - // overflow exception - try - let overflowint = Operators.Checked.int 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt16() = + [] + member _.KeyValue() = - // char - let charInt16 = Operators.Checked.int16 '0' - Assert.AreEqual(charInt16,(int16)48) - - // float - let floatInt16 = Operators.Checked.int16 10.0 - Assert.AreEqual(floatInt16,(int16)10) - - // boundary value - let boundInt16 = Operators.Checked.int16 32767.0 - Assert.AreEqual(boundInt16, (int16)32767) - - // overflow exception - try - let overflowint16 = Operators.Checked.int16 32768.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedInt32() = - - // char - let charInt32 = Operators.Checked.int32 '0' - Assert.AreEqual(charInt32,(int32)48) - - // float - let floatInt32 = Operators.Checked.int32 10.0 - Assert.AreEqual(floatInt32,(int32)10) - - // boundary value - let boundInt32 = Operators.Checked.int32 2147483647.0 - Assert.AreEqual(boundInt32, (int32)2147483647) - - // overflow exception - try - let overflowint32 = Operators.Checked.int32 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.CheckedInt64() = - - // char - let charInt64 = Operators.Checked.int64 '0' - Assert.AreEqual(charInt64,(int64)48) - - // float - let floatInt64 = Operators.Checked.int64 10.0 - Assert.AreEqual(floatInt64,(int64)10) - - // boundary value - let boundInt64 = Operators.Checked.int64 9223372036854775807I - let a = 9223372036854775807L - Assert.AreEqual(boundInt64, 9223372036854775807L) - - // overflow exception - try - let overflowint64 = Operators.Checked.int64 (System.Double.MaxValue+2.0) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.CheckedNativeint() = - - // char - let charnativeint = Operators.Checked.nativeint '0' - Assert.AreEqual(charnativeint,(nativeint)48) - - // float - let floatnativeint = Operators.Checked.nativeint 10.0 - Assert.AreEqual(floatnativeint,(nativeint)10) - - // boundary value - let boundnativeint = Operators.Checked.nativeint 32767.0 - Assert.AreEqual(boundnativeint, (nativeint)32767) - - // overflow exception - try - let overflownativeint = Operators.Checked.nativeint 2147483648.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedsbyte() = - - // char - let charsbyte = Operators.Checked.sbyte '0' - Assert.AreEqual(charsbyte,(sbyte)48) - - // float - let floatsbyte = Operators.Checked.sbyte -10.0 - Assert.AreEqual(floatsbyte,(sbyte)(-10)) - - // boundary value - let boundsbyte = Operators.Checked.sbyte -127.0 - Assert.AreEqual(boundsbyte, (sbyte)(-127)) - - // overflow exception - try - let overflowsbyte = Operators.Checked.sbyte -256.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - - () - - [] - member this.Checkeduint16() = - - // char - let charuint16 = Operators.Checked.uint16 '0' - Assert.AreEqual(charuint16,(uint16)48) - - // float - let floatuint16 = Operators.Checked.uint16 10.0 - Assert.AreEqual(floatuint16,(uint16)(10)) - - // boundary value - let bounduint16 = Operators.Checked.uint16 65535.0 - Assert.AreEqual(bounduint16, (uint16)(65535)) - - // overflow exception - try - let overflowuint16 = Operators.Checked.uint16 65536.0 - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint32() = - - // char - let charuint32 = Operators.Checked.uint32 '0' - Assert.AreEqual(charuint32,(uint32)48) - - // float - let floatuint32 = Operators.Checked.uint32 10.0 - Assert.AreEqual(floatuint32,(uint32)(10)) - - // boundary value - let bounduint32 = Operators.Checked.uint32 429496729.0 - Assert.AreEqual(bounduint32, (uint32)(429496729)) - - - // overflow exception - try - let overflowuint32 = Operators.Checked.uint32 uint32.MaxValue+1u - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkeduint64() = - - // char - let charuint64 = Operators.Checked.uint64 '0' - Assert.AreEqual(charuint64,(uint64)48) - - // float - let floatuint64 = Operators.Checked.uint64 10.0 - Assert.AreEqual(floatuint64,(uint64)(10)) - - // boundary value - let bounduint64 = Operators.Checked.uint64 429496729.0 - Assert.AreEqual(bounduint64, (uint64)(429496729)) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.Checkedunativeint() = - - // char - let charunativeint = Operators.Checked.unativeint '0' - Assert.AreEqual(charunativeint,(unativeint)48) - - // float - let floatunativeint = Operators.Checked.unativeint 10.0 - Assert.AreEqual(floatunativeint,(unativeint)10) - - // boundary value - let boundunativeint = Operators.Checked.unativeint 65353.0 - Assert.AreEqual(boundunativeint, (unativeint)65353) - - // overflow exception - try - let overflowuint64 = Operators.Checked.uint64 System.UInt64.MaxValue+1UL - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") - () - - [] - member this.KeyValue() = - - let funcKeyValue x = match x with | Operators.KeyValue(a) -> a // string int let stringint = funcKeyValue ( new System.Collections.Generic.KeyValuePair("string",1)) - Assert.AreEqual(stringint,("string",1)) + Assert.AreEqual(("string",1), stringint) // float char let floatchar = funcKeyValue ( new System.Collections.Generic.KeyValuePair(1.0,'a')) - Assert.AreEqual(floatchar,(1.0,'a')) + Assert.AreEqual((1.0,'a'), floatchar) // null let nullresult = funcKeyValue ( new System.Collections.Generic.KeyValuePair(null,' ')) let (nullstring:string,blankchar:char) = nullresult CheckThrowsNullRefException(fun () -> nullstring.ToString() |> ignore) - - - () - - [] - member this.OptimizedRangesGetArraySlice() = - + [] + member _.OptimizedRangesGetArraySlice() = + let param1 = Some(1) let param2 = Some(2) // int let intslice = Operators.OperatorIntrinsics.GetArraySlice [|1;2;3;4;5;6|] param1 param2 - Assert.AreEqual(intslice,[|2;3|]) + Assert.AreEqual([|2;3|], intslice) // string let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|"1";"2";"3"|] param1 param2 - Assert.AreEqual(stringslice,[|"2";"3"|]) + Assert.AreEqual([|"2";"3"|], stringslice) // null let stringslice = Operators.OperatorIntrinsics.GetArraySlice [|null;null;null|] param1 param2 - Assert.AreEqual(stringslice,[|null;null|]) - - () - - [] - member this.OptimizedRangesGetArraySlice2D() = + Assert.AreEqual([|null;null|], stringslice) + + [] + member _.OptimizedRangesGetArraySlice2D() = - let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -366,36 +62,32 @@ type OperatorsModule1() = let intArray2D = Array2D.init 2 3 (fun i j -> i*100+j) let intslice = Operators.OperatorIntrinsics.GetArraySlice2D intArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(intslice.[1,1],101) + Assert.AreEqual(101, intslice.[1,1]) // string let stringArray2D = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) let stringslice = Operators.OperatorIntrinsics.GetArraySlice2D stringArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(stringslice.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringslice.[1,1]) // null let nullArray2D = Array2D.init 2 3 (fun i j -> null) let nullslice = Operators.OperatorIntrinsics.GetArraySlice2D nullArray2D param1D1 param1D2 param2D1 param2D2 - Assert.AreEqual(nullslice.[1,1],null) - - () - - [] - member this.OptimizedRangesGetStringSlice() = + Assert.AreEqual(null, nullslice.[1,1]) + + [] + member _.OptimizedRangesGetStringSlice() = let param1 = Some(4) let param2 = Some(6) // string let stringslice = Operators.OperatorIntrinsics.GetStringSlice "abcdefg" param1 param2 - Assert.AreEqual(stringslice,"efg") + Assert.AreEqual("efg", stringslice) // null CheckThrowsNullRefException(fun () -> Operators.OperatorIntrinsics.GetStringSlice null param1 param2 |> ignore) - () - - - [] - member this.OptimizedRangesSetArraySlice() = + + [] + member _.OptimizedRangesSetArraySlice() = let param1 = Some(1) let param2 = Some(2) @@ -403,23 +95,22 @@ type OperatorsModule1() = let intArray1 = [|1;2;3|] let intArray2 = [|4;5;6|] Operators.OperatorIntrinsics.SetArraySlice intArray1 param1 param2 intArray2 - Assert.AreEqual(intArray1,[|1;4;5|]) + Assert.AreEqual([|1;4;5|], intArray1) // string let stringArray1 = [|"1";"2";"3"|] let stringArray2 = [|"4";"5";"6"|] Operators.OperatorIntrinsics.SetArraySlice stringArray1 param1 param2 stringArray2 - Assert.AreEqual(stringArray1,[|"1";"4";"5"|]) + Assert.AreEqual([|"1";"4";"5"|], stringArray1) // null let nullArray1 = [|null;null;null|] let nullArray2 = [|null;null;null|] Operators.OperatorIntrinsics.SetArraySlice nullArray1 param1 param2 nullArray2 CheckThrowsNullRefException(fun () -> nullArray1.[0].ToString() |> ignore) - () - - [] - member this.OptimizedRangesSetArraySlice2D() = + + [] + member _.OptimizedRangesSetArraySlice2D() = let param1D1 = Some(0) let param1D2 = Some(1) let param2D1 = Some(0) @@ -429,43 +120,40 @@ type OperatorsModule1() = let intArray1 = Array2D.init 2 3 (fun i j -> i*10+j) let intArray2 = Array2D.init 2 3 (fun i j -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice2D intArray1 param1D1 param1D2 param2D1 param2D2 intArray2 - Assert.AreEqual(intArray1.[1,1],101) + Assert.AreEqual(101, intArray1.[1,1]) // string let stringArray2D1 = Array2D.init 2 3 (fun i j -> (i*10+j).ToString()) let stringArray2D2 = Array2D.init 2 3 (fun i j -> (i*100+j).ToString()) Operators.OperatorIntrinsics.SetArraySlice2D stringArray2D1 param1D1 param1D2 param2D1 param2D2 stringArray2D2 - Assert.AreEqual(stringArray2D1.[1,1],(101).ToString()) + Assert.AreEqual((101).ToString(), stringArray2D1.[1,1]) // null let nullArray2D1 = Array2D.init 2 3 (fun i j -> null) let nullArray2D2 = Array2D.init 2 3 (fun i j -> null) Operators.OperatorIntrinsics.SetArraySlice2D nullArray2D1 param1D1 param1D2 param2D1 param2D2 nullArray2D2 CheckThrowsNullRefException(fun () -> nullArray2D1.[0,0].ToString() |> ignore) - () - - [] - member this.OptimizedRangesSetArraySlice3D() = + + [] + member _.OptimizedRangesSetArraySlice3D() = let intArray1 = Array3D.init 2 3 4 (fun i j k -> i*10+j) let intArray2 = Array3D.init 2 3 4 (fun i j k -> i*100+j) Operators.OperatorIntrinsics.SetArraySlice3D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1],101) - () + Assert.AreEqual(101, intArray1.[1,1,1]) - [] - member this.OptimizedRangesSetArraySlice4D() = + [] + member _.OptimizedRangesSetArraySlice4D() = let intArray1 = Array4D.init 2 3 4 5 (fun i j k l -> i*10+j) let intArray2 = Array4D.init 2 3 4 5 (fun i j k l -> i*100+j) - Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 - Assert.AreEqual(intArray1.[1,1,1,1],101) - () - - [] - member this.Uncheckeddefaultof () = + Operators.OperatorIntrinsics.SetArraySlice4D intArray1 (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) (Some 0) (Some 1) intArray2 + Assert.AreEqual(101, intArray1.[1,1,1,1]) + + [] + member _.Uncheckeddefaultof () = // int let intdefault = Operators.Unchecked.defaultof - Assert.AreEqual(intdefault, 0) + Assert.AreEqual(0, intdefault) // string let stringdefault = Operators.Unchecked.defaultof @@ -473,472 +161,451 @@ type OperatorsModule1() = // null let structdefault = Operators.Unchecked.defaultof - Assert.AreEqual( structdefault.Day,1) - - () - - [] - member this.abs () = + Assert.AreEqual(1, structdefault.Day) + + [] + member _.abs () = // int let intabs = Operators.abs (-7) - Assert.AreEqual(intabs, 7) + Assert.AreEqual(7, intabs) - // float + // float let floatabs = Operators.abs (-100.0) - Assert.AreEqual(floatabs, 100.0) + Assert.AreEqual(100.0, floatabs) // decimal let decimalabs = Operators.abs (-1000M) - Assert.AreEqual(decimalabs, 1000M) - - () - - [] - member this.acos () = + Assert.AreEqual(1000M, decimalabs) + + [] + member _.acos () = // min value let minacos = Operators.acos (0.0) - Assert.AreEqual(minacos, 1.5707963267948966) + Assert.AreNearEqual(1.5707963267948966, minacos) // normal value let normalacos = Operators.acos (0.3) - Assert.AreEqual(normalacos, 1.2661036727794992) + Assert.AreNearEqual(1.2661036727794992, normalacos) // max value let maxacos = Operators.acos (1.0) - Assert.AreEqual(maxacos, 0.0) - () - - [] - member this.asin () = + Assert.AreEqual(0.0, maxacos) + + [] + member _.asin () = // min value let minasin = Operators.asin (0.0) - Assert.AreEqual(minasin, 0) + Assert.AreEqual(0.0, minasin) // normal value let normalasin = Operators.asin (0.5) - Assert.AreEqual(normalasin, 0.52359877559829893) + Assert.AreNearEqual(0.52359877559829893, normalasin) // max value let maxasin = Operators.asin (1.0) - Assert.AreEqual(maxasin, 1.5707963267948966) - () - - - - [] - member this.atan () = + Assert.AreNearEqual(1.5707963267948966, maxasin) + + [] + member _.atan () = // min value let minatan = Operators.atan (0.0) - Assert.AreEqual(minatan, 0) + Assert.AreNearEqual(0.0, minatan) // normal value let normalatan = Operators.atan (1.0) - Assert.AreEqual(normalatan, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan) // biggish value let maxatan = Operators.atan (infinity) - Assert.AreEqual(maxatan, 1.5707963267948966) - () - - [] - member this.atan2 () = + Assert.AreNearEqual(1.5707963267948966, maxatan) + + [] + member _.atan2 () = // min value let minatan2 = Operators.atan2 (0.0) (1.0) - Assert.AreEqual(minatan2, 0) + Assert.AreNearEqual(0.0, minatan2) // normal value let normalatan2 = Operators.atan2 (1.0) (1.0) - Assert.AreEqual(normalatan2, 0.78539816339744828) + Assert.AreNearEqual(0.78539816339744828, normalatan2) // biggish value let maxatan2 = Operators.atan2 (1.0) (0.0) - Assert.AreEqual(maxatan2, 1.5707963267948966) - () - - [] - member this.box () = + Assert.AreNearEqual(1.5707963267948966, maxatan2) + + [] + member _.box () = // int value let intbox = Operators.box 1 - Assert.AreEqual(intbox, 1) + Assert.AreEqual(1, intbox) // string value let stringlbox = Operators.box "string" - Assert.AreEqual(stringlbox, "string") + Assert.AreEqual("string", stringlbox) // null value let nullbox = Operators.box null CheckThrowsNullRefException(fun () -> nullbox.ToString() |> ignore) - () - - [] - member this.byte() = - // int type + + [] + member _.byte() = + // int type let intByte = Operators.byte 100 - Assert.AreEqual(intByte,(byte)100) + Assert.AreEqual(100uy, intByte) - // char type + // char type let charByte = Operators.byte '0' - Assert.AreEqual(charByte,(byte)48) + Assert.AreEqual(48uy, charByte) // boundary value let boundByte = Operators.byte 255.0 - Assert.AreEqual(boundByte, (byte)255) + Assert.AreEqual(255uy, boundByte) - // overflow exception - try - let overflowbyte = Operators.byte (System.Int64.MaxValue*(int64)2) - Assert.Fail("Expectt overflow exception but not.") - with - | :? System.OverflowException -> () - | _ -> Assert.Fail("Expectt overflow exception but not.") + // Overflow + let result = Operators.byte Int64.MaxValue + Assert.AreEqual(Byte.MaxValue, result) + + // Overflow + let result = Operators.byte Int64.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MaxValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte (Int64.MaxValue * 8L) + Assert.AreEqual(248uy, result) // bit-complement + + // Overflow + let result = 255uy + 5uy + Assert.AreEqual(4uy, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) - [] - member this.ceil() = - // min value + [] + member _.ceil() = + // min value let minceil = Operators.ceil 0.1 - Assert.AreEqual(minceil,1.0) + Assert.AreEqual(1.0, minceil) - // normal value + // normal value let normalceil = Operators.ceil 100.0 - Assert.AreEqual(normalceil,100.0) + Assert.AreEqual(100.0, normalceil) // max value let maxceil = Operators.ceil 1.7E+308 - Assert.AreEqual(maxceil, 1.7E+308) + Assert.AreEqual(1.7E+308, maxceil) - [] - member this.char() = - // int type + [] + member _.char() = + // int type let intchar = Operators.char 48 - Assert.AreEqual(intchar,'0') + Assert.AreEqual('0', intchar) - // string type + // string type let stringchar = Operators.char " " - Assert.AreEqual(stringchar, ' ') + Assert.AreEqual(' ', stringchar) - [] - member this.compare() = - // int type + [] + member _.compare() = + // int type let intcompare = Operators.compare 100 101 - Assert.AreEqual(intcompare,-1) + Assert.AreEqual(-1, intcompare) - // char type + // char type let charcompare = Operators.compare '0' '1' - Assert.AreEqual(charcompare,-1) + Assert.AreEqual(-1, charcompare) // null value let boundcompare = Operators.compare null null - Assert.AreEqual(boundcompare, 0) - - - [] - member this.cos () = + Assert.AreEqual(0, boundcompare) + + [] + member _.cos () = // min value let mincos = Operators.cos (0.0) - Assert.AreEqual(mincos, 1) + Assert.AreEqual(1.0, mincos) // normal value let normalcos = Operators.cos (1.0) - Assert.AreEqual(normalcos, 0.54030230586813977) + Assert.AreNearEqual(0.54030230586813977, normalcos) // biggish value let maxcos = Operators.cos (1.57) - Assert.AreEqual(maxcos, 0.00079632671073326335) - () - - [] - member this.cosh () = - + Assert.AreNearEqual(0.00079632671073326335, maxcos) + + [] + member _.cosh () = + // min value let mincosh = Operators.cosh (0.0) - Assert.AreEqual(mincosh, 1.0) + Assert.AreEqual(1.0, mincosh) // normal value let normalcosh = Operators.cosh (1.0) - Assert.AreEqual(normalcosh, 1.5430806348152437) + Assert.AreNearEqual(1.5430806348152437, normalcosh) // biggish value let maxcosh = Operators.cosh (1.57) - Assert.AreEqual(maxcosh, 2.5073466880660993) - - - () - - - - [] - member this.decimal () = + Assert.AreNearEqual(2.5073466880660993, maxcosh) + + [] + member _.decimal () = // int value let mindecimal = Operators.decimal (1) - Assert.AreEqual(mindecimal, 1) + Assert.AreEqual(1M, mindecimal) // float value let maxdecimal = Operators.decimal (1.0) - Assert.AreEqual(maxdecimal, 1) - () - - [] - member this.decr() = - // zero + Assert.AreEqual(1M, maxdecimal) + + [] + member _.decr() = + // zero let zeroref = ref 0 Operators.decr zeroref - Assert.AreEqual(zeroref,(ref -1)) + Assert.AreEqual((ref -1), zeroref) // big number let bigref = ref 32767 Operators.decr bigref - Assert.AreEqual(bigref,(ref 32766)) + Assert.AreEqual((ref 32766), bigref) // normal value let normalref = ref 100 Operators.decr (normalref) - Assert.AreEqual(normalref,(ref 99)) + Assert.AreEqual((ref 99), normalref) - [] - member this.defaultArg() = - // zero + [] + member _.defaultArg() = + // zero let zeroOption = Some(0) let intdefaultArg = Operators.defaultArg zeroOption 2 - Assert.AreEqual(intdefaultArg,0) + Assert.AreEqual(0, intdefaultArg) // big number let bigOption = Some(32767) let bigdefaultArg = Operators.defaultArg bigOption 32766 - Assert.AreEqual(bigdefaultArg,32767) + Assert.AreEqual(32767, bigdefaultArg) // normal value let normalOption = Some(100) let normalfaultArg = Operators.defaultArg normalOption 100 - Assert.AreEqual(normalfaultArg, 100) - - [] - member this.double() = - // int type - let intdouble = Operators.double 100 - Assert.AreEqual(intdouble,100.0) - - // char type - let chardouble = Operators.double '0' - Assert.AreEqual(chardouble,48) - () - - [] - member this.enum() = - // zero + Assert.AreEqual(100, normalfaultArg) + + [] + member _.double() = + // int type + let intdouble = Operators.float 100 + Assert.AreEqual(100.0, intdouble) + + // char type + let chardouble = Operators.float '0' + Assert.AreEqual(48.0, chardouble) + + [] + member _.enum() = + // zero let intarg : int32 = 0 let intenum = Operators.enum intarg - Assert.AreEqual(intenum,System.ConsoleColor.Black) + Assert.AreEqual(System.ConsoleColor.Black, intenum) // big number let bigarg : int32 = 15 let charenum = Operators.enum bigarg - Assert.AreEqual(charenum,System.ConsoleColor.White) + Assert.AreEqual(System.ConsoleColor.White, charenum) // normal value let normalarg : int32 = 9 let boundenum = Operators.enum normalarg - Assert.AreEqual(boundenum, System.ConsoleColor.Blue) + Assert.AreEqual(System.ConsoleColor.Blue, boundenum) #if IGNORED [] - member this.exit() = - // zero - try + member _.exit() = + // zero + try let intexit = Operators.exit 1 - () + with | _ -> () - //Assert.AreEqual(intexit,-1) + //Assert.AreEqual(-1, intexit) // big number let charexit = Operators.exit 32767 - //Assert.AreEqual(charexit,-1) + //Assert.AreEqual(-1, charexit) // normal value let boundexit = Operators.exit 100 - Assert.AreEqual(boundexit, 0) + Assert.AreEqual(0, boundexit) #endif - [] - member this.exp() = - // zero + [] + member _.exp() = + // zero let zeroexp = Operators.exp 0.0 - Assert.AreEqual(zeroexp,1.0) + Assert.AreEqual(1.0, zeroexp) // big number let bigexp = Operators.exp 32767.0 - Assert.AreEqual(bigexp,infinity) + Assert.AreEqual(infinity, bigexp) // normal value let normalexp = Operators.exp 100.0 - Assert.AreEqual(normalexp, 2.6881171418161356E+43) + Assert.AreEqual(2.6881171418161356E+43, normalexp) - [] - member this.failwith() = - try + [] + member _.failwith() = + try let _ = Operators.failwith "failwith" Assert.Fail("Expect fail but not.") - () + with | Failure("failwith") -> () |_ -> Assert.Fail("Throw unexpected exception") - - - [] - member this.float() = - // int type + + [] + member _.float() = + // int type let intfloat = Operators.float 100 - Assert.AreEqual(intfloat,(float)100) + Assert.AreEqual((float)100, intfloat) - // char type + // char type let charfloat = Operators.float '0' - Assert.AreEqual(charfloat,(float)48) - - () - - - [] - member this.float32() = - // int type + Assert.AreEqual((float)48, charfloat) + + [] + member _.float32() = + // int type let intfloat32 = Operators.float32 100 - Assert.AreEqual(intfloat32,(float32)100) + Assert.AreEqual((float32)100, intfloat32) - // char type + // char type let charfloat32 = Operators.float32 '0' - Assert.AreEqual(charfloat32,(float32)48) - - () - - - [] - member this.floor() = - // float type - let intfloor = Operators.floor 100.0 - Assert.AreEqual(intfloor,100) - - // float32 type - let charfloor = Operators.floor ((float32)100.0) - Assert.AreEqual(charfloor,100) + Assert.AreEqual((float32)48, charfloat32) + + [] + member _.floor() = + // float type + let intfloor = Operators.floor 100.9 + Assert.AreEqual(100.0, intfloor) + + // float32 type + let charfloor = Operators.floor ((float32)100.9) + Assert.AreEqual(100.0f, charfloor) - [] - member this.fst() = - // int type + [] + member _.fst() = + // int type let intfst = Operators.fst (100,101) - Assert.AreEqual(intfst,100) + Assert.AreEqual(100, intfst) - // char type + // char type let charfst = Operators.fst ('0','1') - Assert.AreEqual(charfst,'0') + Assert.AreEqual('0', charfst) // null value let boundfst = Operators.fst (null,null) - Assert.AreEqual(boundfst, null) + Assert.AreEqual(null, boundfst) - [] - member this.hash() = - // int type + [] + member _.hash() = + // int type (stable between JIT versions) let inthash = Operators.hash 100 - Assert.AreEqual(inthash,100) + Assert.AreEqual(100, inthash) - // char type + // char type (stable between JIT versions) let charhash = Operators.hash '0' - Assert.AreEqual(charhash,3145776) + Assert.AreEqual(3145776, charhash) - // string value - let boundhash = Operators.hash "A" - Assert.AreEqual(boundhash, -842352673) + // string value (test disabled, each JIT and each x86 vs x64 creates a different hash here) + //let boundhash = Operators.hash "A" + //Assert.AreEqual(-842352673, boundhash) - [] - member this.id() = - // int type + [] + member _.id() = + // int type let intid = Operators.id 100 - Assert.AreEqual(intid,100) + Assert.AreEqual(100, intid) - // char type + // char type let charid = Operators.id '0' - Assert.AreEqual(charid,'0') + Assert.AreEqual('0', charid) // string value let boundid = Operators.id "A" - Assert.AreEqual(boundid, "A") - - - [] - member this.ignore() = - // value type + Assert.AreEqual("A", boundid) + + [] + member _.ignore() = + // value type let result = Operators.ignore 10 - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) // reference type let result = Operators.ignore "A" - Assert.AreEqual(result,null) - - () + Assert.AreEqual(null, result) -#if IGNORED - [] - member this.incr() = - // legit value + [] + member _.incr() = + // legit value let result = ref 10 Operators.incr result - Assert.AreEqual(!result,11) + Assert.AreEqual(11, !result) - // overflow + // Overflow. let result = ref (Operators.Checked.int System.Int32.MaxValue) - CheckThrowsOverflowException(fun() -> Operators.incr result |> ignore) - - () -#endif + Operators.incr result + Assert.AreEqual(System.Int32.MinValue, !result) - [] - member this.infinity() = + [] + member _.infinity() = let inf = Operators.infinity let result = inf > System.Double.MaxValue - Assert.IsTrue(result) + Assert.True(result) // arithmetic operation let result = infinity + 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity - 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity * 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) let result = infinity / 3.0 - Assert.AreEqual(result,infinity) - - - () - - [] - member this.infinityf() = + Assert.AreEqual(Double.PositiveInfinity, result) + + [] + member _.infinityf() = let inf = Operators.infinityf let result = inf > System.Single.MaxValue - Assert.IsTrue(result) + Assert.True(result) // arithmetic operation let result = infinityf + 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf - 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf * 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinity) + Assert.AreEqual(Single.PositiveInfinity, result) let result = infinityf / 3.0f - Assert.AreEqual(result,infinityf) - - () - - \ No newline at end of file + Assert.AreEqual(Single.PositiveInfinity, result) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index 8ac0ebfd9c6..5e30b9aada9 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -3,138 +3,214 @@ // Various tests for the: // Microsoft.FSharp.Core.Operators module -namespace SystematicUnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests.Operators open System -open SystematicUnitTests.LibraryTestFx -open NUnit.Framework -open Microsoft.FSharp.Core.Operators.Checked +open System.Text +open System.Globalization +open System.Threading + +open FSharp.Core.UnitTests.LibraryTestFx + +open Xunit + + +/// If this type compiles without error it is correct +/// Wrong if you see: FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope. +type TestFs0670Error<'T> = + | TestFs0670Error of 'T + override this.ToString() = + match this with + | TestFs0670Error x -> + // This used to raise FS0670 because the type is generic, and 'string' was inline + // See: https://github.com/dotnet/fsharp/issues/7958 + Operators.string x -[] type OperatorsModule2() = -#if IGNORED - [] - member this.int() = - // int + [] + member _.int() = + // int let result = Operators.int 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // string let result = Operators.int "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int System.Double.MaxValue |>ignore) + // Overflow + let result = Operators.int Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) - () -#endif + // Overflow + let result = Operators.int Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 1 + Assert.AreEqual(Int32.MinValue, result) -#if IGNORED - [] - member this.int16() = - // int + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + + [] + member _.int16() = + // int let result = Operators.int16 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // double let result = Operators.int16 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) // negative let result = Operators.int16 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10s, result) // zero let result = Operators.int16 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0s, result) // string let result = Operators.int16 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10s, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int16 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int32() = - // int + // Overflow + let result = Operators.int16 Double.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Double.MinValue + Assert.AreEqual(0s, result) + + let result = Operators.int16 Int64.MaxValue + Assert.AreEqual(-1s, result) + + // Overflow + let result = Operators.int16 Int64.MinValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Int16.MaxValue + 1s + Assert.AreEqual(Int16.MinValue, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + + [] + member _.int32() = + // int let result = Operators.int32 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // double let result = Operators.int32 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.int32 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10, result) // zero let result = Operators.int32 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // string let result = Operators.int32 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int32 System.Double.MaxValue |>ignore) - () -#endif - -#if IGNORED - [] - member this.int64() = - // int + // Overflow + let result = Operators.int32 Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int32 Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 5 + Assert.AreEqual(Int32.MinValue + 4, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + + [] + member _.int64() = + // int let result = Operators.int64 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // double let result = Operators.int64 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) // negative let result = Operators.int64 -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10L, result) // zero let result = Operators.int64 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0L, result) // string let result = Operators.int64 "10" - Assert.AreEqual(result,10) + Assert.AreEqual(10L, result) - // overflow - CheckThrowsOverflowException(fun() -> Operators.int64 System.Double.MaxValue |>ignore) - () -#endif - -// [] -// member this.invalidArg() = -// CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) -// -// () - - [] - member this.lock() = - // lock + // Overflow. + let result = Operators.int64 Double.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Double.MinValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 UInt64.MaxValue + Assert.AreEqual(-1L, result) + + // max and min value as literals (this breaks compilation if the lexer fails) + Assert.AreEqual(-9223372036854775808L, Int64.MinValue) + Assert.AreEqual(9223372036854775807L, Int64.MaxValue) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + + [] + member _.invalidArg() = + CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) + + + [] + member _.lock() = + // lock printfn "test8 started" let syncRoot = System.Object() let k = ref 0 @@ -142,542 +218,832 @@ type OperatorsModule2() = System.Threading.Thread.Sleep(1) !k ) } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..50])) - Assert.AreEqual((Array.sort compare arr; arr), [|1..50|]) + Assert.AreEqual([|1..50|], Array.sort arr) // without lock let syncRoot = System.Object() let k = ref 0 let comp _ = async { do incr k - do! System.Threading.Thread.AsyncSleep(10) + do! Async.Sleep (10) return !k } let arr = Async.RunSynchronously (Async.Parallel(Seq.map comp [1..100])) - Assert.AreNotEqual ((Array.sort compare arr; arr) , [|1..100|]) - - () + Assert.AreNotEqual ([|1..100|], Array.sort arr) - [] - member this.log() = + [] + member _.log() = // double let result = Operators.log 10.0 - Assert.AreEqual(result.ToString(),"2.30258509299405") + Assert.AreEqual(2.3025850929940459, result) // negative let result = Operators.log -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(Double.NaN, result) // zero let result = Operators.log 0.0 - Assert.AreEqual(result,-infinity) + Assert.AreEqual(Double.NegativeInfinity , result) - () - - [] - member this.log10() = + [] + member _.log10() = // double let result = Operators.log10 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1.0, result) // negative let result = Operators.log10 -10.0 - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) + Assert.AreEqual(System.Double.NaN, result) // zero let result = Operators.log10 0.0 - Assert.AreEqual(result,-infinity) - - () + Assert.AreEqual(Double.NegativeInfinity, result) - [] - member this.max() = + [] + member _.max() = // value type let result = Operators.max 10 8 - Assert.AreEqual(result,10) + Assert.AreEqual(10, result) // negative let result = Operators.max -10.0 -8.0 - Assert.AreEqual(result,-8.0) + Assert.AreEqual(-8.0, result) // zero let result = Operators.max 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.max "A" "ABC" - Assert.AreEqual(result,"ABC") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.max 10 System.Int32.MaxValue+1 |>ignore) - - () + Assert.AreEqual("ABC", result) - [] - member this.min() = + [] + member _.min() = // value type let result = Operators.min 10 8 - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) // negative let result = Operators.min -10.0 -8.0 - Assert.AreEqual(result,-10.0) + Assert.AreEqual(-10.0, result) // zero let result = Operators.min 0 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // reference type let result = Operators.min "A" "ABC" - Assert.AreEqual(result,"A") - - // overflow - CheckThrowsOverflowException(fun() -> Operators.min 10 System.Int32.MinValue - 1 |>ignore) - - () + Assert.AreEqual("A", result) - [] - member this.nan() = + [] + member _.nan() = // value type - let result = Operators.nan - Assert.AreEqual(result.ToString(),System.Double.NaN.ToString()) - - () + let result = Operators.nan + Assert.AreEqual(System.Double.NaN, nan) - [] - member this.nanf() = + [] + member _.nanf() = // value type - let result = Operators.nanf - Assert.AreEqual(result,System.Single.NaN) + let result = Operators.nanf + Assert.AreEqual(System.Single.NaN, result) - () - -#if IGNORED - [] - member this.nativeint() = - // int + [] + member _.nativeint() = + // int let result = Operators.nativeint 10 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // double let result = Operators.nativeint 10.0 - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // int64 let result = Operators.nativeint 10L - Assert.AreEqual(result,10n) + Assert.AreEqual(10n, result) // negative let result = Operators.nativeint -10 - Assert.AreEqual(result,-10n) + Assert.AreEqual(-10n, result) // zero let result = Operators.nativeint 0 - Assert.AreEqual(result,0n) - - // overflow - CheckThrowsOverflowException(fun() -> Operators.nativeint System.Double.MaxValue |>ignore) - - () -#endif + Assert.AreEqual(0n, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + if Info.isX86Runtime then + let result = nativeint Int32.MaxValue + 5n + Assert.AreEqual(-2147483644n, result) + else + let result = nativeint Int64.MaxValue + 5n + Assert.AreEqual(-9223372036854775804n, result) + + + // Overflow (depends on pointer size) + let result = Operators.nativeint System.Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) + + let result = Operators.nativeint System.Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) - [] - member this.not() = + // Max and min value as literals (this breaks compilation if the lexer fails). + // The following tests ensure that the proper value is parsed, which is similar to `nativeint Int64.MaxValue` etc. + if Info.isX86Runtime then + Assert.AreEqual("0", string -9223372036854775808n) // same as int32 -9223372036854775808L + Assert.AreEqual("-1", string 9223372036854775807n) // same as int32 9223372036854775807L + else + Assert.AreEqual("-9223372036854775808", string -9223372036854775808n) + Assert.AreEqual("9223372036854775807", string 9223372036854775807n) + + + [] + member _.not() = let result = Operators.not true - Assert.IsFalse(result) + Assert.False(result) let result = Operators.not false - Assert.IsTrue(result) - - () + Assert.True(result) -// [] -// member this.nullArg() = -// CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) -// -// () + [] + member _.nullArg() = + CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) + - [] - member this.pown() = - // int + [] + member _.pown() = + // int let result = Operators.pown 10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // double let result = Operators.pown 10.0 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100.0, result) // int64 let result = Operators.pown 10L 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100L, result) // decimal let result = Operators.pown 10M 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100M, result) // negative let result = Operators.pown -10 2 - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // zero let result = Operators.pown 0 2 - Assert.AreEqual(result,0) + Assert.AreEqual(0, result) // overflow let result = Operators.pown System.Double.MaxValue System.Int32.MaxValue - Assert.AreEqual(result,infinity) + Assert.AreEqual(Double.PositiveInfinity, result) CheckThrowsOverflowException(fun() -> Operators.pown System.Int32.MaxValue System.Int32.MaxValue |>ignore) - () - - [] - member this.raise() = + [] + member _.raise() = CheckThrowsArgumentException(fun()-> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore) - - () - [] - member this.ref() = + [] + member _.ref() = // value type - let result = Operators.ref 0 - let funInt (x:int) = - result := !result + x - () - Array.iter funInt [|1..10|] + let result = Operators.ref 0 + let funInt (x:int) = + result := !result + x + () + Array.iter funInt [|1..10|] Assert.AreEqual(!result,55) // reference type let result = Operators.ref "" let funStr (x : string) = - result := (!result) + x + result := (!result) + x () Array.iter funStr [|"A";"B";"C";"D"|] Assert.AreEqual(!result,"ABCD") - () - - [] - member this.reraise() = - // double + [] + member _.reraise() = + // nothing to reraise should not trigger exception try () with | _ -> Operators.reraise() - () - - [] - member this.round() = + [] + member _.round() = // double let result = Operators.round 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) + + // double + let result = Operators.round 0.6640367702678489 + Assert.AreEqual(1.0, result) + + // double + let result = Operators.round 0.6640367702678489e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6640500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6639500000e4 + Assert.AreEqual(6640.0, result) + + // double, show half-to-even + let result = Operators.round 0.6641500000e4 + Assert.AreEqual(6642.0, result) + + // double, show rounding up if anything follows '5' + let result = Operators.round 0.66405000001e4 + Assert.AreEqual(6641.0, result) // decimal let result = Operators.round 10M - Assert.AreEqual(result,10) + Assert.AreEqual(10M, result) - () - - [] - member this.sbyte() = - // int + // decimal, show half-to-even + let result = Operators.round 1233.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1234.5M + Assert.AreEqual(1234M, result) + + // decimal, show half-to-even + let result = Operators.round 1235.5M + Assert.AreEqual(1236M, result) + + // decimal, show rounding up if anything follows '5' + let result = Operators.round 1234.500000000001M + Assert.AreEqual(1235M, result) + + // decimal, round up + let result = Operators.round 1234.6M + Assert.AreEqual(1235M, result) + + [] + member _.sbyte() = + // int let result = Operators.sbyte 10 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // double let result = Operators.sbyte 10.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10y, result) // negative let result = Operators.sbyte -10 - Assert.AreEqual(result,-10) + Assert.AreEqual(-10y, result) // zero let result = Operators.sbyte 0 - Assert.AreEqual(result,0) + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Int64.MaxValue + Assert.AreEqual(-1y, result) - () - - [] - member this.sign() = - // int + // Overflow + let result = Operators.sbyte Int64.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MaxValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte (Int64.MaxValue * 8L) + Assert.AreEqual(-8y, result) // bit-complement + + // Overflow + let result = 127y + 1y + Assert.AreEqual(-128y, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) + + [] + member _.sign() = + // int let result = Operators.sign 10 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) + + // negative int + let result = Operators.sign -10 + Assert.AreEqual(-1, result) + // zero int + let result = Operators.sign 0 + Assert.AreEqual(0, result) + // double let result = Operators.sign 10.0 - Assert.AreEqual(result,1) + Assert.AreEqual(1, result) - // negative - let result = Operators.sign -10 - Assert.AreEqual(result,-1) + // double max + let result = Operators.sign Double.MaxValue + Assert.AreEqual(1, result) - // zero - let result = Operators.sign 0 - Assert.AreEqual(result,0) + // double min + let result = Operators.sign Double.MinValue + Assert.AreEqual(-1, result) - () - - [] - member this.sin() = + // double epsilon positive + let result = Operators.sign Double.Epsilon + Assert.AreEqual(1, result) + + // double epsilon negative + let result = Operators.sign (-Double.Epsilon) + Assert.AreEqual(-1, result) + + // double inf + let result = Operators.sign Double.PositiveInfinity + Assert.AreEqual(1, result) + + // double -inf + let result = Operators.sign Double.NegativeInfinity + Assert.AreEqual(-1, result) + + // float32 + let result = Operators.sign 10.0f + Assert.AreEqual(1, result) + + // float32 max + let result = Operators.sign Single.MaxValue + Assert.AreEqual(1, result) + + // float32 min + let result = Operators.sign Single.MinValue + Assert.AreEqual(-1, result) + + // float32 epsilon positive + let result = Operators.sign Single.Epsilon + Assert.AreEqual(1, result) + + // float32 epsilon negative + let result = Operators.sign (-Single.Epsilon) + Assert.AreEqual(-1, result) + + // float32 inf + let result = Operators.sign Single.PositiveInfinity + Assert.AreEqual(1, result) + + // float32 -inf + let result = Operators.sign Single.NegativeInfinity + Assert.AreEqual(-1, result) + + // double nan + CheckThrowsArithmeticException(fun () -> Operators.sign Double.NaN |> ignore) + + // float32 nan + CheckThrowsArithmeticException(fun () -> Operators.sign Single.NaN |> ignore) + + [] + member _.sin() = let result = Operators.sin 0.5 - Assert.AreEqual(result.ToString(),"0.479425538604203") + Assert.AreNearEqual(0.479425538604203, result) + + let result = Operators.sin Double.NaN + Assert.AreEqual(Double.NaN, result) - () - - [] - member this.single() = - // int - let result = Operators.single 10 - Assert.AreEqual(result,10) + let result = Operators.sin Double.PositiveInfinity + Assert.AreEqual(Double.NaN, result) + + let result = Operators.sin Double.NegativeInfinity + Assert.AreEqual(Double.NaN, result) + + [] + member _.single() = + // int + let result = Operators.float32 10 + Assert.AreEqual(10f, result) // double - let result = Operators.single 10.0 - Assert.AreEqual(result,10) + let result = Operators.float32 10.0 + Assert.AreEqual(10f, result) // string - let result = Operators.single "10" - Assert.AreEqual(result,10) - - () - - [] - member this.sinh() = + let result = Operators.float32 "10" + Assert.AreEqual(10f, result) + + [] + member _.sinh() = let result = Operators.sinh 1.0 - Assert.AreEqual(result.ToString(),"1.1752011936438") + Assert.AreNearEqual(1.1752011936438014, result) - () - - [] - member this.sizeof() = - // value type + let result = Operators.sinh 0.0 + Assert.AreNearEqual(0.0, result) + + let result = Operators.sinh Double.PositiveInfinity + Assert.AreNearEqual(Double.PositiveInfinity, result) + + let result = Operators.sinh Double.NegativeInfinity + Assert.AreNearEqual(Double.NegativeInfinity, result) + + let result = Operators.sinh Double.NaN + Assert.AreNearEqual(Double.NaN, result) + + [] + member _.sizeof() = + // value type let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(4, result) - // System.Int64 + // System.Int64 let result = Operators.sizeof - Assert.AreEqual(result,8) + Assert.AreEqual(8, result) - // reference type + // reference type should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - // null + // null should have the same size as the IntPtr let result = Operators.sizeof - Assert.AreEqual(result,4) + Assert.AreEqual(IntPtr.Size, result) - () - - [] - member this.snd() = - // value type + [] + member _.snd() = + // value type let result = Operators.snd ("ABC",100) - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) - // reference type + // reference type let result = Operators.snd (100,"ABC") - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let result = Operators.snd (100,null) - Assert.AreEqual(result,null) + Assert.AreEqual(null, result) - () - - [] - member this.sqrt() = - // double + [] + member _.sqrt() = + // double let result = Operators.sqrt 100.0 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) - () - - [] - member this.stderr() = - let result = Operators.stderr - Assert.AreEqual(result.WriteLine("go"),null) + let result = Operators.sqrt -2.0 + Assert.AreEqual(Double.NaN, result) - () - - [] - member this.stdin() = - let result = Operators.stdin - Assert.AreEqual(result.Dispose(),null) + [] + member _.stderr() = + let result = Operators.stderr + Assert.AreEqual(null, result.WriteLine("go")) - () - - [] - member this.stdout() = - let result = Operators.stdout - Assert.AreEqual(result.WriteLine("go"),null) + [] + member _.stdin() = + let result = Operators.stdin + Assert.AreEqual(null, result.Dispose()) - () - - [] - member this.string() = + [] + member _.stdout() = + let result = Operators.stdout + Assert.AreEqual(null, result.WriteLine("go")) + + [] + member _.string() = + + let result = Operators.string null + Assert.AreEqual("", result) + + let nullStr:string = null + let result = Operators.string nullStr + Assert.AreEqual("", result) + + let result = Operators.string null + Assert.AreEqual("", result) + + let result = Operators.string (null:string) + Assert.AreEqual("", result) + + let result = Operators.string (null:StringBuilder) + Assert.AreEqual("", result) + + let result = Operators.string (null:IFormattable) + Assert.AreEqual("", result) + // value type let result = Operators.string 100 - Assert.AreEqual(result,"100") + Assert.AreEqual("100", result) // reference type let result = Operators.string "ABC" - Assert.AreEqual(result,"ABC") - - // unit - CheckThrowsNullRefException(fun () -> Operators.string null |>ignore) + Assert.AreEqual("ABC", result) + + // reference type without a `ToString()` overload + let result = Operators.string (obj()) + Assert.AreEqual("System.Object", result) + + let result = Operators.string 1un + Assert.AreEqual("1", result) + + let result = Operators.string (obj()) + Assert.AreEqual("System.Object", result) + + let result = Operators.string 123.456M + Assert.AreEqual("123.456", result) + + // Following tests ensure that InvariantCulture is used if type implements IFormattable - () - - [] - member this.tan() = + // safe current culture, then switch culture + let currentCI = Thread.CurrentThread.CurrentCulture + Thread.CurrentThread.CurrentCulture <- CultureInfo.GetCultureInfo("de-DE") + + // make sure the culture switch happened, and verify + let wrongResult = 123.456M.ToString() + Assert.AreEqual("123,456", wrongResult) + + // test that culture has no influence on decimals with `string` + let correctResult = Operators.string 123.456M + Assert.AreEqual("123.456", correctResult) + + // make sure that the German culture is indeed selected for DateTime + let dttm = DateTime(2020, 6, 23) + let wrongResult = dttm.ToString() + Assert.AreEqual("23.06.2020 00:00:00", wrongResult) + + // test that culture has no influence on DateTime types when used with `string` + let correctResult = Operators.string dttm + Assert.AreEqual("06/23/2020 00:00:00", correctResult) + + // reset the culture + Thread.CurrentThread.CurrentCulture <- currentCI + + + + [] + member _.``string: don't raise FS0670 anymore``() = + // The type used here, when compiled, should not raise this error: + // "FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope." + // See: https://github.com/dotnet/fsharp/issues/7958 + let result = TestFs0670Error 32uy |> Operators.string + Assert.AreEqual("32", result) + + [] + member _.tan() = // double let result = Operators.tan 1.0 - Assert.AreEqual(result.ToString(),"1.5574077246549") + Assert.AreNearEqual(1.5574077246549023, result) - () - - [] - member this.tanh() = - // double + [] + member _.tanh() = + // The x86 runtime uses 64 bit precision, whereas the x64 runtime uses SSE instructions with 80 bit precision + // details can be found here: https://github.com/dotnet/fsharp/issues/9522 let result = Operators.tanh 0.8 - Assert.AreEqual(result,0.664036770267849) + Assert.AreNearEqual(0.66403677026784902, result) + + let result = Operators.tanh 19.06154 + Assert.AreNearEqual(1.0, result) // can be 0.99999999999999989 + + let result = tanh 0.0 + Assert.AreEqual(0.0, result) + + let result = tanh infinity + Assert.AreEqual(1.0, result) + + let result = tanh -infinity + Assert.AreEqual(-1.0, result) - () - - [] - member this.truncate() = + [] + member _.truncate() = // double let result = Operators.truncate 10.101 - Assert.AreEqual(result,10) + Assert.AreEqual(10.0, result) // decimal let result = Operators.truncate 10.101M - Assert.AreEqual(result,10M) + Assert.AreEqual(10M, result) // zero let result = Operators.truncate 0.101 - Assert.AreEqual(result,0) + Assert.AreEqual(0.0, result) - () - - [] - member this.typedefof() = + [] + member _.typedefof() = // value type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typedefof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typedefof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - - [] - member this.typeof() = + [] + member _.typeof() = // value type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.Int32") + Assert.AreEqual("System.Int32", result.FullName) // reference type let result = Operators.typeof - Assert.AreEqual(result.FullName,"System.String") + Assert.AreEqual("System.String", result.FullName) // unit let result = Operators.typeof - Assert.AreEqual(result.FullName,"Microsoft.FSharp.Core.Unit") + Assert.AreEqual("Microsoft.FSharp.Core.Unit", result.FullName) - () - - [] - member this.uint16() = - // int + [] + member _.uint16() = + // int let result = Operators.uint16 100 - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // double let result = Operators.uint16 (100.0:double) - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) // decimal let result = Operators.uint16 100M - Assert.AreEqual(result,100us) + Assert.AreEqual(100us, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) - () - - [] - member this.uint32() = + [] + member _.uint32() = // int let result = Operators.uint32 100 - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // double let result = Operators.uint32 (100.0:double) - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) // decimal let result = Operators.uint32 100M - Assert.AreEqual(result,100ul) + Assert.AreEqual(100u, result) - () - - [] - member this.uint64() = + // Overflow + let result = Operators.uint32 Double.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Double.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Int64.MaxValue + Assert.AreEqual(UInt32.MaxValue, result) + + // Overflow + let result = Operators.uint32 Int64.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = UInt32.MaxValue + 5u + Assert.AreEqual(4u, result) + + // both 'u' and 'ul' are valid numeric suffixes for UInt32 + let result = 42u + 42ul + Assert.AreEqual(84u, result) + Assert.AreEqual(84ul, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + + [] + member _.uint64() = // int let result = Operators.uint64 100 - Assert.AreEqual(result,100UL) + Assert.AreEqual(100UL, result) // double - let result = Operators.uint64 (100.0:double) - Assert.AreEqual(result,100UL) + let result = Operators.uint64 100.0 + Assert.AreEqual(100UL, result) // decimal let result = Operators.uint64 100M - Assert.AreEqual(result,100UL) - - () - - [] - member this.unativeint() = + Assert.AreEqual(100UL, result) + + // Overflow + let result = Operators.uint64 Double.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Double.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + + // Overflow + let result = Operators.uint64 Int64.MinValue + Assert.AreEqual(9223372036854775808UL, result) + + // Overflow + let result = Operators.uint64 SByte.MinValue + Assert.AreEqual(UInt64.MaxValue - 127UL, result) + + // Overflow + let result = UInt64.MaxValue + 5UL + Assert.AreEqual(4UL, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + + [] + member _.unativeint() = // int let result = Operators.unativeint 100 - Assert.AreEqual(result,100un) + let x: unativeint = 12un + Assert.AreEqual(100un, result) // double - let result = Operators.unativeint (100.0:double) - Assert.AreEqual(result,100un) - - () - - [] - member this.unbox() = + let result = Operators.unativeint 100.0 + Assert.AreEqual(100un, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Double.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + + // Overflow (depends on pointer size) + let result = Operators.unativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) + + // Overflow (depends on pointer size) + let result = 0un - 1un + if Info.isX86Runtime then + Assert.AreEqual(4294967295un, result) + else + Assert.AreEqual(18446744073709551615un, result) + + [] + member _.unbox() = // value type let oint = box 100 let result = Operators.unbox oint - Assert.AreEqual(result,100) + Assert.AreEqual(100, result) // reference type let ostr = box "ABC" let result = Operators.unbox ostr - Assert.AreEqual(result,"ABC") + Assert.AreEqual("ABC", result) - // null + // null let onull = box null let result = Operators.unbox onull - Assert.AreEqual(result,null) - - () - - [] - member this.using() = + Assert.AreEqual(null, result) + + // None == null + let onone = box None + let result = Operators.unbox onone + Assert.AreEqual(None, result) + Assert.AreEqual(null, result) + + [] + member _.using() = let sr = new System.IO.StringReader("ABCD") Assert.AreEqual(sr.ReadToEnd(),"ABCD") - let result = Operators.using sr (fun x -> x.ToString()) + let _ = Operators.using sr (fun x -> x.ToString()) CheckThrowsObjectDisposedException(fun () -> sr.ReadToEnd() |> ignore) - - () \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs new file mode 100644 index 00000000000..bcd16f54e27 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs @@ -0,0 +1,306 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Various tests for the Checked module + +namespace FSharp.Core.UnitTests.Operators + +open System +open FSharp.Core.UnitTests.LibraryTestFx +open Xunit +open Microsoft.FSharp.Core.Operators.Checked + +type OperatorsModuleChecked() = + + [] + member _.Checkedbyte() = + // int type + let intByte = Operators.Checked.byte 100 + Assert.AreEqual(100uy, intByte) + + // char type + let charByte = Operators.Checked.byte '0' + Assert.AreEqual(48uy, charByte) + + // boundary value + let boundByte = Operators.Checked.byte 255.0 + Assert.AreEqual(255uy, boundByte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 0uy - 1uy |> ignore) + + [] + member _.Checkedchar() = + + // number + let numberChar = Operators.Checked.char 48 + Assert.AreEqual('0', numberChar) + + // letter + let letterChar = Operators.Checked.char 65 + Assert.AreEqual('A', letterChar) + + // boundary value + let boundchar = Operators.Checked.char 126 + Assert.AreEqual('~', boundchar) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) + + + [] + member _.CheckedInt() = + + // char + let charInt = Operators.Checked.int '0' + Assert.AreEqual(48, charInt) + + // float + let floatInt = Operators.Checked.int 10.0 + Assert.AreEqual(10, floatInt) + + // boundary value + let boundInt = Operators.Checked.int 32767.0 + Assert.AreEqual(32767, boundInt) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt16() = + + // char + let charInt16 = Operators.Checked.int16 '0' + Assert.AreEqual(48s, charInt16) + + // float + let floatInt16 = Operators.Checked.int16 10.0 + Assert.AreEqual(10s, floatInt16) + + // boundary value + let boundInt16 = Operators.Checked.int16 32767.0 + Assert.AreEqual(32767s, boundInt16) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MinValue - 1s |> ignore) + + [] + member _.CheckedInt32() = + + // char + let charInt32 = Operators.Checked.int32 '0' + Assert.AreEqual(48, charInt32) + + // float + let floatInt32 = Operators.Checked.int32 10.0 + Assert.AreEqual(10, floatInt32) + + // boundary value + let boundInt32 = Operators.Checked.int32 2147483647.0 + Assert.AreEqual(2147483647, boundInt32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + member _.CheckedInt64() = + + // char + let charInt64 = Operators.Checked.int64 '0' + Assert.AreEqual(48L, charInt64) + + // float + let floatInt64 = Operators.Checked.int64 10.0 + Assert.AreEqual(10L, floatInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 9223372036854775807I + let _ = 9223372036854775807L + Assert.AreEqual(9223372036854775807L, boundInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 -9223372036854775808I + let _ = -9223372036854775808L + Assert.AreEqual(-9223372036854775808L, boundInt64) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MinValue - 1L |> ignore) + + [] + member _.CheckedNativeint() = + + // char + let charnativeint = Operators.Checked.nativeint '0' + Assert.AreEqual(48n, charnativeint) + + // float + let floatnativeint = Operators.Checked.nativeint 10.0 + Assert.AreEqual(10n, floatnativeint) + + // boundary value + let boundnativeint = Operators.Checked.nativeint 32767.0 + Assert.AreEqual(32767n, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun() -> + if Info.isX86Runtime then + Operators.Checked.nativeint 2147483648.0 |> ignore + else + Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + + + [] + member _.Checkedsbyte() = + + // char + let charsbyte = Operators.Checked.sbyte '0' + Assert.AreEqual(48y, charsbyte) + + // float + let floatsbyte = Operators.Checked.sbyte -10.0 + Assert.AreEqual(-10y, floatsbyte) + + // boundary value + let boundsbyte = Operators.Checked.sbyte -127.0 + Assert.AreEqual(-127y, boundsbyte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MinValue - 1y |> ignore) + + [] + member _.Checkeduint16() = + + // char + let charuint16 = Operators.Checked.uint16 '0' + Assert.AreEqual(48us, charuint16) + + // float + let floatuint16 = Operators.Checked.uint16 10.0 + Assert.AreEqual(10us, floatuint16) + + // boundary value + let bounduint16 = Operators.Checked.uint16 65535.0 + Assert.AreEqual(65535us, bounduint16) + + CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MinValue - 1us |> ignore) + + [] + member _.Checkeduint32() = + + // char + let charuint32 = Operators.Checked.uint32 '0' + Assert.AreEqual(48u, charuint32) + + // float + let floatuint32 = Operators.Checked.uint32 10.0 + Assert.AreEqual(10u, floatuint32) + + // boundary value + let bounduint32 = Operators.Checked.uint32 429496729.0 + Assert.AreEqual(429496729u, bounduint32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MinValue - 1u |> ignore) + + [] + member _.Checkeduint64() = + + // char + let charuint64 = Operators.Checked.uint64 '0' + Assert.AreEqual(48UL, charuint64) + + // float + let floatuint64 = Operators.Checked.uint64 10.0 + Assert.AreEqual(10UL, floatuint64) + + // boundary value + let bounduint64 = Operators.Checked.uint64 429496729.0 + Assert.AreEqual(429496729UL, bounduint64) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MinValue - 1UL |> ignore) + + [] + member _.Checkedunativeint() = + + // char + let charunativeint = Operators.Checked.unativeint '0' + Assert.AreEqual(48un, charunativeint) + + // float + let floatunativeint = Operators.Checked.unativeint 10.0 + Assert.AreEqual(10un, floatunativeint) + + // boundary value (dependent on pointer size) + if Info.isX86Runtime then + let boundunativeint = Operators.Checked.unativeint 4294967295.0 + Assert.AreEqual(4294967295un, boundunativeint) + else + let boundnativeint = Operators.Checked.unativeint 1.84467440737095505E+19 // 64 bit max value cannot be expressed exactly as double + Assert.AreEqual(18446744073709549568un, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun () -> + if Info.isX86Runtime then + Operators.Checked.unativeint (float UInt32.MaxValue + 1.0) |> ignore + else + Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore + ) + + diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs index 9d92d474cff..81429996a05 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs @@ -3,20 +3,25 @@ // Various tests for the: // Microsoft.FSharp.Core.LanguagePrimitives module -namespace FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core +namespace FSharp.Core.UnitTests open System open System.Numerics open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit [] type m -[] type LanguagePrimitivesModule() = - [] + [] + member _.CastingUint () = + let expected = 12u + let actual = uint 12 + Assert.AreEqual(expected, actual) + + [] member this.CastingUnits() = let f = 2.5 Assert.AreEqual(f, f |> LanguagePrimitives.FloatWithMeasure |> float) @@ -38,26 +43,58 @@ type LanguagePrimitivesModule() = let y = 2y Assert.AreEqual(y, y |> LanguagePrimitives.SByteWithMeasure |> sbyte) + + let n = 2n + Assert.AreEqual(n, n |> LanguagePrimitives.IntPtrWithMeasure |> nativeint) + + let i = 2u + Assert.AreEqual(i, i |> LanguagePrimitives.UInt32WithMeasure |> uint) + + let l = 2UL + Assert.AreEqual(l, l |> LanguagePrimitives.UInt64WithMeasure |> uint64) + + let s = 2us + Assert.AreEqual(s, s |> LanguagePrimitives.UInt16WithMeasure |> uint16) + + let uy = 2uy + Assert.AreEqual(uy, uy |> LanguagePrimitives.ByteWithMeasure |> byte) - [] + let n = 2un + Assert.AreEqual(n, n |> LanguagePrimitives.UIntPtrWithMeasure |> unativeint) + + [] + member _.MeasurableAliases() = + let f (x: int) y: int32 = x + y // should be: `int -> int -> int32` + let g (x: int) (y:int32) = x * y // should be: `int -> int32 -> int` + let h (x: int) y = x * y + let i (x: int32) y = x * y + + let tres = 3 + let ocho : int32 = 8 + + Assert.Equal(ocho, f tres 5) + Assert.Equal(64, g ocho ocho) + Assert.Equal(h ocho tres, i tres ocho) + + [] member this.MaxMinNan() = - Assert.IsTrue(Double.IsNaN(max nan 1.0)) - Assert.IsTrue(Double.IsNaN(max 1.0 nan)) - Assert.IsTrue(Double.IsNaN(max nan nan)) + Assert.True(Double.IsNaN(max nan 1.0)) + Assert.True(Double.IsNaN(max 1.0 nan)) + Assert.True(Double.IsNaN(max nan nan)) - Assert.IsTrue(Single.IsNaN(max Single.NaN 1.0f)) - Assert.IsTrue(Single.IsNaN(max 1.0f Single.NaN)) - Assert.IsTrue(Single.IsNaN(max Single.NaN Single.NaN)) + Assert.True(Single.IsNaN(max Single.NaN 1.0f)) + Assert.True(Single.IsNaN(max 1.0f Single.NaN)) + Assert.True(Single.IsNaN(max Single.NaN Single.NaN)) - Assert.IsTrue(Double.IsNaN(min nan 1.0)) - Assert.IsTrue(Double.IsNaN(min 1.0 nan)) - Assert.IsTrue(Double.IsNaN(min nan nan)) + Assert.True(Double.IsNaN(min nan 1.0)) + Assert.True(Double.IsNaN(min 1.0 nan)) + Assert.True(Double.IsNaN(min nan nan)) - Assert.IsTrue(Single.IsNaN(min Single.NaN 1.0f)) - Assert.IsTrue(Single.IsNaN(min 1.0f Single.NaN)) - Assert.IsTrue(Single.IsNaN(min Single.NaN Single.NaN)) + Assert.True(Single.IsNaN(min Single.NaN 1.0f)) + Assert.True(Single.IsNaN(min 1.0f Single.NaN)) + Assert.True(Single.IsNaN(min Single.NaN Single.NaN)) - [] + [] member this.DivideByInt() = // float32 let resultFloat32 = LanguagePrimitives.DivideByInt 3.0f 3 @@ -71,27 +108,27 @@ type LanguagePrimitivesModule() = let resultDecimal = LanguagePrimitives.DivideByInt 3.9M 3 Assert.AreEqual(1.3M, resultDecimal) - [] + [] member this.EnumOfValue() = let monday = System.DayOfWeek.Monday let result = LanguagePrimitives.EnumOfValue(1) Assert.AreEqual(monday, result) - [] + [] member this.EnumToValue() = let monday = System.DayOfWeek.Monday let result = LanguagePrimitives.EnumToValue monday Assert.AreEqual(1, result) - [] + [] member this.GuidToString() = let s = "F99D95E0-2A5E-47c4-9B92-6661D65AE6B3" let guid = new Guid(s) Assert.AreEqual((string guid).ToLowerInvariant(), s.ToLowerInvariant()) - [] + [] member this.GenericComparison() = // value type let resultValue = LanguagePrimitives.GenericComparison 1 1 @@ -109,7 +146,7 @@ type LanguagePrimitivesModule() = #if NETSTANDARD1_6 || NETCOREAPP // TODO named #define ? #else - [] + [] member this.GenericComparisonBiModal() = // value type let resultValue = LanguagePrimitives.GenericComparisonWithComparer System.Collections.Comparer.Default 100 1 @@ -143,90 +180,90 @@ type LanguagePrimitivesModule() = #endif - [] + [] member this.GenericEquality() = // value type let resultValue = LanguagePrimitives.GenericEquality 1 1 - Assert.IsTrue(resultValue) + Assert.True(resultValue) let resultValue = LanguagePrimitives.GenericEquality 1 2 - Assert.IsFalse(resultValue) + Assert.False(resultValue) // reference type let resultRef = LanguagePrimitives.GenericEquality "ABC" "ABC" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericEquality "ABC" "ABCDE" - Assert.IsFalse(resultRef) + Assert.False(resultRef) // null reference let resultNul = LanguagePrimitives.GenericEquality null null - Assert.IsTrue(resultNul) + Assert.True(resultNul) let resultNul = LanguagePrimitives.GenericEquality "ABC" null - Assert.IsFalse(resultNul) + Assert.False(resultNul) - [] + [] member this.GenericGreaterOrEqual() = // value type let resultValue = LanguagePrimitives.GenericGreaterOrEqual 1 1 - Assert.IsTrue(resultValue) + Assert.True(resultValue) let resultValue = LanguagePrimitives.GenericGreaterOrEqual 2 1 - Assert.IsTrue(resultValue) + Assert.True(resultValue) let resultValue = LanguagePrimitives.GenericGreaterOrEqual 1 2 - Assert.IsFalse(resultValue) + Assert.False(resultValue) // reference type let resultRef = LanguagePrimitives.GenericGreaterOrEqual "abcde" "abc" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericGreaterOrEqual "ABCDE" "ABCDE" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericGreaterOrEqual "ABC" "ABCDE" - Assert.IsFalse(resultRef) + Assert.False(resultRef) // null reference let resultNul = LanguagePrimitives.GenericGreaterOrEqual null null - Assert.IsTrue(resultNul) + Assert.True(resultNul) let resultNul = LanguagePrimitives.GenericGreaterOrEqual null "ABCDE" - Assert.IsFalse(resultNul) + Assert.False(resultNul) - [] + [] member this.GenericGreaterThan() = // value type let resultValue = LanguagePrimitives.GenericGreaterThan 1 1 - Assert.IsFalse(resultValue) + Assert.False(resultValue) let resultValue = LanguagePrimitives.GenericGreaterThan 2 1 - Assert.IsTrue(resultValue) + Assert.True(resultValue) // reference type let resultRef = LanguagePrimitives.GenericGreaterThan "ABC" "ABCDE" - Assert.IsFalse(resultRef) + Assert.False(resultRef) let resultRef = LanguagePrimitives.GenericGreaterThan "ABCDE" "ABCDE" - Assert.IsFalse(resultRef) + Assert.False(resultRef) let resultRef = LanguagePrimitives.GenericGreaterThan "abc" "a" - Assert.IsTrue(resultRef) + Assert.True(resultRef) // null reference let resultNul = LanguagePrimitives.GenericGreaterThan null null - Assert.IsFalse(resultNul) + Assert.False(resultNul) let resultNul = LanguagePrimitives.GenericGreaterThan null "ABC" - Assert.IsFalse(resultNul) + Assert.False(resultNul) let resultNul = LanguagePrimitives.GenericGreaterThan "ABC" null - Assert.IsTrue(resultNul) + Assert.True(resultNul) - [] + [] member this.GenericHash() = // value type let resultValue = LanguagePrimitives.GenericHash 1 @@ -246,72 +283,72 @@ type LanguagePrimitivesModule() = Assert.AreEqual(0, resultNul) - [] + [] member this.GenericLessOrEqual() = // value type let resultValue = LanguagePrimitives.GenericLessOrEqual 1 1 - Assert.IsTrue(resultValue) + Assert.True(resultValue) let resultValue = LanguagePrimitives.GenericLessOrEqual 1 2 - Assert.IsTrue(resultValue) + Assert.True(resultValue) let resultValue = LanguagePrimitives.GenericLessOrEqual -1 0 - Assert.IsTrue(resultValue) + Assert.True(resultValue) // reference type let resultRef = LanguagePrimitives.GenericLessOrEqual "ABC" "ABCDE" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericLessOrEqual "ABCDE" "ABCDE" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericLessOrEqual "abcde" "abc" - Assert.IsFalse(resultRef) + Assert.False(resultRef) // null reference let resultNul = LanguagePrimitives.GenericLessOrEqual null null - Assert.IsTrue(resultNul) + Assert.True(resultNul) let resultNul = LanguagePrimitives.GenericLessOrEqual null "abc" - Assert.IsTrue(resultNul) + Assert.True(resultNul) let resultNul = LanguagePrimitives.GenericLessOrEqual "abc" null - Assert.IsFalse(resultNul) + Assert.False(resultNul) - [] + [] member this.GenericLessThan() = // value type let resultValue = LanguagePrimitives.GenericLessThan 1 1 - Assert.IsFalse(resultValue) + Assert.False(resultValue) let resultValue = LanguagePrimitives.GenericLessThan -2 -4 - Assert.IsFalse(resultValue) + Assert.False(resultValue) let resultValue = LanguagePrimitives.GenericLessThan 1 2 - Assert.IsTrue(resultValue) + Assert.True(resultValue) // reference type let resultRef = LanguagePrimitives.GenericLessThan "ABC" "ABCDE" - Assert.IsTrue(resultRef) + Assert.True(resultRef) let resultRef = LanguagePrimitives.GenericLessThan "ABC" "ABC" - Assert.IsFalse(resultRef) + Assert.False(resultRef) let resultRef = LanguagePrimitives.GenericLessThan "abc" "a" - Assert.IsFalse(resultRef) + Assert.False(resultRef) // null reference let resultNul = LanguagePrimitives.GenericLessThan null "abc" - Assert.IsTrue(resultNul) + Assert.True(resultNul) let resultNul = LanguagePrimitives.GenericLessThan "aa" null - Assert.IsFalse(resultNul) + Assert.False(resultNul) let resultNul = LanguagePrimitives.GenericLessThan null null - Assert.IsFalse(resultNul) + Assert.False(resultNul) - [] + [] member this.GenericMaximum() = // value type let resultValue = LanguagePrimitives.GenericMaximum 8 9 @@ -330,7 +367,7 @@ type LanguagePrimitivesModule() = // null reference let resultNul = LanguagePrimitives.GenericMaximum null null - Assert.IsNull(resultNul) + Assert.Null(resultNul) let resultNul = LanguagePrimitives.GenericMaximum null "ABCDE" Assert.AreEqual("ABCDE", resultNul) @@ -338,7 +375,7 @@ type LanguagePrimitivesModule() = let resultNul = LanguagePrimitives.GenericMaximum "ABCDE" null Assert.AreEqual("ABCDE", resultNul) - [] + [] member this.GenericMinimum() = // value type let resultValue = LanguagePrimitives.GenericMinimum 8 9 @@ -356,15 +393,15 @@ type LanguagePrimitivesModule() = // null reference let resultNul = LanguagePrimitives.GenericMinimum null null - Assert.IsNull(resultNul) + Assert.Null(resultNul) let resultNul = LanguagePrimitives.GenericMinimum null "ABC" - Assert.IsNull(resultNul) + Assert.Null(resultNul) let resultNul = LanguagePrimitives.GenericMinimum "ABC" null - Assert.IsNull(resultNul) + Assert.Null(resultNul) - [] + [] member this.GenericOne() = // int type let resultValue = LanguagePrimitives.GenericOne @@ -378,7 +415,7 @@ type LanguagePrimitivesModule() = let resultValue = LanguagePrimitives.GenericOne Assert.AreEqual(1I, resultValue) - [] + [] member this.GenericZero() = // int type let resultValue = LanguagePrimitives.GenericZero @@ -392,7 +429,7 @@ type LanguagePrimitivesModule() = let resultValue = LanguagePrimitives.GenericZero Assert.AreEqual(0I, resultValue) - [] + [] member this.ParseInt32() = let resultValue = LanguagePrimitives.ParseInt32 "100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -411,7 +448,7 @@ type LanguagePrimitivesModule() = CheckThrowsArgumentNullException(fun () -> LanguagePrimitives.ParseInt32 null |> ignore) - [] + [] member this.ParseInt64() = let resultValue = LanguagePrimitives.ParseInt64 "100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -430,7 +467,7 @@ type LanguagePrimitivesModule() = CheckThrowsArgumentNullException(fun () -> LanguagePrimitives.ParseInt64 null |> ignore) - [] + [] member this.ParseBinaryInt64() = let resultValue = LanguagePrimitives.ParseInt64 "0b1100100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -447,7 +484,7 @@ type LanguagePrimitivesModule() = CheckThrowsOverflowException(fun () -> LanguagePrimitives.ParseInt64 "0b10000000000000000000000000000000000000000000000000000000000000000" |> ignore) - [] + [] member this.ParseOctalInt64() = let resultValue = LanguagePrimitives.ParseInt64 "0o144" Assert.AreEqual(typeof, resultValue.GetType()) @@ -464,7 +501,7 @@ type LanguagePrimitivesModule() = CheckThrowsOverflowException(fun () -> LanguagePrimitives.ParseInt64 "0o2000000000000000000000" |> ignore) - [] + [] member this.ParseUInt32() = let resultValue = LanguagePrimitives.ParseUInt32 "100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -474,7 +511,7 @@ type LanguagePrimitivesModule() = CheckThrowsArgumentNullException(fun () -> LanguagePrimitives.ParseUInt32 null |> ignore) - [] + [] member this.ParseUInt64() = let resultValue = LanguagePrimitives.ParseUInt64 "100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -485,7 +522,7 @@ type LanguagePrimitivesModule() = CheckThrowsArgumentNullException(fun () -> LanguagePrimitives.ParseUInt64 null |> ignore) - [] + [] member this.ParseBinaryUInt64() = let resultValue = LanguagePrimitives.ParseUInt64 "0b1100100" Assert.AreEqual(typeof, resultValue.GetType()) @@ -494,7 +531,7 @@ type LanguagePrimitivesModule() = CheckThrowsFormatException(fun () -> LanguagePrimitives.ParseUInt64 "-0b1" |> ignore) CheckThrowsOverflowException(fun () -> LanguagePrimitives.ParseUInt64 "0b10000000000000000000000000000000000000000000000000000000000000000" |> ignore) - [] + [] member this.ParseOctalUInt64() = let resultValue = LanguagePrimitives.ParseUInt64 "0o144" Assert.AreEqual(typeof, resultValue.GetType()) @@ -503,7 +540,7 @@ type LanguagePrimitivesModule() = CheckThrowsFormatException(fun () -> LanguagePrimitives.ParseUInt64 "-0o1" |> ignore) CheckThrowsOverflowException(fun () -> LanguagePrimitives.ParseUInt64 "0o2000000000000000000000" |> ignore) - [] + [] member this.ParseStringViaConversionOps() = let s : string = null CheckThrowsArgumentNullException2 "sbyte" (fun () -> sbyte s |> ignore) @@ -520,80 +557,80 @@ type LanguagePrimitivesModule() = CheckThrowsArgumentNullException2 "decimal" (fun () -> decimal s |> ignore) CheckThrowsArgumentNullException2 "char" (fun () -> char s |> ignore) - [] + [] member this.PhysicalEquality() = // revordtype let ref1 = ref 8 let ref2 = ref 8 let resultValue = LanguagePrimitives.PhysicalEquality ref1 ref2 - Assert.IsFalse(resultValue) - Assert.IsTrue(LanguagePrimitives.PhysicalEquality ref1 ref1) - Assert.IsTrue(LanguagePrimitives.PhysicalEquality ref2 ref2) + Assert.False(resultValue) + Assert.True(LanguagePrimitives.PhysicalEquality ref1 ref1) + Assert.True(LanguagePrimitives.PhysicalEquality ref2 ref2) // reference type let resultRef0 = LanguagePrimitives.PhysicalEquality "ABC" "ABC" - Assert.IsTrue(resultRef0) + Assert.True(resultRef0) let resultRef1 = LanguagePrimitives.PhysicalEquality "ABC" "DEF" - Assert.IsFalse(resultRef1) + Assert.False(resultRef1) // object type let resultRef2 = LanguagePrimitives.PhysicalEquality (obj()) (obj()) - Assert.IsFalse(resultRef2) + Assert.False(resultRef2) // object type let o = obj() let resultRef3 = LanguagePrimitives.PhysicalEquality o o - Assert.IsTrue(resultRef3) + Assert.True(resultRef3) // System.ValueType type let resultRef4 = LanguagePrimitives.PhysicalEquality (1 :> System.ValueType) (1 :> System.ValueType) - Assert.IsFalse(resultRef4) + Assert.False(resultRef4) // System.ValueType type let resultRef5 = LanguagePrimitives.PhysicalEquality (1 :> System.ValueType) (2 :> System.ValueType) - Assert.IsFalse(resultRef5) + Assert.False(resultRef5) // null reference let resultNul = LanguagePrimitives.PhysicalEquality null null - Assert.IsTrue(resultNul) + Assert.True(resultNul) + -[] type HashCompareModule() = // this module is internal/obsolete, but contains code reachable from many public APIs member inline this.ComparisonsFor< ^T when ^T : comparison>(x : ^T, y : ^T) = - Assert.IsTrue( x < y ) - Assert.IsTrue( y > x ) - Assert.IsTrue( (x = x) ) - Assert.IsFalse( y < x ) - Assert.IsFalse( x > y ) - Assert.IsFalse( (x = y) ) - - [] + Assert.True( x < y ) + Assert.True( y > x ) + Assert.True( (x = x) ) + Assert.False( y < x ) + Assert.False( x > y ) + Assert.False( (x = y) ) + + [] member this.ComparisonsForArraysOfNativeInts() = this.ComparisonsFor( [|0n|], [|1n|] ) this.ComparisonsFor( [|0un|], [|1un|] ) - [] + [] member this.ComparisonsForArraysOfFloatingPoints() = this.ComparisonsFor( [|0.0|], [|1.0|] ) this.ComparisonsFor( [|0.0f|], [|1.0f|] ) - Assert.IsFalse( [| System.Double.NaN |] = [| System.Double.NaN |] ) - Assert.IsFalse( [| System.Single.NaN |] = [| System.Single.NaN |] ) - Assert.IsFalse( [| System.Double.NaN |] < [| System.Double.NaN |] ) - Assert.IsFalse( [| System.Single.NaN |] < [| System.Single.NaN |] ) + Assert.False( [| System.Double.NaN |] = [| System.Double.NaN |] ) + Assert.False( [| System.Single.NaN |] = [| System.Single.NaN |] ) + Assert.False( [| System.Double.NaN |] < [| System.Double.NaN |] ) + Assert.False( [| System.Single.NaN |] < [| System.Single.NaN |] ) - [] + [] member this.ComparisonsForOtherArrays() = this.ComparisonsFor( [|0uy|], [|1uy|] ) this.ComparisonsFor( [|'a'|], [|'b'|] ) this.ComparisonsFor( [|0UL|], [|1UL|] ) - [] + [] member this.ComparisonsForStrings() = this.ComparisonsFor( "bar", "foo" ) this.ComparisonsFor( [| "bar" |], [| "foo" |] ) - [] + [] member this.ComparisonsForMultidimensionalIntArrays() = let N = 10 let M = 100 @@ -612,7 +649,7 @@ type HashCompareModule() = // this module is internal/obsolete, but contains cod y.[2,2,2] <- Z this.ComparisonsFor( x, y ) - [] + [] member this.ComparisonsForMultidimensionalInt64Arrays() = let N = 10L let M = 100L @@ -631,17 +668,17 @@ type HashCompareModule() = // this module is internal/obsolete, but contains cod y.[2,2,2] <- Z this.ComparisonsFor( x, y ) - [] + [] member this.MonsterTuple() = let mt = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' let mt2 = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' Assert.AreEqual(mt,mt2) - -[] + + type UnitType() = // interface - [] + [] member this.IComparable() = let u:Unit = () // value type @@ -649,42 +686,41 @@ type UnitType() = CheckThrowsNullRefException(fun() ->ic.CompareTo(3) |>ignore) // Base class methods - [] + [] member this.ObjectGetHashCode() = let u:Unit = () CheckThrowsNullRefException(fun() ->u.GetHashCode() |>ignore) - [] + [] member this.ObjectEquals() = let u:Unit = () CheckThrowsNullRefException(fun() ->u.Equals(null) |>ignore) #if NETSTANDARD1_6 || NETCOREAPP // TODO named #define ? -#else -[] +#else type SourceConstructFlagsEnum() = - [] + [] member this.Getvalue() = let names = [| "None";"SumType";"RecordType";"ObjectType";"Field"; "Exception";"Closure";"Module";"UnionCase";"Value"; "KindMask";"NonPublicRepresentation" |] Assert.AreEqual(names, SourceConstructFlags.GetNames(typeof)) - -[] + + type CompilationRepresentationFlagsEnum() = - [] + [] member this.Getvalue() = let names = [| "None";"Static";"Instance";"ModuleSuffix";"UseNullAsTrueValue";"Event" |] Assert.AreEqual(names, SourceConstructFlags.GetNames(typeof)) #endif -[] + type MiscStuff() = - [] + [] member this.ListToString() = Assert.AreEqual("[]", [].ToString()) Assert.AreEqual("[1]", [1].ToString()) @@ -692,44 +728,42 @@ type MiscStuff() = Assert.AreEqual("[1; 2; 3]", [1;2;3].ToString()) Assert.AreEqual("[1; 2; 3; ... ]", [1;2;3;4].ToString()) - [] + [] member this.Refs() = let x = ref 0 incr x incr x decr x - Assert.IsTrue( 1 = !x ) - - + Assert.True( 1 = !x ) + -[] type UnboxAndOptionStuff() = - [] + [] member this.TryUnbox() = - Assert.IsTrue( tryUnbox (box ([] : int list)) = Some ([]: int list)) - Assert.IsTrue( tryUnbox (box ([1] : int list)) = Some ([1]: int list)) - Assert.IsTrue( tryUnbox (box ([] : string list)) = (None : int list option)) // Option uses 'null' as representation - Assert.IsTrue( tryUnbox (box ([] : string list)) = None) - Assert.IsTrue( tryUnbox (box (None : int option)) = Some (None: int option)) - Assert.IsTrue( tryUnbox (box (None : string option)) = Some (None: string option)) - Assert.IsTrue( tryUnbox (box (None : string option)) = Some (None: int option)) // Option uses 'null' as representation - Assert.IsTrue( tryUnbox (box "") = Some "") - Assert.IsTrue( tryUnbox (box null) = Some None) // Option uses 'null' as representation - Assert.IsTrue( tryUnbox (box null) = None) - Assert.IsTrue( tryUnbox (box null) = None) - Assert.IsTrue( tryUnbox (box "1") = None) - Assert.IsTrue( tryUnbox (box 1) = Some 1) - Assert.IsTrue( tryUnbox (box "") = Some "") - Assert.IsTrue( tryUnbox (box 1) = None) - - [] + Assert.True( tryUnbox (box ([] : int list)) = Some ([]: int list)) + Assert.True( tryUnbox (box ([1] : int list)) = Some ([1]: int list)) + Assert.True( tryUnbox (box ([] : string list)) = (None : int list option)) // Option uses 'null' as representation + Assert.True( tryUnbox (box ([] : string list)) = None) + Assert.True( tryUnbox (box (None : int option)) = Some (None: int option)) + Assert.True( tryUnbox (box (None : string option)) = Some (None: string option)) + Assert.True( tryUnbox (box (None : string option)) = Some (None: int option)) // Option uses 'null' as representation + Assert.True( tryUnbox (box "") = Some "") + Assert.True( tryUnbox (box null) = Some None) // Option uses 'null' as representation + Assert.True( tryUnbox (box null) = None) + Assert.True( tryUnbox (box null) = None) + Assert.True( tryUnbox (box "1") = None) + Assert.True( tryUnbox (box 1) = Some 1) + Assert.True( tryUnbox (box "") = Some "") + Assert.True( tryUnbox (box 1) = None) + + [] member this.IsNull() = - Assert.IsTrue( isNull (null : string)) - Assert.IsTrue( isNull (null : string[])) - Assert.IsTrue( isNull (null : int[])) - Assert.IsTrue( not (isNull [| |])) - Assert.IsTrue( not (isNull "")) - Assert.IsTrue( not (isNull "1")) + Assert.True( isNull (null : string)) + Assert.True( isNull (null : string[])) + Assert.True( isNull (null : int[])) + Assert.True( not (isNull [| |])) + Assert.True( not (isNull "")) + Assert.True( not (isNull "1")) module internal RangeTestsHelpers = @@ -849,24 +883,24 @@ module internal RangeTestsHelpers = Assert.AreEqual ([min0 .. max2 .. max0], [min0; min0 + max2]) Assert.AreEqual ([min0 .. max3 .. max0], [min0; min0 + max3]) -[] + type RangeTests() = - [] member __.``Range.SByte`` () = RangeTestsHelpers.signed System.SByte.MinValue System.SByte.MaxValue - [] member __.``Range.Byte`` () = RangeTestsHelpers.unsigned System.Byte.MinValue System.Byte.MaxValue - [] member __.``Range.Int16`` () = RangeTestsHelpers.signed System.Int16.MinValue System.Int16.MaxValue - [] member __.``Range.UInt16`` () = RangeTestsHelpers.unsigned System.UInt16.MinValue System.UInt16.MaxValue - [] member __.``Range.Int32`` () = RangeTestsHelpers.signed System.Int32.MinValue System.Int32.MaxValue - [] member __.``Range.UInt32`` () = RangeTestsHelpers.unsigned System.UInt32.MinValue System.UInt32.MaxValue - [] member __.``Range.Int64`` () = RangeTestsHelpers.signed System.Int64.MinValue System.Int64.MaxValue - [] member __.``Range.UInt64`` () = RangeTestsHelpers.unsigned System.UInt64.MinValue System.UInt64.MaxValue - - [] - member __.``Range.IntPtr`` () = + [] member _.``Range.SByte`` () = RangeTestsHelpers.signed System.SByte.MinValue System.SByte.MaxValue + [] member _.``Range.Byte`` () = RangeTestsHelpers.unsigned System.Byte.MinValue System.Byte.MaxValue + [] member _.``Range.Int16`` () = RangeTestsHelpers.signed System.Int16.MinValue System.Int16.MaxValue + [] member _.``Range.UInt16`` () = RangeTestsHelpers.unsigned System.UInt16.MinValue System.UInt16.MaxValue + [] member _.``Range.Int32`` () = RangeTestsHelpers.signed System.Int32.MinValue System.Int32.MaxValue + [] member _.``Range.UInt32`` () = RangeTestsHelpers.unsigned System.UInt32.MinValue System.UInt32.MaxValue + [] member _.``Range.Int64`` () = RangeTestsHelpers.signed System.Int64.MinValue System.Int64.MaxValue + [] member _.``Range.UInt64`` () = RangeTestsHelpers.unsigned System.UInt64.MinValue System.UInt64.MaxValue + + [] + member _.``Range.IntPtr`` () = if System.IntPtr.Size >= 4 then RangeTestsHelpers.signed (System.IntPtr System.Int32.MinValue) (System.IntPtr System.Int32.MaxValue) if System.IntPtr.Size >= 8 then RangeTestsHelpers.signed (System.IntPtr System.Int64.MinValue) (System.IntPtr System.Int64.MaxValue) - [] - member __.``Range.UIntPtr`` () = + [] + member _.``Range.UIntPtr`` () = if System.UIntPtr.Size >= 4 then RangeTestsHelpers.unsigned (System.UIntPtr System.UInt32.MinValue) (System.UIntPtr System.UInt32.MaxValue) if System.UIntPtr.Size >= 8 then RangeTestsHelpers.unsigned (System.UIntPtr System.UInt64.MinValue) (System.UIntPtr System.UInt64.MaxValue) @@ -874,13 +908,12 @@ type RangeTests() = open NonStructuralComparison -[] type NonStructuralComparisonTests() = - [] - member __.CompareFloat32() = // https://github.com/Microsoft/visualfsharp/pull/4493 + [] + member _.CompareFloat32() = // https://github.com/Microsoft/visualfsharp/pull/4493 let x = 32 |> float32 let y = 32 |> float32 let comparison = compare x y - Assert.AreEqual(0, comparison) \ No newline at end of file + Assert.AreEqual(0, comparison) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/RecordTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/RecordTypes.fs index e131a9274dd..c186eaf675d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/RecordTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/RecordTypes.fs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core.RecordTypes +module FSharp.Core.UnitTests.RecordTypes #nowarn "9" #nowarn "44" // deprecation of some APIs on CoreCLR @@ -7,7 +7,7 @@ module FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Core.RecordTypes open System open System.Reflection open System.Runtime.InteropServices -open NUnit.Framework +open Xunit open FsCheck open FsCheck.PropOperators @@ -17,7 +17,7 @@ type Record = } -let [] ``can compare records`` () = +let [] ``can compare records`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> i1 <> i2 ==> @@ -38,11 +38,11 @@ let private hasAttribute<'T,'Attr>() = typeof<'T>.GetTypeInfo().GetCustomAttributes() |> Seq.exists (fun x -> x.GetType() = typeof<'Attr>) -let [] ``struct records hold [] metadata`` () = - Assert.IsTrue (hasAttribute()) +let [] ``struct records hold [] metadata`` () = + Assert.True (hasAttribute()) -let [] ``struct records are comparable`` () = +let [] ``struct records are comparable`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> i1 <> i2 ==> @@ -53,7 +53,7 @@ let [] ``struct records are comparable`` () = (sr1.Equals sr2) |@ "sr1.Equals sr2" -let [] ``struct records support pattern matching`` () = +let [] ``struct records support pattern matching`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let sr1 = { C = i1; D = i2 } @@ -67,7 +67,7 @@ let [] ``struct records support pattern matching`` () = |@ "function pattern match on struct record" -let [] ``struct records support let binds using `` () = +let [] ``struct records support let binds using `` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let sr1 = { C = i1; D = i2 } @@ -76,7 +76,7 @@ let [] ``struct records support let binds using `` () = (c1 = i1 && d2 = i2) |@ "c1 = i1 && d2 = i2" -let [] ``struct records support function argument bindings`` () = +let [] ``struct records support function argument bindings`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let sr1 = { C = i1; D = i2 } @@ -92,7 +92,7 @@ type MutableStructRecord = } -let [] ``struct recrods fields can be mutated`` () = +let [] ``struct recrods fields can be mutated`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) (m1:int) (m2:int) -> (i1 <> m1 && i2 <> m2) ==> @@ -110,7 +110,7 @@ type StructRecordDefaultValue = } -let [] ``struct records have correct behaviour with a [] on a ref type field`` () = +let [] ``struct records have correct behaviour with a [] on a ref type field`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let s = { C = i1; D = i2 } @@ -127,7 +127,7 @@ type StructRecordDefaultValue2 = } -let [] ``struct records have correct behaviour with a [] on a value type field`` () = +let [] ``struct records have correct behaviour with a [] on a value type field`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let r = { A = i1; B = i2 } @@ -136,7 +136,7 @@ let [] ``struct records have correct behaviour with a [] on (r1.R2 = { C = 0; D = 0 }) |@ "r1.R2 = { C = 0; D = 0 }" -let [] ``struct records exhibit correct behaviour for Unchecked.defaultof`` () = +let [] ``struct records exhibit correct behaviour for Unchecked.defaultof`` () = let x1 = { C = 0; D = 0 } let x2 : StructRecordDefaultValue = { R2 = { C = 0; D = 0 } } let x3 : StructRecordDefaultValue2 = { R1 = Unchecked.defaultof } @@ -145,15 +145,15 @@ let [] ``struct records exhibit correct behaviour for Unchecked.defaultof` let y2 = Unchecked.defaultof let y3 = Unchecked.defaultof - Assert.IsTrue ((x1 = y1)) + Assert.True ((x1 = y1)) - Assert.IsTrue (( (obj.ReferenceEquals (x2.R1, null)) = (obj.ReferenceEquals (y2.R1, null)) )) - Assert.IsTrue ((x2.R2 = x1)) - Assert.IsTrue ((y2.R2 = x1)) + Assert.True (( (obj.ReferenceEquals (x2.R1, null)) = (obj.ReferenceEquals (y2.R1, null)) )) + Assert.True ((x2.R2 = x1)) + Assert.True ((y2.R2 = x1)) - Assert.IsTrue (( (obj.ReferenceEquals (x3.R1, null)) = (obj.ReferenceEquals (y3.R1, null)) )) - Assert.IsTrue ((x3.R2 = x1)) - Assert.IsTrue ((y3.R2 = x1)) + Assert.True (( (obj.ReferenceEquals (x3.R1, null)) = (obj.ReferenceEquals (y3.R1, null)) )) + Assert.True ((x3.R2 = x1)) + Assert.True ((y3.R2 = x1)) [] @@ -175,7 +175,7 @@ type ComparisonStructRecord = | _ -> invalidArg "other" "cannot compare values of different types" -let [] ``struct records support []`` () = +let [] ``struct records support []`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) -> let sr1 = { C1 = i1; C2 = i2 } @@ -183,7 +183,7 @@ let [] ``struct records support []`` () = (sr1.Equals sr2) -let [] ``struct records support []`` () = +let [] ``struct records support []`` () = Check.QuickThrowOnFailure <| fun (i1:int) (i2:int) (k1:int) (k2:int) -> let sr1 = { C1 = i1; C2 = i2 } @@ -194,9 +194,9 @@ let [] ``struct records support []`` () = else false -let [] ``struct records hold [] [] metadata`` () = - Assert.IsTrue (hasAttribute()) - Assert.IsTrue (hasAttribute()) +let [] ``struct records hold [] [] metadata`` () = + Assert.True (hasAttribute()) + Assert.True (hasAttribute()) [] @@ -207,9 +207,9 @@ type NoComparisonStructRecord = } -let [] ``struct records hold [] [] metadata`` () = - Assert.IsTrue (hasAttribute()) - Assert.IsTrue (hasAttribute()) +let [] ``struct records hold [] [] metadata`` () = + Assert.True (hasAttribute()) + Assert.True (hasAttribute()) [] @@ -221,12 +221,12 @@ type ExplicitLayoutStructRecord = } -let [] ``struct records offset fields correctly with [] and []`` () = +let [] ``struct records offset fields correctly with [] and []`` () = let checkOffset fieldName offset = offset = int (Marshal.OffsetOf (typeof, fieldName)) - Assert.IsTrue (checkOffset "X@" 0) - Assert.IsTrue (checkOffset "Y@" 4) - Assert.IsTrue (checkOffset "Z@" 8) + Assert.True (checkOffset "X@" 0) + Assert.True (checkOffset "Y@" 4) + Assert.True (checkOffset "Z@" 8) [] @@ -238,12 +238,12 @@ type ExplicitLayoutMutableStructRecord = } -let [] ``struct records offset mutable fields correctly with [] and []`` () = +let [] ``struct records offset mutable fields correctly with [] and []`` () = let checkOffset fieldName offset = offset = int (Marshal.OffsetOf (typeof, fieldName)) - Assert.IsTrue (checkOffset "X@" 0) - Assert.IsTrue (checkOffset "Y@" 4) - Assert.IsTrue (checkOffset "Z@" 8) + Assert.True (checkOffset "X@" 0) + Assert.True (checkOffset "Y@" 4) + Assert.True (checkOffset "Z@" 8) [] @@ -265,23 +265,23 @@ type SequentialLayoutStructRecord = } -let [] ``struct records order fields correctly with []`` () = +let [] ``struct records order fields correctly with []`` () = let compareOffsets field1 fn field2 = fn (Marshal.OffsetOf (typeof, field1)) (Marshal.OffsetOf (typeof, field2)) - Assert.IsTrue (compareOffsets "First@" (<) "Second@") - Assert.IsTrue (compareOffsets "Second@" (<) "Third@") - Assert.IsTrue (compareOffsets "Third@" (<) "Fourth@") + Assert.True (compareOffsets "First@" (<) "Second@") + Assert.True (compareOffsets "Second@" (<) "Third@") + Assert.True (compareOffsets "Third@" (<) "Fourth@") -let [] ``struct records default field order matches []`` () = +let [] ``struct records default field order matches []`` () = let compareOffsets field1 fn field2 = fn (Marshal.OffsetOf (typeof, field1)) (Marshal.OffsetOf (typeof, field2)) - Assert.IsTrue (compareOffsets "First@" (=) "First@") - Assert.IsTrue (compareOffsets "Second@" (=) "Second@") - Assert.IsTrue (compareOffsets "Third@" (=) "Third@") - Assert.IsTrue (compareOffsets "Fourth@" (=) "Fourth@") + Assert.True (compareOffsets "First@" (=) "First@") + Assert.True (compareOffsets "Second@" (=) "Second@") + Assert.True (compareOffsets "Third@" (=) "Third@") + Assert.True (compareOffsets "Fourth@" (=) "Fourth@") [] @@ -294,18 +294,18 @@ type SequentialLayoutMutableStructRecord = } -let [] ``struct records order mutable field correctly with []`` () = +let [] ``struct records order mutable field correctly with []`` () = let compareOffsets field1 fn field2 = fn (Marshal.OffsetOf (typeof, field1)) (Marshal.OffsetOf (typeof, field2)) - Assert.IsTrue (compareOffsets "First@" (<) "Second@") - Assert.IsTrue (compareOffsets "Second@" (<) "Third@") - Assert.IsTrue (compareOffsets "Third@" (<) "Fourth@") + Assert.True (compareOffsets "First@" (<) "Second@") + Assert.True (compareOffsets "Second@" (<) "Third@") + Assert.True (compareOffsets "Third@" (<) "Fourth@") -let [] ``can properly construct a struct record using FSharpValue.MakeRecord, and we get the fields by FSharpValue.GetRecordFields`` () = +let [] ``can properly construct a struct record using FSharpValue.MakeRecord, and we get the fields by FSharpValue.GetRecordFields`` () = let structRecord = Microsoft.FSharp.Reflection.FSharpValue.MakeRecord (typeof, [|box 1234;box 999|]) - Assert.IsTrue (structRecord.GetType().IsValueType) + Assert.True (structRecord.GetType().IsValueType) let fields = Microsoft.FSharp.Reflection.FSharpValue.GetRecordFields structRecord @@ -336,7 +336,7 @@ type Members() = static member CreateMutableStructRecord() = { M1 = 1; M2 = 2 } -let [] ``inline constraints resolve correctly`` () = +let [] ``inline constraints resolve correctly`` () = let v = CX_get_A ({ A = 1; B = 2 }) Assert.AreEqual (1, v) @@ -352,7 +352,7 @@ let [] ``inline constraints resolve correctly`` () = let v3 = CX_set_First (m,1) Assert.AreEqual (1, m.First) -let [] ``member setters resolve correctly`` () = +let [] ``member setters resolve correctly`` () = let v = Members.CreateMutableStructRecord() Assert.AreEqual (1, v.M1) diff --git a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs index f17daba432e..70697fb43e3 100644 --- a/tests/FSharp.Core.UnitTests/LibraryTestFx.fs +++ b/tests/FSharp.Core.UnitTests/LibraryTestFx.fs @@ -4,8 +4,9 @@ module FSharp.Core.UnitTests.LibraryTestFx open System open System.Collections.Generic - -open NUnit.Framework +open System.IO +open System.Reflection +open Xunit // Workaround for bug 3601, we are issuing an unnecessary warning #nowarn "0004" @@ -37,6 +38,7 @@ let private CheckThrowsExn2<'a when 'a :> exn> s (f : unit -> unit) = // attribute to flag these exception's usage as a bug. let CheckThrowsNullRefException f = CheckThrowsExn f let CheckThrowsIndexOutRangException f = CheckThrowsExn f +let CheckThrowsObjectDisposedException f = CheckThrowsExn f // Legit exceptions let CheckThrowsNotSupportedException f = CheckThrowsExn f @@ -49,6 +51,7 @@ let CheckThrowsDivideByZeroException f = CheckThrowsExn let CheckThrowsOverflowException f = CheckThrowsExn f let CheckThrowsInvalidOperationExn f = CheckThrowsExn f let CheckThrowsFormatException f = CheckThrowsExn f +let CheckThrowsArithmeticException f = CheckThrowsExn f // Verifies two sequences are equal (same length, equiv elements) let VerifySeqsEqual (seq1 : seq<'T>) (seq2 : seq<'T>) = @@ -80,10 +83,10 @@ module SurfaceArea = let cast (info: #MemberInfo) = (t, info :> MemberInfo) let isDeclaredInFSharpCore (m:MemberInfo) = m.DeclaringType.Assembly.FullName = fsCoreFullName seq { - yield! t.GetRuntimeEvents() |> Seq.filter (fun m -> m.AddMethod.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast - yield! t.GetRuntimeProperties() |> Seq.filter (fun m -> m.GetMethod.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast - yield! t.GetRuntimeMethods() |> Seq.filter (fun m -> m.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast - yield! t.GetRuntimeFields() |> Seq.filter (fun m -> m.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast + yield! ti.DeclaredEvents |> Seq.filter (fun m -> m.AddMethod.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast + yield! ti.DeclaredProperties |> Seq.filter (fun m -> m.GetMethod.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast + yield! ti.DeclaredMethods |> Seq.filter (fun m -> m.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast + yield! ti.DeclaredFields |> Seq.filter (fun m -> m.IsPublic && m |> isDeclaredInFSharpCore) |> Seq.map cast yield! ti.DeclaredConstructors |> Seq.filter (fun m -> m.IsPublic) |> Seq.map cast yield! ti.DeclaredNestedTypes |> Seq.filter (fun ty -> ty.IsNestedPublic) |> Seq.map cast } |> Array.ofSeq @@ -104,58 +107,27 @@ module SurfaceArea = Regex.Replace(s, "(\\r\\n|\\n|\\r)+", "\r\n").Trim() let asm, actualNotNormalized = getActual () - let actual = actualNotNormalized |> Seq.map normalize |> Seq.filter (String.IsNullOrWhiteSpace >> not) |> set + let actual = + actualNotNormalized + |> Seq.map normalize + |> Seq.filter (String.IsNullOrWhiteSpace >> not) + |> String.concat Environment.NewLine - let expected = - // Split the "expected" string into individual lines, then normalize it. - (normalize expected).Split([|"\r\n"; "\n"; "\r"|], StringSplitOptions.RemoveEmptyEntries) - |> set - - // - // Find types/members which exist in exactly one of the expected or actual surface areas. - // - - /// Surface area types/members which were expected to be found but missing from the actual surface area. - let unexpectedlyMissing = Set.difference expected actual - - /// Surface area types/members present in the actual surface area but weren't expected to be. - let unexpectedlyPresent = Set.difference actual expected - - // If both sets are empty, the surface areas match so allow the test to pass. - if Set.isEmpty unexpectedlyMissing - && Set.isEmpty unexpectedlyPresent then - // pass - () - else + let expected = normalize expected + match Tests.TestHelpers.assembleDiffMessage actual expected with + | None -> () + | Some diff -> let logFile = - let workDir = TestContext.CurrentContext.WorkDirectory + let workDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) sprintf "%s\\FSharp.Core.SurfaceArea.%s.txt" workDir platform System.IO.File.WriteAllText(logFile, String.Join("\r\n", actual)) - // The surface areas don't match; prepare an easily-readable output message. - let msg = - let inline newLine (sb : System.Text.StringBuilder) = sb.AppendLine () |> ignore - let sb = System.Text.StringBuilder () - Printf.bprintf sb "Assembly: %A" asm - newLine sb - sb.AppendLine "Expected and actual surface area don't match. To see the delta, run:" |> ignore - Printf.bprintf sb " windiff %s %s" fileName logFile - newLine sb - newLine sb - sb.Append "Unexpectedly missing (expected, not actual):" |> ignore - for s in unexpectedlyMissing do - newLine sb - sb.Append " " |> ignore - sb.Append s |> ignore - newLine sb - newLine sb - sb.Append "Unexpectedly present (actual, not expected):" |> ignore - for s in unexpectedlyPresent do - newLine sb - sb.Append " " |> ignore - sb.Append s |> ignore - newLine sb - sb.ToString () + let msg = $"""Assembly: %A{asm} + + Expected and actual surface area don't match. To see the delta, run: + windiff %s{fileName} %s{logFile} + + {diff}""" failwith msg diff --git a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs b/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs deleted file mode 100644 index 8b0eec34fed..00000000000 --- a/tests/FSharp.Core.UnitTests/NUnitFrameworkShims.fs +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace NUnit.Framework - -open System -open System.Collections.Generic -open System.Linq -#if XUNIT -open Xunit - -(* The threading tests under XUnit seem prone to be very Flakey *) -[] -do () - - -type TestAttribute() = - inherit FactAttribute() - -type TestFixtureAttribute() = - inherit System.Attribute() - -type Explicit() = - inherit System.Attribute() - -type SetUpAttribute() = - inherit System.Attribute() - -[] -type Category(_categories:string) = - inherit System.Attribute() - -type TearDownAttribute() = - inherit System.Attribute() - -type IgnoreAttribute (_comment:string) = - inherit System.Attribute () -#endif - -// Alias NUnit and XUnit Assert as LocalAssert -type TestFrameworkAssert = Assert - -exception AssertionException of string - -module private Impl = - open FsCheck.Arb - - let rec equals (expected:obj) (actual:obj) = - - // get length expected - let toArray (o:obj) = - match o with - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> Enumerable.ToArray(seq) :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | :? seq as seq -> seq |> Seq.toArray :>obj - | _ -> o - - // get length expected - let expected = toArray expected - let actual = toArray actual - - match expected, actual with - | (:? Array as a1), (:? Array as a2) -> - if a1.Rank > 1 then failwith "Rank > 1 not supported" - if a2.Rank > 1 then false - else - let lb = a1.GetLowerBound(0) - let ub = a1.GetUpperBound(0) - if lb <> a2.GetLowerBound(0) || ub <> a2.GetUpperBound(0) then false - else - {lb..ub} |> Seq.forall(fun i -> equals (a1.GetValue(i)) (a2.GetValue(i))) - | _ -> - Object.Equals(expected, actual) - -type Assert = - static member AreEqual(expected : obj, actual : obj, message : string) = - if not (Impl.equals expected actual) then - let message = sprintf "%s: Expected %A but got %A" message expected actual - AssertionException message |> raise - - static member AreNotEqual(expected : obj, actual : obj, message : string) = - if Impl.equals expected actual then - let message = sprintf "%s: Expected not %A but got %A" message expected actual - AssertionException message |> raise - - static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion") - - static member AreNotEqual(expected : obj, actual : obj) = Assert.AreNotEqual(expected, actual, "Assertion") - - static member IsNull(o : obj) = Assert.AreEqual(null, o) - - static member IsTrue(x : bool, message : string) = - if not x then - AssertionException(message) |> raise - - static member IsTrue(x : bool) = Assert.IsTrue(x, "") - - static member True(x : bool) = Assert.IsTrue(x) - - static member IsFalse(x : bool, message : string) = - if x then - AssertionException(message) |> raise - - static member IsFalse(x : bool) = Assert.IsFalse(x, "") - - static member False(x : bool) = Assert.IsFalse(x) - - static member Fail(message : string) = AssertionException(message) |> raise - - static member Fail() = Assert.Fail("") - - static member Fail(message : string, args : obj[]) = Assert.Fail(String.Format(message,args)) - -#if XUNIT - static member Throws(except:Type, func: unit -> unit ) = TestFrameworkAssert.Throws(except, new Action(func)) -#else - static member Throws(except:Type, func: unit -> unit ) = TestFrameworkAssert.Throws(except, TestDelegate(func)) -#endif - -type CollectionAssert = - static member AreEqual(expected, actual) = - Assert.AreEqual(expected, actual) - diff --git a/tests/FSharp.Core.UnitTests/StructTuples.fs b/tests/FSharp.Core.UnitTests/StructTuples.fs index 63451250d12..5896b5ab5b0 100644 --- a/tests/FSharp.Core.UnitTests/StructTuples.fs +++ b/tests/FSharp.Core.UnitTests/StructTuples.fs @@ -2,143 +2,143 @@ // Various tests for Microsoft.FSharp.Core type forwarding -namespace FSharp.Core.UnitTests.FSharpStructTuples +namespace FSharp.Core.UnitTests.StructTuples #if TUPLE_SAMPLE open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit open TupleSample [] type StructTuplesCSharpInterop() = - [] + [] member this.ValueTupleDirect () = // Basic Tuple Two Values let struct (one,two) = System.ValueTuple.Create(1,2) - Assert.IsTrue( ((one=1) && (two=2)) ) + Assert.True( ((one=1) && (two=2)) ) // Basic Tuple Three Values let struct (one,two,three) = System.ValueTuple.Create(1, 2, 3) - Assert.IsTrue( (one=1) && (two=2) && (three=3) ) + Assert.True( (one=1) && (two=2) && (three=3) ) // Basic Tuple Four Values let struct (one,two,three,four) = System.ValueTuple.Create(1, 2, 3, 4) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) ) // Basic Tuple Five Values let struct (one,two,three,four,five) = System.ValueTuple.Create(1, 2, 3, 4, 5) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five=5)) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five=5)) // Basic Tuple six Values let struct (one,two,three,four,five,six) = System.ValueTuple.Create(1, 2, 3, 4, 5, 6) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) ) // Basic Tuple seven Values let struct (one,two,three,four,five,six,seven) = System.ValueTuple.Create(1, 2, 3, 4, 5, 6, 7) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) && (seven=7) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) && (seven=7) ) // Basic Tuple eight Values let struct (one,two,three,four,five,six,seven,eight) = System.ValueTuple.Create(1, 2, 3, 4, 5, 6, 7, 8) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) && (seven=7) && (eight=8)) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five=5) && (six=6) && (seven=7) && (eight=8)) () - [] + [] member this.CSharpInteropTupleReturns () = // Basic Tuple Two Values let struct (one,two) = TupleReturns.GetTuple(1, 2) - Assert.IsTrue( ((one=1) && (two=2)) ) + Assert.True( ((one=1) && (two=2)) ) // Basic Tuple Three Values let struct (one,two,three) = TupleReturns.GetTuple(1, 2, 3) - Assert.IsTrue( (one=1) && (two=2) && (three=3) ) + Assert.True( (one=1) && (two=2) && (three=3) ) // Basic Tuple Four Values let struct (one,two,three,four) = TupleReturns.GetTuple(1, 2, 3, 4) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) ) // Basic Tuple Five Values let struct (one,two,three,four,five) = TupleReturns.GetTuple(1, 2, 3, 4, 5) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) ) // Basic Tuple six Values let struct (one,two,three,four,five,six) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) ) // Basic Tuple seven Values let struct (one,two,three,four,five,six,seven) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) ) // Basic Tuple eight Values let struct (one,two,three,four,five,six,seven,eight) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7, 8) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) ) // Basic Tuple nine Values let struct (one,two,three,four,five,six,seven,eight,nine) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7, 8, 9) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9)) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9)) // Basic Tuple ten Values let struct (one,two,three,four,five,six,seven,eight,nine,ten) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) ) // Basic Tuple fifteen Values + 7T + 7T + 1T let struct (one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) ) // Basic Tuple sixteen Values + 7T + 7T + 2T let struct (one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen) = TupleReturns.GetTuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) && (sixteen=16) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) && (sixteen=16) ) () - [] + [] member this.CSharpInteropTupleArguments () = // Basic Tuple Two Values let struct (one,two) = TupleArguments.GetTuple( struct (1, 2) ) - Assert.IsTrue( (one=1) && (two=2) ) + Assert.True( (one=1) && (two=2) ) // Basic Tuple Three Values let struct (one,two,three) = TupleArguments.GetTuple( struct (1, 2, 3) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) ) + Assert.True( (one=1) && (two=2) && (three=3) ) // Basic Tuple Four Values let struct (one,two,three,four) = TupleArguments.GetTuple( struct (1, 2, 3, 4) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) ) // Basic Tuple Five Values let struct (one,two,three,four,five) = TupleArguments.GetTuple(struct (1, 2, 3, 4, 5) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) ) // Basic Tuple six Values let struct (one,two,three,four,five,six) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) ) // Basic Tuple seven Values let struct (one,two,three,four,five,six,seven) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) ) // Basic Tuple eight Values let struct (one,two,three,four,five,six,seven,eight) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7, 8) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) ) // Basic Tuple nine Values let struct (one,two,three,four,five,six,seven,eight,nine) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7, 8, 9) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9)) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9)) // Basic Tuple ten Values let struct (one,two,three,four,five,six,seven,eight,nine,ten) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) ) // Basic Tuple fifteen Values + 7T + 7T + 1T let struct (one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) ) // Basic Tuple sixteen Values + 7T + 7T + 2T let struct (one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen) = TupleArguments.GetTuple( struct (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) ) - Assert.IsTrue( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) && (sixteen=16) ) + Assert.True( (one=1) && (two=2) && (three=3) && (four=4) && (five = 5) && (six=6) && (seven=7) && (eight=8) && (nine=9) && (ten=10) && (eleven=11) && (twelve=12) && (thirteen=13) && (fourteen=14) && (fifteen=15) && (sixteen=16) ) () #endif diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs deleted file mode 100644 index 5e179041377..00000000000 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ /dev/null @@ -1,2758 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Core.UnitTests.Portable.SurfaceArea - -open NUnit.Framework -open FSharp.Core.UnitTests.LibraryTestFx - -type SurfaceAreaTest() = - [] - member this.VerifyArea() = - let expected = @" -Microsoft.FSharp.Collections.Array2DModule: Int32 Base1[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Base2[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Length1[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Length2[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T Get[T](T[,], Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: TResult[,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]], T[,]) -Microsoft.FSharp.Collections.Array2DModule: TResult[,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Copy[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] CreateBased[T](Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array2DModule: T[,] Create[T](Int32, Int32, T) -Microsoft.FSharp.Collections.Array2DModule: T[,] InitializeBased[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Initialize[T](Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Rebase[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreateBased[T](Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreate[T](Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: Void CopyTo[T](T[,], Int32, Int32, T[,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]], T[,]) -Microsoft.FSharp.Collections.Array2DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,]) -Microsoft.FSharp.Collections.Array2DModule: Void Set[T](T[,], Int32, Int32, T) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length1[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length2[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length3[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: T Get[T](T[,,], Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array3DModule: TResult[,,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]]], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: TResult[,,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: T[,,] Create[T](Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array3DModule: T[,,] Initialize[T](Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]) -Microsoft.FSharp.Collections.Array3DModule: T[,,] ZeroCreate[T](Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array3DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]]], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Void Set[T](T[,,], Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length1[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length2[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length3[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length4[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: T Get[T](T[,,,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Contains[T](T, T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean IsEmpty[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 Length[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.ArrayModule+Parallel -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] SplitAt[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1,T2,T3][] Zip3[T1,T2,T3](T1[], T2[], T3[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1[],T2[],T3[]] Unzip3[T1,T2,T3](System.Tuple`3[T1,T2,T3][]) -Microsoft.FSharp.Collections.ArrayModule: T Average[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T ExactlyOne[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Get[T](T[], Int32) -Microsoft.FSharp.Collections.ArrayModule: T Head[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T Item[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T Last[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Max[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Min[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Sum[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1[], T2[], T3[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], T1[], T2[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: TState[] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState[] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Append[T](T[], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Concat[T](System.Collections.Generic.IEnumerable`1[T[]]) -Microsoft.FSharp.Collections.ArrayModule: T[] Copy[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Create[T](Int32, T) -Microsoft.FSharp.Collections.ArrayModule: T[] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Distinct[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Empty[T]() -Microsoft.FSharp.Collections.ArrayModule: T[] Except[T](System.Collections.Generic.IEnumerable`1[T], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] GetSubArray[T](T[], Int32, Int32) -Microsoft.FSharp.Collections.ArrayModule: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ArrayModule: T[] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ArrayModule: T[] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.ArrayModule: T[] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.ArrayModule: T[] Reverse[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Singleton[T](T) -Microsoft.FSharp.Collections.ArrayModule: T[] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Skip[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortDescending[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Sort[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Tail[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Take[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Truncate[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.ArrayModule: T[] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] ZeroCreate[T](Int32) -Microsoft.FSharp.Collections.ArrayModule: T[][] ChunkBySize[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[][] SplitInto[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[][] Transpose[T](System.Collections.Generic.IEnumerable`1[T[]]) -Microsoft.FSharp.Collections.ArrayModule: T[][] Windowed[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: Void CopyTo[T](T[], Int32, T[], Int32, Int32) -Microsoft.FSharp.Collections.ArrayModule: Void Fill[T](T[], Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void Set[T](T[], Int32, T) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlace[T](T[]) -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] FromFunction[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]]) -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] NonStructural[T]() -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() -Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons -Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsCons -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsCons() -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetReverseIndex(Int32, Int32) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Length -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Tag -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Length() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Tag() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1+Tags[T] -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Cons(T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Empty -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] GetSlice(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Tail -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] TailOrNull -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Empty() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Tail() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_TailOrNull() -Microsoft.FSharp.Collections.FSharpList`1[T]: System.String ToString() -Microsoft.FSharp.Collections.FSharpList`1[T]: T Head -Microsoft.FSharp.Collections.FSharpList`1[T]: T HeadOrDefault -Microsoft.FSharp.Collections.FSharpList`1[T]: T Item [Int32] -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Head() -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_HeadOrDefault() -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Item(Int32) -Microsoft.FSharp.Collections.FSharpList`1[T]: Void .ctor(T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean ContainsKey(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean TryGetValue(TKey, TValue ByRef) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 Count -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 get_Count() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Add(TKey, TValue) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Remove(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Core.FSharpOption`1[TValue] TryFind(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.String ToString() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue Item [TKey] -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue get_Item(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Void .ctor(System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Contains(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 Count -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 get_Count() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Add(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Addition(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Subtraction(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: System.String ToString() -Microsoft.FSharp.Collections.FSharpSet`1[T]: T MaximumElement -Microsoft.FSharp.Collections.FSharpSet`1[T]: T MinimumElement -Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MaximumElement() -Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MinimumElement() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] FromFunctions[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]]) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] LimitedStructural[T](Int32) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] NonStructural[T]() -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Reference[T]() -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() -Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 Length[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] SplitInto[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Transpose[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Collections.FSharpList`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Concat[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Distinct[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Empty[T]() -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Reverse[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortDescending[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Sort[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Tail[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Take[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2]] Unzip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] SplitAt[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`3[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2],Microsoft.FSharp.Collections.FSharpList`1[T3]] Unzip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]]) -Microsoft.FSharp.Collections.ListModule: T Average[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T ExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Get[T](Microsoft.FSharp.Collections.FSharpList`1[T], Int32) -Microsoft.FSharp.Collections.ListModule: T Head[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Item[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Last[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Max[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Min[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Sum[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], TState) -Microsoft.FSharp.Collections.ListModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.MapModule: Boolean ContainsKey[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean Exists[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean ForAll[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean IsEmpty[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Int32 Count[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]] ToList[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TResult] Map[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Add[TKey,T](TKey, T, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Empty[TKey,T]() -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Filter[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfArray[TKey,T](System.Tuple`2[TKey,T][]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfList[TKey,T](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfSeq[TKey,T](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Remove[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TKey] TryFindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]] ToSeq[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpMap`2[TKey,T],Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]] Partition[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Tuple`2[TKey,T][] ToArray[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: T Find[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TKey FindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) -Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 Length[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Collections.Generic.IEnumerable`1[T]] Transpose[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] ChunkBySize[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] SplitInto[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] Windowed[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Append[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cache[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cast[T](System.Collections.IEnumerable) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Concat[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Collections.Generic.IEnumerable`1[T]]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Distinct[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Empty[T]() -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] ReadOnly[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Reverse[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Skip[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortDescending[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Sort[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Tail[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Take[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Truncate[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Average[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T ExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Get[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Head[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Item[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Last[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Max[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Min[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Sum[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], TState) -Microsoft.FSharp.Collections.SeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T[] ToArray[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsProperSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsProperSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Int32 Count[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Add[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Difference[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Empty[T]() -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] IntersectMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Intersect[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] UnionMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Union[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpSet`1[T],Microsoft.FSharp.Collections.FSharpSet`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T MaxElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T MinElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpSet`1[T], TState) -Microsoft.FSharp.Collections.SetModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean IsCancellationRequested -Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean get_IsCancellationRequested() -Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnCancellation() -Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnSuccess(T) -Microsoft.FSharp.Control.AsyncActivation`1[T]: Void OnExceptionRaised() -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Bind[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn CallThenInvoke[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], TResult, Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Invoke[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Control.AsyncActivation`1[T]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryFinally[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryWith[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.FSharpAsync`1[T] MakeAsync[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.AsyncActivation`1[T],Microsoft.FSharp.Control.AsyncReturn]) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncWrite(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncReadBytes(System.IO.Stream, Int32) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Int32] AsyncRead(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.CommonExtensions: System.IDisposable SubscribeToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.CommonExtensions: Void AddToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[T,T]],System.Tuple`2[T,T]] Pairwise[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Choose[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Map[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Scan[TResult,T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Filter[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Merge[TDel1,T,TDel2](Microsoft.FSharp.Control.IEvent`2[TDel1,T], Microsoft.FSharp.Control.IEvent`2[TDel2,T]) -Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult1],TResult1],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult2],TResult2]] Split[T,TResult1,TResult2,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T]] Partition[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Void Add[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Control.FSharpAsync`1[T]] StartChild[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpChoice`2[T,System.Exception]] Catch[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] Choice[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AwaitTask(System.Threading.Tasks.Task) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Ignore[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(Int32) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToContext(System.Threading.SynchronizationContext) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToNewThread() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToThreadPool() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitIAsyncResult(System.IAsyncResult, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitWaitHandle(System.Threading.WaitHandle, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.IDisposable] OnCancel(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] CancellationToken -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] get_CancellationToken() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.Tasks.Task`1[T]] StartChildAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Sequential[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitEvent[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitTask[T](System.Threading.Tasks.Task`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,TArg3,T](TArg1, TArg2, TArg3, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[TArg1,TArg2,TArg3,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,T](TArg1, TArg2, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[TArg1,TArg2,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,T](TArg1, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg1,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromContinuations[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]],Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] TryCancelled[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken DefaultCancellationToken -Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken get_DefaultCancellationToken() -Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartImmediateAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg,System.AsyncCallback,System.Object],System.IAsyncResult],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,Microsoft.FSharp.Core.Unit]] AsBeginEnd[TArg,T](Microsoft.FSharp.Core.FSharpFunc`2[TArg,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: T RunSynchronously[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void CancelDefaultToken() -Microsoft.FSharp.Control.FSharpAsync: Void Start(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void StartImmediate(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void StartWithContinuations[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] For[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] While(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Zero() -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Bind[T,TResult](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Combine[T](Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] ReturnFrom[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Return[T](T) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryFinally[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryWith[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply]: Void Reply(TReply) -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] Publish -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] get_Publish() -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void .ctor() -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void Trigger(System.Object[]) -Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Publish -Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] get_Publish() -Microsoft.FSharp.Control.FSharpEvent`1[T]: Void .ctor() -Microsoft.FSharp.Control.FSharpEvent`1[T]: Void Trigger(T) -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] Publish -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] get_Publish() -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void .ctor() -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void Trigger(System.Object, TArgs) -Microsoft.FSharp.Control.FSharpHandler`1[T]: System.IAsyncResult BeginInvoke(System.Object, T, System.AsyncCallback, System.Object) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void .ctor(System.Object, IntPtr) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void EndInvoke(System.IAsyncResult) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void Invoke(System.Object, T) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 CurrentQueueLength -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 DefaultTimeout -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_CurrentQueueLength() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_DefaultTimeout() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TMsg]] TryReceive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TReply]] PostAndTryAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] TryScan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TMsg] Receive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Start() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void add_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void remove_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void set_DefaultTimeout(Int32) -Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void AddHandler(TDelegate) -Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void RemoveHandler(TDelegate) -Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] CreateFromValue[T](T) -Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] Create[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) -Microsoft.FSharp.Control.LazyExtensions: T Force[T](System.Lazy`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IDisposable Subscribe[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[System.Tuple`2[T,T]] Pairwise[T](System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Scan[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Merge[T](System.IObservable`1[T], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[TResult1],System.IObservable`1[TResult2]] Split[T,TResult1,TResult2](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[T],System.IObservable`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: Void Add[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncDownloadFile(System.Net.WebClient, System.Uri, System.String) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncDownloadData(System.Net.WebClient, System.Uri) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Net.WebResponse] AsyncGetResponse(System.Net.WebRequest) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.String] AsyncDownloadString(System.Net.WebClient, System.Uri) -Microsoft.FSharp.Core.AbstractClassAttribute: Void .ctor() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Value -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean get_Value() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.AutoOpenAttribute: System.String Path -Microsoft.FSharp.Core.AutoOpenAttribute: System.String get_Path() -Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor() -Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean Value -Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean get_Value() -Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+In -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+InOut -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+Out -Microsoft.FSharp.Core.CLIEventAttribute: Void .ctor() -Microsoft.FSharp.Core.CLIMutableAttribute: Void .ctor() -Microsoft.FSharp.Core.ClassAttribute: Void .ctor() -Microsoft.FSharp.Core.ComparisonConditionalOnAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] Counts -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] get_Counts() -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: Void .ctor(Int32[]) -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 SequenceNumber -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 VariantNumber -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_SequenceNumber() -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_VariantNumber() -Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags SourceConstructFlags -Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags get_SourceConstructFlags() -Microsoft.FSharp.Core.CompilationMappingAttribute: System.String ResourceName -Microsoft.FSharp.Core.CompilationMappingAttribute: System.String get_ResourceName() -Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] TypeDefinitions -Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] get_TypeDefinitions() -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32, Int32) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(System.String, System.Type[]) -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags Flags -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags get_Flags() -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Void .ctor(Microsoft.FSharp.Core.CompilationRepresentationFlags) -Microsoft.FSharp.Core.CompilationRepresentationFlags: Int32 value__ -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Event -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Instance -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags ModuleSuffix -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags None -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Static -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags UseNullAsTrueValue -Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String SourceName -Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String get_SourceName() -Microsoft.FSharp.Core.CompilationSourceNameAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompiledNameAttribute: System.String CompiledName -Microsoft.FSharp.Core.CompiledNameAttribute: System.String get_CompiledName() -Microsoft.FSharp.Core.CompiledNameAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsError -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsHidden -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsError() -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsHidden() -Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 MessageNumber -Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 get_MessageNumber() -Microsoft.FSharp.Core.CompilerMessageAttribute: System.String Message -Microsoft.FSharp.Core.CompilerMessageAttribute: System.String get_Message() -Microsoft.FSharp.Core.CompilerMessageAttribute: Void .ctor(System.String, Int32) -Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsError(Boolean) -Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsHidden(Boolean) -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean CheckClose -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T get_LastGenerated() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void Close() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNestedNamespaces() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String NamespaceName -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String get_NamespaceName() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type ResolveTypeName(System.String) -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type[] GetTypes() -Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.MethodBase ApplyStaticArgumentsForMethod(System.Reflection.MethodBase, System.String, System.Object[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.ParameterInfo[] GetStaticParametersForMethod(System.Reflection.MethodBase) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Byte[] GetGeneratedAssemblyContents(System.Reflection.Assembly) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNamespaces() -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Quotations.FSharpExpr GetInvokerExpression(System.Reflection.MethodBase, Microsoft.FSharp.Quotations.FSharpExpr[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.EventHandler Invalidate -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Reflection.ParameterInfo[] GetStaticParameters(System.Type) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Type ApplyStaticArguments(System.Type, System.String[], System.Object[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void add_Invalidate(System.EventHandler) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void remove_Invalidate(System.EventHandler) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] CreateEvent[TDelegate,TArgs](Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[System.Object,Microsoft.FSharp.Core.FSharpFunc`2[TArgs,Microsoft.FSharp.Core.Unit]],TDelegate]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateFromFunctions[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateUsing[T,TCollection,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateThenFinally[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String AssemblyName -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String get_AssemblyName() -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsHostedExecution -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsInvalidationSupported -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean SystemRuntimeContainsType(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsHostedExecution() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsInvalidationSupported() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String ResolutionFolder -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String RuntimeAssembly -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String TemporaryFolder -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_ResolutionFolder() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_RuntimeAssembly() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_TemporaryFolder() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] ReferencedAssemblies -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] get_ReferencedAssemblies() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version SystemRuntimeAssemblyVersion -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version get_SystemRuntimeAssemblyVersion() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsHostedExecution(Boolean) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsInvalidationSupported(Boolean) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ReferencedAssemblies(System.String[]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ResolutionFolder(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_RuntimeAssembly(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_SystemRuntimeAssemblyVersion(System.Version) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_TemporaryFolder(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Column -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Line -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Column() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Line() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String FilePath -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String get_FilePath() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Column(Int32) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_FilePath(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Line(Int32) -Microsoft.FSharp.Core.CompilerServices.TypeProviderEditorHideMethodsAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Int32 value__ -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes IsErased -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes SuppressRelocate -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String CommentText -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String get_CommentText() -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CustomComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.CustomEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean AllowIntoPattern -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeGroupJoin -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeJoin -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeZip -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpace -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpaceUsingBind -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_AllowIntoPattern() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeGroupJoin() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeJoin() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeZip() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpace() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpaceUsingBind() -Microsoft.FSharp.Core.CustomOperationAttribute: System.String JoinConditionWord -Microsoft.FSharp.Core.CustomOperationAttribute: System.String Name -Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_JoinConditionWord() -Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_Name() -Microsoft.FSharp.Core.CustomOperationAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_AllowIntoPattern(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeGroupJoin(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeJoin(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeZip(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_JoinConditionWord(System.String) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpace(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpaceUsingBind(Boolean) -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean Value -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean get_Value() -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.DefaultValueAttribute: Boolean Check -Microsoft.FSharp.Core.DefaultValueAttribute: Boolean get_Check() -Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor() -Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.EntryPointAttribute: Void .ctor() -Microsoft.FSharp.Core.EqualityConditionalOnAttribute: Void .ctor() -Microsoft.FSharp.Core.ExperimentalAttribute: System.String Message -Microsoft.FSharp.Core.ExperimentalAttribute: System.String get_Message() -Microsoft.FSharp.Core.ExperimentalAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: Byte ToByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: SByte ToSByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Byte ToByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Double ToDouble[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Collections.FSharpSet`1[T] CreateSet[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder DefaultAsyncBuilder -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder get_DefaultAsyncBuilder() -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder get_query() -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder query -Microsoft.FSharp.Core.ExtraTopLevelOperators: SByte ToSByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Single ToSingle[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IDictionary`2[TKey,TValue] CreateDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IReadOnlyDictionary`2[TKey,TValue] CreateReadOnlyDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T LazyPattern[T](System.Lazy`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToString[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice1Of2(T1) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice2Of2(T2) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice1Of3(T1) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice2Of3(T2) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice3Of3(T3) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice1Of4(T1) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice2Of4(T2) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice3Of4(T3) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice4Of4(T4) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice1Of5(T1) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice2Of5(T2) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice3Of5(T3) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice4Of5(T4) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice5Of5(T5) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice1Of6(T1) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice2Of6(T2) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice3Of6(T3) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice4Of6(T4) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice5Of6(T5) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice6Of6(T6) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice1Of7(T1) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice2Of7(T2) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice3Of7(T3) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice4Of7(T4) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice5Of7(T5) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice6Of7(T6) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice7Of7(T7) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromConverter(System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] op_Implicit(System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] ToConverter(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] op_Implicit(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: TResult Invoke(T) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: V InvokeFast[V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], T, TResult) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Void .ctor() -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: W InvokeFast[V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], T, TResult, V) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: X InvokeFast[V,W,X](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,X]]]], T, TResult, V, W) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Y InvokeFast[V,W,X,Y](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,Microsoft.FSharp.Core.FSharpFunc`2[X,Y]]]]], T, TResult, V, W, X) -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Major -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Minor -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Release -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Major() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Minor() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Release() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Void .ctor(Int32, Int32, Int32) -Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 None -Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 Some -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsNone -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsSome -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsNone(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsSome(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetTag(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1+Tags[T] -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] None -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] Some(T) -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] get_None() -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] op_Implicit(T) -Microsoft.FSharp.Core.FSharpOption`1[T]: System.String ToString() -Microsoft.FSharp.Core.FSharpOption`1[T]: T Value -Microsoft.FSharp.Core.FSharpOption`1[T]: T get_Value() -Microsoft.FSharp.Core.FSharpOption`1[T]: Void .ctor(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: T Value -Microsoft.FSharp.Core.FSharpRef`1[T]: T contents -Microsoft.FSharp.Core.FSharpRef`1[T]: T contents@ -Microsoft.FSharp.Core.FSharpRef`1[T]: T get_Value() -Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents() -Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T) -Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error -Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError] -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T ResultValue -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T get_ResultValue() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError ErrorValue -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError get_ErrorValue() -Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]() -Microsoft.FSharp.Core.FSharpTypeFunc: Void .ctor() -Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueNone -Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsSome() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueSome() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 Tag -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T] -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] NewValueSome(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] None -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] Some(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] ValueNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_None() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_ValueNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] op_Implicit(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: System.String ToString() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Item -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Value -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Item() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Value() -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit] FromAction(System.Action) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T] FromFunc[T](System.Func`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] FromAction[T](System.Action`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] ToFSharpFunc[T](System.Action`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromFunc[T,TResult](System.Func`2[T,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] ToFSharpFunc[T,TResult](System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,Microsoft.FSharp.Core.Unit]]]]] FromAction[T1,T2,T3,T4,T5](System.Action`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FromFunc[T1,T2,T3,T4,T5,TResult](System.Func`6[T1,T2,T3,T4,T5,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FuncFromTupled[T1,T2,T3,T4,T5,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[T1,T2,T3,T4,T5],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.Unit]]]] FromAction[T1,T2,T3,T4](System.Action`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FromFunc[T1,T2,T3,T4,TResult](System.Func`5[T1,T2,T3,T4,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FuncFromTupled[T1,T2,T3,T4,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[T1,T2,T3,T4],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.Unit]]] FromAction[T1,T2,T3](System.Action`3[T1,T2,T3]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FromFunc[T1,T2,T3,TResult](System.Func`4[T1,T2,T3,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FuncFromTupled[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[T1,T2,T3],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]] FromAction[T1,T2](System.Action`2[T1,T2]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FromFunc[T1,T2,TResult](System.Func`3[T1,T2,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FuncFromTupled[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[T1,T2],TResult]) -Microsoft.FSharp.Core.GeneralizableValueAttribute: Void .ctor() -Microsoft.FSharp.Core.InterfaceAttribute: Void .ctor() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String AddressOpNotFirstClassString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputArrayEmptyString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputMustBeNonNegativeString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputSequenceEmptyString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String NoNegateMinValueString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_AddressOpNotFirstClassString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputArrayEmptyString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputMustBeNonNegativeString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputSequenceEmptyString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_NoNegateMinValueString() -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityERIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterOrEqualIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterThanIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessOrEqualIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessThanIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean PhysicalEqualityIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple2[T1,T2](System.Collections.IComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple3[T1,T2,T3](System.Collections.IComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple4[T1,T2,T3,T4](System.Collections.IComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple5[T1,T2,T3,T4,T5](System.Collections.IComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonWithComparerIntrinsic[T](System.Collections.IComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashIntrinsic[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 LimitedGenericHashIntrinsic[T](Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 PhysicalHashIntrinsic[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestFast[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestGeneric[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Char GetString(System.String, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: System.Decimal MakeDecimal(Int32, Int32, Int32, Boolean, Byte) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CheckThis[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CreateInstance[T]() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray2D[T](T[,], Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray3D[T](T[,,], Int32, Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray4D[T](T[,,,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray[T](T[], Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxFast[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxGeneric[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void Dispose[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailInit() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailStaticInit() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray2D[T](T[,], Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray3D[T](T[,,], Int32, Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray4D[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray[T](T[], Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean Or(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_Amp(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanAnd(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanOr(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: IntPtr op_IntegerAddressOf[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: T& op_AddressOf[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityER[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityWithComparer[T](System.Collections.IEqualityComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEquality[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterOrEqual[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterThan[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessOrEqual[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessThan[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean PhysicalEquality[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Double FloatWithMeasure(Double) -Microsoft.FSharp.Core.LanguagePrimitives: Int16 Int16WithMeasure(Int16) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparisonWithComparer[T](System.Collections.IComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparison[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHashWithComparer[T](System.Collections.IEqualityComparer, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHash[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericLimitedHash[T](Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 Int32WithMeasure(Int32) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 ParseInt32(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 PhysicalHash[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Int64 Int64WithMeasure(Int64) -Microsoft.FSharp.Core.LanguagePrimitives: Int64 ParseInt64(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+HashCompare -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators -Microsoft.FSharp.Core.LanguagePrimitives: SByte SByteWithMeasure(SByte) -Microsoft.FSharp.Core.LanguagePrimitives: Single Float32WithMeasure(Single) -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparerFromTable[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparer[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparerFromTable[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparer[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastLimitedGenericEqualityComparer[T](Int32) -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer GenericComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer get_GenericComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityERComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityERComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Decimal DecimalWithMeasure(System.Decimal) -Microsoft.FSharp.Core.LanguagePrimitives: T DivideByIntDynamic[T](T, Int32) -Microsoft.FSharp.Core.LanguagePrimitives: T DivideByInt[T](T, Int32) -Microsoft.FSharp.Core.LanguagePrimitives: T EnumToValue[TEnum,T](TEnum) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericMaximum[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericMinimum[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericOneDynamic[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericOne[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericZeroDynamic[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericZero[T]() -Microsoft.FSharp.Core.LanguagePrimitives: TEnum EnumOfValue[T,TEnum](T) -Microsoft.FSharp.Core.LanguagePrimitives: TResult AdditionDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedAdditionDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedMultiplyDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult MultiplyDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: UInt32 ParseUInt32(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: UInt64 ParseUInt64(System.String) -Microsoft.FSharp.Core.LiteralAttribute: Void .ctor() -Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object) -Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.MatchFailureException: Int32 Data1 -Microsoft.FSharp.Core.MatchFailureException: Int32 Data2 -Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode() -Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data1() -Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data2() -Microsoft.FSharp.Core.MatchFailureException: System.String Data0 -Microsoft.FSharp.Core.MatchFailureException: System.String Message -Microsoft.FSharp.Core.MatchFailureException: System.String get_Data0() -Microsoft.FSharp.Core.MatchFailureException: System.String get_Message() -Microsoft.FSharp.Core.MatchFailureException: Void .ctor() -Microsoft.FSharp.Core.MatchFailureException: Void .ctor(System.String, Int32, Int32) -Microsoft.FSharp.Core.MeasureAnnotatedAbbreviationAttribute: Void .ctor() -Microsoft.FSharp.Core.MeasureAttribute: Void .ctor() -Microsoft.FSharp.Core.NoComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.NoDynamicInvocationAttribute: Void .ctor() -Microsoft.FSharp.Core.NoEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromInt64Dynamic(Int64) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromStringDynamic(System.String) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt32[T](Int32) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt64[T](Int64) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromOne[T]() -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromString[T](System.String) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromZero[T]() -Microsoft.FSharp.Core.NumericLiterals: Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 String.GetReverseIndex(System.String, Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,,]`1.GetReverseIndex[T](T[,,,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,]`1.GetReverseIndex[T](T[,,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,]`1.GetReverseIndex[T](T[,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 []`1.GetReverseIndex[T](T[], Int32, Int32) -Microsoft.FSharp.Core.Operators+Checked: Byte ToByte[T](T) -Microsoft.FSharp.Core.Operators+Checked: Char ToChar[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt32[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int64 ToInt64[T](T) -Microsoft.FSharp.Core.Operators+Checked: IntPtr ToIntPtr[T](T) -Microsoft.FSharp.Core.Operators+Checked: SByte ToSByte[T](T) -Microsoft.FSharp.Core.Operators+Checked: T op_UnaryNegation[T](T) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Addition[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Multiply[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Subtraction[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: UInt16 ToUInt16[T](T) -Microsoft.FSharp.Core.Operators+Checked: UInt32 ToUInt32[T](T) -Microsoft.FSharp.Core.Operators+Checked: UInt64 ToUInt64[T](T) -Microsoft.FSharp.Core.Operators+Checked: UIntPtr ToUIntPtr[T](T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Equality[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThanOrEqual[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThan[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Inequality[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThanOrEqual[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThan[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Max[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Min[T](T, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Byte PowByte(Byte, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Double PowDouble(Double, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int16 PowInt16(Int16, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 PowInt32(Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 SignDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int64 PowInt64(Int64, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: IntPtr PowIntPtr(IntPtr, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: SByte PowSByte(SByte, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Single PowSingle(Single, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Byte] RangeByte(Byte, Byte, Byte) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Char] RangeChar(Char, Char) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Double] RangeDouble(Double, Double, Double) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int16] RangeInt16(Int16, Int16, Int16) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int32] RangeInt32(Int32, Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int64] RangeInt64(Int64, Int64, Int64) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.IntPtr] RangeIntPtr(IntPtr, IntPtr, IntPtr) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.SByte] RangeSByte(SByte, SByte, SByte) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Single] RangeSingle(Single, Single, Single) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt16] RangeUInt16(UInt16, UInt16, UInt16) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt32] RangeUInt32(UInt32, UInt32, UInt32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt64] RangeUInt64(UInt64, UInt64, UInt64) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UIntPtr] RangeUIntPtr(UIntPtr, UIntPtr, UIntPtr) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeStepGeneric[TStep,T](TStep, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TStep,T]], T, TStep, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Decimal PowDecimal(System.Decimal, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.String GetStringSlice(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AbsDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AcosDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AsinDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AtanDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CeilingDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CosDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CoshDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T ExpDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T FloorDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T Log10Dynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T LogDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowDynamic[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T RoundDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinhDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanhDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TruncateDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 Atan2Dynamic[T1,T2](T1, T1) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 SqrtDynamic[T1,T2](T1) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,,] GetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt16 PowUInt16(UInt16, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt32 PowUInt32(UInt32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt64 PowUInt64(UInt64, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UIntPtr PowUIntPtr(UIntPtr, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) -Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() -Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) -Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) -Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) -Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_GreaterThanOrEqual[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_GreaterThan[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_Inequality[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_LessThanOrEqual[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_LessThan[T](T, T) -Microsoft.FSharp.Core.Operators: Byte ToByte[T](T) -Microsoft.FSharp.Core.Operators: Char ToChar[T](T) -Microsoft.FSharp.Core.Operators: Double Infinity -Microsoft.FSharp.Core.Operators: Double NaN -Microsoft.FSharp.Core.Operators: Double ToDouble[T](T) -Microsoft.FSharp.Core.Operators: Double get_Infinity() -Microsoft.FSharp.Core.Operators: Double get_NaN() -Microsoft.FSharp.Core.Operators: Int16 ToInt16[T](T) -Microsoft.FSharp.Core.Operators: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators: Int32 Sign[T](T) -Microsoft.FSharp.Core.Operators: Int32 SizeOf[T]() -Microsoft.FSharp.Core.Operators: Int32 ToInt32[T](T) -Microsoft.FSharp.Core.Operators: Int32 ToInt[T](T) -Microsoft.FSharp.Core.Operators: Int32 limitedHash[T](Int32, T) -Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) -Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[T] TryUnbox[T](System.Object) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpRef`1[T] Ref[T](T) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+ArrayExtensions -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Checked -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+NonStructuralComparison -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+OperatorIntrinsics -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Unchecked -Microsoft.FSharp.Core.Operators: SByte ToSByte[T](T) -Microsoft.FSharp.Core.Operators: Single InfinitySingle -Microsoft.FSharp.Core.Operators: Single NaNSingle -Microsoft.FSharp.Core.Operators: Single ToSingle[T](T) -Microsoft.FSharp.Core.Operators: Single get_InfinitySingle() -Microsoft.FSharp.Core.Operators: Single get_NaNSingle() -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] CreateSequence[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_RangeStep[T,TStep](T, TStep, T) -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_Range[T](T, T) -Microsoft.FSharp.Core.Operators: System.Decimal ToDecimal[T](T) -Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) -Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() -Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() -Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() -Microsoft.FSharp.Core.Operators: System.Object Box[T](T) -Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) -Microsoft.FSharp.Core.Operators: System.String ToString[T](T) -Microsoft.FSharp.Core.Operators: System.String op_Concatenate(System.String, System.String) -Microsoft.FSharp.Core.Operators: System.Tuple`2[TKey,TValue] KeyValuePattern[TKey,TValue](System.Collections.Generic.KeyValuePair`2[TKey,TValue]) -Microsoft.FSharp.Core.Operators: System.Type TypeDefOf[T]() -Microsoft.FSharp.Core.Operators: System.Type TypeOf[T]() -Microsoft.FSharp.Core.Operators: T Abs[T](T) -Microsoft.FSharp.Core.Operators: T Acos[T](T) -Microsoft.FSharp.Core.Operators: T Asin[T](T) -Microsoft.FSharp.Core.Operators: T Atan[T](T) -Microsoft.FSharp.Core.Operators: T Ceiling[T](T) -Microsoft.FSharp.Core.Operators: T Cos[T](T) -Microsoft.FSharp.Core.Operators: T Cosh[T](T) -Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) -Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) -Microsoft.FSharp.Core.Operators: T Exit[T](Int32) -Microsoft.FSharp.Core.Operators: T Exp[T](T) -Microsoft.FSharp.Core.Operators: T FailWith[T](System.String) -Microsoft.FSharp.Core.Operators: T Floor[T](T) -Microsoft.FSharp.Core.Operators: T Identity[T](T) -Microsoft.FSharp.Core.Operators: T InvalidArg[T](System.String, System.String) -Microsoft.FSharp.Core.Operators: T InvalidOp[T](System.String) -Microsoft.FSharp.Core.Operators: T Lock[TLock,T](TLock, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) -Microsoft.FSharp.Core.Operators: T Log10[T](T) -Microsoft.FSharp.Core.Operators: T Log[T](T) -Microsoft.FSharp.Core.Operators: T Max[T](T, T) -Microsoft.FSharp.Core.Operators: T Min[T](T, T) -Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) -Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) -Microsoft.FSharp.Core.Operators: T Raise[T](System.Exception) -Microsoft.FSharp.Core.Operators: T Reraise[T]() -Microsoft.FSharp.Core.Operators: T Rethrow[T]() -Microsoft.FSharp.Core.Operators: T Round[T](T) -Microsoft.FSharp.Core.Operators: T Sin[T](T) -Microsoft.FSharp.Core.Operators: T Sinh[T](T) -Microsoft.FSharp.Core.Operators: T Tan[T](T) -Microsoft.FSharp.Core.Operators: T Tanh[T](T) -Microsoft.FSharp.Core.Operators: T Truncate[T](T) -Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) -Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) -Microsoft.FSharp.Core.Operators: T op_BitwiseOr[T](T, T) -Microsoft.FSharp.Core.Operators: T op_Dereference[T](Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.Operators: T op_ExclusiveOr[T](T, T) -Microsoft.FSharp.Core.Operators: T op_Exponentiation[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators: T op_LeftShift[T](T, Int32) -Microsoft.FSharp.Core.Operators: T op_LogicalNot[T](T) -Microsoft.FSharp.Core.Operators: T op_RightShift[T](T, Int32) -Microsoft.FSharp.Core.Operators: T op_UnaryNegation[T](T) -Microsoft.FSharp.Core.Operators: T op_UnaryPlus[T](T) -Microsoft.FSharp.Core.Operators: T1 Fst[T1,T2](System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.Operators: T2 Atan2[T1,T2](T1, T1) -Microsoft.FSharp.Core.Operators: T2 Snd[T1,T2](System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.Operators: T3 op_Addition[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Division[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Modulus[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Multiply[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Subtraction[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: TResult Sqrt[T,TResult](T) -Microsoft.FSharp.Core.Operators: TResult ToEnum[TResult](Int32) -Microsoft.FSharp.Core.Operators: TResult Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1, T2) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1, T2, T3) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight2[T1,T2,TResult](T1, T2, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight3[T1,T2,T3,TResult](T1, T2, T3, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight[T1,TResult](T1, Microsoft.FSharp.Core.FSharpFunc`2[T1,TResult]) -Microsoft.FSharp.Core.Operators: UInt16 ToUInt16[T](T) -Microsoft.FSharp.Core.Operators: UInt32 ToUInt32[T](T) -Microsoft.FSharp.Core.Operators: UInt64 ToUInt64[T](T) -Microsoft.FSharp.Core.Operators: UIntPtr ToUIntPtr[T](T) -Microsoft.FSharp.Core.Operators: Void Decrement(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) -Microsoft.FSharp.Core.Operators: Void Ignore[T](T) -Microsoft.FSharp.Core.Operators: Void Increment(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) -Microsoft.FSharp.Core.Operators: Void op_ColonEquals[T](Microsoft.FSharp.Core.FSharpRef`1[T], T) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: FSharpFunc`3 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: TResult Invoke(T1, T2) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: FSharpFunc`4 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: TResult Invoke(T1, T2, T3) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: FSharpFunc`5 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: TResult Invoke(T1, T2, T3, T4) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: FSharpFunc`6 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: TResult Invoke(T1, T2, T3, T4, T5) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult] -Microsoft.FSharp.Core.OptionModule: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Int32 Count[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2], Microsoft.FSharp.Core.FSharpOption`1[T3]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[T]]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfNullable[T](System.Nullable`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfObj[T](T) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpOption`1[T], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T GetValue[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T ToObj[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpOption`1[T], TState) -Microsoft.FSharp.Core.OptionModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T[] ToArray[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionalArgumentAttribute: Void .ctor() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String ToString() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String Value -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String get_Value() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: Void .ctor(System.String) -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String ToString() -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String Value -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String get_Value() -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: Void .ctor(System.String) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilderThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilder[T](System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriterThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ProjectionParameterAttribute: Void .ctor() -Microsoft.FSharp.Core.ReferenceEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean IncludeValue -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean get_IncludeValue() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.RequireQualifiedAccessAttribute: Void .ctor() -Microsoft.FSharp.Core.RequiresExplicitTypeArgumentsAttribute: Void .ctor() -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[T,TResult] MapError[TError,TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TError,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Bind[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpResult`2[TResult,TError]], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Map[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.SealedAttribute: Boolean Value -Microsoft.FSharp.Core.SealedAttribute: Boolean get_Value() -Microsoft.FSharp.Core.SealedAttribute: Void .ctor() -Microsoft.FSharp.Core.SealedAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.SourceConstructFlags: Int32 value__ -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Closure -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Exception -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Field -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags KindMask -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Module -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags NonPublicRepresentation -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags None -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags ObjectType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags RecordType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags SumType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags UnionCase -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Value -Microsoft.FSharp.Core.StringModule: Boolean Exists(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: Boolean ForAll(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: Int32 Length(System.String) -Microsoft.FSharp.Core.StringModule: System.String Collect(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.String], System.String) -Microsoft.FSharp.Core.StringModule: System.String Concat(System.String, System.Collections.Generic.IEnumerable`1[System.String]) -Microsoft.FSharp.Core.StringModule: System.String Filter(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: System.String Initialize(Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String]) -Microsoft.FSharp.Core.StringModule: System.String Map(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char], System.String) -Microsoft.FSharp.Core.StringModule: System.String MapIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char]], System.String) -Microsoft.FSharp.Core.StringModule: System.String Replicate(Int32, System.String) -Microsoft.FSharp.Core.StringModule: Void Iterate(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit], System.String) -Microsoft.FSharp.Core.StringModule: Void IterateIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit]], System.String) -Microsoft.FSharp.Core.StructAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuralComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuralEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String Value -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String get_Value() -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.Unit: Boolean Equals(System.Object) -Microsoft.FSharp.Core.Unit: Int32 GetHashCode() -Microsoft.FSharp.Core.UnverifiableAttribute: Void .ctor() -Microsoft.FSharp.Core.ValueOption: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Int32 Count[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpValueOption`1[TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2], Microsoft.FSharp.Core.FSharpValueOption`1[T3]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpValueOption`1[Microsoft.FSharp.Core.FSharpValueOption`1[T]]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfNullable[T](System.Nullable`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfObj[T](T) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpValueOption`1[T]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T GetValue[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T ToObj[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpValueOption`1[T], TState) -Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Char] ToChar[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Decimal] ToDecimal[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToDouble[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToFloat[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int16] ToInt16[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int64] ToInt64[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.IntPtr] ToIntPtr[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToInt8[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToSByte[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToFloat32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToSingle[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt16] ToUInt16[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt64] ToUInt64[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UIntPtr] ToUIntPtr[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[TResult] ToEnum[TResult](System.Nullable`1[System.Int32]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_EqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterEqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessEqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessGreaterQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreater[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreater[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLess[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_DivideQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MinusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MultiplyQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PercentQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PlusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivideQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivide[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinus[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiplyQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiply[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercentQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercent[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlus[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.QueryBuilder: Boolean All[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Boolean Contains[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], T) -Microsoft.FSharp.Linq.QueryBuilder: Boolean Exists[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Int32 Count[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,TValue],Q] GroupValBy[T,TKey,TValue,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,T],Q] GroupBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Distinct[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SkipWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Skip[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Source[T,Q](System.Linq.IQueryable`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] TakeWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Take[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Where[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] YieldFrom[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Yield[T,Q](T) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Zero[T,Q]() -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable] Source[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] For[T,Q,TResult,Q2](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Linq.QuerySource`2[TResult,Q2]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] GroupJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Join[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[TInner,TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] LeftOuterJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Select[T,Q,TResult](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Quote[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: System.Linq.IQueryable`1[T] Run[T](Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Linq.IQueryable]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] AverageByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MaxByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MinByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] SumByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOneOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOne[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Find[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: T HeadOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Head[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T LastOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Last[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Nth[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: TValue AverageBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue MaxBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue MinBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue SumBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: Void .ctor() -Microsoft.FSharp.Linq.QueryRunExtensions.HighPriority: System.Collections.Generic.IEnumerable`1[T] RunQueryAsEnumerable[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable]]) -Microsoft.FSharp.Linq.QueryRunExtensions.LowPriority: T RunQueryAsValue[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] Source -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] get_Source() -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: Void .ctor(T1) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: Void .ctor(T1, T2) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: Void .ctor(T1, T2, T3) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: Void .ctor(T1, T2, T3, T4) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: Void .ctor(T1, T2, T3, T4, T5) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: Void .ctor(T1, T2, T3, T4, T5, T6) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 Item7 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item7() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: Void .ctor(T1, T2, T3, T4, T5, T6, T7) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 Item7 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 get_Item7() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 Item8 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 get_Item8() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: Void .ctor(T1, T2, T3, T4, T5, T6, T7, T8) -Microsoft.FSharp.Linq.RuntimeHelpers.Grouping`2[K,T]: Void .ctor(K, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr SubstHelperRaw(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr`1[T] SubstHelper[T](Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression QuotationToExpression(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] ImplicitExpressionConversionHelper[T](T) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] QuotationToLambdaExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Object EvaluateQuotation(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T MemberInitializationHelper[T](T) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T NewAnonymousObjectHelper[T](T) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr AddPointerInlined[T](IntPtr, Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfNativeIntInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfVoidPtrInlined[T](Void*) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr StackAllocate[T](Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr ToNativeIntInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: T GetPointerInlined[T](IntPtr, Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: T& ToByRefInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void* ToVoidPtrInlined[T](IntPtr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] UnitPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] MethodWithReflectedDefinitionPattern(System.Reflection.MethodBase) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertyGetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertySetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Boolean] BoolPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Byte] BytePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Char] CharPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Decimal] DecimalPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Double] DoublePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int16] Int16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] Int32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int64] Int64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.SByte] SBytePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Single] SinglePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.String] StringPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar]],Microsoft.FSharp.Quotations.FSharpExpr]] LambdasPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] ApplicationsPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AndAlsoPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] OrElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt16] UInt16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt32] UInt32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt64] UInt64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Core.FSharpChoice`3[Microsoft.FSharp.Quotations.FSharpVar,System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr],System.Tuple`2[System.Object,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] ShapePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Quotations.FSharpExpr RebuildShapeCombination(System.Object, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpExpr: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] CustomAttributes -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] get_CustomAttributes() -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] TryGetReflectedDefinition(System.Reflection.MethodBase) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressOf(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressSet(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Application(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Applications(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Coerce(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr DefaultValue(System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize(System.Type, Microsoft.FSharp.Collections.FSharpList`1[System.Type], Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr], Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize40(System.Type, System.Type[], System.Type[], Microsoft.FSharp.Quotations.FSharpExpr[], Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(System.Reflection.FieldInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ForIntegerRangeLoop(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr IfThenElse(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Lambda(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Let(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr LetRecursive(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]], Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewArray(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Quote(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteRaw(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteTyped(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Sequential(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Substitute(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryFinally(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryWith(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TupleGet(Microsoft.FSharp.Quotations.FSharpExpr, Int32) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TypeTest(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr UnionCaseTest(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Reflection.UnionCaseInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value(System.Object, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName(System.Object, System.Type, System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName[T](T, System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value[T](T) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Var(Microsoft.FSharp.Quotations.FSharpVar) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr VarSet(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WhileLoop(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WithValue(System.Object, System.Type, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Cast[T](Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] GlobalVar[T](System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] WithValue[T](T, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Quotations.FSharpExpr: System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Quotations.FSharpVar] GetFreeVars() -Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString() -Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString(Boolean) -Microsoft.FSharp.Quotations.FSharpExpr: System.Type Type -Microsoft.FSharp.Quotations.FSharpExpr: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[], System.Type[]) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] CustomAttributes -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] get_CustomAttributes() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr Raw -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr Substitute(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr get_Raw() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Quotations.FSharpVar] GetFreeVars() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.String ToString() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.String ToString(Boolean) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Type Type -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpVar: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpVar: Boolean IsMutable -Microsoft.FSharp.Quotations.FSharpVar: Boolean get_IsMutable() -Microsoft.FSharp.Quotations.FSharpVar: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpVar: Microsoft.FSharp.Quotations.FSharpVar Global(System.String, System.Type) -Microsoft.FSharp.Quotations.FSharpVar: System.String Name -Microsoft.FSharp.Quotations.FSharpVar: System.String ToString() -Microsoft.FSharp.Quotations.FSharpVar: System.String get_Name() -Microsoft.FSharp.Quotations.FSharpVar: System.Type Type -Microsoft.FSharp.Quotations.FSharpVar: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpVar: Void .ctor(System.String, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewStructTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] AddressOfPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuotePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteRawPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteTypedPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpVar] VarPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]],Microsoft.FSharp.Quotations.FSharpExpr]] LetRecursivePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo]] FieldGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AddressSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ApplicationPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] SequentialPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] TryFinallyPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] WhileLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Reflection.UnionCaseInfo]] UnionCaseTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Int32]] TupleGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] CoercePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] TypeTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] LambdaPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] VarSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewUnionCasePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Object,System.Type]] ValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewObjectPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewArrayPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewRecordPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo,Microsoft.FSharp.Quotations.FSharpExpr]] FieldSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.MethodInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] CallPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] PropertyGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] IfThenElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] LetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,Microsoft.FSharp.Quotations.FSharpExpr]] WithValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,System.String]] ValueWithNamePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar],Microsoft.FSharp.Quotations.FSharpExpr]] NewDelegatePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Quotations.FSharpExpr]] PropertySetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ForIntegerRangeLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] TryWithPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Type] DefaultValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsExceptionRepresentation.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsRecord.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsUnion.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] FSharpValue.PreComputeUnionTagReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeRecordReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeUnionReader.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeRecordConstructor.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeUnionConstructor.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Reflection.UnionCaseInfo[] FSharpType.GetUnionCases.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeRecord.Static(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeUnion.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetExceptionFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetRecordFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.ConstructorInfo FSharpValue.PreComputeRecordConstructorInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MemberInfo FSharpValue.PreComputeUnionTagMemberInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MethodInfo FSharpValue.PreComputeUnionConstructorInfo.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetExceptionFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetRecordFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] FSharpValue.GetUnionFields.Static(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsExceptionRepresentation(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsFunction(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsModule(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsRecord(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsTuple(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsUnion(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Microsoft.FSharp.Reflection.UnionCaseInfo[] GetUnionCases(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetExceptionFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetRecordFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] PreComputeUnionTagReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeRecordReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeTupleReader(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeUnionReader(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object] PreComputeRecordFieldReader(System.Reflection.PropertyInfo) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeRecordConstructor(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeTupleConstructor(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeUnionConstructor(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object GetRecordField(System.Object, System.Reflection.PropertyInfo) -Microsoft.FSharp.Reflection.FSharpValue: System.Object GetTupleField(System.Object, Int32) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeFunction(System.Type, Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeRecord(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeTuple(System.Object[], System.Type) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeUnion(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetExceptionFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetRecordFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetTupleFields(System.Object) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.ConstructorInfo PreComputeRecordConstructorInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MemberInfo PreComputeUnionTagMemberInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MethodInfo PreComputeUnionConstructorInfo(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] GetUnionFields(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Type]] PreComputeTupleConstructorInfo(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.PropertyInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,System.Int32]]] PreComputeTuplePropertyInfo(System.Type, Int32) -Microsoft.FSharp.Reflection.UnionCaseInfo: Boolean Equals(System.Object) -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 GetHashCode() -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 Tag -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 get_Tag() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Collections.Generic.IList`1[System.Reflection.CustomAttributeData] GetCustomAttributesData() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes(System.Type) -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Reflection.PropertyInfo[] GetFields() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String Name -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String ToString() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String get_Name() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type DeclaringType -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type get_DeclaringType() -" -#if DEBUG - let expected = - expected + - @"Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult])" -#endif - SurfaceArea.verify expected "coreclr" (System.IO.Path.Combine(__SOURCE_DIRECTORY__,__SOURCE_FILE__)) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.fs new file mode 100644 index 00000000000..3b885f60c33 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.fs @@ -0,0 +1,2508 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Core.UnitTests.Portable.SurfaceArea + +open Xunit +open FSharp.Core.UnitTests.LibraryTestFx + +type SurfaceAreaTest() = + [] + member this.VerifyArea() = + let expected = @" +Microsoft.FSharp.Collections.Array2DModule: Int32 Base1[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: Int32 Base2[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: Int32 Length1[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: Int32 Length2[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: T Get[T](T[,], Int32, Int32) +Microsoft.FSharp.Collections.Array2DModule: TResult[,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]], T[,]) +Microsoft.FSharp.Collections.Array2DModule: TResult[,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,]) +Microsoft.FSharp.Collections.Array2DModule: T[,] Copy[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: T[,] CreateBased[T](Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.Array2DModule: T[,] Create[T](Int32, Int32, T) +Microsoft.FSharp.Collections.Array2DModule: T[,] InitializeBased[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) +Microsoft.FSharp.Collections.Array2DModule: T[,] Initialize[T](Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) +Microsoft.FSharp.Collections.Array2DModule: T[,] Rebase[T](T[,]) +Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreateBased[T](Int32, Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreate[T](Int32, Int32) +Microsoft.FSharp.Collections.Array2DModule: Void CopyTo[T](T[,], Int32, Int32, T[,], Int32, Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array2DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]], T[,]) +Microsoft.FSharp.Collections.Array2DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,]) +Microsoft.FSharp.Collections.Array2DModule: Void Set[T](T[,], Int32, Int32, T) +Microsoft.FSharp.Collections.Array3DModule: Int32 Length1[T](T[,,]) +Microsoft.FSharp.Collections.Array3DModule: Int32 Length2[T](T[,,]) +Microsoft.FSharp.Collections.Array3DModule: Int32 Length3[T](T[,,]) +Microsoft.FSharp.Collections.Array3DModule: T Get[T](T[,,], Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array3DModule: TResult[,,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]]], T[,,]) +Microsoft.FSharp.Collections.Array3DModule: TResult[,,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,,]) +Microsoft.FSharp.Collections.Array3DModule: T[,,] Create[T](Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.Array3DModule: T[,,] Initialize[T](Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]) +Microsoft.FSharp.Collections.Array3DModule: T[,,] ZeroCreate[T](Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array3DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]]], T[,,]) +Microsoft.FSharp.Collections.Array3DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,,]) +Microsoft.FSharp.Collections.Array3DModule: Void Set[T](T[,,], Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.Array4DModule: Int32 Length1[T](T[,,,]) +Microsoft.FSharp.Collections.Array4DModule: Int32 Length2[T](T[,,,]) +Microsoft.FSharp.Collections.Array4DModule: Int32 Length3[T](T[,,,]) +Microsoft.FSharp.Collections.Array4DModule: Int32 Length4[T](T[,,,]) +Microsoft.FSharp.Collections.Array4DModule: T Get[T](T[,,,], Int32, Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) +Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) +Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean Contains[T](T, T[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Boolean IsEmpty[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[], T[]) +Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Int32 Length[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.ArrayModule+Parallel +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], T[], TState) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] SplitAt[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1,T2,T3][] Zip3[T1,T2,T3](T1[], T2[], T3[]) +Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1[],T2[],T3[]] Unzip3[T1,T2,T3](System.Tuple`3[T1,T2,T3][]) +Microsoft.FSharp.Collections.ArrayModule: T Average$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Average[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T ExactlyOne[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Get[T](T[], Int32) +Microsoft.FSharp.Collections.ArrayModule: T Head[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T Item[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T Last[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Max[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Min[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Sum$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) +Microsoft.FSharp.Collections.ArrayModule: T Sum[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult AverageBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult SumBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1[], T2[], T3[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], T1[], T2[], TState) +Microsoft.FSharp.Collections.ArrayModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) +Microsoft.FSharp.Collections.ArrayModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) +Microsoft.FSharp.Collections.ArrayModule: TState[] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) +Microsoft.FSharp.Collections.ArrayModule: TState[] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Append[T](T[], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Concat[T](System.Collections.Generic.IEnumerable`1[T[]]) +Microsoft.FSharp.Collections.ArrayModule: T[] Copy[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Create[T](Int32, T) +Microsoft.FSharp.Collections.ArrayModule: T[] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Distinct[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Empty[T]() +Microsoft.FSharp.Collections.ArrayModule: T[] Except[T](System.Collections.Generic.IEnumerable`1[T], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] GetSubArray[T](T[], Int32, Int32) +Microsoft.FSharp.Collections.ArrayModule: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ArrayModule: T[] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ArrayModule: T[] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.ArrayModule: T[] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.ArrayModule: T[] Reverse[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Singleton[T](T) +Microsoft.FSharp.Collections.ArrayModule: T[] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Skip[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] SortDescending[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Sort[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Tail[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Take[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Truncate[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.ArrayModule: T[] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] ZeroCreate[T](Int32) +Microsoft.FSharp.Collections.ArrayModule: T[][] ChunkBySize[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[][] SplitInto[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[][] Transpose[T](System.Collections.Generic.IEnumerable`1[T[]]) +Microsoft.FSharp.Collections.ArrayModule: T[][] Windowed[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: Void CopyTo[T](T[], Int32, T[], Int32, Int32) +Microsoft.FSharp.Collections.ArrayModule: Void Fill[T](T[], Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) +Microsoft.FSharp.Collections.ArrayModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) +Microsoft.FSharp.Collections.ArrayModule: Void Set[T](T[], Int32, T) +Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) +Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) +Microsoft.FSharp.Collections.ArrayModule: Void SortInPlace[T](T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] InsertAt[T](Int32, T, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] InsertManyAt[T](Int32, System.Collections.Generic.IEnumerable`1[T], T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] RemoveAt[T](Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] RemoveManyAt[T](Int32, Int32, T[]) +Microsoft.FSharp.Collections.ArrayModule: T[] UpdateAt[T](Int32, T, T[]) +Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] FromFunction[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]]) +Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] NonStructural$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]]) +Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] NonStructural[T]() +Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() +Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons +Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsCons +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsEmpty +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsCons() +Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsEmpty() +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetReverseIndex(Int32, Int32) +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Length +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Tag +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Length() +Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Tag() +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1+Tags[T] +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Cons(T, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Empty +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] GetSlice(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Tail +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] TailOrNull +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Empty() +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Tail() +Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_TailOrNull() +Microsoft.FSharp.Collections.FSharpList`1[T]: System.String ToString() +Microsoft.FSharp.Collections.FSharpList`1[T]: T Head +Microsoft.FSharp.Collections.FSharpList`1[T]: T HeadOrDefault +Microsoft.FSharp.Collections.FSharpList`1[T]: T Item [Int32] +Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Head() +Microsoft.FSharp.Collections.FSharpList`1[T]: T get_HeadOrDefault() +Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Item(Int32) +Microsoft.FSharp.Collections.FSharpList`1[T]: Void .ctor(T, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean ContainsKey(TKey) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean IsEmpty +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean TryGetValue(TKey, TValue ByRef) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean get_IsEmpty() +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 Count +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 GetHashCode() +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 get_Count() +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Add(TKey, TValue) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Change(TKey, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpOption`1[TValue],Microsoft.FSharp.Core.FSharpOption`1[TValue]]) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Remove(TKey) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Core.FSharpOption`1[TValue] TryFind(TKey) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.String ToString() +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue Item [TKey] +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue get_Item(TKey) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Void .ctor(System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.Collections.Generic.ICollection`1[TKey] Keys +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.Collections.Generic.ICollection`1[TKey] get_Keys() +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.Collections.Generic.ICollection`1[TValue] Values +Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.Collections.Generic.ICollection`1[TValue] get_Values() +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Contains(T) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsEmpty +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean get_IsEmpty() +Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 Count +Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 get_Count() +Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Add(T) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove(T) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Addition(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Subtraction(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.FSharpSet`1[T]: System.String ToString() +Microsoft.FSharp.Collections.FSharpSet`1[T]: T MaximumElement +Microsoft.FSharp.Collections.FSharpSet`1[T]: T MinimumElement +Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MaximumElement() +Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MinimumElement() +Microsoft.FSharp.Collections.FSharpSet`1[T]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] FromFunctions[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]]) +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] LimitedStructural[T](Int32) +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] NonStructural$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]]) +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] NonStructural[T]() +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Reference[T]() +Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() +Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Int32 Length[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] SplitInto[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Transpose[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Collections.FSharpList`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Concat[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Distinct[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Empty[T]() +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Reverse[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortDescending[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Sort[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Tail[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Take[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2]] Unzip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]]) +Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) +Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] SplitAt[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: System.Tuple`3[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2],Microsoft.FSharp.Collections.FSharpList`1[T3]] Unzip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]]) +Microsoft.FSharp.Collections.ListModule: T Average$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Average[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T ExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Get[T](Microsoft.FSharp.Collections.FSharpList`1[T], Int32) +Microsoft.FSharp.Collections.ListModule: T Head[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Item[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Last[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Max[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Min[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Sum$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T Sum[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TResult AverageBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TResult SumBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], TState) +Microsoft.FSharp.Collections.ListModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) +Microsoft.FSharp.Collections.ListModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) +Microsoft.FSharp.Collections.ListModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] InsertAt[T](Int32, T, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] InsertManyAt[T](Int32, System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] RemoveAt[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] RemoveManyAt[T](Int32, Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] UpdateAt[T](Int32, T, Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.MapModule: Boolean ContainsKey[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Boolean Exists[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Boolean ForAll[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Boolean IsEmpty[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Int32 Count[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]] ToList[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TResult] Map[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Add[TKey,T](TKey, T, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Change[TKey,T](TKey, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpOption`1[T],Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Empty[TKey,T]() +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Filter[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfArray[TKey,T](System.Tuple`2[TKey,T][]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfList[TKey,T](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfSeq[TKey,T](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Remove[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TKey] TryFindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]] ToSeq[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpMap`2[TKey,T],Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]] Partition[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: System.Tuple`2[TKey,T][] ToArray[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: T Find[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: TKey FindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) +Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: System.Collections.Generic.ICollection`1[TKey] Keys[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.MapModule: System.Collections.Generic.ICollection`1[T] Values[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Int32 Length[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Collections.Generic.IEnumerable`1[T]] Transpose[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] ChunkBySize[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] SplitInto[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] Windowed[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Append[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cache[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cast[T](System.Collections.IEnumerable) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Concat[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Collections.Generic.IEnumerable`1[T]]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Distinct[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Empty[T]() +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] ReadOnly[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Reverse[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Skip[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortDescending[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Sort[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Tail[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Take[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Truncate[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], System.Collections.Generic.IEnumerable`1[T], TState) +Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Average$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Average[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T ExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Get[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Head[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Item[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Last[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Max[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Min[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Sum$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T Sum[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TResult AverageBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TResult SumBy$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[TResult,TResult]], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], TState) +Microsoft.FSharp.Collections.SeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) +Microsoft.FSharp.Collections.SeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: T[] ToArray[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) +Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] InsertAt[T](Int32, T, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] InsertManyAt[T](Int32, System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] RemoveAt[T](Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] RemoveManyAt[T](Int32, Int32, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] UpdateAt[T](Int32, T, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean IsProperSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean IsProperSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean IsSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Boolean IsSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Int32 Count[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Add[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Difference[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Empty[T]() +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] IntersectMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Intersect[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] UnionMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) +Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Union[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpSet`1[T],Microsoft.FSharp.Collections.FSharpSet`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: T MaxElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: T MinElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpSet`1[T], TState) +Microsoft.FSharp.Collections.SetModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Collections.SetModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean IsCancellationRequested +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean get_IsCancellationRequested() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnCancellation() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnSuccess(T) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn Success(Microsoft.FSharp.Control.AsyncActivation`1[T], T) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Void OnExceptionRaised() +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Bind[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn CallThenInvoke[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], TResult, Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Invoke[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Control.AsyncActivation`1[T]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryFinally[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryWith[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.FSharpAsync`1[T] MakeAsync[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.AsyncActivation`1[T],Microsoft.FSharp.Control.AsyncReturn]) +Microsoft.FSharp.Control.BackgroundTaskBuilder: System.Threading.Tasks.Task`1[T] RunDynamic[T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T]) +Microsoft.FSharp.Control.BackgroundTaskBuilder: System.Threading.Tasks.Task`1[T] Run[T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T]) +Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncWrite(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncReadBytes(System.IO.Stream, Int32) +Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Int32] AsyncRead(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.CommonExtensions: System.IDisposable SubscribeToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.CommonExtensions: Void AddToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[T,T]],System.Tuple`2[T,T]] Pairwise[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Choose[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Map[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Scan[TResult,T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Filter[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Merge[TDel1,T,TDel2](Microsoft.FSharp.Control.IEvent`2[TDel1,T], Microsoft.FSharp.Control.IEvent`2[TDel2,T]) +Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult1],TResult1],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult2],TResult2]] Split[T,TResult1,TResult2,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T]] Partition[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.EventModule: Void Add[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.IEvent`2[TDel,T]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Control.FSharpAsync`1[T]] StartChild[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpChoice`2[T,System.Exception]] Catch[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] Choice[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AwaitTask(System.Threading.Tasks.Task) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Ignore[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(Int32) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(System.TimeSpan) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToContext(System.Threading.SynchronizationContext) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToNewThread() +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToThreadPool() +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitIAsyncResult(System.IAsyncResult, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitWaitHandle(System.Threading.WaitHandle, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.IDisposable] OnCancel(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] CancellationToken +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] get_CancellationToken() +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.Tasks.Task`1[T]] StartChildAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Sequential[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitEvent[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitTask[T](System.Threading.Tasks.Task`1[T]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,TArg3,T](TArg1, TArg2, TArg3, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[TArg1,TArg2,TArg3,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,T](TArg1, TArg2, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[TArg1,TArg2,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,T](TArg1, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg1,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromContinuations[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]],Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] TryCancelled[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken DefaultCancellationToken +Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken get_DefaultCancellationToken() +Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartImmediateAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsync: System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg,System.AsyncCallback,System.Object],System.IAsyncResult],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,Microsoft.FSharp.Core.Unit]] AsBeginEnd[TArg,T](Microsoft.FSharp.Core.FSharpFunc`2[TArg,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.FSharpAsync: T RunSynchronously[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsync: Void CancelDefaultToken() +Microsoft.FSharp.Control.FSharpAsync: Void Start(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsync: Void StartImmediate(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsync: Void StartWithContinuations[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] For[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] While(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Zero() +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Bind[T,TResult](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Combine[T](Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.FSharpAsync`1[T]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] ReturnFrom[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Return[T](T) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryFinally[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryWith[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply]: Void Reply(TReply) +Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] Publish +Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] get_Publish() +Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void .ctor() +Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void Trigger(System.Object[]) +Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Publish +Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] get_Publish() +Microsoft.FSharp.Control.FSharpEvent`1[T]: Void .ctor() +Microsoft.FSharp.Control.FSharpEvent`1[T]: Void Trigger(T) +Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] Publish +Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] get_Publish() +Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void .ctor() +Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void Trigger(System.Object, TArgs) +Microsoft.FSharp.Control.FSharpHandler`1[T]: System.IAsyncResult BeginInvoke(System.Object, T, System.AsyncCallback, System.Object) +Microsoft.FSharp.Control.FSharpHandler`1[T]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Control.FSharpHandler`1[T]: Void EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Control.FSharpHandler`1[T]: Void Invoke(System.Object, T) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 CurrentQueueLength +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 DefaultTimeout +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_CurrentQueueLength() +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_DefaultTimeout() +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TMsg]] TryReceive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TReply]] PostAndTryAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] TryScan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TMsg] Receive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Start() +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void add_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void remove_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void set_DefaultTimeout(Int32) +Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void AddHandler(TDelegate) +Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void RemoveHandler(TDelegate) +Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] CreateFromValue[T](T) +Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] Create[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +Microsoft.FSharp.Control.LazyExtensions: T Force[T](System.Lazy`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IDisposable Subscribe[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[System.Tuple`2[T,T]] Pairwise[T](System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Scan[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Merge[T](System.IObservable`1[T], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[TResult1],System.IObservable`1[TResult2]] Split[T,TResult1,TResult2](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[T],System.IObservable`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) +Microsoft.FSharp.Control.ObservableModule: Void Add[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) +Microsoft.FSharp.Control.TaskBuilder: System.Threading.Tasks.Task`1[T] RunDynamic[T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T]) +Microsoft.FSharp.Control.TaskBuilder: System.Threading.Tasks.Task`1[T] Run[T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit] For[T,TOverall](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit] While[TOverall](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit] Zero[TOverall]() +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] Combine[TOverall,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] Delay[TOverall,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T]]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] TryFinally[TOverall,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] TryWith[TOverall,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T]]) +Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T] Return[T](T) +Microsoft.FSharp.Control.TaskBuilderExtensions.HighPriority: Boolean TaskBuilderBase.BindDynamic.Static[TOverall,TResult1,TResult2](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall]] ByRef, System.Threading.Tasks.Task`1[TResult1], Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.HighPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2] TaskBuilderBase.Bind[TResult1,TOverall,TResult2](Microsoft.FSharp.Control.TaskBuilderBase, System.Threading.Tasks.Task`1[TResult1], Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.HighPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T] TaskBuilderBase.ReturnFrom[T](Microsoft.FSharp.Control.TaskBuilderBase, System.Threading.Tasks.Task`1[T]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Boolean TaskBuilderBase.BindDynamic.Static$W[TTaskLike,TResult1,TResult2,TAwaiter,TOverall](Microsoft.FSharp.Core.FSharpFunc`2[TTaskLike,TAwaiter], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,TResult1], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,System.Boolean], Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall]] ByRef, TTaskLike, Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Boolean TaskBuilderBase.BindDynamic.Static[TTaskLike,TResult1,TResult2,TAwaiter,TOverall](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall]] ByRef, TTaskLike, Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2] TaskBuilderBase.Bind$W[TTaskLike,TResult1,TResult2,TAwaiter,TOverall](Microsoft.FSharp.Core.FSharpFunc`2[TTaskLike,TAwaiter], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,TResult1], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,System.Boolean], Microsoft.FSharp.Control.TaskBuilderBase, TTaskLike, Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2] TaskBuilderBase.Bind[TTaskLike,TResult1,TResult2,TAwaiter,TOverall](Microsoft.FSharp.Control.TaskBuilderBase, TTaskLike, Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] TaskBuilderBase.Using[TResource,TOverall,T](Microsoft.FSharp.Control.TaskBuilderBase, TResource, Microsoft.FSharp.Core.FSharpFunc`2[TResource,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T] TaskBuilderBase.ReturnFrom$W[TTaskLike,TAwaiter,T](Microsoft.FSharp.Core.FSharpFunc`2[TTaskLike,TAwaiter], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,T], Microsoft.FSharp.Core.FSharpFunc`2[TAwaiter,System.Boolean], Microsoft.FSharp.Control.TaskBuilderBase, TTaskLike) +Microsoft.FSharp.Control.TaskBuilderExtensions.LowPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T] TaskBuilderBase.ReturnFrom[TTaskLike,TAwaiter,T](Microsoft.FSharp.Control.TaskBuilderBase, TTaskLike) +Microsoft.FSharp.Control.TaskBuilderExtensions.MediumPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2] TaskBuilderBase.Bind[TResult1,TOverall,TResult2](Microsoft.FSharp.Control.TaskBuilderBase, Microsoft.FSharp.Control.FSharpAsync`1[TResult1], Microsoft.FSharp.Core.FSharpFunc`2[TResult1,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],TResult2]]) +Microsoft.FSharp.Control.TaskBuilderExtensions.MediumPriority: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[T],T] TaskBuilderBase.ReturnFrom[T](Microsoft.FSharp.Control.TaskBuilderBase, Microsoft.FSharp.Control.FSharpAsync`1[T]) +Microsoft.FSharp.Control.TaskBuilderModule: Microsoft.FSharp.Control.BackgroundTaskBuilder backgroundTask +Microsoft.FSharp.Control.TaskBuilderModule: Microsoft.FSharp.Control.BackgroundTaskBuilder get_backgroundTask() +Microsoft.FSharp.Control.TaskBuilderModule: Microsoft.FSharp.Control.TaskBuilder get_task() +Microsoft.FSharp.Control.TaskBuilderModule: Microsoft.FSharp.Control.TaskBuilder task +Microsoft.FSharp.Control.TaskStateMachineData`1[T]: System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[T] MethodBuilder +Microsoft.FSharp.Control.TaskStateMachineData`1[T]: T Result +Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncDownloadFile(System.Net.WebClient, System.Uri, System.String) +Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncDownloadData(System.Net.WebClient, System.Uri) +Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Net.WebResponse] AsyncGetResponse(System.Net.WebRequest) +Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.String] AsyncDownloadString(System.Net.WebClient, System.Uri) +Microsoft.FSharp.Core.AbstractClassAttribute: Void .ctor() +Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Value +Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean get_Value() +Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor() +Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.AutoOpenAttribute: System.String Path +Microsoft.FSharp.Core.AutoOpenAttribute: System.String get_Path() +Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor() +Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean Value +Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean get_Value() +Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+In +Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+InOut +Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+Out +Microsoft.FSharp.Core.CLIEventAttribute: Void .ctor() +Microsoft.FSharp.Core.CLIMutableAttribute: Void .ctor() +Microsoft.FSharp.Core.ClassAttribute: Void .ctor() +Microsoft.FSharp.Core.ComparisonConditionalOnAttribute: Void .ctor() +Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] Counts +Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] get_Counts() +Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: Void .ctor(Int32[]) +Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 SequenceNumber +Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 VariantNumber +Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_SequenceNumber() +Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_VariantNumber() +Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags SourceConstructFlags +Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags get_SourceConstructFlags() +Microsoft.FSharp.Core.CompilationMappingAttribute: System.String ResourceName +Microsoft.FSharp.Core.CompilationMappingAttribute: System.String get_ResourceName() +Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] TypeDefinitions +Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] get_TypeDefinitions() +Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags) +Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32) +Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32, Int32) +Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(System.String, System.Type[]) +Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags Flags +Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags get_Flags() +Microsoft.FSharp.Core.CompilationRepresentationAttribute: Void .ctor(Microsoft.FSharp.Core.CompilationRepresentationFlags) +Microsoft.FSharp.Core.CompilationRepresentationFlags: Int32 value__ +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Event +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Instance +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags ModuleSuffix +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags None +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Static +Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags UseNullAsTrueValue +Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String SourceName +Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String get_SourceName() +Microsoft.FSharp.Core.CompilationSourceNameAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.CompiledNameAttribute: System.String CompiledName +Microsoft.FSharp.Core.CompiledNameAttribute: System.String get_CompiledName() +Microsoft.FSharp.Core.CompiledNameAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsError +Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsHidden +Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsError() +Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsHidden() +Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 MessageNumber +Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 get_MessageNumber() +Microsoft.FSharp.Core.CompilerMessageAttribute: System.String Message +Microsoft.FSharp.Core.CompilerMessageAttribute: System.String get_Message() +Microsoft.FSharp.Core.CompilerMessageAttribute: Void .ctor(System.String, Int32) +Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsError(Boolean) +Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsHidden(Boolean) +Microsoft.FSharp.Core.CompilerServices.AfterCode`2[TData,TResult]: System.IAsyncResult BeginInvoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.AsyncCallback, System.Object) +Microsoft.FSharp.Core.CompilerServices.AfterCode`2[TData,TResult]: TResult EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Core.CompilerServices.AfterCode`2[TData,TResult]: TResult Invoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.AfterCode`2[TData,TResult]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1[T]: T[] Close() +Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1[T]: Void Add(T) +Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1[T]: Void AddMany(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.CompilerServices.ArrayCollector`1[T]: T[] AddManyAndClose(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.CompilerServices.ListCollector`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Close() +Microsoft.FSharp.Core.CompilerServices.ListCollector`1[T]: Void Add(T) +Microsoft.FSharp.Core.CompilerServices.ListCollector`1[T]: Void AddMany(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.CompilerServices.ListCollector`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] AddManyAndClose(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean CheckClose +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T get_LastGenerated() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void .ctor() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void Close() +Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNestedNamespaces() +Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String NamespaceName +Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String get_NamespaceName() +Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type ResolveTypeName(System.String) +Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type[] GetTypes() +Microsoft.FSharp.Core.CompilerServices.IResumableStateMachine`1[TData]: Int32 ResumptionPoint +Microsoft.FSharp.Core.CompilerServices.IResumableStateMachine`1[TData]: Int32 get_ResumptionPoint() +Microsoft.FSharp.Core.CompilerServices.IResumableStateMachine`1[TData]: TData Data +Microsoft.FSharp.Core.CompilerServices.IResumableStateMachine`1[TData]: TData get_Data() +Microsoft.FSharp.Core.CompilerServices.IResumableStateMachine`1[TData]: Void set_Data(TData) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.MethodBase ApplyStaticArgumentsForMethod(System.Reflection.MethodBase, System.String, System.Object[]) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.ParameterInfo[] GetStaticParametersForMethod(System.Reflection.MethodBase) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Byte[] GetGeneratedAssemblyContents(System.Reflection.Assembly) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNamespaces() +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Quotations.FSharpExpr GetInvokerExpression(System.Reflection.MethodBase, Microsoft.FSharp.Quotations.FSharpExpr[]) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.EventHandler Invalidate +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Reflection.ParameterInfo[] GetStaticParameters(System.Type) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Type ApplyStaticArguments(System.Type, System.String[], System.Object[]) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void add_Invalidate(System.EventHandler) +Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void remove_Invalidate(System.EventHandler) +Microsoft.FSharp.Core.CompilerServices.MoveNextMethodImpl`1[TData]: System.IAsyncResult BeginInvoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.AsyncCallback, System.Object) +Microsoft.FSharp.Core.CompilerServices.MoveNextMethodImpl`1[TData]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Core.CompilerServices.MoveNextMethodImpl`1[TData]: Void EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Core.CompilerServices.MoveNextMethodImpl`1[TData]: Void Invoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Boolean CombineDynamic[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Boolean TryFinallyAsyncDynamic[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Boolean TryWithDynamic[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Boolean WhileDynamic[TData](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Boolean YieldDynamic[TData](Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit] For[T,TData](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit] While[TData](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit] Yield[TData]() +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit] Zero[TData]() +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] Combine[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] Delay[TData,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] TryFinallyAsync[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] TryFinally[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T], Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] TryWith[TData,T](Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T] Using[TResource,TData,T](TResource, Microsoft.FSharp.Core.FSharpFunc`2[TResource,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]]) +Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]: Boolean EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]: Boolean Invoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]: System.IAsyncResult BeginInvoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.AsyncCallback, System.Object) +Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[TData,T]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData]: Int32 ResumptionPoint +Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData]: Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData] ResumptionDynamicInfo +Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData]: TData Data +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData] ResumptionFunc +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData] get_ResumptionFunc() +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: System.Object ResumptionData +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: System.Object get_ResumptionData() +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Void .ctor(Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]) +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Void MoveNext(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Void SetStateMachine(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.Runtime.CompilerServices.IAsyncStateMachine) +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Void set_ResumptionData(System.Object) +Microsoft.FSharp.Core.CompilerServices.ResumptionDynamicInfo`1[TData]: Void set_ResumptionFunc(Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]) +Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]: Boolean EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]: Boolean Invoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef) +Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]: System.IAsyncResult BeginInvoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.AsyncCallback, System.Object) +Microsoft.FSharp.Core.CompilerServices.ResumptionFunc`1[TData]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] CreateEvent[TDelegate,TArgs](Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[System.Object,Microsoft.FSharp.Core.FSharpFunc`2[TArgs,Microsoft.FSharp.Core.Unit]],TDelegate]) +Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateFromFunctions[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) +Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateUsing[T,TCollection,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection]) +Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateThenFinally[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.CompilerServices.SetStateMachineMethodImpl`1[TData]: System.IAsyncResult BeginInvoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.Runtime.CompilerServices.IAsyncStateMachine, System.AsyncCallback, System.Object) +Microsoft.FSharp.Core.CompilerServices.SetStateMachineMethodImpl`1[TData]: Void .ctor(System.Object, IntPtr) +Microsoft.FSharp.Core.CompilerServices.SetStateMachineMethodImpl`1[TData]: Void EndInvoke(System.IAsyncResult) +Microsoft.FSharp.Core.CompilerServices.SetStateMachineMethodImpl`1[TData]: Void Invoke(Microsoft.FSharp.Core.CompilerServices.ResumableStateMachine`1[TData] ByRef, System.Runtime.CompilerServices.IAsyncStateMachine) +Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers: Boolean __useResumableCode[T]() +Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] __resumableEntry() +Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers: T __resumeAt[T](Int32) +Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers: TResult __stateMachine[TData,TResult](Microsoft.FSharp.Core.CompilerServices.MoveNextMethodImpl`1[TData], Microsoft.FSharp.Core.CompilerServices.SetStateMachineMethodImpl`1[TData], Microsoft.FSharp.Core.CompilerServices.AfterCode`2[TData,TResult]) +Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String AssemblyName +Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String get_AssemblyName() +Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor() +Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderAttribute: Void .ctor() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsHostedExecution +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsInvalidationSupported +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean SystemRuntimeContainsType(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsHostedExecution() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsInvalidationSupported() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String ResolutionFolder +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String RuntimeAssembly +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String TemporaryFolder +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_ResolutionFolder() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_RuntimeAssembly() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_TemporaryFolder() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] ReferencedAssemblies +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] get_ReferencedAssemblies() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version SystemRuntimeAssemblyVersion +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version get_SystemRuntimeAssemblyVersion() +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean]) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsHostedExecution(Boolean) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsInvalidationSupported(Boolean) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ReferencedAssemblies(System.String[]) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ResolutionFolder(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_RuntimeAssembly(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_SystemRuntimeAssemblyVersion(System.Version) +Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_TemporaryFolder(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Column +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Line +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Column() +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Line() +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String FilePath +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String get_FilePath() +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void .ctor() +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Column(Int32) +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_FilePath(System.String) +Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Line(Int32) +Microsoft.FSharp.Core.CompilerServices.TypeProviderEditorHideMethodsAttribute: Void .ctor() +Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Int32 value__ +Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes IsErased +Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes SuppressRelocate +Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String CommentText +Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String get_CommentText() +Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.CustomComparisonAttribute: Void .ctor() +Microsoft.FSharp.Core.CustomEqualityAttribute: Void .ctor() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean AllowIntoPattern +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeGroupJoin +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeJoin +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeZip +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpace +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpaceUsingBind +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_AllowIntoPattern() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeGroupJoin() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeJoin() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeZip() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpace() +Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpaceUsingBind() +Microsoft.FSharp.Core.CustomOperationAttribute: System.String JoinConditionWord +Microsoft.FSharp.Core.CustomOperationAttribute: System.String Name +Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_JoinConditionWord() +Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_Name() +Microsoft.FSharp.Core.CustomOperationAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_AllowIntoPattern(Boolean) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeGroupJoin(Boolean) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeJoin(Boolean) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeZip(Boolean) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_JoinConditionWord(System.String) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpace(Boolean) +Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpaceUsingBind(Boolean) +Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean Value +Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean get_Value() +Microsoft.FSharp.Core.DefaultAugmentationAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.DefaultValueAttribute: Boolean Check +Microsoft.FSharp.Core.DefaultValueAttribute: Boolean get_Check() +Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor() +Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.EntryPointAttribute: Void .ctor() +Microsoft.FSharp.Core.EqualityConditionalOnAttribute: Void .ctor() +Microsoft.FSharp.Core.ExperimentalAttribute: System.String Message +Microsoft.FSharp.Core.ExperimentalAttribute: System.String get_Message() +Microsoft.FSharp.Core.ExperimentalAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: Byte ToByte[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: SByte ToSByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: SByte ToSByte[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Byte ToByte[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Double ToDouble$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Double], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Double ToDouble[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Collections.FSharpSet`1[T] CreateSet[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder DefaultAsyncBuilder +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder get_DefaultAsyncBuilder() +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder get_query() +Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder query +Microsoft.FSharp.Core.ExtraTopLevelOperators: SByte ToSByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: SByte ToSByte[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Single ToSingle$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Single], T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: Single ToSingle[T](T) +Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IDictionary`2[TKey,TValue] CreateDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IReadOnlyDictionary`2[TKey,TValue] CreateReadOnlyDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T LazyPattern[T](System.Lazy`1[T]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToString[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?]) +Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice1Of2 +Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice2Of2 +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice1Of2 +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice2Of2 +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice1Of2() +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice2Of2() +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2] +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2] +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2] +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice1Of2(T1) +Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice2Of2(T2) +Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 Item +Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 get_Item() +Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice1Of3 +Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice2Of3 +Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice3Of3 +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice1Of3 +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice2Of3 +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice3Of3 +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice1Of3() +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice2Of3() +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice3Of3() +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3] +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3] +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3] +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3] +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice1Of3(T1) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice2Of3(T2) +Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice3Of3(T3) +Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 Item +Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 get_Item() +Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 Item +Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 get_Item() +Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice1Of4 +Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice2Of4 +Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice3Of4 +Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice4Of4 +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice1Of4 +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice2Of4 +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice3Of4 +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice4Of4 +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4] +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4] +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4] +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4] +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4] +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice1Of4(T1) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice2Of4(T2) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice3Of4(T3) +Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice4Of4(T4) +Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 Item +Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 get_Item() +Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 Item +Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 get_Item() +Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 Item +Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 get_Item() +Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice1Of5 +Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice2Of5 +Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice3Of5 +Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice4Of5 +Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice5Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5] +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice1Of5(T1) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice2Of5(T2) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice3Of5(T3) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice4Of5(T4) +Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice5Of5(T5) +Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 Item +Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 get_Item() +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice1Of6 +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice2Of6 +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice3Of6 +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice4Of6 +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice5Of6 +Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice6Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6] +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice1Of6(T1) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice2Of6(T2) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice3Of6(T3) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice4Of6(T4) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice5Of6(T5) +Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice6Of6(T6) +Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 Item +Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item() +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice1Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice2Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice3Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice4Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice5Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice6Of7 +Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice7Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7] +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice1Of7(T1) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice2Of7(T2) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice3Of7(T3) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice4Of7(T4) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice5Of7(T5) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice6Of7(T6) +Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice7Of7(T7) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromConverter(System.Converter`2[T,TResult]) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] op_Implicit(System.Converter`2[T,TResult]) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] ToConverter(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] op_Implicit(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: TResult Invoke(T) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: V InvokeFast[V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], T, TResult) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: W InvokeFast[V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], T, TResult, V) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: X InvokeFast[V,W,X](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,X]]]], T, TResult, V, W) +Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Y InvokeFast[V,W,X,Y](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,Microsoft.FSharp.Core.FSharpFunc`2[X,Y]]]]], T, TResult, V, W, X) +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Major +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Minor +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Release +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Major() +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Minor() +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Release() +Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Void .ctor(Int32, Int32, Int32) +Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 None +Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 Some +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsNone +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsSome +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsNone(Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsSome(Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetTag(Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1+Tags[T] +Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] None +Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] Some(T) +Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] get_None() +Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] op_Implicit(T) +Microsoft.FSharp.Core.FSharpOption`1[T]: System.String ToString() +Microsoft.FSharp.Core.FSharpOption`1[T]: T Value +Microsoft.FSharp.Core.FSharpOption`1[T]: T get_Value() +Microsoft.FSharp.Core.FSharpOption`1[T]: Void .ctor(T) +Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpRef`1[T]) +Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpRef`1[T]) +Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpRef`1[T]: T Value +Microsoft.FSharp.Core.FSharpRef`1[T]: T contents +Microsoft.FSharp.Core.FSharpRef`1[T]: T contents@ +Microsoft.FSharp.Core.FSharpRef`1[T]: T get_Value() +Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents() +Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T) +Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T) +Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T) +Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error +Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError() +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk() +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError] +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T) +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T ResultValue +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T get_ResultValue() +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError ErrorValue +Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError get_ErrorValue() +Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]() +Microsoft.FSharp.Core.FSharpTypeFunc: Void .ctor() +Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueNone +Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueSome +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsNone +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsSome +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueNone +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueSome +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsNone() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsSome() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueNone() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueSome() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 Tag +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 get_Tag() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T] +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] NewValueSome(T) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] None +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] Some(T) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] ValueNone +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_None() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_ValueNone() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] op_Implicit(T) +Microsoft.FSharp.Core.FSharpValueOption`1[T]: System.String ToString() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Item +Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Value +Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Item() +Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Value() +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit] FromAction(System.Action) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T] FromFunc[T](System.Func`1[T]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] FromAction[T](System.Action`1[T]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] ToFSharpFunc[T](System.Action`1[T]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromFunc[T,TResult](System.Func`2[T,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] ToFSharpFunc[T,TResult](System.Converter`2[T,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,Microsoft.FSharp.Core.Unit]]]]] FromAction[T1,T2,T3,T4,T5](System.Action`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FromFunc[T1,T2,T3,T4,T5,TResult](System.Func`6[T1,T2,T3,T4,T5,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FuncFromTupled[T1,T2,T3,T4,T5,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[T1,T2,T3,T4,T5],TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.Unit]]]] FromAction[T1,T2,T3,T4](System.Action`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FromFunc[T1,T2,T3,T4,TResult](System.Func`5[T1,T2,T3,T4,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FuncFromTupled[T1,T2,T3,T4,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[T1,T2,T3,T4],TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.Unit]]] FromAction[T1,T2,T3](System.Action`3[T1,T2,T3]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FromFunc[T1,T2,T3,TResult](System.Func`4[T1,T2,T3,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FuncFromTupled[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[T1,T2,T3],TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]] FromAction[T1,T2](System.Action`2[T1,T2]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FromFunc[T1,T2,TResult](System.Func`3[T1,T2,TResult]) +Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FuncFromTupled[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[T1,T2],TResult]) +Microsoft.FSharp.Core.GeneralizableValueAttribute: Void .ctor() +Microsoft.FSharp.Core.InlineIfLambdaAttribute: Void .ctor() +Microsoft.FSharp.Core.InterfaceAttribute: Void .ctor() +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String AddressOpNotFirstClassString +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputArrayEmptyString +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputMustBeNonNegativeString +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputSequenceEmptyString +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String NoNegateMinValueString +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_AddressOpNotFirstClassString() +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputArrayEmptyString() +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputMustBeNonNegativeString() +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputSequenceEmptyString() +Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_NoNegateMinValueString() +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityERIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterOrEqualIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterThanIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessOrEqualIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessThanIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean PhysicalEqualityIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple2[T1,T2](System.Collections.IComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple3[T1,T2,T3](System.Collections.IComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple4[T1,T2,T3,T4](System.Collections.IComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple5[T1,T2,T3,T4,T5](System.Collections.IComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5]) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonIntrinsic[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonWithComparerIntrinsic[T](System.Collections.IComparer, T, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashIntrinsic[T](T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 LimitedGenericHashIntrinsic[T](Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 PhysicalHashIntrinsic[T](T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestFast[T](System.Object) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestGeneric[T](System.Object) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Char GetString(System.String, Int32) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: System.Decimal MakeDecimal(Int32, Int32, Int32, Boolean, Byte) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CheckThis[T](T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CreateInstance[T]() +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray2D[T](T[,], Int32, Int32) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray3D[T](T[,,], Int32, Int32, Int32) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray4D[T](T[,,,], Int32, Int32, Int32, Int32) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray[T](T[], Int32) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxFast[T](System.Object) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxGeneric[T](System.Object) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void Dispose[T](T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailInit() +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailStaticInit() +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray2D[T](T[,], Int32, Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray3D[T](T[,,], Int32, Int32, Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray4D[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray[T](T[], Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean Or(Boolean, Boolean) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_Amp(Boolean, Boolean) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanAnd(Boolean, Boolean) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanOr(Boolean, Boolean) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: IntPtr op_IntegerAddressOf[T](T) +Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: T& op_AddressOf[T](T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityER[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityWithComparer[T](System.Collections.IEqualityComparer, T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEquality[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterOrEqual[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterThan[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessOrEqual[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessThan[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Boolean PhysicalEquality[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Byte ByteWithMeasure(Byte) +Microsoft.FSharp.Core.LanguagePrimitives: Double FloatWithMeasure(Double) +Microsoft.FSharp.Core.LanguagePrimitives: Int16 Int16WithMeasure(Int16) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparisonWithComparer[T](System.Collections.IComparer, T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparison[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHashWithComparer[T](System.Collections.IEqualityComparer, T) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHash[T](T) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericLimitedHash[T](Int32, T) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 Int32WithMeasure(Int32) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 ParseInt32(System.String) +Microsoft.FSharp.Core.LanguagePrimitives: Int32 PhysicalHash[T](T) +Microsoft.FSharp.Core.LanguagePrimitives: Int64 Int64WithMeasure(Int64) +Microsoft.FSharp.Core.LanguagePrimitives: Int64 ParseInt64(System.String) +Microsoft.FSharp.Core.LanguagePrimitives: IntPtr IntPtrWithMeasure(IntPtr) +Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings +Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+HashCompare +Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions +Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators +Microsoft.FSharp.Core.LanguagePrimitives: SByte SByteWithMeasure(SByte) +Microsoft.FSharp.Core.LanguagePrimitives: Single Float32WithMeasure(Single) +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparerFromTable[T]() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparer[T]() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparerFromTable[T]() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparer[T]() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastLimitedGenericEqualityComparer[T](Int32) +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer GenericComparer +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer get_GenericComparer() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityComparer +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityERComparer +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityComparer() +Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityERComparer() +Microsoft.FSharp.Core.LanguagePrimitives: System.Decimal DecimalWithMeasure(System.Decimal) +Microsoft.FSharp.Core.LanguagePrimitives: T DivideByInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], T, Int32) +Microsoft.FSharp.Core.LanguagePrimitives: T DivideByIntDynamic[T](T, Int32) +Microsoft.FSharp.Core.LanguagePrimitives: T DivideByInt[T](T, Int32) +Microsoft.FSharp.Core.LanguagePrimitives: T EnumToValue[TEnum,T](TEnum) +Microsoft.FSharp.Core.LanguagePrimitives: T GenericMaximum[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: T GenericMinimum[T](T, T) +Microsoft.FSharp.Core.LanguagePrimitives: T GenericOne$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +Microsoft.FSharp.Core.LanguagePrimitives: T GenericOneDynamic[T]() +Microsoft.FSharp.Core.LanguagePrimitives: T GenericOne[T]() +Microsoft.FSharp.Core.LanguagePrimitives: T GenericZero$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +Microsoft.FSharp.Core.LanguagePrimitives: T GenericZeroDynamic[T]() +Microsoft.FSharp.Core.LanguagePrimitives: T GenericZero[T]() +Microsoft.FSharp.Core.LanguagePrimitives: TEnum EnumOfValue[T,TEnum](T) +Microsoft.FSharp.Core.LanguagePrimitives: TResult AdditionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult BitwiseAndDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult BitwiseOrDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedAdditionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedMultiplyDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedSubtractionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedUnaryNegationDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: TResult DivisionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult EqualityDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult ExclusiveOrDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult ExplicitDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: TResult GreaterThanDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult GreaterThanOrEqualDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult InequalityDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult LeftShiftDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult LessThanDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult LessThanOrEqualDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult LogicalNotDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: TResult ModulusDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult MultiplyDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult RightShiftDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult SubtractionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult UnaryNegationDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: UInt16 UInt16WithMeasure(UInt16) +Microsoft.FSharp.Core.LanguagePrimitives: UInt32 ParseUInt32(System.String) +Microsoft.FSharp.Core.LanguagePrimitives: UInt32 UInt32WithMeasure(UInt32) +Microsoft.FSharp.Core.LanguagePrimitives: UInt64 ParseUInt64(System.String) +Microsoft.FSharp.Core.LanguagePrimitives: UInt64 UInt64WithMeasure(UInt64) +Microsoft.FSharp.Core.LanguagePrimitives: UIntPtr UIntPtrWithMeasure(UIntPtr) +Microsoft.FSharp.Core.LiteralAttribute: Void .ctor() +Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object) +Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object, System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.MatchFailureException: Int32 Data1 +Microsoft.FSharp.Core.MatchFailureException: Int32 Data2 +Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode() +Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode(System.Collections.IEqualityComparer) +Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data1() +Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data2() +Microsoft.FSharp.Core.MatchFailureException: System.String Data0 +Microsoft.FSharp.Core.MatchFailureException: System.String Message +Microsoft.FSharp.Core.MatchFailureException: System.String get_Data0() +Microsoft.FSharp.Core.MatchFailureException: System.String get_Message() +Microsoft.FSharp.Core.MatchFailureException: Void .ctor() +Microsoft.FSharp.Core.MatchFailureException: Void .ctor(System.String, Int32, Int32) +Microsoft.FSharp.Core.MeasureAnnotatedAbbreviationAttribute: Void .ctor() +Microsoft.FSharp.Core.MeasureAttribute: Void .ctor() +Microsoft.FSharp.Core.NoComparisonAttribute: Void .ctor() +Microsoft.FSharp.Core.NoDynamicInvocationAttribute: Void .ctor() +Microsoft.FSharp.Core.NoEqualityAttribute: Void .ctor() +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromInt64Dynamic(Int64) +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromStringDynamic(System.String) +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt32[T](Int32) +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt64[T](Int64) +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromOne[T]() +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromString[T](System.String) +Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromZero[T]() +Microsoft.FSharp.Core.NumericLiterals: Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI +Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 String.GetReverseIndex(System.String, Int32, Int32) +Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,,]`1.GetReverseIndex[T](T[,,,], Int32, Int32) +Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,]`1.GetReverseIndex[T](T[,,], Int32, Int32) +Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,]`1.GetReverseIndex[T](T[,], Int32, Int32) +Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 []`1.GetReverseIndex[T](T[], Int32, Int32) +Microsoft.FSharp.Core.Operators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) +Microsoft.FSharp.Core.Operators+Checked: Byte ToByte[T](T) +Microsoft.FSharp.Core.Operators+Checked: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) +Microsoft.FSharp.Core.Operators+Checked: Char ToChar[T](T) +Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) +Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16[T](T) +Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], T) +Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], T) +Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt32[T](T) +Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt[T](T) +Microsoft.FSharp.Core.Operators+Checked: Int64 ToInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int64], T) +Microsoft.FSharp.Core.Operators+Checked: Int64 ToInt64[T](T) +Microsoft.FSharp.Core.Operators+Checked: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) +Microsoft.FSharp.Core.Operators+Checked: IntPtr ToIntPtr[T](T) +Microsoft.FSharp.Core.Operators+Checked: SByte ToSByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], T) +Microsoft.FSharp.Core.Operators+Checked: SByte ToSByte[T](T) +Microsoft.FSharp.Core.Operators+Checked: T op_UnaryNegation$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators+Checked: T op_UnaryNegation[T](T) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Addition$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Addition[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Multiply$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Multiply[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Subtraction$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators+Checked: T3 op_Subtraction[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators+Checked: UInt16 ToUInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt16], T) +Microsoft.FSharp.Core.Operators+Checked: UInt16 ToUInt16[T](T) +Microsoft.FSharp.Core.Operators+Checked: UInt32 ToUInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt32], T) +Microsoft.FSharp.Core.Operators+Checked: UInt32 ToUInt32[T](T) +Microsoft.FSharp.Core.Operators+Checked: UInt64 ToUInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt64], T) +Microsoft.FSharp.Core.Operators+Checked: UInt64 ToUInt64[T](T) +Microsoft.FSharp.Core.Operators+Checked: UIntPtr ToUIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UIntPtr], T) +Microsoft.FSharp.Core.Operators+Checked: UIntPtr ToUIntPtr[T](T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Equality$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Equality[T](T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThan$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThanOrEqual$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThanOrEqual[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThan[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Inequality$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Inequality[T](T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThan$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThanOrEqual$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThanOrEqual[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThan[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Compare$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Compare[T](T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Hash[T](T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Max$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Max[T](T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Min$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], T, T) +Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Min[T](T, T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Byte PowByte(Byte, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Double PowDouble(Double, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int16 PowInt16(Int16, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 PowInt32(Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 SignDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int64 PowInt64(Int64, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: IntPtr PowIntPtr(IntPtr, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: SByte PowSByte(SByte, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Single PowSingle(Single, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Byte] RangeByte(Byte, Byte, Byte) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Char] RangeChar(Char, Char) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Double] RangeDouble(Double, Double, Double) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int16] RangeInt16(Int16, Int16, Int16) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int32] RangeInt32(Int32, Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int64] RangeInt64(Int64, Int64, Int64) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.IntPtr] RangeIntPtr(IntPtr, IntPtr, IntPtr) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.SByte] RangeSByte(SByte, SByte, SByte) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Single] RangeSingle(Single, Single, Single) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt16] RangeUInt16(UInt16, UInt16, UInt16) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt32] RangeUInt32(UInt32, UInt32, UInt32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt64] RangeUInt64(UInt64, UInt64, UInt64) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UIntPtr] RangeUIntPtr(UIntPtr, UIntPtr, UIntPtr) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeStepGeneric[TStep,T](TStep, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TStep,T]], T, TStep, T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Decimal PowDecimal(System.Decimal, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.String GetStringSlice(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AbsDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AcosDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AsinDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AtanDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CeilingDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CosDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CoshDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T ExpDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T FloorDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T Log10Dynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T LogDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowDynamic[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T RoundDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinhDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanhDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TruncateDynamic[T](T) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 Atan2Dynamic[T1,T2](T1, T1) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 SqrtDynamic[T1,T2](T1) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,,] GetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt16 PowUInt16(UInt16, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt32 PowUInt32(UInt32, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt64 PowUInt64(UInt64, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UIntPtr PowUIntPtr(UIntPtr, Int32) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,,]) +Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) +Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) +Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) +Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) +Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() +Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) +Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) +Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) +Microsoft.FSharp.Core.Operators: Boolean op_GreaterThanOrEqual[T](T, T) +Microsoft.FSharp.Core.Operators: Boolean op_GreaterThan[T](T, T) +Microsoft.FSharp.Core.Operators: Boolean op_Inequality[T](T, T) +Microsoft.FSharp.Core.Operators: Boolean op_LessThanOrEqual[T](T, T) +Microsoft.FSharp.Core.Operators: Boolean op_LessThan[T](T, T) +Microsoft.FSharp.Core.Operators: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) +Microsoft.FSharp.Core.Operators: Byte ToByte[T](T) +Microsoft.FSharp.Core.Operators: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) +Microsoft.FSharp.Core.Operators: Char ToChar[T](T) +Microsoft.FSharp.Core.Operators: Double Infinity +Microsoft.FSharp.Core.Operators: Double NaN +Microsoft.FSharp.Core.Operators: Double ToDouble$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Double], T) +Microsoft.FSharp.Core.Operators: Double ToDouble[T](T) +Microsoft.FSharp.Core.Operators: Double get_Infinity() +Microsoft.FSharp.Core.Operators: Double get_NaN() +Microsoft.FSharp.Core.Operators: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) +Microsoft.FSharp.Core.Operators: Int16 ToInt16[T](T) +Microsoft.FSharp.Core.Operators: Int32 Compare[T](T, T) +Microsoft.FSharp.Core.Operators: Int32 Hash[T](T) +Microsoft.FSharp.Core.Operators: Int32 Sign$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], T) +Microsoft.FSharp.Core.Operators: Int32 Sign[T](T) +Microsoft.FSharp.Core.Operators: Int32 SizeOf[T]() +Microsoft.FSharp.Core.Operators: Int32 ToInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], T) +Microsoft.FSharp.Core.Operators: Int32 ToInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], T) +Microsoft.FSharp.Core.Operators: Int32 ToInt32[T](T) +Microsoft.FSharp.Core.Operators: Int32 ToInt[T](T) +Microsoft.FSharp.Core.Operators: Int32 limitedHash[T](Int32, T) +Microsoft.FSharp.Core.Operators: Int64 ToInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int64], T) +Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) +Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], T) +Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[T] TryUnbox[T](System.Object) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpRef`1[T] Ref[T](T) +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+ArrayExtensions +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Checked +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+NonStructuralComparison +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+OperatorIntrinsics +Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Unchecked +Microsoft.FSharp.Core.Operators: SByte ToSByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], T) +Microsoft.FSharp.Core.Operators: SByte ToSByte[T](T) +Microsoft.FSharp.Core.Operators: Single InfinitySingle +Microsoft.FSharp.Core.Operators: Single NaNSingle +Microsoft.FSharp.Core.Operators: Single ToSingle$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Single], T) +Microsoft.FSharp.Core.Operators: Single ToSingle[T](T) +Microsoft.FSharp.Core.Operators: Single get_InfinitySingle() +Microsoft.FSharp.Core.Operators: Single get_NaNSingle() +Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] CreateSequence[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_Range$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) +Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_RangeStep$W[T,TStep](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TStep], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TStep,T]], T, TStep, T) +Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_RangeStep[T,TStep](T, TStep, T) +Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_Range[T](T, T) +Microsoft.FSharp.Core.Operators: System.Decimal ToDecimal$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Decimal], T) +Microsoft.FSharp.Core.Operators: System.Decimal ToDecimal[T](T) +Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) +Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() +Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() +Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() +Microsoft.FSharp.Core.Operators: System.Object Box[T](T) +Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) +Microsoft.FSharp.Core.Operators: System.String ToString[T](T) +Microsoft.FSharp.Core.Operators: System.String op_Concatenate(System.String, System.String) +Microsoft.FSharp.Core.Operators: System.Tuple`2[TKey,TValue] KeyValuePattern[TKey,TValue](System.Collections.Generic.KeyValuePair`2[TKey,TValue]) +Microsoft.FSharp.Core.Operators: System.Type TypeDefOf[T]() +Microsoft.FSharp.Core.Operators: System.Type TypeOf[T]() +Microsoft.FSharp.Core.Operators: T Abs$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Abs[T](T) +Microsoft.FSharp.Core.Operators: T Acos$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Acos[T](T) +Microsoft.FSharp.Core.Operators: T Asin$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Asin[T](T) +Microsoft.FSharp.Core.Operators: T Atan$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Atan[T](T) +Microsoft.FSharp.Core.Operators: T Ceiling$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Ceiling[T](T) +Microsoft.FSharp.Core.Operators: T Cos$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Cos[T](T) +Microsoft.FSharp.Core.Operators: T Cosh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Cosh[T](T) +Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) +Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) +Microsoft.FSharp.Core.Operators: T Exit[T](Int32) +Microsoft.FSharp.Core.Operators: T Exp$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Exp[T](T) +Microsoft.FSharp.Core.Operators: T FailWith[T](System.String) +Microsoft.FSharp.Core.Operators: T Floor$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Floor[T](T) +Microsoft.FSharp.Core.Operators: T Identity[T](T) +Microsoft.FSharp.Core.Operators: T InvalidArg[T](System.String, System.String) +Microsoft.FSharp.Core.Operators: T InvalidOp[T](System.String) +Microsoft.FSharp.Core.Operators: T Lock[TLock,T](TLock, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) +Microsoft.FSharp.Core.Operators: T Log$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Log10$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Log10[T](T) +Microsoft.FSharp.Core.Operators: T Log[T](T) +Microsoft.FSharp.Core.Operators: T Max[T](T, T) +Microsoft.FSharp.Core.Operators: T Min[T](T, T) +Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) +Microsoft.FSharp.Core.Operators: T PowInteger$W[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) +Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) +Microsoft.FSharp.Core.Operators: T Raise[T](System.Exception) +Microsoft.FSharp.Core.Operators: T Reraise[T]() +Microsoft.FSharp.Core.Operators: T Rethrow[T]() +Microsoft.FSharp.Core.Operators: T Round$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Round[T](T) +Microsoft.FSharp.Core.Operators: T Sin$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Sin[T](T) +Microsoft.FSharp.Core.Operators: T Sinh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Sinh[T](T) +Microsoft.FSharp.Core.Operators: T Tan$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Tan[T](T) +Microsoft.FSharp.Core.Operators: T Tanh$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Tanh[T](T) +Microsoft.FSharp.Core.Operators: T Truncate$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T Truncate[T](T) +Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) +Microsoft.FSharp.Core.Operators: T op_BitwiseAnd$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) +Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) +Microsoft.FSharp.Core.Operators: T op_BitwiseOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) +Microsoft.FSharp.Core.Operators: T op_BitwiseOr[T](T, T) +Microsoft.FSharp.Core.Operators: T op_Dereference[T](Microsoft.FSharp.Core.FSharpRef`1[T]) +Microsoft.FSharp.Core.Operators: T op_ExclusiveOr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) +Microsoft.FSharp.Core.Operators: T op_ExclusiveOr[T](T, T) +Microsoft.FSharp.Core.Operators: T op_Exponentiation$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,T]], T, TResult) +Microsoft.FSharp.Core.Operators: T op_Exponentiation[T,TResult](T, TResult) +Microsoft.FSharp.Core.Operators: T op_LeftShift$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], T, Int32) +Microsoft.FSharp.Core.Operators: T op_LeftShift[T](T, Int32) +Microsoft.FSharp.Core.Operators: T op_LogicalNot$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T op_LogicalNot[T](T) +Microsoft.FSharp.Core.Operators: T op_RightShift$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]], T, Int32) +Microsoft.FSharp.Core.Operators: T op_RightShift[T](T, Int32) +Microsoft.FSharp.Core.Operators: T op_UnaryNegation$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T op_UnaryNegation[T](T) +Microsoft.FSharp.Core.Operators: T op_UnaryPlus$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,T], T) +Microsoft.FSharp.Core.Operators: T op_UnaryPlus[T](T) +Microsoft.FSharp.Core.Operators: T1 Fst[T1,T2](System.Tuple`2[T1,T2]) +Microsoft.FSharp.Core.Operators: T2 Atan2$W[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]], T1, T1) +Microsoft.FSharp.Core.Operators: T2 Atan2[T1,T2](T1, T1) +Microsoft.FSharp.Core.Operators: T2 Snd[T1,T2](System.Tuple`2[T1,T2]) +Microsoft.FSharp.Core.Operators: T3 op_Addition$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Addition[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Division$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Division[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Modulus$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Modulus[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Multiply$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Multiply[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Subtraction$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, T2) +Microsoft.FSharp.Core.Operators: T3 op_Subtraction[T1,T2,T3](T1, T2) +Microsoft.FSharp.Core.Operators: TResult Sqrt$W[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T) +Microsoft.FSharp.Core.Operators: TResult Sqrt[T,TResult](T) +Microsoft.FSharp.Core.Operators: TResult ToEnum[TResult](Int32) +Microsoft.FSharp.Core.Operators: TResult Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) +Microsoft.FSharp.Core.Operators: TResult op_PipeLeft2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1, T2) +Microsoft.FSharp.Core.Operators: TResult op_PipeLeft3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1, T2, T3) +Microsoft.FSharp.Core.Operators: TResult op_PipeLeft[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T) +Microsoft.FSharp.Core.Operators: TResult op_PipeRight2[T1,T2,TResult](T1, T2, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) +Microsoft.FSharp.Core.Operators: TResult op_PipeRight3[T1,T2,T3,TResult](T1, T2, T3, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) +Microsoft.FSharp.Core.Operators: TResult op_PipeRight[T1,TResult](T1, Microsoft.FSharp.Core.FSharpFunc`2[T1,TResult]) +Microsoft.FSharp.Core.Operators: UInt16 ToUInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt16], T) +Microsoft.FSharp.Core.Operators: UInt16 ToUInt16[T](T) +Microsoft.FSharp.Core.Operators: UInt32 ToUInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt32], T) +Microsoft.FSharp.Core.Operators: UInt32 ToUInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt32], T) +Microsoft.FSharp.Core.Operators: UInt32 ToUInt32[T](T) +Microsoft.FSharp.Core.Operators: UInt32 ToUInt[T](T) +Microsoft.FSharp.Core.Operators: UInt64 ToUInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt64], T) +Microsoft.FSharp.Core.Operators: UInt64 ToUInt64[T](T) +Microsoft.FSharp.Core.Operators: UIntPtr ToUIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UIntPtr], T) +Microsoft.FSharp.Core.Operators: UIntPtr ToUIntPtr[T](T) +Microsoft.FSharp.Core.Operators: Void Decrement(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) +Microsoft.FSharp.Core.Operators: Void Ignore[T](T) +Microsoft.FSharp.Core.Operators: Void Increment(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) +Microsoft.FSharp.Core.Operators: Void op_ColonEquals[T](Microsoft.FSharp.Core.FSharpRef`1[T], T) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: FSharpFunc`3 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult] Invoke(T1) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: TResult Invoke(T1, T2) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Void .ctor() +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: FSharpFunc`4 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]] Invoke(T1) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: TResult Invoke(T1, T2, T3) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Void .ctor() +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: FSharpFunc`5 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]]) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]] Invoke(T1) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: TResult Invoke(T1, T2, T3, T4) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Void .ctor() +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: FSharpFunc`6 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]]) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]] Invoke(T1) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: TResult Invoke(T1, T2, T3, T4, T5) +Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Void .ctor() +Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult] +Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult] +Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult] +Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult] +Microsoft.FSharp.Core.OptionModule: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Int32 Count[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2], Microsoft.FSharp.Core.FSharpOption`1[T3]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[T]]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfNullable[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfObj[T](T) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpOption`1[T], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: T GetValue[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: T ToObj[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpOption`1[T], TState) +Microsoft.FSharp.Core.OptionModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: T[] ToArray[T](Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[T]) +Microsoft.FSharp.Core.OptionalArgumentAttribute: Void .ctor() +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.Object[] Captures +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.Object[] get_Captures() +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String ToString() +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String Value +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String get_Value() +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.Type[] CaptureTypes +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.Type[] get_CaptureTypes() +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: Void .ctor(System.String) +Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: Void .ctor(System.String, System.Object[], System.Type[]) +Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: Void .ctor(System.String) +Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: Void .ctor(System.String, System.Object[], System.Type[]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilderThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,TResult]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilder[T](System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriterThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,TResult]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.PrintfModule: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Core.ProjectionParameterAttribute: Void .ctor() +Microsoft.FSharp.Core.ReferenceEqualityAttribute: Void .ctor() +Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean IncludeValue +Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean get_IncludeValue() +Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor() +Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.RequireQualifiedAccessAttribute: Void .ctor() +Microsoft.FSharp.Core.RequiresExplicitTypeArgumentsAttribute: Void .ctor() +Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[T,TResult] MapError[TError,TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TError,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) +Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Bind[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpResult`2[TResult,TError]], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) +Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Map[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) +Microsoft.FSharp.Core.SealedAttribute: Boolean Value +Microsoft.FSharp.Core.SealedAttribute: Boolean get_Value() +Microsoft.FSharp.Core.SealedAttribute: Void .ctor() +Microsoft.FSharp.Core.SealedAttribute: Void .ctor(Boolean) +Microsoft.FSharp.Core.SourceConstructFlags: Int32 value__ +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Closure +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Exception +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Field +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags KindMask +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Module +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags NonPublicRepresentation +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags None +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags ObjectType +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags RecordType +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags SumType +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags UnionCase +Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Value +Microsoft.FSharp.Core.StringModule: Boolean Exists(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) +Microsoft.FSharp.Core.StringModule: Boolean ForAll(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) +Microsoft.FSharp.Core.StringModule: Int32 Length(System.String) +Microsoft.FSharp.Core.StringModule: System.String Collect(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.String], System.String) +Microsoft.FSharp.Core.StringModule: System.String Concat(System.String, System.Collections.Generic.IEnumerable`1[System.String]) +Microsoft.FSharp.Core.StringModule: System.String Filter(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) +Microsoft.FSharp.Core.StringModule: System.String Initialize(Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String]) +Microsoft.FSharp.Core.StringModule: System.String Map(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char], System.String) +Microsoft.FSharp.Core.StringModule: System.String MapIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char]], System.String) +Microsoft.FSharp.Core.StringModule: System.String Replicate(Int32, System.String) +Microsoft.FSharp.Core.StringModule: Void Iterate(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit], System.String) +Microsoft.FSharp.Core.StringModule: Void IterateIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit]], System.String) +Microsoft.FSharp.Core.StructAttribute: Void .ctor() +Microsoft.FSharp.Core.StructuralComparisonAttribute: Void .ctor() +Microsoft.FSharp.Core.StructuralEqualityAttribute: Void .ctor() +Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String Value +Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String get_Value() +Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: Void .ctor(System.String) +Microsoft.FSharp.Core.Unit: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Unit: Int32 GetHashCode() +Microsoft.FSharp.Core.UnverifiableAttribute: Void .ctor() +Microsoft.FSharp.Core.ValueOption: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Int32 Count[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpValueOption`1[TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2], Microsoft.FSharp.Core.FSharpValueOption`1[T3]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpValueOption`1[Microsoft.FSharp.Core.FSharpValueOption`1[T]]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfNullable[T](System.Nullable`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfObj[T](T) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpValueOption`1[T]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T GetValue[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T ToObj[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpValueOption`1[T], TState) +Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) +Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Char] ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Char] ToChar[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Decimal] ToDecimal$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Decimal], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Decimal] ToDecimal[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToDouble$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Double], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToDouble[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToFloat$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Double], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToFloat[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int16] ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int16] ToInt16[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt32[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int64] ToInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int64], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int64] ToInt64[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.IntPtr] ToIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.IntPtr], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.IntPtr] ToIntPtr[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToInt8$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToInt8[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToSByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.SByte], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToSByte[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToFloat32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Single], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToFloat32[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToSingle$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Single], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToSingle[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt16] ToUInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt16], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt16] ToUInt16[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt32], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt32$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt32], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt32[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt64] ToUInt64$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UInt64], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt64] ToUInt64[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UIntPtr] ToUIntPtr$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.UIntPtr], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UIntPtr] ToUIntPtr[T](System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[TResult] ToEnum[TResult](System.Nullable`1[System.Int32]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_EqualsQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterEqualsQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessEqualsQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessGreaterQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessQmark[T](T, System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEquals[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEquals[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreater[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEquals[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreater[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessQmark[T](System.Nullable`1[T], System.Nullable`1[T]) +Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLess[T](System.Nullable`1[T], T) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_DivideQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_DivideQmark[T1,T2,T3](T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MinusQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MinusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MultiplyQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MultiplyQmark[T1,T2,T3](T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PercentQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PercentQmark[T1,T2,T3](T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PlusQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PlusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivide$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivideQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivideQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivide[T1,T2,T3](System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinus$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinusQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinus[T1,T2,T3](System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiply$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiplyQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiplyQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiply[T1,T2,T3](System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercent$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercentQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercentQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercent[T1,T2,T3](System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlus$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlusQmark$W[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]], System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) +Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlus[T1,T2,T3](System.Nullable`1[T1], T2) +Microsoft.FSharp.Linq.QueryBuilder: Boolean All[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: Boolean Contains[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], T) +Microsoft.FSharp.Linq.QueryBuilder: Boolean Exists[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: Int32 Count[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,TValue],Q] GroupValBy[T,TKey,TValue,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,T],Q] GroupBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Distinct[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SkipWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Skip[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Source[T,Q](System.Linq.IQueryable`1[T]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] TakeWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Take[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Where[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] YieldFrom[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Yield[T,Q](T) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Zero[T,Q]() +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable] Source[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] For[T,Q,TResult,Q2](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Linq.QuerySource`2[TResult,Q2]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] GroupJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Join[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[TInner,TResult]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] LeftOuterJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Select[T,Q,TResult](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) +Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Quote[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) +Microsoft.FSharp.Linq.QueryBuilder: System.Linq.IQueryable`1[T] Run[T](Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Linq.IQueryable]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] AverageByNullable$W[T,Q,TValue](Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,TValue]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TValue], Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[TValue,TValue]], Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] AverageByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MaxByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MinByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] SumByNullable$W[T,Q,TValue](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TValue], Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[TValue,TValue]], Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] SumByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) +Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOneOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOne[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T Find[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) +Microsoft.FSharp.Linq.QueryBuilder: T HeadOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T Head[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T LastOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T Last[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) +Microsoft.FSharp.Linq.QueryBuilder: T Nth[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) +Microsoft.FSharp.Linq.QueryBuilder: TValue AverageBy$W[T,Q,TValue](Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,TValue]], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TValue], Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[TValue,TValue]], Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: TValue AverageBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: TValue MaxBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: TValue MinBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: TValue SumBy$W[T,Q,TValue](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TValue], Microsoft.FSharp.Core.FSharpFunc`2[TValue,Microsoft.FSharp.Core.FSharpFunc`2[TValue,TValue]], Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: TValue SumBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) +Microsoft.FSharp.Linq.QueryBuilder: Void .ctor() +Microsoft.FSharp.Linq.QueryRunExtensions.HighPriority: System.Collections.Generic.IEnumerable`1[T] RunQueryAsEnumerable[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable]]) +Microsoft.FSharp.Linq.QueryRunExtensions.LowPriority: T RunQueryAsValue[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) +Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] Source +Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] get_Source() +Microsoft.FSharp.Linq.QuerySource`2[T,Q]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: Void .ctor(T1) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: Void .ctor(T1, T2) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: Void .ctor(T1, T2, T3) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 Item4 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 get_Item4() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: Void .ctor(T1, T2, T3, T4) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 Item4 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 get_Item4() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 Item5 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 get_Item5() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: Void .ctor(T1, T2, T3, T4, T5) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 Item4 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 get_Item4() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 Item5 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 get_Item5() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 Item6 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 get_Item6() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: Void .ctor(T1, T2, T3, T4, T5, T6) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 Item4 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item4() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 Item5 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item5() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 Item6 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item6() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 Item7 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item7() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: Void .ctor(T1, T2, T3, T4, T5, T6, T7) +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 Item1 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 get_Item1() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 Item2 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 get_Item2() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 Item3 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 get_Item3() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 Item4 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 get_Item4() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 Item5 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 get_Item5() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 Item6 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 get_Item6() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 Item7 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 get_Item7() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 Item8 +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 get_Item8() +Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: Void .ctor(T1, T2, T3, T4, T5, T6, T7, T8) +Microsoft.FSharp.Linq.RuntimeHelpers.Grouping`2[K,T]: Void .ctor(K, System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr SubstHelperRaw(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr`1[T] SubstHelper[T](Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression QuotationToExpression(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] ImplicitExpressionConversionHelper[T](T) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] QuotationToLambdaExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Object EvaluateQuotation(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T MemberInitializationHelper[T](T) +Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T NewAnonymousObjectHelper[T](T) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr AddPointerInlined[T](IntPtr, Int32) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfNativeIntInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfVoidPtrInlined[T](Void*) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr StackAllocate[T](Int32) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr ToNativeIntInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: T GetPointerInlined[T](IntPtr, Int32) +Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: T& ToByRefInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void* ToVoidPtrInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: Boolean IsNullPointer[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr NullPointer[T]() +Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfILSigPtrInlined[T](T*) +Microsoft.FSharp.NativeInterop.NativePtrModule: T* ToILSigPtrInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void ClearPointerInlined[T](IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void CopyBlockInlined[T](IntPtr, IntPtr, Int32) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void CopyPointerInlined[T](IntPtr, IntPtr) +Microsoft.FSharp.NativeInterop.NativePtrModule: Void InitializeBlockInlined[T](IntPtr, Byte, UInt32) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] UnitPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] MethodWithReflectedDefinitionPattern(System.Reflection.MethodBase) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertyGetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertySetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Boolean] BoolPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Byte] BytePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Char] CharPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Decimal] DecimalPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Double] DoublePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int16] Int16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] Int32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int64] Int64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.SByte] SBytePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Single] SinglePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.String] StringPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar]],Microsoft.FSharp.Quotations.FSharpExpr]] LambdasPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] ApplicationsPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AndAlsoPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] OrElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt16] UInt16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt32] UInt32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt64] UInt64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Core.FSharpChoice`3[Microsoft.FSharp.Quotations.FSharpVar,System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr],System.Tuple`2[System.Object,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] ShapePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Quotations.FSharpExpr RebuildShapeCombination(System.Object, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Boolean Equals(System.Object) +Microsoft.FSharp.Quotations.FSharpExpr: Int32 GetHashCode() +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] CustomAttributes +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] get_CustomAttributes() +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] TryGetReflectedDefinition(System.Reflection.MethodBase) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressOf(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressSet(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Application(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Applications(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr CallWithWitnesses(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.MethodInfo, System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr], Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr CallWithWitnesses(System.Reflection.MethodInfo, System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr], Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Coerce(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr DefaultValue(System.Type) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize(System.Type, Microsoft.FSharp.Collections.FSharpList`1[System.Type], Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr], Byte[]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize40(System.Type, System.Type[], System.Type[], Microsoft.FSharp.Quotations.FSharpExpr[], Byte[]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(System.Reflection.FieldInfo) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ForIntegerRangeLoop(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr IfThenElse(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Lambda(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Let(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr LetRecursive(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]], Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewArray(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Quote(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteRaw(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteTyped(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Sequential(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Substitute(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr]]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryFinally(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryWith(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TupleGet(Microsoft.FSharp.Quotations.FSharpExpr, Int32) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TypeTest(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr UnionCaseTest(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Reflection.UnionCaseInfo) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value(System.Object, System.Type) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName(System.Object, System.Type, System.String) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName[T](T, System.String) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value[T](T) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Var(Microsoft.FSharp.Quotations.FSharpVar) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr VarSet(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WhileLoop(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WithValue(System.Object, System.Type, Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Cast[T](Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] GlobalVar[T](System.String) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] WithValue[T](T, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) +Microsoft.FSharp.Quotations.FSharpExpr: System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Quotations.FSharpVar] GetFreeVars() +Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString() +Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString(Boolean) +Microsoft.FSharp.Quotations.FSharpExpr: System.Type Type +Microsoft.FSharp.Quotations.FSharpExpr: System.Type get_Type() +Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[]) +Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[], System.Type[]) +Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr Raw +Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr get_Raw() +Microsoft.FSharp.Quotations.FSharpVar: Boolean Equals(System.Object) +Microsoft.FSharp.Quotations.FSharpVar: Boolean IsMutable +Microsoft.FSharp.Quotations.FSharpVar: Boolean get_IsMutable() +Microsoft.FSharp.Quotations.FSharpVar: Int32 GetHashCode() +Microsoft.FSharp.Quotations.FSharpVar: Microsoft.FSharp.Quotations.FSharpVar Global(System.String, System.Type) +Microsoft.FSharp.Quotations.FSharpVar: System.String Name +Microsoft.FSharp.Quotations.FSharpVar: System.String ToString() +Microsoft.FSharp.Quotations.FSharpVar: System.String get_Name() +Microsoft.FSharp.Quotations.FSharpVar: System.Type Type +Microsoft.FSharp.Quotations.FSharpVar: System.Type get_Type() +Microsoft.FSharp.Quotations.FSharpVar: Void .ctor(System.String, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewStructTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] AddressOfPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuotePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteRawPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteTypedPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpVar] VarPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]],Microsoft.FSharp.Quotations.FSharpExpr]] LetRecursivePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo]] FieldGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AddressSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ApplicationPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] SequentialPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] TryFinallyPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] WhileLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Reflection.UnionCaseInfo]] UnionCaseTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Int32]] TupleGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] CoercePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] TypeTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] LambdaPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] VarSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewUnionCasePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Object,System.Type]] ValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewObjectPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewArrayPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewRecordPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo,Microsoft.FSharp.Quotations.FSharpExpr]] FieldSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.MethodInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] CallPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] PropertyGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] IfThenElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] LetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,Microsoft.FSharp.Quotations.FSharpExpr]] WithValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,System.String]] ValueWithNamePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar],Microsoft.FSharp.Quotations.FSharpExpr]] NewDelegatePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Quotations.FSharpExpr]] PropertySetPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ForIntegerRangeLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.MethodInfo,System.Reflection.MethodInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] CallWithWitnessesPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] TryWithPattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Type] DefaultValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsExceptionRepresentation.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsRecord.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsUnion.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] FSharpValue.PreComputeUnionTagReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeRecordReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeUnionReader.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeRecordConstructor.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeUnionConstructor.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Reflection.UnionCaseInfo[] FSharpType.GetUnionCases.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeRecord.Static(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeUnion.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetExceptionFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetRecordFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.ConstructorInfo FSharpValue.PreComputeRecordConstructorInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MemberInfo FSharpValue.PreComputeUnionTagMemberInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MethodInfo FSharpValue.PreComputeUnionConstructorInfo.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetExceptionFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetRecordFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] FSharpValue.GetUnionFields.Static(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsExceptionRepresentation(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsFunction(System.Type) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsModule(System.Type) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsRecord(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsTuple(System.Type) +Microsoft.FSharp.Reflection.FSharpType: Boolean IsUnion(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: Microsoft.FSharp.Reflection.UnionCaseInfo[] GetUnionCases(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetExceptionFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetRecordFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] PreComputeUnionTagReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeRecordReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeTupleReader(System.Type) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeUnionReader(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object] PreComputeRecordFieldReader(System.Reflection.PropertyInfo) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeRecordConstructor(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeTupleConstructor(System.Type) +Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeUnionConstructor(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object GetRecordField(System.Object, System.Reflection.PropertyInfo) +Microsoft.FSharp.Reflection.FSharpValue: System.Object GetTupleField(System.Object, Int32) +Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeFunction(System.Type, Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeRecord(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeTuple(System.Object[], System.Type) +Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeUnion(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetExceptionFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetRecordFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetTupleFields(System.Object) +Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.ConstructorInfo PreComputeRecordConstructorInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MemberInfo PreComputeUnionTagMemberInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MethodInfo PreComputeUnionConstructorInfo(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] GetUnionFields(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) +Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Type]] PreComputeTupleConstructorInfo(System.Type) +Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.PropertyInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,System.Int32]]] PreComputeTuplePropertyInfo(System.Type, Int32) +Microsoft.FSharp.Reflection.UnionCaseInfo: Boolean Equals(System.Object) +Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 GetHashCode() +Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 Tag +Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 get_Tag() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Collections.Generic.IList`1[System.Reflection.CustomAttributeData] GetCustomAttributesData() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes(System.Type) +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Reflection.PropertyInfo[] GetFields() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.String Name +Microsoft.FSharp.Reflection.UnionCaseInfo: System.String ToString() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.String get_Name() +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type DeclaringType +Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type get_DeclaringType() +" +#if NETCOREAPP +// This is in netstandard 2.1 + let expected = + expected + + """Microsoft.FSharp.Control.TaskBuilderBase: Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T] Using[TResource,TOverall,T](TResource, Microsoft.FSharp.Core.FSharpFunc`2[TResource,Microsoft.FSharp.Core.CompilerServices.ResumableCode`2[Microsoft.FSharp.Control.TaskStateMachineData`1[TOverall],T]]) +""" +#endif +#if DEBUG + let expected = + expected + + @"Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult])" +#endif + SurfaceArea.verify expected "coreclr" (System.IO.Path.Combine(__SOURCE_DIRECTORY__,__SOURCE_FILE__)) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs deleted file mode 100644 index 42984aa8315..00000000000 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ /dev/null @@ -1,2763 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Core.UnitTests.SurfaceArea - -open NUnit.Framework -open FSharp.Core.UnitTests.LibraryTestFx - -type SurfaceAreaTest() = - [] - member this.VerifyArea() = - let expected = @" -Microsoft.FSharp.Collections.Array2DModule: Int32 Base1[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Base2[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Length1[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: Int32 Length2[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T Get[T](T[,], Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: TResult[,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]], T[,]) -Microsoft.FSharp.Collections.Array2DModule: TResult[,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Copy[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] CreateBased[T](Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array2DModule: T[,] Create[T](Int32, Int32, T) -Microsoft.FSharp.Collections.Array2DModule: T[,] InitializeBased[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Initialize[T](Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]) -Microsoft.FSharp.Collections.Array2DModule: T[,] Rebase[T](T[,]) -Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreateBased[T](Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: T[,] ZeroCreate[T](Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: Void CopyTo[T](T[,], Int32, Int32, T[,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array2DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]], T[,]) -Microsoft.FSharp.Collections.Array2DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,]) -Microsoft.FSharp.Collections.Array2DModule: Void Set[T](T[,], Int32, Int32, T) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length1[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length2[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Int32 Length3[T](T[,,]) -Microsoft.FSharp.Collections.Array3DModule: T Get[T](T[,,], Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array3DModule: TResult[,,] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]]]], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: TResult[,,] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: T[,,] Create[T](Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array3DModule: T[,,] Initialize[T](Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]) -Microsoft.FSharp.Collections.Array3DModule: T[,,] ZeroCreate[T](Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array3DModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]]]], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[,,]) -Microsoft.FSharp.Collections.Array3DModule: Void Set[T](T[,,], Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length1[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length2[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length3[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: Int32 Length4[T](T[,,,]) -Microsoft.FSharp.Collections.Array4DModule: T Get[T](T[,,,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) -Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) -Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) -Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Contains[T](T, T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Boolean IsEmpty[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Int32 Length[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.ArrayModule+Parallel -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[System.Int32,T][] Indexed[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] AllPairs[T1,T2](T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TResult[],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] SplitAt[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1,T2,T3][] Zip3[T1,T2,T3](T1[], T2[], T3[]) -Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1[],T2[],T3[]] Unzip3[T1,T2,T3](System.Tuple`3[T1,T2,T3][]) -Microsoft.FSharp.Collections.ArrayModule: T Average[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T ExactlyOne[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Get[T](T[], Int32) -Microsoft.FSharp.Collections.ArrayModule: T Head[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T Item[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T Last[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Max[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Min[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T Sum[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1[], T2[], T3[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) -Microsoft.FSharp.Collections.ArrayModule: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) -Microsoft.FSharp.Collections.ArrayModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], T1[], T2[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: TState[] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], T[], TState) -Microsoft.FSharp.Collections.ArrayModule: TState[] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Append[T](T[], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Concat[T](System.Collections.Generic.IEnumerable`1[T[]]) -Microsoft.FSharp.Collections.ArrayModule: T[] Copy[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Create[T](Int32, T) -Microsoft.FSharp.Collections.ArrayModule: T[] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Distinct[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Empty[T]() -Microsoft.FSharp.Collections.ArrayModule: T[] Except[T](System.Collections.Generic.IEnumerable`1[T], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] GetSubArray[T](T[], Int32, Int32) -Microsoft.FSharp.Collections.ArrayModule: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ArrayModule: T[] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ArrayModule: T[] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.ArrayModule: T[] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.ArrayModule: T[] Reverse[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Singleton[T](T) -Microsoft.FSharp.Collections.ArrayModule: T[] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Skip[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortDescending[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Sort[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Tail[T](T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Take[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Truncate[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.ArrayModule: T[] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) -Microsoft.FSharp.Collections.ArrayModule: T[] ZeroCreate[T](Int32) -Microsoft.FSharp.Collections.ArrayModule: T[][] ChunkBySize[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[][] SplitInto[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: T[][] Transpose[T](System.Collections.Generic.IEnumerable`1[T[]]) -Microsoft.FSharp.Collections.ArrayModule: T[][] Windowed[T](Int32, T[]) -Microsoft.FSharp.Collections.ArrayModule: Void CopyTo[T](T[], Int32, T[], Int32, Int32) -Microsoft.FSharp.Collections.ArrayModule: Void Fill[T](T[], Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], T1[], T2[]) -Microsoft.FSharp.Collections.ArrayModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void Set[T](T[], Int32, T) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlaceWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], T[]) -Microsoft.FSharp.Collections.ArrayModule: Void SortInPlace[T](T[]) -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] FromFunction[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]]) -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] NonStructural[T]() -Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() -Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons -Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsCons -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsCons() -Microsoft.FSharp.Collections.FSharpList`1[T]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 GetReverseIndex(Int32, Int32) -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Length -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 Tag -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Length() -Microsoft.FSharp.Collections.FSharpList`1[T]: Int32 get_Tag() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1+Tags[T] -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Cons(T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Empty -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] GetSlice(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] Tail -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] TailOrNull -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Empty() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_Tail() -Microsoft.FSharp.Collections.FSharpList`1[T]: Microsoft.FSharp.Collections.FSharpList`1[T] get_TailOrNull() -Microsoft.FSharp.Collections.FSharpList`1[T]: System.String ToString() -Microsoft.FSharp.Collections.FSharpList`1[T]: T Head -Microsoft.FSharp.Collections.FSharpList`1[T]: T HeadOrDefault -Microsoft.FSharp.Collections.FSharpList`1[T]: T Item [Int32] -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Head() -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_HeadOrDefault() -Microsoft.FSharp.Collections.FSharpList`1[T]: T get_Item(Int32) -Microsoft.FSharp.Collections.FSharpList`1[T]: Void .ctor(T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean ContainsKey(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean TryGetValue(TKey, TValue ByRef) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 Count -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Int32 get_Count() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Add(TKey, TValue) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue] Remove(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Microsoft.FSharp.Core.FSharpOption`1[TValue] TryFind(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: System.String ToString() -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue Item [TKey] -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: TValue get_Item(TKey) -Microsoft.FSharp.Collections.FSharpMap`2[TKey,TValue]: Void .ctor(System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Contains(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsEmpty -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsProperSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSubsetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean IsSupersetOf(Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Boolean get_IsEmpty() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 Count -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Int32 get_Count() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Add(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove(T) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Addition(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: Microsoft.FSharp.Collections.FSharpSet`1[T] op_Subtraction(Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.FSharpSet`1[T]: System.String ToString() -Microsoft.FSharp.Collections.FSharpSet`1[T]: T MaximumElement -Microsoft.FSharp.Collections.FSharpSet`1[T]: T MinimumElement -Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MaximumElement() -Microsoft.FSharp.Collections.FSharpSet`1[T]: T get_MinimumElement() -Microsoft.FSharp.Collections.FSharpSet`1[T]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] FromFunctions[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]]) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] LimitedStructural[T](Int32) -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] NonStructural[T]() -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Reference[T]() -Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() -Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Int32 Length[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] SplitInto[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Transpose[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[T]] Windowed[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.Int32,T]] Indexed[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Collections.FSharpList`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Concat[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpList`1[T]]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Distinct[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Empty[T]() -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Reverse[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortDescending[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Sort[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Tail[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Take[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Unfold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2]] Unzip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[T],Microsoft.FSharp.Collections.FSharpList`1[T]] SplitAt[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: System.Tuple`3[Microsoft.FSharp.Collections.FSharpList`1[T1],Microsoft.FSharp.Collections.FSharpList`1[T2],Microsoft.FSharp.Collections.FSharpList`1[T3]] Unzip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]]) -Microsoft.FSharp.Collections.ListModule: T Average[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T ExactlyOne[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Get[T](Microsoft.FSharp.Collections.FSharpList`1[T], Int32) -Microsoft.FSharp.Collections.ListModule: T Head[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Item[T](Int32, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Last[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Max[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Min[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T Sum[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], TState) -Microsoft.FSharp.Collections.ListModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpList`1[T], TState) -Microsoft.FSharp.Collections.ListModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) -Microsoft.FSharp.Collections.ListModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.ListModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.MapModule: Boolean ContainsKey[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean Exists[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean ForAll[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Boolean IsEmpty[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Int32 Count[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]] ToList[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,TResult] Map[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Add[TKey,T](TKey, T, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Empty[TKey,T]() -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Filter[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfArray[TKey,T](System.Tuple`2[TKey,T][]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfList[TKey,T](Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,T]]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] OfSeq[TKey,T](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Collections.FSharpMap`2[TKey,T] Remove[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TKey] TryFindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,T]] ToSeq[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpMap`2[TKey,T],Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]] Partition[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: System.Tuple`2[TKey,T][] ToArray[TKey,T](Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: T Find[TKey,T](TKey, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TKey FindKey[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) -Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) -Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Int32 Length[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Collections.Generic.IEnumerable`1[T]] Transpose[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.Int32,T]] Indexed[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T,T]] Pairwise[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[T1,T2]] Zip[T1,T2](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Collections.Generic.IEnumerable`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], System.Collections.Generic.IEnumerable`1[T3]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[TState] Scan[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] ChunkBySize[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] SplitInto[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T[]] Windowed[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Append[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cache[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Cast[T](System.Collections.IEnumerable) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Concat[TCollection,T](System.Collections.Generic.IEnumerable`1[TCollection]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Collections.Generic.IEnumerable`1[T]]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Distinct[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Empty[T]() -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] ReadOnly[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Replicate[T](Int32, T) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Reverse[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Skip[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortDescending[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Sort[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Tail[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Take[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Truncate[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) -Microsoft.FSharp.Collections.SeqModule: System.Collections.Generic.IEnumerable`1[T] Where[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: System.Tuple`2[System.Collections.Generic.IEnumerable`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Average[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T ExactlyOne[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Get[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Head[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Item[T](Int32, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Last[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Max[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Min[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T Sum[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2], TState) -Microsoft.FSharp.Collections.SeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], System.Collections.Generic.IEnumerable`1[T], TState) -Microsoft.FSharp.Collections.SeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: T[] ToArray[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Void Iterate2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) -Microsoft.FSharp.Collections.SeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsProperSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsProperSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsSubset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Boolean IsSuperset[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Int32 Count[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Add[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Difference[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Empty[T]() -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] IntersectMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Intersect[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfArray[T](T[]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Remove[T](T, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Singleton[T](T) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] UnionMany[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Collections.FSharpSet`1[T]]) -Microsoft.FSharp.Collections.SetModule: Microsoft.FSharp.Collections.FSharpSet`1[T] Union[T](Microsoft.FSharp.Collections.FSharpSet`1[T], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: System.Collections.Generic.IEnumerable`1[T] ToSeq[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: System.Tuple`2[Microsoft.FSharp.Collections.FSharpSet`1[T],Microsoft.FSharp.Collections.FSharpSet`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T MaxElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T MinElement[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.FSharpSet`1[T], TState) -Microsoft.FSharp.Collections.SetModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Collections.SetModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpSet`1[T]) -Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean IsCancellationRequested -Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean get_IsCancellationRequested() -Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnCancellation() -Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnSuccess(T) -Microsoft.FSharp.Control.AsyncActivation`1[T]: Void OnExceptionRaised() -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Bind[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn CallThenInvoke[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], TResult, Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Invoke[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Control.AsyncActivation`1[T]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryFinally[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryWith[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]]) -Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.FSharpAsync`1[T] MakeAsync[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.AsyncActivation`1[T],Microsoft.FSharp.Control.AsyncReturn]) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncWrite(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncReadBytes(System.IO.Stream, Int32) -Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Int32] AsyncRead(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.CommonExtensions: System.IDisposable SubscribeToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.CommonExtensions: Void AddToObservable[T](System.IObservable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[System.Tuple`2[T,T]],System.Tuple`2[T,T]] Pairwise[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Choose[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Map[T,TResult,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult],TResult] Scan[TResult,T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Filter[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Merge[TDel1,T,TDel2](Microsoft.FSharp.Control.IEvent`2[TDel1,T], Microsoft.FSharp.Control.IEvent`2[TDel2,T]) -Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult1],TResult1],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[TResult2],TResult2]] Split[T,TResult1,TResult2,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: System.Tuple`2[Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T],Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T]] Partition[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.EventModule: Void Add[T,TDel](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.IEvent`2[TDel,T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Control.FSharpAsync`1[T]] StartChild[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpChoice`2[T,System.Exception]] Catch[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] Choice[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AwaitTask(System.Threading.Tasks.Task) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Ignore[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(Int32) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToContext(System.Threading.SynchronizationContext) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToNewThread() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToThreadPool() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitIAsyncResult(System.IAsyncResult, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Boolean] AwaitWaitHandle(System.Threading.WaitHandle, Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.IDisposable] OnCancel(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] CancellationToken -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.CancellationToken] get_CancellationToken() -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[System.Threading.Tasks.Task`1[T]] StartChildAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Parallel[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T[]] Sequential[T](System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitEvent[TDel,T](Microsoft.FSharp.Control.IEvent`2[TDel,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] AwaitTask[T](System.Threading.Tasks.Task`1[T]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,TArg3,T](TArg1, TArg2, TArg3, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[TArg1,TArg2,TArg3,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,TArg2,T](TArg1, TArg2, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[TArg1,TArg2,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[TArg1,T](TArg1, Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg1,System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromBeginEnd[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[System.AsyncCallback,System.Object],System.IAsyncResult], Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] FromContinuations[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit],Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]],Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[T] TryCancelled[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken DefaultCancellationToken -Microsoft.FSharp.Control.FSharpAsync: System.Threading.CancellationToken get_DefaultCancellationToken() -Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.Tasks.TaskCreationOptions], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: System.Threading.Tasks.Task`1[T] StartImmediateAsTask[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: System.Tuple`3[Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[TArg,System.AsyncCallback,System.Object],System.IAsyncResult],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,T],Microsoft.FSharp.Core.FSharpFunc`2[System.IAsyncResult,Microsoft.FSharp.Core.Unit]] AsBeginEnd[TArg,T](Microsoft.FSharp.Core.FSharpFunc`2[TArg,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsync: T RunSynchronously[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void CancelDefaultToken() -Microsoft.FSharp.Control.FSharpAsync: Void Start(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void StartImmediate(Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsync: Void StartWithContinuations[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[System.OperationCanceledException,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] For[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] While(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Zero() -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Bind[T,TResult](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[TResult] Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Control.FSharpAsync`1[TResult]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Combine[T](Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] ReturnFrom[T](Microsoft.FSharp.Control.FSharpAsync`1[T]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] Return[T](T) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryFinally[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Control.FSharpAsyncBuilder: Microsoft.FSharp.Control.FSharpAsync`1[T] TryWith[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Control.FSharpAsync`1[T]]) -Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply]: Void Reply(TReply) -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] Publish -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate] get_Publish() -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void .ctor() -Microsoft.FSharp.Control.FSharpDelegateEvent`1[TDelegate]: Void Trigger(System.Object[]) -Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] Publish -Microsoft.FSharp.Control.FSharpEvent`1[T]: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[T],T] get_Publish() -Microsoft.FSharp.Control.FSharpEvent`1[T]: Void .ctor() -Microsoft.FSharp.Control.FSharpEvent`1[T]: Void Trigger(T) -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] Publish -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] get_Publish() -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void .ctor() -Microsoft.FSharp.Control.FSharpEvent`2[TDelegate,TArgs]: Void Trigger(System.Object, TArgs) -Microsoft.FSharp.Control.FSharpHandler`1[T]: System.IAsyncResult BeginInvoke(System.Object, T, System.AsyncCallback, System.Object) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void .ctor(System.Object, IntPtr) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void EndInvoke(System.IAsyncResult) -Microsoft.FSharp.Control.FSharpHandler`1[T]: Void Invoke(System.Object, T) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 CurrentQueueLength -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 DefaultTimeout -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_CurrentQueueLength() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Int32 get_DefaultTimeout() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TMsg]] TryReceive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[TReply]] PostAndTryAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.FSharpOption`1[T]] TryScan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TMsg] Receive(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Start() -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void add_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void remove_Error(Microsoft.FSharp.Control.FSharpHandler`1[System.Exception]) -Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void set_DefaultTimeout(Int32) -Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void AddHandler(TDelegate) -Microsoft.FSharp.Control.IDelegateEvent`1[TDelegate]: Void RemoveHandler(TDelegate) -Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] CreateFromValue[T](T) -Microsoft.FSharp.Control.LazyExtensions: System.Lazy`1[T] Create[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) -Microsoft.FSharp.Control.LazyExtensions: T Force[T](System.Lazy`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IDisposable Subscribe[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[System.Tuple`2[T,T]] Pairwise[T](System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[TResult] Scan[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], TResult, System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.IObservable`1[T] Merge[T](System.IObservable`1[T], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[TResult1],System.IObservable`1[TResult2]] Split[T,TResult1,TResult2](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpChoice`2[TResult1,TResult2]], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: System.Tuple`2[System.IObservable`1[T],System.IObservable`1[T]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.IObservable`1[T]) -Microsoft.FSharp.Control.ObservableModule: Void Add[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncDownloadFile(System.Net.WebClient, System.Uri, System.String) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncDownloadData(System.Net.WebClient, System.Uri) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Net.WebResponse] AsyncGetResponse(System.Net.WebRequest) -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.String] AsyncDownloadString(System.Net.WebClient, System.Uri) -Microsoft.FSharp.Core.AbstractClassAttribute: Void .ctor() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean Value -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Boolean get_Value() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor() -Microsoft.FSharp.Core.AllowNullLiteralAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.AutoOpenAttribute: System.String Path -Microsoft.FSharp.Core.AutoOpenAttribute: System.String get_Path() -Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor() -Microsoft.FSharp.Core.AutoOpenAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean Value -Microsoft.FSharp.Core.AutoSerializableAttribute: Boolean get_Value() -Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+In -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+InOut -Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+Out -Microsoft.FSharp.Core.CLIEventAttribute: Void .ctor() -Microsoft.FSharp.Core.CLIMutableAttribute: Void .ctor() -Microsoft.FSharp.Core.ClassAttribute: Void .ctor() -Microsoft.FSharp.Core.ComparisonConditionalOnAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] Counts -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: System.Collections.Generic.IEnumerable`1[System.Int32] get_Counts() -Microsoft.FSharp.Core.CompilationArgumentCountsAttribute: Void .ctor(Int32[]) -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 SequenceNumber -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 VariantNumber -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_SequenceNumber() -Microsoft.FSharp.Core.CompilationMappingAttribute: Int32 get_VariantNumber() -Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags SourceConstructFlags -Microsoft.FSharp.Core.CompilationMappingAttribute: Microsoft.FSharp.Core.SourceConstructFlags get_SourceConstructFlags() -Microsoft.FSharp.Core.CompilationMappingAttribute: System.String ResourceName -Microsoft.FSharp.Core.CompilationMappingAttribute: System.String get_ResourceName() -Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] TypeDefinitions -Microsoft.FSharp.Core.CompilationMappingAttribute: System.Type[] get_TypeDefinitions() -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(Microsoft.FSharp.Core.SourceConstructFlags, Int32, Int32) -Microsoft.FSharp.Core.CompilationMappingAttribute: Void .ctor(System.String, System.Type[]) -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags Flags -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Microsoft.FSharp.Core.CompilationRepresentationFlags get_Flags() -Microsoft.FSharp.Core.CompilationRepresentationAttribute: Void .ctor(Microsoft.FSharp.Core.CompilationRepresentationFlags) -Microsoft.FSharp.Core.CompilationRepresentationFlags: Int32 value__ -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Event -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Instance -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags ModuleSuffix -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags None -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags Static -Microsoft.FSharp.Core.CompilationRepresentationFlags: Microsoft.FSharp.Core.CompilationRepresentationFlags UseNullAsTrueValue -Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String SourceName -Microsoft.FSharp.Core.CompilationSourceNameAttribute: System.String get_SourceName() -Microsoft.FSharp.Core.CompilationSourceNameAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompiledNameAttribute: System.String CompiledName -Microsoft.FSharp.Core.CompiledNameAttribute: System.String get_CompiledName() -Microsoft.FSharp.Core.CompiledNameAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsError -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean IsHidden -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsError() -Microsoft.FSharp.Core.CompilerMessageAttribute: Boolean get_IsHidden() -Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 MessageNumber -Microsoft.FSharp.Core.CompilerMessageAttribute: Int32 get_MessageNumber() -Microsoft.FSharp.Core.CompilerMessageAttribute: System.String Message -Microsoft.FSharp.Core.CompilerMessageAttribute: System.String get_Message() -Microsoft.FSharp.Core.CompilerMessageAttribute: Void .ctor(System.String, Int32) -Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsError(Boolean) -Microsoft.FSharp.Core.CompilerMessageAttribute: Void set_IsHidden(Boolean) -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean CheckClose -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T get_LastGenerated() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Void Close() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNestedNamespaces() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String NamespaceName -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.String get_NamespaceName() -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type ResolveTypeName(System.String) -Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace: System.Type[] GetTypes() -Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.MethodBase ApplyStaticArgumentsForMethod(System.Reflection.MethodBase, System.String, System.Object[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider2: System.Reflection.ParameterInfo[] GetStaticParametersForMethod(System.Reflection.MethodBase) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Byte[] GetGeneratedAssemblyContents(System.Reflection.Assembly) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Core.CompilerServices.IProvidedNamespace[] GetNamespaces() -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Microsoft.FSharp.Quotations.FSharpExpr GetInvokerExpression(System.Reflection.MethodBase, Microsoft.FSharp.Quotations.FSharpExpr[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.EventHandler Invalidate -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Reflection.ParameterInfo[] GetStaticParameters(System.Type) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: System.Type ApplyStaticArguments(System.Type, System.String[], System.Object[]) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void add_Invalidate(System.EventHandler) -Microsoft.FSharp.Core.CompilerServices.ITypeProvider: Void remove_Invalidate(System.EventHandler) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: Microsoft.FSharp.Control.IEvent`2[TDelegate,TArgs] CreateEvent[TDelegate,TArgs](Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[TDelegate,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[System.Object,Microsoft.FSharp.Core.FSharpFunc`2[TArgs,Microsoft.FSharp.Core.Unit]],TDelegate]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateFromFunctions[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[TResult] EnumerateUsing[T,TCollection,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateThenFinally[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers: System.Collections.Generic.IEnumerable`1[T] EnumerateWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String AssemblyName -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: System.String get_AssemblyName() -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsHostedExecution -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean IsInvalidationSupported -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean SystemRuntimeContainsType(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsHostedExecution() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Boolean get_IsInvalidationSupported() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String ResolutionFolder -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String RuntimeAssembly -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String TemporaryFolder -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_ResolutionFolder() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_RuntimeAssembly() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String get_TemporaryFolder() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] ReferencedAssemblies -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.String[] get_ReferencedAssemblies() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version SystemRuntimeAssemblyVersion -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: System.Version get_SystemRuntimeAssemblyVersion() -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Boolean]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsHostedExecution(Boolean) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_IsInvalidationSupported(Boolean) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ReferencedAssemblies(System.String[]) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_ResolutionFolder(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_RuntimeAssembly(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_SystemRuntimeAssemblyVersion(System.Version) -Microsoft.FSharp.Core.CompilerServices.TypeProviderConfig: Void set_TemporaryFolder(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Column -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 Line -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Column() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Int32 get_Line() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String FilePath -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: System.String get_FilePath() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Column(Int32) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_FilePath(System.String) -Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute: Void set_Line(Int32) -Microsoft.FSharp.Core.CompilerServices.TypeProviderEditorHideMethodsAttribute: Void .ctor() -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Int32 value__ -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes IsErased -Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes: Microsoft.FSharp.Core.CompilerServices.TypeProviderTypeAttributes SuppressRelocate -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String CommentText -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: System.String get_CommentText() -Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CustomComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.CustomEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean AllowIntoPattern -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeGroupJoin -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeJoin -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean IsLikeZip -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpace -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean MaintainsVariableSpaceUsingBind -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_AllowIntoPattern() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeGroupJoin() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeJoin() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_IsLikeZip() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpace() -Microsoft.FSharp.Core.CustomOperationAttribute: Boolean get_MaintainsVariableSpaceUsingBind() -Microsoft.FSharp.Core.CustomOperationAttribute: System.String JoinConditionWord -Microsoft.FSharp.Core.CustomOperationAttribute: System.String Name -Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_JoinConditionWord() -Microsoft.FSharp.Core.CustomOperationAttribute: System.String get_Name() -Microsoft.FSharp.Core.CustomOperationAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_AllowIntoPattern(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeGroupJoin(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeJoin(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_IsLikeZip(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_JoinConditionWord(System.String) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpace(Boolean) -Microsoft.FSharp.Core.CustomOperationAttribute: Void set_MaintainsVariableSpaceUsingBind(Boolean) -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean Value -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Boolean get_Value() -Microsoft.FSharp.Core.DefaultAugmentationAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.DefaultValueAttribute: Boolean Check -Microsoft.FSharp.Core.DefaultValueAttribute: Boolean get_Check() -Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor() -Microsoft.FSharp.Core.DefaultValueAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.EntryPointAttribute: Void .ctor() -Microsoft.FSharp.Core.EqualityConditionalOnAttribute: Void .ctor() -Microsoft.FSharp.Core.ExperimentalAttribute: System.String Message -Microsoft.FSharp.Core.ExperimentalAttribute: System.String get_Message() -Microsoft.FSharp.Core.ExperimentalAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: Byte ToByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked: SByte ToSByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Byte ToByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Double ToDouble[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Collections.FSharpSet`1[T] CreateSet[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder DefaultAsyncBuilder -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Control.FSharpAsyncBuilder get_DefaultAsyncBuilder() -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder get_query() -Microsoft.FSharp.Core.ExtraTopLevelOperators: Microsoft.FSharp.Linq.QueryBuilder query -Microsoft.FSharp.Core.ExtraTopLevelOperators: SByte ToSByte[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: Single ToSingle[T](T) -Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IDictionary`2[TKey,TValue] CreateDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: System.Collections.Generic.IReadOnlyDictionary`2[TKey,TValue] CreateReadOnlyDictionary[TKey,TValue](System.Collections.Generic.IEnumerable`1[System.Tuple`2[TKey,TValue]]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T LazyPattern[T](System.Lazy`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToString[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T SpliceUntypedExpression[T](Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Core.ExtraTopLevelOperators: T[,] CreateArray2D[?,T](System.Collections.Generic.IEnumerable`1[?]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2]: Int32 Choice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice1Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean IsChoice2Of2 -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice1Of2() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Boolean get_IsChoice2Of2() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice1Of2[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Choice2Of2[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2+Tags[T1,T2] -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice1Of2(T1) -Microsoft.FSharp.Core.FSharpChoice`2[T1,T2]: Microsoft.FSharp.Core.FSharpChoice`2[T1,T2] NewChoice2Of2(T2) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3]: Int32 Choice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice1Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice2Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean IsChoice3Of3 -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice1Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice2Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Boolean get_IsChoice3Of3() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice1Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice2Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Choice3Of3[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3+Tags[T1,T2,T3] -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice1Of3(T1) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice2Of3(T2) -Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3]: Microsoft.FSharp.Core.FSharpChoice`3[T1,T2,T3] NewChoice3Of3(T3) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4]: Int32 Choice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice1Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice2Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice3Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean IsChoice4Of4 -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice1Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice2Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice3Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Boolean get_IsChoice4Of4() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice1Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice2Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice3Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Choice4Of4[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4+Tags[T1,T2,T3,T4] -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice1Of4(T1) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice2Of4(T2) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice3Of4(T3) -Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4]: Microsoft.FSharp.Core.FSharpChoice`4[T1,T2,T3,T4] NewChoice4Of4(T4) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5]: Int32 Choice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice1Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice2Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice3Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice4Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean IsChoice5Of5 -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice1Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice2Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice3Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice4Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Boolean get_IsChoice5Of5() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice1Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice2Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice3Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice4Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Choice5Of5[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5+Tags[T1,T2,T3,T4,T5] -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice1Of5(T1) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice2Of5(T2) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice3Of5(T3) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice4Of5(T4) -Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5]: Microsoft.FSharp.Core.FSharpChoice`5[T1,T2,T3,T4,T5] NewChoice5Of5(T5) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 Item -Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6]: T6 get_Item() -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6]: Int32 Choice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice1Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice2Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice3Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice4Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice5Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean IsChoice6Of6 -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice1Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice2Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice3Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice4Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice5Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Boolean get_IsChoice6Of6() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice1Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice2Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice3Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice4Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice5Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Choice6Of6[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6+Tags[T1,T2,T3,T4,T5,T6] -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice1Of6(T1) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice2Of6(T2) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice3Of6(T3) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice4Of6(T4) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice5Of6(T5) -Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6]: Microsoft.FSharp.Core.FSharpChoice`6[T1,T2,T3,T4,T5,T6] NewChoice6Of6(T6) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 Item -Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item() -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7]: Int32 Choice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice1Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice2Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice3Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice4Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice5Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice6Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean IsChoice7Of7 -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice1Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice2Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice3Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice4Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice5Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice6Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Boolean get_IsChoice7Of7() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 Tag -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice1Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice2Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice3Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice4Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice5Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice6Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Choice7Of7[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7+Tags[T1,T2,T3,T4,T5,T6,T7] -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice1Of7(T1) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice2Of7(T2) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice3Of7(T3) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice4Of7(T4) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice5Of7(T5) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice6Of7(T6) -Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7]: Microsoft.FSharp.Core.FSharpChoice`7[T1,T2,T3,T4,T5,T6,T7] NewChoice7Of7(T7) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromConverter(System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] op_Implicit(System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] ToConverter(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: System.Converter`2[T,TResult] op_Implicit(Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: TResult Invoke(T) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: V InvokeFast[V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], T, TResult) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Void .ctor() -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: W InvokeFast[V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], T, TResult, V) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: X InvokeFast[V,W,X](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,X]]]], T, TResult, V, W) -Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]: Y InvokeFast[V,W,X,Y](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,Microsoft.FSharp.Core.FSharpFunc`2[W,Microsoft.FSharp.Core.FSharpFunc`2[X,Y]]]]], T, TResult, V, W, X) -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Major -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Minor -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 Release -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Major() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Minor() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Int32 get_Release() -Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute: Void .ctor(Int32, Int32, Int32) -Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 None -Microsoft.FSharp.Core.FSharpOption`1+Tags[T]: Int32 Some -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsNone -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean IsSome -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsNone(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Boolean get_IsSome(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpOption`1[T]: Int32 GetTag(Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1+Tags[T] -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] None -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] Some(T) -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] get_None() -Microsoft.FSharp.Core.FSharpOption`1[T]: Microsoft.FSharp.Core.FSharpOption`1[T] op_Implicit(T) -Microsoft.FSharp.Core.FSharpOption`1[T]: System.String ToString() -Microsoft.FSharp.Core.FSharpOption`1[T]: T Value -Microsoft.FSharp.Core.FSharpOption`1[T]: T get_Value() -Microsoft.FSharp.Core.FSharpOption`1[T]: Void .ctor(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpRef`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpRef`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpRef`1[T]: T Value -Microsoft.FSharp.Core.FSharpRef`1[T]: T contents -Microsoft.FSharp.Core.FSharpRef`1[T]: T contents@ -Microsoft.FSharp.Core.FSharpRef`1[T]: T get_Value() -Microsoft.FSharp.Core.FSharpRef`1[T]: T get_contents() -Microsoft.FSharp.Core.FSharpRef`1[T]: Void .ctor(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_Value(T) -Microsoft.FSharp.Core.FSharpRef`1[T]: Void set_contents(T) -Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Error -Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError]: Int32 Ok -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsError -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean IsOk -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsError() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Boolean get_IsOk() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 Tag -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2+Tags[T,TError] -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewError(TError) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: Microsoft.FSharp.Core.FSharpResult`2[T,TError] NewOk(T) -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T ResultValue -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: T get_ResultValue() -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError ErrorValue -Microsoft.FSharp.Core.FSharpResult`2[T,TError]: TError get_ErrorValue() -Microsoft.FSharp.Core.FSharpTypeFunc: System.Object Specialize[T]() -Microsoft.FSharp.Core.FSharpTypeFunc: Void .ctor() -Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueNone -Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T]: Int32 ValueSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean IsValueSome -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsSome() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Boolean get_IsValueSome() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 CompareTo(System.Object, System.Collections.IComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 Tag -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Int32 get_Tag() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1+Tags[T] -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] NewValueSome(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] None -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] Some(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] ValueNone -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_None() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] get_ValueNone() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: Microsoft.FSharp.Core.FSharpValueOption`1[T] op_Implicit(T) -Microsoft.FSharp.Core.FSharpValueOption`1[T]: System.String ToString() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Item -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T Value -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Item() -Microsoft.FSharp.Core.FSharpValueOption`1[T]: T get_Value() -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit] FromAction(System.Action) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T] FromFunc[T](System.Func`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] FromAction[T](System.Action`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit] ToFSharpFunc[T](System.Action`1[T]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] FromFunc[T,TResult](System.Func`2[T,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T,TResult] ToFSharpFunc[T,TResult](System.Converter`2[T,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,Microsoft.FSharp.Core.Unit]]]]] FromAction[T1,T2,T3,T4,T5](System.Action`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FromFunc[T1,T2,T3,T4,T5,TResult](System.Func`6[T1,T2,T3,T4,T5,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]] FuncFromTupled[T1,T2,T3,T4,T5,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`5[T1,T2,T3,T4,T5],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.Unit]]]] FromAction[T1,T2,T3,T4](System.Action`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FromFunc[T1,T2,T3,T4,TResult](System.Func`5[T1,T2,T3,T4,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]] FuncFromTupled[T1,T2,T3,T4,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`4[T1,T2,T3,T4],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.Unit]]] FromAction[T1,T2,T3](System.Action`3[T1,T2,T3]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FromFunc[T1,T2,T3,TResult](System.Func`4[T1,T2,T3,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]] FuncFromTupled[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`3[T1,T2,T3],TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.Unit]] FromAction[T1,T2](System.Action`2[T1,T2]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FromFunc[T1,T2,TResult](System.Func`3[T1,T2,TResult]) -Microsoft.FSharp.Core.FuncConvert: Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]] FuncFromTupled[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Tuple`2[T1,T2],TResult]) -Microsoft.FSharp.Core.GeneralizableValueAttribute: Void .ctor() -Microsoft.FSharp.Core.InterfaceAttribute: Void .ctor() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String AddressOpNotFirstClassString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputArrayEmptyString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputMustBeNonNegativeString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String InputSequenceEmptyString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String NoNegateMinValueString -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_AddressOpNotFirstClassString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputArrayEmptyString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputMustBeNonNegativeString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_InputSequenceEmptyString() -Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings: System.String get_NoNegateMinValueString() -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean FastEqualsTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityERIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericEqualityWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterOrEqualIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericGreaterThanIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessOrEqualIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean GenericLessThanIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Boolean PhysicalEqualityIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple2[T1,T2](System.Collections.IComparer, System.Tuple`2[T1,T2], System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple3[T1,T2,T3](System.Collections.IComparer, System.Tuple`3[T1,T2,T3], System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple4[T1,T2,T3,T4](System.Collections.IComparer, System.Tuple`4[T1,T2,T3,T4], System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastCompareTuple5[T1,T2,T3,T4,T5](System.Collections.IComparer, System.Tuple`5[T1,T2,T3,T4,T5], System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple2[T1,T2](System.Collections.IEqualityComparer, System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple3[T1,T2,T3](System.Collections.IEqualityComparer, System.Tuple`3[T1,T2,T3]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple4[T1,T2,T3,T4](System.Collections.IEqualityComparer, System.Tuple`4[T1,T2,T3,T4]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 FastHashTuple5[T1,T2,T3,T4,T5](System.Collections.IEqualityComparer, System.Tuple`5[T1,T2,T3,T4,T5]) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonIntrinsic[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericComparisonWithComparerIntrinsic[T](System.Collections.IComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashIntrinsic[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 GenericHashWithComparerIntrinsic[T](System.Collections.IEqualityComparer, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 LimitedGenericHashIntrinsic[T](Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+HashCompare: Int32 PhysicalHashIntrinsic[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestFast[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Boolean TypeTestGeneric[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Char GetString(System.String, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: System.Decimal MakeDecimal(Int32, Int32, Int32, Boolean, Byte) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CheckThis[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T CreateInstance[T]() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray2D[T](T[,], Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray3D[T](T[,,], Int32, Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray4D[T](T[,,,], Int32, Int32, Int32, Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T GetArray[T](T[], Int32) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxFast[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: T UnboxGeneric[T](System.Object) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void Dispose[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailInit() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void FailStaticInit() -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray2D[T](T[,], Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray3D[T](T[,,], Int32, Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray4D[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions: Void SetArray[T](T[], Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean Or(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_Amp(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanAnd(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: Boolean op_BooleanOr(Boolean, Boolean) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: IntPtr op_IntegerAddressOf[T](T) -Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators: T& op_AddressOf[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityER[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEqualityWithComparer[T](System.Collections.IEqualityComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericEquality[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterOrEqual[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericGreaterThan[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessOrEqual[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean GenericLessThan[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Boolean PhysicalEquality[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Double FloatWithMeasure(Double) -Microsoft.FSharp.Core.LanguagePrimitives: Int16 Int16WithMeasure(Int16) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparisonWithComparer[T](System.Collections.IComparer, T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericComparison[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHashWithComparer[T](System.Collections.IEqualityComparer, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericHash[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 GenericLimitedHash[T](Int32, T) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 Int32WithMeasure(Int32) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 ParseInt32(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: Int32 PhysicalHash[T](T) -Microsoft.FSharp.Core.LanguagePrimitives: Int64 Int64WithMeasure(Int64) -Microsoft.FSharp.Core.LanguagePrimitives: Int64 ParseInt64(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+ErrorStrings -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+HashCompare -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicFunctions -Microsoft.FSharp.Core.LanguagePrimitives: Microsoft.FSharp.Core.LanguagePrimitives+IntrinsicOperators -Microsoft.FSharp.Core.LanguagePrimitives: SByte SByteWithMeasure(SByte) -Microsoft.FSharp.Core.LanguagePrimitives: Single Float32WithMeasure(Single) -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparerFromTable[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IComparer`1[T] FastGenericComparer[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparerFromTable[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastGenericEqualityComparer[T]() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.Generic.IEqualityComparer`1[T] FastLimitedGenericEqualityComparer[T](Int32) -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer GenericComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IComparer get_GenericComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer GenericEqualityERComparer -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Collections.IEqualityComparer get_GenericEqualityERComparer() -Microsoft.FSharp.Core.LanguagePrimitives: System.Decimal DecimalWithMeasure(System.Decimal) -Microsoft.FSharp.Core.LanguagePrimitives: T DivideByIntDynamic[T](T, Int32) -Microsoft.FSharp.Core.LanguagePrimitives: T DivideByInt[T](T, Int32) -Microsoft.FSharp.Core.LanguagePrimitives: T EnumToValue[TEnum,T](TEnum) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericMaximum[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericMinimum[T](T, T) -Microsoft.FSharp.Core.LanguagePrimitives: T GenericOneDynamic[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericOne[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericZeroDynamic[T]() -Microsoft.FSharp.Core.LanguagePrimitives: T GenericZero[T]() -Microsoft.FSharp.Core.LanguagePrimitives: TEnum EnumOfValue[T,TEnum](T) -Microsoft.FSharp.Core.LanguagePrimitives: TResult AdditionDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedAdditionDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedMultiplyDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: TResult MultiplyDynamic[T1,T2,TResult](T1, T2) -Microsoft.FSharp.Core.LanguagePrimitives: UInt32 ParseUInt32(System.String) -Microsoft.FSharp.Core.LanguagePrimitives: UInt64 ParseUInt64(System.String) -Microsoft.FSharp.Core.LiteralAttribute: Void .ctor() -Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object) -Microsoft.FSharp.Core.MatchFailureException: Boolean Equals(System.Object, System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.MatchFailureException: Int32 Data1 -Microsoft.FSharp.Core.MatchFailureException: Int32 Data2 -Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode() -Microsoft.FSharp.Core.MatchFailureException: Int32 GetHashCode(System.Collections.IEqualityComparer) -Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data1() -Microsoft.FSharp.Core.MatchFailureException: Int32 get_Data2() -Microsoft.FSharp.Core.MatchFailureException: System.String Data0 -Microsoft.FSharp.Core.MatchFailureException: System.String Message -Microsoft.FSharp.Core.MatchFailureException: System.String get_Data0() -Microsoft.FSharp.Core.MatchFailureException: System.String get_Message() -Microsoft.FSharp.Core.MatchFailureException: Void .ctor() -Microsoft.FSharp.Core.MatchFailureException: Void .ctor(System.String, Int32, Int32) -Microsoft.FSharp.Core.MeasureAnnotatedAbbreviationAttribute: Void .ctor() -Microsoft.FSharp.Core.MeasureAttribute: Void .ctor() -Microsoft.FSharp.Core.NoComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.NoDynamicInvocationAttribute: Void .ctor() -Microsoft.FSharp.Core.NoEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromInt64Dynamic(Int64) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: System.Object FromStringDynamic(System.String) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt32[T](Int32) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromInt64[T](Int64) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromOne[T]() -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromString[T](System.String) -Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI: T FromZero[T]() -Microsoft.FSharp.Core.NumericLiterals: Microsoft.FSharp.Core.NumericLiterals+NumericLiteralI -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 String.GetReverseIndex(System.String, Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,,]`1.GetReverseIndex[T](T[,,,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,,]`1.GetReverseIndex[T](T[,,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 [,]`1.GetReverseIndex[T](T[,], Int32, Int32) -Microsoft.FSharp.Core.Operators+ArrayExtensions: Int32 []`1.GetReverseIndex[T](T[], Int32, Int32) -Microsoft.FSharp.Core.Operators+Checked: Byte ToByte[T](T) -Microsoft.FSharp.Core.Operators+Checked: Char ToChar[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt32[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int32 ToInt[T](T) -Microsoft.FSharp.Core.Operators+Checked: Int64 ToInt64[T](T) -Microsoft.FSharp.Core.Operators+Checked: IntPtr ToIntPtr[T](T) -Microsoft.FSharp.Core.Operators+Checked: SByte ToSByte[T](T) -Microsoft.FSharp.Core.Operators+Checked: T op_UnaryNegation[T](T) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Addition[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Multiply[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: T3 op_Subtraction[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators+Checked: UInt16 ToUInt16[T](T) -Microsoft.FSharp.Core.Operators+Checked: UInt32 ToUInt32[T](T) -Microsoft.FSharp.Core.Operators+Checked: UInt64 ToUInt64[T](T) -Microsoft.FSharp.Core.Operators+Checked: UIntPtr ToUIntPtr[T](T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Equality[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThanOrEqual[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_GreaterThan[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_Inequality[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThanOrEqual[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Boolean op_LessThan[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Max[T](T, T) -Microsoft.FSharp.Core.Operators+NonStructuralComparison: T Min[T](T, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Byte PowByte(Byte, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Double PowDouble(Double, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int16 PowInt16(Int16, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 PowInt32(Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int32 SignDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Int64 PowInt64(Int64, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: IntPtr PowIntPtr(IntPtr, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: SByte PowSByte(SByte, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Single PowSingle(Single, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Byte] RangeByte(Byte, Byte, Byte) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Char] RangeChar(Char, Char) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Double] RangeDouble(Double, Double, Double) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int16] RangeInt16(Int16, Int16, Int16) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int32] RangeInt32(Int32, Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Int64] RangeInt64(Int64, Int64, Int64) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.IntPtr] RangeIntPtr(IntPtr, IntPtr, IntPtr) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.SByte] RangeSByte(SByte, SByte, SByte) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.Single] RangeSingle(Single, Single, Single) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt16] RangeUInt16(UInt16, UInt16, UInt16) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt32] RangeUInt32(UInt32, UInt32, UInt32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UInt64] RangeUInt64(UInt64, UInt64, UInt64) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[System.UIntPtr] RangeUIntPtr(UIntPtr, UIntPtr, UIntPtr) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Collections.Generic.IEnumerable`1[T] RangeStepGeneric[TStep,T](TStep, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TStep,T]], T, TStep, T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.Decimal PowDecimal(System.Decimal, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: System.String GetStringSlice(System.String, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AbsDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AcosDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AsinDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T AtanDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CeilingDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CosDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T CoshDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T ExpDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T FloorDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T Log10Dynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T LogDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowDynamic[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T PowGeneric[T](T, Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], T, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T RoundDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T SinhDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TanhDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T TruncateDynamic[T](T) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 Atan2Dynamic[T1,T2](T1, T1) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T2 SqrtDynamic[T1,T2](T1) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,,] GetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt16 PowUInt16(UInt16, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt32 PowUInt32(UInt32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UInt64 PowUInt64(UInt64, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: UIntPtr PowUIntPtr(UIntPtr, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed1[T](T[,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2DFixed2[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice2D[T](T[,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3D[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble1[T](T[,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble2[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedDouble3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle1[T](T[,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle2[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice3DFixedSingle3[T](T[,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4D[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,,] GetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[,] GetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: T[] GetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble1[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble3[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble5[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedDouble6[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle1[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle2[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle3[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedSingle4[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[,,]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple1[T](T[,,,], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple2[T](T[,,,], Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple3[T](T[,,,], Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Int32, T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice4DFixedTriple4[T](T[,,,], Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+OperatorIntrinsics: Void SetArraySlice[T](T[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], T[]) -Microsoft.FSharp.Core.Operators+Unchecked: Boolean Equals[T](T, T) -Microsoft.FSharp.Core.Operators+Unchecked: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators+Unchecked: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() -Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) -Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) -Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) -Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_GreaterThanOrEqual[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_GreaterThan[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_Inequality[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_LessThanOrEqual[T](T, T) -Microsoft.FSharp.Core.Operators: Boolean op_LessThan[T](T, T) -Microsoft.FSharp.Core.Operators: Byte ToByte[T](T) -Microsoft.FSharp.Core.Operators: Char ToChar[T](T) -Microsoft.FSharp.Core.Operators: Double Infinity -Microsoft.FSharp.Core.Operators: Double NaN -Microsoft.FSharp.Core.Operators: Double ToDouble[T](T) -Microsoft.FSharp.Core.Operators: Double get_Infinity() -Microsoft.FSharp.Core.Operators: Double get_NaN() -Microsoft.FSharp.Core.Operators: Int16 ToInt16[T](T) -Microsoft.FSharp.Core.Operators: Int32 Compare[T](T, T) -Microsoft.FSharp.Core.Operators: Int32 Hash[T](T) -Microsoft.FSharp.Core.Operators: Int32 Sign[T](T) -Microsoft.FSharp.Core.Operators: Int32 SizeOf[T]() -Microsoft.FSharp.Core.Operators: Int32 ToInt32[T](T) -Microsoft.FSharp.Core.Operators: Int32 ToInt[T](T) -Microsoft.FSharp.Core.Operators: Int32 limitedHash[T](Int32, T) -Microsoft.FSharp.Core.Operators: Int64 ToInt64[T](T) -Microsoft.FSharp.Core.Operators: IntPtr ToIntPtr[T](T) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Collections.FSharpList`1[T] op_Append[T](Microsoft.FSharp.Collections.FSharpList`1[T], Microsoft.FSharp.Collections.FSharpList`1[T]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeLeft[T2,T3,T1](Microsoft.FSharp.Core.FSharpFunc`2[T2,T3], Microsoft.FSharp.Core.FSharpFunc`2[T1,T2]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpFunc`2[T1,T3] op_ComposeRight[T1,T2,T3](Microsoft.FSharp.Core.FSharpFunc`2[T1,T2], Microsoft.FSharp.Core.FSharpFunc`2[T2,T3]) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[System.String] FailurePattern(System.Exception) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpOption`1[T] TryUnbox[T](System.Object) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.FSharpRef`1[T] Ref[T](T) -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+ArrayExtensions -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Checked -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+NonStructuralComparison -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+OperatorIntrinsics -Microsoft.FSharp.Core.Operators: Microsoft.FSharp.Core.Operators+Unchecked -Microsoft.FSharp.Core.Operators: SByte ToSByte[T](T) -Microsoft.FSharp.Core.Operators: Single InfinitySingle -Microsoft.FSharp.Core.Operators: Single NaNSingle -Microsoft.FSharp.Core.Operators: Single ToSingle[T](T) -Microsoft.FSharp.Core.Operators: Single get_InfinitySingle() -Microsoft.FSharp.Core.Operators: Single get_NaNSingle() -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] CreateSequence[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_RangeStep[T,TStep](T, TStep, T) -Microsoft.FSharp.Core.Operators: System.Collections.Generic.IEnumerable`1[T] op_Range[T](T, T) -Microsoft.FSharp.Core.Operators: System.Decimal ToDecimal[T](T) -Microsoft.FSharp.Core.Operators: System.Exception Failure(System.String) -Microsoft.FSharp.Core.Operators: System.IO.TextReader ConsoleIn[T]() -Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleError[T]() -Microsoft.FSharp.Core.Operators: System.IO.TextWriter ConsoleOut[T]() -Microsoft.FSharp.Core.Operators: System.Object Box[T](T) -Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) -Microsoft.FSharp.Core.Operators: System.String ToString[T](T) -Microsoft.FSharp.Core.Operators: System.String op_Concatenate(System.String, System.String) -Microsoft.FSharp.Core.Operators: System.Tuple`2[TKey,TValue] KeyValuePattern[TKey,TValue](System.Collections.Generic.KeyValuePair`2[TKey,TValue]) -Microsoft.FSharp.Core.Operators: System.Type TypeDefOf[T]() -Microsoft.FSharp.Core.Operators: System.Type TypeOf[T]() -Microsoft.FSharp.Core.Operators: T Abs[T](T) -Microsoft.FSharp.Core.Operators: T Acos[T](T) -Microsoft.FSharp.Core.Operators: T Asin[T](T) -Microsoft.FSharp.Core.Operators: T Atan[T](T) -Microsoft.FSharp.Core.Operators: T Ceiling[T](T) -Microsoft.FSharp.Core.Operators: T Cos[T](T) -Microsoft.FSharp.Core.Operators: T Cosh[T](T) -Microsoft.FSharp.Core.Operators: T DefaultArg[T](Microsoft.FSharp.Core.FSharpOption`1[T], T) -Microsoft.FSharp.Core.Operators: T DefaultValueArg[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], T) -Microsoft.FSharp.Core.Operators: T Exit[T](Int32) -Microsoft.FSharp.Core.Operators: T Exp[T](T) -Microsoft.FSharp.Core.Operators: T FailWith[T](System.String) -Microsoft.FSharp.Core.Operators: T Floor[T](T) -Microsoft.FSharp.Core.Operators: T Identity[T](T) -Microsoft.FSharp.Core.Operators: T InvalidArg[T](System.String, System.String) -Microsoft.FSharp.Core.Operators: T InvalidOp[T](System.String) -Microsoft.FSharp.Core.Operators: T Lock[TLock,T](TLock, Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T]) -Microsoft.FSharp.Core.Operators: T Log10[T](T) -Microsoft.FSharp.Core.Operators: T Log[T](T) -Microsoft.FSharp.Core.Operators: T Max[T](T, T) -Microsoft.FSharp.Core.Operators: T Min[T](T, T) -Microsoft.FSharp.Core.Operators: T NullArg[T](System.String) -Microsoft.FSharp.Core.Operators: T PowInteger[T](T, Int32) -Microsoft.FSharp.Core.Operators: T Raise[T](System.Exception) -Microsoft.FSharp.Core.Operators: T Reraise[T]() -Microsoft.FSharp.Core.Operators: T Rethrow[T]() -Microsoft.FSharp.Core.Operators: T Round[T](T) -Microsoft.FSharp.Core.Operators: T Sin[T](T) -Microsoft.FSharp.Core.Operators: T Sinh[T](T) -Microsoft.FSharp.Core.Operators: T Tan[T](T) -Microsoft.FSharp.Core.Operators: T Tanh[T](T) -Microsoft.FSharp.Core.Operators: T Truncate[T](T) -Microsoft.FSharp.Core.Operators: T Unbox[T](System.Object) -Microsoft.FSharp.Core.Operators: T op_BitwiseAnd[T](T, T) -Microsoft.FSharp.Core.Operators: T op_BitwiseOr[T](T, T) -Microsoft.FSharp.Core.Operators: T op_Dereference[T](Microsoft.FSharp.Core.FSharpRef`1[T]) -Microsoft.FSharp.Core.Operators: T op_ExclusiveOr[T](T, T) -Microsoft.FSharp.Core.Operators: T op_Exponentiation[T,TResult](T, TResult) -Microsoft.FSharp.Core.Operators: T op_LeftShift[T](T, Int32) -Microsoft.FSharp.Core.Operators: T op_LogicalNot[T](T) -Microsoft.FSharp.Core.Operators: T op_RightShift[T](T, Int32) -Microsoft.FSharp.Core.Operators: T op_UnaryNegation[T](T) -Microsoft.FSharp.Core.Operators: T op_UnaryPlus[T](T) -Microsoft.FSharp.Core.Operators: T1 Fst[T1,T2](System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.Operators: T2 Atan2[T1,T2](T1, T1) -Microsoft.FSharp.Core.Operators: T2 Snd[T1,T2](System.Tuple`2[T1,T2]) -Microsoft.FSharp.Core.Operators: T3 op_Addition[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Division[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Modulus[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Multiply[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: T3 op_Subtraction[T1,T2,T3](T1, T2) -Microsoft.FSharp.Core.Operators: TResult Sqrt[T,TResult](T) -Microsoft.FSharp.Core.Operators: TResult ToEnum[TResult](Int32) -Microsoft.FSharp.Core.Operators: TResult Using[T,TResult](T, Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], T1, T2) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], T1, T2, T3) -Microsoft.FSharp.Core.Operators: TResult op_PipeLeft[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight2[T1,T2,TResult](T1, T2, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight3[T1,T2,T3,TResult](T1, T2, T3, Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) -Microsoft.FSharp.Core.Operators: TResult op_PipeRight[T1,TResult](T1, Microsoft.FSharp.Core.FSharpFunc`2[T1,TResult]) -Microsoft.FSharp.Core.Operators: UInt16 ToUInt16[T](T) -Microsoft.FSharp.Core.Operators: UInt32 ToUInt32[T](T) -Microsoft.FSharp.Core.Operators: UInt64 ToUInt64[T](T) -Microsoft.FSharp.Core.Operators: UIntPtr ToUIntPtr[T](T) -Microsoft.FSharp.Core.Operators: Void Decrement(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) -Microsoft.FSharp.Core.Operators: Void Ignore[T](T) -Microsoft.FSharp.Core.Operators: Void Increment(Microsoft.FSharp.Core.FSharpRef`1[System.Int32]) -Microsoft.FSharp.Core.Operators: Void op_ColonEquals[T](Microsoft.FSharp.Core.FSharpRef`1[T], T) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: FSharpFunc`3 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: TResult Invoke(T1, T2) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: FSharpFunc`4 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: TResult Invoke(T1, T2, T3) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: FSharpFunc`5 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,TResult]]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: TResult Invoke(T1, T2, T3, T4) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: FSharpFunc`6 Adapt(Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]]]) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,Microsoft.FSharp.Core.FSharpFunc`2[T4,Microsoft.FSharp.Core.FSharpFunc`2[T5,TResult]]]] Invoke(T1) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: TResult Invoke(T1, T2, T3, T4, T5) -Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult]: Void .ctor() -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`3[T1,T2,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`4[T1,T2,T3,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`5[T1,T2,T3,T4,TResult] -Microsoft.FSharp.Core.OptimizedClosures: Microsoft.FSharp.Core.OptimizedClosures+FSharpFunc`6[T1,T2,T3,T4,T5,TResult] -Microsoft.FSharp.Core.OptionModule: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Int32 Count[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpOption`1[T1], Microsoft.FSharp.Core.FSharpOption`1[T2], Microsoft.FSharp.Core.FSharpOption`1[T3]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpOption`1[T]]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfNullable[T](System.Nullable`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OfObj[T](T) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpOption`1[T]], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Microsoft.FSharp.Core.FSharpOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpOption`1[T], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T GetValue[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T ToObj[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpOption`1[T], TState) -Microsoft.FSharp.Core.OptionModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: T[] ToArray[T](Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[T]) -Microsoft.FSharp.Core.OptionalArgumentAttribute: Void .ctor() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String ToString() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String Value -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: System.String get_Value() -Microsoft.FSharp.Core.PrintfFormat`4[TPrinter,TState,TResidue,TResult]: Void .ctor(System.String) -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String ToString() -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String Value -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: System.String get_Value() -Microsoft.FSharp.Core.PrintfFormat`5[TPrinter,TState,TResidue,TResult,TTuple]: Void .ctor(System.String) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLineToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatLine[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToError[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilderThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringBuilder[T](System.Text.StringBuilder, Microsoft.FSharp.Core.PrintfFormat`4[T,System.Text.StringBuilder,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThenFail[T,TResult](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[System.String,TResult], Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToStringThen[T](Microsoft.FSharp.Core.PrintfFormat`4[T,Microsoft.FSharp.Core.Unit,System.String,System.String]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriterThen[TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,TResult], System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,TResult]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormatToTextWriter[T](System.IO.TextWriter, Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.PrintfModule: T PrintFormat[T](Microsoft.FSharp.Core.PrintfFormat`4[T,System.IO.TextWriter,Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) -Microsoft.FSharp.Core.ProjectionParameterAttribute: Void .ctor() -Microsoft.FSharp.Core.ReferenceEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean IncludeValue -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Boolean get_IncludeValue() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor() -Microsoft.FSharp.Core.ReflectedDefinitionAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.RequireQualifiedAccessAttribute: Void .ctor() -Microsoft.FSharp.Core.RequiresExplicitTypeArgumentsAttribute: Void .ctor() -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[T,TResult] MapError[TError,TResult,T](Microsoft.FSharp.Core.FSharpFunc`2[TError,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Bind[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpResult`2[TResult,TError]], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.ResultModule: Microsoft.FSharp.Core.FSharpResult`2[TResult,TError] Map[T,TResult,TError](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpResult`2[T,TError]) -Microsoft.FSharp.Core.SealedAttribute: Boolean Value -Microsoft.FSharp.Core.SealedAttribute: Boolean get_Value() -Microsoft.FSharp.Core.SealedAttribute: Void .ctor() -Microsoft.FSharp.Core.SealedAttribute: Void .ctor(Boolean) -Microsoft.FSharp.Core.SourceConstructFlags: Int32 value__ -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Closure -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Exception -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Field -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags KindMask -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Module -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags NonPublicRepresentation -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags None -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags ObjectType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags RecordType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags SumType -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags UnionCase -Microsoft.FSharp.Core.SourceConstructFlags: Microsoft.FSharp.Core.SourceConstructFlags Value -Microsoft.FSharp.Core.StringModule: Boolean Exists(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: Boolean ForAll(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: Int32 Length(System.String) -Microsoft.FSharp.Core.StringModule: System.String Collect(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.String], System.String) -Microsoft.FSharp.Core.StringModule: System.String Concat(System.String, System.Collections.Generic.IEnumerable`1[System.String]) -Microsoft.FSharp.Core.StringModule: System.String Filter(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Boolean], System.String) -Microsoft.FSharp.Core.StringModule: System.String Initialize(Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String]) -Microsoft.FSharp.Core.StringModule: System.String Map(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char], System.String) -Microsoft.FSharp.Core.StringModule: System.String MapIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,System.Char]], System.String) -Microsoft.FSharp.Core.StringModule: System.String Replicate(Int32, System.String) -Microsoft.FSharp.Core.StringModule: Void Iterate(Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit], System.String) -Microsoft.FSharp.Core.StringModule: Void IterateIndexed(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Char,Microsoft.FSharp.Core.Unit]], System.String) -Microsoft.FSharp.Core.StructAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuralComparisonAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuralEqualityAttribute: Void .ctor() -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String Value -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: System.String get_Value() -Microsoft.FSharp.Core.StructuredFormatDisplayAttribute: Void .ctor(System.String) -Microsoft.FSharp.Core.Unit: Boolean Equals(System.Object) -Microsoft.FSharp.Core.Unit: Int32 GetHashCode() -Microsoft.FSharp.Core.UnverifiableAttribute: Void .ctor() -Microsoft.FSharp.Core.ValueOption: Boolean Contains[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean IsNone[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Boolean IsSome[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Int32 Count[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Bind[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpValueOption`1[TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map2[T1,T2,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TResult]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map3[T1,T2,T3,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[T3,TResult]]], Microsoft.FSharp.Core.FSharpValueOption`1[T1], Microsoft.FSharp.Core.FSharpValueOption`1[T2], Microsoft.FSharp.Core.FSharpValueOption`1[T3]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] Flatten[T](Microsoft.FSharp.Core.FSharpValueOption`1[Microsoft.FSharp.Core.FSharpValueOption`1[T]]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfNullable[T](System.Nullable`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OfObj[T](T) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElseWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.FSharpValueOption`1[T]], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Microsoft.FSharp.Core.FSharpValueOption`1[T] OrElse[T](Microsoft.FSharp.Core.FSharpValueOption`1[T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: System.Nullable`1[T] ToNullable[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T DefaultValue[T](T, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T DefaultWith[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T GetValue[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T ToObj[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Core.FSharpValueOption`1[T], TState) -Microsoft.FSharp.Core.ValueOption: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: T[] ToArray[T](Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.ValueOption: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpValueOption`1[T]) -Microsoft.FSharp.Core.VolatileFieldAttribute: Void .ctor() -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToByte[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Byte] ToUInt8[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Char] ToChar[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Decimal] ToDecimal[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToDouble[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Double] ToFloat[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int16] ToInt16[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int32] ToInt[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Int64] ToInt64[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.IntPtr] ToIntPtr[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToInt8[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.SByte] ToSByte[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToFloat32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.Single] ToSingle[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt16] ToUInt16[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt32] ToUInt32[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UInt64] ToUInt64[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[System.UIntPtr] ToUIntPtr[T](System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableModule: System.Nullable`1[TResult] ToEnum[TResult](System.Nullable`1[System.Int32]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_EqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterEqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_GreaterQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessEqualsQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessGreaterQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_LessQmark[T](T, System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkGreater[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEqualsQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessEquals[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreaterQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessGreater[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLessQmark[T](System.Nullable`1[T], System.Nullable`1[T]) -Microsoft.FSharp.Linq.NullableOperators: Boolean op_QmarkLess[T](System.Nullable`1[T], T) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_DivideQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MinusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_MultiplyQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PercentQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_PlusQmark[T1,T2,T3](T1, System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivideQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkDivide[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMinus[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiplyQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkMultiply[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercentQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPercent[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlusQmark[T1,T2,T3](System.Nullable`1[T1], System.Nullable`1[T2]) -Microsoft.FSharp.Linq.NullableOperators: System.Nullable`1[T3] op_QmarkPlus[T1,T2,T3](System.Nullable`1[T1], T2) -Microsoft.FSharp.Linq.QueryBuilder: Boolean All[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Boolean Contains[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], T) -Microsoft.FSharp.Linq.QueryBuilder: Boolean Exists[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Int32 Count[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,TValue],Q] GroupValBy[T,TKey,TValue,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[System.Linq.IGrouping`2[TKey,T],Q] GroupBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Distinct[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SkipWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Skip[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] SortBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Source[T,Q](System.Linq.IQueryable`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] TakeWhile[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Take[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullableDescending[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenByNullable[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TKey]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] ThenBy[T,Q,TKey](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TKey]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Where[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] YieldFrom[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Yield[T,Q](T) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,Q] Zero[T,Q]() -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable] Source[T](System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] For[T,Q,TResult,Q2](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Linq.QuerySource`2[TResult,Q2]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] GroupJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Join[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[TInner,TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] LeftOuterJoin[TOuter,Q,TInner,TKey,TResult](Microsoft.FSharp.Linq.QuerySource`2[TOuter,Q], Microsoft.FSharp.Linq.QuerySource`2[TInner,Q], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TInner,TKey], Microsoft.FSharp.Core.FSharpFunc`2[TOuter,Microsoft.FSharp.Core.FSharpFunc`2[System.Collections.Generic.IEnumerable`1[TInner],TResult]]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Linq.QuerySource`2[TResult,Q] Select[T,Q,TResult](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]) -Microsoft.FSharp.Linq.QueryBuilder: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Quote[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.QueryBuilder: System.Linq.IQueryable`1[T] Run[T](Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Linq.IQueryable]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] AverageByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MaxByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] MinByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: System.Nullable`1[TValue] SumByNullable[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Nullable`1[TValue]]) -Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOneOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T ExactlyOne[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Find[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean]) -Microsoft.FSharp.Linq.QueryBuilder: T HeadOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Head[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T LastOrDefault[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Last[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q]) -Microsoft.FSharp.Linq.QueryBuilder: T Nth[T,Q](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Int32) -Microsoft.FSharp.Linq.QueryBuilder: TValue AverageBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue MaxBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue MinBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: TValue SumBy[T,Q,TValue](Microsoft.FSharp.Linq.QuerySource`2[T,Q], Microsoft.FSharp.Core.FSharpFunc`2[T,TValue]) -Microsoft.FSharp.Linq.QueryBuilder: Void .ctor() -Microsoft.FSharp.Linq.QueryRunExtensions.HighPriority: System.Collections.Generic.IEnumerable`1[T] RunQueryAsEnumerable[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[Microsoft.FSharp.Linq.QuerySource`2[T,System.Collections.IEnumerable]]) -Microsoft.FSharp.Linq.QueryRunExtensions.LowPriority: T RunQueryAsValue[T](Microsoft.FSharp.Linq.QueryBuilder, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] Source -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: System.Collections.Generic.IEnumerable`1[T] get_Source() -Microsoft.FSharp.Linq.QuerySource`2[T,Q]: Void .ctor(System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`1[T1]: Void .ctor(T1) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`2[T1,T2]: Void .ctor(T1, T2) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`3[T1,T2,T3]: Void .ctor(T1, T2, T3) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`4[T1,T2,T3,T4]: Void .ctor(T1, T2, T3, T4) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`5[T1,T2,T3,T4,T5]: Void .ctor(T1, T2, T3, T4, T5) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`6[T1,T2,T3,T4,T5,T6]: Void .ctor(T1, T2, T3, T4, T5, T6) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 Item7 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: T7 get_Item7() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`7[T1,T2,T3,T4,T5,T6,T7]: Void .ctor(T1, T2, T3, T4, T5, T6, T7) -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 Item1 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T1 get_Item1() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 Item2 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T2 get_Item2() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 Item3 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T3 get_Item3() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 Item4 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T4 get_Item4() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 Item5 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T5 get_Item5() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 Item6 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T6 get_Item6() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 Item7 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T7 get_Item7() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 Item8 -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: T8 get_Item8() -Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject`8[T1,T2,T3,T4,T5,T6,T7,T8]: Void .ctor(T1, T2, T3, T4, T5, T6, T7, T8) -Microsoft.FSharp.Linq.RuntimeHelpers.Grouping`2[K,T]: Void .ctor(K, System.Collections.Generic.IEnumerable`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr SubstHelperRaw(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: Microsoft.FSharp.Quotations.FSharpExpr`1[T] SubstHelper[T](Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar[], System.Object[]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression QuotationToExpression(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] ImplicitExpressionConversionHelper[T](T) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Linq.Expressions.Expression`1[T] QuotationToLambdaExpression[T](Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: System.Object EvaluateQuotation(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T MemberInitializationHelper[T](T) -Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter: T NewAnonymousObjectHelper[T](T) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr AddPointerInlined[T](IntPtr, Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfNativeIntInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfVoidPtrInlined[T](Void*) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr StackAllocate[T](Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr ToNativeIntInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: T GetPointerInlined[T](IntPtr, Int32) -Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: T& ToByRefInlined[T](IntPtr) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T) -Microsoft.FSharp.NativeInterop.NativePtrModule: Void* ToVoidPtrInlined[T](IntPtr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.Unit] UnitPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] MethodWithReflectedDefinitionPattern(System.Reflection.MethodBase) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertyGetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] PropertySetterWithReflectedDefinitionPattern(System.Reflection.PropertyInfo) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Boolean] BoolPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Byte] BytePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Char] CharPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Decimal] DecimalPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Double] DoublePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int16] Int16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] Int32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int64] Int64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.SByte] SBytePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Single] SinglePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.String] StringPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar]],Microsoft.FSharp.Quotations.FSharpExpr]] LambdasPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] ApplicationsPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AndAlsoPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] OrElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt16] UInt16Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt32] UInt32Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.UInt64] UInt64Pattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Core.FSharpChoice`3[Microsoft.FSharp.Quotations.FSharpVar,System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr],System.Tuple`2[System.Object,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] ShapePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.ExprShapeModule: Microsoft.FSharp.Quotations.FSharpExpr RebuildShapeCombination(System.Object, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpExpr: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] CustomAttributes -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] get_CustomAttributes() -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] TryGetReflectedDefinition(System.Reflection.MethodBase) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressOf(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr AddressSet(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Application(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Applications(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Call(System.Reflection.MethodInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Coerce(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr DefaultValue(System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize(System.Type, Microsoft.FSharp.Collections.FSharpList`1[System.Type], Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr], Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Deserialize40(System.Type, System.Type[], System.Type[], Microsoft.FSharp.Quotations.FSharpExpr[], Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldGet(System.Reflection.FieldInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr FieldSet(System.Reflection.FieldInfo, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ForIntegerRangeLoop(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr IfThenElse(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Lambda(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Let(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr LetRecursive(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]], Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewArray(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertyGet(System.Reflection.PropertyInfo, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(Microsoft.FSharp.Quotations.FSharpExpr, System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr PropertySet(System.Reflection.PropertyInfo, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Quote(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteRaw(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr QuoteTyped(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Sequential(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Substitute(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryFinally(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TryWith(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TupleGet(Microsoft.FSharp.Quotations.FSharpExpr, Int32) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr TypeTest(Microsoft.FSharp.Quotations.FSharpExpr, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr UnionCaseTest(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Reflection.UnionCaseInfo) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value(System.Object, System.Type) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName(System.Object, System.Type, System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr ValueWithName[T](T, System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Value[T](T) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr Var(Microsoft.FSharp.Quotations.FSharpVar) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr VarSet(Microsoft.FSharp.Quotations.FSharpVar, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WhileLoop(Microsoft.FSharp.Quotations.FSharpExpr, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr WithValue(System.Object, System.Type, Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] Cast[T](Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] GlobalVar[T](System.String) -Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr`1[T] WithValue[T](T, Microsoft.FSharp.Quotations.FSharpExpr`1[T]) -Microsoft.FSharp.Quotations.FSharpExpr: System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Quotations.FSharpVar] GetFreeVars() -Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString() -Microsoft.FSharp.Quotations.FSharpExpr: System.String ToString(Boolean) -Microsoft.FSharp.Quotations.FSharpExpr: System.Type Type -Microsoft.FSharp.Quotations.FSharpExpr: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[]) -Microsoft.FSharp.Quotations.FSharpExpr: Void RegisterReflectedDefinitions(System.Reflection.Assembly, System.String, Byte[], System.Type[]) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] CustomAttributes -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr] get_CustomAttributes() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr Raw -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr Substitute(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr]]) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: Microsoft.FSharp.Quotations.FSharpExpr get_Raw() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Quotations.FSharpVar] GetFreeVars() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.String ToString() -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.String ToString(Boolean) -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Type Type -Microsoft.FSharp.Quotations.FSharpExpr`1[T]: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpVar: Boolean Equals(System.Object) -Microsoft.FSharp.Quotations.FSharpVar: Boolean IsMutable -Microsoft.FSharp.Quotations.FSharpVar: Boolean get_IsMutable() -Microsoft.FSharp.Quotations.FSharpVar: Int32 GetHashCode() -Microsoft.FSharp.Quotations.FSharpVar: Microsoft.FSharp.Quotations.FSharpVar Global(System.String, System.Type) -Microsoft.FSharp.Quotations.FSharpVar: System.String Name -Microsoft.FSharp.Quotations.FSharpVar: System.String ToString() -Microsoft.FSharp.Quotations.FSharpVar: System.String get_Name() -Microsoft.FSharp.Quotations.FSharpVar: System.Type Type -Microsoft.FSharp.Quotations.FSharpVar: System.Type get_Type() -Microsoft.FSharp.Quotations.FSharpVar: Void .ctor(System.String, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewStructTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]] NewTuplePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] AddressOfPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuotePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteRawPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr] QuoteTypedPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpVar] VarPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]],Microsoft.FSharp.Quotations.FSharpExpr]] LetRecursivePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo]] FieldGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] AddressSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ApplicationPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] SequentialPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] TryFinallyPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] WhileLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Reflection.UnionCaseInfo]] UnionCaseTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Int32]] TupleGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] CoercePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpExpr,System.Type]] TypeTestPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] LambdaPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] VarSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewUnionCasePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Object,System.Type]] ValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewObjectPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewArrayPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] NewRecordPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.FieldInfo,Microsoft.FSharp.Quotations.FSharpExpr]] FieldSetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.MethodInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] CallPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]] PropertyGetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] IfThenElsePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] LetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,Microsoft.FSharp.Quotations.FSharpExpr]] WithValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Object,System.Type,System.String]] ValueWithNamePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.Type,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar],Microsoft.FSharp.Quotations.FSharpExpr]] NewDelegatePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],System.Reflection.PropertyInfo,Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Quotations.FSharpExpr]] PropertySetPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`4[Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpExpr]] ForIntegerRangeLoopPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Quotations.FSharpVar,Microsoft.FSharp.Quotations.FSharpExpr]] TryWithPattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Quotations.PatternsModule: Microsoft.FSharp.Core.FSharpOption`1[System.Type] DefaultValuePattern(Microsoft.FSharp.Quotations.FSharpExpr) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsExceptionRepresentation.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsRecord.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Boolean FSharpType.IsUnion.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] FSharpValue.PreComputeUnionTagReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeRecordReader.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] FSharpValue.PreComputeUnionReader.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeRecordConstructor.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] FSharpValue.PreComputeUnionConstructor.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: Microsoft.FSharp.Reflection.UnionCaseInfo[] FSharpType.GetUnionCases.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeRecord.Static(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object FSharpValue.MakeUnion.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetExceptionFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Object[] FSharpValue.GetRecordFields.Static(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.ConstructorInfo FSharpValue.PreComputeRecordConstructorInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MemberInfo FSharpValue.PreComputeUnionTagMemberInfo.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.MethodInfo FSharpValue.PreComputeUnionConstructorInfo.Static(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetExceptionFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Reflection.PropertyInfo[] FSharpType.GetRecordFields.Static(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpReflectionExtensions: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] FSharpValue.GetUnionFields.Static(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsExceptionRepresentation(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsFunction(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsModule(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsRecord(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsTuple(System.Type) -Microsoft.FSharp.Reflection.FSharpType: Boolean IsUnion(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: Microsoft.FSharp.Reflection.UnionCaseInfo[] GetUnionCases(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetExceptionFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetRecordFields(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) -Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Int32] PreComputeUnionTagReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeRecordReader(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeTupleReader(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object[]] PreComputeUnionReader(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object] PreComputeRecordFieldReader(System.Reflection.PropertyInfo) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeRecordConstructor(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeTupleConstructor(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: Microsoft.FSharp.Core.FSharpFunc`2[System.Object[],System.Object] PreComputeUnionConstructor(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object GetRecordField(System.Object, System.Reflection.PropertyInfo) -Microsoft.FSharp.Reflection.FSharpValue: System.Object GetTupleField(System.Object, Int32) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeFunction(System.Type, Microsoft.FSharp.Core.FSharpFunc`2[System.Object,System.Object]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeRecord(System.Type, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeTuple(System.Object[], System.Type) -Microsoft.FSharp.Reflection.FSharpValue: System.Object MakeUnion(Microsoft.FSharp.Reflection.UnionCaseInfo, System.Object[], Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetExceptionFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetRecordFields(System.Object, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Object[] GetTupleFields(System.Object) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.ConstructorInfo PreComputeRecordConstructorInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MemberInfo PreComputeUnionTagMemberInfo(System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Reflection.MethodInfo PreComputeUnionConstructorInfo(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[Microsoft.FSharp.Reflection.UnionCaseInfo,System.Object[]] GetUnionFields(System.Object, System.Type, Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.BindingFlags]) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.ConstructorInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Type]] PreComputeTupleConstructorInfo(System.Type) -Microsoft.FSharp.Reflection.FSharpValue: System.Tuple`2[System.Reflection.PropertyInfo,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.Type,System.Int32]]] PreComputeTuplePropertyInfo(System.Type, Int32) -Microsoft.FSharp.Reflection.UnionCaseInfo: Boolean Equals(System.Object) -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 GetHashCode() -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 Tag -Microsoft.FSharp.Reflection.UnionCaseInfo: Int32 get_Tag() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Collections.Generic.IList`1[System.Reflection.CustomAttributeData] GetCustomAttributesData() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Object[] GetCustomAttributes(System.Type) -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Reflection.PropertyInfo[] GetFields() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String Name -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String ToString() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.String get_Name() -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type DeclaringType -Microsoft.FSharp.Reflection.UnionCaseInfo: System.Type get_DeclaringType() -" -#if DEBUG - let expected = - expected + - @"Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult])" -#endif -#if CROSS_PLATFORM_COMPILER - () - // disabled because of slight order and GetMember discrepencies -#else - SurfaceArea.verify expected "net40" (System.IO.Path.Combine(__SOURCE_DIRECTORY__,__SOURCE_FILE__)) -#endif diff --git a/tests/FSharp.Core.UnitTests/TestFrameworkHelpers.fs b/tests/FSharp.Core.UnitTests/TestFrameworkHelpers.fs new file mode 100644 index 00000000000..03f42a01d30 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/TestFrameworkHelpers.fs @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Xunit + +open System +open System.Collections.Generic +open System.Linq +open System.Runtime.InteropServices + +open Xunit + +module Info = + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX86Runtime = sizeof = 4 + + /// Use this to distinguish cases where output is deterministically different between x86 runtime or x64 runtime, + /// for instance w.r.t. floating point arithmetic. For more info, see https://github.com/dotnet/roslyn/issues/7333 + let isX64Runtime = sizeof = 8 + + let framework = RuntimeInformation.FrameworkDescription + + /// Whether a test is run inside a .NET Core Runtime + let isNetCore = framework.StartsWith(".NET Core") + + /// Whether a test is run using a .NET Framework Runtime + let isNetFramework = framework.StartsWith(".NET Framework") + + /// Whether a test is run after being compiled to .NET Native + let isNetNative = framework.StartsWith(".NET Native") + + +module private Impl = + + let rec equals (expected:obj) (actual:obj) = + + // get length expected + let toArray (o:obj) = + match o with + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> Enumerable.ToArray(seq) :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | :? seq as seq -> seq |> Seq.toArray :>obj + | _ -> o + + // get length expected + let expected = toArray expected + let actual = toArray actual + + match expected, actual with + | (:? Array as a1), (:? Array as a2) -> + if a1.Rank > 1 then failwith "Rank > 1 not supported" + if a2.Rank > 1 then false + else + let lb = a1.GetLowerBound(0) + let ub = a1.GetUpperBound(0) + if lb <> a2.GetLowerBound(0) || ub <> a2.GetUpperBound(0) then false + else + {lb..ub} |> Seq.forall(fun i -> equals (a1.GetValue(i)) (a2.GetValue(i))) + | _ -> + Object.Equals(expected, actual) + + /// Special treatment of float and float32 to get a somewhat meaningful error message + /// (otherwise, the missing precision leads to different values that are close together looking the same) + let floatStr (flt1: obj) (flt2: obj) = + match flt1, flt2 with + | :? float as flt1, (:? float as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | :? float32 as flt1, (:? float32 as flt2) -> + flt1.ToString("R"), flt2.ToString("R") + + | _ -> flt1.ToString(), flt2.ToString() + + +type Assert = + + static member AreEqual(expected : obj, actual : obj, message : string) = + if not (Impl.equals expected actual) then + let message = + let (exp, act) = Impl.floatStr expected actual + sprintf "%s: Expected %s but got %s" message exp act + + Exception message |> raise + + static member AreNotEqual(expected : obj, actual : obj, message : string) = + if Impl.equals expected actual then + let message = sprintf "%s: Expected not %A but got %A" message expected actual + Exception message |> raise + + static member AreEqual(expected : obj, actual : obj) = Assert.AreEqual(expected, actual, "Assertion") + + /// Use this to compare floats within a delta of 1e-15, useful for discrepancies + /// between 80-bit (dotnet, RyuJIT) and 64-bit (x86, Legacy JIT) floating point calculations + static member AreNearEqual(expected: float, actual: float) = + let delta = 1.0e-15 + let message = + let ((e, a)) = Impl.floatStr expected actual + sprintf "Are near equal: expected %s, but got %s (with delta: %f)" e a delta + + Assert.AreEqual(Math.Round(expected, 15), Math.Round(actual, 15), message) + + static member AreNotEqual(expected: obj, actual: obj) = Assert.AreNotEqual(expected, actual, "Assertion") + + static member Fail(message : string) = Exception(message) |> raise + + static member Fail() = Assert.Fail("") + + static member Fail(message : string, args : obj[]) = Assert.Fail(String.Format(message,args)) + +type CollectionAssert = + static member AreEqual(expected, actual) = + Assert.AreEqual(expected, actual) + diff --git a/tests/FSharp.Core.UnitTests/TypeForwarding.fs b/tests/FSharp.Core.UnitTests/TypeForwarding.fs index 28d53156a60..524d62e65ee 100644 --- a/tests/FSharp.Core.UnitTests/TypeForwarding.fs +++ b/tests/FSharp.Core.UnitTests/TypeForwarding.fs @@ -2,16 +2,16 @@ // Various tests for Microsoft.FSharp.Core type forwarding -namespace FSharp.Core.UnitTests.FSharp_Core.Type_Forwarding +namespace FSharp.Core.UnitTests.Type_Forwarding open System open FSharp.Core.UnitTests.LibraryTestFx -open NUnit.Framework +open Xunit #if NET46 [] type TypeForwardingModule() = - [] + [] member this.TypeForwarding() = let currentRuntimeVersion = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion() let currentFSharpCoreTargetRuntime = typeof.Assembly.ImageRuntimeVersion diff --git a/tests/FSharp.Core.UnitTests/xunit.runner.json b/tests/FSharp.Core.UnitTests/xunit.runner.json new file mode 100644 index 00000000000..ff6ac3098c1 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/xunit.runner.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "appDomain": "denied", + "shadowCopy": false, + "parallelizeTestCollections": false, + "maxParallelThreads": 1 +} diff --git a/tests/FSharp.DependencyManager.UnitTests/DependencyManagerInteractiveTests.fs b/tests/FSharp.DependencyManager.UnitTests/DependencyManagerInteractiveTests.fs deleted file mode 100644 index 1b15cd7cfaa..00000000000 --- a/tests/FSharp.DependencyManager.UnitTests/DependencyManagerInteractiveTests.fs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.DependencyManager.UnitTests - -open System -open System.IO -open FSharp.Compiler.Interactive.Shell -open FSharp.Compiler.Scripting -open FSharp.Compiler.SourceCodeServices - -open NUnit.Framework - -[] -type DependencyManagerInteractiveTests() = - - let getValue ((value: Result), (errors: FSharpErrorInfo[])) = - if errors.Length > 0 then - failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors)) - match value with - | Ok(value) -> value - | Error ex -> raise ex - - let ignoreValue = getValue >> ignore - - let scriptHost () = new FSharpScript(additionalArgs=[|"/langversion:preview"|]) - - [] - member __.``SmokeTest - #r nuget``() = - let text = """ -#r @"nuget:System.Collections.Immutable, version=1.5.0" -0""" - use script = scriptHost() - let mutable assemblyResolveEventCount = 0 - let mutable foundAssemblyReference = false - Event.add (fun (assembly: string) -> - assemblyResolveEventCount <- assemblyResolveEventCount + 1 - foundAssemblyReference <- String.Compare("System.Collections.Immutable.dll", Path.GetFileName(assembly), StringComparison.OrdinalIgnoreCase) = 0) - script.AssemblyReferenceAdded - let opt = script.Eval(text) |> getValue - let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual(0, value.ReflectionValue :?> int) - Assert.AreEqual(1, assemblyResolveEventCount) - Assert.AreEqual(true, foundAssemblyReference) - - [] - member __.``SmokeTest - #r nuget package not found``() = - let text = """ -#r @"nuget:System.Collections.Immutable.DoesNotExist, version=1.5.0" -0""" - use script = scriptHost() - let mutable assemblyResolveEventCount = 0 - Event.add (fun (assembly: string) -> - assemblyResolveEventCount <- assemblyResolveEventCount + 1) - script.AssemblyReferenceAdded - let opt = script.Eval(text) |> getValue - let value = opt.Value - Assert.AreEqual(typeof, value.ReflectionType) - Assert.AreEqual(0, value.ReflectionValue :?> int) - Assert.AreEqual(0, assemblyResolveEventCount) - - [] - member __.``Dependency add events successful``() = - let referenceText = "System.Collections.Immutable, version=1.5.0" - let text = referenceText |> sprintf """ -#r @"nuget:%s" -0""" - use script = scriptHost() - let mutable dependencyAddingEventCount = 0 - let mutable dependencyAddedEventCount = 0 - let mutable foundDependencyAdding = false - let mutable foundDependencyAdded = false - Event.add (fun (dep: string * string) -> - let key, dependency = dep - dependencyAddingEventCount <- dependencyAddingEventCount + 1 - foundDependencyAdding <- foundDependencyAdding || (key = "nuget" && dependency = referenceText)) - script.DependencyAdding - Event.add (fun (dep: string * string) -> - let key, dependency = dep - dependencyAddedEventCount <- dependencyAddedEventCount + 1 - foundDependencyAdded <- foundDependencyAdded || (key = "nuget" && dependency = referenceText)) - script.DependencyAdded - script.Eval(text) |> ignoreValue - Assert.AreEqual(1, dependencyAddingEventCount) - Assert.AreEqual(1, dependencyAddedEventCount) - Assert.AreEqual(true, foundDependencyAdding) - Assert.AreEqual(true, foundDependencyAdded) - - [] - member __.``Dependency add events failed``() = - let referenceText = "System.Collections.Immutable.DoesNotExist, version=1.5.0" - let text = referenceText |> sprintf """ -#r @"nuget:%s" -0""" - use script = scriptHost() - let mutable dependencyAddingEventCount = 0 - let mutable dependencyFailedEventCount = 0 - let mutable foundDependencyAdding = false - let mutable foundDependencyFailed = false - Event.add (fun (dep: string * string) -> - let key, dependency = dep - dependencyAddingEventCount <- dependencyAddingEventCount + 1 - foundDependencyAdding <- foundDependencyAdding || (key = "nuget" && dependency = referenceText)) - script.DependencyAdding - Event.add (fun (dep: string * string) -> - let key, dependency = dep - dependencyFailedEventCount <- dependencyFailedEventCount + 1 - foundDependencyFailed <- foundDependencyFailed || (key = "nuget" && dependency = referenceText)) - script.DependencyFailed - script.Eval(text) |> ignoreValue - Assert.AreEqual(1, dependencyAddingEventCount) - Assert.AreEqual(1, dependencyFailedEventCount) - Assert.AreEqual(true, foundDependencyAdding) - Assert.AreEqual(true, foundDependencyFailed) - - [] - member __.``Dependency add events aren't repeated``() = - use script = scriptHost() - let mutable dependencyAddingEventCount = 0 - Event.add (fun _ -> dependencyAddingEventCount <- dependencyAddingEventCount + 1) script.DependencyAdding - script.Eval("#r \"nuget:System.Collections.Immutable, Version=1.5.0\"") |> ignoreValue - script.Eval("#r \"nuget:Newtonsoft.Json, Version=9.0.1\"\n0") |> ignoreValue - Assert.AreEqual(2, dependencyAddingEventCount) diff --git a/tests/FSharp.DependencyManager.UnitTests/DependencyManagerLineParserTests.fs b/tests/FSharp.DependencyManager.UnitTests/DependencyManagerLineParserTests.fs deleted file mode 100644 index a655b261984..00000000000 --- a/tests/FSharp.DependencyManager.UnitTests/DependencyManagerLineParserTests.fs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.DependencyManager.UnitTests - -open System.Linq -open FSharp.DependencyManager -open NUnit.Framework - -[] -type DependencyManagerLineParserTests() = - - let parseBinLogPath text = - let _, binLogPath = FSharpDependencyManager.parsePackageReference [text] - binLogPath - - let parseSingleReference text = - let packageReferences, _ = FSharpDependencyManager.parsePackageReference [text] - packageReferences.Single() - - [] - member __.``Binary logging defaults to disabled``() = - let _, binLogPath = FSharpDependencyManager.parsePackageReference [] - Assert.AreEqual(None, binLogPath) - - [] - member __.``Binary logging can be set to default path``() = - let binLogPath = parseBinLogPath "bl=true" - Assert.AreEqual(Some (None: string option), binLogPath) - - [] - member __.``Binary logging can be disabled``() = - let binLogPath = parseBinLogPath "bl=false" - Assert.AreEqual(None, binLogPath) - - [] - member __.``Binary logging can be set to specific location``() = - let binLogPath = parseBinLogPath "bl=path/to/file.binlog" - Assert.AreEqual(Some(Some "path/to/file.binlog"), binLogPath) - - [] - member __.``Bare binary log argument isn't parsed as a package name: before``() = - let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ["bl, MyPackage"] - Assert.AreEqual("MyPackage", packageReferences.Single().Include) - Assert.AreEqual(Some (None: string option), binLogPath) - - [] - member __.``Bare binary log argument isn't parsed as a package name: middle``() = - let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ["MyPackage, bl, 1.2.3.4"] - Assert.AreEqual("MyPackage", packageReferences.Single().Include) - Assert.AreEqual("1.2.3.4", packageReferences.Single().Version) - Assert.AreEqual(Some (None: string option), binLogPath) - - [] - member __.``Bare binary log argument isn't parsed as a package name: after``() = - let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ["MyPackage, bl"] - Assert.AreEqual("MyPackage", packageReferences.Single().Include) - Assert.AreEqual(Some (None: string option), binLogPath) - - [] - member __.``Package named 'bl' can be explicitly referenced``() = - let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ["Include=bl"] - Assert.AreEqual("bl", packageReferences.Single().Include) - Assert.AreEqual(None, binLogPath) - - [] - member __.``Package named 'bl' can be explicitly referenced with binary logging``() = - let packageReferences, binLogPath = FSharpDependencyManager.parsePackageReference ["Include=bl,bl"] - Assert.AreEqual("bl", packageReferences.Single().Include) - Assert.AreEqual(Some (None: string option), binLogPath) - - [] - member __.``Parse explicitly specified package name``() = - let pr = parseSingleReference "Include=MyPackage" - Assert.AreEqual("MyPackage", pr.Include) - - [] - member __.``Parse implicitly specified package name``() = - let pr = parseSingleReference "MyPackage" - Assert.AreEqual("MyPackage", pr.Include) - - [] - member __.``Parse version number``() = - let pr = parseSingleReference "MyPackage, Version=1.2.3.4" - Assert.AreEqual("1.2.3.4", pr.Version) - - [] - member __.``Parse implicitly specified package name and implicitly specified version number``() = - let pr = parseSingleReference "MyPackage, 1.2.3.4" - Assert.AreEqual("MyPackage", pr.Include) - Assert.AreEqual("1.2.3.4", pr.Version) - - [] - member __.``Parse single restore source``() = - let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource" - Assert.AreEqual("MyRestoreSource", pr.RestoreSources) - - [] - member __.``Parse multiple restore sources``() = - let pr = parseSingleReference "MyPackage, RestoreSources=MyRestoreSource1, RestoreSources=MyRestoreSource2" - Assert.AreEqual("MyRestoreSource1;MyRestoreSource2", pr.RestoreSources) - - [] - member __.``Parse script``() = - let pr = parseSingleReference "MyPackage, Script=SomeScript" - Assert.AreEqual("SomeScript", pr.Script) - - [] - member __.``Include strings that look different but parse the same are reduced to a single item``() = - let prs, _ = - [ "MyPackage, Version=1.2.3.4" - "Include=MyPackage, Version=1.2.3.4" ] - |> FSharpDependencyManager.parsePackageReference - let pr = prs.Single() - Assert.AreEqual("MyPackage", pr.Include) diff --git a/tests/FSharp.DependencyManager.UnitTests/Directory.Build.props b/tests/FSharp.DependencyManager.UnitTests/Directory.Build.props deleted file mode 100644 index 7cd41381b5d..00000000000 --- a/tests/FSharp.DependencyManager.UnitTests/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - true - - - - - diff --git a/tests/FSharp.DependencyManager.UnitTests/FSharp.DependencyManager.UnitTests.fsproj b/tests/FSharp.DependencyManager.UnitTests/FSharp.DependencyManager.UnitTests.fsproj deleted file mode 100644 index 042986e8ada..00000000000 --- a/tests/FSharp.DependencyManager.UnitTests/FSharp.DependencyManager.UnitTests.fsproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - - net472;netcoreapp3.0 - netcoreapp3.0 - Library - true - nunit - true - - - - - - - - - - - - - - - diff --git a/tests/FSharp.Test.Utilities/Assert.fs b/tests/FSharp.Test.Utilities/Assert.fs new file mode 100644 index 00000000000..41af78c735d --- /dev/null +++ b/tests/FSharp.Test.Utilities/Assert.fs @@ -0,0 +1,26 @@ +namespace FSharp.Test + +module Assert = + open FluentAssertions + open System.Collections + + let inline shouldBeEqualWith (expected : ^T) (message: string) (actual: ^U) = + actual.Should().BeEquivalentTo(expected, message) |> ignore + + let inline shouldBeEquivalentTo (expected : ^T) (actual : ^U) = + actual.Should().BeEquivalentTo(expected, "") |> ignore + + let inline shouldBe (expected : ^T) (actual : ^U) = + actual.Should().Be(expected, "") |> ignore + + let inline shouldBeEmpty (actual : ^T when ^T :> IEnumerable) = + actual.Should().BeEmpty("") |> ignore + + let inline shouldNotBeEmpty (actual : ^T when ^T :> IEnumerable) = + actual.Should().NotBeEmpty("") |> ignore + + let shouldBeFalse (actual: bool) = + actual.Should().BeFalse("") |> ignore + + let shouldBeTrue (actual: bool) = + actual.Should().BeTrue("") |> ignore diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs new file mode 100644 index 00000000000..511b0db5a1e --- /dev/null +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -0,0 +1,816 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Test + +open FSharp.Compiler.Interactive.Shell +open FSharp.Compiler.IO +open FSharp.Compiler.Diagnostics +open FSharp.Test.Assert +open FSharp.Test.Utilities +open FSharp.Test.ScriptHelpers +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.CSharp +open NUnit.Framework +open System +open System.Collections.Immutable +open System.IO +open System.Text +open System.Text.RegularExpressions + + +module rec Compiler = + type BaselineFile = { FilePath: string; Content: string option } + + type Baseline = + { SourceFilename: string option + OutputBaseline: BaselineFile + ILBaseline: BaselineFile } + + type TestType = + | Text of string + | Path of string + + type CompilationUnit = + | FS of FSharpCompilationSource + | CS of CSharpCompilationSource + | IL of ILCompilationSource + override this.ToString() = match this with | FS fs -> fs.ToString() | _ -> (sprintf "%A" this ) + + type FSharpCompilationSource = + { Source: TestType + Baseline: Baseline option + Options: string list + OutputType: CompileOutput + SourceKind: SourceKind + Name: string option + IgnoreWarnings: bool + References: CompilationUnit list } + override this.ToString() = match this.Name with | Some n -> n | _ -> (sprintf "%A" this) + + type CSharpCompilationSource = + { Source: TestType + LangVersion: CSharpLanguageVersion + TargetFramework: TargetFramework + Name: string option + References: CompilationUnit list } + + type ILCompilationSource = + { Source: TestType + References: CompilationUnit list } + + type ErrorType = Error of int | Warning of int + + type Line = Line of int + type Col = Col of int + + type Range = + { StartLine: int + StartColumn: int + EndLine: int + EndColumn: int } + + type ErrorInfo = + { Error: ErrorType + Range: Range + Message: string } + + type EvalOutput = Result + + type ExecutionOutput = + { ExitCode: int + StdOut: string + StdErr: string } + + type RunOutput = + | EvalOutput of EvalOutput + | ExecutionOutput of ExecutionOutput + + type Output = + { OutputPath: string option + Dependencies: string list + Adjust: int + Diagnostics: ErrorInfo list + Output: RunOutput option } + + type TestResult = + | Success of Output + | Failure of Output + + let private defaultOptions : string list = [] + + // Not very safe version of reading stuff from file, but we want to fail fast for now if anything goes wrong. + let private getSource (src: TestType) : string = + match src with + | Text t -> t + | Path p -> + use stream = FileSystem.OpenFileForReadShim(p) + stream.ReadAllText() + + let private fsFromString (source: string) (kind: SourceKind) : FSharpCompilationSource = + match source with + | null -> failwith "Source cannot be null" + | _ -> + { Source = Text source + Baseline = None + Options = defaultOptions + OutputType = Library + SourceKind = kind + Name = None + IgnoreWarnings = false + References = [] } + + let private csFromString (source: string) : CSharpCompilationSource = + match source with + | null -> failwith "Source cannot be null" + | _ -> + { Source = Text source + LangVersion = CSharpLanguageVersion.CSharp9 + TargetFramework = TargetFramework.Current + Name = None + References = [] } + + let private fromFSharpDiagnostic (errors: FSharpDiagnostic[]) : ErrorInfo list = + let toErrorInfo (e: FSharpDiagnostic) : ErrorInfo = + let errorNumber = e.ErrorNumber + let severity = e.Severity + + let error = if severity = FSharpDiagnosticSeverity.Warning then Warning errorNumber else Error errorNumber + + { Error = error + Range = + { StartLine = e.StartLine + StartColumn = e.StartColumn + EndLine = e.EndLine + EndColumn = e.EndColumn } + Message = e.Message } + + errors + |> List.ofArray + |> List.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message) + |> List.map toErrorInfo + + let private partitionErrors diagnostics = diagnostics |> List.partition (fun e -> match e.Error with Error _ -> true | _ -> false) + + let private getErrors diagnostics = diagnostics |> List.filter (fun e -> match e.Error with Error _ -> true | _ -> false) + + let private getWarnings diagnostics = diagnostics |> List.filter (fun e -> match e.Error with Warning _ -> true | _ -> false) + + let private adjustRange (range: Range) (adjust: int) : Range = + { range with + StartLine = range.StartLine - adjust + StartColumn = range.StartColumn + 1 + EndLine = range.EndLine - adjust + EndColumn = range.EndColumn + 1 } + + let Fsx (source: string) : CompilationUnit = + fsFromString source SourceKind.Fsx |> FS + + let FSharp (source: string) : CompilationUnit = + fsFromString source SourceKind.Fs |> FS + + let CSharp (source: string) : CompilationUnit = + csFromString source |> CS + + let asFsx (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS src -> FS { src with SourceKind = SourceKind.Fsx } + | _ -> failwith "Only F# compilation can be of type Fsx." + + let asFs (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS src -> FS { src with SourceKind = SourceKind.Fs } + | _ -> failwith "Only F# compilation can be of type Fs." + + let withName (name: string) (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS src -> FS { src with Name = Some name } + | CS src -> CS { src with Name = Some name } + | IL _ -> failwith "IL Compilation cannot be named." + + let withReferences (references: CompilationUnit list) (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> FS { fs with References = fs.References @ references } + | CS cs -> CS { cs with References = cs.References @ references } + | IL _ -> failwith "References are not supported in IL" + + let private withOptionsHelper (options: string list) (message:string) (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> FS { fs with Options = fs.Options @ options } + | _ -> failwith message + + let withOptions (options: string list) (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper options "withOptions is only supported for F#" cUnit + + let withErrorRanges (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--test:ErrorRanges" ] "withErrorRanges is only supported on F#" cUnit + + let withLangVersion46 (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--langversion:4.6" ] "withLangVersion46 is only supported on F#" cUnit + + let withLangVersion47 (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--langversion:4.7" ] "withLangVersion47 is only supported on F#" cUnit + + let withLangVersion50 (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--langversion:5.0" ] "withLangVersion50 is only supported on F#" cUnit + + let withLangVersionPreview (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--langversion:preview" ] "withLangVersionPreview is only supported on F#" cUnit + + /// Turns on checks that check integrity of XML doc comments + let withXmlCommentChecking (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--warnon:3390" ] "withXmlCommentChecking is only supported for F#" cUnit + + /// Turns on checks that force the documentation of all parameters + let withXmlCommentStrictParamChecking (cUnit: CompilationUnit) : CompilationUnit = + withOptionsHelper [ "--warnon:3391" ] "withXmlCommentChecking is only supported for F#" cUnit + + let asLibrary (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> FS { fs with OutputType = CompileOutput.Library } + | _ -> failwith "TODO: Implement where applicable." + + let asExe (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> FS { fs with OutputType = CompileOutput.Exe } + | _ -> failwith "TODO: Implement where applicable." + + let ignoreWarnings (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> FS { fs with IgnoreWarnings = true } + | _ -> failwith "TODO: Implement ignorewarnings for the rest." + + let rec private asMetadataReference reference = + match reference with + | CompilationReference (cmpl, _) -> + let result = compileFSharpCompilation cmpl false + match result with + | Failure f -> + let message = sprintf "Operation failed (expected to succeed).\n All errors:\n%A" (f.Diagnostics) + failwith message + | Success s -> + match s.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> p |> MetadataReference.CreateFromFile + | _ -> failwith "Conversion isn't possible" + + let private processReferences (references: CompilationUnit list) = + let rec loop acc = function + | [] -> List.rev acc + | x::xs -> + match x with + | FS fs -> + let refs = loop [] fs.References + let source = getSource fs.Source + let name = defaultArg fs.Name null + let cmpl = Compilation.Create(source, fs.SourceKind, fs.OutputType, cmplRefs = refs, name = name) |> CompilationReference.CreateFSharp + loop (cmpl::acc) xs + | CS cs -> + let refs = loop [] cs.References + let source = getSource cs.Source + let name = defaultArg cs.Name null + let metadataReferences = List.map asMetadataReference refs + let cmpl = CompilationUtil.CreateCSharpCompilation(source, cs.LangVersion, cs.TargetFramework, additionalReferences = metadataReferences.ToImmutableArray().As(), name = name) + |> CompilationReference.Create + loop (cmpl::acc) xs + | IL _ -> failwith "TODO: Process references for IL" + loop [] references + + let private compileFSharpCompilation compilation ignoreWarnings : TestResult = + + let ((err: FSharpDiagnostic[], outputFilePath: string), deps) = CompilerAssert.CompileRaw(compilation, ignoreWarnings) + + let diagnostics = err |> fromFSharpDiagnostic + + let result = + { OutputPath = None + Dependencies = deps + Adjust = 0 + Diagnostics = diagnostics + Output = None } + + let (errors, warnings) = partitionErrors diagnostics + + // Treat warnings as errors if "IgnoreWarnings" is false + if errors.Length > 0 || (warnings.Length > 0 && not ignoreWarnings) then + Failure result + else + Success { result with OutputPath = Some outputFilePath } + + let private compileFSharp (fsSource: FSharpCompilationSource) : TestResult = + + let source = getSource fsSource.Source + let sourceKind = fsSource.SourceKind + let output = fsSource.OutputType + let options = fsSource.Options |> Array.ofList + + let references = processReferences fsSource.References + + let compilation = Compilation.Create(source, sourceKind, output, options, references) + + compileFSharpCompilation compilation fsSource.IgnoreWarnings + + let private compileCSharpCompilation (compilation: CSharpCompilation) : TestResult = + + let outputPath = Path.Combine(Path.GetTempPath(), "FSharpCompilerTests", Path.GetRandomFileName()) + + Directory.CreateDirectory(outputPath) |> ignore + + let filename = compilation.AssemblyName + + let output = Path.Combine(outputPath, Path.ChangeExtension(filename, ".dll")) + + let cmplResult = compilation.Emit (output) + + let result = + { OutputPath = None + Dependencies = [] + Adjust = 0 + Diagnostics = [] + Output = None } + + if cmplResult.Success then + Success { result with OutputPath = Some output } + else + Failure result + + let private compileCSharp (csSource: CSharpCompilationSource) : TestResult = + + let source = getSource csSource.Source + let name = defaultArg csSource.Name (Guid.NewGuid().ToString ()) + + let additionalReferences = + match processReferences csSource.References with + | [] -> ImmutableArray.Empty + | r -> (List.map asMetadataReference r).ToImmutableArray().As() + + let references = TargetFrameworkUtil.getReferences csSource.TargetFramework + + let lv = + match csSource.LangVersion with + | CSharpLanguageVersion.CSharp8 -> LanguageVersion.CSharp8 + | _ -> LanguageVersion.Default + + let cmpl = + CSharpCompilation.Create( + name, + [ CSharpSyntaxTree.ParseText (source, CSharpParseOptions lv) ], + references.As().AddRange additionalReferences, + CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary)) + + cmpl |> compileCSharpCompilation + + let compile (cUnit: CompilationUnit) : TestResult = + match cUnit with + | FS fs -> compileFSharp fs + | CS cs -> compileCSharp cs + | _ -> failwith "TODO" + + let private parseFSharp (fsSource: FSharpCompilationSource) : TestResult = + let source = getSource fsSource.Source + let parseResults = CompilerAssert.Parse source + let failed = parseResults.ParseHadErrors + + let diagnostics = parseResults.Diagnostics |> fromFSharpDiagnostic + + let result = + { OutputPath = None + Dependencies = [] + Adjust = 0 + Diagnostics = diagnostics + Output = None } + + if failed then + Failure result + else + Success result + + let parse (cUnit: CompilationUnit) : TestResult = + match cUnit with + | FS fs -> parseFSharp fs + | _ -> failwith "Parsing only supported for F#." + + let private typecheckFSharpSourceAndReturnErrors (fsSource: FSharpCompilationSource) : FSharpDiagnostic [] = + let source = getSource fsSource.Source + let options = fsSource.Options |> Array.ofList + + let name = match fsSource.Name with | None -> "test.fs" | Some n -> n + + let (err: FSharpDiagnostic []) = CompilerAssert.TypeCheckWithOptionsAndName options name source + + err + + let private typecheckFSharpSource (fsSource: FSharpCompilationSource) : TestResult = + + let (err: FSharpDiagnostic []) = typecheckFSharpSourceAndReturnErrors fsSource + + let diagnostics = err |> fromFSharpDiagnostic + + let result = + { OutputPath = None + Dependencies = [] + Adjust = 0 + Diagnostics = diagnostics + Output = None } + + let (errors, warnings) = partitionErrors diagnostics + + // Treat warnings as errors if "IgnoreWarnings" is false; + if errors.Length > 0 || (warnings.Length > 0 && not fsSource.IgnoreWarnings) then + Failure result + else + Success result + + let private typecheckFSharp (fsSource: FSharpCompilationSource) : TestResult = + match fsSource.Source with + | _ -> typecheckFSharpSource fsSource + + let typecheck (cUnit: CompilationUnit) : TestResult = + match cUnit with + | FS fs -> typecheckFSharp fs + | _ -> failwith "Typecheck only supports F#" + + let typecheckResults (cUnit: CompilationUnit) : FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults = + match cUnit with + | FS fsSource -> + let source = getSource fsSource.Source + let options = fsSource.Options |> Array.ofList + + let name = match fsSource.Name with | None -> "test.fs" | Some n -> n + + CompilerAssert.TypeCheck(options, name, source) + | _ -> failwith "Typecheck only supports F#" + + let run (result: TestResult) : TestResult = + match result with + | Failure f -> failwith (sprintf "Compilation should be successful in order to run.\n Errors: %A" (f.Diagnostics)) + | Success s -> + match s.OutputPath with + | None -> failwith "Compilation didn't produce any output. Unable to run. (Did you forget to set output type to Exe?)" + | Some p -> + let (exitCode, output, errors) = CompilerAssert.ExecuteAndReturnResult (p, s.Dependencies, false) + printfn "---------output-------\n%s\n-------" output + printfn "---------errors-------\n%s\n-------" errors + let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) } + if exitCode = 0 then + Success executionResult + else + Failure executionResult + + let compileAndRun = compile >> run + + let compileExeAndRun = asExe >> compileAndRun + + let private evalFSharp (fs: FSharpCompilationSource) : TestResult = + let source = getSource fs.Source + let options = fs.Options |> Array.ofList + + use script = new FSharpScript(additionalArgs=options) + + let ((evalresult: Result), (err: FSharpDiagnostic[])) = script.Eval(source) + + let diagnostics = err |> fromFSharpDiagnostic + + let result = + { OutputPath = None + Dependencies = [] + Adjust = 0 + Diagnostics = diagnostics + Output = Some(EvalOutput evalresult) } + + let (errors, warnings) = partitionErrors diagnostics + + let evalError = match evalresult with Ok _ -> false | _ -> true + + if evalError || errors.Length > 0 || (warnings.Length > 0 && not fs.IgnoreWarnings) then + Failure result + else + Success result + + let eval (cUnit: CompilationUnit) : TestResult = + match cUnit with + | FS fs -> evalFSharp fs + | _ -> failwith "Script evaluation is only supported for F#." + + let runFsi (cUnit: CompilationUnit) : TestResult = + match cUnit with + | FS fs -> + let source = getSource fs.Source + + let options = fs.Options |> Array.ofList + + let errors = CompilerAssert.RunScriptWithOptionsAndReturnResult options source + + let result = + { OutputPath = None + Dependencies = [] + Adjust = 0 + Diagnostics = [] + Output = None } + + if errors.Count > 0 then + let output = ExecutionOutput { + ExitCode = -1 + StdOut = String.Empty + StdErr = ((errors |> String.concat "\n").Replace("\r\n","\n")) } + Failure { result with Output = Some output } + else + Success result + | _ -> failwith "FSI running only supports F#." + + + let private createBaselineErrors (baselineFile: BaselineFile) (actualErrors: string) : unit = + FileSystem.OpenFileForWriteShim(baselineFile.FilePath + ".err").Write(actualErrors) + + let private verifyFSBaseline (fs) : unit = + match fs.Baseline with + | None -> failwith "Baseline was not provided." + | Some bsl -> + let errorsExpectedBaseLine = + match bsl.OutputBaseline.Content with + | Some b -> b.Replace("\r\n","\n") + | None -> String.Empty + + let typecheckDiagnostics = fs |> typecheckFSharpSourceAndReturnErrors + + let errorsActual = (typecheckDiagnostics |> Array.map (sprintf "%A") |> String.concat "\n").Replace("\r\n","\n") + + if errorsExpectedBaseLine <> errorsActual then + createBaselineErrors bsl.OutputBaseline errorsActual + + Assert.AreEqual(errorsExpectedBaseLine, errorsActual) + + /// Check the typechecker output against the baseline, if invoked with empty baseline, will expect no error/warnings output. + let verifyBaseline (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> (verifyFSBaseline fs) |> ignore + | _ -> failwith "Baseline tests are only supported for F#." + + cUnit + + let verifyIL (il: string list) (result: TestResult) : unit = + match result with + | Success s -> + match s.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> ILChecker.checkIL p il + | Failure _ -> failwith "Result should be \"Success\" in order to get IL." + + let private verifyFSILBaseline (baseline: Baseline option) (result: Output) : unit = + match baseline with + | None -> failwith "Baseline was not provided." + | Some bsl -> + match result.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + let expectedIL = + match bsl.ILBaseline.Content with + | Some b -> b.Replace("\r\n","\n") + | None -> String.Empty + let (success, errorMsg, actualIL) = ILChecker.verifyILAndReturnActual p expectedIL + + if not success then + createBaselineErrors bsl.ILBaseline actualIL + Assert.Fail(errorMsg) + + let verifyILBaseline (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS fs -> + match fs |> compileFSharp |> shouldSucceed with + | Failure _ -> failwith "Result should be \"Success\" in order to get IL." + | Success s -> verifyFSILBaseline fs.Baseline s + | _ -> failwith "Baseline tests are only supported for F#." + + cUnit + + let verifyBaselines = verifyBaseline >> verifyILBaseline + + [] + module Assertions = + let private getErrorNumber (error: ErrorType) : int = + match error with + | Error e | Warning e -> e + + let private getErrorInfo (info: ErrorInfo) : string = + sprintf "%A %A" info.Error info.Message + + let inline private assertErrorsLength (source: ErrorInfo list) (expected: 'a list) : unit = + if (List.length source) <> (List.length expected) then + failwith (sprintf "Expected list of issues differ from compilation result:\nExpected:\n %A\nActual:\n %A" expected (List.map getErrorInfo source)) + () + + let private assertErrorMessages (source: ErrorInfo list) (expected: string list) : unit = + for exp in expected do + if not (List.exists (fun (el: ErrorInfo) -> el.Message = exp) source) then + failwith (sprintf "Mismatch in error message, expected '%A' was not found during compilation.\nAll errors:\n%A" exp (List.map getErrorInfo source)) + assertErrorsLength source expected + + let private assertErrorNumbers (source: ErrorInfo list) (expected: int list) : unit = + for exp in expected do + if not (List.exists (fun (el: ErrorInfo) -> (getErrorNumber el.Error) = exp) source) then + failwith (sprintf "Mismatch in ErrorNumber, expected '%A' was not found during compilation.\nAll errors:\n%A" exp (List.map getErrorInfo source)) + + let private assertErrors (what: string) libAdjust (source: ErrorInfo list) (expected: ErrorInfo list) : unit = + let errors = source |> List.map (fun error -> { error with Range = adjustRange error.Range libAdjust }) + + let inline checkEqual k a b = + if a <> b then + Assert.AreEqual(a, b, sprintf "%s: Mismatch in %s, expected '%A', got '%A'.\nAll errors:\n%A\nExpected errors:\n%A" what k a b errors expected) + // For lists longer than 100 errors: + errors |> List.iter System.Diagnostics.Debug.WriteLine + + // TODO: Check all "categories", collect all results and print alltogether. + checkEqual "Errors count" expected.Length errors.Length + + (errors, expected) + ||> List.iter2 (fun actualError expectedError -> + let { Error = actualError; Range = actualRange; Message = actualMessage } = actualError + let { Error = expectedError; Range = expectedRange; Message = expectedMessage } = expectedError + checkEqual "Error" expectedError actualError + checkEqual "ErrorRange" expectedRange actualRange + checkEqual "Message" expectedMessage actualMessage) + () + + let adjust (adjust: int) (result: TestResult) : TestResult = + match result with + | Success s -> Success { s with Adjust = adjust } + | Failure f -> Failure { f with Adjust = adjust } + + let shouldSucceed (result: TestResult) : TestResult = + match result with + | Success _ -> result + | Failure r -> + let message = + [ sprintf "Operation failed (expected to succeed).\n All errors:\n%A\n" r.Diagnostics + match r.Output with + | Some (ExecutionOutput output) -> + sprintf "----output-----\n%s\n----error-------\n%s\n----------" output.StdOut output.StdErr + | _ -> () ] + |> String.concat "\n" + failwith message + + let shouldFail (result: TestResult) : TestResult = + match result with + | Success _ -> failwith "Operation was succeeded (expected to fail)." + | Failure _ -> result + + let private assertResultsCategory (what: string) (selector: Output -> ErrorInfo list) (expected: ErrorInfo list) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + assertErrors what r.Adjust (selector r) expected + result + + let withResults (expectedResults: ErrorInfo list) result : TestResult = + assertResultsCategory "Results" (fun r -> r.Diagnostics) expectedResults result + + let withResult (expectedResult: ErrorInfo ) (result: TestResult) : TestResult = + withResults [expectedResult] result + + let withDiagnostics (expected: (ErrorType * Line * Col * Line * Col * string) list) (result: TestResult) : TestResult = + let (expectedResults: ErrorInfo list) = + expected |> + List.map( + fun e -> + let (error, (Line startLine), (Col startCol), (Line endLine), (Col endCol), message) = e + { Error = error + Range = + { StartLine = startLine + StartColumn = startCol + EndLine = endLine + EndColumn = endCol } + Message = message }) + withResults expectedResults result + + let withSingleDiagnostic (expected: (ErrorType * Line * Col * Line * Col * string)) (result: TestResult) : TestResult = + withDiagnostics [expected] result + + let withErrors (expectedErrors: ErrorInfo list) (result: TestResult) : TestResult = + assertResultsCategory "Errors" (fun r -> getErrors r.Diagnostics) expectedErrors result + + let withError (expectedError: ErrorInfo) (result: TestResult) : TestResult = + withErrors [expectedError] result + + let checkCodes (expected: int list) (selector: Output -> ErrorInfo list) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + assertErrorNumbers (selector r) expected + result + + let withErrorCodes (expectedCodes: int list) (result: TestResult) : TestResult = + checkCodes expectedCodes (fun r -> getErrors r.Diagnostics) result + + let withErrorCode (expectedCode: int) (result: TestResult) : TestResult = + withErrorCodes [expectedCode] result + + let withWarnings (expectedWarnings: ErrorInfo list) (result: TestResult) : TestResult = + assertResultsCategory "Warnings" (fun r -> getWarnings r.Diagnostics) expectedWarnings result + + let withWarning (expectedWarning: ErrorInfo) (result: TestResult) : TestResult = + withWarnings [expectedWarning] result + + let withWarningCodes (expectedCodes: int list) (result: TestResult) : TestResult = + checkCodes expectedCodes (fun r -> getWarnings r.Diagnostics) result + + let withWarningCode (expectedCode: int) (result: TestResult) : TestResult = + withWarningCodes [expectedCode] result + + let private checkErrorMessages (messages: string list) (selector: Output -> ErrorInfo list) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> assertErrorMessages (selector r) messages + result + + let private diagnosticMatches (pattern: string) (diagnostics: ErrorInfo list) : bool = + diagnostics |> List.exists (fun d -> Regex.IsMatch(d.Message, pattern)) + + let withDiagnosticMessageMatches (pattern: string) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + if not <| diagnosticMatches pattern r.Diagnostics then + failwithf "Expected diagnostic message pattern was not found in compilation diagnostics.\nDiagnostics:\n%A" r.Diagnostics + result + + let withDiagnosticMessageDoesntMatch (pattern: string) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + if diagnosticMatches pattern r.Diagnostics then + failwith "Diagnostic message pattern was not expected, but was present." + result + + let withMessages (messages: string list) (result: TestResult) : TestResult = + checkErrorMessages messages (fun r -> r.Diagnostics) result + + let withMessage (message: string) (result: TestResult) : TestResult = + withMessages [message] result + + let withErrorMessages (messages: string list) (result: TestResult) : TestResult = + checkErrorMessages messages (fun r -> getErrors r.Diagnostics) result + + let withErrorMessage (message: string) (result: TestResult) : TestResult = + withErrorMessages [message] result + + let withWarningMessages (messages: string list) (result: TestResult) : TestResult = + checkErrorMessages messages (fun r -> getWarnings r.Diagnostics) result + + let withWarningMessage (message: string) (result: TestResult) : TestResult = + withWarningMessages [message] result + + let withExitCode (expectedExitCode: int) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + match r.Output with + | None -> failwith "Execution output is missing, cannot check exit code." + | Some o -> + match o with + | ExecutionOutput e -> Assert.AreEqual(e.ExitCode, expectedExitCode, sprintf "Exit code was expected to be: %A, but got %A." expectedExitCode e.ExitCode) + | _ -> failwith "Cannot check exit code on this run result." + result + + let private checkOutput (category: string) (substring: string) (selector: ExecutionOutput -> string) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + match r.Output with + | None -> failwith (sprintf "Execution output is missing cannot check \"%A\"" category) + | Some o -> + match o with + | ExecutionOutput e -> + let where = selector e + if not (where.Contains(substring)) then + failwith (sprintf "\nThe following substring:\n %A\nwas not found in the %A\nOutput:\n %A" substring category where) + | _ -> failwith "Cannot check output on this run result." + result + + let withOutputContains (substring: string) (result: TestResult) : TestResult = + checkOutput "STDERR/STDOUT" substring (fun o -> o.StdOut + "\n" + o.StdErr) result + + let withStdOutContains (substring: string) (result: TestResult) : TestResult = + checkOutput "STDOUT" substring (fun o -> o.StdOut) result + + let withStdErrContains (substring: string) (result: TestResult) : TestResult = + checkOutput "STDERR" substring (fun o -> o.StdErr) result + + // TODO: probably needs a bit of simplification, + need to remove that pyramid of doom. + let private assertEvalOutput (selector: FsiValue -> 'T) (value: 'T) (result: TestResult) : TestResult = + match result with + | Success r | Failure r -> + match r.Output with + | None -> failwith "Execution output is missing cannot check value." + | Some o -> + match o with + | EvalOutput e -> + match e with + | Ok v -> + match v with + | None -> failwith "Cannot assert value of evaluation, since it is None." + | Some e -> Assert.AreEqual(value, (selector e)) + | Result.Error ex -> raise ex + | _ -> failwith "Only 'eval' output is supported." + result + + // TODO: Need to support for: + // STDIN, to test completions + // Contains + // Cancellation + let withEvalValueEquals (value: 'T) (result: TestResult) : TestResult = + assertEvalOutput (fun (x: FsiValue) -> x.ReflectionValue :?> 'T) value result + + let withEvalTypeEquals t (result: TestResult) : TestResult = + assertEvalOutput (fun (x: FsiValue) -> x.ReflectionType) t result diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs new file mode 100644 index 00000000000..cd7120029ac --- /dev/null +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -0,0 +1,723 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Test + +open System +open System.IO +open System.Text +open System.Reflection +open FSharp.Compiler.Interactive.Shell +open FSharp.Compiler.IO +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Text +#if FX_NO_APP_DOMAINS +open System.Runtime.Loader +#endif +open NUnit.Framework +open FSharp.Test.Utilities +open TestFramework + +[] +type ILVerifier (dllFilePath: string) = + + member _.VerifyIL (expectedIL: string list) = + ILChecker.checkIL dllFilePath expectedIL + +[] +type PdbDebugInfo(debugInfo: string) = + + member _.InfoText = debugInfo + +type Worker () = + inherit MarshalByRefObject() + + member x.ExecuteTestCase assemblyPath (deps: string[]) = + AppDomain.CurrentDomain.add_AssemblyResolve(ResolveEventHandler(fun _ args -> + deps + |> Array.tryFind (fun (x: string) -> Path.GetFileNameWithoutExtension x = args.Name) + |> Option.bind (fun x -> if FileSystem.FileExistsShim x then Some x else None) + |> Option.map Assembly.LoadFile + |> Option.defaultValue null)) + let asm = Assembly.LoadFrom(assemblyPath) + let entryPoint = asm.EntryPoint + (entryPoint.Invoke(Unchecked.defaultof, [||])) |> ignore + +type SourceKind = + | Fs + | Fsx + +type CompileOutput = + | Library + | Exe + +type CompilationReference = + private + | CompilationReference of Compilation * staticLink: bool + | TestCompilationReference of TestCompilation + + static member CreateFSharp(cmpl: Compilation, ?staticLink) = + let staticLink = defaultArg staticLink false + CompilationReference(cmpl, staticLink) + + static member Create(cmpl: TestCompilation) = + TestCompilationReference cmpl + +and Compilation = private Compilation of source: string * SourceKind * CompileOutput * options: string[] * CompilationReference list * name: string option with + + static member Create(source, sourceKind, output, ?options, ?cmplRefs, ?name) = + let options = defaultArg options [||] + let cmplRefs = defaultArg cmplRefs [] + Compilation(source, sourceKind, output, options, cmplRefs, name) + +[] +type CompilerAssert private () = + + static let checker = FSharpChecker.Create(suggestNamesForErrors=true) + +#if FX_NO_APP_DOMAINS + static let executeBuiltApp assembly deps = + let ctxt = AssemblyLoadContext("ContextName", true) + try + let asm = ctxt.LoadFromAssemblyPath(assembly) + let entryPoint = asm.EntryPoint + ctxt.add_Resolving(fun ctxt name -> + deps + |> List.tryFind (fun (x: string) -> Path.GetFileNameWithoutExtension x = name.Name) + |> Option.map ctxt.LoadFromAssemblyPath + |> Option.defaultValue null) + (entryPoint.Invoke(Unchecked.defaultof, [||])) |> ignore + finally + ctxt.Unload() +#else + + static let pathToThisDll = Assembly.GetExecutingAssembly().CodeBase + + static let adSetup = + let setup = new System.AppDomainSetup () + setup.PrivateBinPath <- pathToThisDll + setup + + static let executeBuiltApp assembly deps = + let ad = AppDomain.CreateDomain((Guid()).ToString(), null, adSetup) + let worker = (ad.CreateInstanceFromAndUnwrap(pathToThisDll, typeof.FullName)) :?> Worker + worker.ExecuteTestCase assembly (deps |> Array.ofList) |>ignore +#endif + + static let defaultProjectOptions = + { + ProjectFileName = "Z:\\test.fsproj" + ProjectId = None + SourceFiles = [|"test.fs"|] + OtherOptions = + let assemblies = TargetFrameworkUtil.currentReferences |> Array.map (fun x -> sprintf "-r:%s" x) +#if NETCOREAPP + Array.append [|"--preferreduilang:en-US"; "--targetprofile:netcore"; "--noframework"; "--simpleresolution"; "--warn:5"|] assemblies +#else + Array.append [|"--preferreduilang:en-US"; "--targetprofile:mscorlib"; "--noframework"; "--warn:5"|] assemblies +#endif + ReferencedProjects = [||] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false + LoadTime = DateTime() + UnresolvedReferences = None + OriginalLoadReferences = [] + Stamp = None + } + + static let rawCompile inputFilePath outputFilePath isExe options source = + File.WriteAllText (inputFilePath, source) + let args = + [| yield "fsc.dll"; + yield inputFilePath; + yield "-o:" + outputFilePath; + yield (if isExe then "--target:exe" else "--target:library"); + yield "--nowin32manifest" + yield! defaultProjectOptions.OtherOptions + yield! options + |] + let errors, _ = checker.Compile args |> Async.RunImmediate + errors, outputFilePath + + static let compileAux isExe options source f : unit = + let inputFilePath = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let outputFilePath = Path.ChangeExtension (tryCreateTemporaryFileName (), if isExe then ".exe" else ".dll") + try + f (rawCompile inputFilePath outputFilePath isExe options source) + finally + try File.Delete inputFilePath with | _ -> () + try File.Delete outputFilePath with | _ -> () + + static let compileDisposable outputPath isScript isExe options nameOpt source = + let ext = + if isScript then ".fsx" + else ".fs" + let inputFilePath = Path.ChangeExtension(Path.Combine(outputPath, Path.GetRandomFileName()), ext) + let name = + match nameOpt with + | Some name -> name + | _ -> Path.GetRandomFileName() + let outputFilePath = Path.ChangeExtension (Path.Combine(outputPath, name), if isExe then ".exe" else ".dll") + let o = + { new IDisposable with + member _.Dispose() = + try File.Delete inputFilePath with | _ -> () + try File.Delete outputFilePath with | _ -> () } + try + o, rawCompile inputFilePath outputFilePath isExe options source + with + | _ -> + o.Dispose() + reraise() + + static let assertErrors libAdjust ignoreWarnings (errors: FSharpDiagnostic []) expectedErrors = + let errors = + errors + |> Array.filter (fun error -> if ignoreWarnings then error.Severity <> FSharpDiagnosticSeverity.Warning else true) + |> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message) + |> Array.map (fun info -> + (info.Severity, info.ErrorNumber, (info.StartLine - libAdjust, info.StartColumn + 1, info.EndLine - libAdjust, info.EndColumn + 1), info.Message)) + + let checkEqual k a b = + if a <> b then + Assert.AreEqual(a, b, sprintf "Mismatch in %s, expected '%A', got '%A'.\nAll errors:\n%A" k a b errors) + + checkEqual "Errors" (Array.length expectedErrors) errors.Length + + Array.zip errors expectedErrors + |> Array.iter (fun (actualError, expectedError) -> + let (expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg: string) = expectedError + let (actualSeverity, actualErrorNumber, actualErrorRange, actualErrorMsg: string) = actualError + let expectedErrorMsg = expectedErrorMsg.Replace("\r\n", "\n") + let actualErrorMsg = actualErrorMsg.Replace("\r\n", "\n") + checkEqual "Severity" expectedSeverity actualSeverity + checkEqual "ErrorNumber" expectedErrorNumber actualErrorNumber + checkEqual "ErrorRange" expectedErrorRange actualErrorRange + checkEqual "Message" expectedErrorMsg actualErrorMsg) + + static let compile isExe options source f = + compileAux isExe options source f + + static let rec compileCompilationAux outputPath (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * string) * string list = + let compilationRefs, deps = + match cmpl with + | Compilation(_, _, _, _, cmpls, _) -> + let compiledRefs = + cmpls + |> List.map (fun cmpl -> + match cmpl with + | CompilationReference (cmpl, staticLink) -> + compileCompilationAux outputPath disposals ignoreWarnings cmpl, staticLink + | TestCompilationReference (cmpl) -> + let filename = + match cmpl with + | TestCompilation.CSharp c when not (String.IsNullOrWhiteSpace c.AssemblyName) -> c.AssemblyName + | _ -> Path.GetRandomFileName() + let tmp = Path.Combine(outputPath, Path.ChangeExtension(filename, ".dll")) + disposals.Add({ new IDisposable with + member _.Dispose() = + try File.Delete tmp with | _ -> () }) + cmpl.EmitAsFile tmp + (([||], tmp), []), false) + + let compilationRefs = + compiledRefs + |> List.map (fun (((errors, outputFilePath), _), staticLink) -> + assertErrors 0 ignoreWarnings errors [||] + let rOption = "-r:" + outputFilePath + if staticLink then + [rOption;"--staticlink:" + Path.GetFileNameWithoutExtension outputFilePath] + else + [rOption]) + |> List.concat + |> Array.ofList + + let deps = + compiledRefs + |> List.map (fun ((_, deps), _) -> deps) + |> List.concat + |> List.distinct + + compilationRefs, deps + + let isScript = + match cmpl with + | Compilation(_, kind, _, _, _, _) -> + match kind with + | Fs -> false + | Fsx -> true + + let isExe = + match cmpl with + | Compilation(_, _, output, _, _, _) -> + match output with + | Library -> false + | Exe -> true + + let source = + match cmpl with + | Compilation(source, _, _, _, _, _) -> source + + let options = + match cmpl with + | Compilation(_, _, _, options, _, _) -> options + + let nameOpt = + match cmpl with + | Compilation(_, _, _, _, _, nameOpt) -> nameOpt + + let disposal, res = compileDisposable outputPath isScript isExe (Array.append options compilationRefs) nameOpt source + disposals.Add disposal + + let deps2 = + compilationRefs + |> Array.filter (fun x -> not (x.Contains("--staticlink"))) + |> Array.map (fun x -> x.Replace("-r:", String.Empty)) + |> List.ofArray + + res, (deps @ deps2) + + static let rec compileCompilation ignoreWarnings (cmpl: Compilation) f = + let compileDirectory = Path.Combine(Path.GetTempPath(), "CompilerAssert", Path.GetRandomFileName()) + let disposals = ResizeArray() + try + Directory.CreateDirectory(compileDirectory) |> ignore + f (compileCompilationAux compileDirectory disposals ignoreWarnings cmpl) + finally + try Directory.Delete compileDirectory with | _ -> () + disposals + |> Seq.iter (fun x -> x.Dispose()) + + // NOTE: This function will not clean up all the compiled projects after itself. + // The reason behind is so we can compose verification of test runs easier. + // TODO: We must not rely on the filesystem when compiling + static let rec returnCompilation (cmpl: Compilation) ignoreWarnings = + let compileDirectory = Path.Combine(Path.GetTempPath(), "CompilerAssert", Path.GetRandomFileName()) + Directory.CreateDirectory(compileDirectory) |> ignore + compileCompilationAux compileDirectory (ResizeArray()) ignoreWarnings cmpl + + static let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) : (int * string * string) = + let out = Console.Out + let err = Console.Error + + let stdout = StringBuilder () + let stderr = StringBuilder () + + let outWriter = new StringWriter (stdout) + let errWriter = new StringWriter (stderr) + + let mutable exitCode = 0 + + try + try + Console.SetOut(outWriter) + Console.SetError(errWriter) + (executeBuiltApp outputFilePath deps) |> ignore + with e -> + let errorMessage = if e.InnerException <> null then (e.InnerException.ToString()) else (e.ToString()) + stderr.Append (errorMessage) |> ignore + exitCode <- -1 + finally + Console.SetOut(out) + Console.SetError(err) + outWriter.Close() + errWriter.Close() + + (exitCode, stdout.ToString(), stderr.ToString()) + + static let executeBuiltAppNewProcessAndReturnResult (outputFilePath: string) : (int * string * string) = +#if !NETCOREAPP + let filename = outputFilePath + let arguments = "" +#else + let filename = "dotnet" + let arguments = outputFilePath + + let runtimeconfig = """ +{ + "runtimeOptions": { + "tfm": "net5.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0" + } + } +}""" + let runtimeconfigPath = Path.ChangeExtension(outputFilePath, ".runtimeconfig.json") + File.WriteAllText(runtimeconfigPath, runtimeconfig) + use _disposal = + { new IDisposable with + member _.Dispose() = try File.Delete runtimeconfigPath with | _ -> () } +#endif + let timeout = 30000 + let exitCode, output, errors = Commands.executeProcess (Some filename) arguments (Path.GetDirectoryName(outputFilePath)) timeout + (exitCode, output |> String.concat "\n", errors |> String.concat "\n") + + static member Checker = checker + + static member DefaultProjectOptions = defaultProjectOptions + + static member CompileWithErrors(cmpl: Compilation, expectedErrors, ?ignoreWarnings) = + let ignoreWarnings = defaultArg ignoreWarnings false + compileCompilation ignoreWarnings cmpl (fun ((errors, _), _) -> + assertErrors 0 ignoreWarnings errors expectedErrors) + + static member Compile(cmpl: Compilation, ?ignoreWarnings) = + CompilerAssert.CompileWithErrors(cmpl, [||], defaultArg ignoreWarnings false) + + static member CompileRaw(cmpl: Compilation, ?ignoreWarnings) = + returnCompilation cmpl (defaultArg ignoreWarnings false) + + static member ExecuteAndReturnResult (outputFilePath: string, deps: string list, newProcess: bool) = + // If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception. + if not newProcess then + executeBuiltAppAndReturnResult outputFilePath deps + else + executeBuiltAppNewProcessAndReturnResult outputFilePath + + static member Execute(cmpl: Compilation, ?ignoreWarnings, ?beforeExecute, ?newProcess, ?onOutput) = + let ignoreWarnings = defaultArg ignoreWarnings false + let beforeExecute = defaultArg beforeExecute (fun _ _ -> ()) + let newProcess = defaultArg newProcess false + let onOutput = defaultArg onOutput (fun _ -> ()) + compileCompilation ignoreWarnings cmpl (fun ((errors, outputFilePath), deps) -> + assertErrors 0 ignoreWarnings errors [||] + beforeExecute outputFilePath deps + if newProcess then + let (exitCode, output, errors) = executeBuiltAppNewProcessAndReturnResult outputFilePath + if exitCode <> 0 then + Assert.Fail errors + onOutput output + else + executeBuiltApp outputFilePath deps) + + static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) = + CompilerAssert.Execute(cmpl, newProcess = true, onOutput = (fun output -> Assert.AreEqual(expectedOutput, output, sprintf "'%s' = '%s'" expectedOutput output))) + + /// Assert that the given source code compiles with the `defaultProjectOptions`, with no errors or warnings + static member CompileOfAst isExe source = + let outputFilePath = Path.ChangeExtension (tryCreateTemporaryFileName (), if isExe then "exe" else ".dll") + let parseOptions = { FSharpParsingOptions.Default with SourceFiles = [|"test.fs"|] } + + let parseResults = + checker.ParseFile("test.fs", SourceText.ofString source, parseOptions) + |> Async.RunImmediate + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + let dependencies = + #if NETCOREAPP + Array.toList TargetFrameworkUtil.currentReferences + #else + [] + #endif + + let compileErrors, statusCode = + checker.Compile([parseResults.ParseTree], "test", outputFilePath, dependencies, executable = isExe, noframework = true) + |> Async.RunImmediate + + Assert.IsEmpty(compileErrors, sprintf "Compile errors: %A" compileErrors) + Assert.AreEqual(0, statusCode, sprintf "Nonzero status code: %d" statusCode) + outputFilePath + + static member CompileOfAstToDynamicAssembly source = + let assemblyName = sprintf "test-%O" (Guid.NewGuid()) + let parseOptions = { FSharpParsingOptions.Default with SourceFiles = [|"test.fs"|] } + let parseResults = + checker.ParseFile("test.fs", SourceText.ofString source, parseOptions) + |> Async.RunImmediate + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + let dependencies = + #if NETCOREAPP + Array.toList TargetFrameworkUtil.currentReferences + #else + [] + #endif + + let compileErrors, statusCode, assembly = + checker.CompileToDynamicAssembly([parseResults.ParseTree], assemblyName, dependencies, None, noframework = true) + |> Async.RunImmediate + + Assert.IsEmpty(compileErrors, sprintf "Compile errors: %A" compileErrors) + Assert.AreEqual(0, statusCode, sprintf "Nonzero status code: %d" statusCode) + Assert.IsTrue(assembly.IsSome, "no assembly returned") + Option.get assembly + + static member Pass (source: string) = + let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunImmediate + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> + + Assert.IsEmpty(typeCheckResults.Diagnostics, sprintf "Type Check errors: %A" typeCheckResults.Diagnostics) + + static member PassWithOptions options (source: string) = + let options = { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions} + + let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, options) |> Async.RunImmediate + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> + + Assert.IsEmpty(typeCheckResults.Diagnostics, sprintf "Type Check errors: %A" typeCheckResults.Diagnostics) + + static member TypeCheckWithErrorsAndOptionsAgainstBaseLine options (sourceDirectory:string) (sourceFile: string) = + let absoluteSourceFile = System.IO.Path.Combine(sourceDirectory, sourceFile) + let parseResults, fileAnswer = + checker.ParseAndCheckFileInProject( + sourceFile, + 0, + SourceText.ofString (File.ReadAllText absoluteSourceFile), + { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions; SourceFiles = [|sourceFile|] }) + |> Async.RunImmediate + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> + + let errorsExpectedBaseLine = + let bslFile = Path.ChangeExtension(absoluteSourceFile, "bsl") + if not (FileSystem.FileExistsShim bslFile) then + // new test likely initialized, create empty baseline file + File.WriteAllText(bslFile, "") + File.ReadAllText(Path.ChangeExtension(absoluteSourceFile, "bsl")) + let errorsActual = + typeCheckResults.Diagnostics + |> Array.map (sprintf "%A") + |> String.concat "\n" + File.WriteAllText(Path.ChangeExtension(absoluteSourceFile,"err"), errorsActual) + + Assert.AreEqual(errorsExpectedBaseLine.Replace("\r\n","\n"), errorsActual.Replace("\r\n","\n")) + + static member TypeCheckWithOptionsAndName options name (source: string) = + let errors = + let parseResults, fileAnswer = + checker.ParseAndCheckFileInProject( + name, + 0, + SourceText.ofString source, + { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions; SourceFiles = [|name|] }) + |> Async.RunImmediate + + if parseResults.Diagnostics.Length > 0 then + parseResults.Diagnostics + else + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted"); [| |] + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> typeCheckResults.Diagnostics + + errors + + static member TypeCheckWithOptions options (source: string) = + let errors = + let parseResults, fileAnswer = + checker.ParseAndCheckFileInProject( + "test.fs", + 0, + SourceText.ofString source, + { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions}) + |> Async.RunImmediate + + if parseResults.Diagnostics.Length > 0 then + parseResults.Diagnostics + else + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted"); [| |] + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> typeCheckResults.Diagnostics + + errors + + /// Parses and type checks the given source. Fails if type checker is aborted. + static member ParseAndTypeCheck(options, name, source: string) = + let parseResults, fileAnswer = + checker.ParseAndCheckFileInProject( + name, + 0, + SourceText.ofString source, + { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions}) + |> Async.RunImmediate + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted"); failwith "Type Checker Aborted" + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> parseResults, typeCheckResults + + /// Parses and type checks the given source. Fails if the type checker is aborted or the parser returns any diagnostics. + static member TypeCheck(options, name, source: string) = + let parseResults, checkResults = CompilerAssert.ParseAndTypeCheck(options, name, source) + + Assert.IsEmpty(parseResults.Diagnostics, sprintf "Parse errors: %A" parseResults.Diagnostics) + + checkResults + + static member TypeCheckWithErrorsAndOptionsAndAdjust options libAdjust (source: string) expectedTypeErrors = + let errors = + let parseResults, fileAnswer = + checker.ParseAndCheckFileInProject( + "test.fs", + 0, + SourceText.ofString source, + { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions}) + |> Async.RunImmediate + + if parseResults.Diagnostics.Length > 0 then + parseResults.Diagnostics + else + + match fileAnswer with + | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted"); [| |] + | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> typeCheckResults.Diagnostics + + assertErrors libAdjust false errors expectedTypeErrors + + + static member TypeCheckWithErrorsAndOptions options (source: string) expectedTypeErrors = + CompilerAssert.TypeCheckWithErrorsAndOptionsAndAdjust options 0 (source: string) expectedTypeErrors + + static member TypeCheckWithErrors (source: string) expectedTypeErrors = + CompilerAssert.TypeCheckWithErrorsAndOptions [||] source expectedTypeErrors + + static member TypeCheckSingleErrorWithOptions options (source: string) (expectedSeverity: FSharpDiagnosticSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) = + CompilerAssert.TypeCheckWithErrorsAndOptions options source [| expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |] + + static member TypeCheckSingleError (source: string) (expectedSeverity: FSharpDiagnosticSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) = + CompilerAssert.TypeCheckWithErrors source [| expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |] + + static member CompileExeWithOptions options (source: string) = + compile true options source (fun (errors, _) -> + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)) + + static member CompileExe (source: string) = + CompilerAssert.CompileExeWithOptions [||] source + + static member CompileExeAndRunWithOptions options (source: string) = + compile true options source (fun (errors, outputExe) -> + + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) + + executeBuiltApp outputExe [] + ) + + static member CompileExeAndRun (source: string) = + CompilerAssert.CompileExeAndRunWithOptions [||] source + + static member CompileLibraryAndVerifyILWithOptions options (source: string) (f: ILVerifier -> unit) = + compile false options source (fun (errors, outputFilePath) -> + let errors = + errors |> Array.filter (fun x -> x.Severity = FSharpDiagnosticSeverity.Error) + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had errors: %A" errors) + + f (ILVerifier outputFilePath) + ) + + static member CompileLibraryAndVerifyDebugInfoWithOptions options (expectedFile: string) (source: string) = + let options = [| yield! options; yield"--test:DumpDebugInfo" |] + compile false options source (fun (errors, outputFilePath) -> + let errors = + errors |> Array.filter (fun x -> x.Severity = FSharpDiagnosticSeverity.Error) + if errors.Length > 0 then + Assert.Fail (sprintf "Compile had errors: %A" errors) + let debugInfoFile = outputFilePath + ".debuginfo" + if not (File.Exists expectedFile) then + File.Copy(debugInfoFile, expectedFile) + failwith $"debug info expected file {expectedFile} didn't exist, now copied over" + let debugInfo = File.ReadAllLines(debugInfoFile) + let expected = File.ReadAllLines(expectedFile) + if debugInfo <> expected then + File.Copy(debugInfoFile, expectedFile, overwrite=true) + failwith $"""debug info mismatch +Expected is in {expectedFile} +Actual is in {debugInfoFile} +Updated automatically, please check diffs in your pull request, changes must be scrutinized +""" + ) + + static member CompileLibraryAndVerifyIL (source: string) (f: ILVerifier -> unit) = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [||] source f + + static member RunScriptWithOptionsAndReturnResult options (source: string) = + // Intialize output and input streams + use inStream = new StringReader("") + use outStream = new StringWriter() + use errStream = new StringWriter() + + // Build command line arguments & start FSI session + let argv = [| "C:\\fsi.exe" |] +#if NETCOREAPP + let args = Array.append argv [|"--noninteractive"; "--targetprofile:netcore"|] +#else + let args = Array.append argv [|"--noninteractive"; "--targetprofile:mscorlib"|] +#endif + let allArgs = Array.append args options + + let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() + use fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream, collectible = true) + + let ch, errors = fsiSession.EvalInteractionNonThrowing source + + let errorMessages = ResizeArray() + errors + |> Seq.iter (fun error -> errorMessages.Add(error.Message)) + + match ch with + | Choice2Of2 ex -> errorMessages.Add(ex.Message) + | _ -> () + + errorMessages + + static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) = + let errorMessages = CompilerAssert.RunScriptWithOptionsAndReturnResult options source + if expectedErrorMessages.Length <> errorMessages.Count then + Assert.Fail(sprintf "Expected error messages: %A \n\n Actual error messages: %A" expectedErrorMessages errorMessages) + else + (expectedErrorMessages, errorMessages) + ||> Seq.iter2 (fun expectedErrorMessage errorMessage -> + Assert.AreEqual(expectedErrorMessage, errorMessage) + ) + + static member RunScript source expectedErrorMessages = + CompilerAssert.RunScriptWithOptions [||] source expectedErrorMessages + + static member Parse (source: string, ?langVersion: string) = + let langVersion = defaultArg langVersion "default" + let sourceFileName = "test.fs" + let parsingOptions = + { FSharpParsingOptions.Default with + SourceFiles = [| sourceFileName |] + LangVersionText=langVersion } + checker.ParseFile(sourceFileName, SourceText.ofString source, parsingOptions) |> Async.RunImmediate + + static member ParseWithErrors (source: string, ?langVersion: string) = fun expectedParseErrors -> + let parseResults = CompilerAssert.Parse (source, ?langVersion=langVersion) + + Assert.True(parseResults.ParseHadErrors) + + let errors = + parseResults.Diagnostics + |> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message) + + printfn $"diagnostics: %A{[| for e in errors -> e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message |]}" + Assert.AreEqual(Array.length expectedParseErrors, errors.Length, sprintf "Parse errors: %A" parseResults.Diagnostics) + + Array.zip errors expectedParseErrors + |> Array.iter (fun (info, expectedError) -> + let (expectedSeverity: FSharpDiagnosticSeverity, expectedErrorNumber: int, expectedErrorRange: int * int * int * int, expectedErrorMsg: string) = expectedError + Assert.AreEqual(expectedSeverity, info.Severity) + Assert.AreEqual(expectedErrorNumber, info.ErrorNumber, "expectedErrorNumber") + Assert.AreEqual(expectedErrorRange, (info.StartLine, info.StartColumn + 1, info.EndLine, info.EndColumn + 1), "expectedErrorRange") + Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg") + ) diff --git a/src/fsharp/FSharp.Compiler.Private/Directory.Build.props b/tests/FSharp.Test.Utilities/Directory.Build.props similarity index 100% rename from src/fsharp/FSharp.Compiler.Private/Directory.Build.props rename to tests/FSharp.Test.Utilities/Directory.Build.props diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj new file mode 100644 index 00000000000..e1d3a54ed4f --- /dev/null +++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj @@ -0,0 +1,82 @@ + + + + net472;net5.0 + net5.0 + win-x86;win-x64;linux-x64;osx-x64 + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81 + true + Library + true + false + false + $(OtherFlags) --warnon:1182 + + + + + scriptlib.fsx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs new file mode 100644 index 00000000000..6357af6102d --- /dev/null +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Test + +open System +open System.IO +open System.Diagnostics + +open NUnit.Framework +open TestFramework + +[] +module ILChecker = + + let config = initializeSuite () + + let private exec exe args = + let arguments = args |> String.concat " " + let timeout = 30000 + let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout + let errors = errors |> String.concat Environment.NewLine + errors, exitCode + + /// Filters i.e ['The system type \'System.ReadOnlySpan`1\' was required but no referenced system DLL contained this type'] + let private filterSpecialComment (text: string) = + let pattern = @"(\[\'(.*?)\'\])" + System.Text.RegularExpressions.Regex.Replace(text, pattern, + (fun me -> String.Empty) + ) + + let private checkILPrim ildasmArgs dllFilePath expectedIL = + let ilFilePath = Path.ChangeExtension(dllFilePath, ".il") + + let mutable errorMsgOpt = None + let mutable actualIL = String.Empty + try + let ildasmPath = config.ILDASM + + let ildasmFullArgs = [ yield dllFilePath; yield sprintf "-out=%s" ilFilePath; yield! ildasmArgs ] + + let stdErr, exitCode = exec ildasmPath ildasmFullArgs + + if exitCode <> 0 then + failwith (sprintf "ILASM Expected exit code \"0\", got \"%d\"\nSTDERR: %s" exitCode stdErr) + + if not (String.IsNullOrWhiteSpace stdErr) then + failwith (sprintf "ILASM Stderr is not empty:\n %s" stdErr) + + let unifyRuntimeAssemblyName ilCode = + System.Text.RegularExpressions.Regex.Replace(ilCode, + "\[System.Runtime\]|\[System.Console\]|\[System.Runtime.Extensions\]|\[mscorlib\]","[runtime]", + System.Text.RegularExpressions.RegexOptions.Singleline) + + let raw = File.ReadAllText(ilFilePath) + + let textAfterUnifyingAssemblies = + let asmName = Path.GetFileNameWithoutExtension(dllFilePath) + raw.Replace(asmName, "assembly") + |> unifyRuntimeAssemblyName + + let blockComments = @"/\*(.*?)\*/" + let lineComments = @"//(.*?)\r?\n" + let strings = @"""((\\[^\n]|[^""\n])*)""" + let verbatimStrings = @"@(""[^""]*"")+" + let textNoComments = + System.Text.RegularExpressions.Regex.Replace(textAfterUnifyingAssemblies, + blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, + (fun me -> + if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) then + if me.Value.StartsWith("//") then Environment.NewLine else String.Empty + else + me.Value), System.Text.RegularExpressions.RegexOptions.Singleline) + |> filterSpecialComment + + expectedIL + |> List.map (fun (ilCode: string) -> ilCode.Trim() |> unifyRuntimeAssemblyName ) + |> List.iter (fun (ilCode: string) -> + let expectedLines = ilCode.Split('\n') + let startIndex = textNoComments.IndexOf(expectedLines.[0].Trim()) + if startIndex = -1 then + errorMsgOpt <- Some("\nExpected:\n" + ilCode + "\n") + else + let errors = ResizeArray() + let actualLines = textNoComments.Substring(startIndex, textNoComments.Length - startIndex).Split('\n') + if actualLines.Length < expectedLines.Length then + let msg = sprintf "\nExpected at least %d lines but found only %d\n" expectedLines.Length actualLines.Length + errorMsgOpt <- Some(msg + "\nExpected:\n" + ilCode + "\n") + else + for i = 0 to expectedLines.Length - 1 do + let expected = expectedLines.[i].Trim() + let actual = actualLines.[i].Trim() + if expected <> actual then + errors.Add(sprintf "\n==\nName: '%s'\n\nExpected:\t %s\nActual:\t\t %s\n==" actualLines.[0] expected actual) + + if errors.Count > 0 then + let msg = String.concat "\n" errors + "\n\n\Expected:\n" + ilCode + "\n" + errorMsgOpt <- Some(msg + "\n\n\nActual:\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) + ) + + if expectedIL.Length = 0 then + errorMsgOpt <- Some ("No Expected IL") + + actualIL <- textNoComments + + match errorMsgOpt with + | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\nEntire actual:\n" + textNoComments) + | _ -> () + finally + try File.Delete(ilFilePath) with | _ -> () + + match errorMsgOpt with + | Some(errorMsg) -> (false, errorMsg, actualIL) + | _ -> (true, String.Empty, String.Empty) + + let private checkILAux ildasmArgs dllFilePath expectedIL = + let (success, errorMsg, _) = checkILPrim ildasmArgs dllFilePath expectedIL + if not success then + Assert.Fail(errorMsg) + else () + + // This doesn't work because the '/linenum' is being ignored by + // the version of ILDASM we are using, which we acquire from a nuget package + //let checkILWithDebugPoints dllFilePath expectedIL = + // checkILAux [ "/linenum" ] dllFilePath expectedIL + + let checkIL dllFilePath expectedIL = + checkILAux [] dllFilePath expectedIL + + let verifyIL (dllFilePath: string) (expectedIL: string) = + checkIL dllFilePath [expectedIL] + + let verifyILAndReturnActual (dllFilePath: string) (expectedIL: string) = + checkILPrim [] dllFilePath [expectedIL] + + let reassembleIL ilFilePath dllFilePath = + let ilasmPath = config.ILASM + let errors, _ = exec ilasmPath ([ sprintf "%s /output=%s /dll" ilFilePath dllFilePath ]) + errors diff --git a/tests/FSharp.Test.Utilities/ScriptHelpers.fs b/tests/FSharp.Test.Utilities/ScriptHelpers.fs new file mode 100644 index 00000000000..afb592b8c72 --- /dev/null +++ b/tests/FSharp.Test.Utilities/ScriptHelpers.fs @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Test.ScriptHelpers + +open System +open System.Collections.Generic +open System.IO +open System.Text +open System.Threading +open FSharp.Compiler +open FSharp.Compiler.Interactive.Shell +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices + +type CapturedTextReader() = + inherit TextReader() + let queue = Queue() + member _.ProvideInput(text: string) = + for c in text.ToCharArray() do + queue.Enqueue(c) + override _.Peek() = + if queue.Count > 0 then queue.Peek() |> int else -1 + override _.Read() = + if queue.Count > 0 then queue.Dequeue() |> int else -1 + +type RedirectConsoleInput() = + let oldStdIn = Console.In + let newStdIn = new CapturedTextReader() + do Console.SetIn(newStdIn) + member _.ProvideInput(text: string) = + newStdIn.ProvideInput(text) + interface IDisposable with + member _.Dispose() = + Console.SetIn(oldStdIn) + newStdIn.Dispose() + +type EventedTextWriter() = + inherit TextWriter() + let sb = StringBuilder() + let lineWritten = Event() + member _.LineWritten = lineWritten.Publish + override _.Encoding = Encoding.UTF8 + override _.Write(c: char) = + if c = '\n' then + let line = + let v = sb.ToString() + if v.EndsWith("\r") then v.Substring(0, v.Length - 1) + else v + sb.Clear() |> ignore + lineWritten.Trigger(line) + else sb.Append(c) |> ignore + +type RedirectConsoleOutput() = + let outputProduced = Event() + let errorProduced = Event() + let oldStdOut = Console.Out + let oldStdErr = Console.Error + let newStdOut = new EventedTextWriter() + let newStdErr = new EventedTextWriter() + do newStdOut.LineWritten.Add outputProduced.Trigger + do newStdErr.LineWritten.Add errorProduced.Trigger + do Console.SetOut(newStdOut) + do Console.SetError(newStdErr) + member _.OutputProduced = outputProduced.Publish + member _.ErrorProduced = errorProduced.Publish + interface IDisposable with + member _.Dispose() = + Console.SetOut(oldStdOut) + Console.SetError(oldStdErr) + newStdOut.Dispose() + newStdErr.Dispose() + + +[] +type LangVersion = + | V47 + | V50 + | Preview + +type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion) = + + let additionalArgs = defaultArg additionalArgs [||] + let quiet = defaultArg quiet true + let langVersion = defaultArg langVersion LangVersion.Preview + let config = FsiEvaluationSession.GetDefaultConfiguration() + + let computedProfile = + // If we are being executed on the desktop framework (we can tell because the assembly containing int is mscorlib) then profile must be mscorlib otherwise use netcore + if typeof.Assembly.GetName().Name = "mscorlib" then "mscorlib" + else "netcore" + + let baseArgs = [| + typeof.Assembly.Location; + "--noninteractive"; + "--targetprofile:" + computedProfile + if quiet then "--quiet" + match langVersion with + | LangVersion.V47 -> "--langversion:4.7" + | LangVersion.V50 -> "--langversion:5.0" + | LangVersion.Preview -> "--langversion:preview" + |] + + let argv = Array.append baseArgs additionalArgs + + let fsi = FsiEvaluationSession.Create (config, argv, stdin, stdout, stderr) + + member _.ValueBound = fsi.ValueBound + + member _.Fsi = fsi + + member _.Eval(code: string, ?cancellationToken: CancellationToken) = + let cancellationToken = defaultArg cancellationToken CancellationToken.None + let ch, errors = fsi.EvalInteractionNonThrowing(code, cancellationToken) + match ch with + | Choice1Of2 v -> Ok(v), errors + | Choice2Of2 ex -> Error(ex), errors + + /// Get the available completion items from the code at the specified location. + /// + /// The input text on which completions will be calculated + /// The 1-based line index + /// The 0-based column index + member _.GetCompletionItems(text: string, line: int, column: int) = + async { + let parseResults, checkResults, _projectResults = fsi.ParseAndCheckInteraction(text) + let lineText = text.Split('\n').[line - 1] + let partialName = QuickParse.GetPartialLongNameEx(lineText, column - 1) + let declarationListInfos = checkResults.GetDeclarationListInfo(Some parseResults, line, lineText, partialName) + return declarationListInfos.Items + } + + interface IDisposable with + member _.Dispose() = + (fsi :> IDisposable).Dispose() + +[] +module TestHelpers = + + let getValue ((value: Result), (errors: FSharpDiagnostic[])) = + if errors.Length > 0 then + failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors)) + match value with + | Ok(value) -> value + | Error ex -> raise ex + + let ignoreValue = getValue >> ignore + + let getTempDir () = + let sysTempDir = Path.GetTempPath() + let customTempDirName = Guid.NewGuid().ToString("D") + let fullDirName = Path.Combine(sysTempDir, customTempDirName) + let dirInfo = Directory.CreateDirectory(fullDirName) + { new Object() with + member _.ToString() = dirInfo.FullName + interface IDisposable with + member _.Dispose() = + dirInfo.Delete(true) + } diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs new file mode 100644 index 00000000000..07b9c557ea1 --- /dev/null +++ b/tests/FSharp.Test.Utilities/TestFramework.fs @@ -0,0 +1,677 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module TestFramework + +open System +open System.IO +open System.Reflection +open System.Diagnostics +open Scripting +open NUnit.Framework +open FSharp.Compiler.IO + +let inline getTestsDirectory src dir = src ++ dir + +// Temporary directory is TempPath + "/FSharp.Test.Utilities/" date ("yyy-MM-dd") +// Throws exception if it Fails +let tryCreateTemporaryDirectory () = + let path = Path.GetTempPath() + let now = DateTime.Now.ToString("yyyy-MM-dd") + let directory = Path.Combine(path, "FSharp.Test.Utilities", now) + Directory.CreateDirectory(directory).FullName + +// Create a temporaryFileName -- newGuid is random --- there is no point validating the file alread exists because: threading and Path.ChangeExtension() is commonly used after this API +let tryCreateTemporaryFileName () = + let directory = tryCreateTemporaryDirectory () + let fileName = ("Temp-" + Guid.NewGuid().ToString() + ".tmp").Replace('-', '_') + let filePath = Path.Combine(directory, fileName) + filePath + +[] +module Commands = + + let gate = obj() + + // Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever + // returns exit code, stdio and stderr as string arrays + let executeProcess pathToExe arguments workingDir timeout = + match pathToExe with + | Some path -> + let errorsList = ResizeArray() + let outputList = ResizeArray() + let mutable errorslock = obj + let mutable outputlock = obj + let outputDataReceived (message: string) = + if not (isNull message) then + lock outputlock (fun () -> outputList.Add(message)) + + let errorDataReceived (message: string) = + if not (isNull message) then + lock errorslock (fun () -> errorsList.Add(message)) + + let psi = ProcessStartInfo() + psi.FileName <- path + psi.WorkingDirectory <- workingDir + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.Arguments <- arguments + psi.CreateNoWindow <- true + // When running tests, we want to roll forward to minor versions (including previews). + psi.EnvironmentVariables.["DOTNET_ROLL_FORWARD"] <- "LatestMajor" + psi.EnvironmentVariables.["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1" + psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things + psi.UseShellExecute <- false + + use p = new Process() + p.StartInfo <- psi + + p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data) + p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data) + + if p.Start() then + p.BeginOutputReadLine() + p.BeginErrorReadLine() + if not(p.WaitForExit(timeout)) then + // Timed out resolving throw a diagnostic. + raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments))) + else + p.WaitForExit() + #if DEBUG + let workingDir' = + if workingDir = "" + then + // Assign working dir to prevent default to C:\Windows\System32 + let executionLocation = Assembly.GetExecutingAssembly().Location + Path.GetDirectoryName executionLocation + else + workingDir + + lock gate (fun () -> + File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList) + File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList) + ) + #endif + p.ExitCode, outputList.ToArray(), errorsList.ToArray() + | None -> -1, Array.empty, Array.empty + + let getfullpath workDir (path:string) = + let rooted = + if Path.IsPathRooted(path) then path + else Path.Combine(workDir, path) + rooted |> Path.GetFullPath + + let fileExists workDir path = + if path |> getfullpath workDir |> FileSystem.FileExistsShim then Some path else None + + let directoryExists workDir path = + if path |> getfullpath workDir |> Directory.Exists then Some path else None + + let copy_y workDir source dest = + log "copy /y %s %s" source dest + File.Copy( source |> getfullpath workDir, dest |> getfullpath workDir, true) + CmdResult.Success + + let mkdir_p workDir dir = + log "mkdir %s" dir + Directory.CreateDirectory ( Path.Combine(workDir, dir) ) |> ignore + + let rm dir path = + let p = path |> getfullpath dir + if FileSystem.FileExistsShim(p) then + (log "rm %s" p) |> ignore + File.Delete(p) + else + (log "not found: %s p") |> ignore + + let rmdir dir path = + let p = path |> getfullpath dir + if Directory.Exists(p) then + (log "rmdir /sy %s" p) |> ignore + Directory.Delete(p, true) + else + (log "not found: %s p") |> ignore + + let pathAddBackslash (p: FilePath) = + if String.IsNullOrWhiteSpace (p) then p + else + p.TrimEnd ([| Path.DirectorySeparatorChar; Path.AltDirectorySeparatorChar |]) + + Path.DirectorySeparatorChar.ToString() + + let echoAppendToFile workDir text p = + log "echo %s> %s" text p + let dest = p |> getfullpath workDir in File.AppendAllText(dest, text + Environment.NewLine) + + let appendToFile workDir source p = + log "type %s >> %s" source p + let from = source |> getfullpath workDir + let dest = p |> getfullpath workDir + let contents = File.ReadAllText(from) + File.AppendAllText(dest, contents) + + let fsc workDir exec (dotNetExe: FilePath) (fscExe: FilePath) flags srcFiles = + let args = (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) + +#if FSC_IN_PROCESS + // This is not yet complete + printfn "Hosted Compiler:" + printfn "workdir: %A\nargs: %A"workdir args + let fscCompiler = FSharp.Compiler.Hosted.FscCompiler() + let exitCode, _stdin, _stdout = FSharp.Compiler.Hosted.CompilerHelpers.fscCompile workDir (FSharp.Compiler.Hosted.CompilerHelpers.parseCommandLine args) + + match exitCode with + | 0 -> CmdResult.Success + | err -> + let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'" fscExe args workDir + CmdResult.ErrorLevel (msg, err) +#else + ignore workDir +#if NETCOREAPP + exec dotNetExe (fscExe + " " + args) +#else + ignore dotNetExe + printfn "fscExe: %A" fscExe + printfn "args: %A" args + exec fscExe args +#endif +#endif + + let csc exec cscExe flags srcFiles = + exec cscExe (sprintf "%s %s /reference:netstandard.dll" flags (srcFiles |> Seq.ofList |> String.concat " ")) + + let vbc exec vbcExe flags srcFiles = + exec vbcExe (sprintf "%s %s /reference:netstandard.dll" flags (srcFiles |> Seq.ofList |> String.concat " ")) + + let fsi exec fsiExe flags sources = + exec fsiExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " ")) + + let internal quotepath (p: FilePath) = + let quote = '"'.ToString() + if p.Contains(" ") then (sprintf "%s%s%s" quote p quote) else p + + let ildasm exec ildasmExe flags assembly = + exec ildasmExe (sprintf "%s %s" flags (quotepath assembly)) + + let ilasm exec ilasmExe flags assembly = + exec ilasmExe (sprintf "%s %s" flags (quotepath assembly)) + + let peverify exec peverifyExe flags path = + exec peverifyExe (sprintf "%s %s" (quotepath path) flags) + + let createTempDir () = + let path = tryCreateTemporaryFileName () + File.Delete path + Directory.CreateDirectory path |> ignore + path + +type TestConfig = + { EnvironmentVariables : Map + CSC : string + csc_flags : string + VBC : string + vbc_flags : string + BUILD_CONFIG : string + FSC : string + fsc_flags : string + FSCOREDLLPATH : string + FSI : string +#if !NETCOREAPP + FSIANYCPU : string +#endif + FSI_FOR_SCRIPTS : string + FSharpBuild : string + FSharpCompilerInteractiveSettings : string + fsi_flags : string + ILDASM : string + ILASM : string + PEVERIFY : string + Directory: string + DotNetExe: string + DotNetMultiLevelLookup: string + DotNetRoot: string + DefaultPlatform: string} + +#if NETCOREAPP +open System.Runtime.InteropServices +#endif + +let getOperatingSystem () = +#if NETCOREAPP + let isPlatform p = RuntimeInformation.IsOSPlatform(p) + if isPlatform OSPlatform.Windows then "win" + elif isPlatform OSPlatform.Linux then "linux" + elif isPlatform OSPlatform.OSX then "osx" + else "unknown" +#else + "win" +#endif + +module DotnetPlatform = + let Is64BitOperatingSystem envVars = + match getOperatingSystem () with + | "win" -> + // On Windows PROCESSOR_ARCHITECTURE has the value AMD64 on 64 bit Intel Machines + let value = + let find s = envVars |> Map.tryFind s + [| "PROCESSOR_ARCHITECTURE" |] |> Seq.tryPick (fun s -> find s) |> function None -> "" | Some x -> x + value = "AMD64" + | _ -> System.Environment.Is64BitOperatingSystem // As an alternative for netstandard1.4+: System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture + +type FSLibPaths = + { FSCOREDLLPATH : string } + +let getPackagesDir () = + match Environment.GetEnvironmentVariable("NUGET_PACKAGES") with + | null -> + let path = match Environment.GetEnvironmentVariable("USERPROFILE") with + | null -> Environment.GetEnvironmentVariable("HOME") + | p -> p + path ++ ".nuget" ++ "packages" + | path -> path + +let requireFile dir path = + // Linux filesystems are (in most cases) case-sensitive. + // However when nuget packages are installed to $HOME/.nuget/packages, it seems they are lowercased + let fullPath = (dir ++ path) + match Commands.fileExists __SOURCE_DIRECTORY__ fullPath with + | Some _ -> fullPath + | None -> + let fullPathLower = (dir ++ path.ToLower()) + match Commands.fileExists __SOURCE_DIRECTORY__ fullPathLower with + | Some _ -> fullPathLower + | None -> failwith (sprintf "Couldn't find \"%s\" on the following paths: \"%s\", \"%s\". Running 'build test' once might solve this issue" path fullPath fullPathLower) + +let config configurationName envVars = + let SCRIPT_ROOT = __SOURCE_DIRECTORY__ + let fsharpCoreArchitecture = "netstandard2.0" + let fsharpBuildArchitecture = "netstandard2.0" + let fsharpCompilerInteractiveSettingsArchitecture = "netstandard2.0" +#if NET472 + let fscArchitecture = "net472" + let fsiArchitecture = "net472" + let peverifyArchitecture = "net472" +#else + let fscArchitecture = "net5.0" + let fsiArchitecture = "net5.0" + let peverifyArchitecture = "net5.0" +#endif + let repoRoot = SCRIPT_ROOT ++ ".." ++ ".." + let artifactsPath = repoRoot ++ "artifacts" + let artifactsBinPath = artifactsPath ++ "bin" + let coreClrRuntimePackageVersion = "5.0.0-preview.7.20364.11" + let csc_flags = "/nologo" + let vbc_flags = "/nologo" + let fsc_flags = "-r:System.Core.dll --nowarn:20 --define:COMPILED" + let fsi_flags = "-r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror" + let operatingSystem = getOperatingSystem () + let Is64BitOperatingSystem = DotnetPlatform.Is64BitOperatingSystem envVars + let architectureMoniker = if Is64BitOperatingSystem then "x64" else "x86" + let packagesDir = getPackagesDir () + let requirePackage = requireFile packagesDir + let requireArtifact = requireFile artifactsBinPath + let CSC = requirePackage ("Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "csc.exe") + let VBC = requirePackage ("Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "vbc.exe") + let ILDASM_EXE = if operatingSystem = "win" then "ildasm.exe" else "ildasm" + let ILDASM = requirePackage (("runtime." + operatingSystem + "-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ (operatingSystem + "-" + architectureMoniker) ++ "native" ++ ILDASM_EXE) + let ILASM_EXE = if operatingSystem = "win" then "ilasm.exe" else "ilasm" + let ILASM = requirePackage (("runtime." + operatingSystem + "-" + architectureMoniker + ".Microsoft.NETCore.ILAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ (operatingSystem + "-" + architectureMoniker) ++ "native" ++ ILASM_EXE) + let PEVERIFY_EXE = if operatingSystem = "win" then "PEVerify.exe" elif operatingSystem = "osx" then "PEVerify.dll" else "PEVerify" + let PEVERIFY = requireArtifact ("PEVerify" ++ configurationName ++ peverifyArchitecture ++ PEVERIFY_EXE) +// let FSI_FOR_SCRIPTS = artifactsBinPath ++ "fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.exe" + let FSharpBuild = requireArtifact ("FSharp.Build" ++ configurationName ++ fsharpBuildArchitecture ++ "FSharp.Build.dll") + let FSharpCompilerInteractiveSettings = requireArtifact ("FSharp.Compiler.Interactive.Settings" ++ configurationName ++ fsharpCompilerInteractiveSettingsArchitecture ++ "FSharp.Compiler.Interactive.Settings.dll") + + let dotNetExe = + // first look for {repoRoot}\.dotnet\dotnet.exe, otherwise fallback to %PATH% + let DOTNET_EXE = if operatingSystem = "win" then "dotnet.exe" else "dotnet" + let repoLocalDotnetPath = repoRoot ++ ".dotnet" ++ DOTNET_EXE + if FileSystem.FileExistsShim(repoLocalDotnetPath) then repoLocalDotnetPath + else DOTNET_EXE + +#if !NETCOREAPP + let FSI_PATH = ("fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.exe") +#else + let FSI_PATH = ("fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.dll") +#endif + let FSI_FOR_SCRIPTS = requireArtifact FSI_PATH + let FSI = requireArtifact FSI_PATH +#if !NETCOREAPP + let FSIANYCPU = requireArtifact ("fsiAnyCpu" ++ configurationName ++ "net472" ++ "fsiAnyCpu.exe") + let FSC = requireArtifact ("fsc" ++ configurationName ++ fscArchitecture ++ "fsc.exe") +#else + let FSC = requireArtifact ("fsc" ++ configurationName ++ fscArchitecture ++ "fsc.dll") +#endif + let FSCOREDLLPATH = requireArtifact ("FSharp.Core" ++ configurationName ++ fsharpCoreArchitecture ++ "FSharp.Core.dll") + + let defaultPlatform = + match Is64BitOperatingSystem with +// | PlatformID.MacOSX, true -> "osx.10.10-x64" +// | PlatformID.Unix,true -> "ubuntu.14.04-x64" + | true -> "win7-x64" + | false -> "win7-x86" + + { EnvironmentVariables = envVars + FSCOREDLLPATH = FSCOREDLLPATH + ILDASM = ILDASM + ILASM = ILASM + PEVERIFY = PEVERIFY + VBC = VBC + CSC = CSC + BUILD_CONFIG = configurationName + FSC = FSC + FSI = FSI +#if !NETCOREAPP + FSIANYCPU = FSIANYCPU +#endif + FSI_FOR_SCRIPTS = FSI_FOR_SCRIPTS + FSharpBuild = FSharpBuild + FSharpCompilerInteractiveSettings = FSharpCompilerInteractiveSettings + csc_flags = csc_flags + fsc_flags = fsc_flags + fsi_flags = fsi_flags + vbc_flags = vbc_flags + Directory="" + DotNetExe = dotNetExe + DotNetMultiLevelLookup = System.Environment.GetEnvironmentVariable "DOTNET_MULTILEVEL_LOOKUP" + DotNetRoot = System.Environment.GetEnvironmentVariable "DOTNET_ROOT" + DefaultPlatform = defaultPlatform } + +let logConfig (cfg: TestConfig) = + log "---------------------------------------------------------------" + log "Executables" + log "" + log "CSC = %s" cfg.CSC + log "BUILD_CONFIG = %s" cfg.BUILD_CONFIG + log "csc_flags = %s" cfg.csc_flags + log "FSC = %s" cfg.FSC + log "fsc_flags = %s" cfg.fsc_flags + log "FSCOREDLLPATH = %s" cfg.FSCOREDLLPATH + log "FSI = %s" cfg.FSI +#if NETCOREAPP + log "DotNetExe =%s" cfg.DotNetExe + log "DOTNET_MULTILEVEL_LOOKUP = %s" cfg.DotNetMultiLevelLookup + log "DOTNET_ROOT = %s" cfg.DotNetRoot +#else + log "FSIANYCPU = %s" cfg.FSIANYCPU +#endif + log "FSI_FOR_SCRIPTS = %s" cfg.FSI_FOR_SCRIPTS + log "fsi_flags = %s" cfg.fsi_flags + log "ILDASM = %s" cfg.ILDASM + log "PEVERIFY = %s" cfg.PEVERIFY + log "---------------------------------------------------------------" + +let checkResult result = + match result with + | CmdResult.ErrorLevel (msg1, err) -> Assert.Fail (sprintf "%s. ERRORLEVEL %d" msg1 err) + | CmdResult.Success -> () + +let checkErrorLevel1 result = + match result with + | CmdResult.ErrorLevel (_,1) -> () + | CmdResult.Success | CmdResult.ErrorLevel _ -> Assert.Fail (sprintf "Command passed unexpectedly") + +let envVars () = + System.Environment.GetEnvironmentVariables () + |> Seq.cast + |> Seq.map (fun d -> d.Key :?> string, d.Value :?> string) + |> Map.ofSeq + +let initializeSuite () = + +#if DEBUG + let configurationName = "Debug" +#else + let configurationName = "Release" +#endif + let env = envVars () + + let cfg = + let c = config configurationName env + let usedEnvVars = c.EnvironmentVariables |> Map.add "FSC" c.FSC + { c with EnvironmentVariables = usedEnvVars } + + logConfig cfg + + cfg + + +let suiteHelpers = lazy (initializeSuite ()) + +[] +type public InitializeSuiteAttribute () = + inherit TestActionAttribute() + + override x.BeforeTest details = + try + if details.IsSuite + then suiteHelpers.Force() |> ignore + with + | e -> raise (Exception("failed test suite initialization, debug code in InitializeSuiteAttribute", e)) + override x.AfterTest _details = + () + + override x.Targets = ActionTargets.Test ||| ActionTargets.Suite + +let testConfig (testDir: string) = + let cfg = suiteHelpers.Value + if not (Path.IsPathRooted testDir) then + failwith $"path is not rooted: {testDir}" + let testDir = Path.GetFullPath testDir // mostly used to normalize / and \ + log "------------------ %s ---------------" testDir + log "cd %s" testDir + { cfg with Directory = testDir } + +[] +type FileGuard(path: string) = + let remove path = if FileSystem.FileExistsShim(path) then Commands.rm (Path.GetTempPath()) path + do if not (Path.IsPathRooted(path)) then failwithf "path '%s' must be absolute" path + do remove path + member x.Path = path + member x.Exists = x.Path |> FileSystem.FileExistsShim + member x.CheckExists() = + if not x.Exists then + failwith (sprintf "exit code 0 but %s file doesn't exists" (x.Path |> Path.GetFileName)) + + interface IDisposable with + member x.Dispose () = remove path + + +type RedirectToType = + | Overwrite of FilePath + | Append of FilePath + +type RedirectTo = + | Inherit + | Output of RedirectToType + | OutputAndError of RedirectToType * RedirectToType + | OutputAndErrorToSameFile of RedirectToType + | Error of RedirectToType + +type RedirectFrom = + | RedirectInput of FilePath + +type RedirectInfo = + { Output : RedirectTo + Input : RedirectFrom option } + + +module Command = + + let logExec _dir path args redirect = + let inF = + function + | None -> "" + | Some(RedirectInput l) -> sprintf " <%s" l + let redirectType = function Overwrite x -> sprintf ">%s" x | Append x -> sprintf ">>%s" x + let outF = + function + | Inherit -> "" + | Output r-> sprintf " 1%s" (redirectType r) + | OutputAndError (r1, r2) -> sprintf " 1%s 2%s" (redirectType r1) (redirectType r2) + | OutputAndErrorToSameFile r -> sprintf " 1%s 2>1" (redirectType r) + | Error r -> sprintf " 2%s" (redirectType r) + sprintf "%s%s%s%s" path (match args with "" -> "" | x -> " " + x) (inF redirect.Input) (outF redirect.Output) + + let exec dir envVars (redirect:RedirectInfo) path args = + + let inputWriter sources (writer: StreamWriter) = + let pipeFile name = async { + let path = Commands.getfullpath dir name + use reader = File.OpenRead (path) + use ms = new MemoryStream() + do! reader.CopyToAsync (ms) |> (Async.AwaitIAsyncResult >> Async.Ignore) + ms.Position <- 0L + try + do! ms.CopyToAsync(writer.BaseStream) |> (Async.AwaitIAsyncResult >> Async.Ignore) + do! writer.FlushAsync() |> (Async.AwaitIAsyncResult >> Async.Ignore) + with + | :? System.IO.IOException -> //input closed is ok if process is closed + () + } + sources |> pipeFile |> Async.RunSynchronously + + let inF fCont cmdArgs = + match redirect.Input with + | None -> fCont cmdArgs + | Some(RedirectInput l) -> fCont { cmdArgs with RedirectInput = Some (inputWriter l) } + + let openWrite rt = + let fullpath = Commands.getfullpath dir + match rt with + | Append p -> File.AppendText( p |> fullpath) + | Overwrite p -> new StreamWriter(new FileStream(p |> fullpath, FileMode.Create)) + + let outF fCont cmdArgs = + match redirect.Output with + | RedirectTo.Inherit -> + use toLog = redirectToLog () + fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (toLog.Post) } + | Output r -> + use writer = openWrite r + use outFile = redirectTo writer + use toLog = redirectToLog () + fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (toLog.Post) } + | OutputAndError (r1,r2) -> + use writer1 = openWrite r1 + use writer2 = openWrite r2 + use outFile1 = redirectTo writer1 + use outFile2 = redirectTo writer2 + fCont { cmdArgs with RedirectOutput = Some (outFile1.Post); RedirectError = Some (outFile2.Post) } + | OutputAndErrorToSameFile r -> + use writer = openWrite r + use outFile = redirectTo writer + fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (outFile.Post) } + | Error r -> + use writer = openWrite r + use outFile = redirectTo writer + use toLog = redirectToLog () + fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (outFile.Post) } + + let exec cmdArgs = + log "%s" (logExec dir path args redirect) + Process.exec cmdArgs dir envVars path args + + { RedirectOutput = None; RedirectError = None; RedirectInput = None } + |> (outF (inF exec)) + +let alwaysSuccess _ = () + +let execArgs = { Output = Inherit; Input = None; } +let execAppend cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> checkResult +let execAppendIgnoreExitCode cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> alwaysSuccess +let exec cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkResult +let execExpectFail cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkErrorLevel1 +let execIn cfg workDir p = Command.exec workDir cfg.EnvironmentVariables execArgs p >> checkResult +let execBothToOutNoCheck cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = OutputAndErrorToSameFile(Overwrite(outFile)) } p +let execBothToOut cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkResult +let execBothToOutExpectFail cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkErrorLevel1 +let execAppendOutIgnoreExitCode cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = Output(Append(outFile)) } p >> alwaysSuccess +let execAppendErrExpectFail cfg errPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = Error(Overwrite(errPath)) } p >> checkErrorLevel1 +let execStdin cfg l p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult +let execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Append(stdoutPath), Append(stderrPath)); Input = Some(RedirectInput(stdinPath)) } p >> alwaysSuccess +let fsc cfg arg = Printf.ksprintf (Commands.fsc cfg.Directory (exec cfg) cfg.DotNetExe cfg.FSC) arg +let fscIn cfg workDir arg = Printf.ksprintf (Commands.fsc workDir (execIn cfg workDir) cfg.DotNetExe cfg.FSC) arg +let fscAppend cfg stdoutPath stderrPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppend cfg stdoutPath stderrPath) cfg.DotNetExe cfg.FSC) arg +let fscAppendIgnoreExitCode cfg stdoutPath stderrPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.DotNetExe cfg.FSC) arg +let fscBothToOut cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (execBothToOut cfg cfg.Directory out) cfg.DotNetExe cfg.FSC) arg +let fscBothToOutExpectFail cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (execBothToOutExpectFail cfg cfg.Directory out) cfg.DotNetExe cfg.FSC) arg +let fscAppendErrExpectFail cfg errPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendErrExpectFail cfg errPath) cfg.DotNetExe cfg.FSC) arg +let csc cfg arg = Printf.ksprintf (Commands.csc (exec cfg) cfg.CSC) arg +let vbc cfg arg = Printf.ksprintf (Commands.vbc (exec cfg) cfg.VBC) arg +let ildasm cfg arg = Printf.ksprintf (Commands.ildasm (exec cfg) cfg.ILDASM) arg +let ilasm cfg arg = Printf.ksprintf (Commands.ilasm (exec cfg) cfg.ILASM) arg +let peverify cfg = Commands.peverify (exec cfg) cfg.PEVERIFY "/nologo" +let peverifyWithArgs cfg args = Commands.peverify (exec cfg) cfg.PEVERIFY args +let fsi cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI) +#if !NETCOREAPP +let fsiAnyCpu cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSIANYCPU) +#endif +let fsi_script cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI_FOR_SCRIPTS) +let fsiExpectFail cfg = Printf.ksprintf (Commands.fsi (execExpectFail cfg) cfg.FSI) +let fsiAppendIgnoreExitCode cfg stdoutPath stderrPath = Printf.ksprintf (Commands.fsi (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.FSI) +let fileguard cfg = (Commands.getfullpath cfg.Directory) >> (fun x -> new FileGuard(x)) +let getfullpath cfg = Commands.getfullpath cfg.Directory +let fileExists cfg = Commands.fileExists cfg.Directory >> Option.isSome +let fsiStdin cfg stdinPath = Printf.ksprintf (Commands.fsi (execStdin cfg stdinPath) cfg.FSI) +let fsiStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath = Printf.ksprintf (Commands.fsi (execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath) cfg.FSI) +let rm cfg x = Commands.rm cfg.Directory x +let rmdir cfg x = Commands.rmdir cfg.Directory x +let mkdir cfg = Commands.mkdir_p cfg.Directory +let copy_y cfg f = Commands.copy_y cfg.Directory f >> checkResult +let copySystemValueTuple cfg = copy_y cfg (getDirectoryName(cfg.FSC) ++ "System.ValueTuple.dll") ("." ++ "System.ValueTuple.dll") + +let diff normalize path1 path2 = + let result = System.Text.StringBuilder() + let append s = result.AppendLine s |> ignore + let cwd = Directory.GetCurrentDirectory() + + if not <| FileSystem.FileExistsShim(path1) then + // creating empty baseline file as this is likely someone initializing a new test + File.WriteAllText(path1, String.Empty) + if not <| FileSystem.FileExistsShim(path2) then failwithf "Invalid path %s" path2 + + let lines1 = File.ReadAllLines(path1) + let lines2 = File.ReadAllLines(path2) + + let minLines = min lines1.Length lines2.Length + + for i = 0 to (minLines - 1) do + let normalizePath (line:string) = + if normalize then + let x = line.IndexOf(cwd, StringComparison.OrdinalIgnoreCase) + if x >= 0 then line.Substring(x+cwd.Length) else line + else line + + let line1 = normalizePath lines1.[i] + let line2 = normalizePath lines2.[i] + + if line1 <> line2 then + append <| sprintf "diff between [%s] and [%s]" path1 path2 + append <| sprintf "line %d" (i+1) + append <| sprintf " - %s" line1 + append <| sprintf " + %s" line2 + + if lines1.Length <> lines2.Length then + append <| sprintf "diff between [%s] and [%s]" path1 path2 + append <| sprintf "diff at line %d" minLines + lines1.[minLines .. (lines1.Length - 1)] |> Array.iter (append << sprintf "- %s") + lines2.[minLines .. (lines2.Length - 1)] |> Array.iter (append << sprintf "+ %s") + + result.ToString() + +let fsdiff cfg a b = + let actualFile = System.IO.Path.Combine(cfg.Directory, a) + let expectedFile = System.IO.Path.Combine(cfg.Directory, b) + let errorText = System.IO.File.ReadAllText (System.IO.Path.Combine(cfg.Directory, a)) + + let result = diff false expectedFile actualFile + if result <> "" then + log "%s" result + log "New error file:" + log "%s" errorText + + result + +let requireENCulture () = + match System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName with + | "en" -> true + | _ -> false diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs new file mode 100644 index 00000000000..9c9c62d8503 --- /dev/null +++ b/tests/FSharp.Test.Utilities/Utilities.fs @@ -0,0 +1,302 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Test + +open System +open System.IO +open System.Reflection +open System.Collections.Immutable +open System.Diagnostics +open System.Threading.Tasks +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.CSharp +open TestFramework +open NUnit.Framework + +// This file mimics how Roslyn handles their compilation references for compilation testing + +module Utilities = + + type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + + [] + type TargetFramework = + | NetStandard20 + | NetCoreApp31 + | Current + + let private getResourceStream name = + let assembly = typeof.GetTypeInfo().Assembly + + let stream = assembly.GetManifestResourceStream(name); + + match stream with + | null -> failwith (sprintf "Resource '%s' not found in %s." name assembly.FullName) + | _ -> stream + + let private getResourceBlob name = + use stream = getResourceStream name + let (bytes: byte[]) = Array.zeroCreate (int stream.Length) + use memoryStream = new MemoryStream (bytes) + stream.CopyTo(memoryStream) + bytes + + let inline getTestsDirectory src dir = src ++ dir + + let private getOrCreateResource (resource: byref) (name: string) = + match resource with + | null -> getResourceBlob name + | _ -> resource + + module private TestReferences = + [] + module NetStandard20 = + let netStandard = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.netstandard).GetReference(display = "netstandard.dll (netstandard 2.0 ref)") + let mscorlibRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.mscorlib).GetReference(display = "mscorlib.dll (netstandard 2.0 ref)") + let systemRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Runtime).GetReference(display = "System.Runtime.dll (netstandard 2.0 ref)") + let systemCoreRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Core).GetReference(display = "System.Core.dll (netstandard 2.0 ref)") + let systemDynamicRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Dynamic_Runtime).GetReference(display = "System.Dynamic.Runtime.dll (netstandard 2.0 ref)") + + + module private NetCoreApp31Refs = + let mutable (_mscorlib: byte[]) = Unchecked.defaultof + let mutable (_netstandard: byte[]) = Unchecked.defaultof + let mutable (_System_Console: byte[]) = Unchecked.defaultof + let mutable (_System_Core: byte[]) = Unchecked.defaultof + let mutable (_System_Dynamic_Runtime: byte[]) = Unchecked.defaultof + let mutable (_System_Runtime: byte[]) = Unchecked.defaultof + let mscorlib () = getOrCreateResource &_mscorlib "mscorlib.dll" + let netstandard () = getOrCreateResource &_netstandard "netstandard.dll" + let System_Core () = getOrCreateResource &_System_Core "System.Core.dll" + let System_Console () = getOrCreateResource &_System_Console "System.Console.dll" + let System_Runtime () = getOrCreateResource &_System_Runtime "System.Runtime.dll" + let System_Dynamic_Runtime () = getOrCreateResource &_System_Dynamic_Runtime "System.Dynamic.Runtime.dll" + + [] + module NetCoreApp31 = + let netStandard = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.netstandard ()).GetReference(display = "netstandard.dll (netcoreapp 3.1 ref)") + let mscorlibRef = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.mscorlib ()).GetReference(display = "mscorlib.dll (netcoreapp 3.1 ref)") + let systemRuntimeRef = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.System_Runtime ()).GetReference(display = "System.Runtime.dll (netcoreapp 3.1 ref)") + let systemCoreRef = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.System_Core ()).GetReference(display = "System.Core.dll (netcoreapp 3.1 ref)") + let systemDynamicRuntimeRef = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.System_Dynamic_Runtime ()).GetReference(display = "System.Dynamic.Runtime.dll (netcoreapp 3.1 ref)") + let systemConsoleRef = lazy AssemblyMetadata.CreateFromImage(NetCoreApp31Refs.System_Console ()).GetReference(display = "System.Console.dll (netcoreapp 3.1 ref)") + + [] + module TargetFrameworkUtil = + + let private config = TestFramework.initializeSuite () + + // Do a one time dotnet sdk build to compute the proper set of reference assemblies to pass to the compiler + let private projectFile = """ + + + + Exe + $TARGETFRAMEWORK + true + true + + + + + + + + + + + + + + + + + + + + + + + +""" + + let private directoryBuildProps = """ + + +""" + + let private directoryBuildTargets = """ + + +""" + + let private programFs = """ +open System + +[] +let main argv = 0""" + + let private getNetCoreAppReferences = + let mutable output = "" + let mutable errors = "" + let mutable cleanUp = true + let pathToArtifacts = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "../../../..")) + if Path.GetFileName(pathToArtifacts) <> "artifacts" then failwith "CompilerAssert did not find artifacts directory --- has the location changed????" + let pathToTemp = Path.Combine(pathToArtifacts, "Temp") + let projectDirectory = Path.Combine(pathToTemp, "CompilerAssert", Path.GetRandomFileName()) + let pathToFSharpCore = typeof.Assembly.Location + try + try + Directory.CreateDirectory(projectDirectory) |> ignore + let projectFileName = Path.Combine(projectDirectory, "ProjectFile.fsproj") + let programFsFileName = Path.Combine(projectDirectory, "Program.fs") + let directoryBuildPropsFileName = Path.Combine(projectDirectory, "Directory.Build.props") + let directoryBuildTargetsFileName = Path.Combine(projectDirectory, "Directory.Build.targets") + let frameworkReferencesFileName = Path.Combine(projectDirectory, "FrameworkReferences.txt") +#if NETCOREAPP + File.WriteAllText(projectFileName, projectFile.Replace("$TARGETFRAMEWORK", "net5.0").Replace("$FSHARPCORELOCATION", pathToFSharpCore)) +#else + File.WriteAllText(projectFileName, projectFile.Replace("$TARGETFRAMEWORK", "net472").Replace("$FSHARPCORELOCATION", pathToFSharpCore)) +#endif + File.WriteAllText(programFsFileName, programFs) + File.WriteAllText(directoryBuildPropsFileName, directoryBuildProps) + File.WriteAllText(directoryBuildTargetsFileName, directoryBuildTargets) + + let timeout = 30000 + let exitCode, output, errors = Commands.executeProcess (Some config.DotNetExe) "build" projectDirectory timeout + + if exitCode <> 0 || errors.Length > 0 then + printfn "Output:\n=======\n" + output |> Seq.iter(fun line -> printfn "STDOUT:%s\n" line) + printfn "Errors:\n=======\n" + errors |> Seq.iter(fun line -> printfn "STDERR:%s\n" line) + Assert.True(false, "Errors produced generating References") + + File.ReadLines(frameworkReferencesFileName) |> Seq.toArray + with | e -> + cleanUp <- false + printfn "Project directory: %s" projectDirectory + printfn "STDOUT: %s" output + File.WriteAllText(Path.Combine(projectDirectory, "project.stdout"), output) + printfn "STDERR: %s" errors + File.WriteAllText(Path.Combine(projectDirectory, "project.stderror"), errors) + raise (new Exception (sprintf "An error occurred getting netcoreapp references: %A" e)) + finally + if cleanUp then + try Directory.Delete(projectDirectory, recursive=true) with | _ -> () + + open TestReferences + + let private netStandard20References = + lazy ImmutableArray.Create(NetStandard20.netStandard.Value, NetStandard20.mscorlibRef.Value, NetStandard20.systemRuntimeRef.Value, NetStandard20.systemCoreRef.Value, NetStandard20.systemDynamicRuntimeRef.Value) + let private netCoreApp31References = + lazy ImmutableArray.Create(NetCoreApp31.netStandard.Value, NetCoreApp31.mscorlibRef.Value, NetCoreApp31.systemRuntimeRef.Value, NetCoreApp31.systemCoreRef.Value, NetCoreApp31.systemDynamicRuntimeRef.Value, NetCoreApp31.systemConsoleRef.Value) + + let currentReferences = + getNetCoreAppReferences + + let currentReferencesAsPEs = + getNetCoreAppReferences + |> Seq.map (fun x -> + PortableExecutableReference.CreateFromFile(x) + ) + |> ImmutableArray.CreateRange + + let getReferences tf = + match tf with + | TargetFramework.NetStandard20 -> netStandard20References.Value + | TargetFramework.NetCoreApp31 -> netCoreApp31References.Value + | TargetFramework.Current -> currentReferencesAsPEs + + type RoslynLanguageVersion = LanguageVersion + + [] + type CSharpCompilationFlags = + | None = 0x0 + | InternalsVisibleTo = 0x1 + + [] + type TestCompilation = + | CSharp of CSharpCompilation + | IL of ilSource: string * result: Lazy + + member this.AssertNoErrorsOrWarnings () = + match this with + | TestCompilation.CSharp c -> + let diagnostics = c.GetDiagnostics () + + if not diagnostics.IsEmpty then + NUnit.Framework.Assert.Fail ("CSharp source diagnostics:\n" + (diagnostics |> Seq.map (fun x -> x.GetMessage () + "\n") |> Seq.reduce (+))) + + | TestCompilation.IL (_, result) -> + let errors, _ = result.Value + if errors.Length > 0 then + NUnit.Framework.Assert.Fail ("IL source errors: " + errors) + + member this.EmitAsFile (outputPath: string) = + match this with + | TestCompilation.CSharp c -> + let c = c.WithAssemblyName(Path.GetFileNameWithoutExtension outputPath) + let emitResult = c.Emit outputPath + if not emitResult.Success then + failwithf "Unable to emit C# compilation.\n%A" emitResult.Diagnostics + + | TestCompilation.IL (_, result) -> + let (_, data) = result.Value + File.WriteAllBytes (outputPath, data) + + type CSharpLanguageVersion = + | CSharp8 = 0 + | CSharp9 = 1 + + [] + type CompilationUtil private () = + + static member CreateCSharpCompilation (source: string, lv: CSharpLanguageVersion, ?tf, ?additionalReferences, ?name) = + let lv = + match lv with + | CSharpLanguageVersion.CSharp8 -> LanguageVersion.CSharp8 + | CSharpLanguageVersion.CSharp9 -> LanguageVersion.CSharp9 + | _ -> LanguageVersion.Default + + let tf = defaultArg tf TargetFramework.NetStandard20 + let n = defaultArg name (Guid.NewGuid().ToString ()) + let additionalReferences = defaultArg additionalReferences ImmutableArray.Empty + let references = TargetFrameworkUtil.getReferences tf + let c = + CSharpCompilation.Create( + n, + [ CSharpSyntaxTree.ParseText (source, CSharpParseOptions lv) ], + references.As().AddRange additionalReferences, + CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary)) + TestCompilation.CSharp c + + static member CreateILCompilation (source: string) = + let compute = + lazy + let ilFilePath = tryCreateTemporaryFileName () + let tmp = tryCreateTemporaryFileName () + let dllFilePath = Path.ChangeExtension (tmp, ".dll") + try + File.WriteAllText (ilFilePath, source) + let errors = ILChecker.reassembleIL ilFilePath dllFilePath + try + (errors, File.ReadAllBytes dllFilePath) + with + | _ -> (errors, [||]) + finally + try File.Delete ilFilePath with | _ -> () + try File.Delete tmp with | _ -> () + try File.Delete dllFilePath with | _ -> () + TestCompilation.IL (source, compute) diff --git a/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs new file mode 100644 index 00000000000..facf0674bd7 --- /dev/null +++ b/tests/FSharp.Test.Utilities/Xunit/Attributes/DirectoryAttribute.fs @@ -0,0 +1,79 @@ +namespace FSharp.Test.Xunit.Attributes + +open System +open System.IO +open System.Reflection +open Xunit.Sdk + +open FSharp.Compiler.IO + +open FSharp.Test +open FSharp.Test.Compiler + +/// Attribute to use with Xunit's TheoryAttribute. +/// Takes a directory, relative to current test suite's root. +/// Returns a CompilationUnit with encapsulated source code, error baseline and IL baseline (if any). +[] +[] +type DirectoryAttribute(dir: string) = + inherit DataAttribute() + do + if String.IsNullOrWhiteSpace(dir) then + invalidArg "dir" "Directory cannot be null, empty or whitespace only." + + let directory = dir + + let mutable includes = Array.empty + + let readFileOrDefault (path: string) : string option = + match FileSystem.FileExistsShim(path) with + | true -> Some <| File.ReadAllText path + | _ -> None + + let createCompilationUnit path fs = + let filePath = path ++ fs + let fsSource = File.ReadAllText filePath + let bslFilePath = filePath + ".bsl" + let ilFilePath = filePath + ".il" + let bslSource = readFileOrDefault bslFilePath + let ilSource = readFileOrDefault ilFilePath + + { Source = Text fsSource + Baseline = + Some { SourceFilename = Some filePath + OutputBaseline = { FilePath = bslFilePath; Content = bslSource } + ILBaseline = { FilePath = ilFilePath; Content = ilSource } } + Options = [] + OutputType = Library + SourceKind = SourceKind.Fsx + Name = Some fs + IgnoreWarnings = false + References = [] } |> FS + + member _.Includes with get() = includes and set v = includes <- v + + override _.GetData(_: MethodInfo) = + let absolutePath = Path.GetFullPath(directory) + + if not (Directory.Exists(absolutePath)) then + failwith (sprintf "Directory does not exist: \"%s\"." absolutePath) + + let allFiles : string[] = Directory.GetFiles(absolutePath, "*.fs") + + let filteredFiles = + match (includes |> Array.map (fun f -> absolutePath ++ f)) with + | [||] -> allFiles + | incl -> incl + + let fsFiles = filteredFiles |> Array.map Path.GetFileName + + if fsFiles |> Array.length < 1 then + failwith (sprintf "No required files found in \"%s\".\nAll files: %A.\nIncludes:%A." absolutePath allFiles includes) + + for f in filteredFiles do + if not <| FileSystem.FileExistsShim(f) then + failwithf "Requested file \"%s\" not found.\nAll files: %A.\nIncludes:%A." f allFiles includes + + fsFiles + |> Array.map (fun fs -> createCompilationUnit absolutePath fs) + |> Seq.map (fun c -> [| c |]) diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000000..59ad0678aac --- /dev/null +++ b/tests/README.md @@ -0,0 +1,109 @@ +# F# Testing proposal + +## Why do we test + +* To prevent regressions (behavioral, performance). +* To have a quicker debug feedback (thus, find problems quicker). +* To verify conformance to language spec (API contract testing). +* To have IL verification (both read and write). +* To have a quicker design feedback. +* To document behavior. + +## Goals + +* Use one standardized testing framework across all of test projects, and get rid of custom old solutions (FSharpQA and Cambridge suites). +* Have tests restructured the way, that they are easy to discover. +* Have tests building and running on all supported platforms (Windows, macOS and Linux) and different frameworks (with exceptions when this is not applicable). +* Make it easy to run tests using standard .NET instruments (dotnet cli, test explorer, etc.). +* Leverage standard .NET testing platform and use all its benefits, suck as live unit testing, code coverage collecting, dead code elimination, etc. + +## Framework for testing + +The following test frameworks and libraries will be used for new test projects **[xUnit Test Framework](https://xunit.net/), [FluentAssertions](https://fluentassertions.com/) (+ [FsUnit](https://fsprojects.github.io/FsUnit/) and [FsCheck](https://github.com/fscheck/FsCheck) when needed)**. All existing NUnit test suites will be migrated to xUnit. + +**Justification:** + +* **xUnit** is an extensible, TDD adherent, testing framework, which was successfully adopted by many .NET engineering teams, including Roslyn, AspNetCore, EFcore, etc, has a "cleaner" approach for writing test suites (i.e. class constructor for setup, implementing IDisposable for teardown, as oppose to custom attributes). More info [here](https://xunit.net/docs/comparisons). +* **FluentAssertions** makes it easier to write scoped assertions, provides better error messages. + +**Alternatives:** NUnit, MSBuild, Expecto + +### Tests categorization + +#### New tests should be grouped based on two factors: test type (1) + test category and subcategory (2) + +1. **Test type**: +**Determines what type of test is it:** + * __Functional tests__: + * __Unit Tests__: a lightweight testing for smaller modules, functions, etc. + * __Examples__: Testing individual parts/functions of lexer, parser, syntax tree, standard library modules, etc. + * __Subgroups__: there should be a separation between testing private and public parts of each module (i.e. compiler tests for private and public API should be in separate test projects). + * __Component Tests__: testing for bigger parts of compiler. + * __Examples__: Tests for the compiler components as whole, such as Code generation, IL Generation, Compiler optimizations, Type Checker, Type Providers, Conformance, etc. + * __Integration and End2End Tests__: testing of F# compiler & tooling integration, as well as e2e experiences. + * __Examples__: VS Integration, .NET Interactive integration, LSP integration. Integration with dotnet CLI, project creation, building, running. + * __Non-functional tests__: + * __Load and Stress Tests__: testing for high level modules/components to understand peak performance and potentially catch any performance regressions. + * __Examples__: measuring compile, build, link times for the compiler, individual functions (i.e. data structures sorting, traversing, etc.). +1. **Test category and subcategory**: Tests (sub)categories shall be determined by the project, library, module, and functionality tests are covering. + +#### Examples + +* F# compiler component test which is verifying generated IL for computation expression will have category `Compiler` and subcategories `EmittedIL` and `ComputationExpressions`. +* F# compiler service unit test which is testing F# tokenizer, will have category `Compiler.Service` and subcategory `Tokenizer`. + +Please, refer to [File and project structure](#File-and-project-structure) for more information on how tests will be organized on the filesystem. + +## File and project structure + +### Naming schema + +The proposed naming schema for test projects is: `FSharp.Category.Subcategory.TestType`, where +`Category.Subcategory` is either a corresponding source project, or a more generic component (e.g. `Compiler`, `Compiler.Private` or more granular `Compiler.CodeGen`, `Compiler.CodeGen.EmittedIL` if category or subcategory project becomes too big, etc.) and `TestType` is the type of the test (one of `UnitTests`, `ComponentTests`, `IntegrationTests`, `LoadTests`). + +### Projects organization + +Please refer to the "[Naming schema](#Naming-schema)" section above for more information on the projects naming. + +New test projects will be grouped by category and test type, all subcategories are just test folders/files in the test project. + +* __Examples__: Having test project organized like: + > `tests/FSharp.Compiler.ComponentTests/CodeGen/EmittedIL/BasicTests.fs` + > `tests/FSharp.Compiler.ComponentTests/CodeGen/StringEncoding/StringTests.fs` + > `tests/FSharp.Compiler.ComponentTests/Optimizations/Inlining/InliningTests.fs` + + Will result in one test dll "`FSharp.Compiler.ComponentTests.dll`" which will contain all the subcategories of tests. +* **Notes**: + * This will result in reduced fragmentation of tests, all the tests files are under one big category, easier to understand what each component/unit test suite covers, less confusion in test classification for new tests. + * If some categories (or subcategories) will become big enough - they can be factored out to a separate project. + +### Test Utilities/Helpers + +For all new and migrated tests, any common/helper functionality shall be factored out to a separate project - `FSharp.Test.Utilities`. + +## New tests + +* All new tests should be created in the new projects only. +* All new tests should contain a brief docstring description of what is being tested, link to an issue if applicable. +* All new tests should be categorized using xUnit's `Trait`, based on their `Category` and `Subcategories`. + +## Migrating existing tests + +Existing FSharpQA and Cambridge need to be migrated to corresponding test projects: component-style tests to the `FSharp.Compiler.ComponentTests` and unittest-style tests - `FSharp.Compiler.UnitTests`, `FSharp.Compiler.Private.Scripting.UnitTests`, `FSharp.Build.UnitTests`, etc. + +## Next steps + +* [**In Progress**] Migrate existing `NUnit` tests to xUnit. +* Clean up CompilerAssert. +* Make PEVerify tests work in netcore/non-windows environment. +* Start migration of existing (namely, FSharpQA and Cambridge) suites to xUnit-based projects. + +## Open questions: + +* As far as I know, [FSharp.Compiler.Service](https://github.com/fsharp/FSharp.Compiler.Service) is dependant on some of the F# compiler tests. Does it have to be changed as well? + +## Other + +Related issues: (https://github.com/dotnet/fsharp/issues/7075) + +You can find this document under 'tests/README.md'. diff --git a/tests/benchmarks/BenchmarkComparison/BenchmarkComparison.fs b/tests/benchmarks/BenchmarkComparison/BenchmarkComparison.fs new file mode 100644 index 00000000000..bbdfb9a0784 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/BenchmarkComparison.fs @@ -0,0 +1,131 @@ +module BenchmarkComparison + +open System +open System.IO +open System.Threading.Tasks +open BenchmarkDotNet.Attributes + +[] +module BenchmarkHelpers = + + type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + +#if SERVICE_13_0_0 + open Microsoft.FSharp.Compiler.SourceCodeServices +#else +#if SERVICE_30_0_0 + open FSharp.Compiler.SourceCodeServices + open FSharp.Compiler.Text +#else + open FSharp.Compiler.Diagnostics + open FSharp.Compiler.CodeAnalysis + open FSharp.Compiler.Text +#endif +#endif + + type BenchmarkSingleFileCompiler(filePath: string) = + + let mutable checkerOpt = None + let mutable testFileOpt = None + let mutable assembliesOpt = None + + let fileText = +#if SERVICE_13_0_0 + File.ReadAllText(filePath) +#else + SourceText.ofString(File.ReadAllText(filePath)) +#endif + + member _.Setup() = + match checkerOpt with + | None -> checkerOpt <- Some(FSharpChecker.Create(projectCacheSize = 200)) + | _ -> () + + match assembliesOpt with + | None -> + let mainAssemblyLocation = typeof.Assembly.Location + let frameworkDirectory = Path.GetDirectoryName(mainAssemblyLocation) + assembliesOpt <- + Directory.EnumerateFiles(frameworkDirectory) + |> Seq.filter (fun x -> + let name = Path.GetFileName(x) + (name.StartsWith("System.") && name.EndsWith(".dll") && not(name.Contains("Native"))) || + name.Contains("netstandard") || + name.Contains("mscorlib") + ) + |> Array.ofSeq + |> Array.append [|typeof.Assembly.Location|] + |> Some + + | _ -> () + + match testFileOpt with + | None -> + let refs = + assembliesOpt.Value + |> Array.map (fun x -> + $"-r:{x}" + ) + let args = + Array.append refs [|"--simpleresolution";"--targetprofile:netcore";"--noframework"|] + let args = + Array.append [|filePath|] args + let options = + checkerOpt.Value.GetProjectOptionsFromCommandLineArgs("test.fsproj", args) + testFileOpt <- Some options + | _ -> () + + member _.Run() = + match checkerOpt, testFileOpt with + | None, _ -> failwith "no checker" + | _, None -> failwith "no test file" + | Some(checker), Some(options) -> + let _, result = + checker.ParseAndCheckFileInProject(filePath, 0, fileText, options) + |> Async.RunImmediate + match result with + | FSharpCheckFileAnswer.Aborted -> failwith "checker aborted" + | FSharpCheckFileAnswer.Succeeded results -> +#if SERVICE_13_0_0 + if results.Errors.Length > 0 then failwithf "had errors: %A" results.Errors +#else +#if SERVICE_30_0_0 + if results.Errors.Length > 0 then failwithf "had errors: %A" results.Errors +#else + if results.Diagnostics.Length > 0 then failwithf "had errors: %A" results.Diagnostics +#endif +#endif + + member _.Cleanup() = + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + +[] +type TypeCheckingBenchmark1() = + let compiler = BenchmarkSingleFileCompiler(Path.Combine(__SOURCE_DIRECTORY__, "decentlySizedStandAloneFile.fs")) + + [] + member _.Setup() = + compiler.Setup() + + [] + member _.Run() = + compiler.Run() + + [] + member _.Cleanup() = + compiler.Cleanup() \ No newline at end of file diff --git a/tests/benchmarks/BenchmarkComparison/Program.fs b/tests/benchmarks/BenchmarkComparison/Program.fs new file mode 100644 index 00000000000..d60a6dabe40 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/Program.fs @@ -0,0 +1,11 @@ + +open System.IO +open System.Reflection +open BenchmarkDotNet.Running +open BenchmarkComparison + +[] +let main _ = + BenchmarkRunner.Run() |> ignore + 0 + diff --git a/tests/benchmarks/BenchmarkComparison/decentlySizedStandAloneFile.fs b/tests/benchmarks/BenchmarkComparison/decentlySizedStandAloneFile.fs new file mode 100644 index 00000000000..95b2f151be6 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/decentlySizedStandAloneFile.fs @@ -0,0 +1,547 @@ +module Parser = + + (* + F# implementation of a generic Top-Down-Operator-Precedence Parser + as described in this paper http://portal.acm.org/citation.cfm?id=512931. + + The parser has been extended to allow for statements in comparison to Pratt's + original algorithm which only parsed languages which use expression-only grammar. + + The parsers is "impure" in the sense that is uses a ref-cell for storing the + input in the T<_, _, _> record class, this is soley for performance reasons + as it's to expensive to create a new record object for every consumed token. + Certain functions also throw exceptions, which generally also is considered impure. + + The parser produces nice error message in this style: + + Error on line: 5 col: 9 + 4: if(x == y) { + 5: print'x equals y'); + ----------^ + Unexpected: #string "x equals y" + + More information: + * http://en.wikipedia.org/wiki/Vaughan_Pratt (Original Inventor) + * http://en.wikipedia.org/wiki/Pratt_parser (Alias name) + * http://effbot.org/zone/simple-top-down-parsing.htm (Python implementation) + * http://javascript.crockford.com/tdop/tdop.html (JavaScript implementation) + *) + + type Pos = int * int + + type T<'a, 'b, 'c> when 'c : comparison = { + Input : 'a list ref + Lines : string option + + Type : 'a -> 'c + Position : 'a -> Pos + PrettyPrint : ('a -> string) option + + //Parser definitions and binding powers + BindingPower : Map<'c, int> + Null : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Stmt : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Left : Map<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b> + } + + type Pattern<'a, 'b, 'c> when 'c : comparison + = Sym of 'c + | Get of (T<'a, 'b, 'c> -> 'b) + + //Errors + type Exn (msg, pos) = + inherit System.Exception(msg) + member x.Position = pos + + (* + Creates a string error snippet + that points out the exact source position + where the error occured, for example: + + 4: if(x == y) { + 5: print'x equals y'); + ----------^ + *) + let errorSource pos source = + + let splitLines (text:string) = + let text = text.Replace("\r\n", "\n").Replace("\r", "\n") + System.Text.RegularExpressions.Regex.Split(text, "\n") + + let lineNum (input:int) n = + (input.ToString()).PadLeft(n, '0') + + let stringRepeat n input = + if System.String.IsNullOrEmpty input then input + else + let result = new System.Text.StringBuilder(input.Length * n) + result.Insert(0, input, n).ToString() + + match source with + | None -> "" + | Some(source:string) -> + let source = source |> splitLines + let result = ref "" + let line, column = pos + + if line <= source.Length && line > 1 then + let nr = line.ToString() + let nrl = nr.Length + + //previous line + let pline = line - 1 + if pline >= 1 then + let num = lineNum pline nrl + result := num+": "+source.[pline-1]+"\n" + + //current line + let text = source.[line-1] + if column <= text.Length then + let arrow = "-" |> stringRepeat (nrl + column) + result := !result+nr+": "+text+"\n"+arrow+"^\n" + + !result + + let exn msg = Exn(msg, (0, 0)) |> raise + let exnLine pos msg = + let line = sprintf "Error on line: %i col: %i\n" (fst pos) (snd pos) + Exn(line + msg, pos) |> raise + + let private unexpectedEnd () = "Unexpected end of input" |> exn + let private unexpectedToken token parser = + let type' = + match parser.PrettyPrint with + | None -> (token |> parser.Type).ToString() + | Some f -> token |> f + + let pos = token |> parser.Position + let source = parser.Lines |> errorSource pos + let expected = sprintf "Unexpected: %s" type' + (source + expected) |> exnLine pos + + let inline private getBindingPower tok parser = + let pwr = parser.BindingPower.TryFind (parser.Type tok) + match pwr with Some pwr -> pwr | _ -> 0 + + let current parser = + match !parser.Input with + | token::_ -> token + | _ -> unexpectedEnd () + + let currentTry parser = + match !parser.Input with + | token::_ -> Some token + | _ -> None + + let currentType parser = + parser |> current |> parser.Type + + let currentTypeTry parser = + match parser |> currentTry with + | Some token -> Some(token |> parser.Type) + | _ -> None + + let skip parser = + match !parser.Input with + | _::input -> parser.Input := input + | _ -> unexpectedEnd () + + let skipIf type' parser = + match !parser.Input with + | token::xs when parser.Type token = type' -> + parser.Input := xs + + | token::_ -> + unexpectedToken token parser + + | _ -> unexpectedEnd () + + let skipCurrent parser = + let current = parser |> current + parser |> skip + current + + let exprPwr rbpw parser = + let rec expr left = + match parser |> currentTry with + | Some token when rbpw < (parser |> getBindingPower token) -> + parser |> skip + + let type' = parser.Type token + let led = + match parser.Left.TryFind type' with + | None -> unexpectedToken token parser + | Some led -> led + + led token left parser |> expr + + | _ -> left + + let tok = parser |> skipCurrent + let type' = parser.Type tok + let nud = + match parser.Null.TryFind type' with + | None -> unexpectedToken tok parser + | Some nud -> nud + + nud tok parser |> expr + + let expr parser = + parser |> exprPwr 0 + + let exprSkip type' parser = + let expr = parser |> expr + parser |> skipIf type' + expr + + let rec exprList parser = + match !parser.Input with + | [] -> [] + | _ -> (parser |> expr) :: (parser |> exprList) + + let stmt term parser = + let token = parser |> current + match parser.Stmt.TryFind (token |> parser.Type) with + | Some stmt -> parser |> skip; stmt token parser + | None -> parser |> exprSkip term + + let rec stmtList term parser = + match !parser.Input with + | [] -> [] + | _ -> (parser |> stmt term) :: (parser |> stmtList term) + + let match' pattern parser = + let rec match' acc pattern parser = + match pattern with + | [] -> acc |> List.rev + + | Sym(symbol)::pattern -> + parser |> skipIf symbol + parser |> match' acc pattern + + | Get(f)::pattern -> + let acc = (f parser) :: acc + parser |> match' acc pattern + + parser |> match' [] pattern + + (* + Convenience functions exposed for + easing parser definition and usage + *) + + let create<'a, 'b, 'c when 'c : comparison> type' position prettyPrint = { + Input = ref [] + Lines = None + + Type = type' + Position = position + PrettyPrint = prettyPrint + + BindingPower = Map.empty<'c, int> + Null = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Stmt = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Left = Map.empty<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b> + } + + let matchError () = exn "Match pattern failed" + let smd token funct parser = {parser with T.Stmt = parser.Stmt.Add(token, funct)} + let nud token funct parser = {parser with T.Null = parser.Null.Add(token, funct)} + let led token funct parser = {parser with T.Left = parser.Left.Add(token, funct)} + let bpw token power parser = {parser with T.BindingPower = parser.BindingPower.Add(token, power)} + + (*Defines a left-associative infix operator*) + let infix f typ pwr p = + let infix tok left p = + f tok left (p |> exprPwr pwr) + + p |> bpw typ pwr |> led typ infix + + (*Defines a right-associative infix operator*) + let infixr f typ pwr p = + let lpwr = pwr - 1 + + let infix tok left p = + f tok left (p |> exprPwr lpwr) + + p |> bpw typ pwr |> led typ infix + + (*Defines a prefix/unary operator*) + let prefix f typ pwr p = + let prefix tok parser = + f tok (parser |> exprPwr pwr) + + p |> nud typ prefix + + (*Defines a constant*) + let constant symbol value p = + p |> nud symbol (fun _ _ -> value) + + (* + Runs the parser and treats all + top level construct as expressions + *) + let runExpr input source parser = + {parser with + T.Input = ref input + T.Lines = source + } |> exprList + + (* + Runs the parser and treats all + top level construct as statements + *) + let runStmt input source term parser = + {parser with + T.Input = ref input + T.Lines = source + } |> stmtList term + +(* + Example parser for a very simple grammar +*) + +//AST Types +type UnaryOp + = Plus + | Minus + +type BinaryOp + = Multiply + | Add + | Subtract + | Divide + | Assign + | Equals + +type Ast + = Number of int + | Identifier of string + | String of string + | Binary of BinaryOp * Ast * Ast + | Unary of UnaryOp * Ast + | Ternary of Ast * Ast * Ast // test * ifTrue * ifFalse + | If of Ast * Ast * Ast option // test + ifTrue and possibly ifFalse (else branch) + | Call of Ast * Ast list // target + arguments list + | Block of Ast list // statements list + | True + | False + +//Shorthand types for convenience +module P = Parser +type Token = string * string * (Parser.Pos) +type P = Parser.T + +//Utility functions for extracting values out of Token +let type' ((t, _, _):Token) = t +let value ((_, v, _):Token) = v +let pos ((_, _, p):Token) = p +let value_num (t:Token) = t |> value |> int + +//Utility functions for creating new tokens +let number value pos : Token = "#number", value, pos +let string value pos : Token = "#string", value, pos +let identifier name pos : Token = "#identifier", name, pos + +let symbol type' pos : Token = type', "", pos +let add = symbol "+" +let sub = symbol "-" +let mul = symbol "*" +let div = symbol "/" +let assign = symbol "=" +let equals = symbol "==" +let lparen = symbol "(" +let rparen = symbol ")" +let lbrace = symbol "{" +let rbrace = symbol "}" +let comma = symbol "," +let qmark = symbol "?" +let colon = symbol ":" +let scolon = symbol ";" +let if' = symbol "if" +let true' = symbol "true" +let else' = symbol "else" + +//Utility functions for converting tokens to binary and unary operators +let toBinaryOp tok = + match type' tok with + | "=" -> BinaryOp.Assign + | "+" -> BinaryOp.Add + | "-" -> BinaryOp.Subtract + | "*" -> BinaryOp.Multiply + | "/" -> BinaryOp.Divide + | "==" -> BinaryOp.Equals + | _ -> P.exn (sprintf "Couldn't convert %s-token to BinaryOp" (type' tok)) + +let toUnaryOp tok = + match type' tok with + | "+" -> UnaryOp.Plus + | "-" -> UnaryOp.Minus + | _ -> P.exn (sprintf "Couldn't convert %s-token to UnaryOp" (type' tok)) + +//Utility function for defining infix operators +let infix = + P.infix (fun token left right -> + Binary(token |> toBinaryOp, left, right)) + +//Utility function for defining prefix operators +let prefix = + P.prefix (fun token ast -> + Unary(token |> toUnaryOp, ast)) + +//Utility function for defining constants +let constant typ value p = + p |> P.nud typ (fun _ _ -> value) + +//Utility function for parsing a block +let block p = + let rec stmts p = + match p |> P.currentTypeTry with + | None -> [] + | Some "}" -> p |> P.skip; [] + | _ -> (p |> P.stmt ";") :: (stmts p) + + p |> P.skipIf "{" + Block(p |> stmts) + +//Pretty printing function for error messages +let prettyPrint (tok:Token) = + match tok with + | "#number", value, _ -> sprintf "#number %s" value + | "#identifier", name, _ -> sprintf "#identifier %s" name + | "#string", value, _ -> sprintf "#string \"%s\"" value + | type', _, _ -> type' + +//The parser definition +let example_parser = + (P.create type' pos (Some prettyPrint)) + + //Literals and identifiers + |> P.nud "#number" (fun t _ -> t |> value |> int |> Number) + |> P.nud "#identifier" (fun t _ -> t |> value |> Identifier) + |> P.nud "#string" (fun t _ -> t |> value |> String) + + //Constants + |> constant "true" Ast.True + |> constant "false" Ast.False + + //Infix Operators + |> infix "==" 40 + |> infix "+" 50 + |> infix "-" 50 + |> infix "*" 60 + |> infix "/" 60 + |> infix "=" 80 + + //Prefix Operators + |> prefix "+" 70 + |> prefix "-" 70 + + //Grouping expressions () + |> P.nud "(" (fun t p -> p |> P.exprSkip ")") + + //Ternary operator ? : + |> P.bpw "?" 70 + |> P.led "?" (fun _ left p -> + let ternary = [P.Get P.expr; P.Sym ":"; P.Get P.expr] + match p |> P.match' ternary with + | ifTrue::ifFalse::_ -> Ternary(left, ifTrue, ifFalse) + | _ -> P.matchError() + ) + + //If/Else statement if() { }] + |> P.smd "if" (fun _ p -> + let if' = [P.Sym "("; P.Get P.expr; P.Sym ")"; P.Get block] + let else' = [P.Sym "else"; P.Get block] + + match p |> P.match' if' with + | test::ifTrue::_ -> + match p |> P.match' else' with + | ifFalse::_ -> If(test, ifTrue, Some(ifFalse)) + | _ -> If(test, ifTrue, None) + | _ -> P.matchError() + ) + + //Function call + |> P.bpw "(" 80 + |> P.led "(" (fun _ func p -> + let rec args (p:P) = + match p |> P.currentType with + | ")" -> p |> P.skip; [] + | "," -> p |> P.skip; args p + | _ -> (p |> P.expr) :: args p + + Call(func, args p) + ) + +//Code to parse +(* +1: x = 5; +2: y = 5; +3: +4: if(x == y) { +5: print("x equals y"); +6: } else { +7: print("x doesn't equal y"); +8: } +*) + +let code = @"x = 5; +y = 5; + +if(x == y) { + print('x equals y'); +} else { + print('x doesn't equal y'); +}" + +//The code in tokens, manually entered +//since we don't have a lexer to produce +//the tokens for us +let tokens = + [ + //x = 5; + identifier "x" (1, 1) + assign (1, 3) + number "5" (1, 5) + scolon (1, 6) + + //y = 5; + identifier "y" (2, 1) + assign (2, 3) + number "5" (2, 5) + scolon (2, 6) + + //if(x == y) { + if' (4, 1) + lparen (4, 3) + identifier "x" (4, 4) + equals (4, 6) + identifier "y" (4, 9) + rparen (4, 10) + lbrace (4, 12) + + //print("x equals y"); + identifier "print" (5, 3) + lparen (5, 8) + string "x equals y" (5, 9) + rparen (5, 21) + scolon (5, 22) + + //} else { + rbrace (6, 1) + else' (6, 3) + lbrace (6, 7) + + //print("x doesn't equal y"); + identifier "print" (7, 3) + lparen (7, 7) + string "x doesn't equal y" (7, 9) + rparen (7, 27) + scolon (7, 28) + + //} + rbrace (8, 1) + ] + +let ast = example_parser |> P.runStmt tokens (Some code) ";" diff --git a/tests/benchmarks/BenchmarkComparison/run.fsproj b/tests/benchmarks/BenchmarkComparison/run.fsproj new file mode 100644 index 00000000000..7bae666b94c --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/run.fsproj @@ -0,0 +1,23 @@ + + + + Exe + net6 + true + Release + + + + true + true + + + + + + + + + + + diff --git a/tests/benchmarks/BenchmarkComparison/run_current.fsproj b/tests/benchmarks/BenchmarkComparison/run_current.fsproj new file mode 100644 index 00000000000..7f417d9a002 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/run_current.fsproj @@ -0,0 +1,23 @@ + + + + Exe + net6 + true + Release + + + + true + true + + + + + + + + + + + diff --git a/tests/benchmarks/BenchmarkComparison/runner.ipynb b/tests/benchmarks/BenchmarkComparison/runner.ipynb new file mode 100644 index 00000000000..bda88e2e313 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/runner.ipynb @@ -0,0 +1,235 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "source": [ + "#r \"nuget: Plotly.NET, 2.0.0-preview.6\"\r\n", + "#r \"nuget: Plotly.NET.Interactive, 2.0.0-preview.6\"\r\n", + "#r \"nuget: Microsoft.Data.Analysis, 0.18.0\"\r\n", + "\r\n", + "open System.IO\r\n", + "open System.Diagnostics\r\n", + "open Microsoft.Data.Analysis\r\n", + "open Plotly.NET\r\n", + "\r\n", + "let parseMilliseconds (str: string) =\r\n", + " if str.Contains(\" ms\") then\r\n", + " Single.Parse(str.Replace(\" ms\", \"\"))\r\n", + " elif str.Contains(\" s\") then\r\n", + " Single.Parse(str.Replace(\" s\", \"\")) * 1000.f\r\n", + " else\r\n", + " failwith \"Invalid string\"\r\n", + "\r\n", + "let parseAllocated (str: string) =\r\n", + " if str.Contains(\" MB\") then\r\n", + " Single.Parse(str.Replace(\" MB\", \"\"))\r\n", + " elif str.Contains(\" KB\") then\r\n", + " Single.Parse(str.Replace(\" KB\", \"\")) / 1024.f\r\n", + " else\r\n", + " failwith \"Invalid string\"\r\n", + "\r\n", + "let run name args workingDir =\r\n", + " let info = ProcessStartInfo()\r\n", + " info.WindowStyle <- ProcessWindowStyle.Hidden\r\n", + " info.Arguments <- args\r\n", + " info.FileName <- name\r\n", + " info.UseShellExecute <- false\r\n", + " info.WorkingDirectory <- workingDir\r\n", + " info.RedirectStandardError <- true\r\n", + " info.RedirectStandardOutput <- true\r\n", + " info.RedirectStandardInput <- true\r\n", + " info.CreateNoWindow <- true\r\n", + " let p = Process.Start(info)\r\n", + " p.WaitForExit()\r\n", + " let errors = p.StandardError.ReadToEnd()\r\n", + " p.StandardOutput.ReadToEnd() |> ignore\r\n", + " p.WaitForExit()\r\n", + " if p.ExitCode <> 0 then\r\n", + " failwith $\"Process {name} {args} failed: {errors}.\"\r\n", + "\r\n", + "let resultsPath = Path.Combine(__SOURCE_DIRECTORY__, \"BenchmarkDotNet.Artifacts\\\\results\\\\BenchmarkComparison.TypeCheckingBenchmark1-report.csv\")\r\n", + "\r\n", + "let benchmarkCurrent(): string * DataFrame =\r\n", + " printfn \"Benchmarking Current (Today)...\"\r\n", + " run \"dotnet\" \"run -c Release --project run_current.fsproj\" __SOURCE_DIRECTORY__\r\n", + " let df = DataFrame.LoadCsv(resultsPath)\r\n", + " printfn \"Current (Today) Done\"\r\n", + " (\"Current (Today)\", df)\r\n", + "\r\n", + "let benchmarkVersion (name: string) (version: string) (constants: string): string * DataFrame =\r\n", + " try File.Delete(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\")) with | _ -> ()\r\n", + " try\r\n", + " printfn $\"Benchmarking {name}...\"\r\n", + " let setupTemplate = File.ReadAllText(Path.Combine(__SOURCE_DIRECTORY__, \"setup_version_template.fsproj\"))\r\n", + " let setup = setupTemplate.Replace(\"{TEMPLATE_FCS_VERSION}\", version).Replace(\"{TEMPLATE_DEFINE_CONSTANTS}\", constants)\r\n", + " File.WriteAllText(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\"), setup)\r\n", + " run \"dotnet\" \"run -c Release --project run.fsproj\" __SOURCE_DIRECTORY__\r\n", + "\r\n", + " let df = DataFrame.LoadCsv(resultsPath)\r\n", + " printfn $\"{name} Done\"\r\n", + " (name, df)\r\n", + " finally\r\n", + " try File.Delete(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\")) with | _ -> ()\r\n", + "\r\n", + "let benchmarkCommit (commitHash: string) (constants: string): string * DataFrame =\r\n", + " try File.Delete(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\")) with | _ -> ()\r\n", + " let tmp = Path.GetTempFileName()\r\n", + " try File.Delete(tmp) with | _ -> ()\r\n", + " let tmpDir = Path.Combine(Path.GetDirectoryName(tmp), Path.GetFileNameWithoutExtension(tmp))\r\n", + " Directory.CreateDirectory(tmpDir) |> ignore\r\n", + "\r\n", + " try\r\n", + " let fcsOutputPath = Path.Combine(tmpDir, \"artifacts/bin/FSharp.Compiler.Service/Release/netstandard2.0/FSharp.Compiler.Service.dll\")\r\n", + " printfn $\"Cloning 'dotnet/fsharp.git' in '{tmpDir}'...\"\r\n", + " run \"git\" $\"clone https://github.com/dotnet/fsharp.git {tmpDir}\" __SOURCE_DIRECTORY__\r\n", + " printfn $\"Switching to '{commitHash}'...\"\r\n", + " run \"git\" $\"reset --hard {commitHash}\" tmpDir\r\n", + " printfn \"Building fsharp...\"\r\n", + " run \"cmd\" \"/C build.cmd -c Release\" tmpDir\r\n", + " \r\n", + " printfn $\"Benchmarking {commitHash}...\"\r\n", + " let setupTemplate = File.ReadAllText(Path.Combine(__SOURCE_DIRECTORY__, \"setup_commit_template.fsproj\"))\r\n", + " let setup = setupTemplate.Replace(\"{TEMPLATE_FCS_PATH}\", fcsOutputPath).Replace(\"{TEMPLATE_DEFINE_CONSTANTS}\", constants)\r\n", + " File.WriteAllText(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\"), setup)\r\n", + " run \"dotnet\" \"run -c Release --project run.fsproj\" __SOURCE_DIRECTORY__\r\n", + "\r\n", + " let df = DataFrame.LoadCsv(resultsPath)\r\n", + " printfn $\"{commitHash} Done\"\r\n", + " (commitHash, df)\r\n", + " finally\r\n", + " try File.Delete(Path.Combine(__SOURCE_DIRECTORY__, \"setup.fsproj\")) with | _ -> ()\r\n", + " try Directory.Delete(tmpDir) with | _ -> ()" + ], + "outputs": [ + { + "data": { + "text/html": [ + "
Installed Packages
  • Microsoft.Data.Analysis, 0.18.0
  • Plotly.NET, 2.0.0-preview.6
  • Plotly.NET.Interactive, 2.0.0-preview.6
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "let benchmarkData =\r\n", + " [\r\n", + " // Note: SERVICE_30_0_0 and SERVICE_13_0_0 refer to define constants in order to build the benchmark on older versions.\r\n", + " benchmarkCurrent()\r\n", + " //benchmarkCommit doesn't fully work yet\r\n", + " //benchmarkCommit \"81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa\" \"\"\r\n", + " //benchmarkCommit \"1d36c75225436f8a7d30c4691f20d6118b657fec\" \"\"\r\n", + " //benchmarkCommit \"2e4096153972abedae142da85cac2ffbcf57fe0a\" \"\"\r\n", + " //benchmarkCommit \"af6ff33b5bc15951a6854bdf3b226db8f0e28b56\" \"\"\r\n", + " benchmarkVersion \"40.0.0 (6/22/2021)\" \"40.0.0\" \"\"\r\n", + " benchmarkVersion \"35.0.0 (4/10/2020)\" \"35.0.0\" \"SERVICE_30_0_0\"\r\n", + " benchmarkVersion \"30.0.0 (6/29/2019)\" \"30.0.0\" \"SERVICE_30_0_0\"\r\n", + " benchmarkVersion \"25.0.1 (9/5/2018)\" \"25.0.1\" \"SERVICE_13_0_0\"\r\n", + " benchmarkVersion \"20.0.1 (2/21/2018)\" \"20.0.1\" \"SERVICE_13_0_0\"\r\n", + " benchmarkVersion \"13.0.0 (6/28/2017)\" \"13.0.0\" \"SERVICE_13_0_0\"\r\n", + " ]" + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Cloning 'dotnet/fsharp.git' in 'C:\\Users\\lolti\\AppData\\Local\\Temp\\tmp286'...\r\n", + "Switching to '81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa'...\r\n", + "Building fsharp...\r\n" + ] + }, + { + "output_type": "error", + "ename": "Error", + "evalue": "System.OperationCanceledException: Command :SubmitCode: let benchmarkData =\r\n [\r\n // Note: SERVI ... cancelled.", + "traceback": [ + "System.OperationCanceledException: Command :SubmitCode: let benchmarkData =\r\n", + " [\r\n", + " // Note: SERVI ... cancelled." + ] + } + ], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "// Data cleanup\r\n", + "\r\n", + "let df =\r\n", + " (benchmarkData.[0] |> snd, benchmarkData.[1..])\r\n", + " ||> List.fold (fun df (_, df2) ->\r\n", + " df.Append(df2.Rows)\r\n", + " )\r\n", + "\r\n", + "let x =\r\n", + " benchmarkData\r\n", + " |> List.map (fun (name, _) -> name)\r\n", + "\r\n", + "let meanColumn = df.Columns.[\"Mean\"]\r\n", + "let allocatedColumn = df.Columns.[\"Allocated\"]\r\n", + "\r\n", + "let y1 =\r\n", + " [\r\n", + " for i = 0L to meanColumn.Length - 1L do\r\n", + " meanColumn.[i] :?> string\r\n", + " |> parseMilliseconds\r\n", + " ]\r\n", + "let meanData = (x, y1) ||> List.zip |> List.rev\r\n", + "let y2 =\r\n", + " [\r\n", + " for i = 0L to allocatedColumn.Length - 1L do\r\n", + " allocatedColumn.[i] :?> string\r\n", + " |> parseAllocated\r\n", + " ]\r\n", + "let allocatedData = (x, y2) ||> List.zip |> List.rev\r\n", + "\r\n", + "// Charts\r\n", + "\r\n", + "let meanLine = Chart.Line(meanData, Name=\"Mean (ms)\")\r\n", + "let allocatedLine = Chart.Line(allocatedData, Name=\"Allocated (MB)\")\r\n", + "\r\n", + "Chart.Combine([meanLine;allocatedLine])" + ], + "outputs": [], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + } + ], + "metadata": { + "orig_nbformat": 4, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/x-csharp", + "name": "C#", + "pygments_lexer": "csharp", + "version": "9.0" + }, + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/benchmarks/BenchmarkComparison/setup_commit_template.fsproj b/tests/benchmarks/BenchmarkComparison/setup_commit_template.fsproj new file mode 100644 index 00000000000..b0332e6b1c8 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/setup_commit_template.fsproj @@ -0,0 +1,27 @@ + + + + net6 + true + Release + {TEMPLATE_DEFINE_CONSTANTS} + + + + true + true + + + + + + + + + + + {TEMPLATE_FCS_PATH} + + + + diff --git a/tests/benchmarks/BenchmarkComparison/setup_current.fsproj b/tests/benchmarks/BenchmarkComparison/setup_current.fsproj new file mode 100644 index 00000000000..7c8f131da60 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/setup_current.fsproj @@ -0,0 +1,25 @@ + + + + net6 + true + Release + {TEMPLATE_DEFINE_CONSTANTS} + + + + true + true + + + + + + + + + + + + + diff --git a/tests/benchmarks/BenchmarkComparison/setup_version_template.fsproj b/tests/benchmarks/BenchmarkComparison/setup_version_template.fsproj new file mode 100644 index 00000000000..41f345df095 --- /dev/null +++ b/tests/benchmarks/BenchmarkComparison/setup_version_template.fsproj @@ -0,0 +1,25 @@ + + + + net6 + true + Release + {TEMPLATE_DEFINE_CONSTANTS} + + + + true + true + + + + + + + + + + + + + diff --git a/tests/benchmarks/CompilerServiceBenchmarks/Benchmarks.fs b/tests/benchmarks/CompilerServiceBenchmarks/Benchmarks.fs new file mode 100644 index 00000000000..434d6870bd3 --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/Benchmarks.fs @@ -0,0 +1,387 @@ +namespace FSharp.Compiler.Benchmarks + +open System +open System.IO +open System.Text +open System.Threading.Tasks +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Running +open FSharp.Compiler.Benchmarks + +[] +module BenchmarkHelpers = + + type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + + let createProject name referencedProjects = + let tmpPath = Path.GetTempPath() + let file = Path.Combine(tmpPath, Path.ChangeExtension(name, ".fs")) + { + ProjectFileName = Path.Combine(tmpPath, Path.ChangeExtension(name, ".dll")) + ProjectId = None + SourceFiles = [|file|] + OtherOptions = + Array.append [|"--optimize+"; "--target:library" |] (referencedProjects |> Array.ofList |> Array.map (fun x -> "-r:" + x.ProjectFileName)) + ReferencedProjects = + referencedProjects + |> List.map (fun x -> FSharpReferencedProject.CreateFSharp (x.ProjectFileName, x)) + |> Array.ofList + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false + LoadTime = DateTime() + UnresolvedReferences = None + OriginalLoadReferences = [] + Stamp = Some 0L (* set the stamp to 0L on each run so we don't evaluate the whole project again *) + } + + let generateSourceCode moduleName = + sprintf """ +module Benchmark.%s + +type %s = + + val X : int + + val Y : int + + val Z : int + +let function%s (x: %s) = + let x = 1 + let y = 2 + let z = x + y + z""" moduleName moduleName moduleName moduleName + + let decentlySizedStandAloneFile = File.ReadAllText(Path.Combine(__SOURCE_DIRECTORY__, "decentlySizedStandAloneFile.fsx")) + +[] +type TypeCheckingBenchmark1() = + let mutable checkerOpt = None + let mutable assembliesOpt = None + let mutable testFileOpt = None + + let parsingOptions = + { + SourceFiles = [|"decentlySizedStandAloneFile.fsx"|] + ConditionalCompilationDefines = [] + ErrorSeverityOptions = FSharpDiagnosticOptions.Default + LangVersionText = "default" + IsInteractive = false + LightSyntax = None + CompilingFsLib = false + IsExe = false + } + + [] + member __.Setup() = + match checkerOpt with + | None -> checkerOpt <- Some(FSharpChecker.Create(projectCacheSize = 200)) + | _ -> () + + match assembliesOpt with + | None -> + assembliesOpt <- + System.AppDomain.CurrentDomain.GetAssemblies() + |> Array.map (fun x -> (x.Location)) + |> Some + + | _ -> () + + match testFileOpt with + | None -> + let options, _ = + checkerOpt.Value.GetProjectOptionsFromScript("decentlySizedStandAloneFile.fsx", SourceText.ofString decentlySizedStandAloneFile) + |> Async.RunImmediate + testFileOpt <- Some options + | _ -> () + + [] + member __.Run() = + match checkerOpt, testFileOpt with + | None, _ -> failwith "no checker" + | _, None -> failwith "no test file" + | Some(checker), Some(options) -> + let _, result = + checker.ParseAndCheckFileInProject("decentlySizedStandAloneFile.fsx", 0, SourceText.ofString decentlySizedStandAloneFile, options) + |> Async.RunImmediate + match result with + | FSharpCheckFileAnswer.Aborted -> failwith "checker aborted" + | FSharpCheckFileAnswer.Succeeded results -> + if results.Diagnostics.Length > 0 then failwithf "had errors: %A" results.Diagnostics + + [] + member __.Cleanup() = + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + ClearAllILModuleReaderCache() + +module Test = + let inline f x y = x + y + + + +[] +type CompilerService() = + let mutable checkerOpt = None + let mutable sourceOpt = None + let mutable assembliesOpt = None + let mutable decentlySizedStandAloneFileCheckResultOpt = None + + let parsingOptions = + { + SourceFiles = [|"CheckExpressions.fs"|] + ConditionalCompilationDefines = [] + ErrorSeverityOptions = FSharpDiagnosticOptions.Default + LangVersionText = "default" + IsInteractive = false + LightSyntax = None + CompilingFsLib = false + IsExe = false + } + + let readerOptions = + { + pdbDirPath = None + reduceMemoryUsage = ReduceMemoryFlag.No + metadataOnly = MetadataOnlyFlag.Yes + tryGetMetadataSnapshot = fun _ -> None + } + + [] + member __.Setup() = + match checkerOpt with + | None -> checkerOpt <- Some(FSharpChecker.Create(projectCacheSize = 200)) + | _ -> () + + match sourceOpt with + | None -> + sourceOpt <- Some <| FSharpSourceText.From(File.OpenRead("""..\..\..\..\..\..\..\..\..\src\fsharp\CheckExpressions.fs"""), Encoding.Default, FSharpSourceHashAlgorithm.Sha1, true) + | _ -> () + + match assembliesOpt with + | None -> + assembliesOpt <- + System.AppDomain.CurrentDomain.GetAssemblies() + |> Array.map (fun x -> (x.Location)) + |> Some + + | _ -> () + + match decentlySizedStandAloneFileCheckResultOpt with + | None -> + let options, _ = + checkerOpt.Value.GetProjectOptionsFromScript("decentlySizedStandAloneFile.fsx", SourceText.ofString decentlySizedStandAloneFile) + |> Async.RunImmediate + let _, checkResult = + checkerOpt.Value.ParseAndCheckFileInProject("decentlySizedStandAloneFile.fsx", 0, SourceText.ofString decentlySizedStandAloneFile, options) + |> Async.RunImmediate + decentlySizedStandAloneFileCheckResultOpt <- Some checkResult + | _ -> () + + [] + member __.ParsingTypeCheckerFs() = + match checkerOpt, sourceOpt with + | None, _ -> failwith "no checker" + | _, None -> failwith "no source" + | Some(checker), Some(source) -> + let results = checker.ParseFile("CheckExpressions.fs", source.ToFSharpSourceText(), parsingOptions) |> Async.RunImmediate + if results.ParseHadErrors then failwithf "parse had errors: %A" results.Diagnostics + + [] + member __.ParsingTypeCheckerFsSetup() = + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + checker.ParseFile("dummy.fs", SourceText.ofString "dummy", parsingOptions) |> Async.RunImmediate |> ignore + ClearAllILModuleReaderCache() + + [] + member __.ILReading() = + match assembliesOpt with + | None -> failwith "no assemblies" + | Some(assemblies) -> + // We try to read most of everything in the assembly that matter, mainly types with their properties, methods, and fields. + // CustomAttrs and SecurityDecls are lazy until you call them, so we call them here for benchmarking. + assemblies + |> Array.iter (fun (fileName) -> + let reader = OpenILModuleReader fileName readerOptions + + let ilModuleDef = reader.ILModuleDef + + let ilAssemblyManifest = ilModuleDef.Manifest.Value + + ilAssemblyManifest.CustomAttrs |> ignore + ilAssemblyManifest.SecurityDecls |> ignore + ilAssemblyManifest.ExportedTypes.AsList + |> List.iter (fun x -> + x.CustomAttrs |> ignore + ) + + ilModuleDef.CustomAttrs |> ignore + ilModuleDef.TypeDefs.AsArray + |> Array.iter (fun ilTypeDef -> + ilTypeDef.CustomAttrs |> ignore + ilTypeDef.SecurityDecls |> ignore + + ilTypeDef.Methods.AsArray + |> Array.iter (fun ilMethodDef -> + ilMethodDef.CustomAttrs |> ignore + ilMethodDef.SecurityDecls |> ignore + ) + + ilTypeDef.Fields.AsList + |> List.iter (fun ilFieldDef -> + ilFieldDef.CustomAttrs |> ignore + ) + + ilTypeDef.Properties.AsList + |> List.iter (fun ilPropertyDef -> + ilPropertyDef.CustomAttrs |> ignore + ) + ) + ) + + [] + member __.ILReadingSetup() = + // With caching, performance increases an order of magnitude when re-reading an ILModuleReader. + // Clear it for benchmarking. + ClearAllILModuleReaderCache() + + member val TypeCheckFileWith100ReferencedProjectsOptions = + createProject "MainProject" + [ for i = 1 to 100 do + yield + createProject ("ReferencedProject" + string i) [] + ] + + member this.TypeCheckFileWith100ReferencedProjectsRun() = + let options = this.TypeCheckFileWith100ReferencedProjectsOptions + let file = options.SourceFiles.[0] + + match checkerOpt with + | None -> failwith "no checker" + | Some checker -> + let parseResult, checkResult = + checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString (File.ReadAllText(file)), options) + |> Async.RunImmediate + + if parseResult.Diagnostics.Length > 0 then + failwithf "%A" parseResult.Diagnostics + + match checkResult with + | FSharpCheckFileAnswer.Aborted -> failwith "aborted" + | FSharpCheckFileAnswer.Succeeded checkFileResult -> + + if checkFileResult.Diagnostics.Length > 0 then + failwithf "%A" checkFileResult.Diagnostics + + [] + member this.TypeCheckFileWith100ReferencedProjectsSetup() = + this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles + |> Seq.iter (fun file -> + File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) + ) + + this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects + |> Seq.iter (function + | FSharpReferencedProject.FSharpReference(_, referencedProjectOptions) -> + referencedProjectOptions.SourceFiles + |> Seq.iter (fun file -> + File.WriteAllText(file, generateSourceCode (Path.GetFileNameWithoutExtension(file))) + ) + | _ -> () + ) + + this.TypeCheckFileWith100ReferencedProjectsRun() + + [] + member this.TypeCheckFileWith100ReferencedProjects() = + // Because the checker's projectcachesize is set to 200, this should be fast. + // If set to 3, it will be almost as slow as re-evaluating all project and it's projects references on setup; this could be a bug or not what we want. + this.TypeCheckFileWith100ReferencedProjectsRun() + + member val TypeCheckFileWithNoReferencesOptions = createProject "MainProject" [] + + [] + member this.TypeCheckFileWith100ReferencedProjectsCleanup() = + this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles + |> Seq.iter (fun file -> + try File.Delete(file) with | _ -> () + ) + + this.TypeCheckFileWith100ReferencedProjectsOptions.ReferencedProjects + |> Seq.iter (function + | FSharpReferencedProject.FSharpReference(_, referencedProjectOptions) -> + referencedProjectOptions.SourceFiles + |> Seq.iter (fun file -> + try File.Delete(file) with | _ -> () + ) + | _ -> () + ) + + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + ClearAllILModuleReaderCache() + + [] + member this.SimplifyNames() = + match decentlySizedStandAloneFileCheckResultOpt with + | Some checkResult -> + match checkResult with + | FSharpCheckFileAnswer.Aborted -> failwith "checker aborted" + | FSharpCheckFileAnswer.Succeeded results -> + let sourceLines = decentlySizedStandAloneFile.Split ([|"\r\n"; "\n"; "\r"|], StringSplitOptions.None) + let ranges = SimplifyNames.getSimplifiableNames(results, fun lineNum -> sourceLines.[Line.toZ lineNum]) |> Async.RunImmediate + ignore ranges + () + | _ -> failwith "oopsie" + + [] + member this.UnusedOpens() = + match decentlySizedStandAloneFileCheckResultOpt with + | Some checkResult -> + match checkResult with + | FSharpCheckFileAnswer.Aborted -> failwith "checker aborted" + | FSharpCheckFileAnswer.Succeeded results -> + let sourceLines = decentlySizedStandAloneFile.Split ([|"\r\n"; "\n"; "\r"|], StringSplitOptions.None) + let decls = UnusedOpens.getUnusedOpens(results, fun lineNum -> sourceLines.[Line.toZ lineNum]) |> Async.RunImmediate + ignore decls + () + | _ -> failwith "oopsie" + + [] + member this.UnusedDeclarations() = + match decentlySizedStandAloneFileCheckResultOpt with + | Some checkResult -> + match checkResult with + | FSharpCheckFileAnswer.Aborted -> failwith "checker aborted" + | FSharpCheckFileAnswer.Succeeded results -> + let decls = UnusedDeclarations.getUnusedDeclarations(results, true) |> Async.RunImmediate + ignore decls // should be 16 + () + | _ -> failwith "oopsie" \ No newline at end of file diff --git a/tests/benchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj b/tests/benchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj new file mode 100644 index 00000000000..68b175fc21a --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj @@ -0,0 +1,26 @@ + + + + Exe + net5.0 + true + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/CompilerServiceBenchmarks/Helpers.fs b/tests/benchmarks/CompilerServiceBenchmarks/Helpers.fs new file mode 100644 index 00000000000..21952786f1c --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/Helpers.fs @@ -0,0 +1,116 @@ +[] +module internal FSharp.Compiler.Benchmarks.Helpers + +open System +open System.IO +open System.Threading.Tasks +open Microsoft.CodeAnalysis.Text +open FSharp.Compiler.Text +open FSharp.Compiler.CodeAnalysis + +module private SourceText = + + open System.Runtime.CompilerServices + + let weakTable = ConditionalWeakTable() + + let create (sourceText: SourceText) = + + let sourceText = + { new ISourceText with + + member __.Item with get index = sourceText.[index] + + member __.GetLineString(lineIndex) = + sourceText.Lines.[lineIndex].ToString() + + member __.GetLineCount() = + sourceText.Lines.Count + + member __.GetLastCharacterPosition() = + if sourceText.Lines.Count > 0 then + (sourceText.Lines.Count, sourceText.Lines.[sourceText.Lines.Count - 1].Span.Length) + else + (0, 0) + + member __.GetSubTextString(start, length) = + sourceText.GetSubText(TextSpan(start, length)).ToString() + + member __.SubTextEquals(target, startIndex) = + if startIndex < 0 || startIndex >= sourceText.Length then + raise (ArgumentOutOfRangeException("startIndex")) + + if String.IsNullOrEmpty(target) then + raise (ArgumentException("Target is null or empty.", "target")) + + let lastIndex = startIndex + target.Length + if lastIndex <= startIndex || lastIndex >= sourceText.Length then + raise (ArgumentException("Target is too big.", "target")) + + let mutable finished = false + let mutable didEqual = true + let mutable i = 0 + while not finished && i < target.Length do + if target.[i] <> sourceText.[startIndex + i] then + didEqual <- false + finished <- true // bail out early + else + i <- i + 1 + + didEqual + + member __.ContentEquals(sourceText) = + match sourceText with + | :? SourceText as sourceText -> sourceText.ContentEquals(sourceText) + | _ -> false + + member __.Length = sourceText.Length + + member __.CopyTo(sourceIndex, destination, destinationIndex, count) = + sourceText.CopyTo(sourceIndex, destination, destinationIndex, count) + } + + sourceText + +type SourceText with + + member this.ToFSharpSourceText() = + SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create)) + +type FSharpSourceText = SourceText +type FSharpSourceHashAlgorithm = SourceHashAlgorithm + +type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + +let CreateProject name referencedProjects = + let tmpPath = Path.GetTempPath() + let file = Path.Combine(tmpPath, Path.ChangeExtension(name, ".fs")) + { + ProjectFileName = Path.Combine(tmpPath, Path.ChangeExtension(name, ".dll")) + ProjectId = None + SourceFiles = [|file|] + OtherOptions = + Array.append [|"--optimize+"; "--target:library" |] (referencedProjects |> Array.ofList |> Array.map (fun x -> "-r:" + x.ProjectFileName)) + ReferencedProjects = + referencedProjects + |> List.map (fun x -> FSharpReferencedProject.CreateFSharp (x.ProjectFileName, x)) + |> Array.ofList + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false + LoadTime = DateTime() + UnresolvedReferences = None + OriginalLoadReferences = [] + Stamp = Some 0L (* set the stamp to 0L on each run so we don't evaluate the whole project again *) + } + diff --git a/tests/benchmarks/CompilerServiceBenchmarks/Program.fs b/tests/benchmarks/CompilerServiceBenchmarks/Program.fs new file mode 100644 index 00000000000..d624def2d8c --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/Program.fs @@ -0,0 +1,8 @@ +open BenchmarkDotNet.Running +open FSharp.Compiler.Benchmarks + +[] +let main _ = + //BenchmarkRunner.Run() |> ignore + BenchmarkRunner.Run() |> ignore + 0 diff --git a/tests/benchmarks/CompilerServiceBenchmarks/benchmarks.ipynb b/tests/benchmarks/CompilerServiceBenchmarks/benchmarks.ipynb new file mode 100644 index 00000000000..cbf5270689c --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/benchmarks.ipynb @@ -0,0 +1,154 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "source": [ + "#!pwsh\r\n", + "dotnet build -c release\r\n" + ], + "outputs": [], + "metadata": { + "dotnet_interactive": { + "language": "pwsh" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "#r \"../../../artifacts/bin/FSharp.Compiler.Benchmarks/Release/net5.0/FSharp.Compiler.Benchmarks.dll\"\r\n", + "#r \"../../../artifacts/bin/FSharp.Compiler.Benchmarks/Release/net5.0/BenchmarkDotNet.dll\"" + ], + "outputs": [], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "open BenchmarkDotNet.Running\r\n", + "open FSharp.Compiler.Benchmarks\r\n", + "\r\n", + "let summary = BenchmarkRunner.Run()" + ], + "outputs": [], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "// https://benchmarkdotnet.org/api/BenchmarkDotNet.Reports.BenchmarkReport.html\r\n", + "#r \"nuget: XPlot.Plotly.Interactive, 4.0.2\"\r\n", + "\r\n", + "open XPlot.Plotly\r\n", + "\r\n", + "let gcStats = summary.Reports |> Seq.map (fun x -> x.GcStats)\r\n", + "\r\n", + "let gen0Series =\r\n", + " Bar(\r\n", + " name = \"Gen 0\",\r\n", + " y = (gcStats |> Seq.map (fun x -> x.Gen0Collections))\r\n", + " )\r\n", + "\r\n", + "let gen1Series =\r\n", + " Bar(\r\n", + " name = \"Gen 1\",\r\n", + " y = (gcStats |> Seq.map (fun x -> x.Gen1Collections))\r\n", + " )\r\n", + "\r\n", + "let gen2Series =\r\n", + " Bar(\r\n", + " name = \"Gen 2\",\r\n", + " y = (gcStats |> Seq.map (fun x -> x.Gen2Collections))\r\n", + " )\r\n", + "\r\n", + "[gen0Series;gen1Series;gen2Series]\r\n", + "|> Chart.Plot\r\n", + "|> Chart.WithTitle(\"F# Type-Checking Benchmark 1 - GC Collection Counts\")" + ], + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\r\n", + "
\r\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "metadata": { + "dotnet_interactive": { + "language": "fsharp" + } + } + } + ], + "metadata": { + "orig_nbformat": 4, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/x-csharp", + "name": "C#", + "pygments_lexer": "csharp", + "version": "9.0" + }, + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/tests/benchmarks/CompilerServiceBenchmarks/decentlySizedStandAloneFile.fsx b/tests/benchmarks/CompilerServiceBenchmarks/decentlySizedStandAloneFile.fsx new file mode 100644 index 00000000000..95b2f151be6 --- /dev/null +++ b/tests/benchmarks/CompilerServiceBenchmarks/decentlySizedStandAloneFile.fsx @@ -0,0 +1,547 @@ +module Parser = + + (* + F# implementation of a generic Top-Down-Operator-Precedence Parser + as described in this paper http://portal.acm.org/citation.cfm?id=512931. + + The parser has been extended to allow for statements in comparison to Pratt's + original algorithm which only parsed languages which use expression-only grammar. + + The parsers is "impure" in the sense that is uses a ref-cell for storing the + input in the T<_, _, _> record class, this is soley for performance reasons + as it's to expensive to create a new record object for every consumed token. + Certain functions also throw exceptions, which generally also is considered impure. + + The parser produces nice error message in this style: + + Error on line: 5 col: 9 + 4: if(x == y) { + 5: print'x equals y'); + ----------^ + Unexpected: #string "x equals y" + + More information: + * http://en.wikipedia.org/wiki/Vaughan_Pratt (Original Inventor) + * http://en.wikipedia.org/wiki/Pratt_parser (Alias name) + * http://effbot.org/zone/simple-top-down-parsing.htm (Python implementation) + * http://javascript.crockford.com/tdop/tdop.html (JavaScript implementation) + *) + + type Pos = int * int + + type T<'a, 'b, 'c> when 'c : comparison = { + Input : 'a list ref + Lines : string option + + Type : 'a -> 'c + Position : 'a -> Pos + PrettyPrint : ('a -> string) option + + //Parser definitions and binding powers + BindingPower : Map<'c, int> + Null : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Stmt : Map<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Left : Map<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b> + } + + type Pattern<'a, 'b, 'c> when 'c : comparison + = Sym of 'c + | Get of (T<'a, 'b, 'c> -> 'b) + + //Errors + type Exn (msg, pos) = + inherit System.Exception(msg) + member x.Position = pos + + (* + Creates a string error snippet + that points out the exact source position + where the error occured, for example: + + 4: if(x == y) { + 5: print'x equals y'); + ----------^ + *) + let errorSource pos source = + + let splitLines (text:string) = + let text = text.Replace("\r\n", "\n").Replace("\r", "\n") + System.Text.RegularExpressions.Regex.Split(text, "\n") + + let lineNum (input:int) n = + (input.ToString()).PadLeft(n, '0') + + let stringRepeat n input = + if System.String.IsNullOrEmpty input then input + else + let result = new System.Text.StringBuilder(input.Length * n) + result.Insert(0, input, n).ToString() + + match source with + | None -> "" + | Some(source:string) -> + let source = source |> splitLines + let result = ref "" + let line, column = pos + + if line <= source.Length && line > 1 then + let nr = line.ToString() + let nrl = nr.Length + + //previous line + let pline = line - 1 + if pline >= 1 then + let num = lineNum pline nrl + result := num+": "+source.[pline-1]+"\n" + + //current line + let text = source.[line-1] + if column <= text.Length then + let arrow = "-" |> stringRepeat (nrl + column) + result := !result+nr+": "+text+"\n"+arrow+"^\n" + + !result + + let exn msg = Exn(msg, (0, 0)) |> raise + let exnLine pos msg = + let line = sprintf "Error on line: %i col: %i\n" (fst pos) (snd pos) + Exn(line + msg, pos) |> raise + + let private unexpectedEnd () = "Unexpected end of input" |> exn + let private unexpectedToken token parser = + let type' = + match parser.PrettyPrint with + | None -> (token |> parser.Type).ToString() + | Some f -> token |> f + + let pos = token |> parser.Position + let source = parser.Lines |> errorSource pos + let expected = sprintf "Unexpected: %s" type' + (source + expected) |> exnLine pos + + let inline private getBindingPower tok parser = + let pwr = parser.BindingPower.TryFind (parser.Type tok) + match pwr with Some pwr -> pwr | _ -> 0 + + let current parser = + match !parser.Input with + | token::_ -> token + | _ -> unexpectedEnd () + + let currentTry parser = + match !parser.Input with + | token::_ -> Some token + | _ -> None + + let currentType parser = + parser |> current |> parser.Type + + let currentTypeTry parser = + match parser |> currentTry with + | Some token -> Some(token |> parser.Type) + | _ -> None + + let skip parser = + match !parser.Input with + | _::input -> parser.Input := input + | _ -> unexpectedEnd () + + let skipIf type' parser = + match !parser.Input with + | token::xs when parser.Type token = type' -> + parser.Input := xs + + | token::_ -> + unexpectedToken token parser + + | _ -> unexpectedEnd () + + let skipCurrent parser = + let current = parser |> current + parser |> skip + current + + let exprPwr rbpw parser = + let rec expr left = + match parser |> currentTry with + | Some token when rbpw < (parser |> getBindingPower token) -> + parser |> skip + + let type' = parser.Type token + let led = + match parser.Left.TryFind type' with + | None -> unexpectedToken token parser + | Some led -> led + + led token left parser |> expr + + | _ -> left + + let tok = parser |> skipCurrent + let type' = parser.Type tok + let nud = + match parser.Null.TryFind type' with + | None -> unexpectedToken tok parser + | Some nud -> nud + + nud tok parser |> expr + + let expr parser = + parser |> exprPwr 0 + + let exprSkip type' parser = + let expr = parser |> expr + parser |> skipIf type' + expr + + let rec exprList parser = + match !parser.Input with + | [] -> [] + | _ -> (parser |> expr) :: (parser |> exprList) + + let stmt term parser = + let token = parser |> current + match parser.Stmt.TryFind (token |> parser.Type) with + | Some stmt -> parser |> skip; stmt token parser + | None -> parser |> exprSkip term + + let rec stmtList term parser = + match !parser.Input with + | [] -> [] + | _ -> (parser |> stmt term) :: (parser |> stmtList term) + + let match' pattern parser = + let rec match' acc pattern parser = + match pattern with + | [] -> acc |> List.rev + + | Sym(symbol)::pattern -> + parser |> skipIf symbol + parser |> match' acc pattern + + | Get(f)::pattern -> + let acc = (f parser) :: acc + parser |> match' acc pattern + + parser |> match' [] pattern + + (* + Convenience functions exposed for + easing parser definition and usage + *) + + let create<'a, 'b, 'c when 'c : comparison> type' position prettyPrint = { + Input = ref [] + Lines = None + + Type = type' + Position = position + PrettyPrint = prettyPrint + + BindingPower = Map.empty<'c, int> + Null = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Stmt = Map.empty<'c, 'a -> T<'a, 'b, 'c> -> 'b> + Left = Map.empty<'c, 'a -> 'b -> T<'a, 'b, 'c> -> 'b> + } + + let matchError () = exn "Match pattern failed" + let smd token funct parser = {parser with T.Stmt = parser.Stmt.Add(token, funct)} + let nud token funct parser = {parser with T.Null = parser.Null.Add(token, funct)} + let led token funct parser = {parser with T.Left = parser.Left.Add(token, funct)} + let bpw token power parser = {parser with T.BindingPower = parser.BindingPower.Add(token, power)} + + (*Defines a left-associative infix operator*) + let infix f typ pwr p = + let infix tok left p = + f tok left (p |> exprPwr pwr) + + p |> bpw typ pwr |> led typ infix + + (*Defines a right-associative infix operator*) + let infixr f typ pwr p = + let lpwr = pwr - 1 + + let infix tok left p = + f tok left (p |> exprPwr lpwr) + + p |> bpw typ pwr |> led typ infix + + (*Defines a prefix/unary operator*) + let prefix f typ pwr p = + let prefix tok parser = + f tok (parser |> exprPwr pwr) + + p |> nud typ prefix + + (*Defines a constant*) + let constant symbol value p = + p |> nud symbol (fun _ _ -> value) + + (* + Runs the parser and treats all + top level construct as expressions + *) + let runExpr input source parser = + {parser with + T.Input = ref input + T.Lines = source + } |> exprList + + (* + Runs the parser and treats all + top level construct as statements + *) + let runStmt input source term parser = + {parser with + T.Input = ref input + T.Lines = source + } |> stmtList term + +(* + Example parser for a very simple grammar +*) + +//AST Types +type UnaryOp + = Plus + | Minus + +type BinaryOp + = Multiply + | Add + | Subtract + | Divide + | Assign + | Equals + +type Ast + = Number of int + | Identifier of string + | String of string + | Binary of BinaryOp * Ast * Ast + | Unary of UnaryOp * Ast + | Ternary of Ast * Ast * Ast // test * ifTrue * ifFalse + | If of Ast * Ast * Ast option // test + ifTrue and possibly ifFalse (else branch) + | Call of Ast * Ast list // target + arguments list + | Block of Ast list // statements list + | True + | False + +//Shorthand types for convenience +module P = Parser +type Token = string * string * (Parser.Pos) +type P = Parser.T + +//Utility functions for extracting values out of Token +let type' ((t, _, _):Token) = t +let value ((_, v, _):Token) = v +let pos ((_, _, p):Token) = p +let value_num (t:Token) = t |> value |> int + +//Utility functions for creating new tokens +let number value pos : Token = "#number", value, pos +let string value pos : Token = "#string", value, pos +let identifier name pos : Token = "#identifier", name, pos + +let symbol type' pos : Token = type', "", pos +let add = symbol "+" +let sub = symbol "-" +let mul = symbol "*" +let div = symbol "/" +let assign = symbol "=" +let equals = symbol "==" +let lparen = symbol "(" +let rparen = symbol ")" +let lbrace = symbol "{" +let rbrace = symbol "}" +let comma = symbol "," +let qmark = symbol "?" +let colon = symbol ":" +let scolon = symbol ";" +let if' = symbol "if" +let true' = symbol "true" +let else' = symbol "else" + +//Utility functions for converting tokens to binary and unary operators +let toBinaryOp tok = + match type' tok with + | "=" -> BinaryOp.Assign + | "+" -> BinaryOp.Add + | "-" -> BinaryOp.Subtract + | "*" -> BinaryOp.Multiply + | "/" -> BinaryOp.Divide + | "==" -> BinaryOp.Equals + | _ -> P.exn (sprintf "Couldn't convert %s-token to BinaryOp" (type' tok)) + +let toUnaryOp tok = + match type' tok with + | "+" -> UnaryOp.Plus + | "-" -> UnaryOp.Minus + | _ -> P.exn (sprintf "Couldn't convert %s-token to UnaryOp" (type' tok)) + +//Utility function for defining infix operators +let infix = + P.infix (fun token left right -> + Binary(token |> toBinaryOp, left, right)) + +//Utility function for defining prefix operators +let prefix = + P.prefix (fun token ast -> + Unary(token |> toUnaryOp, ast)) + +//Utility function for defining constants +let constant typ value p = + p |> P.nud typ (fun _ _ -> value) + +//Utility function for parsing a block +let block p = + let rec stmts p = + match p |> P.currentTypeTry with + | None -> [] + | Some "}" -> p |> P.skip; [] + | _ -> (p |> P.stmt ";") :: (stmts p) + + p |> P.skipIf "{" + Block(p |> stmts) + +//Pretty printing function for error messages +let prettyPrint (tok:Token) = + match tok with + | "#number", value, _ -> sprintf "#number %s" value + | "#identifier", name, _ -> sprintf "#identifier %s" name + | "#string", value, _ -> sprintf "#string \"%s\"" value + | type', _, _ -> type' + +//The parser definition +let example_parser = + (P.create type' pos (Some prettyPrint)) + + //Literals and identifiers + |> P.nud "#number" (fun t _ -> t |> value |> int |> Number) + |> P.nud "#identifier" (fun t _ -> t |> value |> Identifier) + |> P.nud "#string" (fun t _ -> t |> value |> String) + + //Constants + |> constant "true" Ast.True + |> constant "false" Ast.False + + //Infix Operators + |> infix "==" 40 + |> infix "+" 50 + |> infix "-" 50 + |> infix "*" 60 + |> infix "/" 60 + |> infix "=" 80 + + //Prefix Operators + |> prefix "+" 70 + |> prefix "-" 70 + + //Grouping expressions () + |> P.nud "(" (fun t p -> p |> P.exprSkip ")") + + //Ternary operator ? : + |> P.bpw "?" 70 + |> P.led "?" (fun _ left p -> + let ternary = [P.Get P.expr; P.Sym ":"; P.Get P.expr] + match p |> P.match' ternary with + | ifTrue::ifFalse::_ -> Ternary(left, ifTrue, ifFalse) + | _ -> P.matchError() + ) + + //If/Else statement if() { }] + |> P.smd "if" (fun _ p -> + let if' = [P.Sym "("; P.Get P.expr; P.Sym ")"; P.Get block] + let else' = [P.Sym "else"; P.Get block] + + match p |> P.match' if' with + | test::ifTrue::_ -> + match p |> P.match' else' with + | ifFalse::_ -> If(test, ifTrue, Some(ifFalse)) + | _ -> If(test, ifTrue, None) + | _ -> P.matchError() + ) + + //Function call + |> P.bpw "(" 80 + |> P.led "(" (fun _ func p -> + let rec args (p:P) = + match p |> P.currentType with + | ")" -> p |> P.skip; [] + | "," -> p |> P.skip; args p + | _ -> (p |> P.expr) :: args p + + Call(func, args p) + ) + +//Code to parse +(* +1: x = 5; +2: y = 5; +3: +4: if(x == y) { +5: print("x equals y"); +6: } else { +7: print("x doesn't equal y"); +8: } +*) + +let code = @"x = 5; +y = 5; + +if(x == y) { + print('x equals y'); +} else { + print('x doesn't equal y'); +}" + +//The code in tokens, manually entered +//since we don't have a lexer to produce +//the tokens for us +let tokens = + [ + //x = 5; + identifier "x" (1, 1) + assign (1, 3) + number "5" (1, 5) + scolon (1, 6) + + //y = 5; + identifier "y" (2, 1) + assign (2, 3) + number "5" (2, 5) + scolon (2, 6) + + //if(x == y) { + if' (4, 1) + lparen (4, 3) + identifier "x" (4, 4) + equals (4, 6) + identifier "y" (4, 9) + rparen (4, 10) + lbrace (4, 12) + + //print("x equals y"); + identifier "print" (5, 3) + lparen (5, 8) + string "x equals y" (5, 9) + rparen (5, 21) + scolon (5, 22) + + //} else { + rbrace (6, 1) + else' (6, 3) + lbrace (6, 7) + + //print("x doesn't equal y"); + identifier "print" (7, 3) + lparen (7, 7) + string "x doesn't equal y" (7, 9) + rparen (7, 27) + scolon (7, 28) + + //} + rbrace (8, 1) + ] + +let ast = example_parser |> P.runStmt tokens (Some code) ";" diff --git a/tests/benchmarks/MicroPerf/Async.fs b/tests/benchmarks/MicroPerf/Async.fs new file mode 100644 index 00000000000..704b0723c94 --- /dev/null +++ b/tests/benchmarks/MicroPerf/Async.fs @@ -0,0 +1,21 @@ +module Async + +open BenchmarkDotNet.Attributes + +[] +[] +[] +[] +type AsyncWhileMemoryBench() = + + [] + member val Length = 0 with get, set + + [] + member x.Run() = + async { + let mutable i = 0 + while i < x.Length do + i <- i + 1 + return i + } |> Async.StartAsTask \ No newline at end of file diff --git a/tests/benchmarks/MicroPerf/Benchmarks.fs b/tests/benchmarks/MicroPerf/Benchmarks.fs new file mode 100644 index 00000000000..366efa97439 --- /dev/null +++ b/tests/benchmarks/MicroPerf/Benchmarks.fs @@ -0,0 +1,18 @@ +(* +msbuild tests\fsharp\perf\tasks\FS\TaskPerf.fsproj /p:Configuration=Release +dotnet artifacts\bin\TaskPerf\Release\netcoreapp2.1\TaskPerf.dll +*) + +namespace TaskPerf + +open BenchmarkDotNet.Running + +module Main = + + [] + let main argv = + printfn "Running benchmarks..." + //let results = BenchmarkRunner.Run() + //let results = BenchmarkRunner.Run() + let results = BenchmarkRunner.Run() + 0 diff --git a/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.cs b/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.cs new file mode 100644 index 00000000000..409ed07ac55 --- /dev/null +++ b/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.cs @@ -0,0 +1,17 @@ + +using System.Runtime.CompilerServices; + +public class MicroPerfCSharp +{ + // + // FSharp will not inline the code so we shouldn't eiter. + // + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Cond(int x) + { + if (x == 1 || x == 2) return 1; + else if (x == 3 || x == 4) return 2; + + else return 8; + } +} \ No newline at end of file diff --git a/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.csproj b/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.csproj new file mode 100644 index 00000000000..875fdf3236c --- /dev/null +++ b/tests/benchmarks/MicroPerf/CS/MicroPerfCSharp.csproj @@ -0,0 +1,19 @@ + + + + net5.0 + Library + 8.0 + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/benchmarks/MicroPerf/Collections.fs b/tests/benchmarks/MicroPerf/Collections.fs new file mode 100644 index 00000000000..1fdacc37fd9 --- /dev/null +++ b/tests/benchmarks/MicroPerf/Collections.fs @@ -0,0 +1,216 @@ +module Collections + +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Running +open BenchmarkDotNet.Configs +open BenchmarkDotNet.Diagnosers +open System.Runtime.CompilerServices + +[] +[] +[] +[] +type CollectionsBenchmark() = + let mutable length = 0 + let mutable list = [] + let mutable array = [||] + + [] + member this.Length + with get () = length + and set (value) = + length <- value + list <- List.init length (fun _ -> 0) + array <- Array.init length (fun _ -> 0) + + /// List + [] + member x.ListRemoveAtBeginning() = + list + |> List.removeAt 0 + |> ignore + + [] + member x.ListRemoveAtEnd() = + list + |> List.removeAt (x.Length - 1) + |> ignore + + [] + member x.ListRemoveManyAtBeginning() = + list + |> List.removeManyAt 0 10 + |> ignore + + [] + member x.ListRemoveManyAtEnd() = + list + |> List.removeManyAt (x.Length - 11) 10 + |> ignore + + [] + member x.ListInsertAtBeginning() = + list + |> List.insertAt 0 1 + |> ignore + + [] + member x.ListInsertAtEnd() = + list + |> List.insertAt (x.Length - 1) 1 + |> ignore + + [] + member x.ListInsertManyAtBeginning() = + list + |> List.insertManyAt 0 [1..10] + |> ignore + + [] + member x.ListInsertManyAtEnd() = + list + |> List.insertManyAt (x.Length - 11) [1..10] + |> ignore + + [] + member x.ListUpdateAtBeginning() = + list + |> List.updateAt 0 1 + |> ignore + + [] + member x.ListUpdateEnd() = + list + |> List.updateAt (x.Length - 1) 1 + |> ignore + + /// Array + [] + member x.ArrayRemoveAtBeginning() = + array + |> Array.removeAt 0 + |> ignore + + [] + member x.ArrayRemoveAtEnd() = + array + |> Array.removeAt (x.Length - 1) + |> ignore + + [] + member x.ArrayRemoveManyAtBeginning() = + array + |> Array.removeManyAt 0 10 + |> ignore + + [] + member x.ArrayRemoveManyAtEnd() = + array + |> Array.removeManyAt (x.Length - 11) 10 + |> ignore + + [] + member x.ArrayInsertAtBeginning() = + array + |> Array.insertAt 0 1 + |> ignore + + [] + member x.ArrayInsertAtEnd() = + array + |> Array.insertAt (x.Length - 1) 1 + |> ignore + + [] + member x.ArrayInsertManyAtBeginning() = + array + |> Array.insertManyAt 0 [1..10] + |> ignore + + [] + member x.ArrayInsertManyAtEnd() = + array + |> Array.insertManyAt (x.Length - 11) [1..10] + |> ignore + + [] + member x.ArrayUpdateAtBeginning() = + array + |> Array.updateAt 0 1 + |> ignore + + [] + member x.ArrayUpdateEnd() = + array + |> Array.updateAt (x.Length - 1) 1 + |> ignore + + /// Seq + [] + member x.SeqBaseline() = + array + |> Seq.toList + |> ignore + + [] + member x.SeqRemoveAtBeginning() = + list + |> Seq.removeAt 0 + |> Seq.toList + |> ignore + + [] + member x.SeqRemoveAtEnd() = + list + |> Seq.removeAt (x.Length - 1) + |> Seq.toList + |> ignore + + [] + member x.SeqRemoveManyAtBeginning() = + list + |> Seq.removeManyAt 0 10 + |> Seq.toList + |> ignore + + [] + member x.SeqRemoveManyAtEnd() = + list + |> Seq.removeManyAt (x.Length - 11) 10 + |> Seq.iter ignore + + [] + member x.SeqInsertAtBeginning() = + list + |> Seq.insertAt 0 1 + |> Seq.iter ignore + + [] + member x.SeqInsertAtEnd() = + list + |> Seq.insertAt (x.Length - 1) 1 + |> Seq.iter ignore + + [] + member x.SeqInsertManyAtBeginning() = + list + |> Seq.insertManyAt 0 [1..10] + |> Seq.iter ignore + + [] + member x.SeqInsertManyAtEnd() = + list + |> Seq.insertManyAt (x.Length - 11) [1..10] + |> Seq.iter ignore + + [] + member x.SeqUpdateAtBeginning() = + list + |> Seq.updateAt 0 1 + |> Seq.iter ignore + + [] + member x.SeqUpdateEnd() = + list + |> Seq.updateAt (x.Length - 1) 1 + |> Seq.iter ignore \ No newline at end of file diff --git a/tests/benchmarks/MicroPerf/Conditions.fs b/tests/benchmarks/MicroPerf/Conditions.fs new file mode 100644 index 00000000000..e2a6a634b5e --- /dev/null +++ b/tests/benchmarks/MicroPerf/Conditions.fs @@ -0,0 +1,31 @@ +module Conditions + +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Diagnosers +open System.Runtime.CompilerServices + +[] +let condition_2 x = + if (x = 1 || x = 2) then 1 + elif(x = 3 || x = 4) then 2 + else 8 + +[] +[] +type Benchmarks() = + + [] + [] + [] + [] + [] + member _.CSharp(x: int) = + MicroPerfCSharp.Cond(x) + + [] + [] + [] + [] + [] + member _.FSharp(x: int) = + condition_2(x) \ No newline at end of file diff --git a/tests/benchmarks/MicroPerf/MicroPerf.fsproj b/tests/benchmarks/MicroPerf/MicroPerf.fsproj new file mode 100644 index 00000000000..ac86fbbdcc2 --- /dev/null +++ b/tests/benchmarks/MicroPerf/MicroPerf.fsproj @@ -0,0 +1,30 @@ + + + net5.0 + Exe + true + + $(OtherFlags) --nowarn:1204 + + $(OtherFlags) --nowarn:57 + $(OtherFlags) --langversion:preview + $(OtherFlags) --define:PREVIEW + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/benchmarks/TaskPerf/TaskBuilder.fs b/tests/benchmarks/TaskPerf/TaskBuilder.fs new file mode 100644 index 00000000000..9d3683e4b27 --- /dev/null +++ b/tests/benchmarks/TaskPerf/TaskBuilder.fs @@ -0,0 +1,416 @@ +// TaskBuilder.fs - TPL task computation expressions for F# +// +// Written in 2016 by Robert Peele (humbobst@gmail.com) +// New operator-based overload resolution for F# 4.0 compatibility by Gustavo Leon in 2018. +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights +// to this software to the public domain worldwide. This software is distributed without any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication along with this software. +// If not, see . + +namespace TaskBuilderTasks +open System +open System.Threading.Tasks +open System.Runtime.CompilerServices + +// This module is not really obsolete, but it's not intended to be referenced directly from user code. +// However, it can't be private because it is used within inline functions that *are* user-visible. +// Marking it as obsolete is a workaround to hide it from auto-completion tools. +[] +module TaskBuilder = + /// Represents the state of a computation: + /// either awaiting something with a continuation, + /// or completed with a return value. + type Step<'a> = + | Await of ICriticalNotifyCompletion * (unit -> Step<'a>) + | Return of 'a + /// We model tail calls explicitly, but still can't run them without O(n) memory usage. + | ReturnFrom of 'a Task + /// Implements the machinery of running a `Step<'m, 'm>` as a task returning a continuation task. + and StepStateMachine<'a>(firstStep) as this = + let methodBuilder = AsyncTaskMethodBuilder<'a Task>() + /// The continuation we left off awaiting on our last MoveNext(). + let mutable continuation = fun () -> firstStep + /// Returns next pending awaitable or null if exiting (including tail call). + let nextAwaitable() = + try + match continuation() with + | Return r -> + methodBuilder.SetResult(Task.FromResult(r)) + null + | ReturnFrom t -> + methodBuilder.SetResult(t) + null + | Await (await, next) -> + continuation <- next + await + with + | exn -> + methodBuilder.SetException(exn) + null + let mutable self = this + + /// Start execution as a `Task>`. + member __.Run() = + methodBuilder.Start(&self) + methodBuilder.Task + + interface IAsyncStateMachine with + /// Proceed to one of three states: result, failure, or awaiting. + /// If awaiting, MoveNext() will be called again when the awaitable completes. + member __.MoveNext() = + let mutable await = nextAwaitable() + if not (isNull await) then + // Tell the builder to call us again when this thing is done. + methodBuilder.AwaitUnsafeOnCompleted(&await, &self) + member __.SetStateMachine(_) = () // Doesn't really apply since we're a reference type. + + let unwrapException (agg : AggregateException) = + let inners = agg.InnerExceptions + if inners.Count = 1 then inners.[0] + else agg :> Exception + + /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression. + let zero = Return () + + /// Used to return a value. + let ret (x : 'a) = Return x + + type Binder<'out> = + // We put the output generic parameter up here at the class level, so it doesn't get subject to + // inline rules. If we put it all in the inline function, then the compiler gets confused at the + // below and demands that the whole function either is limited to working with (x : obj), or must + // be inline itself. + // + // let yieldThenReturn (x : 'a) = + // task { + // do! Task.Yield() + // return x + // } + + static member inline GenericAwait< ^abl, ^awt, ^inp + when ^abl : (member GetAwaiter : unit -> ^awt) + and ^awt :> ICriticalNotifyCompletion + and ^awt : (member get_IsCompleted : unit -> bool) + and ^awt : (member GetResult : unit -> ^inp) > + (abl : ^abl, continuation : ^inp -> 'out Step) : 'out Step = + let awt = (^abl : (member GetAwaiter : unit -> ^awt)(abl)) // get an awaiter from the awaitable + if (^awt : (member get_IsCompleted : unit -> bool)(awt)) then // shortcut to continue immediately + continuation (^awt : (member GetResult : unit -> ^inp)(awt)) + else + Await (awt, fun () -> continuation (^awt : (member GetResult : unit -> ^inp)(awt))) + + static member inline GenericAwaitConfigureFalse< ^tsk, ^abl, ^awt, ^inp + when ^tsk : (member ConfigureAwait : bool -> ^abl) + and ^abl : (member GetAwaiter : unit -> ^awt) + and ^awt :> ICriticalNotifyCompletion + and ^awt : (member get_IsCompleted : unit -> bool) + and ^awt : (member GetResult : unit -> ^inp) > + (tsk : ^tsk, continuation : ^inp -> 'out Step) : 'out Step = + let abl = (^tsk : (member ConfigureAwait : bool -> ^abl)(tsk, false)) + Binder<'out>.GenericAwait(abl, continuation) + + /// Special case of the above for `Task<'a>`. Have to write this out by hand to avoid confusing the compiler + /// trying to decide between satisfying the constraints with `Task` or `Task<'a>`. + let bindTask (task : 'a Task) (continuation : 'a -> Step<'b>) = + let awt = task.GetAwaiter() + if awt.IsCompleted then // Proceed to the next step based on the result we already have. + continuation(awt.GetResult()) + else // Await and continue later when a result is available. + Await (awt, (fun () -> continuation(awt.GetResult()))) + + /// Special case of the above for `Task<'a>`, for the context-insensitive builder. + /// Have to write this out by hand to avoid confusing the compiler thinking our built-in bind method + /// defined on the builder has fancy generic constraints on inp and out parameters. + let bindTaskConfigureFalse (task : 'a Task) (continuation : 'a -> Step<'b>) = + let awt = task.ConfigureAwait(false).GetAwaiter() + if awt.IsCompleted then // Proceed to the next step based on the result we already have. + continuation(awt.GetResult()) + else // Await and continue later when a result is available. + Await (awt, (fun () -> continuation(awt.GetResult()))) + + /// Chains together a step with its following step. + /// Note that this requires that the first step has no result. + /// This prevents constructs like `task { return 1; return 2; }`. + let rec combine (step : Step) (continuation : unit -> Step<'b>) = + match step with + | Return _ -> continuation() + | ReturnFrom t -> + Await (t.GetAwaiter(), continuation) + | Await (awaitable, next) -> + Await (awaitable, fun () -> combine (next()) continuation) + + /// Builds a step that executes the body while the condition predicate is true. + let whileLoop (cond : unit -> bool) (body : unit -> Step) = + if cond() then + // Create a self-referencing closure to test whether to repeat the loop on future iterations. + let rec repeat () = + if cond() then + let body = body() + match body with + | Return _ -> repeat() + | ReturnFrom t -> Await(t.GetAwaiter(), repeat) + | Await (awaitable, next) -> + Await (awaitable, fun () -> combine (next()) repeat) + else zero + // Run the body the first time and chain it to the repeat logic. + combine (body()) repeat + else zero + + /// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + let rec tryWith(step : unit -> Step<'a>) (catch : exn -> Step<'a>) = + try + match step() with + | Return _ as i -> i + | ReturnFrom t -> + let awaitable = t.GetAwaiter() + Await(awaitable, fun () -> + try + awaitable.GetResult() |> Return + with + | exn -> catch exn) + | Await (awaitable, next) -> Await (awaitable, fun () -> tryWith next catch) + with + | exn -> catch exn + + /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + let rec tryFinally (step : unit -> Step<'a>) fin = + let step = + try step() + // Important point: we use a try/with, not a try/finally, to implement tryFinally. + // The reason for this is that if we're just building a continuation, we definitely *shouldn't* + // execute the `fin()` part yet -- the actual execution of the asynchronous code hasn't completed! + with + | _ -> + fin() + reraise() + match step with + | Return _ as i -> + fin() + i + | ReturnFrom t -> + let awaitable = t.GetAwaiter() + Await(awaitable, fun () -> + let result = + try + awaitable.GetResult() |> Return + with + | _ -> + fin() + reraise() + fin() // if we got here we haven't run fin(), because we would've reraised after doing so + result) + | Await (awaitable, next) -> + Await (awaitable, fun () -> tryFinally next fin) + + /// Implements a using statement that disposes `disp` after `body` has completed. + let using (disp : #IDisposable) (body : _ -> Step<'a>) = + // A using statement is just a try/finally with the finally block disposing if non-null. + tryFinally + (fun () -> body disp) + (fun () -> if not (isNull (box disp)) then disp.Dispose()) + + /// Implements a loop that runs `body` for each element in `sequence`. + let forLoop (sequence : 'a seq) (body : 'a -> Step) = + // A for loop is just a using statement on the sequence's enumerator... + using (sequence.GetEnumerator()) + // ... and its body is a while loop that advances the enumerator and runs the body on each element. + (fun e -> whileLoop e.MoveNext (fun () -> body e.Current)) + + /// Runs a step as a task -- with a short-circuit for immediately completed steps. + let run (firstStep : unit -> Step<'a>) = + try + match firstStep() with + | Return x -> Task.FromResult(x) + | ReturnFrom t -> t + | Await _ as step -> StepStateMachine<'a>(step).Run().Unwrap() // sadly can't do tail recursion + // Any exceptions should go on the task, rather than being thrown from this call. + // This matches C# behavior where you won't see an exception until awaiting the task, + // even if it failed before reaching the first "await". + with + | exn -> + let src = new TaskCompletionSource<_>() + src.SetException(exn) + src.Task + + // We have to have a dedicated overload for Task<'a> so the compiler doesn't get confused with Convenience overloads for Asyncs + // Everything else can use bindGenericAwaitable via an extension member + + type Priority3 = obj + type Priority2 = IComparable + + type BindS = Priority1 with + static member inline (>>=) (_:Priority2, taskLike : 't) = fun (k: _ -> 'b Step) -> Binder<'b>.GenericAwait (taskLike, k): 'b Step + static member (>>=) ( Priority1, task: 'a Task) = fun (k: 'a -> 'b Step) -> bindTask task k : 'b Step + static member (>>=) ( Priority1, a : 'a Async) = fun (k: 'a -> 'b Step) -> bindTask (Async.StartAsTask a) k : 'b Step + + type ReturnFromS = Priority1 with + static member inline ($) (Priority1, taskLike ) = Binder<_>.GenericAwait (taskLike, ret) + static member ($) (Priority1, a : 'a Async) = bindTask (Async.StartAsTask a) ret : Step<'a> + + type BindI = Priority1 with + static member inline (>>=) (_:Priority3, taskLike : 't) = fun (k : _ -> 'b Step) -> Binder<'b>.GenericAwait (taskLike, k) : 'b Step + static member inline (>>=) (_:Priority2, configurableTaskLike: 't) = fun (k : _ -> 'b Step) -> Binder<'b>.GenericAwaitConfigureFalse (configurableTaskLike, k): 'b Step + static member (>>=) ( Priority1, task: 'a Task ) = fun (k : 'a -> 'b Step) -> bindTaskConfigureFalse task k : 'b Step + static member (>>=) ( Priority1, a : 'a Async ) = fun (k : 'a -> 'b Step) -> bindTaskConfigureFalse (Async.StartAsTask a) k : 'b Step + + type ReturnFromI = Priority1 with + static member inline ($) (_:Priority2, taskLike ) = Binder<_>.GenericAwait(taskLike, ret) + static member inline ($) ( Priority1, configurableTaskLike) = Binder<_>.GenericAwaitConfigureFalse(configurableTaskLike, ret) + static member ($) ( Priority1, a : 'a Async ) = bindTaskConfigureFalse (Async.StartAsTask a) ret + + // New style task builder. + type TaskBuilderV2() = + // These methods are consistent between all builders. + member __.Delay(f : unit -> Step<_>) = f + member __.Run(f : unit -> Step<'m>) = run f + member __.Zero() = zero + member __.Return(x) = ret x + member __.Combine(step : unit Step, continuation) = combine step continuation + member __.While(condition : unit -> bool, body : unit -> unit Step) = whileLoop condition body + member __.For(sequence : _ seq, body : _ -> unit Step) = forLoop sequence body + member __.TryWith(body : unit -> _ Step, catch : exn -> _ Step) = tryWith body catch + member __.TryFinally(body : unit -> _ Step, fin : unit -> unit) = tryFinally body fin + member __.Using(disp : #IDisposable, body : #IDisposable -> _ Step) = using disp body + member __.ReturnFrom a : _ Step = ReturnFrom a + + // Old style task builder. Retained for binary compatibility. + type TaskBuilder() = + // These methods are consistent between the two builders. + // Unfortunately, inline members do not work with inheritance. + member inline __.Delay(f : unit -> Step<_>) = f + member inline __.Run(f : unit -> Step<'m>) = run f + member inline __.Zero() = zero + member inline __.Return(x) = ret x + member inline __.Combine(step : unit Step, continuation) = combine step continuation + member inline __.While(condition : unit -> bool, body : unit -> unit Step) = whileLoop condition body + member inline __.For(sequence : _ seq, body : _ -> unit Step) = forLoop sequence body + member inline __.TryWith(body : unit -> _ Step, catch : exn -> _ Step) = tryWith body catch + member inline __.TryFinally(body : unit -> _ Step, fin : unit -> unit) = tryFinally body fin + member inline __.Using(disp : #IDisposable, body : #IDisposable -> _ Step) = using disp body + // End of consistent methods -- the following methods are different between + // `TaskBuilder` and `ContextInsensitiveTaskBuilder`! + + // We have to have a dedicated overload for Task<'a> so the compiler doesn't get confused. + // Everything else can use bindGenericAwaitable via an extension member (defined later). + member inline __.ReturnFrom(task : _ Task) = ReturnFrom task + member inline __.Bind(task : 'a Task, continuation : 'a -> 'b Step) : 'b Step = + bindTask task continuation + + // Old style task builder. Retained for binary compatibility. + type ContextInsensitiveTaskBuilder() = + // These methods are consistent between the two builders. + // Unfortunately, inline members do not work with inheritance. + member inline __.Delay(f : unit -> Step<_>) = f + member inline __.Run(f : unit -> Step<'m>) = run f + member inline __.Zero() = zero + member inline __.Return(x) = ret x + member inline __.Combine(step : unit Step, continuation) = combine step continuation + member inline __.While(condition : unit -> bool, body : unit -> unit Step) = whileLoop condition body + member inline __.For(sequence : _ seq, body : _ -> unit Step) = forLoop sequence body + member inline __.TryWith(body : unit -> _ Step, catch : exn -> _ Step) = tryWith body catch + member inline __.TryFinally(body : unit -> _ Step, fin : unit -> unit) = tryFinally body fin + member inline __.Using(disp : #IDisposable, body : #IDisposable -> _ Step) = using disp body + // End of consistent methods -- the following methods are different between + // `TaskBuilder` and `ContextInsensitiveTaskBuilder`! + + // We have to have a dedicated overload for Task<'a> so the compiler doesn't get confused. + // Everything else can use bindGenericAwaitable via an extension member (defined later). + member inline __.ReturnFrom(task : _ Task) = ReturnFrom task + member inline __.Bind(task : 'a Task, continuation : 'a -> 'b Step) : 'b Step = + bindTaskConfigureFalse task continuation + + +// Don't warn about our use of the "obsolete" module we just defined (see notes at start of file). +#nowarn "44" + +[] +module ContextSensitive = + /// Builds a `System.Threading.Tasks.Task<'a>` similarly to a C# async/await method. + /// Use this like `task { let! taskResult = someTask(); return taskResult.ToString(); }`. + let taskBuilder = TaskBuilder.TaskBuilder() + + [] + let inline unitTask t = t :> Task + + // These are fallbacks when the Bind and ReturnFrom on the builder object itself don't apply. + // This is how we support binding arbitrary task-like types. + type TaskBuilder.TaskBuilder with + member inline this.ReturnFrom(taskLike) = + TaskBuilder.Binder<_>.GenericAwait(taskLike, TaskBuilder.ret) + member inline this.Bind(taskLike, continuation : _ -> 'a TaskBuilder.Step) : 'a TaskBuilder.Step = + TaskBuilder.Binder<'a>.GenericAwait(taskLike, continuation) + // Convenience overloads for Asyncs. + member __.ReturnFrom(a : 'a Async) = + TaskBuilder.bindTask (Async.StartAsTask a) TaskBuilder.ret + member __.Bind(a : 'a Async, continuation : 'a -> 'b TaskBuilder.Step) : 'b TaskBuilder.Step = + TaskBuilder.bindTask (Async.StartAsTask a) continuation + +module ContextInsensitive = + /// Builds a `System.Threading.Tasks.Task<'a>` similarly to a C# async/await method, but with + /// all awaited tasks automatically configured *not* to resume on the captured context. + /// This is often preferable when writing library code that is not context-aware, but undesirable when writing + /// e.g. code that must interact with user interface controls on the same thread as its caller. + let task = TaskBuilder.ContextInsensitiveTaskBuilder() + + [] + let inline unitTask (t : Task) = t.ConfigureAwait(false) + + // These are fallbacks when the Bind and ReturnFrom on the builder object itself don't apply. + // This is how we support binding arbitrary task-like types. + type TaskBuilder.ContextInsensitiveTaskBuilder with + member inline this.ReturnFrom(taskLike) = + TaskBuilder.Binder<_>.GenericAwait(taskLike, TaskBuilder.ret) + member inline this.Bind(taskLike, continuation : _ -> 'a TaskBuilder.Step) : 'a TaskBuilder.Step = + TaskBuilder.Binder<'a>.GenericAwait(taskLike, continuation) + + // Convenience overloads for Asyncs. + member __.ReturnFrom(a : 'a Async) = + TaskBuilder.bindTaskConfigureFalse (Async.StartAsTask a) TaskBuilder.ret + member __.Bind(a : 'a Async, continuation : 'a -> 'b TaskBuilder.Step) : 'b TaskBuilder.Step = + TaskBuilder.bindTaskConfigureFalse (Async.StartAsTask a) continuation + + [] + module HigherPriorityBinds = + // When it's possible for these to work, the compiler should prefer them since they shadow the ones above. + type TaskBuilder.ContextInsensitiveTaskBuilder with + member inline this.ReturnFrom(configurableTaskLike) = + TaskBuilder.Binder<_>.GenericAwaitConfigureFalse(configurableTaskLike, TaskBuilder.ret) + member inline this.Bind(configurableTaskLike, continuation : _ -> 'a TaskBuilder.Step) : 'a TaskBuilder.Step = + TaskBuilder.Binder<'a>.GenericAwaitConfigureFalse(configurableTaskLike, continuation) + + +module V2 = + [] + module ContextSensitive = + open TaskBuilder + + /// Builds a `System.Threading.Tasks.Task<'a>` similarly to a C# async/await method. + /// Use this like `task { let! taskResult = someTask(); return taskResult.ToString(); }`. + let taskBuilder = TaskBuilderV2() + + [] + let unitTask (t : Task) = t + + type TaskBuilderV2 with + member inline __.Bind (task, continuation : 'a -> 'b Step) : 'b Step = (BindS.Priority1 >>= task) continuation + member inline __.ReturnFrom a : 'b Step = ReturnFromS.Priority1 $ a + + module ContextInsensitive = + open TaskBuilder + + /// Builds a `System.Threading.Tasks.Task<'a>` similarly to a C# async/await method, but with + /// all awaited tasks automatically configured *not* to resume on the captured context. + /// This is often preferable when writing library code that is not context-aware, but undesirable when writing + /// e.g. code that must interact with user interface controls on the same thread as its caller. + let task = TaskBuilderV2() + + [] + let unitTask (t : Task) = t.ConfigureAwait(false) + + type TaskBuilderV2 with + member inline __.Bind (task, continuation : 'a -> 'b Step) : 'b Step = (BindI.Priority1 >>= task) continuation + member inline __.ReturnFrom a : 'b Step = ReturnFromI.Priority1 $ a \ No newline at end of file diff --git a/tests/benchmarks/TaskPerf/TaskPerf.fs b/tests/benchmarks/TaskPerf/TaskPerf.fs new file mode 100644 index 00000000000..5feafc4a3da --- /dev/null +++ b/tests/benchmarks/TaskPerf/TaskPerf.fs @@ -0,0 +1,476 @@ +(* +msbuild tests\fsharp\perf\tasks\FS\TaskPerf.fsproj /p:Configuration=Release +dotnet artifacts\bin\TaskPerf\Release\netcoreapp2.1\TaskPerf.dll +*) + +namespace TaskPerf + +//open FSharp.Control.Tasks +open System +open System.Diagnostics +open System.Threading.Tasks +open System.IO +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Running +open TaskBuilderTasks //.ContextSensitive // TaskBuilder.fs extension members +//open FSharp.Control.ContextSensitiveTasks // the default +open FSharp.Control // AsyncSeq +open Tests.SyncBuilder +open BenchmarkDotNet.Configs +#if PREVIEW +open FSharp.Control.Async2 +open Tests.TaskSeq +#endif + +[] +module Helpers = + let bufferSize = 128 + let manyIterations = 1000 + let syncTask() = Task.FromResult 100 + let syncTask_async() = async.Return 100 + let syncTask_async2() = Task.FromResult 100 + let asyncYield() = Async.Sleep(0) + let asyncTask() = Task.Yield() + + let tenBindSync_taskBuilder() = + taskBuilder { + let! res1 = syncTask() + let! res2 = syncTask() + let! res3 = syncTask() + let! res4 = syncTask() + let! res5 = syncTask() + let! res6 = syncTask() + let! res7 = syncTask() + let! res8 = syncTask() + let! res9 = syncTask() + let! res10 = syncTask() + return res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10 + } + + let tenBindSync_async() = + async { + let! res1 = syncTask_async() + let! res2 = syncTask_async() + let! res3 = syncTask_async() + let! res4 = syncTask_async() + let! res5 = syncTask_async() + let! res6 = syncTask_async() + let! res7 = syncTask_async() + let! res8 = syncTask_async() + let! res9 = syncTask_async() + let! res10 = syncTask_async() + return res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10 + } + +#if PREVIEW + let tenBindSync_task() = + task { + let! res1 = syncTask() + let! res2 = syncTask() + let! res3 = syncTask() + let! res4 = syncTask() + let! res5 = syncTask() + let! res6 = syncTask() + let! res7 = syncTask() + let! res8 = syncTask() + let! res9 = syncTask() + let! res10 = syncTask() + return res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10 + } + + let tenBindSync_async2() = + async2 { + let! res1 = syncTask_async2() + let! res2 = syncTask_async2() + let! res3 = syncTask_async2() + let! res4 = syncTask_async2() + let! res5 = syncTask_async2() + let! res6 = syncTask_async2() + let! res7 = syncTask_async2() + let! res8 = syncTask_async2() + let! res9 = syncTask_async2() + let! res10 = syncTask_async2() + return res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10 + } +#endif + + let tenBindAsync_taskBuilder() = + taskBuilder { + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + } + + let tenBindAsync_async() = + async { + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + do! asyncYield() + } +#if PREVIEW + let tenBindAsync_task() = + task { + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + } + + let tenBindAsync_async2() = + async2 { + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + do! asyncTask() + } +#endif + + let singleTask_taskBuilder() = + taskBuilder { return 1 } + + let singleTask_async() = + async { return 1 } +#if PREVIEW + let singleTask_task() = + task { return 1 } + + let singleTask_async2() = + async2 { return 1 } +#endif + +[] +[] +[] +type Benchmarks() = + + [] + member _.ManyWriteFile_CSharpTasks () = + TaskPerfCSharp.ManyWriteFileAsync(manyIterations).Wait(); + + [] + member _.ManyWriteFile_taskBuilder () = + let path = Path.GetTempFileName() + taskBuilder { + let junk = Array.zeroCreate bufferSize + use file = File.Create(path) + for i = 1 to manyIterations do + do! file.WriteAsync(junk, 0, junk.Length) + } + |> fun t -> t.Wait() + File.Delete(path) + + [] + member _.ManyWriteFile_async () = + let path = Path.GetTempFileName() + async { + let junk = Array.zeroCreate bufferSize + use file = File.Create(path) + for i = 1 to manyIterations do + do! Async.AwaitTask(file.WriteAsync(junk, 0, junk.Length)) + } + |> Async.RunSynchronously + File.Delete(path) + +#if PREVIEW + [] + member _.ManyWriteFile_task () = + let path = Path.GetTempFileName() + task { + let junk = Array.zeroCreate bufferSize + use file = File.Create(path) + for i = 1 to manyIterations do + do! file.WriteAsync(junk, 0, junk.Length) + } + |> fun t -> t.Wait() + File.Delete(path) + + [] + member _.ManyWriteFile_async2 () = + let path = Path.GetTempFileName() + async2 { + let junk = Array.zeroCreate bufferSize + use file = File.Create(path) + for i = 1 to manyIterations do + do! file.WriteAsync(junk, 0, junk.Length) + } + |> Async2.RunSynchronously + File.Delete(path) +#endif + + + + [] + member _.NonAsyncBinds_CSharpTasks() = + for i in 1 .. manyIterations*100 do + TaskPerfCSharp.TenBindsSync_CSharp().Wait() + + [] + member _.NonAsyncBinds_taskBuilder() = + for i in 1 .. manyIterations*100 do + tenBindSync_taskBuilder().Wait() + + [] + member _.NonAsyncBinds_async() = + for i in 1 .. manyIterations*100 do + tenBindSync_async() |> Async.RunSynchronously |> ignore + +#if PREVIEW + [] + member _.NonAsyncBinds_async2() = + for i in 1 .. manyIterations*100 do + tenBindSync_async2() |> Async2.RunSynchronously |> ignore + + [] + member _.NonAsyncBinds_task() = + for i in 1 .. manyIterations*100 do + tenBindSync_task().Wait() + +#endif + + + + + [] + member _.AsyncBinds_CSharpTasks() = + for i in 1 .. manyIterations do + TaskPerfCSharp.TenBindsAsync_CSharp().Wait() + + [] + member _.AsyncBinds_taskBuilder() = + for i in 1 .. manyIterations do + tenBindAsync_taskBuilder().Wait() + + [] + member _.AsyncBinds_async() = + for i in 1 .. manyIterations do + tenBindAsync_async() |> Async.RunSynchronously + +#if PREVIEW + [] + member _.AsyncBinds_task() = + for i in 1 .. manyIterations do + tenBindAsync_task().Wait() + + [] + member _.AsyncBinds_async2() = + for i in 1 .. manyIterations do + tenBindAsync_async2() |> Async2.RunSynchronously +#endif + + + [] + member _.SingleSyncTask_CSharpTasks() = + for i in 1 .. manyIterations*500 do + TaskPerfCSharp.SingleSyncTask_CSharp().Wait() + + [] + member _.SingleSyncTask_taskBuilder() = + for i in 1 .. manyIterations*500 do + singleTask_taskBuilder().Wait() + + [] + member _.SingleSyncTask_async() = + for i in 1 .. manyIterations*500 do + singleTask_async() |> Async.RunSynchronously |> ignore + +#if PREVIEW + [] + member _.SingleSyncTask_task() = + for i in 1 .. manyIterations*500 do + singleTask_task().Wait() + + [] + member _.SingleSyncTask_async2() = + for i in 1 .. manyIterations*500 do + singleTask_async2() |> Async2.RunSynchronously |> ignore +#endif + + [] + member _.SyncBuilderLoop_NormalCode() = + for i in 1 .. manyIterations do + let mutable res = 0 + for i in Seq.init 1000 id do + res <- i + res + + [] + member _.SyncBuilderLoop_WorkflowCode() = + for i in 1 .. manyIterations do + sync { let mutable res = 0 + for i in Seq.init 1000 id do + res <- i + res } + +#if FSHARP_CORE_HAS_LIST_COLLECTOR + [] + member _.TinyVariableSizedList_Builtin() = Tests.ListBuilders.Examples.tinyVariableSizeBuiltin() + + + [] + member _.TinyVariableSizedList_NewBuilder() = Tests.ListBuilders.Examples.tinyVariableSizeNew() + + + [] + member _.VariableSizedList_Builtin() = Tests.ListBuilders.Examples.variableSizeBuiltin() + + [] + member _.VariableSizedList_NewBuilder() = Tests.ListBuilders.Examples.variableSizeNew() + + + [] + member _.FixedSizeList_Builtin() = Tests.ListBuilders.Examples.fixedSizeBase() + + [] + member _.FixedSizeList_NewBuilder() = Tests.ListBuilders.Examples.fixedSizeC() +#endif + + [] + member _.TinyVariableSizedArray_Builtin() = Tests.ArrayBuilders.Examples.tinyVariableSizeBuiltin() + + [] + member _.TinyVariableSizedArray_NewBuilder() = Tests.ArrayBuilders.Examples.tinyVariableSizeNew() + + + [] + member _.VariableSizedArray_Builtin() = Tests.ArrayBuilders.Examples.variableSizeBuiltin() + + [] + member _.VariableSizedArray_NewBuilder() = Tests.ArrayBuilders.Examples.variableSizeNew() + + + [] + member _.FixedSizeArray_Builtin() = Tests.ArrayBuilders.Examples.fixedSizeBase() + + + [] + member _.FixedSizeArray_NewBuilder() = Tests.ArrayBuilders.Examples.fixedSizeC() + + + [] + member _.MultiStepOption_OldBuilder() = Tests.OptionBuilders.Examples.multiStepOldBuilder() + + [] + member _.MultiStepOption_NewBuilder() = Tests.OptionBuilders.Examples.multiStepNewBuilder() + + [] + member _.MultiStepOption_NoBuilder() = Tests.OptionBuilders.Examples.multiStepNoBuilder() + + + [] + member _.MultiStepValueOption_OldBuilder() = Tests.OptionBuilders.Examples.multiStepOldBuilderV() + + [] + member _.MultiStepValueOption_NewBuilder() = Tests.OptionBuilders.Examples.multiStepNewBuilderV() + + [] + member _.MultiStepValueOption_NoBuilder() = Tests.OptionBuilders.Examples.multiStepNoBuilderV() + + +#if PREVIEW + [] + member _.NestedForLoops_CSharpAsyncEnumerable() = + TaskPerfCSharp.perf2_AsyncEnumerable() |> TaskSeq.iter ignore + + [] + member _.NestedForLoops_taskSeq() = + Tests.TaskSeq.Examples.perf2() |> TaskSeq.iter ignore + + //[] + //member _.NestedForLoops_asyncSeq() = + // Tests.TaskSeq.Examples.perf2_AsyncSeq() |> AsyncSeq.iter ignore |> Async.RunSynchronously + +#endif + +module Main = + + [] + let main argv = + let require x msg = if not x then failwith msg + printfn "Testing that the tests run..." + printfn "Running testUsing..." + let f () = + let mutable disposed = 0 + let t = + task { + use d = + { new IAsyncDisposable with + member __.DisposeAsync() = + task { + disposed <- disposed + 1 + printfn $"in disposal, disposed = {disposed}" + do! Task.Delay(10) + disposed <- disposed + 1 + printfn $"after disposal, disposed = {disposed}" + } + |> ValueTask + } + printfn $"in using, disposed = {disposed}" + do! Task.Delay(10) + } + + printfn $"outside using, disposed = {disposed}" + t.Wait() + printfn $"after full disposal, disposed = {disposed}" + + f() + + //Benchmarks().SingleSyncTask_async2() + //Benchmarks().NonAsyncBinds_async2() + //Benchmarks().ManyWriteFile_CSharpTasks() + //Benchmarks().ManyWriteFile_task () + //Benchmarks().ManyWriteFile_taskBuilder () + //Benchmarks().ManyWriteFile_FSharpAsync () + //Benchmarks().NonAsyncBinds_CSharpTasks() + //Benchmarks().NonAsyncBinds_task() + //Benchmarks().NonAsyncBinds_taskBuilder() + //Benchmarks().NonAsyncBinds_FSharpAsync() + //Benchmarks().AsyncBinds_CSharpTasks() + //Benchmarks().AsyncBinds_task() + //Benchmarks().AsyncBinds_taskBuilder() + //Benchmarks().SingleSyncTask_CSharpTasks() + //Benchmarks().SingleSyncTask_task() + //Benchmarks().SingleSyncTask_taskBuilder() + //Benchmarks().SingleSyncTask_FSharpAsync() + + //printfn "Sample t1..." + //Tests.akSeqBuilder.Examples.t1() |> TaskSeq.iter (printfn "t1(): %s") + //printfn "Sample t2..." + //Tests.TaskSeqBuilder.Examples.t2() |> TaskSeq.iter (printfn "t2(): %s") + //printfn "Sample perf1(2)..." + //Tests.TaskSeqBuilder.Examples.perf1(2) |> TaskSeq.iter (printfn "perf1(2): %d") + //printfn "Sample perf1(3)..." + //Tests.TaskSeqBuilder.Examples.perf1(3) |> TaskSeq.iter (printfn "perf1(3): %d") + //printfn "Sample perf2..." + //Tests.TaskSeqBuilder.Examples.perf2() |> TaskSeq.iter (printfn "perf2: %d") + + //Tests.TaskSeq.Examples.perf2_AsyncSeq() |> AsyncSeq.toArrayAsync |> Async.RunSynchronously |> Array.sum |> (printf "%d."); printfn "" + //Tests.TaskSeq.Examples.perf2() |> TaskSeq.toArray |> Array.sum |> (printfn "%d.") + //TaskPerfCSharp.perf2_AsyncEnumerable() |> TaskSeq.toArray |> Array.sum |> (printfn "%d.") + + printfn "Running benchmarks..." + let results = BenchmarkRunner.Run() + 0 \ No newline at end of file diff --git a/tests/benchmarks/TaskPerf/TaskPerf.fsproj b/tests/benchmarks/TaskPerf/TaskPerf.fsproj new file mode 100644 index 00000000000..88e9af5c263 --- /dev/null +++ b/tests/benchmarks/TaskPerf/TaskPerf.fsproj @@ -0,0 +1,44 @@ + + + + net5.0 + Exe + true + + $(OtherFlags) --nowarn:1204 + + $(OtherFlags) --nowarn:57 + + + $(OtherFlags) --nowarn:3511 --nowarn:3513 + $(OtherFlags) --langversion:preview + $(OtherFlags) --define:PREVIEW + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/TaskPerf/array.fs b/tests/benchmarks/TaskPerf/array.fs new file mode 100644 index 00000000000..8c1409f1233 --- /dev/null +++ b/tests/benchmarks/TaskPerf/array.fs @@ -0,0 +1,192 @@ + +module Tests.ArrayBuilders + +open System +open System.Collections.Generic + +[] +module UsingInlinedCodeAndCollector = + + [] + type ArrayBuilderCollector<'T> = + [] + val mutable Result : ResizeArray<'T> + + member sm.Yield (value: 'T) = + match sm.Result with + | null -> + let ra = ResizeArray() + sm.Result <- ra + ra.Add(value) + | ra -> ra.Add(value) + + member sm.ToResizeArray() = + match sm.Result with + | null -> ResizeArray() + | ra -> ra + + member sm.ToArray() = + match sm.Result with + | null -> Array.empty + | ra -> ra.ToArray() + + type ArrayBuilderCode<'T> = delegate of byref> -> unit + + type ArrayBuilderViaCollector() = + + member inline _.Delay([] f: unit -> ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> (f()).Invoke &sm) + + member inline _.Zero() : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun _sm -> ()) + + member inline _.Combine([] part1: ArrayBuilderCode<'T>, [] part2: ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> + part1.Invoke &sm + part2.Invoke &sm) + + member inline _.While([] condition : unit -> bool, [] body : ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> + while condition() do + body.Invoke &sm) + + member inline _.TryWith([] body: ArrayBuilderCode<'T>, [] handler: exn -> ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> + try + body.Invoke &sm + with exn -> + (handler exn).Invoke &sm) + + member inline _.TryFinally([] body: ArrayBuilderCode<'T>, compensation : unit -> unit) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> + try + body.Invoke &sm + with _ -> + compensation() + reraise() + + compensation()) + + member inline b.Using(disp : #IDisposable, [] body: #IDisposable -> ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + // A using statement is just a try/finally with the finally block disposing if non-null. + b.TryFinally( + (fun sm -> (body disp).Invoke &sm), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline b.For(sequence: seq<'TElement>, [] body: 'TElement -> ArrayBuilderCode<'T>) : ArrayBuilderCode<'T> = + b.Using (sequence.GetEnumerator(), + (fun e -> b.While((fun () -> e.MoveNext()), (fun sm -> (body e.Current).Invoke &sm)))) + + member inline _.Yield (v: 'T) : ArrayBuilderCode<'T> = + ArrayBuilderCode<_>(fun sm -> + sm.Yield v) + + member inline b.YieldFrom (source: IEnumerable<'T>) : ArrayBuilderCode<'T> = + b.For(source, (fun value -> b.Yield(value))) + + member inline _.Run([] code: ArrayBuilderCode<'T>) : 'T[] = + let mutable sm = ArrayBuilderCollector<'T>() + code.Invoke &sm + sm.ToArray() + + let arrayNew = ArrayBuilderViaCollector() + +module Examples = + + let tinyVariableSizeNew () = + for i in 1 .. 1000000 do + arrayNew { + if i % 3 = 0 then + yield "b" + } |> Array.length |> ignore + + let tinyVariableSizeBuiltin () = + for i in 1 .. 1000000 do + [| + if i % 3 = 0 then + yield "b" + |] |> Array.length |> ignore + + let variableSizeNew () = + for i in 1 .. 1000000 do + arrayNew { + yield "a" + yield "b" + yield "b" + yield "b" + yield "b" + if i % 3 = 0 then + yield "b" + yield "b" + yield "b" + yield "b" + yield "c" + } |> Array.length |> ignore + + let variableSizeBuiltin () = + for i in 1 .. 1000000 do + [| + yield "a" + yield "b" + yield "b" + yield "b" + yield "b" + if i % 3 = 0 then + yield "b" + yield "b" + yield "b" + yield "b" + yield "c" + |] |> Array.length |> ignore + + let fixedSizeC () = + for i in 1 .. 1000000 do + arrayNew { + "a" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "c" + } |> Array.length |> ignore + + let fixedSizeBase () = + for i in 1 .. 1000000 do + [| + "a" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "c" + |] |> Array.length |> ignore + + let perf s f = + let t = System.Diagnostics.Stopwatch() + t.Start() + f() + t.Stop() + printfn "PERF: %s : %d" s t.ElapsedMilliseconds + + perf "tinyVariableSizeBuiltin" tinyVariableSizeBuiltin + perf "tinyVariableSizeNew " tinyVariableSizeNew + + perf "variableSizeBuiltin" variableSizeBuiltin + perf "variableSizeNew" variableSizeNew + + perf "fixedSizeBase" fixedSizeBase + perf "fixedSizeC" fixedSizeC + // let dumpSeq (t: IEnumerable<_>) = + // let e = t.GetEnumerator() + // while e.MoveNext() do + // printfn "yield %A" e.Current + // dumpSeq (t1()) + // dumpSeq (t2()) diff --git a/tests/benchmarks/TaskPerf/async2.fs b/tests/benchmarks/TaskPerf/async2.fs new file mode 100644 index 00000000000..06938716ae1 --- /dev/null +++ b/tests/benchmarks/TaskPerf/async2.fs @@ -0,0 +1,1131 @@ + +namespace FSharp.Control.Async2 + +open System.Runtime.CompilerServices + +#nowarn "42" +open System +open System.Threading +open System.Threading.Tasks +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers + +[] +module Utils = + let verbose = false + + let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() + +[] +type Async2StateMachineData<'T>() = + [] + val mutable cancellationToken : CancellationToken + [] + val mutable result : 'T + [] + val mutable builder : AsyncTaskMethodBuilder<'T> + [] + val mutable taken : bool + //// For tailcalls using 'return!' + //[] + //val mutable tailcallTarget: IAsync2Invocation<'T> + +and IAsync2Invokable<'T> = + abstract StartImmediate: CancellationToken -> IAsync2Invocation<'T> + +and [] IAsync2Invocation<'T> = + inherit IAsyncStateMachine + //abstract TailcallTarget: IAsync2Invocation<'T> + abstract CancellationToken: CancellationToken + abstract Task: Task<'T> + +and [] + Async2<'T>() = + + // F# requires that we implement interfaces even on an abstract class + interface IAsync2Invokable<'T> with + member _.StartImmediate(ct) = failwith "abstract" + + interface IAsync2Invocation<'T> with + //member _.TailcallTarget = failwith "abstract" + member _.CancellationToken = failwith "abstract" + member _.Task = failwith "abstract" + interface IAsyncStateMachine with + member _.MoveNext() = failwith "abstract" + member _.SetStateMachine(_state) = failwith "abstract" + + member inline x.StartImmediate(ct) = (x :> IAsync2Invokable<'T>).StartImmediate(ct) + +and [] + Async2<'Machine, 'T when 'Machine :> IAsyncStateMachine and 'Machine :> IResumableStateMachine>>() = + inherit Async2<'T>() + let initialThreadId = Environment.CurrentManagedThreadId + + [] + val mutable Machine : 'Machine + + //member internal ts.hijack() = (ts :> IAsync2Invocation<_>) + //let res = ts.Machine.Data.tailcallTarget + //match res with + //| null -> (ts :> IAsync2Invocation<_>) + //| tg -> + // match (tg :> IAsync2Invocation<_>).TailcallTarget with + // | null -> + // res + // | res2 -> + // // Cut out chains of tailcalls + // ts.Machine.Data.tailcallTarget <- res2 + // res2 + + interface IAsyncStateMachine with + member ts.MoveNext() = + MoveNext(&ts.Machine) + + //match ts.hijack() with + //| null -> + //| tg -> (tg :> IAsyncStateMachine).MoveNext() + + member ts.SetStateMachine(state) = + //printfn "SetStateMachine" + () + //ts.Machine.Data.builder.SetStateMachine(state) + + interface IAsync2Invokable<'T> with + member ts.StartImmediate(ct) = + let data = ts.Machine.Data + if (not data.taken && initialThreadId = Environment.CurrentManagedThreadId) then + data.taken <- true + data.cancellationToken <- ct + //printfn "creating" + data.builder <- AsyncTaskMethodBuilder<'T>.Create() + //printfn "starting" + data.builder.Start(&ts.Machine) + (ts :> IAsync2Invocation<_>) + else + let clone = ts.MemberwiseClone() :?> Async2<'Machine, 'T> + data.taken <- true + clone.Machine.Data.cancellationToken <- ct + clone.Machine.MoveNext() + (clone :> IAsync2Invocation<'T>) + + interface IAsync2Invocation<'T> with + member ts.CancellationToken = ts.Machine.Data.cancellationToken + member ts.Task = ts.Machine.Data.builder.Task + //member ts.TailcallTarget = ts.hijack() + +and Async2Code<'TOverall, 'T> = ResumableCode, 'T> +and Async2StateMachine<'T> = ResumableStateMachine> +and Async2ResumptionFunc<'T> = ResumptionFunc> +and Async2ResumptionDynamicInfo<'T> = ResumptionDynamicInfo> + +[] +type Async2Builder() = + + member inline _.Delay(f : unit -> Async2Code<'TOverall, 'T>) : Async2Code<'TOverall, 'T> = + Async2Code<'TOverall, 'T>(fun sm -> f().Invoke(&sm)) + + member inline _.Run(code : Async2Code<'T, 'T>) : Async2<'T> = + if __useResumableCode then + // This is the static implementation. A new struct type is created. + __stateMachine, Async2<'T>> + (MoveNextMethodImpl<_>(fun sm -> + //-- RESUMABLE CODE START + __resumeAt sm.ResumptionPoint + try + //printfn "at Run.MoveNext start" + //Console.WriteLine("[{0}] resuming by invoking {1}....", sm.MethodBuilder.Task.Id, hashq sm.ResumptionFunc ) + let __stack_code_fin = code.Invoke(&sm) + //printfn $"at Run.MoveNext, __stack_code_fin={__stack_code_fin}" + if __stack_code_fin then + //printfn $"at Run.MoveNext, done" + sm.Data.builder.SetResult(sm.Data.result) + + with exn -> + //Console.WriteLine("[{0}] SetException {1}", sm.MethodBuilder.Task.Id, exn) + sm.Data.builder.SetException(exn) + + //// tailcall + //match sm.Data.tailcallTarget with + //| null -> + // printfn $"at Run.MoveNext, await" + //| tg -> + // printfn $"at Run.MoveNext, hijack" + // let mutable tg = tg + // MoveNext(&tg) + //-- RESUMABLE CODE END + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> + let ts = Async2, 'T>() + ts.Machine <- sm + ts.Machine.Data <- Async2StateMachineData() + ts :> Async2<'T>)) + else + failwith "no dynamic implementation as yet" + // let initialResumptionFunc = Async2ResumptionFunc<'T>(fun sm -> code.Invoke(&sm)) + // let resumptionFuncExecutor = Async2ResumptionExecutor<'T>(fun sm f -> + // // TODO: add exception handling? + // if f.Invoke(&sm) then + // sm.ResumptionPoint <- -2) + // let setStateMachine = SetStateMachineMethodImpl<_>(fun sm f -> ()) + // sm.Machine.ResumptionFuncInfo <- (initialResumptionFunc, resumptionFuncExecutor, setStateMachine) + //sm.Start() + + + [] + member inline _.Zero() : Async2Code<'TOverall, unit> = + ResumableCode.Zero() + + member inline _.Combine(task1: Async2Code<'TOverall, unit>, task2: Async2Code<'TOverall, 'T>) : Async2Code<'TOverall, 'T> = + ResumableCode.Combine(task1, task2) + + member inline _.WhileAsync([] condition : unit -> ValueTask, body : Async2Code<'TOverall, unit>) : Async2Code<'TOverall, unit> = + let mutable condition_res = true + ResumableCode.While((fun () -> condition_res), + ResumableCode<_,_>(fun sm -> + let mutable __stack_condition_fin = true + let __stack_vtask = condition() + if __stack_vtask.IsCompleted then + __stack_condition_fin <- true + condition_res <- __stack_vtask.Result + else + let task = __stack_vtask.AsTask() + let mutable awaiter = task.GetAwaiter() + // This will yield with __stack_fin = false + // This will resume with __stack_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_condition_fin <- __stack_yield_fin + + if __stack_condition_fin then + condition_res <- task.Result + else + sm.Data.builder.AwaitUnsafeOnCompleted(&awaiter, &sm) + + if __stack_condition_fin then + if condition_res then + body.Invoke(&sm) + else + true + else + false + )) + + member inline _.While([] condition : unit -> bool, body : Async2Code<'TOverall, unit>) : Async2Code<'TOverall, unit> = + ResumableCode.While(condition, body) + + member inline _.TryWith(body : Async2Code<'TOverall, 'T>, catch : exn -> Async2Code<'TOverall, 'T>) : Async2Code<'TOverall, 'T> = + ResumableCode.TryWith(body, catch) + + member inline internal _.TryFinallyAsync(body: Async2Code<'TOverall, 'T>, compensation : unit -> Task) : Async2Code<'TOverall, 'T> = + ResumableCode.TryFinallyAsync(body, ResumableCode<_,_>(fun sm -> + let mutable __stack_condition_fin = true + let __stack_vtask = compensation() + if not __stack_vtask.IsCompleted then + let mutable awaiter = __stack_vtask.GetAwaiter() + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_condition_fin <- __stack_yield_fin + + if not __stack_condition_fin then + sm.Data.builder.AwaitUnsafeOnCompleted(&awaiter, &sm) + + __stack_condition_fin)) + + member inline _.TryFinally(body: Async2Code<'TOverall, 'T>, compensation : unit -> unit) : Async2Code<'TOverall, 'T> = + ResumableCode.TryFinally(body, ResumableCode<_,_>(fun sm -> compensation(); true)) + + member inline this.Using(resource : #IAsyncDisposable, body : #IAsyncDisposable -> Async2Code<'TOverall, 'T>) : Async2Code<'TOverall, 'T> = + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinallyAsync( + (fun sm -> (body resource).Invoke(&sm)), + (fun () -> + if not (isNull (box resource)) then + resource.DisposeAsync().AsTask() + else + Task.CompletedTask)) + + member inline _.Return (v: 'T) : Async2Code<'T, 'T> = + Async2Code<'T, 'T>(fun sm -> + sm.Data.result <- v + true) + + member inline _.Bind (task: Task<'TResult1>, continuation: ('TResult1 -> Async2Code<'TOverall, 'T>)) : Async2Code<'TOverall, 'T> = + Async2Code<'TOverall, 'T>(fun sm -> + let mutable awaiter = task.GetAwaiter() + let mutable __stack_fin = true + if not awaiter.IsCompleted then + // This will yield with __stack_fin2 = false + // This will resume with __stack_fin2 = true + let __stack_fin2 = ResumableCode.Yield().Invoke(&sm) + __stack_fin <- __stack_fin2 + + if __stack_fin then + let result = awaiter.GetResult() + (continuation result).Invoke(&sm) + else + sm.Data.builder.AwaitUnsafeOnCompleted(&awaiter, &sm) + false) + + member inline b.Bind (computation: Async2<'TResult1>, continuation: ('TResult1 -> Async2Code<'TOverall, 'T>)) : Async2Code<'TOverall, 'T> = + Async2Code<'TOverall, 'T>(fun sm -> + let ct = sm.Data.cancellationToken + b.Bind(computation.StartImmediate(ct).Task, continuation).Invoke(&sm)) + + member inline b.Bind (computation: Async<'TResult1>, continuation: ('TResult1 -> Async2Code<'TOverall, 'T>)) : Async2Code<'TOverall, 'T> = + Async2Code<'TOverall, 'T>(fun sm -> + let ct = sm.Data.cancellationToken + b.Bind(Async.StartImmediateAsTask(computation, ct), continuation).Invoke(&sm)) + + member inline b.ReturnFrom (task: Task<'T>) : Async2Code<'T, 'T> = + // No tailcalling to tasks + b.Bind(task, (fun res -> b.Return(res))) + + member inline b.ReturnFrom (computation: Async<'T>) : Async2Code<'T, 'T> = + // No tailcalling to Async + b.Bind(computation, (fun res -> b.Return(res))) + +// TODO - implement RFC for ReturnFromTailcall to make this safe + member inline b.ReturnFrom (other: Async2<'T>) : Async2Code<'T, 'T> = + b.Bind(other, (fun res -> b.Return(res))) + //Async2Code<'T, _>(fun sm -> + // printfn "setting hijack target and starting" + // sm.Data.tailcallTarget <- other + // // For tailcalls we return 'false' and re-run from the entry (trampoline) + // false + //) + + + +[] +module Async2 = + type Async2Builder with + member inline this.Using(resource : ('TResource :> IDisposable), body : ('TResource -> Async2Code<'TOverall, 'T>)) : Async2Code<'TOverall, 'T> = + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinally( + (fun sm -> (body resource).Invoke(&sm)), + (fun () -> if not (isNull (box resource)) then resource.Dispose())) + + member inline _.Bind< ^TaskLike, ^TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^TResult1)> + (task: ^TaskLike, continuation: (^TResult1 -> Async2Code<'TOverall, 'TResult2>)) : Async2Code<'TOverall, 'TResult2> = + + Async2Code<'TOverall, 'TResult2>(fun sm -> + if __useResumableCode then + //-- RESUMABLE CODE START + // Get an awaiter from the awaitable + let mutable awaiter = (^TaskLike: (member GetAwaiter : unit -> ^Awaiter)(task)) + + let mutable __stack_fin = true + if not (^Awaiter : (member get_IsCompleted : unit -> bool)(awaiter)) then + // This will yield with __stack_yield_fin = false + // This will resume with __stack_yield_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_fin <- __stack_yield_fin + + if __stack_fin then + let result = (^Awaiter : (member GetResult : unit -> ^TResult1)(awaiter)) + (continuation result).Invoke(&sm) + else + sm.Data.builder.AwaitUnsafeOnCompleted(&awaiter, &sm) + false + else + failwith "dynamic" //TaskWitnesses.CanBindDynamic< ^TaskLike, ^TResult1, 'TResult2, ^Awaiter , 'TOverall>(&sm, priority, task, continuation) + //-- RESUMABLE CODE END + ) + + member inline b.ReturnFrom< ^TaskLike, ^Awaiter, ^T + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^T)> + (task: ^TaskLike) : Async2Code< ^T, ^T> = + b.Bind(task, (fun res -> b.Return(res))) + + member inline this.For(sequence : seq<'TElement>, body : 'TElement -> Async2Code<'TOverall, unit>) : Async2Code<'TOverall, unit> = + // A for loop is just a using statement on the sequence's enumerator... + this.Using (sequence.GetEnumerator(), + // ... and its body is a while loop that advances the enumerator and runs the body on each element. + (fun e -> this.While((fun () -> e.MoveNext()), (fun sm -> (body e.Current).Invoke(&sm))))) + + let async2 = Async2Builder() + + let runSynchronously ct (t: Async2<'T>) = + let e = t.StartImmediate(ct) + e.Task.Result + + let cancellationTokenAsync = + async2.Run(Async2Code(fun sm -> + sm.Data.result <- sm.Data.cancellationToken + true)) + + let unitAsync = async2 { return () } + +[] +type Async2 = + + static member CancellationToken = cancellationTokenAsync + + static member CancelCheck () = unitAsync + + static member DefaultCancellationToken = Async.DefaultCancellationToken + + static member CancelDefaultToken() = Async.CancelDefaultToken() + + static member Catch (computation: Async2<'T>) = + async2 { try let! res = computation in return Choice1Of2 res with e -> return Choice2Of2 e } + + static member RunSynchronously (computation: Async2<'T>, ?timeout: int, ?cancellationToken:CancellationToken) = + // TODO: timeout + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let e = computation.StartImmediate(cancellationToken) + e.Task.Result + + static member StartImmediateAsTask (computation: Async2<'T>, ?cancellationToken ) : Task<'T> = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let e = computation.StartImmediate(cancellationToken) + e.Task + + static member StartImmediate(computation:Async2, ?cancellationToken) : unit = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let e = computation.StartImmediate(cancellationToken) + e |> ignore + + static member SwitchToNewThread() = + async2 { return! Task.CompletedTask.ConfigureAwait(false) } + + static member SwitchToThreadPool() : Async2 = + async2 { return! Task.CompletedTask.ConfigureAwait(false) } + + static member Start (computation: Async2, ?cancellationToken) = + let p = + async2 { + do! Async2.SwitchToThreadPool() + return! computation + } + Async2.StartImmediate(p, ?cancellationToken=cancellationToken) + + static member StartAsTask (computation: Async2<'T>, ?taskCreationOptions: TaskCreationOptions, ?cancellationToken) = + // TODO: taskCreationOptions + let p = + async2 { + do! Async2.SwitchToThreadPool() + return! computation + } + Async2.StartImmediateAsTask(p, ?cancellationToken=cancellationToken) + + static member StartChildAsTask (computation: Async2<'T>, ?taskCreationOptions) : Async2> = + async2 { + let! cancellationToken = cancellationTokenAsync + return Async2.StartAsTask (computation, ?taskCreationOptions=taskCreationOptions, cancellationToken=cancellationToken) + } + + + static member Sleep (millisecondsDueTime: int64) : Async2 = + // TODO: int64 millisecondsDueTime? + async2 { return! Task.Delay(int millisecondsDueTime)} + + static member Sleep (millisecondsDueTime: int32) : Async2 = + async2 { return! Task.Delay(millisecondsDueTime)} + + static member Sleep (dueTime: TimeSpan) = + async2 { return! Task.Delay(dueTime)} + + static member Ignore (computation: Async2<'T>) = + async2 { let! _res = computation in return () } + + static member AwaitTask (task:Task<'T>) : Async2<'T> = + async2 { return! task } + + static member AwaitTask (task:Task) : Async2 = + async2 { return! task } + + //static member FromContinuations (callback: ('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) : Async2<'T> = + // MakeAsync (fun ctxt -> + // if ctxt.IsCancellationRequested then + // ctxt.OnCancellation () + // else + // let mutable underCurrentThreadStack = true + // let mutable contToTailCall = None + // let thread = Thread.CurrentThread + // let latch = Latch() + // let once cont x = + // if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) + // if Thread.CurrentThread.Equals thread && underCurrentThreadStack then + // contToTailCall <- Some(fun () -> cont x) + // else if Trampoline.ThisThreadHasTrampoline then + // let syncCtxt = SynchronizationContext.Current + // ctxt.trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> cont x) |> unfake + // else + // ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont x ) |> unfake + // try + // callback (once ctxt.cont, (fun exn -> once ctxt.econt (ExceptionDispatchInfo.RestoreOrCapture exn)), once ctxt.ccont) + // with exn -> + // if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) + // let edi = ExceptionDispatchInfo.RestoreOrCapture exn + // ctxt.econt edi |> unfake + + // underCurrentThreadStack <- false + + // match contToTailCall with + // | Some k -> k() + // | _ -> fake()) + + //static member Parallel (computations: seq>) = Async.Parallel(computations, ?maxDegreeOfParallelism=None) + + //static member Parallel (computations: seq>, ?maxDegreeOfParallelism: int) = + // match maxDegreeOfParallelism with + // | Some x when x < 1 -> raise(System.ArgumentException(String.Format(SR.GetString(SR.maxDegreeOfParallelismNotPositive), x), "maxDegreeOfParallelism")) + // | _ -> () + + // MakeAsync (fun ctxt -> + // let tasks, result = + // try + // Seq.toArray computations, None // manually protect eval of seq + // with exn -> + // let edi = ExceptionDispatchInfo.RestoreOrCapture exn + // null, Some (ctxt.econt edi) + + // match result with + // | Some r -> r + // | None -> + // if tasks.Length = 0 then + // // must not be in a 'protect' if we call cont explicitly; if cont throws, it should unwind the stack, preserving Dev10 behavior + // ctxt.cont [| |] + // else + // ProtectedCode ctxt (fun ctxt -> + // let ctxtWithSync = DelimitSyncContext ctxt // manually resync + // let mutable count = tasks.Length + // let mutable firstExn = None + // let results = Array.zeroCreate tasks.Length + // // Attempt to cancel the individual operations if an exception happens on any of the other threads + // let innerCTS = new LinkedSubSource(ctxtWithSync.token) + + // let finishTask remaining = + // if (remaining = 0) then + // innerCTS.Dispose() + // match firstExn with + // | None -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont results) + // | Some (Choice1Of2 exn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) + // | Some (Choice2Of2 cexn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont cexn) + // else + // fake() + + // // recordSuccess and recordFailure between them decrement count to 0 and + // // as soon as 0 is reached dispose innerCancellationSource + + // let recordSuccess i res = + // results.[i] <- res + // finishTask(Interlocked.Decrement &count) + + // let recordFailure exn = + // // capture first exception and then decrement the counter to avoid race when + // // - thread 1 decremented counter and preempted by the scheduler + // // - thread 2 decremented counter and called finishTask + // // since exception is not yet captured - finishtask will fall into success branch + // match Interlocked.CompareExchange(&firstExn, Some exn, None) with + // | None -> + // // signal cancellation before decrementing the counter - this guarantees that no other thread can sneak to finishTask and dispose innerCTS + // // NOTE: Cancel may introduce reentrancy - i.e. when handler registered for the cancellation token invokes cancel continuation that will call 'recordFailure' + // // to correctly handle this we need to return decremented value, not the current value of 'count' otherwise we may invoke finishTask with value '0' several times + // innerCTS.Cancel() + // | _ -> () + // finishTask(Interlocked.Decrement &count) + + // // If maxDegreeOfParallelism is set but is higher then the number of tasks we have we set it back to None to fall into the simple + // // queue all items branch + // let maxDegreeOfParallelism = + // match maxDegreeOfParallelism with + // | None -> None + // | Some x when x >= tasks.Length -> None + // | Some _ as x -> x + + // // Simple case (no maxDegreeOfParallelism) just queue all the work, if we have maxDegreeOfParallelism set we start that many workers + // // which will make progress on the actual computations + // match maxDegreeOfParallelism with + // | None -> + // tasks |> Array.iteri (fun i p -> + // QueueAsync + // innerCTS.Token + // // on success, record the result + // (fun res -> recordSuccess i res) + // // on exception... + // (fun edi -> recordFailure (Choice1Of2 edi)) + // // on cancellation... + // (fun cexn -> recordFailure (Choice2Of2 cexn)) + // p + // |> unfake) + // | Some maxDegreeOfParallelism -> + // let mutable i = -1 + // let rec worker (trampolineHolder : TrampolineHolder) = + // if i < tasks.Length then + // let j = Interlocked.Increment &i + // if j < tasks.Length then + // if innerCTS.Token.IsCancellationRequested then + // let cexn = OperationCanceledException (innerCTS.Token) + // recordFailure (Choice2Of2 cexn) |> unfake + // worker trampolineHolder |> unfake + // else + // let taskCtxt = + // AsyncActivation.Create + // innerCTS.Token + // trampolineHolder + // (fun res -> recordSuccess j res |> unfake; worker trampolineHolder) + // (fun edi -> recordFailure (Choice1Of2 edi) |> unfake; worker trampolineHolder) + // (fun cexn -> recordFailure (Choice2Of2 cexn) |> unfake; worker trampolineHolder) + // tasks.[j].Invoke taskCtxt |> unfake + // fake() + // for x = 1 to maxDegreeOfParallelism do + // let trampolineHolder = TrampolineHolder() + // trampolineHolder.QueueWorkItemWithTrampoline (fun () -> + // worker trampolineHolder) + // |> unfake + + // fake())) + + //static member Sequential (computations: seq>) = Async.Parallel(computations, maxDegreeOfParallelism=1) + + //static member Choice(computations: Async2<'T option> seq) : Async2<'T option> = + // MakeAsync (fun ctxt -> + // let result = + // try Seq.toArray computations |> Choice1Of2 + // with exn -> ExceptionDispatchInfo.RestoreOrCapture exn |> Choice2Of2 + + // match result with + // | Choice2Of2 edi -> ctxt.econt edi + // | Choice1Of2 [||] -> ctxt.cont None + // | Choice1Of2 computations -> + // ProtectedCode ctxt (fun ctxt -> + // let ctxtWithSync = DelimitSyncContext ctxt + // let mutable count = computations.Length + // let mutable noneCount = 0 + // let mutable someOrExnCount = 0 + // let innerCts = new LinkedSubSource(ctxtWithSync.token) + + // let scont (result: 'T option) = + // let result = + // match result with + // | Some _ -> + // if Interlocked.Increment &someOrExnCount = 1 then + // innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont result) + // else + // fake() + + // | None -> + // if Interlocked.Increment &noneCount = computations.Length then + // innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont None) + // else + // fake() + + // if Interlocked.Decrement &count = 0 then + // innerCts.Dispose() + + // result + + // let econt (exn: ExceptionDispatchInfo) = + // let result = + // if Interlocked.Increment &someOrExnCount = 1 then + // innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) + // else + // fake() + + // if Interlocked.Decrement &count = 0 then + // innerCts.Dispose() + + // result + + // let ccont (exn: OperationCanceledException) = + // let result = + // if Interlocked.Increment &someOrExnCount = 1 then + // innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont exn) + // else + // fake() + + // if Interlocked.Decrement &count = 0 then + // innerCts.Dispose() + + // result + + // for c in computations do + // QueueAsync innerCts.Token scont econt ccont c |> unfake + + // fake())) + + /// StartWithContinuations, except the exception continuation is given an ExceptionDispatchInfo + //static member StartWithContinuationsUsingDispatchInfo(computation:Async2<'T>, continuation, exceptionContinuation, cancellationContinuation, ?cancellationToken) : unit = + // let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + // AsyncPrimitives.StartWithContinuations cancellationToken computation continuation exceptionContinuation cancellationContinuation + + //static member StartWithContinuations(computation:Async2<'T>, continuation, exceptionContinuation, cancellationContinuation, ?cancellationToken) : unit = + // Async.StartWithContinuationsUsingDispatchInfo(computation, continuation, (fun edi -> exceptionContinuation (edi.GetAssociatedSourceException())), cancellationContinuation, ?cancellationToken=cancellationToken) + + ///// Wait for a wait handle. Both timeout and cancellation are supported + //static member AwaitWaitHandle(waitHandle: WaitHandle, ?millisecondsTimeout:int) = + // let millisecondsTimeout = defaultArg millisecondsTimeout Threading.Timeout.Infinite + // if millisecondsTimeout = 0 then + // async.Delay(fun () -> + // let ok = waitHandle.WaitOne(0, exitContext=false) + // async.Return ok) + // else + // CreateDelimitedUserCodeAsync(fun ctxt -> + // let aux = ctxt.aux + // let rwh = ref (None: RegisteredWaitHandle option) + // let latch = Latch() + // let rec cancelHandler = + // Action(fun () -> + // if latch.Enter() then + // // if we got here - then we need to unregister RegisteredWaitHandle + trigger cancellation + // // entrance to TP callback is protected by latch - so savedCont will never be called + // lock rwh (fun () -> + // match !rwh with + // | None -> () + // | Some rwh -> rwh.Unregister null |> ignore) + // Async.Start (async2 { do (ctxt.ccont (OperationCanceledException(aux.token)) |> unfake) })) + + // and registration: CancellationTokenRegistration = aux.token.Register(cancelHandler) + + // let savedCont = ctxt.cont + // try + // lock rwh (fun () -> + // rwh := Some(ThreadPool.RegisterWaitForSingleObject + // (waitObject=waitHandle, + // callBack=WaitOrTimerCallback(fun _ timeOut -> + // if latch.Enter() then + // lock rwh (fun () -> rwh.Value.Value.Unregister null |> ignore) + // rwh := None + // registration.Dispose() + // ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCont (not timeOut)) |> unfake), + // state=null, + // millisecondsTimeOutInterval=millisecondsTimeout, + // executeOnlyOnce=true)) + // fake()) + // with _ -> + // if latch.Enter() then + // registration.Dispose() + // reraise() // reraise exception only if we successfully enter the latch (no other continuations were called) + // else + // fake() + // ) + + //static member AwaitIAsyncResult(iar: IAsyncResult, ?millisecondsTimeout): Async2 = + // async2 { if iar.CompletedSynchronously then + // return true + // else + // return! Async.AwaitWaitHandle(iar.AsyncWaitHandle, ?millisecondsTimeout=millisecondsTimeout) } + + + ///// Bind the result of a result cell, calling the appropriate continuation. + //static member BindResult (result: AsyncResult<'T>) : Async2<'T> = + // MakeAsync (fun ctxt -> + // (match result with + // | Ok v -> ctxt.cont v + // | Error exn -> ctxt.econt exn + // | Canceled exn -> ctxt.ccont exn) ) + + ///// Await and use the result of a result cell. The resulting async doesn't support cancellation + ///// or timeout directly, rather the underlying computation must fill the result if cancellation + ///// or timeout occurs. + //static member AwaitAndBindResult_NoDirectCancelOrTimeout(resultCell: ResultCell>) : Async2<'T> = + // async2 { + // let! result = resultCell.AwaitResult_NoDirectCancelOrTimeout + // return! Async.BindResult result + // } + + ///// Await the result of a result cell belonging to a child computation. The resulting async supports timeout and if + ///// it happens the child computation will be cancelled. The resulting async doesn't support cancellation + ///// directly, rather the underlying computation must fill the result if cancellation occurs. + //static member AwaitAndBindChildResult(innerCTS: CancellationTokenSource, resultCell: ResultCell>, millisecondsTimeout) : Async2<'T> = + // match millisecondsTimeout with + // | None | Some -1 -> + // resultCell |> Async.AwaitAndBindResult_NoDirectCancelOrTimeout + + // | Some 0 -> + // async2 { if resultCell.ResultAvailable then + // let res = resultCell.GrabResult() + // return res.Commit() + // else + // return raise (System.TimeoutException()) } + // | _ -> + // async2 { try + // if resultCell.ResultAvailable then + // let res = resultCell.GrabResult() + // return res.Commit() + // else + // let! ok = Async.AwaitWaitHandle (resultCell.GetWaitHandle(), ?millisecondsTimeout=millisecondsTimeout) + // if ok then + // let res = resultCell.GrabResult() + // return res.Commit() + // else // timed out + // // issue cancellation signal + // innerCTS.Cancel() + // // wait for computation to quiesce + // let! _ = Async.AwaitWaitHandle (resultCell.GetWaitHandle()) + // return raise (System.TimeoutException()) + // finally + // resultCell.Close() } + + + //static member FromBeginEnd(beginAction, endAction, ?cancelAction): Async2<'T> = + // async2 { let! cancellationToken = cancellationTokenAsync + // let resultCell = new ResultCell<_>() + + // let once = Once() + + // let registration: CancellationTokenRegistration = + + // let onCancel () = + // // Call the cancellation routine + // match cancelAction with + // | None -> + // // Register the result. This may race with a successful result, but + // // ResultCell allows a race and throws away whichever comes last. + // once.Do(fun () -> + // let canceledResult = Canceled (OperationCanceledException cancellationToken) + // resultCell.RegisterResult(canceledResult, reuseThread=true) |> unfake + // ) + // | Some cancel -> + // // If we get an exception from a cooperative cancellation function + // // we assume the operation has already completed. + // try cancel() with _ -> () + + // cancellationToken.Register(Action(onCancel)) + + // let callback = + // System.AsyncCallback(fun iar -> + // if not iar.CompletedSynchronously then + // // The callback has been activated, so ensure cancellation is not possible + // // beyond this point. + // match cancelAction with + // | Some _ -> + // registration.Dispose() + // | None -> + // once.Do(fun () -> registration.Dispose()) + + // // Run the endAction and collect its result. + // let res = + // try + // Ok(endAction iar) + // with exn -> + // let edi = ExceptionDispatchInfo.RestoreOrCapture exn + // Error edi + + // // Register the result. This may race with a cancellation result, but + // // ResultCell allows a race and throws away whichever comes last. + // resultCell.RegisterResult(res, reuseThread=true) |> unfake) + + // let (iar:IAsyncResult) = beginAction (callback, (null:obj)) + // if iar.CompletedSynchronously then + // registration.Dispose() + // return endAction iar + // else + // // Note: ok to use "NoDirectCancel" here because cancellation has been registered above + // // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method + // return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell } + + + //static member FromBeginEnd(arg, beginAction, endAction, ?cancelAction): Async2<'T> = + // Async.FromBeginEnd((fun (iar, state) -> beginAction(arg, iar, state)), endAction, ?cancelAction=cancelAction) + + //static member FromBeginEnd(arg1, arg2, beginAction, endAction, ?cancelAction): Async2<'T> = + // Async.FromBeginEnd((fun (iar, state) -> beginAction(arg1, arg2, iar, state)), endAction, ?cancelAction=cancelAction) + + //static member FromBeginEnd(arg1, arg2, arg3, beginAction, endAction, ?cancelAction): Async2<'T> = + // Async.FromBeginEnd((fun (iar, state) -> beginAction(arg1, arg2, arg3, iar, state)), endAction, ?cancelAction=cancelAction) + + //static member AsBeginEnd<'Arg, 'T> (computation:('Arg -> Async2<'T>)) : + // // The 'Begin' member + // ('Arg * System.AsyncCallback * obj -> System.IAsyncResult) * + // // The 'End' member + // (System.IAsyncResult -> 'T) * + // // The 'Cancel' member + // (System.IAsyncResult -> unit) = + // let beginAction = fun (a1, callback, state) -> AsBeginEndHelpers.beginAction ((computation a1), callback, state) + // beginAction, AsBeginEndHelpers.endAction<'T>, AsBeginEndHelpers.cancelAction<'T> + + //static member AwaitEvent(event:IEvent<'Delegate, 'T>, ?cancelAction) : Async2<'T> = + // async2 { let! cancellationToken = cancellationTokenAsync + // let resultCell = new ResultCell<_>() + // // Set up the handlers to listen to events and cancellation + // let once = Once() + // let rec registration: CancellationTokenRegistration= + // let onCancel () = + // // We've been cancelled. Call the given cancellation routine + // match cancelAction with + // | None -> + // // We've been cancelled without a cancel action. Stop listening to events + // event.RemoveHandler del + // // Register the result. This may race with a successful result, but + // // ResultCell allows a race and throws away whichever comes last. + // once.Do(fun () -> resultCell.RegisterResult(Canceled (OperationCanceledException cancellationToken), reuseThread=true) |> unfake) + // | Some cancel -> + // // If we get an exception from a cooperative cancellation function + // // we assume the operation has already completed. + // try cancel() with _ -> () + // cancellationToken.Register(Action(onCancel)) + + // and del = + // FuncDelegate<'T>.Create<'Delegate>(fun eventArgs -> + // // Stop listening to events + // event.RemoveHandler del + // // The callback has been activated, so ensure cancellation is not possible beyond this point + // once.Do(fun () -> registration.Dispose()) + // let res = Ok eventArgs + // // Register the result. This may race with a cancellation result, but + // // ResultCell allows a race and throws away whichever comes last. + // resultCell.RegisterResult(res, reuseThread=true) |> unfake) + + // // Start listening to events + // event.AddHandler del + + // // Return the async computation that allows us to await the result + // // Note: ok to use "NoDirectCancel" here because cancellation has been registered above + // // Note: ok to use "NoDirectTimeout" here because no timeout parameter to this method + // return! Async.AwaitAndBindResult_NoDirectCancelOrTimeout resultCell } + + //static member StartChild (computation:Async2<'T>, ?millisecondsTimeout) = + // async2 { + // let resultCell = new ResultCell<_>() + // let! cancellationToken = cancellationTokenAsync + // let innerCTS = new CancellationTokenSource() // innerCTS does not require disposal + // let mutable ctsRef = innerCTS + // let reg = cancellationToken.Register( + // (fun () -> + // match ctsRef with + // | null -> () + // | otherwise -> otherwise.Cancel())) + // do QueueAsync + // innerCTS.Token + // // since innerCTS is not ever Disposed, can call reg.Dispose() without a safety Latch + // (fun res -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Ok res, reuseThread=true)) + // (fun edi -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Error edi, reuseThread=true)) + // (fun err -> ctsRef <- null; reg.Dispose(); resultCell.RegisterResult (Canceled err, reuseThread=true)) + // computation + // |> unfake + + // return Async.AwaitAndBindChildResult(innerCTS, resultCell, millisecondsTimeout) } + + //static member SwitchToContext syncContext = + // let t = + // Task.Factory.StartNew( + // (fun () -> ()), // this will use current synchronization context + // CancellationToken.None, + // TaskCreationOptions.None, + // TaskScheduler. .FromCurrentSynchronizationContext()) + // async2 { match syncContext with + // | null -> + // // no synchronization context, just switch to the thread pool + // do! Async.SwitchToThreadPool() + // | syncCtxt -> + // // post the continuation to the synchronization context + // return! CreateSwitchToAsync syncCtxt } + + //static member OnCancel interruption = + // async2 { let! cancellationToken = cancellationTokenAsync + // // latch protects CancellationTokenRegistration.Dispose from being called twice + // let latch = Latch() + // let rec handler () = + // try + // if latch.Enter() then registration.Dispose() + // interruption () + // with _ -> () + // and registration: CancellationTokenRegistration = cancellationToken.Register(Action(handler)) + // return { new System.IDisposable with + // member this.Dispose() = + // // dispose CancellationTokenRegistration only if cancellation was not requested. + // // otherwise - do nothing, disposal will be performed by the handler itself + // if not cancellationToken.IsCancellationRequested then + // if latch.Enter() then registration.Dispose() } } + + //static member TryCancelled (computation: Async2<'T>, compensation) = + // CreateWhenCancelledAsync compensation computation + +//module CommonExtensions = + +// type System.IO.Stream with + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member stream.AsyncRead(buffer: byte[], ?offset, ?count) = +// let offset = defaultArg offset 0 +// let count = defaultArg count buffer.Length +// Async.FromBeginEnd (buffer, offset, count, stream.BeginRead, stream.EndRead) + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member stream.AsyncRead count = +// async2 { +// let buffer = Array.zeroCreate count +// let mutable i = 0 +// while i < count do +// let! n = stream.AsyncRead(buffer, i, count - i) +// i <- i + n +// if n = 0 then +// raise(System.IO.EndOfStreamException()) +// return buffer } + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member stream.AsyncWrite(buffer:byte[], ?offset:int, ?count:int) = +// let offset = defaultArg offset 0 +// let count = defaultArg count buffer.Length +// Async.FromBeginEnd (buffer, offset, count, stream.BeginWrite, stream.EndWrite) + + +//module WebExtensions = + +// type System.Net.WebRequest with +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member req.AsyncGetResponse() : Async2 = + +// let mutable canceled = false // WebException with Status = WebExceptionStatus.RequestCanceled can be raised in other situations except cancellation, use flag to filter out false positives + +// // Use CreateTryWithFilterAsync to allow propagation of exception without losing stack +// Async.FromBeginEnd(beginAction=req.BeginGetResponse, +// endAction = req.EndGetResponse, +// cancelAction = fun() -> canceled <- true; req.Abort()) +// |> CreateTryWithFilterAsync (fun exn -> +// match exn with +// | :? System.Net.WebException as webExn +// when webExn.Status = System.Net.WebExceptionStatus.RequestCanceled && canceled -> + +// Some (Async.BindResult(AsyncResult.Canceled (OperationCanceledException webExn.Message))) +// | _ -> +// None) + +// type System.Net.WebClient with +// member inline private this.Download(event: IEvent<'T, _>, handler: _ -> 'T, start, result) = +// let downloadAsync = +// Async.FromContinuations (fun (cont, econt, ccont) -> +// let userToken = obj() +// let rec delegate' (_: obj) (args: #ComponentModel.AsyncCompletedEventArgs) = +// // ensure we handle the completed event from correct download call +// if userToken = args.UserState then +// event.RemoveHandler handle +// if args.Cancelled then +// ccont (OperationCanceledException()) +// elif isNotNull args.Error then +// econt args.Error +// else +// cont (result args) +// and handle = handler delegate' +// event.AddHandler handle +// start userToken +// ) + +// async2 { +// use! _holder = Async.OnCancel(fun _ -> this.CancelAsync()) +// return! downloadAsync +// } + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member this.AsyncDownloadString (address:Uri) : Async2 = +// this.Download( +// event = this.DownloadStringCompleted, +// handler = (fun action -> Net.DownloadStringCompletedEventHandler action), +// start = (fun userToken -> this.DownloadStringAsync(address, userToken)), +// result = (fun args -> args.Result) +// ) + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member this.AsyncDownloadData (address:Uri) : Async2 = +// this.Download( +// event = this.DownloadDataCompleted, +// handler = (fun action -> Net.DownloadDataCompletedEventHandler action), +// start = (fun userToken -> this.DownloadDataAsync(address, userToken)), +// result = (fun args -> args.Result) +// ) + +// [] // give the extension member a 'nice', unmangled compiled name, unique within this module +// member this.AsyncDownloadFile (address:Uri, fileName:string) : Async2 = +// this.Download( +// event = this.DownloadFileCompleted, +// handler = (fun action -> ComponentModel.AsyncCompletedEventHandler action), +// start = (fun userToken -> this.DownloadFileAsync(address, fileName, userToken)), +// result = (fun _ -> ()) +// ) + +module Examples = + + let t1 () = + async2 { + printfn "in t1" + do! Async2.Sleep 100 + printfn "resuming t1" + + return "a" + } + + let testTailcallTiny () = + async2 { + return! t1() + } + let rec testTailcall (n: int) = + async2 { + if n % 100 = 0 then + printfn $"in t1, n = {n}" + if n > 0 then + return! testTailcall(n-1) + //yield () + } + + //let t2 () = + // async2 { + // printfn "in t2" + // yield "d" + // printfn "in t2 b" + // for x in t1 () do + // printfn "t2 - got %A" x + // yield "e" + // let! v = + // task { + // printfn "hey yo" + // do! Task.Delay(200) + // } + // yield "[T1]" + x + // let! v = + // task { + // printfn "hey yo" + // do! Task.Delay(10) + // } + // yield "f" + // } + + let perf1 (x: int) = + async2 { + return 1 + } + + //let perf1_AsyncSeq (x: int) = + // FSharp.Control.AsyncSeqExtensions.asyncSeq { + // yield 1 + // yield 2 + // if x >= 2 then + // yield 3 + // yield 4 + // } + + //let perf2_AsyncSeq () = + // FSharp.Control.AsyncSeqExtensions.asyncSeq { + // for i1 in perf1_AsyncSeq 3 do + // for i2 in perf1_AsyncSeq 3 do + // for i3 in perf1_AsyncSeq 3 do + // for i4 in perf1_AsyncSeq 3 do + // for i5 in perf1_AsyncSeq 3 do + // yield! perf1_AsyncSeq i5 + // } + + let dumpAsync2 (t: Async2<_>) = + printfn "-----" + let e = t.StartImmediate(CancellationToken()) + let res = e.Task.Result + printfn "result: %A" res + + //dumpAsync2 (t1()) + dumpAsync2 (testTailcallTiny()) + ////dumpAsync2 (t2()) + + //printfn "t1() = %A" (Async2.toArray (t1())) + //printfn "testTailcallTiny() = %A" (Async2.toArray (testTailcallTiny())) + //dumpAsync2 (testTailcall(100000)) + //printfn "t2() = %A" (Async2.toArray (t2())) + + //printfn "perf2() = %A" (Async2.toArray (perf2()) |> Array.sum) + diff --git a/tests/benchmarks/TaskPerf/async2.fsi b/tests/benchmarks/TaskPerf/async2.fsi new file mode 100644 index 00000000000..9398b1223c2 --- /dev/null +++ b/tests/benchmarks/TaskPerf/async2.fsi @@ -0,0 +1,255 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace rec FSharp.Control.Async2 + +open System +open System.Threading +open System.Threading.Tasks +open FSharp.Core.CompilerServices +open System.Runtime.CompilerServices + +[] +type Async2StateMachineData<'T> = + new: unit -> Async2StateMachineData<'T> + [] + val mutable cancellationToken: CancellationToken + [] + val mutable result: 'T + [] + val mutable builder: AsyncTaskMethodBuilder<'T> + [] + val mutable taken: bool + //// For tailcalls using 'return!' + //[] + //val mutable tailcallTarget: IAsync2Invocation<'T> + +type Async2Code<'TOverall, 'T> = ResumableCode, 'T> +and Async2StateMachine<'T> = ResumableStateMachine> +and Async2ResumptionFunc<'T> = ResumptionFunc> +and Async2ResumptionDynamicInfo<'T> = ResumptionDynamicInfo> + +type IAsync2Invokable<'T> = + abstract StartImmediate: CancellationToken -> IAsync2Invocation<'T> + +type IAsync2Invocation<'T> = + inherit IAsyncStateMachine + //abstract TailcallTarget: IAsync2Invocation<'T> + abstract CancellationToken: CancellationToken + abstract Task: Task<'T> + +[] +type Async2<'T> = + interface IAsync2Invokable<'T> + interface IAsync2Invocation<'T> + interface IAsyncStateMachine + member inline StartImmediate: ct: CancellationToken -> IAsync2Invocation<'T> + +[] +type Async2<'Machine, 'T when 'Machine :> IAsyncStateMachine and 'Machine :> IResumableStateMachine>> = + new : unit -> Async2<'Machine, 'T> + inherit Async2<'T> + [] + val mutable Machine: 'Machine + interface IAsyncStateMachine + interface IAsync2Invokable<'T> + interface IAsync2Invocation<'T> + +[] +type Async2 = + + static member RunSynchronously: computation:Async2<'T> * ?timeout: int * ?cancellationToken:CancellationToken-> 'T + + static member Start: computation:Async2 * ?cancellationToken:CancellationToken -> unit + + static member StartAsTask: computation:Async2<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T> +(* + static member StartChildAsTask: computation:Async2<'T> * ?taskCreationOptions:TaskCreationOptions -> Async2> +*) + + static member Catch: computation:Async2<'T> -> Async2> + + (* + static member TryCancelled: computation:Async2<'T> * compensation:(OperationCanceledException -> unit) -> Async2<'T> + + static member OnCancel: interruption: (unit -> unit) -> Async2 + *) + + static member CancellationToken: Async2 + + static member CancelDefaultToken: unit -> unit + + static member DefaultCancellationToken: CancellationToken + + //---------- Parallelism +(* + static member StartChild: computation:Async2<'T> * ?millisecondsTimeout: int -> Async2> + + static member Parallel: computations:seq> -> Async2<'T[]> + + static member Parallel: computations:seq> * ?maxDegreeOfParallelism: int -> Async2<'T[]> + + static member Sequential: computations:seq> -> Async2<'T[]> + + static member Choice: computations:seq> -> Async2<'T option> +*) + static member SwitchToNewThread: unit -> Async2 + + static member SwitchToThreadPool: unit -> Async2 + +(* + static member SwitchToContext: syncContext:System.Threading.SynchronizationContext -> Async2 + + static member FromContinuations: callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async2<'T> + + static member AwaitEvent: event:IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async2<'T> when 'Del: delegate<'T,unit> and 'Del :> System.Delegate + + static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout:int -> Async2 + + static member AwaitIAsyncResult: iar: System.IAsyncResult * ?millisecondsTimeout:int -> Async2 +*) + static member AwaitTask: task: Task<'T> -> Async2<'T> + + static member AwaitTask: task: Task -> Async2 + + static member Sleep: millisecondsDueTime:int -> Async2 + + static member Ignore: computation: Async2<'T> -> Async2 +(* + static member StartWithContinuations: + computation:Async2<'T> * + continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * + ?cancellationToken:CancellationToken-> unit +*) + static member StartImmediate: + computation:Async2 * ?cancellationToken:CancellationToken-> unit + + static member StartImmediateAsTask: + computation:Async2<'T> * ?cancellationToken:CancellationToken-> Task<'T> + +(* +type Async2Return + +[] +type Async2Activation<'T> = + + member IsCancellationRequested: bool + + member OnSuccess: 'T -> Async2Return + + member OnExceptionRaised: unit -> unit + + member OnCancellation: unit -> Async2Return + +[] +module Async2Primitives = + + val MakeAsync: body:(Async2Activation<'T> -> Async2Return) -> Async2<'T> + + val Invoke: computation: Async2<'T> -> ctxt:Async2Activation<'T> -> Async2Return + + val CallThenInvoke: ctxt:Async2Activation<'T> -> result1:'U -> part2:('U -> Async2<'T>) -> Async2Return + + val Bind: ctxt:Async2Activation<'T> -> part1:Async2<'U> -> part2:('U -> Async2<'T>) -> Async2Return + + val TryFinally: ctxt:Async2Activation<'T> -> computation: Async2<'T> -> finallyFunction: (unit -> unit) -> Async2Return + + val TryWith: ctxt:Async2Activation<'T> -> computation: Async2<'T> -> catchFunction: (Exception -> Async2<'T> option) -> Async2Return + +*) + +[] +type Async2Builder = + + member inline Run: code : Async2Code<'T, 'T> -> Async2<'T> + + [] + member inline Zero: unit -> Async2Code<'TOverall, unit> + + member inline Combine: task1: Async2Code<'TOverall, unit> * task2: Async2Code<'TOverall, 'T> -> Async2Code<'TOverall, 'T> + + member inline While: [] condition: (unit -> bool) * body: Async2Code<'TOverall, unit> -> Async2Code<'TOverall, unit> + + member inline Return: v: 'T -> Async2Code<'T, 'T> + + member inline ReturnFrom: task: Task<'T> -> Async2Code<'T, 'T> + + member inline ReturnFrom: computation: Async<'T> -> Async2Code<'T, 'T> + + member inline ReturnFrom: other: Async2<'T> -> Async2Code<'T, 'T> + + member inline Delay: f: (unit -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline Using: resource: ('TResource :> IAsyncDisposable) * body: ('TResource -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline TryFinally: body: Async2Code<'TOverall, 'T> * compensation: (unit -> unit) -> Async2Code<'TOverall, 'T> + + member inline TryWith: body: Async2Code<'TOverall, 'T> * catch: (exn -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline Bind: task: Task<'TResult1> * continuation: ('TResult1 -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline Bind: computation: Async<'TResult1> * continuation: ('TResult1 -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline Bind: computation: Async2<'TResult1> * continuation: ('TResult1 -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + +[] +module Async2 = + type Async2Builder with + member inline ReturnFrom< ^TaskLike, ^Awaiter, ^T + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^T)> + : task: ^TaskLike -> Async2Code< ^T, ^T> + + member inline Bind< ^TaskLike, ^TResult1, 'TResult2, ^Awaiter , 'TOverall + when ^TaskLike: (member GetAwaiter: unit -> ^Awaiter) + and ^Awaiter :> ICriticalNotifyCompletion + and ^Awaiter: (member get_IsCompleted: unit -> bool) + and ^Awaiter: (member GetResult: unit -> ^TResult1)> + : task: ^TaskLike * continuation: (^TResult1 -> Async2Code<'TOverall, 'TResult2>) -> Async2Code<'TOverall, 'TResult2> + + member inline Using: resource: ('TResource :> IDisposable) * body: ('TResource -> Async2Code<'TOverall, 'T>) -> Async2Code<'TOverall, 'T> + + member inline For: sequence: seq<'TElement> * body: ('TElement -> Async2Code<'TOverall, unit>) -> Async2Code<'TOverall, unit> + + val async2: Async2Builder +//[] +///// A module of extension members providing asynchronous operations for some basic CLI types related to concurrency and I/O. +///// +///// Async Programming +//module CommonExtensions = + +// type System.IO.Stream with + +// /// Returns an asynchronous computation that will read from the stream into the given buffer. +// /// The buffer to read into. +// /// An optional offset as a number of bytes in the stream. +// /// An optional number of bytes to read from the stream. +// /// +// /// An asynchronous computation that will read from the stream into the given buffer. +// /// Thrown when the sum of offset and count is longer than +// /// the buffer length. +// /// Thrown when offset or count is negative. +// member AsyncRead: buffer:byte[] * ?offset:int * ?count:int -> Async2 + +// /// Returns an asynchronous computation that will read the given number of bytes from the stream. +// /// +// /// The number of bytes to read. +// /// +// /// An asynchronous computation that returns the read byte[] when run. +// member AsyncRead: count:int -> Async2 + +// /// Returns an asynchronous computation that will write the given bytes to the stream. +// /// +// /// The buffer to write from. +// /// An optional offset as a number of bytes in the stream. +// /// An optional number of bytes to write to the stream. +// /// +// /// An asynchronous computation that will write the given bytes to the stream. +// /// Thrown when the sum of offset and count is longer than +// /// the buffer length. +// /// Thrown when offset or count is negative. +// member AsyncWrite: buffer:byte[] * ?offset:int * ?count:int -> Async2 + + diff --git a/tests/benchmarks/TaskPerf/coroutine.fs b/tests/benchmarks/TaskPerf/coroutine.fs new file mode 100644 index 00000000000..04c4defdbfc --- /dev/null +++ b/tests/benchmarks/TaskPerf/coroutine.fs @@ -0,0 +1,279 @@ + + +// This is a sample and test showing how to use resumable code to implement +// coroutines with tailcall support +// +// A coroutine is a value of type Coroutine normally constructed using this form: +// +// coroutine { +// printfn "in t1" +// yield () +// printfn "hey" +// } +// +// We also support `yield!` and tailcalls using the (non-standard) syntax of `return!`/ReturnFrom + +module Tests.Coroutines + +open System +open System.Runtime.CompilerServices +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers +open FSharp.Core.LanguagePrimitives.IntrinsicOperators +open FSharp.Collections + +let verbose = false + +/// Helpers to do zero-allocation call to interface methods on structs +[] +module internal Helpers = + let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() + let inline SetStateMachine(x: byref<'T> when 'T :> IAsyncStateMachine, state) = x.SetStateMachine(state) + let inline GetResumptionPoint(x: byref<'T> when 'T :> IResumableStateMachine<'Data>) = x.ResumptionPoint + +/// This is the type of coroutines +[] +type Coroutine() = + + /// Checks if the coroutine is completed + abstract IsCompleted: bool + + /// Executes the coroutine until the next 'yield' + abstract MoveNext: unit -> unit + + /// Gets the tailcall target if the coroutine has executed a `return!` + abstract TailcallTarget: Coroutine option + +/// This is the implementation of Coroutine with respect to a particular struct state machine type. +and [] + Coroutine<'Machine when 'Machine : struct + and 'Machine :> IAsyncStateMachine + and 'Machine :> ICoroutineStateMachine>() = + inherit Coroutine() + + // The state machine struct + [] + val mutable Machine: 'Machine + + override cr.IsCompleted = + match cr.TailcallTarget with + | None -> + GetResumptionPoint(&cr.Machine) = -1 + | Some tg -> + tg.IsCompleted + + override cr.TailcallTarget = + CoroutineStateMachineData.GetHijackTarget(&cr.Machine) + + override cr.MoveNext() = + match cr.TailcallTarget with + | None -> //if verbose then printfn $"[{cr.Id}] move" + MoveNext(&cr.Machine) + | Some tg -> + match tg.TailcallTarget with + | None -> tg.MoveNext() + | Some tg2 -> + // Cut out chains of tailcalls + CoroutineStateMachineData.SetHijackTarget(&cr.Machine, tg2) + tg2.MoveNext() +/// This extra data stored in ResumableStateMachine (and it's templated copies using __stateMachine) +/// It only contains one field, the hijack target for tailcalls. +and [] + CoroutineStateMachineData = + + /// This is used for tailcalls using 'return!' + [] + val mutable TailcallTarget: Coroutine option + + static member GetHijackTarget(x: byref<'Machine> when 'Machine :> IResumableStateMachine) = + x.Data.TailcallTarget + + static member SetHijackTarget(x: byref<'Machine>, tg: Coroutine) : unit when 'Machine :> IResumableStateMachine = + let mutable newData = CoroutineStateMachineData() + newData.TailcallTarget <- Some tg + x.Data <- newData + +/// These are standard definitions filling in the 'Data' parameter of each +and ICoroutineStateMachine = IResumableStateMachine +and CoroutineStateMachine = ResumableStateMachine +and CoroutineResumptionFunc = ResumptionFunc +and CoroutineResumptionDynamicInfo = ResumptionDynamicInfo +and CoroutineCode = ResumableCode + + +/// The builder for tailcalls, defined using resumable code combinators +type CoroutineBuilder() = + + member inline _.Delay(f : unit -> CoroutineCode) : CoroutineCode = ResumableCode.Delay(f) + + /// Create the state machine and outer execution logic + member inline _.Run(code : CoroutineCode) : Coroutine = + if __useResumableCode then + __stateMachine + + // IAsyncStateMachine.MoveNext + (MoveNextMethodImpl<_>(fun sm -> + //-- RESUMABLE CODE START + __resumeAt sm.ResumptionPoint + let __stack_code_fin = code.Invoke(&sm) + if __stack_code_fin then + sm.ResumptionPoint <- -1 // indicates complete + else + // Goto request + match sm.Data.TailcallTarget with + | Some tg -> tg.MoveNext() // recurse + | None -> () + //-- RESUMABLE CODE END + )) + + // IAsyncStateMachine.SetStateMachine + (SetStateMachineMethodImpl<_>(fun sm state -> SetStateMachine(&sm, state))) + + // Box the coroutine. In this example we don't start execution of the coroutine. + (AfterCode<_,_>(fun sm -> + let mutable cr = Coroutine() + cr.Machine <- sm + cr :> Coroutine)) + else + // The dynamic implementation + let initialResumptionFunc = CoroutineResumptionFunc(fun sm -> code.Invoke(&sm)) + let resumptionInfo = + { new CoroutineResumptionDynamicInfo(initialResumptionFunc) with + member info.MoveNext(sm) = + if info.ResumptionFunc.Invoke(&sm) then + sm.ResumptionPoint <- -1 + member info.SetStateMachine(sm, state) = () + } + let mutable cr = Coroutine() + cr.Machine.ResumptionDynamicInfo <- resumptionInfo + cr :> Coroutine + + /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression. + [] + member inline _.Zero() : CoroutineCode = ResumableCode.Zero() + + /// Chains together a step with its following step. + /// Note that this requires that the first step has no result. + /// This prevents constructs like `task { return 1; return 2; }`. + member inline _.Combine(code1: CoroutineCode, code2: CoroutineCode) : CoroutineCode = + ResumableCode.Combine(code1, code2) + + /// Builds a step that executes the body while the condition predicate is true. + member inline _.While ([] condition : unit -> bool, body : CoroutineCode) : CoroutineCode = + ResumableCode.While(condition, body) + + /// Wraps a step in a try/with. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + member inline _.TryWith (body: CoroutineCode, catch: exn -> CoroutineCode) : CoroutineCode = + ResumableCode.TryWith(body, catch) + + /// Wraps a step in a try/finally. This catches exceptions both in the evaluation of the function + /// to retrieve the step, and in the continuation of the step (if any). + member inline _.TryFinally (body: CoroutineCode, [] compensation : unit -> unit) : CoroutineCode = + ResumableCode.TryFinally(body, ResumableCode<_,_>(fun _ -> compensation(); true)) + + member inline _.Using (resource : 'Resource, body : 'Resource -> CoroutineCode) : CoroutineCode when 'Resource :> IDisposable = + ResumableCode.Using(resource, body) + + member inline _.For (sequence : seq<'T>, body : 'T -> CoroutineCode) : CoroutineCode = + ResumableCode.For(sequence, body) + + member inline _.Yield (_dummy: unit) : CoroutineCode = + ResumableCode.Yield() + + // The implementation of `yield!` + member inline _.YieldFrom (other: Coroutine) : CoroutineCode = + ResumableCode.While((fun () -> not other.IsCompleted), CoroutineCode(fun sm -> + other.MoveNext() + let __stack_other_fin = other.IsCompleted + if not __stack_other_fin then + // This will yield with __stack_yield_fin = false + // This will resume with __stack_yield_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_yield_fin + else + true)) + + // The implementation of `return!`, non-standard for tailcalls + member inline _.ReturnFrom (other: Coroutine) : CoroutineCode = + ResumableCode<_,_>(fun sm -> + sm.Data.TailcallTarget <- Some other + // For tailcalls we return 'false' and re-run from the entry (trampoline) + false + // We could do this immediately with future cut-out, though this will stack-dive on sync code. + // We could also trampoline less frequently via a counter + // b.YieldFrom(other).Invoke(&sm) + ) + +[] +module CoroutineBuilder = + + let coroutine = CoroutineBuilder() + + +module Examples = + + let t1 () = + coroutine { + printfn "in t1" + yield () + printfn "hey ho" + yield () + yield! + coroutine{ + printfn "hey yo" + yield () + printfn "hey go" + } + } + + let testTailcallTiny () = + coroutine { + return! t1() + } + let rec testTailcall (n: int) = + coroutine { + if n % 100 = 0 then printfn $"in t1, n = {n}" + yield () + if n > 0 then + return! testTailcall(n-1) + } + + + let t2 () = + coroutine { + printfn "in t2" + yield () + printfn "in t2 b" + yield! t1() + //for x in t1 () do + // printfn "t2 - got %A" x + // yield () + // yield! + // coroutine { + // printfn "hey yo" + // } + // yield "[T1]" + x + yield! + coroutine { + printfn "hey yo" + //do! Task.Delay(10) + } + yield () + } + + + let dumpCoroutine (t: Coroutine) = + printfn "-----" + while ( //if verbose then printfn $"[{t.Id}] calling t.MoveNext, will resume at {t.ResumptionPoint}"; + t.MoveNext() + not t.IsCompleted) do + () // printfn "yield" + + dumpCoroutine (t1()) + dumpCoroutine (testTailcallTiny()) + dumpCoroutine (testTailcall(1000000)) + dumpCoroutine (t2()) + + + diff --git a/tests/benchmarks/TaskPerf/coroutineBasic.fs b/tests/benchmarks/TaskPerf/coroutineBasic.fs new file mode 100644 index 00000000000..8f8d707b6de --- /dev/null +++ b/tests/benchmarks/TaskPerf/coroutineBasic.fs @@ -0,0 +1,169 @@ +// This is a sample and test showing how to use resumable code to implement coroutines +// +// A coroutine is a value of type Coroutine normally constructed using this form: +// +// coroutine { +// printfn "in t1" +// yield () +// printfn "hey" +// } + +module rec Tests.CoroutinesBasic + +open System +open System.Runtime.CompilerServices +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers + +/// This is the type of coroutines +[] +type Coroutine() = + + /// Checks if the coroutine is completed + abstract IsCompleted: bool + + /// Executes the coroutine until the next 'yield' + abstract MoveNext: unit -> unit + +/// Helpers to do zero-allocation call to interface methods on structs +[] +module internal Helpers = + let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() + let inline GetResumptionPoint(x: byref<'T> when 'T :> IResumableStateMachine<'Data>) = x.ResumptionPoint + let inline SetData(x: byref<'T> when 'T :> IResumableStateMachine<'Data>, data) = x.Data <- data + +/// This is the implementation of Coroutine with respect to a particular struct state machine type. +[] +type Coroutine<'Machine when 'Machine : struct + and 'Machine :> IAsyncStateMachine + and 'Machine :> ICoroutineStateMachine>() = + inherit Coroutine() + + // The state machine struct + [] + val mutable Machine: 'Machine + + override cr.IsCompleted = + GetResumptionPoint(&cr.Machine) = -1 + + override cr.MoveNext() = + MoveNext(&cr.Machine) + +/// This extra data stored in ResumableStateMachine (and it's templated copies using __stateMachine) +/// In this example there is just an ID +[] +type CoroutineStateMachineData(id: int) = + member _.Id = id + +let nextId = + let mutable n = 0 + fun () -> n <- n + 1; n + +/// These are standard definitions filling in the 'Data' parameter of each +type ICoroutineStateMachine = IResumableStateMachine +type CoroutineStateMachine = ResumableStateMachine +type CoroutineResumptionFunc = ResumptionFunc +type CoroutineResumptionDynamicInfo = ResumptionDynamicInfo +type CoroutineCode = ResumableCode + +type CoroutineBuilder() = + + member inline _.Delay(f : unit -> CoroutineCode) : CoroutineCode = ResumableCode.Delay(f) + + /// Used to represent no-ops like the implicit empty "else" branch of an "if" expression. + [] + member inline _.Zero() : CoroutineCode = ResumableCode.Zero() + + // The implementation of `e1; e2` + member inline _.Combine(code1: CoroutineCode, code2: CoroutineCode) : CoroutineCode = + ResumableCode.Combine(code1, code2) + + // The implementation of `while` + member inline _.While ([] condition : unit -> bool, body : CoroutineCode) : CoroutineCode = + ResumableCode.While(condition, body) + + // The implementation of `try/with` + member inline _.TryWith (body: CoroutineCode, catch: exn -> CoroutineCode) : CoroutineCode = + ResumableCode.TryWith(body, catch) + + // The implementation of `try/finally` + member inline _.TryFinally (body: CoroutineCode, [] compensation : unit -> unit) : CoroutineCode = + ResumableCode.TryFinally(body, ResumableCode<_,_>(fun _ -> compensation(); true)) + + // The implementation of `use` + member inline _.Using (resource : 'Resource, body : 'Resource -> CoroutineCode) : CoroutineCode when 'Resource :> IDisposable = + ResumableCode.Using(resource, body) + + // The implementation of `for` + member inline _.For (sequence : seq<'T>, body : 'T -> CoroutineCode) : CoroutineCode = + ResumableCode.For(sequence, body) + + // The implementation of `yield` + member inline _.Yield (_dummy: unit) : CoroutineCode = + ResumableCode.Yield() + + // The implementation of `yield!` + member inline _.YieldFrom (other: Coroutine) : CoroutineCode = + ResumableCode.While((fun () -> not other.IsCompleted), CoroutineCode(fun sm -> + other.MoveNext() + let __stack_other_fin = other.IsCompleted + if not __stack_other_fin then + ResumableCode.Yield().Invoke(&sm) + else + true)) + + /// Create the state machine and outer execution logic + member inline _.Run(code : CoroutineCode) : Coroutine = + if __useResumableCode then + __stateMachine + + // IAsyncStateMachine.MoveNext + (MoveNextMethodImpl<_>(fun sm -> + __resumeAt sm.ResumptionPoint + let __stack_code_fin = code.Invoke(&sm) + if __stack_code_fin then + sm.ResumptionPoint <- -1 // indicates complete + )) + + // IAsyncStateMachine.SetStateMachine + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + + // Box the coroutine. In this example we don't start execution of the coroutine. + (AfterCode<_,_>(fun sm -> + let mutable cr = Coroutine() + SetData(&cr.Machine, CoroutineStateMachineData(nextId())) + cr.Machine <- sm + cr :> Coroutine)) + else + // The dynamic implementation + let initialResumptionFunc = CoroutineResumptionFunc(fun sm -> code.Invoke(&sm)) + let resumptionInfo = + { new CoroutineResumptionDynamicInfo(initialResumptionFunc) with + member info.MoveNext(sm) = + if info.ResumptionFunc.Invoke(&sm) then + sm.ResumptionPoint <- -1 + member info.SetStateMachine(sm, state) = () + } + let mutable cr = Coroutine() + cr.Machine.ResumptionDynamicInfo <- resumptionInfo + cr :> Coroutine + +[] +module CoroutineBuilder = + + let coroutine = CoroutineBuilder() + +module Examples = + let t1 () = + coroutine { + printfn "in t1" + yield () + printfn "hey ho" + yield () + } + let dumpCoroutine (t: Coroutine) = + printfn "-----" + while ( t.MoveNext() + not t.IsCompleted) do + printfn "yield" + diff --git a/tests/benchmarks/TaskPerf/empty.fs b/tests/benchmarks/TaskPerf/empty.fs new file mode 100644 index 00000000000..41ce540367b --- /dev/null +++ b/tests/benchmarks/TaskPerf/empty.fs @@ -0,0 +1,5 @@ + +module Tests.Empty + + +let _ = printfn "hello" \ No newline at end of file diff --git a/tests/benchmarks/TaskPerf/list.fs b/tests/benchmarks/TaskPerf/list.fs new file mode 100644 index 00000000000..14240aac764 --- /dev/null +++ b/tests/benchmarks/TaskPerf/list.fs @@ -0,0 +1,195 @@ + +module Tests.ListBuilders + +#if FSHARP_CORE_HAS_LIST_COLLECTOR +open System +open System.Collections.Generic +open FSharp.Core.CompilerServices + +#nowarn "57" + +[] +module UsingInlinedCodeAndCollector = + [] + type ListBuilderCollector<'T> = + [] + val mutable Collector : ListCollector<'T> + + member sm.Yield (value: 'T) = sm.Collector.Yield(value) + + member sm.ToList() = sm.Collector.ToList() + + type ListBuilderCode<'T> = delegate of byref> -> unit + + type ListBuilderViaCollector() = + + member inline _.Delay([] f: unit -> ListBuilderCode<'T>) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> (f()).Invoke &sm) + + member inline _.Zero() : ListBuilderCode<'T> = + ListBuilderCode<_>(fun _sm -> ()) + + member inline _.Combine([] part1: ListBuilderCode<'T>, [] part2: ListBuilderCode<'T>) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> + part1.Invoke &sm + part2.Invoke &sm) + + member inline _.While([] condition : unit -> bool, [] body : ListBuilderCode<'T>) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> + while condition() do + body.Invoke &sm) + + member inline _.TryWith([] body: ListBuilderCode<'T>, [] handler: exn -> ListBuilderCode<'T>) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> + try + body.Invoke &sm + with exn -> + (handler exn).Invoke &sm) + + member inline _.TryFinally([] body: ListBuilderCode<'T>, compensation : unit -> unit) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> + try + body.Invoke &sm + with _ -> + compensation() + reraise() + + compensation()) + + member inline b.Using(disp : #IDisposable, [] body: #IDisposable -> ListBuilderCode<'T>) : ListBuilderCode<'T> = + // A using statement is just a try/finally with the finally block disposing if non-null. + b.TryFinally( + (fun sm -> (body disp).Invoke &sm), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline b.For(sequence: seq<'TElement>, [] body: 'TElement -> ListBuilderCode<'T>) : ListBuilderCode<'T> = + b.Using (sequence.GetEnumerator(), + (fun e -> b.While((fun () -> e.MoveNext()), (fun sm -> (body e.Current).Invoke &sm)))) + + member inline _.Yield (v: 'T) : ListBuilderCode<'T> = + ListBuilderCode<_>(fun sm -> + sm.Yield v) + + member inline b.YieldFrom (source: IEnumerable<'T>) : ListBuilderCode<'T> = + b.For(source, (fun value -> b.Yield(value))) + + member inline _.Run([] code: ListBuilderCode<'T>) : 'T list = + let mutable sm = ListBuilderCollector<'T>() + code.Invoke &sm + sm.ToList() + + let listc = ListBuilderViaCollector() + +module Examples = + let t1C () = + listc { + printfn "in t1" + yield "a" + let x = "d" + yield "b" + yield "c" + x + } + + let t2C () = + listc { + printfn "in t2" + yield "d" + for x in t1C () do + printfn "t2 - got %A" x + yield "e" + yield "[T1]" + x + yield "f" + } + + let tinyVariableSizeNew () = + for i in 1 .. 1000000 do + listc { + if i % 3 = 0 then + yield "b" + } |> List.length |> ignore + + let tinyVariableSizeBuiltin () = + for i in 1 .. 1000000 do + [ + if i % 3 = 0 then + yield "b" + ] |> List.length |> ignore + + let variableSizeNew () = + for i in 1 .. 1000000 do + listc { + yield "a" + yield "b" + yield "b" + yield "b" + yield "b" + if i % 3 = 0 then + yield "b" + yield "b" + yield "b" + yield "b" + yield "c" + } |> List.length |> ignore + + let variableSizeBuiltin () = + for i in 1 .. 1000000 do + [ + yield "a" + yield "b" + yield "b" + yield "b" + yield "b" + if i % 3 = 0 then + yield "b" + yield "b" + yield "b" + yield "b" + yield "c" + ] |> List.length |> ignore + + let fixedSizeC () = + for i in 1 .. 1000000 do + listc { + "a" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "c" + } |> List.length |> ignore + + let fixedSizeBase () = + for i in 1 .. 1000000 do + [ + "a" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "b" + "c" + ] |> List.length |> ignore + + let perf s f = + let t = System.Diagnostics.Stopwatch() + t.Start() + f() + t.Stop() + printfn "PERF: %s : %d" s t.ElapsedMilliseconds + + perf "tinyVariableSizeBuiltin" tinyVariableSizeBuiltin + perf "tinyVariableSizeNew " tinyVariableSizeNew + + perf "variableSizeBuiltin" variableSizeBuiltin + perf "variableSizeNew" variableSizeNew + + perf "fixedSizeBase" fixedSizeBase + perf "fixedSizeC" fixedSizeC +#endif \ No newline at end of file diff --git a/tests/benchmarks/TaskPerf/option.fs b/tests/benchmarks/TaskPerf/option.fs new file mode 100644 index 00000000000..20003378273 --- /dev/null +++ b/tests/benchmarks/TaskPerf/option.fs @@ -0,0 +1,310 @@ + +module Tests.OptionBuilders + +open System + +type OptionCode<'T> = unit -> 'T voption + +type OptionBuilderUsingInlineIfLambdaBase() = + + member inline _.Delay([] f : unit -> OptionCode<'T>) : OptionCode<'T> = + (fun () -> (f())()) + // Note, not "f()()" - the F# compiler optimzier likes arguments to match lamdas in order to preserve + // argument evaluation order, so for "(f())()" the optimizer reduces one lambda then another, while "f()()" doesn't + + member inline _.Combine([] task1: OptionCode, [] task2: OptionCode<'T>) : OptionCode<'T> = + (fun () -> + match task1() with + | ValueNone -> ValueNone + | ValueSome() -> task2()) + + member inline _.Bind(res1: 'T1 option, [] task2: ('T1 -> OptionCode<'T>)) : OptionCode<'T> = + (fun () -> + match res1 with + | None -> ValueNone + | Some v -> (task2 v)()) + + member inline _.Bind(res1: 'T1 voption, [] task2: ('T1 -> OptionCode<'T>)) : OptionCode<'T> = + (fun () -> + match res1 with + | ValueNone -> ValueNone + | ValueSome v -> (task2 v)()) + + member inline _.While([] condition : unit -> bool, [] body : OptionCode) : OptionCode = + (fun () -> + let mutable proceed = true + while proceed && condition() do + match body() with + | ValueNone -> proceed <- false + | ValueSome () -> () + ValueSome(())) + + member inline _.TryWith([] body : OptionCode<'T>, [] catch : exn -> OptionCode<'T>) : OptionCode<'T> = + (fun () -> + try + body() + with exn -> + (catch exn)()) + + member inline _.TryFinally([] body: OptionCode<'T>, [] compensation : unit -> unit) : OptionCode<'T> = + (fun () -> + let res = + try + body() + with _ -> + compensation() + reraise() + + compensation() + res) + + member inline this.Using(disp: #IDisposable, [] body: #IDisposable -> OptionCode<'T>) : OptionCode<'T> = + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinally( + (fun () -> (body disp)()), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline this.For(sequence : seq<'TElement>, [] body : 'TElement -> OptionCode) : OptionCode = + this.Using (sequence.GetEnumerator(), + (fun e -> this.While((fun () -> e.MoveNext()), (fun () -> (body e.Current)())))) + + member inline _.Return (value: 'T) : OptionCode<'T> = + (fun () -> + ValueSome value) + + member inline this.ReturnFrom (source: option<'T>) : OptionCode<'T> = + (fun () -> + match source with Some x -> ValueOption.Some x | None -> ValueOption.None) + + member inline this.ReturnFrom (source: voption<'T>) : OptionCode<'T> = + (fun () -> source) + +type OptionBuilderUsingInlineIfLambda() = + inherit OptionBuilderUsingInlineIfLambdaBase() + + member inline _.Run([] code : OptionCode<'T>) : 'T option = + match code () with + | ValueNone -> None + | ValueSome v -> Some v + +type ValueOptionBuilderUsingInlineIfLambda() = + inherit OptionBuilderUsingInlineIfLambdaBase() + + member inline _.Run([] code : OptionCode<'T>) : 'T voption = + code() + +let optionNew = OptionBuilderUsingInlineIfLambda() +let voptionNew = ValueOptionBuilderUsingInlineIfLambda() + + +type SlowOptionBuilder() = + member inline _.Zero() = None + + member inline _.Return(x: 'T) = Some x + + member inline _.ReturnFrom(m: 'T option) = m + + member inline _.Bind(m: 'T option, f) = Option.bind f m + + member inline _.Delay(f: unit -> _) = f + + member inline _.Run(f) = f() + + member this.TryWith(delayedExpr, handler) = + try this.Run(delayedExpr) + with exn -> handler exn + + member this.TryFinally(delayedExpr, compensation) = + try this.Run(delayedExpr) + finally compensation() + + member this.Using(resource:#IDisposable, body) = + this.TryFinally(this.Delay(fun ()->body resource), fun () -> match box resource with null -> () | _ -> resource.Dispose()) + +let optionOld = SlowOptionBuilder() + +type SlowValueOptionBuilder() = + member inline _.Zero() = ValueNone + + member inline _.Return(x: 'T) = ValueSome x + + member inline _.ReturnFrom(m: 'T voption) = m + + member inline _.Bind(m: 'T voption, f) = ValueOption.bind f m + + member inline _.Delay(f: unit -> _) = f + + member inline _.Run(f) = f() + + member inline this.TryWith(delayedExpr, handler) = + try this.Run(delayedExpr) + with exn -> handler exn + + member inline this.TryFinally(delayedExpr, compensation) = + try this.Run(delayedExpr) + finally compensation() + + member inline this.Using(resource:#IDisposable, body) = + this.TryFinally(this.Delay(fun ()->body resource), fun () -> match box resource with null -> () | _ -> resource.Dispose()) + +let voptionOld = SlowValueOptionBuilder() + +module Examples = + + + let multiStepOldBuilder () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + optionOld { + try + let! x1 = (if i % 5 <> 2 then Some i else None) + let! x2 = (if i % 3 <> 1 then Some i else None) + let! x3 = (if i % 3 <> 1 then Some i else None) + let! x4 = (if i % 3 <> 1 then Some i else None) + res <- res + 1 + return x1 + x2 + x3 + x4 + with e -> + return failwith "unexpected" + } + v |> ignore + res + + let multiStepOldBuilderV () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + voptionOld { + try + let! x1 = (if i % 5 <> 2 then ValueSome i else ValueNone) + let! x2 = (if i % 3 <> 1 then ValueSome i else ValueNone) + let! x3 = (if i % 3 <> 1 then ValueSome i else ValueNone) + let! x4 = (if i % 3 <> 1 then ValueSome i else ValueNone) + res <- res + 1 + return x1 + x2 + x3 + x4 + with e -> + return failwith "unexpected" + } + v |> ignore + res + + let multiStepNoBuilder () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + try + match (if i % 5 <> 2 then Some i else None) with + | None -> None + | Some x1 -> + match (if i % 3 <> 1 then Some i else None) with + | None -> None + | Some x2 -> + match (if i % 3 <> 1 then Some i else None) with + | None -> None + | Some x3 -> + match (if i % 3 <> 1 then Some i else None) with + | None -> None + | Some x4 -> + res <- res + 1 + Some (x1 + x2 + x3 + x4) + with e -> + failwith "unexpected" + v |> ignore + res + + let multiStepNoBuilderV () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + try + match (if i % 5 <> 2 then ValueSome i else ValueNone) with + | ValueNone -> ValueNone + | ValueSome x1 -> + match (if i % 3 <> 1 then ValueSome i else ValueNone) with + | ValueNone -> ValueNone + | ValueSome x2 -> + match (if i % 3 <> 1 then ValueSome i else ValueNone) with + | ValueNone -> ValueNone + | ValueSome x3 -> + match (if i % 3 <> 1 then ValueSome i else ValueNone) with + | ValueNone -> ValueNone + | ValueSome x4 -> + res <- res + 1 + ValueSome (x1 + x2 + x3 + x4) + with e -> + failwith "unexpected" + v |> ignore + res + + let multiStepNewBuilder () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + optionNew { + try + let! x1 = (if i % 5 <> 2 then Some i else None) + let! x2 = (if i % 3 <> 1 then Some i else None) + let! x3 = (if i % 3 <> 1 then Some i else None) + let! x4 = (if i % 3 <> 1 then Some i else None) + res <- res + 1 + return x1 + x2 + x3 + x4 + with e -> + return failwith "unexpected" + } + v |> ignore + res + + + let multiStepNewBuilderV () = + let mutable res = 0 + for i in 1 .. 1000000 do + let v = + voptionNew { + try + let! x1 = (if i % 5 <> 2 then ValueSome i else ValueNone) + let! x2 = (if i % 3 <> 1 then ValueSome i else ValueNone) + let! x3 = (if i % 3 <> 1 then ValueSome i else ValueNone) + let! x4 = (if i % 3 <> 1 then ValueSome i else ValueNone) + res <- res + 1 + return x1 + x2 + x3 + x4 + with e -> + return failwith "unexpected" + } + v |> ignore + res + + // let perf s f = + // let t = System.Diagnostics.Stopwatch() + // t.Start() + // for i in 1 .. 100 do + // f() |> ignore + // t.Stop() + // printfn "PERF: %s : %d" s t.ElapsedMilliseconds + + // printfn "check %d = %d = %d"(multiStepStateMachineBuilder()) (multiStepNoBuilder()) (multiStepOldBuilder()) + + // perf "perf (state mechine option)" multiStepStateMachineBuilder + // perf "perf (no builder option)" multiStepNoBuilder + // perf "perf (slow builder option)" multiStepOldBuilder + + // printfn "check %d = %d = %d" (multiStepStateMachineBuilderV()) (multiStepNoBuilder()) (multiStepOldBuilder()) + // perf "perf (state mechine voption)" multiStepStateMachineBuilderV + // perf "perf (no builder voption)" multiStepNoBuilderV + // perf "perf (slow builder voption)" multiStepOldBuilderV + +module A = + + let multiStepNewBuilder (i) = + let mutable res = 0 + optionNew { + try + let! x1 = (if i % 5 <> 2 then Some i else None) + let! x2 = (if i % 3 <> 1 then Some i else None) + let! x3 = (if i % 3 <> 1 then Some i else None) + let! x4 = (if i % 3 <> 1 then Some i else None) + res <- res + 1 + return x1 + x2 + x3 + x4 + with e -> + return failwith "unexpected" + } + diff --git a/tests/benchmarks/TaskPerf/option2.fs b/tests/benchmarks/TaskPerf/option2.fs new file mode 100644 index 00000000000..7d911b68890 --- /dev/null +++ b/tests/benchmarks/TaskPerf/option2.fs @@ -0,0 +1,25 @@ + +module Tests.OptionBuilderUsingInlineIfLambda + +open System + + + // let perf s f = + // let t = System.Diagnostics.Stopwatch() + // t.Start() + // for i in 1 .. 100 do + // f() |> ignore + // t.Stop() + // printfn "PERF: %s : %d" s t.ElapsedMilliseconds + + // printfn "check %d = %d = %d"(multiStepInlineIfLambdaBuilder()) (multiStepNoBuilder()) (multiStepOldBuilder()) + + // perf "perf (state mechine option)" multiStepInlineIfLambdaBuilder + // perf "perf (no builder option)" multiStepNoBuilder + // perf "perf (slow builder option)" multiStepOldBuilder + + // printfn "check %d = %d = %d" (multiStepInlineIfLambdaBuilderV()) (multiStepNoBuilder()) (multiStepOldBuilder()) + // perf "perf (state mechine voption)" multiStepInlineIfLambdaBuilderV + // perf "perf (no builder voption)" multiStepNoBuilderV + // perf "perf (slow builder voption)" multiStepOldBuilderV + diff --git a/tests/benchmarks/TaskPerf/seq2.fs b/tests/benchmarks/TaskPerf/seq2.fs new file mode 100644 index 00000000000..5df130c6eae --- /dev/null +++ b/tests/benchmarks/TaskPerf/seq2.fs @@ -0,0 +1,262 @@ + +module Tests.Seq2 + +#nowarn "42" +open System +open System.Collections +open System.Collections.Generic +open System.Runtime.CompilerServices +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers + +[] +type SeqStateMachine<'T>() = + let disposalStack = ResizeArray<(unit -> unit)>() + + /// Proceed to the next state or raise an exception. Returns true if completed + abstract Step : unit -> bool + + member val Current : 'T voption = ValueNone with get, set + + member val ResumptionPoint: int = 0 with get, set + + member val ResumptionFunc: (SeqStateMachine<'T> -> bool) = Unchecked.defaultof<_> with get, set + + interface IEnumerable with + member this.GetEnumerator() = + // TODO: make new object if needed + (this :> IEnumerator) + + interface IEnumerable<'T> with + member this.GetEnumerator() = + // TODO: make new object if needed + (this :> IEnumerator<'T>) + + interface IDisposable with + member __.Dispose() = + let mutable exn = None + for d in Seq.rev disposalStack do + try + d() + with e -> + exn <- Some e // keep the last exception - TODO - check this + match exn with + | None -> () + | Some e -> raise e + + interface IEnumerator with + + member __.Reset() = failwith "no reset supported" + member sm.Current = box sm.Current + member sm.MoveNext() = sm.Step() + + interface IEnumerator<'T> with + member sm.Current = match sm.Current with ValueNone -> failwith "no value available yet" | ValueSome x -> x + + member __.PushDispose (f: unit -> unit) = disposalStack.Add(f) + + member __.PopDispose () = disposalStack.RemoveAt(disposalStack.Count - 1) + + [] + member sm.Start() = (sm :> IEnumerable<'T>) + +type SeqCode<'T> = SeqStateMachine<'T> -> bool + +type SeqBuilder() = + + [] + member inline __.Delay(__expand_f : unit -> SeqCode<'T>) : SeqCode<'T> = (fun sm -> __expand_f () sm) + + [] + member inline __.Run(__expand_code : SeqCode<'T>) : IEnumerable<'T> = + if __useResumableCode then + (__resumableStateMachine + { new SeqStateMachine<'T>() with + member sm.Step () = + __resumeAt sm.ResumptionPoint + __expand_code sm }).Start() + else + let sm = + { new SeqStateMachine<'T>() with + member sm.Step () = + sm.ResumptionFunc sm } + sm.ResumptionFunc <- __expand_code + sm.Start() + + [] + member inline __.Zero() : SeqCode<'T> = + (fun _sm -> true) + + [] + member inline __.Combine(__expand_task1: SeqCode<'T>, __expand_task2: SeqCode<'T>) : SeqCode<'T> = + (fun sm -> + if __useResumableCode then + let __stack_step = __expand_task1 sm + if __stack_step then + __expand_task2 sm + else + false + else + let completed = __expand_task1 sm + if completed then + __expand_task2 sm + else + // If state machines are not supported, then we must adjust the resumption to also run __expand_task2 on completion + let rec resume rf = + (fun (sm: SeqStateMachine<_>) -> + let completed = rf sm + if completed then + __expand_task2 sm + else + sm.ResumptionFunc <- resume sm.ResumptionFunc + false) + + sm.ResumptionFunc <- resume sm.ResumptionFunc + false) + + [] + member inline __.While(__expand_condition : unit -> bool, __expand_body : SeqCode<'T>) : SeqCode<'T> = + (fun sm -> + if __useResumableCode then + let mutable __stack_completed = false + while __stack_completed && __expand_condition() do + // NOTE: The body of the 'while' may contain await points, resuming may branch directly into the while loop + let __stack_step = __expand_body sm + // If we make it to the assignment we prove we've made a step + __stack_completed <- __stack_step + __stack_completed + else + let rec repeat sm = + if __expand_condition() then + let step = __expand_body sm + if step then + repeat sm + else + //Console.WriteLine("[{0}] rebinding ResumptionFunc for While", sm.MethodBuilder.Task.Id) + sm.ResumptionFunc <- resume sm.ResumptionFunc + false + else + true + and resume mf sm = + //Console.WriteLine("[{0}] resume WhileLoop body", sm.MethodBuilder.Task.Id) + let step = mf sm + if step then + repeat sm + else + //Console.WriteLine("[{0}] rebinding ResumptionFunc for While", sm.MethodBuilder.Task.Id) + sm.ResumptionFunc <- resume sm.ResumptionFunc + false + + repeat sm) + + [] + member inline __.TryWith(__expand_body : SeqCode<'T>, __expand_catch : exn -> SeqCode<'T>) : SeqCode<'T> = + (fun sm -> + if __useResumableCode then + let mutable __stack_completed = false + let mutable __stack_caught = false + let mutable __stack_savedExn = Unchecked.defaultof<_> + try + // The try block may contain await points. + let __stack_step = __expand_body sm + // If we make it to the assignment we prove we've made a step + __stack_completed <- __stack_step + with exn -> + __stack_caught <- true + __stack_savedExn <- exn + + if __stack_caught then + // Place the catch code outside the catch block + __expand_catch __stack_savedExn sm + else + __stack_completed + else + failwith "tbd") + + [] + member inline __.TryFinally(__expand_body: SeqCode<'T>, compensation : unit -> unit) : SeqCode<'T> = + (fun sm -> + let mutable completed = false + sm.PushDispose compensation + try + let __stack_step = __expand_body sm + // If we make it to the assignment we prove we've made a step without an exception + completed <- __stack_step + with _ -> + sm.PopDispose() + compensation() + reraise() + + if completed then + sm.PopDispose() + compensation() + completed) + + [] + member inline this.Using(disp : #IDisposable, __expand_body : #IDisposable -> SeqCode<'T>) = + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinally( + (fun sm -> __expand_body disp sm), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + [] + member inline this.For(sequence : seq<'TElement>, __expand_body : 'TElement -> SeqCode<'T>) : SeqCode<'T> = + // A for loop is just a using statement on the sequence's enumerator... + this.Using (sequence.GetEnumerator(), + // ... and its body is a while loop that advances the enumerator and runs the body on each element. + (fun e -> this.While((fun () -> e.MoveNext()), (fun sm -> __expand_body e.Current sm)))) + + [] + member inline __.Yield (v: 'T) : SeqCode<'T> = + (fun sm -> + if __useResumableCode then + match __resumableEntry() with + | Some contID -> + sm.ResumptionPoint <- contID + sm.Current <- ValueSome v + false + | None -> + sm.Current <- ValueNone + true + else + let cont (sm: SeqStateMachine<'T>) = + sm.Current <- ValueNone + true + sm.ResumptionFunc <- cont + sm.Current <- ValueSome v + false) + + [] + member inline this.YieldFrom (source: IEnumerable<'T>) : SeqCode<'T> = + this.For(source, (fun v -> this.Yield v)) + +let seq2 = SeqBuilder() + +module Examples = + + let t1 () = + seq2 { + printfn "in t1" + yield "a" + let x = 1 + yield "b" + yield "c" + } + + let t2 () = + seq2 { + printfn "in t2" + yield "d" + for x in t1 () do + printfn "t2 - got %A" x + yield "e" + yield "[T1]" + x + yield "f" + } + + let dumpSeq (t: IEnumerable<_>) = + let e = t.GetEnumerator() + while e.MoveNext() do + printfn "yield %A" e.Current + dumpSeq (t1()) + dumpSeq (t2()) diff --git a/tests/benchmarks/TaskPerf/sync.fs b/tests/benchmarks/TaskPerf/sync.fs new file mode 100644 index 00000000000..9a4ccb5b72f --- /dev/null +++ b/tests/benchmarks/TaskPerf/sync.fs @@ -0,0 +1,88 @@ + +module Tests.SyncBuilder + +open System + +type SyncCode<'T> = unit -> 'T + +type SyncBuilder() = + + member inline _.Delay([] f: unit -> SyncCode<'T>) : SyncCode<'T> = + (fun () -> (f())()) + + member inline _.Run([] code : SyncCode<'T>) : 'T = + code() + +#if PREVIEW + [] +#endif + member inline _.Zero() : SyncCode< unit> = + (fun () -> ()) + + member inline _.Return (x: 'T) : SyncCode<'T> = + (fun () -> x) + + member inline _.Combine([] code1: SyncCode, [] code2: SyncCode<'T>) : SyncCode<'T> = + (fun () -> + code1() + code2()) + + member inline _.While([] condition: unit -> bool, [] body: SyncCode) : SyncCode = + (fun () -> + while condition() do + body()) + + member inline _.TryWith([] body: SyncCode<'T>, [] catch: exn -> 'T) : SyncCode<'T> = + (fun () -> + try + body() + with exn -> + catch exn) + + member inline _.TryFinally([] body: SyncCode<'T>, compensation: unit -> unit) : SyncCode<'T> = + (fun () -> + let __stack_step = + try + body() + with _ -> + compensation() + reraise() + compensation() + __stack_step) + + member inline this.Using(disp : #IDisposable, [] body: #IDisposable -> SyncCode<'T>) : SyncCode<'T> = + this.TryFinally( + (fun () -> (body disp)()), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline this.For(sequence : seq<'T>, [] body : 'T -> SyncCode) : SyncCode = + this.Using (sequence.GetEnumerator(), + (fun e -> this.While((fun () -> e.MoveNext()), (fun () -> (body e.Current)())))) + + member inline _.ReturnFrom (value: 'T) : SyncCode<'T> = + (fun () -> + value) + + member inline _.Bind (v: 'TResult1, [] continuation: 'TResult1 -> SyncCode<'TResult2>) : SyncCode<'TResult2> = + (fun () -> + (continuation v)()) + +let sync = SyncBuilder() + +module Examples = + + let t1 y = + sync { + let x = 4 + 5 + y + return x + } + + let t2 y = + sync { + printfn "in t2" + let! x = t1 y + return x + y + } + + + //printfn "t2 6 = %d" (t2 6) diff --git a/tests/benchmarks/TaskPerf/taskSeq.fs b/tests/benchmarks/TaskPerf/taskSeq.fs new file mode 100644 index 00000000000..c87c79f37db --- /dev/null +++ b/tests/benchmarks/TaskPerf/taskSeq.fs @@ -0,0 +1,599 @@ + +module Tests.TaskSeq + +open System.Runtime.CompilerServices +open System.Threading.Tasks.Sources + +#nowarn "42" +open System +open System.Collections.Generic +open System.Threading +open System.Threading.Tasks +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers + +let verbose = false + +let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() + +type taskSeq<'T> = IAsyncEnumerable<'T> + +type IPriority1 = interface end +type IPriority2 = interface end + +[] +type TaskSeqStateMachineData<'T>() = + [] + val mutable cancellationToken : CancellationToken + [] + val mutable disposalStack : ResizeArray<(unit -> Task)> + [] + val mutable awaiter : ICriticalNotifyCompletion + [] + val mutable promiseOfValueOrEnd: ManualResetValueTaskSourceCore + [] + val mutable builder : AsyncIteratorMethodBuilder + [] + val mutable taken : bool + [] + val mutable current : ValueOption<'T> + [] + val mutable boxed: TaskSeq<'T> + // For tailcalls using 'return!' + [] + val mutable tailcallTarget: TaskSeq<'T> option + + member data.PushDispose (f: unit -> Task) = + match data.disposalStack with + | null -> data.disposalStack <- ResizeArray() + | _ -> () + data.disposalStack.Add(f) + + member data.PopDispose () = + match data.disposalStack with + | null -> () + | _ -> + data.disposalStack.RemoveAt(data.disposalStack.Count - 1) + +and [] + TaskSeq<'T>() = + abstract TailcallTarget: TaskSeq<'T> option + abstract MoveNextAsyncResult: unit -> ValueTask + + // F# requires that we implement interfaces even on an abstract class + interface IAsyncEnumerator<'T> with + member _.Current = failwith "abstract" + member _.MoveNextAsync() = failwith "abstract" + interface IAsyncDisposable with + member _.DisposeAsync() = failwith "abstract" + interface IAsyncEnumerable<'T> with + member _.GetAsyncEnumerator(ct) = failwith "abstract" + interface IAsyncStateMachine with + member _.MoveNext() = failwith "abstract" + member _.SetStateMachine(_state) = failwith "abstract" + interface IValueTaskSource with + member _.GetResult(_token: int16) = failwith "abstract" + member _.GetStatus(_token: int16) = failwith "abstract" + member _.OnCompleted(_continuation, _state, _token, _flags) = failwith "abstract" + interface IValueTaskSource with + member _.GetStatus(_token: int16) = failwith "abstract" + member _.GetResult(_token: int16) = failwith "abstract" + member _.OnCompleted(_continuation, _state, _token, _flags) = failwith "abstract" + +and [] + TaskSeq<'Machine, 'T when 'Machine :> IAsyncStateMachine and 'Machine :> IResumableStateMachine>>() = + inherit TaskSeq<'T>() + let initialThreadId = Environment.CurrentManagedThreadId + + [] + val mutable Machine : 'Machine + + member internal ts.hijack() = + let res = ts.Machine.Data.tailcallTarget + match res with + | Some tg -> + match tg.TailcallTarget with + | None -> + res + | (Some tg2 as res2) -> + // Cut out chains of tailcalls + ts.Machine.Data.tailcallTarget <- Some tg2 + res2 + | None -> + res + + // Note: Not entirely clear if this is needed, everything still compiles without it + interface IValueTaskSource with + member ts.GetResult(token: int16) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).GetResult(token) + | None -> ts.Machine.Data.promiseOfValueOrEnd.GetResult(token) |> ignore + member ts.GetStatus(token: int16) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).GetStatus(token) + | None -> ts.Machine.Data.promiseOfValueOrEnd.GetStatus(token) + member ts.OnCompleted(continuation, state, token, flags) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).OnCompleted(continuation, state, token, flags) + | None -> ts.Machine.Data.promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags) + + // Needed for MoveNextAsync to return a ValueTask + interface IValueTaskSource with + member ts.GetStatus(token: int16) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).GetStatus(token) + | None -> ts.Machine.Data.promiseOfValueOrEnd.GetStatus(token) + member ts.GetResult(token: int16) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).GetResult(token) + | None -> ts.Machine.Data.promiseOfValueOrEnd.GetResult(token) + member ts.OnCompleted(continuation, state, token, flags) = + match ts.hijack() with + | Some tg -> (tg :> IValueTaskSource).OnCompleted(continuation, state, token, flags) + | None -> ts.Machine.Data.promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags) + + interface IAsyncStateMachine with + member ts.MoveNext() = + match ts.hijack() with + | Some tg -> (tg :> IAsyncStateMachine).MoveNext() + | None -> MoveNext(&ts.Machine) + + member _.SetStateMachine(_state) = () // not needed for reference type + + interface IAsyncEnumerable<'T> with + member ts.GetAsyncEnumerator(ct) = + let data = ts.Machine.Data + if (not data.taken && initialThreadId = Environment.CurrentManagedThreadId) then + data.taken <- true + data.cancellationToken <- ct + data.builder <- AsyncIteratorMethodBuilder.Create() + (ts :> IAsyncEnumerator<_>) + else + if verbose then printfn "GetAsyncEnumerator, cloning..." + let clone = ts.MemberwiseClone() :?> TaskSeq<'Machine, 'T> + data.taken <- true + clone.Machine.Data.cancellationToken <- ct + (clone :> System.Collections.Generic.IAsyncEnumerator<'T>) + + interface IAsyncDisposable with + member ts.DisposeAsync() = + match ts.hijack() with + | Some tg -> (tg :> IAsyncDisposable).DisposeAsync() + | None -> + if verbose then printfn "DisposeAsync..." + task { + match ts.Machine.Data.disposalStack with + | null -> () + | _ -> + let mutable exn = None + for d in Seq.rev ts.Machine.Data.disposalStack do + try + do! d() + with e -> + if exn.IsNone then + exn <- Some e + match exn with + | None -> () + | Some e -> raise e + } + |> ValueTask + + interface System.Collections.Generic.IAsyncEnumerator<'T> with + member ts.Current = + match ts.hijack() with + | Some tg -> (tg :> IAsyncEnumerator<'T>).Current + | None -> + match ts.Machine.Data.current with + | ValueSome x -> x + | ValueNone -> failwith "no current value" + + member ts.MoveNextAsync() = + match ts.hijack() with + | Some tg -> (tg :> IAsyncEnumerator<'T>).MoveNextAsync() + | None -> + if verbose then printfn "MoveNextAsync..." + if ts.Machine.ResumptionPoint = -1 then // can't use as IAsyncEnumerator before IAsyncEnumerable + ValueTask() + else + let data = ts.Machine.Data + data.promiseOfValueOrEnd.Reset() + let mutable ts = ts + data.builder.MoveNext(&ts) + + // If the move did a hijack then get the result from the final one + match ts.hijack() with + | Some tg -> tg.MoveNextAsyncResult() + | None -> ts.MoveNextAsyncResult() + + override ts.MoveNextAsyncResult() = + let data = ts.Machine.Data + let version = data.promiseOfValueOrEnd.Version + let status = data.promiseOfValueOrEnd.GetStatus(version) + if status = ValueTaskSourceStatus.Succeeded then + let result = data.promiseOfValueOrEnd.GetResult(version) + ValueTask(result) + else + if verbose then printfn "MoveNextAsync pending/faulted/cancelled..." + ValueTask(ts, version) // uses IValueTaskSource<'T> + + override cr.TailcallTarget = + cr.hijack() + +and TaskSeqCode<'T> = ResumableCode, unit> +and TaskSeqStateMachine<'T> = ResumableStateMachine> +and TaskSeqResumptionFunc<'T> = ResumptionFunc> +and TaskSeqResumptionDynamicInfo<'T> = ResumptionDynamicInfo> + +type TaskSeqBuilder() = + + member inline _.Delay(f : unit -> TaskSeqCode<'T>) : TaskSeqCode<'T> = + TaskSeqCode<'T>(fun sm -> f().Invoke(&sm)) + + member inline _.Run(code : TaskSeqCode<'T>) : IAsyncEnumerable<'T> = + if __useResumableCode then + // This is the static implementation. A new struct type is created. + __stateMachine, IAsyncEnumerable<'T>> + // IAsyncStateMachine.MoveNext + (MoveNextMethodImpl<_>(fun sm -> + //-- RESUMABLE CODE START + __resumeAt sm.ResumptionPoint + try + //printfn "at Run.MoveNext start" + //Console.WriteLine("[{0}] resuming by invoking {1}....", sm.MethodBuilder.Task.Id, hashq sm.ResumptionFunc ) + let __stack_code_fin = code.Invoke(&sm) + //printfn $"at Run.MoveNext, __stack_code_fin={__stack_code_fin}" + if __stack_code_fin then + //printfn $"at Run.MoveNext, done" + sm.Data.promiseOfValueOrEnd.SetResult(false) + sm.Data.builder.Complete() + elif sm.Data.current.IsSome then + //printfn $"at Run.MoveNext, yield" + sm.Data.promiseOfValueOrEnd.SetResult(true) + else + // Goto request + match sm.Data.tailcallTarget with + | Some tg -> + //printfn $"at Run.MoveNext, hijack" + let mutable tg = tg + MoveNext(&tg) + | None -> + //printfn $"at Run.MoveNext, await" + let boxed = sm.Data.boxed + sm.Data.awaiter.UnsafeOnCompleted(Action(fun () -> + let mutable boxed = boxed + MoveNext(&boxed))) + + with exn -> + //Console.WriteLine("[{0}] SetException {1}", sm.MethodBuilder.Task.Id, exn) + sm.Data.promiseOfValueOrEnd.SetException(exn) + sm.Data.builder.Complete() + //-- RESUMABLE CODE END + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> + let ts = TaskSeq, 'T>() + ts.Machine <- sm + ts.Machine.Data <- TaskSeqStateMachineData() + ts.Machine.Data.boxed <- ts + ts :> IAsyncEnumerable<'T>)) + else + failwith "no dynamic implementation as yet" + // let initialResumptionFunc = TaskSeqResumptionFunc<'T>(fun sm -> code.Invoke(&sm)) + // let resumptionFuncExecutor = TaskSeqResumptionExecutor<'T>(fun sm f -> + // // TODO: add exception handling? + // if f.Invoke(&sm) then + // sm.ResumptionPoint <- -2) + // let setStateMachine = SetStateMachineMethodImpl<_>(fun sm f -> ()) + // sm.Machine.ResumptionFuncInfo <- (initialResumptionFunc, resumptionFuncExecutor, setStateMachine) + //sm.Start() + + + member inline _.Zero() : TaskSeqCode<'T> = + ResumableCode.Zero() + + member inline _.Combine(task1: TaskSeqCode<'T>, task2: TaskSeqCode<'T>) : TaskSeqCode<'T> = + ResumableCode.Combine(task1, task2) + + member inline _.WhileAsync([] condition : unit -> ValueTask, body : TaskSeqCode<'T>) : TaskSeqCode<'T> = + let mutable condition_res = true + ResumableCode.While((fun () -> condition_res), + ResumableCode<_,_>(fun sm -> + let mutable __stack_condition_fin = true + let __stack_vtask = condition() + if __stack_vtask.IsCompleted then + __stack_condition_fin <- true + condition_res <- __stack_vtask.Result + else + let task = __stack_vtask.AsTask() + let mutable awaiter = task.GetAwaiter() + // This will yield with __stack_fin = false + // This will resume with __stack_fin = true + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_condition_fin <- __stack_yield_fin + + if __stack_condition_fin then + condition_res <- task.Result + else + //if verbose then printfn "calling AwaitUnsafeOnCompleted" + sm.Data.awaiter <- awaiter + sm.Data.current <- ValueNone + + if __stack_condition_fin then + if condition_res then + body.Invoke(&sm) + else + true + else + false + )) + + member inline b.While([] condition : unit -> bool, body : TaskSeqCode<'T>) : TaskSeqCode<'T> = + b.WhileAsync((fun () -> ValueTask(condition())), body) + + member inline _.TryWith(body : TaskSeqCode<'T>, catch : exn -> TaskSeqCode<'T>) : TaskSeqCode<'T> = + ResumableCode.TryWith(body, catch) + + member inline _.TryFinallyAsync(body: TaskSeqCode<'T>, compensation : unit -> Task) : TaskSeqCode<'T> = + ResumableCode.TryFinallyAsync( + TaskSeqCode<'T>(fun sm -> + sm.Data.PushDispose (fun () -> compensation()) + body.Invoke(&sm)), + ResumableCode<_,_>(fun sm -> + sm.Data.PopDispose(); + let mutable __stack_condition_fin = true + let __stack_vtask = compensation() + if not __stack_vtask.IsCompleted then + let mutable awaiter = __stack_vtask.GetAwaiter() + let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) + __stack_condition_fin <- __stack_yield_fin + + if not __stack_condition_fin then + sm.Data.awaiter <- awaiter + + __stack_condition_fin)) + + member inline _.TryFinally(body: TaskSeqCode<'T>, compensation : unit -> unit) : TaskSeqCode<'T> = + ResumableCode.TryFinally( + TaskSeqCode<'T>(fun sm -> + sm.Data.PushDispose (fun () -> compensation(); Task.CompletedTask) + body.Invoke(&sm)), + ResumableCode<_,_>(fun sm -> sm.Data.PopDispose(); compensation(); true)) + + member inline this.Using(disp : #IDisposable, body : #IDisposable -> TaskSeqCode<'T>, ?priority: IPriority2) : TaskSeqCode<'T> = + ignore priority + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinally( + (fun sm -> (body disp).Invoke(&sm)), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline this.Using(disp : #IAsyncDisposable, body : #IAsyncDisposable -> TaskSeqCode<'T>, ?priority: IPriority1) : TaskSeqCode<'T> = + ignore priority + // A using statement is just a try/finally with the finally block disposing if non-null. + this.TryFinallyAsync( + (fun sm -> (body disp).Invoke(&sm)), + (fun () -> + if not (isNull (box disp)) then + disp.DisposeAsync().AsTask() + else + Task.CompletedTask)) + + member inline this.For(sequence : seq<'TElement>, body : 'TElement -> TaskSeqCode<'T>) : TaskSeqCode<'T> = + // A for loop is just a using statement on the sequence's enumerator... + this.Using (sequence.GetEnumerator(), + // ... and its body is a while loop that advances the enumerator and runs the body on each element. + (fun e -> this.While((fun () -> e.MoveNext()), (fun sm -> (body e.Current).Invoke(&sm))))) + + member inline this.For(source: #IAsyncEnumerable<'TElement>, body : 'TElement -> TaskSeqCode<'T>) : TaskSeqCode<'T> = + TaskSeqCode<'T>(fun sm -> + this.Using(source.GetAsyncEnumerator(sm.Data.cancellationToken), + (fun e -> this.WhileAsync((fun () -> e.MoveNextAsync()), + (fun sm -> (body e.Current).Invoke(&sm))))).Invoke(&sm)) + + member inline _.Yield (v: 'T) : TaskSeqCode<'T> = + TaskSeqCode<'T>(fun sm -> + // This will yield with __stack_fin = false + // This will resume with __stack_fin = true + let __stack_fin = ResumableCode.Yield().Invoke(&sm) + sm.Data.current <- ValueSome v + sm.Data.awaiter <- null + __stack_fin) + + member inline this.YieldFrom (source: IAsyncEnumerable<'T>) : TaskSeqCode<'T> = + this.For(source, (fun v -> this.Yield(v))) + + member inline _.Bind (task: Task<'TResult1>, continuation: ('TResult1 -> TaskSeqCode<'T>)) : TaskSeqCode<'T> = + TaskSeqCode<'T>(fun sm -> + let mutable awaiter = task.GetAwaiter() + let mutable __stack_fin = true + if not awaiter.IsCompleted then + // This will yield with __stack_fin2 = false + // This will resume with __stack_fin2 = true + let __stack_fin2 = ResumableCode.Yield().Invoke(&sm) + __stack_fin <- __stack_fin2 + + if __stack_fin then + let result = awaiter.GetResult() + (continuation result).Invoke(&sm) + else + if verbose then printfn "calling AwaitUnsafeOnCompleted" + sm.Data.awaiter <- awaiter + sm.Data.current <- ValueNone + false) + + // TODO: using return! for tailcalls is wrong. We should use yield! and have F# + // desugar to a different builder method when in tailcall position + // + // Because of this using return! from non-tailcall position e.g. in a try-finally or try-with will + // giv incorrect results (escaping the exception handler - 'close up shop and draw results from somewhere else') + member inline b.ReturnFrom (other: IAsyncEnumerable<'T>) : TaskSeqCode<'T> = + TaskSeqCode<_>(fun sm -> + match other with + | :? TaskSeq<'T> as other -> + sm.Data.tailcallTarget <- Some other + sm.Data.awaiter <- null + sm.Data.current <- ValueNone + // For tailcalls we return 'false' and re-run from the entry (trampoline) + false + | _ -> + b.YieldFrom(other).Invoke(&sm) + ) + +let taskSeq = TaskSeqBuilder() + +module TaskSeq = + let toList (t: taskSeq<'T>) = + [ let e = t.GetAsyncEnumerator(CancellationToken()) + try + while (let vt = e.MoveNextAsync() in if vt.IsCompleted then vt.Result else vt.AsTask().Result) do + yield e.Current + finally + e.DisposeAsync().AsTask().Wait() ] + + let toArray (t: taskSeq<'T>) = + [| let e = t.GetAsyncEnumerator(CancellationToken()) + try + while (let vt = e.MoveNextAsync() in if vt.IsCompleted then vt.Result else vt.AsTask().Result) do + yield e.Current + finally + e.DisposeAsync().AsTask().Wait() |] + + let toArrayAsync (t: taskSeq<'T>) : Task<'T[]> = + task { + let res = ResizeArray<'T>() + let e = t.GetAsyncEnumerator(CancellationToken()) + let mutable go = true + let! step = e.MoveNextAsync() + go <- step + while go do + res.Add e.Current + if verbose then printfn "yield %A" e.Current + let! step = e.MoveNextAsync() + go <- step + return res.ToArray() + } + + let iter f (t: taskSeq<'T>) = + let e = t.GetAsyncEnumerator(CancellationToken()) + try + while (let vt = e.MoveNextAsync() in if vt.IsCompleted then vt.Result else vt.AsTask().Result) do + f e.Current + finally + e.DisposeAsync().AsTask().Wait() + +module Examples = + + let t1 () = + taskSeq { + printfn "in t1" + yield "a" + let x = 1 + let! v = + task { + printfn "hey" + do! Task.Delay(10) + } + yield "b" + let! v = + task { + printfn "hey yo" + do! Task.FromResult(()) + } + yield "c" + let! v = + task { + printfn "and a bottle of rum" + do! Task.Delay(0) + } + yield "d" + } + + let testTailcallTiny () = + taskSeq { + return! t1() + } + let rec testTailcall (n: int) = + taskSeq { + if n % 100 = 0 then printfn $"in t1, n = {n}" + yield n + if n > 0 then + return! testTailcall(n-1) + //yield () + } + + //let t2 () = + // taskSeq { + // printfn "in t2" + // yield "d" + // printfn "in t2 b" + // for x in t1 () do + // printfn "t2 - got %A" x + // yield "e" + // let! v = + // task { + // printfn "hey yo" + // do! Task.Delay(200) + // } + // yield "[T1]" + x + // let! v = + // task { + // printfn "hey yo" + // do! Task.Delay(10) + // } + // yield "f" + // } + + let perf1 (x: int) = + taskSeq { + yield 1 + yield 2 + if x >= 2 then + yield 3 + yield 4 + } + + let perf2 () = + taskSeq { + for i1 in perf1 3 do + for i2 in perf1 3 do + for i3 in perf1 3 do + for i4 in perf1 3 do + for i5 in perf1 3 do + yield! perf1 i5 + } + + //let perf1_AsyncSeq (x: int) = + // FSharp.Control.AsyncSeqExtensions.asyncSeq { + // yield 1 + // yield 2 + // if x >= 2 then + // yield 3 + // yield 4 + // } + + //let perf2_AsyncSeq () = + // FSharp.Control.AsyncSeqExtensions.asyncSeq { + // for i1 in perf1_AsyncSeq 3 do + // for i2 in perf1_AsyncSeq 3 do + // for i3 in perf1_AsyncSeq 3 do + // for i4 in perf1_AsyncSeq 3 do + // for i5 in perf1_AsyncSeq 3 do + // yield! perf1_AsyncSeq i5 + // } + + let dumpTaskSeq (t: IAsyncEnumerable<_>) = + printfn "-----" + let e = t.GetAsyncEnumerator(CancellationToken()) + while (let vt = e.MoveNextAsync() in if vt.IsCompleted then vt.Result else vt.AsTask().Result) do + printfn "yield %A" e.Current + + //dumpTaskSeq (t1()) + //dumpTaskSeq (testTailcallTiny()) + ////dumpTaskSeq (t2()) + + //printfn "t1() = %A" (TaskSeq.toArray (t1())) + //printfn "testTailcallTiny() = %A" (TaskSeq.toArray (testTailcallTiny())) + //dumpTaskSeq (testTailcall(100000)) + //printfn "t2() = %A" (TaskSeq.toArray (t2())) + + printfn "perf2() = %A" (TaskSeq.toArray (perf2()) |> Array.sum) + diff --git a/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.cs b/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.cs new file mode 100644 index 00000000000..32ea6fcb66c --- /dev/null +++ b/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; + +#pragma warning disable 1998 + +public static class TaskPerfCSharp +{ + public const int BufferSize = 128; + //public const int ManyIterations = 10000; + + public static async Task ManyWriteFileAsync(int ManyIterations) + { + const string path = "tmp"; + var junk = new byte[BufferSize]; + using (var file = File.Create(path)) + { + for (var i = 1; i <= ManyIterations; i++) + { + await file.WriteAsync(junk, 0, junk.Length); + } + } + File.Delete(path); + } + + public static System.Runtime.CompilerServices.YieldAwaitable AsyncTask() + { + return Task.Yield(); + } + + public static Task SyncTask() + { + return Task.FromResult(100); + } + + public static async Task TenBindsSync_CSharp() + { + var x1 = await SyncTask(); + var x2 = await SyncTask(); + var x3 = await SyncTask(); + var x4 = await SyncTask(); + var x5 = await SyncTask(); + var x6 = await SyncTask(); + var x7 = await SyncTask(); + var x8 = await SyncTask(); + var x9 = await SyncTask(); + var x10 = await SyncTask(); + return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10; + } + + public static async Task TenBindsAsync_CSharp() + { + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + await AsyncTask(); + return 100; + } + + public static async Task SingleSyncTask_CSharp() + { + return 1; + } + + public static async Task SingleSyncExceptionTask_CSharp() + { + throw (new System.Exception("fail")); + } + + + public static async IAsyncEnumerable perf1_AsyncEnumerable(int x) + { + yield return 1; + yield return 2; + if (x >= 2) + { + yield return 3; + yield return 4; + } + } + + public static async IAsyncEnumerable perf2_AsyncEnumerable() + { + await foreach (var i1 in perf1_AsyncEnumerable(3)) + { + await foreach (var i2 in perf1_AsyncEnumerable(3)) + { + await foreach (var i3 in perf1_AsyncEnumerable(3)) + { + await foreach (var i4 in perf1_AsyncEnumerable(3)) + { + await foreach (var i5 in perf1_AsyncEnumerable(3)) + { + await foreach (var i6 in perf1_AsyncEnumerable(i5)) + { + yield return i6; + + } + } + + } + + } + + } + + } + } + +#if MAIN + public static void Main() { + var t = SingleSyncExceptionTask_CSharp(); + System.Console.WriteLine("t = {0}", t); + } +#endif +} + diff --git a/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.csproj b/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.csproj new file mode 100644 index 00000000000..f55b590cb26 --- /dev/null +++ b/tests/benchmarks/TaskPerfCSharp/TaskPerfCSharp.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp3.1 + Library + 8.0 + + + + + + + + diff --git a/tests/benchmarks/TaskPerfPreviousCompiler/TaskPerfPreviousCompiler.fsproj b/tests/benchmarks/TaskPerfPreviousCompiler/TaskPerfPreviousCompiler.fsproj new file mode 100644 index 00000000000..d9446577406 --- /dev/null +++ b/tests/benchmarks/TaskPerfPreviousCompiler/TaskPerfPreviousCompiler.fsproj @@ -0,0 +1,30 @@ + + + + net5.0 + Exe + true + $(OtherFlags) --define:ASYNC_PERF + true + + C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\FSharp + fsc.exe + + + + + + + + + + + + + + + + + + + diff --git a/tests/benchmarks/TaskPerfPreviousCompiler/defs.fs b/tests/benchmarks/TaskPerfPreviousCompiler/defs.fs new file mode 100644 index 00000000000..42cea70022c --- /dev/null +++ b/tests/benchmarks/TaskPerfPreviousCompiler/defs.fs @@ -0,0 +1,14 @@ + +namespace Tests + +open System + +#if !PREVIEW + +[] +[] +type InlineIfLambdaAttribute() = + inherit Attribute() + +#endif + diff --git a/tests/fsharp/.vscode/settings.json b/tests/fsharp/.vscode/settings.json new file mode 100644 index 00000000000..67c22405bad --- /dev/null +++ b/tests/fsharp/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "FSharp.suggestGitignore": false +} \ No newline at end of file diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/BooleanLogic.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/BooleanLogic.fs new file mode 100644 index 00000000000..2a981b237f5 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/BooleanLogic.fs @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +[] +module BooleanLogic = + + [] + let BooleanOrs() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize+"|] + """ +module BooleanOrs +let compute (x: int) = + if (x = 1 || x = 2) then 2 + elif (x = 3 || x = 4) then 3 + else 4 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 compute(int32 x) cil managed + { + + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: beq.s IL_0009 + + IL_0005: ldarg.0 + IL_0006: ldc.i4.2 + IL_0007: bne.un.s IL_000b + + IL_0009: ldc.i4.2 + IL_000a: ret + + IL_000b: nop + IL_000c: ldarg.0 + IL_000d: ldc.i4.3 + IL_000e: beq.s IL_0014 + + IL_0010: ldarg.0 + IL_0011: ldc.i4.4 + IL_0012: bne.un.s IL_0016 + + IL_0014: ldc.i4.3 + IL_0015: ret + + IL_0016: ldc.i4.4 + IL_0017: ret +} + """ + ]) + +[] +// We had a regression in debug code regression where we were falsely marking pipelines +// as non-side-effecting, causing them to be eliminated in loops. +// +// After the fix +// 1. pipelines are correctly marked as having effect +// 2. we don't eliminate loops anyway +module DontEliminateForLoopsInDebugCode = + + [] + // See https://github.com/dotnet/fsharp/pull/12021 + let Regression12021() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module DontEliminateForLoops + +let unsolved = [true] +let ApplyDefaults () = + + for priority = 0 to 10 do + unsolved |> List.iter (fun tp -> System.Console.WriteLine()) + + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static void ApplyDefaults() cil managed +{ + + .maxstack 5 + .locals init (int32 V_0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_3, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_4, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_5, + bool V_6) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_004b + + IL_0004: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 DontEliminateForLoops::get_unsolved() + IL_0009: stloc.1 + IL_000a: ldsfld class DontEliminateForLoops/ApplyDefaults@8 DontEliminateForLoops/ApplyDefaults@8::@_instance + IL_000f: stloc.2 + IL_0010: ldloc.1 + IL_0011: stloc.3 + IL_0012: ldloc.3 + IL_0013: stloc.s V_4 + IL_0015: ldloc.s V_4 + IL_0017: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_001c: stloc.s V_5 + IL_001e: ldloc.s V_5 + IL_0020: ldnull + IL_0021: cgt.un + IL_0023: brfalse.s IL_0047 + + IL_0025: ldloc.s V_4 + IL_0027: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_002c: stloc.s V_6 + IL_002e: ldloc.2 + IL_002f: ldloc.s V_6 + IL_0031: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0036: pop + IL_0037: ldloc.s V_5 + IL_0039: stloc.s V_4 + IL_003b: ldloc.s V_4 + IL_003d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0042: stloc.s V_5 + IL_0044: nop + IL_0045: br.s IL_001e + + IL_0047: ldloc.0 + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: stloc.0 + IL_004b: ldloc.0 + IL_004c: ldc.i4.1 + IL_004d: ldc.i4.s 10 + IL_004f: add + IL_0050: blt.s IL_0004 + + IL_0052: ret +} + """ + ]) + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ByrefTailcalls.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ByrefTailcalls.fs new file mode 100644 index 00000000000..8abc32d756d --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ByrefTailcalls.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +open System +open System.Threading.Tasks + +[] +module ByrefTailcalls = + + [] + let ``check no tailcall to inref``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/optimize";"/tailcalls" |] + """ +module Test + +type Getter<'T, 'FT> = delegate of inref<'T> -> 'FT + +type GetterWrapper<'T, 'FT> (getter : Getter<'T, 'FT>) = + member _.Get (instance : 'T) = getter.Invoke &instance + + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public hidebysig instance !FT + Get(!T 'instance') cil managed +{ + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class Test/Getter`2 class Test/GetterWrapper`2::getter + IL_0006: ldarga.s 'instance' + IL_0008: callvirt instance !1 class Test/Getter`2::Invoke(!0& modreq([runtime]System.Runtime.InteropServices.InAttribute)) + IL_000d: ret +} + """ + ]) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs new file mode 100644 index 00000000000..33355e4053d --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Compiler.UnitTests +open NUnit.Framework +open FSharp.Test + +[] +module CeEdiThrow = + + [] + let ``Emits EDI.Throw``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module CE + +open System +type Try() = + member _.Return i = i + member _.Delay f = f + member _.Run f = f() + member _.TryWith(body : unit -> int, catch : exn -> int) = + try body() with ex -> catch ex + +let foo = Try(){ + try return invalidOp "Ex" + with :? ArgumentException -> return 1 +} + """ + (fun verifier -> verifier.VerifyIL [ + """ + .method public strict virtual instance int32 + Invoke(class [runtime]System.Exception _arg1) cil managed + { + + .maxstack 5 + .locals init (class [runtime]System.ArgumentException V_0) + IL_0000: ldarg.1 + IL_0001: isinst [runtime]System.ArgumentException + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_000c + + IL_000a: ldc.i4.1 + IL_000b: ret + + IL_000c: ldarg.1 + IL_000d: call class [runtime]System.Runtime.ExceptionServices.ExceptionDispatchInfo [runtime]System.Runtime.ExceptionServices.ExceptionDispatchInfo::Capture(class [runtime]System.Exception) + IL_0012: callvirt instance void [runtime]System.Runtime.ExceptionServices.ExceptionDispatchInfo::Throw() + IL_0017: ldc.i4.0 + IL_0018: ret + } + """ + ]) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ComplexShadowingFunction.debuginfo.expected b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComplexShadowingFunction.debuginfo.expected new file mode 100644 index 00000000000..d4290843220 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComplexShadowingFunction.debuginfo.expected @@ -0,0 +1,66 @@ +ENTRYPOINT + false + +DOCUMENTS + [0] + Type: None + Language: None + Vendor: None + +METHODS + f2 + Params: [] + Range: Some "[0,5:9] - [0,5:11]" + Points: + - Doc: 0 Offset:0 [5:5]-[5-15] + - Doc: 0 Offset:2 [6:5]-[6-14] + - Doc: 0 Offset:3 [16707566:0]-[16707566-0] + - Doc: 0 Offset:6 [7:9]-[7-21] + - Doc: 0 Offset:16 [8:9]-[8-18] + - Doc: 0 Offset:17 [16707566:0]-[16707566-0] + - Doc: 0 Offset:20 [9:12]-[9-24] + - Doc: 0 Offset:26 [10:12]-[10-22] + - Doc: 0 Offset:28 [11:12]-[11-14] + - Doc: 0 Offset:30 [13:12]-[13-24] + - Doc: 0 Offset:37 [14:12]-[14-22] + - Doc: 0 Offset:40 [15:12]-[15-14] + - Doc: 0 Offset:43 [17:9]-[17-21] + - Doc: 0 Offset:54 [18:9]-[18-18] + - Doc: 0 Offset:55 [16707566:0]-[16707566-0] + - Doc: 0 Offset:58 [19:12]-[19-24] + - Doc: 0 Offset:65 [20:12]-[20-22] + - Doc: 0 Offset:68 [21:12]-[21-14] + - Doc: 0 Offset:71 [23:12]-[23-24] + - Doc: 0 Offset:78 [24:12]-[24-22] + - Doc: 0 Offset:81 [25:12]-[25-14] + Scopes: + - [0-84] + - [1-15] + Locals: ["0: v1"] + - [15-25] + Locals: ["0: v1"; "1: v2"] + - [25-27] + Locals: ["0: v1 (shadowed)"; "1: v2"; "2: v1"] + - [27-30] + Locals: ["1: v2 (shadowed)"; "0: v1 (shadowed)"; "2: v1"; "3: v2"] + - [30-35] + Locals: ["0: v1"; "1: v2"] + - [35-38] + Locals: ["0: v1 (shadowed)"; "1: v2"; "4: v1"] + - [38-43] + Locals: ["1: v2 (shadowed)"; "0: v1 (shadowed)"; "4: v1"; "5: v2"] + - [43-52] + Locals: ["0: v1"] + - [52-63] + Locals: ["0: v1"; "6: v2"] + - [63-66] + Locals: ["0: v1 (shadowed)"; "6: v2"; "7: v1"] + - [66-71] + Locals: ["6: v2 (shadowed)"; "0: v1 (shadowed)"; "7: v1"; "8: v2"] + - [71-76] + Locals: ["0: v1"; "6: v2"] + - [76-79] + Locals: ["0: v1 (shadowed)"; "6: v2"; "9: v1"] + - [79-84] + Locals: ["6: v2 (shadowed)"; "0: v1 (shadowed)"; "9: v1"; "10: v2"] + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputationExpressionOptimizations.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputationExpressionOptimizations.fs new file mode 100644 index 00000000000..301412aed52 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputationExpressionOptimizations.fs @@ -0,0 +1,317 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +open System + +[] +module ComputationExpressionOptimizations = + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + // + // This tests a number of code optimizations cooperating together. + // - InlineIfLambda must be applied + // - Computed functions must be reduced. + // + // This is for the "sync { ... }" builder that simply runs code synchronously - no + // one uses this in practice but it's a good baseline test for the elimination and redution of constructs. + // + let ``check reduction of sample builder for synchronous code``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module Test + +open System + +type SyncCode<'T> = unit -> 'T + +type SyncBuilder() = + + member inline _.Delay([] f: unit -> SyncCode<'T>) : SyncCode<'T> = + (fun () -> (f())()) + + member inline _.Run([] code : SyncCode<'T>) : 'T = + code() + + [] + member inline _.Zero() : SyncCode< unit> = + (fun () -> ()) + + member inline _.Return (x: 'T) : SyncCode<'T> = + (fun () -> x) + + member inline _.Combine([] code1: SyncCode, [] code2: SyncCode<'T>) : SyncCode<'T> = + (fun () -> + code1() + code2()) + + member inline _.While([] condition: unit -> bool, [] body: SyncCode) : SyncCode = + (fun () -> + while condition() do + body()) + + member inline _.TryWith([] body: SyncCode<'T>, [] catch: exn -> SyncCode<'T>) : SyncCode<'T> = + (fun () -> + try + body() + with exn -> + (catch exn)()) + + member inline _.TryFinally([] body: SyncCode<'T>, compensation: unit -> unit) : SyncCode<'T> = + (fun () -> + let res = + try + body() + with _ -> + compensation() + reraise() + compensation() + res) + + member inline this.Using(disp : #IDisposable, [] body: #IDisposable -> SyncCode<'T>) : SyncCode<'T> = + this.TryFinally( + (fun () -> (body disp)()), + (fun () -> if not (isNull (box disp)) then disp.Dispose())) + + member inline this.For(sequence : seq<'T>, [] body : 'T -> SyncCode) : SyncCode = + this.Using (sequence.GetEnumerator(), + (fun e -> this.While((fun () -> e.MoveNext()), (fun () -> (body e.Current)())))) + + member inline _.ReturnFrom (value: 'T) : SyncCode<'T> = + (fun () -> + value) + + member inline _.Bind (v: 'TResult1, [] continuation: 'TResult1 -> SyncCode<'TResult2>) : SyncCode<'TResult2> = + (fun () -> + (continuation v)()) + +let sync = SyncBuilder() + +module Examples = + + let t1 y = + sync { + let x = 4 + 5 + y + return x + } + + let testFunctionWithBind y = + sync { + printfn "step" + let! x = t1 y + return x + y + } + + let testFunctionWithWhile y = + sync { + printfn "step" + while y < 0 do + let! x = t1 y + printfn $"step {x}" + + return y + y + } + let testFunctionWithTryCatch y = + sync { + try + printfn "step" + let! x = t1 y + return x + y + with _ -> + return 5 + } + let testFunctionWithFinally y = + sync { + try + printfn "step" + let! x = t1 y + return x + y + finally + printfn "step" + } + """ + (fun verifier -> verifier.VerifyIL [ + // Check testFunctionWithBind is flattened + """ +.method public static int32 testFunctionWithBind(int32 y) cil managed +{ + + .maxstack 4 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0) + IL_0000: ldstr "step" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldc.i4.s 9 + IL_0019: ldarg.0 + IL_001a: add + IL_001b: ldarg.0 + IL_001c: add + IL_001d: ret +} + """ + + // Check testFunctionWithWhile is flattened + """ +.method public static int32 testFunctionWithWhile(int32 y) cil managed +{ + + .maxstack 7 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0, + int32 V_1) + IL_0000: ldstr "step" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: bge.s IL_004d + + IL_001b: ldc.i4.s 9 + IL_001d: ldarg.0 + IL_001e: add + IL_001f: stloc.1 + IL_0020: ldstr "step %P()" + IL_0025: ldc.i4.1 + IL_0026: newarr [runtime]System.Object + IL_002b: dup + IL_002c: ldc.i4.0 + IL_002d: ldloc.1 + IL_002e: box [runtime]System.Int32 + IL_0033: stelem [runtime]System.Object + IL_0038: ldnull + IL_0039: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string, + object[], + class [runtime]System.Type[]) + IL_003e: stloc.0 + IL_003f: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0044: ldloc.0 + IL_0045: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_004a: pop + IL_004b: br.s IL_0017 + + IL_004d: ldarg.0 + IL_004e: ldarg.0 + IL_004f: add + IL_0050: ret +} + """ + + // Check testFunctionWithTryCatch is flattened + """ +.method public static int32 testFunctionWithTryCatch(int32 y) cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_1, + class [runtime]System.Exception V_2) + .try + { + IL_0000: ldstr "step" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.1 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.1 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldc.i4.s 9 + IL_0019: ldarg.0 + IL_001a: add + IL_001b: ldarg.0 + IL_001c: add + IL_001d: stloc.0 + IL_001e: leave.s IL_002a + + } + catch [runtime]System.Object + { + IL_0020: castclass [runtime]System.Exception + IL_0025: stloc.2 + IL_0026: ldc.i4.5 + IL_0027: stloc.0 + IL_0028: leave.s IL_002a + + } + IL_002a: ldloc.0 + IL_002b: ret +} + """ + // Check testFunctionWithFinally is flattened + """ +.method public static int32 testFunctionWithFinally(int32 y) cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + int32 V_1, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_2, + class [runtime]System.Exception V_3) + .try + { + IL_0000: ldstr "step" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.2 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.2 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldc.i4.s 9 + IL_0019: ldarg.0 + IL_001a: add + IL_001b: ldarg.0 + IL_001c: add + IL_001d: stloc.1 + IL_001e: leave.s IL_0048 + + } + catch [runtime]System.Object + { + IL_0020: castclass [runtime]System.Exception + IL_0025: stloc.3 + IL_0026: ldstr "step" + IL_002b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0030: stloc.2 + IL_0031: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0036: ldloc.2 + IL_0037: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_003c: pop + IL_003d: rethrow + IL_003f: ldnull + IL_0040: unbox.any [runtime]System.Int32 + IL_0045: stloc.1 + IL_0046: leave.s IL_0048 + + } + IL_0048: ldloc.1 + IL_0049: stloc.0 + IL_004a: ldstr "step" + IL_004f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0054: stloc.2 + IL_0055: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_005a: ldloc.2 + IL_005b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0060: pop + IL_0061: ldloc.0 + IL_0062: ret +} + """ + ]) + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputedListExpressions.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputedListExpressions.fs new file mode 100644 index 00000000000..ca68e2e9d7a --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ComputedListExpressions.fs @@ -0,0 +1,404 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +[] +module ``ComputedListExpressions`` = + + [] + let ``ComputedListExpression01``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression01 +let ListExpressionSteppingTest1 () = [ yield 1 ] + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + ListExpressionSteppingTest1() cil managed +{ + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0008: nop + IL_0009: ldloca.s V_0 + IL_000b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0010: ret +} + """ + ]) + + [] + let ``ComputedListExpression02``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression02 +let ListExpressionSteppingTest2 () = + [ printfn "hello" + yield 1 + printfn "goodbye" + yield 2] + """ + (fun verifier -> verifier.VerifyIL [ + """ + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + ListExpressionSteppingTest2() cil managed + { + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0) + IL_0000: nop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.1 + IL_0014: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0019: nop + IL_001a: ldstr "goodbye" + IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0029: pop + IL_002a: ldloca.s V_0 + IL_002c: ldc.i4.2 + IL_002d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0032: nop + IL_0033: ldloca.s V_0 + IL_0035: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003a: ret + } + """ + ]) + + [] + let ``ComputedListExpression03``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression03 +let ListExpressionSteppingTest3 () = + let x = ref 0 + [ while !x < 4 do + incr x + printfn "hello" + yield x ] + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> + ListExpressionSteppingTest3() cil managed +{ + + .maxstack 4 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_0, + valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1> V_1) + IL_0000: ldc.i4.0 + IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0006: stloc.0 + IL_0007: nop + IL_0008: ldloc.0 + IL_0009: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_000e: ldc.i4.4 + IL_000f: bge.s IL_0034 + + IL_0011: ldloc.0 + IL_0012: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0017: nop + IL_0018: ldstr "hello" + IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0027: pop + IL_0028: ldloca.s V_1 + IL_002a: ldloc.0 + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Add(!0) + IL_0030: nop + IL_0031: nop + IL_0032: br.s IL_0007 + + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Close() + IL_003b: ret +} + """ + ]) + + [] + let ``ComputedListExpression04``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression04 +let ListExpressionSteppingTest4 () = + [ let x = ref 0 + try + let y = ref 0 + incr y + yield !x + let z = !x + !y + yield z + finally + incr x + printfn "done" ] + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + ListExpressionSteppingTest4() cil managed +{ + + .maxstack 4 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 V_3, + int32 V_4) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0007: stloc.1 + .try + { + IL_0008: nop + IL_0009: ldc.i4.0 + IL_000a: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_000f: stloc.3 + IL_0010: ldloc.3 + IL_0011: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0016: nop + IL_0017: ldloca.s V_0 + IL_0019: ldloc.1 + IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_001f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0024: nop + IL_0025: ldloc.1 + IL_0026: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_002b: ldloc.3 + IL_002c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0031: add + IL_0032: stloc.s V_4 + IL_0034: ldloca.s V_0 + IL_0036: ldloc.s V_4 + IL_0038: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_003d: nop + IL_003e: ldnull + IL_003f: stloc.2 + IL_0040: leave.s IL_005b + + } + finally + { + IL_0042: nop + IL_0043: ldloc.1 + IL_0044: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0049: nop + IL_004a: ldstr "done" + IL_004f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0054: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0059: pop + IL_005a: endfinally + } + IL_005b: ldloc.2 + IL_005c: pop + IL_005d: ldloca.s V_0 + IL_005f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0064: ret +} + + """ + ]) + + [] + let ``ComputedListExpression05``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression05 +let ListExpressionSteppingTest5 () = + [ for x in 1..4 do + printfn "hello" + yield x ] + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + ListExpressionSteppingTest5() cil managed + { + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: ldc.i4.1 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.4 + IL_0003: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0008: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.1 + .try + { + IL_000e: ldloc.1 + IL_000f: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0014: brfalse.s IL_0039 + + IL_0016: ldloc.1 + IL_0017: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001c: stloc.3 + IL_001d: ldstr "hello" + IL_0022: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0027: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002c: pop + IL_002d: ldloca.s V_0 + IL_002f: ldloc.3 + IL_0030: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0035: nop + IL_0036: nop + IL_0037: br.s IL_000e + + IL_0039: ldnull + IL_003a: stloc.2 + IL_003b: leave.s IL_0052 + + } + finally + { + IL_003d: ldloc.1 + IL_003e: isinst [runtime]System.IDisposable + IL_0043: stloc.s V_4 + IL_0045: ldloc.s V_4 + IL_0047: brfalse.s IL_0051 + + IL_0049: ldloc.s V_4 + IL_004b: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0050: endfinally + IL_0051: endfinally + } + IL_0052: ldloc.2 + IL_0053: pop + IL_0054: ldloca.s V_0 + IL_0056: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_005b: ret + } + +} + """ + ]) + + [] + let ``ComputedListExpression06``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"|] + """ +module ComputedListExpression06 +let ListExpressionSteppingTest6 () = + [ for x in 1..4 do + match x with + | 1 -> + printfn "hello" + yield x + | 2 -> + printfn "hello" + yield x + | _ -> + yield x + ] + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + ListExpressionSteppingTest6() cil managed +{ + + .maxstack 5 + .locals init (valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + class [runtime]System.Collections.Generic.IEnumerator`1 V_1, + class [runtime]System.Collections.Generic.IEnumerable`1 V_2, + int32 V_3, + class [runtime]System.IDisposable V_4) + IL_0000: ldc.i4.1 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.4 + IL_0003: call class [runtime]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0008: callvirt instance class [runtime]System.Collections.Generic.IEnumerator`1 class [runtime]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.1 + .try + { + IL_000e: ldloc.1 + IL_000f: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0014: brfalse.s IL_0074 + + IL_0016: ldloc.1 + IL_0017: callvirt instance !0 class [runtime]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001c: stloc.3 + IL_001d: nop + IL_001e: ldloc.3 + IL_001f: ldc.i4.1 + IL_0020: sub + IL_0021: switch ( + IL_0030, + IL_004c) + IL_002e: br.s IL_0068 + + IL_0030: ldstr "hello" + IL_0035: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_003a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_003f: pop + IL_0040: ldloca.s V_0 + IL_0042: ldloc.3 + IL_0043: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0048: nop + IL_0049: nop + IL_004a: br.s IL_000e + + IL_004c: ldstr "hello" + IL_0051: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0056: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_005b: pop + IL_005c: ldloca.s V_0 + IL_005e: ldloc.3 + IL_005f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0064: nop + IL_0065: nop + IL_0066: br.s IL_000e + + IL_0068: ldloca.s V_0 + IL_006a: ldloc.3 + IL_006b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0070: nop + IL_0071: nop + IL_0072: br.s IL_000e + + IL_0074: ldnull + IL_0075: stloc.2 + IL_0076: leave.s IL_008d + + } + finally + { + IL_0078: ldloc.1 + IL_0079: isinst [runtime]System.IDisposable + IL_007e: stloc.s V_4 + IL_0080: ldloc.s V_4 + IL_0082: brfalse.s IL_008c + + IL_0084: ldloc.s V_4 + IL_0086: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_008b: endfinally + IL_008c: endfinally + } + IL_008d: ldloc.2 + IL_008e: pop + IL_008f: ldloca.s V_0 + IL_0091: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0096: ret +} + """ + ]) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/DebugScopes.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/DebugScopes.fs new file mode 100644 index 00000000000..19353b0466f --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/DebugScopes.fs @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +[] +module DebugScopes = + + [] + let SimpleFunction() = + CompilerAssert.CompileLibraryAndVerifyDebugInfoWithOptions + [|"--debug:portable"; "--optimize-"; "--optimize-"|] + (__SOURCE_DIRECTORY__ + "/SimpleFunction.debuginfo.expected") + """ +module Test +let f x = + let y = 1 + 2 + """ + + [] + let SimpleShadowingFunction() = + CompilerAssert.CompileLibraryAndVerifyDebugInfoWithOptions + [|"--debug:portable"; "--optimize-"; "--optimize-"|] + (__SOURCE_DIRECTORY__ + "/SimpleShadowingFunction.debuginfo.expected") + """ +module Test +let f x = + let y = 1 + let y = y+1 + let y = y+1 + 2 + """ + + [] + let ComplexShadowingFunction() = + CompilerAssert.CompileLibraryAndVerifyDebugInfoWithOptions + [|"--debug:portable"; "--optimize-"; "--optimize-"|] + (__SOURCE_DIRECTORY__ + "/ComplexShadowingFunction.debuginfo.expected") + """ +module Test + +let f2 (a, b) = + let v1 = 1 + if a then + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + else + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + + + + """ + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/DelegateAndFuncOptimizations.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/DelegateAndFuncOptimizations.fs new file mode 100644 index 00000000000..319ff8690a3 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/DelegateAndFuncOptimizations.fs @@ -0,0 +1,530 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +[] +module DelegateAndFuncOptimizations = + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce function via InlineIfLambda``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module InlineIfLambda01 + +open System + +type C = + static member inline M([] f: int -> int) = f 3 + f 4 + static member M2() = C.M(fun x -> x + 1) + static member M3() = + C.M(fun x -> + printfn("code") + printfn("code") + printfn("code") + printfn("code") + printfn("code") + printfn("code") + x + 1) + """ + (fun verifier -> verifier.VerifyIL [ + // Check M is inlined and optimized when small + """ +.method public static int32 M2() cil managed +{ + + .maxstack 8 + IL_0000: ldc.i4.s 9 + IL_0002: ret +} + """ + // Check M is inlined and optimized when largs + """ +.method public static int32 M3() cil managed +{ + + .maxstack 5 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0) + IL_0000: ldstr "code" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldstr "code" + IL_001c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0021: stloc.0 + IL_0022: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0027: ldloc.0 + IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002d: pop + IL_002e: ldstr "code" + IL_0033: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0038: stloc.0 + IL_0039: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_003e: ldloc.0 + IL_003f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0044: pop + IL_0045: ldstr "code" + IL_004a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_004f: stloc.0 + IL_0050: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0055: ldloc.0 + IL_0056: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_005b: pop + IL_005c: ldstr "code" + IL_0061: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0066: stloc.0 + IL_0067: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_006c: ldloc.0 + IL_006d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0072: pop + IL_0073: ldstr "code" + IL_0078: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_007d: stloc.0 + IL_007e: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0083: ldloc.0 + IL_0084: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0089: pop + IL_008a: ldc.i4.4 + IL_008b: ldstr "code" + IL_0090: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0095: stloc.0 + IL_0096: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_009b: ldloc.0 + IL_009c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00a1: pop + IL_00a2: ldstr "code" + IL_00a7: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00ac: stloc.0 + IL_00ad: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00b2: ldloc.0 + IL_00b3: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00b8: pop + IL_00b9: ldstr "code" + IL_00be: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00c3: stloc.0 + IL_00c4: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00c9: ldloc.0 + IL_00ca: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00cf: pop + IL_00d0: ldstr "code" + IL_00d5: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00da: stloc.0 + IL_00db: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00e0: ldloc.0 + IL_00e1: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00e6: pop + IL_00e7: ldstr "code" + IL_00ec: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00f1: stloc.0 + IL_00f2: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00f7: ldloc.0 + IL_00f8: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00fd: pop + IL_00fe: ldstr "code" + IL_0103: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0108: stloc.0 + IL_0109: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_010e: ldloc.0 + IL_010f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0114: pop + IL_0115: ldc.i4.5 + IL_0116: add + IL_0117: ret +} + """ + ]) + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce delegate invoke via InlineIfLambda``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module InlineIfLambdaOnDelegate + +open System +type D = delegate of int -> int +type C = + static member inline M([] f: D) = f.Invoke 3 + f.Invoke 4 + + // Check M is inlined and optimized when small + static member M2() = C.M(D(fun x -> x + 1)) + + // Check M is inlined and optimized when large + static member M3() = + C.M(D(fun x -> + printfn("code") + printfn("code") + printfn("code") + printfn("code") + printfn("code") + printfn("code") + x + 1)) + """ + (fun verifier -> verifier.VerifyIL [ + // Check M is inlined and optimized when small + """ +.method public static int32 M2() cil managed +{ + + .maxstack 8 + IL_0000: ldc.i4.s 9 + IL_0002: ret +} + """ + // Check M is inlined and optimized when largs + """ +.method public static int32 M3() cil managed +{ + + .maxstack 5 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0) + IL_0000: ldstr "code" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldstr "code" + IL_001c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0021: stloc.0 + IL_0022: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0027: ldloc.0 + IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002d: pop + IL_002e: ldstr "code" + IL_0033: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0038: stloc.0 + IL_0039: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_003e: ldloc.0 + IL_003f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0044: pop + IL_0045: ldstr "code" + IL_004a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_004f: stloc.0 + IL_0050: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0055: ldloc.0 + IL_0056: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_005b: pop + IL_005c: ldstr "code" + IL_0061: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0066: stloc.0 + IL_0067: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_006c: ldloc.0 + IL_006d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0072: pop + IL_0073: ldstr "code" + IL_0078: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_007d: stloc.0 + IL_007e: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0083: ldloc.0 + IL_0084: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0089: pop + IL_008a: ldc.i4.4 + IL_008b: ldstr "code" + IL_0090: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0095: stloc.0 + IL_0096: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_009b: ldloc.0 + IL_009c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00a1: pop + IL_00a2: ldstr "code" + IL_00a7: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00ac: stloc.0 + IL_00ad: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00b2: ldloc.0 + IL_00b3: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00b8: pop + IL_00b9: ldstr "code" + IL_00be: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00c3: stloc.0 + IL_00c4: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00c9: ldloc.0 + IL_00ca: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00cf: pop + IL_00d0: ldstr "code" + IL_00d5: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00da: stloc.0 + IL_00db: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00e0: ldloc.0 + IL_00e1: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00e6: pop + IL_00e7: ldstr "code" + IL_00ec: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00f1: stloc.0 + IL_00f2: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00f7: ldloc.0 + IL_00f8: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00fd: pop + IL_00fe: ldstr "code" + IL_0103: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0108: stloc.0 + IL_0109: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_010e: ldloc.0 + IL_010f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0114: pop + IL_0115: ldc.i4.5 + IL_0116: add + IL_0117: ret +} + """ + ]) + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce computed function invoke``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module ReduceComputedFunction + +open System + +let ApplyComputedFunction(c: int) = + (let x = c+c in printfn("hello"); (fun y -> x + y)) 3 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 ApplyComputedFunction(int32 c) cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_1) + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: add + IL_0003: stloc.0 + IL_0004: ldstr "hello" + IL_0009: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000e: stloc.1 + IL_000f: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0014: ldloc.1 + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.0 + IL_001c: ldc.i4.3 + IL_001d: add + IL_001e: ret +} + """ + ]) + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce Computed Delegate``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module ReduceComputedDelegate + +open System +type D = delegate of int -> int +let ApplyComputedDelegate(c: int) = + (let x = c+c in printfn("hello"); D(fun y -> x + y)).Invoke 3 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 ApplyComputedDelegate(int32 c) cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_1) + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: add + IL_0003: stloc.0 + IL_0004: ldstr "hello" + IL_0009: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000e: stloc.1 + IL_000f: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0014: ldloc.1 + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.0 + IL_001c: ldc.i4.3 + IL_001d: add + IL_001e: ret +} + """ + ]) + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce Computed Function with irreducible match``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module ReduceComputedFunction + +open System + +let ApplyComputedFunction(c: int) = + (let x = c+c in printfn("hello"); match x with 1 -> (fun y -> x + y) | _ -> (fun y -> x - y)) 3 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 ApplyComputedFunction(int32 c) cil managed +{ + + .maxstack 4 + .locals init (int32 V_0, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_1) + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: add + IL_0003: stloc.0 + IL_0004: ldstr "hello" + IL_0009: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000e: stloc.1 + IL_000f: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0014: ldloc.1 + IL_0015: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_001a: pop + IL_001b: ldloc.0 + IL_001c: ldc.i4.1 + IL_001d: sub + IL_001e: switch ( + IL_0029) + IL_0027: br.s IL_002d + + IL_0029: ldloc.0 + IL_002a: ldc.i4.3 + IL_002b: add + IL_002c: ret + + IL_002d: ldloc.0 + IL_002e: ldc.i4.3 + IL_002f: sub + IL_0030: ret +} + """ + ]) + + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Immediately apply computed function in sequential``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module ImmediatelyApplyComputedFunction + +open System + +let ApplyComputedFunction(c: int) = + let part1 = match c with 1 -> (fun y -> printfn("a")) | _ -> (fun y -> printfn("b")) + part1 3 + printfn("done!") + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static void ApplyComputedFunction(int32 c) cil managed +{ + + .maxstack 4 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.1 + IL_0002: sub + IL_0003: switch ( + IL_000e) + IL_000c: br.s IL_0027 + + IL_000e: ldstr "a" + IL_0013: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0018: stloc.0 + IL_0019: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_001e: ldloc.0 + IL_001f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0024: pop + IL_0025: br.s IL_003e + + IL_0027: ldstr "b" + IL_002c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0031: stloc.0 + IL_0032: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0037: ldloc.0 + IL_0038: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_003d: pop + IL_003e: ldstr "done!" + IL_0043: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0048: stloc.0 + IL_0049: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_004e: ldloc.0 + IL_004f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0054: pop + IL_0055: ret +} + """ + ]) + + [] + // See https://github.com/fsharp/fslang-design/blob/master/tooling/FST-1034-lambda-optimizations.md + let ``Reduce Computed Delegate with let rec``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module ReduceComputedDelegate + +open System +type D = delegate of int -> int +let ApplyComputedDelegate(c: int) = + (let rec f x = if x = 0 then x else f (x-1) in printfn("hello"); D(fun y -> f c + y)).Invoke 3 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 ApplyComputedDelegate(int32 c) cil managed +{ + + .maxstack 4 + .locals init (class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_0) + IL_0000: ldstr "hello" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000a: stloc.0 + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0010: ldloc.0 + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [runtime]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: ldarg.0 + IL_0018: call int32 ReduceComputedDelegate::f@7(int32) + IL_001d: ldc.i4.3 + IL_001e: add + IL_001f: ret +} + """ + ]) + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/LiteralValue.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/LiteralValue.fs deleted file mode 100644 index 7431bd0397c..00000000000 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/LiteralValue.fs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL - -open FSharp.Compiler.UnitTests -open NUnit.Framework - -[] -module ``Literal Value`` = - - [] - let ``Literal Value``() = - CompilerAssert.CompileLibraryAndVerifyIL - """ -module LiteralValue - -[] -let x = 7 - -[] -let main _ = - 0 - """ - (fun verifier -> verifier.VerifyIL [ - """ -.field public static literal int32 x = int32(0x00000007) - """ - ]) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs index f90d93b5d4e..2546833ff0f 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs @@ -3,6 +3,7 @@ namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL open FSharp.Compiler.UnitTests +open FSharp.Test open NUnit.Framework [] @@ -27,16 +28,19 @@ type Test = struct .field public int32 v """ """ - .method public hidebysig instance void - setV
(!!a v) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldc.i4.0 - IL_0002: stfld int32 Mutation01/Test::v - IL_0007: ret - } + .method public hidebysig instance void + setV(!!a v) cil managed + { + + .maxstack 4 + .locals init (valuetype Mutation01/Test& V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldarg.0 + IL_0003: ldc.i4.0 + IL_0004: stfld int32 Mutation01/Test::v + IL_0009: ret + } """ ]) @@ -283,24 +287,20 @@ type StaticC() = { .maxstack 8 - IL_0000: volatile. - IL_0002: ldsfld int32 Mutation05/StaticC::init@10 - IL_0007: ldc.i4.1 - IL_0008: bge.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0017 - - IL_000e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() - IL_0013: nop - IL_0014: nop - IL_0015: br.s IL_0018 - - IL_0017: nop - IL_0018: volatile. - IL_001a: ldsfld int32 Mutation05/StaticC::x - IL_001f: ret + IL_0000: volatile. + IL_0002: ldsfld int32 Mutation05/StaticC::init@10 + IL_0007: ldc.i4.1 + IL_0008: bge.s IL_0013 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: nop + IL_0010: nop + IL_0011: br.s IL_0014 + + IL_0013: nop + IL_0014: volatile. + IL_0016: ldsfld int32 Mutation05/StaticC::x + IL_001b: ret } .method public specialname static void @@ -308,25 +308,21 @@ type StaticC() = { .maxstack 8 - IL_0000: volatile. - IL_0002: ldsfld int32 Mutation05/StaticC::init@10 - IL_0007: ldc.i4.1 - IL_0008: bge.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0017 - - IL_000e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() - IL_0013: nop - IL_0014: nop - IL_0015: br.s IL_0018 - - IL_0017: nop - IL_0018: ldarg.0 - IL_0019: volatile. - IL_001b: stsfld int32 Mutation05/StaticC::x - IL_0020: ret + IL_0000: volatile. + IL_0002: ldsfld int32 Mutation05/StaticC::init@10 + IL_0007: ldc.i4.1 + IL_0008: bge.s IL_0013 + + IL_000a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_000f: nop + IL_0010: nop + IL_0011: br.s IL_0014 + + IL_0013: nop + IL_0014: ldarg.0 + IL_0015: volatile. + IL_0017: stsfld int32 Mutation05/StaticC::x + IL_001c: ret } .method private specialname rtspecialname static @@ -357,4 +353,4 @@ type StaticC() = IL_000b: stsfld int32 Mutation05/StaticC::init@10 IL_0010: ret """ - ]) \ No newline at end of file + ]) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleFunction.debuginfo.expected b/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleFunction.debuginfo.expected new file mode 100644 index 00000000000..e33acec2b5e --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleFunction.debuginfo.expected @@ -0,0 +1,21 @@ +ENTRYPOINT + false + +DOCUMENTS + [0] + Type: None + Language: None + Vendor: None + +METHODS + f + Params: [] + Range: Some "[0,4:9] - [0,4:10]" + Points: + - Doc: 0 Offset:0 [4:5]-[4-14] + - Doc: 0 Offset:2 [5:5]-[5-6] + Scopes: + - [0-4] + - [1-4] + Locals: ["0: y"] + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleShadowingFunction.debuginfo.expected b/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleShadowingFunction.debuginfo.expected new file mode 100644 index 00000000000..6204777c113 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/SimpleShadowingFunction.debuginfo.expected @@ -0,0 +1,27 @@ +ENTRYPOINT + false + +DOCUMENTS + [0] + Type: None + Language: None + Vendor: None + +METHODS + f + Params: [] + Range: Some "[0,4:9] - [0,4:10]" + Points: + - Doc: 0 Offset:0 [4:5]-[4-14] + - Doc: 0 Offset:2 [5:5]-[5-16] + - Doc: 0 Offset:6 [6:5]-[6-16] + - Doc: 0 Offset:10 [7:5]-[7-6] + Scopes: + - [0-12] + - [1-5] + Locals: ["0: y"] + - [5-9] + Locals: ["0: y (shadowed)"; "1: y"] + - [9-12] + Locals: ["1: y (shadowed)"; "0: y (shadowed)"; "2: y"] + diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticLinkTests.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticLinkTests.fs index ad5c9eda65b..e07f0103ee2 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticLinkTests.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticLinkTests.fs @@ -4,7 +4,7 @@ namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL open System.IO open System.Reflection -open FSharp.Compiler.UnitTests +open FSharp.Test open NUnit.Framework [] @@ -236,9 +236,7 @@ let _ = List.iter (fun s -> eprintf "%s" s) ["hello"; " "; "world"] let _ = eprintfn "%s" "." let _ = exit 0 """ - let module1 = Compilation.Create(source, Fsx, Exe, [|"--standalone"|]) - CompilerAssert.Execute(module1, newProcess=true) [] @@ -254,4 +252,4 @@ let _ = exit 0 let module1 = Compilation.Create(source, Fsx, Exe, [|"--standalone"; "--optimize+"|]) - CompilerAssert.Execute(module1, newProcess=true) \ No newline at end of file + CompilerAssert.Execute(module1, newProcess=true) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs new file mode 100644 index 00000000000..459972bf5c6 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/StaticMember.fs @@ -0,0 +1,314 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +[] +module ``Static Member`` = + + [] + let ``Action on Static Member``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember01 + +open System +type C = + static member M() = () + static member CreateAction() = + new Action(C.M) + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [runtime]System.Action + CreateAction() cil managed +{ + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void StaticMember01/CreateAction@8::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret +} + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname CreateAction@8 + extends [runtime]System.Object + """ + ]) + + [] + let ``Action on Static Member with lambda``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember02 + +open System +type C = + static member M(x : int32) = () + static member CreateAction() = + new Action(fun x -> C.M x) + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [runtime]System.Action`1 + CreateAction() cil managed +{ + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void StaticMember02/CreateAction@8::Invoke(int32) + IL_0007: newobj instance void class [runtime]System.Action`1::.ctor(object, + native int) + IL_000c: ret +} + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname CreateAction@8 + extends [runtime]System.Object + """ + ]) + + [] + let ``Action on Static Member with closure``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember03 + +open System + +type C = + static member M(x: int32) = () + +type MyClass(x: int32) = + member this.X = x + +[] +let main _ = + let input = new MyClass(7) + let func = new Action(fun x -> C.M input.X) + box func |> ignore // make sure 'func' is not optimized away + 0 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 main(string[] _arg1) cil managed +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals init (class StaticMember03/MyClass V_0, + class [runtime]System.Action`1 V_1, + object V_2) + IL_0000: ldc.i4.7 + IL_0001: newobj instance void StaticMember03/MyClass::.ctor(int32) + IL_0006: stloc.0 + IL_0007: ldnull + IL_0008: ldftn void StaticMember03/func@15::Invoke(int32) + IL_000e: newobj instance void class [runtime]System.Action`1::.ctor(object, + native int) + IL_0013: stloc.1 + IL_0014: ldloc.1 + IL_0015: box class [runtime]System.Action`1 + IL_001a: stloc.2 + IL_001b: ldc.i4.0 + IL_001c: ret +} + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname func@15 + extends [runtime]System.Object + """ + ]) + + [] + let ``Func on Static Member``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember04 + +open System +type C = + static member M(x: int32) = + x + 1 + static member CreateFunc() = + new Func(C.M) + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [runtime]System.Func`2 + CreateFunc() cil managed +{ + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 StaticMember04/CreateFunc@9::Invoke(int32) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret +} + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname CreateFunc@9 + extends [runtime]System.Object + """ + ]) + + [] + let ``Func on Static Member with lambda``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember05 + +open System +type C = + static member M(x: int32) = + x + 43 + static member CreateFunc() = + new Func(fun x -> C.M x) + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static class [runtime]System.Func`2 + CreateFunc() cil managed +{ + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 StaticMember05/CreateFunc@9::Invoke(int32) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret +} + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname CreateFunc@9 + extends [runtime]System.Object + """ + ]) + + [] + let ``Func on Static Member with closure``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember06 + +open System + +type C = + static member M(x: int32) = + x + 43 + +type MyClass(x: int32) = + member this.X = x + +[] +let main _ = + let input = new MyClass(7) + let func = new Func(fun x -> C.M input.X) + box func |> ignore // dummy code to prevent func being optimized away + 0 + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public static int32 main(string[] _arg1) cil managed +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals init (class StaticMember06/MyClass V_0, + class [runtime]System.Func`2 V_1, + object V_2) + IL_0000: ldc.i4.7 + IL_0001: newobj instance void StaticMember06/MyClass::.ctor(int32) + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: newobj instance void StaticMember06/func@16::.ctor(class StaticMember06/MyClass) + IL_000d: ldftn instance int32 StaticMember06/func@16::Invoke(int32) + IL_0013: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0018: stloc.1 + IL_0019: ldloc.1 + IL_001a: box class [runtime]System.Func`2 + IL_001f: stloc.2 + IL_0020: ldc.i4.0 + IL_0021: ret +} + """ + """ +.class auto autochar serializable sealed nested assembly beforefieldinit specialname func@16 + extends [runtime]System.Object + """ + ]) + +#if !FX_NO_WINFORMS + [] + let ``EventHandler from Regression/83``() = + CompilerAssert.CompileLibraryAndVerifyIL + """ +module StaticMember07 + +// #Regression +let failures = ref false +let report_failure () = + System.Console.Error.WriteLine " NO"; failures := true + +open System +open System.Windows.Forms + +let form = new Form() + +let lblHello = new Label() +let btnSay = new Button() + +let btnSay_Click(sender, e) = + lblHello.Text <- "Hello" + +let form_Load(sender, e) = + btnSay.add_Click(new EventHandler(fun sender e -> btnSay_Click(sender, e))) + + + +let _ = lblHello.Location <- new System.Drawing.Point(16, 16) +let _ = lblHello.Name <- "lblHello" +let _ = lblHello.Size <- new System.Drawing.Size(72, 23) +let _ = lblHello.TabIndex <- 0 + +let _ = btnSay.Location <- new System.Drawing.Point(216, 16) +let _ = btnSay.Name <- "btnApply" +let _ = btnSay.TabIndex <- 1 +let _ = btnSay.Text <- "Apply" + +let _ = form.Text <- "1st F# App" +let _ = form.add_Load(new EventHandler(fun sender e -> form_Load(sender, e))) +let _ = form.Controls.AddRange(Array.ofList [(upcast (lblHello) : Control); + (upcast (btnSay) : Control); + ]) + +(* let _ = Application.Run(form) *) + +let _ = + if !failures then (System.Console.Out.WriteLine "Test Failed"; exit 1) + +do (System.Console.Out.WriteLine "Test Passed"; + System.IO.File.WriteAllText("test.ok", "ok"); + exit 0) + """ + (fun verifier -> verifier.VerifyIL [ + """ +IL_00bc: ldnull +IL_00bd: ldftn void StaticMember07/clo@36::Invoke(object, + class [runtime]System.EventArgs) +IL_00c3: newobj instance void [runtime]System.EventHandler::.ctor(object, + native int) +IL_00c8: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Form::add_Load(class [runtime]System.EventHandler) + """ + """ +.class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname clo@36 + extends [runtime]System.Object + """ + ]) +#endif diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/TailCalls.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/TailCalls.fs deleted file mode 100644 index a61bd24ecb6..00000000000 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/TailCalls.fs +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL - -open FSharp.Compiler.UnitTests -open NUnit.Framework - -[] -module ``TailCalls`` = - // Regression test for DevDiv:72571 - - [] - let ``TailCall 01``() = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"; "--tailcalls+"|] - """ -module TailCall01 -let foo(x:int, y) = printfn "%d" x -let run() = let x = 0 in foo(x,5) - """ - (fun verifier -> verifier.VerifyIL [ - """ - .method public static void foo(int32 x, - !!a y) cil managed - { - - .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - int32 V_1) - IL_0000: ldstr "%d" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: ldarg.0 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldloc.1 - IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0019: pop - IL_001a: ret - } - """ - """ - .method public static void run() cil managed - { - - .maxstack 4 - .locals init (int32 V_0) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: ldloc.0 - IL_0003: ldc.i4.5 - IL_0004: tail. - IL_0006: call void TailCall01::foo(int32, - !!0) - IL_000b: ret - } - """ - ]) - - [] - let ``TailCall 02``() = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"; "--tailcalls+"|] - """ -module TailCall02 -let foo(x:int byref) = x -let run() = let mutable x = 0 in foo(&x) - """ - (fun verifier -> verifier.VerifyIL [ - """ - .method public static int32 foo(int32& x) cil managed - { - - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldobj [runtime]System.Int32 - IL_0006: ret - } - """ - """ - .method public static int32 run() cil managed - { - - .maxstack 3 - .locals init (int32 V_0) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: call int32 TailCall02::foo(int32&) - IL_0009: ret - } - """ - ]) - - [] - let ``TailCall 03``() = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"; "--tailcalls+"|] - """ -module TailCall03 -let foo (x:int byref) (y:int byref) z = printfn "%d" (x+y) -let run() = let mutable x = 0 in foo &x &x 5 - """ - (fun verifier -> verifier.VerifyIL [ - """ - .method public static void foo(int32& x, - int32& y, - !!a z) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 - 00 00 00 00 ) - - .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - int32 V_1) - IL_0000: ldstr "%d" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: ldarg.0 - IL_0011: ldobj [runtime]System.Int32 - IL_0016: ldarg.1 - IL_0017: ldobj [runtime]System.Int32 - IL_001c: add - IL_001d: stloc.1 - IL_001e: ldloc.0 - IL_001f: ldloc.1 - IL_0020: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0025: pop - IL_0026: ret - } - """ - """ - .method public static void run() cil managed - { - - .maxstack 5 - .locals init (int32 V_0) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: ldloca.s V_0 - IL_0006: ldc.i4.5 - IL_0007: call void TailCall03::foo(int32&, - int32&, - !!0) - IL_000c: nop - IL_000d: ret - } - """ - ]) - - [] - let ``TailCall 04``() = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"; "--tailcalls+"|] - """ -module TailCall04 -let foo(x:int byref, y) = printfn "%d" x -let run() = let mutable x = 0 in foo(&x,5) - """ - (fun verifier -> verifier.VerifyIL [ - """ - .method public static void foo(int32& x, - !!a y) cil managed - { - - .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - int32 V_1) - IL_0000: ldstr "%d" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: ldarg.0 - IL_0011: ldobj [runtime]System.Int32 - IL_0016: stloc.1 - IL_0017: ldloc.0 - IL_0018: ldloc.1 - IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001e: pop - IL_001f: ret - } - """ - """ - .method public static void run() cil managed - { - - .maxstack 4 - .locals init (int32 V_0) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: ldc.i4.5 - IL_0005: call void TailCall04::foo(int32&, - !!0) - IL_000a: nop - IL_000b: ret - - """ - ]) - - [] - let ``TailCall 05``() = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [|"-g"; "--optimize-"; "--tailcalls+"|] - """ -module TailCall05 -let foo(x:int byref, y:int byref, z) = printfn "%d" (x+y) -let run() = let mutable x = 0 in foo(&x,&x,5) - """ - (fun verifier -> verifier.VerifyIL [ - """ - .method public static void foo(int32& x, - int32& y, - !!a z) cil managed - { - - .maxstack 4 - .locals init (class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - int32 V_1) - IL_0000: ldstr "%d" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [runtime]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: ldarg.0 - IL_0011: ldobj [runtime]System.Int32 - IL_0016: ldarg.1 - IL_0017: ldobj [runtime]System.Int32 - IL_001c: add - IL_001d: stloc.1 - IL_001e: ldloc.0 - IL_001f: ldloc.1 - IL_0020: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0025: pop - IL_0026: ret - } - """ - """ - .method public static void run() cil managed - { - - .maxstack 5 - .locals init (int32 V_0) - IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: ldloca.s V_0 - IL_0004: ldloca.s V_0 - IL_0006: ldc.i4.5 - IL_0007: call void TailCall05::foo(int32&, - int32&, - !!0) - IL_000c: nop - IL_000d: ret - } - """ - ]) \ No newline at end of file diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs new file mode 100644 index 00000000000..d75e1849213 --- /dev/null +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs @@ -0,0 +1,1143 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.CodeGen.EmittedIL + +open FSharp.Test +open NUnit.Framework + +open System +open System.Threading.Tasks + +// These tests are sensitive to the fact that FSharp.Core is compiled release, not debug +// The code generated changes slightly in debug mode +#if !DEBUG +// Check the exact code produced for tasks +[] +module TaskGeneratedCode = + + // This tests the exact optimized code generated for the MoveNext for a trivial task - we expect 'MoveNext' to be there + // because state machine compilation succeeds + // + // The code is not perfect - because the MoveNext is generated late - but the JIT does a good job on it. + // + // The try/catch for the task still exists even though there is no chance of an exception + // + // The crucial code for "return 1" is really just + // IL_000e: ldc.i4.1 + // IL_000f: stfld int32 Test/testTask@4::Result + + [] + let ``check MoveNext of simple task debug``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize-";"/debug:portable";"/tailcalls-" |] + """ +module Test + +let testTask() = task { return 1 } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void +MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + int32 V_3, + class [runtime]System.Exception V_4, + class [runtime]System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.1 + IL_0008: stloc.3 + IL_0009: ldarg.0 + IL_000a: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_000f: ldloc.3 + IL_0010: stfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0015: ldc.i4.1 + IL_0016: stloc.2 + IL_0017: ldloc.2 + IL_0018: brfalse.s IL_0037 + + IL_001a: ldarg.0 + IL_001b: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0020: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0025: ldarg.0 + IL_0026: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_002b: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0030: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_0035: leave.s IL_0045 + + IL_0037: leave.s IL_0045 + + } + catch [runtime]System.Object + { + IL_0039: castclass [runtime]System.Exception + IL_003e: stloc.s V_4 + IL_0040: ldloc.s V_4 + IL_0042: stloc.1 + IL_0043: leave.s IL_0045 + + } + IL_0045: ldloc.1 + IL_0046: stloc.s V_5 + IL_0048: ldloc.s V_5 + IL_004a: brtrue.s IL_004d + + IL_004c: ret + + IL_004d: ldarg.0 + IL_004e: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0053: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0058: ldloc.s V_5 + IL_005a: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_005f: ret +} + """ + ]) + + // This tests the exact optimized code generated for the MoveNext for a trivial task - we expect 'MoveNext' to be there + // because state machine compilation succeeds + // + // The code is not perfect - because the MoveNext is generated late - but the JIT does a good job on it. + // + // The try/catch for the task still exists even though there is no chance of an exception + // + // The crucial code for "return 1" is really just + // IL_000e: ldc.i4.1 + // IL_000f: stfld int32 Test/testTask@4::Result + + [] + let ``check MoveNext of simple task optimized``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize+";"/debug:portable";"/tailcalls+" |] + """ +module Test + +let testTask() = task { return 1 } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + class [runtime]System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldarg.0 + IL_0008: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_000d: ldc.i4.1 + IL_000e: stfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0013: ldc.i4.1 + IL_0014: stloc.2 + IL_0015: ldloc.2 + IL_0016: brfalse.s IL_0035 + + IL_0018: ldarg.0 + IL_0019: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_001e: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0023: ldarg.0 + IL_0024: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0029: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_002e: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_0033: leave.s IL_0041 + + IL_0035: leave.s IL_0041 + + } + catch [runtime]System.Object + { + IL_0037: castclass [runtime]System.Exception + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: stloc.1 + IL_003f: leave.s IL_0041 + + } + IL_0041: ldloc.1 + IL_0042: stloc.3 + IL_0043: ldloc.3 + IL_0044: brtrue.s IL_0047 + + IL_0046: ret + + IL_0047: ldarg.0 + IL_0048: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_004d: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0052: ldloc.3 + IL_0053: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_0058: ret +} + """ + ]) + + + [] + let ``check MoveNext of simple binding task debug``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview"; "/debug:portable"; "/optimize-"; "/tailcalls-" |] + """ +module Test +open System.Threading.Tasks +let testTask(t: Task) = task { let! res = t in return res+1 } + """ + (fun verifier -> verifier.VerifyIL [ + """ + .method public strict virtual instance void + MoveNext() cil managed + { + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 5 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + class [runtime]System.Threading.Tasks.Task`1 V_3, + bool V_4, + bool V_5, + int32 V_6, + int32 V_7, + int32 V_8, + int32 V_9, + valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 V_10, + class [runtime]System.Exception V_11, + class [runtime]System.Exception V_12) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.1 + IL_0009: sub + IL_000a: switch ( + IL_0015) + IL_0013: br.s IL_0018 + + IL_0015: nop + IL_0016: br.s IL_0019 + + IL_0018: nop + .try + { + IL_0019: ldloc.0 + IL_001a: ldc.i4.1 + IL_001b: sub + IL_001c: switch ( + IL_0027) + IL_0025: br.s IL_002a + + IL_0027: nop + IL_0028: br.s IL_0053 + + IL_002a: nop + IL_002b: ldarg.0 + IL_002c: ldfld class [runtime]System.Threading.Tasks.Task`1 Test/testTask@4::t + IL_0031: stloc.3 + IL_0032: ldarg.0 + IL_0033: ldloc.3 + IL_0034: callvirt instance valuetype [netstandard]System.Runtime.CompilerServices.TaskAwaiter`1 class [netstandard]System.Threading.Tasks.Task`1::GetAwaiter() + IL_0039: stfld valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 Test/testTask@4::awaiter + IL_003e: ldc.i4.1 + IL_003f: stloc.s V_4 + IL_0041: ldarg.0 + IL_0042: ldflda valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 Test/testTask@4::awaiter + IL_0047: call instance bool valuetype [netstandard]System.Runtime.CompilerServices.TaskAwaiter`1::get_IsCompleted() + IL_004c: brfalse.s IL_0050 + + IL_004e: br.s IL_0069 + + IL_0050: ldc.i4.0 + IL_0051: brfalse.s IL_0057 + + IL_0053: ldc.i4.1 + IL_0054: nop + IL_0055: br.s IL_0060 + + IL_0057: ldarg.0 + IL_0058: ldc.i4.1 + IL_0059: stfld int32 Test/testTask@4::ResumptionPoint + IL_005e: ldc.i4.0 + IL_005f: nop + IL_0060: stloc.s V_5 + IL_0062: ldloc.s V_5 + IL_0064: stloc.s V_4 + IL_0066: nop + IL_0067: br.s IL_006a + + IL_0069: nop + IL_006a: ldloc.s V_4 + IL_006c: brfalse.s IL_009a + + IL_006e: ldarg.0 + IL_006f: ldflda valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 Test/testTask@4::awaiter + IL_0074: call instance !0 valuetype [netstandard]System.Runtime.CompilerServices.TaskAwaiter`1::GetResult() + IL_0079: stloc.s V_6 + IL_007b: ldloc.s V_6 + IL_007d: stloc.s V_7 + IL_007f: ldloc.s V_7 + IL_0081: stloc.s V_8 + IL_0083: ldloc.s V_8 + IL_0085: ldc.i4.1 + IL_0086: add + IL_0087: stloc.s V_9 + IL_0089: ldarg.0 + IL_008a: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_008f: ldloc.s V_9 + IL_0091: stfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0096: ldc.i4.1 + IL_0097: nop + IL_0098: br.s IL_00b3 + + IL_009a: ldarg.0 + IL_009b: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_00a0: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_00a5: ldarg.0 + IL_00a6: ldflda valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 Test/testTask@4::awaiter + IL_00ab: ldarg.0 + IL_00ac: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::AwaitUnsafeOnCompleted,valuetype Test/testTask@4>(!!0&, + !!1&) + IL_00b1: ldc.i4.0 + IL_00b2: nop + IL_00b3: brfalse.s IL_00c1 + + IL_00b5: ldarg.0 + IL_00b6: ldloc.s V_10 + IL_00b8: stfld valuetype [runtime]System.Runtime.CompilerServices.TaskAwaiter`1 Test/testTask@4::awaiter + IL_00bd: ldc.i4.1 + IL_00be: nop + IL_00bf: br.s IL_00c3 + + IL_00c1: ldc.i4.0 + IL_00c2: nop + IL_00c3: stloc.2 + IL_00c4: ldloc.2 + IL_00c5: brfalse.s IL_00e4 + + IL_00c7: ldarg.0 + IL_00c8: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_00cd: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_00d2: ldarg.0 + IL_00d3: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_00d8: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_00dd: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_00e2: leave.s IL_00f2 + + IL_00e4: leave.s IL_00f2 + + } + catch [runtime]System.Object + { + IL_00e6: castclass [runtime]System.Exception + IL_00eb: stloc.s V_11 + IL_00ed: ldloc.s V_11 + IL_00ef: stloc.1 + IL_00f0: leave.s IL_00f2 + + } + IL_00f2: ldloc.1 + IL_00f3: stloc.s V_12 + IL_00f5: ldloc.s V_12 + IL_00f7: brtrue.s IL_00fa + + IL_00f9: ret + + IL_00fa: ldarg.0 + IL_00fb: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0100: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0105: ldloc.s V_12 + IL_0107: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_010c: ret + } + """ + ]) + +module TaskTryFinallyGeneration = + + [] + let ``check MoveNext of task try/finally optimized``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize+";"/debug:portable";"/tailcalls+" |] + """ +module Test + +let testTask() = task { try 1+1 finally System.Console.WriteLine("finally") } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.0 + IL_0008: stloc.3 + IL_0009: ldloc.3 + IL_000a: brfalse.s IL_0010 + + IL_000c: ldc.i4.1 + IL_000d: nop + IL_000e: br.s IL_0012 + + IL_0010: ldloc.3 + IL_0011: nop + IL_0012: stloc.3 + .try + { + IL_0013: nop + IL_0014: ldc.i4.1 + IL_0015: stloc.s V_4 + IL_0017: ldloc.s V_4 + IL_0019: stloc.3 + IL_001a: leave.s IL_003b + + } + catch [runtime]System.Object + { + IL_001c: castclass [runtime]System.Exception + IL_0021: stloc.s V_5 + IL_0023: ldstr "finally" + IL_0028: call void [runtime]System.Console::WriteLine(string) + IL_002d: ldc.i4.1 + IL_002e: stloc.s V_4 + IL_0030: rethrow + IL_0032: ldnull + IL_0033: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit + IL_0038: pop + IL_0039: leave.s IL_003b + + } + IL_003b: ldloc.3 + IL_003c: brfalse.s IL_004e + + IL_003e: ldstr "finally" + IL_0043: call void [runtime]System.Console::WriteLine(string) + IL_0048: ldc.i4.1 + IL_0049: stloc.s V_4 + IL_004b: nop + IL_004c: br.s IL_004f + + IL_004e: nop + IL_004f: ldloc.3 + IL_0050: stloc.2 + IL_0051: ldloc.2 + IL_0052: brfalse.s IL_0071 + + IL_0054: ldarg.0 + IL_0055: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_005a: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_005f: ldarg.0 + IL_0060: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0065: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_006a: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_006f: leave.s IL_007f + + IL_0071: leave.s IL_007f + + } + catch [runtime]System.Object + { + IL_0073: castclass [runtime]System.Exception + IL_0078: stloc.s V_5 + IL_007a: ldloc.s V_5 + IL_007c: stloc.1 + IL_007d: leave.s IL_007f + + } + IL_007f: ldloc.1 + IL_0080: stloc.s V_5 + IL_0082: ldloc.s V_5 + IL_0084: brtrue.s IL_0087 + + IL_0086: ret + + IL_0087: ldarg.0 + IL_0088: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_008d: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0092: ldloc.s V_5 + IL_0094: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_0099: ret +} + """ + ]) + + + [] + let ``check MoveNext of task try/finally debug``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize-";"/debug:portable";"/tailcalls-" |] + """ +module Test + +let testTask() = task { try 1+1 finally System.Console.WriteLine("finally") } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5, + bool V_6, + bool V_7, + class [runtime]System.Exception V_8, + class [runtime]System.Exception V_9) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.0 + IL_0008: stloc.3 + IL_0009: ldloc.3 + IL_000a: brfalse.s IL_0010 + + IL_000c: ldc.i4.1 + IL_000d: nop + IL_000e: br.s IL_0012 + + IL_0010: ldloc.3 + IL_0011: nop + IL_0012: stloc.3 + .try + { + IL_0013: nop + IL_0014: ldc.i4.1 + IL_0015: stloc.s V_4 + IL_0017: ldloc.s V_4 + IL_0019: stloc.3 + IL_001a: leave.s IL_003b + + } + catch [runtime]System.Object + { + IL_001c: castclass [runtime]System.Exception + IL_0021: stloc.s V_5 + IL_0023: ldstr "finally" + IL_0028: call void [runtime]System.Console::WriteLine(string) + IL_002d: ldc.i4.1 + IL_002e: stloc.s V_6 + IL_0030: rethrow + IL_0032: ldnull + IL_0033: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit + IL_0038: pop + IL_0039: leave.s IL_003b + + } + IL_003b: ldloc.3 + IL_003c: brfalse.s IL_004e + + IL_003e: ldstr "finally" + IL_0043: call void [runtime]System.Console::WriteLine(string) + IL_0048: ldc.i4.1 + IL_0049: stloc.s V_7 + IL_004b: nop + IL_004c: br.s IL_004f + + IL_004e: nop + IL_004f: ldloc.3 + IL_0050: stloc.2 + IL_0051: ldloc.2 + IL_0052: brfalse.s IL_0071 + + IL_0054: ldarg.0 + IL_0055: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_005a: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_005f: ldarg.0 + IL_0060: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0065: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_006a: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_006f: leave.s IL_007f + + IL_0071: leave.s IL_007f + + } + catch [runtime]System.Object + { + IL_0073: castclass [runtime]System.Exception + IL_0078: stloc.s V_8 + IL_007a: ldloc.s V_8 + IL_007c: stloc.1 + IL_007d: leave.s IL_007f + + } + IL_007f: ldloc.1 + IL_0080: stloc.s V_9 + IL_0082: ldloc.s V_9 + IL_0084: brtrue.s IL_0087 + + IL_0086: ret + + IL_0087: ldarg.0 + IL_0088: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_008d: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0092: ldloc.s V_9 + IL_0094: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_0099: ret +} + """ + ]) + +module TaskTryWithGeneration = + + [] + let ``check MoveNext of task try/with optimized``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize+";"/debug:portable";"/tailcalls+" |] + """ +module Test + +let testTask() = task { try 1 with e -> System.Console.WriteLine("finally"); 2 } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5, + bool V_6, + class [runtime]System.Exception V_7) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.0 + IL_0008: stloc.3 + IL_0009: ldc.i4.0 + IL_000a: stloc.s V_4 + IL_000c: ldnull + IL_000d: stloc.s V_5 + IL_000f: ldloc.3 + IL_0010: brfalse.s IL_0016 + + IL_0012: ldc.i4.1 + IL_0013: nop + IL_0014: br.s IL_0018 + + IL_0016: ldloc.3 + IL_0017: nop + IL_0018: stloc.3 + .try + { + IL_0019: nop + IL_001a: ldc.i4.1 + IL_001b: stloc.s V_6 + IL_001d: ldloc.s V_6 + IL_001f: stloc.3 + IL_0020: leave.s IL_0032 + + } + catch [runtime]System.Object + { + IL_0022: castclass [runtime]System.Exception + IL_0027: stloc.s V_7 + IL_0029: ldc.i4.1 + IL_002a: stloc.s V_4 + IL_002c: ldloc.s V_7 + IL_002e: stloc.s V_5 + IL_0030: leave.s IL_0032 + + } + IL_0032: ldloc.s V_4 + IL_0034: brfalse.s IL_0048 + + IL_0036: ldloc.s V_5 + IL_0038: stloc.s V_7 + IL_003a: ldstr "finally" + IL_003f: call void [runtime]System.Console::WriteLine(string) + IL_0044: ldc.i4.1 + IL_0045: nop + IL_0046: br.s IL_004a + + IL_0048: ldloc.3 + IL_0049: nop + IL_004a: stloc.2 + IL_004b: ldloc.2 + IL_004c: brfalse.s IL_006b + + IL_004e: ldarg.0 + IL_004f: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0054: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0059: ldarg.0 + IL_005a: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_005f: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0064: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_0069: leave.s IL_0079 + + IL_006b: leave.s IL_0079 + + } + catch [runtime]System.Object + { + IL_006d: castclass [runtime]System.Exception + IL_0072: stloc.s V_5 + IL_0074: ldloc.s V_5 + IL_0076: stloc.1 + IL_0077: leave.s IL_0079 + + } + IL_0079: ldloc.1 + IL_007a: stloc.s V_5 + IL_007c: ldloc.s V_5 + IL_007e: brtrue.s IL_0081 + + IL_0080: ret + + IL_0081: ldarg.0 + IL_0082: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0087: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_008c: ldloc.s V_5 + IL_008e: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_0093: ret +} + """ + ]) + + + [] + let ``check MoveNext of task try/with debug``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize-";"/debug:portable";"/tailcalls-" |] + """ +module Test + +let testTask() = task { try 1 with e -> System.Console.WriteLine("with"); 2 } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5, + bool V_6, + class [runtime]System.Exception V_7, + class [runtime]System.Exception V_8, + class [runtime]System.Exception V_9, + class [runtime]System.Exception V_10, + class [runtime]System.Exception V_11) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@4::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.0 + IL_0008: stloc.3 + IL_0009: ldc.i4.0 + IL_000a: stloc.s V_4 + IL_000c: ldnull + IL_000d: stloc.s V_5 + IL_000f: ldloc.3 + IL_0010: brfalse.s IL_0016 + + IL_0012: ldc.i4.1 + IL_0013: nop + IL_0014: br.s IL_0018 + + IL_0016: ldloc.3 + IL_0017: nop + IL_0018: stloc.3 + .try + { + IL_0019: nop + IL_001a: ldc.i4.1 + IL_001b: stloc.s V_6 + IL_001d: ldloc.s V_6 + IL_001f: stloc.3 + IL_0020: leave.s IL_0032 + + } + catch [runtime]System.Object + { + IL_0022: castclass [runtime]System.Exception + IL_0027: stloc.s V_7 + IL_0029: ldc.i4.1 + IL_002a: stloc.s V_4 + IL_002c: ldloc.s V_7 + IL_002e: stloc.s V_5 + IL_0030: leave.s IL_0032 + + } + IL_0032: ldloc.s V_4 + IL_0034: brfalse.s IL_004c + + IL_0036: ldloc.s V_5 + IL_0038: stloc.s V_8 + IL_003a: ldloc.s V_8 + IL_003c: stloc.s V_9 + IL_003e: ldstr "with" + IL_0043: call void [runtime]System.Console::WriteLine(string) + IL_0048: ldc.i4.1 + IL_0049: nop + IL_004a: br.s IL_004e + + IL_004c: ldloc.3 + IL_004d: nop + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: brfalse.s IL_006f + + IL_0052: ldarg.0 + IL_0053: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0058: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_005d: ldarg.0 + IL_005e: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_0063: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_0068: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_006d: leave.s IL_007d + + IL_006f: leave.s IL_007d + + } + catch [runtime]System.Object + { + IL_0071: castclass [runtime]System.Exception + IL_0076: stloc.s V_10 + IL_0078: ldloc.s V_10 + IL_007a: stloc.1 + IL_007b: leave.s IL_007d + + } + IL_007d: ldloc.1 + IL_007e: stloc.s V_11 + IL_0080: ldloc.s V_11 + IL_0082: brtrue.s IL_0085 + + IL_0084: ret + + IL_0085: ldarg.0 + IL_0086: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@4::Data + IL_008b: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0090: ldloc.s V_11 + IL_0092: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_0097: ret +} + """ + ]) + +module TaskWhileLoopGeneration = + + [] + let ``check MoveNext of task while loop optimized``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize+";"/debug:portable";"/tailcalls+" |] + """ +module Test + +let mutable x = 1 +let testTask() = task { while x > 4 do System.Console.WriteLine("loop") } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@5::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.1 + IL_0008: stloc.3 + IL_0009: nop + IL_000a: ldloc.3 + IL_000b: brfalse.s IL_0018 + + IL_000d: call int32 Test::get_x() + IL_0012: ldc.i4.4 + IL_0013: cgt + IL_0015: nop + IL_0016: br.s IL_001a + + IL_0018: ldc.i4.0 + IL_0019: nop + IL_001a: brfalse.s IL_0031 + + IL_001c: ldstr "loop" + IL_0021: call void [runtime]System.Console::WriteLine(string) + IL_0026: ldc.i4.1 + IL_0027: stloc.s V_4 + IL_0029: ldloc.s V_4 + IL_002b: stloc.3 + IL_002c: ldc.i4.0 + IL_002d: stloc.0 + IL_002e: nop + IL_002f: br.s IL_0009 + + IL_0031: ldloc.3 + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: brfalse.s IL_0053 + + IL_0036: ldarg.0 + IL_0037: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_003c: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0041: ldarg.0 + IL_0042: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_0047: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_004c: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_0051: leave.s IL_0061 + + IL_0053: leave.s IL_0061 + + } + catch [runtime]System.Object + { + IL_0055: castclass [runtime]System.Exception + IL_005a: stloc.s V_5 + IL_005c: ldloc.s V_5 + IL_005e: stloc.1 + IL_005f: leave.s IL_0061 + + } + IL_0061: ldloc.1 + IL_0062: stloc.s V_5 + IL_0064: ldloc.s V_5 + IL_0066: brtrue.s IL_0069 + + IL_0068: ret + + IL_0069: ldarg.0 + IL_006a: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_006f: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0074: ldloc.s V_5 + IL_0076: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_007b: ret +} + """ + ]) + + + [] + let ``check MoveNext of task while loop debug``() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions [| "/langversion:preview";"/optimize-";"/debug:portable";"/tailcalls-" |] + """ +module Test + +let mutable x = 1 +let testTask() = task { while x > 4 do System.Console.WriteLine("loop") } + """ + (fun verifier -> verifier.VerifyIL [ + """ +.method public strict virtual instance void + MoveNext() cil managed +{ + .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + + .maxstack 4 + .locals init (int32 V_0, + class [runtime]System.Exception V_1, + bool V_2, + bool V_3, + bool V_4, + class [runtime]System.Exception V_5, + class [runtime]System.Exception V_6) + IL_0000: ldarg.0 + IL_0001: ldfld int32 Test/testTask@5::ResumptionPoint + IL_0006: stloc.0 + .try + { + IL_0007: ldc.i4.1 + IL_0008: stloc.3 + IL_0009: nop + IL_000a: ldloc.3 + IL_000b: brfalse.s IL_0018 + + IL_000d: call int32 Test::get_x() + IL_0012: ldc.i4.4 + IL_0013: cgt + IL_0015: nop + IL_0016: br.s IL_001a + + IL_0018: ldc.i4.0 + IL_0019: nop + IL_001a: brfalse.s IL_0031 + + IL_001c: ldstr "loop" + IL_0021: call void [runtime]System.Console::WriteLine(string) + IL_0026: ldc.i4.1 + IL_0027: stloc.s V_4 + IL_0029: ldloc.s V_4 + IL_002b: stloc.3 + IL_002c: ldc.i4.0 + IL_002d: stloc.0 + IL_002e: nop + IL_002f: br.s IL_0009 + + IL_0031: ldloc.3 + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: brfalse.s IL_0053 + + IL_0036: ldarg.0 + IL_0037: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_003c: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0041: ldarg.0 + IL_0042: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_0047: ldfld !0 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::Result + IL_004c: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetResult(!0) + IL_0051: leave.s IL_0061 + + IL_0053: leave.s IL_0061 + + } + catch [runtime]System.Object + { + IL_0055: castclass [runtime]System.Exception + IL_005a: stloc.s V_5 + IL_005c: ldloc.s V_5 + IL_005e: stloc.1 + IL_005f: leave.s IL_0061 + + } + IL_0061: ldloc.1 + IL_0062: stloc.s V_6 + IL_0064: ldloc.s V_6 + IL_0066: brtrue.s IL_0069 + + IL_0068: ret + + IL_0069: ldarg.0 + IL_006a: ldflda valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1 Test/testTask@5::Data + IL_006f: ldflda valuetype [runtime]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 valuetype [FSharp.Core]Microsoft.FSharp.Control.TaskStateMachineData`1::MethodBuilder + IL_0074: ldloc.s V_6 + IL_0076: call instance void valuetype [netstandard]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1::SetException(class [netstandard]System.Exception) + IL_007b: ret +} + """ + ]) +#endif + + +#if NETCOREAPP +[] +module ``Check stack traces`` = + [] + let ``check stack trace of async exception from task``() = + let t() = + task { + let! throws = task { + do! System.Threading.Tasks.Task.Yield() + failwith "Inner task exception" + return () + } + return throws + } + + let f() = t().Wait() + + let stackTrace = try f(); failwith "huh?" with e -> e.ToString() + + if stackTrace.Contains("huh?") then + failwith "unexpected - inner exception not generated correctly" + + if not (stackTrace.Contains("MoveNext()")) then + failwith "expected MoveNext() on stack trace" + + if stackTrace.Contains("End of stack trace from previous location") then + failwith "expected emit of CompilerGeneratedAtrtibute to suppress message in .NET Core stack walking " +#endif + + +// Test that the SRTP Bind on a ValueTask is still generic in the bind type +[] +module ``Check return attributes`` = + let incr (x:int) : [] (int -> int) = (fun a -> a + x) + + // Putting a return atribute of any kind on f function should be respected + // If the function is curried its inferred arity should be no more than + // the declared arguments (the F# rule that infers additional arguments + // should not kick in). + [] + let ``check return attribute of curried function``() = + match <@ incr 3 4 @> with + | Quotations.Patterns.Application (Quotations.Patterns.Call(None, mi, [Quotations.DerivedPatterns.Int32 3]), Quotations.DerivedPatterns.Int32 4) -> + if mi.GetParameters().Length <> 1 then + failwith "wrong number of parameters" + if mi.ReturnTypeCustomAttributes.GetCustomAttributes(false).Length <> 1 then + failwith "wrong number of attributes" + () + | _ -> failwith "curried function expected" + + +// Compilation test +// Test that the SRTP Bind on a ValueTask is still generic in the bind type +module ``SRTP Bind on a ValueTask is still generic in the bind type (nested)`` = + let FindAsync() = ValueTask<'T>(Unchecked.defaultof<'T>) + let TryFindAsync() : Task<'T voption> = task { + let! r = FindAsync() + if obj.ReferenceEquals(r, null) then return ValueNone + else return ValueSome r + } + let t1 : Task = TryFindAsync() // test TryFindAsync is generic + let t2 : Task = TryFindAsync() // test TryFindAsync is generic + +// Compilation test +// Test that the SRTP Bind on a ValueTask is still generic in the bind type +module ``SRTP Bind on a ValueTask is still generic in the bind type`` = + let FindAsync() = ValueTask<'T>(Unchecked.defaultof<'T>) + let TryFindAsync() : Task<'T> = task { + let! r = FindAsync() + return r + } + +// Compilation test +module ``SRTP ReturnFrom on a ValueTask is still generic in the bind type`` = + let FindAsync() = ValueTask<'T>(Unchecked.defaultof<'T>) + let TryFindAsync() : Task<'T> = task { + return! FindAsync() + } + + let t1 : Task = TryFindAsync() // test TryFindAsync is generic + let t2 : Task = TryFindAsync() // test TryFindAsync is generic + diff --git a/tests/fsharp/Compiler/CompilerAssert.fs b/tests/fsharp/Compiler/CompilerAssert.fs deleted file mode 100644 index 9f0bc09553b..00000000000 --- a/tests/fsharp/Compiler/CompilerAssert.fs +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -[] -module FSharp.Compiler.UnitTests.CompilerAssert - -open System -open System.Diagnostics -open System.IO -open System.Text -open System.Diagnostics -open System.Reflection -open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Interactive.Shell -#if FX_NO_APP_DOMAINS -open System.Runtime.Loader -#endif -open NUnit.Framework -open System.Reflection.Emit - -[] -type ILVerifier (dllFilePath: string) = - - member this.VerifyIL (qualifiedItemName: string, expectedIL: string) = - ILChecker.checkILItem qualifiedItemName dllFilePath [ expectedIL ] - - member this.VerifyIL (expectedIL: string list) = - ILChecker.checkIL dllFilePath expectedIL - - member this.VerifyILWithLineNumbers (qualifiedItemName: string, expectedIL: string) = - ILChecker.checkILItemWithLineNumbers qualifiedItemName dllFilePath [ expectedIL ] - -type Worker () = - inherit MarshalByRefObject() - - member x.ExecuteTestCase assemblyPath (deps: string[]) = - AppDomain.CurrentDomain.add_AssemblyResolve(ResolveEventHandler(fun _ args -> - deps - |> Array.tryFind (fun (x: string) -> Path.GetFileNameWithoutExtension x = args.Name) - |> Option.bind (fun x -> if File.Exists x then Some x else None) - |> Option.map Assembly.LoadFile - |> Option.defaultValue null)) - let asm = Assembly.LoadFrom(assemblyPath) - let entryPoint = asm.EntryPoint - (entryPoint.Invoke(Unchecked.defaultof, [||])) |> ignore - -type SourceKind = - | Fs - | Fsx - -type CompileOutput = - | Library - | Exe - -type CompilationReference = private CompilationReference of Compilation * staticLink: bool with - - static member CreateFSharp(cmpl: Compilation, ?staticLink) = - let staticLink = defaultArg staticLink false - CompilationReference(cmpl, staticLink) - -and Compilation = private Compilation of string * SourceKind * CompileOutput * options: string[] * CompilationReference list with - - static member Create(source, sourceKind, output, ?options, ?cmplRefs) = - let options = defaultArg options [||] - let cmplRefs = defaultArg cmplRefs [] - Compilation(source, sourceKind, output, options, cmplRefs) - -[] -type CompilerAssert private () = - - static let checker = FSharpChecker.Create(suggestNamesForErrors=true) - - static let config = TestFramework.initializeSuite () - - static let _ = config |> ignore - -// Do a one time dotnet sdk build to compute the proper set of reference assemblies to pass to the compiler -#if !NETCOREAPP -#else - static let projectFile = """ - - - - Exe - netcoreapp3.0 - true - true - - - - - - - - -""" - - static let programFs = """ -open System - -[] -let main argv = 0""" - - static let getNetCoreAppReferences = - let mutable output = "" - let mutable errors = "" - let mutable cleanUp = true - let projectDirectory = Path.Combine(Path.GetTempPath(), "CompilerAssert", Path.GetRandomFileName()) - try - try - Directory.CreateDirectory(projectDirectory) |> ignore - let projectFileName = Path.Combine(projectDirectory, "ProjectFile.fsproj") - let programFsFileName = Path.Combine(projectDirectory, "Program.fs") - let frameworkReferencesFileName = Path.Combine(projectDirectory, "FrameworkReferences.txt") - - File.WriteAllText(projectFileName, projectFile) - File.WriteAllText(programFsFileName, programFs) - - let pInfo = ProcessStartInfo () - - pInfo.FileName <- config.DotNetExe - pInfo.Arguments <- "build" - pInfo.WorkingDirectory <- projectDirectory - pInfo.RedirectStandardOutput <- true - pInfo.RedirectStandardError <- true - pInfo.UseShellExecute <- false - - let p = Process.Start(pInfo) - p.WaitForExit() - - output <- p.StandardOutput.ReadToEnd () - errors <- p.StandardError.ReadToEnd () - if not (String.IsNullOrWhiteSpace errors) then Assert.Fail errors - - if p.ExitCode <> 0 then Assert.Fail(sprintf "Program exited with exit code %d" p.ExitCode) - - File.ReadLines(frameworkReferencesFileName) |> Seq.toArray - with | e -> - cleanUp <- false - printfn "%s" output - printfn "%s" errors - raise (new Exception (sprintf "An error occured getting netcoreapp references: %A" e)) - finally - if cleanUp then - try Directory.Delete(projectDirectory) with | _ -> () -#endif - -#if FX_NO_APP_DOMAINS - static let executeBuiltApp assembly deps = - let ctxt = AssemblyLoadContext("ContextName", true) - try - let asm = ctxt.LoadFromAssemblyPath(assembly) - let entryPoint = asm.EntryPoint - ctxt.add_Resolving(fun ctxt name -> - deps - |> List.tryFind (fun (x: string) -> Path.GetFileNameWithoutExtension x = name.Name) - |> Option.map ctxt.LoadFromAssemblyPath - |> Option.defaultValue null) - (entryPoint.Invoke(Unchecked.defaultof, [||])) |> ignore - finally - ctxt.Unload() -#else - - static let pathToThisDll = Assembly.GetExecutingAssembly().CodeBase - - static let adSetup = - let setup = new System.AppDomainSetup () - setup.PrivateBinPath <- pathToThisDll - setup - - static let executeBuiltApp assembly deps = - let ad = AppDomain.CreateDomain((Guid()).ToString(), null, adSetup) - let worker = (ad.CreateInstanceFromAndUnwrap(pathToThisDll, typeof.FullName)) :?> Worker - worker.ExecuteTestCase assembly (deps |> Array.ofList) |>ignore -#endif - - static let defaultProjectOptions = - { - ProjectFileName = "Z:\\test.fsproj" - ProjectId = None - SourceFiles = [|"test.fs"|] -#if !NETCOREAPP - OtherOptions = [|"--preferreduilang:en-US";"--warn:5"|] -#else - OtherOptions = - let assemblies = getNetCoreAppReferences |> Array.map (fun x -> sprintf "-r:%s" x) - Array.append [|"--preferreduilang:en-US"; "--targetprofile:netcore"; "--noframework";"--warn:5"|] assemblies -#endif - ReferencedProjects = [||] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime() - UnresolvedReferences = None - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = None - } - - static let rawCompile inputFilePath outputFilePath isExe options source = - File.WriteAllText (inputFilePath, source) - let args = - options - |> Array.append defaultProjectOptions.OtherOptions - |> Array.append [| "fsc.exe"; inputFilePath; "-o:" + outputFilePath; (if isExe then "--target:exe" else "--target:library"); "--nowin32manifest" |] - let errors, _ = checker.Compile args |> Async.RunSynchronously - - errors, outputFilePath - - static let compileAux isExe options source f : unit = - let inputFilePath = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let outputFilePath = Path.ChangeExtension (Path.GetTempFileName(), if isExe then ".exe" else ".dll") - try - f (rawCompile inputFilePath outputFilePath isExe options source) - finally - try File.Delete inputFilePath with | _ -> () - try File.Delete outputFilePath with | _ -> () - - static let compileDisposable isScript isExe options source = - let ext = - if isScript then ".fsx" - else ".fs" - let inputFilePath = Path.ChangeExtension(Path.GetTempFileName(), ext) - let outputFilePath = Path.ChangeExtension (Path.GetTempFileName(), if isExe then ".exe" else ".dll") - let o = - { new IDisposable with - member _.Dispose() = - try File.Delete inputFilePath with | _ -> () - try File.Delete outputFilePath with | _ -> () } - try - o, rawCompile inputFilePath outputFilePath isExe options source - with - | _ -> - o.Dispose() - reraise() - - static let gate = obj () - - static let compile isExe options source f = - lock gate (fun _ -> compileAux isExe options source f) - - static let assertErrors ignoreWarnings (errors: FSharpErrorInfo[]) = - let errors = - if ignoreWarnings then - errors - |> Array.filter (fun error -> error.Severity <> FSharpErrorSeverity.Warning) - else - errors - if errors.Length > 0 then - Assert.Fail(sprintf "%A" errors) - - static let rec compileCompilationAux (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpErrorInfo[] * string) * string list = - let compilationRefs, deps = - match cmpl with - | Compilation(_, _, _, _, cmpls) -> - let compiledRefs = - cmpls - |> List.map (fun cmpl -> - match cmpl with - | CompilationReference (cmpl, staticLink) -> - compileCompilationAux disposals ignoreWarnings cmpl, staticLink) - - let compilationRefs = - compiledRefs - |> List.map (fun (((errors, outputFilePath), _), staticLink) -> - assertErrors ignoreWarnings errors - let rOption = "-r:" + outputFilePath - if staticLink then - [rOption;"--staticlink:" + Path.GetFileNameWithoutExtension outputFilePath] - else - [rOption]) - |> List.concat - |> Array.ofList - - let deps = - compiledRefs - |> List.map (fun ((_, deps), _) -> deps) - |> List.concat - |> List.distinct - - compilationRefs, deps - - let isScript = - match cmpl with - | Compilation(_, kind, _, _, _) -> - match kind with - | Fs -> false - | Fsx -> true - - let isExe = - match cmpl with - | Compilation(_, _, output, _, _) -> - match output with - | Library -> false - | Exe -> true - - let source = - match cmpl with - | Compilation(source, _, _, _, _) -> source - - let options = - match cmpl with - | Compilation(_, _, _, options, _) -> options - - let disposal, res = compileDisposable isScript isExe (Array.append options compilationRefs) source - disposals.Add disposal - - let deps2 = - compilationRefs - |> Array.filter (fun x -> not (x.Contains("--staticlink"))) - |> Array.map (fun x -> x.Replace("-r:", String.Empty)) - |> List.ofArray - - res, (deps @ deps2) - - static let rec compileCompilation ignoreWarnings (cmpl: Compilation) f = - let disposals = ResizeArray() - try - f (compileCompilationAux disposals ignoreWarnings cmpl) - finally - disposals - |> Seq.iter (fun x -> x.Dispose()) - - static member Compile(cmpl: Compilation, ?ignoreWarnings) = - let ignoreWarnings = defaultArg ignoreWarnings false - lock gate (fun () -> - compileCompilation ignoreWarnings cmpl (fun ((errors, _), _) -> - assertErrors ignoreWarnings errors)) - - static member Execute(cmpl: Compilation, ?ignoreWarnings, ?beforeExecute, ?newProcess) = - let ignoreWarnings = defaultArg ignoreWarnings false - let beforeExecute = defaultArg beforeExecute (fun _ _ -> ()) - let newProcess = defaultArg newProcess false - lock gate (fun () -> - compileCompilation ignoreWarnings cmpl (fun ((errors, outputFilePath), deps) -> - assertErrors ignoreWarnings errors - beforeExecute outputFilePath deps - if newProcess then - let mutable pinfo = ProcessStartInfo() - pinfo.RedirectStandardError <- true - pinfo.RedirectStandardOutput <- true -#if !NETCOREAPP - pinfo.FileName <- outputFilePath -#else - pinfo.FileName <- "dotnet" - pinfo.Arguments <- outputFilePath - - let runtimeconfig = - """ -{ - "runtimeOptions": { - "tfm": "netcoreapp3.1", - "framework": { - "name": "Microsoft.NETCore.App", - "version": "3.1.0" - } - } -} - """ - - let runtimeconfigPath = Path.ChangeExtension(outputFilePath, ".runtimeconfig.json") - File.WriteAllText(runtimeconfigPath, runtimeconfig) - use _disposal = - { new IDisposable with - member _.Dispose() = try File.Delete runtimeconfigPath with | _ -> () } -#endif - pinfo.UseShellExecute <- false - let p = Process.Start pinfo - let errors = p.StandardError.ReadToEnd() - Assert.True(p.WaitForExit(120000)) - if p.ExitCode <> 0 then - Assert.Fail errors - else - executeBuiltApp outputFilePath deps)) - - static member Pass (source: string) = - lock gate <| fun () -> - let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously - - Assert.IsEmpty(parseResults.Errors, sprintf "Parse errors: %A" parseResults.Errors) - - match fileAnswer with - | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") - | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> - - Assert.IsEmpty(typeCheckResults.Errors, sprintf "Type Check errors: %A" typeCheckResults.Errors) - - static member PassWithOptions options (source: string) = - lock gate <| fun () -> - let options = { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions} - - let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, options) |> Async.RunSynchronously - - Assert.IsEmpty(parseResults.Errors, sprintf "Parse errors: %A" parseResults.Errors) - - match fileAnswer with - | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") - | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> - - Assert.IsEmpty(typeCheckResults.Errors, sprintf "Type Check errors: %A" typeCheckResults.Errors) - - static member TypeCheckWithErrorsAndOptions options (source: string) expectedTypeErrors = - lock gate <| fun () -> - let parseResults, fileAnswer = - checker.ParseAndCheckFileInProject( - "test.fs", - 0, - SourceText.ofString source, - { defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions}) - |> Async.RunSynchronously - - Assert.IsEmpty(parseResults.Errors, sprintf "Parse errors: %A" parseResults.Errors) - - match fileAnswer with - | FSharpCheckFileAnswer.Aborted _ -> Assert.Fail("Type Checker Aborted") - | FSharpCheckFileAnswer.Succeeded(typeCheckResults) -> - - let errors = - typeCheckResults.Errors - |> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLineAlternate, e.StartColumn, e.EndLineAlternate, e.EndColumn, e.Message) - - Assert.AreEqual(Array.length expectedTypeErrors, errors.Length, sprintf "Type check errors: %A" errors) - - Array.zip errors expectedTypeErrors - |> Array.iter (fun (info, expectedError) -> - let (expectedServerity: FSharpErrorSeverity, expectedErrorNumber: int, expectedErrorRange: int * int * int * int, expectedErrorMsg: string) = expectedError - Assert.AreEqual(expectedServerity, info.Severity) - Assert.AreEqual(expectedErrorNumber, info.ErrorNumber, "expectedErrorNumber") - Assert.AreEqual(expectedErrorRange, (info.StartLineAlternate, info.StartColumn + 1, info.EndLineAlternate, info.EndColumn + 1), "expectedErrorRange") - Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg") - ) - - static member TypeCheckWithErrors (source: string) expectedTypeErrors = - CompilerAssert.TypeCheckWithErrorsAndOptions [||] source expectedTypeErrors - - static member TypeCheckSingleErrorWithOptions options (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) = - CompilerAssert.TypeCheckWithErrorsAndOptions options source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |] - - static member TypeCheckSingleError (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) = - CompilerAssert.TypeCheckWithErrors source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |] - - static member CompileExeWithOptions options (source: string) = - compile true options source (fun (errors, _) -> - if errors.Length > 0 then - Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)) - - static member CompileExe (source: string) = - CompilerAssert.CompileExeWithOptions [||] source - - static member CompileExeAndRunWithOptions options (source: string) = - compile true options source (fun (errors, outputExe) -> - - if errors.Length > 0 then - Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors) - - executeBuiltApp outputExe [] - ) - - static member CompileExeAndRun (source: string) = - CompilerAssert.CompileExeAndRunWithOptions [||] source - - static member CompileLibraryAndVerifyILWithOptions options (source: string) (f: ILVerifier -> unit) = - compile false options source (fun (errors, outputFilePath) -> - let errors = - errors |> Array.filter (fun x -> x.Severity = FSharpErrorSeverity.Error) - if errors.Length > 0 then - Assert.Fail (sprintf "Compile had errors: %A" errors) - - f (ILVerifier outputFilePath) - ) - - static member CompileLibraryAndVerifyIL (source: string) (f: ILVerifier -> unit) = - CompilerAssert.CompileLibraryAndVerifyILWithOptions [||] source f - - static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) = - lock gate <| fun () -> - // Intialize output and input streams - use inStream = new StringReader("") - use outStream = new StringWriter() - use errStream = new StringWriter() - - // Build command line arguments & start FSI session - let argv = [| "C:\\fsi.exe" |] - #if !NETCOREAPP - let args = Array.append argv [|"--noninteractive"|] - #else - let args = Array.append argv [|"--noninteractive"; "--targetprofile:netcore"|] - #endif - let allArgs = Array.append args options - - let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() - use fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream, collectible = true) - - let ch, errors = fsiSession.EvalInteractionNonThrowing source - - let errorMessages = ResizeArray() - errors - |> Seq.iter (fun error -> errorMessages.Add(error.Message)) - - match ch with - | Choice2Of2 ex -> errorMessages.Add(ex.Message) - | _ -> () - - if expectedErrorMessages.Length <> errorMessages.Count then - Assert.Fail(sprintf "Expected error messages: %A \n\n Actual error messages: %A" expectedErrorMessages errorMessages) - else - (expectedErrorMessages, errorMessages) - ||> Seq.iter2 (fun expectedErrorMessage errorMessage -> - Assert.AreEqual(expectedErrorMessage, errorMessage) - ) - - static member RunScript source expectedErrorMessages = - CompilerAssert.RunScriptWithOptions [||] source expectedErrorMessages - - static member ParseWithErrors (source: string) expectedParseErrors = - let sourceFileName = "test.fs" - let parsingOptions = { FSharpParsingOptions.Default with SourceFiles = [| sourceFileName |] } - let parseResults = checker.ParseFile(sourceFileName, SourceText.ofString source, parsingOptions) |> Async.RunSynchronously - - Assert.True(parseResults.ParseHadErrors) - - let errors = - parseResults.Errors - |> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLineAlternate, e.StartColumn, e.EndLineAlternate, e.EndColumn, e.Message) - - Assert.AreEqual(Array.length expectedParseErrors, errors.Length, sprintf "Parse errors: %A" parseResults.Errors) - - Array.zip errors expectedParseErrors - |> Array.iter (fun (info, expectedError) -> - let (expectedServerity: FSharpErrorSeverity, expectedErrorNumber: int, expectedErrorRange: int * int * int * int, expectedErrorMsg: string) = expectedError - Assert.AreEqual(expectedServerity, info.Severity) - Assert.AreEqual(expectedErrorNumber, info.ErrorNumber, "expectedErrorNumber") - Assert.AreEqual(expectedErrorRange, (info.StartLineAlternate, info.StartColumn + 1, info.EndLineAlternate, info.EndColumn + 1), "expectedErrorRange") - Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg") - ) diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs index edc84c07a6c..30b1e1aa4c3 100644 --- a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/BasicConstants.fs @@ -3,7 +3,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module ``Basic Grammar Element Constants`` = @@ -175,24 +176,52 @@ if x14 <> 0o52 then failwith "Wrong parsing" printfn "%A" x14 """ [] - let ``float without dot``() = - CompilerAssert.CompileExeWithOptions [|"--langversion:preview"|] + let ``dotless float``() = + CompilerAssert.CompileExeWithOptions [|"--langversion:5.0"|] """ let x = 42f printfn "%A" x """ - + [] - let ``float with dot``() = - CompilerAssert.CompileExeWithOptions [|"--langversion:preview"|] + let ``dotted float``() = + CompilerAssert.CompileExe """ let x = 42.f printfn "%A" x """ - + + [] + let ``dotted floats should be equal to dotless floats``() = + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] + """ +if 1.0f <> 1f then failwith "1.0f <> 1f" + """ + + [] + let ``exponent dotted floats should be equal to dotted floats``() = + CompilerAssert.CompileExeAndRun + """ +if 1.0e1f <> 10.f then failwith "1.0e1f <> 10.f" + """ + + [] + let ``exponent dotless floats should be equal to dotted floats``() = + CompilerAssert.CompileExeAndRun + """ +if 1e1f <> 10.f then failwith "1e1f <> 10.f" + """ + + [] + let ``exponent dotted floats should be equal to dotless floats``() = + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] + """ +if 1.0e1f <> 10f then failwith "1.0e1f <> 10f" + """ + [] - let ``floats with dot should be equal to floats without dot``() = - CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:preview"|] + let ``exponent dotless floats should be equal to dotless floats``() = + CompilerAssert.CompileExeAndRunWithOptions [|"--langversion:5.0"|] """ -if 1.0f <> 1f then failwith "1.0f is not equal to 1f" +if 1e1f <> 10f then failwith "1e1f <> 10f" """ diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs new file mode 100644 index 00000000000..0ff4375ce51 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/CharConstants.fs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Char Constants`` = + + [] // alert + [] // backspace + [] // horizontal tab + [] // new line + [] // vertical tab + [] // form feed + [] // return + [] // double quote + [] // single quote + [] // backslash + let ``Escape characters`` character value = + Assert.areEqual character (char value) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs new file mode 100644 index 00000000000..4fd012f7a03 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/DecimalConstants.fs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Decimal Constants`` = + + [] + let ``Product of decimal constants``() = + let oneOfOneMiDec = 1.0E-6M + let oneMiDec = 1.0E+6M + + Assert.areEqual 1.0M (oneOfOneMiDec * oneMiDec) + + [] + let ``Sum of decimal constants``() = + let x = + 1.0E0M + + 2.0E1M + + 3.0E2M + + 4.0E3M + + 5.0E4M + + 6.0E5M + + 7.0E6M + + 8.0E7M + + 9.0E8M + + 1.0E-1M + + 2.0E-2M + + 3.0E-3M + + 4.0E-4M + + 5.0E-5M + + 6.0E-6M + + 7.0E-7M + + 8.0E-8M + + 9.0E-9M + + Assert.areEqual 987654321.123456789M x + + [] + let ``Sum of decimal literals with leading zero in exponential``() = + let x = 1.0E00M + 2.0E01M + 3.E02M + 1.E-01M + 2.0E-02M + + Assert.areEqual 321.12M x + + [] + let ``Non-representable small values are rounded to zero``() = + // This test involves rounding of decimals. The F# design is to follow the BCL. + // This means that the behavior is not deterministic, e.g. Mono and NetFx4 round; NetFx2 gives an error + // This is a positive test on Dev10, at least until + // FSHARP1.0:4523 gets resolved. + + Assert.areEqual 0.0M 1.0E-50M \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs new file mode 100644 index 00000000000..a5be0ccde11 --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/BasicGrammarElements/IntegerConstants.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Integer Constants`` = + + [] + let ``Operations with negative one``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let x = -1 + + Assert.areEqual -2 (x + x) + Assert.areEqual 0 (x - x) + Assert.areEqual 1 (x * x) + Assert.areEqual 1 (x / x) + + [] + let ``Operations with negative integers``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let fiveMinusSix = 5 - 6 + let fiveMinusSeven = 5-7 + let negativeSeven = -7 + + Assert.areEqual -1 fiveMinusSix + Assert.areEqual -2 fiveMinusSeven + Assert.areEqual (-1 * 7) negativeSeven + + [] + let ``Functions with negative integers``() = + // Verify the ability to specify negative numbers + // (And not get confused wrt subtraction.) + + let ident x = x + let add x y = x + y + + Assert.areEqual -10 (ident -10) + Assert.areEqual -10 (add -5 -5) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Conformance/DataExpressions/ComputationExpressions.fs b/tests/fsharp/Compiler/Conformance/DataExpressions/ComputationExpressions.fs new file mode 100644 index 00000000000..bda70e564be --- /dev/null +++ b/tests/fsharp/Compiler/Conformance/DataExpressions/ComputationExpressions.fs @@ -0,0 +1,838 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Compiler.Diagnostics + +[] +module ``ComputationExpressions`` = + let tmp = 1 + + type Flags = { includeMergeSourcesOverloads: bool; includeBindReturnExtras: bool } + let applicativeLib (opts: Flags) = + """ +/// Used for tracking what operations a Trace builder was asked to perform +[] +type TraceOp = + | ApplicativeBind + | ApplicativeBind2 + | ApplicativeBindReturn + | ApplicativeBind2Return + | ApplicativeReturn + | ApplicativeCombine + | ApplicativeYield + | MergeSources + | MergeSources3 + | MergeSources4 + | MonadicBind + | MonadicBind2 + | MonadicReturn + | Run + | Delay + | Log of string + +/// A pseudo identity functor +type Trace<'T>(v: 'T) = + member x.Value = v + override this.ToString () = + sprintf "%+A" v + +/// A builder which records what operations it is asked to perform +type TraceCore() = + + let mutable trace = ResizeArray<_>() + + member _.GetTrace () = trace.ToArray() + + member _.Trace x = trace.Add(x) + +type TraceMergeSourcesCore() = + inherit TraceCore() + + member builder.MergeSources(x1: Trace<'T1>, x2: Trace<'T2>) : Trace<'T1 * 'T2> = + builder.Trace TraceOp.MergeSources + Trace (x1.Value, x2.Value) + """ + (if opts.includeMergeSourcesOverloads then """ + + // Note the struct tuple is acceptable + member builder.MergeSources3(x1: Trace<'T1>, x2: Trace<'T2>, x3: Trace<'T3>) : Trace = + builder.Trace TraceOp.MergeSources3 + Trace (struct (x1.Value, x2.Value, x3.Value)) + + member builder.MergeSources4(x1: Trace<'T1>, x2: Trace<'T2>, x3: Trace<'T3>, x4: Trace<'T4>) : Trace<'T1 * 'T2 * 'T3 * 'T4> = + builder.Trace TraceOp.MergeSources4 + Trace (x1.Value, x2.Value, x3.Value, x4.Value) + """ else "") + """ + +type TraceApplicative() = + inherit TraceMergeSourcesCore() + + member builder.BindReturn(x: Trace<'T1>, f: 'T1 -> 'T2) : Trace<'T2> = + builder.Trace TraceOp.ApplicativeBindReturn + Trace (f x.Value) + + """ + (if opts.includeBindReturnExtras then """ + member builder.Bind2Return(x1: Trace<'T1>, x2: Trace<'T2>, f: 'T1 * 'T2 -> 'T3) : Trace<'T3> = + builder.Trace TraceOp.ApplicativeBind2Return + Trace (f (x1.Value, x2.Value)) + """ else "") + """ + +type TraceApplicativeWithDelayAndRun() = + inherit TraceApplicative() + + member builder.Run(x) = + builder.Trace TraceOp.Run + x + + member builder.Delay(thunk) = + builder.Trace TraceOp.Delay + thunk () + +type TraceApplicativeWithDelay() = + inherit TraceApplicative() + + member builder.Delay(thunk) = + builder.Trace TraceOp.Delay + thunk () + +type TraceApplicativeWithRun() = + inherit TraceApplicative() + + member builder.Run(x) = + builder.Trace TraceOp.Run + x + +type TraceMultiBindingMonadic() = + inherit TraceMergeSourcesCore() + + member builder.Bind(x : Trace<'T1>, f : 'T1 -> Trace<'T2>) : Trace<'T2> = + builder.Trace TraceOp.MonadicBind + f x.Value + + member builder.Bind2(x1 : 'T1 Trace, x2 : 'T2 Trace, f : 'T1 * 'T2 -> Trace<'T3>) : Trace<'T3> = + builder.Trace TraceOp.MonadicBind2 + f (x1.Value, x2.Value) + + member builder.Return(x: 'T) : Trace<'T> = + builder.Trace TraceOp.MonadicReturn + Trace x + +type TraceMultiBindingMonoid() = + inherit TraceMergeSourcesCore() + + member builder.Bind(x : Trace<'T1>, f : 'T1 -> Trace<'T2>) : Trace<'T2> = + builder.Trace TraceOp.MonadicBind + f x.Value + + member builder.Bind2(x1 : 'T1 Trace, x2 : 'T2 Trace, f : 'T1 * 'T2 -> Trace<'T3>) : Trace<'T3> = + builder.Trace TraceOp.MonadicBind2 + f (x1.Value, x2.Value) + + member builder.Yield(x: 'T) : Trace<'T list> = + builder.Trace TraceOp.ApplicativeYield + Trace [x] + + member builder.Combine(x1: Trace<'T list>, x2: Trace<'T list>) : Trace<'T list> = + builder.Trace TraceOp.ApplicativeCombine + Trace (x1.Value @ x2.Value) + + member builder.Delay(thunk) = + builder.Trace TraceOp.Delay + thunk () + + member builder.Zero() = + Trace [] + +type TraceApplicativeNoMergeSources() = + inherit TraceCore() + + member builder.BindReturn(x: Trace<'T1>, f: 'T1 -> 'T2) : Trace<'T2> = + builder.Trace TraceOp.ApplicativeBind + Trace (f x.Value) + +type TraceApplicativeNoBindReturn() = + inherit TraceCore() + + member builder.MergeSources(x1: Trace<'T1>, x2: Trace<'T2>) : Trace<'T1 * 'T2> = + builder.Trace TraceOp.MergeSources + Trace (x1.Value, x2.Value) + +type TraceMultiBindingMonadicCustomOp() = + inherit TraceMultiBindingMonadic() + + [] + member builder.Log(boundValues : Trace<'T>, [] messageFunc: 'T -> string) = + builder.Trace (TraceOp.Log (messageFunc boundValues.Value)) + boundValues + +type TraceApplicativeCustomOp() = + inherit TraceApplicative() + + [] + member builder.Log(boundValues : Trace<'T>, message: string) = + builder.Trace (TraceOp.Log message) + boundValues + +let check msg actual expected = if actual <> expected then failwithf "FAILED %s, expected %A, got %A" msg expected actual + """ + + let includeAll = { includeMergeSourcesOverloads = true; includeBindReturnExtras=true } + let includeMinimal = { includeMergeSourcesOverloads = false; includeBindReturnExtras=false } + + let ApplicativeLibTest opts source = + CompilerAssert.CompileExeAndRunWithOptions [| "/langversion:preview" |] (applicativeLib opts + source) + + let ApplicativeLibErrorTest opts source errors = + let lib = applicativeLib opts + // Adjust the expected errors for the number of lines in the library + let libLineAdjust = lib |> Seq.filter (fun c -> c = '\n') |> Seq.length + CompilerAssert.TypeCheckWithErrorsAndOptionsAndAdjust [| "/langversion:preview" |] libLineAdjust (lib + source) errors + + let ApplicativeLibErrorTestFeatureDisabled opts source errors = + let lib = applicativeLib opts + // Adjust the expected errors for the number of lines in the library + let libLineAdjust = lib |> Seq.filter (fun c -> c = '\n') |> Seq.length + CompilerAssert.TypeCheckWithErrorsAndOptionsAndAdjust [| "/langversion:4.7" |] libLineAdjust (lib + source) errors + + [] + let ``AndBang TraceApplicative`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "fewljvwerjl1" ceResult.Value 3 +check "fewljvwerj12" (tracer.GetTrace ()) [|TraceOp.ApplicativeBind2Return|] + """ + + [] + let ``AndBang TraceApplicativeCustomOp`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicativeCustomOp() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + log "hello!" + return if y then x else -1 + } + +check "fewljvwerjlvwe1" ceResult.Value 3 +check "fewljvwerjvwe12" (tracer.GetTrace ()) [|TraceOp.ApplicativeBind2Return; TraceOp.Log "hello!";TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicativeCustomOp Minimal`` () = + ApplicativeLibTest includeMinimal """ + +let tracer = TraceApplicativeCustomOp() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + log "hello!" + return if y then x else -1 + } + +check "fewljvwerjlvwe1" ceResult.Value 3 +check "fewljvwerjvwe12" (tracer.GetTrace ()) [|TraceOp.MergeSources; TraceOp.ApplicativeBindReturn; TraceOp.Log "hello!";TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicativeCustomOpTwice`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicativeCustomOp() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + log "hello!" + log "goodbye!" + return if y then x else -1 + } + +check "fewljvwerjlvwe1" ceResult.Value 3 +check "fewljvwerjvwe12" (tracer.GetTrace ()) [|TraceOp.ApplicativeBind2Return; TraceOp.Log "hello!";TraceOp.Log "goodbye!";TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicative Disable`` () = + ApplicativeLibErrorTestFeatureDisabled includeAll + """ +let tracer = TraceApplicative() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + """ + [| FSharpDiagnosticSeverity.Error, 3344, (6, 9, 8, 35), "This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature." |] + + [] + let ``AndBang TraceMultiBindingMonoid`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceMultiBindingMonoid() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + yield (if y then x else -1) + yield (if y then 5 else -1) + } + +check "fewljvwerjl5" ceResult.Value [3; 5] +check "fewljvwerj16" (tracer.GetTrace ()) [|TraceOp.Delay; TraceOp.MonadicBind2; TraceOp.ApplicativeYield; TraceOp.Delay; TraceOp.ApplicativeYield; TraceOp.ApplicativeCombine|] + """ + + [] + let ``AndBang TraceMultiBindingMonadic`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceMultiBindingMonadic() + +let ceResult : Trace = + tracer { + let fb = Trace "foobar" + match! fb with + | "bar" -> + let! bar = fb + return String.length bar + | _ -> + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "gwrhjkrwpoiwer1" ceResult.Value 3 +check "gwrhjkrwpoiwer2" (tracer.GetTrace ()) [|TraceOp.MonadicBind; TraceOp.MonadicBind2; TraceOp.MonadicReturn|] + """ + + [] + let ``AndBang TraceMultiBindingMonadicCustomOp A`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceMultiBindingMonadicCustomOp() +let ceResult : Trace = + tracer { + let! x = Trace 3 + log (sprintf "%A" x) + return x + } + +check "gwrhjkrwpoiwer1t4" ceResult.Value 3 + """ + + [] + let ``AndBang TraceMultiBindingMonadicCustomOp B`` () = + ApplicativeLibTest includeAll """ +let tracer = TraceMultiBindingMonadicCustomOp() +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + log (sprintf "%A" (x,y)) + return (ignore y; x) + } + +check "gwrhjkrwpoiwer1t45" ceResult.Value 3 +check "gwrhjkrwpoiwer2t36" (tracer.GetTrace ()) [|TraceOp.MonadicBind2; TraceOp.MonadicReturn; TraceOp.Log "(3, true)"; TraceOp.MonadicBind; TraceOp.MonadicReturn |] + """ + + [] + let ``AndBang TraceMultiBindingMonadic TwoBind`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceMultiBindingMonadic() + +let ceResult : Trace = + tracer { + let fb = Trace "foobar" + match! fb with + | "bar" -> + let! bar = fb + return String.length bar + | _ -> + let! x = Trace 3 + and! y = Trace true + let! x2 = Trace x + and! y2 = Trace y + if y2 then return x2 else return -1 + } + +check "gwrhjkrwpoiwer38" ceResult.Value 3 +check "gwrhjkrwpoiwer39" (tracer.GetTrace ()) [|TraceOp.MonadicBind; TraceOp.MonadicBind2; TraceOp.MonadicBind2; TraceOp.MonadicReturn|] + """ + + [] + let ``AndBang TraceApplicativeWithDelayAndRun`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicativeWithDelayAndRun() + +let ceResult : Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "vlkjrrlwevlk23" ceResult.Value 3 +check "vlkjrrlwevlk24" (tracer.GetTrace ()) [|TraceOp.Delay; TraceOp.ApplicativeBind2Return; TraceOp.Run|] + """ + + [] + let ``AndBang TraceApplicativeWithDelay`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicativeWithDelay() + +let ceResult : int Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "vlkjrrlwevlk23" ceResult.Value 3 +check "vlkjrrlwevlk24" (tracer.GetTrace ()) [|TraceOp.Delay; TraceOp.ApplicativeBind2Return|] + """ + + [] + let ``AndBang TraceApplicativeWithDelay Minimal`` () = + ApplicativeLibTest includeMinimal """ + +let tracer = TraceApplicativeWithDelay() + +let ceResult : int Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "vlkjrrlwevlk23" ceResult.Value 3 +check "vlkjrrlwevlk24" (tracer.GetTrace ()) [|TraceOp.Delay; TraceOp.MergeSources; TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicativeWithRun`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicativeWithRun() + +let ceResult : int Trace = + tracer { + let! x = Trace 3 + and! y = Trace true + return if y then x else -1 + } + +check "vwerweberlk3" ceResult.Value 3 +check "vwerweberlk4" (tracer.GetTrace ()) [|TraceOp.ApplicativeBind2Return; TraceOp.Run |] + """ + + + [] + let ``AndBang TraceApplicative Size 3`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x = Trace 3 + and! y = Trace true + and! z = Trace 5 + return if y then x else z + } + +check "fewljvwerjl7" ceResult.Value 3 +check "fewljvwerj18" (tracer.GetTrace ()) [|TraceOp.MergeSources3; TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicative Size 3 minimal`` () = + ApplicativeLibTest includeMinimal """ + +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x = Trace 3 + and! y = Trace true + and! z = Trace 5 + return if y then x else z + } + +check "fewljvwerjl7" ceResult.Value 3 +check "fewljvwerj18" (tracer.GetTrace ()) [|TraceOp.MergeSources; TraceOp.MergeSources; TraceOp.ApplicativeBindReturn|] + """ + [] + let ``AndBang TraceApplicative Size 4`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x1 = Trace 3 + and! x2 = Trace true + and! x3 = Trace 5 + and! x4 = Trace 5 + return if x2 then x1 else x3+x4 + } + +check "fewljvwerjl191" ceResult.Value 3 +check "fewljvwerj1192" (tracer.GetTrace ()) [|TraceOp.MergeSources4; TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicative Size 5`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult : Trace = + tracer { + let! x1 = Trace 3 + and! x2 = Trace true + and! x3 = Trace 5 + and! x4 = Trace 5 + and! x5 = Trace 8 + return if x2 then x1+x4+x5 else x3 + } + +check "fewljvwerjl193" ceResult.Value 16 +check "fewljvwerj1194" (tracer.GetTrace ()) [|TraceOp.MergeSources; TraceOp.MergeSources4; TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicative Size 6`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult : Trace = + tracer { + let! x1 = Trace 3 + and! x2 = Trace true + and! x3 = Trace 5 + and! x4 = Trace 5 + and! x5 = Trace 8 + and! x6 = Trace 9 + return if x2 then x1+x4+x5+x6 else x3 + } + +check "fewljvwerjl195" ceResult.Value 25 +check "fewljvwerj1196" (tracer.GetTrace ()) [|TraceOp.MergeSources3; TraceOp.MergeSources4; TraceOp.ApplicativeBindReturn|] + """ + + [] + let ``AndBang TraceApplicative Size 10`` () = + ApplicativeLibTest includeAll """ + +let tracer = TraceApplicative() + +let ceResult : Trace = + tracer { + let! x1 = Trace 3 + and! x2 = Trace true + and! x3 = Trace 5 + and! x4 = Trace 5 + and! x5 = Trace 8 + and! x6 = Trace 9 + and! x7 = Trace 1 + and! x8 = Trace 2 + and! x9 = Trace 3 + and! x10 = Trace 4 + return if x2 then x1+x4+x5+x6+x7+x8+x9+x10 else x3 + } + +check "fewljvwerjl197" ceResult.Value 35 +check "fewljvwerj1198" (tracer.GetTrace ()) [|TraceOp.MergeSources4; TraceOp.MergeSources4; TraceOp.MergeSources4; TraceOp.ApplicativeBindReturn|] + """ + + + [] + let ``AndBang Negative TraceApplicative missing MergeSources`` () = + ApplicativeLibErrorTest includeAll """ +let tracer = TraceApplicativeNoMergeSources() + +let _ = + tracer { + let! x = Trace 1 + and! y = Trace 2 + return x + y + } + """ + [|(FSharpDiagnosticSeverity.Error, 3343, (6, 9, 6, 25), "The 'let! ... and! ...' construct may only be used if the computation expression builder defines either a 'Bind2' method or appropriate 'MergeSource' and 'Bind' methods")|] + + [] + let ``AndBang Negative TraceApplicative missing Bind and BindReturn`` () = + ApplicativeLibErrorTest includeAll """ +let tracer = TraceApplicativeNoBindReturn() + +let _ = + tracer { + let! x = Trace 1 + and! y = Trace 2 + return x + y + } + """ + [|(FSharpDiagnosticSeverity.Error, 708, (6, 9, 6, 25), "This control construct may only be used if the computation expression builder defines a 'Bind' method")|] + + + [] + let ``AndBang Negative TraceApplicative with bad construct`` () = + ApplicativeLibErrorTest includeAll """ + +let tracer = TraceApplicativeNoBindReturn() + +let _ = + tracer { + let! x = Trace 1 // this is a true bind, check the error message here + let! x2 = Trace 1 + return x + y + } + """ + [| FSharpDiagnosticSeverity.Error, 708, (7, 9, 7, 25), "This control construct may only be used if the computation expression builder defines a 'Bind' method" |] + + [] + let ``AndBang TraceApplicative with do-bang`` () = + ApplicativeLibErrorTest includeAll """ +let tracer = TraceApplicative() + +let _ = + tracer { + do! Trace() + and! x = Trace 1 + and! y = Trace 2 + return x + y + } + """ + [|(FSharpDiagnosticSeverity.Error, 10, (7, 9, 7, 13),"Unexpected keyword 'and!' in expression. Expected '}' or other token."); + (FSharpDiagnosticSeverity.Error, 604, (5, 12, 5, 13), "Unmatched '{'"); + (FSharpDiagnosticSeverity.Error, 10, (8, 9, 8, 13), "Unexpected keyword 'and!' in implementation file")|] + + [] + let ``AndBang Negative TraceApplicative let betweeen let! and and!`` () = + ApplicativeLibErrorTest includeAll """ +let tracer = TraceApplicative() + +let _ = + tracer { + let! x = Trace 1 + let _ = 42 + and! y = Trace 2 + return x + y + } + """ + [| (FSharpDiagnosticSeverity.Error, 10, (8, 9, 8, 13), "Unexpected keyword 'and!' in expression") |] + + + [] + let ``AndBang Negative TraceApplicative no return`` () = + ApplicativeLibErrorTest includeAll """ +let tracer = TraceApplicative() + +let _ = + tracer { + let! x = Trace 1 + and! y = Trace 2 + } + """ + [|(FSharpDiagnosticSeverity.Error, 10, (8, 5, 8, 6), "Unexpected symbol '}' in expression")|] + + [] + let ``AndBang TraceApplicative conditional return`` () = + ApplicativeLibTest includeAll """ +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x = Trace 1 + and! y = Trace 2 + if x = 1 then + return y + else + return 4 + } +check "grwerjkrwejgk" ceResult.Value 2 + """ + + [] + let ``AndBang TraceApplicative match return`` () = + ApplicativeLibTest includeAll """ +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x = Trace 1 + and! y = Trace 2 + match x with + | 1 -> return y + | _ -> return 4 + } +check "grwerjkrwejgk42" ceResult.Value 2 + """ + + [] + let ``AndBang TraceApplicative incomplete match return`` () = + ApplicativeLibTest includeAll """ +#nowarn "25" + +let tracer = TraceApplicative() + +let ceResult = + tracer { + let! x = Trace 1 + and! y = Trace 2 + match x with + | 1 -> return y + } +check "grwerjkrwejgk42" ceResult.Value 2 + """ + + let overloadLib includeInternalExtensions includeExternalExtensions = + """ +open System + +type Content = ArraySegment list + +type ContentBuilder() = + member this.Run(c: Content) = + let crlf = "\r\n"B + [|for part in List.rev c do + yield! part.Array[part.Offset..(part.Count+part.Offset-1)] + yield! crlf |] + + member this.Yield(_) = [] + + [] + member this.Body(c: Content, segment: ArraySegment) = + segment::c + """ + (if includeInternalExtensions then """ + +type ContentBuilder with + // unattributed internal type extension with same arity + member this.Body(c: Content, bytes: byte[]) = + ArraySegment(bytes, 0, bytes.Length)::c + + // internal type extension with different arity + [] + member this.Body(c: Content, bytes: byte[], offset, count) = + ArraySegment(bytes, offset, count)::c + """ else """ + + // unattributed type member with same arity + member this.Body(c: Content, bytes: byte[]) = + ArraySegment(bytes, 0, bytes.Length)::c + + // type member with different arity + [] + member this.Body(c: Content, bytes: byte[], offset, count) = + ArraySegment(bytes, offset, count)::c + """) + (if includeExternalExtensions then """ + +module Extensions = + type ContentBuilder with + // unattributed external type extension with same arity + member this.Body(c: Content, content: System.IO.Stream) = + let mem = new System.IO.MemoryStream() + content.CopyTo(mem) + let bytes = mem.ToArray() + ArraySegment(bytes, 0, bytes.Length)::c + + // external type extensions as ParamArray + [] + member this.Body(c: Content, [] contents: string[]) = + List.rev [for c in contents -> let b = Text.Encoding.ASCII.GetBytes c in ArraySegment<_>(b,0,b.Length)] @ c +open Extensions + """ else """ + + // unattributed type member with same arity + member this.Body(c: Content, content: System.IO.Stream) = + let mem = new System.IO.MemoryStream() + content.CopyTo(mem) + let bytes = mem.ToArray() + ArraySegment(bytes, 0, bytes.Length)::c + + // type members + [] + member this.Body(c: Content, [] contents: string[]) = + List.rev [for c in contents -> let b = Text.Encoding.ASCII.GetBytes c in ArraySegment<_>(b,0,b.Length)] @ c + """) + """ + +let check msg actual expected = if actual <> expected then failwithf "FAILED %s, expected %A, got %A" msg expected actual + """ + + let OverloadLibTest inclInternalExt inclExternalExt source = + CompilerAssert.CompileExeAndRunWithOptions [| "/langversion:preview" |] (overloadLib inclInternalExt inclExternalExt + source) + + [] + let ``OverloadLib accepts overloaded methods`` () = + OverloadLibTest false false """ +let mem = new System.IO.MemoryStream("Stream"B) +let content = ContentBuilder() +let ceResult = + content { + body "Name" + body (ArraySegment<_>("Email"B, 0, 5)) + body "Password"B 2 4 + body "BYTES"B + body mem + body "Description" "of" "content" + } +check "TmFtZVxyXG5FbWF1" ceResult "Name\r\nEmail\r\nsswo\r\nBYTES\r\nStream\r\nDescription\r\nof\r\ncontent\r\n"B + """ + + [] + let ``OverloadLib accepts overloaded internal extension methods`` () = + OverloadLibTest true false """ +let mem = new System.IO.MemoryStream("Stream"B) +let content = ContentBuilder() +let ceResult = + content { + body "Name" + body (ArraySegment<_>("Email"B, 0, 5)) + body "Password"B 2 4 + body "BYTES"B + body mem + body "Description" "of" "content" + } +check "TmFtZVxyXG5FbWF2" ceResult "Name\r\nEmail\r\nsswo\r\nBYTES\r\nStream\r\nDescription\r\nof\r\ncontent\r\n"B + """ + + [] + let ``OverloadLib accepts overloaded internal and external extensions`` () = + OverloadLibTest true true """ +let mem = new System.IO.MemoryStream("Stream"B) +let content = ContentBuilder() +let ceResult = + content { + body "Name" + body (ArraySegment<_>("Email"B, 0, 5)) + body "Password"B 2 4 + body "BYTES"B + body mem + body "Description" "of" "content" + } +check "TmFtZVxyXG5FbWF3" ceResult "Name\r\nEmail\r\nsswo\r\nBYTES\r\nStream\r\nDescription\r\nof\r\ncontent\r\n"B + """ diff --git a/tests/fsharp/Compiler/ConstraintSolver/MemberConstraints.fs b/tests/fsharp/Compiler/ConstraintSolver/MemberConstraints.fs deleted file mode 100644 index c7a67e78389..00000000000 --- a/tests/fsharp/Compiler/ConstraintSolver/MemberConstraints.fs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module MemberConstraints = - - [] - let ``we can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() = - CompilerAssert.CompileExeAndRun - """ -type Foo(x : int) = - member this.Val = x - - static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val) - static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target) - - static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val) - static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target) - -let x = Foo(3) --> 4 -let y = Foo(3) --> Foo(4) -let x2 = Foo(3) + 4 -let y2 = Foo(3) + Foo(4) - -if x.Val <> 7 then failwith "x.Val <> 7" -elif y.Val <> 7 then failwith "y.Val <> 7" -elif x2.Val <> 7 then failwith "x2.Val <> 7" -elif y2.Val <> 7 then failwith "x.Val <> 7" -else () - """ - - [] - let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262 - CompilerAssert.TypeCheckSingleErrorWithOptions - [| "--test:ErrorRanges" |] - """ -let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ())) - """ - FSharpErrorSeverity.Error - 697 - (2, 42, 2, 75) - "Invalid constraint" diff --git a/tests/fsharp/Compiler/ConstraintSolver/PrimitiveConstraints.fs b/tests/fsharp/Compiler/ConstraintSolver/PrimitiveConstraints.fs deleted file mode 100644 index 0b61ffbb96b..00000000000 --- a/tests/fsharp/Compiler/ConstraintSolver/PrimitiveConstraints.fs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module PrimitiveConstraints = - - [] - let ``Test primitive : constraints``() = - CompilerAssert.CompileExeAndRun - """ -#light - -type Foo(x : int) = - member this.Value = x - override this.ToString() = "Foo" - -type Bar(x : int) = - inherit Foo(-1) - member this.Value2 = x - override this.ToString() = "Bar" - -let test1 (x : Foo) = x.Value -let test2 (x : Bar) = (x.Value, x.Value2) - -let f = new Foo(128) -let b = new Bar(256) - -if test1 f <> 128 then failwith "test1 f <> 128" -elif test2 b <> (-1, 256) then failwith "test2 b <> (-1, 256)" -else () -""" - - [] - let ``Test primitive :> constraints``() = - CompilerAssert.CompileExeAndRun - """ -#light -type Foo(x : int) = - member this.Value = x - override this.ToString() = "Foo" - -type Bar(x : int) = - inherit Foo(-1) - member this.Value2 = x - override this.ToString() = "Bar" - -type Ram(x : int) = - inherit Foo(10) - member this.ValueA = x - override this.ToString() = "Ram" - -let test (x : Foo) = (x.Value, x.ToString()) - -let f = new Foo(128) -let b = new Bar(256) -let r = new Ram(314) - -if test f <> (128, "Foo") then failwith "test f <> (128, 'Foo')" -elif test b <> (-1, "Bar") then failwith "test b <> (-1, 'Bar')" -elif test r <> (10, "Ram") then failwith "test r <> (10, 'Ram')" -else () -""" - - [] - let ``Test primitive : null constraint``() = - CompilerAssert.CompileExeAndRun - """ -let inline isNull<'a when 'a : null> (x : 'a) = - match x with - | null -> "is null" - | _ -> (x :> obj).ToString() - -let runTest = - // Wrapping in try block to work around FSB 1989 - try - if isNull null <> "is null" then failwith "isNull null <> is null" - if isNull "F#" <> "F#" then failwith "isNull F# <> F#" - () - with _ -> reraise() - -runTest -""" - - [] - /// Title: Type checking oddity - /// - /// This suggestion was resolved as by design, - /// so the test makes sure, we're emitting error message about 'not being a valid object construction expression' - let ``Invalid object constructor``() = // Regression test for FSharp1.0:4189 - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--test:ErrorRanges" |] - """ -type ImmutableStack<'a> private(items: 'a list) = - - member this.Push item = ImmutableStack(item::items) - member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs) - - // Notice type annotation is commented out, which results in an error - new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col) - - """ - [| FSharpErrorSeverity.Error, 41, (4, 29, 4, 56), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>" - FSharpErrorSeverity.Error, 41, (5, 93, 5, 111), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>" - FSharpErrorSeverity.Error, 41, (8, 30, 8, 60), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a> when 'b :> seq<'c>, private new : items:'a list -> ImmutableStack<'a>" - FSharpErrorSeverity.Error, 696, (8, 30, 8, 60), "This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor." |] \ No newline at end of file diff --git a/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs b/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs deleted file mode 100644 index 0143486a349..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/AccessOfTypeAbbreviationTests.fs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Access Of Type Abbreviation`` = - - [] - let ``Test1``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type private Hidden = Hidden of unit - type Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 8, 4, 16) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test2``() = - CompilerAssert.Pass - """ -module Library = - type internal Hidden = Hidden of unit - type internal Exported = Hidden - """ - - [] - let ``Test3``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type internal Hidden = Hidden of unit - type Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 8, 4, 16) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test4``() = - CompilerAssert.TypeCheckSingleError - """ -module Library = - type private Hidden = Hidden of unit - type internal Exported = Hidden - """ - FSharpErrorSeverity.Warning - 44 - (4, 17, 4, 25) - "This construct is deprecated. The type 'Hidden' is less accessible than the value, member or type 'Exported' it is used in.\r\nAs of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors." - - [] - let ``Test5``() = - CompilerAssert.Pass - """ -module Library = - type private Hidden = Hidden of unit - type private Exported = Hidden - """ - - [] - let ``Test6``() = - CompilerAssert.Pass - """ -module Library = - type Hidden = Hidden of unit - type Exported = Hidden - """ \ No newline at end of file diff --git a/tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs b/tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs deleted file mode 100644 index c3cc42e43c1..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/AssignmentErrorTests.fs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Errors assigning to mutable objects`` = - - [] - let ``Assign to immutable error``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -x <- 20 - """ - FSharpErrorSeverity.Error - 27 - (3, 1, 3, 8) - "This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'." \ No newline at end of file diff --git a/tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs b/tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs deleted file mode 100644 index 8fa8856d548..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/ClassesTests.fs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Classes`` = - - [] - let ``Tuple In Abstract Method``() = - CompilerAssert.TypeCheckWithErrors - """ -type IInterface = - abstract Function : (int32 * int32) -> unit - -let x = - { new IInterface with - member this.Function (i, j) = () - } - """ - [| - FSharpErrorSeverity.Error, 768, (7, 16, 7, 36), "The member 'Function' does not accept the correct number of arguments. 1 argument(s) are expected, but 2 were given. The required signature is 'member IInterface.Function : (int32 * int32) -> unit'.\nA tuple type is required for one or more arguments. Consider wrapping the given arguments in additional parentheses or review the definition of the interface." - FSharpErrorSeverity.Error, 17, (7, 21, 7, 29), "The member 'Function : 'a * 'b -> unit' does not have the correct type to override the corresponding abstract method. The required signature is 'Function : (int32 * int32) -> unit'." - FSharpErrorSeverity.Error, 783, (6, 9, 6, 19), "At least one override did not correctly implement its corresponding abstract member" - |] - - [] - let ``Wrong Arity``() = - CompilerAssert.TypeCheckSingleError - """ -type MyType() = - static member MyMember(arg1, arg2:int ) = () - static member MyMember(arg1, arg2:byte) = () - - -MyType.MyMember("", 0, 0) - """ - FSharpErrorSeverity.Error - 503 - (7, 1, 7, 26) - "A member or object constructor 'MyMember' taking 3 arguments is not accessible from this code location. All accessible versions of method 'MyMember' take 2 arguments." - - [] - let ``Method Is Not Static``() = - CompilerAssert.TypeCheckSingleError - """ -type Class1() = - member this.X() = "F#" - -let x = Class1.X() - """ - FSharpErrorSeverity.Error - 3214 - (5, 9, 5, 17) - "Method or object constructor 'X' is not static" - - [] - let ``Matching Method With Same Name Is Not Abstract``() = - CompilerAssert.TypeCheckWithErrors - """ -type Foo(x : int) = - member v.MyX() = x - -let foo = - { new Foo(3) - with - member v.MyX() = 4 } - """ - [| - FSharpErrorSeverity.Error, 767, (8, 16, 8, 23), "The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement." - FSharpErrorSeverity.Error, 17, (8, 18, 8, 21), "The member 'MyX : unit -> int' does not have the correct type to override any given virtual method" - FSharpErrorSeverity.Error, 783, (6, 11, 6, 14), "At least one override did not correctly implement its corresponding abstract member" - |] - - [] - let ``No Matching Abstract Method With Same Name``() = - CompilerAssert.TypeCheckWithErrors - """ -type IInterface = - abstract MyFunction : int32 * int32 -> unit - abstract SomeOtherFunction : int32 * int32 -> unit - -let x = - { new IInterface with - member this.Function (i, j) = () - } - """ - [| - FSharpErrorSeverity.Error, 767, (8, 14, 8, 34), "The member 'Function' does not correspond to any abstract or virtual method available to override or implement. Maybe you want one of the following:\r\n MyFunction" - FSharpErrorSeverity.Error, 17, (8, 19, 8, 27), "The member 'Function : 'a * 'b -> unit' does not have the correct type to override any given virtual method" - FSharpErrorSeverity.Error, 366, (7, 3, 9, 4), "No implementation was given for those members: \r\n\t'abstract member IInterface.MyFunction : int32 * int32 -> unit'\r\n\t'abstract member IInterface.SomeOtherFunction : int32 * int32 -> unit'\r\nNote that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." - FSharpErrorSeverity.Error, 783, (7, 9, 7, 19), "At least one override did not correctly implement its corresponding abstract member" - |] - - [] - let ``Member Has Multiple Possible Dispatch Slots``() = - CompilerAssert.TypeCheckWithErrors - """ -type IOverload = - abstract member Bar : int -> int - abstract member Bar : double -> int - -type Overload = - interface IOverload with - override __.Bar _ = 1 - """ - [| - FSharpErrorSeverity.Error, 366, (7, 15, 7, 24), "No implementation was given for those members: \r\n\t'abstract member IOverload.Bar : double -> int'\r\n\t'abstract member IOverload.Bar : int -> int'\r\nNote that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'." - FSharpErrorSeverity.Error, 3213, (8, 21, 8, 24), "The member 'Bar<'a0> : 'a0 -> int' matches multiple overloads of the same method.\nPlease restrict it to one of the following:\r\n Bar : double -> int\r\n Bar : int -> int." - |] - - [] - let ``Do Cannot Have Visibility Declarations``() = - CompilerAssert.ParseWithErrors - """ -type X() = - do () - private do () - static member Y() = 1 - """ - [| - FSharpErrorSeverity.Error, 531, (4, 5, 4, 12), "Accessibility modifiers should come immediately prior to the identifier naming a construct" - FSharpErrorSeverity.Error, 512, (4, 13, 4, 18), "Accessibility modifiers are not permitted on 'do' bindings, but 'Private' was given." - FSharpErrorSeverity.Error, 222, (2, 1, 3, 1), "Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration." - |] diff --git a/tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs b/tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs deleted file mode 100644 index d03747d8daf..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/ConstructorTests.fs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Constructor`` = - - [] - let ``Invalid Record``() = - CompilerAssert.TypeCheckWithErrors - """ -type Record = {field1:int; field2:int} -let doSomething (xs) = List.map (fun {field1=x} -> x) xs - -doSomething {Record.field1=0; field2=0} - """ - [| - FSharpErrorSeverity.Error, 1, (5, 13, 5, 40), "This expression was expected to have type\n 'Record list' \nbut here has type\n 'Record' " - FSharpErrorSeverity.Warning, 20, (5, 1, 5, 40), "The result of this expression has type 'int list' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - |] - - [] - let ``Comma In Rec Ctor``() = - CompilerAssert.TypeCheckWithErrors - """ -type Person = { Name : string; Age : int; City : string } -let x = { Name = "Isaac", Age = 21, City = "London" } - """ - [| - FSharpErrorSeverity.Error, 1, (3, 18, 3, 52), "This expression was expected to have type\n 'string' \nbut here has type\n ''a * 'b * 'c' \r\nA ';' is used to separate field values in records. Consider replacing ',' with ';'." - FSharpErrorSeverity.Error, 764, (3, 9, 3, 54), "No assignment given for field 'Age' of type 'Test.Person'" - |] - - [] - let ``Missing Comma In Ctor``() = - CompilerAssert.TypeCheckWithErrors - """ -type Person() = - member val Name = "" with get,set - member val Age = 0 with get,set - -let p = - Person(Name = "Fred" - Age = 18) - """ - [| - FSharpErrorSeverity.Error, 39, (7, 12, 7, 16), "The value or constructor 'Name' is not defined. Maybe you want one of the following:\r\n nan" - FSharpErrorSeverity.Warning, 20, (7, 12, 7, 25), "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." - FSharpErrorSeverity.Error, 39, (8, 12, 8, 15), "The value or constructor 'Age' is not defined." - FSharpErrorSeverity.Error, 501, (7, 5, 8, 21), "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'. If some of the arguments are meant to assign values to properties, consider separating those arguments with a comma (',')." - |] - - [] - let ``Missing Ctor Value``() = - CompilerAssert.TypeCheckSingleError - """ -type Person(x:int) = - member val Name = "" with get,set - member val Age = x with get,set - -let p = - Person(Name = "Fred", - Age = 18) - """ - FSharpErrorSeverity.Error - 496 - (7, 5, 8, 21) - "The member or object constructor 'Person' requires 1 argument(s). The required signature is 'new : x:int -> Person'." - - [] - let ``Extra Argument In Ctor``() = - CompilerAssert.TypeCheckSingleError - """ -type Person() = - member val Name = "" with get,set - member val Age = 0 with get,set - -let p = - Person(1) - """ - FSharpErrorSeverity.Error - 501 - (7, 5, 7, 14) - "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'." - - [] - let ``Extra Argument In Ctor2``() = - CompilerAssert.TypeCheckSingleError - """ -type Person() = - member val Name = "" with get,set - member val Age = 0 with get,set - -let b = 1 - -let p = - Person(1=b) - """ - FSharpErrorSeverity.Error - 501 - (9, 5, 9, 16) - "The object constructor 'Person' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> Person'." - - [] - let ``Valid Comma In Rec Ctor``() = - CompilerAssert.Pass - """ -type Person = { Name : string * bool * bool } -let Age = 22 -let City = "London" -let x = { Name = "Isaac", Age = 21, City = "London" } - """ diff --git a/tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs b/tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs deleted file mode 100644 index cf2e040fd26..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/DontSuggestTests.fs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Don't Suggest`` = - - [] - let ``Dont Suggest Completely Wrong Stuff``() = - CompilerAssert.TypeCheckSingleError - """ -let _ = Path.GetFullPath "images" - """ - FSharpErrorSeverity.Error - 39 - (2, 9, 2, 13) - "The value, namespace, type or module 'Path' is not defined. Maybe you want one of the following:\r\n Math" - - [] - let ``Dont Suggest When Things Are Open``() = - CompilerAssert.ParseWithErrors - """ -module N = - let name = "hallo" - -type T = - static member myMember = 1 - -let x = N. - """ - [| - FSharpErrorSeverity.Error, 599, (8, 10, 8, 11), "Missing qualification after '.'" - FSharpErrorSeverity.Error, 222, (2, 1, 3, 1), "Files in libraries or multiple-file applications must begin with a namespace or module declaration. When using a module declaration at the start of a file the '=' sign is not allowed. If this is a top-level module, consider removing the = to resolve this error." - |] - - [] - let ``Dont Suggest Intentionally Unused Variables``() = - CompilerAssert.TypeCheckSingleError - """ -let hober xy _xyz = xyz - """ - FSharpErrorSeverity.Error - 39 - (2, 21, 2, 24) - "The value or constructor 'xyz' is not defined." diff --git a/tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs b/tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs deleted file mode 100644 index 21c7bb29269..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/ElseBranchHasWrongTypeTests.fs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Else branch has wrong type`` = - - [] - let ``Else branch is int while if branch is string``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let y = - if test > 10 then "test" - else 123 - """ - FSharpErrorSeverity.Error - 1 - (5, 10, 5, 13) - "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - - [] - let ``Else branch is a function that returns int while if branch is string``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let f x = test -let y = - if test > 10 then "test" - else f 10 - """ - FSharpErrorSeverity.Error - 1 - (6, 10, 6, 14) - "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - - - [] - let ``Else branch is a sequence of expressions that returns int while if branch is string``() = - CompilerAssert.TypeCheckSingleError - """ -let f x = x + 4 - -let y = - if true then - "" - else - "" |> ignore - (f 5) - """ - FSharpErrorSeverity.Error - 1 - (9, 10, 9, 13) - "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - - - [] - let ``Else branch is a longer sequence of expressions that returns int while if branch is string``() = - CompilerAssert.TypeCheckSingleError - """ -let f x = x + 4 - -let y = - if true then - "" - else - "" |> ignore - let z = f 4 - let a = 3 * z - (f a) - """ - FSharpErrorSeverity.Error - 1 - (11, 10, 11, 13) - "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'int'." - - - [] - let ``Else branch context doesn't propagate into function application``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let f x : string = x -let y = - if test > 10 then "test" - else - f 123 - """ - FSharpErrorSeverity.Error - 1 - (7, 11, 7, 14) - "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - - [] - let ``Else branch context doesn't propagate into function application even if not last expr``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let f x = printfn "%s" x -let y = - if test > 10 then "test" - else - f 123 - "test" - """ - FSharpErrorSeverity.Error - 1 - (7, 11, 7, 14) - "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - - [] - let ``Else branch context doesn't propagate into for loop``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let list = [1..10] -let y = - if test > 10 then "test" - else - for (x:string) in list do - printfn "%s" x - - "test" - """ - FSharpErrorSeverity.Error - 1 - (7, 14, 7, 22) - "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " - - [] - let ``Else branch context doesn't propagate to lines before last line``() = - CompilerAssert.TypeCheckSingleError - """ -let test = 100 -let list = [1..10] -let y = - if test > 10 then "test" - else - printfn "%s" 1 - - "test" - """ - FSharpErrorSeverity.Error - 1 - (7, 22, 7, 23) - "This expression was expected to have type\n 'string' \nbut here has type\n 'int' " - - [] - let ``Else branch should not have wrong context type``() = - CompilerAssert.TypeCheckWithErrors - """ -let x = 1 -let y : bool = - if x = 2 then "A" - else "B" - """ - [| FSharpErrorSeverity.Error, 1, (4, 19, 4, 22), "The 'if' expression needs to have type 'bool' to satisfy context type requirements. It currently has type 'string'." - FSharpErrorSeverity.Error, 1, (5, 10, 5, 13), "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'bool'. This branch returns a value of type 'string'." |] - - - [] - let ``Else branch has wrong type in nested if``() = - CompilerAssert.TypeCheckWithErrors - """ -let x = 1 -if x = 1 then true -else - if x = 2 then "A" - else "B" - """ - [| FSharpErrorSeverity.Error, 1, (5, 19, 5, 22), "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'bool'. This branch returns a value of type 'string'." - FSharpErrorSeverity.Error, 1, (6, 10, 6, 13), "All branches of an 'if' expression must return values of the same type as the first branch, which here is 'bool'. This branch returns a value of type 'string'." - FSharpErrorSeverity.Warning, 20, (3, 1, 6, 13), "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." |] diff --git a/tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs b/tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs deleted file mode 100644 index 06f9cb160d9..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/MissingElseBranch.fs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Else branch is missing`` = - - [] - let ``Fail if else branch is missing``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -let y = - if x > 10 then "test" - """ - FSharpErrorSeverity.Error - 1 - (4, 19, 4, 25) - "This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'string'." - - [] - let ``Fail on type error in condition``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -let y = - if x > 10 then - if x <> "test" then printfn "test" - () - """ - FSharpErrorSeverity.Error - 1 - (5, 14, 5, 20) - "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " - - [] - let ``Fail if else branch is missing in nesting``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -let y = - if x > 10 then ("test") - """ - FSharpErrorSeverity.Error - 1 - (4, 20, 4, 26) - "This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'string'." diff --git a/tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs b/tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs deleted file mode 100644 index 77ee538ec77..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/NameResolutionTests.fs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module NameResolutionTests = - - [] - let FieldNotInRecord () = - CompilerAssert.TypeCheckSingleError - """ -type A = { Hello:string; World:string } -type B = { Size:int; Height:int } -type C = { Wheels:int } -type D = { Size:int; Height:int; Walls:int } -type E = { Unknown:string } -type F = { Wallis:int; Size:int; Height:int; } - -let r:F = { Size=3; Height=4; Wall=1 } - """ - FSharpErrorSeverity.Error - 1129 - (9, 31, 9, 35) - "The record type 'F' does not contain a label 'Wall'. Maybe you want one of the following:\r\n Wallis" - - [] - let RecordFieldProposal () = - CompilerAssert.TypeCheckSingleError - """ -type A = { Hello:string; World:string } -type B = { Size:int; Height:int } -type C = { Wheels:int } -type D = { Size:int; Height:int; Walls:int } -type E = { Unknown:string } -type F = { Wallis:int; Size:int; Height:int; } - -let r = { Size=3; Height=4; Wall=1 } - """ - FSharpErrorSeverity.Error - 39 - (9, 29, 9, 33) - "The record label 'Wall' is not defined. Maybe you want one of the following:\r\n Walls\r\n Wallis" \ No newline at end of file diff --git a/tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs b/tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs deleted file mode 100644 index 4ce8c481853..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/SuggestionsTests.fs +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module Suggestions = - - [] - let ``Field Suggestion`` () = - CompilerAssert.TypeCheckSingleError - """ -type Person = { Name : string; } - -let x = { Person.Names = "Isaac" } - """ - FSharpErrorSeverity.Error - 39 - (4, 18, 4, 23) - "The field, constructor or member 'Names' is not defined. Maybe you want one of the following:\r\n Name" - - - [] - let ``Suggest Array Module Functions`` () = - CompilerAssert.TypeCheckSingleError - """ -let f = - Array.blt - """ - FSharpErrorSeverity.Error - 39 - (3, 11, 3, 14) - "The value, constructor, namespace or type 'blt' is not defined. Maybe you want one of the following:\r\n blit" - - - [] - let ``Suggest Async Module`` () = - CompilerAssert.TypeCheckSingleError - """ -let f = - Asnc.Sleep 1000 - """ - FSharpErrorSeverity.Error - 39 - (3, 5, 3, 9) - "The value, namespace, type or module 'Asnc' is not defined. Maybe you want one of the following:\r\n Async\r\n async\r\n asin\r\n snd" - - - [] - let ``Suggest Attribute`` () = - CompilerAssert.TypeCheckSingleError - """ -[] -type MyClass<'Bar>() = - abstract M<'T> : 'T -> 'T - abstract M2<'T> : 'T -> 'Bar - """ - FSharpErrorSeverity.Error - 39 - (2, 3, 2, 15) - "The type 'AbstractClas' is not defined. Maybe you want one of the following:\r\n AbstractClass\r\n AbstractClassAttribute" - - - [] - let ``Suggest Double Backtick Identifiers`` () = - CompilerAssert.TypeCheckSingleError - """ -module N = - let ``longer name`` = "hallo" - -let x = N.``longe name`` - """ - FSharpErrorSeverity.Error - 39 - (5, 11, 5, 25) - "The value, constructor, namespace or type 'longe name' is not defined. Maybe you want one of the following:\r\n longer name" - - - [] - let ``Suggest Double Backtick Unions`` () = - CompilerAssert.TypeCheckSingleError - """ -module N = - type MyUnion = - | ``My Case1`` - | Case2 - -open N - -let x = N.MyUnion.``My Case2`` - """ - FSharpErrorSeverity.Error - 39 - (9, 19, 9,31) - "The field, constructor or member 'My Case2' is not defined. Maybe you want one of the following:\r\n My Case1\r\n Case2" - - - [] - let ``Suggest Fields In Constructor`` () = - CompilerAssert.TypeCheckSingleError - """ -type MyClass() = - member val MyProperty = "" with get, set - member val MyProperty2 = "" with get, set - member val ABigProperty = "" with get, set - -let c = MyClass(Property = "") - """ - FSharpErrorSeverity.Error - 495 - (7, 17, 7, 25) - "The object constructor 'MyClass' has no argument or settable return property 'Property'. The required signature is new : unit -> MyClass. Maybe you want one of the following:\r\n MyProperty\r\n MyProperty2\r\n ABigProperty" - - - [] - let ``Suggest Generic Type`` () = - CompilerAssert.TypeCheckSingleError - """ -type T = System.Collections.Generic.Dictionary - """ - FSharpErrorSeverity.Error - 39 - (2, 48, 2, 53) - "The type 'int11' is not defined. Maybe you want one of the following:\r\n int16\r\n int16`1\r\n int8\r\n uint16\r\n int" - - - [] - let ``Suggest Methods`` () = - CompilerAssert.TypeCheckSingleError - """ -module Test2 = - type D() = - - static let x = 1 - - member x.Method1() = 10 - - D.Method2() - """ - FSharpErrorSeverity.Error - 39 - (9, 7, 9, 14) - "The field, constructor or member 'Method2' is not defined. Maybe you want one of the following:\r\n Method1" - - - [] - let ``Suggest Modules`` () = - CompilerAssert.TypeCheckSingleError - """ -module Collections = - - let f () = printfn "%s" "Hello" - -open Collectons - """ - FSharpErrorSeverity.Error - 39 - (6, 6, 6, 16) - "The namespace or module 'Collectons' is not defined. Maybe you want one of the following:\r\n Collections" - - - [] - let ``Suggest Namespaces`` () = - CompilerAssert.TypeCheckSingleError - """ -open System.Collectons - """ - FSharpErrorSeverity.Error - 39 - (2, 13, 2, 23) - "The namespace 'Collectons' is not defined." - - - [] - let ``Suggest Record Labels`` () = - CompilerAssert.TypeCheckSingleError - """ -type MyRecord = { Hello: int; World: bool} - -let r = { Hello = 2 ; World = true} - -let x = r.ello - """ - FSharpErrorSeverity.Error - 39 - (6, 11, 6, 15) - "The field, constructor or member 'ello' is not defined. Maybe you want one of the following:\r\n Hello" - - - [] - let ``Suggest Record Type for RequireQualifiedAccess Records`` () = - CompilerAssert.TypeCheckSingleError - """ -[] -type MyRecord = { - Field1: string - Field2: int -} - -let r = { Field1 = "hallo"; Field2 = 1 } - """ - FSharpErrorSeverity.Error - 39 - (8, 11, 8, 17) - "The record label 'Field1' is not defined. Maybe you want one of the following:\r\n MyRecord.Field1" - - - [] - let ``Suggest To Use Indexer`` () = - CompilerAssert.TypeCheckWithErrors - """ -let d = [1,1] |> dict -let y = d[1] - -let z = d[|1|] - -let f() = d -let a = (f())[1] - """ - [| - FSharpErrorSeverity.Error, 3217, (3, 9, 3, 10), "This value is not a function and cannot be applied. Did you intend to access the indexer via d.[index] instead?" - FSharpErrorSeverity.Error, 3, (5, 9, 5, 10), "This value is not a function and cannot be applied." - FSharpErrorSeverity.Error, 3217, (8, 10, 8, 13), "This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead?" - |] - - - [] - let ``Suggest Type Parameters`` () = - CompilerAssert.TypeCheckSingleError - """ -[] -type MyClass<'Bar>() = - abstract M<'T> : 'T -> 'T - abstract M2<'T> : 'T -> 'Bar - abstract M3<'T> : 'T -> 'B - """ - FSharpErrorSeverity.Error - 39 - (6, 28, 6, 30) - "The type parameter 'B is not defined." - - - [] - let ``Suggest Types in Module`` () = - CompilerAssert.TypeCheckSingleError - """ -let x : System.Collections.Generic.Lst = ResizeArray() - """ - FSharpErrorSeverity.Error - 39 - (2, 36, 2, 39) - "The type 'Lst' is not defined in 'System.Collections.Generic'. Maybe you want one of the following:\r\n List\r\n IList\r\n List`1" - - [] - let ``Suggest Types in Namespace`` () = - CompilerAssert.TypeCheckSingleError - """ -let x = System.DateTie.MaxValue - """ - FSharpErrorSeverity.Error - 39 - (2, 16, 2, 23) - "The value, constructor, namespace or type 'DateTie' is not defined. Maybe you want one of the following:\r\n DateTime\r\n DateTimeKind\r\n DateTimeOffset\r\n Data" - - - [] - let ``Suggest Union Cases`` () = - CompilerAssert.TypeCheckSingleError - """ -type MyUnion = -| ASimpleCase -| AnotherCase of int - -let u = MyUnion.AntherCase - """ - FSharpErrorSeverity.Error - 39 - (6, 17, 6, 27) - "The field, constructor or member 'AntherCase' is not defined. Maybe you want one of the following:\r\n AnotherCase" - - - [] - let ``Suggest Union Type for RequireQualifiedAccess Unions`` () = - CompilerAssert.TypeCheckSingleError - """ -[] -type MyUnion = -| MyCase1 -| MyCase2 of string - -let x : MyUnion = MyCase1 - """ - FSharpErrorSeverity.Error - 39 - (7, 19, 7, 26) - "The value or constructor 'MyCase1' is not defined. Maybe you want one of the following:\r\n MyUnion.MyCase1" - - - [] - let ``Suggest Unions in PatternMatch`` () = - CompilerAssert.TypeCheckSingleError - """ -[] -type MyUnion = -| Case1 -| Case2 - -let y = MyUnion.Case1 - -let x = - match y with - | MyUnion.Cas1 -> 1 - | _ -> 2 - """ - FSharpErrorSeverity.Error - 39 - (11, 15, 11, 19) - "The field, constructor or member 'Cas1' is not defined. Maybe you want one of the following:\r\n Case1\r\n Case2" \ No newline at end of file diff --git a/tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs b/tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs deleted file mode 100644 index 652361045c9..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/TypeMismatchTests.fs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Type Mismatch`` = - - [] - let ``return Instead Of return!``() = - CompilerAssert.TypeCheckSingleError - """ -let rec foo() = async { return foo() } - """ - FSharpErrorSeverity.Error - 1 - (2, 32, 2, 37) - "Type mismatch. Expecting a\n ''a' \nbut given a\n 'Async<'a>' \nThe types ''a' and 'Async<'a>' cannot be unified. Consider using 'return!' instead of 'return'." - - [] - let ``yield Instead Of yield!``() = - CompilerAssert.TypeCheckSingleError - """ -type Foo() = - member this.Yield(x) = [x] - -let rec f () = Foo() { yield f ()} - """ - FSharpErrorSeverity.Error - 1 - (5, 30, 5, 34) - "Type mismatch. Expecting a\n ''a' \nbut given a\n ''a list' \nThe types ''a' and ''a list' cannot be unified. Consider using 'yield!' instead of 'yield'." - - [] - let ``Ref Cell Instead Of Not``() = - CompilerAssert.TypeCheckSingleError - """ -let x = true -if !x then - printfn "hello" - """ - FSharpErrorSeverity.Error - 1 - (3, 5, 3, 6) - "This expression was expected to have type\n 'bool ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here." - - [] - let ``Ref Cell Instead Of Not 2``() = - CompilerAssert.TypeCheckSingleError - """ -let x = true -let y = !x - """ - FSharpErrorSeverity.Error - 1 - (3, 10, 3, 11) - "This expression was expected to have type\n ''a ref' \nbut here has type\n 'bool' \r\nThe '!' operator is used to dereference a ref cell. Consider using 'not expr' here." - - [] - let ``Guard Has Wrong Type``() = - CompilerAssert.TypeCheckWithErrors - """ -let x = 1 -match x with -| 1 when "s" -> true -| _ -> false - """ - [| - FSharpErrorSeverity.Error, 1, (4, 10, 4, 13), "A pattern match guard must be of type 'bool', but this 'when' expression is of type 'string'." - FSharpErrorSeverity.Warning, 20, (3, 1, 5, 13), "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - |] - - [] - let ``Runtime Type Test In Pattern``() = - CompilerAssert.TypeCheckWithErrors - """ -open System.Collections.Generic - -let orig = Dictionary() - -let c = - match orig with - | :? IDictionary -> "yes" - | _ -> "no" - """ - [| - FSharpErrorSeverity.Warning, 67, (8, 5, 8, 28), "This type test or downcast will always hold" - FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" - |] - - [] - let ``Runtime Type Test In Pattern 2``() = - CompilerAssert.TypeCheckWithErrors - """ -open System.Collections.Generic - -let orig = Dictionary() - -let c = - match orig with - | :? IDictionary as y -> "yes" + y.ToString() - | _ -> "no" - """ - [| - FSharpErrorSeverity.Warning, 67, (8, 5, 8, 28), "This type test or downcast will always hold" - FSharpErrorSeverity.Error, 193, (8, 5, 8, 28), "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" - |] - - [] - let ``Override Errors``() = - CompilerAssert.TypeCheckWithErrors - """ -type Base() = - abstract member Member: int * string -> string - default x.Member (i, s) = s - -type Derived1() = - inherit Base() - override x.Member() = 5 - -type Derived2() = - inherit Base() - override x.Member (i : int) = "Hello" - -type Derived3() = - inherit Base() - override x.Member (s : string, i : int) = sprintf "Hello %s" s - """ - [| - FSharpErrorSeverity.Error, 856, (8, 16, 8, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string" - FSharpErrorSeverity.Error, 856, (12, 16, 12, 22), "This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:\r\n abstract member Base.Member : int * string -> string" - FSharpErrorSeverity.Error, 1, (16, 24, 16, 34), "This expression was expected to have type\n 'int' \nbut here has type\n 'string' " - |] diff --git a/tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs b/tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs deleted file mode 100644 index e9165a4cf6a..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/UnitGenericAbstactType.fs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Unit generic abstract Type`` = - - [] - let ``Unit can not be used as return type of abstract method paramete on return type``() = - CompilerAssert.TypeCheckSingleError - """ -type EDF<'S> = - abstract member Apply : int -> 'S -type SomeEDF () = - interface EDF with - member this.Apply d = - // [ERROR] The member 'Apply' does not have the correct type to override the corresponding abstract method. - () - """ - FSharpErrorSeverity.Error - 17 - (6, 21, 6, 26) - "The member 'Apply : int -> unit' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type." - diff --git a/tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs b/tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs deleted file mode 100644 index 739f841bfca..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/UpcastDowncastTests.fs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Upcast and Downcast`` = - - [] - let ``Downcast Instead Of Upcast``() = - CompilerAssert.TypeCheckSingleError - """ -open System.Collections.Generic - -let orig = Dictionary() :> IDictionary -let c = orig :> Dictionary - """ - FSharpErrorSeverity.Error - 193 - (5, 9, 5, 36) - "Type constraint mismatch. The type \n 'IDictionary' \nis not compatible with type\n 'Dictionary' \n" - - [] - let ``Upcast Instead Of Downcast``() = - CompilerAssert.TypeCheckWithErrors - """ -open System.Collections.Generic - -let orig = Dictionary() -let c = orig :?> IDictionary - """ - [| - FSharpErrorSeverity.Warning, 67, (5, 9, 5, 38), "This type test or downcast will always hold" - FSharpErrorSeverity.Error, 3198, (5, 9, 5, 38), "The conversion from Dictionary to IDictionary is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator." - |] - - [] - let ``Upcast Function Instead Of Downcast``() = - CompilerAssert.TypeCheckWithErrors - """ -open System.Collections.Generic - -let orig = Dictionary() -let c : IDictionary = downcast orig - """ - [| - FSharpErrorSeverity.Warning, 67, (5, 32, 5, 45), "This type test or downcast will always hold" - FSharpErrorSeverity.Error, 3198, (5, 32, 5, 45), "The conversion from Dictionary to IDictionary is a compile-time safe upcast, not a downcast. Consider using 'upcast' instead of 'downcast'." - |] diff --git a/tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs b/tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs deleted file mode 100644 index 8929183b83e..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/WarnExpressionTests.fs +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Warn Expression`` = - - [] - let ``Warn If Expression Result Unused``() = - CompilerAssert.TypeCheckSingleError - """ -1 + 2 -printfn "%d" 3 - """ - FSharpErrorSeverity.Warning - 20 - (2, 1, 2, 6) - "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - - [] - let ``Warn If Possible Assignment``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -let y = "hello" - -let changeX() = - x = 20 - y = "test" - """ - FSharpErrorSeverity.Warning - 20 - (6, 5, 6, 11) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'." - - [] - let ``Warn If Possible Assignment To Mutable``() = - CompilerAssert.TypeCheckSingleError - """ -let mutable x = 10 -let y = "hello" - -let changeX() = - x = 20 - y = "test" - """ - FSharpErrorSeverity.Warning - 20 - (6, 5, 6, 11) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'." - - [] - let ``Warn If Possible dotnet Property Setter``() = - CompilerAssert.TypeCheckWithErrors - """ -open System - -let z = System.Timers.Timer() -let y = "hello" - -let changeProperty() = - z.Enabled = true - y = "test" - """ - [| - FSharpErrorSeverity.Warning, 760, (4, 9, 4, 30), "It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value" - FSharpErrorSeverity.Warning, 20, (8, 5, 8, 21), "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'." - |] - - [] - let ``Don't Warn If Property Without Setter``() = - CompilerAssert.TypeCheckSingleError - """ -type MyClass(property1 : int) = - member val Property2 = "" with get - -let x = MyClass(1) -let y = "hello" - -let changeProperty() = - x.Property2 = "22" - y = "test" - """ - FSharpErrorSeverity.Warning - 20 - (9, 5, 9, 23) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." - - [] - let ``Warn If Implicitly Discarded``() = - CompilerAssert.TypeCheckSingleError - """ -let x = 10 -let y = 20 - -let changeX() = - y * x = 20 - y = 30 - """ - FSharpErrorSeverity.Warning - 20 - (6, 5, 6, 15) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." - - [] - let ``Warn If Discarded In List``() = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - """ -let div _ _ = 1 -let subView _ _ = [1; 2] - -// elmish view -let view model dispatch = - [ - yield! subView model dispatch - div [] [] - ] - """ - [| - FSharpErrorSeverity.Warning, - 3221, - (9, 8, 9, 17), - "This expression returns a value of type 'int' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'." - |] - - [] - let ``Warn If Discarded In List 2``() = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - """ -// stupid things to make the sample compile -let div _ _ = 1 -let subView _ _ = [1; 2] -let y = 1 - -// elmish view -let view model dispatch = - [ - div [] [ - match y with - | 1 -> yield! subView model dispatch - | _ -> subView model dispatch - ] - ] - """ - [| - FSharpErrorSeverity.Warning, - 3222, - (13, 19, 13, 41), - "This expression returns a value of type 'int list' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'." - |] - - [] - let ``Warn If Discarded In List 3``() = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - """ -// stupid things to make the sample compile -let div _ _ = 1 -let subView _ _ = true -let y = 1 - -// elmish view -let view model dispatch = - [ - div [] [ - match y with - | 1 -> () - | _ -> subView model dispatch - ] - ] - """ - [| - FSharpErrorSeverity.Warning, - 20, - (13, 19, 13, 41), - "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - |] - - [] - let ``Warn Only On Last Expression``() = - CompilerAssert.TypeCheckSingleError - """ -let mutable x = 0 -while x < 1 do - printfn "unneeded" - x <- x + 1 - true - """ - FSharpErrorSeverity.Warning - 20 - (6, 5, 6, 9) - "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'." - - [] - let ``Warn If Possible Property Setter``() = - CompilerAssert.TypeCheckSingleError - """ -type MyClass(property1 : int) = - member val Property1 = property1 - member val Property2 = "" with get, set - -let x = MyClass(1) -let y = "hello" - -let changeProperty() = - x.Property2 = "20" - y = "test" - """ - FSharpErrorSeverity.Warning - 20 - (10, 5, 10, 23) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'." - - - [] - let ``Dont warn external function as unused``() = - CompilerAssert.Pass - """ -open System -open System.Runtime.InteropServices - -module Test = - - [] - extern int32 ExtractIconEx(string szFileName, int nIconIndex,IntPtr[] phiconLarge, IntPtr[] phiconSmall,uint32 nIcons) - - [] - extern int DestroyIcon(IntPtr hIcon) - -[] -let main _argv = - let _ = Test.DestroyIcon IntPtr.Zero - - let _ = Test.ExtractIconEx("", 0, [| |], [| |], 0u) - - 0 - """ diff --git a/tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs b/tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs deleted file mode 100644 index 860e6ca55c2..00000000000 --- a/tests/fsharp/Compiler/ErrorMessages/WrongSyntaxInForLoop.fs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open NUnit.Framework -open FSharp.Compiler.SourceCodeServices - -[] -module ``Wrong syntax in for loop`` = - - [] - let ``Equals instead of in``() = - CompilerAssert.ParseWithErrors - """ -module X -for i = 0 .. 100 do - () - """ - [|FSharpErrorSeverity.Error, 3215, (3, 7, 3, 8), "Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead?" |] diff --git a/tests/fsharp/Compiler/ILChecker.fs b/tests/fsharp/Compiler/ILChecker.fs deleted file mode 100644 index 4558d089113..00000000000 --- a/tests/fsharp/Compiler/ILChecker.fs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open System -open System.IO -open System.Diagnostics - -open NUnit.Framework -open TestFramework - -[] -module ILChecker = - - let config = initializeSuite () - - let private exec exe args = - let startInfo = ProcessStartInfo(exe, String.concat " " args) - startInfo.RedirectStandardError <- true - startInfo.UseShellExecute <- false - use p = Process.Start(startInfo) - p.WaitForExit() - p.StandardError.ReadToEnd(), p.ExitCode - - /// Filters i.e ['The system type \'System.ReadOnlySpan`1\' was required but no referenced system DLL contained this type'] - let private filterSpecialComment (text: string) = - let pattern = @"(\[\'(.*?)\'\])" - System.Text.RegularExpressions.Regex.Replace(text, pattern, - (fun me -> String.Empty) - ) - - let private checkILAux ildasmArgs dllFilePath expectedIL = - let ilFilePath = Path.ChangeExtension(dllFilePath, ".il") - - let mutable errorMsgOpt = None - try - let ildasmPath = config.ILDASM - - exec ildasmPath (ildasmArgs @ [ sprintf "%s /out=%s" dllFilePath ilFilePath ]) |> ignore - - let unifyRuntimeAssemblyName ilCode = - System.Text.RegularExpressions.Regex.Replace(ilCode, - "\[System.Runtime\]|\[System.Runtime.Extensions\]|\[mscorlib\]","[runtime]", - System.Text.RegularExpressions.RegexOptions.Singleline) - - let text = - let raw = File.ReadAllText(ilFilePath) - let asmName = Path.GetFileNameWithoutExtension(dllFilePath) - raw.Replace(asmName, "assembly") - |> unifyRuntimeAssemblyName - let blockComments = @"/\*(.*?)\*/" - let lineComments = @"//(.*?)\r?\n" - let strings = @"""((\\[^\n]|[^""\n])*)""" - let verbatimStrings = @"@(""[^""]*"")+" - let textNoComments = - System.Text.RegularExpressions.Regex.Replace(text, - blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, - (fun me -> - if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) then - if me.Value.StartsWith("//") then Environment.NewLine else String.Empty - else - me.Value), System.Text.RegularExpressions.RegexOptions.Singleline) - |> filterSpecialComment - - expectedIL - |> List.map (fun (ilCode: string) -> ilCode.Trim() |> unifyRuntimeAssemblyName ) - |> List.iter (fun (ilCode: string) -> - let expectedLines = ilCode.Split('\n') - let startIndex = textNoComments.IndexOf(expectedLines.[0].Trim()) - if startIndex = -1 then - errorMsgOpt <- Some("==EXPECTED CONTAINS==\n" + ilCode + "\n") - else - let errors = ResizeArray() - let actualLines = textNoComments.Substring(startIndex, textNoComments.Length - startIndex).Split('\n') - if actualLines.Length < expectedLines.Length then - let msg = sprintf "==EXPECTED AT LEAST %d LINES BUT FOUND ONLY %d ==\n" expectedLines.Length actualLines.Length - errorMsgOpt <- Some(msg + "==EXPECTED CONTAINS==\n" + ilCode + "\n") - else - for i = 0 to expectedLines.Length - 1 do - let expected = expectedLines.[i].Trim() - let actual = actualLines.[i].Trim() - if expected <> actual then - errors.Add(sprintf "\n==\nName: '%s'\n\nExpected:\t %s\nActual:\t\t %s\n==" actualLines.[0] expected actual) - - if errors.Count > 0 then - let msg = String.concat "\n" errors + "\n\n\n==EXPECTED==\n" + ilCode + "\n" - errorMsgOpt <- Some(msg + "\n\n\n==ACTUAL==\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) - ) - - if expectedIL.Length = 0 then - errorMsgOpt <- Some ("No Expected IL") - - match errorMsgOpt with - | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\n==ENTIRE ACTUAL==\n" + textNoComments) - | _ -> () - finally - try File.Delete(ilFilePath) with | _ -> () - - match errorMsgOpt with - | Some(errorMsg) -> - Assert.Fail(errorMsg) - | _ -> () - - let checkILItem item dllFilePath expectedIL = - checkILAux [ sprintf "/item:%s" item ] dllFilePath expectedIL - - let checkILItemWithLineNumbers item dllFilePath expectedIL = - checkILAux [ sprintf "/item:\"%s\"" item; "/linenum" ] dllFilePath expectedIL - - let checkIL dllFilePath expectedIL = - checkILAux [] dllFilePath expectedIL - - let reassembleIL ilFilePath dllFilePath = - let ilasmPath = config.ILASM - let errors, _ = exec ilasmPath ([ sprintf "%s /output=%s /dll" ilFilePath dllFilePath ]) - errors diff --git a/tests/fsharp/Compiler/Infrastructure/AstCompiler.fs b/tests/fsharp/Compiler/Infrastructure/AstCompiler.fs new file mode 100644 index 00000000000..8f254fa03d5 --- /dev/null +++ b/tests/fsharp/Compiler/Infrastructure/AstCompiler.fs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests.AstCompiler + +open FSharp.Test +open NUnit.Framework +open System.Reflection + +[] +module ``AST Compiler Smoke Tests`` = + + [] + let ``Simple E2E module compilation``() = + let assembly = + CompilerAssert.CompileOfAstToDynamicAssembly + """ +module TestModule + + let rec fib n = if n <= 1 then n else fib (n - 2) + fib (n - 1) +""" + + let method = assembly.GetType("TestModule").GetMethod("fib", BindingFlags.Static ||| BindingFlags.Public) + Assert.NotNull(method) + Assert.AreEqual(55, method.Invoke(null, [|10|])) + + [] + let ``Compile to Assembly``() = + let assembly = + CompilerAssert.CompileOfAst false + """ +module LiteralValue + +[] +let x = 7 +""" + + (ILVerifier assembly).VerifyIL [ + """ +.field public static literal int32 x = int32(0x00000007) + """ + ] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Language/AnonRecordTests.fs b/tests/fsharp/Compiler/Language/AnonRecordTests.fs index befa39f2bfc..fd7535d0079 100644 --- a/tests/fsharp/Compiler/Language/AnonRecordTests.fs +++ b/tests/fsharp/Compiler/Language/AnonRecordTests.fs @@ -3,7 +3,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module AnonRecordsTests = @@ -31,7 +32,7 @@ let sAnon = StructClass() type RefClass<'a when 'a : not struct>() = class end let rAnon = RefClass() """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 1 (3, 13, 3, 42) "A generic construct requires that the type 'struct {| R: int |}' have reference semantics, but it does not, i.e. it is a struct" @@ -43,7 +44,7 @@ let rAnon = RefClass() type StructClass<'a when 'a : struct>() = class end let sAnon = StructClass<{| S: int |}>() """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 1 (3, 13, 3, 38) "A generic construct requires that the type '{| S: int |}' is a CLI or F# struct type" diff --git a/tests/fsharp/Compiler/Language/ByrefTests.fs b/tests/fsharp/Compiler/Language/ByrefTests.fs index 2797125d791..2bb9709a86f 100644 --- a/tests/fsharp/Compiler/Language/ByrefTests.fs +++ b/tests/fsharp/Compiler/Language/ByrefTests.fs @@ -3,7 +3,10 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler [] module ByrefTests = @@ -82,31 +85,31 @@ let f5 () = """ [| ( - FSharpErrorSeverity.Error, + FSharpDiagnosticSeverity.Error, 3228, (12, 6, 12, 25), "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." ) ( - FSharpErrorSeverity.Error, + FSharpDiagnosticSeverity.Error, 3228, (17, 10, 17, 19), "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." ) ( - FSharpErrorSeverity.Error, + FSharpDiagnosticSeverity.Error, 3228, (21, 5, 21, 50), "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." ) ( - FSharpErrorSeverity.Error, + FSharpDiagnosticSeverity.Error, 3228, (25, 6, 25, 26), "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." ) ( - FSharpErrorSeverity.Error, + FSharpDiagnosticSeverity.Error, 3228, (28, 6, 28, 51), "The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." @@ -171,28 +174,198 @@ let test1 () = """ [| ( - FSharpErrorSeverity.Warning, + FSharpDiagnosticSeverity.Warning, 52, (3, 30, 3, 45), "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" ) ( - FSharpErrorSeverity.Warning, + FSharpDiagnosticSeverity.Warning, 52, (7, 5, 7, 20), "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" ) ( - FSharpErrorSeverity.Warning, + FSharpDiagnosticSeverity.Warning, 52, (10, 5, 10, 26), "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" ) ( - FSharpErrorSeverity.Warning, + FSharpDiagnosticSeverity.Warning, 52, (20, 5, 20, 29), "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" ) |] -#endif \ No newline at end of file +#endif + +#if NETCOREAPP + [] + let ``Consume CSharp interface with a method that has a readonly byref`` () = + let cs = + """ +using System; +using System.Buffers; + +namespace Example +{ + public interface IMessageReader + { + bool TryParseMessage(in byte input); + } +} + """ + let fs = + """ +module Module1 + +open Example + +type MyClass() = + + interface IMessageReader with + member this.TryParseMessage(input: inref): bool = + failwith "Not Implemented" + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(cs, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fs, SourceKind.Fsx, Library, cmplRefs = [csCmpl]) + + CompilerAssert.Compile fsCmpl + +#endif + + [] + let ``Can take native address to get a nativeptr of a mutable value`` () = + CompilerAssert.Pass + """ +#nowarn "51" + +let test () = + let mutable x = 1 + let y = &&x + () + """ + + [] + let ``Cannot take native address to get a nativeptr of an immmutable value`` () = + CompilerAssert.TypeCheckWithErrors + """ +#nowarn "51" + +let test () = + let x = 1 + let y = &&x + () + """ [| + (FSharpDiagnosticSeverity.Error, 256, (6, 13, 6, 16), "A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'") + |] + + [] + let ``Returning an 'inref<_>' from a property should emit System.Runtime.CompilerServices.IsReadOnlyAttribute on the return type of the signature`` () = + let src = + """ +module Test + +type C() = + let x = 59 + member _.X: inref<_> = &x + """ + + let verifyProperty = """.property instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) + X() + { + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) Test/C::get_X() + }""" + + let verifyMethod = """.method public hidebysig specialname + instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) + get_X() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" + + FSharp src + |> compile + |> verifyIL [verifyProperty;verifyMethod] + |> ignore + + [] + let ``Returning an 'inref<_>' from a generic method should emit System.Runtime.CompilerServices.IsReadOnlyAttribute on the return type of the signature`` () = + let src = + """ +module Test + +type C<'T>() = + let x = Unchecked.defaultof<'T> + member _.X<'U>(): inref<'T> = &x + """ + + let verifyMethod = """.method public hidebysig instance !T& modreq([runtime]System.Runtime.InteropServices.InAttribute) + X() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" + + FSharp src + |> compile + |> verifyIL [verifyMethod] + |> ignore + + [] + let ``Returning an 'inref<_>' from an abstract generic method should emit System.Runtime.CompilerServices.IsReadOnlyAttribute on the return type of the signature`` () = + let src = + """ +module Test + +[] +type C<'T>() = + abstract X<'U> : unit -> inref<'U> + """ + + let verifyMethod = """.method public hidebysig abstract virtual + instance !!U& modreq([runtime]System.Runtime.InteropServices.InAttribute) + X() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) """ + + FSharp src + |> compile + |> verifyIL [verifyMethod] + |> ignore + + [] + let ``Returning an 'inref<_>' from an abstract property should emit System.Runtime.CompilerServices.IsReadOnlyAttribute on the return type of the signature`` () = + let src = + """ +module Test + +type C = + abstract X: inref + """ + + let verifyProperty = """.property instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) + X() + { + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) Test/C::get_X() + }""" + + let verifyMethod = """.method public hidebysig specialname abstract virtual + instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) + get_X() cil managed + { + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" + + FSharp src + |> compile + |> verifyIL [verifyProperty;verifyMethod] + |> ignore \ No newline at end of file diff --git a/tests/fsharp/Compiler/Language/CompilerDirectiveTests.fs b/tests/fsharp/Compiler/Language/CompilerDirectiveTests.fs new file mode 100644 index 00000000000..46160b309bf --- /dev/null +++ b/tests/fsharp/Compiler/Language/CompilerDirectiveTests.fs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Compiler.Diagnostics + +[] +module ``Test Compiler Directives`` = + + [] + let ``compiler #r "" is invalid``() = + let source = """ +#r "" +""" + CompilerAssert.CompileWithErrors( + Compilation.Create(source, Fsx, Library), + [| + FSharpDiagnosticSeverity.Warning, 213, (2,1,2,6), "'' is not a valid assembly name" + |]) + + [] + let ``compiler #r " " is invalid``() = + let source = """ +#r " " +""" + CompilerAssert.CompileWithErrors( + Compilation.Create(source, Fsx, Library), + [| + FSharpDiagnosticSeverity.Warning, 213, (2,1,2,10), "'' is not a valid assembly name" + |]) diff --git a/tests/fsharp/Compiler/Language/ComputationExpressionTests.fs b/tests/fsharp/Compiler/Language/ComputationExpressionTests.fs new file mode 100644 index 00000000000..583c1c31e99 --- /dev/null +++ b/tests/fsharp/Compiler/Language/ComputationExpressionTests.fs @@ -0,0 +1,193 @@ +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Compiler.Diagnostics + +[] +module ComputationExpressionTests = + + let ``complex CE with source member and applicatives`` ceUsage = + sprintf """ +module Code +type ResultBuilder() = + member _.Return value = Ok value + member _.ReturnFrom (result: Result<_,_>) = result + member x.Zero() = x.Return () + member _.Bind(r: Result<'t,_>, binder: 't -> Result<_,_>) = match r with | Ok r' -> binder r' | Error e -> e + member _.Delay(gen: unit -> Result<_,_>) = gen + member _.Run(gen: unit -> Result<_,_>) = gen() + member _.BindReturn(x: Result<'t,_>, f) = Result.map f x + member inline _.Source(result : Result<_,_>) : Result<_,_> = result + +let result = ResultBuilder() + +module Result = + let zip x1 x2 = + match x1,x2 with + | Ok x1res, Ok x2res -> Ok (x1res, x2res) + | Error e, _ -> Error e + | _, Error e -> Error e + + let ofChoice c = + match c with + | Choice1Of2 x -> Ok x + | Choice2Of2 x -> Error x + + let fold onOk onError r = + match r with + | Ok x -> onOk x + | Error y -> onError y + +module Async = + let inline singleton value = value |> async.Return + let inline bind f x = async.Bind(x, f) + let inline map f x = x |> bind (f >> singleton) + let zip a1 a2 = async { + let! r1 = a1 + let! r2 = a2 + return r1,r2 + } + +module AsyncResult = + let zip x1 x2 = + Async.zip x1 x2 + |> Async.map(fun (r1, r2) -> Result.zip r1 r2) + + let foldResult onSuccess onError ar = + Async.map (Result.fold onSuccess onError) ar + +type AsyncResultBuilder() = + + member _.Return (value: 'T) : Async> = + async.Return <| result.Return value + + member inline _.ReturnFrom + (asyncResult: Async>) + : Async> = + asyncResult + + member _.Zero () : Async> = + async.Return <| result.Zero () + + member inline _.Bind + (asyncResult: Async>, + binder: 'T -> Async>) + : Async> = + async { + let! result = asyncResult + match result with + | Ok x -> return! binder x + | Error x -> return Error x + } + + member _.Delay + (generator: unit -> Async>) + : Async> = + async.Delay generator + + member this.Combine + (computation1: Async>, + computation2: Async>) + : Async> = + this.Bind(computation1, fun () -> computation2) + + member _.TryWith + (computation: Async>, + handler: System.Exception -> Async>) + : Async> = + async.TryWith(computation, handler) + + member _.TryFinally + (computation: Async>, + compensation: unit -> unit) + : Async> = + async.TryFinally(computation, compensation) + + member _.Using + (resource: 'T when 'T :> System.IDisposable, + binder: 'T -> Async>) + : Async> = + async.Using(resource, binder) + + member this.While + (guard: unit -> bool, computation: Async>) + : Async> = + if not <| guard () then this.Zero () + else this.Bind(computation, fun () -> this.While (guard, computation)) + + member this.For + (sequence: #seq<'T>, binder: 'T -> Async>) + : Async> = + this.Using(sequence.GetEnumerator (), fun enum -> + this.While(enum.MoveNext, + this.Delay(fun () -> binder enum.Current))) + + member inline _.BindReturn(x: Async>, f) = async.Bind(x, fun r -> Result.map f r |> async.Return) + member inline _.MergeSources(t1: Async>, t2: Async>) = + AsyncResult.zip t1 t2 + + member inline _.Source(result : Async>) : Async> = result + +[] +module ARExts = + type AsyncResultBuilder with + /// + /// Needed to allow `for..in` and `for..do` functionality + /// + member inline _.Source(s: #seq<_>) = s + + /// + /// Method lets us transform data types into our internal representation. + /// + member inline _.Source(result : Result<_,_>) : Async> = Async.singleton result + + /// + /// Method lets us transform data types into our internal representation. + /// + member inline _.Source(choice : Choice<_,_>) : Async> = + choice + |> Result.ofChoice + |> Async.singleton + + /// + /// Method lets us transform data types into our internal representation. + /// + member inline _.Source(asyncComputation : Async<_>) : Async> = asyncComputation |> Async.map Ok + +let asyncResult = AsyncResultBuilder() + +%s""" ceUsage + + [] + let ``do-bang can be used with nested CE expressions``() = + let code = ``complex CE with source member and applicatives`` """ +asyncResult { + let! something = asyncResult { return 5 } + do! asyncResult { + return () + } + return something +} +|> AsyncResult.foldResult id (fun (_err: string) -> 10) +|> Async.RunSynchronously +|> printfn "%d" +""" + CompilerAssert.Pass code + + [] + let ``match-bang should apply source transformations to its inputs`` () = + let code = ``complex CE with source member and applicatives`` """ +asyncResult { + // if the source transformation is not applied, the match will not work, + // because match! is only defined in terms of let!, and the only + // bind overload provided takes AsyncResult as its input. + match! Ok 5 with + | 5 -> return "ok" + | n -> return! (Error (sprintf "boo %d" n)) +} +|> AsyncResult.foldResult id (fun (err: string) -> err) +|> Async.RunSynchronously +|> printfn "%s" +""" + CompilerAssert.Pass code diff --git a/tests/fsharp/Compiler/Language/CustomCollectionTests.fs b/tests/fsharp/Compiler/Language/CustomCollectionTests.fs index 552be4e49d1..05840ec2b06 100644 --- a/tests/fsharp/Compiler/Language/CustomCollectionTests.fs +++ b/tests/fsharp/Compiler/Language/CustomCollectionTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module CustomCollectionTests = @@ -13,12 +14,12 @@ open System type foo() = let mutable i = "" member this.GetReverseIndex(_x: int, y: string) = y + " " - member __.Item with get (_x: string) = i and set idx value = i <- idx + value + member _.Item with get (_x: string) = i and set idx value = i <- idx + value let a = foo() -a.[^"2"] <- "-1" +a[^"2"] <- "-1" -if a.["2"] <> "2 -1" then failwithf "expected 2 -1 but got %A" a.["2"] +if a["2"] <> "2 -1" then failwithf "expected 2 -1 but got %A" a["2"] """ [] @@ -33,9 +34,9 @@ type foo() = member this.GetSlice(_: string option, _: string option) = i let a = foo() -a.[^"2"..^"1"] <- "-1" +a[^"2"..^"1"] <- "-1" -if a.["2".."1"] <> "2 1 -1" then failwithf "expected 2 1 -1 but got %A" a.["2".."1"] +if a["2".."1"] <> "2 1 -1" then failwithf "expected 2 1 -1 but got %A" a["2".."1"] """ [] @@ -50,7 +51,7 @@ type foo() = let a = foo() -if a.[^2] <> 12 then failwith "expected 12" +if a[^2] <> 12 then failwith "expected 12" """ [] @@ -62,12 +63,12 @@ open System type foo() = let mutable i = "" member this.GetReverseIndex(x: int, y: string) = x.ToString() + " " + y - member __.Item with get (_x: string) = i and set (idx1, idx2) value = i <- idx1 + " " + idx2 + " " + value + member _.Item with get (_x: string) = i and set (idx1, idx2) value = i <- idx1 + " " + idx2 + " " + value let a = foo() -a.[^"1",^"2"] <- "3" +a[^"1",^"2"] <- "3" -if a.[""] <> "0 1 1 2 3" then failwithf "expected 0 1 1 2 3 but got %A" a.[""] +if a[""] <> "0 1 1 2 3" then failwithf "expected 0 1 1 2 3 but got %A" a[""] """ [] @@ -82,12 +83,12 @@ type foo() = let a = foo() -if a.[^2,^1] <> 24 then failwithf "expected 23 but got %A" a.[^2,^1] +if a[^2,^1] <> 24 then failwithf "expected 23 but got %A" a[^2,^1] """ [] let ``Custom collection with Item and no GetReverseIndex should not support reverse index indexing``() = - CompilerAssert.TypeCheckSingleError + CompilerAssert.TypeCheckSingleErrorWithOptions [| "--langversion:preview" |] """ open System @@ -98,11 +99,10 @@ let a = foo() if a.[^2] <> 12 then failwith "expected 12" """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 39 (9,7,9,9) - "The field, constructor or member 'GetReverseIndex' is not defined." - + "The type 'foo' does not define the field, constructor or member 'GetReverseIndex'." [] let ``Custom collection with GetSlice and GetReverseIndex should support reverse index slicing``() = @@ -120,7 +120,7 @@ type foo() = let a = foo() -if a.[^2..1] <> 13 then failwith "expected 13" +if a[^2..1] <> 13 then failwith "expected 13" """ [] @@ -137,9 +137,9 @@ type foo() = let a = foo() -if a.[^2..1] <> 13 then failwith "expected 13" +if a[^2..1] <> 13 then failwith "expected 13" """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 39 - (12,7,12,9) - "The field, constructor or member 'GetReverseIndex' is not defined." + (12,6,12,8) + "The type 'foo' does not define the field, constructor or member 'GetReverseIndex'." diff --git a/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs new file mode 100644 index 00000000000..fca1e5fd706 --- /dev/null +++ b/tests/fsharp/Compiler/Language/DefaultInterfaceMemberTests.fs @@ -0,0 +1,5056 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Compiler.Diagnostics + +#if NETCOREAPP + +[] +module DefaultInterfaceMemberConsumptionTests_LanguageVersion_4_6 = + + [] + let targetVersion = "5.0" + + [] + let ``IL - Errors with lang version not supported`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class interface public abstract auto ansi ILTest.ITest +{ + .method public hidebysig newslot virtual instance void DefaultMethod() cil managed + { + .maxstack 8 + IL_0000: ret + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open ILTest + +type Test () = + + interface ITest + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [ilCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.DefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# with explicit implementation - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write("ITest1." + nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method2() + { + Console.Write("ITest2" + nameof(Method2)); + } + + void Method3(); + } + + public interface ITest3 : ITest2 + { + void ITest2.Method3() + { + Console.Write("ITest3" + nameof(Method3)); + } + + void Method4(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest3 with + + member __.Method1 () = Console.Write("FSharp-Method1") + + member __.Method2 () = Console.Write("FSharp-Method2") + + member __.Method3 () = Console.Write("FSharp-Method3") + + member __.Method4 () = Console.Write("FSharp-Method4") + +[] +let main _ = + let test = Test () :> ITest3 + test.Method1 () + Console.Write("-") + test.Method2 () + Console.Write("-") + test.Method3 () + Console.Write("-") + test.Method4 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharp-Method1-FSharp-Method2-FSharp-Method3-FSharp-Method4") + + [] + let ``C# simple - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface ITest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for those members: +\t'ITest.DefaultMethod() : unit' +\t'ITest.NonDefaultMethod() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple - Errors with lang version not supported - 2`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface ITest with + + member __.NonDefaultMethod () = () + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.DefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple - Errors with lang version not supported - 3`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface ITest + { + void Method1() + { + } + + void Method2() + { + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface ITest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for those members: + 'ITest.Method1() : unit' + 'ITest.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with internal DIM - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest with + + member __.NonDefaultMethod () = Console.Write("NonDefaultMethod") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (9, 15, 9, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 20), "No implementation was given for 'ITest.DefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with internal DIM - Errors with not accessible`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest with + + member __.DefaultMethod () = Console.Write("DefaultMethod") + + member __.NonDefaultMethod () = Console.Write("NonDefaultMethod") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 855, (11, 19, 11, 32), "No abstract or interface member was found that corresponds to this override") + |]) + + [] + let ``C# simple with static operator method - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int operator +(I1 x, I1 y) + { + Console.Write("I1.+"); + return 1; + } + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface I2 + +let f () = + let x = Test () :> I1 + let y = Test () :> I2 + x + y + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (14, 7, 14, 8), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 3350, (14, 9, 14, 10), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + + [] + let ``C# simple with static method - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(I1 x, I1 y) + { + Console.Write("I1.+"); + return 1; + } + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface I2 + +let f () = + let x = Test () :> I1 + let y = Test () :> I2 + I1.StaticMethod (x, y) + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (14, 5, 14, 27), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + + [] + let ``C# simple with static property - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticProperty { get; set; } + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +let f () = + I1.StaticProperty + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 5, 8, 22), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + + [] + let ``C# simple with static field - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticField; + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +let f () = + I1.StaticField + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (8, 5, 8, 19), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + + [] + let ``C# simple with static method using SRTP - Errors with lang version not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +let inline callStatic< ^T when ^T : (static member StaticMethod : int * int -> int)> x y = + ( ^T : (static member StaticMethod : int * int -> int) (x, y)) + +let f1 () = + callStatic 1 2 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (9, 5, 9, 15), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + + [] + let ``C# simple diamond inheritance - Errors with lang version not supported and should not see the error for specific implementation`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface IB + interface IC + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 363, (8, 15, 8, 17), "The interface 'IA' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") + (FSharpDiagnosticSeverity.Error, 3350, (9, 15, 9, 17), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 17), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple diamond inheritance - Errors with lang version not supported and should not see the error for specific implementation - 2`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface IB + interface IC + interface IA + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (10, 15, 10, 17), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (10, 15, 10, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with protected DIM - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + protected void M1() + { + Console.Write(nameof(M1)); + } + + public void M2() + { + this.M1(); + this.M1(); + } + } + + public interface ITest2 : ITest + { + void ITest.M1() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + // protected member + member __.M1() = + Console.Write("Protected") + + member __.M2() = + Console.Write("Explicit") + +type Test2 () = + inherit Test () + + interface ITest2 with + + // protected member + member __.M1() = + Console.Write("ProtectedOverride") + +[] +let main _ = + let test = Test () :> ITest + test.M2 () + + Console.Write("-") + + let test2 = Test2 () :> ITest + test2.M2 () + 0 + """ + + // Explicitly implementing a protected DIM is allowed in F# 4.6. + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "Explicit-Explicit") + + [] + let ``C# with overloading and generics - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M(U x, T y) + { + Console.Write("M(U, T)"); + } + + void M(T x, U y); + + void M(T x); + + void M(U x); + + void M(T x, string text); + } + + public interface IB : IA + { + void IA.M(T x) + { + Console.Write("InIB"); + } + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IA with + + member __.M(_x: int) = Console.Write("InTest") + + member __.M<'Item> (x: int, y: 'Item) = + Console.Write(x.ToString()) + Console.Write(y.ToString ()) + + member __.M<'TTT> (x: 'TTT) = + Console.Write(x.ToString ()) + + member __.M (x: int, text: string) = + Console.Write("ABC") + Console.Write(x.ToString()) + Console.Write(text) + + member __.M<'U> (_x: 'U, _y: int) = () + +type Test2 () = + inherit Test () + + interface IB with + + member __.M(_x: int) = Console.Write("InTest2") + +[] +let main _ = + let test = Test () :> IA + let test2 = Test2 () :> IA + + test.M 1 + test2.M 1 + + test.M (123, 456s) + test2.M (789, 111s) + + test.M "STRING" + test2.M "-STRING" + + test.M (222, "FSharp") + test2.M (333, "CSharp") + + test.M (obj (), 1) + test2.M (obj (), 1) + + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "InTestInTest2123456789111STRING-STRINGABC222FSharpABC333CSharp") + + + [] + let ``C# with overloading and generics - Errors with lang version`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M(U x, T y) + { + Console.Write("M(U, T)"); + } + + void M(T x, U y); + + void M(T x); + + void M(U x); + + void M(T x, string text); + } + + public interface IB : IA + { + void IA.M(T x) + { + Console.Write("InIB"); + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +open System + +type Test () = + + interface IA with + + member __.M(_x: int) = Console.Write("InTest") + + member __.M<'Item> (x: int, y: 'Item) = + Console.Write(string x) + Console.Write(y.ToString ()) + + member __.M<'TTT> (x: 'TTT) = + Console.Write(x.ToString ()) + + member __.M (x: int, text: string) = + Console.Write("ABC") + Console.Write(string x) + Console.Write(text) + +type Test2 () = + inherit Test () + + interface IB + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3350, (10, 15, 10, 22), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 358, (10, 15, 10, 22), "The override for 'M<'U> : 'U * int -> unit' was ambiguous") + |]) + +#else + +[] +module DefaultInterfaceMemberConsumptionTests_LanguageVersion_4_6_net472 = + + [] + let targetVersion = "5.0" + + [] + let ``IL - Errors with lang version and target runtime not supported`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class interface public abstract auto ansi ILTest.ITest +{ + .method public hidebysig newslot virtual instance void DefaultMethod() cil managed + { + .maxstack 8 + IL_0000: ret + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open ILTest + +type Test () = + + interface ITest + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [ilCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3351, (8, 15, 8, 20), "Feature 'default interface member consumption' is not supported by target runtime.") + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.DefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``IL - Errors with target runtime not supported when implemented`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class interface public abstract auto ansi ILTest.ITest +{ + .method public hidebysig newslot virtual instance void DefaultMethod() cil managed + { + .maxstack 8 + IL_0000: ret + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open ILTest + +type Test () = + + interface ITest with + + member __.DefaultMethod () = () + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [ilCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3351, (8, 15, 8, 20), "Feature 'default interface member consumption' is not supported by target runtime.") + |]) + + [] + let ``C# simple with static method - Errors with lang version and target runtime not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(I1 x, I1 y) + { + Console.Write("I1.+"); + return 1; + } + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface I2 + +let f () = + let x = Test () :> I1 + let y = Test () :> I2 + I1.StaticMethod (x, y) + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3351, (14, 5, 14, 27), "Feature 'default interface member consumption' is not supported by target runtime.") + (FSharpDiagnosticSeverity.Error, 3350, (14, 5, 14, 27), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + +#endif + +#if NETCOREAPP + +[] +module DefaultInterfaceMemberConsumptionTests = + + [] + let ``C# simple - Errors with un-implemented non-DIM`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface ITest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.NonDefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with static operator method - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int operator +(I1 x, I1 y) + { + Console.Write("I1.+"); + return 1; + } + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface I2 + +[] +let main _ = + let x = Test () :> I1 + let y = Test () :> I2 + let result = x + y + Console.Write(result.ToString()) + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "I1.+1") + + [] + let ``C# simple - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + test.DefaultMethod () + Console.Write("-") + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod-NonDefaultMethod") + + [] + let ``C# simple with protected DIM - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + protected void M1() + { + Console.Write(nameof(M1)); + } + + public void M2() + { + this.M1(); + this.M1(); + } + } + + public interface ITest2 : ITest + { + void ITest.M1() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + // protected member + member _.M1() = + Console.Write("Protected") + +type Test2 () = + inherit Test () + + interface ITest2 with + + // protected member + member _.M1() = + Console.Write("ProtectedOverride") + +[] +let main _ = + let test = Test () :> ITest + test.M2 () + + Console.Write("-") + + let test2 = Test2 () :> ITest + test2.M2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "ProtectedProtected-ProtectedOverrideProtectedOverride") + + [] + let ``C# simple with protected DIM using object expression - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + protected void M1() + { + Console.Write(nameof(M1)); + } + + public void M2() + { + this.M1(); + this.M1(); + } + } + + public interface ITest2 : ITest + { + void ITest.M1() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +[] +let main _ = + let test = + { new ITest with + member _.M1() = + Console.Write("ObjExprProtected") } + test.M2 () + + Console.Write("-") + + let test2 = + { new ITest2 with + member _.M1() = + Console.Write("ObjExprProtected2") } + test2.M2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "ObjExprProtectedObjExprProtected-ObjExprProtected2ObjExprProtected2") + + [] + let ``C# simple with protected DIM - Errors due to protected level`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + protected void M1() + { + Console.Write(nameof(M1)); + } + + public void M2() + { + this.M1(); + this.M1(); + } + } + + public interface ITest2 : ITest + { + void ITest.M1() + { + } + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest with + + // protected member + member _.M1() = + Console.Write("Protected") + +type Test2 () = + inherit Test () + + interface ITest2 with + + // protected member + member _.M1() = + Console.Write("ProtectedOverride") + +let f () = + let test = Test () :> ITest + test.M1 () + + Console.Write("-") + + let test2 = Test2 () :> ITest + test2.M1 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 491, (26, 5, 26, 15), "The member or object constructor 'M1' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + (FSharpDiagnosticSeverity.Error, 491, (31, 5, 31, 16), "The member or object constructor 'M1' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.") + |]) + + [] + let ``C# simple with protected DIM - Errors due to protected level - 2`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + protected void M1() + { + Console.Write(nameof(M1)); + } + + public void M2() + { + this.M1(); + this.M1(); + } + } + + public interface ITest2 : ITest + { + void ITest.M1() + { + } + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + member this.M() = + (this :> ITest).M1() + + interface ITest with + + member this.M2() = + (this :> ITest).M1() + + // protected member + member _.M1() = + Console.Write("Protected") + +type Test2 () = + inherit Test () + + member this.M() = + (this :> ITest2).M1() + + interface ITest2 with + + member this.M2() = + (this :> ITest).M1() + + // protected member + member _.M1() = + Console.Write("ProtectedOverride") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 629, (10, 9, 10, 27), "Method 'M1' is not accessible from this code location") + (FSharpDiagnosticSeverity.Error, 629, (15, 13, 15, 31), "Method 'M1' is not accessible from this code location") + (FSharpDiagnosticSeverity.Error, 629, (25, 9, 25, 28), "Method 'M1' is not accessible from this code location") + (FSharpDiagnosticSeverity.Error, 629, (30, 13, 30, 31), "Method 'M1' is not accessible from this code location") + |]) + + [] + let ``C# simple with internal DIM - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "NonDefaultMethod") + + [] + let ``C# simple with internal DIM - Errors with missing method`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +let f () = + let test = Test () :> ITest + test.DefaultMethod () + test.NonDefaultMethod () + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 39, (16, 10, 16, 23), "The type 'ITest' does not define the field, constructor or member 'DefaultMethod'. Maybe you want one of the following: + NonDefaultMethod") + |]) + + [] + let ``C# simple with internal DIM - Errors with not accessible`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest with + + member __.DefaultMethod () = + Console.Write("DefaultMethod") + + member __.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 855, (11, 19, 11, 32), "No abstract or interface member was found that corresponds to this override") + |]) + + [] + let ``C# simple with internal DIM but with IVT - Runs`` () = + let csharpSource = + """ +using System; +using System.Runtime.CompilerServices; + +[assembly:InternalsVisibleTo("Test")] + +namespace CSharpTest +{ + public interface ITest + { + internal void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.DefaultMethod () = + Console.Write("IVT-") + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + test.DefaultMethod () + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl], name = "Test") + + CompilerAssert.ExecutionHasOutput(fsCmpl, "IVT-NonDefaultMethod") + + [] + let ``C# simple with one DIM for F# object expression - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +[] +let main _ = + let test = { new ITest } + test.DefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod") + + [] + let ``C# simple with one DIM and one non-DIM for F# object expression - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +[] +let main _ = + let test = { new ITest with member _.NonDefaultMethod () = Console.Write("ObjExpr") } + test.DefaultMethod () + Console.Write("-") + test.NonDefaultMethod(); + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "DefaultMethod-ObjExpr") + + [] + let ``C# simple with one DIM and one non-DIM for F# object expression - Errors with lack of implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +let test = { new ITest } + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 366, (7, 12, 7, 25), "No implementation was given for 'ITest.NonDefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with override - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.DefaultMethod () = + Console.Write("OverrideDefaultMethod") + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + test.DefaultMethod () + Console.Write("-") + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "OverrideDefaultMethod-NonDefaultMethod") + + [] + let ``C# simple with override for object expression - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + void DefaultMethod() + { + Console.Write(nameof(DefaultMethod)); + } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +[] +let main _ = + let test = + { new ITest with + member _.DefaultMethod () = + Console.Write("ObjExprOverrideDefaultMethod") + member _.NonDefaultMethod () = + Console.Write("ObjExprNonDefaultMethod") } + test.DefaultMethod () + Console.Write("-") + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "ObjExprOverrideDefaultMethod-ObjExprNonDefaultMethod") + + [] + let ``C# from hierarchical interfaces - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest2 + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "FromITest2-Method1-FromITest2-Method2") + + [] + let ``C# diamond hierarchical interfaces - Errors with lack of explicit shared interface type`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest2 + interface ITest3 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 363, (9, 15, 9, 21), "The interface 'ITest1' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") + (FSharpDiagnosticSeverity.Error, 3352, (10, 15, 10, 21), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (10, 15, 10, 21), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (10, 15, 10, 21), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 21), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 21), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 21), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces - Errors with no most specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ITest1 + interface ITest2 + interface ITest3 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 21), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 21), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 21), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces but combined in one C# interface - Errors with no most specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest : ITest2, ITest3 + { + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface ICombinedTest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 28), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 28), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces but combined in one F# interface - Errors with no most specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type ICombinedTest = + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (13, 15, 13, 28), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces but re-abstracted in one and then combined in one F# interface - Errors with no most specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type ICombinedTest = + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (13, 15, 13, 28), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces but all re-abstracted and then combined in one F# interface - Errors with need to implement members`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } + + public interface ITest3 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type ICombinedTest = + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 3352, (13, 15, 13, 28), "Interface member 'ITest1.Method2() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (13, 15, 13, 28), "No implementation was given for those members: + 'ITest1.Method1() : unit' + 'ITest1.Method2() : unit' +Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces then combined in one F# interface and then implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type ICombinedTest = + inherit ITest1 + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest with + + member _.Method1 () = Console.Write("FSharpICombinedTest-Method1") + + member _.Method2 () = Console.Write("FSharpICombinedTest-Method2") + +[] +let main _ = + let test = Test () :> ITest3 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpICombinedTest-Method1-FSharpICombinedTest-Method2") + + [] + let ``C# diamond hierarchical interfaces but all re-abstracted and then combined in one F# interface and then implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } + + public interface ITest3 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type ICombinedTest = + inherit ITest1 + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest with + + member _.Method1 () = Console.Write("FSharpICombinedTest-Method1") + + member _.Method2 () = Console.Write("FSharpICombinedTest-Method2") + +[] +let main _ = + let test = Test () :> ITest2 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpICombinedTest-Method1-FSharpICombinedTest-Method2") + + [] + let ``C# diamond hierarchical interfaces then using explicit interfaces and then implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest2 + interface ITest1 with + + member _.Method1 () = Console.Write("FSharpExplicitTest-Method1") + + member _.Method2 () = Console.Write("FSharpExplicitTest-Method2") + interface ITest3 + +[] +let main _ = + let test = Test () :> ITest2 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "FSharpExplicitTest-Method1-FSharpExplicitTest-Method2") + + [] + let ``C# diamond hierarchical interfaces but all re-abstracted and then combined in one F# interface and then implemented one method - Errors with no most specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } + + public interface ITest3 : ITest1 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type ICombinedTest = + inherit ITest1 + inherit ITest2 + inherit ITest3 + +type Test () = + + interface ICombinedTest with + + member _.Method2 () = Console.Write("FSharpICombinedTest-Method2") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (14, 15, 14, 28), "Interface member 'ITest1.Method1() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (14, 15, 14, 28), "No implementation was given for 'ITest1.Method1() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond hierarchical interfaces then combined in one C# interface and then implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ICombinedTest + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpICombinedTest-Method1-CSharpICombinedTest-Method2") + + [] + let ``C# diamond complex hierarchical interfaces then combined in one C# interface and then implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest3-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest1 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method2)); + } + } + + public interface ICombinedTest2 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method2)); + } + } + + public interface ICombinedSideTest : ICombinedTest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method2)); + } + } + + public interface IFinalCombinedTest : ICombinedTest1, ICombinedSideTest + { + void ITest1.Method1() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface IFinalCombinedTest + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-CSharpIFinalCombinedTest-Method2") + + [] + let ``C# diamond complex hierarchical interfaces then combined in one C# interface and then implemented - Runs - 2`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest1 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method2)); + } + } + + public interface ICombinedTest2 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method1)); + } + } + + public interface ICombinedSideTest : ICombinedTest1 + { + void ITest1.Method2() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method2)); + } + } + + public interface IFinalCombinedTest : ICombinedTest2, ICombinedSideTest + { + void ITest1.Method1() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method1)); + } + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ICombinedSideTest with + + member _.Method2 () = () + + interface IFinalCombinedTest + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-") + + [] + let ``C# diamond complex hierarchical interfaces then combined in one C# interface and then implemented - Runs - 3`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest1 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method2)); + } + } + + public interface ICombinedTest2 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method1)); + } + } + + public interface ICombinedSideTest : ICombinedTest1 + { + void ITest1.Method2() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method2)); + } + } + + public interface IFinalCombinedTest : ICombinedTest2, ICombinedSideTest + { + void ITest1.Method1() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ICombinedSideTest + interface IFinalCombinedTest + interface ITest1 + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "CSharpIFinalCombinedTest-Method1-CSharpIFinalCombinedTest-Method2") + + [] + let ``C# multi-diamond complex hierarchical interfaces with hiding methods then explicitly implemented - Runs`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IBase + { + void Method() + { + } + } + + public interface IA1 : IBase + { + void IBase.Method() + { + } + + new void Method(); + } + + public interface IB1 : IBase + { + void IBase.Method() + { + } + + new void Method(); + } + + public interface IC1 : IBase + { + void IBase.Method() + { + } + + new void Method(); + } + + public interface ID1 : IBase + { + void IBase.Method() + { + } + } + + public interface IDiamond1 : IA1, IB1 + { + } + + public interface IDiamond2 : IC1, ID1 + { + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface IBase with + + member _.Method () = Console.Write("IBase") + + interface IA1 with + + member _.Method () = Console.Write("IA1") + + interface IB1 with + + member _.Method () = Console.Write("IB1") + + interface IC1 with + + member _.Method () = Console.Write("IC1") + + interface IDiamond1 + interface IDiamond2 + +[] +let main _ = + let test = Test () :> ID1 + test.Method () + Console.Write("-") // IBase + + //let test = Test () :> IDiamond1 + //test.Method () + //Console.Write("-") // IA1 + + let test = Test () :> IB1 + test.Method () + Console.Write("-") // IB1 + + let test = Test () :> IA1 + test.Method () + Console.Write("-") // IA1 + + let test = Test () :> IDiamond2 + test.Method () + Console.Write("-") // IC1 + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "IBase-IB1-IA1-IC1-") + + [] + let ``C# multi-diamond complex hierarchical interfaces then explicitly implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IBase + { + void Method() + { + } + } + + public interface IA1 : IBase + { + abstract void IBase.Method(); + } + + public interface IB1 : IBase + { + } + + public interface IC1 : IBase + { + void CMethod() + { + Console.Write("ABC"); + } + } + + public interface IC2 : IC1 + { + abstract void IC1.CMethod(); + } + + public interface IC3 : IC2 + { + void IC1.CMethod() + { + Console.Write("XYZ"); + } + } + + public interface ID1 : IBase + { + } + + public interface IDiamond1 : IA1, IB1 + { + } + + public interface IDiamond2 : IC2, ID1 + { + } + + public interface IDiamond3 : IC3, IA1 + { + } + + public interface IMultiDiamond1 : IDiamond1, IDiamond3 + { + } + + class CSharpClass : IBase, IDiamond2, IMultiDiamond1 + { + void IBase.Method() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface IBase with + + member _.Method () = Console.Write "123" + + interface IC2 + interface IDiamond2 + interface IMultiDiamond1 + +[] +let main _ = + let test = Test () :> IMultiDiamond1 + test.Method () + test.CMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "123XYZ") + + [] + let ``C# diamond complex hierarchical interfaces then explicitly implemented - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest1 : ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("CSharpICombinedTest1-" + nameof(Method2)); + } + } + + public interface ICombinedTest2 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method1)); + } + } + + public interface ICombinedSideTest : ICombinedTest1 + { + void ITest1.Method2() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method2)); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest2 + interface ICombinedSideTest + interface ITest1 with + + member _.Method1 () = () + + member _.Method2 () = () + +[] +let main _ = + let test = Test () :> ITest1 + test.Method1 () + Console.Write("-") + test.Method2 () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "-") + + [] + let ``C# diamond complex hierarchical interfaces then combined in one C# interface and then implemented - Errors with no impl`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1() + { + Console.Write(nameof(Method1)); + } + + void Method2(); + } + + public interface ITest2 : ITest1 + { + void ITest1.Method1() + { + Console.Write("FromITest2-" + nameof(Method1)); + } + + void ITest1.Method2() + { + Console.Write("FromITest2-" + nameof(Method2)); + } + } + + public interface ITest3 : ITest1 + { + void ITest1.Method2() + { + Console.Write("FromITest3-" + nameof(Method2)); + } + } + + public interface ICombinedTest1 : ITest3, ITest2 + { + abstract void ITest1.Method1(); + + abstract void ITest1.Method2(); + } + + public interface ICombinedTest2 : ITest3, ITest2 + { + void ITest1.Method1() + { + Console.Write("CSharpICombinedTest2-" + nameof(Method1)); + } + } + + public interface ICombinedSideTest : ICombinedTest1 + { + void ITest1.Method2() + { + Console.Write("CSharpICombinedSideTest-" + nameof(Method2)); + } + } + + public interface IFinalCombinedTest : ICombinedTest2, ICombinedSideTest + { + void ITest1.Method1() + { + Console.Write("CSharpIFinalCombinedTest-" + nameof(Method1)); + } + + abstract void ITest1.Method2(); + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open System +open CSharpTest + +type Test () = + + interface IFinalCombinedTest + interface ICombinedSideTest + +type Test2 () = + inherit Test () + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 366, (10, 15, 10, 32), "No implementation was given for 'ITest1.Method2() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with property - Runs`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface ITest + { + string A { get { return "A"; } } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + Console.Write(test.A) + Console.Write("-") + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "A-NonDefaultMethod") + + [] + let ``C# simple with property and override - Runs`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface ITest + { + string A { get { return "A"; } } + + void NonDefaultMethod(); + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest with + + member _.A with get () = "OverrideA" + + member _.NonDefaultMethod () = + Console.Write("NonDefaultMethod") + +[] +let main _ = + let test = Test () :> ITest + Console.Write(test.A) + Console.Write("-") + test.NonDefaultMethod () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "OverrideA-NonDefaultMethod") + + [] + let ``C# with same methods names that hide with overloading - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest1 + { + void Method1(int x) + { + Console.Write(x); + } + } + + public interface ITest2 : ITest1 + { + void Method1(int x) + { + Console.Write(x); + } + } + + public interface ITest3 : ITest2 + { + void ITest1.Method1(int x) + { + Console.Write(x); + } + + void ITest2.Method1(int x) + { + Console.Write(x); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface ITest2 + interface ITest3 + +[] +let main _ = + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "") + + [] + let ``C# with mutliple separate interfaces - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void MA() + { + Console.Write("IA.MA"); + } + } + + public interface IB + { + void MB() + { + Console.Write("IB.MB"); + } + } + + public interface IB1 : IB + { + void IB.MB() + { + Console.Write("IB1.IB.MB"); + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type Test () = + + interface IA + interface IB1 + +[] +let main _ = + let test = Test () + let testIA = test :> IA + let testIB = test :> IB + let testIB1 = test :> IB1 + testIA.MA () + Console.Write("-") + testIB.MB () + Console.Write("-") + testIB1.MB () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "IA.MA-IB1.IB.MB-IB1.IB.MB") + + [] + let ``C# simple diamond inheritance - Errors with no specific implementation`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open CSharpTest + +type Test () = + + interface IB + interface IC + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 363, (8, 15, 8, 17), "The interface 'IA' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") + (FSharpDiagnosticSeverity.Error, 3352, (9, 15, 9, 17), "Interface member 'IA.M() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (9, 15, 9, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (FSharpDiagnosticSeverity.Error, 3352, (8, 15, 8, 17), "Interface member 'IA.M() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple diamond inheritance - Errors with no specific implementation - 2`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +type Test () = + + interface IB + interface IC + interface IA + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (10, 15, 10, 17), "Interface member 'IA.M() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (10, 15, 10, 17), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple diamond inheritance - Runs`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IB + interface IC + interface IA with + + member _.M () = Console.Write("M") + +[] +let main _ = + let test = Test () + let testIA = test :> IA + let testIB = test :> IB + let testIC = test :> IC + testIA.M () + testIB.M () + testIC.M () + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "MMM") + + [] + let ``C# simple diamond inheritance with overloading - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M(int x, float y) + { + } + + void M(); + + void M(int x); + + void M(float x); + + void M(int x, int y) + { + } + } + + public interface IB : IA + { + void IA.M() + { + } + + void IA.M(int x) + { + Console.Write(x); + } + } + + public interface IC : IA + { + void IA.M() + { + } + + void IA.M(int x, float y) + { + Console.Write(x); + Console.Write("float"); + } + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IB + interface IC + interface IA with + + member _.M () = Console.Write("M") + + member _.M (_x: single) = Console.Write("fs_single") + +[] +let main _ = + let test = Test () + let testIA = test :> IA + let testIB = test :> IB + let testIC = test :> IC + testIA.M () + testIC.M 123 + testIB.M (456, 1.f) + testIC.M 1.f + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "M123456floatfs_single") + + [] + let ``C# simple diamond inheritance with overloading - Errors with missing overload method`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M(int x, float y) + { + } + + void M(); + + void M(int x); + + void M(float x); + + void M(int x, int y) + { + } + } + + public interface IB : IA + { + void IA.M() + { + } + + void IA.M(int x) + { + Console.Write(x); + } + } + + public interface IC : IA + { + void IA.M() + { + } + + void IA.M(int x, float y) + { + Console.Write(x); + Console.Write("float"); + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +open System + +type Test () = + + interface IB + interface IC + interface IA with + + member _.M () = Console.Write("M") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 366, (12, 15, 12, 17), "No implementation was given for 'IA.M(x: float32) : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# with overloading and generics - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M(U x, T y) + { + Console.Write("M(U, T)"); + } + + void M(T x, U y); + + void M(T x); + + void M(U x); + + void M(T x, string text); + } + + public interface IB : IA + { + void IA.M(T x) + { + Console.Write("InIB"); + } + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IA with + + member _.M(_x: int) = Console.Write("InTest") + + member _.M<'Item> (x: int, y: 'Item) = + Console.Write(x.ToString()) + Console.Write(y.ToString ()) + + member _.M<'TTT> (x: 'TTT) = + Console.Write(x.ToString ()) + + member _.M (x: int, text: string) = + Console.Write("ABC") + Console.Write(x.ToString()) + Console.Write(text) + +type Test2 () = + inherit Test () + + interface IB + +[] +let main _ = + let test = Test () :> IA + let test2 = Test2 () :> IB + + test.M 1 + test2.M 1 + + test.M (123, 456s) + test2.M (789, 111s) + + test.M "STRING" + test2.M "-STRING" + + test.M (222, "FSharp") + test2.M (333, "CSharp") + + test.M (obj (), 1) + test2.M (obj (), 1) + + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "InTestInTest123456789111STRING-STRINGABC222FSharpABC333CSharpM(U, T)M(U, T)") + + [] + let ``C# diamond inheritance with overloading and generics and properties - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + T Prop1 { get { return default(T); } } + + T Prop2 { set; } + + T Prop3 { get { return default(T); } set { } } + + void M(T x); + + void M(int x) + { + } + } + + public interface IB : IA + { + void IA.M(T x) + { + Console.Write("InIB"); + } + + T IA.Prop2 + { + set + { + Console.Write("IB.Prop2Set"); + } + } + } + + public interface IC : IA + { + void IA.M(string x) + { + Console.Write("InIC"); + } + + string IA.Prop2 + { + set + { + Console.Write("IC.Prop2Set"); + } + } + + void M_C() + { + } + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IB + interface IC + interface IA with + + member _.M(_x: string) = Console.Write("Test.String") + + member _.Prop2 with set _ = Console.Write("Test.Prop2") + +[] +let main _ = + let test = Test () :> IC + test.M("") + Console.Write("-") + test.Prop2 <- "" + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "Test.String-Test.Prop2") + + [] + let ``C# diamond inheritance with overloading and generics and properties - Errors with no specific implementation`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + T Prop1 { get { return default(T); } } + + T Prop2 { set; } + + T Prop3 { get { return default(T); } set { } } + + void M(T x); + + void M(int x) + { + } + } + + public interface IB : IA + { + void IA.M(T x) + { + Console.Write("InIB"); + } + + T IA.Prop2 + { + set + { + Console.Write("IB.Prop2Set"); + } + } + } + + public interface IC : IA + { + void IA.M(string x) + { + Console.Write("InIC"); + } + + string IA.Prop2 + { + set + { + Console.Write("IC.Prop2Set"); + } + } + + void M_C() + { + } + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open CSharpTest + +open System + +type Test () = + + interface IB + interface IC + interface IA with + + member _.M(_x: string) = Console.Write("Test.String") + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3352, (12, 15, 12, 25), "Interface member 'IA.set_Prop2(value: string) : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (12, 15, 12, 25), "No implementation was given for 'IA.set_Prop2(value: string) : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple diamond inheritance using object expression - Errors with no specific implementation`` () = + let csharpSource = + """ +namespace CSharpTest +{ + public interface IA + { + void M(); + } + + public interface IB : IA + { + void IA.M() + { + } + } + + public interface IC : IA + { + void IA.M() + { + } + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open CSharpTest + +let test = + { new IB + interface IC } + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 363, (8, 7, 8, 21), "The interface 'IA' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface.") + (FSharpDiagnosticSeverity.Error, 3352, (7, 5, 8, 21), "Interface member 'IA.M() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (7, 5, 8, 21), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + (FSharpDiagnosticSeverity.Error, 3352, (8, 7, 8, 21), "Interface member 'IA.M() : unit' does not have a most specific implementation.") + (FSharpDiagnosticSeverity.Error, 366, (8, 7, 8, 21), "No implementation was given for 'IA.M() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# diamond inheritance with no most specific problem - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M() + { + } + } + + public interface IB : IA + { + void IA.M() + { + Console.Write("IB.IA.M"); + } + } + + public interface IC : IA + { + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IA + interface IC + interface IB + +[] +let main _ = + let test = Test () :> IC + test.M(); + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "IB.IA.M") + + [] + let ``C# diamond inheritance with no most specific problem - Runs - 2`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface IA + { + void M() + { + } + } + + public interface IB : IA + { + void IA.M() + { + Console.Write("IB.IA.M"); + } + } + + public interface IC : IA + { + } +} + """ + + let fsharpSource = + """ +open CSharpTest + +open System + +type Test () = + + interface IC + interface IB + +[] +let main _ = + let test = Test () :> IC + test.M(); + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "IB.IA.M") + + [] + let ``C# with interface statics - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type I3 = + inherit I2 + +let f () = + I1.StaticMethod (1, 2) |> ignore + + // Even though I1 declares statics, it can be called by qualifying I2 or I3(declared in F#). + I2.StaticMethod (1, 2) |> ignore + I2.StaticProperty <- 5 + let _value = I2.StaticProperty + I2.StaticField <- 5 + let _value = I2.StaticField + () + I3.StaticMethod (1, 2) |> ignore + I3.StaticProperty <- 5 + I2.StaticProperty + let _value = I3.StaticProperty + I3.StaticField <- 6 + I2.StaticField + let _value = I3.StaticField + + Console.Write I2.StaticProperty + Console.Write I3.StaticField + +f () + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "1011") + + [] + let ``C# interface statics and F# SRTP (statically resolved type parameters) - Runs`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type I3 = + inherit I2 + +let inline callStatic< ^T when ^T : (static member StaticMethod : int * int -> int)> x y = + let value = ( ^T : (static member StaticMethod : int * int -> int) (x, y)) + Console.Write value + +let f1 () = + callStatic 1 2 + +let f2 () = + callStatic 2 3 + +let f3 () = + callStatic 4 5 + +f1 () +f2 () +f3 () + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "359") + + [] + let ``C# interface statics - Errors with method not defined on C# class`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} + + public class CSharpClass : I2 { } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +let f () = + CSharpClass.StaticMethod(1, 2) + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 39, (6, 17, 6, 29), "The type 'CSharpClass' does not define the field, constructor or member 'StaticMethod'.") + |]) + + [] + let ``C# interface statics - Errors with method not defined on F# class`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type FSharpClass() = + + interface I1 + interface I2 + +let f () = + FSharpClass.StaticMethod(1, 2) + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 39, (11, 17, 11, 29), "The type 'FSharpClass' does not define the field, constructor or member 'StaticMethod'.") + |]) + + [] + let ``C# interface statics - Errors with method not defined on C# class using SRTP`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} + + public class CSharpClass : I2 { } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +let inline callStatic< ^T when ^T : (static member StaticMethod : int * int -> int)> x y = + ( ^T : (static member StaticMethod : int * int -> int) (x, y)) + +let f () = + callStatic 1 2 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 1, (9, 5, 9, 15), "The type 'CSharpClass' does not support the operator 'StaticMethod'") + |]) + + [] + let ``C# interface statics - Errors with method not defined on F# class using SRTP`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(int x, int y) + { + return x + y; + } + + public static int StaticProperty { get; set; } + + public static int StaticField; + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +type FSharpClass() = + + interface I1 + interface I2 + +let inline callStatic< ^T when ^T : (static member StaticMethod : int * int -> int)> x y = + ( ^T : (static member StaticMethod : int * int -> int) (x, y)) + +let f () = + callStatic 1 2 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fsx, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 1, (14, 5, 14, 15), "The type 'FSharpClass' does not support the operator 'StaticMethod'") + |]) + +#else + +[] +module DefaultInterfaceMemberConsumptionTests_net472 = + + [] + let targetVersion = "5.0" + + [] + let ``IL - Errors with target runtime not supported`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class interface public abstract auto ansi ILTest.ITest +{ + .method public hidebysig newslot virtual instance void DefaultMethod() cil managed + { + .maxstack 8 + IL_0000: ret + } +} + """ + + let fsharpSource = + """ +namespace FSharpTest + +open ILTest + +type Test () = + + interface ITest + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [ilCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3351, (8, 15, 8, 20), "Feature 'default interface member consumption' is not supported by target runtime.") + (FSharpDiagnosticSeverity.Error, 3350, (8, 15, 8, 20), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (FSharpDiagnosticSeverity.Error, 366, (8, 15, 8, 20), "No implementation was given for 'ITest.DefaultMethod() : unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.") + |]) + + [] + let ``C# simple with static method - Errors with target runtime not supported`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface I1 + { + public static int StaticMethod(I1 x, I1 y) + { + Console.Write("I1.+"); + return 1; + } + } + + public interface I2 : I1 + {} +} + """ + + let fsharpSource = + """ +module FSharpTest + +open System +open CSharpTest + +type Test () = + + interface I2 + +let f () = + let x = Test () :> I1 + let y = Test () :> I2 + I1.StaticMethod (x, y) + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:4.6"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 3351, (14, 5, 14, 27), "Feature 'default interface member consumption' is not supported by target runtime.") + (FSharpDiagnosticSeverity.Error, 3350, (14, 5, 14, 27), "Feature 'default interface member consumption' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + |]) + +#endif diff --git a/tests/fsharp/Compiler/Language/FixedIndexSliceTests.fs b/tests/fsharp/Compiler/Language/FixedIndexSliceTests.fs index 56b47334a40..344c5178b18 100644 --- a/tests/fsharp/Compiler/Language/FixedIndexSliceTests.fs +++ b/tests/fsharp/Compiler/Language/FixedIndexSliceTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module FixedIndexSliceTests = @@ -21,12 +22,12 @@ arr3.[*, 1, *] arr3.[*, 1, 1] """ [| - FSharpErrorSeverity.Error, 39, (5,1,5,15), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (6,1,6,15), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (7,1,7,15), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (8,1,8,15), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (9,1,9,15), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (10,1,10,15), "The field, constructor or member 'GetSlice' is not defined." + FSharpDiagnosticSeverity.Error, 39, (5,1,5,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (6,1,6,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (7,1,7,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (8,1,8,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (9,1,9,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (10,1,10,15), "The type '[,,]<_>' does not define the field, constructor or member 'GetSlice'." |] [] @@ -51,19 +52,19 @@ arr4.[1, 1, 1, *] arr4.[*, 1, 1, 1] """ [| - FSharpErrorSeverity.Error, 39, (5,1,5,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (6,1,6,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (7,1,7,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (8,1,8,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (9,1,9,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (10,1,10,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (11,1,11,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (12,1,12,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (13,1,13,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (14,1,14,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (15,1,15,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (16,1,16,18), "The field, constructor or member 'GetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (17,1,17,18), "The field, constructor or member 'GetSlice' is not defined." + FSharpDiagnosticSeverity.Error, 39, (5,1,5,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (6,1,6,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (7,1,7,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (8,1,8,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (9,1,9,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (10,1,10,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (11,1,11,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (12,1,12,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (13,1,13,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (14,1,14,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (15,1,15,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (16,1,16,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." + FSharpDiagnosticSeverity.Error, 39, (17,1,17,18), "The type '[,,,]<_>' does not define the field, constructor or member 'GetSlice'." |] [] @@ -83,12 +84,12 @@ arr3.[*, 1, *] <- arr1 arr3.[*, 1, 1] <- arr1 """ [| - FSharpErrorSeverity.Error, 39, (7,1,7,15), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (8,1,8,15), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (9,1,9,15), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (10,1,10,15), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (11,1,11,15), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (12,1,12,15), "The field, constructor or member 'SetSlice' is not defined." + FSharpDiagnosticSeverity.Error, 39, (7,1,7,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (8,1,8,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (9,1,9,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (10,1,10,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (11,1,11,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (12,1,12,15), "The type '[,,]<_>' does not define the field, constructor or member 'SetSlice'." |] [] @@ -117,23 +118,18 @@ arr4.[1, 1, 1, *] <- arr1 arr4.[*, 1, 1, 1] <- arr1 """ [| - FSharpErrorSeverity.Error, 39, (8,1,8,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (9,1,9,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (10,1,10,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (11,1,11,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (12,1,12,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (13,1,13,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (14,1,14,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (15,1,15,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (16,1,16,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (17,1,17,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (18,1,18,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (19,1,19,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (20,1,20,18), "The field, constructor or member 'SetSlice' is not defined." - FSharpErrorSeverity.Error, 39, (21,1,21,18), "The field, constructor or member 'SetSlice' is not defined." + FSharpDiagnosticSeverity.Error, 39, (8,1,8,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (9,1,9,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (10,1,10,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (11,1,11,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (12,1,12,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (13,1,13,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (14,1,14,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (15,1,15,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (16,1,16,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (17,1,17,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (18,1,18,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (19,1,19,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (20,1,20,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." + FSharpDiagnosticSeverity.Error, 39, (21,1,21,18), "The type '[,,,]<_>' does not define the field, constructor or member 'SetSlice'." |] - - - - - diff --git a/tests/fsharp/Compiler/Language/HatDesugaringTests.fs b/tests/fsharp/Compiler/Language/HatDesugaringTests.fs index 5d04d65250d..73bad5cee68 100644 --- a/tests/fsharp/Compiler/Language/HatDesugaringTests.fs +++ b/tests/fsharp/Compiler/Language/HatDesugaringTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module HatDesugaringTests = @@ -27,7 +28,7 @@ module X open System let (^) (x: int) (y: int) = x + y -let result = [1;2].[^1..] +let result = [1;2][^1..] if result <> [1;2] then failwithf "expected result to be [1;2] but got %A" result Console.WriteLine() """ @@ -35,85 +36,81 @@ Console.WriteLine() [] let ``At operator should not be usable in prefix context``() = CompilerAssert.ParseWithErrors - """ + (""" module X let x = @1 - """ + """, langVersion="preview") [| - FSharpErrorSeverity.Error, 10, (4,9,4,10), "Unexpected infix operator in binding" + FSharpDiagnosticSeverity.Error, 1208, (4,9,4,10), "Invalid prefix operator" |] [] - let ``Hat operator should not be overloadable in prefix context``() = + let ``Hat operator should not be overloadable as prefix operator``() = CompilerAssert.ParseWithErrors """ module X open System let (~^) (x: int) (y:int) = x + y - -Console.WriteLine(^1) """ [| - FSharpErrorSeverity.Error, 1208, (5,6,5,8), "Invalid operator definition. Prefix operator definitions must use a valid prefix operator name."; - FSharpErrorSeverity.Error, 10, (7,20,7,21), "Unexpected integer literal in expression. Expected ')' or other token."; - FSharpErrorSeverity.Error, 583, (7,18,7,19), "Unmatched '('"; + FSharpDiagnosticSeverity.Error, 1208, (5,6,5,8), "Invalid operator definition. Prefix operator definitions must use a valid prefix operator name."; |] [] let ``Reverse slicing should not work with at symbol in 1st slice index``() = CompilerAssert.ParseWithErrors - """ + (""" module X open System let list = [1;2;3] -Console.WriteLine(list.[@1..]) - """ +Console.WriteLine(list[@1..]) + """, langVersion="preview") [| - FSharpErrorSeverity.Error, 1208, (6,25,6,26), "Invalid prefix operator" + FSharpDiagnosticSeverity.Error, 1208, (6,24,6,25), "Invalid prefix operator" |] [] let ``Reverse slicing should not work with at symbol in 2nd slice index``() = CompilerAssert.ParseWithErrors - """ + (""" module X open System let list = [1;2;3] -Console.WriteLine(list.[..@1]) - """ +Console.WriteLine(list[..@1]) + """, langVersion="preview") [| - FSharpErrorSeverity.Error, 1208, (6,25,6,28), "Invalid prefix operator" + FSharpDiagnosticSeverity.Error, 1208, (6,24,6,27), "Invalid prefix operator" |] [] let ``Reverse slicing should not work with at symbol in both slice index``() = CompilerAssert.ParseWithErrors - """ + (""" module X open System let list = [1;2;3] -Console.WriteLine(list.[@1..@1]) - """ +Console.WriteLine(list[@1..@1]) + """, langVersion="preview") [| - FSharpErrorSeverity.Error, 1208, (6,25,6,26), "Invalid prefix operator"; - FSharpErrorSeverity.Error, 1208, (6,29,6,30), "Invalid prefix operator" + FSharpDiagnosticSeverity.Error, 1208, (6,24,6,25), "Invalid prefix operator"; + FSharpDiagnosticSeverity.Error, 1208, (6,28,6,29), "Invalid prefix operator" |] [] let ``Reverse indexing should not work with at symbol``() = CompilerAssert.ParseWithErrors - """ + (""" module X open System let list = [1;2;3] -Console.WriteLine(list.[@11]) - """ +Console.WriteLine(list[@11]) + """, langVersion="preview") [| - FSharpErrorSeverity.Error, 1208, (6,25,6,26), "Invalid prefix operator" + FSharpDiagnosticSeverity.Error, 1208, (6,24,6,25), "Invalid prefix operator" |] diff --git a/tests/fsharp/Compiler/Language/InitOnlyPropertyConsumptionTests.fs b/tests/fsharp/Compiler/Language/InitOnlyPropertyConsumptionTests.fs new file mode 100644 index 00000000000..56d828f8a78 --- /dev/null +++ b/tests/fsharp/Compiler/Language/InitOnlyPropertyConsumptionTests.fs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Test.Utilities + +#if NETCOREAPP + +[] +module InitOnlyPropertyConsumptionTests = + + [] + let ``Should be able to set an init-only property from a C# record`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public record Test + { + public int X { get; init; } + } +} + """ + + let fsharpSource = + """ +open System +open System.Runtime.CompilerServices +open CSharpTest + +let test() = + Test(X = 123) + +[] +let main _ = + let x = test() + Console.Write(x.X) + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp9, TargetFramework.Current) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "123") + +#endif + diff --git a/tests/fsharp/Compiler/Language/InterfaceTests.fs b/tests/fsharp/Compiler/Language/InterfaceTests.fs new file mode 100644 index 00000000000..231ab11248a --- /dev/null +++ b/tests/fsharp/Compiler/Language/InterfaceTests.fs @@ -0,0 +1,255 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open FSharp.Compiler.Diagnostics +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities + +[] +module InterfaceTests = + + [] + let ShouldnWork() = + CompilerAssert.Pass """ +type IGet<'T> = + abstract member Get : unit -> 'T + +type GetTuple() = + interface IGet with + member x.Get() = 1, 2 + +type GetFunction() = + interface IGetint> with + member x.Get() = fun () -> 1 + +type GetAnonymousRecord() = + interface IGet<{| X : int |}> with + member x.Get() = {| X = 1 |} + +type GetNativePtr() = + interface IGet> with + member x.Get() = failwith "not implemented" + +type TUnion = A | B of int + +type GetUnion() = + interface IGet with + member x.Get() = B 2 + +exit 0 +""" + + let ``C# base with dim`` = """ +using System; + +namespace CSharpTest +{ + public interface ITestDim + { + int GetIt(int x) { return x; } + } +} +""" + + let ``Many Instantiations of the same interface - SetUp`` = """ +module Program + +open System +#if TEST_DIMS +open CSharpTest +#endif + +type AnEnum = + | One + | Two + +[] +type AStructRecord = { Forename:string; Surname:string } + +type AClass = + val value: int + + new(value) = { value = value } + +type IInterface<'a> = + abstract GetIt: 'a -> 'a + +type implementation () = +// DIMs only available on netcoreapp 3 +#if TEST_DIMS + interface ITestDim +#endif + interface IInterface with member _.GetIt(x) = x // bool + interface IInterface with member _.GetIt(x) = x // byte + interface IInterface with member _.GetIt(x) = x // byte array + interface IInterface with member _.GetIt(x) = x // sbyte + interface IInterface with member _.GetIt(x) = x // int 16 + interface IInterface with member _.GetIt(x) = x // uint16 + interface IInterface with member _.GetIt(x) = x // int + interface IInterface with member _.GetIt(x) = x // uint32 + interface IInterface with member _.GetIt(x) = x // int64 + interface IInterface with member _.GetIt(x) = x // uint64 + interface IInterface with member _.GetIt(x) = x // nativeint + interface IInterface with member _.GetIt(x) = x // unativeint + interface IInterface with member _.GetIt(x) = x // char + interface IInterface with member _.GetIt(x) = x // string + interface IInterface with member _.GetIt(x) = x // single + interface IInterface with member _.GetIt(x) = x // double + interface IInterface with member _.GetIt(x) = x // decimal + interface IInterface with member _.GetIt(x) = x // bigint + interface IInterface with member _.GetIt(x) = x // struct tuple + interface IInterface with member _.GetIt(x) = x // enum + interface IInterface> with member _.GetIt(x) = x // struct union + interface IInterface with member _.GetIt(x) = x // struct record + // Anonymous records are non-deterministic So don't include for il comparison +#if !NO_ANONYMOUS + interface IInterface with member _.GetIt(x) = x // Anonymous record +#endif + interface IInterface int> with member _.GetIt(x) = x // func + interface IInterface float> with member _.GetIt(x) = x // func +""" + + let ``Many Instantiations of the same interface - Asserts`` = """ +let x = implementation () +let assertion v assertIt = + if not (assertIt(v)) then + raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) + +let assertionRecord v assertIt = + if not (assertIt(v)) then + raise (new Exception (sprintf "Failed to retrieve %A from implementation" v)) + +// Ensure we can invoke the method and get the value back for each native F# type +#if TEST_DIMS +assertion 7 (fun v -> (x :> ITestDim).GetIt(v) = v) +#endif + +assertion true (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 1uy (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 2y (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 3s (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 4us (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 5l (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 6ul (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 7n (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 8un (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 9L (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 10UL (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 12.12 (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 13I (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 14M (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 'A' (fun v -> (x :> IInterface).GetIt(v) = v) +assertion 'a'B (fun v -> (x :> IInterface).GetIt(v) = v) +assertion "16"B (fun v -> (x :> IInterface).GetIt(v) = v) +assertion AnEnum.Two (fun v -> (x :> IInterface).GetIt(v) = v) +assertion (ValueSome "7") (fun v -> (x :> IInterface>).GetIt(v) = v) +assertion struct (1,2) (fun v -> (x :> IInterface).GetIt(v) = v) +assertion { Forename="Forename"; Surname="Surname" } (fun v -> (x :> IInterface).GetIt(v) = v) +#if !NO_ANONYMOUS // Anonymous records are non-deterministic So don't include for il comparison +assertion struct {|First=2; Second=3 |} (fun (v:struct {|First:int; Second:int|}) -> (x :> IInterface).GetIt(v) = v) +#endif +assertion (fun x -> x * 2) (fun v -> + let f = (x :> IInterface int>).GetIt(v) + f(7) = 14) +assertion (fun (x:float) -> x * 3.0) (fun v -> + let f = (x :> IInterface float>).GetIt(v) + f(2.0) = 6.0) +""" + + let ``Many Instantiations of the same interface`` = + ``Many Instantiations of the same interface - SetUp`` + ``Many Instantiations of the same interface - Asserts`` + + + [] + let MultipleTypedInterfacesFSharp50() = + +#if NETSTANDARD + let csCmpl = + CompilationUtil.CreateCSharpCompilation(``C# base with dim``, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create +#endif + + let fsCmpl = + Compilation.Create( + ``Many Instantiations of the same interface - SetUp`` + + ``Many Instantiations of the same interface - Asserts``, + Fs, Library, + options = [| + "--langversion:5.0"; +#if !NETSTANDARD + |]) +#else + "--define:NETSTANDARD"; + "--define:TEST_DIMS"; + |], + cmplRefs = [csCmpl]) +#endif + + CompilerAssert.Compile fsCmpl + + [] + let MultipleTypedInterfacesFSharp47() = + CompilerAssert.TypeCheckWithErrorsAndOptions + [| + "--langversion:4.7"; +#if NETSTANDARD + "--define:NETSTANDARD"; +#endif + |] + ``Many Instantiations of the same interface`` + [| + (FSharpDiagnosticSeverity.Error, 3350, (24, 6, 24, 20), "Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater.") + |] + + [] + let MultipleTypedInterfacesFSharp50VerifyIl() = + CompilerAssert.CompileLibraryAndVerifyILWithOptions + [| + "--langversion:5.0"; + "--deterministic+"; + "--define:NO_ANONYMOUS"; +#if NETSTANDARD + "--define:NETSTANDARD"; +#endif + |] + ``Many Instantiations of the same interface - SetUp`` + (fun verifier -> verifier.VerifyIL [""" +.class auto ansi serializable nested public implementation + extends [mscorlib]System.Object + implements class Program/IInterface`1>, + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1>, + class Program/IInterface`1,""" + +#if NETSTANDARD + """ + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1,""" + +#else + """ + class Program/IInterface`1>, + class Program/IInterface`1, + class Program/IInterface`1,""" + +#endif + """ + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1, + class Program/IInterface`1 +{ +"""] ) diff --git a/tests/fsharp/Compiler/Language/OpenStaticClasses.fs b/tests/fsharp/Compiler/Language/OpenStaticClasses.fs deleted file mode 100644 index f4f955b0d5f..00000000000 --- a/tests/fsharp/Compiler/Language/OpenStaticClasses.fs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace FSharp.Compiler.UnitTests - -open FSharp.Compiler.SourceCodeServices -open NUnit.Framework - - -(* - Tests in this file evaluate whether the language supports accessing functions on static classes using open - The feature was added in preview, the test cases ensure that the original errors are reproduced when the langversion:4.6 is specified -*) - -[] -module OpenStaticClassesTests = - - let baseModule = """ -module Core_OpenStaticClasses - -[] -type MyMath() = - static member Min(a: double, b: double) = System.Math.Min(a, b) - static member Min(a: int, b: int) = System.Math.Min(a, b) - -[] -type AutoOpenMyMath() = - static member AutoMin(a: double, b: double) = System.Math.Min(a, b) - static member AutoMin(a: int, b: int) = System.Math.Min(a, b) - -[] -type NotAllowedToOpen() = - static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b) - static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b) - -""" - - [] - let ``OpenStaticClassesTests - OpenSystemMathOnce - langversion:v4.6`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - (baseModule + """ -module OpenSystemMathOnce = - - open System.Math - let x = Min(1.0, 2.0)""") - [| - (FSharpErrorSeverity.Error, 39, (22,28,22,32), "The namespace 'Math' is not defined."); - (FSharpErrorSeverity.Error, 39, (23,24,23,27), "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") - |] - - [] - let ``OpenStaticClassesTests - OpenSystemMathOnce - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module OpenSystemMathOnce = - - open System.Math - let x = Min(1.0, 2.0)""") - [| |] - - [] - let ``OpenStaticClassesTests - OpenSystemMathTwice - langversion:v4.6`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - (baseModule + """ -module OpenSystemMathTwice = - - open System.Math - let x = Min(1.0, 2.0) - - open System.Math - let x2 = Min(2.0, 1.0)""") - [| - (FSharpErrorSeverity.Error, 39, (22,17,22,21), "The namespace 'Math' is not defined."); - (FSharpErrorSeverity.Error, 39, (23,13,23,16), "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") - (FSharpErrorSeverity.Error, 39, (25,17,25,21), "The namespace 'Math' is not defined."); - (FSharpErrorSeverity.Error, 39, (26,14,26,17), "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") - |] - - [] - let ``OpenStaticClassesTests - OpenSystemMathTwice - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module OpenSystemMathOnce = - - open System.Math - let x = Min(1.0, 2.0)""") - [| |] - - [] - let ``OpenStaticClassesTests - OpenMyMathOnce - langversion:v4.6`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - (baseModule + """ -module OpenMyMathOnce = - - open MyMath - let x = Min(1.0, 2.0) - let x2 = Min(1, 2)""") - [| - (FSharpErrorSeverity.Error, 39, (22,10,22,16), "The namespace or module 'MyMath' is not defined. Maybe you want one of the following:\r\n Math"); - (FSharpErrorSeverity.Error, 39, (23,13,23,16), "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") - (FSharpErrorSeverity.Error, 39, (24,14,24,17), "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") - |] - - [] - let ``OpenStaticClassesTests - OpenMyMathOnce - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module OpenMyMathOnce = - - open MyMath - let x = Min(1.0, 2.0) - let x2 = Min(1, 2)""") - [| |] - - [] - let ``OpenStaticClassesTests - DontOpenAutoMath - langversion:v4.6`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - (baseModule + """ -module DontOpenAutoMath = - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2)""") - [| - (FSharpErrorSeverity.Error, 39, (22,13,22,20), "The value or constructor 'AutoMin' is not defined."); - (FSharpErrorSeverity.Error, 39, (23,14,23,21), "The value or constructor 'AutoMin' is not defined.") - |] - - [] - let ``OpenStaticClassesTests - DontOpenAutoMath - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module DontOpenAutoMath = - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2)""") - [| |] - - [] - let ``OpenStaticClassesTests - OpenAutoMath - langversion:v4.6`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:4.6" |] - (baseModule + """ -module OpenAutoMath = - open AutoOpenMyMath - //open NotAllowedToOpen - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2)""") - [| - (FSharpErrorSeverity.Error, 39, (21,10,21,24), "The namespace or module 'AutoOpenMyMath' is not defined."); - (FSharpErrorSeverity.Error, 39, (24,13,24,20), "The value or constructor 'AutoMin' is not defined.") - (FSharpErrorSeverity.Error, 39, (25,14,25,21), "The value or constructor 'AutoMin' is not defined.") - |] - - [] - let ``OpenStaticClassesTests - OpenAutoMath - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module OpenAutoMath = - open AutoOpenMyMath - //open NotAllowedToOpen - - let x = AutoMin(1.0, 2.0) - let x2 = AutoMin(1, 2)""") - [| |] - - [] - let ``OpenStaticClassesTests - OpenAccessibleFields - langversion:preview`` () = - CompilerAssert.TypeCheckWithErrorsAndOptions - [| "--langversion:preview" |] - (baseModule + """ -module OpenAFieldFromMath = - open System.Math - - let pi = PI""") - [||] - - // TODO - wait for Will's integration of testing changes that makes this easlier - // [] - // let ``OpenStaticClassesTests - InternalsVisibleWhenHavingAnIVT - langversion:preview``() = ... \ No newline at end of file diff --git a/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs b/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs new file mode 100644 index 00000000000..7d04809e436 --- /dev/null +++ b/tests/fsharp/Compiler/Language/OpenTypeDeclarationTests.fs @@ -0,0 +1,2460 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open FSharp.Compiler.Diagnostics +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler + +[] +module OpenTypeDeclarationTests = + + [] + let targetVersion = "5.0" + + let baseModule = """ +module Core_OpenStaticClasses + +[] +type MyMath() = + static member Min(a: double, b: double) = System.Math.Min(a, b) + static member Min(a: int, b: int) = System.Math.Min(a, b) + +[] +type AutoOpenMyMath() = + static member AutoMin(a: double, b: double) = System.Math.Min(a, b) + static member AutoMin(a: int, b: int) = System.Math.Min(a, b) + +[] +type NotAllowedToOpen() = + static member QualifiedMin(a: double, b: double) = System.Math.Min(a, b) + static member QualifiedMin(a: int, b: int) = System.Math.Min(a, b) + +""" + + [] + let ``OpenSystemMathOnce - langversion:4.6`` () = + Fsx (baseModule + """ +module OpenSystemMathOnce = + + open type System.Math + let x = Min(1.0, 2.0)""") + |> withLangVersion46 + |> typecheck + |> withDiagnostics + [ + (Error 3350, Line 22, Col 16, Line 22, Col 37, "Feature 'open type declaration' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (Error 39, Line 23, Col 24, Line 23, Col 27, "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") + ] + |> ignore + + [] + let ``OpenSystemMathOnce - langversion:5.0`` () = + Fsx (baseModule + """ +module OpenSystemMathOnce = + + open type System.Math + let x = Min(1.0, 2.0)""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``OpenSystemMathTwice - langversion:4.6`` () = + Fsx (baseModule + """ +module OpenSystemMathTwice = + + open type System.Math + let x = Min(1.0, 2.0) + + open type System.Math + let x2 = Min(2.0, 1.0)""") + |> withLangVersion46 + |> typecheck + |> withDiagnostics + [ + (Error 3350, Line 22, Col 5, Line 22, Col 26, "Feature 'open type declaration' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (Error 39, Line 23, Col 13, Line 23, Col 16, "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") + (Error 3350, Line 25, Col 5, Line 25, Col 26, "Feature 'open type declaration' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (Error 39, Line 26, Col 14, Line 26, Col 17, "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") + ] + |> ignore + + [] + let ``OpenSystemMathTwice - langversion:50`` () = + Fsx (baseModule + """ +module OpenSystemMathOnce = + + open type System.Math + let x = Min(1.0, 2.0)""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``OpenMyMathOnce - langversion:4.6`` () = + Fsx (baseModule + """ +module OpenMyMathOnce = + + open type MyMath + let x = Min(1.0, 2.0) + let x2 = Min(1, 2)""") + |> withLangVersion46 + |> typecheck + |> withDiagnostics + [ + (Error 3350, Line 22, Col 5, Line 22, Col 21, "Feature 'open type declaration' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (Error 39, Line 23, Col 13, Line 23, Col 16, "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") + (Error 39, Line 24, Col 14, Line 24, Col 17, "The value or constructor 'Min' is not defined. Maybe you want one of the following:\r\n min\r\n sin") + ] + |> ignore + + [] + let ``OpenMyMathOnce - langversion:5.0`` () = + Fsx (baseModule + """ +module OpenMyMathOnce = + + open type MyMath + let x = Min(1.0, 2.0) + let x2 = Min(1, 2)""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``DontOpenAutoMath - langversion:4.6`` () = + Fsx (baseModule + """ +module DontOpenAutoMath = + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2)""") + |> withLangVersion46 + |> typecheck + |> withDiagnostics + [ + (Error 39, Line 22, Col 13, Line 22, Col 20, "The value or constructor 'AutoMin' is not defined.") + (Error 39, Line 23, Col 14, Line 23, Col 21, "The value or constructor 'AutoMin' is not defined.") + ] + |> ignore + + [] + let ``DontOpenAutoMath - langversion:5.0`` () = + Fsx (baseModule + """ +module DontOpenAutoMath = + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2)""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``OpenAutoMath - langversion:4.6`` () = + Fsx (baseModule + """ +module OpenAutoMath = + open type AutoOpenMyMath + //open type NotAllowedToOpen + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2)""") + |> withLangVersion46 + |> typecheck + |> withDiagnostics + [ + (Error 3350, Line 21, Col 5, Line 21, Col 29, "Feature 'open type declaration' is not available in F# 4.6. Please use language version " + targetVersion + " or greater.") + (Error 39, Line 24, Col 13, Line 24, Col 20, "The value or constructor 'AutoMin' is not defined.") + (Error 39, Line 25, Col 14, Line 25, Col 21, "The value or constructor 'AutoMin' is not defined.") + ] + |> ignore + + [] + let ``OpenAutoMath - langversion:5.0`` () = + Fsx (baseModule + """ +module OpenAutoMath = + open type AutoOpenMyMath + //open type NotAllowedToOpen + + let x = AutoMin(1.0, 2.0) + let x2 = AutoMin(1, 2)""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``OpenAccessibleFields - langversion:5.0`` () = + Fsx (baseModule + """ +module OpenAFieldFromMath = + open type System.Math + + let pi = PI""") + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Open type and use nested types as unqualified`` () = + let csharp = + CSharp """ +using System; + +namespace CSharpTest +{ + public static class Test + { + public class NestedTest + { + public void A() + { + } + } + + public class NestedTest + { + public void B() + { + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open type CSharpTest.Test + +module Test = + let x = NestedTest() + let y = NestedTest() + let a = x.A() + let b = y.B()""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open a type where the type declaration uses a type abbreviation as a qualifier to a real nested type`` () = + let csharp = + CSharp """ +using System; + +namespace CSharpTest +{ + public static class Test + { + public class NestedTest + { + public void A() + { + } + } + + public class NestedTest + { + public void B() + { + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open System +type Abbrev = CSharpTest.Test +open type Abbrev.NestedTest""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open a type where the type declaration uses a type abbreviation`` () = + let csharp = + CSharp """ +using System; + +namespace CSharpTest +{ + public static class Test + { + public class NestedTest + { + public void A() + { + } + } + + public class NestedTest + { + public void B() + { + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open System +type Abbrev = CSharpTest.Test +open type Abbrev""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open a nested type as qualified`` () = + let csharp = + CSharp """ +using System; + +namespace CSharpTest +{ + public static class Test + { + public class NestedTest + { + public static void A() + { + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open System +open type CSharpTest.Test.NestedTest + +module Test = + let x = A()""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic type and use nested types as unqualified`` () = + let csharp = + CSharp """ +namespace CSharpTest +{ + public class Test + { + public class NestedTest + { + public T B() + { + return default(T); + } + } + + public class NestedTest + { + public T A() + { + return default(T); + } + } + } + + public class Test + { + } +}""" + + FSharp """ +namespace FSharpTest + +open System + +module Test = + + let x : CSharpTest.Test.NestedTest = CSharpTest.Test.NestedTest() + let y : CSharpTest.Test.NestedTest = CSharpTest.Test.NestedTest() + + let t1 = CSharpTest.Test() + + let t2 = CSharpTest.Test() + +open type CSharpTest.Test + +module Test2 = + + let x = NestedTest() + let xb : byte = x.B() + + let y = NestedTest() + let ya : byte = y.A() + + let x1 = new NestedTest() + let x1b : byte = x1.B() + + let y1 = new NestedTest() + let y1a : byte = y1.A() + + let x2 : NestedTest = new NestedTest() + let x2b : byte = x2.B() + + let y2 : NestedTest = new NestedTest() + let y2a : byte = y2.A()""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic type and use nested types as unqualified 2`` () = + FSharp """ +namespace FSharpTest + +open type System.Collections.Generic.List + +module Test = + let e2 = new Enumerator()""" + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic type and use nested types as unqualified 3`` () = + let csharp = + CSharp """ +namespace CSharpTest +{ + public class Test + { + public class NestedTest + { + public class NestedNestedTest + { + public T A() + { + return default(T); + } + } + + public class NestedNestedTest + { + public U B() + { + return default(U); + } + } + } + + public class NestedTest + { + public class NestedNestedTest + { + public U C() + { + return default(U); + } + } + + public class NestedNestedTest + { + public R D() + { + return default(R); + } + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open System + +module Test = + + let a : CSharpTest.Test.NestedTest = CSharpTest.Test.NestedTest() + let b : CSharpTest.Test.NestedTest = CSharpTest.Test.NestedTest() + + let c : CSharpTest.Test.NestedTest.NestedNestedTest = CSharpTest.Test.NestedTest.NestedNestedTest() + let d : CSharpTest.Test.NestedTest.NestedNestedTest = CSharpTest.Test.NestedTest.NestedNestedTest() + + let e : CSharpTest.Test.NestedTest.NestedNestedTest = CSharpTest.Test.NestedTest.NestedNestedTest() + let f : CSharpTest.Test.NestedTest.NestedNestedTest = CSharpTest.Test.NestedTest.NestedNestedTest() + +open type CSharpTest.Test + +module Test2 = + + let a : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + let aa : byte = a.A() + + let b : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + let bb : float = b.B() + + let c : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + let cc : float = c.C() + + let d : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + let dd : int = d.D() + +open type NestedTest + +module Test3 = + + let a : NestedNestedTest = NestedNestedTest() + let aa : byte = a.A() + + let b : NestedNestedTest = NestedNestedTest() + let bb : float = b.B() + +open type NestedTest + +module Test4 = + + let c : NestedNestedTest = NestedNestedTest() + let cc : float = c.C() + + let d : NestedNestedTest = NestedNestedTest() + let dd : int = d.D()""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic type and use nested types as unqualified 4`` () = + let csharp = + CSharp """ +namespace CSharpTest +{ + public class Test + { + public class NestedTest + { + public class NestedNestedTest + { + public T7 A() + { + return default(T7); + } + } + + public class NestedNestedTest + { + public T8 B() + { + return default(T8); + } + } + + public class NestedNestedTest + { + public T9 C() + { + return default(T9); + } + } + } + } +}""" + + FSharp """ +namespace FSharpTest + +open System +open CSharpTest + +open type Test.NestedTest + +module Test = + + let aa : NestedNestedTest = NestedNestedTest() + + let bb : NestedNestedTest = NestedNestedTest() + + let cc : NestedNestedTest = NestedNestedTest() + + let r1 : string = aa.A() + + let r2 : int list = bb.B() + + let r3 : float list = cc.C() + +open type Test + +module Test2 = + + let a : NestedTest = NestedTest() + + let aa : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + + let bb : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + + let cc : NestedTest.NestedNestedTest = NestedTest.NestedNestedTest() + + let r1 : uint32 = aa.A() + + let r2 : int [] = bb.B() + + let r3 : float [] = cc.C() + +module Test3 = + + let a : Test.NestedTest = Test.NestedTest() + + let aa : Test.NestedTest.NestedNestedTest = Test.NestedTest.NestedNestedTest() + + let bb : Test.NestedTest.NestedNestedTest = Test.NestedTest.NestedNestedTest() + + let cc : Test.NestedTest.NestedNestedTest = Test.NestedTest.NestedNestedTest() + + let r1 : int64 = aa.A() + + let r2 : string = bb.B() + + let r3 : int list = cc.C() + """ + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open unit of measure - Errors`` () = + FSharp """ +namespace FSharpTest + +open System + +[] +type kg + +open type kg + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 704, Line 9, Col 11, Line 9, Col 13, "Expected type, not unit-of-measure") + ] + |> ignore + + [] + let ``Open type with unit of measure`` () = + FSharp """ +namespace FSharpTest + +open System +open System.Numerics + +[] +type kg + +open type float + +[] +type vec3<[] 'Measure> = Vector3 + +open type vec3 + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open custom type with unit of measure`` () = + FSharp """ +namespace FSharpTest + +[] +type kg + +type Custom<[] 'Measure> = + { + X: float<'Measure> + Y: float<'Measure> + } + + static member GetX(c: Custom<'Measure>) = c.X + + static member GetY(c: Custom<'Measure>) = c.Y + +open type Custom + +module Test = + + let x : float = GetX(Unchecked.defaultof<_>) + + let y : float = GetY(Unchecked.defaultof<_>) + + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open custom type with unit of measure and more type params`` () = + FSharp """ +namespace FSharpTest + +[] +type kg + +type Custom<'T, [] 'Measure, 'U> = + { + X: float<'Measure> + Y: float<'Measure> + Z: 'T + W: 'U + } + + static member GetX(c: Custom<'T, 'Measure, 'U>) = c.X + + static member GetY(c: Custom<'T, 'Measure, 'U>) = c.Y + + static member GetZ(c: Custom<'T, 'Measure, 'U>) = c.Z + + static member GetW(c: Custom<'T, 'Measure, 'U>) = c.W + +open type Custom + +module Test = + + let x : float = GetX(Unchecked.defaultof<_>) + + let y : float = GetY(Unchecked.defaultof<_>) + + let z : int = GetZ(Unchecked.defaultof<_>) + + let w : float = GetW(Unchecked.defaultof<_>) + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open custom type with unit of measure should error with measure mismatch`` () = + FSharp """ +namespace FSharpTest + +[] +type kg + +[] +type g + +type Custom<[] 'Measure> = + { + X: float<'Measure> + Y: float<'Measure> + } + + static member GetX(c: Custom<'Measure>) = c.X + + static member GetY(c: Custom<'Measure>) = c.Y + +open type Custom + +module Test = + + let x : float = GetX(Unchecked.defaultof<_>) + """ + |> withLangVersion50 + |> compile + |> withErrorCode 1 + |> ignore + + [] + let ``Open tuple - Errors`` () = + FSharp """ +namespace FSharpTest + +open type (int * int) + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 22, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open struct tuple - Errors`` () = + FSharp """ +namespace FSharpTest + +open type struct (int * int) + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 29, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open function - Errors`` () = + FSharp """ +namespace FSharpTest + +open type (int -> int) + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 23, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open anon type - Errors`` () = + FSharp """ +namespace FSharpTest + +open type {| x: int |} + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 23, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open struct anon type - Errors`` () = + FSharp """ +namespace FSharpTest + +open type struct {| x: int |} + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 30, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open direct tuple - Errors`` () = + // Note: `Tuple` is technically a named type but it gets decompiled into F#'s representation of a tuple in its type system. + // This test is to verify that behavior. + FSharp """ +namespace FSharpTest + +open System + +open type Tuple + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 6, Col 11, Line 6, Col 26, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open direct value tuple - Errors`` () = + // Note: `ValueTuple` is technically a named type but it gets decompiled into F#'s representation of a struct tuple in its type system. + // This test is to verify that behavior. + FSharp """ +namespace FSharpTest + +open System + +open type ValueTuple + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 6, Col 11, Line 6, Col 31, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open direct function - Errors`` () = + // Note: `FSharpFunc` is technically a named type but it gets decompiled into F#'s representation of a function in its type system. + // This test is to verify that behavior. + FSharp """ +namespace FSharpTest + +open type FSharpFunc + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 756, Line 4, Col 11, Line 4, Col 31, "'open type' may only be used with named types") + ] + |> ignore + + [] + let ``Open enum should have access to its cases`` () = + FSharp """ +namespace FSharpTest + +type TestEnum = + | EnumCase1 = 1 + | EnumCase2 = 2 + +open type TestEnum + +module Test = + + let x = EnumCase1 + let y = EnumCase2 + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open C# enum should have access to its cases`` () = + let csharp = + CSharp """ +namespace CSharpTest +{ + public enum CSharpEnum + { + CSharpEnumCase1 = 1, + CsharpEnumCase2 = 2 + } +} + """ + + FSharp """ +namespace FSharpTest + +open type CSharpTest.CSharpEnum + +module Test = + + let x = CSharpEnumCase1 + let y = CSharpEnumCase2 + """ + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> ignore + + [] + let ``Open union should have access to union cases`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestUnion = + | UCase1 + | UCase2 with + + static member M() = () + +open type Test.TestUnion + +module Test2 = + + let x = UCase1 + + let y = M() + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic union should have access to union cases with the enclosing type instantiations`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestUnion<'T> = + | UCase1 of 'T + | UCase2 with + + static member M() = () + +open type Test.TestUnion + +module Test2 = + + let x = UCase1 "" + + let y = M() + """ + |> withLangVersion50 + |> compile + |> withErrorCode 1 + |> ignore + + [] + let ``Open generic union should have access to pattern union cases with the enclosing type instantiations - Errors`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestUnion<'T> = + | UCase1 of 'T + +open type Test.TestUnion + +module Test2 = + + let f x : string = + match x with + | UCase1 x -> x + """ + |> withLangVersionPreview + |> compile + |> withErrorCode 1 + |> ignore + + [] + let ``Open record should have access to construct record via labels`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestRecord = { X: int } with + + static member M() = () + +open type Test.TestRecord + +module Test2 = + + let x = { X = 1 } + + let y = M() + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open generic record should have access to construct record via labels with enclosing type instantiations`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestRecord<'T> = { X: 'T } with + + static member M() = () + +open Test + +module Test2 = + + let x = { X = "" } + +open type Test.TestRecord + +module Test3 = + + let x = { X = "" } + + let y = M() + """ + |> withLangVersion50 + |> compile + |> withErrorCode 1 + |> ignore + + [] + let ``Open generic record should have access to pattern record via labels with enclosing type instantiations - Errors`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestRecord<'T> = { X: 'T } + +open Test + +module Test2 = + + let f x : string = + match x with + | { X = x } -> x + +open type Test.TestRecord + +module Test3 = + + let f x : string = + match x with + | { X = x } -> x + """ + |> withLangVersionPreview + |> compile + |> withErrorCode 1 + |> ignore + + [] + let ``Open type should have no access to constructor - Errors`` () = + FSharp """ +namespace FSharpTest + +module Test = + + type TestClass() = + + static member M() = () + +open type Test.TestClass + +module Test2 = + + let x = TestClass() + + let y = M() + """ + |> withLangVersion50 + |> compile + |> withErrorCode 39 + |> ignore + + [] + let ``Open type should combine both extension and intrinsic method groups`` () = + FSharp """ +namespace FSharpTest + +type Test = + + static member M(_x: int) = () + +module Test = + + type Test with + + static member M(_x: float) : int = 5 + +open Test +open type Test + +module Test2 = + + let test () : int = + M(1) + M(2.0) + """ + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Open type should combine both extension and intrinsic method groups but error if extensions are added after opening the type`` () = + FSharp """ +namespace FSharpTest + +type Test = + + static member M(_x: int) = () + +module Test = + + type Test with + + static member M(_x: float) : int = 5 + +open type Test +open Test + +module Test2 = + + let test () : int = + M(1) + M(2.0) + """ + |> withLangVersion50 + |> compile + |> withErrorCodes [1;1] + |> ignore + + [] + let ``Using the 'open' declaration on a possible type identifier - Error`` () = + let csharp = + CSharp """ +using System; + +namespace CSharpTest +{ + public static class Test + { + public static void A() + { + } + } +} + """ + + FSharp """ +namespace FSharpTest + +open System +open CSharpTest.Test + +module Test = + let x = A()""" + |> withLangVersion50 + |> withReferences [csharp] + |> compile + |> withDiagnostics + [ + (Error 39, Line 5, Col 17, Line 5, Col 21, "The namespace 'Test' is not defined.") + (Error 39, Line 8, Col 13, Line 8, Col 14, "The value or constructor 'A' is not defined.") + ] + |> ignore + + [] + let ``Open type declaration on a namespace - Error`` () = + FSharp """ +namespace FSharpTest + +open type System""" + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 39, Line 4, Col 11, Line 4, Col 17, "The type 'System' is not defined.") + ] + |> ignore + + [] + let ``Open type declaration on a module - Error`` () = + FSharp """ +namespace FSharpTest + +open type FSharp.Core.Option""" + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 33, Line 4, Col 11, Line 4, Col 29, "The type 'Microsoft.FSharp.Core.Option<_>' expects 1 type argument(s) but is given 0") + ] + |> ignore + + [] + let ``Open type declaration on a byref - Error`` () = + FSharp """ +namespace FSharpTest + +open type byref +open type inref +open type outref""" + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + (Error 3252, Line 4, Col 11, Line 4, Col 21, "Byref types are not allowed in an open type declaration.") + (Error 3252, Line 5, Col 11, Line 5, Col 21, "Byref types are not allowed in an open type declaration.") + (Error 3252, Line 6, Col 11, Line 6, Col 22, "Byref types are not allowed in an open type declaration.") + ] + |> ignore + + [] + let ``Type extensions with static members are able to be accessed in an unqualified manner`` () = + let fsharpSource = + """ +open System + +type A () = + + static member M() = Console.Write "M" + + static member P = Console.Write "P" + +[] +module AExtensions = + + type A with + + static member M2() = Console.Write "M2Ext" + + static member P2 = Console.Write "P2Ext" + +open type A + +[] +let main _ = + M() + P + M2() + P2 + 0 + """ + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "MPM2ExtP2Ext") + + [] + let ``Type extensions with static members are able to be accessed in an unqualified manner with no shadowing on identical names`` () = + let fsharpSource = + """ +open System + +type A () = + + static member M() = Console.Write "M" + + static member P = Console.Write "P" + +[] +module AExtensions = + + type A with + + static member M() = Console.Write "MExt" + + static member P = Console.Write "PExt" + +open type A + +[] +let main _ = + M() + P + 0 + """ + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "MP") + + [] + let ``Type extensions with static members are able to be accessed in an unqualified manner with the nuance of favoring extension properties over extension methods of identical names`` () = + let fsharpSource = + """ +open System + +type A () = + + static member P = Console.Write "P" + +[] +module AExtensions = + + type A with + + static member M = Console.Write "MExt" + +[] +module AExtensions2 = + + type A with + + static member M() = Console.Write "M" + +open type A + +[] +let main _ = + M + P + 0 + """ + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "MExtP") + + [] + let ``Type extensions with static members are able to be accessed in an unqualified manner with no shadowing on identical method/property names`` () = + let fsharpSource = + """ +open System + +type A () = + + static member M() = Console.Write "M" + +[] +module AExtensions = + + type A with + + static member M = Console.Write "MExt" + +open type A + +[] +let main _ = + M() + 0 + """ + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|]) + + CompilerAssert.ExecutionHasOutput(fsCmpl, "M") + + [] + let ``Opened types do no allow unqualified access to their inherited type's members - Error`` () = + Fsx """ +open type System.Math + +let x = Equals(2.0, 3.0) + """ + |> withLangVersion50 + |> compile + |> withDiagnostics + [ + ( Error 39, Line 4, Col 9, Line 4, Col 15, "The value or constructor 'Equals' is not defined.") + ] + |> ignore + + [] + let ``Opened types do no allow unqualified access to C#-style extension methods - Error`` () = + FSharp """ +open System.Runtime.CompilerServices + +module TestExtensions = + [] + type IntExtensions = + + [] + static member Test(_: int) = () + +open type TestExtensions.IntExtensions + +[] +let main _ = + Test(1) + 0""" + |> withLangVersion50 + |> asExe + |> compile + |> withDiagnostics + [ + (Error 39, Line 15, Col 5, Line 15, Col 9, + "The value or constructor 'Test' is not defined. Maybe you want one of the following: + Text + TestExtensions") + ] + |> ignore + + [] + let ``Opened types do allow unqualified access to C#-style extension methods if type has no [] attribute`` () = + FSharp """ +open System.Runtime.CompilerServices + +module TestExtensions = + type IntExtensions = + + [] + static member Test(_: int) = () + +open type TestExtensions.IntExtensions + +[] +let main _ = + Test(1) + 0""" + |> withLangVersion50 + |> asExe + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Opened types do allow unqualified access to members with no [] attribute`` () = + FSharp """ +open System.Runtime.CompilerServices + +module TestExtensions = + [] + type IntExtensions = + + static member Test(_: int) = () + +open type TestExtensions.IntExtensions + +[] +let main _ = + Test(1) + 0""" + |> withLangVersion50 + |> asExe + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Opened types with C# style extension members are available for normal extension method lookup`` () = + FSharp """ +open System.Runtime.CompilerServices + +module TestExtensions = + [] + type IntExtensions = + + [] + static member Test(_: int) = () + +open type TestExtensions.IntExtensions + +[] +let main _ = + let x = 1 + x.Test() + 0""" + |> withLangVersion50 + |> asExe + |> compile + |> shouldSucceed + |> ignore + + [] + let ``Opened types with operators`` () = + FSharp """ +type A() = + + static member (+) (x: string, y: string) = x + y + +open type A + +[] +let main _ = + let _x = 1 + 1 + 0""" + |> withLangVersion50 + |> asExe + |> compile + |> shouldSucceed + |> ignore + + [] + let ``An assembly with an event and field with the same name, favor the field`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class public auto ansi abstract sealed beforefieldinit ILTest.C + extends [netstandard]System.Object +{ + .field public static class [netstandard]System.EventHandler E + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + void add_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Combine(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .method public hidebysig specialname static + void remove_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Remove(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .event [netstandard]System.EventHandler X + { + .addon void ILTest.C::add_E(class [netstandard]System.EventHandler) + .removeon void ILTest.C::remove_E(class [netstandard]System.EventHandler) + } + + .field public static int32 X +} + """ + + let fsharpSource = + """ +module FSharpTest + +open ILTest + +type C with + + member _.X = obj () + +type C with + + member _.X() = obj () + +let x1: int = C.X + +open type C + +let x2: int = X + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [ilCmpl]) + + CompilerAssert.Compile(fsCmpl) + + [] + let ``An assembly with an event and field with the same name, favor the field - reversed`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class public auto ansi abstract sealed beforefieldinit ILTest.C + extends [netstandard]System.Object +{ + .field public static int32 X + .field public static class [netstandard]System.EventHandler E + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + void add_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Combine(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .method public hidebysig specialname static + void remove_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Remove(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .event [netstandard]System.EventHandler X + { + .addon void ILTest.C::add_E(class [netstandard]System.EventHandler) + .removeon void ILTest.C::remove_E(class [netstandard]System.EventHandler) + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open ILTest + +type C with + + member _.X = obj () + +type C with + + member _.X() = obj () + +let x1: int = C.X + +open type C + +let x2: int = X + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [ilCmpl]) + + CompilerAssert.Compile(fsCmpl) + + [] + let ``An assembly with a property, event, and field with the same name`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class public auto ansi abstract sealed beforefieldinit ILTest.C + extends [netstandard]System.Object +{ + .field public static class [netstandard]System.EventHandler E + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + void add_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Combine(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .method public hidebysig specialname static + void remove_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Remove(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .event [netstandard]System.EventHandler X + { + .addon void ILTest.C::add_E(class [netstandard]System.EventHandler) + .removeon void ILTest.C::remove_E(class [netstandard]System.EventHandler) + } + + .field public static int32 X + + .field private static initonly string 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + string get_Y () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 8 + + IL_0000: ldsfld string ILTest.C::'k__BackingField' + IL_0005: ret + } + + .property string X() + { + .get string ILTest.C::get_Y() + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open ILTest + +type C with + + member _.X = obj () + +type C with + + member _.X() = obj () + +let x1: string = C.X + +open type C + +let x2: string = X + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [ilCmpl]) + + CompilerAssert.Compile(fsCmpl) + + [] + let ``An assembly with a method, property, event, and field with the same name`` () = + let ilSource = + """ +.assembly il.dll +{ +} +.class public auto ansi abstract sealed beforefieldinit ILTest.C + extends [netstandard]System.Object +{ + .field public static class [netstandard]System.EventHandler E + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + void add_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Combine(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .method public hidebysig specialname static + void remove_E ( + class [netstandard]System.EventHandler 'value' + ) cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 3 + .locals init ( + [0] class [netstandard]System.EventHandler, + [1] class [netstandard]System.EventHandler, + [2] class [netstandard]System.EventHandler + ) + + IL_0000: ldsfld class [netstandard]System.EventHandler ILTest.C::E + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldarg.0 + IL_000a: call class [netstandard]System.Delegate [netstandard]System.Delegate::Remove(class [netstandard]System.Delegate, class [netstandard]System.Delegate) + IL_000f: castclass [netstandard]System.EventHandler + IL_0014: stloc.2 + IL_0015: ldsflda class [netstandard]System.EventHandler ILTest.C::E + IL_001a: ldloc.2 + IL_001b: ldloc.1 + IL_001c: call !!0 [netstandard]System.Threading.Interlocked::CompareExchange(!!0&, !!0, !!0) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: ldloc.1 + IL_0024: bne.un.s IL_0006 + IL_0026: ret + } + + .event [netstandard]System.EventHandler X + { + .addon void ILTest.C::add_E(class [netstandard]System.EventHandler) + .removeon void ILTest.C::remove_E(class [netstandard]System.EventHandler) + } + + .field public static int32 X + + .field private static initonly string 'k__BackingField' + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .method public hidebysig specialname static + string get_Y () cil managed + { + .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( + 01 00 00 00 + ) + + .maxstack 8 + + IL_0000: ldsfld string ILTest.C::'k__BackingField' + IL_0005: ret + } + + .property string X() + { + .get string ILTest.C::get_Y() + } + + .method public hidebysig static + float32 X () cil managed + { + .maxstack 8 + + IL_0000: ldc.r4 0.0 + IL_0005: ret + } +} + """ + + let fsharpSource = + """ +module FSharpTest + +open ILTest + +type C with + + member _.X = obj () + +type C with + + member _.X() = obj () + +let x1: float32 = C.X() + +open type C + +let x2: float32 = X() + """ + + let ilCmpl = + CompilationUtil.CreateILCompilation ilSource + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Library, options = [|"--langversion:5.0"|], cmplRefs = [ilCmpl]) + + CompilerAssert.Compile(fsCmpl) + +#if NETCOREAPP + + [] + let ``Opening an interface with a static method`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + public static void M() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +open type ITest + +[] +let main _ = + M() + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.Compile(fsCmpl) + + [] + let ``Opening an interface with an internal static method`` () = + let csharpSource = + """ +using System; +using System.Runtime.CompilerServices; + +[assembly:InternalsVisibleTo("Test")] + +namespace CSharpTest +{ + public interface ITest + { + internal static void M() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +open type ITest + +[] +let main _ = + M() + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl], name = "Test") + + CompilerAssert.Compile(fsCmpl) + + [] + let ``Opening an interface with an internal static method - Error`` () = + let csharpSource = + """ +using System; + +namespace CSharpTest +{ + public interface ITest + { + internal static void M() + { + } + } +} + """ + + let fsharpSource = + """ +open System +open CSharpTest + +open type ITest + +[] +let main _ = + M() + 0 + """ + + let csCmpl = + CompilationUtil.CreateCSharpCompilation(csharpSource, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31) + |> CompilationReference.Create + + let fsCmpl = + Compilation.Create(fsharpSource, Fs, Exe, options = [|"--langversion:5.0"|], cmplRefs = [csCmpl]) + + CompilerAssert.CompileWithErrors(fsCmpl, [| + (FSharpDiagnosticSeverity.Error, 39, (9, 5, 9, 6), "The value or constructor 'M' is not defined.") + |]) + +#endif + +#if !NETCOREAPP + + [] + let ``Opening type providers with abbreviation result in unqualified access to types and members`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + + let provider = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> withName "provider" + |> ignoreWarnings + |> withLangVersion50 + + let provided = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provided.fs")) + |> withName "provided" + |> ignoreWarnings + |> withLangVersion50 + + let test = + Fsx """ +type T = FSharp.HelloWorld.HelloWorldTypeWithStaticInt32Parameter<1> + +open type T + +if NestedType.StaticProperty1 <> "You got a static property" then + failwith "failed" + +open type T.NestedType + +if StaticProperty1 <> "You got a static property" then + failwith "failed" + """ + |> asExe + |> ignoreWarnings + |> withLangVersion50 + |> withReferences [provider;provided] + + compileAndRun test + |> ignore + + [] + let ``Opening type providers result in unqualified access to types and members`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + + let provider = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> withName "provider" + |> ignoreWarnings + |> withLangVersion50 + + let provided = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provided.fs")) + |> withName "provided" + |> ignoreWarnings + |> withLangVersion50 + + let test = + Fsx """ +open type FSharp.HelloWorld.HelloWorldTypeWithStaticInt32Parameter<1> + +if NestedType.StaticProperty1 <> "You got a static property" then + failwith "failed" + +open type NestedType + +if StaticProperty1 <> "You got a static property" then + failwith "failed" + """ + |> asExe + |> ignoreWarnings + |> withLangVersion50 + |> withReferences [provider;provided] + + compileAndRun test + |> ignore + + [] + let ``Opening type providers with nested result in unqualified access to types and members`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + + let provider = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> withName "provider" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let provided = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provided.fs")) + |> withName "provided" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let test = + Fsx """ +open type FSharp.HelloWorld.HelloWorldTypeWithStaticInt32Parameter<1>.NestedType + +if StaticProperty1 <> "You got a static property" then + failwith "failed" + """ + |> asExe + |> ignoreWarnings + |> withLangVersion50 + |> withReferences [provider;provided] + + compileAndRun test + |> ignore + + [] + let ``Opening generative type providers in unqualified access to types and members`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + + let provider = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> withName "provider" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let provided = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provided.fs")) + |> withName "provided" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let test = + Fsx """ +type TheOuterType = FSharp.HelloWorldGenerative.TheContainerType<"TheOuterType"> + +open type TheOuterType + +let _ : TheNestedGeneratedType = Unchecked.defaultof<_> + """ + |> asExe + |> withLangVersion50 + |> withReferences [provider;provided] + |> ignoreWarnings + + compileAndRun test + |> ignore + + [] + let ``Opening generative type providers directly in unqualified access to types and members - Errors`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + + let provider = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> withName "provider" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let provided = + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provided.fs")) + |> withName "provided" + |> withLangVersion50 + |> ignoreWarnings + |> withLangVersionPreview + + let test = + Fsx """ +open type FSharp.HelloWorldGenerative.TheContainerType<"TheOuterType"> + +let _ : TheNestedGeneratedType = Unchecked.defaultof<_> + """ + |> asExe + |> withLangVersion50 + |> withReferences [provider;provided] + |> ignoreWarnings + + compile test + |> withDiagnostics + [ + (Error 3039, Line 2, Col 11, Line 2, Col 55, "A direct reference to the generated type 'TheContainerType' is not permitted. Instead, use a type definition, e.g. 'type TypeAlias = '. This indicates that a type provider adds generated types to your assembly.") + (Error 39, Line 4, Col 9, Line 4, Col 31, "The type 'TheNestedGeneratedType' is not defined. Maybe you want one of the following: + TheGeneratedType1 + TheGeneratedType2 + TheGeneratedType4 + TheGeneratedType5 + TheGeneratedDelegateType") + ] + |> ignore + +#endif diff --git a/tests/fsharp/Compiler/Language/OptionalInteropTests.fs b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs new file mode 100644 index 00000000000..17dcfd4f62e --- /dev/null +++ b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System.Collections.Immutable +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler +open FSharp.Compiler.Diagnostics +open Microsoft.CodeAnalysis + +[] +module OptionalInteropTests = + + [] + let ``C# method with an optional parameter and called with an option type should compile`` () = + let csSrc = + """ +using Microsoft.FSharp.Core; + +namespace CSharpTest +{ + public static class Test + { + public static void M(FSharpOption x = null) { } + public static int MethodTakingOptionals(int x = 3, string y = "abc", double d = 5.0) + { + return x + y.Length + (int) d; + } + public static int MethodTakingNullableOptionalsWithDefaults(int? x = 3, string y = "abc", double? d = 5.0) + { + return (x.HasValue ? x.Value : -100) + y.Length + (int) (d.HasValue ? d.Value : 0.0); + } + public static int MethodTakingNullableOptionals(int? x = null, string y = null, double? d = null) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + public static int OverloadedMethodTakingOptionals(int x = 3, string y = "abc", double d = 5.0) + { + return x + y.Length + (int) d; + } + public static int OverloadedMethodTakingOptionals(int x = 3, string y = "abc", System.Single d = 5.0f) + { + return x + y.Length + (int) d + 7; + } + public static int OverloadedMethodTakingNullableOptionalsWithDefaults(int? x = 3, string y = "abc", double? d = 5.0) + { + return (x.HasValue ? x.Value : -100) + y.Length + (int) (d.HasValue ? d.Value : 0.0); + } + public static int OverloadedMethodTakingNullableOptionalsWithDefaults(long? x = 3, string y = "abc", double? d = 5.0) + { + return (x.HasValue ? (int) x.Value : -100) + y.Length + (int) (d.HasValue ? d.Value : 0.0) + 7; + } + public static int OverloadedMethodTakingNullableOptionals(int? x = null, string y = null, double? d = null) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + public static int OverloadedMethodTakingNullableOptionals(long? x = null, string y = null, double? d = null) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? (int) x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0) + 7; + } + public static int MethodTakingNullables(int? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + + public static int OverloadedMethodTakingNullables(int? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + public static int OverloadedMethodTakingNullables(long? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? (int) x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0) + 7; + } + public static int SimpleOverload(int? x = 3) + { + return (x.HasValue ? x.Value : 100); + } + + public static int SimpleOverload(int x = 3) + { + return (x + 200); + } + } +} + """ + + let fsSrc = + """ +open System +open CSharpTest + +Test.M(x = Some 1) +Test.MethodTakingNullables(6, "aaaaaa", 8.0) |> ignore +Test.MethodTakingNullables(6, "aaaaaa", Nullable 8.0) |> ignore +Test.MethodTakingNullables(6, "aaaaaa", Nullable ()) |> ignore +Test.MethodTakingNullables(Nullable (), "aaaaaa", 8.0) |> ignore +Test.MethodTakingNullables(Nullable 6, "aaaaaa", 8.0) |> ignore + +Test.MethodTakingNullables(6, "aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(6, "aaaaaa", d=Nullable 8.0) |> ignore +Test.MethodTakingNullables(6, "aaaaaa", d=Nullable ()) |> ignore +Test.MethodTakingNullables(Nullable (), "aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(Nullable 6, "aaaaaa", d=8.0) |> ignore + +Test.MethodTakingNullables(6, y="aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(6, y="aaaaaa", d=Nullable 8.0) |> ignore +Test.MethodTakingNullables(6, y="aaaaaa", d=Nullable ()) |> ignore +Test.MethodTakingNullables(Nullable (), y="aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(Nullable 6, y="aaaaaa", d=8.0) |> ignore + +Test.MethodTakingNullables(6, y="aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(6, y="aaaaaa", d=Nullable 8.0) |> ignore +Test.MethodTakingNullables(6, y="aaaaaa", d=Nullable ()) |> ignore +Test.MethodTakingNullables(Nullable (), y="aaaaaa", d=8.0) |> ignore +Test.MethodTakingNullables(Nullable 6, y="aaaaaa", d=8.0) |> ignore + """ + + let fsharpCoreAssembly = + typeof<_ list>.Assembly.Location + |> MetadataReference.CreateFromFile + + let cs = + CompilationUtil.CreateCSharpCompilation(csSrc, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp31, additionalReferences = ImmutableArray.CreateRange [fsharpCoreAssembly]) + |> CompilationReference.Create + + let fs = Compilation.Create(fsSrc, SourceKind.Fsx, CompileOutput.Exe, options = [|"--langversion:5.0"|], cmplRefs = [cs]) + CompilerAssert.Compile fs diff --git a/tests/fsharp/Compiler/Language/SlicingQuotationTests.fs b/tests/fsharp/Compiler/Language/SlicingQuotationTests.fs index 94cce8c3bd7..414d562708e 100644 --- a/tests/fsharp/Compiler/Language/SlicingQuotationTests.fs +++ b/tests/fsharp/Compiler/Language/SlicingQuotationTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module SlicingQuotationTests = diff --git a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs index c5fd682e993..6d155dc723e 100644 --- a/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs +++ b/tests/fsharp/Compiler/Language/SpanOptimizationTests.fs @@ -3,6 +3,7 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework +open FSharp.Test #if NETCOREAPP [] @@ -26,45 +27,37 @@ let test () = (fun verifier -> verifier.VerifyIL [ - """.method public static void test() cil managed - { + """ +.method public static void test() cil managed +{ - .maxstack 5 - .locals init (valuetype [System.Runtime]System.Span`1 V_0, + .maxstack 4 + .locals init (valuetype [runtime]System.Span`1 V_0, int32 V_1, - int32 V_2, - object& V_3) - IL_0000: call valuetype [System.Runtime]System.Span`1 valuetype [System.Runtime]System.Span`1::get_Empty() + object& V_2) + IL_0000: call valuetype [runtime]System.Span`1 valuetype [runtime]System.Span`1::get_Empty() IL_0005: stloc.0 IL_0006: ldc.i4.0 - IL_0007: stloc.2 - IL_0008: ldloca.s V_0 - IL_000a: call instance int32 valuetype [System.Runtime]System.Span`1::get_Length() - IL_000f: ldc.i4.1 - IL_0010: sub - IL_0011: stloc.1 - IL_0012: ldloc.1 + IL_0007: stloc.1 + IL_0008: br.s IL_0022 + + IL_000a: ldloca.s V_0 + IL_000c: ldloc.1 + IL_000d: call instance !0& valuetype [runtime]System.Span`1::get_Item(int32) + IL_0012: stloc.2 IL_0013: ldloc.2 - IL_0014: blt.s IL_0034 - - IL_0016: ldloca.s V_0 - IL_0018: ldloc.2 - IL_0019: call instance !0& valuetype [System.Runtime]System.Span`1::get_Item(int32) - IL_001e: stloc.3 - IL_001f: ldloc.3 - IL_0020: ldobj [System.Runtime]System.Object - IL_0025: call void [System.Console]System.Console::WriteLine(object) - IL_002a: ldloc.2 - IL_002b: ldc.i4.1 - IL_002c: add - IL_002d: stloc.2 - IL_002e: ldloc.2 - IL_002f: ldloc.1 - IL_0030: ldc.i4.1 - IL_0031: add - IL_0032: bne.un.s IL_0016 - - IL_0034: ret + IL_0014: ldobj [runtime]System.Object + IL_0019: call void [System.Console]System.Console::WriteLine(object) + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloca.s V_0 + IL_0025: call instance int32 valuetype [runtime]System.Span`1::get_Length() + IL_002a: blt.s IL_000a + + IL_002c: ret }""" ]) @@ -89,42 +82,33 @@ let test () = """.method public static void test() cil managed { - .maxstack 5 - .locals init (valuetype [System.Runtime]System.ReadOnlySpan`1 V_0, - int32 V_1, - int32 V_2, - object& V_3) - IL_0000: call valuetype [System.Runtime]System.ReadOnlySpan`1 valuetype [System.Runtime]System.ReadOnlySpan`1::get_Empty() + .maxstack 4 + .locals init (valuetype [runtime]System.ReadOnlySpan`1 V_0, + int32 V_1, + object& V_2) + IL_0000: call valuetype [runtime]System.ReadOnlySpan`1 valuetype [runtime]System.ReadOnlySpan`1::get_Empty() IL_0005: stloc.0 IL_0006: ldc.i4.0 - IL_0007: stloc.2 - IL_0008: ldloca.s V_0 - IL_000a: call instance int32 valuetype [System.Runtime]System.ReadOnlySpan`1::get_Length() - IL_000f: ldc.i4.1 - IL_0010: sub - IL_0011: stloc.1 - IL_0012: ldloc.1 + IL_0007: stloc.1 + IL_0008: br.s IL_0022 + + IL_000a: ldloca.s V_0 + IL_000c: ldloc.1 + IL_000d: call instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) valuetype [runtime]System.ReadOnlySpan`1::get_Item(int32) + IL_0012: stloc.2 IL_0013: ldloc.2 - IL_0014: blt.s IL_0034 - - IL_0016: ldloca.s V_0 - IL_0018: ldloc.2 - IL_0019: call instance !0& modreq([System.Runtime]System.Runtime.InteropServices.InAttribute) valuetype [System.Runtime]System.ReadOnlySpan`1::get_Item(int32) - IL_001e: stloc.3 - IL_001f: ldloc.3 - IL_0020: ldobj [System.Runtime]System.Object - IL_0025: call void [System.Console]System.Console::WriteLine(object) - IL_002a: ldloc.2 - IL_002b: ldc.i4.1 - IL_002c: add - IL_002d: stloc.2 - IL_002e: ldloc.2 - IL_002f: ldloc.1 - IL_0030: ldc.i4.1 - IL_0031: add - IL_0032: bne.un.s IL_0016 - - IL_0034: ret + IL_0014: ldobj [runtime]System.Object + IL_0019: call void [System.Console]System.Console::WriteLine(object) + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloca.s V_0 + IL_0025: call instance int32 valuetype [runtime]System.ReadOnlySpan`1::get_Length() + IL_002a: blt.s IL_000a + + IL_002c: ret }""" ]) @@ -149,17 +133,17 @@ open System.Runtime.CompilerServices [] type Span<'T>(arr: 'T []) = - member __.Item + member _.Item with get (i: int) = &arr.[i] - member __.Length + member _.Length with get () = 0 static member Empty = Span<'T>([||]) interface IEnumerable with - member __.GetEnumerator() = null + member _.GetEnumerator() = null module Test = @@ -170,6 +154,74 @@ module Test = """ // The current behavior doesn't optimize, but it could in the future. Making a test to catch if it ever does. + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + """ + .method public static void test() cil managed + { + + .maxstack 3 + .locals init (valuetype System.Span`1 V_0, + class [runtime]System.Collections.IEnumerator V_1, + class [runtime]System.IDisposable V_2) + IL_0000: call !!0[] [runtime]System.Array::Empty() + IL_0005: newobj instance void valuetype System.Span`1::.ctor(!0[]) + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: box valuetype System.Span`1 + IL_0011: unbox.any [runtime]System.Collections.IEnumerable + IL_0016: callvirt instance class [runtime]System.Collections.IEnumerator [runtime]System.Collections.IEnumerable::GetEnumerator() + IL_001b: stloc.1 + .try + { + IL_001c: ldloc.1 + IL_001d: callvirt instance bool [runtime]System.Collections.IEnumerator::MoveNext() + IL_0022: brfalse.s IL_0031 + + IL_0024: ldloc.1 + IL_0025: callvirt instance object [runtime]System.Collections.IEnumerator::get_Current() + IL_002a: call void [runtime]System.Console::WriteLine(object) + IL_002f: br.s IL_001c + + IL_0031: leave.s IL_0045 + + } + finally + { + IL_0033: ldloc.1 + IL_0034: isinst [runtime]System.IDisposable + IL_0039: stloc.2 + IL_003a: ldloc.2 + IL_003b: brfalse.s IL_0044 + + IL_003d: ldloc.2 + IL_003e: callvirt instance void [runtime]System.IDisposable::Dispose() + IL_0043: endfinally + IL_0044: endfinally + } + IL_0045: ret + } + + } +""" + ]) + + [] + let SpanForInBoundsDo() = + let source = + """ +module Test + +open System + +let test () = +let span = Span.Empty +for i in 0 .. span.Length-1 do + Console.WriteLine(span.[i]) + """ + CompilerAssert.CompileLibraryAndVerifyIL source (fun verifier -> verifier.VerifyIL @@ -177,56 +229,84 @@ module Test = """.method public static void test() cil managed { - .maxstack 3 - .locals init (valuetype System.Span`1 V_0, - class [System.Runtime]System.Collections.IEnumerator V_1, - class [FSharp.Core]Microsoft.FSharp.Core.Unit V_2, - class [System.Runtime]System.IDisposable V_3) - IL_0000: ldc.i4.0 - IL_0001: newarr [System.Runtime]System.Object - IL_0006: newobj instance void valuetype System.Span`1::.ctor(!0[]) - IL_000b: stloc.0 - IL_000c: ldloc.0 - IL_000d: box valuetype System.Span`1 - IL_0012: unbox.any [System.Runtime]System.Collections.IEnumerable - IL_0017: callvirt instance class [System.Runtime]System.Collections.IEnumerator [System.Runtime]System.Collections.IEnumerable::GetEnumerator() - IL_001c: stloc.1 - .try - { - IL_001d: ldloc.1 - IL_001e: callvirt instance bool [System.Runtime]System.Collections.IEnumerator::MoveNext() - IL_0023: brfalse.s IL_0032 - - IL_0025: ldloc.1 - IL_0026: callvirt instance object [System.Runtime]System.Collections.IEnumerator::get_Current() - IL_002b: call void [System.Console]System.Console::WriteLine(object) - IL_0030: br.s IL_001d - - IL_0032: ldnull - IL_0033: stloc.2 - IL_0034: leave.s IL_004c + .maxstack 4 + .locals init (valuetype [runtime]System.Span`1 V_0, + int32 V_1, + object& V_2) + IL_0000: call valuetype [runtime]System.Span`1 valuetype [runtime]System.Span`1::get_Empty() + IL_0005: stloc.0 + IL_0006: ldc.i4.0 + IL_0007: stloc.1 + IL_0008: br.s IL_0022 + + IL_000a: ldloca.s V_0 + IL_000c: ldloc.1 + IL_000d: call instance !0& valuetype [runtime]System.Span`1::get_Item(int32) + IL_0012: stloc.2 + IL_0013: ldloc.2 + IL_0014: ldobj [runtime]System.Object + IL_0019: call void [System.Console]System.Console::WriteLine(object) + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloca.s V_0 + IL_0025: call instance int32 valuetype [runtime]System.Span`1::get_Length() + IL_002a: blt.s IL_000a + + IL_002c: ret + }""" + ]) + [] + let ReadOnlySpanForInBoundsDo() = + let source = + """ +module Test + +open System + +let test () = +let span = ReadOnlySpan.Empty +for i in 0 .. span.Length-1 do +Console.WriteLine(span.[i]) + """ + + CompilerAssert.CompileLibraryAndVerifyIL source + (fun verifier -> + verifier.VerifyIL + [ + """.method public static void test() cil managed + { + + .maxstack 4 + .locals init (valuetype [runtime]System.ReadOnlySpan`1 V_0, + int32 V_1, + object& V_2) + IL_0000: call valuetype [runtime]System.ReadOnlySpan`1 valuetype [runtime]System.ReadOnlySpan`1::get_Empty() + IL_0005: stloc.0 + IL_0006: ldc.i4.0 + IL_0007: stloc.1 + IL_0008: br.s IL_0022 - } - finally - { - IL_0036: ldloc.1 - IL_0037: isinst [System.Runtime]System.IDisposable - IL_003c: stloc.3 - IL_003d: ldloc.3 - IL_003e: brfalse.s IL_0049 - - IL_0040: ldloc.3 - IL_0041: callvirt instance void [System.Runtime]System.IDisposable::Dispose() - IL_0046: ldnull - IL_0047: pop - IL_0048: endfinally - IL_0049: ldnull - IL_004a: pop - IL_004b: endfinally - } - IL_004c: ldloc.2 - IL_004d: pop - IL_004e: ret + IL_000a: ldloca.s V_0 + IL_000c: ldloc.1 + IL_000d: call instance !0& modreq([runtime]System.Runtime.InteropServices.InAttribute) valuetype [runtime]System.ReadOnlySpan`1::get_Item(int32) + IL_0012: stloc.2 + IL_0013: ldloc.2 + IL_0014: ldobj [runtime]System.Object + IL_0019: call void [System.Console]System.Console::WriteLine(object) + IL_001e: ldloc.1 + IL_001f: ldc.i4.1 + IL_0020: add + IL_0021: stloc.1 + IL_0022: ldloc.1 + IL_0023: ldloca.s V_0 + IL_0025: call instance int32 valuetype [runtime]System.ReadOnlySpan`1::get_Length() + IL_002a: blt.s IL_000a + + IL_002c: ret }""" ]) + #endif diff --git a/tests/fsharp/Compiler/Language/SpanTests.fs b/tests/fsharp/Compiler/Language/SpanTests.fs index 646032880ac..009a69c15a9 100644 --- a/tests/fsharp/Compiler/Language/SpanTests.fs +++ b/tests/fsharp/Compiler/Language/SpanTests.fs @@ -3,8 +3,9 @@ namespace FSharp.Compiler.UnitTests open System -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics open NUnit.Framework +open FSharp.Test #if NETCOREAPP [] @@ -25,6 +26,45 @@ let test () : unit = if result.[0] <> 1 || result.[1] <> 2 || result.[2] <> 3 || result.[3] <> 4 then failwith "SpanForInDo didn't work properly" +test () + """ + + CompilerAssert.RunScript script [] + [] + let Script_SpanForInBoundsDo() = + let script = + """ +open System + +let test () : unit = + let span = Span([|1;2;3;4|]) + let result = ResizeArray() + for i in 0 .. span.Length-1 do + result.Add(span.[i]) + + if result.[0] <> 1 || result.[1] <> 2 || result.[2] <> 3 || result.[3] <> 4 then + failwith "SpanForInBoundsDo didn't work properly" + +test () + """ + + CompilerAssert.RunScript script [] + + [] + let Script_EmptySpanForInBoundsDo() = + let script = + """ +open System + +let test () : unit = + let span = Span([||]) + let result = ResizeArray() + for i in 0 .. span.Length-1 do + result.Add(span.[i]) + + if result.Count <> 0 then + failwith "EmptySpanForInBoundsDo didn't work properly" + test () """ @@ -48,9 +88,27 @@ let test () : unit = test () """ - // We expect this error until System.Reflection.Emit gets fixed for emitting `modreq` on method calls. - // See: https://github.com/dotnet/corefx/issues/29254 - CompilerAssert.RunScript script [ "Method not found: '!0 ByRef System.ReadOnlySpan`1.get_Item(Int32)'." ] + CompilerAssert.RunScript script [] + + [] + let Script_ReadOnlySpanForInBoundsDo() = + let script = + """ +open System + +let test () : unit = + let span = ReadOnlySpan([|1;2;3;4|]) + let result = ResizeArray() + for i in 0 .. span.Length-1 do + result.Add(span.[i]) + + if result.[0] <> 1 || result.[1] <> 2 || result.[2] <> 3 || result.[3] <> 4 then + failwith "Script_ReadOnlySpanForInBoundsDo didn't work properly" + +test () + """ + + CompilerAssert.RunScript script [] [] @@ -85,9 +143,9 @@ let test () = 0 """ [| - FSharpErrorSeverity.Error, 412, (11, 17, 11, 28), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." - FSharpErrorSeverity.Error, 412, (19, 17, 19, 29), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." - FSharpErrorSeverity.Error, 412, (19, 27, 19, 29), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." + FSharpDiagnosticSeverity.Error, 412, (11, 17, 11, 28), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." + FSharpDiagnosticSeverity.Error, 412, (19, 17, 19, 29), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." + FSharpDiagnosticSeverity.Error, 412, (19, 27, 19, 29), "A type instantiation involves a byref type. This is not permitted by the rules of Common IL." |] [] @@ -100,6 +158,6 @@ type TA = Span * Span let f (x: TA) = () """ [| - FSharpErrorSeverity.Error, 3300, (6, 8, 6, 9), "The parameter 'x' has an invalid type 'TA'. This is not permitted by the rules of Common IL." + FSharpDiagnosticSeverity.Error, 3300, (6, 8, 6, 9), "The parameter 'x' has an invalid type 'TA'. This is not permitted by the rules of Common IL." |] -#endif +#endif \ No newline at end of file diff --git a/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs b/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs index 37f3ce3c410..f27b3bdc23f 100644 --- a/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs +++ b/tests/fsharp/Compiler/Language/StringConcatOptimizationTests.fs @@ -4,6 +4,7 @@ namespace FSharp.Compiler.UnitTests open System open NUnit.Framework +open FSharp.Test #if !NETCOREAPP [] @@ -249,195 +250,203 @@ let test4 () = { .maxstack 8 - .locals init (int32 V_0) - IL_0000: ldc.i4.s 13 - IL_0002: newarr [mscorlib]System.String - IL_0007: dup - IL_0008: ldc.i4.0 - IL_0009: ldc.i4.5 - IL_000a: stloc.0 - IL_000b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0010: ldc.i4.5 - IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0016: ldstr "_" - IL_001b: ldloca.s V_0 - IL_001d: constrained. [mscorlib]System.Int32 - IL_0023: callvirt instance string [mscorlib]System.Object::ToString() - IL_0028: ldstr "_" - IL_002d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0032: stelem [mscorlib]System.String - IL_0037: dup - IL_0038: ldc.i4.1 - IL_0039: ldc.i4.6 - IL_003a: stloc.0 - IL_003b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0040: ldc.i4.6 - IL_0041: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0046: ldstr "_" - IL_004b: ldloca.s V_0 - IL_004d: constrained. [mscorlib]System.Int32 - IL_0053: callvirt instance string [mscorlib]System.Object::ToString() - IL_0058: ldstr "_" - IL_005d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0062: stelem [mscorlib]System.String - IL_0067: dup - IL_0068: ldc.i4.2 - IL_0069: ldc.i4.7 - IL_006a: stloc.0 - IL_006b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0070: ldc.i4.7 - IL_0071: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0076: ldstr "_" - IL_007b: ldloca.s V_0 - IL_007d: constrained. [mscorlib]System.Int32 - IL_0083: callvirt instance string [mscorlib]System.Object::ToString() - IL_0088: ldstr "_" - IL_008d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0092: stelem [mscorlib]System.String - IL_0097: dup - IL_0098: ldc.i4.3 - IL_0099: ldc.i4.8 - IL_009a: stloc.0 - IL_009b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_00a0: ldc.i4.8 - IL_00a1: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_00a6: ldstr "_" - IL_00ab: ldloca.s V_0 - IL_00ad: constrained. [mscorlib]System.Int32 - IL_00b3: callvirt instance string [mscorlib]System.Object::ToString() - IL_00b8: ldstr "_" - IL_00bd: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_00c2: stelem [mscorlib]System.String - IL_00c7: dup - IL_00c8: ldc.i4.4 - IL_00c9: ldc.i4.s 9 - IL_00cb: stloc.0 - IL_00cc: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_00d1: ldc.i4.s 9 - IL_00d3: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_00d8: ldstr "_" - IL_00dd: ldloca.s V_0 - IL_00df: constrained. [mscorlib]System.Int32 - IL_00e5: callvirt instance string [mscorlib]System.Object::ToString() - IL_00ea: ldstr "_" - IL_00ef: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_00f4: stelem [mscorlib]System.String - IL_00f9: dup - IL_00fa: ldc.i4.5 - IL_00fb: ldc.i4.s 10 - IL_00fd: stloc.0 - IL_00fe: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0103: ldc.i4.s 10 - IL_0105: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_010a: ldstr "_" - IL_010f: ldloca.s V_0 - IL_0111: constrained. [mscorlib]System.Int32 - IL_0117: callvirt instance string [mscorlib]System.Object::ToString() - IL_011c: ldstr "_" - IL_0121: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0126: stelem [mscorlib]System.String - IL_012b: dup - IL_012c: ldc.i4.6 - IL_012d: ldstr "_50__60_" - IL_0132: stelem [mscorlib]System.String - IL_0137: dup - IL_0138: ldc.i4.7 - IL_0139: ldc.i4.s 100 - IL_013b: stloc.0 - IL_013c: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0141: ldc.i4.s 100 - IL_0143: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0148: ldstr "_" - IL_014d: ldloca.s V_0 - IL_014f: constrained. [mscorlib]System.Int32 - IL_0155: callvirt instance string [mscorlib]System.Object::ToString() - IL_015a: ldstr "_" - IL_015f: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0164: stelem [mscorlib]System.String - IL_0169: dup - IL_016a: ldc.i4.8 - IL_016b: ldc.i4.s 101 - IL_016d: stloc.0 - IL_016e: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0173: ldc.i4.s 101 - IL_0175: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_017a: ldstr "_" - IL_017f: ldloca.s V_0 - IL_0181: constrained. [mscorlib]System.Int32 - IL_0187: callvirt instance string [mscorlib]System.Object::ToString() - IL_018c: ldstr "_" - IL_0191: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0196: stelem [mscorlib]System.String - IL_019b: dup - IL_019c: ldc.i4.s 9 - IL_019e: ldc.i4.s 102 - IL_01a0: stloc.0 - IL_01a1: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_01a6: ldc.i4.s 102 - IL_01a8: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_01ad: ldstr "_" - IL_01b2: ldloca.s V_0 - IL_01b4: constrained. [mscorlib]System.Int32 - IL_01ba: callvirt instance string [mscorlib]System.Object::ToString() - IL_01bf: ldstr "_" - IL_01c4: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_01c9: stelem [mscorlib]System.String - IL_01ce: dup - IL_01cf: ldc.i4.s 10 - IL_01d1: ldc.i4.s 103 - IL_01d3: stloc.0 - IL_01d4: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_01d9: ldc.i4.s 103 - IL_01db: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_01e0: ldstr "_" - IL_01e5: ldloca.s V_0 - IL_01e7: constrained. [mscorlib]System.Int32 - IL_01ed: callvirt instance string [mscorlib]System.Object::ToString() - IL_01f2: ldstr "_" - IL_01f7: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_01fc: stelem [mscorlib]System.String - IL_0201: dup - IL_0202: ldc.i4.s 11 - IL_0204: ldstr "_104__105_" - IL_0209: stelem [mscorlib]System.String - IL_020e: dup - IL_020f: ldc.i4.s 12 - IL_0211: ldc.i4.s 106 - IL_0213: stloc.0 - IL_0214: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0219: ldc.i4.s 106 - IL_021b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0220: ldstr "_" - IL_0225: ldloca.s V_0 - IL_0227: constrained. [mscorlib]System.Int32 - IL_022d: callvirt instance string [mscorlib]System.Object::ToString() - IL_0232: ldstr "_" - IL_0237: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_023c: stelem [mscorlib]System.String - IL_0241: call string [mscorlib]System.String::Concat(string[]) - IL_0246: ret + .locals init (int32 V_0) + IL_0000: ldc.i4.s 15 + IL_0002: newarr [runtime]System.String + IL_0007: dup + IL_0008: ldc.i4.0 + IL_0009: ldc.i4.5 + IL_000a: stloc.0 + IL_000b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0010: ldc.i4.5 + IL_0011: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0016: ldstr "_" + IL_001b: ldloca.s V_0 + IL_001d: constrained. [runtime]System.Int32 + IL_0023: callvirt instance string [runtime]System.Object::ToString() + IL_0028: ldstr "_" + IL_002d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0032: stelem [runtime]System.String + IL_0037: dup + IL_0038: ldc.i4.1 + IL_0039: ldc.i4.6 + IL_003a: stloc.0 + IL_003b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0040: ldc.i4.6 + IL_0041: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0046: ldstr "_" + IL_004b: ldloca.s V_0 + IL_004d: constrained. [runtime]System.Int32 + IL_0053: callvirt instance string [runtime]System.Object::ToString() + IL_0058: ldstr "_" + IL_005d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0062: stelem [runtime]System.String + IL_0067: dup + IL_0068: ldc.i4.2 + IL_0069: ldc.i4.7 + IL_006a: stloc.0 + IL_006b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0070: ldc.i4.7 + IL_0071: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0076: ldstr "_" + IL_007b: ldloca.s V_0 + IL_007d: constrained. [runtime]System.Int32 + IL_0083: callvirt instance string [runtime]System.Object::ToString() + IL_0088: ldstr "_" + IL_008d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0092: stelem [runtime]System.String + IL_0097: dup + IL_0098: ldc.i4.3 + IL_0099: ldc.i4.8 + IL_009a: stloc.0 + IL_009b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_00a0: ldc.i4.8 + IL_00a1: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_00a6: ldstr "_" + IL_00ab: ldloca.s V_0 + IL_00ad: constrained. [runtime]System.Int32 + IL_00b3: callvirt instance string [runtime]System.Object::ToString() + IL_00b8: ldstr "_" + IL_00bd: call string [runtime]System.String::Concat(string, + string, + string) + IL_00c2: stelem [runtime]System.String + IL_00c7: dup + IL_00c8: ldc.i4.4 + IL_00c9: ldc.i4.s 9 + IL_00cb: stloc.0 + IL_00cc: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_00d1: ldc.i4.s 9 + IL_00d3: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_00d8: ldstr "_" + IL_00dd: ldloca.s V_0 + IL_00df: constrained. [runtime]System.Int32 + IL_00e5: callvirt instance string [runtime]System.Object::ToString() + IL_00ea: ldstr "_" + IL_00ef: call string [runtime]System.String::Concat(string, + string, + string) + IL_00f4: stelem [runtime]System.String + IL_00f9: dup + IL_00fa: ldc.i4.5 + IL_00fb: ldc.i4.s 10 + IL_00fd: stloc.0 + IL_00fe: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0103: ldc.i4.s 10 + IL_0105: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_010a: ldstr "_" + IL_010f: ldloca.s V_0 + IL_0111: constrained. [runtime]System.Int32 + IL_0117: callvirt instance string [runtime]System.Object::ToString() + IL_011c: ldstr "_" + IL_0121: call string [runtime]System.String::Concat(string, + string, + string) + IL_0126: stelem [runtime]System.String + IL_012b: dup + IL_012c: ldc.i4.6 + IL_012d: ldstr "_50_" + IL_0132: stelem [runtime]System.String + IL_0137: dup + IL_0138: ldc.i4.7 + IL_0139: ldstr "_60_" + IL_013e: stelem [runtime]System.String + IL_0143: dup + IL_0144: ldc.i4.8 + IL_0145: ldc.i4.s 100 + IL_0147: stloc.0 + IL_0148: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_014d: ldc.i4.s 100 + IL_014f: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0154: ldstr "_" + IL_0159: ldloca.s V_0 + IL_015b: constrained. [runtime]System.Int32 + IL_0161: callvirt instance string [runtime]System.Object::ToString() + IL_0166: ldstr "_" + IL_016b: call string [runtime]System.String::Concat(string, + string, + string) + IL_0170: stelem [runtime]System.String + IL_0175: dup + IL_0176: ldc.i4.s 9 + IL_0178: ldc.i4.s 101 + IL_017a: stloc.0 + IL_017b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0180: ldc.i4.s 101 + IL_0182: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0187: ldstr "_" + IL_018c: ldloca.s V_0 + IL_018e: constrained. [runtime]System.Int32 + IL_0194: callvirt instance string [runtime]System.Object::ToString() + IL_0199: ldstr "_" + IL_019e: call string [runtime]System.String::Concat(string, + string, + string) + IL_01a3: stelem [runtime]System.String + IL_01a8: dup + IL_01a9: ldc.i4.s 10 + IL_01ab: ldc.i4.s 102 + IL_01ad: stloc.0 + IL_01ae: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_01b3: ldc.i4.s 102 + IL_01b5: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_01ba: ldstr "_" + IL_01bf: ldloca.s V_0 + IL_01c1: constrained. [runtime]System.Int32 + IL_01c7: callvirt instance string [runtime]System.Object::ToString() + IL_01cc: ldstr "_" + IL_01d1: call string [runtime]System.String::Concat(string, + string, + string) + IL_01d6: stelem [runtime]System.String + IL_01db: dup + IL_01dc: ldc.i4.s 11 + IL_01de: ldc.i4.s 103 + IL_01e0: stloc.0 + IL_01e1: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_01e6: ldc.i4.s 103 + IL_01e8: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_01ed: ldstr "_" + IL_01f2: ldloca.s V_0 + IL_01f4: constrained. [runtime]System.Int32 + IL_01fa: callvirt instance string [runtime]System.Object::ToString() + IL_01ff: ldstr "_" + IL_0204: call string [runtime]System.String::Concat(string, + string, + string) + IL_0209: stelem [runtime]System.String + IL_020e: dup + IL_020f: ldc.i4.s 12 + IL_0211: ldstr "_104_" + IL_0216: stelem [runtime]System.String + IL_021b: dup + IL_021c: ldc.i4.s 13 + IL_021e: ldstr "_105_" + IL_0223: stelem [runtime]System.String + IL_0228: dup + IL_0229: ldc.i4.s 14 + IL_022b: ldc.i4.s 106 + IL_022d: stloc.0 + IL_022e: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0233: ldc.i4.s 106 + IL_0235: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_023a: ldstr "_" + IL_023f: ldloca.s V_0 + IL_0241: constrained. [runtime]System.Int32 + IL_0247: callvirt instance string [runtime]System.Object::ToString() + IL_024c: ldstr "_" + IL_0251: call string [runtime]System.String::Concat(string, + string, + string) + IL_0256: stelem [runtime]System.String + IL_025b: call string [runtime]System.String::Concat(string[]) + IL_0260: ret }""" let test5Source = """ @@ -447,200 +456,208 @@ let test5 () = let test5IL = """.method public static string test5() cil managed { - .maxstack 9 - .locals init (int32 V_0, - string V_1) - IL_0000: ldc.i4.s 12 - IL_0002: newarr [mscorlib]System.String - IL_0007: dup - IL_0008: ldc.i4.0 - IL_0009: ldc.i4.5 - IL_000a: stloc.0 - IL_000b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0010: ldc.i4.5 - IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0016: ldstr "_" - IL_001b: ldloca.s V_0 - IL_001d: constrained. [mscorlib]System.Int32 - IL_0023: callvirt instance string [mscorlib]System.Object::ToString() - IL_0028: ldstr "_" - IL_002d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0032: stelem [mscorlib]System.String - IL_0037: dup - IL_0038: ldc.i4.1 - IL_0039: ldc.i4.6 - IL_003a: stloc.0 - IL_003b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0040: ldc.i4.6 - IL_0041: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0046: ldstr "_" - IL_004b: ldloca.s V_0 - IL_004d: constrained. [mscorlib]System.Int32 - IL_0053: callvirt instance string [mscorlib]System.Object::ToString() - IL_0058: ldstr "_" - IL_005d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0062: stelem [mscorlib]System.String - IL_0067: dup - IL_0068: ldc.i4.2 - IL_0069: ldc.i4.7 - IL_006a: stloc.0 - IL_006b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0070: ldc.i4.7 - IL_0071: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0076: ldstr "_" - IL_007b: ldloca.s V_0 - IL_007d: constrained. [mscorlib]System.Int32 - IL_0083: callvirt instance string [mscorlib]System.Object::ToString() - IL_0088: ldstr "_" - IL_008d: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0092: stelem [mscorlib]System.String - IL_0097: dup - IL_0098: ldc.i4.3 - IL_0099: ldc.i4.8 - IL_009a: stloc.0 - IL_009b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_00a0: ldc.i4.8 - IL_00a1: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_00a6: ldstr "_" - IL_00ab: ldloca.s V_0 - IL_00ad: constrained. [mscorlib]System.Int32 - IL_00b3: callvirt instance string [mscorlib]System.Object::ToString() - IL_00b8: ldstr "_" - IL_00bd: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_00c2: stelem [mscorlib]System.String - IL_00c7: dup - IL_00c8: ldc.i4.4 - IL_00c9: ldc.i4.s 9 - IL_00cb: stloc.0 - IL_00cc: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_00d1: ldc.i4.s 9 - IL_00d3: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_00d8: ldstr "_" - IL_00dd: ldloca.s V_0 - IL_00df: constrained. [mscorlib]System.Int32 - IL_00e5: callvirt instance string [mscorlib]System.Object::ToString() - IL_00ea: ldstr "_" - IL_00ef: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_00f4: stelem [mscorlib]System.String - IL_00f9: dup - IL_00fa: ldc.i4.5 - IL_00fb: ldc.i4.s 10 - IL_00fd: stloc.0 - IL_00fe: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0103: ldc.i4.s 10 - IL_0105: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_010a: ldstr "_" - IL_010f: ldloca.s V_0 - IL_0111: constrained. [mscorlib]System.Int32 - IL_0117: callvirt instance string [mscorlib]System.Object::ToString() - IL_011c: ldstr "_" - IL_0121: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0126: stelem [mscorlib]System.String - IL_012b: dup - IL_012c: ldc.i4.6 - IL_012d: ldstr "_50__60_" - IL_0132: stelem [mscorlib]System.String - IL_0137: dup - IL_0138: ldc.i4.7 - IL_0139: ldc.i4.s 100 - IL_013b: stloc.0 - IL_013c: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0141: ldc.i4.s 100 - IL_0143: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0148: ldstr "_" - IL_014d: ldloca.s V_0 - IL_014f: constrained. [mscorlib]System.Int32 - IL_0155: callvirt instance string [mscorlib]System.Object::ToString() - IL_015a: ldstr "_" - IL_015f: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0164: stelem [mscorlib]System.String - IL_0169: dup - IL_016a: ldc.i4.8 - IL_016b: ldc.i4.s 101 - IL_016d: stloc.0 - IL_016e: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_0173: ldc.i4.s 101 - IL_0175: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_017a: ldstr "_" - IL_017f: ldloca.s V_0 - IL_0181: constrained. [mscorlib]System.Int32 - IL_0187: callvirt instance string [mscorlib]System.Object::ToString() - IL_018c: ldstr "_" - IL_0191: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0196: ldc.i4.s 102 - IL_0198: stloc.0 - IL_0199: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_019e: ldc.i4.s 102 - IL_01a0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_01a5: ldstr "_" - IL_01aa: ldloca.s V_0 - IL_01ac: constrained. [mscorlib]System.Int32 - IL_01b2: callvirt instance string [mscorlib]System.Object::ToString() - IL_01b7: ldstr "_" - IL_01bc: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_01c1: call string [mscorlib]System.String::Concat(string, - string) - IL_01c6: stloc.1 - IL_01c7: ldloc.1 - IL_01c8: call void [mscorlib]System.Console::WriteLine(string) - IL_01cd: ldloc.1 - IL_01ce: stelem [mscorlib]System.String - IL_01d3: dup - IL_01d4: ldc.i4.s 9 - IL_01d6: ldc.i4.s 103 - IL_01d8: stloc.0 - IL_01d9: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_01de: ldc.i4.s 103 - IL_01e0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_01e5: ldstr "_" - IL_01ea: ldloca.s V_0 - IL_01ec: constrained. [mscorlib]System.Int32 - IL_01f2: callvirt instance string [mscorlib]System.Object::ToString() - IL_01f7: ldstr "_" - IL_01fc: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0201: stelem [mscorlib]System.String - IL_0206: dup - IL_0207: ldc.i4.s 10 - IL_0209: ldstr "_104__105_" - IL_020e: stelem [mscorlib]System.String - IL_0213: dup - IL_0214: ldc.i4.s 11 - IL_0216: ldc.i4.s 106 - IL_0218: stloc.0 - IL_0219: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() - IL_021e: ldc.i4.s 106 - IL_0220: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) - IL_0225: ldstr "_" - IL_022a: ldloca.s V_0 - IL_022c: constrained. [mscorlib]System.Int32 - IL_0232: callvirt instance string [mscorlib]System.Object::ToString() - IL_0237: ldstr "_" - IL_023c: call string [mscorlib]System.String::Concat(string, - string, - string) - IL_0241: stelem [mscorlib]System.String - IL_0246: call string [mscorlib]System.String::Concat(string[]) - IL_024b: ret +.maxstack 9 + .locals init (int32 V_0, + string V_1) + IL_0000: ldc.i4.s 14 + IL_0002: newarr [runtime]System.String + IL_0007: dup + IL_0008: ldc.i4.0 + IL_0009: ldc.i4.5 + IL_000a: stloc.0 + IL_000b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0010: ldc.i4.5 + IL_0011: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0016: ldstr "_" + IL_001b: ldloca.s V_0 + IL_001d: constrained. [runtime]System.Int32 + IL_0023: callvirt instance string [runtime]System.Object::ToString() + IL_0028: ldstr "_" + IL_002d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0032: stelem [runtime]System.String + IL_0037: dup + IL_0038: ldc.i4.1 + IL_0039: ldc.i4.6 + IL_003a: stloc.0 + IL_003b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0040: ldc.i4.6 + IL_0041: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0046: ldstr "_" + IL_004b: ldloca.s V_0 + IL_004d: constrained. [runtime]System.Int32 + IL_0053: callvirt instance string [runtime]System.Object::ToString() + IL_0058: ldstr "_" + IL_005d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0062: stelem [runtime]System.String + IL_0067: dup + IL_0068: ldc.i4.2 + IL_0069: ldc.i4.7 + IL_006a: stloc.0 + IL_006b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0070: ldc.i4.7 + IL_0071: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0076: ldstr "_" + IL_007b: ldloca.s V_0 + IL_007d: constrained. [runtime]System.Int32 + IL_0083: callvirt instance string [runtime]System.Object::ToString() + IL_0088: ldstr "_" + IL_008d: call string [runtime]System.String::Concat(string, + string, + string) + IL_0092: stelem [runtime]System.String + IL_0097: dup + IL_0098: ldc.i4.3 + IL_0099: ldc.i4.8 + IL_009a: stloc.0 + IL_009b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_00a0: ldc.i4.8 + IL_00a1: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_00a6: ldstr "_" + IL_00ab: ldloca.s V_0 + IL_00ad: constrained. [runtime]System.Int32 + IL_00b3: callvirt instance string [runtime]System.Object::ToString() + IL_00b8: ldstr "_" + IL_00bd: call string [runtime]System.String::Concat(string, + string, + string) + IL_00c2: stelem [runtime]System.String + IL_00c7: dup + IL_00c8: ldc.i4.4 + IL_00c9: ldc.i4.s 9 + IL_00cb: stloc.0 + IL_00cc: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_00d1: ldc.i4.s 9 + IL_00d3: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_00d8: ldstr "_" + IL_00dd: ldloca.s V_0 + IL_00df: constrained. [runtime]System.Int32 + IL_00e5: callvirt instance string [runtime]System.Object::ToString() + IL_00ea: ldstr "_" + IL_00ef: call string [runtime]System.String::Concat(string, + string, + string) + IL_00f4: stelem [runtime]System.String + IL_00f9: dup + IL_00fa: ldc.i4.5 + IL_00fb: ldc.i4.s 10 + IL_00fd: stloc.0 + IL_00fe: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0103: ldc.i4.s 10 + IL_0105: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_010a: ldstr "_" + IL_010f: ldloca.s V_0 + IL_0111: constrained. [runtime]System.Int32 + IL_0117: callvirt instance string [runtime]System.Object::ToString() + IL_011c: ldstr "_" + IL_0121: call string [runtime]System.String::Concat(string, + string, + string) + IL_0126: stelem [runtime]System.String + IL_012b: dup + IL_012c: ldc.i4.6 + IL_012d: ldstr "_50_" + IL_0132: stelem [runtime]System.String + IL_0137: dup + IL_0138: ldc.i4.7 + IL_0139: ldstr "_60_" + IL_013e: stelem [runtime]System.String + IL_0143: dup + IL_0144: ldc.i4.8 + IL_0145: ldc.i4.s 100 + IL_0147: stloc.0 + IL_0148: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_014d: ldc.i4.s 100 + IL_014f: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0154: ldstr "_" + IL_0159: ldloca.s V_0 + IL_015b: constrained. [runtime]System.Int32 + IL_0161: callvirt instance string [runtime]System.Object::ToString() + IL_0166: ldstr "_" + IL_016b: call string [runtime]System.String::Concat(string, + string, + string) + IL_0170: stelem [runtime]System.String + IL_0175: dup + IL_0176: ldc.i4.s 9 + IL_0178: ldc.i4.s 101 + IL_017a: stloc.0 + IL_017b: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0180: ldc.i4.s 101 + IL_0182: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_0187: ldstr "_" + IL_018c: ldloca.s V_0 + IL_018e: constrained. [runtime]System.Int32 + IL_0194: callvirt instance string [runtime]System.Object::ToString() + IL_0199: ldstr "_" + IL_019e: call string [runtime]System.String::Concat(string, + string, + string) + IL_01a3: ldc.i4.s 102 + IL_01a5: stloc.0 + IL_01a6: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_01ab: ldc.i4.s 102 + IL_01ad: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_01b2: ldstr "_" + IL_01b7: ldloca.s V_0 + IL_01b9: constrained. [runtime]System.Int32 + IL_01bf: callvirt instance string [runtime]System.Object::ToString() + IL_01c4: ldstr "_" + IL_01c9: call string [runtime]System.String::Concat(string, + string, + string) + IL_01ce: call string [runtime]System.String::Concat(string, + string) + IL_01d3: stloc.1 + IL_01d4: ldloc.1 + IL_01d5: call void [runtime]System.Console::WriteLine(string) + IL_01da: ldloc.1 + IL_01db: stelem [runtime]System.String + IL_01e0: dup + IL_01e1: ldc.i4.s 10 + IL_01e3: ldc.i4.s 103 + IL_01e5: stloc.0 + IL_01e6: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_01eb: ldc.i4.s 103 + IL_01ed: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_01f2: ldstr "_" + IL_01f7: ldloca.s V_0 + IL_01f9: constrained. [runtime]System.Int32 + IL_01ff: callvirt instance string [runtime]System.Object::ToString() + IL_0204: ldstr "_" + IL_0209: call string [runtime]System.String::Concat(string, + string, + string) + IL_020e: stelem [runtime]System.String + IL_0213: dup + IL_0214: ldc.i4.s 11 + IL_0216: ldstr "_104_" + IL_021b: stelem [runtime]System.String + IL_0220: dup + IL_0221: ldc.i4.s 12 + IL_0223: ldstr "_105_" + IL_0228: stelem [runtime]System.String + IL_022d: dup + IL_022e: ldc.i4.s 13 + IL_0230: ldc.i4.s 106 + IL_0232: stloc.0 + IL_0233: call class [runtime]System.Collections.Generic.List`1 Test::get_arr() + IL_0238: ldc.i4.s 106 + IL_023a: callvirt instance void class [runtime]System.Collections.Generic.List`1::Add(!0) + IL_023f: ldstr "_" + IL_0244: ldloca.s V_0 + IL_0246: constrained. [runtime]System.Int32 + IL_024c: callvirt instance string [runtime]System.Object::ToString() + IL_0251: ldstr "_" + IL_0256: call string [runtime]System.String::Concat(string, + string, + string) + IL_025b: stelem [runtime]System.String + IL_0260: call string [runtime]System.String::Concat(string[]) + IL_0265: ret }""" let test6Source = """ @@ -848,4 +865,4 @@ let test9 () = test9IL ] ) -#endif \ No newline at end of file +#endif diff --git a/tests/fsharp/Compiler/Language/StringInterpolation.fs b/tests/fsharp/Compiler/Language/StringInterpolation.fs new file mode 100644 index 00000000000..be7812ff7c0 --- /dev/null +++ b/tests/fsharp/Compiler/Language/StringInterpolation.fs @@ -0,0 +1,875 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.Diagnostics +open FSharp.Test + +[] +module StringInterpolationTests = + + let SimpleCheckTest text = + CompilerAssert.CompileExeAndRunWithOptions [| "--langversion:5.0" |] (""" +let check msg a b = + if a = b then printfn "test case '%s' succeeded" msg else failwithf "test case '%s' failed, expected %A, got %A" msg b a + +""" + text) + + [] + let ``Basic string interpolation`` () = + SimpleCheckTest + """ +check "basic-string-interp1" $"this is 2" "this is 2" + +check "basic-string-interp2" $"this is {1} + 1 = 2" "this is 1 + 1 = 2" + +check "basic-string-interp3" $"this is {1} + {1+1} = 3" "this is 1 + 2 = 3" + +check "basic-string-interp4" $"this is {1} + {1+1}" "this is 1 + 2" + +check "basic-string-interp5" $"this is {1}" "this is 1" + +check "basic-string-interp6" $"123{456}789{012}345" "12345678912345" + +check "basic-string-interp7" $"this is {1} {2} {3} {4} {5} {6} {7}" "this is 1 2 3 4 5 6 7" + +check "basic-string-interp8" $"this is {7} {6} {5} {4} {3} {2} {1}" "this is 7 6 5 4 3 2 1" + +check "basic-string-interp9" $"{1} +{2}" "1 +2" + """ + + [] + let ``Neighbouring specifiers for string interpolation`` () = + SimpleCheckTest + """ +check "nbr-interp71" $"this is {1} {2} {3} {4} {5} {6} {7}" "this is 1 2 3 4 5 6 7" +check "nbr-interp7b2" $"this is {1}{2}{3}{4}{5}{6}{7}" "this is 1234567" +check "nbr-interp7c3" $"this is {1}{2}{3}{4}{5}{6}" "this is 123456" +check "nbr-interp7c4" $"this is {1}{2}{3}{4}{5}" "this is 12345" +check "nbr-interp7c5" $"this is {1}{2}{3}{4}" "this is 1234" +check "nbr-interp7c6" $"this is {1}{2}{3} {4}" "this is 123 4" +check "nbr-interp7c7" $"this is {1}{2} {3} {4}" "this is 12 3 4" +check "nbr-interp7c8" $"this is {1}{2} {3}{4}" "this is 12 34" +check "nbr-interp7c9" $"this is {1}{2}{3}" "this is 123" +check "nbr-interp7cq" $"this is {1} {2}{3}" "this is 1 23" +check "nbr-interp7cw" $"this is {1}{2} {3}" "this is 12 3" +check "nbr-interp7ce" $"this is {1}{2}" "this is 12" + +check "nbr-interp7r" $"this is %d{1} {2} {3} {4} {5} {6} {7}" "this is 1 2 3 4 5 6 7" +check "nbr-interp7bt" $"this is %d{1}{2}{3}{4}{5}{6}{7}" "this is 1234567" +check "nbr-interp7cy" $"this is %d{1}{2}{3}{4}{5}{6}" "this is 123456" +check "nbr-interp7cu" $"this is %d{1}{2}{3}{4}{5}" "this is 12345" +check "nbr-interp7ci" $"this is %d{1}{2}{3}{4}" "this is 1234" +check "nbr-interp7co" $"this is %d{1}{2}{3} {4}" "this is 123 4" +check "nbr-interp7cp" $"this is %d{1}{2} {3} {4}" "this is 12 3 4" +check "nbr-interp7ca" $"this is %d{1}{2} {3}{4}" "this is 12 34" +check "nbr-interp7cs" $"this is %d{1}{2}{3}" "this is 123" +check "nbr-interp7cd" $"this is %d{1} {2}{3}" "this is 1 23" +check "nbr-interp7cf" $"this is %d{1}{2} {3}" "this is 12 3" +check "nbr-interp7cg" $"this is %d{1}{2}" "this is 12" + +check "nbr-interp7h" $"this is %d{1} %d{2} {3} {4} {5} {6} {7}" "this is 1 2 3 4 5 6 7" +check "nbr-interp7bj" $"this is %d{1}%d{2}{3}{4}{5}{6}{7}" "this is 1234567" +check "nbr-interp7ck" $"this is %d{1}%d{2}{3}{4}{5}{6}" "this is 123456" +check "nbr-interp7cl" $"this is %d{1}%d{2}{3}{4}{5}" "this is 12345" +check "nbr-interp7cz" $"this is %d{1}%d{2}{3}{4}" "this is 1234" +check "nbr-interp7cx" $"this is %d{1}%d{2}{3} {4}" "this is 123 4" +check "nbr-interp7cc" $"this is %d{1}%d{2} {3} {4}" "this is 12 3 4" +check "nbr-interp7cv" $"this is %d{1}%d{2} {3}{4}" "this is 12 34" +check "nbr-interp7cb" $"this is %d{1}%d{2}{3}" "this is 123" +check "nbr-interp7cn" $"this is %d{1} %d{2}{3}" "this is 1 23" +check "nbr-interp7cm" $"this is %d{1}%d{2} {3}" "this is 12 3" +check "nbr-interp7cp" $"this is %d{1}%d{2}" "this is 12" + +check "nbr-interp7" $"this is %d{1} %d{2} %d{3} {4} {5} {6} {7}" "this is 1 2 3 4 5 6 7" +check "nbr-interp7b" $"this is %d{1}%d{2}%d{3}{4}{5}{6}{7}" "this is 1234567" +check "nbr-interp7c" $"this is %d{1}%d{2}%d{3}{4}{5}{6}" "this is 123456" +check "nbr-interp7c" $"this is %d{1}%d{2}%d{3}{4}{5}" "this is 12345" +check "nbr-interp7c" $"this is %d{1}%d{2}%d{3}{4}" "this is 1234" +check "nbr-interp7c" $"this is %d{1}%d{2}%d{3} {4}" "this is 123 4" +check "nbr-interp7c" $"this is %d{1}%d{2} %d{3} {4}" "this is 12 3 4" +check "nbr-interp7c" $"this is %d{1}%d{2} %d{3}{4}" "this is 12 34" +check "nbr-interp7c" $"this is %d{1}%d{2}%d{3}" "this is 123" +check "nbr-interp7c" $"this is %d{1} %d{2}%d{3}" "this is 1 23" +check "nbr-interp7c" $"this is %d{1}%d{2} %d{3}" "this is 12 3" +check "nbr-interp7c" $"this is %d{1}%d{2}" "this is 12" + """ + + [] + let ``Basic string interpolation verbatim strings`` () = + SimpleCheckTest + """ +check "basic-string-interp-triple1" @$"this is 2" "this is 2" + +check "basic-string-interp-verbatim2" @$"this is {1} + 1 = 2" "this is 1 + 1 = 2" + +check "basic-string-interp-verbatim3" @$"this is {1} + {1+1} = 3" "this is 1 + 2 = 3" + +check "basic-string-interp-verbatim4" @$"this is {1} + {1+1}" "this is 1 + 2" + +check "basic-string-interp-verbatim5" @$"this is {1}" "this is 1" + +check "basic-string-interp-verbatim6" @$"this i\s {1}" "this i\s 1" + +check "basic-string-interp-verbatim1b" $@"this is 2" "this is 2" + +check "basic-string-interp-verbatim2b" $@"this is {1} + 1 = 2" "this is 1 + 1 = 2" + +check "basic-string-interp-verbatim3b" $@"this is {1} + {1+1} = 3" "this is 1 + 2 = 3" + +check "basic-string-interp-verbatim4b" $@"this is {1} + {1+1}" "this is 1 + 2" + +check "basic-string-interp-verbatim5b" $@"this is {1}" "this is 1" + +check "basic-string-interp-verbatim6b" $@"this i\s {1}" "this i\s 1" + + """ + + [] + let ``Basic string interpolation triple quote strings`` () = + SimpleCheckTest + " +check \"basic-string-interp-triple1\" $\"\"\"this is 2\"\"\" \"this is 2\" + +check \"basic-string-interp-triple2\" $\"\"\"this is {1} + 1 = 2\"\"\" \"this is 1 + 1 = 2\" + +check \"basic-string-interp-triple3\" $\"\"\"this is {1} + {1+1} = 3\"\"\" \"this is 1 + 2 = 3\" + +check \"basic-string-interp-triple4\" $\"\"\"this is {1} + {1+1}\"\"\" \"this is 1 + 2\" + +check \"basic-string-interp-triple5\" $\"\"\"this is {1}\"\"\" \"this is 1\" + +check \"basic-string-interp-triple6\" $\"\"\"this i\s {1}\"\"\" \"this i\s 1\" + +// check nested string with %s +check \"basic-string-interp-triple7\" $\"\"\"x = %s{\"1\"}\"\"\" \"x = 1\" + +// multiline +check \"basic-string-interp-triple8\" + $\"\"\"this +is {1+1}\"\"\" + \"\"\"this +is 2\"\"\" + " + + [] + let ``String interpolation using atomic expression forms`` () = + SimpleCheckTest + """ +let x = 12 +let s = "sixsix" + +check "vcewwei4" $"this is %d{1} + {1+1+3} = 6" "this is 1 + 5 = 6" + +check "vcewwei5" $"this is 0x%08x{x} + {1+1} = 14" "this is 0x0000000c + 2 = 14" + +// Check dot notation +check "vcewwei6" $"this is {s.Length} + {1+1} = 8" "this is 6 + 2 = 8" + +// Check null expression +check "vcewwei8" $"abc{null}def" "abcdef" + +// Check mod operator +check "vcewwei8" $"abc{4%3}def" "abc1def" + + """ + + + [] + let ``String interpolation using nested control flow expressions`` () = + SimpleCheckTest + """ +let x = 12 +let s = "sixsix" + +// Check let expression +check "string-interp-nested7" $"abc {let x = 3 in x + x} def" "abc 6 def" + +// Check if expression (parenthesized) +check "string-interp-nested9" $"abc{(if true then 3 else 4)}def" "abc3def" + +// Check if-then-else expression (un-parenthesized) +check "string-interp-nested10" $"abc{if true then 3 else 4}def" "abc3def" + +// Check two if-then-else expression (un-parenthesized) +check "string-interp-nested11" $"abc{if true then 3 else 4}def{if false then 3 else 4}xyz" "abc3def4xyz" + +// Check two if-then-else expression (un-parenthesized, first split) +check "string-interp-nested12" + $"abc{if true then 3 + else 4}def{if false then 3 else 4}xyz" "abc3def4xyz" + +// Check two if-then-else expression (un-parenthesized, second split) +check "string-interp-nested13" + $"abc{if true then 3 else 4}def{if false then 3 + else 4}xyz" "abc3def4xyz" + +// Check two if-then-else expression (un-parenthesized, both split) +check "string-interp-nested14" + $"abc{if true then 3 + else 4}def{if false then 3 + else 4}xyz" "abc3def4xyz" + +// Check if-then expression (un-parenthesized) +check "string-interp-nested15" $"abc{if true then ()}def" "abcdef" + +// Check two if-then expression (un-parenthesized) +check "string-interp-nested16" $"abc{if true then ()}def{if true then ()}xyz" "abcdefxyz" + +// Check multi-line let with parentheses +check "string-interp-nested17" + $"abc {(let x = 3 + x + x)} def" + "abc 6 def" + +// Check multi-line let without parentheses +check "string-interp-nested18" + $"abc {let x = 3 + x + x} def" + "abc 6 def" + +// Check multi-line let without parentheses (two) +check "string-interp-nested19" + $"abc {let x = 3 + x + x} def {let x = 3 + x + x} xyz" + "abc 6 def 6 xyz" + +// Check while expression (un-parenthesized) +check "vcewweh17" $"abc{while false do ()}def" "abcdef" + + """ + + + + [] + let ``String interpolation using nested string`` () = + SimpleCheckTest + " +// check nested string +check \"vcewweh22m1\" $\"\"\"x = {\"1\"} \"\"\" \"x = 1 \" + +check \"vcewweh22m2\" $\"\"\"x = {$\"\"} \"\"\" \"x = \" + +do + let genreSpecified = true + let getGenre() = \"comedy\" + check \"vcewweh22m6\" $\"\"\"/api/movie/{if not genreSpecified then \"\" else $\"q?genre={getGenre()}\"}\"\"\" \"/api/movie/q?genre=comedy\" + +" + + [] + let ``Triple quote string interpolation using nested string`` () = + SimpleCheckTest + " +do + let itvar=\"i\" + let iterfrom=\"0\" + let iterto=\"100\" + let block= $\"\"\"printf(\"%%d\", {itvar}); + do({itvar});\"\"\" + check \"vcewweh22m7\" $\"\"\" +for({itvar}={iterfrom};{itvar}<{iterto};++{itvar}) {{ + {block} +}}\"\"\" \"\"\" +for(i=0;i<100;++i) { + printf(\"%d\", i); + do(i); +}\"\"\" +" + + [] + let ``Mixed quote string interpolation using nested string`` () = + SimpleCheckTest + " + +check \"vcewweh22n1\" + $\"\"\" + PROCEDURE SEARCH; + BEGIN + END;\"\"\" + \"\"\" + PROCEDURE SEARCH; + BEGIN + END;\"\"\" + +check \"vcewweh22n2\" + $\"\"\" + PROCEDURE SEARCH; + BEGIN + WRITELN({ $\"{21+21}\" }); + END;\"\"\" + \"\"\" + PROCEDURE SEARCH; + BEGIN + WRITELN(42); + END;\"\"\" +" + + [] + let ``String interpolation to FormattableString`` () = + SimpleCheckTest + """ +open System +open System.Globalization + +let fmt (x: FormattableString) = x.ToString() +let fmt_us (x: FormattableString) = x.ToString(CultureInfo("en-US")) +let fmt_de (x: FormattableString) = x.ToString(CultureInfo("de-DE")) + +check "fwejwflpej1" (fmt $"") "" +check "fwejwflpej2" (fmt $"abc") "abc" +check "fwejwflpej3" (fmt $"abc{1}") "abc1" +check "fwejwflpej6" (fmt_us $"abc {30000} def") "abc 30000 def" +check "fwejwflpej7" (fmt_de $"abc {30000} def") "abc 30000 def" +check "fwejwflpej8" (fmt_us $"abc {30000:N2} def") "abc 30,000.00 def" +check "fwejwflpej9" (fmt_de $"abc {30000:N2} def") "abc 30.000,00 def" +check "fwejwflpej10" (fmt_us $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej11" (fmt_us $"abc {30000,-10} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej12" (fmt_us $"abc {30000,10} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej13" (fmt_de $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej14" (fmt_us $"abc {30000:N2} def {40000:N2} hij") "abc 30,000.00 def 40,000.00 hij" +check "fwejwflpej15" (fmt_de $"abc {30000:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" +check "fwejwflpej16" (fmt_de $"abc {30000,10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" +check "fwejwflpej17" (fmt_de $"abc {30000,-10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" + + """ + + [] + let ``String interpolation to IFormattable`` () = + SimpleCheckTest + """ +open System +open System.Globalization + +let fmt (x: IFormattable) = x.ToString() +let fmt_us (x: IFormattable) = x.ToString("", CultureInfo("en-US")) +let fmt_de (x: IFormattable) = x.ToString("", CultureInfo("de-DE")) + +check "fwejwflpej1" (fmt $"") "" +check "fwejwflpej2" (fmt $"abc") "abc" +check "fwejwflpej3" (fmt $"abc{1}") "abc1" +check "fwejwflpej6" (fmt_us $"abc {30000} def") "abc 30000 def" +check "fwejwflpej7" (fmt_de $"abc {30000} def") "abc 30000 def" +check "fwejwflpej8" (fmt_us $"abc {30000:N2} def") "abc 30,000.00 def" +check "fwejwflpej9" (fmt_de $"abc {30000:N2} def") "abc 30.000,00 def" +check "fwejwflpej10" (fmt_us $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej11" (fmt_us $"abc {30000,-10} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej12" (fmt_us $"abc {30000,10} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej13" (fmt_de $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij" +check "fwejwflpej14" (fmt_us $"abc {30000:N2} def {40000:N2} hij") "abc 30,000.00 def 40,000.00 hij" +check "fwejwflpej15" (fmt_de $"abc {30000:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" +check "fwejwflpej16" (fmt_de $"abc {30000,10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" +check "fwejwflpej17" (fmt_de $"abc {30000,-10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij" + + """ + + [] + let ``String interpolation to PrintFormat`` () = + SimpleCheckTest + """ +open System.Text +open Printf + +check "fwejwflpej1" (sprintf $"") "" +check "fwejwflpej2" (sprintf $"abc") "abc" +check "fwejwflpej3" (sprintf $"abc{1}") "abc1" + +let sb = StringBuilder() +bprintf sb $"{0}" +bprintf sb $"abc" +bprintf sb $"abc{1}" +check "fwejwflpej4" (sb.ToString()) "0abcabc1" + + """ + + + [] + let ``String interpolation using .NET Formats`` () = + SimpleCheckTest + """ +check "vcewweh221q" $"abc {1}" "abc 1" +check "vcewweh222w" $"abc {1:N3}" "abc 1.000" +check "vcewweh223e" $"abc {1,10}" "abc 1" +check "vcewweh223r" $"abc {1,-10}" "abc 1 " +check "vcewweh224t" $"abc {1,10:N3}" "abc 1.000" +check "vcewweh224y" $"abc {1,-10:N3}" "abc 1.000 " +check "vcewweh225u" $"abc %d{1}" "abc 1" +check "vcewweh225u" $"abc %5d{1}" "abc 1" +check "vcewweh225u" $"abc %-5d{1}" "abc 1 " + """ + + [] + let ``String interpolation of null`` () = + SimpleCheckTest + """ + +check "vcewweh221q1" $"{null}" "" +check "vcewweh221q2" $"%s{null}" "" +check "vcewweh221q3" $"abc %s{null}" "abc " +check "vcewweh221q4" $"abc %s{null} def" "abc def" + """ + + [] + let ``String interpolation of basic types`` () = + SimpleCheckTest + """ +check "vcewweh221q11" $"{1y}" "1" +check "vcewweh221q12" $"{1uy}" "1" +check "vcewweh221q13" $"{1s}" "1" +check "vcewweh221q14" $"{1us}" "1" +check "vcewweh221q15" $"{1u}" "1" +check "vcewweh221q16" $"{1}" "1" +check "vcewweh221q17" $"{-1}" "-1" +check "vcewweh221q18" $"{1L}" "1" +check "vcewweh221q19" $"{1UL}" "1" +check "vcewweh221q1q" $"{1n}" "1" +check "vcewweh221q1w" $"{1un}" "1" +check "vcewweh221q1e" $"{1.0}" "1" +check "vcewweh221q1r" $"{1.01}" "1.01" +check "vcewweh221q1t" $"{-1.01}" "-1.01" +check "vcewweh221q1y" $"{1I}" "1" +check "vcewweh221q1i" $"{1M}" "1" + +check "vcewweh221q1o" $"%d{1y}" "1" +check "vcewweh221q1p" $"%d{1uy}" "1" +check "vcewweh221q1a" $"%d{1s}" "1" +check "vcewweh221q1s" $"%d{1us}" "1" +check "vcewweh221q1d" $"%d{1u}" "1" +check "vcewweh221q1f" $"%d{1}" "1" +check "vcewweh221q1g" $"%d{-1}" "-1" +check "vcewweh221q1h" $"%d{1L}" "1" +check "vcewweh221q1j" $"%d{1UL}" "1" +check "vcewweh221q1k" $"%d{1n}" "1" +check "vcewweh221q1l" $"%d{1un}" "1" + +check "vcewweh221q1" $"%f{1.0}" "1.000000" + """ + [] + let ``String interpolation using escaped braces`` () = + SimpleCheckTest + """ +check "vcewweh226i" $"{{" "{" +check "vcewweh226o" $"{{{{" "{{" +check "vcewweh226p" $"{{{1}}}" "{1}" +check "vcewweh227a" $"}}" "}" +check "vcewweh227s" $"}}}}" "}}" +check "vcewweh228d" "{{" "{{" +check "vcewweh229f" "}}" "}}" + """ + + [] + let ``String interpolation using verbatim strings`` () = + SimpleCheckTest + """ +check "vcewweh226i" $"{{" "{" +check "vcewweh226o" $"{{{{" "{{" +check "vcewweh226p" $"{{{1}}}" "{1}" +check "vcewweh227a" $"}}" "}" +check "vcewweh227s" $"}}}}" "}}" +check "vcewweh228d" "{{" "{{" +check "vcewweh229f" "}}" "}}" + """ + + + [] + let ``String interpolation using record data`` () = + SimpleCheckTest + """ +type R = { X : int } +type R2 = { X : int ; Y: int } + +// Check record expression (parenthesized) +check "vcewweh18" $"abc{({contents=1}.contents)}def" "abc1def" + +// Check record expression (unparenthesized, spaced) +check "vcewweh19a" $"abc{ {X=1} }def" "abc{ X = 1 }def" + +check "vcewweh19b" $"abc{ {X=1} }def" "abc{ X = 1 }def" + +// Check record expression (unparenthesized, spaced ending in token brace then string hole brace) +check "vcewweh19v" $"abc{ {X=1}}def" "abc{ X = 1 }def" + +// Check thing that is not really a record expression (braces are escaped) +check "vcewweh20" $"abc{{X=1}}def" "abc{X=1}def" + +// Check thing that is not really a record expression (braces are escaped) +check "vcewweh20b" $"abc{{quack=1}}def" "abc{quack=1}def" + +// Check thing that is not really a record expression (braces are escaped) +check "vcewweh21" $"abc{{X=1; Y=2}}def" "abc{X=1; Y=2}def" + + """ + + + [] + let ``String interpolation using printf formats`` () = + SimpleCheckTest + """ +let x = 12 +let s = "sixsix" + +// check %A +check "vcewweh22" $"x = %A{1}" "x = 1" + +// check %d +check "vcewweh22b" $"x = %d{1}" "x = 1" + +// check %x +check "vcewweh22c" $"x = %x{1}" "x = 1" + +// check %o (octal) +check "vcewweh22d" $"x = %o{15}" "x = 17" + +// check %b +check "vcewweh22e" $"x = %b{true}" "x = true" + +// check %s +check "vcewweh22f" $"x = %s{s}" "x = sixsix" + +// check %A of string +check "vcewweh22g" $"x = %A{s}" "x = \"sixsix\"" + +check "vcewweh20" $"x = %A{1}" "x = 1" + + """ + [] + let ``%B fails for langVersion 5.0`` () = + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + """printf "%B" 10""" + [|(FSharpDiagnosticSeverity.Error, 3350, (1, 8, 1, 12), + "Feature 'binary formatting for integers' is not available in F# 5.0. Please use language version 'preview' or greater.")|] + [] + let ``%B succeeds for langVersion preview`` () = + CompilerAssert.CompileExeAndRunWithOptions [| "--langversion:preview" |] """ +let check msg a b = + if a = b then printfn "test case '%s' succeeded" msg else failwithf "test case '%s' failed, expected %A, got %A" msg b a +check "vcewweh22a" $"x = %B{19}" "x = 10011" + """ + + [] + let ``String interpolation using list and array data`` () = + SimpleCheckTest + """ +// check unannotated of list +check "vcewweh22i" $"x = {[0..100]} " "x = [0; 1; 2; ... ] " + +let xs = [0..100] +// check unannotated of list +check "vcewweh22i" $"x = {xs} " "x = [0; 1; 2; ... ] " + +// check %A of list +check "vcewweh22h" $"x = %0A{[0..100]} " "x = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59; 60; 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82; 83; 84; 85; 86; 87; 88; 89; 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; ...] " + +// check unannotated of array +check "vcewweh22j" $"x = {[|0..100|]} " "x = System.Int32[] " + +let arr = [|0..100|] +// check unannotated of array +check "vcewweh22j" $"x = {arr} " "x = System.Int32[] " + +// check %0A of array +check "vcewweh22k" $"x = %0A{[|0..100|]} " "x = [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59; 60; 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82; 83; 84; 85; 86; 87; 88; 89; 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; ...|] " + + """ + + + [] + let ``Quotations of interpolation`` () = + SimpleCheckTest + """ +check "vcewweh1" + ((<@ $"this {1} is 2" @>).ToString().Replace("\r","").Replace("\n","").Replace("\"","")) + "Call (None, PrintFormatToString, [NewObject (PrintfFormat`5, Value (this %P() is 2), NewArray (Object, Call (None, Box, [Value (1)])), Value ())])" + """ + + [] + let ``Quotations in interpolation`` () = + SimpleCheckTest + """ +check "check-quotation1" $"this {<@ 1 @>} is 2" "this Value (1) is 2" + """ + + [] + let ``Object expression in interpolation`` () = + SimpleCheckTest + """ +check "check-object-expression-in-interpolation1" + (let s = "AA" in $"this { {new System.Object() with member x.ToString() = s } } is 2") + "this AA is 2" + """ + + [] + let ``Exception handling in interpolation`` () = + SimpleCheckTest + """ +check "check-object-expression-in-interpolation1" + (let s = "AA" in $"this { try failwith s with _ -> s } is 2") + "this AA is 2" + """ + + [] + let ``String interpolation using anonymous records`` () = + SimpleCheckTest + """ +// Check anonymous record expression (parenthesized) +check "vcewweh23" $"abc{({| A=1 |})}def" "abc{ A = 1 }def" + + """ + + + [] + let ``Basic string interpolation (4.7)`` () = + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:4.7" |] + """ +let x = $"one" + """ + [|(FSharpDiagnosticSeverity.Error, 3350, (2, 9, 2, 15), + "Feature 'string interpolation' is not available in F# 4.7. Please use language version 5.0 or greater.")|] + + + [] + let ``Basic string interpolation negative`` () = + let code = """ +let x1 = $"one %d{System.String.Empty}" // mismatched types +let x2 = $"one %s{1}" // mismatched types +let x3 = $"one %s" // naked percent in interpolated +let x4 = $"one %d" // naked percent in interpolated +let x5 = $"one %A" // naked percent in interpolated +let x6 = $"one %P" // interpolation hole marker in interploation +let x7 = $"one %P()" // interpolation hole marker in interploation +let x8 = $"one %P(){1}" // interpolation hole marker in interploation +let x9 = $"one %f" // naked percent in interpolated +let xa = $"one %d{3:N}" // mix of formats +let xc = $"5%6" // bad F# format specifier +let xe = $"%A{{1}}" // fake expression (delimiters escaped) +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 1, (2, 19, 2, 38), + "The type 'string' is not compatible with any of the types byte,int16,int32,int64,sbyte,uint16,uint32,uint64,nativeint,unativeint, arising from the use of a printf-style format string"); + (FSharpDiagnosticSeverity.Error, 1, (3, 19, 3, 20), + """This expression was expected to have type + 'string' +but here has type + 'int' """); + (FSharpDiagnosticSeverity.Error, 3376, (4, 10, 4, 19), + "Invalid interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'."); + (FSharpDiagnosticSeverity.Error, 3376, (5, 10, 5, 19), + "Invalid interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'."); + (FSharpDiagnosticSeverity.Error, 3376, (6, 10, 6, 19), + "Invalid interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'."); + (FSharpDiagnosticSeverity.Error, 3376, (7, 10, 7, 19), + "Invalid interpolated string. The '%P' specifier may not be used explicitly."); + (FSharpDiagnosticSeverity.Error, 3371, (8, 10, 8, 21), + "Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'"); + (FSharpDiagnosticSeverity.Error, 3371, (9, 10, 9, 24), + "Mismatch in interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'"); + (FSharpDiagnosticSeverity.Error, 3376, (10, 10, 10, 19), + "Invalid interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'."); + (FSharpDiagnosticSeverity.Error, 3376, (11, 10, 11, 24), + "Invalid interpolated string. .NET-style format specifiers such as '{x,3}' or '{x:N5}' may not be mixed with '%' format specifiers.") + (FSharpDiagnosticSeverity.Error, 3376, (12, 10, 12, 16), + "Invalid interpolated string. Bad precision in format specifier") + (FSharpDiagnosticSeverity.Error, 3376, (13, 10, 13, 20), + "Invalid interpolated string. Interpolated strings may not use '%' format specifiers unless each is given an expression, e.g. '%d{1+1}'.") + |] + + let code = """ +let xb = $"{%5d{1:N3}}" // inner error that looks like format specifiers +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 1156, (2, 14, 2, 16), + "This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0o1, 0b1, 1l (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger)."); + (FSharpDiagnosticSeverity.Error, 10, (2, 18, 2, 19), + "Unexpected symbol ':' in expression. Expected '}' or other token."); + (FSharpDiagnosticSeverity.Error, 604, (2, 16, 2, 17), "Unmatched '{'") + |] + + let code = """ +let xd = $"%A{}" // empty expression +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3382, (2, 15, 2, 15), + "Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.") + |] + + let code = """ +let xd = $"%A{ }" // empty expression +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3382, (2, 15, 2, 17), + "Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.") + |] + + [] + let ``String interpolation FormattableString negative`` () = + let code = """ + +open System +let x1 : FormattableString = $"one %d{100}" // no %d in FormattableString +let x2 : FormattableString = $"one %s{String.Empty}" // no %s in FormattableString +let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in FormattableString +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3376, (4, 30, 4, 44), + "Invalid interpolated string. Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{expr}', '{expr,3}' or '{expr:N5}' may be used."); + (FSharpDiagnosticSeverity.Error, 3376, (5, 30, 5, 53), + "Invalid interpolated string. Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{expr}', '{expr,3}' or '{expr:N5}' may be used."); + (FSharpDiagnosticSeverity.Error, 3376, (6, 30, 6, 55), + "Invalid interpolated string. Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{expr}', '{expr,3}' or '{expr:N5}' may be used.")|] + + + [] + let ``String interpolation negative nested in single`` () = + let code = """ + +open System +let s1 = $"123{456}789{"012"}345" +let s2 = $"123{456}789{@"012"}345" +let s3 = $"123{456}789{$"012"}345" +let s4 = $@"123{456}789{"012"}345" +let s5 = @$"123{456}789{"012"}345" +let s6 = $@"123{456}789{@"012"}345" +let s7 = @$"123{456}789{$"012"}345" +let s8 = $@"123{456}789{@$"012"}345" +let s9 = @$"123{456}789{$@"012"}345" +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3373, (4, 24, 4, 25), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (5, 24, 5, 26), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (6, 24, 6, 26), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (7, 25, 7, 26), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (8, 25, 8, 26), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (9, 25, 9, 27), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (10, 25, 10, 27), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (11, 25, 11, 28), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal."); + (FSharpDiagnosticSeverity.Error, 3373, (12, 25, 12, 28), + "Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.")|] + + [] + let ``String interpolation negative nested in triple`` () = + let code = " + +open System +let TripleInTripleInterpolated = $\"\"\"123{456}789{\"\"\"012\"\"\"}345\"\"\" +let TripleInSingleInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\" +let TripleInVerbatimInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\" +let TripleInterpolatedInTripleInterpolated = $\"\"\"123{456}789{$\"\"\"012\"\"\"}345\"\"\" +let TripleInterpolatedInSingleInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\" +let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\" +" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3374, (4, 52, 4, 55), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (5, 50, 5, 53), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (6, 50, 6, 53), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (7, 64, 7, 68), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (8, 62, 8, 66), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (9, 62, 9, 66), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.")|] + + [] + let ``String interpolation negative incomplete string`` () = + let code = """let x1 = $"one %d{System.String.Empty}""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 39), + "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); + (FSharpDiagnosticSeverity.Error, 3379, (1, 38, 1, 39), + "Incomplete interpolated string begun at or before here")|] + + [] + let ``String interpolation negative incomplete string fill`` () = + let code = """let x1 = $"one %d{System.String.Empty""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 38), + "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); + (FSharpDiagnosticSeverity.Error, 3378, (1, 18, 1, 19), + "Incomplete interpolated string expression fill begun at or before here")|] + + [] + let ``String interpolation negative incomplete verbatim string`` () = + let code = """let x1 = @$"one %d{System.String.Empty} """ + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 41), + "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); + (FSharpDiagnosticSeverity.Error, 3380, (1, 39, 1, 40), + "Incomplete interpolated verbatim string begun at or before here")|] + + [] + let ``String interpolation negative incomplete triple quote string`` () = + let code = "let x1 = $\"\"\"one" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Warning, 58, (1, 1, 1, 17), + "Possible incorrect indentation: this token is offside of context started at position (1:1). Try indenting this token further or using standard formatting conventions."); + (FSharpDiagnosticSeverity.Warning, 58, (1, 17, 1, 17), + "Possible incorrect indentation: this token is offside of context started at position (1:1). Try indenting this token further or using standard formatting conventions."); + (FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 17), + "Incomplete structured construct at or before this point in binding"); + (FSharpDiagnosticSeverity.Error, 3381, (1, 10, 1, 14), + "Incomplete interpolated triple-quote string begun at or before here")|] + + [] + let ``String interpolation extra right brace single quote`` () = + let code = "let x1 = $\"}\"" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3383, (1, 10, 1, 14), + "A '}' character must be escaped (by doubling) in an interpolated string.")|] + + [] + let ``String interpolation extra right brace verbatim`` () = + let code = "let x1 = @$\"}\"" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3383, (1, 10, 1, 15), + "A '}' character must be escaped (by doubling) in an interpolated string.")|] + + [] + let ``String interpolation extra right brace triple`` () = + let code = "let x1 = $\"\"\"}\"\"\"" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3383, (1, 10, 1, 18), + "A '}' character must be escaped (by doubling) in an interpolated string.")|] + + [] + let ``String interpolation extra right brace single quote with hole`` () = + let code = "let x1 = $\"{0}}\"" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + code + [|(FSharpDiagnosticSeverity.Error, 3383, (1, 14, 1, 17), + "A '}' character must be escaped (by doubling) in an interpolated string.")|] + + [] + let ``String continuation character gives right ranges`` () = + let code = "let x1 = \"hello \\\n world\", foo" + CompilerAssert.TypeCheckWithErrorsAndOptions [| |] + code + [|(FSharpDiagnosticSeverity.Error, 39, (2, 14, 2, 17), + "The value or constructor 'foo' is not defined. Maybe you want one of the following:\n floor")|] diff --git a/tests/fsharp/Compiler/Language/StructActivePatternTests.fs b/tests/fsharp/Compiler/Language/StructActivePatternTests.fs new file mode 100644 index 00000000000..6107d368ef9 --- /dev/null +++ b/tests/fsharp/Compiler/Language/StructActivePatternTests.fs @@ -0,0 +1,205 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.Diagnostics +open FSharp.Test + +[] +module StructActivePatternTests = + + let private pass = CompilerAssert.PassWithOptions [| "--langversion:preview" |] + let private fail = CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |] + let private run src = CompilerAssert.CompileExeAndRunWithOptions [| "--langversion:preview" |] (""" +let fail msg = + printfn "%s" msg + failwith msg +""" + src) + + [] + let ``Partial active pattern returns Option`1`` () = + pass "let (|Foo|_|) x = None" + + [] + let ``Partial struct active pattern returns ValueOption`1`` () = + pass "[] let (|P1|_|) x = ValueNone" + + [] + let ``StructAttribute can be placed at the active pattern return type annotation`` () = + pass + """ +let (|P1|_|) x: [] _ = ValueNone +let (|P2|_|) x: [] _ = ValueNone + """ + + [] + let ``Partial struct active pattern results can be retrieved`` () = + run """ +[] +type T1 = { v1: int } +and T2 = + | T2C1 of int * string + | T2C2 of T1 * T2 +and [] T3 = { v3: T2 } +and T4() = + let mutable _v4 = { v3 = T2C2({v1=0}, T2C1(1, "hey")) } + member __.v4 with get() = _v4 and set (x) = _v4 <- x + +[] +let (|P1|_|) = + function + | 0 -> ValueNone + | _ -> ValueSome() + +[] +let (|P2|_|) = + function + | "foo" -> ValueNone + | _ -> ValueSome "bar" + +[] +let (|P3|_|) (x: T2) = + match x with + | T2C1(a, b) -> ValueSome(a, b) + | _ -> ValueNone + +[] +let (|P4|_|) (x: T4) = + match x.v4 with + | { v3 = T2C2 ({v1=a}, P3(b, c)) } -> ValueSome (a, b, c) + | _ -> ValueNone + +match 0, 1 with +| P1, _ -> fail "unit" +| _, P1 -> () +| _ -> fail "unit" + +match "foo", "bar" with +| P2 _, _ -> fail "string" +| _, P2("bar") -> () +| _ -> fail "string" + +let t4 = T4() +match t4 with +| P4 (0, 1, "hey") -> () +| _ -> fail "nested" + """ + + [] + let ``[] attribute is rotated to the return value``() = + run + """ +open System + +[] +type MyAttribute() = + inherit Attribute() + +let extract xs = + xs + |> Seq.map (fun x -> x.GetType().Name) + |> List.ofSeq + |> FSharp.Core.String.concat "," + +[] +let Fn () = () + +let method = Fn.GetType() + .DeclaringType + .GetMethod("Fn") + +let ret_attrs = method.ReturnTypeCustomAttributes + .GetCustomAttributes(false) + |> extract + +let binding_attrs = method.GetCustomAttributes(false) + |> extract + +match ret_attrs, binding_attrs with +| "MyAttribute", "" -> () +| _ -> fail $"ret_attrs = {ret_attrs}, binding_attrs = {binding_attrs} method = {method}" + """ + [] + let ``Implicitly-targeted attribute on let binding do not target return``() = + run + """ +open System + +[] +type MyAttribute() = + inherit Attribute() + +let extract xs = + xs + |> Seq.map (fun x -> x.GetType().Name) + |> List.ofSeq + |> FSharp.Core.String.concat "," + +[] +let Fn () = () + +let method = Fn.GetType() + .DeclaringType + .GetMethod("Fn") + +let ret_attrs = method.ReturnTypeCustomAttributes + .GetCustomAttributes(false) + |> extract + +let binding_attrs = method.GetCustomAttributes(false) + |> extract + +match ret_attrs, binding_attrs with +| "", "MyAttribute" -> () +| _ -> fail $"ret_attrs = {ret_attrs}, binding_attrs = {binding_attrs} method = {method}" + """ + + +// negative tests + + [] + let ``Struct active pattern (no preview)`` () = + CompilerAssert.TypeCheckWithErrorsAndOptions [| |] + """ +[] +let (|Foo|_|) x = ValueNone + """ + [|(FSharpDiagnosticSeverity.Error, 3350, (2, 1, 3, 16), + "Feature 'struct representation for active patterns' is not available in F# 5.0. Please use language version 'preview' or greater.")|] + + [] + let ``StructAttribute must explicitly target active pattern return value`` () = + fail + """ +[] +let (|Foo|_|) x = ValueNone +""" + [|(FSharpDiagnosticSeverity.Error, 842, (2, 3, 2, 9), + "This attribute is not valid for use on this language element"); + (FSharpDiagnosticSeverity.Error, 1, (2, 1, 3, 16), + "This expression was expected to have type + ''a option' +but here has type + ''b voption' ")|] + + [] + let ``StructAttribute not allowed on other bindings than partial active pattern definitions`` () = + fail + """ +[] +let x = 1 + +[] +let f x = x + +[] +let (|A|B|) x = A +""" + [|(FSharpDiagnosticSeverity.Error, 3385, (2, 1, 3, 6), + "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions") + (FSharpDiagnosticSeverity.Error, 3385, (5, 1, 6, 8), + "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions") + (FSharpDiagnosticSeverity.Error, 3385, (8, 1, 9, 14), + "The use of '[]' on values, functions and methods is only allowed on partial active pattern definitions")|] + diff --git a/tests/fsharp/Compiler/Language/TypeAttributeTests.fs b/tests/fsharp/Compiler/Language/TypeAttributeTests.fs index 44a1cac08b7..23d09d9e706 100644 --- a/tests/fsharp/Compiler/Language/TypeAttributeTests.fs +++ b/tests/fsharp/Compiler/Language/TypeAttributeTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module TypeAttributeTests = @@ -23,7 +24,7 @@ open System type String with member this.test = 42 """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 3246 (4, 1, 4, 15) "Attributes cannot be applied to type extensions." @@ -38,7 +39,7 @@ type Point = {x:int; y:int} type Point with member this.test = 42 """ - FSharpErrorSeverity.Error + FSharpDiagnosticSeverity.Error 3246 (4, 1, 4, 15) "Attributes cannot be applied to type extensions." diff --git a/tests/fsharp/Compiler/Language/UIntTests.fs b/tests/fsharp/Compiler/Language/UIntTests.fs new file mode 100644 index 00000000000..05bf78bbebf --- /dev/null +++ b/tests/fsharp/Compiler/Language/UIntTests.fs @@ -0,0 +1,11 @@ +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test + +[] +module UIntTests = + let ``uint type abbreviation works`` () = + let src = "let x = uint 12" + let expectedErrors = [||] + CompilerAssert.TypeCheckWithErrors src expectedErrors diff --git a/tests/fsharp/Compiler/Language/WitnessTests.fs b/tests/fsharp/Compiler/Language/WitnessTests.fs new file mode 100644 index 00000000000..74e7cba55f4 --- /dev/null +++ b/tests/fsharp/Compiler/Language/WitnessTests.fs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler +open TestFramework + +#if !NETCOREAPP + +[] +module WitnessTests = + + [] + let ``Witness expressions are created as a result of compiling the type provider tests`` () = + let dir = getTestsDirectory __SOURCE_DIRECTORY__ "../../typeProviders/helloWorld" + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> asExe + |> ignoreWarnings + |> withLangVersion50 + |> compile + |> shouldSucceed + |> ignore +#endif + + diff --git a/tests/fsharp/Compiler/Libraries/Core/Collections/CollectionTests.fs b/tests/fsharp/Compiler/Libraries/Core/Collections/CollectionTests.fs new file mode 100644 index 00000000000..934936fd0c3 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Collections/CollectionTests.fs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Array2D Tests`` = + + [] + let ``Iter should not throw on non-zero based 2D arrays``() = + // Regression for FSHARP1.0: 5919 + // bug in array2D functions would cause iter to blow up + + let a = Array2D.createBased 1 5 10 10 0.0 + let testDelegate = TestDelegate (fun _ -> a |> Array2D.iter (printf "%f")) + + Assert.DoesNotThrow testDelegate + + [] + let ``Iteri should not throw on non-zero based 2D arrays``() = + // Regression for FSHARP1.0: 5919 + // bug in array2D functions would cause iteri to blow up + + let a = Array2D.createBased 1 5 10 10 0.0 + let testDelegate = TestDelegate (fun _ -> a |> Array2D.iteri (fun _ _ x -> printf "%f" x)) + + Assert.DoesNotThrow testDelegate \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Collections/IEnumerableTests.fs b/tests/fsharp/Compiler/Libraries/Core/Collections/IEnumerableTests.fs new file mode 100644 index 00000000000..d9671884293 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Collections/IEnumerableTests.fs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``IEnumerable Tests`` = + + // Regression test for FSHARP1.0:4726 + // Makes sure that the .Dispose() method, if available, in invoked on IEnumerable + + let mutable dispose_called_in_E = 0 // we expect this to be incremented 3 times + let mutable dispose_called_in_C = 0 // we expect this to be incremented once (=this is what the bug was about, i.e. .Dispose() was never invoked) + + type E(_c:int) = class + interface System.IDisposable with + member _.Dispose () = dispose_called_in_E <- dispose_called_in_E + 1 + end + + type C() = class + let mutable i = 0 + interface System.Collections.IEnumerator with + member _.Current with get () = new E(i) :> obj + member _.MoveNext () = + i <- i+1 + i<4 + member _.Reset () = i <- 0 + interface System.Collections.IEnumerable with + member x.GetEnumerator () = x :> System.Collections.IEnumerator + + interface System.IDisposable with + member _.Dispose () = dispose_called_in_C <- dispose_called_in_C + 1 + end + end + + [] + let ``Dispose``() = + let _ = Seq.cast (new C()) |> Seq.map (fun x -> use o = x; + o) |> Seq.length + + Assert.areEqual 3 dispose_called_in_E + Assert.areEqual 1 dispose_called_in_C \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Collections/ListTests.fs b/tests/fsharp/Compiler/Libraries/Core/Collections/ListTests.fs new file mode 100644 index 00000000000..626f9c6e2c0 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Collections/ListTests.fs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Compiler.Diagnostics + +[] +module ``List Tests`` = + + [] + let ``List hd should not exist``() = + // Regression test for FSharp1.0:5641 + // Title: List.hd/tl --> List.head/tail + + CompilerAssert.TypeCheckSingleError + """ +List.hd [1] |> ignore + """ + FSharpDiagnosticSeverity.Error + 39 + (2, 6, 2, 8) + "The value, constructor, namespace or type 'hd' is not defined." + + + + [] + let ``List tl should not exist``() = + // Regression test for FSharp1.0:5641 + // Title: List.hd/tl --> List.head/tail + + CompilerAssert.TypeCheckSingleError + """ +List.tl [1] |> ignore + """ + FSharpDiagnosticSeverity.Error + 39 + (2, 6, 2, 8) + "The value, constructor, namespace or type 'tl' is not defined." + + [] + let ``List head of empty list``() = + let testDelegate = TestDelegate (fun _ -> (List.head [] |> ignore)) + + Assert.Throws testDelegate |> ignore + + [] + let ``List tail of empty list``() = + let testDelegate = TestDelegate (fun _ -> (List.tail [] |> ignore)) + + Assert.Throws testDelegate |> ignore + + [] + let ``List head and tail``() = + Assert.areEqual 1 (List.head [1 .. 10]) + Assert.areEqual "a" (List.head ["a"]) + Assert.areEqual [2 .. 10] (List.tail [1 .. 10]) + Assert.areEqual [] (List.tail [1]) + Assert.areEqual (List.head (List.tail ['a'; 'a'])) (List.head ['a'; 'a']) diff --git a/tests/fsharp/Compiler/Libraries/Core/Collections/MapTests.fs b/tests/fsharp/Compiler/Libraries/Core/Collections/MapTests.fs new file mode 100644 index 00000000000..a0418bb000b --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Collections/MapTests.fs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Map Tests`` = + + [] + let ``Equality should be implemented on map``() = + // Dev11:19569 - this used to throw an ArgumentException saying Object didn't implement IComparable + + let m = Map.ofArray [| 1, obj() |] + let testDelegate = TestDelegate (fun _ -> (m = m) |> ignore) + + Assert.DoesNotThrow testDelegate \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/ExtraTopLevelOperators/DictionaryTests.fs b/tests/fsharp/Compiler/Libraries/Core/ExtraTopLevelOperators/DictionaryTests.fs new file mode 100644 index 00000000000..d52624ee01c --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/ExtraTopLevelOperators/DictionaryTests.fs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test + +module ``Dictionary Tests`` = + + [] + let ``Assigning to dictionary should compile``() = + // Regression test for FSHARP1.0:5365 + + CompilerAssert.Pass + """ +module N.M + + open System + open System.Collections.Generic + + type ICloneable<'a> = + abstract Clone : unit -> 'a + + type DictionaryFeature<'key> (dict: IDictionary<'key, int>) = + member this.Add key value = + dict.[key] <- value + """ + + [] + let ``Assigning to dictionary with type constraint should compile``() = + // Regression test for FSHARP1.0:5365 + // Used to give error: value must be local and mutable in order to mutate the contents of a value type, e.g. 'let mutable x = ...' + + CompilerAssert.Pass + """ +module N.M + + open System + open System.Collections.Generic + + type ICloneable<'a> = + abstract Clone : unit -> 'a + + type DictionaryFeature<'key, 'dict when 'dict :> IDictionary<'key, int> and 'dict :> ICloneable<'dict>> (dict: 'dict) = + member this.Add key value = + dict.[key] <- value + """ diff --git a/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/CastToUnitsTests.fs b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/CastToUnitsTests.fs new file mode 100644 index 00000000000..be85ccd4092 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/CastToUnitsTests.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test + +[] +module ``Cast to Units Tests`` = + + [] + let ``Casting to Measures should compile``() = + CompilerAssert.PassWithOptions [| "--langversion:preview" |] + """ +module M + +open Microsoft.FSharp.Core.LanguagePrimitives + +[] +type M + +let r1 = SByteWithMeasure 1y + 2y +let r2 = Int16WithMeasure 2s - 2s +let r3 = Int32WithMeasure 3 * 3 +let r4 = Int64WithMeasure 5L / 5L +let r5a = FloatWithMeasure 11.11 + 1.1 +let r5b = FloatWithMeasure 0x0000000000000010LF + 0x0000000000000001LF +let r6a = Float32WithMeasure 22.22f - 11.11f +let r6b = Float32WithMeasure 22.22F - 11.11F +let r6c = Float32WithMeasure 0x00000010lf - 0x00000001lf +let r7a = DecimalWithMeasure 33.33M * 44.44M +let r7b = DecimalWithMeasure 33.33m * 44.44m +let r8 = ByteWithMeasure 1uy + 2uy +let r9 = UInt16WithMeasure 1us + 2us +let r10a = UInt32WithMeasure 1u + 2u +let r10b = UInt32WithMeasure 1ul + 2ul +let r11 = UInt64WithMeasure 1UL + 2UL +let r12 = IntPtrWithMeasure 1n + 2n +let r13 = UIntPtrWithMeasure 1un + 2un + """ diff --git a/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/ComparisonTests.fs b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/ComparisonTests.fs new file mode 100644 index 00000000000..e3b5abf34ff --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/ComparisonTests.fs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test + +[] +module ``Comparison Tests`` = + + type 'a www = W of 'a + + [] + let ``Comparisons with wrapped NaN``() = + // Regression test for FSHARP1.0:5640 + // This is a sanity test: more coverage in FSHARP suite... + + Assert.IsFalse (W System.Double.NaN = W System.Double.NaN) + Assert.IsTrue ((W System.Double.NaN).Equals(W System.Double.NaN)) + Assert.areEqual (compare (W System.Double.NaN) (W System.Double.NaN)) 0 + + [] + let ``Comparisons with wrapped NaN in FSI``() = + // Regression test for FSHARP1.0:5640 + // This is a sanity test: more coverage in FSHARP suite... + + CompilerAssert.RunScriptWithOptions [| "--langversion:5.0" |] + """ +type 'a www = W of 'a + +let assertTrue a = + if (not a) then failwithf "Expected true, but found false." + () + +let p = W System.Double.NaN = W System.Double.NaN +let q = (W System.Double.NaN).Equals(W System.Double.NaN) +let z = compare (W System.Double.NaN) (W System.Double.NaN) + +assertTrue (not p) +assertTrue q +assertTrue (z = 0) + """ + [] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/StringFormatTests.fs b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/StringFormatTests.fs new file mode 100644 index 00000000000..46380acecde --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/LanguagePrimitives/StringFormatTests.fs @@ -0,0 +1,207 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test + +[] +module ``String Format Tests`` = + + [] + let ``sprintf with %d format specifier``() = + // Regression test for FSHARP1.0:4120 + // format specifier %d does not work correctly with UInt64 values + + Assert.areEqual (sprintf "%d" System.UInt64.MaxValue) "18446744073709551615" + Assert.areEqual (sprintf "%d" System.UInt64.MinValue) "0" + Assert.areEqual (sprintf "%d" System.UInt32.MaxValue) "4294967295" + Assert.areEqual (sprintf "%d" System.UInt32.MinValue) "0" + Assert.areEqual (sprintf "%d" System.UInt16.MaxValue) "65535" + Assert.areEqual (sprintf "%d" System.UInt16.MinValue) "0" + Assert.areEqual (sprintf "%d" System.Byte.MaxValue) "255" + Assert.areEqual (sprintf "%d" System.Byte.MinValue) "0" + Assert.areEqual (sprintf "%d" System.Int64.MaxValue) "9223372036854775807" + Assert.areEqual (sprintf "%d" System.Int64.MinValue) "-9223372036854775808" + Assert.areEqual (sprintf "%d" System.Int32.MaxValue) "2147483647" + Assert.areEqual (sprintf "%d" System.Int32.MinValue) "-2147483648" + Assert.areEqual (sprintf "%d" System.Int16.MaxValue) "32767" + Assert.areEqual (sprintf "%d" System.Int16.MinValue) "-32768" + Assert.areEqual (sprintf "%d" System.SByte.MaxValue) "127" + Assert.areEqual (sprintf "%d" System.SByte.MinValue) "-128" + Assert.areEqual (sprintf "%d" 1un) "1" + Assert.areEqual (sprintf "%d" -1n) "-1" + + [] + let ``sprintf with %i format specifier``() = + // Regression test for FSHARP1.0:4120 + // format specifier %i does not work correctly with UInt64 values + + Assert.areEqual (sprintf "%i" System.UInt64.MaxValue) "18446744073709551615" + Assert.areEqual (sprintf "%i" System.UInt64.MinValue) "0" + Assert.areEqual (sprintf "%i" System.UInt32.MaxValue) "4294967295" + Assert.areEqual (sprintf "%i" System.UInt32.MinValue) "0" + Assert.areEqual (sprintf "%i" System.UInt16.MaxValue) "65535" + Assert.areEqual (sprintf "%i" System.UInt16.MinValue) "0" + Assert.areEqual (sprintf "%i" System.Byte.MaxValue) "255" + Assert.areEqual (sprintf "%i" System.Byte.MinValue) "0" + Assert.areEqual (sprintf "%i" System.Int64.MaxValue) "9223372036854775807" + Assert.areEqual (sprintf "%i" System.Int64.MinValue) "-9223372036854775808" + Assert.areEqual (sprintf "%i" System.Int32.MaxValue) "2147483647" + Assert.areEqual (sprintf "%i" System.Int32.MinValue) "-2147483648" + Assert.areEqual (sprintf "%i" System.Int16.MaxValue) "32767" + Assert.areEqual (sprintf "%i" System.Int16.MinValue) "-32768" + Assert.areEqual (sprintf "%i" System.SByte.MaxValue) "127" + Assert.areEqual (sprintf "%i" System.SByte.MinValue) "-128" + Assert.areEqual (sprintf "%i" 1un) "1" + Assert.areEqual (sprintf "%i" -1n) "-1" + + [] + let ``sprintf with %u format specifier``() = + // Regression test for FSHARP1.0:4120 + // format specifier %u does not work correctly with UInt64 values + + Assert.areEqual (sprintf "%u" System.UInt64.MaxValue) "18446744073709551615" + Assert.areEqual (sprintf "%u" System.UInt64.MinValue) "0" + Assert.areEqual (sprintf "%u" System.UInt32.MaxValue) "4294967295" + Assert.areEqual (sprintf "%u" System.UInt32.MinValue) "0" + Assert.areEqual (sprintf "%u" System.UInt16.MaxValue) "65535" + Assert.areEqual (sprintf "%u" System.UInt16.MinValue) "0" + Assert.areEqual (sprintf "%u" System.Byte.MaxValue) "255" + Assert.areEqual (sprintf "%u" System.Byte.MinValue) "0" + Assert.areEqual (sprintf "%u" System.Int64.MaxValue) "9223372036854775807" + Assert.areEqual (sprintf "%u" System.Int64.MinValue) "9223372036854775808" + Assert.areEqual (sprintf "%u" System.Int32.MaxValue) "2147483647" + Assert.areEqual (sprintf "%u" System.Int32.MinValue) "2147483648" + Assert.areEqual (sprintf "%u" System.Int16.MaxValue) "32767" + Assert.areEqual (sprintf "%u" System.Int16.MinValue) "32768" + Assert.areEqual (sprintf "%u" System.SByte.MaxValue) "127" + Assert.areEqual (sprintf "%u" System.SByte.MinValue) "128" + Assert.areEqual (sprintf "%u" 1un) "1" + Assert.areEqual (sprintf "%u" -1n) (if System.IntPtr.Size = 4 then "4294967295" else "18446744073709551615") + + [] + let ``string constructor``() = + // Regression test for FSHARP1.0:5894 + + Assert.areEqual (string 1.0f) "1" + Assert.areEqual (string 1.00001f) "1.00001" + Assert.areEqual (string -1.00001f) "-1.00001" + Assert.areEqual (string 1.0) "1" + Assert.areEqual (string 1.00001) "1.00001" + Assert.areEqual (string -1.00001) "-1.00001" + Assert.areEqual (string System.SByte.MaxValue) "127" + Assert.areEqual (string System.SByte.MinValue) "-128" + Assert.areEqual (string 0y) "0" + Assert.areEqual (string -1y) "-1" + Assert.areEqual (string 1y) "1" + Assert.areEqual (string System.Byte.MaxValue) "255" + Assert.areEqual (string System.Byte.MinValue) "0" + Assert.areEqual (string 0uy) "0" + Assert.areEqual (string 1uy) "1" + Assert.areEqual (string System.Int16.MaxValue) "32767" + Assert.areEqual (string System.Int16.MinValue) "-32768" + Assert.areEqual (string 0s) "0" + Assert.areEqual (string -10s) "-10" + Assert.areEqual (string 10s) "10" + Assert.areEqual (string System.UInt16.MaxValue) "65535" + Assert.areEqual (string System.UInt16.MinValue) "0" + Assert.areEqual (string 0us) "0" + Assert.areEqual (string 110us) "110" + Assert.areEqual (string System.Int32.MaxValue) "2147483647" + Assert.areEqual (string System.Int32.MinValue) "-2147483648" + Assert.areEqual (string 0) "0" + Assert.areEqual (string -10) "-10" + Assert.areEqual (string 10) "10" + Assert.areEqual (string System.UInt32.MaxValue) "4294967295" + Assert.areEqual (string System.UInt32.MinValue) "0" + Assert.areEqual (string 0u) "0" + Assert.areEqual (string 10u) "10" + Assert.areEqual (string System.Int64.MaxValue) "9223372036854775807" + Assert.areEqual (string System.Int64.MinValue) "-9223372036854775808" + Assert.areEqual (string 0L) "0" + Assert.areEqual (string -10L) "-10" + Assert.areEqual (string 10L) "10" + Assert.areEqual (string System.UInt64.MaxValue) "18446744073709551615" + Assert.areEqual (string System.UInt64.MinValue) "0" + Assert.areEqual (string 0UL) "0" + Assert.areEqual (string 10UL) "10" + Assert.areEqual (string System.Decimal.MaxValue) "79228162514264337593543950335" + Assert.areEqual (string System.Decimal.MinValue) "-79228162514264337593543950335" + Assert.areEqual (string System.Decimal.Zero) "0" + Assert.areEqual (string 12345678M) "12345678" + Assert.areEqual (string -12345678M) "-12345678" + Assert.areEqual (string -infinity) "-Infinity" + Assert.areEqual (string infinity) "Infinity" + Assert.areEqual (string nan) "NaN" + Assert.areEqual (string -infinityf) "-Infinity" + Assert.areEqual (string infinityf) "Infinity" + Assert.areEqual (string nanf) "NaN" + Assert.areEqual (string (new System.Guid("210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0"))) "210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0" + + [] + let ``string constructor in FSI``() = + // Regression test for FSHARP1.0:5894 + + CompilerAssert.RunScriptWithOptions [| "--langversion:5.0" |] + """ +let assertEqual a b = + if a <> b then failwithf "Expected '%s', but got '%s'" a b + () + +assertEqual (string 1.0f) "1" +assertEqual (string 1.00001f) "1.00001" +assertEqual (string -1.00001f) "-1.00001" +assertEqual (string 1.0) "1" +assertEqual (string 1.00001) "1.00001" +assertEqual (string -1.00001) "-1.00001" +assertEqual (string System.SByte.MaxValue) "127" +assertEqual (string System.SByte.MinValue) "-128" +assertEqual (string 0y) "0" +assertEqual (string -1y) "-1" +assertEqual (string 1y) "1" +assertEqual (string System.Byte.MaxValue) "255" +assertEqual (string System.Byte.MinValue) "0" +assertEqual (string 0uy) "0" +assertEqual (string 1uy) "1" +assertEqual (string System.Int16.MaxValue) "32767" +assertEqual (string System.Int16.MinValue) "-32768" +assertEqual (string 0s) "0" +assertEqual (string -10s) "-10" +assertEqual (string 10s) "10" +assertEqual (string System.UInt16.MaxValue) "65535" +assertEqual (string System.UInt16.MinValue) "0" +assertEqual (string 0us) "0" +assertEqual (string 110us) "110" +assertEqual (string System.Int32.MaxValue) "2147483647" +assertEqual (string System.Int32.MinValue) "-2147483648" +assertEqual (string 0) "0" +assertEqual (string -10) "-10" +assertEqual (string 10) "10" +assertEqual (string System.UInt32.MaxValue) "4294967295" +assertEqual (string System.UInt32.MinValue) "0" +assertEqual (string 0u) "0" +assertEqual (string 10u) "10" +assertEqual (string System.Int64.MaxValue) "9223372036854775807" +assertEqual (string System.Int64.MinValue) "-9223372036854775808" +assertEqual (string 0L) "0" +assertEqual (string -10L) "-10" +assertEqual (string 10L) "10" +assertEqual (string System.UInt64.MaxValue) "18446744073709551615" +assertEqual (string System.UInt64.MinValue) "0" +assertEqual (string 0UL) "0" +assertEqual (string 10UL) "10" +assertEqual (string System.Decimal.MaxValue) "79228162514264337593543950335" +assertEqual (string System.Decimal.MinValue) "-79228162514264337593543950335" +assertEqual (string System.Decimal.Zero) "0" +assertEqual (string 12345678M) "12345678" +assertEqual (string -12345678M) "-12345678" +assertEqual (string -infinity) "-Infinity" +assertEqual (string infinity) "Infinity" +assertEqual (string nan) "NaN" +assertEqual (string -infinityf) "-Infinity" +assertEqual (string infinityf) "Infinity" +assertEqual (string nanf) "NaN" +assertEqual (string (new System.Guid("210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0"))) "210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0" + """ + [] diff --git a/tests/fsharp/Compiler/Libraries/Core/NativeInterop/StackallocTests.fs b/tests/fsharp/Compiler/Libraries/Core/NativeInterop/StackallocTests.fs new file mode 100644 index 00000000000..1e244b53aa5 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/NativeInterop/StackallocTests.fs @@ -0,0 +1,187 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open FSharp.Compiler.Diagnostics + +#nowarn "9" + +[] +module ``Stackalloc Tests`` = + + type E = | A = 1 + | B = 2 + + [] + let ``Stackalloc of DateTime``() = + let data = NativeInterop.NativePtr.stackalloc 100 + let now = System.DateTime.Now + for i = 0 to 99 do + NativeInterop.NativePtr.set data i now + for i = 0 to 99 do + Assert.areEqual (NativeInterop.NativePtr.get data i) now + + let later = now.AddDays 1. + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + datai <- later + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + Assert.areEqual datai later + + [] + let ``Stackalloc of enum``() = + let data = NativeInterop.NativePtr.stackalloc 10 + + for i = 0 to 9 do + NativeInterop.NativePtr.set data i (if (i % 2)=0 then E.A else E.B) + + for i = 0 to 9 do + let expected = if (i % 2) = 0 then E.A else E.B + Assert.areEqual (NativeInterop.NativePtr.get data i) expected + + for i = 0 to 9 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + datai <- (if (i % 2)=1 then E.A else E.B) + + for i = 0 to 9 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + let expected = if (i % 2)=1 then E.A else E.B + Assert.areEqual datai expected + + [] + let ``Stackalloc of imported enum``() = + Assert.DoesNotThrow (TestDelegate (fun () -> + NativeInterop.NativePtr.stackalloc 1 |> ignore)) + + [] + let ``Stackalloc of imported struct``() = + Assert.DoesNotThrow (TestDelegate (fun () -> + NativeInterop.NativePtr.stackalloc 1 |> ignore)) + + [] + let ``Stackalloc of imported class``() = + CompilerAssert.TypeCheckSingleError + """ +#nowarn "9" + +let _ = NativeInterop.NativePtr.stackalloc 1 + """ + FSharpDiagnosticSeverity.Error + 1 + (4, 9, 4, 43) + "A generic construct requires that the type 'System.Object' is an unmanaged type" + + [] + let ``Stackalloc of imported interface``() = + CompilerAssert.TypeCheckSingleError + """ +#nowarn "9" + +let _ = NativeInterop.NativePtr.stackalloc 1 + """ + FSharpDiagnosticSeverity.Error + 1 + (4, 9, 4, 43) + "A generic construct requires that the type 'System.Collections.IEnumerable' is an unmanaged type" + + [] + let ``Stackalloc of imported delegate``() = + CompilerAssert.TypeCheckSingleError + """ +#nowarn "9" + +let _ = NativeInterop.NativePtr.stackalloc 1 + """ + FSharpDiagnosticSeverity.Error + 1 + (4, 9, 4, 43) + "A generic construct requires that the type 'System.EventHandler' is an unmanaged type" + + [] + let ``Stackalloc of int``() = + let data = NativeInterop.NativePtr.stackalloc 100 + + for i = 0 to 99 do + NativeInterop.NativePtr.set data i (i*i) + + for i = 0 to 99 do + Assert.areEqual (NativeInterop.NativePtr.get data i) (i*i) + + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + datai <- 1-i + + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + Assert.areEqual datai (1-i) + + [] + let ``Stackalloc of int64``() = + let data = NativeInterop.NativePtr.stackalloc 100 + + for i = 0 to 99 do + NativeInterop.NativePtr.set data i (int64 (i*i)) + for i = 0 to 99 do + Assert.areEqual (NativeInterop.NativePtr.get data i) (int64 (i*i)) + + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + datai <- int64 (1-i) + + for i = 0 to 99 do + let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) + Assert.areEqual datai (int64 (1-i)) + + [] + let ``Stackalloc of managed class``() = + CompilerAssert.TypeCheckSingleError + """ +#nowarn "9" + +type C() = + class + member _.M = 10 + member _.N(x) = x + 1 + end + +let _ = NativeInterop.NativePtr.stackalloc 1 + """ + FSharpDiagnosticSeverity.Error + 1 + (10, 9, 10, 43) + "A generic construct requires that the type 'C' is an unmanaged type" + + [] + let ``Stackalloc of managed record``() = + CompilerAssert.TypeCheckSingleError + """ +#nowarn "9" + +type R = { A : int } + +let _ = NativeInterop.NativePtr.stackalloc 1 + """ + FSharpDiagnosticSeverity.Error + 1 + (6, 9, 6, 43) + "A generic construct requires that the type 'R' is an unmanaged type" + + [] + let ``Stackalloc zero-size``() = + // Regression test for FSHARP1.0: + // stackalloc 0 + + let testDelegate = TestDelegate (fun () -> + // check stackalloc 0 -- ok + let data = NativeInterop.NativePtr.stackalloc 0 + + // The returned pointer is undefined + // No allocation should happen + let _ = NativeInterop.NativePtr.toNativeInt data + + ()) + + Assert.DoesNotThrow testDelegate \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs new file mode 100644 index 00000000000..ca2f753de4e --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/AbsTests.fs @@ -0,0 +1,94 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.Diagnostics +open FSharp.Test + +[] +module ``Abs Tests`` = + + [] + let ``Abs of signed integral types``() = + // Regression test for FSHARP1.0:3470 - exception on abs of native integer + + Assert.areEqual (abs -1y) 1y // signed byte + Assert.areEqual (abs -1s) 1s // int16 + Assert.areEqual (abs -1l) 1l // int32 + Assert.areEqual (abs -1n) 1n // nativeint + Assert.areEqual (abs -1L) 1L // int64 + Assert.areEqual (abs -1I) 1I // bigint + + [] + let ``Abs of byte``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1uy |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'byte' does not support the operator 'Abs'" + + [] + let ``Abs of uint16``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1us |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint16' does not support the operator 'Abs'" + + [] + let ``Abs of uint32``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1ul |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint32' does not support the operator 'Abs'" + + CompilerAssert.TypeCheckSingleError + """ +abs -1u |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 8) + "The type 'uint32' does not support the operator 'Abs'" + + [] + let ``Abs of unativeint``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1un |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'unativeint' does not support the operator 'Abs'" + + [] + let ``Abs of uint64``() = + CompilerAssert.TypeCheckSingleError + """ +abs -1uL |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'Abs'" + + CompilerAssert.TypeCheckSingleError + """ +abs -1UL |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'Abs'" \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs new file mode 100644 index 00000000000..df5bc326025 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/CastTests.fs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test +open System + +[] +module ``Cast Tests`` = + + [] + let ``Cast precedence over expression forms``() = + // Regression test for FSHARP1.0:1247 + // Precedence of type annotations :> and :?> over preceeding expression forms, e.g. if-then-else etc. + + Assert.IsInstanceOf (2 :> Object) + Assert.IsInstanceOf [(2 :> Object)] + Assert.IsInstanceOf [2 :> Object] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs new file mode 100644 index 00000000000..e809fafa937 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.Diagnostics +open FSharp.Test + +[] +module ``Hash Tests`` = + + [] + let ``Hash of function values``() = + // Regression test for FSHARP1.0:5436 + // You should not be able to hash F# function values + // Note: most positive cases already covered under fsharp\typecheck\sigs + // I'm adding this simple one since I did not see it there. + + CompilerAssert.TypeCheckSingleError + """ +hash id |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 8) + "The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type" + + [] + let ``Unchecked hash of function values``() = + // Regression test for FSHARP1.0:5436 + // You should not be able to hash F# function values + // Note: most positive cases already covered under fsharp\typecheck\sigs + // I'm adding this simple one since I did not see it there. + + // This is ok (unchecked) + CompilerAssert.TypeCheckWithErrors + """ +Unchecked.hash id |> ignore + """ + [||] \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs new file mode 100644 index 00000000000..4bdb77bca28 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/PowTests.fs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Pow Tests`` = + + type T() = + static let mutable m = false + static member Pow (g: T, _: float) = + m <- true + g + static member Check() = m + + [] + let ``Pow of custom type``() = + // Regression test for FSHARP1.0:4487 + // Feature request: loosen Pow operator constraints + + let t = T() + let _ = t ** 3. + + Assert.IsTrue (T.Check()) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs new file mode 100644 index 00000000000..bdb8e321823 --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/RoundTests.fs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Round Tests`` = + + [] + let ``Round of integers``() = + for i in [1 .. 10000] do + Assert.areEqual (i |> float |> round) (float i) + Assert.areEqual (i |> float32 |> round) (float32 i) + Assert.areEqual (i |> decimal |> round) (decimal i) + + [] + let ``Round of floats``() = + // Round down + Assert.areEqual (round 1.1) 1.0 + Assert.areEqual (round 1.2) 1.0 + Assert.areEqual (round 1.3) 1.0 + Assert.areEqual (round 1.4) 1.0 + Assert.areEqual (round 1.1f) 1.0f + Assert.areEqual (round 1.2f) 1.0f + Assert.areEqual (round 1.3f) 1.0f + Assert.areEqual (round 1.4f) 1.0f + Assert.areEqual (round 1.1m) 1.0m + Assert.areEqual (round 1.2m) 1.0m + Assert.areEqual (round 1.3m) 1.0m + Assert.areEqual (round 1.4m) 1.0m + + // Round down + Assert.areEqual (round 1.6) 2.0 + Assert.areEqual (round 1.7) 2.0 + Assert.areEqual (round 1.8) 2.0 + Assert.areEqual (round 1.9) 2.0 + Assert.areEqual (round 1.6f) 2.0f + Assert.areEqual (round 1.7f) 2.0f + Assert.areEqual (round 1.8f) 2.0f + Assert.areEqual (round 1.9f) 2.0f + Assert.areEqual (round 1.6m) 2.0m + Assert.areEqual (round 1.7m) 2.0m + Assert.areEqual (round 1.8m) 2.0m + Assert.areEqual (round 1.9m) 2.0m + + // Midpoint rounding. If between two numbers, round to the 'even' one. + Assert.areEqual (round 1.5 ) 2.0 + Assert.areEqual (round 1.5f) 2.0f + Assert.areEqual (round 1.5m) 2.0m + Assert.areEqual (round 2.5 ) 2.0 + Assert.areEqual (round 2.5f) 2.0f + Assert.areEqual (round 2.5m) 2.0m + + // If not midpoint, round to nearest as usual + Assert.areEqual (round 2.500001 ) 3.0 + Assert.areEqual (round 2.500001f) 3.0f + Assert.areEqual (round 2.500001m) 3.0m \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs new file mode 100644 index 00000000000..2c67b1d1b8d --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/SignTests.fs @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Compiler.Diagnostics +open FSharp.Test + +[] +module ``Sign Tests`` = + + [] + let ``Sign of signed types``() = + Assert.areEqual (sign 1y) 1 // byte + Assert.areEqual (sign 1s) 1 // int16 + Assert.areEqual (sign 1) 1 // int32 + Assert.areEqual (sign 1L) 1 // int64 + Assert.areEqual (sign 1.0f) 1 // float + Assert.areEqual (sign 1.0) 1 // double + Assert.areEqual (sign 1.0m) 1 // decimal + Assert.areEqual (sign 0y) 0 // byte + Assert.areEqual (sign 0s) 0 // int16 + Assert.areEqual (sign 0) 0 // int32 + Assert.areEqual (sign 0L) 0 // int64 + Assert.areEqual (sign 0.0f) 0 // float + Assert.areEqual (sign 0.0) 0 // double + Assert.areEqual (sign 0.0m) 0 // decimal + Assert.areEqual (sign -1y) -1 // byte + Assert.areEqual (sign -1s) -1 // int16 + Assert.areEqual (sign -1) -1 // int32 + Assert.areEqual (sign -1L) -1 // int64 + Assert.areEqual (sign -1.0f) -1 // float + Assert.areEqual (sign -1.0) -1 // double + Assert.areEqual (sign -1.0m) -1 // decimal + + // #Regression #Libraries #Operators + // Test sign function on unsigned primitives, should get error. + + [] + let ``Sign of byte``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0uy |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'byte' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint16``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0us |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint16' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint32``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0u |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 8) + "The type 'uint32' does not support the operator 'get_Sign'" + + [] + let ``Sign of uint64``() = + CompilerAssert.TypeCheckSingleError + """ +sign 0uL |> ignore + """ + FSharpDiagnosticSeverity.Error + 1 + (2, 6, 2, 9) + "The type 'uint64' does not support the operator 'get_Sign'" \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs new file mode 100644 index 00000000000..ad54fd0940f --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/StringTests.fs @@ -0,0 +1,115 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open System + +[] +module ``String Tests`` = + + type CalcSum(x : int, y: int) = + let mutable x = x + let mutable y = y + + member _.Sum () = x + y + + interface IFormattable with + member x.ToString (format: string, _ : IFormatProvider) = + match format with + | null | "" + | "g" | "G" -> String.Format("X + Y = {0}", x.Sum()) + | "s" | "S" -> x.Sum().ToString() // Short form + | _ -> invalidArg format "Format is wrong!" + + override x.ToString() = (x :> IFormattable).ToString(null, null) + + [] + let ``String of custom type``() = + let calc = CalcSum(10, 20) + Assert.areEqual (string calc) "X + Y = 30" + + let testDelegate = TestDelegate (fun () -> + printfn "%s" (calc.ToString()) + Console.WriteLine("{0:S}", calc) + Console.Write("{0} {1} {2:D}", 10, 20, calc)) + let e = Assert.Throws testDelegate + Assert.areEqual e.ParamName "D" + + // int32 + type Foo = + | A = 1 + | B = 2 + + [] + let ``String of int32 based enum``() = + let a = Foo.A + let r = a :> System.IFormattable + + Assert.areEqual (string a) (string r) + + // uint32 + type Foo2 = + | A = 3u + | B = 4u + + [] + let ``String of uint32 based enum``() = + let a = Foo2.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // char + type Foo3 = + | A = 'a' + | B = 'b' + + [] + let ``String of char based enum``() = + let a = Foo3.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // int16 + type Foo4 = + | A = 1s + | B = 2s + + [] + let ``String of int16 based enum``() = + let a = Foo4.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // uint16 + type Foo5 = + | A = 1us + | B = 2us + + [] + let ``String of uint16 based enum``() = + let a = Foo5.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // sbyte + type Foo6 = + | A = 1y + | B = 2y + + [] + let ``String of sbyte based enum``() = + let a = Foo6.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) + + // byte + type Foo7 = + | A = 1uy + | B = 2uy + + [] + let ``String of byte based enum``() = + let a = Foo7.A + let r = a :> System.IFormattable + Assert.areEqual (string a) (string r) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs b/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs new file mode 100644 index 00000000000..6b2a0c0752d --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Reflection/PreComputedTupleConstructorTests.fs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``PreComputedTupleConstructor Tests`` = + + [] + let ``PreComputedTupleConstructor of int and string``() = + // Regression test for FSHARP1.0:5113 + // MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler + + let testDelegate = TestDelegate (fun () -> + Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box 12; box "text" |] |> ignore) + + Assert.DoesNotThrow testDelegate |> ignore + + [] + let ``PreComputedTupleConstructor with wrong order of arguments``() = + // Regression test for FSHARP1.0:5113 + // MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler + + let testDelegate = TestDelegate (fun () -> + Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box "text"; box 12; |] |> ignore) + + Assert.Throws testDelegate |> ignore \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs b/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs new file mode 100644 index 00000000000..67ea1baa1bb --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Reflection/SprintfTests.fs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``Sprintf Tests`` = + + type MyR = {c:int;b:int;a:int} + + [] + let ``Sprintf %A of record type``() = + // Regression test for FSHARP1.0:5113 + + let s1 = sprintf "%A" {a=1;b=2;c=3} + let s2 = sprintf "%A" {c=3;b=2;a=1} + + Assert.areEqual s1 s2 + + type MyT = MyC of int * string * bool + + [] + let ``Sprintf %A of discriminated union type``() = + // Regression test for FSHARP1.0:5113 + + let DU = MyC (1,"2",true) + Assert.areEqual "MyC (1, \"2\", true)" (sprintf "%A" DU) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs b/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs new file mode 100644 index 00000000000..7c732e479ad --- /dev/null +++ b/tests/fsharp/Compiler/Libraries/Core/Unchecked/DefaultOfTests.fs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework + +[] +module ``DefaultOf Tests`` = + + type DUType = + | A + | B of int + | C of DUType * DUType + + type RecordType = { A : int; B : string; C : DUType } + + type ClassType = string + + type InterfaceType = + abstract DoStuff : unit -> unit + + type EnumType = + | A = 1 + | B = 2 + | C = 4 + + type StructType = struct + val m_ivalue : int + val m_svalue : string + member this.IValue = this.m_ivalue + member this.SValue = this.m_svalue + end + + [] + let `` Unchecked defaultof reference types``() = + Assert.areEqual Unchecked.defaultof null + Assert.areEqual (box Unchecked.defaultof) null + Assert.areEqual (box Unchecked.defaultof) null + Assert.areEqual (box Unchecked.defaultof) null + + [] + let ``Unchecked defaultof stack types``() = + Assert.areEqual Unchecked.defaultof 0 + Assert.areEqual Unchecked.defaultof 0.0 + Assert.areEqual Unchecked.defaultof (enum 0) + Assert.areEqual Unchecked.defaultof.IValue 0 + Assert.areEqual Unchecked.defaultof.SValue null + + type R = { x : int; y : string } + type U = | A of int | B of string + type S = struct val mutable x : int end + type C() = class end + + [] + let ``Unchecked defaultof and equality``() = + // FSharp1.0:5417 - Unchecked.defaultof<_> on records/unions can cause structural equality check to throw + // Check that Unchecked.defaultof<_> works correctly on various types, mostly structs/unions/records + + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof + Assert.areEqual Unchecked.defaultof Unchecked.defaultof \ No newline at end of file diff --git a/tests/fsharp/Compiler/Regressions/ForInDoMutableRegressionTest.fs b/tests/fsharp/Compiler/Regressions/ForInDoMutableRegressionTest.fs index 7319c2fab76..6ea9fe2dc42 100644 --- a/tests/fsharp/Compiler/Regressions/ForInDoMutableRegressionTest.fs +++ b/tests/fsharp/Compiler/Regressions/ForInDoMutableRegressionTest.fs @@ -4,6 +4,7 @@ namespace FSharp.Compiler.UnitTests open System open NUnit.Framework +open FSharp.Test [] module ForInDoMutableRegressionTest = diff --git a/tests/fsharp/Compiler/Regressions/IndexerRegressionTests.fs b/tests/fsharp/Compiler/Regressions/IndexerRegressionTests.fs new file mode 100644 index 00000000000..c9c1a77bafd --- /dev/null +++ b/tests/fsharp/Compiler/Regressions/IndexerRegressionTests.fs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System +open NUnit.Framework +open FSharp.Test + +[] +module IndexerRegressionTests = + + [] + let ``Indexer has qualified type value``() = + CompilerAssert.Pass + """ +let a = [| 1 |] +let f y = a.[y:int] + """ diff --git a/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs new file mode 100644 index 00000000000..c4009ee5233 --- /dev/null +++ b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test.Compiler + +[] +module NullableOptionalRegressionTests = + + [] + let ``Should compile with generic overloaded nullable methods``() = + Fsx """ +open System + +type OverloadMeths = + static member Map(m: 'T option, f) = Option.map f m + static member Map(m: 'T when 'T:null, f) = m |> Option.ofObj |> Option.map f + static member Map(m: 'T Nullable, f) = m |> Option.ofNullable |> Option.map f + +[] +type Node (child:Node)= + new() = new Node(null) + member val child:Node = child with get,set + +let test () = + let parent = Node() + let b1 = OverloadMeths.Map(parent.child, fun x -> x.child) + let c1 = OverloadMeths.Map(b1, fun x -> x.child) + () + """ + |> withLangVersion50 + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Method should infer 'z' correctly``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE (encoder, x: Nullable<'a>) = if x.HasValue then encoder x.Value else Test() + static member nullable codec z = Test.nullableE(codec, z) + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Method should infer correctly``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE encoder (x: Nullable<'a>) = if x.HasValue then encoder x.Value else Test() + static member nullable codec = Test.nullableE codec + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Method should infer correctly 2``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE encoder (x: Nullable) = if x.HasValue then encoder x.Value else Test() + static member nullable codec = Test.nullableE codec + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore diff --git a/tests/fsharp/Compiler/Service/MultiProjectTests.fs b/tests/fsharp/Compiler/Service/MultiProjectTests.fs new file mode 100644 index 00000000000..fa9541707d7 --- /dev/null +++ b/tests/fsharp/Compiler/Service/MultiProjectTests.fs @@ -0,0 +1,210 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System +open System.IO +open FSharp.Compiler.Diagnostics +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler +open FSharp.Compiler.CodeAnalysis +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.CSharp +open FSharp.Compiler.Text +open TestFramework + +[] +module MultiProjectTests = + + let AssertInMemoryCSharpReferenceIsValid () = + let csSrc = + """ +namespace CSharpTest +{ + public class CSharpClass + { + } +} + """ + + let csOptions = CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) + let csSyntax = CSharpSyntaxTree.ParseText(csSrc) + let csReferences = TargetFrameworkUtil.getReferences TargetFramework.NetStandard20 + let cs = CSharpCompilation.Create("csharp_test.dll", references = csReferences.As(), syntaxTrees = [csSyntax], options = csOptions) + + let ms = new MemoryStream() + let getStream = + fun ct -> + cs.Emit(ms, cancellationToken = ct) |> ignore + ms.Position <- 0L + ms :> Stream + |> Some + + let csRefProj = FSharpReferencedProject.CreatePortableExecutable("""Z:\csharp_test.dll""", DateTime.UtcNow, getStream) + + let fsOptions = CompilerAssert.DefaultProjectOptions + let fsOptions = + { fsOptions with + ProjectId = Some(Guid.NewGuid().ToString()) + OtherOptions = Array.append fsOptions.OtherOptions [|"""-r:Z:\csharp_test.dll"""|] + ReferencedProjects = [|csRefProj|] } + + let fsText = + """ +module FSharpTest + +open CSharpTest + +let test() = + CSharpClass() + """ + |> SourceText.ofString + let _, checkAnswer = + CompilerAssert.Checker.ParseAndCheckFileInProject("test.fs", 0, fsText, fsOptions) + |> Async.RunImmediate + + + match checkAnswer with + | FSharpCheckFileAnswer.Aborted -> failwith "check file aborted" + | FSharpCheckFileAnswer.Succeeded(checkResults) -> + Assert.shouldBeEmpty(checkResults.Diagnostics) + WeakReference(ms) + + let compileFileAsDll (checker: FSharpChecker) filePath outputFilePath = + try + let result, _ = + checker.Compile([|"fsc.dll";filePath;$"-o:{ outputFilePath }";"--deterministic+";"--optimize+";"--target:library"|]) + |> Async.RunImmediate + + if result.Length > 0 then + failwith "Compilation has errors." + with + | _ -> + try File.Delete(outputFilePath) with | _ -> () + reraise() + + let createOnDisk src = + let tmpFilePath = tryCreateTemporaryFileName () + let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fs") + try File.Delete(tmpFilePath) with | _ -> () + File.WriteAllText(tmpRealFilePath, src) + tmpRealFilePath + + let createOnDiskCompiledAsDll checker src = + let tmpFilePath = tryCreateTemporaryFileName () + let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fs") + try File.Delete(tmpFilePath) with | _ -> () + File.WriteAllText(tmpRealFilePath, src) + + let outputFilePath = Path.ChangeExtension(tmpRealFilePath, ".dll") + + try + compileFileAsDll checker tmpRealFilePath outputFilePath + outputFilePath + finally + try File.Delete(tmpRealFilePath) with | _ -> () + + let updateFileOnDisk filePath src = + File.WriteAllText(filePath, src) + + let updateCompiledDllOnDisk checker (dllPath: string) src = + if not (File.Exists dllPath) then + failwith $"File {dllPath} does not exist." + + let filePath = createOnDisk src + + try + compileFileAsDll checker filePath dllPath + finally + try File.Delete(filePath) with | _ -> () + + [] + let ``Using a CSharp reference project in-memory``() = + AssertInMemoryCSharpReferenceIsValid() |> ignore + + [] + let ``Using a CSharp reference project in-memory and it gets GCed``() = + let weakRef = AssertInMemoryCSharpReferenceIsValid() + CompilerAssert.Checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + GC.Collect(2, GCCollectionMode.Forced, true) + Assert.shouldBeFalse(weakRef.IsAlive) + + [] + let ``Using compiler service, file referencing a DLL will correctly update when the referenced DLL file changes``() = + let checker = CompilerAssert.Checker + + // Create an assembly with the module Script1 and function x. + let dllPath1 = + createOnDiskCompiledAsDll checker + """ +module Script1 + +let x = 1 + """ + + // Create script with that uses Script1 and function x + let filePath1 = + createOnDisk + """ +module Script2 + +let x = Script1.x + """ + + try + let fsOptions1 = CompilerAssert.DefaultProjectOptions + let fsOptions1 = + { fsOptions1 with + ProjectId = Some(Guid.NewGuid().ToString()) + OtherOptions = [|"-r:" + dllPath1|] + ReferencedProjects = [||] + SourceFiles = [|filePath1|] } + + // Verify that a script using Script1.x works + let checkProjectResults1 = + checker.ParseAndCheckProject(fsOptions1) + |> Async.RunImmediate + + Assert.IsEmpty(checkProjectResults1.Diagnostics) + + // Create script with that uses Script1 and function x and function y + updateFileOnDisk filePath1 + """ +module Script2 + +let x = Script1.x +let y = Script1.y + """ + + // Verify that a script using Script1.x and Script1.y fails + let checkProjectResults2 = + checker.ParseAndCheckProject(fsOptions1) + |> Async.RunImmediate + + Assert.IsNotEmpty(checkProjectResults2.Diagnostics) + + // Create an assembly with the module Script1 and function x and function y + updateCompiledDllOnDisk checker dllPath1 + """ +module Script1 + +let x = 1 +let y = 1 + """ + + // Verify that a script using Script1.x and Script1.y fails + let checkProjectResults3 = + checker.ParseAndCheckProject(fsOptions1) + |> Async.RunImmediate + + Assert.IsEmpty(checkProjectResults3.Diagnostics) + + finally + try File.Delete(dllPath1) with | _ -> () + try File.Delete(filePath1) with | _ -> () + + + + diff --git a/tests/fsharp/Compiler/Service/SignatureGenerationTests.fs b/tests/fsharp/Compiler/Service/SignatureGenerationTests.fs new file mode 100644 index 00000000000..5807c51b644 --- /dev/null +++ b/tests/fsharp/Compiler/Service/SignatureGenerationTests.fs @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open FSharp.Compiler.Diagnostics +open NUnit.Framework +open FSharp.Test +open FSharp.Test.Utilities +open FSharp.Test.Compiler + +[] +module SignatureGenerationTests = + + let sigText (checkResults: FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults) = + match checkResults.GenerateSignature() with + | None -> failwith "Unable to generate signature text." + | Some text -> text + + let sigShouldBe (expected: string) src = + let text = + FSharp src + |> withLangVersion50 + |> typecheckResults + |> sigText + + let actual = + text.ToString() + |> fun s -> s.Split('\n') + |> Array.map (fun s -> s.TrimEnd(' ')) + + printfn $"actual is\n-------\n{text.ToString()}\n---------" + + let expected2 = + expected.Replace("\r\n", "\n") + |> fun s -> s.Split('\n') + |> Array.map (fun s -> s.TrimEnd(' ')) + + Assert.shouldBeEquivalentTo expected2 actual + + [] + let ``can generate sigs with comments`` () = + """ +/// namespace comments +namespace Sample + +/// exception comments +exception MyEx of reason: string + +/// module-level docs +module Inner = + /// type-level docs + type Facts + /// primary ctor docs + (name: string) = + /// constructor-level docs + new() = Facts("default name") + /// member-level docs + member x.blah() = [1;2;3] + /// auto-property-level docs + member val Name = name with get, set + + /// module-level binding docs + let module_member = () + + /// record docs + type TestRecord = + { + /// record field docs + RecordField: int + } + /// record member docs + member x.Data = 1 + /// static record member docs + static member Foo = true + + /// union docs + type TestUnion = + /// docs for first case + | FirstCase of thing: int + /// union member + member x.Thing = match x with | FirstCase thing -> thing + """ + |> sigShouldBe """namespace Sample + + /// exception comments + exception MyEx of reason: string + + /// module-level docs + module Inner = + + /// type-level docs + type Facts = + + /// constructor-level docs + new: unit -> Facts + + /// primary ctor docs + new: name: string -> Facts + + /// member-level docs + member blah: unit -> int list + + /// auto-property-level docs + member Name: string + + /// module-level binding docs + val module_member: unit + + /// record docs + type TestRecord = + { + /// record field docs + RecordField: int + } + + /// record member docs + member Data: int + + /// static record member docs + static member Foo: bool + + /// union docs + type TestUnion = + + /// docs for first case + | FirstCase of thing: int + + /// union member + member Thing: int + """ \ No newline at end of file diff --git a/tests/fsharp/Compiler/SourceTextTests.fs b/tests/fsharp/Compiler/SourceTextTests.fs index e32647195b0..1111039c304 100644 --- a/tests/fsharp/Compiler/SourceTextTests.fs +++ b/tests/fsharp/Compiler/SourceTextTests.fs @@ -5,6 +5,7 @@ namespace FSharp.Compiler.UnitTests open System open NUnit.Framework +open FSharp.Compiler.Diagnostics open FSharp.Compiler.Text [] diff --git a/tests/fsharp/Compiler/Stress/LargeExprTests.fs b/tests/fsharp/Compiler/Stress/LargeExprTests.fs index 004f737cb9c..b9d6e7bece2 100644 --- a/tests/fsharp/Compiler/Stress/LargeExprTests.fs +++ b/tests/fsharp/Compiler/Stress/LargeExprTests.fs @@ -3,6 +3,7 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework +open FSharp.Test [] module LargeExprTests = @@ -983,36 +984,6 @@ type TestRecord = test968: int test969: int test970: int - test971: int - test972: int - test973: int - test974: int - test975: int - test976: int - test977: int - test978: int - test979: int - test980: int - test981: int - test982: int - test983: int - test984: int - test985: int - test986: int - test987: int - test988: int - test989: int - test990: int - test991: int - test992: int - test993: int - test994: int - test995: int - test996: int - test997: int - test998: int - test999: int - test1000: int } [] @@ -1995,36 +1966,7 @@ type TestRecord = test968: string test969: string test970: string - test971: string - test972: string - test973: string - test974: string - test975: string - test976: string - test977: string - test978: string - test979: string - test980: string - test981: string - test982: string - test983: string - test984: string - test985: string - test986: string - test987: string - test988: string - test989: string - test990: string - test991: string - test992: string - test993: string - test994: string - test995: string - test996: string - test997: string - test998: string - test999: string - test1000: string + } [] @@ -5572,4 +5514,4 @@ let test () : unit = test () """ - CompilerAssert.RunScript source [] \ No newline at end of file + CompilerAssert.RunScript source [] diff --git a/tests/fsharp/Compiler/Utilities.fs b/tests/fsharp/Compiler/Utilities.fs deleted file mode 100644 index 29de21ad3e3..00000000000 --- a/tests/fsharp/Compiler/Utilities.fs +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module FSharp.Compiler.UnitTests.Utilities - -open System -open System.IO -open System.Collections.Immutable -open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.CSharp - -// This file mimics how Roslyn handles their compilation references for compilation testing - -[] -type TargetFramework = - | NetStandard20 - | NetCoreApp30 - -module private TestReferences = - - [] - module NetStandard20 = - - let netStandard = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.netstandard).GetReference(display = "netstandard.dll (netstandard 2.0 ref)") - - let mscorlibRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.mscorlib).GetReference(display = "mscorlib.dll (netstandard 2.0 ref)") - - let systemRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Runtime).GetReference(display = "System.Runtime.dll (netstandard 2.0 ref)") - - let systemCoreRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Core).GetReference(display = "System.Core.dll (netstandard 2.0 ref)") - - let systemDynamicRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netstandard20.System_Dynamic_Runtime).GetReference(display = "System.Dynamic.Runtime.dll (netstandard 2.0 ref)") - - [] - module NetCoreApp30 = - - let netStandard = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.netstandard).GetReference(display = "netstandard.dll (netcoreapp 3.0 ref)") - - let mscorlibRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.mscorlib).GetReference(display = "mscorlib.dll (netcoreapp 3.0 ref)") - - let systemRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.System_Runtime).GetReference(display = "System.Runtime.dll (netcoreapp 3.0 ref)") - - let systemCoreRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.System_Core).GetReference(display = "System.Core.dll (netcoreapp 3.0 ref)") - - let systemDynamicRuntimeRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.System_Dynamic_Runtime).GetReference(display = "System.Dynamic.Runtime.dll (netcoreapp 3.0 ref)") - - let systemConsoleRef = lazy AssemblyMetadata.CreateFromImage(TestResources.NetFX.netcoreapp30.System_Console).GetReference(display = "System.Console.dll (netcoreapp 3.0 ref)") - - -[] -module private TargetFrameworkUtil = - - open TestReferences - - let private netStandard20References = - lazy ImmutableArray.Create(NetStandard20.netStandard.Value, NetStandard20.mscorlibRef.Value, NetStandard20.systemRuntimeRef.Value, NetStandard20.systemCoreRef.Value, NetStandard20.systemDynamicRuntimeRef.Value) - - let private netCoreApp30References = - lazy ImmutableArray.Create(NetCoreApp30.netStandard.Value, NetCoreApp30.mscorlibRef.Value, NetCoreApp30.systemRuntimeRef.Value, NetCoreApp30.systemCoreRef.Value, NetCoreApp30.systemDynamicRuntimeRef.Value, NetCoreApp30.systemConsoleRef.Value) - - let getReferences tf = - match tf with - | TargetFramework.NetStandard20 -> netStandard20References.Value - | TargetFramework.NetCoreApp30 -> netCoreApp30References.Value - -type RoslynLanguageVersion = LanguageVersion - -[] -type CSharpCompilationFlags = - | None = 0x0 - | InternalsVisibleTo = 0x1 - -[] -type TestCompilation = - | CSharp of CSharpCompilation * CSharpCompilationFlags - | IL of ilSource: string * result: Lazy - - member this.AssertNoErrorsOrWarnings () = - match this with - | TestCompilation.CSharp (c, _) -> - let diagnostics = c.GetDiagnostics () - - if not diagnostics.IsEmpty then - NUnit.Framework.Assert.Fail ("CSharp source diagnostics:\n" + (diagnostics |> Seq.map (fun x -> x.GetMessage () + "\n") |> Seq.reduce (+))) - - | TestCompilation.IL (_, result) -> - let errors, _ = result.Value - if errors.Length > 0 then - NUnit.Framework.Assert.Fail ("IL source errors: " + errors) - - member this.EmitAsFile (outputPath: string) = - match this with - | TestCompilation.CSharp (c, _) -> - let emitResult = c.Emit outputPath - if not emitResult.Success then - failwithf "Unable to emit C# compilation.\n%A" emitResult.Diagnostics - - | TestCompilation.IL (_, result) -> - let (_, data) = result.Value - File.WriteAllBytes (outputPath, data) - -type CSharpLanguageVersion = - | CSharp8 = 0 - -[] -type CompilationUtil private () = - - static member CreateCSharpCompilation (source: string, lv: CSharpLanguageVersion, ?tf, ?additionalReferences, ?flags) = - let lv = - match lv with - | CSharpLanguageVersion.CSharp8 -> LanguageVersion.CSharp8 - | _ -> LanguageVersion.Default - - let tf = defaultArg tf TargetFramework.NetStandard20 - let additionalReferences = defaultArg additionalReferences ImmutableArray.Empty - let flags = defaultArg flags CSharpCompilationFlags.None - let references = TargetFrameworkUtil.getReferences tf - let c = - CSharpCompilation.Create( - Guid.NewGuid().ToString (), - [ CSharpSyntaxTree.ParseText (source, CSharpParseOptions lv) ], - references.As().AddRange additionalReferences, - CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary)) - Some (TestCompilation.CSharp (c, flags)) - - static member CreateILCompilation (source: string) = - let compute = - lazy - let ilFilePath = Path.GetTempFileName () - let tmp = Path.GetTempFileName() - let dllFilePath = Path.ChangeExtension (tmp, ".dll") - try - File.WriteAllText (ilFilePath, source) - let errors = ILChecker.reassembleIL ilFilePath dllFilePath - try - (errors, File.ReadAllBytes dllFilePath) - with - | _ -> (errors, [||]) - finally - try File.Delete ilFilePath with | _ -> () - try File.Delete tmp with | _ -> () - try File.Delete dllFilePath with | _ -> () - Some (TestCompilation.IL (source, compute)) \ No newline at end of file diff --git a/tests/fsharp/Compiler/Warnings/AssignmentWarningTests.fs b/tests/fsharp/Compiler/Warnings/AssignmentWarningTests.fs index 533d4c43445..d6ef26bcdf1 100644 --- a/tests/fsharp/Compiler/Warnings/AssignmentWarningTests.fs +++ b/tests/fsharp/Compiler/Warnings/AssignmentWarningTests.fs @@ -3,7 +3,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module ``Warnings assigning to mutable and immutable objects`` = @@ -19,7 +20,7 @@ let changeX() = x = 20 y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (6, 5, 6, 11) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'." @@ -35,7 +36,7 @@ let changeX() = x = 20 y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (6, 5, 6, 11) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'." @@ -53,7 +54,7 @@ let changeProperty() = z.Enabled = true y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (8, 5, 8, 21) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'." @@ -73,7 +74,7 @@ let changeProperty() = x.Property2 = "20" y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (10, 5, 10, 23) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'." @@ -92,7 +93,7 @@ let changeProperty() = x.Property2 = "22" y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (9, 5, 9, 23) - "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." \ No newline at end of file + "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." diff --git a/tests/fsharp/Compiler/Warnings/ExperimentalAttributeTests.fs b/tests/fsharp/Compiler/Warnings/ExperimentalAttributeTests.fs index dc930600241..ed51078bf7a 100644 --- a/tests/fsharp/Compiler/Warnings/ExperimentalAttributeTests.fs +++ b/tests/fsharp/Compiler/Warnings/ExperimentalAttributeTests.fs @@ -2,7 +2,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module ``Validate ExperimentalAttribute and LanguageVersion`` = @@ -26,7 +27,7 @@ module TestModule = let ``ExperimentalAttribute warn when preview not specified``() = CompilerAssert.TypeCheckSingleError experimentalSource - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 57 (7, 8, 7, 17) "Preview library feature, requires '--langversion:preview'. This warning can be disabled using '--nowarn:57' or '#nowarn \"57\"'." diff --git a/tests/fsharp/Compiler/Warnings/PatternMatchingWarningTests.fs b/tests/fsharp/Compiler/Warnings/PatternMatchingWarningTests.fs index f8f9804ef23..864f760cc04 100644 --- a/tests/fsharp/Compiler/Warnings/PatternMatchingWarningTests.fs +++ b/tests/fsharp/Compiler/Warnings/PatternMatchingWarningTests.fs @@ -1,7 +1,8 @@ namespace FSharp.Compiler.UnitTests open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Test +open FSharp.Compiler.Diagnostics [] module PatternMatchingWarningTests = diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index 0daec217daa..e31827eb064 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -2,8 +2,8 @@ - net472;netcoreapp3.0 - netcoreapp3.0 + net472;net5.0 + net5.0 win-x86;win-x64 $(AssetTargetFallback);portable-net45+win8+wp8+wpa81 true @@ -11,77 +11,96 @@ true false false - $(OtherFlags) --warnon:1182 + $(OtherFlags) --warnon:1182 --langversion:preview nunit - - - - $(DefineConstants);FSHARP_SUITE_DRIVES_CORECLR_TESTS + 3186 scriptlib.fsx - - - NunitHelpers.fs - + - - - + + + + + - + + + - + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + - + + + + + - + + + + + + + + + + + + + + + + + + + + - - + + diff --git a/tests/fsharp/NUnitHelpers.fs b/tests/fsharp/NUnitHelpers.fs new file mode 100644 index 00000000000..1a212fdfdc4 --- /dev/null +++ b/tests/fsharp/NUnitHelpers.fs @@ -0,0 +1,17 @@ +namespace NUnit.Framework + +module Assert = + + [] + do() + + let inline fail message = Assert.Fail message + + let inline failf fmt = Printf.kprintf fail fmt + + let inline areEqual (expected: ^T) (actual: ^T) = + Assert.AreEqual(expected, actual) + +module StringAssert = + + let inline contains expected actual = StringAssert.Contains(expected, actual) diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdk.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdk.proj new file mode 100644 index 00000000000..8dc457f7bb9 --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdk.proj @@ -0,0 +1,20 @@ + + + + + + <_NETCoreSdkIsPreview>false + + + + + + false + true + true + $(FSCorePackageVersion) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkDisablePreviewCheck.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkDisablePreviewCheck.proj new file mode 100644 index 00000000000..002ab3b54aa --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkDisablePreviewCheck.proj @@ -0,0 +1,21 @@ + + + + + + <_NETCoreSdkIsPreview>false + + + + + + false + true + true + true + $(FSCorePackageVersion) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkEnablePreviewCheck.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkEnablePreviewCheck.proj new file mode 100644 index 00000000000..fe7c0400744 --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsNotPreviewSdkEnablePreviewCheck.proj @@ -0,0 +1,21 @@ + + + + + + <_NETCoreSdkIsPreview>false + + + + + + false + true + false + true + $(FSCorePackageVersion) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdk.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdk.proj new file mode 100644 index 00000000000..2a676575e2c --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdk.proj @@ -0,0 +1,20 @@ + + + + + + <_NETCoreSdkIsPreview>true + + + + + + false + true + true + $(FSharpCorePreviewPackageVersion) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkDisablePreviewCheck.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkDisablePreviewCheck.proj new file mode 100644 index 00000000000..7fdf2b2dbed --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkDisablePreviewCheck.proj @@ -0,0 +1,21 @@ + + + + + + <_NETCoreSdkIsPreview>true + + + + + + false + true + true + true + $(FSharpCoreShippedPackageVersionProperty) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkEnablePreviewCheck.proj b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkEnablePreviewCheck.proj new file mode 100644 index 00000000000..f8a76401cc0 --- /dev/null +++ b/tests/fsharp/SDKTests/tests/DefaultFSharpCore - IsPreviewSdkEnablePreviewCheck.proj @@ -0,0 +1,21 @@ + + + + + + <_NETCoreSdkIsPreview>true + + + + + + false + true + false + true + $(FSharpCorePreviewPackageVersion) + + + + + diff --git a/tests/fsharp/SDKTests/tests/DefaultImplicitReferenceTest.proj b/tests/fsharp/SDKTests/tests/DefaultImplicitReferenceTest.proj deleted file mode 100644 index beabbba8a29..00000000000 --- a/tests/fsharp/SDKTests/tests/DefaultImplicitReferenceTest.proj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - true - $(DefaultFSharpCorePackageVersion) - - true - $(DefaultValueTuplePackageVersion) - - - - - - diff --git a/tests/fsharp/SDKTests/tests/Test.props b/tests/fsharp/SDKTests/tests/Test.props index 8d29b210bfb..fea3092ec88 100644 --- a/tests/fsharp/SDKTests/tests/Test.props +++ b/tests/fsharp/SDKTests/tests/Test.props @@ -1,13 +1,14 @@ - + + net472 <_TargetFrameworkVersionWithoutV Condition="'$(_TargetFrameworkVersionWithoutV)' == ''">4.7.2 .NETFramework Release - $(MSBuildThisFileDirectory)..\..\..\..\artifacts\bin\FSharp.Build\$(Configuration)\net472 + $(MSBuildThisFileDirectory)..\..\..\..\artifacts\bin\FSharp.Build\$(Configuration)\netstandard2.0 AnyCPU diff --git a/tests/fsharp/SDKTests/tests/Test.targets b/tests/fsharp/SDKTests/tests/Test.targets index 6f1638051d8..c018aa9a326 100644 --- a/tests/fsharp/SDKTests/tests/Test.targets +++ b/tests/fsharp/SDKTests/tests/Test.targets @@ -32,6 +32,7 @@ + diff --git a/tests/fsharp/TestHelpers.fs b/tests/fsharp/TestHelpers.fs new file mode 100644 index 00000000000..f6b17da6c06 --- /dev/null +++ b/tests/fsharp/TestHelpers.fs @@ -0,0 +1,47 @@ +module Tests.TestHelpers +open System.IO + +let assembleDiffMessage actual expected = + + let getLines text = + use reader = new StringReader(text) + Seq.initInfinite (fun _ -> reader.ReadLine()) + |> Seq.takeWhile (not << isNull) + |> set + let actual = getLines actual + let expected = getLines expected + // + // Find types/members which exist in exactly one of the expected or actual surface areas. + // + + /// Surface area types/members which were expected to be found but missing from the actual surface area. + let unexpectedlyMissing = Set.difference expected actual + + /// Surface area types/members present in the actual surface area but weren't expected to be. + let unexpectedlyPresent = Set.difference actual expected + + // If both sets are empty, the surface areas match so allow the test to pass. + if Set.isEmpty unexpectedlyMissing + && Set.isEmpty unexpectedlyPresent then + None + else + // The surface areas don't match; prepare an easily-readable output message. + let msg = + let inline newLine (sb : System.Text.StringBuilder) = sb.AppendLine () |> ignore + let sb = System.Text.StringBuilder () + sb.Append "Unexpectedly missing (expected, not actual):" |> ignore + for s in unexpectedlyMissing do + newLine sb + sb.Append " " |> ignore + sb.Append s |> ignore + newLine sb + newLine sb + sb.Append "Unexpectedly present (actual, not expected):" |> ignore + for s in unexpectedlyPresent do + newLine sb + sb.Append " " |> ignore + sb.Append s |> ignore + newLine sb + sb.ToString () + + Some msg \ No newline at end of file diff --git a/tests/fsharp/TypeProviderTests.fs b/tests/fsharp/TypeProviderTests.fs index f5d9f909450..76561ffdaaf 100644 --- a/tests/fsharp/TypeProviderTests.fs +++ b/tests/fsharp/TypeProviderTests.fs @@ -3,11 +3,11 @@ #if INTERACTIVE //#r @"../../release/net40/bin/FSharp.Compiler.dll" #r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll" -#load "../../src/scripts/scriptlib.fsx" -#load "test-framework.fs" +#load "../../src/scripts/scriptlib.fsx" +#load "../FSharp.Test.Utilities/TestFramework.fs" #load "single-test.fs" #else -[] +[] module FSharp.Test.FSharpSuite.TypeProviderTests #endif @@ -19,24 +19,30 @@ open TestFramework open Scripting open SingleTest -#if FSHARP_SUITE_DRIVES_CORECLR_TESTS +open FSharp.Compiler.IO + +#if !NETCOREAPP +// All tests which do a manual invoke of the F# compiler are disabled + +#if NETCOREAPP // Use these lines if you want to test CoreCLR let FSC_BASIC = FSC_CORECLR let FSI_BASIC = FSI_CORECLR -let FSIANYCPU_BASIC = FSI_CORECLR #else let FSC_BASIC = FSC_OPT_PLUS_DEBUG let FSI_BASIC = FSI_FILE #endif -(* +let inline getTestsDirectory dir = getTestsDirectory __SOURCE_DIRECTORY__ dir +let testConfig = getTestsDirectory >> testConfig + [] -let diamondAssembly () = +let diamondAssembly () = let cfg = testConfig "typeProviders/diamondAssembly" rm cfg "provider.dll" - // Add a version flag to make this generate native resources. The native resources aren't important and + // Add a version flag to make this generate native resources. The native resources aren't important and // can be dropped when the provided.dll is linked but we need to tolerate generated DLLs that have them fsc cfg "%s" "--out:provided.dll -a --version:0.0.0.1" [".." ++ "helloWorld" ++ "provided.fs"] @@ -65,16 +71,16 @@ let diamondAssembly () = fsi cfg "%s" cfg.fsi_flags ["test3.fsx"] testOkFile.CheckExists() - + [] -let globalNamespace () = +let globalNamespace () = let cfg = testConfig "typeProviders/globalNamespace" - csc cfg """/out:globalNamespaceTP.dll /debug+ /target:library /r:"%s" """ cfg.FSCOREDLLPATH ["globalNamespaceTP.cs"] + csc cfg """/out:globalNamespaceTP.dll /debug+ /target:library /r:netstandard.dll /r:"%s" """ cfg.FSCOREDLLPATH ["globalNamespaceTP.cs"] fsc cfg "%s /debug+ /r:globalNamespaceTP.dll /optimize-" cfg.fsc_flags ["test.fsx"] - -let helloWorld p = + +let helloWorld p = let cfg = testConfig "typeProviders/helloWorld" fsc cfg "%s" "--out:provided1.dll -g -a" [".." ++ "helloWorld" ++ "provided.fs"] @@ -99,7 +105,7 @@ let helloWorld p = fsc cfg "--out:provider.dll -a" ["provider.fsx"] - SingleTest.singleTestBuildAndRunAux cfg p + SingleTest.singleTestBuildAndRunAux cfg p rm cfg "provider_with_binary_compat_changes.dll" @@ -119,7 +125,7 @@ let helloWorld p = log "popd" mkdir cfg "bincompat2" - + log "pushd bincompat2" let bincompat2 = getfullpath cfg "bincompat2" @@ -143,12 +149,13 @@ let helloWorld p = [] let ``helloWorld fsc`` () = helloWorld FSC_BASIC +#if !NETCOREAPP [] let ``helloWorld fsi`` () = helloWorld FSI_STDIN - +#endif [] -let helloWorldCSharp () = +let helloWorldCSharp () = let cfg = testConfig "typeProviders/helloWorldCSharp" rm cfg "magic.dll" @@ -157,7 +164,7 @@ let helloWorldCSharp () = rm cfg "provider.dll" - csc cfg """/out:provider.dll /target:library "/r:%s" /r:magic.dll""" cfg.FSCOREDLLPATH ["provider.cs"] + csc cfg """/out:provider.dll /target:library "/r:%s" /r:netstandard.dll /r:magic.dll""" cfg.FSCOREDLLPATH ["provider.cs"] fsc cfg "%s /debug+ /r:provider.dll /optimize-" cfg.fsc_flags ["test.fsx"] @@ -168,14 +175,14 @@ let helloWorldCSharp () = peverify cfg "test.exe" exec cfg ("." ++ "test.exe") "" - + [] [] [] [] [] -[] +[] [] [] [] @@ -197,6 +204,7 @@ let helloWorldCSharp () = [] [] [] +[] let ``negative type provider tests`` (name:string) = let cfg = testConfig "typeProviders/negTests" let dir = cfg.Directory @@ -219,7 +227,7 @@ let ``negative type provider tests`` (name:string) = rm cfg "provider.dll" - fsc cfg "--out:provider.dll -a" ["provider.fsx"] + fsc cfg "--out:provider.dll -g --optimize- -a" ["provider.fsx"] fsc cfg "--out:provider_providerAttributeErrorConsume.dll -a" ["providerAttributeError.fsx"] @@ -227,34 +235,36 @@ let ``negative type provider tests`` (name:string) = rm cfg "helloWorldProvider.dll" - fsc cfg "--out:helloWorldProvider.dll -a" [".." ++ "helloWorld" ++ "provider.fsx"] + fsc cfg "--out:helloWorldProvider.dll -g --optimize- -a" [".." ++ "helloWorld" ++ "provider.fsx"] rm cfg "MostBasicProvider.dll" - fsc cfg "--out:MostBasicProvider.dll -a" ["MostBasicProvider.fsx"] + fsc cfg "--out:MostBasicProvider.dll -g --optimize- -a" ["MostBasicProvider.fsx"] - let preprocess name pref = + let preprocess name pref = let dirp = (dir |> Commands.pathAddBackslash) do - File.ReadAllText(sprintf "%s%s.%sbslpp" dirp name pref) - .Replace("", getfullpath cfg (sprintf "provider_%s.dll" name)) - .Replace("",sprintf "file:///%s" dirp) - |> fun txt -> File.WriteAllText(sprintf "%s%s.%sbsl" dirp name pref,txt) - + FileSystem.OpenFileForReadShim(sprintf "%s%s.%sbslpp" dirp name pref) + .ReadAllText() + .Replace("", getfullpath cfg (sprintf "provider_%s.dll" name)) + .Replace("",dirp) + .Replace("",sprintf "file:///%s" dirp) + |> fun txt -> FileSystem.OpenFileForWriteShim(sprintf "%s%s.%sbsl" dirp name pref).Write(txt) + if name = "ProviderAttribute_EmptyConsume" || name = "providerAttributeErrorConsume" then () else fsc cfg "--define:%s --out:provider_%s.dll -a" name name ["provider.fsx"] - if fileExists (sprintf "%s.bslpp" name) then preprocess name "" + if fileExists (sprintf "%s.bslpp" name) then preprocess name "" if fileExists (sprintf "%s.vsbslpp" name) then preprocess name "vs" SingleTest.singleNegTest cfg name let splitAssembly subdir project = - + let subdir = getTestsDirectory subdir let cfg = testConfig project - let clean() = + let clean() = rm cfg "providerDesigner.dll" rmdir cfg "typeproviders" rmdir cfg "tools" @@ -267,20 +277,29 @@ let splitAssembly subdir project = fsc cfg "--out:providerDesigner.dll -a" ["providerDesigner.fsx"] - SingleTest.singleTestBuildAndRunAux cfg FSC_BASIC + fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"] - SingleTest.singleTestBuildAndRunAux cfg FSI_BASIC + begin + use testOkFile = fileguard cfg "test.ok" -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - SingleTest.singleTestBuildAndRunAux cfg FSIANYCPU_BASIC -#endif + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + end + + begin + use testOkFile = fileguard cfg "test.ok" + + fsi cfg "%s" cfg.fsi_flags ["test.fsx"] + testOkFile.CheckExists() + end // Do the same thing with different load locations for the type provider design-time component clean() // check a few load locations - let someLoadPaths = + let someLoadPaths = [ subdir ++ "fsharp41" ++ "net461" subdir ++ "fsharp41" ++ "net45" // include up one directory @@ -289,23 +308,30 @@ let splitAssembly subdir project = for dir in someLoadPaths do + printfn "" + printfn "Checking load path '%s'" dir clean() // put providerDesigner.dll into a different place mkdir cfg dir fsc cfg "--out:%s/providerDesigner.dll -a" dir ["providerDesigner.fsx"] - SingleTest.singleTestBuildAndRunAux cfg FSC_BASIC + fsc cfg "--out:test.exe -r:provider.dll" ["test.fsx"] - for dir in someLoadPaths do + begin + use testOkFile = fileguard cfg "test.ok" - clean() + exec cfg ("." ++ "test.exe") "" - // put providerDesigner.dll into a different place - mkdir cfg dir - fsc cfg "--out:%s/providerDesigner.dll -a" dir ["providerDesigner.fsx"] + testOkFile.CheckExists() + end - SingleTest.singleTestBuildAndRunAux cfg FSI_BASIC + begin + use testOkFile = fileguard cfg "test.ok" + + fsi cfg "%s" cfg.fsi_flags ["test.fsx"] + testOkFile.CheckExists() + end clean() @@ -316,7 +342,7 @@ let splitAssemblyTools () = splitAssembly "tools" "typeProviders/splitAssemblyTo let splitAssemblyTypeProviders () = splitAssembly "typeproviders" "typeProviders/splitAssemblyTypeproviders" [] -let wedgeAssembly () = +let wedgeAssembly () = let cfg = testConfig "typeProviders/wedgeAssembly" rm cfg "provider.dll" @@ -360,4 +386,4 @@ let wedgeAssembly () = peverify cfg "test3.exe" exec cfg ("." ++ "test3.exe") "" -*) +#endif diff --git a/tests/fsharp/app.config b/tests/fsharp/app.config deleted file mode 100644 index b64cfc5852a..00000000000 --- a/tests/fsharp/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.bsl b/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.bsl index 7f35dc88647..4f092ad8b6c 100644 --- a/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.bsl +++ b/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.bsl @@ -1,14 +1,38 @@ -E_Slices01.fsx(22,9,22,19): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member Foo.GetSlice : x:int * y1:int option * y2:float option -> unit, member Foo.GetSlice : x:int * y1:int option * y2:int option -> unit +E_Slices01.fsx(15,9,15,19): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_Slices01.fsx(23,9,23,17): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member Foo.GetSlice : x:int * y1:int option * y2:float option -> unit, member Foo.GetSlice : x:int * y1:int option * y2:int option -> unit +Known types of arguments: int * int option * 'a option -E_Slices01.fsx(24,9,24,19): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member Foo.GetSlice : x1:float option * x2:int option * y:int -> unit, member Foo.GetSlice : x1:int option * x2:int option * y:int -> unit +Candidates: + - member Foo.GetSlice: x: int * y1: int option * y2: float option -> unit + - member Foo.GetSlice: x: int * y1: int option * y2: int option -> unit -E_Slices01.fsx(25,9,25,17): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member Foo.GetSlice : x1:float option * x2:int option * y:int -> unit, member Foo.GetSlice : x1:int option * x2:int option * y:int -> unit +E_Slices01.fsx(16,9,16,17): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_Slices01.fsx(26,9,26,17): typecheck error FS0039: The field, constructor or member 'Item' is not defined. +Known types of arguments: int * 'a option * 'b option -E_Slices01.fsx(27,9,27,26): typecheck error FS0503: A member or object constructor 'GetSlice' taking 4 arguments is not accessible from this code location. All accessible versions of method 'GetSlice' take 3 arguments. +Candidates: + - member Foo.GetSlice: x: int * y1: int option * y2: float option -> unit + - member Foo.GetSlice: x: int * y1: int option * y2: int option -> unit -E_Slices01.fsx(28,9,28,20): typecheck error FS0503: A member or object constructor 'GetSlice' taking 5 arguments is not accessible from this code location. All accessible versions of method 'GetSlice' take 3 arguments. +E_Slices01.fsx(17,9,17,19): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a option * int option * int + +Candidates: + - member Foo.GetSlice: x1: float option * x2: int option * y: int -> unit + - member Foo.GetSlice: x1: int option * x2: int option * y: int -> unit + +E_Slices01.fsx(18,9,18,17): typecheck error FS0041: A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a option * 'b option * int + +Candidates: + - member Foo.GetSlice: x1: float option * x2: int option * y: int -> unit + - member Foo.GetSlice: x1: int option * x2: int option * y: int -> unit + +E_Slices01.fsx(19,9,19,17): typecheck error FS0039: The type 'Foo<_>' does not define the field, constructor or member 'Item'. + +E_Slices01.fsx(20,9,20,26): typecheck error FS0503: A member or object constructor 'GetSlice' taking 4 arguments is not accessible from this code location. All accessible versions of method 'GetSlice' take 3 arguments. + +E_Slices01.fsx(21,9,21,20): typecheck error FS0503: A member or object constructor 'GetSlice' taking 5 arguments is not accessible from this code location. All accessible versions of method 'GetSlice' take 3 arguments. diff --git a/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.fsx b/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.fsx index 72e00c534e7..3512f1ec0a8 100644 --- a/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.fsx +++ b/tests/fsharp/conformance/expressions/syntacticsugar/E_Slices01.fsx @@ -2,13 +2,6 @@ #light // Verify errors related to ambiguous slicing overloads -//A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point\. A type annotation may be needed\. Candidates: member Foo\.GetSlice : x:int \* y1:int option \* y2:float option -> unit, member Foo\.GetSlice : x:int \* y1:int option \* y2:int option -> unit -//A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point\. A type annotation may be needed\. Candidates: member Foo\.GetSlice : x:int \* y1:int option \* y2:float option -> unit, member Foo\.GetSlice : x:int \* y1:int option \* y2:int option -> unit -//A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point\. A type annotation may be needed\. Candidates: member Foo\.GetSlice : x1:float option \* x2:int option \* y:int -> unit, member Foo\.GetSlice : x1:int option \* x2:int option \* y:int -> unit -//A unique overload for method 'GetSlice' could not be determined based on type information prior to this program point\. A type annotation may be needed\. Candidates: member Foo\.GetSlice : x1:float option \* x2:int option \* y:int -> unit, member Foo\.GetSlice : x1:int option \* x2:int option \* y:int -> unit -//The field, constructor or member 'Item' is not defined -//A member or object constructor 'GetSlice' taking 4 arguments is not accessible from this code location\. All accessible versions of method 'GetSlice' take 3 arguments\. -//A member or object constructor 'GetSlice' taking 5 arguments is not accessible from this code location\. All accessible versions of method 'GetSlice' take 3 arguments\. type Foo<'a>() = member this.GetSlice(x : int, y1 : int option, y2 : int option) = () diff --git a/tests/fsharp/conformance/expressions/type-relatedexpressions/E_RigidTypeAnnotation03.bsl b/tests/fsharp/conformance/expressions/type-relatedexpressions/E_RigidTypeAnnotation03.bsl new file mode 100644 index 00000000000..974190e66a3 --- /dev/null +++ b/tests/fsharp/conformance/expressions/type-relatedexpressions/E_RigidTypeAnnotation03.bsl @@ -0,0 +1,70 @@ + +E_RigidTypeAnnotation03.fsx(17,13,17,16): typecheck error FS0001: This expression was expected to have type + 'sbyte' +but here has type + 'byte' + +E_RigidTypeAnnotation03.fsx(17,9,17,25): typecheck error FS0041: No overloads match for method 'M'. + +Known type of argument: sbyte + +Available overloads: + - static member T.M: a: byte -> int // Argument 'a' doesn't match + - static member T.M: a: decimal -> int // Argument 'a' doesn't match + - static member T.M: a: float -> int // Argument 'a' doesn't match + - static member T.M: a: float32 -> int // Argument 'a' doesn't match + - static member T.M: a: string -> int // Argument 'a' doesn't match + +E_RigidTypeAnnotation03.fsx(18,13,18,19): typecheck error FS0001: This expression was expected to have type + 'float32' +but here has type + 'float<'u>' + +E_RigidTypeAnnotation03.fsx(18,9,18,30): typecheck error FS0041: No overloads match for method 'M'. + +Known type of argument: float32 + +Available overloads: + - static member T.M: a: byte -> int // Argument 'a' doesn't match + - static member T.M: a: decimal -> int // Argument 'a' doesn't match + - static member T.M: a: float -> int // Argument 'a' doesn't match + - static member T.M: a: float32 -> int // Argument 'a' doesn't match + - static member T.M: a: string -> int // Argument 'a' doesn't match + +E_RigidTypeAnnotation03.fsx(19,13,19,20): typecheck error FS0001: This expression was expected to have type + 'float32<'u>' +but here has type + 'decimal' + +E_RigidTypeAnnotation03.fsx(20,13,20,21): typecheck error FS0001: Type mismatch. Expecting a + 'decimal' +but given a + 'decimal' +The unit of measure 'N s ^ 2' does not match the unit of measure 'Kg' + +E_RigidTypeAnnotation03.fsx(20,9,20,39): typecheck error FS0041: No overloads match for method 'M'. + +Known type of argument: decimal + +Available overloads: + - static member T.M: a: byte -> int // Argument 'a' doesn't match + - static member T.M: a: decimal -> int // Argument 'a' doesn't match + - static member T.M: a: float -> int // Argument 'a' doesn't match + - static member T.M: a: float32 -> int // Argument 'a' doesn't match + - static member T.M: a: string -> int // Argument 'a' doesn't match + +E_RigidTypeAnnotation03.fsx(21,14,21,18): typecheck error FS0001: This expression was expected to have type + 'char' +but here has type + 'string' + +E_RigidTypeAnnotation03.fsx(21,9,21,27): typecheck error FS0041: No overloads match for method 'M'. + +Known type of argument: char + +Available overloads: + - static member T.M: a: byte -> int // Argument 'a' doesn't match + - static member T.M: a: decimal -> int // Argument 'a' doesn't match + - static member T.M: a: float -> int // Argument 'a' doesn't match + - static member T.M: a: float32 -> int // Argument 'a' doesn't match + - static member T.M: a: string -> int // Argument 'a' doesn't match diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_RigidTypeAnnotation03.fsx b/tests/fsharp/conformance/expressions/type-relatedexpressions/E_RigidTypeAnnotation03.fsx similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_RigidTypeAnnotation03.fsx rename to tests/fsharp/conformance/expressions/type-relatedexpressions/E_RigidTypeAnnotation03.fsx diff --git a/tests/fsharp/conformance/inference/E_LeftToRightOverloadResolution01.bsl b/tests/fsharp/conformance/inference/E_LeftToRightOverloadResolution01.bsl index 640806d814c..1eebf220332 100644 --- a/tests/fsharp/conformance/inference/E_LeftToRightOverloadResolution01.bsl +++ b/tests/fsharp/conformance/inference/E_LeftToRightOverloadResolution01.bsl @@ -1,4 +1,38 @@ -E_LeftToRightOverloadResolution01.fsx(7,23,7,51): typecheck error FS0041: A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Console.WriteLine(buffer: char []) : unit, System.Console.WriteLine(format: string, [] arg: obj []) : unit, System.Console.WriteLine(value: bool) : unit, System.Console.WriteLine(value: char) : unit, System.Console.WriteLine(value: decimal) : unit, System.Console.WriteLine(value: float) : unit, System.Console.WriteLine(value: float32) : unit, System.Console.WriteLine(value: int) : unit, System.Console.WriteLine(value: int64) : unit, System.Console.WriteLine(value: obj) : unit, System.Console.WriteLine(value: string) : unit, System.Console.WriteLine(value: uint32) : unit, System.Console.WriteLine(value: uint64) : unit +E_LeftToRightOverloadResolution01.fsx(7,23,7,51): typecheck error FS0041: A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_LeftToRightOverloadResolution01.fsx(9,23,9,51): typecheck error FS0041: A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Console.WriteLine(buffer: char []) : unit, System.Console.WriteLine(format: string, [] arg: obj []) : unit, System.Console.WriteLine(value: bool) : unit, System.Console.WriteLine(value: char) : unit, System.Console.WriteLine(value: decimal) : unit, System.Console.WriteLine(value: float) : unit, System.Console.WriteLine(value: float32) : unit, System.Console.WriteLine(value: int) : unit, System.Console.WriteLine(value: int64) : unit, System.Console.WriteLine(value: obj) : unit, System.Console.WriteLine(value: string) : unit, System.Console.WriteLine(value: uint32) : unit, System.Console.WriteLine(value: uint64) : unit +Known type of argument: 'a + +Candidates: + - System.Console.WriteLine(buffer: char[]) : unit + - System.Console.WriteLine(format: string, [] arg: obj[]) : unit + - System.Console.WriteLine(value: bool) : unit + - System.Console.WriteLine(value: char) : unit + - System.Console.WriteLine(value: decimal) : unit + - System.Console.WriteLine(value: float) : unit + - System.Console.WriteLine(value: float32) : unit + - System.Console.WriteLine(value: int) : unit + - System.Console.WriteLine(value: int64) : unit + - System.Console.WriteLine(value: obj) : unit + - System.Console.WriteLine(value: string) : unit + - System.Console.WriteLine(value: uint32) : unit + - System.Console.WriteLine(value: uint64) : unit + +E_LeftToRightOverloadResolution01.fsx(9,23,9,51): typecheck error FS0041: A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a + +Candidates: + - System.Console.WriteLine(buffer: char[]) : unit + - System.Console.WriteLine(format: string, [] arg: obj[]) : unit + - System.Console.WriteLine(value: bool) : unit + - System.Console.WriteLine(value: char) : unit + - System.Console.WriteLine(value: decimal) : unit + - System.Console.WriteLine(value: float) : unit + - System.Console.WriteLine(value: float32) : unit + - System.Console.WriteLine(value: int) : unit + - System.Console.WriteLine(value: int64) : unit + - System.Console.WriteLine(value: obj) : unit + - System.Console.WriteLine(value: string) : unit + - System.Console.WriteLine(value: uint32) : unit + - System.Console.WriteLine(value: uint64) : unit diff --git a/tests/fsharp/conformance/inference/E_OneTypeVariable03.bsl b/tests/fsharp/conformance/inference/E_OneTypeVariable03.bsl index ca730fe7ad2..e46f1757896 100644 --- a/tests/fsharp/conformance/inference/E_OneTypeVariable03.bsl +++ b/tests/fsharp/conformance/inference/E_OneTypeVariable03.bsl @@ -1,4 +1,17 @@ -E_OneTypeVariable03.fsx(60,34,60,44): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C23.M : x:'a * y:'b -> Two, static member C23.M : x:'a * y:int -> Three +E_OneTypeVariable03.fsx(60,34,60,44): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_OneTypeVariable03.fsx(61,34,61,45): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C123.M : x:'a * y:'a -> One, static member C123.M : x:'a * y:'b -> Two, static member C123.M : x:'a * y:int -> Three +Known types of arguments: 'a * int + +Candidates: + - static member C23.M: x: 'a * y: 'b -> Two + - static member C23.M: x: 'a * y: int -> Three + +E_OneTypeVariable03.fsx(61,34,61,45): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * int + +Candidates: + - static member C123.M: x: 'a * y: 'a -> One + - static member C123.M: x: 'a * y: 'b -> Two + - static member C123.M: x: 'a * y: int -> Three diff --git a/tests/fsharp/conformance/inference/E_OneTypeVariable03rec.bsl b/tests/fsharp/conformance/inference/E_OneTypeVariable03rec.bsl index c3d473b6f8c..3da07112f80 100644 --- a/tests/fsharp/conformance/inference/E_OneTypeVariable03rec.bsl +++ b/tests/fsharp/conformance/inference/E_OneTypeVariable03rec.bsl @@ -1,4 +1,17 @@ -E_OneTypeVariable03rec.fsx(60,38,60,48): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C23.M : x:'a * y:'b -> Two, static member C23.M : x:'a * y:int -> Three +E_OneTypeVariable03rec.fsx(60,38,60,48): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_OneTypeVariable03rec.fsx(61,38,61,49): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C123.M : x:'a * y:'a -> One, static member C123.M : x:'a * y:'b -> Two, static member C123.M : x:'a * y:int -> Three +Known types of arguments: 'a * int + +Candidates: + - static member C23.M: x: 'a * y: 'b -> Two + - static member C23.M: x: 'a * y: int -> Three + +E_OneTypeVariable03rec.fsx(61,38,61,49): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * int + +Candidates: + - static member C123.M: x: 'a * y: 'a -> One + - static member C123.M: x: 'a * y: 'b -> Two + - static member C123.M: x: 'a * y: int -> Three diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01.bsl index ad9bf2298fc..bef5539b00a 100644 --- a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01.bsl +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01.bsl @@ -1,8 +1,32 @@ -E_TwoDifferentTypeVariables01.fsx(61,33,61,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariables01.fsx(61,33,61,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoDifferentTypeVariables01.fsx(62,33,62,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C24.M : x:'a * y:'b -> Two, static member C24.M : x:'a * y:C -> Four +Known types of arguments: 'a * 'b -E_TwoDifferentTypeVariables01.fsx(63,33,63,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three -E_TwoDifferentTypeVariables01.fsx(64,33,64,46): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariables01.fsx(62,33,62,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C24.M: x: 'a * y: 'b -> Two + - static member C24.M: x: 'a * y: C -> Four + +E_TwoDifferentTypeVariables01.fsx(63,33,63,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three + +E_TwoDifferentTypeVariables01.fsx(64,33,64,46): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01rec.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01rec.bsl index 45b7dfd315d..c00efb90a64 100644 --- a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01rec.bsl +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariables01rec.bsl @@ -1,8 +1,32 @@ -E_TwoDifferentTypeVariables01rec.fsx(60,37,60,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariables01rec.fsx(60,37,60,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoDifferentTypeVariables01rec.fsx(61,37,61,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C24.M : x:'a * y:'b -> Two, static member C24.M : x:'a * y:C -> Four +Known types of arguments: 'a * 'b -E_TwoDifferentTypeVariables01rec.fsx(62,37,62,51): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three -E_TwoDifferentTypeVariables01rec.fsx(63,37,63,50): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariables01rec.fsx(61,37,61,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C24.M: x: 'a * y: 'b -> Two + - static member C24.M: x: 'a * y: C -> Four + +E_TwoDifferentTypeVariables01rec.fsx(62,37,62,51): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three + +E_TwoDifferentTypeVariables01rec.fsx(63,37,63,50): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl new file mode 100644 index 00000000000..b8d0b1ba38c --- /dev/null +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.bsl @@ -0,0 +1,56 @@ + +E_TwoDifferentTypeVariablesGen00.fsx(61,52,61,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. + +E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. + +E_TwoDifferentTypeVariablesGen00.fsx(61,18,61,42): typecheck error FS0043: The type ''b' does not match the type ''b0' + +E_TwoDifferentTypeVariablesGen00.fsx(62,52,62,53): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. + +E_TwoDifferentTypeVariablesGen00.fsx(62,18,62,42): typecheck error FS0043: The type ''b' does not match the type 'int' + +E_TwoDifferentTypeVariablesGen00.fsx(63,45,63,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three + +E_TwoDifferentTypeVariablesGen00.fsx(64,56,64,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. + +E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. + +E_TwoDifferentTypeVariablesGen00.fsx(64,18,64,42): typecheck error FS0043: The type ''b' does not match the type ''b0' + +E_TwoDifferentTypeVariablesGen00.fsx(65,54,65,55): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. + +E_TwoDifferentTypeVariablesGen00.fsx(65,56,65,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'. + +E_TwoDifferentTypeVariablesGen00.fsx(65,18,65,42): typecheck error FS0043: The type ''a' does not match the type 'int' + +E_TwoDifferentTypeVariablesGen00.fsx(66,45,66,59): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three + +E_TwoDifferentTypeVariablesGen00.fsx(67,55,67,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. + +E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,42): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type ''a'. + +E_TwoDifferentTypeVariablesGen00.fsx(67,18,67,42): typecheck error FS0043: The type ''b' does not match the type ''b0' + +E_TwoDifferentTypeVariablesGen00.fsx(68,45,68,58): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three + +E_TwoDifferentTypeVariablesGen00.fsx(69,55,69,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. + +E_TwoDifferentTypeVariablesGen00.fsx(69,18,69,42): typecheck error FS0043: The type ''b' does not match the type 'int' diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.fsx b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.fsx new file mode 100644 index 00000000000..304f6681422 --- /dev/null +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00.fsx @@ -0,0 +1,69 @@ +// #Regression #TypeInference +// Regression test for FSHARP1.0:4758 +// Type Inference +// Check Method Disambiguation When User Generic Variable Get Instantiated By Overload Resolution +module M +// These different return types are used to determine which overload got chosen +type One = | One +type Two = | Two +type Three = | Three +type Four = | Four + +// An unsealed type +type C() = + member x.P = 1 + +type C1 = + static member M<'a>(x:'a,y:'a) = One + +type C2 = + static member M<'a,'b>(x:'a,y:'b) = Two + +type C3 = + static member M<'a>(x:'a,y:int) = Three + +type C4 = + static member M<'a>(x:'a,y:C) = Four + +type C12 = + static member M<'a>(x:'a,y:'a) = One + static member M<'a,'b>(x:'a,y:'b) = Two + +type C23 = + static member M<'a,'b>(x:'a,y:'b) = Two + static member M<'a>(x:'a,y:int) = Three + +type C13 = + static member M<'a>(x:'a,y:'a) = One + static member M<'a>(x:'a,y:int) = Three + +type C14 = + static member M<'a>(x:'a,y:'a) = One + static member M<'a>(x:'a,y:C) = Four + +type C24 = + static member M<'a,'b>(x:'a,y:'b) = Two + static member M<'a>(x:'a,y:C) = Four + +type C123 = + static member M<'a>(x:'a,y:'a) = One + static member M<'a,'b>(x:'a,y:'b) = Two + static member M<'a>(x:'a,y:int) = Three + +type C1234 = + static member M<'a>(x:'a,y:'a) = One + static member M<'a,'b>(x:'a,y:'b) = Two + static member M<'a>(x:'a,y:int) = Three + static member M<'a>(x:'a,y:C) = Four + + +module M0Rec = + let rec gB1<'a,'b> (x:'a) (y:'b) = C1.M(x,y) = One // expect: type error + let rec gB3<'a,'b> (x:'a) (y:'b) = C3.M(x,y) = Three // expect: type error + let rec gB13<'a,'b> (x:'a) (y:'b) = C13.M(x,y) // expect: ambiguity error (and note: both would instantiate 'a or 'b) + let rec gC1<'a,'b> (x:'a) (y:'b) = C1.M<'a>(x,y) = One // expect: error + let rec gC3<'a,'b> (x:'a) (y:'b) = C3.M<'b>(x,y) = Three // expect: error + let rec gC13<'a,'b> (x:'a) (y:'b) = C13.M<'a>(x,y) // expect: ambiguity error + let rec gD1<'a,'b> (x:'a) (y:'b) = C1.M<_>(x,y) = One // expect: type error + let rec gD13<'a,'b> (x:'a) (y:'b) = C13.M<_>(x,y) // expect: ambiguity error (and note: both would instantiate 'a or 'b) + let rec gD3<'a,'b> (x:'a) (y:'b) = C3.M<_>(x,y) = Three // expect: error diff --git a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl index 615200ca5b2..f24aa582b86 100644 --- a/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl +++ b/tests/fsharp/conformance/inference/E_TwoDifferentTypeVariablesGen00rec.bsl @@ -9,7 +9,13 @@ E_TwoDifferentTypeVariablesGen00rec.fsx(62,52,62,53): typecheck error FS0064: Th E_TwoDifferentTypeVariablesGen00rec.fsx(62,18,62,42): typecheck error FS0043: The type ''b' does not match the type 'int' -E_TwoDifferentTypeVariablesGen00rec.fsx(63,45,63,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariablesGen00rec.fsx(63,45,63,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three E_TwoDifferentTypeVariablesGen00rec.fsx(64,56,64,57): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. @@ -23,7 +29,13 @@ E_TwoDifferentTypeVariablesGen00rec.fsx(65,56,65,57): typecheck error FS0064: Th E_TwoDifferentTypeVariablesGen00rec.fsx(65,18,65,42): typecheck error FS0043: The type ''a' does not match the type 'int' -E_TwoDifferentTypeVariablesGen00rec.fsx(66,45,66,59): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariablesGen00rec.fsx(66,45,66,59): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three E_TwoDifferentTypeVariablesGen00rec.fsx(67,55,67,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type ''b'. @@ -31,7 +43,13 @@ E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,42): typecheck error FS0064: Th E_TwoDifferentTypeVariablesGen00rec.fsx(67,18,67,42): typecheck error FS0043: The type ''b' does not match the type ''b0' -E_TwoDifferentTypeVariablesGen00rec.fsx(68,45,68,58): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C13.M : x:'a * y:'a -> One, static member C13.M : x:'a * y:int -> Three +E_TwoDifferentTypeVariablesGen00rec.fsx(68,45,68,58): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'b + +Candidates: + - static member C13.M: x: 'a * y: 'a -> One + - static member C13.M: x: 'a * y: int -> Three E_TwoDifferentTypeVariablesGen00rec.fsx(69,55,69,56): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'b has been constrained to be type 'int'. diff --git a/tests/fsharp/conformance/inference/E_TwoEqualTypeVariables02.bsl b/tests/fsharp/conformance/inference/E_TwoEqualTypeVariables02.bsl index 0e2957d293f..d9df255dd5a 100644 --- a/tests/fsharp/conformance/inference/E_TwoEqualTypeVariables02.bsl +++ b/tests/fsharp/conformance/inference/E_TwoEqualTypeVariables02.bsl @@ -1,12 +1,51 @@ -E_TwoEqualTypeVariables02.fsx(61,33,61,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C12.M : x:'a * y:'a -> One, static member C12.M : x:'a * y:'b -> Two +E_TwoEqualTypeVariables02.fsx(61,33,61,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoEqualTypeVariables02.fsx(62,33,62,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C14.M : x:'a * y:'a -> One, static member C14.M : x:'a * y:C -> Four +Known types of arguments: 'a * 'a -E_TwoEqualTypeVariables02.fsx(63,33,63,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C24.M : x:'a * y:'b -> Two, static member C24.M : x:'a * y:C -> Four +Candidates: + - static member C12.M: x: 'a * y: 'a -> One + - static member C12.M: x: 'a * y: 'b -> Two -E_TwoEqualTypeVariables02.fsx(64,33,64,44): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C123.M : x:'a * y:'a -> One, static member C123.M : x:'a * y:'b -> Two, static member C123.M : x:'a * y:int -> Three +E_TwoEqualTypeVariables02.fsx(62,33,62,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoEqualTypeVariables02.fsx(65,33,65,45): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C1234.M : x:'a * y:'a -> One, static member C1234.M : x:'a * y:'b -> Two, static member C1234.M : x:'a * y:C -> Four, static member C1234.M : x:'a * y:int -> Three +Known types of arguments: 'a * 'a -E_TwoEqualTypeVariables02.fsx(66,33,66,46): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C14.M : x:'a * y:'a -> One, static member C14.M : x:'a * y:C -> Four +Candidates: + - static member C14.M: x: 'a * y: 'a -> One + - static member C14.M: x: 'a * y: C -> Four + +E_TwoEqualTypeVariables02.fsx(63,33,63,43): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C24.M: x: 'a * y: 'b -> Two + - static member C24.M: x: 'a * y: C -> Four + +E_TwoEqualTypeVariables02.fsx(64,33,64,44): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C123.M: x: 'a * y: 'a -> One + - static member C123.M: x: 'a * y: 'b -> Two + - static member C123.M: x: 'a * y: int -> Three + +E_TwoEqualTypeVariables02.fsx(65,33,65,45): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C1234.M: x: 'a * y: 'a -> One + - static member C1234.M: x: 'a * y: 'b -> Two + - static member C1234.M: x: 'a * y: C -> Four + - static member C1234.M: x: 'a * y: int -> Three + +E_TwoEqualTypeVariables02.fsx(66,33,66,46): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C14.M: x: 'a * y: 'a -> One + - static member C14.M: x: 'a * y: C -> Four diff --git a/tests/fsharp/conformance/inference/E_TwoEqualYypeVariables02rec.bsl b/tests/fsharp/conformance/inference/E_TwoEqualYypeVariables02rec.bsl index d9974a98abe..6584af92343 100644 --- a/tests/fsharp/conformance/inference/E_TwoEqualYypeVariables02rec.bsl +++ b/tests/fsharp/conformance/inference/E_TwoEqualYypeVariables02rec.bsl @@ -1,12 +1,51 @@ -E_TwoEqualYypeVariables02rec.fsx(60,37,60,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C12.M : x:'a * y:'a -> One, static member C12.M : x:'a * y:'b -> Two +E_TwoEqualYypeVariables02rec.fsx(60,37,60,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoEqualYypeVariables02rec.fsx(61,37,61,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C14.M : x:'a * y:'a -> One, static member C14.M : x:'a * y:C -> Four +Known types of arguments: 'a * 'a -E_TwoEqualYypeVariables02rec.fsx(62,37,62,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C24.M : x:'a * y:'b -> Two, static member C24.M : x:'a * y:C -> Four +Candidates: + - static member C12.M: x: 'a * y: 'a -> One + - static member C12.M: x: 'a * y: 'b -> Two -E_TwoEqualYypeVariables02rec.fsx(63,37,63,48): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C123.M : x:'a * y:'a -> One, static member C123.M : x:'a * y:'b -> Two, static member C123.M : x:'a * y:int -> Three +E_TwoEqualYypeVariables02rec.fsx(61,37,61,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_TwoEqualYypeVariables02rec.fsx(64,37,64,49): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C1234.M : x:'a * y:'a -> One, static member C1234.M : x:'a * y:'b -> Two, static member C1234.M : x:'a * y:C -> Four, static member C1234.M : x:'a * y:int -> Three +Known types of arguments: 'a * 'a -E_TwoEqualYypeVariables02rec.fsx(65,37,65,50): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C14.M : x:'a * y:'a -> One, static member C14.M : x:'a * y:C -> Four +Candidates: + - static member C14.M: x: 'a * y: 'a -> One + - static member C14.M: x: 'a * y: C -> Four + +E_TwoEqualYypeVariables02rec.fsx(62,37,62,47): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C24.M: x: 'a * y: 'b -> Two + - static member C24.M: x: 'a * y: C -> Four + +E_TwoEqualYypeVariables02rec.fsx(63,37,63,48): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C123.M: x: 'a * y: 'a -> One + - static member C123.M: x: 'a * y: 'b -> Two + - static member C123.M: x: 'a * y: int -> Three + +E_TwoEqualYypeVariables02rec.fsx(64,37,64,49): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C1234.M: x: 'a * y: 'a -> One + - static member C1234.M: x: 'a * y: 'b -> Two + - static member C1234.M: x: 'a * y: C -> Four + - static member C1234.M: x: 'a * y: int -> Three + +E_TwoEqualYypeVariables02rec.fsx(65,37,65,50): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: 'a * 'a + +Candidates: + - static member C14.M: x: 'a * y: 'a -> One + - static member C14.M: x: 'a * y: C -> Four diff --git a/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.bsl b/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.bsl new file mode 100644 index 00000000000..fa5c8fbaf67 --- /dev/null +++ b/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.bsl @@ -0,0 +1,32 @@ + +E_LessThanDotOpenParen001.fsx(23,12,23,15): typecheck error FS0043: No overloads match for method 'op_PlusPlusPlus'. + +Known return type: ^a + +Known type parameters: < (string -> int) , TestType > + +Available overloads: + - static member TestType.(+++) : a: 'T * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: 'T -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: ('T -> 'S) -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match + +E_LessThanDotOpenParen001.fsx(25,10,25,45): typecheck error FS0041: No overloads match for method 'op_PlusPlusPlus'. + +Known types of arguments: (string -> int) * TestType + +Available overloads: + - static member TestType.(+++) : a: 'T * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: 'T -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: ('T -> 'S) -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match + +E_LessThanDotOpenParen001.fsx(26,10,26,68): typecheck error FS0041: No overloads match for method 'op_PlusPlusPlus'. + +Known types of arguments: (string -> int) * TestType + +Available overloads: + - static member TestType.(+++) : a: 'T * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: 'T -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: ('T -> 'S) -> 'T // Argument 'a' doesn't match + - static member TestType.(+++) : a: TestType<'T,'S> * b: TestType<'T,'S> -> 'T // Argument 'a' doesn't match diff --git a/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.fsx b/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.fsx new file mode 100644 index 00000000000..fa36780197d --- /dev/null +++ b/tests/fsharp/conformance/lexicalanalysis/E_LessThanDotOpenParen001.fsx @@ -0,0 +1,26 @@ +type public TestType<'T,'S>() = + + member public s.Value with get() = Unchecked.defaultof<'T> + static member public (+++) (a : TestType<'T,'S>, b : TestType<'T,'S>) = a.Value + static member public (+++) (a : TestType<'T,'S>, b : 'T) = b + static member public (+++) (a : 'T, b : TestType<'T,'S>) = a + static member public (+++) (a : TestType<'T,'S>, b : 'T -> 'S) = a.Value + + // this is triggering https://github.com/dotnet/fsharp/issues/6725 and make the error reported by compiler flaky + //static member public (+++) (a : 'S -> 'T, b : TestType<'T,'S>) = (a 17) + b.Value + +let inline (+++) (a : ^a) (b : ^b) = ((^a or ^b): (static member (+++): ^a * ^b -> ^c) (a,b) ) + +let tt0 = TestType() +let tt1 = TestType() + +let f (x : string) = 18 + +let a0 = tt0 +++ tt1 +let a1 = tt0 +++ 11 +let a2 = 12 +++ tt1 +let a3 = tt0 +++ (fun x -> "18") +let a4 = f +++ tt0 + +let a5 = TestType.(+++)(f, tt0) +let a6 = TestType.(+++)((fun (x : string) -> 18), tt0) diff --git a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass01.bsl b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass01.bsl index 89cb5ac7714..d19330fa22b 100644 --- a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass01.bsl +++ b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass01.bsl @@ -1,2 +1,5 @@ -E_Clashing_Values_in_AbstractClass01.fsx(22,11,22,16): typecheck error FS0041: A unique overload for method 'X' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member Q.X : unit -> decimal, member Q.X : unit -> float +E_Clashing_Values_in_AbstractClass01.fsx(22,11,22,16): typecheck error FS0041: A unique overload for method 'X' could not be determined based on type information prior to this program point. A type annotation may be needed. +Candidates: + - member Q.X: unit -> decimal + - member Q.X: unit -> float diff --git a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass03.bsl b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass03.bsl index 76328f65578..756341cd472 100644 --- a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass03.bsl +++ b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass03.bsl @@ -1,4 +1,16 @@ -E_Clashing_Values_in_AbstractClass03.fsx(16,18,16,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: abstract member D.M : 'T -> int, abstract member D.M : 'U -> string +E_Clashing_Values_in_AbstractClass03.fsx(16,18,16,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_Clashing_Values_in_AbstractClass03.fsx(17,18,17,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: abstract member D.M : 'T -> int, abstract member D.M : 'U -> string +Known type of argument: int + +Candidates: + - abstract D.M: 'T -> int + - abstract D.M: 'U -> string + +E_Clashing_Values_in_AbstractClass03.fsx(17,18,17,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: int + +Candidates: + - abstract D.M: 'T -> int + - abstract D.M: 'U -> string diff --git a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass04.bsl b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass04.bsl index af3ee273c49..89195ec2cc3 100644 --- a/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass04.bsl +++ b/tests/fsharp/conformance/wellformedness/E_Clashing_Values_in_AbstractClass04.bsl @@ -1,4 +1,16 @@ -E_Clashing_Values_in_AbstractClass04.fsx(16,18,16,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: abstract member D.M : 'T -> int, abstract member D.M : 'U -> string +E_Clashing_Values_in_AbstractClass04.fsx(16,18,16,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -E_Clashing_Values_in_AbstractClass04.fsx(17,18,17,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: abstract member D.M : 'T -> int, abstract member D.M : 'U -> string +Known type of argument: int + +Candidates: + - abstract D.M: 'T -> int + - abstract D.M: 'U -> string + +E_Clashing_Values_in_AbstractClass04.fsx(17,18,17,25): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: int + +Candidates: + - abstract D.M: 'T -> int + - abstract D.M: 'U -> string diff --git a/tests/fsharp/core/access/test.fsx b/tests/fsharp/core/access/test.fsx index 26034dc99e5..3d7e7f1624a 100644 --- a/tests/fsharp/core/access/test.fsx +++ b/tests/fsharp/core/access/test.fsx @@ -267,7 +267,6 @@ module RestrictedRecordsAndUnionsUsingPrivateAndInternalTypes = (*--------------------*) - #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.bsl b/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.bsl new file mode 100644 index 00000000000..8513a2590bc --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.bsl @@ -0,0 +1,4 @@ + +test-langversion-5.0.fsx(9,18,9,21): typecheck error FS0001: The type 'float' does not match the type 'int' + +test-langversion-5.0.fsx(9,16,9,17): typecheck error FS0043: The type 'float' does not match the type 'int' diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.fsx b/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.fsx new file mode 100644 index 00000000000..7f44d714162 --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-5.0.fsx @@ -0,0 +1,19 @@ +let f1 a = () +let f2 a b = () + +let v1 = f1[1] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v2 = f2[1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v3 = f2 [1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v4 = f2 (id [1])[2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview + +let _error = 1 + 1.0 + +let xs = [1] +let v5 = xs@[1] //should not give warning + +let arr2 = [| 1 .. 5 |] +arr2.[1..] <- [| 9;8;7;6 |] //should not give warning + +let expectedLists = Array2D.zeroCreate 6 6 +expectedLists.[1,1] <- [ [1] ] //should not give warning + diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.bsl b/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.bsl new file mode 100644 index 00000000000..a2ae7d91887 --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.bsl @@ -0,0 +1,12 @@ + +test-langversion-default.fsx(4,10,4,15): typecheck info FS3367: The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. + +test-langversion-default.fsx(5,10,5,15): typecheck info FS3367: The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. + +test-langversion-default.fsx(6,13,6,19): typecheck info FS3368: The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. + +test-langversion-default.fsx(7,13,7,24): typecheck info FS3368: The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. + +test-langversion-default.fsx(9,18,9,21): typecheck error FS0001: The type 'float' does not match the type 'int' + +test-langversion-default.fsx(9,16,9,17): typecheck error FS0043: The type 'float' does not match the type 'int' diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.fsx b/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.fsx new file mode 100644 index 00000000000..7f44d714162 --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-default.fsx @@ -0,0 +1,19 @@ +let f1 a = () +let f2 a b = () + +let v1 = f1[1] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v2 = f2[1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v3 = f2 [1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v4 = f2 (id [1])[2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview + +let _error = 1 + 1.0 + +let xs = [1] +let v5 = xs@[1] //should not give warning + +let arr2 = [| 1 .. 5 |] +arr2.[1..] <- [| 9;8;7;6 |] //should not give warning + +let expectedLists = Array2D.zeroCreate 6 6 +expectedLists.[1,1] <- [ [1] ] //should not give warning + diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.bsl b/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.bsl new file mode 100644 index 00000000000..3cc3850adfe --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.bsl @@ -0,0 +1,12 @@ + +test-langversion-preview.fsx(4,10,4,15): typecheck info FS3365: The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. + +test-langversion-preview.fsx(5,10,5,15): typecheck info FS3365: The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'. + +test-langversion-preview.fsx(6,13,6,19): typecheck error FS3369: The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. + +test-langversion-preview.fsx(7,13,7,24): typecheck error FS3369: The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. + +test-langversion-preview.fsx(9,18,9,21): typecheck error FS0001: The type 'float' does not match the type 'int' + +test-langversion-preview.fsx(9,16,9,17): typecheck error FS0043: The type 'float' does not match the type 'int' diff --git a/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.fsx b/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.fsx new file mode 100644 index 00000000000..25159f89ff3 --- /dev/null +++ b/tests/fsharp/core/array-no-dot-warnings/test-langversion-preview.fsx @@ -0,0 +1,18 @@ +let f1 a = () +let f2 a b = () + +let v1 = f1[1] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v2 = f2[1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v3 = f2 [1][2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview +let v4 = f2 (id [1])[2] // with langversion 'default' or 'latest' enabled this should give a warning saying to add a space or enable preview + +let _error = 1 + 1.0 + +let xs = [1] +let v5 = xs@[1] //should not give warning + +let arr2 = [| 1 .. 5 |] +arr2.[1..] <- [| 9;8;7;6 |] //should not give warning + +let expectedLists = Array2D.zeroCreate 6 6 +expectedLists.[1,1] <- [ [1] ] //should not give warning diff --git a/tests/fsharp/core/array-no-dot/test.fsx b/tests/fsharp/core/array-no-dot/test.fsx new file mode 100644 index 00000000000..4cba7c3268b --- /dev/null +++ b/tests/fsharp/core/array-no-dot/test.fsx @@ -0,0 +1,444 @@ +// #Conformance #Arrays #Stress #Structs #Mutable #ControlFlow #LetBindings +#if TESTS_AS_APP +module Core_array +#endif + +let mutable failures = [] +let report_failure (s) = + stderr.WriteLine " NO"; failures <- s :: failures +let test s b = if not b then (stderr.Write(s:string); report_failure(s) ) +let check s b1 b2 = test s (b1 = b2) + + +(* TEST SUITE FOR Array *) + +module Array2Tests = + + let test_make_get_set_length () = + let arr = Array2D.create 3 4 0 in + test "fewoih1" (Array2D.get arr 0 0 = 0); + test "fewoih2" (Array2D.get arr 0 1 = 0); + test "vvrew03" (Array2D.get arr 2 2 = 0); + test "vvrew04" (Array2D.get arr 2 3 = 0); + ignore (Array2D.set arr 0 2 4); + test "vsdiuvs5" (Array2D.get arr 0 2 = 4); + arr[0,2] <- 2; + test "vsdiuvs6" (arr[0,2] = 2); + test "vropivrwe7" (Array2D.length1 arr = 3); + test "vropivrwe8" (Array2D.length2 arr = 4) + + let a = Array2D.init 10 10 (fun i j -> i,j) + let b = Array2D.init 2 2 (fun i j -> i+1,j+1) + //test "a2_sub" + // (Array2D.sub a 1 1 2 2 = b) + + + Array2D.blit b 0 0 a 0 0 2 2 + //test "a2_blit" + // (Array2D.sub a 0 0 2 2 = b) + + let _ = test_make_get_set_length () + +module ArrayNonZeroBasedTestsSlice = + let runTest () = + let arr = (Array2D.initBased 5 4 3 2 (fun i j -> (i,j))) + test "fewoih1" (arr[6,*] = [|(6, 4); (6, 5)|]) + test "fewoih2" (arr[*,*][1,*] = [|(6, 4); (6, 5)|]) + test "fewoih3" (arr[*,5] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih4" (arr[*,*][*,1] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih5" (arr.GetLowerBound(0) = 5) + test "fewoih6" (arr.GetLowerBound(1) = 4) + test "fewoih7" (arr[*,*].GetLowerBound(0) = 0) + test "fewoih8" (arr[*,*].GetLowerBound(1) = 0) + test "fewoih9" (arr[*,*][0..,1] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih10" (arr[*,*][1..,1] = [|(6, 5); (7, 5)|]) + let arr2d = + let arr = Array2D.zeroCreateBased 5 4 3 2 + for i in 5..7 do for j in 4..5 do arr[i,j] <- (i,j) + arr + let arr2d2 = + let arr = Array2D.zeroCreate 3 2 + for i in 0..2 do for j in 0..1 do arr[i,j] <- (j,i) + arr + test "fewoih11" (arr2d[6..6,5] = [|(6, 5)|]) + test "fewoih11" (arr2d[..6,5] = [|(5, 5); (6, 5)|]) + test "fewoih11" (arr2d[6..,5] = [|(6, 5); (7, 5)|]) + test "fewoih12" (arr2d[*,*][1..,1] = [|(6, 5); (7, 5)|]) + arr2d[*,*] <- arr2d2 + test "fewoih13" (arr2d[*,*][0..0,1] = [|(1, 0)|]) + test "fewoih13" (arr2d[*,*][1..,1] = [|(1, 1); (1, 2)|]) + test "fewoih13" (arr2d[*,*][1,1..] = [|(1, 1)|]) + test "fewoih13" (arr2d[*,*][1,0..0] = [|(0, 1)|]) + let arr3d = + let arr = System.Array.CreateInstance(typeof, [| 3;2;1 |], [|5;4;3|]) :?> (int*int*int)[,,] + for i in 5..7 do for j in 4..5 do for k in 3..3 do arr[i,j,k] <- (i,j,k) + arr + let arr3d2 = + let arr = System.Array.CreateInstance(typeof, [| 3;2;1 |]) :?> (int*int*int)[,,] + for i in 0..2 do for j in 0..1 do for k in 0..0 do arr[i,j,k] <- (k,j,i) + arr + + test "fewoih14" (arr3d[5,4,3] = (5,4,3)) + test "fewoih15" (arr3d[*,*,*][0,0,0] = (5,4,3)) + arr3d[*,*,*] <- arr3d2 + test "fewoih16" (arr3d[5,4,3] = (0,0,0)) + test "fewoih16" (arr3d[5,5,3] = (0,1,0)) + test "fewoih16" (arr3d[6,5,3] = (0,1,1)) + let _ = runTest() + +module Array3Tests = + + let test_make_get_set_length () = + let arr = Array3D.create 3 4 5 0 in + test "fewoih1" (Array3D.get arr 0 0 0 = 0); + test "fewoih2" (Array3D.get arr 0 1 0 = 0); + test "vvrew03" (Array3D.get arr 2 2 2 = 0); + test "vvrew04" (Array3D.get arr 2 3 4 = 0); + ignore (Array3D.set arr 0 2 3 4); + test "vsdiuvs5" (Array3D.get arr 0 2 3 = 4); + arr[0,2,3] <- 2; + test "vsdiuvs6" (arr[0,2,3] = 2); + arr[0,2,3] <- 3; + test "vsdiuvs" (arr[0,2,3] = 3); + test "vropivrwe7" (Array3D.length1 arr = 3); + test "vropivrwe8" (Array3D.length2 arr = 4); + test "vropivrwe9" (Array3D.length3 arr = 5) + + let _ = test_make_get_set_length () + +module Array4Tests = + + let test_make_get_set_length () = + let arr = Array4D.create 3 4 5 6 0 in + arr[0,2,3,4] <- 2; + test "vsdiuvsq" (arr[0,2,3,4] = 2); + arr[0,2,3,4] <- 3; + test "vsdiuvsw" (arr[0,2,3,4] = 3); + test "vsdiuvsw" (Array4D.get arr 0 2 3 4 = 3); + Array4D.set arr 0 2 3 4 5; + test "vsdiuvsw" (Array4D.get arr 0 2 3 4 = 5); + test "vropivrwee" (Array4D.length1 arr = 3); + test "vropivrwer" (Array4D.length2 arr = 4); + test "vropivrwet" (Array4D.length3 arr = 5) + test "vropivrwey" (Array4D.length4 arr = 6) + + let test_init () = + let arr = Array4D.init 3 4 5 6 (fun i j k m -> i+j+k+m) in + test "vsdiuvs1" (arr[0,2,3,4] = 9); + test "vsdiuvs2" (arr[0,2,3,3] = 8); + test "vsdiuvs3" (arr[0,0,0,0] = 0); + arr[0,2,3,4] <- 2; + test "vsdiuvs4" (arr[0,2,3,4] = 2); + arr[0,2,3,4] <- 3; + test "vsdiuvs5" (arr[0,2,3,4] = 3); + test "vropivrwe1" (Array4D.length1 arr = 3); + test "vropivrwe2" (Array4D.length2 arr = 4); + test "vropivrwe3" (Array4D.length3 arr = 5) + test "vropivrwe4" (Array4D.length4 arr = 6) + + let _ = test_make_get_set_length () + let _ = test_init () + +module Array2TestsNoDot = + + let test_make_get_set_length () = + let arr = Array2D.create 3 4 0 in + test "fewoih1" (Array2D.get arr 0 0 = 0); + test "fewoih2" (Array2D.get arr 0 1 = 0); + test "vvrew03" (Array2D.get arr 2 2 = 0); + test "vvrew04" (Array2D.get arr 2 3 = 0); + ignore (Array2D.set arr 0 2 4); + test "vsdiuvs5" (Array2D.get arr 0 2 = 4); + arr[0,2] <- 2; + test "vsdiuvs6" (arr[0,2] = 2); + test "vropivrwe7" (Array2D.length1 arr = 3); + test "vropivrwe8" (Array2D.length2 arr = 4) + + let a = Array2D.init 10 10 (fun i j -> i,j) + let b = Array2D.init 2 2 (fun i j -> i+1,j+1) + //test "a2_sub" + // (Array2D.sub a 1 1 2 2 = b) + + + Array2D.blit b 0 0 a 0 0 2 2 + //test "a2_blit" + // (Array2D.sub a 0 0 2 2 = b) + + let _ = test_make_get_set_length () + + +module ArrayNonZeroBasedTestsSliceNoDot = + let runTest () = + let arr = (Array2D.initBased 5 4 3 2 (fun i j -> (i,j))) + test "fewoih1" (arr[6,*] = [|(6, 4); (6, 5)|]) + test "fewoih2" (arr[*,*][1,*] = [|(6, 4); (6, 5)|]) + test "fewoih3" (arr[*,5] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih4" (arr[*,*][*,1] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih5" (arr.GetLowerBound(0) = 5) + test "fewoih6" (arr.GetLowerBound(1) = 4) + test "fewoih7" (arr[*,*].GetLowerBound(0) = 0) + test "fewoih8" (arr[*,*].GetLowerBound(1) = 0) + test "fewoih9" (arr[*,*][0..,1] = [|(5, 5); (6, 5); (7, 5)|]) + test "fewoih10" (arr[*,*][1..,1] = [|(6, 5); (7, 5)|]) + let arr2d = + let arr = Array2D.zeroCreateBased 5 4 3 2 + for i in 5..7 do for j in 4..5 do arr[i,j] <- (i,j) + arr + let arr2d2 = + let arr = Array2D.zeroCreate 3 2 + for i in 0..2 do for j in 0..1 do arr[i,j] <- (j,i) + arr + test "fewoih11" (arr2d[6..6,5] = [|(6, 5)|]) + test "fewoih11" (arr2d[..6,5] = [|(5, 5); (6, 5)|]) + test "fewoih11" (arr2d[6..,5] = [|(6, 5); (7, 5)|]) + test "fewoih12" (arr2d[*,*][1..,1] = [|(6, 5); (7, 5)|]) + arr2d[*,*] <- arr2d2 + test "fewoih13" (arr2d[*,*][0..0,1] = [|(1, 0)|]) + test "fewoih13" (arr2d[*,*][1..,1] = [|(1, 1); (1, 2)|]) + test "fewoih13" (arr2d[*,*][1,1..] = [|(1, 1)|]) + test "fewoih13" (arr2d[*,*][1,0..0] = [|(0, 1)|]) + let arr3d = + let arr = System.Array.CreateInstance(typeof, [| 3;2;1 |], [|5;4;3|]) :?> (int*int*int)[,,] + for i in 5..7 do for j in 4..5 do for k in 3..3 do arr[i,j,k] <- (i,j,k) + arr + let arr3d2 = + let arr = System.Array.CreateInstance(typeof, [| 3;2;1 |]) :?> (int*int*int)[,,] + for i in 0..2 do for j in 0..1 do for k in 0..0 do arr[i,j,k] <- (k,j,i) + arr + + test "fewoih14" (arr3d[5,4,3] = (5,4,3)) + test "fewoih15" (arr3d[*,*,*][0,0,0] = (5,4,3)) + arr3d[*,*,*] <- arr3d2 + test "fewoih16" (arr3d[5,4,3] = (0,0,0)) + test "fewoih16" (arr3d[5,5,3] = (0,1,0)) + test "fewoih16" (arr3d[6,5,3] = (0,1,1)) + let _ = runTest() + +module Array3TestsNoDot = + + let test_make_get_set_length () = + let arr = Array3D.create 3 4 5 0 in + test "fewoih1" (Array3D.get arr 0 0 0 = 0); + test "fewoih2" (Array3D.get arr 0 1 0 = 0); + test "vvrew03" (Array3D.get arr 2 2 2 = 0); + test "vvrew04" (Array3D.get arr 2 3 4 = 0); + ignore (Array3D.set arr 0 2 3 4); + test "vsdiuvs5" (Array3D.get arr 0 2 3 = 4); + arr[0,2,3] <- 2; + test "vsdiuvs6" (arr[0,2,3] = 2); + arr[0,2,3] <- 3; + test "vsdiuvs" (arr[0,2,3] = 3); + test "vropivrwe7" (Array3D.length1 arr = 3); + test "vropivrwe8" (Array3D.length2 arr = 4); + test "vropivrwe9" (Array3D.length3 arr = 5) + + let _ = test_make_get_set_length () + +module Array4TestsNoDot = + + let test_make_get_set_length () = + let arr = Array4D.create 3 4 5 6 0 in + arr[0,2,3,4] <- 2; + test "vsdiuvsq" (arr[0,2,3,4] = 2); + arr[0,2,3,4] <- 3; + test "vsdiuvsw" (arr[0,2,3,4] = 3); + test "vsdiuvsw" (Array4D.get arr 0 2 3 4 = 3); + Array4D.set arr 0 2 3 4 5; + test "vsdiuvsw" (Array4D.get arr 0 2 3 4 = 5); + test "vropivrwee" (Array4D.length1 arr = 3); + test "vropivrwer" (Array4D.length2 arr = 4); + test "vropivrwet" (Array4D.length3 arr = 5) + test "vropivrwey" (Array4D.length4 arr = 6) + + let test_init () = + let arr = Array4D.init 3 4 5 6 (fun i j k m -> i+j+k+m) in + test "vsdiuvs1" (arr[0,2,3,4] = 9); + test "vsdiuvs2" (arr[0,2,3,3] = 8); + test "vsdiuvs3" (arr[0,0,0,0] = 0); + arr[0,2,3,4] <- 2; + test "vsdiuvs4" (arr[0,2,3,4] = 2); + arr[0,2,3,4] <- 3; + test "vsdiuvs5" (arr[0,2,3,4] = 3); + test "vropivrwe1" (Array4D.length1 arr = 3); + test "vropivrwe2" (Array4D.length2 arr = 4); + test "vropivrwe3" (Array4D.length3 arr = 5) + test "vropivrwe4" (Array4D.length4 arr = 6) + + let _ = test_make_get_set_length () + let _ = test_init () + +module MiscIndexNotationTests = + [] + type foo + let m, n = 1, 10 + let vs1 = seq { 1 .. 2 .. 3 } + let vs2 = [ 1 .. 2 .. 4 ] + let vs3 = [m .. 1 .. n] + let vs4 = [| 1 .. 2 .. 4 |] + let vs5 = [| m .. 1 .. n |] + + let arr = [| 1;2;3;4;5 |] + let arr2 : int[,] = Array2D.zeroCreate 5 5 + + let v1 = arr[1] + let v2 = arr2[1,1] + let v3 = arr[1..3] + + let v4 = arr[..3] + let v5 = arr[1..] + let v6 = arr[*] + + let v7 = arr2[1..3,1..3] + let v8 = arr2[..3,1..3] + let v9 = arr2[1..,1..3] + let v10 = arr2[*,1..3] + let v11 = arr2[1..3,1..] + let v12 = arr2[..3,1..] + let v13 = arr2[1..,1..] + let v14 = arr2[*,1..] + let v15 = arr2[1..3,..3] + let v16 = arr2[..3,..3] + let v17 = arr2[1..,..3] + let v18 = arr2[*,..3] + let v19 = arr2[1..3,*] + let v20 = arr2[..3,*] + let v21 = arr2[1..,*] + let v22 = arr2[*,*] + + module Apps = + let arrf () = arr + let arrf2 () = arr2 + let v1 = arrf()[1] + let v2 = arrf2()[1,1] + let v3 = arrf()[1..3] + + let v4 = arrf()[..3] + let v5 = arrf()[1..] + let v6 = arrf()[*] + + let v7 = arrf2()[1..3,1..3] + let v8 = arrf2()[..3,1..3] + let v9 = arrf2()[1..,1..3] + let v10 = arrf2()[*,1..3] + let v11 = arrf2()[1..3,1..] + let v12 = arrf2()[..3,1..] + let v13 = arrf2()[1..,1..] + let v14 = arrf2()[*,1..] + let v15 = arrf2()[1..3,..3] + let v16 = arrf2()[..3,..3] + let v17 = arrf2()[1..,..3] + let v18 = arrf2()[*,..3] + let v19 = arrf2()[1..3,*] + let v20 = arrf2()[..3,*] + let v21 = arrf2()[1..,*] + let v22 = arrf2()[*,*] + +module ArrayStructMutation = + module Array1D = + module Test1 = + [] + type T = + val mutable i : int + let a = Array.create 10 Unchecked.defaultof + a[0].i <- 27 + check "wekvw0301" 27 a[0].i + + + module Test2 = + + [] + type T = + val mutable public i : int + member public this.Set i = this.i <- i + let a = Array.create 10 Unchecked.defaultof + a[0].Set 27 + a[2].Set 27 + check "wekvw0302" 27 a[0].i + check "wekvw0303" 27 a[2].i + + module Array2D = + module Test1 = + [] + type T = + val mutable i : int + let a = Array2D.create 10 10 Unchecked.defaultof + a[0,0].i <- 27 + check "wekvw0304" 27 a[0,0].i + + + module Test2 = + + [] + type T = + val mutable public i : int + member public this.Set i = this.i <- i + let a = Array2D.create 10 10 Unchecked.defaultof + a[0,0].Set 27 + a[0,2].Set 27 + check "wekvw0305" 27 a[0,0].i + check "wekvw0306" 27 a[0,2].i + + + module Array3D = + module Test1 = + [] + type T = + val mutable i : int + let a = Array3D.create 10 10 10 Unchecked.defaultof + a[0,0,0].i <- 27 + a[0,2,3].i <- 27 + check "wekvw0307" 27 a[0,0,0].i + check "wekvw0308" 27 a[0,2,3].i + + + module Test2 = + + [] + type T = + val mutable public i : int + member public this.Set i = this.i <- i + let a = Array3D.create 10 10 10 Unchecked.defaultof + a[0,0,0].Set 27 + a[0,2,3].Set 27 + check "wekvw0309" 27 a[0,0,0].i + check "wekvw030q" 27 a[0,2,3].i + + module Array4D = + module Test1 = + [] + type T = + val mutable i : int + let a = Array4D.create 10 10 10 10 Unchecked.defaultof + a[0,0,0,0].i <- 27 + a[0,2,3,4].i <- 27 + check "wekvw030w" 27 a[0,0,0,0].i + check "wekvw030e" 27 a[0,2,3,4].i + + + module Test2 = + + [] + type T = + val mutable public i : int + member public this.Set i = this.i <- i + let a = Array4D.create 10 10 10 10 Unchecked.defaultof + a[0,0,0,0].Set 27 + a[0,2,3,4].Set 27 + check "wekvw030r" 27 a[0,0,0,0].i + check "wekvw030t" 27 a[0,2,3,4].i + + +#if TESTS_AS_APP +let RUN() = failures +#else +let aa = + match failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + stdout.WriteLine "Test Failed" + exit 1 +#endif + diff --git a/tests/fsharp/core/array/test.fsx b/tests/fsharp/core/array/test.fsx index b1879845778..e9d208db69a 100644 --- a/tests/fsharp/core/array/test.fsx +++ b/tests/fsharp/core/array/test.fsx @@ -567,9 +567,11 @@ module Array2Tests = begin test "fewoih2" (Array2D.get arr 0 1 = 0); test "vvrew03" (Array2D.get arr 2 2 = 0); test "vvrew04" (Array2D.get arr 2 3 = 0); + ignore (Array2D.set arr 0 2 4); test "vsdiuvs5" (Array2D.get arr 0 2 = 4); arr.[0,2] <- 2; + test "vsdiuvs6" (arr.[0,2] = 2); test "vropivrwe7" (Array2D.length1 arr = 3); test "vropivrwe8" (Array2D.length2 arr = 4) diff --git a/tests/fsharp/core/auto-widen/5.0/test.bsl b/tests/fsharp/core/auto-widen/5.0/test.bsl new file mode 100644 index 00000000000..9aac4fe55fb --- /dev/null +++ b/tests/fsharp/core/auto-widen/5.0/test.bsl @@ -0,0 +1,879 @@ + +test.fsx(11,20,11,21): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(14,20,14,41): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(17,20,17,44): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(20,21,20,24): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + ''a * 'b' + +test.fsx(28,31,28,32): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(33,27,33,28): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(33,29,33,30): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(36,56,36,57): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(36,58,36,59): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(39,43,39,44): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(39,45,39,46): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(44,41,44,42): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(45,48,45,49): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(45,50,45,51): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(48,30,48,31): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(48,32,48,33): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(58,22,58,24): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(59,22,59,23): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(60,28,60,29): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(60,30,60,31): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'int64'. This element has type 'int'. + +test.fsx(60,32,60,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'int64'. This element has type 'int'. + +test.fsx(60,34,60,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'int64'. This element has type 'int'. + +test.fsx(61,28,61,29): typecheck error FS0001: This expression was expected to have type + 'float' +but here has type + 'int' + +test.fsx(61,30,61,31): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'int'. + +test.fsx(61,32,61,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'int'. + +test.fsx(61,34,61,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'int'. + +test.fsx(62,30,62,31): typecheck error FS0001: This expression was expected to have type + 'float32' +but here has type + 'int' + +test.fsx(62,32,62,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(62,34,62,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(62,36,62,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(63,22,63,43): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(64,28,64,49): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(64,50,64,71): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'int64'. This element has type 'int'. + +test.fsx(67,20,67,23): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(67,20,67,23): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(68,22,68,25): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(68,22,68,25): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(69,26,69,29): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(69,26,69,29): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(93,13,93,20): typecheck error FS0041: No overloads match for method 'M1'. + +Known type of argument: int + +Available overloads: + - static member C.M1: x: int64 -> unit // Argument 'x' doesn't match + - static member C.M1: x: string -> 'a0 // Argument 'x' doesn't match + +test.fsx(99,13,99,22): typecheck error FS0041: No overloads match for method 'M1'. + +Known type of argument: x: int + +Available overloads: + - static member C.M1: ?x: int64 -> unit // Argument 'x' doesn't match + - static member C.M1: x: string -> 'a0 // Argument 'x' doesn't match + +test.fsx(116,20,116,21): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(121,14,121,21): typecheck error FS0041: No overloads match for method 'M1'. + +Known type of argument: int + +Available overloads: + - static member C.M1: [] x: int64[] -> int64 // Argument 'x' doesn't match + - static member C.M1: [] x: int64[] -> int64 // Argument at index 1 doesn't match + +test.fsx(122,19,122,20): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(122,22,122,23): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(127,14,127,21): typecheck error FS0041: No overloads match for method 'M1'. + +Known type of argument: int + +Available overloads: + - static member C.M1: [] x: double[] -> double // Argument 'x' doesn't match + - static member C.M1: [] x: double[] -> double // Argument at index 1 doesn't match + +test.fsx(128,19,128,20): typecheck error FS0001: This expression was expected to have type + 'double' +but here has type + 'int' + +test.fsx(128,22,128,23): typecheck error FS0001: This expression was expected to have type + 'double' +but here has type + 'int' + +test.fsx(135,18,135,19): typecheck error FS0001: This expression was expected to have type + 'C' +but here has type + 'int' + +test.fsx(140,18,140,19): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(145,18,145,19): typecheck error FS0001: This expression was expected to have type + 'decimal' +but here has type + 'int' + +test.fsx(147,18,147,19): typecheck error FS0001: This expression was expected to have type + 'decimal' +but here has type + 'int' + +test.fsx(149,39,149,41): typecheck error FS0001: This expression was expected to have type + 'Xml.Linq.XNamespace' +but here has type + 'string' + +test.fsx(154,18,154,20): typecheck error FS0001: This expression was expected to have type + 'Xml.Linq.XNamespace' +but here has type + 'string' + +test.fsx(159,18,159,21): typecheck error FS0001: This expression was expected to have type + 'Xml.Linq.XName' +but here has type + 'string' + +test.fsx(165,18,165,19): typecheck error FS0001: The type 'int' is not compatible with the type 'C' + +test.fsx(165,17,165,20): typecheck error FS0193: Type constraint mismatch. The type + 'int' +is not compatible with type + 'C' + + +test.fsx(172,18,172,21): typecheck error FS0001: The type 'Y' is not compatible with the type 'X' + +test.fsx(172,17,172,22): typecheck error FS0193: Type constraint mismatch. The type + 'Y' +is not compatible with type + 'X' + + +test.fsx(178,20,178,21): typecheck error FS0001: This expression was expected to have type + 'C' +but here has type + 'int' + +test.fsx(180,15,180,16): typecheck error FS0001: The type 'int' is not compatible with the type 'C' + +test.fsx(186,27,186,28): typecheck error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(188,15,188,16): typecheck error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(191,21,191,24): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + ''a * 'b' + +test.fsx(192,27,192,28): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(192,29,192,30): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(195,56,195,57): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(195,58,195,59): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(198,49,198,50): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(198,51,198,54): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(201,33,201,34): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(201,35,201,38): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(204,43,204,44): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(204,45,204,46): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(207,20,207,35): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'R' + +test.fsx(210,22,210,41): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'R' + +test.fsx(213,20,213,36): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'SR' + +test.fsx(216,22,216,43): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'SR' + +test.fsx(219,20,219,33): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'U' + +test.fsx(222,21,222,31): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'U' + +test.fsx(225,21,225,31): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int -> U' + +test.fsx(228,21,228,40): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'SU' + +test.fsx(231,21,231,37): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'SU' + +test.fsx(234,21,234,37): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int -> SU' + +test.fsx(237,13,237,14): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(237,16,237,19): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'byte' + +test.fsx(237,30,237,33): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(237,35,237,36): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(243,42,243,43): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(246,45,246,46): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(246,54,246,57): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(246,65,246,68): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'byte'. + +test.fsx(248,49,248,50): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(248,51,248,52): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(253,36,253,37): typecheck error FS0001: This expression was expected to have type + 'IComparable' +but here has type + 'int' + +test.fsx(256,30,256,39): typecheck error FS0001: This expression was expected to have type + 'Array' +but here has type + 'uint16[]' + +test.fsx(258,30,258,38): typecheck error FS0001: This expression was expected to have type + 'Array' +but here has type + ''a[]' + +test.fsx(260,36,260,38): typecheck error FS0001: This expression was expected to have type + 'IComparable' +but here has type + 'Numerics.BigInteger' + +test.fsx(263,44,263,63): typecheck error FS0001: This expression was expected to have type + 'IComparable' +but here has type + 'string' + +test.fsx(266,44,266,68): typecheck error FS0001: This expression was expected to have type + 'IComparable' +but here has type + 'string' + +test.fsx(268,21,268,45): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(270,36,270,60): typecheck error FS0001: This expression was expected to have type + 'IComparable' +but here has type + 'string' + +test.fsx(275,35,275,36): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(275,37,275,38): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(276,35,276,40): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(276,41,276,42): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(277,44,277,45): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(278,44,278,45): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(278,55,278,58): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(279,68,279,71): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(280,82,280,85): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(282,21,282,22): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(283,22,283,29): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(284,21,284,23): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(285,22,285,33): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(286,22,286,45): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'IComparable' + +test.fsx(287,22,287,24): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(288,22,288,24): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(289,21,289,76): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'ICloneable' + +test.fsx(290,21,290,23): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(291,21,291,30): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(291,21,291,30): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(292,24,292,26): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +test.fsx(295,34,295,35): typecheck error FS0001: The 'if' expression needs to have type 'obj' to satisfy context type requirements. It currently has type 'int'. + +test.fsx(295,41,295,44): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(296,35,296,36): typecheck error FS0001: The 'if' expression needs to have type 'obj' to satisfy context type requirements. It currently has type 'int'. + +test.fsx(296,42,296,45): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(297,35,297,36): typecheck error FS0001: The 'if' expression needs to have type 'obj' to satisfy context type requirements. It currently has type 'int'. + +test.fsx(297,52,297,55): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'byte'. + +test.fsx(297,61,297,64): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(300,25,300,26): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(300,37,300,40): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'float' + +test.fsx(303,25,303,26): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(306,45,306,46): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(306,54,306,57): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(309,19,309,20): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'int' + +test.fsx(310,32,310,33): typecheck error FS0001: The 'if' expression needs to have type 'obj' to satisfy context type requirements. It currently has type 'int'. + +test.fsx(310,39,310,42): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'obj'. This branch returns a value of type 'float'. + +test.fsx(313,37,313,38): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(314,37,314,38): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(317,50,317,51): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(319,52,319,53): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(320,37,320,38): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(323,57,323,58): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(325,57,325,58): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(326,37,326,38): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(328,42,328,43): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(330,42,330,43): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(331,38,331,39): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(335,28,335,39): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(337,9,338,34): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(340,9,341,33): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(343,9,344,35): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(346,9,347,36): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(349,9,349,36): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(351,9,351,40): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(353,9,354,40): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(356,9,357,41): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(359,9,359,35): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(361,9,362,36): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(364,9,365,37): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a list' + +test.fsx(368,39,368,40): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(369,39,369,40): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(372,52,372,53): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(374,54,374,55): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(375,39,375,40): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(378,59,378,60): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(380,59,380,60): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(381,39,381,40): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(383,44,383,45): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(385,44,385,45): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(386,40,386,41): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(390,28,390,41): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(391,30,392,57): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(393,30,394,56): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(395,30,396,58): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(397,30,398,59): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(399,30,399,59): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(400,30,400,63): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(401,30,402,63): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(403,30,404,64): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(405,31,405,59): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(406,31,407,60): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(408,31,409,61): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + ''a[]' + +test.fsx(429,10,437,16): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + 'OtherSeq<'a>' + +test.fsx(448,9,450,49): typecheck error FS0001: This expression was expected to have type + 'seq' +but here has type + 'OtherSeqImpl<'a>' + +test.fsx(452,32,452,33): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' + +test.fsx(454,46,454,47): typecheck error FS0001: This expression was expected to have type + 'int64' +but here has type + 'int' diff --git a/tests/fsharp/core/auto-widen/5.0/test.fsx b/tests/fsharp/core/auto-widen/5.0/test.fsx new file mode 100644 index 00000000000..1905c5977d0 --- /dev/null +++ b/tests/fsharp/core/auto-widen/5.0/test.fsx @@ -0,0 +1,467 @@ + +#r "System.Xml.Linq.dll" +#r "System.Xml.XDocument.dll" + +let mutable failures : string list = [] + +open System + +module BasicTypeDirectedConversionsToObj = + // Constant expression + let x1 : obj = 1 + + // Field literal expressions + let x2 : obj = System.Int32.MaxValue + + // Field literal expressions + let x3 : obj = System.Int32.Parse("12") + + // Tuple expressions + let x4 : obj = (1,2) + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x : obj = 1 + 1 + + // Values + let x8 (s:string) : obj = s + +module BasicTypeDirectedConversionsToTuple = + + // Tuple expressions + let x2 : obj * obj = (1,2) + + // Let expressions + let x3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // Struct tuple expressions + let x4 : struct (obj * obj) = struct (1,2) + +module BasicTypeDirectedConversionsForFuncReturn = + + // Return in lambda expressions + let x5 : (unit -> obj) = (fun () -> 1) + let x6 : (unit -> obj * obj) = (fun () -> (1,2)) + + // Return in function expressions + let x7 () : obj * obj = (1,2) + +type R = { mutable F1: (obj * obj) } +[] +type SR = { mutable SF1: (obj * obj) } +type U = UnionCase0 | UnionCase1 of int +[] +type SU = StructUnionCase0 | StructUnionCase1 of int +module IntegerWidening = + let i1 = 0 + let x0 : int64 = i1 // integer value + let x1 : int64 = 0 // integer constant + let x2 : int64 list = [1;2;3;4] // within a list + let x3 : float list = [1;2;3;4] + let x4 : float32 list = [1;2;3;4] + let x5 : int64 = System.Int32.MaxValue + let x6 : int64 list = [System.Int32.MaxValue;System.Int32.MaxValue] + let f () = 1 + + let x7 : obj = f() + let x8 : int64 = f() + let x9 : int64 = id (f()) // generic does work + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x6 : int64 = 1 + 1 + // let x6 : int64 = id (1 + 1) + +module Overloads1 = + type C() = + static member M1(x:int) = 1 + static member M1(x:int64) = failwith "nope" + let x = C.M1(2) + +module Overloads2 = + type C() = + static member M1(x:int) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2L) + +module Overloads3 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2) + +module OverloadedOptionals1 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2) + +module OverloadedOptionals2 = + type C() = + static member M1(?x:int) = printfn "ok at line %s" __LINE__ + static member M1(?x:int64) = failwith "nope" + let x = C.M1(x=2) + +module OverloadedOptionals3 = + type C() = + static member M1(?x:int) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2L) + +module Optionals1 = + type C() = + static member M1(?x:int64) = 1 + let x = C.M1(x=2) + +module ParamArray1 = + type C() = + static member M1([] x:int64[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5L) + +module ParamArray2 = + type C() = + static member M1([] x:double[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5.0) + +module ConvertToSealedViaOpImplicit = + [] + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertNoOverloadin = + type C() = + static member M1(x:int64) = 1 + let x = C.M1(2) + +module ConvertNoOverloadingViaOpImplicit = + type C() = + static member M1(x:decimal) = () + let x = C.M1(2) + +let d: decimal = 3 + +let ns : System.Xml.Linq.XNamespace = "" + +module ConvertViaOpImplicit2 = + type C() = + static member M1(ns:System.Xml.Linq.XNamespace) = 1 + let x = C.M1("") + +module ConvertViaOpImplicit3 = + type C() = + static member M1(ns:System.Xml.Linq.XName) = 1 + let x = C.M1("a") + +module ConvertViaOpImplicit4 = + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertViaOpImplicit5 = + type X() = + static member M1(x:X) = 1 + type Y() = + static member op_Implicit(y:Y) = X() + let x = X.M1(Y()) + +module ConvertViaOpImplicitGeneric = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:C = 1 + let f (c:C) = 1 + let x = f 2 + +module ConvertViaNullable = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:Nullable = 1 + let f (c:Nullable) = 1 + let x = f 2 + +let annotations = + let v1 : obj = (1,2) + let v2 : obj * obj = (1,2) + + // structure through let + let v3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // structure through let rec + let v4 : (obj * obj) = (let rec f x = x in (3,4.0)) + + // structure through sequence + let v5 : (obj * obj) = (); (3,4.0) + + // struct tuple + let v6 : struct (obj * obj) = struct (1,2) + + // record (both field and overall result) + let v7 : obj = { F1 = (1, 2) } + + // record + let v7a : obj = ({ F1 = (1, 2) } : R) + + // struct record (both field and overall result) + let v8 : obj = { SF1 = (1, 2) } + + // struct record (both field and overall result) + let v8a : obj = ({ SF1 = (1, 2) } : SR) + + // union + let v9 : obj = UnionCase1(3) + + // union + let v10 : obj = UnionCase0 + + // union as first-class + let v11 : obj = UnionCase1 + + // struct union + let v12 : obj = StructUnionCase1(3) + + // struct union + let v13 : obj = StructUnionCase0 + + // struct union as first-class + let v14 : obj = StructUnionCase1 + + // record (both field and overall result) + { F1 = (1, 2uy) }.F1 <- (3.0, 4) + + // anon record + let v15 : {| A: obj |} = {| A = 1 |} + + // lambda return + let v16 : (unit -> obj) = (fun () -> 1) + + // function lambda return + let v17 : (int -> obj) = (function 1 -> 1 | 2 -> 3.0 | _ -> 4uy) + + let v18 : (unit -> obj * obj) = (fun () -> (1,2)) + + // constants + (1 :> System.IComparable) |> ignore + + let v19 : System.IComparable = 1 + + // array constants + let v20 : System.Array = [| 1us |] + + let v21 : System.Array = [| 1I |] + + let v22 : System.IComparable = 1I + + // property + let v23 : System.IComparable = System.String.Empty + + // method + let v24 : System.IComparable = System.String.Format("") + + let v25 : obj = System.String.Format("") + + let v26 : System.IComparable = System.String.Format("") + + // array constants + + let v27 : obj[] = [| 1 |] + let v28 : (obj * obj)[] = [| (1,1) |] + let v29 : (obj * obj)[] = [| ("abc",1) |] + let v30 : (string * obj)[] = [| ("abc",1) |] + let v31 : (string * obj)[] = [| ("abc",1); ("abc",3.0) |] + let v32 : (string * obj)[] = [| Unchecked.defaultof<_>; ("abc",3.0) |] + let v33 : struct (string * obj)[] = [| Unchecked.defaultof<_>; struct ("abc",3.0) |] + + let v34 : obj = 1 + let v35 : obj = (1 : int) + let v36 : obj = "" + let v37 : obj = ("" : string) + let v38 : obj = ("" : System.IComparable) + let v39 : obj = ("" : _) + let v40 : obj = ("" : obj) + let v41 : obj = { new System.ICloneable with member x.Clone() = obj() } + let v42 : obj = "" + let v43 : obj = string "" + let v44 : obj = id "" + + // conditional + let v45 : obj = if true then 1 else 3.0 + let v46 : obj = (if true then 1 else 3.0) + let v47 : obj = (if true then 1 elif true then 2uy else 3.0) + + // try-with + let v48 : obj = try 1 with _ -> 3.0 + + // try-finally + let v49 : obj = try 1 finally () + + // match + let v50 : obj = match true with true -> 1 | _ -> 3.0 + () + +let f1 () : obj = 1 +let f2 () : obj = if true then 1 else 3.0 + +module TestComputedListExpressionsAtList = + let x1 : list = [ yield 1 ] + let x2 : list = [ yield 1; + if true then yield 2L ] + let x3 : list = [ yield 1L; + if true then yield 2 ] + let x4 : list = [ yield 1L; + while false do yield 2 ] + let x5 : list = [ yield 1; + while false do yield 2L ] + let x6 : list = [ while false do yield 2L ] + let x7 : list = [ for i in 0 .. 10 do yield 2 ] + let x8 : list = [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : list = [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : list = [ try yield 2 finally () ] + let x11 : list = [ yield 1L + try yield 2 finally () ] + let x12 : list = [ yield 1 + try yield 2L finally () ] + +module TestComputedListExpressionsAtSeq = + let x1 : seq = [ yield 1 ] + let x2 : seq = + [ yield 1; + if true then yield 2L ] + let x3 : seq = + [ yield 1L; + if true then yield 2 ] + let x4 : seq = + [ yield 1L; + while false do yield 2 ] + let x5 : seq = + [ yield 1; + while false do yield 2L ] + let x6 : seq = + [ while false do yield 2L ] + let x7 : seq = + [ for i in 0 .. 10 do yield 2 ] + let x8 : seq = + [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : seq = + [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : seq = + [ try yield 2 finally () ] + let x11 : seq = + [ yield 1L + try yield 2 finally () ] + let x12 : seq = + [ yield 1 + try yield 2L finally () ] + +module TestComputedArrayExpressionsAtArray = + let x1 : array = [| yield 1 |] + let x2 : array = [| yield 1; + if true then yield 2L |] + let x3 : array = [| yield 1L; + if true then yield 2 |] + let x4 : array = [| yield 1L; + while false do yield 2 |] + let x5 : array = [| yield 1; + while false do yield 2L |] + let x6 : array = [| while false do yield 2L |] + let x7 : array = [| for i in 0 .. 10 do yield 2 |] + let x8 : array = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : array = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : array = [| try yield 2 finally () |] + let x11 : array = [| yield 1L + try yield 2 finally () |] + let x12 : array = [| yield 1 + try yield 2L finally () |] + +module TestComputedArrayExpressionsAtSeq = + let x1 : seq = [| yield 1 |] + let x2 : seq = [| yield 1; + if true then yield 2L |] + let x3 : seq = [| yield 1L; + if true then yield 2 |] + let x4 : seq = [| yield 1L; + while false do yield 2 |] + let x5 : seq = [| yield 1; + while false do yield 2L |] + let x6 : seq = [| while false do yield 2L |] + let x7 : seq = [| for i in 0 .. 10 do yield 2 |] + let x8 : seq = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : seq = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : seq = [| try yield 2 finally () |] + let x11 : seq = [| yield 1L + try yield 2 finally () |] + let x12 : seq = [| yield 1 + try yield 2L finally () |] + +module TestInferObjExprTypeParamFromKNownType = + // Check we are inferring type int64 + let x1 : seq = + { new seq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeq<'T> = + inherit seq<'T> + + // Check we are inferring type int64 + let x2 : seq = + { new OtherSeq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeqImpl<'T>(f : 'T -> unit) = + interface OtherSeq<'T> with + member x.GetEnumerator() = + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + + let x3 : seq = + new OtherSeqImpl<_>(fun x -> + // The 'ToString("4")' would not resolve if the type parameter is not inferred to be int64 by this point + x.ToString("4") |> ignore) + + let x4 : int64 * int32 = (3, 3) + + let x5 : {| A: int64; B: int32 |} = {| A=3; B=3 |} + +printfn "test done" + +let aa = + match failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + printfn "Test Failed, failures = %A" failures + exit 1 + diff --git a/tests/fsharp/core/auto-widen/preview-default-warns/test.bsl b/tests/fsharp/core/auto-widen/preview-default-warns/test.bsl new file mode 100644 index 00000000000..fc365207280 --- /dev/null +++ b/tests/fsharp/core/auto-widen/preview-default-warns/test.bsl @@ -0,0 +1,49 @@ + +test.fsx(147,18,147,19): typecheck error FS3391: This expression uses the implicit conversion 'Decimal.op_Implicit(value: int) : decimal' to convert type 'int' to type 'decimal'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(149,39,149,41): typecheck error FS3391: This expression uses the implicit conversion 'Xml.Linq.XNamespace.op_Implicit(namespaceName: string) : Xml.Linq.XNamespace' to convert type 'string' to type 'Xml.Linq.XNamespace'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(178,20,178,21): typecheck error FS3391: This expression uses the implicit conversion 'static member C.op_Implicit: x: 'T -> C<'T>' to convert type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(180,15,180,16): typecheck error FS3391: This expression uses the implicit conversion 'static member C.op_Implicit: x: 'T -> C<'T>' to convert type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(186,27,186,28): typecheck error FS3391: This expression uses the implicit conversion 'Nullable.op_Implicit(value: int) : Nullable' to convert type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(188,15,188,16): typecheck error FS3391: This expression uses the implicit conversion 'Nullable.op_Implicit(value: int) : Nullable' to convert type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(463,18,463,19): typecheck error FS0001: This expression was expected to have type + 'C' +but here has type + 'int' + +test.fsx(471,18,471,19): typecheck error FS0044: This construct is deprecated. nope + +test.fsx(482,18,482,21): typecheck error FS3387: This expression has type 'B' and is only made compatible with type 'C' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are: + static member B.op_Implicit: x: B -> C + static member C.op_Implicit: x: B -> C + +test.fsx(482,18,482,21): typecheck error FS3387: This expression has type 'B' and is only made compatible with type 'C' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are: + static member B.op_Implicit: x: B -> C + static member C.op_Implicit: x: B -> C + +test.fsx(546,30,546,31): typecheck error FS0001: This expression was expected to have type + 'float32' +but here has type + 'int' + +test.fsx(546,32,546,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(546,34,546,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(546,36,546,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(547,28,547,32): typecheck error FS0001: This expression was expected to have type + 'float' +but here has type + 'float32' + +test.fsx(547,33,547,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'float32'. + +test.fsx(547,38,547,42): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'float32'. + +test.fsx(547,43,547,47): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float'. This element has type 'float32'. diff --git a/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx b/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx new file mode 100644 index 00000000000..753a70f94ad --- /dev/null +++ b/tests/fsharp/core/auto-widen/preview-default-warns/test.fsx @@ -0,0 +1,574 @@ + +#r "System.Xml.Linq.dll" +#r "System.Xml.XDocument.dll" + +let mutable failures : string list = [] + +open System + +module BasicTypeDirectedConversionsToObj = + // Constant expression + let x1 : obj = 1 + + // Field literal expressions + let x2 : obj = System.Int32.MaxValue + + // Field literal expressions + let x3 : obj = System.Int32.Parse("12") + + // Tuple expressions + let x4 : obj = (1,2) + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x : obj = 1 + 1 + + // Values + let x8 (s:string) : obj = s + +module BasicTypeDirectedConversionsToTuple = + + // Tuple expressions + let x2 : obj * obj = (1,2) + + // Let expressions + let x3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // Struct tuple expressions + let x4 : struct (obj * obj) = struct (1,2) + +module BasicTypeDirectedConversionsForFuncReturn = + + // Return in lambda expressions + let x5 : (unit -> obj) = (fun () -> 1) + let x6 : (unit -> obj * obj) = (fun () -> (1,2)) + + // Return in function expressions + let x7 () : obj * obj = (1,2) + +type R = { mutable F1: (obj * obj) } +[] +type SR = { mutable SF1: (obj * obj) } +type U = UnionCase0 | UnionCase1 of int +[] +type SU = StructUnionCase0 | StructUnionCase1 of int +module IntegerWidening = + let i1 = 0 + let x0 : int64 = i1 // integer value + let x1 : int64 = 0 // integer constant + let x2 : int64 list = [1;2;3;4] // within a list + let x3 : float list = [1;2;3;4.0] + //let x4 : float32 list = [1;2;3;4] + let x5 : int64 = System.Int32.MaxValue + let x6 : int64 list = [System.Int32.MaxValue;System.Int32.MaxValue] + let f () = 1 + + let x7 : obj = f() + let x8 : int64 = f() + let x9 : int64 = id (f()) // generic does work + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x6 : int64 = 1 + 1 + // let x6 : int64 = id (1 + 1) + +module Overloads1 = + type C() = + static member M1(x:int) = 1 + static member M1(x:int64) = failwith "nope" + let x = C.M1(2) + +module Overloads2 = + type C() = + static member M1(x:int) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2L) + +module Overloads3 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2) + +module OverloadedOptionals1 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2) + +module OverloadedOptionals2 = + type C() = + static member M1(?x:int) = printfn "ok at line %s" __LINE__ + static member M1(?x:int64) = failwith "nope" + let x = C.M1(x=2) + +module OverloadedOptionals3 = + type C() = + static member M1(?x:int) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2L) + +module Optionals1 = + type C() = + static member M1(?x:int64) = 1 + let x = C.M1(x=2) + +module ParamArray1 = + type C() = + static member M1([] x:int64[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5L) + +module ParamArray2 = + type C() = + static member M1([] x:double[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5.0) + +module ConvertToSealedViaOpImplicit = + [] + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertNoOverloadin = + type C() = + static member M1(x:int64) = 1 + let x = C.M1(2) + +module ConvertNoOverloadingViaOpImplicit = + type C() = + static member M1(x:decimal) = () + let x = C.M1(2) + +let d: decimal = 3 + +let ns : System.Xml.Linq.XNamespace = "" + +module ConvertViaOpImplicit2 = + type C() = + static member M1(ns:System.Xml.Linq.XNamespace) = 1 + let x = C.M1("") + +module ConvertViaOpImplicit3 = + type C() = + static member M1(ns:System.Xml.Linq.XName) = 1 + let x = C.M1("a") + +module ConvertViaOpImplicit4 = + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertViaOpImplicit5 = + type X() = + static member M1(x:X) = 1 + type Y() = + static member op_Implicit(y:Y) = X() + let x = X.M1(Y()) + +module ConvertViaOpImplicitGeneric = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:C = 1 + let f (c:C) = 1 + let x = f 2 + +module ConvertViaNullable = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:Nullable = 1 + let f (c:Nullable) = 1 + let x = f 2 + +let annotations = + let v1 : obj = (1,2) + let v2 : obj * obj = (1,2) + + // structure through let + let v3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // structure through let rec + let v4 : (obj * obj) = (let rec f x = x in (3,4.0)) + + // structure through sequence + let v5 : (obj * obj) = (); (3,4.0) + + // struct tuple + let v6 : struct (obj * obj) = struct (1,2) + + // record (both field and overall result) + let v7 : obj = { F1 = (1, 2) } + + // record + let v7a : obj = ({ F1 = (1, 2) } : R) + + // struct record (both field and overall result) + let v8 : obj = { SF1 = (1, 2) } + + // struct record (both field and overall result) + let v8a : obj = ({ SF1 = (1, 2) } : SR) + + // union + let v9 : obj = UnionCase1(3) + + // union + let v10 : obj = UnionCase0 + + // union as first-class + let v11 : obj = UnionCase1 + + // struct union + let v12 : obj = StructUnionCase1(3) + + // struct union + let v13 : obj = StructUnionCase0 + + // struct union as first-class + let v14 : obj = StructUnionCase1 + + // record (both field and overall result) + { F1 = (1, 2uy) }.F1 <- (3.0, 4) + + // anon record + let v15 : {| A: obj |} = {| A = 1 |} + + // lambda return + let v16 : (unit -> obj) = (fun () -> 1) + + // function lambda return + let v17 : (int -> obj) = (function 1 -> 1 | 2 -> 3.0 | _ -> 4uy) + + let v18 : (unit -> obj * obj) = (fun () -> (1,2)) + + // constants + (1 :> System.IComparable) |> ignore + + let v19 : System.IComparable = 1 + + // array constants + let v20 : System.Array = [| 1us |] + + let v21 : System.Array = [| 1I |] + + let v22 : System.IComparable = 1I + + // property + let v23 : System.IComparable = System.String.Empty + + // method + let v24 : System.IComparable = System.String.Format("") + + let v25 : obj = System.String.Format("") + + let v26 : System.IComparable = System.String.Format("") + + // array constants + + let v27 : obj[] = [| 1 |] + let v28 : (obj * obj)[] = [| (1,1) |] + let v29 : (obj * obj)[] = [| ("abc",1) |] + let v30 : (string * obj)[] = [| ("abc",1) |] + let v31 : (string * obj)[] = [| ("abc",1); ("abc",3.0) |] + let v32 : (string * obj)[] = [| Unchecked.defaultof<_>; ("abc",3.0) |] + let v33 : struct (string * obj)[] = [| Unchecked.defaultof<_>; struct ("abc",3.0) |] + + let v34 : obj = 1 + let v35 : obj = (1 : int) + let v36 : obj = "" + let v37 : obj = ("" : string) + let v38 : obj = ("" : System.IComparable) + let v39 : obj = ("" : _) + let v40 : obj = ("" : obj) + let v41 : obj = { new System.ICloneable with member x.Clone() = obj() } + let v42 : obj = "" + let v43 : obj = string "" + let v44 : obj = id "" + + // conditional + let v45 : obj = if true then 1 else 3.0 + let v46 : obj = (if true then 1 else 3.0) + let v47 : obj = (if true then 1 elif true then 2uy else 3.0) + + // try-with + let v48 : obj = try 1 with _ -> 3.0 + + // try-finally + let v49 : obj = try 1 finally () + + // match + let v50 : obj = match true with true -> 1 | _ -> 3.0 + () + +let f1 () : obj = 1 +let f2 () : obj = if true then 1 else 3.0 + +module TestComputedListExpressionsAtList = + let x1 : list = [ yield 1 ] + let x2 : list = [ yield 1; + if true then yield 2L ] + let x3 : list = [ yield 1L; + if true then yield 2 ] + let x4 : list = [ yield 1L; + while false do yield 2 ] + let x5 : list = [ yield 1; + while false do yield 2L ] + let x6 : list = [ while false do yield 2L ] + let x7 : list = [ for i in 0 .. 10 do yield 2 ] + let x8 : list = [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : list = [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : list = [ try yield 2 finally () ] + let x11 : list = [ yield 1L + try yield 2 finally () ] + let x12 : list = [ yield 1 + try yield 2L finally () ] + +module TestComputedListExpressionsAtSeq = + let x1 : seq = [ yield 1 ] + let x2 : seq = + [ yield 1; + if true then yield 2L ] + let x3 : seq = + [ yield 1L; + if true then yield 2 ] + let x4 : seq = + [ yield 1L; + while false do yield 2 ] + let x5 : seq = + [ yield 1; + while false do yield 2L ] + let x6 : seq = + [ while false do yield 2L ] + let x7 : seq = + [ for i in 0 .. 10 do yield 2 ] + let x8 : seq = + [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : seq = + [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : seq = + [ try yield 2 finally () ] + let x11 : seq = + [ yield 1L + try yield 2 finally () ] + let x12 : seq = + [ yield 1 + try yield 2L finally () ] + +module TestComputedArrayExpressionsAtArray = + let x1 : array = [| yield 1 |] + let x2 : array = [| yield 1; + if true then yield 2L |] + let x3 : array = [| yield 1L; + if true then yield 2 |] + let x4 : array = [| yield 1L; + while false do yield 2 |] + let x5 : array = [| yield 1; + while false do yield 2L |] + let x6 : array = [| while false do yield 2L |] + let x7 : array = [| for i in 0 .. 10 do yield 2 |] + let x8 : array = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : array = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : array = [| try yield 2 finally () |] + let x11 : array = [| yield 1L + try yield 2 finally () |] + let x12 : array = [| yield 1 + try yield 2L finally () |] + +module TestComputedArrayExpressionsAtSeq = + let x1 : seq = [| yield 1 |] + let x2 : seq = [| yield 1; + if true then yield 2L |] + let x3 : seq = [| yield 1L; + if true then yield 2 |] + let x4 : seq = [| yield 1L; + while false do yield 2 |] + let x5 : seq = [| yield 1; + while false do yield 2L |] + let x6 : seq = [| while false do yield 2L |] + let x7 : seq = [| for i in 0 .. 10 do yield 2 |] + let x8 : seq = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : seq = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : seq = [| try yield 2 finally () |] + let x11 : seq = [| yield 1L + try yield 2 finally () |] + let x12 : seq = [| yield 1 + try yield 2L finally () |] + +module TestInferObjExprTypeParamFromKNownType = + // Check we are inferring type int64 + let x1 : seq = + { new seq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeq<'T> = + inherit seq<'T> + + // Check we are inferring type int64 + let x2 : seq = + { new OtherSeq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeqImpl<'T>(f : 'T -> unit) = + interface OtherSeq<'T> with + member x.GetEnumerator() = + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + + let x3 : seq = + new OtherSeqImpl<_>(fun x -> + // The 'ToString("4")' would not resolve if the type parameter is not inferred to be int64 by this point + x.ToString("4") |> ignore) + + let x4 : int64 * int32 = (3, 3) + + let x5 : {| A: int64; B: int32 |} = {| A=3; B=3 |} + +// These tests are activate for the case where warnings are on +#if NEGATIVE +module TestAcessibilityOfOpImplicit = + [] + type C() = + static member private op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module TestObsoleteOfOpImplicit = + [] + type C() = + [] + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module TestAmbiguousOpImplicit = + [] + type B() = + static member op_Implicit(x:B) = C(2) + + and [] C(x:int) = + static member op_Implicit(x:B) = C(1) + static member M1(C:C) = 1 + member _.Value = x + let x = C.M1(B()) + +#endif + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures <- failures @ [s] + +let test (s : string) b = + stderr.Write(s) + if b then stderr.WriteLine " OK" + else report_failure (s) + +let check s b1 b2 = test s (b1 = b2) + +module TestAmbiguousOpImplicitOkOneIsPrivate = + [] + type B() = + static member private op_Implicit(x:B) = C(1) + + and [] C(x:int) = + static member op_Implicit(x:B) = C(2) + static member M1(c:C) = c.Value + member _.Value = x + let x = C.M1(B()) + check "vewenlwevl" x 2 + +module TestAmbiguousOpImplicitOkOtherIsPrivate = + [] + type B() = + static member op_Implicit(x:B) = C(1) + + and [] C(x:int) = + static member private op_Implicit(x:B) = C(2) + static member M1(c:C) = c.Value + member _.Value = x + let x = C.M1(B()) + check "vewenlwevl" x 1 + +#nowarn "1215" +module TestExtrinsicOpImplicitIgnoredCompletely = + [] + type B() = class end + + and [] C(x:int) = + static member op_Implicit(x:B) = C(3) + static member M1(c:C) = c.Value + member _.Value = x + + [] + module Extensions = + type B with + // This gets ignored - a warning 1215 is actually reported implying this (ignored above) + static member op_Implicit(x:B) = C(1) + + let x = C.M1(B()) + check "vewenlwevlce" x 3 + +#nowarn "33" + + +#if NEGATIVE +module TestNoWidening = + let x4 : float32 list = [1;2;3;4] + let x5 : float list = [1.0f;2.0f;3.0f;4.0f] +#endif + + +module CheckNoWarningOnUsingImplicitForAPI = + type C() = + static member op_Implicit(x: int) = C() + static member op_Implicit(x: float) = C() + + + type API() = + static member M(c: C) = () + + API.M(3) + API.M(3.1) + +printfn "test done" + +let aa = + match failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + printfn "Test Failed, failures = %A" failures + exit 1 + diff --git a/tests/fsharp/core/auto-widen/preview/test.bsl b/tests/fsharp/core/auto-widen/preview/test.bsl new file mode 100644 index 00000000000..5b791a6d89a --- /dev/null +++ b/tests/fsharp/core/auto-widen/preview/test.bsl @@ -0,0 +1,638 @@ + +test.fsx(11,20,11,21): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(14,20,14,41): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(20,21,20,24): typecheck error FS3388: This expression implicitly converts type 'int * int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(28,31,28,32): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(33,27,33,28): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(33,29,33,30): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(36,56,36,57): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(36,58,36,59): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(39,43,39,44): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(39,45,39,46): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(44,41,44,42): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(45,48,45,49): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(45,50,45,51): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(48,30,48,31): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(48,32,48,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(58,22,58,24): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(58,22,58,24): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(59,22,59,23): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(59,22,59,23): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,28,60,29): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,28,60,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,30,60,31): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,30,60,31): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,32,60,33): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,32,60,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,34,60,35): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(60,34,60,35): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,28,61,29): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,28,61,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,30,61,31): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,30,61,31): typecheck error FS3388: This expression implicitly converts type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,32,61,33): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(61,32,61,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'float'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(63,22,63,43): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(63,22,63,43): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(64,28,64,49): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(64,28,64,49): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(64,50,64,71): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(64,50,64,71): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(67,20,67,23): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(67,20,67,23): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(68,22,68,25): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(68,22,68,25): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(68,22,68,25): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(68,22,68,25): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(69,26,69,29): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(69,26,69,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(69,26,69,29): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(69,26,69,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(93,18,93,19): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(93,18,93,19): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(99,20,99,21): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(99,20,99,21): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(116,20,116,21): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(116,20,116,21): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(121,19,121,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(121,19,121,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(122,19,122,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(122,19,122,20): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(122,22,122,23): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(122,22,122,23): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(127,19,127,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(127,19,127,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(128,19,128,20): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(128,19,128,20): typecheck error FS3388: This expression implicitly converts type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(128,22,128,23): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(128,22,128,23): typecheck error FS3388: This expression implicitly converts type 'int' to type 'double'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(135,18,135,19): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: int -> C' to convert type 'int' to type 'C'. + +test.fsx(135,18,135,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(140,18,140,19): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(140,18,140,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(145,18,145,19): typecheck error FS3390: This expression uses the implicit conversion 'Decimal.op_Implicit(value: int) : decimal' to convert type 'int' to type 'decimal'. + +test.fsx(145,18,145,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'decimal'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(147,18,147,19): typecheck error FS3391: This expression uses the implicit conversion 'Decimal.op_Implicit(value: int) : decimal' to convert type 'int' to type 'decimal'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(147,18,147,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'decimal'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(149,39,149,41): typecheck error FS3391: This expression uses the implicit conversion 'Xml.Linq.XNamespace.op_Implicit(namespaceName: string) : Xml.Linq.XNamespace' to convert type 'string' to type 'Xml.Linq.XNamespace'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(149,39,149,41): typecheck error FS3388: This expression implicitly converts type 'string' to type 'Xml.Linq.XNamespace'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(154,18,154,20): typecheck error FS3390: This expression uses the implicit conversion 'Xml.Linq.XNamespace.op_Implicit(namespaceName: string) : Xml.Linq.XNamespace' to convert type 'string' to type 'Xml.Linq.XNamespace'. + +test.fsx(154,18,154,20): typecheck error FS3388: This expression implicitly converts type 'string' to type 'Xml.Linq.XNamespace'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(159,18,159,21): typecheck error FS3390: This expression uses the implicit conversion 'Xml.Linq.XName.op_Implicit(expandedName: string) : Xml.Linq.XName' to convert type 'string' to type 'Xml.Linq.XName'. + +test.fsx(159,18,159,21): typecheck error FS3388: This expression implicitly converts type 'string' to type 'Xml.Linq.XName'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(165,18,165,19): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: int -> C' to convert type 'int' to type 'C'. + +test.fsx(165,18,165,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(172,18,172,21): typecheck error FS3390: This expression uses the implicit conversion 'static member Y.op_Implicit: y: Y -> X' to convert type 'Y' to type 'X'. + +test.fsx(172,18,172,21): typecheck error FS3390: This expression uses the implicit conversion 'static member Y.op_Implicit: y: Y -> X' to convert type 'Y' to type 'X'. + +test.fsx(178,20,178,21): typecheck error FS3391: This expression uses the implicit conversion 'static member C.op_Implicit: x: 'T -> C<'T>' to convert type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(178,20,178,21): typecheck error FS3388: This expression implicitly converts type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(180,15,180,16): typecheck error FS3391: This expression uses the implicit conversion 'static member C.op_Implicit: x: 'T -> C<'T>' to convert type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(180,15,180,16): typecheck error FS3388: This expression implicitly converts type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(186,27,186,28): typecheck error FS3391: This expression uses the implicit conversion 'Nullable.op_Implicit(value: int) : Nullable' to convert type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(186,27,186,28): typecheck error FS3388: This expression implicitly converts type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(188,15,188,16): typecheck error FS3391: This expression uses the implicit conversion 'Nullable.op_Implicit(value: int) : Nullable' to convert type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. This warning may be disabled using '#nowarn "3391". + +test.fsx(188,15,188,16): typecheck error FS3388: This expression implicitly converts type 'int' to type 'Nullable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(191,21,191,24): typecheck error FS3388: This expression implicitly converts type 'int * int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(192,27,192,28): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(192,29,192,30): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(195,56,195,57): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(195,58,195,59): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(198,49,198,50): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(198,51,198,54): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(201,33,201,34): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(201,35,201,38): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(204,43,204,44): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(204,45,204,46): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(207,28,207,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(207,31,207,32): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(207,20,207,35): typecheck error FS3388: This expression implicitly converts type 'R' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(210,22,210,41): typecheck error FS3388: This expression implicitly converts type 'R' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(210,30,210,31): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(210,33,210,34): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(213,29,213,30): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(213,32,213,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(213,20,213,36): typecheck error FS3388: This expression implicitly converts type 'SR' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(216,22,216,43): typecheck error FS3388: This expression implicitly converts type 'SR' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(216,31,216,32): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(216,34,216,35): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(219,20,219,33): typecheck error FS3388: This expression implicitly converts type 'U' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(219,20,219,33): typecheck error FS3388: This expression implicitly converts type 'U' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(222,21,222,31): typecheck error FS3388: This expression implicitly converts type 'U' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(225,21,225,31): typecheck error FS3388: This expression implicitly converts type 'int -> U' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(228,21,228,40): typecheck error FS3388: This expression implicitly converts type 'SU' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(228,21,228,40): typecheck error FS3388: This expression implicitly converts type 'SU' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(231,21,231,37): typecheck error FS3388: This expression implicitly converts type 'SU' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(234,21,234,37): typecheck error FS3388: This expression implicitly converts type 'int -> SU' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(237,13,237,14): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(237,16,237,19): typecheck error FS3388: This expression implicitly converts type 'byte' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(237,30,237,33): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(237,35,237,36): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(243,42,243,43): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(246,45,246,46): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(246,54,246,57): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(246,65,246,68): typecheck error FS3388: This expression implicitly converts type 'byte' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(248,49,248,50): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(248,51,248,52): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(253,36,253,37): typecheck error FS3388: This expression implicitly converts type 'int' to type 'IComparable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(256,30,256,39): typecheck error FS3388: This expression implicitly converts type 'uint16[]' to type 'Array'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(258,30,258,38): typecheck error FS3388: This expression implicitly converts type ''a[]' to type 'Array'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(260,36,260,38): typecheck error FS3388: This expression implicitly converts type 'Numerics.BigInteger' to type 'IComparable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(263,44,263,63): typecheck error FS3388: This expression implicitly converts type 'string' to type 'IComparable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(275,35,275,36): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(275,37,275,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(276,35,276,40): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(276,41,276,42): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(277,44,277,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(278,44,278,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(278,55,278,58): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(279,68,279,71): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(280,82,280,85): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(282,21,282,22): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(283,22,283,29): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(284,21,284,23): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(285,22,285,33): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(286,22,286,45): typecheck error FS3388: This expression implicitly converts type 'IComparable' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(286,22,286,24): typecheck error FS3388: This expression implicitly converts type 'string' to type 'IComparable'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(287,22,287,24): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(288,22,288,24): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(289,21,289,76): typecheck error FS3388: This expression implicitly converts type 'ICloneable' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(290,21,290,23): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(291,21,291,30): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(291,21,291,30): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(292,24,292,26): typecheck error FS3388: This expression implicitly converts type 'string' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(295,34,295,35): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(295,41,295,44): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(296,35,296,36): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(296,42,296,45): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(297,35,297,36): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(297,52,297,55): typecheck error FS3388: This expression implicitly converts type 'byte' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(297,61,297,64): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(300,25,300,26): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(300,37,300,40): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(303,25,303,26): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(306,45,306,46): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(306,54,306,57): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(309,19,309,20): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(310,32,310,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(310,39,310,42): typecheck error FS3388: This expression implicitly converts type 'float' to type 'obj'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(313,37,313,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(313,37,313,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(314,37,314,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(314,37,314,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(317,50,317,51): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(317,50,317,51): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(319,52,319,53): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(319,52,319,53): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(320,37,320,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(320,37,320,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(323,57,323,58): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(323,57,323,58): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(325,57,325,58): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(325,57,325,58): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(326,37,326,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(326,37,326,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(328,42,328,43): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(328,42,328,43): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(330,42,330,43): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(330,42,330,43): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(331,38,331,39): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(331,38,331,39): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(335,28,335,39): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(335,36,335,37): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(335,36,335,37): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(337,9,338,34): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(337,17,337,18): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(337,17,337,18): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(340,9,341,33): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(341,30,341,31): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(341,30,341,31): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(343,9,344,35): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(344,32,344,33): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(344,32,344,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(346,9,347,36): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(346,17,346,18): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(346,17,346,18): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(349,9,349,36): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(351,9,351,40): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(351,37,351,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(351,37,351,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(353,9,354,40): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(354,37,354,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(354,37,354,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(356,9,357,41): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(356,17,356,18): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(356,17,356,18): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(359,9,359,35): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(359,21,359,22): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(359,21,359,22): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(361,9,362,36): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(362,21,362,22): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(362,21,362,22): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(364,9,365,37): typecheck error FS3388: This expression implicitly converts type 'int64 list' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(364,17,364,18): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(364,17,364,18): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(368,39,368,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(368,39,368,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(369,39,369,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(369,39,369,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(372,52,372,53): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(372,52,372,53): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(374,54,374,55): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(374,54,374,55): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(375,39,375,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(375,39,375,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(378,59,378,60): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(378,59,378,60): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(380,59,380,60): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(380,59,380,60): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(381,39,381,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(381,39,381,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(383,44,383,45): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(383,44,383,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(385,44,385,45): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(385,44,385,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(386,40,386,41): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(386,40,386,41): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(390,28,390,41): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(390,37,390,38): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(390,37,390,38): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(391,30,392,57): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(391,39,391,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(391,39,391,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(393,30,394,56): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(394,52,394,53): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(394,52,394,53): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(395,30,396,58): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(396,54,396,55): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(396,54,396,55): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(397,30,398,59): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(397,39,397,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(397,39,397,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(399,30,399,59): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(400,30,400,63): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(400,59,400,60): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(400,59,400,60): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(401,30,402,63): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(402,59,402,60): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(402,59,402,60): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(403,30,404,64): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(403,39,403,40): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(403,39,403,40): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(405,31,405,59): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(405,44,405,45): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(405,44,405,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(406,31,407,60): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(407,44,407,45): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(407,44,407,45): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(408,31,409,61): typecheck error FS3388: This expression implicitly converts type 'int64[]' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(408,40,408,41): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(408,40,408,41): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(429,10,437,16): typecheck error FS3388: This expression implicitly converts type 'OtherSeq' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(448,9,450,49): typecheck error FS3388: This expression implicitly converts type 'OtherSeqImpl' to type 'seq'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(452,32,452,33): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(452,32,452,33): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(454,46,454,47): typecheck error FS3389: This expression uses a built-in implicit conversion to convert type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(454,46,454,47): typecheck error FS3388: This expression implicitly converts type 'int' to type 'int64'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(463,18,463,19): typecheck error FS0001: This expression was expected to have type + 'C' +but here has type + 'int' + +test.fsx(471,18,471,19): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: int -> C' to convert type 'int' to type 'C'. + +test.fsx(471,18,471,19): typecheck error FS3388: This expression implicitly converts type 'int' to type 'C'. See https://aka.ms/fsharp-implicit-convs. + +test.fsx(471,18,471,19): typecheck error FS0044: This construct is deprecated. nope + +test.fsx(482,18,482,21): typecheck error FS3387: This expression has type 'B' and is only made compatible with type 'C' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are: + static member B.op_Implicit: x: B -> C + static member C.op_Implicit: x: B -> C + +test.fsx(482,18,482,21): typecheck error FS3390: This expression uses the implicit conversion 'static member B.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(482,18,482,21): typecheck error FS3387: This expression has type 'B' and is only made compatible with type 'C' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are: + static member B.op_Implicit: x: B -> C + static member C.op_Implicit: x: B -> C + +test.fsx(482,18,482,21): typecheck error FS3390: This expression uses the implicit conversion 'static member B.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(507,18,507,21): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(507,18,507,21): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(519,18,519,21): typecheck error FS3390: This expression uses the implicit conversion 'static member B.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(519,18,519,21): typecheck error FS3390: This expression uses the implicit conversion 'static member B.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(538,18,538,21): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(538,18,538,21): typecheck error FS3390: This expression uses the implicit conversion 'static member C.op_Implicit: x: B -> C' to convert type 'B' to type 'C'. + +test.fsx(543,30,543,31): typecheck error FS0001: This expression was expected to have type + 'float32' +but here has type + 'int' + +test.fsx(543,32,543,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(543,34,543,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(543,36,543,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'float32'. This element has type 'int'. + +test.fsx(544,14,544,21): typecheck error FS0039: The type 'float64' is not defined. Maybe you want one of the following: + float + float32 \ No newline at end of file diff --git a/tests/fsharp/core/auto-widen/preview/test.fsx b/tests/fsharp/core/auto-widen/preview/test.fsx new file mode 100644 index 00000000000..2e6454d13cd --- /dev/null +++ b/tests/fsharp/core/auto-widen/preview/test.fsx @@ -0,0 +1,605 @@ + +#r "System.Xml.Linq.dll" +#r "System.Xml.XDocument.dll" + +let mutable failures : string list = [] + +open System + +module BasicTypeDirectedConversionsToObj = + // Constant expression + let x1 : obj = 1 + + // Field literal expressions + let x2 : obj = System.Int32.MaxValue + + // Field literal expressions + let x3 : obj = System.Int32.Parse("12") + + // Tuple expressions + let x4 : obj = (1,2) + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x : obj = 1 + 1 + + // Values + let x8 (s:string) : obj = s + +module BasicTypeDirectedConversionsToTuple = + + // Tuple expressions + let x2 : obj * obj = (1,2) + + // Let expressions + let x3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // Struct tuple expressions + let x4 : struct (obj * obj) = struct (1,2) + +module BasicTypeDirectedConversionsForFuncReturn = + + // Return in lambda expressions + let x5 : (unit -> obj) = (fun () -> 1) + let x6 : (unit -> obj * obj) = (fun () -> (1,2)) + + // Return in function expressions + let x7 () : obj * obj = (1,2) + +type R = { mutable F1: (obj * obj) } +[] +type SR = { mutable SF1: (obj * obj) } +type U = UnionCase0 | UnionCase1 of int +[] +type SU = StructUnionCase0 | StructUnionCase1 of int +module IntegerWidening = + let i1 = 0 + let x0 : int64 = i1 // integer value + let x1 : int64 = 0 // integer constant + let x2 : int64 list = [1;2;3;4] // within a list + let x3 : float list = [1;2;3;4.0] + //let x4 : float32 list = [1;2;3;4] + let x5 : int64 = System.Int32.MaxValue + let x6 : int64 list = [System.Int32.MaxValue;System.Int32.MaxValue] + let f () = 1 + + let x7 : obj = f() + let x8 : int64 = f() + let x9 : int64 = id (f()) // generic does work + + // Arithmetic expressions + // These do NOT permit type-directed subsumption nor widening because a generic return type is involved + // the is not yet committed + // let x6 : int64 = 1 + 1 + // let x6 : int64 = id (1 + 1) + +module Overloads1 = + type C() = + static member M1(x:int) = 1 + static member M1(x:int64) = failwith "nope" + let x = C.M1(2) + +module Overloads2 = + type C() = + static member M1(x:int) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2L) + +module Overloads3 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(2) + +module OverloadedOptionals1 = + type C() = + static member M1(x:string) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2) + +module OverloadedOptionals2 = + type C() = + static member M1(?x:int) = printfn "ok at line %s" __LINE__ + static member M1(?x:int64) = failwith "nope" + let x = C.M1(x=2) + +module OverloadedOptionals3 = + type C() = + static member M1(?x:int) = failwith "nope" + static member M1(?x:int64) = printfn "ok at line %s" __LINE__ + let x = C.M1(x=2L) + +module Optionals1 = + type C() = + static member M1(?x:int64) = 1 + let x = C.M1(x=2) + +module ParamArray1 = + type C() = + static member M1([] x:int64[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5L) + +module ParamArray2 = + type C() = + static member M1([] x:double[]) = Array.sum x + let x1 = C.M1(2) + let x2 = C.M1(2, 3, 5.0) + +module ConvertToSealedViaOpImplicit = + [] + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertNoOverloadin = + type C() = + static member M1(x:int64) = 1 + let x = C.M1(2) + +module ConvertNoOverloadingViaOpImplicit = + type C() = + static member M1(x:decimal) = () + let x = C.M1(2) + +let d: decimal = 3 + +let ns : System.Xml.Linq.XNamespace = "" + +module ConvertViaOpImplicit2 = + type C() = + static member M1(ns:System.Xml.Linq.XNamespace) = 1 + let x = C.M1("") + +module ConvertViaOpImplicit3 = + type C() = + static member M1(ns:System.Xml.Linq.XName) = 1 + let x = C.M1("a") + +module ConvertViaOpImplicit4 = + type C() = + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module ConvertViaOpImplicit5 = + type X() = + static member M1(x:X) = 1 + type Y() = + static member op_Implicit(y:Y) = X() + let x = X.M1(Y()) // Note this counts as a use in a method arg position, when processing the return type of 'Y' + +module ConvertViaOpImplicitGeneric = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:C = 1 + let f (c:C) = 1 + let x = f 2 + +module ConvertViaNullable = + type C<'T>() = + static member op_Implicit(x: 'T) = C<'T>() + + let c:Nullable = 1 + let f (c:Nullable) = 1 + let x = f 2 + +let annotations = + let v1 : obj = (1,2) + let v2 : obj * obj = (1,2) + + // structure through let + let v3 : (obj * obj) = (let x = 1 in let y = 2 in (x,y)) + + // structure through let rec + let v4 : (obj * obj) = (let rec f x = x in (3,4.0)) + + // structure through sequence + let v5 : (obj * obj) = (); (3,4.0) + + // struct tuple + let v6 : struct (obj * obj) = struct (1,2) + + // record (both field and overall result) + let v7 : obj = { F1 = (1, 2) } + + // record + let v7a : obj = ({ F1 = (1, 2) } : R) + + // struct record (both field and overall result) + let v8 : obj = { SF1 = (1, 2) } + + // struct record (both field and overall result) + let v8a : obj = ({ SF1 = (1, 2) } : SR) + + // union + let v9 : obj = UnionCase1(3) + + // union + let v10 : obj = UnionCase0 + + // union as first-class + let v11 : obj = UnionCase1 + + // struct union + let v12 : obj = StructUnionCase1(3) + + // struct union + let v13 : obj = StructUnionCase0 + + // struct union as first-class + let v14 : obj = StructUnionCase1 + + // record (both field and overall result) + { F1 = (1, 2uy) }.F1 <- (3.0, 4) + + // anon record + let v15 : {| A: obj |} = {| A = 1 |} + + // lambda return + let v16 : (unit -> obj) = (fun () -> 1) + + // function lambda return + let v17 : (int -> obj) = (function 1 -> 1 | 2 -> 3.0 | _ -> 4uy) + + let v18 : (unit -> obj * obj) = (fun () -> (1,2)) + + // constants + (1 :> System.IComparable) |> ignore + + let v19 : System.IComparable = 1 + + // array constants + let v20 : System.Array = [| 1us |] + + let v21 : System.Array = [| 1I |] + + let v22 : System.IComparable = 1I + + // property + let v23 : System.IComparable = System.String.Empty + + // method + let v24 : System.IComparable = System.String.Format("") + + let v25 : obj = System.String.Format("") + + let v26 : System.IComparable = System.String.Format("") + + // array constants + + let v27 : obj[] = [| 1 |] + let v28 : (obj * obj)[] = [| (1,1) |] + let v29 : (obj * obj)[] = [| ("abc",1) |] + let v30 : (string * obj)[] = [| ("abc",1) |] + let v31 : (string * obj)[] = [| ("abc",1); ("abc",3.0) |] + let v32 : (string * obj)[] = [| Unchecked.defaultof<_>; ("abc",3.0) |] + let v33 : struct (string * obj)[] = [| Unchecked.defaultof<_>; struct ("abc",3.0) |] + + let v34 : obj = 1 + let v35 : obj = (1 : int) + let v36 : obj = "" + let v37 : obj = ("" : string) + let v38 : obj = ("" : System.IComparable) + let v39 : obj = ("" : _) + let v40 : obj = ("" : obj) + let v41 : obj = { new System.ICloneable with member x.Clone() = obj() } + let v42 : obj = "" + let v43 : obj = string "" + let v44 : obj = id "" + + // conditional + let v45 : obj = if true then 1 else 3.0 + let v46 : obj = (if true then 1 else 3.0) + let v47 : obj = (if true then 1 elif true then 2uy else 3.0) + + // try-with + let v48 : obj = try 1 with _ -> 3.0 + + // try-finally + let v49 : obj = try 1 finally () + + // match + let v50 : obj = match true with true -> 1 | _ -> 3.0 + () + +let f1 () : obj = 1 +let f2 () : obj = if true then 1 else 3.0 + +module TestComputedListExpressionsAtList = + let x1 : list = [ yield 1 ] + let x2 : list = [ yield 1; + if true then yield 2L ] + let x3 : list = [ yield 1L; + if true then yield 2 ] + let x4 : list = [ yield 1L; + while false do yield 2 ] + let x5 : list = [ yield 1; + while false do yield 2L ] + let x6 : list = [ while false do yield 2L ] + let x7 : list = [ for i in 0 .. 10 do yield 2 ] + let x8 : list = [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : list = [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : list = [ try yield 2 finally () ] + let x11 : list = [ yield 1L + try yield 2 finally () ] + let x12 : list = [ yield 1 + try yield 2L finally () ] + +module TestComputedListExpressionsAtSeq = + let x1 : seq = [ yield 1 ] + let x2 : seq = + [ yield 1; + if true then yield 2L ] + let x3 : seq = + [ yield 1L; + if true then yield 2 ] + let x4 : seq = + [ yield 1L; + while false do yield 2 ] + let x5 : seq = + [ yield 1; + while false do yield 2L ] + let x6 : seq = + [ while false do yield 2L ] + let x7 : seq = + [ for i in 0 .. 10 do yield 2 ] + let x8 : seq = + [ yield 1L + for i in 0 .. 10 do yield 2 ] + let x9 : seq = + [ yield 1 + for i in 0 .. 10 do yield 2L ] + let x10 : seq = + [ try yield 2 finally () ] + let x11 : seq = + [ yield 1L + try yield 2 finally () ] + let x12 : seq = + [ yield 1 + try yield 2L finally () ] + +module TestComputedArrayExpressionsAtArray = + let x1 : array = [| yield 1 |] + let x2 : array = [| yield 1; + if true then yield 2L |] + let x3 : array = [| yield 1L; + if true then yield 2 |] + let x4 : array = [| yield 1L; + while false do yield 2 |] + let x5 : array = [| yield 1; + while false do yield 2L |] + let x6 : array = [| while false do yield 2L |] + let x7 : array = [| for i in 0 .. 10 do yield 2 |] + let x8 : array = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : array = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : array = [| try yield 2 finally () |] + let x11 : array = [| yield 1L + try yield 2 finally () |] + let x12 : array = [| yield 1 + try yield 2L finally () |] + +module TestComputedArrayExpressionsAtSeq = + let x1 : seq = [| yield 1 |] + let x2 : seq = [| yield 1; + if true then yield 2L |] + let x3 : seq = [| yield 1L; + if true then yield 2 |] + let x4 : seq = [| yield 1L; + while false do yield 2 |] + let x5 : seq = [| yield 1; + while false do yield 2L |] + let x6 : seq = [| while false do yield 2L |] + let x7 : seq = [| for i in 0 .. 10 do yield 2 |] + let x8 : seq = [| yield 1L + for i in 0 .. 10 do yield 2 |] + let x9 : seq = [| yield 1 + for i in 0 .. 10 do yield 2L |] + let x10 : seq = [| try yield 2 finally () |] + let x11 : seq = [| yield 1L + try yield 2 finally () |] + let x12 : seq = [| yield 1 + try yield 2L finally () |] + +module TestInferObjExprTypeParamFromKNownType = + // Check we are inferring type int64 + let x1 : seq = + { new seq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeq<'T> = + inherit seq<'T> + + // Check we are inferring type int64 + let x2 : seq = + { new OtherSeq<_> with + member x.GetEnumerator() = + // The 'ToString("4")' would not resolve if the type parameter is not inferred by this point + x.GetEnumerator().Current.ToString("4") |> ignore + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + } + + type OtherSeqImpl<'T>(f : 'T -> unit) = + interface OtherSeq<'T> with + member x.GetEnumerator() = + failwith "" + + interface System.Collections.IEnumerable with + member x.GetEnumerator() = failwith "" + + let x3 : seq = + new OtherSeqImpl<_>(fun x -> + // The 'ToString("4")' would not resolve if the type parameter is not inferred to be int64 by this point + x.ToString("4") |> ignore) + + let x4 : int64 * int32 = (3, 3) + + let x5 : {| A: int64; B: int32 |} = {| A=3; B=3 |} + +// These tests are activate for the case where warnings are on +#if NEGATIVE +module TestAcessibilityOfOpImplicit = + [] + type C() = + static member private op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module TestObsoleteOfOpImplicit = + [] + type C() = + [] + static member op_Implicit(x:int) = C() + static member M1(C:C) = 1 + let x = C.M1(2) + +module TestAmbiguousOpImplicit = + [] + type B() = + static member op_Implicit(x:B) = C(2) + + and [] C(x:int) = + static member op_Implicit(x:B) = C(1) + static member M1(C:C) = 1 + member _.Value = x + let x = C.M1(B()) + +#endif + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures <- failures @ [s] + +let test (s : string) b = + stderr.Write(s) + if b then stderr.WriteLine " OK" + else report_failure (s) + +let check s b1 b2 = test s (b1 = b2) + +module TestAmbiguousOpImplicitOkOneIsPrivate = + [] + type B() = + static member private op_Implicit(x:B) = C(1) + + and [] C(x:int) = + static member op_Implicit(x:B) = C(2) + static member M1(c:C) = c.Value + member _.Value = x + let x = C.M1(B()) + check "vewenlwevl" x 2 + +module TestAmbiguousOpImplicitOkOtherIsPrivate = + [] + type B() = + static member op_Implicit(x:B) = C(1) + + and [] C(x:int) = + static member private op_Implicit(x:B) = C(2) + static member M1(c:C) = c.Value + member _.Value = x + let x = C.M1(B()) + check "vewenlwevl" x 1 + +#nowarn "1215" +module TestExtrinsicOpImplicitIgnoredCompletely = + [] + type B() = class end + + and [] C(x:int) = + static member op_Implicit(x:B) = C(3) + static member M1(c:C) = c.Value + member _.Value = x + + [] + module Extensions = + type B with + // This gets ignored - a warning 1215 is actually reported implying this (ignored above) + static member op_Implicit(x:B) = C(1) + + let x = C.M1(B()) + check "vewenlwevlce" x 3 + +#if NEGATIVE +module TestNoWidening = + let x4 : float32 list = [1;2;3;4] + let x5 : float64 list = [1.0f;2.0f;3.0f;4.0f] +#endif + + +module TestRecursiveInferenceForPropagatingCases = + + module Bug1 = + type RecordTypeA = + { Name: string + FieldA: string } + + type RecordTypeB = + { Name: string + FieldB: int} + + // When the record expression is encountered, it must commit to "RecordTypeA" + // because the return type of "f" is, at that point, a variable type + // and must be correctly inferred by the point where we process the subsequence + // dot-notation "f().Name" + let rec f() = + { Name="" + FieldA = f().Name + } + + module Bug2 = + + type RecordTypeB = + { Name: string + FieldB: int} + + // When the anonymous record expression is encountered, it must commit to "RecordTypeA". + // The return type of "f" is, at that point, a variable type + // and must be correctly inferred by the point where we process the subsequence + // dot-notation "f().Name" + let rec f() = + {| Name="" + FieldA = f().Name + |} + + module Test3 = + + // Check the return type of 'f' is known by the time we process "f().Length" + let rec f() = [ f().Length ] + + module Test4 = + + // Check the return type of 'f' is known by the time we process "f().CompareTo(y)" + let rec f() = { new System.IComparable with member x.CompareTo(y) = f().CompareTo(y) } + + +printfn "test done" + +let aa = + match failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + printfn "Test Failed, failures = %A" failures + exit 1 + diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 5583cfa7c72..25f739a103f 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -502,7 +502,7 @@ module ByrefReturnTests = test() test2() - module TestTryCatchReturn = + module TestTryWithReturn = let mutable x = 1 let mutable y = 1 @@ -815,7 +815,7 @@ module ByrefReturnMemberTests = test() test2() - module TestTryCatchReturn = + module TestTryWithReturn = let mutable x = 1 let mutable y = 1 @@ -1500,7 +1500,28 @@ module ByrefReturnMemberTests = let link item = { item with Link = "" } + +// https://github.com/dotnet/fsharp/issues/12085 +module NoTailcallToByrefsWithModReq = + module ClassLibrary = + + // F# equivalent of `public delegate FieldType Getter(in DeclaringType);` + type Getter<'DeclaringType, 'FieldType> = delegate of inref<'DeclaringType> -> 'FieldType + + type GetterWrapper<'DeclaringType, 'FieldType> (getter : Getter<'DeclaringType, 'FieldType>) = + member _.Get (instance : 'DeclaringType) = getter.Invoke &instance + open ClassLibrary + type MyRecord = { Value: int[] } + let App() = + + let wrapper = new GetterWrapper(fun (record: inref) -> record.Value) + + let record = { Value = [| 42 |] } + let value = wrapper.Get(record) + value.GetEnumerator() + App() + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) else (stdout.WriteLine "Test Passed"; diff --git a/tests/fsharp/core/fsfromfsviacs/compilation.errors.output.bsl b/tests/fsharp/core/fsfromfsviacs/compilation.errors.output.bsl new file mode 100644 index 00000000000..8e846a78b70 --- /dev/null +++ b/tests/fsharp/core/fsfromfsviacs/compilation.errors.output.bsl @@ -0,0 +1,213 @@ + +test.fsx(217,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(218,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: x: int + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(219,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: y: string + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(220,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: x: int option + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(221,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: y: string option + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(222,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: x: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(223,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: y: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(224,34): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(227,42): error FS0041: A unique overload for method 'OverloadedMethodTakingOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float) : int + - SomeClass.OverloadedMethodTakingOptionals(?x: int, ?y: string, ?d: float32) : int + +test.fsx(229,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(230,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: y: string + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(231,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: Nullable + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(232,36): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: float + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(233,36): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: float option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(234,36): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: x: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(235,36): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(237,43): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionalsWithDefaults' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(239,34): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(240,34): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: y: string + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(241,33): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: float + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(242,34): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: Nullable + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(243,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: float + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(244,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: float option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(245,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: x: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(246,35): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: d: 'a option + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(247,42): error FS0041: A unique overload for method 'OverloadedMethodTakingNullableOptionals' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullableOptionals(?x: Nullable, ?y: string, ?d: Nullable) : int + +test.fsx(249,93): error FS0691: Named arguments must appear after all other arguments + +test.fsx(250,88): error FS0041: A unique overload for method 'OverloadedMethodTakingNullables' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: Nullable<'a> * string * Nullable<'b> when 'a: (new: unit -> 'a) and 'a: struct and 'a :> ValueType and 'b: (new: unit -> 'b) and 'b: struct and 'b :> ValueType + +Candidates: + - SomeClass.OverloadedMethodTakingNullables(x: Nullable, y: string, d: Nullable) : int + - SomeClass.OverloadedMethodTakingNullables(x: Nullable, y: string, d: Nullable) : int + +test.fsx(267,15): warning FS0025: Incomplete pattern matches on this expression. For example, the value 'U2 (_, U1 (_, "a"))' may indicate a case not covered by the pattern(s). + +test.fsx(284,15): warning FS0025: Incomplete pattern matches on this expression. For example, the value 'U2 (_, U1 (_, "a"))' may indicate a case not covered by the pattern(s). diff --git a/tests/fsharp/core/fsfromfsviacs/compilation.langversion.old.output.bsl b/tests/fsharp/core/fsfromfsviacs/compilation.langversion.old.output.bsl new file mode 100644 index 00000000000..10932d2ab4a --- /dev/null +++ b/tests/fsharp/core/fsfromfsviacs/compilation.langversion.old.output.bsl @@ -0,0 +1,128 @@ + +test.fsx(99,70): error FS0193: Type constraint mismatch. The type + 'int option' +is not compatible with type + 'int' + + +test.fsx(100,70): error FS0193: Type constraint mismatch. The type + 'string option' +is not compatible with type + 'string' + + +test.fsx(101,70): error FS0193: Type constraint mismatch. The type + 'float option' +is not compatible with type + 'float' + + +test.fsx(103,70): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'int' + + +test.fsx(104,70): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'string' + + +test.fsx(105,70): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'float' + + +test.fsx(111,89): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(117,90): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(118,90): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'float' + +test.fsx(121,91): error FS0193: Type constraint mismatch. The type + 'int option' +is not compatible with type + 'Nullable' + + +test.fsx(122,91): error FS0193: Type constraint mismatch. The type + 'float option' +is not compatible with type + 'Nullable' + + +test.fsx(124,91): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'Nullable' + + +test.fsx(125,91): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'Nullable' + + +test.fsx(131,77): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(133,77): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'float' + +test.fsx(138,78): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'int' + +test.fsx(139,78): error FS0001: This expression was expected to have type + 'Nullable' +but here has type + 'float' + +test.fsx(142,79): error FS0193: Type constraint mismatch. The type + 'int option' +is not compatible with type + 'Nullable' + + +test.fsx(143,79): error FS0193: Type constraint mismatch. The type + 'float option' +is not compatible with type + 'Nullable' + + +test.fsx(145,79): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'Nullable' + + +test.fsx(146,79): error FS0193: Type constraint mismatch. The type + ''a option' +is not compatible with type + 'Nullable' + + +test.fsx(267,15): warning FS0025: Incomplete pattern matches on this expression. For example, the value 'U2 (_, U1 (_, "a"))' may indicate a case not covered by the pattern(s). + +test.fsx(284,15): warning FS0025: Incomplete pattern matches on this expression. For example, the value 'U2 (_, U1 (_, "a"))' may indicate a case not covered by the pattern(s). + +test.fsx(418,29): error FS0041: A unique overload for method 'SimpleOverload' could not be determined based on type information prior to this program point. A type annotation may be needed. +Candidates: + - SomeClass.SimpleOverload(?x: Nullable) : int + - SomeClass.SimpleOverload(?x: int) : int diff --git a/tests/fsharp/core/fsfromfsviacs/lib3.cs b/tests/fsharp/core/fsfromfsviacs/lib3.cs index 91a3dffe4bb..ee7ed96c52c 100644 --- a/tests/fsharp/core/fsfromfsviacs/lib3.cs +++ b/tests/fsharp/core/fsfromfsviacs/lib3.cs @@ -47,6 +47,77 @@ public static int MethodTakingNullableOptionals(int? x = null, string y = null, length = y.Length; return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); } + public static int OverloadedMethodTakingOptionals(int x = 3, string y = "abc", double d = 5.0) + { + return x + y.Length + (int) d; + } + public static int OverloadedMethodTakingOptionals(int x = 3, string y = "abc", System.Single d = 5.0f) + { + return x + y.Length + (int) d + 7; + } + public static int OverloadedMethodTakingNullableOptionalsWithDefaults(int? x = 3, string y = "abc", double? d = 5.0) + { + return (x.HasValue ? x.Value : -100) + y.Length + (int) (d.HasValue ? d.Value : 0.0); + } + public static int OverloadedMethodTakingNullableOptionalsWithDefaults(long? x = 3, string y = "abc", double? d = 5.0) + { + return (x.HasValue ? (int) x.Value : -100) + y.Length + (int) (d.HasValue ? d.Value : 0.0) + 7; + } + public static int OverloadedMethodTakingNullableOptionals(int? x = null, string y = null, double? d = null) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + public static int OverloadedMethodTakingNullableOptionals(long? x = null, string y = null, double? d = null) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? (int) x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0) + 7; + } + public static int MethodTakingNullables(int? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + + public static int OverloadedMethodTakingNullables(int? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0); + } + public static int OverloadedMethodTakingNullables(long? x, string y, double? d) + { + int length; + if (y == null) + length = -1; + else + length = y.Length; + return (x.HasValue ? (int) x.Value : -1) + length + (int) (d.HasValue ? d.Value : -1.0) + 7; + } + public static int SimpleOverload(int? x = 3) + { + return (x.HasValue ? x.Value : 100); + } + + public static int SimpleOverload(int x = 3) + { + return (x + 200); + } } } diff --git a/tests/fsharp/core/fsfromfsviacs/test.fsx b/tests/fsharp/core/fsfromfsviacs/test.fsx index 47e2e359769..732c127e7d6 100644 --- a/tests/fsharp/core/fsfromfsviacs/test.fsx +++ b/tests/fsharp/core/fsfromfsviacs/test.fsx @@ -96,28 +96,159 @@ module TestConsumeCSharpOptionalParameter = check "csoptional23982f33" (SomeClass.MethodTakingOptionals(y = "aaaaaa")) 14 check "csoptional23982f34" (SomeClass.MethodTakingOptionals(d = 8.0)) 14 + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?x = Some 6)) 14 + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?y = Some "aaaaaa")) 14 + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?d = Some 8.0)) 14 + + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?x = None)) 11 + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?y = None)) 11 + check "csoptional23982f3a" (SomeClass.MethodTakingOptionals(?d = None)) 11 + + // Check the type inferred for an un-annotated first-class use of the method + check "csoptional23982f35" (let f = SomeClass.MethodTakingOptionals in ((f : unit -> int) ())) 11 + check "csoptional23982f41" (SomeClass.MethodTakingNullableOptionalsWithDefaults()) 11 - check "csoptional23982f42" (SomeClass.MethodTakingNullableOptionalsWithDefaults(x = Nullable 6)) 14 + check "csoptional23982f42" (SomeClass.MethodTakingNullableOptionalsWithDefaults(x = 6)) 14 // can provide non-nullable check "csoptional23982f43" (SomeClass.MethodTakingNullableOptionalsWithDefaults(y = "aaaaaa")) 14 - check "csoptional23982f44" (SomeClass.MethodTakingNullableOptionalsWithDefaults(d = Nullable 8.0)) 14 + // See https://github.com/fsharp/fslang-suggestions/issues/774#issuecomment-516423841 + check "csoptional23982f42" (SomeClass.MethodTakingNullableOptionalsWithDefaults(x = Nullable 6)) 14 // can provide nullable for legacy + check "csoptional23982f44" (SomeClass.MethodTakingNullableOptionalsWithDefaults(d = Nullable 8.0)) 14 // can provide nullable for legacy + + check "csoptional23982f431" (SomeClass.MethodTakingNullableOptionalsWithDefaults(x = 6)) 14 + check "csoptional23982f442" (SomeClass.MethodTakingNullableOptionalsWithDefaults(d = 8.0)) 14 + + // When a C# argument has a default value and is nullable (without a default), using ?x to provide an argument takes type option + check "csoptional23982f435" (SomeClass.MethodTakingNullableOptionalsWithDefaults(?x = Some 6)) 14 + check "csoptional23982f446" (SomeClass.MethodTakingNullableOptionalsWithDefaults(?d = Some 8.0)) 14 + + check "csoptional23982f43E" (SomeClass.MethodTakingNullableOptionalsWithDefaults(?x = None)) -92 + check "csoptional23982f44R" (SomeClass.MethodTakingNullableOptionalsWithDefaults(?d = None)) 6 + + // Check the type inferred for an un-annotated first-class use of the method + check "csoptional23982f45" (let f = SomeClass.MethodTakingNullableOptionalsWithDefaults in ((f : unit -> int) ())) 11 check "csoptional23982f51" (SomeClass.MethodTakingNullableOptionals()) -3 - check "csoptional23982f52" (SomeClass.MethodTakingNullableOptionals(x = Nullable 6)) 4 + check "csoptional23982f52" (SomeClass.MethodTakingNullableOptionals(x = 6)) 4 // can provide nullable for legacy check "csoptional23982f53" (SomeClass.MethodTakingNullableOptionals(y = "aaaaaa")) 4 - check "csoptional23982f54" (SomeClass.MethodTakingNullableOptionals(d = Nullable 8.0)) 6 + check "csoptional23982f54" (SomeClass.MethodTakingNullableOptionals(d = 8.0)) 6 + // See https://github.com/fsharp/fslang-suggestions/issues/774#issuecomment-516423841 + check "csoptional23982f52" (SomeClass.MethodTakingNullableOptionals(x = Nullable 6)) 4 // can provide nullable for legacy + check "csoptional23982f54" (SomeClass.MethodTakingNullableOptionals(d = Nullable 8.0)) 6 // can provide nullable for legacy + + check "csoptional23982f523" (SomeClass.MethodTakingNullableOptionals(x = 6)) 4 + check "csoptional23982f544" (SomeClass.MethodTakingNullableOptionals(d = 8.0)) 6 + + // When a C# argument has a default value and is nullable (without a default), using ?x to provide an argument takes type option + check "csoptional23982f527" (SomeClass.MethodTakingNullableOptionals(?x = Some 6)) 4 + check "csoptional23982f548" (SomeClass.MethodTakingNullableOptionals(?d = Some 8.0)) 6 + + check "csoptional23982f52T" (SomeClass.MethodTakingNullableOptionals(?x = None)) -3 + check "csoptional23982f54Y" (SomeClass.MethodTakingNullableOptionals(?d = None)) -3 + + // Check the type inferred for an un-annotated first-class use of the method + check "csoptional23982f55" (let f = SomeClass.MethodTakingNullableOptionals in ((f : unit -> int) ())) -3 + +#if LANGVERSION_PREVIEW + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", 8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", Nullable 8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", Nullable ())) 11 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable (), "aaaaaa", 8.0)) 13 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable 6, "aaaaaa", 8.0)) 20 + + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", d=8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", d=Nullable 8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, "aaaaaa", d=Nullable ())) 11 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable (), "aaaaaa", d=8.0)) 13 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable 6, "aaaaaa", d=8.0)) 20 + + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=Nullable 8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=Nullable ())) 11 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable (), y="aaaaaa", d=8.0)) 13 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable 6, y="aaaaaa", d=8.0)) 20 + + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=Nullable 8.0)) 20 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(6, y="aaaaaa", d=Nullable ())) 11 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable (), y="aaaaaa", d=8.0)) 13 + check "acsoptional23982f51" (SomeClass.MethodTakingNullables(Nullable 6, y="aaaaaa", d=8.0)) 20 + + // Check the type inferred for an un-annotated first-class use of the method + check "acsoptional23982f55" (let f = SomeClass.MethodTakingNullables in ((f : Nullable * string * Nullable -> int) (Nullable 1,"aaaa",Nullable 3.0))) 8 +#endif + +// This tests overloaded variaitons of the methods, where the overloads vary by type but not nullability +// +// The CHECK_ERRORS cases are not execpted to compile +module TestConsumeCSharpOptionalParameterOverloads = + open System + open CSharpOptionalParameters + + check "csoptional23982f34o" (SomeClass.OverloadedMethodTakingOptionals(d = 8.0)) 14 - // These require https://github.com/fsharp/fslang-suggestions/issues/774 to be implemented - //check "csoptional23982f3no" (SomeClass.SomeMethod(?x = Some 6)) 14 - //check "csoptional23982f3no" (SomeClass.SomeMethod(?y = Some "aaaaaa")) 14 - //check "csoptional23982f3no" (SomeClass.SomeMethod(?d = Some 8.0)) 14 - //check "csoptional23982f3no" (SomeClass.SomeMethod(?x = None)) 11 - //check "csoptional23982f3no" (SomeClass.SomeMethod(?y = None)) 11 - //check "csoptional23982f3no" (SomeClass.SomeMethod(?d = None)) 11 +#if LANGVERSION_PREVIEW + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?d = Some 8.0)) 14 + + check "csoptional23982f42o" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(x = 6)) 14 // can provide non-nullable + + // See https://github.com/fsharp/fslang-suggestions/issues/774#issuecomment-516423841 + check "csoptional23982f42o" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(x = Nullable 6)) 14 // can provide nullable for legacy + + check "csoptional23982f431o" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(x = 6)) 14 + + // When a C# argument has a default value and is nullable (without a default), using ?x to provide an argument takes type option + check "csoptional23982f435o" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x = Some 6)) 14 + + check "csoptional23982f52o" (SomeClass.OverloadedMethodTakingNullableOptionals(x = 6)) 4 // can provide nullable for legacy + + // See https://github.com/fsharp/fslang-suggestions/issues/774#issuecomment-516423841 + check "csoptional23982f52o" (SomeClass.OverloadedMethodTakingNullableOptionals(x = Nullable 6)) 4 // can provide nullable for legacy + + check "csoptional23982f523o" (SomeClass.OverloadedMethodTakingNullableOptionals(x = 6)) 4 + + check "csoptional23982f52o1" (SomeClass.OverloadedMethodTakingNullables(6, "aaaaaa", 8.0)) 20 // can provide non-nullable + check "csoptional23982f52o2" (SomeClass.OverloadedMethodTakingNullables(Nullable(6), "aaaaaa", 8.0)) 20 // can provide nullable + check "csoptional23982f52o3" (SomeClass.OverloadedMethodTakingNullables(Nullable(6), "aaaaaa", Nullable(8.0))) 20 // can provide nullable + +#endif - //check "csoptional23982f42" (SomeClass.MethodTakingNullableOptionalsWithDefaults(x = 6)) 14 - //check "csoptional23982f44" (SomeClass.MethodTakingNullableOptionalsWithDefaults(d = 8.0)) 14 - //check "csoptional23982f52" (SomeClass.MethodTakingNullableOptionals(x = 6)) 4 - //check "csoptional23982f54" (SomeClass.MethodTakingNullableOptionals(d = 8.0)) 6 +#if CHECK_ERRORS + // in these cases there's not enough information to resolve the overload + check "csoptional23982f31o" (SomeClass.OverloadedMethodTakingOptionals()) 11 + check "csoptional23982f32o" (SomeClass.OverloadedMethodTakingOptionals(x = 6)) 14 + check "csoptional23982f33o" (SomeClass.OverloadedMethodTakingOptionals(y = "aaaaaa")) 14 + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?x = Some 6)) 14 + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?y = Some "aaaaaa")) 14 + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?x = None)) 11 + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?y = None)) 11 + check "csoptional23982f3ao" (SomeClass.OverloadedMethodTakingOptionals(?d = None)) 11 + + // Check the type inferred for an un-annotated first-class use of the method + check "csoptional23982f35o" (let f = SomeClass.OverloadedMethodTakingOptionals in ((f : unit -> int) ())) 11 + + check "csoptional23982f41ox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults()) 11 + check "csoptional23982f43ox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(y = "aaaaaa")) 14 + check "csoptional23982f44ox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(d = Nullable 8.0)) 14 // can provide nullable for legacy + check "csoptional23982f442ox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(d = 8.0)) 14 + check "csoptional23982f446ox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?d = Some 8.0)) 14 + check "csoptional23982f43Eox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?x = None)) -92 + check "csoptional23982f44Rox" (SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults(?d = None)) 6 + // Check the type inferred for an un-annotated first-class use of the method + check "csoptional23982f45ox" (let f = SomeClass.OverloadedMethodTakingNullableOptionalsWithDefaults in ((f : unit -> int) ())) 11 + + check "csoptional23982f51o" (SomeClass.OverloadedMethodTakingNullableOptionals()) -3 + check "csoptional23982f53o" (SomeClass.OverloadedMethodTakingNullableOptionals(y = "aaaaaa")) 4 + check "soptional23982f54o" (SomeClass.OverloadedMethodTakingNullableOptionals(d = 8.0)) 6 + check "csoptional23982f54o" (SomeClass.OverloadedMethodTakingNullableOptionals(d = Nullable 8.0)) 6 // can provide nullable for legacy + check "csoptional23982f544o" (SomeClass.OverloadedMethodTakingNullableOptionals(d = 8.0)) 6 + check "csoptional23982f548o" (SomeClass.OverloadedMethodTakingNullableOptionals(?d = Some 8.0)) 6 + check "csoptional23982f52To" (SomeClass.OverloadedMethodTakingNullableOptionals(?x = None)) -3 + check "csoptional23982f54Yo" (SomeClass.OverloadedMethodTakingNullableOptionals(?d = None)) -3 + check "csoptional23982f55o" (let f = SomeClass.OverloadedMethodTakingNullableOptionals in ((f : unit -> int) ())) -3 + + check "dcsoptional23982f544o" (SomeClass.OverloadedMethodTakingNullables(x= Nullable(), "aaaa" d = Nullable())) 6 + check "dcsoptional23982f55o" (let (f: Nullable<_> * string * Nullable<_> -> int) = SomeClass.OverloadedMethodTakingNullables in f (Nullable(), "aaa", Nullable())) -3 +#endif module NestedStructPatternMatchingAcrossAssemblyBoundaries = open Lib.NestedStructUnionsTests @@ -281,6 +412,17 @@ TestStructs.test5 () #endif +module TestConsumeCSharpOptionalParameterOverloads_ByNullability = + open System + open CSharpOptionalParameters + check "cenwceoweioij1" (SomeClass.SimpleOverload()) 203 + check "cenwceoweioij2" (SomeClass.SimpleOverload(6)) 206 + check "cenwceoweioij3" (SomeClass.SimpleOverload(x=6)) 206 + check "cenwceoweioij4" (SomeClass.SimpleOverload(Nullable(6))) 6 + check "cenwceoweioij5" (SomeClass.SimpleOverload(Nullable())) 100 + check "cenwceoweioij4" (SomeClass.SimpleOverload(x=Nullable(6))) 6 + check "cenwceoweioij5" (SomeClass.SimpleOverload(x=Nullable())) 100 + #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/core/genericmeasures/test.fsx b/tests/fsharp/core/genericmeasures/test.fsx index 265b1865826..b7de5c84aaa 100644 --- a/tests/fsharp/core/genericmeasures/test.fsx +++ b/tests/fsharp/core/genericmeasures/test.fsx @@ -5,20 +5,29 @@ module Core_genericMeasures = #endif [] - type C<'T> = class end + type C<'T> = member x.P = 1 [] type t + [] type t2 let f1 (_ : int) = () let f2 (_ : float) = () let f3 (_ : int<_>) = () let f4 (_ : float<_>) = () let f5 (_ : C<'a>) = () - let f6 (_ : list<'a>) = () + let f6 (xs : list<'a>) = + match box xs with + | null -> failwith "unexpected null list" + | _ -> if List.length xs <> 0 then failwith "expected empty list" + let f7 (xs : list<'a>) = + match box xs with + | null -> failwith "unexpected null list" + | _ -> if List.length xs <> 0 then failwith "expected empty list" let foo() = let a = 0<_> let b = 0.0<_> let c = null : C> + let c2 = c : C> let d = null : C> let e = [] : list> let f = [] : list> @@ -26,12 +35,14 @@ module Core_genericMeasures = let h = null : C<_ * int<_> * _> let i : List> = List.empty let j : List> = List.empty + let k : List> = j f1 a f2 b f3 a f4 b f5 c + f5 c2 f5 d f6 e f6 f @@ -39,6 +50,12 @@ module Core_genericMeasures = f5 h f6 i f6 j + f7 (i : List>) + f7 (i : List>) + f7 (j : List>) + f7 (j : List>) + f7 (k : List>) + f7 (k : List>) type T = static member Foo(_ : int) = () diff --git a/tests/fsharp/core/innerpoly/test.fsx b/tests/fsharp/core/innerpoly/test.fsx index 657b8c2e81a..012df22100f 100644 --- a/tests/fsharp/core/innerpoly/test.fsx +++ b/tests/fsharp/core/innerpoly/test.fsx @@ -389,6 +389,96 @@ module InnerGenericBindingsInComputationExpressions = begin f() end +module LocalTypeFunctionRequiredForWitnessPassingOfGenericInnerFunctionsConstrainedByMemberConstraints = + let inline clamp16 v = uint16 (max 0. (min 65535. v)) + let inline clamp8 v = uint8 (max 0. (min 255. v)) + + type Clampage = + static member inline FromFloat (_ : byte, _ : Clampage) = fun (x : float) -> clamp8 x + static member inline FromFloat (_ : uint16, _ : Clampage) = fun (x : float) -> clamp16 x + + static member inline Invoke (x: float) : 'Num = + let inline call2 (a: ^a, b: ^b) = ((^a or ^b) : (static member FromFloat : _*_ -> _) (b, a)) + let inline call (a: 'a) = fun (x: 'x) -> call2 (a, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof x + + let inline clamp x = Clampage.Invoke x + let x1 : byte = clamp 3.0 + let x2 : uint16 = clamp 3.0 + let x3 : byte = clamp 257.0 + check "clecqwe1" x1 3uy + check "clecqwe2" x2 3us + check "clecqwe3" x3 255uy + +// Same as the above but capturing an extra constrained free type variable 'Free +module LocalTypeFunctionRequiredForWitnessPassingOfGenericInnerFunctionsConstrainedByMemberConstraints2 = + let inline clamp16 v = uint16 (max 0. (min 65535. v)) + let inline clamp8 v = uint8 (max 0. (min 255. v)) + + type Clampage = + static member inline FromFloat (_ : byte, _ : Clampage) = fun (x : float) -> clamp8 x + static member inline FromFloat (_ : uint16, _ : Clampage) = fun (x : float) -> clamp16 x + + static member inline Invoke (x: float) (free: 'Free) : 'Num * 'Free = + let inline call2 (a: ^a, b: ^b) = ((^a or ^b) : (static member FromFloat : _*_ -> _) (b, a)) + let inline call (a: 'a) = (fun (x: 'x) -> call2 (a, Unchecked.defaultof<'r>) x : 'r), free + free + let f, info = call Unchecked.defaultof + f x, info + + let inline clamp x free = Clampage.Invoke x free + let (x1a1: byte, x1a2: int64) = clamp 3.0 1L + let (x1b1: uint16, x1b2: string) = clamp 3.0 "abc" + check "clecqwea1" x1a1 3uy + check "clecqwea2" x1a2 2L + check "clecqwea3" x1b1 3us + check "clecqwea4" x1b2 "abcabc" + +module Bug10408 = + let test x = + match x with + | [| |] -> x + | _ -> x + +module Bug11620A = + + let createService (metadata: 'T) : 'Data when 'Data :> System.IComparable = Unchecked.defaultof<'Data> + + let getCreateServiceCallback<'T> (thing: 'T) = + let getService () : 'Data = createService thing + (fun () -> getService) + +// The generated signature for this bug repro has mistakes, we are not enabling it yet +#if !GENERATED_SIGNATURE +module Bug11620B = + + type Data = interface end + and Service<'Data when 'Data :> Data>() = class end + + type IThing = interface end + and Thing<'T> = { Metadata: 'T } with interface IThing + + let createService metadata = (Service<'Data>()) + + let getCreateServiceCallback<'T> (thing: IThing) = + let upcastThing = + thing + :?> Thing<'T> + let getService () = createService upcastThing.Metadata + (fun () -> getService) + + let main _ = + let dummyThing : Thing = { Thing.Metadata = 42 } + // crash occured on the following line + let callback = getCreateServiceCallback dummyThing + let resolvedService = callback () + printfn "Resolved service: %A" resolvedService + 0 + + main () + +#endif + + #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index f708f50351b..bf58ea27d08 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -5263,8 +5263,8 @@ module Check1043 = begin (* LBRACKET STAR RBRACKET becomes a valid operator identifier *) let (*) = 12 let x = (*) - let f (*) = 12 + (*) - let x24 = f 12 + let test() = let f (*) = 12 + (*) in f 12 + let x24 = test() end diff --git a/tests/fsharp/core/load-script/out.stderr.bsl b/tests/fsharp/core/load-script/out.stderr.bsl index 0c48e3a9444..3090d5e2f89 100644 --- a/tests/fsharp/core/load-script/out.stderr.bsl +++ b/tests/fsharp/core/load-script/out.stderr.bsl @@ -1,4 +1,3 @@ usesfsi.fsx(2,1): error FS0039: The value, namespace, type or module 'fsi' is not defined. Maybe you want one of the following: - fst diff --git a/tests/fsharp/core/map/test.fsx b/tests/fsharp/core/map/test.fsx index 984ab4d24e0..2e80355e94a 100644 --- a/tests/fsharp/core/map/test.fsx +++ b/tests/fsharp/core/map/test.fsx @@ -166,6 +166,9 @@ module Bug_FSharp_1_0_6307 = // below does not parse let t = typeof +module TestSetHashCodeCase = + let s = Set.singleton 2147483017 + s.GetHashCode() // this was failing due to use of 'abs' in GetHashCode #if TESTS_AS_APP let RUN() = !failures diff --git a/tests/fsharp/core/members/basics/test.fs b/tests/fsharp/core/members/basics/test.fs index a5da244c0a6..79fd5eb33eb 100644 --- a/tests/fsharp/core/members/basics/test.fs +++ b/tests/fsharp/core/members/basics/test.fs @@ -1588,7 +1588,7 @@ module DeepGenericInterfaceInheritance = begin end -module PointTest = struct +module PointTest = begin type Point = @@ -3038,6 +3038,7 @@ module ContraintTest = begin open System.Numerics let check s p = printf "Test %s: %s\n" s (if p then "pass" else "fail") do check "d3oc001" (LanguagePrimitives.GenericZero = 0I) + do check "d3oc002" (LanguagePrimitives.GenericZero = '\000') do check "d3oc003a" (LanguagePrimitives.GenericZero = 0) do check "d3oc003b" (LanguagePrimitives.GenericZero = 0un) do check "d3oc003c" (LanguagePrimitives.GenericZero = 0UL) @@ -3051,7 +3052,8 @@ module ContraintTest = begin do check "d3oc003k" (LanguagePrimitives.GenericZero = 0y) do check "d3oc003l" (LanguagePrimitives.GenericZero = 0M) - do check "d3oc001q" (LanguagePrimitives.GenericOne = 1I) + do check "d3oc113q" (LanguagePrimitives.GenericOne = 1I) + do check "d3oc113w" (LanguagePrimitives.GenericOne = '\001') do check "d3oc113e" (LanguagePrimitives.GenericOne = 1) do check "d3oc113r" (LanguagePrimitives.GenericOne = 1un) do check "d3oc113t" (LanguagePrimitives.GenericOne = 1UL) @@ -3466,7 +3468,12 @@ module AutoProps_2 = begin check "autoprops_262" c61.Property 44 end +module MoreKindInferenceTests = + + type C1<'a> = class member _.Foo(x:'a) = x end + + #if TESTS_AS_APP let RUN() = !failures #else diff --git a/tests/fsharp/core/members/basics/test.fsi b/tests/fsharp/core/members/basics/test.fsi index 7efd5cdd50a..b18bf68d4ac 100644 --- a/tests/fsharp/core/members/basics/test.fsi +++ b/tests/fsharp/core/members/basics/test.fsi @@ -30,7 +30,7 @@ type ClassType2 = end -module RecordTypeTest: begin +module RecordTypeTest = begin [] type AbstractType = @@ -79,7 +79,7 @@ module RecordTypeTest: begin end -module UnionTypeTest: begin +module UnionTypeTest = begin [] type AbstractType = @@ -130,12 +130,12 @@ module UnionTypeTest: begin end -module ToStringOnUnionTest: begin +module ToStringOnUnionTest = begin type MyUnion = A of string | B end -module ToStringOnUnionTestOverride: begin +module ToStringOnUnionTestOverride = begin type MyUnion = A of string | B end \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/calls.bsl b/tests/fsharp/core/members/set-only-property/calls.bsl new file mode 100644 index 00000000000..d4fa4927d1a --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.bsl @@ -0,0 +1,12 @@ + +calls.fsx(18,30,18,31): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(19,34,19,35): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(20,24,20,29): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop2'. The required signature is new: unit -> fsharp.Class. + +calls.fsx(22,29,22,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(23,29,23,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(24,23,24,28): typecheck error FS0495: The member or object constructor 'mkFs' has no argument or settable return property 'Prop2'. The required signature is static member Maker.mkFs: unit -> fsharp.Class. diff --git a/tests/fsharp/core/members/set-only-property/calls.fsx b/tests/fsharp/core/members/set-only-property/calls.fsx new file mode 100644 index 00000000000..ddd6b365cb3 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.fsx @@ -0,0 +1,24 @@ +#r "cs.dll" +#r "vb.dll" +#r "fs.dll" +type Maker = + static member mkCs () = csharp.Class() + static member mkVb () = basic.BasicClass() + static member mkFs () = fsharp.Class() +// so long https://github.com/dotnet/fsharp/issues/8351 isn't fixed, Prop1 setters are failing +let a = csharp.Class(Prop1=1) +let b = basic.BasicClass(Prop1=1) +let c = fsharp.Class(Prop1=1) // this one works, inconsistent but correct. + +let aa = Maker.mkCs(Prop1=1) +let bb = Maker.mkVb(Prop1=1) +let cc = Maker.mkFs(Prop1=1) // this one works, inconsistent but correct. + +// those are expected to fail, albeit with inconsistent error messages / marked ranges +let aaa = csharp.Class(Prop2=1) +let bbb = basic.BasicClass(Prop2=1) +let ccc = fsharp.Class(Prop2=1) + +let aaaa = Maker.mkCs(Prop2=1) +let bbbb = Maker.mkVb(Prop2=1) +let cccc = Maker.mkFs(Prop2=1) diff --git a/tests/fsharp/core/members/set-only-property/cs.cs b/tests/fsharp/core/members/set-only-property/cs.cs new file mode 100644 index 00000000000..18818edcf45 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/cs.cs @@ -0,0 +1,8 @@ +namespace csharp +{ + public class Class + { + public int Prop1 { set; private get; } + public int Prop2 { private set; get; } + } +} \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs new file mode 100644 index 00000000000..9b05bc67e70 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -0,0 +1,8 @@ +namespace fsharp +type Class () = + let mutable v = 0 + member x.Prop1 with set(value) = v <- value + and private get () = v + + member x.Prop2 with private set(value) = v <- value + and public get () = v diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb new file mode 100644 index 00000000000..c6a4865c012 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -0,0 +1,21 @@ +namespace basic + public class BasicClass + dim v as integer + public property Prop1 as integer + private get + return v + end get + set(value as integer) + v = value + end set + end property + public property Prop2 as integer + get + return v + end get + private set(value as integer) + v = value + end set + end property + end class +end namespace \ No newline at end of file diff --git a/tests/fsharp/core/nameof/preview/test.fsx b/tests/fsharp/core/nameof/preview/test.fsx index bbad8d142ad..0a952ab823f 100644 --- a/tests/fsharp/core/nameof/preview/test.fsx +++ b/tests/fsharp/core/nameof/preview/test.fsx @@ -9,10 +9,6 @@ open System exception ABC -type Assert = - static member AreEqual (a, b) = a=b - static member Fail = raise (Exception("Fail")) - let failures = ref [] let report_failure (s : string) = @@ -27,6 +23,9 @@ let test (s : string) b = let check s b1 b2 = test s (b1 = b2) +type Assert = + static member AreEqual msg (a, b) = check msg a b; (a = b) + type BasicNameOfTests() = static let staticConstant = 23 @@ -47,34 +46,34 @@ type BasicNameOfTests() = static member ``local variable name lookup`` () = let a = 0 let b = nameof a - let result = Assert.AreEqual("a", b) + let result = Assert.AreEqual ("line " + string __LINE__) ("a", b) let c = nameof b - result || Assert.AreEqual("b", c) + result || Assert.AreEqual ("line " + string __LINE__) ("b", c) static member ``local int function name`` () = let myFunction x = 0 * x let result = nameof myFunction - Assert.AreEqual("myFunction", result) + Assert.AreEqual ("line " + string __LINE__) ("myFunction", result) static member ``local curried function name`` () = let curriedFunction x y = x * y let result = nameof curriedFunction - Assert.AreEqual("curriedFunction", result) + Assert.AreEqual ("line " + string __LINE__) ("curriedFunction", result) static member ``local tupled function name`` () = let tupledFunction(x,y) = x * y let result = nameof tupledFunction - Assert.AreEqual("tupledFunction", result) + Assert.AreEqual ("line " + string __LINE__) ("tupledFunction", result) static member ``local unit function name`` () = let myFunction() = 1 let result = nameof(myFunction) - Assert.AreEqual("myFunction", result) + Assert.AreEqual ("line " + string __LINE__) ("myFunction", result) static member ``local function parameter name`` () = let myFunction parameter1 = nameof parameter1 let result = myFunction "x" - Assert.AreEqual("parameter1", result) + Assert.AreEqual ("line " + string __LINE__) ("parameter1", result) static member ``can get name from inside a local function (needs to be let rec)`` () = let rec myLocalFunction x = @@ -82,83 +81,91 @@ type BasicNameOfTests() = nameof myLocalFunction + " " + z.ToString() let a = myLocalFunction 23 - let result = Assert.AreEqual("myLocalFunction 46", a) + let result = Assert.AreEqual ("line " + string __LINE__) ("myLocalFunction 46", a) let b = myLocalFunction 25 - result || Assert.AreEqual("myLocalFunction 50", b) + result || Assert.AreEqual ("line " + string __LINE__) ("myLocalFunction 50", b) static member ``can get name from inside static member`` () = let b = nameof(BasicNameOfTests.``can get name from inside static member``) - Assert.AreEqual("can get name from inside static member", b) + Assert.AreEqual ("line " + string __LINE__) ("can get name from inside static member", b) member this.``can get name from inside instance member`` () = let b = nameof(this.``can get name from inside instance member``) - Assert.AreEqual("can get name from inside instance member", b) + Assert.AreEqual ("line " + string __LINE__) ("can get name from inside instance member", b) static member ``can get name of static member`` () = let b = nameof(BasicNameOfTests.``can get name of static member``) - Assert.AreEqual("can get name of static member", b) + Assert.AreEqual ("line " + string __LINE__) ("can get name of static member", b) member this.``can get name of instance member`` () = let b = nameof(this.MemberMethod) - Assert.AreEqual("MemberMethod", b) + Assert.AreEqual ("line " + string __LINE__) ("MemberMethod", b) + + member this.``can get name of instance member via unchecked`` () = + let b = nameof(Unchecked.defaultof.MemberMethod) + Assert.AreEqual ("line " + string __LINE__) ("MemberMethod", b) + + member this.``can get name of method type parameter``<'TTT> () = + let b = nameof<'TTT> + Assert.AreEqual ("line " + string __LINE__) ("TTT", b) static member ``namespace name`` () = let b = nameof(FSharp.Core) - Assert.AreEqual("Core",b) + Assert.AreEqual ("line " + string __LINE__) ("Core",b) static member ``module name`` () = let b = nameof(FSharp.Core.Operators) - Assert.AreEqual("Operators",b) + Assert.AreEqual ("line " + string __LINE__) ("Operators",b) static member ``exception name`` () = let b = nameof(ABC) - Assert.AreEqual("ABC",b) + Assert.AreEqual ("line " + string __LINE__) ("ABC",b) static member ``nested type name 1`` () = let b = nameof(System.Collections.Generic.List.Enumerator<_>) - Assert.AreEqual("Enumerator",b) + Assert.AreEqual ("line " + string __LINE__) ("Enumerator",b) static member ``type name 2`` () = let b = nameof(System.Action<_>) - Assert.AreEqual("Action",b) + Assert.AreEqual ("line " + string __LINE__) ("Action",b) static member ``member function which is defined below`` () = let x = BasicNameOfTests() let b = nameof(x.MemberMethodDefinedBelow) - Assert.AreEqual("MemberMethodDefinedBelow",b) + Assert.AreEqual ("line " + string __LINE__) ("MemberMethodDefinedBelow",b) member this.MemberMethodDefinedBelow(x,y) = x * y static member ``static member function name`` () = let b = nameof(BasicNameOfTests.StaticMethod) - Assert.AreEqual("StaticMethod",b) + Assert.AreEqual ("line " + string __LINE__) ("StaticMethod",b) member this.``class member lookup`` () = let b = nameof(localConstant) - Assert.AreEqual("localConstant",b) + Assert.AreEqual ("line " + string __LINE__) ("localConstant",b) static member ``static property name`` () = let b = nameof(BasicNameOfTests.StaticProperty) - Assert.AreEqual("StaticProperty",b) + Assert.AreEqual ("line " + string __LINE__) ("StaticProperty",b) member this.get_XYZ() = 1 static member ``member method starting with get_`` () = let x = BasicNameOfTests() let b = nameof(x.get_XYZ) - Assert.AreEqual("get_XYZ",b) + Assert.AreEqual ("line " + string __LINE__) ("get_XYZ",b) static member get_SXYZ() = 1 static member ``static method starting with get_`` () = let b = nameof(BasicNameOfTests.get_SXYZ) - Assert.AreEqual("get_SXYZ",b) + Assert.AreEqual ("line " + string __LINE__) ("get_SXYZ",b) static member ``nameof local property with encapsulated name`` () = let ``local property with encapsulated name and %.f`` = 0 let b = nameof(``local property with encapsulated name and %.f``) - Assert.AreEqual("local property with encapsulated name and %.f",b) + Assert.AreEqual ("line " + string __LINE__) ("local property with encapsulated name and %.f",b) type MethodGroupNameOfTests() = member this.MethodGroup() = () @@ -170,20 +177,20 @@ type MethodGroupNameOfTests() = member this.``single argument method group name lookup`` () = let b = nameof(this.MethodGroup) - Assert.AreEqual("MethodGroup",b) + Assert.AreEqual ("line " + string __LINE__) ("MethodGroup",b) member this.``multiple argument method group name lookup`` () = let b = nameof(this.MethodGroup1 : (float * int64 -> _)) - Assert.AreEqual("MethodGroup1",b) + Assert.AreEqual ("line " + string __LINE__) ("MethodGroup1",b) type FrameworkMethodTests() = member this.``library function name`` () = let b = nameof(List.map) - Assert.AreEqual("map",b) + Assert.AreEqual ("line " + string __LINE__) ("map",b) member this.``static class function name`` () = let b = nameof(System.Tuple.Create) - Assert.AreEqual("Create",b) + Assert.AreEqual ("line " + string __LINE__) ("Create",b) type CustomUnionType = | OptionA @@ -198,22 +205,22 @@ type UnionAndRecordNameOfTests() = member this.``measure 1`` () = let b = nameof(Milliquacks) - Assert.AreEqual("Milliquacks",b) + Assert.AreEqual ("line " + string __LINE__) ("Milliquacks",b) member this.``record case 1`` () = let sample = Unchecked.defaultof let b = nameof(sample.X) - let result = Assert.AreEqual("X",b) + let result = Assert.AreEqual ("line " + string __LINE__) ("X",b) let b = nameof(sample.Y) - result || Assert.AreEqual("Y",b) + result || Assert.AreEqual ("line " + string __LINE__) ("Y",b) member this.``union case 1`` () = let b = nameof(OptionA) - Assert.AreEqual("OptionA",b) + Assert.AreEqual ("line " + string __LINE__) ("OptionA",b) member this.``union case 2`` () = let b = nameof(OptionB) - Assert.AreEqual("OptionB",b) + Assert.AreEqual ("line " + string __LINE__) ("OptionB",b) type AttributeNameOfTests() = @@ -222,27 +229,33 @@ type AttributeNameOfTests() = let t = typeof.GetMethod("ok in attribute") let attrs = t.GetCustomAttributes(typeof, false) let attr = attrs.[0] :?> ObsoleteAttribute - Assert.AreEqual(attr.Message, "test string") + Assert.AreEqual ("line " + string __LINE__) (attr.Message, "test string") type OperatorNameOfTests() = member this.``lookup name of typeof operator`` () = let b = nameof(typeof) - Assert.AreEqual("typeof",b) + Assert.AreEqual ("line " + string __LINE__) ("typeof",b) member this.``lookup name of + operator`` () = let b = nameof(+) - Assert.AreEqual("op_Addition",b) + Assert.AreEqual ("line " + string __LINE__) ("+",b) + let b2 = nameof(op_Addition) + Assert.AreEqual ("line " + string __LINE__) ("op_Addition",b2) + let b3 = nameof(FSharp.Core.Operators.(+)) + Assert.AreEqual ("line " + string __LINE__) ("+",b3) + let b4 = nameof(FSharp.Core.Operators.op_Addition) + Assert.AreEqual ("line " + string __LINE__) ("op_Addition",b4) member this.``lookup name of |> operator`` () = let a = nameof(|>) - let result = Assert.AreEqual("op_PipeRight",a) + let result = Assert.AreEqual ("line " + string __LINE__) ("|>",a) let b = nameof(op_PipeRight) - result || Assert.AreEqual("op_PipeRight",b) + result || Assert.AreEqual ("line " + string __LINE__) ("op_PipeRight",b) member this.``lookup name of nameof operator`` () = let b = nameof(nameof) - Assert.AreEqual("nameof",b) + Assert.AreEqual ("line " + string __LINE__) ("nameof",b) type PatternMatchingOfOperatorNameTests() = member this.Method1(i:int) = () @@ -265,17 +278,17 @@ type NameOfOperatorForGenerics() = member this.``use it in a generic function`` () = let fullyGeneric x = x let b = nameof(fullyGeneric) - Assert.AreEqual("fullyGeneric",b) + Assert.AreEqual ("line " + string __LINE__) ("fullyGeneric",b) member this.``lookup name of a generic class`` () = let b = nameof System.Collections.Generic.List - Assert.AreEqual("List",b) + Assert.AreEqual ("line " + string __LINE__) ("List",b) type UserDefinedNameOfTests() = static member ``user defined nameof should shadow the operator`` () = let nameof x = "test" + x.ToString() let y = nameof 1 - Assert.AreEqual("test1",y) + Assert.AreEqual ("line " + string __LINE__) ("test1",y) type Person = { Name : string @@ -286,6 +299,30 @@ type Person = | x when x = nameof __.Age -> { __ with Age = value :?> int } | _ -> __ +type GenericClassNameOfTests<'TTT>() = + + static member ``can get name of class type parameter`` () = + let b = nameof<'TTT> + Assert.AreEqual ("line " + string __LINE__) ("TTT", b) + +type GenericClassNameOfTests2<[] 'TTT>() = + + static member ``can get name of class unit of measure type parameter`` () = + let b = nameof<'TTT> + Assert.AreEqual ("line " + string __LINE__) ("TTT", b) + +module RecTest = + let rec [] two = 2 + and twoName = nameof(two) + let ``can get name of recursive literal`` () = + Assert.AreEqual ("line " + string __LINE__) ("two", twoName) + +module rec RecTest2 = + let [] two = 2 + let twoName = nameof(two) + let ``can get name of literal in recursive module`` () = + Assert.AreEqual ("line " + string __LINE__) ("two", twoName) + do test "local variable name lookup" (BasicNameOfTests.``local variable name lookup`` ()) do test "local int function name" (BasicNameOfTests.``local int function name`` ()) do test "local curried function name" (BasicNameOfTests.``local curried function name`` ()) @@ -297,6 +334,7 @@ do test "can get name from inside a local function (needs to be let rec)" do test "can get name from inside static member" (BasicNameOfTests.``can get name from inside static member`` ()) do test "can get name from inside instance member" ((BasicNameOfTests()).``can get name from inside instance member`` ()) do test "can get name of instance member" ((BasicNameOfTests()).``can get name of instance member`` ()) +do test "can get name of instance member via unchecked" ((BasicNameOfTests()).``can get name of instance member via unchecked`` ()) do test "namespace name" (BasicNameOfTests.``namespace name`` ()) do test "module name" (BasicNameOfTests.``module name`` ()) do test "exception name" (BasicNameOfTests.``exception name`` ()) @@ -334,6 +372,41 @@ do test "lookup name of a generic class" ((NameOfOperatorForGener do test "user defined nameof should shadow the operator"(UserDefinedNameOfTests.``user defined nameof should shadow the operator`` ()) +do test "can get name of class type parameter"(GenericClassNameOfTests.``can get name of class type parameter`` ()) +do test "can get name of class type parameter"(GenericClassNameOfTests2.``can get name of class unit of measure type parameter`` ()) +do test "can get name of recursive literal"(RecTest.``can get name of recursive literal`` ()) +do test "can get name of literal in recursive module"(RecTest2.``can get name of literal in recursive module`` ()) + +module PatternMatchingWithNameof = + /// Simplified version of EventStore's API + type RecordedEvent = { EventType: string; Data: string } + + /// My concrete type: + type MyEvent = + | A of string + | B of string + + let deserialize (e: RecordedEvent) : MyEvent = + match e.EventType with + | nameof A -> A e.Data + | nameof B -> B e.Data + | t -> failwithf "Invalid EventType: %s" t + + let getData event = + match event with + | A amsg -> amsg + | B bmsg -> bmsg + + let re1 = { EventType = nameof A; Data = "hello" } + let re2 = { EventType = nameof B; Data = "world" } + + let a = deserialize re1 + let b = deserialize re2 + + check "fklwveoihwq1" (getData a) re1.Data + check "fklwveoihwq2" (getData b) re2.Data + + #if TESTS_AS_APP let RUN() = match !failures with diff --git a/tests/fsharp/core/nameof/version46/test.fsx b/tests/fsharp/core/nameof/version46/test.fsx index 2f17dc5aa03..214bb498d90 100644 --- a/tests/fsharp/core/nameof/version46/test.fsx +++ b/tests/fsharp/core/nameof/version46/test.fsx @@ -341,68 +341,3 @@ module Foo = let nameof = () let x = name () -do test "local variable name lookup" (BasicNameOfTests.``local variable name lookup`` ()) -do test "local int function name" (BasicNameOfTests.``local int function name`` ()) -do test "local curried function name" (BasicNameOfTests.``local curried function name`` ()) -do test "local tupled function name" (BasicNameOfTests.``local tupled function name`` ()) -do test "local unit function name" (BasicNameOfTests.``local unit function name`` ()) -do test "local function parameter name" (BasicNameOfTests.``local function parameter name`` ()) -do test "can get name from inside a local function (needs to be let rec)" - (BasicNameOfTests.``can get name from inside a local function (needs to be let rec)`` ()) -do test "can get name from inside static member" (BasicNameOfTests.``can get name from inside static member`` ()) -do test "can get name from inside instance member" ((BasicNameOfTests()).``can get name from inside instance member`` ()) -do test "can get name of instance member" ((BasicNameOfTests()).``can get name of instance member`` ()) -do test "namespace name" (BasicNameOfTests.``namespace name`` ()) -do test "module name" (BasicNameOfTests.``module name`` ()) -do test "exception name" (BasicNameOfTests.``exception name`` ()) -do test "nested type name 1" (BasicNameOfTests.``nested type name 1`` ()) -do test "type name 2" (BasicNameOfTests.``type name 2`` ()) -do test "member function which is defined below" (BasicNameOfTests.``member function which is defined below`` ()) -do test "class member lookup" ((BasicNameOfTests()).``class member lookup`` ()) -do test "static member function name" (BasicNameOfTests.``static member function name`` ()) -do test "static property name" (BasicNameOfTests.``static property name`` ()) -do test "member method starting with get_" (BasicNameOfTests.``member method starting with get_`` ()) -do test "static method starting with get_" (BasicNameOfTests.``static method starting with get_`` ()) -do test "nameof local property with encapsulated name" (BasicNameOfTests.``nameof local property with encapsulated name`` ()) - -do test "single argument method group name lookup" ((MethodGroupNameOfTests()).``single argument method group name lookup`` ()) -do test "multiple argument method group name lookup" ((MethodGroupNameOfTests()).``multiple argument method group name lookup`` ()) - -do test "measure 1" ((UnionAndRecordNameOfTests()).``measure 1`` ()) -do test "record case 1" ((UnionAndRecordNameOfTests()).``record case 1`` ()) -do test "union case 1" ((UnionAndRecordNameOfTests()).``union case 1`` ()) -do test "union case 2" ((UnionAndRecordNameOfTests()).``union case 2`` ()) - -do test "ok in attribute" ((AttributeNameOfTests()).``ok in attribute`` ()) - -do test "lookup name of typeof operator" ((OperatorNameOfTests()).``lookup name of typeof operator`` ()) -do test "lookup name of + operator" ((OperatorNameOfTests()).``lookup name of + operator`` ()) -do test "lookup name of |> operator" ((OperatorNameOfTests()).``lookup name of |> operator`` ()) -do test "lookup name of nameof operator" ((OperatorNameOfTests()).``lookup name of nameof operator`` ()) - -do test "use it as a match case guard" ((PatternMatchingOfOperatorNameTests()).``use it as a match case guard`` ()) - -do test "se it in a quotation" ((NameOfOperatorInQuotations()).``use it in a quotation`` ()) - -do test "use it in a generic function" ((NameOfOperatorForGenerics()).``use it in a generic function`` ()) -do test "lookup name of a generic class" ((NameOfOperatorForGenerics()).``lookup name of a generic class`` ()) - -do test "user defined nameof should shadow the operator"(UserDefinedNameOfTests.``user defined nameof should shadow the operator`` ()) - -#if TESTS_AS_APP -let RUN() = - match !failures with - | [] -> stdout.WriteLine "Test Passed" - | _ -> stdout.WriteLine "Test Failed" -#else -let aa = - match !failures with - | [] -> - stdout.WriteLine "Test Passed" - System.IO.File.WriteAllText("test.ok","ok") - exit 0 - | _ -> - stdout.WriteLine "Test Failed" - exit 1 -#endif - diff --git a/tests/fsharp/core/pinvoke/test.fsx b/tests/fsharp/core/pinvoke/test.fsx index 990df5a5998..28257b02025 100644 --- a/tests/fsharp/core/pinvoke/test.fsx +++ b/tests/fsharp/core/pinvoke/test.fsx @@ -16,7 +16,7 @@ let report_failure (s : string) = stderr.WriteLine s failures := !failures @ [s] -// We currently build targeting netcoreapp2_1, and will continue to do so through this VS cycle +// We currently build targeting netcoreapp3_1, and will continue to do so through this VS cycle // We will use this api to see if we are running on a netcore which supports pinvoke / refemit let definePInvokeMethod = typeof.GetMethod("DefinePInvokeMethod", [| diff --git a/tests/fsharp/core/printf-interpolated/test.fsx b/tests/fsharp/core/printf-interpolated/test.fsx new file mode 100644 index 00000000000..b1891f31ad9 --- /dev/null +++ b/tests/fsharp/core/printf-interpolated/test.fsx @@ -0,0 +1,301 @@ +// #Conformance #Printing + +#if TESTS_AS_APP +module Core_printf_interp +#endif + +open Printf + +let failures = ref [] + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures := !failures @ [s] + +// change this to true to run every test case +// leave as false to randomly execute a subset of cases (this is a very expensive test area) +let runEveryTest = true + +let test t (s1:Lazy) s2 = + stdout.WriteLine ("running test "+t+"...") + let s1 = s1.Force() + if s1 <> s2 then + report_failure ("test "+t+": expected \n\t'"+s2+"' but produced \n\t'"+s1+"'") + else + stdout.WriteLine ("test "+t+": correctly produced '"+s1+"'") + +let verify actual expected = test expected actual expected + +let adjust1 obj n1 = unbox ((unbox obj) n1) + +let _ = test "cewoui20" (lazy(sprintf $"")) "" +let _ = test "cewoui21" (lazy(sprintf $"abc")) "abc" +let _ = test "cewoui22" (lazy(sprintf $"%d{3}")) "3" +let _ = test "cewoui2a" (lazy(sprintf $"%o{0}")) "0" +let _ = test "cewoui2b" (lazy(sprintf $"%o{0}")) "0" +let _ = test "cewoui2c" (lazy(sprintf $"%o{5}")) "5" +let _ = test "cewoui2q" (lazy(sprintf $"%o{8}")) "10" +let _ = test "cewoui2w" (lazy(sprintf $"%o{15}")) "17" +let _ = test "cewoui2e" (lazy(sprintf $"%o{System.Int32.MinValue}" )) "20000000000" +let _ = test "cewoui2r" (lazy(sprintf $"%o{0xffffffff}" )) "37777777777" +let _ = test "cewoui2t" (lazy(sprintf $"%o{System.Int32.MinValue+1}")) "20000000001" +let _ = test "cewoui2y" (lazy(sprintf $"%o{System.Int32.MaxValue}")) "17777777777" +let _ = test "cewoui2u" (lazy(sprintf $"%o{-1}" )) "37777777777" +let _ = test "cewoui2aB" (lazy(sprintf $"%B{0}")) "0" +let _ = test "cewoui2bB" (lazy(sprintf $"%B{0}")) "0" +let _ = test "cewoui2cB" (lazy(sprintf $"%B{5}")) "101" +let _ = test "cewoui2qB" (lazy(sprintf $"%B{8}")) "1000" +let _ = test "cewoui2wB" (lazy(sprintf $"%B{15}")) "1111" +let _ = test "cewoui2eB" (lazy(sprintf $"%B{System.Int32.MinValue}" )) "10000000000000000000000000000000" +let _ = test "cewoui2rB" (lazy(sprintf $"%B{0xffffffff}" )) "11111111111111111111111111111111" +let _ = test "cewoui2tB" (lazy(sprintf $"%B{System.Int32.MinValue+1}")) "10000000000000000000000000000001" +let _ = test "cewoui2yB" (lazy(sprintf $"%B{System.Int32.MaxValue}")) "1111111111111111111111111111111" +let _ = test "cewoui2uB" (lazy(sprintf $"%B{-1}" )) "11111111111111111111111111111111" + +let f z = sprintf $"%o{z}" + +let _ = test "cewoui2a" (lazy(f 0)) "0" +let _ = test "cewoui2s" (lazy(f 0)) "0" +let _ = test "cewoui2d" (lazy(f 5)) "5" +let _ = test "cewoui2f" (lazy(f 8)) "10" +let _ = test "cewoui2g" (lazy(f 15)) "17" +let _ = test "cewoui2h" (lazy(f System.Int32.MinValue)) "20000000000" +let _ = test "cewoui2j" (lazy(f 0xffffffff)) "37777777777" +let _ = test "cewoui2lk" (lazy(f (System.Int32.MinValue+1))) "20000000001" +let _ = test "cewoui2l" (lazy(f System.Int32.MaxValue)) "17777777777" +let _ = test "cewoui212" (lazy(f (-1))) "37777777777" + +let fB z = sprintf $"%B{z}" + +let _ = test "cewoui2aB" (lazy(fB 0)) "0" +let _ = test "cewoui2sB" (lazy(fB 0)) "0" +let _ = test "cewoui2dB" (lazy(fB 5)) "101" +let _ = test "cewoui2fB" (lazy(fB 8)) "1000" +let _ = test "cewoui2gB" (lazy(fB 15)) "1111" +let _ = test "cewoui2hB" (lazy(fB System.Int32.MinValue)) "10000000000000000000000000000000" +let _ = test "cewoui2jB" (lazy(fB 0xffffffff)) "11111111111111111111111111111111" +let _ = test "cewoui2lkB" (lazy(fB (System.Int32.MinValue+1))) "10000000000000000000000000000001" +let _ = test "cewoui2lB" (lazy(fB System.Int32.MaxValue)) "1111111111111111111111111111111" +let _ = test "cewoui212B" (lazy(fB (-1))) "11111111111111111111111111111111" + +// check bprintf +let _ = test "csd3oui2!" (lazy(let buf = new System.Text.StringBuilder() in ignore (bprintf buf $"%x{0}%x{1}"); buf.ToString())) "01" + +// check kbprintf +let _ = test "csd3oui2!1" (lazy(let buf = new System.Text.StringBuilder() in kbprintf (fun () -> buf.ToString()) buf $"%x{0}%x{1}")) "01" + +let _ = test "cewoui2!" (lazy(sprintf $"%x{0}")) "0" +let _ = test "cewoui26" (lazy(sprintf $"%x{5}")) "5" +let _ = test "cewoui2f" (lazy(sprintf $"%x{8}")) "8" +let _ = test "cewoui29" (lazy(sprintf $"%x{15}")) "f" +let _ = test "cewoui2Z" (lazy(sprintf $"%x{System.Int32.MinValue}" )) "80000000" +let _ = test "cewoui2X" (lazy(sprintf $"%x{0xffffffff}" )) "ffffffff" +let _ = test "cewoui2A" (lazy(sprintf $"%x{System.Int32.MinValue+1}" )) "80000001" +let _ = test "cewoui2Q" (lazy(sprintf $"%x{System.Int32.MaxValue}" )) "7fffffff" + +let fx z = sprintf $"%x{z}" +let _ = test "cewoui2W" (lazy(fx 0)) "0" +let _ = test "cewoui2E" (lazy(fx 5)) "5" +let _ = test "cewoui2R" (lazy(fx 8)) "8" +let _ = test "cewoui2T" (lazy(fx 15)) "f" +let _ = test "cewoui2Y" (lazy(fx System.Int32.MinValue)) "80000000" +let _ = test "cewoui2U" (lazy(fx 0xffffffff)) "ffffffff" +let _ = test "cewoui2I" (lazy(fx (System.Int32.MinValue+1))) "80000001" +let _ = test "cewoui2O" (lazy(fx System.Int32.MaxValue)) "7fffffff" + +let _ = test "cewoui2Z" (lazy(sprintf $"%X{0}")) "0" +let _ = test "cewoui2X" (lazy(sprintf $"%X{5}")) "5" +let _ = test "cewoui2C" (lazy(sprintf $"%X{8}")) "8" +let _ = test "cewoui2V" (lazy(sprintf $"%X{15}")) "F" +let _ = test "cewoui2v" (lazy(sprintf $"%X{System.Int32.MinValue}" )) "80000000" +let _ = test "cewoui2B" (lazy(sprintf $"%X{0xffffffff}" )) "FFFFFFFF" +let _ = test "cewoui2N" (lazy(sprintf $"%X{System.Int32.MinValue+1}")) "80000001" +let _ = test "cewoui2M" (lazy(sprintf $"%X{System.Int32.MaxValue}" )) "7FFFFFFF" + +let _ = test "cewou44a" (lazy(sprintf $"%u{0}")) "0" +let _ = test "cewou44b" (lazy(sprintf $"%u{5}" )) "5" +let _ = test "cewou44c" (lazy(sprintf $"%u{8}" )) "8" +let _ = test "cewou44d" (lazy(sprintf $"%u{15}" )) "15" +let _ = test "cewou44e" (lazy(sprintf $"%u{System.Int32.MinValue}" )) "2147483648" +let _ = test "cewou44f" (lazy(sprintf $"%u{0xffffffff}" )) "4294967295" +let _ = test "cewou44g" (lazy(sprintf $"%u{System.Int32.MinValue+1}" )) "2147483649" +let _ = test "cewou44h" (lazy(sprintf $"%u{System.Int32.MaxValue}" )) "2147483647" + +let _ = test "cewou45a" (lazy(sprintf $"%d{0ul}" )) "0" +let _ = test "cewou45b" (lazy(sprintf $"%d{5ul}" )) "5" +let _ = test "cewou45c" (lazy(sprintf $"%d{8ul}" )) "8" +let _ = test "cewou45d" (lazy(sprintf $"%d{15ul}" )) "15" +let _ = test "cewou45e" (lazy(sprintf $"%d{2147483648ul}" )) "2147483648" +let _ = test "cewou45f" (lazy(sprintf $"%d{4294967295ul}" )) "4294967295" +let _ = test "cewou45g" (lazy(sprintf $"%d{2147483649ul}" )) "2147483649" +let _ = test "cewou45h" (lazy(sprintf $"%d{2147483647ul}" )) "2147483647" + +let _ = test "cewou46a" (lazy(sprintf $"%d{0ul}" )) "0" +let _ = test "cewou46b" (lazy(sprintf $"%d{5ul}" )) "5" +let _ = test "cewou46c" (lazy(sprintf $"%d{8ul}" )) "8" +let _ = test "cewou46d" (lazy(sprintf $"%d{15ul}" )) "15" +let _ = test "cewou46e" (lazy(sprintf $"%d{2147483648ul}" )) "2147483648" +let _ = test "cewou46f" (lazy(sprintf $"%d{4294967295ul}" )) "4294967295" +let _ = test "cewou46g" (lazy(sprintf $"%d{2147483649ul}" )) "2147483649" +let _ = test "cewou46h" (lazy(sprintf $"%d{2147483647ul}" )) "2147483647" + +let _ = test "ceew903" (lazy(sprintf $"%u{System.Int64.MaxValue}" )) "9223372036854775807" +let _ = test "ceew903" (lazy(sprintf $"%u{System.Int64.MinValue}" )) "9223372036854775808" +let _ = test "ceew903" (lazy(sprintf $"%d{System.Int64.MaxValue}" )) "9223372036854775807" +let _ = test "ceew903" (lazy(sprintf $"%d{System.Int64.MinValue}" )) "-9223372036854775808" + +let _ = test "ceew903" (lazy(sprintf $"%u{System.Int64.MaxValue}" )) "9223372036854775807" +let _ = test "ceew903" (lazy(sprintf $"%u{System.Int64.MinValue}" )) "9223372036854775808" +let _ = test "ceew903" (lazy(sprintf $"%d{System.Int64.MaxValue}" )) "9223372036854775807" +let _ = test "ceew903" (lazy(sprintf $"%d{System.Int64.MinValue}" )) "-9223372036854775808" + +let _ = test "cewou47a" (lazy(sprintf $"%d{0n}" )) "0" +let _ = test "cewou47b" (lazy(sprintf $"%d{5n}" )) "5" +let _ = test "cewou47c" (lazy(sprintf $"%d{8n}" )) "8" +let _ = test "cewou47d" (lazy(sprintf $"%d{15n}" )) "15" +let _ = test "cewou47e" (lazy(sprintf $"%u{2147483648n}" )) "2147483648" +let _ = test "cewou47f" (lazy(sprintf $"%u{4294967295n}" )) "4294967295" +let _ = test "cewou47g" (lazy(sprintf $"%u{2147483649n}" )) "2147483649" +let _ = test "cewou47h" (lazy(sprintf $"%u{2147483647n}" )) "2147483647" + +let _ = test "cewou47a" (lazy(sprintf $"%d{0n}" )) "0" +let _ = test "cewou47b" (lazy(sprintf $"%d{5n}" )) "5" +let _ = test "cewou47c" (lazy(sprintf $"%d{8n}" )) "8" +let _ = test "cewou47d" (lazy(sprintf $"%d{15n}" )) "15" +let _ = test "cewou47e" (lazy(sprintf $"%u{2147483648n}" )) "2147483648" +let _ = test "cewou47f" (lazy(sprintf $"%u{4294967295n}" )) "4294967295" +let _ = test "cewou47g" (lazy(sprintf $"%u{2147483649n}" )) "2147483649" +let _ = test "cewou47h" (lazy(sprintf $"%u{2147483647n}" )) "2147483647" + +let _ = test "cewou48a" (lazy(sprintf $"%d{0un}" )) "0" +let _ = test "cewou48b" (lazy(sprintf $"%d{5un}" )) "5" +let _ = test "cewou48c" (lazy(sprintf $"%d{8un}" )) "8" +let _ = test "cewou48d" (lazy(sprintf $"%d{15un}" )) "15" +let _ = test "cewou48e" (lazy(sprintf $"%u{2147483648un}" )) "2147483648" +let _ = test "cewou48f" (lazy(sprintf $"%u{4294967295un}" )) "4294967295" +let _ = test "cewou48g" (lazy(sprintf $"%u{2147483649un}" )) "2147483649" +let _ = test "cewou48h" (lazy(sprintf $"%u{2147483647un}" )) "2147483647" + +let _ = test "cewou49c" (lazy(sprintf $"%+d{5}" )) "+5" +let _ = test "cewou49d" (lazy(sprintf $"% d{5}" )) " 5" +let _ = test "cewou49e" (lazy(sprintf $"%+4d{5}" )) " +5" +let _ = test "cewou49f" (lazy(sprintf $"%-+4d{5}" )) "+5 " +let _ = test "cewou49g" (lazy(sprintf $"%-4d{5}" )) "5 " +let _ = test "cewou49h" (lazy(sprintf $"%- 4d{5}" )) " 5 " +let _ = test "cewou49i" (lazy(sprintf $"%- d{5}" )) " 5" +let _ = test "cewou49j" (lazy(sprintf $"% d{5}" )) " 5" +let _ = test "weioj31" (lazy(sprintf $"%3d{5}")) " 5" +let _ = test "weioj32" (lazy(sprintf $"%1d{5}")) "5" +let _ = test "weioj33" (lazy(sprintf $"%2d{500}")) "500" + +let _ = + test "test8535" (lazy(sprintf $"""%t{(fun _ -> "???")}""" )) "???" + test "test8536" (lazy(sprintf $"A%d{0}B")) "A0B" + test "test8537" (lazy(sprintf $"A%d{0}B%d{1}C")) "A0B1C" + test "test8538" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D")) "A0B1C2D" + test "test8539" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D%d{3}E")) "A0B1C2D3E" + test "test8540" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D%d{3}E%d{4}F")) "A0B1C2D3E4F" + test "test8541" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D%d{3}E%d{4}F%d{5}G")) "A0B1C2D3E4F5G" + test "test8542" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D%d{3}E%d{4}F%d{5}G%d{6}H")) "A0B1C2D3E4F5G6H" + test "test8543" (lazy(sprintf $"A%d{0}B%d{1}C%d{2}D%d{3}E%d{4}F%d{5}G%d{6}H%d{7}I")) "A0B1C2D3E4F5G6H7I" + + +let _ = + test "test8361" (lazy(sprintf $"""%A{"abc"}""")) "\"abc\"" + test "test8362" (lazy(sprintf $"""%5A{"abc"}""")) "\"abc\"" + test "test8363" (lazy(sprintf $"""%1A{"abc"}""")) "\"abc\"" + test "test8365" (lazy(sprintf $"""%.5A{"abc"}""")) "\"abc\"" + test "test8368" (lazy(sprintf $"""%-A{"abc"}""")) "\"abc\"" + test "test8369" (lazy(sprintf $"""%-5A{"abc"}""")) "\"abc\"" + test "test8370" (lazy(sprintf $"""%-1A{"abc"}""")) "\"abc\"" + test "test8372" (lazy(sprintf $"""%-.5A{"abc"}""")) "\"abc\"" + test "test8375" (lazy(sprintf $"""%+A{"abc"}""")) "\"abc\"" + test "test8376" (lazy(sprintf $"""%+5A{"abc"}""")) "\"abc\"" + test "test8377" (lazy(sprintf $"""%+1A{"abc"}""")) "\"abc\"" + test "test8379" (lazy(sprintf $"""%+.5A{"abc"}""")) "\"abc\"" + test "test8382" (lazy(sprintf $"""%-+A{"abc"}""")) "\"abc\"" + test "test8383" (lazy(sprintf $"""%-+5A{"abc"}""")) "\"abc\"" + test "test8384" (lazy(sprintf $"""%-+1A{"abc"}""")) "\"abc\"" + test "test8386" (lazy(sprintf $"""%-+.5A{"abc"}""")) "\"abc\"" + test "test8389" (lazy(sprintf $"""%A{15}""")) "15" + test "test8390" (lazy(sprintf $"""%5A{15}""")) "15" + test "test8391" (lazy(sprintf $"""%1A{15}""")) "15" + test "test8393" (lazy(sprintf $"""%.5A{15}""")) "15" + test "test8396" (lazy(sprintf $"""%-A{15}""")) "15" + test "test8397" (lazy(sprintf $"""%-5A{15}""")) "15" + test "test8398" (lazy(sprintf $"""%-1A{15}""")) "15" + test "test8400" (lazy(sprintf $"""%-.5A{15}""")) "15" + test "test8403" (lazy(sprintf $"""%+A{15}""")) "15" + test "test8404" (lazy(sprintf $"""%+5A{15}""")) "15" + test "test8405" (lazy(sprintf $"""%+1A{15}""")) "15" + test "test8407" (lazy(sprintf $"""%+.5A{15}""")) "15" + test "test8410" (lazy(sprintf $"""%-+A{15}""")) "15" + test "test8411" (lazy(sprintf $"""%-+5A{15}""")) "15" + test "test8412" (lazy(sprintf $"""%-+1A{15}""")) "15" + test "test8414" (lazy(sprintf $"""%-+.5A{15}""")) "15" + + test "test8417" (lazy(sprintf $"""%A{-10}""")) "-10" + test "test8418" (lazy(sprintf $"""%5A{-10}""")) "-10" + test "test8419" (lazy(sprintf $"""%1A{-10}""")) "-10" + test "test8421" (lazy(sprintf $"""%.5A{-10}""")) "-10" + test "test8424" (lazy(sprintf $"""%-A{-10}""")) "-10" + test "test8425" (lazy(sprintf $"""%-5A{-10}""")) "-10" + test "test8426" (lazy(sprintf $"""%-1A{-10}""")) "-10" + test "test8428" (lazy(sprintf $"""%-.5A{-10}""")) "-10" + test "test8431" (lazy(sprintf $"""%+A{-10}""")) "-10" + test "test8432" (lazy(sprintf $"""%+5A{-10}""")) "-10" + test "test8433" (lazy(sprintf $"""%+1A{-10}""")) "-10" + test "test8435" (lazy(sprintf $"""%+.5A{-10}""")) "-10" + test "test8438" (lazy(sprintf $"""%-+A{-10}""")) "-10" + test "test8439" (lazy(sprintf $"""%-+5A{-10}""")) "-10" + test "test8440" (lazy(sprintf $"""%-+1A{-10}""")) "-10" + test "test8442" (lazy(sprintf $"""%-+.5A{-10}""")) "-10" + + // Check the static type matters for %A holes + test "test8445b1" (lazy(sprintf $"""%A{(Unchecked.defaultof)}""")) "None" + test "test8445b2" (lazy(sprintf $"""%A{box (None: int option)}""")) "" + test "test8445b3" (lazy(sprintf $"""%A{(None: int option)}""")) "None" + test "test8445b4" (lazy(sprintf $"""%A{(None: string option)}""")) "None" + test "test8445b5" (lazy(sprintf $"""%A{(None: obj option)}""")) "None" + test "test8445b6" (lazy($"""%A{(Unchecked.defaultof)}""")) "None" + test "test8445b7a" (lazy($"""{null}""")) "" + test "test8445b7b" (lazy($"""%O{null}""")) "" + test "test8445b8" (lazy($"""%A{null}""")) "" + test "test8445b9" (lazy($"""%A{box (None: int option)}""")) "" + test "test8445b10" (lazy($"""%A{(None: int option)}""")) "None" + test "test8445b11" (lazy($"""%A{(None: string option)}""")) "None" + test "test8445b12" (lazy($"""%A{(None: obj option)}""")) "None" + + test "test8445" (lazy(sprintf $"""%A{null}""")) "" + test "test8446" (lazy(sprintf $"""%5A{null}""")) "" + test "test8447" (lazy(sprintf $"""%1A{null}""")) "" + test "test8449" (lazy(sprintf $"""%.5A{null}""")) "" + test "test8452" (lazy(sprintf $"""%-A{null}""")) "" + test "test8453" (lazy(sprintf $"""%-5A{null}""")) "" + test "test8454" (lazy(sprintf $"""%-1A{null}""")) "" + test "test8456" (lazy(sprintf $"""%-.5A{null}""")) "" + test "test8459" (lazy(sprintf $"""%+A{null}""")) "" + test "test8460" (lazy(sprintf $"""%+5A{null}""")) "" + test "test8461" (lazy(sprintf $"""%+1A{null}""")) "" + test "test8463" (lazy(sprintf $"""%+.5A{null}""")) "" + test "test8466" (lazy(sprintf $"""%-+A{null}""")) "" + test "test8467" (lazy(sprintf $"""%-+5A{null}""")) "" + test "test8468" (lazy(sprintf $"""%-+1A{null}""")) "" + test "test8470" (lazy(sprintf $"""%-+.5A{null}""")) "" + + +#if TESTS_AS_APP +let RUN() = !failures +#else +let aa = + match !failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + stdout.WriteLine "Test Failed" + exit 1 +#endif + diff --git a/tests/fsharp/core/printf/test.fsx b/tests/fsharp/core/printf/test.fsx index fe48744f84e..8ea722c9ee4 100644 --- a/tests/fsharp/core/printf/test.fsx +++ b/tests/fsharp/core/printf/test.fsx @@ -25,6 +25,7 @@ let rnd = System.Random() let test t (s1:Lazy) s2 = if runEveryTest || (rnd.Next() % 10) = 0 then + stdout.WriteLine ("running test "+t+"...") let s1 = s1.Force() if s1 <> s2 then report_failure ("test "+t+": expected \n\t'"+s2+"' but produced \n\t'"+s1+"'") @@ -57,8 +58,22 @@ let _ = test "cewoui2e" (lazy(sprintf "%o" System.Int32.MinValue)) "20000000000" let _ = test "cewoui2r" (lazy(sprintf "%o" 0xffffffff)) "37777777777" let _ = test "cewoui2t" (lazy(sprintf "%o" (System.Int32.MinValue+1))) "20000000001" let _ = test "cewoui2y" (lazy(sprintf "%o" System.Int32.MaxValue)) "17777777777" - let _ = test "cewoui2u" (lazy(sprintf "%o" (-1))) "37777777777" +let _ = test "cewoui2i" (lazy(sprintf "%o" System.UInt64.MaxValue)) "1777777777777777777777" +let _ = test "cewoui2i" (lazy(sprintf "%o" System.Int64.MinValue)) "1000000000000000000000" + +let _ = test "cewoui2aB" (lazy(sprintf "%B" 0)) "0" +let _ = test "cewoui2bB" (lazy(sprintf "%B" 0)) "0" +let _ = test "cewoui2cB" (lazy(sprintf "%B" 5)) "101" +let _ = test "cewoui2qB" (lazy(sprintf "%B" 8)) "1000" +let _ = test "cewoui2wB" (lazy(sprintf "%B" 15)) "1111" +let _ = test "cewoui2eB" (lazy(sprintf "%B" System.Int32.MinValue)) "10000000000000000000000000000000" +let _ = test "cewoui2rB" (lazy(sprintf "%B" 0xffffffff)) "11111111111111111111111111111111" +let _ = test "cewoui2tB" (lazy(sprintf "%B" (System.Int32.MinValue+1))) "10000000000000000000000000000001" +let _ = test "cewoui2yB" (lazy(sprintf "%B" System.Int32.MaxValue)) "1111111111111111111111111111111" +let _ = test "cewoui2uB" (lazy(sprintf "%B" (-1))) "11111111111111111111111111111111" +let _ = test "cewoui2iB" (lazy(sprintf "%B" System.UInt64.MaxValue)) "1111111111111111111111111111111111111111111111111111111111111111" +let _ = test "cewoui2iB" (lazy(sprintf "%B" System.Int64.MinValue)) "1000000000000000000000000000000000000000000000000000000000000000" let f = sprintf "%o" @@ -71,9 +86,21 @@ let _ = test "cewoui2h" (lazy(f System.Int32.MinValue)) "20000000000" let _ = test "cewoui2j" (lazy(f 0xffffffff)) "37777777777" let _ = test "cewoui2lk" (lazy(f (System.Int32.MinValue+1))) "20000000001" let _ = test "cewoui2l" (lazy(f System.Int32.MaxValue)) "17777777777" - let _ = test "cewoui212" (lazy(f (-1))) "37777777777" +let fB = sprintf "%B" + +let _ = test "cewoui2a" (lazy(fB 0)) "0" +let _ = test "cewoui2s" (lazy(fB 0)) "0" +let _ = test "cewoui2d" (lazy(fB 5)) "101" +let _ = test "cewoui2f" (lazy(fB 8)) "1000" +let _ = test "cewoui2g" (lazy(fB 15)) "1111" +let _ = test "cewoui2h" (lazy(fB System.Int32.MinValue)) "10000000000000000000000000000000" +let _ = test "cewoui2j" (lazy(fB 0xffffffff)) "11111111111111111111111111111111" +let _ = test "cewoui2lk" (lazy(fB (System.Int32.MinValue+1))) "10000000000000000000000000000001" +let _ = test "cewoui2l" (lazy(fB System.Int32.MaxValue)) "1111111111111111111111111111111" +let _ = test "cewoui212" (lazy(fB (-1))) "11111111111111111111111111111111" + // Test nothing comes out until all arguments have been applied let _ = test "csd3oui2!" (lazy(let buf = new System.Text.StringBuilder() in ignore (bprintf buf "%x%x" 0); buf.ToString())) "" let _ = test "csd3oui2!" (lazy(let buf = new System.Text.StringBuilder() in ignore (bprintf buf "%x%x" 0 1); buf.ToString())) "01" @@ -88,6 +115,8 @@ let _ = test "cewoui2Z" (lazy(sprintf "%x" System.Int32.MinValue)) "80000000" let _ = test "cewoui2X" (lazy(sprintf "%x" 0xffffffff)) "ffffffff" let _ = test "cewoui2A" (lazy(sprintf "%x" (System.Int32.MinValue+1))) "80000001" let _ = test "cewoui2Q" (lazy(sprintf "%x" System.Int32.MaxValue)) "7fffffff" +let _ = test "cewoui2`" (lazy(sprintf "%x" System.UInt64.MaxValue)) "ffffffffffffffff" +let _ = test "cewoui2~" (lazy(sprintf "%x" System.Int64.MinValue)) "8000000000000000" let fx = sprintf "%x" let _ = test "cewoui2W" (lazy(fx 0)) "0" @@ -107,6 +136,8 @@ let _ = test "cewoui2v" (lazy(sprintf "%X" System.Int32.MinValue)) "80000000" let _ = test "cewoui2B" (lazy(sprintf "%X" 0xffffffff)) "FFFFFFFF" let _ = test "cewoui2N" (lazy(sprintf "%X" (System.Int32.MinValue+1))) "80000001" let _ = test "cewoui2M" (lazy(sprintf "%X" System.Int32.MaxValue)) "7FFFFFFF" +let _ = test "cewoui2," (lazy(sprintf "%X" System.UInt64.MaxValue)) "FFFFFFFFFFFFFFFF" +let _ = test "cewoui2." (lazy(sprintf "%X" System.Int64.MinValue)) "8000000000000000" let _ = test "cewou44a" (lazy(sprintf "%u" 0)) "0" let _ = test "cewou44b" (lazy(sprintf "%u" 5)) "5" @@ -116,6 +147,7 @@ let _ = test "cewou44e" (lazy(sprintf "%u" System.Int32.MinValue)) "2147483648" let _ = test "cewou44f" (lazy(sprintf "%u" 0xffffffff)) "4294967295" let _ = test "cewou44g" (lazy(sprintf "%u" (System.Int32.MinValue+1))) "2147483649" let _ = test "cewou44h" (lazy(sprintf "%u" System.Int32.MaxValue)) "2147483647" +let _ = test "cewou44i" (lazy(sprintf "%u" System.UInt64.MaxValue)) "18446744073709551615" let _ = test "cewou45a" (lazy(sprintf "%d" 0ul)) "0" let _ = test "cewou45b" (lazy(sprintf "%d" 5ul)) "5" @@ -125,6 +157,7 @@ let _ = test "cewou45e" (lazy(sprintf "%d" 2147483648ul)) "2147483648" let _ = test "cewou45f" (lazy(sprintf "%d" 4294967295ul)) "4294967295" let _ = test "cewou45g" (lazy(sprintf "%d" 2147483649ul)) "2147483649" let _ = test "cewou45h" (lazy(sprintf "%d" 2147483647ul)) "2147483647" +let _ = test "cewou45i" (lazy(sprintf "%d" System.UInt64.MaxValue)) "18446744073709551615" let _ = test "cewou46a" (lazy(sprintf "%d" 0ul)) "0" let _ = test "cewou46b" (lazy(sprintf "%d" 5ul)) "5" @@ -134,6 +167,7 @@ let _ = test "cewou46e" (lazy(sprintf "%d" 2147483648ul)) "2147483648" let _ = test "cewou46f" (lazy(sprintf "%d" 4294967295ul)) "4294967295" let _ = test "cewou46g" (lazy(sprintf "%d" 2147483649ul)) "2147483649" let _ = test "cewou46h" (lazy(sprintf "%d" 2147483647ul)) "2147483647" +let _ = test "cewou46i" (lazy(sprintf "%d" System.UInt64.MaxValue)) "18446744073709551615" let _ = test "ceew903" (lazy(sprintf "%u" System.Int64.MaxValue)) "9223372036854775807" let _ = test "ceew903" (lazy(sprintf "%u" System.Int64.MinValue)) "9223372036854775808" diff --git a/tests/fsharp/core/printing/test.fsx b/tests/fsharp/core/printing/test.fsx index 60b36a00ea2..51c2c82c29f 100644 --- a/tests/fsharp/core/printing/test.fsx +++ b/tests/fsharp/core/printing/test.fsx @@ -1,5 +1,4 @@ // #Regression #Conformance #Printing #FSI #Regression -#light;; let repeatId = "A";; let repeatId = "B";; @@ -217,7 +216,7 @@ module RepeatedModule = begin let repeatedByteLiteral = [| 12uy; 13uy; 14uy |] e (* no eval in between, since time can vary and look like a regression *) #time;; (* time off *) "Check #unknown command";; -#blaaaaaa;; // blaaaaaa is not a known command +#blaaaaaa // blaaaaaa is not a known command;; "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)";; #I "/";; @@ -929,6 +928,163 @@ type optionRecord = { x: obj } let x = { x = null } ;; +type RecordWithMembers = + { x: obj } + member a.Property = 1 + member a.Method() = 2 +;; +type UnionWithMembers = + /// This is Case1 + | Case1 + /// This is Case2 + | Case2 of int + /// This is Property + member a.Property = 1 + /// This is Method + member a.Method() = 2 +;; +type OneFieldRecordNoXmlDoc = + { OneField: obj} +;; +type OneFieldRecordXmlDoc = + { /// Hello! + OneField: obj} +;; +type TwoFieldRecordNoXmlDoc = + { TwoFields1: obj; TwoFields2: obj } +;; +type TwoFieldRecordXmlDoc = + { /// Goog + TwoFields1: obj; + /// Even more good + TwoFields2: obj } +;; +type System.Int32 with + member a.ExtrinsicExtensionProperty = 1 + member a.ExtrinsicExtensionMethod() = 2 +;; + +let ``value with spaces in name`` = true +;; + +let functionWhichTakesLongNameMixedParameters + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int) + (ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int, + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int) = 1 + 1 +;; + +let functionWhichTakesLongNameTupledParameters + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int, + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int, + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int) = 1 + 1 +;; + +let functionWhichTakesLongNameCurriedParameters + (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int) + (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int) + (cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int) + (dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int) = 1 + 1 +;; + +let functionWhichTakesMixedLengthCurriedParametersA a b c ddddddddddddddddddddddddddddddddddddddddddddd = 1 + 1 +;; + +let functionWhichTakesMixedLengthCurriedParametersB aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d = 1 + 1 +;; + + +let f (``parameter with spaces in name``: int) = 1 +;; + +let functionWhichTakesAParameterPeeciselyPlusButNotOpAddition (``+``: int -> int -> int) = ``+`` 1 2 +;; + +let functionWhichTakesAParameterOpAddition ((+): int -> int -> int) = 1 + 1 +;; + +let functionWhichTakesAParameterCalled_land (``land``: int -> int -> int) = 1 + 1 +;; + +type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition : obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } +;; + +type UnionWithSpacesInNamesOfCases = + | ``Funky name`` // Check this gets double ticks + | ``Funky name 2`` // Check this gets double ticks +;; + +type ``Type with spaces in name`` = // Check this gets double ticks + | A + | B +;; + +type op_Addition = // Check this doesn't go to (+) for types + | A + | B +;; + +type ``land`` = // Check this doesn't go to (land) for types, it gets double ticks because (land) is deprecated + | A + | B +;; + +module ``Module with spaces in name`` = // Check this gets double ticks + let x = 1 +;; + +module op_Addition = // Check this doesn't go to (+) for modules, nor get double ticks + let x = 1 +;; + +module ``land`` = // Check this doesn't go to (land) for modules, it gets double ticks because (land) is deprecated + let x = 1 +;; + +let ``+`` x y = 1 // This is not op_Addition but a function called '+' +;; + +let (+) x y = x + y + 1 // This is op_Addition not a function called '+' +;; + +let ``base`` = 2 // This is not a base value but a value called 'base' +;; + +let ``mod`` = 2 // This is a value called 'mod' in .NET IL, but we can't distinguish from (mod), so print it as (mod) +;; + +let ``or`` = 2 // This is a value called 'or' in .NET IL, legacy, but we can't distinguish from (or), so print it as ``or`` +;; + +let ``land`` = 2 // This is a value called 'land' in .NET IL, legacy, but we can't distinguish from legacy unused (land), so print it as ``land`` +;; + +let ``.ctor`` = 2 // This is a value called '.ctor' in .NET IL, and has no special properties +;; + +let ``.cctor`` = 2 // This is a value called '.cctor' in .NET IL, and has no special properties +;; + +// Check line wrapping of very long literals +[] +let SomeLiteralWithASomewhatLongName = "SomeVeryLongLiteralValueWithLotsOfCharacters" + +[] +let SomeLiteralWithASomewhatLongName2 = "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" + +[] +let ShortName = "hi" +;; + + ;; (* ;; needed, to isolate error regressions *) ;;exit 0;; (* piped in to enable error regressions *) \ No newline at end of file diff --git a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl index 386c625eeff..4d3209ca246 100644 --- a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl @@ -1,330 +1,336 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^^^^^^^^^ + +stdin(219,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ -stdin(572,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(571,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1 = static member (+-+-+) x = "1 argument";; -----------------------------------------^^^^^ -stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(572,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1b = static member (+-+-+) (x) = "1 (argument) [brackets make no diff]";; -----------------------------------------^^^^^ -stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1c = static member (+-+-+) x = let a,b = x in "1 argument, tuple typed from RHS. Still not OK";; -----------------------------------------^^^^^ -stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1d = static member (+-+-+) (x:int*int) = "1 argument, tuple typed from LHS. Still not OK";; -----------------------------------------^^^^^ -stdin(576,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T3 = static member (+-+-+) (x,y,z) = "3 arguments";; -----------------------------------------^^^^^ -stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(577,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U2 = static member (+-+-+) (x,y) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(584,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(584,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(588,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. +stdin(588,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. static member (&^) = "AMP_AMP" -------------------^^ -stdin(590,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(589,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(590,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. +stdin(590,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. static member (!=) = "INFIX_COMPARE_OP" -------------------^^ -stdin(593,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(592,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(597,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(596,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...!=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^^ -stdin(598,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(597,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...<) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(599,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(598,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...>) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(600,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(599,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ($) = "DOLLAR" -------------------^ -stdin(602,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(601,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(602,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. +stdin(602,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(603,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. +stdin(603,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(604,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(604,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(605,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(605,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (...@) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(607,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(606,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...^) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(608,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(607,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (%) = "PERCENT_OP" -------------------^ -stdin(609,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(608,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (-) = "MINUS" -------------------^ -stdin(611,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(610,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( * ) = "STAR" --------------------^ -stdin(612,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(611,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (/) = "INFIX_STAR_DIV_MOD_OP" -------------------^ -stdin(614,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(613,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...* ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(616,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(615,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( .../ ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(617,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(616,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...% ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(618,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(617,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ** ) = "INFIX_STAR_STAR_OP" --------------------^^ -stdin(619,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(618,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... member this.ToString() = "ABC" ----------------^^^^^^^^ -stdin(624,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. +stdin(623,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. member this.M() = "string" ----------------^ -stdin(765,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. +stdin(764,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. member this.P = "string" ----------------^ -stdin(772,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. +stdin(771,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. type public IBPublic = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^ -stdin(779,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(778,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. type internal IBInternal = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^^^ -stdin(784,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. +stdin(783,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. type public IBPublic = interface inherit IAInternal abstract Q : int end ------------------^^^^^^^^ -stdin(793,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(792,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. override x.M(a:string) = 1 -------------------^ -stdin(825,20): error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member Regression4232.D.M : 'U -> int' and 'abstract member Regression4232.D.M : 'T -> int' +stdin(824,20): error FS0361: The override 'M: string -> int' implements more than one abstract slot, e.g. 'abstract Regression4232.D.M: 'U -> int' and 'abstract Regression4232.D.M: 'T -> int' let (|A|B|) (x:int) = A x;; -----^^^^^ -stdin(833,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(832,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (x:'a) = A x;; -----^^^^^ -stdin(836,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(835,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (p:'a) (x:int) = A p;; -----^^^^^ -stdin(839,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(838,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) = failwith "" : Choice;; -----^^^^^ -stdin(845,6): error FS1209: Active pattern '|A|B|' is not a function +stdin(844,6): error FS1209: Active pattern '|A|B|' is not a function diff --git a/tests/fsharp/core/printing/z.output.test.1000.stdout.47.bsl b/tests/fsharp/core/printing/z.output.test.1000.stdout.47.bsl new file mode 100644 index 00000000000..ec6c7345481 --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.1000.stdout.47.bsl @@ -0,0 +1,2714 @@ + +> val it: unit = () + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; + System.Windows.Forms.Form, Text: fs #20; + System.Windows.Forms.Form, Text: fs #21; + System.Windows.Forms.Form, Text: fs #22; + System.Windows.Forms.Form, Text: fs #23; + System.Windows.Forms.Form, Text: fs #24; + System.Windows.Forms.Form, Text: fs #25; + System.Windows.Forms.Form, Text: fs #26; + System.Windows.Forms.Form, Text: fs #27; + System.Windows.Forms.Form, Text: fs #28; + System.Windows.Forms.Form, Text: fs #29; + System.Windows.Forms.Form, Text: fs #30; + System.Windows.Forms.Form, Text: fs #31; + System.Windows.Forms.Form, Text: fs #32; + System.Windows.Forms.Form, Text: fs #33; + System.Windows.Forms.Form, Text: fs #34; + System.Windows.Forms.Form, Text: fs #35; + System.Windows.Forms.Form, Text: fs #36; + System.Windows.Forms.Form, Text: fs #37; + System.Windows.Forms.Form, Text: fs #38; + System.Windows.Forms.Form, Text: fs #39; + System.Windows.Forms.Form, Text: fs #40; + System.Windows.Forms.Form, Text: fs #41; + System.Windows.Forms.Form, Text: fs #42; + System.Windows.Forms.Form, Text: fs #43; + System.Windows.Forms.Form, Text: fs #44; + System.Windows.Forms.Form, Text: fs #45; + System.Windows.Forms.Form, Text: fs #46; + System.Windows.Forms.Form, Text: fs #47; + System.Windows.Forms.Form, Text: fs #48; + System.Windows.Forms.Form, Text: fs #49; + System.Windows.Forms.Form, Text: fs #50; + System.Windows.Forms.Form, Text: fs #51; + System.Windows.Forms.Form, Text: fs #52; + System.Windows.Forms.Form, Text: fs #53; + System.Windows.Forms.Form, Text: fs #54; + System.Windows.Forms.Form, Text: fs #55; + System.Windows.Forms.Form, Text: fs #56; + System.Windows.Forms.Form, Text: fs #57; + System.Windows.Forms.Form, Text: fs #58; + System.Windows.Forms.Form, Text: fs #59; + System.Windows.Forms.Form, Text: fs #60; + System.Windows.Forms.Form, Text: fs #61; + System.Windows.Forms.Form, Text: fs #62; + System.Windows.Forms.Form, Text: fs #63; + System.Windows.Forms.Form, Text: fs #64; + System.Windows.Forms.Form, Text: fs #65; + System.Windows.Forms.Form, Text: fs #66; + System.Windows.Forms.Form, Text: fs #67; + System.Windows.Forms.Form, Text: fs #68; + System.Windows.Forms.Form, Text: fs #69; + System.Windows.Forms.Form, Text: fs #70; + System.Windows.Forms.Form, Text: fs #71; + System.Windows.Forms.Form, Text: fs #72; + System.Windows.Forms.Form, Text: fs #73; + System.Windows.Forms.Form, Text: fs #74; + System.Windows.Forms.Form, Text: fs #75; + System.Windows.Forms.Form, Text: fs #76; + System.Windows.Forms.Form, Text: fs #77; + System.Windows.Forms.Form, Text: fs #78; + System.Windows.Forms.Form, Text: fs #79; + System.Windows.Forms.Form, Text: fs #80; + System.Windows.Forms.Form, Text: fs #81; + System.Windows.Forms.Form, Text: fs #82; + System.Windows.Forms.Form, Text: fs #83; + System.Windows.Forms.Form, Text: fs #84; + System.Windows.Forms.Form, Text: fs #85; + System.Windows.Forms.Form, Text: fs #86; + System.Windows.Forms.Form, Text: fs #87; + System.Windows.Forms.Form, Text: fs #88; + System.Windows.Forms.Form, Text: fs #89; + System.Windows.Forms.Form, Text: fs #90; + System.Windows.Forms.Form, Text: fs #91; + System.Windows.Forms.Form, Text: fs #92; + System.Windows.Forms.Form, Text: fs #93; + System.Windows.Forms.Form, Text: fs #94; + System.Windows.Forms.Form, Text: fs #95; + System.Windows.Forms.Form, Text: fs #96; + System.Windows.Forms.Form, Text: fs #97; + System.Windows.Forms.Form, Text: fs #98; + System.Windows.Forms.Form, Text: fs #99; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; ...], ..., ...)) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some + (Some + (Some + (Some + (Some + [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; + 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; + 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------"; + "---------------------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------"; + "------------------------------------------------------"; + "-------------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------"; + "----------------------------------------------------------"; + "-----------------------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"; + "--------------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[12 chars]; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[18 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[22 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[28 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[36 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[38 chars]; + ...|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[310 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[352 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[366 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[380 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[408 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[422 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[436 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[450 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[478 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[492 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[506 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[520 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[548 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[562 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[576 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[590 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[618 chars]; + "-------------------------------------------------------------"+[625 chars]; + "-------------------------------------------------------------"+[632 chars]; + ...|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] + [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N ...; ...]; ...]; ...]; ...]; ...] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N ...; ...]; ...]; ...]; ...]; ...] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N ...; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; N ...; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; N [N [L; L; L; L; ...]; ...]; + ...] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)); Var 4; + Bop (5, Var 2, Bop (1, Var 0, Var 0)); Var 6; + Bop (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2); + Var 8; + Bop (9, Var 4, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))); + Var 10; + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop (11, ..., ...)), ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), + Var 2)))) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop (25507, ..., ...)))), ...))) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), ...), ...), ...)), + ...))), ...)))), ...), ...)) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop + (8388607, + Bop + (4194303, + Bop + (2097151, + Bop + (1048575, + Bop + (524287, + Bop + (262143, + Bop + (131071, + Bop + (65535, + Bop + (32767, + Bop + (16383, + Bop + (8191, + Bop + (4095, + Bop + (2047, + Bop + (1023, + Bop + (511, + Bop + (255, + Bop + (127, + Bop + (63, + Bop + (31, + Bop + (15, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2), + Bop + (5, + Var + 2, + Bop + (1, + Var + 0, + Var + 0))), + Var + 10), + Bop + (21, + Var + 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + ...), + ...))), + ...), + ...), + ...), + ...), + ...), ...), + ...), ...), ...), + ...), ...), ...), ...), + ...), ...), ...), ...), ...), ...), + ...), ...), ...), ...), ...), ...) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; ...|] +val r10s': string * r[] = + ("one extra node", + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = ... }; ...|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0107+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.1000.stdout.50.bsl b/tests/fsharp/core/printing/z.output.test.1000.stdout.50.bsl new file mode 100644 index 00000000000..a745431f238 --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.1000.stdout.50.bsl @@ -0,0 +1,2716 @@ + +> val it: unit = () + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; + System.Windows.Forms.Form, Text: fs #20; + System.Windows.Forms.Form, Text: fs #21; + System.Windows.Forms.Form, Text: fs #22; + System.Windows.Forms.Form, Text: fs #23; + System.Windows.Forms.Form, Text: fs #24; + System.Windows.Forms.Form, Text: fs #25; + System.Windows.Forms.Form, Text: fs #26; + System.Windows.Forms.Form, Text: fs #27; + System.Windows.Forms.Form, Text: fs #28; + System.Windows.Forms.Form, Text: fs #29; + System.Windows.Forms.Form, Text: fs #30; + System.Windows.Forms.Form, Text: fs #31; + System.Windows.Forms.Form, Text: fs #32; + System.Windows.Forms.Form, Text: fs #33; + System.Windows.Forms.Form, Text: fs #34; + System.Windows.Forms.Form, Text: fs #35; + System.Windows.Forms.Form, Text: fs #36; + System.Windows.Forms.Form, Text: fs #37; + System.Windows.Forms.Form, Text: fs #38; + System.Windows.Forms.Form, Text: fs #39; + System.Windows.Forms.Form, Text: fs #40; + System.Windows.Forms.Form, Text: fs #41; + System.Windows.Forms.Form, Text: fs #42; + System.Windows.Forms.Form, Text: fs #43; + System.Windows.Forms.Form, Text: fs #44; + System.Windows.Forms.Form, Text: fs #45; + System.Windows.Forms.Form, Text: fs #46; + System.Windows.Forms.Form, Text: fs #47; + System.Windows.Forms.Form, Text: fs #48; + System.Windows.Forms.Form, Text: fs #49; + System.Windows.Forms.Form, Text: fs #50; + System.Windows.Forms.Form, Text: fs #51; + System.Windows.Forms.Form, Text: fs #52; + System.Windows.Forms.Form, Text: fs #53; + System.Windows.Forms.Form, Text: fs #54; + System.Windows.Forms.Form, Text: fs #55; + System.Windows.Forms.Form, Text: fs #56; + System.Windows.Forms.Form, Text: fs #57; + System.Windows.Forms.Form, Text: fs #58; + System.Windows.Forms.Form, Text: fs #59; + System.Windows.Forms.Form, Text: fs #60; + System.Windows.Forms.Form, Text: fs #61; + System.Windows.Forms.Form, Text: fs #62; + System.Windows.Forms.Form, Text: fs #63; + System.Windows.Forms.Form, Text: fs #64; + System.Windows.Forms.Form, Text: fs #65; + System.Windows.Forms.Form, Text: fs #66; + System.Windows.Forms.Form, Text: fs #67; + System.Windows.Forms.Form, Text: fs #68; + System.Windows.Forms.Form, Text: fs #69; + System.Windows.Forms.Form, Text: fs #70; + System.Windows.Forms.Form, Text: fs #71; + System.Windows.Forms.Form, Text: fs #72; + System.Windows.Forms.Form, Text: fs #73; + System.Windows.Forms.Form, Text: fs #74; + System.Windows.Forms.Form, Text: fs #75; + System.Windows.Forms.Form, Text: fs #76; + System.Windows.Forms.Form, Text: fs #77; + System.Windows.Forms.Form, Text: fs #78; + System.Windows.Forms.Form, Text: fs #79; + System.Windows.Forms.Form, Text: fs #80; + System.Windows.Forms.Form, Text: fs #81; + System.Windows.Forms.Form, Text: fs #82; + System.Windows.Forms.Form, Text: fs #83; + System.Windows.Forms.Form, Text: fs #84; + System.Windows.Forms.Form, Text: fs #85; + System.Windows.Forms.Form, Text: fs #86; + System.Windows.Forms.Form, Text: fs #87; + System.Windows.Forms.Form, Text: fs #88; + System.Windows.Forms.Form, Text: fs #89; + System.Windows.Forms.Form, Text: fs #90; + System.Windows.Forms.Form, Text: fs #91; + System.Windows.Forms.Form, Text: fs #92; + System.Windows.Forms.Form, Text: fs #93; + System.Windows.Forms.Form, Text: fs #94; + System.Windows.Forms.Form, Text: fs #95; + System.Windows.Forms.Form, Text: fs #96; + System.Windows.Forms.Form, Text: fs #97; + System.Windows.Forms.Form, Text: fs #98; + System.Windows.Forms.Form, Text: fs #99; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; ...], ..., ...)) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some + (Some + (Some + (Some + (Some + [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; + 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; + 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------"; + "---------------------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------"; + "------------------------------------------------------"; + "-------------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------"; + "----------------------------------------------------------"; + "-----------------------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"; + "--------------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[12 chars]; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[18 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[22 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[28 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[36 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[38 chars]; + ...|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[310 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[352 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[366 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[380 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[408 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[422 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[436 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[450 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[478 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[492 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[506 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[520 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[548 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[562 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[576 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[590 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[618 chars]; + "-------------------------------------------------------------"+[625 chars]; + "-------------------------------------------------------------"+[632 chars]; + ...|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] + [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N ...; ...]; ...]; ...]; ...]; ...] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N ...; ...]; ...]; ...]; ...]; ...] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N ...; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; N ...; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; N [N [L; L; L; L; ...]; ...]; + ...] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)); Var 4; + Bop (5, Var 2, Bop (1, Var 0, Var 0)); Var 6; + Bop (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2); + Var 8; + Bop (9, Var 4, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))); + Var 10; + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop (11, ..., ...)), ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), + Var 2)))) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop (25507, ..., ...)))), ...))) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), ...), ...), ...)), + ...))), ...)))), ...), ...)) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop + (8388607, + Bop + (4194303, + Bop + (2097151, + Bop + (1048575, + Bop + (524287, + Bop + (262143, + Bop + (131071, + Bop + (65535, + Bop + (32767, + Bop + (16383, + Bop + (8191, + Bop + (4095, + Bop + (2047, + Bop + (1023, + Bop + (511, + Bop + (255, + Bop + (127, + Bop + (63, + Bop + (31, + Bop + (15, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2), + Bop + (5, + Var + 2, + Bop + (1, + Var + 0, + Var + 0))), + Var + 10), + Bop + (21, + Var + 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + ...), + ...))), + ...), + ...), + ...), + ...), + ...), ...), + ...), ...), ...), + ...), ...), ...), ...), + ...), ...), ...), ...), ...), ...), + ...), ...), ...), ...), ...), ...) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #r "nuget:FSharp.Data, 3.1.2";; // Load Nuget Package 'FSharp.Data' version '3.1.2' + #r "nuget:FSharp.Data";; // Load Nuget Package 'FSharp.Data' with the highest version + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; ...|] +val r10s': string * r[] = + ("one extra node", + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = ... }; ...|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0107+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl b/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl deleted file mode 100644 index 52c96dd7598..00000000000 --- a/tests/fsharp/core/printing/z.output.test.1000.stdout.bsl +++ /dev/null @@ -1,2742 +0,0 @@ - -> val it : unit = () - -> > val repeatId : string = "A" - -> val repeatId : string = "B" - -namespace FSI_0005 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -> val x1 : seq -val x2 : seq -val x3 : seq -val f1 : System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form -val fs : System.Windows.Forms.Form [] = - [|System.Windows.Forms.Form, Text: fs #0; - System.Windows.Forms.Form, Text: fs #1; - System.Windows.Forms.Form, Text: fs #2; - System.Windows.Forms.Form, Text: fs #3; - System.Windows.Forms.Form, Text: fs #4; - System.Windows.Forms.Form, Text: fs #5; - System.Windows.Forms.Form, Text: fs #6; - System.Windows.Forms.Form, Text: fs #7; - System.Windows.Forms.Form, Text: fs #8; - System.Windows.Forms.Form, Text: fs #9; - System.Windows.Forms.Form, Text: fs #10; - System.Windows.Forms.Form, Text: fs #11; - System.Windows.Forms.Form, Text: fs #12; - System.Windows.Forms.Form, Text: fs #13; - System.Windows.Forms.Form, Text: fs #14; - System.Windows.Forms.Form, Text: fs #15; - System.Windows.Forms.Form, Text: fs #16; - System.Windows.Forms.Form, Text: fs #17; - System.Windows.Forms.Form, Text: fs #18; - System.Windows.Forms.Form, Text: fs #19; - System.Windows.Forms.Form, Text: fs #20; - System.Windows.Forms.Form, Text: fs #21; - System.Windows.Forms.Form, Text: fs #22; - System.Windows.Forms.Form, Text: fs #23; - System.Windows.Forms.Form, Text: fs #24; - System.Windows.Forms.Form, Text: fs #25; - System.Windows.Forms.Form, Text: fs #26; - System.Windows.Forms.Form, Text: fs #27; - System.Windows.Forms.Form, Text: fs #28; - System.Windows.Forms.Form, Text: fs #29; - System.Windows.Forms.Form, Text: fs #30; - System.Windows.Forms.Form, Text: fs #31; - System.Windows.Forms.Form, Text: fs #32; - System.Windows.Forms.Form, Text: fs #33; - System.Windows.Forms.Form, Text: fs #34; - System.Windows.Forms.Form, Text: fs #35; - System.Windows.Forms.Form, Text: fs #36; - System.Windows.Forms.Form, Text: fs #37; - System.Windows.Forms.Form, Text: fs #38; - System.Windows.Forms.Form, Text: fs #39; - System.Windows.Forms.Form, Text: fs #40; - System.Windows.Forms.Form, Text: fs #41; - System.Windows.Forms.Form, Text: fs #42; - System.Windows.Forms.Form, Text: fs #43; - System.Windows.Forms.Form, Text: fs #44; - System.Windows.Forms.Form, Text: fs #45; - System.Windows.Forms.Form, Text: fs #46; - System.Windows.Forms.Form, Text: fs #47; - System.Windows.Forms.Form, Text: fs #48; - System.Windows.Forms.Form, Text: fs #49; - System.Windows.Forms.Form, Text: fs #50; - System.Windows.Forms.Form, Text: fs #51; - System.Windows.Forms.Form, Text: fs #52; - System.Windows.Forms.Form, Text: fs #53; - System.Windows.Forms.Form, Text: fs #54; - System.Windows.Forms.Form, Text: fs #55; - System.Windows.Forms.Form, Text: fs #56; - System.Windows.Forms.Form, Text: fs #57; - System.Windows.Forms.Form, Text: fs #58; - System.Windows.Forms.Form, Text: fs #59; - System.Windows.Forms.Form, Text: fs #60; - System.Windows.Forms.Form, Text: fs #61; - System.Windows.Forms.Form, Text: fs #62; - System.Windows.Forms.Form, Text: fs #63; - System.Windows.Forms.Form, Text: fs #64; - System.Windows.Forms.Form, Text: fs #65; - System.Windows.Forms.Form, Text: fs #66; - System.Windows.Forms.Form, Text: fs #67; - System.Windows.Forms.Form, Text: fs #68; - System.Windows.Forms.Form, Text: fs #69; - System.Windows.Forms.Form, Text: fs #70; - System.Windows.Forms.Form, Text: fs #71; - System.Windows.Forms.Form, Text: fs #72; - System.Windows.Forms.Form, Text: fs #73; - System.Windows.Forms.Form, Text: fs #74; - System.Windows.Forms.Form, Text: fs #75; - System.Windows.Forms.Form, Text: fs #76; - System.Windows.Forms.Form, Text: fs #77; - System.Windows.Forms.Form, Text: fs #78; - System.Windows.Forms.Form, Text: fs #79; - System.Windows.Forms.Form, Text: fs #80; - System.Windows.Forms.Form, Text: fs #81; - System.Windows.Forms.Form, Text: fs #82; - System.Windows.Forms.Form, Text: fs #83; - System.Windows.Forms.Form, Text: fs #84; - System.Windows.Forms.Form, Text: fs #85; - System.Windows.Forms.Form, Text: fs #86; - System.Windows.Forms.Form, Text: fs #87; - System.Windows.Forms.Form, Text: fs #88; - System.Windows.Forms.Form, Text: fs #89; - System.Windows.Forms.Form, Text: fs #90; - System.Windows.Forms.Form, Text: fs #91; - System.Windows.Forms.Form, Text: fs #92; - System.Windows.Forms.Form, Text: fs #93; - System.Windows.Forms.Form, Text: fs #94; - System.Windows.Forms.Form, Text: fs #95; - System.Windows.Forms.Form, Text: fs #96; - System.Windows.Forms.Form, Text: fs #97; - System.Windows.Forms.Form, Text: fs #98; - System.Windows.Forms.Form, Text: fs #99; ...|] -val xs : string list = - ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; - "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; - "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; - "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; - "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; - "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; - "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; - "98"; "99"; ...] -val xa : string [] = - [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; - "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; - "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; - "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; - "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; - "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; - "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; - "98"; "99"; ...|] -val xa2 : string [,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] - ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] - ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] - ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] - ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] - ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] - ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] - ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] -val sxs0 : Set = set [] - -> val sxs1 : Set = set ["0"] - -> val sxs2 : Set = set ["0"; "1"] - -> val sxs3 : Set = set ["0"; "1"; "2"] - -> val sxs4 : Set = set ["0"; "1"; "2"; "3"] - -> val sxs200 : Set = - set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] - -> val msxs0 : Map = map [] - -> val msxs1 : Map = map [(0, "0")] - -> val msxs2 : Map = map [(0, "0"); (1, "1")] - -> val msxs3 : Map = map [(0, "0"); (1, "1"); (2, "2")] - -> val msxs4 : Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] - -> val msxs200 : Map = - map - [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); - (7, "7"); (8, "8"); ...] - -> module M = begin - val a : string = "sub-binding" - val b : - (seq * seq * seq * System.Windows.Forms.Form) option * - (string list * string list * string [,]) option = - (Some (, , , System.Windows.Forms.Form, Text: f1 form), - Some - (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; - "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; - "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; - "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; - "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; - "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; - "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; - "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; - "90"; "91"; "92"; "93"; "94"; "95"; "96"; ...], ..., ...)) -end -type T = - class - new : a:int * b:int -> T - member AMethod : x:int -> int - member AProperty : int - static member StaticMethod : x:int -> int - static member StaticProperty : int - end -val f_as_method : x:int -> int -val f_as_thunk : (int -> int) -val refCell : string ref = { contents = "value" } -module D1 = begin - val words : System.Collections.Generic.IDictionary - val words2000 : System.Collections.Generic.IDictionary -end - -> > module D2 = begin - val words : IDictionary - val words2000 : IDictionary -end -val opt1 : 'a option -val opt1b : int option = None -val opt4 : 'a option option option option -val opt4b : int option option option option = Some (Some (Some None)) -val opt5 : int list option option option option option list = - [Some (Some (Some (Some None))); - Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); - Some - (Some - (Some - (Some - (Some - [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; - 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; - 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] -val mkStr : n:int -> string -val strs : string [] = - [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; - "---------"; "----------"; "-----------"; "------------"; "-------------"; - "--------------"; "---------------"; "----------------"; - "-----------------"; "------------------"; "-------------------"; - "--------------------"; "---------------------"; "----------------------"; - "-----------------------"; "------------------------"; - "-------------------------"; "--------------------------"; - "---------------------------"; "----------------------------"; - "-----------------------------"; "------------------------------"; - "-------------------------------"; "--------------------------------"; - "---------------------------------"; "----------------------------------"; - "-----------------------------------"; - "------------------------------------"; - "-------------------------------------"; - "--------------------------------------"; - "---------------------------------------"; - "----------------------------------------"; - "-----------------------------------------"; - "------------------------------------------"; - "-------------------------------------------"; - "--------------------------------------------"; - "---------------------------------------------"; - "----------------------------------------------"; - "-----------------------------------------------"; - "------------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------"; - "---------------------------------------------------"; - "----------------------------------------------------"; - "-----------------------------------------------------"; - "------------------------------------------------------"; - "-------------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------"; - "----------------------------------------------------------"; - "-----------------------------------------------------------"; - "------------------------------------------------------------"; - "-------------------------------------------------------------"; - "--------------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------"; - "-----------------------------------------------------------------"; - "------------------------------------------------------------------"; - "-------------------------------------------------------------------"; - "--------------------------------------------------------------------"; - "---------------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-----------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[12 chars]; - "-------------------------------------------------------------"+[13 chars]; - "-------------------------------------------------------------"+[14 chars]; - "-------------------------------------------------------------"+[15 chars]; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[18 chars]; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[20 chars]; - "-------------------------------------------------------------"+[21 chars]; - "-------------------------------------------------------------"+[22 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[24 chars]; - "-------------------------------------------------------------"+[25 chars]; - "-------------------------------------------------------------"+[26 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[28 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[31 chars]; - "-------------------------------------------------------------"+[32 chars]; - "-------------------------------------------------------------"+[33 chars]; - "-------------------------------------------------------------"+[34 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[36 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[38 chars]; - ...|] -val str7s : string [] = - [|""; "-------"; "--------------"; "---------------------"; - "----------------------------"; "-----------------------------------"; - "------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[58 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[72 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[86 chars]; - "-------------------------------------------------------------"+[93 chars]; - "-------------------------------------------------------------"+[100 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[114 chars]; - "-------------------------------------------------------------"+[121 chars]; - "-------------------------------------------------------------"+[128 chars]; - "-------------------------------------------------------------"+[135 chars]; - "-------------------------------------------------------------"+[142 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[156 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[170 chars]; - "-------------------------------------------------------------"+[177 chars]; - "-------------------------------------------------------------"+[184 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[198 chars]; - "-------------------------------------------------------------"+[205 chars]; - "-------------------------------------------------------------"+[212 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[226 chars]; - "-------------------------------------------------------------"+[233 chars]; - "-------------------------------------------------------------"+[240 chars]; - "-------------------------------------------------------------"+[247 chars]; - "-------------------------------------------------------------"+[254 chars]; - "-------------------------------------------------------------"+[261 chars]; - "-------------------------------------------------------------"+[268 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[282 chars]; - "-------------------------------------------------------------"+[289 chars]; - "-------------------------------------------------------------"+[296 chars]; - "-------------------------------------------------------------"+[303 chars]; - "-------------------------------------------------------------"+[310 chars]; - "-------------------------------------------------------------"+[317 chars]; - "-------------------------------------------------------------"+[324 chars]; - "-------------------------------------------------------------"+[331 chars]; - "-------------------------------------------------------------"+[338 chars]; - "-------------------------------------------------------------"+[345 chars]; - "-------------------------------------------------------------"+[352 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[366 chars]; - "-------------------------------------------------------------"+[373 chars]; - "-------------------------------------------------------------"+[380 chars]; - "-------------------------------------------------------------"+[387 chars]; - "-------------------------------------------------------------"+[394 chars]; - "-------------------------------------------------------------"+[401 chars]; - "-------------------------------------------------------------"+[408 chars]; - "-------------------------------------------------------------"+[415 chars]; - "-------------------------------------------------------------"+[422 chars]; - "-------------------------------------------------------------"+[429 chars]; - "-------------------------------------------------------------"+[436 chars]; - "-------------------------------------------------------------"+[443 chars]; - "-------------------------------------------------------------"+[450 chars]; - "-------------------------------------------------------------"+[457 chars]; - "-------------------------------------------------------------"+[464 chars]; - "-------------------------------------------------------------"+[471 chars]; - "-------------------------------------------------------------"+[478 chars]; - "-------------------------------------------------------------"+[485 chars]; - "-------------------------------------------------------------"+[492 chars]; - "-------------------------------------------------------------"+[499 chars]; - "-------------------------------------------------------------"+[506 chars]; - "-------------------------------------------------------------"+[513 chars]; - "-------------------------------------------------------------"+[520 chars]; - "-------------------------------------------------------------"+[527 chars]; - "-------------------------------------------------------------"+[534 chars]; - "-------------------------------------------------------------"+[541 chars]; - "-------------------------------------------------------------"+[548 chars]; - "-------------------------------------------------------------"+[555 chars]; - "-------------------------------------------------------------"+[562 chars]; - "-------------------------------------------------------------"+[569 chars]; - "-------------------------------------------------------------"+[576 chars]; - "-------------------------------------------------------------"+[583 chars]; - "-------------------------------------------------------------"+[590 chars]; - "-------------------------------------------------------------"+[597 chars]; - "-------------------------------------------------------------"+[604 chars]; - "-------------------------------------------------------------"+[611 chars]; - "-------------------------------------------------------------"+[618 chars]; - "-------------------------------------------------------------"+[625 chars]; - "-------------------------------------------------------------"+[632 chars]; - ...|] -val grids : string [,] = - [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; - ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; - ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] - [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; - "---------"; "----------"; "-----------"; "------------"; "-------------"; - "--------------"; "---------------"; "----------------"; - "-----------------"; "------------------"; "-------------------"; - "--------------------"; "---------------------"; "----------------------"; - "-----------------------"; "------------------------"; - "-------------------------"; "--------------------------"; - "---------------------------"; "----------------------------"; - "-----------------------------"; "------------------------------"; - "-------------------------------"; "--------------------------------"; - "---------------------------------"; "----------------------------------"; - "-----------------------------------"; - "------------------------------------"; - "-------------------------------------"; - "--------------------------------------"; - "---------------------------------------"; - "----------------------------------------"; - "-----------------------------------------"; - "------------------------------------------"; - "-------------------------------------------"; - "--------------------------------------------"; - "---------------------------------------------"; - "----------------------------------------------"; - "-----------------------------------------------"; - "------------------------------------------------"; - "-------------------------------------------------"; ...] - ...] - -> type tree = - | L - | N of tree list -val mkT : w:int -> d:int -> tree -val tree : w:int -> d:int -> tree - -> [Building 2 4...done] -val tree_2_4 : tree = - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] - -> [Building 2 6...done] -val tree_2_6 : tree = - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N ...; ...]; ...]; ...]; ...]; ...] - -> [Building 2 8...done] -val tree_2_8 : tree = - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N ...; ...]; ...]; ...]; ...]; ...] - -> [Building 2 10...done] -val tree_2_10 : tree = - N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...] - -> [Building 2 12...done] -val tree_2_12 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N ...; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 2 14...done] -val tree_2_14 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; - ...] - -> [Building 3 8...done] -val tree_3_8 : tree = - N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; - ...]; ...]; ...]; ...]; ...] - -> [Building 4 8...done] -val tree_4_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...] - -> [Building 5 8...done] -val tree_5_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; N ...; ...]; ...]; - ...]; ...]; ...]; ...] - -> [Building 6 8...done] -val tree_6_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L; ...]; ...]; ...]; ...]; ...]; ...]; - ...]; ...] - -> [Building 5 3...done] -val tree_5_3 : tree = - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; N [N [L; L; L; L; ...]; ...]; - ...] - -> > type X = - | Var of int - | Bop of int * X * X -val generate : x:int -> X - -> val exps : X list = - [Bop (1,Var 0,Var 0); Var 2; Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)); - Var 4; Bop (5,Var 2,Bop (1,Var 0,Var 0)); Var 6; - Bop (7,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)),Var 2); Var 8; - Bop (9,Var 4,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0))); Var 10; - Bop - (213,Var 106, - Bop - (71, - Bop - (35,Bop (17,Var 8,Bop (5,Var 2,Bop (1,Var 0,Var 0))), - Bop (11,...,...)),...)); ...] - -> module Exprs = begin - val x1 : X = - Bop - (213,Var 106, - Bop - (71, - Bop - (35,Bop (17,Var 8,Bop (5,Var 2,Bop (1,Var 0,Var 0))), - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)))), - Bop - (23, - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0))), - Bop (7,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)),Var 2)))) - val x2 : X = Var 21342314 - val x3 : X = Var 3214 - val x4 : X = Bop (1231357,Var 615678,Var 410452) - val x5 : X = - Bop - (5234547,Bop (2617273,Var 1308636,Var 872424), - Bop (1744849,Var 872424,Var 581616)) - val x6 : X = - Bop (923759825,Var 461879912,Bop (307919941,Var 153959970,Var 102639980)) - val x7 : X = Var 2435234 - val x8 : X = - Bop - (12396777,Var 6198388, - Bop - (4132259, - Bop - (2066129,Var 1033064, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502))))), - Bop - (1377419, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop (25507,...,...)))),...))) - val x9 : X = - Bop - (3333333,Var 1666666, - Bop - (1111111, - Bop - (555555,Bop (277777,Var 138888,Var 92592), - Bop (185185,Var 92592,Var 61728)),Var 370370)) - val x10 : X = - Bop - (1312311237,Var 656155618, - Bop - (437437079, - Bop - (218718539, - Bop - (109359269,Var 54679634, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562),...),...),...)),...))), - ...)))),...),...)) - val x11 : X = - Bop - (2147483647, - Bop - (1073741823, - Bop - (536870911, - Bop - (268435455, - Bop - (134217727, - Bop - (67108863, - Bop - (33554431, - Bop - (16777215, - Bop - (8388607, - Bop - (4194303, - Bop - (2097151, - Bop - (1048575, - Bop - (524287, - Bop - (262143, - Bop - (131071, - Bop - (65535, - Bop - (32767, - Bop - (16383, - Bop - (8191, - Bop - (4095, - Bop - (2047, - Bop - (1023, - Bop - (511, - Bop - (255, - Bop - (127, - Bop - (63, - Bop - (31, - Bop - (15, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var - 2), - Bop - (5, - Var - 2, - Bop - (1, - Var - 0, - Var - 0))), - Var - 10), - Bop - (21, - Var - 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - ...), - ...))), - ...), - ...), - ...), - ...),...), - ...),...),...), - ...),...),...),...),...), - ...),...),...),...),...),...),...),...), - ...),...),...),...) -end - -> type C = - class - new : x:string -> C - override ToString : unit -> string - end -val c1 : C = -val csA : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csB : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csC : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] - -> exception Abc - -> exception AbcInt of int - -> exception AbcString of string - -> exception AbcExn of exn list - -> exception AbcException of System.Exception list - -> val exA1 : exn = Abc -val exA2 : exn = AbcInt 2 -val exA3 : exn = AbcString "3" -val exA4 : exn = AbcExn [Abc; AbcInt 2; AbcString "3"] -val exA5 : exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] -exception Ex0 -exception ExUnit of unit -exception ExUnits of unit * unit -exception ExUnitOption of unit option -val ex0 : exn = Ex0 -val exU : exn = ExUnit () -val exUs : exn = ExUnits ((),()) -val exUSome : exn = ExUnitOption (Some ()) -val exUNone : exn = ExUnitOption None -type 'a T4063 = | AT4063 of 'a - -> val valAT3063_12 : int T4063 = AT4063 12 - -> val valAT3063_True : bool T4063 = AT4063 true - -> val valAT3063_text : string T4063 = AT4063 "text" - -> val valAT3063_null : System.Object T4063 = AT4063 null - -> type M4063<'a> = - class - new : x:'a -> M4063<'a> - end - -> val v4063 : M4063 - -> type Taaaaa<'a> = - class - new : unit -> Taaaaa<'a> - end - -> type Taaaaa2<'a> = - class - inherit Taaaaa<'a> - new : unit -> Taaaaa2<'a> - member M : unit -> Taaaaa2<'a> - end - -> type Tbbbbb<'a> = - class - new : x:'a -> Tbbbbb<'a> - member M : unit -> 'a - end - -> type Tbbbbb2 = - class - inherit Tbbbbb - new : x:string -> Tbbbbb2 - end - -> val it : (unit -> string) = - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> val it : string = "Check #help" - -> - F# Interactive directives: - - #r "file.dll";; Reference (dynamically load) the given DLL - #I "path";; Add the given search path for referenced DLLs - #load "file.fs" ...;; Load the given file(s) as if compiled and referenced - #time ["on"|"off"];; Toggle timing on/off - #help;; Display help - #quit;; Exit - - F# Interactive command line options: - - - -> val it : string = "Check #time on and then off" - -> ---> Timing now on - -> ---> Timing now off - -> val it : string = "Check #unknown command" - -> Invalid directive '#blaaaaaa ' -> val it : string = - "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" - -> ---> Added '/' to library include path - -> type internal T1 = - | A - | B - -> type internal T2 = - { x: int } - -> type internal T3 - -> type internal T4 = - class - new : unit -> T4 - end - -> type T1 = - internal | A - | B - -> type T2 = - internal { x: int } - -> type private T1 = - | A - | B - -> type private T2 = - { x: int } - -> type T1 = - private | A - | B - -> type T2 = - private { x: int } - -> type internal T1 = - private | A - | B - -> type internal T2 = - private { x: int } - -> type private T3 - -> type private T4 = - class - new : unit -> T4 - end - -> exception X1 of int - -> exception private X2 of int - -> exception internal X3 of int - -> type T0 = - class - new : unit -> T0 - end -type T1Post<'a> = - class - new : unit -> T1Post<'a> - end -type 'a T1Pre = - class - new : unit -> 'a T1Pre - end - -> type T0 with - member M : unit -> T0 list -type T0 with - member P : T0 * T0 -type T0 with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type r = - { f0: int - f1: int - f2: int - f3: int - f4: int - f5: int - f6: int - f7: int - f8: int - f9: int } -val r10 : r = { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 } -val r10s : r [] = - [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; ...|] -val r10s' : string * r [] = - ("one extra node", - [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = ... }; ...|]) - -> val x1564_A1 : int = 1 - - ---> Added '\' to library include path - -val x1564_A2 : int = 2 - - ---> Added '\' to library include path - -val x1564_A3 : int = 3 - -> type internal Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - -> module internal InternalM = begin - val x : int = 1 - type Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - type private Foo3 = - class - new : unit -> Foo3 - new : x:int -> Foo3 - new : x:int * y:int -> Foo3 - new : x:int * y:int * z:int -> Foo3 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end -module internal PrivateM = begin - val private x : int = 1 - type private Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end - -> val it : seq = - seq - [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); - (58, "2/10/2009", 1)] - -> module Test4343a = begin - val mk : i:int -> string - val x100 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] - val x90 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] - val x80 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] - val x75 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] - val x74 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] - val x73 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] - val x72 : string = - "012345678901234567890123456789012345678901234567890123456789012345678901" - val x71 : string = - "01234567890123456789012345678901234567890123456789012345678901234567890" - val x70 : string = - "0123456789012345678901234567890123456789012345678901234567890123456789" -end -module Test4343b = begin - val fA : x:int -> int - val fB : x:'a -> y:'a -> 'a list - val gA : (int -> int) - val gB : ('a -> 'a -> 'a list) - val gAB : (int -> int) * ('a -> 'a -> 'a list) - val hB : ('a -> 'a -> 'a list) - val hA : (int -> int) -end -module Test4343c = begin - val typename<'a> : string - val typename2<'a> : string * string -end -module Test4343d = begin - val xList : int list = [1; 2; 3] - val xArray : int [] = [|1; 2; 3|] - val xString : string = "abcdef" - val xOption : int option = Some 12 - val xArray2 : (int * int) [,] = [[(0, 0); (0, 1)] - [(1, 0); (1, 1)]] - val xSeq : seq -end -module Test4343e = begin - type C = - class - new : x:int -> C - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, - [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) - type D = - class - new : x:int -> D - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - module Generic = begin - type CGeneric<'a> = - class - new : x:'a -> CGeneric<'a> - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, - [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) - type D<'a> = - class - new : x:'a -> D<'a> - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - val dC : D = D(True) - val boxed_dABC : obj list = [D(1); D(2); D(True)] - end -end -type F1 = - class - inherit System.Windows.Forms.Form - interface System.IDisposable - val x: F1 - val x2: F1 - abstract member MMM : bool -> bool - abstract member AAA : int - abstract member ZZZ : int - abstract member BBB : bool with set - member B : unit -> int - member D : unit -> int - member D : x:int -> int - member D : x:int * y:int -> int - override ToString : unit -> string - member D2 : int - member E : int - member D2 : int with set - member E : int with set - static val mutable private sx: F1 - static val mutable private sx2: F1 - static member A : unit -> int - static member C : unit -> int - end -type IP = - struct - new : x:int * y:int -> IP - static val mutable private AA: IP - end -module Regression4643 = begin - type RIP = - struct - new : x:int -> RIP - static val mutable private y: RIP - end - type arg_unused_is_RIP = - struct - new : x:RIP -> arg_unused_is_RIP - end - type arg_used_is_RIP = - struct - new : x:RIP -> arg_used_is_RIP - member X : RIP - end - type field_is_RIP = - struct - val x: RIP - end -end -type Either<'a,'b> = - | This of 'a - | That of 'b -val catch : f:(unit -> 'a) -> Either<'a,(string * string)> -val seqFindIndexFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqFindFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqPickFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -module Regression5218 = begin - val t1 : int = 1 - val t2 : int * int = (1, 2) - val t3 : int * int * int = (1, 2, 3) - val t4 : int * int * int * int = (1, 2, 3, 4) - val t5 : int * int * int * int * int = (1, 2, 3, 4, 5) - val t6 : int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) - val t7 : int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) - val t8 : int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8) - val t9 : int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9) - val t10 : int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val t11 : int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - val t12 : - int * int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) - val t13 : - int * int * int * int * int * int * int * int * int * int * int * int * - int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) - val t14 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) - val t15 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3740 = begin - type Writer<'a> = - interface - abstract member get_path : unit -> string - end - type MyClass = - class - interface Writer - val path: string - end -end - -> type Regression4319_T2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> string - end - -> type Regression4319_T0 = - class - static member ( +-+-+ ) : string - end - -> type Regression4319_T1 = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1b = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1c = - class - static member ( +-+-+ ) : x:('a * 'b) -> string - end - -> type Regression4319_T1d = - class - static member ( +-+-+ ) : x:(int * int) -> string - end - -> type Regression4319_T3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> string - end - -> type Regression4319_U1 = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U1b = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> moreArgs:'c -> string - end - -> type Regression4319_U3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> moreArgs:'d -> string - end - -> type Regression4319_check = - class - static member ( & ) : string - static member ( &^ ) : string - static member ( @ ) : string - static member ( != ) : string - static member ( := ) : string - static member ( ^ ) : string - static member ( / ) : string - static member ( $ ) : string - static member ( ...@ ) : string - static member ( ...!= ) : string - static member ( .../ ) : string - static member ( ...= ) : string - static member ( ...> ) : string - static member ( ...^ ) : string - static member ( ...< ) : string - static member ( ...* ) : string - static member ( ...% ) : string - static member ( = ) : string - static member ( ** ) : string - static member ( > ) : string - static member ( < ) : string - static member ( % ) : string - static member ( * ) : string - static member ( - ) : string - end - -> Expect ABC = ABC -type Regression4469 = - class - new : unit -> Regression4469 - member ToString : unit -> string - end -val r4469 : Regression4469 = FSI_0107+Regression4469 -val it : unit = () - -> Expect ABC = ABC -val it : unit = () - -> module Regression1019_short = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end -module Regression1019_long = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end - -> val it : int ref = { contents = 1 } - -> val x : int ref = { contents = 1 } -val f : (unit -> int) - -> val it : int = 1 - -> val it : unit = () - -> val it : int = 3 - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : 'a list - -> val it : 'a list list - -> val it : 'a option - -> val it : 'a list * 'b list - -> val it : x:'a -> 'a - -> val fff : x:'a -> 'a - -> val it : ('a -> 'a) - -> val note_ExpectDupMethod : string = - "Regression4927: Expect error due to duplicate methods in the "+[20 chars] - -> > val note_ExpectDupProperty : string = - "Regression4927: Expect error due to duplicate properties in t"+[23 chars] - -> > > val it : string = "NOTE: Expect IAPrivate less accessible IBPublic" - -> > val it : string = "NOTE: Expect IAPrivate less accessible IBInternal" - -> > module Regression5265_PriPri = begin - type private IAPrivate = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPrivate - abstract member Q : int - end -end - -> val it : string = "NOTE: Expect IAInternal less accessible IBPublic" - -> > module Regression5265_IntInt = begin - type internal IAInternal = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_IntPri = begin - type internal IAInternal = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_PubPub = begin - type IAPublic = - interface - abstract member P : int - end - type IBPublic = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubInt = begin - type IAPublic = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubPri = begin - type IAPublic = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPublic - abstract member Q : int - end -end - -> val it : string = - "Regression4232: Expect an error about duplicate virtual methods from parent type" - -> > val it : string = - "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" - -> type AnAxHostSubClass = - class - inherit System.Windows.Forms.AxHost - new : x:string -> AnAxHostSubClass - end - -> val it : string = - "** Expect error because the active pattern result contains free type variables" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (match value generic)" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" - -> > val it : string = - "** Expect OK, since error message says constraint should work!" - -> val ( |A|B| ) : x:int -> Choice - -> val it : string = "** Expect error since active pattern is not a function!" - -> > val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on match val" - -> val ( |A|B| ) : p:bool -> 'a * 'b -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on parameters" - -> val ( |A|B| ) : aval:'a -> bval:'b -> x:bool -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is generic, but it typar from closure, so OK" - -> val outer : x:'a -> (int -> 'a option) - -> val it : string = - "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" - -> val ( |Check1| ) : a:int -> int * 'a option - -> > module ReflectionEmit = begin - type IA = - interface - abstract member M : #IB -> int - end - and IB = - interface - abstract member M : #IA -> int - end - type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = - interface - abstract member M : int - end - and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = - interface - abstract member M : int - end -end - -> val it : string = - "Regression_139182: Expect the follow code to be accepted without error" - -> type S = - struct - member TheMethod : unit -> int64 - end -val theMethod : s:S -> int64 -type T = - class - new : unit -> T - member Prop5 : int64 - static member Prop1 : int64 - static member Prop2 : int64 - static member Prop3 : int64 - static member Prop4 : string - end - -> val it : System.Threading.ThreadLocal list = [0 {IsValueCreated = false; - Values = ?;}] - -> type MyDU = - | Case1 of Val1: int * Val2: string - | Case2 of string * V2: bool * float - | Case3 of int - | Case4 of Item1: bool - | Case5 of bool * string - | Case6 of Val1: int * bool * string - | Case7 of Big Name: int -val namedFieldVar1 : MyDU = Case1 (5,"") -val namedFieldVar2 : MyDU = Case7 25 - -> exception MyNamedException1 of Val1: int * Val2: string -exception MyNamedException2 of string * V2: bool * float -exception MyNamedException3 of Data: int -exception MyNamedException4 of bool -exception MyNamedException5 of int * string -exception MyNamedException6 of Val1: int * bool * string * Data8: float -exception MyNamedException7 of Big Named Field: int -val namedEx1 : exn = MyNamedException1 (5,"") -val namedEx2 : exn = MyNamedException7 25 - -> type optionRecord = - { x: int option } -val x : optionRecord = { x = None } - -> type optionRecord = - { x: obj } -val x : optionRecord = { x = null } - -> > > diff --git a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl index 386c625eeff..4d3209ca246 100644 --- a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl @@ -1,330 +1,336 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^^^^^^^^^ + +stdin(219,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ -stdin(572,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(571,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1 = static member (+-+-+) x = "1 argument";; -----------------------------------------^^^^^ -stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(572,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1b = static member (+-+-+) (x) = "1 (argument) [brackets make no diff]";; -----------------------------------------^^^^^ -stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1c = static member (+-+-+) x = let a,b = x in "1 argument, tuple typed from RHS. Still not OK";; -----------------------------------------^^^^^ -stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1d = static member (+-+-+) (x:int*int) = "1 argument, tuple typed from LHS. Still not OK";; -----------------------------------------^^^^^ -stdin(576,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T3 = static member (+-+-+) (x,y,z) = "3 arguments";; -----------------------------------------^^^^^ -stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(577,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U2 = static member (+-+-+) (x,y) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(584,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(584,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(588,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. +stdin(588,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. static member (&^) = "AMP_AMP" -------------------^^ -stdin(590,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(589,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(590,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. +stdin(590,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. static member (!=) = "INFIX_COMPARE_OP" -------------------^^ -stdin(593,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(592,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(597,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(596,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...!=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^^ -stdin(598,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(597,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...<) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(599,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(598,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...>) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(600,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(599,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ($) = "DOLLAR" -------------------^ -stdin(602,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(601,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(602,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. +stdin(602,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(603,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. +stdin(603,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(604,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(604,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(605,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(605,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (...@) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(607,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(606,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...^) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(608,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(607,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (%) = "PERCENT_OP" -------------------^ -stdin(609,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(608,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (-) = "MINUS" -------------------^ -stdin(611,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(610,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( * ) = "STAR" --------------------^ -stdin(612,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(611,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (/) = "INFIX_STAR_DIV_MOD_OP" -------------------^ -stdin(614,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(613,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...* ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(616,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(615,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( .../ ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(617,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(616,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...% ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(618,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(617,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ** ) = "INFIX_STAR_STAR_OP" --------------------^^ -stdin(619,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(618,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... member this.ToString() = "ABC" ----------------^^^^^^^^ -stdin(624,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. +stdin(623,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. member this.M() = "string" ----------------^ -stdin(765,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. +stdin(764,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. member this.P = "string" ----------------^ -stdin(772,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. +stdin(771,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. type public IBPublic = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^ -stdin(779,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(778,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. type internal IBInternal = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^^^ -stdin(784,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. +stdin(783,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. type public IBPublic = interface inherit IAInternal abstract Q : int end ------------------^^^^^^^^ -stdin(793,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(792,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. override x.M(a:string) = 1 -------------------^ -stdin(825,20): error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member Regression4232.D.M : 'U -> int' and 'abstract member Regression4232.D.M : 'T -> int' +stdin(824,20): error FS0361: The override 'M: string -> int' implements more than one abstract slot, e.g. 'abstract Regression4232.D.M: 'U -> int' and 'abstract Regression4232.D.M: 'T -> int' let (|A|B|) (x:int) = A x;; -----^^^^^ -stdin(833,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(832,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (x:'a) = A x;; -----^^^^^ -stdin(836,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(835,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (p:'a) (x:int) = A p;; -----^^^^^ -stdin(839,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(838,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) = failwith "" : Choice;; -----^^^^^ -stdin(845,6): error FS1209: Active pattern '|A|B|' is not a function +stdin(844,6): error FS1209: Active pattern '|A|B|' is not a function diff --git a/tests/fsharp/core/printing/z.output.test.200.stdout.47.bsl b/tests/fsharp/core/printing/z.output.test.200.stdout.47.bsl new file mode 100644 index 00000000000..8bf2618f762 --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.200.stdout.47.bsl @@ -0,0 +1,1959 @@ + +> val it: unit = () + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; ...] + ...] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; ...], ..., ...)) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some (Some (Some (Some ...))); ...] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; ...|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + ...|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; ...]; ...]; ...]; ...] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; N [N ...; ...]; + ...]; ...]; ...] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N ...; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N ...; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N ...; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; + ...] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, ...))), ...), + ...)) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop (229569, Var 114784, Bop (76523, ..., ...)))), ...)) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), ...)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop (36453089, Var 18226544, Bop (12151029, Var 6075514, ...))), + ...), ...)) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop (8388607, Bop (4194303, ..., ...), ...), ...), + ...), ...), ...), ...), ...), ...), ...) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; ...|] +val r10s': string * r[] = ("one extra node", [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = ... }; ...|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0107+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.200.stdout.50.bsl b/tests/fsharp/core/printing/z.output.test.200.stdout.50.bsl new file mode 100644 index 00000000000..1436aecaeaf --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.200.stdout.50.bsl @@ -0,0 +1,1961 @@ + +> val it: unit = () + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; ...] + ...] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; ...], ..., ...)) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some (Some (Some (Some ...))); ...] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; ...|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + ...|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; ...]; ...]; ...]; ...] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; N [N ...; ...]; + ...]; ...]; ...] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N ...; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N ...; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N ...; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; + ...] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, ...))), ...), + ...)) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop (229569, Var 114784, Bop (76523, ..., ...)))), ...)) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), ...)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop (36453089, Var 18226544, Bop (12151029, Var 6075514, ...))), + ...), ...)) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop (8388607, Bop (4194303, ..., ...), ...), ...), + ...), ...), ...), ...), ...), ...), ...) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #r "nuget:FSharp.Data, 3.1.2";; // Load Nuget Package 'FSharp.Data' version '3.1.2' + #r "nuget:FSharp.Data";; // Load Nuget Package 'FSharp.Data' with the highest version + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; ...|] +val r10s': string * r[] = ("one extra node", [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = ... }; ...|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, + [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0107+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.200.stdout.bsl b/tests/fsharp/core/printing/z.output.test.200.stdout.bsl deleted file mode 100644 index 249743e0cff..00000000000 --- a/tests/fsharp/core/printing/z.output.test.200.stdout.bsl +++ /dev/null @@ -1,1991 +0,0 @@ - -> val it : unit = () - -> > val repeatId : string = "A" - -> val repeatId : string = "B" - -namespace FSI_0005 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -> val x1 : seq -val x2 : seq -val x3 : seq -val f1 : System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form -val fs : System.Windows.Forms.Form [] = - [|System.Windows.Forms.Form, Text: fs #0; - System.Windows.Forms.Form, Text: fs #1; - System.Windows.Forms.Form, Text: fs #2; - System.Windows.Forms.Form, Text: fs #3; - System.Windows.Forms.Form, Text: fs #4; - System.Windows.Forms.Form, Text: fs #5; - System.Windows.Forms.Form, Text: fs #6; - System.Windows.Forms.Form, Text: fs #7; - System.Windows.Forms.Form, Text: fs #8; - System.Windows.Forms.Form, Text: fs #9; - System.Windows.Forms.Form, Text: fs #10; - System.Windows.Forms.Form, Text: fs #11; - System.Windows.Forms.Form, Text: fs #12; - System.Windows.Forms.Form, Text: fs #13; - System.Windows.Forms.Form, Text: fs #14; - System.Windows.Forms.Form, Text: fs #15; - System.Windows.Forms.Form, Text: fs #16; - System.Windows.Forms.Form, Text: fs #17; - System.Windows.Forms.Form, Text: fs #18; - System.Windows.Forms.Form, Text: fs #19; ...|] -val xs : string list = - ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; ...] -val xa : string [] = - [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; ...|] -val xa2 : string [,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] - ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] - ["20"; "21"; "22"; "23"; ...] - ...] -val sxs0 : Set = set [] - -> val sxs1 : Set = set ["0"] - -> val sxs2 : Set = set ["0"; "1"] - -> val sxs3 : Set = set ["0"; "1"; "2"] - -> val sxs4 : Set = set ["0"; "1"; "2"; "3"] - -> val sxs200 : Set = - set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] - -> val msxs0 : Map = map [] - -> val msxs1 : Map = map [(0, "0")] - -> val msxs2 : Map = map [(0, "0"); (1, "1")] - -> val msxs3 : Map = map [(0, "0"); (1, "1"); (2, "2")] - -> val msxs4 : Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] - -> val msxs200 : Map = - map - [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); - (7, "7"); (8, "8"); ...] - -> module M = begin - val a : string = "sub-binding" - val b : - (seq * seq * seq * System.Windows.Forms.Form) option * - (string list * string list * string [,]) option = - (Some (, , , System.Windows.Forms.Form, Text: f1 form), - Some - (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; - "13"; "14"; "15"; "16"; ...], ..., ...)) -end -type T = - class - new : a:int * b:int -> T - member AMethod : x:int -> int - member AProperty : int - static member StaticMethod : x:int -> int - static member StaticProperty : int - end -val f_as_method : x:int -> int -val f_as_thunk : (int -> int) -val refCell : string ref = { contents = "value" } -module D1 = begin - val words : System.Collections.Generic.IDictionary - val words2000 : System.Collections.Generic.IDictionary -end - -> > module D2 = begin - val words : IDictionary - val words2000 : IDictionary -end -val opt1 : 'a option -val opt1b : int option = None -val opt4 : 'a option option option option -val opt4b : int option option option option = Some (Some (Some None)) -val opt5 : int list option option option option option list = - [Some (Some (Some (Some None))); - Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); - Some (Some (Some (Some ...))); ...] -val mkStr : n:int -> string -val strs : string [] = - [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; - "---------"; "----------"; "-----------"; "------------"; "-------------"; - "--------------"; "---------------"; "----------------"; - "-----------------"; "------------------"; "-------------------"; ...|] -val str7s : string [] = - [|""; "-------"; "--------------"; "---------------------"; - "----------------------------"; "-----------------------------------"; - "------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[58 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[72 chars]; - ...|] -val grids : string [,] = - [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; - ""; ...] - ...] - -> type tree = - | L - | N of tree list -val mkT : w:int -> d:int -> tree -val tree : w:int -> d:int -> tree - -> [Building 2 4...done] -val tree_2_4 : tree = - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; ...]; ...]; ...]; ...] - -> [Building 2 6...done] -val tree_2_6 : tree = - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; N [N ...; ...]; - ...]; ...]; ...] - -> [Building 2 8...done] -val tree_2_8 : tree = - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 2 10...done] -val tree_2_10 : tree = - N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N ...; ...]; - ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 2 12...done] -val tree_2_12 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; - ...]; ...] - -> [Building 2 14...done] -val tree_2_14 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N ...; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...]; ...]; ...]; - ...]; ...] - -> [Building 3 8...done] -val tree_3_8 : tree = - N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; N ...; ...]; - ...]; ...]; ...]; ...]; ...] - -> [Building 4 8...done] -val tree_4_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 5 8...done] -val tree_5_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N ...; ...]; ...]; - ...]; ...]; ...]; ...]; ...] - -> [Building 6 8...done] -val tree_6_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...] - -> [Building 5 3...done] -val tree_5_3 : tree = - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L; ...]; ...]; - ...] - -> > type X = - | Var of int - | Bop of int * X * X -val generate : x:int -> X - -> val exps : X list = - [Bop (1,Var 0,Var 0); Var 2; Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,...)); - ...] - -> module Exprs = begin - val x1 : X = - Bop - (213,Var 106, - Bop - (71,Bop (35,Bop (17,Var 8,Bop (5,Var 2,Bop (1,Var 0,...))),...),...)) - val x2 : X = Var 21342314 - val x3 : X = Var 3214 - val x4 : X = Bop (1231357,Var 615678,Var 410452) - val x5 : X = - Bop - (5234547,Bop (2617273,Var 1308636,Var 872424), - Bop (1744849,Var 872424,Var 581616)) - val x6 : X = - Bop (923759825,Var 461879912,Bop (307919941,Var 153959970,Var 102639980)) - val x7 : X = Var 2435234 - val x8 : X = - Bop - (12396777,Var 6198388, - Bop - (4132259, - Bop - (2066129,Var 1033064, - Bop - (688709,Var 344354,Bop (229569,Var 114784,Bop (76523,...,...)))), - ...)) - val x9 : X = - Bop - (3333333,Var 1666666, - Bop - (1111111, - Bop - (555555,Bop (277777,Var 138888,Var 92592), - Bop (185185,Var 92592,Var 61728)),...)) - val x10 : X = - Bop - (1312311237,Var 656155618, - Bop - (437437079, - Bop - (218718539, - Bop - (109359269,Var 54679634, - Bop (36453089,Var 18226544,Bop (12151029,Var 6075514,...))), - ...),...)) - val x11 : X = - Bop - (2147483647, - Bop - (1073741823, - Bop - (536870911, - Bop - (268435455, - Bop - (134217727, - Bop - (67108863, - Bop - (33554431, - Bop - (16777215,Bop (8388607,Bop (4194303,...,...),...), - ...),...),...),...),...),...),...),...) -end - -> type C = - class - new : x:string -> C - override ToString : unit -> string - end -val c1 : C = -val csA : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csB : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csC : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] - -> exception Abc - -> exception AbcInt of int - -> exception AbcString of string - -> exception AbcExn of exn list - -> exception AbcException of System.Exception list - -> val exA1 : exn = Abc -val exA2 : exn = AbcInt 2 -val exA3 : exn = AbcString "3" -val exA4 : exn = AbcExn [Abc; AbcInt 2; AbcString "3"] -val exA5 : exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] -exception Ex0 -exception ExUnit of unit -exception ExUnits of unit * unit -exception ExUnitOption of unit option -val ex0 : exn = Ex0 -val exU : exn = ExUnit () -val exUs : exn = ExUnits ((),()) -val exUSome : exn = ExUnitOption (Some ()) -val exUNone : exn = ExUnitOption None -type 'a T4063 = | AT4063 of 'a - -> val valAT3063_12 : int T4063 = AT4063 12 - -> val valAT3063_True : bool T4063 = AT4063 true - -> val valAT3063_text : string T4063 = AT4063 "text" - -> val valAT3063_null : System.Object T4063 = AT4063 null - -> type M4063<'a> = - class - new : x:'a -> M4063<'a> - end - -> val v4063 : M4063 - -> type Taaaaa<'a> = - class - new : unit -> Taaaaa<'a> - end - -> type Taaaaa2<'a> = - class - inherit Taaaaa<'a> - new : unit -> Taaaaa2<'a> - member M : unit -> Taaaaa2<'a> - end - -> type Tbbbbb<'a> = - class - new : x:'a -> Tbbbbb<'a> - member M : unit -> 'a - end - -> type Tbbbbb2 = - class - inherit Tbbbbb - new : x:string -> Tbbbbb2 - end - -> val it : (unit -> string) = - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> val it : string = "Check #help" - -> - F# Interactive directives: - - #r "file.dll";; Reference (dynamically load) the given DLL - #I "path";; Add the given search path for referenced DLLs - #load "file.fs" ...;; Load the given file(s) as if compiled and referenced - #time ["on"|"off"];; Toggle timing on/off - #help;; Display help - #quit;; Exit - - F# Interactive command line options: - - - -> val it : string = "Check #time on and then off" - -> ---> Timing now on - -> ---> Timing now off - -> val it : string = "Check #unknown command" - -> Invalid directive '#blaaaaaa ' -> val it : string = - "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" - -> ---> Added '/' to library include path - -> type internal T1 = - | A - | B - -> type internal T2 = - { x: int } - -> type internal T3 - -> type internal T4 = - class - new : unit -> T4 - end - -> type T1 = - internal | A - | B - -> type T2 = - internal { x: int } - -> type private T1 = - | A - | B - -> type private T2 = - { x: int } - -> type T1 = - private | A - | B - -> type T2 = - private { x: int } - -> type internal T1 = - private | A - | B - -> type internal T2 = - private { x: int } - -> type private T3 - -> type private T4 = - class - new : unit -> T4 - end - -> exception X1 of int - -> exception private X2 of int - -> exception internal X3 of int - -> type T0 = - class - new : unit -> T0 - end -type T1Post<'a> = - class - new : unit -> T1Post<'a> - end -type 'a T1Pre = - class - new : unit -> 'a T1Pre - end - -> type T0 with - member M : unit -> T0 list -type T0 with - member P : T0 * T0 -type T0 with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type r = - { f0: int - f1: int - f2: int - f3: int - f4: int - f5: int - f6: int - f7: int - f8: int - f9: int } -val r10 : r = { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 } -val r10s : r [] = [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; ...|] -val r10s' : string * r [] = ("one extra node", [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = ... }; ...|]) - -> val x1564_A1 : int = 1 - - ---> Added '\' to library include path - -val x1564_A2 : int = 2 - - ---> Added '\' to library include path - -val x1564_A3 : int = 3 - -> type internal Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - -> module internal InternalM = begin - val x : int = 1 - type Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - type private Foo3 = - class - new : unit -> Foo3 - new : x:int -> Foo3 - new : x:int * y:int -> Foo3 - new : x:int * y:int * z:int -> Foo3 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end -module internal PrivateM = begin - val private x : int = 1 - type private Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end - -> val it : seq = - seq - [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); - (58, "2/10/2009", 1)] - -> module Test4343a = begin - val mk : i:int -> string - val x100 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] - val x90 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] - val x80 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] - val x75 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] - val x74 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] - val x73 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] - val x72 : string = - "012345678901234567890123456789012345678901234567890123456789012345678901" - val x71 : string = - "01234567890123456789012345678901234567890123456789012345678901234567890" - val x70 : string = - "0123456789012345678901234567890123456789012345678901234567890123456789" -end -module Test4343b = begin - val fA : x:int -> int - val fB : x:'a -> y:'a -> 'a list - val gA : (int -> int) - val gB : ('a -> 'a -> 'a list) - val gAB : (int -> int) * ('a -> 'a -> 'a list) - val hB : ('a -> 'a -> 'a list) - val hA : (int -> int) -end -module Test4343c = begin - val typename<'a> : string - val typename2<'a> : string * string -end -module Test4343d = begin - val xList : int list = [1; 2; 3] - val xArray : int [] = [|1; 2; 3|] - val xString : string = "abcdef" - val xOption : int option = Some 12 - val xArray2 : (int * int) [,] = [[(0, 0); (0, 1)] - [(1, 0); (1, 1)]] - val xSeq : seq -end -module Test4343e = begin - type C = - class - new : x:int -> C - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, - [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) - type D = - class - new : x:int -> D - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - module Generic = begin - type CGeneric<'a> = - class - new : x:'a -> CGeneric<'a> - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0091+Test4343e+C, FSI_0091+Test4343e+C, - [FSI_0091+Test4343e+C; FSI_0091+Test4343e+C]) - type D<'a> = - class - new : x:'a -> D<'a> - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - val dC : D = D(True) - val boxed_dABC : obj list = [D(1); D(2); D(True)] - end -end -type F1 = - class - inherit System.Windows.Forms.Form - interface System.IDisposable - val x: F1 - val x2: F1 - abstract member MMM : bool -> bool - abstract member AAA : int - abstract member ZZZ : int - abstract member BBB : bool with set - member B : unit -> int - member D : unit -> int - member D : x:int -> int - member D : x:int * y:int -> int - override ToString : unit -> string - member D2 : int - member E : int - member D2 : int with set - member E : int with set - static val mutable private sx: F1 - static val mutable private sx2: F1 - static member A : unit -> int - static member C : unit -> int - end -type IP = - struct - new : x:int * y:int -> IP - static val mutable private AA: IP - end -module Regression4643 = begin - type RIP = - struct - new : x:int -> RIP - static val mutable private y: RIP - end - type arg_unused_is_RIP = - struct - new : x:RIP -> arg_unused_is_RIP - end - type arg_used_is_RIP = - struct - new : x:RIP -> arg_used_is_RIP - member X : RIP - end - type field_is_RIP = - struct - val x: RIP - end -end -type Either<'a,'b> = - | This of 'a - | That of 'b -val catch : f:(unit -> 'a) -> Either<'a,(string * string)> -val seqFindIndexFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqFindFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqPickFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -module Regression5218 = begin - val t1 : int = 1 - val t2 : int * int = (1, 2) - val t3 : int * int * int = (1, 2, 3) - val t4 : int * int * int * int = (1, 2, 3, 4) - val t5 : int * int * int * int * int = (1, 2, 3, 4, 5) - val t6 : int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) - val t7 : int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) - val t8 : int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8) - val t9 : int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9) - val t10 : int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val t11 : int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - val t12 : - int * int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) - val t13 : - int * int * int * int * int * int * int * int * int * int * int * int * - int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) - val t14 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) - val t15 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3740 = begin - type Writer<'a> = - interface - abstract member get_path : unit -> string - end - type MyClass = - class - interface Writer - val path: string - end -end - -> type Regression4319_T2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> string - end - -> type Regression4319_T0 = - class - static member ( +-+-+ ) : string - end - -> type Regression4319_T1 = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1b = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1c = - class - static member ( +-+-+ ) : x:('a * 'b) -> string - end - -> type Regression4319_T1d = - class - static member ( +-+-+ ) : x:(int * int) -> string - end - -> type Regression4319_T3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> string - end - -> type Regression4319_U1 = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U1b = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> moreArgs:'c -> string - end - -> type Regression4319_U3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> moreArgs:'d -> string - end - -> type Regression4319_check = - class - static member ( & ) : string - static member ( &^ ) : string - static member ( @ ) : string - static member ( != ) : string - static member ( := ) : string - static member ( ^ ) : string - static member ( / ) : string - static member ( $ ) : string - static member ( ...@ ) : string - static member ( ...!= ) : string - static member ( .../ ) : string - static member ( ...= ) : string - static member ( ...> ) : string - static member ( ...^ ) : string - static member ( ...< ) : string - static member ( ...* ) : string - static member ( ...% ) : string - static member ( = ) : string - static member ( ** ) : string - static member ( > ) : string - static member ( < ) : string - static member ( % ) : string - static member ( * ) : string - static member ( - ) : string - end - -> Expect ABC = ABC -type Regression4469 = - class - new : unit -> Regression4469 - member ToString : unit -> string - end -val r4469 : Regression4469 = FSI_0107+Regression4469 -val it : unit = () - -> Expect ABC = ABC -val it : unit = () - -> module Regression1019_short = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end -module Regression1019_long = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end - -> val it : int ref = { contents = 1 } - -> val x : int ref = { contents = 1 } -val f : (unit -> int) - -> val it : int = 1 - -> val it : unit = () - -> val it : int = 3 - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : 'a list - -> val it : 'a list list - -> val it : 'a option - -> val it : 'a list * 'b list - -> val it : x:'a -> 'a - -> val fff : x:'a -> 'a - -> val it : ('a -> 'a) - -> val note_ExpectDupMethod : string = - "Regression4927: Expect error due to duplicate methods in the "+[20 chars] - -> > val note_ExpectDupProperty : string = - "Regression4927: Expect error due to duplicate properties in t"+[23 chars] - -> > > val it : string = "NOTE: Expect IAPrivate less accessible IBPublic" - -> > val it : string = "NOTE: Expect IAPrivate less accessible IBInternal" - -> > module Regression5265_PriPri = begin - type private IAPrivate = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPrivate - abstract member Q : int - end -end - -> val it : string = "NOTE: Expect IAInternal less accessible IBPublic" - -> > module Regression5265_IntInt = begin - type internal IAInternal = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_IntPri = begin - type internal IAInternal = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_PubPub = begin - type IAPublic = - interface - abstract member P : int - end - type IBPublic = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubInt = begin - type IAPublic = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubPri = begin - type IAPublic = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPublic - abstract member Q : int - end -end - -> val it : string = - "Regression4232: Expect an error about duplicate virtual methods from parent type" - -> > val it : string = - "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" - -> type AnAxHostSubClass = - class - inherit System.Windows.Forms.AxHost - new : x:string -> AnAxHostSubClass - end - -> val it : string = - "** Expect error because the active pattern result contains free type variables" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (match value generic)" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" - -> > val it : string = - "** Expect OK, since error message says constraint should work!" - -> val ( |A|B| ) : x:int -> Choice - -> val it : string = "** Expect error since active pattern is not a function!" - -> > val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on match val" - -> val ( |A|B| ) : p:bool -> 'a * 'b -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on parameters" - -> val ( |A|B| ) : aval:'a -> bval:'b -> x:bool -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is generic, but it typar from closure, so OK" - -> val outer : x:'a -> (int -> 'a option) - -> val it : string = - "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" - -> val ( |Check1| ) : a:int -> int * 'a option - -> > module ReflectionEmit = begin - type IA = - interface - abstract member M : #IB -> int - end - and IB = - interface - abstract member M : #IA -> int - end - type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = - interface - abstract member M : int - end - and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = - interface - abstract member M : int - end -end - -> val it : string = - "Regression_139182: Expect the follow code to be accepted without error" - -> type S = - struct - member TheMethod : unit -> int64 - end -val theMethod : s:S -> int64 -type T = - class - new : unit -> T - member Prop5 : int64 - static member Prop1 : int64 - static member Prop2 : int64 - static member Prop3 : int64 - static member Prop4 : string - end - -> val it : System.Threading.ThreadLocal list = [0 {IsValueCreated = false; - Values = ?;}] - -> type MyDU = - | Case1 of Val1: int * Val2: string - | Case2 of string * V2: bool * float - | Case3 of int - | Case4 of Item1: bool - | Case5 of bool * string - | Case6 of Val1: int * bool * string - | Case7 of Big Name: int -val namedFieldVar1 : MyDU = Case1 (5,"") -val namedFieldVar2 : MyDU = Case7 25 - -> exception MyNamedException1 of Val1: int * Val2: string -exception MyNamedException2 of string * V2: bool * float -exception MyNamedException3 of Data: int -exception MyNamedException4 of bool -exception MyNamedException5 of int * string -exception MyNamedException6 of Val1: int * bool * string * Data8: float -exception MyNamedException7 of Big Named Field: int -val namedEx1 : exn = MyNamedException1 (5,"") -val namedEx2 : exn = MyNamedException7 25 - -> type optionRecord = - { x: int option } -val x : optionRecord = { x = None } - -> type optionRecord = - { x: obj } -val x : optionRecord = { x = null } - -> > > diff --git a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl index 386c625eeff..4d3209ca246 100644 --- a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl @@ -1,330 +1,336 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^^^^^^^^^ + +stdin(219,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ -stdin(572,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(571,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1 = static member (+-+-+) x = "1 argument";; -----------------------------------------^^^^^ -stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(572,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1b = static member (+-+-+) (x) = "1 (argument) [brackets make no diff]";; -----------------------------------------^^^^^ -stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1c = static member (+-+-+) x = let a,b = x in "1 argument, tuple typed from RHS. Still not OK";; -----------------------------------------^^^^^ -stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1d = static member (+-+-+) (x:int*int) = "1 argument, tuple typed from LHS. Still not OK";; -----------------------------------------^^^^^ -stdin(576,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T3 = static member (+-+-+) (x,y,z) = "3 arguments";; -----------------------------------------^^^^^ -stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(577,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U2 = static member (+-+-+) (x,y) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(584,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(584,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(588,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. +stdin(588,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. static member (&^) = "AMP_AMP" -------------------^^ -stdin(590,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(589,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(590,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. +stdin(590,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. static member (!=) = "INFIX_COMPARE_OP" -------------------^^ -stdin(593,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(592,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(597,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(596,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...!=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^^ -stdin(598,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(597,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...<) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(599,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(598,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...>) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(600,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(599,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ($) = "DOLLAR" -------------------^ -stdin(602,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(601,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(602,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. +stdin(602,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(603,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. +stdin(603,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(604,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(604,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(605,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(605,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (...@) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(607,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(606,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...^) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(608,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(607,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (%) = "PERCENT_OP" -------------------^ -stdin(609,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(608,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (-) = "MINUS" -------------------^ -stdin(611,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(610,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( * ) = "STAR" --------------------^ -stdin(612,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(611,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (/) = "INFIX_STAR_DIV_MOD_OP" -------------------^ -stdin(614,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(613,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...* ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(616,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(615,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( .../ ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(617,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(616,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...% ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(618,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(617,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ** ) = "INFIX_STAR_STAR_OP" --------------------^^ -stdin(619,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(618,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... member this.ToString() = "ABC" ----------------^^^^^^^^ -stdin(624,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. +stdin(623,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. member this.M() = "string" ----------------^ -stdin(765,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. +stdin(764,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. member this.P = "string" ----------------^ -stdin(772,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. +stdin(771,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. type public IBPublic = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^ -stdin(779,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(778,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. type internal IBInternal = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^^^ -stdin(784,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. +stdin(783,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. type public IBPublic = interface inherit IAInternal abstract Q : int end ------------------^^^^^^^^ -stdin(793,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(792,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. override x.M(a:string) = 1 -------------------^ -stdin(825,20): error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member Regression4232.D.M : 'U -> int' and 'abstract member Regression4232.D.M : 'T -> int' +stdin(824,20): error FS0361: The override 'M: string -> int' implements more than one abstract slot, e.g. 'abstract Regression4232.D.M: 'U -> int' and 'abstract Regression4232.D.M: 'T -> int' let (|A|B|) (x:int) = A x;; -----^^^^^ -stdin(833,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(832,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (x:'a) = A x;; -----^^^^^ -stdin(836,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(835,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (p:'a) (x:int) = A p;; -----^^^^^ -stdin(839,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(838,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) = failwith "" : Choice;; -----^^^^^ -stdin(845,6): error FS1209: Active pattern '|A|B|' is not a function +stdin(844,6): error FS1209: Active pattern '|A|B|' is not a function diff --git a/tests/fsharp/core/printing/z.output.test.default.stdout.47.bsl b/tests/fsharp/core/printing/z.output.test.default.stdout.47.bsl new file mode 100644 index 00000000000..706237bb693 --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.default.stdout.47.bsl @@ -0,0 +1,6261 @@ + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0004 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; + System.Windows.Forms.Form, Text: fs #20; + System.Windows.Forms.Form, Text: fs #21; + System.Windows.Forms.Form, Text: fs #22; + System.Windows.Forms.Form, Text: fs #23; + System.Windows.Forms.Form, Text: fs #24; + System.Windows.Forms.Form, Text: fs #25; + System.Windows.Forms.Form, Text: fs #26; + System.Windows.Forms.Form, Text: fs #27; + System.Windows.Forms.Form, Text: fs #28; + System.Windows.Forms.Form, Text: fs #29; + System.Windows.Forms.Form, Text: fs #30; + System.Windows.Forms.Form, Text: fs #31; + System.Windows.Forms.Form, Text: fs #32; + System.Windows.Forms.Form, Text: fs #33; + System.Windows.Forms.Form, Text: fs #34; + System.Windows.Forms.Form, Text: fs #35; + System.Windows.Forms.Form, Text: fs #36; + System.Windows.Forms.Form, Text: fs #37; + System.Windows.Forms.Form, Text: fs #38; + System.Windows.Forms.Form, Text: fs #39; + System.Windows.Forms.Form, Text: fs #40; + System.Windows.Forms.Form, Text: fs #41; + System.Windows.Forms.Form, Text: fs #42; + System.Windows.Forms.Form, Text: fs #43; + System.Windows.Forms.Form, Text: fs #44; + System.Windows.Forms.Form, Text: fs #45; + System.Windows.Forms.Form, Text: fs #46; + System.Windows.Forms.Form, Text: fs #47; + System.Windows.Forms.Form, Text: fs #48; + System.Windows.Forms.Form, Text: fs #49; + System.Windows.Forms.Form, Text: fs #50; + System.Windows.Forms.Form, Text: fs #51; + System.Windows.Forms.Form, Text: fs #52; + System.Windows.Forms.Form, Text: fs #53; + System.Windows.Forms.Form, Text: fs #54; + System.Windows.Forms.Form, Text: fs #55; + System.Windows.Forms.Form, Text: fs #56; + System.Windows.Forms.Form, Text: fs #57; + System.Windows.Forms.Form, Text: fs #58; + System.Windows.Forms.Form, Text: fs #59; + System.Windows.Forms.Form, Text: fs #60; + System.Windows.Forms.Form, Text: fs #61; + System.Windows.Forms.Form, Text: fs #62; + System.Windows.Forms.Form, Text: fs #63; + System.Windows.Forms.Form, Text: fs #64; + System.Windows.Forms.Form, Text: fs #65; + System.Windows.Forms.Form, Text: fs #66; + System.Windows.Forms.Form, Text: fs #67; + System.Windows.Forms.Form, Text: fs #68; + System.Windows.Forms.Form, Text: fs #69; + System.Windows.Forms.Form, Text: fs #70; + System.Windows.Forms.Form, Text: fs #71; + System.Windows.Forms.Form, Text: fs #72; + System.Windows.Forms.Form, Text: fs #73; + System.Windows.Forms.Form, Text: fs #74; + System.Windows.Forms.Form, Text: fs #75; + System.Windows.Forms.Form, Text: fs #76; + System.Windows.Forms.Form, Text: fs #77; + System.Windows.Forms.Form, Text: fs #78; + System.Windows.Forms.Form, Text: fs #79; + System.Windows.Forms.Form, Text: fs #80; + System.Windows.Forms.Form, Text: fs #81; + System.Windows.Forms.Form, Text: fs #82; + System.Windows.Forms.Form, Text: fs #83; + System.Windows.Forms.Form, Text: fs #84; + System.Windows.Forms.Form, Text: fs #85; + System.Windows.Forms.Form, Text: fs #86; + System.Windows.Forms.Form, Text: fs #87; + System.Windows.Forms.Form, Text: fs #88; + System.Windows.Forms.Form, Text: fs #89; + System.Windows.Forms.Form, Text: fs #90; + System.Windows.Forms.Form, Text: fs #91; + System.Windows.Forms.Form, Text: fs #92; + System.Windows.Forms.Form, Text: fs #93; + System.Windows.Forms.Form, Text: fs #94; + System.Windows.Forms.Form, Text: fs #95; + System.Windows.Forms.Form, Text: fs #96; + System.Windows.Forms.Form, Text: fs #97; + System.Windows.Forms.Form, Text: fs #98; + System.Windows.Forms.Form, Text: fs #99; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], + [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]])) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some + (Some + (Some + (Some + (Some + [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; + 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; + 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------"; + "---------------------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------"; + "------------------------------------------------------"; + "-------------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------"; + "----------------------------------------------------------"; + "-----------------------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"; + "--------------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[12 chars]; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[18 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[22 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[28 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[36 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[38 chars]|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[310 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[352 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[366 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[380 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[408 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[422 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[436 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[450 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[478 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[492 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[506 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[520 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[548 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[562 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[576 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[590 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[618 chars]; + "-------------------------------------------------------------"+[625 chars]; + "-------------------------------------------------------------"+[632 chars]|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] + [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"] + [""; "--"; "----"; "------"; "--------"; "----------"; "------------"; + "--------------"; "----------------"; "------------------"; + "--------------------"; "----------------------"; + "------------------------"; "--------------------------"; + "----------------------------"; "------------------------------"; + "--------------------------------"; "----------------------------------"; + "------------------------------------"; + "--------------------------------------"; + "----------------------------------------"; + "------------------------------------------"; + "--------------------------------------------"; + "----------------------------------------------"; + "------------------------------------------------"; + "--------------------------------------------------"; + "----------------------------------------------------"; + "------------------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------"; + "------------------------------------------------------------"; + "--------------------------------------------------------------"; + "----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[37 chars]] + [""; "---"; "------"; "---------"; "------------"; "---------------"; + "------------------"; "---------------------"; "------------------------"; + "---------------------------"; "------------------------------"; + "---------------------------------"; + "------------------------------------"; + "---------------------------------------"; + "------------------------------------------"; + "---------------------------------------------"; + "------------------------------------------------"; + "---------------------------------------------------"; + "------------------------------------------------------"; + "---------------------------------------------------------"; + "------------------------------------------------------------"; + "---------------------------------------------------------------"; + "------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[50 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[62 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[68 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[77 chars]; + "-------------------------------------------------------------"+[80 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[86 chars]] + [""; "----"; "--------"; "------------"; "----------------"; + "--------------------"; "------------------------"; + "----------------------------"; "--------------------------------"; + "------------------------------------"; + "----------------------------------------"; + "--------------------------------------------"; + "------------------------------------------------"; + "----------------------------------------------------"; + "--------------------------------------------------------"; + "------------------------------------------------------------"; + "----------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[55 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[63 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[87 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[103 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[111 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[123 chars]; + "-------------------------------------------------------------"+[127 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[135 chars]] + [""; "-----"; "----------"; "---------------"; "--------------------"; + "-------------------------"; "------------------------------"; + "-----------------------------------"; + "----------------------------------------"; + "---------------------------------------------"; + "--------------------------------------------------"; + "-------------------------------------------------------"; + "------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[54 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[64 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[84 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[94 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[124 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[144 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[154 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[169 chars]; + "-------------------------------------------------------------"+[174 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[184 chars]] + [""; "------"; "------------"; "------------------"; + "------------------------"; "------------------------------"; + "------------------------------------"; + "------------------------------------------"; + "------------------------------------------------"; + "------------------------------------------------------"; + "------------------------------------------------------------"; + "------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[77 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[113 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[125 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[161 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[185 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[197 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[215 chars]; + "-------------------------------------------------------------"+[221 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[233 chars]] + [""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]] + [""; "--------"; "----------------"; "------------------------"; + "--------------------------------"; + "----------------------------------------"; + "------------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[123 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[171 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[187 chars]; + "-------------------------------------------------------------"+[195 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[235 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[267 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[283 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[307 chars]; + "-------------------------------------------------------------"+[315 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[331 chars]] + [""; "---------"; "------------------"; "---------------------------"; + "------------------------------------"; + "---------------------------------------------"; + "------------------------------------------------------"; + "---------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[92 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[110 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[146 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[182 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[200 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[218 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[236 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[272 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[290 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[308 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[326 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[344 chars]; + "-------------------------------------------------------------"+[353 chars]; + "-------------------------------------------------------------"+[362 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[380 chars]] + [""; "----------"; "--------------------"; "------------------------------"; + "----------------------------------------"; + "--------------------------------------------------"; + "------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[169 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[189 chars]; + "-------------------------------------------------------------"+[199 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[229 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[249 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[279 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[309 chars]; + "-------------------------------------------------------------"+[319 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[339 chars]; + "-------------------------------------------------------------"+[349 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[369 chars]; + "-------------------------------------------------------------"+[379 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[399 chars]; + "-------------------------------------------------------------"+[409 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[429 chars]] + [""; "-----------"; "----------------------"; + "---------------------------------"; + "--------------------------------------------"; + "-------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[60 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[82 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[126 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[148 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[181 chars]; + "-------------------------------------------------------------"+[192 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[214 chars]; + "-------------------------------------------------------------"+[225 chars]; + "-------------------------------------------------------------"+[236 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[258 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[280 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[302 chars]; + "-------------------------------------------------------------"+[313 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[346 chars]; + "-------------------------------------------------------------"+[357 chars]; + "-------------------------------------------------------------"+[368 chars]; + "-------------------------------------------------------------"+[379 chars]; + "-------------------------------------------------------------"+[390 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[412 chars]; + "-------------------------------------------------------------"+[423 chars]; + "-------------------------------------------------------------"+[434 chars]; + "-------------------------------------------------------------"+[445 chars]; + "-------------------------------------------------------------"+[456 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[478 chars]] + [""; "------------"; "------------------------"; + "------------------------------------"; + "------------------------------------------------"; + "------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[215 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[287 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[311 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[347 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[383 chars]; + "-------------------------------------------------------------"+[395 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[431 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[455 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[491 chars]; + "-------------------------------------------------------------"+[503 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[527 chars]] + [""; "-------------"; "--------------------------"; + "---------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------------------"; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[82 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[108 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[160 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[186 chars]; + "-------------------------------------------------------------"+[199 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[225 chars]; + "-------------------------------------------------------------"+[238 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[264 chars]; + "-------------------------------------------------------------"+[277 chars]; + "-------------------------------------------------------------"+[290 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[316 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[342 chars]; + "-------------------------------------------------------------"+[355 chars]; + "-------------------------------------------------------------"+[368 chars]; + "-------------------------------------------------------------"+[381 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[420 chars]; + "-------------------------------------------------------------"+[433 chars]; + "-------------------------------------------------------------"+[446 chars]; + "-------------------------------------------------------------"+[459 chars]; + "-------------------------------------------------------------"+[472 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[498 chars]; + "-------------------------------------------------------------"+[511 chars]; + "-------------------------------------------------------------"+[524 chars]; + "-------------------------------------------------------------"+[537 chars]; + "-------------------------------------------------------------"+[550 chars]; + "-------------------------------------------------------------"+[563 chars]; + "-------------------------------------------------------------"+[576 chars]] + [""; "--------------"; "----------------------------"; + "------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[625 chars]] + [""; "---------------"; "------------------------------"; + "---------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[194 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[224 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[284 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[314 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[344 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[374 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[404 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[434 chars]; + "-------------------------------------------------------------"+[449 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[494 chars]; + "-------------------------------------------------------------"+[509 chars]; + "-------------------------------------------------------------"+[524 chars]; + "-------------------------------------------------------------"+[539 chars]; + "-------------------------------------------------------------"+[554 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[584 chars]; + "-------------------------------------------------------------"+[599 chars]; + "-------------------------------------------------------------"+[614 chars]; + "-------------------------------------------------------------"+[629 chars]; + "-------------------------------------------------------------"+[644 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[674 chars]] + [""; "----------------"; "--------------------------------"; + "------------------------------------------------"; + "----------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[195 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[307 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[339 chars]; + "-------------------------------------------------------------"+[355 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[403 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[435 chars]; + "-------------------------------------------------------------"+[451 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[483 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[531 chars]; + "-------------------------------------------------------------"+[547 chars]; + "-------------------------------------------------------------"+[563 chars]; + "-------------------------------------------------------------"+[579 chars]; + "-------------------------------------------------------------"+[595 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[627 chars]; + "-------------------------------------------------------------"+[643 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[675 chars]; + "-------------------------------------------------------------"+[691 chars]; + "-------------------------------------------------------------"+[707 chars]; + "-------------------------------------------------------------"+[723 chars]] + [""; "-----------------"; "----------------------------------"; + "---------------------------------------------------"; + "--------------------------------------------------------------------"; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[92 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[126 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[160 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[194 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[228 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[262 chars]; + "-------------------------------------------------------------"+[279 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[313 chars]; + "-------------------------------------------------------------"+[330 chars]; + "-------------------------------------------------------------"+[347 chars]; + "-------------------------------------------------------------"+[364 chars]; + "-------------------------------------------------------------"+[381 chars]; + "-------------------------------------------------------------"+[398 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[432 chars]; + "-------------------------------------------------------------"+[449 chars]; + "-------------------------------------------------------------"+[466 chars]; + "-------------------------------------------------------------"+[483 chars]; + "-------------------------------------------------------------"+[500 chars]; + "-------------------------------------------------------------"+[517 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[551 chars]; + "-------------------------------------------------------------"+[568 chars]; + "-------------------------------------------------------------"+[585 chars]; + "-------------------------------------------------------------"+[602 chars]; + "-------------------------------------------------------------"+[619 chars]; + "-------------------------------------------------------------"+[636 chars]; + "-------------------------------------------------------------"+[653 chars]; + "-------------------------------------------------------------"+[670 chars]; + "-------------------------------------------------------------"+[687 chars]; + "-------------------------------------------------------------"+[704 chars]; + "-------------------------------------------------------------"+[721 chars]; + "-------------------------------------------------------------"+[738 chars]; + "-------------------------------------------------------------"+[755 chars]; + "-------------------------------------------------------------"+[772 chars]] + [""; "------------------"; "------------------------------------"; + "------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[353 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[425 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[461 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[497 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[533 chars]; + "-------------------------------------------------------------"+[551 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[587 chars]; + "-------------------------------------------------------------"+[605 chars]; + "-------------------------------------------------------------"+[623 chars]; + "-------------------------------------------------------------"+[641 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[677 chars]; + "-------------------------------------------------------------"+[695 chars]; + "-------------------------------------------------------------"+[713 chars]; + "-------------------------------------------------------------"+[731 chars]; + "-------------------------------------------------------------"+[749 chars]; + "-------------------------------------------------------------"+[767 chars]; + "-------------------------------------------------------------"+[785 chars]; + "-------------------------------------------------------------"+[803 chars]; + "-------------------------------------------------------------"+[821 chars]] + [""; "-------------------"; "--------------------------------------"; + "---------------------------------------------------------"; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[110 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[148 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[186 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[224 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[262 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[300 chars]; + "-------------------------------------------------------------"+[319 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[357 chars]; + "-------------------------------------------------------------"+[376 chars]; + "-------------------------------------------------------------"+[395 chars]; + "-------------------------------------------------------------"+[414 chars]; + "-------------------------------------------------------------"+[433 chars]; + "-------------------------------------------------------------"+[452 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[490 chars]; + "-------------------------------------------------------------"+[509 chars]; + "-------------------------------------------------------------"+[528 chars]; + "-------------------------------------------------------------"+[547 chars]; + "-------------------------------------------------------------"+[566 chars]; + "-------------------------------------------------------------"+[585 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[623 chars]; + "-------------------------------------------------------------"+[642 chars]; + "-------------------------------------------------------------"+[661 chars]; + "-------------------------------------------------------------"+[680 chars]; + "-------------------------------------------------------------"+[699 chars]; + "-------------------------------------------------------------"+[718 chars]; + "-------------------------------------------------------------"+[737 chars]; + "-------------------------------------------------------------"+[756 chars]; + "-------------------------------------------------------------"+[775 chars]; + "-------------------------------------------------------------"+[794 chars]; + "-------------------------------------------------------------"+[813 chars]; + "-------------------------------------------------------------"+[832 chars]; + "-------------------------------------------------------------"+[851 chars]; + "-------------------------------------------------------------"+[870 chars]; + ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N ...; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; + N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; + N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]]; + N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]]; + N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]]; + N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N ...; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)); Var 4; + Bop (5, Var 2, Bop (1, Var 0, Var 0)); Var 6; + Bop (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2); + Var 8; + Bop (9, Var 4, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))); + Var 10; + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2)))); + Var 21342314; Var 3214; Bop (1231357, Var 615678, Var 410452); + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)); + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)); + Var 2435234; + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502)))), + Bop + (459139, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))), + Var 153046)))); + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)); + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))), + Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)))), + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))), + Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114))), + Bop (24302059, Bop (12151029, ..., ...), ...))), ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), + Var 2)))) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502)))), + Bop + (459139, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))), + Var 153046)))) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)))), + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114))), + Bop + (24302059, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)), Var 8100686))), + Bop + (145812359, + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + ...), ...))), + ...)))), ...), ...)), + ...))), ...))), ...), ...))) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop + (8388607, + Bop + (4194303, + Bop + (2097151, + Bop + (1048575, + Bop + (524287, + Bop + (262143, + Bop + (131071, + Bop + (65535, + Bop + (32767, + Bop + (16383, + Bop + (8191, + Bop + (4095, + Bop + (2047, + Bop + (1023, + Bop + (511, + Bop + (255, + Bop + (127, + Bop + (63, + Bop + (31, + Bop + (15, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2), + Bop + (5, + Var + 2, + Bop + (1, + Var + 0, + Var + 0))), + Var + 10), + Bop + (21, + Var + 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2))), + Var + 42), + Bop + (85, + Var + 42, + Var + 28)), + Var + 170), + Bop + (341, + Var + 170, + Bop + (113, + Var + 56, + Bop + (37, + Var + 18, + Var + 12)))), + Var 682), + Bop + (1365, + Var 682, + Bop + (455, + Bop + (227, + Bop + (113, + Var + 56, + Bop + (37, + Var + 18, + Var + 12)), + Bop + (75, + Bop + (37, + Var + 18, + Var + 12), + Bop + (25, + Var + 12, + Var + 8))), + Bop + (151, + Bop + (75, + Bop + (37, + Var + 18, + Var + 12), + Bop + (25, + Var + 12, + Var + 8)), + Var + 50)))), + Var 2730), + Bop + (5461, Var 2730, + Var 1820)), + Var 10922), + Bop + (21845, Var 10922, + Bop + (7281, Var 3640, + Bop + (2427, + Bop + (1213, Var 606, + Var 404), + Bop + (809, Var 404, + Bop + (269, + Var 134, + Bop + (89, + Var 44, + Bop + (29, + Var + 14, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))))))))))), + Var 43690), + Bop + (87381, Var 43690, + Bop + (29127, + Bop + (14563, + Bop + (7281, Var 3640, + Bop + (2427, + Bop + (1213, Var 606, + Var 404), + Bop + (809, Var 404, + Bop + (269, + Var 134, + Bop + (89, + Var 44, + Bop + (29, + Var + 14, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))))))))), + Var 4854), + Bop + (9709, Var 4854, + Var 3236)))), + Var 174762), + Bop (349525, Var 174762, Var 116508)), + Var 699050), + Bop + (1398101, Var 699050, + Bop (466033, Var 233016, Var 155344))), + Var 2796202), + Bop + (5592405, Var 2796202, + Bop + (1864135, + Bop + (932067, + Bop (466033, Var 233016, Var 155344), + Bop + (310689, Var 155344, + Bop + (103563, + Bop (51781, Var 25890, Var 17260), + Bop + (34521, Var 17260, + Bop + (11507, + Bop + (5753, Var 2876, + Bop + (1917, Var 958, + Bop + (639, + Bop + (319, + Bop + (159, + Bop + (79, + Bop + (39, + Bop + (19, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Var 6), + Bop + (13, + Var 6, + Var 4)), + Var 26), + Bop + (53, Var 26, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))))), + Var 106), + Bop + (213, Var 106, + Bop + (71, + Bop + (35, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))), + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)))), + Bop + (23, + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))))), + Bop + (3835, + Bop + (1917, Var 958, + Bop + (639, + Bop + (319, + Bop + (159, + Bop + (79, + Bop + (39, + Bop + (19, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Var 6), + Bop + (13, + Var 6, + Var 4)), + Var 26), + Bop + (53, Var 26, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))))), + Var 106), + Bop + (213, Var 106, + Bop + (71, + Bop + (35, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))), + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)))), + Bop + (23, + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2)))))), + Var 1278)))))), Var 621378))), + Var 11184810), + Bop (22369621, Var 11184810, Var 7456540)), Var 44739242), + Bop + (89478485, Var 44739242, + Bop + (29826161, Var 14913080, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672))))), + Var 178956970), + Bop + (357913941, Var 178956970, + Bop + (119304647, + Bop + (59652323, + Bop + (29826161, Var 14913080, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672))), + Bop + (19884107, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672)), + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448)))), + Bop + (39768215, + Bop + (19884107, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672)), + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448))), + Bop + (13256071, + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448)), Var 4418690))))), + Var 715827882) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }|] +val r10s': string * r[] = + ("one extra node", + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, + [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, + [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0106+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.default.stdout.50.bsl b/tests/fsharp/core/printing/z.output.test.default.stdout.50.bsl new file mode 100644 index 00000000000..de121c1f46e --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.default.stdout.50.bsl @@ -0,0 +1,6263 @@ + +> val repeatId: string = "A" + +> val repeatId: string = "B" + +namespace FSI_0004 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form +val fs: System.Windows.Forms.Form[] = + [|System.Windows.Forms.Form, Text: fs #0; + System.Windows.Forms.Form, Text: fs #1; + System.Windows.Forms.Form, Text: fs #2; + System.Windows.Forms.Form, Text: fs #3; + System.Windows.Forms.Form, Text: fs #4; + System.Windows.Forms.Form, Text: fs #5; + System.Windows.Forms.Form, Text: fs #6; + System.Windows.Forms.Form, Text: fs #7; + System.Windows.Forms.Form, Text: fs #8; + System.Windows.Forms.Form, Text: fs #9; + System.Windows.Forms.Form, Text: fs #10; + System.Windows.Forms.Form, Text: fs #11; + System.Windows.Forms.Form, Text: fs #12; + System.Windows.Forms.Form, Text: fs #13; + System.Windows.Forms.Form, Text: fs #14; + System.Windows.Forms.Form, Text: fs #15; + System.Windows.Forms.Form, Text: fs #16; + System.Windows.Forms.Form, Text: fs #17; + System.Windows.Forms.Form, Text: fs #18; + System.Windows.Forms.Form, Text: fs #19; + System.Windows.Forms.Form, Text: fs #20; + System.Windows.Forms.Form, Text: fs #21; + System.Windows.Forms.Form, Text: fs #22; + System.Windows.Forms.Form, Text: fs #23; + System.Windows.Forms.Form, Text: fs #24; + System.Windows.Forms.Form, Text: fs #25; + System.Windows.Forms.Form, Text: fs #26; + System.Windows.Forms.Form, Text: fs #27; + System.Windows.Forms.Form, Text: fs #28; + System.Windows.Forms.Form, Text: fs #29; + System.Windows.Forms.Form, Text: fs #30; + System.Windows.Forms.Form, Text: fs #31; + System.Windows.Forms.Form, Text: fs #32; + System.Windows.Forms.Form, Text: fs #33; + System.Windows.Forms.Form, Text: fs #34; + System.Windows.Forms.Form, Text: fs #35; + System.Windows.Forms.Form, Text: fs #36; + System.Windows.Forms.Form, Text: fs #37; + System.Windows.Forms.Form, Text: fs #38; + System.Windows.Forms.Form, Text: fs #39; + System.Windows.Forms.Form, Text: fs #40; + System.Windows.Forms.Form, Text: fs #41; + System.Windows.Forms.Form, Text: fs #42; + System.Windows.Forms.Form, Text: fs #43; + System.Windows.Forms.Form, Text: fs #44; + System.Windows.Forms.Form, Text: fs #45; + System.Windows.Forms.Form, Text: fs #46; + System.Windows.Forms.Form, Text: fs #47; + System.Windows.Forms.Form, Text: fs #48; + System.Windows.Forms.Form, Text: fs #49; + System.Windows.Forms.Form, Text: fs #50; + System.Windows.Forms.Form, Text: fs #51; + System.Windows.Forms.Form, Text: fs #52; + System.Windows.Forms.Form, Text: fs #53; + System.Windows.Forms.Form, Text: fs #54; + System.Windows.Forms.Form, Text: fs #55; + System.Windows.Forms.Form, Text: fs #56; + System.Windows.Forms.Form, Text: fs #57; + System.Windows.Forms.Form, Text: fs #58; + System.Windows.Forms.Form, Text: fs #59; + System.Windows.Forms.Form, Text: fs #60; + System.Windows.Forms.Form, Text: fs #61; + System.Windows.Forms.Form, Text: fs #62; + System.Windows.Forms.Form, Text: fs #63; + System.Windows.Forms.Form, Text: fs #64; + System.Windows.Forms.Form, Text: fs #65; + System.Windows.Forms.Form, Text: fs #66; + System.Windows.Forms.Form, Text: fs #67; + System.Windows.Forms.Form, Text: fs #68; + System.Windows.Forms.Form, Text: fs #69; + System.Windows.Forms.Form, Text: fs #70; + System.Windows.Forms.Form, Text: fs #71; + System.Windows.Forms.Form, Text: fs #72; + System.Windows.Forms.Form, Text: fs #73; + System.Windows.Forms.Form, Text: fs #74; + System.Windows.Forms.Form, Text: fs #75; + System.Windows.Forms.Form, Text: fs #76; + System.Windows.Forms.Form, Text: fs #77; + System.Windows.Forms.Form, Text: fs #78; + System.Windows.Forms.Form, Text: fs #79; + System.Windows.Forms.Form, Text: fs #80; + System.Windows.Forms.Form, Text: fs #81; + System.Windows.Forms.Form, Text: fs #82; + System.Windows.Forms.Form, Text: fs #83; + System.Windows.Forms.Form, Text: fs #84; + System.Windows.Forms.Form, Text: fs #85; + System.Windows.Forms.Form, Text: fs #86; + System.Windows.Forms.Form, Text: fs #87; + System.Windows.Forms.Form, Text: fs #88; + System.Windows.Forms.Form, Text: fs #89; + System.Windows.Forms.Form, Text: fs #90; + System.Windows.Forms.Form, Text: fs #91; + System.Windows.Forms.Form, Text: fs #92; + System.Windows.Forms.Form, Text: fs #93; + System.Windows.Forms.Form, Text: fs #94; + System.Windows.Forms.Form, Text: fs #95; + System.Windows.Forms.Form, Text: fs #96; + System.Windows.Forms.Form, Text: fs #97; + System.Windows.Forms.Form, Text: fs #98; + System.Windows.Forms.Form, Text: fs #99; ...|] +val xs: string list = + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...] +val xa: string[] = + [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; + "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; + "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; + "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; + "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; + "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; + "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; + "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; + "98"; "99"; ...|] +val xa2: string[,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] +val sxs0: Set = set [] + +> val sxs1: Set = set ["0"] + +> val sxs2: Set = set ["0"; "1"] + +> val sxs3: Set = set ["0"; "1"; "2"] + +> val sxs4: Set = set ["0"; "1"; "2"; "3"] + +> val sxs200: Set = + set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] + +> val msxs0: Map = map [] + +> val msxs1: Map = map [(0, "0")] + +> val msxs2: Map = map [(0, "0"); (1, "1")] + +> val msxs3: Map = map [(0, "0"); (1, "1"); (2, "2")] + +> val msxs4: Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] + +> val msxs200: Map = + map + [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); + (7, "7"); (8, "8"); ...] + +> module M = + val a: string = "sub-binding" + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option = + (Some (, , , System.Windows.Forms.Form, Text: f1 form), + Some + (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], + ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; + "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; + "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; + "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; + "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; + "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; + "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; + "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; + "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], + [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] + ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] + ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] + ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] + ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] + ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] + ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] + ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]])) +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref = { contents = "value" } +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option = None +val opt4: 'a option option option option +val opt4b: int option option option option = Some (Some (Some None)) +val opt5: int list option option option option option list = + [Some (Some (Some (Some None))); + Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); + Some + (Some + (Some + (Some + (Some + [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; + 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; + 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] +val mkStr: n: int -> string +val strs: string[] = + [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------"; + "---------------------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------"; + "------------------------------------------------------"; + "-------------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------"; + "----------------------------------------------------------"; + "-----------------------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"; + "--------------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[12 chars]; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[18 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[22 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[28 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[36 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[38 chars]|] +val str7s: string[] = + [|""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[310 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[352 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[366 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[380 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[408 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[422 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[436 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[450 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[478 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[492 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[506 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[520 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[548 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[562 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[576 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[590 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[618 chars]; + "-------------------------------------------------------------"+[625 chars]; + "-------------------------------------------------------------"+[632 chars]|] +val grids: string[,] = + [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; + ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] + [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; + "---------"; "----------"; "-----------"; "------------"; "-------------"; + "--------------"; "---------------"; "----------------"; + "-----------------"; "------------------"; "-------------------"; + "--------------------"; "---------------------"; "----------------------"; + "-----------------------"; "------------------------"; + "-------------------------"; "--------------------------"; + "---------------------------"; "----------------------------"; + "-----------------------------"; "------------------------------"; + "-------------------------------"; "--------------------------------"; + "---------------------------------"; "----------------------------------"; + "-----------------------------------"; + "------------------------------------"; + "-------------------------------------"; + "--------------------------------------"; + "---------------------------------------"; + "----------------------------------------"; + "-----------------------------------------"; + "------------------------------------------"; + "-------------------------------------------"; + "--------------------------------------------"; + "---------------------------------------------"; + "----------------------------------------------"; + "-----------------------------------------------"; + "------------------------------------------------"; + "-------------------------------------------------"] + [""; "--"; "----"; "------"; "--------"; "----------"; "------------"; + "--------------"; "----------------"; "------------------"; + "--------------------"; "----------------------"; + "------------------------"; "--------------------------"; + "----------------------------"; "------------------------------"; + "--------------------------------"; "----------------------------------"; + "------------------------------------"; + "--------------------------------------"; + "----------------------------------------"; + "------------------------------------------"; + "--------------------------------------------"; + "----------------------------------------------"; + "------------------------------------------------"; + "--------------------------------------------------"; + "----------------------------------------------------"; + "------------------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------"; + "------------------------------------------------------------"; + "--------------------------------------------------------------"; + "----------------------------------------------------------------"; + "------------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[13 chars]; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[21 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[25 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[33 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[37 chars]] + [""; "---"; "------"; "---------"; "------------"; "---------------"; + "------------------"; "---------------------"; "------------------------"; + "---------------------------"; "------------------------------"; + "---------------------------------"; + "------------------------------------"; + "---------------------------------------"; + "------------------------------------------"; + "---------------------------------------------"; + "------------------------------------------------"; + "---------------------------------------------------"; + "------------------------------------------------------"; + "---------------------------------------------------------"; + "------------------------------------------------------------"; + "---------------------------------------------------------------"; + "------------------------------------------------------------------"; + "---------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[26 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[32 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[50 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[62 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[68 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[77 chars]; + "-------------------------------------------------------------"+[80 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[86 chars]] + [""; "----"; "--------"; "------------"; "----------------"; + "--------------------"; "------------------------"; + "----------------------------"; "--------------------------------"; + "------------------------------------"; + "----------------------------------------"; + "--------------------------------------------"; + "------------------------------------------------"; + "----------------------------------------------------"; + "--------------------------------------------------------"; + "------------------------------------------------------------"; + "----------------------------------------------------------------"; + "--------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[31 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[55 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[63 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[87 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[103 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[111 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[123 chars]; + "-------------------------------------------------------------"+[127 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[135 chars]] + [""; "-----"; "----------"; "---------------"; "--------------------"; + "-------------------------"; "------------------------------"; + "-----------------------------------"; + "----------------------------------------"; + "---------------------------------------------"; + "--------------------------------------------------"; + "-------------------------------------------------------"; + "------------------------------------------------------------"; + "-----------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[54 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[64 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[84 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[94 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[124 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[144 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[154 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[169 chars]; + "-------------------------------------------------------------"+[174 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[184 chars]] + [""; "------"; "------------"; "------------------"; + "------------------------"; "------------------------------"; + "------------------------------------"; + "------------------------------------------"; + "------------------------------------------------"; + "------------------------------------------------------"; + "------------------------------------------------------------"; + "------------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[77 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[113 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[125 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[161 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[185 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[197 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[215 chars]; + "-------------------------------------------------------------"+[221 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[233 chars]] + [""; "-------"; "--------------"; "---------------------"; + "----------------------------"; "-----------------------------------"; + "------------------------------------------"; + "-------------------------------------------------"; + "--------------------------------------------------------"; + "---------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[86 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[100 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[114 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[142 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[156 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[184 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[198 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[226 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[240 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[268 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[282 chars]] + [""; "--------"; "----------------"; "------------------------"; + "--------------------------------"; + "----------------------------------------"; + "------------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[123 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[171 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[187 chars]; + "-------------------------------------------------------------"+[195 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[235 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[267 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[283 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[307 chars]; + "-------------------------------------------------------------"+[315 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[331 chars]] + [""; "---------"; "------------------"; "---------------------------"; + "------------------------------------"; + "---------------------------------------------"; + "------------------------------------------------------"; + "---------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[20 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[92 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[110 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[128 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[146 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[182 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[200 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[218 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[236 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[272 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[290 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[308 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[326 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[344 chars]; + "-------------------------------------------------------------"+[353 chars]; + "-------------------------------------------------------------"+[362 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[380 chars]] + [""; "----------"; "--------------------"; "------------------------------"; + "----------------------------------------"; + "--------------------------------------------------"; + "------------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[39 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[139 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[169 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[189 chars]; + "-------------------------------------------------------------"+[199 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[229 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[249 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[279 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[309 chars]; + "-------------------------------------------------------------"+[319 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[339 chars]; + "-------------------------------------------------------------"+[349 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[369 chars]; + "-------------------------------------------------------------"+[379 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[399 chars]; + "-------------------------------------------------------------"+[409 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[429 chars]] + [""; "-----------"; "----------------------"; + "---------------------------------"; + "--------------------------------------------"; + "-------------------------------------------------------"; + "------------------------------------------------------------------"; + "-------------------------------------------------------------"+[16 chars]; + "-------------------------------------------------------------"+[27 chars]; + "-------------------------------------------------------------"+[38 chars]; + "-------------------------------------------------------------"+[49 chars]; + "-------------------------------------------------------------"+[60 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[82 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[126 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[148 chars]; + "-------------------------------------------------------------"+[159 chars]; + "-------------------------------------------------------------"+[170 chars]; + "-------------------------------------------------------------"+[181 chars]; + "-------------------------------------------------------------"+[192 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[214 chars]; + "-------------------------------------------------------------"+[225 chars]; + "-------------------------------------------------------------"+[236 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[258 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[280 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[302 chars]; + "-------------------------------------------------------------"+[313 chars]; + "-------------------------------------------------------------"+[324 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[346 chars]; + "-------------------------------------------------------------"+[357 chars]; + "-------------------------------------------------------------"+[368 chars]; + "-------------------------------------------------------------"+[379 chars]; + "-------------------------------------------------------------"+[390 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[412 chars]; + "-------------------------------------------------------------"+[423 chars]; + "-------------------------------------------------------------"+[434 chars]; + "-------------------------------------------------------------"+[445 chars]; + "-------------------------------------------------------------"+[456 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[478 chars]] + [""; "------------"; "------------------------"; + "------------------------------------"; + "------------------------------------------------"; + "------------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[71 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[203 chars]; + "-------------------------------------------------------------"+[215 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[287 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[311 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[347 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[383 chars]; + "-------------------------------------------------------------"+[395 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[431 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[455 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[491 chars]; + "-------------------------------------------------------------"+[503 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[527 chars]] + [""; "-------------"; "--------------------------"; + "---------------------------------------"; + "----------------------------------------------------"; + "-----------------------------------------------------------------"; + "-------------------------------------------------------------"+[17 chars]; + "-------------------------------------------------------------"+[30 chars]; + "-------------------------------------------------------------"+[43 chars]; + "-------------------------------------------------------------"+[56 chars]; + "-------------------------------------------------------------"+[69 chars]; + "-------------------------------------------------------------"+[82 chars]; + "-------------------------------------------------------------"+[95 chars]; + "-------------------------------------------------------------"+[108 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[160 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[186 chars]; + "-------------------------------------------------------------"+[199 chars]; + "-------------------------------------------------------------"+[212 chars]; + "-------------------------------------------------------------"+[225 chars]; + "-------------------------------------------------------------"+[238 chars]; + "-------------------------------------------------------------"+[251 chars]; + "-------------------------------------------------------------"+[264 chars]; + "-------------------------------------------------------------"+[277 chars]; + "-------------------------------------------------------------"+[290 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[316 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[342 chars]; + "-------------------------------------------------------------"+[355 chars]; + "-------------------------------------------------------------"+[368 chars]; + "-------------------------------------------------------------"+[381 chars]; + "-------------------------------------------------------------"+[394 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[420 chars]; + "-------------------------------------------------------------"+[433 chars]; + "-------------------------------------------------------------"+[446 chars]; + "-------------------------------------------------------------"+[459 chars]; + "-------------------------------------------------------------"+[472 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[498 chars]; + "-------------------------------------------------------------"+[511 chars]; + "-------------------------------------------------------------"+[524 chars]; + "-------------------------------------------------------------"+[537 chars]; + "-------------------------------------------------------------"+[550 chars]; + "-------------------------------------------------------------"+[563 chars]; + "-------------------------------------------------------------"+[576 chars]] + [""; "--------------"; "----------------------------"; + "------------------------------------------"; + "--------------------------------------------------------"; + "----------------------------------------------------------------------"; + "-------------------------------------------------------------"+[23 chars]; + "-------------------------------------------------------------"+[37 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[79 chars]; + "-------------------------------------------------------------"+[93 chars]; + "-------------------------------------------------------------"+[107 chars]; + "-------------------------------------------------------------"+[121 chars]; + "-------------------------------------------------------------"+[135 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[219 chars]; + "-------------------------------------------------------------"+[233 chars]; + "-------------------------------------------------------------"+[247 chars]; + "-------------------------------------------------------------"+[261 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[289 chars]; + "-------------------------------------------------------------"+[303 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[331 chars]; + "-------------------------------------------------------------"+[345 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[373 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[401 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[429 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[457 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[485 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[513 chars]; + "-------------------------------------------------------------"+[527 chars]; + "-------------------------------------------------------------"+[541 chars]; + "-------------------------------------------------------------"+[555 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[583 chars]; + "-------------------------------------------------------------"+[597 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[625 chars]] + [""; "---------------"; "------------------------------"; + "---------------------------------------------"; + "------------------------------------------------------------"; + "-------------------------------------------------------------"+[14 chars]; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[44 chars]; + "-------------------------------------------------------------"+[59 chars]; + "-------------------------------------------------------------"+[74 chars]; + "-------------------------------------------------------------"+[89 chars]; + "-------------------------------------------------------------"+[104 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[134 chars]; + "-------------------------------------------------------------"+[149 chars]; + "-------------------------------------------------------------"+[164 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[194 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[224 chars]; + "-------------------------------------------------------------"+[239 chars]; + "-------------------------------------------------------------"+[254 chars]; + "-------------------------------------------------------------"+[269 chars]; + "-------------------------------------------------------------"+[284 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[314 chars]; + "-------------------------------------------------------------"+[329 chars]; + "-------------------------------------------------------------"+[344 chars]; + "-------------------------------------------------------------"+[359 chars]; + "-------------------------------------------------------------"+[374 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[404 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[434 chars]; + "-------------------------------------------------------------"+[449 chars]; + "-------------------------------------------------------------"+[464 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[494 chars]; + "-------------------------------------------------------------"+[509 chars]; + "-------------------------------------------------------------"+[524 chars]; + "-------------------------------------------------------------"+[539 chars]; + "-------------------------------------------------------------"+[554 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[584 chars]; + "-------------------------------------------------------------"+[599 chars]; + "-------------------------------------------------------------"+[614 chars]; + "-------------------------------------------------------------"+[629 chars]; + "-------------------------------------------------------------"+[644 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[674 chars]] + [""; "----------------"; "--------------------------------"; + "------------------------------------------------"; + "----------------------------------------------------------------"; + "-------------------------------------------------------------"+[19 chars]; + "-------------------------------------------------------------"+[35 chars]; + "-------------------------------------------------------------"+[51 chars]; + "-------------------------------------------------------------"+[67 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[99 chars]; + "-------------------------------------------------------------"+[115 chars]; + "-------------------------------------------------------------"+[131 chars]; + "-------------------------------------------------------------"+[147 chars]; + "-------------------------------------------------------------"+[163 chars]; + "-------------------------------------------------------------"+[179 chars]; + "-------------------------------------------------------------"+[195 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[259 chars]; + "-------------------------------------------------------------"+[275 chars]; + "-------------------------------------------------------------"+[291 chars]; + "-------------------------------------------------------------"+[307 chars]; + "-------------------------------------------------------------"+[323 chars]; + "-------------------------------------------------------------"+[339 chars]; + "-------------------------------------------------------------"+[355 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[387 chars]; + "-------------------------------------------------------------"+[403 chars]; + "-------------------------------------------------------------"+[419 chars]; + "-------------------------------------------------------------"+[435 chars]; + "-------------------------------------------------------------"+[451 chars]; + "-------------------------------------------------------------"+[467 chars]; + "-------------------------------------------------------------"+[483 chars]; + "-------------------------------------------------------------"+[499 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[531 chars]; + "-------------------------------------------------------------"+[547 chars]; + "-------------------------------------------------------------"+[563 chars]; + "-------------------------------------------------------------"+[579 chars]; + "-------------------------------------------------------------"+[595 chars]; + "-------------------------------------------------------------"+[611 chars]; + "-------------------------------------------------------------"+[627 chars]; + "-------------------------------------------------------------"+[643 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[675 chars]; + "-------------------------------------------------------------"+[691 chars]; + "-------------------------------------------------------------"+[707 chars]; + "-------------------------------------------------------------"+[723 chars]] + [""; "-----------------"; "----------------------------------"; + "---------------------------------------------------"; + "--------------------------------------------------------------------"; + "-------------------------------------------------------------"+[24 chars]; + "-------------------------------------------------------------"+[41 chars]; + "-------------------------------------------------------------"+[58 chars]; + "-------------------------------------------------------------"+[75 chars]; + "-------------------------------------------------------------"+[92 chars]; + "-------------------------------------------------------------"+[109 chars]; + "-------------------------------------------------------------"+[126 chars]; + "-------------------------------------------------------------"+[143 chars]; + "-------------------------------------------------------------"+[160 chars]; + "-------------------------------------------------------------"+[177 chars]; + "-------------------------------------------------------------"+[194 chars]; + "-------------------------------------------------------------"+[211 chars]; + "-------------------------------------------------------------"+[228 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[262 chars]; + "-------------------------------------------------------------"+[279 chars]; + "-------------------------------------------------------------"+[296 chars]; + "-------------------------------------------------------------"+[313 chars]; + "-------------------------------------------------------------"+[330 chars]; + "-------------------------------------------------------------"+[347 chars]; + "-------------------------------------------------------------"+[364 chars]; + "-------------------------------------------------------------"+[381 chars]; + "-------------------------------------------------------------"+[398 chars]; + "-------------------------------------------------------------"+[415 chars]; + "-------------------------------------------------------------"+[432 chars]; + "-------------------------------------------------------------"+[449 chars]; + "-------------------------------------------------------------"+[466 chars]; + "-------------------------------------------------------------"+[483 chars]; + "-------------------------------------------------------------"+[500 chars]; + "-------------------------------------------------------------"+[517 chars]; + "-------------------------------------------------------------"+[534 chars]; + "-------------------------------------------------------------"+[551 chars]; + "-------------------------------------------------------------"+[568 chars]; + "-------------------------------------------------------------"+[585 chars]; + "-------------------------------------------------------------"+[602 chars]; + "-------------------------------------------------------------"+[619 chars]; + "-------------------------------------------------------------"+[636 chars]; + "-------------------------------------------------------------"+[653 chars]; + "-------------------------------------------------------------"+[670 chars]; + "-------------------------------------------------------------"+[687 chars]; + "-------------------------------------------------------------"+[704 chars]; + "-------------------------------------------------------------"+[721 chars]; + "-------------------------------------------------------------"+[738 chars]; + "-------------------------------------------------------------"+[755 chars]; + "-------------------------------------------------------------"+[772 chars]] + [""; "------------------"; "------------------------------------"; + "------------------------------------------------------"; + "------------------------------------------------------------------------"; + "-------------------------------------------------------------"+[29 chars]; + "-------------------------------------------------------------"+[47 chars]; + "-------------------------------------------------------------"+[65 chars]; + "-------------------------------------------------------------"+[83 chars]; + "-------------------------------------------------------------"+[101 chars]; + "-------------------------------------------------------------"+[119 chars]; + "-------------------------------------------------------------"+[137 chars]; + "-------------------------------------------------------------"+[155 chars]; + "-------------------------------------------------------------"+[173 chars]; + "-------------------------------------------------------------"+[191 chars]; + "-------------------------------------------------------------"+[209 chars]; + "-------------------------------------------------------------"+[227 chars]; + "-------------------------------------------------------------"+[245 chars]; + "-------------------------------------------------------------"+[263 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[299 chars]; + "-------------------------------------------------------------"+[317 chars]; + "-------------------------------------------------------------"+[335 chars]; + "-------------------------------------------------------------"+[353 chars]; + "-------------------------------------------------------------"+[371 chars]; + "-------------------------------------------------------------"+[389 chars]; + "-------------------------------------------------------------"+[407 chars]; + "-------------------------------------------------------------"+[425 chars]; + "-------------------------------------------------------------"+[443 chars]; + "-------------------------------------------------------------"+[461 chars]; + "-------------------------------------------------------------"+[479 chars]; + "-------------------------------------------------------------"+[497 chars]; + "-------------------------------------------------------------"+[515 chars]; + "-------------------------------------------------------------"+[533 chars]; + "-------------------------------------------------------------"+[551 chars]; + "-------------------------------------------------------------"+[569 chars]; + "-------------------------------------------------------------"+[587 chars]; + "-------------------------------------------------------------"+[605 chars]; + "-------------------------------------------------------------"+[623 chars]; + "-------------------------------------------------------------"+[641 chars]; + "-------------------------------------------------------------"+[659 chars]; + "-------------------------------------------------------------"+[677 chars]; + "-------------------------------------------------------------"+[695 chars]; + "-------------------------------------------------------------"+[713 chars]; + "-------------------------------------------------------------"+[731 chars]; + "-------------------------------------------------------------"+[749 chars]; + "-------------------------------------------------------------"+[767 chars]; + "-------------------------------------------------------------"+[785 chars]; + "-------------------------------------------------------------"+[803 chars]; + "-------------------------------------------------------------"+[821 chars]] + [""; "-------------------"; "--------------------------------------"; + "---------------------------------------------------------"; + "-------------------------------------------------------------"+[15 chars]; + "-------------------------------------------------------------"+[34 chars]; + "-------------------------------------------------------------"+[53 chars]; + "-------------------------------------------------------------"+[72 chars]; + "-------------------------------------------------------------"+[91 chars]; + "-------------------------------------------------------------"+[110 chars]; + "-------------------------------------------------------------"+[129 chars]; + "-------------------------------------------------------------"+[148 chars]; + "-------------------------------------------------------------"+[167 chars]; + "-------------------------------------------------------------"+[186 chars]; + "-------------------------------------------------------------"+[205 chars]; + "-------------------------------------------------------------"+[224 chars]; + "-------------------------------------------------------------"+[243 chars]; + "-------------------------------------------------------------"+[262 chars]; + "-------------------------------------------------------------"+[281 chars]; + "-------------------------------------------------------------"+[300 chars]; + "-------------------------------------------------------------"+[319 chars]; + "-------------------------------------------------------------"+[338 chars]; + "-------------------------------------------------------------"+[357 chars]; + "-------------------------------------------------------------"+[376 chars]; + "-------------------------------------------------------------"+[395 chars]; + "-------------------------------------------------------------"+[414 chars]; + "-------------------------------------------------------------"+[433 chars]; + "-------------------------------------------------------------"+[452 chars]; + "-------------------------------------------------------------"+[471 chars]; + "-------------------------------------------------------------"+[490 chars]; + "-------------------------------------------------------------"+[509 chars]; + "-------------------------------------------------------------"+[528 chars]; + "-------------------------------------------------------------"+[547 chars]; + "-------------------------------------------------------------"+[566 chars]; + "-------------------------------------------------------------"+[585 chars]; + "-------------------------------------------------------------"+[604 chars]; + "-------------------------------------------------------------"+[623 chars]; + "-------------------------------------------------------------"+[642 chars]; + "-------------------------------------------------------------"+[661 chars]; + "-------------------------------------------------------------"+[680 chars]; + "-------------------------------------------------------------"+[699 chars]; + "-------------------------------------------------------------"+[718 chars]; + "-------------------------------------------------------------"+[737 chars]; + "-------------------------------------------------------------"+[756 chars]; + "-------------------------------------------------------------"+[775 chars]; + "-------------------------------------------------------------"+[794 chars]; + "-------------------------------------------------------------"+[813 chars]; + "-------------------------------------------------------------"+[832 chars]; + "-------------------------------------------------------------"+[851 chars]; + "-------------------------------------------------------------"+[870 chars]; + ...] + ...] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree = + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] + +> [Building 2 6...done] +val tree_2_6: tree = + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]] + +> [Building 2 8...done] +val tree_2_8: tree = + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]] + +> [Building 2 10...done] +val tree_2_10: tree = + N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N ...; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 2 12...done] +val tree_2_12: tree = + N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 2 14...done] +val tree_2_14: tree = + N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]]; + N [N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]]; + N [N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]]; + N [N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]]; + N [N [N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]; + N [N [N [L; L]; N [L; L]]; + N [N [L; L]; N [L; L]]]]; + N [N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 3 8...done] +val tree_3_8: tree = + N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; + N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; + N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; + N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; + N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; + N [N [L; L; L]; N [L; L; L]; N [L; ...]; ...]; ...]; ...]; + ...]; ...]; ...]; ...] + +> [Building 4 8...done] +val tree_4_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]]; + N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]]; + N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]]; + N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; + N [L; L; L; L]]; + N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; ...]; ...]; + ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 8...done] +val tree_5_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]]; + N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]]; + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N ...; ...]; ...]; ...]; ...]; ...]; + ...]; ...] + +> [Building 6 8...done] +val tree_6_8: tree = + N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; + N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; + N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; + N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; ...] + +> [Building 5 3...done] +val tree_5_3: tree = + N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]; + N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; + N [L; L; L; L; L]; N [L; L; L; L; L]]] + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list = + [Bop (1, Var 0, Var 0); Var 2; + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)); Var 4; + Bop (5, Var 2, Bop (1, Var 0, Var 0)); Var 6; + Bop (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2); + Var 8; + Bop (9, Var 4, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))); + Var 10; + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), Var 2)))); + Var 21342314; Var 3214; Bop (1231357, Var 615678, Var 410452); + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)); + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)); + Var 2435234; + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502)))), + Bop + (459139, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))), + Var 153046)))); + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)); + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))), + Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)))), + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38))), + Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114))), + Bop (24302059, Bop (12151029, ..., ...), ...))), ...)); ...] + +> module Exprs = + val x1: X = + Bop + (213, Var 106, + Bop + (71, + Bop + (35, Bop (17, Var 8, Bop (5, Var 2, Bop (1, Var 0, Var 0))), + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)))), + Bop + (23, + Bop + (11, Bop (5, Var 2, Bop (1, Var 0, Var 0)), + Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0))), + Bop + (7, Bop (3, Bop (1, Var 0, Var 0), Bop (1, Var 0, Var 0)), + Var 2)))) + val x2: X = Var 21342314 + val x3: X = Var 3214 + val x4: X = Bop (1231357, Var 615678, Var 410452) + val x5: X = + Bop + (5234547, Bop (2617273, Var 1308636, Var 872424), + Bop (1744849, Var 872424, Var 581616)) + val x6: X = + Bop + (923759825, Var 461879912, Bop (307919941, Var 153959970, Var 102639980)) + val x7: X = Var 2435234 + val x8: X = + Bop + (12396777, Var 6198388, + Bop + (4132259, + Bop + (2066129, Var 1033064, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))))), + Bop + (1377419, + Bop + (688709, Var 344354, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502)))), + Bop + (459139, + Bop + (229569, Var 114784, + Bop + (76523, + Bop + (38261, Var 19130, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472)))), + Bop + (25507, + Bop + (12753, Var 6376, + Bop + (4251, Bop (2125, Var 1062, Var 708), + Bop (1417, Var 708, Var 472))), Var 8502))), + Var 153046)))) + val x9: X = + Bop + (3333333, Var 1666666, + Bop + (1111111, + Bop + (555555, Bop (277777, Var 138888, Var 92592), + Bop (185185, Var 92592, Var 61728)), Var 370370)) + val x10: X = + Bop + (1312311237, Var 656155618, + Bop + (437437079, + Bop + (218718539, + Bop + (109359269, Var 54679634, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)))), + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114))), + Bop + (24302059, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))))), + Var 6250), + Bop + (12501, Var 6250, + Bop + (4167, + Bop + (2083, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6))), + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38))), Var 694), + Bop + (1389, Var 694, + Bop + (463, + Bop + (231, + Bop + (115, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + Bop + (3, + Bop + (1, + Var 0, + Var 0), + Bop + (1, + Var 0, + Var 0))), + Var 6)), + Var 38), + Bop + (77, Var 38, + Bop + (25, Var 12, Var 8))), + Var 154)))))), Var 75006))), + Var 1350114)), Var 8100686))), + Bop + (145812359, + Bop + (72906179, + Bop + (36453089, Var 18226544, + Bop + (12151029, Var 6075514, + Bop + (4050343, + Bop + (2025171, Bop (1012585, Var 506292, Var 337528), + Bop + (675057, Var 337528, + Bop + (225019, + Bop + (112509, Var 56254, + Bop + (37503, + Bop + (18751, + Bop + (9375, + Bop + (4687, + Bop + (2343, + Bop + (1171, + Bop + (585, Var 292, + Bop + (195, + Bop + (97, Var 48, + Var 32), + Bop + (65, Var 32, + Bop + (21, Var 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))), + Var 390), + Bop + (781, Var 390, Var 260)), + Var 1562), + Bop + (3125, Var 1562, + Bop + (1041, Var 520, + Bop + (347, + Bop + (173, Var 86, + Bop + (57, Var 28, + Bop + (19, + Bop + (9, Var 4, + ...), ...))), + ...)))), ...), ...)), + ...))), ...))), ...), ...))) + val x11: X = + Bop + (2147483647, + Bop + (1073741823, + Bop + (536870911, + Bop + (268435455, + Bop + (134217727, + Bop + (67108863, + Bop + (33554431, + Bop + (16777215, + Bop + (8388607, + Bop + (4194303, + Bop + (2097151, + Bop + (1048575, + Bop + (524287, + Bop + (262143, + Bop + (131071, + Bop + (65535, + Bop + (32767, + Bop + (16383, + Bop + (8191, + Bop + (4095, + Bop + (2047, + Bop + (1023, + Bop + (511, + Bop + (255, + Bop + (127, + Bop + (63, + Bop + (31, + Bop + (15, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2), + Bop + (5, + Var + 2, + Bop + (1, + Var + 0, + Var + 0))), + Var + 10), + Bop + (21, + Var + 10, + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var + 2))), + Var + 42), + Bop + (85, + Var + 42, + Var + 28)), + Var + 170), + Bop + (341, + Var + 170, + Bop + (113, + Var + 56, + Bop + (37, + Var + 18, + Var + 12)))), + Var 682), + Bop + (1365, + Var 682, + Bop + (455, + Bop + (227, + Bop + (113, + Var + 56, + Bop + (37, + Var + 18, + Var + 12)), + Bop + (75, + Bop + (37, + Var + 18, + Var + 12), + Bop + (25, + Var + 12, + Var + 8))), + Bop + (151, + Bop + (75, + Bop + (37, + Var + 18, + Var + 12), + Bop + (25, + Var + 12, + Var + 8)), + Var + 50)))), + Var 2730), + Bop + (5461, Var 2730, + Var 1820)), + Var 10922), + Bop + (21845, Var 10922, + Bop + (7281, Var 3640, + Bop + (2427, + Bop + (1213, Var 606, + Var 404), + Bop + (809, Var 404, + Bop + (269, + Var 134, + Bop + (89, + Var 44, + Bop + (29, + Var + 14, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))))))))))), + Var 43690), + Bop + (87381, Var 43690, + Bop + (29127, + Bop + (14563, + Bop + (7281, Var 3640, + Bop + (2427, + Bop + (1213, Var 606, + Var 404), + Bop + (809, Var 404, + Bop + (269, + Var 134, + Bop + (89, + Var 44, + Bop + (29, + Var + 14, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))))))))), + Var 4854), + Bop + (9709, Var 4854, + Var 3236)))), + Var 174762), + Bop (349525, Var 174762, Var 116508)), + Var 699050), + Bop + (1398101, Var 699050, + Bop (466033, Var 233016, Var 155344))), + Var 2796202), + Bop + (5592405, Var 2796202, + Bop + (1864135, + Bop + (932067, + Bop (466033, Var 233016, Var 155344), + Bop + (310689, Var 155344, + Bop + (103563, + Bop (51781, Var 25890, Var 17260), + Bop + (34521, Var 17260, + Bop + (11507, + Bop + (5753, Var 2876, + Bop + (1917, Var 958, + Bop + (639, + Bop + (319, + Bop + (159, + Bop + (79, + Bop + (39, + Bop + (19, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Var 6), + Bop + (13, + Var 6, + Var 4)), + Var 26), + Bop + (53, Var 26, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))))), + Var 106), + Bop + (213, Var 106, + Bop + (71, + Bop + (35, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))), + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)))), + Bop + (23, + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2))))))), + Bop + (3835, + Bop + (1917, Var 958, + Bop + (639, + Bop + (319, + Bop + (159, + Bop + (79, + Bop + (39, + Bop + (19, + Bop + (9, + Var + 4, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Var 6), + Bop + (13, + Var 6, + Var 4)), + Var 26), + Bop + (53, Var 26, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))))), + Var 106), + Bop + (213, Var 106, + Bop + (71, + Bop + (35, + Bop + (17, + Var 8, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0))), + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)))), + Bop + (23, + Bop + (11, + Bop + (5, + Var 2, + Bop + (1, + Var + 0, + Var + 0)), + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0))), + Bop + (7, + Bop + (3, + Bop + (1, + Var + 0, + Var + 0), + Bop + (1, + Var + 0, + Var + 0)), + Var 2)))))), + Var 1278)))))), Var 621378))), + Var 11184810), + Bop (22369621, Var 11184810, Var 7456540)), Var 44739242), + Bop + (89478485, Var 44739242, + Bop + (29826161, Var 14913080, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672))))), + Var 178956970), + Bop + (357913941, Var 178956970, + Bop + (119304647, + Bop + (59652323, + Bop + (29826161, Var 14913080, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672))), + Bop + (19884107, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672)), + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448)))), + Bop + (39768215, + Bop + (19884107, + Bop + (9942053, Var 4971026, + Bop (3314017, Var 1657008, Var 1104672)), + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448))), + Bop + (13256071, + Bop + (6628035, Bop (3314017, Var 1657008, Var 1104672), + Bop (2209345, Var 1104672, Var 736448)), Var 4418690))))), + Var 715827882) + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C = +val csA: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csB: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] +val csC: C[] = + [|; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; + ; ; ...|] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn = Abc +val exA2: exn = AbcInt 2 +val exA3: exn = AbcString "3" +val exA4: exn = AbcExn [Abc; AbcInt 2; AbcString "3"] +val exA5: exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn = Ex0 +val exU: exn = ExUnit () +val exUs: exn = ExUnits ((), ()) +val exUSome: exn = ExUnitOption (Some ()) +val exUNone: exn = ExUnitOption None +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 = AT4063 12 + +> val valAT3063_True: bool T4063 = AT4063 true + +> val valAT3063_text: string T4063 = AT4063 "text" + +> val valAT3063_null: System.Object T4063 = AT4063 null + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] = [|12uy; 13uy; 14uy|] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #r "nuget:FSharp.Data, 3.1.2";; // Load Nuget Package 'FSharp.Data' version '3.1.2' + #r "nuget:FSharp.Data";; // Load Nuget Package 'FSharp.Data' with the highest version + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r = { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 } +val r10s: r[] = + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }|] +val r10s': string * r[] = + ("one extra node", + [|{ f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }; + { f0 = 0 + f1 = 1 + f2 = 2 + f3 = 3 + f4 = 4 + f5 = 5 + f6 = 6 + f7 = 7 + f8 = 8 + f9 = 9 }|]) + +> val x1564_A1: int = 1 + + +--> Added '\' to library include path + +val x1564_A2: int = 2 + + +--> Added '\' to library include path + +val x1564_A3: int = 3 + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int = 1 + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int = 1 + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string = + "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] + val x90: string = + "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] + val x80: string = + "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] + val x75: string = + "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] + val x74: string = + "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] + val x73: string = + "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] + val x72: string = + "012345678901234567890123456789012345678901234567890123456789012345678901" + val x71: string = + "01234567890123456789012345678901234567890123456789012345678901234567890" + val x70: string = + "0123456789012345678901234567890123456789012345678901234567890123456789" +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list = [1; 2; 3] + val xArray: int[] = [|1; 2; 3|] + val xString: string = "abcdef" + val xOption: int option = Some 12 + val xArray2: (int * int)[,] = [[(0, 0); (0, 1)] + [(1, 0); (1, 1)]] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, + [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list = + (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, + [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D = D(1) + val dB: D = D(2) + val dAB: D * D * D list = (D(1), D(2), [D(1); D(2)]) + val dC: D = D(True) + val boxed_dABC: obj list = [D(1); D(2); D(True)] +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqFindFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +val seqPickFailure: Either = + That + ("System.Collections.Generic.KeyNotFoundException", + "An index satisfying the predicate was not found in the collection.") +module Regression5218 = + val t1: int = 1 + val t2: int * int = (1, 2) + val t3: int * int * int = (1, 2, 3) + val t4: int * int * int * int = (1, 2, 3, 4) + val t5: int * int * int * int * int = (1, 2, 3, 4, 5) + val t6: int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) + val t7: int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) + val t8: int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8) + val t9: int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9) + val t10: int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val t11: int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val t12: + int * int * int * int * int * int * int * int * int * int * int * int = + (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 = FSI_0106+Regression4469 +val it: unit = () + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf +module Regression1019_long = + val double_nan: float = nan + val double_infinity: float = infinity + val single_nan: float32 = nanf + val single_infinity: float32 = infinityf + +> val it: int ref = { contents = 1 } + +> val x: int ref = { contents = 1 } +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string = + "Regression4927: Expect error due to duplicate methods in the "+[20 chars] + +> > val note_ExpectDupProperty: string = + "Regression4927: Expect error due to duplicate properties in t"+[23 chars] + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU = Case1 (5, "") +val namedFieldVar2: MyDU = Case7 25 + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn = MyNamedException1 (5, "") +val namedEx2: exn = MyNamedException7 25 + +> type optionRecord = + { x: int option } +val x: optionRecord = { x = None } + +> type optionRecord = + { x: obj } +val x: optionRecord = { x = null } + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool = true + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int = 1 + +> module op_Addition = + val x: int = 1 + +> module ``land`` = + val x: int = 1 + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int = 2 + +> val (mod) : int = 2 + +> val ``or`` : int = 2 + +> val ``land`` : int = 2 + +> val ``.ctor`` : int = 2 + +> val ``.cctor`` : int = 2 + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.default.stdout.bsl b/tests/fsharp/core/printing/z.output.test.default.stdout.bsl deleted file mode 100644 index f861d11fef2..00000000000 --- a/tests/fsharp/core/printing/z.output.test.default.stdout.bsl +++ /dev/null @@ -1,6268 +0,0 @@ - -> > val repeatId : string = "A" - -> val repeatId : string = "B" - -namespace FSI_0004 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0005 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0005 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -> val x1 : seq -val x2 : seq -val x3 : seq -val f1 : System.Windows.Forms.Form = System.Windows.Forms.Form, Text: f1 form -val fs : System.Windows.Forms.Form [] = - [|System.Windows.Forms.Form, Text: fs #0; - System.Windows.Forms.Form, Text: fs #1; - System.Windows.Forms.Form, Text: fs #2; - System.Windows.Forms.Form, Text: fs #3; - System.Windows.Forms.Form, Text: fs #4; - System.Windows.Forms.Form, Text: fs #5; - System.Windows.Forms.Form, Text: fs #6; - System.Windows.Forms.Form, Text: fs #7; - System.Windows.Forms.Form, Text: fs #8; - System.Windows.Forms.Form, Text: fs #9; - System.Windows.Forms.Form, Text: fs #10; - System.Windows.Forms.Form, Text: fs #11; - System.Windows.Forms.Form, Text: fs #12; - System.Windows.Forms.Form, Text: fs #13; - System.Windows.Forms.Form, Text: fs #14; - System.Windows.Forms.Form, Text: fs #15; - System.Windows.Forms.Form, Text: fs #16; - System.Windows.Forms.Form, Text: fs #17; - System.Windows.Forms.Form, Text: fs #18; - System.Windows.Forms.Form, Text: fs #19; - System.Windows.Forms.Form, Text: fs #20; - System.Windows.Forms.Form, Text: fs #21; - System.Windows.Forms.Form, Text: fs #22; - System.Windows.Forms.Form, Text: fs #23; - System.Windows.Forms.Form, Text: fs #24; - System.Windows.Forms.Form, Text: fs #25; - System.Windows.Forms.Form, Text: fs #26; - System.Windows.Forms.Form, Text: fs #27; - System.Windows.Forms.Form, Text: fs #28; - System.Windows.Forms.Form, Text: fs #29; - System.Windows.Forms.Form, Text: fs #30; - System.Windows.Forms.Form, Text: fs #31; - System.Windows.Forms.Form, Text: fs #32; - System.Windows.Forms.Form, Text: fs #33; - System.Windows.Forms.Form, Text: fs #34; - System.Windows.Forms.Form, Text: fs #35; - System.Windows.Forms.Form, Text: fs #36; - System.Windows.Forms.Form, Text: fs #37; - System.Windows.Forms.Form, Text: fs #38; - System.Windows.Forms.Form, Text: fs #39; - System.Windows.Forms.Form, Text: fs #40; - System.Windows.Forms.Form, Text: fs #41; - System.Windows.Forms.Form, Text: fs #42; - System.Windows.Forms.Form, Text: fs #43; - System.Windows.Forms.Form, Text: fs #44; - System.Windows.Forms.Form, Text: fs #45; - System.Windows.Forms.Form, Text: fs #46; - System.Windows.Forms.Form, Text: fs #47; - System.Windows.Forms.Form, Text: fs #48; - System.Windows.Forms.Form, Text: fs #49; - System.Windows.Forms.Form, Text: fs #50; - System.Windows.Forms.Form, Text: fs #51; - System.Windows.Forms.Form, Text: fs #52; - System.Windows.Forms.Form, Text: fs #53; - System.Windows.Forms.Form, Text: fs #54; - System.Windows.Forms.Form, Text: fs #55; - System.Windows.Forms.Form, Text: fs #56; - System.Windows.Forms.Form, Text: fs #57; - System.Windows.Forms.Form, Text: fs #58; - System.Windows.Forms.Form, Text: fs #59; - System.Windows.Forms.Form, Text: fs #60; - System.Windows.Forms.Form, Text: fs #61; - System.Windows.Forms.Form, Text: fs #62; - System.Windows.Forms.Form, Text: fs #63; - System.Windows.Forms.Form, Text: fs #64; - System.Windows.Forms.Form, Text: fs #65; - System.Windows.Forms.Form, Text: fs #66; - System.Windows.Forms.Form, Text: fs #67; - System.Windows.Forms.Form, Text: fs #68; - System.Windows.Forms.Form, Text: fs #69; - System.Windows.Forms.Form, Text: fs #70; - System.Windows.Forms.Form, Text: fs #71; - System.Windows.Forms.Form, Text: fs #72; - System.Windows.Forms.Form, Text: fs #73; - System.Windows.Forms.Form, Text: fs #74; - System.Windows.Forms.Form, Text: fs #75; - System.Windows.Forms.Form, Text: fs #76; - System.Windows.Forms.Form, Text: fs #77; - System.Windows.Forms.Form, Text: fs #78; - System.Windows.Forms.Form, Text: fs #79; - System.Windows.Forms.Form, Text: fs #80; - System.Windows.Forms.Form, Text: fs #81; - System.Windows.Forms.Form, Text: fs #82; - System.Windows.Forms.Form, Text: fs #83; - System.Windows.Forms.Form, Text: fs #84; - System.Windows.Forms.Form, Text: fs #85; - System.Windows.Forms.Form, Text: fs #86; - System.Windows.Forms.Form, Text: fs #87; - System.Windows.Forms.Form, Text: fs #88; - System.Windows.Forms.Form, Text: fs #89; - System.Windows.Forms.Form, Text: fs #90; - System.Windows.Forms.Form, Text: fs #91; - System.Windows.Forms.Form, Text: fs #92; - System.Windows.Forms.Form, Text: fs #93; - System.Windows.Forms.Form, Text: fs #94; - System.Windows.Forms.Form, Text: fs #95; - System.Windows.Forms.Form, Text: fs #96; - System.Windows.Forms.Form, Text: fs #97; - System.Windows.Forms.Form, Text: fs #98; - System.Windows.Forms.Form, Text: fs #99; ...|] -val xs : string list = - ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; - "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; - "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; - "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; - "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; - "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; - "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; - "98"; "99"; ...] -val xa : string [] = - [|"0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; "13"; - "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; "25"; - "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"; - "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"; "48"; "49"; - "50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"; "58"; "59"; "60"; "61"; - "62"; "63"; "64"; "65"; "66"; "67"; "68"; "69"; "70"; "71"; "72"; "73"; - "74"; "75"; "76"; "77"; "78"; "79"; "80"; "81"; "82"; "83"; "84"; "85"; - "86"; "87"; "88"; "89"; "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; - "98"; "99"; ...|] -val xa2 : string [,] = [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] - ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] - ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] - ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] - ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] - ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] - ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] - ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]] -val sxs0 : Set = set [] - -> val sxs1 : Set = set ["0"] - -> val sxs2 : Set = set ["0"; "1"] - -> val sxs3 : Set = set ["0"; "1"; "2"] - -> val sxs4 : Set = set ["0"; "1"; "2"; "3"] - -> val sxs200 : Set = - set ["0"; "1"; "10"; "100"; "101"; "102"; "103"; "104"; "105"; ...] - -> val msxs0 : Map = map [] - -> val msxs1 : Map = map [(0, "0")] - -> val msxs2 : Map = map [(0, "0"); (1, "1")] - -> val msxs3 : Map = map [(0, "0"); (1, "1"); (2, "2")] - -> val msxs4 : Map = map [(0, "0"); (1, "1"); (2, "2"); (3, "3")] - -> val msxs200 : Map = - map - [(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5"); (6, "6"); - (7, "7"); (8, "8"); ...] - -> module M = begin - val a : string = "sub-binding" - val b : - (seq * seq * seq * System.Windows.Forms.Form) option * - (string list * string list * string [,]) option = - (Some (, , , System.Windows.Forms.Form, Text: f1 form), - Some - (["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; - "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; - "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; - "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; - "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; - "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; - "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; - "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; - "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], - ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; "11"; "12"; - "13"; "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; "22"; "23"; - "24"; "25"; "26"; "27"; "28"; "29"; "30"; "31"; "32"; "33"; "34"; - "35"; "36"; "37"; "38"; "39"; "40"; "41"; "42"; "43"; "44"; "45"; - "46"; "47"; "48"; "49"; "50"; "51"; "52"; "53"; "54"; "55"; "56"; - "57"; "58"; "59"; "60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"; - "68"; "69"; "70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"; "78"; - "79"; "80"; "81"; "82"; "83"; "84"; "85"; "86"; "87"; "88"; "89"; - "90"; "91"; "92"; "93"; "94"; "95"; "96"; "97"; "98"; "99"; ...], - [["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"] - ["10"; "11"; "12"; "13"; "14"; "15"; "16"; "17"] - ["20"; "21"; "22"; "23"; "24"; "25"; "26"; "27"] - ["30"; "31"; "32"; "33"; "34"; "35"; "36"; "37"] - ["40"; "41"; "42"; "43"; "44"; "45"; "46"; "47"] - ["50"; "51"; "52"; "53"; "54"; "55"; "56"; "57"] - ["60"; "61"; "62"; "63"; "64"; "65"; "66"; "67"] - ["70"; "71"; "72"; "73"; "74"; "75"; "76"; "77"]])) -end -type T = - class - new : a:int * b:int -> T - member AMethod : x:int -> int - member AProperty : int - static member StaticMethod : x:int -> int - static member StaticProperty : int - end -val f_as_method : x:int -> int -val f_as_thunk : (int -> int) -val refCell : string ref = { contents = "value" } -module D1 = begin - val words : System.Collections.Generic.IDictionary - val words2000 : System.Collections.Generic.IDictionary -end - -> > module D2 = begin - val words : IDictionary - val words2000 : IDictionary -end -val opt1 : 'a option -val opt1b : int option = None -val opt4 : 'a option option option option -val opt4b : int option option option option = Some (Some (Some None)) -val opt5 : int list option option option option option list = - [Some (Some (Some (Some None))); - Some (Some (Some (Some (Some [1; 2; 3; 4; 5; 6])))); - Some - (Some - (Some - (Some - (Some - [1; 2; 3; 4; 5; 6; 7; 8; 9; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; - 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 1; 2; 3; - 4; 5; 6; 7; 8; 9; 1; 2; 3; 4; 5; 6; 7; 8; 9; 0]))))] -val mkStr : n:int -> string -val strs : string [] = - [|""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; - "---------"; "----------"; "-----------"; "------------"; "-------------"; - "--------------"; "---------------"; "----------------"; - "-----------------"; "------------------"; "-------------------"; - "--------------------"; "---------------------"; "----------------------"; - "-----------------------"; "------------------------"; - "-------------------------"; "--------------------------"; - "---------------------------"; "----------------------------"; - "-----------------------------"; "------------------------------"; - "-------------------------------"; "--------------------------------"; - "---------------------------------"; "----------------------------------"; - "-----------------------------------"; - "------------------------------------"; - "-------------------------------------"; - "--------------------------------------"; - "---------------------------------------"; - "----------------------------------------"; - "-----------------------------------------"; - "------------------------------------------"; - "-------------------------------------------"; - "--------------------------------------------"; - "---------------------------------------------"; - "----------------------------------------------"; - "-----------------------------------------------"; - "------------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------"; - "---------------------------------------------------"; - "----------------------------------------------------"; - "-----------------------------------------------------"; - "------------------------------------------------------"; - "-------------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------"; - "----------------------------------------------------------"; - "-----------------------------------------------------------"; - "------------------------------------------------------------"; - "-------------------------------------------------------------"; - "--------------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------"; - "-----------------------------------------------------------------"; - "------------------------------------------------------------------"; - "-------------------------------------------------------------------"; - "--------------------------------------------------------------------"; - "---------------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-----------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[12 chars]; - "-------------------------------------------------------------"+[13 chars]; - "-------------------------------------------------------------"+[14 chars]; - "-------------------------------------------------------------"+[15 chars]; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[18 chars]; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[20 chars]; - "-------------------------------------------------------------"+[21 chars]; - "-------------------------------------------------------------"+[22 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[24 chars]; - "-------------------------------------------------------------"+[25 chars]; - "-------------------------------------------------------------"+[26 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[28 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[31 chars]; - "-------------------------------------------------------------"+[32 chars]; - "-------------------------------------------------------------"+[33 chars]; - "-------------------------------------------------------------"+[34 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[36 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[38 chars]|] -val str7s : string [] = - [|""; "-------"; "--------------"; "---------------------"; - "----------------------------"; "-----------------------------------"; - "------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[58 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[72 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[86 chars]; - "-------------------------------------------------------------"+[93 chars]; - "-------------------------------------------------------------"+[100 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[114 chars]; - "-------------------------------------------------------------"+[121 chars]; - "-------------------------------------------------------------"+[128 chars]; - "-------------------------------------------------------------"+[135 chars]; - "-------------------------------------------------------------"+[142 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[156 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[170 chars]; - "-------------------------------------------------------------"+[177 chars]; - "-------------------------------------------------------------"+[184 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[198 chars]; - "-------------------------------------------------------------"+[205 chars]; - "-------------------------------------------------------------"+[212 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[226 chars]; - "-------------------------------------------------------------"+[233 chars]; - "-------------------------------------------------------------"+[240 chars]; - "-------------------------------------------------------------"+[247 chars]; - "-------------------------------------------------------------"+[254 chars]; - "-------------------------------------------------------------"+[261 chars]; - "-------------------------------------------------------------"+[268 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[282 chars]; - "-------------------------------------------------------------"+[289 chars]; - "-------------------------------------------------------------"+[296 chars]; - "-------------------------------------------------------------"+[303 chars]; - "-------------------------------------------------------------"+[310 chars]; - "-------------------------------------------------------------"+[317 chars]; - "-------------------------------------------------------------"+[324 chars]; - "-------------------------------------------------------------"+[331 chars]; - "-------------------------------------------------------------"+[338 chars]; - "-------------------------------------------------------------"+[345 chars]; - "-------------------------------------------------------------"+[352 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[366 chars]; - "-------------------------------------------------------------"+[373 chars]; - "-------------------------------------------------------------"+[380 chars]; - "-------------------------------------------------------------"+[387 chars]; - "-------------------------------------------------------------"+[394 chars]; - "-------------------------------------------------------------"+[401 chars]; - "-------------------------------------------------------------"+[408 chars]; - "-------------------------------------------------------------"+[415 chars]; - "-------------------------------------------------------------"+[422 chars]; - "-------------------------------------------------------------"+[429 chars]; - "-------------------------------------------------------------"+[436 chars]; - "-------------------------------------------------------------"+[443 chars]; - "-------------------------------------------------------------"+[450 chars]; - "-------------------------------------------------------------"+[457 chars]; - "-------------------------------------------------------------"+[464 chars]; - "-------------------------------------------------------------"+[471 chars]; - "-------------------------------------------------------------"+[478 chars]; - "-------------------------------------------------------------"+[485 chars]; - "-------------------------------------------------------------"+[492 chars]; - "-------------------------------------------------------------"+[499 chars]; - "-------------------------------------------------------------"+[506 chars]; - "-------------------------------------------------------------"+[513 chars]; - "-------------------------------------------------------------"+[520 chars]; - "-------------------------------------------------------------"+[527 chars]; - "-------------------------------------------------------------"+[534 chars]; - "-------------------------------------------------------------"+[541 chars]; - "-------------------------------------------------------------"+[548 chars]; - "-------------------------------------------------------------"+[555 chars]; - "-------------------------------------------------------------"+[562 chars]; - "-------------------------------------------------------------"+[569 chars]; - "-------------------------------------------------------------"+[576 chars]; - "-------------------------------------------------------------"+[583 chars]; - "-------------------------------------------------------------"+[590 chars]; - "-------------------------------------------------------------"+[597 chars]; - "-------------------------------------------------------------"+[604 chars]; - "-------------------------------------------------------------"+[611 chars]; - "-------------------------------------------------------------"+[618 chars]; - "-------------------------------------------------------------"+[625 chars]; - "-------------------------------------------------------------"+[632 chars]|] -val grids : string [,] = - [[""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; - ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; - ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""; ""] - [""; "-"; "--"; "---"; "----"; "-----"; "------"; "-------"; "--------"; - "---------"; "----------"; "-----------"; "------------"; "-------------"; - "--------------"; "---------------"; "----------------"; - "-----------------"; "------------------"; "-------------------"; - "--------------------"; "---------------------"; "----------------------"; - "-----------------------"; "------------------------"; - "-------------------------"; "--------------------------"; - "---------------------------"; "----------------------------"; - "-----------------------------"; "------------------------------"; - "-------------------------------"; "--------------------------------"; - "---------------------------------"; "----------------------------------"; - "-----------------------------------"; - "------------------------------------"; - "-------------------------------------"; - "--------------------------------------"; - "---------------------------------------"; - "----------------------------------------"; - "-----------------------------------------"; - "------------------------------------------"; - "-------------------------------------------"; - "--------------------------------------------"; - "---------------------------------------------"; - "----------------------------------------------"; - "-----------------------------------------------"; - "------------------------------------------------"; - "-------------------------------------------------"] - [""; "--"; "----"; "------"; "--------"; "----------"; "------------"; - "--------------"; "----------------"; "------------------"; - "--------------------"; "----------------------"; - "------------------------"; "--------------------------"; - "----------------------------"; "------------------------------"; - "--------------------------------"; "----------------------------------"; - "------------------------------------"; - "--------------------------------------"; - "----------------------------------------"; - "------------------------------------------"; - "--------------------------------------------"; - "----------------------------------------------"; - "------------------------------------------------"; - "--------------------------------------------------"; - "----------------------------------------------------"; - "------------------------------------------------------"; - "--------------------------------------------------------"; - "----------------------------------------------------------"; - "------------------------------------------------------------"; - "--------------------------------------------------------------"; - "----------------------------------------------------------------"; - "------------------------------------------------------------------"; - "--------------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[13 chars]; - "-------------------------------------------------------------"+[15 chars]; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[21 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[25 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[31 chars]; - "-------------------------------------------------------------"+[33 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[37 chars]] - [""; "---"; "------"; "---------"; "------------"; "---------------"; - "------------------"; "---------------------"; "------------------------"; - "---------------------------"; "------------------------------"; - "---------------------------------"; - "------------------------------------"; - "---------------------------------------"; - "------------------------------------------"; - "---------------------------------------------"; - "------------------------------------------------"; - "---------------------------------------------------"; - "------------------------------------------------------"; - "---------------------------------------------------------"; - "------------------------------------------------------------"; - "---------------------------------------------------------------"; - "------------------------------------------------------------------"; - "---------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[14 chars]; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[20 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[26 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[32 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[38 chars]; - "-------------------------------------------------------------"+[41 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[50 chars]; - "-------------------------------------------------------------"+[53 chars]; - "-------------------------------------------------------------"+[56 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[62 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[68 chars]; - "-------------------------------------------------------------"+[71 chars]; - "-------------------------------------------------------------"+[74 chars]; - "-------------------------------------------------------------"+[77 chars]; - "-------------------------------------------------------------"+[80 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[86 chars]] - [""; "----"; "--------"; "------------"; "----------------"; - "--------------------"; "------------------------"; - "----------------------------"; "--------------------------------"; - "------------------------------------"; - "----------------------------------------"; - "--------------------------------------------"; - "------------------------------------------------"; - "----------------------------------------------------"; - "--------------------------------------------------------"; - "------------------------------------------------------------"; - "----------------------------------------------------------------"; - "--------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[15 chars]; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[31 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[39 chars]; - "-------------------------------------------------------------"+[43 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[55 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[63 chars]; - "-------------------------------------------------------------"+[67 chars]; - "-------------------------------------------------------------"+[71 chars]; - "-------------------------------------------------------------"+[75 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[87 chars]; - "-------------------------------------------------------------"+[91 chars]; - "-------------------------------------------------------------"+[95 chars]; - "-------------------------------------------------------------"+[99 chars]; - "-------------------------------------------------------------"+[103 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[111 chars]; - "-------------------------------------------------------------"+[115 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[123 chars]; - "-------------------------------------------------------------"+[127 chars]; - "-------------------------------------------------------------"+[131 chars]; - "-------------------------------------------------------------"+[135 chars]] - [""; "-----"; "----------"; "---------------"; "--------------------"; - "-------------------------"; "------------------------------"; - "-----------------------------------"; - "----------------------------------------"; - "---------------------------------------------"; - "--------------------------------------------------"; - "-------------------------------------------------------"; - "------------------------------------------------------------"; - "-----------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[14 chars]; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[24 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[34 chars]; - "-------------------------------------------------------------"+[39 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[49 chars]; - "-------------------------------------------------------------"+[54 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[64 chars]; - "-------------------------------------------------------------"+[69 chars]; - "-------------------------------------------------------------"+[74 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[84 chars]; - "-------------------------------------------------------------"+[89 chars]; - "-------------------------------------------------------------"+[94 chars]; - "-------------------------------------------------------------"+[99 chars]; - "-------------------------------------------------------------"+[104 chars]; - "-------------------------------------------------------------"+[109 chars]; - "-------------------------------------------------------------"+[114 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[124 chars]; - "-------------------------------------------------------------"+[129 chars]; - "-------------------------------------------------------------"+[134 chars]; - "-------------------------------------------------------------"+[139 chars]; - "-------------------------------------------------------------"+[144 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[154 chars]; - "-------------------------------------------------------------"+[159 chars]; - "-------------------------------------------------------------"+[164 chars]; - "-------------------------------------------------------------"+[169 chars]; - "-------------------------------------------------------------"+[174 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[184 chars]] - [""; "------"; "------------"; "------------------"; - "------------------------"; "------------------------------"; - "------------------------------------"; - "------------------------------------------"; - "------------------------------------------------"; - "------------------------------------------------------"; - "------------------------------------------------------------"; - "------------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[41 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[53 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[71 chars]; - "-------------------------------------------------------------"+[77 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[89 chars]; - "-------------------------------------------------------------"+[95 chars]; - "-------------------------------------------------------------"+[101 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[113 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[125 chars]; - "-------------------------------------------------------------"+[131 chars]; - "-------------------------------------------------------------"+[137 chars]; - "-------------------------------------------------------------"+[143 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[155 chars]; - "-------------------------------------------------------------"+[161 chars]; - "-------------------------------------------------------------"+[167 chars]; - "-------------------------------------------------------------"+[173 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[185 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[197 chars]; - "-------------------------------------------------------------"+[203 chars]; - "-------------------------------------------------------------"+[209 chars]; - "-------------------------------------------------------------"+[215 chars]; - "-------------------------------------------------------------"+[221 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[233 chars]] - [""; "-------"; "--------------"; "---------------------"; - "----------------------------"; "-----------------------------------"; - "------------------------------------------"; - "-------------------------------------------------"; - "--------------------------------------------------------"; - "---------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[58 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[72 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[86 chars]; - "-------------------------------------------------------------"+[93 chars]; - "-------------------------------------------------------------"+[100 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[114 chars]; - "-------------------------------------------------------------"+[121 chars]; - "-------------------------------------------------------------"+[128 chars]; - "-------------------------------------------------------------"+[135 chars]; - "-------------------------------------------------------------"+[142 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[156 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[170 chars]; - "-------------------------------------------------------------"+[177 chars]; - "-------------------------------------------------------------"+[184 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[198 chars]; - "-------------------------------------------------------------"+[205 chars]; - "-------------------------------------------------------------"+[212 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[226 chars]; - "-------------------------------------------------------------"+[233 chars]; - "-------------------------------------------------------------"+[240 chars]; - "-------------------------------------------------------------"+[247 chars]; - "-------------------------------------------------------------"+[254 chars]; - "-------------------------------------------------------------"+[261 chars]; - "-------------------------------------------------------------"+[268 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[282 chars]] - [""; "--------"; "----------------"; "------------------------"; - "--------------------------------"; - "----------------------------------------"; - "------------------------------------------------"; - "--------------------------------------------------------"; - "----------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[43 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[67 chars]; - "-------------------------------------------------------------"+[75 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[91 chars]; - "-------------------------------------------------------------"+[99 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[115 chars]; - "-------------------------------------------------------------"+[123 chars]; - "-------------------------------------------------------------"+[131 chars]; - "-------------------------------------------------------------"+[139 chars]; - "-------------------------------------------------------------"+[147 chars]; - "-------------------------------------------------------------"+[155 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[171 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[187 chars]; - "-------------------------------------------------------------"+[195 chars]; - "-------------------------------------------------------------"+[203 chars]; - "-------------------------------------------------------------"+[211 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[235 chars]; - "-------------------------------------------------------------"+[243 chars]; - "-------------------------------------------------------------"+[251 chars]; - "-------------------------------------------------------------"+[259 chars]; - "-------------------------------------------------------------"+[267 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[283 chars]; - "-------------------------------------------------------------"+[291 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[307 chars]; - "-------------------------------------------------------------"+[315 chars]; - "-------------------------------------------------------------"+[323 chars]; - "-------------------------------------------------------------"+[331 chars]] - [""; "---------"; "------------------"; "---------------------------"; - "------------------------------------"; - "---------------------------------------------"; - "------------------------------------------------------"; - "---------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[20 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[38 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[56 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[74 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[92 chars]; - "-------------------------------------------------------------"+[101 chars]; - "-------------------------------------------------------------"+[110 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[128 chars]; - "-------------------------------------------------------------"+[137 chars]; - "-------------------------------------------------------------"+[146 chars]; - "-------------------------------------------------------------"+[155 chars]; - "-------------------------------------------------------------"+[164 chars]; - "-------------------------------------------------------------"+[173 chars]; - "-------------------------------------------------------------"+[182 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[200 chars]; - "-------------------------------------------------------------"+[209 chars]; - "-------------------------------------------------------------"+[218 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[236 chars]; - "-------------------------------------------------------------"+[245 chars]; - "-------------------------------------------------------------"+[254 chars]; - "-------------------------------------------------------------"+[263 chars]; - "-------------------------------------------------------------"+[272 chars]; - "-------------------------------------------------------------"+[281 chars]; - "-------------------------------------------------------------"+[290 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[308 chars]; - "-------------------------------------------------------------"+[317 chars]; - "-------------------------------------------------------------"+[326 chars]; - "-------------------------------------------------------------"+[335 chars]; - "-------------------------------------------------------------"+[344 chars]; - "-------------------------------------------------------------"+[353 chars]; - "-------------------------------------------------------------"+[362 chars]; - "-------------------------------------------------------------"+[371 chars]; - "-------------------------------------------------------------"+[380 chars]] - [""; "----------"; "--------------------"; "------------------------------"; - "----------------------------------------"; - "--------------------------------------------------"; - "------------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[39 chars]; - "-------------------------------------------------------------"+[49 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[69 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[89 chars]; - "-------------------------------------------------------------"+[99 chars]; - "-------------------------------------------------------------"+[109 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[129 chars]; - "-------------------------------------------------------------"+[139 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[159 chars]; - "-------------------------------------------------------------"+[169 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[189 chars]; - "-------------------------------------------------------------"+[199 chars]; - "-------------------------------------------------------------"+[209 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[229 chars]; - "-------------------------------------------------------------"+[239 chars]; - "-------------------------------------------------------------"+[249 chars]; - "-------------------------------------------------------------"+[259 chars]; - "-------------------------------------------------------------"+[269 chars]; - "-------------------------------------------------------------"+[279 chars]; - "-------------------------------------------------------------"+[289 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[309 chars]; - "-------------------------------------------------------------"+[319 chars]; - "-------------------------------------------------------------"+[329 chars]; - "-------------------------------------------------------------"+[339 chars]; - "-------------------------------------------------------------"+[349 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[369 chars]; - "-------------------------------------------------------------"+[379 chars]; - "-------------------------------------------------------------"+[389 chars]; - "-------------------------------------------------------------"+[399 chars]; - "-------------------------------------------------------------"+[409 chars]; - "-------------------------------------------------------------"+[419 chars]; - "-------------------------------------------------------------"+[429 chars]] - [""; "-----------"; "----------------------"; - "---------------------------------"; - "--------------------------------------------"; - "-------------------------------------------------------"; - "------------------------------------------------------------------"; - "-------------------------------------------------------------"+[16 chars]; - "-------------------------------------------------------------"+[27 chars]; - "-------------------------------------------------------------"+[38 chars]; - "-------------------------------------------------------------"+[49 chars]; - "-------------------------------------------------------------"+[60 chars]; - "-------------------------------------------------------------"+[71 chars]; - "-------------------------------------------------------------"+[82 chars]; - "-------------------------------------------------------------"+[93 chars]; - "-------------------------------------------------------------"+[104 chars]; - "-------------------------------------------------------------"+[115 chars]; - "-------------------------------------------------------------"+[126 chars]; - "-------------------------------------------------------------"+[137 chars]; - "-------------------------------------------------------------"+[148 chars]; - "-------------------------------------------------------------"+[159 chars]; - "-------------------------------------------------------------"+[170 chars]; - "-------------------------------------------------------------"+[181 chars]; - "-------------------------------------------------------------"+[192 chars]; - "-------------------------------------------------------------"+[203 chars]; - "-------------------------------------------------------------"+[214 chars]; - "-------------------------------------------------------------"+[225 chars]; - "-------------------------------------------------------------"+[236 chars]; - "-------------------------------------------------------------"+[247 chars]; - "-------------------------------------------------------------"+[258 chars]; - "-------------------------------------------------------------"+[269 chars]; - "-------------------------------------------------------------"+[280 chars]; - "-------------------------------------------------------------"+[291 chars]; - "-------------------------------------------------------------"+[302 chars]; - "-------------------------------------------------------------"+[313 chars]; - "-------------------------------------------------------------"+[324 chars]; - "-------------------------------------------------------------"+[335 chars]; - "-------------------------------------------------------------"+[346 chars]; - "-------------------------------------------------------------"+[357 chars]; - "-------------------------------------------------------------"+[368 chars]; - "-------------------------------------------------------------"+[379 chars]; - "-------------------------------------------------------------"+[390 chars]; - "-------------------------------------------------------------"+[401 chars]; - "-------------------------------------------------------------"+[412 chars]; - "-------------------------------------------------------------"+[423 chars]; - "-------------------------------------------------------------"+[434 chars]; - "-------------------------------------------------------------"+[445 chars]; - "-------------------------------------------------------------"+[456 chars]; - "-------------------------------------------------------------"+[467 chars]; - "-------------------------------------------------------------"+[478 chars]] - [""; "------------"; "------------------------"; - "------------------------------------"; - "------------------------------------------------"; - "------------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[71 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[95 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[131 chars]; - "-------------------------------------------------------------"+[143 chars]; - "-------------------------------------------------------------"+[155 chars]; - "-------------------------------------------------------------"+[167 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[203 chars]; - "-------------------------------------------------------------"+[215 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[239 chars]; - "-------------------------------------------------------------"+[251 chars]; - "-------------------------------------------------------------"+[263 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[287 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[311 chars]; - "-------------------------------------------------------------"+[323 chars]; - "-------------------------------------------------------------"+[335 chars]; - "-------------------------------------------------------------"+[347 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[371 chars]; - "-------------------------------------------------------------"+[383 chars]; - "-------------------------------------------------------------"+[395 chars]; - "-------------------------------------------------------------"+[407 chars]; - "-------------------------------------------------------------"+[419 chars]; - "-------------------------------------------------------------"+[431 chars]; - "-------------------------------------------------------------"+[443 chars]; - "-------------------------------------------------------------"+[455 chars]; - "-------------------------------------------------------------"+[467 chars]; - "-------------------------------------------------------------"+[479 chars]; - "-------------------------------------------------------------"+[491 chars]; - "-------------------------------------------------------------"+[503 chars]; - "-------------------------------------------------------------"+[515 chars]; - "-------------------------------------------------------------"+[527 chars]] - [""; "-------------"; "--------------------------"; - "---------------------------------------"; - "----------------------------------------------------"; - "-----------------------------------------------------------------"; - "-------------------------------------------------------------"+[17 chars]; - "-------------------------------------------------------------"+[30 chars]; - "-------------------------------------------------------------"+[43 chars]; - "-------------------------------------------------------------"+[56 chars]; - "-------------------------------------------------------------"+[69 chars]; - "-------------------------------------------------------------"+[82 chars]; - "-------------------------------------------------------------"+[95 chars]; - "-------------------------------------------------------------"+[108 chars]; - "-------------------------------------------------------------"+[121 chars]; - "-------------------------------------------------------------"+[134 chars]; - "-------------------------------------------------------------"+[147 chars]; - "-------------------------------------------------------------"+[160 chars]; - "-------------------------------------------------------------"+[173 chars]; - "-------------------------------------------------------------"+[186 chars]; - "-------------------------------------------------------------"+[199 chars]; - "-------------------------------------------------------------"+[212 chars]; - "-------------------------------------------------------------"+[225 chars]; - "-------------------------------------------------------------"+[238 chars]; - "-------------------------------------------------------------"+[251 chars]; - "-------------------------------------------------------------"+[264 chars]; - "-------------------------------------------------------------"+[277 chars]; - "-------------------------------------------------------------"+[290 chars]; - "-------------------------------------------------------------"+[303 chars]; - "-------------------------------------------------------------"+[316 chars]; - "-------------------------------------------------------------"+[329 chars]; - "-------------------------------------------------------------"+[342 chars]; - "-------------------------------------------------------------"+[355 chars]; - "-------------------------------------------------------------"+[368 chars]; - "-------------------------------------------------------------"+[381 chars]; - "-------------------------------------------------------------"+[394 chars]; - "-------------------------------------------------------------"+[407 chars]; - "-------------------------------------------------------------"+[420 chars]; - "-------------------------------------------------------------"+[433 chars]; - "-------------------------------------------------------------"+[446 chars]; - "-------------------------------------------------------------"+[459 chars]; - "-------------------------------------------------------------"+[472 chars]; - "-------------------------------------------------------------"+[485 chars]; - "-------------------------------------------------------------"+[498 chars]; - "-------------------------------------------------------------"+[511 chars]; - "-------------------------------------------------------------"+[524 chars]; - "-------------------------------------------------------------"+[537 chars]; - "-------------------------------------------------------------"+[550 chars]; - "-------------------------------------------------------------"+[563 chars]; - "-------------------------------------------------------------"+[576 chars]] - [""; "--------------"; "----------------------------"; - "------------------------------------------"; - "--------------------------------------------------------"; - "----------------------------------------------------------------------"; - "-------------------------------------------------------------"+[23 chars]; - "-------------------------------------------------------------"+[37 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[79 chars]; - "-------------------------------------------------------------"+[93 chars]; - "-------------------------------------------------------------"+[107 chars]; - "-------------------------------------------------------------"+[121 chars]; - "-------------------------------------------------------------"+[135 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[177 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[205 chars]; - "-------------------------------------------------------------"+[219 chars]; - "-------------------------------------------------------------"+[233 chars]; - "-------------------------------------------------------------"+[247 chars]; - "-------------------------------------------------------------"+[261 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[289 chars]; - "-------------------------------------------------------------"+[303 chars]; - "-------------------------------------------------------------"+[317 chars]; - "-------------------------------------------------------------"+[331 chars]; - "-------------------------------------------------------------"+[345 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[373 chars]; - "-------------------------------------------------------------"+[387 chars]; - "-------------------------------------------------------------"+[401 chars]; - "-------------------------------------------------------------"+[415 chars]; - "-------------------------------------------------------------"+[429 chars]; - "-------------------------------------------------------------"+[443 chars]; - "-------------------------------------------------------------"+[457 chars]; - "-------------------------------------------------------------"+[471 chars]; - "-------------------------------------------------------------"+[485 chars]; - "-------------------------------------------------------------"+[499 chars]; - "-------------------------------------------------------------"+[513 chars]; - "-------------------------------------------------------------"+[527 chars]; - "-------------------------------------------------------------"+[541 chars]; - "-------------------------------------------------------------"+[555 chars]; - "-------------------------------------------------------------"+[569 chars]; - "-------------------------------------------------------------"+[583 chars]; - "-------------------------------------------------------------"+[597 chars]; - "-------------------------------------------------------------"+[611 chars]; - "-------------------------------------------------------------"+[625 chars]] - [""; "---------------"; "------------------------------"; - "---------------------------------------------"; - "------------------------------------------------------------"; - "-------------------------------------------------------------"+[14 chars]; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[44 chars]; - "-------------------------------------------------------------"+[59 chars]; - "-------------------------------------------------------------"+[74 chars]; - "-------------------------------------------------------------"+[89 chars]; - "-------------------------------------------------------------"+[104 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[134 chars]; - "-------------------------------------------------------------"+[149 chars]; - "-------------------------------------------------------------"+[164 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[194 chars]; - "-------------------------------------------------------------"+[209 chars]; - "-------------------------------------------------------------"+[224 chars]; - "-------------------------------------------------------------"+[239 chars]; - "-------------------------------------------------------------"+[254 chars]; - "-------------------------------------------------------------"+[269 chars]; - "-------------------------------------------------------------"+[284 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[314 chars]; - "-------------------------------------------------------------"+[329 chars]; - "-------------------------------------------------------------"+[344 chars]; - "-------------------------------------------------------------"+[359 chars]; - "-------------------------------------------------------------"+[374 chars]; - "-------------------------------------------------------------"+[389 chars]; - "-------------------------------------------------------------"+[404 chars]; - "-------------------------------------------------------------"+[419 chars]; - "-------------------------------------------------------------"+[434 chars]; - "-------------------------------------------------------------"+[449 chars]; - "-------------------------------------------------------------"+[464 chars]; - "-------------------------------------------------------------"+[479 chars]; - "-------------------------------------------------------------"+[494 chars]; - "-------------------------------------------------------------"+[509 chars]; - "-------------------------------------------------------------"+[524 chars]; - "-------------------------------------------------------------"+[539 chars]; - "-------------------------------------------------------------"+[554 chars]; - "-------------------------------------------------------------"+[569 chars]; - "-------------------------------------------------------------"+[584 chars]; - "-------------------------------------------------------------"+[599 chars]; - "-------------------------------------------------------------"+[614 chars]; - "-------------------------------------------------------------"+[629 chars]; - "-------------------------------------------------------------"+[644 chars]; - "-------------------------------------------------------------"+[659 chars]; - "-------------------------------------------------------------"+[674 chars]] - [""; "----------------"; "--------------------------------"; - "------------------------------------------------"; - "----------------------------------------------------------------"; - "-------------------------------------------------------------"+[19 chars]; - "-------------------------------------------------------------"+[35 chars]; - "-------------------------------------------------------------"+[51 chars]; - "-------------------------------------------------------------"+[67 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[99 chars]; - "-------------------------------------------------------------"+[115 chars]; - "-------------------------------------------------------------"+[131 chars]; - "-------------------------------------------------------------"+[147 chars]; - "-------------------------------------------------------------"+[163 chars]; - "-------------------------------------------------------------"+[179 chars]; - "-------------------------------------------------------------"+[195 chars]; - "-------------------------------------------------------------"+[211 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[243 chars]; - "-------------------------------------------------------------"+[259 chars]; - "-------------------------------------------------------------"+[275 chars]; - "-------------------------------------------------------------"+[291 chars]; - "-------------------------------------------------------------"+[307 chars]; - "-------------------------------------------------------------"+[323 chars]; - "-------------------------------------------------------------"+[339 chars]; - "-------------------------------------------------------------"+[355 chars]; - "-------------------------------------------------------------"+[371 chars]; - "-------------------------------------------------------------"+[387 chars]; - "-------------------------------------------------------------"+[403 chars]; - "-------------------------------------------------------------"+[419 chars]; - "-------------------------------------------------------------"+[435 chars]; - "-------------------------------------------------------------"+[451 chars]; - "-------------------------------------------------------------"+[467 chars]; - "-------------------------------------------------------------"+[483 chars]; - "-------------------------------------------------------------"+[499 chars]; - "-------------------------------------------------------------"+[515 chars]; - "-------------------------------------------------------------"+[531 chars]; - "-------------------------------------------------------------"+[547 chars]; - "-------------------------------------------------------------"+[563 chars]; - "-------------------------------------------------------------"+[579 chars]; - "-------------------------------------------------------------"+[595 chars]; - "-------------------------------------------------------------"+[611 chars]; - "-------------------------------------------------------------"+[627 chars]; - "-------------------------------------------------------------"+[643 chars]; - "-------------------------------------------------------------"+[659 chars]; - "-------------------------------------------------------------"+[675 chars]; - "-------------------------------------------------------------"+[691 chars]; - "-------------------------------------------------------------"+[707 chars]; - "-------------------------------------------------------------"+[723 chars]] - [""; "-----------------"; "----------------------------------"; - "---------------------------------------------------"; - "--------------------------------------------------------------------"; - "-------------------------------------------------------------"+[24 chars]; - "-------------------------------------------------------------"+[41 chars]; - "-------------------------------------------------------------"+[58 chars]; - "-------------------------------------------------------------"+[75 chars]; - "-------------------------------------------------------------"+[92 chars]; - "-------------------------------------------------------------"+[109 chars]; - "-------------------------------------------------------------"+[126 chars]; - "-------------------------------------------------------------"+[143 chars]; - "-------------------------------------------------------------"+[160 chars]; - "-------------------------------------------------------------"+[177 chars]; - "-------------------------------------------------------------"+[194 chars]; - "-------------------------------------------------------------"+[211 chars]; - "-------------------------------------------------------------"+[228 chars]; - "-------------------------------------------------------------"+[245 chars]; - "-------------------------------------------------------------"+[262 chars]; - "-------------------------------------------------------------"+[279 chars]; - "-------------------------------------------------------------"+[296 chars]; - "-------------------------------------------------------------"+[313 chars]; - "-------------------------------------------------------------"+[330 chars]; - "-------------------------------------------------------------"+[347 chars]; - "-------------------------------------------------------------"+[364 chars]; - "-------------------------------------------------------------"+[381 chars]; - "-------------------------------------------------------------"+[398 chars]; - "-------------------------------------------------------------"+[415 chars]; - "-------------------------------------------------------------"+[432 chars]; - "-------------------------------------------------------------"+[449 chars]; - "-------------------------------------------------------------"+[466 chars]; - "-------------------------------------------------------------"+[483 chars]; - "-------------------------------------------------------------"+[500 chars]; - "-------------------------------------------------------------"+[517 chars]; - "-------------------------------------------------------------"+[534 chars]; - "-------------------------------------------------------------"+[551 chars]; - "-------------------------------------------------------------"+[568 chars]; - "-------------------------------------------------------------"+[585 chars]; - "-------------------------------------------------------------"+[602 chars]; - "-------------------------------------------------------------"+[619 chars]; - "-------------------------------------------------------------"+[636 chars]; - "-------------------------------------------------------------"+[653 chars]; - "-------------------------------------------------------------"+[670 chars]; - "-------------------------------------------------------------"+[687 chars]; - "-------------------------------------------------------------"+[704 chars]; - "-------------------------------------------------------------"+[721 chars]; - "-------------------------------------------------------------"+[738 chars]; - "-------------------------------------------------------------"+[755 chars]; - "-------------------------------------------------------------"+[772 chars]] - [""; "------------------"; "------------------------------------"; - "------------------------------------------------------"; - "------------------------------------------------------------------------"; - "-------------------------------------------------------------"+[29 chars]; - "-------------------------------------------------------------"+[47 chars]; - "-------------------------------------------------------------"+[65 chars]; - "-------------------------------------------------------------"+[83 chars]; - "-------------------------------------------------------------"+[101 chars]; - "-------------------------------------------------------------"+[119 chars]; - "-------------------------------------------------------------"+[137 chars]; - "-------------------------------------------------------------"+[155 chars]; - "-------------------------------------------------------------"+[173 chars]; - "-------------------------------------------------------------"+[191 chars]; - "-------------------------------------------------------------"+[209 chars]; - "-------------------------------------------------------------"+[227 chars]; - "-------------------------------------------------------------"+[245 chars]; - "-------------------------------------------------------------"+[263 chars]; - "-------------------------------------------------------------"+[281 chars]; - "-------------------------------------------------------------"+[299 chars]; - "-------------------------------------------------------------"+[317 chars]; - "-------------------------------------------------------------"+[335 chars]; - "-------------------------------------------------------------"+[353 chars]; - "-------------------------------------------------------------"+[371 chars]; - "-------------------------------------------------------------"+[389 chars]; - "-------------------------------------------------------------"+[407 chars]; - "-------------------------------------------------------------"+[425 chars]; - "-------------------------------------------------------------"+[443 chars]; - "-------------------------------------------------------------"+[461 chars]; - "-------------------------------------------------------------"+[479 chars]; - "-------------------------------------------------------------"+[497 chars]; - "-------------------------------------------------------------"+[515 chars]; - "-------------------------------------------------------------"+[533 chars]; - "-------------------------------------------------------------"+[551 chars]; - "-------------------------------------------------------------"+[569 chars]; - "-------------------------------------------------------------"+[587 chars]; - "-------------------------------------------------------------"+[605 chars]; - "-------------------------------------------------------------"+[623 chars]; - "-------------------------------------------------------------"+[641 chars]; - "-------------------------------------------------------------"+[659 chars]; - "-------------------------------------------------------------"+[677 chars]; - "-------------------------------------------------------------"+[695 chars]; - "-------------------------------------------------------------"+[713 chars]; - "-------------------------------------------------------------"+[731 chars]; - "-------------------------------------------------------------"+[749 chars]; - "-------------------------------------------------------------"+[767 chars]; - "-------------------------------------------------------------"+[785 chars]; - "-------------------------------------------------------------"+[803 chars]; - "-------------------------------------------------------------"+[821 chars]] - [""; "-------------------"; "--------------------------------------"; - "---------------------------------------------------------"; - "-------------------------------------------------------------"+[15 chars]; - "-------------------------------------------------------------"+[34 chars]; - "-------------------------------------------------------------"+[53 chars]; - "-------------------------------------------------------------"+[72 chars]; - "-------------------------------------------------------------"+[91 chars]; - "-------------------------------------------------------------"+[110 chars]; - "-------------------------------------------------------------"+[129 chars]; - "-------------------------------------------------------------"+[148 chars]; - "-------------------------------------------------------------"+[167 chars]; - "-------------------------------------------------------------"+[186 chars]; - "-------------------------------------------------------------"+[205 chars]; - "-------------------------------------------------------------"+[224 chars]; - "-------------------------------------------------------------"+[243 chars]; - "-------------------------------------------------------------"+[262 chars]; - "-------------------------------------------------------------"+[281 chars]; - "-------------------------------------------------------------"+[300 chars]; - "-------------------------------------------------------------"+[319 chars]; - "-------------------------------------------------------------"+[338 chars]; - "-------------------------------------------------------------"+[357 chars]; - "-------------------------------------------------------------"+[376 chars]; - "-------------------------------------------------------------"+[395 chars]; - "-------------------------------------------------------------"+[414 chars]; - "-------------------------------------------------------------"+[433 chars]; - "-------------------------------------------------------------"+[452 chars]; - "-------------------------------------------------------------"+[471 chars]; - "-------------------------------------------------------------"+[490 chars]; - "-------------------------------------------------------------"+[509 chars]; - "-------------------------------------------------------------"+[528 chars]; - "-------------------------------------------------------------"+[547 chars]; - "-------------------------------------------------------------"+[566 chars]; - "-------------------------------------------------------------"+[585 chars]; - "-------------------------------------------------------------"+[604 chars]; - "-------------------------------------------------------------"+[623 chars]; - "-------------------------------------------------------------"+[642 chars]; - "-------------------------------------------------------------"+[661 chars]; - "-------------------------------------------------------------"+[680 chars]; - "-------------------------------------------------------------"+[699 chars]; - "-------------------------------------------------------------"+[718 chars]; - "-------------------------------------------------------------"+[737 chars]; - "-------------------------------------------------------------"+[756 chars]; - "-------------------------------------------------------------"+[775 chars]; - "-------------------------------------------------------------"+[794 chars]; - "-------------------------------------------------------------"+[813 chars]; - "-------------------------------------------------------------"+[832 chars]; - "-------------------------------------------------------------"+[851 chars]; - "-------------------------------------------------------------"+[870 chars]; - ...] - ...] - -> type tree = - | L - | N of tree list -val mkT : w:int -> d:int -> tree -val tree : w:int -> d:int -> tree - -> [Building 2 4...done] -val tree_2_4 : tree = - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]] - -> [Building 2 6...done] -val tree_2_6 : tree = - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]] - -> [Building 2 8...done] -val tree_2_8 : tree = - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]] - -> [Building 2 10...done] -val tree_2_10 : tree = - N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N ...; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...] - -> [Building 2 12...done] -val tree_2_12 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]]; - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; ...]; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 2 14...done] -val tree_2_14 : tree = - N [N [N [N [N [N [N [N [N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]]]; - N [N [N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]]; - N [N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]]; - N [N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]]; - N [N [N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]; - N [N [N [L; L]; N [L; L]]; - N [N [L; L]; N [L; L]]]]; - N [N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 3 8...done] -val tree_3_8 : tree = - N [N [N [N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; - N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]]; - N [N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]; - N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; L; L]]]]; - N [N [N [N [L; L; L]; N [L; L; L]; N [L; L; L]]; - N [N [L; L; L]; N [L; L; L]; N [L; ...]; ...]; ...]; ...]; - ...]; ...]; ...]; ...] - -> [Building 4 8...done] -val tree_4_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]]; - N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]]; - N [N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]]; - N [N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; L]; - N [L; L; L; L]]; - N [N [L; L; L; L]; N [L; L; L; L]; N [L; L; L; ...]; ...]; - ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 5 8...done] -val tree_5_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]; - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]; - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]; - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]; - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]]; - N [N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]]; - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N ...; ...]; ...]; ...]; ...]; ...]; - ...]; ...] - -> [Building 6 8...done] -val tree_6_8 : tree = - N [N [N [N [N [N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; - N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; - N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]]; - N [N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]; - N [L; L; L; L; L; L]; N [L; L; L; L; L; L]]; - N [N ...; ...]; ...]; ...]; ...]; ...]; ...]; ...] - -> [Building 5 3...done] -val tree_5_3 : tree = - N [N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]; - N [N [L; L; L; L; L]; N [L; L; L; L; L]; N [L; L; L; L; L]; - N [L; L; L; L; L]; N [L; L; L; L; L]]] - -> > type X = - | Var of int - | Bop of int * X * X -val generate : x:int -> X - -> val exps : X list = - [Bop (1,Var 0,Var 0); Var 2; Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)); - Var 4; Bop (5,Var 2,Bop (1,Var 0,Var 0)); Var 6; - Bop (7,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)),Var 2); Var 8; - Bop (9,Var 4,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0))); Var 10; - Bop - (213,Var 106, - Bop - (71, - Bop - (35,Bop (17,Var 8,Bop (5,Var 2,Bop (1,Var 0,Var 0))), - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)))), - Bop - (23, - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0))), - Bop (7,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)),Var 2)))); - Var 21342314; Var 3214; Bop (1231357,Var 615678,Var 410452); - Bop - (5234547,Bop (2617273,Var 1308636,Var 872424), - Bop (1744849,Var 872424,Var 581616)); - Bop (923759825,Var 461879912,Bop (307919941,Var 153959970,Var 102639980)); - Var 2435234; - Bop - (12396777,Var 6198388, - Bop - (4132259, - Bop - (2066129,Var 1033064, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502))))), - Bop - (1377419, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502)))), - Bop - (459139, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502))), - Var 153046)))); - Bop - (3333333,Var 1666666, - Bop - (1111111, - Bop - (555555,Bop (277777,Var 138888,Var 92592), - Bop (185185,Var 92592,Var 61728)),Var 370370)); - Bop - (1312311237,Var 656155618, - Bop - (437437079, - Bop - (218718539, - Bop - (109359269,Var 54679634, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))))), - Var 6250), - Bop - (12501,Var 6250, - Bop - (4167, - Bop - (2083, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))), - Var 694), - Bop - (1389,Var 694, - Bop - (463, - Bop - (231, - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38), - Bop - (77,Var 38, - Bop (25,Var 12,Var 8))), - Var 154)))))),Var 75006))), - Var 1350114)))), - Bop - (72906179, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))))), - Var 6250), - Bop - (12501,Var 6250, - Bop - (4167, - Bop - (2083, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))), - Var 694), - Bop - (1389,Var 694, - Bop - (463, - Bop - (231, - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38), - Bop - (77,Var 38, - Bop (25,Var 12,Var 8))), - Var 154)))))),Var 75006))), - Var 1350114))), - Bop (24302059,Bop (12151029,...,...),...))),...)); ...] - -> module Exprs = begin - val x1 : X = - Bop - (213,Var 106, - Bop - (71, - Bop - (35,Bop (17,Var 8,Bop (5,Var 2,Bop (1,Var 0,Var 0))), - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)))), - Bop - (23, - Bop - (11,Bop (5,Var 2,Bop (1,Var 0,Var 0)), - Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0))), - Bop (7,Bop (3,Bop (1,Var 0,Var 0),Bop (1,Var 0,Var 0)),Var 2)))) - val x2 : X = Var 21342314 - val x3 : X = Var 3214 - val x4 : X = Bop (1231357,Var 615678,Var 410452) - val x5 : X = - Bop - (5234547,Bop (2617273,Var 1308636,Var 872424), - Bop (1744849,Var 872424,Var 581616)) - val x6 : X = - Bop (923759825,Var 461879912,Bop (307919941,Var 153959970,Var 102639980)) - val x7 : X = Var 2435234 - val x8 : X = - Bop - (12396777,Var 6198388, - Bop - (4132259, - Bop - (2066129,Var 1033064, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502))))), - Bop - (1377419, - Bop - (688709,Var 344354, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502)))), - Bop - (459139, - Bop - (229569,Var 114784, - Bop - (76523, - Bop - (38261,Var 19130, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472)))), - Bop - (25507, - Bop - (12753,Var 6376, - Bop - (4251,Bop (2125,Var 1062,Var 708), - Bop (1417,Var 708,Var 472))),Var 8502))), - Var 153046)))) - val x9 : X = - Bop - (3333333,Var 1666666, - Bop - (1111111, - Bop - (555555,Bop (277777,Var 138888,Var 92592), - Bop (185185,Var 92592,Var 61728)),Var 370370)) - val x10 : X = - Bop - (1312311237,Var 656155618, - Bop - (437437079, - Bop - (218718539, - Bop - (109359269,Var 54679634, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))))), - Var 6250), - Bop - (12501,Var 6250, - Bop - (4167, - Bop - (2083, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))), - Var 694), - Bop - (1389,Var 694, - Bop - (463, - Bop - (231, - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38), - Bop - (77,Var 38, - Bop - (25,Var 12,Var 8))), - Var 154)))))),Var 75006))), - Var 1350114)))), - Bop - (72906179, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))))), - Var 6250), - Bop - (12501,Var 6250, - Bop - (4167, - Bop - (2083, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))), - Var 694), - Bop - (1389,Var 694, - Bop - (463, - Bop - (231, - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38), - Bop - (77,Var 38, - Bop - (25,Var 12,Var 8))), - Var 154)))))),Var 75006))), - Var 1350114))), - Bop - (24302059, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))))), - Var 6250), - Bop - (12501,Var 6250, - Bop - (4167, - Bop - (2083, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6))), - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38))), - Var 694), - Bop - (1389,Var 694, - Bop - (463, - Bop - (231, - Bop - (115, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4, - Bop - (3, - Bop - (1, - Var 0, - Var 0), - Bop - (1, - Var 0, - Var 0))), - Var 6)),Var 38), - Bop - (77,Var 38, - Bop - (25,Var 12,Var 8))), - Var 154)))))),Var 75006))), - Var 1350114)),Var 8100686))), - Bop - (145812359, - Bop - (72906179, - Bop - (36453089,Var 18226544, - Bop - (12151029,Var 6075514, - Bop - (4050343, - Bop - (2025171,Bop (1012585,Var 506292,Var 337528), - Bop - (675057,Var 337528, - Bop - (225019, - Bop - (112509,Var 56254, - Bop - (37503, - Bop - (18751, - Bop - (9375, - Bop - (4687, - Bop - (2343, - Bop - (1171, - Bop - (585,Var 292, - Bop - (195, - Bop - (97,Var 48, - Var 32), - Bop - (65,Var 32, - Bop - (21,Var 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))), - Var 390), - Bop (781,Var 390,Var 260)), - Var 1562), - Bop - (3125,Var 1562, - Bop - (1041,Var 520, - Bop - (347, - Bop - (173,Var 86, - Bop - (57,Var 28, - Bop - (19, - Bop - (9,Var 4,...), - ...))),...)))), - ...),...)),...))),...))),...),...))) - val x11 : X = - Bop - (2147483647, - Bop - (1073741823, - Bop - (536870911, - Bop - (268435455, - Bop - (134217727, - Bop - (67108863, - Bop - (33554431, - Bop - (16777215, - Bop - (8388607, - Bop - (4194303, - Bop - (2097151, - Bop - (1048575, - Bop - (524287, - Bop - (262143, - Bop - (131071, - Bop - (65535, - Bop - (32767, - Bop - (16383, - Bop - (8191, - Bop - (4095, - Bop - (2047, - Bop - (1023, - Bop - (511, - Bop - (255, - Bop - (127, - Bop - (63, - Bop - (31, - Bop - (15, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var - 2), - Bop - (5, - Var - 2, - Bop - (1, - Var - 0, - Var - 0))), - Var - 10), - Bop - (21, - Var - 10, - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var - 2))), - Var - 42), - Bop - (85, - Var - 42, - Var - 28)), - Var - 170), - Bop - (341, - Var - 170, - Bop - (113, - Var - 56, - Bop - (37, - Var - 18, - Var - 12)))), - Var 682), - Bop - (1365, - Var 682, - Bop - (455, - Bop - (227, - Bop - (113, - Var - 56, - Bop - (37, - Var - 18, - Var - 12)), - Bop - (75, - Bop - (37, - Var - 18, - Var - 12), - Bop - (25, - Var - 12, - Var - 8))), - Bop - (151, - Bop - (75, - Bop - (37, - Var - 18, - Var - 12), - Bop - (25, - Var - 12, - Var - 8)), - Var - 50)))), - Var 2730), - Bop - (5461,Var 2730, - Var 1820)), - Var 10922), - Bop - (21845,Var 10922, - Bop - (7281,Var 3640, - Bop - (2427, - Bop - (1213,Var 606, - Var 404), - Bop - (809,Var 404, - Bop - (269,Var 134, - Bop - (89, - Var 44, - Bop - (29, - Var - 14, - Bop - (9, - Var - 4, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))))))))))), - Var 43690), - Bop - (87381,Var 43690, - Bop - (29127, - Bop - (14563, - Bop - (7281,Var 3640, - Bop - (2427, - Bop - (1213,Var 606, - Var 404), - Bop - (809,Var 404, - Bop - (269,Var 134, - Bop - (89, - Var 44, - Bop - (29, - Var - 14, - Bop - (9, - Var - 4, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))))))))), - Var 4854), - Bop - (9709,Var 4854,Var 3236)))), - Var 174762), - Bop (349525,Var 174762,Var 116508)), - Var 699050), - Bop - (1398101,Var 699050, - Bop (466033,Var 233016,Var 155344))), - Var 2796202), - Bop - (5592405,Var 2796202, - Bop - (1864135, - Bop - (932067,Bop (466033,Var 233016,Var 155344), - Bop - (310689,Var 155344, - Bop - (103563, - Bop (51781,Var 25890,Var 17260), - Bop - (34521,Var 17260, - Bop - (11507, - Bop - (5753,Var 2876, - Bop - (1917,Var 958, - Bop - (639, - Bop - (319, - Bop - (159, - Bop - (79, - Bop - (39, - Bop - (19, - Bop - (9, - Var - 4, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))), - Var 6), - Bop - (13, - Var 6, - Var 4)), - Var 26), - Bop - (53,Var 26, - Bop - (17,Var 8, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0))))), - Var 106), - Bop - (213,Var 106, - Bop - (71, - Bop - (35, - Bop - (17,Var 8, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0))), - Bop - (11, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0)), - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)))), - Bop - (23, - Bop - (11, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0)), - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))), - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2))))))), - Bop - (3835, - Bop - (1917,Var 958, - Bop - (639, - Bop - (319, - Bop - (159, - Bop - (79, - Bop - (39, - Bop - (19, - Bop - (9, - Var - 4, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))), - Var 6), - Bop - (13, - Var 6, - Var 4)), - Var 26), - Bop - (53,Var 26, - Bop - (17,Var 8, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0))))), - Var 106), - Bop - (213,Var 106, - Bop - (71, - Bop - (35, - Bop - (17,Var 8, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0))), - Bop - (11, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0)), - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)))), - Bop - (23, - Bop - (11, - Bop - (5, - Var 2, - Bop - (1, - Var - 0, - Var - 0)), - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0))), - Bop - (7, - Bop - (3, - Bop - (1, - Var - 0, - Var - 0), - Bop - (1, - Var - 0, - Var - 0)), - Var 2)))))), - Var 1278)))))),Var 621378))), - Var 11184810),Bop (22369621,Var 11184810,Var 7456540)), - Var 44739242), - Bop - (89478485,Var 44739242, - Bop - (29826161,Var 14913080, - Bop - (9942053,Var 4971026, - Bop (3314017,Var 1657008,Var 1104672))))), - Var 178956970), - Bop - (357913941,Var 178956970, - Bop - (119304647, - Bop - (59652323, - Bop - (29826161,Var 14913080, - Bop - (9942053,Var 4971026, - Bop (3314017,Var 1657008,Var 1104672))), - Bop - (19884107, - Bop - (9942053,Var 4971026, - Bop (3314017,Var 1657008,Var 1104672)), - Bop - (6628035,Bop (3314017,Var 1657008,Var 1104672), - Bop (2209345,Var 1104672,Var 736448)))), - Bop - (39768215, - Bop - (19884107, - Bop - (9942053,Var 4971026, - Bop (3314017,Var 1657008,Var 1104672)), - Bop - (6628035,Bop (3314017,Var 1657008,Var 1104672), - Bop (2209345,Var 1104672,Var 736448))), - Bop - (13256071, - Bop - (6628035,Bop (3314017,Var 1657008,Var 1104672), - Bop (2209345,Var 1104672,Var 736448)),Var 4418690))))), - Var 715827882) -end - -> type C = - class - new : x:string -> C - override ToString : unit -> string - end -val c1 : C = -val csA : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csB : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] -val csC : C [] = - [|; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; - ; ; ...|] - -> exception Abc - -> exception AbcInt of int - -> exception AbcString of string - -> exception AbcExn of exn list - -> exception AbcException of System.Exception list - -> val exA1 : exn = Abc -val exA2 : exn = AbcInt 2 -val exA3 : exn = AbcString "3" -val exA4 : exn = AbcExn [Abc; AbcInt 2; AbcString "3"] -val exA5 : exn = AbcException [AbcExn [Abc; AbcInt 2; AbcString "3"]] -exception Ex0 -exception ExUnit of unit -exception ExUnits of unit * unit -exception ExUnitOption of unit option -val ex0 : exn = Ex0 -val exU : exn = ExUnit () -val exUs : exn = ExUnits ((),()) -val exUSome : exn = ExUnitOption (Some ()) -val exUNone : exn = ExUnitOption None -type 'a T4063 = | AT4063 of 'a - -> val valAT3063_12 : int T4063 = AT4063 12 - -> val valAT3063_True : bool T4063 = AT4063 true - -> val valAT3063_text : string T4063 = AT4063 "text" - -> val valAT3063_null : System.Object T4063 = AT4063 null - -> type M4063<'a> = - class - new : x:'a -> M4063<'a> - end - -> val v4063 : M4063 - -> type Taaaaa<'a> = - class - new : unit -> Taaaaa<'a> - end - -> type Taaaaa2<'a> = - class - inherit Taaaaa<'a> - new : unit -> Taaaaa2<'a> - member M : unit -> Taaaaa2<'a> - end - -> type Tbbbbb<'a> = - class - new : x:'a -> Tbbbbb<'a> - member M : unit -> 'a - end - -> type Tbbbbb2 = - class - inherit Tbbbbb - new : x:string -> Tbbbbb2 - end - -> val it : (unit -> string) = - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] = [|12uy; 13uy; 14uy|] -end - -> val it : string = "Check #help" - -> - F# Interactive directives: - - #r "file.dll";; Reference (dynamically load) the given DLL - #I "path";; Add the given search path for referenced DLLs - #load "file.fs" ...;; Load the given file(s) as if compiled and referenced - #time ["on"|"off"];; Toggle timing on/off - #help;; Display help - #quit;; Exit - - F# Interactive command line options: - - - -> val it : string = "Check #time on and then off" - -> ---> Timing now on - -> ---> Timing now off - -> val it : string = "Check #unknown command" - -> Invalid directive '#blaaaaaa ' -> val it : string = - "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" - -> ---> Added '/' to library include path - -> type internal T1 = - | A - | B - -> type internal T2 = - { x: int } - -> type internal T3 - -> type internal T4 = - class - new : unit -> T4 - end - -> type T1 = - internal | A - | B - -> type T2 = - internal { x: int } - -> type private T1 = - | A - | B - -> type private T2 = - { x: int } - -> type T1 = - private | A - | B - -> type T2 = - private { x: int } - -> type internal T1 = - private | A - | B - -> type internal T2 = - private { x: int } - -> type private T3 - -> type private T4 = - class - new : unit -> T4 - end - -> exception X1 of int - -> exception private X2 of int - -> exception internal X3 of int - -> type T0 = - class - new : unit -> T0 - end -type T1Post<'a> = - class - new : unit -> T1Post<'a> - end -type 'a T1Pre = - class - new : unit -> 'a T1Pre - end - -> type T0 with - member M : unit -> T0 list -type T0 with - member P : T0 * T0 -type T0 with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type r = - { f0: int - f1: int - f2: int - f3: int - f4: int - f5: int - f6: int - f7: int - f8: int - f9: int } -val r10 : r = { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 } -val r10s : r [] = - [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }|] -val r10s' : string * r [] = - ("one extra node", - [|{ f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }; - { f0 = 0 - f1 = 1 - f2 = 2 - f3 = 3 - f4 = 4 - f5 = 5 - f6 = 6 - f7 = 7 - f8 = 8 - f9 = 9 }|]) - -> val x1564_A1 : int = 1 - - ---> Added '\' to library include path - -val x1564_A2 : int = 2 - - ---> Added '\' to library include path - -val x1564_A3 : int = 3 - -> type internal Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - -> module internal InternalM = begin - val x : int = 1 - type Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - type private Foo3 = - class - new : unit -> Foo3 - new : x:int -> Foo3 - new : x:int * y:int -> Foo3 - new : x:int * y:int * z:int -> Foo3 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end -module internal PrivateM = begin - val private x : int = 1 - type private Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end - -> val it : seq = - seq - [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); - (58, "2/10/2009", 1)] - -> module Test4343a = begin - val mk : i:int -> string - val x100 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[39 chars] - val x90 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[29 chars] - val x80 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[19 chars] - val x75 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[14 chars] - val x74 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[13 chars] - val x73 : string = - "0123456789012345678901234567890123456789012345678901234567890"+[12 chars] - val x72 : string = - "012345678901234567890123456789012345678901234567890123456789012345678901" - val x71 : string = - "01234567890123456789012345678901234567890123456789012345678901234567890" - val x70 : string = - "0123456789012345678901234567890123456789012345678901234567890123456789" -end -module Test4343b = begin - val fA : x:int -> int - val fB : x:'a -> y:'a -> 'a list - val gA : (int -> int) - val gB : ('a -> 'a -> 'a list) - val gAB : (int -> int) * ('a -> 'a -> 'a list) - val hB : ('a -> 'a -> 'a list) - val hA : (int -> int) -end -module Test4343c = begin - val typename<'a> : string - val typename2<'a> : string * string -end -module Test4343d = begin - val xList : int list = [1; 2; 3] - val xArray : int [] = [|1; 2; 3|] - val xString : string = "abcdef" - val xOption : int option = Some 12 - val xArray2 : (int * int) [,] = [[(0, 0); (0, 1)] - [(1, 0); (1, 1)]] - val xSeq : seq -end -module Test4343e = begin - type C = - class - new : x:int -> C - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, - [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) - type D = - class - new : x:int -> D - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - module Generic = begin - type CGeneric<'a> = - class - new : x:'a -> CGeneric<'a> - end - val cA : C - val cB : C - val cAB : C * C * C list = - (FSI_0090+Test4343e+C, FSI_0090+Test4343e+C, - [FSI_0090+Test4343e+C; FSI_0090+Test4343e+C]) - type D<'a> = - class - new : x:'a -> D<'a> - override ToString : unit -> string - end - val dA : D = D(1) - val dB : D = D(2) - val dAB : D * D * D list = (D(1), D(2), [D(1); D(2)]) - val dC : D = D(True) - val boxed_dABC : obj list = [D(1); D(2); D(True)] - end -end -type F1 = - class - inherit System.Windows.Forms.Form - interface System.IDisposable - val x: F1 - val x2: F1 - abstract member MMM : bool -> bool - abstract member AAA : int - abstract member ZZZ : int - abstract member BBB : bool with set - member B : unit -> int - member D : unit -> int - member D : x:int -> int - member D : x:int * y:int -> int - override ToString : unit -> string - member D2 : int - member E : int - member D2 : int with set - member E : int with set - static val mutable private sx: F1 - static val mutable private sx2: F1 - static member A : unit -> int - static member C : unit -> int - end -type IP = - struct - new : x:int * y:int -> IP - static val mutable private AA: IP - end -module Regression4643 = begin - type RIP = - struct - new : x:int -> RIP - static val mutable private y: RIP - end - type arg_unused_is_RIP = - struct - new : x:RIP -> arg_unused_is_RIP - end - type arg_used_is_RIP = - struct - new : x:RIP -> arg_used_is_RIP - member X : RIP - end - type field_is_RIP = - struct - val x: RIP - end -end -type Either<'a,'b> = - | This of 'a - | That of 'b -val catch : f:(unit -> 'a) -> Either<'a,(string * string)> -val seqFindIndexFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqFindFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -val seqPickFailure : Either = - That - ("System.Collections.Generic.KeyNotFoundException", - "An index satisfying the predicate was not found in the collection.") -module Regression5218 = begin - val t1 : int = 1 - val t2 : int * int = (1, 2) - val t3 : int * int * int = (1, 2, 3) - val t4 : int * int * int * int = (1, 2, 3, 4) - val t5 : int * int * int * int * int = (1, 2, 3, 4, 5) - val t6 : int * int * int * int * int * int = (1, 2, 3, 4, 5, 6) - val t7 : int * int * int * int * int * int * int = (1, 2, 3, 4, 5, 6, 7) - val t8 : int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8) - val t9 : int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9) - val t10 : int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val t11 : int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - val t12 : - int * int * int * int * int * int * int * int * int * int * int * int = - (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) - val t13 : - int * int * int * int * int * int * int * int * int * int * int * int * - int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) - val t14 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) - val t15 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int * int = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3740 = begin - type Writer<'a> = - interface - abstract member get_path : unit -> string - end - type MyClass = - class - interface Writer - val path: string - end -end - -> type Regression4319_T2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> string - end - -> type Regression4319_T0 = - class - static member ( +-+-+ ) : string - end - -> type Regression4319_T1 = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1b = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1c = - class - static member ( +-+-+ ) : x:('a * 'b) -> string - end - -> type Regression4319_T1d = - class - static member ( +-+-+ ) : x:(int * int) -> string - end - -> type Regression4319_T3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> string - end - -> type Regression4319_U1 = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U1b = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> moreArgs:'c -> string - end - -> type Regression4319_U3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> moreArgs:'d -> string - end - -> type Regression4319_check = - class - static member ( & ) : string - static member ( &^ ) : string - static member ( @ ) : string - static member ( != ) : string - static member ( := ) : string - static member ( ^ ) : string - static member ( / ) : string - static member ( $ ) : string - static member ( ...@ ) : string - static member ( ...!= ) : string - static member ( .../ ) : string - static member ( ...= ) : string - static member ( ...> ) : string - static member ( ...^ ) : string - static member ( ...< ) : string - static member ( ...* ) : string - static member ( ...% ) : string - static member ( = ) : string - static member ( ** ) : string - static member ( > ) : string - static member ( < ) : string - static member ( % ) : string - static member ( * ) : string - static member ( - ) : string - end - -> Expect ABC = ABC -type Regression4469 = - class - new : unit -> Regression4469 - member ToString : unit -> string - end -val r4469 : Regression4469 = FSI_0106+Regression4469 -val it : unit = () - -> Expect ABC = ABC -val it : unit = () - -> module Regression1019_short = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end -module Regression1019_long = begin - val double_nan : float = nan - val double_infinity : float = infinity - val single_nan : float32 = nanf - val single_infinity : float32 = infinityf -end - -> val it : int ref = { contents = 1 } - -> val x : int ref = { contents = 1 } -val f : (unit -> int) - -> val it : int = 1 - -> val it : unit = () - -> val it : int = 3 - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : 'a list - -> val it : 'a list list - -> val it : 'a option - -> val it : 'a list * 'b list - -> val it : x:'a -> 'a - -> val fff : x:'a -> 'a - -> val it : ('a -> 'a) - -> val note_ExpectDupMethod : string = - "Regression4927: Expect error due to duplicate methods in the "+[20 chars] - -> > val note_ExpectDupProperty : string = - "Regression4927: Expect error due to duplicate properties in t"+[23 chars] - -> > > val it : string = "NOTE: Expect IAPrivate less accessible IBPublic" - -> > val it : string = "NOTE: Expect IAPrivate less accessible IBInternal" - -> > module Regression5265_PriPri = begin - type private IAPrivate = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPrivate - abstract member Q : int - end -end - -> val it : string = "NOTE: Expect IAInternal less accessible IBPublic" - -> > module Regression5265_IntInt = begin - type internal IAInternal = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_IntPri = begin - type internal IAInternal = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_PubPub = begin - type IAPublic = - interface - abstract member P : int - end - type IBPublic = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubInt = begin - type IAPublic = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubPri = begin - type IAPublic = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPublic - abstract member Q : int - end -end - -> val it : string = - "Regression4232: Expect an error about duplicate virtual methods from parent type" - -> > val it : string = - "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" - -> type AnAxHostSubClass = - class - inherit System.Windows.Forms.AxHost - new : x:string -> AnAxHostSubClass - end - -> val it : string = - "** Expect error because the active pattern result contains free type variables" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (match value generic)" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" - -> > val it : string = - "** Expect OK, since error message says constraint should work!" - -> val ( |A|B| ) : x:int -> Choice - -> val it : string = "** Expect error since active pattern is not a function!" - -> > val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on match val" - -> val ( |A|B| ) : p:bool -> 'a * 'b -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on parameters" - -> val ( |A|B| ) : aval:'a -> bval:'b -> x:bool -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is generic, but it typar from closure, so OK" - -> val outer : x:'a -> (int -> 'a option) - -> val it : string = - "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" - -> val ( |Check1| ) : a:int -> int * 'a option - -> > module ReflectionEmit = begin - type IA = - interface - abstract member M : #IB -> int - end - and IB = - interface - abstract member M : #IA -> int - end - type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = - interface - abstract member M : int - end - and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = - interface - abstract member M : int - end -end - -> val it : string = - "Regression_139182: Expect the follow code to be accepted without error" - -> type S = - struct - member TheMethod : unit -> int64 - end -val theMethod : s:S -> int64 -type T = - class - new : unit -> T - member Prop5 : int64 - static member Prop1 : int64 - static member Prop2 : int64 - static member Prop3 : int64 - static member Prop4 : string - end - -> val it : System.Threading.ThreadLocal list = [0 {IsValueCreated = false; - Values = ?;}] - -> type MyDU = - | Case1 of Val1: int * Val2: string - | Case2 of string * V2: bool * float - | Case3 of int - | Case4 of Item1: bool - | Case5 of bool * string - | Case6 of Val1: int * bool * string - | Case7 of Big Name: int -val namedFieldVar1 : MyDU = Case1 (5,"") -val namedFieldVar2 : MyDU = Case7 25 - -> exception MyNamedException1 of Val1: int * Val2: string -exception MyNamedException2 of string * V2: bool * float -exception MyNamedException3 of Data: int -exception MyNamedException4 of bool -exception MyNamedException5 of int * string -exception MyNamedException6 of Val1: int * bool * string * Data8: float -exception MyNamedException7 of Big Named Field: int -val namedEx1 : exn = MyNamedException1 (5,"") -val namedEx2 : exn = MyNamedException7 25 - -> type optionRecord = - { x: int option } -val x : optionRecord = { x = None } - -> type optionRecord = - { x: obj } -val x : optionRecord = { x = null } - -> > > diff --git a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl index 386c625eeff..4d3209ca246 100644 --- a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl @@ -1,330 +1,336 @@ + #blaaaaaa // blaaaaaa is not a known command;; + ^^^^^^^^^ + +stdin(219,1): warning FS3353: Invalid directive '#blaaaaaa ' + + type Regression4319_T0 = static member (+-+-+) = "0 arguments";; -----------------------------------------^^^^^ -stdin(572,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(571,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1 = static member (+-+-+) x = "1 argument";; -----------------------------------------^^^^^ -stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(572,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1b = static member (+-+-+) (x) = "1 (argument) [brackets make no diff]";; -----------------------------------------^^^^^ -stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1c = static member (+-+-+) x = let a,b = x in "1 argument, tuple typed from RHS. Still not OK";; -----------------------------------------^^^^^ -stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T1d = static member (+-+-+) (x:int*int) = "1 argument, tuple typed from LHS. Still not OK";; -----------------------------------------^^^^^ -stdin(576,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_T3 = static member (+-+-+) (x,y,z) = "3 arguments";; -----------------------------------------^^^^^ -stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(577,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(578,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; -----------------------------------------^^^^^ -stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U2 = static member (+-+-+) (x,y) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; -----------------------------------------^^^^^ -stdin(582,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(584,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (:=) = "COLON_EQUALS" -------------------^^ -stdin(585,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(584,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(588,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (&) = "AMP" -------------------^ -stdin(589,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. +stdin(588,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. static member (&^) = "AMP_AMP" -------------------^^ -stdin(590,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(589,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(590,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (=) = "EQUALS" -------------------^ -stdin(591,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. +stdin(590,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. static member (!=) = "INFIX_COMPARE_OP" -------------------^^ -stdin(593,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(592,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(597,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(596,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...!=) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^^ -stdin(598,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(597,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...<) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(599,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(598,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...>) = "INFIX_COMPARE_OP" // with $. prefix -------------------^^^^ -stdin(600,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(599,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ($) = "DOLLAR" -------------------^ -stdin(602,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(601,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(602,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (<) = "LESS" -------------------^ -stdin(603,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. +stdin(602,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(603,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (>) = "GREATER" -------------------^ -stdin(604,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. +stdin(603,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(604,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (@) = "INFIX_AT_HAT_OP" -------------------^ -stdin(605,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(604,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(605,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (^) = "INFIX_AT_HAT_OP" -------------------^ -stdin(606,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types +stdin(605,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types static member (...@) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(607,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(606,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (...^) = "INFIX_AT_HAT_OP" // with $. prefix -------------------^^^^ -stdin(608,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(607,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (%) = "PERCENT_OP" -------------------^ -stdin(609,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(608,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (-) = "MINUS" -------------------^ -stdin(611,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(610,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( * ) = "STAR" --------------------^ -stdin(612,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(611,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member (/) = "INFIX_STAR_DIV_MOD_OP" -------------------^ -stdin(614,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(613,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...* ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(616,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(615,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( .../ ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(617,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(616,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ...% ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix --------------------^^^^ -stdin(618,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(617,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... static member ( ** ) = "INFIX_STAR_STAR_OP" --------------------^^ -stdin(619,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... +stdin(618,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... member this.ToString() = "ABC" ----------------^^^^^^^^ -stdin(624,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. +stdin(623,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. member this.M() = "string" ----------------^ -stdin(765,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. +stdin(764,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. member this.P = "string" ----------------^ -stdin(772,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. +stdin(771,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. type public IBPublic = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^ -stdin(779,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(778,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. type internal IBInternal = interface inherit IAPrivate abstract Q : int end ------------------^^^^^^^^^^ -stdin(784,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. +stdin(783,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. type public IBPublic = interface inherit IAInternal abstract Q : int end ------------------^^^^^^^^ -stdin(793,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. +stdin(792,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. override x.M(a:string) = 1 -------------------^ -stdin(825,20): error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member Regression4232.D.M : 'U -> int' and 'abstract member Regression4232.D.M : 'T -> int' +stdin(824,20): error FS0361: The override 'M: string -> int' implements more than one abstract slot, e.g. 'abstract Regression4232.D.M: 'U -> int' and 'abstract Regression4232.D.M: 'T -> int' let (|A|B|) (x:int) = A x;; -----^^^^^ -stdin(833,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(832,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (x:'a) = A x;; -----^^^^^ -stdin(836,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(835,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) (p:'a) (x:int) = A p;; -----^^^^^ -stdin(839,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' +stdin(838,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' let (|A|B|) = failwith "" : Choice;; -----^^^^^ -stdin(845,6): error FS1209: Active pattern '|A|B|' is not a function +stdin(844,6): error FS1209: Active pattern '|A|B|' is not a function diff --git a/tests/fsharp/core/printing/z.output.test.off.stdout.47.bsl b/tests/fsharp/core/printing/z.output.test.off.stdout.47.bsl new file mode 100644 index 00000000000..512975f670b --- /dev/null +++ b/tests/fsharp/core/printing/z.output.test.off.stdout.47.bsl @@ -0,0 +1,1729 @@ + +> val it: unit = () + +> val repeatId: string + +> val repeatId: string + +namespace FSI_0005 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +namespace FSI_0006 + val x1: int + val x2: string + val x3: 'a option + val x4: int option + val x5: 'a list + val x6: int list + val x7: System.Windows.Forms.Form + val x8: int[,] + val x9: Lazy + +> val x1: seq +val x2: seq +val x3: seq +val f1: System.Windows.Forms.Form +val fs: System.Windows.Forms.Form[] +val xs: string list +val xa: string[] +val xa2: string[,] +val sxs0: Set + +> val sxs1: Set + +> val sxs2: Set + +> val sxs3: Set + +> val sxs4: Set + +> val sxs200: Set + +> val msxs0: Map + +> val msxs1: Map + +> val msxs2: Map + +> val msxs3: Map + +> val msxs4: Map + +> val msxs200: Map + +> module M = + val a: string + val b: + (seq * seq * seq * System.Windows.Forms.Form) option * + (string list * string list * string[,]) option +type T = + new: a: int * b: int -> T + member AMethod: x: int -> int + static member StaticMethod: x: int -> int + member AProperty: int + static member StaticProperty: int +val f_as_method: x: int -> int +val f_as_thunk: (int -> int) +val refCell: string ref +module D1 = + val words: System.Collections.Generic.IDictionary + val words2000: System.Collections.Generic.IDictionary + +> > module D2 = + val words: IDictionary + val words2000: IDictionary +val opt1: 'a option +val opt1b: int option +val opt4: 'a option option option option +val opt4b: int option option option option +val opt5: int list option option option option option list +val mkStr: n: int -> string +val strs: string[] +val str7s: string[] +val grids: string[,] + +> type tree = + | L + | N of tree list +val mkT: w: int -> d: int -> tree +val tree: w: int -> d: int -> tree + +> [Building 2 4...done] +val tree_2_4: tree + +> [Building 2 6...done] +val tree_2_6: tree + +> [Building 2 8...done] +val tree_2_8: tree + +> [Building 2 10...done] +val tree_2_10: tree + +> [Building 2 12...done] +val tree_2_12: tree + +> [Building 2 14...done] +val tree_2_14: tree + +> [Building 3 8...done] +val tree_3_8: tree + +> [Building 4 8...done] +val tree_4_8: tree + +> [Building 5 8...done] +val tree_5_8: tree + +> [Building 6 8...done] +val tree_6_8: tree + +> [Building 5 3...done] +val tree_5_3: tree + +> > type X = + | Var of int + | Bop of int * X * X +val generate: x: int -> X + +> val exps: X list + +> module Exprs = + val x1: X + val x2: X + val x3: X + val x4: X + val x5: X + val x6: X + val x7: X + val x8: X + val x9: X + val x10: X + val x11: X + +> type C = + new: x: string -> C + override ToString: unit -> string +val c1: C +val csA: C[] +val csB: C[] +val csC: C[] + +> exception Abc + +> exception AbcInt of int + +> exception AbcString of string + +> exception AbcExn of exn list + +> exception AbcException of System.Exception list + +> val exA1: exn +val exA2: exn +val exA3: exn +val exA4: exn +val exA5: exn +exception Ex0 +exception ExUnit of unit +exception ExUnits of unit * unit +exception ExUnitOption of unit option +val ex0: exn +val exU: exn +val exUs: exn +val exUSome: exn +val exUNone: exn +type 'a T4063 = | AT4063 of 'a + +> val valAT3063_12: int T4063 + +> val valAT3063_True: bool T4063 + +> val valAT3063_text: string T4063 + +> val valAT3063_null: System.Object T4063 + +> type M4063<'a> = + new: x: 'a -> M4063<'a> + +> val v4063: M4063 + +> type Taaaaa<'a> = + new: unit -> Taaaaa<'a> + +> type Taaaaa2<'a> = + inherit Taaaaa<'a> + new: unit -> Taaaaa2<'a> + member M: unit -> Taaaaa2<'a> + +> type Tbbbbb<'a> = + new: x: 'a -> Tbbbbb<'a> + member M: unit -> 'a + +> type Tbbbbb2 = + inherit Tbbbbb + new: x: string -> Tbbbbb2 + +> val it: (unit -> string) = + +> module RepeatedModule = + val repeatedByteLiteral: byte[] + +> module RepeatedModule = + val repeatedByteLiteral: byte[] + +> val it: string = "Check #help" + +> + F# Interactive directives: + + #r "file.dll";; // Reference (dynamically load) the given DLL + #i "package source uri";; // Include package source uri when searching for packages + #I "path";; // Add the given search path for referenced DLLs + #load "file.fs" ...;; // Load the given file(s) as if compiled and referenced + #time ["on"|"off"];; // Toggle timing on/off + #help;; // Display help + #quit;; // Exit + + F# Interactive command line options: + + + +> val it: string = "Check #time on and then off" + +> +--> Timing now on + +> +--> Timing now off + +> val it: string = "Check #unknown command" + +> val it: string = + "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" + +> +--> Added '/' to library include path + +> type internal T1 = + | A + | B + +> type internal T2 = + { x: int } + +> type internal T3 + +> type internal T4 = + new: unit -> T4 + +> type T1 = + internal | A + | B + +> type T2 = + internal { x: int } + +> type private T1 = + | A + | B + +> type private T2 = + { x: int } + +> type T1 = + private | A + | B + +> type T2 = + private { x: int } + +> type internal T1 = + private | A + | B + +> type internal T2 = + private { x: int } + +> type private T3 + +> type private T4 = + new: unit -> T4 + +> exception X1 of int + +> exception private X2 of int + +> exception internal X3 of int + +> type T0 = + new: unit -> T0 +type T1Post<'a> = + new: unit -> T1Post<'a> +type 'a T1Pre = + new: unit -> 'a T1Pre + +> type T0 with + member M: unit -> T0 list +type T0 with + member P: T0 * T0 +type T0 with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type T1Post<'a> with + member M: unit -> T1Post<'a> list +type T1Post<'a> with + member P: T1Post<'a> * T1Post<'a> +type T1Post<'a> with + member E: IEvent + +> type 'a T1Pre with + member M: unit -> 'a T1Pre list +type 'a T1Pre with + member P: 'a T1Pre * 'a T1Pre +type 'a T1Pre with + member E: IEvent + +> type r = + { + f0: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + } +val r10: r +val r10s: r[] +val r10s': string * r[] + +> val x1564_A1: int + + +--> Added '\' to library include path + +val x1564_A2: int + + +--> Added '\' to library include path + +val x1564_A3: int + +> type internal Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + +> module internal InternalM = + val x: int + type Foo2 = + private new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member private Prop3: int + type private Foo3 = + new: x: int * y: int * z: int -> Foo3 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 +module internal PrivateM = + val private x: int + type private Foo2 = + new: x: int * y: int * z: int -> Foo2 + 3 overloads + member Prop1: int + member Prop2: int + member Prop3: int + type T1 = + | A + | B + type T2 = + { x: int } + type T3 + type T4 = + new: unit -> T4 + type T5 = + | A + | B + type T6 = + { x: int } + type private T7 = + | A + | B + type private T8 = + { x: int } + type T9 = + private | A + | B + type T10 = + private { x: int } + type T11 = + private | A + | B + type T12 = + private { x: int } + type private T13 + type private T14 = + new: unit -> T14 + +> val it: seq = + seq + [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); + (58, "2/10/2009", 1)] + +> module Test4343a = + val mk: i: int -> string + val x100: string + val x90: string + val x80: string + val x75: string + val x74: string + val x73: string + val x72: string + val x71: string + val x70: string +module Test4343b = + val fA: x: int -> int + val fB: x: 'a -> y: 'a -> 'a list + val gA: (int -> int) + val gB: ('a -> 'a -> 'a list) + val gAB: (int -> int) * ('a -> 'a -> 'a list) + val hB: ('a -> 'a -> 'a list) + val hA: (int -> int) +module Test4343c = + val typename<'a> : string + val typename2<'a> : string * string +module Test4343d = + val xList: int list + val xArray: int[] + val xString: string + val xOption: int option + val xArray2: (int * int)[,] + val xSeq: seq +module Test4343e = + type C = + new: x: int -> C + val cA: C + val cB: C + val cAB: C * C * C list + type D = + new: x: int -> D + override ToString: unit -> string + val dA: D + val dB: D + val dAB: D * D * D list + module Generic = + type CGeneric<'a> = + new: x: 'a -> CGeneric<'a> + val cA: C + val cB: C + val cAB: C * C * C list + type D<'a> = + new: x: 'a -> D<'a> + override ToString: unit -> string + val dA: D + val dB: D + val dAB: D * D * D list + val dC: D + val boxed_dABC: obj list +type F1 = + inherit System.Windows.Forms.Form + interface System.IDisposable + val x: F1 + val x2: F1 + member B: unit -> int + member D: x: int -> int + 2 overloads + abstract MMM: bool -> bool + override ToString: unit -> string + static member A: unit -> int + static member C: unit -> int + abstract AAA: int + abstract BBB: bool with set + member D2: int + member E: int + abstract ZZZ: int + static val mutable private sx: F1 + static val mutable private sx2: F1 +[] +type IP = + new: x: int * y: int -> IP + static val mutable private AA: IP +module Regression4643 = + [] + type RIP = + new: x: int -> RIP + static val mutable private y: RIP + [] + type arg_unused_is_RIP = + new: x: RIP -> arg_unused_is_RIP + [] + type arg_used_is_RIP = + new: x: RIP -> arg_used_is_RIP + member X: RIP + [] + type field_is_RIP = + val x: RIP +type Either<'a,'b> = + | This of 'a + | That of 'b +val catch: f: (unit -> 'a) -> Either<'a,(string * string)> +val seqFindIndexFailure: Either +val seqFindFailure: Either +val seqPickFailure: Either +module Regression5218 = + val t1: int + val t2: int * int + val t3: int * int * int + val t4: int * int * int * int + val t5: int * int * int * int * int + val t6: int * int * int * int * int * int + val t7: int * int * int * int * int * int * int + val t8: int * int * int * int * int * int * int * int + val t9: int * int * int * int * int * int * int * int * int + val t10: int * int * int * int * int * int * int * int * int * int + val t11: int * int * int * int * int * int * int * int * int * int * int + val t12: + int * int * int * int * int * int * int * int * int * int * int * int + val t13: + int * int * int * int * int * int * int * int * int * int * int * int * + int + val t14: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int + val t15: + int * int * int * int * int * int * int * int * int * int * int * int * + int * int * int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3739 = + type IB = + abstract AbstractMember: int -> int + type C<'a when 'a :> IB> = + new: unit -> C<'a> + static member StaticMember: x: 'a -> int + +> module Regression3740 = + type Writer<'a> = + abstract get_path: unit -> string + type MyClass = + interface Writer + val path: string + +> type Regression4319_T2 = + static member (+-+-+) : x: 'a * y: 'b -> string + +> type Regression4319_T0 = + static member (+-+-+) : string + +> type Regression4319_T1 = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1b = + static member (+-+-+) : x: 'a -> string + +> type Regression4319_T1c = + static member (+-+-+) : x: ('a * 'b) -> string + +> type Regression4319_T1d = + static member (+-+-+) : x: (int * int) -> string + +> type Regression4319_T3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> string + +> type Regression4319_U1 = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U1b = + static member (+-+-+) : x: 'a -> moreArgs: 'b -> string + +> type Regression4319_U2 = + static member (+-+-+) : x: 'a * y: 'b -> moreArgs: 'c -> string + +> type Regression4319_U3 = + static member (+-+-+) : x: 'a * y: 'b * z: 'c -> moreArgs: 'd -> string + +> type Regression4319_check = + static member (&) : string + static member (&^) : string + static member (@) : string + static member (!=) : string + static member (:=) : string + static member (^) : string + static member (/) : string + static member ($) : string + static member (...@) : string + static member (...!=) : string + static member (.../) : string + static member (...=) : string + static member (...>) : string + static member (...^) : string + static member (...<) : string + static member ( ...* ) : string + static member (...%) : string + static member (=) : string + static member ( ** ) : string + static member (>) : string + static member (<) : string + static member (%) : string + static member ( * ) : string + static member (-) : string + +> Expect ABC = ABC +type Regression4469 = + new: unit -> Regression4469 + member ToString: unit -> string +val r4469: Regression4469 +val it: unit + +> Expect ABC = ABC +val it: unit = () + +> module Regression1019_short = + val double_nan: float + val double_infinity: float + val single_nan: float32 + val single_infinity: float32 +module Regression1019_long = + val double_nan: float + val double_infinity: float + val single_nan: float32 + val single_infinity: float32 + +> val it: int ref = { contents = 1 } + +> val x: int ref +val f: (unit -> int) + +> val it: int = 1 + +> val it: unit = () + +> val it: int = 3 + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: int[] = + [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; + ...|] + +> val it: 'a list + +> val it: 'a list list + +> val it: 'a option + +> val it: 'a list * 'b list + +> val it: x: 'a -> 'a + +> val fff: x: 'a -> 'a + +> val it: ('a -> 'a) + +> val note_ExpectDupMethod: string + +> > val note_ExpectDupProperty: string + +> > > val it: string = "NOTE: Expect IAPrivate less accessible IBPublic" + +> > val it: string = "NOTE: Expect IAPrivate less accessible IBInternal" + +> > module Regression5265_PriPri = + type private IAPrivate = + abstract P: int + type private IBPrivate = + inherit IAPrivate + abstract Q: int + +> val it: string = "NOTE: Expect IAInternal less accessible IBPublic" + +> > module Regression5265_IntInt = + type internal IAInternal = + abstract P: int + type internal IBInternal = + inherit IAInternal + abstract Q: int + +> module Regression5265_IntPri = + type internal IAInternal = + abstract P: int + type private IBPrivate = + inherit IAInternal + abstract Q: int + +> module Regression5265_PubPub = + type IAPublic = + abstract P: int + type IBPublic = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubInt = + type IAPublic = + abstract P: int + type internal IBInternal = + inherit IAPublic + abstract Q: int + +> module Regression5265_PubPri = + type IAPublic = + abstract P: int + type private IBPrivate = + inherit IAPublic + abstract Q: int + +> val it: string = + "Regression4232: Expect an error about duplicate virtual methods from parent type" + +> > val it: string = + "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" + +> type AnAxHostSubClass = + inherit System.Windows.Forms.AxHost + new: x: string -> AnAxHostSubClass + +> val it: string = + "** Expect error because the active pattern result contains free type variables" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (match value generic)" + +> > val it: string = + "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" + +> > val it: string = + "** Expect OK, since error message says constraint should work!" + +> val (|A|B|) : x: int -> Choice + +> val it: string = "** Expect error since active pattern is not a function!" + +> > val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on match val" + +> val (|A|B|) : p: bool -> 'a * 'b -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is not too generic, typars depend on parameters" + +> val (|A|B|) : aval: 'a -> bval: 'b -> x: bool -> Choice<'a,'b> + +> val it: string = + "** Expect OK since active pattern result is generic, but it typar from closure, so OK" + +> val outer: x: 'a -> (int -> 'a option) + +> val it: string = + "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" + +> val (|Check1|) : a: int -> int * 'a option + +> > module ReflectionEmit = + type IA = + abstract M: #IB -> int + and IB = + abstract M: #IA -> int + type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = + abstract M: int + and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = + abstract M: int + +> val it: string = + "Regression_139182: Expect the follow code to be accepted without error" + +> [] +type S = + member TheMethod: unit -> int64 +val theMethod: s: S -> int64 +type T = + new: unit -> T + member Prop5: int64 + static member Prop1: int64 + static member Prop2: int64 + static member Prop3: int64 + static member Prop4: string + +> val it: System.Threading.ThreadLocal list = [0 {IsValueCreated = false; + Values = ?;}] + +> type MyDU = + | Case1 of Val1: int * Val2: string + | Case2 of string * V2: bool * float + | Case3 of int + | Case4 of Item1: bool + | Case5 of bool * string + | Case6 of Val1: int * bool * string + | Case7 of ``Big Name`` : int +val namedFieldVar1: MyDU +val namedFieldVar2: MyDU + +> exception MyNamedException1 of Val1: int * Val2: string +exception MyNamedException2 of string * V2: bool * float +exception MyNamedException3 of Data: int +exception MyNamedException4 of bool +exception MyNamedException5 of int * string +exception MyNamedException6 of Val1: int * bool * string * Data8: float +exception MyNamedException7 of ``Big Named Field`` : int +val namedEx1: exn +val namedEx2: exn + +> type optionRecord = + { x: int option } +val x: optionRecord + +> type optionRecord = + { x: obj } +val x: optionRecord + +> type RecordWithMembers = + { x: obj } + member Method: unit -> int + member Property: int + +> type UnionWithMembers = + | Case1 + | Case2 of int + member Method: unit -> int + member Property: int + +> type OneFieldRecordNoXmlDoc = + { OneField: obj } + +> type OneFieldRecordXmlDoc = + { + OneField: obj + } + +> type TwoFieldRecordNoXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type TwoFieldRecordXmlDoc = + { + TwoFields1: obj + TwoFields2: obj + } + +> type Int32 with + member ExtrinsicExtensionProperty: int +type Int32 with + member ExtrinsicExtensionMethod: unit -> int + +> val ``value with spaces in name`` : bool + +> val functionWhichTakesLongNameMixedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameTupledParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int * + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int * + ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int * + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesLongNameCurriedParameters: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int + -> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int + -> cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc: int + -> dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: int + -> int + +> val functionWhichTakesMixedLengthCurriedParametersA: + a: 'a -> b: 'b -> c: 'c -> ddddddddddddddddddddddddddddddddddddddddddddd: 'd + -> int + +> val functionWhichTakesMixedLengthCurriedParametersB: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'a -> b: 'b -> c: 'c -> d: 'd -> int + +> val f: ``parameter with spaces in name`` : int -> int + +> val functionWhichTakesAParameterPeeciselyPlusButNotOpAddition: + ``+`` : (int -> int -> int) -> int + +> val functionWhichTakesAParameterOpAddition: (+) : (int -> int -> int) -> int + +> val functionWhichTakesAParameterCalled_land: + ``land`` : (int -> int -> int) -> int + +> type RecordWithStrangeNames = + { + ``funky name`` : obj + op_Addition: obj + ``+`` : obj + ``land`` : obj + ``base`` : obj + } + +> type UnionWithSpacesInNamesOfCases = + | ``Funky name`` + | ``Funky name 2`` + +> type ``Type with spaces in name`` = + | A + | B + +> type op_Addition = + | A + | B + +> type ``land`` = + | A + | B + +> module ``Module with spaces in name`` = + val x: int + +> module op_Addition = + val x: int + +> module ``land`` = + val x: int + +> val ``+`` : x: 'a -> y: 'b -> int + +> val (+) : x: int -> y: int -> int + +> val ``base`` : int + +> val (mod) : int + +> val ``or`` : int + +> val ``land`` : int + +> val ``.ctor`` : int + +> val ``.cctor`` : int + +> [] +val SomeLiteralWithASomewhatLongName: string + = "SomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val SomeLiteralWithASomewhatLongName2: string + = + "SomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharactersSomeVeryLongLiteralValueWithLotsOfCharacters" +[] +val ShortName: string = "hi" + +> > > diff --git a/tests/fsharp/core/printing/z.output.test.off.stdout.bsl b/tests/fsharp/core/printing/z.output.test.off.stdout.bsl deleted file mode 100644 index 9c90f3e2fac..00000000000 --- a/tests/fsharp/core/printing/z.output.test.off.stdout.bsl +++ /dev/null @@ -1,1765 +0,0 @@ - -> val it : unit = () - -> > val repeatId : string - -> val repeatId : string - -namespace FSI_0005 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -namespace FSI_0006 - val x1 : int - val x2 : string - val x3 : 'a option - val x4 : int option - val x5 : 'a list - val x6 : int list - val x7 : System.Windows.Forms.Form - val x8 : int [,] - val x9 : Lazy - -> val x1 : seq -val x2 : seq -val x3 : seq -val f1 : System.Windows.Forms.Form -val fs : System.Windows.Forms.Form [] -val xs : string list -val xa : string [] -val xa2 : string [,] -val sxs0 : Set - -> val sxs1 : Set - -> val sxs2 : Set - -> val sxs3 : Set - -> val sxs4 : Set - -> val sxs200 : Set - -> val msxs0 : Map - -> val msxs1 : Map - -> val msxs2 : Map - -> val msxs3 : Map - -> val msxs4 : Map - -> val msxs200 : Map - -> module M = begin - val a : string - val b : - (seq * seq * seq * System.Windows.Forms.Form) option * - (string list * string list * string [,]) option -end -type T = - class - new : a:int * b:int -> T - member AMethod : x:int -> int - member AProperty : int - static member StaticMethod : x:int -> int - static member StaticProperty : int - end -val f_as_method : x:int -> int -val f_as_thunk : (int -> int) -val refCell : string ref -module D1 = begin - val words : System.Collections.Generic.IDictionary - val words2000 : System.Collections.Generic.IDictionary -end - -> > module D2 = begin - val words : IDictionary - val words2000 : IDictionary -end -val opt1 : 'a option -val opt1b : int option -val opt4 : 'a option option option option -val opt4b : int option option option option -val opt5 : int list option option option option option list -val mkStr : n:int -> string -val strs : string [] -val str7s : string [] -val grids : string [,] - -> type tree = - | L - | N of tree list -val mkT : w:int -> d:int -> tree -val tree : w:int -> d:int -> tree - -> [Building 2 4...done] -val tree_2_4 : tree - -> [Building 2 6...done] -val tree_2_6 : tree - -> [Building 2 8...done] -val tree_2_8 : tree - -> [Building 2 10...done] -val tree_2_10 : tree - -> [Building 2 12...done] -val tree_2_12 : tree - -> [Building 2 14...done] -val tree_2_14 : tree - -> [Building 3 8...done] -val tree_3_8 : tree - -> [Building 4 8...done] -val tree_4_8 : tree - -> [Building 5 8...done] -val tree_5_8 : tree - -> [Building 6 8...done] -val tree_6_8 : tree - -> [Building 5 3...done] -val tree_5_3 : tree - -> > type X = - | Var of int - | Bop of int * X * X -val generate : x:int -> X - -> val exps : X list - -> module Exprs = begin - val x1 : X - val x2 : X - val x3 : X - val x4 : X - val x5 : X - val x6 : X - val x7 : X - val x8 : X - val x9 : X - val x10 : X - val x11 : X -end - -> type C = - class - new : x:string -> C - override ToString : unit -> string - end -val c1 : C -val csA : C [] -val csB : C [] -val csC : C [] - -> exception Abc - -> exception AbcInt of int - -> exception AbcString of string - -> exception AbcExn of exn list - -> exception AbcException of System.Exception list - -> val exA1 : exn -val exA2 : exn -val exA3 : exn -val exA4 : exn -val exA5 : exn -exception Ex0 -exception ExUnit of unit -exception ExUnits of unit * unit -exception ExUnitOption of unit option -val ex0 : exn -val exU : exn -val exUs : exn -val exUSome : exn -val exUNone : exn -type 'a T4063 = | AT4063 of 'a - -> val valAT3063_12 : int T4063 - -> val valAT3063_True : bool T4063 - -> val valAT3063_text : string T4063 - -> val valAT3063_null : System.Object T4063 - -> type M4063<'a> = - class - new : x:'a -> M4063<'a> - end - -> val v4063 : M4063 - -> type Taaaaa<'a> = - class - new : unit -> Taaaaa<'a> - end - -> type Taaaaa2<'a> = - class - inherit Taaaaa<'a> - new : unit -> Taaaaa2<'a> - member M : unit -> Taaaaa2<'a> - end - -> type Tbbbbb<'a> = - class - new : x:'a -> Tbbbbb<'a> - member M : unit -> 'a - end - -> type Tbbbbb2 = - class - inherit Tbbbbb - new : x:string -> Tbbbbb2 - end - -> val it : (unit -> string) = - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] -end - -> module RepeatedModule = begin - val repeatedByteLiteral : byte [] -end - -> val it : string = "Check #help" - -> - F# Interactive directives: - - #r "file.dll";; Reference (dynamically load) the given DLL - #I "path";; Add the given search path for referenced DLLs - #load "file.fs" ...;; Load the given file(s) as if compiled and referenced - #time ["on"|"off"];; Toggle timing on/off - #help;; Display help - #quit;; Exit - - F# Interactive command line options: - - - -> val it : string = "Check #time on and then off" - -> ---> Timing now on - -> ---> Timing now off - -> val it : string = "Check #unknown command" - -> Invalid directive '#blaaaaaa ' -> val it : string = - "Check #I with a known directory (to avoid a warning, which includes the location of this file, which is fragile...)" - -> ---> Added '/' to library include path - -> type internal T1 = - | A - | B - -> type internal T2 = - { x: int } - -> type internal T3 - -> type internal T4 = - class - new : unit -> T4 - end - -> type T1 = - internal | A - | B - -> type T2 = - internal { x: int } - -> type private T1 = - | A - | B - -> type private T2 = - { x: int } - -> type T1 = - private | A - | B - -> type T2 = - private { x: int } - -> type internal T1 = - private | A - | B - -> type internal T2 = - private { x: int } - -> type private T3 - -> type private T4 = - class - new : unit -> T4 - end - -> exception X1 of int - -> exception private X2 of int - -> exception internal X3 of int - -> type T0 = - class - new : unit -> T0 - end -type T1Post<'a> = - class - new : unit -> T1Post<'a> - end -type 'a T1Pre = - class - new : unit -> 'a T1Pre - end - -> type T0 with - member M : unit -> T0 list -type T0 with - member P : T0 * T0 -type T0 with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type T1Post<'a> with - member M : unit -> T1Post<'a> list -type T1Post<'a> with - member P : T1Post<'a> * T1Post<'a> -type T1Post<'a> with - member E : IEvent - -> type 'a T1Pre with - member M : unit -> 'a T1Pre list -type 'a T1Pre with - member P : 'a T1Pre * 'a T1Pre -type 'a T1Pre with - member E : IEvent - -> type r = - { f0: int - f1: int - f2: int - f3: int - f4: int - f5: int - f6: int - f7: int - f8: int - f9: int } -val r10 : r -val r10s : r [] -val r10s' : string * r [] - -> val x1564_A1 : int - - ---> Added '\' to library include path - -val x1564_A2 : int - - ---> Added '\' to library include path - -val x1564_A3 : int - -> type internal Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - -> module internal InternalM = begin - val x : int - type Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - private new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member private Prop3 : int - end - type private Foo3 = - class - new : unit -> Foo3 - new : x:int -> Foo3 - new : x:int * y:int -> Foo3 - new : x:int * y:int * z:int -> Foo3 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end -module internal PrivateM = begin - val private x : int - type private Foo2 = - class - new : unit -> Foo2 - new : x:int -> Foo2 - new : x:int * y:int -> Foo2 - new : x:int * y:int * z:int -> Foo2 - member Prop1 : int - member Prop2 : int - member Prop3 : int - end - type T1 = - | A - | B - type T2 = - { x: int } - type T3 - type T4 = - class - new : unit -> T4 - end - type T5 = - | A - | B - type T6 = - { x: int } - type private T7 = - | A - | B - type private T8 = - { x: int } - type T9 = - private | A - | B - type T10 = - private { x: int } - type T11 = - private | A - | B - type T12 = - private { x: int } - type private T13 - type private T14 = - class - new : unit -> T14 - end -end - -> val it : seq = - seq - [(43, "10/28/2008", 1); (46, "11/18/2008", 1); (56, "1/27/2009", 2); - (58, "2/10/2009", 1)] - -> module Test4343a = begin - val mk : i:int -> string - val x100 : string - val x90 : string - val x80 : string - val x75 : string - val x74 : string - val x73 : string - val x72 : string - val x71 : string - val x70 : string -end -module Test4343b = begin - val fA : x:int -> int - val fB : x:'a -> y:'a -> 'a list - val gA : (int -> int) - val gB : ('a -> 'a -> 'a list) - val gAB : (int -> int) * ('a -> 'a -> 'a list) - val hB : ('a -> 'a -> 'a list) - val hA : (int -> int) -end -module Test4343c = begin - val typename<'a> : string - val typename2<'a> : string * string -end -module Test4343d = begin - val xList : int list - val xArray : int [] - val xString : string - val xOption : int option - val xArray2 : (int * int) [,] - val xSeq : seq -end -module Test4343e = begin - type C = - class - new : x:int -> C - end - val cA : C - val cB : C - val cAB : C * C * C list - type D = - class - new : x:int -> D - override ToString : unit -> string - end - val dA : D - val dB : D - val dAB : D * D * D list - module Generic = begin - type CGeneric<'a> = - class - new : x:'a -> CGeneric<'a> - end - val cA : C - val cB : C - val cAB : C * C * C list - type D<'a> = - class - new : x:'a -> D<'a> - override ToString : unit -> string - end - val dA : D - val dB : D - val dAB : D * D * D list - val dC : D - val boxed_dABC : obj list - end -end -type F1 = - class - inherit System.Windows.Forms.Form - interface System.IDisposable - val x: F1 - val x2: F1 - abstract member MMM : bool -> bool - abstract member AAA : int - abstract member ZZZ : int - abstract member BBB : bool with set - member B : unit -> int - member D : unit -> int - member D : x:int -> int - member D : x:int * y:int -> int - override ToString : unit -> string - member D2 : int - member E : int - member D2 : int with set - member E : int with set - static val mutable private sx: F1 - static val mutable private sx2: F1 - static member A : unit -> int - static member C : unit -> int - end -type IP = - struct - new : x:int * y:int -> IP - static val mutable private AA: IP - end -module Regression4643 = begin - type RIP = - struct - new : x:int -> RIP - static val mutable private y: RIP - end - type arg_unused_is_RIP = - struct - new : x:RIP -> arg_unused_is_RIP - end - type arg_used_is_RIP = - struct - new : x:RIP -> arg_used_is_RIP - member X : RIP - end - type field_is_RIP = - struct - val x: RIP - end -end -type Either<'a,'b> = - | This of 'a - | That of 'b -val catch : f:(unit -> 'a) -> Either<'a,(string * string)> -val seqFindIndexFailure : Either -val seqFindFailure : Either -val seqPickFailure : Either -module Regression5218 = begin - val t1 : int - val t2 : int * int - val t3 : int * int * int - val t4 : int * int * int * int - val t5 : int * int * int * int * int - val t6 : int * int * int * int * int * int - val t7 : int * int * int * int * int * int * int - val t8 : int * int * int * int * int * int * int * int - val t9 : int * int * int * int * int * int * int * int * int - val t10 : int * int * int * int * int * int * int * int * int * int - val t11 : int * int * int * int * int * int * int * int * int * int * int - val t12 : - int * int * int * int * int * int * int * int * int * int * int * int - val t13 : - int * int * int * int * int * int * int * int * int * int * int * int * - int - val t14 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int - val t15 : - int * int * int * int * int * int * int * int * int * int * int * int * - int * int * int -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3739 = begin - type IB = - interface - abstract member AbstractMember : int -> int - end - type C<'a when 'a :> IB> = - class - new : unit -> C<'a> - static member StaticMember : x:'a -> int - end -end - -> module Regression3740 = begin - type Writer<'a> = - interface - abstract member get_path : unit -> string - end - type MyClass = - class - interface Writer - val path: string - end -end - -> type Regression4319_T2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> string - end - -> type Regression4319_T0 = - class - static member ( +-+-+ ) : string - end - -> type Regression4319_T1 = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1b = - class - static member ( +-+-+ ) : x:'a -> string - end - -> type Regression4319_T1c = - class - static member ( +-+-+ ) : x:('a * 'b) -> string - end - -> type Regression4319_T1d = - class - static member ( +-+-+ ) : x:(int * int) -> string - end - -> type Regression4319_T3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> string - end - -> type Regression4319_U1 = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U1b = - class - static member ( +-+-+ ) : x:'a -> moreArgs:'b -> string - end - -> type Regression4319_U2 = - class - static member ( +-+-+ ) : x:'a * y:'b -> moreArgs:'c -> string - end - -> type Regression4319_U3 = - class - static member ( +-+-+ ) : x:'a * y:'b * z:'c -> moreArgs:'d -> string - end - -> type Regression4319_check = - class - static member ( & ) : string - static member ( &^ ) : string - static member ( @ ) : string - static member ( != ) : string - static member ( := ) : string - static member ( ^ ) : string - static member ( / ) : string - static member ( $ ) : string - static member ( ...@ ) : string - static member ( ...!= ) : string - static member ( .../ ) : string - static member ( ...= ) : string - static member ( ...> ) : string - static member ( ...^ ) : string - static member ( ...< ) : string - static member ( ...* ) : string - static member ( ...% ) : string - static member ( = ) : string - static member ( ** ) : string - static member ( > ) : string - static member ( < ) : string - static member ( % ) : string - static member ( * ) : string - static member ( - ) : string - end - -> Expect ABC = ABC -type Regression4469 = - class - new : unit -> Regression4469 - member ToString : unit -> string - end -val r4469 : Regression4469 -val it : unit - -> Expect ABC = ABC -val it : unit = () - -> module Regression1019_short = begin - val double_nan : float - val double_infinity : float - val single_nan : float32 - val single_infinity : float32 -end -module Regression1019_long = begin - val double_nan : float - val double_infinity : float - val single_nan : float32 - val single_infinity : float32 -end - -> val it : int ref = { contents = 1 } - -> val x : int ref -val f : (unit -> int) - -> val it : int = 1 - -> val it : unit = () - -> val it : int = 3 - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : int [] = - [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; - ...|] - -> val it : 'a list - -> val it : 'a list list - -> val it : 'a option - -> val it : 'a list * 'b list - -> val it : x:'a -> 'a - -> val fff : x:'a -> 'a - -> val it : ('a -> 'a) - -> val note_ExpectDupMethod : string - -> > val note_ExpectDupProperty : string - -> > > val it : string = "NOTE: Expect IAPrivate less accessible IBPublic" - -> > val it : string = "NOTE: Expect IAPrivate less accessible IBInternal" - -> > module Regression5265_PriPri = begin - type private IAPrivate = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPrivate - abstract member Q : int - end -end - -> val it : string = "NOTE: Expect IAInternal less accessible IBPublic" - -> > module Regression5265_IntInt = begin - type internal IAInternal = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_IntPri = begin - type internal IAInternal = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAInternal - abstract member Q : int - end -end - -> module Regression5265_PubPub = begin - type IAPublic = - interface - abstract member P : int - end - type IBPublic = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubInt = begin - type IAPublic = - interface - abstract member P : int - end - type internal IBInternal = - interface - inherit IAPublic - abstract member Q : int - end -end - -> module Regression5265_PubPri = begin - type IAPublic = - interface - abstract member P : int - end - type private IBPrivate = - interface - inherit IAPublic - abstract member Q : int - end -end - -> val it : string = - "Regression4232: Expect an error about duplicate virtual methods from parent type" - -> > val it : string = - "** Expect AnAxHostSubClass to be accepted. AxHost has a newslot virtual RightToLeft property outscope RightToLeft on Control" - -> type AnAxHostSubClass = - class - inherit System.Windows.Forms.AxHost - new : x:string -> AnAxHostSubClass - end - -> val it : string = - "** Expect error because the active pattern result contains free type variables" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (match value generic)" - -> > val it : string = - "** Expect error because the active pattern result contains free type variables (when active pattern also has parameters)" - -> > val it : string = - "** Expect OK, since error message says constraint should work!" - -> val ( |A|B| ) : x:int -> Choice - -> val it : string = "** Expect error since active pattern is not a function!" - -> > val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on match val" - -> val ( |A|B| ) : p:bool -> 'a * 'b -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is not too generic, typars depend on parameters" - -> val ( |A|B| ) : aval:'a -> bval:'b -> x:bool -> Choice<'a,'b> - -> val it : string = - "** Expect OK since active pattern result is generic, but it typar from closure, so OK" - -> val outer : x:'a -> (int -> 'a option) - -> val it : string = - "** Expect OK, BUG 472278: revert unintended breaking change to Active Patterns in F# 3.0" - -> val ( |Check1| ) : a:int -> int * 'a option - -> > module ReflectionEmit = begin - type IA = - interface - abstract member M : #IB -> int - end - and IB = - interface - abstract member M : #IA -> int - end - type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = - interface - abstract member M : int - end - and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = - interface - abstract member M : int - end -end - -> val it : string = - "Regression_139182: Expect the follow code to be accepted without error" - -> type S = - struct - member TheMethod : unit -> int64 - end -val theMethod : s:S -> int64 -type T = - class - new : unit -> T - member Prop5 : int64 - static member Prop1 : int64 - static member Prop2 : int64 - static member Prop3 : int64 - static member Prop4 : string - end - -> val it : System.Threading.ThreadLocal list = [0 {IsValueCreated = false; - Values = ?;}] - -> type MyDU = - | Case1 of Val1: int * Val2: string - | Case2 of string * V2: bool * float - | Case3 of int - | Case4 of Item1: bool - | Case5 of bool * string - | Case6 of Val1: int * bool * string - | Case7 of Big Name: int -val namedFieldVar1 : MyDU -val namedFieldVar2 : MyDU - -> exception MyNamedException1 of Val1: int * Val2: string -exception MyNamedException2 of string * V2: bool * float -exception MyNamedException3 of Data: int -exception MyNamedException4 of bool -exception MyNamedException5 of int * string -exception MyNamedException6 of Val1: int * bool * string * Data8: float -exception MyNamedException7 of Big Named Field: int -val namedEx1 : exn -val namedEx2 : exn - -> type optionRecord = - { x: int option } -val x : optionRecord - -> type optionRecord = - { x: obj } -val x : optionRecord - -> > > diff --git a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl b/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl deleted file mode 100644 index 386c625eeff..00000000000 --- a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl +++ /dev/null @@ -1,330 +0,0 @@ - - type Regression4319_T0 = static member (+-+-+) = "0 arguments";; - -----------------------------------------^^^^^ - -stdin(572,42): warning FS1172: Infix operator member '+-+-+' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_T1 = static member (+-+-+) x = "1 argument";; - -----------------------------------------^^^^^ - -stdin(573,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_T1b = static member (+-+-+) (x) = "1 (argument) [brackets make no diff]";; - -----------------------------------------^^^^^ - -stdin(574,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_T1c = static member (+-+-+) x = let a,b = x in "1 argument, tuple typed from RHS. Still not OK";; - -----------------------------------------^^^^^ - -stdin(575,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_T1d = static member (+-+-+) (x:int*int) = "1 argument, tuple typed from LHS. Still not OK";; - -----------------------------------------^^^^^ - -stdin(576,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_T3 = static member (+-+-+) (x,y,z) = "3 arguments";; - -----------------------------------------^^^^^ - -stdin(578,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; - -----------------------------------------^^^^^ - -stdin(579,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U1 = static member (+-+-+) x moreArgs = "1 argument and further args";; - -----------------------------------------^^^^^ - -stdin(579,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; - -----------------------------------------^^^^^ - -stdin(580,42): warning FS1173: Infix operator member '+-+-+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U1b = static member (+-+-+) (x) moreArgs = "1 (argument) [brackets make no diff] and further args";; - -----------------------------------------^^^^^ - -stdin(580,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U2 = static member (+-+-+) (x,y) moreArgs = "1 argument and further args";; - -----------------------------------------^^^^^ - -stdin(581,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; - -----------------------------------------^^^^^ - -stdin(582,42): warning FS1173: Infix operator member '+-+-+' has 3 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - type Regression4319_U3 = static member (+-+-+) (x,y,z) moreArgs = "1 argument and further args";; - -----------------------------------------^^^^^ - -stdin(582,42): warning FS1174: Infix operator member '+-+-+' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (:=) = "COLON_EQUALS" - -------------------^^ - -stdin(585,20): warning FS1172: Infix operator member ':=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (:=) = "COLON_EQUALS" - -------------------^^ - -stdin(585,20): warning FS0086: The name '(:=)' should not be used as a member name because it is given a standard definition in the F# library over fixed types - - - static member (&) = "AMP" - -------------------^ - -stdin(589,20): warning FS1172: Infix operator member '&' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (&) = "AMP" - -------------------^ - -stdin(589,20): warning FS0086: The name '(&)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_Amp' instead. - - - static member (&^) = "AMP_AMP" - -------------------^^ - -stdin(590,20): warning FS1172: Infix operator member '&^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (=) = "EQUALS" - -------------------^ - -stdin(591,20): warning FS1172: Infix operator member '=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (=) = "EQUALS" - -------------------^ - -stdin(591,20): warning FS0086: The name '(=)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name 'op_Equality' instead. - - - static member (!=) = "INFIX_COMPARE_OP" - -------------------^^ - -stdin(593,20): warning FS1172: Infix operator member '!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (...=) = "INFIX_COMPARE_OP" // with $. prefix - -------------------^^^^ - -stdin(597,20): warning FS1172: Infix operator member '...=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (...!=) = "INFIX_COMPARE_OP" // with $. prefix - -------------------^^^^^ - -stdin(598,20): warning FS1172: Infix operator member '...!=' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (...<) = "INFIX_COMPARE_OP" // with $. prefix - -------------------^^^^ - -stdin(599,20): warning FS1172: Infix operator member '...<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (...>) = "INFIX_COMPARE_OP" // with $. prefix - -------------------^^^^ - -stdin(600,20): warning FS1172: Infix operator member '...>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ($) = "DOLLAR" - -------------------^ - -stdin(602,20): warning FS1172: Infix operator member '$' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (<) = "LESS" - -------------------^ - -stdin(603,20): warning FS1172: Infix operator member '<' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (<) = "LESS" - -------------------^ - -stdin(603,20): warning FS0086: The name '(<)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_LessThan' instead. - - - static member (>) = "GREATER" - -------------------^ - -stdin(604,20): warning FS1172: Infix operator member '>' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (>) = "GREATER" - -------------------^ - -stdin(604,20): warning FS0086: The name '(>)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name 'op_GreaterThan' instead. - - - static member (@) = "INFIX_AT_HAT_OP" - -------------------^ - -stdin(605,20): warning FS1172: Infix operator member '@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (@) = "INFIX_AT_HAT_OP" - -------------------^ - -stdin(605,20): warning FS0086: The name '(@)' should not be used as a member name because it is given a standard definition in the F# library over fixed types - - - static member (^) = "INFIX_AT_HAT_OP" - -------------------^ - -stdin(606,20): warning FS1172: Infix operator member '^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (^) = "INFIX_AT_HAT_OP" - -------------------^ - -stdin(606,20): warning FS0086: The name '(^)' should not be used as a member name because it is given a standard definition in the F# library over fixed types - - - static member (...@) = "INFIX_AT_HAT_OP" // with $. prefix - -------------------^^^^ - -stdin(607,20): warning FS1172: Infix operator member '...@' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (...^) = "INFIX_AT_HAT_OP" // with $. prefix - -------------------^^^^ - -stdin(608,20): warning FS1172: Infix operator member '...^' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (%) = "PERCENT_OP" - -------------------^ - -stdin(609,20): warning FS1172: Infix operator member '%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (-) = "MINUS" - -------------------^ - -stdin(611,20): warning FS1172: Infix operator member '-' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ( * ) = "STAR" - --------------------^ - -stdin(612,21): warning FS1172: Infix operator member '*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member (/) = "INFIX_STAR_DIV_MOD_OP" - -------------------^ - -stdin(614,20): warning FS1172: Infix operator member '/' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ( ...* ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix - --------------------^^^^ - -stdin(616,21): warning FS1172: Infix operator member '...*' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ( .../ ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix - --------------------^^^^ - -stdin(617,21): warning FS1172: Infix operator member '.../' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ( ...% ) = "INFIX_STAR_DIV_MOD_OP" // with $. prefix - --------------------^^^^ - -stdin(618,21): warning FS1172: Infix operator member '...%' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - static member ( ** ) = "INFIX_STAR_STAR_OP" - --------------------^^ - -stdin(619,21): warning FS1172: Infix operator member '**' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - - - member this.ToString() = "ABC" - ----------------^^^^^^^^ - -stdin(624,17): warning FS0864: This new member hides the abstract member 'System.Object.ToString() : string'. Rename the member or use 'override' instead. - - - member this.M() = "string" - ----------------^ - -stdin(765,17): error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'ExpectDupMethod'. - - - member this.P = "string" - ----------------^ - -stdin(772,17): error FS0438: Duplicate method. The method 'get_P' has the same name and signature as another method in type 'ExpectDupProperty'. - - - type public IBPublic = interface inherit IAPrivate abstract Q : int end - ------------------^^^^^^^^ - -stdin(779,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBPublic' it is used in. - - - type internal IBInternal = interface inherit IAPrivate abstract Q : int end - ------------------^^^^^^^^^^ - -stdin(784,19): error FS0410: The type 'IAPrivate' is less accessible than the value, member or type 'IBInternal' it is used in. - - - type public IBPublic = interface inherit IAInternal abstract Q : int end - ------------------^^^^^^^^ - -stdin(793,19): error FS0410: The type 'IAInternal' is less accessible than the value, member or type 'IBPublic' it is used in. - - - override x.M(a:string) = 1 - -------------------^ - -stdin(825,20): error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member Regression4232.D.M : 'U -> int' and 'abstract member Regression4232.D.M : 'T -> int' - - - let (|A|B|) (x:int) = A x;; - -----^^^^^ - -stdin(833,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' - - - let (|A|B|) (x:'a) = A x;; - -----^^^^^ - -stdin(836,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' - - - let (|A|B|) (p:'a) (x:int) = A p;; - -----^^^^^ - -stdin(839,6): error FS1210: Active pattern '|A|B|' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' - - - let (|A|B|) = failwith "" : Choice;; - -----^^^^^ - -stdin(845,6): error FS1209: Active pattern '|A|B|' is not a function - diff --git a/tests/fsharp/core/printing/z.output.test.quiet.stdout.bsl b/tests/fsharp/core/printing/z.output.test.quiet.stdout.bsl deleted file mode 100644 index 26683b52103..00000000000 --- a/tests/fsharp/core/printing/z.output.test.quiet.stdout.bsl +++ /dev/null @@ -1,13 +0,0 @@ -[Building 2 4...done] -[Building 2 6...done] -[Building 2 8...done] -[Building 2 10...done] -[Building 2 12...done] -[Building 2 14...done] -[Building 3 8...done] -[Building 4 8...done] -[Building 5 8...done] -[Building 6 8...done] -[Building 5 3...done] -Expect ABC = ABC -Expect ABC = ABC diff --git a/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx b/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx index 5bc75468288..24420815309 100644 --- a/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx +++ b/tests/fsharp/core/queriesLeafExpressionConvert/test.fsx @@ -664,7 +664,15 @@ module LeafExpressionEvaluationTests = checkEval "castingunits5" (<@ 2L |> LanguagePrimitives.Int64WithMeasure |> int64 @>) 2L checkEval "castingunits6" (<@ 2s |> LanguagePrimitives.Int16WithMeasure |> int16 @>) 2s checkEval "castingunits7" (<@ 2y |> LanguagePrimitives.SByteWithMeasure |> sbyte @>) 2y - + checkEval "castingunits8" (<@ 2ul |> LanguagePrimitives.UInt32WithMeasure |> uint @>) 2ul + checkEval "castingunits9" (<@ 2UL |> LanguagePrimitives.UInt64WithMeasure |> uint64 @>) 2UL + checkEval "castingunits10" (<@ 2us |> LanguagePrimitives.UInt16WithMeasure |> uint16 @>) 2us + checkEval "castingunits11" (<@ 2uy |> LanguagePrimitives.ByteWithMeasure |> byte @>) 2uy + + //NOTE quotations currently *DO NOT* support native integers + //TODO revisit when the test scaffolding is changed/migrated! + // checkEval "castingunits12" (<@ 2n |> LanguagePrimitives.IntPtrWithMeasure |> nativeint @>) 2n + // checkEval "castingunits13" (<@ 2un |> LanguagePrimitives.UIntPtrWithMeasure |> unativeint @>) 2un module LargerAutomaticDiferentiationTest_FSharp_1_0_Bug_3498 = @@ -1003,4 +1011,3 @@ let aa = exit 1 #endif - diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 8be5e210971..39d2e4218ed 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -10,6 +10,13 @@ module Core_quotes #nowarn "57" +open System +open System.Reflection +open Microsoft.FSharp.Quotations +open Microsoft.FSharp.Quotations.Patterns +open Microsoft.FSharp.Quotations.DerivedPatterns + + let failures = ref [] let report_failure (s : string) = @@ -27,12 +34,19 @@ let check s v1 v2 = eprintf " FAILED: got %A, expected %A" v1 v2 report_failure s +let rec removeDoubleSpaces (s: string) = + let s2 = s.Replace(" ", " ") + if s = s2 then s else removeDoubleSpaces s2 -open System -open System.Reflection -open Microsoft.FSharp.Quotations -open Microsoft.FSharp.Quotations.Patterns -open Microsoft.FSharp.Quotations.DerivedPatterns +let normalizeActivePatternResults (s: string) = + System.Text.RegularExpressions.Regex(@"activePatternResult\d+").Replace(s, "activePatternResult") + +let checkStrings s (v1: string) (v2: string) = + check s + (v1.Replace("\r","").Replace("\n","") |> removeDoubleSpaces |> normalizeActivePatternResults) + (v2.Replace("\r","").Replace("\n","") |> removeDoubleSpaces |> normalizeActivePatternResults) + +let checkQuoteString s expected (q: Expr) = checkStrings s (sprintf "%A" q) expected let (|TypedValue|_|) (v : 'T) value = match value with @@ -1444,42 +1458,39 @@ end module MoreQuotationsTests = let t1 = <@@ try 1 with e when true -> 2 | e -> 3 @@> - printfn "t1 = %A" t1 - check "vwjnkwve0-vwnio" - (sprintf "%A" t1) - "TryWith (Value (1), matchValue, - IfThenElse (Let (e, matchValue, Value (true)), - Let (e, matchValue, Value (1)), - Let (e, matchValue, Value (1))), matchValue, - IfThenElse (Let (e, matchValue, Value (true)), - Let (e, matchValue, Value (2)), - Let (e, matchValue, Value (3))))" + checkStrings "vwjnkwve0-vwnio" + (sprintf "%A" t1) + """TryWith (Value (1), matchValue, + IfThenElse (Let (e, matchValue, Value (true)), + Let (e, matchValue, Value (1)), + Let (e, matchValue, Value (1))), matchValue, + IfThenElse (Let (e, matchValue, Value (true)), + Let (e, matchValue, Value (2)), + Let (e, matchValue, Value (3))))""" [] let k (x:int) = try 1 with _ when true -> 2 | e -> 3 let t2 = <@@ Map.empty.[0] @@> - printfn "t2 = %A" t2 - check "vwjnkwve0-vwnio1" + checkStrings "vwjnkwve0-vwnio1" (sprintf "%A" t2) "PropertyGet (Some (Call (None, Empty, [])), Item, [Value (0)])" let t4 = <@@ use a = new System.IO.StreamWriter(System.IO.Stream.Null) in a @@> - printfn "t4 = %A" t4 - check "vwjnkwve0-vwnio3" + checkStrings "vwjnkwve0-vwnio3" (sprintf "%A" t4) - "Let (a, NewObject (StreamWriter, FieldGet (None, Null)), + "Let (a, NewObject (StreamWriter, FieldGet (None, Null)), TryFinally (a, IfThenElse (TypeTest (IDisposable, Coerce (a, Object)), Call (Some (Call (None, UnboxGeneric, [Coerce (a, Object)])), Dispose, []), Value ())))" - check "vwjnkwve0-vwnio3fuull" + checkStrings "vwjnkwve0-vwnio3fuull" (t4.ToString(true)) - "Let (a, + "Let (a, NewObject (Void .ctor(System.IO.Stream), FieldGet (None, System.IO.Stream Null)), TryFinally (a, @@ -1492,47 +1503,129 @@ module MoreQuotationsTests = let t5 = <@@ try failwith "test" with _ when true -> 0 @@> - printfn "t5 = %A" t5 + checkStrings "vwekwvel5" (sprintf "%A" t5) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + IfThenElse (Value (true), Value (1), Value (0)), matchValue, + IfThenElse (Value (true), Value (0), Call (None, Reraise, [])))""" let t6 = <@@ let mutable a = 0 in a <- 2 @@> - printfn "t6 = %A" t6 + checkStrings "vwewvwewe6" (sprintf "%A" t6) + """Let (a, Value (0), VarSet (a, Value (2)))""" let f (x: _ byref) = x let t7 = <@@ let mutable a = 0 in f (&a) @@> - printfn "t7 = %A" t7 - - let t8 = <@@ for i in 1s .. 10s do printfn "%A" i @@> - printfn "t8 = %A" t8 + checkStrings "vwewvwewe7" (sprintf "%A" t7) + """Let (a, Value (0), Call (None, f, [AddressOf (a)]))""" - let t9 = <@@ try failwith "test" with Failure _ -> 0 @@> - printfn "t9 = %A" t9 + let t8 = <@@ for i in 1s .. 10s do printfn "%A" i @@> + checkStrings "vwewvwewe8" (sprintf "%A" t8) + """Let (inputSequence, Call (None, op_Range, [Value (1s), Value (10s)]), + Let (enumerator, Call (Some (inputSequence), GetEnumerator, []), + TryFinally (WhileLoop (Call (Some (enumerator), MoveNext, []), + Let (i, + PropertyGet (Some (enumerator), Current, + []), + Application (Let (clo1, + Call (None, + PrintFormatLine, + [Coerce (NewObject (PrintfFormat`5, + Value ("%A")), + PrintfFormat`4)]), + Lambda (arg10, + Application (clo1, + arg10))), + i))), + IfThenElse (TypeTest (IDisposable, + Coerce (enumerator, Object)), + Call (Some (Call (None, UnboxGeneric, + [Coerce (enumerator, Object)])), + Dispose, []), Value ()))))""" + + let t9() = <@@ try failwith "test" with Failure _ -> 0 @@> + checkStrings "vwewvwewe9" (sprintf "%A" (t9())) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + Let (activePatternResult1557, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1557, Some), + Value (1), Value (0))), matchValue, + Let (activePatternResult1558, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1558, Some), + Value (0), Call (None, Reraise, []))))""" let t9b = <@@ Failure "fil" @@> - printfn "t9b = %A" t9b + checkStrings "vwewvwewe9b" (sprintf "%A" t9b) + """Call (None, Failure, [Value ("fil")])""" + let t9c = <@@ match Failure "fil" with Failure msg -> msg | _ -> "no" @@> - printfn "t9c = %A" t9c + checkStrings "vwewvwewe9c" (sprintf "%A" t9c) + """Let (matchValue, Call (None, Failure, [Value ("fil")]), + Let (activePatternResult1564, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1564, Some), + Let (msg, + PropertyGet (Some (activePatternResult1564), Value, + []), msg), Value ("no"))))""" let t10 = <@@ try failwith "test" with Failure _ -> 0 | _ -> 1 @@> - printfn "t10 = %A" t10 + checkStrings "vwewvwewe10" (sprintf "%A" t10) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + Let (activePatternResult1565, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1565, Some), + Value (1), Value (1))), matchValue, + Let (activePatternResult1566, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1566, Some), + Value (0), Value (1))))""" let t11 = <@@ try failwith "test" with :? System.NullReferenceException -> 0 @@> - printfn "t11 = %A" t11 + checkStrings "vwewvwewe11" (sprintf "%A" t11) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + IfThenElse (TypeTest (NullReferenceException, matchValue), Value (1), + Value (0)), matchValue, + IfThenElse (TypeTest (NullReferenceException, matchValue), Value (0), + Call (None, Reraise, [])))""" let t12 = <@@ try failwith "test" with :? System.NullReferenceException as n -> 0 @@> - printfn "t12 = %A" t12 + checkStrings "vwewvwewe12" (sprintf "%A" t12) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + IfThenElse (TypeTest (NullReferenceException, matchValue), + Let (n, Call (None, UnboxGeneric, [matchValue]), Value (1)), + Value (0)), matchValue, + IfThenElse (TypeTest (NullReferenceException, matchValue), + Let (n, Call (None, UnboxGeneric, [matchValue]), Value (0)), + Call (None, Reraise, [])))""" let t13 = <@@ try failwith "test" with Failure _ -> 1 | :? System.NullReferenceException as n -> 0 @@> - printfn "t13 = %A" t13 + checkStrings "vwewvwewe13" (sprintf "%A" t13) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + Let (activePatternResult1576, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1576, Some), + Value (1), + IfThenElse (TypeTest (NullReferenceException, + matchValue), + Let (n, + Call (None, UnboxGeneric, + [matchValue]), Value (1)), + Value (0)))), matchValue, + Let (activePatternResult1577, Call (None, FailurePattern, [matchValue]), + IfThenElse (UnionCaseTest (activePatternResult1577, Some), + Value (1), + IfThenElse (TypeTest (NullReferenceException, + matchValue), + Let (n, + Call (None, UnboxGeneric, + [matchValue]), Value (0)), + Call (None, Reraise, [])))))""" let t14 = <@@ try failwith "test" with _ when true -> 0 @@> - printfn "t14 = %A" t14 + checkStrings "vwewvwewe13" (sprintf "%A" t14) + """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, + IfThenElse (Value (true), Value (1), Value (0)), matchValue, + IfThenElse (Value (true), Value (0), Call (None, Reraise, [])))""" - let _ = <@@ let x : int option = None in x.IsSome @@> |> printfn "quote = %A" - let _ = <@@ let x : int option = None in x.IsNone @@> |> printfn "quote = %A" - let _ = <@@ let x : int option = None in x.Value @@> |> printfn "quote = %A" - let _ = <@@ let x : int option = None in x.ToString() @@> |> printfn "quote = %A" + let _ = <@@ let x : int option = None in x.IsSome @@> |> checkQuoteString "fqekhec1" """Let (x, NewUnionCase (None), Call (None, get_IsSome, [x]))""" + let _ = <@@ let x : int option = None in x.IsNone @@> |> checkQuoteString "fqekhec2" """Let (x, NewUnionCase (None), Call (None, get_IsNone, [x]))""" + let _ = <@@ let x : int option = None in x.Value @@> |> checkQuoteString "fqekhec3" """Let (x, NewUnionCase (None), PropertyGet (Some (x), Value, []))""" + let _ = <@@ let x : int option = None in x.ToString() @@> |> checkQuoteString "fqekhec4" """Let (x, NewUnionCase (None), Call (Some (x), ToString, []))""" module Extensions = type System.Object with @@ -1562,63 +1655,63 @@ module MoreQuotationsTests = member x.Int32ExtensionIndexer2 with set(idx:int) (v:int) = () let v = new obj() - let _ = <@@ v.ExtensionMethod0() @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod1() @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod2(3) @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod3(3) @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod4(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod5(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionProperty1 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionProperty2 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionProperty3 <- 4 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionIndexer1(3) @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionIndexer2(3) <- 4 @@> |> printfn "quote = %A" - - let _ = <@@ v.ExtensionMethod0 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod1 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod2 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod3 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod4 @@> |> printfn "quote = %A" - let _ = <@@ v.ExtensionMethod5 @@> |> printfn "quote = %A" + let _ = <@@ v.ExtensionMethod0() @@> |> checkQuoteString "fqekhec5" """Call (None, Object.ExtensionMethod0, [PropertyGet (None, v, [])])""" + let _ = <@@ v.ExtensionMethod1() @@> |> checkQuoteString "fqekhec6" """Call (None, Object.ExtensionMethod1, [PropertyGet (None, v, [])])""" + let _ = <@@ v.ExtensionMethod2(3) @@> |> checkQuoteString "fqekhec7" """Call (None, Object.ExtensionMethod2, [PropertyGet (None, v, []), Value (3)])""" + let _ = <@@ v.ExtensionMethod3(3) @@> |> checkQuoteString "fqekhec8" """Call (None, Object.ExtensionMethod3, [PropertyGet (None, v, []), Value (3)])""" + let _ = <@@ v.ExtensionMethod4(3,4) @@> |> checkQuoteString "fqekhec9" """Call (None, Object.ExtensionMethod4, [PropertyGet (None, v, []), Value (3), Value (4)])""" + let _ = <@@ v.ExtensionMethod5(3,4) @@> |> checkQuoteString "fqekhec10" """Call (None, Object.ExtensionMethod5, [PropertyGet (None, v, []), NewTuple (Value (3), Value (4))])""" + let _ = <@@ v.ExtensionProperty1 @@> |> checkQuoteString "fqekhec11" """Call (None, Object.get_ExtensionProperty1, [PropertyGet (None, v, [])])""" + let _ = <@@ v.ExtensionProperty2 @@> |> checkQuoteString "fqekhec12" """Call (None, Object.get_ExtensionProperty2, [PropertyGet (None, v, [])])""" + let _ = <@@ v.ExtensionProperty3 <- 4 @@> |> checkQuoteString "fqekhec13" """Call (None, Object.set_ExtensionProperty3, [PropertyGet (None, v, []), Value (4)])""" + let _ = <@@ v.ExtensionIndexer1(3) @@> |> checkQuoteString "fqekhec14" """Call (None, Object.get_ExtensionIndexer1, [PropertyGet (None, v, []), Value (3)])""" + let _ = <@@ v.ExtensionIndexer2(3) <- 4 @@> |> checkQuoteString "fqekhec15" """Call (None, Object.set_ExtensionIndexer2, [PropertyGet (None, v, []), Value (3), Value (4)])""" + + let _ = <@@ v.ExtensionMethod0 @@> |> checkQuoteString "fqekhec16" """Lambda (unitVar, Call (None, Object.ExtensionMethod0, [PropertyGet (None, v, [])]))""" + let _ = <@@ v.ExtensionMethod1 @@> |> checkQuoteString "fqekhec17" """Lambda (unitVar, Call (None, Object.ExtensionMethod1, [PropertyGet (None, v, [])]))""" + let _ = <@@ v.ExtensionMethod2 @@> |> checkQuoteString "fqekhec18" """Lambda (arg00, Call (None, Object.ExtensionMethod2, [PropertyGet (None, v, []), arg00]))""" + let _ = <@@ v.ExtensionMethod3 @@> |> checkQuoteString "fqekhec19" """Lambda (arg00, Call (None, Object.ExtensionMethod3, [PropertyGet (None, v, []), arg00]))""" + let _ = <@@ v.ExtensionMethod4 @@> |> checkQuoteString "fqekhec20" """Lambda (tupledArg, Let (arg00, TupleGet (tupledArg, 0), Let (arg01, TupleGet (tupledArg, 1), Call (None, Object.ExtensionMethod4, [PropertyGet (None, v, []), arg00, arg01]))))""" + let _ = <@@ v.ExtensionMethod5 @@> |> checkQuoteString "fqekhec21" """Lambda (arg00, Call (None, Object.ExtensionMethod5, [PropertyGet (None, v, []), arg00]))""" let v2 = 3 - let _ = <@@ v2.ExtensionMethod0() @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod1() @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod2(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod3(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod4(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod5(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionProperty1 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionProperty2 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionProperty3 <- 4 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionIndexer1(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionIndexer2(3) <- 4 @@> |> printfn "quote = %A" - - let _ = <@@ v2.ExtensionMethod0 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod1 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod2 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod3 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod4 @@> |> printfn "quote = %A" - let _ = <@@ v2.ExtensionMethod5 @@> |> printfn "quote = %A" - - let _ = <@@ v2.Int32ExtensionMethod0() @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod1() @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod2(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod3(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod4(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod5(3,4) @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionProperty1 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionProperty2 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionProperty3 <- 4 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionIndexer1(3) @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionIndexer2(3) <- 4 @@> |> printfn "quote = %A" - - let _ = <@@ v2.Int32ExtensionMethod0 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod1 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod2 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod3 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod4 @@> |> printfn "quote = %A" - let _ = <@@ v2.Int32ExtensionMethod5 @@> |> printfn "quote = %A" + let _ = <@@ v2.ExtensionMethod0() @@> |> checkQuoteString "fqekhec22" """Call (None, Object.ExtensionMethod0, [Coerce (PropertyGet (None, v2, []), Object)])""" + let _ = <@@ v2.ExtensionMethod1() @@> |> checkQuoteString "fqekhec23" """Call (None, Object.ExtensionMethod1, [Coerce (PropertyGet (None, v2, []), Object)])""" + let _ = <@@ v2.ExtensionMethod2(3) @@> |> checkQuoteString "fqekhec24" """Call (None, Object.ExtensionMethod2, [Coerce (PropertyGet (None, v2, []), Object), Value (3)])""" + let _ = <@@ v2.ExtensionMethod3(3) @@> |> checkQuoteString "fqekhec25" """Call (None, Object.ExtensionMethod3, [Coerce (PropertyGet (None, v2, []), Object), Value (3)])""" + let _ = <@@ v2.ExtensionMethod4(3,4) @@> |> checkQuoteString "fqekhec26" """Call (None, Object.ExtensionMethod4, [Coerce (PropertyGet (None, v2, []), Object), Value (3), Value (4)])""" + let _ = <@@ v2.ExtensionMethod5(3,4) @@> |> checkQuoteString "fqekhec27" """Call (None, Object.ExtensionMethod5, [Coerce (PropertyGet (None, v2, []), Object), NewTuple (Value (3), Value (4))])""" + let _ = <@@ v2.ExtensionProperty1 @@> |> checkQuoteString "fqekhec28" """Call (None, Object.get_ExtensionProperty1, [Coerce (PropertyGet (None, v2, []), Object)])""" + let _ = <@@ v2.ExtensionProperty2 @@> |> checkQuoteString "fqekhec29" """Call (None, Object.get_ExtensionProperty2, [Coerce (PropertyGet (None, v2, []), Object)])""" + let _ = <@@ v2.ExtensionProperty3 <- 4 @@> |> checkQuoteString "fqekhec30" """Call (None, Object.set_ExtensionProperty3, [Coerce (PropertyGet (None, v2, []), Object), Value (4)])""" + let _ = <@@ v2.ExtensionIndexer1(3) @@> |> checkQuoteString "fqekhec31" """Call (None, Object.get_ExtensionIndexer1, [Coerce (PropertyGet (None, v2, []), Object), Value (3)])""" + let _ = <@@ v2.ExtensionIndexer2(3) <- 4 @@> |> checkQuoteString "fqekhec32" """Call (None, Object.set_ExtensionIndexer2, [Coerce (PropertyGet (None, v2, []), Object), Value (3), Value (4)])""" + + let _ = <@@ v2.ExtensionMethod0 @@> |> checkQuoteString "fqekhec33" """Lambda (unitVar, Call (None, Object.ExtensionMethod0, [Coerce (PropertyGet (None, v2, []), Object)]))""" + let _ = <@@ v2.ExtensionMethod1 @@> |> checkQuoteString "fqekhec34" """Lambda (unitVar, Call (None, Object.ExtensionMethod1, [Coerce (PropertyGet (None, v2, []), Object)]))""" + let _ = <@@ v2.ExtensionMethod2 @@> |> checkQuoteString "fqekhec35" """Lambda (arg00, Call (None, Object.ExtensionMethod2, [Coerce (PropertyGet (None, v2, []), Object), arg00]))""" + let _ = <@@ v2.ExtensionMethod3 @@> |> checkQuoteString "fqekhec36" """Lambda (arg00, Call (None, Object.ExtensionMethod3, [Coerce (PropertyGet (None, v2, []), Object), arg00]))""" + let _ = <@@ v2.ExtensionMethod4 @@> |> checkQuoteString "fqekhec37" """Lambda (tupledArg, Let (arg00, TupleGet (tupledArg, 0), Let (arg01, TupleGet (tupledArg, 1), Call (None, Object.ExtensionMethod4, [Coerce (PropertyGet (None, v2, []), Object), arg00, arg01]))))""" + let _ = <@@ v2.ExtensionMethod5 @@> |> checkQuoteString "fqekhec38" """Lambda (arg00, Call (None, Object.ExtensionMethod5, [Coerce (PropertyGet (None, v2, []), Object), arg00]))""" + + let _ = <@@ v2.Int32ExtensionMethod0() @@> |> checkQuoteString "fqekhec39" """Call (None, Int32.Int32ExtensionMethod0, [PropertyGet (None, v2, [])])""" + let _ = <@@ v2.Int32ExtensionMethod1() @@> |> checkQuoteString "fqekhec40" """Call (None, Int32.Int32ExtensionMethod1, [PropertyGet (None, v2, [])])""" + let _ = <@@ v2.Int32ExtensionMethod2(3) @@> |> checkQuoteString "fqekhec41" """Call (None, Int32.Int32ExtensionMethod2, [PropertyGet (None, v2, []), Value (3)])""" + let _ = <@@ v2.Int32ExtensionMethod3(3) @@> |> checkQuoteString "fqekhec42" """Call (None, Int32.Int32ExtensionMethod3, [PropertyGet (None, v2, []), Value (3)])""" + let _ = <@@ v2.Int32ExtensionMethod4(3,4) @@> |> checkQuoteString "fqekhec43" """Call (None, Int32.Int32ExtensionMethod4, [PropertyGet (None, v2, []), Value (3), Value (4)])""" + let _ = <@@ v2.Int32ExtensionMethod5(3,4) @@> |> checkQuoteString "fqekhec44" """Call (None, Int32.Int32ExtensionMethod5, [PropertyGet (None, v2, []), NewTuple (Value (3), Value (4))])""" + let _ = <@@ v2.Int32ExtensionProperty1 @@> |> checkQuoteString "fqekhec45" """Call (None, Int32.get_Int32ExtensionProperty1, [PropertyGet (None, v2, [])])""" + let _ = <@@ v2.Int32ExtensionProperty2 @@> |> checkQuoteString "fqekhec46" """Call (None, Int32.get_Int32ExtensionProperty2, [PropertyGet (None, v2, [])])""" + let _ = <@@ v2.Int32ExtensionProperty3 <- 4 @@> |> checkQuoteString "fqekhec47" """Call (None, Int32.set_Int32ExtensionProperty3, [PropertyGet (None, v2, []), Value (4)])""" + let _ = <@@ v2.Int32ExtensionIndexer1(3) @@> |> checkQuoteString "fqekhec48" """Call (None, Int32.get_Int32ExtensionIndexer1, [PropertyGet (None, v2, []), Value (3)])""" + let _ = <@@ v2.Int32ExtensionIndexer2(3) <- 4 @@> |> checkQuoteString "fqekhec49" """Call (None, Int32.set_Int32ExtensionIndexer2, [PropertyGet (None, v2, []), Value (3), Value (4)])""" + + let _ = <@@ v2.Int32ExtensionMethod0 @@> |> checkQuoteString "fqekhec50" """Lambda (unitVar, Call (None, Int32.Int32ExtensionMethod0, [PropertyGet (None, v2, [])]))""" + let _ = <@@ v2.Int32ExtensionMethod1 @@> |> checkQuoteString "fqekhec51" """Lambda (unitVar, Call (None, Int32.Int32ExtensionMethod1, [PropertyGet (None, v2, [])]))""" + let _ = <@@ v2.Int32ExtensionMethod2 @@> |> checkQuoteString "fqekhec52" """Lambda (arg00, Call (None, Int32.Int32ExtensionMethod2, [PropertyGet (None, v2, []), arg00]))""" + let _ = <@@ v2.Int32ExtensionMethod3 @@> |> checkQuoteString "fqekhec53" """Lambda (arg00, Call (None, Int32.Int32ExtensionMethod3, [PropertyGet (None, v2, []), arg00]))""" + let _ = <@@ v2.Int32ExtensionMethod4 @@> |> checkQuoteString "fqekhec54" """Lambda (tupledArg, Let (arg00, TupleGet (tupledArg, 0), Let (arg01, TupleGet (tupledArg, 1), Call (None, Int32.Int32ExtensionMethod4, [PropertyGet (None, v2, []), arg00, arg01]))))""" + let _ = <@@ v2.Int32ExtensionMethod5 @@> |> checkQuoteString "fqekhec55" """Lambda (arg00, Call (None, Int32.Int32ExtensionMethod5, [PropertyGet (None, v2, []), arg00]))""" module QuotationConstructionTests = @@ -2819,7 +2912,7 @@ module ReflectionOverTypeInstantiations = let notRequired opname item = let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item - System.Diagnostics.Debug.Assert (false, msg) + //System.Diagnostics.Debug.Assert (false, msg) raise (System.NotSupportedException msg) /// DO NOT ADJUST THIS TYPE - it is the implementation of symbol types from the F# type provider starer pack. @@ -3161,6 +3254,883 @@ module TestMatchBang = (Ok ()) testSimpleMatchBang() + +#if LANGVERSION_PREVIEW +module WitnessTests = + open FSharp.Data.UnitSystems.SI.UnitSymbols + + test "check CallWithWitness" + (<@ 1 + 1 @> + |> function + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.Name = "op_Addition" && + minfo1.GetParameters().Length = 2 && + minfo2.Name = "op_Addition$W" && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length = %d... args.Length"; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length = %d... args.Length"; true) && + args.Length = 2 && + (printfn "checking witnessArgs is a Lambda..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "checking witnessArg is the expected call..."; true) && + (match witnessArgs with [ Lambda (v1A, Lambda (v2A, Call(None, m, [ Patterns.Var v1B; Patterns.Var v2B]))) ] when m.Name = "op_Addition" && v1A = v1B && v2A = v2B -> true | _ -> false) + (printfn "checking witnessArg is not a CalWithWitnesses..."; true) && + (match witnessArgs with [ Lambda (v1A, Lambda (v2A, CallWithWitnesses _)) ] -> false | _ -> true) && + (printfn "checking args..."; true) && + (match args with [ Int32 _; Int32 _ ] -> true | _ -> false) + | _ -> false) + + test "check CallWithWitness (DateTime + TimeSpan)" + (<@ System.DateTime.Now + System.TimeSpan.Zero @> + |> function + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.Name = "op_Addition" && + (printfn "checking minfo1.GetParameters().Length..."; true) && + minfo1.GetParameters().Length = 2 && + minfo2.Name = "op_Addition$W" && + (printfn "checking minfo2.GetParameters().Length..."; true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking witnessArg is the expected call, witnessArgs = %A" witnessArgs; true) && + (match witnessArgs with + | [ Lambda (v1A, Lambda (v2A, Call(None, m, [Patterns.Var v1B; Patterns.Var v2B]))) ] + when m.Name = "op_Addition" + && m.GetParameters().[0].ParameterType.Name = "DateTime" + && m.GetParameters().[1].ParameterType.Name = "TimeSpan" + && v1A = v1B + && v2A = v2B -> true + | _ -> false) + (printfn "checking witnessArg is not a CallWithWitnesses, witnessArgs = %A" witnessArgs; true) && + (match witnessArgs with [ Lambda (v1A, Lambda (v2A, CallWithWitnesses args)) ] -> printfn "unexpected! %A" args; false | _ -> true) && + args.Length = 2 && + (printfn "checking args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) + | CallWithWitnesses _ -> + printfn "no object" + false + | _ -> + printfn "incorrect node" + false) + + test "check Call (DateTime + TimeSpan)" + (<@ System.DateTime.Now + System.TimeSpan.Zero @> + |> function + | Call(None, minfo1, args) -> + minfo1.Name = "op_Addition" && + (printfn "checking minfo1.GetParameters().Length..."; true) && + minfo1.GetParameters().Length = 2 && + //minfo2.GetParameters().[0].Name = "op_Addition" && + args.Length = 2 && + (match args with [ _; _ ] -> true | _ -> false) + | _ -> false) + + type C() = + static member inline StaticAdd (x, y) = x + y + member inline __.InstanceAdd (x, y) = x + y + + test "check CallWithWitness (DateTime + TimeSpan) using static member" + (<@ C.StaticAdd(System.DateTime.Now, System.TimeSpan.Zero) @> + |> function + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.IsStatic && + minfo1.Name = "StaticAdd" && + (printfn "checking minfo1.GetParameters().Length..."; true) && + minfo1.GetParameters().Length = 2 && + minfo2.IsStatic && + minfo2.Name = "StaticAdd$W" && + (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length..."; true) && + args.Length = 2 && + (printfn "witnessArgs..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + printfn "no object..." + false + | _ -> false) + + test "check CallWithWitness (DateTime + TimeSpan) using instance member" + (<@ C().InstanceAdd(System.DateTime.Now, System.TimeSpan.Zero) @> + |> function + | CallWithWitnesses(Some _obj, minfo1, minfo2, witnessArgs, args) -> + not minfo1.IsStatic && + minfo1.Name = "InstanceAdd" && + (printfn "checking minfo1.GetParameters().Length..."; true) && + minfo1.GetParameters().Length = 2 && + not minfo2.IsStatic && + minfo2.Name = "InstanceAdd$W" && + (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length..."; true) && + args.Length = 2 && + (printfn "witnessArgs..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + printfn "no object..." + false + | _ -> false) + + test "check CallWithWitnesses all operators)" + (let tests = + [ <@@ sin 1.0 @@>, true + <@@ sin 1.0f @@>, true + <@@ sign 1.0f @@>, true + <@@ sqrt 1.0f @@>, true + <@@ 2.0f ** 2.0f @@>, true + <@@ atan2 3.0 4.0 @@>, true + <@@ 1.0f + 4.0f @@>, true + <@@ 1.0f - 4.0f @@>, true + <@@ 1.0f * 4.0f @@>, true + <@@ 1.0M * 4.0M @@>, true + <@@ 1.0f / 4.0f @@>, true + <@@ 1 % 4 @@>, true + <@@ -(4.0M) @@>, true + + <@@ 1y <<< 3 @@>, true + <@@ 1uy <<< 3 @@>, true + <@@ 1s <<< 3 @@>, true + <@@ 1us <<< 3 @@>, true + <@@ 1 <<< 3 @@>, true + <@@ 1u <<< 3 @@>, true + <@@ 1L <<< 3 @@>, true + <@@ 1UL <<< 3 @@>, true + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, false + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, false + + <@@ 1y >>> 3 @@>, true + <@@ 1uy >>> 3 @@>, true + <@@ 1s >>> 3 @@>, true + <@@ 1us >>> 3 @@>, true + <@@ 1 >>> 3 @@>, true + <@@ 1u >>> 3 @@>, true + <@@ 1L >>> 3 @@>, true + <@@ 1UL >>> 3 @@>, true + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, false + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, false + + <@@ 1y &&& 3y @@>, true + <@@ 1uy &&& 3uy @@>, true + <@@ 1s &&& 3s @@>, true + <@@ 1us &&& 3us @@>, true + <@@ 1 &&& 3 @@>, true + <@@ 1u &&& 3u @@>, true + <@@ 1L &&& 3L @@>, true + <@@ 1UL &&& 3UL @@>, true + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, false + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, false + + <@@ 1y ||| 3y @@>, true + <@@ 1uy ||| 3uy @@>, true + <@@ 1s ||| 3s @@>, true + <@@ 1us ||| 3us @@>, true + <@@ 1 ||| 3 @@>, true + <@@ 1u ||| 3u @@>, true + <@@ 1L ||| 3L @@>, true + <@@ 1UL ||| 3UL @@>, true + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, false + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, false + + <@@ 1y ^^^ 3y @@>, true + <@@ 1uy ^^^ 3uy @@>, true + <@@ 1s ^^^ 3s @@>, true + <@@ 1us ^^^ 3us @@>, true + <@@ 1 ^^^ 3 @@>, true + <@@ 1u ^^^ 3u @@>, true + <@@ 1L ^^^ 3L @@>, true + <@@ 1UL ^^^ 3UL @@>, true + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, false + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, false + + <@@ ~~~3y @@>, true + <@@ ~~~3uy @@>, true + <@@ ~~~3s @@>, true + <@@ ~~~3us @@>, true + <@@ ~~~3 @@>, true + <@@ ~~~3u @@>, true + <@@ ~~~3L @@>, true + <@@ ~~~3UL @@>, true + <@@ ~~~LanguagePrimitives.GenericOne @@>, false + <@@ ~~~LanguagePrimitives.GenericOne @@>, false + + <@@ byte 3uy @@>, true + <@@ byte 3y @@>, true + <@@ byte 3s @@>, true + <@@ byte 3us @@>, true + <@@ byte 3 @@>, true + <@@ byte 3u @@>, true + <@@ byte 3L @@>, true + <@@ byte 3UL @@>, true + <@@ byte 3.0f @@>, true + <@@ byte 3.0 @@>, true + <@@ byte LanguagePrimitives.GenericOne @@>, false + <@@ byte LanguagePrimitives.GenericOne @@>, false + <@@ byte 3.0M @@>, true + <@@ byte "3" @@>, false + + <@@ sbyte 3uy @@>, true + <@@ sbyte 3y @@>, true + <@@ sbyte 3s @@>, true + <@@ sbyte 3us @@>, true + <@@ sbyte 3 @@>, true + <@@ sbyte 3u @@>, true + <@@ sbyte 3L @@>, true + <@@ sbyte 3UL @@>, true + <@@ sbyte 3.0f @@>, true + <@@ sbyte 3.0 @@>, true + <@@ sbyte LanguagePrimitives.GenericOne @@>, false + <@@ sbyte LanguagePrimitives.GenericOne @@>, false + <@@ sbyte 3.0M @@>, true + <@@ sbyte "3" @@>, false + + <@@ int16 3uy @@>, true + <@@ int16 3y @@>, true + <@@ int16 3s @@>, true + <@@ int16 3us @@>, true + <@@ int16 3 @@>, true + <@@ int16 3u @@>, true + <@@ int16 3L @@>, true + <@@ int16 3UL @@>, true + <@@ int16 3.0f @@>, true + <@@ int16 3.0 @@>, true + <@@ int16 LanguagePrimitives.GenericOne @@>, false + <@@ int16 LanguagePrimitives.GenericOne @@>, false + <@@ int16 3.0M @@>, true + <@@ int16 "3" @@>, false + + <@@ uint16 3uy @@>, true + <@@ uint16 3y @@>, true + <@@ uint16 3s @@>, true + <@@ uint16 3us @@>, true + <@@ uint16 3 @@>, true + <@@ uint16 3u @@>, true + <@@ uint16 3L @@>, true + <@@ uint16 3UL @@>, true + <@@ uint16 3.0f @@>, true + <@@ uint16 3.0 @@>, true + <@@ uint16 LanguagePrimitives.GenericOne @@>, false + <@@ uint16 LanguagePrimitives.GenericOne @@>, false + <@@ uint16 3.0M @@>, true + <@@ uint16 "3" @@>, false + + <@@ int32 3uy @@>, true + <@@ int32 3y @@>, true + <@@ int32 3s @@>, true + <@@ int32 3us @@>, true + <@@ int32 3 @@>, true + <@@ int32 3u @@>, true + <@@ int32 3L @@>, true + <@@ int32 3UL @@>, true + <@@ int32 3.0f @@>, true + <@@ int32 3.0 @@>, true + <@@ int32 LanguagePrimitives.GenericOne @@>, false + <@@ int32 LanguagePrimitives.GenericOne @@>, false + <@@ int32 3.0M @@>, true + <@@ int32 "3" @@>, false + + <@@ uint32 3uy @@>, true + <@@ uint32 3y @@>, true + <@@ uint32 3s @@>, true + <@@ uint32 3us @@>, true + <@@ uint32 3 @@>, true + <@@ uint32 3u @@>, true + <@@ uint32 3L @@>, true + <@@ uint32 3UL @@>, true + <@@ uint32 3.0f @@>, true + <@@ uint32 3.0 @@>, true + <@@ uint32 LanguagePrimitives.GenericOne @@>, false + <@@ uint32 LanguagePrimitives.GenericOne @@>, false + <@@ uint32 3.0M @@>, true + <@@ uint32 "3" @@>, false + + <@@ int64 3uy @@>, true + <@@ int64 3y @@>, true + <@@ int64 3s @@>, true + <@@ int64 3us @@>, true + <@@ int64 3 @@>, true + <@@ int64 3u @@>, true + <@@ int64 3L @@>, true + <@@ int64 3UL @@>, true + <@@ int64 3.0f @@>, true + <@@ int64 3.0 @@>, true + <@@ int64 LanguagePrimitives.GenericOne @@>, false + <@@ int64 LanguagePrimitives.GenericOne @@>, false + <@@ int64 3.0M @@>, true + <@@ int64 "3" @@>, false + + <@@ uint64 3uy @@>, true + <@@ uint64 3y @@>, true + <@@ uint64 3s @@>, true + <@@ uint64 3us @@>, true + <@@ uint64 3 @@>, true + <@@ uint64 3u @@>, true + <@@ uint64 3L @@>, true + <@@ uint64 3UL @@>, true + <@@ uint64 3.0f @@>, true + <@@ uint64 3.0 @@>, true + <@@ uint64 LanguagePrimitives.GenericOne @@>, false + <@@ uint64 LanguagePrimitives.GenericOne @@>, false + <@@ uint64 3.0M @@>, true + <@@ uint64 "3" @@>, false + + <@@ nativeint 3uy @@>, true + <@@ nativeint 3y @@>, true + <@@ nativeint 3s @@>, true + <@@ nativeint 3us @@>, true + <@@ nativeint 3 @@>, true + <@@ nativeint 3u @@>, true + <@@ nativeint 3L @@>, true + <@@ nativeint 3UL @@>, true + <@@ nativeint 3.0f @@>, true + <@@ nativeint 3.0 @@>, true + <@@ nativeint LanguagePrimitives.GenericOne @@>, false + <@@ nativeint LanguagePrimitives.GenericOne @@>, false + //<@@ nativeint 3.0M @@>, false + //<@@ nativeint "3" @@>, false + + <@@ unativeint 3uy @@>, true + <@@ unativeint 3y @@>, true + <@@ unativeint 3s @@>, true + <@@ unativeint 3us @@>, true + <@@ unativeint 3 @@>, true + <@@ unativeint 3u @@>, true + <@@ unativeint 3L @@>, true + <@@ unativeint 3UL @@>, true + <@@ unativeint 3.0f @@>, true + <@@ unativeint 3.0 @@>, true + <@@ unativeint LanguagePrimitives.GenericOne @@>, false + <@@ unativeint LanguagePrimitives.GenericOne @@>, false + //<@@ unativeint 3.0M @@>, true + //<@@ unativeint "3" @@>, true + + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericZero @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ LanguagePrimitives.GenericOne @@>, true + <@@ List.sum [ 1; 2 ] @@>, true + <@@ List.sum [ 1.0f; 2.0f ] @@>, true + <@@ List.sum [ 1.0; 2.0 ] @@>, true + <@@ List.sum [ 1.0M; 2.0M ] @@>, true + <@@ List.average [ 1.0; 2.0 ] @@>, true + <@@ List.average [ 1.0f; 2.0f ] @@>, true + <@@ List.average [ 1.0M; 2.0M ] @@>, true + ] + + tests |> List.forall (fun (test, canEval) -> + if canEval then + printfn "--> checking we can evaluate %A" test + FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test |> ignore + printfn "<-- evaluated!" + else + printfn "skipping evaluation of %A because LinqExpressionConverter can't handle it" test + printfn "checking %A" test + match test with + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.IsStatic && + minfo2.IsStatic && + minfo2.Name = minfo1.Name + "$W" && + (* + (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length..."; true) && + args.Length = 2 && + (printfn "witnessArgs..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) + *) + true + | _ -> false)) + +module MoreWitnessTests = + + open System.Runtime.CompilerServices + open System.IO + + [] + module Tests = + let inline f0 (x: 'T) : (unit -> 'T) list = + [] + + let inline f (x: 'T) : (unit -> 'T) list = + [(fun () -> x + x)] + + type C() = + member inline __.F(x: 'T) = x + x + + [] + module M = + + type C with + member inline __.F2(x: 'T) = x + x + static member inline F2Static(x: 'T) = x + x + + [] + type FileExt = + [] + static member CreateDirectory(fileInfo: FileInfo) = + Directory.CreateDirectory fileInfo.Directory.FullName + + [] + static member inline F3(s: string, x: 'T) = + x + x + + [] + static member inline F4(s: string, x1: 'T, x2: 'T) = + x1 + x2 + + + [] + module Usage = + let q0 = <@ f0 3 @> + let q1 = <@ f 3 @> + let q2 = <@ C().F(3) @> + let q3 = <@ C().F2(3) @> + let q4 = <@ C.F2Static(3) @> + let q5 = <@ "".F3(3) @> + let q6 = <@ "".F4(3, 4) @> + + check "wekncjeck1" (q0.ToString()) "Call (None, f0, [Value (3)])" + check "wekncjeck2" (q1.ToString()) "Call (None, f, [Value (3)])" + check "wekncjeck3" (q2.ToString()) "Call (Some (NewObject (C)), F, [Value (3)])" + check "wekncjeck4" (q3.ToString()) "Call (None, C.F2, [NewObject (C), Value (3)])" + check "wekncjeck5" (q4.ToString()) "Call (None, C.F2Static.Static, [Value (3)])" + check "wekncjeck6" (q5.ToString()) "Call (None, F3, [Value (\"\"), Value (3)])" + check "wekncjeck7" (q6.ToString()) "Call (None, F4, [Value (\"\"), Value (3), Value (4)])" + + check "ewlknweknl1" (FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q0) (box ([] : (unit -> int) list)) + check "ewlknweknl2" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q1 with :? ((unit -> int) list) as x -> x.[0] ()) 6 + check "ewlknweknl3" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q2 with :? int as x -> x) 6 + check "ewlknweknl4" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q3 with :? int as x -> x) 6 + check "ewlknweknl5" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q4 with :? int as x -> x) 6 + check "ewlknweknl6" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q5 with :? int as x -> x) 6 + check "ewlknweknl7" (match FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation q6 with :? int as x -> x) 7 + +// Check we can take ReflectedDefinition of things involving witness and trait calls +module QuotationsOfGenericCodeWithWitnesses = + [] + let inline f1 (x: ^T) = x + x // ( ^T : (static member Foo: int -> int) (3)) + + match <@ f1 1 @> with + | Quotations.Patterns.Call(_, mi, _) -> + let mi1 = mi.GetGenericMethodDefinition() + let q1 = Quotations.Expr.TryGetReflectedDefinition(mi1) + check "vwehwevrwv" q1 None + | q -> report_failure (sprintf "gfwhoewvioh - unexpected %A" q) + + + match <@ f1 1 @> with + | Quotations.Patterns.CallWithWitnesses(_, mi, minfoWithWitnesses, _, _) -> + let q2 = Quotations.Expr.TryGetReflectedDefinition(minfoWithWitnesses) + + match q2 with + | Some (Lambda (witnessArgVar, Lambda(v, CallWithWitnesses(None, mi, minfoWithWitnesses, [Var witnessArgVar2], [a2;b2])))) -> + + check "cewlkjwvw0a" witnessArgVar.Name "op_Addition" + check "cewlkjwvw0b" witnessArgVar.Type (typeof int -> int>) + check "cewlkjwvw1a" witnessArgVar2.Name "op_Addition" + check "cewlkjwvw1b" witnessArgVar2.Type (typeof int -> int>) + check "cewlkjwvw2" minfoWithWitnesses.Name "op_Addition$W" + check "vjnvwiowve" a2 b2 + check "cewlkjwvw0" witnessArgVar witnessArgVar2 + + | q -> report_failure (sprintf "gfwhoewvioh32 - unexpected %A" q) + + | q -> report_failure (sprintf "gfwhoewvioh37 - unexpected %A" q) + + + type C() = + static member Foo (x:int) = x + + [] + let inline f3 (x: ^T) = + ( ^T : (static member Foo: int -> int) (3)) + + match <@ f3 (C()) @> with + | Quotations.Patterns.Call(_, mi, _) -> + let mi3 = mi.GetGenericMethodDefinition() + let q3 = Quotations.Expr.TryGetReflectedDefinition(mi3) + check "fekjevwlw" q3 None + | q -> report_failure (sprintf "3kjhhjkkjhe9 - %A unexpected" q) + + match <@ f3 (C()) @> with + | Quotations.Patterns.CallWithWitnesses(_, mi, miw, [w4], _) -> + let q4 = Quotations.Expr.TryGetReflectedDefinition(miw) + + check "vwroirvjkn" miw.Name "f3$W" + + match q4 with + | Some (Lambda(witnessArgVar, Lambda(v, Application(Var witnessArgVar2, Int32 3)))) -> + check "vwehjrwlkj0" witnessArgVar.Name "Foo" + check "vwehjrwlkj1" witnessArgVar.Type (typeof int>) + check "vwehjrwlkj2" witnessArgVar2.Name "Foo" + check "vwehjrwlkj3" witnessArgVar2 witnessArgVar + | _ -> report_failure (sprintf "3kjhhjkkjhe1 - %A unexpected" q4) + + match w4 with + | Lambda(v, Call(None, miFoo, [Var v2])) -> + check "vewhjwveoi1" miFoo.Name "Foo" + check "vewhjwveoi2" v v2 + | _ -> report_failure (sprintf "3kjhhjkkjhe2 - %A unexpected" w4) + + | q -> report_failure (sprintf "3kjhhjkkjhe0 - %A unexpected" q) + +/// Check we can take quotations of implicit operator trait calls + +module QuotationOfConcreteTraitCalls = + + type Foo(s: string) = + member _.S = s + static member (?) (foo : Foo, name : string) = foo.S + name + static member (++) (foo : Foo, name : string) = foo.S + name + static member (?<-) (foo : Foo, name : string, v : string) = () + + let foo = Foo("hello, ") + + // Desugared form is ok, but ? desugars to a method with constraints which aren't allowed in quotes + let q1 = <@ Foo.op_Dynamic(foo, "uhh") @> + let q2 = <@ foo ? uhh @> + + let q3 = <@ Foo.op_DynamicAssignment(foo, "uhh", "hm") @> + let q4 = <@ foo ? uhh <- "hm" @> + let q5 = <@ foo ++ "uhh" @> + + let cleanup (s:string) = s.Replace(" ","").Replace("\n","").Replace("\r","") + check "wekncjeck112a" (cleanup (sprintf "%0A" q1)) "Call(None,op_Dynamic,[PropertyGet(None,foo,[]),Value(\"uhh\")])" + check "wekncjeck112b" (cleanup (sprintf "%0A" q2)) "Application(Application(Lambda(arg0,Lambda(arg1,Call(None,op_Dynamic,[arg0,arg1]))),PropertyGet(None,foo,[])),Value(\"uhh\"))" + check "wekncjeck112c" (cleanup (sprintf "%0A" q3)) "Call(None,op_DynamicAssignment,[PropertyGet(None,foo,[]),Value(\"uhh\"),Value(\"hm\")])" + check "wekncjeck112d" (cleanup (sprintf "%0A" q4)) "Application(Application(Application(Lambda(arg0,Lambda(arg1,Lambda(arg2,Call(None,op_DynamicAssignment,[arg0,arg1,arg2])))),PropertyGet(None,foo,[])),Value(\"uhh\")),Value(\"hm\"))" + check "wekncjeck112e" (cleanup (sprintf "%0A" q5)) "Application(Application(Lambda(arg0,Lambda(arg1,Call(None,op_PlusPlus,[arg0,arg1]))),PropertyGet(None,foo,[])),Value(\"uhh\"))" + + // Let bound functions handle this ok + let (?) o s = + printfn "%s" s + + // No error here because it binds to the let bound version + let q8 = <@ foo ? uhh @> + +// Check we can take ReflectedDefinition of things involving multiple implicit witnesses and trait calls +module QuotationsOfGenericCodeWithMultipleWitnesses = + + // This has three type paramters and two witnesses, one for + and one for - + [] + let inline f1 x y z = (x + y) - z + + match <@ f1 1 2 3 @> with + | Quotations.Patterns.Call(_, mi, _) -> + let q1 = Quotations.Expr.TryGetReflectedDefinition(mi) + check "vwehwevrwv" q1 None + | q -> report_failure (sprintf "gfwhoewvioh - unexpected %A" q) + + match <@ f1 1 2 3 @> with + | Quotations.Patterns.CallWithWitnesses(_, mi, minfoWithWitnesses, _, _) -> + let q2 = Quotations.Expr.TryGetReflectedDefinition(minfoWithWitnesses) + + match q2 with + | Some (Lambda (witnessArgVarAdd, + Lambda (witnessArgVarSub, + Lambda(xVar, + Lambda(yVar, + Lambda(zVar, + CallWithWitnesses(None, mi1, minfoWithWitnesses1, [Var witnessArgVarSub2], + [CallWithWitnesses(None, mi2, minfoWithWitnesses2, [Var witnessArgVarAdd2], + [Var xVar2; Var yVar2]); + Var zVar2]))))))) -> + + check "cewlkjwv54" witnessArgVarAdd.Name "op_Addition" + check "cewlkjwv55" witnessArgVarSub.Name "op_Subtraction" + check "cewlkjwv56" witnessArgVarAdd.Type (typeof int -> int>) + check "cewlkjwv57" witnessArgVarSub.Type (typeof int -> int>) + check "cewlkjwv58" witnessArgVarAdd witnessArgVarAdd2 + check "cewlkjwv59" witnessArgVarSub witnessArgVarSub2 + check "cewlkjwv60" xVar xVar2 + check "cewlkjwv61" yVar yVar2 + check "cewlkjwv62" zVar zVar2 + + | q -> report_failure (sprintf "gfwhoewvioh32 - unexpected %A" q) + + | q -> report_failure (sprintf "gfwhoewvioh37 - unexpected %A" q) + +// Like QuotationsOfGenericCodeWithMultipleWitnesses but with implementation code the other way around +module QuotationsOfGenericCodeWithMultipleWitnesses2 = + + [] + let inline f1 x y z = (x - y) + z + + match <@ f1 1 2 3 @> with + | Quotations.Patterns.Call(_, mi, _) -> + let q1 = Quotations.Expr.TryGetReflectedDefinition(mi) + check "xvwehwevrwv" q1 None + | q -> report_failure (sprintf "xgfwhoewvioh - unexpected %A" q) + + match <@ f1 1 2 3 @> with + | Quotations.Patterns.CallWithWitnesses(_, mi, minfoWithWitnesses, _, _) -> + let q2 = Quotations.Expr.TryGetReflectedDefinition(minfoWithWitnesses) + + match q2 with + | Some (Lambda (witnessArgVarAdd, + Lambda (witnessArgVarSub, + Lambda(xVar, + Lambda(yVar, + Lambda(zVar, + CallWithWitnesses(None, mi1, minfoWithWitnesses1, [Var witnessArgVarAdd2], + [CallWithWitnesses(None, mi2, minfoWithWitnesses2, [Var witnessArgVarSub2], + [Var xVar2; Var yVar2]); + Var zVar2]))))))) -> + + check "xcewlkjwv54" witnessArgVarAdd.Name "op_Addition" + check "xcewlkjwv55" witnessArgVarSub.Name "op_Subtraction" + check "xcewlkjwv56" witnessArgVarAdd.Type (typeof int -> int>) + check "xcewlkjwv57" witnessArgVarSub.Type (typeof int -> int>) + check "xcewlkjwv58" witnessArgVarAdd witnessArgVarAdd2 + check "xcewlkjwv59" witnessArgVarSub witnessArgVarSub2 + check "xcewlkjwv60" xVar xVar2 + check "xcewlkjwv61" yVar yVar2 + check "xcewlkjwv62" zVar zVar2 + + | q -> report_failure (sprintf "xgfwhoewvioh32 - unexpected %A" q) + + | q -> report_failure (sprintf "xgfwhoewvioh37 - unexpected %A" q) + + +module TestOuterConstrainedClass = + // This example where there is an outer constrained class caused numerous failures + // because it was trying to pass witnesses for the constraint in the type + // + // No witnesses are passed for these + type hoop< ^a when ^a : (static member (+) : ^a * ^a -> ^a) > = + { Group1 : ^a + Group2 : ^a } + static member inline (+) (x, y) = x.Group1 + y.Group2 + //member inline this.Sum = this.Group1 + this.Group2 + + let z = { Group1 = 1; Group2 = 2 } + { Group1 = 2; Group2 = 3 } // ok + +module TestInlineQuotationOfAbsOperator = + + let inline f x = <@ abs x @> + + type C(n:int) = + static member Abs(c: C) = C(-c.P) + member x.P = n + + let v1 = f 3 + let v2 = f 3.4 + let v3 = f (C(4)) + + test "check abs1" + (match v1 with + | CallWithWitnesses(None, minfo1, minfo2, [Value(f,_)], [Int32 3]) -> + minfo1.Name = "Abs" && minfo2.Name = "Abs$W" && ((f :?> (int -> int)) -3 = 3) + | _ -> false) + + test "check abs2" + (match v2 with + | CallWithWitnesses(None, minfo1, minfo2, [Value(f,_)], [Double 3.4]) -> + minfo1.Name = "Abs" && minfo2.Name = "Abs$W" && ((f :?> (double -> double)) -3.0 = 3.0) + | _ -> false) + + test "check abs3" + (match v3 with + | CallWithWitnesses(None, minfo1, minfo2, [Value(f,_)], [Value (v,_)]) -> + minfo1.Name = "Abs" && minfo2.Name = "Abs$W" && ((v :?> C).P = 4) && (((f :?> (C -> C)) (C(-7))).P = 7) + | _ -> false) + + +module TestQuotationOfListSum = + type Point = + { x: int; y: int } + static member Zero = { x=0; y=0 } + static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y } + let points = [{x=1; y=10}] + + let q = <@ List.sum points @> + + match q with + | CallWithWitnesses(None, minfo1, minfo2, [w1; w2], [_]) -> + test "check List.sum 111" (minfo1.Name = "Sum") + test "check List.sum 112" (minfo2.Name = "Sum$W") + printfn "w1 = %A" w1 + match w1 with + | Lambda(v, PropertyGet(None, miFoo, [])) -> + test "check List.sum 113" (miFoo.Name = "Zero") + | _ -> + test "check List.sum 114" false + match w2 with + | Lambda(v, Lambda(v2, Call(None, miFoo, [_;_]))) -> + test "check List.sum 115" (miFoo.Name = "op_Addition") + | _ -> + test "check List.sum 116" false + | _ -> + test "check List.sum 117" false + + +module TestQuotationOfListSum2 = + type Point = + { x: int; y: int } + static member Zero = { x=0; y=0 } + static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y } + let points = [{x=1; y=10}] + + let inline quoteListSum points = <@ List.sum points @> + + match quoteListSum points with + | CallWithWitnesses(None, minfo1, minfo2, [Value (f1, _); Value (f2, _)], [Value (v,_)]) -> + test "check List.sum 211" (minfo1.Name = "Sum") + test "check List.sum 212" (minfo2.Name = "Sum$W") + test "check List.sum 213" (((v :?> Point list) = points)) + test "check List.sum 214" ((((f1 :?> (unit -> Point)) ()) = Point.Zero)) + test "check List.sum 215" ((((f2 :?> (Point -> Point -> Point)) {x=1;y=1} {x=1;y=2}) = {x=2;y=3})) + | _ -> + test "check List.sum 216" false + + +module ComputationExpressionWithOptionalsAndParamArray = + open System + type InputKind = + | Text of placeholder:string option + | Password of placeholder: string option + type InputOptions = + { Label: string option + Kind : InputKind + Validators : (string -> bool) array } + type InputBuilder() = + member t.Yield(_) = + { Label = None + Kind = Text None + Validators = [||] } + [] + member this.Text(io, ?placeholder) = + { io with Kind = Text placeholder } + [] + member this.Password(io, ?placeholder) = + { io with Kind = Password placeholder } + [] + member this.Label(io, label) = + { io with Label = Some label } + [] + member this.Validators(io, [] validators) = + { io with Validators = validators } + + let input = InputBuilder() + let name = + input { + label "Name" + text + with_validators + (String.IsNullOrWhiteSpace >> not) + } + let email = + input { + label "Email" + text "Your email" + with_validators + (String.IsNullOrWhiteSpace >> not) + (fun s -> s.Contains "@") + } + let password = + input { + label "Password" + password "Must contains at least 6 characters, one number and one uppercase" + with_validators + (String.exists Char.IsUpper) + (String.exists Char.IsDigit) + (fun s -> s.Length >= 6) + } + check "vewhkvh1" name.Kind (Text None) + check "vewhkvh2" email.Kind (Text (Some "Your email")) + check "vewhkvh3" email.Label (Some "Email") + check "vewhkvh4" email.Validators.Length 2 + check "vewhkvh5" password.Label (Some "Password") + check "vewhkvh6" password.Validators.Length 3 + +#endif + +module QuotationOfComputationExpressionZipOperation = + + type Builder() = + member __.Bind (x, f) = f x + member __.Return x = x + member __.For (x, f) = f x + member __.Yield x = x + [] + member __.Var (x, y, f) = f x y + + let builder = Builder() + + let q = + <@ builder { + let! x = 1 + var y in 2 + return x + y + } @> + + let actual = (q.ToString()) + checkStrings "brewbreebr" actual + """Application (Lambda (builder@, + Call (Some (builder@), For, + [Call (Some (builder@), Var, + [Call (Some (builder@), Bind, + [Value (1), + Lambda (_arg1, + Let (x, _arg1, + Call (Some (builder@), + Yield, [x])))]), + Value (2), + Lambda (x, Lambda (y, NewTuple (x, y)))]), + Lambda (_arg2, + Let (y, TupleGet (_arg2, 1), + Let (x, TupleGet (_arg2, 0), + Call (Some (builder@), Return, + [Call (None, op_Addition, + [x, y])]))))])), + PropertyGet (None, builder, []))""" + +module CheckEliminatedConstructs = + let isNullQuoted (ts : 't[]) = + <@ + match ts with + | null -> true + | _ -> false + @> + + let actual1 = ((isNullQuoted [| |]).ToString()) + checkStrings "brewbreebrvwe1" actual1 + """IfThenElse (Call (None, op_Equality, [ValueWithName ([||], ts), Value ()]), + Value (true), Value (false))""" + +module Interpolation = + let interpolatedNoHoleQuoted = <@ $"abc" @> + let actual1 = interpolatedNoHoleQuoted.ToString() + checkStrings "brewbreebrwhat1" actual1 """Value ("abc")""" + + let interpolatedWithLiteralQuoted = <@ $"abc {1} def" @> + let actual2 = interpolatedWithLiteralQuoted.ToString() + checkStrings "brewbreebrwhat2" actual2 + """Call (None, PrintFormatToString, + [NewObject (PrintfFormat`5, Value ("abc %P() def"), + NewArray (Object, Call (None, Box, [Value (1)])), + Value ())])""" module TestAssemblyAttributes = let attributes = System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(false) @@ -3174,8 +4144,8 @@ let aa = stdout.WriteLine "Test Passed" System.IO.File.WriteAllText("test.ok","ok") exit 0 - | _ -> - stdout.WriteLine "Test Failed" + | errs -> + printfn "Test Failed, errors = %A" errs exit 1 #endif diff --git a/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.bsl b/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.bsl new file mode 100644 index 00000000000..e3b148ff622 --- /dev/null +++ b/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.bsl @@ -0,0 +1,12 @@ + +test-langversion-preview.fsx(2,3,2,5): typecheck info FS3370: The use of ':=' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'cell := expr' to 'cell.Value <- expr'. + +test-langversion-preview.fsx(3,10,3,11): typecheck info FS3370: The use of '!' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change '!cell' to 'cell.Value'. + +test-langversion-preview.fsx(4,1,4,5): typecheck info FS3370: The use of 'incr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'incr cell' to 'cell.Value <- cell.Value + 1'. + +test-langversion-preview.fsx(5,1,5,5): typecheck info FS3370: The use of 'decr' from the F# library is deprecated. See https://aka.ms/fsharp-refcell-ops. For example, please change 'decr cell' to 'cell.Value <- cell.Value - 1'. + +test-langversion-preview.fsx(9,14,9,15): typecheck error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'X'. + +test-langversion-preview.fsx(8,14,8,15): typecheck error FS0438: Duplicate method. The method 'M' has the same name and signature as another method in type 'X'. diff --git a/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.fsx b/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.fsx new file mode 100644 index 00000000000..34bb29ad8e1 --- /dev/null +++ b/tests/fsharp/core/ref-ops-deprecation/test-langversion-preview.fsx @@ -0,0 +1,9 @@ +let r = ref 3 +r := 4 // generates an informational in preview +let rv = !r // generates an informational in preview +incr r // generates an informational in preview +decr r // generates an informational in preview + +type X() = + member x.M(a:int) = a + member x.M(b:int) = b \ No newline at end of file diff --git a/tests/fsharp/core/seq/test.fsx b/tests/fsharp/core/seq/test.fsx index 14f71eb2940..107f79676d1 100644 --- a/tests/fsharp/core/seq/test.fsx +++ b/tests/fsharp/core/seq/test.fsx @@ -729,7 +729,33 @@ module TestCollectOnStructSeq = seq { yield! Seq.collect (fun _ -> x) [1] } check "ccekecnwe" (iterate (Unchecked.defaultof) |> Seq.length) 2 - + +module CheckStateMachineCompilationOfMatchBindingVariables = + let f xs = + seq { + match xs with + | 1,h + | h,1 -> + let stackTrace = new System.Diagnostics.StackTrace() + let methodBase = stackTrace.GetFrame(1).GetMethod() + System.Console.WriteLine(methodBase.Name) + // This checks we have a state machine. In the combinator compilation + // we get 'Invoke'. + check "vwehoehwvo" methodBase.Name "MoveNextImpl" + yield h + yield h + | 2,h + | h,2 -> + yield h + | _ -> () + } + + check "ccekecnwevwe1" (f (1, 2) |> Seq.toList) [2;2] + check "ccekecnwevwe2" (f (2, 1) |> Seq.toList) [2;2] + check "ccekecnwevwe3" (f (2, 3) |> Seq.toList) [3] + check "ccekecnwevwe4" (f (3, 2) |> Seq.toList) [3] + check "ccekecnwevwe5" (f (3, 3) |> Seq.toList) [] + (*--------------------------------------------------------------------------- !* wrap up *--------------------------------------------------------------------------- *) diff --git a/tests/fsharp/core/span/common-pre.fsx b/tests/fsharp/core/span/common-pre.fsx index c6f05de3a5b..ddd4a03e8fb 100644 --- a/tests/fsharp/core/span/common-pre.fsx +++ b/tests/fsharp/core/span/common-pre.fsx @@ -1,4 +1,8 @@ open System open System.IO -File.WriteAllText("refs.generated.fsx", sprintf @"#r @""%s\.nuget\packages\System.Memory\4.5.2\lib\netstandard2.0\System.Memory.dll""" (Environment.GetEnvironmentVariable("USERPROFILE"))) +let packagesDir = + match Environment.GetEnvironmentVariable("NUGET_PACKAGES") with + | null -> Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".nuget", "packages") + | path -> path +File.WriteAllText("refs.generated.fsx", sprintf @"#r @""%s\System.Memory\4.5.3\lib\netstandard2.0\System.Memory.dll""" packagesDir) diff --git a/tests/fsharp/core/state-machines/neg-resumable-01.bsl b/tests/fsharp/core/state-machines/neg-resumable-01.bsl new file mode 100644 index 00000000000..a41e25ac3f5 --- /dev/null +++ b/tests/fsharp/core/state-machines/neg-resumable-01.bsl @@ -0,0 +1,18 @@ + +neg-resumable-01.fsx(62,17,63,37): typecheck error FS3501: Invalid resumable code. A 'let rec' occured in the resumable code specification + +neg-resumable-01.fsx(70,9,70,19): typecheck error FS3402: The construct '__resumeAt' may only be used in valid resumable code. + +neg-resumable-01.fsx(75,42,75,54): typecheck error FS3402: The construct '__resumeAt' may only be used in valid resumable code. + +neg-resumable-01.fsx(83,21,83,31): typecheck error FS3402: The construct '__resumeAt' may only be used in valid resumable code. + +neg-resumable-01.fsx(92,23,92,41): typecheck error FS3402: The construct '__resumableEntry' may only be used in valid resumable code. + +neg-resumable-01.fsx(104,31,104,47): typecheck error FS3402: The construct '__resumableEntry' may only be used in valid resumable code. + +neg-resumable-01.fsx(106,29,106,39): typecheck error FS3402: The construct '__resumeAt' may only be used in valid resumable code. + +neg-resumable-01.fsx(122,31,122,47): typecheck error FS3402: The construct '__resumableEntry' may only be used in valid resumable code. + +neg-resumable-01.fsx(144,31,144,47): typecheck error FS3402: The construct '__resumableEntry' may only be used in valid resumable code. diff --git a/tests/fsharp/core/state-machines/neg-resumable-01.fsx b/tests/fsharp/core/state-machines/neg-resumable-01.fsx new file mode 100644 index 00000000000..ae41702953d --- /dev/null +++ b/tests/fsharp/core/state-machines/neg-resumable-01.fsx @@ -0,0 +1,152 @@ +module Tests_Tasks + +#nowarn "57" // experimental +#nowarn "3513" // resumable code invocation +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers +open System.Runtime.CompilerServices + +//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// No warnings expected in the declarations + +module ``No warning for resumable code that is just a simple expression`` = + + let inline f1 () = ResumableCode(fun sm -> true ) + +module ``No warning for resumable code that is just a sequential expression`` = + + + let inline f1 () = + ResumableCode(fun sm -> + printfn "hello" + true) + +module ``No warning for protected use of __resumeAt`` = + + + let inline f1 () = + ResumableCode(fun sm -> + if __useResumableCode then + __resumeAt 0 // we don't get a warning here + true + else + false ) + +module ``No warning for protected use of __resumableEntry`` = + + + let inline f1 () = + ResumableCode(fun sm -> + if __useResumableCode then + match __resumableEntry() with + | Some contID -> true + | None -> true + else + false) + +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// No warnings expected in code before this line + + +let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() +let inline MoveOnce(x: byref<'T> when 'T :> IAsyncStateMachine and 'T :> IResumableStateMachine<'Data>) = + MoveNext(&x) + x.Data + +// Resumable code may not have let rec statements +module ``Error on let rec in resumable code`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + + let rec f x = if x > 0 then f (x-1) else inputValue + 13 + f 10 + f 2 |> ignore + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + +module ``Error on unprotected __resumeAt`` = + let inline f1 () = + __resumeAt 0 + 1 + +module ``Error on unprotected __resumeAt in resumable code`` = + let inline f1 () = + ResumableCode(fun sm -> __resumeAt 0) + +module ``Error because fast integer for loop doesn't supported resumable code`` = + + let inline f1 () = + ResumableCode(fun sm -> + if __useResumableCode then + for i = 0 to 1 do + __resumeAt 0 // we expect an error here - this is not valid resumable code + true + else + false) + +module ``Error because unprotected __resumableEntry`` = + + let inline f1 () = + ResumableCode(fun sm -> + match __resumableEntry() with // we expect an error here - this is not valid resumable code without 'if .. ' + | Some contID -> false + | None -> true + ) + +module ``let bound function can't use resumable code constructs`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + + __resumeAt 1 + let f () = + match __resumableEntry() with // we expect an error here - this is not in resumable code + | Some contID -> + __resumeAt contID + | None -> + 20+inputValue + f() |> ignore + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + +module ``Check no resumption point in try-finally `` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + __resumeAt 1 + let mutable res = inputValue + try + // Attempt to specify a resumption point in the try-finally + match __resumableEntry() with // we expect an error here - this is not in resumable code + | Some contID -> + failwith "unreachable" + res <- 0 + | None -> + res <- res + 10 + finally + res <- res + 20 + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + +module ``Check no resumption point in fast integer for loop`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + __resumeAt 1 + let mutable res = inputValue + let mutable count = 0 + for i = 0 to 9 do + // Attempt to specify a resumption point in the for loop. THis is not permitted + // and while loops should be used instead + match __resumableEntry() with // we expect an error here - this is not in resumable code + | Some contID -> + failwith "unreachable" + res <- 0 + | None -> + res <- res + 10 + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) diff --git a/tests/fsharp/core/state-machines/neg-resumable-02.bsl b/tests/fsharp/core/state-machines/neg-resumable-02.bsl new file mode 100644 index 00000000000..6ca06f293de --- /dev/null +++ b/tests/fsharp/core/state-machines/neg-resumable-02.bsl @@ -0,0 +1,6 @@ + +neg-resumable-02.fsx(22,9,32,54): ilxgen error FS3512: This state machine is not statically compilable and no alternative is available. A 'let rec' occured in the resumable code specification. Use an 'if __useResumableCode then else ' to give an alternative. + +neg-resumable-02.fsx(41,9,54,14): ilxgen error FS3511: This state machine is not statically compilable. A 'let rec' occured in the resumable code specification. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning. + +neg-resumable-02.fsx(75,9,75,13): ilxgen error FS3511: This state machine is not statically compilable. A 'let rec' occured in the resumable code specification. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning. diff --git a/tests/fsharp/core/state-machines/neg-resumable-02.fsx b/tests/fsharp/core/state-machines/neg-resumable-02.fsx new file mode 100644 index 00000000000..91fed86d501 --- /dev/null +++ b/tests/fsharp/core/state-machines/neg-resumable-02.fsx @@ -0,0 +1,79 @@ +module Tests_Tasks + +#nowarn "57" +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers +open System.Threading.Tasks +open System.Runtime.CompilerServices + +//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// No warnings expected in the declarations + +let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() +let inline MoveOnce(x: byref<'T> when 'T :> IAsyncStateMachine and 'T :> IResumableStateMachine<'Data>) = + MoveNext(&x) + x.Data + +module ``late compilation error on user-defined let rec in resumable code`` = + + let inline f1 (code: unit -> ResumableCode<_,_>) = ResumableCode(fun sm -> code().Invoke(&sm)) + + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + let __stack_step = + f1(fun () -> + let rec f x = f x + 1 // resumable code can't be used because of 'let rec' and no alternative is given + f 3 |> ignore + ResumableCode.Zero()).Invoke(&sm) + () + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + makeStateMachine 4 + +module ``compilation warning on user-defined let rec in resumable code when alternative given`` = + + let inline f1 (code: unit -> ResumableCode<_,_>) = ResumableCode(fun sm -> code().Invoke(&sm)) + + let makeStateMachine () = + if __useResumableCode then + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + let __stack_step = + f1(fun () -> + let rec f x = f x + 1 // resumable code can't be used because of 'let rec' and no alternative is given + f 3 |> ignore + ResumableCode.Zero()).Invoke(&sm) + () + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + else + 2 + + + makeStateMachine () + +module ``no compilation warning on user-defined let in task`` = + + let makeTask () = + task { + let f x = + printfn "ewcvw" + printfn "ewcvw" + printfn "ewcvw" + printfn "ewcvw" + 1 + return f 1 + } + +module ``compilation warning on user-defined let rec in task`` = + + let makeTask () = + task { + let rec f x = f x + 1 + return f 1 + } + diff --git a/tests/fsharp/core/state-machines/test.fsx b/tests/fsharp/core/state-machines/test.fsx new file mode 100644 index 00000000000..6139f25053b --- /dev/null +++ b/tests/fsharp/core/state-machines/test.fsx @@ -0,0 +1,672 @@ +module Tests_Tasks + +#nowarn "57" +open FSharp.Core.CompilerServices +open FSharp.Core.CompilerServices.StateMachineHelpers +open System.Runtime.CompilerServices +open System.Threading.Tasks + + +let failures = ref [] + +let report_failure (s : string) = + stderr.Write" NO: " + stderr.WriteLine s + failures := !failures @ [s] + +let test s b = + stderr.Write(s:string) + if b then stderr.WriteLine " OK" else report_failure s + stderr.WriteLine "" + +let check s v1 v2 = + stderr.Write(s:string); + if (v1 = v2) then + stderr.WriteLine " OK" + stderr.WriteLine "" + else + eprintf " FAILED: got %A, expected %A" v1 v2 + stderr.WriteLine "" + report_failure s + +let inline MoveNext(x: byref<'T> when 'T :> IAsyncStateMachine) = x.MoveNext() +let inline MoveOnce(x: byref<'T> when 'T :> IAsyncStateMachine and 'T :> IResumableStateMachine<'Data>) = + MoveNext(&x) + x.Data + +module ``Check simple state machine`` = + let makeStateMachine() = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + sm.Data <- 1 // we expect this result for successful resumable code compilation + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "ResumableObject_SimpleImmediateExpression" (makeStateMachine()) 1 + + +module ``Check resumable code can capture variables`` = + let makeStateMachine x = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + sm.Data <- 1 + x // we expect this result for successful resumable code compilation + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + let sm3 = makeStateMachine 3 + check "vwervwkhevh" (makeStateMachine 3) 4 + + +module ``Check resumable code may be preceeded by value definitions`` = + let makeStateMachine x = + let rnd = System.Random().Next(4) + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + sm.Data <- x + rnd - rnd // we expect this result for successful resumable code compilation + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "cvwvweewvhjkv" (makeStateMachine 4) 4 + +module ``Check resumable code may contain local function definitions`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let someFunction x = x + 1 + sm.Data <- someFunction y + someFunction y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "vewwevbrklbre" (makeStateMachine 3) 8 + +module ``Check resumable code may be preceeded by function definitions`` = + let makeStateMachine y = + let someFunction1 x = x + 1 + let someFunction2 x = someFunction1 x + 2 + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + sm.Data <- someFunction2 y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "vwekvewkhvew" (makeStateMachine 3) 6 + +module ``Check resumable code may contain let statements without resumption points`` = + let makeStateMachine x = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let y = 1 - x + if x > 3 then + sm.Data <- 1 + x + else + sm.Data <- y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "vwelvewl" (makeStateMachine 3) -2 + +module ``Check resumable code may contain sequential statements without resumption points`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + printfn "step1" + sm.Data <- y + 2 + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "ewvkwekvwevwvek" (makeStateMachine 3) 5 + +module ``Check resuming at start of method`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + + if __useResumableCode then + __resumeAt 0 + let __stack_fin = ResumableCode.Yield().Invoke(&sm) // label 1 + if __stack_fin then + sm.Data <- 20+y + else + sm.Data <- 10+y // we should end up here + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "vwrvwlkelwe" (makeStateMachine 3) 13 + +module ``Check resuming at drop through`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 100 + let __stack_fin = ResumableCode.Yield().Invoke(&sm) // label 1 + if __stack_fin then + sm.Data <- 20+y + else + sm.Data <- 10+y // we should end up here + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "cvqelekckeq" (makeStateMachine 3) 13 + +module ``Check resuming at a resumption point`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + + if __useResumableCode then + __resumeAt 1 + let __stack_fin = ResumableCode.Yield().Invoke(&sm) // label 1 + if __stack_fin then + sm.Data <- 20+y // we should end up here + else + sm.Data <- 10+y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + check "vwlvkjlewjwevj" (makeStateMachine 3) 23 + + +module ``Check resumable code may contain try-with without resumption points`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + + if __useResumableCode then + try + sm.Data <- inputValue + 10 + with e -> + sm.Data <- 12 + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "fvwewejkhkwe" (makeStateMachine 13) 23 + +module ``Check resuming at resumption point in try block`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 // this goes straight to label 1 + try + failwith "unreachable #1" // this is skipped because we jump straight to label 1 + let __stack_fin = ResumableCode.Yield().Invoke(&sm) // label 1 is resumption of this + if __stack_fin then + // This is the resumption path + sm.Data <- 20+inputValue // this is the result + else + // This is the suspension path. It is not executed in this test because we jump straight to label 1 + failwith "unreachable #2" + with e -> + sm.Data <- 12 + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "ResumableCode_TryWithResumption" (makeStateMachine 13) 33 + +module ``Check exception thrown in try block after resumption is caught`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 // this goes straight to label 1 + try + // Specify a resumption point + let __stack_fin = ResumableCode.Yield().Invoke(&sm) // label 1 is resumption of this + if not __stack_fin then + // This is the suspension path. It is not executed in this test because we jump straight to label 1 + sm.Data <- 10+inputValue + else + // This is the resumption path + failwith "raise" + sm.Data <- inputValue + 15 + with e -> + sm.Data <- inputValue + 12 // this is the result + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "ResumableCode_TryWithResumptionException" (makeStateMachine 13) 25 + +module ``Check exception thrown in try block with no resumption points is caught`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + try + failwith "fail" + with e -> + sm.Data <- inputValue + 12 + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "ResumableCode_TryWithExceptionNoResumption" (makeStateMachine 13) 25 + +module ``Check resumable code may contain try-finally without resumption points`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let mutable res = 0 + try + res <- inputValue + 10 + finally + res <- inputValue + 40 + sm.Data <- res + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "ResumableCode_TryFinallyNoResumption" (makeStateMachine 13) 53 + +// try-finally may **not** contain resumption points. This is because it's +// very difficult to codegen them in IL. Instead you have to code try/finally logic as shown below. +// See also tasks.fs. +module ``Check can simulate try-finally via try-with`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 // this goes straight to label 1 + let mutable res = 0 // note, this initialization doesn't actually happen since we go straight to label 1. However this is the zero-init value. + let mutable __stack_completed = false // note, this initialization doesn't actually happen since we go straight to label 1. However this is the zero-init value. + try + failwith "unreachable" // this code is not executed as the __resumeAt goes straight to resumption label 1 + + // Specify a resumption point + let __stack_fin = ResumableCode.Yield().Invoke(&sm) + if not __stack_fin then + // This is the suspension path. It is not executed in this test because we jump straight to label 1 + failwith "unreachable" + res <- 0 + __stack_completed <- false + else + // This is the resumption path + // Label 1 goes here + res <- res + + inputValue + 10 // this gets executed and contributes to the result + __stack_completed <- true + with _ -> + res <- res + 20 + reraise() + if __stack_completed then + res <- res + 20 + sm.Data <- res + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "vwevewewlvjve" (makeStateMachine 13) 43 + +module ``Check resumable code may contain try-finally without resumption points and raising exception`` = + let mutable res = 0 + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + try + failwith "fail" + finally + res <- inputValue + 10 + sm.Data <- res + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "cvwekjwejkl" (try makeStateMachine 13 with _ -> res ) 23 + +module ``Check resumable code may contain while loop without resumption`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let mutable count = 0 + while count < 10 do + count <- count + 1 + sm.Data <- inputValue + 12 + count + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "fvewhjkvekwhk" (makeStateMachine 13) 35 + +module ``Check resumable code may contain while loop with resumption`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 // this goes straight to label 1 + let mutable count = 0 // note, this initialization doesn't actually happen since we go straight to label 1. However this is the zero-init value. + let mutable res = 0 // note, this initialization doesn't actually happen since we go straight to label 1. However this is the zero-init value. + while count < 10 do + // Specify a resumption point in the loop + let __stack_fin = ResumableCode.Yield().Invoke(&sm) + if not __stack_fin then + // This is the suspension path. It is executed in this test for subsequent iterations in this loop + count <- count + 1 + res <- res + 20 // gets executed 9 times + else + // This is the resumption path + // Label 1 goes here + count <- count + 1 + res <- res + 10 // gets executed once + // res ends up as 190 + sm.Data <- inputValue + res + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "wejlcewjllkjwce" (makeStateMachine 13) 203 + + +module ``Check resumable code may contain integer for loop without resumption`` = + let makeStateMachine inputValue = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let mutable count = 0 + for i = 0 to 9 do + count <- count + 1 + sm.Data <- inputValue + 12 + count + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "celjkcwljeljwecl" (makeStateMachine 13) 35 + +module ``Check resumable code can contain a conditional with a resumption point`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 + failwith "fail" + if y > 10 then + let __stack_fin = ResumableCode.Yield().Invoke(&sm) + if not __stack_fin then + // This is the suspension path. It is not executed in this test as we go straight to label 1 + failwith "fail" + else + // This is the resumption path + // Label 1 goes here + sm.Data <- 20+y // this is the answer + else + sm.Data <- 30 + y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "vewowevewoi" (makeStateMachine 13) 33 + +module ``Check resumable code can contain a conditional with a resumption point in else branch`` = + let makeStateMachine y = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + __resumeAt 1 + failwith "fail" + if y <= 10 then + sm.Data <- 30 + y + else + let __stack_fin = ResumableCode.Yield().Invoke(&sm) + if not __stack_fin then + // This is the suspension path. It is not executed in this test as we go straight to label 1 + failwith "fail" + else + // This is the resumption path + // Label 1 goes here + sm.Data <- 20+y // this is the answer + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun sm -> MoveOnce(&sm))) + + check "vewowevewoi" (makeStateMachine 13) 33 + + + +let inline checkStateMachine nm = + check nm (System.Reflection.MethodBase.GetCurrentMethod().Name) "MoveNext" + +// The main tests for tasks are in tests\FSharp.Core.UnitTests\FSharp.Core\Microsoft.FSharp.Control\Tasks.fs +// These simply detect state machine compilation +module ``Check simple task compiles to state machine`` = + + let test1() = + + task { + checkStateMachine "vevroerhn11" + return 1 + } + + test1().Wait() + +module ``Check simple task with bind compiles to state machine`` = + let test2() = + + task { + checkStateMachine "vevroerhn12" + let! v1 = Task.FromResult 1 + checkStateMachine "vevroerhn13" + return 1 + } + + test2().Wait() + + +module ``Check task with multiple bind doesn't cause code explosion from inlining and compiles to state machine`` = + + let syncTask() = Task.FromResult 100 + + let tenBindSync_Task() = + task { + let! res1 = syncTask() + checkStateMachine "vevroerhn121" + let! res2 = syncTask() + checkStateMachine "vevroerhn122" + let! res3 = syncTask() + checkStateMachine "vevroerhn123" + let! res4 = syncTask() + checkStateMachine "vevroerhn124" + let! res5 = syncTask() + checkStateMachine "vevroerhn125" + let! res6 = syncTask() + checkStateMachine "vevroerhn126" + let! res7 = syncTask() + checkStateMachine "vevroerhn127" + let! res8 = syncTask() + checkStateMachine "vevroerhn128" + let! res9 = syncTask() + checkStateMachine "vevroerhn129" + let! res10 = syncTask() + checkStateMachine "vevroerhn120" + return res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9 + res10 + } + + tenBindSync_Task().Wait() + +module ``Check task with try with compiles to state machine`` = + let t67() = + task { + checkStateMachine "vevroerhn180" + try + checkStateMachine "vevroerhn181" + do! Task.Delay(0) + checkStateMachine "vevroerhn182" + with + | :? System.ArgumentException -> + () + | _ -> + () + } + + t67().Wait() + +module ``Check task with try with and incomplete match compiles to state machine`` = + let t68() = + task { + try + checkStateMachine "vevroerhn190" + do! Task.Delay(0) + checkStateMachine "vevroerhn191" + with + | :? System.ArgumentException -> + () + } + + t68().Wait() + +module ``Check task with while loop with resumption points compiles to state machine`` = + let t68() : Task = + task { + checkStateMachine "vevroerhn200" + let mutable i = 0 + while i < 1 do + checkStateMachine "vevroerhn201" + i <- i + 1 + do! Task.Yield() + () + checkStateMachine "vevroerhn202" + return i + } + + t68().Wait() + +module ``Check task with try finally compiles to state machine`` = + let t68() = + task { + let mutable ran = false + try + checkStateMachine "vevroerhn210" + do! Task.Delay(100) + checkStateMachine "vevroerhn211" + + finally + ran <- true + return ran + } + + t68().Wait() + +module ``Check task with use compiles to state machine`` = + let t68() = + task { + let mutable disposed = false + use d = { new System.IDisposable with member __.Dispose() = disposed <- true } + checkStateMachine "vevroerhn221" + do! Task.Delay(100) + checkStateMachine "vevroerhn221" + } + + t68().Wait() + +module ``Check nested task compiles to state machine`` = + let t68() = + task { + let mutable n = 0 + checkStateMachine "vevroerhn230" + while n < 10 do + let! _ = + task { + do! Task.Yield() + checkStateMachine "vevroerhn231" + let! _ = Task.FromResult(0) + n <- n + 1 + } + n <- n + 1 + } + + t68().Wait() + +module ``Check after code may include closures`` = + let makeStateMachine x = + __stateMachine + (MoveNextMethodImpl<_>(fun sm -> + if __useResumableCode then + let y = 1 - x + if x > 3 then + sm.Data <- 1 + x + else + sm.Data <- y + else + sm.Data <- 0xdeadbeef // if we get this result it means we've failed to compile as resumable code + )) + (SetStateMachineMethodImpl<_>(fun sm state -> ())) + (AfterCode<_,_>(fun smref -> + let sm = smref // deref the byref so we can rvalue copy-capture the state machine + let f (x:int ) = + printfn "large closure" + printfn "large closure" + printfn "large closure" + printfn "large closure" + let mutable sm = sm + MoveOnce(&sm) + f 3)) + check "vwelvewl" (makeStateMachine 3) -2 + +#if TESTS_AS_APP +let RUN() = !failures +#else +let aa = + match !failures with + | [] -> + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + | _ -> + stdout.WriteLine "Test Failed" + exit 1 +#endif + diff --git a/tests/fsharp/core/unitsOfMeasure/test.fs b/tests/fsharp/core/unitsOfMeasure/test.fs index deafae9588a..93094a79892 100644 --- a/tests/fsharp/core/unitsOfMeasure/test.fs +++ b/tests/fsharp/core/unitsOfMeasure/test.fs @@ -29,16 +29,36 @@ let foo = problem // Error: Incorrect number of type arguments to local call -let nullReferenceError weightedList = - let rec loop accumululatedWeight (remaining : float<'u> list) = - match remaining with - | [] -> accumululatedWeight - | weight :: tail -> - loop (accumululatedWeight + weight) tail - - loop 0.0<_> weightedList - -let ``is this null?`` = nullReferenceError [ 0.3; 0.3; 0.4 ] +// This was causing bad codegen in debug code +module InnerFunctionGenericOnlyByMeasure = + let nullReferenceError weightedList = + let rec loop accumululatedWeight (remaining : float<'u> list) = + match remaining with + | [] -> accumululatedWeight + | weight :: tail -> + loop (accumululatedWeight + weight) tail + + loop 0.0<_> weightedList + + let ``is this null?`` = nullReferenceError [ 0.3; 0.3; 0.4 ] + +// Another variation on the above test case, where the recursive thing is a type function generic unly by a unit of measure +module TopLevelTypeFunctionGenericOnlyByMeasure = + type C< [] 'u> = + abstract Invoke: float<'u> list -> int + + let rec loop<[]'u> = + { new C<'u> with + member _.Invoke(xs) = + match xs with + | [] -> 1 + | weight :: tail -> + loop<'u>.Invoke(tail) } + + let nullReferenceError2 (weightedList: float<'u> list) = + loop<'u>.Invoke(weightedList) + + let ``is this null 2?`` = nullReferenceError2 [ 0.3; 0.3; 0.4 ] module TestLibrary = diff --git a/tests/fsharp/optimize/analyses/effects.HasEffect.output.test.bsl b/tests/fsharp/optimize/analyses/effects.HasEffect.output.test.bsl index cbe4469bf05..709d75c6df2 100644 --- a/tests/fsharp/optimize/analyses/effects.HasEffect.output.test.bsl +++ b/tests/fsharp/optimize/analyses/effects.HasEffect.output.test.bsl @@ -48,24 +48,24 @@ function simpleLibraryUse19 at line 66 causes side effects or may not terminate function complexDataAnalysisFunction at line 73 causes no side effects function complexDataConstructionFunction at line 81 causes side effects or may not terminate function veryComplexDataConstructionFunction at line 90 causes side effects or may not terminate -function ( .ctor ) at line 118 causes side effects or may not terminate +function ``.ctor`` at line 118 causes side effects or may not terminate function X at line 119 causes no side effects function A at line 121 causes no side effects -function ( .ctor ) at line 124 causes side effects or may not terminate +function ``.ctor`` at line 124 causes side effects or may not terminate function X at line 125 causes no side effects function A at line 127 causes no side effects -function ( .ctor ) at line 130 causes side effects or may not terminate +function ``.ctor`` at line 130 causes side effects or may not terminate function X at line 131 causes side effects or may not terminate function A at line 133 causes side effects or may not terminate -function ( .ctor ) at line 135 causes side effects or may not terminate +function ``.ctor`` at line 135 causes side effects or may not terminate function Y at line 137 causes no side effects function Z at line 138 causes side effects or may not terminate function A at line 139 causes no side effects -function ( .ctor ) at line 142 causes side effects or may not terminate +function ``.ctor`` at line 142 causes side effects or may not terminate function Y at line 144 causes no side effects function Z at line 145 causes side effects or may not terminate function A at line 146 causes no side effects -function ( .ctor ) at line 149 causes side effects or may not terminate +function ``.ctor`` at line 149 causes side effects or may not terminate function Y at line 151 causes side effects or may not terminate function Z at line 152 causes side effects or may not terminate -function A at line 153 causes side effects or may not terminate \ No newline at end of file +function A at line 153 causes side effects or may not terminate diff --git a/tests/fsharp/perf/computation-expressions/dependency_graph.fsx b/tests/fsharp/perf/computation-expressions/dependency_graph.fsx new file mode 100644 index 00000000000..348aab0349b --- /dev/null +++ b/tests/fsharp/perf/computation-expressions/dependency_graph.fsx @@ -0,0 +1,192 @@ + +let mutable nodes = 0 +let mutable recalcs = 0 + +[] +type Node(dirty) = + do nodes <- nodes + 1 + + let dependees = ResizeArray>() + let mutable dirty = dirty + + member _.Dirty with get() = dirty and set v = dirty <- v + + member _.Dependees = + dependees.ToArray() + |> Array.choose (fun c -> match c.TryGetTarget() with true, tg -> Some tg | _ -> None) + + member _.AddDependee(c) = + dependees.Add(System.WeakReference<_>(c)) + + member _.InputChanged() = + for c in dependees do + match c.TryGetTarget() with + | true, tg -> tg.SetDirty() + | _ -> () + + member n.SetDirty() = + if not dirty then + dirty <- true + n.InputChanged() + + +[] +type Node<'T>(dirty) = + inherit Node(dirty) + abstract Value : 'T + +/// A node that recomputes if any if its inputs change +type RecalcNode<'T>(dirty, initial, f: unit -> 'T) = + inherit Node<'T>(dirty) + + let mutable cachedValue = initial + + new (f) = new RecalcNode<'T>(true, Unchecked.defaultof<_>, f) + + new (initial, f) = new RecalcNode<'T>(false, initial, f) + + override n.Value = + if n.Dirty then + recalcs <- recalcs + 1 + cachedValue <- f() + n.Dirty <- false + cachedValue + + override _.ToString() = sprintf "(latest %A)" cachedValue + +/// A node that never recomputes +type ConstantNode<'T>(x: 'T) = + inherit Node<'T>(false) + + override _.Value = x + + override _.ToString() = sprintf "(latest %A)" x + +type InputNode<'T>(v: 'T) = + inherit Node<'T>(false) + let mutable currentValue = v + override _.Value = currentValue + + member node.SetValue v = + currentValue <- v + node.InputChanged() + +type NodeBuilder() = + + member _.Bind(x: Node<'T1>, f: 'T1 -> Node<'T2>) : Node<'T2> = + let rec n = + RecalcNode<'T2>(fun () -> + let n2 = f x.Value + n2.AddDependee(n) + n2.Value) + x.AddDependee(n) + n :> Node<_> + + member _.BindReturn(x: Node<'T1>, f: 'T1 -> 'T2) : Node<'T2> = + let n = RecalcNode<'T2>(fun () -> f x.Value) + x.AddDependee(n) + n :> Node<_> + + member _.Bind2(x1: Node<'T1>, x2: Node<'T2>, f: 'T1 * 'T2 -> Node<'T3>) : Node<'T3> = + let rec n = + RecalcNode<'T3>(fun () -> + let n2 = f (x1.Value, x2.Value) + n2.AddDependee(n) + n2.Value) + x1.AddDependee(n) + x2.AddDependee(n) + n :> Node<_> + + member _.Bind2Return(x1: Node<'T1>, x2: Node<'T2>, f: 'T1 * 'T2 -> 'T3) : Node<'T3> = + let n = RecalcNode<'T3>(fun () -> f (x1.Value, x2.Value)) + x1.AddDependee(n) + x2.AddDependee(n) + n :> Node<_> + + member _.Bind3(x1: Node<'T1>, x2: Node<'T2>, x3: Node<'T3>, f: 'T1 * 'T2 * 'T3 -> Node<'T4>) : Node<'T4> = + let rec n = + RecalcNode<'T4>(fun () -> + let n2 = f (x1.Value, x2.Value, x3.Value) + n2.AddDependee(n) + n2.Value) + x1.AddDependee(n) + x2.AddDependee(n) + x3.AddDependee(n) + n :> Node<_> + + member _.Bind3Return(x1: Node<'T1>, x2: Node<'T2>, x3: Node<'T3>, f: 'T1 * 'T2 * 'T3 -> 'T4) : Node<'T4> = + let n = RecalcNode<'T4>(fun () -> f (x1.Value, x2.Value, x3.Value)) + x1.AddDependee(n) + x2.AddDependee(n) + x3.AddDependee(n) + n :> Node<_> + + member _.MergeSources(x1: Node<'T1>, x2: Node<'T2>) : Node<'T1 * 'T2> = + let n = RecalcNode<_>(fun () -> (x1.Value, x2.Value)) + x1.AddDependee(n) + x2.AddDependee(n) + n :> Node<_> + + member _.Return(x: 'T) : Node<'T> = + ConstantNode<'T>(x) :> Node<_> + +let node = NodeBuilder() +let input v = InputNode(v) + +let inp1 = input 3 +let inp2 = input 7 +let inp3 = input 0 + +let test1() = + node { + let! v1 = inp1 + and! v2 = inp2 + and! v3 = inp3 + return v1 + v2 + v3 + } + //let n1 = node.Bind3Return(inp1.Node, inp2.Node, inp3.Node, (fun (v1, v2, v3) -> v1 + v2 + v3)) + +let test2() = + node { + let! v1 = inp1 + let! v2 = inp2 + let! v3 = inp3 + return v1 + v2 + v3 + } + +let test msg f = + recalcs <- 0 + nodes <- 0 + + let (n: Node) = f() + + let v1 = n.Value // now 10 + + recalcs <- 0 + + for i in 1 .. 1000 do + inp1.SetValue 4 + let v2 = n.Value // now 11 + + inp2.SetValue 10 + let v3 = n.Value // now 14 + () + + printfn "inp1.Dependees.Length = %d" inp1.Dependees.Length + printfn "inp2.Dependees.Length = %d" inp2.Dependees.Length + printfn "total recalcs %s = %d" msg recalcs + printfn "total nodes %s = %d" msg nodes + printfn "----" + +test "using and!" test1 +test "using let!" test2 + +//inp1.Dependees.Length = 1 +//inp2.Dependees.Length = 1 +//total recalcs using and! = 2000 +//total nodes using and! = 1 +//---- +//inp1.Dependees.Length = 1 +//inp2.Dependees.Length = 2000 +//total recalcs using let! = 6000 +//total nodes using let! = 4003 \ No newline at end of file diff --git a/tests/fsharp/readme.md b/tests/fsharp/readme.md index c12bf5a5e44..42960c28c31 100644 --- a/tests/fsharp/readme.md +++ b/tests/fsharp/readme.md @@ -2,7 +2,7 @@ ## Layout -The tests are NUNIT test cases.. They test a very wide range of compiler, interactive and FSharp.Core scenarios. +The tests are NUNIT test cases. They test a very wide range of compiler, interactive and FSharp.Core scenarios. The bulk of the test cases are enumerated in tests.fs, these are the old cambridge test suite. They build on a test-suite ported from windows batch files. They run the compiler and fsi as seperate processes, when built for the coreclr it runs the coreclr versions using dotnet.exe @@ -16,7 +16,7 @@ test cases look similar to: This test case builds and runs the test case in the folder core/array this #define is used to exclude from the build tests that run will not run correctly on the coreclr -__#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS__ +__#if !NETCOREAPP__ There are some older tests in this section that looks similar to: ```` @@ -49,7 +49,7 @@ let changeX() = x = 20 y = "test" """ - FSharpErrorSeverity.Warning + FSharpDiagnosticSeverity.Warning 20 (6, 5, 6, 11) "The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'." @@ -60,8 +60,6 @@ let changeX() = When a test is run, .err/.vserr output files are created and compared to their matching .bsl files. -When many tests fail due to a change being worked on, the [update.base.line.with.actuals.fsx](update.base.line.with.actuals.fsx) script helps updating the .bsl against the actuals. - -After editing the folder list, evaluating the script should replace the .bsl files with actual .err/.vserr, after which the same test is supposed to pass. +Refer to [Test Guide](../../TESTGUIDE.md#baselines) to know more about how to update them. Tests are organized under modules as functions bearing NUnit `[]` attribute and can be run from an IDE or the command line (see the [Test Guide](../../TESTGUIDE.md)). diff --git a/tests/fsharp/regression/5531/compilation.output.test.bsl b/tests/fsharp/regression/5531/compilation.output.test.bsl index 4154944d97d..24c26167e3a 100644 --- a/tests/fsharp/regression/5531/compilation.output.test.bsl +++ b/tests/fsharp/regression/5531/compilation.output.test.bsl @@ -1,2 +1,2 @@ -test.fs(7,17): warning FS0864: This new member hides the abstract member 'abstract member Base.Foo : unit -> unit'. Rename the member or use 'override' instead. \ No newline at end of file +test.fs(7,17): warning FS0864: This new member hides the abstract member 'abstract Base.Foo: unit -> unit'. Rename the member or use 'override' instead. diff --git a/tests/fsharp/regression/5531/compilation.output.test.txt b/tests/fsharp/regression/5531/compilation.output.test.txt deleted file mode 100644 index 7c43a910eee..00000000000 --- a/tests/fsharp/regression/5531/compilation.output.test.txt +++ /dev/null @@ -1,2 +0,0 @@ - -test.fs(7,17): warning FS0864: This new member hides the abstract member 'abstract member Base.Foo : unit -> unit'. Rename the member or use 'override' instead. diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs index 236ef364371..68cb5c0f3d6 100644 --- a/tests/fsharp/single-test.fs +++ b/tests/fsharp/single-test.fs @@ -2,16 +2,17 @@ open System open System.IO -open System.Diagnostics -open NUnit.Framework +open System.Reflection open TestFramework open HandleExpects +open FSharp.Compiler.IO -type Permutation = +type Permutation = | FSC_CORECLR + | FSC_CORECLR_OPT_MINUS | FSC_CORECLR_BUILDONLY | FSI_CORECLR -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP | FSI_FILE | FSI_STDIN | GENERATED_SIGNATURE @@ -94,7 +95,7 @@ let generateOverrides = // Arguments: // pc = ProjectConfiguration // outputType = OutputType.Exe, OutputType.Library or OutputType.Script -// targetFramework optimize = "net472" OR NETCOREAPP3.0 etc ... +// targetFramework optimize = "net472" or net5.0 etc ... // optimize = true or false // configuration = "Release" or "Debug" // @@ -105,12 +106,7 @@ let generateProjectArtifacts (pc:ProjectConfiguration) outputType (targetFramewo "fsi" else "FSharp.Core" - let targetCore = - if targetFramework.StartsWith("netstandard", StringComparison.InvariantCultureIgnoreCase) || targetFramework.StartsWith("netcoreapp", StringComparison.InvariantCultureIgnoreCase) then - "netstandard2.0" - else - "net45" - (Path.GetFullPath(__SOURCE_DIRECTORY__) + "/../../artifacts/bin/" + compiler + "/" + configuration + "/" + targetCore + "/FSharp.Core.dll") + (Path.GetFullPath(__SOURCE_DIRECTORY__) + "/../../artifacts/bin/" + compiler + "/" + configuration + "/netstandard2.0/FSharp.Core.dll") let computeSourceItems addDirectory addCondition (compileItem:CompileItem) sources = let computeInclude src = @@ -155,6 +151,7 @@ let generateProjectArtifacts (pc:ProjectConfiguration) outputType (targetFramewo false $(RestoreFromArtifactsPath) $(RestoreAdditionalProjectSources);$(RestoreFromArtifactsPath) + LatestMajor @@ -214,12 +211,12 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = let extraSources = ["testlib.fsi";"testlib.fs";"test.mli";"test.ml";"test.fsi";"test.fs";"test2.fsi";"test2.fs";"test.fsx";"test2.fsx"] let utilitySources = [__SOURCE_DIRECTORY__ ++ "coreclr_utilities.fs"] let referenceItems = if String.IsNullOrEmpty(copyFiles) then [] else [copyFiles] - let framework = "netcoreapp3.0" + let framework = "net5.0" // Arguments: // outputType = OutputType.Exe, OutputType.Library or OutputType.Script // compilerType = "coreclr" or "net40" - // targetFramework optimize = "net472" OR NETCOREAPP3.0 etc ... + // targetFramework optimize = "net472" OR net5.0 etc ... // optimize = true or false let executeSingleTestBuildAndRun outputType compilerType targetFramework optimize buildOnly = let mutable result = false @@ -227,12 +224,15 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = let mutable result = "" lock lockObj <| (fun () -> let rec loop () = - let dir = Path.Combine(Path.GetTempPath(), "FSharp.Cambridge", Path.GetRandomFileName()) - if Directory.Exists(dir) then + let pathToArtifacts = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "../../../..")) + if Path.GetFileName(pathToArtifacts) <> "artifacts" then failwith "FSharp.Cambridge did not find artifacts directory --- has the location changed????" + let pathToTemp = Path.Combine(pathToArtifacts, "Temp") + let projectDirectory = Path.Combine(pathToTemp, "FSharp.Cambridge", Path.GetRandomFileName()) + if Directory.Exists(projectDirectory) then loop () else - Directory.CreateDirectory(dir) |>ignore - dir + Directory.CreateDirectory(projectDirectory) |>ignore + projectDirectory result <- loop()) result @@ -251,13 +251,14 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = let findFirstSourceFile (pc:ProjectConfiguration) = let sources = List.append pc.SourceItems pc.ExtraSourceItems - let found = sources |> List.tryFind(fun source -> File.Exists(Path.Combine(directory, source))) + let found = sources |> List.tryFind(fun source -> FileSystem.FileExistsShim(Path.Combine(directory, source))) match found with | Some p -> Path.Combine(directory, p) | None -> failwith "Missing SourceFile in test case" let targetsBody = generateTargets let overridesBody = generateOverrides + let targetsFileName = Path.Combine(directory, "Directory.Build.targets") let propsFileName = Path.Combine(directory, "Directory.Build.props") let overridesFileName = Path.Combine(directory, "Directory.Overrides.targets") @@ -280,7 +281,7 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = let cfg = { cfg with Directory = directory } let result = execBothToOutNoCheck cfg directory buildOutputFile cfg.DotNetExe (sprintf "run -f %s" targetFramework) if not (buildOnly) then - result |> checkResult + result |> checkResult testOkFile.CheckExists() executeFsc compilerType targetFramework if buildOnly then verifyResults (findFirstSourceFile pc) buildOutputFile @@ -305,18 +306,19 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = printfn "Filename: %s" projectFileName match p with - | FSC_CORECLR -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "netcoreapp3.0" true false - | FSC_CORECLR_BUILDONLY -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "netcoreapp3.0" true true - | FSI_CORECLR -> executeSingleTestBuildAndRun OutputType.Script "coreclr" "netcoreapp3.0" true false + | FSC_CORECLR -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true false + | FSC_CORECLR_OPT_MINUS -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" false false + | FSC_CORECLR_BUILDONLY -> executeSingleTestBuildAndRun OutputType.Exe "coreclr" "net5.0" true true + | FSI_CORECLR -> executeSingleTestBuildAndRun OutputType.Script "coreclr" "net5.0" true false -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP | FSC_BUILDONLY -> executeSingleTestBuildAndRun OutputType.Exe "net40" "net472" false true | FSC_OPT_PLUS_DEBUG -> executeSingleTestBuildAndRun OutputType.Exe "net40" "net472" true false | FSC_OPT_MINUS_DEBUG -> executeSingleTestBuildAndRun OutputType.Exe "net40" "net472" false false | FSI_FILE -> executeSingleTestBuildAndRun OutputType.Script "net40" "net472" true false - | FSI_STDIN -> - use cleanup = (cleanUpFSharpCore cfg) + | FSI_STDIN -> + use _cleanup = (cleanUpFSharpCore cfg) use testOkFile = new FileGuard (getfullpath cfg "test.ok") let sources = extraSources |> List.filter (fileExists cfg) @@ -324,34 +326,32 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = testOkFile.CheckExists() - | GENERATED_SIGNATURE -> - use cleanup = (cleanUpFSharpCore cfg) + | GENERATED_SIGNATURE -> + use _cleanup = (cleanUpFSharpCore cfg) - let source1 = - ["test.ml"; "test.fs"; "test.fsx"] + let source1 = + ["test.ml"; "test.fs"; "test.fsx"] |> List.rev |> List.tryFind (fileExists cfg) source1 |> Option.iter (fun from -> copy_y cfg from "tmptest.fs") log "Generated signature file..." - fsc cfg "%s --sig:tmptest.fsi" cfg.fsc_flags ["tmptest.fs"] - (if File.Exists("FSharp.Core.dll") then log "found fsharp.core.dll after build" else log "found fsharp.core.dll after build") |> ignore + fsc cfg "%s --sig:tmptest.fsi --define:GENERATED_SIGNATURE" cfg.fsc_flags ["tmptest.fs"] log "Compiling against generated signature file..." fsc cfg "%s -o:tmptest1.exe" cfg.fsc_flags ["tmptest.fsi";"tmptest.fs"] - (if File.Exists("FSharp.Core.dll") then log "found fsharp.core.dll after build" else log "found fsharp.core.dll after build") |> ignore log "Verifying built .exe..." peverify cfg "tmptest1.exe" - | AS_DLL -> + | AS_DLL -> // Compile as a DLL to exercise pickling of interface data, then recompile the original source file referencing this DLL // THe second compilation will not utilize the information from the first in any meaningful way, but the // compiler will unpickle the interface and optimization data, so we test unpickling as well. - use cleanup = (cleanUpFSharpCore cfg) + use _cleanup = (cleanUpFSharpCore cfg) use testOkFile = new FileGuard (getfullpath cfg "test.ok") - + let sources = extraSources |> List.filter (fileExists cfg) fsc cfg "%s --optimize -a -o:test--optimize-lib.dll -g --langversion:preview " cfg.fsc_flags sources @@ -365,18 +365,20 @@ let singleTestBuildAndRunCore cfg copyFiles p languageVersion = testOkFile.CheckExists() #endif -let singleTestBuildAndRunAux cfg p = +let singleTestBuildAndRunAux cfg p = singleTestBuildAndRunCore cfg "" p "latest" -let singleTestBuildAndRunWithCopyDlls cfg copyFiles p = + +let singleTestBuildAndRunWithCopyDlls cfg copyFiles p = singleTestBuildAndRunCore cfg copyFiles p "latest" -let singleTestBuildAndRun dir p = +let singleTestBuildAndRun dir p = let cfg = testConfig dir singleTestBuildAndRunAux cfg p let singleTestBuildAndRunVersion dir p version = let cfg = testConfig dir + singleTestBuildAndRunCore cfg "" p version let singleVersionedNegTest (cfg: TestConfig) version testname = @@ -388,29 +390,29 @@ let singleVersionedNegTest (cfg: TestConfig) version testname = } // REM == Set baseline (fsc vs vs, in case the vs baseline exists) - let VSBSLFILE = + let VSBSLFILE = if (sprintf "%s.vsbsl" testname) |> (fileExists cfg) then sprintf "%s.vsbsl" testname else sprintf "%s.bsl" testname let sources = [ let src = [ testname + ".mli"; testname + ".fsi"; testname + ".ml"; testname + ".fs"; testname + ".fsx"; - testname + "a.mli"; testname + "a.fsi"; testname + "a.ml"; testname + "a.fs"; + testname + "a.mli"; testname + "a.fsi"; testname + "a.ml"; testname + "a.fs"; testname + "b.mli"; testname + "b.fsi"; testname + "b.ml"; testname + "b.fs"; ] yield! src |> List.filter (fileExists cfg) - if fileExists cfg "helloWorldProvider.dll" then + if fileExists cfg "helloWorldProvider.dll" then yield "-r:helloWorldProvider.dll" - if fileExists cfg (testname + "-pre.fs") then + if fileExists cfg (testname + "-pre.fs") then yield (sprintf "-r:%s-pre.dll" testname) ] if fileExists cfg (testname + "-pre.fs") then - fsc cfg "%s -a -o:%s-pre.dll" cfg.fsc_flags testname [testname + "-pre.fs"] + fsc cfg "%s -a -o:%s-pre.dll" cfg.fsc_flags testname [testname + "-pre.fs"] else () if fileExists cfg (testname + "-pre.fsx") then @@ -435,19 +437,21 @@ let singleVersionedNegTest (cfg: TestConfig) version testname = let vbslDiff = fsdiff cfg (sprintf "%s.vserr" testname) VSBSLFILE match diff,vbslDiff with - | "","" -> + | "","" -> log "Good, output %s.err matched %s.bsl" testname testname log "Good, output %s.vserr matched %s" testname VSBSLFILE - | l,"" -> - log "***** %s.err %s.bsl differed: a bug or baseline may need updating" testname testname + | l,"" -> + log "***** %s.err %s.bsl differed: a bug or baseline may need updating" testname testname failwithf "%s.err %s.bsl differ; %A" testname testname l | "",l -> log "Good, output %s.err matched %s.bsl" testname testname log "***** %s.vserr %s differed: a bug or baseline may need updating" testname VSBSLFILE failwithf "%s.vserr %s differ; %A" testname VSBSLFILE l - | l1,l2 -> - log "***** %s.err %s.bsl differed: a bug or baseline may need updating" testname testname + | l1,l2 -> + log "***** %s.err %s.bsl differed: a bug or baseline may need updating" testname testname log "***** %s.vserr %s differed: a bug or baseline may need updating" testname VSBSLFILE failwithf "%s.err %s.bsl differ; %A; %s.vserr %s differ; %A" testname testname l1 testname VSBSLFILE l2 -let singleNegTest (cfg: TestConfig) testname = singleVersionedNegTest (cfg: TestConfig) "" testname + +let singleNegTest (cfg: TestConfig) testname = + singleVersionedNegTest (cfg: TestConfig) "" testname diff --git a/tests/fsharp/test-framework.fs b/tests/fsharp/test-framework.fs deleted file mode 100644 index d63bda88416..00000000000 --- a/tests/fsharp/test-framework.fs +++ /dev/null @@ -1,534 +0,0 @@ -module TestFramework - -open Microsoft.Win32 -open System -open System.IO -open System.Text.RegularExpressions -open Scripting -open NUnit.Framework - - -[] -module Commands = - - let getfullpath workDir (path:string) = - let rooted = - if Path.IsPathRooted(path) then path - else Path.Combine(workDir, path) - rooted |> Path.GetFullPath - - let fileExists workDir path = - if path |> getfullpath workDir |> File.Exists then Some path else None - - let directoryExists workDir path = - if path |> getfullpath workDir |> Directory.Exists then Some path else None - - let copy_y workDir source dest = - log "copy /y %s %s" source dest - File.Copy( source |> getfullpath workDir, dest |> getfullpath workDir, true) - CmdResult.Success - - let mkdir_p workDir dir = - log "mkdir %s" dir - Directory.CreateDirectory ( Path.Combine(workDir, dir) ) |> ignore - - let rm dir path = - let p = path |> getfullpath dir - if File.Exists(p) then - (log "rm %s" p) |> ignore - File.Delete(p) - else - (log "not found: %s p") |> ignore - - let rmdir dir path = - let p = path |> getfullpath dir - if Directory.Exists(p) then - (log "rmdir /sy %s" p) |> ignore - Directory.Delete(p, true) - else - (log "not found: %s p") |> ignore - - let pathAddBackslash (p: FilePath) = - if String.IsNullOrWhiteSpace (p) then p - else - p.TrimEnd ([| Path.DirectorySeparatorChar; Path.AltDirectorySeparatorChar |]) - + Path.DirectorySeparatorChar.ToString() - - let echoAppendToFile workDir text p = - log "echo %s> %s" text p - let dest = p |> getfullpath workDir in File.AppendAllText(dest, text + Environment.NewLine) - - let appendToFile workDir source p = - log "type %s >> %s" source p - let from = source |> getfullpath workDir - let dest = p |> getfullpath workDir - let contents = File.ReadAllText(from) - File.AppendAllText(dest, contents) - - let fsc workDir exec (dotNetExe: FilePath) (fscExe: FilePath) flags srcFiles = - let args = (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) - -#if FSC_IN_PROCESS - // This is not yet complete - printfn "Hosted Compiler:" - printfn "workdir: %A\nargs: %A"workdir args - let fscCompiler = FSharp.Compiler.Hosted.FscCompiler() - let exitCode, _stdin, _stdout = FSharp.Compiler.Hosted.CompilerHelpers.fscCompile workDir (FSharp.Compiler.Hosted.CompilerHelpers.parseCommandLine args) - - match exitCode with - | 0 -> CmdResult.Success - | err -> - let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'" fscExe args workDir - CmdResult.ErrorLevel (msg, err) -#else - ignore workDir -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - ignore dotNetExe - printfn "fscExe: %A" fscExe - printfn "args: %A" args - exec fscExe args -#else - exec dotNetExe (fscExe + " " + args) -#endif -#endif - - let csc exec cscExe flags srcFiles = - exec cscExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) - - let fsi exec fsiExe flags sources = - exec fsiExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " ")) - - let internal quotepath (p: FilePath) = - let quote = '"'.ToString() - if p.Contains(" ") then (sprintf "%s%s%s" quote p quote) else p - - let ildasm exec ildasmExe flags assembly = - exec ildasmExe (sprintf "%s %s" flags (quotepath assembly)) - - let ilasm exec ilasmExe flags assembly = - exec ilasmExe (sprintf "%s %s" flags (quotepath assembly)) - - let peverify exec peverifyExe flags path = - exec peverifyExe (sprintf "%s %s" (quotepath path) flags) - - let createTempDir () = - let path = Path.GetTempFileName () - File.Delete path - Directory.CreateDirectory path |> ignore - path - - -type TestConfig = - { EnvironmentVariables : Map - CSC : string - csc_flags : string - BUILD_CONFIG : string - FSC : string - fsc_flags : string - FSCOREDLLPATH : string - FSI : string -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - FSIANYCPU : string -#endif - FSI_FOR_SCRIPTS : string - FSharpBuild : string - FSharpCompilerInteractiveSettings : string - fsi_flags : string - ILDASM : string - ILASM : string - PEVERIFY : string - Directory: string - DotNetExe: string - DefaultPlatform: string} - - -module WindowsPlatform = - let Is64BitOperatingSystem envVars = - // On Windows PROCESSOR_ARCHITECTURE has the value AMD64 on 64 bit Intel Machines - let value = - let find s = envVars |> Map.tryFind s - [| "PROCESSOR_ARCHITECTURE" |] |> Seq.tryPick (fun s -> find s) |> function None -> "" | Some x -> x - value = "AMD64" - -type FSLibPaths = - { FSCOREDLLPATH : string } - -let requireFile nm = - if Commands.fileExists __SOURCE_DIRECTORY__ nm |> Option.isSome then nm else failwith (sprintf "couldn't find %s. Running 'build test' once might solve this issue" nm) - -let packagesDir = Environment.GetEnvironmentVariable("USERPROFILE") ++ ".nuget" ++ "packages" - -let config configurationName envVars = - - let SCRIPT_ROOT = __SOURCE_DIRECTORY__ -#if NET472 - let fscArchitecture = "net472" - let fsiArchitecture = "net472" - let fsharpCoreArchitecture = "net45" - let fsharpBuildArchitecture = "net472" - let fsharpCompilerInteractiveSettingsArchitecture = "net472" -#else - let fscArchitecture = "netcoreapp3.0" - let fsiArchitecture = "netcoreapp3.0" - let fsharpCoreArchitecture = "netstandard2.0" - let fsharpBuildArchitecture = "netcoreapp3.0" - let fsharpCompilerInteractiveSettingsArchitecture = "netstandard2.0" -#endif - let repoRoot = SCRIPT_ROOT ++ ".." ++ ".." - let artifactsPath = repoRoot ++ "artifacts" - let artifactsBinPath = artifactsPath ++ "bin" - let coreClrRuntimePackageVersion = "3.0.0-preview-27318-01" - let csc_flags = "/nologo" - let fsc_flags = "-r:System.Core.dll --nowarn:20 --define:COMPILED" - let fsi_flags = "-r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror" - let Is64BitOperatingSystem = WindowsPlatform.Is64BitOperatingSystem envVars - let architectureMoniker = if Is64BitOperatingSystem then "x64" else "x86" - let CSC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "csc.exe") - let ILDASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ildasm.exe") - let ILASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ilasm.exe") - let coreclrdll = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.Runtime.CoreCLR") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "coreclr.dll") - let PEVERIFY = requireFile (artifactsBinPath ++ "PEVerify" ++ configurationName ++ "net472" ++ "PEVerify.exe") - let FSI_FOR_SCRIPTS = artifactsBinPath ++ "fsi" ++ configurationName ++ fsiArchitecture ++ "fsi.exe" - let FSharpBuild = requireFile (artifactsBinPath ++ "FSharp.Build" ++ configurationName ++ fsharpBuildArchitecture ++ "FSharp.Build.dll") - let FSharpCompilerInteractiveSettings = requireFile (artifactsBinPath ++ "FSharp.Compiler.Interactive.Settings" ++ configurationName ++ fsharpCompilerInteractiveSettingsArchitecture ++ "FSharp.Compiler.Interactive.Settings.dll") - let dotNetExe = - // first look for {repoRoot}\.dotnet\dotnet.exe, otherwise fallback to %PATH% - let repoLocalDotnetPath = repoRoot ++ ".dotnet" ++ "dotnet.exe" - if File.Exists(repoLocalDotnetPath) then repoLocalDotnetPath - else "dotnet.exe" - // ildasm + ilasm requires coreclr.dll to run which has already been restored to the packages directory - File.Copy(coreclrdll, Path.GetDirectoryName(ILDASM) ++ "coreclr.dll", overwrite=true) - File.Copy(coreclrdll, Path.GetDirectoryName(ILASM) ++ "coreclr.dll", overwrite=true) - - let FSI = requireFile (FSI_FOR_SCRIPTS) -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - let FSIANYCPU = requireFile (artifactsBinPath ++ "fsiAnyCpu" ++ configurationName ++ "net472" ++ "fsiAnyCpu.exe") -#endif - let FSC = requireFile (artifactsBinPath ++ "fsc" ++ configurationName ++ fscArchitecture ++ "fsc.exe") - let FSCOREDLLPATH = requireFile (artifactsBinPath ++ "FSharp.Core" ++ configurationName ++ fsharpCoreArchitecture ++ "FSharp.Core.dll") - - let defaultPlatform = - match Is64BitOperatingSystem with -// | PlatformID.MacOSX, true -> "osx.10.10-x64" -// | PlatformID.Unix,true -> "ubuntu.14.04-x64" - | true -> "win7-x64" - | false -> "win7-x86" - - { EnvironmentVariables = envVars - FSCOREDLLPATH = FSCOREDLLPATH - ILDASM = ILDASM - ILASM = ILASM - PEVERIFY = PEVERIFY - CSC = CSC - BUILD_CONFIG = configurationName - FSC = FSC - FSI = FSI -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - FSIANYCPU = FSIANYCPU -#endif - FSI_FOR_SCRIPTS = FSI_FOR_SCRIPTS - FSharpBuild = FSharpBuild - FSharpCompilerInteractiveSettings = FSharpCompilerInteractiveSettings - csc_flags = csc_flags - fsc_flags = fsc_flags - fsi_flags = fsi_flags - Directory="" - DotNetExe = dotNetExe - DefaultPlatform = defaultPlatform } - -let logConfig (cfg: TestConfig) = - log "---------------------------------------------------------------" - log "Executables" - log "" - log "CSC =%s" cfg.CSC - log "BUILD_CONFIG =%s" cfg.BUILD_CONFIG - log "csc_flags =%s" cfg.csc_flags - log "FSC =%s" cfg.FSC - log "fsc_flags =%s" cfg.fsc_flags - log "FSCOREDLLPATH =%s" cfg.FSCOREDLLPATH - log "FSI =%s" cfg.FSI -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS - log "FSIANYCPU =%s" cfg.FSIANYCPU -#endif - log "fsi_flags =%s" cfg.fsi_flags - log "ILDASM =%s" cfg.ILDASM - log "PEVERIFY =%s" cfg.PEVERIFY - log "---------------------------------------------------------------" - - -let checkResult result = - match result with - | CmdResult.ErrorLevel (msg1, err) -> Assert.Fail (sprintf "%s. ERRORLEVEL %d" msg1 err) - | CmdResult.Success -> () - -let checkErrorLevel1 result = - match result with - | CmdResult.ErrorLevel (_,1) -> () - | CmdResult.Success | CmdResult.ErrorLevel _ -> Assert.Fail (sprintf "Command passed unexpectedly") - -let envVars () = - System.Environment.GetEnvironmentVariables () - |> Seq.cast - |> Seq.map (fun d -> d.Key :?> string, d.Value :?> string) - |> Map.ofSeq - -let initializeSuite () = - -#if DEBUG - let configurationName = "debug" -#else - let configurationName = "release" -#endif - let env = envVars () - - let cfg = - let c = config configurationName env - let usedEnvVars = c.EnvironmentVariables |> Map.add "FSC" c.FSC - { c with EnvironmentVariables = usedEnvVars } - - logConfig cfg - - cfg - - -let suiteHelpers = lazy (initializeSuite ()) - -[] -type public InitializeSuiteAttribute () = - inherit TestActionAttribute() - - override x.BeforeTest details = - try - if details.IsSuite - then suiteHelpers.Force() |> ignore - with - | e -> raise (Exception("failed test suite initialization, debug code in InitializeSuiteAttribute", e)) - override x.AfterTest _details = - () - - override x.Targets = ActionTargets.Test ||| ActionTargets.Suite - - -[] -[] -() - -let fsharpSuiteDirectory = __SOURCE_DIRECTORY__ - -let testConfig testDir = - let cfg = suiteHelpers.Value - let dir = Path.GetFullPath(fsharpSuiteDirectory ++ testDir) - log "------------------ %s ---------------" dir - log "cd %s" dir - { cfg with Directory = dir} - -[] -type FileGuard(path: string) = - let remove path = if File.Exists(path) then Commands.rm (Path.GetTempPath()) path - do if not (Path.IsPathRooted(path)) then failwithf "path '%s' must be absolute" path - do remove path - member x.Path = path - member x.Exists = x.Path |> File.Exists - member x.CheckExists() = - if not x.Exists then - failwith (sprintf "exit code 0 but %s file doesn't exists" (x.Path |> Path.GetFileName)) - - interface IDisposable with - member x.Dispose () = remove path - - -type RedirectToType = - | Overwrite of FilePath - | Append of FilePath - -type RedirectTo = - | Inherit - | Output of RedirectToType - | OutputAndError of RedirectToType * RedirectToType - | OutputAndErrorToSameFile of RedirectToType - | Error of RedirectToType - -type RedirectFrom = - | RedirectInput of FilePath - -type RedirectInfo = - { Output : RedirectTo - Input : RedirectFrom option } - - -module Command = - - let logExec _dir path args redirect = - let inF = - function - | None -> "" - | Some(RedirectInput l) -> sprintf " <%s" l - let redirectType = function Overwrite x -> sprintf ">%s" x | Append x -> sprintf ">>%s" x - let outF = - function - | Inherit -> "" - | Output r-> sprintf " 1%s" (redirectType r) - | OutputAndError (r1, r2) -> sprintf " 1%s 2%s" (redirectType r1) (redirectType r2) - | OutputAndErrorToSameFile r -> sprintf " 1%s 2>1" (redirectType r) - | Error r -> sprintf " 2%s" (redirectType r) - sprintf "%s%s%s%s" path (match args with "" -> "" | x -> " " + x) (inF redirect.Input) (outF redirect.Output) - - let exec dir envVars (redirect:RedirectInfo) path args = - - let inputWriter sources (writer: StreamWriter) = - let pipeFile name = async { - let path = Commands.getfullpath dir name - use reader = File.OpenRead (path) - use ms = new MemoryStream() - do! reader.CopyToAsync (ms) |> (Async.AwaitIAsyncResult >> Async.Ignore) - ms.Position <- 0L - try - do! ms.CopyToAsync(writer.BaseStream) |> (Async.AwaitIAsyncResult >> Async.Ignore) - do! writer.FlushAsync() |> (Async.AwaitIAsyncResult >> Async.Ignore) - with - | :? System.IO.IOException -> //input closed is ok if process is closed - () - } - sources |> pipeFile |> Async.RunSynchronously - - let inF fCont cmdArgs = - match redirect.Input with - | None -> fCont cmdArgs - | Some(RedirectInput l) -> fCont { cmdArgs with RedirectInput = Some (inputWriter l) } - - let openWrite rt = - let fullpath = Commands.getfullpath dir - match rt with - | Append p -> File.AppendText( p |> fullpath) - | Overwrite p -> new StreamWriter(new FileStream(p |> fullpath, FileMode.Create)) - - let outF fCont cmdArgs = - match redirect.Output with - | RedirectTo.Inherit -> - use toLog = redirectToLog () - fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (toLog.Post) } - | Output r -> - use writer = openWrite r - use outFile = redirectTo writer - use toLog = redirectToLog () - fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (toLog.Post) } - | OutputAndError (r1,r2) -> - use writer1 = openWrite r1 - use writer2 = openWrite r2 - use outFile1 = redirectTo writer1 - use outFile2 = redirectTo writer2 - fCont { cmdArgs with RedirectOutput = Some (outFile1.Post); RedirectError = Some (outFile2.Post) } - | OutputAndErrorToSameFile r -> - use writer = openWrite r - use outFile = redirectTo writer - fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (outFile.Post) } - | Error r -> - use writer = openWrite r - use outFile = redirectTo writer - use toLog = redirectToLog () - fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (outFile.Post) } - - let exec cmdArgs = - log "%s" (logExec dir path args redirect) - Process.exec cmdArgs dir envVars path args - - { RedirectOutput = None; RedirectError = None; RedirectInput = None } - |> (outF (inF exec)) - -let alwaysSuccess _ = () - -let execArgs = { Output = Inherit; Input = None; } -let execAppend cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> checkResult -let execAppendIgnoreExitCode cfg stdoutPath stderrPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = OutputAndError(Append(stdoutPath), Append(stderrPath)) } p >> alwaysSuccess -let exec cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkResult -let execExpectFail cfg p = Command.exec cfg.Directory cfg.EnvironmentVariables execArgs p >> checkErrorLevel1 -let execIn cfg workDir p = Command.exec workDir cfg.EnvironmentVariables execArgs p >> checkResult -let execBothToOutNoCheck cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = OutputAndErrorToSameFile(Overwrite(outFile)) } p -let execBothToOut cfg workDir outFile p = execBothToOutNoCheck cfg workDir outFile p >> checkResult -let execAppendOutIgnoreExitCode cfg workDir outFile p = Command.exec workDir cfg.EnvironmentVariables { execArgs with Output = Output(Append(outFile)) } p >> alwaysSuccess -let execAppendErrExpectFail cfg errPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { execArgs with Output = Error(Overwrite(errPath)) } p >> checkErrorLevel1 -let execStdin cfg l p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult -let execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath p = Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Append(stdoutPath), Append(stderrPath)); Input = Some(RedirectInput(stdinPath)) } p >> alwaysSuccess -let fsc cfg arg = Printf.ksprintf (Commands.fsc cfg.Directory (exec cfg) cfg.DotNetExe cfg.FSC) arg -let fscIn cfg workDir arg = Printf.ksprintf (Commands.fsc workDir (execIn cfg workDir) cfg.DotNetExe cfg.FSC) arg -let fscAppend cfg stdoutPath stderrPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppend cfg stdoutPath stderrPath) cfg.DotNetExe cfg.FSC) arg -let fscAppendIgnoreExitCode cfg stdoutPath stderrPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.DotNetExe cfg.FSC) arg -let fscBothToOut cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (execBothToOut cfg cfg.Directory out) cfg.DotNetExe cfg.FSC) arg -let fscAppendErrExpectFail cfg errPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendErrExpectFail cfg errPath) cfg.DotNetExe cfg.FSC) arg -let csc cfg arg = Printf.ksprintf (Commands.csc (exec cfg) cfg.CSC) arg -let ildasm cfg arg = Printf.ksprintf (Commands.ildasm (exec cfg) cfg.ILDASM) arg -let ilasm cfg arg = Printf.ksprintf (Commands.ilasm (exec cfg) cfg.ILASM) arg -let peverify cfg = Commands.peverify (exec cfg) cfg.PEVERIFY "/nologo" -let peverifyWithArgs cfg args = Commands.peverify (exec cfg) cfg.PEVERIFY args -let fsi cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI) -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS -let fsiAnyCpu cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSIANYCPU) -#endif -let fsi_script cfg = Printf.ksprintf (Commands.fsi (exec cfg) cfg.FSI_FOR_SCRIPTS) -let fsiExpectFail cfg = Printf.ksprintf (Commands.fsi (execExpectFail cfg) cfg.FSI) -let fsiAppendIgnoreExitCode cfg stdoutPath stderrPath = Printf.ksprintf (Commands.fsi (execAppendIgnoreExitCode cfg stdoutPath stderrPath) cfg.FSI) -let fileguard cfg = (Commands.getfullpath cfg.Directory) >> (fun x -> new FileGuard(x)) -let getfullpath cfg = Commands.getfullpath cfg.Directory -let fileExists cfg = Commands.fileExists cfg.Directory >> Option.isSome -let fsiStdin cfg stdinPath = Printf.ksprintf (Commands.fsi (execStdin cfg stdinPath) cfg.FSI) -let fsiStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath = Printf.ksprintf (Commands.fsi (execStdinAppendBothIgnoreExitCode cfg stdoutPath stderrPath stdinPath) cfg.FSI) -let rm cfg x = Commands.rm cfg.Directory x -let rmdir cfg x = Commands.rmdir cfg.Directory x -let mkdir cfg = Commands.mkdir_p cfg.Directory -let copy_y cfg f = Commands.copy_y cfg.Directory f >> checkResult -let copySystemValueTuple cfg = copy_y cfg (getDirectoryName(cfg.FSC) ++ "System.ValueTuple.dll") ("." ++ "System.ValueTuple.dll") - -let diff normalize path1 path2 = - let result = System.Text.StringBuilder() - let append s = result.AppendLine s |> ignore - let cwd = Directory.GetCurrentDirectory() - - if not <| File.Exists(path1) then failwithf "Invalid path %s" path1 - if not <| File.Exists(path2) then failwithf "Invalid path %s" path2 - - let lines1 = File.ReadAllLines(path1) - let lines2 = File.ReadAllLines(path2) - - let minLines = min lines1.Length lines2.Length - - for i = 0 to (minLines - 1) do - let normalizePath (line:string) = - if normalize then - let x = line.IndexOf(cwd, StringComparison.OrdinalIgnoreCase) - if x >= 0 then line.Substring(x+cwd.Length) else line - else line - - let line1 = normalizePath lines1.[i] - let line2 = normalizePath lines2.[i] - - if line1 <> line2 then - append <| sprintf "diff between [%s] and [%s]" path1 path2 - append <| sprintf "line %d" (i+1) - append <| sprintf " - %s" line1 - append <| sprintf " + %s" line2 - - if lines1.Length <> lines2.Length then - append <| sprintf "diff between [%s] and [%s]" path1 path2 - append <| sprintf "diff at line %d" minLines - lines1.[minLines .. (lines1.Length - 1)] |> Array.iter (append << sprintf "- %s") - lines2.[minLines .. (lines2.Length - 1)] |> Array.iter (append << sprintf "+ %s") - - result.ToString() - -let fsdiff cfg a b = - let actualFile = System.IO.Path.Combine(cfg.Directory, a) - let expectedFile = System.IO.Path.Combine(cfg.Directory, b) - let errorText = System.IO.File.ReadAllText (System.IO.Path.Combine(cfg.Directory, a)) - - let result = diff false expectedFile actualFile - if result <> "" then - log "%s" result - log "New error file:" - log "%s" errorText - - result - -let requireENCulture () = - match System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName with - | "en" -> true - | _ -> false diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 2247c318f6a..f5ff5ca719c 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -1,11 +1,11 @@ // To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test #if INTERACTIVE #r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll" -#load "../../src/scripts/scriptlib.fsx" -#load "test-framework.fs" +#load "../../src/scripts/scriptlib.fsx" +#load "../FSharp.Test.Utilities/TestFramework.fs" #load "single-test.fs" #else -module ``FSharp-Tests-Core`` +module FSharp.Tests.Core #endif open System @@ -17,26 +17,41 @@ open TestFramework open Scripting open SingleTest open HandleExpects +open FSharp.Test -#if FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if NETCOREAPP // Use these lines if you want to test CoreCLR let FSC_BASIC = FSC_CORECLR +let FSC_BASIC_OPT_MINUS = FSC_CORECLR_OPT_MINUS let FSC_BUILDONLY = FSC_CORECLR_BUILDONLY let FSI_BASIC = FSI_CORECLR #else let FSC_BASIC = FSC_OPT_PLUS_DEBUG +let FSC_BASIC_OPT_MINUS = FSC_OPT_MINUS_DEBUG let FSI_BASIC = FSI_FILE #endif // ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^ +let inline getTestsDirectory dir = getTestsDirectory __SOURCE_DIRECTORY__ dir +let singleTestBuildAndRun = getTestsDirectory >> singleTestBuildAndRun +let singleTestBuildAndRunVersion = getTestsDirectory >> singleTestBuildAndRunVersion +let testConfig = getTestsDirectory >> testConfig + +[] module CoreTests = // These tests are enabled for .NET Framework and .NET Core + [] + let ``access-FSC_BASIC_OPT_MINUS``() = singleTestBuildAndRun "core/access" FSC_BASIC_OPT_MINUS + [] let ``access-FSC_BASIC``() = singleTestBuildAndRun "core/access" FSC_BASIC [] let ``access-FSI_BASIC``() = singleTestBuildAndRun "core/access" FSI_BASIC + [] + let ``apporder-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC_OPT_MINUS + [] let ``apporder-FSC_BASIC`` () = singleTestBuildAndRun "core/apporder" FSC_BASIC @@ -44,10 +59,73 @@ module CoreTests = let ``apporder-FSI_BASIC`` () = singleTestBuildAndRun "core/apporder" FSI_BASIC [] - let ``array-FSC_BASIC`` () = singleTestBuildAndRun "core/array" FSC_BASIC + let ``array-FSC_BASIC_OPT_MINUS-5.0`` () = singleTestBuildAndRunVersion "core/array" FSC_BASIC_OPT_MINUS "5.0" + + [] + let ``array-FSC_BASIC-5.0`` () = singleTestBuildAndRunVersion "core/array" FSC_BASIC "5.0" + + [] + let ``array-FSI_BASIC-5.0`` () = singleTestBuildAndRunVersion "core/array" FSI_BASIC "5.0" + + [] + let ``array-FSC_BASIC-preview`` () = singleTestBuildAndRunVersion "core/array" FSC_BASIC "preview" + + [] + let ``array-no-dot-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRunVersion "core/array-no-dot" FSC_BASIC_OPT_MINUS "preview" + + [] + let ``array-no-dot-FSC_BASIC`` () = singleTestBuildAndRunVersion "core/array-no-dot" FSC_BASIC "preview" + + [] + let ``array-no-dot-FSI_BASIC`` () = singleTestBuildAndRunVersion "core/array-no-dot" FSI_BASIC "preview" + + [] + let ``array-no-dot-warnings-langversion-default`` () = + let cfg = testConfig "core/array-no-dot-warnings" + singleVersionedNegTest cfg "default" "test-langversion-default" + + [] + let ``array-no-dot-warnings-langversion-5_0`` () = + let cfg = testConfig "core/array-no-dot-warnings" + singleVersionedNegTest cfg "5.0" "test-langversion-5.0" + + [] + let ``array-no-dot-warnings-langversion-preview`` () = + let cfg = testConfig "core/array-no-dot-warnings" + singleVersionedNegTest cfg "preview" "test-langversion-preview" + + [] + let ``ref-ops-deprecation-langversion-preview`` () = + let cfg = testConfig "core/ref-ops-deprecation" + singleVersionedNegTest cfg "preview" "test-langversion-preview" + + [] + let ``auto-widen-version-5_0``() = + let cfg = testConfig "core/auto-widen/5.0" + singleVersionedNegTest cfg "5.0" "test" + + [] + let ``auto-widen-version-FSC_BASIC_OPT_MINUS-preview``() = + singleTestBuildAndRunVersion "core/auto-widen/preview" FSC_BASIC_OPT_MINUS "preview" + + [] + let ``auto-widen-version-FSC_BASIC-preview``() = + singleTestBuildAndRunVersion "core/auto-widen/preview" FSC_BASIC "preview" + + [] + let ``auto-widen-version-preview-warns-on``() = + let cfg = testConfig "core/auto-widen/preview" + let cfg = { cfg with fsc_flags = cfg.fsc_flags + " --warnon:3388 --warnon:3389 --warnon:3390 --warnaserror+ --define:NEGATIVE" } + singleVersionedNegTest cfg "preview" "test" + + [] + let ``auto-widen-version-preview-default-warns``() = + let cfg = testConfig "core/auto-widen/preview-default-warns" + let cfg = { cfg with fsc_flags = cfg.fsc_flags + " --warnaserror+ --define:NEGATIVE" } + singleVersionedNegTest cfg "preview" "test" [] - let ``array-FSI_BASIC`` () = singleTestBuildAndRun "core/array" FSI_BASIC + let ``comprehensions-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC_OPT_MINUS [] let ``comprehensions-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSC_BASIC @@ -55,75 +133,114 @@ module CoreTests = [] let ``comprehensions-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions" FSI_BASIC + [] + let ``comprehensionshw-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC_OPT_MINUS + [] let ``comprehensionshw-FSC_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSC_BASIC [] let ``comprehensionshw-FSI_BASIC`` () = singleTestBuildAndRun "core/comprehensions-hw" FSI_BASIC + [] + let ``genericmeasures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC_OPT_MINUS + [] let ``genericmeasures-FSC_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSC_BASIC [] let ``genericmeasures-FSI_BASIC`` () = singleTestBuildAndRun "core/genericmeasures" FSI_BASIC + [] + let ``innerpoly-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC_OPT_MINUS + [] let ``innerpoly-FSC_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSC_BASIC [] let ``innerpoly-FSI_BASIC`` () = singleTestBuildAndRun "core/innerpoly" FSI_BASIC + [] + let ``namespaceAttributes-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC_OPT_MINUS + [] let ``namespaceAttributes-FSC_BASIC`` () = singleTestBuildAndRun "core/namespaces" FSC_BASIC + [] + let ``unicode2-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC_OPT_MINUS // TODO: fails on coreclr + [] let ``unicode2-FSC_BASIC`` () = singleTestBuildAndRun "core/unicode" FSC_BASIC // TODO: fails on coreclr [] let ``unicode2-FSI_BASIC`` () = singleTestBuildAndRun "core/unicode" FSI_BASIC + [] + let ``lazy test-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC_OPT_MINUS + [] let ``lazy test-FSC_BASIC`` () = singleTestBuildAndRun "core/lazy" FSC_BASIC [] let ``lazy test-FSI_BASIC`` () = singleTestBuildAndRun "core/lazy" FSI_BASIC + [] + let ``letrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC_OPT_MINUS + [] let ``letrec-FSC_BASIC`` () = singleTestBuildAndRun "core/letrec" FSC_BASIC [] let ``letrec-FSI_BASIC`` () = singleTestBuildAndRun "core/letrec" FSI_BASIC + [] + let ``letrec (mutrec variations part one) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC_OPT_MINUS + [] let ``letrec (mutrec variations part one) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSC_BASIC [] let ``letrec (mutrec variations part one) FSI_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec" FSI_BASIC + [] + let ``libtest-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC_OPT_MINUS + [] let ``libtest-FSC_BASIC`` () = singleTestBuildAndRun "core/libtest" FSC_BASIC [] let ``libtest-FSI_BASIC`` () = singleTestBuildAndRun "core/libtest" FSI_BASIC + [] + let ``lift-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/lift" FSC_BASIC_OPT_MINUS + [] let ``lift-FSC_BASIC`` () = singleTestBuildAndRun "core/lift" FSC_BASIC [] let ``lift-FSI_BASIC`` () = singleTestBuildAndRun "core/lift" FSI_BASIC + [] + let ``map-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/map" FSC_BASIC_OPT_MINUS + [] let ``map-FSC_BASIC`` () = singleTestBuildAndRun "core/map" FSC_BASIC [] let ``map-FSI_BASIC`` () = singleTestBuildAndRun "core/map" FSI_BASIC + [] + let ``measures-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/measures" FSC_BASIC_OPT_MINUS + [] let ``measures-FSC_BASIC`` () = singleTestBuildAndRun "core/measures" FSC_BASIC [] let ``measures-FSI_BASIC`` () = singleTestBuildAndRun "core/measures" FSI_BASIC + [] + let ``nested-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/nested" FSC_BASIC_OPT_MINUS + [] let ``nested-FSC_BASIC`` () = singleTestBuildAndRun "core/nested" FSC_BASIC @@ -133,15 +250,24 @@ module CoreTests = [] let ``members-ops-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC + [] + let ``members-ops-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops" FSC_BASIC_OPT_MINUS + [] let ``members-ops-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops" FSI_BASIC + [] + let ``members-ops-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC_OPT_MINUS + [] let ``members-ops-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSC_BASIC [] let ``members-ops-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ops-mutrec" FSI_BASIC + [] + let ``seq-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/seq" FSC_BASIC_OPT_MINUS + [] let ``seq-FSC_BASIC`` () = singleTestBuildAndRun "core/seq" FSC_BASIC @@ -154,36 +280,54 @@ module CoreTests = [] let ``math-numbers-FSI_BASIC`` () = singleTestBuildAndRun "core/math/numbers" FSI_BASIC + [] + let ``members-ctree-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC_OPT_MINUS + [] let ``members-ctree-FSC_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSC_BASIC [] let ``members-ctree-FSI_BASIC`` () = singleTestBuildAndRun "core/members/ctree" FSI_BASIC + [] + let ``members-factors-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC_OPT_MINUS + [] let ``members-factors-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSC_BASIC [] let ``members-factors-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors" FSI_BASIC + [] + let ``members-factors-mutrec-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC_OPT_MINUS + [] let ``members-factors-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSC_BASIC [] let ``members-factors-mutrec-FSI_BASIC`` () = singleTestBuildAndRun "core/members/factors-mutrec" FSI_BASIC + [] + let ``graph-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC_OPT_MINUS + [] let ``graph-FSC_BASIC`` () = singleTestBuildAndRun "perf/graph" FSC_BASIC [] let ``graph-FSI_BASIC`` () = singleTestBuildAndRun "perf/graph" FSI_BASIC + [] + let ``nbody-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC_OPT_MINUS + [] let ``nbody-FSC_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSC_BASIC [] let ``nbody-FSI_BASIC`` () = singleTestBuildAndRun "perf/nbody" FSI_BASIC + [] + let ``letrec (mutrec variations part two) FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC_OPT_MINUS + [] let ``letrec (mutrec variations part two) FSC_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSC_BASIC @@ -191,7 +335,13 @@ module CoreTests = let ``letrec (mutrec variations part two) FSI_BASIC`` () = singleTestBuildAndRun "core/letrec-mutrec2" FSI_BASIC [] - let ``printf-FSC_BASIC`` () = singleTestBuildAndRun "core/printf" FSC_BASIC + let ``printf`` () = singleTestBuildAndRunVersion "core/printf" FSC_BASIC "preview" + + [] + let ``printf-interpolated`` () = singleTestBuildAndRunVersion "core/printf-interpolated" FSC_BASIC "preview" + + [] + let ``tlr-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC_OPT_MINUS [] let ``tlr-FSC_BASIC`` () = singleTestBuildAndRun "core/tlr" FSC_BASIC @@ -199,37 +349,57 @@ module CoreTests = [] let ``tlr-FSI_BASIC`` () = singleTestBuildAndRun "core/tlr" FSI_BASIC + [] + let ``subtype-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC_OPT_MINUS + [] let ``subtype-FSC_BASIC`` () = singleTestBuildAndRun "core/subtype" FSC_BASIC [] let ``subtype-FSI_BASIC`` () = singleTestBuildAndRun "core/subtype" FSI_BASIC + [] + let ``syntax-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC_OPT_MINUS + [] let ``syntax-FSC_BASIC`` () = singleTestBuildAndRun "core/syntax" FSC_BASIC [] let ``syntax-FSI_BASIC`` () = singleTestBuildAndRun "core/syntax" FSI_BASIC + [] + let ``test int32-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/int32" FSC_BASIC_OPT_MINUS + [] let ``test int32-FSC_BASIC`` () = singleTestBuildAndRun "core/int32" FSC_BASIC [] let ``test int32-FSI_BASIC`` () = singleTestBuildAndRun "core/int32" FSI_BASIC + [] + let ``quotes-FSC-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC_OPT_MINUS + [] let ``quotes-FSC-BASIC`` () = singleTestBuildAndRun "core/quotes" FSC_BASIC [] let ``quotes-FSI-BASIC`` () = singleTestBuildAndRun "core/quotes" FSI_BASIC + [] + let ``recordResolution-FSC_BASIC_OPT_MINUS`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC_OPT_MINUS + [] let ``recordResolution-FSC_BASIC`` () = singleTestBuildAndRun "core/recordResolution" FSC_BASIC [] let ``recordResolution-FSI_BASIC`` () = singleTestBuildAndRun "core/recordResolution" FSI_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS + [] + let ``SDKTests`` () = + let cfg = testConfig "SDKTests" + exec cfg cfg.DotNetExe ("msbuild " + Path.Combine(cfg.Directory, "AllSdkTargetsTests.proj") + " /p:Configuration=" + cfg.BUILD_CONFIG) + +#if !NETCOREAPP [] let ``attributes-FSC_BASIC`` () = singleTestBuildAndRun "core/attributes" FSC_BASIC @@ -237,16 +407,27 @@ module CoreTests = let ``attributes-FSI_BASIC`` () = singleTestBuildAndRun "core/attributes" FSI_BASIC [] - let byrefs () = + let byrefs () = let cfg = testConfig "core/byrefs" begin use testOkFile = fileguard cfg "test.ok" - fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s -o:test.exe -g --langversion:4.7" cfg.fsc_flags ["test.fsx"] - singleNegTest cfg "test" + singleVersionedNegTest cfg "4.7" "test" + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + end + + begin + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test.exe -g --langversion:5.0" cfg.fsc_flags ["test.fsx"] + + singleVersionedNegTest cfg "5.0" "test" exec cfg ("." ++ "test.exe") "" @@ -280,7 +461,7 @@ module CoreTests = end [] - let span () = + let span () = let cfg = testConfig "core/span" @@ -326,7 +507,7 @@ module CoreTests = end [] - let asyncStackTraces () = + let asyncStackTraces () = let cfg = testConfig "core/asyncStackTraces" use testOkFile = fileguard cfg "test.ok" @@ -338,7 +519,46 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-conditionals``() = + let ``state-machines-non-optimized`` () = + let cfg = testConfig "core/state-machines" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test.exe -g --tailcalls- --optimize- --langversion:preview" cfg.fsc_flags ["test.fsx"] + + peverify cfg "test.exe" + + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + + [] + let ``state-machines-optimized`` () = + let cfg = testConfig "core/state-machines" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test.exe -g --tailcalls+ --optimize+ --langversion:preview" cfg.fsc_flags ["test.fsx"] + + peverify cfg "test.exe" + + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + + [] + let ``state-machines neg-resumable-01`` () = + let cfg = testConfig "core/state-machines" + singleVersionedNegTest cfg "preview" "neg-resumable-01" + + + [] + let ``state-machines neg-resumable-02`` () = + let cfg = testConfig "core/state-machines" + singleVersionedNegTest cfg "preview" "neg-resumable-02" + + [] + let ``lots-of-conditionals``() = let cfg = testConfig "core/large/conditionals" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeConditionals-200.fs"] @@ -346,7 +566,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-conditionals-maxtested``() = + let ``lots-of-conditionals-maxtested``() = let cfg = testConfig "core/large/conditionals" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeConditionals-maxtested.fs"] @@ -354,7 +574,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-lets``() = + let ``lots-of-lets``() = let cfg = testConfig "core/large/lets" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeLets-500.fs"] @@ -362,7 +582,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-lets-maxtested``() = + let ``lots-of-lets-maxtested``() = let cfg = testConfig "core/large/lets" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeLets-maxtested.fs"] @@ -370,7 +590,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-lists``() = + let ``lots-of-lists``() = let cfg = testConfig "core/large/lists" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test-500.exe " cfg.fsc_flags ["LargeList-500.fs"] @@ -378,7 +598,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-matches``() = + let ``lots-of-matches``() = let cfg = testConfig "core/large/matches" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeMatches-200.fs"] @@ -386,7 +606,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-matches-maxtested``() = + let ``lots-of-matches-maxtested``() = let cfg = testConfig "core/large/matches" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeMatches-maxtested.fs"] @@ -394,7 +614,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-sequential-and-let``() = + let ``lots-of-sequential-and-let``() = let cfg = testConfig "core/large/mixed" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequentialLet-500.fs"] @@ -402,7 +622,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-sequential-and-let-maxtested``() = + let ``lots-of-sequential-and-let-maxtested``() = let cfg = testConfig "core/large/mixed" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequentialLet-maxtested.fs"] @@ -410,7 +630,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-sequential``() = + let ``lots-of-sequential``() = let cfg = testConfig "core/large/sequential" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequential-500.fs"] @@ -418,7 +638,7 @@ module CoreTests = testOkFile.CheckExists() [] - let ``lots-of-sequential-maxtested``() = + let ``lots-of-sequential-maxtested``() = let cfg = testConfig "core/large/sequential" use testOkFile = fileguard cfg "test.ok" fsc cfg "%s -o:test.exe " cfg.fsc_flags ["LargeSequential-maxtested.fs"] @@ -444,7 +664,7 @@ module CoreTests = singleTestBuildAndRunAux {cfg with fsi_flags = " --tailcalls" } FSC_BASIC [] - let ``controlChamenos-FSI_BASIC`` () = + let ``controlChamenos-FSI_BASIC`` () = let cfg = testConfig "core/controlChamenos" singleTestBuildAndRunAux {cfg with fsi_flags = " --tailcalls" } FSI_BASIC @@ -471,7 +691,7 @@ module CoreTests = [] let ``enum-FSI_BASIC`` () = singleTestBuildAndRun "core/enum" FSI_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP // Requires winforms will not run on coreclr [] @@ -479,7 +699,7 @@ module CoreTests = // These tests are enabled for .NET Framework [] - let ``anon-FSC_BASIC``() = + let ``anon-FSC_BASIC``() = let cfg = testConfig "core/anon" fsc cfg "%s -a -o:lib.dll" cfg.fsc_flags ["lib.fs"] @@ -490,7 +710,7 @@ module CoreTests = peverify cfg "test.exe" - begin + begin use testOkFile = fileguard cfg "test.ok" exec cfg ("." ++ "test.exe") "" @@ -498,7 +718,7 @@ module CoreTests = testOkFile.CheckExists() end - begin + begin use testOkFile = fileguard cfg "test.ok" fsi cfg "-r:lib.dll" ["test.fsx"] @@ -507,7 +727,7 @@ module CoreTests = end [] - let events () = + let events () = let cfg = testConfig "core/events" fsc cfg "%s -a -o:test.dll -g" cfg.fsc_flags ["test.fs"] @@ -517,7 +737,7 @@ module CoreTests = csc cfg """/r:"%s" /reference:test.dll /debug+""" cfg.FSCOREDLLPATH ["testcs.cs"] peverify cfg "testcs.exe" - + use testOkFile = fileguard cfg "test.ok" fsi cfg "" ["test.fs"] @@ -531,15 +751,15 @@ module CoreTests = // Shadowcopy does not work for public signed assemblies // ===================================================== // - //module ``FSI-Shadowcopy`` = + //module ``FSI-Shadowcopy`` = // // [] // // "%FSI%" %fsi_flags% < test1.fsx // [] // // "%FSI%" %fsi_flags% /shadowcopyreferences+ < test2.fsx // [] - let forwarders () = + let forwarders () = let cfg = testConfig "core/forwarders" mkdir cfg "orig" @@ -611,7 +831,7 @@ module CoreTests = peverify cfg ("split" ++ "c.dll") [] - let fsfromcs () = + let fsfromcs () = let cfg = testConfig "core/fsfromcs" fsc cfg "%s -a --doc:lib.xml -o:lib.dll -g" cfg.fsc_flags ["lib.fs"] @@ -629,9 +849,9 @@ module CoreTests = exec cfg ("." ++ "test.exe") "" exec cfg ("." ++ "test--optimize.exe") "" - + [] - let fsfromfsviacs () = + let fsfromfsviacs () = let cfg = testConfig "core/fsfromfsviacs" fsc cfg "%s -a -o:lib.dll -g" cfg.fsc_flags ["lib.fs"] @@ -642,28 +862,50 @@ module CoreTests = csc cfg """/nologo /target:library /r:"%s" /out:lib3.dll /langversion:7.2""" cfg.FSCOREDLLPATH ["lib3.cs"] - fsc cfg "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + // some features missing in 4.7 + for version in ["4.7"] do + let outFile = "compilation.langversion.old.output.txt" + let expectedFile = "compilation.langversion.old.output.bsl" + fscBothToOutExpectFail cfg outFile "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g --nologo --define:LANGVERSION_%s --langversion:%s" cfg.fsc_flags (version.Replace(".","_")) version ["test.fsx"] + + let diffs = fsdiff cfg outFile expectedFile + match diffs with + | "" -> () + | _ -> Assert.Fail (sprintf "'%s' and '%s' differ; %A" outFile expectedFile diffs) + + // all features available in preview + fsc cfg "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g --define:LANGVERSION_PREVIEW --langversion:preview" cfg.fsc_flags ["test.fsx"] peverify cfg "test.exe" exec cfg ("." ++ "test.exe") "" // Same with library references the other way around - fsc cfg "%s -r:lib.dll -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s -r:lib.dll -r:lib3.dll -r:lib2.dll -o:test.exe -g --define:LANGVERSION_PREVIEW --langversion:preview" cfg.fsc_flags ["test.fsx"] peverify cfg "test.exe" exec cfg ("." ++ "test.exe") "" // Same without the reference to lib.dll - testing an incomplete reference set, but only compiling a subset of the code - fsc cfg "%s -r:System.Runtime.dll --noframework --define:NO_LIB_REFERENCE -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s --define:NO_LIB_REFERENCE -r:lib3.dll -r:lib2.dll -o:test.exe -g --define:LANGVERSION_PREVIEW --langversion:preview" cfg.fsc_flags ["test.fsx"] peverify cfg "test.exe" exec cfg ("." ++ "test.exe") "" + // check error messages for some cases + let outFile = "compilation.errors.output.txt" + let expectedFile = "compilation.errors.output.bsl" + fscBothToOutExpectFail cfg outFile "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g --nologo --define:LANGVERSION_PREVIEW --langversion:preview --define:CHECK_ERRORS" cfg.fsc_flags ["test.fsx"] + + let diffs = fsdiff cfg outFile expectedFile + match diffs with + | "" -> () + | _ -> Assert.Fail (sprintf "'%s' and '%s' differ; %A" outFile expectedFile diffs) + [] - let ``fsi-reference`` () = + let ``fsi-reference`` () = let cfg = testConfig "core/fsi-reference" @@ -676,7 +918,7 @@ module CoreTests = end [] - let ``fsi-reload`` () = + let ``fsi-reload`` () = let cfg = testConfig "core/fsi-reload" begin @@ -684,7 +926,7 @@ module CoreTests = fsiStdin cfg "test1.ml" "--maxerrors:1" [] testOkFile.CheckExists() end - + begin use testOkFile = fileguard cfg "test.ok" fsi cfg "%s --maxerrors:1" cfg.fsi_flags ["load1.fsx"] @@ -702,7 +944,7 @@ module CoreTests = [] - let fsiAndModifiers () = + let fsiAndModifiers () = let cfg = testConfig "core/fsiAndModifiers" do if fileExists cfg "TestLibrary.dll" then rm cfg "TestLibrary.dll" @@ -714,15 +956,13 @@ module CoreTests = fsiStdin cfg "test.fsx" "--maxerrors:1" [] testOkFile.CheckExists() - - [] let ``genericmeasures-AS_DLL`` () = singleTestBuildAndRun "core/genericmeasures" AS_DLL [] - let hiding () = + let hiding () = let cfg = testConfig "core/hiding" fsc cfg "%s -a --optimize -o:lib.dll" cfg.fsc_flags ["lib.mli";"lib.ml";"libv.ml"] @@ -738,10 +978,10 @@ module CoreTests = peverify cfg "client.exe" [] - let ``innerpoly-AS_DLL`` () = singleTestBuildAndRun "core/innerpoly" AS_DLL + let ``innerpoly-AS_DLL`` () = singleTestBuildAndRun "core/innerpoly" AS_DLL [] - let queriesCustomQueryOps () = + let queriesCustomQueryOps () = let cfg = testConfig "core/queriesCustomQueryOps" fsc cfg """%s -o:test.exe -g""" cfg.fsc_flags ["test.fsx"] @@ -778,11 +1018,11 @@ module CoreTests = testOkFile.CheckExists() end - // Debug with + // Debug with // ..\..\..\..\debug\net40\bin\fsi.exe --nologo < test.fsx >a.out 2>a.err - // then + // then /// windiff z.output.test.default.stdout.bsl a.out - let printing flag diffFileOut expectedFileOut diffFileErr expectedFileErr = + let printing flag diffFileOut expectedFileOut diffFileErr expectedFileErr = let cfg = testConfig "core/printing" if requireENCulture () then @@ -791,15 +1031,15 @@ module CoreTests = let ``fsi b 2>c`` = // "%FSI%" %fsc_flags_errors_ok% --nologo z.raw.output.test.default.txt 2>&1 - let ``exec b 2>c`` (inFile, outFile, errFile) p = - Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Overwrite(outFile), Overwrite(errFile)); Input = Some(RedirectInput(inFile)); } p + let ``exec b 2>c`` (inFile, outFile, errFile) p = + Command.exec cfg.Directory cfg.EnvironmentVariables { Output = OutputAndError(Overwrite(outFile), Overwrite(errFile)); Input = Some(RedirectInput(inFile)); } p >> checkResult Printf.ksprintf (fun flags (inFile, outFile, errFile) -> Commands.fsi (``exec b 2>c`` (inFile, outFile, errFile)) cfg.FSI flags []) let fsc_flags_errors_ok = "" - let rawFileOut = Path.GetTempFileName() - let rawFileErr = Path.GetTempFileName() + let rawFileOut = tryCreateTemporaryFileName () + let rawFileErr = tryCreateTemporaryFileName () ``fsi b 2>c`` "%s --nologo %s" fsc_flags_errors_ok flag ("test.fsx", rawFileOut, rawFileErr) // REM REVIEW: want to normalise CWD paths, not suppress them. @@ -816,7 +1056,7 @@ module CoreTests = expectedFileOut |> withDefault diffFileOut expectedFileErr |> withDefault diffFileErr - + match fsdiff cfg diffFileOut expectedFileOut with | "" -> () | diffs -> Assert.Fail (sprintf "'%s' and '%s' differ; %A" diffFileOut expectedFileOut diffs) @@ -826,23 +1066,39 @@ module CoreTests = | diffs -> Assert.Fail (sprintf "'%s' and '%s' differ; %A" diffFileErr expectedFileErr diffs) [] - let ``printing-1`` () = - printing "" "z.output.test.default.stdout.txt" "z.output.test.default.stdout.bsl" "z.output.test.default.stderr.txt" "z.output.test.default.stderr.bsl" + let ``printing-default-stdout-47 --langversion:4_7`` () = + printing "--langversion:4.7" "z.output.test.default.stdout.47.txt" "z.output.test.default.stdout.47.bsl" "z.output.test.default.stderr.txt" "z.output.test.default.stderr.bsl" + + [] + let ``printing-default-stdout-50 --langversion:5_0`` () = + printing "--langversion:5.0" "z.output.test.default.stdout.50.txt" "z.output.test.default.stdout.50.bsl" "z.output.test.default.stderr.txt" "z.output.test.default.stderr.bsl" + + [] + let ``printing-1000-stdout-47 --langversion:4_7`` () = + printing "--langversion:4.7 --use:preludePrintSize1000.fsx" "z.output.test.1000.stdout.47.txt" "z.output.test.1000.stdout.47.bsl" "z.output.test.1000.stderr.txt" "z.output.test.1000.stderr.bsl" [] - let ``printing-2`` () = - printing "--use:preludePrintSize1000.fsx" "z.output.test.1000.stdout.txt" "z.output.test.1000.stdout.bsl" "z.output.test.1000.stderr.txt" "z.output.test.1000.stderr.bsl" + let ``printing-1000-stdout-50 --langversion:5_0`` () = + printing "--langversion:5.0 --use:preludePrintSize1000.fsx" "z.output.test.1000.stdout.50.txt" "z.output.test.1000.stdout.50.bsl" "z.output.test.1000.stderr.txt" "z.output.test.1000.stderr.bsl" [] - let ``printing-3`` () = - printing "--use:preludePrintSize200.fsx" "z.output.test.200.stdout.txt" "z.output.test.200.stdout.bsl" "z.output.test.200.stderr.txt" "z.output.test.200.stderr.bsl" + let ``printing-200-stdout-47 --langversion:4_7`` () = + printing "--langversion:4.7 --use:preludePrintSize200.fsx" "z.output.test.200.stdout.47.txt" "z.output.test.200.stdout.47.bsl" "z.output.test.200.stderr.txt" "z.output.test.200.stderr.bsl" [] - let ``printing-4`` () = - printing "--use:preludeShowDeclarationValuesFalse.fsx" "z.output.test.off.stdout.txt" "z.output.test.off.stdout.bsl" "z.output.test.off.stderr.txt" "z.output.test.off.stderr.bsl" + let ``printing-200-stdout-50 --langversion:5_0`` () = + printing "--langversion:5.0 --use:preludePrintSize200.fsx" "z.output.test.200.stdout.50.txt" "z.output.test.200.stdout.50.bsl" "z.output.test.200.stderr.txt" "z.output.test.200.stderr.bsl" [] - let ``printing-5`` () = + let ``printing-off-stdout-47 --langversion:4_7`` () = + printing "--langversion:4.7 --use:preludeShowDeclarationValuesFalse.fsx" "z.output.test.off.stdout.47.txt" "z.output.test.off.stdout.47.bsl" "z.output.test.off.stderr.txt" "z.output.test.off.stderr.bsl" + + [] + let ``printing-off-stdout-50 --langversion:5_0`` () = + printing "--langversion:5.0 --use:preludeShowDeclarationValuesFalse.fsx" "z.output.test.off.stdout.50.txt" "z.output.test.off.stdout.50.bsl" "z.output.test.off.stderr.txt" "z.output.test.off.stderr.bsl" + + [] + let ``printing-quiet-stdout`` () = printing "--quiet" "z.output.test.quiet.stdout.txt" "z.output.test.quiet.stdout.bsl" "z.output.test.quiet.stderr.txt" "z.output.test.quiet.stderr.bsl" type SigningType = @@ -850,8 +1106,8 @@ module CoreTests = | PublicSigned | NotSigned - let signedtest(programId:string, args:string, expectedSigning:SigningType) = - + let signedtest(programId:string, args:string, expectedSigning:SigningType) = + let cfg = testConfig "core/signedtests" let newFlags = cfg.fsc_flags + " " + args @@ -929,15 +1185,15 @@ module CoreTests = let ``signedtest-16`` () = signedtest("test-sha1024-full-attributes", "--define:SHA1024", SigningType.PublicSigned) #endif -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP [] - let quotes () = + let quotes () = let cfg = testConfig "core/quotes" csc cfg """/nologo /target:library /out:cslib.dll""" ["cslib.cs"] - fsc cfg "%s -o:test.exe -r cslib.dll -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s --define:LANGVERSION_PREVIEW --langversion:preview -o:test.exe -r cslib.dll -g" cfg.fsc_flags ["test.fsx"] peverify cfg "test.exe" @@ -976,9 +1232,9 @@ module CoreTests = end [] - let parsing () = + let parsing () = let cfg = testConfig "core/parsing" - + fsc cfg "%s -a -o:crlf.dll -g" cfg.fsc_flags ["crlf.ml"] fsc cfg "%s -o:toplet.exe -g" cfg.fsc_flags ["toplet.ml"] @@ -986,7 +1242,7 @@ module CoreTests = peverify cfg "toplet.exe" [] - let unicode () = + let unicode () = let cfg = testConfig "core/unicode" fsc cfg "%s -a -o:kanji-unicode-utf8-nosig-codepage-65001.dll -g" cfg.fsc_flags ["kanji-unicode-utf8-nosig-codepage-65001.fs"] @@ -996,7 +1252,7 @@ module CoreTests = fsc cfg "%s -a -o:kanji-unicode-utf16.dll -g" cfg.fsc_flags ["kanji-unicode-utf16.fs"] fsc cfg "%s -a --codepage:65000 -o:kanji-unicode-utf7-codepage-65000.dll -g" cfg.fsc_flags ["kanji-unicode-utf7-codepage-65000.fs"] - + fsc cfg "%s -a -o:kanji-unicode-utf8-withsig-codepage-65001.dll -g" cfg.fsc_flags ["kanji-unicode-utf8-withsig-codepage-65001.fs"] fsi cfg "%s --utf8output" cfg.fsi_flags ["kanji-unicode-utf8-nosig-codepage-65001.fs"] @@ -1008,10 +1264,10 @@ module CoreTests = fsi cfg "%s --utf8output --codepage:65000" cfg.fsi_flags ["kanji-unicode-utf7-codepage-65000.fs"] fsi cfg "%s --utf8output" cfg.fsi_flags ["kanji-unicode-utf16.fs"] - + [] - let internalsvisible () = + let internalsvisible () = let cfg = testConfig "core/internalsvisible" // Compiling F# Library @@ -1031,11 +1287,11 @@ module CoreTests = // Run F# main. Quick test! exec cfg ("." ++ "main.exe") "" - + // Repro for https://github.com/Microsoft/visualfsharp/issues/1298 [] - let fileorder () = + let fileorder () = let cfg = testConfig "core/fileorder" log "== Compiling F# Library and Code, when empty file libfile2.fs IS NOT included" @@ -1062,7 +1318,7 @@ module CoreTests = // Repro for https://github.com/Microsoft/visualfsharp/issues/2679 [] - let ``add files with same name from different folders`` () = + let ``add files with same name from different folders`` () = let cfg = testConfig "core/samename" log "== Compiling F# Code with files with same name in different folders" @@ -1097,9 +1353,6 @@ module CoreTests = [] let ``libtest-FSI_STDIN`` () = singleTestBuildAndRun "core/libtest" FSI_STDIN - [] - let ``libtest-GENERATED_SIGNATURE`` () = singleTestBuildAndRun "core/libtest" GENERATED_SIGNATURE - [] let ``libtest-FSC_OPT_MINUS_DEBUG`` () = singleTestBuildAndRun "core/libtest" FSC_OPT_MINUS_DEBUG @@ -1167,13 +1420,13 @@ module CoreTests = | _ -> Assert.Fail (sprintf "'%s' and '%s' differ; %A" stderrPath stderrBaseline diffs2) [] - let ``load-script`` () = + let ``load-script`` () = let cfg = testConfig "core/load-script" let stdoutPath = "out.stdout.txt" |> getfullpath cfg let stderrPath = "out.stderr.txt" |> getfullpath cfg - let stderrBaseline = "out.stderr.bsl" |> getfullpath cfg - let stdoutBaseline = "out.stdout.bsl" |> getfullpath cfg + let stderrBaseline = "out.stderr.bsl" |> getfullpath cfg + let stdoutBaseline = "out.stdout.bsl" |> getfullpath cfg let appendToFile from = Commands.appendToFile cfg.Directory from stdoutPath let echo text = Commands.echoAppendToFile cfg.Directory text stdoutPath @@ -1313,7 +1566,7 @@ module CoreTests = //BUGBUG: https://github.com/Microsoft/visualfsharp/issues/6601 // [] -// let ``patterns-FSI_BASIC`` () = singleTestBuildAndRun "core/patterns" FSI_BASIC +// let ``patterns-FSI_BASIC`` () = singleTestBuildAndRun' "core/patterns" FSI_BASIC [] let ``pinvoke-FSC_BASIC`` () = singleTestBuildAndRun "core/pinvoke" FSC_BASIC @@ -1328,7 +1581,7 @@ module CoreTests = [] let ``fsi_load-FSI_BASIC`` () = singleTestBuildAndRun "core/fsi-load" FSI_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP [] let ``measures-AS_DLL`` () = singleTestBuildAndRun "core/measures" AS_DLL @@ -1357,7 +1610,7 @@ module CoreTests = let ``members-incremental-hw-mutrec-FSC_BASIC`` () = singleTestBuildAndRun "core/members/incremental-hw-mutrec" FSC_BASIC [] - let queriesLeafExpressionConvert () = + let queriesLeafExpressionConvert () = let cfg = testConfig "core/queriesLeafExpressionConvert" fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] @@ -1385,10 +1638,10 @@ module CoreTests = exec cfg ("." ++ "test--optimize.exe") "" testOkFile3.CheckExists() - + [] - let queriesNullableOperators () = + let queriesNullableOperators () = let cfg = testConfig "core/queriesNullableOperators" fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] @@ -1410,14 +1663,14 @@ module CoreTests = use testOkFile3 = fileguard cfg "test.ok" exec cfg ("." ++ "test--optimize.exe") "" testOkFile3.CheckExists() - + [] - let queriesOverIEnumerable () = + let queriesOverIEnumerable () = let cfg = testConfig "core/queriesOverIEnumerable" fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] - peverify cfg "test.exe" + peverify cfg "test.exe" fsc cfg "%s --optimize -o:test--optimize.exe -g" cfg.fsc_flags ["test.fsx"] @@ -1440,9 +1693,9 @@ module CoreTests = exec cfg ("." ++ "test--optimize.exe") "" testOkFile3.CheckExists() - + [] - let queriesOverIQueryable () = + let queriesOverIQueryable () = let cfg = testConfig "core/queriesOverIQueryable" fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] @@ -1473,7 +1726,7 @@ module CoreTests = [] - let quotesDebugInfo () = + let quotesDebugInfo () = let cfg = testConfig "core/quotesDebugInfo" fsc cfg "%s --quotations-debug+ --optimize -o:test.exe -g" cfg.fsc_flags ["test.fsx"] @@ -1504,7 +1757,7 @@ module CoreTests = [] - let quotesInMultipleModules () = + let quotesInMultipleModules () = let cfg = testConfig "core/quotesInMultipleModules" fsc cfg "%s -o:module1.dll --target:library" cfg.fsc_flags ["module1.fsx"] @@ -1514,7 +1767,7 @@ module CoreTests = fsc cfg "%s -o:module2.exe -r:module1.dll" cfg.fsc_flags ["module2.fsx"] peverify cfg "module2.exe" - + fsc cfg "%s --staticlink:module1 -o:module2-staticlink.exe -r:module1.dll" cfg.fsc_flags ["module2.fsx"] peverify cfg "module2-staticlink.exe" @@ -1559,9 +1812,9 @@ module CoreTests = [] let ``reflect-FSI_BASIC`` () = singleTestBuildAndRun "core/reflect" FSI_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP [] - let refnormalization () = + let refnormalization () = let cfg = testConfig "core/refnormalization" // Prepare by building multiple versions of the test assemblies @@ -1597,7 +1850,7 @@ module CoreTests = [] - let testResources () = + let testResources () = let cfg = testConfig "core/resources" fsc cfg "%s --resource:Resources.resources -o:test-embed.exe -g" cfg.fsc_flags ["test.fs"] @@ -1625,7 +1878,7 @@ module CoreTests = exec cfg ("." ++ "test-embed-named.exe") "ResourceName" [] - let topinit () = + let topinit () = let cfg = testConfig "core/topinit" fsc cfg "%s --optimize -o both69514.exe -g" cfg.fsc_flags ["lib69514.fs"; "app69514.fs"] @@ -1751,9 +2004,9 @@ module CoreTests = exec cfg ("." ++ "test_static_init_exe.exe") "" exec cfg ("." ++ "test_static_init_exe--optimize.exe") "" - + [] - let unitsOfMeasure () = + let unitsOfMeasure () = let cfg = testConfig "core/unitsOfMeasure" fsc cfg "%s --optimize- -o:test.exe -g" cfg.fsc_flags ["test.fs"] @@ -1767,7 +2020,7 @@ module CoreTests = testOkFile.CheckExists() [] - let verify () = + let verify () = let cfg = testConfig "core/verify" peverifyWithArgs cfg "/nologo" (cfg.FSharpBuild) @@ -1781,23 +2034,34 @@ module CoreTests = fsc cfg "%s -o:xmlverify.exe -g" cfg.fsc_flags ["xmlverify.fs"] peverifyWithArgs cfg "/nologo" "xmlverify.exe" + + + [] + let ``property setter in method or constructor`` () = + let cfg = testConfig "core/members/set-only-property" + csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] + vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] + fsc cfg @"%s /target:library /out:fs.dll" cfg.fsc_flags ["fs.fs"] + singleNegTest cfg "calls" + #endif +[] module VersionTests = [] - let ``member-selfidentifier-version4.6``() = singleTestBuildAndRunVersion "core/members/self-identifier/version46" FSC_BUILDONLY "4.6" + let ``member-selfidentifier-version4_6``() = singleTestBuildAndRunVersion "core/members/self-identifier/version46" FSC_BUILDONLY "4.6" [] - let ``member-selfidentifier-version4.7``() = singleTestBuildAndRun "core/members/self-identifier/version47" FSC_BUILDONLY + let ``member-selfidentifier-version4_7``() = singleTestBuildAndRun "core/members/self-identifier/version47" FSC_BUILDONLY [] - let ``indent-version4.6``() = singleTestBuildAndRunVersion "core/indent/version46" FSC_BUILDONLY "4.6" + let ``indent-version4_6``() = singleTestBuildAndRunVersion "core/indent/version46" FSC_BUILDONLY "4.6" [] - let ``indent-version4.7``() = singleTestBuildAndRun "core/indent/version47" FSC_BUILDONLY + let ``indent-version4_7``() = singleTestBuildAndRun "core/indent/version47" FSC_BUILDONLY [] - let ``nameof-version4.6``() = singleTestBuildAndRunVersion "core/nameof/version46" FSC_BUILDONLY "4.6" + let ``nameof-version4_6``() = singleTestBuildAndRunVersion "core/nameof/version46" FSC_BUILDONLY "4.6" [] let ``nameof-versionpreview``() = singleTestBuildAndRunVersion "core/nameof/preview" FSC_BUILDONLY "preview" @@ -1808,28 +2072,29 @@ module VersionTests = [] let ``nameof-fsi``() = singleTestBuildAndRunVersion "core/nameof/preview" FSI_BASIC "preview" -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS -module ToolsTests = +#if !NETCOREAPP +[] +module ToolsTests = // This test is disabled in coreclr builds dependent on fixing : https://github.com/Microsoft/visualfsharp/issues/2600 [] - let bundle () = + let bundle () = let cfg = testConfig "tools/bundle" fsc cfg "%s --progress --standalone -o:test-one-fsharp-module.exe -g" cfg.fsc_flags ["test-one-fsharp-module.fs"] peverify cfg "test-one-fsharp-module.exe" - + fsc cfg "%s -a -o:test_two_fsharp_modules_module_1.dll -g" cfg.fsc_flags ["test_two_fsharp_modules_module_1.fs"] - + peverify cfg "test_two_fsharp_modules_module_1.dll" - + fsc cfg "%s --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2.exe -g" cfg.fsc_flags ["test_two_fsharp_modules_module_2.fs"] - + peverify cfg "test_two_fsharp_modules_module_2.exe" - + fsc cfg "%s -a --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2_as_dll.dll -g" cfg.fsc_flags ["test_two_fsharp_modules_module_2.fs"] - + peverify cfg "test_two_fsharp_modules_module_2_as_dll.dll" #endif @@ -1838,7 +2103,8 @@ module ToolsTests = [] let ``eval-FSI_BASIC`` () = singleTestBuildAndRun "tools/eval" FSI_BASIC -module RegressionTests = +[] +module RegressionTests = [] let ``literal-value-bug-2-FSC_BASIC`` () = singleTestBuildAndRun "regression/literal-value-bug-2" FSC_BASIC @@ -1858,33 +2124,33 @@ module RegressionTests = [] let ``tuple-bug-1-FSC_BASIC`` () = singleTestBuildAndRun "regression/tuple-bug-1" FSC_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP [] let ``SRTP doesn't handle calling member hiding hinherited members`` () = - let cfg = testConfig "regression/5531" + let cfg = testConfig "regression/5531" - let outFile = "compilation.output.test.txt" - let expectedFile = "compilation.output.test.bsl" + let outFile = "compilation.output.test.txt" + let expectedFile = "compilation.output.test.bsl" - fscBothToOut cfg outFile "%s --nologo -O" cfg.fsc_flags ["test.fs"] + fscBothToOut cfg outFile "%s --nologo -O" cfg.fsc_flags ["test.fs"] - let diff = fsdiff cfg outFile expectedFile + let diff = fsdiff cfg outFile expectedFile - match diff with - | "" -> () - | _ -> - Assert.Fail (sprintf "'%s' and '%s' differ; %A" (getfullpath cfg outFile) (getfullpath cfg expectedFile) diff) + match diff with + | "" -> () + | _ -> + Assert.Fail (sprintf "'%s' and '%s' differ; %A" (getfullpath cfg outFile) (getfullpath cfg expectedFile) diff) - let outFile2 = "output.test.txt" - let expectedFile2 = "output.test.bsl" + let outFile2 = "output.test.txt" + let expectedFile2 = "output.test.bsl" - execBothToOut cfg (cfg.Directory) outFile2 (cfg.Directory ++ "test.exe") "" + execBothToOut cfg (cfg.Directory) outFile2 (cfg.Directory ++ "test.exe") "" - let diff2 = fsdiff cfg outFile2 expectedFile2 - match diff2 with - | "" -> () - | _ -> - Assert.Fail (sprintf "'%s' and '%s' differ; %A" (getfullpath cfg outFile2) (getfullpath cfg expectedFile2) diff2) + let diff2 = fsdiff cfg outFile2 expectedFile2 + match diff2 with + | "" -> () + | _ -> + Assert.Fail (sprintf "'%s' and '%s' differ; %A" (getfullpath cfg outFile2) (getfullpath cfg expectedFile2) diff2) #endif [] @@ -1893,10 +2159,10 @@ module RegressionTests = [] let ``321`` () = singleTestBuildAndRun "regression/321" FSC_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP // This test is disabled in coreclr builds dependent on fixing : https://github.com/Microsoft/visualfsharp/issues/2600 [] - let ``655`` () = + let ``655`` () = let cfg = testConfig "regression/655" fsc cfg "%s -a -o:pack.dll" cfg.fsc_flags ["xlibC.ml"] @@ -1912,18 +2178,18 @@ module RegressionTests = exec cfg ("." ++ "test.exe") "" testOkFile.CheckExists() - + // This test is disabled in coreclr builds dependent on fixing : https://github.com/Microsoft/visualfsharp/issues/2600 [] - let ``656`` () = + let ``656`` () = let cfg = testConfig "regression/656" fsc cfg "%s -o:pack.exe" cfg.fsc_flags ["misc.fs mathhelper.fs filehelper.fs formshelper.fs plot.fs traj.fs playerrecord.fs trackedplayers.fs form.fs"] peverify cfg "pack.exe" #endif - -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS + +#if !NETCOREAPP // Requires WinForms [] let ``83`` () = singleTestBuildAndRun "regression/83" FSC_BASIC @@ -1932,7 +2198,7 @@ module RegressionTests = let ``84`` () = singleTestBuildAndRun "regression/84" FSC_BASIC [] - let ``85`` () = + let ``85`` () = let cfg = testConfig "regression/85" fsc cfg "%s -r:Category.dll -a -o:petshop.dll" cfg.fsc_flags ["Category.ml"] @@ -1946,28 +2212,28 @@ module RegressionTests = [] let ``struct-tuple-bug-1-FSI_BASIC`` () = singleTestBuildAndRun "regression/struct-tuple-bug-1" FSI_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP // This test is disabled in coreclr builds dependent on fixing : https://github.com/Microsoft/visualfsharp/issues/2600 [] - let ``struct-measure-bug-1`` () = + let ``struct-measure-bug-1`` () = let cfg = testConfig "regression/struct-measure-bug-1" fsc cfg "%s --optimize- -o:test.exe -g" cfg.fsc_flags ["test.fs"] peverify cfg "test.exe" -#endif -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS + +[] module OptimizationTests = [] - let functionSizes () = + let functionSizes () = let cfg = testConfig "optimize/analyses" let outFile = "sizes.FunctionSizes.output.test.txt" let expectedFile = "sizes.FunctionSizes.output.test.bsl" log "== FunctionSizes" - fscBothToOut cfg outFile "%s --nologo -O --test:FunctionSizes" cfg.fsc_flags ["sizes.fs"] + fscBothToOut cfg outFile "%s --nologo -O --test:FunctionSizes" cfg.fsc_flags ["sizes.fs"] let diff = fsdiff cfg outFile expectedFile @@ -1978,14 +2244,14 @@ module OptimizationTests = [] - let totalSizes () = + let totalSizes () = let cfg = testConfig "optimize/analyses" let outFile = "sizes.TotalSizes.output.test.txt" let expectedFile = "sizes.TotalSizes.output.test.bsl" log "== TotalSizes" - fscBothToOut cfg outFile "%s --nologo -O --test:TotalSizes" cfg.fsc_flags ["sizes.fs"] + fscBothToOut cfg outFile "%s --nologo -O --test:TotalSizes" cfg.fsc_flags ["sizes.fs"] let diff = fsdiff cfg outFile expectedFile @@ -1995,14 +2261,14 @@ module OptimizationTests = [] - let hasEffect () = + let hasEffect () = let cfg = testConfig "optimize/analyses" let outFile = "effects.HasEffect.output.test.txt" let expectedFile = "effects.HasEffect.output.test.bsl" log "== HasEffect" - fscBothToOut cfg outFile "%s --nologo -O --test:HasEffect" cfg.fsc_flags ["effects.fs"] + fscBothToOut cfg outFile "%s --nologo -O --test:HasEffect" cfg.fsc_flags ["effects.fs"] let diff = fsdiff cfg outFile expectedFile @@ -2012,14 +2278,14 @@ module OptimizationTests = [] - let noNeedToTailcall () = + let noNeedToTailcall () = let cfg = testConfig "optimize/analyses" let outFile = "tailcalls.NoNeedToTailcall.output.test.txt" let expectedFile = "tailcalls.NoNeedToTailcall.output.test.bsl" log "== NoNeedToTailcall" - fscBothToOut cfg outFile "%s --nologo -O --test:NoNeedToTailcall" cfg.fsc_flags ["tailcalls.fs"] + fscBothToOut cfg outFile "%s --nologo -O --test:NoNeedToTailcall" cfg.fsc_flags ["tailcalls.fs"] let diff = fsdiff cfg outFile expectedFile @@ -2029,12 +2295,12 @@ module OptimizationTests = [] - let ``inline`` () = + let ``inline`` () = let cfg = testConfig "optimize/inline" fsc cfg "%s -g --optimize- --target:library -o:lib.dll" cfg.fsc_flags ["lib.fs"; "lib2.fs"] - peverify cfg "lib.dll " + peverify cfg "lib.dll " fsc cfg "%s -g --optimize- --target:library -o:lib3.dll -r:lib.dll " cfg.fsc_flags ["lib3.fs"] @@ -2050,17 +2316,17 @@ module OptimizationTests = ildasm cfg "/out=test--optimize.il" "test--optimize.exe" - let ``test--optimize.il`` = + let ``test--optimize.il`` = File.ReadLines (getfullpath cfg "test--optimize.il") |> Seq.filter (fun line -> line.Contains(".locals init")) |> List.ofSeq match ``test--optimize.il`` with | [] -> () - | lines -> + | lines -> Assert.Fail (sprintf "Error: optimizations not removed. Relevant lines from IL file follow: %A" lines) - let numElim = + let numElim = File.ReadLines (getfullpath cfg "test.il") |> Seq.filter (fun line -> line.Contains(".locals init")) |> Seq.length @@ -2068,7 +2334,7 @@ module OptimizationTests = log "Ran ok - optimizations removed %d textual occurrences of optimizable identifiers from target IL" numElim [] - let stats () = + let stats () = let cfg = testConfig "optimize/stats" ildasm cfg "/out=FSharp.Core.il" cfg.FSCOREDLLPATH @@ -2090,182 +2356,223 @@ module OptimizationTests = log "%s" m #endif -module TypecheckTests = +[] +module TypecheckTests = [] - let ``full-rank-arrays`` () = + let ``full-rank-arrays`` () = let cfg = testConfig "typecheck/full-rank-arrays" SingleTest.singleTestBuildAndRunWithCopyDlls cfg "full-rank-arrays.dll" FSC_BASIC [] let misc () = singleTestBuildAndRun "typecheck/misc" FSC_BASIC -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP [] - let ``sigs pos26`` () = + let ``sigs pos26`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos26.exe" cfg.fsc_flags ["pos26.fsi"; "pos26.fs"] peverify cfg "pos26.exe" [] - let ``sigs pos25`` () = + let ``sigs pos25`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos25.exe" cfg.fsc_flags ["pos25.fs"] peverify cfg "pos25.exe" [] - let ``sigs pos27`` () = + let ``sigs pos27`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos27.exe" cfg.fsc_flags ["pos27.fs"] peverify cfg "pos27.exe" [] - let ``sigs pos28`` () = + let ``sigs pos28`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos28.exe" cfg.fsc_flags ["pos28.fs"] peverify cfg "pos28.exe" [] - let ``sigs pos29`` () = + let ``sigs pos29`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos29.exe" cfg.fsc_flags ["pos29.fsi"; "pos29.fs"; "pos29.app.fs"] peverify cfg "pos29.exe" [] - let ``sigs pos30`` () = + let ``sigs pos30`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos30.exe --warnaserror+" cfg.fsc_flags ["pos30.fs"] peverify cfg "pos30.exe" [] - let ``sigs pos24`` () = + let ``sigs pos24`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos24.exe" cfg.fsc_flags ["pos24.fs"] peverify cfg "pos24.exe" [] - let ``sigs pos31`` () = + let ``sigs pos31`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos31.exe --warnaserror" cfg.fsc_flags ["pos31.fsi"; "pos31.fs"] peverify cfg "pos31.exe" [] - let ``sigs pos32`` () = + let ``sigs pos32`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:library -o:pos32.dll --warnaserror" cfg.fsc_flags ["pos32.fs"] peverify cfg "pos32.dll" [] - let ``sigs pos33`` () = + let ``sigs pos33`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:library -o:pos33.dll --warnaserror" cfg.fsc_flags ["pos33.fsi"; "pos33.fs"] peverify cfg "pos33.dll" [] - let ``sigs pos23`` () = + let ``sigs pos34`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:library -o:pos34.dll --warnaserror" cfg.fsc_flags ["pos34.fs"] + peverify cfg "pos34.dll" + + [] + let ``sigs pos35`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:library -o:pos35.dll --warnaserror" cfg.fsc_flags ["pos35.fs"] + peverify cfg "pos35.dll" + + [] + let ``sigs pos36-srtp`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:library -o:pos36-srtp-lib.dll --warnaserror" cfg.fsc_flags ["pos36-srtp-lib.fs"] + fsc cfg "%s --target:exe -r:pos36-srtp-lib.dll -o:pos36-srtp-app.exe --warnaserror" cfg.fsc_flags ["pos36-srtp-app.fs"] + peverify cfg "pos36-srtp-lib.dll" + peverify cfg "pos36-srtp-app.exe" + exec cfg ("." ++ "pos36-srtp-app.exe") "" + + [] + let ``sigs pos37`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:library -o:pos37.dll --warnaserror" cfg.fsc_flags ["pos37.fs"] + peverify cfg "pos37.dll" + + [] + let ``sigs pos38`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:library -o:pos38.dll --warnaserror" cfg.fsc_flags ["pos38.fs"] + peverify cfg "pos38.dll" + + [] + let ``sigs pos39`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:exe -o:pos39.exe" cfg.fsc_flags ["pos39.fs"] + peverify cfg "pos39.exe" + exec cfg ("." ++ "pos39.exe") "" + + [] + let ``sigs pos23`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos23.exe" cfg.fsc_flags ["pos23.fs"] peverify cfg "pos23.exe" exec cfg ("." ++ "pos23.exe") "" [] - let ``sigs pos20`` () = + let ``sigs pos20`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos20.exe" cfg.fsc_flags ["pos20.fs"] peverify cfg "pos20.exe" exec cfg ("." ++ "pos20.exe") "" [] - let ``sigs pos19`` () = + let ``sigs pos19`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos19.exe" cfg.fsc_flags ["pos19.fs"] peverify cfg "pos19.exe" exec cfg ("." ++ "pos19.exe") "" [] - let ``sigs pos18`` () = + let ``sigs pos18`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos18.exe" cfg.fsc_flags ["pos18.fs"] peverify cfg "pos18.exe" exec cfg ("." ++ "pos18.exe") "" [] - let ``sigs pos16`` () = + let ``sigs pos16`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos16.exe" cfg.fsc_flags ["pos16.fs"] peverify cfg "pos16.exe" exec cfg ("." ++ "pos16.exe") "" [] - let ``sigs pos17`` () = + let ``sigs pos17`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos17.exe" cfg.fsc_flags ["pos17.fs"] peverify cfg "pos17.exe" exec cfg ("." ++ "pos17.exe") "" [] - let ``sigs pos15`` () = + let ``sigs pos15`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos15.exe" cfg.fsc_flags ["pos15.fs"] peverify cfg "pos15.exe" exec cfg ("." ++ "pos15.exe") "" [] - let ``sigs pos14`` () = + let ``sigs pos14`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos14.exe" cfg.fsc_flags ["pos14.fs"] peverify cfg "pos14.exe" exec cfg ("." ++ "pos14.exe") "" [] - let ``sigs pos13`` () = + let ``sigs pos13`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s --target:exe -o:pos13.exe" cfg.fsc_flags ["pos13.fs"] peverify cfg "pos13.exe" exec cfg ("." ++ "pos13.exe") "" [] - let ``sigs pos12 `` () = + let ``sigs pos12 `` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos12.dll" cfg.fsc_flags ["pos12.fs"] [] - let ``sigs pos11`` () = + let ``sigs pos11`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos11.dll" cfg.fsc_flags ["pos11.fs"] [] - let ``sigs pos10`` () = + let ``sigs pos10`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos10.dll" cfg.fsc_flags ["pos10.fs"] peverify cfg "pos10.dll" [] - let ``sigs pos09`` () = + let ``sigs pos09`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos09.dll" cfg.fsc_flags ["pos09.fs"] peverify cfg "pos09.dll" [] - let ``sigs pos07`` () = + let ``sigs pos07`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos07.dll" cfg.fsc_flags ["pos07.fs"] peverify cfg "pos07.dll" [] - let ``sigs pos08`` () = + let ``sigs pos08`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos08.dll" cfg.fsc_flags ["pos08.fs"] peverify cfg "pos08.dll" [] - let ``sigs pos06`` () = + let ``sigs pos06`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos06.dll" cfg.fsc_flags ["pos06.fs"] peverify cfg "pos06.dll" [] - let ``sigs pos03`` () = + let ``sigs pos03`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos03.dll" cfg.fsc_flags ["pos03.fs"] peverify cfg "pos03.dll" @@ -2273,355 +2580,367 @@ module TypecheckTests = peverify cfg "pos03a.dll" [] - let ``sigs pos01a`` () = + let ``sigs pos01a`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos01a.dll" cfg.fsc_flags ["pos01a.fsi"; "pos01a.fs"] peverify cfg "pos01a.dll" [] - let ``sigs pos02`` () = + let ``sigs pos02`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos02.dll" cfg.fsc_flags ["pos02.fs"] peverify cfg "pos02.dll" [] - let ``sigs pos05`` () = + let ``sigs pos05`` () = let cfg = testConfig "typecheck/sigs" fsc cfg "%s -a -o:pos05.dll" cfg.fsc_flags ["pos05.fs"] - [] + [] let ``type check neg01`` () = singleNegTest (testConfig "typecheck/sigs") "neg01" - [] + [] let ``type check neg02`` () = singleNegTest (testConfig "typecheck/sigs") "neg02" - [] + [] let ``type check neg03`` () = singleNegTest (testConfig "typecheck/sigs") "neg03" - [] + [] let ``type check neg04`` () = singleNegTest (testConfig "typecheck/sigs") "neg04" - [] + [] let ``type check neg05`` () = singleNegTest (testConfig "typecheck/sigs") "neg05" - [] + [] let ``type check neg06`` () = singleNegTest (testConfig "typecheck/sigs") "neg06" - [] + [] let ``type check neg06_a`` () = singleNegTest (testConfig "typecheck/sigs") "neg06_a" - [] + [] let ``type check neg06_b`` () = singleNegTest (testConfig "typecheck/sigs") "neg06_b" - [] + [] let ``type check neg07`` () = singleNegTest (testConfig "typecheck/sigs") "neg07" - [] + [] let ``type check neg08`` () = singleNegTest (testConfig "typecheck/sigs") "neg08" - [] + [] let ``type check neg09`` () = singleNegTest (testConfig "typecheck/sigs") "neg09" - [] + [] let ``type check neg10`` () = singleNegTest (testConfig "typecheck/sigs") "neg10" - [] + [] let ``type check neg10_a`` () = singleNegTest (testConfig "typecheck/sigs") "neg10_a" - [] + [] let ``type check neg11`` () = singleNegTest (testConfig "typecheck/sigs") "neg11" - [] + [] let ``type check neg12`` () = singleNegTest (testConfig "typecheck/sigs") "neg12" - [] + [] let ``type check neg13`` () = singleNegTest (testConfig "typecheck/sigs") "neg13" - [] + [] let ``type check neg14`` () = singleNegTest (testConfig "typecheck/sigs") "neg14" - [] + [] let ``type check neg15`` () = singleNegTest (testConfig "typecheck/sigs") "neg15" - [] + [] let ``type check neg16`` () = singleNegTest (testConfig "typecheck/sigs") "neg16" - [] + [] let ``type check neg17`` () = singleNegTest (testConfig "typecheck/sigs") "neg17" - [] + [] let ``type check neg18`` () = singleNegTest (testConfig "typecheck/sigs") "neg18" - [] + [] let ``type check neg19`` () = singleNegTest (testConfig "typecheck/sigs") "neg19" - [] + [] let ``type check neg20`` () = singleNegTest (testConfig "typecheck/sigs") "neg20" - [] + [] + let ``type check neg20 version 5_0`` () = + let cfg = testConfig "typecheck/sigs/version50" + singleVersionedNegTest cfg "5.0" "neg20" + + [] let ``type check neg21`` () = singleNegTest (testConfig "typecheck/sigs") "neg21" - [] + [] let ``type check neg22`` () = singleNegTest (testConfig "typecheck/sigs") "neg22" - [] + [] let ``type check neg23`` () = singleNegTest (testConfig "typecheck/sigs") "neg23" [] - let ``type check neg24 version 4.6`` () = + let ``type check neg24 version 4_6`` () = let cfg = testConfig "typecheck/sigs/version46" // For some reason this warning is off by default in the test framework but in this case we are testing for it let cfg = { cfg with fsc_flags = cfg.fsc_flags.Replace("--nowarn:20", "") } singleVersionedNegTest cfg "4.6" "neg24" - [] - let ``type check neg24 version 4.7`` () = + [] + let ``type check neg24 version 4_7`` () = let cfg = testConfig "typecheck/sigs/version47" // For some reason this warning is off by default in the test framework but in this case we are testing for it let cfg = { cfg with fsc_flags = cfg.fsc_flags.Replace("--nowarn:20", "") } + singleVersionedNegTest cfg "4.7" "neg24" + + [] + let ``type check neg24 version preview`` () = + let cfg = testConfig "typecheck/sigs" + // For some reason this warning is off by default in the test framework but in this case we are testing for it + let cfg = { cfg with fsc_flags = cfg.fsc_flags.Replace("--nowarn:20", "") } singleVersionedNegTest cfg "preview" "neg24" [] let ``type check neg25`` () = singleNegTest (testConfig "typecheck/sigs") "neg25" - [] + [] let ``type check neg26`` () = singleNegTest (testConfig "typecheck/sigs") "neg26" - [] + [] let ``type check neg27`` () = singleNegTest (testConfig "typecheck/sigs") "neg27" - [] + [] let ``type check neg28`` () = singleNegTest (testConfig "typecheck/sigs") "neg28" - [] + [] let ``type check neg29`` () = singleNegTest (testConfig "typecheck/sigs") "neg29" - [] + [] let ``type check neg30`` () = singleNegTest (testConfig "typecheck/sigs") "neg30" - [] + [] let ``type check neg31`` () = singleNegTest (testConfig "typecheck/sigs") "neg31" - [] + [] let ``type check neg32`` () = singleNegTest (testConfig "typecheck/sigs") "neg32" - [] + [] let ``type check neg33`` () = singleNegTest (testConfig "typecheck/sigs") "neg33" - [] + [] let ``type check neg34`` () = singleNegTest (testConfig "typecheck/sigs") "neg34" - [] + [] let ``type check neg35`` () = singleNegTest (testConfig "typecheck/sigs") "neg35" - [] + [] let ``type check neg36`` () = singleNegTest (testConfig "typecheck/sigs") "neg36" - [] + [] let ``type check neg37`` () = singleNegTest (testConfig "typecheck/sigs") "neg37" - [] + [] let ``type check neg37_a`` () = singleNegTest (testConfig "typecheck/sigs") "neg37_a" - [] + [] let ``type check neg38`` () = singleNegTest (testConfig "typecheck/sigs") "neg38" - [] + [] let ``type check neg39`` () = singleNegTest (testConfig "typecheck/sigs") "neg39" - [] + [] let ``type check neg40`` () = singleNegTest (testConfig "typecheck/sigs") "neg40" - [] + [] let ``type check neg41`` () = singleNegTest (testConfig "typecheck/sigs") "neg41" - [] + [] let ``type check neg42`` () = singleNegTest (testConfig "typecheck/sigs") "neg42" - [] + [] let ``type check neg43`` () = singleNegTest (testConfig "typecheck/sigs") "neg43" - [] + [] let ``type check neg44`` () = singleNegTest (testConfig "typecheck/sigs") "neg44" - [] + [] let ``type check neg45`` () = singleNegTest (testConfig "typecheck/sigs") "neg45" - [] + [] let ``type check neg46`` () = singleNegTest (testConfig "typecheck/sigs") "neg46" - [] + [] let ``type check neg47`` () = singleNegTest (testConfig "typecheck/sigs") "neg47" - [] + [] let ``type check neg48`` () = singleNegTest (testConfig "typecheck/sigs") "neg48" - [] + [] let ``type check neg49`` () = singleNegTest (testConfig "typecheck/sigs") "neg49" - [] + [] let ``type check neg50`` () = singleNegTest (testConfig "typecheck/sigs") "neg50" - [] + [] let ``type check neg51`` () = singleNegTest (testConfig "typecheck/sigs") "neg51" - [] + [] let ``type check neg52`` () = singleNegTest (testConfig "typecheck/sigs") "neg52" - [] + [] let ``type check neg53`` () = singleNegTest (testConfig "typecheck/sigs") "neg53" - [] + [] let ``type check neg54`` () = singleNegTest (testConfig "typecheck/sigs") "neg54" - [] + [] let ``type check neg55`` () = singleNegTest (testConfig "typecheck/sigs") "neg55" - [] + [] let ``type check neg56`` () = singleNegTest (testConfig "typecheck/sigs") "neg56" - [] + [] let ``type check neg56_a`` () = singleNegTest (testConfig "typecheck/sigs") "neg56_a" - [] + [] let ``type check neg56_b`` () = singleNegTest (testConfig "typecheck/sigs") "neg56_b" - [] + [] let ``type check neg57`` () = singleNegTest (testConfig "typecheck/sigs") "neg57" - [] + [] let ``type check neg58`` () = singleNegTest (testConfig "typecheck/sigs") "neg58" - [] + [] let ``type check neg59`` () = singleNegTest (testConfig "typecheck/sigs") "neg59" - [] + [] let ``type check neg60`` () = singleNegTest (testConfig "typecheck/sigs") "neg60" - [] + [] let ``type check neg61`` () = singleNegTest (testConfig "typecheck/sigs") "neg61" - [] + [] let ``type check neg62`` () = singleNegTest (testConfig "typecheck/sigs") "neg62" - [] + [] let ``type check neg63`` () = singleNegTest (testConfig "typecheck/sigs") "neg63" - [] + [] let ``type check neg64`` () = singleNegTest (testConfig "typecheck/sigs") "neg64" - [] + [] let ``type check neg65`` () = singleNegTest (testConfig "typecheck/sigs") "neg65" - [] + [] let ``type check neg66`` () = singleNegTest (testConfig "typecheck/sigs") "neg66" - [] + [] let ``type check neg67`` () = singleNegTest (testConfig "typecheck/sigs") "neg67" - [] + [] let ``type check neg68`` () = singleNegTest (testConfig "typecheck/sigs") "neg68" - [] + [] let ``type check neg69`` () = singleNegTest (testConfig "typecheck/sigs") "neg69" - [] + [] let ``type check neg70`` () = singleNegTest (testConfig "typecheck/sigs") "neg70" - [] + [] let ``type check neg71`` () = singleNegTest (testConfig "typecheck/sigs") "neg71" - [] + [] let ``type check neg72`` () = singleNegTest (testConfig "typecheck/sigs") "neg72" - [] + [] let ``type check neg73`` () = singleNegTest (testConfig "typecheck/sigs") "neg73" - [] + [] let ``type check neg74`` () = singleNegTest (testConfig "typecheck/sigs") "neg74" - [] + [] let ``type check neg75`` () = singleNegTest (testConfig "typecheck/sigs") "neg75" - [] + [] let ``type check neg76`` () = singleNegTest (testConfig "typecheck/sigs") "neg76" - [] + [] let ``type check neg77`` () = singleNegTest (testConfig "typecheck/sigs") "neg77" - [] + [] let ``type check neg78`` () = singleNegTest (testConfig "typecheck/sigs") "neg78" - [] + [] let ``type check neg79`` () = singleNegTest (testConfig "typecheck/sigs") "neg79" - [] + [] let ``type check neg80`` () = singleNegTest (testConfig "typecheck/sigs") "neg80" - [] + [] let ``type check neg81`` () = singleNegTest (testConfig "typecheck/sigs") "neg81" - [] + [] let ``type check neg82`` () = singleNegTest (testConfig "typecheck/sigs") "neg82" - [] + [] let ``type check neg83`` () = singleNegTest (testConfig "typecheck/sigs") "neg83" - [] + [] let ``type check neg84`` () = singleNegTest (testConfig "typecheck/sigs") "neg84" - [] + [] let ``type check neg85`` () = singleNegTest (testConfig "typecheck/sigs") "neg85" - [] + [] let ``type check neg86`` () = singleNegTest (testConfig "typecheck/sigs") "neg86" - [] + [] let ``type check neg87`` () = singleNegTest (testConfig "typecheck/sigs") "neg87" - [] + [] let ``type check neg88`` () = singleNegTest (testConfig "typecheck/sigs") "neg88" - [] + [] let ``type check neg89`` () = singleNegTest (testConfig "typecheck/sigs") "neg89" - [] + [] let ``type check neg90`` () = singleNegTest (testConfig "typecheck/sigs") "neg90" - [] + [] let ``type check neg91`` () = singleNegTest (testConfig "typecheck/sigs") "neg91" - [] + [] let ``type check neg92`` () = singleNegTest (testConfig "typecheck/sigs") "neg92" - [] + [] let ``type check neg93`` () = singleNegTest (testConfig "typecheck/sigs") "neg93" - [] + [] let ``type check neg94`` () = singleNegTest (testConfig "typecheck/sigs") "neg94" - [] + [] let ``type check neg95`` () = singleNegTest (testConfig "typecheck/sigs") "neg95" - [] + [] let ``type check neg96`` () = singleNegTest (testConfig "typecheck/sigs") "neg96" - [] + [] let ``type check neg97`` () = singleNegTest (testConfig "typecheck/sigs") "neg97" - [] + [] let ``type check neg98`` () = singleNegTest (testConfig "typecheck/sigs") "neg98" - [] + [] let ``type check neg99`` () = singleNegTest (testConfig "typecheck/sigs") "neg99" - [] - let ``type check neg100`` () = + [] + let ``type check neg100`` () = let cfg = testConfig "typecheck/sigs" let cfg = { cfg with fsc_flags = cfg.fsc_flags + " --warnon:3218" } singleNegTest cfg "neg100" - [] + [] let ``type check neg101`` () = singleNegTest (testConfig "typecheck/sigs") "neg101" [] @@ -2652,93 +2971,141 @@ module TypecheckTests = let ``type check neg111`` () = singleNegTest (testConfig "typecheck/sigs") "neg111" [] + let ``type check neg112`` () = singleNegTest (testConfig "typecheck/sigs") "neg112" + + [] let ``type check neg113`` () = singleNegTest (testConfig "typecheck/sigs") "neg113" - [] + [] let ``type check neg114`` () = singleNegTest (testConfig "typecheck/sigs") "neg114" - [] + [] let ``type check neg115`` () = singleNegTest (testConfig "typecheck/sigs") "neg115" - [] + [] + let ``type check neg116`` () = singleNegTest (testConfig "typecheck/sigs") "neg116" + + [] + let ``type check neg117`` () = singleNegTest (testConfig "typecheck/sigs") "neg117" + + [] + let ``type check neg118`` () = singleNegTest (testConfig "typecheck/sigs") "neg118" + + [] + let ``type check neg119`` () = singleNegTest (testConfig "typecheck/sigs") "neg119" + + [] + let ``type check neg120`` () = singleNegTest (testConfig "typecheck/sigs") "neg120" + + [] + let ``type check neg121`` () = singleNegTest (testConfig "typecheck/sigs") "neg121" + + [] + let ``type check neg122`` () = singleNegTest (testConfig "typecheck/sigs") "neg122" + + [] + let ``type check neg123`` () = singleNegTest (testConfig "typecheck/sigs") "neg123" + + [] + let ``type check neg124`` () = singleNegTest (testConfig "typecheck/sigs") "neg124" + + [] + let ``type check neg125`` () = singleNegTest (testConfig "typecheck/sigs") "neg125" + + [] + let ``type check neg126`` () = singleNegTest (testConfig "typecheck/sigs") "neg126" + + [] + let ``type check neg127`` () = singleNegTest (testConfig "typecheck/sigs") "neg127" + + [] + let ``type check neg128`` () = singleNegTest (testConfig "typecheck/sigs") "neg128" + + [] + let ``type check neg129`` () = singleNegTest (testConfig "typecheck/sigs") "neg129" + + [] + let ``type check neg130`` () = singleNegTest (testConfig "typecheck/sigs") "neg130" + + [] let ``type check neg_anon_1`` () = singleNegTest (testConfig "typecheck/sigs") "neg_anon_1" - [] + [] let ``type check neg_anon_2`` () = singleNegTest (testConfig "typecheck/sigs") "neg_anon_2" - [] + [] let ``type check neg_issue_3752`` () = singleNegTest (testConfig "typecheck/sigs") "neg_issue_3752" - [] + [] let ``type check neg_byref_1`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_1" - [] + [] let ``type check neg_byref_2`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_2" - [] + [] let ``type check neg_byref_3`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_3" - [] + [] let ``type check neg_byref_4`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_4" - [] + [] let ``type check neg_byref_5`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_5" - [] + [] let ``type check neg_byref_6`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_6" - [] + [] let ``type check neg_byref_7`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_7" - [] + [] let ``type check neg_byref_8`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_8" - [] + [] let ``type check neg_byref_10`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_10" - [] + [] let ``type check neg_byref_11`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_11" - [] + [] let ``type check neg_byref_12`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_12" - [] + [] let ``type check neg_byref_13`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_13" - [] + [] let ``type check neg_byref_14`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_14" - [] + [] let ``type check neg_byref_15`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_15" - [] + [] let ``type check neg_byref_16`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_16" - [] + [] let ``type check neg_byref_17`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_17" - [] + [] let ``type check neg_byref_18`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_18" - [] + [] let ``type check neg_byref_19`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_19" - [] + [] let ``type check neg_byref_20`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_20" - [] + [] let ``type check neg_byref_21`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_21" - [] + [] let ``type check neg_byref_22`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_22" - [] + [] let ``type check neg_byref_23`` () = singleNegTest (testConfig "typecheck/sigs") "neg_byref_23" - -module FscTests = +[] +module FscTests = [] - let ``should be raised if AssemblyInformationalVersion has invalid version`` () = + let ``should be raised if AssemblyInformationalVersion has invalid version`` () = let cfg = testConfig (Commands.createTempDir()) let code = @@ -2758,12 +3125,12 @@ open System.Reflection fv.ProductVersion |> Assert.areEqual "45.2048.main1.2-hotfix (upgrade Second Chance security)" - (fv.ProductMajorPart, fv.ProductMinorPart, fv.ProductBuildPart, fv.ProductPrivatePart) - |> Assert.areEqual (45,2048,0,0) + (fv.ProductMajorPart, fv.ProductMinorPart, fv.ProductBuildPart, fv.ProductPrivatePart) + |> Assert.areEqual (45, 2048, 0, 2) [] - let ``should set file version info on generated file`` () = + let ``should set file version info on generated file`` () = let cfg = testConfig (Commands.createTempDir()) let code = @@ -2792,19 +3159,20 @@ open System.Runtime.InteropServices let fv = System.Diagnostics.FileVersionInfo.GetVersionInfo(Commands.getfullpath cfg.Directory "lib.dll") fv.CompanyName |> Assert.areEqual "Compressed Space Transport" fv.FileVersion |> Assert.areEqual "99.88.77.66" - + (fv.FileMajorPart, fv.FileMinorPart, fv.FileBuildPart, fv.FilePrivatePart) |> Assert.areEqual (99,88,77,66) - + fv.ProductVersion |> Assert.areEqual "17.56.2912.14" - (fv.ProductMajorPart, fv.ProductMinorPart, fv.ProductBuildPart, fv.ProductPrivatePart) + (fv.ProductMajorPart, fv.ProductMinorPart, fv.ProductBuildPart, fv.ProductPrivatePart) |> Assert.areEqual (17,56,2912,14) - + fv.LegalCopyright |> Assert.areEqual "Copyright \u00A9 Compressed Space Transport 2380" fv.LegalTrademarks |> Assert.areEqual "CST \u2122" #endif #if NET472 +[] module ProductVersionTest = let informationalVersionAttrName = typeof.FullName @@ -2821,7 +3189,7 @@ module ProductVersionTest = [] let ``should use correct fallback``() = - + for (assemblyVersion, fileVersion, infoVersion, expected) in fallbackTestData () do let cfg = testConfig (Commands.createTempDir()) let dir = cfg.Directory @@ -2853,16 +3221,19 @@ namespace CST.RI.Anshun fileVersionInfo.ProductVersion |> Assert.areEqual expected module GeneratedSignatureTests = + [] + let ``libtest-GENERATED_SIGNATURE`` () = singleTestBuildAndRun "core/libtest" GENERATED_SIGNATURE + [] let ``members-basics-GENERATED_SIGNATURE`` () = singleTestBuildAndRun "core/members/basics" GENERATED_SIGNATURE - [] + [] let ``access-GENERATED_SIGNATURE``() = singleTestBuildAndRun "core/access" GENERATED_SIGNATURE [] let ``array-GENERATED_SIGNATURE``() = singleTestBuildAndRun "core/array" GENERATED_SIGNATURE - [] + [] let ``genericmeasures-GENERATED_SIGNATURE`` () = singleTestBuildAndRun "core/genericmeasures" GENERATED_SIGNATURE [] @@ -2872,19 +3243,38 @@ module GeneratedSignatureTests = let ``measures-GENERATED_SIGNATURE`` () = singleTestBuildAndRun "core/measures" GENERATED_SIGNATURE #endif -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS +#if !NETCOREAPP +[] module OverloadResolution = - module FSharpQAMigrated = + module ``fsharpqa migrated tests`` = let [] ``Conformance\Expressions\SyntacticSugar (E_Slices01.fs)`` () = singleNegTest (testConfig "conformance/expressions/syntacticsugar") "E_Slices01" - let [] ``Conformance\InferenceProcedures\TypeInference (E_OneTypeVariable03.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_OneTypeVariable03" - let [] ``Conformance\InferenceProcedures\TypeInference (E_OneTypeVariable03rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_OneTypeVariable03rec" - let [] ``Conformance\InferenceProcedures\TypeInference (E_TwoDifferentTypeVariables01.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariables01" - let [] ``Conformance\InferenceProcedures\TypeInference (E_TwoDifferentTypeVariables01rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariables01rec" - let [] ``Conformance\InferenceProcedures\TypeInference (E_TwoDifferentTypeVariablesGen00rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariablesGen00rec" - let [] ``Conformance\InferenceProcedures\TypeInference (E_TwoEqualTypeVariables02.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoEqualTypeVariables02" - let [] ``Conformance\InferenceProcedures\TypeInference (E_TwoEqualYypeVariables02rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoEqualYypeVariables02rec" - let [] ``Conformance\InferenceProcedures\TypeInference (E_LeftToRightOverloadResolution01.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_LeftToRightOverloadResolution01" - let [] ``Conformance\InferenceProcedures\WellFormednessChecking (E_Clashing_Values_in_AbstractClass01.fs) `` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass01" - let [] ``Conformance\InferenceProcedures\WellFormednessChecking (E_Clashing_Values_in_AbstractClass03.fs) `` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass03" - let [] ``Conformance\InferenceProcedures\WellFormednessChecking (E_Clashing_Values_in_AbstractClass04.fs) `` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass04" + let [] ``Conformance\Expressions\Type-relatedExpressions (E_RigidTypeAnnotation03.fsx)`` () = singleNegTest (testConfig "conformance/expressions/type-relatedexpressions") "E_RigidTypeAnnotation03" + let [] ``Conformance\Inference (E_OneTypeVariable03.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_OneTypeVariable03" + let [] ``Conformance\Inference (E_OneTypeVariable03rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_OneTypeVariable03rec" + let [] ``Conformance\Inference (E_TwoDifferentTypeVariablesGen00.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariablesGen00" + let [] ``Conformance\Inference (E_TwoDifferentTypeVariables01.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariables01" + let [] ``Conformance\Inference (E_TwoDifferentTypeVariables01rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariables01rec" + let [] ``Conformance\Inference (E_TwoDifferentTypeVariablesGen00rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoDifferentTypeVariablesGen00rec" + let [] ``Conformance\Inference (E_TwoEqualTypeVariables02.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoEqualTypeVariables02" + let [] ``Conformance\Inference (E_TwoEqualYypeVariables02rec.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_TwoEqualYypeVariables02rec" + let [] ``Conformance\Inference (E_LeftToRightOverloadResolution01.fs)`` () = singleNegTest (testConfig "conformance/inference") "E_LeftToRightOverloadResolution01" + let [] ``Conformance\WellFormedness (E_Clashing_Values_in_AbstractClass01.fs)`` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass01" + let [] ``Conformance\WellFormedness (E_Clashing_Values_in_AbstractClass03.fs)`` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass03" + let [] ``Conformance\WellFormedness (E_Clashing_Values_in_AbstractClass04.fs)`` () = singleNegTest (testConfig "conformance/wellformedness") "E_Clashing_Values_in_AbstractClass04" + // note: this test still exist in fsharpqa to assert the compiler doesn't crash + // the part of the code generating a flaky error due to https://github.com/dotnet/fsharp/issues/6725 + // is elided here to focus on overload resolution error messages + let [] ``Conformance\LexicalAnalysis\SymbolicOperators (E_LessThanDotOpenParen001.fs)`` () = singleNegTest (testConfig "conformance/lexicalanalysis") "E_LessThanDotOpenParen001" + + module ``error messages using BCL``= + let [] ``neg_System.Convert.ToString.OverloadList``() = singleNegTest (testConfig "typecheck/overloads") "neg_System.Convert.ToString.OverloadList" + let [] ``neg_System.Threading.Tasks.Task.Run.OverloadList``() = singleNegTest (testConfig "typecheck/overloads") "neg_System.Threading.Tasks.Task.Run.OverloadList" + let [] ``neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx``() = singleNegTest (testConfig "typecheck/overloads") "neg_System.Drawing.Graphics.DrawRectangleOverloadList" + + module ``ad hoc code overload error messages``= + let [] ``neg_many_many_overloads`` () = singleNegTest (testConfig "typecheck/overloads") "neg_many_many_overloads" + let [] ``neg_interface_generics`` () = singleNegTest (testConfig "typecheck/overloads") "neg_interface_generics" + let [] ``neg_known_return_type_and_known_type_arguments`` () = singleNegTest (testConfig "typecheck/overloads") "neg_known_return_type_and_known_type_arguments" + let [] ``neg_generic_known_argument_types`` () = singleNegTest (testConfig "typecheck/overloads") "neg_generic_known_argument_types" + let [] ``neg_tupled_arguments`` () = singleNegTest (testConfig "typecheck/overloads") "neg_tupled_arguments" #endif diff --git a/tests/fsharp/tools/eval/test.fsx b/tests/fsharp/tools/eval/test.fsx index e3545645b2e..a289c17794a 100644 --- a/tests/fsharp/tools/eval/test.fsx +++ b/tests/fsharp/tools/eval/test.fsx @@ -1193,35 +1193,35 @@ module EvaluationTests = module InlinedOperationsStillDynamicallyAvailableTests = - checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero @>) 0y - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0s - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0 - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0L - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0n - checkEval "vroievr093" (<@ LanguagePrimitives.GenericZero @>) 0uy - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0us - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0u - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0UL - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0un - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0.0 - checkEval "vroievr091" (<@ LanguagePrimitives.GenericZero @>) 0.0f - checkEval "vroievr092" (<@ LanguagePrimitives.GenericZero @>) 0M - - - - checkEval "vroievr093" (<@ LanguagePrimitives.GenericOne @>) 1y - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1s - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1 - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1L - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1n - checkEval "vroievr193" (<@ LanguagePrimitives.GenericOne @>) 1uy - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1us - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1u - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1UL - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1un - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1.0 - checkEval "vroievr191" (<@ LanguagePrimitives.GenericOne @>) 1.0f - checkEval "vroievr192" (<@ LanguagePrimitives.GenericOne @>) 1M + checkEval "vroievr091a" (<@ LanguagePrimitives.GenericZero @>) '\000' + checkEval "vroievr091b" (<@ LanguagePrimitives.GenericZero @>) 0y + checkEval "vroievr091c" (<@ LanguagePrimitives.GenericZero @>) 0s + checkEval "vroievr091d" (<@ LanguagePrimitives.GenericZero @>) 0 + checkEval "vroievr091e" (<@ LanguagePrimitives.GenericZero @>) 0L + checkEval "vroievr091f" (<@ LanguagePrimitives.GenericZero @>) 0n + checkEval "vroievr091g" (<@ LanguagePrimitives.GenericZero @>) 0uy + checkEval "vroievr091h" (<@ LanguagePrimitives.GenericZero @>) 0us + checkEval "vroievr091i" (<@ LanguagePrimitives.GenericZero @>) 0u + checkEval "vroievr091j" (<@ LanguagePrimitives.GenericZero @>) 0UL + checkEval "vroievr091k" (<@ LanguagePrimitives.GenericZero @>) 0un + checkEval "vroievr091l" (<@ LanguagePrimitives.GenericZero @>) 0.0 + checkEval "vroievr091m" (<@ LanguagePrimitives.GenericZero @>) 0.0f + checkEval "vroievr091n" (<@ LanguagePrimitives.GenericZero @>) 0M + + checkEval "vroievr092a" (<@ LanguagePrimitives.GenericOne @>) '\001' + checkEval "vroievr092b" (<@ LanguagePrimitives.GenericOne @>) 1y + checkEval "vroievr092c" (<@ LanguagePrimitives.GenericOne @>) 1s + checkEval "vroievr092d" (<@ LanguagePrimitives.GenericOne @>) 1 + checkEval "vroievr092e" (<@ LanguagePrimitives.GenericOne @>) 1L + checkEval "vroievr092f" (<@ LanguagePrimitives.GenericOne @>) 1n + checkEval "vroievr092g" (<@ LanguagePrimitives.GenericOne @>) 1uy + checkEval "vroievr092h" (<@ LanguagePrimitives.GenericOne @>) 1us + checkEval "vroievr092i" (<@ LanguagePrimitives.GenericOne @>) 1u + checkEval "vroievr092j" (<@ LanguagePrimitives.GenericOne @>) 1UL + checkEval "vroievr092k" (<@ LanguagePrimitives.GenericOne @>) 1un + checkEval "vroievr092l" (<@ LanguagePrimitives.GenericOne @>) 1.0 + checkEval "vroievr092m" (<@ LanguagePrimitives.GenericOne @>) 1.0f + checkEval "vroievr092n" (<@ LanguagePrimitives.GenericOne @>) 1M check "vroievr0971" (LanguagePrimitives.AdditionDynamic 3y 4y) 7y check "vroievr0972" (LanguagePrimitives.AdditionDynamic 3s 4s) 7s @@ -1461,6 +1461,268 @@ module EvaluationTests = + // Round dynamic dispatch on Decimal + checkEval "vrewoinrv09FF" (<@ round 2.3M @>) (round 2.3M) + + // Measure stuff: + checkEval "vrewoinrv09GG" (<@ atan2 3.0 4.0 @>) (atan2 3.0 4.0 ) + + [] + type kg + checkEval "vrewoinrv09HH" (<@ 1.0 @>) (1.0) + + // Measure stuff: + checkEval "vrewoinrv09JJ" (<@ 1.0 + 2.0 @>) (3.0) + + + Eval <@ Array.average [| 0.0 .. 1.0 .. 10000.0 |] @> + + module GenericInlinedOperationsStillDynamicallyAvailableTests = + + let inline test1 (x: 'T) = + checkEval ("vroievr093-(" + typeof<'T>.ToString() + ")") (<@ LanguagePrimitives.GenericZero<_> @>) x + + test1 0s + test1 0 + test1 0L + test1 0n + test1 0uy + test1 0us + test1 0u + test1 0UL + test1 0un + test1 0.0 + test1 0.0f + test1 0M + + let inline test2 (x: 'T) = + checkEval ("vroievr095f3-(" + typeof<'T>.ToString() + ")") (<@ LanguagePrimitives.GenericOne<_> @>) x + + test2 1s + test2 1 + test2 1L + test2 1n + test2 1uy + test2 1us + test2 1u + test2 1UL + test2 1un + test2 1.0 + test2 1.0f + test2 1M + + let inline test3 (x: 'T) y = + checkEval ("vroievr096cfqw-(" + typeof<'T>.ToString() + ")") (<@ x + y @>) (x + y) + + test3 3s 4s + test3 3L 4L + + let inline test4 (x: 'T) = + checkEval ("vroievrgerwwge41-(" + typeof<'T>.ToString() + ")") (<@ abs x @>) (abs x) + checkEval ("vroievrgerwwge42-(" + typeof<'T>.ToString() + ")") (<@ sin x @>) (sin x) + checkEval ("vroievrgerwwge43-(" + typeof<'T>.ToString() + ")") (<@ cos x @>) (cos x) + checkEval ("vroievrgerwwge44-(" + typeof<'T>.ToString() + ")") (<@ tan x @>) (tan x) + checkEval ("vroievrgerwwge45-(" + typeof<'T>.ToString() + ")") (<@ sinh x @>) (sinh x) + checkEval ("vroievrgerwwge46-(" + typeof<'T>.ToString() + ")") (<@ cosh x @>) (cosh x) + checkEval ("vroievrgerwwge47-(" + typeof<'T>.ToString() + ")") (<@ ceil x @>) (ceil x) + checkEval ("vroievrgerwwge49-(" + typeof<'T>.ToString() + ")") (<@ tanh x @>) (tanh x) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ floor x @>) (floor x) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ truncate x @>) (truncate x) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ round x @>) (round x) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ log (abs x) @>) (log (abs x)) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ sqrt (abs x) @>) (sqrt (abs x)) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ log10 (abs x) @>) (log10 (abs x)) + checkEval ("vroievrgerwwge48-(" + typeof<'T>.ToString() + ")") (<@ exp (abs x) @>) (exp (abs x)) + + test4 -1.1 + test4 -1.1f + + let inline test5 (x: 'T) y = + checkEval ("vrbrer096cfqw-(" + typeof<'T>.ToString() + ")") (<@ (fun x2 y2 -> x2 + y2) x y @>) (x + y) + + test5 3s 4s + test5 3L 4L + + let iarr = [| 0..1000 |] + let ilist = [ 0..1000 ] + + let farr = [| 0.0 .. 1.0 .. 100.0 |] + let flist = [ 0.0 .. 1.0 .. 100.0 ] + + Array.average farr + + checkEval "vrewoinrv091" (<@ farr.[0] @>) 0.0 + checkEval "vrewoinrv092" (<@ flist.[0] @>) 0.0 + checkEval "vrewoinrv093" (<@ iarr.[0] @>) 0 + checkEval "vrewoinrv094" (<@ ilist.[0] @>) 0 + + checkEval "vrewoinrv095" (<@ farr.[0] <- 0.0 @>) () + checkEval "vrewoinrv096" (<@ iarr.[0] <- 0 @>) () + + checkEval "vrewoinrv097" (<@ farr.[0] <- 1.0 @>) () + checkEval "vrewoinrv098" (<@ iarr.[0] <- 1 @>) () + + checkEval "vrewoinrv099" (<@ farr.[0] @>) 1.0 + checkEval "vrewoinrv09q" (<@ iarr.[0] @>) 1 + + checkEval "vrewoinrv09w" (<@ farr.[0] <- 0.0 @>) () + checkEval "vrewoinrv09e" (<@ iarr.[0] <- 0 @>) () + + + checkEval "vrewoinrv09r" (<@ Array.average farr @>) (Array.average farr) + checkEval "vrewoinrv09t" (<@ Array.sum farr @>) (Array.sum farr) + checkEval "vrewoinrv09y" (<@ Seq.sum farr @>) (Seq.sum farr) + checkEval "vrewoinrv09u" (<@ Seq.average farr @>) (Seq.average farr) + checkEval "vrewoinrv09i" (<@ Seq.average flist @>) (Seq.average flist) + checkEval "vrewoinrv09o" (<@ Seq.averageBy (fun x -> x) farr @> ) (Seq.averageBy (fun x -> x) farr ) + checkEval "vrewoinrv09p" (<@ Seq.averageBy (fun x -> x) flist @>) (Seq.averageBy (fun x -> x) flist ) + checkEval "vrewoinrv09a" (<@ Seq.averageBy float ilist @>) (Seq.averageBy float ilist) + checkEval "vrewoinrv09s" (<@ List.sum flist @>) (List.sum flist) + checkEval "vrewoinrv09d" (<@ List.average flist @>) (List.average flist) + checkEval "vrewoinrv09f" (<@ List.averageBy float ilist @>) (List.averageBy float ilist) + + checkEval "vrewoinrv09g1" (<@ compare 0 0 = 0 @>) true + checkEval "vrewoinrv09g2" (<@ compare 0 1 < 0 @>) true + checkEval "vrewoinrv09g3" (<@ compare 1 0 > 0 @>) true + checkEval "vrewoinrv09g4" (<@ 0 < 1 @>) true + checkEval "vrewoinrv09g5" (<@ 0 <= 1 @>) true + checkEval "vrewoinrv09g6" (<@ 1 <= 1 @>) true + checkEval "vrewoinrv09g7" (<@ 2 <= 1 @>) false + checkEval "vrewoinrv09g8" (<@ 0 > 1 @>) false + checkEval "vrewoinrv09g9" (<@ 0 >= 1 @>) false + checkEval "vrewoinrv09g0" (<@ 1 >= 1 @>) true + checkEval "vrewoinrv09gQ" (<@ 2 >= 1 @>) true + + checkEval "vrewoinrv09gw" (<@ compare 0.0 0.0 = 0 @>) true + checkEval "vrewoinrv09ge" (<@ compare 0.0 1.0 < 0 @>) true + checkEval "vrewoinrv09gr" (<@ compare 1.0 0.0 > 0 @>) true + checkEval "vrewoinrv09gt" (<@ 0.0 < 1.0 @>) true + checkEval "vrewoinrv09gy" (<@ 0.0 <= 1.0 @>) true + checkEval "vrewoinrv09gu" (<@ 1.0 <= 1.0 @>) true + checkEval "vrewoinrv09gi" (<@ 2.0 <= 1.0 @>) false + checkEval "vrewoinrv09go" (<@ 0.0 > 1.0 @>) false + checkEval "vrewoinrv09gp" (<@ 0.0 >= 1.0 @>) false + checkEval "vrewoinrv09ga" (<@ 1.0 >= 1.0 @>) true + checkEval "vrewoinrv09gs" (<@ 2.0 >= 1.0 @>) true + + checkEval "vrewoinrv09gd" (<@ compare 0.0f 0.0f = 0 @>) true + checkEval "vrewoinrv09gf" (<@ compare 0.0f 1.0f < 0 @>) true + checkEval "vrewoinrv09gg" (<@ compare 1.0f 0.0f > 0 @>) true + checkEval "vrewoinrv09gh" (<@ 0.0f < 1.0f @>) true + checkEval "vrewoinrv09gk" (<@ 0.0f <= 1.0f @>) true + checkEval "vrewoinrv09gl" (<@ 1.0f <= 1.0f @>) true + checkEval "vrewoinrv09gz" (<@ 2.0f <= 1.0f @>) false + checkEval "vrewoinrv09gx" (<@ 0.0f > 1.0f @>) false + checkEval "vrewoinrv09gc" (<@ 0.0f >= 1.0f @>) false + checkEval "vrewoinrv09gv" (<@ 1.0f >= 1.0f @>) true + checkEval "vrewoinrv09gb" (<@ 2.0f >= 1.0f @>) true + + checkEval "vrewoinrv09gn" (<@ compare 0L 0L = 0 @>) true + checkEval "vrewoinrv09gm" (<@ compare 0L 1L < 0 @>) true + checkEval "vrewoinrv09g11" (<@ compare 1L 0L > 0 @>) true + checkEval "vrewoinrv09g12" (<@ 0L < 1L @>) true + checkEval "vrewoinrv09g13" (<@ 0L <= 1L @>) true + checkEval "vrewoinrv09g14" (<@ 1L <= 1L @>) true + checkEval "vrewoinrv09g15" (<@ 2L <= 1L @>) false + checkEval "vrewoinrv09g16" (<@ 0L > 1L @>) false + checkEval "vrewoinrv09g17" (<@ 0L >= 1L @>) false + checkEval "vrewoinrv09g18" (<@ 1L >= 1L @>) true + checkEval "vrewoinrv09g19" (<@ 2L >= 1L @>) true + + checkEval "vrewoinrv09g21" (<@ compare 0y 0y = 0 @>) true + checkEval "vrewoinrv09g22" (<@ compare 0y 1y < 0 @>) true + checkEval "vrewoinrv09g23" (<@ compare 1y 0y > 0 @>) true + checkEval "vrewoinrv09g24" (<@ 0y < 1y @>) true + checkEval "vrewoinrv09g25" (<@ 0y <= 1y @>) true + checkEval "vrewoinrv09g26" (<@ 1y <= 1y @>) true + checkEval "vrewoinrv09g27" (<@ 2y <= 1y @>) false + checkEval "vrewoinrv09g28" (<@ 0y > 1y @>) false + checkEval "vrewoinrv09g29" (<@ 0y >= 1y @>) false + checkEval "vrewoinrv09g30" (<@ 1y >= 1y @>) true + checkEval "vrewoinrv09g31" (<@ 2y >= 1y @>) true + + checkEval "vrewoinrv09g32" (<@ compare 0M 0M = 0 @>) true + checkEval "vrewoinrv09g33" (<@ compare 0M 1M < 0 @>) true + checkEval "vrewoinrv09g34" (<@ compare 1M 0M > 0 @>) true + checkEval "vrewoinrv09g35" (<@ 0M < 1M @>) true + checkEval "vrewoinrv09g36" (<@ 0M <= 1M @>) true + checkEval "vrewoinrv09g37" (<@ 1M <= 1M @>) true + checkEval "vrewoinrv09g38" (<@ 2M <= 1M @>) false + checkEval "vrewoinrv09g39" (<@ 0M > 1M @>) false + checkEval "vrewoinrv09g40" (<@ 0M >= 1M @>) false + checkEval "vrewoinrv09g41" (<@ 1M >= 1M @>) true + checkEval "vrewoinrv09g42" (<@ 2M >= 1M @>) true + + checkEval "vrewoinrv09g43" (<@ compare 0I 0I = 0 @>) true + checkEval "vrewoinrv09g44" (<@ compare 0I 1I < 0 @>) true + checkEval "vrewoinrv09g45" (<@ compare 1I 0I > 0 @>) true + checkEval "vrewoinrv09g46" (<@ 0I < 1I @>) true + checkEval "vrewoinrv09g47" (<@ 0I <= 1I @>) true + checkEval "vrewoinrv09g48" (<@ 1I <= 1I @>) true + checkEval "vrewoinrv09g49" (<@ 2I <= 1I @>) false + checkEval "vrewoinrv09g50" (<@ 0I > 1I @>) false + checkEval "vrewoinrv09g51" (<@ 0I >= 1I @>) false + checkEval "vrewoinrv09g52" (<@ 1I >= 1I @>) true + checkEval "vrewoinrv09g53" (<@ 2I >= 1I @>) true + + + checkEval "vrewoinrv09g" (<@ sin 0.0 @>) (sin 0.0) + checkEval "vrewoinrv09h" (<@ sinh 0.0 @>) (sinh 0.0) + checkEval "vrewoinrv09j" (<@ cos 0.0 @>) (cos 0.0) + checkEval "vrewoinrv09k" (<@ cosh 0.0 @>) (cosh 0.0) + checkEval "vrewoinrv09l" (<@ tan 1.0 @>) (tan 1.0) + checkEval "vrewoinrv09z" (<@ tanh 1.0 @>) (tanh 1.0) + checkEval "vrewoinrv09x" (<@ abs -2.0 @>) (abs -2.0) + checkEval "vrewoinrv09c" (<@ ceil 2.0 @>) (ceil 2.0) + checkEval "vrewoinrv09v" (<@ sqrt 2.0 @>) (sqrt 2.0) + checkEval "vrewoinrv09b" (<@ sign 2.0 @>) (sign 2.0) + checkEval "vrewoinrv09n" (<@ truncate 2.3 @>) (truncate 2.3) + checkEval "vrewoinrv09m" (<@ floor 2.3 @>) (floor 2.3) + checkEval "vrewoinrv09Q" (<@ round 2.3 @>) (round 2.3) + checkEval "vrewoinrv09W" (<@ log 2.3 @>) (log 2.3) + checkEval "vrewoinrv09E" (<@ log10 2.3 @>) (log10 2.3) + checkEval "vrewoinrv09R" (<@ exp 2.3 @>) (exp 2.3) + checkEval "vrewoinrv09T" (<@ 2.3 ** 2.4 @>) (2.3 ** 2.4) + + checkEval "vrewoinrv09Y" (<@ sin 0.0f @>) (sin 0.0f) + checkEval "vrewoinrv09U" (<@ sinh 0.0f @>) (sinh 0.0f) + checkEval "vrewoinrv09I" (<@ cos 0.0f @>) (cos 0.0f) + checkEval "vrewoinrv09O" (<@ cosh 0.0f @>) (cosh 0.0f) + checkEval "vrewoinrv09P" (<@ tan 1.0f @>) (tan 1.0f) + checkEval "vrewoinrv09A" (<@ tanh 1.0f @>) (tanh 1.0f) + checkEval "vrewoinrv09S" (<@ abs -2.0f @>) (abs -2.0f) + checkEval "vrewoinrv09D" (<@ ceil 2.0f @>) (ceil 2.0f) + checkEval "vrewoinrv09F" (<@ sqrt 2.0f @>) (sqrt 2.0f) + checkEval "vrewoinrv09G" (<@ sign 2.0f @>) (sign 2.0f) + checkEval "vrewoinrv09H" (<@ truncate 2.3f @>) (truncate 2.3f) + checkEval "vrewoinrv09J" (<@ floor 2.3f @>) (floor 2.3f) + checkEval "vrewoinrv09K" (<@ round 2.3f @>) (round 2.3f) + checkEval "vrewoinrv09L" (<@ log 2.3f @>) (log 2.3f) + checkEval "vrewoinrv09Z" (<@ log10 2.3f @>) (log10 2.3f) + checkEval "vrewoinrv09X" (<@ exp 2.3f @>) (exp 2.3f) + checkEval "vrewoinrv09C" (<@ 2.3f ** 2.4f @>) (2.3f ** 2.4f) + + checkEval "vrewoinrv09V" (<@ ceil 2.0M @>) (ceil 2.0M) + checkEval "vrewoinrv09B" (<@ sign 2.0M @>) (sign 2.0M) + checkEval "vrewoinrv09N" (<@ truncate 2.3M @>) (truncate 2.3M) + checkEval "vrewoinrv09M" (<@ floor 2.3M @>) (floor 2.3M) + + checkEval "vrewoinrv09QQ" (<@ sign -2 @>) (sign -2) + checkEval "vrewoinrv09WW" (<@ sign -2y @>) (sign -2y) + checkEval "vrewoinrv09EE" (<@ sign -2s @>) (sign -2s) + checkEval "vrewoinrv09RR" (<@ sign -2L @>) (sign -2L) + + checkEval "vrewoinrv09TT" (<@ [ 0 .. 10 ] @>) [ 0 .. 10 ] + checkEval "vrewoinrv09YY" (<@ [ 0y .. 10y ] @>) [ 0y .. 10y ] + checkEval "vrewoinrv09UU" (<@ [ 0s .. 10s ] @>) [ 0s .. 10s ] + checkEval "vrewoinrv09II" (<@ [ 0L .. 10L ] @>) [ 0L .. 10L ] + checkEval "vrewoinrv09OO" (<@ [ 0u .. 10u ] @>) [ 0u .. 10u ] + checkEval "vrewoinrv09PP" (<@ [ 0uy .. 10uy ] @>) [ 0uy .. 10uy ] + checkEval "vrewoinrv09AA" (<@ [ 0us .. 10us ] @>) [ 0us .. 10us ] + checkEval "vrewoinrv09SS" (<@ [ 0UL .. 10UL ] @>) [ 0UL .. 10UL ] + + + // Round dynamic dispatch on Decimal checkEval "vrewoinrv09FF" (<@ round 2.3M @>) (round 2.3M) @@ -1488,6 +1750,15 @@ module EvaluationTests = checkEval "castingunits5" (<@ 2L |> LanguagePrimitives.Int64WithMeasure |> int64 @>) 2L checkEval "castingunits6" (<@ 2s |> LanguagePrimitives.Int16WithMeasure |> int16 @>) 2s checkEval "castingunits7" (<@ 2y |> LanguagePrimitives.SByteWithMeasure |> sbyte @>) 2y + checkEval "castingunits8" (<@ 2ul |> LanguagePrimitives.UInt32WithMeasure |> uint32 @>) 2ul + checkEval "castingunits9" (<@ 2UL |> LanguagePrimitives.UInt64WithMeasure |> uint64 @>) 2UL + checkEval "castingunits10" (<@ 2us |> LanguagePrimitives.UInt16WithMeasure |> uint16 @>) 2us + checkEval "castingunits11" (<@ 2uy |> LanguagePrimitives.ByteWithMeasure |> byte @>) 2uy + + //NOTE quotations currently *DO NOT* support native integers + //TODO revisit when the test scaffolding is changed/migrated! + // checkEval "castingunits12" (<@ 2n |> LanguagePrimitives.IntPtrWithMeasure |> nativeint @>) 2n + // checkEval "castingunits13" (<@ 2un |> unativeint |> LanguagePrimitives.UIntPtrWithMeasure |> unativeint @>) 2un module QuotationTests = open Microsoft.FSharp.Quotations @@ -2014,7 +2285,7 @@ module Query = F ([srcTy],[src]) let MakeQueryableTake = - let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Take @> + let F = MakeGenericStaticMethod <@ System.Linq.Queryable.Take : _ * int -> _ @> fun (srcTy,src,count) -> let src = Expr.Coerce(src,MakeIQueryableTy srcTy) F ([srcTy],[src;count]) @@ -2497,4 +2768,3 @@ let _ = stdout.WriteLine "Test Passed"; System.IO.File.WriteAllText("test.ok","ok"); exit 0 - diff --git a/tests/fsharp/tools/fsharp41/net45/providerDesigner.dll b/tests/fsharp/tools/fsharp41/net45/providerDesigner.dll new file mode 100644 index 00000000000..7dc9ab96355 Binary files /dev/null and b/tests/fsharp/tools/fsharp41/net45/providerDesigner.dll differ diff --git a/tests/fsharp/tools/fsharp41/net461/providerDesigner.dll b/tests/fsharp/tools/fsharp41/net461/providerDesigner.dll new file mode 100644 index 00000000000..7e7821bdd45 Binary files /dev/null and b/tests/fsharp/tools/fsharp41/net461/providerDesigner.dll differ diff --git a/tests/fsharp/tools/fsharp41/netstandard2.0/providerDesigner.dll b/tests/fsharp/tools/fsharp41/netstandard2.0/providerDesigner.dll new file mode 100644 index 00000000000..c3d2de6083b Binary files /dev/null and b/tests/fsharp/tools/fsharp41/netstandard2.0/providerDesigner.dll differ diff --git a/tests/fsharp/typeProviders/fsharp41/net45/providerDesigner.dll b/tests/fsharp/typeProviders/fsharp41/net45/providerDesigner.dll new file mode 100644 index 00000000000..569260eff75 Binary files /dev/null and b/tests/fsharp/typeProviders/fsharp41/net45/providerDesigner.dll differ diff --git a/tests/fsharp/typeProviders/fsharp41/net461/providerDesigner.dll b/tests/fsharp/typeProviders/fsharp41/net461/providerDesigner.dll new file mode 100644 index 00000000000..3e45a70c53b Binary files /dev/null and b/tests/fsharp/typeProviders/fsharp41/net461/providerDesigner.dll differ diff --git a/tests/fsharp/typeProviders/fsharp41/netstandard2.0/providerDesigner.dll b/tests/fsharp/typeProviders/fsharp41/netstandard2.0/providerDesigner.dll new file mode 100644 index 00000000000..8bfed32f1c5 Binary files /dev/null and b/tests/fsharp/typeProviders/fsharp41/netstandard2.0/providerDesigner.dll differ diff --git a/tests/fsharp/typeProviders/helloWorld/provided.fs b/tests/fsharp/typeProviders/helloWorld/provided.fs index bcdc86452eb..4601e26f89a 100644 --- a/tests/fsharp/typeProviders/helloWorld/provided.fs +++ b/tests/fsharp/typeProviders/helloWorld/provided.fs @@ -196,5 +196,5 @@ module TheOuterType = module DllImportSmokeTest = [] - extern System.UInt32 private GetLastError() + extern System.UInt32 GetLastError() diff --git a/tests/fsharp/typeProviders/helloWorld/test.fsx b/tests/fsharp/typeProviders/helloWorld/test.fsx index 1a38103ba6a..891fa7fdbe1 100644 --- a/tests/fsharp/typeProviders/helloWorld/test.fsx +++ b/tests/fsharp/typeProviders/helloWorld/test.fsx @@ -760,6 +760,9 @@ module String = check "vlkrrevpojvr1" FSharp.HelloWorld.HelloWorldTypeWithStaticStringParameter<"10000">.StaticProperty1 "You got a static property" + check "vlkrrevpojvr1c" + FSharp.HelloWorld.HelloWorldTypeWithStaticStringParameter<__SOURCE_DIRECTORY__>.StaticProperty1 + "You got a static property" module Bool = check "vlkrrevpojvr1" diff --git a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.bsl b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.bsl index 7962c96169d..67d18357023 100644 --- a/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.bsl +++ b/tests/fsharp/typeProviders/negTests/EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.bsl @@ -5,4 +5,4 @@ EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.fsx(6,39,6,14 EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.fsx(8,41,8,58): typecheck error FS0039: The type 'TheGeneratedTypeJ' is not defined. -EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.fsx(8,79,8,96): typecheck error FS0039: The field, constructor or member 'TheGeneratedTypeJ' is not defined. +EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments.fsx(8,79,8,96): typecheck error FS0039: The type 'Object' does not define the field, constructor or member 'TheGeneratedTypeJ'. diff --git a/tests/fsharp/typeProviders/negTests/ProviderAttributeErrorConsume.bslpp b/tests/fsharp/typeProviders/negTests/ProviderAttributeErrorConsume.bslpp index 59ee16d380b..b2073904818 100644 --- a/tests/fsharp/typeProviders/negTests/ProviderAttributeErrorConsume.bslpp +++ b/tests/fsharp/typeProviders/negTests/ProviderAttributeErrorConsume.bslpp @@ -1,4 +1,4 @@ -providerAttributeErrorConsume.fsx(1,1,1,48): parse error FS3031: The type provider '' reported an error: Assembly attribute 'TypeProviderAssemblyAttribute' refers to a designer assembly 'Invalid.Assembly.Name' which cannot be loaded or doesn't exist. Could not load file or assembly 'Invalid.Assembly.Name.dll' or one of its dependencies. The system cannot find the file specified. +providerAttributeErrorConsume.fsx(1,1,1,48): parse error FS3031: The type provider '' reported an error: Assembly attribute 'TypeProviderAssemblyAttribute' refers to a designer assembly 'Invalid.Assembly.Name' which cannot be loaded from path 'Invalid.Assembly.Name.dll'. The exception reported was: System.IO.FileNotFoundException - Could not load file or assembly 'Invalid.Assembly.Name.dll' or one of its dependencies. The system cannot find the file specified. providerAttributeErrorConsume.fsx(1,1,1,48): parse error FS3005: Referenced assembly '' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found diff --git a/tests/fsharp/typeProviders/negTests/neg1.bsl b/tests/fsharp/typeProviders/negTests/neg1.bsl index ac639a9095c..8572d60442e 100644 --- a/tests/fsharp/typeProviders/negTests/neg1.bsl +++ b/tests/fsharp/typeProviders/negTests/neg1.bsl @@ -29,7 +29,6 @@ neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilP neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - IsArrayTypeRaisesException neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes @@ -41,7 +40,6 @@ neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilP neg1.fsx(11,38,11,66): typecheck error FS3072: The type provider 'Provider.EvilProvider' reported an error: An exception occurred when accessing the 'Name' of a provided type: deliberate error for testing purposes neg1.fsx(11,38,11,66): typecheck error FS0039: The type 'TypeWhereNameRaisesException' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - IsArrayTypeRaisesException neg1.fsx(12,38,12,62): typecheck error FS3073: The type provider 'Provider.EvilProvider' reported an error: The 'Name' of a provided type was null or empty. @@ -305,7 +303,6 @@ neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provide neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes @@ -317,7 +314,6 @@ neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provide neg1.fsx(25,39,25,78): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsRaisesException' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: deliberate error for testing purposes neg1.fsx(25,39,25,78): typecheck error FS0039: The type 'TypeWhereGetConstructorsRaisesException' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods' @@ -329,7 +325,6 @@ neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provide neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods' neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods' @@ -341,7 +336,6 @@ neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provide neg1.fsx(27,39,27,69): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetMethodsReturnsNull' member 'GetMethods': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetMethods' neg1.fsx(27,39,27,69): typecheck error FS0039: The type 'TypeWhereGetMethodsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents' @@ -353,7 +347,6 @@ neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provide neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents' neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents' @@ -365,7 +358,6 @@ neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provide neg1.fsx(28,39,28,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetEventsReturnsNull' member 'GetEvents': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetEvents' neg1.fsx(28,39,28,68): typecheck error FS0039: The type 'TypeWhereGetEventsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields' @@ -377,7 +369,6 @@ neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provide neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields' neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields' @@ -389,7 +380,6 @@ neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provide neg1.fsx(29,39,29,68): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetFieldsReturnsNull' member 'GetFields': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetFields' neg1.fsx(29,39,29,68): typecheck error FS0039: The type 'TypeWhereGetFieldsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties' @@ -401,7 +391,6 @@ neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provide neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties' neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties' @@ -413,7 +402,6 @@ neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provide neg1.fsx(30,39,30,72): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetPropertiesReturnsNull' member 'GetProperties': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetProperties' neg1.fsx(30,39,30,72): typecheck error FS0039: The type 'TypeWhereGetPropertiesReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesRaisesException neg1.fsx(31,39,31,73): typecheck error FS3004: The provided type 'FSharp.EvilProvider.TypeWhereGetNestedTypesReturnsNull' has member 'Boo' which has declaring type 'FSharp.EvilProvider.TheType'. Expected declaring type to be the same as provided type. @@ -429,9 +417,7 @@ neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provide neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors' neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesReturnsNull - TypeWhereGetNestedTypesRaisesException neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors' @@ -443,9 +429,7 @@ neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provide neg1.fsx(32,39,32,74): typecheck error FS3021: Unexpected exception from provided type 'FSharp.EvilProvider.TypeWhereGetConstructorsReturnsNull' member 'GetConstructors': The type provider 'Provider.EvilProvider' reported an error: The type provider returned 'null', which is not a valid return value from 'GetConstructors' neg1.fsx(32,39,32,74): typecheck error FS0039: The type 'TypeWhereGetConstructorsReturnsNull' is not defined in 'FSharp.EvilProvider'. Maybe you want one of the following: - TypeWhereGetNestedTypesReturnsNull - TypeWhereGetNestedTypesRaisesException neg1.fsx(33,39,33,72): typecheck error FS3042: Unexpected 'null' return value from provided type 'FSharp.EvilProvider.TypeWhereGetInterfacesReturnsNull' member 'GetInterfaces' @@ -1374,7 +1358,7 @@ neg1.fsx(341,110,341,114): typecheck error FS0001: This expression was expected but here has type 'bool' -neg1.fsx(342,110,342,114): typecheck error FS3045: Invalid static argument to provided type. Expected an argument of kind 'string'. +neg1.fsx(342,104,342,114): typecheck error FS3045: Invalid static argument to provided type. Expected an argument of kind 'string'. neg1.fsx(345,104,345,106): typecheck error FS3045: Invalid static argument to provided type. Expected an argument of kind 'float'. @@ -1654,22 +1638,16 @@ neg1.fsx(438,109,438,110): typecheck error FS0001: This expression was expected but here has type 'string' -neg1.fsx(438,9,438,111): typecheck error FS3033: The type provider 'Provider.GoodProviderForNegativeStaticParameterTypeTests' reported an error: Specified cast is not valid. - neg1.fsx(440,119,440,120): typecheck error FS0001: This expression was expected to have type 'int' but here has type 'string' -neg1.fsx(440,19,440,121): typecheck error FS3033: The type provider 'Provider.GoodProviderForNegativeStaticParameterTypeTests' reported an error: Specified cast is not valid. - neg1.fsx(440,119,440,120): typecheck error FS0001: This expression was expected to have type 'int' but here has type 'string' -neg1.fsx(440,19,440,121): typecheck error FS3033: The type provider 'Provider.GoodProviderForNegativeStaticParameterTypeTests' reported an error: Specified cast is not valid. - neg1.fsx(448,9,448,107): typecheck error FS3148: Too many static parameters. Expected at most 1 parameters, but got 2 unnamed and 0 named parameters. neg1.fsx(449,105,449,110): typecheck error FS3083: The static parameter 'Count' has already been given a value diff --git a/tests/fsharp/typeProviders/negTests/neg2.bsl b/tests/fsharp/typeProviders/negTests/neg2.bsl index c6d55da6a6c..94c5fb792a7 100644 --- a/tests/fsharp/typeProviders/negTests/neg2.bsl +++ b/tests/fsharp/typeProviders/negTests/neg2.bsl @@ -4,5 +4,4 @@ neg2.fsx(3,59,3,66): typecheck error FS3033: The type provider 'Provider.GoodPro neg2.fsx(3,59,3,66): typecheck error FS3033: The type provider 'Provider.GoodProviderForNegativeTypeTests1' reported an error: Kaboom neg2.fsx(3,59,3,66): typecheck error FS0039: The value, constructor, namespace or type 'TheHype' is not defined. Maybe you want one of the following: - TheType diff --git a/tests/fsharp/typeProviders/negTests/neg2c.bsl b/tests/fsharp/typeProviders/negTests/neg2c.bsl index 866b4c826c9..4db9de30d0e 100644 --- a/tests/fsharp/typeProviders/negTests/neg2c.bsl +++ b/tests/fsharp/typeProviders/negTests/neg2c.bsl @@ -1,2 +1,2 @@ -neg2c.fsx(6,5,6,7): typecheck error FS0410: The type 'TheGeneratedType1' is less accessible than the value, member or type 'val f2 : unit -> TheGeneratedType1' it is used in. +neg2c.fsx(6,5,6,7): typecheck error FS0410: The type 'TheGeneratedType1' is less accessible than the value, member or type 'val f2: unit -> TheGeneratedType1' it is used in. diff --git a/tests/fsharp/typecheck/constructors/neg_invalid_constructor.bsl b/tests/fsharp/typecheck/constructors/neg_invalid_constructor.bsl new file mode 100644 index 00000000000..3b2777c1504 --- /dev/null +++ b/tests/fsharp/typecheck/constructors/neg_invalid_constructor.bsl @@ -0,0 +1,22 @@ +typecheck/constructors/neg_invalid_constructor.fs (3,29)-(3,56) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new : col:'b -> ImmutableStack<'a> + - private new : items:'a list -> ImmutableStack<'a> +typecheck/constructors/neg_invalid_constructor.fs (4,93)-(4,111) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new : col:'b -> ImmutableStack<'a> + - private new : items:'a list -> ImmutableStack<'a> +typecheck/constructors/neg_invalid_constructor.fs (7,30)-(7,60) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a list + +Candidates: + - new : col:'b -> ImmutableStack<'a> when 'b :> seq<'c> + - private new : items:'a list -> ImmutableStack<'a> +typecheck/constructors/neg_invalid_constructor.fs (7,30)-(7,60) typecheck error This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor. \ No newline at end of file diff --git a/tests/fsharp/typecheck/constructors/neg_invalid_constructor.fs b/tests/fsharp/typecheck/constructors/neg_invalid_constructor.fs new file mode 100644 index 00000000000..02be510295d --- /dev/null +++ b/tests/fsharp/typecheck/constructors/neg_invalid_constructor.fs @@ -0,0 +1,7 @@ +type ImmutableStack<'a> private(items: 'a list) = + + member this.Push item = ImmutableStack(item::items) + member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs) + + // Notice type annotation is commented out, which results in an error + new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col) diff --git a/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.bsl b/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.bsl new file mode 100644 index 00000000000..54fe7678dff --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.bsl @@ -0,0 +1,48 @@ + +neg_System.Convert.ToString.OverloadList.fsx(1,1,1,31): typecheck error FS0041: No overloads match for method 'ToString'. + +Known types of arguments: char * int + +Available overloads: + - System.Convert.ToString(value: System.DateTime, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: bool, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: byte, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: byte, toBase: int) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: char, provider: System.IFormatProvider) : string // Argument 'provider' doesn't match + - System.Convert.ToString(value: decimal, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: float, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: float32, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int, toBase: int) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int16, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int16, toBase: int) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int64, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int64, toBase: int) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: obj, provider: System.IFormatProvider) : string // Argument 'provider' doesn't match + - System.Convert.ToString(value: sbyte, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: string, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint16, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint32, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint64, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + +neg_System.Convert.ToString.OverloadList.fsx(2,1,2,47): typecheck error FS0041: No overloads match for method 'ToString'. + +Known types of arguments: provider: char * value: int + +Available overloads: + - System.Convert.ToString(value: System.DateTime, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: bool, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: byte, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: char, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: decimal, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: float, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: float32, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int, provider: System.IFormatProvider) : string // Argument 'provider' doesn't match + - System.Convert.ToString(value: int16, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: int64, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: obj, provider: System.IFormatProvider) : string // Argument 'provider' doesn't match + - System.Convert.ToString(value: sbyte, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: string, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint16, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint32, provider: System.IFormatProvider) : string // Argument 'value' doesn't match + - System.Convert.ToString(value: uint64, provider: System.IFormatProvider) : string // Argument 'value' doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.fsx b/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.fsx new file mode 100644 index 00000000000..be91d10893c --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Convert.ToString.OverloadList.fsx @@ -0,0 +1,4 @@ +System.Convert.ToString('a',0) |> ignore +System.Convert.ToString(provider='a', value=0) |> ignore +System.Convert.ToString(provider=null, value=0) |> ignore +;; \ No newline at end of file diff --git a/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.bsl b/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.bsl new file mode 100644 index 00000000000..cfa6d36b91b --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.bsl @@ -0,0 +1,16 @@ + +neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx(9,1,9,31): typecheck error FS0041: No overloads match for method 'DrawRectangle'. + +Known types of arguments: Pen * float32 * float32 * float32 * int + +Available overloads: + - Graphics.DrawRectangle(pen: Pen, x: float32, y: float32, width: float32, height: float32) : unit // Argument 'height' doesn't match + - Graphics.DrawRectangle(pen: Pen, x: int, y: int, width: int, height: int) : unit // Argument 'x' doesn't match + +neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx(10,1,10,32): typecheck error FS0041: No overloads match for method 'DrawRectangle'. + +Known types of arguments: Pen * int * float32 * float32 * decimal + +Available overloads: + - Graphics.DrawRectangle(pen: Pen, x: float32, y: float32, width: float32, height: float32) : unit // Argument 'x' doesn't match + - Graphics.DrawRectangle(pen: Pen, x: int, y: int, width: int, height: int) : unit // Argument 'y' doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx b/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx new file mode 100644 index 00000000000..e0069481662 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Drawing.Graphics.DrawRectangleOverloadList.fsx @@ -0,0 +1,10 @@ +open System.Drawing +let g : Graphics = null +let p : Pen = null +let x = 1.f +let y = 1.f +let w = 1.f +let h = 1 + +g.DrawRectangle(p, x, y, w, h) +g.DrawRectangle(p, 4, y, w, 5m) \ No newline at end of file diff --git a/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.bsl b/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.bsl new file mode 100644 index 00000000000..c004363a8f2 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.bsl @@ -0,0 +1,48 @@ + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(5,11,5,35): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: (unit -> Task) + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(6,11,6,44): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: Func> + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(7,11,7,47): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: Func> + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(8,21,8,57): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: Func> + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(9,11,9,50): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: Func> + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> + +neg_System.Threading.Tasks.Task.Run.OverloadList.fsx(10,11,10,52): typecheck error FS0041: A unique overload for method 'Run' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: Func> + +Candidates: + - Task.Run<'TResult>(``function`` : Func<'TResult>) : Task<'TResult> + - Task.Run<'TResult>(``function`` : Func>) : Task<'TResult> diff --git a/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.fsx b/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.fsx new file mode 100644 index 00000000000..0d44ca44b8b --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_System.Threading.Tasks.Task.Run.OverloadList.fsx @@ -0,0 +1,14 @@ +open System +open System.Threading.Tasks +let makeTask () = new Task<_>(fun () -> 1) +let task = makeTask() +let rt1 = Task.Run(fun () -> task) +let rt2 = Task.Run(Func<_>(fun () -> task)) +let rt3 = Task.Run<_>(Func<_>(fun () -> task)) +let rt4 : Task<_> = Task.Run<_>(Func<_>(fun () -> task)) +let rt5 = Task.Run(Func>(fun () -> task)) +let rt6 = Task.Run(Func>(fun () -> task)) +let rt7 = Task.Run(Func>(fun () -> task)) +let rt8 = Task.Run(Func>(fun () -> task)) +let rt9 = Task.Run(Func<_>(fun () -> task)) +let rt10 = Task.Run(fun () -> task) diff --git a/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl new file mode 100644 index 00000000000..ee9b9d3dde2 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.bsl @@ -0,0 +1,8 @@ + +neg_generic_known_argument_types.fsx(9,16,9,49): typecheck error FS0041: A unique overload for method 'Foo' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: ^fa * 'fb * 'a * argD: 'c when ^fa: (member X: ^fa * ^b -> ^b) and ^b: (member BBBB: ^b -> unit) + +Candidates: + - static member A.Foo: argA1: 'a * argB1: ('a -> 'b) * argC1: ('a -> 'b) * argD: ('a -> 'b) * argZ1: 'zzz -> 'b + - static member A.Foo: argA2: 'a * argB2: ('a -> 'b) * argC2: ('b -> 'c) * argD: ('c -> 'd) * argZ2: 'zzz -> 'd diff --git a/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.fsx b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.fsx new file mode 100644 index 00000000000..60b76f772ab --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_generic_known_argument_types.fsx @@ -0,0 +1,10 @@ +open System.Runtime.InteropServices + +type A<'zzz> = + static member Foo(argA1: 'a, argB1: 'a -> 'b) : 'b = argB1 argA1 + static member Foo(argA1: 'a, argB1: 'a -> 'b, argC1: 'a -> 'b, argD: 'a -> 'b, [] argZ1: 'zzz) : 'b = argB1 argA1 + static member Foo(argA2: 'a, argB2: 'a -> 'b, argC2: 'b -> 'c, argD: 'c -> 'd, [] argZ2: 'zzz) : 'd = argD (argC2( argB2 argA2)) + +let inline f (aa: 'fa) (ab: 'fb) ac ad : 'e when (^fa) : (member X : 'b -> 'b) and (^b) : (member BBBB : unit -> unit) = + let e : 'e = A.Foo(aa, ab, ac, argD = ad) + e \ No newline at end of file diff --git a/tests/fsharp/typecheck/overloads/neg_interface_generics.bsl b/tests/fsharp/typecheck/overloads/neg_interface_generics.bsl new file mode 100644 index 00000000000..8cb798d4fa7 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_interface_generics.bsl @@ -0,0 +1,10 @@ + +neg_interface_generics.fsx(14,1,18,2): typecheck error FS0505: The member or object constructor 'Foo' does not take 13073 argument(s). An overload was found taking 1 arguments. + +neg_interface_generics.fsx(20,9,20,27): typecheck error FS0041: No overloads match for method 'Foo'. + +Known types of arguments: string * XmlReader + +Available overloads: + - abstract IFoo.Foo: t: Type * r: TextReader -> obj * 't // Argument 't' doesn't match + - abstract IFoo.Foo: t: string * r: TextReader -> obj * 't // Argument 'r' doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_interface_generics.fsx b/tests/fsharp/typecheck/overloads/neg_interface_generics.fsx new file mode 100644 index 00000000000..dbfeed64193 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_interface_generics.fsx @@ -0,0 +1,21 @@ +open System +open System.Xml +open System.IO +type IFoo = + abstract Foo: t: string * r: XmlReader -> obj + abstract Foo: t: Type * r: TextReader -> obj + abstract Foo<'t> : t: string * r: TextReader -> obj * 't + abstract Foo<'t> : t: Type * r: TextReader -> obj * 't + abstract Foo<'t when 't : struct> : TextReader -> 't + abstract Foo<'t when 't :> IDisposable > : XmlReader -> 't + +let foo = Unchecked.defaultof +let r = Unchecked.defaultof +foo.Foo<_>(r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r +,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r +,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r +,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r +) +let a = foo.Foo( "", r) +let b = foo.Foo<_>( "", r) + diff --git a/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.bsl b/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.bsl new file mode 100644 index 00000000000..9dadb19ee6e --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.bsl @@ -0,0 +1,26 @@ + +neg_known_return_type_and_known_type_arguments.fsx(90,24,90,28): typecheck error FS0001: No overloads match for method 'Zero'. + +Known return type: MonoidSample + +Known type parameters: < MonoidSample , Zero > + +Available overloads: + - static member Zero.Zero: ^t * Default1 -> ^t when ^t: (static member get_Zero: -> ^t) // Argument at index 1 doesn't match + - static member Zero.Zero: ^t * Default1 -> ('a1 -> 'a1) when ^t: null and ^t: struct // Argument at index 1 doesn't match + - static member Zero.Zero: ^t * Default2 -> ^t when (FromInt32 or ^t) : (static member FromInt32: ^t * FromInt32 -> (int32 -> ^t)) // Argument at index 1 doesn't match + - static member Zero.Zero: ^t * Default2 -> ('a1 -> 'a1) when ^t: null and ^t: struct // Argument at index 1 doesn't match + - static member Zero.Zero: ^t * Default3 -> ^t when ^t: (static member get_Empty: -> ^t) // Argument at index 1 doesn't match + - static member Zero.Zero: 'a array * Zero -> 'a array // Argument at index 1 doesn't match + - static member Zero.Zero: 'a list * Zero -> 'a list // Argument at index 1 doesn't match + - static member Zero.Zero: 'a option * Zero -> 'a option // Argument at index 1 doesn't match + - static member Zero.Zero: ('T -> ^Monoid) * Zero -> ('T -> ^Monoid) when (Zero or ^Monoid) : (static member Zero: ^Monoid * Zero -> ^Monoid) // Argument at index 1 doesn't match + - static member Zero.Zero: Async< ^a> * Zero -> Async< ^a> when (Zero or ^a) : (static member Zero: ^a * Zero -> ^a) // Argument at index 1 doesn't match + - static member Zero.Zero: Lazy< ^a> * Zero -> Lazy< ^a> when (Zero or ^a) : (static member Zero: ^a * Zero -> ^a) // Argument at index 1 doesn't match + - static member Zero.Zero: Map<'a,'b> * Zero -> Map<'a,'b> when 'a: comparison // Argument at index 1 doesn't match + - static member Zero.Zero: ResizeArray<'a> * Zero -> ResizeArray<'a> // Argument at index 1 doesn't match + - static member Zero.Zero: Set<'a> * Zero -> Set<'a> when 'a: comparison // Argument at index 1 doesn't match + - static member Zero.Zero: System.TimeSpan * Zero -> System.TimeSpan // Argument at index 1 doesn't match + - static member Zero.Zero: seq<'a> * Zero -> seq<'a> // Argument at index 1 doesn't match + - static member Zero.Zero: string * Zero -> string // Argument at index 1 doesn't match + - static member Zero.Zero: unit * Zero -> unit // Argument at index 1 doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.fsx b/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.fsx new file mode 100644 index 00000000000..db2b2ae297c --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_known_return_type_and_known_type_arguments.fsx @@ -0,0 +1,90 @@ +open System.Runtime.CompilerServices +open System.Runtime.InteropServices +open System.Runtime.InteropServices +type Default6 = class end +type Default5 = class inherit Default6 end +type Default4 = class inherit Default5 end +type Default3 = class inherit Default4 end +type Default2 = class inherit Default3 end +type Default1 = class inherit Default2 end + +[] +type Plus = + inherit Default1 + static member inline ``+`` (x: 'Plus , y: 'Plus , _mthd: Default2) = (^Plus : (static member (<|>) : _*_ -> _) x, y) : ^Plus + static member inline ``+`` (x: 'Plus , y: 'Plus , []_mthd: Default1) = x + y : ^Plus + static member inline ``+`` (_: ^t when ^t: null and ^t: struct, _: ^t , []_mthd: Default1) = id + + static member inline Invoke (x: 'Plus) (y: 'Plus) : 'Plus = + let inline call (mthd : ^M, input1 : ^I, input2 : ^I) = ((^M or ^I) : (static member ``+`` : _*_*_ -> _) input1, input2, mthd) + call (Unchecked.defaultof, x, y) + +type FromInt32 = + inherit Default1 + static member inline FromInt32 (_: ^R , _: Default1 ) = fun (x: int32) -> (^R : (static member FromInt32 : _ -> ^R) x) + static member inline FromInt32 (_: Default1 , _: Default1 ) = fun (x: int32) -> (^R : (static member FromInt32 : _ -> ^R) x) + static member FromInt32 (_: int32 , _: FromInt32) = fun (x: int32) -> x + static member FromInt32 (_: int64 , _: FromInt32) = fun (x: int32) -> int64 x + #if !FABLE_COMPILER + static member FromInt32 (_: nativeint , _: FromInt32) = fun (x: int32) -> nativeint (int x) + static member FromInt32 (_: unativeint, _: FromInt32) = fun (x: int32) -> unativeint (int x) + #endif + static member FromInt32 (_: bigint , _: FromInt32) = fun (x: int32) -> bigint x + static member FromInt32 (_: float , _: FromInt32) = fun (x: int32) -> float x + static member FromInt32 (_: sbyte , _: FromInt32) = fun (x: int32) -> sbyte x + static member FromInt32 (_: int16 , _: FromInt32) = fun (x: int32) -> int16 x + static member FromInt32 (_: byte , _: FromInt32) = fun (x: int32) -> byte x + static member FromInt32 (_: uint16 , _: FromInt32) = fun (x: int32) -> uint16 x + static member FromInt32 (_: uint32 , _: FromInt32) = fun (x: int32) -> uint32 x + static member FromInt32 (_: uint64 , _: FromInt32) = fun (x: int32) -> uint64 x + static member FromInt32 (_: float32 , _: FromInt32) = fun (x: int32) -> float32 x + static member FromInt32 (_: decimal , _: FromInt32) = fun (x: int32) -> decimal x + + static member inline Invoke (x: int32) : 'Num = + let inline call_2 (a: ^a, b: ^b) = ((^a or ^b) : (static member FromInt32 : _*_ -> _) b, a) + let inline call (a: 'a) = fun (x: 'x) -> call_2 (a, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof x + +type Zero = + inherit Default1 + static member inline Zero (_: 't , _: Default3) = (^t : (static member Empty : ^t) ()) : 't + static member inline Zero (_: 't , _: Default2) = FromInt32.Invoke 0 : 't + static member inline Zero (_: ^t when ^t: null and ^t: struct, _: Default2) = id + static member inline Zero (_: 't , _: Default1) = LanguagePrimitives.GenericZero : 't + static member inline Zero (_: ^t when ^t: null and ^t: struct, _: Default1) = id + static member Zero (_: System.TimeSpan , _: Zero ) = System.TimeSpan () + static member Zero (_: list<'a> , _: Zero ) = [] : list<'a> + static member Zero (_: option<'a> , _: Zero ) = None : option<'a> + static member Zero (_: array<'a> , _: Zero ) = [||] : array<'a> + static member Zero (_: string , _: Zero ) = "" + static member Zero (_: unit , _: Zero ) = () + static member Zero (_: Set<'a> , _: Zero ) = Set.empty : Set<'a> + static member Zero (_: Map<'a,'b> , _: Zero ) = Map.empty : Map<'a,'b> + + static member inline Invoke () = + let inline call_2 (a: ^a, b: ^b) = ((^a or ^b) : (static member Zero : _*_ -> _) b, a) + let inline call (a: 'a) = call_2 (a, Unchecked.defaultof<'r>) : 'r + call Unchecked.defaultof + +type Zero with + static member inline Zero (_: 'T->'Monoid , _: Zero) = (fun _ -> Zero.Invoke ()) : 'T->'Monoid + static member inline Zero (_: Async<'a> , _: Zero) = let (v: 'a) = Zero.Invoke () in async.Return v + static member inline Zero (_: Lazy<'a> , _: Zero) = let (v: 'a) = Zero.Invoke () in lazy v + static member Zero (_: ResizeArray<'a> , _: Zero) = ResizeArray () : ResizeArray<'a> + static member Zero (_: seq<'a> , _: Zero) = Seq.empty : seq<'a> + +let inline (++) (x: 'Monoid) (y: 'Monoid) : 'Monoid = Plus.Invoke x y +let inline zero< ^Monoid when (Zero or ^Monoid) : (static member Zero : ^Monoid * Zero -> ^Monoid) > : ^Monoid = Zero.Invoke () + +type MonoidSample = + | MonoidSample of int + + static member getr_Zero () = MonoidSample 0 + //static member (+) (MonoidSample(x), MonoidSample(y)) = MonoidSample (x+y) + static member (+) (MonoidSample(x), y) = MonoidSample (x+y), 1 + static member (+) (x,MonoidSample(y)) = MonoidSample (x+y) + static member (+) (x, y) = MonoidSample (x+y), 3 + +let a = MonoidSample 1 +let b = MonoidSample 2 +let c : MonoidSample = zero diff --git a/tests/fsharp/typecheck/overloads/neg_many_many_overloads.bsl b/tests/fsharp/typecheck/overloads/neg_many_many_overloads.bsl new file mode 100644 index 00000000000..c37fa993868 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_many_many_overloads.bsl @@ -0,0 +1,348 @@ + +neg_many_many_overloads.fsx(123,1,123,13): typecheck error FS0041: A unique overload for method 'A' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 when 'a0: null + +Candidates: + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: Dictionary -> Dictionary + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: HashSet -> HashSet + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: List -> List + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Queue -> Queue + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: Task -> Task + - static member Class.A: a: string -> string + +neg_many_many_overloads.fsx(124,1,124,34): typecheck error FS0041: No overloads match for method 'A'. + +Known type of argument: Type + +Available overloads: + - static member Class.A: a: DateTime -> DateTime // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: decimal -> decimal // Argument 'a' doesn't match + - static member Class.A: a: float -> float // Argument 'a' doesn't match + - static member Class.A: a: float32 -> float32 // Argument 'a' doesn't match + - static member Class.A: a: int16 -> int16 // Argument 'a' doesn't match + - static member Class.A: a: int32 -> int32 // Argument 'a' doesn't match + - static member Class.A: a: int64 -> int64 // Argument 'a' doesn't match + - static member Class.A: a: int8 -> int8 // Argument 'a' doesn't match + - static member Class.A: a: string -> string // Argument 'a' doesn't match + - static member Class.A: a: uint16 -> uint16 // Argument 'a' doesn't match + - static member Class.A: a: uint32 -> uint32 // Argument 'a' doesn't match + - static member Class.A: a: uint64 -> uint64 // Argument 'a' doesn't match + - static member Class.A: a: uint8 -> uint8 // Argument 'a' doesn't match + +neg_many_many_overloads.fsx(125,1,125,25): typecheck error FS0041: No overloads match for method 'A'. + +Known type of argument: Guid + +Available overloads: + - static member Class.A: a: DateTime -> DateTime // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: decimal -> decimal // Argument 'a' doesn't match + - static member Class.A: a: float -> float // Argument 'a' doesn't match + - static member Class.A: a: float32 -> float32 // Argument 'a' doesn't match + - static member Class.A: a: int16 -> int16 // Argument 'a' doesn't match + - static member Class.A: a: int32 -> int32 // Argument 'a' doesn't match + - static member Class.A: a: int64 -> int64 // Argument 'a' doesn't match + - static member Class.A: a: int8 -> int8 // Argument 'a' doesn't match + - static member Class.A: a: string -> string // Argument 'a' doesn't match + - static member Class.A: a: uint16 -> uint16 // Argument 'a' doesn't match + - static member Class.A: a: uint32 -> uint32 // Argument 'a' doesn't match + - static member Class.A: a: uint64 -> uint64 // Argument 'a' doesn't match + - static member Class.A: a: uint8 -> uint8 // Argument 'a' doesn't match + +neg_many_many_overloads.fsx(126,1,126,48): typecheck error FS0041: No overloads match for method 'A'. + +Known type of argument: DayOfWeek + +Available overloads: + - static member Class.A: a: DateTime -> DateTime // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: Dictionary -> Dictionary // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: HashSet -> HashSet // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: List -> List // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Queue -> Queue // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: Task -> Task // Argument 'a' doesn't match + - static member Class.A: a: decimal -> decimal // Argument 'a' doesn't match + - static member Class.A: a: float -> float // Argument 'a' doesn't match + - static member Class.A: a: float32 -> float32 // Argument 'a' doesn't match + - static member Class.A: a: int16 -> int16 // Argument 'a' doesn't match + - static member Class.A: a: int32 -> int32 // Argument 'a' doesn't match + - static member Class.A: a: int64 -> int64 // Argument 'a' doesn't match + - static member Class.A: a: int8 -> int8 // Argument 'a' doesn't match + - static member Class.A: a: string -> string // Argument 'a' doesn't match + - static member Class.A: a: uint16 -> uint16 // Argument 'a' doesn't match + - static member Class.A: a: uint32 -> uint32 // Argument 'a' doesn't match + - static member Class.A: a: uint64 -> uint64 // Argument 'a' doesn't match + - static member Class.A: a: uint8 -> uint8 // Argument 'a' doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_many_many_overloads.fsx b/tests/fsharp/typecheck/overloads/neg_many_many_overloads.fsx new file mode 100644 index 00000000000..9a32383821d --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_many_many_overloads.fsx @@ -0,0 +1,126 @@ +(**) +let types0 = [ + "int8" + "int16" + "int32" + "int64" + "uint8" + "uint16" + "uint32" + "uint64" + "string" + "decimal" + "float" + "float32" + "DateTime" + "Task" + +] + +let types = [ + yield! types0 + for t in types0 do + yield sprintf "Task<%s>" t + yield sprintf "Dictionary<%s,%s>" t t + yield sprintf "HashSet<%s>" t + yield sprintf "List<%s>" t + yield sprintf "Queue<%s>" t +] + +let generate () = + [ for t in types -> sprintf " static member A (a:%s) = a" t ] + |> String.concat "\n" +printfn "%s" (generate ()) +(**) +open System +open System.Collections.Generic +open System.Threading.Tasks +type Class() = + static member A (a:int8) = a + static member A (a:int16) = a + static member A (a:int32) = a + static member A (a:int64) = a + static member A (a:uint8) = a + static member A (a:uint16) = a + static member A (a:uint32) = a + static member A (a:uint64) = a + static member A (a:string) = a + static member A (a:decimal) = a + static member A (a:float) = a + static member A (a:float32) = a + static member A (a:DateTime) = a + static member A (a:Task) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a + static member A (a:Task) = a + static member A (a:Dictionary) = a + static member A (a:HashSet) = a + static member A (a:List) = a + static member A (a:Queue) = a +Class.A null // does filter only reference type +Class.A typedefof> +Class.A (Guid.NewGuid()) +Class.A (Unchecked.defaultof) diff --git a/tests/fsharp/typecheck/overloads/neg_tupled_arguments.bsl b/tests/fsharp/typecheck/overloads/neg_tupled_arguments.bsl new file mode 100644 index 00000000000..33de258632b --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_tupled_arguments.bsl @@ -0,0 +1,18 @@ + +neg_tupled_arguments.fsx(6,9,6,31): typecheck error FS0041: No overloads match for method 'A'. + +Known types of arguments: (int * (int * string) * int) * int + +Available overloads: + - static member A.A: ('a0 * ('a1 * int) * 'a2) * ('a3 * ('a4 * 'a5)) -> 'a0 * 'a1 * int * 'a2 * 'a3 * 'a4 * 'a5 // Argument at index 1 doesn't match + - static member A.A: ('a0 * ('a1 * int) * 'a2) * e: 'a3 -> 'a0 * 'a1 * int * 'a2 * 'a3 // Argument at index 1 doesn't match + +neg_tupled_arguments.fsx(7,9,7,28): typecheck error FS0503: A member or object constructor 'A' taking 4 arguments is not accessible from this code location. All accessible versions of method 'A' take 2 arguments. + +neg_tupled_arguments.fsx(14,9,14,40): typecheck error FS0041: No overloads match for method 'B'. + +Known types of arguments: int * int * (int * (int * int * int * (int * int))) * int * int + +Available overloads: + - static member B.B: a: 'a0 * b: 'a1 * ('a2 * ('a3 * 'a4 * 'a5 * ('a6 * decimal))) * i: 'a7 * j: 'a8 -> 'a0 * 'a1 * 'a2 * 'a3 * 'a4 * 'a5 * 'a6 * decimal * 'a7 * 'a8 // Argument at index 3 doesn't match + - static member B.B: a: 'a0 * b: 'a1 * ('a2 * ('a3 * 'a4 * 'a5 * ('a6 * string))) * i: 'a7 * j: 'a8 -> 'a0 * 'a1 * 'a2 * 'a3 * 'a4 * 'a5 * 'a6 * string * 'a7 * 'a8 // Argument at index 3 doesn't match diff --git a/tests/fsharp/typecheck/overloads/neg_tupled_arguments.fsx b/tests/fsharp/typecheck/overloads/neg_tupled_arguments.fsx new file mode 100644 index 00000000000..53fc7e76d78 --- /dev/null +++ b/tests/fsharp/typecheck/overloads/neg_tupled_arguments.fsx @@ -0,0 +1,14 @@ +type A() = + static member A ((a,(b,(c:int)),d),e) = a,b,c,d,e + static member A ((a,(b,(c:int)),d),(e,(f,g))) = a,b,c,d,e,f,g + ;; + +let a = A.A ((1,(2,("")),4),5);; +let a = A.A("a",("",1),1,1);; + + +type B = + static member B (a,b,(c,(d,e,f,(g,h:string))),i,j) = a,b,c,d,e,f,g,h,i,j + static member B (a,b,(c,(d,e,f,(g,h:decimal))),i,j) = a,b,c,d,e,f,g,h,i,j +;; +let b = B.B(1,2,(3,(4,5,6,(7,8))),9,10);; diff --git a/tests/fsharp/typecheck/sigs/neg03.bsl b/tests/fsharp/typecheck/sigs/neg03.bsl index c956b2738dd..bd38f05401f 100644 --- a/tests/fsharp/typecheck/sigs/neg03.bsl +++ b/tests/fsharp/typecheck/sigs/neg03.bsl @@ -13,7 +13,7 @@ neg03.fs(14,5,14,8): typecheck error FS0025: Incomplete pattern matches on this neg03.fs(16,8,16,11): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s). -neg03.fs(22,39,22,42): typecheck error FS0026: This rule will never be matched +neg03.fs(22,39,22,47): typecheck error FS0026: This rule will never be matched neg03.fs(25,9,25,13): typecheck error FS0001: The type 'bool' does not support the operator '<<<' @@ -88,13 +88,13 @@ neg03.fs(84,9,84,23): typecheck error FS0025: Incomplete pattern matches on this neg03.fs(85,9,85,27): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '"a"' may indicate a case not covered by the pattern(s). -neg03.fs(86,9,86,13): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '( some-non-null-value )' may indicate a case not covered by the pattern(s). +neg03.fs(86,9,86,13): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s). -neg03.fs(87,19,87,26): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '( some-other-subtype )' may indicate a case not covered by the pattern(s). +neg03.fs(87,19,87,26): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s). -neg03.fs(91,11,91,20): typecheck error FS0026: This rule will never be matched +neg03.fs(91,11,91,26): typecheck error FS0026: This rule will never be matched -neg03.fs(97,11,97,20): typecheck error FS0026: This rule will never be matched +neg03.fs(97,11,97,26): typecheck error FS0026: This rule will never be matched neg03.fs(100,9,100,12): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '[_]' may indicate a case not covered by the pattern(s). diff --git a/tests/fsharp/typecheck/sigs/neg04.bsl b/tests/fsharp/typecheck/sigs/neg04.bsl index 058e3226a02..55f25656a14 100644 --- a/tests/fsharp/typecheck/sigs/neg04.bsl +++ b/tests/fsharp/typecheck/sigs/neg04.bsl @@ -11,8 +11,7 @@ neg04.fs(22,8,22,17): typecheck error FS0912: This declaration element is not pe neg04.fs(26,8,26,17): typecheck error FS0912: This declaration element is not permitted in an augmentation -neg04.fs(32,8,32,11): typecheck error FS0039: The field, constructor or member 'Nan' is not defined. Maybe you want one of the following: - +neg04.fs(32,8,32,11): typecheck error FS0039: The type 'Double' does not define the field, constructor or member 'Nan'. Maybe you want one of the following: IsNaN neg04.fs(46,69,46,94): typecheck error FS0001: Type mismatch. Expecting a @@ -69,7 +68,7 @@ but here has type neg04.fs(83,39,83,46): typecheck error FS0752: The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints -neg04.fs(85,47,85,52): typecheck error FS0039: The field, constructor or member 'Item' is not defined. +neg04.fs(85,47,85,52): typecheck error FS0039: The type 'Int32' does not define the field, constructor or member 'Item'. neg04.fs(87,73,87,78): typecheck error FS0752: The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints @@ -111,19 +110,19 @@ is not compatible with type 'IBar' -neg04.fs(144,10,144,25): typecheck error FS0193: Type constraint mismatch. The type +neg04.fs(144,10,144,26): typecheck error FS0193: Type constraint mismatch. The type 'int * int' is not compatible with type 'IBar' neg04.fs(147,10,147,20): typecheck error FS0193: Type constraint mismatch. The type - 'int []' + 'int[]' is not compatible with type 'IBar' -neg04.fs(150,10,150,26): typecheck error FS0193: Type constraint mismatch. The type +neg04.fs(150,10,150,27): typecheck error FS0193: Type constraint mismatch. The type 'int -> int' is not compatible with type 'IBar' diff --git a/tests/fsharp/typecheck/sigs/neg06.bsl b/tests/fsharp/typecheck/sigs/neg06.bsl index bd3a528947b..cc7fc113cfc 100644 --- a/tests/fsharp/typecheck/sigs/neg06.bsl +++ b/tests/fsharp/typecheck/sigs/neg06.bsl @@ -1,6 +1,5 @@ -neg06.fs(3,40,3,45): typecheck error FS0039: The field, constructor or member 'Ascii' is not defined. Maybe you want one of the following: - +neg06.fs(3,40,3,45): typecheck error FS0039: The type 'Encoding' does not define the field, constructor or member 'Ascii'. Maybe you want one of the following: ASCII neg06.fs(12,6,12,31): typecheck error FS0942: Struct types are always sealed @@ -91,7 +90,7 @@ neg06.fs(124,9,124,10): typecheck error FS0953: This type definition involves an neg06.fs(128,19,128,46): typecheck error FS0700: 'new' constraints must take one argument of type 'unit' and return the constructed type -neg06.fs(128,53,128,61): typecheck error FS0043: A type parameter is missing a constraint 'when 'a : (new : unit -> 'a)' +neg06.fs(128,53,128,61): typecheck error FS0043: A type parameter is missing a constraint 'when 'a: (new: unit -> 'a)' neg06.fs(141,10,141,18): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation @@ -139,6 +138,12 @@ neg06.fs(350,13,350,21): typecheck error FS0039: The value or constructor 'BadTy neg06.fs(375,9,375,10): typecheck error FS1197: The parameter 'x' was inferred to have byref type. Parameters of byref type must be given an explicit type annotation, e.g. 'x1: byref'. When used, a byref parameter is implicitly dereferenced. -neg06.fs(382,13,382,19): typecheck error FS0041: A unique overload for method 'M1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member C.M1 : x:int -> int, static member C.M1 : x:string -> int +neg06.fs(382,13,382,19): typecheck error FS0041: A unique overload for method 'M1' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a + +Candidates: + - static member C.M1: x: int -> int + - static member C.M1: x: string -> int neg06.fs(398,13,398,14): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). Unmatched elements will be ignored. diff --git a/tests/fsharp/typecheck/sigs/neg07.bsl b/tests/fsharp/typecheck/sigs/neg07.bsl index af0466dd3f0..b768e036c87 100644 --- a/tests/fsharp/typecheck/sigs/neg07.bsl +++ b/tests/fsharp/typecheck/sigs/neg07.bsl @@ -1,34 +1,30 @@ -neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(7,10,7,29): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. neg07.fs(24,13,24,23): typecheck error FS0039: The value or constructor 'UnionCase1' is not defined. Maybe you want one of the following: - X.UnionCase1 -neg07.fs(27,11,27,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(27,11,27,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(28,11,28,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(28,11,28,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(28,11,28,21): typecheck error FS0026: This rule will never be matched +neg07.fs(28,11,28,26): typecheck error FS0026: This rule will never be matched neg07.fs(31,18,31,28): typecheck error FS0039: The value or constructor 'UnionCase1' is not defined. Maybe you want one of the following: - X.UnionCase1 -neg07.fs(35,11,35,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(35,11,35,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(36,11,36,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name. +neg07.fs(36,11,36,21): typecheck error FS0049: Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name. -neg07.fs(36,11,36,21): typecheck error FS0026: This rule will never be matched +neg07.fs(36,11,36,27): typecheck error FS0026: This rule will never be matched neg07.fs(46,15,46,27): typecheck error FS0039: The record label 'RecordLabel1' is not defined. Maybe you want one of the following: - R.RecordLabel1 neg07.fs(47,19,47,31): typecheck error FS0039: The record label 'RecordLabel1' is not defined. Maybe you want one of the following: - R.RecordLabel1 neg07.fs(57,10,57,17): typecheck error FS1196: The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case diff --git a/tests/fsharp/typecheck/sigs/neg08.bsl b/tests/fsharp/typecheck/sigs/neg08.bsl index 5e737872b0c..f5c1b315dd8 100644 --- a/tests/fsharp/typecheck/sigs/neg08.bsl +++ b/tests/fsharp/typecheck/sigs/neg08.bsl @@ -19,6 +19,6 @@ neg08.fs(55,7,55,14): typecheck error FS0773: Cannot create an extension of a se neg08.fs(55,7,55,14): typecheck error FS0776: Object construction expressions may only be used to implement constructors in class types -neg08.fs(61,19,61,26): typecheck error FS0039: The field, constructor or member 'value__' is not defined. +neg08.fs(61,19,61,26): typecheck error FS0039: The type 'Type' does not define the field, constructor or member 'value__'. -neg08.fs(79,5,79,44): typecheck error FS0502: The member or object constructor 'Random' takes 0 type argument(s) but is here given 1. The required signature is 'static member Variable.Random : y:Variable<'a> -> Variable<'a>'. +neg08.fs(79,5,79,44): typecheck error FS0502: The member or object constructor 'Random' takes 0 type argument(s) but is here given 1. The required signature is 'static member Variable.Random: y: Variable<'a> -> Variable<'a>'. diff --git a/tests/fsharp/typecheck/sigs/neg09.bsl b/tests/fsharp/typecheck/sigs/neg09.bsl index 4db6dab5184..b6b98819491 100644 --- a/tests/fsharp/typecheck/sigs/neg09.bsl +++ b/tests/fsharp/typecheck/sigs/neg09.bsl @@ -9,7 +9,7 @@ neg09.fs(6,5,6,8): typecheck error FS0201: Namespaces cannot contain values. Con neg09.fs(20,32,20,42): typecheck error FS0941: Accessibility modifiers are not permitted on overrides or interface implementations -neg09.fs(26,8,26,39): typecheck error FS0497: The member or object constructor 'NamedMeth1' requires 1 additional argument(s). The required signature is 'abstract member IFoo.NamedMeth1 : arg1:int * arg2:int * arg3:int * arg4:int -> float'. +neg09.fs(26,8,26,39): typecheck error FS0497: The member or object constructor 'NamedMeth1' requires 1 additional argument(s). The required signature is 'abstract IFoo.NamedMeth1: arg1: int * arg2: int * arg3: int * arg4: int -> float'. neg09.fs(49,19,49,20): typecheck error FS1173: Infix operator member '+' has 1 initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... diff --git a/tests/fsharp/typecheck/sigs/neg10.bsl b/tests/fsharp/typecheck/sigs/neg10.bsl index c31220273da..b19cbe84bb4 100644 --- a/tests/fsharp/typecheck/sigs/neg10.bsl +++ b/tests/fsharp/typecheck/sigs/neg10.bsl @@ -13,13 +13,9 @@ neg10.fs(16,32,16,34): typecheck error FS0887: The type 'C1' is not an interface neg10.fs(16,32,16,34): typecheck error FS1207: Interfaces inherited by other interfaces should be declared using 'inherit ...' instead of 'interface ...' -neg10.fs(16,32,16,34): typecheck error FS0908: This type is not an interface type - neg10.fs(17,28,17,30): typecheck error FS0887: The type 'C1' is not an interface type -neg10.fs(17,28,17,30): typecheck error FS0908: This type is not an interface type - -neg10.fs(19,17,19,28): typecheck error FS0870: Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor. +neg10.fs(19,17,19,22): typecheck error FS0870: Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor. neg10.fs(21,16,21,46): typecheck error FS0001: A generic construct requires that the type 'System.Enum' have a public default constructor @@ -61,12 +57,10 @@ neg10.fs(131,23,131,29): typecheck error FS0906: Type abbreviations cannot have neg10.fs(169,32,169,35): typecheck error FS0035: This construct is deprecated: This form of object expression is not used in F#. Use 'member this.MemberName ... = ...' to define member implementations in object expressions. -neg10.fs(169,32,169,33): typecheck error FS3213: The member 'X : unit -> 'a' matches multiple overloads of the same method. +neg10.fs(169,32,169,33): typecheck error FS3213: The member 'X: unit -> 'a' matches multiple overloads of the same method. Please restrict it to one of the following: - - X : unit -> 'a - - X : unit -> 'a. + X: unit -> 'a + X: unit -> 'a. neg10.fs(169,19,169,26): typecheck error FS0783: At least one override did not correctly implement its corresponding abstract member @@ -76,7 +70,7 @@ neg10.fs(180,10,180,11): typecheck error FS0866: Interfaces cannot contain defin neg10.fs(193,39,193,46): typecheck error FS0767: The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement. -neg10.fs(193,41,193,44): typecheck error FS0017: The member 'MyX : unit -> int' does not have the correct type to override any given virtual method +neg10.fs(193,41,193,44): typecheck error FS0017: The member 'MyX: unit -> int' does not have the correct type to override any given virtual method neg10.fs(193,20,193,23): typecheck error FS0783: At least one override did not correctly implement its corresponding abstract member @@ -152,7 +146,7 @@ neg10.fs(324,17,324,29): typecheck error FS1187: An indexer property must be giv neg10.fs(333,17,333,29): typecheck error FS1187: An indexer property must be given at least one argument -neg10.fs(335,17,335,39): typecheck error FS0501: The member or object constructor 'X' takes 2 argument(s) but is here given 3. The required signature is 'member T3.X : a:int -> int * int with set'. +neg10.fs(335,17,335,39): typecheck error FS0501: The member or object constructor 'X' takes 2 argument(s) but is here given 3. The required signature is 'member T3.X: a: int -> int * int with set'. neg10.fs(345,23,345,24): typecheck error FS0001: The type 'SqlDecimal' does not support a conversion to the type 'float' diff --git a/tests/fsharp/typecheck/sigs/neg101.bsl b/tests/fsharp/typecheck/sigs/neg101.bsl index 84e53b5e6ab..44a8c10cdd6 100644 --- a/tests/fsharp/typecheck/sigs/neg101.bsl +++ b/tests/fsharp/typecheck/sigs/neg101.bsl @@ -1,5 +1,5 @@ -neg101.fs(7,11,7,14): typecheck error FS0039: The field, constructor or member 'Foo' is not defined. +neg101.fs(7,11,7,14): typecheck error FS0039: The type 'Int32' does not define the field, constructor or member 'Foo'. neg101.fs(14,6,14,17): typecheck error FS3220: This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead. diff --git a/tests/fsharp/typecheck/sigs/neg103.bsl b/tests/fsharp/typecheck/sigs/neg103.bsl index 422a9e3bf81..d2a0cc1220d 100644 --- a/tests/fsharp/typecheck/sigs/neg103.bsl +++ b/tests/fsharp/typecheck/sigs/neg103.bsl @@ -19,6 +19,8 @@ neg103.fs(21,7,21,9): typecheck error FS0001: This expression was expected to ha but here has type 'int' +neg103.fs(20,5,20,29): typecheck error FS0025: Incomplete pattern matches on this expression. + neg103.fs(25,11,25,19): typecheck error FS0001: This expression was expected to have type 'int' but here has type diff --git a/tests/fsharp/typecheck/sigs/neg103.vsbsl b/tests/fsharp/typecheck/sigs/neg103.vsbsl index 422a9e3bf81..d2a0cc1220d 100644 --- a/tests/fsharp/typecheck/sigs/neg103.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg103.vsbsl @@ -19,6 +19,8 @@ neg103.fs(21,7,21,9): typecheck error FS0001: This expression was expected to ha but here has type 'int' +neg103.fs(20,5,20,29): typecheck error FS0025: Incomplete pattern matches on this expression. + neg103.fs(25,11,25,19): typecheck error FS0001: This expression was expected to have type 'int' but here has type diff --git a/tests/fsharp/typecheck/sigs/neg104.bsl b/tests/fsharp/typecheck/sigs/neg104.bsl index 022a8e3e4b2..e93db87ef8d 100644 --- a/tests/fsharp/typecheck/sigs/neg104.bsl +++ b/tests/fsharp/typecheck/sigs/neg104.bsl @@ -7,7 +7,7 @@ neg104.fs(20,23,20,24): parse error FS0010: Incomplete structured construct at o neg104.fs(23,25,23,26): parse error FS0010: Incomplete structured construct at or before this point in expression -neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern +neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. neg104.fs(29,31,29,32): parse error FS0010: Incomplete structured construct at or before this point in pattern matching diff --git a/tests/fsharp/typecheck/sigs/neg104.vsbsl b/tests/fsharp/typecheck/sigs/neg104.vsbsl index e4e6e79397a..87d4a4e89db 100644 --- a/tests/fsharp/typecheck/sigs/neg104.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg104.vsbsl @@ -7,7 +7,7 @@ neg104.fs(20,23,20,24): parse error FS0010: Incomplete structured construct at o neg104.fs(23,25,23,26): parse error FS0010: Incomplete structured construct at or before this point in expression -neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern +neg104.fs(26,28,26,29): parse error FS0010: Incomplete structured construct at or before this point in pattern matching. Expected '->' or other token. neg104.fs(29,31,29,32): parse error FS0010: Incomplete structured construct at or before this point in pattern matching @@ -27,8 +27,6 @@ neg104.fs(20,9,20,22): typecheck error FS0025: Incomplete pattern matches on thi neg104.fs(23,9,23,22): typecheck error FS0025: Incomplete pattern matches on this expression. -neg104.fs(26,9,26,22): typecheck error FS0025: Incomplete pattern matches on this expression. - neg104.fs(32,21,32,26): typecheck error FS0003: This value is not a function and cannot be applied. neg104.fs(35,9,35,18): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'. diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index e07dd731fbb..6630d22d110 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -1,81 +1,33 @@ neg106.fs(8,59,8,61): typecheck error FS3230: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' -neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref<'a>' -. +neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. + +Known types of arguments: inref * int * int + +Available overloads: + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange<'T when 'T: not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T // Argument 'location1' doesn't match neg106.fs(17,59,17,61): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. -neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref<'a>' -. +neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. + +Known types of arguments: inref * int * int + +Available overloads: + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange<'T when 'T: not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T // Argument 'location1' doesn't match neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a 'byref' @@ -89,29 +41,21 @@ but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'string' -is not compatible with type - 'int' -. - -neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'int' -is not compatible with type - 'string' -. -neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. +neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * inref + +Available overloads: + - static member C.M: a: int * x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: string * x: byref -> unit // Argument 'x' doesn't match + +neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: int * inref + +Available overloads: + - static member C.M: a: int * x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: string * x: byref -> unit // Argument 'a' doesn't match neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index e07dd731fbb..6630d22d110 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -1,81 +1,33 @@ neg106.fs(8,59,8,61): typecheck error FS3230: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' -neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref<'a>' -. +neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. + +Known types of arguments: inref * int * int + +Available overloads: + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange<'T when 'T: not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T // Argument 'location1' doesn't match neg106.fs(17,59,17,61): typecheck error FS3236: Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address. -neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref<'a>' -. +neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. + +Known types of arguments: inref * int * int + +Available overloads: + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64 // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj // Argument 'location1' doesn't match + - System.Threading.Interlocked.CompareExchange<'T when 'T: not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T // Argument 'location1' doesn't match neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a 'byref' @@ -89,29 +41,21 @@ but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. -neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'string' -is not compatible with type - 'int' -. - -neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'int' -is not compatible with type - 'string' -. -neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'inref' -is not compatible with type - 'byref' -. +neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * inref + +Available overloads: + - static member C.M: a: int * x: byref -> unit // Argument 'a' doesn't match + - static member C.M: a: string * x: byref -> unit // Argument 'x' doesn't match + +neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: int * inref + +Available overloads: + - static member C.M: a: int * x: byref -> unit // Argument 'x' doesn't match + - static member C.M: a: string * x: byref -> unit // Argument 'a' doesn't match neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' diff --git a/tests/fsharp/typecheck/sigs/neg107-pre.fsx b/tests/fsharp/typecheck/sigs/neg107-pre.fsx index dbe73fd7e5f..b090dbcbbfe 100644 --- a/tests/fsharp/typecheck/sigs/neg107-pre.fsx +++ b/tests/fsharp/typecheck/sigs/neg107-pre.fsx @@ -1,4 +1,8 @@ open System open System.IO -File.WriteAllText("neg107.generated.fsx", sprintf @"#r @""%s\.nuget\packages\System.Memory\4.5.2\lib\netstandard2.0\System.Memory.dll""" (Environment.GetEnvironmentVariable("USERPROFILE"))) +let packagesDir = + match Environment.GetEnvironmentVariable("NUGET_PACKAGES") with + | null -> Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".nuget", "packages") + | path -> path +File.WriteAllText("neg107.generated.fsx", sprintf @"#r @""%s\System.Memory\4.5.3\lib\netstandard2.0\System.Memory.dll""" packagesDir) diff --git a/tests/fsharp/typecheck/sigs/neg111.bsl b/tests/fsharp/typecheck/sigs/neg111.bsl index afe770b8fdc..c5048f7c299 100644 --- a/tests/fsharp/typecheck/sigs/neg111.bsl +++ b/tests/fsharp/typecheck/sigs/neg111.bsl @@ -4,11 +4,8 @@ neg111.fs(2,552,2,557): typecheck error FS0039: The type 'fail1' is not defined. neg111.fs(2,552,2,557): typecheck error FS0039: The type 'fail1' is not defined. neg111.fs(3,624,3,629): typecheck error FS0039: The value or constructor 'fail2' is not defined. Maybe you want one of the following: - Failure - failwith - failwithf neg111.fs(5,538,5,540): typecheck error FS0003: This value is not a function and cannot be applied. diff --git a/tests/fsharp/typecheck/sigs/neg112.bsl b/tests/fsharp/typecheck/sigs/neg112.bsl new file mode 100644 index 00000000000..e6d4ed7bc8e --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg112.bsl @@ -0,0 +1,6 @@ + +neg112.fs(20,49,20,62): typecheck error FS0001: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' + +neg112.fs(20,31,20,39): typecheck error FS0043: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' + +neg112.fs(20,31,20,39): typecheck error FS0043: A type parameter is missing a constraint 'when (Tuple or ^options) : (static member TupleMap: ^options * Tuple -> (('item -> ^value) -> ^values))' diff --git a/tests/fsharp/typecheck/sigs/neg112.fs b/tests/fsharp/typecheck/sigs/neg112.fs new file mode 100644 index 00000000000..b544ee5834b --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg112.fs @@ -0,0 +1,22 @@ +module Something +type Tuple = + static member inline TupleMap ((a, b), _ : Tuple) = fun f -> (f a, f b) + static member inline TupleMap ((a, b, c), _ : Tuple) = fun f -> (f a, f b, f c) + static member inline TupleMap ((a, b, c, d), _ : Tuple) = fun f -> (f a, f b, f c, f d) + + static member inline Map f (x: 'Tin) : 'Tout = + let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a)) + call_2 (Unchecked.defaultof, x) f + +type IOption<'T> = + abstract member Value : 'T + +let inline tupleMap f x = Tuple.Map f x + +let inline addOptionValues< ^value, ^options, ^values, 'item when + 'item :> IOption< ^value>> + (addUp : ^values -> ^value, sourceOptions : ^options) = + let getValue (i : 'item) = i.Value + let allValues : ^values = tupleMap getValue sourceOptions + let result : ^value = addUp allValues + result diff --git a/tests/fsharp/typecheck/sigs/neg116.bsl b/tests/fsharp/typecheck/sigs/neg116.bsl new file mode 100644 index 00000000000..e5225d4225e --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg116.bsl @@ -0,0 +1,10 @@ + +neg116.fs(10,44,10,45): typecheck error FS0043: No overloads match for method 'op_Multiply'. + +Known return type: ^a + +Known type parameters: < float , Polynomial > + +Available overloads: + - static member Polynomial.( * ) : s: Complex * p: Polynomial -> Polynomial // Argument 's' doesn't match + - static member Polynomial.( * ) : s: decimal * p: Polynomial -> Polynomial // Argument 's' doesn't match diff --git a/tests/fsharp/typecheck/sigs/neg116.fs b/tests/fsharp/typecheck/sigs/neg116.fs new file mode 100644 index 00000000000..fff55619afe --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg116.fs @@ -0,0 +1,10 @@ +module Neg116 + +type Complex = unit + +type Polynomial () = + static member (*) (s: decimal, p: Polynomial) : Polynomial = failwith "" + static member (*) (s: Complex, p: Polynomial) : Polynomial = failwith "" + +module Foo = + let test t (p: Polynomial) = (1.0 - t) * p diff --git a/tests/fsharp/typecheck/sigs/neg117.bsl b/tests/fsharp/typecheck/sigs/neg117.bsl new file mode 100644 index 00000000000..8dd725f4721 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg117.bsl @@ -0,0 +1,10 @@ + +neg117.fs(79,18,79,59): ilxgen error FS0041: No overloads match for method 'Transform'. + +Known return type: ('a -> Neg117.TargetA.M1 Microsoft.FSharp.Core.[]) + +Known type parameters: < Neg117.TargetA.M1 Microsoft.FSharp.Core.[] , Microsoft.FSharp.Core.obj , Neg117.Superpower.Transformer > + +Available overloads: + - static member Neg117.Superpower.Transformer.Transform: ^f * Neg117.TargetB.TargetB * Neg117.Superpower.Transformer -> (Neg117.TargetB.TransformerKind -> ^f) when (Neg117.TargetB.TargetB or ^f) : (static member Transform: ^f * Neg117.TargetB.TargetB -> (Neg117.TargetB.TransformerKind -> ^f)) // Argument at index 1 doesn't match + - static member Neg117.Superpower.Transformer.Transform: ^r * Neg117.TargetA.TargetA * Neg117.Superpower.Transformer -> (Neg117.TargetA.TransformerKind -> ^r) when (Neg117.TargetA.TargetA or ^r) : (static member Transform: ^r * Neg117.TargetA.TargetA -> (Neg117.TargetA.TransformerKind -> ^r)) // Argument at index 1 doesn't match diff --git a/tests/fsharp/typecheck/sigs/neg117.fs b/tests/fsharp/typecheck/sigs/neg117.fs new file mode 100644 index 00000000000..a5de1db5a25 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg117.fs @@ -0,0 +1,82 @@ +module Neg117 + +#nowarn "64" // This construct causes code to be less generic than indicated by the type annotations. + +module TargetA = + + [] + type TransformerKind = + | A + | B + + type M1 = int + + type M2 = float + + type Target() = + + member __.TransformM1 (kind: TransformerKind) : M1[] option = [| 0 |] |> Some + member __.TransformM2 (kind: TransformerKind) : M2[] option = [| 1. |] |> Some + + type TargetA = + + static member instance : Target option = None + + static member inline Transform(_: ^r, _: TargetA) = fun (kind:TransformerKind) -> TargetA.instance.Value.TransformM1 kind : ^r + static member inline Transform(_: ^r, _: TargetA) = fun (kind:TransformerKind) -> TargetA.instance.Value.TransformM2 kind : ^r + + static member inline Transform(kind: TransformerKind) = + let inline call2(a:^a, b:^b) = ((^a or ^b) : (static member Transform: _ * _ -> _) b, a) + let inline call (a: 'a) = fun (x: 'x) -> call2(a, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof kind + + let inline Transform kind = TargetA.Transform kind + +module TargetB = + [] + type TransformerKind = + | C + | D + + type M1 = | M1 + + type M2 = | M2 + + type Target() = + + member __.TransformM1 (kind: TransformerKind) = [| M1 |] |> Some + member __.TransformM2 (kind: TransformerKind) = [| M2 |] |> Some + + type TargetB = + + static member instance : Target option = None + + static member inline Transform(_: ^r, _: TargetB) = fun (kind:TransformerKind) -> TargetB.instance.Value.TransformM1 kind : ^r + static member inline Transform(_: ^r, _: TargetB) = fun (kind:TransformerKind) -> TargetB.instance.Value.TransformM2 kind : ^r + + static member inline Transform(kind: TransformerKind) = + let inline call2(a:^a, b:^b) = ((^a or ^b) : (static member Transform: _ * _ -> _) b, a) + let inline call (a: 'a) = fun (x: 'x) -> call2(a, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof kind + let inline Transform kind = TargetB.Transform kind + +module Superpower = + + type Transformer = + + static member inline Transform(_: ^f, _: TargetB.TargetB, _: Transformer) = + fun x -> TargetB.Transform x : ^f + + static member inline Transform(_: ^r, _: TargetA.TargetA, _: Transformer) = + fun x -> TargetA.Transform x : ^r + + static member inline YeahTransform kind = + let inline call2(a:^a, b:^b, c: ^c) = ((^a or ^b or ^c) : (static member Transform: _ * _ * _ -> _) c, b, a) + let inline call (a: 'a) = fun (x: 'x) -> call2(a, Unchecked.defaultof<_>, Unchecked.defaultof<'r>) x : 'r + call Unchecked.defaultof kind + +module Examples = + let a kind = Superpower.Transformer.YeahTransform kind : TargetA.M1[] + let b = Superpower.Transformer.YeahTransform TargetA.TransformerKind.A : TargetA.M2[] option + let c = Superpower.Transformer.YeahTransform TargetB.TransformerKind.C : TargetB.M1[] option + let d = Superpower.Transformer.YeahTransform TargetA.TransformerKind.A : TargetA.M1[] option diff --git a/tests/fsharp/typecheck/sigs/neg118.bsl b/tests/fsharp/typecheck/sigs/neg118.bsl new file mode 100644 index 00000000000..7b70803cc6c --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg118.bsl @@ -0,0 +1,12 @@ + +neg118.fs(18,21,18,37): typecheck error FS0003: This value is not a function and cannot be applied. + +neg118.fs(19,21,19,37): typecheck error FS0003: This value is not a function and cannot be applied. + +neg118.fs(20,21,20,39): typecheck error FS0003: This value is not a function and cannot be applied. + +neg118.fs(21,21,21,41): typecheck error FS0003: This value is not a function and cannot be applied. + +neg118.fs(22,21,22,39): typecheck error FS0003: This value is not a function and cannot be applied. + +neg118.fs(25,51,25,67): typecheck error FS0003: This value is not a function and cannot be applied. diff --git a/tests/fsharp/typecheck/sigs/neg118.fs b/tests/fsharp/typecheck/sigs/neg118.fs new file mode 100644 index 00000000000..fb951db31c4 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg118.fs @@ -0,0 +1,28 @@ +module Neg118 + +// This is the example provided by Gustavo Leon in https://github.com/dotnet/fsharp/pull/4173 +// The code is potentially valid and, if that PR had been accepted, would compile. +// It's being added as a negative test case to capture the fact that it currently +// fails to compile. + +type FoldArgs<'t> = FoldArgs of ('t -> 't -> 't) + +let inline foldArgs f (x:'t) (y:'t) :'rest = (FoldArgs f $ Unchecked.defaultof<'rest>) x y + +type FoldArgs<'t> with + static member inline ($) (FoldArgs f, _:'t-> 'rest) = fun (a:'t) -> f a >> foldArgs f + static member ($) (FoldArgs f, _:'t ) = f + +let test1() = + let x:int = foldArgs (+) 2 3 + let y:int = foldArgs (+) 2 3 4 + let z:int = foldArgs (+) 2 3 4 5 + let d:decimal = foldArgs (+) 2M 3M 4M + let e:string = foldArgs (+) "h" "e" "l" "l" "o" + let f:float = foldArgs (+) 2. 3. 4. + + let mult3Numbers a b c = a * b * c + let res2 = mult3Numbers 3 (foldArgs (+) 3 4) (foldArgs (+) 2 2 3 3) + () + + diff --git a/tests/fsharp/typecheck/sigs/neg119.bsl b/tests/fsharp/typecheck/sigs/neg119.bsl new file mode 100644 index 00000000000..9bbdf9ccdaa --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg119.bsl @@ -0,0 +1,12 @@ + +neg119.fs(40,20,40,22): typecheck error FS0071: Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'Return'. + +Known return type: ((int -> int -> int) -> obj) + +Known type parameters: < obj , Applicatives.Ap > + +Available overloads: + - static member Applicatives.Ap.Return: ('r -> 'a) * Ap: Applicatives.Ap -> (('a -> 'r -> 'a2) -> 'a3 -> 'a -> 'r -> 'a2) // Argument at index 1 doesn't match + - static member Applicatives.Ap.Return: System.Tuple<'a> * Ap: Applicatives.Ap -> ('a -> System.Tuple<'a>) // Argument at index 1 doesn't match + - static member Applicatives.Ap.Return: r: ^R * obj -> ('a1 -> ^R) when ^R: (static member Return: 'a1 -> ^R) // Argument 'r' doesn't match + - static member Applicatives.Ap.Return: seq<'a> * Ap: Applicatives.Ap -> ('a -> seq<'a>) // Argument at index 1 doesn't match Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg119.fs b/tests/fsharp/typecheck/sigs/neg119.fs new file mode 100644 index 00000000000..46d64d49395 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg119.fs @@ -0,0 +1,40 @@ +module Neg119 + +// This is an example provided by Gustavo Leon in https://github.com/dotnet/fsharp/pull/4173 +// The code is potentially valid and, if that PR had been accepted, would compile. +// It's being added as a negative test case to capture the fact that it currently +// fails to compile. + +module Applicatives = + open System + + type Ap = Ap with + static member inline Invoke (x:'T) : '``Applicative<'T>`` = + let inline call (mthd : ^M, output : ^R) = ((^M or ^R) : (static member Return: _*_ -> _) output, mthd) + call (Ap, Unchecked.defaultof<'``Applicative<'T>``>) x + static member inline InvokeOnInstance (x:'T) = (^``Applicative<'T>`` : (static member Return: ^T -> ^``Applicative<'T>``) x) + static member inline Return (r:'R , _:obj) = Ap.InvokeOnInstance :_ -> 'R + static member Return (_:seq<'a> , Ap ) = fun x -> Seq.singleton x : seq<'a> + static member Return (_:Tuple<'a>, Ap ) = fun x -> Tuple x : Tuple<'a> + static member Return (_:'r -> 'a , Ap ) = fun k _ -> k : 'a -> 'r -> _ + + let inline result (x:'T) = Ap.Invoke x + + let inline (<*>) (f:'``Applicative<'T->'U>``) (x:'``Applicative<'T>``) : '``Applicative<'U>`` = + (( ^``Applicative<'T->'U>`` or ^``Applicative<'T>`` or ^``Applicative<'U>``) : (static member (<*>): _*_ -> _) f, x) + + let inline (+) (a:'Num) (b:'Num) :'Num = a + b + + type ZipList<'s> = ZipList of 's seq with + static member Return (x:'a) = ZipList (Seq.initInfinite (fun _ -> x)) + static member (<*>) (ZipList (f:seq<'a->'b>), ZipList x) = ZipList (Seq.zip f x |> Seq.map (fun (f, x) -> f x)) :ZipList<'b> + + type Ii = Ii + type Idiomatic = Idiomatic with + static member inline ($) (Idiomatic, si) = fun sfi x -> (Idiomatic $ x) (sfi <*> si) + static member ($) (Idiomatic, Ii) = id + let inline idiomatic a b = (Idiomatic $ b) a + let inline iI x = (idiomatic << result) x + + let res1n2n3 = iI (+) (result 0M ) (ZipList [1M;2M;3M]) Ii + let res2n3n4 = iI (+) (result LanguagePrimitives.GenericOne) (ZipList [1 ;2 ;3 ]) Ii diff --git a/tests/fsharp/typecheck/sigs/neg120.bsl b/tests/fsharp/typecheck/sigs/neg120.bsl new file mode 100644 index 00000000000..e0b1aebc7b2 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg120.bsl @@ -0,0 +1,13 @@ + +neg120.fs(95,18,95,21): typecheck error FS0071: Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'op_GreaterGreaterEquals'. + +Known return type: obj + +Known type parameters: < Id , (int -> obj) > + +Available overloads: + - static member Bind.(>>=) : source: 'T option * f: ('T -> 'U option) -> 'U option // Argument 'source' doesn't match + - static member Bind.(>>=) : source: Async<'T> * f: ('T -> Async<'a1>) -> Async<'a1> // Argument 'source' doesn't match + - static member Bind.(>>=) : source: Id<'T> * f: ('T -> Id<'U>) -> Id<'U> // Argument 'f' doesn't match + - static member Bind.(>>=) : source: Lazy<'T> * f: ('T -> Lazy<'U>) -> Lazy<'U> // Argument 'source' doesn't match + - static member Bind.(>>=) : source: Task<'T> * f: ('T -> Task<'U>) -> Task<'U> // Argument 'source' doesn't match Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg120.fs b/tests/fsharp/typecheck/sigs/neg120.fs new file mode 100644 index 00000000000..48ab1db0a0c --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg120.fs @@ -0,0 +1,97 @@ +module Neg120 + +// From https://github.com/dotnet/fsharp/issues/4171#issuecomment-528063764 +open System.Threading.Tasks +// [] +type Id<'t> (v: 't) = + let value = v + member __.getValue = value + +[] +module Id = + let run (x: Id<_>) = x.getValue + let map f (x: Id<_>) = Id (f x.getValue) + let create x = Id x + + +type Bind = + static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U> + static member (>>=) (source: Task<'T> , f: 'T -> Task<'U> ) = source.ContinueWith(fun (x: Task<_>) -> f x.Result).Unwrap () : Task<'U> + static member (>>=) (source , f: 'T -> _ ) = Option.bind f source : option<'U> + static member (>>=) (source , f: 'T -> _ ) = async.Bind (source, f) + static member (>>=) (source : Id<_> , f: 'T -> _ ) = f source.getValue : Id<'U> + + static member inline Invoke (source: '``Monad<'T>``) (binder: 'T -> '``Monad<'U>``) : '``Monad<'U>`` = + let inline call (_mthd: 'M, input: 'I, _output: 'R, f) = ((^M or ^I or ^R) : (static member (>>=) : _*_ -> _) input, f) + call (Unchecked.defaultof, source, Unchecked.defaultof<'``Monad<'U>``>, binder) + +let inline (>>=) (x: '``Monad<'T>``) (f: 'T->'``Monad<'U>``) : '``Monad<'U>`` = Bind.Invoke x f + +type Return = + static member inline Invoke (x: 'T) : '``Applicative<'T>`` = + let inline call (mthd: ^M, output: ^R) = ((^M or ^R) : (static member Return : _*_ -> _) output, mthd) + call (Unchecked.defaultof, Unchecked.defaultof<'``Applicative<'T>``>) x + + static member Return (_: Lazy<'a> , _: Return ) = fun x -> Lazy<_>.CreateFromValue x : Lazy<'a> + static member Return (_: 'a Task , _: Return ) = fun x -> Task.FromResult x : 'a Task + static member Return (_: option<'a> , _: Return ) = fun x -> Some x : option<'a> + static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x + static member Return (_: 'a Id , _: Return ) = fun (x: 'a) -> Id x + +let inline result (x: 'T) : '``Functor<'T>`` = Return.Invoke x + + +type TypeT<'``monad<'t>``> = TypeT of obj +type Node<'``monad<'t>``,'t> = A | B of 't * TypeT<'``monad<'t>``> + +let inline wrap (mit: 'mit) = + let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_:'t) -> (result Node<'mt,'t>.A ) : 'mit + TypeT mit : TypeT<'mt> + +let inline unwrap (TypeT mit : TypeT<'mt>) = + let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_:'t) -> (result Node<'mt,'t>.A ) : 'mit + unbox mit : 'mit + +let inline empty () = wrap ((result Node<'mt,'t>.A) : 'mit) : TypeT<'mt> + +let inline concat l1 l2 = + let rec loop (l1: TypeT<'mt>) (lst2: TypeT<'mt>) = + let (l1, l2) = unwrap l1, unwrap lst2 + TypeT (l1 >>= function A -> l2 | B (x: 't, xs) -> ((result (B (x, loop xs lst2))) : 'mit)) + loop l1 l2 : TypeT<'mt> + + +let inline bind f (source: TypeT<'mt>) : TypeT<'mu> = + // let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_: 't) -> (result Unchecked.defaultof<'u>) : 'mu + let rec loop f input = + TypeT ( + (unwrap input : 'mit) >>= function + | A -> result <| (A : Node<'mu,'u>) : 'miu + | B (h:'t, t: TypeT<'mt>) -> + let res = concat (f h: TypeT<'mu>) (loop f t) + unwrap res : 'miu) + loop f source : TypeT<'mu> + + +let inline map (f: 'T->'U) (x: '``Monad<'T>`` ) = Bind.Invoke x (f >> Return.Invoke) : '``Monad<'U>`` + + +let inline unfold (f:'State -> '``M<('T * 'State) option>``) (s:'State) : TypeT<'MT> = + let rec loop f s = f s |> map (function + | Some (a, s) -> B (a, loop f s) + | None -> A) |> wrap + loop f s + +let inline create (al: '``Monad>``) : TypeT<'``Monad<'T>``> = + unfold (fun i -> map (fun (lst:list<_>) -> if lst.Length > i then Some (lst.[i], i+1) else None) al) 0 + +let inline run (lst: TypeT<'MT>) : '``Monad>`` = + let rec loop acc x = unwrap x >>= function + | A -> result (List.rev acc) + | B (x, xs) -> loop (x::acc) xs + loop [] lst + +let c0 = create (Id ([1..10])) +let res0 = c0 |> run |> create |> run + +// See pos34.fs for the Sealed case that compiles without complaint \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/neg121.bsl b/tests/fsharp/typecheck/sigs/neg121.bsl new file mode 100644 index 00000000000..49d735e7295 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg121.bsl @@ -0,0 +1,2 @@ + +neg121.fs(19,28,19,38): typecheck error FS0071: Type constraint mismatch when applying the default type 'int' for a type inference variable. The type 'int' does not support the operator 'ParseApply' Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg121.fs b/tests/fsharp/typecheck/sigs/neg121.fs new file mode 100644 index 00000000000..598820f4c9d --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg121.fs @@ -0,0 +1,19 @@ +module Neg121 + +// See https://github.com/dotnet/fsharp/pull/3582#issuecomment-399755533, which listed +// this as a test case of interest. +// +// This is to pin down that behaviour doesn't change in the future unless we intend it to. +open System +type System.String with static member inline ParseApply (path:string) (fn: string -> ^b) : ^b = fn "" +type System.Int32 with static member inline ParseApply (path:string) (fn: int -> ^b) : ^b = fn 0 +type System.Double with static member inline ParseApply (path:string) (fn: float -> ^b) : ^b = fn 0. +type System.Boolean with static member inline ParseApply (path:string) (fn: bool -> ^b) : ^b = fn true + +let inline parser (fmt:PrintfFormat< ^a -> ^b,_,_,^b>) (fn:^a -> ^b) (v:string) : ^b + when ^a : (static member ParseApply: string -> (^a -> ^b) -> ^b) = + (^a : (static member ParseApply: string -> (^a -> ^b) -> ^b)(v,fn)) + +let inline patternTest (fmt:PrintfFormat< ^a -> Action< ^T>,_,_,Action< ^T>>) (fn:^a -> Action< ^T>) v : Action< ^T> = parser fmt fn v + +let parseFn1 = patternTest "adfadf%i" (fun v -> printfn "%i" v; Unchecked.defaultof> ) diff --git a/tests/fsharp/typecheck/sigs/neg122.bsl b/tests/fsharp/typecheck/sigs/neg122.bsl new file mode 100644 index 00000000000..7fb422b9f43 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg122.bsl @@ -0,0 +1,2 @@ + +neg122.fs(19,28,19,38): typecheck error FS0001: The type 'string' does not support the operator 'ParseApply' diff --git a/tests/fsharp/typecheck/sigs/neg122.fs b/tests/fsharp/typecheck/sigs/neg122.fs new file mode 100644 index 00000000000..981460feb12 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg122.fs @@ -0,0 +1,19 @@ +module Neg122 + +// See https://github.com/dotnet/fsharp/pull/3582#issuecomment-399755533, which listed +// this as a test case of interest. +// +// This is to pin down that behaviour doesn't change in the future unless we intend it to. +open System +type System.String with static member inline ParseApply (path:string) (fn: string -> ^b) : ^b = fn "" +type System.Int32 with static member inline ParseApply (path:string) (fn: int -> ^b) : ^b = fn 0 +type System.Double with static member inline ParseApply (path:string) (fn: float -> ^b) : ^b = fn 0. +type System.Boolean with static member inline ParseApply (path:string) (fn: bool -> ^b) : ^b = fn true + +let inline parser (fmt:PrintfFormat< ^a -> ^b,_,_,^b>) (fn:^a -> ^b) (v:string) : ^b + when ^a : (static member ParseApply: string -> (^a -> ^b) -> ^b) = + (^a : (static member ParseApply: string -> (^a -> ^b) -> ^b)(v,fn)) + +let inline patternTest (fmt:PrintfFormat< ^a -> Action< ^T>,_,_,Action< ^T>>) (fn:^a -> Action< ^T>) v : Action< ^T> = parser fmt fn v + +let parseFn2 = patternTest "adf%s245" (fun v -> printfn "%s" v; Unchecked.defaultof> ) diff --git a/tests/fsharp/typecheck/sigs/neg123.bsl b/tests/fsharp/typecheck/sigs/neg123.bsl new file mode 100644 index 00000000000..a944f087500 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg123.bsl @@ -0,0 +1,2 @@ + +neg123.fs(19,18,19,27): typecheck error FS0003: This value is not a function and cannot be applied. diff --git a/tests/fsharp/typecheck/sigs/neg123.fs b/tests/fsharp/typecheck/sigs/neg123.fs new file mode 100644 index 00000000000..14943058132 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg123.fs @@ -0,0 +1,19 @@ +module Neg123 + +type Switcher = Switcher + +let inline checker< ^s, ^r when (^s or ^r) : (static member pass : ^r -> unit)> (s : ^s) (r : ^r) = () + +let inline format () : ^r = + checker Switcher Unchecked.defaultof< ^r> + () :> obj :?> ^r + +type Switcher with + static member inline pass(_ : string -> ^r) = + checker Switcher Unchecked.defaultof< ^r> + static member inline pass(_ : int -> ^r) = + checker Switcher Unchecked.defaultof< ^r> + static member inline pass(_ : unit) = () + static member inline pass(_ : int) = () + +let res : unit = format () "text" 5 "more text" () diff --git a/tests/fsharp/typecheck/sigs/neg124.bsl b/tests/fsharp/typecheck/sigs/neg124.bsl new file mode 100644 index 00000000000..5b13ecc8bd6 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg124.bsl @@ -0,0 +1,16 @@ + +neg124.fs(39,27,39,35): typecheck error FS0071: Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'unsigned_witness'. + +Known return type: uint8 + +Known type parameter: < obj > + +Available overloads: + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: byte -> byte // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: int16 -> uint16 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: int32 -> uint32 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: int64 -> uint64 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: sbyte -> uint8 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: uint16 -> uint16 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: uint32 -> uint32 // Argument 'x' doesn't match + - static member Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector.witnesses.unsigned_witness: x: uint64 -> uint64 // Argument 'x' doesn't match Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg124.fs b/tests/fsharp/typecheck/sigs/neg124.fs new file mode 100644 index 00000000000..d8a7c937dd4 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg124.fs @@ -0,0 +1,40 @@ +module Neg124 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +module Negative_SelectOverloadedWitnessBasedOnInputAndReturnTypeWithoutOutputTypeSelector = + type witnesses = + static member inline unsigned_witness (x : sbyte) = uint8 x + static member inline unsigned_witness (x : byte) = x + static member inline unsigned_witness (x : int16) = uint16 x + static member inline unsigned_witness (x : uint16) = x + static member inline unsigned_witness (x : int32) = uint32 x + static member inline unsigned_witness (x : uint32) = x + static member inline unsigned_witness (x : int64) = uint64 x + static member inline unsigned_witness (x : uint64) = x + + // Note, this doesn't try to use the output to select + let inline call_unsigned_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member unsigned_witness : ^input -> ^output)> (x : ^input) = + ((^witnesses or ^input) : (static member unsigned_witness : ^input -> ^output) x) + + // unsigned: ^a -> ^b + let inline unsigned num = call_unsigned_witness num + + // Positive cases + let v1 = unsigned 0y + let v2 = unsigned 0s + let v3 = unsigned 0 + let v4 = unsigned 0L + + let f1 : int8 -> uint8 = unsigned + let f2 : int16 -> uint16 = unsigned + let f3 : int32 -> uint32 = unsigned + let f4 : int64 -> uint64 = unsigned + + let g1 : int8 -> _ = unsigned + let g2 : int16 -> _ = unsigned + let g3 : int32 -> _ = unsigned + let g4 : int64 -> _ = unsigned + + // Negative case - not enough information here + let h1 : _ -> uint8 = unsigned + \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/neg125.bsl b/tests/fsharp/typecheck/sigs/neg125.bsl new file mode 100644 index 00000000000..17a6052b4e5 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg125.bsl @@ -0,0 +1,273 @@ + +neg125.fs(39,30,39,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(40,30,40,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int64 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(41,31,41,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: bigint + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(42,30,42,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: float + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(43,30,43,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: sbyte + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(44,30,44,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int16 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(45,29,45,31): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: byte + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(46,31,46,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint16 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(47,31,47,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(48,32,48,34): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint64 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(49,33,49,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: float32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(50,33,50,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: decimal + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg125.fs(51,33,51,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: Complex + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 diff --git a/tests/fsharp/typecheck/sigs/neg125.fs b/tests/fsharp/typecheck/sigs/neg125.fs new file mode 100644 index 00000000000..f2a0975a06d --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg125.fs @@ -0,0 +1,51 @@ +module Neg125 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// See also pos35.fs +// +// This removes ^output as a type selector for the witness, and no longer passes a dummy ^output +// +// This means that when both ^witnesses and ^input are known, the overload determining the ^output still can't be determined, +// and overload resolutiuon failures are reported +module Negative_SelectOverloadedWitnessBasedOnReturnTypeWithoutOutputTypeSelectAndWithoutPassingDummyArgument = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint) = x + static member inline convert_witness (x : bigint) = float x + static member inline convert_witness (x : bigint) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint) = float32 x + static member inline convert_witness (x : bigint) = decimal x + static member inline convert_witness (x : bigint) = Complex(float x, 0.0) + // Note ^output in the list of "or" types + let inline call_convert_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member convert_witness : ^input -> ^output)> (b : ^input) = + ((^witnesses or ^input) : (static member convert_witness : ^input -> ^output) (b)) + + let inline convert num = + call_convert_witness (num) + + let v1 : int32 = convert 0I + let v2 : int64 = convert 0I + let v3 : bigint = convert 0I + let v4 : float = convert 0I + let v5 : sbyte = convert 0I + let v6 : int16 = convert 0I + let v7 : byte = convert 0I + let v8 : uint16 = convert 0I + let v9 : uint32 = convert 0I + let v10 : uint64 = convert 0I + let v11 : float32 = convert 0I + let v12 : decimal = convert 0I + let v13 : Complex = convert 0I diff --git a/tests/fsharp/typecheck/sigs/neg126.bsl b/tests/fsharp/typecheck/sigs/neg126.bsl new file mode 100644 index 00000000000..b8808b85143 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg126.bsl @@ -0,0 +1,2 @@ + +neg126.fs(30,32,30,48): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'sbyte'. diff --git a/tests/fsharp/typecheck/sigs/neg126.fs b/tests/fsharp/typecheck/sigs/neg126.fs new file mode 100644 index 00000000000..232a35bb9c1 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg126.fs @@ -0,0 +1,32 @@ +module Neg126 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// Here we are attempting to select a witness based on input type. +// +// However, only one witness is present. +// +// Due to the problem described in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580396911, +// "generic inline code we apply weak resolution to constraints that could otherwise be generalised", +// this generates a warning because overload resolution is invoked and the input type of "foo" becomes "sbyte" +// +// The inferred type should ideally be +// foo: ^a -> ^b +// but is actually +// foo: sbyte -> byte +// +// That is, the code is not generic at all, because the F# compiler thinks that it commit to the one and only witness. +// +// This test exists to pin down that we get a warning produced saying ^a has been instantiated to "sbyte" + +module Negative_SelectOverloadedWitnessBasedOnInputTypeOneWitness = + type witnesses = + static member inline foo_witness (x : sbyte) : byte = byte x + + // Note, this doesn't try to use the output to select + let inline call_foo_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member foo_witness : ^input -> ^output)> (x : ^input) = + ((^witnesses or ^input) : (static member foo_witness : ^input -> ^output) x) + + let inline foo (num: ^a) = call_foo_witness num + let v1 = foo 0y + diff --git a/tests/fsharp/typecheck/sigs/neg127.bsl b/tests/fsharp/typecheck/sigs/neg127.bsl new file mode 100644 index 00000000000..76b3c8e353f --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg127.bsl @@ -0,0 +1,273 @@ + +neg127.fs(47,30,47,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(48,30,48,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int64 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(49,31,49,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: bigint + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(50,30,50,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: float + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(51,30,51,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: sbyte + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(52,30,52,32): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: int16 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(53,29,53,31): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: byte + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(54,31,54,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint16 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(55,31,55,33): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(56,32,56,34): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: uint64 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(57,33,57,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: float32 + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(58,33,58,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: decimal + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 + +neg127.fs(59,33,59,35): typecheck error FS0001: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: Complex + +Known type parameter: < BigInteger > + +Candidates: + - static member witnesses.convert_witness: x: bigint -> Complex + - static member witnesses.convert_witness: x: bigint -> bigint + - static member witnesses.convert_witness: x: bigint -> byte + - static member witnesses.convert_witness: x: bigint -> decimal + - static member witnesses.convert_witness: x: bigint -> float + - static member witnesses.convert_witness: x: bigint -> float32 + - static member witnesses.convert_witness: x: bigint -> int + - static member witnesses.convert_witness: x: bigint -> int16 + - static member witnesses.convert_witness: x: bigint -> int64 + - static member witnesses.convert_witness: x: bigint -> sbyte + - static member witnesses.convert_witness: x: bigint -> uint16 + - static member witnesses.convert_witness: x: bigint -> uint32 + - static member witnesses.convert_witness: x: bigint -> uint64 diff --git a/tests/fsharp/typecheck/sigs/neg127.fs b/tests/fsharp/typecheck/sigs/neg127.fs new file mode 100644 index 00000000000..ba44a1ae772 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg127.fs @@ -0,0 +1,59 @@ +module Neg127 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// See also pos35.fs, neg125.fs +// +// This no longer passes a dummy ^output but keeps ^output as a witness selector +// +// When both ^witnesses and ^input are known, the overload determining the ^output still can't be determined. +// However overload resolution is **not** delayed because the language rule is that overload resolution +// goes ahead once the support in the **argument** types of the constraint have all been resolved. +// +// This design decision for SRTP resolution was based on the (technically false but normally true) assumption that +// overload resolution will not depend on return type. +// +// The workaround for this in SRTP generic code is to pass a dummy Unchecked.defaultof<_> argument of the type of the +// return type. + +module Negative_SelectOverloadedWitnessBasedOnReturnTypeWithoutPassingDummyArgument = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint) = x + static member inline convert_witness (x : bigint) = float x + static member inline convert_witness (x : bigint) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint) = float32 x + static member inline convert_witness (x : bigint) = decimal x + static member inline convert_witness (x : bigint) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, ^output when (^witnesses or ^input or ^output) : (static member convert_witness : ^input -> ^output)> (b : ^input) = + ((^witnesses or ^input or ^output) : (static member convert_witness : ^input -> ^output) (b)) + + let inline convert num = + call_convert_witness (num) + // These all cause errors + let v1 : int32 = convert 0I + let v2 : int64 = convert 0I + let v3 : bigint = convert 0I + let v4 : float = convert 0I + let v5 : sbyte = convert 0I + let v6 : int16 = convert 0I + let v7 : byte = convert 0I + let v8 : uint16 = convert 0I + let v9 : uint32 = convert 0I + let v10 : uint64 = convert 0I + let v11 : float32 = convert 0I + let v12 : decimal = convert 0I + let v13 : Complex = convert 0I diff --git a/tests/fsharp/typecheck/sigs/neg128.bsl b/tests/fsharp/typecheck/sigs/neg128.bsl new file mode 100644 index 00000000000..bf6b57d9ba6 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg128.bsl @@ -0,0 +1,21 @@ + +neg128.fs(36,47,36,54): typecheck error FS0043: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: 'output + +Known type parameters: < bigint , 'output > + +Candidates: + - static member witnesses.convert_witness: x: bigint * _output: Complex -> Complex + - static member witnesses.convert_witness: x: bigint * _output: bigint -> bigint + - static member witnesses.convert_witness: x: bigint * _output: byte -> byte + - static member witnesses.convert_witness: x: bigint * _output: decimal -> decimal + - static member witnesses.convert_witness: x: bigint * _output: float -> float + - static member witnesses.convert_witness: x: bigint * _output: float32 -> float32 + - static member witnesses.convert_witness: x: bigint * _output: int16 -> int16 + - static member witnesses.convert_witness: x: bigint * _output: int32 -> int + - static member witnesses.convert_witness: x: bigint * _output: int64 -> int64 + - static member witnesses.convert_witness: x: bigint * _output: sbyte -> sbyte + - static member witnesses.convert_witness: x: bigint * _output: uint16 -> uint16 + - static member witnesses.convert_witness: x: bigint * _output: uint32 -> uint32 + - static member witnesses.convert_witness: x: bigint * _output: uint64 -> uint64 diff --git a/tests/fsharp/typecheck/sigs/neg128.fs b/tests/fsharp/typecheck/sigs/neg128.fs new file mode 100644 index 00000000000..b936ee254b6 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg128.fs @@ -0,0 +1,36 @@ +module Neg128 + +module Negative_SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentGenericOutputSelector = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint, _output : int32) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint, _output : int64) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint, _output : bigint) = x + static member inline convert_witness (x : bigint, _output : float) = float x + static member inline convert_witness (x : bigint, _output : sbyte) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint, _output : int16) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint, _output : byte) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint, _output : uint16) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint, _output : uint32) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint, _output : uint64) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint, _output : float32) = float32 x + static member inline convert_witness (x : bigint, _output : decimal) = decimal x + static member inline convert_witness (x : bigint, _output : Complex) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, 'output when (^witnesses or ^input) : (static member convert_witness : ^input * 'output -> 'output)> (b : ^input, c : 'output) = + ((^witnesses or ^input) : (static member convert_witness : ^input * 'output -> 'output) (b, c)) + + let inline convert num : 'output = + call_convert_witness (num, Unchecked.defaultof<'output>) + + // These solve ok + let v1 : int32 = convert 777I + let v2 : int64 = convert 777I + + // This gives an error, because solving kicks in once all selector types are known + let inline inst (num: bigint) : 'output = convert num diff --git a/tests/fsharp/typecheck/sigs/neg129.bsl b/tests/fsharp/typecheck/sigs/neg129.bsl new file mode 100644 index 00000000000..82773932a9f --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg129.bsl @@ -0,0 +1,21 @@ + +neg129.fs(67,47,67,54): typecheck error FS0043: A unique overload for method 'convert_witness' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known return type: ^output + +Known type parameters: < bigint , ^output > + +Candidates: + - static member witnesses.convert_witness: x: bigint * _output: Complex -> Complex + - static member witnesses.convert_witness: x: bigint * _output: bigint -> bigint + - static member witnesses.convert_witness: x: bigint * _output: byte -> byte + - static member witnesses.convert_witness: x: bigint * _output: decimal -> decimal + - static member witnesses.convert_witness: x: bigint * _output: float -> float + - static member witnesses.convert_witness: x: bigint * _output: float32 -> float32 + - static member witnesses.convert_witness: x: bigint * _output: int16 -> int16 + - static member witnesses.convert_witness: x: bigint * _output: int32 -> int + - static member witnesses.convert_witness: x: bigint * _output: int64 -> int64 + - static member witnesses.convert_witness: x: bigint * _output: sbyte -> sbyte + - static member witnesses.convert_witness: x: bigint * _output: uint16 -> uint16 + - static member witnesses.convert_witness: x: bigint * _output: uint32 -> uint32 + - static member witnesses.convert_witness: x: bigint * _output: uint64 -> uint64 diff --git a/tests/fsharp/typecheck/sigs/neg129.fs b/tests/fsharp/typecheck/sigs/neg129.fs new file mode 100644 index 00000000000..d65671900bd --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg129.fs @@ -0,0 +1,67 @@ +module Neg129 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// This removes ^output as a type selector for the witness, but continues to pass a dummy ^output +// +// This is sufficient to make nearly all resolutions go through except when we instantiate by input type alone +module Negative_SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentNoOutputSelector = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint, _output : int32) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint, _output : int64) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint, _output : bigint) = x + static member inline convert_witness (x : bigint, _output : float) = float x + static member inline convert_witness (x : bigint, _output : sbyte) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint, _output : int16) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint, _output : byte) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint, _output : uint16) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint, _output : uint32) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint, _output : uint64) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint, _output : float32) = float32 x + static member inline convert_witness (x : bigint, _output : decimal) = decimal x + static member inline convert_witness (x : bigint, _output : Complex) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member convert_witness : ^input * ^output -> ^output)> (b : ^input, c : ^output) = + ((^witnesses or ^input) : (static member convert_witness : ^input * ^output -> ^output) (b, c)) + + let inline convert num = + call_convert_witness (num, Unchecked.defaultof<'b>) + + // These are ok + let v1 : int32 = convert 777I + let v2 : int64 = convert 777I + let v3 : bigint = convert 777I + let v4 : float = convert 777I + let v5 : sbyte = convert 777I + let v6 : int16 = convert 777I + let v7 : byte = convert 777I + let v8 : uint16 = convert 777I + let v9 : uint32 = convert 777I + let v10 : uint64 = convert 777I + let v11 : float32 = convert 777I + let v12 : decimal = convert 777I + let v13 : Complex = convert 777I + + // These are ok + let f1 : _ -> int32 = convert + let f2 : _ -> int64 = convert + let f3 : _ -> bigint = convert + let f4 : _ -> float = convert + let f5 : _ -> sbyte = convert + let f6 : _ -> int16 = convert + let f7 : _ -> byte = convert + let f8 : _ -> uint16 = convert + let f9 : _ -> uint32 = convert + let f10 : _ -> uint64 = convert + let f11 : _ -> float32 = convert + let f12 : _ -> decimal = convert + let f13 : _ -> Complex = convert + + // This gives an error, because all selector types are known and overload resolution kicks in + let inline inst (num: bigint) : ^output = convert num diff --git a/tests/fsharp/typecheck/sigs/neg130.bsl b/tests/fsharp/typecheck/sigs/neg130.bsl new file mode 100644 index 00000000000..29c3307c67c --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg130.bsl @@ -0,0 +1,8 @@ + +neg130.fs(11,17,11,50): typecheck error FS0001: A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation. + +neg130.fs(15,14,15,47): typecheck error FS0001: A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation. + +neg130.fs(21,17,21,50): typecheck error FS0001: A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation. + +neg130.fs(25,14,25,47): typecheck error FS0001: A generic construct requires that a generic type parameter be known as a struct or reference type. Consider adding a type annotation. diff --git a/tests/fsharp/typecheck/sigs/neg130.fs b/tests/fsharp/typecheck/sigs/neg130.fs new file mode 100644 index 00000000000..5bb47f6daf5 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg130.fs @@ -0,0 +1,27 @@ +module Neg130 + +open System + +let PlaceDefaultConstructorConstraint<'T when 'T : (new : unit -> 'T)> (x : 'T) = x + +module TestVariableTypesForTuples = + + // The case for type variables (declared) where struct/reference is not known + type T3b<'T>(x : struct (int * 'T)) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + // The case for type variables (inferred) where struct/reference is not known + let f3b (x : struct (int * 'T)) = + x |> PlaceDefaultConstructorConstraint |> ignore + +module TestVariableTypesForAnonRecords = + // Struct anon record are always considered to satisfy ValueType constraint + // + type T3b<'T>(x : struct {| X : int; Y : 'T |}) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + // The case for type variables (inferred) where struct/reference is not known + let f3b (x : struct {| X : int; Y : 'T |}) = + x |> PlaceDefaultConstructorConstraint |> ignore + + diff --git a/tests/fsharp/typecheck/sigs/neg15.bsl b/tests/fsharp/typecheck/sigs/neg15.bsl index c8c59c1dc29..055ddf9fcc3 100644 --- a/tests/fsharp/typecheck/sigs/neg15.bsl +++ b/tests/fsharp/typecheck/sigs/neg15.bsl @@ -30,21 +30,15 @@ neg15.fs(115,19,115,48): typecheck error FS0072: Lookup on object of indetermina neg15.fs(116,20,116,73): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. neg15.fs(122,32,122,57): typecheck error FS0039: The value, constructor, namespace or type 'InternalTagOfInternalType' is not defined. Maybe you want one of the following: - InternalUnionType - InternalRecordType - DefaultTagOfInternalType neg15.fs(128,31,128,61): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. neg15.fs(135,31,135,56): typecheck error FS0039: The value, constructor, namespace or type 'InternalTagOfInternalType' is not defined. Maybe you want one of the following: - InternalUnionType - InternalRecordType - DefaultTagOfInternalType neg15.fs(141,30,141,60): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. @@ -69,4 +63,4 @@ neg15.fs(190,1,190,6): typecheck error FS0491: The member or object constructor neg15.fs(191,1,191,8): typecheck error FS0491: The member or object constructor 'SM' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions. -neg15.fs(204,11,204,16): typecheck error FS0501: The object constructor 'X2' takes 0 argument(s) but is here given 1. The required signature is 'new : unit -> X2'. +neg15.fs(204,11,204,16): typecheck error FS0501: The object constructor 'X2' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> X2'. diff --git a/tests/fsharp/typecheck/sigs/neg16.bsl b/tests/fsharp/typecheck/sigs/neg16.bsl index 555e62a1024..c32ad022d1f 100644 --- a/tests/fsharp/typecheck/sigs/neg16.bsl +++ b/tests/fsharp/typecheck/sigs/neg16.bsl @@ -63,30 +63,34 @@ but here has type neg16.fs(85,8,85,18): typecheck error FS0039: The pattern discriminator 'FooA++' is not defined. +neg16.fs(85,7,85,22): typecheck error FS0025: Incomplete pattern matches on this expression. + neg16.fs(87,50,87,54): typecheck error FS0039: The value or constructor 'OneA' is not defined. neg16.fs(87,60,87,69): typecheck error FS0039: The value or constructor 'TwoA+' is not defined. neg16.fs(90,8,90,18): typecheck error FS0039: The pattern discriminator 'FooB++' is not defined. -neg16.fs(97,15,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(90,7,90,22): typecheck error FS0025: Incomplete pattern matches on this expression. + +neg16.fs(96,3,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(100,11,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(99,3,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(100,11,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(99,3,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(103,7,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes +neg16.fs(102,3,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(103,7,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(102,3,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static neg16.fs(119,17,119,24): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes -neg16.fs(107,16,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(106,5,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(110,16,110,20): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(109,5,110,20): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(113,9,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(112,5,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static -neg16.fs(116,9,116,13): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static +neg16.fs(115,5,116,13): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static neg16.fs(130,10,130,11): typecheck error FS0935: Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal diff --git a/tests/fsharp/typecheck/sigs/neg17.bsl b/tests/fsharp/typecheck/sigs/neg17.bsl index 499430cdaa7..673e0b7ec78 100644 --- a/tests/fsharp/typecheck/sigs/neg17.bsl +++ b/tests/fsharp/typecheck/sigs/neg17.bsl @@ -5,16 +5,14 @@ neg17b.fs(7,17,7,31): typecheck error FS1094: The value 'privateValue' is not ac neg17b.fs(8,18,8,43): typecheck error FS1092: The type 'PrivateUnionType' is not accessible from this code location -neg17b.fs(11,26,11,41): typecheck error FS0039: The field, constructor or member 'PrivateProperty' is not defined. - -neg17b.fs(12,24,12,45): typecheck error FS0039: The field, constructor or member 'PrivateStaticProperty' is not defined. Maybe you want one of the following: +neg17b.fs(11,26,11,41): typecheck error FS0039: The type 'Type' does not define the field, constructor or member 'PrivateProperty'. +neg17b.fs(12,24,12,45): typecheck error FS0039: The type 'Type' does not define the field, constructor or member 'PrivateStaticProperty'. Maybe you want one of the following: InternalStaticProperty -neg17b.fs(13,26,13,39): typecheck error FS0039: The field, constructor or member 'PrivateMethod' is not defined. - -neg17b.fs(14,24,14,43): typecheck error FS0039: The field, constructor or member 'PrivateStaticMethod' is not defined. Maybe you want one of the following: +neg17b.fs(13,26,13,39): typecheck error FS0039: The type 'Type' does not define the field, constructor or member 'PrivateMethod'. +neg17b.fs(14,24,14,43): typecheck error FS0039: The type 'Type' does not define the field, constructor or member 'PrivateStaticMethod'. Maybe you want one of the following: InternalStaticMethod neg17b.fs(15,17,15,52): typecheck error FS1092: The type 'PrivateRecordType' is not accessible from this code location @@ -26,9 +24,7 @@ neg17b.fs(16,19,16,48): typecheck error FS0072: Lookup on object of indeterminat neg17b.fs(17,19,17,47): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. neg17b.fs(21,31,21,77): typecheck error FS0039: The value, constructor, namespace or type 'DefaultTagOfUnionTypeWithPrivateRepresentation' is not defined. Maybe you want one of the following: - DefaultTagOfInternalType - UnionTypeWithPrivateRepresentation neg17b.fs(29,31,29,61): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. @@ -36,13 +32,11 @@ neg17b.fs(29,31,29,61): typecheck error FS0072: Lookup on object of indeterminat neg17b.fs(30,31,30,84): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. neg17b.fs(32,24,32,50): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined in 'Neg17.M'. Maybe you want one of the following: - RecordTypeWithPrivateRepresentation neg17b.fs(43,30,43,60): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. neg17b.fs(45,23,45,49): typecheck error FS0039: The type 'RecordTypeWithPrivateField' is not defined in 'Neg17.M'. Maybe you want one of the following: - RecordTypeWithPrivateRepresentation neg17b.fs(54,20,54,50): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl index ae9600cdae6..0fb6114762b 100644 --- a/tests/fsharp/typecheck/sigs/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/neg20.bsl @@ -69,17 +69,17 @@ neg20.fs(53,38,53,39): typecheck error FS0001: This expression was expected to h but here has type 'int' -neg20.fs(60,26,60,33): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'B'. This element has type 'A'. +neg20.fs(60,26,60,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'A'. -neg20.fs(61,27,61,35): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'B1'. This element has type 'B2'. +neg20.fs(61,27,61,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B1'. This element has type 'B2'. -neg20.fs(62,26,62,33): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'C'. This element has type 'B'. +neg20.fs(62,26,62,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'C'. This element has type 'B'. -neg20.fs(66,25,66,32): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'A'. This element has type 'B'. +neg20.fs(66,25,66,32): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'A'. This element has type 'B'. -neg20.fs(67,27,67,34): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'B'. This element has type 'C'. +neg20.fs(67,27,67,34): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'C'. -neg20.fs(70,31,70,38): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'B'. This element has type 'C'. +neg20.fs(70,31,70,38): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'C'. neg20.fs(71,34,71,42): typecheck error FS0001: Type mismatch. Expecting a 'A list' @@ -110,9 +110,9 @@ but given a 'B list' The type 'A' does not match the type 'B' -neg20.fs(83,47,83,54): typecheck error FS0001: All branches of an 'if' expression must return values of the same type as the first branch, which here is 'B'. This branch returns a value of type 'C'. +neg20.fs(83,47,83,54): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'B'. This branch returns a value of type 'C'. -neg20.fs(87,54,87,61): typecheck error FS0001: All branches of a pattern match expression must return values of the same type as the first branch, which here is 'B'. This branch returns a value of type 'C'. +neg20.fs(87,54,87,61): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'B'. This branch returns a value of type 'C'. neg20.fs(92,19,92,26): typecheck error FS0001: This expression was expected to have type 'A' @@ -129,7 +129,7 @@ neg20.fs(97,26,97,33): typecheck error FS0001: This expression was expected to h but here has type 'B' -neg20.fs(99,26,99,33): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'B'. This element has type 'A'. +neg20.fs(99,26,99,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'A'. neg20.fs(108,12,108,16): typecheck error FS0001: Type mismatch. Expecting a 'B * B -> 'a' @@ -159,57 +159,49 @@ neg20.fs(129,19,129,22): typecheck error FS0001: This expression was expected to but here has type 'string' -neg20.fs(131,5,131,24): typecheck error FS0041: No overloads match for method 'OM3'. The available overloads are shown below. -neg20.fs(131,5,131,24): typecheck error FS0041: Possible overload: 'static member C.OM3 : x:'b * y:int -> int'. Type constraint mismatch. The type - 'obj' -is not compatible with type - 'int' -. -neg20.fs(131,5,131,24): typecheck error FS0041: Possible overload: 'static member C.OM3 : x:'b * y:'b -> int'. Type constraint mismatch. The type - 'obj' -is not compatible with type - ''a' -. +neg20.fs(131,5,131,24): typecheck error FS0041: No overloads match for method 'OM3'. + +Known types of arguments: string * obj + +Available overloads: + - static member C.OM3: x: 'b * y: 'b -> int // Argument 'y' doesn't match + - static member C.OM3: x: 'b * y: int -> int // Argument 'y' doesn't match neg20.fs(152,13,152,23): typecheck error FS0033: The type 'Test.BadNumberOfGenericParameters.C<_>' expects 1 type argument(s) but is given 2 neg20.fs(153,13,153,23): typecheck error FS0033: The type 'Test.BadNumberOfGenericParameters.C<_>' expects 1 type argument(s) but is given 2 -neg20.fs(154,13,154,25): typecheck error FS0502: The member or object constructor 'SM1' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM1 : unit -> int'. +neg20.fs(154,13,154,25): typecheck error FS0502: The member or object constructor 'SM1' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM1: unit -> int'. -neg20.fs(155,13,155,26): typecheck error FS0502: The member or object constructor 'SM2' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM2 : y:int -> int'. +neg20.fs(155,13,155,26): typecheck error FS0502: The member or object constructor 'SM2' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM2: y: int -> int'. -neg20.fs(156,13,156,28): typecheck error FS0502: The member or object constructor 'SM3' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM3 : y:int * z:int -> int'. +neg20.fs(156,13,156,28): typecheck error FS0502: The member or object constructor 'SM3' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM3: y: int * z: int -> int'. -neg20.fs(157,28,157,29): typecheck error FS0495: The member or object constructor 'SM3' has no argument or settable return property 'x'. The required signature is static member C.SM3 : y:int * z:int -> int. +neg20.fs(157,28,157,29): typecheck error FS0495: The member or object constructor 'SM3' has no argument or settable return property 'x'. The required signature is static member C.SM3: y: int * z: int -> int. -neg20.fs(158,13,158,36): typecheck error FS0502: The member or object constructor 'SM4' takes 1 type argument(s) but is here given 2. The required signature is 'static member C.SM4 : y:'a * z:'b -> int'. +neg20.fs(158,13,158,36): typecheck error FS0502: The member or object constructor 'SM4' takes 1 type argument(s) but is here given 2. The required signature is 'static member C.SM4: y: 'a * z: 'b -> int'. -neg20.fs(159,13,159,32): typecheck error FS0502: The member or object constructor 'SM5' takes 2 type argument(s) but is here given 1. The required signature is 'static member C.SM5 : y:'a * z:'b -> int'. +neg20.fs(159,13,159,32): typecheck error FS0502: The member or object constructor 'SM5' takes 2 type argument(s) but is here given 1. The required signature is 'static member C.SM5: y: 'a * z: 'b -> int'. -neg20.fs(162,13,162,24): typecheck error FS0502: The member or object constructor 'M1' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M1 : unit -> int'. +neg20.fs(162,13,162,24): typecheck error FS0502: The member or object constructor 'M1' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M1: unit -> int'. -neg20.fs(163,13,163,25): typecheck error FS0502: The member or object constructor 'M2' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M2 : y:int -> int'. +neg20.fs(163,13,163,25): typecheck error FS0502: The member or object constructor 'M2' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M2: y: int -> int'. -neg20.fs(164,13,164,27): typecheck error FS0502: The member or object constructor 'M3' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M3 : y:int * z:int -> int'. +neg20.fs(164,13,164,27): typecheck error FS0502: The member or object constructor 'M3' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M3: y: int * z: int -> int'. -neg20.fs(165,27,165,28): typecheck error FS0495: The member or object constructor 'M3' has no argument or settable return property 'x'. The required signature is member C.M3 : y:int * z:int -> int. +neg20.fs(165,27,165,28): typecheck error FS0495: The member or object constructor 'M3' has no argument or settable return property 'x'. The required signature is member C.M3: y: int * z: int -> int. -neg20.fs(166,13,166,35): typecheck error FS0502: The member or object constructor 'M4' takes 1 type argument(s) but is here given 2. The required signature is 'member C.M4 : y:'a * z:'b -> int'. +neg20.fs(166,13,166,35): typecheck error FS0502: The member or object constructor 'M4' takes 1 type argument(s) but is here given 2. The required signature is 'member C.M4: y: 'a * z: 'b -> int'. -neg20.fs(167,13,167,31): typecheck error FS0502: The member or object constructor 'M5' takes 2 type argument(s) but is here given 1. The required signature is 'member C.M5 : y:'a * z:'b -> int'. +neg20.fs(167,13,167,31): typecheck error FS0502: The member or object constructor 'M5' takes 2 type argument(s) but is here given 1. The required signature is 'member C.M5: y: 'a * z: 'b -> int'. -neg20.fs(182,14,182,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg20.fs(182,14,182,31): typecheck error FS0041: Possible overload: 'static member C2.M : fmt:string * [] args:int [] -> string'. Type constraint mismatch. The type - 'obj' -is not compatible with type - 'int' -. -neg20.fs(182,14,182,31): typecheck error FS0041: Possible overload: 'static member C2.M : fmt:string * [] args:int [] -> string'. Type constraint mismatch. The type - 'obj' -is not compatible with type - 'int []' -. +neg20.fs(182,14,182,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * obj + +Available overloads: + - static member C2.M: fmt: string * [] args: int[] -> string // Argument 'args' doesn't match + - static member C2.M: fmt: string * [] args: int[] -> string // Argument at index 1 doesn't match neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type 'int' @@ -256,17 +248,13 @@ neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to but here has type 'obj' -neg20.fs(188,14,188,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg20.fs(188,14,188,31): typecheck error FS0041: Possible overload: 'static member C3.M : fmt:string * [] args:string [] -> string'. Type constraint mismatch. The type - 'obj' -is not compatible with type - 'string' -. -neg20.fs(188,14,188,31): typecheck error FS0041: Possible overload: 'static member C3.M : fmt:string * [] args:string [] -> string'. Type constraint mismatch. The type - 'obj' -is not compatible with type - 'string []' -. +neg20.fs(188,14,188,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * obj + +Available overloads: + - static member C3.M: fmt: string * [] args: string[] -> string // Argument 'args' doesn't match + - static member C3.M: fmt: string * [] args: string[] -> string // Argument at index 1 doesn't match neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type 'string' @@ -317,7 +305,7 @@ neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for neg20.fs(198,5,198,11): typecheck error FS0842: This attribute is not valid for use on this language element -neg20.fs(202,7,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations +neg20.fs(201,3,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations neg20.fs(204,5,204,14): typecheck error FS0842: This attribute is not valid for use on this language element @@ -389,9 +377,22 @@ neg20.fs(319,8,319,17): typecheck error FS3132: This type definition may not hav neg20.fs(322,8,322,18): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. -neg20.fs(335,11,335,24): typecheck error FS0041: A unique overload for method 'String' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.String(value: char []) : System.String, System.String(value: nativeptr) : System.String, System.String(value: nativeptr) : System.String +neg20.fs(335,11,335,24): typecheck error FS0041: A unique overload for method 'String' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - System.String(value: char[]) : System.String + - System.String(value: nativeptr) : System.String + - System.String(value: nativeptr) : System.String + +neg20.fs(336,11,336,22): typecheck error FS0041: A unique overload for method 'Guid' could not be determined based on type information prior to this program point. A type annotation may be needed. -neg20.fs(336,11,336,22): typecheck error FS0041: A unique overload for method 'Guid' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Guid(b: byte []) : System.Guid, System.Guid(g: string) : System.Guid +Known type of argument: 'a0 + +Candidates: + - System.Guid(b: byte[]) : System.Guid + - System.Guid(g: string) : System.Guid neg20.fs(355,19,355,38): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. @@ -407,10 +408,20 @@ neg20.fs(373,22,373,41): typecheck error FS1124: Multiple types exist called 'Ov neg20.fs(382,19,382,40): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. -neg20.fs(383,39,383,41): typecheck error FS0039: The field, constructor or member 'S2' is not defined. +neg20.fs(383,39,383,41): typecheck error FS0039: The type 'OverloadedClassName<_>' does not define the field, constructor or member 'S2'. neg20.fs(428,19,428,38): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' neg20.fs(430,22,430,41): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' -neg20.fs(444,39,444,41): typecheck error FS0039: The field, constructor or member 'S2' is not defined. +neg20.fs(444,39,444,41): typecheck error FS0039: The type 'OverloadedClassName' does not define the field, constructor or member 'S2'. + +neg20.fs(447,27,447,28): typecheck error FS0001: This expression was expected to have type + 'int option' +but here has type + 'int' + +neg20.fs(448,30,448,33): typecheck error FS0001: This expression was expected to have type + 'string option' +but here has type + 'string' diff --git a/tests/fsharp/typecheck/sigs/neg20.fs b/tests/fsharp/typecheck/sigs/neg20.fs index 5d465aeea93..4b0a08e0033 100644 --- a/tests/fsharp/typecheck/sigs/neg20.fs +++ b/tests/fsharp/typecheck/sigs/neg20.fs @@ -49,7 +49,7 @@ module BiGenericFunctionTests = module NoSubsumptionOnApplication = - (fun (x:A) -> 1) (new B()) // no: subsumption comes from de-condensation, not application! + (fun (x:A) -> 1) (new B()) // now permitted (fun (x:System.ValueType) -> 1) 1 // coercion on application! @@ -73,7 +73,7 @@ module NoSubsumptionForLists = // Q: how about on sequence expressions? let controls2 = [ yield (new B()) yield (new C()) ] - StaticClass2.DisplayControls controls2 // bang + StaticClass2.DisplayControls controls2 // Q: how about on sequence expressions? let controls3 = [ yield! [new B()] @@ -81,14 +81,14 @@ module NoSubsumptionForLists = StaticClass2.DisplayControls controls3 // bang let controls4 = if true then new B() else new C() - StaticClass2.DisplayControls [controls4] // bang + StaticClass2.DisplayControls [controls4] // allowed - // Q: how about on matches? Not covered. Decision: disallow + // Q: how about on matches? allowed let controls5 = match 1 with 1 -> new B() | _ -> new C() - StaticClass2.DisplayControls [controls5] // bang + StaticClass2.DisplayControls [controls5] // allowed - // Q. subsumption on 'let v = expr'? Not covered. Disallow + // Q. subsumption on 'let v = expr'? Allowed let x76 : A = new B() module NoSubsumptionForLists2 = @@ -126,7 +126,7 @@ module BiGenericMethodsInGenericClassTests = let str = "" C.M3("a",obj) // this is not permitted since 'b is inferred to be "string". Fair enough - C.M3(obj,"a") + C.M3(obj,"a") // now permitted C.OM3("a",obj) // this is not permitted since 'b is inferred to be "string". Fair enough @@ -443,3 +443,7 @@ module OverloadedTypeNamesIncludingNonGenericTypeNoConstructors = let t3 = 3 |> OverloadedClassName.S // NO ERROR EXPECTED let t4 = 3 |> OverloadedClassName.S2 // expected error - The field, constructor or member 'S2' is not defined +module OptionTypeOpImplicitsIgnored = + let x1 : int option = 3 + let x2 : string option = "a" + diff --git a/tests/fsharp/typecheck/sigs/neg24.bsl b/tests/fsharp/typecheck/sigs/neg24.bsl new file mode 100644 index 00000000000..1e46868f266 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg24.bsl @@ -0,0 +1,40 @@ + +neg24.fs(53,24,53,30): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(55,31,55,37): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(57,38,57,42): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(60,24,60,34): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(62,31,62,41): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(64,44,64,48): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. + +neg24.fs(70,15,70,18): typecheck error FS0495: The member or object constructor 'M' has no argument or settable return property 'qez'. The required signature is member C.M: abc: int * def: string -> int. + +neg24.fs(300,29,300,30): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(301,17,301,18): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(302,33,302,34): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. + +neg24.fs(302,36,302,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. + +neg24.fs(304,9,305,34): typecheck error FS0193: Type constraint mismatch. The type + 'int' +is not compatible with type + 'unit' + + +neg24.fs(308,30,308,31): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(309,31,309,32): typecheck error FS0001: This 'if' expression is missing an 'else' branch. Because 'if' is an expression, and not a statement, add an 'else' branch which also returns a value of type 'int'. + +neg24.fs(312,33,312,34): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(313,38,313,39): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(313,47,313,48): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. + +neg24.fs(337,37,337,42): typecheck error FS0020: The result of this expression has type 'obj' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. diff --git a/tests/fsharp/typecheck/sigs/neg24.fs b/tests/fsharp/typecheck/sigs/neg24.fs new file mode 100644 index 00000000000..38cb01cf2d2 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg24.fs @@ -0,0 +1,339 @@ +module Test +open Microsoft.FSharp.Quotations + + +let test2 (v : Expr<'a> -> Expr<'b>) = <@ fun (i: 'a) -> %v <@i@> @> + +let test (v : 'a -> Expr<'b>) = <@ fun (i: 'a) -> %(v i) @> + + +module OldNegative = + let v1 = [ if true then 1 else 2 ] // no longer an error or warning + let v2 = [ if true then () else () ] // no longer an error or warning + let v6 = [ if true then () ] // no longer an error or warning + let a1 = [| if true then 1 else 2 |] // no longer an error or warning + let a2 = [| if true then () else () |] // no longer an error or warning + let a6 = [| if true then () |] // no longer an error or warning + let s3 = seq { (if true then 1 else 2) } // no longer an error or warning + +// expect no warning +module Positive = + let v3 = [ (if true then 1 else 2) ] + let v4 = [ if true then yield 1 else yield 2 ] + let v5 = [ if true then yield 1 ] + let a3 = [| (if true then 1 else 2) |] + let a4 = [| if true then yield 1 else yield 2 |] + let a5 = [| if true then yield 1 |] + let s2 = seq { if true then () else () } + let s6 = seq { if true then () } + let s4 = seq { if true then yield 1 else yield 2 } + let s5 = seq { if true then yield 1 } + + +module BadCurriedExtensionMember = + type C() = + member x.P = 1 + + module M1 = + type C with + member x.M1 a b = a + b + member x.M2 (a,b) c = a + b + c + + module M2 = + type C with + member x.M1 a b = a + b + member x.M2 (a,b) c = a + b + c + + open M1 + open M2 + + let c = C() + + // negative test - error expected here + let x1 : int = c.M1 3 4 + // negative test - error expected here + let x2 : int -> int = c.M1 3 + // negative test - error expected here + let x3 : int -> int -> int = c.M1 + + // negative test - error expected here + let y1 : int = c.M2 (3,4) 4 + // negative test - error expected here + let y2 : int -> int = c.M2 (3,4) + // negative test - error expected here + let y3 : int * int -> int -> int = c.M2 + +type C() = + member x.M(abc:int,def:string) = abc + def.Length + +// Check that the error for a named argument/setter that does not exist is located in a good place +let _ = C().M(qez=3) + +module ListPositive2 = + // In this example, implicit yield is enabled becaue there is no explicit 'yield' + let v3 = + [ if true then 1 else 2 ] + + // In this example, implicit yield is enabled because there is no explicit 'yield'. + // When using implicit yield, statements are detected via a type-directed rule which tries + // checks the statement without an expected type and then checks if the type of the resulting + // expression has type 'unit'. + let v3a = + [ printfn "hello" + if true then 1 else 2 // implicit yield enabled + ] + + // In this example, implicit yield is enabled even though there is an explicit 'yield!' + // This is because using 'yield!' is the only way to yield anything + let v3b = + [ printfn "hello" + if true then 1 else 2 + yield! [] ] + + // This example checks subsumption is permitted when using implicit yield + let v3c : obj list = + [ printfn "hello" + if true then 1 else obj() ] + + // Another check that implicit yield is enabled , even though there is a `yield!` + let v3d = + [ if true then 1 else 2 + yield! [] ] + + // Another check that implicit yield is enabled , even though there is a `yield!` + let v3e = + [ yield! [] + if true then 1 else 2 + ] + + // Another check that implicit yield is enabled + let v3f = + [ if true then + printfn "hello" + 1 + else + 2 ] + + // Another check that implicit yield is enabled + let v3g = + [ if true then + 1 + else + printfn "hello" + 2 ] + + // Another check that implicit yield is enabled + let v3h = + [ for i in 1 .. 10 do + 10 + printfn "hello" ] + + // Another check that implicit yield is enabled + let v5 = + [ if true then 1 ] + + // Another check that implicit yield is enabled + let v5a = + [ printfn "hello"; + if true then 1 ] + + // Another check that implicit yield is enabled + let v5b = + [ if true then + printfn "hello" + 1 + ] + +module ArrayPositive2 = + let a3 = + [| (if true then 1 else 2) |] // simple single element sequence + + let a5 = + [| if true then 1 |] + + let l10 = + [ printfn "hello"; yield 1; yield 2 ] // expect ok - the printfn has type unit and is not interpreted as a yield + + // simple case of explicit yield + let l12 : int list = + [ printfn "hello" + if true then yield 1 else yield 2 ] + + // check subsumption is allowed when using explicit yield + let l13 : obj list = + [ printfn "hello" + if true then yield 1 else yield 2 ] + + // check subsumption is allowed when using explicit yield + let l14 : obj list = + [ printfn "hello" + if true then yield 1 ] + +module SeqPositive2 = + let s2 = + seq { if true then () else () } + + let s6 = + seq { if true then () } + + let s4 = + seq { if true then 1 else 2 } + + let s6 = + seq { if true then 1 } + + let s7 = + seq { match 1 with 1 -> 4 | 2 -> 5 | 3 -> 6 | _ -> () } + +module BuilderPositive2 = + type L<'T> = { Make: (unit -> 'T list) } + let L f = { Make = f } + + type ListBuilder() = + member __.Combine(x1: L<'T>, x2: L<'T>) = L(fun () -> x1.Make() @ x2.Make()) + member __.Delay(f: unit -> L<'T>) = L(fun () -> f().Make()) + member __.Zero() = L(fun () -> []) + member __.Yield(a: 'T) = L(fun () -> [a]) + member __.YieldFrom(x: L<'T>) = x + + let list = ListBuilder() + let empty<'T> : L<'T> = list.Zero() + + let v3 = + list { if true then 1 else 2 } // implicit yield enabled + + let v3y = + list { if true then yield 1 else yield 2 } // equivalent explicit yield + + let v3a = + list { + printfn "hello" + if true then 1 else 2 // implicit yield enabled + } + + let v3ay = + list { + printfn "hello" + if true then yield 1 else yield 2 // equivalent explicit yield + } + + let v3b = + list { + printfn "hello" + if true then 1 else 2 // implicit yield, even though there is a `yield!` + yield! empty + } + + let v3bc = + list { + printfn "hello" + if true then yield 1 else yield 2 // equivalent explicit yield + yield! empty + } + + + + + + + + + + + + + + let v3d = + list { + if true then 1 else 2 // implicit yield enabled , even though there is a `yield!` + yield! empty + } + + let v3dy = + list { + if true then yield 1 else yield 2 // equivalent explicit yield + yield! empty + } + + let v3e = + list { + yield! empty + if true then 1 else 2 // implicit yield enabled , even though there is a `yield!` + } + + let v3f = + list { + if true then + printfn "hello" + 1 + else 2 + } + + let v3g = + list { + if true then + 1 + else + printfn "hello" + 2 + } + + let v5 = + list { + if true then 1 + } + + let v5a = + list { + printfn "hello"; + if true then 1 + } + + let v5b = + list { + if true then + printfn "hello" + 1 + } + +module ListNegative2 = + let v4 = [ if true then 1 else yield 2 ] // expect warning about "1" being ignored. There is a 'yield' so statements are statements. + let l11 = [ 4; yield 1; yield 2 ] // expect warning about "1" being ignored. There is a 'yield' so statements are statements. + let l9 = [ printfn "hello"; 1; 2 ] // Note, this is interpreted as a "SimpleSemicolonSequence", so we get "All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element..." + let v3a : unit list = + [ printfn "hello" + if true then 1 else 2 ] + +module ArrayNegative2 = + let a4 = [| if true then 1 else yield 2 |] // expect warning about "1" being ignored. There is a 'yield' so statements are statements. + let a4 = [| (if true then 1) |] + +module SeqNegative2 = + let s5 = seq { if true then 1 else yield 2 } // expect warning about "1" being ignored. There is a 'yield' so statements are statements. + let s8 = seq { match 1 with 1 -> 4 | 2 -> 5 | 3 -> yield 6 | _ -> () } // expect warning about "4" being ignored. There is a 'yield' so statements are statements. + +module BuilderNegative2 = + type L<'T> = { Make: (unit -> 'T list) } + let L f = { Make = f } + + type ListBuilder() = + member __.Combine(x1: L<'T>, x2: L<'T>) = L(fun () -> x1.Make() @ x2.Make()) + member __.Delay(f: unit -> L<'T>) = L(fun () -> f().Make()) + member __.Zero() = L(fun () -> []) + member __.Yield(a: 'T) = L(fun () -> [a]) + member __.YieldFrom(x: L<'T>) = x + + let list = ListBuilder() + + let v3c : L = + list { + printfn "hello" + if true then 1 else obj() + } + + let v3c : L = + list { + printfn "hello" + if true then yield 1 else obj() + } + diff --git a/tests/fsharp/typecheck/sigs/neg25.bsl b/tests/fsharp/typecheck/sigs/neg25.bsl index 6a9653c42dc..50b01ad713e 100644 --- a/tests/fsharp/typecheck/sigs/neg25.bsl +++ b/tests/fsharp/typecheck/sigs/neg25.bsl @@ -1,26 +1,23 @@ -neg25.fs(15,23,15,31): typecheck error FS0366: No implementation was given for 'abstract member NegativeTests.Test1.ITest.Meth1 : string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(15,23,15,31): typecheck error FS0366: No implementation was given for 'abstract NegativeTests.Test1.ITest.Meth1: string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(32,23,32,31): typecheck error FS0366: No implementation was given for 'abstract member NegativeTests.Test2.ITest.Meth1 : string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(32,23,32,31): typecheck error FS0366: No implementation was given for 'abstract NegativeTests.Test2.ITest.Meth1: string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(64,19,64,45): typecheck error FS0366: No implementation was given for 'abstract member NegativeTestsActualRepro1.INodeWrapper.Node : NegativeTestsActualRepro1.Node'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(64,19,64,45): typecheck error FS0366: No implementation was given for 'abstract NegativeTestsActualRepro1.INodeWrapper.Node: NegativeTestsActualRepro1.Node'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(87,19,87,25): typecheck error FS0366: No implementation was given for 'abstract member NegativeTestsActualRepro3.IThing.Name : string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(87,19,87,25): typecheck error FS0366: No implementation was given for 'abstract NegativeTestsActualRepro3.IThing.Name: string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(104,19,104,27): typecheck error FS0366: No implementation was given for 'abstract member AnotherNegativeTest.ITestSub.Meth1 : int -> int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(104,19,104,27): typecheck error FS0366: No implementation was given for 'abstract AnotherNegativeTest.ITestSub.Meth1: int -> int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. neg25.fs(126,27,126,35): typecheck error FS0366: No implementation was given for those members: - - 'abstract member MissingInterfaceMemberTests.Test0.ITestSub.Meth2 : int -> int' - - 'abstract member MissingInterfaceMemberTests.Test0.ITest.Meth1 : string -> string' - + 'abstract MissingInterfaceMemberTests.Test0.ITestSub.Meth2: int -> int' + 'abstract MissingInterfaceMemberTests.Test0.ITest.Meth1: string -> string' Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(147,27,147,35): typecheck error FS0366: No implementation was given for 'abstract member MissingInterfaceMemberTests.Test1.ITest.Meth1 : string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(147,27,147,35): typecheck error FS0366: No implementation was given for 'abstract MissingInterfaceMemberTests.Test1.ITest.Meth1: string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(171,27,171,35): typecheck error FS0366: No implementation was given for 'abstract member MissingInterfaceMemberTests.Test3.ITest.Meth1 : string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(171,27,171,35): typecheck error FS0366: No implementation was given for 'abstract MissingInterfaceMemberTests.Test3.ITest.Meth1: string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(192,23,192,45): typecheck error FS0366: No implementation was given for 'abstract member NegativeTestsActualRepro2.IEvent.Add2 : ('a -> unit) -> unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(192,23,192,45): typecheck error FS0366: No implementation was given for 'abstract NegativeTestsActualRepro2.IEvent.Add2: ('a -> unit) -> unit'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg25.fs(211,23,211,29): typecheck error FS0366: No implementation was given for 'abstract member NegativeTestsActualRepro4.IThing.Name : string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg25.fs(211,23,211,29): typecheck error FS0366: No implementation was given for 'abstract NegativeTestsActualRepro4.IThing.Name: string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. diff --git a/tests/fsharp/typecheck/sigs/neg26.bsl b/tests/fsharp/typecheck/sigs/neg26.bsl index d17ba9ed7ee..34d68fb5305 100644 --- a/tests/fsharp/typecheck/sigs/neg26.bsl +++ b/tests/fsharp/typecheck/sigs/neg26.bsl @@ -1,15 +1,13 @@ -neg26.fs(15,13,15,56): typecheck error FS0366: No implementation was given for 'abstract member ITest.Meth1 : string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg26.fs(15,13,15,56): typecheck error FS0366: No implementation was given for 'abstract ITest.Meth1: string -> string'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg26.fs(27,13,27,66): typecheck error FS0366: No implementation was given for 'abstract member ITestSub.Meth2 : int -> int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. +neg26.fs(27,13,27,66): typecheck error FS0366: No implementation was given for 'abstract ITestSub.Meth2: int -> int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. -neg26.fs(40,27,40,32): typecheck error FS0361: The override 'Meth1 : int -> int' implements more than one abstract slot, e.g. 'abstract member ITestSub.Meth1 : int -> int' and 'abstract member ITest.Meth1 : int -> int' +neg26.fs(40,27,40,32): typecheck error FS0361: The override 'Meth1: int -> int' implements more than one abstract slot, e.g. 'abstract ITestSub.Meth1: int -> int' and 'abstract ITest.Meth1: int -> int' -neg26.fs(53,27,53,32): typecheck error FS3213: The member 'Meth1 : 'a -> 'a' matches multiple overloads of the same method. +neg26.fs(53,27,53,32): typecheck error FS3213: The member 'Meth1: 'a -> 'a' matches multiple overloads of the same method. Please restrict it to one of the following: - - Meth1 : int -> int - - Meth1 : int -> int. + Meth1: int -> int + Meth1: int -> int. neg26.fs(52,15,52,23): typecheck error FS0783: At least one override did not correctly implement its corresponding abstract member diff --git a/tests/fsharp/typecheck/sigs/neg33.bsl b/tests/fsharp/typecheck/sigs/neg33.bsl index 5a68e0f57dd..25a5d57b43a 100644 --- a/tests/fsharp/typecheck/sigs/neg33.bsl +++ b/tests/fsharp/typecheck/sigs/neg33.bsl @@ -1,2 +1,2 @@ -neg33.fs(4,8,4,13): typecheck error FS0193: Module 'MyNS.File2' requires a value 'member File2.LSS.Bar : string -> int' +neg33.fs(4,8,4,13): typecheck error FS0193: Module 'MyNS.File2' requires a value 'member File2.LSS.Bar: string -> int' diff --git a/tests/fsharp/typecheck/sigs/neg34.bsl b/tests/fsharp/typecheck/sigs/neg34.bsl index 4cfced465c5..c36527910bf 100644 --- a/tests/fsharp/typecheck/sigs/neg34.bsl +++ b/tests/fsharp/typecheck/sigs/neg34.bsl @@ -1,2 +1,2 @@ -neg34.fsi(3,19,3,24): typecheck error FS0001: A type parameter is missing a constraint 'when 'a : struct' +neg34.fsi(3,19,3,24): typecheck error FS0001: A type parameter is missing a constraint 'when 'a: struct' diff --git a/tests/fsharp/typecheck/sigs/neg36.bsl b/tests/fsharp/typecheck/sigs/neg36.bsl index bbee183544f..e23c595d662 100644 --- a/tests/fsharp/typecheck/sigs/neg36.bsl +++ b/tests/fsharp/typecheck/sigs/neg36.bsl @@ -1,4 +1,4 @@ -neg36.fs(11,20,11,21): typecheck error FS0361: The override 'M : string -> int' implements more than one abstract slot, e.g. 'abstract member TestAbstractOverrides_Bug4232_Case1.D.M : 'U -> int' and 'abstract member TestAbstractOverrides_Bug4232_Case1.D.M : 'T -> int' +neg36.fs(11,20,11,21): typecheck error FS0361: The override 'M: string -> int' implements more than one abstract slot, e.g. 'abstract TestAbstractOverrides_Bug4232_Case1.D.M: 'U -> int' and 'abstract TestAbstractOverrides_Bug4232_Case1.D.M: 'T -> int' -neg36.fs(32,23,32,24): typecheck error FS0361: The override 'M : int -> unit' implements more than one abstract slot, e.g. 'abstract member TestAbstractOverrides_Bug4232_Case2.PB.M : 'a -> unit' and 'abstract member TestAbstractOverrides_Bug4232_Case2.PA.M : int -> unit' +neg36.fs(32,23,32,24): typecheck error FS0361: The override 'M: int -> unit' implements more than one abstract slot, e.g. 'abstract TestAbstractOverrides_Bug4232_Case2.PB.M: 'a -> unit' and 'abstract TestAbstractOverrides_Bug4232_Case2.PA.M: int -> unit' diff --git a/tests/fsharp/typecheck/sigs/neg37_a.bsl b/tests/fsharp/typecheck/sigs/neg37_a.bsl index 8a7ff772644..b1657dda675 100644 --- a/tests/fsharp/typecheck/sigs/neg37_a.bsl +++ b/tests/fsharp/typecheck/sigs/neg37_a.bsl @@ -1,2 +1,2 @@ -neg37_a.fs(7,26,7,41): typecheck error FS3068: The function or member 'Bar' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member BBB.Bar : ('T -> unit)'. +neg37_a.fs(7,26,7,41): typecheck error FS3068: The function or member 'Bar' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member BBB.Bar: ('T -> unit)'. diff --git a/tests/fsharp/typecheck/sigs/neg45.bsl b/tests/fsharp/typecheck/sigs/neg45.bsl index 466a998514d..59d7ec8fa86 100644 --- a/tests/fsharp/typecheck/sigs/neg45.bsl +++ b/tests/fsharp/typecheck/sigs/neg45.bsl @@ -11,7 +11,7 @@ neg45.fs(34,25,34,26): typecheck error FS0465: Type inference problem too compli neg45.fs(41,23,41,41): typecheck error FS0827: This is not a valid name for an active pattern -neg45.fs(52,14,52,17): typecheck error FS0039: The field, constructor or member 'Foo' is not defined. +neg45.fs(52,14,52,17): typecheck error FS0039: The type 'FooBir' does not define the field, constructor or member 'Foo'. neg45.fs(56,16,56,31): typecheck error FS0827: This is not a valid name for an active pattern @@ -53,11 +53,29 @@ neg45.fs(80,20,80,22): typecheck error FS0340: The signature and implementation neg45.fs(81,35,81,40): typecheck error FS0001: A type parameter is missing a constraint 'when 'T :> System.IComparable' -neg45.fs(89,26,89,40): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member D.M : 'a -> 'b, member D.M : 'a -> 'b +neg45.fs(89,26,89,40): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. -neg45.fs(97,26,97,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member D.M : 'a -> 'b, member D.M : 'a -> 'b +Known type of argument: R1 -neg45.fs(104,26,104,31): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member D.M : 'a -> 'b, member D.M : 'a -> 'b +Candidates: + - member D.M: 'a -> 'b + - member D.M: 'a -> 'b + +neg45.fs(97,26,97,55): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: (R1 * R1) + +Candidates: + - member D.M: 'a -> 'b + - member D.M: 'a -> 'b + +neg45.fs(104,26,104,31): typecheck error FS0041: A unique overload for method 'M' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: int + +Candidates: + - member D.M: 'a -> 'b + - member D.M: 'a -> 'b neg45.fs(105,24,105,25): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s). diff --git a/tests/fsharp/typecheck/sigs/neg45.fs b/tests/fsharp/typecheck/sigs/neg45.fs index 2958041e5e4..3f651a02211 100644 --- a/tests/fsharp/typecheck/sigs/neg45.fs +++ b/tests/fsharp/typecheck/sigs/neg45.fs @@ -70,15 +70,15 @@ module CheckThatNoConstraintPropagationHappensForTypeParameters = member x.P = 1 type Negative1<'T> = C<'T> - type Negative2<'T>() = inherit C<'T>() /// EXPECT ERROR - type Negative3<'T >() = abstract X : C<'T> /// EXPECT ERROR - type Negative4<'T > = UnionCase1 of C<'T> /// EXPECT ERROR - type Negative5<'T > = { rf1 : C<'T> } /// EXPECT ERROR - type Negative6<'T >(rf1: C<'T>) = struct end /// EXPECT ERROR - type Negative7<'T > = val rf1 : C<'T> /// EXPECT ERROR - type Negative8<'T >(c: C<'T>) = member x.P = 1 /// EXPECT ERROR - type Negative9<'T>(x : C<'T> when 'T :> System.IComparable) = member x.P = 1 /// EXPECT ERROR - type Negative10<'T when 'T :> C<'T> > = member x.P = 1 /// EXPECT ERROR + type Negative2<'T>() = inherit C<'T>() // EXPECT ERROR + type Negative3<'T >() = abstract X : C<'T> // EXPECT ERROR + type Negative4<'T > = UnionCase1 of C<'T> // EXPECT ERROR + type Negative5<'T > = { rf1 : C<'T> } // EXPECT ERROR + type Negative6<'T >(rf1: C<'T>) = struct end // EXPECT ERROR + type Negative7<'T > = val rf1 : C<'T> // EXPECT ERROR + type Negative8<'T >(c: C<'T>) = member x.P = 1 // EXPECT ERROR + type Negative9<'T>(x : C<'T> when 'T :> System.IComparable) = member x.P = 1 // EXPECT ERROR + type Negative10<'T when 'T :> C<'T> > = member x.P = 1 // EXPECT ERROR module CheckNoOverloadResolutionAgainstSignatureInformationGivenByTUpledAndRecordPatterns = diff --git a/tests/fsharp/typecheck/sigs/neg47.bsl b/tests/fsharp/typecheck/sigs/neg47.bsl index 52964659d68..7653ed8d5b1 100644 --- a/tests/fsharp/typecheck/sigs/neg47.bsl +++ b/tests/fsharp/typecheck/sigs/neg47.bsl @@ -1,8 +1,8 @@ neg47.fs(18,9,18,26): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(24,12,24,33): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(23,5,24,33): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(29,16,29,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(28,9,29,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module -neg47.fs(33,12,33,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module +neg47.fs(32,5,33,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module diff --git a/tests/fsharp/typecheck/sigs/neg55.bsl b/tests/fsharp/typecheck/sigs/neg55.bsl index aca6b07765a..76f4b6b8c81 100644 --- a/tests/fsharp/typecheck/sigs/neg55.bsl +++ b/tests/fsharp/typecheck/sigs/neg55.bsl @@ -1,6 +1,6 @@ neg55.fs(10,5,10,19): typecheck error FS0491: The member or object constructor '.cctor' is not accessible. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions. -neg55.fs(19,7,19,16): typecheck error FS0039: The field, constructor or member '.ctor' is not defined. +neg55.fs(19,7,19,16): typecheck error FS0039: The type 'D' does not define the field, constructor or member '.ctor'. neg55.fs(24,22,24,31): typecheck error FS3066: Invalid member name. Members may not have name '.ctor' or '.cctor' diff --git a/tests/fsharp/typecheck/sigs/neg56.bsl b/tests/fsharp/typecheck/sigs/neg56.bsl index 3dbb2483d76..1c1fbd7bcda 100644 --- a/tests/fsharp/typecheck/sigs/neg56.bsl +++ b/tests/fsharp/typecheck/sigs/neg56.bsl @@ -1,10 +1,10 @@ -neg56.fs(9,39,9,44): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A : unit -> 'T'. +neg56.fs(9,39,9,44): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A: unit -> 'T'. -neg56.fs(12,36,12,41): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A : unit -> 'T'. +neg56.fs(12,36,12,41): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A: unit -> 'T'. -neg56.fs(15,39,15,44): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A : unit -> 'T'. +neg56.fs(15,39,15,44): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'member C.A: unit -> 'T'. -neg56.fs(26,30,26,43): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member C.A : unit -> 'T'. +neg56.fs(26,30,26,43): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member C.A: unit -> 'T'. -neg56.fs(27,30,27,40): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member C.A : unit -> 'T'. +neg56.fs(27,30,27,40): typecheck error FS3068: The function or member 'A' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member C.A: unit -> 'T'. diff --git a/tests/fsharp/typecheck/sigs/neg56_b.bsl b/tests/fsharp/typecheck/sigs/neg56_b.bsl index c3bc36c80c7..4e844fe5979 100644 --- a/tests/fsharp/typecheck/sigs/neg56_b.bsl +++ b/tests/fsharp/typecheck/sigs/neg56_b.bsl @@ -1,8 +1,8 @@ -neg56_b.fs(8,36,8,39): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member Foo.Inf : 'T ref'. +neg56_b.fs(8,36,8,39): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member Foo.Inf: 'T ref'. -neg56_b.fs(15,37,15,40): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member Foo2.Inf : 'T ref'. +neg56_b.fs(15,37,15,40): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member Foo2.Inf: 'T ref'. -neg56_b.fs(26,13,26,23): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member private Foo.Inf : ('T list -> 'T list)'. +neg56_b.fs(26,13,26,23): typecheck error FS3068: The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member private Foo.Inf: ('T list -> 'T list)'. -neg56_b.fs(36,13,36,23): typecheck error FS3068: The function or member 'Foo' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member private Qux.Foo : ('T list -> 'T list)'. +neg56_b.fs(36,13,36,23): typecheck error FS3068: The function or member 'Foo' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is 'static member private Qux.Foo: ('T list -> 'T list)'. diff --git a/tests/fsharp/typecheck/sigs/neg57.bsl b/tests/fsharp/typecheck/sigs/neg57.bsl index aff6f93a03f..700888656fa 100644 --- a/tests/fsharp/typecheck/sigs/neg57.bsl +++ b/tests/fsharp/typecheck/sigs/neg57.bsl @@ -1,4 +1,4 @@ neg57.fs(4,6,4,9): typecheck error FS0314: The type definitions for type 'Foo' in the signature and implementation are not compatible because the field 'offset' was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'. -neg57.fs(1,8,1,9): typecheck error FS0193: Module 'M' requires a value 'new : unit -> Foo<'T>' +neg57.fs(1,8,1,9): typecheck error FS0193: Module 'M' requires a value 'new: unit -> Foo<'T>' diff --git a/tests/fsharp/typecheck/sigs/neg58.bsl b/tests/fsharp/typecheck/sigs/neg58.bsl index 8d1acf45492..7eb33661582 100644 --- a/tests/fsharp/typecheck/sigs/neg58.bsl +++ b/tests/fsharp/typecheck/sigs/neg58.bsl @@ -2,7 +2,7 @@ neg58.fs(5,6,5,9): typecheck error FS0314: The type definitions for type 'Foo' in the signature and implementation are not compatible because the field 'offset' was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'. neg58.fs(9,17,9,30): typecheck error FS0034: Module 'FooBarSoftware' contains - override Foo.GetEnumerator : unit -> IEnumerator<'T> + override Foo.GetEnumerator: unit -> IEnumerator<'T> but its signature specifies - member Foo.GetEnumerator : unit -> IEnumerator<'T> + member Foo.GetEnumerator: unit -> IEnumerator<'T> The compiled names differ diff --git a/tests/fsharp/typecheck/sigs/neg60.bsl b/tests/fsharp/typecheck/sigs/neg60.bsl index 9e05fc389f2..f3f19fa1c3d 100644 --- a/tests/fsharp/typecheck/sigs/neg60.bsl +++ b/tests/fsharp/typecheck/sigs/neg60.bsl @@ -57,6 +57,12 @@ neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refe neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. +neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + neg60.fs(65,19,65,38): typecheck error FS0001: This expression was expected to have type 'bool' but here has type @@ -79,3 +85,107 @@ neg60.fs(80,19,80,20): typecheck error FS0043: Expecting a type supporting the o neg60.fs(81,22,81,34): typecheck error FS0002: This function takes too many arguments, or is used in a context where a function is not expected neg60.fs(87,10,87,13): typecheck error FS0043: The type 'System.Nullable' does not support the operator '?=?'. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(128,9,128,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(129,9,129,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(130,9,130,13): typecheck error FS3099: 'body' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 3. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3087: The custom operation 'body' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg60.fs(131,9,131,13): typecheck error FS3099: 'body' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 3. + +neg60.fs(177,9,177,13): typecheck error FS3099: 'text' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 0. + +neg60.fs(186,9,186,24): typecheck error FS3099: 'with_validators' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 2. + +neg60.fs(195,9,195,24): typecheck error FS3099: 'with_validators' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 3. diff --git a/tests/fsharp/typecheck/sigs/neg60.fs b/tests/fsharp/typecheck/sigs/neg60.fs index 15475f55884..70026402204 100644 --- a/tests/fsharp/typecheck/sigs/neg60.fs +++ b/tests/fsharp/typecheck/sigs/neg60.fs @@ -85,3 +85,115 @@ module NullableOperators3 = let a = new System.Nullable(0) let b = new System.Nullable(1) if a ?=? b then printfn "Same" else printfn "Differerent" + +module QuerySyntaxWithValidOverloading = + + open System + + type Content = ArraySegment list + + type ContentBuilder() = + member this.Run(c: Content) = + let crlf = "\r\n"B + [|for part in List.rev c do + yield! part.Array.[part.Offset..(part.Count+part.Offset-1)] + yield! crlf |] + + member this.Yield(_) = [] + + [] + member this.Body(c: Content, segment: ArraySegment) = + segment::c + + [] + member this.Body(c: Content, bytes: byte[], offset, count) = + ArraySegment(bytes, offset, count)::c + + [] + member this.Body(c: Content, [] contents: string[]) = + let rec loop acc (contents: string list) = + match contents with + | [] -> acc + | content::rest -> + let bytes = Text.Encoding.ASCII.GetBytes(content) + loop (this.Body(c, bytes, 0, bytes.Length)) rest + loop c (List.ofArray contents) + + let content = ContentBuilder() + + //--------------------------------------------------------------- + + let values = + content { + body "Name" + body (ArraySegment<_>("Email"B, 0, 5)) + body "Password"B 2 4 + body "Description" "of" "content" + } + +module QuerySyntaxWithOptionalParamAndParamsArray = + + open System + + type InputKind = + | Text of placeholder:string option + | Password of placeholder: string option + + type InputOptions = + { Label: string option + Kind : InputKind + Validators : (string -> bool) array } + + type InputBuilder() = + + member t.Yield(_) = + { Label = None + Kind = Text None + Validators = [||] } + + [] + member this.Text(io,?placeholder) = + { io with Kind = Text placeholder } + + [] + member this.Password(io,?placeholder) = + { io with Kind = Password placeholder } + + [] + member this.Label(io,label) = + { io with Label = Some label } + + [] + member this.Validators(io, [] validators) = + { io with Validators = validators } + + let input = InputBuilder() + + //--------------------------------------------------------------- + + let name = + input { + label "Name" + text + with_validators + (String.IsNullOrWhiteSpace >> not) + } + + let email = + input { + label "Email" + text "Your email" + with_validators + (String.IsNullOrWhiteSpace >> not) + (fun s -> s.Contains "@") + } + + let password = + input { + label "Password" + password "Must contains at least 6 characters, one number and one uppercase" + with_validators + (String.exists Char.IsUpper) + (String.exists Char.IsDigit) + (fun s -> s.Length >= 6) + } diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl index b513bb46a9c..e4657e510b1 100644 --- a/tests/fsharp/typecheck/sigs/neg61.bsl +++ b/tests/fsharp/typecheck/sigs/neg61.bsl @@ -83,17 +83,13 @@ neg61.fs(156,21,156,22): typecheck error FS3147: This 'let' definition may not b neg61.fs(171,13,171,18): typecheck error FS3099: 'sumBy' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 0. -neg61.fs(174,22,174,23): typecheck error FS0041: No overloads match for method 'Source'. The available overloads are shown below. -neg61.fs(174,22,174,23): typecheck error FS0041: Possible overload: 'member Linq.QueryBuilder.Source : source:System.Linq.IQueryable<'T> -> Linq.QuerySource<'T,'Q>'. Type constraint mismatch. The type - 'int' -is not compatible with type - 'System.Linq.IQueryable<'a>' -. -neg61.fs(174,22,174,23): typecheck error FS0041: Possible overload: 'member Linq.QueryBuilder.Source : source:System.Collections.Generic.IEnumerable<'T> -> Linq.QuerySource<'T,System.Collections.IEnumerable>'. Type constraint mismatch. The type - 'int' -is not compatible with type - 'System.Collections.Generic.IEnumerable<'a>' -. +neg61.fs(174,22,174,23): typecheck error FS0041: No overloads match for method 'Source'. + +Known type of argument: int + +Available overloads: + - member Linq.QueryBuilder.Source: source: System.Collections.Generic.IEnumerable<'T> -> Linq.QuerySource<'T,System.Collections.IEnumerable> // Argument 'source' doesn't match + - member Linq.QueryBuilder.Source: source: System.Linq.IQueryable<'T> -> Linq.QuerySource<'T,'Q> // Argument 'source' doesn't match neg61.fs(180,19,180,31): typecheck error FS3153: Arguments to query operators may require parentheses, e.g. 'where (x > y)' or 'groupBy (x.Length / 10)' diff --git a/tests/fsharp/typecheck/sigs/neg78.bsl b/tests/fsharp/typecheck/sigs/neg78.bsl index 38d7beca531..202792198ce 100644 --- a/tests/fsharp/typecheck/sigs/neg78.bsl +++ b/tests/fsharp/typecheck/sigs/neg78.bsl @@ -1,2 +1,2 @@ -neg78.fsx(3,15,3,17): parse error FS0010: Unexpected symbol '..' in binding. Expected incomplete structured construct at or before this point or other token. +neg78.fsx(3,9,3,17): typecheck error FS0751: Incomplete expression or invalid use of indexer syntax diff --git a/tests/fsharp/typecheck/sigs/neg78.vsbsl b/tests/fsharp/typecheck/sigs/neg78.vsbsl index 5857bfb98d5..202792198ce 100644 --- a/tests/fsharp/typecheck/sigs/neg78.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg78.vsbsl @@ -1,4 +1,2 @@ -neg78.fsx(3,15,3,17): parse error FS0010: Unexpected symbol '..' in binding. Expected incomplete structured construct at or before this point or other token. - -neg78.fsx(3,15,3,17): parse error FS0010: Unexpected symbol '..' in binding. Expected incomplete structured construct at or before this point or other token. +neg78.fsx(3,9,3,17): typecheck error FS0751: Incomplete expression or invalid use of indexer syntax diff --git a/tests/fsharp/typecheck/sigs/neg80.vsbsl b/tests/fsharp/typecheck/sigs/neg80.vsbsl index d8bb6d1a0bb..63aba7d33db 100644 --- a/tests/fsharp/typecheck/sigs/neg80.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg80.vsbsl @@ -2,7 +2,3 @@ neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching - -neg80.fsx(79,6,79,6): typecheck error FS0001: All branches of a pattern match expression must return values of the same type as the first branch, which here is 'string'. This branch returns a value of type 'unit'. - -neg80.fsx(76,11,76,13): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value 'Horizontal (_, _)' may indicate a case not covered by the pattern(s). diff --git a/tests/fsharp/typecheck/sigs/neg87.bsl b/tests/fsharp/typecheck/sigs/neg87.bsl index 5359647ec21..8e4711554e4 100644 --- a/tests/fsharp/typecheck/sigs/neg87.bsl +++ b/tests/fsharp/typecheck/sigs/neg87.bsl @@ -38,3 +38,9 @@ neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refe neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. + +neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. diff --git a/tests/fsharp/typecheck/sigs/neg95.bsl b/tests/fsharp/typecheck/sigs/neg95.bsl index 378917767a9..48eddb2718a 100644 --- a/tests/fsharp/typecheck/sigs/neg95.bsl +++ b/tests/fsharp/typecheck/sigs/neg95.bsl @@ -1,15 +1,15 @@ neg95.fs(3,5,3,26): typecheck error FS3199: The 'rec' on this module is implied by an outer 'rec' declaration and is being ignored -neg95.fs(11,12,11,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module +neg95.fs(11,7,11,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module neg95.fs(19,7,19,22): typecheck error FS3201: In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations -neg95.fs(26,12,26,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module +neg95.fs(26,7,26,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module -neg95.fs(32,12,32,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module +neg95.fs(32,7,32,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module -neg95.fs(39,12,39,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module +neg95.fs(39,7,39,18): typecheck error FS3200: In a recursive declaration group, 'open' declarations must come first in each module neg95.fs(45,10,45,22): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation diff --git a/tests/fsharp/typecheck/sigs/neg98.bsl b/tests/fsharp/typecheck/sigs/neg98.bsl index 1aef477debf..c049a325a8b 100644 --- a/tests/fsharp/typecheck/sigs/neg98.bsl +++ b/tests/fsharp/typecheck/sigs/neg98.bsl @@ -1,8 +1,8 @@ -neg98.fs(10,20,10,34): typecheck error FS0768: The member 'Eval' does not accept the correct number of arguments. 2 argument(s) are expected, but 2 were given. The required signature is 'member Evaluator.Eval : ('t -> 'u) -> 'u list -> 'ret'. +neg98.fs(10,20,10,34): typecheck error FS0768: The member 'Eval' does not accept the correct number of arguments. 2 argument(s) are expected, but 2 were given. The required signature is 'Evaluator.Eval: ('t -> 'u) -> 'u list -> 'ret'. -neg98.fs(10,23,10,27): typecheck error FS0017: The member 'Eval : 'a * 'b -> 'c' does not have the correct type to override the corresponding abstract method. The required signature is 'Eval<'u> : ('t -> 'u) -> 'u list -> 'a'. +neg98.fs(10,23,10,27): typecheck error FS0017: The member 'Eval: 'a * 'b -> 'c' does not have the correct type to override the corresponding abstract method. The required signature is 'Eval<'u> : ('t -> 'u) -> 'u list -> 'a'. -neg98.fs(10,23,10,27): typecheck error FS0367: The member 'Eval : 'a * 'b -> 'c' does not have the correct number of arguments. The required signature is 'Eval<'u> : ('t -> 'u) -> 'u list -> 'a'. +neg98.fs(10,23,10,27): typecheck error FS0367: The member 'Eval: 'a * 'b -> 'c' does not have the correct number of arguments. The required signature is 'Eval<'u> : ('t -> 'u) -> 'u list -> 'a'. neg98.fs(9,22,9,36): typecheck error FS0783: At least one override did not correctly implement its corresponding abstract member diff --git a/tests/fsharp/typecheck/sigs/neg99.bsl b/tests/fsharp/typecheck/sigs/neg99.bsl index 6482281b893..9f6010f249d 100644 --- a/tests/fsharp/typecheck/sigs/neg99.bsl +++ b/tests/fsharp/typecheck/sigs/neg99.bsl @@ -3,4 +3,4 @@ neg99.fs(19,16,19,64): typecheck error FS0077: Member constraints with the name neg99.fs(22,18,22,64): typecheck error FS0077: Member constraints with the name 'op_Explicit' are given special status by the F# compiler as certain .NET types are implicitly augmented with this member. This may result in runtime failures if you attempt to invoke the member constraint from your own code. -neg99.fs(25,39,25,43): typecheck error FS0043: The type 'CrashFSC.OhOh.MyByte' does not support a conversion to the type 'CrashFSC.OhOh.MyByte' \ No newline at end of file +neg99.fs(25,39,25,43): typecheck error FS0043: The type 'CrashFSC.OhOh.MyByte' does not support a conversion to the type 'CrashFSC.OhOh.MyByte' diff --git a/tests/fsharp/typecheck/sigs/neg_byref_13.bsl b/tests/fsharp/typecheck/sigs/neg_byref_13.bsl index 985177e9793..af1356864f5 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_13.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_13.bsl @@ -5,4 +5,4 @@ neg_byref_13.fs(3,12,3,13): typecheck error FS3300: The parameter 'x' has an inv neg_byref_13.fs(3,5,3,10): typecheck error FS3301: The function or method has an invalid return type 'M5'. This is not permitted by the rules of Common IL. -neg_byref_13.fs(3,20,3,21): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. \ No newline at end of file +neg_byref_13.fs(3,20,3,21): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/pos34.fs b/tests/fsharp/typecheck/sigs/pos34.fs new file mode 100644 index 00000000000..73cebb29505 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos34.fs @@ -0,0 +1,101 @@ +module Pos34 + +// From https://github.com/dotnet/fsharp/issues/4171#issuecomment-528063764 +// This case is where the type gets labelled as Sealed +// This case compiles without complaint +// +// See also neg120.fs +open System.Threading.Tasks + +[] +type Id<'t> (v: 't) = + let value = v + member __.getValue = value + +[] +module Id = + let run (x: Id<_>) = x.getValue + let map f (x: Id<_>) = Id (f x.getValue) + let create x = Id x + + +type Bind = + static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U> + static member (>>=) (source: Task<'T> , f: 'T -> Task<'U> ) = source.ContinueWith(fun (x: Task<_>) -> f x.Result).Unwrap () : Task<'U> + static member (>>=) (source , f: 'T -> _ ) = Option.bind f source : option<'U> + static member (>>=) (source , f: 'T -> _ ) = async.Bind (source, f) + static member (>>=) (source : Id<_> , f: 'T -> _ ) = f source.getValue : Id<'U> + + static member inline Invoke (source: '``Monad<'T>``) (binder: 'T -> '``Monad<'U>``) : '``Monad<'U>`` = + let inline call (_mthd: 'M, input: 'I, _output: 'R, f) = ((^M or ^I or ^R) : (static member (>>=) : _*_ -> _) input, f) + call (Unchecked.defaultof, source, Unchecked.defaultof<'``Monad<'U>``>, binder) + +let inline (>>=) (x: '``Monad<'T>``) (f: 'T->'``Monad<'U>``) : '``Monad<'U>`` = Bind.Invoke x f + +type Return = + static member inline Invoke (x: 'T) : '``Applicative<'T>`` = + let inline call (mthd: ^M, output: ^R) = ((^M or ^R) : (static member Return : _*_ -> _) output, mthd) + call (Unchecked.defaultof, Unchecked.defaultof<'``Applicative<'T>``>) x + + static member Return (_: Lazy<'a> , _: Return ) = fun x -> Lazy<_>.CreateFromValue x : Lazy<'a> + static member Return (_: 'a Task , _: Return ) = fun x -> Task.FromResult x : 'a Task + static member Return (_: option<'a> , _: Return ) = fun x -> Some x : option<'a> + static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x + static member Return (_: 'a Id , _: Return ) = fun (x: 'a) -> Id x + +let inline result (x: 'T) : '``Functor<'T>`` = Return.Invoke x + + +type TypeT<'``monad<'t>``> = TypeT of obj +type Node<'``monad<'t>``,'t> = A | B of 't * TypeT<'``monad<'t>``> + +let inline wrap (mit: 'mit) = + let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_:'t) -> (result Node<'mt,'t>.A ) : 'mit + TypeT mit : TypeT<'mt> + +let inline unwrap (TypeT mit : TypeT<'mt>) = + let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_:'t) -> (result Node<'mt,'t>.A ) : 'mit + unbox mit : 'mit + +let inline empty () = wrap ((result Node<'mt,'t>.A) : 'mit) : TypeT<'mt> + +let inline concat l1 l2 = + let rec loop (l1: TypeT<'mt>) (lst2: TypeT<'mt>) = + let (l1, l2) = unwrap l1, unwrap lst2 + TypeT (l1 >>= function A -> l2 | B (x: 't, xs) -> ((result (B (x, loop xs lst2))) : 'mit)) + loop l1 l2 : TypeT<'mt> + + +let inline bind f (source: TypeT<'mt>) : TypeT<'mu> = + // let _mnil = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_: 't) -> (result Unchecked.defaultof<'u>) : 'mu + let rec loop f input = + TypeT ( + (unwrap input : 'mit) >>= function + | A -> result <| (A : Node<'mu,'u>) : 'miu + | B (h:'t, t: TypeT<'mt>) -> + let res = concat (f h: TypeT<'mu>) (loop f t) + unwrap res : 'miu) + loop f source : TypeT<'mu> + + +let inline map (f: 'T->'U) (x: '``Monad<'T>`` ) = Bind.Invoke x (f >> Return.Invoke) : '``Monad<'U>`` + + +let inline unfold (f:'State -> '``M<('T * 'State) option>``) (s:'State) : TypeT<'MT> = + let rec loop f s = f s |> map (function + | Some (a, s) -> B (a, loop f s) + | None -> A) |> wrap + loop f s + +let inline create (al: '``Monad>``) : TypeT<'``Monad<'T>``> = + unfold (fun i -> map (fun (lst:list<_>) -> if lst.Length > i then Some (lst.[i], i+1) else None) al) 0 + +let inline run (lst: TypeT<'MT>) : '``Monad>`` = + let rec loop acc x = unwrap x >>= function + | A -> result (List.rev acc) + | B (x, xs) -> loop (x::acc) xs + loop [] lst + +let c0 = create (Id ([1..10])) +let res0 = c0 |> run |> create |> run + diff --git a/tests/fsharp/typecheck/sigs/pos35.fs b/tests/fsharp/typecheck/sigs/pos35.fs new file mode 100644 index 00000000000..8848c965cd5 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos35.fs @@ -0,0 +1,315 @@ +module Pos35 + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// We are selecting an overloaded witness based on input type +module SelectOverloadedWitnessBasedOnInputType = + type witnesses = + static member inline unsigned_witness (x : sbyte) = uint8 x + static member inline unsigned_witness (x : byte) = x + static member inline unsigned_witness (x : int16) = uint16 x + static member inline unsigned_witness (x : uint16) = x + static member inline unsigned_witness (x : int32) = uint32 x + static member inline unsigned_witness (x : uint32) = x + static member inline unsigned_witness (x : int64) = uint64 x + static member inline unsigned_witness (x : uint64) = x + + // Note, this doesn't try to use the output to select + let inline call_unsigned_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member unsigned_witness : ^input -> ^output)> (x : ^input) = + ((^witnesses or ^input) : (static member unsigned_witness : ^input -> ^output) x) + + // unsigned: ^a -> ^b + let inline unsigned num = call_unsigned_witness num + let v1 = unsigned 0y + let v2 = unsigned 0s + let v3 = unsigned 0 + let v4 = unsigned 0L + + let f1 : int8 -> uint8 = unsigned + let f2 : int16 -> uint16 = unsigned + let f3 : int32 -> uint32 = unsigned + let f4 : int64 -> uint64 = unsigned + + let g1 : int8 -> _ = unsigned + let g2 : int16 -> _ = unsigned + let g3 : int32 -> _ = unsigned + let g4 : int64 -> _ = unsigned + + // Negative cases - not enough information here - see neg124.fs which checks these + //let h1 : _ -> uint8 = unsigned + //let h2 : _ -> uint16 = unsigned + //let h3 : _ -> uint32 = unsigned + //let h4 : _ -> uint64 = unsigned + + +// Variation on the previous test case +// +// Note, this adds output as a selector though that shouldn't make any difference +module SelectOverloadedWitnessBasedOnInputTypePlusNeedlessOutputTypeSelector = + type witnesses = + static member inline unsigned_witness (x : sbyte) = uint8 x + static member inline unsigned_witness (x : byte) = x + static member inline unsigned_witness (x : int16) = uint16 x + static member inline unsigned_witness (x : uint16) = x + static member inline unsigned_witness (x : int32) = uint32 x + static member inline unsigned_witness (x : uint32) = x + static member inline unsigned_witness (x : int64) = uint64 x + static member inline unsigned_witness (x : uint64) = x + + let inline call_unsigned_witness< ^witnesses, ^input, ^output when (^witnesses or ^input or ^output) : (static member unsigned_witness : ^input -> ^output)> (x : ^input) = + ((^witnesses or ^input or ^output) : (static member unsigned_witness : ^input -> ^output) x) + + // unsigned: ^a -> ^b + let inline unsigned num = call_unsigned_witness num + let v1 = unsigned 0y + let v2 = unsigned 0s + let v3 = unsigned 0 + let v4 = unsigned 0L + + let f1 : int8 -> uint8 = unsigned + let f2 : int16 -> uint16 = unsigned + let f3 : int32 -> uint32 = unsigned + let f4 : int64 -> uint64 = unsigned + + let g1 : int8 -> _ = unsigned + let g2 : int16 -> _ = unsigned + let g3 : int32 -> _ = unsigned + let g4 : int64 -> _ = unsigned + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +module SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentAndUsingOutputSelector = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint, _output : int32) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint, _output : int64) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint, _output : bigint) = x + static member inline convert_witness (x : bigint, _output : float) = float x + static member inline convert_witness (x : bigint, _output : sbyte) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint, _output : int16) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint, _output : byte) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint, _output : uint16) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint, _output : uint32) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint, _output : uint64) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint, _output : float32) = float32 x + static member inline convert_witness (x : bigint, _output : decimal) = decimal x + static member inline convert_witness (x : bigint, _output : Complex) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, ^output when (^witnesses or ^input or ^output) : (static member convert_witness : ^input * ^output -> ^output)> (b : ^input, c : ^output) = + ((^witnesses or ^input or ^output) : (static member convert_witness : ^input * ^output -> ^output) (b, c)) + + let inline convert num = + call_convert_witness (num, Unchecked.defaultof<'b>) + + let v1 : int32 = convert 777I + let v2 : int64 = convert 777I + let v3 : bigint = convert 777I + let v4 : float = convert 777I + let v5 : sbyte = convert 777I + let v6 : int16 = convert 777I + let v7 : byte = convert 777I + let v8 : uint16 = convert 777I + let v9 : uint32 = convert 777I + let v10 : uint64 = convert 777I + let v11 : float32 = convert 777I + let v12 : decimal = convert 777I + let v13 : Complex = convert 777I + + // This is enough to determine the input as bigint because those are the only solutions available + let f1 : _ -> int32 = convert + let f2 : _ -> int64 = convert + let f3 : _ -> bigint = convert + let f4 : _ -> float = convert + let f5 : _ -> sbyte = convert + let f6 : _ -> int16 = convert + let f7 : _ -> byte = convert + let f8 : _ -> uint16 = convert + let f9 : _ -> uint32 = convert + let f10 : _ -> uint64 = convert + let f11 : _ -> float32 = convert + let f12 : _ -> decimal = convert + let f13 : _ -> Complex = convert + + // This is permitted because the ^output type is still a selector + // + // The resulting type is like this: + // + // val inline inst : num:bigint -> ^output when (witnesses or bigint or ^output) : (static member convert_witness : bigint * ^output -> ^output) + let inline inst (num: bigint) : ^output = convert num + let i1 : int32 = inst 777I + let i2 : int64 = inst 777I + let i3 : bigint = inst 777I + let i4 : float = inst 777I + let i5 : sbyte = inst 777I + let i6 : int16 = inst 777I + let i7 : byte = inst 777I + let i8 : uint16 = inst 777I + let i9 : uint32 = inst 777I + let i10 : uint64 = inst 777I + let i11 : float32 = inst 777I + let i12 : decimal = inst 777I + let i13 : Complex = inst 777I + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// This removes ^output as a type selector for the witness, but continues to pass a dummy ^output +// +// This is sufficient to make the resolutions go through +module SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentNoOutputSelector = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint, _output : int32) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint, _output : int64) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint, _output : bigint) = x + static member inline convert_witness (x : bigint, _output : float) = float x + static member inline convert_witness (x : bigint, _output : sbyte) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint, _output : int16) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint, _output : byte) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint, _output : uint16) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint, _output : uint32) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint, _output : uint64) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint, _output : float32) = float32 x + static member inline convert_witness (x : bigint, _output : decimal) = decimal x + static member inline convert_witness (x : bigint, _output : Complex) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, ^output when (^witnesses or ^input) : (static member convert_witness : ^input * ^output -> ^output)> (b : ^input, c : ^output) = + ((^witnesses or ^input) : (static member convert_witness : ^input * ^output -> ^output) (b, c)) + + let inline convert num = + call_convert_witness (num, Unchecked.defaultof<'b>) + + let v1 : int32 = convert 777I + let v2 : int64 = convert 777I + let v3 : bigint = convert 777I + let v4 : float = convert 777I + let v5 : sbyte = convert 777I + let v6 : int16 = convert 777I + let v7 : byte = convert 777I + let v8 : uint16 = convert 777I + let v9 : uint32 = convert 777I + let v10 : uint64 = convert 777I + let v11 : float32 = convert 777I + let v12 : decimal = convert 777I + let v13 : Complex = convert 777I + + // This is enough to determine the input as bigint because those are the only solutions available + let f1 : _ -> int32 = convert + let f2 : _ -> int64 = convert + let f3 : _ -> bigint = convert + let f4 : _ -> float = convert + let f5 : _ -> sbyte = convert + let f6 : _ -> int16 = convert + let f7 : _ -> byte = convert + let f8 : _ -> uint16 = convert + let f9 : _ -> uint32 = convert + let f10 : _ -> uint64 = convert + let f11 : _ -> float32 = convert + let f12 : _ -> decimal = convert + let f13 : _ -> Complex = convert + + // Adding this gives an error, see neg129.fs for the test for this + // let inline inst (num: bigint) : ^output = convert num + +// Variation on test case mentioned in https://github.com/dotnet/fsharp/pull/6805#issuecomment-580368303 +// +// Same as SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentNoOutputSelector but the output type +// parameter is generic 'output rather than SRTP ^output +// + +module SelectOverloadedWitnessBasedOnReturnTypeByPassingDummyArgumentGenericOutputType = + open System + open System.Numerics + let _uint8max = bigint (uint32 Byte.MaxValue) + let _uint16max = bigint (uint32 UInt16.MaxValue) + let _uint32max = bigint UInt32.MaxValue + let _uint64max = bigint UInt64.MaxValue + type witnesses = + static member inline convert_witness (x : bigint, _output : int32) = int (uint32 (x &&& _uint32max)) + static member inline convert_witness (x : bigint, _output : int64) = int64 (uint64 (x &&& _uint64max)) + static member inline convert_witness (x : bigint, _output : bigint) = x + static member inline convert_witness (x : bigint, _output : float) = float x + static member inline convert_witness (x : bigint, _output : sbyte) = sbyte (byte (x &&& _uint8max)) + static member inline convert_witness (x : bigint, _output : int16) = int16 (uint16 (x &&& _uint16max)) + static member inline convert_witness (x : bigint, _output : byte) = byte (x &&& _uint8max) + static member inline convert_witness (x : bigint, _output : uint16) = uint16 (x &&& _uint16max) + static member inline convert_witness (x : bigint, _output : uint32) = uint32 (x &&& _uint32max) + static member inline convert_witness (x : bigint, _output : uint64) = uint64 (x &&& _uint64max) + static member inline convert_witness (x : bigint, _output : float32) = float32 x + static member inline convert_witness (x : bigint, _output : decimal) = decimal x + static member inline convert_witness (x : bigint, _output : Complex) = Complex(float x, 0.0) + + let inline call_convert_witness< ^witnesses, ^input, 'output when (^witnesses or ^input) : (static member convert_witness : ^input * 'output -> 'output)> (b : ^input, c : 'output) = + ((^witnesses or ^input) : (static member convert_witness : ^input * 'output -> 'output) (b, c)) + + let inline convert num : 'output = + call_convert_witness (num, Unchecked.defaultof<'output>) + + let v1 : int32 = convert 777I + let v2 : int64 = convert 777I + let v3 : bigint = convert 777I + let v4 : float = convert 777I + let v5 : sbyte = convert 777I + let v6 : int16 = convert 777I + let v7 : byte = convert 777I + let v8 : uint16 = convert 777I + let v9 : uint32 = convert 777I + let v10 : uint64 = convert 777I + let v11 : float32 = convert 777I + let v12 : decimal = convert 777I + let v13 : Complex = convert 777I + + // This is enough to determine the input as bigint because those are the only solutions available + let f1 : _ -> int32 = convert + let f2 : _ -> int64 = convert + let f3 : _ -> bigint = convert + let f4 : _ -> float = convert + let f5 : _ -> sbyte = convert + let f6 : _ -> int16 = convert + let f7 : _ -> byte = convert + let f8 : _ -> uint16 = convert + let f9 : _ -> uint32 = convert + let f10 : _ -> uint64 = convert + let f11 : _ -> float32 = convert + let f12 : _ -> decimal = convert + let f13 : _ -> Complex = convert + + // Adding this gives an error, see neg128.fs for the test for this + // let inline inst (num: bigint) : 'output = convert num + + +// Reduced FSharpPlus tests case from https://github.com/dotnet/fsharp/pull/6805#issuecomment-580365649 +module PositiveTestCase3 = + [] + module Extensions = + + type Async<'T> with + + static member Quack (x:seq>) : Async> = failwith "" + + type Option<'T> with + + static member Quack (x: seq>) : option> = failwith "" + + let inline CallQuack (x: ^a) : ^Output = (^a : (static member Quack : ^a -> ^Output) x) + + type Witnesses = + + static member inline QuackWitness (x: ^a, _output: ^Output, _impl: Witnesses) : ^Output = CallQuack x + static member inline QuackWitness (x: ref<_>, _output: ^Output, _impl: Witnesses) : ^Output = Unchecked.defaultof<_> + + let inline CallQuackWitness (x: ^a, output: ^Output, witnesses: ^Witnesses) = + ((^a or ^Output or ^Witnesses) : (static member QuackWitness : _*_*_ -> _) (x, output, witnesses)) + + let inline call (x: seq< ^b > ) : ^Output = + CallQuackWitness (x, Unchecked.defaultof< ^Output >, Unchecked.defaultof) + + + diff --git a/tests/fsharp/typecheck/sigs/pos36-srtp-app.fs b/tests/fsharp/typecheck/sigs/pos36-srtp-app.fs new file mode 100644 index 00000000000..57c78b65fd1 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos36-srtp-app.fs @@ -0,0 +1,11 @@ +module Pos36 + +open Lib + +let check msg x y = if x = y then printfn "passed %s" msg else failwithf "failed '%s'" msg + +let tbind () = + check "vwknvewoiwvren1" (StaticMethods.M(C(3))) "M(C), x = 3" + check "vwknvewoiwvren2" (StaticMethods.M(3L)) "M(int64), x = 3" + +tbind() diff --git a/tests/fsharp/typecheck/sigs/pos36-srtp-lib.fs b/tests/fsharp/typecheck/sigs/pos36-srtp-lib.fs new file mode 100644 index 00000000000..f8b24122724 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos36-srtp-lib.fs @@ -0,0 +1,22 @@ + + +module Lib + +let inline RequireM< ^Witnesses, ^T when (^Witnesses or ^T): (static member M : ^T -> string) > (x: ^T) : string = + ((^Witnesses or ^T): (static member M : ^T -> string) x) + +type C(p:int) = + member x.P = p + +type Witnesses() = + + static member M (x: C) : string = sprintf "M(C), x = %d" x.P + + static member M (x: int64) : string = sprintf "M(int64), x = %d" x + +type StaticMethods = + + static member inline M< ^T when (Witnesses or ^T): (static member M: ^T -> string)> (x: ^T) : string = + + RequireM< Witnesses, ^T> (x) + diff --git a/tests/fsharp/typecheck/sigs/pos37.fs b/tests/fsharp/typecheck/sigs/pos37.fs new file mode 100644 index 00000000000..71199d438e1 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos37.fs @@ -0,0 +1,225 @@ +module Pos37 + +open System + +let PlaceReferenceConstraint<'T when 'T : not struct> (x : 'T) = x +let PlaceNullConstraint<'T when 'T : null> (x : 'T) = x +let PlaceStructConstraint<'T when 'T : struct> (x : 'T) = x +let PlaceValueTypeConstraint<'T when 'T :> ValueType> (x : 'T) = x +let PlaceDefaultConstructorConstraint<'T when 'T : (new : unit -> 'T)> (x : 'T) = x + +module TestVariableTypes = + + // Variable types are considered to satisfy ValueType constraint if they have that constraint + // or it is inferred + // + type T1<'T when 'T :> ValueType>(x : 'T) = + do x |> PlaceValueTypeConstraint |> ignore + + let f1 x = x |> PlaceValueTypeConstraint |> ignore + + // Variable types are considered to satisfy struct constraint if they have that constraint + // or it is inferred + // + type T2<'T when 'T : struct>(x : 'T) = + do x |> PlaceStructConstraint |> ignore + + let f2 x = x |> PlaceStructConstraint |> ignore + + // Variable types are considered to satisfy default constructor constraint if they have that constraint + // or it is inferred + // + type T3<'T when 'T : (new : unit -> 'T)>(x : 'T) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let f3 x = x |> PlaceDefaultConstructorConstraint |> ignore + +module TestStructTuples = + // Struct tuples are always considered to satisfy ValueType constraint + // + type T1<'T when 'T :> ValueType>(x : struct ('T * 'T)) = + do x |> PlaceValueTypeConstraint |> ignore + + let f1 (x : struct ('T * 'T)) = + x |> PlaceValueTypeConstraint |> ignore + + f1 (struct (1, 1)) + f1 (struct (System.DateTime.Now, System.DateTime.Now)) + + // Struct tuple types are considered to satisfy struct constraint if they have that constraint + // or it is inferred + // + type T2<'T when 'T : struct>(x : struct ('T * 'T)) = + do x |> PlaceStructConstraint |> ignore + + let f2 (x : struct ('T * 'T)) = + x |> PlaceStructConstraint |> ignore + + f2 (struct (1, 1)) + f2 (struct (System.DateTime.Now, System.DateTime.Now)) + + // Struct tuple types are considered to satisfy default constructor constraint if each element + // type is known (without placing any constraints) to have a default value. If the element types + // are variable types they must have been pre-determined through inference or explicit + // declaration to be either struct or reference variable types. + type T3a(x : struct (int * string)) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let v3a = T3a (struct (1, "a")) + + // The case for struct and reference element types + let f3a (x : struct (int * string)) = + x |> PlaceDefaultConstructorConstraint |> ignore + + f3a (struct (1, "a")) + + // The case for struct type variables (declared) + type T3b<'T when 'T : struct and 'T : (new : unit -> 'T)>(x : struct (int * 'T)) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let v3b = T3b (struct (1, System.DateTime.Now)) + + // The case for struct type variables (inferred) + let f3b (x : struct (int * 'T)) = + let (struct (a,b)) = x + b |> PlaceStructConstraint |> ignore + x |> PlaceDefaultConstructorConstraint |> ignore + + f3b (struct (1, 1)) + f3b (struct (1, System.DateTime.Now)) + + // The case for reference type variables (declared) + type T3c<'T when 'T : not struct and 'T : null>(x : struct (int * 'T)) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let v3c = T3c (struct (1, "abc")) + + // The case for reference type variables (inferred) + let f3c (x : struct (int * 'T)) = + let (struct (a,b)) = x + b |> PlaceReferenceConstraint |> ignore + x |> PlaceDefaultConstructorConstraint |> ignore + + f3c (struct (1, "abc")) + f3c (struct (1, obj())) + +module TestStructAnonRecords = + // Struct anon record are always considered to satisfy ValueType constraint + // + type T1<'T when 'T :> ValueType>(x : struct {| X : 'T; Y : 'T |}) = + do x |> PlaceValueTypeConstraint |> ignore + + let f1 (x : struct {| X : 'T; Y : 'T |}) = + x |> PlaceValueTypeConstraint |> ignore + + f1 {| X = 1; Y = 1 |} + f1 {| X = System.DateTime.Now ; Y = System.DateTime.Now |} + + // Struct tuple types are considered to satisfy struct constraint if they have that constraint + // or it is inferred + // + type T2<'T when 'T : struct>(x : struct {| X : 'T; Y : 'T |}) = + do x |> PlaceStructConstraint |> ignore + + let f2 (x : struct {| X : 'T; Y : 'T |}) = + x |> PlaceStructConstraint |> ignore + + f2 {| X = 1; Y = 1 |} + f2 {| X = System.DateTime.Now ; Y = System.DateTime.Now |} + + // Struct tuple types are considered to satisfy default constructor constraint if each element + // type is known (without placing any constraints) to have a default value. If the element types + // are variable types they must have been pre-determined through inference or explicit + // declaration to be either struct or reference variable types. + type T3a(x : struct {| X : int; Y : string |}) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + // The case for struct and reference element types + let f3a (x : struct {| X : int; Y : string |}) = + x |> PlaceDefaultConstructorConstraint |> ignore + + f3a {| X = 1; Y = "a" |} + + // The case for struct type variables (declared) + type T3b<'T when 'T : struct and 'T : (new : unit -> 'T)>(x : struct {| X : int; Y : 'T |}) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let v3b = T3b {| X = 1; Y = System.DateTime.Now |} + + // The case for struct type variables (inferred) + let f3b (x : struct {| X : int; Y : 'T |}) = + x.Y |> PlaceStructConstraint |> ignore + x |> PlaceDefaultConstructorConstraint |> ignore + + f3b {| X = 1; Y = 1 |} + f3b {| X = 1; Y = System.DateTime.Now |} + + // The case for reference type variables (declared) + type T3c<'T when 'T : not struct and 'T : null>(x : struct {| X : int; Y : 'T |}) = + do x |> PlaceDefaultConstructorConstraint |> ignore + + let v3c = T3c {| X = 1; Y = "abc" |} + + // The case for reference type variables (inferred) + let f3c (x : struct {| X : int; Y : 'T |}) = + x.Y |> PlaceReferenceConstraint |> ignore + x |> PlaceDefaultConstructorConstraint |> ignore + + f3c {| X = 1; Y = "abc" |} + f3c {| X = 1; Y = obj() |} + +module TestNullableStructTuples = + // Struct tuples are considered to satisfy the combined Nullable<_> constraints + // X : struct + // X :> ValueType + // X : (new : unit -> X) + // if each element type is known to have a default value. + let m1 (x: Nullable) = () + + let m2 (x: Nullable>) = () + + type T<'T when 'T :> ValueType and 'T : struct and 'T : (new : unit -> 'T)>() = + let m (x: Nullable) = () + +module TestNullableStructAnonRecds = + // Struct anon records are considered to satisfy the combined Nullable<_> constraints + // X : struct + // X :> ValueType + // X : (new : unit -> X) + // if each element type is known to have a default value. For variable types + // this means knowing whether the variable type is a reference or value type + let m1 (x: Nullable) = () + + type Ta<'T when 'T :> ValueType and 'T : struct and 'T : (new : unit -> 'T)>() = + let m (x: Nullable) = () + + type Tb<'T when 'T : not struct and 'T : null>() = + let m (x: Nullable) = () + +module TestAnotherStructRecord = + + let inline test<'t when 't: (new: unit -> 't) and 't: struct and 't:> ValueType> () = () + + [] + type Delta = + { SkipX: byte + Control: sbyte } + + test () + test< struct {| SkipX: byte; Control: sbyte |} > () + test< struct (byte * sbyte) > () + +module TestAnotherStructTuple = + + let x = System.Nullable(struct (0, 0)) // note, the type annotations are required + +module TestAnotherStructTuple2 = + + let x = struct(0, 0) + let y = System.Nullable(x) + +module TestAnotherStructTuple3 = + + let x = struct(0, 0) + let y = System.Nullable(struct (0, 0) |> unbox>) + let z = System.Nullable(x |> unbox>) diff --git a/tests/fsharp/typecheck/sigs/pos38.fs b/tests/fsharp/typecheck/sigs/pos38.fs new file mode 100644 index 00000000000..bf9ad7ea8f9 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos38.fs @@ -0,0 +1,28 @@ +module Pos38 + +type Expression = + | EndOp + | BinaryOp of Expression * Expression + +let mutable count = 0 + +[] +module Extensions = + + type Expression with + + member this.Foobar2 : unit = + match this with + | BinaryOp (_, e2) -> + e2.Foobar2 + | EndOp -> + count <- count + 1 + () + + +let c = BinaryOp(EndOp, EndOp) + +c.Foobar2 + +if count <> 1 then failwith "incorrect count" + diff --git a/tests/fsharp/typecheck/sigs/pos39.fs b/tests/fsharp/typecheck/sigs/pos39.fs new file mode 100644 index 00000000000..aced03845e4 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos39.fs @@ -0,0 +1,32 @@ +module Pos39 + +module BigAnonRecords4 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; |}, () ] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + +module BigAnonRecords5 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; E = "" ;|}, () ] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = "" |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + +module BigAnonRecords6 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""|}, () ] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = "" |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + +module BigAnonRecords7 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""; G = "" |}, () ] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = ""; G = "" |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + +module BigAnonRecords8 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""; G = ""; H = 1 |}, () + {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""; G = ""; H = 2 |}, ()] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = ""; G = ""; H = 2 |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = ""; G = ""; H = 1 |} |> sprintf "%A" |> fun s -> if s <> "Some ()" then failwith "unexpected" + +module BigAnonRecords9 = + let v = Map [ {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""; G = ""; H = 1; I = 3.0M |}, 1 + {| A = ""; B = ""; C = ""; D = ""; E = "" ; F = ""; G = ""; H = 2; I = 3.0M |}, 2] + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = ""; G = ""; H = 2; I = 3.0M |} |> sprintf "%A" |> fun s -> if s <> "Some 2" then failwith "unexpected" + v.TryFind {| A = ""; B = ""; C = ""; D = ""; E = ""; F = ""; G = ""; H = 1; I = 3.0M |} |> sprintf "%A" |> fun s -> if s <> "Some 1" then failwith "unexpected" + +printfn "test completed" +exit 0 \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/version46/neg24.bsl b/tests/fsharp/typecheck/sigs/version46/neg24.bsl index 96a64e8c88f..97aa11a5d26 100644 --- a/tests/fsharp/typecheck/sigs/version46/neg24.bsl +++ b/tests/fsharp/typecheck/sigs/version46/neg24.bsl @@ -27,4 +27,4 @@ neg24.fs(62,31,62,41): typecheck error FS0816: One or more of the overloads of t neg24.fs(64,44,64,48): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. -neg24.fs(70,15,70,18): typecheck error FS0495: The member or object constructor 'M' has no argument or settable return property 'qez'. The required signature is member C.M : abc:int * def:string -> int. \ No newline at end of file +neg24.fs(70,15,70,18): typecheck error FS0495: The member or object constructor 'M' has no argument or settable return property 'qez'. The required signature is member C.M: abc: int * def: string -> int. diff --git a/tests/fsharp/typecheck/sigs/version47/neg24.bsl b/tests/fsharp/typecheck/sigs/version47/neg24.bsl index f276c01968b..50782788689 100644 --- a/tests/fsharp/typecheck/sigs/version47/neg24.bsl +++ b/tests/fsharp/typecheck/sigs/version47/neg24.bsl @@ -11,17 +11,17 @@ neg24.fs(62,31,62,41): typecheck error FS0816: One or more of the overloads of t neg24.fs(64,44,64,48): typecheck error FS0816: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. -neg24.fs(70,15,70,18): typecheck error FS0495: The member or object constructor 'M' has no argument or settable return property 'qez'. The required signature is member C.M : abc:int * def:string -> int. +neg24.fs(70,15,70,18): typecheck error FS0495: The member or object constructor 'M' has no argument or settable return property 'qez'. The required signature is member C.M: abc: int * def: string -> int. neg24.fs(300,29,300,30): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. neg24.fs(301,17,301,18): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. -neg24.fs(302,33,302,34): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'unit'. This element has type 'int'. +neg24.fs(302,33,302,34): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. -neg24.fs(302,36,302,37): typecheck error FS0001: All elements of a list must be of the same type as the first element, which here is 'unit'. This element has type 'int'. +neg24.fs(302,36,302,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. -neg24.fs(304,11,305,32): typecheck error FS0193: Type constraint mismatch. The type +neg24.fs(304,9,305,34): typecheck error FS0193: Type constraint mismatch. The type 'int' is not compatible with type 'unit' diff --git a/tests/fsharp/typecheck/sigs/version47/neg24.fs b/tests/fsharp/typecheck/sigs/version47/neg24.fs index 6e1e072cf1a..38cb01cf2d2 100644 --- a/tests/fsharp/typecheck/sigs/version47/neg24.fs +++ b/tests/fsharp/typecheck/sigs/version47/neg24.fs @@ -299,7 +299,7 @@ module BuilderPositive2 = module ListNegative2 = let v4 = [ if true then 1 else yield 2 ] // expect warning about "1" being ignored. There is a 'yield' so statements are statements. let l11 = [ 4; yield 1; yield 2 ] // expect warning about "1" being ignored. There is a 'yield' so statements are statements. - let l9 = [ printfn "hello"; 1; 2 ] // Note, this is interpreted as a "SimpleSemicolonSequence", so we get "All elements of a list must be of the same type as the first element, which here is 'unit'. This element..." + let l9 = [ printfn "hello"; 1; 2 ] // Note, this is interpreted as a "SimpleSemicolonSequence", so we get "All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element..." let v3a : unit list = [ printfn "hello" if true then 1 else 2 ] diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl new file mode 100644 index 00000000000..9bc473d3a3b --- /dev/null +++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl @@ -0,0 +1,417 @@ + +neg20.fs(30,28,30,31): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(31,32,31,35): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(32,28,32,31): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(32,32,32,35): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(34,24,34,27): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +neg20.fs(35,24,35,27): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(43,15,43,18): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(44,19,44,22): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(45,15,45,18): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(45,19,45,22): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(47,11,47,14): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +neg20.fs(48,11,48,14): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(52,24,52,31): typecheck error FS0001: This expression was expected to have type + 'A' +but here has type + 'B' + +neg20.fs(53,38,53,39): typecheck error FS0001: This expression was expected to have type + 'System.ValueType' +but here has type + 'int' + +neg20.fs(60,26,60,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'A'. + +neg20.fs(61,27,61,35): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B1'. This element has type 'B2'. + +neg20.fs(62,26,62,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'C'. This element has type 'B'. + +neg20.fs(66,25,66,32): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'A'. This element has type 'B'. + +neg20.fs(67,27,67,34): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'C'. + +neg20.fs(70,31,70,38): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'C'. + +neg20.fs(71,34,71,42): typecheck error FS0001: Type mismatch. Expecting a + 'A list' +but given a + 'B list' +The type 'A' does not match the type 'B' + +neg20.fs(75,30,75,37): typecheck error FS0001: This expression was expected to have type + 'B' +but here has type + 'C' + +neg20.fs(76,34,76,43): typecheck error FS0001: Type mismatch. Expecting a + 'A list' +but given a + 'B list' +The type 'A' does not match the type 'B' + +neg20.fs(80,23,80,39): typecheck error FS0193: Type constraint mismatch. The type + 'C list' +is not compatible with type + 'seq' + + +neg20.fs(81,34,81,43): typecheck error FS0001: Type mismatch. Expecting a + 'A list' +but given a + 'B list' +The type 'A' does not match the type 'B' + +neg20.fs(83,47,83,54): typecheck error FS0001: All branches of an 'if' expression must return values implicitly convertible to the type of the first branch, which here is 'B'. This branch returns a value of type 'C'. + +neg20.fs(87,54,87,61): typecheck error FS0001: All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'B'. This branch returns a value of type 'C'. + +neg20.fs(92,19,92,26): typecheck error FS0001: This expression was expected to have type + 'A' +but here has type + 'B' + +neg20.fs(96,26,96,33): typecheck error FS0001: This expression was expected to have type + 'B' +but here has type + 'A' + +neg20.fs(97,26,97,33): typecheck error FS0001: This expression was expected to have type + 'A' +but here has type + 'B' + +neg20.fs(99,26,99,33): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'B'. This element has type 'A'. + +neg20.fs(108,12,108,16): typecheck error FS0001: Type mismatch. Expecting a + 'B * B -> 'a' +but given a + 'A * A -> Data' +The type 'B' does not match the type 'A' + +neg20.fs(109,12,109,16): typecheck error FS0001: Type mismatch. Expecting a + 'A * B -> 'a' +but given a + 'A * A -> Data' +The type 'B' does not match the type 'A' + +neg20.fs(110,12,110,16): typecheck error FS0001: Type mismatch. Expecting a + 'B * A -> 'a' +but given a + 'A * A -> Data' +The type 'B' does not match the type 'A' + +neg20.fs(128,19,128,22): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(129,19,129,22): typecheck error FS0001: This expression was expected to have type + 'obj' +but here has type + 'string' + +neg20.fs(131,5,131,24): typecheck error FS0041: No overloads match for method 'OM3'. + +Known types of arguments: string * obj + +Available overloads: + - static member C.OM3: x: 'b * y: 'b -> int // Argument 'y' doesn't match + - static member C.OM3: x: 'b * y: int -> int // Argument 'y' doesn't match + +neg20.fs(152,13,152,23): typecheck error FS0033: The type 'Test.BadNumberOfGenericParameters.C<_>' expects 1 type argument(s) but is given 2 + +neg20.fs(153,13,153,23): typecheck error FS0033: The type 'Test.BadNumberOfGenericParameters.C<_>' expects 1 type argument(s) but is given 2 + +neg20.fs(154,13,154,25): typecheck error FS0502: The member or object constructor 'SM1' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM1: unit -> int'. + +neg20.fs(155,13,155,26): typecheck error FS0502: The member or object constructor 'SM2' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM2: y: int -> int'. + +neg20.fs(156,13,156,28): typecheck error FS0502: The member or object constructor 'SM3' takes 0 type argument(s) but is here given 1. The required signature is 'static member C.SM3: y: int * z: int -> int'. + +neg20.fs(157,28,157,29): typecheck error FS0495: The member or object constructor 'SM3' has no argument or settable return property 'x'. The required signature is static member C.SM3: y: int * z: int -> int. + +neg20.fs(158,13,158,36): typecheck error FS0502: The member or object constructor 'SM4' takes 1 type argument(s) but is here given 2. The required signature is 'static member C.SM4: y: 'a * z: 'b -> int'. + +neg20.fs(159,13,159,32): typecheck error FS0502: The member or object constructor 'SM5' takes 2 type argument(s) but is here given 1. The required signature is 'static member C.SM5: y: 'a * z: 'b -> int'. + +neg20.fs(162,13,162,24): typecheck error FS0502: The member or object constructor 'M1' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M1: unit -> int'. + +neg20.fs(163,13,163,25): typecheck error FS0502: The member or object constructor 'M2' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M2: y: int -> int'. + +neg20.fs(164,13,164,27): typecheck error FS0502: The member or object constructor 'M3' takes 0 type argument(s) but is here given 1. The required signature is 'member C.M3: y: int * z: int -> int'. + +neg20.fs(165,27,165,28): typecheck error FS0495: The member or object constructor 'M3' has no argument or settable return property 'x'. The required signature is member C.M3: y: int * z: int -> int. + +neg20.fs(166,13,166,35): typecheck error FS0502: The member or object constructor 'M4' takes 1 type argument(s) but is here given 2. The required signature is 'member C.M4: y: 'a * z: 'b -> int'. + +neg20.fs(167,13,167,31): typecheck error FS0502: The member or object constructor 'M5' takes 2 type argument(s) but is here given 1. The required signature is 'member C.M5: y: 'a * z: 'b -> int'. + +neg20.fs(182,14,182,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * obj + +Available overloads: + - static member C2.M: fmt: string * [] args: int[] -> string // Argument 'args' doesn't match + - static member C2.M: fmt: string * [] args: int[] -> string // Argument at index 1 doesn't match + +neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(183,29,183,34): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(183,35,183,40): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(183,14,183,41): typecheck error FS0001: This expression was expected to have type + 'unit' +but here has type + 'string' + +neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(184,28,184,33): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(184,34,184,39): typecheck error FS0001: This expression was expected to have type + 'int' +but here has type + 'obj' + +neg20.fs(188,14,188,31): typecheck error FS0041: No overloads match for method 'M'. + +Known types of arguments: string * obj + +Available overloads: + - static member C3.M: fmt: string * [] args: string[] -> string // Argument 'args' doesn't match + - static member C3.M: fmt: string * [] args: string[] -> string // Argument at index 1 doesn't match + +neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(189,29,189,34): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(189,35,189,40): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(189,14,189,41): typecheck error FS0001: This expression was expected to have type + 'unit' +but here has type + 'string' + +neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(190,28,190,33): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(190,34,190,39): typecheck error FS0001: This expression was expected to have type + 'string' +but here has type + 'obj' + +neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(198,5,198,11): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(201,3,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations + +neg20.fs(204,5,204,14): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(207,5,207,11): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(210,5,210,12): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(213,5,213,33): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(216,5,216,12): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(219,5,219,15): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(222,5,222,24): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(225,5,225,22): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(228,5,228,23): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(231,5,231,21): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(234,5,234,34): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(237,5,237,34): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(240,5,240,23): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(243,5,243,23): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(249,9,249,27): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(255,5,255,21): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(258,5,258,31): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(261,5,261,17): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(265,5,265,24): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(268,5,268,27): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(271,5,271,13): typecheck error FS0842: This attribute is not valid for use on this language element + +neg20.fs(278,14,278,95): typecheck error FS0507: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. Note the call to this member also provides 2 named arguments. + +neg20.fs(280,14,280,94): typecheck error FS0508: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. The named argument 'Argument' doesn't correspond to any argument or settable return property for any overload. + +neg20.fs(285,12,285,13): typecheck error FS0038: 'x' is bound twice in this pattern + +neg20.fs(286,14,286,15): typecheck error FS0038: 'x' is bound twice in this pattern + +neg20.fs(288,17,288,18): typecheck error FS0038: 'x' is bound twice in this pattern + +neg20.fs(294,5,294,36): typecheck error FS0840: Unrecognized attribute target. Valid attribute targets are 'assembly', 'module', 'type', 'method', 'property', 'return', 'param', 'field', 'event', 'constructor'. + +neg20.fs(301,8,301,16): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(304,8,304,16): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(307,8,307,20): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(310,8,310,17): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(313,8,313,15): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(316,8,316,19): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(319,8,319,17): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(322,8,322,18): typecheck error FS3132: This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. + +neg20.fs(335,11,335,24): typecheck error FS0041: A unique overload for method 'String' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - System.String(value: char[]) : System.String + - System.String(value: nativeptr) : System.String + - System.String(value: nativeptr) : System.String + +neg20.fs(336,11,336,22): typecheck error FS0041: A unique overload for method 'Guid' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 + +Candidates: + - System.Guid(b: byte[]) : System.Guid + - System.Guid(g: string) : System.Guid + +neg20.fs(355,19,355,38): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. + +neg20.fs(356,22,356,41): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. + +neg20.fs(370,19,370,38): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' + +neg20.fs(371,19,371,38): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. + +neg20.fs(372,22,372,41): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' + +neg20.fs(373,22,373,41): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. + +neg20.fs(382,19,382,40): typecheck error FS1124: Multiple types exist called 'OverloadedClassName', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'OverloadedClassName<_>'. + +neg20.fs(383,39,383,41): typecheck error FS0039: The type 'OverloadedClassName<_>' does not define the field, constructor or member 'S2'. + +neg20.fs(428,19,428,38): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' + +neg20.fs(430,22,430,41): typecheck error FS1133: No constructors are available for the type 'OverloadedClassName<'a,'b>' + +neg20.fs(444,39,444,41): typecheck error FS0039: The type 'OverloadedClassName' does not define the field, constructor or member 'S2'. diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.fs b/tests/fsharp/typecheck/sigs/version50/neg20.fs new file mode 100644 index 00000000000..1574d4d3340 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/version50/neg20.fs @@ -0,0 +1,445 @@ +module Test + +type A() = + member x.P = 1 + +type B() = + inherit A() + member x.P = 1 + +type B1() = + inherit A() + member x.P = 1 + +type B2() = + inherit A() + member x.P = 1 + + +type C() = + inherit B() + member x.P = 1 + +module BiGenericStaticMemberTests = + type StaticClass1() = + static member M<'b>(c:'b, d:'b) = 1 + + let obj = new obj() + let str = "" + + StaticClass1.M(obj,str) + StaticClass1.M(str,obj) + StaticClass1.M(obj,obj) + + StaticClass1.M(obj,str) // obj :> 'b --> obj = 'b + StaticClass1.M(str,obj) // string :> 'b --> string = 'b + +module BiGenericFunctionTests = + let M<'b>(c:'b, d:'b) = 1 + + let obj = new obj() + let str = "" + + M(obj,str) + M(str,obj) + M(obj,obj) + + M(obj,str) // obj :> 'b --> obj = 'b + M(str,obj) // string :> 'b --> string = 'b + + +module NoSubsumptionOnApplication = + (fun (x:A) -> 1) (new B()) // now permitted + (fun (x:System.ValueType) -> 1) 1 // coercion on application! + + +module NoSubsumptionForLists = + type StaticClass2() = + static member DisplayControls(controls: A list) = () + + let v21 = [ new B(); new A() ] + let v22 = [ new B1(); new B2() ] + let v2b = [ new C(); new B() ] + let v2c : A list = [ new B(); new C() ] + StaticClass2.DisplayControls [ new B1(); new B2() ] + + let v2 = [ new A(); new B() ] + let v2b' = [ new B(); new C() ] + let v2c' : A list = [ (new B() :> A); new C() ] + + let controls = [ new B(); new C() ] + StaticClass2.DisplayControls controls // bang + + // Q: how about on sequence expressions? + let controls2 = [ yield (new B()) + yield (new C()) ] + StaticClass2.DisplayControls controls2 + + // Q: how about on sequence expressions? + let controls3 = [ yield! [new B()] + yield! [new C()] ] + StaticClass2.DisplayControls controls3 // bang + + let controls4 = if true then new B() else new C() + StaticClass2.DisplayControls [controls4] // allowed + + // Q: how about on matches? allowed + let controls5 = match 1 with 1 -> new B() | _ -> new C() + StaticClass2.DisplayControls [controls5] // allowed + + + // Q. subsumption on 'let v = expr'? Allowed + let x76 : A = new B() + +module NoSubsumptionForLists2 = + + let d1 = new B() :: new A() :: [] + let d2 = new A() :: new B() :: [] + + let v2a = [ new B(); new A() ] // would not work! + // cf. let v2b = [ (new B() :> A); new A() ] + + type Data = Data of A * A + let data (x,y) = Data (x,y) + let pAA = (new A(),new A()) + let pBB = (new B(),new B()) + let pAB = (new A(),new B()) + let pBA = (new B(),new A()) + pBB |> Data // not permitted (questionable) + pAB |> Data // not permitted (questionable) + pBA |> Data // not permitted (questionable) + pBB |> data // permitted + pAB |> data // permitted + pBA |> data // permitted + +module BiGenericMethodsInGenericClassTests = + type C<'a>() = + static member M(x:'a) = 1 + static member M2<'b>(x:'b) = 1 + static member M3<'b>(x:'b,y:'b) = 1 + + static member OM3<'b>(x:'b,y:'b) = 1 + + static member OM3<'b>(x:'b,y:int) = 1 + + let obj = new obj() + let str = "" + + C.M3("a",obj) // this is not permitted since 'b is inferred to be "string". Fair enough + C.M3(obj,"a") // now permitted + + C.OM3("a",obj) // this is not permitted since 'b is inferred to be "string". Fair enough + + + + +module BadNumberOfGenericParameters = + + type C<'a>() = + member x.P = 1 + member x.M1() = 2 + member x.M2(y:int) = 2 + member x.M3(y:int,z:int) = 2 + member x.M4<'b>(y:'a,z:'b) = 2 + member x.M5<'b,'c>(y:'a,z:'b) = 2 + + static member SP = 1 + static member SM1() = 2 + static member SM2(y:int) = 2 + static member SM3(y:int,z:int) = 2 + static member SM4<'b>(y:'a,z:'b) = 2 + static member SM5<'b,'c>(y:'a,z:'b) = 2 + let _ = C.SP + let _ = C.M1 + let _ = C.SM1() // expect error here + let _ = C.SM2(3) // expect error here + let _ = C.SM3(3,4) // expect error here + let _ = C.SM3(y=3,x=4) // expect error here + let _ = C.SM4(y=3,z=4) // expect error here + let _ = C.SM5(y=3,z=4) // expect error here + + let c = C() + let _ = c.M1() // expect error here + let _ = c.M2(3) // expect error here + let _ = c.M3(3,4) // expect error here + let _ = c.M3(y=3,x=4) // expect error here + let _ = c.M4(y=3,z=4) // expect error here + let _ = c.M5(y=3,z=4) // expect error here + + module PositiveTests = + let _ = C.SM4(y=3,z=4) // expect NO NO NO NO NO error here + let _ = C.SM4(y=3,z=4) // expect NO NO NO NO NO error here + let _ = C.SM5(y=3,z=4) // expect NO NO NO NO NO error here + let _ = c.M4(y=3,z=4) // expect NO NO NO NO NO error here + let _ = c.M4(y=3,z=4) // expect NO NO NO NO NO error here + let _ = c.M5(y=3,z=4) // expect NO NO NO NO NO error here + + +module ParamArgs = begin + type C2() = class + static member M( fmt:string, [] args : int[]) = System.String.Format(fmt,args) + end + let () = C2.M("{0}",box 1) // expect error + let () = C2.M("{0},{1}",box 1,box 2) // expect error + let _ = C2.M("{0},{1}",box 1,box 2) // expect error + type C3() = class + static member M( fmt:string, [] args : string[]) = System.String.Format(fmt,args) + end + let () = C3.M("{0}",box 1) // expect error + let () = C3.M("{0},{1}",box 1,box 2) // expect error + let _ = C3.M("{0},{1}",box 1,box 2) // expect error +end + +module BadAttribute = begin + + [] + let T1 = 1 + + [] + let T2 = 1 + + [] + let T3 = 1 + + [] + let T4 = 1 + + [] + let T5 = 1 + + [] + let T6 = 1 + + [] + let T7 = 1 + + [] + type C1() = class end + + [] + type C2() = class end + + [] + let T8 = 1 + + [] + let T9 = 1 + + [] + let T10 = 1 + + [] + let T11 = 1 + + [] + type C3() = class end + + [] + module M = begin end + + [] + module M2 = begin end + + [] + type C4() = class end + + + type C5 = + class + [] val x : int + end + + + type C6() = class end + + [] + let T12 = 1 + + [] + let T13 = 1 + + [] + type C7() = class end + + + [] + type C8() = class end + + [] + let T14 = 1 + + [] + let T15 = 1 + +end + +module BadArgName = begin + + let psi1 = new System.Diagnostics.ProcessStartInfo(FileName = "test", arguments = "testarg") + + let psi2 = new System.Diagnostics.ProcessStartInfo(FileName = "test", Argument = "testarg") +end + +module DuplicateArgNames = begin + + let f1 x x = () + let f2 x _ x = () + type C() = + member x.M(x:int) = x + x +end + + +module BogusAttributeTarget = begin + + [] + let x = 5 +end + +module BogusUseOfCLIMutable = begin + + [] + type BadClass() = member x.P = 1 + + [] + type BadUnion = A | B + + [] + type BadInterface = interface end + + [] + type BadClass2 = class end + + [] + type BadEnum = | A = 1 | B = 2 + + [] + type BadDelegate = delegate of int * int -> int + + [] + type BadStruct = struct val x : int end + + [] + type BadStruct2(x:int) = struct member v.X = x end + + [] + type Good1 = { x : int; y : int } + let good1 = { x = 1; y = 2 } + + [] + type Good2 = { x : int } + let good2 = { x = 1 } + +end + + +let ss1 = System.String +let ss2 = System.Guid + +type ClassWithOneConstructor(x:int) = member x.P = 1 + +let ss3 = ClassWithOneConstructor + + +module OverloadedTypeNamesBothHaveConstructors = + type OverloadedClassName<'T>(x:int) = + new (y:string) = OverloadedClassName<'T>(1) + member __.P = x + static member S() = 3 + + + type OverloadedClassName<'T1,'T2>(x:int) = + new (y:string) = OverloadedClassName<'T1,'T2>(1) + member __.P = x + static member S() = 3 + + let t3 = 3 |> OverloadedClassName // expected error - multiple types exist + let t3s = "3" |> OverloadedClassName // expected error - multiple types exist + + +module OverloadedTypeNamesSomeConstructors = + type OverloadedClassName<'T>(x:int) = + new (y:string) = OverloadedClassName<'T>(1) + member __.P = x + static member S() = 3 + + + type OverloadedClassName<'T1,'T2> = + member __.P = 1 + static member S() = 3 + + let t2 = 3 |> OverloadedClassName // CHANGE IN ERROR MESSAGE IN F# 4.x: Was "Invalid use of a type name", now "No constructors are available for the type 'OverloadedClassName<'a,'b>'" + let t3 = 3 |> OverloadedClassName // expected error - multiple types exist + let t2s = "3" |> OverloadedClassName // CHANGE IN ERROR MESSAGE IN F# 4.x: Was "Invalid use of a type name", now "No constructors are available for the type 'OverloadedClassName<'a,'b>'" + let t3s = "3" |> OverloadedClassName // expected error - multiple types exist + +module OverloadedTypeNamesNoConstructors = + type OverloadedClassName<'T> = + static member S(x:int) = 3 + + type OverloadedClassName<'T1,'T2> = + static member S(x:int) = 3 + + let t3 = 3 |> OverloadedClassName.S // expected error - multiple types exist + let t4 = 3 |> OverloadedClassName.S2 // expected error - The field, constructor or member 'S2' is not defined + + + + + + +module OverloadedTypeNamesIncludingNonGenericTypeBothHaveConstructors = + + type OverloadedClassName(x:int) = + new (y:string) = OverloadedClassName(1) + member __.P = x + static member S() = 3 + + type OverloadedClassName<'T>(x:int) = + new (y:string) = OverloadedClassName<'T>(1) + member __.P = x + static member S() = 3 + + + type OverloadedClassName<'T1,'T2>(x:int) = + new (y:string) = OverloadedClassName<'T1,'T2>(1) + member __.P = x + static member S() = 3 + + let t3 = 3 |> OverloadedClassName // expected error - multiple types exist + let t3s = "3" |> OverloadedClassName // expected error - multiple types exist + + +module OverloadedTypeNamesIncludingNonGenericTypeSomeConstructors = + type OverloadedClassName(x:int) = + new (y:string) = OverloadedClassName(1) + member __.P = x + static member S() = 3 + + type OverloadedClassName<'T>(x:int) = + new (y:string) = OverloadedClassName<'T>(1) + member __.P = x + static member S() = 3 + + + type OverloadedClassName<'T1,'T2> = + member __.P = 1 + static member S() = 3 + + let t2 = 3 |> OverloadedClassName // CHANGE IN ERROR MESSAGE IN F# 4.x: Was "Invalid use of a type name", now "No constructors are available for the type 'OverloadedClassName<'a,'b>'" + let t3 = 3 |> OverloadedClassName // NO ERROR EXPECTED + let t2s = "3" |> OverloadedClassName // CHANGE IN ERROR MESSAGE IN F# 4.x: Was "Invalid use of a type name", now "No constructors are available for the type 'OverloadedClassName<'a,'b>'" + let t3s = "3" |> OverloadedClassName // expected error - multiple types exist + +module OverloadedTypeNamesIncludingNonGenericTypeNoConstructors = + type OverloadedClassName = + static member S(x:int) = 3 + + type OverloadedClassName<'T> = + static member S(x:int) = 3 + + type OverloadedClassName<'T1,'T2> = + static member S(x:int) = 3 + + let t3 = 3 |> OverloadedClassName.S // NO ERROR EXPECTED + let t4 = 3 |> OverloadedClassName.S2 // expected error - The field, constructor or member 'S2' is not defined + diff --git a/tests/fsharp/update.base.line.with.actuals.fsx b/tests/fsharp/update.base.line.with.actuals.fsx deleted file mode 100644 index 8b391a2f459..00000000000 --- a/tests/fsharp/update.base.line.with.actuals.fsx +++ /dev/null @@ -1,27 +0,0 @@ -open System.IO - -// this script is usefull for tests using a .bsl file (baseline) containing expected compiler output -// which is matched against .vserr or .err file aside once the test has run -// the script replaces all the .bsl/.bslpp with either .err or .vserr - -let directories = - [ - "typecheck/sigs" - "typeProviders/negTests" - ] - |> List.map (fun d -> Path.Combine(__SOURCE_DIRECTORY__, d) |> DirectoryInfo) - -let extensionPatterns = ["*.err"; "*.vserr"] -for d in directories do - for p in extensionPatterns do - for errFile in d.GetFiles p do - let baseLineFile = FileInfo(Path.ChangeExtension(errFile.FullName, "bsl")) - let baseLineFilePreProcess = FileInfo(Path.ChangeExtension(errFile.FullName, "bslpp")) - - if File.ReadAllText(errFile.FullName) <> File.ReadAllText(baseLineFile.FullName) then - let expectedFile = - if baseLineFilePreProcess.Exists then baseLineFilePreProcess - else baseLineFile - - printfn "%s not matching, replacing with %s" expectedFile.FullName errFile.FullName - errFile.CopyTo(expectedFile.FullName, true) |> ignore diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/.il.bsl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl index 3e69ae4967f..821abbd9685 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest1 { - // Offset: 0x00000000 Length: 0x0000026C + // Offset: 0x00000000 Length: 0x00000260 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest1 { - // Offset: 0x00000270 Length: 0x000000B1 + // Offset: 0x00000268 Length: 0x000000B1 } .module AsyncExpressionSteppingTest1.dll -// MVID: {5AF5DDAE-6394-B5D4-A745-0383AEDDF55A} +// MVID: {611B0EC4-6394-B5D4-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02880000 +// Image base: 0x06680000 // =============== CLASS MEMBERS DECLARATION =================== @@ -83,7 +83,7 @@ // Code size 62 (0x3e) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 17,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs' + .line 6,6 : 17,32 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs' IL_0000: ldstr "hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -140,11 +140,12 @@ { // Code size 18 (0x12) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0, + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 10', [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1) - .line 10,10 : 13,43 '' + .line 10,10 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest1/AsyncExpressionSteppingTest1::f1() IL_0005: stloc.0 + .line 10,10 : 21,43 '' IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: ldloc.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl index 7bdb6a074c0..c5227768562 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest2 { - // Offset: 0x00000000 Length: 0x0000026C + // Offset: 0x00000000 Length: 0x00000260 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest2 { - // Offset: 0x00000270 Length: 0x000000B1 + // Offset: 0x00000268 Length: 0x000000B1 } .module AsyncExpressionSteppingTest2.dll -// MVID: {5AF5DDAE-6394-D499-A745-0383AEDDF55A} +// MVID: {611B0EC4-6394-D499-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x04520000 +// Image base: 0x06860000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,7 +80,7 @@ // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 23,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs' + .line 6,6 : 23,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs' IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest2/AsyncExpressionSteppingTest2/'f2@6-1'::x IL_0006: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) @@ -237,11 +237,12 @@ { // Code size 18 (0x12) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0, + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 11', [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1) - .line 11,11 : 13,43 '' + .line 11,11 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest2/AsyncExpressionSteppingTest2::f2() IL_0005: stloc.0 + .line 11,11 : 21,43 '' IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: ldloc.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl index 6dfebd88b1e..71cebc43a5d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest3 { - // Offset: 0x00000000 Length: 0x00000277 + // Offset: 0x00000000 Length: 0x0000026B } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest3 { - // Offset: 0x00000280 Length: 0x000000B1 + // Offset: 0x00000270 Length: 0x000000B1 } .module AsyncExpressionSteppingTest3.dll -// MVID: {5AF5DDAE-6394-F35E-A745-0383AEDDF55A} +// MVID: {611C52A3-6394-F35E-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x04650000 +// Image base: 0x06660000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,15 +80,17 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest3.fs' - IL_0000: ldarga.s ctxt - IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/'f3@10-1'::'value' - IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) - IL_000d: ret + .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest3.fs' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld int32 AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/'f3@10-1'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret } // end of method 'f3@10-1'::Invoke } // end of class 'f3@10-1' @@ -196,11 +198,12 @@ { // Code size 18 (0x12) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0, + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 12', [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1) - .line 12,12 : 13,43 '' + .line 12,12 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3::f3() IL_0005: stloc.0 + .line 12,12 : 21,43 '' IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: ldloc.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl index ce54bd4945d..a411614d6f9 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest4 { - // Offset: 0x00000000 Length: 0x00000277 + // Offset: 0x00000000 Length: 0x0000026B } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest4 { - // Offset: 0x00000280 Length: 0x000000B1 + // Offset: 0x00000270 Length: 0x000000B1 } .module AsyncExpressionSteppingTest4.dll -// MVID: {5AF5DDAE-6394-6D4B-A745-0383AEDDF55A} +// MVID: {611C52A3-6394-6D4B-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x028F0000 +// Image base: 0x06B50000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,15 +80,17 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 10,10 : 21,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest4.fs' - IL_0000: ldarga.s ctxt - IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@10-2'::'value' - IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) - IL_000d: ret + .line 10,10 : 21,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest4.fs' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld int32 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@10-2'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret } // end of method 'f4@10-2'::Invoke } // end of class 'f4@10-2' @@ -344,11 +346,12 @@ { // Code size 18 (0x12) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0, + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 15', [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1) - .line 15,15 : 13,43 '' + .line 15,15 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4::f4() IL_0005: stloc.0 + .line 15,15 : 21,43 '' IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: ldloc.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl index da554a3adf4..8ecc211736a 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest5 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest5 { - // Offset: 0x00000000 Length: 0x000002B8 + // Offset: 0x00000000 Length: 0x000002AC } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest5 { - // Offset: 0x000002C0 Length: 0x000000BE + // Offset: 0x000002B0 Length: 0x000000BE } .module AsyncExpressionSteppingTest5.dll -// MVID: {5AF5DDAE-6394-30E8-A745-0383AEDDF55A} +// MVID: {611C52A3-6394-30E8-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x04430000 +// Image base: 0x06B50000 // =============== CLASS MEMBERS DECLARATION =================== @@ -84,7 +84,7 @@ .maxstack 5 .locals init ([0] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 17,31 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest5.fs' + .line 6,6 : 17,31 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest5.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 7,7 : 20,35 '' @@ -399,7 +399,7 @@ // Code size 48 (0x30) .maxstack 6 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 es, - [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 13', [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2) .line 4,4 : 5,21 '' IL_0000: ldc.i4.3 @@ -415,9 +415,10 @@ IL_0017: dup IL_0018: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$AsyncExpressionSteppingTest5::es@4 IL_001d: stloc.0 - .line 13,13 : 13,43 '' + .line 13,13 : 13,17 '' IL_001e: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5::f7() IL_0023: stloc.1 + .line 13,13 : 21,43 '' IL_0024: ldloc.1 IL_0025: stloc.2 IL_0026: ldloc.2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl index 379ad6bbe7c..8fc65940265 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly AsyncExpressionSteppingTest6 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest6 { - // Offset: 0x00000000 Length: 0x000002A3 + // Offset: 0x00000000 Length: 0x00000297 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest6 { - // Offset: 0x000002A8 Length: 0x000000BE + // Offset: 0x000002A0 Length: 0x000000BE } .module AsyncExpressionSteppingTest6.dll -// MVID: {5AF5DDAE-6394-4FAD-A745-0383AEDDF55A} +// MVID: {611C52A3-6394-4FAD-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x04C40000 +// Image base: 0x06B60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +55,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@10-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@10-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public int32 'value' @@ -73,27 +73,29 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::'value' + IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-1'::'value' IL_000d: ret - } // end of method 'f2@10-4'::.ctor + } // end of method 'f2@10-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest6.fs' - IL_0000: ldarga.s ctxt - IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::'value' - IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) - IL_000d: ret - } // end of method 'f2@10-4'::Invoke + .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest6.fs' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-1'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } // end of method 'f2@10-1'::Invoke - } // end of class 'f2@10-4' + } // end of class 'f2@10-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@5-3' + .class auto ansi serializable sealed nested assembly beforefieldinit f2@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -111,9 +113,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@5-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f2@5::builder@ IL_000d: ret - } // end of method 'f2@5-3'::.ctor + } // end of method f2@5::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed @@ -150,20 +152,20 @@ IL_0029: stloc.2 .line 10,10 : 17,25 '' IL_002a: ldarg.0 - IL_002b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@5-3'::builder@ + IL_002b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f2@5::builder@ IL_0030: stloc.3 IL_0031: ldloc.2 IL_0032: stloc.s V_4 IL_0034: ldloc.s V_4 - IL_0036: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::.ctor(int32) + IL_0036: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-1'::.ctor(int32) IL_003b: tail. IL_003d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_0042: ret - } // end of method 'f2@5-3'::Invoke + } // end of method f2@5::Invoke - } // end of class 'f2@5-3' + } // end of class f2@5 - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@20-7' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@20-5' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public int32 'value' @@ -181,26 +183,28 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::'value' + IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-5'::'value' IL_000d: ret - } // end of method 'f3@20-7'::.ctor + } // end of method 'f3@20-5'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 8 .line 20,20 : 17,25 '' - IL_0000: ldarga.s ctxt - IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::'value' - IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) - IL_000d: ret - } // end of method 'f3@20-7'::Invoke + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-5'::'value' + IL_0007: tail. + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::Success(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + !0) + IL_000e: ret + } // end of method 'f3@20-5'::Invoke - } // end of class 'f3@20-7' + } // end of class 'f3@20-5' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-6' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -222,15 +226,15 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::x1 IL_0014: ldarg.0 IL_0015: ldarg.3 - IL_0016: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::y + IL_0016: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::y IL_001b: ret - } // end of method 'f3@19-6'::.ctor + } // end of method 'f3@19-4'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg4) cil managed @@ -246,9 +250,9 @@ IL_0001: stloc.0 .line 19,19 : 17,37 '' IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::x1 + IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::x1 IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::y + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::y IL_000e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) IL_0013: add IL_0014: ldloc.0 @@ -256,20 +260,20 @@ IL_0016: stloc.1 .line 20,20 : 17,25 '' IL_0017: ldarg.0 - IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::builder@ + IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::builder@ IL_001d: stloc.2 IL_001e: ldloc.1 IL_001f: stloc.3 IL_0020: ldloc.3 - IL_0021: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::.ctor(int32) + IL_0021: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-5'::.ctor(int32) IL_0026: tail. IL_0028: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_002d: ret - } // end of method 'f3@19-6'::Invoke + } // end of method 'f3@19-4'::Invoke - } // end of class 'f3@19-6' + } // end of class 'f3@19-4' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@18-8' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@18-6' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation @@ -292,12 +296,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::computation + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-6'::computation IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::binder + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-6'::binder IL_0014: ret - } // end of method 'f3@18-8'::.ctor + } // end of method 'f3@18-6'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed @@ -307,19 +311,19 @@ .line 18,18 : 17,31 '' IL_0000: ldarg.1 IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::computation + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-6'::computation IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::binder + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-6'::binder IL_000d: tail. IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret - } // end of method 'f3@18-8'::Invoke + } // end of method 'f3@18-6'::Invoke - } // end of class 'f3@18-8' + } // end of class 'f3@18-6' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -339,12 +343,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::x1 IL_0014: ret - } // end of method 'f3@16-5'::.ctor + } // end of method 'f3@16-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg3) cil managed @@ -369,31 +373,31 @@ IL_000f: nop .line 18,18 : 17,31 '' IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::builder@ IL_0016: stloc.2 IL_0017: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() IL_001c: stloc.3 IL_001d: ldarg.0 - IL_001e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ + IL_001e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::builder@ IL_0023: ldarg.0 - IL_0024: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::x1 + IL_0024: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::x1 IL_0029: ldloc.1 - IL_002a: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_002a: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) IL_002f: stloc.s V_4 IL_0031: ldloc.3 IL_0032: ldloc.s V_4 - IL_0034: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + IL_0034: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-6'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0039: tail. IL_003b: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_0040: ret - } // end of method 'f3@16-5'::Invoke + } // end of method 'f3@16-3'::Invoke - } // end of class 'f3@16-5' + } // end of class 'f3@16-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-9' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-7' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation @@ -416,12 +420,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::computation + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-7'::computation IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::binder + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-7'::binder IL_0014: ret - } // end of method 'f3@15-9'::.ctor + } // end of method 'f3@15-7'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed @@ -431,19 +435,19 @@ .line 15,15 : 17,31 '' IL_0000: ldarg.1 IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::computation + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-7'::computation IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::binder + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-7'::binder IL_000d: tail. IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret - } // end of method 'f3@15-9'::Invoke + } // end of method 'f3@15-7'::Invoke - } // end of class 'f3@15-9' + } // end of class 'f3@15-7' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -463,12 +467,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::x1 IL_0014: ret - } // end of method 'f3@15-4'::.ctor + } // end of method 'f3@15-2'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg2) cil managed @@ -484,29 +488,29 @@ IL_0001: stloc.0 .line 15,15 : 17,31 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::builder@ IL_0008: stloc.1 IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() IL_000e: stloc.2 IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ + IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::builder@ IL_0015: ldarg.0 - IL_0016: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::x1 - IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_0016: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::x1 + IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32) IL_0020: stloc.3 IL_0021: ldloc.2 IL_0022: ldloc.3 - IL_0023: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + IL_0023: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-7'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0028: tail. IL_002a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_002f: ret - } // end of method 'f3@15-4'::Invoke + } // end of method 'f3@15-2'::Invoke - } // end of class 'f3@15-4' + } // end of class 'f3@15-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-10' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-8' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation @@ -529,12 +533,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::computation + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-8'::computation IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::binder + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-8'::binder IL_0014: ret - } // end of method 'f3@14-10'::.ctor + } // end of method 'f3@14-8'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed @@ -544,19 +548,19 @@ .line 14,14 : 17,31 '' IL_0000: ldarg.1 IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::computation + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-8'::computation IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::binder + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-8'::binder IL_000d: tail. IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret - } // end of method 'f3@14-10'::Invoke + } // end of method 'f3@14-8'::Invoke - } // end of class 'f3@14-10' + } // end of class 'f3@14-8' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -574,9 +578,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-1'::builder@ IL_000d: ret - } // end of method 'f3@14-3'::.ctor + } // end of method 'f3@14-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg1) cil managed @@ -592,28 +596,28 @@ IL_0001: stloc.0 .line 14,14 : 17,31 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-1'::builder@ IL_0008: stloc.1 IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() IL_000e: stloc.2 IL_000f: ldarg.0 - IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ + IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-1'::builder@ IL_0015: ldloc.0 - IL_0016: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_0016: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32) IL_001b: stloc.3 IL_001c: ldloc.2 IL_001d: ldloc.3 - IL_001e: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_001e: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-8'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0023: tail. IL_0025: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_002a: ret - } // end of method 'f3@14-3'::Invoke + } // end of method 'f3@14-1'::Invoke - } // end of class 'f3@14-3' + } // end of class 'f3@14-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-11' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-9' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation @@ -636,12 +640,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::computation + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-9'::computation IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::binder + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-9'::binder IL_0014: ret - } // end of method 'f3@13-11'::.ctor + } // end of method 'f3@13-9'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed @@ -651,19 +655,19 @@ .line 13,13 : 17,31 '' IL_0000: ldarg.1 IL_0001: ldarg.0 - IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::computation + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-9'::computation IL_0007: ldarg.0 - IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::binder + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-9'::binder IL_000d: tail. IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret - } // end of method 'f3@13-11'::Invoke + } // end of method 'f3@13-9'::Invoke - } // end of class 'f3@13-11' + } // end of class 'f3@13-9' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-2' + .class auto ansi serializable sealed nested assembly beforefieldinit f3@13 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -681,9 +685,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f3@13::builder@ IL_000d: ret - } // end of method 'f3@13-2'::.ctor + } // end of method f3@13::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed @@ -695,24 +699,24 @@ [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_2) .line 13,13 : 17,31 '' IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f3@13::builder@ IL_0006: stloc.0 IL_0007: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() IL_000c: stloc.1 IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ - IL_0013: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f3@13::builder@ + IL_0013: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) IL_0018: stloc.2 IL_0019: ldloc.1 IL_001a: ldloc.2 - IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-9'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0020: tail. IL_0022: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) IL_0027: ret - } // end of method 'f3@13-2'::Invoke + } // end of method f3@13::Invoke - } // end of class 'f3@13-2' + } // end of class f3@13 .method public static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 f2() cil managed @@ -725,7 +729,7 @@ IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 - IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@5-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f2@5::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) IL_000d: tail. IL_000f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret @@ -742,7 +746,7 @@ IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 - IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/f3@13::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) IL_000d: tail. IL_000f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret @@ -764,11 +768,12 @@ { // Code size 18 (0x12) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_0, + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 'Pipe #1 input at line 22', [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1) - .line 22,22 : 13,43 '' + .line 22,22 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f3() IL_0005: stloc.0 + .line 22,22 : 21,43 '' IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: ldloc.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Default.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Default.il.bsl index bbe5b40ba64..9584bf6b19d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Default.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Default.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Default { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Default { - // Offset: 0x00000000 Length: 0x000003FA + // Offset: 0x00000000 Length: 0x000003F0 } .mresource public FSharpOptimizationData.Default { - // Offset: 0x00000400 Length: 0x000000BA + // Offset: 0x000003F8 Length: 0x000000BA } .module Default.dll -// MVID: {59B19208-AAA9-67BB-A745-03830892B159} +// MVID: {611C4D7D-AAA9-67BB-A745-03837D4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00E30000 +// Image base: 0x070A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AttributeTargets\\Default.fs' + .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AttributeTargets\\Default.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Attribute::.ctor() IL_0006: ldarg.0 @@ -103,20 +103,22 @@ .method private specialname rtspecialname static void .cctor() cil managed { - // Code size 25 (0x19) + // Code size 26 (0x1a) .maxstack 4 .locals init ([0] int32 T) + .line 11,12 : 1,29 '' + IL_0000: nop .line 12,12 : 10,25 '' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 12,12 : 27,28 '' - IL_0010: ldc.i4.1 - IL_0011: dup - IL_0012: stsfld int32 ''.$M::T@12 - IL_0017: stloc.0 - IL_0018: ret + IL_0011: ldc.i4.1 + IL_0012: dup + IL_0013: stsfld int32 ''.$M::T@12 + IL_0018: stloc.0 + IL_0019: ret } // end of method $M::.cctor } // end of class ''.$M diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Field.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Field.il.bsl index 6d4d86af42b..4eb09976030 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Field.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Field.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Field { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Field { - // Offset: 0x00000000 Length: 0x000003F4 + // Offset: 0x00000000 Length: 0x000003EA } .mresource public FSharpOptimizationData.Field { - // Offset: 0x000003F8 Length: 0x000000B8 + // Offset: 0x000003F0 Length: 0x000000B8 } .module Field.dll -// MVID: {59B19208-96F8-CD6E-A745-03830892B159} +// MVID: {611C4D7D-96F8-CD6E-A745-03837D4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F60000 +// Image base: 0x06AD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AttributeTargets\\Field.fs' + .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AttributeTargets\\Field.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Attribute::.ctor() IL_0006: ldarg.0 @@ -78,7 +78,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld int32 ''.$M::'T@12-2' + IL_0000: ldsfld int32 ''.$M::T@12 IL_0005: ret } // end of method M::get_T @@ -92,7 +92,7 @@ .class private abstract auto ansi sealed ''.$M extends [mscorlib]System.Object { - .field static assembly initonly int32 'T@12-2' + .field static assembly initonly int32 T@12 .custom instance void M/ExportAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly int32 init@ @@ -102,20 +102,22 @@ .method private specialname rtspecialname static void .cctor() cil managed { - // Code size 25 (0x19) + // Code size 26 (0x1a) .maxstack 4 .locals init ([0] int32 T) + .line 11,12 : 1,29 '' + IL_0000: nop .line 12,12 : 10,25 '' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 12,12 : 27,28 '' - IL_0010: ldc.i4.1 - IL_0011: dup - IL_0012: stsfld int32 ''.$M::'T@12-2' - IL_0017: stloc.0 - IL_0018: ret + IL_0011: ldc.i4.1 + IL_0012: dup + IL_0013: stsfld int32 ''.$M::T@12 + IL_0018: stloc.0 + IL_0019: ret } // end of method $M::.cctor } // end of class ''.$M diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Property.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Property.il.bsl index eb0160f0a01..1e5bb37b225 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Property.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AttributeTargets/Property.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Property { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Property { - // Offset: 0x00000000 Length: 0x000003FD + // Offset: 0x00000000 Length: 0x000003F3 } .mresource public FSharpOptimizationData.Property { - // Offset: 0x00000408 Length: 0x000000BB + // Offset: 0x000003F8 Length: 0x000000BB } .module Property.dll -// MVID: {59B19208-9B5C-7949-A745-03830892B159} +// MVID: {611C4D7D-9B5C-7949-A745-03837D4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02E80000 +// Image base: 0x06F60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AttributeTargets\\Property.fs' + .line 9,9 : 4,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AttributeTargets\\Property.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Attribute::.ctor() IL_0006: ldarg.0 @@ -78,7 +78,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld int32 ''.$M::'T@12-4' + IL_0000: ldsfld int32 ''.$M::T@12 IL_0005: ret } // end of method M::get_T @@ -93,7 +93,7 @@ .class private abstract auto ansi sealed ''.$M extends [mscorlib]System.Object { - .field static assembly initonly int32 'T@12-4' + .field static assembly initonly int32 T@12 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly int32 init@ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -102,20 +102,22 @@ .method private specialname rtspecialname static void .cctor() cil managed { - // Code size 25 (0x19) + // Code size 26 (0x1a) .maxstack 4 .locals init ([0] int32 T) + .line 11,12 : 1,29 '' + IL_0000: nop .line 12,12 : 10,25 '' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 12,12 : 27,28 '' - IL_0010: ldc.i4.1 - IL_0011: dup - IL_0012: stsfld int32 ''.$M::'T@12-4' - IL_0017: stloc.0 - IL_0018: ret + IL_0011: ldc.i4.1 + IL_0012: dup + IL_0013: stsfld int32 ''.$M::T@12 + IL_0018: stloc.0 + IL_0019: ret } // end of method $M::.cctor } // end of class ''.$M diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl index 5875beb14e4..f8f286e007d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CCtorDUWithMember01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CCtorDUWithMember01 { - // Offset: 0x00000000 Length: 0x00000790 + // Offset: 0x00000000 Length: 0x0000077A } .mresource public FSharpOptimizationData.CCtorDUWithMember01 { - // Offset: 0x00000798 Length: 0x00000227 + // Offset: 0x00000780 Length: 0x00000227 } .module CCtorDUWithMember01.exe -// MVID: {59B1923F-26F1-14EE-A745-03833F92B159} +// MVID: {6124062C-26F1-14EE-A745-03832C062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00A70000 +// Image base: 0x068A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,36 +63,24 @@ .method public static void main@() cil managed { .entrypoint - // Code size 61 (0x3d) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - [1] class CCtorDUWithMember01a/C V_1, - [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_2, - [3] class CCtorDUWithMember01a/C V_3) + // Code size 53 (0x35) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember01.fs' + .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember01.fs' IL_0000: ldstr "File1.A = %A" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class CCtorDUWithMember01a/C>::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: call class CCtorDUWithMember01a/C CCtorDUWithMember01a/C::get_A() - IL_0015: stloc.1 - IL_0016: ldloc.0 - IL_0017: ldloc.1 - IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001d: pop + IL_000f: call class CCtorDUWithMember01a/C CCtorDUWithMember01a/C::get_A() + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: pop .line 3,3 : 1,23 '' - IL_001e: ldstr "Test.e2 = %A" - IL_0023: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class CCtorDUWithMember01a/C>::.ctor(string) - IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_002d: stloc.2 - IL_002e: call class CCtorDUWithMember01a/C CCtorDUWithMember01a::get_e2() - IL_0033: stloc.3 - IL_0034: ldloc.2 - IL_0035: ldloc.3 - IL_0036: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_003b: pop - IL_003c: ret + IL_001a: ldstr "Test.e2 = %A" + IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class CCtorDUWithMember01a/C>::.ctor(string) + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0029: call class CCtorDUWithMember01a/C CCtorDUWithMember01a::get_e2() + IL_002e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0033: pop + IL_0034: ret } // end of method $CCtorDUWithMember01::main@ } // end of class ''.$CCtorDUWithMember01 @@ -255,76 +243,63 @@ instance int32 CompareTo(class CCtorDUWithMember01a/C obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 64 (0x40) + // Code size 49 (0x31) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember01a.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0032 - + .line 3,3 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember01a.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0030 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: bne.un.s IL_0028 - - IL_0026: br.s IL_002a - - IL_0028: br.s IL_002c - + IL_001a: stloc.1 .line 100001,100001 : 0,0 '' - IL_002a: ldc.i4.0 - IL_002b: ret + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: bne.un.s IL_0021 .line 100001,100001 : 0,0 '' - IL_002c: ldloc.0 - IL_002d: ldloc.1 - IL_002e: sub - IL_002f: ret + IL_001f: ldc.i4.0 + IL_0020: ret .line 100001,100001 : 0,0 '' - IL_0030: ldc.i4.1 - IL_0031: ret + IL_0021: ldloc.0 + IL_0022: ldloc.1 + IL_0023: sub + IL_0024: ret .line 100001,100001 : 0,0 '' - IL_0032: ldarg.1 - IL_0033: ldnull - IL_0034: cgt.un - IL_0036: brfalse.s IL_003a - - IL_0038: br.s IL_003c + IL_0025: ldc.i4.1 + IL_0026: ret - IL_003a: br.s IL_003e + .line 100001,100001 : 0,0 '' + IL_0027: ldarg.1 + IL_0028: ldnull + IL_0029: cgt.un + IL_002b: brfalse.s IL_002f .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.m1 - IL_003d: ret + IL_002d: ldc.i4.m1 + IL_002e: ret .line 100001,100001 : 0,0 '' - IL_003e: ldc.i4.0 - IL_003f: ret + IL_002f: ldc.i4.0 + IL_0030: ret } // end of method C::CompareTo .method public hidebysig virtual final @@ -346,7 +321,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) + // Code size 65 (0x41) .maxstack 4 .locals init ([0] class CCtorDUWithMember01a/C V_0, [1] int32 V_1, @@ -355,102 +330,86 @@ IL_0000: ldarg.1 IL_0001: unbox.any CCtorDUWithMember01a/C IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0011 - - IL_000f: br.s IL_003e + IL_000b: brfalse.s IL_0032 .line 100001,100001 : 0,0 '' - IL_0011: ldarg.1 - IL_0012: unbox.any CCtorDUWithMember01a/C - IL_0017: ldnull - IL_0018: cgt.un - IL_001a: brfalse.s IL_001e - - IL_001c: br.s IL_0020 - - IL_001e: br.s IL_003c + IL_000d: ldarg.1 + IL_000e: unbox.any CCtorDUWithMember01a/C + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_0030 .line 100001,100001 : 0,0 '' - IL_0020: ldarg.0 - IL_0021: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0026: stloc.1 - IL_0027: ldloc.0 - IL_0028: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_002d: stloc.2 - IL_002e: ldloc.1 - IL_002f: ldloc.2 - IL_0030: bne.un.s IL_0034 - - IL_0032: br.s IL_0036 - - IL_0034: br.s IL_0038 - + IL_0018: ldarg.0 + IL_0019: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_001e: stloc.1 + IL_001f: ldloc.0 + IL_0020: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0025: stloc.2 .line 100001,100001 : 0,0 '' - IL_0036: ldc.i4.0 - IL_0037: ret + IL_0026: ldloc.1 + IL_0027: ldloc.2 + IL_0028: bne.un.s IL_002c .line 100001,100001 : 0,0 '' - IL_0038: ldloc.1 - IL_0039: ldloc.2 - IL_003a: sub - IL_003b: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.1 - IL_003d: ret + IL_002c: ldloc.1 + IL_002d: ldloc.2 + IL_002e: sub + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003e: ldarg.1 - IL_003f: unbox.any CCtorDUWithMember01a/C - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d + IL_0030: ldc.i4.1 + IL_0031: ret - IL_004b: br.s IL_004f + .line 100001,100001 : 0,0 '' + IL_0032: ldarg.1 + IL_0033: unbox.any CCtorDUWithMember01a/C + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f .line 100001,100001 : 0,0 '' - IL_004d: ldc.i4.m1 - IL_004e: ret + IL_003d: ldc.i4.m1 + IL_003e: ret .line 100001,100001 : 0,0 '' - IL_004f: ldc.i4.0 - IL_0050: ret + IL_003f: ldc.i4.0 + IL_0040: ret } // end of method C::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 21 (0x15) + // Code size 18 (0x12) .maxstack 3 .locals init ([0] int32 V_0) + .line 3,3 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0013 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0010 .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0012: ret + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_000f: ret .line 100001,100001 : 0,0 '' - IL_0013: ldc.i4.0 - IL_0014: ret + IL_0010: ldc.i4.0 + IL_0011: ret } // end of method C::GetHashCode .method public hidebysig virtual final @@ -471,150 +430,142 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 55 (0x37) + // Code size 48 (0x30) .maxstack 4 .locals init ([0] class CCtorDUWithMember01a/C V_0, [1] class CCtorDUWithMember01a/C V_1, [2] int32 V_2, [3] int32 V_3) + .line 3,3 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_002f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst CCtorDUWithMember01a/C - IL_0010: stloc.0 - IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_002d + IL_0007: ldarg.1 + IL_0008: isinst CCtorDUWithMember01a/C + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0026 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.0 + IL_0011: ldloc.0 + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0019: stloc.2 + IL_001a: ldloc.1 IL_001b: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0020: stloc.2 - IL_0021: ldloc.1 - IL_0022: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0027: stloc.3 - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: ceq - IL_002c: ret + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: ceq + IL_0025: ret .line 100001,100001 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_0026: ldc.i4.0 + IL_0027: ret .line 100001,100001 : 0,0 '' - IL_002f: ldarg.1 - IL_0030: ldnull - IL_0031: cgt.un - IL_0033: ldc.i4.0 - IL_0034: ceq - IL_0036: ret + IL_0028: ldarg.1 + IL_0029: ldnull + IL_002a: cgt.un + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: ret } // end of method C::Equals .method public hidebysig specialname instance int32 get_P() cil managed { - // Code size 2 (0x2) - .maxstack 8 + // Code size 4 (0x4) + .maxstack 3 + .locals init ([0] class CCtorDUWithMember01a/C x) + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: stloc.0 .line 6,6 : 18,19 '' - IL_0000: ldc.i4.1 - IL_0001: ret + IL_0002: ldc.i4.1 + IL_0003: ret } // end of method C::get_P .method public hidebysig virtual final instance bool Equals(class CCtorDUWithMember01a/C obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 49 (0x31) + // Code size 42 (0x2a) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) + .line 3,3 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0029 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0022 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0027 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0020 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 CCtorDUWithMember01a/C::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: ceq - IL_0026: ret + IL_001a: stloc.1 + .line 100001,100001 : 0,0 '' + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: ceq + IL_001f: ret .line 100001,100001 : 0,0 '' - IL_0027: ldc.i4.0 - IL_0028: ret + IL_0020: ldc.i4.0 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0029: ldarg.1 - IL_002a: ldnull - IL_002b: cgt.un - IL_002d: ldc.i4.0 - IL_002e: ceq - IL_0030: ret + IL_0022: ldarg.1 + IL_0023: ldnull + IL_0024: cgt.un + IL_0026: ldc.i4.0 + IL_0027: ceq + IL_0029: ret } // end of method C::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class CCtorDUWithMember01a/C V_0) .line 3,3 : 6,7 '' IL_0000: ldarg.1 IL_0001: isinst CCtorDUWithMember01a/C IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool CCtorDUWithMember01a/C::Equals(class CCtorDUWithMember01a/C) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool CCtorDUWithMember01a/C::Equals(class CCtorDUWithMember01a/C) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method C::Equals .property instance int32 Tag() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember02.il.bsl index f8d32ee78a8..c9441f898d1 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CCtorDUWithMember02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CCtorDUWithMember02 { - // Offset: 0x00000000 Length: 0x0000030C + // Offset: 0x00000000 Length: 0x00000302 } .mresource public FSharpOptimizationData.CCtorDUWithMember02 { - // Offset: 0x00000310 Length: 0x000000E4 + // Offset: 0x00000308 Length: 0x000000E4 } .module CCtorDUWithMember02.exe -// MVID: {59B1923F-D176-C99D-A745-03833F92B159} +// MVID: {608C04FF-D176-C99D-A745-0383FF048C60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01380000 +// Image base: 0x06EF0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,23 +63,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 31 (0x1f) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - [1] int32 V_1) + // Code size 27 (0x1b) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 2,2 : 1,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember02.fs' + .line 2,2 : 1,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember02.fs' IL_0000: ldstr "x = %A" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: call int32 CCtorDUWithMember02a::get_y() - IL_0015: stloc.1 - IL_0016: ldloc.0 - IL_0017: ldloc.1 - IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001d: pop - IL_001e: ret + IL_000f: call int32 CCtorDUWithMember02a::get_y() + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: pop + IL_001a: ret } // end of method $CCtorDUWithMember02::main@ } // end of class ''.$CCtorDUWithMember02 @@ -152,7 +146,7 @@ // Code size 77 (0x4d) .maxstack 4 .locals init ([0] int32 y) - .line 3,3 : 1,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember02a.fs' + .line 3,3 : 1,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember02a.fs' IL_0000: ldstr "hello1" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember03.il.bsl index 2ded0bcb8b9..3f429b894ad 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CCtorDUWithMember03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CCtorDUWithMember03 { - // Offset: 0x00000000 Length: 0x0000029D + // Offset: 0x00000000 Length: 0x00000293 } .mresource public FSharpOptimizationData.CCtorDUWithMember03 { - // Offset: 0x000002A8 Length: 0x000000B2 + // Offset: 0x00000298 Length: 0x000000B2 } .module CCtorDUWithMember03.exe -// MVID: {59B1923F-C97B-D207-A745-03833F92B159} +// MVID: {608C04FF-C97B-D207-A745-0383FF048C60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x030C0000 +// Image base: 0x072C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,23 +63,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 31 (0x1f) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - [1] int32 V_1) + // Code size 27 (0x1b) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember03.fs' + .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember03.fs' IL_0000: ldstr "File1.x = %A" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: call int32 CCtorDUWithMember03a::get_x() - IL_0015: stloc.1 - IL_0016: ldloc.0 - IL_0017: ldloc.1 - IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001d: pop - IL_001e: ret + IL_000f: call int32 CCtorDUWithMember03a::get_x() + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: pop + IL_001a: ret } // end of method $CCtorDUWithMember03::main@ } // end of class ''.$CCtorDUWithMember03 @@ -93,7 +87,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld int32 ''.$CCtorDUWithMember03a::'x@3-1' + IL_0000: ldsfld int32 ''.$CCtorDUWithMember03a::x@3 IL_0005: ret } // end of method CCtorDUWithMember03a::get_x @@ -103,7 +97,7 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: stsfld int32 ''.$CCtorDUWithMember03a::'x@3-1' + IL_0001: stsfld int32 ''.$CCtorDUWithMember03a::x@3 IL_0006: ret } // end of method CCtorDUWithMember03a::set_x @@ -118,7 +112,7 @@ .class private abstract auto ansi sealed ''.$CCtorDUWithMember03a extends [mscorlib]System.Object { - .field static assembly int32 'x@3-1' + .field static assembly int32 x@3 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly int32 init@ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -129,9 +123,9 @@ { // Code size 7 (0x7) .maxstack 8 - .line 3,3 : 1,18 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember03a.fs' + .line 3,3 : 1,18 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember03a.fs' IL_0000: ldc.i4.1 - IL_0001: stsfld int32 ''.$CCtorDUWithMember03a::'x@3-1' + IL_0001: stsfld int32 ''.$CCtorDUWithMember03a::x@3 IL_0006: ret } // end of method $CCtorDUWithMember03a::.cctor diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember04.il.bsl index 4063e241fda..41590465474 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CCtorDUWithMember04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CCtorDUWithMember04 { - // Offset: 0x00000000 Length: 0x0000029D + // Offset: 0x00000000 Length: 0x00000293 } .mresource public FSharpOptimizationData.CCtorDUWithMember04 { - // Offset: 0x000002A8 Length: 0x000000B2 + // Offset: 0x00000298 Length: 0x000000B2 } .module CCtorDUWithMember04.exe -// MVID: {59B1923F-CF28-717B-A745-03833F92B159} +// MVID: {608C04FF-CF28-717B-A745-0383FF048C60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AA0000 +// Image base: 0x06780000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,23 +63,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 31 (0x1f) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0, - [1] int32 V_1) + // Code size 27 (0x1b) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember04.fs' + .line 2,2 : 1,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember04.fs' IL_0000: ldstr "File1.x = %A" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: stloc.0 - IL_0010: call int32 CCtorDUWithMember04a::get_x() - IL_0015: stloc.1 - IL_0016: ldloc.0 - IL_0017: ldloc.1 - IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001d: pop - IL_001e: ret + IL_000f: call int32 CCtorDUWithMember04a::get_x() + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: pop + IL_001a: ret } // end of method $CCtorDUWithMember04::main@ } // end of class ''.$CCtorDUWithMember04 @@ -118,7 +112,7 @@ // Code size 7 (0x7) .maxstack 3 .locals init ([0] int32 x) - .line 3,3 : 1,10 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember04a.fs' + .line 3,3 : 1,10 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CCtorDUWithMember\\CCtorDUWithMember04a.fs' IL_0000: call int32 CCtorDUWithMember04a::get_x() IL_0005: stloc.0 IL_0006: ret diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd index 1786d4bc552..ea97cebadcb 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompareIL.cmd @@ -1,9 +1,17 @@ REM == %1 --> assembly ildasm /TEXT /LINENUM /NOBAR "%~nx1" >"%~n1.il" -IF NOT ERRORLEVEL 0 exit 1 +IF %ERRORLEVEL% NEQ 0 exit /b 1 echo %~dp0..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" %~dp0..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" -exit /b %ERRORLEVEL% + +IF %ERRORLEVEL% EQU 0 exit /b 0 + +if /i "%TEST_UPDATE_BSL%" == "1" ( + echo copy /y "%~n1.il" "%~n1.il.bsl" + copy /y "%~n1.il" "%~n1.il.bsl" +) + +exit /b 1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute02.il.bsl index 6adf54e44d5..cc0468b88a0 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CompiledNameAttribute02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CompiledNameAttribute02 { - // Offset: 0x00000000 Length: 0x000002E8 + // Offset: 0x00000000 Length: 0x000002E4 } .mresource public FSharpOptimizationData.CompiledNameAttribute02 { - // Offset: 0x000002F0 Length: 0x000000CD + // Offset: 0x000002E8 Length: 0x000000CD } .module CompiledNameAttribute02.exe -// MVID: {59B1923F-F755-F3C0-A745-03833F92B159} +// MVID: {6124062C-F755-F3C0-A745-03832C062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x018A0000 +// Image base: 0x06A90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,14 +60,18 @@ int32 y) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationSourceNameAttribute::.ctor(string) = ( 01 00 06 4D 65 74 68 6F 64 00 00 ) // ...Method.. - // Code size 4 (0x4) - .maxstack 8 + // Code size 6 (0x6) + .maxstack 4 + .locals init ([0] class CompiledNameAttribute02/T a) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 34,39 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\CompiledNameAttribute\\CompiledNameAttribute02.fs' - IL_0000: ldarg.1 - IL_0001: ldarg.2 - IL_0002: add - IL_0003: ret + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\CompiledNameAttribute\\CompiledNameAttribute02.fs' + IL_0000: ldarg.0 + IL_0001: stloc.0 + .line 5,5 : 34,39 '' + IL_0002: ldarg.1 + IL_0003: ldarg.2 + IL_0004: add + IL_0005: ret } // end of method T::SomeCompiledName } // end of class T diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl index 6007efcdfb7..71f865a4cfa 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CompiledNameAttribute/CompiledNameAttribute04.il.bsl @@ -327,7 +327,7 @@ } // end of method a@49::.ctor .method private hidebysig newslot virtual final - instance int32 'CompiledNameAttribute04-ITestInterface-M'(int32 x) cil managed + instance int32 CompiledNameAttribute04.ITestInterface.M(int32 x) cil managed { .custom instance void [mscorlib]System.Runtime.InteropServices.PreserveSigAttribute::.ctor() = ( 01 00 00 00 ) .override CompiledNameAttribute04/ITestInterface::M @@ -338,7 +338,7 @@ IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret - } // end of method a@49::'CompiledNameAttribute04-ITestInterface-M' + } // end of method a@49::CompiledNameAttribute04.ITestInterface.M } // end of class a@49 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr01.il.bsl index 056640724cf..08899c42c83 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr01 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr01 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr01.exe -// MVID: {5A1F62A7-3703-E566-A745-0383A7621F5A} +// MVID: {611B0EC4-3703-E566-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x007B0000 +// Image base: 0x071D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -83,7 +83,7 @@ // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 9,17 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr01.fs' + .line 8,8 : 9,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr01.fs' IL_0000: ldarg.0 IL_0001: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr01/res1@8::builder@ IL_0006: ldc.i4.1 @@ -123,10 +123,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res1, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 10') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -137,11 +138,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr01::res1@6 IL_0018: stloc.0 - .line 10,10 : 1,25 '' + .line 10,10 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr01::get_res1() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 10,10 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr01::main@ } // end of class ''.$ComputationExpr01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr02.il.bsl index 80dd23ca0b0..c9914148327 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr02 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr02 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr02.exe -// MVID: {5A1F62A7-3624-E566-A745-0383A7621F5A} +// MVID: {611C4D7F-3624-E566-A745-03837F4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01010000 +// Image base: 0x071B0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,28 +80,30 @@ .method public strict virtual instance class [ComputationExprLibrary]Library.Eventually`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 44 (0x2c) + // Code size 45 (0x2d) .maxstack 7 .locals init ([0] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 18,33 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr02.fs' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + .line 8,8 : 9,50 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr02.fs' + IL_0000: nop + .line 8,8 : 18,33 '' + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 8,8 : 35,49 '' - IL_0010: ldstr "hello" - IL_0015: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_001a: stloc.0 + IL_0011: ldstr "hello" + IL_0016: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_001b: stloc.0 .line 9,9 : 9,21 '' - IL_001b: ldarg.0 - IL_001c: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr02/res2@8::builder@ - IL_0021: ldloc.0 + IL_001c: ldarg.0 + IL_001d: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr02/res2@8::builder@ IL_0022: ldloc.0 - IL_0023: add - IL_0024: tail. - IL_0026: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) - IL_002b: ret + IL_0023: ldloc.0 + IL_0024: add + IL_0025: tail. + IL_0027: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) + IL_002c: ret } // end of method res2@8::Invoke } // end of class res2@8 @@ -135,10 +137,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res2, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 10') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -149,11 +152,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr02::res2@6 IL_0018: stloc.0 - .line 10,10 : 1,25 '' + .line 10,10 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr02::get_res2() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 10,10 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr02::main@ } // end of class ''.$ComputationExpr02 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr03.il.bsl index 46926f5d00e..2451cc77523 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr03 { - // Offset: 0x00000000 Length: 0x00000222 + // Offset: 0x00000000 Length: 0x00000238 } .mresource public FSharpOptimizationData.ComputationExpr03 { - // Offset: 0x00000228 Length: 0x0000008C + // Offset: 0x00000240 Length: 0x0000008C } .module ComputationExpr03.exe -// MVID: {5A1F62A7-3649-E566-A745-0383A7621F5A} +// MVID: {611C4D7F-3649-E566-A745-03837F4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00BF0000 +// Image base: 0x06EE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +55,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'res2@8-1' + .class auto ansi serializable sealed nested assembly beforefieldinit res2@8 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [ComputationExprLibrary]Library.EventuallyBuilder builder@ @@ -73,38 +73,40 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/'res2@8-1'::builder@ + IL_0008: stfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/res2@8::builder@ IL_000d: ret - } // end of method 'res2@8-1'::.ctor + } // end of method res2@8::.ctor .method public strict virtual instance class [ComputationExprLibrary]Library.Eventually`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 44 (0x2c) + // Code size 45 (0x2d) .maxstack 7 .locals init ([0] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 18,33 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr03.fs' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + .line 8,8 : 9,50 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr03.fs' + IL_0000: nop + .line 8,8 : 18,33 '' + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 8,8 : 35,49 '' - IL_0010: ldstr "hello" - IL_0015: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_001a: stloc.0 + IL_0011: ldstr "hello" + IL_0016: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_001b: stloc.0 .line 9,9 : 9,21 '' - IL_001b: ldarg.0 - IL_001c: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/'res2@8-1'::builder@ - IL_0021: ldloc.0 + IL_001c: ldarg.0 + IL_001d: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/res2@8::builder@ IL_0022: ldloc.0 - IL_0023: add - IL_0024: tail. - IL_0026: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) - IL_002b: ret - } // end of method 'res2@8-1'::Invoke + IL_0023: ldloc.0 + IL_0024: add + IL_0025: tail. + IL_0027: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) + IL_002c: ret + } // end of method res2@8::Invoke - } // end of class 'res2@8-1' + } // end of class res2@8 .class auto ansi serializable sealed nested assembly beforefieldinit 'res3@17-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> @@ -131,25 +133,27 @@ .method public strict virtual instance class [ComputationExprLibrary]Library.Eventually`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 42 (0x2a) + // Code size 43 (0x2b) .maxstack 6 .locals init ([0] int32 x) + .line 17,17 : 17,58 '' + IL_0000: nop .line 17,17 : 26,41 '' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 17,17 : 43,57 '' - IL_0010: ldstr "hello" - IL_0015: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_001a: stloc.0 + IL_0011: ldstr "hello" + IL_0016: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_001b: stloc.0 .line 18,18 : 17,25 '' - IL_001b: ldarg.0 - IL_001c: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/'res3@17-2'::builder@ - IL_0021: ldc.i4.1 - IL_0022: tail. - IL_0024: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) - IL_0029: ret + IL_001c: ldarg.0 + IL_001d: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr03/'res3@17-2'::builder@ + IL_0022: ldc.i4.1 + IL_0023: tail. + IL_0025: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) + IL_002a: ret } // end of method 'res3@17-2'::Invoke } // end of class 'res3@17-2' @@ -295,7 +299,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::'res2@6-2' + IL_0000: ldsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::res2@6 IL_0005: ret } // end of method ComputationExpr03::get_res2 @@ -325,7 +329,7 @@ .class private abstract auto ansi sealed ''.$ComputationExpr03 extends [mscorlib]System.Object { - .field static assembly class [ComputationExprLibrary]Library.Eventually`1 'res2@6-2' + .field static assembly class [ComputationExprLibrary]Library.Eventually`1 res2@6 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [ComputationExprLibrary]Library.Eventually`1 res3@12 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -336,40 +340,48 @@ .method public static void main@() cil managed { .entrypoint - // Code size 73 (0x49) + // Code size 82 (0x52) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res2, [1] class [ComputationExprLibrary]Library.Eventually`1 res3, [2] class [ComputationExprLibrary]Library.EventuallyBuilder V_2, - [3] class [ComputationExprLibrary]Library.EventuallyBuilder V_3) + [3] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 10', + [4] class [ComputationExprLibrary]Library.EventuallyBuilder V_4, + [5] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #2 input at line 22') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.2 IL_0006: ldloc.2 IL_0007: ldloc.2 - IL_0008: newobj instance void ComputationExpr03/'res2@8-1'::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) + IL_0008: newobj instance void ComputationExpr03/res2@8::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) IL_000d: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0012: dup - IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::'res2@6-2' + IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::res2@6 IL_0018: stloc.0 - .line 10,10 : 1,25 '' + .line 10,10 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr03::get_res2() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() - IL_0029: stloc.3 - IL_002a: ldloc.3 - IL_002b: ldloc.3 - IL_002c: newobj instance void ComputationExpr03/res3@14::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) - IL_0031: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0036: dup - IL_0037: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::res3@12 - IL_003c: stloc.1 - .line 22,22 : 1,26 '' - IL_003d: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr03::get_res3() - IL_0042: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0047: pop - IL_0048: ret + IL_001e: stloc.3 + .line 10,10 : 9,25 '' + IL_001f: ldloc.3 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() + IL_002b: stloc.s V_4 + IL_002d: ldloc.s V_4 + IL_002f: ldloc.s V_4 + IL_0031: newobj instance void ComputationExpr03/res3@14::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) + IL_0036: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_003b: dup + IL_003c: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr03::res3@12 + IL_0041: stloc.1 + .line 22,22 : 1,5 '' + IL_0042: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr03::get_res3() + IL_0047: stloc.s 'Pipe #2 input at line 22' + .line 22,22 : 10,26 '' + IL_0049: ldloc.s 'Pipe #2 input at line 22' + IL_004b: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0050: pop + IL_0051: ret } // end of method $ComputationExpr03::main@ } // end of class ''.$ComputationExpr03 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr04.il.bsl index 6f211063ee2..fec0b17fa41 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr04 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr04 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr04.exe -// MVID: {5A1F62A7-366A-E566-A745-0383A7621F5A} +// MVID: {611C4D7F-366A-E566-A745-03837F4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x04DD0000 +// Image base: 0x06D30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,42 +80,44 @@ .method public strict virtual instance class [ComputationExprLibrary]Library.Eventually`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 67 (0x43) + // Code size 68 (0x44) .maxstack 6 .locals init ([0] int32 x, [1] string V_1) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 22,37 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr04.fs' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + .line 7,7 : 13,54 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr04.fs' + IL_0000: nop + .line 7,7 : 22,37 '' + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 7,7 : 39,53 '' - IL_0010: ldstr "hello" - IL_0015: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_001a: stloc.0 + IL_0011: ldstr "hello" + IL_0016: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_001b: stloc.0 .line 8,8 : 13,28 '' - IL_001b: ldstr "fail" - IL_0020: stloc.1 - IL_0021: ldc.i4.0 - IL_0022: brfalse.s IL_002c + IL_001c: ldstr "fail" + IL_0021: stloc.1 + IL_0022: ldc.i4.0 + IL_0023: brfalse.s IL_002d - IL_0024: ldnull - IL_0025: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit - IL_002a: br.s IL_0033 + IL_0025: ldnull + IL_0026: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit + IL_002b: br.s IL_0034 - IL_002c: ldloc.1 - IL_002d: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0032: throw + IL_002d: ldloc.1 + IL_002e: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0033: throw - IL_0033: pop + IL_0034: pop .line 9,9 : 13,21 '' - IL_0034: ldarg.0 - IL_0035: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr04/'res4@7-1'::builder@ - IL_003a: ldloc.0 - IL_003b: tail. - IL_003d: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) - IL_0042: ret + IL_0035: ldarg.0 + IL_0036: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr04/'res4@7-1'::builder@ + IL_003b: ldloc.0 + IL_003c: tail. + IL_003e: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Return(!!0) + IL_0043: ret } // end of method 'res4@7-1'::Invoke } // end of class 'res4@7-1' @@ -250,10 +252,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res4, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 14') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -264,11 +267,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr04::res4@4 IL_0018: stloc.0 - .line 14,14 : 1,25 '' + .line 14,14 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr04::get_res4() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 14,14 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr04::main@ } // end of class ''.$ComputationExpr04 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl index 8f5858d32b2..8556c5ef694 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr05 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr05 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr05.exe -// MVID: {5A1F62A7-3687-E566-A745-0383A7621F5A} +// MVID: {6124062C-3687-E566-A745-03832C062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x039D0000 +// Image base: 0x07110000 // =============== CLASS MEMBERS DECLARATION =================== @@ -73,15 +73,19 @@ } // end of method 'res5@9-1'::.ctor .method private hidebysig newslot virtual final - instance void 'System-IDisposable-Dispose'() cil managed + instance void System.IDisposable.Dispose() cil managed { .override [mscorlib]System.IDisposable::Dispose - // Code size 1 (0x1) - .maxstack 8 + // Code size 3 (0x3) + .maxstack 4 + .locals init ([0] class [mscorlib]System.IDisposable x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 68,70 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr05.fs' - IL_0000: ret - } // end of method 'res5@9-1'::'System-IDisposable-Dispose' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr05.fs' + IL_0000: ldarg.0 + IL_0001: stloc.0 + .line 9,9 : 68,70 '' + IL_0002: ret + } // end of method 'res5@9-1'::System.IDisposable.Dispose } // end of class 'res5@9-1' @@ -112,8 +116,8 @@ { // Code size 45 (0x2d) .maxstack 6 - .locals init ([0] class [mscorlib]System.IDisposable x, - [1] int32 V_1) + .locals init ([0] class [mscorlib]System.IDisposable 'x (shadowed)', + [1] int32 x) .line 10,10 : 9,50 '' IL_0000: ldarg.1 IL_0001: stloc.0 @@ -164,29 +168,31 @@ .method public strict virtual instance class [ComputationExprLibrary]Library.Eventually`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 57 (0x39) + // Code size 58 (0x3a) .maxstack 7 .locals init ([0] int32 x) + .line 8,8 : 9,50 '' + IL_0000: nop .line 8,8 : 18,33 '' - IL_0000: ldstr "hello" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: pop + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop .line 8,8 : 35,49 '' - IL_0010: ldstr "hello" - IL_0015: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_001a: stloc.0 + IL_0011: ldstr "hello" + IL_0016: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_001b: stloc.0 .line 9,9 : 17,72 '' - IL_001b: ldarg.0 - IL_001c: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr05/res5@8::builder@ - IL_0021: newobj instance void ComputationExpr05/'res5@9-1'::.ctor() - IL_0026: ldarg.0 - IL_0027: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr05/res5@8::builder@ - IL_002c: newobj instance void ComputationExpr05/'res5@10-2'::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) - IL_0031: tail. - IL_0033: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Using(class [mscorlib]System.IDisposable, + IL_001c: ldarg.0 + IL_001d: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr05/res5@8::builder@ + IL_0022: newobj instance void ComputationExpr05/'res5@9-1'::.ctor() + IL_0027: ldarg.0 + IL_0028: ldfld class [ComputationExprLibrary]Library.EventuallyBuilder ComputationExpr05/res5@8::builder@ + IL_002d: newobj instance void ComputationExpr05/'res5@10-2'::.ctor(class [ComputationExprLibrary]Library.EventuallyBuilder) + IL_0032: tail. + IL_0034: callvirt instance class [ComputationExprLibrary]Library.Eventually`1 [ComputationExprLibrary]Library.EventuallyBuilder::Using(class [mscorlib]System.IDisposable, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0038: ret + IL_0039: ret } // end of method res5@8::Invoke } // end of class res5@8 @@ -220,10 +226,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res5, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 13') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -234,11 +241,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr05::res5@6 IL_0018: stloc.0 - .line 13,13 : 1,25 '' + .line 13,13 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr05::get_res5() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 13,13 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr05::main@ } // end of class ''.$ComputationExpr05 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr06.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr06.il.bsl index 93152a9b90f..02b98964ca4 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr06.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr06 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr06 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr06.exe -// MVID: {5A1F62A7-35A8-E566-A745-0383A7621F5A} +// MVID: {611B0EC4-35A8-E566-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00DD0000 +// Image base: 0x07080000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,7 +80,7 @@ // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 15,21 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr06.fs' + .line 9,9 : 15,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr06.fs' IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ComputationExpr06/'res6@9-1'::x IL_0006: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) @@ -292,10 +292,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res6, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 18') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -306,11 +307,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr06::res6@6 IL_0018: stloc.0 - .line 18,18 : 1,25 '' + .line 18,18 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr06::get_res6() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 18,18 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr06::main@ } // end of class ''.$ComputationExpr06 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr07.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr07.il.bsl index 2e07f1e3d66..a9c352baefe 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr07.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExpr07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern ComputationExprLibrary { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.ComputationExpr07 { - // Offset: 0x00000000 Length: 0x000001F8 + // Offset: 0x00000000 Length: 0x0000020E } .mresource public FSharpOptimizationData.ComputationExpr07 { - // Offset: 0x00000200 Length: 0x0000007D + // Offset: 0x00000218 Length: 0x0000007D } .module ComputationExpr07.exe -// MVID: {5A1F62A7-35BD-E566-A745-0383A7621F5A} +// MVID: {611B0EC4-35BD-E566-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03800000 +// Image base: 0x06E40000 // =============== CLASS MEMBERS DECLARATION =================== @@ -89,7 +89,7 @@ .maxstack 7 .locals init ([0] int32 v) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 9,9 : 9,29 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr07.fs' + .line 9,9 : 9,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ComputationExpressions\\ComputationExpr07.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 10,10 : 13,24 '' @@ -254,10 +254,11 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) + // Code size 39 (0x27) .maxstack 4 .locals init ([0] class [ComputationExprLibrary]Library.Eventually`1 res7, - [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1) + [1] class [ComputationExprLibrary]Library.EventuallyBuilder V_1, + [2] class [ComputationExprLibrary]Library.Eventually`1 'Pipe #1 input at line 13') .line 100001,100001 : 0,0 '' IL_0000: call class [ComputationExprLibrary]Library.EventuallyBuilder [ComputationExprLibrary]Library.TheEventuallyBuilder::get_eventually() IL_0005: stloc.1 @@ -268,11 +269,14 @@ IL_0012: dup IL_0013: stsfld class [ComputationExprLibrary]Library.Eventually`1 ''.$ComputationExpr07::res7@6 IL_0018: stloc.0 - .line 13,13 : 1,25 '' + .line 13,13 : 1,5 '' IL_0019: call class [ComputationExprLibrary]Library.Eventually`1 ComputationExpr07::get_res7() - IL_001e: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) - IL_0023: pop - IL_0024: ret + IL_001e: stloc.2 + .line 13,13 : 9,25 '' + IL_001f: ldloc.2 + IL_0020: call !!0 [ComputationExprLibrary]Library.EventuallyModule::force(class [ComputationExprLibrary]Library.Eventually`1) + IL_0025: pop + IL_0026: ret } // end of method $ComputationExpr07::main@ } // end of class ''.$ComputationExpr07 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExprLibrary.fs b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExprLibrary.fs index 90ae5e8665c..4b1c9bd1304 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExprLibrary.fs +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExprLibrary.fs @@ -74,7 +74,7 @@ module Eventually = let tryWith e handler = catch e |> bind (function Result v -> Done v | Exception e -> handler e) - + let rec doWhile f e = if f() then e |> bind (fun () -> doWhile f e) else Eventually.Done () diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface.il.bsl index 4693af05dc0..9b45e6d76b1 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_ArrayOfArray_FSInterface { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_ArrayOfArray_FSInterface { - // Offset: 0x00000000 Length: 0x00000272 + // Offset: 0x00000000 Length: 0x0000026E } .mresource public FSharpOptimizationData.DoNotBoxStruct_ArrayOfArray_FSInterface { // Offset: 0x00000278 Length: 0x000000A6 } .module DoNotBoxStruct_ArrayOfArray_FSInterface.exe -// MVID: {59B1920A-8A45-C8A0-A745-03830A92B159} +// MVID: {5FCFFD0B-8A45-C8A0-A745-03830BFDCF5F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00680000 +// Image base: 0x06B80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,9 +51,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'F@5-4' + .class auto ansi serializable sealed nested assembly beforefieldinit F@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class DoNotBoxStruct_ArrayOfArray_FSInterface/F@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -64,7 +65,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'F@5-4'::.ctor + } // end of method F@5::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(int32 x) cil managed @@ -72,12 +73,22 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 71,73 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_ArrayOfArray_FSInterface.fs' + .line 5,5 : 71,73 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_ArrayOfArray_FSInterface.fs' IL_0000: ldnull IL_0001: ret - } // end of method 'F@5-4'::Invoke + } // end of method F@5::Invoke - } // end of class 'F@5-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void DoNotBoxStruct_ArrayOfArray_FSInterface/F@5::.ctor() + IL_0005: stsfld class DoNotBoxStruct_ArrayOfArray_FSInterface/F@5 DoNotBoxStruct_ArrayOfArray_FSInterface/F@5::@_instance + IL_000a: ret + } // end of method F@5::.cctor + + } // end of class F@5 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[][] x) cil managed { @@ -91,7 +102,7 @@ IL_0008: ldelem !!T IL_000d: box !!T IL_0012: unbox.any class [mscorlib]System.IObservable`1 - IL_0017: newobj instance void DoNotBoxStruct_ArrayOfArray_FSInterface/'F@5-4'::.ctor() + IL_0017: ldsfld class DoNotBoxStruct_ArrayOfArray_FSInterface/F@5 DoNotBoxStruct_ArrayOfArray_FSInterface/F@5::@_instance IL_001c: tail. IL_001e: call void [FSharp.Core]Microsoft.FSharp.Control.CommonExtensions::AddToObservable(class [mscorlib]System.IObservable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.il.bsl index 1ef23f5de14..ca9de145cae 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth { - // Offset: 0x00000000 Length: 0x00000291 + // Offset: 0x00000000 Length: 0x0000028D } .mresource public FSharpOptimizationData.DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth { // Offset: 0x00000298 Length: 0x000000BA } .module DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.exe -// MVID: {59B1920A-1475-D984-A745-03830A92B159} +// MVID: {60E47018-1475-D984-A745-03831870E460} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x015B0000 +// Image base: 0x07120000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,40 +51,25 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname F@6 + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname F@6 extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method assembly static void Invoke(object x, + int32 _arg1) cil managed { - // Code size 7 (0x7) + // Code size 1 (0x1) .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method F@6::.ctor - - .method assembly hidebysig instance void - Invoke(object x, - int32 _arg1) cil managed - { - // Code size 3 (0x3) - .maxstack 5 - .locals init ([0] int32 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.fs' - IL_0000: ldarg.2 - IL_0001: stloc.0 - .line 6,6 : 80,82 '' - IL_0002: ret + .line 6,6 : 80,82 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth.fs' + IL_0000: ret } // end of method F@6::Invoke } // end of class F@6 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[][] x) cil managed { - // Code size 44 (0x2c) + // Code size 40 (0x28) .maxstack 8 .line 6,6 : 48,83 '' IL_0000: ldarg.0 @@ -93,15 +78,15 @@ IL_0007: ldc.i4.0 IL_0008: readonly. IL_000a: ldelema !!T - IL_000f: newobj instance void DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth/F@6::.ctor() - IL_0014: ldftn instance void DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth/F@6::Invoke(object, - int32) - IL_001a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, + IL_000f: ldnull + IL_0010: ldftn void DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth/F@6::Invoke(object, + int32) + IL_0016: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, native int) - IL_001f: constrained. !!T - IL_0025: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) - IL_002a: nop - IL_002b: ret + IL_001b: constrained. !!T + IL_0021: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) + IL_0026: nop + IL_0027: ret } // end of method DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth::F } // end of class DoNotBoxStruct_ArrayOfArray_FSInterface_NoExtMeth diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface.il.bsl index 6b25b5eec24..ac37c4ffa3f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_Array_FSInterface { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_Array_FSInterface { - // Offset: 0x00000000 Length: 0x00000259 + // Offset: 0x00000000 Length: 0x00000255 } .mresource public FSharpOptimizationData.DoNotBoxStruct_Array_FSInterface { // Offset: 0x00000260 Length: 0x00000098 } .module DoNotBoxStruct_Array_FSInterface.exe -// MVID: {59B1920A-1737-9DA5-A745-03830A92B159} +// MVID: {5FCFFD0B-1737-9DA5-A745-03830BFDCF5F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00300000 +// Image base: 0x07340000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,9 +51,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'F@5-5' + .class auto ansi serializable sealed nested assembly beforefieldinit F@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class DoNotBoxStruct_Array_FSInterface/F@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -64,7 +65,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'F@5-5'::.ctor + } // end of method F@5::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(int32 x) cil managed @@ -72,12 +73,22 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 65,67 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_Array_FSInterface.fs' + .line 5,5 : 65,67 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_Array_FSInterface.fs' IL_0000: ldnull IL_0001: ret - } // end of method 'F@5-5'::Invoke + } // end of method F@5::Invoke - } // end of class 'F@5-5' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void DoNotBoxStruct_Array_FSInterface/F@5::.ctor() + IL_0005: stsfld class DoNotBoxStruct_Array_FSInterface/F@5 DoNotBoxStruct_Array_FSInterface/F@5::@_instance + IL_000a: ret + } // end of method F@5::.cctor + + } // end of class F@5 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[] x) cil managed { @@ -89,7 +100,7 @@ IL_0002: ldelem !!T IL_0007: box !!T IL_000c: unbox.any class [mscorlib]System.IObservable`1 - IL_0011: newobj instance void DoNotBoxStruct_Array_FSInterface/'F@5-5'::.ctor() + IL_0011: ldsfld class DoNotBoxStruct_Array_FSInterface/F@5 DoNotBoxStruct_Array_FSInterface/F@5::@_instance IL_0016: tail. IL_0018: call void [FSharp.Core]Microsoft.FSharp.Control.CommonExtensions::AddToObservable(class [mscorlib]System.IObservable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface_NoExtMeth.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface_NoExtMeth.il.bsl index c4a168a2d73..49e25d8ea32 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface_NoExtMeth.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_Array_FSInterface_NoExtMeth.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_Array_FSInterface_NoExtMeth { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_Array_FSInterface_NoExtMeth { - // Offset: 0x00000000 Length: 0x00000278 + // Offset: 0x00000000 Length: 0x00000273 } .mresource public FSharpOptimizationData.DoNotBoxStruct_Array_FSInterface_NoExtMeth { - // Offset: 0x00000280 Length: 0x000000AC + // Offset: 0x00000278 Length: 0x000000AC } .module DoNotBoxStruct_Array_FSInterface_NoExtMeth.exe -// MVID: {59B1920A-8127-3EE3-A745-03830A92B159} +// MVID: {60E47018-8127-3EE3-A745-03831870E460} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00740000 +// Image base: 0x054A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,55 +51,40 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'F@6-1' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname F@6 extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method assembly static void Invoke(object x, + int32 _arg1) cil managed { - // Code size 7 (0x7) + // Code size 1 (0x1) .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'F@6-1'::.ctor - - .method assembly hidebysig instance void - Invoke(object x, - int32 _arg1) cil managed - { - // Code size 3 (0x3) - .maxstack 5 - .locals init ([0] int32 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_Array_FSInterface_NoExtMeth.fs' - IL_0000: ldarg.2 - IL_0001: stloc.0 - .line 6,6 : 74,76 '' - IL_0002: ret - } // end of method 'F@6-1'::Invoke + .line 6,6 : 74,76 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_Array_FSInterface_NoExtMeth.fs' + IL_0000: ret + } // end of method F@6::Invoke - } // end of class 'F@6-1' + } // end of class F@6 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[] x) cil managed { - // Code size 38 (0x26) + // Code size 34 (0x22) .maxstack 8 .line 6,6 : 46,77 '' IL_0000: ldarg.0 IL_0001: ldc.i4.0 IL_0002: readonly. IL_0004: ldelema !!T - IL_0009: newobj instance void DoNotBoxStruct_Array_FSInterface_NoExtMeth/'F@6-1'::.ctor() - IL_000e: ldftn instance void DoNotBoxStruct_Array_FSInterface_NoExtMeth/'F@6-1'::Invoke(object, - int32) - IL_0014: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, + IL_0009: ldnull + IL_000a: ldftn void DoNotBoxStruct_Array_FSInterface_NoExtMeth/F@6::Invoke(object, + int32) + IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, native int) - IL_0019: constrained. !!T - IL_001f: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) - IL_0024: nop - IL_0025: ret + IL_0015: constrained. !!T + IL_001b: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) + IL_0020: nop + IL_0021: ret } // end of method DoNotBoxStruct_Array_FSInterface_NoExtMeth::F } // end of class DoNotBoxStruct_Array_FSInterface_NoExtMeth diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface.il.bsl index c0d5f4ce7db..f2c29723485 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_MDArray_FSInterface { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_MDArray_FSInterface { - // Offset: 0x00000000 Length: 0x00000260 + // Offset: 0x00000000 Length: 0x0000025C } .mresource public FSharpOptimizationData.DoNotBoxStruct_MDArray_FSInterface { - // Offset: 0x00000268 Length: 0x0000009C + // Offset: 0x00000260 Length: 0x0000009C } .module DoNotBoxStruct_MDArray_FSInterface.exe -// MVID: {59B1920A-8279-DA45-A745-03830A92B159} +// MVID: {5FCFFD0B-8279-DA45-A745-03830BFDCF5F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F20000 +// Image base: 0x05A00000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,9 +51,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'F@5-6' + .class auto ansi serializable sealed nested assembly beforefieldinit F@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class DoNotBoxStruct_MDArray_FSInterface/F@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -64,7 +65,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'F@5-6'::.ctor + } // end of method F@5::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(int32 x) cil managed @@ -72,12 +73,22 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 68,70 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_MDArray_FSInterface.fs' + .line 5,5 : 68,70 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_MDArray_FSInterface.fs' IL_0000: ldnull IL_0001: ret - } // end of method 'F@5-6'::Invoke + } // end of method F@5::Invoke - } // end of class 'F@5-6' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void DoNotBoxStruct_MDArray_FSInterface/F@5::.ctor() + IL_0005: stsfld class DoNotBoxStruct_MDArray_FSInterface/F@5 DoNotBoxStruct_MDArray_FSInterface/F@5::@_instance + IL_000a: ret + } // end of method F@5::.cctor + + } // end of class F@5 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[0...,0...] x) cil managed { @@ -91,7 +102,7 @@ int32) IL_0008: box !!T IL_000d: unbox.any class [mscorlib]System.IObservable`1 - IL_0012: newobj instance void DoNotBoxStruct_MDArray_FSInterface/'F@5-6'::.ctor() + IL_0012: ldsfld class DoNotBoxStruct_MDArray_FSInterface/F@5 DoNotBoxStruct_MDArray_FSInterface/F@5::@_instance IL_0017: tail. IL_0019: call void [FSharp.Core]Microsoft.FSharp.Control.CommonExtensions::AddToObservable(class [mscorlib]System.IObservable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.il.bsl index 00d5ffc2e07..5112dc687d5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_MDArray_FSInterface_NoExtMeth { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_MDArray_FSInterface_NoExtMeth { - // Offset: 0x00000000 Length: 0x0000027F + // Offset: 0x00000000 Length: 0x0000027A } .mresource public FSharpOptimizationData.DoNotBoxStruct_MDArray_FSInterface_NoExtMeth { - // Offset: 0x00000288 Length: 0x000000B0 + // Offset: 0x00000280 Length: 0x000000B0 } .module DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.exe -// MVID: {59B1920A-A67D-867A-A745-03830A92B159} +// MVID: {60E47018-A67D-867A-A745-03831870E460} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010C0000 +// Image base: 0x056F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,40 +51,25 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'F@6-2' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname F@6 extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method assembly static void Invoke(object x, + int32 _arg1) cil managed { - // Code size 7 (0x7) + // Code size 1 (0x1) .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'F@6-2'::.ctor - - .method assembly hidebysig instance void - Invoke(object x, - int32 _arg1) cil managed - { - // Code size 3 (0x3) - .maxstack 5 - .locals init ([0] int32 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.fs' - IL_0000: ldarg.2 - IL_0001: stloc.0 - .line 6,6 : 77,79 '' - IL_0002: ret - } // end of method 'F@6-2'::Invoke + .line 6,6 : 77,79 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_MDArray_FSInterface_NoExtMeth.fs' + IL_0000: ret + } // end of method F@6::Invoke - } // end of class 'F@6-2' + } // end of class F@6 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T[0...,0...] x) cil managed { - // Code size 39 (0x27) + // Code size 35 (0x23) .maxstack 8 .line 6,6 : 47,80 '' IL_0000: ldarg.0 @@ -93,15 +78,15 @@ IL_0003: readonly. IL_0005: call instance !!T& !!T[0...,0...]::Address(int32, int32) - IL_000a: newobj instance void DoNotBoxStruct_MDArray_FSInterface_NoExtMeth/'F@6-2'::.ctor() - IL_000f: ldftn instance void DoNotBoxStruct_MDArray_FSInterface_NoExtMeth/'F@6-2'::Invoke(object, - int32) - IL_0015: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, + IL_000a: ldnull + IL_000b: ldftn void DoNotBoxStruct_MDArray_FSInterface_NoExtMeth/F@6::Invoke(object, + int32) + IL_0011: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, native int) - IL_001a: constrained. !!T - IL_0020: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) - IL_0025: nop - IL_0026: ret + IL_0016: constrained. !!T + IL_001c: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) + IL_0021: nop + IL_0022: ret } // end of method DoNotBoxStruct_MDArray_FSInterface_NoExtMeth::F } // end of class DoNotBoxStruct_MDArray_FSInterface_NoExtMeth diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface.il.bsl index 02f0492ad4a..4df05e344dd 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_NoArray_FSInterface { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_NoArray_FSInterface { - // Offset: 0x00000000 Length: 0x00000250 + // Offset: 0x00000000 Length: 0x0000024C } .mresource public FSharpOptimizationData.DoNotBoxStruct_NoArray_FSInterface { - // Offset: 0x00000258 Length: 0x0000009C + // Offset: 0x00000250 Length: 0x0000009C } .module DoNotBoxStruct_NoArray_FSInterface.exe -// MVID: {59B1920A-3F8A-B9D0-A745-03830A92B159} +// MVID: {5FCFFD0B-3F8A-B9D0-A745-03830BFDCF5F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00680000 +// Image base: 0x06AB0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,9 +51,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'F@5-7' + .class auto ansi serializable sealed nested assembly beforefieldinit F@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class DoNotBoxStruct_NoArray_FSInterface/F@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -64,7 +65,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'F@5-7'::.ctor + } // end of method F@5::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(int32 x) cil managed @@ -72,12 +73,22 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 59,61 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_NoArray_FSInterface.fs' + .line 5,5 : 59,61 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_NoArray_FSInterface.fs' IL_0000: ldnull IL_0001: ret - } // end of method 'F@5-7'::Invoke + } // end of method F@5::Invoke - } // end of class 'F@5-7' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void DoNotBoxStruct_NoArray_FSInterface/F@5::.ctor() + IL_0005: stsfld class DoNotBoxStruct_NoArray_FSInterface/F@5 DoNotBoxStruct_NoArray_FSInterface/F@5::@_instance + IL_000a: ret + } // end of method F@5::.cctor + + } // end of class F@5 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T x) cil managed { @@ -87,7 +98,7 @@ IL_0000: ldarg.0 IL_0001: box !!T IL_0006: unbox.any class [mscorlib]System.IObservable`1 - IL_000b: newobj instance void DoNotBoxStruct_NoArray_FSInterface/'F@5-7'::.ctor() + IL_000b: ldsfld class DoNotBoxStruct_NoArray_FSInterface/F@5 DoNotBoxStruct_NoArray_FSInterface/F@5::@_instance IL_0010: tail. IL_0012: call void [FSharp.Core]Microsoft.FSharp.Control.CommonExtensions::AddToObservable(class [mscorlib]System.IObservable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.il.bsl index 92d007fed43..191a24a1018 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/DoNotBoxStruct/DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly DoNotBoxStruct_NoArray_FSInterface_NoExtMeth { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.DoNotBoxStruct_NoArray_FSInterface_NoExtMeth { - // Offset: 0x00000000 Length: 0x0000026F + // Offset: 0x00000000 Length: 0x0000026A } .mresource public FSharpOptimizationData.DoNotBoxStruct_NoArray_FSInterface_NoExtMeth { - // Offset: 0x00000278 Length: 0x000000B0 + // Offset: 0x00000270 Length: 0x000000B0 } .module DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.exe -// MVID: {59B1920A-CD0A-F713-A745-03830A92B159} +// MVID: {60E47018-CD0A-F713-A745-03831870E460} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00720000 +// Image base: 0x06A30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,55 +51,40 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'F@6-3' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname F@6 extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method assembly static void Invoke(object x, + int32 _arg1) cil managed { - // Code size 7 (0x7) + // Code size 1 (0x1) .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'F@6-3'::.ctor - - .method assembly hidebysig instance void - Invoke(object x, - int32 _arg1) cil managed - { - // Code size 3 (0x3) - .maxstack 5 - .locals init ([0] int32 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.fs' - IL_0000: ldarg.2 - IL_0001: stloc.0 - .line 6,6 : 68,70 '' - IL_0002: ret - } // end of method 'F@6-3'::Invoke + .line 6,6 : 68,70 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\DoNotBoxStruct\\DoNotBoxStruct_NoArray_FSInterface_NoExtMeth.fs' + IL_0000: ret + } // end of method F@6::Invoke - } // end of class 'F@6-3' + } // end of class F@6 .method public static void F<(class [FSharp.Core]Microsoft.FSharp.Control.IEvent`2,int32>) T>(!!T x) cil managed { - // Code size 33 (0x21) + // Code size 29 (0x1d) .maxstack 5 .locals init ([0] !!T V_0) .line 6,6 : 44,71 '' IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj instance void DoNotBoxStruct_NoArray_FSInterface_NoExtMeth/'F@6-3'::.ctor() - IL_0009: ldftn instance void DoNotBoxStruct_NoArray_FSInterface_NoExtMeth/'F@6-3'::Invoke(object, - int32) - IL_000f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, + IL_0004: ldnull + IL_0005: ldftn void DoNotBoxStruct_NoArray_FSInterface_NoExtMeth/F@6::Invoke(object, + int32) + IL_000b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Control.FSharpHandler`1::.ctor(object, native int) - IL_0014: constrained. !!T - IL_001a: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) - IL_001f: nop - IL_0020: ret + IL_0010: constrained. !!T + IL_0016: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Control.IDelegateEvent`1>::AddHandler(!0) + IL_001b: nop + IL_001c: ret } // end of method DoNotBoxStruct_NoArray_FSInterface_NoExtMeth::F } // end of class DoNotBoxStruct_NoArray_FSInterface_NoExtMeth diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter01.il.bsl index 601e4ffc1e7..a3ec1e93096 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly GenIter01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GenIter01 { - // Offset: 0x00000000 Length: 0x000001FF + // Offset: 0x00000000 Length: 0x000001F3 } .mresource public FSharpOptimizationData.GenIter01 { - // Offset: 0x00000208 Length: 0x0000007A + // Offset: 0x000001F8 Length: 0x0000007A } .module GenIter01.exe -// MVID: {5B9A6329-F836-DC98-A745-038329639A5B} +// MVID: {611C4D7C-F836-DC98-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x06D20000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,355 +51,76 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname squaresOfOneToTen@5 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + squaresOfOneToTen() cil managed { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum' - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum', - int32 pc, - int32 current) cil managed + // Code size 78 (0x4e) + .maxstack 5 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1, + [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_2, + [3] int32 x, + [4] class [mscorlib]System.IDisposable V_4) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 5,6 : 5,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter01.fs' + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.2 + IL_0003: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.1 + .line 5,5 : 7,26 '' + .try { - // Code size 28 (0x1c) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 GenIter01/squaresOfOneToTen@5::current - IL_0015: ldarg.0 - IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_001b: ret - } // end of method squaresOfOneToTen@5::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 157 (0x9d) - .maxstack 8 - .locals init ([0] int32 x) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter01.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0073 + IL_000e: ldloc.1 + IL_000f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0014: brfalse.s IL_002b - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0070 - - .line 100001,100001 : 0,0 '' + IL_0016: ldloc.1 + IL_0017: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001c: stloc.3 + .line 6,6 : 18,23 '' + IL_001d: ldloca.s V_0 + IL_001f: ldloc.3 + IL_0020: ldloc.3 + IL_0021: mul + IL_0022: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) IL_0027: nop - IL_0028: br.s IL_0094 - .line 100001,100001 : 0,0 '' - IL_002a: nop - .line 5,6 : 7,23 '' - IL_002b: ldarg.0 - IL_002c: ldc.i4.0 - IL_002d: ldc.i4.1 - IL_002e: ldc.i4.2 - IL_002f: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0034: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0039: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_003e: ldarg.0 - IL_003f: ldc.i4.1 - IL_0040: stfld int32 GenIter01/squaresOfOneToTen@5::pc - .line 5,6 : 7,23 '' - IL_0045: ldarg.0 - IL_0046: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_004b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0050: brfalse.s IL_0073 - - IL_0052: ldarg.0 - IL_0053: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_0058: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005d: stloc.0 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 GenIter01/squaresOfOneToTen@5::pc - .line 6,6 : 18,23 '' - IL_0065: ldarg.0 - IL_0066: ldloc.0 - IL_0067: ldloc.0 - IL_0068: mul - IL_0069: stfld int32 GenIter01/squaresOfOneToTen@5::current - IL_006e: ldc.i4.1 - IL_006f: ret + IL_0028: nop + IL_0029: br.s IL_000e - .line 100001,100001 : 0,0 '' - IL_0070: nop - IL_0071: br.s IL_0045 + IL_002b: ldnull + IL_002c: stloc.2 + IL_002d: leave.s IL_0044 - IL_0073: ldarg.0 - IL_0074: ldc.i4.3 - IL_0075: stfld int32 GenIter01/squaresOfOneToTen@5::pc .line 5,6 : 7,23 '' - IL_007a: ldarg.0 - IL_007b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_0080: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0085: nop - IL_0086: ldarg.0 - IL_0087: ldnull - IL_0088: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_008d: ldarg.0 - IL_008e: ldc.i4.3 - IL_008f: stfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0094: ldarg.0 - IL_0095: ldc.i4.0 - IL_0096: stfld int32 GenIter01/squaresOfOneToTen@5::current - IL_009b: ldc.i4.0 - IL_009c: ret - } // end of method squaresOfOneToTen@5::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 148 (0x94) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0006: ldc.i4.3 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_0087 - - .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0020: switch ( - IL_0037, - IL_0039, - IL_003b, - IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d - - .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c - - .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_004b: nop - .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter01/squaresOfOneToTen@5::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop - .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 GenIter01/squaresOfOneToTen@5::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f - - } // end .try - catch [mscorlib]System.Object - { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 - .line 5,6 : 7,23 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f - - .line 100001,100001 : 0,0 '' - } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 - - .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw - - .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method squaresOfOneToTen@5::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed + } // end .try + finally { - // Code size 56 (0x38) - .maxstack 8 + IL_002f: ldloc.1 + IL_0030: isinst [mscorlib]System.IDisposable + IL_0035: stloc.s V_4 .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter01/squaresOfOneToTen@5::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0037: ldloc.s V_4 + IL_0039: brfalse.s IL_0043 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 - + IL_003b: ldloc.s V_4 + IL_003d: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0042: endfinally .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 - + IL_0043: endfinally .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret - - IL_0034: ldc.i4.1 - IL_0035: ret - - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method squaresOfOneToTen@5::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter01/squaresOfOneToTen@5::current - IL_0006: ret - } // end of method squaresOfOneToTen@5::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 9 (0x9) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter01/squaresOfOneToTen@5::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: ret - } // end of method squaresOfOneToTen@5::GetFreshEnumerator - - } // end of class squaresOfOneToTen@5 - - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTen() cil managed - { - // Code size 16 (0x10) - .maxstack 8 + } // end handler + IL_0044: ldloc.2 + IL_0045: pop .line 5,6 : 5,25 '' - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter01/squaresOfOneToTen@5::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: tail. - IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000f: ret + IL_0046: ldloca.s V_0 + IL_0048: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_004d: ret } // end of method GenIter01::squaresOfOneToTen } // end of class GenIter01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter02.il.bsl index aa203793fe4..2874e0e1be7 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly GenIter02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GenIter02 { - // Offset: 0x00000000 Length: 0x00000200 + // Offset: 0x00000000 Length: 0x000001F4 } .mresource public FSharpOptimizationData.GenIter02 { - // Offset: 0x00000208 Length: 0x0000007B + // Offset: 0x000001F8 Length: 0x0000007B } .module GenIter02.exe -// MVID: {5B9A6329-F857-DC98-A745-038329639A5B} +// MVID: {611C4D7C-F857-DC98-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02900000 +// Image base: 0x070F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,360 +51,81 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname squaresOfOneToTenB@5 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + squaresOfOneToTenB() cil managed { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum' - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum', - int32 pc, - int32 current) cil managed + // Code size 94 (0x5e) + .maxstack 5 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1, + [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_2, + [3] int32 x, + [4] class [mscorlib]System.IDisposable V_4) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 5,7 : 5,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter02.fs' + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.2 + IL_0003: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0008: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000d: stloc.1 + .line 5,5 : 7,25 '' + .try { - // Code size 28 (0x1c) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 GenIter02/squaresOfOneToTenB@5::current - IL_0015: ldarg.0 - IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_001b: ret - } // end of method squaresOfOneToTenB@5::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 176 (0xb0) - .maxstack 8 - .locals init ([0] int32 x) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter02.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0086 - - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0083 - - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00a7 - - .line 100001,100001 : 0,0 '' - IL_002d: nop - .line 5,7 : 7,23 '' - IL_002e: ldarg.0 - IL_002f: ldc.i4.0 - IL_0030: ldc.i4.1 - IL_0031: ldc.i4.2 - IL_0032: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0037: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_003c: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_0041: ldarg.0 - IL_0042: ldc.i4.1 - IL_0043: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - .line 5,7 : 7,23 '' - IL_0048: ldarg.0 - IL_0049: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_004e: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0053: brfalse.s IL_0086 + IL_000e: ldloc.1 + IL_000f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0014: brfalse.s IL_003b - IL_0055: ldarg.0 - IL_0056: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_005b: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0060: stloc.0 + IL_0016: ldloc.1 + IL_0017: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001c: stloc.3 .line 6,6 : 12,27 '' - IL_0061: ldstr "hello" - IL_0066: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_006b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0070: pop - IL_0071: ldarg.0 - IL_0072: ldc.i4.2 - IL_0073: stfld int32 GenIter02/squaresOfOneToTenB@5::pc + IL_001d: ldstr "hello" + IL_0022: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0027: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002c: pop .line 7,7 : 12,23 '' - IL_0078: ldarg.0 - IL_0079: ldloc.0 - IL_007a: ldloc.0 - IL_007b: mul - IL_007c: stfld int32 GenIter02/squaresOfOneToTenB@5::current - IL_0081: ldc.i4.1 - IL_0082: ret - - .line 100001,100001 : 0,0 '' - IL_0083: nop - IL_0084: br.s IL_0048 - - IL_0086: ldarg.0 - IL_0087: ldc.i4.3 - IL_0088: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - .line 5,7 : 7,23 '' - IL_008d: ldarg.0 - IL_008e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_0093: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0098: nop - IL_0099: ldarg.0 - IL_009a: ldnull - IL_009b: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_00a0: ldarg.0 - IL_00a1: ldc.i4.3 - IL_00a2: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_00a7: ldarg.0 - IL_00a8: ldc.i4.0 - IL_00a9: stfld int32 GenIter02/squaresOfOneToTenB@5::current - IL_00ae: ldc.i4.0 - IL_00af: ret - } // end of method squaresOfOneToTenB@5::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 148 (0x94) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0006: ldc.i4.3 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_0087 - - .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0020: switch ( - IL_0037, - IL_0039, - IL_003b, - IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d - - .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c - - .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_004b: nop - .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter02/squaresOfOneToTenB@5::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop - .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 GenIter02/squaresOfOneToTenB@5::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f - - } // end .try - catch [mscorlib]System.Object - { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 - .line 5,7 : 7,23 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f - - .line 100001,100001 : 0,0 '' - } // end handler - IL_007f: ldloc.1 - IL_0080: pop + IL_002d: ldloca.s V_0 + IL_002f: ldloc.3 + IL_0030: ldloc.3 + IL_0031: mul + IL_0032: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0037: nop .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0038: nop + IL_0039: br.s IL_000e - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 - - .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_003b: ldnull + IL_003c: stloc.2 + IL_003d: leave.s IL_0054 - .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method squaresOfOneToTenB@5::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed + .line 5,7 : 7,23 '' + } // end .try + finally { - // Code size 56 (0x38) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter02/squaresOfOneToTenB@5::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - + IL_003f: ldloc.1 + IL_0040: isinst [mscorlib]System.IDisposable + IL_0045: stloc.s V_4 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_0047: ldloc.s V_4 + IL_0049: brfalse.s IL_0053 .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 - + IL_004b: ldloc.s V_4 + IL_004d: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0052: endfinally .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 - + IL_0053: endfinally .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret - - IL_0034: ldc.i4.1 - IL_0035: ret - - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method squaresOfOneToTenB@5::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter02/squaresOfOneToTenB@5::current - IL_0006: ret - } // end of method squaresOfOneToTenB@5::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 9 (0x9) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter02/squaresOfOneToTenB@5::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: ret - } // end of method squaresOfOneToTenB@5::GetFreshEnumerator - - } // end of class squaresOfOneToTenB@5 - - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTenB() cil managed - { - // Code size 16 (0x10) - .maxstack 8 + } // end handler + IL_0054: ldloc.2 + IL_0055: pop .line 5,7 : 5,25 '' - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter02/squaresOfOneToTenB@5::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: tail. - IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000f: ret + IL_0056: ldloca.s V_0 + IL_0058: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_005d: ret } // end of method GenIter02::squaresOfOneToTenB } // end of class GenIter02 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter03.il.bsl index 88bd760bc85..6e06141da8b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly GenIter03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GenIter03 { - // Offset: 0x00000000 Length: 0x00000200 + // Offset: 0x00000000 Length: 0x000001F4 } .mresource public FSharpOptimizationData.GenIter03 { - // Offset: 0x00000208 Length: 0x0000007B + // Offset: 0x000001F8 Length: 0x0000007B } .module GenIter03.exe -// MVID: {5B9A6329-F77C-DC98-A745-038329639A5B} +// MVID: {611C4D7C-F77C-DC98-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026B0000 +// Image base: 0x06DC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,355 +51,76 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname squaresOfOneToTenC@4 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + squaresOfOneToTenC() cil managed { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum' - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum', - int32 pc, - int32 current) cil managed + // Code size 79 (0x4f) + .maxstack 5 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1, + [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_2, + [3] int32 x, + [4] class [mscorlib]System.IDisposable V_4) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 4,4 : 28,57 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter03.fs' + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.s 10 + IL_0004: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0009: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000e: stloc.1 + .line 4,4 : 30,46 '' + .try { - // Code size 28 (0x1c) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 GenIter03/squaresOfOneToTenC@4::current - IL_0015: ldarg.0 - IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_001b: ret - } // end of method squaresOfOneToTenC@4::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 158 (0x9e) - .maxstack 8 - .locals init ([0] int32 x) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter03.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0074 + IL_000f: ldloc.1 + IL_0010: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0015: brfalse.s IL_002c - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0071 - - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0095 - - .line 100001,100001 : 0,0 '' - IL_002a: nop - .line 4,4 : 30,55 '' - IL_002b: ldarg.0 - IL_002c: ldc.i4.0 - IL_002d: ldc.i4.1 - IL_002e: ldc.i4.s 10 - IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_003f: ldarg.0 - IL_0040: ldc.i4.1 - IL_0041: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - .line 4,4 : 30,55 '' - IL_0046: ldarg.0 - IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0051: brfalse.s IL_0074 - - IL_0053: ldarg.0 - IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005e: stloc.0 - IL_005f: ldarg.0 - IL_0060: ldc.i4.2 - IL_0061: stfld int32 GenIter03/squaresOfOneToTenC@4::pc + IL_0017: ldloc.1 + IL_0018: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001d: stloc.3 .line 4,4 : 50,55 '' - IL_0066: ldarg.0 - IL_0067: ldloc.0 - IL_0068: ldloc.0 - IL_0069: mul - IL_006a: stfld int32 GenIter03/squaresOfOneToTenC@4::current - IL_006f: ldc.i4.1 - IL_0070: ret - - .line 100001,100001 : 0,0 '' - IL_0071: nop - IL_0072: br.s IL_0046 - - IL_0074: ldarg.0 - IL_0075: ldc.i4.3 - IL_0076: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - .line 4,4 : 30,55 '' - IL_007b: ldarg.0 - IL_007c: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_0081: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0086: nop - IL_0087: ldarg.0 - IL_0088: ldnull - IL_0089: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_008e: ldarg.0 - IL_008f: ldc.i4.3 - IL_0090: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0095: ldarg.0 - IL_0096: ldc.i4.0 - IL_0097: stfld int32 GenIter03/squaresOfOneToTenC@4::current - IL_009c: ldc.i4.0 - IL_009d: ret - } // end of method squaresOfOneToTenC@4::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 148 (0x94) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0006: ldc.i4.3 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_0087 - - .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0020: switch ( - IL_0037, - IL_0039, - IL_003b, - IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d - - .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c - - .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_004b: nop - .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter03/squaresOfOneToTenC@4::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop - .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 GenIter03/squaresOfOneToTenC@4::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f - - } // end .try - catch [mscorlib]System.Object - { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 - .line 4,4 : 30,55 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f - - .line 100001,100001 : 0,0 '' - } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 - + IL_001e: ldloca.s V_0 + IL_0020: ldloc.3 + IL_0021: ldloc.3 + IL_0022: mul + IL_0023: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0028: nop .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_0029: nop + IL_002a: br.s IL_000f - .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method squaresOfOneToTenC@4::Close + IL_002c: ldnull + IL_002d: stloc.2 + IL_002e: leave.s IL_0045 - .method public strict virtual instance bool - get_CheckClose() cil managed + .line 4,4 : 30,55 '' + } // end .try + finally { - // Code size 56 (0x38) - .maxstack 8 + IL_0030: ldloc.1 + IL_0031: isinst [mscorlib]System.IDisposable + IL_0036: stloc.s V_4 .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter03/squaresOfOneToTenC@4::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0038: ldloc.s V_4 + IL_003a: brfalse.s IL_0044 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 - + IL_003c: ldloc.s V_4 + IL_003e: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0043: endfinally .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 - + IL_0044: endfinally .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret - - IL_0034: ldc.i4.1 - IL_0035: ret - - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method squaresOfOneToTenC@4::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter03/squaresOfOneToTenC@4::current - IL_0006: ret - } // end of method squaresOfOneToTenC@4::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 9 (0x9) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter03/squaresOfOneToTenC@4::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: ret - } // end of method squaresOfOneToTenC@4::GetFreshEnumerator - - } // end of class squaresOfOneToTenC@4 - - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - squaresOfOneToTenC() cil managed - { - // Code size 16 (0x10) - .maxstack 8 + } // end handler + IL_0045: ldloc.2 + IL_0046: pop .line 4,4 : 28,57 '' - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter03/squaresOfOneToTenC@4::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: tail. - IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000f: ret + IL_0047: ldloca.s V_0 + IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_004e: ret } // end of method GenIter03::squaresOfOneToTenC } // end of class GenIter03 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter04.il.bsl index 25a08dfd652..ba6e8bc9d3d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/GeneratedIterators/GenIter04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly GenIter04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GenIter04 { - // Offset: 0x00000000 Length: 0x000001F0 + // Offset: 0x00000000 Length: 0x000001E4 } .mresource public FSharpOptimizationData.GenIter04 { - // Offset: 0x000001F8 Length: 0x0000007B + // Offset: 0x000001E8 Length: 0x0000007B } .module GenIter04.exe -// MVID: {5B9A6329-F79D-DC98-A745-038329639A5B} +// MVID: {611C4D7C-F79D-DC98-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00790000 +// Image base: 0x06650000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,340 +51,6 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname squaresOfOneToTenD@4 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum' - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum', - int32 pc, - int32 current) cil managed - { - // Code size 28 (0x1c) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 GenIter04/squaresOfOneToTenD@4::current - IL_0015: ldarg.0 - IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_001b: ret - } // end of method squaresOfOneToTenD@4::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 158 (0x9e) - .maxstack 8 - .locals init ([0] int32 x) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter04.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0074 - - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0071 - - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0095 - - .line 100001,100001 : 0,0 '' - IL_002a: nop - .line 4,4 : 28,53 '' - IL_002b: ldarg.0 - IL_002c: ldc.i4.0 - IL_002d: ldc.i4.1 - IL_002e: ldc.i4.s 10 - IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, - int32, - int32) - IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_003f: ldarg.0 - IL_0040: ldc.i4.1 - IL_0041: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - .line 4,4 : 28,53 '' - IL_0046: ldarg.0 - IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0051: brfalse.s IL_0074 - - IL_0053: ldarg.0 - IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005e: stloc.0 - IL_005f: ldarg.0 - IL_0060: ldc.i4.2 - IL_0061: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - .line 4,4 : 48,53 '' - IL_0066: ldarg.0 - IL_0067: ldloc.0 - IL_0068: ldloc.0 - IL_0069: mul - IL_006a: stfld int32 GenIter04/squaresOfOneToTenD@4::current - IL_006f: ldc.i4.1 - IL_0070: ret - - .line 100001,100001 : 0,0 '' - IL_0071: nop - IL_0072: br.s IL_0046 - - IL_0074: ldarg.0 - IL_0075: ldc.i4.3 - IL_0076: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - .line 4,4 : 28,53 '' - IL_007b: ldarg.0 - IL_007c: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_0081: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0086: nop - IL_0087: ldarg.0 - IL_0088: ldnull - IL_0089: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_008e: ldarg.0 - IL_008f: ldc.i4.3 - IL_0090: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0095: ldarg.0 - IL_0096: ldc.i4.0 - IL_0097: stfld int32 GenIter04/squaresOfOneToTenD@4::current - IL_009c: ldc.i4.0 - IL_009d: ret - } // end of method squaresOfOneToTenD@4::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 148 (0x94) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0006: ldc.i4.3 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_0087 - - .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0020: switch ( - IL_0037, - IL_0039, - IL_003b, - IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d - - .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c - - .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_004b: nop - .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 GenIter04/squaresOfOneToTenD@4::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop - .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 GenIter04/squaresOfOneToTenD@4::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f - - } // end .try - catch [mscorlib]System.Object - { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 - .line 4,4 : 28,53 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f - - .line 100001,100001 : 0,0 '' - } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 - - .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw - - .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method squaresOfOneToTenD@4::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 56 (0x38) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter04/squaresOfOneToTenD@4::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 - - .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 - - .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret - - IL_0034: ldc.i4.1 - IL_0035: ret - - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method squaresOfOneToTenD@4::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 GenIter04/squaresOfOneToTenD@4::current - IL_0006: ret - } // end of method squaresOfOneToTenD@4::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 9 (0x9) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter04/squaresOfOneToTenD@4::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: ret - } // end of method squaresOfOneToTenD@4::GetFreshEnumerator - - } // end of class squaresOfOneToTenD@4 - .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_squaresOfOneToTenD() cil managed { @@ -414,21 +80,76 @@ .method public static void main@() cil managed { .entrypoint - // Code size 21 (0x15) + // Code size 89 (0x59) .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 squaresOfOneToTenD) - .line 4,4 : 1,55 '' - IL_0000: ldnull - IL_0001: ldc.i4.0 - IL_0002: ldc.i4.0 - IL_0003: newobj instance void GenIter04/squaresOfOneToTenD@4::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0008: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000d: dup - IL_000e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$GenIter04::squaresOfOneToTenD@4 - IL_0013: stloc.0 - IL_0014: ret + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 squaresOfOneToTenD, + [1] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_1, + [2] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_2, + [3] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_3, + [4] int32 x, + [5] class [mscorlib]System.IDisposable V_5) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 4,4 : 1,55 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\GeneratedIterators\\GenIter04.fs' + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.s 10 + IL_0004: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0009: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000e: stloc.2 + .line 4,4 : 28,44 '' + .try + { + IL_000f: ldloc.2 + IL_0010: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0015: brfalse.s IL_002f + + IL_0017: ldloc.2 + IL_0018: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_001d: stloc.s x + .line 4,4 : 48,53 '' + IL_001f: ldloca.s V_1 + IL_0021: ldloc.s x + IL_0023: ldloc.s x + IL_0025: mul + IL_0026: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002b: nop + .line 100001,100001 : 0,0 '' + IL_002c: nop + IL_002d: br.s IL_000f + + IL_002f: ldnull + IL_0030: stloc.3 + IL_0031: leave.s IL_0048 + + .line 4,4 : 28,53 '' + } // end .try + finally + { + IL_0033: ldloc.2 + IL_0034: isinst [mscorlib]System.IDisposable + IL_0039: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_003b: ldloc.s V_5 + IL_003d: brfalse.s IL_0047 + + .line 100001,100001 : 0,0 '' + IL_003f: ldloc.s V_5 + IL_0041: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_0046: endfinally + .line 100001,100001 : 0,0 '' + IL_0047: endfinally + .line 100001,100001 : 0,0 '' + } // end handler + IL_0048: ldloc.3 + IL_0049: pop + IL_004a: ldloca.s V_1 + IL_004c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0051: dup + IL_0052: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$GenIter04::squaresOfOneToTenD@4 + IL_0057: stloc.0 + IL_0058: ret } // end of method $GenIter04::main@ } // end of class ''.$GenIter04 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison01.il.bsl index 37c0b51c0e3..bc1449351fd 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly InequalityComparison01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.InequalityComparison01 { - // Offset: 0x00000000 Length: 0x0000020E + // Offset: 0x00000000 Length: 0x0000020A } .mresource public FSharpOptimizationData.InequalityComparison01 { - // Offset: 0x00000218 Length: 0x00000085 + // Offset: 0x00000210 Length: 0x00000085 } .module InequalityComparison01.exe -// MVID: {59B19213-263A-E6D5-A745-03831392B159} +// MVID: {60B68B7E-263A-E6D5-A745-03837E8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x074E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ // Code size 8 (0x8) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 27,33 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison01.fs' + .line 3,3 : 27,33 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison01.fs' IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: cgt diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison02.il.bsl index 6ce221af23c..ca23c28d8a2 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly InequalityComparison02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.InequalityComparison02 { - // Offset: 0x00000000 Length: 0x0000020E + // Offset: 0x00000000 Length: 0x0000020A } .mresource public FSharpOptimizationData.InequalityComparison02 { - // Offset: 0x00000218 Length: 0x00000085 + // Offset: 0x00000210 Length: 0x00000085 } .module InequalityComparison02.exe -// MVID: {59B19213-263A-E72C-A745-03831392B159} +// MVID: {60B68B7E-263A-E72C-A745-03837E8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02D40000 +// Image base: 0x07180000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ // Code size 8 (0x8) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 27,33 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison02.fs' + .line 3,3 : 27,33 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison02.fs' IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: clt diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison03.il.bsl index 96a9c5591cc..4fd361bb957 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly InequalityComparison03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.InequalityComparison03 { - // Offset: 0x00000000 Length: 0x0000020E + // Offset: 0x00000000 Length: 0x0000020A } .mresource public FSharpOptimizationData.InequalityComparison03 { - // Offset: 0x00000218 Length: 0x00000085 + // Offset: 0x00000210 Length: 0x00000085 } .module InequalityComparison03.exe -// MVID: {59B19213-263A-E70B-A745-03831392B159} +// MVID: {60B68B7E-263A-E70B-A745-03837E8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x008E0000 +// Image base: 0x06510000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ // Code size 5 (0x5) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 27,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison03.fs' + .line 3,3 : 27,32 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison03.fs' IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: clt diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison04.il.bsl index 5209536406c..988eae50727 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly InequalityComparison04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.InequalityComparison04 { - // Offset: 0x00000000 Length: 0x0000020E + // Offset: 0x00000000 Length: 0x0000020A } .mresource public FSharpOptimizationData.InequalityComparison04 { - // Offset: 0x00000218 Length: 0x00000085 + // Offset: 0x00000210 Length: 0x00000085 } .module InequalityComparison04.exe -// MVID: {59B19213-263A-E772-A745-03831392B159} +// MVID: {60B68B7E-263A-E772-A745-03837E8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F20000 +// Image base: 0x07590000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ // Code size 5 (0x5) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 27,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison04.fs' + .line 3,3 : 27,32 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison04.fs' IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: cgt diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison05.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison05.il.bsl index 173552b2fa4..d8b995dda8c 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison05.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/InequalityComparison/InequalityComparison05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly InequalityComparison05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.InequalityComparison05 { - // Offset: 0x00000000 Length: 0x00000236 + // Offset: 0x00000000 Length: 0x00000232 } .mresource public FSharpOptimizationData.InequalityComparison05 { - // Offset: 0x00000240 Length: 0x00000085 + // Offset: 0x00000238 Length: 0x00000085 } .module InequalityComparison05.exe -// MVID: {59B19213-263A-E751-A745-03831392B159} +// MVID: {611C4D7C-263A-E751-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x001D0000 +// Image base: 0x06C10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,25 +58,23 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 04 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 12 (0xc) + // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 40,55 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison05.fs' - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: ble.s IL_0006 - - IL_0004: br.s IL_0008 - - IL_0006: br.s IL_000a + .line 3,3 : 40,55 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\InequalityComparison\\InequalityComparison05.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: ble.s IL_0007 .line 3,3 : 56,57 '' - IL_0008: ldarg.2 - IL_0009: ret + IL_0005: ldarg.2 + IL_0006: ret .line 3,3 : 63,64 '' - IL_000a: ldarg.3 - IL_000b: ret + IL_0007: ldarg.3 + IL_0008: ret } // end of method InequalityComparison05::f5 } // end of class InequalityComparison05 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest1.il.bsl index 831514e5f3c..0ee5384e72f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest1.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest1 { - // Offset: 0x00000000 Length: 0x0000026D + // Offset: 0x00000000 Length: 0x00000269 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest1 { - // Offset: 0x00000278 Length: 0x000000AF + // Offset: 0x00000270 Length: 0x000000AF } .module ListExpressionSteppingTest1.exe -// MVID: {59B1920C-50CF-F6CE-A745-03830C92B159} +// MVID: {60B78A57-50CF-F6CE-A745-0383578AB760} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x030B0000 +// Image base: 0x07190000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,178 +55,22 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f0@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(int32 pc, - int32 current) cil managed - { - // Code size 21 (0x15) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::current - IL_000e: ldarg.0 - IL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0014: ret - } // end of method f0@6::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 66 (0x42) - .maxstack 6 - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest1.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_0017, - IL_0019) - IL_0015: br.s IL_0021 - - IL_0017: br.s IL_001b - - IL_0019: br.s IL_001e - - .line 100001,100001 : 0,0 '' - IL_001b: nop - IL_001c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_001e: nop - IL_001f: br.s IL_0039 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: ldarg.0 - IL_0023: ldc.i4.1 - IL_0024: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - .line 6,6 : 11,18 '' - IL_0029: ldarg.0 - IL_002a: ldc.i4.1 - IL_002b: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::current - IL_0030: ldc.i4.1 - IL_0031: ret - - IL_0032: ldarg.0 - IL_0033: ldc.i4.2 - IL_0034: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - IL_0039: ldarg.0 - IL_003a: ldc.i4.0 - IL_003b: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::current - IL_0040: ldc.i4.0 - IL_0041: ret - } // end of method f0@6::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldc.i4.2 - IL_0002: stfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - IL_0007: ret - } // end of method f0@6::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 45 (0x2d) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::pc - IL_0006: switch ( - IL_0019, - IL_001b, - IL_001d) - IL_0017: br.s IL_0028 - - IL_0019: br.s IL_001f - - IL_001b: br.s IL_0022 - - IL_001d: br.s IL_0025 - - .line 100001,100001 : 0,0 '' - IL_001f: nop - IL_0020: br.s IL_002b - - .line 100001,100001 : 0,0 '' - IL_0022: nop - IL_0023: br.s IL_0029 - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002b - - .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: ldc.i4.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method f0@6::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::current - IL_0006: ret - } // end of method f0@6::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldc.i4.0 - IL_0001: ldc.i4.0 - IL_0002: newobj instance void ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::.ctor(int32, - int32) - IL_0007: ret - } // end of method f0@6::GetFreshEnumerator - - } // end of class f0@6 - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f0() cil managed { - // Code size 15 (0xf) - .maxstack 8 + // Code size 17 (0x11) + .maxstack 4 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 6,6 : 9,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest1.fs' + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0008: nop .line 6,6 : 9,20 '' - IL_0000: ldc.i4.0 - IL_0001: ldc.i4.0 - IL_0002: newobj instance void ListExpressionSteppingTest1/ListExpressionSteppingTest1/f0@6::.ctor(int32, - int32) - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000e: ret + IL_0009: ldloca.s V_0 + IL_000b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0010: ret } // end of method ListExpressionSteppingTest1::f0 } // end of class ListExpressionSteppingTest1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.fs b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.fs index 85178bf4e0b..b8bc07e5119 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.fs +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.fs @@ -9,3 +9,22 @@ module ListExpressionSteppingTest2 = yield 2] let _ = f1() + + // Test debug point generation for ||> and |||> + let f2 x = + let xs1 = + ([x;x;x], [0..2]) + ||> List.zip + |> List.map (fun (a,b) -> a, b+1) + |> List.map (fun (a,b) -> a, b+1) + + let xs2 = + ([x;x;x], [0..2], [0..2]) + |||> List.zip3 + |> List.map (fun (a,b,c) -> a, b+1, c) + |> List.map (fun (a,b,c) -> a, b+1, c) + + xs1, xs2 + + let _ = f2 5 + diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.il.bsl index 2b86c1c4ba1..5676d0a6476 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest2.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest2 { - // Offset: 0x00000000 Length: 0x0000026D + // Offset: 0x00000000 Length: 0x000002C8 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest2 { - // Offset: 0x00000278 Length: 0x000000AF + // Offset: 0x000002D0 Length: 0x000000BC } .module ListExpressionSteppingTest2.exe -// MVID: {59B1920C-D3DE-B780-A745-03830C92B159} +// MVID: {611C4D7C-D3DE-B780-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00690000 +// Image base: 0x06F60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,217 +55,381 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f1@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 stage #2 at line 18@18' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(int32 pc, - int32 current) cil managed + .field static assembly initonly class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18' @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed { - // Code size 21 (0x15) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::current - IL_000e: ldarg.0 - IL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0014: ret - } // end of method f1@6::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() + IL_0006: ret + } // end of method 'Pipe #1 stage #2 at line 18@18'::.ctor + + .method public strict virtual instance class [mscorlib]System.Tuple`2 + Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed { - // Code size 123 (0x7b) - .maxstack 6 + // Code size 24 (0x18) + .maxstack 7 + .locals init ([0] !a a, + [1] int32 b) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest2.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_004b + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest2.fs' + IL_0000: ldarg.1 + IL_0001: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0006: stloc.0 + IL_0007: ldarg.1 + IL_0008: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_000d: stloc.1 + .line 18,18 : 38,44 '' + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldc.i4.1 + IL_0011: add + IL_0012: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + !1) + IL_0017: ret + } // end of method 'Pipe #1 stage #2 at line 18@18'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18'::.ctor() + IL_0005: stsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18' class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 stage #2 at line 18@18'::.cctor - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006b + } // end of class 'Pipe #1 stage #2 at line 18@18' - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0072 - - .line 100001,100001 : 0,0 '' - IL_002a: nop - .line 6,6 : 11,26 '' - IL_002b: ldstr "hello" - IL_0030: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0035: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_003a: pop - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - .line 7,7 : 11,18 '' - IL_0042: ldarg.0 - IL_0043: ldc.i4.1 - IL_0044: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::current - IL_0049: ldc.i4.1 - IL_004a: ret - - .line 8,8 : 11,28 '' - IL_004b: ldstr "goodbye" - IL_0050: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0055: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_005a: pop - IL_005b: ldarg.0 - IL_005c: ldc.i4.2 - IL_005d: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - .line 9,9 : 11,18 '' - IL_0062: ldarg.0 - IL_0063: ldc.i4.2 - IL_0064: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::current - IL_0069: ldc.i4.1 - IL_006a: ret - - IL_006b: ldarg.0 - IL_006c: ldc.i4.3 - IL_006d: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - IL_0072: ldarg.0 - IL_0073: ldc.i4.0 - IL_0074: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::current - IL_0079: ldc.i4.0 - IL_007a: ret - } // end of method f1@6::GenerateNext - - .method public strict virtual instance void - Close() cil managed + .class auto ansi serializable sealed nested assembly beforefieldinit xs1@19 + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> + { + .field static assembly initonly class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19 @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed { - // Code size 8 (0x8) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldc.i4.3 - IL_0002: stfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - IL_0007: ret - } // end of method f1@6::Close + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() + IL_0006: ret + } // end of method xs1@19::.ctor - .method public strict virtual instance bool - get_CheckClose() cil managed + .method public strict virtual instance class [mscorlib]System.Tuple`2 + Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed { - // Code size 56 (0x38) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 - + // Code size 24 (0x18) + .maxstack 7 + .locals init ([0] !a a, + [1] int32 b) .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0000: ldarg.1 + IL_0001: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0006: stloc.0 + IL_0007: ldarg.1 + IL_0008: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_000d: stloc.1 + .line 19,19 : 38,44 '' + IL_000e: ldloc.0 + IL_000f: ldloc.1 + IL_0010: ldc.i4.1 + IL_0011: add + IL_0012: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + !1) + IL_0017: ret + } // end of method xs1@19::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19::.ctor() + IL_0005: stsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19 class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19::@_instance + IL_000a: ret + } // end of method xs1@19::.cctor - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + } // end of class xs1@19 - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 stage #2 at line 24@24' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> + { + .field static assembly initonly class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24' @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() + IL_0006: ret + } // end of method 'Pipe #2 stage #2 at line 24@24'::.ctor + .method public strict virtual instance class [mscorlib]System.Tuple`3 + Invoke(class [mscorlib]System.Tuple`3 tupledArg) cil managed + { + // Code size 32 (0x20) + .maxstack 7 + .locals init ([0] !a a, + [1] int32 b, + [2] int32 c) .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret - - IL_0034: ldc.i4.0 - IL_0035: ret + IL_0000: ldarg.1 + IL_0001: call instance !0 class [mscorlib]System.Tuple`3::get_Item1() + IL_0006: stloc.0 + IL_0007: ldarg.1 + IL_0008: call instance !1 class [mscorlib]System.Tuple`3::get_Item2() + IL_000d: stloc.1 + IL_000e: ldarg.1 + IL_000f: call instance !2 class [mscorlib]System.Tuple`3::get_Item3() + IL_0014: stloc.2 + .line 24,24 : 40,49 '' + IL_0015: ldloc.0 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: add + IL_0019: ldloc.2 + IL_001a: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_001f: ret + } // end of method 'Pipe #2 stage #2 at line 24@24'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24'::.ctor() + IL_0005: stsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24' class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 stage #2 at line 24@24'::.cctor - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method f1@6::get_CheckClose + } // end of class 'Pipe #2 stage #2 at line 24@24' - .method public strict virtual instance int32 - get_LastGenerated() cil managed + .class auto ansi serializable sealed nested assembly beforefieldinit xs2@25 + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> + { + .field static assembly initonly class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25 @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::current + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() IL_0006: ret - } // end of method f1@6::get_LastGenerated + } // end of method xs2@25::.ctor - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed + .method public strict virtual instance class [mscorlib]System.Tuple`3 + Invoke(class [mscorlib]System.Tuple`3 tupledArg) cil managed { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldc.i4.0 - IL_0001: ldc.i4.0 - IL_0002: newobj instance void ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::.ctor(int32, - int32) - IL_0007: ret - } // end of method f1@6::GetFreshEnumerator + // Code size 32 (0x20) + .maxstack 7 + .locals init ([0] !a a, + [1] int32 b, + [2] int32 c) + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.1 + IL_0001: call instance !0 class [mscorlib]System.Tuple`3::get_Item1() + IL_0006: stloc.0 + IL_0007: ldarg.1 + IL_0008: call instance !1 class [mscorlib]System.Tuple`3::get_Item2() + IL_000d: stloc.1 + IL_000e: ldarg.1 + IL_000f: call instance !2 class [mscorlib]System.Tuple`3::get_Item3() + IL_0014: stloc.2 + .line 25,25 : 40,49 '' + IL_0015: ldloc.0 + IL_0016: ldloc.1 + IL_0017: ldc.i4.1 + IL_0018: add + IL_0019: ldloc.2 + IL_001a: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, + !1, + !2) + IL_001f: ret + } // end of method xs2@25::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25::.ctor() + IL_0005: stsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25 class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25::@_instance + IL_000a: ret + } // end of method xs2@25::.cctor - } // end of class f1@6 + } // end of class xs2@25 .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f1() cil managed { - // Code size 15 (0xf) - .maxstack 8 + // Code size 59 (0x3b) + .maxstack 4 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0) .line 6,9 : 9,19 '' - IL_0000: ldc.i4.0 - IL_0001: ldc.i4.0 - IL_0002: newobj instance void ListExpressionSteppingTest2/ListExpressionSteppingTest2/f1@6::.ctor(int32, - int32) - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000e: ret + IL_0000: nop + .line 6,6 : 11,26 '' + IL_0001: ldstr "hello" + IL_0006: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_000b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0010: pop + .line 7,7 : 11,18 '' + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.1 + IL_0014: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0019: nop + .line 8,8 : 11,28 '' + IL_001a: ldstr "goodbye" + IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0029: pop + .line 9,9 : 11,18 '' + IL_002a: ldloca.s V_0 + IL_002c: ldc.i4.2 + IL_002d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0032: nop + .line 6,9 : 9,19 '' + IL_0033: ldloca.s V_0 + IL_0035: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003a: ret } // end of method ListExpressionSteppingTest2::f1 + .method public static class [mscorlib]System.Tuple`2>,class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>> + f2(!!a x) cil managed + { + // Code size 194 (0xc2) + .maxstack 6 + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> xs1, + [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #1 input #1 at line 16', + [2] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #1 input #2 at line 16', + [3] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> 'Pipe #1 stage #1 at line 17', + [4] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> 'Pipe #1 stage #2 at line 18', + [5] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> xs2, + [6] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #2 input #1 at line 22', + [7] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #2 input #2 at line 22', + [8] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #2 input #3 at line 22', + [9] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> 'Pipe #2 stage #1 at line 23', + [10] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> 'Pipe #2 stage #2 at line 24') + .line 15,19 : 9,45 '' + IL_0000: nop + .line 16,16 : 13,20 '' + IL_0001: ldarg.0 + IL_0002: ldarg.0 + IL_0003: ldarg.0 + IL_0004: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_000e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0013: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0018: stloc.1 + .line 16,16 : 22,28 '' + IL_0019: ldc.i4.0 + IL_001a: ldc.i4.1 + IL_001b: ldc.i4.2 + IL_001c: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0021: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::CreateSequence(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_002b: stloc.2 + .line 17,17 : 16,24 '' + IL_002c: ldloc.1 + IL_002d: ldloc.2 + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Zip(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0033: stloc.3 + .line 18,18 : 15,45 '' + IL_0034: ldsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18' class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #1 stage #2 at line 18@18'::@_instance + IL_0039: ldloc.3 + IL_003a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_003f: stloc.s 'Pipe #1 stage #2 at line 18' + .line 19,19 : 15,45 '' + IL_0041: ldsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19 class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs1@19::@_instance + IL_0046: ldloc.s 'Pipe #1 stage #2 at line 18' + IL_0048: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_004d: stloc.0 + .line 21,25 : 9,50 '' + IL_004e: nop + .line 22,22 : 13,20 '' + IL_004f: ldarg.0 + IL_0050: ldarg.0 + IL_0051: ldarg.0 + IL_0052: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0057: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_005c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0061: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0066: stloc.s 'Pipe #2 input #1 at line 22' + .line 22,22 : 22,28 '' + IL_0068: ldc.i4.0 + IL_0069: ldc.i4.1 + IL_006a: ldc.i4.2 + IL_006b: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0070: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::CreateSequence(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0075: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_007a: stloc.s 'Pipe #2 input #2 at line 22' + .line 22,22 : 30,36 '' + IL_007c: ldc.i4.0 + IL_007d: ldc.i4.1 + IL_007e: ldc.i4.2 + IL_007f: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators/OperatorIntrinsics::RangeInt32(int32, + int32, + int32) + IL_0084: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::CreateSequence(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0089: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_008e: stloc.s 'Pipe #2 input #3 at line 22' + .line 23,23 : 17,26 '' + IL_0090: ldloc.s 'Pipe #2 input #1 at line 22' + IL_0092: ldloc.s 'Pipe #2 input #2 at line 22' + IL_0094: ldloc.s 'Pipe #2 input #3 at line 22' + IL_0096: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Zip3(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_009b: stloc.s 'Pipe #2 stage #1 at line 23' + .line 24,24 : 15,50 '' + IL_009d: ldsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24' class ListExpressionSteppingTest2/ListExpressionSteppingTest2/'Pipe #2 stage #2 at line 24@24'::@_instance + IL_00a2: ldloc.s 'Pipe #2 stage #1 at line 23' + IL_00a4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_00a9: stloc.s 'Pipe #2 stage #2 at line 24' + .line 25,25 : 15,50 '' + IL_00ab: ldsfld class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25 class ListExpressionSteppingTest2/ListExpressionSteppingTest2/xs2@25::@_instance + IL_00b0: ldloc.s 'Pipe #2 stage #2 at line 24' + IL_00b2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_00b7: stloc.s xs2 + .line 27,27 : 9,17 '' + IL_00b9: ldloc.0 + IL_00ba: ldloc.s xs2 + IL_00bc: newobj instance void class [mscorlib]System.Tuple`2>,class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>>::.ctor(!0, + !1) + IL_00c1: ret + } // end of method ListExpressionSteppingTest2::f2 + } // end of class ListExpressionSteppingTest2 } // end of class ListExpressionSteppingTest2 @@ -280,12 +444,16 @@ .method public static void main@() cil managed { .entrypoint - // Code size 7 (0x7) + // Code size 14 (0xe) .maxstack 8 .line 11,11 : 13,17 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest2/ListExpressionSteppingTest2::f1() IL_0005: pop - IL_0006: ret + .line 29,29 : 13,17 '' + IL_0006: ldc.i4.5 + IL_0007: call class [mscorlib]System.Tuple`2>,class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>> ListExpressionSteppingTest2/ListExpressionSteppingTest2::f2(!!0) + IL_000c: pop + IL_000d: ret } // end of method $ListExpressionSteppingTest2::main@ } // end of class ''.$ListExpressionSteppingTest2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest3.il.bsl index 864056dbe8c..92f1f9b3632 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest3.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest3 { - // Offset: 0x00000000 Length: 0x0000027D + // Offset: 0x00000000 Length: 0x00000279 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest3 { - // Offset: 0x00000288 Length: 0x000000AF + // Offset: 0x00000280 Length: 0x000000AF } .module ListExpressionSteppingTest3.exe -// MVID: {59B1920C-AE45-39B4-A745-03830C92B159} +// MVID: {60B78A57-AE45-39B4-A745-0383578AB760} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00FF0000 +// Image base: 0x06EB0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,215 +55,48 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f2@7 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1> - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, - int32 pc, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 current) cil managed - { - // Code size 28 (0x1c) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::x - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::current - IL_0015: ldarg.0 - IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1>::.ctor() - IL_001b: ret - } // end of method f2@7::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed - { - // Code size 116 (0x74) - .maxstack 6 - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest3.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_0017, - IL_0019) - IL_0015: br.s IL_0021 - - IL_0017: br.s IL_001b - - IL_0019: br.s IL_001e - - .line 100001,100001 : 0,0 '' - IL_001b: nop - IL_001c: br.s IL_0061 - - .line 100001,100001 : 0,0 '' - IL_001e: nop - IL_001f: br.s IL_006b - - .line 100001,100001 : 0,0 '' - IL_0021: nop - .line 7,7 : 17,23 '' - IL_0022: ldarg.0 - IL_0023: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::x - IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002d: ldc.i4.4 - IL_002e: bge.s IL_0064 - - .line 8,8 : 14,20 '' - IL_0030: ldarg.0 - IL_0031: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::x - IL_0036: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_003b: nop - .line 9,9 : 14,29 '' - IL_003c: ldstr "hello" - IL_0041: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0046: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_004b: pop - IL_004c: ldarg.0 - IL_004d: ldc.i4.1 - IL_004e: stfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - .line 10,10 : 14,21 '' - IL_0053: ldarg.0 - IL_0054: ldarg.0 - IL_0055: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::x - IL_005a: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::current - IL_005f: ldc.i4.1 - IL_0060: ret - - .line 100001,100001 : 0,0 '' - IL_0061: nop - IL_0062: br.s IL_0022 - - IL_0064: ldarg.0 - IL_0065: ldc.i4.2 - IL_0066: stfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - IL_006b: ldarg.0 - IL_006c: ldnull - IL_006d: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::current - IL_0072: ldc.i4.0 - IL_0073: ret - } // end of method f2@7::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldc.i4.2 - IL_0002: stfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - IL_0007: ret - } // end of method f2@7::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 45 (0x2d) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::pc - IL_0006: switch ( - IL_0019, - IL_001b, - IL_001d) - IL_0017: br.s IL_0028 - - IL_0019: br.s IL_001f - - IL_001b: br.s IL_0022 - - IL_001d: br.s IL_0025 - - .line 100001,100001 : 0,0 '' - IL_001f: nop - IL_0020: br.s IL_002b - - .line 100001,100001 : 0,0 '' - IL_0022: nop - IL_0023: br.s IL_0029 - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002b - - .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: ldc.i4.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method f2@7::get_CheckClose - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::current - IL_0006: ret - } // end of method f2@7::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1> - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::x - IL_0006: ldc.i4.0 - IL_0007: ldnull - IL_0008: newobj instance void ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_000d: ret - } // end of method f2@7::GetFreshEnumerator - - } // end of class f2@7 - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> f2() cil managed { - // Code size 23 (0x17) - .maxstack 5 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x) - .line 6,6 : 9,22 '' + // Code size 60 (0x3c) + .maxstack 4 + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, + [1] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1> V_1) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 6,6 : 9,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest3.fs' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 .line 7,10 : 9,23 '' - IL_0007: ldloc.0 - IL_0008: ldc.i4.0 - IL_0009: ldnull - IL_000a: newobj instance void ListExpressionSteppingTest3/ListExpressionSteppingTest3/f2@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_000f: tail. - IL_0011: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0016: ret + IL_0007: nop + .line 7,7 : 11,23 '' + IL_0008: ldloc.0 + IL_0009: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_000e: ldc.i4.4 + IL_000f: bge.s IL_0034 + + .line 8,8 : 14,20 '' + IL_0011: ldloc.0 + IL_0012: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0017: nop + .line 9,9 : 14,29 '' + IL_0018: ldstr "hello" + IL_001d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0022: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0027: pop + .line 10,10 : 14,21 '' + IL_0028: ldloca.s V_1 + IL_002a: ldloc.0 + IL_002b: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Add(!0) + IL_0030: nop + .line 100001,100001 : 0,0 '' + IL_0031: nop + IL_0032: br.s IL_0007 + + .line 7,10 : 9,23 '' + IL_0034: ldloca.s V_1 + IL_0036: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1>::Close() + IL_003b: ret } // end of method ListExpressionSteppingTest3::f2 } // end of class ListExpressionSteppingTest3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest4.il.bsl index 2d0ccb9e33d..26509649fd5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest4.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest4 { - // Offset: 0x00000000 Length: 0x00000275 + // Offset: 0x00000000 Length: 0x00000269 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest4 { - // Offset: 0x00000280 Length: 0x000000AF + // Offset: 0x00000270 Length: 0x000000AF } .module ListExpressionSteppingTest4.exe -// MVID: {5B9A68C1-3154-FA67-A745-0383C1689A5B} +// MVID: {611C4D7C-3154-FA67-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x018D0000 +// Image base: 0x06AA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,262 +55,56 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f3@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, - int32 pc, - int32 current) cil managed - { - // Code size 36 (0x24) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::y - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - IL_0015: ldarg.0 - IL_0016: ldarg.s current - IL_0018: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::current - IL_001d: ldarg.0 - IL_001e: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0023: ret - } // end of method f3@6::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 190 (0xbe) - .maxstack 6 - .locals init ([0] int32 z) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest4.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0078 - - .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_00a0 - - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00b5 - - .line 100001,100001 : 0,0 '' - IL_002d: nop - .line 6,6 : 11,24 '' - IL_002e: ldarg.0 - IL_002f: ldc.i4.0 - IL_0030: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0035: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - .line 7,7 : 11,17 '' - IL_003a: ldarg.0 - IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - IL_0040: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0045: nop - .line 8,8 : 11,24 '' - IL_0046: ldarg.0 - IL_0047: ldc.i4.0 - IL_0048: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_004d: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::y - .line 9,9 : 11,17 '' - IL_0052: ldarg.0 - IL_0053: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::y - IL_0058: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_005d: nop - IL_005e: ldarg.0 - IL_005f: ldc.i4.1 - IL_0060: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - .line 10,10 : 11,19 '' - IL_0065: ldarg.0 - IL_0066: ldarg.0 - IL_0067: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - IL_006c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0071: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::current - IL_0076: ldc.i4.1 - IL_0077: ret - - .line 11,11 : 11,26 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - IL_007e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0083: ldarg.0 - IL_0084: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::y - IL_0089: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_008e: add - IL_008f: stloc.0 - IL_0090: ldarg.0 - IL_0091: ldc.i4.2 - IL_0092: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - .line 12,12 : 11,18 '' - IL_0097: ldarg.0 - IL_0098: ldloc.0 - IL_0099: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::current - IL_009e: ldc.i4.1 - IL_009f: ret - - .line 8,8 : 15,16 '' - IL_00a0: ldarg.0 - IL_00a1: ldnull - IL_00a2: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::y - IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::x - IL_00ae: ldarg.0 - IL_00af: ldc.i4.3 - IL_00b0: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - IL_00b5: ldarg.0 - IL_00b6: ldc.i4.0 - IL_00b7: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::current - IL_00bc: ldc.i4.0 - IL_00bd: ret - } // end of method f3@6::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldc.i4.3 - IL_0002: stfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - IL_0007: ret - } // end of method f3@6::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 56 (0x38) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::pc - IL_0006: switch ( - IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 - - .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 - - .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret - - IL_0034: ldc.i4.0 - IL_0035: ret - - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method f3@6::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::current - IL_0006: ret - } // end of method f3@6::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 10 (0xa) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - int32) - IL_0009: ret - } // end of method f3@6::GetFreshEnumerator - - } // end of class f3@6 - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f3() cil managed { - // Code size 17 (0x11) - .maxstack 8 + // Code size 74 (0x4a) + .maxstack 4 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, + [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, + [3] int32 z) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 6,12 : 9,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest4.fs' + IL_0000: nop + .line 6,6 : 11,24 '' + IL_0001: ldc.i4.0 + IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0007: stloc.1 + .line 7,7 : 11,17 '' + IL_0008: ldloc.1 + IL_0009: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_000e: nop + .line 8,8 : 11,24 '' + IL_000f: ldc.i4.0 + IL_0010: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0015: stloc.2 + .line 9,9 : 11,17 '' + IL_0016: ldloc.2 + IL_0017: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_001c: nop + .line 10,10 : 11,19 '' + IL_001d: ldloca.s V_0 + IL_001f: ldloc.1 + IL_0020: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0025: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_002a: nop + .line 11,11 : 11,26 '' + IL_002b: ldloc.1 + IL_002c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0031: ldloc.2 + IL_0032: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0037: add + IL_0038: stloc.3 + .line 12,12 : 11,18 '' + IL_0039: ldloca.s V_0 + IL_003b: ldloc.3 + IL_003c: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0041: nop .line 6,12 : 9,20 '' - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest4/ListExpressionSteppingTest4/f3@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - int32) - IL_0009: tail. - IL_000b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0010: ret + IL_0042: ldloca.s V_0 + IL_0044: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0049: ret } // end of method ListExpressionSteppingTest4::f3 } // end of class ListExpressionSteppingTest4 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest5.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest5.il.bsl index 39def210b7f..fce50680f94 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest5.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest5.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest5 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest5 { - // Offset: 0x00000000 Length: 0x00000275 + // Offset: 0x00000000 Length: 0x00000269 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest5 { - // Offset: 0x00000280 Length: 0x000000AF + // Offset: 0x00000270 Length: 0x000000AF } .module ListExpressionSteppingTest5.exe -// MVID: {5B9A6329-CBE3-BFEA-A745-038329639A5B} +// MVID: {611C4D7C-CBE3-BFEA-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x027C0000 +// Image base: 0x06B30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,413 +55,80 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f4@6 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f4() cil managed { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x - .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, - int32 pc, - int32 current) cil managed - { - // Code size 36 (0x24) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::y - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0015: ldarg.0 - IL_0016: ldarg.s current - IL_0018: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_001d: ldarg.0 - IL_001e: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0023: ret - } // end of method f4@6::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed + // Code size 101 (0x65) + .maxstack 4 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, + [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, + [4] int32 z) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 6,15 : 9,30 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest5.fs' + IL_0000: nop + .line 6,6 : 11,24 '' + IL_0001: ldc.i4.0 + IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0007: stloc.1 + .line 7,7 : 11,14 '' + .try { - // Code size 232 (0xe8) - .maxstack 6 - .locals init ([0] int32 z) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest5.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_001f, - IL_0021, - IL_0023, - IL_0025) - IL_001d: br.s IL_0039 - - IL_001f: br.s IL_0027 - - IL_0021: br.s IL_002d - - IL_0023: br.s IL_0030 - - IL_0025: br.s IL_0033 - - .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00ae - - .line 100001,100001 : 0,0 '' - IL_002d: nop - IL_002e: br.s IL_007f - - .line 100001,100001 : 0,0 '' - IL_0030: nop - IL_0031: br.s IL_00a7 - - .line 100001,100001 : 0,0 '' - IL_0033: nop - IL_0034: br IL_00df - - .line 100001,100001 : 0,0 '' - IL_0039: nop - .line 6,6 : 11,24 '' - IL_003a: ldarg.0 - IL_003b: ldc.i4.0 - IL_003c: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0041: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_0046: ldarg.0 - IL_0047: ldc.i4.1 - IL_0048: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc + IL_0008: nop .line 8,8 : 15,28 '' - IL_004d: ldarg.0 - IL_004e: ldc.i4.0 - IL_004f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0054: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::y + IL_0009: ldc.i4.0 + IL_000a: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_000f: stloc.3 .line 9,9 : 15,21 '' - IL_0059: ldarg.0 - IL_005a: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::y - IL_005f: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0064: nop - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc + IL_0010: ldloc.3 + IL_0011: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0016: nop .line 10,10 : 15,23 '' - IL_006c: ldarg.0 - IL_006d: ldarg.0 - IL_006e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_0073: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0078: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_007d: ldc.i4.1 - IL_007e: ret - + IL_0017: ldloca.s V_0 + IL_0019: ldloc.1 + IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_001f: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0024: nop .line 11,11 : 15,30 '' - IL_007f: ldarg.0 - IL_0080: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_0085: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_008a: ldarg.0 - IL_008b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::y - IL_0090: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0095: add - IL_0096: stloc.0 - IL_0097: ldarg.0 - IL_0098: ldc.i4.3 - IL_0099: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc + IL_0025: ldloc.1 + IL_0026: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_002b: ldloc.3 + IL_002c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0031: add + IL_0032: stloc.s z .line 12,12 : 15,22 '' - IL_009e: ldarg.0 - IL_009f: ldloc.0 - IL_00a0: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_00a5: ldc.i4.1 - IL_00a6: ret - - IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::y - IL_00ae: ldarg.0 - IL_00af: ldc.i4.4 - IL_00b0: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc + IL_0034: ldloca.s V_0 + IL_0036: ldloc.s z + IL_0038: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_003d: nop + IL_003e: ldnull + IL_003f: stloc.2 + IL_0040: leave.s IL_005b + + .line 13,13 : 11,18 '' + } // end .try + finally + { + IL_0042: nop .line 14,14 : 14,20 '' - IL_00b5: ldarg.0 - IL_00b6: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_00bb: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_00c0: nop + IL_0043: ldloc.1 + IL_0044: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0049: nop .line 15,15 : 14,28 '' - IL_00c1: ldstr "done" - IL_00c6: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_00cb: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_00d0: pop - IL_00d1: ldarg.0 - IL_00d2: ldnull - IL_00d3: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_00d8: ldarg.0 - IL_00d9: ldc.i4.4 - IL_00da: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_00df: ldarg.0 - IL_00e0: ldc.i4.0 - IL_00e1: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_00e6: ldc.i4.0 - IL_00e7: ret - } // end of method f4@6::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 176 (0xb0) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0006: ldc.i4.4 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_00a3 - - .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0020: switch ( - IL_003b, - IL_003d, - IL_003f, - IL_0041, - IL_0043) - IL_0039: br.s IL_0054 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - IL_003f: br.s IL_004b - - IL_0041: br.s IL_004e - - IL_0043: br.s IL_0051 - - .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_007d - - .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0059 - - .line 100001,100001 : 0,0 '' - IL_004b: nop - IL_004c: br.s IL_0058 - - .line 100001,100001 : 0,0 '' - IL_004e: nop - IL_004f: br.s IL_0055 - - .line 100001,100001 : 0,0 '' - IL_0051: nop - IL_0052: br.s IL_007d - - .line 100001,100001 : 0,0 '' - IL_0054: nop - .line 100001,100001 : 0,0 '' - IL_0055: nop - IL_0056: br.s IL_0059 - - .line 100001,100001 : 0,0 '' - IL_0058: nop - IL_0059: ldarg.0 - IL_005a: ldc.i4.4 - IL_005b: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - .line 14,14 : 14,20 '' - IL_0060: ldarg.0 - IL_0061: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::x - IL_0066: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_006b: nop - .line 15,15 : 14,28 '' - IL_006c: ldstr "done" - IL_0071: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0076: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_007b: pop - .line 100001,100001 : 0,0 '' - IL_007c: nop - IL_007d: ldarg.0 - IL_007e: ldc.i4.4 - IL_007f: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0084: ldarg.0 - IL_0085: ldc.i4.0 - IL_0086: stfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_008b: ldnull - IL_008c: stloc.1 - IL_008d: leave.s IL_009b - - } // end .try - catch [mscorlib]System.Object - { - IL_008f: castclass [mscorlib]System.Exception - IL_0094: stloc.2 - .line 6,6 : 15,16 '' - IL_0095: ldloc.2 - IL_0096: stloc.0 - IL_0097: ldnull - IL_0098: stloc.1 - IL_0099: leave.s IL_009b - - .line 100001,100001 : 0,0 '' - } // end handler - IL_009b: ldloc.1 - IL_009c: pop - .line 100001,100001 : 0,0 '' - IL_009d: nop - IL_009e: br IL_0000 - - IL_00a3: ldloc.0 - IL_00a4: ldnull - IL_00a5: cgt.un - IL_00a7: brfalse.s IL_00ab - - IL_00a9: br.s IL_00ad - - IL_00ab: br.s IL_00af - - .line 100001,100001 : 0,0 '' - IL_00ad: ldloc.0 - IL_00ae: throw - - .line 100001,100001 : 0,0 '' - IL_00af: ret - } // end of method f4@6::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 67 (0x43) - .maxstack 5 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::pc - IL_0006: switch ( - IL_0021, - IL_0023, - IL_0025, - IL_0027, - IL_0029) - IL_001f: br.s IL_003a - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - - IL_0025: br.s IL_0031 - - IL_0027: br.s IL_0034 - - IL_0029: br.s IL_0037 - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0041 - - .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_003f - - .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: br.s IL_003d - - .line 100001,100001 : 0,0 '' - IL_0034: nop - IL_0035: br.s IL_003b - - .line 100001,100001 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_0041 - - .line 100001,100001 : 0,0 '' - IL_003a: nop - IL_003b: ldc.i4.1 - IL_003c: ret - - IL_003d: ldc.i4.1 - IL_003e: ret - - IL_003f: ldc.i4.1 - IL_0040: ret - - IL_0041: ldc.i4.0 - IL_0042: ret - } // end of method f4@6::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::current - IL_0006: ret - } // end of method f4@6::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 10 (0xa) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - int32) - IL_0009: ret - } // end of method f4@6::GetFreshEnumerator - - } // end of class f4@6 - - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - f4() cil managed - { - // Code size 17 (0x11) - .maxstack 8 + IL_004a: ldstr "done" + IL_004f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0054: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0059: pop + IL_005a: endfinally + .line 100001,100001 : 0,0 '' + } // end handler + IL_005b: ldloc.2 + IL_005c: pop .line 6,15 : 9,30 '' - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest5/ListExpressionSteppingTest5/f4@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1, - int32, - int32) - IL_0009: tail. - IL_000b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0010: ret + IL_005d: ldloca.s V_0 + IL_005f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_0064: ret } // end of method ListExpressionSteppingTest5::f4 } // end of class ListExpressionSteppingTest5 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest6.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest6.il.bsl index 2d43c04e954..78f4860f029 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest6.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/ListExpressionStepping/ListExpressionSteppingTest6.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly ListExpressionSteppingTest6 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ListExpressionSteppingTest6 { - // Offset: 0x00000000 Length: 0x0000029D + // Offset: 0x00000000 Length: 0x00000291 } .mresource public FSharpOptimizationData.ListExpressionSteppingTest6 { - // Offset: 0x000002A8 Length: 0x000000BC + // Offset: 0x00000298 Length: 0x000000BC } .module ListExpressionSteppingTest6.exe -// MVID: {5B9A6329-98A2-AB14-A745-038329639A5B} +// MVID: {611C4D7C-98A2-AB14-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x007B0000 +// Image base: 0x06930000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,484 +55,139 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f7@7 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + get_es() cil managed { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum' - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public class [mscorlib]System.Collections.Generic.IEnumerator`1 enum0 - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public int32 current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1 'enum', - class [mscorlib]System.Collections.Generic.IEnumerator`1 enum0, - int32 pc, - int32 current) cil managed - { - // Code size 36 (0x24) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_000e: ldarg.0 - IL_000f: ldarg.3 - IL_0010: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0015: ldarg.0 - IL_0016: ldarg.s current - IL_0018: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_001d: ldarg.0 - IL_001e: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0023: ret - } // end of method f7@7::.ctor + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$ListExpressionSteppingTest6::es@5 + IL_0005: ret + } // end of method ListExpressionSteppingTest6::get_es - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + f7() cil managed + { + // Code size 178 (0xb2) + .maxstack 4 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_1, + [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_2, + [3] int32 x, + [4] class [mscorlib]System.IDisposable V_4, + [5] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_5, + [6] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_6, + [7] int32 V_7, + [8] class [mscorlib]System.IDisposable V_8) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 7,12 : 9,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest6.fs' + IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6::get_es() + IL_0005: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_000a: stloc.1 + .line 7,7 : 11,25 '' + .try { - // Code size 304 (0x130) - .maxstack 6 - .locals init ([0] int32 x, - [1] int32 V_1) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\ListExpressionStepping\\ListExpressionSteppingTest6.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_0023, - IL_0025, - IL_0027, - IL_0029, - IL_002b) - IL_0021: br.s IL_0045 - - IL_0023: br.s IL_002d - - IL_0025: br.s IL_0030 - - IL_0027: br.s IL_0033 - - IL_0029: br.s IL_0039 - - IL_002b: br.s IL_003f - - .line 100001,100001 : 0,0 '' - IL_002d: nop - IL_002e: br.s IL_0099 - - .line 100001,100001 : 0,0 '' - IL_0030: nop - IL_0031: br.s IL_0096 - - .line 100001,100001 : 0,0 '' - IL_0033: nop - IL_0034: br IL_0106 - - .line 100001,100001 : 0,0 '' - IL_0039: nop - IL_003a: br IL_0103 - - .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br IL_0127 + IL_000b: ldloc.1 + IL_000c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0011: brfalse.s IL_0036 - .line 100001,100001 : 0,0 '' - IL_0045: nop - .line 7,9 : 11,21 '' - IL_0046: ldarg.0 - IL_0047: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6::get_es() - IL_004c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0051: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_0056: ldarg.0 - IL_0057: ldc.i4.1 - IL_0058: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - .line 7,9 : 11,21 '' - IL_005d: ldarg.0 - IL_005e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_0063: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0068: brfalse.s IL_0099 - - IL_006a: ldarg.0 - IL_006b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_0070: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0075: stloc.0 + IL_0013: ldloc.1 + IL_0014: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0019: stloc.3 .line 8,8 : 14,29 '' - IL_0076: ldstr "hello" - IL_007b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0080: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0085: pop - IL_0086: ldarg.0 - IL_0087: ldc.i4.2 - IL_0088: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc + IL_001a: ldstr "hello" + IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0029: pop .line 9,9 : 14,21 '' - IL_008d: ldarg.0 - IL_008e: ldloc.0 - IL_008f: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_0094: ldc.i4.1 - IL_0095: ret - - .line 100001,100001 : 0,0 '' - IL_0096: nop - IL_0097: br.s IL_005d - - IL_0099: ldarg.0 - IL_009a: ldc.i4.5 - IL_009b: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - .line 7,9 : 11,21 '' - IL_00a0: ldarg.0 - IL_00a1: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_00a6: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_00ab: nop - IL_00ac: ldarg.0 - IL_00ad: ldnull - IL_00ae: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - .line 10,12 : 11,21 '' - IL_00b3: ldarg.0 - IL_00b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6::get_es() - IL_00b9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_00be: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_00c3: ldarg.0 - IL_00c4: ldc.i4.3 - IL_00c5: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - .line 10,12 : 11,21 '' - IL_00ca: ldarg.0 - IL_00cb: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_00d0: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_00d5: brfalse.s IL_0106 - - IL_00d7: ldarg.0 - IL_00d8: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_00dd: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_00e2: stloc.1 - .line 11,11 : 14,31 '' - IL_00e3: ldstr "goodbye" - IL_00e8: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_00ed: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_00f2: pop - IL_00f3: ldarg.0 - IL_00f4: ldc.i4.4 - IL_00f5: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - .line 12,12 : 14,21 '' - IL_00fa: ldarg.0 - IL_00fb: ldloc.1 - IL_00fc: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_0101: ldc.i4.1 - IL_0102: ret - + IL_002a: ldloca.s V_0 + IL_002c: ldloc.3 + IL_002d: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0032: nop .line 100001,100001 : 0,0 '' - IL_0103: nop - IL_0104: br.s IL_00ca + IL_0033: nop + IL_0034: br.s IL_000b - IL_0106: ldarg.0 - IL_0107: ldc.i4.5 - IL_0108: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - .line 10,12 : 11,21 '' - IL_010d: ldarg.0 - IL_010e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_0113: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0118: nop - IL_0119: ldarg.0 - IL_011a: ldnull - IL_011b: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_0120: ldarg.0 - IL_0121: ldc.i4.5 - IL_0122: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0127: ldarg.0 - IL_0128: ldc.i4.0 - IL_0129: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_012e: ldc.i4.0 - IL_012f: ret - } // end of method f7@7::GenerateNext + IL_0036: ldnull + IL_0037: stloc.2 + IL_0038: leave.s IL_004f - .method public strict virtual instance void - Close() cil managed + .line 7,9 : 11,21 '' + } // end .try + finally { - // Code size 189 (0xbd) - .maxstack 6 - .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0006: ldc.i4.5 - IL_0007: sub - IL_0008: switch ( - IL_0013) - IL_0011: br.s IL_0019 - - .line 100001,100001 : 0,0 '' - IL_0013: nop - IL_0014: br IL_00b0 - + IL_003a: ldloc.1 + IL_003b: isinst [mscorlib]System.IDisposable + IL_0040: stloc.s V_4 .line 100001,100001 : 0,0 '' - IL_0019: nop - .try - { - IL_001a: ldarg.0 - IL_001b: ldfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0020: switch ( - IL_003f, - IL_0041, - IL_0043, - IL_0045, - IL_0047, - IL_0049) - IL_003d: br.s IL_005d - - IL_003f: br.s IL_004b - - IL_0041: br.s IL_004e - - IL_0043: br.s IL_0051 - - IL_0045: br.s IL_0054 - - IL_0047: br.s IL_0057 - - IL_0049: br.s IL_005a + IL_0042: ldloc.s V_4 + IL_0044: brfalse.s IL_004e - .line 100001,100001 : 0,0 '' - IL_004b: nop - IL_004c: br.s IL_008a - - .line 100001,100001 : 0,0 '' - IL_004e: nop - IL_004f: br.s IL_0076 - - .line 100001,100001 : 0,0 '' - IL_0051: nop - IL_0052: br.s IL_0075 - - .line 100001,100001 : 0,0 '' - IL_0054: nop - IL_0055: br.s IL_005f - - .line 100001,100001 : 0,0 '' - IL_0057: nop - IL_0058: br.s IL_005e - - .line 100001,100001 : 0,0 '' - IL_005a: nop - IL_005b: br.s IL_008a - - .line 100001,100001 : 0,0 '' - IL_005d: nop - .line 100001,100001 : 0,0 '' - IL_005e: nop - IL_005f: ldarg.0 - IL_0060: ldc.i4.5 - IL_0061: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0066: ldarg.0 - IL_0067: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::enum0 - IL_006c: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0071: nop - .line 100001,100001 : 0,0 '' - IL_0072: nop - IL_0073: br.s IL_008a - - .line 100001,100001 : 0,0 '' - IL_0075: nop - IL_0076: ldarg.0 - IL_0077: ldc.i4.5 - IL_0078: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_007d: ldarg.0 - IL_007e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::'enum' - IL_0083: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0088: nop - .line 100001,100001 : 0,0 '' - IL_0089: nop - IL_008a: ldarg.0 - IL_008b: ldc.i4.5 - IL_008c: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0091: ldarg.0 - IL_0092: ldc.i4.0 - IL_0093: stfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_0098: ldnull - IL_0099: stloc.1 - IL_009a: leave.s IL_00a8 - - } // end .try - catch [mscorlib]System.Object - { - IL_009c: castclass [mscorlib]System.Exception - IL_00a1: stloc.2 - .line 7,9 : 11,21 '' - IL_00a2: ldloc.2 - IL_00a3: stloc.0 - IL_00a4: ldnull - IL_00a5: stloc.1 - IL_00a6: leave.s IL_00a8 - - .line 100001,100001 : 0,0 '' - } // end handler - IL_00a8: ldloc.1 - IL_00a9: pop .line 100001,100001 : 0,0 '' - IL_00aa: nop - IL_00ab: br IL_0000 - - IL_00b0: ldloc.0 - IL_00b1: ldnull - IL_00b2: cgt.un - IL_00b4: brfalse.s IL_00b8 - - IL_00b6: br.s IL_00ba - - IL_00b8: br.s IL_00bc - + IL_0046: ldloc.s V_4 + IL_0048: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_004d: endfinally .line 100001,100001 : 0,0 '' - IL_00ba: ldloc.0 - IL_00bb: throw - + IL_004e: endfinally .line 100001,100001 : 0,0 '' - IL_00bc: ret - } // end of method f7@7::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed + } // end handler + IL_004f: ldloc.2 + IL_0050: pop + IL_0051: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ListExpressionSteppingTest6/ListExpressionSteppingTest6::get_es() + IL_0056: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_005b: stloc.s V_5 + .line 10,10 : 11,25 '' + .try { - // Code size 78 (0x4e) - .maxstack 5 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::pc - IL_0006: switch ( - IL_0025, - IL_0027, - IL_0029, - IL_002b, - IL_002d, - IL_002f) - IL_0023: br.s IL_0043 - - IL_0025: br.s IL_0031 - - IL_0027: br.s IL_0034 - - IL_0029: br.s IL_0037 - - IL_002b: br.s IL_003a - - IL_002d: br.s IL_003d - - IL_002f: br.s IL_0040 - - .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: br.s IL_004c + IL_005d: ldloc.s V_5 + IL_005f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0064: brfalse.s IL_008c + IL_0066: ldloc.s V_5 + IL_0068: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_006d: stloc.s V_7 + .line 11,11 : 14,31 '' + IL_006f: ldstr "goodbye" + IL_0074: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0079: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_007e: pop + .line 12,12 : 14,21 '' + IL_007f: ldloca.s V_0 + IL_0081: ldloc.s V_7 + IL_0083: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Add(!0) + IL_0088: nop .line 100001,100001 : 0,0 '' - IL_0034: nop - IL_0035: br.s IL_004a + IL_0089: nop + IL_008a: br.s IL_005d - .line 100001,100001 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_0048 + IL_008c: ldnull + IL_008d: stloc.s V_6 + IL_008f: leave.s IL_00a7 + .line 10,12 : 11,21 '' + } // end .try + finally + { + IL_0091: ldloc.s V_5 + IL_0093: isinst [mscorlib]System.IDisposable + IL_0098: stloc.s V_8 .line 100001,100001 : 0,0 '' - IL_003a: nop - IL_003b: br.s IL_0046 + IL_009a: ldloc.s V_8 + IL_009c: brfalse.s IL_00a6 .line 100001,100001 : 0,0 '' - IL_003d: nop - IL_003e: br.s IL_0044 - + IL_009e: ldloc.s V_8 + IL_00a0: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_00a5: endfinally .line 100001,100001 : 0,0 '' - IL_0040: nop - IL_0041: br.s IL_004c - + IL_00a6: endfinally .line 100001,100001 : 0,0 '' - IL_0043: nop - IL_0044: ldc.i4.1 - IL_0045: ret - - IL_0046: ldc.i4.1 - IL_0047: ret - - IL_0048: ldc.i4.1 - IL_0049: ret - - IL_004a: ldc.i4.1 - IL_004b: ret - - IL_004c: ldc.i4.0 - IL_004d: ret - } // end of method f7@7::get_CheckClose - - .method public strict virtual instance int32 - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::current - IL_0006: ret - } // end of method f7@7::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 10 (0xa) - .maxstack 8 - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0009: ret - } // end of method f7@7::GetFreshEnumerator - - } // end of class f7@7 - - .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - get_es() cil managed - { - // Code size 6 (0x6) - .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$ListExpressionSteppingTest6::es@5 - IL_0005: ret - } // end of method ListExpressionSteppingTest6::get_es - - .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - f7() cil managed - { - // Code size 17 (0x11) - .maxstack 8 + } // end handler + IL_00a7: ldloc.s V_6 + IL_00a9: pop .line 7,12 : 9,23 '' - IL_0000: ldnull - IL_0001: ldnull - IL_0002: ldc.i4.0 - IL_0003: ldc.i4.0 - IL_0004: newobj instance void ListExpressionSteppingTest6/ListExpressionSteppingTest6/f7@7::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0009: tail. - IL_000b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0010: ret + IL_00aa: ldloca.s V_0 + IL_00ac: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_00b1: ret } // end of method ListExpressionSteppingTest6::f7 .property class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AbstractClass.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AbstractClass.il.bsl index 0bae910d0f1..4c8bea58a08 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AbstractClass.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AbstractClass.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly AbstractClass { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AbstractClass { - // Offset: 0x00000000 Length: 0x00000306 + // Offset: 0x00000000 Length: 0x00000302 } .mresource public FSharpOptimizationData.AbstractClass { - // Offset: 0x00000310 Length: 0x000000B1 + // Offset: 0x00000308 Length: 0x000000B1 } .module AbstractClass.exe -// MVID: {59B19213-333C-8BAF-A745-03831392B159} +// MVID: {60B68B7F-333C-8BAF-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010A0000 +// Image base: 0x07500000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\AbstractClass.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\AbstractClass.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AnonRecd.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AnonRecd.il.bsl index af9a419018c..bfe21b6f486 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AnonRecd.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/AnonRecd.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.7.3081.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:6:0:0 + .ver 5:0:0:0 } .assembly AnonRecd { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AnonRecd { - // Offset: 0x00000000 Length: 0x000001CE + // Offset: 0x00000000 Length: 0x000001C2 } .mresource public FSharpOptimizationData.AnonRecd { - // Offset: 0x000001D8 Length: 0x0000006B + // Offset: 0x000001C8 Length: 0x0000006B } .module AnonRecd.exe -// MVID: {5CBDEF61-C42F-5208-A745-038361EFBD5C} +// MVID: {611C4D7C-C42F-5208-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00D20000 +// Image base: 0x07240000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ .locals init ([0] int32 x, [1] class '<>f__AnonymousType1912756633`2' a) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 5,22 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\AnonRecd.fs' + .line 4,4 : 5,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\AnonRecd.fs' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 6,6 : 5,31 '' @@ -161,97 +161,80 @@ instance int32 CompareTo(class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 104 (0x68) + // Code size 85 (0x55) .maxstack 5 .locals init ([0] int32 V_0) - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\unknown' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_005a - + .line 1,1 : 1,1 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\unknown' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_004b - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0058 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0049 .line 100001,100001 : 0,0 '' - IL_0014: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0019: ldarg.0 - IL_001a: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_001f: ldarg.1 - IL_0020: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0025: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: ldarg.0 + IL_0013: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0018: ldarg.1 + IL_0019: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_001e: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_002a: stloc.0 - IL_002b: ldloc.0 - IL_002c: ldc.i4.0 - IL_002d: bge.s IL_0031 - - IL_002f: br.s IL_0033 - - IL_0031: br.s IL_0035 - + IL_0023: stloc.0 .line 100001,100001 : 0,0 '' - IL_0033: ldloc.0 - IL_0034: ret + IL_0024: ldloc.0 + IL_0025: ldc.i4.0 + IL_0026: bge.s IL_002a .line 100001,100001 : 0,0 '' - IL_0035: ldloc.0 - IL_0036: ldc.i4.0 - IL_0037: ble.s IL_003b - - IL_0039: br.s IL_003d + IL_0028: ldloc.0 + IL_0029: ret - IL_003b: br.s IL_003f + .line 100001,100001 : 0,0 '' + IL_002a: ldloc.0 + IL_002b: ldc.i4.0 + IL_002c: ble.s IL_0030 .line 100001,100001 : 0,0 '' - IL_003d: ldloc.0 - IL_003e: ret + IL_002e: ldloc.0 + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003f: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0044: ldarg.0 - IL_0045: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_004a: ldarg.1 - IL_004b: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0050: tail. - IL_0052: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, + IL_0030: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0035: ldarg.0 + IL_0036: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_003b: ldarg.1 + IL_003c: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0041: tail. + IL_0043: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0057: ret + IL_0048: ret .line 100001,100001 : 0,0 '' - IL_0058: ldc.i4.1 - IL_0059: ret + IL_0049: ldc.i4.1 + IL_004a: ret .line 100001,100001 : 0,0 '' - IL_005a: ldarg.1 - IL_005b: ldnull - IL_005c: cgt.un - IL_005e: brfalse.s IL_0062 - - IL_0060: br.s IL_0064 - - IL_0062: br.s IL_0066 + IL_004b: ldarg.1 + IL_004c: ldnull + IL_004d: cgt.un + IL_004f: brfalse.s IL_0053 .line 100001,100001 : 0,0 '' - IL_0064: ldc.i4.m1 - IL_0065: ret + IL_0051: ldc.i4.m1 + IL_0052: ret .line 100001,100001 : 0,0 '' - IL_0066: ldc.i4.0 - IL_0067: ret + IL_0053: ldc.i4.0 + IL_0054: ret } // end of method '<>f__AnonymousType1912756633`2'::CompareTo .method public hidebysig virtual final @@ -274,7 +257,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 115 (0x73) + // Code size 95 (0x5f) .maxstack 5 .locals init ([0] class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> V_0, [1] class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> V_1, @@ -285,155 +268,135 @@ IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: stloc.1 + .line 100001,100001 : 0,0 '' IL_0009: ldarg.0 IL_000a: ldnull IL_000b: cgt.un - IL_000d: brfalse.s IL_0011 - - IL_000f: br.s IL_0013 - - IL_0011: br.s IL_0060 + IL_000d: brfalse.s IL_0050 .line 100001,100001 : 0,0 '' - IL_0013: ldarg.1 - IL_0014: unbox.any class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> - IL_0019: ldnull - IL_001a: cgt.un - IL_001c: brfalse.s IL_0020 - - IL_001e: br.s IL_0022 - - IL_0020: br.s IL_005e + IL_000f: ldarg.1 + IL_0010: unbox.any class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> + IL_0015: ldnull + IL_0016: cgt.un + IL_0018: brfalse.s IL_004e .line 100001,100001 : 0,0 '' - IL_0022: ldarg.2 - IL_0023: ldarg.0 - IL_0024: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0029: ldloc.1 - IL_002a: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_002f: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, + IL_001a: ldarg.2 + IL_001b: ldarg.0 + IL_001c: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0021: ldloc.1 + IL_0022: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0027: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0034: stloc.2 - IL_0035: ldloc.2 - IL_0036: ldc.i4.0 - IL_0037: bge.s IL_003b - - IL_0039: br.s IL_003d - - IL_003b: br.s IL_003f - + IL_002c: stloc.2 .line 100001,100001 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_002d: ldloc.2 + IL_002e: ldc.i4.0 + IL_002f: bge.s IL_0033 .line 100001,100001 : 0,0 '' - IL_003f: ldloc.2 - IL_0040: ldc.i4.0 - IL_0041: ble.s IL_0045 - - IL_0043: br.s IL_0047 + IL_0031: ldloc.2 + IL_0032: ret - IL_0045: br.s IL_0049 + .line 100001,100001 : 0,0 '' + IL_0033: ldloc.2 + IL_0034: ldc.i4.0 + IL_0035: ble.s IL_0039 .line 100001,100001 : 0,0 '' - IL_0047: ldloc.2 - IL_0048: ret + IL_0037: ldloc.2 + IL_0038: ret .line 100001,100001 : 0,0 '' - IL_0049: ldarg.2 - IL_004a: ldarg.0 - IL_004b: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0050: ldloc.1 - IL_0051: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0056: tail. - IL_0058: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, + IL_0039: ldarg.2 + IL_003a: ldarg.0 + IL_003b: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0040: ldloc.1 + IL_0041: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0046: tail. + IL_0048: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericComparisonWithComparerj__TPar'>(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_005d: ret + IL_004d: ret .line 100001,100001 : 0,0 '' - IL_005e: ldc.i4.1 - IL_005f: ret + IL_004e: ldc.i4.1 + IL_004f: ret .line 100001,100001 : 0,0 '' - IL_0060: ldarg.1 - IL_0061: unbox.any class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> - IL_0066: ldnull - IL_0067: cgt.un - IL_0069: brfalse.s IL_006d - - IL_006b: br.s IL_006f - - IL_006d: br.s IL_0071 + IL_0050: ldarg.1 + IL_0051: unbox.any class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> + IL_0056: ldnull + IL_0057: cgt.un + IL_0059: brfalse.s IL_005d .line 100001,100001 : 0,0 '' - IL_006f: ldc.i4.m1 - IL_0070: ret + IL_005b: ldc.i4.m1 + IL_005c: ret .line 100001,100001 : 0,0 '' - IL_0071: ldc.i4.0 - IL_0072: ret + IL_005d: ldc.i4.0 + IL_005e: ret } // end of method '<>f__AnonymousType1912756633`2'::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 70 (0x46) + // Code size 67 (0x43) .maxstack 7 .locals init ([0] int32 V_0) + .line 1,1 : 1,1 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0044 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0041 .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldc.i4 0x9e3779b9 - IL_0011: ldarg.1 - IL_0012: ldarg.0 - IL_0013: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0018: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: ldarg.0 + IL_0010: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0015: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, !!0) + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl IL_001d: ldloc.0 - IL_001e: ldc.i4.6 - IL_001f: shl - IL_0020: ldloc.0 - IL_0021: ldc.i4.2 - IL_0022: shr - IL_0023: add - IL_0024: add - IL_0025: add - IL_0026: stloc.0 - IL_0027: ldc.i4 0x9e3779b9 - IL_002c: ldarg.1 - IL_002d: ldarg.0 - IL_002e: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0033: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, + IL_001e: ldc.i4.2 + IL_001f: shr + IL_0020: add + IL_0021: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldarg.1 + IL_002a: ldarg.0 + IL_002b: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0030: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericHashWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, !!0) + IL_0035: ldloc.0 + IL_0036: ldc.i4.6 + IL_0037: shl IL_0038: ldloc.0 - IL_0039: ldc.i4.6 - IL_003a: shl - IL_003b: ldloc.0 - IL_003c: ldc.i4.2 - IL_003d: shr - IL_003e: add - IL_003f: add - IL_0040: add - IL_0041: stloc.0 - IL_0042: ldloc.0 - IL_0043: ret + IL_0039: ldc.i4.2 + IL_003a: shr + IL_003b: add + IL_003c: add + IL_003d: add + IL_003e: stloc.0 + IL_003f: ldloc.0 + IL_0040: ret .line 100001,100001 : 0,0 '' - IL_0044: ldc.i4.0 - IL_0045: ret + IL_0041: ldc.i4.0 + IL_0042: ret } // end of method '<>f__AnonymousType1912756633`2'::GetHashCode .method public hidebysig virtual final @@ -455,171 +418,150 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 83 (0x53) + // Code size 72 (0x48) .maxstack 5 .locals init ([0] class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> V_0, [1] class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> V_1) + .line 1,1 : 1,1 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0040 - IL_0008: br.s IL_004b + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003e .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> - IL_0010: stloc.0 IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_0049 - + IL_0012: stloc.1 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.2 - IL_001b: ldarg.0 - IL_001c: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0021: ldloc.1 - IL_0022: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0027: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, + IL_0013: ldarg.2 + IL_0014: ldarg.0 + IL_0015: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_001a: ldloc.1 + IL_001b: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0020: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_002c: brfalse.s IL_0030 - - IL_002e: br.s IL_0032 - - IL_0030: br.s IL_0047 + IL_0025: brfalse.s IL_003c .line 100001,100001 : 0,0 '' - IL_0032: ldarg.2 - IL_0033: ldarg.0 - IL_0034: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0039: ldloc.1 - IL_003a: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_003f: tail. - IL_0041: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, + IL_0027: ldarg.2 + IL_0028: ldarg.0 + IL_0029: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_002e: ldloc.1 + IL_002f: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0034: tail. + IL_0036: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityWithComparerj__TPar'>(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_0046: ret + IL_003b: ret .line 100001,100001 : 0,0 '' - IL_0047: ldc.i4.0 - IL_0048: ret + IL_003c: ldc.i4.0 + IL_003d: ret .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.0 - IL_004a: ret + IL_003e: ldc.i4.0 + IL_003f: ret .line 100001,100001 : 0,0 '' - IL_004b: ldarg.1 - IL_004c: ldnull - IL_004d: cgt.un - IL_004f: ldc.i4.0 - IL_0050: ceq - IL_0052: ret + IL_0040: ldarg.1 + IL_0041: ldnull + IL_0042: cgt.un + IL_0044: ldc.i4.0 + IL_0045: ceq + IL_0047: ret } // end of method '<>f__AnonymousType1912756633`2'::Equals .method public hidebysig virtual final instance bool Equals(class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 75 (0x4b) + // Code size 64 (0x40) .maxstack 4 + .line 1,1 : 1,1 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0043 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0041 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0036 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_001a: ldarg.1 - IL_001b: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ - IL_0020: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + IL_000d: ldarg.0 + IL_000e: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0013: ldarg.1 + IL_0014: ldfld !0 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::A@ + IL_0019: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, !!0) - IL_0025: brfalse.s IL_0029 - - IL_0027: br.s IL_002b - - IL_0029: br.s IL_003f + IL_001e: brfalse.s IL_0034 .line 100001,100001 : 0,0 '' - IL_002b: ldarg.0 - IL_002c: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0031: ldarg.1 - IL_0032: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ - IL_0037: tail. - IL_0039: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, + IL_0020: ldarg.0 + IL_0021: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_0026: ldarg.1 + IL_0027: ldfld !1 class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::B@ + IL_002c: tail. + IL_002e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::GenericEqualityERj__TPar'>(!!0, !!0) - IL_003e: ret + IL_0033: ret .line 100001,100001 : 0,0 '' - IL_003f: ldc.i4.0 - IL_0040: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 100001,100001 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 100001,100001 : 0,0 '' - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: ldc.i4.0 - IL_0048: ceq - IL_004a: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method '<>f__AnonymousType1912756633`2'::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 26 (0x1a) + // Code size 22 (0x16) .maxstack 4 .locals init ([0] class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> V_0) .line 1,1 : 1,1 '' IL_0000: ldarg.1 IL_0001: isinst class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'> IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0018 + IL_0008: brfalse.s IL_0014 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: tail. - IL_0012: callvirt instance bool class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType1912756633`2') - IL_0017: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: tail. + IL_000e: callvirt instance bool class '<>f__AnonymousType1912756633`2'j__TPar',!'j__TPar'>::Equals(class '<>f__AnonymousType1912756633`2') + IL_0013: ret .line 100001,100001 : 0,0 '' - IL_0018: ldc.i4.0 - IL_0019: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method '<>f__AnonymousType1912756633`2'::Equals .property instance !'j__TPar' A() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ArgumentNamesInClosures01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ArgumentNamesInClosures01.il.bsl index dcaa46948ee..3065bbcf302 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ArgumentNamesInClosures01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ArgumentNamesInClosures01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ArgumentNamesInClosures01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ArgumentNamesInClosures01 { - // Offset: 0x00000000 Length: 0x0000039F + // Offset: 0x00000000 Length: 0x0000039B } .mresource public FSharpOptimizationData.ArgumentNamesInClosures01 { - // Offset: 0x000003A8 Length: 0x0000010D + // Offset: 0x000003A0 Length: 0x0000010D } .module ArgumentNamesInClosures01.dll -// MVID: {59B19213-39CA-41B5-A745-03831392B159} +// MVID: {6124062D-39CA-41B5-A745-03832D062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02A00000 +// Image base: 0x06BD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,14 +58,18 @@ .method public hidebysig instance int32 F(object o) cil managed { - // Code size 9 (0x9) - .maxstack 8 + // Code size 11 (0xb) + .maxstack 3 + .locals init ([0] class M/C x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 36,36 : 29,44 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\ArgumentNamesInClosures01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\ArgumentNamesInClosures01.fs' IL_0000: ldarg.0 - IL_0001: tail. - IL_0003: callvirt instance int32 [mscorlib]System.Object::GetHashCode() - IL_0008: ret + IL_0001: stloc.0 + .line 36,36 : 29,44 '' + IL_0002: ldarg.0 + IL_0003: tail. + IL_0005: callvirt instance int32 [mscorlib]System.Object::GetHashCode() + IL_000a: ret } // end of method C::F } // end of class C @@ -92,11 +96,15 @@ instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 get_F() cil managed { - // Code size 6 (0x6) - .maxstack 8 + // Code size 8 (0x8) + .maxstack 3 + .locals init ([0] class M/T x) + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: stloc.0 .line 41,41 : 22,23 '' - IL_0000: newobj instance void M/get_F@41::.ctor() - IL_0005: ret + IL_0002: ldsfld class M/get_F@41 M/get_F@41::@_instance + IL_0007: ret } // end of method T::get_F .property instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 @@ -109,6 +117,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit get_F@41 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class M/get_F@41 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -133,6 +142,16 @@ IL_0008: ret } // end of method get_F@41::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void M/get_F@41::.ctor() + IL_0005: stsfld class M/get_F@41 M/get_F@41::@_instance + IL_000a: ret + } // end of method get_F@41::.cctor + } // end of class get_F@41 .method public static int32 I(class M/C i_want_to_see_this_identifier) cil managed diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CodeGenRenamings01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CodeGenRenamings01.il.bsl index 6fab8d600ef..63fa4df14a2 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CodeGenRenamings01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CodeGenRenamings01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CodeGenRenamings01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CodeGenRenamings01 { - // Offset: 0x00000000 Length: 0x000003CC + // Offset: 0x00000000 Length: 0x000003C8 } .mresource public FSharpOptimizationData.CodeGenRenamings01 { // Offset: 0x000003D0 Length: 0x0000011B } .module CodeGenRenamings01.exe -// MVID: {59B19213-8173-986B-A745-03831392B159} +// MVID: {611B0EC4-8173-986B-A745-0383C40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010A0000 +// Image base: 0x06620000 // =============== CLASS MEMBERS DECLARATION =================== @@ -83,74 +83,68 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed { - // Code size 103 (0x67) + // Code size 97 (0x61) .maxstack 7 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\CodeGenRenamings01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\CodeGenRenamings01.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 CodeGenRenamings01/seq1@9::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0041 + IL_001b: nop + IL_001c: br.s IL_003b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0057 + IL_001e: nop + IL_001f: br.s IL_0051 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_005e + IL_0021: nop + IL_0022: br.s IL_0058 .line 100001,100001 : 0,0 '' - IL_002a: nop - IL_002b: ldarg.0 - IL_002c: ldc.i4.1 - IL_002d: stfld int32 CodeGenRenamings01/seq1@9::pc + IL_0024: nop .line 9,9 : 18,30 '' - IL_0032: ldarg.0 - IL_0033: ldc.i4.1 - IL_0034: ldc.i4.1 - IL_0035: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 CodeGenRenamings01/seq1@9::pc + IL_002c: ldarg.0 + IL_002d: ldc.i4.1 + IL_002e: ldc.i4.1 + IL_002f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_003a: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current - IL_003f: ldc.i4.1 - IL_0040: ret + IL_0034: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current + IL_0039: ldc.i4.1 + IL_003a: ret - IL_0041: ldarg.0 - IL_0042: ldc.i4.2 - IL_0043: stfld int32 CodeGenRenamings01/seq1@9::pc .line 9,9 : 32,44 '' - IL_0048: ldarg.0 - IL_0049: ldc.i4.2 - IL_004a: ldc.i4.2 - IL_004b: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_003b: ldarg.0 + IL_003c: ldc.i4.2 + IL_003d: stfld int32 CodeGenRenamings01/seq1@9::pc + IL_0042: ldarg.0 + IL_0043: ldc.i4.2 + IL_0044: ldc.i4.2 + IL_0045: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0050: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current - IL_0055: ldc.i4.1 - IL_0056: ret - - IL_0057: ldarg.0 - IL_0058: ldc.i4.3 - IL_0059: stfld int32 CodeGenRenamings01/seq1@9::pc - IL_005e: ldarg.0 - IL_005f: ldnull - IL_0060: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current - IL_0065: ldc.i4.0 - IL_0066: ret + IL_004a: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current + IL_004f: ldc.i4.1 + IL_0050: ret + + IL_0051: ldarg.0 + IL_0052: ldc.i4.3 + IL_0053: stfld int32 CodeGenRenamings01/seq1@9::pc + IL_0058: ldarg.0 + IL_0059: ldnull + IL_005a: stfld class [mscorlib]System.Tuple`2 CodeGenRenamings01/seq1@9::current + IL_005f: ldc.i4.0 + IL_0060: ret } // end of method seq1@9::GenerateNext .method public strict virtual instance void @@ -167,52 +161,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 CodeGenRenamings01/seq1@9::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method seq1@9::get_CheckClose .method public strict virtual instance class [mscorlib]System.Tuple`2 @@ -436,8 +422,8 @@ .method public static void main@() cil managed { .entrypoint - // Code size 567 (0x237) - .maxstack 12 + // Code size 583 (0x247) + .maxstack 8 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 alist, [1] int32[] 'array', [2] class [mscorlib]System.Collections.Generic.IEnumerable`1 aseq, @@ -449,12 +435,16 @@ [8] int32[0...,0...,0...,0...] array4D, [9] int32[] a1, [10] int32[] a2, - [11] class [mscorlib]System.Tuple`4 V_11, - [12] class [mscorlib]System.Tuple`4 V_12, - [13] class [mscorlib]System.Tuple`3 V_13, - [14] class [mscorlib]System.Tuple`3 V_14, - [15] class [mscorlib]System.Tuple`4 V_15, - [16] class [mscorlib]System.Tuple`4 V_16) + [11] int32 'Pipe #1 input at line 27', + [12] class [mscorlib]System.Tuple`4 'Pipe #2 input at line 30', + [13] class [mscorlib]System.Tuple`4 V_13, + [14] int32 'Pipe #3 input at line 31', + [15] class [mscorlib]System.Tuple`3 'Pipe #4 input at line 34', + [16] class [mscorlib]System.Tuple`3 V_16, + [17] int32 'Pipe #5 input at line 35', + [18] class [mscorlib]System.Tuple`4 'Pipe #6 input at line 38', + [19] class [mscorlib]System.Tuple`4 V_19, + [20] int32 'Pipe #7 input at line 39') .line 5,5 : 1,24 '' IL_0000: ldc.i4.1 IL_0001: ldc.i4.1 @@ -485,7 +475,6 @@ IL_0038: dup IL_0039: stsfld int32[] ''.$CodeGenRenamings01::array@6 IL_003e: stloc.1 - .line 7,7 : 1,27 '' IL_003f: ldc.i4.1 IL_0040: ldc.i4.1 IL_0041: ldc.i4.s 10 @@ -608,66 +597,70 @@ IL_0137: dup IL_0138: stsfld int32[] ''.$CodeGenRenamings01::a2@26 IL_013d: stloc.s a2 - .line 27,27 : 1,33 '' - IL_013f: call int32[] CodeGenRenamings01::get_a2() + .line 27,27 : 1,15 '' + IL_013f: call int32[] CodeGenRenamings01::get_a1() IL_0144: ldc.i4.0 - IL_0145: call int32[] CodeGenRenamings01::get_a1() - IL_014a: ldc.i4.0 - IL_014b: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Get(!!0[], + IL_0145: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Get(!!0[], int32) - IL_0150: call void [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Set(!!0[], + IL_014a: stloc.s 'Pipe #1 input at line 27' + .line 27,27 : 19,33 '' + IL_014c: call int32[] CodeGenRenamings01::get_a2() + IL_0151: ldc.i4.0 + IL_0152: ldloc.s 'Pipe #1 input at line 27' + IL_0154: call void [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Set(!!0[], int32, !!0) - IL_0155: nop - .line 30,30 : 1,87 '' - IL_0156: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_015b: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Length1(!!0[0...,0...]) - IL_0160: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_0165: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Length2(!!0[0...,0...]) - IL_016a: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_016f: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Base1(!!0[0...,0...]) - IL_0174: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_0179: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Base2(!!0[0...,0...]) - IL_017e: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, + IL_0159: nop + .line 30,30 : 2,76 '' + IL_015a: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_015f: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Length1(!!0[0...,0...]) + IL_0164: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_0169: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Length2(!!0[0...,0...]) + IL_016e: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_0173: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Base1(!!0[0...,0...]) + IL_0178: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_017d: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Base2(!!0[0...,0...]) + IL_0182: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, !1, !2, !3) - IL_0183: stloc.s V_11 - IL_0185: ldloc.s V_11 - IL_0187: stloc.s V_12 - .line 31,31 : 1,41 '' - IL_0189: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_018e: ldc.i4.0 - IL_018f: ldc.i4.0 - IL_0190: call int32[0...,0...] CodeGenRenamings01::get_a3() - IL_0195: ldc.i4.0 - IL_0196: ldc.i4.0 - IL_0197: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Get(!!0[0...,0...], + IL_0187: stloc.s 'Pipe #2 input at line 30' + .line 30,30 : 81,87 '' + IL_0189: ldloc.s 'Pipe #2 input at line 30' + IL_018b: stloc.s V_13 + .line 31,31 : 1,19 '' + IL_018d: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_0192: ldc.i4.0 + IL_0193: ldc.i4.0 + IL_0194: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Get(!!0[0...,0...], int32, int32) - IL_019c: call void [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Set(!!0[0...,0...], + IL_0199: stloc.s 'Pipe #3 input at line 31' + .line 31,31 : 23,41 '' + IL_019b: call int32[0...,0...] CodeGenRenamings01::get_a3() + IL_01a0: ldc.i4.0 + IL_01a1: ldc.i4.0 + IL_01a2: ldloc.s 'Pipe #3 input at line 31' + IL_01a4: call void [FSharp.Core]Microsoft.FSharp.Collections.Array2DModule::Set(!!0[0...,0...], int32, int32, !!0) - IL_01a1: nop - .line 34,34 : 1,86 '' - IL_01a2: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() - IL_01a7: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length1(!!0[0...,0...,0...]) - IL_01ac: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() - IL_01b1: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length2(!!0[0...,0...,0...]) - IL_01b6: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() - IL_01bb: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length3(!!0[0...,0...,0...]) - IL_01c0: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, + IL_01a9: nop + .line 34,34 : 2,75 '' + IL_01aa: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() + IL_01af: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length1(!!0[0...,0...,0...]) + IL_01b4: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() + IL_01b9: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length2(!!0[0...,0...,0...]) + IL_01be: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() + IL_01c3: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Length3(!!0[0...,0...,0...]) + IL_01c8: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, !1, !2) - IL_01c5: stloc.s V_13 - IL_01c7: ldloc.s V_13 - IL_01c9: stloc.s V_14 - .line 35,35 : 1,55 '' - IL_01cb: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() - IL_01d0: ldc.i4.0 - IL_01d1: ldc.i4.0 - IL_01d2: ldc.i4.0 + IL_01cd: stloc.s 'Pipe #4 input at line 34' + .line 34,34 : 80,86 '' + IL_01cf: ldloc.s 'Pipe #4 input at line 34' + IL_01d1: stloc.s V_16 + .line 35,35 : 1,26 '' IL_01d3: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() IL_01d8: ldc.i4.0 IL_01d9: ldc.i4.0 @@ -676,52 +669,63 @@ int32, int32, int32) - IL_01e0: call void [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Set(!!0[0...,0...,0...], + IL_01e0: stloc.s 'Pipe #5 input at line 35' + .line 35,35 : 30,55 '' + IL_01e2: call int32[0...,0...,0...] CodeGenRenamings01::get_array3D() + IL_01e7: ldc.i4.0 + IL_01e8: ldc.i4.0 + IL_01e9: ldc.i4.0 + IL_01ea: ldloc.s 'Pipe #5 input at line 35' + IL_01ec: call void [FSharp.Core]Microsoft.FSharp.Collections.Array3DModule::Set(!!0[0...,0...,0...], int32, int32, int32, !!0) - IL_01e5: nop - .line 38,38 : 1,111 '' - IL_01e6: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_01eb: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length1(!!0[0...,0...,0...,0...]) - IL_01f0: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_01f5: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length2(!!0[0...,0...,0...,0...]) - IL_01fa: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_01ff: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length3(!!0[0...,0...,0...,0...]) - IL_0204: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_0209: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length4(!!0[0...,0...,0...,0...]) - IL_020e: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, + IL_01f1: nop + .line 38,38 : 2,100 '' + IL_01f2: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() + IL_01f7: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length1(!!0[0...,0...,0...,0...]) + IL_01fc: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() + IL_0201: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length2(!!0[0...,0...,0...,0...]) + IL_0206: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() + IL_020b: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length3(!!0[0...,0...,0...,0...]) + IL_0210: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() + IL_0215: call int32 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Length4(!!0[0...,0...,0...,0...]) + IL_021a: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, !1, !2, !3) - IL_0213: stloc.s V_15 - IL_0215: ldloc.s V_15 - IL_0217: stloc.s V_16 - .line 39,39 : 1,59 '' - IL_0219: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_021e: ldc.i4.0 - IL_021f: ldc.i4.0 - IL_0220: ldc.i4.0 - IL_0221: ldc.i4.0 - IL_0222: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() - IL_0227: ldc.i4.0 - IL_0228: ldc.i4.0 - IL_0229: ldc.i4.0 + IL_021f: stloc.s 'Pipe #6 input at line 38' + .line 38,38 : 105,111 '' + IL_0221: ldloc.s 'Pipe #6 input at line 38' + IL_0223: stloc.s V_19 + .line 39,39 : 1,28 '' + IL_0225: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() IL_022a: ldc.i4.0 - IL_022b: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Get(!!0[0...,0...,0...,0...], + IL_022b: ldc.i4.0 + IL_022c: ldc.i4.0 + IL_022d: ldc.i4.0 + IL_022e: call !!0 [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Get(!!0[0...,0...,0...,0...], int32, int32, int32, int32) - IL_0230: call void [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Set(!!0[0...,0...,0...,0...], + IL_0233: stloc.s 'Pipe #7 input at line 39' + .line 39,39 : 32,59 '' + IL_0235: call int32[0...,0...,0...,0...] CodeGenRenamings01::get_array4D() + IL_023a: ldc.i4.0 + IL_023b: ldc.i4.0 + IL_023c: ldc.i4.0 + IL_023d: ldc.i4.0 + IL_023e: ldloc.s 'Pipe #7 input at line 39' + IL_0240: call void [FSharp.Core]Microsoft.FSharp.Collections.Array4DModule::Set(!!0[0...,0...,0...,0...], int32, int32, int32, int32, !!0) - IL_0235: nop - IL_0236: ret + IL_0245: nop + IL_0246: ret } // end of method $CodeGenRenamings01::main@ } // end of class ''.$CodeGenRenamings01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CustomAttributeGenericParameter01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CustomAttributeGenericParameter01.il.bsl index 63d76598150..f3c32848290 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CustomAttributeGenericParameter01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/CustomAttributeGenericParameter01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly CustomAttributeGenericParameter01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.CustomAttributeGenericParameter01 { - // Offset: 0x00000000 Length: 0x000002C2 + // Offset: 0x00000000 Length: 0x000002BE } .mresource public FSharpOptimizationData.CustomAttributeGenericParameter01 { // Offset: 0x000002C8 Length: 0x0000007A } .module CustomAttributeGenericParameter01.exe -// MVID: {59B19213-F08A-F524-A745-03831392B159} +// MVID: {60B68B7F-F08A-F524-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x001D0000 +// Image base: 0x05340000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 48,49 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\CustomAttributeGenericParameter01.fs' + .line 4,4 : 48,49 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\CustomAttributeGenericParameter01.fs' IL_0000: ldarg.0 IL_0001: ret } // end of method M::f diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Decimal01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Decimal01.il.bsl index d4e75ea07e1..b0c34bdda4a 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Decimal01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Decimal01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Decimal01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Decimal01 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Decimal01 { - // Offset: 0x00000148 Length: 0x00000050 + // Offset: 0x00000140 Length: 0x00000050 } .module Decimal01.exe -// MVID: {59B19213-F150-FA46-A745-03831392B159} +// MVID: {60B68B7F-F150-FA46-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x05600000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,17 +71,17 @@ // Code size 13 (0xd) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 9,13 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\Decimal01.fs' + .line 6,6 : 9,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\Decimal01.fs' IL_0000: ldc.i4.s 12 IL_0002: ldc.i4.0 IL_0003: ldc.i4.0 IL_0004: ldc.i4.0 IL_0005: ldc.i4.1 - IL_0006: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_0006: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_000b: pop IL_000c: ret } // end of method $Decimal01::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EntryPoint01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EntryPoint01.il.bsl index 4768f783d4c..d17322d83b4 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EntryPoint01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EntryPoint01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly EntryPoint01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.EntryPoint01 { - // Offset: 0x00000000 Length: 0x00000253 + // Offset: 0x00000000 Length: 0x0000024F } .mresource public FSharpOptimizationData.EntryPoint01 { // Offset: 0x00000258 Length: 0x00000090 } .module EntryPoint01.exe -// MVID: {59B19213-9846-72C1-A745-03831392B159} +// MVID: {611C4D7C-9846-72C1-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00680000 +// Image base: 0x06DA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,37 +66,37 @@ { .entrypoint .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 39 (0x27) + // Code size 37 (0x25) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 9,39 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\EntryPoint01.fs' + .line 8,8 : 4,49 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\EntryPoint01.fs' .line 100001,100001 : 0,0 '' IL_0000: ldc.i4.0 IL_0001: stsfld int32 ''.$EntryPoint01::init@ IL_0006: ldsfld int32 ''.$EntryPoint01::init@ IL_000b: pop - IL_000c: call int32 EntryPoint01::get_static_initializer() - IL_0011: ldc.i4.s 10 - IL_0013: bne.un.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_001d + IL_000c: nop + .line 8,8 : 9,39 '' + IL_000d: nop + .line 100001,100001 : 0,0 '' + IL_000e: call int32 EntryPoint01::get_static_initializer() + IL_0013: ldc.i4.s 10 + IL_0015: bne.un.s IL_001b .line 8,8 : 40,41 '' - IL_0019: ldc.i4.0 + IL_0017: ldc.i4.0 .line 100001,100001 : 0,0 '' - IL_001a: nop - IL_001b: br.s IL_001f + IL_0018: nop + IL_0019: br.s IL_001d .line 8,8 : 47,48 '' - IL_001d: ldc.i4.1 + IL_001b: ldc.i4.1 .line 100001,100001 : 0,0 '' - IL_001e: nop + IL_001c: nop .line 100001,100001 : 0,0 '' - IL_001f: tail. - IL_0021: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Exit(int32) - IL_0026: ret + IL_001d: tail. + IL_001f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Exit(int32) + IL_0024: ret } // end of method EntryPoint01::main .property int32 static_initializer() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl index 5d270545498..ba4e9d4b2d6 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly EqualsOnUnions01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.EqualsOnUnions01 { - // Offset: 0x00000000 Length: 0x0000064B + // Offset: 0x00000000 Length: 0x0000063B } .mresource public FSharpOptimizationData.EqualsOnUnions01 { - // Offset: 0x00000650 Length: 0x000001C7 + // Offset: 0x00000640 Length: 0x000001C7 } .module EqualsOnUnions01.exe -// MVID: {59B19213-BBFB-14A0-A745-03831392B159} +// MVID: {611C52A3-BBFB-14A0-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01350000 +// Image base: 0x04FE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -339,7 +339,7 @@ instance int32 CompareTo(class EqualsOnUnions01/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 158 (0x9e) + // Code size 132 (0x84) .maxstack 4 .locals init ([0] int32 V_0, [1] class EqualsOnUnions01/U V_1, @@ -351,130 +351,110 @@ [7] int32 V_7, [8] int32 V_8) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\EqualsOnUnions01.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_0090 - + .line 6,6 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\EqualsOnUnions01.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_001a - - IL_0015: br IL_008e + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_007a .line 100001,100001 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldloc.1 - IL_001d: isinst EqualsOnUnions01/U/B - IL_0022: brfalse.s IL_0027 + IL_000a: ldarg.1 + IL_000b: ldnull + IL_000c: cgt.un + IL_000e: brfalse.s IL_0078 - IL_0024: ldc.i4.1 - IL_0025: br.s IL_0028 - - IL_0027: ldc.i4.0 - IL_0028: stloc.0 - IL_0029: ldarg.1 - IL_002a: stloc.3 - IL_002b: ldloc.3 - IL_002c: isinst EqualsOnUnions01/U/B - IL_0031: brfalse.s IL_0036 - - IL_0033: ldc.i4.1 - IL_0034: br.s IL_0037 + .line 100001,100001 : 0,0 '' + IL_0010: ldarg.0 + IL_0011: stloc.1 + IL_0012: ldloc.1 + IL_0013: isinst EqualsOnUnions01/U/B + IL_0018: brfalse.s IL_001d - IL_0036: ldc.i4.0 - IL_0037: stloc.2 - IL_0038: ldloc.0 - IL_0039: ldloc.2 - IL_003a: bne.un.s IL_003e + IL_001a: ldc.i4.1 + IL_001b: br.s IL_001e - IL_003c: br.s IL_0040 + IL_001d: ldc.i4.0 + IL_001e: stloc.0 + IL_001f: ldarg.1 + IL_0020: stloc.3 + IL_0021: ldloc.3 + IL_0022: isinst EqualsOnUnions01/U/B + IL_0027: brfalse.s IL_002c - IL_003e: br.s IL_008a + IL_0029: ldc.i4.1 + IL_002a: br.s IL_002d + IL_002c: ldc.i4.0 + IL_002d: stloc.2 .line 100001,100001 : 0,0 '' - IL_0040: ldarg.0 - IL_0041: isinst EqualsOnUnions01/U/B - IL_0046: brfalse.s IL_004a - - IL_0048: br.s IL_004c - - IL_004a: br.s IL_0088 + IL_002e: ldloc.0 + IL_002f: ldloc.2 + IL_0030: bne.un.s IL_0074 .line 100001,100001 : 0,0 '' - IL_004c: ldarg.0 - IL_004d: castclass EqualsOnUnions01/U/B - IL_0052: stloc.s V_4 - IL_0054: ldarg.1 - IL_0055: castclass EqualsOnUnions01/U/B - IL_005a: stloc.s V_5 - IL_005c: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0061: stloc.s V_6 - IL_0063: ldloc.s V_4 - IL_0065: ldfld int32 EqualsOnUnions01/U/B::item - IL_006a: stloc.s V_7 - IL_006c: ldloc.s V_5 - IL_006e: ldfld int32 EqualsOnUnions01/U/B::item - IL_0073: stloc.s V_8 - IL_0075: ldloc.s V_7 - IL_0077: ldloc.s V_8 - IL_0079: bge.s IL_007d - - IL_007b: br.s IL_007f - - IL_007d: br.s IL_0081 + IL_0032: ldarg.0 + IL_0033: isinst EqualsOnUnions01/U/B + IL_0038: brfalse.s IL_0072 .line 100001,100001 : 0,0 '' - IL_007f: ldc.i4.m1 - IL_0080: ret - + IL_003a: ldarg.0 + IL_003b: castclass EqualsOnUnions01/U/B + IL_0040: stloc.s V_4 + IL_0042: ldarg.1 + IL_0043: castclass EqualsOnUnions01/U/B + IL_0048: stloc.s V_5 + IL_004a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004f: stloc.s V_6 + IL_0051: ldloc.s V_4 + IL_0053: ldfld int32 EqualsOnUnions01/U/B::item + IL_0058: stloc.s V_7 + IL_005a: ldloc.s V_5 + IL_005c: ldfld int32 EqualsOnUnions01/U/B::item + IL_0061: stloc.s V_8 .line 100001,100001 : 0,0 '' - IL_0081: ldloc.s V_7 - IL_0083: ldloc.s V_8 - IL_0085: cgt - IL_0087: ret + IL_0063: ldloc.s V_7 + IL_0065: ldloc.s V_8 + IL_0067: bge.s IL_006b .line 100001,100001 : 0,0 '' - IL_0088: ldc.i4.0 - IL_0089: ret + IL_0069: ldc.i4.m1 + IL_006a: ret .line 100001,100001 : 0,0 '' - IL_008a: ldloc.0 - IL_008b: ldloc.2 - IL_008c: sub - IL_008d: ret + IL_006b: ldloc.s V_7 + IL_006d: ldloc.s V_8 + IL_006f: cgt + IL_0071: ret .line 100001,100001 : 0,0 '' - IL_008e: ldc.i4.1 - IL_008f: ret + IL_0072: ldc.i4.0 + IL_0073: ret .line 100001,100001 : 0,0 '' - IL_0090: ldarg.1 - IL_0091: ldnull - IL_0092: cgt.un - IL_0094: brfalse.s IL_0098 + IL_0074: ldloc.0 + IL_0075: ldloc.2 + IL_0076: sub + IL_0077: ret - IL_0096: br.s IL_009a + .line 100001,100001 : 0,0 '' + IL_0078: ldc.i4.1 + IL_0079: ret - IL_0098: br.s IL_009c + .line 100001,100001 : 0,0 '' + IL_007a: ldarg.1 + IL_007b: ldnull + IL_007c: cgt.un + IL_007e: brfalse.s IL_0082 .line 100001,100001 : 0,0 '' - IL_009a: ldc.i4.m1 - IL_009b: ret + IL_0080: ldc.i4.m1 + IL_0081: ret .line 100001,100001 : 0,0 '' - IL_009c: ldc.i4.0 - IL_009d: ret + IL_0082: ldc.i4.0 + IL_0083: ret } // end of method U::CompareTo .method public hidebysig virtual final @@ -496,7 +476,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 173 (0xad) + // Code size 146 (0x92) .maxstack 4 .locals init ([0] class EqualsOnUnions01/U V_0, [1] int32 V_1, @@ -512,204 +492,178 @@ IL_0000: ldarg.1 IL_0001: unbox.any EqualsOnUnions01/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0014 - - IL_000f: br IL_009a + IL_000b: brfalse IL_0083 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.1 - IL_0015: unbox.any EqualsOnUnions01/U - IL_001a: ldnull - IL_001b: cgt.un - IL_001d: brfalse.s IL_0021 - - IL_001f: br.s IL_0026 - - IL_0021: br IL_0098 + IL_0010: ldarg.1 + IL_0011: unbox.any EqualsOnUnions01/U + IL_0016: ldnull + IL_0017: cgt.un + IL_0019: brfalse.s IL_0081 .line 100001,100001 : 0,0 '' - IL_0026: ldarg.0 - IL_0027: stloc.2 - IL_0028: ldloc.2 - IL_0029: isinst EqualsOnUnions01/U/B - IL_002e: brfalse.s IL_0033 - - IL_0030: ldc.i4.1 - IL_0031: br.s IL_0034 - - IL_0033: ldc.i4.0 - IL_0034: stloc.1 - IL_0035: ldloc.0 - IL_0036: stloc.s V_4 - IL_0038: ldloc.s V_4 - IL_003a: isinst EqualsOnUnions01/U/B - IL_003f: brfalse.s IL_0044 - - IL_0041: ldc.i4.1 - IL_0042: br.s IL_0045 + IL_001b: ldarg.0 + IL_001c: stloc.2 + IL_001d: ldloc.2 + IL_001e: isinst EqualsOnUnions01/U/B + IL_0023: brfalse.s IL_0028 - IL_0044: ldc.i4.0 - IL_0045: stloc.3 - IL_0046: ldloc.1 - IL_0047: ldloc.3 - IL_0048: bne.un.s IL_004c + IL_0025: ldc.i4.1 + IL_0026: br.s IL_0029 - IL_004a: br.s IL_004e + IL_0028: ldc.i4.0 + IL_0029: stloc.1 + IL_002a: ldloc.0 + IL_002b: stloc.s V_4 + IL_002d: ldloc.s V_4 + IL_002f: isinst EqualsOnUnions01/U/B + IL_0034: brfalse.s IL_0039 - IL_004c: br.s IL_0094 + IL_0036: ldc.i4.1 + IL_0037: br.s IL_003a + IL_0039: ldc.i4.0 + IL_003a: stloc.3 .line 100001,100001 : 0,0 '' - IL_004e: ldarg.0 - IL_004f: isinst EqualsOnUnions01/U/B - IL_0054: brfalse.s IL_0058 - - IL_0056: br.s IL_005a - - IL_0058: br.s IL_0092 + IL_003b: ldloc.1 + IL_003c: ldloc.3 + IL_003d: bne.un.s IL_007d .line 100001,100001 : 0,0 '' - IL_005a: ldarg.0 - IL_005b: castclass EqualsOnUnions01/U/B - IL_0060: stloc.s V_5 - IL_0062: ldloc.0 - IL_0063: castclass EqualsOnUnions01/U/B - IL_0068: stloc.s V_6 - IL_006a: ldarg.2 - IL_006b: stloc.s V_7 - IL_006d: ldloc.s V_5 - IL_006f: ldfld int32 EqualsOnUnions01/U/B::item - IL_0074: stloc.s V_8 - IL_0076: ldloc.s V_6 - IL_0078: ldfld int32 EqualsOnUnions01/U/B::item - IL_007d: stloc.s V_9 - IL_007f: ldloc.s V_8 - IL_0081: ldloc.s V_9 - IL_0083: bge.s IL_0087 - - IL_0085: br.s IL_0089 - - IL_0087: br.s IL_008b + IL_003f: ldarg.0 + IL_0040: isinst EqualsOnUnions01/U/B + IL_0045: brfalse.s IL_007b .line 100001,100001 : 0,0 '' - IL_0089: ldc.i4.m1 - IL_008a: ret - + IL_0047: ldarg.0 + IL_0048: castclass EqualsOnUnions01/U/B + IL_004d: stloc.s V_5 + IL_004f: ldloc.0 + IL_0050: castclass EqualsOnUnions01/U/B + IL_0055: stloc.s V_6 + IL_0057: ldarg.2 + IL_0058: stloc.s V_7 + IL_005a: ldloc.s V_5 + IL_005c: ldfld int32 EqualsOnUnions01/U/B::item + IL_0061: stloc.s V_8 + IL_0063: ldloc.s V_6 + IL_0065: ldfld int32 EqualsOnUnions01/U/B::item + IL_006a: stloc.s V_9 .line 100001,100001 : 0,0 '' - IL_008b: ldloc.s V_8 - IL_008d: ldloc.s V_9 - IL_008f: cgt - IL_0091: ret + IL_006c: ldloc.s V_8 + IL_006e: ldloc.s V_9 + IL_0070: bge.s IL_0074 .line 100001,100001 : 0,0 '' - IL_0092: ldc.i4.0 - IL_0093: ret + IL_0072: ldc.i4.m1 + IL_0073: ret .line 100001,100001 : 0,0 '' - IL_0094: ldloc.1 - IL_0095: ldloc.3 - IL_0096: sub - IL_0097: ret + IL_0074: ldloc.s V_8 + IL_0076: ldloc.s V_9 + IL_0078: cgt + IL_007a: ret .line 100001,100001 : 0,0 '' - IL_0098: ldc.i4.1 - IL_0099: ret + IL_007b: ldc.i4.0 + IL_007c: ret .line 100001,100001 : 0,0 '' - IL_009a: ldarg.1 - IL_009b: unbox.any EqualsOnUnions01/U - IL_00a0: ldnull - IL_00a1: cgt.un - IL_00a3: brfalse.s IL_00a7 + IL_007d: ldloc.1 + IL_007e: ldloc.3 + IL_007f: sub + IL_0080: ret - IL_00a5: br.s IL_00a9 + .line 100001,100001 : 0,0 '' + IL_0081: ldc.i4.1 + IL_0082: ret - IL_00a7: br.s IL_00ab + .line 100001,100001 : 0,0 '' + IL_0083: ldarg.1 + IL_0084: unbox.any EqualsOnUnions01/U + IL_0089: ldnull + IL_008a: cgt.un + IL_008c: brfalse.s IL_0090 .line 100001,100001 : 0,0 '' - IL_00a9: ldc.i4.m1 - IL_00aa: ret + IL_008e: ldc.i4.m1 + IL_008f: ret .line 100001,100001 : 0,0 '' - IL_00ab: ldc.i4.0 - IL_00ac: ret + IL_0090: ldc.i4.0 + IL_0091: ret } // end of method U::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 75 (0x4b) + // Code size 68 (0x44) .maxstack 7 .locals init ([0] int32 V_0, [1] class EqualsOnUnions01/U/B V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2, [3] class EqualsOnUnions01/U V_3) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0049 - - .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: isinst EqualsOnUnions01/U/B - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_003a - - .line 100001,100001 : 0,0 '' - IL_0018: ldarg.0 - IL_0019: castclass EqualsOnUnions01/U/B - IL_001e: stloc.1 - IL_001f: ldc.i4.1 - IL_0020: stloc.0 - IL_0021: ldc.i4 0x9e3779b9 - IL_0026: ldarg.1 - IL_0027: stloc.2 - IL_0028: ldloc.1 - IL_0029: ldfld int32 EqualsOnUnions01/U/B::item - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl + .line 6,6 : 6,7 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0042 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: isinst EqualsOnUnions01/U/B + IL_000f: brfalse.s IL_0033 + + .line 100001,100001 : 0,0 '' + IL_0011: ldarg.0 + IL_0012: castclass EqualsOnUnions01/U/B + IL_0017: stloc.1 + IL_0018: ldc.i4.1 + IL_0019: stloc.0 + IL_001a: ldc.i4 0x9e3779b9 + IL_001f: ldarg.1 + IL_0020: stloc.2 + IL_0021: ldloc.1 + IL_0022: ldfld int32 EqualsOnUnions01/U/B::item + IL_0027: ldloc.0 + IL_0028: ldc.i4.6 + IL_0029: shl + IL_002a: ldloc.0 + IL_002b: ldc.i4.2 + IL_002c: shr + IL_002d: add + IL_002e: add + IL_002f: add + IL_0030: stloc.0 IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add - IL_0035: add - IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0032: ret .line 100001,100001 : 0,0 '' - IL_003a: ldarg.0 - IL_003b: stloc.3 - IL_003c: ldloc.3 - IL_003d: isinst EqualsOnUnions01/U/B - IL_0042: brfalse.s IL_0047 + IL_0033: ldarg.0 + IL_0034: stloc.3 + IL_0035: ldloc.3 + IL_0036: isinst EqualsOnUnions01/U/B + IL_003b: brfalse.s IL_0040 - IL_0044: ldc.i4.1 - IL_0045: br.s IL_0048 + IL_003d: ldc.i4.1 + IL_003e: br.s IL_0041 - IL_0047: ldc.i4.0 - IL_0048: ret + IL_0040: ldc.i4.0 + IL_0041: ret .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.0 - IL_004a: ret + IL_0042: ldc.i4.0 + IL_0043: ret } // end of method U::GetHashCode .method public hidebysig virtual final @@ -730,7 +684,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 133 (0x85) + // Code size 115 (0x73) .maxstack 4 .locals init ([0] class EqualsOnUnions01/U V_0, [1] class EqualsOnUnions01/U V_1, @@ -741,111 +695,99 @@ [6] class EqualsOnUnions01/U/B V_6, [7] class EqualsOnUnions01/U/B V_7, [8] class [mscorlib]System.Collections.IEqualityComparer V_8) + .line 6,6 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006b - IL_0008: br IL_007d + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst EqualsOnUnions01/U + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0069 .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: isinst EqualsOnUnions01/U - IL_0013: stloc.0 - IL_0014: ldloc.0 - IL_0015: brfalse.s IL_0019 + IL_0011: ldloc.0 + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: isinst EqualsOnUnions01/U/B + IL_001b: brfalse.s IL_0020 - IL_0017: br.s IL_001b + IL_001d: ldc.i4.1 + IL_001e: br.s IL_0021 - IL_0019: br.s IL_007b + IL_0020: ldc.i4.0 + IL_0021: stloc.2 + IL_0022: ldloc.1 + IL_0023: stloc.s V_5 + IL_0025: ldloc.s V_5 + IL_0027: isinst EqualsOnUnions01/U/B + IL_002c: brfalse.s IL_0031 - .line 100001,100001 : 0,0 '' - IL_001b: ldloc.0 - IL_001c: stloc.1 - IL_001d: ldarg.0 - IL_001e: stloc.3 - IL_001f: ldloc.3 - IL_0020: isinst EqualsOnUnions01/U/B - IL_0025: brfalse.s IL_002a - - IL_0027: ldc.i4.1 - IL_0028: br.s IL_002b - - IL_002a: ldc.i4.0 - IL_002b: stloc.2 - IL_002c: ldloc.1 - IL_002d: stloc.s V_5 - IL_002f: ldloc.s V_5 - IL_0031: isinst EqualsOnUnions01/U/B - IL_0036: brfalse.s IL_003b - - IL_0038: ldc.i4.1 - IL_0039: br.s IL_003c - - IL_003b: ldc.i4.0 - IL_003c: stloc.s V_4 - IL_003e: ldloc.2 - IL_003f: ldloc.s V_4 - IL_0041: bne.un.s IL_0045 - - IL_0043: br.s IL_0047 - - IL_0045: br.s IL_0079 + IL_002e: ldc.i4.1 + IL_002f: br.s IL_0032 + IL_0031: ldc.i4.0 + IL_0032: stloc.s V_4 .line 100001,100001 : 0,0 '' - IL_0047: ldarg.0 - IL_0048: isinst EqualsOnUnions01/U/B - IL_004d: brfalse.s IL_0051 - - IL_004f: br.s IL_0053 + IL_0034: ldloc.2 + IL_0035: ldloc.s V_4 + IL_0037: bne.un.s IL_0067 - IL_0051: br.s IL_0077 + .line 100001,100001 : 0,0 '' + IL_0039: ldarg.0 + IL_003a: isinst EqualsOnUnions01/U/B + IL_003f: brfalse.s IL_0065 .line 100001,100001 : 0,0 '' - IL_0053: ldarg.0 - IL_0054: castclass EqualsOnUnions01/U/B - IL_0059: stloc.s V_6 - IL_005b: ldloc.1 - IL_005c: castclass EqualsOnUnions01/U/B - IL_0061: stloc.s V_7 - IL_0063: ldarg.2 - IL_0064: stloc.s V_8 - IL_0066: ldloc.s V_6 - IL_0068: ldfld int32 EqualsOnUnions01/U/B::item - IL_006d: ldloc.s V_7 - IL_006f: ldfld int32 EqualsOnUnions01/U/B::item - IL_0074: ceq - IL_0076: ret + IL_0041: ldarg.0 + IL_0042: castclass EqualsOnUnions01/U/B + IL_0047: stloc.s V_6 + IL_0049: ldloc.1 + IL_004a: castclass EqualsOnUnions01/U/B + IL_004f: stloc.s V_7 + IL_0051: ldarg.2 + IL_0052: stloc.s V_8 + IL_0054: ldloc.s V_6 + IL_0056: ldfld int32 EqualsOnUnions01/U/B::item + IL_005b: ldloc.s V_7 + IL_005d: ldfld int32 EqualsOnUnions01/U/B::item + IL_0062: ceq + IL_0064: ret .line 100001,100001 : 0,0 '' - IL_0077: ldc.i4.1 - IL_0078: ret + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_0079: ldc.i4.0 - IL_007a: ret + IL_0067: ldc.i4.0 + IL_0068: ret .line 100001,100001 : 0,0 '' - IL_007b: ldc.i4.0 - IL_007c: ret + IL_0069: ldc.i4.0 + IL_006a: ret .line 100001,100001 : 0,0 '' - IL_007d: ldarg.1 - IL_007e: ldnull - IL_007f: cgt.un - IL_0081: ldc.i4.0 - IL_0082: ceq - IL_0084: ret + IL_006b: ldarg.1 + IL_006c: ldnull + IL_006d: cgt.un + IL_006f: ldc.i4.0 + IL_0070: ceq + IL_0072: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(class EqualsOnUnions01/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 120 (0x78) + // Code size 102 (0x66) .maxstack 4 .locals init ([0] int32 V_0, [1] class EqualsOnUnions01/U V_1, @@ -853,128 +795,112 @@ [3] class EqualsOnUnions01/U V_3, [4] class EqualsOnUnions01/U/B V_4, [5] class EqualsOnUnions01/U/B V_5) + .line 6,6 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_0070 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_005e .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_0017 - - IL_0015: br.s IL_006e + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_005c .line 100001,100001 : 0,0 '' - IL_0017: ldarg.0 - IL_0018: stloc.1 - IL_0019: ldloc.1 - IL_001a: isinst EqualsOnUnions01/U/B - IL_001f: brfalse.s IL_0024 + IL_000d: ldarg.0 + IL_000e: stloc.1 + IL_000f: ldloc.1 + IL_0010: isinst EqualsOnUnions01/U/B + IL_0015: brfalse.s IL_001a - IL_0021: ldc.i4.1 - IL_0022: br.s IL_0025 + IL_0017: ldc.i4.1 + IL_0018: br.s IL_001b - IL_0024: ldc.i4.0 - IL_0025: stloc.0 - IL_0026: ldarg.1 - IL_0027: stloc.3 - IL_0028: ldloc.3 - IL_0029: isinst EqualsOnUnions01/U/B - IL_002e: brfalse.s IL_0033 + IL_001a: ldc.i4.0 + IL_001b: stloc.0 + IL_001c: ldarg.1 + IL_001d: stloc.3 + IL_001e: ldloc.3 + IL_001f: isinst EqualsOnUnions01/U/B + IL_0024: brfalse.s IL_0029 - IL_0030: ldc.i4.1 - IL_0031: br.s IL_0034 - - IL_0033: ldc.i4.0 - IL_0034: stloc.2 - IL_0035: ldloc.0 - IL_0036: ldloc.2 - IL_0037: bne.un.s IL_003b - - IL_0039: br.s IL_003d - - IL_003b: br.s IL_006c + IL_0026: ldc.i4.1 + IL_0027: br.s IL_002a + IL_0029: ldc.i4.0 + IL_002a: stloc.2 .line 100001,100001 : 0,0 '' - IL_003d: ldarg.0 - IL_003e: isinst EqualsOnUnions01/U/B - IL_0043: brfalse.s IL_0047 + IL_002b: ldloc.0 + IL_002c: ldloc.2 + IL_002d: bne.un.s IL_005a - IL_0045: br.s IL_0049 - - IL_0047: br.s IL_006a + .line 100001,100001 : 0,0 '' + IL_002f: ldarg.0 + IL_0030: isinst EqualsOnUnions01/U/B + IL_0035: brfalse.s IL_0058 .line 100001,100001 : 0,0 '' - IL_0049: ldarg.0 - IL_004a: castclass EqualsOnUnions01/U/B - IL_004f: stloc.s V_4 - IL_0051: ldarg.1 - IL_0052: castclass EqualsOnUnions01/U/B - IL_0057: stloc.s V_5 - IL_0059: ldloc.s V_4 - IL_005b: ldfld int32 EqualsOnUnions01/U/B::item - IL_0060: ldloc.s V_5 - IL_0062: ldfld int32 EqualsOnUnions01/U/B::item - IL_0067: ceq - IL_0069: ret + IL_0037: ldarg.0 + IL_0038: castclass EqualsOnUnions01/U/B + IL_003d: stloc.s V_4 + IL_003f: ldarg.1 + IL_0040: castclass EqualsOnUnions01/U/B + IL_0045: stloc.s V_5 + IL_0047: ldloc.s V_4 + IL_0049: ldfld int32 EqualsOnUnions01/U/B::item + IL_004e: ldloc.s V_5 + IL_0050: ldfld int32 EqualsOnUnions01/U/B::item + IL_0055: ceq + IL_0057: ret .line 100001,100001 : 0,0 '' - IL_006a: ldc.i4.1 - IL_006b: ret + IL_0058: ldc.i4.1 + IL_0059: ret .line 100001,100001 : 0,0 '' - IL_006c: ldc.i4.0 - IL_006d: ret + IL_005a: ldc.i4.0 + IL_005b: ret .line 100001,100001 : 0,0 '' - IL_006e: ldc.i4.0 - IL_006f: ret + IL_005c: ldc.i4.0 + IL_005d: ret .line 100001,100001 : 0,0 '' - IL_0070: ldarg.1 - IL_0071: ldnull - IL_0072: cgt.un - IL_0074: ldc.i4.0 - IL_0075: ceq - IL_0077: ret + IL_005e: ldarg.1 + IL_005f: ldnull + IL_0060: cgt.un + IL_0062: ldc.i4.0 + IL_0063: ceq + IL_0065: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class EqualsOnUnions01/U V_0) .line 6,6 : 6,7 '' IL_0000: ldarg.1 IL_0001: isinst EqualsOnUnions01/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool EqualsOnUnions01/U::Equals(class EqualsOnUnions01/U) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool EqualsOnUnions01/U::Equals(class EqualsOnUnions01/U) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method U::Equals .property instance int32 Tag() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop01.il.bsl index 0f5a2183244..c748c706949 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ForLoop01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ForLoop01 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.ForLoop01 { - // Offset: 0x00000148 Length: 0x00000050 + // Offset: 0x00000140 Length: 0x00000050 } .module ForLoop01.exe -// MVID: {59B19213-1795-791C-A745-03831392B159} +// MVID: {60BCDCE8-1795-791C-A745-0383E8DCBC60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x070C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,15 +63,13 @@ .method public static void main@() cil managed { .entrypoint - // Code size 80 (0x50) + // Code size 74 (0x4a) .maxstack 5 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, - [2] int32 wi, - [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_3, - [4] int32 V_4) + [2] int32 wi) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 1,24 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\ForLoop01.fs' + .line 5,5 : 1,24 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\ForLoop01.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.1 IL_0002: ldc.i4.3 @@ -89,7 +87,7 @@ IL_001a: ldloc.1 IL_001b: ldnull IL_001c: cgt.un - IL_001e: brfalse.s IL_004f + IL_001e: brfalse.s IL_0049 .line 5,5 : 1,24 '' IL_0020: ldloc.0 @@ -98,23 +96,19 @@ IL_0027: ldstr "%A" IL_002c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_0031: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: stloc.s V_4 - IL_003a: ldloc.3 - IL_003b: ldloc.s V_4 - IL_003d: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0042: pop - IL_0043: ldloc.1 - IL_0044: stloc.0 - IL_0045: ldloc.0 - IL_0046: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_004b: stloc.1 + IL_0036: ldloc.2 + IL_0037: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_003c: pop + IL_003d: ldloc.1 + IL_003e: stloc.0 + IL_003f: ldloc.0 + IL_0040: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0045: stloc.1 .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: br.s IL_001a + IL_0046: nop + IL_0047: br.s IL_001a - IL_004f: ret + IL_0049: ret } // end of method $ForLoop01::main@ } // end of class ''.$ForLoop01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop02.il.bsl index f54c8480177..aa69d91fe75 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ForLoop02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ForLoop02 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.ForLoop02 { - // Offset: 0x00000148 Length: 0x00000050 + // Offset: 0x00000140 Length: 0x00000050 } .module ForLoop02.exe -// MVID: {59B19213-1736-791C-A745-03831392B159} +// MVID: {60BCDCE8-1736-791C-A745-0383E8DCBC60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03030000 +// Image base: 0x068C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,40 +63,34 @@ .method public static void main@() cil managed { .entrypoint - // Code size 41 (0x29) + // Code size 37 (0x25) .maxstack 5 - .locals init ([0] int32 wi, - [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_1, - [2] int32 V_2) + .locals init ([0] int32 wi) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 1,19 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\ForLoop02.fs' + .line 5,5 : 1,19 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\ForLoop02.fs' IL_0000: ldc.i4.1 IL_0001: stloc.0 - IL_0002: br.s IL_0022 + IL_0002: br.s IL_001e .line 6,6 : 5,17 '' IL_0004: ldstr "%A" IL_0009: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_000e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldloc.2 - IL_0018: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001d: pop + IL_0013: ldloc.0 + IL_0014: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0019: pop + IL_001a: ldloc.0 + IL_001b: ldc.i4.1 + IL_001c: add + IL_001d: stloc.0 + .line 5,5 : 1,19 '' IL_001e: ldloc.0 IL_001f: ldc.i4.1 - IL_0020: add - IL_0021: stloc.0 - .line 5,5 : 1,19 '' - IL_0022: ldloc.0 - IL_0023: ldc.i4.1 - IL_0024: ldc.i4.3 - IL_0025: add - IL_0026: blt.s IL_0004 + IL_0020: ldc.i4.3 + IL_0021: add + IL_0022: blt.s IL_0004 - IL_0028: ret + IL_0024: ret } // end of method $ForLoop02::main@ } // end of class ''.$ForLoop02 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop03.il.bsl index e6fda0879b7..d1f71df8ed2 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ForLoop03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ForLoop03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ForLoop03 { - // Offset: 0x00000000 Length: 0x000001FA + // Offset: 0x00000000 Length: 0x000001F6 } .mresource public FSharpOptimizationData.ForLoop03 { // Offset: 0x00000200 Length: 0x0000007B } .module ForLoop03.exe -// MVID: {59B19213-1757-791C-A745-03831392B159} +// MVID: {60BCDCE8-1757-791C-A745-0383E8DCBC60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00680000 +// Image base: 0x066B0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,24 +62,21 @@ .method public static void test1() cil managed { - // Code size 113 (0x71) + // Code size 97 (0x61) .maxstack 5 .locals init ([0] int32 z, [1] int32 i, [2] class [mscorlib]System.Collections.Generic.List`1 V_2, [3] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator V_3, - [4] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_4, - [5] int32 x, - [6] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_6, - [7] int32 V_7) + [4] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 10,10 : 4,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\ForLoop03.fs' + .line 10,10 : 4,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\ForLoop03.fs' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 11,11 : 4,28 '' IL_0002: ldc.i4.0 IL_0003: stloc.1 - IL_0004: br.s IL_0048 + IL_0004: br.s IL_0040 .line 12,12 : 6,20 '' IL_0006: call class [mscorlib]System.Collections.Generic.List`1 ForLoop03::get_ra() @@ -106,46 +103,36 @@ IL_0029: nop IL_002a: br.s IL_0013 - IL_002c: ldnull - IL_002d: stloc.s V_4 - IL_002f: leave.s IL_0041 + IL_002c: leave.s IL_003c } // end .try finally { - IL_0031: ldloca.s V_3 - IL_0033: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator - IL_0039: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_003e: ldnull - IL_003f: pop - IL_0040: endfinally + IL_002e: ldloca.s V_3 + IL_0030: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_003b: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_0041: ldloc.s V_4 - IL_0043: pop - IL_0044: ldloc.1 - IL_0045: ldc.i4.1 - IL_0046: add - IL_0047: stloc.1 + IL_003c: ldloc.1 + IL_003d: ldc.i4.1 + IL_003e: add + IL_003f: stloc.1 .line 11,11 : 4,28 '' - IL_0048: ldloc.1 - IL_0049: ldc.i4.1 - IL_004a: ldc.i4 0x989680 - IL_004f: add - IL_0050: blt.s IL_0006 + IL_0040: ldloc.1 + IL_0041: ldc.i4.1 + IL_0042: ldc.i4 0x989680 + IL_0047: add + IL_0048: blt.s IL_0006 .line 14,14 : 4,20 '' - IL_0052: ldstr "z = %d" - IL_0057: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) - IL_005c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0061: stloc.s V_6 - IL_0063: ldloc.0 - IL_0064: stloc.s V_7 - IL_0066: ldloc.s V_6 - IL_0068: ldloc.s V_7 - IL_006a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_006f: pop - IL_0070: ret + IL_004a: ldstr "z = %d" + IL_004f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_0054: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0059: ldloc.0 + IL_005a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_005f: pop + IL_0060: ret } // end of method ForLoop03::test1 .property class [mscorlib]System.Collections.Generic.List`1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl index eca246c526b..5ef897b2169 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly GeneralizationOnUnions01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GeneralizationOnUnions01 { - // Offset: 0x00000000 Length: 0x00000699 + // Offset: 0x00000000 Length: 0x00000689 } .mresource public FSharpOptimizationData.GeneralizationOnUnions01 { - // Offset: 0x000006A0 Length: 0x000001F4 + // Offset: 0x00000690 Length: 0x000001F4 } .module GeneralizationOnUnions01.exe -// MVID: {59B19213-4CA2-8CD1-A745-03831392B159} +// MVID: {611C4D7C-4CA2-8CD1-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x014C0000 +// Image base: 0x06A80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -145,54 +145,44 @@ instance int32 CompareTo(class GeneralizationOnUnions01/Weirdo obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 38 (0x26) + // Code size 27 (0x1b) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\GeneralizationOnUnions01.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0018 - + .line 4,4 : 6,12 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\GeneralizationOnUnions01.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0016 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0011 .line 100001,100001 : 0,0 '' - IL_0014: ldc.i4.0 - IL_0015: ret + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_000f .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.1 - IL_0017: ret + IL_000d: ldc.i4.0 + IL_000e: ret .line 100001,100001 : 0,0 '' - IL_0018: ldarg.1 - IL_0019: ldnull - IL_001a: cgt.un - IL_001c: brfalse.s IL_0020 + IL_000f: ldc.i4.1 + IL_0010: ret - IL_001e: br.s IL_0022 - - IL_0020: br.s IL_0024 + .line 100001,100001 : 0,0 '' + IL_0011: ldarg.1 + IL_0012: ldnull + IL_0013: cgt.un + IL_0015: brfalse.s IL_0019 .line 100001,100001 : 0,0 '' - IL_0022: ldc.i4.m1 - IL_0023: ret + IL_0017: ldc.i4.m1 + IL_0018: ret .line 100001,100001 : 0,0 '' - IL_0024: ldc.i4.0 - IL_0025: ret + IL_0019: ldc.i4.0 + IL_001a: ret } // end of method Weirdo::CompareTo .method public hidebysig virtual final @@ -214,89 +204,76 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 55 (0x37) + // Code size 43 (0x2b) .maxstack 3 .locals init ([0] class GeneralizationOnUnions01/Weirdo V_0) .line 4,4 : 6,12 '' IL_0000: ldarg.1 IL_0001: unbox.any GeneralizationOnUnions01/Weirdo IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0011 - - IL_000f: br.s IL_0024 + IL_000b: brfalse.s IL_001c .line 100001,100001 : 0,0 '' - IL_0011: ldarg.1 - IL_0012: unbox.any GeneralizationOnUnions01/Weirdo - IL_0017: ldnull - IL_0018: cgt.un - IL_001a: brfalse.s IL_001e - - IL_001c: br.s IL_0020 - - IL_001e: br.s IL_0022 + IL_000d: ldarg.1 + IL_000e: unbox.any GeneralizationOnUnions01/Weirdo + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_001a .line 100001,100001 : 0,0 '' - IL_0020: ldc.i4.0 - IL_0021: ret + IL_0018: ldc.i4.0 + IL_0019: ret .line 100001,100001 : 0,0 '' - IL_0022: ldc.i4.1 - IL_0023: ret + IL_001a: ldc.i4.1 + IL_001b: ret .line 100001,100001 : 0,0 '' - IL_0024: ldarg.1 - IL_0025: unbox.any GeneralizationOnUnions01/Weirdo - IL_002a: ldnull - IL_002b: cgt.un - IL_002d: brfalse.s IL_0031 - - IL_002f: br.s IL_0033 - - IL_0031: br.s IL_0035 + IL_001c: ldarg.1 + IL_001d: unbox.any GeneralizationOnUnions01/Weirdo + IL_0022: ldnull + IL_0023: cgt.un + IL_0025: brfalse.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0033: ldc.i4.m1 - IL_0034: ret + IL_0027: ldc.i4.m1 + IL_0028: ret .line 100001,100001 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0029: ldc.i4.0 + IL_002a: ret } // end of method Weirdo::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 18 (0x12) + // Code size 15 (0xf) .maxstack 3 .locals init ([0] int32 V_0) + .line 4,4 : 6,12 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0010 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_000d .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: pop - IL_000e: ldc.i4.0 - IL_000f: ret + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: pop + IL_000b: ldc.i4.0 + IL_000c: ret .line 100001,100001 : 0,0 '' - IL_0010: ldc.i4.0 - IL_0011: ret + IL_000d: ldc.i4.0 + IL_000e: ret } // end of method Weirdo::GetHashCode .method public hidebysig virtual final @@ -317,108 +294,98 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 38 (0x26) + // Code size 31 (0x1f) .maxstack 4 .locals init ([0] class GeneralizationOnUnions01/Weirdo V_0, [1] class GeneralizationOnUnions01/Weirdo V_1) + .line 4,4 : 6,12 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_001e + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0017 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst GeneralizationOnUnions01/Weirdo - IL_0010: stloc.0 - IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_001c + IL_0007: ldarg.1 + IL_0008: isinst GeneralizationOnUnions01/Weirdo + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0015 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldc.i4.1 - IL_001b: ret + IL_0011: ldloc.0 + IL_0012: stloc.1 + IL_0013: ldc.i4.1 + IL_0014: ret .line 100001,100001 : 0,0 '' - IL_001c: ldc.i4.0 - IL_001d: ret + IL_0015: ldc.i4.0 + IL_0016: ret .line 100001,100001 : 0,0 '' - IL_001e: ldarg.1 - IL_001f: ldnull - IL_0020: cgt.un - IL_0022: ldc.i4.0 - IL_0023: ceq - IL_0025: ret + IL_0017: ldarg.1 + IL_0018: ldnull + IL_0019: cgt.un + IL_001b: ldc.i4.0 + IL_001c: ceq + IL_001e: ret } // end of method Weirdo::Equals .method public hidebysig virtual final instance bool Equals(class GeneralizationOnUnions01/Weirdo obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 23 (0x17) + // Code size 20 (0x14) .maxstack 8 + .line 4,4 : 6,12 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_000f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_000c .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: ret + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: ret .line 100001,100001 : 0,0 '' - IL_000f: ldarg.1 - IL_0010: ldnull - IL_0011: cgt.un - IL_0013: ldc.i4.0 - IL_0014: ceq - IL_0016: ret + IL_000c: ldarg.1 + IL_000d: ldnull + IL_000e: cgt.un + IL_0010: ldc.i4.0 + IL_0011: ceq + IL_0013: ret } // end of method Weirdo::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class GeneralizationOnUnions01/Weirdo V_0) .line 4,4 : 6,12 '' IL_0000: ldarg.1 IL_0001: isinst GeneralizationOnUnions01/Weirdo IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool GeneralizationOnUnions01/Weirdo::Equals(class GeneralizationOnUnions01/Weirdo) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool GeneralizationOnUnions01/Weirdo::Equals(class GeneralizationOnUnions01/Weirdo) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method Weirdo::Equals .property instance int32 Tag() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GenericTypeStaticField01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GenericTypeStaticField01.il.bsl index 0715db93d79..928e00e3cfd 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GenericTypeStaticField01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GenericTypeStaticField01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly GenericTypeStaticField01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.GenericTypeStaticField01 { - // Offset: 0x00000000 Length: 0x00000608 + // Offset: 0x00000000 Length: 0x00000604 } .mresource public FSharpOptimizationData.GenericTypeStaticField01 { - // Offset: 0x00000610 Length: 0x000001E7 + // Offset: 0x00000608 Length: 0x000001E1 } .module GenericTypeStaticField01.exe -// MVID: {59B19213-1E75-7E6B-A745-03831392B159} +// MVID: {60B68B7F-1E75-7E6B-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00730000 +// Image base: 0x00F10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,7 +63,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\GenericTypeStaticField01.fs' + .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\GenericTypeStaticField01.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/IfThenElse01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/IfThenElse01.il.bsl index 3505d4f8e23..da3619e275e 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/IfThenElse01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/IfThenElse01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly IfThenElse01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.IfThenElse01 { - // Offset: 0x00000000 Length: 0x00000201 + // Offset: 0x00000000 Length: 0x000001FD } .mresource public FSharpOptimizationData.IfThenElse01 { // Offset: 0x00000208 Length: 0x00000092 } .module IfThenElse01.dll -// MVID: {59B19213-2D6C-0B5D-A745-03831392B159} +// MVID: {611C4D7C-2D6C-0B5D-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00BD0000 +// Image base: 0x06B70000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,6 +58,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit f5@5 extends [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc { + .field static assembly initonly class IfThenElse01/M/f5@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -85,6 +86,18 @@ IL_000b: ret } // end of method f5@5::Specialize + .method private specialname rtspecialname static + void .cctor() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void IfThenElse01/M/f5@5::.ctor() + IL_0005: stsfld class IfThenElse01/M/f5@5 IfThenElse01/M/f5@5::@_instance + IL_000a: ret + } // end of method f5@5::.cctor + } // end of class f5@5 .class auto ansi serializable sealed nested assembly beforefieldinit f5@5T @@ -115,29 +128,27 @@ !a z, !a w) cil managed { - // Code size 20 (0x14) + // Code size 17 (0x11) .maxstack 7 .locals init ([0] class IfThenElse01/M/f5@5 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 48,63 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\IfThenElse01.fs' + .line 5,5 : 48,63 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\IfThenElse01.fs' IL_0000: ldarg.0 IL_0001: ldfld class IfThenElse01/M/f5@5 class IfThenElse01/M/f5@5T::self0@ IL_0006: stloc.0 - IL_0007: ldarg.1 - IL_0008: ldarg.2 - IL_0009: ble.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0011 + IL_0007: nop + .line 100001,100001 : 0,0 '' + IL_0008: ldarg.1 + IL_0009: ldarg.2 + IL_000a: ble.s IL_000e .line 5,5 : 64,65 '' - IL_000f: ldarg.3 - IL_0010: ret + IL_000c: ldarg.3 + IL_000d: ret .line 5,5 : 71,72 '' - IL_0011: ldarg.s w - IL_0013: ret + IL_000e: ldarg.s w + IL_0010: ret } // end of method f5@5T::Invoke } // end of class f5@5T @@ -152,7 +163,7 @@ [3] int32 V_3, [4] int32 V_4) .line 100001,100001 : 0,0 '' - IL_0000: newobj instance void IfThenElse01/M/f5@5::.ctor() + IL_0000: ldsfld class IfThenElse01/M/f5@5 IfThenElse01/M/f5@5::@_instance IL_0005: stloc.0 .line 6,6 : 9,25 '' IL_0006: ldloc.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/LetIfThenElse01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/LetIfThenElse01.il.bsl index 8c6ee74160d..d52b78f54d7 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/LetIfThenElse01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/LetIfThenElse01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly LetIfThenElse01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.LetIfThenElse01 { - // Offset: 0x00000000 Length: 0x000001E5 + // Offset: 0x00000000 Length: 0x000001D9 } .mresource public FSharpOptimizationData.LetIfThenElse01 { - // Offset: 0x000001F0 Length: 0x00000076 + // Offset: 0x000001E0 Length: 0x00000076 } .module LetIfThenElse01.exe -// MVID: {59B19213-BE5A-D8FD-A745-03831392B159} +// MVID: {611C4D7C-BE5A-D8FD-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02940000 +// Image base: 0x06920000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,7 +54,7 @@ .method public static class [mscorlib]System.Tuple`4 F(!!a y) cil managed { - // Code size 140 (0x8c) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] int32 x1, [1] valuetype [mscorlib]System.DateTime V_1, @@ -65,112 +65,104 @@ [6] int32 y2, [7] valuetype [mscorlib]System.DateTime V_7) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 12,51 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\LetIfThenElse01.fs' - IL_0000: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() - IL_0005: stloc.1 - IL_0006: ldloca.s V_1 - IL_0008: call instance int32 [mscorlib]System.DateTime::get_Year() - IL_000d: ldc.i4 0x7d0 - IL_0012: ble.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_001c + .line 6,6 : 12,51 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\LetIfThenElse01.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() + IL_0006: stloc.1 + IL_0007: ldloca.s V_1 + IL_0009: call instance int32 [mscorlib]System.DateTime::get_Year() + IL_000e: ldc.i4 0x7d0 + IL_0013: ble.s IL_0019 .line 6,6 : 52,53 '' - IL_0018: ldc.i4.1 + IL_0015: ldc.i4.1 .line 100001,100001 : 0,0 '' - IL_0019: nop - IL_001a: br.s IL_001e + IL_0016: nop + IL_0017: br.s IL_001b .line 6,6 : 59,60 '' - IL_001c: ldc.i4.2 + IL_0019: ldc.i4.2 .line 100001,100001 : 0,0 '' - IL_001d: nop + IL_001a: nop .line 100001,100001 : 0,0 '' - IL_001e: stloc.0 + IL_001b: stloc.0 .line 7,7 : 12,51 '' - IL_001f: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() - IL_0024: stloc.3 - IL_0025: ldloca.s V_3 - IL_0027: call instance int32 [mscorlib]System.DateTime::get_Year() - IL_002c: ldc.i4 0x7d0 - IL_0031: ble.s IL_0035 - - IL_0033: br.s IL_0037 - - IL_0035: br.s IL_003b + IL_001c: nop + .line 100001,100001 : 0,0 '' + IL_001d: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() + IL_0022: stloc.3 + IL_0023: ldloca.s V_3 + IL_0025: call instance int32 [mscorlib]System.DateTime::get_Year() + IL_002a: ldc.i4 0x7d0 + IL_002f: ble.s IL_0035 .line 7,7 : 52,53 '' - IL_0037: ldc.i4.1 + IL_0031: ldc.i4.1 .line 100001,100001 : 0,0 '' - IL_0038: nop - IL_0039: br.s IL_003d + IL_0032: nop + IL_0033: br.s IL_0037 .line 7,7 : 59,60 '' - IL_003b: ldc.i4.2 + IL_0035: ldc.i4.2 .line 100001,100001 : 0,0 '' - IL_003c: nop + IL_0036: nop .line 100001,100001 : 0,0 '' - IL_003d: stloc.2 + IL_0037: stloc.2 .line 8,8 : 12,51 '' - IL_003e: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() - IL_0043: stloc.s V_5 - IL_0045: ldloca.s V_5 - IL_0047: call instance int32 [mscorlib]System.DateTime::get_Year() - IL_004c: ldc.i4 0x7d0 - IL_0051: bge.s IL_0055 - - IL_0053: br.s IL_0057 - - IL_0055: br.s IL_005b + IL_0038: nop + .line 100001,100001 : 0,0 '' + IL_0039: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() + IL_003e: stloc.s V_5 + IL_0040: ldloca.s V_5 + IL_0042: call instance int32 [mscorlib]System.DateTime::get_Year() + IL_0047: ldc.i4 0x7d0 + IL_004c: bge.s IL_0052 .line 8,8 : 52,53 '' - IL_0057: ldc.i4.1 + IL_004e: ldc.i4.1 .line 100001,100001 : 0,0 '' - IL_0058: nop - IL_0059: br.s IL_005d + IL_004f: nop + IL_0050: br.s IL_0054 .line 8,8 : 59,60 '' - IL_005b: ldc.i4.2 + IL_0052: ldc.i4.2 .line 100001,100001 : 0,0 '' - IL_005c: nop + IL_0053: nop .line 100001,100001 : 0,0 '' - IL_005d: stloc.s x2 + IL_0054: stloc.s x2 .line 9,9 : 12,51 '' - IL_005f: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() - IL_0064: stloc.s V_7 - IL_0066: ldloca.s V_7 - IL_0068: call instance int32 [mscorlib]System.DateTime::get_Year() - IL_006d: ldc.i4 0x7d0 - IL_0072: bge.s IL_0076 - - IL_0074: br.s IL_0078 - - IL_0076: br.s IL_007c + IL_0056: nop + .line 100001,100001 : 0,0 '' + IL_0057: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now() + IL_005c: stloc.s V_7 + IL_005e: ldloca.s V_7 + IL_0060: call instance int32 [mscorlib]System.DateTime::get_Year() + IL_0065: ldc.i4 0x7d0 + IL_006a: bge.s IL_0070 .line 9,9 : 52,53 '' - IL_0078: ldc.i4.1 + IL_006c: ldc.i4.1 .line 100001,100001 : 0,0 '' - IL_0079: nop - IL_007a: br.s IL_007e + IL_006d: nop + IL_006e: br.s IL_0072 .line 9,9 : 59,60 '' - IL_007c: ldc.i4.2 + IL_0070: ldc.i4.2 .line 100001,100001 : 0,0 '' - IL_007d: nop + IL_0071: nop .line 100001,100001 : 0,0 '' - IL_007e: stloc.s y2 + IL_0072: stloc.s y2 .line 10,10 : 3,14 '' - IL_0080: ldloc.0 - IL_0081: ldloc.2 - IL_0082: ldloc.s x2 - IL_0084: ldloc.s y2 - IL_0086: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, + IL_0074: ldloc.0 + IL_0075: ldloc.2 + IL_0076: ldloc.s x2 + IL_0078: ldloc.s y2 + IL_007a: newobj instance void class [mscorlib]System.Tuple`4::.ctor(!0, !1, !2, !3) - IL_008b: ret + IL_007f: ret } // end of method LetIfThenElse01::F } // end of class LetIfThenElse01 @@ -187,12 +179,13 @@ .entrypoint // Code size 10 (0xa) .maxstack 3 - .locals init ([0] class [mscorlib]System.Tuple`4 V_0, + .locals init ([0] class [mscorlib]System.Tuple`4 'Pipe #1 input at line 12', [1] class [mscorlib]System.Tuple`4 V_1) - .line 12,12 : 1,15 '' + .line 12,12 : 1,5 '' IL_0000: ldc.i4.1 IL_0001: call class [mscorlib]System.Tuple`4 LetIfThenElse01::F(!!0) IL_0006: stloc.0 + .line 12,12 : 9,15 '' IL_0007: ldloc.0 IL_0008: stloc.1 IL_0009: ret diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Lock01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Lock01.il.bsl index 641008a218f..3884536a990 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Lock01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Lock01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Lock01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Lock01 { - // Offset: 0x00000000 Length: 0x00000184 + // Offset: 0x00000000 Length: 0x00000180 } .mresource public FSharpOptimizationData.Lock01 { // Offset: 0x00000188 Length: 0x00000064 } .module Lock01.exe -// MVID: {59B19213-2BCA-B308-A745-03831392B159} +// MVID: {611C4D7C-2BCA-B308-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02FB0000 +// Image base: 0x071E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +59,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit clo@20 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Lock01/clo@20 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -72,11 +78,21 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 20,20 : 19,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\Lock01.fs' + .line 20,20 : 19,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\Lock01.fs' IL_0000: ldnull IL_0001: ret } // end of method clo@20::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Lock01/clo@20::.ctor() + IL_0005: stsfld class Lock01/clo@20 Lock01/clo@20::@_instance + IL_000a: ret + } // end of method clo@20::.cctor + } // end of class clo@20 .method public specialname static object @@ -107,13 +123,12 @@ .method public static void main@() cil managed { .entrypoint - // Code size 68 (0x44) + // Code size 56 (0x38) .maxstack 4 .locals init ([0] object o, [1] object V_1, [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_2, - [3] bool V_3, - [4] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_4) + [3] bool V_3) .line 19,19 : 1,28 '' IL_0000: newobj instance void [mscorlib]System.Object::.ctor() IL_0005: dup @@ -122,7 +137,7 @@ .line 20,20 : 1,23 '' IL_000c: call object Lock01::get_o() IL_0011: stloc.1 - IL_0012: newobj instance void Lock01/clo@20::.ctor() + IL_0012: ldsfld class Lock01/clo@20 Lock01/clo@20::@_instance IL_0017: stloc.2 IL_0018: ldc.i4.0 IL_0019: stloc.3 @@ -130,39 +145,30 @@ { IL_001a: ldloc.1 IL_001b: ldloca.s V_3 - IL_001d: call void [mscorlib]System.Threading.Monitor::Enter(object, - bool&) + IL_001d: call void [netstandard]System.Threading.Monitor::Enter(object, + bool&) IL_0022: ldloc.2 IL_0023: ldnull IL_0024: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0029: stloc.s V_4 - IL_002b: leave.s IL_0040 + IL_0029: pop + IL_002a: leave.s IL_0037 + .line 100001,100001 : 0,0 '' } // end .try finally { - IL_002d: ldloc.3 - IL_002e: brfalse.s IL_0032 - - IL_0030: br.s IL_0034 - - IL_0032: br.s IL_003d + IL_002c: ldloc.3 + IL_002d: brfalse.s IL_0036 .line 100001,100001 : 0,0 '' - IL_0034: ldloc.1 - IL_0035: call void [mscorlib]System.Threading.Monitor::Exit(object) - IL_003a: ldnull - IL_003b: pop - IL_003c: endfinally + IL_002f: ldloc.1 + IL_0030: call void [netstandard]System.Threading.Monitor::Exit(object) + IL_0035: endfinally .line 100001,100001 : 0,0 '' - IL_003d: ldnull - IL_003e: pop - IL_003f: endfinally + IL_0036: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_0040: ldloc.s V_4 - IL_0042: pop - IL_0043: ret + IL_0037: ret } // end of method $Lock01::main@ } // end of class ''.$Lock01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Marshal.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Marshal.il.bsl index a4ee5c51231..a72c99aedd5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Marshal.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Marshal.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Marshal { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Marshal { - // Offset: 0x00000000 Length: 0x0000050B + // Offset: 0x00000000 Length: 0x00000507 } .mresource public FSharpOptimizationData.Marshal { // Offset: 0x00000510 Length: 0x0000004E } .module Marshal.exe -// MVID: {59B19213-7500-369C-A745-03831392B159} +// MVID: {60B68B7F-7500-369C-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x068F0000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline.il.bsl index 9a2538f734d..af2fb2f1a54 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly MethodImplNoInline { @@ -25,20 +30,20 @@ } .mresource public FSharpSignatureData.MethodImplNoInline { - // Offset: 0x00000000 Length: 0x000002FF + // Offset: 0x00000000 Length: 0x000002FB } .mresource public FSharpOptimizationData.MethodImplNoInline { - // Offset: 0x00000308 Length: 0x000000F5 + // Offset: 0x00000300 Length: 0x000000F5 } .module MethodImplNoInline.exe -// MVID: {59B19213-4480-09E2-A745-03831392B159} +// MVID: {611C52A3-4480-09E2-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00D80000 +// Image base: 0x06F00000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +60,7 @@ IL_0000: ldstr "Hey!" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: stloc.0 - IL_000b: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0010: ldloc.0 IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline02.il.bsl index 784e3d51a37..4016869a49c 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/MethodImplNoInline02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly MethodImplNoInline02 { @@ -25,20 +30,20 @@ } .mresource public FSharpSignatureData.MethodImplNoInline02 { - // Offset: 0x00000000 Length: 0x00000305 + // Offset: 0x00000000 Length: 0x00000301 } .mresource public FSharpOptimizationData.MethodImplNoInline02 { - // Offset: 0x00000310 Length: 0x000000F9 + // Offset: 0x00000308 Length: 0x000000F9 } .module MethodImplNoInline02.exe -// MVID: {59B19213-084F-1A8E-A745-03831392B159} +// MVID: {611C52A3-084F-1A8E-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x012C0000 +// Image base: 0x06B60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +60,7 @@ IL_0000: ldstr "Hey!" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: stloc.0 - IL_000b: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_000b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0010: ldloc.0 IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ModuleWithExpression01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ModuleWithExpression01.il.bsl index 479fa38706d..4dbdb7783fe 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ModuleWithExpression01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/ModuleWithExpression01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ModuleWithExpression01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ModuleWithExpression01 { - // Offset: 0x00000000 Length: 0x0000020E + // Offset: 0x00000000 Length: 0x0000020A } .mresource public FSharpOptimizationData.ModuleWithExpression01 { - // Offset: 0x00000218 Length: 0x000000A6 + // Offset: 0x00000210 Length: 0x000000A6 } .module ModuleWithExpression01.exe -// MVID: {59B19213-CD1E-A8B4-A745-03831392B159} +// MVID: {60B68B7F-CD1E-A8B4-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x030A0000 +// Image base: 0x07550000 // =============== CLASS MEMBERS DECLARATION =================== @@ -88,7 +88,7 @@ .maxstack 3 .locals init ([0] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\ModuleWithExpression01.fs' + .line 8,8 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\ModuleWithExpression01.fs' IL_0000: ldstr "hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NoBoxingOnDispose01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NoBoxingOnDispose01.il.bsl index 2e111b971f8..570d4feb14e 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NoBoxingOnDispose01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NoBoxingOnDispose01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly NoBoxingOnDispose01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.NoBoxingOnDispose01 { - // Offset: 0x00000000 Length: 0x0000021A + // Offset: 0x00000000 Length: 0x00000216 } .mresource public FSharpOptimizationData.NoBoxingOnDispose01 { // Offset: 0x00000220 Length: 0x0000007F } .module NoBoxingOnDispose01.exe -// MVID: {59B19213-4EA9-C934-A745-03831392B159} +// MVID: {60BCDCE8-4EA9-C934-A745-0383E8DCBC60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00590000 +// Image base: 0x07070000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,14 +53,13 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void f1(class [mscorlib]System.Collections.Generic.List`1 x) cil managed { - // Code size 52 (0x34) + // Code size 46 (0x2e) .maxstack 3 .locals init ([0] class [mscorlib]System.Collections.Generic.List`1 V_0, [1] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator V_1, - [2] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_2, - [3] !!T a) + [2] !!T a) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 3,16 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\NoBoxingOnDispose01.fs' + .line 6,6 : 3,16 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\NoBoxingOnDispose01.fs' IL_0000: ldarg.0 IL_0001: stloc.0 .line 6,6 : 3,16 '' @@ -76,29 +75,23 @@ .line 6,6 : 3,16 '' IL_0012: ldloca.s V_1 IL_0014: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator::get_Current() - IL_0019: stloc.3 + IL_0019: stloc.2 .line 100001,100001 : 0,0 '' IL_001a: nop IL_001b: br.s IL_0009 - IL_001d: ldnull - IL_001e: stloc.2 - IL_001f: leave.s IL_0031 + IL_001d: leave.s IL_002d } // end .try finally { - IL_0021: ldloca.s V_1 - IL_0023: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator - IL_0029: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_002e: ldnull - IL_002f: pop - IL_0030: endfinally + IL_001f: ldloca.s V_1 + IL_0021: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator + IL_0027: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_002c: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_0031: ldloc.2 - IL_0032: pop - IL_0033: ret + IL_002d: ret } // end of method NoBoxingOnDispose01::f1 } // end of class NoBoxingOnDispose01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NonEscapingArguments02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NonEscapingArguments02.il.bsl index 5209960dc5f..a20d0205daa 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NonEscapingArguments02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/NonEscapingArguments02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly NonEscapingArguments02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.NonEscapingArguments02 { - // Offset: 0x00000000 Length: 0x00000359 + // Offset: 0x00000000 Length: 0x00000355 } .mresource public FSharpOptimizationData.NonEscapingArguments02 { - // Offset: 0x00000360 Length: 0x000001A4 + // Offset: 0x00000360 Length: 0x0000019E } .module NonEscapingArguments02.dll -// MVID: {59B19213-BB56-6582-A745-03831392B159} +// MVID: {60B68B7F-BB56-6582-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01730000 +// Image base: 0x06B40000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 21 (0x15) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\NonEscapingArguments02.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\NonEscapingArguments02.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/PreserveSig.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/PreserveSig.il.bsl index 5a8b4ef3b76..bbd2fc4fee7 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/PreserveSig.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/PreserveSig.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly PreserveSig { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.PreserveSig { - // Offset: 0x00000000 Length: 0x000002F5 + // Offset: 0x00000000 Length: 0x000002F1 } .mresource public FSharpOptimizationData.PreserveSig { - // Offset: 0x00000300 Length: 0x0000004A + // Offset: 0x000002F8 Length: 0x0000004A } .module PreserveSig.dll -// MVID: {59B19213-E8CC-64FE-A745-03831392B159} +// MVID: {60B68B7F-E8CC-64FE-A745-03837F8BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01660000 +// Image base: 0x05120000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Seq_for_all01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Seq_for_all01.il.bsl index 5ccceb26460..e0302a0c9f5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Seq_for_all01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Seq_for_all01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Seq_for_all01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Seq_for_all01 { - // Offset: 0x00000000 Length: 0x000001AB + // Offset: 0x00000000 Length: 0x000001A7 } .mresource public FSharpOptimizationData.Seq_for_all01 { // Offset: 0x000001B0 Length: 0x00000072 } .module Seq_for_all01.exe -// MVID: {59B19213-D30D-BA80-A745-03831392B159} +// MVID: {611C4D7C-D30D-BA80-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02A60000 +// Image base: 0x07110000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +54,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit q@4 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Seq_for_all01/q@4 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -69,30 +70,43 @@ .method public strict virtual instance bool Invoke(int32 s) cil managed { - // Code size 14 (0xe) + // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 31,47 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\Seq_for_all01.fs' - IL_0000: ldc.i4.1 - IL_0001: brtrue.s IL_0005 - - IL_0003: br.s IL_0007 - - IL_0005: br.s IL_000b + .line 5,5 : 31,47 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\Seq_for_all01.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldc.i4.1 + IL_0002: ldc.i4.0 + IL_0003: ceq + .line 100001,100001 : 0,0 '' + IL_0005: nop + .line 100001,100001 : 0,0 '' + IL_0006: brfalse.s IL_000c .line 5,5 : 48,50 '' - IL_0007: nop - .line 100001,100001 : 0,0 '' IL_0008: nop - IL_0009: br.s IL_000c + .line 100001,100001 : 0,0 '' + IL_0009: nop + IL_000a: br.s IL_000d .line 100001,100001 : 0,0 '' - IL_000b: nop + IL_000c: nop .line 6,6 : 31,35 '' - IL_000c: ldc.i4.1 - IL_000d: ret + IL_000d: ldc.i4.1 + IL_000e: ret } // end of method q@4::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Seq_for_all01/q@4::.ctor() + IL_0005: stsfld class Seq_for_all01/q@4 Seq_for_all01/q@4::@_instance + IL_000a: ret + } // end of method q@4::.cctor + } // end of class q@4 .method public specialname static bool @@ -127,7 +141,7 @@ .maxstack 5 .locals init ([0] bool q) .line 4,7 : 1,28 '' - IL_0000: newobj instance void Seq_for_all01/q@4::.ctor() + IL_0000: ldsfld class Seq_for_all01/q@4 Seq_for_all01/q@4::@_instance IL_0005: ldc.i4.1 IL_0006: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_000b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs01.il.bsl index b3476b282f7..b03d9a51166 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Structs01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Structs01 { - // Offset: 0x00000000 Length: 0x0000074D + // Offset: 0x00000000 Length: 0x0000073D } .mresource public FSharpOptimizationData.Structs01 { - // Offset: 0x00000758 Length: 0x00000231 + // Offset: 0x00000748 Length: 0x00000231 } .module Structs01.exe -// MVID: {59B19213-701F-5E27-A745-03831392B159} +// MVID: {611C52A3-701F-5E27-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01470000 +// Image base: 0x06680000 // =============== CLASS MEMBERS DECLARATION =================== @@ -65,14 +65,14 @@ instance int32 CompareTo(valuetype Experiment.Test/Test obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 38 (0x26) + // Code size 34 (0x22) .maxstack 4 .locals init ([0] valuetype Experiment.Test/Test& V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 6,10 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\Structs01.fs' + .line 7,7 : 6,10 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\Structs01.fs' IL_0000: ldarga.s obj IL_0002: stloc.0 IL_0003: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() @@ -83,23 +83,20 @@ IL_0010: ldloc.0 IL_0011: ldfld int32 Experiment.Test/Test::Field IL_0016: stloc.3 + .line 100001,100001 : 0,0 '' IL_0017: ldloc.2 IL_0018: ldloc.3 IL_0019: bge.s IL_001d - IL_001b: br.s IL_001f - - IL_001d: br.s IL_0021 - .line 100001,100001 : 0,0 '' - IL_001f: ldc.i4.m1 - IL_0020: ret + IL_001b: ldc.i4.m1 + IL_001c: ret .line 100001,100001 : 0,0 '' - IL_0021: ldloc.2 - IL_0022: ldloc.3 - IL_0023: cgt - IL_0025: ret + IL_001d: ldloc.2 + IL_001e: ldloc.3 + IL_001f: cgt + IL_0021: ret } // end of method Test::CompareTo .method public hidebysig virtual final @@ -121,7 +118,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 44 (0x2c) + // Code size 40 (0x28) .maxstack 4 .locals init ([0] valuetype Experiment.Test/Test V_0, [1] valuetype Experiment.Test/Test& V_1, @@ -142,23 +139,20 @@ IL_0013: ldloc.1 IL_0014: ldfld int32 Experiment.Test/Test::Field IL_0019: stloc.s V_4 + .line 100001,100001 : 0,0 '' IL_001b: ldloc.3 IL_001c: ldloc.s V_4 IL_001e: bge.s IL_0022 - IL_0020: br.s IL_0024 - - IL_0022: br.s IL_0026 - .line 100001,100001 : 0,0 '' - IL_0024: ldc.i4.m1 - IL_0025: ret + IL_0020: ldc.i4.m1 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: cgt - IL_002b: ret + IL_0022: ldloc.3 + IL_0023: ldloc.s V_4 + IL_0025: cgt + IL_0027: ret } // end of method Test::CompareTo .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs02.il.bsl index dc002382e1d..15115f5ba6f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/Structs02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Structs02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Structs02 { - // Offset: 0x00000000 Length: 0x00000787 + // Offset: 0x00000000 Length: 0x00000777 } .mresource public FSharpOptimizationData.Structs02 { - // Offset: 0x00000790 Length: 0x00000237 + // Offset: 0x00000780 Length: 0x00000237 } .module Structs02.exe -// MVID: {59B19213-7040-5E27-A745-03831392B159} +// MVID: {611C52A3-7040-5E27-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002F0000 +// Image base: 0x051F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -76,14 +76,14 @@ instance int32 CompareTo(valuetype Experiment.Test/Repro obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 38 (0x26) + // Code size 34 (0x22) .maxstack 4 .locals init ([0] valuetype Experiment.Test/Repro& V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 6,11 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\Structs02.fs' + .line 6,6 : 6,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\Structs02.fs' IL_0000: ldarga.s obj IL_0002: stloc.0 IL_0003: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() @@ -94,23 +94,20 @@ IL_0010: ldloc.0 IL_0011: ldfld int32 Experiment.Test/Repro::hash@ IL_0016: stloc.3 + .line 100001,100001 : 0,0 '' IL_0017: ldloc.2 IL_0018: ldloc.3 IL_0019: bge.s IL_001d - IL_001b: br.s IL_001f - - IL_001d: br.s IL_0021 - .line 100001,100001 : 0,0 '' - IL_001f: ldc.i4.m1 - IL_0020: ret + IL_001b: ldc.i4.m1 + IL_001c: ret .line 100001,100001 : 0,0 '' - IL_0021: ldloc.2 - IL_0022: ldloc.3 - IL_0023: cgt - IL_0025: ret + IL_001d: ldloc.2 + IL_001e: ldloc.3 + IL_001f: cgt + IL_0021: ret } // end of method Repro::CompareTo .method public hidebysig virtual final @@ -132,7 +129,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 44 (0x2c) + // Code size 40 (0x28) .maxstack 4 .locals init ([0] valuetype Experiment.Test/Repro V_0, [1] valuetype Experiment.Test/Repro& V_1, @@ -153,23 +150,20 @@ IL_0013: ldloc.1 IL_0014: ldfld int32 Experiment.Test/Repro::hash@ IL_0019: stloc.s V_4 + .line 100001,100001 : 0,0 '' IL_001b: ldloc.3 IL_001c: ldloc.s V_4 IL_001e: bge.s IL_0022 - IL_0020: br.s IL_0024 - - IL_0022: br.s IL_0026 - .line 100001,100001 : 0,0 '' - IL_0024: ldc.i4.m1 - IL_0025: ret + IL_0020: ldc.i4.m1 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: cgt - IL_002b: ret + IL_0022: ldloc.3 + IL_0023: ldloc.s V_4 + IL_0025: cgt + IL_0027: ret } // end of method Repro::CompareTo .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/StructsAsArrayElements01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/StructsAsArrayElements01.il.bsl index e3e7795ebd4..0e812538db2 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/StructsAsArrayElements01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/StructsAsArrayElements01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly StructsAsArrayElements01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.StructsAsArrayElements01 { - // Offset: 0x00000000 Length: 0x00000758 + // Offset: 0x00000000 Length: 0x00000754 } .mresource public FSharpOptimizationData.StructsAsArrayElements01 { - // Offset: 0x00000760 Length: 0x0000022C + // Offset: 0x00000758 Length: 0x0000022C } .module StructsAsArrayElements01.dll -// MVID: {5B17FC4F-29F3-6E68-A745-03834FFC175B} +// MVID: {611C52A3-29F3-6E68-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00E30000 +// Image base: 0x06670000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,14 +66,14 @@ instance int32 CompareTo(valuetype StructsAsArrayElements01/T obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 38 (0x26) + // Code size 34 (0x22) .maxstack 4 .locals init ([0] valuetype StructsAsArrayElements01/T& V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 6,7 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\StructsAsArrayElements01.fs' + .line 7,7 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\StructsAsArrayElements01.fs' IL_0000: ldarga.s obj IL_0002: stloc.0 IL_0003: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() @@ -84,23 +84,20 @@ IL_0010: ldloc.0 IL_0011: ldfld int32 StructsAsArrayElements01/T::i IL_0016: stloc.3 + .line 100001,100001 : 0,0 '' IL_0017: ldloc.2 IL_0018: ldloc.3 IL_0019: bge.s IL_001d - IL_001b: br.s IL_001f - - IL_001d: br.s IL_0021 - .line 100001,100001 : 0,0 '' - IL_001f: ldc.i4.m1 - IL_0020: ret + IL_001b: ldc.i4.m1 + IL_001c: ret .line 100001,100001 : 0,0 '' - IL_0021: ldloc.2 - IL_0022: ldloc.3 - IL_0023: cgt - IL_0025: ret + IL_001d: ldloc.2 + IL_001e: ldloc.3 + IL_001f: cgt + IL_0021: ret } // end of method T::CompareTo .method public hidebysig virtual final @@ -122,7 +119,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 44 (0x2c) + // Code size 40 (0x28) .maxstack 4 .locals init ([0] valuetype StructsAsArrayElements01/T V_0, [1] valuetype StructsAsArrayElements01/T& V_1, @@ -143,23 +140,20 @@ IL_0013: ldloc.1 IL_0014: ldfld int32 StructsAsArrayElements01/T::i IL_0019: stloc.s V_4 + .line 100001,100001 : 0,0 '' IL_001b: ldloc.3 IL_001c: ldloc.s V_4 IL_001e: bge.s IL_0022 - IL_0020: br.s IL_0024 - - IL_0022: br.s IL_0026 - .line 100001,100001 : 0,0 '' - IL_0024: ldc.i4.m1 - IL_0025: ret + IL_0020: ldc.i4.m1 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: cgt - IL_002b: ret + IL_0022: ldloc.3 + IL_0023: ldloc.s V_4 + IL_0025: cgt + IL_0027: ret } // end of method T::CompareTo .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/TryWith_NoFilterBlocks01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/TryWith_NoFilterBlocks01.il.bsl index 63da7e6e404..7e3a902de5b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/TryWith_NoFilterBlocks01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/TryWith_NoFilterBlocks01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TryWith_NoFilterBlocks01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TryWith_NoFilterBlocks01 { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.TryWith_NoFilterBlocks01 { - // Offset: 0x00000168 Length: 0x0000005F + // Offset: 0x00000160 Length: 0x0000005F } .module TryWith_NoFilterBlocks01.exe -// MVID: {59B19213-3DEF-9A40-A745-03831392B159} +// MVID: {611C4D7C-3DEF-9A40-A745-03837C4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x017A0000 +// Image base: 0x066A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,55 +63,48 @@ .method public static void main@() cil managed { .entrypoint - // Code size 40 (0x28) + // Code size 30 (0x1e) .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] class [mscorlib]System.Exception V_1, - [2] class [mscorlib]System.Exception e, - [3] class [mscorlib]System.Exception V_3) + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception e, + [2] class [mscorlib]System.Exception V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 3,5 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\TryWith_NoFilterBlocks01.fs' + .line 3,3 : 1,4 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\TryWith_NoFilterBlocks01.fs' .try { - IL_0000: ldnull - IL_0001: stloc.0 - IL_0002: leave.s IL_0025 + IL_0000: nop + .line 4,4 : 3,5 '' + IL_0001: leave.s IL_001d .line 5,5 : 2,6 '' } // end .try catch [mscorlib]System.Object { - IL_0004: castclass [mscorlib]System.Exception - IL_0009: stloc.1 - IL_000a: ldloc.1 - IL_000b: stloc.2 - IL_000c: ldloc.2 + IL_0003: castclass [mscorlib]System.Exception + IL_0008: stloc.0 + .line 6,6 : 12,31 '' + IL_0009: nop + .line 100001,100001 : 0,0 '' + IL_000a: ldloc.0 + IL_000b: stloc.1 + IL_000c: ldloc.1 IL_000d: callvirt instance int32 [mscorlib]System.Object::GetHashCode() IL_0012: ldc.i4.0 IL_0013: ceq - IL_0015: brfalse.s IL_0019 - - IL_0017: br.s IL_001b + IL_0015: brfalse.s IL_001b - IL_0019: br.s IL_0021 - - IL_001b: ldloc.1 - IL_001c: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0017: ldloc.0 + IL_0018: stloc.2 .line 6,6 : 35,37 '' - IL_001d: ldnull - IL_001e: stloc.0 - IL_001f: leave.s IL_0025 + IL_0019: leave.s IL_001d .line 7,7 : 10,12 '' - IL_0021: ldnull - IL_0022: stloc.0 - IL_0023: leave.s IL_0025 + IL_001b: leave.s IL_001d .line 100001,100001 : 0,0 '' } // end handler - IL_0025: ldloc.0 - IL_0026: pop - IL_0027: ret + IL_001d: ret } // end of method $TryWith_NoFilterBlocks01::main@ } // end of class ''.$TryWith_NoFilterBlocks01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/cas.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/cas.il.bsl index 5f937b00b51..e5496eb0016 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/cas.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/cas.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly extern cas { @@ -36,20 +36,20 @@ } .mresource public FSharpSignatureData.cas { - // Offset: 0x00000000 Length: 0x000005DF + // Offset: 0x00000000 Length: 0x00000619 } .mresource public FSharpOptimizationData.cas { - // Offset: 0x000005E8 Length: 0x000000F3 + // Offset: 0x00000620 Length: 0x000000F3 } .module cas.exe -// MVID: {59B19213-35EA-18E3-A745-03831392B159} +// MVID: {6124062D-35EA-18E3-A745-03832D062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x006A0000 +// Image base: 0x05010000 // =============== CLASS MEMBERS DECLARATION =================== @@ -76,7 +76,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Misc\\cas.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Misc\\cas.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 @@ -92,11 +92,15 @@ = {class 'System.Security.Permissions.PrincipalPermissionAttribute, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' = {property string 'Role' = string('test')}} .permissionset assert = {[cas]CustomSecAttr.CustomPermission2Attribute = {property enum class 'CustomSecAttr.SecurityArgType, cas, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 'SecurityArg' = int32(2)}} - // Code size 6 (0x6) - .maxstack 8 + // Code size 8 (0x8) + .maxstack 3 + .locals init ([0] class Cas/AttrTest/Foo x) + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: stloc.0 .line 14,14 : 33,37 '' - IL_0000: ldc.i4 0x18c0 - IL_0005: ret + IL_0002: ldc.i4 0x18c0 + IL_0007: ret } // end of method Foo::someMethod } // end of class Foo diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Operators/comparison_decimal01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Operators/comparison_decimal01.il.bsl index a30c4a069bd..fefd5e583ba 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Operators/comparison_decimal01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Operators/comparison_decimal01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly comparison_decimal01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.comparison_decimal01 { - // Offset: 0x00000000 Length: 0x00000176 + // Offset: 0x00000000 Length: 0x00000170 } .mresource public FSharpOptimizationData.comparison_decimal01 { - // Offset: 0x00000180 Length: 0x0000005B + // Offset: 0x00000178 Length: 0x0000005B } .module comparison_decimal01.exe -// MVID: {59B19240-76D8-7EE3-A745-03834092B159} +// MVID: {5F1FA087-76D8-7EE3-A745-038387A01F5F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02980000 +// Image base: 0x06BE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,29 +71,29 @@ // Code size 228 (0xe4) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 9,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Operators\\comparison_decimal01.fs' + .line 4,4 : 9,20 'C:\\kevinransom\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Operators\\comparison_decimal01.fs' IL_0000: ldc.i4.s 10 IL_0002: ldc.i4.0 IL_0003: ldc.i4.0 IL_0004: ldc.i4.0 IL_0005: ldc.i4.1 - IL_0006: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_0006: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_000b: ldc.i4.s 20 IL_000d: ldc.i4.0 IL_000e: ldc.i4.0 IL_000f: ldc.i4.0 IL_0010: ldc.i4.1 - IL_0011: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0016: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_0011: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0016: call bool [netstandard]System.Decimal::op_LessThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_001b: pop .line 5,5 : 9,21 '' IL_001c: ldc.i4.s 10 @@ -96,23 +101,23 @@ IL_001f: ldc.i4.0 IL_0020: ldc.i4.0 IL_0021: ldc.i4.1 - IL_0022: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_0022: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_0027: ldc.i4.s 20 IL_0029: ldc.i4.0 IL_002a: ldc.i4.0 IL_002b: ldc.i4.0 IL_002c: ldc.i4.1 - IL_002d: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0032: call bool [mscorlib]System.Decimal::op_LessThanOrEqual(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_002d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0032: call bool [netstandard]System.Decimal::op_LessThanOrEqual(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0037: pop .line 6,6 : 9,20 '' IL_0038: ldc.i4.s 10 @@ -120,23 +125,23 @@ IL_003b: ldc.i4.0 IL_003c: ldc.i4.0 IL_003d: ldc.i4.1 - IL_003e: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_003e: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_0043: ldc.i4.s 20 IL_0045: ldc.i4.0 IL_0046: ldc.i4.0 IL_0047: ldc.i4.0 IL_0048: ldc.i4.1 - IL_0049: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_004e: call bool [mscorlib]System.Decimal::op_GreaterThan(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_0049: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_004e: call bool [netstandard]System.Decimal::op_GreaterThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0053: pop .line 7,7 : 9,21 '' IL_0054: ldc.i4.s 10 @@ -144,23 +149,23 @@ IL_0057: ldc.i4.0 IL_0058: ldc.i4.0 IL_0059: ldc.i4.1 - IL_005a: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_005a: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_005f: ldc.i4.s 20 IL_0061: ldc.i4.0 IL_0062: ldc.i4.0 IL_0063: ldc.i4.0 IL_0064: ldc.i4.1 - IL_0065: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_006a: call bool [mscorlib]System.Decimal::op_GreaterThanOrEqual(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_0065: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_006a: call bool [netstandard]System.Decimal::op_GreaterThanOrEqual(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_006f: pop .line 8,8 : 9,20 '' IL_0070: ldc.i4.s 10 @@ -168,23 +173,23 @@ IL_0073: ldc.i4.0 IL_0074: ldc.i4.0 IL_0075: ldc.i4.1 - IL_0076: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_0076: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_007b: ldc.i4.s 20 IL_007d: ldc.i4.0 IL_007e: ldc.i4.0 IL_007f: ldc.i4.0 IL_0080: ldc.i4.1 - IL_0081: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0086: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_0081: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0086: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_008b: pop .line 9,9 : 9,21 '' IL_008c: ldc.i4.s 10 @@ -192,23 +197,23 @@ IL_008f: ldc.i4.0 IL_0090: ldc.i4.0 IL_0091: ldc.i4.1 - IL_0092: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_0092: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_0097: ldc.i4.s 20 IL_0099: ldc.i4.0 IL_009a: ldc.i4.0 IL_009b: ldc.i4.0 IL_009c: ldc.i4.1 - IL_009d: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_00a2: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_009d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00a2: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_00a7: ldc.i4.0 IL_00a8: ceq IL_00aa: pop @@ -218,23 +223,23 @@ IL_00ae: ldc.i4.0 IL_00af: ldc.i4.0 IL_00b0: ldc.i4.1 - IL_00b1: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_00b1: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_00b6: ldc.i4.s 20 IL_00b8: ldc.i4.0 IL_00b9: ldc.i4.0 IL_00ba: ldc.i4.0 IL_00bb: ldc.i4.1 - IL_00bc: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_00c1: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_00bc: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00c1: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_00c6: pop .line 11,11 : 9,26 '' IL_00c7: ldc.i4.s 10 @@ -242,23 +247,23 @@ IL_00ca: ldc.i4.0 IL_00cb: ldc.i4.0 IL_00cc: ldc.i4.1 - IL_00cd: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) + IL_00cd: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) IL_00d2: ldc.i4.s 20 IL_00d4: ldc.i4.0 IL_00d5: ldc.i4.0 IL_00d6: ldc.i4.0 IL_00d7: ldc.i4.1 - IL_00d8: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_00dd: call int32 [mscorlib]System.Decimal::Compare(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_00d8: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_00dd: call int32 [netstandard]System.Decimal::Compare(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_00e2: pop IL_00e3: ret } // end of method $Comparison_decimal01::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.bsl index 78bfe96fcc7..6dafc94cb80 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { @@ -24,6 +24,11 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101Aggregates01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -38,20 +43,20 @@ } .mresource public FSharpSignatureData.Linq101Aggregates01 { - // Offset: 0x00000000 Length: 0x00000614 + // Offset: 0x00000000 Length: 0x000005E5 } .mresource public FSharpOptimizationData.Linq101Aggregates01 { - // Offset: 0x00000618 Length: 0x00000211 + // Offset: 0x000005F0 Length: 0x00000211 } .module Linq101Aggregates01.exe -// MVID: {5B9A632A-D281-4783-A745-03832A639A5B} +// MVID: {611C52A3-D281-4783-A745-0383A3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026B0000 +// Image base: 0x06ED0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,7 +65,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname uniqueFactors@12 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 11@12' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -85,281 +90,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0009: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Aggregates01/uniqueFactors@12::current + IL_0010: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method uniqueFactors@12::.ctor + } // end of method 'Pipe #1 input at line 11@12'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Aggregates01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Aggregates01.fs' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0001: ldfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 12,12 : 9,33 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_factorsOf300() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_factorsOf300() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc .line 12,12 : 9,33 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 12,12 : 9,33 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 13,13 : 9,17 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Aggregates01/uniqueFactors@12::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc .line 12,12 : 9,33 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Aggregates01/uniqueFactors@12::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method uniqueFactors@12::GenerateNext + IL_0093: ret + } // end of method 'Pipe #1 input at line 11@12'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0001: ldfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/uniqueFactors@12::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/uniqueFactors@12::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/'Pipe #1 input at line 11@12'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/uniqueFactors@12::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Aggregates01/uniqueFactors@12::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 12,12 : 9,33 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 12,12 : 9,33 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method uniqueFactors@12::Close + IL_007f: ret + } // end of method 'Pipe #1 input at line 11@12'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Aggregates01/uniqueFactors@12::pc + IL_0001: ldfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method uniqueFactors@12::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #1 input at line 11@12'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -369,9 +344,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Aggregates01/uniqueFactors@12::current + IL_0001: ldfld int32 Linq101Aggregates01/'Pipe #1 input at line 11@12'::current IL_0006: ret - } // end of method uniqueFactors@12::get_LastGenerated + } // end of method 'Pipe #1 input at line 11@12'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -383,13 +358,13 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Aggregates01/uniqueFactors@12::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Aggregates01/'Pipe #1 input at line 11@12'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method uniqueFactors@12::GetFreshEnumerator + } // end of method 'Pipe #1 input at line 11@12'::GetFreshEnumerator - } // end of class uniqueFactors@12 + } // end of class 'Pipe #1 input at line 11@12' .class auto autochar serializable sealed nested assembly beforefieldinit specialname numSum@21 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -431,7 +406,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -442,94 +417,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 21,21 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/numSum@21::pc .line 21,21 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 21,21 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 22,22 : 9,16 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Aggregates01/numSum@21::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Aggregates01/numSum@21::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/numSum@21::pc .line 21,21 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/numSum@21::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Aggregates01/numSum@21::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Aggregates01/numSum@21::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method numSum@21::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/numSum@21::pc @@ -537,158 +505,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/numSum@21::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/numSum@21::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/numSum@21::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/numSum@21::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/numSum@21::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Aggregates01/numSum@21::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/numSum@21::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Aggregates01/numSum@21::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 21,21 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 21,21 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method numSum@21::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/numSum@21::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method numSum@21::get_CheckClose .method public strict virtual instance int32 @@ -724,6 +669,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'numSum@22-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'numSum@22-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -746,6 +692,16 @@ IL_0001: ret } // end of method 'numSum@22-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'numSum@22-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'numSum@22-1' Linq101Aggregates01/'numSum@22-1'::@_instance + IL_000a: ret + } // end of method 'numSum@22-1'::.cctor + } // end of class 'numSum@22-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname totalChars@30 @@ -788,7 +744,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) @@ -799,94 +755,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 30,30 : 9,26 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/totalChars@30::pc .line 30,30 : 9,26 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 30,30 : 9,26 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 31,31 : 9,25 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Aggregates01/totalChars@30::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Aggregates01/totalChars@30::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/totalChars@30::pc .line 30,30 : 9,26 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/totalChars@30::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Aggregates01/totalChars@30::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Aggregates01/totalChars@30::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method totalChars@30::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/totalChars@30::pc @@ -894,158 +843,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/totalChars@30::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/totalChars@30::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/totalChars@30::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/totalChars@30::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/totalChars@30::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Aggregates01/totalChars@30::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/totalChars@30::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Aggregates01/totalChars@30::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 30,30 : 9,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 30,30 : 9,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method totalChars@30::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/totalChars@30::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method totalChars@30::get_CheckClose .method public strict virtual instance string @@ -1081,6 +1007,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'totalChars@31-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'totalChars@31-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1104,9 +1031,19 @@ IL_0006: ret } // end of method 'totalChars@31-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'totalChars@31-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'totalChars@31-1' Linq101Aggregates01/'totalChars@31-1'::@_instance + IL_000a: ret + } // end of method 'totalChars@31-1'::.cctor + } // end of class 'totalChars@31-1' - .class auto ansi serializable sealed nested assembly beforefieldinit categories@39 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@39' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -1124,9 +1061,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories@39::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #2 input at line 38@39'::builder@ IL_000d: ret - } // end of method categories@39::.ctor + } // end of method 'Pipe #2 input at line 38@39'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -1139,18 +1076,19 @@ IL_0001: stloc.0 .line 40,40 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories@39::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #2 input at line 38@39'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories@39::Invoke + } // end of method 'Pipe #2 input at line 38@39'::Invoke - } // end of class categories@39 + } // end of class 'Pipe #2 input at line 38@39' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories@40-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #2 input at line 38@40-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1161,7 +1099,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories@40-1'::.ctor + } // end of method 'Pipe #2 input at line 38@40-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -1171,13 +1109,24 @@ .line 40,40 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories@40-1'::Invoke + } // end of method 'Pipe #2 input at line 38@40-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #2 input at line 38@40-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #2 input at line 38@40-1' Linq101Aggregates01/'Pipe #2 input at line 38@40-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@40-1'::.cctor - } // end of class 'categories@40-1' + } // end of class 'Pipe #2 input at line 38@40-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories@40-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #2 input at line 38@40-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1188,7 +1137,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories@40-2'::.ctor + } // end of method 'Pipe #2 input at line 38@40-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -1200,9 +1149,19 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories@40-2'::Invoke + } // end of method 'Pipe #2 input at line 38@40-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #2 input at line 38@40-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #2 input at line 38@40-2' Linq101Aggregates01/'Pipe #2 input at line 38@40-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@40-2'::.cctor - } // end of class 'categories@40-2' + } // end of class 'Pipe #2 input at line 38@40-2' .class auto autochar serializable sealed nested assembly beforefieldinit specialname sum@42 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -1249,7 +1208,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -1260,95 +1219,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 42,42 : 13,26 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/sum@42::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/sum@42::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/sum@42::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/sum@42::pc .line 42,42 : 13,26 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 42,42 : 13,26 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/sum@42::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 43,43 : 13,33 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/sum@42::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/sum@42::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/sum@42::pc .line 42,42 : 13,26 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/sum@42::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/sum@42::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method sum@42::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/sum@42::pc @@ -1356,158 +1308,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/sum@42::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/sum@42::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/sum@42::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/sum@42::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/sum@42::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/sum@42::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/sum@42::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/sum@42::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 42,42 : 13,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 42,42 : 13,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method sum@42::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/sum@42::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method sum@42::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -1546,6 +1475,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'sum@43-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'sum@43-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1570,9 +1500,19 @@ IL_0008: ret } // end of method 'sum@43-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'sum@43-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'sum@43-1' Linq101Aggregates01/'sum@43-1'::@_instance + IL_000a: ret + } // end of method 'sum@43-1'::.cctor + } // end of class 'sum@43-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories@40-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,int32>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -1590,14 +1530,14 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,int32>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories@40-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #2 input at line 38@40-3'::builder@ IL_000d: ret - } // end of method 'categories@40-3'::.ctor + } // end of method 'Pipe #2 input at line 38@40-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,int32>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed { - // Code size 145 (0x91) + // Code size 137 (0x89) .maxstack 8 .locals init ([0] class [System.Core]System.Linq.IGrouping`2 g, [1] int32 sum, @@ -1627,27 +1567,27 @@ class [Utils]Utils/Product) IL_0013: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0018: stloc.s V_4 - IL_001a: newobj instance void Linq101Aggregates01/'sum@43-1'::.ctor() + IL_001a: ldsfld class Linq101Aggregates01/'sum@43-1' Linq101Aggregates01/'sum@43-1'::@_instance IL_001f: stloc.s V_5 IL_0021: ldloc.s V_4 IL_0023: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() IL_0028: stloc.s V_6 IL_002a: ldloc.s V_6 - IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_002c: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1::GetEnumerator() IL_0031: stloc.s V_7 .try { IL_0033: ldc.i4.0 IL_0034: stloc.s V_9 IL_0036: ldloc.s V_7 - IL_0038: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0038: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() IL_003d: brfalse.s IL_0055 .line 43,43 : 13,33 '' IL_003f: ldloc.s V_9 IL_0041: ldloc.s V_5 IL_0043: ldloc.s V_7 - IL_0045: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0045: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1::get_Current() IL_004a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) IL_004f: add.ovf IL_0050: stloc.s V_9 @@ -1657,7 +1597,7 @@ IL_0055: ldloc.s V_9 IL_0057: stloc.s V_8 - IL_0059: leave.s IL_0079 + IL_0059: leave.s IL_0071 } // end .try finally @@ -1665,44 +1605,38 @@ IL_005b: ldloc.s V_7 IL_005d: isinst [mscorlib]System.IDisposable IL_0062: stloc.s V_10 + .line 100001,100001 : 0,0 '' IL_0064: ldloc.s V_10 - IL_0066: brfalse.s IL_006a - - IL_0068: br.s IL_006c - - IL_006a: br.s IL_0076 + IL_0066: brfalse.s IL_0070 .line 100001,100001 : 0,0 '' - IL_006c: ldloc.s V_10 - IL_006e: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0073: ldnull - IL_0074: pop - IL_0075: endfinally + IL_0068: ldloc.s V_10 + IL_006a: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_006f: endfinally .line 100001,100001 : 0,0 '' - IL_0076: ldnull - IL_0077: pop - IL_0078: endfinally + IL_0070: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_0079: ldloc.s V_8 - IL_007b: stloc.1 + IL_0071: ldloc.s V_8 + IL_0073: stloc.1 .line 45,45 : 9,28 '' - IL_007c: ldarg.0 - IL_007d: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories@40-3'::builder@ - IL_0082: ldloc.0 - IL_0083: ldloc.1 - IL_0084: newobj instance void class [mscorlib]System.Tuple`2,int32>::.ctor(!0, + IL_0074: ldarg.0 + IL_0075: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #2 input at line 38@40-3'::builder@ + IL_007a: ldloc.0 + IL_007b: ldloc.1 + IL_007c: newobj instance void class [mscorlib]System.Tuple`2,int32>::.ctor(!0, !1) - IL_0089: tail. - IL_008b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,int32>,object>(!!0) - IL_0090: ret - } // end of method 'categories@40-3'::Invoke + IL_0081: tail. + IL_0083: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,int32>,object>(!!0) + IL_0088: ret + } // end of method 'Pipe #2 input at line 38@40-3'::Invoke - } // end of class 'categories@40-3' + } // end of class 'Pipe #2 input at line 38@40-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories@45-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@45-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #2 input at line 38@45-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1713,7 +1647,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'categories@45-4'::.ctor + } // end of method 'Pipe #2 input at line 38@45-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2,int32> tupledArg) cil managed @@ -1736,9 +1670,19 @@ IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_001a: ret - } // end of method 'categories@45-4'::Invoke + } // end of method 'Pipe #2 input at line 38@45-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #2 input at line 38@45-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #2 input at line 38@45-4' Linq101Aggregates01/'Pipe #2 input at line 38@45-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@45-4'::.cctor - } // end of class 'categories@45-4' + } // end of class 'Pipe #2 input at line 38@45-4' .class auto autochar serializable sealed nested assembly beforefieldinit specialname minNum@49 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -1780,7 +1724,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -1791,94 +1735,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 49,49 : 22,41 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/minNum@49::pc .line 49,49 : 22,41 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 49,49 : 22,41 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 49,49 : 42,49 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Aggregates01/minNum@49::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Aggregates01/minNum@49::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/minNum@49::pc .line 49,49 : 22,41 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/minNum@49::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Aggregates01/minNum@49::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Aggregates01/minNum@49::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method minNum@49::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/minNum@49::pc @@ -1886,158 +1823,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/minNum@49::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/minNum@49::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/minNum@49::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/minNum@49::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/minNum@49::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Aggregates01/minNum@49::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/minNum@49::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Aggregates01/minNum@49::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 49,49 : 22,41 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 49,49 : 22,41 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method minNum@49::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/minNum@49::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method minNum@49::get_CheckClose .method public strict virtual instance int32 @@ -2073,6 +1987,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'minNum@49-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'minNum@49-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2095,6 +2010,16 @@ IL_0001: ret } // end of method 'minNum@49-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'minNum@49-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'minNum@49-1' Linq101Aggregates01/'minNum@49-1'::@_instance + IL_000a: ret + } // end of method 'minNum@49-1'::.cctor + } // end of class 'minNum@49-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname shortestWord@52 @@ -2137,7 +2062,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) @@ -2148,94 +2073,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 52,52 : 28,45 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/shortestWord@52::pc .line 52,52 : 28,45 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 52,52 : 28,45 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 52,52 : 46,60 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Aggregates01/shortestWord@52::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Aggregates01/shortestWord@52::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/shortestWord@52::pc .line 52,52 : 28,45 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/shortestWord@52::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Aggregates01/shortestWord@52::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Aggregates01/shortestWord@52::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method shortestWord@52::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/shortestWord@52::pc @@ -2243,158 +2161,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/shortestWord@52::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/shortestWord@52::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/shortestWord@52::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/shortestWord@52::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Aggregates01/shortestWord@52::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/shortestWord@52::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Aggregates01/shortestWord@52::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 52,52 : 28,45 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 52,52 : 28,45 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method shortestWord@52::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/shortestWord@52::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method shortestWord@52::get_CheckClose .method public strict virtual instance string @@ -2430,6 +2325,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'shortestWord@52-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'shortestWord@52-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2453,9 +2349,19 @@ IL_0006: ret } // end of method 'shortestWord@52-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'shortestWord@52-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'shortestWord@52-1' Linq101Aggregates01/'shortestWord@52-1'::@_instance + IL_000a: ret + } // end of method 'shortestWord@52-1'::.cctor + } // end of class 'shortestWord@52-1' - .class auto ansi serializable sealed nested assembly beforefieldinit categories2@57 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 56@57' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2473,9 +2379,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories2@57::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #3 input at line 56@57'::builder@ IL_000d: ret - } // end of method categories2@57::.ctor + } // end of method 'Pipe #3 input at line 56@57'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -2488,18 +2394,19 @@ IL_0001: stloc.0 .line 58,58 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories2@57::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #3 input at line 56@57'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories2@57::Invoke + } // end of method 'Pipe #3 input at line 56@57'::Invoke - } // end of class categories2@57 + } // end of class 'Pipe #3 input at line 56@57' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories2@58-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 56@58-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #3 input at line 56@58-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2510,7 +2417,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories2@58-1'::.ctor + } // end of method 'Pipe #3 input at line 56@58-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -2520,13 +2427,24 @@ .line 58,58 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories2@58-1'::Invoke + } // end of method 'Pipe #3 input at line 56@58-1'::Invoke - } // end of class 'categories2@58-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #3 input at line 56@58-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #3 input at line 56@58-1' Linq101Aggregates01/'Pipe #3 input at line 56@58-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 56@58-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories2@58-2' + } // end of class 'Pipe #3 input at line 56@58-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 56@58-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #3 input at line 56@58-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2537,7 +2455,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories2@58-2'::.ctor + } // end of method 'Pipe #3 input at line 56@58-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -2549,9 +2467,19 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories2@58-2'::Invoke + } // end of method 'Pipe #3 input at line 56@58-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #3 input at line 56@58-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #3 input at line 56@58-2' Linq101Aggregates01/'Pipe #3 input at line 56@58-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 56@58-2'::.cctor - } // end of class 'categories2@58-2' + } // end of class 'Pipe #3 input at line 56@58-2' .class auto autochar serializable sealed nested assembly beforefieldinit specialname min@59 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -2598,7 +2526,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -2609,95 +2537,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 59,59 : 27,40 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/min@59::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/min@59::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/min@59::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/min@59::pc .line 59,59 : 27,40 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 59,59 : 27,40 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/min@59::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 59,59 : 41,58 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/min@59::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/min@59::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/min@59::pc .line 59,59 : 27,40 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/min@59::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/min@59::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method min@59::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/min@59::pc @@ -2705,158 +2626,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/min@59::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/min@59::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/min@59::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/min@59::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/min@59::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/min@59::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/min@59::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/min@59::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 59,59 : 27,40 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 59,59 : 27,40 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method min@59::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/min@59::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method min@59::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -2895,6 +2793,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'min@59-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'min@59-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2919,9 +2818,19 @@ IL_0008: ret } // end of method 'min@59-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'min@59-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'min@59-1' Linq101Aggregates01/'min@59-1'::@_instance + IL_000a: ret + } // end of method 'min@59-1'::.cctor + } // end of class 'min@59-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories2@58-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 56@58-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2939,9 +2848,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories2@58-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #3 input at line 56@58-3'::builder@ IL_000d: ret - } // end of method 'categories2@58-3'::.ctor + } // end of method 'Pipe #3 input at line 56@58-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -2963,13 +2872,13 @@ int32, class [Utils]Utils/Product) IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0015: newobj instance void Linq101Aggregates01/'min@59-1'::.ctor() + IL_0015: ldsfld class Linq101Aggregates01/'min@59-1' Linq101Aggregates01/'min@59-1'::@_instance IL_001a: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_001f: stloc.1 .line 60,60 : 9,28 '' IL_0020: ldarg.0 - IL_0021: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories2@58-3'::builder@ + IL_0021: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #3 input at line 56@58-3'::builder@ IL_0026: ldloc.0 IL_0027: ldloc.1 IL_0028: newobj instance void class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>::.ctor(!0, @@ -2977,13 +2886,14 @@ IL_002d: tail. IL_002f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal>,object>(!!0) IL_0034: ret - } // end of method 'categories2@58-3'::Invoke + } // end of method 'Pipe #3 input at line 56@58-3'::Invoke - } // end of class 'categories2@58-3' + } // end of class 'Pipe #3 input at line 56@58-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories2@60-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 56@60-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #3 input at line 56@60-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2994,7 +2904,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'categories2@60-4'::.ctor + } // end of method 'Pipe #3 input at line 56@60-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal> tupledArg) cil managed @@ -3017,11 +2927,21 @@ IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_001a: ret - } // end of method 'categories2@60-4'::Invoke + } // end of method 'Pipe #3 input at line 56@60-4'::Invoke - } // end of class 'categories2@60-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #3 input at line 56@60-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #3 input at line 56@60-4' Linq101Aggregates01/'Pipe #3 input at line 56@60-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 56@60-4'::.cctor + + } // end of class 'Pipe #3 input at line 56@60-4' - .class auto ansi serializable sealed nested assembly beforefieldinit categories3@66 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 65@66' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -3039,9 +2959,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories3@66::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #4 input at line 65@66'::builder@ IL_000d: ret - } // end of method categories3@66::.ctor + } // end of method 'Pipe #4 input at line 65@66'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -3054,18 +2974,19 @@ IL_0001: stloc.0 .line 67,67 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories3@66::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #4 input at line 65@66'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories3@66::Invoke + } // end of method 'Pipe #4 input at line 65@66'::Invoke - } // end of class categories3@66 + } // end of class 'Pipe #4 input at line 65@66' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories3@67-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 65@67-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #4 input at line 65@67-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3076,7 +2997,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories3@67-1'::.ctor + } // end of method 'Pipe #4 input at line 65@67-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -3086,13 +3007,24 @@ .line 67,67 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories3@67-1'::Invoke + } // end of method 'Pipe #4 input at line 65@67-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #4 input at line 65@67-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #4 input at line 65@67-1' Linq101Aggregates01/'Pipe #4 input at line 65@67-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 65@67-1'::.cctor - } // end of class 'categories3@67-1' + } // end of class 'Pipe #4 input at line 65@67-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories3@67-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 65@67-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #4 input at line 65@67-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3103,7 +3035,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories3@67-2'::.ctor + } // end of method 'Pipe #4 input at line 65@67-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -3115,31 +3047,31 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories3@67-2'::Invoke + } // end of method 'Pipe #4 input at line 65@67-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #4 input at line 65@67-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #4 input at line 65@67-2' Linq101Aggregates01/'Pipe #4 input at line 65@67-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 65@67-2'::.cctor - } // end of class 'categories3@67-2' + } // end of class 'Pipe #4 input at line 65@67-2' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'min@68-2' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname 'min@68-2' extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'min@68-2'::.ctor - - .method assembly hidebysig instance valuetype [mscorlib]System.Decimal + .method assembly static valuetype [mscorlib]System.Decimal Invoke(class [Utils]Utils/Product p) cil managed { // Code size 9 (0x9) .maxstack 8 .line 68,68 : 46,57 '' - IL_0000: ldarg.1 + IL_0000: ldarg.0 IL_0001: tail. IL_0003: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() IL_0008: ret @@ -3192,7 +3124,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -3203,95 +3135,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 69,69 : 40,53 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/cheapestProducts@69::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/cheapestProducts@69::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc .line 69,69 : 40,53 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 69,69 : 40,53 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 69,69 : 54,79 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc .line 69,69 : 40,53 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method cheapestProducts@69::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/cheapestProducts@69::pc @@ -3299,158 +3224,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/cheapestProducts@69::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/cheapestProducts@69::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/cheapestProducts@69::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/cheapestProducts@69::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 69,69 : 40,53 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 69,69 : 40,53 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method cheapestProducts@69::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/cheapestProducts@69::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method cheapestProducts@69::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -3515,14 +3417,14 @@ IL_0001: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() IL_0006: ldarg.0 IL_0007: ldfld valuetype [mscorlib]System.Decimal Linq101Aggregates01/'cheapestProducts@69-1'::min - IL_000c: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_000c: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0011: ret } // end of method 'cheapestProducts@69-1'::Invoke } // end of class 'cheapestProducts@69-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories3@67-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 65@67-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -3540,14 +3442,14 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories3@67-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #4 input at line 65@67-3'::builder@ IL_000d: ret - } // end of method 'categories3@67-3'::.ctor + } // end of method 'Pipe #4 input at line 65@67-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed { - // Code size 85 (0x55) + // Code size 81 (0x51) .maxstack 9 .locals init ([0] class [System.Core]System.Linq.IGrouping`2 g, [1] valuetype [mscorlib]System.Decimal min, @@ -3558,51 +3460,52 @@ IL_0001: stloc.0 .line 68,68 : 9,58 '' IL_0002: ldloc.0 - IL_0003: newobj instance void Linq101Aggregates01/'min@68-2'::.ctor() - IL_0008: ldftn instance valuetype [mscorlib]System.Decimal Linq101Aggregates01/'min@68-2'::Invoke(class [Utils]Utils/Product) - IL_000e: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + IL_0003: ldnull + IL_0004: ldftn valuetype [mscorlib]System.Decimal Linq101Aggregates01/'min@68-2'::Invoke(class [Utils]Utils/Product) + IL_000a: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) - IL_0013: call valuetype [mscorlib]System.Decimal [System.Core]System.Linq.Enumerable::Min(class [mscorlib]System.Collections.Generic.IEnumerable`1, + IL_000f: call valuetype [mscorlib]System.Decimal [System.Core]System.Linq.Enumerable::Min(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) - IL_0018: stloc.1 + IL_0014: stloc.1 .line 70,70 : 9,41 '' - IL_0019: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_001e: stloc.3 - IL_001f: ldloc.3 - IL_0020: ldloc.0 - IL_0021: ldnull - IL_0022: ldc.i4.0 - IL_0023: ldnull - IL_0024: newobj instance void Linq101Aggregates01/cheapestProducts@69::.ctor(class [System.Core]System.Linq.IGrouping`2, + IL_0015: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_001a: stloc.3 + IL_001b: ldloc.3 + IL_001c: ldloc.0 + IL_001d: ldnull + IL_001e: ldc.i4.0 + IL_001f: ldnull + IL_0020: newobj instance void Linq101Aggregates01/cheapestProducts@69::.ctor(class [System.Core]System.Linq.IGrouping`2, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, class [Utils]Utils/Product) - IL_0029: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_002e: ldloc.1 - IL_002f: newobj instance void Linq101Aggregates01/'cheapestProducts@69-1'::.ctor(valuetype [mscorlib]System.Decimal) - IL_0034: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0025: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_002a: ldloc.1 + IL_002b: newobj instance void Linq101Aggregates01/'cheapestProducts@69-1'::.ctor(valuetype [mscorlib]System.Decimal) + IL_0030: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0039: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_003e: stloc.2 + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_003a: stloc.2 .line 70,70 : 9,41 '' - IL_003f: ldarg.0 - IL_0040: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories3@67-3'::builder@ - IL_0045: ldloc.0 - IL_0046: ldloc.1 - IL_0047: ldloc.2 - IL_0048: newobj instance void class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>::.ctor(!0, + IL_003b: ldarg.0 + IL_003c: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #4 input at line 65@67-3'::builder@ + IL_0041: ldloc.0 + IL_0042: ldloc.1 + IL_0043: ldloc.2 + IL_0044: newobj instance void class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>::.ctor(!0, !1, !2) - IL_004d: tail. - IL_004f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(!!0) - IL_0054: ret - } // end of method 'categories3@67-3'::Invoke + IL_0049: tail. + IL_004b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(!!0) + IL_0050: ret + } // end of method 'Pipe #4 input at line 65@67-3'::Invoke - } // end of class 'categories3@67-3' + } // end of class 'Pipe #4 input at line 65@67-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories3@70-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 65@70-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #4 input at line 65@70-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3613,7 +3516,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'categories3@70-4'::.ctor + } // end of method 'Pipe #4 input at line 65@70-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1> tupledArg) cil managed @@ -3640,9 +3543,19 @@ IL_001c: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0021: ret - } // end of method 'categories3@70-4'::Invoke + } // end of method 'Pipe #4 input at line 65@70-4'::Invoke - } // end of class 'categories3@70-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #4 input at line 65@70-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #4 input at line 65@70-4' Linq101Aggregates01/'Pipe #4 input at line 65@70-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 65@70-4'::.cctor + + } // end of class 'Pipe #4 input at line 65@70-4' .class auto autochar serializable sealed nested assembly beforefieldinit specialname maxNum@74 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -3684,7 +3597,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -3695,94 +3608,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 74,74 : 22,41 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/maxNum@74::pc .line 74,74 : 22,41 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 74,74 : 22,41 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 74,74 : 42,49 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Aggregates01/maxNum@74::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Aggregates01/maxNum@74::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/maxNum@74::pc .line 74,74 : 22,41 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/maxNum@74::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Aggregates01/maxNum@74::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Aggregates01/maxNum@74::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method maxNum@74::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/maxNum@74::pc @@ -3790,158 +3696,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/maxNum@74::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/maxNum@74::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/maxNum@74::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxNum@74::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/maxNum@74::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Aggregates01/maxNum@74::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/maxNum@74::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Aggregates01/maxNum@74::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 74,74 : 22,41 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 74,74 : 22,41 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method maxNum@74::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/maxNum@74::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method maxNum@74::get_CheckClose .method public strict virtual instance int32 @@ -3977,6 +3860,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'maxNum@74-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'maxNum@74-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3999,6 +3883,16 @@ IL_0001: ret } // end of method 'maxNum@74-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'maxNum@74-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'maxNum@74-1' Linq101Aggregates01/'maxNum@74-1'::@_instance + IL_000a: ret + } // end of method 'maxNum@74-1'::.cctor + } // end of class 'maxNum@74-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname longestLength@77 @@ -4041,7 +3935,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) @@ -4052,94 +3946,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 77,77 : 29,46 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/longestLength@77::pc .line 77,77 : 29,46 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 77,77 : 29,46 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 77,77 : 47,61 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Aggregates01/longestLength@77::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Aggregates01/longestLength@77::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/longestLength@77::pc .line 77,77 : 29,46 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/longestLength@77::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Aggregates01/longestLength@77::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Aggregates01/longestLength@77::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method longestLength@77::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/longestLength@77::pc @@ -4147,158 +4034,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/longestLength@77::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/longestLength@77::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/longestLength@77::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/longestLength@77::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/longestLength@77::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Aggregates01/longestLength@77::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/longestLength@77::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Aggregates01/longestLength@77::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 77,77 : 29,46 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 77,77 : 29,46 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method longestLength@77::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/longestLength@77::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method longestLength@77::get_CheckClose .method public strict virtual instance string @@ -4334,6 +4198,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'longestLength@77-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'longestLength@77-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4357,9 +4222,19 @@ IL_0006: ret } // end of method 'longestLength@77-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'longestLength@77-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'longestLength@77-1' Linq101Aggregates01/'longestLength@77-1'::@_instance + IL_000a: ret + } // end of method 'longestLength@77-1'::.cctor + } // end of class 'longestLength@77-1' - .class auto ansi serializable sealed nested assembly beforefieldinit categories4@82 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 81@82' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -4377,9 +4252,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories4@82::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #5 input at line 81@82'::builder@ IL_000d: ret - } // end of method categories4@82::.ctor + } // end of method 'Pipe #5 input at line 81@82'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -4392,18 +4267,19 @@ IL_0001: stloc.0 .line 83,83 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories4@82::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #5 input at line 81@82'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories4@82::Invoke + } // end of method 'Pipe #5 input at line 81@82'::Invoke - } // end of class categories4@82 + } // end of class 'Pipe #5 input at line 81@82' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories4@83-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 81@83-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #5 input at line 81@83-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4414,7 +4290,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories4@83-1'::.ctor + } // end of method 'Pipe #5 input at line 81@83-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -4424,13 +4300,24 @@ .line 83,83 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories4@83-1'::Invoke + } // end of method 'Pipe #5 input at line 81@83-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #5 input at line 81@83-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #5 input at line 81@83-1' Linq101Aggregates01/'Pipe #5 input at line 81@83-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 81@83-1'::.cctor - } // end of class 'categories4@83-1' + } // end of class 'Pipe #5 input at line 81@83-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories4@83-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 81@83-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #5 input at line 81@83-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4441,7 +4328,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories4@83-2'::.ctor + } // end of method 'Pipe #5 input at line 81@83-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -4453,9 +4340,19 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories4@83-2'::Invoke + } // end of method 'Pipe #5 input at line 81@83-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #5 input at line 81@83-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #5 input at line 81@83-2' Linq101Aggregates01/'Pipe #5 input at line 81@83-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 81@83-2'::.cctor - } // end of class 'categories4@83-2' + } // end of class 'Pipe #5 input at line 81@83-2' .class auto autochar serializable sealed nested assembly beforefieldinit specialname mostExpensivePrice@84 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -4502,7 +4399,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -4513,95 +4410,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 84,84 : 42,55 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/mostExpensivePrice@84::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/mostExpensivePrice@84::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc .line 84,84 : 42,55 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 84,84 : 42,55 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 84,84 : 56,73 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc .line 84,84 : 42,55 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method mostExpensivePrice@84::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc @@ -4609,158 +4499,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensivePrice@84::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensivePrice@84::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 84,84 : 42,55 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 84,84 : 42,55 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method mostExpensivePrice@84::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/mostExpensivePrice@84::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method mostExpensivePrice@84::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -4799,6 +4666,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'mostExpensivePrice@84-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'mostExpensivePrice@84-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4823,9 +4691,19 @@ IL_0008: ret } // end of method 'mostExpensivePrice@84-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'mostExpensivePrice@84-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'mostExpensivePrice@84-1' Linq101Aggregates01/'mostExpensivePrice@84-1'::@_instance + IL_000a: ret + } // end of method 'mostExpensivePrice@84-1'::.cctor + } // end of class 'mostExpensivePrice@84-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories4@83-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 81@83-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -4843,9 +4721,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories4@83-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #5 input at line 81@83-3'::builder@ IL_000d: ret - } // end of method 'categories4@83-3'::.ctor + } // end of method 'Pipe #5 input at line 81@83-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -4867,13 +4745,13 @@ int32, class [Utils]Utils/Product) IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0015: newobj instance void Linq101Aggregates01/'mostExpensivePrice@84-1'::.ctor() + IL_0015: ldsfld class Linq101Aggregates01/'mostExpensivePrice@84-1' Linq101Aggregates01/'mostExpensivePrice@84-1'::@_instance IL_001a: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_001f: stloc.1 .line 85,85 : 9,43 '' IL_0020: ldarg.0 - IL_0021: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories4@83-3'::builder@ + IL_0021: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #5 input at line 81@83-3'::builder@ IL_0026: ldloc.0 IL_0027: ldloc.1 IL_0028: newobj instance void class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>::.ctor(!0, @@ -4881,13 +4759,14 @@ IL_002d: tail. IL_002f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal>,object>(!!0) IL_0034: ret - } // end of method 'categories4@83-3'::Invoke + } // end of method 'Pipe #5 input at line 81@83-3'::Invoke - } // end of class 'categories4@83-3' + } // end of class 'Pipe #5 input at line 81@83-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories4@85-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 81@85-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #5 input at line 81@85-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4898,7 +4777,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'categories4@85-4'::.ctor + } // end of method 'Pipe #5 input at line 81@85-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal> tupledArg) cil managed @@ -4921,11 +4800,21 @@ IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_001a: ret - } // end of method 'categories4@85-4'::Invoke + } // end of method 'Pipe #5 input at line 81@85-4'::Invoke - } // end of class 'categories4@85-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #5 input at line 81@85-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #5 input at line 81@85-4' Linq101Aggregates01/'Pipe #5 input at line 81@85-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 81@85-4'::.cctor + + } // end of class 'Pipe #5 input at line 81@85-4' - .class auto ansi serializable sealed nested assembly beforefieldinit categories5@91 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 90@91' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -4943,9 +4832,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories5@91::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #6 input at line 90@91'::builder@ IL_000d: ret - } // end of method categories5@91::.ctor + } // end of method 'Pipe #6 input at line 90@91'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -4958,18 +4847,19 @@ IL_0001: stloc.0 .line 92,92 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories5@91::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #6 input at line 90@91'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories5@91::Invoke + } // end of method 'Pipe #6 input at line 90@91'::Invoke - } // end of class categories5@91 + } // end of class 'Pipe #6 input at line 90@91' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories5@92-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 90@92-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #6 input at line 90@92-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -4980,7 +4870,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories5@92-1'::.ctor + } // end of method 'Pipe #6 input at line 90@92-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -4990,13 +4880,24 @@ .line 92,92 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories5@92-1'::Invoke + } // end of method 'Pipe #6 input at line 90@92-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #6 input at line 90@92-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #6 input at line 90@92-1' Linq101Aggregates01/'Pipe #6 input at line 90@92-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 90@92-1'::.cctor - } // end of class 'categories5@92-1' + } // end of class 'Pipe #6 input at line 90@92-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories5@92-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 90@92-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #6 input at line 90@92-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -5007,7 +4908,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories5@92-2'::.ctor + } // end of method 'Pipe #6 input at line 90@92-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -5019,9 +4920,19 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories5@92-2'::Invoke + } // end of method 'Pipe #6 input at line 90@92-2'::Invoke - } // end of class 'categories5@92-2' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #6 input at line 90@92-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #6 input at line 90@92-2' Linq101Aggregates01/'Pipe #6 input at line 90@92-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 90@92-2'::.cctor + + } // end of class 'Pipe #6 input at line 90@92-2' .class auto autochar serializable sealed nested assembly beforefieldinit specialname maxPrice@93 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -5068,7 +4979,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -5079,95 +4990,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 93,93 : 32,45 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/maxPrice@93::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/maxPrice@93::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/maxPrice@93::pc .line 93,93 : 32,45 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 93,93 : 32,45 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 93,93 : 46,63 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/maxPrice@93::pc .line 93,93 : 32,45 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/maxPrice@93::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method maxPrice@93::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/maxPrice@93::pc @@ -5175,158 +5079,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/maxPrice@93::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/maxPrice@93::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/maxPrice@93::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/maxPrice@93::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/maxPrice@93::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/maxPrice@93::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 93,93 : 32,45 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 93,93 : 32,45 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method maxPrice@93::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/maxPrice@93::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method maxPrice@93::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -5365,6 +5246,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'maxPrice@93-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'maxPrice@93-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -5389,6 +5271,16 @@ IL_0008: ret } // end of method 'maxPrice@93-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'maxPrice@93-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'maxPrice@93-1' Linq101Aggregates01/'maxPrice@93-1'::@_instance + IL_000a: ret + } // end of method 'maxPrice@93-1'::.cctor + } // end of class 'maxPrice@93-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname mostExpensiveProducts@94 @@ -5436,7 +5328,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -5447,95 +5339,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 94,94 : 45,58 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/mostExpensiveProducts@94::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/mostExpensiveProducts@94::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc .line 94,94 : 45,58 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 94,94 : 45,58 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 94,94 : 59,89 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc .line 94,94 : 45,58 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method mostExpensiveProducts@94::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc @@ -5543,158 +5428,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/mostExpensiveProducts@94::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/mostExpensiveProducts@94::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 94,94 : 45,58 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 94,94 : 45,58 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method mostExpensiveProducts@94::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/mostExpensiveProducts@94::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method mostExpensiveProducts@94::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -5759,14 +5621,14 @@ IL_0001: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() IL_0006: ldarg.0 IL_0007: ldfld valuetype [mscorlib]System.Decimal Linq101Aggregates01/'mostExpensiveProducts@94-1'::maxPrice - IL_000c: call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_000c: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0011: ret } // end of method 'mostExpensiveProducts@94-1'::Invoke } // end of class 'mostExpensiveProducts@94-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories5@92-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 90@92-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -5784,9 +5646,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories5@92-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #6 input at line 90@92-3'::builder@ IL_000d: ret - } // end of method 'categories5@92-3'::.ctor + } // end of method 'Pipe #6 input at line 90@92-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -5810,7 +5672,7 @@ int32, class [Utils]Utils/Product) IL_0010: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0015: newobj instance void Linq101Aggregates01/'maxPrice@93-1'::.ctor() + IL_0015: ldsfld class Linq101Aggregates01/'maxPrice@93-1' Linq101Aggregates01/'maxPrice@93-1'::@_instance IL_001a: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_001f: stloc.1 @@ -5835,7 +5697,7 @@ IL_0045: stloc.2 .line 95,95 : 9,46 '' IL_0046: ldarg.0 - IL_0047: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories5@92-3'::builder@ + IL_0047: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #6 input at line 90@92-3'::builder@ IL_004c: ldloc.0 IL_004d: ldloc.1 IL_004e: ldloc.2 @@ -5845,13 +5707,14 @@ IL_0054: tail. IL_0056: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(!!0) IL_005b: ret - } // end of method 'categories5@92-3'::Invoke + } // end of method 'Pipe #6 input at line 90@92-3'::Invoke - } // end of class 'categories5@92-3' + } // end of class 'Pipe #6 input at line 90@92-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories5@95-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 90@95-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #6 input at line 90@95-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -5862,7 +5725,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'categories5@95-4'::.ctor + } // end of method 'Pipe #6 input at line 90@95-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1> tupledArg) cil managed @@ -5889,9 +5752,19 @@ IL_001c: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0021: ret - } // end of method 'categories5@95-4'::Invoke + } // end of method 'Pipe #6 input at line 90@95-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #6 input at line 90@95-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #6 input at line 90@95-4' Linq101Aggregates01/'Pipe #6 input at line 90@95-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 90@95-4'::.cctor - } // end of class 'categories5@95-4' + } // end of class 'Pipe #6 input at line 90@95-4' .class auto autochar serializable sealed nested assembly beforefieldinit specialname averageNum@100 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -5933,7 +5806,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 162 (0xa2) + // Code size 156 (0x9c) .maxstack 6 .locals init ([0] float64 V_0, [1] float64 n) @@ -5944,94 +5817,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 100,100 : 26,46 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers2() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_numbers2() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Aggregates01/averageNum@100::pc .line 100,100 : 26,46 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 100,100 : 26,46 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 100,100 : 47,58 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld float64 Linq101Aggregates01/averageNum@100::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld float64 Linq101Aggregates01/averageNum@100::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Aggregates01/averageNum@100::pc .line 100,100 : 26,46 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Aggregates01/averageNum@100::pc - IL_0091: ldarg.0 - IL_0092: ldc.r8 0.0 - IL_009b: stfld float64 Linq101Aggregates01/averageNum@100::current - IL_00a0: ldc.i4.0 - IL_00a1: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_008b: ldarg.0 + IL_008c: ldc.r8 0.0 + IL_0095: stfld float64 Linq101Aggregates01/averageNum@100::current + IL_009a: ldc.i4.0 + IL_009b: ret } // end of method averageNum@100::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 156 (0x9c) + // Code size 136 (0x88) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/averageNum@100::pc @@ -6039,158 +5905,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_008f + IL_0014: br.s IL_007e .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/averageNum@100::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/averageNum@100::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/averageNum@100::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averageNum@100::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/averageNum@100::pc - IL_0068: ldarg.0 - IL_0069: ldc.r8 0.0 - IL_0072: stfld float64 Linq101Aggregates01/averageNum@100::current - IL_0077: ldnull - IL_0078: stloc.1 - IL_0079: leave.s IL_0087 + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/averageNum@100::pc + IL_005d: ldarg.0 + IL_005e: ldc.r8 0.0 + IL_0067: stfld float64 Linq101Aggregates01/averageNum@100::current + IL_006c: leave.s IL_0078 } // end .try catch [mscorlib]System.Object { - IL_007b: castclass [mscorlib]System.Exception - IL_0080: stloc.2 + IL_006e: castclass [mscorlib]System.Exception + IL_0073: stloc.1 .line 100,100 : 26,46 '' - IL_0081: ldloc.2 - IL_0082: stloc.0 - IL_0083: ldnull - IL_0084: stloc.1 - IL_0085: leave.s IL_0087 + IL_0074: ldloc.1 + IL_0075: stloc.0 + IL_0076: leave.s IL_0078 .line 100001,100001 : 0,0 '' } // end handler - IL_0087: ldloc.1 - IL_0088: pop - .line 100001,100001 : 0,0 '' - IL_0089: nop - IL_008a: br IL_0000 - - IL_008f: ldloc.0 - IL_0090: ldnull - IL_0091: cgt.un - IL_0093: brfalse.s IL_0097 + IL_0078: nop + IL_0079: br IL_0000 - IL_0095: br.s IL_0099 - - IL_0097: br.s IL_009b + .line 100,100 : 26,46 '' + IL_007e: nop + .line 100001,100001 : 0,0 '' + IL_007f: ldloc.0 + IL_0080: ldnull + IL_0081: cgt.un + IL_0083: brfalse.s IL_0087 .line 100001,100001 : 0,0 '' - IL_0099: ldloc.0 - IL_009a: throw + IL_0085: ldloc.0 + IL_0086: throw .line 100001,100001 : 0,0 '' - IL_009b: ret + IL_0087: ret } // end of method averageNum@100::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/averageNum@100::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method averageNum@100::get_CheckClose .method public strict virtual instance float64 @@ -6226,6 +6069,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'averageNum@100-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'averageNum@100-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6248,6 +6092,16 @@ IL_0001: ret } // end of method 'averageNum@100-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'averageNum@100-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'averageNum@100-1' Linq101Aggregates01/'averageNum@100-1'::@_instance + IL_000a: ret + } // end of method 'averageNum@100-1'::.cctor + } // end of class 'averageNum@100-1' .class auto ansi serializable sealed nested assembly beforefieldinit averageLength@105 @@ -6275,28 +6129,34 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(string _arg1) cil managed { - // Code size 31 (0x1f) + // Code size 34 (0x22) .maxstack 7 .locals init ([0] string w, - [1] float64 wl) + [1] float64 wl, + [2] int32 'Pipe #1 input at line 106') .line 105,105 : 9,26 '' IL_0000: ldarg.1 IL_0001: stloc.0 .line 106,106 : 9,35 '' - IL_0002: ldloc.0 - IL_0003: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_0008: conv.r8 - IL_0009: stloc.1 + IL_0002: nop + .line 106,106 : 18,26 '' + IL_0003: ldloc.0 + IL_0004: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_0009: stloc.2 + .line 106,106 : 30,35 '' + IL_000a: ldloc.2 + IL_000b: conv.r8 + IL_000c: stloc.1 .line 107,107 : 9,21 '' - IL_000a: ldarg.0 - IL_000b: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/averageLength@105::builder@ - IL_0010: ldloc.0 - IL_0011: ldloc.1 - IL_0012: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_000d: ldarg.0 + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/averageLength@105::builder@ + IL_0013: ldloc.0 + IL_0014: ldloc.1 + IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0017: tail. - IL_0019: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) - IL_001e: ret + IL_001a: tail. + IL_001c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) + IL_0021: ret } // end of method averageLength@105::Invoke } // end of class averageLength@105 @@ -6304,6 +6164,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'averageLength@107-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64> { + .field static assembly initonly class Linq101Aggregates01/'averageLength@107-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6335,9 +6196,19 @@ IL_000f: ret } // end of method 'averageLength@107-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'averageLength@107-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'averageLength@107-1' Linq101Aggregates01/'averageLength@107-1'::@_instance + IL_000a: ret + } // end of method 'averageLength@107-1'::.cctor + } // end of class 'averageLength@107-1' - .class auto ansi serializable sealed nested assembly beforefieldinit categories6@113 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 112@113' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -6355,9 +6226,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories6@113::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #7 input at line 112@113'::builder@ IL_000d: ret - } // end of method categories6@113::.ctor + } // end of method 'Pipe #7 input at line 112@113'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -6370,18 +6241,19 @@ IL_0001: stloc.0 .line 114,114 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/categories6@113::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #7 input at line 112@113'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method categories6@113::Invoke + } // end of method 'Pipe #7 input at line 112@113'::Invoke - } // end of class categories6@113 + } // end of class 'Pipe #7 input at line 112@113' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories6@114-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 112@114-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #7 input at line 112@114-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6392,7 +6264,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories6@114-1'::.ctor + } // end of method 'Pipe #7 input at line 112@114-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -6402,13 +6274,24 @@ .line 114,114 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'categories6@114-1'::Invoke + } // end of method 'Pipe #7 input at line 112@114-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #7 input at line 112@114-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #7 input at line 112@114-1' Linq101Aggregates01/'Pipe #7 input at line 112@114-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #7 input at line 112@114-1'::.cctor - } // end of class 'categories6@114-1' + } // end of class 'Pipe #7 input at line 112@114-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories6@114-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 112@114-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'Pipe #7 input at line 112@114-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6419,7 +6302,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'categories6@114-2'::.ctor + } // end of method 'Pipe #7 input at line 112@114-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -6431,9 +6314,19 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'categories6@114-2'::Invoke + } // end of method 'Pipe #7 input at line 112@114-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #7 input at line 112@114-2'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #7 input at line 112@114-2' Linq101Aggregates01/'Pipe #7 input at line 112@114-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #7 input at line 112@114-2'::.cctor - } // end of class 'categories6@114-2' + } // end of class 'Pipe #7 input at line 112@114-2' .class auto autochar serializable sealed nested assembly beforefieldinit specialname averagePrice@115 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -6480,7 +6373,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 155 (0x9b) + // Code size 149 (0x95) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product x) @@ -6491,95 +6384,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0071 + IL_001b: nop + IL_001c: br.s IL_006b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006e + IL_001e: nop + IL_001f: br.s IL_0068 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0092 + IL_0021: nop + IL_0022: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 115,115 : 36,49 '' - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/averagePrice@115::g - IL_0032: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0037: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_003c: ldarg.0 - IL_003d: ldc.i4.1 - IL_003e: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_0025: ldarg.0 + IL_0026: ldarg.0 + IL_0027: ldfld class [System.Core]System.Linq.IGrouping`2 Linq101Aggregates01/averagePrice@115::g + IL_002c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0031: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld int32 Linq101Aggregates01/averagePrice@115::pc .line 115,115 : 36,49 '' - IL_0043: ldarg.0 - IL_0044: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_0049: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004e: brfalse.s IL_0071 - - IL_0050: ldarg.0 - IL_0051: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_0056: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005b: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_0043: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0048: brfalse.s IL_006b + + IL_004a: ldarg.0 + IL_004b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_0050: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0055: stloc.0 .line 115,115 : 36,49 '' - IL_005c: ldloc.0 - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldc.i4.2 - IL_0060: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_0056: ldloc.0 + IL_0057: stloc.1 .line 115,115 : 50,71 '' - IL_0065: ldarg.0 - IL_0066: ldloc.1 - IL_0067: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current - IL_006c: ldc.i4.1 - IL_006d: ret - - .line 100001,100001 : 0,0 '' - IL_006e: nop - IL_006f: br.s IL_0043 - - IL_0071: ldarg.0 - IL_0072: ldc.i4.3 - IL_0073: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_0058: ldarg.0 + IL_0059: ldc.i4.2 + IL_005a: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current + IL_0066: ldc.i4.1 + IL_0067: ret + + .line 100001,100001 : 0,0 '' + IL_0068: nop + IL_0069: br.s IL_003d + + IL_006b: ldarg.0 + IL_006c: ldc.i4.3 + IL_006d: stfld int32 Linq101Aggregates01/averagePrice@115::pc .line 115,115 : 36,49 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_007e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: ldnull - IL_0086: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Aggregates01/averagePrice@115::pc - IL_0092: ldarg.0 - IL_0093: ldnull - IL_0094: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current - IL_0099: ldc.i4.0 - IL_009a: ret + IL_0072: ldarg.0 + IL_0073: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_0078: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldnull + IL_0080: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_008c: ldarg.0 + IL_008d: ldnull + IL_008e: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current + IL_0093: ldc.i4.0 + IL_0094: ret } // end of method averagePrice@115::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/averagePrice@115::pc @@ -6587,158 +6473,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Aggregates01/averagePrice@115::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Aggregates01/averagePrice@115::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Aggregates01/averagePrice@115::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Aggregates01/averagePrice@115::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Aggregates01/averagePrice@115::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Aggregates01/averagePrice@115::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 115,115 : 36,49 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 115,115 : 36,49 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method averagePrice@115::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/averagePrice@115::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method averagePrice@115::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -6777,6 +6640,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'averagePrice@115-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Aggregates01/'averagePrice@115-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6801,9 +6665,19 @@ IL_0008: ret } // end of method 'averagePrice@115-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'averagePrice@115-1'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'averagePrice@115-1' Linq101Aggregates01/'averagePrice@115-1'::@_instance + IL_000a: ret + } // end of method 'averagePrice@115-1'::.cctor + } // end of class 'averagePrice@115-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories6@114-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 112@114-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -6821,14 +6695,14 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories6@114-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #7 input at line 112@114-3'::builder@ IL_000d: ret - } // end of method 'categories6@114-3'::.ctor + } // end of method 'Pipe #7 input at line 112@114-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,valuetype [mscorlib]System.Decimal>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed { - // Code size 230 (0xe6) + // Code size 216 (0xd8) .maxstack 9 .locals init ([0] class [System.Core]System.Linq.IGrouping`2 g, [1] valuetype [mscorlib]System.Decimal averagePrice, @@ -6861,133 +6735,123 @@ class [Utils]Utils/Product) IL_0013: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0018: stloc.s V_4 - IL_001a: newobj instance void Linq101Aggregates01/'averagePrice@115-1'::.ctor() + IL_001a: ldsfld class Linq101Aggregates01/'averagePrice@115-1' Linq101Aggregates01/'averagePrice@115-1'::@_instance IL_001f: stloc.s V_5 IL_0021: ldloc.s V_4 IL_0023: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() IL_0028: stloc.s V_6 + .line 100001,100001 : 0,0 '' IL_002a: ldloc.s V_6 IL_002c: box class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0031: brfalse.s IL_0035 - - IL_0033: br.s IL_0040 + IL_0031: brtrue.s IL_003e .line 100001,100001 : 0,0 '' - IL_0035: ldstr "source" - IL_003a: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) - IL_003f: throw + IL_0033: ldstr "source" + IL_0038: newobj instance void [netstandard]System.ArgumentNullException::.ctor(string) + IL_003d: throw .line 100001,100001 : 0,0 '' - IL_0040: nop - IL_0041: ldloc.s V_6 - IL_0043: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0048: stloc.s V_7 + IL_003e: nop + IL_003f: ldloc.s V_6 + IL_0041: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0046: stloc.s V_7 .try { + IL_0048: ldc.i4.0 + IL_0049: ldc.i4.0 IL_004a: ldc.i4.0 IL_004b: ldc.i4.0 IL_004c: ldc.i4.0 - IL_004d: ldc.i4.0 - IL_004e: ldc.i4.0 - IL_004f: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0054: stloc.s V_9 - IL_0056: ldc.i4.0 - IL_0057: stloc.s V_10 - IL_0059: ldloc.s V_7 - IL_005b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0060: brfalse.s IL_0082 - - IL_0062: ldloc.s V_9 - IL_0064: ldloc.s V_5 - IL_0066: ldloc.s V_7 - IL_0068: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_006d: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0072: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) - IL_0077: stloc.s V_9 + IL_004d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0052: stloc.s V_9 + IL_0054: ldc.i4.0 + IL_0055: stloc.s V_10 + IL_0057: ldloc.s V_7 + IL_0059: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() + IL_005e: brfalse.s IL_0080 + + IL_0060: ldloc.s V_9 + IL_0062: ldloc.s V_5 + IL_0064: ldloc.s V_7 + IL_0066: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1::get_Current() + IL_006b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0070: call valuetype [netstandard]System.Decimal [netstandard]System.Decimal::op_Addition(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_0075: stloc.s V_9 .line 115,115 : 50,71 '' - IL_0079: ldloc.s V_10 - IL_007b: ldc.i4.1 - IL_007c: add - IL_007d: stloc.s V_10 + IL_0077: ldloc.s V_10 + IL_0079: ldc.i4.1 + IL_007a: add + IL_007b: stloc.s V_10 .line 100001,100001 : 0,0 '' - IL_007f: nop - IL_0080: br.s IL_0059 - - IL_0082: ldloc.s V_10 - IL_0084: brtrue.s IL_0088 - - IL_0086: br.s IL_008a + IL_007d: nop + IL_007e: br.s IL_0057 - IL_0088: br.s IL_0095 + .line 100001,100001 : 0,0 '' + IL_0080: ldloc.s V_10 + IL_0082: brtrue.s IL_008f .line 100001,100001 : 0,0 '' - IL_008a: ldstr "source" - IL_008f: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) - IL_0094: throw + IL_0084: ldstr "source" + IL_0089: newobj instance void [netstandard]System.InvalidOperationException::.ctor(string) + IL_008e: throw .line 100001,100001 : 0,0 '' - IL_0095: nop - IL_0096: ldloc.s V_9 - IL_0098: stloc.s V_11 - IL_009a: ldloc.s V_10 - IL_009c: stloc.s V_12 - IL_009e: ldloc.s V_11 - IL_00a0: ldloc.s V_12 - IL_00a2: call valuetype [mscorlib]System.Decimal [mscorlib]System.Convert::ToDecimal(int32) - IL_00a7: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::Divide(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) - IL_00ac: stloc.s V_8 - IL_00ae: leave.s IL_00ce + IL_008f: nop + IL_0090: ldloc.s V_9 + IL_0092: stloc.s V_11 + IL_0094: ldloc.s V_10 + IL_0096: stloc.s V_12 + IL_0098: ldloc.s V_11 + IL_009a: ldloc.s V_12 + IL_009c: call valuetype [netstandard]System.Decimal [netstandard]System.Convert::ToDecimal(int32) + IL_00a1: call valuetype [netstandard]System.Decimal [netstandard]System.Decimal::Divide(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_00a6: stloc.s V_8 + IL_00a8: leave.s IL_00c0 } // end .try finally { - IL_00b0: ldloc.s V_7 - IL_00b2: isinst [mscorlib]System.IDisposable - IL_00b7: stloc.s V_13 - IL_00b9: ldloc.s V_13 - IL_00bb: brfalse.s IL_00bf - - IL_00bd: br.s IL_00c1 - - IL_00bf: br.s IL_00cb + IL_00aa: ldloc.s V_7 + IL_00ac: isinst [mscorlib]System.IDisposable + IL_00b1: stloc.s V_13 + .line 100001,100001 : 0,0 '' + IL_00b3: ldloc.s V_13 + IL_00b5: brfalse.s IL_00bf .line 100001,100001 : 0,0 '' - IL_00c1: ldloc.s V_13 - IL_00c3: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_00c8: ldnull - IL_00c9: pop - IL_00ca: endfinally + IL_00b7: ldloc.s V_13 + IL_00b9: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_00be: endfinally .line 100001,100001 : 0,0 '' - IL_00cb: ldnull - IL_00cc: pop - IL_00cd: endfinally + IL_00bf: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_00ce: ldloc.s V_8 - IL_00d0: stloc.1 + IL_00c0: ldloc.s V_8 + IL_00c2: stloc.1 .line 116,116 : 9,37 '' - IL_00d1: ldarg.0 - IL_00d2: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories6@114-3'::builder@ - IL_00d7: ldloc.0 - IL_00d8: ldloc.1 - IL_00d9: newobj instance void class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>::.ctor(!0, + IL_00c3: ldarg.0 + IL_00c4: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'Pipe #7 input at line 112@114-3'::builder@ + IL_00c9: ldloc.0 + IL_00ca: ldloc.1 + IL_00cb: newobj instance void class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>::.ctor(!0, !1) - IL_00de: tail. - IL_00e0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal>,object>(!!0) - IL_00e5: ret - } // end of method 'categories6@114-3'::Invoke + IL_00d0: tail. + IL_00d2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,valuetype [mscorlib]System.Decimal>,object>(!!0) + IL_00d7: ret + } // end of method 'Pipe #7 input at line 112@114-3'::Invoke - } // end of class 'categories6@114-3' + } // end of class 'Pipe #7 input at line 112@114-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categories6@116-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 112@116-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Aggregates01/'Pipe #7 input at line 112@116-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -6998,7 +6862,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'categories6@116-4'::.ctor + } // end of method 'Pipe #7 input at line 112@116-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal> tupledArg) cil managed @@ -7021,9 +6885,19 @@ IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_001a: ret - } // end of method 'categories6@116-4'::Invoke + } // end of method 'Pipe #7 input at line 112@116-4'::Invoke - } // end of class 'categories6@116-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Aggregates01/'Pipe #7 input at line 112@116-4'::.ctor() + IL_0005: stsfld class Linq101Aggregates01/'Pipe #7 input at line 112@116-4' Linq101Aggregates01/'Pipe #7 input at line 112@116-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #7 input at line 112@116-4'::.cctor + + } // end of class 'Pipe #7 input at line 112@116-4' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_factorsOf300() cil managed @@ -7368,7 +7242,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 1765 (0x6e5) + // Code size 1756 (0x6dc) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 factorsOf300, [1] int32 uniqueFactors, @@ -7390,55 +7264,62 @@ [17] float64 averageNum, [18] float64 averageLength, [19] class [mscorlib]System.Tuple`2[] categories6, - [20] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_20, + [20] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 11', [21] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_21, [22] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_22, - [23] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_23, - [24] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_24, - [25] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_25, - [26] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_26, - [27] int32 V_27, + [23] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_23, + [24] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_24, + [25] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_25, + [26] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_26, + [27] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_27, [28] int32 V_28, - [29] class [mscorlib]System.IDisposable V_29, - [30] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_30, + [29] int32 V_29, + [30] class [mscorlib]System.IDisposable V_30, [31] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_31, - [32] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_32, - [33] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_33, - [34] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_34, - [35] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_35, - [36] int32 V_36, + [32] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_32, + [33] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_33, + [34] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_34, + [35] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_35, + [36] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_36, [37] int32 V_37, - [38] class [mscorlib]System.IDisposable V_38, - [39] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_39, - [40] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_40, + [38] int32 V_38, + [39] class [mscorlib]System.IDisposable V_39, + [40] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #2 input at line 38', [41] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_41, - [42] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_42, + [42] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #3 input at line 56', [43] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_43, - [44] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_44, + [44] class [mscorlib]System.Collections.Generic.IEnumerable`1>> 'Pipe #4 input at line 65', [45] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_45, - [46] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_46, - [47] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_47, - [48] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_48, - [49] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_49, - [50] float64 V_50, - [51] float64 V_51, - [52] int32 V_52, - [53] float64 V_53, - [54] int32 V_54, - [55] class [mscorlib]System.IDisposable V_55, - [56] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_56, - [57] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_57, - [58] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> V_58, - [59] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64> V_59, - [60] class [mscorlib]System.Collections.Generic.IEnumerable`1> V_60, - [61] class [mscorlib]System.Collections.Generic.IEnumerator`1> V_61, - [62] float64 V_62, - [63] float64 V_63, - [64] int32 V_64, - [65] float64 V_65, - [66] int32 V_66, - [67] class [mscorlib]System.IDisposable V_67, - [68] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_68) + [46] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #5 input at line 81', + [47] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_47, + [48] class [mscorlib]System.Collections.Generic.IEnumerable`1>> 'Pipe #6 input at line 90', + [49] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_49, + [50] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_50, + [51] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_51, + [52] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_52, + [53] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_53, + [54] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_54, + [55] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_55, + [56] float64 V_56, + [57] float64 V_57, + [58] int32 V_58, + [59] float64 V_59, + [60] int32 V_60, + [61] class [mscorlib]System.IDisposable V_61, + [62] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_62, + [63] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_63, + [64] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> V_64, + [65] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64> V_65, + [66] class [mscorlib]System.Collections.Generic.IEnumerable`1> V_66, + [67] class [mscorlib]System.Collections.Generic.IEnumerator`1> V_67, + [68] float64 V_68, + [69] float64 V_69, + [70] int32 V_70, + [71] float64 V_71, + [72] int32 V_72, + [73] class [mscorlib]System.IDisposable V_73, + [74] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #7 input at line 112', + [75] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_75) .line 8,8 : 1,31 '' IL_0000: ldc.i4.2 IL_0001: ldc.i4.2 @@ -7460,36 +7341,39 @@ IL_0024: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::factorsOf300@8 IL_0029: stloc.0 .line 10,14 : 1,20 '' - IL_002a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_002f: stloc.s V_20 - IL_0031: ldloc.s V_20 - IL_0033: ldnull - IL_0034: ldc.i4.0 + IL_002a: nop + .line 11,11 : 5,10 '' + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0030: stloc.s V_21 + IL_0032: ldloc.s V_21 + IL_0034: ldnull IL_0035: ldc.i4.0 - IL_0036: newobj instance void Linq101Aggregates01/uniqueFactors@12::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_003b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0040: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) - IL_0045: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_004a: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_004f: dup - IL_0050: stsfld int32 ''.$Linq101Aggregates01::uniqueFactors@10 - IL_0055: stloc.1 + IL_0036: ldc.i4.0 + IL_0037: newobj instance void Linq101Aggregates01/'Pipe #1 input at line 11@12'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_003c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0041: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) + IL_0046: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_004b: stloc.s 'Pipe #1 input at line 11' + .line 14,14 : 10,20 '' + IL_004d: ldloc.s 'Pipe #1 input at line 11' + IL_004f: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0054: dup + IL_0055: stsfld int32 ''.$Linq101Aggregates01::uniqueFactors@10 + IL_005a: stloc.1 .line 17,17 : 1,47 '' - IL_0056: ldc.i4.5 - IL_0057: ldc.i4.4 - IL_0058: ldc.i4.1 - IL_0059: ldc.i4.3 - IL_005a: ldc.i4.s 9 - IL_005c: ldc.i4.8 - IL_005d: ldc.i4.6 - IL_005e: ldc.i4.7 - IL_005f: ldc.i4.2 - IL_0060: ldc.i4.0 - IL_0061: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0066: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_005b: ldc.i4.5 + IL_005c: ldc.i4.4 + IL_005d: ldc.i4.1 + IL_005e: ldc.i4.3 + IL_005f: ldc.i4.s 9 + IL_0061: ldc.i4.8 + IL_0062: ldc.i4.6 + IL_0063: ldc.i4.7 + IL_0064: ldc.i4.2 + IL_0065: ldc.i4.0 + IL_0066: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_006b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0070: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -7508,679 +7392,675 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0093: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0098: dup - IL_0099: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers@17 - IL_009e: stloc.2 - IL_009f: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00a4: stloc.s V_21 - IL_00a6: ldloc.s V_21 - IL_00a8: stloc.s V_22 - IL_00aa: ldnull - IL_00ab: ldc.i4.0 - IL_00ac: ldc.i4.0 - IL_00ad: newobj instance void Linq101Aggregates01/numSum@21::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0098: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_009d: dup + IL_009e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers@17 + IL_00a3: stloc.2 + IL_00a4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00a9: stloc.s V_22 + IL_00ab: ldloc.s V_22 + IL_00ad: stloc.s V_23 + IL_00af: ldnull + IL_00b0: ldc.i4.0 + IL_00b1: ldc.i4.0 + IL_00b2: newobj instance void Linq101Aggregates01/numSum@21::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_00b2: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00b7: stloc.s V_23 - IL_00b9: newobj instance void Linq101Aggregates01/'numSum@22-1'::.ctor() - IL_00be: stloc.s V_24 - IL_00c0: ldloc.s V_23 - IL_00c2: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_00c7: stloc.s V_25 - IL_00c9: ldloc.s V_25 - IL_00cb: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_00d0: stloc.s V_26 + IL_00b7: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00bc: stloc.s V_24 + IL_00be: ldsfld class Linq101Aggregates01/'numSum@22-1' Linq101Aggregates01/'numSum@22-1'::@_instance + IL_00c3: stloc.s V_25 + IL_00c5: ldloc.s V_24 + IL_00c7: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_00cc: stloc.s V_26 + IL_00ce: ldloc.s V_26 + IL_00d0: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_00d5: stloc.s V_27 .try { - IL_00d2: ldc.i4.0 - IL_00d3: stloc.s V_28 - IL_00d5: ldloc.s V_26 - IL_00d7: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_00dc: brfalse.s IL_00f4 + IL_00d7: ldc.i4.0 + IL_00d8: stloc.s V_29 + IL_00da: ldloc.s V_27 + IL_00dc: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() + IL_00e1: brfalse.s IL_00f9 .line 22,22 : 9,16 '' - IL_00de: ldloc.s V_28 - IL_00e0: ldloc.s V_24 - IL_00e2: ldloc.s V_26 - IL_00e4: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_00e9: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_00ee: add.ovf - IL_00ef: stloc.s V_28 + IL_00e3: ldloc.s V_29 + IL_00e5: ldloc.s V_25 + IL_00e7: ldloc.s V_27 + IL_00e9: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1::get_Current() + IL_00ee: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_00f3: add.ovf + IL_00f4: stloc.s V_29 .line 100001,100001 : 0,0 '' - IL_00f1: nop - IL_00f2: br.s IL_00d5 + IL_00f6: nop + IL_00f7: br.s IL_00da - IL_00f4: ldloc.s V_28 - IL_00f6: stloc.s V_27 - IL_00f8: leave.s IL_0118 + IL_00f9: ldloc.s V_29 + IL_00fb: stloc.s V_28 + IL_00fd: leave.s IL_0115 } // end .try finally { - IL_00fa: ldloc.s V_26 - IL_00fc: isinst [mscorlib]System.IDisposable - IL_0101: stloc.s V_29 - IL_0103: ldloc.s V_29 - IL_0105: brfalse.s IL_0109 - - IL_0107: br.s IL_010b - - IL_0109: br.s IL_0115 + IL_00ff: ldloc.s V_27 + IL_0101: isinst [mscorlib]System.IDisposable + IL_0106: stloc.s V_30 + .line 100001,100001 : 0,0 '' + IL_0108: ldloc.s V_30 + IL_010a: brfalse.s IL_0114 .line 100001,100001 : 0,0 '' - IL_010b: ldloc.s V_29 - IL_010d: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0112: ldnull - IL_0113: pop - IL_0114: endfinally + IL_010c: ldloc.s V_30 + IL_010e: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_0113: endfinally .line 100001,100001 : 0,0 '' - IL_0115: ldnull - IL_0116: pop - IL_0117: endfinally + IL_0114: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_0118: ldloc.s V_27 - IL_011a: dup - IL_011b: stsfld int32 ''.$Linq101Aggregates01::numSum@19 - IL_0120: stloc.3 + IL_0115: ldloc.s V_28 + IL_0117: dup + IL_0118: stsfld int32 ''.$Linq101Aggregates01::numSum@19 + IL_011d: stloc.3 .line 26,26 : 1,45 '' - IL_0121: ldstr "cherry" - IL_0126: ldstr "apple" - IL_012b: ldstr "blueberry" - IL_0130: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0135: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_011e: ldstr "cherry" + IL_0123: ldstr "apple" + IL_0128: ldstr "blueberry" + IL_012d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0132: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_013a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0137: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_013f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_013c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0144: dup - IL_0145: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::words@26 - IL_014a: stloc.s words - IL_014c: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0151: stloc.s V_30 - IL_0153: ldloc.s V_30 - IL_0155: stloc.s V_31 - IL_0157: ldnull - IL_0158: ldc.i4.0 - IL_0159: ldnull - IL_015a: newobj instance void Linq101Aggregates01/totalChars@30::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0141: dup + IL_0142: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::words@26 + IL_0147: stloc.s words + IL_0149: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_014e: stloc.s V_31 + IL_0150: ldloc.s V_31 + IL_0152: stloc.s V_32 + IL_0154: ldnull + IL_0155: ldc.i4.0 + IL_0156: ldnull + IL_0157: newobj instance void Linq101Aggregates01/totalChars@30::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_015f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0164: stloc.s V_32 - IL_0166: newobj instance void Linq101Aggregates01/'totalChars@31-1'::.ctor() - IL_016b: stloc.s V_33 - IL_016d: ldloc.s V_32 - IL_016f: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0174: stloc.s V_34 - IL_0176: ldloc.s V_34 - IL_0178: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_017d: stloc.s V_35 + IL_015c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0161: stloc.s V_33 + IL_0163: ldsfld class Linq101Aggregates01/'totalChars@31-1' Linq101Aggregates01/'totalChars@31-1'::@_instance + IL_0168: stloc.s V_34 + IL_016a: ldloc.s V_33 + IL_016c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0171: stloc.s V_35 + IL_0173: ldloc.s V_35 + IL_0175: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_017a: stloc.s V_36 .try { - IL_017f: ldc.i4.0 - IL_0180: stloc.s V_37 - IL_0182: ldloc.s V_35 - IL_0184: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0189: brfalse.s IL_01a1 + IL_017c: ldc.i4.0 + IL_017d: stloc.s V_38 + IL_017f: ldloc.s V_36 + IL_0181: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() + IL_0186: brfalse.s IL_019e .line 31,31 : 9,25 '' - IL_018b: ldloc.s V_37 - IL_018d: ldloc.s V_33 - IL_018f: ldloc.s V_35 - IL_0191: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0196: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_019b: add.ovf - IL_019c: stloc.s V_37 + IL_0188: ldloc.s V_38 + IL_018a: ldloc.s V_34 + IL_018c: ldloc.s V_36 + IL_018e: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0193: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0198: add.ovf + IL_0199: stloc.s V_38 .line 100001,100001 : 0,0 '' - IL_019e: nop - IL_019f: br.s IL_0182 + IL_019b: nop + IL_019c: br.s IL_017f - IL_01a1: ldloc.s V_37 - IL_01a3: stloc.s V_36 - IL_01a5: leave.s IL_01c5 + IL_019e: ldloc.s V_38 + IL_01a0: stloc.s V_37 + IL_01a2: leave.s IL_01ba } // end .try finally { - IL_01a7: ldloc.s V_35 - IL_01a9: isinst [mscorlib]System.IDisposable - IL_01ae: stloc.s V_38 - IL_01b0: ldloc.s V_38 - IL_01b2: brfalse.s IL_01b6 - - IL_01b4: br.s IL_01b8 - - IL_01b6: br.s IL_01c2 + IL_01a4: ldloc.s V_36 + IL_01a6: isinst [mscorlib]System.IDisposable + IL_01ab: stloc.s V_39 + .line 100001,100001 : 0,0 '' + IL_01ad: ldloc.s V_39 + IL_01af: brfalse.s IL_01b9 .line 100001,100001 : 0,0 '' - IL_01b8: ldloc.s V_38 - IL_01ba: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_01bf: ldnull - IL_01c0: pop - IL_01c1: endfinally + IL_01b1: ldloc.s V_39 + IL_01b3: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_01b8: endfinally .line 100001,100001 : 0,0 '' - IL_01c2: ldnull - IL_01c3: pop - IL_01c4: endfinally + IL_01b9: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_01c5: ldloc.s V_36 - IL_01c7: dup - IL_01c8: stsfld int32 ''.$Linq101Aggregates01::totalChars@28 - IL_01cd: stloc.s totalChars + IL_01ba: ldloc.s V_37 + IL_01bc: dup + IL_01bd: stsfld int32 ''.$Linq101Aggregates01::totalChars@28 + IL_01c2: stloc.s totalChars .line 35,35 : 1,32 '' - IL_01cf: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_01d4: dup - IL_01d5: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::products@35 - IL_01da: stloc.s products + IL_01c4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_01c9: dup + IL_01ca: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::products@35 + IL_01cf: stloc.s products .line 37,46 : 1,21 '' - IL_01dc: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_01e1: stloc.s V_39 - IL_01e3: ldloc.s V_39 - IL_01e5: ldloc.s V_39 - IL_01e7: ldloc.s V_39 - IL_01e9: ldloc.s V_39 - IL_01eb: ldloc.s V_39 - IL_01ed: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_01f2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01f7: ldloc.s V_39 - IL_01f9: newobj instance void Linq101Aggregates01/categories@39::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_01fe: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01d1: nop + .line 38,38 : 5,10 '' + IL_01d2: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01d7: stloc.s V_41 + IL_01d9: ldloc.s V_41 + IL_01db: ldloc.s V_41 + IL_01dd: ldloc.s V_41 + IL_01df: ldloc.s V_41 + IL_01e1: ldloc.s V_41 + IL_01e3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_01e8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01ed: ldloc.s V_41 + IL_01ef: newobj instance void Linq101Aggregates01/'Pipe #2 input at line 38@39'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01f4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0203: newobj instance void Linq101Aggregates01/'categories@40-1'::.ctor() - IL_0208: newobj instance void Linq101Aggregates01/'categories@40-2'::.ctor() - IL_020d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01f9: ldsfld class Linq101Aggregates01/'Pipe #2 input at line 38@40-1' Linq101Aggregates01/'Pipe #2 input at line 38@40-1'::@_instance + IL_01fe: ldsfld class Linq101Aggregates01/'Pipe #2 input at line 38@40-2' Linq101Aggregates01/'Pipe #2 input at line 38@40-2'::@_instance + IL_0203: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0212: ldloc.s V_39 - IL_0214: newobj instance void Linq101Aggregates01/'categories@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0219: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,int32>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0208: ldloc.s V_41 + IL_020a: newobj instance void Linq101Aggregates01/'Pipe #2 input at line 38@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_020f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,int32>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_021e: newobj instance void Linq101Aggregates01/'categories@45-4'::.ctor() - IL_0223: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,int32>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0214: ldsfld class Linq101Aggregates01/'Pipe #2 input at line 38@45-4' Linq101Aggregates01/'Pipe #2 input at line 38@45-4'::@_instance + IL_0219: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,int32>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0228: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_022d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0232: dup - IL_0233: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories@37 - IL_0238: stloc.s categories - IL_023a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_023f: ldnull - IL_0240: ldc.i4.0 - IL_0241: ldc.i4.0 - IL_0242: newobj instance void Linq101Aggregates01/minNum@49::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_021e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0223: stloc.s 'Pipe #2 input at line 38' + .line 46,46 : 10,21 '' + IL_0225: ldloc.s 'Pipe #2 input at line 38' + IL_0227: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_022c: dup + IL_022d: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories@37 + IL_0232: stloc.s categories + IL_0234: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0239: ldnull + IL_023a: ldc.i4.0 + IL_023b: ldc.i4.0 + IL_023c: newobj instance void Linq101Aggregates01/minNum@49::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_0247: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_024c: newobj instance void Linq101Aggregates01/'minNum@49-1'::.ctor() - IL_0251: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0241: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0246: ldsfld class Linq101Aggregates01/'minNum@49-1' Linq101Aggregates01/'minNum@49-1'::@_instance + IL_024b: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0256: dup - IL_0257: stsfld int32 ''.$Linq101Aggregates01::minNum@49 - IL_025c: stloc.s minNum - IL_025e: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0263: ldnull - IL_0264: ldc.i4.0 - IL_0265: ldnull - IL_0266: newobj instance void Linq101Aggregates01/shortestWord@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0250: dup + IL_0251: stsfld int32 ''.$Linq101Aggregates01::minNum@49 + IL_0256: stloc.s minNum + IL_0258: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_025d: ldnull + IL_025e: ldc.i4.0 + IL_025f: ldnull + IL_0260: newobj instance void Linq101Aggregates01/shortestWord@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_026b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0270: newobj instance void Linq101Aggregates01/'shortestWord@52-1'::.ctor() - IL_0275: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0265: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_026a: ldsfld class Linq101Aggregates01/'shortestWord@52-1' Linq101Aggregates01/'shortestWord@52-1'::@_instance + IL_026f: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_027a: dup - IL_027b: stsfld int32 ''.$Linq101Aggregates01::shortestWord@52 - IL_0280: stloc.s shortestWord + IL_0274: dup + IL_0275: stsfld int32 ''.$Linq101Aggregates01::shortestWord@52 + IL_027a: stloc.s shortestWord .line 55,61 : 1,21 '' - IL_0282: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0287: stloc.s V_40 - IL_0289: ldloc.s V_40 - IL_028b: ldloc.s V_40 - IL_028d: ldloc.s V_40 - IL_028f: ldloc.s V_40 - IL_0291: ldloc.s V_40 - IL_0293: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_0298: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_029d: ldloc.s V_40 - IL_029f: newobj instance void Linq101Aggregates01/categories2@57::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_02a4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_027c: nop + .line 56,56 : 5,10 '' + IL_027d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0282: stloc.s V_43 + IL_0284: ldloc.s V_43 + IL_0286: ldloc.s V_43 + IL_0288: ldloc.s V_43 + IL_028a: ldloc.s V_43 + IL_028c: ldloc.s V_43 + IL_028e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_0293: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0298: ldloc.s V_43 + IL_029a: newobj instance void Linq101Aggregates01/'Pipe #3 input at line 56@57'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_029f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_02a9: newobj instance void Linq101Aggregates01/'categories2@58-1'::.ctor() - IL_02ae: newobj instance void Linq101Aggregates01/'categories2@58-2'::.ctor() - IL_02b3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02a4: ldsfld class Linq101Aggregates01/'Pipe #3 input at line 56@58-1' Linq101Aggregates01/'Pipe #3 input at line 56@58-1'::@_instance + IL_02a9: ldsfld class Linq101Aggregates01/'Pipe #3 input at line 56@58-2' Linq101Aggregates01/'Pipe #3 input at line 56@58-2'::@_instance + IL_02ae: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02b8: ldloc.s V_40 - IL_02ba: newobj instance void Linq101Aggregates01/'categories2@58-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_02bf: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02b3: ldloc.s V_43 + IL_02b5: newobj instance void Linq101Aggregates01/'Pipe #3 input at line 56@58-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_02ba: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_02c4: newobj instance void Linq101Aggregates01/'categories2@60-4'::.ctor() - IL_02c9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02bf: ldsfld class Linq101Aggregates01/'Pipe #3 input at line 56@60-4' Linq101Aggregates01/'Pipe #3 input at line 56@60-4'::@_instance + IL_02c4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02ce: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_02d3: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_02d8: dup - IL_02d9: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories2@55 - IL_02de: stloc.s categories2 + IL_02c9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_02ce: stloc.s 'Pipe #3 input at line 56' + .line 61,61 : 10,21 '' + IL_02d0: ldloc.s 'Pipe #3 input at line 56' + IL_02d2: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_02d7: dup + IL_02d8: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories2@55 + IL_02dd: stloc.s categories2 .line 64,71 : 1,21 '' + IL_02df: nop + .line 65,65 : 5,10 '' IL_02e0: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_02e5: stloc.s V_41 - IL_02e7: ldloc.s V_41 - IL_02e9: ldloc.s V_41 - IL_02eb: ldloc.s V_41 - IL_02ed: ldloc.s V_41 - IL_02ef: ldloc.s V_41 + IL_02e5: stloc.s V_45 + IL_02e7: ldloc.s V_45 + IL_02e9: ldloc.s V_45 + IL_02eb: ldloc.s V_45 + IL_02ed: ldloc.s V_45 + IL_02ef: ldloc.s V_45 IL_02f1: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() IL_02f6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_02fb: ldloc.s V_41 - IL_02fd: newobj instance void Linq101Aggregates01/categories3@66::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_02fb: ldloc.s V_45 + IL_02fd: newobj instance void Linq101Aggregates01/'Pipe #4 input at line 65@66'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_0302: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0307: newobj instance void Linq101Aggregates01/'categories3@67-1'::.ctor() - IL_030c: newobj instance void Linq101Aggregates01/'categories3@67-2'::.ctor() + IL_0307: ldsfld class Linq101Aggregates01/'Pipe #4 input at line 65@67-1' Linq101Aggregates01/'Pipe #4 input at line 65@67-1'::@_instance + IL_030c: ldsfld class Linq101Aggregates01/'Pipe #4 input at line 65@67-2' Linq101Aggregates01/'Pipe #4 input at line 65@67-2'::@_instance IL_0311: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0316: ldloc.s V_41 - IL_0318: newobj instance void Linq101Aggregates01/'categories3@67-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0316: ldloc.s V_45 + IL_0318: newobj instance void Linq101Aggregates01/'Pipe #4 input at line 65@67-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_031d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0322: newobj instance void Linq101Aggregates01/'categories3@70-4'::.ctor() + IL_0322: ldsfld class Linq101Aggregates01/'Pipe #4 input at line 65@70-4' Linq101Aggregates01/'Pipe #4 input at line 65@70-4'::@_instance IL_0327: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_032c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0331: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0336: dup - IL_0337: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories3@64 - IL_033c: stloc.s categories3 - IL_033e: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0343: ldnull - IL_0344: ldc.i4.0 - IL_0345: ldc.i4.0 - IL_0346: newobj instance void Linq101Aggregates01/maxNum@74::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0331: stloc.s 'Pipe #4 input at line 65' + .line 71,71 : 10,21 '' + IL_0333: ldloc.s 'Pipe #4 input at line 65' + IL_0335: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_033a: dup + IL_033b: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories3@64 + IL_0340: stloc.s categories3 + IL_0342: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0347: ldnull + IL_0348: ldc.i4.0 + IL_0349: ldc.i4.0 + IL_034a: newobj instance void Linq101Aggregates01/maxNum@74::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_034b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0350: newobj instance void Linq101Aggregates01/'maxNum@74-1'::.ctor() - IL_0355: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_034f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0354: ldsfld class Linq101Aggregates01/'maxNum@74-1' Linq101Aggregates01/'maxNum@74-1'::@_instance + IL_0359: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_035a: dup - IL_035b: stsfld int32 ''.$Linq101Aggregates01::maxNum@74 - IL_0360: stloc.s maxNum - IL_0362: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0367: ldnull - IL_0368: ldc.i4.0 - IL_0369: ldnull - IL_036a: newobj instance void Linq101Aggregates01/longestLength@77::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_035e: dup + IL_035f: stsfld int32 ''.$Linq101Aggregates01::maxNum@74 + IL_0364: stloc.s maxNum + IL_0366: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_036b: ldnull + IL_036c: ldc.i4.0 + IL_036d: ldnull + IL_036e: newobj instance void Linq101Aggregates01/longestLength@77::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_036f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0374: newobj instance void Linq101Aggregates01/'longestLength@77-1'::.ctor() - IL_0379: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0373: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0378: ldsfld class Linq101Aggregates01/'longestLength@77-1' Linq101Aggregates01/'longestLength@77-1'::@_instance + IL_037d: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_037e: dup - IL_037f: stsfld int32 ''.$Linq101Aggregates01::longestLength@77 - IL_0384: stloc.s longestLength + IL_0382: dup + IL_0383: stsfld int32 ''.$Linq101Aggregates01::longestLength@77 + IL_0388: stloc.s longestLength .line 80,86 : 1,21 '' - IL_0386: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_038b: stloc.s V_42 - IL_038d: ldloc.s V_42 - IL_038f: ldloc.s V_42 - IL_0391: ldloc.s V_42 - IL_0393: ldloc.s V_42 - IL_0395: ldloc.s V_42 - IL_0397: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_039c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03a1: ldloc.s V_42 - IL_03a3: newobj instance void Linq101Aggregates01/categories4@82::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_03a8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_038a: nop + .line 81,81 : 5,10 '' + IL_038b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0390: stloc.s V_47 + IL_0392: ldloc.s V_47 + IL_0394: ldloc.s V_47 + IL_0396: ldloc.s V_47 + IL_0398: ldloc.s V_47 + IL_039a: ldloc.s V_47 + IL_039c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_03a1: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03a6: ldloc.s V_47 + IL_03a8: newobj instance void Linq101Aggregates01/'Pipe #5 input at line 81@82'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03ad: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_03ad: newobj instance void Linq101Aggregates01/'categories4@83-1'::.ctor() - IL_03b2: newobj instance void Linq101Aggregates01/'categories4@83-2'::.ctor() - IL_03b7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03b2: ldsfld class Linq101Aggregates01/'Pipe #5 input at line 81@83-1' Linq101Aggregates01/'Pipe #5 input at line 81@83-1'::@_instance + IL_03b7: ldsfld class Linq101Aggregates01/'Pipe #5 input at line 81@83-2' Linq101Aggregates01/'Pipe #5 input at line 81@83-2'::@_instance + IL_03bc: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03bc: ldloc.s V_42 - IL_03be: newobj instance void Linq101Aggregates01/'categories4@83-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_03c3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03c1: ldloc.s V_47 + IL_03c3: newobj instance void Linq101Aggregates01/'Pipe #5 input at line 81@83-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03c8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_03c8: newobj instance void Linq101Aggregates01/'categories4@85-4'::.ctor() - IL_03cd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03cd: ldsfld class Linq101Aggregates01/'Pipe #5 input at line 81@85-4' Linq101Aggregates01/'Pipe #5 input at line 81@85-4'::@_instance + IL_03d2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03d2: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_03d7: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03dc: dup - IL_03dd: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories4@80 - IL_03e2: stloc.s categories4 + IL_03d7: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_03dc: stloc.s 'Pipe #5 input at line 81' + .line 86,86 : 10,21 '' + IL_03de: ldloc.s 'Pipe #5 input at line 81' + IL_03e0: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03e5: dup + IL_03e6: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories4@80 + IL_03eb: stloc.s categories4 .line 89,96 : 1,21 '' - IL_03e4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_03e9: stloc.s V_43 - IL_03eb: ldloc.s V_43 - IL_03ed: ldloc.s V_43 - IL_03ef: ldloc.s V_43 - IL_03f1: ldloc.s V_43 - IL_03f3: ldloc.s V_43 - IL_03f5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_03fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03ff: ldloc.s V_43 - IL_0401: newobj instance void Linq101Aggregates01/categories5@91::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0406: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03ed: nop + .line 90,90 : 5,10 '' + IL_03ee: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_03f3: stloc.s V_49 + IL_03f5: ldloc.s V_49 + IL_03f7: ldloc.s V_49 + IL_03f9: ldloc.s V_49 + IL_03fb: ldloc.s V_49 + IL_03fd: ldloc.s V_49 + IL_03ff: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_0404: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0409: ldloc.s V_49 + IL_040b: newobj instance void Linq101Aggregates01/'Pipe #6 input at line 90@91'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0410: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_040b: newobj instance void Linq101Aggregates01/'categories5@92-1'::.ctor() - IL_0410: newobj instance void Linq101Aggregates01/'categories5@92-2'::.ctor() - IL_0415: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0415: ldsfld class Linq101Aggregates01/'Pipe #6 input at line 90@92-1' Linq101Aggregates01/'Pipe #6 input at line 90@92-1'::@_instance + IL_041a: ldsfld class Linq101Aggregates01/'Pipe #6 input at line 90@92-2' Linq101Aggregates01/'Pipe #6 input at line 90@92-2'::@_instance + IL_041f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_041a: ldloc.s V_43 - IL_041c: newobj instance void Linq101Aggregates01/'categories5@92-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0421: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0424: ldloc.s V_49 + IL_0426: newobj instance void Linq101Aggregates01/'Pipe #6 input at line 90@92-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_042b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0426: newobj instance void Linq101Aggregates01/'categories5@95-4'::.ctor() - IL_042b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0430: ldsfld class Linq101Aggregates01/'Pipe #6 input at line 90@95-4' Linq101Aggregates01/'Pipe #6 input at line 90@95-4'::@_instance + IL_0435: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0430: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0435: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_043a: dup - IL_043b: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories5@89 - IL_0440: stloc.s categories5 + IL_043a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_043f: stloc.s 'Pipe #6 input at line 90' + .line 96,96 : 10,21 '' + IL_0441: ldloc.s 'Pipe #6 input at line 90' + IL_0443: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0448: dup + IL_0449: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories5@89 + IL_044e: stloc.s categories5 .line 99,99 : 1,66 '' - IL_0442: ldc.r8 5. - IL_044b: ldc.r8 4. - IL_0454: ldc.r8 1. - IL_045d: ldc.r8 3. - IL_0466: ldc.r8 9. - IL_046f: ldc.r8 8. - IL_0478: ldc.r8 6. - IL_0481: ldc.r8 7. - IL_048a: ldc.r8 2. - IL_0493: ldc.r8 0.0 - IL_049c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_04a1: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0450: ldc.r8 5. + IL_0459: ldc.r8 4. + IL_0462: ldc.r8 1. + IL_046b: ldc.r8 3. + IL_0474: ldc.r8 9. + IL_047d: ldc.r8 8. + IL_0486: ldc.r8 6. + IL_048f: ldc.r8 7. + IL_0498: ldc.r8 2. + IL_04a1: ldc.r8 0.0 + IL_04aa: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_04af: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04a6: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04ab: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04b9: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04b0: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04be: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04b5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04c3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04ba: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04c8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04bf: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04cd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04c4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04d2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04c9: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04d7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04ce: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04dc: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_04d3: dup - IL_04d4: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers2@99 - IL_04d9: stloc.s numbers2 - IL_04db: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_04e0: stloc.s V_44 - IL_04e2: ldloc.s V_44 - IL_04e4: stloc.s V_45 - IL_04e6: ldnull - IL_04e7: ldc.i4.0 - IL_04e8: ldc.r8 0.0 - IL_04f1: newobj instance void Linq101Aggregates01/averageNum@100::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_04e1: dup + IL_04e2: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers2@99 + IL_04e7: stloc.s numbers2 + IL_04e9: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_04ee: stloc.s V_50 + IL_04f0: ldloc.s V_50 + IL_04f2: stloc.s V_51 + IL_04f4: ldnull + IL_04f5: ldc.i4.0 + IL_04f6: ldc.r8 0.0 + IL_04ff: newobj instance void Linq101Aggregates01/averageNum@100::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, float64) - IL_04f6: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_04fb: stloc.s V_46 - IL_04fd: newobj instance void Linq101Aggregates01/'averageNum@100-1'::.ctor() - IL_0502: stloc.s V_47 - IL_0504: ldloc.s V_46 - IL_0506: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_050b: stloc.s V_48 - IL_050d: ldloc.s V_48 - IL_050f: box class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0514: brfalse.s IL_0518 - - IL_0516: br.s IL_0523 + IL_0504: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0509: stloc.s V_52 + IL_050b: ldsfld class Linq101Aggregates01/'averageNum@100-1' Linq101Aggregates01/'averageNum@100-1'::@_instance + IL_0510: stloc.s V_53 + IL_0512: ldloc.s V_52 + IL_0514: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0519: stloc.s V_54 + .line 100001,100001 : 0,0 '' + IL_051b: ldloc.s V_54 + IL_051d: box class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0522: brtrue.s IL_052f .line 100001,100001 : 0,0 '' - IL_0518: ldstr "source" - IL_051d: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) - IL_0522: throw + IL_0524: ldstr "source" + IL_0529: newobj instance void [netstandard]System.ArgumentNullException::.ctor(string) + IL_052e: throw .line 100001,100001 : 0,0 '' - IL_0523: nop - IL_0524: ldloc.s V_48 - IL_0526: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_052b: stloc.s V_49 + IL_052f: nop + IL_0530: ldloc.s V_54 + IL_0532: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0537: stloc.s V_55 .try { - IL_052d: ldc.r8 0.0 - IL_0536: stloc.s V_51 - IL_0538: ldc.i4.0 - IL_0539: stloc.s V_52 - IL_053b: ldloc.s V_49 - IL_053d: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0542: brfalse.s IL_0560 - - IL_0544: ldloc.s V_51 - IL_0546: ldloc.s V_47 - IL_0548: ldloc.s V_49 - IL_054a: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_054f: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0554: add - IL_0555: stloc.s V_51 + IL_0539: ldc.r8 0.0 + IL_0542: stloc.s V_57 + IL_0544: ldc.i4.0 + IL_0545: stloc.s V_58 + IL_0547: ldloc.s V_55 + IL_0549: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() + IL_054e: brfalse.s IL_056c + + IL_0550: ldloc.s V_57 + IL_0552: ldloc.s V_53 + IL_0554: ldloc.s V_55 + IL_0556: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1::get_Current() + IL_055b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0560: add + IL_0561: stloc.s V_57 .line 100,100 : 47,58 '' - IL_0557: ldloc.s V_52 - IL_0559: ldc.i4.1 - IL_055a: add - IL_055b: stloc.s V_52 + IL_0563: ldloc.s V_58 + IL_0565: ldc.i4.1 + IL_0566: add + IL_0567: stloc.s V_58 .line 100001,100001 : 0,0 '' - IL_055d: nop - IL_055e: br.s IL_053b - - IL_0560: ldloc.s V_52 - IL_0562: brtrue.s IL_0566 - - IL_0564: br.s IL_0568 + IL_0569: nop + IL_056a: br.s IL_0547 - IL_0566: br.s IL_0573 + .line 100001,100001 : 0,0 '' + IL_056c: ldloc.s V_58 + IL_056e: brtrue.s IL_057b .line 100001,100001 : 0,0 '' - IL_0568: ldstr "source" - IL_056d: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) - IL_0572: throw + IL_0570: ldstr "source" + IL_0575: newobj instance void [netstandard]System.InvalidOperationException::.ctor(string) + IL_057a: throw .line 100001,100001 : 0,0 '' - IL_0573: nop - IL_0574: ldloc.s V_51 - IL_0576: stloc.s V_53 - IL_0578: ldloc.s V_52 - IL_057a: stloc.s V_54 - IL_057c: ldloc.s V_53 - IL_057e: ldloc.s V_54 - IL_0580: conv.r8 - IL_0581: div - IL_0582: stloc.s V_50 - IL_0584: leave.s IL_05a4 + IL_057b: nop + IL_057c: ldloc.s V_57 + IL_057e: stloc.s V_59 + IL_0580: ldloc.s V_58 + IL_0582: stloc.s V_60 + IL_0584: ldloc.s V_59 + IL_0586: ldloc.s V_60 + IL_0588: conv.r8 + IL_0589: div + IL_058a: stloc.s V_56 + IL_058c: leave.s IL_05a4 } // end .try finally { - IL_0586: ldloc.s V_49 - IL_0588: isinst [mscorlib]System.IDisposable - IL_058d: stloc.s V_55 - IL_058f: ldloc.s V_55 - IL_0591: brfalse.s IL_0595 - - IL_0593: br.s IL_0597 - - IL_0595: br.s IL_05a1 + IL_058e: ldloc.s V_55 + IL_0590: isinst [mscorlib]System.IDisposable + IL_0595: stloc.s V_61 + .line 100001,100001 : 0,0 '' + IL_0597: ldloc.s V_61 + IL_0599: brfalse.s IL_05a3 .line 100001,100001 : 0,0 '' - IL_0597: ldloc.s V_55 - IL_0599: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_059e: ldnull - IL_059f: pop - IL_05a0: endfinally + IL_059b: ldloc.s V_61 + IL_059d: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_05a2: endfinally .line 100001,100001 : 0,0 '' - IL_05a1: ldnull - IL_05a2: pop IL_05a3: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_05a4: ldloc.s V_50 + IL_05a4: ldloc.s V_56 IL_05a6: dup IL_05a7: stsfld float64 ''.$Linq101Aggregates01::averageNum@100 IL_05ac: stloc.s averageNum IL_05ae: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_05b3: stloc.s V_56 - IL_05b5: ldloc.s V_56 - IL_05b7: stloc.s V_57 - IL_05b9: ldloc.s V_56 - IL_05bb: ldloc.s V_56 + IL_05b3: stloc.s V_62 + IL_05b5: ldloc.s V_62 + IL_05b7: stloc.s V_63 + IL_05b9: ldloc.s V_62 + IL_05bb: ldloc.s V_62 IL_05bd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() IL_05c2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_05c7: ldloc.s V_56 + IL_05c7: ldloc.s V_62 IL_05c9: newobj instance void Linq101Aggregates01/averageLength@105::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_05ce: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_05d3: stloc.s V_58 - IL_05d5: newobj instance void Linq101Aggregates01/'averageLength@107-1'::.ctor() - IL_05da: stloc.s V_59 - IL_05dc: ldloc.s V_58 + IL_05d3: stloc.s V_64 + IL_05d5: ldsfld class Linq101Aggregates01/'averageLength@107-1' Linq101Aggregates01/'averageLength@107-1'::@_instance + IL_05da: stloc.s V_65 + IL_05dc: ldloc.s V_64 IL_05de: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_05e3: stloc.s V_60 - IL_05e5: ldloc.s V_60 + IL_05e3: stloc.s V_66 + .line 100001,100001 : 0,0 '' + IL_05e5: ldloc.s V_66 IL_05e7: box class [mscorlib]System.Collections.Generic.IEnumerable`1> - IL_05ec: brfalse.s IL_05f0 - - IL_05ee: br.s IL_05fb + IL_05ec: brtrue.s IL_05f9 .line 100001,100001 : 0,0 '' - IL_05f0: ldstr "source" - IL_05f5: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) - IL_05fa: throw + IL_05ee: ldstr "source" + IL_05f3: newobj instance void [netstandard]System.ArgumentNullException::.ctor(string) + IL_05f8: throw .line 100001,100001 : 0,0 '' - IL_05fb: nop - IL_05fc: ldloc.s V_60 - IL_05fe: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1>::GetEnumerator() - IL_0603: stloc.s V_61 + IL_05f9: nop + IL_05fa: ldloc.s V_66 + IL_05fc: callvirt instance class [netstandard]System.Collections.Generic.IEnumerator`1 class [netstandard]System.Collections.Generic.IEnumerable`1>::GetEnumerator() + IL_0601: stloc.s V_67 .try { - IL_0605: ldc.r8 0.0 - IL_060e: stloc.s V_63 - IL_0610: ldc.i4.0 - IL_0611: stloc.s V_64 - IL_0613: ldloc.s V_61 - IL_0615: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_061a: brfalse.s IL_0638 - - IL_061c: ldloc.s V_63 - IL_061e: ldloc.s V_59 - IL_0620: ldloc.s V_61 - IL_0622: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1>::get_Current() - IL_0627: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>::Invoke(!0) - IL_062c: add - IL_062d: stloc.s V_63 + IL_0603: ldc.r8 0.0 + IL_060c: stloc.s V_69 + IL_060e: ldc.i4.0 + IL_060f: stloc.s V_70 + IL_0611: ldloc.s V_67 + IL_0613: callvirt instance bool [netstandard]System.Collections.IEnumerator::MoveNext() + IL_0618: brfalse.s IL_0636 + + IL_061a: ldloc.s V_69 + IL_061c: ldloc.s V_65 + IL_061e: ldloc.s V_67 + IL_0620: callvirt instance !0 class [netstandard]System.Collections.Generic.IEnumerator`1>::get_Current() + IL_0625: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>::Invoke(!0) + IL_062a: add + IL_062b: stloc.s V_69 .line 107,107 : 9,21 '' - IL_062f: ldloc.s V_64 - IL_0631: ldc.i4.1 - IL_0632: add - IL_0633: stloc.s V_64 + IL_062d: ldloc.s V_70 + IL_062f: ldc.i4.1 + IL_0630: add + IL_0631: stloc.s V_70 .line 100001,100001 : 0,0 '' - IL_0635: nop - IL_0636: br.s IL_0613 - - IL_0638: ldloc.s V_64 - IL_063a: brtrue.s IL_063e - - IL_063c: br.s IL_0640 + IL_0633: nop + IL_0634: br.s IL_0611 - IL_063e: br.s IL_064b + .line 100001,100001 : 0,0 '' + IL_0636: ldloc.s V_70 + IL_0638: brtrue.s IL_0645 .line 100001,100001 : 0,0 '' - IL_0640: ldstr "source" - IL_0645: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) - IL_064a: throw + IL_063a: ldstr "source" + IL_063f: newobj instance void [netstandard]System.InvalidOperationException::.ctor(string) + IL_0644: throw .line 100001,100001 : 0,0 '' - IL_064b: nop - IL_064c: ldloc.s V_63 - IL_064e: stloc.s V_65 - IL_0650: ldloc.s V_64 - IL_0652: stloc.s V_66 - IL_0654: ldloc.s V_65 - IL_0656: ldloc.s V_66 - IL_0658: conv.r8 - IL_0659: div - IL_065a: stloc.s V_62 - IL_065c: leave.s IL_067c + IL_0645: nop + IL_0646: ldloc.s V_69 + IL_0648: stloc.s V_71 + IL_064a: ldloc.s V_70 + IL_064c: stloc.s V_72 + IL_064e: ldloc.s V_71 + IL_0650: ldloc.s V_72 + IL_0652: conv.r8 + IL_0653: div + IL_0654: stloc.s V_68 + IL_0656: leave.s IL_066e } // end .try finally { - IL_065e: ldloc.s V_61 - IL_0660: isinst [mscorlib]System.IDisposable - IL_0665: stloc.s V_67 - IL_0667: ldloc.s V_67 - IL_0669: brfalse.s IL_066d - - IL_066b: br.s IL_066f - - IL_066d: br.s IL_0679 + IL_0658: ldloc.s V_67 + IL_065a: isinst [mscorlib]System.IDisposable + IL_065f: stloc.s V_73 + .line 100001,100001 : 0,0 '' + IL_0661: ldloc.s V_73 + IL_0663: brfalse.s IL_066d .line 100001,100001 : 0,0 '' - IL_066f: ldloc.s V_67 - IL_0671: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0676: ldnull - IL_0677: pop - IL_0678: endfinally + IL_0665: ldloc.s V_73 + IL_0667: callvirt instance void [netstandard]System.IDisposable::Dispose() + IL_066c: endfinally .line 100001,100001 : 0,0 '' - IL_0679: ldnull - IL_067a: pop - IL_067b: endfinally + IL_066d: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_067c: ldloc.s V_62 - IL_067e: dup - IL_067f: stsfld float64 ''.$Linq101Aggregates01::averageLength@103 - IL_0684: stloc.s averageLength + IL_066e: ldloc.s V_68 + IL_0670: dup + IL_0671: stsfld float64 ''.$Linq101Aggregates01::averageLength@103 + IL_0676: stloc.s averageLength .line 111,117 : 1,21 '' - IL_0686: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_068b: stloc.s V_68 - IL_068d: ldloc.s V_68 - IL_068f: ldloc.s V_68 - IL_0691: ldloc.s V_68 - IL_0693: ldloc.s V_68 - IL_0695: ldloc.s V_68 - IL_0697: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_069c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_06a1: ldloc.s V_68 - IL_06a3: newobj instance void Linq101Aggregates01/categories6@113::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_06a8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0678: nop + .line 112,112 : 5,10 '' + IL_0679: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_067e: stloc.s V_75 + IL_0680: ldloc.s V_75 + IL_0682: ldloc.s V_75 + IL_0684: ldloc.s V_75 + IL_0686: ldloc.s V_75 + IL_0688: ldloc.s V_75 + IL_068a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_068f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0694: ldloc.s V_75 + IL_0696: newobj instance void Linq101Aggregates01/'Pipe #7 input at line 112@113'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_069b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_06ad: newobj instance void Linq101Aggregates01/'categories6@114-1'::.ctor() - IL_06b2: newobj instance void Linq101Aggregates01/'categories6@114-2'::.ctor() - IL_06b7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_06a0: ldsfld class Linq101Aggregates01/'Pipe #7 input at line 112@114-1' Linq101Aggregates01/'Pipe #7 input at line 112@114-1'::@_instance + IL_06a5: ldsfld class Linq101Aggregates01/'Pipe #7 input at line 112@114-2' Linq101Aggregates01/'Pipe #7 input at line 112@114-2'::@_instance + IL_06aa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_06bc: ldloc.s V_68 - IL_06be: newobj instance void Linq101Aggregates01/'categories6@114-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_06c3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_06af: ldloc.s V_75 + IL_06b1: newobj instance void Linq101Aggregates01/'Pipe #7 input at line 112@114-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_06b6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_06c8: newobj instance void Linq101Aggregates01/'categories6@116-4'::.ctor() - IL_06cd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_06bb: ldsfld class Linq101Aggregates01/'Pipe #7 input at line 112@116-4' Linq101Aggregates01/'Pipe #7 input at line 112@116-4'::@_instance + IL_06c0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_06d2: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_06d7: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_06dc: dup - IL_06dd: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories6@111 - IL_06e2: stloc.s categories6 - IL_06e4: ret + IL_06c5: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_06ca: stloc.s 'Pipe #7 input at line 112' + .line 117,117 : 10,21 '' + IL_06cc: ldloc.s 'Pipe #7 input at line 112' + IL_06ce: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_06d3: dup + IL_06d4: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories6@111 + IL_06d9: stloc.s categories6 + IL_06db: ret } // end of method $Linq101Aggregates01::main@ } // end of class ''.$Linq101Aggregates01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101ElementOperators01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101ElementOperators01.il.bsl index b0aa6e961a6..d64da39d4e5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101ElementOperators01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101ElementOperators01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,17 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101ElementOperators01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -33,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101ElementOperators01 { - // Offset: 0x00000000 Length: 0x0000038A + // Offset: 0x00000000 Length: 0x0000037E } .mresource public FSharpOptimizationData.Linq101ElementOperators01 { - // Offset: 0x00000390 Length: 0x00000127 + // Offset: 0x00000388 Length: 0x00000127 } .module Linq101ElementOperators01.exe -// MVID: {5B9A632A-19D7-C20D-A745-03832A639A5B} +// MVID: {611C4D82-19D7-C20D-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x028F0000 +// Image base: 0x06A90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -95,106 +100,99 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product p) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101ElementOperators01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101ElementOperators01.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/products12@12::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 12,12 : 9,29 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_products() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_products() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101ElementOperators01/products12@12::pc .line 12,12 : 9,29 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 12,12 : 9,29 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 13,13 : 9,33 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101ElementOperators01/products12@12::pc .line 12,12 : 9,29 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101ElementOperators01/products12@12::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method products12@12::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/products12@12::pc @@ -202,158 +200,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101ElementOperators01/products12@12::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101ElementOperators01/products12@12::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101ElementOperators01/products12@12::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/products12@12::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101ElementOperators01/products12@12::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101ElementOperators01/products12@12::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101ElementOperators01/products12@12::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 12,12 : 9,29 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 12,12 : 9,29 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method products12@12::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/products12@12::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method products12@12::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product @@ -389,6 +364,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'products12@13-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101ElementOperators01/'products12@13-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -414,6 +390,16 @@ IL_000a: ret } // end of method 'products12@13-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101ElementOperators01/'products12@13-1'::.ctor() + IL_0005: stsfld class Linq101ElementOperators01/'products12@13-1' Linq101ElementOperators01/'products12@13-1'::@_instance + IL_000a: ret + } // end of method 'products12@13-1'::.cctor + } // end of class 'products12@13-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname startsWithO@22 @@ -456,7 +442,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string s) @@ -467,94 +453,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 22,22 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_strings() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_strings() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101ElementOperators01/startsWithO@22::pc .line 22,22 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 22,22 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 23,23 : 9,28 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101ElementOperators01/startsWithO@22::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101ElementOperators01/startsWithO@22::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101ElementOperators01/startsWithO@22::pc .line 22,22 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101ElementOperators01/startsWithO@22::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101ElementOperators01/startsWithO@22::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101ElementOperators01/startsWithO@22::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method startsWithO@22::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/startsWithO@22::pc @@ -562,158 +541,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101ElementOperators01/startsWithO@22::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101ElementOperators01/startsWithO@22::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/startsWithO@22::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101ElementOperators01/startsWithO@22::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101ElementOperators01/startsWithO@22::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101ElementOperators01/startsWithO@22::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101ElementOperators01/startsWithO@22::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 22,22 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 22,22 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method startsWithO@22::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/startsWithO@22::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method startsWithO@22::get_CheckClose .method public strict virtual instance string @@ -749,6 +705,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'startsWithO@23-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101ElementOperators01/'startsWithO@23-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -769,12 +726,22 @@ .line 23,23 : 16,27 '' IL_0000: ldarg.1 IL_0001: ldc.i4.0 - IL_0002: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0002: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0007: ldc.i4.s 111 IL_0009: ceq IL_000b: ret } // end of method 'startsWithO@23-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101ElementOperators01/'startsWithO@23-1'::.ctor() + IL_0005: stsfld class Linq101ElementOperators01/'startsWithO@23-1' Linq101ElementOperators01/'startsWithO@23-1'::@_instance + IL_000a: ret + } // end of method 'startsWithO@23-1'::.cctor + } // end of class 'startsWithO@23-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstNumOrDefault@31 @@ -817,7 +784,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -828,94 +795,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 31,31 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc .line 31,31 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 31,31 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 32,32 : 9,22 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc .line 31,31 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method firstNumOrDefault@31::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc @@ -923,158 +883,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/firstNumOrDefault@31::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101ElementOperators01/firstNumOrDefault@31::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 31,31 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 31,31 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method firstNumOrDefault@31::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/firstNumOrDefault@31::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method firstNumOrDefault@31::get_CheckClose .method public strict virtual instance int32 @@ -1147,7 +1084,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -1158,94 +1095,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 52,52 : 9,29 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_numbers2() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101ElementOperators01::get_numbers2() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc .line 52,52 : 9,29 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 52,52 : 9,29 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 53,53 : 9,22 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc .line 52,52 : 9,29 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method fourthLowNum@52::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/fourthLowNum@52::pc @@ -1253,158 +1183,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101ElementOperators01/fourthLowNum@52::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101ElementOperators01/fourthLowNum@52::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101ElementOperators01/fourthLowNum@52::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101ElementOperators01/fourthLowNum@52::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 52,52 : 9,29 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 52,52 : 9,29 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method fourthLowNum@52::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101ElementOperators01/fourthLowNum@52::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method fourthLowNum@52::get_CheckClose .method public strict virtual instance int32 @@ -1440,6 +1347,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'fourthLowNum@53-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101ElementOperators01/'fourthLowNum@53-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1464,6 +1372,16 @@ IL_0004: ret } // end of method 'fourthLowNum@53-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101ElementOperators01/'fourthLowNum@53-1'::.ctor() + IL_0005: stsfld class Linq101ElementOperators01/'fourthLowNum@53-1' Linq101ElementOperators01/'fourthLowNum@53-1'::@_instance + IL_000a: ret + } // end of method 'fourthLowNum@53-1'::.cctor + } // end of class 'fourthLowNum@53-1' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -1471,7 +1389,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::'products@8-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::products@8 IL_0005: ret } // end of method Linq101ElementOperators01::get_products @@ -1527,7 +1445,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::'numbers2@48-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::numbers2@48 IL_0005: ret } // end of method Linq101ElementOperators01::get_numbers2 @@ -1588,7 +1506,7 @@ .class private abstract auto ansi sealed ''.$Linq101ElementOperators01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@8-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@8 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [Utils]Utils/Product products12@10 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1598,7 +1516,7 @@ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly int32 firstNumOrDefault@29 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers2@48-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers2@48 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly int32 fourthLowNum@50 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1625,7 +1543,7 @@ .line 8,8 : 1,32 '' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() IL_0005: dup - IL_0006: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::'products@8-2' + IL_0006: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::products@8 IL_000b: stloc.0 IL_000c: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() IL_0011: stloc.s V_8 @@ -1638,7 +1556,7 @@ int32, class [Utils]Utils/Product) IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0024: newobj instance void Linq101ElementOperators01/'products12@13-1'::.ctor() + IL_0024: ldsfld class Linq101ElementOperators01/'products12@13-1' Linq101ElementOperators01/'products12@13-1'::@_instance IL_0029: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_002e: callvirt instance !!0 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Head(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) @@ -1691,7 +1609,7 @@ int32, string) IL_00bd: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00c2: newobj instance void Linq101ElementOperators01/'startsWithO@23-1'::.ctor() + IL_00c2: ldsfld class Linq101ElementOperators01/'startsWithO@23-1' Linq101ElementOperators01/'startsWithO@23-1'::@_instance IL_00c7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_00cc: callvirt instance !!0 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Head(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) @@ -1746,7 +1664,7 @@ IL_013b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0140: dup - IL_0141: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::'numbers2@48-2' + IL_0141: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101ElementOperators01::numbers2@48 IL_0146: stloc.s numbers2 IL_0148: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() IL_014d: stloc.s V_10 @@ -1759,7 +1677,7 @@ int32, int32) IL_015b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0160: newobj instance void Linq101ElementOperators01/'fourthLowNum@53-1'::.ctor() + IL_0160: ldsfld class Linq101ElementOperators01/'fourthLowNum@53-1' Linq101ElementOperators01/'fourthLowNum@53-1'::@_instance IL_0165: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_016a: ldc.i4.1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl index 050bdf1cc6d..2ca5a307b26 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Grouping01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern System.Core { @@ -24,6 +24,11 @@ { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101Grouping01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -38,20 +43,20 @@ } .mresource public FSharpSignatureData.Linq101Grouping01 { - // Offset: 0x00000000 Length: 0x0000040F + // Offset: 0x00000000 Length: 0x00000403 } .mresource public FSharpOptimizationData.Linq101Grouping01 { - // Offset: 0x00000418 Length: 0x00000129 + // Offset: 0x00000408 Length: 0x00000129 } .module Linq101Grouping01.exe -// MVID: {5B9A68C1-FB79-E5BF-A745-0383C1689A5B} +// MVID: {611B0EC5-FB79-E5BF-A745-0383C50E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x025F0000 +// Image base: 0x053C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,7 +65,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit numberGroups@14 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@14' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -78,9 +83,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/numberGroups@14::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #1 input at line 13@14'::builder@ IL_000d: ret - } // end of method numberGroups@14::.ctor + } // end of method 'Pipe #1 input at line 13@14'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(int32 _arg1) cil managed @@ -89,23 +94,24 @@ .maxstack 6 .locals init ([0] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 14,14 : 9,28 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Grouping01.fs' + .line 14,14 : 9,28 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Grouping01.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 15,15 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/numberGroups@14::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #1 input at line 13@14'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method numberGroups@14::Invoke + } // end of method 'Pipe #1 input at line 13@14'::Invoke - } // end of class numberGroups@14 + } // end of class 'Pipe #1 input at line 13@14' - .class auto ansi serializable sealed nested assembly beforefieldinit 'numberGroups@15-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@15-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #1 input at line 13@15-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -116,7 +122,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'numberGroups@15-1'::.ctor + } // end of method 'Pipe #1 input at line 13@15-1'::.ctor .method public strict virtual instance int32 Invoke(int32 n) cil managed @@ -126,13 +132,24 @@ .line 15,15 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'numberGroups@15-1'::Invoke + } // end of method 'Pipe #1 input at line 13@15-1'::Invoke - } // end of class 'numberGroups@15-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #1 input at line 13@15-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #1 input at line 13@15-1' Linq101Grouping01/'Pipe #1 input at line 13@15-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 13@15-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'numberGroups@15-2' + } // end of class 'Pipe #1 input at line 13@15-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@15-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #1 input at line 13@15-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -143,7 +160,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'numberGroups@15-2'::.ctor + } // end of method 'Pipe #1 input at line 13@15-2'::.ctor .method public strict virtual instance int32 Invoke(int32 n) cil managed @@ -155,11 +172,21 @@ IL_0001: ldc.i4.5 IL_0002: rem IL_0003: ret - } // end of method 'numberGroups@15-2'::Invoke + } // end of method 'Pipe #1 input at line 13@15-2'::Invoke - } // end of class 'numberGroups@15-2' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #1 input at line 13@15-2'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #1 input at line 13@15-2' Linq101Grouping01/'Pipe #1 input at line 13@15-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 13@15-2'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'numberGroups@15-3' + } // end of class 'Pipe #1 input at line 13@15-2' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@15-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -177,9 +204,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'numberGroups@15-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #1 input at line 13@15-3'::builder@ IL_000d: ret - } // end of method 'numberGroups@15-3'::.ctor + } // end of method 'Pipe #1 input at line 13@15-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -191,18 +218,19 @@ IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'numberGroups@15-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #1 input at line 13@15-3'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0010: ret - } // end of method 'numberGroups@15-3'::Invoke + } // end of method 'Pipe #1 input at line 13@15-3'::Invoke - } // end of class 'numberGroups@15-3' + } // end of class 'Pipe #1 input at line 13@15-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'numberGroups@16-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@16-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Grouping01/'Pipe #1 input at line 13@16-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -213,7 +241,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'numberGroups@16-4'::.ctor + } // end of method 'Pipe #1 input at line 13@16-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed @@ -228,11 +256,21 @@ IL_000c: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0011: ret - } // end of method 'numberGroups@16-4'::Invoke + } // end of method 'Pipe #1 input at line 13@16-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #1 input at line 13@16-4'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #1 input at line 13@16-4' Linq101Grouping01/'Pipe #1 input at line 13@16-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 13@16-4'::.cctor - } // end of class 'numberGroups@16-4' + } // end of class 'Pipe #1 input at line 13@16-4' - .class auto ansi serializable sealed nested assembly beforefieldinit wordGroups@24 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 23@24' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -250,9 +288,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/wordGroups@24::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #2 input at line 23@24'::builder@ IL_000d: ret - } // end of method wordGroups@24::.ctor + } // end of method 'Pipe #2 input at line 23@24'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(string _arg1) cil managed @@ -265,18 +303,19 @@ IL_0001: stloc.0 .line 25,25 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/wordGroups@24::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #2 input at line 23@24'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method wordGroups@24::Invoke + } // end of method 'Pipe #2 input at line 23@24'::Invoke - } // end of class wordGroups@24 + } // end of class 'Pipe #2 input at line 23@24' - .class auto ansi serializable sealed nested assembly beforefieldinit 'wordGroups@25-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 23@25-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #2 input at line 23@25-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -287,7 +326,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'wordGroups@25-1'::.ctor + } // end of method 'Pipe #2 input at line 23@25-1'::.ctor .method public strict virtual instance string Invoke(string w) cil managed @@ -297,13 +336,24 @@ .line 25,25 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'wordGroups@25-1'::Invoke + } // end of method 'Pipe #2 input at line 23@25-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #2 input at line 23@25-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #2 input at line 23@25-1' Linq101Grouping01/'Pipe #2 input at line 23@25-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 23@25-1'::.cctor - } // end of class 'wordGroups@25-1' + } // end of class 'Pipe #2 input at line 23@25-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'wordGroups@25-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 23@25-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #2 input at line 23@25-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -314,23 +364,33 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'wordGroups@25-2'::.ctor + } // end of method 'Pipe #2 input at line 23@25-2'::.ctor .method public strict virtual instance char Invoke(string w) cil managed { // Code size 8 (0x8) .maxstack 8 - .line 25,25 : 24,25 '' + .line 25,25 : 23,28 '' IL_0000: ldarg.1 IL_0001: ldc.i4.0 - IL_0002: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0002: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0007: ret - } // end of method 'wordGroups@25-2'::Invoke + } // end of method 'Pipe #2 input at line 23@25-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #2 input at line 23@25-2'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #2 input at line 23@25-2' Linq101Grouping01/'Pipe #2 input at line 23@25-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 23@25-2'::.cctor - } // end of class 'wordGroups@25-2' + } // end of class 'Pipe #2 input at line 23@25-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'wordGroups@25-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 23@25-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -348,9 +408,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'wordGroups@25-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #2 input at line 23@25-3'::builder@ IL_000d: ret - } // end of method 'wordGroups@25-3'::.ctor + } // end of method 'Pipe #2 input at line 23@25-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -362,18 +422,19 @@ IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'wordGroups@25-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #2 input at line 23@25-3'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0010: ret - } // end of method 'wordGroups@25-3'::Invoke + } // end of method 'Pipe #2 input at line 23@25-3'::Invoke - } // end of class 'wordGroups@25-3' + } // end of class 'Pipe #2 input at line 23@25-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'wordGroups@26-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 23@26-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Grouping01/'Pipe #2 input at line 23@26-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -384,7 +445,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'wordGroups@26-4'::.ctor + } // end of method 'Pipe #2 input at line 23@26-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed @@ -399,11 +460,21 @@ IL_000c: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0011: ret - } // end of method 'wordGroups@26-4'::Invoke + } // end of method 'Pipe #2 input at line 23@26-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #2 input at line 23@26-4'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #2 input at line 23@26-4' Linq101Grouping01/'Pipe #2 input at line 23@26-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 23@26-4'::.cctor - } // end of class 'wordGroups@26-4' + } // end of class 'Pipe #2 input at line 23@26-4' - .class auto ansi serializable sealed nested assembly beforefieldinit orderGroups@34 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 33@34' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -421,9 +492,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/orderGroups@34::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #3 input at line 33@34'::builder@ IL_000d: ret - } // end of method orderGroups@34::.ctor + } // end of method 'Pipe #3 input at line 33@34'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -436,18 +507,19 @@ IL_0001: stloc.0 .line 35,35 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/orderGroups@34::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #3 input at line 33@34'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method orderGroups@34::Invoke + } // end of method 'Pipe #3 input at line 33@34'::Invoke - } // end of class orderGroups@34 + } // end of class 'Pipe #3 input at line 33@34' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orderGroups@35-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 33@35-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #3 input at line 33@35-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -458,7 +530,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'orderGroups@35-1'::.ctor + } // end of method 'Pipe #3 input at line 33@35-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -468,13 +540,24 @@ .line 35,35 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'orderGroups@35-1'::Invoke + } // end of method 'Pipe #3 input at line 33@35-1'::Invoke - } // end of class 'orderGroups@35-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #3 input at line 33@35-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #3 input at line 33@35-1' Linq101Grouping01/'Pipe #3 input at line 33@35-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 33@35-1'::.cctor + + } // end of class 'Pipe #3 input at line 33@35-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orderGroups@35-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 33@35-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'Pipe #3 input at line 33@35-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -485,7 +568,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'orderGroups@35-2'::.ctor + } // end of method 'Pipe #3 input at line 33@35-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -497,11 +580,21 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'orderGroups@35-2'::Invoke + } // end of method 'Pipe #3 input at line 33@35-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #3 input at line 33@35-2'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #3 input at line 33@35-2' Linq101Grouping01/'Pipe #3 input at line 33@35-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 33@35-2'::.cctor - } // end of class 'orderGroups@35-2' + } // end of class 'Pipe #3 input at line 33@35-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orderGroups@35-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 33@35-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -519,9 +612,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'orderGroups@35-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #3 input at line 33@35-3'::builder@ IL_000d: ret - } // end of method 'orderGroups@35-3'::.ctor + } // end of method 'Pipe #3 input at line 33@35-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -533,18 +626,19 @@ IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'orderGroups@35-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #3 input at line 33@35-3'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0010: ret - } // end of method 'orderGroups@35-3'::Invoke + } // end of method 'Pipe #3 input at line 33@35-3'::Invoke - } // end of class 'orderGroups@35-3' + } // end of class 'Pipe #3 input at line 33@35-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orderGroups@36-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 33@36-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Grouping01/'Pipe #3 input at line 33@36-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -555,7 +649,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'orderGroups@36-4'::.ctor + } // end of method 'Pipe #3 input at line 33@36-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed @@ -570,9 +664,19 @@ IL_000c: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0011: ret - } // end of method 'orderGroups@36-4'::Invoke + } // end of method 'Pipe #3 input at line 33@36-4'::Invoke - } // end of class 'orderGroups@36-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #3 input at line 33@36-4'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #3 input at line 33@36-4' Linq101Grouping01/'Pipe #3 input at line 33@36-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 33@36-4'::.cctor + + } // end of class 'Pipe #3 input at line 33@36-4' .class auto ansi serializable sealed nested assembly beforefieldinit yearGroups@47 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> @@ -619,6 +723,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'yearGroups@48-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'yearGroups@48-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -641,11 +746,22 @@ IL_0001: ret } // end of method 'yearGroups@48-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'yearGroups@48-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'yearGroups@48-1' Linq101Grouping01/'yearGroups@48-1'::@_instance + IL_000a: ret + } // end of method 'yearGroups@48-1'::.cctor + } // end of class 'yearGroups@48-1' .class auto ansi serializable sealed nested assembly beforefieldinit 'yearGroups@48-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'yearGroups@48-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -673,6 +789,16 @@ IL_000e: ret } // end of method 'yearGroups@48-2'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'yearGroups@48-2'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'yearGroups@48-2' Linq101Grouping01/'yearGroups@48-2'::@_instance + IL_000a: ret + } // end of method 'yearGroups@48-2'::.cctor + } // end of class 'yearGroups@48-2' .class auto ansi serializable sealed nested assembly beforefieldinit monthGroups@51 @@ -720,6 +846,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'monthGroups@52-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'monthGroups@52-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -742,11 +869,22 @@ IL_0001: ret } // end of method 'monthGroups@52-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'monthGroups@52-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'monthGroups@52-1' Linq101Grouping01/'monthGroups@52-1'::@_instance + IL_000a: ret + } // end of method 'monthGroups@52-1'::.cctor + } // end of class 'monthGroups@52-1' .class auto ansi serializable sealed nested assembly beforefieldinit 'monthGroups@52-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Grouping01/'monthGroups@52-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -774,6 +912,16 @@ IL_000e: ret } // end of method 'monthGroups@52-2'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'monthGroups@52-2'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'monthGroups@52-2' Linq101Grouping01/'monthGroups@52-2'::@_instance + IL_000a: ret + } // end of method 'monthGroups@52-2'::.cctor + } // end of class 'monthGroups@52-2' .class auto ansi serializable sealed nested assembly beforefieldinit 'monthGroups@52-3' @@ -820,6 +968,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'monthGroups@53-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Grouping01/'monthGroups@53-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -847,6 +996,16 @@ IL_0011: ret } // end of method 'monthGroups@53-4'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'monthGroups@53-4'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'monthGroups@53-4' Linq101Grouping01/'monthGroups@53-4'::@_instance + IL_000a: ret + } // end of method 'monthGroups@53-4'::.cctor + } // end of class 'monthGroups@53-4' .class auto ansi serializable sealed nested assembly beforefieldinit 'yearGroups@48-3' @@ -895,8 +1054,8 @@ IL_0014: newobj instance void Linq101Grouping01/monthGroups@51::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_0019: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_001e: newobj instance void Linq101Grouping01/'monthGroups@52-1'::.ctor() - IL_0023: newobj instance void Linq101Grouping01/'monthGroups@52-2'::.ctor() + IL_001e: ldsfld class Linq101Grouping01/'monthGroups@52-1' Linq101Grouping01/'monthGroups@52-1'::@_instance + IL_0023: ldsfld class Linq101Grouping01/'monthGroups@52-2' Linq101Grouping01/'monthGroups@52-2'::@_instance IL_0028: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) @@ -904,7 +1063,7 @@ IL_002e: newobj instance void Linq101Grouping01/'monthGroups@52-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_0033: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0038: newobj instance void Linq101Grouping01/'monthGroups@53-4'::.ctor() + IL_0038: ldsfld class Linq101Grouping01/'monthGroups@53-4' Linq101Grouping01/'monthGroups@53-4'::@_instance IL_003d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_0042: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() @@ -926,6 +1085,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'yearGroups@55-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.Generic.IEnumerable`1>>,class [mscorlib]System.Tuple`2[]>> { + .field static assembly initonly class Linq101Grouping01/'yearGroups@55-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -962,9 +1122,19 @@ IL_001f: ret } // end of method 'yearGroups@55-4'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'yearGroups@55-4'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'yearGroups@55-4' Linq101Grouping01/'yearGroups@55-4'::@_instance + IL_000a: ret + } // end of method 'yearGroups@55-4'::.cctor + } // end of class 'yearGroups@55-4' - .class auto ansi serializable sealed nested assembly beforefieldinit customerOrderGroups@44 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 43@44' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2[]>>>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -982,9 +1152,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2[]>>>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/customerOrderGroups@44::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #4 input at line 43@44'::builder@ IL_000d: ret - } // end of method customerOrderGroups@44::.ctor + } // end of method 'Pipe #4 input at line 43@44'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2[]>>>,object> Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -1012,8 +1182,8 @@ IL_0019: newobj instance void Linq101Grouping01/yearGroups@47::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_001e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0023: newobj instance void Linq101Grouping01/'yearGroups@48-1'::.ctor() - IL_0028: newobj instance void Linq101Grouping01/'yearGroups@48-2'::.ctor() + IL_0023: ldsfld class Linq101Grouping01/'yearGroups@48-1' Linq101Grouping01/'yearGroups@48-1'::@_instance + IL_0028: ldsfld class Linq101Grouping01/'yearGroups@48-2' Linq101Grouping01/'yearGroups@48-2'::@_instance IL_002d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) @@ -1021,14 +1191,14 @@ IL_0033: newobj instance void Linq101Grouping01/'yearGroups@48-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) IL_0038: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.Generic.IEnumerable`1>>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_003d: newobj instance void Linq101Grouping01/'yearGroups@55-4'::.ctor() + IL_003d: ldsfld class Linq101Grouping01/'yearGroups@55-4' Linq101Grouping01/'yearGroups@55-4'::@_instance IL_0042: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.Generic.IEnumerable`1>>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2[]>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_0047: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2[]>,class [mscorlib]System.Collections.IEnumerable>::get_Source() IL_004c: stloc.1 .line 57,57 : 9,53 '' IL_004d: ldarg.0 - IL_004e: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/customerOrderGroups@44::builder@ + IL_004e: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Grouping01/'Pipe #4 input at line 43@44'::builder@ IL_0053: ldloc.0 IL_0054: ldloc.1 IL_0055: newobj instance void class [mscorlib]System.Tuple`2[]>>>::.ctor(!0, @@ -1036,13 +1206,14 @@ IL_005a: tail. IL_005c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield[]>>>,object>(!!0) IL_0061: ret - } // end of method customerOrderGroups@44::Invoke + } // end of method 'Pipe #4 input at line 43@44'::Invoke - } // end of class customerOrderGroups@44 + } // end of class 'Pipe #4 input at line 43@44' - .class auto ansi serializable sealed nested assembly beforefieldinit 'customerOrderGroups@57-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 43@57-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2[]>>>,class [mscorlib]System.Tuple`2[]>[]>> { + .field static assembly initonly class Linq101Grouping01/'Pipe #4 input at line 43@57-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1053,7 +1224,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2[]>>>,class [mscorlib]System.Tuple`2[]>[]>>::.ctor() IL_0006: ret - } // end of method 'customerOrderGroups@57-1'::.ctor + } // end of method 'Pipe #4 input at line 43@57-1'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2[]>[]> Invoke(class [mscorlib]System.Tuple`2[]>>> tupledArg) cil managed @@ -1077,9 +1248,19 @@ IL_001a: newobj instance void class [mscorlib]System.Tuple`2[]>[]>::.ctor(!0, !1) IL_001f: ret - } // end of method 'customerOrderGroups@57-1'::Invoke + } // end of method 'Pipe #4 input at line 43@57-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Grouping01/'Pipe #4 input at line 43@57-1'::.ctor() + IL_0005: stsfld class Linq101Grouping01/'Pipe #4 input at line 43@57-1' Linq101Grouping01/'Pipe #4 input at line 43@57-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 43@57-1'::.cctor - } // end of class 'customerOrderGroups@57-1' + } // end of class 'Pipe #4 input at line 43@57-1' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_digits() cil managed @@ -1095,7 +1276,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'numbers@10-3' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::numbers@10 IL_0005: ret } // end of method Linq101Grouping01::get_numbers @@ -1113,7 +1294,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'words@20-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::words@20 IL_0005: ret } // end of method Linq101Grouping01::get_words @@ -1131,7 +1312,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'products@30-4' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::products@30 IL_0005: ret } // end of method Linq101Grouping01::get_products @@ -1223,15 +1404,15 @@ { .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits@7 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers@10-3' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers@10 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] numberGroups@12 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'words@20-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words@20 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] wordGroups@22 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@30-4' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@30 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] orderGroups@32 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1246,7 +1427,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 628 (0x274) + // Code size 648 (0x288) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers, @@ -1257,10 +1438,14 @@ [6] class [mscorlib]System.Tuple`2[] orderGroups, [7] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers, [8] class [mscorlib]System.Tuple`2[]>[]>[] customerOrderGroups, - [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, + [9] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #1 input at line 13', [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10, - [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, - [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12) + [11] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #2 input at line 23', + [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12, + [13] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #3 input at line 33', + [14] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_14, + [15] class [mscorlib]System.Collections.Generic.IEnumerable`1[]>[]>> 'Pipe #4 input at line 43', + [16] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_16) .line 7,7 : 1,96 '' IL_0000: ldstr "zero" IL_0005: ldstr "one" @@ -1329,49 +1514,52 @@ IL_00ad: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_00b2: dup - IL_00b3: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'numbers@10-3' + IL_00b3: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::numbers@10 IL_00b8: stloc.1 .line 12,17 : 1,21 '' - IL_00b9: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00be: stloc.s V_9 - IL_00c0: ldloc.s V_9 - IL_00c2: ldloc.s V_9 - IL_00c4: ldloc.s V_9 - IL_00c6: ldloc.s V_9 - IL_00c8: ldloc.s V_9 - IL_00ca: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_numbers() - IL_00cf: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00d4: ldloc.s V_9 - IL_00d6: newobj instance void Linq101Grouping01/numberGroups@14::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00db: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00b9: nop + .line 13,13 : 5,10 '' + IL_00ba: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00bf: stloc.s V_10 + IL_00c1: ldloc.s V_10 + IL_00c3: ldloc.s V_10 + IL_00c5: ldloc.s V_10 + IL_00c7: ldloc.s V_10 + IL_00c9: ldloc.s V_10 + IL_00cb: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_numbers() + IL_00d0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00d5: ldloc.s V_10 + IL_00d7: newobj instance void Linq101Grouping01/'Pipe #1 input at line 13@14'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00dc: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00e0: newobj instance void Linq101Grouping01/'numberGroups@15-1'::.ctor() - IL_00e5: newobj instance void Linq101Grouping01/'numberGroups@15-2'::.ctor() - IL_00ea: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00e1: ldsfld class Linq101Grouping01/'Pipe #1 input at line 13@15-1' Linq101Grouping01/'Pipe #1 input at line 13@15-1'::@_instance + IL_00e6: ldsfld class Linq101Grouping01/'Pipe #1 input at line 13@15-2' Linq101Grouping01/'Pipe #1 input at line 13@15-2'::@_instance + IL_00eb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00ef: ldloc.s V_9 - IL_00f1: newobj instance void Linq101Grouping01/'numberGroups@15-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00f6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00f0: ldloc.s V_10 + IL_00f2: newobj instance void Linq101Grouping01/'Pipe #1 input at line 13@15-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00f7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00fb: newobj instance void Linq101Grouping01/'numberGroups@16-4'::.ctor() - IL_0100: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00fc: ldsfld class Linq101Grouping01/'Pipe #1 input at line 13@16-4' Linq101Grouping01/'Pipe #1 input at line 13@16-4'::@_instance + IL_0101: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0105: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_010a: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_010f: dup - IL_0110: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::numberGroups@12 - IL_0115: stloc.2 + IL_0106: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_010b: stloc.s 'Pipe #1 input at line 13' + .line 17,17 : 10,21 '' + IL_010d: ldloc.s 'Pipe #1 input at line 13' + IL_010f: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0114: dup + IL_0115: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::numberGroups@12 + IL_011a: stloc.2 .line 20,20 : 1,80 '' - IL_0116: ldstr "blueberry" - IL_011b: ldstr "chimpanzee" - IL_0120: ldstr "abacus" - IL_0125: ldstr "banana" - IL_012a: ldstr "apple" - IL_012f: ldstr "cheese" - IL_0134: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0139: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_011b: ldstr "blueberry" + IL_0120: ldstr "chimpanzee" + IL_0125: ldstr "abacus" + IL_012a: ldstr "banana" + IL_012f: ldstr "apple" + IL_0134: ldstr "cheese" + IL_0139: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_013e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0143: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -1382,102 +1570,119 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0152: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0157: dup - IL_0158: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'words@20-2' - IL_015d: stloc.3 + IL_0157: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_015c: dup + IL_015d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::words@20 + IL_0162: stloc.3 .line 22,27 : 1,21 '' - IL_015e: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0163: stloc.s V_10 - IL_0165: ldloc.s V_10 - IL_0167: ldloc.s V_10 - IL_0169: ldloc.s V_10 - IL_016b: ldloc.s V_10 - IL_016d: ldloc.s V_10 - IL_016f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_words() - IL_0174: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0179: ldloc.s V_10 - IL_017b: newobj instance void Linq101Grouping01/wordGroups@24::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0180: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0163: nop + .line 23,23 : 5,10 '' + IL_0164: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0169: stloc.s V_12 + IL_016b: ldloc.s V_12 + IL_016d: ldloc.s V_12 + IL_016f: ldloc.s V_12 + IL_0171: ldloc.s V_12 + IL_0173: ldloc.s V_12 + IL_0175: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_words() + IL_017a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_017f: ldloc.s V_12 + IL_0181: newobj instance void Linq101Grouping01/'Pipe #2 input at line 23@24'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0186: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0185: newobj instance void Linq101Grouping01/'wordGroups@25-1'::.ctor() - IL_018a: newobj instance void Linq101Grouping01/'wordGroups@25-2'::.ctor() - IL_018f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_018b: ldsfld class Linq101Grouping01/'Pipe #2 input at line 23@25-1' Linq101Grouping01/'Pipe #2 input at line 23@25-1'::@_instance + IL_0190: ldsfld class Linq101Grouping01/'Pipe #2 input at line 23@25-2' Linq101Grouping01/'Pipe #2 input at line 23@25-2'::@_instance + IL_0195: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0194: ldloc.s V_10 - IL_0196: newobj instance void Linq101Grouping01/'wordGroups@25-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_019b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_019a: ldloc.s V_12 + IL_019c: newobj instance void Linq101Grouping01/'Pipe #2 input at line 23@25-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01a1: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_01a0: newobj instance void Linq101Grouping01/'wordGroups@26-4'::.ctor() - IL_01a5: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01a6: ldsfld class Linq101Grouping01/'Pipe #2 input at line 23@26-4' Linq101Grouping01/'Pipe #2 input at line 23@26-4'::@_instance + IL_01ab: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01aa: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_01af: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01b4: dup - IL_01b5: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::wordGroups@22 - IL_01ba: stloc.s wordGroups + IL_01b0: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_01b5: stloc.s 'Pipe #2 input at line 23' + .line 27,27 : 10,21 '' + IL_01b7: ldloc.s 'Pipe #2 input at line 23' + IL_01b9: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01be: dup + IL_01bf: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::wordGroups@22 + IL_01c4: stloc.s wordGroups .line 30,30 : 1,32 '' - IL_01bc: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_01c1: dup - IL_01c2: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::'products@30-4' - IL_01c7: stloc.s products + IL_01c6: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_01cb: dup + IL_01cc: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::products@30 + IL_01d1: stloc.s products .line 32,37 : 1,21 '' - IL_01c9: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_01ce: stloc.s V_11 - IL_01d0: ldloc.s V_11 - IL_01d2: ldloc.s V_11 - IL_01d4: ldloc.s V_11 - IL_01d6: ldloc.s V_11 - IL_01d8: ldloc.s V_11 - IL_01da: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_products() - IL_01df: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01e4: ldloc.s V_11 - IL_01e6: newobj instance void Linq101Grouping01/orderGroups@34::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_01eb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01d3: nop + .line 33,33 : 5,10 '' + IL_01d4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01d9: stloc.s V_14 + IL_01db: ldloc.s V_14 + IL_01dd: ldloc.s V_14 + IL_01df: ldloc.s V_14 + IL_01e1: ldloc.s V_14 + IL_01e3: ldloc.s V_14 + IL_01e5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_products() + IL_01ea: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01ef: ldloc.s V_14 + IL_01f1: newobj instance void Linq101Grouping01/'Pipe #3 input at line 33@34'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01f6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_01f0: newobj instance void Linq101Grouping01/'orderGroups@35-1'::.ctor() - IL_01f5: newobj instance void Linq101Grouping01/'orderGroups@35-2'::.ctor() - IL_01fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01fb: ldsfld class Linq101Grouping01/'Pipe #3 input at line 33@35-1' Linq101Grouping01/'Pipe #3 input at line 33@35-1'::@_instance + IL_0200: ldsfld class Linq101Grouping01/'Pipe #3 input at line 33@35-2' Linq101Grouping01/'Pipe #3 input at line 33@35-2'::@_instance + IL_0205: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01ff: ldloc.s V_11 - IL_0201: newobj instance void Linq101Grouping01/'orderGroups@35-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0206: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_020a: ldloc.s V_14 + IL_020c: newobj instance void Linq101Grouping01/'Pipe #3 input at line 33@35-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0211: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_020b: newobj instance void Linq101Grouping01/'orderGroups@36-4'::.ctor() - IL_0210: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0216: ldsfld class Linq101Grouping01/'Pipe #3 input at line 33@36-4' Linq101Grouping01/'Pipe #3 input at line 33@36-4'::@_instance + IL_021b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0215: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_021a: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_021f: dup - IL_0220: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::orderGroups@32 - IL_0225: stloc.s orderGroups + IL_0220: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0225: stloc.s 'Pipe #3 input at line 33' + .line 37,37 : 10,21 '' + IL_0227: ldloc.s 'Pipe #3 input at line 33' + IL_0229: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_022e: dup + IL_022f: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Grouping01::orderGroups@32 + IL_0234: stloc.s orderGroups .line 40,40 : 1,34 '' - IL_0227: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() - IL_022c: dup - IL_022d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::customers@40 - IL_0232: stloc.s customers + IL_0236: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() + IL_023b: dup + IL_023c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Grouping01::customers@40 + IL_0241: stloc.s customers .line 42,58 : 1,21 '' - IL_0234: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0239: stloc.s V_12 - IL_023b: ldloc.s V_12 - IL_023d: ldloc.s V_12 - IL_023f: ldloc.s V_12 - IL_0241: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_customers() - IL_0246: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_024b: ldloc.s V_12 - IL_024d: newobj instance void Linq101Grouping01/customerOrderGroups@44::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0252: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For[]>>>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0243: nop + .line 43,43 : 5,10 '' + IL_0244: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0249: stloc.s V_16 + IL_024b: ldloc.s V_16 + IL_024d: ldloc.s V_16 + IL_024f: ldloc.s V_16 + IL_0251: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Grouping01::get_customers() + IL_0256: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_025b: ldloc.s V_16 + IL_025d: newobj instance void Linq101Grouping01/'Pipe #4 input at line 43@44'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0262: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For[]>>>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0257: newobj instance void Linq101Grouping01/'customerOrderGroups@57-1'::.ctor() - IL_025c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select[]>>>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2[]>[]>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0267: ldsfld class Linq101Grouping01/'Pipe #4 input at line 43@57-1' Linq101Grouping01/'Pipe #4 input at line 43@57-1'::@_instance + IL_026c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select[]>>>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2[]>[]>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0261: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2[]>[]>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0266: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray[]>[]>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_026b: dup - IL_026c: stsfld class [mscorlib]System.Tuple`2[]>[]>[] ''.$Linq101Grouping01::customerOrderGroups@42 - IL_0271: stloc.s customerOrderGroups - IL_0273: ret + IL_0271: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2[]>[]>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0276: stloc.s 'Pipe #4 input at line 43' + .line 58,58 : 10,21 '' + IL_0278: ldloc.s 'Pipe #4 input at line 43' + IL_027a: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray[]>[]>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_027f: dup + IL_0280: stsfld class [mscorlib]System.Tuple`2[]>[]>[] ''.$Linq101Grouping01::customerOrderGroups@42 + IL_0285: stloc.s customerOrderGroups + IL_0287: ret } // end of method $Linq101Grouping01::main@ } // end of class ''.$Linq101Grouping01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Joins01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Joins01.il.bsl index f985ce06194..20da6d9ded5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Joins01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Joins01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { @@ -38,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Joins01 { - // Offset: 0x00000000 Length: 0x00000316 + // Offset: 0x00000000 Length: 0x0000030A } .mresource public FSharpOptimizationData.Linq101Joins01 { - // Offset: 0x00000320 Length: 0x000000C3 + // Offset: 0x00000310 Length: 0x000000C3 } .module Linq101Joins01.exe -// MVID: {5B9A68C1-151B-685E-A745-0383C1689A5B} +// MVID: {611C4D82-151B-685E-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026A0000 +// Image base: 0x06C40000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,9 +60,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit q@14 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 12@14' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #1 input at line 12@14' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -73,7 +74,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method q@14::.ctor + } // end of method 'Pipe #1 input at line 12@14'::.ctor .method public strict virtual instance string Invoke(string c) cil managed @@ -81,16 +82,27 @@ // Code size 2 (0x2) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 14,14 : 32,33 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Joins01.fs' + .line 14,14 : 32,33 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Joins01.fs' IL_0000: ldarg.1 IL_0001: ret - } // end of method q@14::Invoke + } // end of method 'Pipe #1 input at line 12@14'::Invoke - } // end of class q@14 + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #1 input at line 12@14'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #1 input at line 12@14' Linq101Joins01/'Pipe #1 input at line 12@14'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 12@14'::.cctor + + } // end of class 'Pipe #1 input at line 12@14' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q@14-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 12@14-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #1 input at line 12@14-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -101,7 +113,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'q@14-1'::.ctor + } // end of method 'Pipe #1 input at line 12@14-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -113,13 +125,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'q@14-1'::Invoke + } // end of method 'Pipe #1 input at line 12@14-1'::Invoke - } // end of class 'q@14-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #1 input at line 12@14-1'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #1 input at line 12@14-1' Linq101Joins01/'Pipe #1 input at line 12@14-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 12@14-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'q@14-2' + } // end of class 'Pipe #1 input at line 12@14-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 12@14-2' extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3> { + .field static assembly initonly class Linq101Joins01/'Pipe #1 input at line 12@14-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -130,7 +153,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3>::.ctor() IL_0006: ret - } // end of method 'q@14-2'::.ctor + } // end of method 'Pipe #1 input at line 12@14-2'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(string c, @@ -144,11 +167,21 @@ IL_0002: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0007: ret - } // end of method 'q@14-2'::Invoke + } // end of method 'Pipe #1 input at line 12@14-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #1 input at line 12@14-2'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #1 input at line 12@14-2' Linq101Joins01/'Pipe #1 input at line 12@14-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 12@14-2'::.cctor - } // end of class 'q@14-2' + } // end of class 'Pipe #1 input at line 12@14-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q@14-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 12@14-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -166,9 +199,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q@14-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #1 input at line 12@14-3'::builder@ IL_000d: ret - } // end of method 'q@14-3'::.ctor + } // end of method 'Pipe #1 input at line 12@14-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [mscorlib]System.Tuple`2 _arg1) cil managed @@ -188,7 +221,7 @@ IL_000a: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() IL_000f: stloc.2 IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q@14-3'::builder@ + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #1 input at line 12@14-3'::builder@ IL_0016: ldloc.2 IL_0017: ldloc.1 IL_0018: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, @@ -196,13 +229,14 @@ IL_001d: tail. IL_001f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0024: ret - } // end of method 'q@14-3'::Invoke + } // end of method 'Pipe #1 input at line 12@14-3'::Invoke - } // end of class 'q@14-3' + } // end of class 'Pipe #1 input at line 12@14-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q@15-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 12@15-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Joins01/'Pipe #1 input at line 12@15-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -213,7 +247,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'q@15-4'::.ctor + } // end of method 'Pipe #1 input at line 12@15-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -236,13 +270,24 @@ IL_0015: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_001a: ret - } // end of method 'q@15-4'::Invoke + } // end of method 'Pipe #1 input at line 12@15-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #1 input at line 12@15-4'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #1 input at line 12@15-4' Linq101Joins01/'Pipe #1 input at line 12@15-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 12@15-4'::.cctor - } // end of class 'q@15-4' + } // end of class 'Pipe #1 input at line 12@15-4' - .class auto ansi serializable sealed nested assembly beforefieldinit q2@22 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 20@22' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #2 input at line 20@22' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -253,7 +298,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method q2@22::.ctor + } // end of method 'Pipe #2 input at line 20@22'::.ctor .method public strict virtual instance string Invoke(string c) cil managed @@ -263,13 +308,24 @@ .line 22,22 : 37,38 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method q2@22::Invoke + } // end of method 'Pipe #2 input at line 20@22'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #2 input at line 20@22'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #2 input at line 20@22' Linq101Joins01/'Pipe #2 input at line 20@22'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 20@22'::.cctor - } // end of class q2@22 + } // end of class 'Pipe #2 input at line 20@22' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q2@22-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 20@22-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #2 input at line 20@22-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -280,7 +336,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'q2@22-1'::.ctor + } // end of method 'Pipe #2 input at line 20@22-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -292,13 +348,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'q2@22-1'::Invoke + } // end of method 'Pipe #2 input at line 20@22-1'::Invoke - } // end of class 'q2@22-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #2 input at line 20@22-1'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #2 input at line 20@22-1' Linq101Joins01/'Pipe #2 input at line 20@22-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 20@22-1'::.cctor + + } // end of class 'Pipe #2 input at line 20@22-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q2@22-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 20@22-2' extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Joins01/'Pipe #2 input at line 20@22-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -309,7 +376,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'q2@22-2'::.ctor + } // end of method 'Pipe #2 input at line 20@22-2'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(string c, @@ -323,11 +390,21 @@ IL_0002: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0007: ret - } // end of method 'q2@22-2'::Invoke + } // end of method 'Pipe #2 input at line 20@22-2'::Invoke - } // end of class 'q2@22-2' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #2 input at line 20@22-2'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #2 input at line 20@22-2' Linq101Joins01/'Pipe #2 input at line 20@22-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 20@22-2'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'q2@22-3' + } // end of class 'Pipe #2 input at line 20@22-2' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 20@22-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -345,9 +422,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q2@22-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #2 input at line 20@22-3'::builder@ IL_000d: ret - } // end of method 'q2@22-3'::.ctor + } // end of method 'Pipe #2 input at line 20@22-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,object> Invoke(class [mscorlib]System.Tuple`2> _arg1) cil managed @@ -367,7 +444,7 @@ IL_000a: call instance !0 class [mscorlib]System.Tuple`2>::get_Item1() IL_000f: stloc.2 IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q2@22-3'::builder@ + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #2 input at line 20@22-3'::builder@ IL_0016: ldloc.2 IL_0017: ldloc.1 IL_0018: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, @@ -375,13 +452,14 @@ IL_001d: tail. IL_001f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield>,object>(!!0) IL_0024: ret - } // end of method 'q2@22-3'::Invoke + } // end of method 'Pipe #2 input at line 20@22-3'::Invoke - } // end of class 'q2@22-3' + } // end of class 'Pipe #2 input at line 20@22-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q2@23-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 20@23-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Joins01/'Pipe #2 input at line 20@23-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -392,7 +470,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'q2@23-4'::.ctor + } // end of method 'Pipe #2 input at line 20@23-4'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(class [mscorlib]System.Tuple`2> tupledArg) cil managed @@ -414,13 +492,24 @@ IL_0010: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0015: ret - } // end of method 'q2@23-4'::Invoke + } // end of method 'Pipe #2 input at line 20@23-4'::Invoke - } // end of class 'q2@23-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #2 input at line 20@23-4'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #2 input at line 20@23-4' Linq101Joins01/'Pipe #2 input at line 20@23-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 20@23-4'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit q3@30 + } // end of class 'Pipe #2 input at line 20@23-4' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@30' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #3 input at line 28@30' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -431,7 +520,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method q3@30::.ctor + } // end of method 'Pipe #3 input at line 28@30'::.ctor .method public strict virtual instance string Invoke(string c) cil managed @@ -441,13 +530,24 @@ .line 30,30 : 37,38 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method q3@30::Invoke + } // end of method 'Pipe #3 input at line 28@30'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@30'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #3 input at line 28@30' Linq101Joins01/'Pipe #3 input at line 28@30'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 28@30'::.cctor - } // end of class q3@30 + } // end of class 'Pipe #3 input at line 28@30' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q3@30-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@30-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #3 input at line 28@30-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -458,7 +558,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'q3@30-1'::.ctor + } // end of method 'Pipe #3 input at line 28@30-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -470,13 +570,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'q3@30-1'::Invoke + } // end of method 'Pipe #3 input at line 28@30-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@30-1'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #3 input at line 28@30-1' Linq101Joins01/'Pipe #3 input at line 28@30-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 28@30-1'::.cctor - } // end of class 'q3@30-1' + } // end of class 'Pipe #3 input at line 28@30-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q3@30-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@30-2' extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Joins01/'Pipe #3 input at line 28@30-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -487,7 +598,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'q3@30-2'::.ctor + } // end of method 'Pipe #3 input at line 28@30-2'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(string c, @@ -501,11 +612,21 @@ IL_0002: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0007: ret - } // end of method 'q3@30-2'::Invoke + } // end of method 'Pipe #3 input at line 28@30-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@30-2'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #3 input at line 28@30-2' Linq101Joins01/'Pipe #3 input at line 28@30-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 28@30-2'::.cctor - } // end of class 'q3@30-2' + } // end of class 'Pipe #3 input at line 28@30-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q3@31-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@31-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -527,15 +648,15 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@31-4'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@31-4'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'q3@31-4'::ps + IL_000f: stfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'Pipe #3 input at line 28@31-4'::ps IL_0014: ldarg.0 IL_0015: ldarg.3 - IL_0016: stfld string Linq101Joins01/'q3@31-4'::c + IL_0016: stfld string Linq101Joins01/'Pipe #3 input at line 28@31-4'::c IL_001b: ret - } // end of method 'q3@31-4'::.ctor + } // end of method 'Pipe #3 input at line 28@31-4'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product>,object> Invoke(class [Utils]Utils/Product _arg2) cil managed @@ -548,11 +669,11 @@ IL_0001: stloc.0 .line 32,32 : 9,34 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@31-4'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@31-4'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld string Linq101Joins01/'q3@31-4'::c + IL_0009: ldfld string Linq101Joins01/'Pipe #3 input at line 28@31-4'::c IL_000e: ldarg.0 - IL_000f: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'q3@31-4'::ps + IL_000f: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'Pipe #3 input at line 28@31-4'::ps IL_0014: ldloc.0 IL_0015: newobj instance void class [mscorlib]System.Tuple`3,class [Utils]Utils/Product>::.ctor(!0, !1, @@ -560,11 +681,11 @@ IL_001a: tail. IL_001c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,class [Utils]Utils/Product>,object>(!!0) IL_0021: ret - } // end of method 'q3@31-4'::Invoke + } // end of method 'Pipe #3 input at line 28@31-4'::Invoke - } // end of class 'q3@31-4' + } // end of class 'Pipe #3 input at line 28@31-4' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q3@30-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@30-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -582,9 +703,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@30-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@30-3'::builder@ IL_000d: ret - } // end of method 'q3@30-3'::.ctor + } // end of method 'Pipe #3 input at line 28@30-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable> Invoke(class [mscorlib]System.Tuple`2> _arg1) cil managed @@ -604,29 +725,30 @@ IL_000a: call instance !0 class [mscorlib]System.Tuple`2>::get_Item1() IL_000f: stloc.2 IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@30-3'::builder@ + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@30-3'::builder@ IL_0016: ldarg.0 - IL_0017: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@30-3'::builder@ + IL_0017: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@30-3'::builder@ IL_001c: ldloc.1 IL_001d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0022: ldarg.0 - IL_0023: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q3@30-3'::builder@ + IL_0023: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #3 input at line 28@30-3'::builder@ IL_0028: ldloc.1 IL_0029: ldloc.2 - IL_002a: newobj instance void Linq101Joins01/'q3@31-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [mscorlib]System.Collections.Generic.IEnumerable`1, - string) + IL_002a: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@31-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [mscorlib]System.Collections.Generic.IEnumerable`1, + string) IL_002f: tail. IL_0031: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [Utils]Utils/Product>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0036: ret - } // end of method 'q3@30-3'::Invoke + } // end of method 'Pipe #3 input at line 28@30-3'::Invoke - } // end of class 'q3@30-3' + } // end of class 'Pipe #3 input at line 28@30-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q3@32-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 28@32-5' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Joins01/'Pipe #3 input at line 28@32-5' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -637,7 +759,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'q3@32-5'::.ctor + } // end of method 'Pipe #3 input at line 28@32-5'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`3,class [Utils]Utils/Product> tupledArg) cil managed @@ -664,13 +786,24 @@ IL_001c: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0021: ret - } // end of method 'q3@32-5'::Invoke + } // end of method 'Pipe #3 input at line 28@32-5'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@32-5'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #3 input at line 28@32-5' Linq101Joins01/'Pipe #3 input at line 28@32-5'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 28@32-5'::.cctor - } // end of class 'q3@32-5' + } // end of class 'Pipe #3 input at line 28@32-5' - .class auto ansi serializable sealed nested assembly beforefieldinit q4@39 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@39' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #4 input at line 37@39' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -681,7 +814,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method q4@39::.ctor + } // end of method 'Pipe #4 input at line 37@39'::.ctor .method public strict virtual instance string Invoke(string c) cil managed @@ -691,13 +824,24 @@ .line 39,39 : 37,38 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method q4@39::Invoke + } // end of method 'Pipe #4 input at line 37@39'::Invoke - } // end of class q4@39 + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@39'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #4 input at line 37@39' Linq101Joins01/'Pipe #4 input at line 37@39'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 37@39'::.cctor + + } // end of class 'Pipe #4 input at line 37@39' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q4@39-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@39-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Joins01/'Pipe #4 input at line 37@39-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -708,7 +852,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'q4@39-1'::.ctor + } // end of method 'Pipe #4 input at line 37@39-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -720,13 +864,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'q4@39-1'::Invoke + } // end of method 'Pipe #4 input at line 37@39-1'::Invoke - } // end of class 'q4@39-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@39-1'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #4 input at line 37@39-1' Linq101Joins01/'Pipe #4 input at line 37@39-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 37@39-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'q4@39-2' + } // end of class 'Pipe #4 input at line 37@39-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@39-2' extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Joins01/'Pipe #4 input at line 37@39-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -737,7 +892,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'q4@39-2'::.ctor + } // end of method 'Pipe #4 input at line 37@39-2'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(string c, @@ -751,11 +906,21 @@ IL_0002: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_0007: ret - } // end of method 'q4@39-2'::Invoke + } // end of method 'Pipe #4 input at line 37@39-2'::Invoke - } // end of class 'q4@39-2' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@39-2'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #4 input at line 37@39-2' Linq101Joins01/'Pipe #4 input at line 37@39-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 37@39-2'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'q4@40-4' + } // end of class 'Pipe #4 input at line 37@39-2' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@40-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product,string>,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -777,20 +942,20 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product,string>,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@40-4'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@40-4'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'q4@40-4'::ps + IL_000f: stfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'Pipe #4 input at line 37@40-4'::ps IL_0014: ldarg.0 IL_0015: ldarg.3 - IL_0016: stfld string Linq101Joins01/'q4@40-4'::c + IL_0016: stfld string Linq101Joins01/'Pipe #4 input at line 37@40-4'::c IL_001b: ret - } // end of method 'q4@40-4'::.ctor + } // end of method 'Pipe #4 input at line 37@40-4'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product,string>,object> Invoke(class [Utils]Utils/Product _arg2) cil managed { - // Code size 69 (0x45) + // Code size 66 (0x42) .maxstack 9 .locals init ([0] class [Utils]Utils/Product p, [1] string t) @@ -798,51 +963,49 @@ IL_0000: ldarg.1 IL_0001: stloc.0 .line 41,41 : 17,39 '' - IL_0002: ldloc.0 - IL_0003: box [Utils]Utils/Product - IL_0008: ldnull - IL_0009: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityIntrinsic(!!0, + IL_0002: nop + .line 100001,100001 : 0,0 '' + IL_0003: ldloc.0 + IL_0004: box [Utils]Utils/Product + IL_0009: ldnull + IL_000a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityIntrinsic(!!0, !!0) - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_001c + IL_000f: brfalse.s IL_0019 .line 41,41 : 40,55 '' - IL_0014: ldstr "(No products)" + IL_0011: ldstr "(No products)" .line 100001,100001 : 0,0 '' - IL_0019: nop - IL_001a: br.s IL_0023 + IL_0016: nop + IL_0017: br.s IL_0020 .line 41,41 : 61,74 '' - IL_001c: ldloc.0 - IL_001d: callvirt instance string [Utils]Utils/Product::get_ProductName() + IL_0019: ldloc.0 + IL_001a: callvirt instance string [Utils]Utils/Product::get_ProductName() .line 100001,100001 : 0,0 '' - IL_0022: nop + IL_001f: nop .line 100001,100001 : 0,0 '' - IL_0023: stloc.1 + IL_0020: stloc.1 .line 42,42 : 9,22 '' - IL_0024: ldarg.0 - IL_0025: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@40-4'::builder@ - IL_002a: ldarg.0 - IL_002b: ldfld string Linq101Joins01/'q4@40-4'::c - IL_0030: ldarg.0 - IL_0031: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'q4@40-4'::ps - IL_0036: ldloc.0 - IL_0037: ldloc.1 - IL_0038: newobj instance void class [mscorlib]System.Tuple`4,class [Utils]Utils/Product,string>::.ctor(!0, + IL_0021: ldarg.0 + IL_0022: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@40-4'::builder@ + IL_0027: ldarg.0 + IL_0028: ldfld string Linq101Joins01/'Pipe #4 input at line 37@40-4'::c + IL_002d: ldarg.0 + IL_002e: ldfld class [mscorlib]System.Collections.Generic.IEnumerable`1 Linq101Joins01/'Pipe #4 input at line 37@40-4'::ps + IL_0033: ldloc.0 + IL_0034: ldloc.1 + IL_0035: newobj instance void class [mscorlib]System.Tuple`4,class [Utils]Utils/Product,string>::.ctor(!0, !1, !2, !3) - IL_003d: tail. - IL_003f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,class [Utils]Utils/Product,string>,object>(!!0) - IL_0044: ret - } // end of method 'q4@40-4'::Invoke + IL_003a: tail. + IL_003c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,class [Utils]Utils/Product,string>,object>(!!0) + IL_0041: ret + } // end of method 'Pipe #4 input at line 37@40-4'::Invoke - } // end of class 'q4@40-4' + } // end of class 'Pipe #4 input at line 37@40-4' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q4@39-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@39-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -860,9 +1023,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@39-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@39-3'::builder@ IL_000d: ret - } // end of method 'q4@39-3'::.ctor + } // end of method 'Pipe #4 input at line 37@39-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable> Invoke(class [mscorlib]System.Tuple`2> _arg1) cil managed @@ -882,30 +1045,31 @@ IL_000a: call instance !0 class [mscorlib]System.Tuple`2>::get_Item1() IL_000f: stloc.2 IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@39-3'::builder@ + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@39-3'::builder@ IL_0016: ldarg.0 - IL_0017: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@39-3'::builder@ + IL_0017: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@39-3'::builder@ IL_001c: ldloc.1 IL_001d: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [System.Core]System.Linq.Enumerable::DefaultIfEmpty(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0022: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0027: ldarg.0 - IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'q4@39-3'::builder@ + IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Joins01/'Pipe #4 input at line 37@39-3'::builder@ IL_002d: ldloc.1 IL_002e: ldloc.2 - IL_002f: newobj instance void Linq101Joins01/'q4@40-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [mscorlib]System.Collections.Generic.IEnumerable`1, - string) + IL_002f: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@40-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [mscorlib]System.Collections.Generic.IEnumerable`1, + string) IL_0034: tail. IL_0036: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [Utils]Utils/Product,string>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_003b: ret - } // end of method 'q4@39-3'::Invoke + } // end of method 'Pipe #4 input at line 37@39-3'::Invoke - } // end of class 'q4@39-3' + } // end of class 'Pipe #4 input at line 37@39-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'q4@42-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 37@42-5' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product,string>,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Joins01/'Pipe #4 input at line 37@42-5' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -916,7 +1080,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [Utils]Utils/Product,string>,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'q4@42-5'::.ctor + } // end of method 'Pipe #4 input at line 37@42-5'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`4,class [Utils]Utils/Product,string> tupledArg) cil managed @@ -946,16 +1110,26 @@ IL_001e: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0023: ret - } // end of method 'q4@42-5'::Invoke + } // end of method 'Pipe #4 input at line 37@42-5'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@42-5'::.ctor() + IL_0005: stsfld class Linq101Joins01/'Pipe #4 input at line 37@42-5' Linq101Joins01/'Pipe #4 input at line 37@42-5'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 37@42-5'::.cctor - } // end of class 'q4@42-5' + } // end of class 'Pipe #4 input at line 37@42-5' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_categories() cil managed { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::'categories@8-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::categories@8 IL_0005: ret } // end of method Linq101Joins01::get_categories @@ -964,7 +1138,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::'products@9-6' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::products@9 IL_0005: ret } // end of method Linq101Joins01::get_products @@ -1045,9 +1219,9 @@ .class private abstract auto ansi sealed ''.$Linq101Joins01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'categories@8-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 categories@8 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@9-6' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@9 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] q@11 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1064,7 +1238,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 461 (0x1cd) + // Code size 481 (0x1e1) .maxstack 10 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 categories, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products, @@ -1072,10 +1246,14 @@ [3] class [mscorlib]System.Tuple`2>[] q2, [4] class [mscorlib]System.Tuple`2[] q3, [5] class [mscorlib]System.Tuple`2[] q4, - [6] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_6, + [6] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #1 input at line 12', [7] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_7, - [8] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_8, - [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9) + [8] class [mscorlib]System.Collections.Generic.IEnumerable`1>> 'Pipe #2 input at line 20', + [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, + [10] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #3 input at line 28', + [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, + [12] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #4 input at line 37', + [13] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_13) .line 8,8 : 1,88 '' IL_0000: ldstr "Beverages" IL_0005: ldstr "Condiments" @@ -1094,142 +1272,162 @@ IL_0032: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0037: dup - IL_0038: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::'categories@8-2' + IL_0038: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::categories@8 IL_003d: stloc.0 .line 9,9 : 1,32 '' IL_003e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() IL_0043: dup - IL_0044: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::'products@9-6' + IL_0044: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Joins01::products@9 IL_0049: stloc.1 .line 11,16 : 1,21 '' - IL_004a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_004f: stloc.s V_6 - IL_0051: ldloc.s V_6 - IL_0053: ldloc.s V_6 - IL_0055: ldloc.s V_6 - IL_0057: ldloc.s V_6 - IL_0059: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() - IL_005e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0063: ldloc.s V_6 - IL_0065: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() - IL_006a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_006f: newobj instance void Linq101Joins01/q@14::.ctor() - IL_0074: newobj instance void Linq101Joins01/'q@14-1'::.ctor() - IL_0079: newobj instance void Linq101Joins01/'q@14-2'::.ctor() - IL_007e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Join>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_004a: nop + .line 12,12 : 5,10 '' + IL_004b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0050: stloc.s V_7 + IL_0052: ldloc.s V_7 + IL_0054: ldloc.s V_7 + IL_0056: ldloc.s V_7 + IL_0058: ldloc.s V_7 + IL_005a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() + IL_005f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0064: ldloc.s V_7 + IL_0066: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() + IL_006b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0070: ldsfld class Linq101Joins01/'Pipe #1 input at line 12@14' Linq101Joins01/'Pipe #1 input at line 12@14'::@_instance + IL_0075: ldsfld class Linq101Joins01/'Pipe #1 input at line 12@14-1' Linq101Joins01/'Pipe #1 input at line 12@14-1'::@_instance + IL_007a: ldsfld class Linq101Joins01/'Pipe #1 input at line 12@14-2' Linq101Joins01/'Pipe #1 input at line 12@14-2'::@_instance + IL_007f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Join>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0083: ldloc.s V_6 - IL_0085: newobj instance void Linq101Joins01/'q@14-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_008a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0084: ldloc.s V_7 + IL_0086: newobj instance void Linq101Joins01/'Pipe #1 input at line 12@14-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_008b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_008f: newobj instance void Linq101Joins01/'q@15-4'::.ctor() - IL_0094: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0090: ldsfld class Linq101Joins01/'Pipe #1 input at line 12@15-4' Linq101Joins01/'Pipe #1 input at line 12@15-4'::@_instance + IL_0095: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0099: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_009e: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00a3: dup - IL_00a4: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q@11 - IL_00a9: stloc.2 + IL_009a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_009f: stloc.s 'Pipe #1 input at line 12' + .line 16,16 : 10,21 '' + IL_00a1: ldloc.s 'Pipe #1 input at line 12' + IL_00a3: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00a8: dup + IL_00a9: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q@11 + IL_00ae: stloc.2 .line 19,24 : 1,21 '' - IL_00aa: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00af: stloc.s V_7 - IL_00b1: ldloc.s V_7 - IL_00b3: ldloc.s V_7 - IL_00b5: ldloc.s V_7 - IL_00b7: ldloc.s V_7 - IL_00b9: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() - IL_00be: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00c3: ldloc.s V_7 - IL_00c5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() - IL_00ca: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00cf: newobj instance void Linq101Joins01/q2@22::.ctor() - IL_00d4: newobj instance void Linq101Joins01/'q2@22-1'::.ctor() - IL_00d9: newobj instance void Linq101Joins01/'q2@22-2'::.ctor() - IL_00de: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00af: nop + .line 20,20 : 5,10 '' + IL_00b0: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00b5: stloc.s V_9 + IL_00b7: ldloc.s V_9 + IL_00b9: ldloc.s V_9 + IL_00bb: ldloc.s V_9 + IL_00bd: ldloc.s V_9 + IL_00bf: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() + IL_00c4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00c9: ldloc.s V_9 + IL_00cb: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() + IL_00d0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00d5: ldsfld class Linq101Joins01/'Pipe #2 input at line 20@22' Linq101Joins01/'Pipe #2 input at line 20@22'::@_instance + IL_00da: ldsfld class Linq101Joins01/'Pipe #2 input at line 20@22-1' Linq101Joins01/'Pipe #2 input at line 20@22-1'::@_instance + IL_00df: ldsfld class Linq101Joins01/'Pipe #2 input at line 20@22-2' Linq101Joins01/'Pipe #2 input at line 20@22-2'::@_instance + IL_00e4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!4>>) - IL_00e3: ldloc.s V_7 - IL_00e5: newobj instance void Linq101Joins01/'q2@22-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00ea: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00e9: ldloc.s V_9 + IL_00eb: newobj instance void Linq101Joins01/'Pipe #2 input at line 20@22-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00f0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00ef: newobj instance void Linq101Joins01/'q2@23-4'::.ctor() - IL_00f4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00f5: ldsfld class Linq101Joins01/'Pipe #2 input at line 20@23-4' Linq101Joins01/'Pipe #2 input at line 20@23-4'::@_instance + IL_00fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00f9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_00fe: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0103: dup - IL_0104: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Joins01::q2@19 - IL_0109: stloc.3 + IL_00ff: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0104: stloc.s 'Pipe #2 input at line 20' + .line 24,24 : 10,21 '' + IL_0106: ldloc.s 'Pipe #2 input at line 20' + IL_0108: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_010d: dup + IL_010e: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Joins01::q2@19 + IL_0113: stloc.3 .line 27,33 : 1,21 '' - IL_010a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_010f: stloc.s V_8 - IL_0111: ldloc.s V_8 - IL_0113: ldloc.s V_8 - IL_0115: ldloc.s V_8 - IL_0117: ldloc.s V_8 - IL_0119: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() - IL_011e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0123: ldloc.s V_8 - IL_0125: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() - IL_012a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_012f: newobj instance void Linq101Joins01/q3@30::.ctor() - IL_0134: newobj instance void Linq101Joins01/'q3@30-1'::.ctor() - IL_0139: newobj instance void Linq101Joins01/'q3@30-2'::.ctor() - IL_013e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0114: nop + .line 28,28 : 5,10 '' + IL_0115: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_011a: stloc.s V_11 + IL_011c: ldloc.s V_11 + IL_011e: ldloc.s V_11 + IL_0120: ldloc.s V_11 + IL_0122: ldloc.s V_11 + IL_0124: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() + IL_0129: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_012e: ldloc.s V_11 + IL_0130: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() + IL_0135: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_013a: ldsfld class Linq101Joins01/'Pipe #3 input at line 28@30' Linq101Joins01/'Pipe #3 input at line 28@30'::@_instance + IL_013f: ldsfld class Linq101Joins01/'Pipe #3 input at line 28@30-1' Linq101Joins01/'Pipe #3 input at line 28@30-1'::@_instance + IL_0144: ldsfld class Linq101Joins01/'Pipe #3 input at line 28@30-2' Linq101Joins01/'Pipe #3 input at line 28@30-2'::@_instance + IL_0149: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!4>>) - IL_0143: ldloc.s V_8 - IL_0145: newobj instance void Linq101Joins01/'q3@30-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_014a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_014e: ldloc.s V_11 + IL_0150: newobj instance void Linq101Joins01/'Pipe #3 input at line 28@30-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0155: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_014f: newobj instance void Linq101Joins01/'q3@32-5'::.ctor() - IL_0154: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_015a: ldsfld class Linq101Joins01/'Pipe #3 input at line 28@32-5' Linq101Joins01/'Pipe #3 input at line 28@32-5'::@_instance + IL_015f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [Utils]Utils/Product>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0159: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_015e: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0163: dup - IL_0164: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q3@27 - IL_0169: stloc.s q3 + IL_0164: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0169: stloc.s 'Pipe #3 input at line 28' + .line 33,33 : 10,21 '' + IL_016b: ldloc.s 'Pipe #3 input at line 28' + IL_016d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0172: dup + IL_0173: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q3@27 + IL_0178: stloc.s q3 .line 36,43 : 1,21 '' - IL_016b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0170: stloc.s V_9 - IL_0172: ldloc.s V_9 - IL_0174: ldloc.s V_9 - IL_0176: ldloc.s V_9 - IL_0178: ldloc.s V_9 - IL_017a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() - IL_017f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0184: ldloc.s V_9 - IL_0186: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() - IL_018b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0190: newobj instance void Linq101Joins01/q4@39::.ctor() - IL_0195: newobj instance void Linq101Joins01/'q4@39-1'::.ctor() - IL_019a: newobj instance void Linq101Joins01/'q4@39-2'::.ctor() - IL_019f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_017a: nop + .line 37,37 : 5,10 '' + IL_017b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0180: stloc.s V_13 + IL_0182: ldloc.s V_13 + IL_0184: ldloc.s V_13 + IL_0186: ldloc.s V_13 + IL_0188: ldloc.s V_13 + IL_018a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_categories() + IL_018f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0194: ldloc.s V_13 + IL_0196: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Joins01::get_products() + IL_019b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01a0: ldsfld class Linq101Joins01/'Pipe #4 input at line 37@39' Linq101Joins01/'Pipe #4 input at line 37@39'::@_instance + IL_01a5: ldsfld class Linq101Joins01/'Pipe #4 input at line 37@39-1' Linq101Joins01/'Pipe #4 input at line 37@39-1'::@_instance + IL_01aa: ldsfld class Linq101Joins01/'Pipe #4 input at line 37@39-2' Linq101Joins01/'Pipe #4 input at line 37@39-2'::@_instance + IL_01af: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupJoin>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!4>>) - IL_01a4: ldloc.s V_9 - IL_01a6: newobj instance void Linq101Joins01/'q4@39-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_01ab: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`4,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01b4: ldloc.s V_13 + IL_01b6: newobj instance void Linq101Joins01/'Pipe #4 input at line 37@39-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01bb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`4,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_01b0: newobj instance void Linq101Joins01/'q4@42-5'::.ctor() - IL_01b5: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01c0: ldsfld class Linq101Joins01/'Pipe #4 input at line 37@42-5' Linq101Joins01/'Pipe #4 input at line 37@42-5'::@_instance + IL_01c5: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [Utils]Utils/Product,string>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01ba: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_01bf: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01c4: dup - IL_01c5: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q4@36 - IL_01ca: stloc.s q4 - IL_01cc: ret + IL_01ca: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_01cf: stloc.s 'Pipe #4 input at line 37' + .line 43,43 : 10,21 '' + IL_01d1: ldloc.s 'Pipe #4 input at line 37' + IL_01d3: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01d8: dup + IL_01d9: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Joins01::q4@36 + IL_01de: stloc.s q4 + IL_01e0: ret } // end of method $Linq101Joins01::main@ } // end of class ''.$Linq101Joins01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Ordering01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Ordering01.il.bsl index 79848765473..e20407700d3 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Ordering01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Ordering01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { @@ -33,20 +33,20 @@ } .mresource public FSharpSignatureData.Linq101Ordering01 { - // Offset: 0x00000000 Length: 0x000003BA + // Offset: 0x00000000 Length: 0x000003AE } .mresource public FSharpOptimizationData.Linq101Ordering01 { - // Offset: 0x000003C0 Length: 0x00000134 + // Offset: 0x000003B8 Length: 0x00000134 } .module Linq101Ordering01.exe -// MVID: {5B9A632A-649A-6956-A745-03832A639A5B} +// MVID: {611C4D82-649A-6956-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AD0000 +// Image base: 0x071E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +55,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname sortedWords@11 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 10@11' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -80,281 +80,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0009: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101Ordering01/sortedWords@11::current + IL_0010: stfld string Linq101Ordering01/'Pipe #1 input at line 10@11'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method sortedWords@11::.ctor + } // end of method 'Pipe #1 input at line 10@11'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Ordering01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Ordering01.fs' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 11,11 : 9,26 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc .line 11,11 : 9,26 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 11,11 : 9,26 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 12,12 : 9,17 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Ordering01/sortedWords@11::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Ordering01/'Pipe #1 input at line 10@11'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc .line 11,11 : 9,26 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Ordering01/sortedWords@11::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Ordering01/sortedWords@11::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method sortedWords@11::GenerateNext + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Ordering01/'Pipe #1 input at line 10@11'::current + IL_0092: ldc.i4.0 + IL_0093: ret + } // end of method 'Pipe #1 input at line 10@11'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Ordering01/sortedWords@11::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Ordering01/sortedWords@11::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords@11::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #1 input at line 10@11'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Ordering01/sortedWords@11::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Ordering01/sortedWords@11::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Ordering01/'Pipe #1 input at line 10@11'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 11,11 : 9,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 11,11 : 9,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method sortedWords@11::Close + IL_007f: ret + } // end of method 'Pipe #1 input at line 10@11'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords@11::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #1 input at line 10@11'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method sortedWords@11::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #1 input at line 10@11'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -364,9 +334,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101Ordering01/sortedWords@11::current + IL_0001: ldfld string Linq101Ordering01/'Pipe #1 input at line 10@11'::current IL_0006: ret - } // end of method sortedWords@11::get_LastGenerated + } // end of method 'Pipe #1 input at line 10@11'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -378,17 +348,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Ordering01/sortedWords@11::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101Ordering01/'Pipe #1 input at line 10@11'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method sortedWords@11::GetFreshEnumerator + } // end of method 'Pipe #1 input at line 10@11'::GetFreshEnumerator - } // end of class sortedWords@11 + } // end of class 'Pipe #1 input at line 10@11' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedWords@12-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 10@12-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #1 input at line 10@12-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -399,7 +370,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedWords@12-1'::.ctor + } // end of method 'Pipe #1 input at line 10@12-1'::.ctor .method public strict virtual instance string Invoke(string w) cil managed @@ -409,11 +380,21 @@ .line 12,12 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'sortedWords@12-1'::Invoke + } // end of method 'Pipe #1 input at line 10@12-1'::Invoke - } // end of class 'sortedWords@12-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #1 input at line 10@12-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #1 input at line 10@12-1' Linq101Ordering01/'Pipe #1 input at line 10@12-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 10@12-1'::.cctor - .class auto autochar serializable sealed nested assembly beforefieldinit specialname sortedWords2@18 + } // end of class 'Pipe #1 input at line 10@12-1' + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #2 input at line 17@18' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -438,280 +419,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0009: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101Ordering01/sortedWords2@18::current + IL_0010: stfld string Linq101Ordering01/'Pipe #2 input at line 17@18'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method sortedWords2@18::.ctor + } // end of method 'Pipe #2 input at line 17@18'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 18,18 : 9,26 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc .line 18,18 : 9,26 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 18,18 : 9,26 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 19,19 : 9,26 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Ordering01/sortedWords2@18::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Ordering01/'Pipe #2 input at line 17@18'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc .line 18,18 : 9,26 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Ordering01/sortedWords2@18::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Ordering01/sortedWords2@18::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method sortedWords2@18::GenerateNext + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Ordering01/'Pipe #2 input at line 17@18'::current + IL_0092: ldc.i4.0 + IL_0093: ret + } // end of method 'Pipe #2 input at line 17@18'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Ordering01/sortedWords2@18::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Ordering01/sortedWords2@18::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedWords2@18::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #2 input at line 17@18'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Ordering01/sortedWords2@18::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Ordering01/sortedWords2@18::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Ordering01/'Pipe #2 input at line 17@18'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 18,18 : 9,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 18,18 : 9,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method sortedWords2@18::Close + IL_007f: ret + } // end of method 'Pipe #2 input at line 17@18'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedWords2@18::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #2 input at line 17@18'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method sortedWords2@18::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #2 input at line 17@18'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -721,9 +672,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101Ordering01/sortedWords2@18::current + IL_0001: ldfld string Linq101Ordering01/'Pipe #2 input at line 17@18'::current IL_0006: ret - } // end of method sortedWords2@18::get_LastGenerated + } // end of method 'Pipe #2 input at line 17@18'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -735,17 +686,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Ordering01/sortedWords2@18::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101Ordering01/'Pipe #2 input at line 17@18'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method sortedWords2@18::GetFreshEnumerator + } // end of method 'Pipe #2 input at line 17@18'::GetFreshEnumerator - } // end of class sortedWords2@18 + } // end of class 'Pipe #2 input at line 17@18' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedWords2@19-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 17@19-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #2 input at line 17@19-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -756,7 +708,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedWords2@19-1'::.ctor + } // end of method 'Pipe #2 input at line 17@19-1'::.ctor .method public strict virtual instance int32 Invoke(string w) cil managed @@ -767,11 +719,21 @@ IL_0000: ldarg.1 IL_0001: callvirt instance int32 [mscorlib]System.String::get_Length() IL_0006: ret - } // end of method 'sortedWords2@19-1'::Invoke + } // end of method 'Pipe #2 input at line 17@19-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #2 input at line 17@19-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #2 input at line 17@19-1' Linq101Ordering01/'Pipe #2 input at line 17@19-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 17@19-1'::.cctor - } // end of class 'sortedWords2@19-1' + } // end of class 'Pipe #2 input at line 17@19-1' - .class auto ansi serializable sealed nested assembly beforefieldinit sortedProducts@26 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 25@26' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -789,9 +751,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/sortedProducts@26::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/'Pipe #3 input at line 25@26'::builder@ IL_000d: ret - } // end of method sortedProducts@26::.ctor + } // end of method 'Pipe #3 input at line 25@26'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -804,18 +766,19 @@ IL_0001: stloc.0 .line 27,27 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/sortedProducts@26::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/'Pipe #3 input at line 25@26'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method sortedProducts@26::Invoke + } // end of method 'Pipe #3 input at line 25@26'::Invoke - } // end of class sortedProducts@26 + } // end of class 'Pipe #3 input at line 25@26' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts@27-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 25@27-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #3 input at line 25@27-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -826,7 +789,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts@27-1'::.ctor + } // end of method 'Pipe #3 input at line 25@27-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -838,13 +801,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_ProductName() IL_0008: ret - } // end of method 'sortedProducts@27-1'::Invoke + } // end of method 'Pipe #3 input at line 25@27-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #3 input at line 25@27-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #3 input at line 25@27-1' Linq101Ordering01/'Pipe #3 input at line 25@27-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 25@27-1'::.cctor - } // end of class 'sortedProducts@27-1' + } // end of class 'Pipe #3 input at line 25@27-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts@28-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 25@28-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #3 input at line 25@28-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -855,7 +829,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts@28-2'::.ctor + } // end of method 'Pipe #3 input at line 25@28-2'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -865,11 +839,21 @@ .line 28,28 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'sortedProducts@28-2'::Invoke + } // end of method 'Pipe #3 input at line 25@28-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #3 input at line 25@28-2'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #3 input at line 25@28-2' Linq101Ordering01/'Pipe #3 input at line 25@28-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 25@28-2'::.cctor - } // end of class 'sortedProducts@28-2' + } // end of class 'Pipe #3 input at line 25@28-2' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname sortedProducts2@44 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #4 input at line 43@44' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -894,280 +878,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0009: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld class [Utils]Utils/Product Linq101Ordering01/sortedProducts2@44::current + IL_0010: stfld class [Utils]Utils/Product Linq101Ordering01/'Pipe #4 input at line 43@44'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method sortedProducts2@44::.ctor + } // end of method 'Pipe #4 input at line 43@44'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] class [Utils]Utils/Product V_0, [1] class [Utils]Utils/Product p) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 44,44 : 9,29 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc .line 44,44 : 9,29 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 44,44 : 9,29 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 45,45 : 9,40 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld class [Utils]Utils/Product Linq101Ordering01/sortedProducts2@44::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld class [Utils]Utils/Product Linq101Ordering01/'Pipe #4 input at line 43@44'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc .line 44,44 : 9,29 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Ordering01/sortedProducts2@44::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld class [Utils]Utils/Product Linq101Ordering01/sortedProducts2@44::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method sortedProducts2@44::GenerateNext + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld class [Utils]Utils/Product Linq101Ordering01/'Pipe #4 input at line 43@44'::current + IL_0092: ldc.i4.0 + IL_0093: ret + } // end of method 'Pipe #4 input at line 43@44'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Ordering01/sortedProducts2@44::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Ordering01/sortedProducts2@44::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedProducts2@44::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #4 input at line 43@44'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Ordering01/sortedProducts2@44::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [Utils]Utils/Product Linq101Ordering01/sortedProducts2@44::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [Utils]Utils/Product Linq101Ordering01/'Pipe #4 input at line 43@44'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 44,44 : 9,29 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 44,44 : 9,29 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method sortedProducts2@44::Close + IL_007f: ret + } // end of method 'Pipe #4 input at line 43@44'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedProducts2@44::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #4 input at line 43@44'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method sortedProducts2@44::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #4 input at line 43@44'::get_CheckClose .method public strict virtual instance class [Utils]Utils/Product get_LastGenerated() cil managed @@ -1177,9 +1131,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld class [Utils]Utils/Product Linq101Ordering01/sortedProducts2@44::current + IL_0001: ldfld class [Utils]Utils/Product Linq101Ordering01/'Pipe #4 input at line 43@44'::current IL_0006: ret - } // end of method sortedProducts2@44::get_LastGenerated + } // end of method 'Pipe #4 input at line 43@44'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -1191,17 +1145,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Ordering01/sortedProducts2@44::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [Utils]Utils/Product) + IL_0003: newobj instance void Linq101Ordering01/'Pipe #4 input at line 43@44'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [Utils]Utils/Product) IL_0008: ret - } // end of method sortedProducts2@44::GetFreshEnumerator + } // end of method 'Pipe #4 input at line 43@44'::GetFreshEnumerator - } // end of class sortedProducts2@44 + } // end of class 'Pipe #4 input at line 43@44' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts2@45-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 43@45-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #4 input at line 43@45-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1212,7 +1167,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts2@45-1'::.ctor + } // end of method 'Pipe #4 input at line 43@45-1'::.ctor .method public strict virtual instance int32 Invoke(class [Utils]Utils/Product p) cil managed @@ -1224,11 +1179,21 @@ IL_0001: tail. IL_0003: callvirt instance int32 [Utils]Utils/Product::get_UnitsInStock() IL_0008: ret - } // end of method 'sortedProducts2@45-1'::Invoke + } // end of method 'Pipe #4 input at line 43@45-1'::Invoke - } // end of class 'sortedProducts2@45-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #4 input at line 43@45-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #4 input at line 43@45-1' Linq101Ordering01/'Pipe #4 input at line 43@45-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 43@45-1'::.cctor + + } // end of class 'Pipe #4 input at line 43@45-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname sortedDigits@52 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #5 input at line 51@52' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1253,280 +1218,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0009: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101Ordering01/sortedDigits@52::current + IL_0010: stfld string Linq101Ordering01/'Pipe #5 input at line 51@52'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method sortedDigits@52::.ctor + } // end of method 'Pipe #5 input at line 51@52'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string d) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 52,52 : 9,27 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_digits() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_digits() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc .line 52,52 : 9,27 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 52,52 : 9,27 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 53,53 : 9,24 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Ordering01/sortedDigits@52::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Ordering01/'Pipe #5 input at line 51@52'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc .line 52,52 : 9,27 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Ordering01/sortedDigits@52::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Ordering01/sortedDigits@52::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method sortedDigits@52::GenerateNext + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Ordering01/'Pipe #5 input at line 51@52'::current + IL_0092: ldc.i4.0 + IL_0093: ret + } // end of method 'Pipe #5 input at line 51@52'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Ordering01/sortedDigits@52::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Ordering01/sortedDigits@52::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/sortedDigits@52::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Ordering01/'Pipe #5 input at line 51@52'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Ordering01/sortedDigits@52::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Ordering01/sortedDigits@52::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Ordering01/'Pipe #5 input at line 51@52'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 52,52 : 9,27 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 52,52 : 9,27 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method sortedDigits@52::Close + IL_007f: ret + } // end of method 'Pipe #5 input at line 51@52'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Ordering01/sortedDigits@52::pc + IL_0001: ldfld int32 Linq101Ordering01/'Pipe #5 input at line 51@52'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method sortedDigits@52::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #5 input at line 51@52'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -1536,9 +1471,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101Ordering01/sortedDigits@52::current + IL_0001: ldfld string Linq101Ordering01/'Pipe #5 input at line 51@52'::current IL_0006: ret - } // end of method sortedDigits@52::get_LastGenerated + } // end of method 'Pipe #5 input at line 51@52'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -1550,17 +1485,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Ordering01/sortedDigits@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101Ordering01/'Pipe #5 input at line 51@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method sortedDigits@52::GetFreshEnumerator + } // end of method 'Pipe #5 input at line 51@52'::GetFreshEnumerator - } // end of class sortedDigits@52 + } // end of class 'Pipe #5 input at line 51@52' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedDigits@53-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 51@53-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #5 input at line 51@53-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1571,7 +1507,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedDigits@53-1'::.ctor + } // end of method 'Pipe #5 input at line 51@53-1'::.ctor .method public strict virtual instance int32 Invoke(string d) cil managed @@ -1582,13 +1518,24 @@ IL_0000: ldarg.1 IL_0001: callvirt instance int32 [mscorlib]System.String::get_Length() IL_0006: ret - } // end of method 'sortedDigits@53-1'::Invoke + } // end of method 'Pipe #5 input at line 51@53-1'::Invoke - } // end of class 'sortedDigits@53-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #5 input at line 51@53-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #5 input at line 51@53-1' Linq101Ordering01/'Pipe #5 input at line 51@53-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 51@53-1'::.cctor + + } // end of class 'Pipe #5 input at line 51@53-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedDigits@54-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 51@54-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #5 input at line 51@54-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1599,7 +1546,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedDigits@54-2'::.ctor + } // end of method 'Pipe #5 input at line 51@54-2'::.ctor .method public strict virtual instance string Invoke(string d) cil managed @@ -1609,11 +1556,21 @@ .line 54,54 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'sortedDigits@54-2'::Invoke + } // end of method 'Pipe #5 input at line 51@54-2'::Invoke - } // end of class 'sortedDigits@54-2' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #5 input at line 51@54-2'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #5 input at line 51@54-2' Linq101Ordering01/'Pipe #5 input at line 51@54-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 51@54-2'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit sortedProducts3@60 + } // end of class 'Pipe #5 input at line 51@54-2' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@60' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -1631,9 +1588,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/sortedProducts3@60::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/'Pipe #6 input at line 59@60'::builder@ IL_000d: ret - } // end of method sortedProducts3@60::.ctor + } // end of method 'Pipe #6 input at line 59@60'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -1646,18 +1603,19 @@ IL_0001: stloc.0 .line 61,61 : 9,26 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/sortedProducts3@60::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Ordering01/'Pipe #6 input at line 59@60'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method sortedProducts3@60::Invoke + } // end of method 'Pipe #6 input at line 59@60'::Invoke - } // end of class sortedProducts3@60 + } // end of class 'Pipe #6 input at line 59@60' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts3@61-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@61-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #6 input at line 59@61-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1668,7 +1626,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts3@61-1'::.ctor + } // end of method 'Pipe #6 input at line 59@61-1'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -1680,13 +1638,24 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'sortedProducts3@61-1'::Invoke + } // end of method 'Pipe #6 input at line 59@61-1'::Invoke - } // end of class 'sortedProducts3@61-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #6 input at line 59@61-1'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #6 input at line 59@61-1' Linq101Ordering01/'Pipe #6 input at line 59@61-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 59@61-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts3@62-2' + } // end of class 'Pipe #6 input at line 59@61-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@62-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #6 input at line 59@62-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1697,7 +1666,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts3@62-2'::.ctor + } // end of method 'Pipe #6 input at line 59@62-2'::.ctor .method public strict virtual instance valuetype [mscorlib]System.Decimal Invoke(class [Utils]Utils/Product p) cil managed @@ -1709,13 +1678,24 @@ IL_0001: tail. IL_0003: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() IL_0008: ret - } // end of method 'sortedProducts3@62-2'::Invoke + } // end of method 'Pipe #6 input at line 59@62-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #6 input at line 59@62-2'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #6 input at line 59@62-2' Linq101Ordering01/'Pipe #6 input at line 59@62-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 59@62-2'::.cctor - } // end of class 'sortedProducts3@62-2' + } // end of class 'Pipe #6 input at line 59@62-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'sortedProducts3@63-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@63-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Ordering01/'Pipe #6 input at line 59@63-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1726,7 +1706,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'sortedProducts3@63-3'::.ctor + } // end of method 'Pipe #6 input at line 59@63-3'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -1736,16 +1716,26 @@ .line 63,63 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'sortedProducts3@63-3'::Invoke + } // end of method 'Pipe #6 input at line 59@63-3'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Ordering01/'Pipe #6 input at line 59@63-3'::.ctor() + IL_0005: stsfld class Linq101Ordering01/'Pipe #6 input at line 59@63-3' Linq101Ordering01/'Pipe #6 input at line 59@63-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 59@63-3'::.cctor - } // end of class 'sortedProducts3@63-3' + } // end of class 'Pipe #6 input at line 59@63-3' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_words() cil managed { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'words@8-4' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::words@8 IL_0005: ret } // end of method Linq101Ordering01::get_words @@ -1772,7 +1762,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'products@23-8' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::products@23 IL_0005: ret } // end of method Linq101Ordering01::get_products @@ -1799,7 +1789,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'digits@49-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::digits@49 IL_0005: ret } // end of method Linq101Ordering01::get_digits @@ -1877,19 +1867,19 @@ .class private abstract auto ansi sealed ''.$Linq101Ordering01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'words@8-4' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words@8 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 sortedWords@9 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 sortedWords2@16 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@23-8' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@23 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [Utils]Utils/Product[] sortedProducts@24 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [Utils]Utils/Product[] sortedProducts2@42 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'digits@49-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits@49 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 sortedDigits@50 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1902,7 +1892,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 540 (0x21c) + // Code size 570 (0x23a) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 sortedWords, @@ -1913,12 +1903,18 @@ [6] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits, [7] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 sortedDigits, [8] class [Utils]Utils/Product[] sortedProducts3, - [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, + [9] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 10', [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10, - [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, + [11] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #2 input at line 17', [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12, - [13] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_13, - [14] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_14) + [13] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #3 input at line 25', + [14] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_14, + [15] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #4 input at line 43', + [16] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_16, + [17] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #5 input at line 51', + [18] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_18, + [19] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #6 input at line 59', + [20] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_20) .line 8,8 : 1,45 '' IL_0000: ldstr "cherry" IL_0005: ldstr "apple" @@ -1931,114 +1927,126 @@ IL_001e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0023: dup - IL_0024: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'words@8-4' + IL_0024: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::words@8 IL_0029: stloc.0 .line 9,13 : 1,20 '' - IL_002a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_002f: stloc.s V_9 - IL_0031: ldloc.s V_9 - IL_0033: ldnull - IL_0034: ldc.i4.0 - IL_0035: ldnull - IL_0036: newobj instance void Linq101Ordering01/sortedWords@11::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_003b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0040: newobj instance void Linq101Ordering01/'sortedWords@12-1'::.ctor() - IL_0045: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_002a: nop + .line 10,10 : 5,10 '' + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0030: stloc.s V_10 + IL_0032: ldloc.s V_10 + IL_0034: ldnull + IL_0035: ldc.i4.0 + IL_0036: ldnull + IL_0037: newobj instance void Linq101Ordering01/'Pipe #1 input at line 10@11'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_003c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0041: ldsfld class Linq101Ordering01/'Pipe #1 input at line 10@12-1' Linq101Ordering01/'Pipe #1 input at line 10@12-1'::@_instance + IL_0046: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_004a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_004f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0054: dup - IL_0055: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedWords@9 - IL_005a: stloc.1 + IL_004b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0050: stloc.s 'Pipe #1 input at line 10' + .line 13,13 : 10,20 '' + IL_0052: ldloc.s 'Pipe #1 input at line 10' + IL_0054: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0059: dup + IL_005a: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedWords@9 + IL_005f: stloc.1 .line 16,20 : 1,20 '' - IL_005b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0060: stloc.s V_10 - IL_0062: ldloc.s V_10 - IL_0064: ldnull - IL_0065: ldc.i4.0 - IL_0066: ldnull - IL_0067: newobj instance void Linq101Ordering01/sortedWords2@18::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_006c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0071: newobj instance void Linq101Ordering01/'sortedWords2@19-1'::.ctor() - IL_0076: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0060: nop + .line 17,17 : 5,10 '' + IL_0061: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0066: stloc.s V_12 + IL_0068: ldloc.s V_12 + IL_006a: ldnull + IL_006b: ldc.i4.0 + IL_006c: ldnull + IL_006d: newobj instance void Linq101Ordering01/'Pipe #2 input at line 17@18'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_0072: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0077: ldsfld class Linq101Ordering01/'Pipe #2 input at line 17@19-1' Linq101Ordering01/'Pipe #2 input at line 17@19-1'::@_instance + IL_007c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_007b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0080: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0085: dup - IL_0086: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedWords2@16 - IL_008b: stloc.2 + IL_0081: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0086: stloc.s 'Pipe #2 input at line 17' + .line 20,20 : 10,20 '' + IL_0088: ldloc.s 'Pipe #2 input at line 17' + IL_008a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_008f: dup + IL_0090: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedWords2@16 + IL_0095: stloc.2 .line 23,23 : 1,32 '' - IL_008c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_0091: dup - IL_0092: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'products@23-8' - IL_0097: stloc.3 + IL_0096: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_009b: dup + IL_009c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::products@23 + IL_00a1: stloc.3 .line 24,29 : 1,21 '' - IL_0098: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_009d: stloc.s V_11 - IL_009f: ldloc.s V_11 - IL_00a1: ldloc.s V_11 - IL_00a3: ldloc.s V_11 - IL_00a5: ldloc.s V_11 - IL_00a7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() - IL_00ac: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00b1: ldloc.s V_11 - IL_00b3: newobj instance void Linq101Ordering01/sortedProducts@26::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00b8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00a2: nop + .line 25,25 : 5,10 '' + IL_00a3: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00a8: stloc.s V_14 + IL_00aa: ldloc.s V_14 + IL_00ac: ldloc.s V_14 + IL_00ae: ldloc.s V_14 + IL_00b0: ldloc.s V_14 + IL_00b2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() + IL_00b7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00bc: ldloc.s V_14 + IL_00be: newobj instance void Linq101Ordering01/'Pipe #3 input at line 25@26'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00c3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00bd: newobj instance void Linq101Ordering01/'sortedProducts@27-1'::.ctor() - IL_00c2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00c8: ldsfld class Linq101Ordering01/'Pipe #3 input at line 25@27-1' Linq101Ordering01/'Pipe #3 input at line 25@27-1'::@_instance + IL_00cd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00c7: newobj instance void Linq101Ordering01/'sortedProducts@28-2'::.ctor() - IL_00cc: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00d2: ldsfld class Linq101Ordering01/'Pipe #3 input at line 25@28-2' Linq101Ordering01/'Pipe #3 input at line 25@28-2'::@_instance + IL_00d7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00d1: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_00d6: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00db: dup - IL_00dc: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts@24 - IL_00e1: stloc.s sortedProducts + IL_00dc: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_00e1: stloc.s 'Pipe #3 input at line 25' + .line 29,29 : 10,21 '' + IL_00e3: ldloc.s 'Pipe #3 input at line 25' + IL_00e5: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00ea: dup + IL_00eb: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts@24 + IL_00f0: stloc.s sortedProducts .line 42,46 : 1,21 '' - IL_00e3: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00e8: stloc.s V_12 - IL_00ea: ldloc.s V_12 - IL_00ec: ldnull - IL_00ed: ldc.i4.0 - IL_00ee: ldnull - IL_00ef: newobj instance void Linq101Ordering01/sortedProducts2@44::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [Utils]Utils/Product) - IL_00f4: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00f9: newobj instance void Linq101Ordering01/'sortedProducts2@45-1'::.ctor() - IL_00fe: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortByDescending(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00f2: nop + .line 43,43 : 5,10 '' + IL_00f3: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00f8: stloc.s V_16 + IL_00fa: ldloc.s V_16 + IL_00fc: ldnull + IL_00fd: ldc.i4.0 + IL_00fe: ldnull + IL_00ff: newobj instance void Linq101Ordering01/'Pipe #4 input at line 43@44'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [Utils]Utils/Product) + IL_0104: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0109: ldsfld class Linq101Ordering01/'Pipe #4 input at line 43@45-1' Linq101Ordering01/'Pipe #4 input at line 43@45-1'::@_instance + IL_010e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortByDescending(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0103: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0108: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_010d: dup - IL_010e: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts2@42 - IL_0113: stloc.s sortedProducts2 + IL_0113: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0118: stloc.s 'Pipe #4 input at line 43' + .line 46,46 : 10,21 '' + IL_011a: ldloc.s 'Pipe #4 input at line 43' + IL_011c: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0121: dup + IL_0122: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts2@42 + IL_0127: stloc.s sortedProducts2 .line 49,49 : 1,96 '' - IL_0115: ldstr "zero" - IL_011a: ldstr "one" - IL_011f: ldstr "two" - IL_0124: ldstr "three" - IL_0129: ldstr "four" - IL_012e: ldstr "five" - IL_0133: ldstr "six" - IL_0138: ldstr "seven" - IL_013d: ldstr "eight" - IL_0142: ldstr "nine" - IL_0147: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_014c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0151: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0156: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_015b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0129: ldstr "zero" + IL_012e: ldstr "one" + IL_0133: ldstr "two" + IL_0138: ldstr "three" + IL_013d: ldstr "four" + IL_0142: ldstr "five" + IL_0147: ldstr "six" + IL_014c: ldstr "seven" + IL_0151: ldstr "eight" + IL_0156: ldstr "nine" + IL_015b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_0160: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0165: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -2051,61 +2059,79 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0179: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_017e: dup - IL_017f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::'digits@49-2' - IL_0184: stloc.s digits + IL_017e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0183: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0188: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_018d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0192: dup + IL_0193: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::digits@49 + IL_0198: stloc.s digits .line 50,55 : 1,20 '' - IL_0186: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_018b: stloc.s V_13 - IL_018d: ldloc.s V_13 - IL_018f: ldloc.s V_13 - IL_0191: ldnull - IL_0192: ldc.i4.0 - IL_0193: ldnull - IL_0194: newobj instance void Linq101Ordering01/sortedDigits@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_0199: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_019e: newobj instance void Linq101Ordering01/'sortedDigits@53-1'::.ctor() - IL_01a3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_019a: nop + .line 51,51 : 5,10 '' + IL_019b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01a0: stloc.s V_18 + IL_01a2: ldloc.s V_18 + IL_01a4: ldloc.s V_18 + IL_01a6: ldnull + IL_01a7: ldc.i4.0 + IL_01a8: ldnull + IL_01a9: newobj instance void Linq101Ordering01/'Pipe #5 input at line 51@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_01ae: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01b3: ldsfld class Linq101Ordering01/'Pipe #5 input at line 51@53-1' Linq101Ordering01/'Pipe #5 input at line 51@53-1'::@_instance + IL_01b8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01a8: newobj instance void Linq101Ordering01/'sortedDigits@54-2'::.ctor() - IL_01ad: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::ThenBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01bd: ldsfld class Linq101Ordering01/'Pipe #5 input at line 51@54-2' Linq101Ordering01/'Pipe #5 input at line 51@54-2'::@_instance + IL_01c2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::ThenBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01b2: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_01b7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01bc: dup - IL_01bd: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedDigits@50 - IL_01c2: stloc.s sortedDigits + IL_01c7: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_01cc: stloc.s 'Pipe #5 input at line 51' + .line 55,55 : 10,20 '' + IL_01ce: ldloc.s 'Pipe #5 input at line 51' + IL_01d0: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01d5: dup + IL_01d6: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Ordering01::sortedDigits@50 + IL_01db: stloc.s sortedDigits .line 58,64 : 1,21 '' - IL_01c4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_01c9: stloc.s V_14 - IL_01cb: ldloc.s V_14 - IL_01cd: ldloc.s V_14 - IL_01cf: ldloc.s V_14 - IL_01d1: ldloc.s V_14 - IL_01d3: ldloc.s V_14 - IL_01d5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() - IL_01da: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01df: ldloc.s V_14 - IL_01e1: newobj instance void Linq101Ordering01/sortedProducts3@60::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_01e6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01dd: nop + .line 59,59 : 5,10 '' + IL_01de: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01e3: stloc.s V_20 + IL_01e5: ldloc.s V_20 + IL_01e7: ldloc.s V_20 + IL_01e9: ldloc.s V_20 + IL_01eb: ldloc.s V_20 + IL_01ed: ldloc.s V_20 + IL_01ef: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Ordering01::get_products() + IL_01f4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01f9: ldloc.s V_20 + IL_01fb: newobj instance void Linq101Ordering01/'Pipe #6 input at line 59@60'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0200: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_01eb: newobj instance void Linq101Ordering01/'sortedProducts3@61-1'::.ctor() - IL_01f0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0205: ldsfld class Linq101Ordering01/'Pipe #6 input at line 59@61-1' Linq101Ordering01/'Pipe #6 input at line 59@61-1'::@_instance + IL_020a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SortBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01f5: newobj instance void Linq101Ordering01/'sortedProducts3@62-2'::.ctor() - IL_01fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::ThenByDescending(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_020f: ldsfld class Linq101Ordering01/'Pipe #6 input at line 59@62-2' Linq101Ordering01/'Pipe #6 input at line 59@62-2'::@_instance + IL_0214: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::ThenByDescending(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01ff: newobj instance void Linq101Ordering01/'sortedProducts3@63-3'::.ctor() - IL_0204: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0219: ldsfld class Linq101Ordering01/'Pipe #6 input at line 59@63-3' Linq101Ordering01/'Pipe #6 input at line 59@63-3'::@_instance + IL_021e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0209: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_020e: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0213: dup - IL_0214: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts3@58 - IL_0219: stloc.s sortedProducts3 - IL_021b: ret + IL_0223: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0228: stloc.s 'Pipe #6 input at line 59' + .line 64,64 : 10,21 '' + IL_022a: ldloc.s 'Pipe #6 input at line 59' + IL_022c: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0231: dup + IL_0232: stsfld class [Utils]Utils/Product[] ''.$Linq101Ordering01::sortedProducts3@58 + IL_0237: stloc.s sortedProducts3 + IL_0239: ret } // end of method $Linq101Ordering01::main@ } // end of class ''.$Linq101Ordering01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Partitioning01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Partitioning01.il.bsl index b210d7f3c90..365fa72d873 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Partitioning01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Partitioning01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,17 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101Partitioning01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -33,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Partitioning01 { - // Offset: 0x00000000 Length: 0x000003DE + // Offset: 0x00000000 Length: 0x000003D2 } .mresource public FSharpOptimizationData.Linq101Partitioning01 { - // Offset: 0x000003E8 Length: 0x00000138 + // Offset: 0x000003D8 Length: 0x00000138 } .module Linq101Partitioning01.exe -// MVID: {5B9A632A-B280-A6A2-A745-03832A639A5B} +// MVID: {611C4D82-B280-A6A2-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AF0000 +// Image base: 0x06570000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +60,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname first3Numbers@12 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 11@12' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -80,281 +85,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0009: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Partitioning01/first3Numbers@12::current + IL_0010: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method first3Numbers@12::.ctor + } // end of method 'Pipe #1 input at line 11@12'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Partitioning01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Partitioning01.fs' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 12,12 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc .line 12,12 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 12,12 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 13,13 : 9,15 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Partitioning01/first3Numbers@12::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc .line 12,12 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Partitioning01/first3Numbers@12::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Partitioning01/first3Numbers@12::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method first3Numbers@12::GenerateNext + IL_0093: ret + } // end of method 'Pipe #1 input at line 11@12'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Partitioning01/first3Numbers@12::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Partitioning01/first3Numbers@12::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/first3Numbers@12::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #1 input at line 11@12'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Partitioning01/first3Numbers@12::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Partitioning01/first3Numbers@12::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 12,12 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 12,12 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method first3Numbers@12::Close + IL_007f: ret + } // end of method 'Pipe #1 input at line 11@12'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/first3Numbers@12::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method first3Numbers@12::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #1 input at line 11@12'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -364,9 +339,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/first3Numbers@12::current + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #1 input at line 11@12'::current IL_0006: ret - } // end of method first3Numbers@12::get_LastGenerated + } // end of method 'Pipe #1 input at line 11@12'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -378,15 +353,15 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Partitioning01/first3Numbers@12::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Partitioning01/'Pipe #1 input at line 11@12'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method first3Numbers@12::GetFreshEnumerator + } // end of method 'Pipe #1 input at line 11@12'::GetFreshEnumerator - } // end of class first3Numbers@12 + } // end of class 'Pipe #1 input at line 11@12' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders@21-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 19@21-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -406,12 +381,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'WAOrders@21-1'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@21-1'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [Utils]Utils/Customer Linq101Partitioning01/'WAOrders@21-1'::c + IL_000f: stfld class [Utils]Utils/Customer Linq101Partitioning01/'Pipe #2 input at line 19@21-1'::c IL_0014: ret - } // end of method 'WAOrders@21-1'::.ctor + } // end of method 'Pipe #2 input at line 19@21-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [Utils]Utils/Order _arg2) cil managed @@ -424,20 +399,20 @@ IL_0001: stloc.0 .line 22,22 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'WAOrders@21-1'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@21-1'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [Utils]Utils/Customer Linq101Partitioning01/'WAOrders@21-1'::c + IL_0009: ldfld class [Utils]Utils/Customer Linq101Partitioning01/'Pipe #2 input at line 19@21-1'::c IL_000e: ldloc.0 IL_000f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0014: tail. IL_0016: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_001b: ret - } // end of method 'WAOrders@21-1'::Invoke + } // end of method 'Pipe #2 input at line 19@21-1'::Invoke - } // end of class 'WAOrders@21-1' + } // end of class 'Pipe #2 input at line 19@21-1' - .class auto ansi serializable sealed nested assembly beforefieldinit WAOrders@20 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 19@20' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -455,9 +430,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders@20::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@20'::builder@ IL_000d: ret - } // end of method WAOrders@20::.ctor + } // end of method 'Pipe #2 input at line 19@20'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -470,28 +445,29 @@ IL_0001: stloc.0 .line 21,21 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders@20::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@20'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders@20::builder@ + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@20'::builder@ IL_000e: ldloc.0 IL_000f: callvirt instance class [Utils]Utils/Order[] [Utils]Utils/Customer::get_Orders() IL_0014: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0019: ldarg.0 - IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders@20::builder@ + IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #2 input at line 19@20'::builder@ IL_001f: ldloc.0 - IL_0020: newobj instance void Linq101Partitioning01/'WAOrders@21-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [Utils]Utils/Customer) + IL_0020: newobj instance void Linq101Partitioning01/'Pipe #2 input at line 19@21-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [Utils]Utils/Customer) IL_0025: tail. IL_0027: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_002c: ret - } // end of method WAOrders@20::Invoke + } // end of method 'Pipe #2 input at line 19@20'::Invoke - } // end of class WAOrders@20 + } // end of class 'Pipe #2 input at line 19@20' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders@22-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 19@22-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Partitioning01/'Pipe #2 input at line 19@22-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -502,7 +478,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'WAOrders@22-2'::.ctor + } // end of method 'Pipe #2 input at line 19@22-2'::.ctor .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -522,16 +498,27 @@ IL_000e: ldloc.0 IL_000f: callvirt instance string [Utils]Utils/Customer::get_Region() IL_0014: ldstr "WA" - IL_0019: call bool [mscorlib]System.String::Equals(string, - string) + IL_0019: call bool [netstandard]System.String::Equals(string, + string) IL_001e: ret - } // end of method 'WAOrders@22-2'::Invoke + } // end of method 'Pipe #2 input at line 19@22-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #2 input at line 19@22-2'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #2 input at line 19@22-2' Linq101Partitioning01/'Pipe #2 input at line 19@22-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 19@22-2'::.cctor - } // end of class 'WAOrders@22-2' + } // end of class 'Pipe #2 input at line 19@22-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders@23-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 19@23-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> { + .field static assembly initonly class Linq101Partitioning01/'Pipe #2 input at line 19@23-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -542,7 +529,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() IL_0006: ret - } // end of method 'WAOrders@23-3'::.ctor + } // end of method 'Pipe #2 input at line 19@23-3'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`3 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -569,11 +556,21 @@ !1, !2) IL_0025: ret - } // end of method 'WAOrders@23-3'::Invoke + } // end of method 'Pipe #2 input at line 19@23-3'::Invoke - } // end of class 'WAOrders@23-3' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #2 input at line 19@23-3'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #2 input at line 19@23-3' Linq101Partitioning01/'Pipe #2 input at line 19@23-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 19@23-3'::.cctor + + } // end of class 'Pipe #2 input at line 19@23-3' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname allButFirst4Numbers@29 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #3 input at line 28@29' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -598,280 +595,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0009: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::current + IL_0010: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method allButFirst4Numbers@29::.ctor + } // end of method 'Pipe #3 input at line 28@29'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 29,29 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc .line 29,29 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 29,29 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 30,30 : 9,15 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc .line 29,29 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method allButFirst4Numbers@29::GenerateNext + IL_0093: ret + } // end of method 'Pipe #3 input at line 28@29'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst4Numbers@29::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #3 input at line 28@29'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Partitioning01/allButFirst4Numbers@29::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 29,29 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 29,29 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method allButFirst4Numbers@29::Close + IL_007f: ret + } // end of method 'Pipe #3 input at line 28@29'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst4Numbers@29::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method allButFirst4Numbers@29::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #3 input at line 28@29'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -881,9 +848,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst4Numbers@29::current + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #3 input at line 28@29'::current IL_0006: ret - } // end of method allButFirst4Numbers@29::get_LastGenerated + } // end of method 'Pipe #3 input at line 28@29'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -895,15 +862,15 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Partitioning01/allButFirst4Numbers@29::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Partitioning01/'Pipe #3 input at line 28@29'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method allButFirst4Numbers@29::GetFreshEnumerator + } // end of method 'Pipe #3 input at line 28@29'::GetFreshEnumerator - } // end of class allButFirst4Numbers@29 + } // end of class 'Pipe #3 input at line 28@29' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders2@37-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 35@37-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -923,12 +890,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'WAOrders2@37-1'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@37-1'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [Utils]Utils/Customer Linq101Partitioning01/'WAOrders2@37-1'::c + IL_000f: stfld class [Utils]Utils/Customer Linq101Partitioning01/'Pipe #4 input at line 35@37-1'::c IL_0014: ret - } // end of method 'WAOrders2@37-1'::.ctor + } // end of method 'Pipe #4 input at line 35@37-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [Utils]Utils/Order _arg2) cil managed @@ -941,20 +908,20 @@ IL_0001: stloc.0 .line 38,38 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'WAOrders2@37-1'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@37-1'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [Utils]Utils/Customer Linq101Partitioning01/'WAOrders2@37-1'::c + IL_0009: ldfld class [Utils]Utils/Customer Linq101Partitioning01/'Pipe #4 input at line 35@37-1'::c IL_000e: ldloc.0 IL_000f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0014: tail. IL_0016: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_001b: ret - } // end of method 'WAOrders2@37-1'::Invoke + } // end of method 'Pipe #4 input at line 35@37-1'::Invoke - } // end of class 'WAOrders2@37-1' + } // end of class 'Pipe #4 input at line 35@37-1' - .class auto ansi serializable sealed nested assembly beforefieldinit WAOrders2@36 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 35@36' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -972,9 +939,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders2@36::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@36'::builder@ IL_000d: ret - } // end of method WAOrders2@36::.ctor + } // end of method 'Pipe #4 input at line 35@36'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -987,28 +954,29 @@ IL_0001: stloc.0 .line 37,37 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders2@36::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@36'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders2@36::builder@ + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@36'::builder@ IL_000e: ldloc.0 IL_000f: callvirt instance class [Utils]Utils/Order[] [Utils]Utils/Customer::get_Orders() IL_0014: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0019: ldarg.0 - IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/WAOrders2@36::builder@ + IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Partitioning01/'Pipe #4 input at line 35@36'::builder@ IL_001f: ldloc.0 - IL_0020: newobj instance void Linq101Partitioning01/'WAOrders2@37-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [Utils]Utils/Customer) + IL_0020: newobj instance void Linq101Partitioning01/'Pipe #4 input at line 35@37-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [Utils]Utils/Customer) IL_0025: tail. IL_0027: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_002c: ret - } // end of method WAOrders2@36::Invoke + } // end of method 'Pipe #4 input at line 35@36'::Invoke - } // end of class WAOrders2@36 + } // end of class 'Pipe #4 input at line 35@36' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders2@38-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 35@38-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Partitioning01/'Pipe #4 input at line 35@38-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1019,7 +987,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'WAOrders2@38-2'::.ctor + } // end of method 'Pipe #4 input at line 35@38-2'::.ctor .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -1039,16 +1007,27 @@ IL_000e: ldloc.0 IL_000f: callvirt instance string [Utils]Utils/Customer::get_Region() IL_0014: ldstr "WA" - IL_0019: call bool [mscorlib]System.String::Equals(string, - string) + IL_0019: call bool [netstandard]System.String::Equals(string, + string) IL_001e: ret - } // end of method 'WAOrders2@38-2'::Invoke + } // end of method 'Pipe #4 input at line 35@38-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #4 input at line 35@38-2'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #4 input at line 35@38-2' Linq101Partitioning01/'Pipe #4 input at line 35@38-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 35@38-2'::.cctor - } // end of class 'WAOrders2@38-2' + } // end of class 'Pipe #4 input at line 35@38-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'WAOrders2@39-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 35@39-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> { + .field static assembly initonly class Linq101Partitioning01/'Pipe #4 input at line 35@39-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1059,7 +1038,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() IL_0006: ret - } // end of method 'WAOrders2@39-3'::.ctor + } // end of method 'Pipe #4 input at line 35@39-3'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`3 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -1086,11 +1065,21 @@ !1, !2) IL_0025: ret - } // end of method 'WAOrders2@39-3'::Invoke + } // end of method 'Pipe #4 input at line 35@39-3'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #4 input at line 35@39-3'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #4 input at line 35@39-3' Linq101Partitioning01/'Pipe #4 input at line 35@39-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 35@39-3'::.cctor - } // end of class 'WAOrders2@39-3' + } // end of class 'Pipe #4 input at line 35@39-3' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstNumbersLessThan6@45 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #5 input at line 44@45' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1115,280 +1104,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0009: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::current + IL_0010: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method firstNumbersLessThan6@45::.ctor + } // end of method 'Pipe #5 input at line 44@45'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 45,45 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc .line 45,45 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 45,45 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 46,46 : 9,26 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc .line 45,45 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method firstNumbersLessThan6@45::GenerateNext + IL_0093: ret + } // end of method 'Pipe #5 input at line 44@45'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/firstNumbersLessThan6@45::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #5 input at line 44@45'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 45,45 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 45,45 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method firstNumbersLessThan6@45::Close + IL_007f: ret + } // end of method 'Pipe #5 input at line 44@45'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method firstNumbersLessThan6@45::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #5 input at line 44@45'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -1398,9 +1357,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/firstNumbersLessThan6@45::current + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #5 input at line 44@45'::current IL_0006: ret - } // end of method firstNumbersLessThan6@45::get_LastGenerated + } // end of method 'Pipe #5 input at line 44@45'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -1412,17 +1371,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Partitioning01/firstNumbersLessThan6@45::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Partitioning01/'Pipe #5 input at line 44@45'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method firstNumbersLessThan6@45::GetFreshEnumerator + } // end of method 'Pipe #5 input at line 44@45'::GetFreshEnumerator - } // end of class firstNumbersLessThan6@45 + } // end of class 'Pipe #5 input at line 44@45' - .class auto ansi serializable sealed nested assembly beforefieldinit 'firstNumbersLessThan6@46-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 44@46-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Partitioning01/'Pipe #5 input at line 44@46-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1433,7 +1393,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'firstNumbersLessThan6@46-1'::.ctor + } // end of method 'Pipe #5 input at line 44@46-1'::.ctor .method public strict virtual instance bool Invoke(int32 n) cil managed @@ -1445,11 +1405,21 @@ IL_0001: ldc.i4.6 IL_0002: clt IL_0004: ret - } // end of method 'firstNumbersLessThan6@46-1'::Invoke + } // end of method 'Pipe #5 input at line 44@46-1'::Invoke - } // end of class 'firstNumbersLessThan6@46-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #5 input at line 44@46-1'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #5 input at line 44@46-1' Linq101Partitioning01/'Pipe #5 input at line 44@46-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 44@46-1'::.cctor - .class auto autochar serializable sealed nested assembly beforefieldinit specialname allButFirst3Numbers@52 + } // end of class 'Pipe #5 input at line 44@46-1' + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #6 input at line 51@52' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1474,280 +1444,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0009: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::current + IL_0010: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method allButFirst3Numbers@52::.ctor + } // end of method 'Pipe #6 input at line 51@52'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 52,52 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc .line 52,52 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 52,52 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 53,53 : 9,31 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc .line 52,52 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method allButFirst3Numbers@52::GenerateNext + IL_0093: ret + } // end of method 'Pipe #6 input at line 51@52'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/allButFirst3Numbers@52::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Partitioning01/'Pipe #6 input at line 51@52'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Partitioning01/allButFirst3Numbers@52::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 52,52 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 52,52 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method allButFirst3Numbers@52::Close + IL_007f: ret + } // end of method 'Pipe #6 input at line 51@52'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst3Numbers@52::pc + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method allButFirst3Numbers@52::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #6 input at line 51@52'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -1757,9 +1697,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Partitioning01/allButFirst3Numbers@52::current + IL_0001: ldfld int32 Linq101Partitioning01/'Pipe #6 input at line 51@52'::current IL_0006: ret - } // end of method allButFirst3Numbers@52::get_LastGenerated + } // end of method 'Pipe #6 input at line 51@52'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -1771,17 +1711,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Partitioning01/allButFirst3Numbers@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Partitioning01/'Pipe #6 input at line 51@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method allButFirst3Numbers@52::GetFreshEnumerator + } // end of method 'Pipe #6 input at line 51@52'::GetFreshEnumerator - } // end of class allButFirst3Numbers@52 + } // end of class 'Pipe #6 input at line 51@52' - .class auto ansi serializable sealed nested assembly beforefieldinit 'allButFirst3Numbers@53-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 51@53-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Partitioning01/'Pipe #6 input at line 51@53-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1792,7 +1733,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'allButFirst3Numbers@53-1'::.ctor + } // end of method 'Pipe #6 input at line 51@53-1'::.ctor .method public strict virtual instance bool Invoke(int32 n) cil managed @@ -1808,16 +1749,26 @@ IL_0006: ldc.i4.0 IL_0007: ceq IL_0009: ret - } // end of method 'allButFirst3Numbers@53-1'::Invoke + } // end of method 'Pipe #6 input at line 51@53-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Partitioning01/'Pipe #6 input at line 51@53-1'::.ctor() + IL_0005: stsfld class Linq101Partitioning01/'Pipe #6 input at line 51@53-1' Linq101Partitioning01/'Pipe #6 input at line 51@53-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 51@53-1'::.cctor - } // end of class 'allButFirst3Numbers@53-1' + } // end of class 'Pipe #6 input at line 51@53-1' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_numbers() cil managed { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::'numbers@7-5' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::numbers@7 IL_0005: ret } // end of method Linq101Partitioning01::get_numbers @@ -1835,7 +1786,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::'customers@17-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::customers@17 IL_0005: ret } // end of method Linq101Partitioning01::get_customers @@ -1937,11 +1888,11 @@ .class private abstract auto ansi sealed ''.$Linq101Partitioning01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers@7-5' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers@7 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 first3Numbers@10 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'customers@17-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers@17 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`3[] WAOrders@18 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1960,7 +1911,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 432 (0x1b0) + // Code size 466 (0x1d2) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 first3Numbers, @@ -1970,12 +1921,19 @@ [5] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> WAOrders2, [6] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 firstNumbersLessThan6, [7] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 allButFirst3Numbers, - [8] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_8, + [8] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 11', [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, - [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10, + [10] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #2 input at line 19', [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, - [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12, - [13] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_13) + [12] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #3 input at line 28', + [13] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_13, + [14] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #4 input at line 35', + [15] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_15, + [16] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #4 stage #1 at line 40', + [17] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #5 input at line 44', + [18] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_18, + [19] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #6 input at line 51', + [20] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_20) .line 7,7 : 1,47 '' IL_0000: ldc.i4.5 IL_0001: ldc.i4.4 @@ -2009,141 +1967,174 @@ IL_003d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0042: dup - IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::'numbers@7-5' + IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::numbers@7 IL_0048: stloc.0 .line 10,14 : 1,20 '' - IL_0049: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_004e: stloc.s V_8 - IL_0050: ldloc.s V_8 - IL_0052: ldnull - IL_0053: ldc.i4.0 + IL_0049: nop + .line 11,11 : 5,10 '' + IL_004a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_004f: stloc.s V_9 + IL_0051: ldloc.s V_9 + IL_0053: ldnull IL_0054: ldc.i4.0 - IL_0055: newobj instance void Linq101Partitioning01/first3Numbers@12::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_005a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_005f: ldc.i4.3 - IL_0060: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Take(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0055: ldc.i4.0 + IL_0056: newobj instance void Linq101Partitioning01/'Pipe #1 input at line 11@12'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_005b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0060: ldc.i4.3 + IL_0061: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Take(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, int32) - IL_0065: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_006a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_006f: dup - IL_0070: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::first3Numbers@10 - IL_0075: stloc.1 + IL_0066: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_006b: stloc.s 'Pipe #1 input at line 11' + .line 14,14 : 10,20 '' + IL_006d: ldloc.s 'Pipe #1 input at line 11' + IL_006f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0074: dup + IL_0075: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::first3Numbers@10 + IL_007a: stloc.1 .line 17,17 : 1,34 '' - IL_0076: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() - IL_007b: dup - IL_007c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::'customers@17-2' - IL_0081: stloc.2 + IL_007b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() + IL_0080: dup + IL_0081: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::customers@17 + IL_0086: stloc.2 .line 18,24 : 1,21 '' - IL_0082: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0087: stloc.s V_9 - IL_0089: ldloc.s V_9 - IL_008b: ldloc.s V_9 - IL_008d: ldloc.s V_9 - IL_008f: ldloc.s V_9 - IL_0091: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_customers() - IL_0096: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_009b: ldloc.s V_9 - IL_009d: newobj instance void Linq101Partitioning01/WAOrders@20::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00a2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0087: nop + .line 19,19 : 5,10 '' + IL_0088: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_008d: stloc.s V_11 + IL_008f: ldloc.s V_11 + IL_0091: ldloc.s V_11 + IL_0093: ldloc.s V_11 + IL_0095: ldloc.s V_11 + IL_0097: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_customers() + IL_009c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00a1: ldloc.s V_11 + IL_00a3: newobj instance void Linq101Partitioning01/'Pipe #2 input at line 19@20'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00a8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00a7: newobj instance void Linq101Partitioning01/'WAOrders@22-2'::.ctor() - IL_00ac: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00ad: ldsfld class Linq101Partitioning01/'Pipe #2 input at line 19@22-2' Linq101Partitioning01/'Pipe #2 input at line 19@22-2'::@_instance + IL_00b2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00b1: newobj instance void Linq101Partitioning01/'WAOrders@23-3'::.ctor() - IL_00b6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00b7: ldsfld class Linq101Partitioning01/'Pipe #2 input at line 19@23-3' Linq101Partitioning01/'Pipe #2 input at line 19@23-3'::@_instance + IL_00bc: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00bb: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_00c0: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00c5: dup - IL_00c6: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Partitioning01::WAOrders@18 - IL_00cb: stloc.3 + IL_00c1: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_00c6: stloc.s 'Pipe #2 input at line 19' + .line 24,24 : 10,21 '' + IL_00c8: ldloc.s 'Pipe #2 input at line 19' + IL_00ca: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00cf: dup + IL_00d0: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Partitioning01::WAOrders@18 + IL_00d5: stloc.3 .line 27,31 : 1,20 '' - IL_00cc: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00d1: stloc.s V_10 - IL_00d3: ldloc.s V_10 - IL_00d5: ldnull - IL_00d6: ldc.i4.0 - IL_00d7: ldc.i4.0 - IL_00d8: newobj instance void Linq101Partitioning01/allButFirst4Numbers@29::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_00dd: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00e2: ldc.i4.4 - IL_00e3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Skip(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00d6: nop + .line 28,28 : 5,10 '' + IL_00d7: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00dc: stloc.s V_13 + IL_00de: ldloc.s V_13 + IL_00e0: ldnull + IL_00e1: ldc.i4.0 + IL_00e2: ldc.i4.0 + IL_00e3: newobj instance void Linq101Partitioning01/'Pipe #3 input at line 28@29'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_00e8: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00ed: ldc.i4.4 + IL_00ee: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Skip(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, int32) - IL_00e8: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_00ed: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00f2: dup - IL_00f3: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::allButFirst4Numbers@27 - IL_00f8: stloc.s allButFirst4Numbers + IL_00f3: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_00f8: stloc.s 'Pipe #3 input at line 28' + .line 31,31 : 10,20 '' + IL_00fa: ldloc.s 'Pipe #3 input at line 28' + IL_00fc: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0101: dup + IL_0102: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::allButFirst4Numbers@27 + IL_0107: stloc.s allButFirst4Numbers .line 34,40 : 1,34 '' - IL_00fa: ldc.i4.2 - IL_00fb: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0100: stloc.s V_11 - IL_0102: ldloc.s V_11 - IL_0104: ldloc.s V_11 - IL_0106: ldloc.s V_11 - IL_0108: ldloc.s V_11 - IL_010a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_customers() - IL_010f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0114: ldloc.s V_11 - IL_0116: newobj instance void Linq101Partitioning01/WAOrders2@36::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_011b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0109: nop + .line 35,35 : 5,10 '' + IL_010a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_010f: stloc.s V_15 + IL_0111: ldloc.s V_15 + IL_0113: ldloc.s V_15 + IL_0115: ldloc.s V_15 + IL_0117: ldloc.s V_15 + IL_0119: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Partitioning01::get_customers() + IL_011e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0123: ldloc.s V_15 + IL_0125: newobj instance void Linq101Partitioning01/'Pipe #4 input at line 35@36'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_012a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0120: newobj instance void Linq101Partitioning01/'WAOrders2@38-2'::.ctor() - IL_0125: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_012f: ldsfld class Linq101Partitioning01/'Pipe #4 input at line 35@38-2' Linq101Partitioning01/'Pipe #4 input at line 35@38-2'::@_instance + IL_0134: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_012a: newobj instance void Linq101Partitioning01/'WAOrders2@39-3'::.ctor() - IL_012f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0139: ldsfld class Linq101Partitioning01/'Pipe #4 input at line 35@39-3' Linq101Partitioning01/'Pipe #4 input at line 35@39-3'::@_instance + IL_013e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0134: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0139: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Skip>(int32, + IL_0143: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0148: stloc.s 'Pipe #4 input at line 35' + .line 40,40 : 10,20 '' + IL_014a: ldc.i4.2 + IL_014b: ldloc.s 'Pipe #4 input at line 35' + IL_014d: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Skip>(int32, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_013e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0143: dup - IL_0144: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> ''.$Linq101Partitioning01::WAOrders2@34 - IL_0149: stloc.s WAOrders2 + IL_0152: stloc.s 'Pipe #4 stage #1 at line 40' + .line 40,40 : 24,34 '' + IL_0154: ldloc.s 'Pipe #4 stage #1 at line 40' + IL_0156: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_015b: dup + IL_015c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> ''.$Linq101Partitioning01::WAOrders2@34 + IL_0161: stloc.s WAOrders2 .line 43,47 : 1,20 '' - IL_014b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0150: stloc.s V_12 - IL_0152: ldloc.s V_12 - IL_0154: ldnull - IL_0155: ldc.i4.0 - IL_0156: ldc.i4.0 - IL_0157: newobj instance void Linq101Partitioning01/firstNumbersLessThan6@45::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_015c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0161: newobj instance void Linq101Partitioning01/'firstNumbersLessThan6@46-1'::.ctor() - IL_0166: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::TakeWhile(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0163: nop + .line 44,44 : 5,10 '' + IL_0164: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0169: stloc.s V_18 + IL_016b: ldloc.s V_18 + IL_016d: ldnull + IL_016e: ldc.i4.0 + IL_016f: ldc.i4.0 + IL_0170: newobj instance void Linq101Partitioning01/'Pipe #5 input at line 44@45'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_0175: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_017a: ldsfld class Linq101Partitioning01/'Pipe #5 input at line 44@46-1' Linq101Partitioning01/'Pipe #5 input at line 44@46-1'::@_instance + IL_017f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::TakeWhile(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_016b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0170: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0175: dup - IL_0176: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::firstNumbersLessThan6@43 - IL_017b: stloc.s firstNumbersLessThan6 + IL_0184: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0189: stloc.s 'Pipe #5 input at line 44' + .line 47,47 : 10,20 '' + IL_018b: ldloc.s 'Pipe #5 input at line 44' + IL_018d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0192: dup + IL_0193: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::firstNumbersLessThan6@43 + IL_0198: stloc.s firstNumbersLessThan6 .line 50,54 : 1,20 '' - IL_017d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0182: stloc.s V_13 - IL_0184: ldloc.s V_13 - IL_0186: ldnull - IL_0187: ldc.i4.0 - IL_0188: ldc.i4.0 - IL_0189: newobj instance void Linq101Partitioning01/allButFirst3Numbers@52::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_018e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0193: newobj instance void Linq101Partitioning01/'allButFirst3Numbers@53-1'::.ctor() - IL_0198: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SkipWhile(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_019a: nop + .line 51,51 : 5,10 '' + IL_019b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01a0: stloc.s V_20 + IL_01a2: ldloc.s V_20 + IL_01a4: ldnull + IL_01a5: ldc.i4.0 + IL_01a6: ldc.i4.0 + IL_01a7: newobj instance void Linq101Partitioning01/'Pipe #6 input at line 51@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_01ac: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01b1: ldsfld class Linq101Partitioning01/'Pipe #6 input at line 51@53-1' Linq101Partitioning01/'Pipe #6 input at line 51@53-1'::@_instance + IL_01b6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::SkipWhile(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_019d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_01a2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01a7: dup - IL_01a8: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::allButFirst3Numbers@50 - IL_01ad: stloc.s allButFirst3Numbers - IL_01af: ret + IL_01bb: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_01c0: stloc.s 'Pipe #6 input at line 51' + .line 54,54 : 10,20 '' + IL_01c2: ldloc.s 'Pipe #6 input at line 51' + IL_01c4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01c9: dup + IL_01ca: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Partitioning01::allButFirst3Numbers@50 + IL_01cf: stloc.s allButFirst3Numbers + IL_01d1: ret } // end of method $Linq101Partitioning01::main@ } // end of class ''.$Linq101Partitioning01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Quantifiers01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Quantifiers01.il.bsl index d2b715c5820..d0dcf614bd4 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Quantifiers01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Quantifiers01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { @@ -38,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Quantifiers01 { - // Offset: 0x00000000 Length: 0x0000039F + // Offset: 0x00000000 Length: 0x00000393 } .mresource public FSharpOptimizationData.Linq101Quantifiers01 { - // Offset: 0x000003A8 Length: 0x000000FF + // Offset: 0x00000398 Length: 0x000000FF } .module Linq101Quantifiers01.exe -// MVID: {5B9A632A-76DD-E373-A745-03832A639A5B} +// MVID: {611C4D82-76DD-E373-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x025D0000 +// Image base: 0x071A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -100,106 +100,99 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] string V_0, [1] string w) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Quantifiers01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Quantifiers01.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Quantifiers01/iAfterE@12::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 12,12 : 9,26 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_words() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_words() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Quantifiers01/iAfterE@12::pc .line 12,12 : 9,26 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 12,12 : 9,26 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 13,13 : 9,34 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld string Linq101Quantifiers01/iAfterE@12::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld string Linq101Quantifiers01/iAfterE@12::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Quantifiers01/iAfterE@12::pc .line 12,12 : 9,26 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Quantifiers01/iAfterE@12::pc - IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld string Linq101Quantifiers01/iAfterE@12::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_008b: ldarg.0 + IL_008c: ldnull + IL_008d: stfld string Linq101Quantifiers01/iAfterE@12::current + IL_0092: ldc.i4.0 + IL_0093: ret } // end of method iAfterE@12::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Quantifiers01/iAfterE@12::pc @@ -207,158 +200,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Quantifiers01/iAfterE@12::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Quantifiers01/iAfterE@12::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/iAfterE@12::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Quantifiers01/iAfterE@12::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Quantifiers01/iAfterE@12::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Quantifiers01/iAfterE@12::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Quantifiers01/iAfterE@12::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 12,12 : 9,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 12,12 : 9,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method iAfterE@12::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Quantifiers01/iAfterE@12::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method iAfterE@12::get_CheckClose .method public strict virtual instance string @@ -394,6 +364,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'iAfterE@13-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'iAfterE@13-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -418,9 +389,19 @@ IL_000b: ret } // end of method 'iAfterE@13-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'iAfterE@13-1'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'iAfterE@13-1' Linq101Quantifiers01/'iAfterE@13-1'::@_instance + IL_000a: ret + } // end of method 'iAfterE@13-1'::.cctor + } // end of class 'iAfterE@13-1' - .class auto ansi serializable sealed nested assembly beforefieldinit productGroups@21 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@21' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -438,9 +419,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/productGroups@21::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #1 input at line 20@21'::builder@ IL_000d: ret - } // end of method productGroups@21::.ctor + } // end of method 'Pipe #1 input at line 20@21'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -453,18 +434,19 @@ IL_0001: stloc.0 .line 22,22 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/productGroups@21::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #1 input at line 20@21'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method productGroups@21::Invoke + } // end of method 'Pipe #1 input at line 20@21'::Invoke - } // end of class productGroups@21 + } // end of class 'Pipe #1 input at line 20@21' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups@22-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@22-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #1 input at line 20@22-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -475,7 +457,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'productGroups@22-1'::.ctor + } // end of method 'Pipe #1 input at line 20@22-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -485,13 +467,24 @@ .line 22,22 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'productGroups@22-1'::Invoke + } // end of method 'Pipe #1 input at line 20@22-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@22-1'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@22-1' Linq101Quantifiers01/'Pipe #1 input at line 20@22-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 20@22-1'::.cctor - } // end of class 'productGroups@22-1' + } // end of class 'Pipe #1 input at line 20@22-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups@22-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@22-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #1 input at line 20@22-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -502,7 +495,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'productGroups@22-2'::.ctor + } // end of method 'Pipe #1 input at line 20@22-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -514,11 +507,21 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'productGroups@22-2'::Invoke + } // end of method 'Pipe #1 input at line 20@22-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@22-2'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@22-2' Linq101Quantifiers01/'Pipe #1 input at line 20@22-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 20@22-2'::.cctor - } // end of class 'productGroups@22-2' + } // end of class 'Pipe #1 input at line 20@22-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups@22-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@22-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -536,9 +539,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'productGroups@22-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #1 input at line 20@22-3'::builder@ IL_000d: ret - } // end of method 'productGroups@22-3'::.ctor + } // end of method 'Pipe #1 input at line 20@22-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -550,47 +553,37 @@ IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'productGroups@22-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #1 input at line 20@22-3'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0010: ret - } // end of method 'productGroups@22-3'::Invoke + } // end of method 'Pipe #1 input at line 20@22-3'::Invoke - } // end of class 'productGroups@22-3' + } // end of class 'Pipe #1 input at line 20@22-3' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'productGroups@23-5' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 20@23-5' extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'productGroups@23-5'::.ctor - - .method assembly hidebysig instance bool - Invoke(class [Utils]Utils/Product x) cil managed + .method assembly static bool Invoke(class [Utils]Utils/Product x) cil managed { // Code size 10 (0xa) .maxstack 8 .line 23,23 : 31,49 '' - IL_0000: ldarg.1 + IL_0000: ldarg.0 IL_0001: callvirt instance int32 [Utils]Utils/Product::get_UnitsInStock() IL_0006: ldc.i4.0 IL_0007: ceq IL_0009: ret - } // end of method 'productGroups@23-5'::Invoke + } // end of method 'Pipe #1 input at line 20@23-5'::Invoke - } // end of class 'productGroups@23-5' + } // end of class 'Pipe #1 input at line 20@23-5' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups@23-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@23-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #1 input at line 20@23-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -601,29 +594,40 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'productGroups@23-4'::.ctor + } // end of method 'Pipe #1 input at line 20@23-4'::.ctor .method public strict virtual instance bool Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed { - // Code size 23 (0x17) + // Code size 19 (0x13) .maxstack 8 .line 23,23 : 16,50 '' IL_0000: ldarg.1 - IL_0001: newobj instance void Linq101Quantifiers01/'productGroups@23-5'::.ctor() - IL_0006: ldftn instance bool Linq101Quantifiers01/'productGroups@23-5'::Invoke(class [Utils]Utils/Product) - IL_000c: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + IL_0001: ldnull + IL_0002: ldftn bool Linq101Quantifiers01/'Pipe #1 input at line 20@23-5'::Invoke(class [Utils]Utils/Product) + IL_0008: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) - IL_0011: call bool [System.Core]System.Linq.Enumerable::Any(class [mscorlib]System.Collections.Generic.IEnumerable`1, + IL_000d: call bool [System.Core]System.Linq.Enumerable::Any(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) - IL_0016: ret - } // end of method 'productGroups@23-4'::Invoke + IL_0012: ret + } // end of method 'Pipe #1 input at line 20@23-4'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@23-4'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@23-4' Linq101Quantifiers01/'Pipe #1 input at line 20@23-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 20@23-4'::.cctor - } // end of class 'productGroups@23-4' + } // end of class 'Pipe #1 input at line 20@23-4' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups@24-6' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 20@24-6' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #1 input at line 20@24-6' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -634,7 +638,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'productGroups@24-6'::.ctor + } // end of method 'Pipe #1 input at line 20@24-6'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed @@ -648,9 +652,19 @@ IL_0007: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_000c: ret - } // end of method 'productGroups@24-6'::Invoke + } // end of method 'Pipe #1 input at line 20@24-6'::Invoke - } // end of class 'productGroups@24-6' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@24-6'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@24-6' Linq101Quantifiers01/'Pipe #1 input at line 20@24-6'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 20@24-6'::.cctor + + } // end of class 'Pipe #1 input at line 20@24-6' .class auto autochar serializable sealed nested assembly beforefieldinit specialname onlyOdd@32 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 @@ -692,7 +706,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) @@ -703,94 +717,87 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 32,32 : 9,28 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_numbers() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_numbers() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc .line 32,32 : 9,28 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 32,32 : 9,28 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 33,33 : 9,24 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101Quantifiers01/onlyOdd@32::current - IL_006b: ldc.i4.1 - IL_006c: ret + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101Quantifiers01/onlyOdd@32::current + IL_0065: ldc.i4.1 + IL_0066: ret .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 + IL_0067: nop + IL_0068: br.s IL_003c - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc .line 32,32 : 9,28 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101Quantifiers01/onlyOdd@32::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101Quantifiers01/onlyOdd@32::current - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0093: ret } // end of method onlyOdd@32::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Quantifiers01/onlyOdd@32::pc @@ -798,158 +805,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Quantifiers01/onlyOdd@32::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Quantifiers01/onlyOdd@32::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Quantifiers01/onlyOdd@32::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Quantifiers01/onlyOdd@32::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Quantifiers01/onlyOdd@32::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 32,32 : 9,28 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 32,32 : 9,28 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method onlyOdd@32::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Quantifiers01/onlyOdd@32::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method onlyOdd@32::get_CheckClose .method public strict virtual instance int32 @@ -985,6 +969,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'onlyOdd@33-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'onlyOdd@33-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1011,9 +996,19 @@ IL_0006: ret } // end of method 'onlyOdd@33-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'onlyOdd@33-1'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'onlyOdd@33-1' Linq101Quantifiers01/'onlyOdd@33-1'::@_instance + IL_000a: ret + } // end of method 'onlyOdd@33-1'::.cctor + } // end of class 'onlyOdd@33-1' - .class auto ansi serializable sealed nested assembly beforefieldinit productGroups2@39 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@39' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -1031,9 +1026,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/productGroups2@39::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #2 input at line 38@39'::builder@ IL_000d: ret - } // end of method productGroups2@39::.ctor + } // end of method 'Pipe #2 input at line 38@39'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -1046,18 +1041,19 @@ IL_0001: stloc.0 .line 40,40 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/productGroups2@39::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #2 input at line 38@39'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method productGroups2@39::Invoke + } // end of method 'Pipe #2 input at line 38@39'::Invoke - } // end of class productGroups2@39 + } // end of class 'Pipe #2 input at line 38@39' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups2@40-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #2 input at line 38@40-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1068,7 +1064,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'productGroups2@40-1'::.ctor + } // end of method 'Pipe #2 input at line 38@40-1'::.ctor .method public strict virtual instance class [Utils]Utils/Product Invoke(class [Utils]Utils/Product p) cil managed @@ -1078,13 +1074,24 @@ .line 40,40 : 20,21 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'productGroups2@40-1'::Invoke + } // end of method 'Pipe #2 input at line 38@40-1'::Invoke - } // end of class 'productGroups2@40-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@40-1'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@40-1' Linq101Quantifiers01/'Pipe #2 input at line 38@40-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@40-1'::.cctor + + } // end of class 'Pipe #2 input at line 38@40-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups2@40-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #2 input at line 38@40-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1095,7 +1102,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'productGroups2@40-2'::.ctor + } // end of method 'Pipe #2 input at line 38@40-2'::.ctor .method public strict virtual instance string Invoke(class [Utils]Utils/Product p) cil managed @@ -1107,11 +1114,21 @@ IL_0001: tail. IL_0003: callvirt instance string [Utils]Utils/Product::get_Category() IL_0008: ret - } // end of method 'productGroups2@40-2'::Invoke + } // end of method 'Pipe #2 input at line 38@40-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@40-2'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@40-2' Linq101Quantifiers01/'Pipe #2 input at line 38@40-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@40-2'::.cctor - } // end of class 'productGroups2@40-2' + } // end of class 'Pipe #2 input at line 38@40-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups2@40-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@40-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -1129,9 +1146,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'productGroups2@40-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #2 input at line 38@40-3'::builder@ IL_000d: ret - } // end of method 'productGroups2@40-3'::.ctor + } // end of method 'Pipe #2 input at line 38@40-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed @@ -1143,47 +1160,37 @@ IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'productGroups2@40-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Quantifiers01/'Pipe #2 input at line 38@40-3'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_0010: ret - } // end of method 'productGroups2@40-3'::Invoke + } // end of method 'Pipe #2 input at line 38@40-3'::Invoke - } // end of class 'productGroups2@40-3' + } // end of class 'Pipe #2 input at line 38@40-3' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'productGroups2@41-5' + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #2 input at line 38@41-5' extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } // end of method 'productGroups2@41-5'::.ctor - - .method assembly hidebysig instance bool - Invoke(class [Utils]Utils/Product x) cil managed + .method assembly static bool Invoke(class [Utils]Utils/Product x) cil managed { // Code size 10 (0xa) .maxstack 8 .line 41,41 : 31,49 '' - IL_0000: ldarg.1 + IL_0000: ldarg.0 IL_0001: callvirt instance int32 [Utils]Utils/Product::get_UnitsInStock() IL_0006: ldc.i4.0 IL_0007: cgt IL_0009: ret - } // end of method 'productGroups2@41-5'::Invoke + } // end of method 'Pipe #2 input at line 38@41-5'::Invoke - } // end of class 'productGroups2@41-5' + } // end of class 'Pipe #2 input at line 38@41-5' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups2@41-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@41-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #2 input at line 38@41-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1194,29 +1201,40 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'productGroups2@41-4'::.ctor + } // end of method 'Pipe #2 input at line 38@41-4'::.ctor .method public strict virtual instance bool Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed { - // Code size 23 (0x17) + // Code size 19 (0x13) .maxstack 8 .line 41,41 : 16,50 '' IL_0000: ldarg.1 - IL_0001: newobj instance void Linq101Quantifiers01/'productGroups2@41-5'::.ctor() - IL_0006: ldftn instance bool Linq101Quantifiers01/'productGroups2@41-5'::Invoke(class [Utils]Utils/Product) - IL_000c: newobj instance void class [mscorlib]System.Func`2::.ctor(object, + IL_0001: ldnull + IL_0002: ldftn bool Linq101Quantifiers01/'Pipe #2 input at line 38@41-5'::Invoke(class [Utils]Utils/Product) + IL_0008: newobj instance void class [mscorlib]System.Func`2::.ctor(object, native int) - IL_0011: call bool [System.Core]System.Linq.Enumerable::All(class [mscorlib]System.Collections.Generic.IEnumerable`1, + IL_000d: call bool [System.Core]System.Linq.Enumerable::All(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [mscorlib]System.Func`2) - IL_0016: ret - } // end of method 'productGroups2@41-4'::Invoke + IL_0012: ret + } // end of method 'Pipe #2 input at line 38@41-4'::Invoke - } // end of class 'productGroups2@41-4' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@41-4'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@41-4' Linq101Quantifiers01/'Pipe #2 input at line 38@41-4'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@41-4'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'productGroups2@42-6' + } // end of class 'Pipe #2 input at line 38@41-4' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 38@42-6' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>> { + .field static assembly initonly class Linq101Quantifiers01/'Pipe #2 input at line 38@42-6' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1227,7 +1245,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>>::.ctor() IL_0006: ret - } // end of method 'productGroups2@42-6'::.ctor + } // end of method 'Pipe #2 input at line 38@42-6'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2> Invoke(class [System.Core]System.Linq.IGrouping`2 g) cil managed @@ -1241,16 +1259,26 @@ IL_0007: newobj instance void class [mscorlib]System.Tuple`2>::.ctor(!0, !1) IL_000c: ret - } // end of method 'productGroups2@42-6'::Invoke + } // end of method 'Pipe #2 input at line 38@42-6'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@42-6'::.ctor() + IL_0005: stsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@42-6' Linq101Quantifiers01/'Pipe #2 input at line 38@42-6'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 38@42-6'::.cctor - } // end of class 'productGroups2@42-6' + } // end of class 'Pipe #2 input at line 38@42-6' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_words() cil managed { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'words@8-6' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::words@8 IL_0005: ret } // end of method Linq101Quantifiers01::get_words @@ -1268,7 +1296,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'products@17-10' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::products@17 IL_0005: ret } // end of method Linq101Quantifiers01::get_products @@ -1286,7 +1314,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'numbers@28-7' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::numbers@28 IL_0005: ret } // end of method Linq101Quantifiers01::get_numbers @@ -1353,15 +1381,15 @@ .class private abstract auto ansi sealed ''.$Linq101Quantifiers01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'words@8-6' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words@8 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly bool iAfterE@10 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@17-10' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@17 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2>[] productGroups@19 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers@28-7' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers@28 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly bool onlyOdd@30 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1374,7 +1402,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 407 (0x197) + // Code size 417 (0x1a1) .maxstack 10 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words, [1] bool iAfterE, @@ -1383,8 +1411,10 @@ [4] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers, [5] bool onlyOdd, [6] class [mscorlib]System.Tuple`2>[] productGroups2, - [7] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_7, - [8] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_8) + [7] class [mscorlib]System.Collections.Generic.IEnumerable`1>> 'Pipe #1 input at line 20', + [8] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_8, + [9] class [mscorlib]System.Collections.Generic.IEnumerable`1>> 'Pipe #2 input at line 38', + [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10) .line 8,8 : 1,54 '' IL_0000: ldstr "believe" IL_0005: ldstr "relief" @@ -1400,7 +1430,7 @@ IL_0028: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_002d: dup - IL_002e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'words@8-6' + IL_002e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::words@8 IL_0033: stloc.0 IL_0034: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() IL_0039: ldnull @@ -1410,7 +1440,7 @@ int32, string) IL_0041: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0046: newobj instance void Linq101Quantifiers01/'iAfterE@13-1'::.ctor() + IL_0046: ldsfld class Linq101Quantifiers01/'iAfterE@13-1' Linq101Quantifiers01/'iAfterE@13-1'::@_instance IL_004b: callvirt instance bool [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Exists(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_0050: dup @@ -1419,54 +1449,57 @@ .line 17,17 : 1,32 '' IL_0057: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() IL_005c: dup - IL_005d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'products@17-10' + IL_005d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::products@17 IL_0062: stloc.2 .line 19,25 : 1,21 '' - IL_0063: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0068: stloc.s V_7 - IL_006a: ldloc.s V_7 - IL_006c: ldloc.s V_7 - IL_006e: ldloc.s V_7 - IL_0070: ldloc.s V_7 - IL_0072: ldloc.s V_7 - IL_0074: ldloc.s V_7 - IL_0076: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_products() - IL_007b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0080: ldloc.s V_7 - IL_0082: newobj instance void Linq101Quantifiers01/productGroups@21::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0087: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0063: nop + .line 20,20 : 5,10 '' + IL_0064: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0069: stloc.s V_8 + IL_006b: ldloc.s V_8 + IL_006d: ldloc.s V_8 + IL_006f: ldloc.s V_8 + IL_0071: ldloc.s V_8 + IL_0073: ldloc.s V_8 + IL_0075: ldloc.s V_8 + IL_0077: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_products() + IL_007c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0081: ldloc.s V_8 + IL_0083: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@21'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0088: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_008c: newobj instance void Linq101Quantifiers01/'productGroups@22-1'::.ctor() - IL_0091: newobj instance void Linq101Quantifiers01/'productGroups@22-2'::.ctor() - IL_0096: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_008d: ldsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@22-1' Linq101Quantifiers01/'Pipe #1 input at line 20@22-1'::@_instance + IL_0092: ldsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@22-2' Linq101Quantifiers01/'Pipe #1 input at line 20@22-2'::@_instance + IL_0097: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_009b: ldloc.s V_7 - IL_009d: newobj instance void Linq101Quantifiers01/'productGroups@22-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00a2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_009c: ldloc.s V_8 + IL_009e: newobj instance void Linq101Quantifiers01/'Pipe #1 input at line 20@22-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00a3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00a7: newobj instance void Linq101Quantifiers01/'productGroups@23-4'::.ctor() - IL_00ac: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00a8: ldsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@23-4' Linq101Quantifiers01/'Pipe #1 input at line 20@23-4'::@_instance + IL_00ad: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00b1: newobj instance void Linq101Quantifiers01/'productGroups@24-6'::.ctor() - IL_00b6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00b2: ldsfld class Linq101Quantifiers01/'Pipe #1 input at line 20@24-6' Linq101Quantifiers01/'Pipe #1 input at line 20@24-6'::@_instance + IL_00b7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00bb: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_00c0: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00c5: dup - IL_00c6: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Quantifiers01::productGroups@19 - IL_00cb: stloc.3 + IL_00bc: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_00c1: stloc.s 'Pipe #1 input at line 20' + .line 25,25 : 10,21 '' + IL_00c3: ldloc.s 'Pipe #1 input at line 20' + IL_00c5: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00ca: dup + IL_00cb: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Quantifiers01::productGroups@19 + IL_00d0: stloc.3 .line 28,28 : 1,35 '' - IL_00cc: ldc.i4.1 - IL_00cd: ldc.i4.s 11 - IL_00cf: ldc.i4.3 - IL_00d0: ldc.i4.s 19 - IL_00d2: ldc.i4.s 41 - IL_00d4: ldc.i4.s 65 - IL_00d6: ldc.i4.s 19 - IL_00d8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_00dd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_00d1: ldc.i4.1 + IL_00d2: ldc.i4.s 11 + IL_00d4: ldc.i4.3 + IL_00d5: ldc.i4.s 19 + IL_00d7: ldc.i4.s 41 + IL_00d9: ldc.i4.s 65 + IL_00db: ldc.i4.s 19 + IL_00dd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_00e2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_00e7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -1479,59 +1512,66 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_00fb: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0100: dup - IL_0101: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::'numbers@28-7' - IL_0106: stloc.s numbers - IL_0108: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_010d: ldnull - IL_010e: ldc.i4.0 - IL_010f: ldc.i4.0 - IL_0110: newobj instance void Linq101Quantifiers01/onlyOdd@32::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0100: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_0105: dup + IL_0106: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Quantifiers01::numbers@28 + IL_010b: stloc.s numbers + IL_010d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0112: ldnull + IL_0113: ldc.i4.0 + IL_0114: ldc.i4.0 + IL_0115: newobj instance void Linq101Quantifiers01/onlyOdd@32::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_0115: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_011a: newobj instance void Linq101Quantifiers01/'onlyOdd@33-1'::.ctor() - IL_011f: callvirt instance bool [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::All(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_011a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_011f: ldsfld class Linq101Quantifiers01/'onlyOdd@33-1' Linq101Quantifiers01/'onlyOdd@33-1'::@_instance + IL_0124: callvirt instance bool [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::All(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0124: dup - IL_0125: stsfld bool ''.$Linq101Quantifiers01::onlyOdd@30 - IL_012a: stloc.s onlyOdd + IL_0129: dup + IL_012a: stsfld bool ''.$Linq101Quantifiers01::onlyOdd@30 + IL_012f: stloc.s onlyOdd .line 37,43 : 1,21 '' - IL_012c: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0131: stloc.s V_8 - IL_0133: ldloc.s V_8 - IL_0135: ldloc.s V_8 - IL_0137: ldloc.s V_8 - IL_0139: ldloc.s V_8 - IL_013b: ldloc.s V_8 - IL_013d: ldloc.s V_8 - IL_013f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_products() - IL_0144: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0149: ldloc.s V_8 - IL_014b: newobj instance void Linq101Quantifiers01/productGroups2@39::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0150: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0131: nop + .line 38,38 : 5,10 '' + IL_0132: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0137: stloc.s V_10 + IL_0139: ldloc.s V_10 + IL_013b: ldloc.s V_10 + IL_013d: ldloc.s V_10 + IL_013f: ldloc.s V_10 + IL_0141: ldloc.s V_10 + IL_0143: ldloc.s V_10 + IL_0145: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Quantifiers01::get_products() + IL_014a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_014f: ldloc.s V_10 + IL_0151: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@39'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0156: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0155: newobj instance void Linq101Quantifiers01/'productGroups2@40-1'::.ctor() - IL_015a: newobj instance void Linq101Quantifiers01/'productGroups2@40-2'::.ctor() - IL_015f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_015b: ldsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@40-1' Linq101Quantifiers01/'Pipe #2 input at line 38@40-1'::@_instance + IL_0160: ldsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@40-2' Linq101Quantifiers01/'Pipe #2 input at line 38@40-2'::@_instance + IL_0165: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0164: ldloc.s V_8 - IL_0166: newobj instance void Linq101Quantifiers01/'productGroups2@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_016b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_016a: ldloc.s V_10 + IL_016c: newobj instance void Linq101Quantifiers01/'Pipe #2 input at line 38@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0171: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [System.Core]System.Linq.IGrouping`2,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0170: newobj instance void Linq101Quantifiers01/'productGroups2@41-4'::.ctor() - IL_0175: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0176: ldsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@41-4' Linq101Quantifiers01/'Pipe #2 input at line 38@41-4'::@_instance + IL_017b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_017a: newobj instance void Linq101Quantifiers01/'productGroups2@42-6'::.ctor() - IL_017f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0180: ldsfld class Linq101Quantifiers01/'Pipe #2 input at line 38@42-6' Linq101Quantifiers01/'Pipe #2 input at line 38@42-6'::@_instance + IL_0185: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0184: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0189: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_018e: dup - IL_018f: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Quantifiers01::productGroups2@37 - IL_0194: stloc.s productGroups2 - IL_0196: ret + IL_018a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_018f: stloc.s 'Pipe #2 input at line 38' + .line 43,43 : 10,21 '' + IL_0191: ldloc.s 'Pipe #2 input at line 38' + IL_0193: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0198: dup + IL_0199: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Quantifiers01::productGroups2@37 + IL_019e: stloc.s productGroups2 + IL_01a0: ret } // end of method $Linq101Quantifiers01::main@ } // end of class ''.$Linq101Quantifiers01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Select01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Select01.il.bsl index 8afae23a726..cfcb02aa149 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Select01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Select01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,17 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101Select01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -33,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Select01 { - // Offset: 0x00000000 Length: 0x00000663 + // Offset: 0x00000000 Length: 0x00000643 } .mresource public FSharpOptimizationData.Linq101Select01 { - // Offset: 0x00000668 Length: 0x00000204 + // Offset: 0x00000648 Length: 0x00000204 } .module Linq101Select01.exe -// MVID: {5B9A632A-6057-8F80-A745-03832A639A5B} +// MVID: {611C5DB0-6057-8F80-A745-0383B05D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00FF0000 +// Image base: 0x05540000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,9 +60,10 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'numsPlusOne@12-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 11@12-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'Pipe #1 input at line 11@12-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -68,7 +74,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'numsPlusOne@12-1'::.ctor + } // end of method 'Pipe #1 input at line 11@12-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(int32 _arg1) cil managed @@ -77,7 +83,7 @@ .maxstack 5 .locals init ([0] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 12,12 : 9,28 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Select01.fs' + .line 12,12 : 9,28 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Select01.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 13,13 : 9,23 '' @@ -85,11 +91,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'numsPlusOne@12-1'::Invoke + } // end of method 'Pipe #1 input at line 11@12-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #1 input at line 11@12-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #1 input at line 11@12-1' Linq101Select01/'Pipe #1 input at line 11@12-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 11@12-1'::.cctor - } // end of class 'numsPlusOne@12-1' + } // end of class 'Pipe #1 input at line 11@12-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname numsPlusOne@13 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 11@13' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -114,281 +130,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0009: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101Select01/numsPlusOne@13::current + IL_0010: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method numsPlusOne@13::.ctor + } // end of method 'Pipe #1 input at line 11@13'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 164 (0xa4) + // Code size 158 (0x9e) .maxstack 7 .locals init ([0] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_007a + IL_001b: nop + IL_001c: br.s IL_0074 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0077 + IL_001e: nop + IL_001f: br.s IL_0071 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_009b + IL_0021: nop + IL_0022: br.s IL_0095 .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 13,13 : 9,23 '' - IL_002b: ldarg.0 - IL_002c: newobj instance void Linq101Select01/'numsPlusOne@12-1'::.ctor() - IL_0031: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() - IL_0036: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0025: ldarg.0 + IL_0026: ldsfld class Linq101Select01/'Pipe #1 input at line 11@12-1' Linq101Select01/'Pipe #1 input at line 11@12-1'::@_instance + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0040: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: stfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_003f: ldarg.0 + IL_0040: ldc.i4.1 + IL_0041: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc .line 13,13 : 9,23 '' - IL_004c: ldarg.0 - IL_004d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_0052: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0057: brfalse.s IL_007a - - IL_0059: ldarg.0 - IL_005a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_005f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0064: stloc.0 - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0046: ldarg.0 + IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0051: brfalse.s IL_0074 + + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_005e: stloc.0 .line 13,13 : 17,22 '' - IL_006c: ldarg.0 - IL_006d: ldloc.0 - IL_006e: ldc.i4.1 - IL_006f: add - IL_0070: stfld int32 Linq101Select01/numsPlusOne@13::current - IL_0075: ldc.i4.1 - IL_0076: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.2 + IL_0061: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc + IL_0066: ldarg.0 + IL_0067: ldloc.0 + IL_0068: ldc.i4.1 + IL_0069: add + IL_006a: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::current + IL_006f: ldc.i4.1 + IL_0070: ret .line 100001,100001 : 0,0 '' - IL_0077: nop - IL_0078: br.s IL_004c + IL_0071: nop + IL_0072: br.s IL_0046 - IL_007a: ldarg.0 - IL_007b: ldc.i4.3 - IL_007c: stfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0074: ldarg.0 + IL_0075: ldc.i4.3 + IL_0076: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc .line 13,13 : 9,23 '' - IL_0081: ldarg.0 - IL_0082: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_0087: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_008c: nop - IL_008d: ldarg.0 - IL_008e: ldnull - IL_008f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_0094: ldarg.0 - IL_0095: ldc.i4.3 - IL_0096: stfld int32 Linq101Select01/numsPlusOne@13::pc - IL_009b: ldarg.0 + IL_007b: ldarg.0 + IL_007c: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_0081: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0086: nop + IL_0087: ldarg.0 + IL_0088: ldnull + IL_0089: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_008e: ldarg.0 + IL_008f: ldc.i4.3 + IL_0090: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc + IL_0095: ldarg.0 + IL_0096: ldc.i4.0 + IL_0097: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::current IL_009c: ldc.i4.0 - IL_009d: stfld int32 Linq101Select01/numsPlusOne@13::current - IL_00a2: ldc.i4.0 - IL_00a3: ret - } // end of method numsPlusOne@13::GenerateNext + IL_009d: ret + } // end of method 'Pipe #1 input at line 11@13'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/numsPlusOne@13::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/numsPlusOne@13::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/numsPlusOne@13::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #1 input at line 11@13'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/numsPlusOne@13::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101Select01/numsPlusOne@13::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 13,13 : 9,23 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 13,13 : 9,23 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method numsPlusOne@13::Close + IL_007f: ret + } // end of method 'Pipe #1 input at line 11@13'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/numsPlusOne@13::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method numsPlusOne@13::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #1 input at line 11@13'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -398,9 +384,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/numsPlusOne@13::current + IL_0001: ldfld int32 Linq101Select01/'Pipe #1 input at line 11@13'::current IL_0006: ret - } // end of method numsPlusOne@13::get_LastGenerated + } // end of method 'Pipe #1 input at line 11@13'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -412,17 +398,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101Select01/numsPlusOne@13::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101Select01/'Pipe #1 input at line 11@13'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method numsPlusOne@13::GetFreshEnumerator + } // end of method 'Pipe #1 input at line 11@13'::GetFreshEnumerator - } // end of class numsPlusOne@13 + } // end of class 'Pipe #1 input at line 11@13' .class auto ansi serializable sealed nested assembly beforefieldinit 'productNames@21-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'productNames@21-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -451,6 +438,16 @@ IL_000a: ret } // end of method 'productNames@21-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'productNames@21-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'productNames@21-1' Linq101Select01/'productNames@21-1'::@_instance + IL_000a: ret + } // end of method 'productNames@21-1'::.cctor + } // end of class 'productNames@21-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname productNames@22 @@ -493,7 +490,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 167 (0xa7) + // Code size 161 (0xa1) .maxstack 7 .locals init ([0] class [Utils]Utils/Product p) .line 100001,100001 : 0,0 '' @@ -503,95 +500,88 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_007d + IL_001b: nop + IL_001c: br.s IL_0077 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_007a + IL_001e: nop + IL_001f: br.s IL_0074 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_009e + IL_0021: nop + IL_0022: br.s IL_0098 .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 22,22 : 9,31 '' - IL_002b: ldarg.0 - IL_002c: newobj instance void Linq101Select01/'productNames@21-1'::.ctor() - IL_0031: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_products() - IL_0036: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0025: ldarg.0 + IL_0026: ldsfld class Linq101Select01/'productNames@21-1' Linq101Select01/'productNames@21-1'::@_instance + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_products() + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0040: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: stfld int32 Linq101Select01/productNames@22::pc + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_003f: ldarg.0 + IL_0040: ldc.i4.1 + IL_0041: stfld int32 Linq101Select01/productNames@22::pc .line 22,22 : 9,31 '' - IL_004c: ldarg.0 - IL_004d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_0052: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0057: brfalse.s IL_007d - - IL_0059: ldarg.0 - IL_005a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_005f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0064: stloc.0 - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 Linq101Select01/productNames@22::pc + IL_0046: ldarg.0 + IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0051: brfalse.s IL_0077 + + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_005e: stloc.0 .line 22,22 : 17,30 '' - IL_006c: ldarg.0 - IL_006d: ldloc.0 - IL_006e: callvirt instance string [Utils]Utils/Product::get_ProductName() - IL_0073: stfld string Linq101Select01/productNames@22::current - IL_0078: ldc.i4.1 - IL_0079: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.2 + IL_0061: stfld int32 Linq101Select01/productNames@22::pc + IL_0066: ldarg.0 + IL_0067: ldloc.0 + IL_0068: callvirt instance string [Utils]Utils/Product::get_ProductName() + IL_006d: stfld string Linq101Select01/productNames@22::current + IL_0072: ldc.i4.1 + IL_0073: ret .line 100001,100001 : 0,0 '' - IL_007a: nop - IL_007b: br.s IL_004c + IL_0074: nop + IL_0075: br.s IL_0046 - IL_007d: ldarg.0 - IL_007e: ldc.i4.3 - IL_007f: stfld int32 Linq101Select01/productNames@22::pc + IL_0077: ldarg.0 + IL_0078: ldc.i4.3 + IL_0079: stfld int32 Linq101Select01/productNames@22::pc .line 22,22 : 9,31 '' - IL_0084: ldarg.0 - IL_0085: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_008a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_008f: nop - IL_0090: ldarg.0 - IL_0091: ldnull - IL_0092: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_0097: ldarg.0 - IL_0098: ldc.i4.3 - IL_0099: stfld int32 Linq101Select01/productNames@22::pc - IL_009e: ldarg.0 - IL_009f: ldnull - IL_00a0: stfld string Linq101Select01/productNames@22::current - IL_00a5: ldc.i4.0 - IL_00a6: ret + IL_007e: ldarg.0 + IL_007f: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_0084: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0089: nop + IL_008a: ldarg.0 + IL_008b: ldnull + IL_008c: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_0091: ldarg.0 + IL_0092: ldc.i4.3 + IL_0093: stfld int32 Linq101Select01/productNames@22::pc + IL_0098: ldarg.0 + IL_0099: ldnull + IL_009a: stfld string Linq101Select01/productNames@22::current + IL_009f: ldc.i4.0 + IL_00a0: ret } // end of method productNames@22::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Select01/productNames@22::pc @@ -599,158 +589,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/productNames@22::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/productNames@22::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/productNames@22::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/productNames@22::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productNames@22::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/productNames@22::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Select01/productNames@22::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/productNames@22::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Select01/productNames@22::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 22,22 : 9,31 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 22,22 : 9,31 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method productNames@22::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Select01/productNames@22::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method productNames@22::get_CheckClose .method public strict virtual instance string @@ -783,9 +750,10 @@ } // end of class productNames@22 - .class auto ansi serializable sealed nested assembly beforefieldinit 'textNums@29-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 28@29-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'Pipe #2 input at line 28@29-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -796,7 +764,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'textNums@29-1'::.ctor + } // end of method 'Pipe #2 input at line 28@29-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(int32 _arg1) cil managed @@ -812,11 +780,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'textNums@29-1'::Invoke + } // end of method 'Pipe #2 input at line 28@29-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #2 input at line 28@29-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #2 input at line 28@29-1' Linq101Select01/'Pipe #2 input at line 28@29-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 28@29-1'::.cctor - } // end of class 'textNums@29-1' + } // end of class 'Pipe #2 input at line 28@29-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname textNums@30 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #2 input at line 28@30' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -841,281 +819,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Select01/textNums@30::pc + IL_0009: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101Select01/textNums@30::current + IL_0010: stfld string Linq101Select01/'Pipe #2 input at line 28@30'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method textNums@30::.ctor + } // end of method 'Pipe #2 input at line 28@30'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 172 (0xac) + // Code size 166 (0xa6) .maxstack 7 .locals init ([0] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/textNums@30::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0082 + IL_001b: nop + IL_001c: br.s IL_007c .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_007f + IL_001e: nop + IL_001f: br.s IL_0079 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_00a3 + IL_0021: nop + IL_0022: br.s IL_009d .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 30,30 : 9,29 '' - IL_002b: ldarg.0 - IL_002c: newobj instance void Linq101Select01/'textNums@29-1'::.ctor() - IL_0031: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() - IL_0036: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0025: ldarg.0 + IL_0026: ldsfld class Linq101Select01/'Pipe #2 input at line 28@29-1' Linq101Select01/'Pipe #2 input at line 28@29-1'::@_instance + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0040: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: stfld int32 Linq101Select01/textNums@30::pc + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_003f: ldarg.0 + IL_0040: ldc.i4.1 + IL_0041: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc .line 30,30 : 9,29 '' - IL_004c: ldarg.0 - IL_004d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_0052: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0057: brfalse.s IL_0082 - - IL_0059: ldarg.0 - IL_005a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_005f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0064: stloc.0 - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 Linq101Select01/textNums@30::pc + IL_0046: ldarg.0 + IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0051: brfalse.s IL_007c + + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_005e: stloc.0 .line 30,30 : 17,28 '' - IL_006c: ldarg.0 - IL_006d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() - IL_0072: ldloc.0 - IL_0073: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Item(int32) - IL_0078: stfld string Linq101Select01/textNums@30::current - IL_007d: ldc.i4.1 - IL_007e: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.2 + IL_0061: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc + IL_0066: ldarg.0 + IL_0067: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() + IL_006c: ldloc.0 + IL_006d: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Item(int32) + IL_0072: stfld string Linq101Select01/'Pipe #2 input at line 28@30'::current + IL_0077: ldc.i4.1 + IL_0078: ret .line 100001,100001 : 0,0 '' - IL_007f: nop - IL_0080: br.s IL_004c + IL_0079: nop + IL_007a: br.s IL_0046 - IL_0082: ldarg.0 - IL_0083: ldc.i4.3 - IL_0084: stfld int32 Linq101Select01/textNums@30::pc + IL_007c: ldarg.0 + IL_007d: ldc.i4.3 + IL_007e: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc .line 30,30 : 9,29 '' - IL_0089: ldarg.0 - IL_008a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_008f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0094: nop - IL_0095: ldarg.0 - IL_0096: ldnull - IL_0097: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_009c: ldarg.0 - IL_009d: ldc.i4.3 - IL_009e: stfld int32 Linq101Select01/textNums@30::pc - IL_00a3: ldarg.0 - IL_00a4: ldnull - IL_00a5: stfld string Linq101Select01/textNums@30::current - IL_00aa: ldc.i4.0 - IL_00ab: ret - } // end of method textNums@30::GenerateNext + IL_0083: ldarg.0 + IL_0084: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_0089: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_008e: nop + IL_008f: ldarg.0 + IL_0090: ldnull + IL_0091: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_0096: ldarg.0 + IL_0097: ldc.i4.3 + IL_0098: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc + IL_009d: ldarg.0 + IL_009e: ldnull + IL_009f: stfld string Linq101Select01/'Pipe #2 input at line 28@30'::current + IL_00a4: ldc.i4.0 + IL_00a5: ret + } // end of method 'Pipe #2 input at line 28@30'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/textNums@30::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/textNums@30::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/textNums@30::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/textNums@30::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #2 input at line 28@30'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/textNums@30::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Select01/textNums@30::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Select01/'Pipe #2 input at line 28@30'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 30,30 : 9,29 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 30,30 : 9,29 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method textNums@30::Close + IL_007f: ret + } // end of method 'Pipe #2 input at line 28@30'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/textNums@30::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #2 input at line 28@30'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method textNums@30::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #2 input at line 28@30'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -1125,9 +1073,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101Select01/textNums@30::current + IL_0001: ldfld string Linq101Select01/'Pipe #2 input at line 28@30'::current IL_0006: ret - } // end of method textNums@30::get_LastGenerated + } // end of method 'Pipe #2 input at line 28@30'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -1139,17 +1087,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Select01/textNums@30::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101Select01/'Pipe #2 input at line 28@30'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method textNums@30::GetFreshEnumerator + } // end of method 'Pipe #2 input at line 28@30'::GetFreshEnumerator - } // end of class textNums@30 + } // end of class 'Pipe #2 input at line 28@30' - .class auto ansi serializable sealed nested assembly beforefieldinit 'upperLowerWords@38-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 37@38-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'Pipe #3 input at line 37@38-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1160,7 +1109,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'upperLowerWords@38-1'::.ctor + } // end of method 'Pipe #3 input at line 37@38-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(string _arg1) cil managed @@ -1176,11 +1125,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'upperLowerWords@38-1'::Invoke + } // end of method 'Pipe #3 input at line 37@38-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #3 input at line 37@38-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #3 input at line 37@38-1' Linq101Select01/'Pipe #3 input at line 37@38-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 37@38-1'::.cctor - } // end of class 'upperLowerWords@38-1' + } // end of class 'Pipe #3 input at line 37@38-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname upperLowerWords@39 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #3 input at line 37@39' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1> { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1205,284 +1164,254 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0009: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld class [mscorlib]System.Tuple`2 Linq101Select01/upperLowerWords@39::current + IL_0010: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #3 input at line 37@39'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1>::.ctor() IL_001b: ret - } // end of method upperLowerWords@39::.ctor + } // end of method 'Pipe #3 input at line 37@39'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed { - // Code size 181 (0xb5) + // Code size 175 (0xaf) .maxstack 7 .locals init ([0] string w) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_008b + IL_001b: nop + IL_001c: br.s IL_0085 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0088 + IL_001e: nop + IL_001f: br.s IL_0082 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00ac + IL_0021: nop + IL_0022: br IL_00a6 .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 39,39 : 8,41 '' - IL_002e: ldarg.0 - IL_002f: newobj instance void Linq101Select01/'upperLowerWords@38-1'::.ctor() - IL_0034: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_words() - IL_0039: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0028: ldarg.0 + IL_0029: ldsfld class Linq101Select01/'Pipe #3 input at line 37@38-1' Linq101Select01/'Pipe #3 input at line 37@38-1'::@_instance + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_words() + IL_0033: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0043: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_0048: ldarg.0 - IL_0049: ldc.i4.1 - IL_004a: stfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0038: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc .line 39,39 : 8,41 '' - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_0055: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_005a: brfalse.s IL_008b - - IL_005c: ldarg.0 - IL_005d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_0062: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0067: stloc.0 - IL_0068: ldarg.0 - IL_0069: ldc.i4.2 - IL_006a: stfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_004f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0054: brfalse.s IL_0085 + + IL_0056: ldarg.0 + IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0061: stloc.0 .line 39,39 : 16,40 '' - IL_006f: ldarg.0 + IL_0062: ldarg.0 + IL_0063: ldc.i4.2 + IL_0064: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc + IL_0069: ldarg.0 + IL_006a: ldloc.0 + IL_006b: callvirt instance string [mscorlib]System.String::ToUpper() IL_0070: ldloc.0 - IL_0071: callvirt instance string [mscorlib]System.String::ToUpper() - IL_0076: ldloc.0 - IL_0077: callvirt instance string [mscorlib]System.String::ToLower() - IL_007c: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_0071: callvirt instance string [mscorlib]System.String::ToLower() + IL_0076: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0081: stfld class [mscorlib]System.Tuple`2 Linq101Select01/upperLowerWords@39::current - IL_0086: ldc.i4.1 - IL_0087: ret + IL_007b: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #3 input at line 37@39'::current + IL_0080: ldc.i4.1 + IL_0081: ret .line 100001,100001 : 0,0 '' - IL_0088: nop - IL_0089: br.s IL_004f + IL_0082: nop + IL_0083: br.s IL_0049 - IL_008b: ldarg.0 - IL_008c: ldc.i4.3 - IL_008d: stfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0085: ldarg.0 + IL_0086: ldc.i4.3 + IL_0087: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc .line 39,39 : 8,41 '' - IL_0092: ldarg.0 - IL_0093: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_0098: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_009d: nop - IL_009e: ldarg.0 - IL_009f: ldnull - IL_00a0: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_00a5: ldarg.0 - IL_00a6: ldc.i4.3 - IL_00a7: stfld int32 Linq101Select01/upperLowerWords@39::pc - IL_00ac: ldarg.0 - IL_00ad: ldnull - IL_00ae: stfld class [mscorlib]System.Tuple`2 Linq101Select01/upperLowerWords@39::current - IL_00b3: ldc.i4.0 - IL_00b4: ret - } // end of method upperLowerWords@39::GenerateNext + IL_008c: ldarg.0 + IL_008d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_0092: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0097: nop + IL_0098: ldarg.0 + IL_0099: ldnull + IL_009a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_009f: ldarg.0 + IL_00a0: ldc.i4.3 + IL_00a1: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc + IL_00a6: ldarg.0 + IL_00a7: ldnull + IL_00a8: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #3 input at line 37@39'::current + IL_00ad: ldc.i4.0 + IL_00ae: ret + } // end of method 'Pipe #3 input at line 37@39'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/upperLowerWords@39::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/upperLowerWords@39::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/upperLowerWords@39::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #3 input at line 37@39'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/upperLowerWords@39::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [mscorlib]System.Tuple`2 Linq101Select01/upperLowerWords@39::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #3 input at line 37@39'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 39,39 : 8,41 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 39,39 : 8,41 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method upperLowerWords@39::Close + IL_007f: ret + } // end of method 'Pipe #3 input at line 37@39'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/upperLowerWords@39::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #3 input at line 37@39'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method upperLowerWords@39::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #3 input at line 37@39'::get_CheckClose .method public strict virtual instance class [mscorlib]System.Tuple`2 get_LastGenerated() cil managed @@ -1492,9 +1421,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld class [mscorlib]System.Tuple`2 Linq101Select01/upperLowerWords@39::current + IL_0001: ldfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #3 input at line 37@39'::current IL_0006: ret - } // end of method upperLowerWords@39::get_LastGenerated + } // end of method 'Pipe #3 input at line 37@39'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1> GetFreshEnumerator() cil managed @@ -1506,17 +1435,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Select01/upperLowerWords@39::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`2) + IL_0003: newobj instance void Linq101Select01/'Pipe #3 input at line 37@39'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`2) IL_0008: ret - } // end of method upperLowerWords@39::GetFreshEnumerator + } // end of method 'Pipe #3 input at line 37@39'::GetFreshEnumerator - } // end of class upperLowerWords@39 + } // end of class 'Pipe #3 input at line 37@39' - .class auto ansi serializable sealed nested assembly beforefieldinit 'digitOddEvens@45-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #4 input at line 44@45-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'Pipe #4 input at line 44@45-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1527,7 +1457,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'digitOddEvens@45-1'::.ctor + } // end of method 'Pipe #4 input at line 44@45-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(int32 _arg1) cil managed @@ -1543,11 +1473,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'digitOddEvens@45-1'::Invoke + } // end of method 'Pipe #4 input at line 44@45-1'::Invoke - } // end of class 'digitOddEvens@45-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #4 input at line 44@45-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #4 input at line 44@45-1' Linq101Select01/'Pipe #4 input at line 44@45-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #4 input at line 44@45-1'::.cctor + + } // end of class 'Pipe #4 input at line 44@45-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname digitOddEvens@46 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #4 input at line 44@46' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1> { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1572,288 +1512,258 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0009: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld class [mscorlib]System.Tuple`2 Linq101Select01/digitOddEvens@46::current + IL_0010: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #4 input at line 44@46'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1>::.ctor() IL_001b: ret - } // end of method digitOddEvens@46::.ctor + } // end of method 'Pipe #4 input at line 44@46'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed { - // Code size 186 (0xba) + // Code size 180 (0xb4) .maxstack 8 .locals init ([0] int32 n) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0090 + IL_001b: nop + IL_001c: br.s IL_008a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_008d + IL_001e: nop + IL_001f: br.s IL_0087 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00b1 + IL_0021: nop + IL_0022: br IL_00ab .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 46,46 : 9,42 '' - IL_002e: ldarg.0 - IL_002f: newobj instance void Linq101Select01/'digitOddEvens@45-1'::.ctor() - IL_0034: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() - IL_0039: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0028: ldarg.0 + IL_0029: ldsfld class Linq101Select01/'Pipe #4 input at line 44@45-1' Linq101Select01/'Pipe #4 input at line 44@45-1'::@_instance + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() + IL_0033: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0043: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_0048: ldarg.0 - IL_0049: ldc.i4.1 - IL_004a: stfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0038: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc .line 46,46 : 9,42 '' - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_0055: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_005a: brfalse.s IL_0090 - - IL_005c: ldarg.0 - IL_005d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_0062: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0067: stloc.0 - IL_0068: ldarg.0 - IL_0069: ldc.i4.2 - IL_006a: stfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_004f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0054: brfalse.s IL_008a + + IL_0056: ldarg.0 + IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0061: stloc.0 .line 46,46 : 17,41 '' - IL_006f: ldarg.0 - IL_0070: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() + IL_0062: ldarg.0 + IL_0063: ldc.i4.2 + IL_0064: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc + IL_0069: ldarg.0 + IL_006a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() + IL_006f: ldloc.0 + IL_0070: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Item(int32) IL_0075: ldloc.0 - IL_0076: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Item(int32) - IL_007b: ldloc.0 - IL_007c: ldc.i4.2 - IL_007d: rem - IL_007e: ldc.i4.0 - IL_007f: ceq - IL_0081: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_0076: ldc.i4.2 + IL_0077: rem + IL_0078: ldc.i4.0 + IL_0079: ceq + IL_007b: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0086: stfld class [mscorlib]System.Tuple`2 Linq101Select01/digitOddEvens@46::current - IL_008b: ldc.i4.1 - IL_008c: ret + IL_0080: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #4 input at line 44@46'::current + IL_0085: ldc.i4.1 + IL_0086: ret .line 100001,100001 : 0,0 '' - IL_008d: nop - IL_008e: br.s IL_004f + IL_0087: nop + IL_0088: br.s IL_0049 - IL_0090: ldarg.0 - IL_0091: ldc.i4.3 - IL_0092: stfld int32 Linq101Select01/digitOddEvens@46::pc + IL_008a: ldarg.0 + IL_008b: ldc.i4.3 + IL_008c: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc .line 46,46 : 9,42 '' - IL_0097: ldarg.0 - IL_0098: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_009d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_00a2: nop - IL_00a3: ldarg.0 - IL_00a4: ldnull - IL_00a5: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_00aa: ldarg.0 - IL_00ab: ldc.i4.3 - IL_00ac: stfld int32 Linq101Select01/digitOddEvens@46::pc - IL_00b1: ldarg.0 - IL_00b2: ldnull - IL_00b3: stfld class [mscorlib]System.Tuple`2 Linq101Select01/digitOddEvens@46::current - IL_00b8: ldc.i4.0 - IL_00b9: ret - } // end of method digitOddEvens@46::GenerateNext + IL_0091: ldarg.0 + IL_0092: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_0097: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_009c: nop + IL_009d: ldarg.0 + IL_009e: ldnull + IL_009f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_00a4: ldarg.0 + IL_00a5: ldc.i4.3 + IL_00a6: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc + IL_00ab: ldarg.0 + IL_00ac: ldnull + IL_00ad: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #4 input at line 44@46'::current + IL_00b2: ldc.i4.0 + IL_00b3: ret + } // end of method 'Pipe #4 input at line 44@46'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/digitOddEvens@46::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/digitOddEvens@46::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/digitOddEvens@46::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #4 input at line 44@46'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/digitOddEvens@46::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [mscorlib]System.Tuple`2 Linq101Select01/digitOddEvens@46::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #4 input at line 44@46'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 46,46 : 9,42 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 46,46 : 9,42 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method digitOddEvens@46::Close + IL_007f: ret + } // end of method 'Pipe #4 input at line 44@46'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/digitOddEvens@46::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #4 input at line 44@46'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method digitOddEvens@46::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #4 input at line 44@46'::get_CheckClose .method public strict virtual instance class [mscorlib]System.Tuple`2 get_LastGenerated() cil managed @@ -1863,9 +1773,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld class [mscorlib]System.Tuple`2 Linq101Select01/digitOddEvens@46::current + IL_0001: ldfld class [mscorlib]System.Tuple`2 Linq101Select01/'Pipe #4 input at line 44@46'::current IL_0006: ret - } // end of method digitOddEvens@46::get_LastGenerated + } // end of method 'Pipe #4 input at line 44@46'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1> GetFreshEnumerator() cil managed @@ -1877,17 +1787,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Select01/digitOddEvens@46::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`2) + IL_0003: newobj instance void Linq101Select01/'Pipe #4 input at line 44@46'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`2) IL_0008: ret - } // end of method digitOddEvens@46::GetFreshEnumerator + } // end of method 'Pipe #4 input at line 44@46'::GetFreshEnumerator - } // end of class digitOddEvens@46 + } // end of class 'Pipe #4 input at line 44@46' - .class auto ansi serializable sealed nested assembly beforefieldinit 'productInfos@52-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #5 input at line 51@52-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Select01/'Pipe #5 input at line 51@52-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1898,7 +1809,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'productInfos@52-1'::.ctor + } // end of method 'Pipe #5 input at line 51@52-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -1914,11 +1825,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'productInfos@52-1'::Invoke + } // end of method 'Pipe #5 input at line 51@52-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #5 input at line 51@52-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #5 input at line 51@52-1' Linq101Select01/'Pipe #5 input at line 51@52-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #5 input at line 51@52-1'::.cctor - } // end of class 'productInfos@52-1' + } // end of class 'Pipe #5 input at line 51@52-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname productInfos@53 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #5 input at line 51@53' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1> { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -1943,287 +1864,257 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Select01/productInfos@53::pc + IL_0009: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld class [mscorlib]System.Tuple`3 Linq101Select01/productInfos@53::current + IL_0010: stfld class [mscorlib]System.Tuple`3 Linq101Select01/'Pipe #5 input at line 51@53'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1>::.ctor() IL_001b: ret - } // end of method productInfos@53::.ctor + } // end of method 'Pipe #5 input at line 51@53'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed { - // Code size 187 (0xbb) + // Code size 181 (0xb5) .maxstack 8 .locals init ([0] class [Utils]Utils/Product p) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/productInfos@53::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0091 + IL_001b: nop + IL_001c: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_008e + IL_001e: nop + IL_001f: br.s IL_0088 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00b2 + IL_0021: nop + IL_0022: br IL_00ac .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 53,53 : 9,56 '' - IL_002e: ldarg.0 - IL_002f: newobj instance void Linq101Select01/'productInfos@52-1'::.ctor() - IL_0034: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_products() - IL_0039: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0028: ldarg.0 + IL_0029: ldsfld class Linq101Select01/'Pipe #5 input at line 51@52-1' Linq101Select01/'Pipe #5 input at line 51@52-1'::@_instance + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_products() + IL_0033: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0043: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_0048: ldarg.0 - IL_0049: ldc.i4.1 - IL_004a: stfld int32 Linq101Select01/productInfos@53::pc + IL_0038: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc .line 53,53 : 9,56 '' - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_0055: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_005a: brfalse.s IL_0091 - - IL_005c: ldarg.0 - IL_005d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_0062: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0067: stloc.0 - IL_0068: ldarg.0 - IL_0069: ldc.i4.2 - IL_006a: stfld int32 Linq101Select01/productInfos@53::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_004f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0054: brfalse.s IL_008b + + IL_0056: ldarg.0 + IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0061: stloc.0 .line 53,53 : 17,55 '' - IL_006f: ldarg.0 + IL_0062: ldarg.0 + IL_0063: ldc.i4.2 + IL_0064: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc + IL_0069: ldarg.0 + IL_006a: ldloc.0 + IL_006b: callvirt instance string [Utils]Utils/Product::get_ProductName() IL_0070: ldloc.0 - IL_0071: callvirt instance string [Utils]Utils/Product::get_ProductName() + IL_0071: callvirt instance string [Utils]Utils/Product::get_Category() IL_0076: ldloc.0 - IL_0077: callvirt instance string [Utils]Utils/Product::get_Category() - IL_007c: ldloc.0 - IL_007d: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() - IL_0082: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, + IL_0077: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() + IL_007c: newobj instance void class [mscorlib]System.Tuple`3::.ctor(!0, !1, !2) - IL_0087: stfld class [mscorlib]System.Tuple`3 Linq101Select01/productInfos@53::current - IL_008c: ldc.i4.1 - IL_008d: ret + IL_0081: stfld class [mscorlib]System.Tuple`3 Linq101Select01/'Pipe #5 input at line 51@53'::current + IL_0086: ldc.i4.1 + IL_0087: ret .line 100001,100001 : 0,0 '' - IL_008e: nop - IL_008f: br.s IL_004f + IL_0088: nop + IL_0089: br.s IL_0049 - IL_0091: ldarg.0 - IL_0092: ldc.i4.3 - IL_0093: stfld int32 Linq101Select01/productInfos@53::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.3 + IL_008d: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc .line 53,53 : 9,56 '' - IL_0098: ldarg.0 - IL_0099: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_009e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_00a3: nop - IL_00a4: ldarg.0 - IL_00a5: ldnull - IL_00a6: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.3 - IL_00ad: stfld int32 Linq101Select01/productInfos@53::pc - IL_00b2: ldarg.0 - IL_00b3: ldnull - IL_00b4: stfld class [mscorlib]System.Tuple`3 Linq101Select01/productInfos@53::current - IL_00b9: ldc.i4.0 - IL_00ba: ret - } // end of method productInfos@53::GenerateNext + IL_0092: ldarg.0 + IL_0093: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_0098: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_009d: nop + IL_009e: ldarg.0 + IL_009f: ldnull + IL_00a0: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_00a5: ldarg.0 + IL_00a6: ldc.i4.3 + IL_00a7: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc + IL_00ac: ldarg.0 + IL_00ad: ldnull + IL_00ae: stfld class [mscorlib]System.Tuple`3 Linq101Select01/'Pipe #5 input at line 51@53'::current + IL_00b3: ldc.i4.0 + IL_00b4: ret + } // end of method 'Pipe #5 input at line 51@53'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/productInfos@53::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Select01/productInfos@53::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Select01/productInfos@53::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/productInfos@53::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Select01/'Pipe #5 input at line 51@53'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Select01/productInfos@53::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld class [mscorlib]System.Tuple`3 Linq101Select01/productInfos@53::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld class [mscorlib]System.Tuple`3 Linq101Select01/'Pipe #5 input at line 51@53'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 53,53 : 9,56 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 + IL_0070: nop + IL_0071: br IL_0000 - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 53,53 : 9,56 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method productInfos@53::Close + IL_007f: ret + } // end of method 'Pipe #5 input at line 51@53'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Select01/productInfos@53::pc + IL_0001: ldfld int32 Linq101Select01/'Pipe #5 input at line 51@53'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method productInfos@53::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #5 input at line 51@53'::get_CheckClose .method public strict virtual instance class [mscorlib]System.Tuple`3 get_LastGenerated() cil managed @@ -2233,9 +2124,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld class [mscorlib]System.Tuple`3 Linq101Select01/productInfos@53::current + IL_0001: ldfld class [mscorlib]System.Tuple`3 Linq101Select01/'Pipe #5 input at line 51@53'::current IL_0006: ret - } // end of method productInfos@53::get_LastGenerated + } // end of method 'Pipe #5 input at line 51@53'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1> GetFreshEnumerator() cil managed @@ -2247,15 +2138,15 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Select01/productInfos@53::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`3) + IL_0003: newobj instance void Linq101Select01/'Pipe #5 input at line 51@53'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`3) IL_0008: ret - } // end of method productInfos@53::GetFreshEnumerator + } // end of method 'Pipe #5 input at line 51@53'::GetFreshEnumerator - } // end of class productInfos@53 + } // end of class 'Pipe #5 input at line 51@53' - .class auto ansi serializable sealed nested assembly beforefieldinit lowNums@60 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@60' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2273,9 +2164,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/lowNums@60::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #6 input at line 59@60'::builder@ IL_000d: ret - } // end of method lowNums@60::.ctor + } // end of method 'Pipe #6 input at line 59@60'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(int32 _arg1) cil managed @@ -2288,18 +2179,19 @@ IL_0001: stloc.0 .line 61,61 : 9,22 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/lowNums@60::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #6 input at line 59@60'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method lowNums@60::Invoke + } // end of method 'Pipe #6 input at line 59@60'::Invoke - } // end of class lowNums@60 + } // end of class 'Pipe #6 input at line 59@60' - .class auto ansi serializable sealed nested assembly beforefieldinit 'lowNums@61-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@61-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Select01/'Pipe #6 input at line 59@61-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2310,7 +2202,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'lowNums@61-1'::.ctor + } // end of method 'Pipe #6 input at line 59@61-1'::.ctor .method public strict virtual instance bool Invoke(int32 n) cil managed @@ -2322,13 +2214,24 @@ IL_0001: ldc.i4.5 IL_0002: clt IL_0004: ret - } // end of method 'lowNums@61-1'::Invoke + } // end of method 'Pipe #6 input at line 59@61-1'::Invoke - } // end of class 'lowNums@61-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #6 input at line 59@61-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #6 input at line 59@61-1' Linq101Select01/'Pipe #6 input at line 59@61-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 59@61-1'::.cctor - .class auto ansi serializable sealed nested assembly beforefieldinit 'lowNums@62-2' + } // end of class 'Pipe #6 input at line 59@61-1' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #6 input at line 59@62-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Select01/'Pipe #6 input at line 59@62-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2339,7 +2242,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'lowNums@62-2'::.ctor + } // end of method 'Pipe #6 input at line 59@62-2'::.ctor .method public strict virtual instance string Invoke(int32 n) cil managed @@ -2352,11 +2255,21 @@ IL_0006: tail. IL_0008: callvirt instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Item(int32) IL_000d: ret - } // end of method 'lowNums@62-2'::Invoke + } // end of method 'Pipe #6 input at line 59@62-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #6 input at line 59@62-2'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #6 input at line 59@62-2' Linq101Select01/'Pipe #6 input at line 59@62-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #6 input at line 59@62-2'::.cctor - } // end of class 'lowNums@62-2' + } // end of class 'Pipe #6 input at line 59@62-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'pairs@73-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 71@73-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2376,12 +2289,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'pairs@73-1'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@73-1'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 Linq101Select01/'pairs@73-1'::a + IL_000f: stfld int32 Linq101Select01/'Pipe #7 input at line 71@73-1'::a IL_0014: ret - } // end of method 'pairs@73-1'::.ctor + } // end of method 'Pipe #7 input at line 71@73-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(int32 _arg2) cil managed @@ -2394,20 +2307,20 @@ IL_0001: stloc.0 .line 74,74 : 9,22 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'pairs@73-1'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@73-1'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld int32 Linq101Select01/'pairs@73-1'::a + IL_0009: ldfld int32 Linq101Select01/'Pipe #7 input at line 71@73-1'::a IL_000e: ldloc.0 IL_000f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0014: tail. IL_0016: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_001b: ret - } // end of method 'pairs@73-1'::Invoke + } // end of method 'Pipe #7 input at line 71@73-1'::Invoke - } // end of class 'pairs@73-1' + } // end of class 'Pipe #7 input at line 71@73-1' - .class auto ansi serializable sealed nested assembly beforefieldinit pairs@72 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 71@72' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2425,9 +2338,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/pairs@72::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@72'::builder@ IL_000d: ret - } // end of method pairs@72::.ctor + } // end of method 'Pipe #7 input at line 71@72'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> Invoke(int32 _arg1) cil managed @@ -2440,27 +2353,28 @@ IL_0001: stloc.0 .line 73,73 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/pairs@72::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@72'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/pairs@72::builder@ + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@72'::builder@ IL_000e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbersB() IL_0013: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0018: ldarg.0 - IL_0019: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/pairs@72::builder@ + IL_0019: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #7 input at line 71@72'::builder@ IL_001e: ldloc.0 - IL_001f: newobj instance void Linq101Select01/'pairs@73-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - int32) + IL_001f: newobj instance void Linq101Select01/'Pipe #7 input at line 71@73-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + int32) IL_0024: tail. IL_0026: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_002b: ret - } // end of method pairs@72::Invoke + } // end of method 'Pipe #7 input at line 71@72'::Invoke - } // end of class pairs@72 + } // end of class 'Pipe #7 input at line 71@72' - .class auto ansi serializable sealed nested assembly beforefieldinit 'pairs@74-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 71@74-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Select01/'Pipe #7 input at line 71@74-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2471,7 +2385,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'pairs@74-2'::.ctor + } // end of method 'Pipe #7 input at line 71@74-2'::.ctor .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -2492,13 +2406,24 @@ IL_000f: ldloc.1 IL_0010: clt IL_0012: ret - } // end of method 'pairs@74-2'::Invoke + } // end of method 'Pipe #7 input at line 71@74-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #7 input at line 71@74-2'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #7 input at line 71@74-2' Linq101Select01/'Pipe #7 input at line 71@74-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #7 input at line 71@74-2'::.cctor - } // end of class 'pairs@74-2' + } // end of class 'Pipe #7 input at line 71@74-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'pairs@75-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #7 input at line 71@75-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Select01/'Pipe #7 input at line 71@75-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2509,7 +2434,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2>::.ctor() IL_0006: ret - } // end of method 'pairs@75-3'::.ctor + } // end of method 'Pipe #7 input at line 71@75-3'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`2 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -2531,11 +2456,21 @@ IL_0010: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0015: ret - } // end of method 'pairs@75-3'::Invoke + } // end of method 'Pipe #7 input at line 71@75-3'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #7 input at line 71@75-3'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #7 input at line 71@75-3' Linq101Select01/'Pipe #7 input at line 71@75-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #7 input at line 71@75-3'::.cctor - } // end of class 'pairs@75-3' + } // end of class 'Pipe #7 input at line 71@75-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders@83-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #8 input at line 81@83-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2555,12 +2490,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@83-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@83-1'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [Utils]Utils/Customer Linq101Select01/'orders@83-3'::c + IL_000f: stfld class [Utils]Utils/Customer Linq101Select01/'Pipe #8 input at line 81@83-1'::c IL_0014: ret - } // end of method 'orders@83-3'::.ctor + } // end of method 'Pipe #8 input at line 81@83-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [Utils]Utils/Order _arg2) cil managed @@ -2573,20 +2508,20 @@ IL_0001: stloc.0 .line 84,84 : 9,34 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@83-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@83-1'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [Utils]Utils/Customer Linq101Select01/'orders@83-3'::c + IL_0009: ldfld class [Utils]Utils/Customer Linq101Select01/'Pipe #8 input at line 81@83-1'::c IL_000e: ldloc.0 IL_000f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0014: tail. IL_0016: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_001b: ret - } // end of method 'orders@83-3'::Invoke + } // end of method 'Pipe #8 input at line 81@83-1'::Invoke - } // end of class 'orders@83-3' + } // end of class 'Pipe #8 input at line 81@83-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders@82-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #8 input at line 81@82' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2604,9 +2539,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@82-2'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@82'::builder@ IL_000d: ret - } // end of method 'orders@82-2'::.ctor + } // end of method 'Pipe #8 input at line 81@82'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -2619,28 +2554,29 @@ IL_0001: stloc.0 .line 83,83 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@82-2'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@82'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@82-2'::builder@ + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@82'::builder@ IL_000e: ldloc.0 IL_000f: callvirt instance class [Utils]Utils/Order[] [Utils]Utils/Customer::get_Orders() IL_0014: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0019: ldarg.0 - IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders@82-2'::builder@ + IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #8 input at line 81@82'::builder@ IL_001f: ldloc.0 - IL_0020: newobj instance void Linq101Select01/'orders@83-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [Utils]Utils/Customer) + IL_0020: newobj instance void Linq101Select01/'Pipe #8 input at line 81@83-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [Utils]Utils/Customer) IL_0025: tail. IL_0027: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_002c: ret - } // end of method 'orders@82-2'::Invoke + } // end of method 'Pipe #8 input at line 81@82'::Invoke - } // end of class 'orders@82-2' + } // end of class 'Pipe #8 input at line 81@82' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders@84-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #8 input at line 81@84-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Select01/'Pipe #8 input at line 81@84-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2651,7 +2587,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'orders@84-4'::.ctor + } // end of method 'Pipe #8 input at line 81@84-2'::.ctor .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -2675,21 +2611,32 @@ IL_001a: ldc.i4.0 IL_001b: ldc.i4.0 IL_001c: ldc.i4.2 - IL_001d: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0022: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_001d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0022: call bool [netstandard]System.Decimal::op_LessThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0027: ret - } // end of method 'orders@84-4'::Invoke + } // end of method 'Pipe #8 input at line 81@84-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #8 input at line 81@84-2'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #8 input at line 81@84-2' Linq101Select01/'Pipe #8 input at line 81@84-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #8 input at line 81@84-2'::.cctor - } // end of class 'orders@84-4' + } // end of class 'Pipe #8 input at line 81@84-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders@85-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #8 input at line 81@85-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> { + .field static assembly initonly class Linq101Select01/'Pipe #8 input at line 81@85-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2700,7 +2647,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() IL_0006: ret - } // end of method 'orders@85-5'::.ctor + } // end of method 'Pipe #8 input at line 81@85-3'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`3 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -2727,11 +2674,21 @@ !1, !2) IL_0025: ret - } // end of method 'orders@85-5'::Invoke + } // end of method 'Pipe #8 input at line 81@85-3'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #8 input at line 81@85-3'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #8 input at line 81@85-3' Linq101Select01/'Pipe #8 input at line 81@85-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #8 input at line 81@85-3'::.cctor - } // end of class 'orders@85-5' + } // end of class 'Pipe #8 input at line 81@85-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders2@92-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #9 input at line 90@92-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2751,12 +2708,12 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders2@92-1'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@92-1'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld class [Utils]Utils/Customer Linq101Select01/'orders2@92-1'::c + IL_000f: stfld class [Utils]Utils/Customer Linq101Select01/'Pipe #9 input at line 90@92-1'::c IL_0014: ret - } // end of method 'orders2@92-1'::.ctor + } // end of method 'Pipe #9 input at line 90@92-1'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,object> Invoke(class [Utils]Utils/Order _arg2) cil managed @@ -2769,20 +2726,20 @@ IL_0001: stloc.0 .line 93,93 : 9,51 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'orders2@92-1'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@92-1'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [Utils]Utils/Customer Linq101Select01/'orders2@92-1'::c + IL_0009: ldfld class [Utils]Utils/Customer Linq101Select01/'Pipe #9 input at line 90@92-1'::c IL_000e: ldloc.0 IL_000f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) IL_0014: tail. IL_0016: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,object>(!!0) IL_001b: ret - } // end of method 'orders2@92-1'::Invoke + } // end of method 'Pipe #9 input at line 90@92-1'::Invoke - } // end of class 'orders2@92-1' + } // end of class 'Pipe #9 input at line 90@92-1' - .class auto ansi serializable sealed nested assembly beforefieldinit orders2@91 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #9 input at line 90@91' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -2800,9 +2757,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Collections.IEnumerable>>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/orders2@91::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@91'::builder@ IL_000d: ret - } // end of method orders2@91::.ctor + } // end of method 'Pipe #9 input at line 90@91'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -2815,28 +2772,29 @@ IL_0001: stloc.0 .line 92,92 : 9,29 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/orders2@91::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@91'::builder@ IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/orders2@91::builder@ + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@91'::builder@ IL_000e: ldloc.0 IL_000f: callvirt instance class [Utils]Utils/Order[] [Utils]Utils/Customer::get_Orders() IL_0014: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0019: ldarg.0 - IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/orders2@91::builder@ + IL_001a: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Select01/'Pipe #9 input at line 90@91'::builder@ IL_001f: ldloc.0 - IL_0020: newobj instance void Linq101Select01/'orders2@92-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, - class [Utils]Utils/Customer) + IL_0020: newobj instance void Linq101Select01/'Pipe #9 input at line 90@92-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder, + class [Utils]Utils/Customer) IL_0025: tail. IL_0027: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_002c: ret - } // end of method orders2@91::Invoke + } // end of method 'Pipe #9 input at line 90@91'::Invoke - } // end of class orders2@91 + } // end of class 'Pipe #9 input at line 90@91' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders2@93-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #9 input at line 90@93-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Select01/'Pipe #9 input at line 90@93-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2847,15 +2805,17 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool>::.ctor() IL_0006: ret - } // end of method 'orders2@93-2'::.ctor + } // end of method 'Pipe #9 input at line 90@93-2'::.ctor .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed { - // Code size 40 (0x28) - .maxstack 8 + // Code size 48 (0x30) + .maxstack 7 .locals init ([0] class [Utils]Utils/Customer c, - [1] class [Utils]Utils/Order o) + [1] class [Utils]Utils/Order o, + [2] valuetype [mscorlib]System.DateTime V_2, + [3] valuetype [mscorlib]System.DateTime V_3) .line 100001,100001 : 0,0 '' IL_0000: ldarg.1 IL_0001: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() @@ -2866,23 +2826,41 @@ .line 93,93 : 16,50 '' IL_000e: ldloc.1 IL_000f: callvirt instance valuetype [mscorlib]System.DateTime [Utils]Utils/Order::get_OrderDate() - IL_0014: ldc.i4 0x7ce - IL_0019: ldc.i4.1 + IL_0014: stloc.2 + IL_0015: ldc.i4 0x7ce IL_001a: ldc.i4.1 - IL_001b: newobj instance void [mscorlib]System.DateTime::.ctor(int32, + IL_001b: ldc.i4.1 + IL_001c: newobj instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32) - IL_0020: tail. - IL_0022: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericGreaterOrEqualIntrinsic(!!0, - !!0) - IL_0027: ret - } // end of method 'orders2@93-2'::Invoke + IL_0021: stloc.3 + IL_0022: ldloc.2 + IL_0023: ldloc.3 + IL_0024: call int32 [netstandard]System.DateTime::Compare(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_0029: ldc.i4.0 + IL_002a: clt + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: ret + } // end of method 'Pipe #9 input at line 90@93-2'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #9 input at line 90@93-2'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #9 input at line 90@93-2' Linq101Select01/'Pipe #9 input at line 90@93-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #9 input at line 90@93-2'::.cctor - } // end of class 'orders2@93-2' + } // end of class 'Pipe #9 input at line 90@93-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'orders2@94-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #9 input at line 90@94-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> { + .field static assembly initonly class Linq101Select01/'Pipe #9 input at line 90@94-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -2893,7 +2871,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3>::.ctor() IL_0006: ret - } // end of method 'orders2@94-3'::.ctor + } // end of method 'Pipe #9 input at line 90@94-3'::.ctor .method public strict virtual instance class [mscorlib]System.Tuple`3 Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed @@ -2920,9 +2898,19 @@ !1, !2) IL_0025: ret - } // end of method 'orders2@94-3'::Invoke + } // end of method 'Pipe #9 input at line 90@94-3'::Invoke - } // end of class 'orders2@94-3' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'Pipe #9 input at line 90@94-3'::.ctor() + IL_0005: stsfld class Linq101Select01/'Pipe #9 input at line 90@94-3' Linq101Select01/'Pipe #9 input at line 90@94-3'::@_instance + IL_000a: ret + } // end of method 'Pipe #9 input at line 90@94-3'::.cctor + + } // end of class 'Pipe #9 input at line 90@94-3' .class auto ansi serializable sealed nested assembly beforefieldinit 'orders3@101-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,object>> @@ -3030,6 +3018,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'orders3@102-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Select01/'orders3@102-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3064,21 +3053,32 @@ IL_001a: ldc.i4.0 IL_001b: ldc.i4.0 IL_001c: ldc.i4.1 - IL_001d: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0022: call bool [mscorlib]System.Decimal::op_GreaterThanOrEqual(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) + IL_001d: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_0022: call bool [netstandard]System.Decimal::op_GreaterThanOrEqual(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) IL_0027: ret } // end of method 'orders3@102-2'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'orders3@102-2'::.ctor() + IL_0005: stsfld class Linq101Select01/'orders3@102-2' Linq101Select01/'orders3@102-2'::@_instance + IL_000a: ret + } // end of method 'orders3@102-2'::.cctor + } // end of class 'orders3@102-2' .class auto ansi serializable sealed nested assembly beforefieldinit 'orders3@103-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`3> { + .field static assembly initonly class Linq101Select01/'orders3@103-3' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3118,6 +3118,16 @@ IL_0025: ret } // end of method 'orders3@103-3'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'orders3@103-3'::.ctor() + IL_0005: stsfld class Linq101Select01/'orders3@103-3' Linq101Select01/'orders3@103-3'::@_instance + IL_000a: ret + } // end of method 'orders3@103-3'::.cctor + } // end of class 'orders3@103-3' .class auto ansi serializable sealed nested assembly beforefieldinit orders4@111 @@ -3165,6 +3175,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'orders4@112-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Select01/'orders4@112-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3186,11 +3197,21 @@ IL_0000: ldarg.1 IL_0001: callvirt instance string [Utils]Utils/Customer::get_Region() IL_0006: ldstr "WA" - IL_000b: call bool [mscorlib]System.String::Equals(string, - string) + IL_000b: call bool [netstandard]System.String::Equals(string, + string) IL_0010: ret } // end of method 'orders4@112-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'orders4@112-1'::.ctor() + IL_0005: stsfld class Linq101Select01/'orders4@112-1' Linq101Select01/'orders4@112-1'::@_instance + IL_000a: ret + } // end of method 'orders4@112-1'::.cctor + } // end of class 'orders4@112-1' .class auto ansi serializable sealed nested assembly beforefieldinit 'orders4@113-3' @@ -3298,6 +3319,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'orders4@114-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,bool> { + .field static assembly initonly class Linq101Select01/'orders4@114-4' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3313,10 +3335,12 @@ .method public strict virtual instance bool Invoke(class [mscorlib]System.Tuple`2 tupledArg) cil managed { - // Code size 33 (0x21) + // Code size 41 (0x29) .maxstack 6 .locals init ([0] class [Utils]Utils/Customer c, - [1] class [Utils]Utils/Order o) + [1] class [Utils]Utils/Order o, + [2] valuetype [mscorlib]System.DateTime V_2, + [3] valuetype [mscorlib]System.DateTime V_3) .line 100001,100001 : 0,0 '' IL_0000: ldarg.1 IL_0001: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() @@ -3327,18 +3351,36 @@ .line 114,114 : 16,41 '' IL_000e: ldloc.1 IL_000f: callvirt instance valuetype [mscorlib]System.DateTime [Utils]Utils/Order::get_OrderDate() - IL_0014: call valuetype [mscorlib]System.DateTime Linq101Select01::get_cutOffDate() - IL_0019: tail. - IL_001b: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericGreaterOrEqualIntrinsic(!!0, - !!0) - IL_0020: ret + IL_0014: stloc.2 + IL_0015: call valuetype [mscorlib]System.DateTime Linq101Select01::get_cutOffDate() + IL_001a: stloc.3 + IL_001b: ldloc.2 + IL_001c: ldloc.3 + IL_001d: call int32 [netstandard]System.DateTime::Compare(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_0022: ldc.i4.0 + IL_0023: clt + IL_0025: ldc.i4.0 + IL_0026: ceq + IL_0028: ret } // end of method 'orders4@114-4'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'orders4@114-4'::.ctor() + IL_0005: stsfld class Linq101Select01/'orders4@114-4' Linq101Select01/'orders4@114-4'::@_instance + IL_000a: ret + } // end of method 'orders4@114-4'::.cctor + } // end of class 'orders4@114-4' .class auto ansi serializable sealed nested assembly beforefieldinit 'orders4@115-5' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [mscorlib]System.Tuple`2> { + .field static assembly initonly class Linq101Select01/'orders4@115-5' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -3375,6 +3417,16 @@ IL_001f: ret } // end of method 'orders4@115-5'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Select01/'orders4@115-5'::.ctor() + IL_0005: stsfld class Linq101Select01/'orders4@115-5' Linq101Select01/'orders4@115-5'::@_instance + IL_000a: ret + } // end of method 'orders4@115-5'::.cctor + } // end of class 'orders4@115-5' .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -3382,7 +3434,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'numbers@7-9' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbers@7 IL_0005: ret } // end of method Linq101Select01::get_numbers @@ -3400,7 +3452,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'products@17-12' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::products@17 IL_0005: ret } // end of method Linq101Select01::get_products @@ -3418,7 +3470,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'strings@26-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::strings@26 IL_0005: ret } // end of method Linq101Select01::get_strings @@ -3436,7 +3488,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'words@34-8' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::words@34 IL_0005: ret } // end of method Linq101Select01::get_words @@ -3472,7 +3524,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'digits@57-4' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::digits@57 IL_0005: ret } // end of method Linq101Select01::get_digits @@ -3517,7 +3569,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'customers@79-4' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::customers@79 IL_0005: ret } // end of method Linq101Select01::get_customers @@ -3697,19 +3749,19 @@ .class private abstract auto ansi sealed ''.$Linq101Select01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers@7-9' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers@7 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numsPlusOne@10 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@17-12' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@17 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Collections.Generic.IEnumerable`1 productNames@19 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'strings@26-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 strings@26 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 textNums@27 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'words@34-8' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 words@34 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] upperLowerWords@36 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -3717,7 +3769,7 @@ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`3[] productInfos@50 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'digits@57-4' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits@57 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 lowNums@58 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -3727,7 +3779,7 @@ .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`2[] pairs@70 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'customers@79-4' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers@79 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Tuple`3[] orders@80 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -3746,7 +3798,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 1128 (0x468) + // Code size 1170 (0x492) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numsPlusOne, @@ -3769,20 +3821,29 @@ [18] class [mscorlib]System.Collections.Generic.IEnumerable`1> orders3, [19] valuetype [mscorlib]System.DateTime cutOffDate, [20] class [mscorlib]System.Collections.Generic.IEnumerable`1> orders4, - [21] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_21, + [21] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 11', [22] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_22, [23] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_23, - [24] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_24, + [24] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #2 input at line 28', [25] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_25, - [26] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_26, + [26] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #3 input at line 37', [27] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_27, - [28] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_28, - [29] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_29, - [30] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_30, + [28] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #4 input at line 44', + [29] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_29, + [30] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #5 input at line 51', [31] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_31, - [32] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_32, + [32] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #6 input at line 59', [33] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_33, - [34] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_34) + [34] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_34, + [35] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_35, + [36] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #7 input at line 71', + [37] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_37, + [38] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #8 input at line 81', + [39] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_39, + [40] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #9 input at line 90', + [41] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_41, + [42] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_42, + [43] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_43) .line 7,7 : 1,47 '' IL_0000: ldc.i4.5 IL_0001: ldc.i4.4 @@ -3816,51 +3877,54 @@ IL_003d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0042: dup - IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'numbers@7-9' + IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbers@7 IL_0048: stloc.0 .line 10,14 : 1,20 '' - IL_0049: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_004e: stloc.s V_21 - IL_0050: ldnull - IL_0051: ldc.i4.0 + IL_0049: nop + .line 11,11 : 5,10 '' + IL_004a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_004f: stloc.s V_22 + IL_0051: ldnull IL_0052: ldc.i4.0 - IL_0053: newobj instance void Linq101Select01/numsPlusOne@13::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_0058: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_005d: dup - IL_005e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numsPlusOne@10 - IL_0063: stloc.1 + IL_0053: ldc.i4.0 + IL_0054: newobj instance void Linq101Select01/'Pipe #1 input at line 11@13'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_0059: stloc.s 'Pipe #1 input at line 11' + .line 14,14 : 10,20 '' + IL_005b: ldloc.s 'Pipe #1 input at line 11' + IL_005d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0062: dup + IL_0063: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numsPlusOne@10 + IL_0068: stloc.1 .line 17,17 : 1,32 '' - IL_0064: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_0069: dup - IL_006a: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'products@17-12' - IL_006f: stloc.2 - IL_0070: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0075: stloc.s V_22 - IL_0077: ldnull - IL_0078: ldc.i4.0 - IL_0079: ldnull - IL_007a: newobj instance void Linq101Select01/productNames@22::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0069: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_006e: dup + IL_006f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::products@17 + IL_0074: stloc.2 + IL_0075: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_007a: stloc.s V_23 + IL_007c: ldnull + IL_007d: ldc.i4.0 + IL_007e: ldnull + IL_007f: newobj instance void Linq101Select01/productNames@22::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_007f: dup - IL_0080: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Select01::productNames@19 - IL_0085: stloc.3 + IL_0084: dup + IL_0085: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Select01::productNames@19 + IL_008a: stloc.3 .line 26,26 : 1,97 '' - IL_0086: ldstr "zero" - IL_008b: ldstr "one" - IL_0090: ldstr "two" - IL_0095: ldstr "three" - IL_009a: ldstr "four" - IL_009f: ldstr "five" - IL_00a4: ldstr "six" - IL_00a9: ldstr "seven" - IL_00ae: ldstr "eight" - IL_00b3: ldstr "nine" - IL_00b8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_00bd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_008b: ldstr "zero" + IL_0090: ldstr "one" + IL_0095: ldstr "two" + IL_009a: ldstr "three" + IL_009f: ldstr "four" + IL_00a4: ldstr "five" + IL_00a9: ldstr "six" + IL_00ae: ldstr "seven" + IL_00b3: ldstr "eight" + IL_00b8: ldstr "nine" + IL_00bd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_00c2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_00c7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -3879,339 +3943,379 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_00ea: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_00ef: dup - IL_00f0: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'strings@26-2' - IL_00f5: stloc.s strings + IL_00ef: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_00f4: dup + IL_00f5: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::strings@26 + IL_00fa: stloc.s strings .line 27,31 : 1,20 '' - IL_00f7: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00fc: stloc.s V_23 - IL_00fe: ldnull - IL_00ff: ldc.i4.0 - IL_0100: ldnull - IL_0101: newobj instance void Linq101Select01/textNums@30::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_0106: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_010b: dup - IL_010c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::textNums@27 - IL_0111: stloc.s textNums + IL_00fc: nop + .line 28,28 : 5,10 '' + IL_00fd: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0102: stloc.s V_25 + IL_0104: ldnull + IL_0105: ldc.i4.0 + IL_0106: ldnull + IL_0107: newobj instance void Linq101Select01/'Pipe #2 input at line 28@30'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_010c: stloc.s 'Pipe #2 input at line 28' + .line 31,31 : 10,20 '' + IL_010e: ldloc.s 'Pipe #2 input at line 28' + IL_0110: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0115: dup + IL_0116: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::textNums@27 + IL_011b: stloc.s textNums .line 34,34 : 1,46 '' - IL_0113: ldstr "aPPLE" - IL_0118: ldstr "BlUeBeRrY" - IL_011d: ldstr "cHeRry" - IL_0122: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0127: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_011d: ldstr "aPPLE" + IL_0122: ldstr "BlUeBeRrY" + IL_0127: ldstr "cHeRry" + IL_012c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0131: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_012c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0136: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0131: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_013b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0136: dup - IL_0137: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'words@34-8' - IL_013c: stloc.s words + IL_0140: dup + IL_0141: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::words@34 + IL_0146: stloc.s words .line 36,40 : 1,20 '' - IL_013e: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0143: stloc.s V_24 - IL_0145: ldnull - IL_0146: ldc.i4.0 - IL_0147: ldnull - IL_0148: newobj instance void Linq101Select01/upperLowerWords@39::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`2) - IL_014d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0152: dup - IL_0153: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Select01::upperLowerWords@36 - IL_0158: stloc.s upperLowerWords + IL_0148: nop + .line 37,37 : 4,9 '' + IL_0149: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_014e: stloc.s V_27 + IL_0150: ldnull + IL_0151: ldc.i4.0 + IL_0152: ldnull + IL_0153: newobj instance void Linq101Select01/'Pipe #3 input at line 37@39'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`2) + IL_0158: stloc.s 'Pipe #3 input at line 37' + .line 40,40 : 9,20 '' + IL_015a: ldloc.s 'Pipe #3 input at line 37' + IL_015c: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0161: dup + IL_0162: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Select01::upperLowerWords@36 + IL_0167: stloc.s upperLowerWords .line 43,47 : 1,20 '' - IL_015a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_015f: stloc.s V_25 - IL_0161: ldnull - IL_0162: ldc.i4.0 - IL_0163: ldnull - IL_0164: newobj instance void Linq101Select01/digitOddEvens@46::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`2) - IL_0169: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_016e: dup - IL_016f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> ''.$Linq101Select01::digitOddEvens@43 - IL_0174: stloc.s digitOddEvens + IL_0169: nop + .line 44,44 : 5,10 '' + IL_016a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_016f: stloc.s V_29 + IL_0171: ldnull + IL_0172: ldc.i4.0 + IL_0173: ldnull + IL_0174: newobj instance void Linq101Select01/'Pipe #4 input at line 44@46'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`2) + IL_0179: stloc.s 'Pipe #4 input at line 44' + .line 47,47 : 10,20 '' + IL_017b: ldloc.s 'Pipe #4 input at line 44' + IL_017d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0182: dup + IL_0183: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> ''.$Linq101Select01::digitOddEvens@43 + IL_0188: stloc.s digitOddEvens .line 50,54 : 1,21 '' - IL_0176: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_017b: stloc.s V_26 - IL_017d: ldnull - IL_017e: ldc.i4.0 - IL_017f: ldnull - IL_0180: newobj instance void Linq101Select01/productInfos@53::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - class [mscorlib]System.Tuple`3) - IL_0185: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_018a: dup - IL_018b: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::productInfos@50 - IL_0190: stloc.s productInfos + IL_018a: nop + .line 51,51 : 5,10 '' + IL_018b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0190: stloc.s V_31 + IL_0192: ldnull + IL_0193: ldc.i4.0 + IL_0194: ldnull + IL_0195: newobj instance void Linq101Select01/'Pipe #5 input at line 51@53'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + class [mscorlib]System.Tuple`3) + IL_019a: stloc.s 'Pipe #5 input at line 51' + .line 54,54 : 10,21 '' + IL_019c: ldloc.s 'Pipe #5 input at line 51' + IL_019e: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01a3: dup + IL_01a4: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::productInfos@50 + IL_01a9: stloc.s productInfos .line 57,57 : 1,21 '' - IL_0192: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() - IL_0197: dup - IL_0198: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'digits@57-4' - IL_019d: stloc.s digits + IL_01ab: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_strings() + IL_01b0: dup + IL_01b1: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::digits@57 + IL_01b6: stloc.s digits .line 58,63 : 1,20 '' - IL_019f: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_01a4: stloc.s V_27 - IL_01a6: ldloc.s V_27 - IL_01a8: ldloc.s V_27 - IL_01aa: ldloc.s V_27 - IL_01ac: ldloc.s V_27 - IL_01ae: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() - IL_01b3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01b8: ldloc.s V_27 - IL_01ba: newobj instance void Linq101Select01/lowNums@60::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_01bf: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01b8: nop + .line 59,59 : 5,10 '' + IL_01b9: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01be: stloc.s V_33 + IL_01c0: ldloc.s V_33 + IL_01c2: ldloc.s V_33 + IL_01c4: ldloc.s V_33 + IL_01c6: ldloc.s V_33 + IL_01c8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbers() + IL_01cd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01d2: ldloc.s V_33 + IL_01d4: newobj instance void Linq101Select01/'Pipe #6 input at line 59@60'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01d9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_01c4: newobj instance void Linq101Select01/'lowNums@61-1'::.ctor() - IL_01c9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01de: ldsfld class Linq101Select01/'Pipe #6 input at line 59@61-1' Linq101Select01/'Pipe #6 input at line 59@61-1'::@_instance + IL_01e3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01ce: newobj instance void Linq101Select01/'lowNums@62-2'::.ctor() - IL_01d3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01e8: ldsfld class Linq101Select01/'Pipe #6 input at line 59@62-2' Linq101Select01/'Pipe #6 input at line 59@62-2'::@_instance + IL_01ed: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_01d8: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_01dd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_01e2: dup - IL_01e3: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::lowNums@58 - IL_01e8: stloc.s lowNums + IL_01f2: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_01f7: stloc.s 'Pipe #6 input at line 59' + .line 63,63 : 10,20 '' + IL_01f9: ldloc.s 'Pipe #6 input at line 59' + IL_01fb: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0200: dup + IL_0201: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::lowNums@58 + IL_0206: stloc.s lowNums .line 64,64 : 1,59 '' - IL_01ea: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_lowNums() - IL_01ef: stloc.s V_28 - IL_01f1: ldstr "four" - IL_01f6: ldstr "one" - IL_01fb: ldstr "three" - IL_0200: ldstr "two" - IL_0205: ldstr "zero" - IL_020a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_020f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0208: nop + .line 100001,100001 : 0,0 '' + IL_0209: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_lowNums() + IL_020e: stloc.s V_34 + IL_0210: ldstr "four" + IL_0215: ldstr "one" + IL_021a: ldstr "three" + IL_021f: ldstr "two" + IL_0224: ldstr "zero" + IL_0229: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_022e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0214: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0233: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0219: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0238: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_021e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_023d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0223: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0242: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0228: stloc.s V_29 - IL_022a: ldloc.s V_28 - IL_022c: ldloc.s V_29 - IL_022e: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0233: callvirt instance bool class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Equals(object, + IL_0247: stloc.s V_35 + IL_0249: ldloc.s V_34 + IL_024b: ldloc.s V_35 + IL_024d: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0252: callvirt instance bool class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_0238: ldc.i4.0 - IL_0239: ceq - IL_023b: brfalse.s IL_023f - - IL_023d: br.s IL_0241 - - IL_023f: br.s IL_025b + IL_0257: ldc.i4.0 + IL_0258: ceq + IL_025a: brfalse.s IL_0276 .line 64,64 : 60,84 '' - IL_0241: ldstr "lowNums failed" - IL_0246: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_024b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0250: pop + IL_025c: ldstr "lowNums failed" + IL_0261: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0266: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_026b: pop .line 64,64 : 86,92 '' - IL_0251: ldc.i4.1 - IL_0252: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Exit(int32) - IL_0257: pop + IL_026c: ldc.i4.1 + IL_026d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Exit(int32) + IL_0272: pop .line 100001,100001 : 0,0 '' - IL_0258: nop - IL_0259: br.s IL_025c + IL_0273: nop + IL_0274: br.s IL_0277 .line 100001,100001 : 0,0 '' - IL_025b: nop + IL_0276: nop .line 67,67 : 1,37 '' - IL_025c: ldc.i4.0 - IL_025d: ldc.i4.2 - IL_025e: ldc.i4.4 - IL_025f: ldc.i4.5 - IL_0260: ldc.i4.6 - IL_0261: ldc.i4.8 - IL_0262: ldc.i4.s 9 - IL_0264: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0269: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0277: ldc.i4.0 + IL_0278: ldc.i4.2 + IL_0279: ldc.i4.4 + IL_027a: ldc.i4.5 + IL_027b: ldc.i4.6 + IL_027c: ldc.i4.8 + IL_027d: ldc.i4.s 9 + IL_027f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0284: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_026e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0289: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0273: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_028e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0278: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0293: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_027d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0298: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0282: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_029d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0287: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02a2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_028c: dup - IL_028d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbersA@67 - IL_0292: stloc.s numbersA + IL_02a7: dup + IL_02a8: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbersA@67 + IL_02ad: stloc.s numbersA .line 68,68 : 1,31 '' - IL_0294: ldc.i4.1 - IL_0295: ldc.i4.3 - IL_0296: ldc.i4.5 - IL_0297: ldc.i4.7 - IL_0298: ldc.i4.8 - IL_0299: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_029e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02af: ldc.i4.1 + IL_02b0: ldc.i4.3 + IL_02b1: ldc.i4.5 + IL_02b2: ldc.i4.7 + IL_02b3: ldc.i4.8 + IL_02b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_02b9: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_02a3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02be: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_02a8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02c3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_02ad: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02c8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_02b2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_02cd: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_02b7: dup - IL_02b8: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbersB@68 - IL_02bd: stloc.s numbersB + IL_02d2: dup + IL_02d3: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::numbersB@68 + IL_02d8: stloc.s numbersB .line 70,76 : 1,21 '' - IL_02bf: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_02c4: stloc.s V_30 - IL_02c6: ldloc.s V_30 - IL_02c8: ldloc.s V_30 - IL_02ca: ldloc.s V_30 - IL_02cc: ldloc.s V_30 - IL_02ce: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbersA() - IL_02d3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_02d8: ldloc.s V_30 - IL_02da: newobj instance void Linq101Select01/pairs@72::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_02df: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02da: nop + .line 71,71 : 5,10 '' + IL_02db: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_02e0: stloc.s V_37 + IL_02e2: ldloc.s V_37 + IL_02e4: ldloc.s V_37 + IL_02e6: ldloc.s V_37 + IL_02e8: ldloc.s V_37 + IL_02ea: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_numbersA() + IL_02ef: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_02f4: ldloc.s V_37 + IL_02f6: newobj instance void Linq101Select01/'Pipe #7 input at line 71@72'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_02fb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_02e4: newobj instance void Linq101Select01/'pairs@74-2'::.ctor() - IL_02e9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0300: ldsfld class Linq101Select01/'Pipe #7 input at line 71@74-2' Linq101Select01/'Pipe #7 input at line 71@74-2'::@_instance + IL_0305: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02ee: newobj instance void Linq101Select01/'pairs@75-3'::.ctor() - IL_02f3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_030a: ldsfld class Linq101Select01/'Pipe #7 input at line 71@75-3' Linq101Select01/'Pipe #7 input at line 71@75-3'::@_instance + IL_030f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02f8: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_02fd: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0302: dup - IL_0303: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Select01::pairs@70 - IL_0308: stloc.s pairs + IL_0314: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0319: stloc.s 'Pipe #7 input at line 71' + .line 76,76 : 10,21 '' + IL_031b: ldloc.s 'Pipe #7 input at line 71' + IL_031d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0322: dup + IL_0323: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Select01::pairs@70 + IL_0328: stloc.s pairs .line 79,79 : 1,34 '' - IL_030a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() - IL_030f: dup - IL_0310: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::'customers@79-4' - IL_0315: stloc.s customers + IL_032a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() + IL_032f: dup + IL_0330: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Select01::customers@79 + IL_0335: stloc.s customers .line 80,86 : 1,21 '' - IL_0317: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_031c: stloc.s V_31 - IL_031e: ldloc.s V_31 - IL_0320: ldloc.s V_31 - IL_0322: ldloc.s V_31 - IL_0324: ldloc.s V_31 - IL_0326: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() - IL_032b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0330: ldloc.s V_31 - IL_0332: newobj instance void Linq101Select01/'orders@82-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0337: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0337: nop + .line 81,81 : 5,10 '' + IL_0338: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_033d: stloc.s V_39 + IL_033f: ldloc.s V_39 + IL_0341: ldloc.s V_39 + IL_0343: ldloc.s V_39 + IL_0345: ldloc.s V_39 + IL_0347: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() + IL_034c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0351: ldloc.s V_39 + IL_0353: newobj instance void Linq101Select01/'Pipe #8 input at line 81@82'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0358: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_033c: newobj instance void Linq101Select01/'orders@84-4'::.ctor() - IL_0341: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_035d: ldsfld class Linq101Select01/'Pipe #8 input at line 81@84-2' Linq101Select01/'Pipe #8 input at line 81@84-2'::@_instance + IL_0362: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0346: newobj instance void Linq101Select01/'orders@85-5'::.ctor() - IL_034b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0367: ldsfld class Linq101Select01/'Pipe #8 input at line 81@85-3' Linq101Select01/'Pipe #8 input at line 81@85-3'::@_instance + IL_036c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0350: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0355: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_035a: dup - IL_035b: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::orders@80 - IL_0360: stloc.s orders + IL_0371: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0376: stloc.s 'Pipe #8 input at line 81' + .line 86,86 : 10,21 '' + IL_0378: ldloc.s 'Pipe #8 input at line 81' + IL_037a: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_037f: dup + IL_0380: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::orders@80 + IL_0385: stloc.s orders .line 89,95 : 1,21 '' - IL_0362: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0367: stloc.s V_32 - IL_0369: ldloc.s V_32 - IL_036b: ldloc.s V_32 - IL_036d: ldloc.s V_32 - IL_036f: ldloc.s V_32 - IL_0371: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() - IL_0376: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_037b: ldloc.s V_32 - IL_037d: newobj instance void Linq101Select01/orders2@91::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0382: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0387: nop + .line 90,90 : 5,10 '' + IL_0388: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_038d: stloc.s V_41 + IL_038f: ldloc.s V_41 + IL_0391: ldloc.s V_41 + IL_0393: ldloc.s V_41 + IL_0395: ldloc.s V_41 + IL_0397: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() + IL_039c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03a1: ldloc.s V_41 + IL_03a3: newobj instance void Linq101Select01/'Pipe #9 input at line 90@91'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03a8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0387: newobj instance void Linq101Select01/'orders2@93-2'::.ctor() - IL_038c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03ad: ldsfld class Linq101Select01/'Pipe #9 input at line 90@93-2' Linq101Select01/'Pipe #9 input at line 90@93-2'::@_instance + IL_03b2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0391: newobj instance void Linq101Select01/'orders2@94-3'::.ctor() - IL_0396: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03b7: ldsfld class Linq101Select01/'Pipe #9 input at line 90@94-3' Linq101Select01/'Pipe #9 input at line 90@94-3'::@_instance + IL_03bc: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_039b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_03a0: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03a5: dup - IL_03a6: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::orders2@89 - IL_03ab: stloc.s orders2 - IL_03ad: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_03b2: stloc.s V_33 - IL_03b4: ldloc.s V_33 - IL_03b6: ldloc.s V_33 - IL_03b8: ldloc.s V_33 - IL_03ba: ldloc.s V_33 - IL_03bc: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() - IL_03c1: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03c6: ldloc.s V_33 - IL_03c8: newobj instance void Linq101Select01/orders3@100::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_03cd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03c1: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_03c6: stloc.s 'Pipe #9 input at line 90' + .line 95,95 : 10,21 '' + IL_03c8: ldloc.s 'Pipe #9 input at line 90' + IL_03ca: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03cf: dup + IL_03d0: stsfld class [mscorlib]System.Tuple`3[] ''.$Linq101Select01::orders2@89 + IL_03d5: stloc.s orders2 + IL_03d7: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_03dc: stloc.s V_42 + IL_03de: ldloc.s V_42 + IL_03e0: ldloc.s V_42 + IL_03e2: ldloc.s V_42 + IL_03e4: ldloc.s V_42 + IL_03e6: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() + IL_03eb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03f0: ldloc.s V_42 + IL_03f2: newobj instance void Linq101Select01/orders3@100::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03f7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_03d2: newobj instance void Linq101Select01/'orders3@102-2'::.ctor() - IL_03d7: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03fc: ldsfld class Linq101Select01/'orders3@102-2' Linq101Select01/'orders3@102-2'::@_instance + IL_0401: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03dc: newobj instance void Linq101Select01/'orders3@103-3'::.ctor() - IL_03e1: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0406: ldsfld class Linq101Select01/'orders3@103-3' Linq101Select01/'orders3@103-3'::@_instance + IL_040b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03e6: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_03eb: dup - IL_03ec: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1> ''.$Linq101Select01::orders3@98 - IL_03f1: stloc.s orders3 + IL_0410: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0415: dup + IL_0416: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1> ''.$Linq101Select01::orders3@98 + IL_041b: stloc.s orders3 .line 107,107 : 1,38 '' - IL_03f3: ldc.i4 0x7cd - IL_03f8: ldc.i4.1 - IL_03f9: ldc.i4.1 - IL_03fa: newobj instance void [mscorlib]System.DateTime::.ctor(int32, + IL_041d: ldc.i4 0x7cd + IL_0422: ldc.i4.1 + IL_0423: ldc.i4.1 + IL_0424: newobj instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32) - IL_03ff: dup - IL_0400: stsfld valuetype [mscorlib]System.DateTime ''.$Linq101Select01::cutOffDate@107 - IL_0405: stloc.s cutOffDate - IL_0407: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_040c: stloc.s V_34 - IL_040e: ldloc.s V_34 - IL_0410: ldloc.s V_34 - IL_0412: ldloc.s V_34 - IL_0414: ldloc.s V_34 - IL_0416: ldloc.s V_34 - IL_0418: ldloc.s V_34 - IL_041a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() - IL_041f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0424: ldloc.s V_34 - IL_0426: newobj instance void Linq101Select01/orders4@111::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_042b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0429: dup + IL_042a: stsfld valuetype [mscorlib]System.DateTime ''.$Linq101Select01::cutOffDate@107 + IL_042f: stloc.s cutOffDate + IL_0431: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0436: stloc.s V_43 + IL_0438: ldloc.s V_43 + IL_043a: ldloc.s V_43 + IL_043c: ldloc.s V_43 + IL_043e: ldloc.s V_43 + IL_0440: ldloc.s V_43 + IL_0442: ldloc.s V_43 + IL_0444: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Select01::get_customers() + IL_0449: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_044e: ldloc.s V_43 + IL_0450: newobj instance void Linq101Select01/orders4@111::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0455: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0430: newobj instance void Linq101Select01/'orders4@112-1'::.ctor() - IL_0435: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_045a: ldsfld class Linq101Select01/'orders4@112-1' Linq101Select01/'orders4@112-1'::@_instance + IL_045f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_043a: ldloc.s V_34 - IL_043c: newobj instance void Linq101Select01/'orders4@111-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0441: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0464: ldloc.s V_43 + IL_0466: newobj instance void Linq101Select01/'orders4@111-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_046b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0446: newobj instance void Linq101Select01/'orders4@114-4'::.ctor() - IL_044b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0470: ldsfld class Linq101Select01/'orders4@114-4' Linq101Select01/'orders4@114-4'::@_instance + IL_0475: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where,class [mscorlib]System.Collections.IEnumerable>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0450: newobj instance void Linq101Select01/'orders4@115-5'::.ctor() - IL_0455: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_047a: ldsfld class Linq101Select01/'orders4@115-5' Linq101Select01/'orders4@115-5'::@_instance + IL_047f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_045a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_045f: dup - IL_0460: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1> ''.$Linq101Select01::orders4@109 - IL_0465: stloc.s orders4 - IL_0467: ret + IL_0484: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0489: dup + IL_048a: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1> ''.$Linq101Select01::orders4@109 + IL_048f: stloc.s orders4 + IL_0491: ret } // end of method $Linq101Select01::main@ } // end of class ''.$Linq101Select01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl index 7b308ef661d..a87b2b30b88 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101SetOperators01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,17 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101SetOperators01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -33,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101SetOperators01 { - // Offset: 0x00000000 Length: 0x00000398 + // Offset: 0x00000000 Length: 0x0000038C } .mresource public FSharpOptimizationData.Linq101SetOperators01 { - // Offset: 0x000003A0 Length: 0x0000011E + // Offset: 0x00000390 Length: 0x0000011E } .module Linq101SetOperators01.exe -// MVID: {5B9A632A-4EE5-349F-A745-03832A639A5B} +// MVID: {611C4D82-4EE5-349F-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026A0000 +// Image base: 0x06410000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +60,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'uniqueFactors@13-1' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #1 input at line 12@13' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -80,281 +85,251 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0009: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::current + IL_0010: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method 'uniqueFactors@13-1'::.ctor + } // end of method 'Pipe #1 input at line 12@13'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 154 (0x9a) + // Code size 148 (0x94) .maxstack 6 .locals init ([0] int32 V_0, [1] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101SetOperators01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101SetOperators01.fs' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0070 + IL_001b: nop + IL_001c: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006d + IL_001e: nop + IL_001f: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0091 + IL_0021: nop + IL_0022: br.s IL_008b .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 13,13 : 9,33 '' - IL_002b: ldarg.0 - IL_002c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_factorsOf300() - IL_0031: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0036: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0025: ldarg.0 + IL_0026: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_factorsOf300() + IL_002b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0030: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc .line 13,13 : 9,33 '' - IL_0042: ldarg.0 - IL_0043: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_0048: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_004d: brfalse.s IL_0070 - - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_0055: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_005a: stloc.0 + IL_003c: ldarg.0 + IL_003d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0047: brfalse.s IL_006a + + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0054: stloc.0 .line 13,13 : 9,33 '' - IL_005b: ldloc.0 - IL_005c: stloc.1 - IL_005d: ldarg.0 - IL_005e: ldc.i4.2 - IL_005f: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0055: ldloc.0 + IL_0056: stloc.1 .line 14,14 : 9,17 '' - IL_0064: ldarg.0 - IL_0065: ldloc.1 - IL_0066: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::current - IL_006b: ldc.i4.1 - IL_006c: ret - - .line 100001,100001 : 0,0 '' - IL_006d: nop - IL_006e: br.s IL_0042 - - IL_0070: ldarg.0 - IL_0071: ldc.i4.3 - IL_0072: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0057: ldarg.0 + IL_0058: ldc.i4.2 + IL_0059: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc + IL_005e: ldarg.0 + IL_005f: ldloc.1 + IL_0060: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::current + IL_0065: ldc.i4.1 + IL_0066: ret + + .line 100001,100001 : 0,0 '' + IL_0067: nop + IL_0068: br.s IL_003c + + IL_006a: ldarg.0 + IL_006b: ldc.i4.3 + IL_006c: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc .line 13,13 : 9,33 '' - IL_0077: ldarg.0 - IL_0078: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_007d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0082: nop - IL_0083: ldarg.0 - IL_0084: ldnull - IL_0085: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_008a: ldarg.0 - IL_008b: ldc.i4.3 - IL_008c: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc - IL_0091: ldarg.0 + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_0084: ldarg.0 + IL_0085: ldc.i4.3 + IL_0086: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc + IL_008b: ldarg.0 + IL_008c: ldc.i4.0 + IL_008d: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::current IL_0092: ldc.i4.0 - IL_0093: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::current - IL_0098: ldc.i4.0 - IL_0099: ret - } // end of method 'uniqueFactors@13-1'::GenerateNext + IL_0093: ret + } // end of method 'Pipe #1 input at line 12@13'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'uniqueFactors@13-1'::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #1 input at line 12@13'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 13,13 : 9,33 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 13,13 : 9,33 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method 'uniqueFactors@13-1'::Close + IL_007f: ret + } // end of method 'Pipe #1 input at line 12@13'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method 'uniqueFactors@13-1'::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #1 input at line 12@13'::get_CheckClose .method public strict virtual instance int32 get_LastGenerated() cil managed @@ -364,9 +339,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/'uniqueFactors@13-1'::current + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #1 input at line 12@13'::current IL_0006: ret - } // end of method 'uniqueFactors@13-1'::get_LastGenerated + } // end of method 'Pipe #1 input at line 12@13'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -378,17 +353,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldc.i4.0 - IL_0003: newobj instance void Linq101SetOperators01/'uniqueFactors@13-1'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) + IL_0003: newobj instance void Linq101SetOperators01/'Pipe #1 input at line 12@13'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) IL_0008: ret - } // end of method 'uniqueFactors@13-1'::GetFreshEnumerator + } // end of method 'Pipe #1 input at line 12@13'::GetFreshEnumerator - } // end of class 'uniqueFactors@13-1' + } // end of class 'Pipe #1 input at line 12@13' - .class auto ansi serializable sealed nested assembly beforefieldinit 'categoryNames@22-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 21@22-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101SetOperators01/'Pipe #2 input at line 21@22-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -399,7 +375,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'categoryNames@22-1'::.ctor + } // end of method 'Pipe #2 input at line 21@22-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(class [Utils]Utils/Product _arg1) cil managed @@ -415,11 +391,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'categoryNames@22-1'::Invoke + } // end of method 'Pipe #2 input at line 21@22-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101SetOperators01/'Pipe #2 input at line 21@22-1'::.ctor() + IL_0005: stsfld class Linq101SetOperators01/'Pipe #2 input at line 21@22-1' Linq101SetOperators01/'Pipe #2 input at line 21@22-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 21@22-1'::.cctor - } // end of class 'categoryNames@22-1' + } // end of class 'Pipe #2 input at line 21@22-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname categoryNames@23 + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #2 input at line 21@23' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -444,280 +430,250 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0009: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101SetOperators01/categoryNames@23::current + IL_0010: stfld string Linq101SetOperators01/'Pipe #2 input at line 21@23'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method categoryNames@23::.ctor + } // end of method 'Pipe #2 input at line 21@23'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 167 (0xa7) + // Code size 161 (0xa1) .maxstack 7 .locals init ([0] class [Utils]Utils/Product p) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_007d + IL_001b: nop + IL_001c: br.s IL_0077 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_007a + IL_001e: nop + IL_001f: br.s IL_0074 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_009e + IL_0021: nop + IL_0022: br.s IL_0098 .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 23,23 : 9,26 '' - IL_002b: ldarg.0 - IL_002c: newobj instance void Linq101SetOperators01/'categoryNames@22-1'::.ctor() - IL_0031: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_products() - IL_0036: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0025: ldarg.0 + IL_0026: ldsfld class Linq101SetOperators01/'Pipe #2 input at line 21@22-1' Linq101SetOperators01/'Pipe #2 input at line 21@22-1'::@_instance + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_products() + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0040: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: stfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_003f: ldarg.0 + IL_0040: ldc.i4.1 + IL_0041: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc .line 23,23 : 9,26 '' - IL_004c: ldarg.0 - IL_004d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_0052: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0057: brfalse.s IL_007d - - IL_0059: ldarg.0 - IL_005a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_005f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0064: stloc.0 - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0046: ldarg.0 + IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0051: brfalse.s IL_0077 + + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_005e: stloc.0 .line 23,23 : 16,26 '' - IL_006c: ldarg.0 - IL_006d: ldloc.0 - IL_006e: callvirt instance string [Utils]Utils/Product::get_Category() - IL_0073: stfld string Linq101SetOperators01/categoryNames@23::current - IL_0078: ldc.i4.1 - IL_0079: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.2 + IL_0061: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc + IL_0066: ldarg.0 + IL_0067: ldloc.0 + IL_0068: callvirt instance string [Utils]Utils/Product::get_Category() + IL_006d: stfld string Linq101SetOperators01/'Pipe #2 input at line 21@23'::current + IL_0072: ldc.i4.1 + IL_0073: ret .line 100001,100001 : 0,0 '' - IL_007a: nop - IL_007b: br.s IL_004c + IL_0074: nop + IL_0075: br.s IL_0046 - IL_007d: ldarg.0 - IL_007e: ldc.i4.3 - IL_007f: stfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0077: ldarg.0 + IL_0078: ldc.i4.3 + IL_0079: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc .line 23,23 : 9,26 '' - IL_0084: ldarg.0 - IL_0085: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_008a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_008f: nop - IL_0090: ldarg.0 - IL_0091: ldnull - IL_0092: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_0097: ldarg.0 - IL_0098: ldc.i4.3 - IL_0099: stfld int32 Linq101SetOperators01/categoryNames@23::pc - IL_009e: ldarg.0 - IL_009f: ldnull - IL_00a0: stfld string Linq101SetOperators01/categoryNames@23::current - IL_00a5: ldc.i4.0 - IL_00a6: ret - } // end of method categoryNames@23::GenerateNext + IL_007e: ldarg.0 + IL_007f: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_0084: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0089: nop + IL_008a: ldarg.0 + IL_008b: ldnull + IL_008c: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_0091: ldarg.0 + IL_0092: ldc.i4.3 + IL_0093: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc + IL_0098: ldarg.0 + IL_0099: ldnull + IL_009a: stfld string Linq101SetOperators01/'Pipe #2 input at line 21@23'::current + IL_009f: ldc.i4.0 + IL_00a0: ret + } // end of method 'Pipe #2 input at line 21@23'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101SetOperators01/categoryNames@23::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101SetOperators01/categoryNames@23::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/categoryNames@23::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/'Pipe #2 input at line 21@23'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101SetOperators01/categoryNames@23::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101SetOperators01/categoryNames@23::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101SetOperators01/'Pipe #2 input at line 21@23'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 23,23 : 9,26 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 23,23 : 9,26 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method categoryNames@23::Close + IL_007f: ret + } // end of method 'Pipe #2 input at line 21@23'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101SetOperators01/categoryNames@23::pc + IL_0001: ldfld int32 Linq101SetOperators01/'Pipe #2 input at line 21@23'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method categoryNames@23::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #2 input at line 21@23'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -727,9 +683,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101SetOperators01/categoryNames@23::current + IL_0001: ldfld string Linq101SetOperators01/'Pipe #2 input at line 21@23'::current IL_0006: ret - } // end of method categoryNames@23::get_LastGenerated + } // end of method 'Pipe #2 input at line 21@23'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -741,17 +697,18 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101SetOperators01/categoryNames@23::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101SetOperators01/'Pipe #2 input at line 21@23'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method categoryNames@23::GetFreshEnumerator + } // end of method 'Pipe #2 input at line 21@23'::GetFreshEnumerator - } // end of class categoryNames@23 + } // end of class 'Pipe #2 input at line 21@23' .class auto ansi serializable sealed nested assembly beforefieldinit 'productFirstChars@32-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101SetOperators01/'productFirstChars@32-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -780,6 +737,16 @@ IL_000a: ret } // end of method 'productFirstChars@32-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101SetOperators01/'productFirstChars@32-1'::.ctor() + IL_0005: stsfld class Linq101SetOperators01/'productFirstChars@32-1' Linq101SetOperators01/'productFirstChars@32-1'::@_instance + IL_000a: ret + } // end of method 'productFirstChars@32-1'::.cctor + } // end of class 'productFirstChars@32-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname productFirstChars@33 @@ -822,7 +789,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 176 (0xb0) + // Code size 170 (0xaa) .maxstack 7 .locals init ([0] class [Utils]Utils/Product p) .line 100001,100001 : 0,0 '' @@ -832,97 +799,90 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0086 + IL_001b: nop + IL_001c: br.s IL_0080 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0083 + IL_001e: nop + IL_001f: br.s IL_007d .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00a7 + IL_0021: nop + IL_0022: br IL_00a1 .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 33,33 : 9,33 '' - IL_002e: ldarg.0 - IL_002f: newobj instance void Linq101SetOperators01/'productFirstChars@32-1'::.ctor() - IL_0034: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_products() - IL_0039: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0028: ldarg.0 + IL_0029: ldsfld class Linq101SetOperators01/'productFirstChars@32-1' Linq101SetOperators01/'productFirstChars@32-1'::@_instance + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_products() + IL_0033: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Product>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0043: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_0048: ldarg.0 - IL_0049: ldc.i4.1 - IL_004a: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_0038: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: stfld int32 Linq101SetOperators01/productFirstChars@33::pc .line 33,33 : 9,33 '' - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_0055: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_005a: brfalse.s IL_0086 - - IL_005c: ldarg.0 - IL_005d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_0062: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0067: stloc.0 - IL_0068: ldarg.0 - IL_0069: ldc.i4.2 - IL_006a: stfld int32 Linq101SetOperators01/productFirstChars@33::pc - .line 33,33 : 29,30 '' - IL_006f: ldarg.0 - IL_0070: ldloc.0 - IL_0071: callvirt instance string [Utils]Utils/Product::get_ProductName() - IL_0076: ldc.i4.0 - IL_0077: callvirt instance char [mscorlib]System.String::get_Chars(int32) - IL_007c: stfld char Linq101SetOperators01/productFirstChars@33::current - IL_0081: ldc.i4.1 - IL_0082: ret - - .line 100001,100001 : 0,0 '' - IL_0083: nop - IL_0084: br.s IL_004f - - IL_0086: ldarg.0 - IL_0087: ldc.i4.3 - IL_0088: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_004f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0054: brfalse.s IL_0080 + + IL_0056: ldarg.0 + IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0061: stloc.0 + .line 33,33 : 16,33 '' + IL_0062: ldarg.0 + IL_0063: ldc.i4.2 + IL_0064: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_0069: ldarg.0 + IL_006a: ldloc.0 + IL_006b: callvirt instance string [Utils]Utils/Product::get_ProductName() + IL_0070: ldc.i4.0 + IL_0071: callvirt instance char [netstandard]System.String::get_Chars(int32) + IL_0076: stfld char Linq101SetOperators01/productFirstChars@33::current + IL_007b: ldc.i4.1 + IL_007c: ret + + .line 100001,100001 : 0,0 '' + IL_007d: nop + IL_007e: br.s IL_0049 + + IL_0080: ldarg.0 + IL_0081: ldc.i4.3 + IL_0082: stfld int32 Linq101SetOperators01/productFirstChars@33::pc .line 33,33 : 9,33 '' - IL_008d: ldarg.0 - IL_008e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_0093: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0098: nop - IL_0099: ldarg.0 - IL_009a: ldnull - IL_009b: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_00a0: ldarg.0 - IL_00a1: ldc.i4.3 - IL_00a2: stfld int32 Linq101SetOperators01/productFirstChars@33::pc - IL_00a7: ldarg.0 + IL_0087: ldarg.0 + IL_0088: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_008d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0092: nop + IL_0093: ldarg.0 + IL_0094: ldnull + IL_0095: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_009a: ldarg.0 + IL_009b: ldc.i4.3 + IL_009c: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_00a1: ldarg.0 + IL_00a2: ldc.i4.0 + IL_00a3: stfld char Linq101SetOperators01/productFirstChars@33::current IL_00a8: ldc.i4.0 - IL_00a9: stfld char Linq101SetOperators01/productFirstChars@33::current - IL_00ae: ldc.i4.0 - IL_00af: ret + IL_00a9: ret } // end of method productFirstChars@33::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101SetOperators01/productFirstChars@33::pc @@ -930,158 +890,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101SetOperators01/productFirstChars@33::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101SetOperators01/productFirstChars@33::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/productFirstChars@33::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101SetOperators01/productFirstChars@33::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld char Linq101SetOperators01/productFirstChars@33::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101SetOperators01/productFirstChars@33::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld char Linq101SetOperators01/productFirstChars@33::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 33,33 : 9,33 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f + IL_0070: nop + IL_0071: br IL_0000 - IL_008d: br.s IL_0091 - - IL_008f: br.s IL_0093 + .line 33,33 : 9,33 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method productFirstChars@33::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101SetOperators01/productFirstChars@33::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method productFirstChars@33::get_CheckClose .method public strict virtual instance char @@ -1117,6 +1054,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'customerFirstChars@38-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101SetOperators01/'customerFirstChars@38-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -1145,6 +1083,16 @@ IL_000a: ret } // end of method 'customerFirstChars@38-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101SetOperators01/'customerFirstChars@38-1'::.ctor() + IL_0005: stsfld class Linq101SetOperators01/'customerFirstChars@38-1' Linq101SetOperators01/'customerFirstChars@38-1'::@_instance + IL_000a: ret + } // end of method 'customerFirstChars@38-1'::.cctor + } // end of class 'customerFirstChars@38-1' .class auto autochar serializable sealed nested assembly beforefieldinit specialname customerFirstChars@39 @@ -1187,7 +1135,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 176 (0xb0) + // Code size 170 (0xaa) .maxstack 7 .locals init ([0] class [Utils]Utils/Customer c) .line 100001,100001 : 0,0 '' @@ -1197,97 +1145,90 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0086 + IL_001b: nop + IL_001c: br.s IL_0080 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0083 + IL_001e: nop + IL_001f: br.s IL_007d .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00a7 + IL_0021: nop + IL_0022: br IL_00a1 .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 39,39 : 9,33 '' - IL_002e: ldarg.0 - IL_002f: newobj instance void Linq101SetOperators01/'customerFirstChars@38-1'::.ctor() - IL_0034: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_customers() - IL_0039: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Customer>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0028: ldarg.0 + IL_0029: ldsfld class Linq101SetOperators01/'customerFirstChars@38-1' Linq101SetOperators01/'customerFirstChars@38-1'::@_instance + IL_002e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101SetOperators01::get_customers() + IL_0033: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,class [Utils]Utils/Customer>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0043: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_0048: ldarg.0 - IL_0049: ldc.i4.1 - IL_004a: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_0038: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc .line 39,39 : 9,33 '' - IL_004f: ldarg.0 - IL_0050: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_0055: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_005a: brfalse.s IL_0086 - - IL_005c: ldarg.0 - IL_005d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_0062: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0067: stloc.0 - IL_0068: ldarg.0 - IL_0069: ldc.i4.2 - IL_006a: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc - .line 39,39 : 29,30 '' - IL_006f: ldarg.0 - IL_0070: ldloc.0 - IL_0071: callvirt instance string [Utils]Utils/Customer::get_CompanyName() - IL_0076: ldc.i4.0 - IL_0077: callvirt instance char [mscorlib]System.String::get_Chars(int32) - IL_007c: stfld char Linq101SetOperators01/customerFirstChars@39::current - IL_0081: ldc.i4.1 - IL_0082: ret - - .line 100001,100001 : 0,0 '' - IL_0083: nop - IL_0084: br.s IL_004f - - IL_0086: ldarg.0 - IL_0087: ldc.i4.3 - IL_0088: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_004f: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0054: brfalse.s IL_0080 + + IL_0056: ldarg.0 + IL_0057: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_005c: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0061: stloc.0 + .line 39,39 : 16,33 '' + IL_0062: ldarg.0 + IL_0063: ldc.i4.2 + IL_0064: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_0069: ldarg.0 + IL_006a: ldloc.0 + IL_006b: callvirt instance string [Utils]Utils/Customer::get_CompanyName() + IL_0070: ldc.i4.0 + IL_0071: callvirt instance char [netstandard]System.String::get_Chars(int32) + IL_0076: stfld char Linq101SetOperators01/customerFirstChars@39::current + IL_007b: ldc.i4.1 + IL_007c: ret + + .line 100001,100001 : 0,0 '' + IL_007d: nop + IL_007e: br.s IL_0049 + + IL_0080: ldarg.0 + IL_0081: ldc.i4.3 + IL_0082: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc .line 39,39 : 9,33 '' - IL_008d: ldarg.0 - IL_008e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_0093: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0098: nop - IL_0099: ldarg.0 - IL_009a: ldnull - IL_009b: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_00a0: ldarg.0 - IL_00a1: ldc.i4.3 - IL_00a2: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc - IL_00a7: ldarg.0 + IL_0087: ldarg.0 + IL_0088: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_008d: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0092: nop + IL_0093: ldarg.0 + IL_0094: ldnull + IL_0095: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_009a: ldarg.0 + IL_009b: ldc.i4.3 + IL_009c: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_00a1: ldarg.0 + IL_00a2: ldc.i4.0 + IL_00a3: stfld char Linq101SetOperators01/customerFirstChars@39::current IL_00a8: ldc.i4.0 - IL_00a9: stfld char Linq101SetOperators01/customerFirstChars@39::current - IL_00ae: ldc.i4.0 - IL_00af: ret + IL_00a9: ret } // end of method customerFirstChars@39::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101SetOperators01/customerFirstChars@39::pc @@ -1295,158 +1236,135 @@ IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101SetOperators01/customerFirstChars@39::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101SetOperators01/customerFirstChars@39::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc - IL_0068: ldarg.0 - IL_0069: ldc.i4.0 - IL_006a: stfld char Linq101SetOperators01/customerFirstChars@39::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101SetOperators01/customerFirstChars@39::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld char Linq101SetOperators01/customerFirstChars@39::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 39,39 : 9,33 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 39,39 : 9,33 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret + IL_007f: ret } // end of method customerFirstChars@39::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101SetOperators01/customerFirstChars@39::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method customerFirstChars@39::get_CheckClose .method public strict virtual instance char @@ -1484,7 +1402,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'factorsOf300@9-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::factorsOf300@9 IL_0005: ret } // end of method Linq101SetOperators01::get_factorsOf300 @@ -1493,7 +1411,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'uniqueFactors@11-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::uniqueFactors@11 IL_0005: ret } // end of method Linq101SetOperators01::get_uniqueFactors @@ -1502,7 +1420,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'products@18-14' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::products@18 IL_0005: ret } // end of method Linq101SetOperators01::get_products @@ -1520,7 +1438,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'customers@28-6' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::customers@28 IL_0005: ret } // end of method Linq101SetOperators01::get_customers @@ -1589,15 +1507,15 @@ .class private abstract auto ansi sealed ''.$Linq101SetOperators01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'factorsOf300@9-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 factorsOf300@9 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'uniqueFactors@11-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 uniqueFactors@11 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@18-14' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@18 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 categoryNames@20 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'customers@28-6' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers@28 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Collections.Generic.IEnumerable`1 productFirstChars@30 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1610,7 +1528,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 202 (0xca) + // Code size 212 (0xd4) .maxstack 8 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 factorsOf300, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 uniqueFactors, @@ -1619,10 +1537,12 @@ [4] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers, [5] class [mscorlib]System.Collections.Generic.IEnumerable`1 productFirstChars, [6] class [mscorlib]System.Collections.Generic.IEnumerable`1 customerFirstChars, - [7] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_7, + [7] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 12', [8] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_8, - [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, - [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10) + [9] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #2 input at line 21', + [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10, + [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, + [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12) .line 9,9 : 1,31 '' IL_0000: ldc.i4.2 IL_0001: ldc.i4.2 @@ -1641,75 +1561,85 @@ IL_001e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0023: dup - IL_0024: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'factorsOf300@9-2' + IL_0024: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::factorsOf300@9 IL_0029: stloc.0 .line 11,15 : 1,20 '' - IL_002a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_002f: stloc.s V_7 - IL_0031: ldloc.s V_7 - IL_0033: ldnull - IL_0034: ldc.i4.0 + IL_002a: nop + .line 12,12 : 5,10 '' + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0030: stloc.s V_8 + IL_0032: ldloc.s V_8 + IL_0034: ldnull IL_0035: ldc.i4.0 - IL_0036: newobj instance void Linq101SetOperators01/'uniqueFactors@13-1'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - int32) - IL_003b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0040: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) - IL_0045: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_004a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_004f: dup - IL_0050: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'uniqueFactors@11-2' - IL_0055: stloc.1 + IL_0036: ldc.i4.0 + IL_0037: newobj instance void Linq101SetOperators01/'Pipe #1 input at line 12@13'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + int32) + IL_003c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0041: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) + IL_0046: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_004b: stloc.s 'Pipe #1 input at line 12' + .line 15,15 : 10,20 '' + IL_004d: ldloc.s 'Pipe #1 input at line 12' + IL_004f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0054: dup + IL_0055: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::uniqueFactors@11 + IL_005a: stloc.1 .line 18,18 : 1,32 '' - IL_0056: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_005b: dup - IL_005c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'products@18-14' - IL_0061: stloc.2 + IL_005b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_0060: dup + IL_0061: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::products@18 + IL_0066: stloc.2 .line 20,25 : 1,20 '' - IL_0062: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0067: stloc.s V_8 - IL_0069: ldloc.s V_8 - IL_006b: ldnull - IL_006c: ldc.i4.0 - IL_006d: ldnull - IL_006e: newobj instance void Linq101SetOperators01/categoryNames@23::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_0073: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0078: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) - IL_007d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0082: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0087: dup - IL_0088: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::categoryNames@20 - IL_008d: stloc.3 + IL_0067: nop + .line 21,21 : 5,10 '' + IL_0068: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_006d: stloc.s V_10 + IL_006f: ldloc.s V_10 + IL_0071: ldnull + IL_0072: ldc.i4.0 + IL_0073: ldnull + IL_0074: newobj instance void Linq101SetOperators01/'Pipe #2 input at line 21@23'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_0079: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_007e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Distinct(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2) + IL_0083: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0088: stloc.s 'Pipe #2 input at line 21' + .line 25,25 : 10,20 '' + IL_008a: ldloc.s 'Pipe #2 input at line 21' + IL_008c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0091: dup + IL_0092: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::categoryNames@20 + IL_0097: stloc.3 .line 28,28 : 1,34 '' - IL_008e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() - IL_0093: dup - IL_0094: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::'customers@28-6' - IL_0099: stloc.s customers - IL_009b: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00a0: stloc.s V_9 - IL_00a2: ldnull - IL_00a3: ldc.i4.0 - IL_00a4: ldc.i4.0 - IL_00a5: newobj instance void Linq101SetOperators01/productFirstChars@33::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_0098: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() + IL_009d: dup + IL_009e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101SetOperators01::customers@28 + IL_00a3: stloc.s customers + IL_00a5: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00aa: stloc.s V_11 + IL_00ac: ldnull + IL_00ad: ldc.i4.0 + IL_00ae: ldc.i4.0 + IL_00af: newobj instance void Linq101SetOperators01/productFirstChars@33::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, char) - IL_00aa: dup - IL_00ab: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101SetOperators01::productFirstChars@30 - IL_00b0: stloc.s productFirstChars - IL_00b2: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00b7: stloc.s V_10 - IL_00b9: ldnull - IL_00ba: ldc.i4.0 - IL_00bb: ldc.i4.0 - IL_00bc: newobj instance void Linq101SetOperators01/customerFirstChars@39::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + IL_00b4: dup + IL_00b5: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101SetOperators01::productFirstChars@30 + IL_00ba: stloc.s productFirstChars + IL_00bc: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00c1: stloc.s V_12 + IL_00c3: ldnull + IL_00c4: ldc.i4.0 + IL_00c5: ldc.i4.0 + IL_00c6: newobj instance void Linq101SetOperators01/customerFirstChars@39::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, char) - IL_00c1: dup - IL_00c2: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101SetOperators01::customerFirstChars@36 - IL_00c7: stloc.s customerFirstChars - IL_00c9: ret + IL_00cb: dup + IL_00cc: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101SetOperators01::customerFirstChars@36 + IL_00d1: stloc.s customerFirstChars + IL_00d3: ret } // end of method $Linq101SetOperators01::main@ } // end of class ''.$Linq101SetOperators01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Where01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Where01.il.bsl index b673d1193cc..3f92cd859e8 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Where01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Where01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,17 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly extern Utils { .ver 0:0:0:0 } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 +} .assembly Linq101Where01 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, @@ -33,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Where01 { - // Offset: 0x00000000 Length: 0x000003D6 + // Offset: 0x00000000 Length: 0x000003CA } .mresource public FSharpOptimizationData.Linq101Where01 { - // Offset: 0x000003E0 Length: 0x0000012E + // Offset: 0x000003D0 Length: 0x0000012E } .module Linq101Where01.exe -// MVID: {5B9A632A-FF23-CD21-A745-03832A639A5B} +// MVID: {611C4D82-FF23-CD21-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x009E0000 +// Image base: 0x06A30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,7 +60,7 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto ansi serializable sealed nested assembly beforefieldinit 'lowNums@14-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@14' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -73,9 +78,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'lowNums@14-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'Pipe #1 input at line 13@14'::builder@ IL_000d: ret - } // end of method 'lowNums@14-3'::.ctor + } // end of method 'Pipe #1 input at line 13@14'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(int32 _arg1) cil managed @@ -84,23 +89,24 @@ .maxstack 6 .locals init ([0] int32 n) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 14,14 : 9,28 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Where01.fs' + .line 14,14 : 9,28 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Where01.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 15,15 : 9,22 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'lowNums@14-3'::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'Pipe #1 input at line 13@14'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method 'lowNums@14-3'::Invoke + } // end of method 'Pipe #1 input at line 13@14'::Invoke - } // end of class 'lowNums@14-3' + } // end of class 'Pipe #1 input at line 13@14' - .class auto ansi serializable sealed nested assembly beforefieldinit 'lowNums@15-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@15-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'Pipe #1 input at line 13@15-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -111,7 +117,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'lowNums@15-4'::.ctor + } // end of method 'Pipe #1 input at line 13@15-1'::.ctor .method public strict virtual instance bool Invoke(int32 n) cil managed @@ -123,13 +129,24 @@ IL_0001: ldc.i4.5 IL_0002: clt IL_0004: ret - } // end of method 'lowNums@15-4'::Invoke + } // end of method 'Pipe #1 input at line 13@15-1'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #1 input at line 13@15-1'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #1 input at line 13@15-1' Linq101Where01/'Pipe #1 input at line 13@15-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 13@15-1'::.cctor - } // end of class 'lowNums@15-4' + } // end of class 'Pipe #1 input at line 13@15-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'lowNums@16-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #1 input at line 13@16-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'Pipe #1 input at line 13@16-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -140,7 +157,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'lowNums@16-5'::.ctor + } // end of method 'Pipe #1 input at line 13@16-2'::.ctor .method public strict virtual instance int32 Invoke(int32 n) cil managed @@ -150,9 +167,19 @@ .line 16,16 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'lowNums@16-5'::Invoke + } // end of method 'Pipe #1 input at line 13@16-2'::Invoke - } // end of class 'lowNums@16-5' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #1 input at line 13@16-2'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #1 input at line 13@16-2' Linq101Where01/'Pipe #1 input at line 13@16-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #1 input at line 13@16-2'::.cctor + + } // end of class 'Pipe #1 input at line 13@16-2' .class auto ansi serializable sealed nested assembly beforefieldinit soldOutProducts@24 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> @@ -199,6 +226,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'soldOutProducts@25-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'soldOutProducts@25-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -224,11 +252,22 @@ IL_0009: ret } // end of method 'soldOutProducts@25-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'soldOutProducts@25-1'::.ctor() + IL_0005: stsfld class Linq101Where01/'soldOutProducts@25-1' Linq101Where01/'soldOutProducts@25-1'::@_instance + IL_000a: ret + } // end of method 'soldOutProducts@25-1'::.cctor + } // end of class 'soldOutProducts@25-1' .class auto ansi serializable sealed nested assembly beforefieldinit 'soldOutProducts@26-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'soldOutProducts@26-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -251,6 +290,16 @@ IL_0001: ret } // end of method 'soldOutProducts@26-2'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'soldOutProducts@26-2'::.ctor() + IL_0005: stsfld class Linq101Where01/'soldOutProducts@26-2' Linq101Where01/'soldOutProducts@26-2'::@_instance + IL_000a: ret + } // end of method 'soldOutProducts@26-2'::.cctor + } // end of class 'soldOutProducts@26-2' .class auto ansi serializable sealed nested assembly beforefieldinit expensiveInStockProducts@32 @@ -298,6 +347,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit 'expensiveInStockProducts@33-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'expensiveInStockProducts@33-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -313,45 +363,54 @@ .method public strict virtual instance bool Invoke(class [Utils]Utils/Product p) cil managed { - // Code size 41 (0x29) + // Code size 38 (0x26) .maxstack 10 + .line 33,33 : 16,57 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.1 - IL_0001: callvirt instance int32 [Utils]Utils/Product::get_UnitsInStock() - IL_0006: ldc.i4.0 - IL_0007: ble.s IL_000b - - IL_0009: br.s IL_000d - - IL_000b: br.s IL_0027 + IL_0001: ldarg.1 + IL_0002: callvirt instance int32 [Utils]Utils/Product::get_UnitsInStock() + IL_0007: ldc.i4.0 + IL_0008: ble.s IL_0024 .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() - IL_0013: ldc.i4 0x12c - IL_0018: ldc.i4.0 - IL_0019: ldc.i4.0 - IL_001a: ldc.i4.0 - IL_001b: ldc.i4.2 - IL_001c: newobj instance void [mscorlib]System.Decimal::.ctor(int32, - int32, - int32, - bool, - uint8) - IL_0021: call bool [mscorlib]System.Decimal::op_GreaterThan(valuetype [mscorlib]System.Decimal, - valuetype [mscorlib]System.Decimal) - IL_0026: ret + IL_000a: ldarg.1 + IL_000b: callvirt instance valuetype [mscorlib]System.Decimal [Utils]Utils/Product::get_UnitPrice() + IL_0010: ldc.i4 0x12c + IL_0015: ldc.i4.0 + IL_0016: ldc.i4.0 + IL_0017: ldc.i4.0 + IL_0018: ldc.i4.2 + IL_0019: newobj instance void [netstandard]System.Decimal::.ctor(int32, + int32, + int32, + bool, + uint8) + IL_001e: call bool [netstandard]System.Decimal::op_GreaterThan(valuetype [netstandard]System.Decimal, + valuetype [netstandard]System.Decimal) + IL_0023: ret .line 100001,100001 : 0,0 '' - IL_0027: ldc.i4.0 - IL_0028: ret + IL_0024: ldc.i4.0 + IL_0025: ret } // end of method 'expensiveInStockProducts@33-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'expensiveInStockProducts@33-1'::.ctor() + IL_0005: stsfld class Linq101Where01/'expensiveInStockProducts@33-1' Linq101Where01/'expensiveInStockProducts@33-1'::@_instance + IL_000a: ret + } // end of method 'expensiveInStockProducts@33-1'::.cctor + } // end of class 'expensiveInStockProducts@33-1' .class auto ansi serializable sealed nested assembly beforefieldinit 'expensiveInStockProducts@34-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'expensiveInStockProducts@34-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -374,9 +433,19 @@ IL_0001: ret } // end of method 'expensiveInStockProducts@34-2'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'expensiveInStockProducts@34-2'::.ctor() + IL_0005: stsfld class Linq101Where01/'expensiveInStockProducts@34-2' Linq101Where01/'expensiveInStockProducts@34-2'::@_instance + IL_000a: ret + } // end of method 'expensiveInStockProducts@34-2'::.cctor + } // end of class 'expensiveInStockProducts@34-2' - .class auto ansi serializable sealed nested assembly beforefieldinit waCustomers@42 + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 41@42' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder builder@ @@ -394,9 +463,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/waCustomers@42::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'Pipe #2 input at line 41@42'::builder@ IL_000d: ret - } // end of method waCustomers@42::.ctor + } // end of method 'Pipe #2 input at line 41@42'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 Invoke(class [Utils]Utils/Customer _arg1) cil managed @@ -409,18 +478,19 @@ IL_0001: stloc.0 .line 43,43 : 9,32 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/waCustomers@42::builder@ + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Where01/'Pipe #2 input at line 41@42'::builder@ IL_0008: ldloc.0 IL_0009: tail. IL_000b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield(!!0) IL_0010: ret - } // end of method waCustomers@42::Invoke + } // end of method 'Pipe #2 input at line 41@42'::Invoke - } // end of class waCustomers@42 + } // end of class 'Pipe #2 input at line 41@42' - .class auto ansi serializable sealed nested assembly beforefieldinit 'waCustomers@43-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 41@43-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'Pipe #2 input at line 41@43-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -431,7 +501,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'waCustomers@43-1'::.ctor + } // end of method 'Pipe #2 input at line 41@43-1'::.ctor .method public strict virtual instance bool Invoke(class [Utils]Utils/Customer c) cil managed @@ -442,16 +512,27 @@ IL_0000: ldarg.1 IL_0001: callvirt instance string [Utils]Utils/Customer::get_Region() IL_0006: ldstr "WA" - IL_000b: call bool [mscorlib]System.String::Equals(string, - string) + IL_000b: call bool [netstandard]System.String::Equals(string, + string) IL_0010: ret - } // end of method 'waCustomers@43-1'::Invoke + } // end of method 'Pipe #2 input at line 41@43-1'::Invoke - } // end of class 'waCustomers@43-1' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #2 input at line 41@43-1'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #2 input at line 41@43-1' Linq101Where01/'Pipe #2 input at line 41@43-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 41@43-1'::.cctor + + } // end of class 'Pipe #2 input at line 41@43-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'waCustomers@44-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #2 input at line 41@44-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class Linq101Where01/'Pipe #2 input at line 41@44-2' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -462,7 +543,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ret - } // end of method 'waCustomers@44-2'::.ctor + } // end of method 'Pipe #2 input at line 41@44-2'::.ctor .method public strict virtual instance class [Utils]Utils/Customer Invoke(class [Utils]Utils/Customer c) cil managed @@ -472,85 +553,24 @@ .line 44,44 : 16,17 '' IL_0000: ldarg.1 IL_0001: ret - } // end of method 'waCustomers@44-2'::Invoke - - } // end of class 'waCustomers@44-2' + } // end of method 'Pipe #2 input at line 41@44-2'::Invoke - .class auto ansi serializable sealed nested assembly beforefieldinit shortDigits@55 - extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1> - { - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method private specialname rtspecialname static + void .cctor() cil managed { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1>::.ctor() - IL_0006: ret - } // end of method shortDigits@55::.ctor - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 - Invoke(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x) cil managed - { - // Code size 9 (0x9) - .maxstack 8 - .line 55,55 : 19,21 '' - IL_0000: ldarg.1 - IL_0001: tail. - IL_0003: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Identity>(!!0) - IL_0008: ret - } // end of method shortDigits@55::Invoke - - } // end of class shortDigits@55 - - .class auto ansi serializable sealed nested assembly beforefieldinit 'shortDigits@54-1' - extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3> - { - .method assembly specialname rtspecialname - instance void .ctor() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3>::.ctor() - IL_0006: ret - } // end of method 'shortDigits@54-1'::.ctor - - .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 - Invoke(int32 i, - string d) cil managed - { - // Code size 22 (0x16) - .maxstack 8 - .line 54,54 : 29,49 '' - IL_0000: ldarg.2 - IL_0001: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_0006: ldarg.1 - IL_0007: bge.s IL_000b - - IL_0009: br.s IL_000d - - IL_000b: br.s IL_0014 - - .line 54,54 : 50,57 '' - IL_000d: ldarg.2 - IL_000e: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_0013: ret - - .line 54,54 : 63,67 '' - IL_0014: ldnull - IL_0015: ret - } // end of method 'shortDigits@54-1'::Invoke + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #2 input at line 41@44-2'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #2 input at line 41@44-2' Linq101Where01/'Pipe #2 input at line 41@44-2'::@_instance + IL_000a: ret + } // end of method 'Pipe #2 input at line 41@44-2'::.cctor - } // end of class 'shortDigits@54-1' + } // end of class 'Pipe #2 input at line 41@44-2' - .class auto ansi serializable sealed nested assembly beforefieldinit 'shortDigits@51-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 input at line 50@51-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { + .field static assembly initonly class Linq101Where01/'Pipe #3 input at line 50@51-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -561,7 +581,7 @@ IL_0000: ldarg.0 IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ret - } // end of method 'shortDigits@51-3'::.ctor + } // end of method 'Pipe #3 input at line 50@51-1'::.ctor .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerable`1 Invoke(string _arg1) cil managed @@ -577,11 +597,21 @@ IL_0003: tail. IL_0005: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Singleton(!!0) IL_000a: ret - } // end of method 'shortDigits@51-3'::Invoke + } // end of method 'Pipe #3 input at line 50@51-1'::Invoke - } // end of class 'shortDigits@51-3' + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #3 input at line 50@51-1'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #3 input at line 50@51-1' Linq101Where01/'Pipe #3 input at line 50@51-1'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 input at line 50@51-1'::.cctor + + } // end of class 'Pipe #3 input at line 50@51-1' - .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'shortDigits@52-2' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'Pipe #3 input at line 50@52' extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) @@ -606,279 +636,249 @@ .maxstack 8 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' + IL_0002: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' IL_0007: ldarg.0 IL_0008: ldarg.2 - IL_0009: stfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0009: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc IL_000e: ldarg.0 IL_000f: ldarg.3 - IL_0010: stfld string Linq101Where01/'shortDigits@52-2'::current + IL_0010: stfld string Linq101Where01/'Pipe #3 input at line 50@52'::current IL_0015: ldarg.0 IL_0016: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() IL_001b: ret - } // end of method 'shortDigits@52-2'::.ctor + } // end of method 'Pipe #3 input at line 50@52'::.ctor .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 162 (0xa2) + // Code size 156 (0x9c) .maxstack 7 .locals init ([0] string d) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0001: ldfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0078 + IL_001b: nop + IL_001c: br.s IL_0072 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0075 + IL_001e: nop + IL_001f: br.s IL_006f .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0099 + IL_0021: nop + IL_0022: br.s IL_0093 .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 52,52 : 9,17 '' - IL_002b: ldarg.0 - IL_002c: newobj instance void Linq101Where01/'shortDigits@51-3'::.ctor() - IL_0031: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_digits() - IL_0036: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, + IL_0025: ldarg.0 + IL_0026: ldsfld class Linq101Where01/'Pipe #3 input at line 50@51-1' Linq101Where01/'Pipe #3 input at line 50@51-1'::@_instance + IL_002b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_digits() + IL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Collect,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0040: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_0045: ldarg.0 - IL_0046: ldc.i4.1 - IL_0047: stfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0035: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_003a: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_003f: ldarg.0 + IL_0040: ldc.i4.1 + IL_0041: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc .line 52,52 : 9,17 '' - IL_004c: ldarg.0 - IL_004d: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_0052: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0057: brfalse.s IL_0078 - - IL_0059: ldarg.0 - IL_005a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_005f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0064: stloc.0 - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0046: ldarg.0 + IL_0047: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_004c: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0051: brfalse.s IL_0072 + + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_0059: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_005e: stloc.0 .line 52,52 : 16,17 '' - IL_006c: ldarg.0 - IL_006d: ldloc.0 - IL_006e: stfld string Linq101Where01/'shortDigits@52-2'::current - IL_0073: ldc.i4.1 - IL_0074: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.2 + IL_0061: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc + IL_0066: ldarg.0 + IL_0067: ldloc.0 + IL_0068: stfld string Linq101Where01/'Pipe #3 input at line 50@52'::current + IL_006d: ldc.i4.1 + IL_006e: ret .line 100001,100001 : 0,0 '' - IL_0075: nop - IL_0076: br.s IL_004c + IL_006f: nop + IL_0070: br.s IL_0046 - IL_0078: ldarg.0 - IL_0079: ldc.i4.3 - IL_007a: stfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0072: ldarg.0 + IL_0073: ldc.i4.3 + IL_0074: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc .line 52,52 : 9,17 '' - IL_007f: ldarg.0 - IL_0080: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_0085: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_008a: nop - IL_008b: ldarg.0 - IL_008c: ldnull - IL_008d: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_0092: ldarg.0 - IL_0093: ldc.i4.3 - IL_0094: stfld int32 Linq101Where01/'shortDigits@52-2'::pc - IL_0099: ldarg.0 - IL_009a: ldnull - IL_009b: stfld string Linq101Where01/'shortDigits@52-2'::current - IL_00a0: ldc.i4.0 - IL_00a1: ret - } // end of method 'shortDigits@52-2'::GenerateNext + IL_0079: ldarg.0 + IL_007a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_007f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0084: nop + IL_0085: ldarg.0 + IL_0086: ldnull + IL_0087: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_008c: ldarg.0 + IL_008d: ldc.i4.3 + IL_008e: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc + IL_0093: ldarg.0 + IL_0094: ldnull + IL_0095: stfld string Linq101Where01/'Pipe #3 input at line 50@52'::current + IL_009a: ldc.i4.0 + IL_009b: ret + } // end of method 'Pipe #3 input at line 50@52'::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 148 (0x94) + // Code size 128 (0x80) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0001: ldfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( IL_0013) - IL_0011: br.s IL_0019 + IL_0011: br.s IL_0016 .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_0087 + IL_0014: br.s IL_0076 .line 100001,100001 : 0,0 '' - IL_0019: nop + IL_0016: nop + .line 100001,100001 : 0,0 '' .try { - IL_001a: ldarg.0 - IL_001b: ldfld int32 Linq101Where01/'shortDigits@52-2'::pc - IL_0020: switch ( + IL_0017: ldarg.0 + IL_0018: ldfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc + IL_001d: switch ( + IL_0034, IL_0037, - IL_0039, - IL_003b, + IL_003a, IL_003d) - IL_0035: br.s IL_004b - - IL_0037: br.s IL_003f - - IL_0039: br.s IL_0042 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 + IL_0032: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br.s IL_0061 + IL_0034: nop + IL_0035: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0042: nop - IL_0043: br.s IL_004d + IL_0037: nop + IL_0038: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004c + IL_003a: nop + IL_003b: br.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0061 + IL_003d: nop + IL_003e: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_004b: nop + IL_0040: nop .line 100001,100001 : 0,0 '' - IL_004c: nop - IL_004d: ldarg.0 - IL_004e: ldc.i4.3 - IL_004f: stfld int32 Linq101Where01/'shortDigits@52-2'::pc - IL_0054: ldarg.0 - IL_0055: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'shortDigits@52-2'::'enum' - IL_005a: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_005f: nop + IL_0041: nop + IL_0042: ldarg.0 + IL_0043: ldc.i4.3 + IL_0044: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc + IL_0049: ldarg.0 + IL_004a: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 Linq101Where01/'Pipe #3 input at line 50@52'::'enum' + IL_004f: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0054: nop .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.3 - IL_0063: stfld int32 Linq101Where01/'shortDigits@52-2'::pc - IL_0068: ldarg.0 - IL_0069: ldnull - IL_006a: stfld string Linq101Where01/'shortDigits@52-2'::current - IL_006f: ldnull - IL_0070: stloc.1 - IL_0071: leave.s IL_007f + IL_0055: nop + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc + IL_005d: ldarg.0 + IL_005e: ldnull + IL_005f: stfld string Linq101Where01/'Pipe #3 input at line 50@52'::current + IL_0064: leave.s IL_0070 } // end .try catch [mscorlib]System.Object { - IL_0073: castclass [mscorlib]System.Exception - IL_0078: stloc.2 + IL_0066: castclass [mscorlib]System.Exception + IL_006b: stloc.1 .line 52,52 : 9,17 '' - IL_0079: ldloc.2 - IL_007a: stloc.0 - IL_007b: ldnull - IL_007c: stloc.1 - IL_007d: leave.s IL_007f + IL_006c: ldloc.1 + IL_006d: stloc.0 + IL_006e: leave.s IL_0070 .line 100001,100001 : 0,0 '' } // end handler - IL_007f: ldloc.1 - IL_0080: pop - .line 100001,100001 : 0,0 '' - IL_0081: nop - IL_0082: br IL_0000 - - IL_0087: ldloc.0 - IL_0088: ldnull - IL_0089: cgt.un - IL_008b: brfalse.s IL_008f - - IL_008d: br.s IL_0091 + IL_0070: nop + IL_0071: br IL_0000 - IL_008f: br.s IL_0093 + .line 52,52 : 9,17 '' + IL_0076: nop + .line 100001,100001 : 0,0 '' + IL_0077: ldloc.0 + IL_0078: ldnull + IL_0079: cgt.un + IL_007b: brfalse.s IL_007f .line 100001,100001 : 0,0 '' - IL_0091: ldloc.0 - IL_0092: throw + IL_007d: ldloc.0 + IL_007e: throw .line 100001,100001 : 0,0 '' - IL_0093: ret - } // end of method 'shortDigits@52-2'::Close + IL_007f: ret + } // end of method 'Pipe #3 input at line 50@52'::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld int32 Linq101Where01/'shortDigits@52-2'::pc + IL_0001: ldfld int32 Linq101Where01/'Pipe #3 input at line 50@52'::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.1 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: ret - IL_0034: ldc.i4.1 - IL_0035: ret + IL_002c: ldc.i4.1 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret - } // end of method 'shortDigits@52-2'::get_CheckClose + IL_002e: ldc.i4.0 + IL_002f: ret + } // end of method 'Pipe #3 input at line 50@52'::get_CheckClose .method public strict virtual instance string get_LastGenerated() cil managed @@ -888,9 +888,9 @@ // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 - IL_0001: ldfld string Linq101Where01/'shortDigits@52-2'::current + IL_0001: ldfld string Linq101Where01/'Pipe #3 input at line 50@52'::current IL_0006: ret - } // end of method 'shortDigits@52-2'::get_LastGenerated + } // end of method 'Pipe #3 input at line 50@52'::get_LastGenerated .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 GetFreshEnumerator() cil managed @@ -902,20 +902,112 @@ IL_0000: ldnull IL_0001: ldc.i4.0 IL_0002: ldnull - IL_0003: newobj instance void Linq101Where01/'shortDigits@52-2'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) + IL_0003: newobj instance void Linq101Where01/'Pipe #3 input at line 50@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) IL_0008: ret - } // end of method 'shortDigits@52-2'::GetFreshEnumerator + } // end of method 'Pipe #3 input at line 50@52'::GetFreshEnumerator + + } // end of class 'Pipe #3 input at line 50@52' - } // end of class 'shortDigits@52-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'Pipe #3 stage #1 at line 54@54' + extends class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3> + { + .field static assembly initonly class Linq101Where01/'Pipe #3 stage #1 at line 54@54' @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.OptimizedClosures/FSharpFunc`3>::.ctor() + IL_0006: ret + } // end of method 'Pipe #3 stage #1 at line 54@54'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 + Invoke(int32 i, + string d) cil managed + { + // Code size 19 (0x13) + .maxstack 8 + .line 54,54 : 29,49 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.2 + IL_0002: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_0007: ldarg.1 + IL_0008: bge.s IL_0011 + + .line 54,54 : 50,57 '' + IL_000a: ldarg.2 + IL_000b: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) + IL_0010: ret + + .line 54,54 : 63,67 '' + IL_0011: ldnull + IL_0012: ret + } // end of method 'Pipe #3 stage #1 at line 54@54'::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/'Pipe #3 stage #1 at line 54@54'::.ctor() + IL_0005: stsfld class Linq101Where01/'Pipe #3 stage #1 at line 54@54' Linq101Where01/'Pipe #3 stage #1 at line 54@54'::@_instance + IL_000a: ret + } // end of method 'Pipe #3 stage #1 at line 54@54'::.cctor + + } // end of class 'Pipe #3 stage #1 at line 54@54' + + .class auto ansi serializable sealed nested assembly beforefieldinit shortDigits@55 + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1> + { + .field static assembly initonly class Linq101Where01/shortDigits@55 @_instance + .method assembly specialname rtspecialname + instance void .ctor() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1>::.ctor() + IL_0006: ret + } // end of method shortDigits@55::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 x) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + .line 55,55 : 19,21 '' + IL_0000: ldarg.1 + IL_0001: tail. + IL_0003: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Identity>(!!0) + IL_0008: ret + } // end of method shortDigits@55::Invoke + + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void Linq101Where01/shortDigits@55::.ctor() + IL_0005: stsfld class Linq101Where01/shortDigits@55 Linq101Where01/shortDigits@55::@_instance + IL_000a: ret + } // end of method shortDigits@55::.cctor + + } // end of class shortDigits@55 .method public specialname static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 get_numbers() cil managed { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'numbers@9-11' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::numbers@9 IL_0005: ret } // end of method Linq101Where01::get_numbers @@ -924,7 +1016,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'lowNums@12-2' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::lowNums@12 IL_0005: ret } // end of method Linq101Where01::get_lowNums @@ -933,7 +1025,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'products@20-16' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::products@20 IL_0005: ret } // end of method Linq101Where01::get_products @@ -960,7 +1052,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'customers@38-8' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::customers@38 IL_0005: ret } // end of method Linq101Where01::get_customers @@ -978,7 +1070,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'digits@48-6' + IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::digits@48 IL_0005: ret } // end of method Linq101Where01::get_digits @@ -1050,21 +1142,21 @@ .class private abstract auto ansi sealed ''.$Linq101Where01 extends [mscorlib]System.Object { - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'numbers@9-11' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers@9 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'lowNums@12-2' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 lowNums@12 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'products@20-16' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 products@20 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Collections.Generic.IEnumerable`1 soldOutProducts@22 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Collections.Generic.IEnumerable`1 expensiveInStockProducts@30 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'customers@38-8' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 customers@38 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [Utils]Utils/Customer[] waCustomers@40 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'digits@48-6' + .field static assembly class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits@48 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly class [mscorlib]System.Collections.Generic.IEnumerable`1 shortDigits@49 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -1075,7 +1167,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 543 (0x21f) + // Code size 562 (0x232) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 numbers, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 lowNums, @@ -1086,11 +1178,15 @@ [6] class [Utils]Utils/Customer[] waCustomers, [7] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 digits, [8] class [mscorlib]System.Collections.Generic.IEnumerable`1 shortDigits, - [9] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_9, + [9] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 13', [10] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_10, [11] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_11, [12] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_12, - [13] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_13) + [13] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #2 input at line 41', + [14] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_14, + [15] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #3 input at line 50', + [16] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_16, + [17] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #3 stage #1 at line 54') .line 9,9 : 1,47 '' IL_0000: ldc.i4.5 IL_0001: ldc.i4.4 @@ -1124,126 +1220,132 @@ IL_003d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0042: dup - IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'numbers@9-11' + IL_0043: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::numbers@9 IL_0048: stloc.0 .line 12,17 : 1,20 '' - IL_0049: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_004e: stloc.s V_9 - IL_0050: ldloc.s V_9 - IL_0052: ldloc.s V_9 - IL_0054: ldloc.s V_9 - IL_0056: ldloc.s V_9 - IL_0058: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_numbers() - IL_005d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0062: ldloc.s V_9 - IL_0064: newobj instance void Linq101Where01/'lowNums@14-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0069: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0049: nop + .line 13,13 : 5,10 '' + IL_004a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_004f: stloc.s V_10 + IL_0051: ldloc.s V_10 + IL_0053: ldloc.s V_10 + IL_0055: ldloc.s V_10 + IL_0057: ldloc.s V_10 + IL_0059: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_numbers() + IL_005e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0063: ldloc.s V_10 + IL_0065: newobj instance void Linq101Where01/'Pipe #1 input at line 13@14'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_006a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_006e: newobj instance void Linq101Where01/'lowNums@15-4'::.ctor() - IL_0073: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_006f: ldsfld class Linq101Where01/'Pipe #1 input at line 13@15-1' Linq101Where01/'Pipe #1 input at line 13@15-1'::@_instance + IL_0074: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0078: newobj instance void Linq101Where01/'lowNums@16-5'::.ctor() - IL_007d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0079: ldsfld class Linq101Where01/'Pipe #1 input at line 13@16-2' Linq101Where01/'Pipe #1 input at line 13@16-2'::@_instance + IL_007e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0082: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0087: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::OfSeq(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_008c: dup - IL_008d: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'lowNums@12-2' - IL_0092: stloc.1 + IL_0083: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0088: stloc.s 'Pipe #1 input at line 13' + .line 17,17 : 10,20 '' + IL_008a: ldloc.s 'Pipe #1 input at line 13' + IL_008c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::OfSeq(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0091: dup + IL_0092: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::lowNums@12 + IL_0097: stloc.1 .line 20,20 : 1,32 '' - IL_0093: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_0098: dup - IL_0099: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'products@20-16' - IL_009e: stloc.2 - IL_009f: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00a4: stloc.s V_10 - IL_00a6: ldloc.s V_10 - IL_00a8: ldloc.s V_10 - IL_00aa: ldloc.s V_10 - IL_00ac: ldloc.s V_10 - IL_00ae: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_products() - IL_00b3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00b8: ldloc.s V_10 - IL_00ba: newobj instance void Linq101Where01/soldOutProducts@24::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_00bf: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0098: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_009d: dup + IL_009e: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::products@20 + IL_00a3: stloc.2 + IL_00a4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00a9: stloc.s V_11 + IL_00ab: ldloc.s V_11 + IL_00ad: ldloc.s V_11 + IL_00af: ldloc.s V_11 + IL_00b1: ldloc.s V_11 + IL_00b3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_products() + IL_00b8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00bd: ldloc.s V_11 + IL_00bf: newobj instance void Linq101Where01/soldOutProducts@24::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_00c4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_00c4: newobj instance void Linq101Where01/'soldOutProducts@25-1'::.ctor() - IL_00c9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00c9: ldsfld class Linq101Where01/'soldOutProducts@25-1' Linq101Where01/'soldOutProducts@25-1'::@_instance + IL_00ce: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00ce: newobj instance void Linq101Where01/'soldOutProducts@26-2'::.ctor() - IL_00d3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00d3: ldsfld class Linq101Where01/'soldOutProducts@26-2' Linq101Where01/'soldOutProducts@26-2'::@_instance + IL_00d8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_00d8: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_00dd: dup - IL_00de: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::soldOutProducts@22 - IL_00e3: stloc.3 - IL_00e4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_00e9: stloc.s V_11 - IL_00eb: ldloc.s V_11 - IL_00ed: ldloc.s V_11 - IL_00ef: ldloc.s V_11 - IL_00f1: ldloc.s V_11 - IL_00f3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_products() - IL_00f8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_00fd: ldloc.s V_11 - IL_00ff: newobj instance void Linq101Where01/expensiveInStockProducts@32::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0104: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_00dd: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_00e2: dup + IL_00e3: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::soldOutProducts@22 + IL_00e8: stloc.3 + IL_00e9: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_00ee: stloc.s V_12 + IL_00f0: ldloc.s V_12 + IL_00f2: ldloc.s V_12 + IL_00f4: ldloc.s V_12 + IL_00f6: ldloc.s V_12 + IL_00f8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_products() + IL_00fd: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0102: ldloc.s V_12 + IL_0104: newobj instance void Linq101Where01/expensiveInStockProducts@32::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0109: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0109: newobj instance void Linq101Where01/'expensiveInStockProducts@33-1'::.ctor() - IL_010e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_010e: ldsfld class Linq101Where01/'expensiveInStockProducts@33-1' Linq101Where01/'expensiveInStockProducts@33-1'::@_instance + IL_0113: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0113: newobj instance void Linq101Where01/'expensiveInStockProducts@34-2'::.ctor() - IL_0118: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0118: ldsfld class Linq101Where01/'expensiveInStockProducts@34-2' Linq101Where01/'expensiveInStockProducts@34-2'::@_instance + IL_011d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_011d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0122: dup - IL_0123: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::expensiveInStockProducts@30 - IL_0128: stloc.s expensiveInStockProducts + IL_0122: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0127: dup + IL_0128: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::expensiveInStockProducts@30 + IL_012d: stloc.s expensiveInStockProducts .line 38,38 : 1,34 '' - IL_012a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() - IL_012f: dup - IL_0130: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'customers@38-8' - IL_0135: stloc.s customers + IL_012f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getCustomerList() + IL_0134: dup + IL_0135: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::customers@38 + IL_013a: stloc.s customers .line 40,45 : 1,21 '' - IL_0137: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_013c: stloc.s V_12 - IL_013e: ldloc.s V_12 - IL_0140: ldloc.s V_12 - IL_0142: ldloc.s V_12 - IL_0144: ldloc.s V_12 - IL_0146: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_customers() - IL_014b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0150: ldloc.s V_12 - IL_0152: newobj instance void Linq101Where01/waCustomers@42::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0157: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_013c: nop + .line 41,41 : 5,10 '' + IL_013d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0142: stloc.s V_14 + IL_0144: ldloc.s V_14 + IL_0146: ldloc.s V_14 + IL_0148: ldloc.s V_14 + IL_014a: ldloc.s V_14 + IL_014c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Where01::get_customers() + IL_0151: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0156: ldloc.s V_14 + IL_0158: newobj instance void Linq101Where01/'Pipe #2 input at line 41@42'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_015d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_015c: newobj instance void Linq101Where01/'waCustomers@43-1'::.ctor() - IL_0161: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0162: ldsfld class Linq101Where01/'Pipe #2 input at line 41@43-1' Linq101Where01/'Pipe #2 input at line 41@43-1'::@_instance + IL_0167: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Where(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0166: newobj instance void Linq101Where01/'waCustomers@44-2'::.ctor() - IL_016b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_016c: ldsfld class Linq101Where01/'Pipe #2 input at line 41@44-2' Linq101Where01/'Pipe #2 input at line 41@44-2'::@_instance + IL_0171: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0170: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0175: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_017a: dup - IL_017b: stsfld class [Utils]Utils/Customer[] ''.$Linq101Where01::waCustomers@40 - IL_0180: stloc.s waCustomers + IL_0176: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_017b: stloc.s 'Pipe #2 input at line 41' + .line 45,45 : 10,21 '' + IL_017d: ldloc.s 'Pipe #2 input at line 41' + IL_017f: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0184: dup + IL_0185: stsfld class [Utils]Utils/Customer[] ''.$Linq101Where01::waCustomers@40 + IL_018a: stloc.s waCustomers .line 48,48 : 1,96 '' - IL_0182: ldstr "zero" - IL_0187: ldstr "one" - IL_018c: ldstr "two" - IL_0191: ldstr "three" - IL_0196: ldstr "four" - IL_019b: ldstr "five" - IL_01a0: ldstr "six" - IL_01a5: ldstr "seven" - IL_01aa: ldstr "eight" - IL_01af: ldstr "nine" - IL_01b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_01b9: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_01be: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_018c: ldstr "zero" + IL_0191: ldstr "one" + IL_0196: ldstr "two" + IL_019b: ldstr "three" + IL_01a0: ldstr "four" + IL_01a5: ldstr "five" + IL_01aa: ldstr "six" + IL_01af: ldstr "seven" + IL_01b4: ldstr "eight" + IL_01b9: ldstr "nine" + IL_01be: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() IL_01c3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_01c8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, @@ -1260,28 +1362,40 @@ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_01e6: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_01eb: dup - IL_01ec: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::'digits@48-6' - IL_01f1: stloc.s digits + IL_01eb: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_01f0: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) + IL_01f5: dup + IL_01f6: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Where01::digits@48 + IL_01fb: stloc.s digits .line 49,55 : 1,21 '' - IL_01f3: newobj instance void Linq101Where01/shortDigits@55::.ctor() - IL_01f8: newobj instance void Linq101Where01/'shortDigits@54-1'::.ctor() - IL_01fd: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0202: stloc.s V_13 - IL_0204: ldnull - IL_0205: ldc.i4.0 - IL_0206: ldnull - IL_0207: newobj instance void Linq101Where01/'shortDigits@52-2'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, - int32, - string) - IL_020c: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::MapIndexed>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + IL_01fd: nop + .line 50,50 : 5,10 '' + IL_01fe: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0203: stloc.s V_16 + IL_0205: ldnull + IL_0206: ldc.i4.0 + IL_0207: ldnull + IL_0208: newobj instance void Linq101Where01/'Pipe #3 input at line 50@52'::.ctor(class [mscorlib]System.Collections.Generic.IEnumerator`1, + int32, + string) + IL_020d: stloc.s 'Pipe #3 input at line 50' + .line 54,54 : 8,68 '' + IL_020f: ldsfld class Linq101Where01/'Pipe #3 stage #1 at line 54@54' Linq101Where01/'Pipe #3 stage #1 at line 54@54'::@_instance + IL_0214: ldloc.s 'Pipe #3 input at line 50' + IL_0216: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::MapIndexed>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0211: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Choose,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + IL_021b: stloc.s 'Pipe #3 stage #1 at line 54' + .line 55,55 : 8,21 '' + IL_021d: ldsfld class Linq101Where01/shortDigits@55 Linq101Where01/shortDigits@55::@_instance + IL_0222: ldloc.s 'Pipe #3 stage #1 at line 54' + IL_0224: call class [mscorlib]System.Collections.Generic.IEnumerable`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Choose,string>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0216: dup - IL_0217: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::shortDigits@49 - IL_021c: stloc.s shortDigits - IL_021e: ret + IL_0229: dup + IL_022a: stsfld class [mscorlib]System.Collections.Generic.IEnumerable`1 ''.$Linq101Where01::shortDigits@49 + IL_022f: stloc.s shortDigits + IL_0231: ret } // end of method $Linq101Where01::main@ } // end of class ''.$Linq101Where01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest1.il.bsl index 884c03da12a..4b4e0c5bf76 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest1.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest1 { - // Offset: 0x00000000 Length: 0x00000267 + // Offset: 0x00000000 Length: 0x00000263 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest1 { - // Offset: 0x00000270 Length: 0x000000AD + // Offset: 0x00000268 Length: 0x000000AD } .module SeqExpressionSteppingTest1.exe -// MVID: {59B19240-2432-947D-A745-03834092B159} +// MVID: {611B0EC5-2432-947D-A745-0383C50E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x06CF0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -87,51 +87,47 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 66 (0x42) - .maxstack 6 + // Code size 62 (0x3e) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest1.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest1.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_0017, - IL_0019) - IL_0015: br.s IL_0021 - - IL_0017: br.s IL_001b - - IL_0019: br.s IL_001e + IL_001a) + IL_0015: br.s IL_001d .line 100001,100001 : 0,0 '' - IL_001b: nop - IL_001c: br.s IL_0032 + IL_0017: nop + IL_0018: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_001e: nop - IL_001f: br.s IL_0039 + IL_001a: nop + IL_001b: br.s IL_0035 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: ldarg.0 - IL_0023: ldc.i4.1 - IL_0024: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc + IL_001d: nop .line 6,6 : 15,22 '' - IL_0029: ldarg.0 - IL_002a: ldc.i4.1 - IL_002b: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::current - IL_0030: ldc.i4.1 - IL_0031: ret - - IL_0032: ldarg.0 - IL_0033: ldc.i4.2 - IL_0034: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc - IL_0039: ldarg.0 - IL_003a: ldc.i4.0 - IL_003b: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::current - IL_0040: ldc.i4.0 - IL_0041: ret + IL_001e: ldarg.0 + IL_001f: ldc.i4.1 + IL_0020: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::current + IL_002c: ldc.i4.1 + IL_002d: ret + + IL_002e: ldarg.0 + IL_002f: ldc.i4.2 + IL_0030: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc + IL_0035: ldarg.0 + IL_0036: ldc.i4.0 + IL_0037: stfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::current + IL_003c: ldc.i4.0 + IL_003d: ret } // end of method f0@6::GenerateNext .method public strict virtual instance void @@ -148,42 +144,36 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 45 (0x2d) + // Code size 39 (0x27) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1/f0@6::pc IL_0006: switch ( IL_0019, - IL_001b, - IL_001d) - IL_0017: br.s IL_0028 - - IL_0019: br.s IL_001f - - IL_001b: br.s IL_0022 - - IL_001d: br.s IL_0025 + IL_001c, + IL_001f) + IL_0017: br.s IL_0022 .line 100001,100001 : 0,0 '' - IL_001f: nop - IL_0020: br.s IL_002b + IL_0019: nop + IL_001a: br.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0022: nop - IL_0023: br.s IL_0029 + IL_001c: nop + IL_001d: br.s IL_0023 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002b + IL_001f: nop + IL_0020: br.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: ldc.i4.0 - IL_002a: ret + IL_0022: nop + IL_0023: ldc.i4.0 + IL_0024: ret - IL_002b: ldc.i4.0 - IL_002c: ret + IL_0025: ldc.i4.0 + IL_0026: ret } // end of method f0@6::get_CheckClose .method public strict virtual instance int32 @@ -241,13 +231,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 12 (0xc) - .maxstack 8 - .line 8,8 : 13,30 '' + // Code size 14 (0xe) + .maxstack 3 + .locals init ([0] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 8') + .line 8,8 : 13,17 '' IL_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionSteppingTest1/SeqExpressionSteppingTest1::f0() - IL_0005: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000a: pop - IL_000b: ret + IL_0005: stloc.0 + .line 8,8 : 20,30 '' + IL_0006: ldloc.0 + IL_0007: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_000c: pop + IL_000d: ret } // end of method $SeqExpressionSteppingTest1::main@ } // end of class ''.$SeqExpressionSteppingTest1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest2.il.bsl index e5450059c32..91422d1148b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest2.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest2 { - // Offset: 0x00000000 Length: 0x00000267 + // Offset: 0x00000000 Length: 0x00000263 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest2 { - // Offset: 0x00000270 Length: 0x000000AD + // Offset: 0x00000268 Length: 0x000000AD } .module SeqExpressionSteppingTest2.exe -// MVID: {59B19240-2432-951E-A745-03834092B159} +// MVID: {611B0EC5-2432-951E-A745-0383C50E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00690000 +// Image base: 0x06940000 // =============== CLASS MEMBERS DECLARATION =================== @@ -87,78 +87,72 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 123 (0x7b) + // Code size 117 (0x75) .maxstack 6 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest2.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest2.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_004b + IL_001b: nop + IL_001c: br.s IL_0045 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_006b + IL_001e: nop + IL_001f: br.s IL_0065 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0072 + IL_0021: nop + IL_0022: br.s IL_006c .line 100001,100001 : 0,0 '' - IL_002a: nop + IL_0024: nop .line 5,5 : 15,30 '' - IL_002b: ldstr "hello" - IL_0030: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0035: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_003a: pop - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc + IL_0025: ldstr "hello" + IL_002a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_002f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0034: pop .line 6,6 : 15,22 '' - IL_0042: ldarg.0 + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc + IL_003c: ldarg.0 + IL_003d: ldc.i4.1 + IL_003e: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current IL_0043: ldc.i4.1 - IL_0044: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current - IL_0049: ldc.i4.1 - IL_004a: ret + IL_0044: ret .line 7,7 : 15,32 '' - IL_004b: ldstr "goodbye" - IL_0050: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0055: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_005a: pop - IL_005b: ldarg.0 - IL_005c: ldc.i4.2 - IL_005d: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc + IL_0045: ldstr "goodbye" + IL_004a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_004f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0054: pop .line 8,8 : 15,22 '' - IL_0062: ldarg.0 - IL_0063: ldc.i4.2 - IL_0064: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current - IL_0069: ldc.i4.1 - IL_006a: ret - - IL_006b: ldarg.0 - IL_006c: ldc.i4.3 - IL_006d: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc - IL_0072: ldarg.0 + IL_0055: ldarg.0 + IL_0056: ldc.i4.2 + IL_0057: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc + IL_005c: ldarg.0 + IL_005d: ldc.i4.2 + IL_005e: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current + IL_0063: ldc.i4.1 + IL_0064: ret + + IL_0065: ldarg.0 + IL_0066: ldc.i4.3 + IL_0067: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc + IL_006c: ldarg.0 + IL_006d: ldc.i4.0 + IL_006e: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current IL_0073: ldc.i4.0 - IL_0074: stfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::current - IL_0079: ldc.i4.0 - IL_007a: ret + IL_0074: ret } // end of method f1@5::GenerateNext .method public strict virtual instance void @@ -175,52 +169,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2/f1@5::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method f1@5::get_CheckClose .method public strict virtual instance int32 @@ -278,13 +264,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 12 (0xc) - .maxstack 8 - .line 10,10 : 13,30 '' + // Code size 14 (0xe) + .maxstack 3 + .locals init ([0] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 10') + .line 10,10 : 13,17 '' IL_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionSteppingTest2/SeqExpressionSteppingTest2::f1() - IL_0005: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000a: pop - IL_000b: ret + IL_0005: stloc.0 + .line 10,10 : 20,30 '' + IL_0006: ldloc.0 + IL_0007: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_000c: pop + IL_000d: ret } // end of method $SeqExpressionSteppingTest2::main@ } // end of class ''.$SeqExpressionSteppingTest2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest3.il.bsl index 37e1a739636..5dfb9d70895 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest3.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest3 { - // Offset: 0x00000000 Length: 0x00000277 + // Offset: 0x00000000 Length: 0x00000273 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest3 { - // Offset: 0x00000280 Length: 0x000000AD + // Offset: 0x00000278 Length: 0x000000AD } .module SeqExpressionSteppingTest3.exe -// MVID: {59B19240-2432-943F-A745-03834092B159} +// MVID: {611B0EC5-2432-943F-A745-0383C50E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02660000 +// Image base: 0x06440000 // =============== CLASS MEMBERS DECLARATION =================== @@ -92,73 +92,69 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1>& next) cil managed { - // Code size 116 (0x74) + // Code size 112 (0x70) .maxstack 6 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest3.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest3.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_0017, - IL_0019) - IL_0015: br.s IL_0021 - - IL_0017: br.s IL_001b - - IL_0019: br.s IL_001e + IL_001a) + IL_0015: br.s IL_001d .line 100001,100001 : 0,0 '' - IL_001b: nop - IL_001c: br.s IL_0061 + IL_0017: nop + IL_0018: br.s IL_005d .line 100001,100001 : 0,0 '' - IL_001e: nop - IL_001f: br.s IL_006b + IL_001a: nop + IL_001b: br.s IL_0067 .line 100001,100001 : 0,0 '' - IL_0021: nop - .line 6,6 : 21,27 '' - IL_0022: ldarg.0 - IL_0023: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x - IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002d: ldc.i4.4 - IL_002e: bge.s IL_0064 + IL_001d: nop + .line 6,6 : 15,27 '' + IL_001e: ldarg.0 + IL_001f: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0029: ldc.i4.4 + IL_002a: bge.s IL_0060 .line 7,7 : 18,24 '' - IL_0030: ldarg.0 - IL_0031: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x - IL_0036: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_003b: nop + IL_002c: ldarg.0 + IL_002d: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x + IL_0032: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0037: nop .line 8,8 : 18,33 '' - IL_003c: ldstr "hello" - IL_0041: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0046: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_004b: pop - IL_004c: ldarg.0 - IL_004d: ldc.i4.1 - IL_004e: stfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc + IL_0038: ldstr "hello" + IL_003d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0042: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0047: pop .line 9,9 : 18,25 '' - IL_0053: ldarg.0 - IL_0054: ldarg.0 - IL_0055: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x - IL_005a: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::current - IL_005f: ldc.i4.1 - IL_0060: ret + IL_0048: ldarg.0 + IL_0049: ldc.i4.1 + IL_004a: stfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc + IL_004f: ldarg.0 + IL_0050: ldarg.0 + IL_0051: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::x + IL_0056: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::current + IL_005b: ldc.i4.1 + IL_005c: ret .line 100001,100001 : 0,0 '' - IL_0061: nop - IL_0062: br.s IL_0022 - - IL_0064: ldarg.0 - IL_0065: ldc.i4.2 - IL_0066: stfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc - IL_006b: ldarg.0 - IL_006c: ldnull - IL_006d: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::current - IL_0072: ldc.i4.0 - IL_0073: ret + IL_005d: nop + IL_005e: br.s IL_001e + + IL_0060: ldarg.0 + IL_0061: ldc.i4.2 + IL_0062: stfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc + IL_0067: ldarg.0 + IL_0068: ldnull + IL_0069: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::current + IL_006e: ldc.i4.0 + IL_006f: ret } // end of method f2@6::GenerateNext .method public strict virtual instance void @@ -175,42 +171,36 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 45 (0x2d) + // Code size 39 (0x27) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest3/SeqExpressionSteppingTest3/f2@6::pc IL_0006: switch ( IL_0019, - IL_001b, - IL_001d) - IL_0017: br.s IL_0028 - - IL_0019: br.s IL_001f - - IL_001b: br.s IL_0022 - - IL_001d: br.s IL_0025 + IL_001c, + IL_001f) + IL_0017: br.s IL_0022 .line 100001,100001 : 0,0 '' - IL_001f: nop - IL_0020: br.s IL_002b + IL_0019: nop + IL_001a: br.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0022: nop - IL_0023: br.s IL_0029 + IL_001c: nop + IL_001d: br.s IL_0023 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002b + IL_001f: nop + IL_0020: br.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: ldc.i4.0 - IL_002a: ret + IL_0022: nop + IL_0023: ldc.i4.0 + IL_0024: ret - IL_002b: ldc.i4.0 - IL_002c: ret + IL_0025: ldc.i4.0 + IL_0026: ret } // end of method f2@6::get_CheckClose .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 @@ -278,13 +268,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 12 (0xc) - .maxstack 8 - .line 11,11 : 13,30 '' + // Code size 14 (0xe) + .maxstack 3 + .locals init ([0] class [mscorlib]System.Collections.Generic.IEnumerable`1> 'Pipe #1 input at line 11') + .line 11,11 : 13,17 '' IL_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1> SeqExpressionSteppingTest3/SeqExpressionSteppingTest3::f2() - IL_0005: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000a: pop - IL_000b: ret + IL_0005: stloc.0 + .line 11,11 : 20,30 '' + IL_0006: ldloc.0 + IL_0007: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_000c: pop + IL_000d: ret } // end of method $SeqExpressionSteppingTest3::main@ } // end of class ''.$SeqExpressionSteppingTest3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest4.il.bsl index ea764c62bb0..0838e192a8b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest4.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest4 { - // Offset: 0x00000000 Length: 0x0000026F + // Offset: 0x00000000 Length: 0x00000263 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest4 { - // Offset: 0x00000278 Length: 0x000000AD + // Offset: 0x00000268 Length: 0x000000AD } .module SeqExpressionSteppingTest4.exe -// MVID: {5B9A68C1-2432-93E0-A745-0383C1689A5B} +// MVID: {611B0EC5-2432-93E0-A745-0383C50E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00760000 +// Image base: 0x06F50000 // =============== CLASS MEMBERS DECLARATION =================== @@ -97,107 +97,101 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 190 (0xbe) + // Code size 184 (0xb8) .maxstack 6 .locals init ([0] int32 z) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest4.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest4.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002d - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0027 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0078 + IL_001b: nop + IL_001c: br.s IL_0072 .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_00a0 + IL_001e: nop + IL_001f: br.s IL_009a .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00b5 + IL_0021: nop + IL_0022: br IL_00af .line 100001,100001 : 0,0 '' - IL_002d: nop + IL_0027: nop .line 5,5 : 15,28 '' - IL_002e: ldarg.0 - IL_002f: ldc.i4.0 - IL_0030: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0035: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x + IL_0028: ldarg.0 + IL_0029: ldc.i4.0 + IL_002a: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_002f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x .line 6,6 : 15,21 '' - IL_003a: ldarg.0 - IL_003b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x - IL_0040: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0045: nop + IL_0034: ldarg.0 + IL_0035: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x + IL_003a: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_003f: nop .line 7,7 : 15,28 '' - IL_0046: ldarg.0 - IL_0047: ldc.i4.0 - IL_0048: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_004d: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y + IL_0040: ldarg.0 + IL_0041: ldc.i4.0 + IL_0042: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0047: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y .line 8,8 : 15,21 '' - IL_0052: ldarg.0 - IL_0053: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y - IL_0058: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_005d: nop - IL_005e: ldarg.0 - IL_005f: ldc.i4.1 - IL_0060: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc + IL_004c: ldarg.0 + IL_004d: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y + IL_0052: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0057: nop .line 9,9 : 15,23 '' - IL_0065: ldarg.0 - IL_0066: ldarg.0 - IL_0067: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x - IL_006c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0071: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current - IL_0076: ldc.i4.1 - IL_0077: ret + IL_0058: ldarg.0 + IL_0059: ldc.i4.1 + IL_005a: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc + IL_005f: ldarg.0 + IL_0060: ldarg.0 + IL_0061: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x + IL_0066: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_006b: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current + IL_0070: ldc.i4.1 + IL_0071: ret .line 10,10 : 15,30 '' - IL_0078: ldarg.0 - IL_0079: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x - IL_007e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0083: ldarg.0 - IL_0084: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y - IL_0089: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_008e: add - IL_008f: stloc.0 - IL_0090: ldarg.0 - IL_0091: ldc.i4.2 - IL_0092: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc + IL_0072: ldarg.0 + IL_0073: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x + IL_0078: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_007d: ldarg.0 + IL_007e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y + IL_0083: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0088: add + IL_0089: stloc.0 .line 11,11 : 15,22 '' - IL_0097: ldarg.0 - IL_0098: ldloc.0 - IL_0099: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current - IL_009e: ldc.i4.1 - IL_009f: ret + IL_008a: ldarg.0 + IL_008b: ldc.i4.2 + IL_008c: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc + IL_0091: ldarg.0 + IL_0092: ldloc.0 + IL_0093: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current + IL_0098: ldc.i4.1 + IL_0099: ret .line 7,7 : 19,20 '' - IL_00a0: ldarg.0 - IL_00a1: ldnull - IL_00a2: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y - IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x - IL_00ae: ldarg.0 - IL_00af: ldc.i4.3 - IL_00b0: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc - IL_00b5: ldarg.0 + IL_009a: ldarg.0 + IL_009b: ldnull + IL_009c: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::y + IL_00a1: ldarg.0 + IL_00a2: ldnull + IL_00a3: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::x + IL_00a8: ldarg.0 + IL_00a9: ldc.i4.3 + IL_00aa: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc + IL_00af: ldarg.0 + IL_00b0: ldc.i4.0 + IL_00b1: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current IL_00b6: ldc.i4.0 - IL_00b7: stfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::current - IL_00bc: ldc.i4.0 - IL_00bd: ret + IL_00b7: ret } // end of method f3@5::GenerateNext .method public strict virtual instance void @@ -214,52 +208,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4/f3@5::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method f3@5::get_CheckClose .method public strict virtual instance int32 @@ -325,13 +311,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 12 (0xc) - .maxstack 8 - .line 13,13 : 13,30 '' + // Code size 14 (0xe) + .maxstack 3 + .locals init ([0] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 13') + .line 13,13 : 13,17 '' IL_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionSteppingTest4/SeqExpressionSteppingTest4::f3() - IL_0005: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000a: pop - IL_000b: ret + IL_0005: stloc.0 + .line 13,13 : 20,30 '' + IL_0006: ldloc.0 + IL_0007: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_000c: pop + IL_000d: ret } // end of method $SeqExpressionSteppingTest4::main@ } // end of class ''.$SeqExpressionSteppingTest4 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest5.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest5.il.bsl index 0af7608e807..665db6c83ac 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest5.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest5.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest5 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest5 { - // Offset: 0x00000000 Length: 0x0000026F + // Offset: 0x00000000 Length: 0x00000263 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest5 { - // Offset: 0x00000278 Length: 0x000000AD + // Offset: 0x00000268 Length: 0x000000AD } .module SeqExpressionSteppingTest5.exe -// MVID: {5B9A632A-2432-9401-A745-03832A639A5B} +// MVID: {611C4D82-2432-9401-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026A0000 +// Image base: 0x04AD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -97,134 +97,125 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 232 (0xe8) + // Code size 224 (0xe0) .maxstack 6 .locals init ([0] int32 z) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest5.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest5.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001f, - IL_0021, - IL_0023, - IL_0025) - IL_001d: br.s IL_0039 - - IL_001f: br.s IL_0027 - - IL_0021: br.s IL_002d - - IL_0023: br.s IL_0030 - - IL_0025: br.s IL_0033 + IL_0025, + IL_0028, + IL_002b) + IL_001d: br.s IL_0031 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br IL_00ae + IL_001f: nop + IL_0020: br IL_00a6 .line 100001,100001 : 0,0 '' - IL_002d: nop - IL_002e: br.s IL_007f + IL_0025: nop + IL_0026: br.s IL_0077 .line 100001,100001 : 0,0 '' - IL_0030: nop - IL_0031: br.s IL_00a7 + IL_0028: nop + IL_0029: br.s IL_009f .line 100001,100001 : 0,0 '' - IL_0033: nop - IL_0034: br IL_00df + IL_002b: nop + IL_002c: br IL_00d7 .line 100001,100001 : 0,0 '' - IL_0039: nop + IL_0031: nop .line 5,5 : 15,28 '' - IL_003a: ldarg.0 - IL_003b: ldc.i4.0 - IL_003c: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0041: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_0046: ldarg.0 - IL_0047: ldc.i4.1 - IL_0048: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_0032: ldarg.0 + IL_0033: ldc.i4.0 + IL_0034: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_0039: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_003e: ldarg.0 + IL_003f: ldc.i4.1 + IL_0040: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc .line 7,7 : 19,32 '' - IL_004d: ldarg.0 - IL_004e: ldc.i4.0 - IL_004f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) - IL_0054: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y + IL_0045: ldarg.0 + IL_0046: ldc.i4.0 + IL_0047: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) + IL_004c: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y .line 8,8 : 19,25 '' - IL_0059: ldarg.0 - IL_005a: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y - IL_005f: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0064: nop - IL_0065: ldarg.0 - IL_0066: ldc.i4.2 - IL_0067: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_0051: ldarg.0 + IL_0052: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y + IL_0057: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_005c: nop .line 9,9 : 19,27 '' - IL_006c: ldarg.0 - IL_006d: ldarg.0 - IL_006e: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_0073: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0078: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current - IL_007d: ldc.i4.1 - IL_007e: ret + IL_005d: ldarg.0 + IL_005e: ldc.i4.2 + IL_005f: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_0064: ldarg.0 + IL_0065: ldarg.0 + IL_0066: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_006b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0070: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current + IL_0075: ldc.i4.1 + IL_0076: ret .line 10,10 : 19,34 '' - IL_007f: ldarg.0 - IL_0080: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_0085: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_008a: ldarg.0 - IL_008b: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y - IL_0090: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0095: add - IL_0096: stloc.0 - IL_0097: ldarg.0 - IL_0098: ldc.i4.3 - IL_0099: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_0077: ldarg.0 + IL_0078: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_007d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0082: ldarg.0 + IL_0083: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y + IL_0088: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_008d: add + IL_008e: stloc.0 .line 11,11 : 19,26 '' - IL_009e: ldarg.0 - IL_009f: ldloc.0 - IL_00a0: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current - IL_00a5: ldc.i4.1 - IL_00a6: ret - - IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y - IL_00ae: ldarg.0 - IL_00af: ldc.i4.4 - IL_00b0: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_008f: ldarg.0 + IL_0090: ldc.i4.3 + IL_0091: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_0096: ldarg.0 + IL_0097: ldloc.0 + IL_0098: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current + IL_009d: ldc.i4.1 + IL_009e: ret + + IL_009f: ldarg.0 + IL_00a0: ldnull + IL_00a1: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::y + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.4 + IL_00a8: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc .line 13,13 : 18,24 '' - IL_00b5: ldarg.0 - IL_00b6: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_00bb: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_00c0: nop + IL_00ad: ldarg.0 + IL_00ae: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_00b3: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_00b8: nop .line 14,14 : 18,32 '' - IL_00c1: ldstr "done" - IL_00c6: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_00cb: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_00d0: pop - IL_00d1: ldarg.0 - IL_00d2: ldnull - IL_00d3: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_00d8: ldarg.0 - IL_00d9: ldc.i4.4 - IL_00da: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc - IL_00df: ldarg.0 - IL_00e0: ldc.i4.0 - IL_00e1: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current - IL_00e6: ldc.i4.0 - IL_00e7: ret + IL_00b9: ldstr "done" + IL_00be: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00c3: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00c8: pop + IL_00c9: ldarg.0 + IL_00ca: ldnull + IL_00cb: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_00d0: ldarg.0 + IL_00d1: ldc.i4.4 + IL_00d2: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_00d7: ldarg.0 + IL_00d8: ldc.i4.0 + IL_00d9: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current + IL_00de: ldc.i4.0 + IL_00df: ret } // end of method f4@5::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 176 (0xb0) + // Code size 157 (0x9d) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc @@ -236,181 +227,154 @@ .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_00a3 + IL_0014: br IL_0093 .line 100001,100001 : 0,0 '' IL_0019: nop + .line 100001,100001 : 0,0 '' .try { IL_001a: ldarg.0 IL_001b: ldfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc IL_0020: switch ( IL_003b, - IL_003d, - IL_003f, + IL_003e, IL_0041, - IL_0043) - IL_0039: br.s IL_0054 - - IL_003b: br.s IL_0045 - - IL_003d: br.s IL_0048 - - IL_003f: br.s IL_004b - - IL_0041: br.s IL_004e - - IL_0043: br.s IL_0051 + IL_0044, + IL_0047) + IL_0039: br.s IL_004a .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_007d + IL_003b: nop + IL_003c: br.s IL_0073 .line 100001,100001 : 0,0 '' - IL_0048: nop - IL_0049: br.s IL_0059 + IL_003e: nop + IL_003f: br.s IL_004f .line 100001,100001 : 0,0 '' - IL_004b: nop - IL_004c: br.s IL_0058 + IL_0041: nop + IL_0042: br.s IL_004e .line 100001,100001 : 0,0 '' - IL_004e: nop - IL_004f: br.s IL_0055 + IL_0044: nop + IL_0045: br.s IL_004b .line 100001,100001 : 0,0 '' - IL_0051: nop - IL_0052: br.s IL_007d + IL_0047: nop + IL_0048: br.s IL_0073 .line 100001,100001 : 0,0 '' - IL_0054: nop + IL_004a: nop .line 100001,100001 : 0,0 '' - IL_0055: nop - IL_0056: br.s IL_0059 + IL_004b: nop + IL_004c: br.s IL_004f .line 100001,100001 : 0,0 '' - IL_0058: nop - IL_0059: ldarg.0 - IL_005a: ldc.i4.4 - IL_005b: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_004e: nop + IL_004f: ldarg.0 + IL_0050: ldc.i4.4 + IL_0051: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc .line 13,13 : 18,24 '' - IL_0060: ldarg.0 - IL_0061: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x - IL_0066: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_006b: nop + IL_0056: ldarg.0 + IL_0057: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::x + IL_005c: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0061: nop .line 14,14 : 18,32 '' - IL_006c: ldstr "done" - IL_0071: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0076: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_007b: pop + IL_0062: ldstr "done" + IL_0067: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_006c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0071: pop .line 100001,100001 : 0,0 '' - IL_007c: nop - IL_007d: ldarg.0 - IL_007e: ldc.i4.4 - IL_007f: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc - IL_0084: ldarg.0 - IL_0085: ldc.i4.0 - IL_0086: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current - IL_008b: ldnull - IL_008c: stloc.1 - IL_008d: leave.s IL_009b + IL_0072: nop + IL_0073: ldarg.0 + IL_0074: ldc.i4.4 + IL_0075: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc + IL_007a: ldarg.0 + IL_007b: ldc.i4.0 + IL_007c: stfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::current + IL_0081: leave.s IL_008d } // end .try catch [mscorlib]System.Object { - IL_008f: castclass [mscorlib]System.Exception - IL_0094: stloc.2 + IL_0083: castclass [mscorlib]System.Exception + IL_0088: stloc.1 .line 5,5 : 19,20 '' - IL_0095: ldloc.2 - IL_0096: stloc.0 - IL_0097: ldnull - IL_0098: stloc.1 - IL_0099: leave.s IL_009b + IL_0089: ldloc.1 + IL_008a: stloc.0 + IL_008b: leave.s IL_008d .line 100001,100001 : 0,0 '' } // end handler - IL_009b: ldloc.1 - IL_009c: pop - .line 100001,100001 : 0,0 '' - IL_009d: nop - IL_009e: br IL_0000 - - IL_00a3: ldloc.0 - IL_00a4: ldnull - IL_00a5: cgt.un - IL_00a7: brfalse.s IL_00ab + IL_008d: nop + IL_008e: br IL_0000 - IL_00a9: br.s IL_00ad - - IL_00ab: br.s IL_00af + .line 5,5 : 19,20 '' + IL_0093: nop + .line 100001,100001 : 0,0 '' + IL_0094: ldloc.0 + IL_0095: ldnull + IL_0096: cgt.un + IL_0098: brfalse.s IL_009c .line 100001,100001 : 0,0 '' - IL_00ad: ldloc.0 - IL_00ae: throw + IL_009a: ldloc.0 + IL_009b: throw .line 100001,100001 : 0,0 '' - IL_00af: ret + IL_009c: ret } // end of method f4@5::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 67 (0x43) - .maxstack 5 + // Code size 57 (0x39) + .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5/f4@5::pc IL_0006: switch ( IL_0021, - IL_0023, - IL_0025, + IL_0024, IL_0027, - IL_0029) - IL_001f: br.s IL_003a - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e - - IL_0025: br.s IL_0031 - - IL_0027: br.s IL_0034 - - IL_0029: br.s IL_0037 + IL_002a, + IL_002d) + IL_001f: br.s IL_0030 .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0041 + IL_0021: nop + IL_0022: br.s IL_0037 .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_003f + IL_0024: nop + IL_0025: br.s IL_0035 .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: br.s IL_003d + IL_0027: nop + IL_0028: br.s IL_0033 .line 100001,100001 : 0,0 '' - IL_0034: nop - IL_0035: br.s IL_003b + IL_002a: nop + IL_002b: br.s IL_0031 .line 100001,100001 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_0041 + IL_002d: nop + IL_002e: br.s IL_0037 .line 100001,100001 : 0,0 '' - IL_003a: nop - IL_003b: ldc.i4.1 - IL_003c: ret + IL_0030: nop + IL_0031: ldc.i4.1 + IL_0032: ret - IL_003d: ldc.i4.1 - IL_003e: ret + IL_0033: ldc.i4.1 + IL_0034: ret - IL_003f: ldc.i4.1 - IL_0040: ret + IL_0035: ldc.i4.1 + IL_0036: ret - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0037: ldc.i4.0 + IL_0038: ret } // end of method f4@5::get_CheckClose .method public strict virtual instance int32 @@ -476,13 +440,17 @@ .method public static void main@() cil managed { .entrypoint - // Code size 12 (0xc) - .maxstack 8 - .line 16,16 : 13,30 '' + // Code size 14 (0xe) + .maxstack 3 + .locals init ([0] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 16') + .line 16,16 : 13,17 '' IL_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionSteppingTest5/SeqExpressionSteppingTest5::f4() - IL_0005: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000a: pop - IL_000b: ret + IL_0005: stloc.0 + .line 16,16 : 20,30 '' + IL_0006: ldloc.0 + IL_0007: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_000c: pop + IL_000d: ret } // end of method $SeqExpressionSteppingTest5::main@ } // end of class ''.$SeqExpressionSteppingTest5 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest6.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest6.il.bsl index d06d692b20b..c50b09633d3 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest6.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest6.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest6 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest6 { - // Offset: 0x00000000 Length: 0x000002A4 + // Offset: 0x00000000 Length: 0x00000298 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest6 { - // Offset: 0x000002A8 Length: 0x000000BA + // Offset: 0x000002A0 Length: 0x000000BA } .module SeqExpressionSteppingTest6.exe -// MVID: {5B9A632A-2432-94A2-A745-03832A639A5B} +// MVID: {611C4D82-2432-94A2-A745-0383824D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01330000 +// Image base: 0x07260000 // =============== CLASS MEMBERS DECLARATION =================== @@ -103,170 +103,161 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 304 (0x130) + // Code size 294 (0x126) .maxstack 6 .locals init ([0] int32 x, [1] int32 V_1) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest6.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest6.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_0023, - IL_0025, - IL_0027, + IL_0026, IL_0029, - IL_002b) - IL_0021: br.s IL_0045 - - IL_0023: br.s IL_002d - - IL_0025: br.s IL_0030 - - IL_0027: br.s IL_0033 - - IL_0029: br.s IL_0039 - - IL_002b: br.s IL_003f + IL_002f, + IL_0035) + IL_0021: br.s IL_003b .line 100001,100001 : 0,0 '' - IL_002d: nop - IL_002e: br.s IL_0099 + IL_0023: nop + IL_0024: br.s IL_008f .line 100001,100001 : 0,0 '' - IL_0030: nop - IL_0031: br.s IL_0096 + IL_0026: nop + IL_0027: br.s IL_008c .line 100001,100001 : 0,0 '' - IL_0033: nop - IL_0034: br IL_0106 + IL_0029: nop + IL_002a: br IL_00fc .line 100001,100001 : 0,0 '' - IL_0039: nop - IL_003a: br IL_0103 + IL_002f: nop + IL_0030: br IL_00f9 .line 100001,100001 : 0,0 '' - IL_003f: nop - IL_0040: br IL_0127 + IL_0035: nop + IL_0036: br IL_011d .line 100001,100001 : 0,0 '' - IL_0045: nop + IL_003b: nop .line 6,8 : 15,25 '' - IL_0046: ldarg.0 - IL_0047: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6::get_es() - IL_004c: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_0051: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' - IL_0056: ldarg.0 - IL_0057: ldc.i4.1 - IL_0058: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_003c: ldarg.0 + IL_003d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6::get_es() + IL_0042: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0047: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_004c: ldarg.0 + IL_004d: ldc.i4.1 + IL_004e: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc .line 6,8 : 15,25 '' - IL_005d: ldarg.0 - IL_005e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' - IL_0063: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0068: brfalse.s IL_0099 - - IL_006a: ldarg.0 - IL_006b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' - IL_0070: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0075: stloc.0 + IL_0053: ldarg.0 + IL_0054: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_0059: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_005e: brfalse.s IL_008f + + IL_0060: ldarg.0 + IL_0061: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_0066: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_006b: stloc.0 .line 7,7 : 18,33 '' - IL_0076: ldstr "hello" - IL_007b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0080: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0085: pop - IL_0086: ldarg.0 - IL_0087: ldc.i4.2 - IL_0088: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_006c: ldstr "hello" + IL_0071: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0076: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_007b: pop .line 8,8 : 18,25 '' - IL_008d: ldarg.0 - IL_008e: ldloc.0 - IL_008f: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current - IL_0094: ldc.i4.1 - IL_0095: ret + IL_007c: ldarg.0 + IL_007d: ldc.i4.2 + IL_007e: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_0083: ldarg.0 + IL_0084: ldloc.0 + IL_0085: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current + IL_008a: ldc.i4.1 + IL_008b: ret .line 100001,100001 : 0,0 '' - IL_0096: nop - IL_0097: br.s IL_005d + IL_008c: nop + IL_008d: br.s IL_0053 - IL_0099: ldarg.0 - IL_009a: ldc.i4.5 - IL_009b: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_008f: ldarg.0 + IL_0090: ldc.i4.5 + IL_0091: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + .line 6,8 : 15,25 '' + IL_0096: ldarg.0 + IL_0097: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_009c: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_00a1: nop .line 6,8 : 15,25 '' - IL_00a0: ldarg.0 - IL_00a1: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' - IL_00a6: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_00ab: nop - IL_00ac: ldarg.0 - IL_00ad: ldnull - IL_00ae: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_00a2: ldarg.0 + IL_00a3: ldnull + IL_00a4: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' .line 9,11 : 15,25 '' - IL_00b3: ldarg.0 - IL_00b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6::get_es() - IL_00b9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_00be: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_00c3: ldarg.0 - IL_00c4: ldc.i4.3 - IL_00c5: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_00a9: ldarg.0 + IL_00aa: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6::get_es() + IL_00af: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_00b4: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_00b9: ldarg.0 + IL_00ba: ldc.i4.3 + IL_00bb: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc .line 9,11 : 15,25 '' - IL_00ca: ldarg.0 - IL_00cb: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_00d0: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_00d5: brfalse.s IL_0106 - - IL_00d7: ldarg.0 - IL_00d8: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_00dd: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_00e2: stloc.1 + IL_00c0: ldarg.0 + IL_00c1: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_00c6: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_00cb: brfalse.s IL_00fc + + IL_00cd: ldarg.0 + IL_00ce: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_00d3: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_00d8: stloc.1 .line 10,10 : 18,35 '' - IL_00e3: ldstr "goodbye" - IL_00e8: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_00ed: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_00f2: pop - IL_00f3: ldarg.0 - IL_00f4: ldc.i4.4 - IL_00f5: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_00d9: ldstr "goodbye" + IL_00de: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_00e3: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00e8: pop .line 11,11 : 18,25 '' - IL_00fa: ldarg.0 - IL_00fb: ldloc.1 - IL_00fc: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current - IL_0101: ldc.i4.1 - IL_0102: ret + IL_00e9: ldarg.0 + IL_00ea: ldc.i4.4 + IL_00eb: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_00f0: ldarg.0 + IL_00f1: ldloc.1 + IL_00f2: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current + IL_00f7: ldc.i4.1 + IL_00f8: ret .line 100001,100001 : 0,0 '' - IL_0103: nop - IL_0104: br.s IL_00ca + IL_00f9: nop + IL_00fa: br.s IL_00c0 - IL_0106: ldarg.0 - IL_0107: ldc.i4.5 - IL_0108: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_00fc: ldarg.0 + IL_00fd: ldc.i4.5 + IL_00fe: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + .line 9,11 : 15,25 '' + IL_0103: ldarg.0 + IL_0104: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_0109: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_010e: nop .line 9,11 : 15,25 '' - IL_010d: ldarg.0 - IL_010e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_0113: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0118: nop - IL_0119: ldarg.0 - IL_011a: ldnull - IL_011b: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_0120: ldarg.0 - IL_0121: ldc.i4.5 - IL_0122: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc - IL_0127: ldarg.0 - IL_0128: ldc.i4.0 - IL_0129: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current - IL_012e: ldc.i4.0 - IL_012f: ret + IL_010f: ldarg.0 + IL_0110: ldnull + IL_0111: stfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_0116: ldarg.0 + IL_0117: ldc.i4.5 + IL_0118: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_011d: ldarg.0 + IL_011e: ldc.i4.0 + IL_011f: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current + IL_0124: ldc.i4.0 + IL_0125: ret } // end of method f7@6::GenerateNext .method public strict virtual instance void Close() cil managed { - // Code size 189 (0xbd) + // Code size 168 (0xa8) .maxstack 6 .locals init ([0] class [mscorlib]System.Exception V_0, - [1] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_1, - [2] class [mscorlib]System.Exception e) + [1] class [mscorlib]System.Exception e) .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc @@ -278,201 +269,170 @@ .line 100001,100001 : 0,0 '' IL_0013: nop - IL_0014: br IL_00b0 + IL_0014: br IL_009e .line 100001,100001 : 0,0 '' IL_0019: nop + .line 100001,100001 : 0,0 '' .try { IL_001a: ldarg.0 IL_001b: ldfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc IL_0020: switch ( IL_003f, - IL_0041, - IL_0043, + IL_0042, IL_0045, - IL_0047, - IL_0049) - IL_003d: br.s IL_005d - - IL_003f: br.s IL_004b - - IL_0041: br.s IL_004e - - IL_0043: br.s IL_0051 - - IL_0045: br.s IL_0054 - - IL_0047: br.s IL_0057 - - IL_0049: br.s IL_005a + IL_0048, + IL_004b, + IL_004e) + IL_003d: br.s IL_0051 .line 100001,100001 : 0,0 '' - IL_004b: nop - IL_004c: br.s IL_008a + IL_003f: nop + IL_0040: br.s IL_007e .line 100001,100001 : 0,0 '' - IL_004e: nop - IL_004f: br.s IL_0076 + IL_0042: nop + IL_0043: br.s IL_006a .line 100001,100001 : 0,0 '' - IL_0051: nop - IL_0052: br.s IL_0075 + IL_0045: nop + IL_0046: br.s IL_0069 .line 100001,100001 : 0,0 '' - IL_0054: nop - IL_0055: br.s IL_005f + IL_0048: nop + IL_0049: br.s IL_0053 .line 100001,100001 : 0,0 '' - IL_0057: nop - IL_0058: br.s IL_005e + IL_004b: nop + IL_004c: br.s IL_0052 .line 100001,100001 : 0,0 '' - IL_005a: nop - IL_005b: br.s IL_008a + IL_004e: nop + IL_004f: br.s IL_007e .line 100001,100001 : 0,0 '' - IL_005d: nop + IL_0051: nop .line 100001,100001 : 0,0 '' - IL_005e: nop - IL_005f: ldarg.0 - IL_0060: ldc.i4.5 - IL_0061: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc - IL_0066: ldarg.0 - IL_0067: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 - IL_006c: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0071: nop + IL_0052: nop + IL_0053: ldarg.0 + IL_0054: ldc.i4.5 + IL_0055: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_005a: ldarg.0 + IL_005b: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::enum0 + IL_0060: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_0065: nop .line 100001,100001 : 0,0 '' - IL_0072: nop - IL_0073: br.s IL_008a + IL_0066: nop + IL_0067: br.s IL_007e .line 100001,100001 : 0,0 '' - IL_0075: nop - IL_0076: ldarg.0 - IL_0077: ldc.i4.5 - IL_0078: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc - IL_007d: ldarg.0 - IL_007e: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' - IL_0083: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) - IL_0088: nop + IL_0069: nop + IL_006a: ldarg.0 + IL_006b: ldc.i4.5 + IL_006c: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_0071: ldarg.0 + IL_0072: ldfld class [mscorlib]System.Collections.Generic.IEnumerator`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::'enum' + IL_0077: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::Dispose>(!!0) + IL_007c: nop .line 100001,100001 : 0,0 '' - IL_0089: nop - IL_008a: ldarg.0 - IL_008b: ldc.i4.5 - IL_008c: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc - IL_0091: ldarg.0 - IL_0092: ldc.i4.0 - IL_0093: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current - IL_0098: ldnull - IL_0099: stloc.1 - IL_009a: leave.s IL_00a8 + IL_007d: nop + IL_007e: ldarg.0 + IL_007f: ldc.i4.5 + IL_0080: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc + IL_0085: ldarg.0 + IL_0086: ldc.i4.0 + IL_0087: stfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::current + IL_008c: leave.s IL_0098 } // end .try catch [mscorlib]System.Object { - IL_009c: castclass [mscorlib]System.Exception - IL_00a1: stloc.2 + IL_008e: castclass [mscorlib]System.Exception + IL_0093: stloc.1 .line 6,8 : 15,25 '' - IL_00a2: ldloc.2 - IL_00a3: stloc.0 - IL_00a4: ldnull - IL_00a5: stloc.1 - IL_00a6: leave.s IL_00a8 + IL_0094: ldloc.1 + IL_0095: stloc.0 + IL_0096: leave.s IL_0098 .line 100001,100001 : 0,0 '' } // end handler - IL_00a8: ldloc.1 - IL_00a9: pop - .line 100001,100001 : 0,0 '' - IL_00aa: nop - IL_00ab: br IL_0000 - - IL_00b0: ldloc.0 - IL_00b1: ldnull - IL_00b2: cgt.un - IL_00b4: brfalse.s IL_00b8 + IL_0098: nop + IL_0099: br IL_0000 - IL_00b6: br.s IL_00ba - - IL_00b8: br.s IL_00bc + .line 6,8 : 15,25 '' + IL_009e: nop + .line 100001,100001 : 0,0 '' + IL_009f: ldloc.0 + IL_00a0: ldnull + IL_00a1: cgt.un + IL_00a3: brfalse.s IL_00a7 .line 100001,100001 : 0,0 '' - IL_00ba: ldloc.0 - IL_00bb: throw + IL_00a5: ldloc.0 + IL_00a6: throw .line 100001,100001 : 0,0 '' - IL_00bc: ret + IL_00a7: ret } // end of method f7@6::Close .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 78 (0x4e) + // Code size 66 (0x42) .maxstack 5 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6/f7@6::pc IL_0006: switch ( IL_0025, - IL_0027, - IL_0029, + IL_0028, IL_002b, - IL_002d, - IL_002f) - IL_0023: br.s IL_0043 - - IL_0025: br.s IL_0031 - - IL_0027: br.s IL_0034 - - IL_0029: br.s IL_0037 - - IL_002b: br.s IL_003a - - IL_002d: br.s IL_003d - - IL_002f: br.s IL_0040 + IL_002e, + IL_0031, + IL_0034) + IL_0023: br.s IL_0037 .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: br.s IL_004c + IL_0025: nop + IL_0026: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_0034: nop - IL_0035: br.s IL_004a + IL_0028: nop + IL_0029: br.s IL_003e .line 100001,100001 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_0048 + IL_002b: nop + IL_002c: br.s IL_003c .line 100001,100001 : 0,0 '' - IL_003a: nop - IL_003b: br.s IL_0046 + IL_002e: nop + IL_002f: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_003d: nop - IL_003e: br.s IL_0044 + IL_0031: nop + IL_0032: br.s IL_0038 .line 100001,100001 : 0,0 '' - IL_0040: nop - IL_0041: br.s IL_004c + IL_0034: nop + IL_0035: br.s IL_0040 .line 100001,100001 : 0,0 '' - IL_0043: nop - IL_0044: ldc.i4.1 - IL_0045: ret + IL_0037: nop + IL_0038: ldc.i4.1 + IL_0039: ret - IL_0046: ldc.i4.1 - IL_0047: ret + IL_003a: ldc.i4.1 + IL_003b: ret - IL_0048: ldc.i4.1 - IL_0049: ret + IL_003c: ldc.i4.1 + IL_003d: ret - IL_004a: ldc.i4.1 - IL_004b: ret + IL_003e: ldc.i4.1 + IL_003f: ret - IL_004c: ldc.i4.0 - IL_004d: ret + IL_0040: ldc.i4.0 + IL_0041: ret } // end of method f7@6::get_CheckClose .method public strict virtual instance int32 @@ -555,9 +515,10 @@ .method public static void main@() cil managed { .entrypoint - // Code size 42 (0x2a) + // Code size 44 (0x2c) .maxstack 6 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 es) + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 es, + [1] class [mscorlib]System.Collections.Generic.IEnumerable`1 'Pipe #1 input at line 13') .line 4,4 : 5,21 '' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 @@ -572,11 +533,14 @@ IL_0017: dup IL_0018: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$SeqExpressionSteppingTest6::es@4 IL_001d: stloc.0 - .line 13,13 : 13,31 '' + .line 13,13 : 13,17 '' IL_001e: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionSteppingTest6/SeqExpressionSteppingTest6::f7() - IL_0023: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0028: pop - IL_0029: ret + IL_0023: stloc.1 + .line 13,13 : 21,31 '' + IL_0024: ldloc.1 + IL_0025: call int32 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::Length(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_002a: pop + IL_002b: ret } // end of method $SeqExpressionSteppingTest6::main@ } // end of class ''.$SeqExpressionSteppingTest6 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest7.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest7.il.bsl index ae9e2337813..7965bb568e8 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest7.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionStepping/SeqExpressionSteppingTest7.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 + .ver 5:0:0:0 } .assembly SeqExpressionSteppingTest7 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionSteppingTest7 { - // Offset: 0x00000000 Length: 0x00000272 + // Offset: 0x00000000 Length: 0x00000266 } .mresource public FSharpOptimizationData.SeqExpressionSteppingTest7 { - // Offset: 0x00000278 Length: 0x00000098 + // Offset: 0x00000270 Length: 0x00000098 } .module SeqExpressionSteppingTest7.exe -// MVID: {5B9A632A-2432-93C3-A745-03832A639A5B} +// MVID: {611C5DB0-2432-93C3-A745-0383B05D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02450000 +// Image base: 0x06AC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,205 +51,6 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar serializable sealed nested assembly beforefieldinit specialname f@5 - extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) - .field public int32 pc - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .field public !a current - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(int32 pc, - !a current) cil managed - { - // Code size 21 (0x15) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldarg.1 - IL_0002: stfld int32 class SeqExpressionSteppingTest7/f@5::pc - IL_0007: ldarg.0 - IL_0008: ldarg.2 - IL_0009: stfld !0 class SeqExpressionSteppingTest7/f@5::current - IL_000e: ldarg.0 - IL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1::.ctor() - IL_0014: ret - } // end of method f@5::.ctor - - .method public strict virtual instance int32 - GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed - { - // Code size 113 (0x71) - .maxstack 7 - .locals init ([0] string V_0, - [1] !a V_1) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest7.fs' - IL_0000: ldarg.0 - IL_0001: ldfld int32 class SeqExpressionSteppingTest7/f@5::pc - IL_0006: ldc.i4.1 - IL_0007: sub - IL_0008: switch ( - IL_0017, - IL_0019) - IL_0015: br.s IL_0021 - - IL_0017: br.s IL_001b - - IL_0019: br.s IL_001e - - .line 100001,100001 : 0,0 '' - IL_001b: nop - IL_001c: br.s IL_005c - - .line 100001,100001 : 0,0 '' - IL_001e: nop - IL_001f: br.s IL_0068 - - .line 100001,100001 : 0,0 '' - IL_0021: nop - .line 5,5 : 14,36 '' - IL_0022: nop - .line 5,5 : 18,24 '' - IL_0023: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest7::get_r() - IL_0028: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002d: nop - .line 5,5 : 26,30 '' - IL_002e: ldc.i4.1 - IL_002f: brfalse.s IL_0033 - - IL_0031: br.s IL_0035 - - IL_0033: br.s IL_005f - - .line 5,5 : 44,55 '' - IL_0035: ldstr "" - IL_003a: stloc.0 - IL_003b: ldarg.0 - IL_003c: ldc.i4.1 - IL_003d: stfld int32 class SeqExpressionSteppingTest7/f@5::pc - .line 5,5 : 44,55 '' - IL_0042: ldarg.1 - IL_0043: ldc.i4.0 - IL_0044: brfalse.s IL_004e - - IL_0046: ldnull - IL_0047: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_004c: br.s IL_0055 - - IL_004e: ldloc.0 - IL_004f: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0054: throw - - IL_0055: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_005a: ldc.i4.2 - IL_005b: ret - - .line 100001,100001 : 0,0 '' - IL_005c: nop - IL_005d: br.s IL_0061 - - .line 5,5 : 14,36 '' - IL_005f: nop - .line 100001,100001 : 0,0 '' - IL_0060: nop - IL_0061: ldarg.0 - IL_0062: ldc.i4.2 - IL_0063: stfld int32 class SeqExpressionSteppingTest7/f@5::pc - IL_0068: ldarg.0 - IL_0069: ldloc.1 - IL_006a: stfld !0 class SeqExpressionSteppingTest7/f@5::current - IL_006f: ldc.i4.0 - IL_0070: ret - } // end of method f@5::GenerateNext - - .method public strict virtual instance void - Close() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldc.i4.2 - IL_0002: stfld int32 class SeqExpressionSteppingTest7/f@5::pc - IL_0007: ret - } // end of method f@5::Close - - .method public strict virtual instance bool - get_CheckClose() cil managed - { - // Code size 46 (0x2e) - .maxstack 8 - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldfld int32 class SeqExpressionSteppingTest7/f@5::pc - IL_0006: switch ( - IL_0019, - IL_001b, - IL_001d) - IL_0017: br.s IL_0028 - - IL_0019: br.s IL_001f - - IL_001b: br.s IL_0022 - - IL_001d: br.s IL_0025 - - .line 100001,100001 : 0,0 '' - IL_001f: nop - IL_0020: br.s IL_002c - - .line 100001,100001 : 0,0 '' - IL_0022: nop - IL_0023: br.s IL_0029 - - .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002c - - .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: ldc.i4.0 - IL_002a: ret - - .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method f@5::get_CheckClose - - .method public strict virtual instance !a - get_LastGenerated() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld !0 class SeqExpressionSteppingTest7/f@5::current - IL_0006: ret - } // end of method f@5::get_LastGenerated - - .method public strict virtual instance class [mscorlib]System.Collections.Generic.IEnumerator`1 - GetFreshEnumerator() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 8 (0x8) - .maxstack 6 - .locals init (!a V_0) - IL_0000: ldc.i4.0 - IL_0001: ldloc.0 - IL_0002: newobj instance void class SeqExpressionSteppingTest7/f@5::.ctor(int32, - !0) - IL_0007: ret - } // end of method f@5::GetFreshEnumerator - - } // end of class f@5 - .method public specialname static class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 get_r() cil managed { @@ -262,17 +63,52 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 f() cil managed { - // Code size 15 (0xf) - .maxstack 4 - .locals init ([0] !!a V_0) + // Code size 61 (0x3d) + .maxstack 5 + .locals init ([0] valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1 V_0, + [1] string V_1) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 5,5 : 12,57 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionStepping\\SeqExpressionSteppingTest7.fs' + IL_0000: nop + .line 5,5 : 14,36 '' + IL_0001: nop + .line 5,5 : 18,24 '' + IL_0002: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest7::get_r() + IL_0007: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_000c: nop + .line 5,5 : 26,30 '' + IL_000d: ldc.i4.1 + IL_000e: brfalse.s IL_0033 + + .line 5,5 : 44,55 '' + IL_0010: ldstr "" + IL_0015: stloc.1 + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.0 + IL_0019: brfalse.s IL_0023 + + IL_001b: ldnull + IL_001c: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0021: br.s IL_002a + + IL_0023: ldloc.1 + IL_0024: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0029: throw + + IL_002a: call instance void valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::AddMany(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_002f: nop + .line 100001,100001 : 0,0 '' + IL_0030: nop + IL_0031: br.s IL_0035 + + .line 5,5 : 14,36 '' + IL_0033: nop + .line 100001,100001 : 0,0 '' + IL_0034: nop .line 5,5 : 12,57 '' - IL_0000: ldc.i4.0 - IL_0001: ldloc.0 - IL_0002: newobj instance void class SeqExpressionSteppingTest7/f@5::.ctor(int32, - !0) - IL_0007: tail. - IL_0009: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToList(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_000e: ret + IL_0035: ldloca.s V_0 + IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.ListCollector`1::Close() + IL_003c: ret } // end of method SeqExpressionSteppingTest7::f .property class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 @@ -295,14 +131,13 @@ .method public static void main@() cil managed { .entrypoint - // Code size 107 (0x6b) + // Code size 98 (0x62) .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 r, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_1, [2] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_2, - [3] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_3, - [4] class [mscorlib]System.Exception V_4, - [5] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_5) + [3] class [mscorlib]System.Exception V_3, + [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4) .line 4,4 : 1,14 '' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) @@ -313,57 +148,51 @@ IL_000d: ldstr "res = %A" IL_0012: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit>,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>::.ctor(string) IL_0017: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine,class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_001c: stloc.1 .line 6,6 : 21,24 '' + IL_001c: stloc.1 + .line 6,6 : 25,29 '' .try { - IL_001d: nop - .line 6,6 : 25,29 '' - IL_001e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest7::f() - IL_0023: stloc.3 - IL_0024: leave.s IL_0060 + IL_001d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 SeqExpressionSteppingTest7::f() + IL_0022: stloc.2 + IL_0023: leave.s IL_0059 .line 6,6 : 30,34 '' } // end .try catch [mscorlib]System.Object { - IL_0026: castclass [mscorlib]System.Exception - IL_002b: stloc.s V_4 - IL_002d: ldloc.s V_4 - IL_002f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) - IL_0034: stloc.s V_5 - IL_0036: ldloc.s V_5 - IL_0038: brfalse.s IL_003c - - IL_003a: br.s IL_003e - - IL_003c: br.s IL_0055 + IL_0025: castclass [mscorlib]System.Exception + IL_002a: stloc.3 + IL_002b: ldloc.3 + IL_002c: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) + IL_0031: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0033: ldloc.s V_4 + IL_0035: brfalse.s IL_004e .line 6,6 : 48,52 '' - IL_003e: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest7::get_r() - IL_0043: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_0048: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_004d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0037: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 SeqExpressionSteppingTest7::get_r() + IL_003c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_0041: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0046: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0052: stloc.3 - IL_0053: leave.s IL_0060 + IL_004b: stloc.2 + IL_004c: leave.s IL_0059 .line 100001,100001 : 0,0 '' - IL_0055: rethrow - IL_0057: ldnull - IL_0058: unbox.any class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 - IL_005d: stloc.3 - IL_005e: leave.s IL_0060 + IL_004e: rethrow + IL_0050: ldnull + IL_0051: unbox.any class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 + IL_0056: stloc.2 + IL_0057: leave.s IL_0059 .line 100001,100001 : 0,0 '' } // end handler - IL_0060: ldloc.3 - IL_0061: stloc.2 - IL_0062: ldloc.1 - IL_0063: ldloc.2 - IL_0064: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0) - IL_0069: pop - IL_006a: ret + IL_0059: ldloc.1 + IL_005a: ldloc.2 + IL_005b: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0) + IL_0060: pop + IL_0061: ret } // end of method $SeqExpressionSteppingTest7::main@ } // end of class ''.$SeqExpressionSteppingTest7 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls01.il.bsl index d03a45be913..94df7654a1d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SeqExpressionTailCalls01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionTailCalls01 { - // Offset: 0x00000000 Length: 0x0000021D + // Offset: 0x00000000 Length: 0x00000219 } .mresource public FSharpOptimizationData.SeqExpressionTailCalls01 { - // Offset: 0x00000228 Length: 0x0000008C + // Offset: 0x00000220 Length: 0x0000008C } .module SeqExpressionTailCalls01.exe -// MVID: {59B19240-093A-A6BE-A745-03834092B159} +// MVID: {60BD414B-093A-A6BE-A745-03834B41BD60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x027D0000 +// Image base: 0x06CE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -88,73 +88,66 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 108 (0x6c) + // Code size 102 (0x66) .maxstack 7 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionTailCalls\\SeqExpressionTailCalls01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionTailCalls\\SeqExpressionTailCalls01.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionTailCalls01/rwalk@3::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0040 + IL_001b: nop + IL_001c: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_005c + IL_001e: nop + IL_001f: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0063 + IL_0021: nop + IL_0022: br.s IL_005d .line 100001,100001 : 0,0 '' - IL_002a: nop - IL_002b: ldarg.0 - IL_002c: ldc.i4.1 - IL_002d: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc + IL_0024: nop .line 3,3 : 25,32 '' - IL_0032: ldarg.0 - IL_0033: ldarg.0 - IL_0034: ldfld int32 SeqExpressionTailCalls01/rwalk@3::x - IL_0039: stfld int32 SeqExpressionTailCalls01/rwalk@3::current - IL_003e: ldc.i4.1 - IL_003f: ret - - IL_0040: ldarg.0 - IL_0041: ldc.i4.2 - IL_0042: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc - .line 3,3 : 41,52 '' - IL_0047: ldarg.1 - IL_0048: ldarg.0 - IL_0049: ldfld int32 SeqExpressionTailCalls01/rwalk@3::x - IL_004e: ldc.i4.1 - IL_004f: add - IL_0050: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls01::rwalk(int32) - IL_0055: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_005a: ldc.i4.2 - IL_005b: ret - - IL_005c: ldarg.0 - IL_005d: ldc.i4.3 - IL_005e: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc - IL_0063: ldarg.0 + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc + IL_002c: ldarg.0 + IL_002d: ldarg.0 + IL_002e: ldfld int32 SeqExpressionTailCalls01/rwalk@3::x + IL_0033: stfld int32 SeqExpressionTailCalls01/rwalk@3::current + IL_0038: ldc.i4.1 + IL_0039: ret + + IL_003a: ldarg.0 + IL_003b: ldc.i4.2 + IL_003c: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc + IL_0041: ldarg.1 + IL_0042: ldarg.0 + IL_0043: ldfld int32 SeqExpressionTailCalls01/rwalk@3::x + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls01::rwalk(int32) + IL_004f: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0054: ldc.i4.2 + IL_0055: ret + + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 SeqExpressionTailCalls01/rwalk@3::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 SeqExpressionTailCalls01/rwalk@3::current IL_0064: ldc.i4.0 - IL_0065: stfld int32 SeqExpressionTailCalls01/rwalk@3::current - IL_006a: ldc.i4.0 - IL_006b: ret + IL_0065: ret } // end of method rwalk@3::GenerateNext .method public strict virtual instance void @@ -171,52 +164,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionTailCalls01/rwalk@3::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method rwalk@3::get_CheckClose .method public strict virtual instance int32 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls02.il.bsl index 4cca2bf3f7c..bd032aa6f46 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SeqExpressionTailCalls/SeqExpressionTailCalls02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SeqExpressionTailCalls02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SeqExpressionTailCalls02 { - // Offset: 0x00000000 Length: 0x00000256 + // Offset: 0x00000000 Length: 0x00000252 } .mresource public FSharpOptimizationData.SeqExpressionTailCalls02 { - // Offset: 0x00000260 Length: 0x0000009E + // Offset: 0x00000258 Length: 0x0000009E } .module SeqExpressionTailCalls02.exe -// MVID: {59B19240-093A-EC43-A745-03834092B159} +// MVID: {60BD414B-093A-EC43-A745-03834B41BD60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x017C0000 +// Image base: 0x06760000 // =============== CLASS MEMBERS DECLARATION =================== @@ -88,73 +88,66 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 108 (0x6c) + // Code size 102 (0x66) .maxstack 7 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SeqExpressionTailCalls\\SeqExpressionTailCalls02.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SeqExpressionTailCalls\\SeqExpressionTailCalls02.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::pc IL_0006: ldc.i4.1 IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0040 + IL_001b: nop + IL_001c: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_005c + IL_001e: nop + IL_001f: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0063 + IL_0021: nop + IL_0022: br.s IL_005d .line 100001,100001 : 0,0 '' - IL_002a: nop - IL_002b: ldarg.0 - IL_002c: ldc.i4.1 - IL_002d: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc + IL_0024: nop .line 5,5 : 26,33 '' - IL_0032: ldarg.0 - IL_0033: ldarg.0 - IL_0034: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::x - IL_0039: stfld int32 SeqExpressionTailCalls02/rwalk1@5::current - IL_003e: ldc.i4.1 - IL_003f: ret - - IL_0040: ldarg.0 - IL_0041: ldc.i4.2 - IL_0042: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc - .line 5,5 : 42,54 '' - IL_0047: ldarg.1 - IL_0048: ldarg.0 - IL_0049: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::x - IL_004e: ldc.i4.1 - IL_004f: add - IL_0050: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls02::rwalk2(int32) - IL_0055: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_005a: ldc.i4.2 - IL_005b: ret - - IL_005c: ldarg.0 - IL_005d: ldc.i4.3 - IL_005e: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc - IL_0063: ldarg.0 + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc + IL_002c: ldarg.0 + IL_002d: ldarg.0 + IL_002e: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::x + IL_0033: stfld int32 SeqExpressionTailCalls02/rwalk1@5::current + IL_0038: ldc.i4.1 + IL_0039: ret + + IL_003a: ldarg.0 + IL_003b: ldc.i4.2 + IL_003c: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc + IL_0041: ldarg.1 + IL_0042: ldarg.0 + IL_0043: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::x + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls02::rwalk2(int32) + IL_004f: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0054: ldc.i4.2 + IL_0055: ret + + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 SeqExpressionTailCalls02/rwalk1@5::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 SeqExpressionTailCalls02/rwalk1@5::current IL_0064: ldc.i4.0 - IL_0065: stfld int32 SeqExpressionTailCalls02/rwalk1@5::current - IL_006a: ldc.i4.0 - IL_006b: ret + IL_0065: ret } // end of method rwalk1@5::GenerateNext .method public strict virtual instance void @@ -171,52 +164,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionTailCalls02/rwalk1@5::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method rwalk1@5::get_CheckClose .method public strict virtual instance int32 @@ -287,7 +272,7 @@ .method public strict virtual instance int32 GenerateNext(class [mscorlib]System.Collections.Generic.IEnumerable`1& next) cil managed { - // Code size 108 (0x6c) + // Code size 102 (0x66) .maxstack 7 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 @@ -296,63 +281,56 @@ IL_0007: sub IL_0008: switch ( IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_002a - - IL_001b: br.s IL_0021 - - IL_001d: br.s IL_0024 - - IL_001f: br.s IL_0027 + IL_001e, + IL_0021) + IL_0019: br.s IL_0024 .line 100001,100001 : 0,0 '' - IL_0021: nop - IL_0022: br.s IL_0040 + IL_001b: nop + IL_001c: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_005c + IL_001e: nop + IL_001f: br.s IL_0056 .line 100001,100001 : 0,0 '' - IL_0027: nop - IL_0028: br.s IL_0063 + IL_0021: nop + IL_0022: br.s IL_005d .line 100001,100001 : 0,0 '' - IL_002a: nop - IL_002b: ldarg.0 - IL_002c: ldc.i4.1 - IL_002d: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc + IL_0024: nop .line 6,6 : 26,33 '' - IL_0032: ldarg.0 - IL_0033: ldarg.0 - IL_0034: ldfld int32 SeqExpressionTailCalls02/rwalk2@6::x - IL_0039: stfld int32 SeqExpressionTailCalls02/rwalk2@6::current - IL_003e: ldc.i4.1 - IL_003f: ret - - IL_0040: ldarg.0 - IL_0041: ldc.i4.2 - IL_0042: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc - .line 6,6 : 42,54 '' - IL_0047: ldarg.1 - IL_0048: ldarg.0 - IL_0049: ldfld int32 SeqExpressionTailCalls02/rwalk2@6::x - IL_004e: ldc.i4.1 - IL_004f: add - IL_0050: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls02::rwalk1(int32) - IL_0055: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_005a: ldc.i4.2 - IL_005b: ret - - IL_005c: ldarg.0 - IL_005d: ldc.i4.3 - IL_005e: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc - IL_0063: ldarg.0 + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc + IL_002c: ldarg.0 + IL_002d: ldarg.0 + IL_002e: ldfld int32 SeqExpressionTailCalls02/rwalk2@6::x + IL_0033: stfld int32 SeqExpressionTailCalls02/rwalk2@6::current + IL_0038: ldc.i4.1 + IL_0039: ret + + IL_003a: ldarg.0 + IL_003b: ldc.i4.2 + IL_003c: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc + IL_0041: ldarg.1 + IL_0042: ldarg.0 + IL_0043: ldfld int32 SeqExpressionTailCalls02/rwalk2@6::x + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: call class [mscorlib]System.Collections.Generic.IEnumerable`1 SeqExpressionTailCalls02::rwalk1(int32) + IL_004f: stobj class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0054: ldc.i4.2 + IL_0055: ret + + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: stfld int32 SeqExpressionTailCalls02/rwalk2@6::pc + IL_005d: ldarg.0 + IL_005e: ldc.i4.0 + IL_005f: stfld int32 SeqExpressionTailCalls02/rwalk2@6::current IL_0064: ldc.i4.0 - IL_0065: stfld int32 SeqExpressionTailCalls02/rwalk2@6::current - IL_006a: ldc.i4.0 - IL_006b: ret + IL_0065: ret } // end of method rwalk2@6::GenerateNext .method public strict virtual instance void @@ -369,52 +347,44 @@ .method public strict virtual instance bool get_CheckClose() cil managed { - // Code size 56 (0x38) + // Code size 48 (0x30) .maxstack 8 .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 IL_0001: ldfld int32 SeqExpressionTailCalls02/rwalk2@6::pc IL_0006: switch ( IL_001d, - IL_001f, - IL_0021, - IL_0023) - IL_001b: br.s IL_0031 - - IL_001d: br.s IL_0025 - - IL_001f: br.s IL_0028 - - IL_0021: br.s IL_002b - - IL_0023: br.s IL_002e + IL_0020, + IL_0023, + IL_0026) + IL_001b: br.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_0036 + IL_001d: nop + IL_001e: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0028: nop - IL_0029: br.s IL_0034 + IL_0020: nop + IL_0021: br.s IL_002c .line 100001,100001 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0032 + IL_0023: nop + IL_0024: br.s IL_002a .line 100001,100001 : 0,0 '' - IL_002e: nop - IL_002f: br.s IL_0036 + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_0031: nop - IL_0032: ldc.i4.0 - IL_0033: ret + IL_0029: nop + IL_002a: ldc.i4.0 + IL_002b: ret - IL_0034: ldc.i4.0 - IL_0035: ret + IL_002c: ldc.i4.0 + IL_002d: ret - IL_0036: ldc.i4.0 - IL_0037: ret + IL_002e: ldc.i4.0 + IL_002f: ret } // end of method rwalk2@6::get_CheckClose .method public strict virtual instance int32 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl index bf83c61d107..27497d9c2c1 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl @@ -1,4 +1,1721 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly extern FSharp.Core +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 5:0:0:0 +} +.assembly TopLevelModule +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 01 01 00 00 00 00 ) + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.TopLevelModule +{ + // Offset: 0x00000000 Length: 0x0000113D +} +.mresource public FSharpOptimizationData.TopLevelModule +{ + // Offset: 0x00001148 Length: 0x000003FD +} +.module TopLevelModule.dll +// MVID: {6125903C-37F5-C118-A745-03833C902561} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x009E0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi sealed ABC + extends [mscorlib]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit Expr + extends [mscorlib]System.Object + implements class [mscorlib]System.IEquatable`1, + [mscorlib]System.Collections.IStructuralEquatable, + class [mscorlib]System.IComparable`1, + [mscorlib]System.IComparable, + [mscorlib]System.Collections.IStructuralComparable + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl + 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .field assembly initonly int32 item + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static class ABC/Expr + NewNum(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void ABC/Expr::.ctor(int32) + IL_0006: ret + } // end of method Expr::NewNum + + .method assembly specialname rtspecialname + instance void .ctor(int32 item) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 ABC/Expr::item + IL_000d: ret + } // end of method Expr::.ctor + + .method public hidebysig instance int32 + get_Item() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ABC/Expr::item + IL_0006: ret + } // end of method Expr::get_Item + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: pop + IL_0002: ldc.i4.0 + IL_0003: ret + } // end of method Expr::get_Tag + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::__DebugDisplay + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class ABC/Expr>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::ToString + + .method public hidebysig virtual final + instance int32 CompareTo(class ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 65 (0x41) + .maxstack 4 + .locals init ([0] class ABC/Expr V_0, + [1] class ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IComparer V_2, + [3] int32 V_3, + [4] int32 V_4) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 6,6 : 14,18 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SerializableAttribute\\ToplevelModule.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0037 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0035 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.2 + IL_0019: ldloc.0 + IL_001a: ldfld int32 ABC/Expr::item + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 ABC/Expr::item + IL_0026: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0028: ldloc.3 + IL_0029: ldloc.s V_4 + IL_002b: bge.s IL_002f + + .line 100001,100001 : 0,0 '' + IL_002d: ldc.i4.m1 + IL_002e: ret + + .line 100001,100001 : 0,0 '' + IL_002f: ldloc.3 + IL_0030: ldloc.s V_4 + IL_0032: cgt + IL_0034: ret + + .line 100001,100001 : 0,0 '' + IL_0035: ldc.i4.1 + IL_0036: ret + + .line 100001,100001 : 0,0 '' + IL_0037: ldarg.1 + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_003d: ldc.i4.m1 + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.0 + IL_0040: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 13 (0xd) + .maxstack 8 + .line 6,6 : 14,18 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any ABC/Expr + IL_0007: callvirt instance int32 ABC/Expr::CompareTo(class ABC/Expr) + IL_000c: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [mscorlib]System.Collections.IComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 80 (0x50) + .maxstack 4 + .locals init ([0] class ABC/Expr V_0, + [1] class ABC/Expr V_1, + [2] class ABC/Expr V_2, + [3] class [mscorlib]System.Collections.IComparer V_3, + [4] int32 V_4, + [5] int32 V_5) + .line 6,6 : 14,18 '' + IL_0000: ldarg.1 + IL_0001: unbox.any ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0041 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: unbox.any ABC/Expr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_0018: ldarg.0 + IL_0019: pop + .line 100001,100001 : 0,0 '' + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 ABC/Expr::item + IL_0026: stloc.s V_4 + IL_0028: ldloc.2 + IL_0029: ldfld int32 ABC/Expr::item + IL_002e: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0030: ldloc.s V_4 + IL_0032: ldloc.s V_5 + IL_0034: bge.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_0036: ldc.i4.m1 + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.s V_4 + IL_003a: ldloc.s V_5 + IL_003c: cgt + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.1 + IL_0040: ret + + .line 100001,100001 : 0,0 '' + IL_0041: ldarg.1 + IL_0042: unbox.any ABC/Expr + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: brfalse.s IL_004e + + .line 100001,100001 : 0,0 '' + IL_004c: ldc.i4.m1 + IL_004d: ret + + .line 100001,100001 : 0,0 '' + IL_004e: ldc.i4.0 + IL_004f: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 42 (0x2a) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 6,6 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 ABC/Expr::item + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: ret + + .line 100001,100001 : 0,0 '' + IL_0028: ldc.i4.0 + IL_0029: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance int32 GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 6,6 : 14,18 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 53 (0x35) + .maxstack 4 + .locals init ([0] class ABC/Expr V_0, + [1] class ABC/Expr V_1, + [2] class ABC/Expr V_2, + [3] class ABC/Expr V_3, + [4] class [mscorlib]System.Collections.IEqualityComparer V_4) + .line 6,6 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002d + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst ABC/Expr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_002b + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: pop + .line 100001,100001 : 0,0 '' + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 ABC/Expr::item + IL_0022: ldloc.3 + IL_0023: ldfld int32 ABC/Expr::item + IL_0028: ceq + IL_002a: ret + + .line 100001,100001 : 0,0 '' + IL_002b: ldc.i4.0 + IL_002c: ret + + .line 100001,100001 : 0,0 '' + IL_002d: ldarg.1 + IL_002e: ldnull + IL_002f: cgt.un + IL_0031: ldc.i4.0 + IL_0032: ceq + IL_0034: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(class ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 44 (0x2c) + .maxstack 4 + .locals init ([0] class ABC/Expr V_0, + [1] class ABC/Expr V_1) + .line 6,6 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0024 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0022 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: ldloc.0 + IL_0014: ldfld int32 ABC/Expr::item + IL_0019: ldloc.1 + IL_001a: ldfld int32 ABC/Expr::item + IL_001f: ceq + IL_0021: ret + + .line 100001,100001 : 0,0 '' + IL_0022: ldc.i4.0 + IL_0023: ret + + .line 100001,100001 : 0,0 '' + IL_0024: ldarg.1 + IL_0025: ldnull + IL_0026: cgt.un + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class ABC/Expr V_0) + .line 6,6 : 14,18 '' + IL_0000: ldarg.1 + IL_0001: isinst ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool ABC/Expr::Equals(class ABC/Expr) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method Expr::Equals + + .property instance int32 Tag() + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 ABC/Expr::get_Tag() + } // end of property Expr::Tag + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 ABC/Expr::get_Item() + } // end of property Expr::Item + } // end of class Expr + + .class auto ansi serializable nested public beforefieldinit MyExn + extends [mscorlib]System.Exception + implements [mscorlib]System.Collections.IStructuralEquatable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) + .field assembly int32 Data0@ + .method public specialname rtspecialname + instance void .ctor(int32 data0) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 ABC/MyExn::Data0@ + IL_000d: ret + } // end of method MyExn::.ctor + + .method public specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ret + } // end of method MyExn::.ctor + + .method family specialname rtspecialname + instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext) + IL_0008: ret + } // end of method MyExn::.ctor + + .method public hidebysig specialname + instance int32 get_Data0() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ABC/MyExn::Data0@ + IL_0006: ret + } // end of method MyExn::get_Data0 + + .method public hidebysig virtual instance int32 + GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class [mscorlib]System.Collections.IEqualityComparer V_1) + .line 7,7 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: castclass ABC/MyExn + IL_0016: call instance int32 ABC/MyExn::get_Data0() + IL_001b: ldloc.0 + IL_001c: ldc.i4.6 + IL_001d: shl + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: shr + IL_0021: add + IL_0022: add + IL_0023: add + IL_0024: stloc.0 + IL_0025: ldloc.0 + IL_0026: ret + + .line 100001,100001 : 0,0 '' + IL_0027: ldc.i4.0 + IL_0028: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance int32 + GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 7,7 : 19,24 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance bool + Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 68 (0x44) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 7,7 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003c + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst [mscorlib]System.Exception + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003a + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0019: brtrue.s IL_001d + + IL_001b: br.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_001d: ldarg.2 + IL_001e: stloc.2 + IL_001f: ldarg.0 + IL_0020: castclass ABC/MyExn + IL_0025: call instance int32 ABC/MyExn::get_Data0() + IL_002a: ldloc.1 + IL_002b: castclass ABC/MyExn + IL_0030: call instance int32 ABC/MyExn::get_Data0() + IL_0035: ceq + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldc.i4.0 + IL_0039: ret + + .line 100001,100001 : 0,0 '' + IL_003a: ldc.i4.0 + IL_003b: ret + + .line 100001,100001 : 0,0 '' + IL_003c: ldarg.1 + IL_003d: ldnull + IL_003e: cgt.un + IL_0040: ldc.i4.0 + IL_0041: ceq + IL_0043: ret + } // end of method MyExn::Equals + + .method public hidebysig instance bool + Equals(class [mscorlib]System.Exception obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 60 (0x3c) + .maxstack 8 + .line 7,7 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0013: brtrue.s IL_0017 + + IL_0015: br.s IL_0030 + + .line 100001,100001 : 0,0 '' + IL_0017: ldarg.0 + IL_0018: castclass ABC/MyExn + IL_001d: call instance int32 ABC/MyExn::get_Data0() + IL_0022: ldarg.1 + IL_0023: castclass ABC/MyExn + IL_0028: call instance int32 ABC/MyExn::get_Data0() + IL_002d: ceq + IL_002f: ret + + .line 100001,100001 : 0,0 '' + IL_0030: ldc.i4.0 + IL_0031: ret + + .line 100001,100001 : 0,0 '' + IL_0032: ldc.i4.0 + IL_0033: ret + + .line 100001,100001 : 0,0 '' + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret + } // end of method MyExn::Equals + + .method public hidebysig virtual instance bool + Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0) + .line 7,7 : 19,24 '' + IL_0000: ldarg.1 + IL_0001: isinst [mscorlib]System.Exception + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool ABC/MyExn::Equals(class [mscorlib]System.Exception) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method MyExn::Equals + + .property instance int32 Data0() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 ABC/MyExn::get_Data0() + } // end of property MyExn::Data0 + } // end of class MyExn + + .class auto ansi serializable nested public A + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly string x + .method public specialname rtspecialname + instance void .ctor(string x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + .line 8,8 : 16,17 '' + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string ABC/A::x + .line 8,8 : 14,15 '' + IL_000f: ret + } // end of method A::.ctor + + .method public hidebysig specialname + instance string get_X() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 8,8 : 42,43 '' + IL_0000: ldarg.0 + IL_0001: ldfld string ABC/A::x + IL_0006: ret + } // end of method A::get_X + + .property instance string X() + { + .get instance string ABC/A::get_X() + } // end of property A::X + } // end of class A + + .class abstract auto ansi sealed nested public ABC + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit Expr + extends [mscorlib]System.Object + implements class [mscorlib]System.IEquatable`1, + [mscorlib]System.Collections.IStructuralEquatable, + class [mscorlib]System.IComparable`1, + [mscorlib]System.IComparable, + [mscorlib]System.Collections.IStructuralComparable + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl + 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .field assembly initonly int32 item + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static class ABC/ABC/Expr + NewNum(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void ABC/ABC/Expr::.ctor(int32) + IL_0006: ret + } // end of method Expr::NewNum + + .method assembly specialname rtspecialname + instance void .ctor(int32 item) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 ABC/ABC/Expr::item + IL_000d: ret + } // end of method Expr::.ctor + + .method public hidebysig instance int32 + get_Item() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ABC/ABC/Expr::item + IL_0006: ret + } // end of method Expr::get_Item + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: pop + IL_0002: ldc.i4.0 + IL_0003: ret + } // end of method Expr::get_Tag + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::__DebugDisplay + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class ABC/ABC/Expr>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::ToString + + .method public hidebysig virtual final + instance int32 CompareTo(class ABC/ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 65 (0x41) + .maxstack 4 + .locals init ([0] class ABC/ABC/Expr V_0, + [1] class ABC/ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IComparer V_2, + [3] int32 V_3, + [4] int32 V_4) + .line 16,16 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0037 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0035 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.2 + IL_0019: ldloc.0 + IL_001a: ldfld int32 ABC/ABC/Expr::item + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 ABC/ABC/Expr::item + IL_0026: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0028: ldloc.3 + IL_0029: ldloc.s V_4 + IL_002b: bge.s IL_002f + + .line 100001,100001 : 0,0 '' + IL_002d: ldc.i4.m1 + IL_002e: ret + + .line 100001,100001 : 0,0 '' + IL_002f: ldloc.3 + IL_0030: ldloc.s V_4 + IL_0032: cgt + IL_0034: ret + + .line 100001,100001 : 0,0 '' + IL_0035: ldc.i4.1 + IL_0036: ret + + .line 100001,100001 : 0,0 '' + IL_0037: ldarg.1 + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_003d: ldc.i4.m1 + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.0 + IL_0040: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 13 (0xd) + .maxstack 8 + .line 16,16 : 18,22 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any ABC/ABC/Expr + IL_0007: callvirt instance int32 ABC/ABC/Expr::CompareTo(class ABC/ABC/Expr) + IL_000c: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [mscorlib]System.Collections.IComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 80 (0x50) + .maxstack 4 + .locals init ([0] class ABC/ABC/Expr V_0, + [1] class ABC/ABC/Expr V_1, + [2] class ABC/ABC/Expr V_2, + [3] class [mscorlib]System.Collections.IComparer V_3, + [4] int32 V_4, + [5] int32 V_5) + .line 16,16 : 18,22 '' + IL_0000: ldarg.1 + IL_0001: unbox.any ABC/ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0041 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: unbox.any ABC/ABC/Expr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_0018: ldarg.0 + IL_0019: pop + .line 100001,100001 : 0,0 '' + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 ABC/ABC/Expr::item + IL_0026: stloc.s V_4 + IL_0028: ldloc.2 + IL_0029: ldfld int32 ABC/ABC/Expr::item + IL_002e: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0030: ldloc.s V_4 + IL_0032: ldloc.s V_5 + IL_0034: bge.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_0036: ldc.i4.m1 + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.s V_4 + IL_003a: ldloc.s V_5 + IL_003c: cgt + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.1 + IL_0040: ret + + .line 100001,100001 : 0,0 '' + IL_0041: ldarg.1 + IL_0042: unbox.any ABC/ABC/Expr + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: brfalse.s IL_004e + + .line 100001,100001 : 0,0 '' + IL_004c: ldc.i4.m1 + IL_004d: ret + + .line 100001,100001 : 0,0 '' + IL_004e: ldc.i4.0 + IL_004f: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 42 (0x2a) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class ABC/ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 16,16 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 ABC/ABC/Expr::item + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: ret + + .line 100001,100001 : 0,0 '' + IL_0028: ldc.i4.0 + IL_0029: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance int32 GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 16,16 : 18,22 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 ABC/ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 53 (0x35) + .maxstack 4 + .locals init ([0] class ABC/ABC/Expr V_0, + [1] class ABC/ABC/Expr V_1, + [2] class ABC/ABC/Expr V_2, + [3] class ABC/ABC/Expr V_3, + [4] class [mscorlib]System.Collections.IEqualityComparer V_4) + .line 16,16 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002d + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst ABC/ABC/Expr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_002b + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: pop + .line 100001,100001 : 0,0 '' + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 ABC/ABC/Expr::item + IL_0022: ldloc.3 + IL_0023: ldfld int32 ABC/ABC/Expr::item + IL_0028: ceq + IL_002a: ret + + .line 100001,100001 : 0,0 '' + IL_002b: ldc.i4.0 + IL_002c: ret + + .line 100001,100001 : 0,0 '' + IL_002d: ldarg.1 + IL_002e: ldnull + IL_002f: cgt.un + IL_0031: ldc.i4.0 + IL_0032: ceq + IL_0034: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(class ABC/ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 44 (0x2c) + .maxstack 4 + .locals init ([0] class ABC/ABC/Expr V_0, + [1] class ABC/ABC/Expr V_1) + .line 16,16 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0024 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0022 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: ldloc.0 + IL_0014: ldfld int32 ABC/ABC/Expr::item + IL_0019: ldloc.1 + IL_001a: ldfld int32 ABC/ABC/Expr::item + IL_001f: ceq + IL_0021: ret + + .line 100001,100001 : 0,0 '' + IL_0022: ldc.i4.0 + IL_0023: ret + + .line 100001,100001 : 0,0 '' + IL_0024: ldarg.1 + IL_0025: ldnull + IL_0026: cgt.un + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class ABC/ABC/Expr V_0) + .line 16,16 : 18,22 '' + IL_0000: ldarg.1 + IL_0001: isinst ABC/ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool ABC/ABC/Expr::Equals(class ABC/ABC/Expr) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method Expr::Equals + + .property instance int32 Tag() + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 ABC/ABC/Expr::get_Tag() + } // end of property Expr::Tag + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 ABC/ABC/Expr::get_Item() + } // end of property Expr::Item + } // end of class Expr + + .class auto ansi serializable nested public beforefieldinit MyExn + extends [mscorlib]System.Exception + implements [mscorlib]System.Collections.IStructuralEquatable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) + .field assembly int32 Data0@ + .method public specialname rtspecialname + instance void .ctor(int32 data0) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 ABC/ABC/MyExn::Data0@ + IL_000d: ret + } // end of method MyExn::.ctor + + .method public specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ret + } // end of method MyExn::.ctor + + .method family specialname rtspecialname + instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext) + IL_0008: ret + } // end of method MyExn::.ctor + + .method public hidebysig specialname + instance int32 get_Data0() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 ABC/ABC/MyExn::Data0@ + IL_0006: ret + } // end of method MyExn::get_Data0 + + .method public hidebysig virtual instance int32 + GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class [mscorlib]System.Collections.IEqualityComparer V_1) + .line 17,17 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: castclass ABC/ABC/MyExn + IL_0016: call instance int32 ABC/ABC/MyExn::get_Data0() + IL_001b: ldloc.0 + IL_001c: ldc.i4.6 + IL_001d: shl + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: shr + IL_0021: add + IL_0022: add + IL_0023: add + IL_0024: stloc.0 + IL_0025: ldloc.0 + IL_0026: ret + + .line 100001,100001 : 0,0 '' + IL_0027: ldc.i4.0 + IL_0028: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance int32 + GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 17,17 : 23,28 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 ABC/ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance bool + Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 68 (0x44) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 17,17 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003c + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst [mscorlib]System.Exception + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003a + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0019: brtrue.s IL_001d + + IL_001b: br.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_001d: ldarg.2 + IL_001e: stloc.2 + IL_001f: ldarg.0 + IL_0020: castclass ABC/ABC/MyExn + IL_0025: call instance int32 ABC/ABC/MyExn::get_Data0() + IL_002a: ldloc.1 + IL_002b: castclass ABC/ABC/MyExn + IL_0030: call instance int32 ABC/ABC/MyExn::get_Data0() + IL_0035: ceq + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldc.i4.0 + IL_0039: ret + + .line 100001,100001 : 0,0 '' + IL_003a: ldc.i4.0 + IL_003b: ret + + .line 100001,100001 : 0,0 '' + IL_003c: ldarg.1 + IL_003d: ldnull + IL_003e: cgt.un + IL_0040: ldc.i4.0 + IL_0041: ceq + IL_0043: ret + } // end of method MyExn::Equals + + .method public hidebysig instance bool + Equals(class [mscorlib]System.Exception obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 60 (0x3c) + .maxstack 8 + .line 17,17 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0013: brtrue.s IL_0017 + + IL_0015: br.s IL_0030 + + .line 100001,100001 : 0,0 '' + IL_0017: ldarg.0 + IL_0018: castclass ABC/ABC/MyExn + IL_001d: call instance int32 ABC/ABC/MyExn::get_Data0() + IL_0022: ldarg.1 + IL_0023: castclass ABC/ABC/MyExn + IL_0028: call instance int32 ABC/ABC/MyExn::get_Data0() + IL_002d: ceq + IL_002f: ret + + .line 100001,100001 : 0,0 '' + IL_0030: ldc.i4.0 + IL_0031: ret + + .line 100001,100001 : 0,0 '' + IL_0032: ldc.i4.0 + IL_0033: ret + + .line 100001,100001 : 0,0 '' + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret + } // end of method MyExn::Equals + + .method public hidebysig virtual instance bool + Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0) + .line 17,17 : 23,28 '' + IL_0000: ldarg.1 + IL_0001: isinst [mscorlib]System.Exception + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool ABC/ABC/MyExn::Equals(class [mscorlib]System.Exception) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method MyExn::Equals + + .property instance int32 Data0() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 ABC/ABC/MyExn::get_Data0() + } // end of property MyExn::Data0 + } // end of class MyExn + + .class auto ansi serializable nested public A + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly string x + .method public specialname rtspecialname + instance void .ctor(string x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + .line 18,18 : 20,21 '' + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string ABC/ABC/A::x + .line 18,18 : 18,19 '' + IL_000f: ret + } // end of method A::.ctor + + .method public hidebysig specialname + instance string get_X() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 18,18 : 46,47 '' + IL_0000: ldarg.0 + IL_0001: ldfld string ABC/ABC/A::x + IL_0006: ret + } // end of method A::get_X + + .property instance string X() + { + .get instance string ABC/ABC/A::get_X() + } // end of property A::X + } // end of class A + + .method public static int32 'add'(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + .line 21,21 : 27,32 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } // end of method ABC::'add' + + .method public specialname static string + get_greeting() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "hello" + IL_0005: ret + } // end of method ABC::get_greeting + + .property string greeting() + { + .get string ABC/ABC::get_greeting() + } // end of property ABC::greeting + } // end of class ABC + + .method public static int32 'add'(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + .line 11,11 : 23,28 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } // end of method ABC::'add' + + .method public specialname static string + get_greeting() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "hello" + IL_0005: ret + } // end of method ABC::get_greeting + + .property string greeting() + { + .get string ABC::get_greeting() + } // end of property ABC::greeting +} // end of class ABC + +.class private abstract auto ansi sealed ''.$ABC + extends [mscorlib]System.Object +{ + .field static assembly int32 init@ + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init ([0] string greeting, + [1] string V_1) + .line 12,12 : 9,31 '' + IL_0000: call string ABC::get_greeting() + IL_0005: stloc.0 + .line 22,22 : 13,35 '' + IL_0006: call string ABC/ABC::get_greeting() + IL_000b: stloc.1 + IL_000c: ret + } // end of method $ABC::.cctor + +} // end of class ''.$ABC + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModuleP.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModuleP.il.bsl deleted file mode 100644 index 771eaa3d503..00000000000 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModuleP.il.bsl +++ /dev/null @@ -1,1737 +0,0 @@ - -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.81.0 -// Copyright (c) Microsoft Corporation. All rights reserved. - - - -// Metadata version: v4.0.30319 -.assembly extern retargetable mscorlib -{ - .publickeytoken = (7C EC 85 D7 BE A7 79 8E ) // |.....y. - .ver 2:0:5:0 -} -.assembly extern FSharp.Core -{ - .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 3:47:41:0 -} -.assembly ToplevelModuleP -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, - int32, - int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - - // --- The following custom attribute is added automatically, do not uncomment ------- - // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 00 01 00 00 00 00 ) - - .hash algorithm 0x00008004 - .ver 0:0:0:0 -} -.mresource public FSharpSignatureData.ToplevelModuleP -{ - // Offset: 0x00000000 Length: 0x0000114F -} -.mresource public FSharpOptimizationData.ToplevelModuleP -{ - // Offset: 0x00001158 Length: 0x000003FE -} -.module ToplevelModuleP.dll -// MVID: {576266E1-5A3A-8E4D-A745-0383E1666257} -.imagebase 0x00400000 -.file alignment 0x00000200 -.stackreserve 0x00100000 -.subsystem 0x0003 // WINDOWS_CUI -.corflags 0x00000001 // ILONLY -// Image base: 0x00A70000 - - -// =============== CLASS MEMBERS DECLARATION =================== - -.class public abstract auto ansi sealed ABC - extends [mscorlib]System.Object -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar sealed nested public beforefieldinit Expr - extends [mscorlib]System.Object - implements class [mscorlib]System.IEquatable`1, - [mscorlib]System.Collections.IStructuralEquatable, - class [mscorlib]System.IComparable`1, - [mscorlib]System.IComparable, - [mscorlib]System.Collections.IStructuralComparable - { - .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl - 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) - .field assembly initonly int32 item - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static class ABC/Expr - NewNum(int32 item) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void ABC/Expr::.ctor(int32) - IL_0006: ret - } // end of method Expr::NewNum - - .method assembly specialname rtspecialname - instance void .ctor(int32 item) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 ABC/Expr::item - IL_000d: ret - } // end of method Expr::.ctor - - .method public hidebysig instance int32 - get_Item() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ABC/Expr::item - IL_0006: ret - } // end of method Expr::get_Item - - .method public hidebysig instance int32 - get_Tag() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 4 (0x4) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: pop - IL_0002: ldc.i4.0 - IL_0003: ret - } // end of method Expr::get_Tag - - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%+0.8A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::__DebugDisplay - - .method public strict virtual instance string - ToString() cil managed - { - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::ToString - - .method public hidebysig virtual final - instance int32 CompareTo(class ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) - .maxstack 4 - .locals init (class ABC/Expr V_0, - class ABC/Expr V_1, - class [mscorlib]System.Collections.IComparer V_2, - int32 V_3, - int32 V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0043 - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_0041 - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0020: stloc.2 - IL_0021: ldloc.0 - IL_0022: ldfld int32 ABC/Expr::item - IL_0027: stloc.3 - IL_0028: ldloc.1 - IL_0029: ldfld int32 ABC/Expr::item - IL_002e: stloc.s V_4 - IL_0030: ldloc.3 - IL_0031: ldloc.s V_4 - IL_0033: bge.s IL_0037 - - IL_0035: br.s IL_0039 - - IL_0037: br.s IL_003b - - IL_0039: ldc.i4.m1 - IL_003a: ret - - IL_003b: ldloc.3 - IL_003c: ldloc.s V_4 - IL_003e: cgt - IL_0040: ret - - IL_0041: ldc.i4.1 - IL_0042: ret - - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d - - IL_004b: br.s IL_004f - - IL_004d: ldc.i4.m1 - IL_004e: ret - - IL_004f: ldc.i4.0 - IL_0050: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 14,18 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SerializableAttribute\\ToplevelModule.fs' - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: unbox.any ABC/Expr - IL_0008: callvirt instance int32 ABC/Expr::CompareTo(class ABC/Expr) - IL_000d: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [mscorlib]System.Collections.IComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 97 (0x61) - .maxstack 4 - .locals init ([0] class ABC/Expr V_0, - [1] class ABC/Expr V_1, - [2] class ABC/Expr V_2, - [3] class [mscorlib]System.Collections.IComparer V_3, - [4] int32 V_4, - [5] int32 V_5) - .line 6,6 : 14,18 - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: unbox.any ABC/Expr - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: ldnull - IL_000a: cgt.un - IL_000c: brfalse.s IL_0010 - - IL_000e: br.s IL_0012 - - IL_0010: br.s IL_004e - - .line 100001,100001 : 0,0 - IL_0012: ldarg.1 - IL_0013: unbox.any ABC/Expr - IL_0018: ldnull - IL_0019: cgt.un - IL_001b: brfalse.s IL_001f - - IL_001d: br.s IL_0021 - - IL_001f: br.s IL_004c - - .line 100001,100001 : 0,0 - IL_0021: ldarg.0 - IL_0022: pop - .line 100001,100001 : 0,0 - IL_0023: ldarg.0 - IL_0024: stloc.1 - IL_0025: ldloc.0 - IL_0026: stloc.2 - IL_0027: ldarg.2 - IL_0028: stloc.3 - IL_0029: ldloc.1 - IL_002a: ldfld int32 ABC/Expr::item - IL_002f: stloc.s V_4 - IL_0031: ldloc.2 - IL_0032: ldfld int32 ABC/Expr::item - IL_0037: stloc.s V_5 - IL_0039: ldloc.s V_4 - IL_003b: ldloc.s V_5 - IL_003d: bge.s IL_0041 - - IL_003f: br.s IL_0043 - - IL_0041: br.s IL_0045 - - .line 100001,100001 : 0,0 - IL_0043: ldc.i4.m1 - IL_0044: ret - - .line 100001,100001 : 0,0 - IL_0045: ldloc.s V_4 - IL_0047: ldloc.s V_5 - IL_0049: cgt - IL_004b: ret - - .line 100001,100001 : 0,0 - IL_004c: ldc.i4.1 - IL_004d: ret - - .line 100001,100001 : 0,0 - IL_004e: ldarg.1 - IL_004f: unbox.any ABC/Expr - IL_0054: ldnull - IL_0055: cgt.un - IL_0057: brfalse.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - - .line 100001,100001 : 0,0 - IL_005d: ldc.i4.m1 - IL_005e: ret - - .line 100001,100001 : 0,0 - IL_005f: ldc.i4.0 - IL_0060: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 46 (0x2e) - .maxstack 7 - .locals init (int32 V_0, - class ABC/Expr V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldarg.0 - IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 - IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldc.i4 0x9e3779b9 - IL_0018: ldarg.1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld int32 ABC/Expr::item - IL_0020: ldloc.0 - IL_0021: ldc.i4.6 - IL_0022: shl - IL_0023: ldloc.0 - IL_0024: ldc.i4.2 - IL_0025: shr - IL_0026: add - IL_0027: add - IL_0028: add - IL_0029: stloc.0 - IL_002a: ldloc.0 - IL_002b: ret - - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance int32 GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 6,6 : 14,18 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance bool Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 61 (0x3d) - .maxstack 4 - .locals init (class ABC/Expr V_0, - class ABC/Expr V_1, - class ABC/Expr V_2, - class ABC/Expr V_3, - class [mscorlib]System.Collections.IEqualityComparer V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0035 - - IL_000b: ldarg.1 - IL_000c: isinst ABC/Expr - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0033 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldarg.0 - IL_001c: pop - IL_001d: ldarg.0 - IL_001e: stloc.2 - IL_001f: ldloc.1 - IL_0020: stloc.3 - IL_0021: ldarg.2 - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: ldfld int32 ABC/Expr::item - IL_002a: ldloc.3 - IL_002b: ldfld int32 ABC/Expr::item - IL_0030: ceq - IL_0032: ret - - IL_0033: ldc.i4.0 - IL_0034: ret - - IL_0035: ldarg.1 - IL_0036: ldnull - IL_0037: cgt.un - IL_0039: ldc.i4.0 - IL_003a: ceq - IL_003c: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(class ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) - .maxstack 4 - .locals init (class ABC/Expr V_0, - class ABC/Expr V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_002a - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: ldfld int32 ABC/Expr::item - IL_0021: ldloc.1 - IL_0022: ldfld int32 ABC/Expr::item - IL_0027: ceq - IL_0029: ret - - IL_002a: ldc.i4.0 - IL_002b: ret - - IL_002c: ldarg.1 - IL_002d: ldnull - IL_002e: cgt.un - IL_0030: ldc.i4.0 - IL_0031: ceq - IL_0033: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class ABC/Expr V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst ABC/Expr - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool ABC/Expr::Equals(class ABC/Expr) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method Expr::Equals - - .property instance int32 Tag() - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .get instance int32 ABC/Expr::get_Tag() - } // end of property Expr::Tag - .property instance int32 Item() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .get instance int32 ABC/Expr::get_Item() - } // end of property Expr::Item - } // end of class Expr - - .class auto ansi nested public beforefieldinit MyExn - extends [mscorlib]System.Exception - implements [mscorlib]System.Collections.IStructuralEquatable - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) - .field assembly int32 Data0@ - .method public specialname rtspecialname - instance void .ctor(int32 data0) cil managed - { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 ABC/MyExn::Data0@ - IL_000d: ret - } // end of method MyExn::.ctor - - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ret - } // end of method MyExn::.ctor - - .method public hidebysig specialname - instance int32 get_Data0() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ABC/MyExn::Data0@ - IL_0006: ret - } // end of method MyExn::get_Data0 - - .method public hidebysig virtual instance int32 - GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 45 (0x2d) - .maxstack 7 - .locals init (int32 V_0, - class [mscorlib]System.Collections.IEqualityComparer V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002b - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldc.i4 0x9e3779b9 - IL_0012: ldarg.1 - IL_0013: stloc.1 - IL_0014: ldarg.0 - IL_0015: castclass ABC/MyExn - IL_001a: call instance int32 ABC/MyExn::get_Data0() - IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldloc.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance int32 - GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 7,7 : 19,24 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance bool - Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0, - class [mscorlib]System.Exception V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0044 - - IL_000b: ldarg.1 - IL_000c: isinst [mscorlib]System.Exception - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0042 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_0021: brtrue.s IL_0025 - - IL_0023: br.s IL_0040 - - IL_0025: ldarg.2 - IL_0026: stloc.2 - IL_0027: ldarg.0 - IL_0028: castclass ABC/MyExn - IL_002d: call instance int32 ABC/MyExn::get_Data0() - IL_0032: ldloc.1 - IL_0033: castclass ABC/MyExn - IL_0038: call instance int32 ABC/MyExn::get_Data0() - IL_003d: ceq - IL_003f: ret - - IL_0040: ldc.i4.0 - IL_0041: ret - - IL_0042: ldc.i4.0 - IL_0043: ret - - IL_0044: ldarg.1 - IL_0045: ldnull - IL_0046: cgt.un - IL_0048: ldc.i4.0 - IL_0049: ceq - IL_004b: ret - } // end of method MyExn::Equals - - .method public hidebysig instance bool - Equals(class [mscorlib]System.Exception obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) - .maxstack 4 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_003c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_003a - - IL_0015: ldarg.1 - IL_0016: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_001b: brtrue.s IL_001f - - IL_001d: br.s IL_0038 - - IL_001f: ldarg.0 - IL_0020: castclass ABC/MyExn - IL_0025: call instance int32 ABC/MyExn::get_Data0() - IL_002a: ldarg.1 - IL_002b: castclass ABC/MyExn - IL_0030: call instance int32 ABC/MyExn::get_Data0() - IL_0035: ceq - IL_0037: ret - - IL_0038: ldc.i4.0 - IL_0039: ret - - IL_003a: ldc.i4.0 - IL_003b: ret - - IL_003c: ldarg.1 - IL_003d: ldnull - IL_003e: cgt.un - IL_0040: ldc.i4.0 - IL_0041: ceq - IL_0043: ret - } // end of method MyExn::Equals - - .method public hidebysig virtual instance bool - Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst [mscorlib]System.Exception - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool ABC/MyExn::Equals(class [mscorlib]System.Exception) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method MyExn::Equals - - .property instance int32 Data0() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) - .get instance int32 ABC/MyExn::get_Data0() - } // end of property MyExn::Data0 - } // end of class MyExn - - .class auto ansi nested public A - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .field assembly string x - .method public specialname rtspecialname - instance void .ctor(string x) cil managed - { - // Code size 17 (0x11) - .maxstack 8 - .line 8,8 : 16,17 - IL_0000: ldarg.0 - IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: pop - IL_0008: nop - IL_0009: ldarg.0 - IL_000a: ldarg.1 - IL_000b: stfld string ABC/A::x - .line 8,8 : 14,15 - IL_0010: ret - } // end of method A::.ctor - - .method public hidebysig specialname - instance string get_X() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - .line 8,8 : 42,43 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldfld string ABC/A::x - IL_0007: ret - } // end of method A::get_X - - .property instance string X() - { - .get instance string ABC/A::get_X() - } // end of property A::X - } // end of class A - - .class abstract auto ansi sealed nested public ABC - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar sealed nested public beforefieldinit Expr - extends [mscorlib]System.Object - implements class [mscorlib]System.IEquatable`1, - [mscorlib]System.Collections.IStructuralEquatable, - class [mscorlib]System.IComparable`1, - [mscorlib]System.IComparable, - [mscorlib]System.Collections.IStructuralComparable - { - .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl - 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) - .field assembly initonly int32 item - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static class ABC/ABC/Expr - NewNum(int32 item) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void ABC/ABC/Expr::.ctor(int32) - IL_0006: ret - } // end of method Expr::NewNum - - .method assembly specialname rtspecialname - instance void .ctor(int32 item) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 ABC/ABC/Expr::item - IL_000d: ret - } // end of method Expr::.ctor - - .method public hidebysig instance int32 - get_Item() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ABC/ABC/Expr::item - IL_0006: ret - } // end of method Expr::get_Item - - .method public hidebysig instance int32 - get_Tag() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 4 (0x4) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: pop - IL_0002: ldc.i4.0 - IL_0003: ret - } // end of method Expr::get_Tag - - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%+0.8A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::__DebugDisplay - - .method public strict virtual instance string - ToString() cil managed - { - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::ToString - - .method public hidebysig virtual final - instance int32 CompareTo(class ABC/ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) - .maxstack 4 - .locals init (class ABC/ABC/Expr V_0, - class ABC/ABC/Expr V_1, - class [mscorlib]System.Collections.IComparer V_2, - int32 V_3, - int32 V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0043 - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_0041 - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0020: stloc.2 - IL_0021: ldloc.0 - IL_0022: ldfld int32 ABC/ABC/Expr::item - IL_0027: stloc.3 - IL_0028: ldloc.1 - IL_0029: ldfld int32 ABC/ABC/Expr::item - IL_002e: stloc.s V_4 - IL_0030: ldloc.3 - IL_0031: ldloc.s V_4 - IL_0033: bge.s IL_0037 - - IL_0035: br.s IL_0039 - - IL_0037: br.s IL_003b - - IL_0039: ldc.i4.m1 - IL_003a: ret - - IL_003b: ldloc.3 - IL_003c: ldloc.s V_4 - IL_003e: cgt - IL_0040: ret - - IL_0041: ldc.i4.1 - IL_0042: ret - - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d - - IL_004b: br.s IL_004f - - IL_004d: ldc.i4.m1 - IL_004e: ret - - IL_004f: ldc.i4.0 - IL_0050: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - .line 16,16 : 18,22 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: unbox.any ABC/ABC/Expr - IL_0008: callvirt instance int32 ABC/ABC/Expr::CompareTo(class ABC/ABC/Expr) - IL_000d: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [mscorlib]System.Collections.IComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 97 (0x61) - .maxstack 4 - .locals init ([0] class ABC/ABC/Expr V_0, - [1] class ABC/ABC/Expr V_1, - [2] class ABC/ABC/Expr V_2, - [3] class [mscorlib]System.Collections.IComparer V_3, - [4] int32 V_4, - [5] int32 V_5) - .line 16,16 : 18,22 - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: unbox.any ABC/ABC/Expr - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: ldnull - IL_000a: cgt.un - IL_000c: brfalse.s IL_0010 - - IL_000e: br.s IL_0012 - - IL_0010: br.s IL_004e - - .line 100001,100001 : 0,0 - IL_0012: ldarg.1 - IL_0013: unbox.any ABC/ABC/Expr - IL_0018: ldnull - IL_0019: cgt.un - IL_001b: brfalse.s IL_001f - - IL_001d: br.s IL_0021 - - IL_001f: br.s IL_004c - - .line 100001,100001 : 0,0 - IL_0021: ldarg.0 - IL_0022: pop - .line 100001,100001 : 0,0 - IL_0023: ldarg.0 - IL_0024: stloc.1 - IL_0025: ldloc.0 - IL_0026: stloc.2 - IL_0027: ldarg.2 - IL_0028: stloc.3 - IL_0029: ldloc.1 - IL_002a: ldfld int32 ABC/ABC/Expr::item - IL_002f: stloc.s V_4 - IL_0031: ldloc.2 - IL_0032: ldfld int32 ABC/ABC/Expr::item - IL_0037: stloc.s V_5 - IL_0039: ldloc.s V_4 - IL_003b: ldloc.s V_5 - IL_003d: bge.s IL_0041 - - IL_003f: br.s IL_0043 - - IL_0041: br.s IL_0045 - - .line 100001,100001 : 0,0 - IL_0043: ldc.i4.m1 - IL_0044: ret - - .line 100001,100001 : 0,0 - IL_0045: ldloc.s V_4 - IL_0047: ldloc.s V_5 - IL_0049: cgt - IL_004b: ret - - .line 100001,100001 : 0,0 - IL_004c: ldc.i4.1 - IL_004d: ret - - .line 100001,100001 : 0,0 - IL_004e: ldarg.1 - IL_004f: unbox.any ABC/ABC/Expr - IL_0054: ldnull - IL_0055: cgt.un - IL_0057: brfalse.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - - .line 100001,100001 : 0,0 - IL_005d: ldc.i4.m1 - IL_005e: ret - - .line 100001,100001 : 0,0 - IL_005f: ldc.i4.0 - IL_0060: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 46 (0x2e) - .maxstack 7 - .locals init (int32 V_0, - class ABC/ABC/Expr V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldarg.0 - IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 - IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldc.i4 0x9e3779b9 - IL_0018: ldarg.1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld int32 ABC/ABC/Expr::item - IL_0020: ldloc.0 - IL_0021: ldc.i4.6 - IL_0022: shl - IL_0023: ldloc.0 - IL_0024: ldc.i4.2 - IL_0025: shr - IL_0026: add - IL_0027: add - IL_0028: add - IL_0029: stloc.0 - IL_002a: ldloc.0 - IL_002b: ret - - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance int32 GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 16,16 : 18,22 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 ABC/ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance bool Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 61 (0x3d) - .maxstack 4 - .locals init (class ABC/ABC/Expr V_0, - class ABC/ABC/Expr V_1, - class ABC/ABC/Expr V_2, - class ABC/ABC/Expr V_3, - class [mscorlib]System.Collections.IEqualityComparer V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0035 - - IL_000b: ldarg.1 - IL_000c: isinst ABC/ABC/Expr - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0033 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldarg.0 - IL_001c: pop - IL_001d: ldarg.0 - IL_001e: stloc.2 - IL_001f: ldloc.1 - IL_0020: stloc.3 - IL_0021: ldarg.2 - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: ldfld int32 ABC/ABC/Expr::item - IL_002a: ldloc.3 - IL_002b: ldfld int32 ABC/ABC/Expr::item - IL_0030: ceq - IL_0032: ret - - IL_0033: ldc.i4.0 - IL_0034: ret - - IL_0035: ldarg.1 - IL_0036: ldnull - IL_0037: cgt.un - IL_0039: ldc.i4.0 - IL_003a: ceq - IL_003c: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(class ABC/ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) - .maxstack 4 - .locals init (class ABC/ABC/Expr V_0, - class ABC/ABC/Expr V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_002a - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: ldfld int32 ABC/ABC/Expr::item - IL_0021: ldloc.1 - IL_0022: ldfld int32 ABC/ABC/Expr::item - IL_0027: ceq - IL_0029: ret - - IL_002a: ldc.i4.0 - IL_002b: ret - - IL_002c: ldarg.1 - IL_002d: ldnull - IL_002e: cgt.un - IL_0030: ldc.i4.0 - IL_0031: ceq - IL_0033: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class ABC/ABC/Expr V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst ABC/ABC/Expr - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool ABC/ABC/Expr::Equals(class ABC/ABC/Expr) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method Expr::Equals - - .property instance int32 Tag() - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .get instance int32 ABC/ABC/Expr::get_Tag() - } // end of property Expr::Tag - .property instance int32 Item() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .get instance int32 ABC/ABC/Expr::get_Item() - } // end of property Expr::Item - } // end of class Expr - - .class auto ansi nested public beforefieldinit MyExn - extends [mscorlib]System.Exception - implements [mscorlib]System.Collections.IStructuralEquatable - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) - .field assembly int32 Data0@ - .method public specialname rtspecialname - instance void .ctor(int32 data0) cil managed - { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 ABC/ABC/MyExn::Data0@ - IL_000d: ret - } // end of method MyExn::.ctor - - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ret - } // end of method MyExn::.ctor - - .method public hidebysig specialname - instance int32 get_Data0() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 ABC/ABC/MyExn::Data0@ - IL_0006: ret - } // end of method MyExn::get_Data0 - - .method public hidebysig virtual instance int32 - GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 45 (0x2d) - .maxstack 7 - .locals init (int32 V_0, - class [mscorlib]System.Collections.IEqualityComparer V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002b - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldc.i4 0x9e3779b9 - IL_0012: ldarg.1 - IL_0013: stloc.1 - IL_0014: ldarg.0 - IL_0015: castclass ABC/ABC/MyExn - IL_001a: call instance int32 ABC/ABC/MyExn::get_Data0() - IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldloc.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance int32 - GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 17,17 : 23,28 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 ABC/ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance bool - Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0, - class [mscorlib]System.Exception V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0044 - - IL_000b: ldarg.1 - IL_000c: isinst [mscorlib]System.Exception - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0042 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_0021: brtrue.s IL_0025 - - IL_0023: br.s IL_0040 - - IL_0025: ldarg.2 - IL_0026: stloc.2 - IL_0027: ldarg.0 - IL_0028: castclass ABC/ABC/MyExn - IL_002d: call instance int32 ABC/ABC/MyExn::get_Data0() - IL_0032: ldloc.1 - IL_0033: castclass ABC/ABC/MyExn - IL_0038: call instance int32 ABC/ABC/MyExn::get_Data0() - IL_003d: ceq - IL_003f: ret - - IL_0040: ldc.i4.0 - IL_0041: ret - - IL_0042: ldc.i4.0 - IL_0043: ret - - IL_0044: ldarg.1 - IL_0045: ldnull - IL_0046: cgt.un - IL_0048: ldc.i4.0 - IL_0049: ceq - IL_004b: ret - } // end of method MyExn::Equals - - .method public hidebysig instance bool - Equals(class [mscorlib]System.Exception obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) - .maxstack 4 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_003c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_003a - - IL_0015: ldarg.1 - IL_0016: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_001b: brtrue.s IL_001f - - IL_001d: br.s IL_0038 - - IL_001f: ldarg.0 - IL_0020: castclass ABC/ABC/MyExn - IL_0025: call instance int32 ABC/ABC/MyExn::get_Data0() - IL_002a: ldarg.1 - IL_002b: castclass ABC/ABC/MyExn - IL_0030: call instance int32 ABC/ABC/MyExn::get_Data0() - IL_0035: ceq - IL_0037: ret - - IL_0038: ldc.i4.0 - IL_0039: ret - - IL_003a: ldc.i4.0 - IL_003b: ret - - IL_003c: ldarg.1 - IL_003d: ldnull - IL_003e: cgt.un - IL_0040: ldc.i4.0 - IL_0041: ceq - IL_0043: ret - } // end of method MyExn::Equals - - .method public hidebysig virtual instance bool - Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst [mscorlib]System.Exception - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool ABC/ABC/MyExn::Equals(class [mscorlib]System.Exception) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method MyExn::Equals - - .property instance int32 Data0() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) - .get instance int32 ABC/ABC/MyExn::get_Data0() - } // end of property MyExn::Data0 - } // end of class MyExn - - .class auto ansi nested public A - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .field assembly string x - .method public specialname rtspecialname - instance void .ctor(string x) cil managed - { - // Code size 17 (0x11) - .maxstack 8 - .line 18,18 : 20,21 - IL_0000: ldarg.0 - IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: pop - IL_0008: nop - IL_0009: ldarg.0 - IL_000a: ldarg.1 - IL_000b: stfld string ABC/ABC/A::x - .line 18,18 : 18,19 - IL_0010: ret - } // end of method A::.ctor - - .method public hidebysig specialname - instance string get_X() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - .line 18,18 : 46,47 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldfld string ABC/ABC/A::x - IL_0007: ret - } // end of method A::get_X - - .property instance string X() - { - .get instance string ABC/ABC/A::get_X() - } // end of property A::X - } // end of class A - - .method public static int32 'add'(int32 x, - int32 y) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 5 (0x5) - .maxstack 8 - .line 21,21 : 27,32 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: add - IL_0004: ret - } // end of method ABC::'add' - - .method public specialname static string - get_greeting() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: nop - IL_0001: ldstr "hello" - IL_0006: ret - } // end of method ABC::get_greeting - - .property string greeting() - { - .get string ABC/ABC::get_greeting() - } // end of property ABC::greeting - } // end of class ABC - - .method public static int32 'add'(int32 x, - int32 y) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 5 (0x5) - .maxstack 8 - .line 11,11 : 23,28 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: add - IL_0004: ret - } // end of method ABC::'add' - - .method public specialname static string - get_greeting() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: nop - IL_0001: ldstr "hello" - IL_0006: ret - } // end of method ABC::get_greeting - - .property string greeting() - { - .get string ABC::get_greeting() - } // end of property ABC::greeting -} // end of class ABC - -.class private abstract auto ansi sealed ''.$ABC - extends [mscorlib]System.Object -{ - .field static assembly int32 init@ - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method private specialname rtspecialname static - void .cctor() cil managed - { - // Code size 14 (0xe) - .maxstack 3 - .locals init ([0] string greeting, - [1] string V_1) - .line 12,12 : 9,31 '' - IL_0000: nop - IL_0001: call string ABC::get_greeting() - IL_0006: stloc.0 - .line 22,22 : 13,35 '' - IL_0007: call string ABC/ABC::get_greeting() - IL_000c: stloc.1 - IL_000d: ret - } // end of method $ABC::.cctor -} // end of class ''.$ABC - - -// ============================================================= - -// *********** DISASSEMBLY COMPLETE *********************** diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespace.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespace.il.bsl index bf83c61d107..5979b8d1850 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespace.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespace.il.bsl @@ -1,4 +1,2507 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly extern FSharp.Core +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 5:0:0:0 +} +.assembly ToplevelNamespace +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 01 01 00 00 00 00 ) + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.mresource public FSharpSignatureData.ToplevelNamespace +{ + // Offset: 0x00000000 Length: 0x00001848 +} +.mresource public FSharpOptimizationData.ToplevelNamespace +{ + // Offset: 0x00001850 Length: 0x0000055C +} +.module ToplevelNamespace.dll +// MVID: {61259040-218B-729A-A745-038340902561} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x073B0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto autochar serializable sealed beforefieldinit XYZ.Expr + extends [mscorlib]System.Object + implements class [mscorlib]System.IEquatable`1, + [mscorlib]System.Collections.IStructuralEquatable, + class [mscorlib]System.IComparable`1, + [mscorlib]System.IComparable, + [mscorlib]System.Collections.IStructuralComparable +{ + .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl + 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .field assembly initonly int32 item + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static class XYZ.Expr NewNum(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void XYZ.Expr::.ctor(int32) + IL_0006: ret + } // end of method Expr::NewNum + + .method assembly specialname rtspecialname + instance void .ctor(int32 item) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.Expr::item + IL_000d: ret + } // end of method Expr::.ctor + + .method public hidebysig instance int32 + get_Item() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.Expr::item + IL_0006: ret + } // end of method Expr::get_Item + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: pop + IL_0002: ldc.i4.0 + IL_0003: ret + } // end of method Expr::get_Tag + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::__DebugDisplay + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class XYZ.Expr>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::ToString + + .method public hidebysig virtual final + instance int32 CompareTo(class XYZ.Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 65 (0x41) + .maxstack 4 + .locals init ([0] class XYZ.Expr V_0, + [1] class XYZ.Expr V_1, + [2] class [mscorlib]System.Collections.IComparer V_2, + [3] int32 V_3, + [4] int32 V_4) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 7,7 : 10,14 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SerializableAttribute\\ToplevelNamespace.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0037 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0035 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.2 + IL_0019: ldloc.0 + IL_001a: ldfld int32 XYZ.Expr::item + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.Expr::item + IL_0026: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0028: ldloc.3 + IL_0029: ldloc.s V_4 + IL_002b: bge.s IL_002f + + .line 100001,100001 : 0,0 '' + IL_002d: ldc.i4.m1 + IL_002e: ret + + .line 100001,100001 : 0,0 '' + IL_002f: ldloc.3 + IL_0030: ldloc.s V_4 + IL_0032: cgt + IL_0034: ret + + .line 100001,100001 : 0,0 '' + IL_0035: ldc.i4.1 + IL_0036: ret + + .line 100001,100001 : 0,0 '' + IL_0037: ldarg.1 + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_003d: ldc.i4.m1 + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.0 + IL_0040: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 13 (0xd) + .maxstack 8 + .line 7,7 : 10,14 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any XYZ.Expr + IL_0007: callvirt instance int32 XYZ.Expr::CompareTo(class XYZ.Expr) + IL_000c: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [mscorlib]System.Collections.IComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 80 (0x50) + .maxstack 4 + .locals init ([0] class XYZ.Expr V_0, + [1] class XYZ.Expr V_1, + [2] class XYZ.Expr V_2, + [3] class [mscorlib]System.Collections.IComparer V_3, + [4] int32 V_4, + [5] int32 V_5) + .line 7,7 : 10,14 '' + IL_0000: ldarg.1 + IL_0001: unbox.any XYZ.Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0041 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: unbox.any XYZ.Expr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_0018: ldarg.0 + IL_0019: pop + .line 100001,100001 : 0,0 '' + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.Expr::item + IL_0026: stloc.s V_4 + IL_0028: ldloc.2 + IL_0029: ldfld int32 XYZ.Expr::item + IL_002e: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0030: ldloc.s V_4 + IL_0032: ldloc.s V_5 + IL_0034: bge.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_0036: ldc.i4.m1 + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.s V_4 + IL_003a: ldloc.s V_5 + IL_003c: cgt + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.1 + IL_0040: ret + + .line 100001,100001 : 0,0 '' + IL_0041: ldarg.1 + IL_0042: unbox.any XYZ.Expr + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: brfalse.s IL_004e + + .line 100001,100001 : 0,0 '' + IL_004c: ldc.i4.m1 + IL_004d: ret + + .line 100001,100001 : 0,0 '' + IL_004e: ldc.i4.0 + IL_004f: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 42 (0x2a) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class XYZ.Expr V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 7,7 : 10,14 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 XYZ.Expr::item + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: ret + + .line 100001,100001 : 0,0 '' + IL_0028: ldc.i4.0 + IL_0029: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance int32 GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 7,7 : 10,14 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 53 (0x35) + .maxstack 4 + .locals init ([0] class XYZ.Expr V_0, + [1] class XYZ.Expr V_1, + [2] class XYZ.Expr V_2, + [3] class XYZ.Expr V_3, + [4] class [mscorlib]System.Collections.IEqualityComparer V_4) + .line 7,7 : 10,14 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002d + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst XYZ.Expr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_002b + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: pop + .line 100001,100001 : 0,0 '' + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 XYZ.Expr::item + IL_0022: ldloc.3 + IL_0023: ldfld int32 XYZ.Expr::item + IL_0028: ceq + IL_002a: ret + + .line 100001,100001 : 0,0 '' + IL_002b: ldc.i4.0 + IL_002c: ret + + .line 100001,100001 : 0,0 '' + IL_002d: ldarg.1 + IL_002e: ldnull + IL_002f: cgt.un + IL_0031: ldc.i4.0 + IL_0032: ceq + IL_0034: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(class XYZ.Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 44 (0x2c) + .maxstack 4 + .locals init ([0] class XYZ.Expr V_0, + [1] class XYZ.Expr V_1) + .line 7,7 : 10,14 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0024 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0022 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: ldloc.0 + IL_0014: ldfld int32 XYZ.Expr::item + IL_0019: ldloc.1 + IL_001a: ldfld int32 XYZ.Expr::item + IL_001f: ceq + IL_0021: ret + + .line 100001,100001 : 0,0 '' + IL_0022: ldc.i4.0 + IL_0023: ret + + .line 100001,100001 : 0,0 '' + IL_0024: ldarg.1 + IL_0025: ldnull + IL_0026: cgt.un + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class XYZ.Expr V_0) + .line 7,7 : 10,14 '' + IL_0000: ldarg.1 + IL_0001: isinst XYZ.Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.Expr::Equals(class XYZ.Expr) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method Expr::Equals + + .property instance int32 Tag() + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.Expr::get_Tag() + } // end of property Expr::Tag + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 XYZ.Expr::get_Item() + } // end of property Expr::Item +} // end of class XYZ.Expr + +.class public auto ansi serializable beforefieldinit XYZ.MyExn + extends [mscorlib]System.Exception + implements [mscorlib]System.Collections.IStructuralEquatable +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) + .field assembly int32 Data0@ + .method public specialname rtspecialname + instance void .ctor(int32 data0) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.MyExn::Data0@ + IL_000d: ret + } // end of method MyExn::.ctor + + .method public specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ret + } // end of method MyExn::.ctor + + .method family specialname rtspecialname + instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext) + IL_0008: ret + } // end of method MyExn::.ctor + + .method public hidebysig specialname instance int32 + get_Data0() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.MyExn::Data0@ + IL_0006: ret + } // end of method MyExn::get_Data0 + + .method public hidebysig virtual instance int32 + GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class [mscorlib]System.Collections.IEqualityComparer V_1) + .line 8,8 : 15,20 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: castclass XYZ.MyExn + IL_0016: call instance int32 XYZ.MyExn::get_Data0() + IL_001b: ldloc.0 + IL_001c: ldc.i4.6 + IL_001d: shl + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: shr + IL_0021: add + IL_0022: add + IL_0023: add + IL_0024: stloc.0 + IL_0025: ldloc.0 + IL_0026: ret + + .line 100001,100001 : 0,0 '' + IL_0027: ldc.i4.0 + IL_0028: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance int32 + GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 8,8 : 15,20 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance bool + Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 68 (0x44) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 8,8 : 15,20 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003c + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst [mscorlib]System.Exception + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003a + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0019: brtrue.s IL_001d + + IL_001b: br.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_001d: ldarg.2 + IL_001e: stloc.2 + IL_001f: ldarg.0 + IL_0020: castclass XYZ.MyExn + IL_0025: call instance int32 XYZ.MyExn::get_Data0() + IL_002a: ldloc.1 + IL_002b: castclass XYZ.MyExn + IL_0030: call instance int32 XYZ.MyExn::get_Data0() + IL_0035: ceq + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldc.i4.0 + IL_0039: ret + + .line 100001,100001 : 0,0 '' + IL_003a: ldc.i4.0 + IL_003b: ret + + .line 100001,100001 : 0,0 '' + IL_003c: ldarg.1 + IL_003d: ldnull + IL_003e: cgt.un + IL_0040: ldc.i4.0 + IL_0041: ceq + IL_0043: ret + } // end of method MyExn::Equals + + .method public hidebysig instance bool + Equals(class [mscorlib]System.Exception obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 60 (0x3c) + .maxstack 8 + .line 8,8 : 15,20 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0013: brtrue.s IL_0017 + + IL_0015: br.s IL_0030 + + .line 100001,100001 : 0,0 '' + IL_0017: ldarg.0 + IL_0018: castclass XYZ.MyExn + IL_001d: call instance int32 XYZ.MyExn::get_Data0() + IL_0022: ldarg.1 + IL_0023: castclass XYZ.MyExn + IL_0028: call instance int32 XYZ.MyExn::get_Data0() + IL_002d: ceq + IL_002f: ret + + .line 100001,100001 : 0,0 '' + IL_0030: ldc.i4.0 + IL_0031: ret + + .line 100001,100001 : 0,0 '' + IL_0032: ldc.i4.0 + IL_0033: ret + + .line 100001,100001 : 0,0 '' + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret + } // end of method MyExn::Equals + + .method public hidebysig virtual instance bool + Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0) + .line 8,8 : 15,20 '' + IL_0000: ldarg.1 + IL_0001: isinst [mscorlib]System.Exception + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.MyExn::Equals(class [mscorlib]System.Exception) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method MyExn::Equals + + .property instance int32 Data0() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.MyExn::get_Data0() + } // end of property MyExn::Data0 +} // end of class XYZ.MyExn + +.class public auto ansi serializable XYZ.A + extends [mscorlib]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly string x + .method public specialname rtspecialname + instance void .ctor(string x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + .line 9,9 : 12,13 '' + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string XYZ.A::x + .line 9,9 : 10,11 '' + IL_000f: ret + } // end of method A::.ctor + + .method public hidebysig specialname instance string + get_X() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 9,9 : 38,39 '' + IL_0000: ldarg.0 + IL_0001: ldfld string XYZ.A::x + IL_0006: ret + } // end of method A::get_X + + .property instance string X() + { + .get instance string XYZ.A::get_X() + } // end of property A::X +} // end of class XYZ.A + +.class public abstract auto ansi sealed XYZ.ABC + extends [mscorlib]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit Expr + extends [mscorlib]System.Object + implements class [mscorlib]System.IEquatable`1, + [mscorlib]System.Collections.IStructuralEquatable, + class [mscorlib]System.IComparable`1, + [mscorlib]System.IComparable, + [mscorlib]System.Collections.IStructuralComparable + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl + 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .field assembly initonly int32 item + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static class XYZ.ABC/Expr + NewNum(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void XYZ.ABC/Expr::.ctor(int32) + IL_0006: ret + } // end of method Expr::NewNum + + .method assembly specialname rtspecialname + instance void .ctor(int32 item) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.ABC/Expr::item + IL_000d: ret + } // end of method Expr::.ctor + + .method public hidebysig instance int32 + get_Item() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.ABC/Expr::item + IL_0006: ret + } // end of method Expr::get_Item + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: pop + IL_0002: ldc.i4.0 + IL_0003: ret + } // end of method Expr::get_Tag + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::__DebugDisplay + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class XYZ.ABC/Expr>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::ToString + + .method public hidebysig virtual final + instance int32 CompareTo(class XYZ.ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 65 (0x41) + .maxstack 4 + .locals init ([0] class XYZ.ABC/Expr V_0, + [1] class XYZ.ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IComparer V_2, + [3] int32 V_3, + [4] int32 V_4) + .line 13,13 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0037 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0035 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.2 + IL_0019: ldloc.0 + IL_001a: ldfld int32 XYZ.ABC/Expr::item + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.ABC/Expr::item + IL_0026: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0028: ldloc.3 + IL_0029: ldloc.s V_4 + IL_002b: bge.s IL_002f + + .line 100001,100001 : 0,0 '' + IL_002d: ldc.i4.m1 + IL_002e: ret + + .line 100001,100001 : 0,0 '' + IL_002f: ldloc.3 + IL_0030: ldloc.s V_4 + IL_0032: cgt + IL_0034: ret + + .line 100001,100001 : 0,0 '' + IL_0035: ldc.i4.1 + IL_0036: ret + + .line 100001,100001 : 0,0 '' + IL_0037: ldarg.1 + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_003d: ldc.i4.m1 + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.0 + IL_0040: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 13 (0xd) + .maxstack 8 + .line 13,13 : 14,18 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any XYZ.ABC/Expr + IL_0007: callvirt instance int32 XYZ.ABC/Expr::CompareTo(class XYZ.ABC/Expr) + IL_000c: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [mscorlib]System.Collections.IComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 80 (0x50) + .maxstack 4 + .locals init ([0] class XYZ.ABC/Expr V_0, + [1] class XYZ.ABC/Expr V_1, + [2] class XYZ.ABC/Expr V_2, + [3] class [mscorlib]System.Collections.IComparer V_3, + [4] int32 V_4, + [5] int32 V_5) + .line 13,13 : 14,18 '' + IL_0000: ldarg.1 + IL_0001: unbox.any XYZ.ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0041 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: unbox.any XYZ.ABC/Expr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_0018: ldarg.0 + IL_0019: pop + .line 100001,100001 : 0,0 '' + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.ABC/Expr::item + IL_0026: stloc.s V_4 + IL_0028: ldloc.2 + IL_0029: ldfld int32 XYZ.ABC/Expr::item + IL_002e: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0030: ldloc.s V_4 + IL_0032: ldloc.s V_5 + IL_0034: bge.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_0036: ldc.i4.m1 + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.s V_4 + IL_003a: ldloc.s V_5 + IL_003c: cgt + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.1 + IL_0040: ret + + .line 100001,100001 : 0,0 '' + IL_0041: ldarg.1 + IL_0042: unbox.any XYZ.ABC/Expr + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: brfalse.s IL_004e + + .line 100001,100001 : 0,0 '' + IL_004c: ldc.i4.m1 + IL_004d: ret + + .line 100001,100001 : 0,0 '' + IL_004e: ldc.i4.0 + IL_004f: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 42 (0x2a) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class XYZ.ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 13,13 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 XYZ.ABC/Expr::item + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: ret + + .line 100001,100001 : 0,0 '' + IL_0028: ldc.i4.0 + IL_0029: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance int32 GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 13,13 : 14,18 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 53 (0x35) + .maxstack 4 + .locals init ([0] class XYZ.ABC/Expr V_0, + [1] class XYZ.ABC/Expr V_1, + [2] class XYZ.ABC/Expr V_2, + [3] class XYZ.ABC/Expr V_3, + [4] class [mscorlib]System.Collections.IEqualityComparer V_4) + .line 13,13 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002d + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst XYZ.ABC/Expr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_002b + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: pop + .line 100001,100001 : 0,0 '' + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 XYZ.ABC/Expr::item + IL_0022: ldloc.3 + IL_0023: ldfld int32 XYZ.ABC/Expr::item + IL_0028: ceq + IL_002a: ret + + .line 100001,100001 : 0,0 '' + IL_002b: ldc.i4.0 + IL_002c: ret + + .line 100001,100001 : 0,0 '' + IL_002d: ldarg.1 + IL_002e: ldnull + IL_002f: cgt.un + IL_0031: ldc.i4.0 + IL_0032: ceq + IL_0034: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(class XYZ.ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 44 (0x2c) + .maxstack 4 + .locals init ([0] class XYZ.ABC/Expr V_0, + [1] class XYZ.ABC/Expr V_1) + .line 13,13 : 14,18 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0024 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0022 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: ldloc.0 + IL_0014: ldfld int32 XYZ.ABC/Expr::item + IL_0019: ldloc.1 + IL_001a: ldfld int32 XYZ.ABC/Expr::item + IL_001f: ceq + IL_0021: ret + + .line 100001,100001 : 0,0 '' + IL_0022: ldc.i4.0 + IL_0023: ret + + .line 100001,100001 : 0,0 '' + IL_0024: ldarg.1 + IL_0025: ldnull + IL_0026: cgt.un + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class XYZ.ABC/Expr V_0) + .line 13,13 : 14,18 '' + IL_0000: ldarg.1 + IL_0001: isinst XYZ.ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.ABC/Expr::Equals(class XYZ.ABC/Expr) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method Expr::Equals + + .property instance int32 Tag() + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.ABC/Expr::get_Tag() + } // end of property Expr::Tag + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 XYZ.ABC/Expr::get_Item() + } // end of property Expr::Item + } // end of class Expr + + .class auto ansi serializable nested public beforefieldinit MyExn + extends [mscorlib]System.Exception + implements [mscorlib]System.Collections.IStructuralEquatable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) + .field assembly int32 Data0@ + .method public specialname rtspecialname + instance void .ctor(int32 data0) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.ABC/MyExn::Data0@ + IL_000d: ret + } // end of method MyExn::.ctor + + .method public specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ret + } // end of method MyExn::.ctor + + .method family specialname rtspecialname + instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext) + IL_0008: ret + } // end of method MyExn::.ctor + + .method public hidebysig specialname + instance int32 get_Data0() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.ABC/MyExn::Data0@ + IL_0006: ret + } // end of method MyExn::get_Data0 + + .method public hidebysig virtual instance int32 + GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class [mscorlib]System.Collections.IEqualityComparer V_1) + .line 14,14 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: castclass XYZ.ABC/MyExn + IL_0016: call instance int32 XYZ.ABC/MyExn::get_Data0() + IL_001b: ldloc.0 + IL_001c: ldc.i4.6 + IL_001d: shl + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: shr + IL_0021: add + IL_0022: add + IL_0023: add + IL_0024: stloc.0 + IL_0025: ldloc.0 + IL_0026: ret + + .line 100001,100001 : 0,0 '' + IL_0027: ldc.i4.0 + IL_0028: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance int32 + GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 14,14 : 19,24 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance bool + Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 68 (0x44) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 14,14 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003c + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst [mscorlib]System.Exception + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003a + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0019: brtrue.s IL_001d + + IL_001b: br.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_001d: ldarg.2 + IL_001e: stloc.2 + IL_001f: ldarg.0 + IL_0020: castclass XYZ.ABC/MyExn + IL_0025: call instance int32 XYZ.ABC/MyExn::get_Data0() + IL_002a: ldloc.1 + IL_002b: castclass XYZ.ABC/MyExn + IL_0030: call instance int32 XYZ.ABC/MyExn::get_Data0() + IL_0035: ceq + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldc.i4.0 + IL_0039: ret + + .line 100001,100001 : 0,0 '' + IL_003a: ldc.i4.0 + IL_003b: ret + + .line 100001,100001 : 0,0 '' + IL_003c: ldarg.1 + IL_003d: ldnull + IL_003e: cgt.un + IL_0040: ldc.i4.0 + IL_0041: ceq + IL_0043: ret + } // end of method MyExn::Equals + + .method public hidebysig instance bool + Equals(class [mscorlib]System.Exception obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 60 (0x3c) + .maxstack 8 + .line 14,14 : 19,24 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0013: brtrue.s IL_0017 + + IL_0015: br.s IL_0030 + + .line 100001,100001 : 0,0 '' + IL_0017: ldarg.0 + IL_0018: castclass XYZ.ABC/MyExn + IL_001d: call instance int32 XYZ.ABC/MyExn::get_Data0() + IL_0022: ldarg.1 + IL_0023: castclass XYZ.ABC/MyExn + IL_0028: call instance int32 XYZ.ABC/MyExn::get_Data0() + IL_002d: ceq + IL_002f: ret + + .line 100001,100001 : 0,0 '' + IL_0030: ldc.i4.0 + IL_0031: ret + + .line 100001,100001 : 0,0 '' + IL_0032: ldc.i4.0 + IL_0033: ret + + .line 100001,100001 : 0,0 '' + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret + } // end of method MyExn::Equals + + .method public hidebysig virtual instance bool + Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0) + .line 14,14 : 19,24 '' + IL_0000: ldarg.1 + IL_0001: isinst [mscorlib]System.Exception + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.ABC/MyExn::Equals(class [mscorlib]System.Exception) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method MyExn::Equals + + .property instance int32 Data0() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.ABC/MyExn::get_Data0() + } // end of property MyExn::Data0 + } // end of class MyExn + + .class auto ansi serializable nested public A + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly string x + .method public specialname rtspecialname + instance void .ctor(string x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + .line 15,15 : 16,17 '' + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string XYZ.ABC/A::x + .line 15,15 : 14,15 '' + IL_000f: ret + } // end of method A::.ctor + + .method public hidebysig specialname + instance string get_X() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 15,15 : 42,43 '' + IL_0000: ldarg.0 + IL_0001: ldfld string XYZ.ABC/A::x + IL_0006: ret + } // end of method A::get_X + + .property instance string X() + { + .get instance string XYZ.ABC/A::get_X() + } // end of property A::X + } // end of class A + + .class abstract auto ansi sealed nested public ABC + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested public beforefieldinit Expr + extends [mscorlib]System.Object + implements class [mscorlib]System.IEquatable`1, + [mscorlib]System.Collections.IStructuralEquatable, + class [mscorlib]System.IComparable`1, + [mscorlib]System.IComparable, + [mscorlib]System.Collections.IStructuralComparable + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl + 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) + .field assembly initonly int32 item + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public static class XYZ.ABC/ABC/Expr + NewNum(int32 item) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void XYZ.ABC/ABC/Expr::.ctor(int32) + IL_0006: ret + } // end of method Expr::NewNum + + .method assembly specialname rtspecialname + instance void .ctor(int32 item) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.ABC/ABC/Expr::item + IL_000d: ret + } // end of method Expr::.ctor + + .method public hidebysig instance int32 + get_Item() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0006: ret + } // end of method Expr::get_Item + + .method public hidebysig instance int32 + get_Tag() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: pop + IL_0002: ldc.i4.0 + IL_0003: ret + } // end of method Expr::get_Tag + + .method assembly hidebysig specialname + instance object __DebugDisplay() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+0.8A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::__DebugDisplay + + .method public strict virtual instance string + ToString() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldstr "%+A" + IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class XYZ.ABC/ABC/Expr>::.ctor(string) + IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_000f: ldarg.0 + IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0015: ret + } // end of method Expr::ToString + + .method public hidebysig virtual final + instance int32 CompareTo(class XYZ.ABC/ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 65 (0x41) + .maxstack 4 + .locals init ([0] class XYZ.ABC/ABC/Expr V_0, + [1] class XYZ.ABC/ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IComparer V_2, + [3] int32 V_3, + [4] int32 V_4) + .line 23,23 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0037 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0035 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.2 + IL_0019: ldloc.0 + IL_001a: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0026: stloc.s V_4 + .line 100001,100001 : 0,0 '' + IL_0028: ldloc.3 + IL_0029: ldloc.s V_4 + IL_002b: bge.s IL_002f + + .line 100001,100001 : 0,0 '' + IL_002d: ldc.i4.m1 + IL_002e: ret + + .line 100001,100001 : 0,0 '' + IL_002f: ldloc.3 + IL_0030: ldloc.s V_4 + IL_0032: cgt + IL_0034: ret + + .line 100001,100001 : 0,0 '' + IL_0035: ldc.i4.1 + IL_0036: ret + + .line 100001,100001 : 0,0 '' + IL_0037: ldarg.1 + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_003d: ldc.i4.m1 + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.0 + IL_0040: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 13 (0xd) + .maxstack 8 + .line 23,23 : 18,22 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any XYZ.ABC/ABC/Expr + IL_0007: callvirt instance int32 XYZ.ABC/ABC/Expr::CompareTo(class XYZ.ABC/ABC/Expr) + IL_000c: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 CompareTo(object obj, + class [mscorlib]System.Collections.IComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 80 (0x50) + .maxstack 4 + .locals init ([0] class XYZ.ABC/ABC/Expr V_0, + [1] class XYZ.ABC/ABC/Expr V_1, + [2] class XYZ.ABC/ABC/Expr V_2, + [3] class [mscorlib]System.Collections.IComparer V_3, + [4] int32 V_4, + [5] int32 V_5) + .line 23,23 : 18,22 '' + IL_0000: ldarg.1 + IL_0001: unbox.any XYZ.ABC/ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0041 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: unbox.any XYZ.ABC/ABC/Expr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_003f + + .line 100001,100001 : 0,0 '' + IL_0018: ldarg.0 + IL_0019: pop + .line 100001,100001 : 0,0 '' + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.3 + IL_0020: ldloc.1 + IL_0021: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0026: stloc.s V_4 + IL_0028: ldloc.2 + IL_0029: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_002e: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0030: ldloc.s V_4 + IL_0032: ldloc.s V_5 + IL_0034: bge.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_0036: ldc.i4.m1 + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.s V_4 + IL_003a: ldloc.s V_5 + IL_003c: cgt + IL_003e: ret + + .line 100001,100001 : 0,0 '' + IL_003f: ldc.i4.1 + IL_0040: ret + + .line 100001,100001 : 0,0 '' + IL_0041: ldarg.1 + IL_0042: unbox.any XYZ.ABC/ABC/Expr + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: brfalse.s IL_004e + + .line 100001,100001 : 0,0 '' + IL_004c: ldc.i4.m1 + IL_004d: ret + + .line 100001,100001 : 0,0 '' + IL_004e: ldc.i4.0 + IL_004f: ret + } // end of method Expr::CompareTo + + .method public hidebysig virtual final + instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 42 (0x2a) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class XYZ.ABC/ABC/Expr V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 23,23 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl + IL_001f: ldloc.0 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: ret + + .line 100001,100001 : 0,0 '' + IL_0028: ldc.i4.0 + IL_0029: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance int32 GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 23,23 : 18,22 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.ABC/ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method Expr::GetHashCode + + .method public hidebysig virtual final + instance bool Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 53 (0x35) + .maxstack 4 + .locals init ([0] class XYZ.ABC/ABC/Expr V_0, + [1] class XYZ.ABC/ABC/Expr V_1, + [2] class XYZ.ABC/ABC/Expr V_2, + [3] class XYZ.ABC/ABC/Expr V_3, + [4] class [mscorlib]System.Collections.IEqualityComparer V_4) + .line 23,23 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002d + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst XYZ.ABC/ABC/Expr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_002b + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: pop + .line 100001,100001 : 0,0 '' + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0022: ldloc.3 + IL_0023: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0028: ceq + IL_002a: ret + + .line 100001,100001 : 0,0 '' + IL_002b: ldc.i4.0 + IL_002c: ret + + .line 100001,100001 : 0,0 '' + IL_002d: ldarg.1 + IL_002e: ldnull + IL_002f: cgt.un + IL_0031: ldc.i4.0 + IL_0032: ceq + IL_0034: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(class XYZ.ABC/ABC/Expr obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 44 (0x2c) + .maxstack 4 + .locals init ([0] class XYZ.ABC/ABC/Expr V_0, + [1] class XYZ.ABC/ABC/Expr V_1) + .line 23,23 : 18,22 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0024 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0022 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 100001,100001 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: ldloc.0 + IL_0014: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_0019: ldloc.1 + IL_001a: ldfld int32 XYZ.ABC/ABC/Expr::item + IL_001f: ceq + IL_0021: ret + + .line 100001,100001 : 0,0 '' + IL_0022: ldc.i4.0 + IL_0023: ret + + .line 100001,100001 : 0,0 '' + IL_0024: ldarg.1 + IL_0025: ldnull + IL_0026: cgt.un + IL_0028: ldc.i4.0 + IL_0029: ceq + IL_002b: ret + } // end of method Expr::Equals + + .method public hidebysig virtual final + instance bool Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class XYZ.ABC/ABC/Expr V_0) + .line 23,23 : 18,22 '' + IL_0000: ldarg.1 + IL_0001: isinst XYZ.ABC/ABC/Expr + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.ABC/ABC/Expr::Equals(class XYZ.ABC/ABC/Expr) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method Expr::Equals + + .property instance int32 Tag() + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.ABC/ABC/Expr::get_Tag() + } // end of property Expr::Tag + .property instance int32 Item() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .get instance int32 XYZ.ABC/ABC/Expr::get_Item() + } // end of property Expr::Item + } // end of class Expr + + .class auto ansi serializable nested public beforefieldinit MyExn + extends [mscorlib]System.Exception + implements [mscorlib]System.Collections.IStructuralEquatable + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) + .field assembly int32 Data0@ + .method public specialname rtspecialname + instance void .ctor(int32 data0) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 XYZ.ABC/ABC/MyExn::Data0@ + IL_000d: ret + } // end of method MyExn::.ctor + + .method public specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Exception::.ctor() + IL_0006: ret + } // end of method MyExn::.ctor + + .method family specialname rtspecialname + instance void .ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo info, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext context) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldarg.2 + IL_0003: call instance void [mscorlib]System.Exception::.ctor(class [mscorlib]System.Runtime.Serialization.SerializationInfo, + valuetype [mscorlib]System.Runtime.Serialization.StreamingContext) + IL_0008: ret + } // end of method MyExn::.ctor + + .method public hidebysig specialname + instance int32 get_Data0() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 XYZ.ABC/ABC/MyExn::Data0@ + IL_0006: ret + } // end of method MyExn::get_Data0 + + .method public hidebysig virtual instance int32 + GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 41 (0x29) + .maxstack 7 + .locals init ([0] int32 V_0, + [1] class [mscorlib]System.Collections.IEqualityComparer V_1) + .line 24,24 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: castclass XYZ.ABC/ABC/MyExn + IL_0016: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + IL_001b: ldloc.0 + IL_001c: ldc.i4.6 + IL_001d: shl + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: shr + IL_0021: add + IL_0022: add + IL_0023: add + IL_0024: stloc.0 + IL_0025: ldloc.0 + IL_0026: ret + + .line 100001,100001 : 0,0 '' + IL_0027: ldc.i4.0 + IL_0028: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance int32 + GetHashCode() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 12 (0xc) + .maxstack 8 + .line 24,24 : 23,28 '' + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: callvirt instance int32 XYZ.ABC/ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_000b: ret + } // end of method MyExn::GetHashCode + + .method public hidebysig virtual instance bool + Equals(object obj, + class [mscorlib]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 68 (0x44) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0, + [1] class [mscorlib]System.Exception V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) + .line 24,24 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003c + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst [mscorlib]System.Exception + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_003a + + .line 100001,100001 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0019: brtrue.s IL_001d + + IL_001b: br.s IL_0038 + + .line 100001,100001 : 0,0 '' + IL_001d: ldarg.2 + IL_001e: stloc.2 + IL_001f: ldarg.0 + IL_0020: castclass XYZ.ABC/ABC/MyExn + IL_0025: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + IL_002a: ldloc.1 + IL_002b: castclass XYZ.ABC/ABC/MyExn + IL_0030: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + IL_0035: ceq + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldc.i4.0 + IL_0039: ret + + .line 100001,100001 : 0,0 '' + IL_003a: ldc.i4.0 + IL_003b: ret + + .line 100001,100001 : 0,0 '' + IL_003c: ldarg.1 + IL_003d: ldnull + IL_003e: cgt.un + IL_0040: ldc.i4.0 + IL_0041: ceq + IL_0043: ret + } // end of method MyExn::Equals + + .method public hidebysig instance bool + Equals(class [mscorlib]System.Exception obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 60 (0x3c) + .maxstack 8 + .line 24,24 : 23,28 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 + + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 + + .line 100001,100001 : 0,0 '' + IL_000d: ldarg.1 + IL_000e: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) + IL_0013: brtrue.s IL_0017 + + IL_0015: br.s IL_0030 + + .line 100001,100001 : 0,0 '' + IL_0017: ldarg.0 + IL_0018: castclass XYZ.ABC/ABC/MyExn + IL_001d: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + IL_0022: ldarg.1 + IL_0023: castclass XYZ.ABC/ABC/MyExn + IL_0028: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + IL_002d: ceq + IL_002f: ret + + .line 100001,100001 : 0,0 '' + IL_0030: ldc.i4.0 + IL_0031: ret + + .line 100001,100001 : 0,0 '' + IL_0032: ldc.i4.0 + IL_0033: ret + + .line 100001,100001 : 0,0 '' + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret + } // end of method MyExn::Equals + + .method public hidebysig virtual instance bool + Equals(object obj) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class [mscorlib]System.Exception V_0) + .line 24,24 : 23,28 '' + IL_0000: ldarg.1 + IL_0001: isinst [mscorlib]System.Exception + IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + + .line 100001,100001 : 0,0 '' + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool XYZ.ABC/ABC/MyExn::Equals(class [mscorlib]System.Exception) + IL_0011: ret + + .line 100001,100001 : 0,0 '' + IL_0012: ldc.i4.0 + IL_0013: ret + } // end of method MyExn::Equals + + .property instance int32 Data0() + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, + int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) + .get instance int32 XYZ.ABC/ABC/MyExn::get_Data0() + } // end of property MyExn::Data0 + } // end of class MyExn + + .class auto ansi serializable nested public A + extends [mscorlib]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly string x + .method public specialname rtspecialname + instance void .ctor(string x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + .line 100001,100001 : 0,0 '' + IL_0000: ldarg.0 + IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + .line 25,25 : 20,21 '' + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld string XYZ.ABC/ABC/A::x + .line 25,25 : 18,19 '' + IL_000f: ret + } // end of method A::.ctor + + .method public hidebysig specialname + instance string get_X() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 25,25 : 46,47 '' + IL_0000: ldarg.0 + IL_0001: ldfld string XYZ.ABC/ABC/A::x + IL_0006: ret + } // end of method A::get_X + + .property instance string X() + { + .get instance string XYZ.ABC/ABC/A::get_X() + } // end of property A::X + } // end of class A + + .method public static int32 'add'(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + .line 28,28 : 27,32 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } // end of method ABC::'add' + + .method public specialname static string + get_greeting() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "hello" + IL_0005: ret + } // end of method ABC::get_greeting + + .property string greeting() + { + .get string XYZ.ABC/ABC::get_greeting() + } // end of property ABC::greeting + } // end of class ABC + + .method public static int32 'add'(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + // Code size 4 (0x4) + .maxstack 8 + .line 18,18 : 23,28 '' + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } // end of method ABC::'add' + + .method public specialname static string + get_greeting() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 6 (0x6) + .maxstack 8 + IL_0000: ldstr "hello" + IL_0005: ret + } // end of method ABC::get_greeting + + .property string greeting() + { + .get string XYZ.ABC::get_greeting() + } // end of property ABC::greeting +} // end of class XYZ.ABC + +.class private abstract auto ansi sealed ''.$ToplevelNamespace + extends [mscorlib]System.Object +{ + .field static assembly int32 init@ + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 13 (0xd) + .maxstack 3 + .locals init ([0] string greeting, + [1] string V_1) + .line 19,19 : 9,31 '' + IL_0000: call string XYZ.ABC::get_greeting() + IL_0005: stloc.0 + .line 29,29 : 13,35 '' + IL_0006: call string XYZ.ABC/ABC::get_greeting() + IL_000b: stloc.1 + IL_000c: ret + } // end of method $ToplevelNamespace::.cctor + +} // end of class ''.$ToplevelNamespace + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespaceP.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespaceP.il.bsl deleted file mode 100644 index 78d8c5dba0c..00000000000 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelNamespaceP.il.bsl +++ /dev/null @@ -1,2529 +0,0 @@ - -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.81.0 -// Copyright (c) Microsoft Corporation. All rights reserved. - - - -// Metadata version: v4.0.30319 -.assembly extern retargetable mscorlib -{ - .publickeytoken = (7C EC 85 D7 BE A7 79 8E ) // |.....y. - .ver 2:0:5:0 -} -.assembly extern FSharp.Core -{ - .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 3:47:41:0 -} -.assembly ToplevelNamespaceP -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, - int32, - int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - - // --- The following custom attribute is added automatically, do not uncomment ------- - // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 00 01 00 00 00 00 ) - - .hash algorithm 0x00008004 - .ver 0:0:0:0 -} -.mresource public FSharpSignatureData.ToplevelNamespaceP -{ - // Offset: 0x00000000 Length: 0x0000185A -} -.mresource public FSharpOptimizationData.ToplevelNamespaceP -{ - // Offset: 0x00001860 Length: 0x0000055D -} -.module ToplevelNamespaceP.dll -// MVID: {576266E4-88D9-D7FD-A745-0383E4666257} -.imagebase 0x00400000 -.file alignment 0x00000200 -.stackreserve 0x00100000 -.subsystem 0x0003 // WINDOWS_CUI -.corflags 0x00000001 // ILONLY -// Image base: 0x01450000 - - -// =============== CLASS MEMBERS DECLARATION =================== - -.class public auto autochar sealed beforefieldinit XYZ.Expr - extends [mscorlib]System.Object - implements class [mscorlib]System.IEquatable`1, - [mscorlib]System.Collections.IStructuralEquatable, - class [mscorlib]System.IComparable`1, - [mscorlib]System.IComparable, - [mscorlib]System.Collections.IStructuralComparable -{ - .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl - 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) - .field assembly initonly int32 item - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static class XYZ.Expr NewNum(int32 item) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void XYZ.Expr::.ctor(int32) - IL_0006: ret - } // end of method Expr::NewNum - - .method assembly specialname rtspecialname - instance void .ctor(int32 item) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.Expr::item - IL_000d: ret - } // end of method Expr::.ctor - - .method public hidebysig instance int32 - get_Item() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.Expr::item - IL_0006: ret - } // end of method Expr::get_Item - - .method public hidebysig instance int32 - get_Tag() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 4 (0x4) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: pop - IL_0002: ldc.i4.0 - IL_0003: ret - } // end of method Expr::get_Tag - - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%+0.8A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::__DebugDisplay - - .method public strict virtual instance string - ToString() cil managed - { - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::ToString - - .method public hidebysig virtual final - instance int32 CompareTo(class XYZ.Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) - .maxstack 4 - .locals init (class XYZ.Expr V_0, - class XYZ.Expr V_1, - class [mscorlib]System.Collections.IComparer V_2, - int32 V_3, - int32 V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0043 - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_0041 - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0020: stloc.2 - IL_0021: ldloc.0 - IL_0022: ldfld int32 XYZ.Expr::item - IL_0027: stloc.3 - IL_0028: ldloc.1 - IL_0029: ldfld int32 XYZ.Expr::item - IL_002e: stloc.s V_4 - IL_0030: ldloc.3 - IL_0031: ldloc.s V_4 - IL_0033: bge.s IL_0037 - - IL_0035: br.s IL_0039 - - IL_0037: br.s IL_003b - - IL_0039: ldc.i4.m1 - IL_003a: ret - - IL_003b: ldloc.3 - IL_003c: ldloc.s V_4 - IL_003e: cgt - IL_0040: ret - - IL_0041: ldc.i4.1 - IL_0042: ret - - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d - - IL_004b: br.s IL_004f - - IL_004d: ldc.i4.m1 - IL_004e: ret - - IL_004f: ldc.i4.0 - IL_0050: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 10,14 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SerializableAttribute\\ToplevelNamespace.fs' - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: unbox.any XYZ.Expr - IL_0008: callvirt instance int32 XYZ.Expr::CompareTo(class XYZ.Expr) - IL_000d: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [mscorlib]System.Collections.IComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 97 (0x61) - .maxstack 4 - .locals init ([0] class XYZ.Expr V_0, - [1] class XYZ.Expr V_1, - [2] class XYZ.Expr V_2, - [3] class [mscorlib]System.Collections.IComparer V_3, - [4] int32 V_4, - [5] int32 V_5) - .line 7,7 : 10,14 - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: unbox.any XYZ.Expr - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: ldnull - IL_000a: cgt.un - IL_000c: brfalse.s IL_0010 - - IL_000e: br.s IL_0012 - - IL_0010: br.s IL_004e - - .line 100001,100001 : 0,0 - IL_0012: ldarg.1 - IL_0013: unbox.any XYZ.Expr - IL_0018: ldnull - IL_0019: cgt.un - IL_001b: brfalse.s IL_001f - - IL_001d: br.s IL_0021 - - IL_001f: br.s IL_004c - - .line 100001,100001 : 0,0 - IL_0021: ldarg.0 - IL_0022: pop - .line 100001,100001 : 0,0 - IL_0023: ldarg.0 - IL_0024: stloc.1 - IL_0025: ldloc.0 - IL_0026: stloc.2 - IL_0027: ldarg.2 - IL_0028: stloc.3 - IL_0029: ldloc.1 - IL_002a: ldfld int32 XYZ.Expr::item - IL_002f: stloc.s V_4 - IL_0031: ldloc.2 - IL_0032: ldfld int32 XYZ.Expr::item - IL_0037: stloc.s V_5 - IL_0039: ldloc.s V_4 - IL_003b: ldloc.s V_5 - IL_003d: bge.s IL_0041 - - IL_003f: br.s IL_0043 - - IL_0041: br.s IL_0045 - - .line 100001,100001 : 0,0 - IL_0043: ldc.i4.m1 - IL_0044: ret - - .line 100001,100001 : 0,0 - IL_0045: ldloc.s V_4 - IL_0047: ldloc.s V_5 - IL_0049: cgt - IL_004b: ret - - .line 100001,100001 : 0,0 - IL_004c: ldc.i4.1 - IL_004d: ret - - .line 100001,100001 : 0,0 - IL_004e: ldarg.1 - IL_004f: unbox.any XYZ.Expr - IL_0054: ldnull - IL_0055: cgt.un - IL_0057: brfalse.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - - .line 100001,100001 : 0,0 - IL_005d: ldc.i4.m1 - IL_005e: ret - - .line 100001,100001 : 0,0 - IL_005f: ldc.i4.0 - IL_0060: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 46 (0x2e) - .maxstack 7 - .locals init (int32 V_0, - class XYZ.Expr V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldarg.0 - IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 - IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldc.i4 0x9e3779b9 - IL_0018: ldarg.1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld int32 XYZ.Expr::item - IL_0020: ldloc.0 - IL_0021: ldc.i4.6 - IL_0022: shl - IL_0023: ldloc.0 - IL_0024: ldc.i4.2 - IL_0025: shr - IL_0026: add - IL_0027: add - IL_0028: add - IL_0029: stloc.0 - IL_002a: ldloc.0 - IL_002b: ret - - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance int32 GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 7,7 : 10,14 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance bool Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 61 (0x3d) - .maxstack 4 - .locals init (class XYZ.Expr V_0, - class XYZ.Expr V_1, - class XYZ.Expr V_2, - class XYZ.Expr V_3, - class [mscorlib]System.Collections.IEqualityComparer V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0035 - - IL_000b: ldarg.1 - IL_000c: isinst XYZ.Expr - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0033 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldarg.0 - IL_001c: pop - IL_001d: ldarg.0 - IL_001e: stloc.2 - IL_001f: ldloc.1 - IL_0020: stloc.3 - IL_0021: ldarg.2 - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: ldfld int32 XYZ.Expr::item - IL_002a: ldloc.3 - IL_002b: ldfld int32 XYZ.Expr::item - IL_0030: ceq - IL_0032: ret - - IL_0033: ldc.i4.0 - IL_0034: ret - - IL_0035: ldarg.1 - IL_0036: ldnull - IL_0037: cgt.un - IL_0039: ldc.i4.0 - IL_003a: ceq - IL_003c: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(class XYZ.Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) - .maxstack 4 - .locals init (class XYZ.Expr V_0, - class XYZ.Expr V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_002a - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: ldfld int32 XYZ.Expr::item - IL_0021: ldloc.1 - IL_0022: ldfld int32 XYZ.Expr::item - IL_0027: ceq - IL_0029: ret - - IL_002a: ldc.i4.0 - IL_002b: ret - - IL_002c: ldarg.1 - IL_002d: ldnull - IL_002e: cgt.un - IL_0030: ldc.i4.0 - IL_0031: ceq - IL_0033: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class XYZ.Expr V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst XYZ.Expr - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.Expr::Equals(class XYZ.Expr) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method Expr::Equals - - .property instance int32 Tag() - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.Expr::get_Tag() - } // end of property Expr::Tag - .property instance int32 Item() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .get instance int32 XYZ.Expr::get_Item() - } // end of property Expr::Item -} // end of class XYZ.Expr - -.class public auto ansi beforefieldinit XYZ.MyExn - extends [mscorlib]System.Exception - implements [mscorlib]System.Collections.IStructuralEquatable -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) - .field assembly int32 Data0@ - .method public specialname rtspecialname - instance void .ctor(int32 data0) cil managed - { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.MyExn::Data0@ - IL_000d: ret - } // end of method MyExn::.ctor - - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ret - } // end of method MyExn::.ctor - - .method public hidebysig specialname instance int32 - get_Data0() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.MyExn::Data0@ - IL_0006: ret - } // end of method MyExn::get_Data0 - - .method public hidebysig virtual instance int32 - GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 45 (0x2d) - .maxstack 7 - .locals init (int32 V_0, - class [mscorlib]System.Collections.IEqualityComparer V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002b - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldc.i4 0x9e3779b9 - IL_0012: ldarg.1 - IL_0013: stloc.1 - IL_0014: ldarg.0 - IL_0015: castclass XYZ.MyExn - IL_001a: call instance int32 XYZ.MyExn::get_Data0() - IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldloc.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance int32 - GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 8,8 : 15,20 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance bool - Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0, - class [mscorlib]System.Exception V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0044 - - IL_000b: ldarg.1 - IL_000c: isinst [mscorlib]System.Exception - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0042 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_0021: brtrue.s IL_0025 - - IL_0023: br.s IL_0040 - - IL_0025: ldarg.2 - IL_0026: stloc.2 - IL_0027: ldarg.0 - IL_0028: castclass XYZ.MyExn - IL_002d: call instance int32 XYZ.MyExn::get_Data0() - IL_0032: ldloc.1 - IL_0033: castclass XYZ.MyExn - IL_0038: call instance int32 XYZ.MyExn::get_Data0() - IL_003d: ceq - IL_003f: ret - - IL_0040: ldc.i4.0 - IL_0041: ret - - IL_0042: ldc.i4.0 - IL_0043: ret - - IL_0044: ldarg.1 - IL_0045: ldnull - IL_0046: cgt.un - IL_0048: ldc.i4.0 - IL_0049: ceq - IL_004b: ret - } // end of method MyExn::Equals - - .method public hidebysig instance bool - Equals(class [mscorlib]System.Exception obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) - .maxstack 4 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_003c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_003a - - IL_0015: ldarg.1 - IL_0016: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_001b: brtrue.s IL_001f - - IL_001d: br.s IL_0038 - - IL_001f: ldarg.0 - IL_0020: castclass XYZ.MyExn - IL_0025: call instance int32 XYZ.MyExn::get_Data0() - IL_002a: ldarg.1 - IL_002b: castclass XYZ.MyExn - IL_0030: call instance int32 XYZ.MyExn::get_Data0() - IL_0035: ceq - IL_0037: ret - - IL_0038: ldc.i4.0 - IL_0039: ret - - IL_003a: ldc.i4.0 - IL_003b: ret - - IL_003c: ldarg.1 - IL_003d: ldnull - IL_003e: cgt.un - IL_0040: ldc.i4.0 - IL_0041: ceq - IL_0043: ret - } // end of method MyExn::Equals - - .method public hidebysig virtual instance bool - Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst [mscorlib]System.Exception - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.MyExn::Equals(class [mscorlib]System.Exception) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method MyExn::Equals - - .property instance int32 Data0() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.MyExn::get_Data0() - } // end of property MyExn::Data0 -} // end of class XYZ.MyExn - -.class public auto ansi XYZ.A - extends [mscorlib]System.Object -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .field assembly string x - .method public specialname rtspecialname - instance void .ctor(string x) cil managed - { - // Code size 17 (0x11) - .maxstack 8 - .line 9,9 : 12,13 - IL_0000: ldarg.0 - IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: pop - IL_0008: nop - IL_0009: ldarg.0 - IL_000a: ldarg.1 - IL_000b: stfld string XYZ.A::x - .line 9,9 : 10,11 - IL_0010: ret - } // end of method A::.ctor - - .method public hidebysig specialname instance string - get_X() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - .line 9,9 : 38,39 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldfld string XYZ.A::x - IL_0007: ret - } // end of method A::get_X - - .property instance string X() - { - .get instance string XYZ.A::get_X() - } // end of property A::X -} // end of class XYZ.A - -.class public abstract auto ansi sealed XYZ.ABC - extends [mscorlib]System.Object -{ - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar sealed nested public beforefieldinit Expr - extends [mscorlib]System.Object - implements class [mscorlib]System.IEquatable`1, - [mscorlib]System.Collections.IStructuralEquatable, - class [mscorlib]System.IComparable`1, - [mscorlib]System.IComparable, - [mscorlib]System.Collections.IStructuralComparable - { - .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl - 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) - .field assembly initonly int32 item - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static class XYZ.ABC/Expr - NewNum(int32 item) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void XYZ.ABC/Expr::.ctor(int32) - IL_0006: ret - } // end of method Expr::NewNum - - .method assembly specialname rtspecialname - instance void .ctor(int32 item) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.ABC/Expr::item - IL_000d: ret - } // end of method Expr::.ctor - - .method public hidebysig instance int32 - get_Item() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.ABC/Expr::item - IL_0006: ret - } // end of method Expr::get_Item - - .method public hidebysig instance int32 - get_Tag() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 4 (0x4) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: pop - IL_0002: ldc.i4.0 - IL_0003: ret - } // end of method Expr::get_Tag - - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%+0.8A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::__DebugDisplay - - .method public strict virtual instance string - ToString() cil managed - { - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::ToString - - .method public hidebysig virtual final - instance int32 CompareTo(class XYZ.ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) - .maxstack 4 - .locals init (class XYZ.ABC/Expr V_0, - class XYZ.ABC/Expr V_1, - class [mscorlib]System.Collections.IComparer V_2, - int32 V_3, - int32 V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0043 - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_0041 - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0020: stloc.2 - IL_0021: ldloc.0 - IL_0022: ldfld int32 XYZ.ABC/Expr::item - IL_0027: stloc.3 - IL_0028: ldloc.1 - IL_0029: ldfld int32 XYZ.ABC/Expr::item - IL_002e: stloc.s V_4 - IL_0030: ldloc.3 - IL_0031: ldloc.s V_4 - IL_0033: bge.s IL_0037 - - IL_0035: br.s IL_0039 - - IL_0037: br.s IL_003b - - IL_0039: ldc.i4.m1 - IL_003a: ret - - IL_003b: ldloc.3 - IL_003c: ldloc.s V_4 - IL_003e: cgt - IL_0040: ret - - IL_0041: ldc.i4.1 - IL_0042: ret - - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d - - IL_004b: br.s IL_004f - - IL_004d: ldc.i4.m1 - IL_004e: ret - - IL_004f: ldc.i4.0 - IL_0050: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - .line 13,13 : 14,18 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: unbox.any XYZ.ABC/Expr - IL_0008: callvirt instance int32 XYZ.ABC/Expr::CompareTo(class XYZ.ABC/Expr) - IL_000d: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [mscorlib]System.Collections.IComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 97 (0x61) - .maxstack 4 - .locals init ([0] class XYZ.ABC/Expr V_0, - [1] class XYZ.ABC/Expr V_1, - [2] class XYZ.ABC/Expr V_2, - [3] class [mscorlib]System.Collections.IComparer V_3, - [4] int32 V_4, - [5] int32 V_5) - .line 13,13 : 14,18 - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: unbox.any XYZ.ABC/Expr - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: ldnull - IL_000a: cgt.un - IL_000c: brfalse.s IL_0010 - - IL_000e: br.s IL_0012 - - IL_0010: br.s IL_004e - - .line 100001,100001 : 0,0 - IL_0012: ldarg.1 - IL_0013: unbox.any XYZ.ABC/Expr - IL_0018: ldnull - IL_0019: cgt.un - IL_001b: brfalse.s IL_001f - - IL_001d: br.s IL_0021 - - IL_001f: br.s IL_004c - - .line 100001,100001 : 0,0 - IL_0021: ldarg.0 - IL_0022: pop - .line 100001,100001 : 0,0 - IL_0023: ldarg.0 - IL_0024: stloc.1 - IL_0025: ldloc.0 - IL_0026: stloc.2 - IL_0027: ldarg.2 - IL_0028: stloc.3 - IL_0029: ldloc.1 - IL_002a: ldfld int32 XYZ.ABC/Expr::item - IL_002f: stloc.s V_4 - IL_0031: ldloc.2 - IL_0032: ldfld int32 XYZ.ABC/Expr::item - IL_0037: stloc.s V_5 - IL_0039: ldloc.s V_4 - IL_003b: ldloc.s V_5 - IL_003d: bge.s IL_0041 - - IL_003f: br.s IL_0043 - - IL_0041: br.s IL_0045 - - .line 100001,100001 : 0,0 - IL_0043: ldc.i4.m1 - IL_0044: ret - - .line 100001,100001 : 0,0 - IL_0045: ldloc.s V_4 - IL_0047: ldloc.s V_5 - IL_0049: cgt - IL_004b: ret - - .line 100001,100001 : 0,0 - IL_004c: ldc.i4.1 - IL_004d: ret - - .line 100001,100001 : 0,0 - IL_004e: ldarg.1 - IL_004f: unbox.any XYZ.ABC/Expr - IL_0054: ldnull - IL_0055: cgt.un - IL_0057: brfalse.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - - .line 100001,100001 : 0,0 - IL_005d: ldc.i4.m1 - IL_005e: ret - - .line 100001,100001 : 0,0 - IL_005f: ldc.i4.0 - IL_0060: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 46 (0x2e) - .maxstack 7 - .locals init (int32 V_0, - class XYZ.ABC/Expr V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldarg.0 - IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 - IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldc.i4 0x9e3779b9 - IL_0018: ldarg.1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld int32 XYZ.ABC/Expr::item - IL_0020: ldloc.0 - IL_0021: ldc.i4.6 - IL_0022: shl - IL_0023: ldloc.0 - IL_0024: ldc.i4.2 - IL_0025: shr - IL_0026: add - IL_0027: add - IL_0028: add - IL_0029: stloc.0 - IL_002a: ldloc.0 - IL_002b: ret - - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance int32 GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 13,13 : 14,18 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance bool Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 61 (0x3d) - .maxstack 4 - .locals init (class XYZ.ABC/Expr V_0, - class XYZ.ABC/Expr V_1, - class XYZ.ABC/Expr V_2, - class XYZ.ABC/Expr V_3, - class [mscorlib]System.Collections.IEqualityComparer V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0035 - - IL_000b: ldarg.1 - IL_000c: isinst XYZ.ABC/Expr - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0033 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldarg.0 - IL_001c: pop - IL_001d: ldarg.0 - IL_001e: stloc.2 - IL_001f: ldloc.1 - IL_0020: stloc.3 - IL_0021: ldarg.2 - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: ldfld int32 XYZ.ABC/Expr::item - IL_002a: ldloc.3 - IL_002b: ldfld int32 XYZ.ABC/Expr::item - IL_0030: ceq - IL_0032: ret - - IL_0033: ldc.i4.0 - IL_0034: ret - - IL_0035: ldarg.1 - IL_0036: ldnull - IL_0037: cgt.un - IL_0039: ldc.i4.0 - IL_003a: ceq - IL_003c: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(class XYZ.ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) - .maxstack 4 - .locals init (class XYZ.ABC/Expr V_0, - class XYZ.ABC/Expr V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_002a - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: ldfld int32 XYZ.ABC/Expr::item - IL_0021: ldloc.1 - IL_0022: ldfld int32 XYZ.ABC/Expr::item - IL_0027: ceq - IL_0029: ret - - IL_002a: ldc.i4.0 - IL_002b: ret - - IL_002c: ldarg.1 - IL_002d: ldnull - IL_002e: cgt.un - IL_0030: ldc.i4.0 - IL_0031: ceq - IL_0033: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class XYZ.ABC/Expr V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst XYZ.ABC/Expr - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.ABC/Expr::Equals(class XYZ.ABC/Expr) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method Expr::Equals - - .property instance int32 Tag() - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.ABC/Expr::get_Tag() - } // end of property Expr::Tag - .property instance int32 Item() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .get instance int32 XYZ.ABC/Expr::get_Item() - } // end of property Expr::Item - } // end of class Expr - - .class auto ansi nested public beforefieldinit MyExn - extends [mscorlib]System.Exception - implements [mscorlib]System.Collections.IStructuralEquatable - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) - .field assembly int32 Data0@ - .method public specialname rtspecialname - instance void .ctor(int32 data0) cil managed - { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.ABC/MyExn::Data0@ - IL_000d: ret - } // end of method MyExn::.ctor - - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ret - } // end of method MyExn::.ctor - - .method public hidebysig specialname - instance int32 get_Data0() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.ABC/MyExn::Data0@ - IL_0006: ret - } // end of method MyExn::get_Data0 - - .method public hidebysig virtual instance int32 - GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 45 (0x2d) - .maxstack 7 - .locals init (int32 V_0, - class [mscorlib]System.Collections.IEqualityComparer V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002b - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldc.i4 0x9e3779b9 - IL_0012: ldarg.1 - IL_0013: stloc.1 - IL_0014: ldarg.0 - IL_0015: castclass XYZ.ABC/MyExn - IL_001a: call instance int32 XYZ.ABC/MyExn::get_Data0() - IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldloc.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance int32 - GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 14,14 : 19,24 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance bool - Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0, - class [mscorlib]System.Exception V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0044 - - IL_000b: ldarg.1 - IL_000c: isinst [mscorlib]System.Exception - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0042 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_0021: brtrue.s IL_0025 - - IL_0023: br.s IL_0040 - - IL_0025: ldarg.2 - IL_0026: stloc.2 - IL_0027: ldarg.0 - IL_0028: castclass XYZ.ABC/MyExn - IL_002d: call instance int32 XYZ.ABC/MyExn::get_Data0() - IL_0032: ldloc.1 - IL_0033: castclass XYZ.ABC/MyExn - IL_0038: call instance int32 XYZ.ABC/MyExn::get_Data0() - IL_003d: ceq - IL_003f: ret - - IL_0040: ldc.i4.0 - IL_0041: ret - - IL_0042: ldc.i4.0 - IL_0043: ret - - IL_0044: ldarg.1 - IL_0045: ldnull - IL_0046: cgt.un - IL_0048: ldc.i4.0 - IL_0049: ceq - IL_004b: ret - } // end of method MyExn::Equals - - .method public hidebysig instance bool - Equals(class [mscorlib]System.Exception obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) - .maxstack 4 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_003c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_003a - - IL_0015: ldarg.1 - IL_0016: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_001b: brtrue.s IL_001f - - IL_001d: br.s IL_0038 - - IL_001f: ldarg.0 - IL_0020: castclass XYZ.ABC/MyExn - IL_0025: call instance int32 XYZ.ABC/MyExn::get_Data0() - IL_002a: ldarg.1 - IL_002b: castclass XYZ.ABC/MyExn - IL_0030: call instance int32 XYZ.ABC/MyExn::get_Data0() - IL_0035: ceq - IL_0037: ret - - IL_0038: ldc.i4.0 - IL_0039: ret - - IL_003a: ldc.i4.0 - IL_003b: ret - - IL_003c: ldarg.1 - IL_003d: ldnull - IL_003e: cgt.un - IL_0040: ldc.i4.0 - IL_0041: ceq - IL_0043: ret - } // end of method MyExn::Equals - - .method public hidebysig virtual instance bool - Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst [mscorlib]System.Exception - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.ABC/MyExn::Equals(class [mscorlib]System.Exception) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method MyExn::Equals - - .property instance int32 Data0() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.ABC/MyExn::get_Data0() - } // end of property MyExn::Data0 - } // end of class MyExn - - .class auto ansi nested public A - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .field assembly string x - .method public specialname rtspecialname - instance void .ctor(string x) cil managed - { - // Code size 17 (0x11) - .maxstack 8 - .line 15,15 : 16,17 - IL_0000: ldarg.0 - IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: pop - IL_0008: nop - IL_0009: ldarg.0 - IL_000a: ldarg.1 - IL_000b: stfld string XYZ.ABC/A::x - .line 15,15 : 14,15 - IL_0010: ret - } // end of method A::.ctor - - .method public hidebysig specialname - instance string get_X() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - .line 15,15 : 42,43 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldfld string XYZ.ABC/A::x - IL_0007: ret - } // end of method A::get_X - - .property instance string X() - { - .get instance string XYZ.ABC/A::get_X() - } // end of property A::X - } // end of class A - - .class abstract auto ansi sealed nested public ABC - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .class auto autochar sealed nested public beforefieldinit Expr - extends [mscorlib]System.Object - implements class [mscorlib]System.IEquatable`1, - [mscorlib]System.Collections.IStructuralEquatable, - class [mscorlib]System.IComparable`1, - [mscorlib]System.IComparable, - [mscorlib]System.Collections.IStructuralComparable - { - .custom instance void [mscorlib]System.Diagnostics.DebuggerDisplayAttribute::.ctor(string) = ( 01 00 15 7B 5F 5F 44 65 62 75 67 44 69 73 70 6C // ...{__DebugDispl - 61 79 28 29 2C 6E 71 7D 00 00 ) // ay(),nq}.. - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 01 00 00 00 00 00 ) - .field assembly initonly int32 item - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static class XYZ.ABC/ABC/Expr - NewNum(int32 item) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: newobj instance void XYZ.ABC/ABC/Expr::.ctor(int32) - IL_0006: ret - } // end of method Expr::NewNum - - .method assembly specialname rtspecialname - instance void .ctor(int32 item) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.ABC/ABC/Expr::item - IL_000d: ret - } // end of method Expr::.ctor - - .method public hidebysig instance int32 - get_Item() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0006: ret - } // end of method Expr::get_Item - - .method public hidebysig instance int32 - get_Tag() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 4 (0x4) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: pop - IL_0002: ldc.i4.0 - IL_0003: ret - } // end of method Expr::get_Tag - - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%+0.8A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::__DebugDisplay - - .method public strict virtual instance string - ToString() cil managed - { - // Code size 22 (0x16) - .maxstack 8 - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,string>::.ctor(string) - IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_000f: ldarg.0 - IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0015: ret - } // end of method Expr::ToString - - .method public hidebysig virtual final - instance int32 CompareTo(class XYZ.ABC/ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) - .maxstack 4 - .locals init (class XYZ.ABC/ABC/Expr V_0, - class XYZ.ABC/ABC/Expr V_1, - class [mscorlib]System.Collections.IComparer V_2, - int32 V_3, - int32 V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0043 - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_0041 - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0020: stloc.2 - IL_0021: ldloc.0 - IL_0022: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0027: stloc.3 - IL_0028: ldloc.1 - IL_0029: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_002e: stloc.s V_4 - IL_0030: ldloc.3 - IL_0031: ldloc.s V_4 - IL_0033: bge.s IL_0037 - - IL_0035: br.s IL_0039 - - IL_0037: br.s IL_003b - - IL_0039: ldc.i4.m1 - IL_003a: ret - - IL_003b: ldloc.3 - IL_003c: ldloc.s V_4 - IL_003e: cgt - IL_0040: ret - - IL_0041: ldc.i4.1 - IL_0042: ret - - IL_0043: ldarg.1 - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d - - IL_004b: br.s IL_004f - - IL_004d: ldc.i4.m1 - IL_004e: ret - - IL_004f: ldc.i4.0 - IL_0050: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 14 (0xe) - .maxstack 8 - .line 23,23 : 18,22 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: unbox.any XYZ.ABC/ABC/Expr - IL_0008: callvirt instance int32 XYZ.ABC/ABC/Expr::CompareTo(class XYZ.ABC/ABC/Expr) - IL_000d: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [mscorlib]System.Collections.IComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 97 (0x61) - .maxstack 4 - .locals init ([0] class XYZ.ABC/ABC/Expr V_0, - [1] class XYZ.ABC/ABC/Expr V_1, - [2] class XYZ.ABC/ABC/Expr V_2, - [3] class [mscorlib]System.Collections.IComparer V_3, - [4] int32 V_4, - [5] int32 V_5) - .line 23,23 : 18,22 - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: unbox.any XYZ.ABC/ABC/Expr - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: ldnull - IL_000a: cgt.un - IL_000c: brfalse.s IL_0010 - - IL_000e: br.s IL_0012 - - IL_0010: br.s IL_004e - - .line 100001,100001 : 0,0 - IL_0012: ldarg.1 - IL_0013: unbox.any XYZ.ABC/ABC/Expr - IL_0018: ldnull - IL_0019: cgt.un - IL_001b: brfalse.s IL_001f - - IL_001d: br.s IL_0021 - - IL_001f: br.s IL_004c - - .line 100001,100001 : 0,0 - IL_0021: ldarg.0 - IL_0022: pop - .line 100001,100001 : 0,0 - IL_0023: ldarg.0 - IL_0024: stloc.1 - IL_0025: ldloc.0 - IL_0026: stloc.2 - IL_0027: ldarg.2 - IL_0028: stloc.3 - IL_0029: ldloc.1 - IL_002a: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_002f: stloc.s V_4 - IL_0031: ldloc.2 - IL_0032: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0037: stloc.s V_5 - IL_0039: ldloc.s V_4 - IL_003b: ldloc.s V_5 - IL_003d: bge.s IL_0041 - - IL_003f: br.s IL_0043 - - IL_0041: br.s IL_0045 - - .line 100001,100001 : 0,0 - IL_0043: ldc.i4.m1 - IL_0044: ret - - .line 100001,100001 : 0,0 - IL_0045: ldloc.s V_4 - IL_0047: ldloc.s V_5 - IL_0049: cgt - IL_004b: ret - - .line 100001,100001 : 0,0 - IL_004c: ldc.i4.1 - IL_004d: ret - - .line 100001,100001 : 0,0 - IL_004e: ldarg.1 - IL_004f: unbox.any XYZ.ABC/ABC/Expr - IL_0054: ldnull - IL_0055: cgt.un - IL_0057: brfalse.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - - .line 100001,100001 : 0,0 - IL_005d: ldc.i4.m1 - IL_005e: ret - - .line 100001,100001 : 0,0 - IL_005f: ldc.i4.0 - IL_0060: ret - } // end of method Expr::CompareTo - - .method public hidebysig virtual final - instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 46 (0x2e) - .maxstack 7 - .locals init (int32 V_0, - class XYZ.ABC/ABC/Expr V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldarg.0 - IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 - IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldc.i4 0x9e3779b9 - IL_0018: ldarg.1 - IL_0019: stloc.2 - IL_001a: ldloc.1 - IL_001b: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0020: ldloc.0 - IL_0021: ldc.i4.6 - IL_0022: shl - IL_0023: ldloc.0 - IL_0024: ldc.i4.2 - IL_0025: shr - IL_0026: add - IL_0027: add - IL_0028: add - IL_0029: stloc.0 - IL_002a: ldloc.0 - IL_002b: ret - - IL_002c: ldc.i4.0 - IL_002d: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance int32 GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 23,23 : 18,22 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.ABC/ABC/Expr::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method Expr::GetHashCode - - .method public hidebysig virtual final - instance bool Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 61 (0x3d) - .maxstack 4 - .locals init (class XYZ.ABC/ABC/Expr V_0, - class XYZ.ABC/ABC/Expr V_1, - class XYZ.ABC/ABC/Expr V_2, - class XYZ.ABC/ABC/Expr V_3, - class [mscorlib]System.Collections.IEqualityComparer V_4) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0035 - - IL_000b: ldarg.1 - IL_000c: isinst XYZ.ABC/ABC/Expr - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0033 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldarg.0 - IL_001c: pop - IL_001d: ldarg.0 - IL_001e: stloc.2 - IL_001f: ldloc.1 - IL_0020: stloc.3 - IL_0021: ldarg.2 - IL_0022: stloc.s V_4 - IL_0024: ldloc.2 - IL_0025: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_002a: ldloc.3 - IL_002b: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0030: ceq - IL_0032: ret - - IL_0033: ldc.i4.0 - IL_0034: ret - - IL_0035: ldarg.1 - IL_0036: ldnull - IL_0037: cgt.un - IL_0039: ldc.i4.0 - IL_003a: ceq - IL_003c: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(class XYZ.ABC/ABC/Expr obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) - .maxstack 4 - .locals init (class XYZ.ABC/ABC/Expr V_0, - class XYZ.ABC/ABC/Expr V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_002a - - IL_0015: ldarg.0 - IL_0016: pop - IL_0017: ldarg.0 - IL_0018: stloc.0 - IL_0019: ldarg.1 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0021: ldloc.1 - IL_0022: ldfld int32 XYZ.ABC/ABC/Expr::item - IL_0027: ceq - IL_0029: ret - - IL_002a: ldc.i4.0 - IL_002b: ret - - IL_002c: ldarg.1 - IL_002d: ldnull - IL_002e: cgt.un - IL_0030: ldc.i4.0 - IL_0031: ceq - IL_0033: ret - } // end of method Expr::Equals - - .method public hidebysig virtual final - instance bool Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class XYZ.ABC/ABC/Expr V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst XYZ.ABC/ABC/Expr - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.ABC/ABC/Expr::Equals(class XYZ.ABC/ABC/Expr) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method Expr::Equals - - .property instance int32 Tag() - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.ABC/ABC/Expr::get_Tag() - } // end of property Expr::Tag - .property instance int32 Item() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .get instance int32 XYZ.ABC/ABC/Expr::get_Item() - } // end of property Expr::Item - } // end of class Expr - - .class auto ansi nested public beforefieldinit MyExn - extends [mscorlib]System.Exception - implements [mscorlib]System.Collections.IStructuralEquatable - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 05 00 00 00 00 00 ) - .field assembly int32 Data0@ - .method public specialname rtspecialname - instance void .ctor(int32 data0) cil managed - { - // Code size 14 (0xe) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ldarg.0 - IL_0007: ldarg.1 - IL_0008: stfld int32 XYZ.ABC/ABC/MyExn::Data0@ - IL_000d: ret - } // end of method MyExn::.ctor - - .method public specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Exception::.ctor() - IL_0006: ret - } // end of method MyExn::.ctor - - .method public hidebysig specialname - instance int32 get_Data0() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: ldfld int32 XYZ.ABC/ABC/MyExn::Data0@ - IL_0006: ret - } // end of method MyExn::get_Data0 - - .method public hidebysig virtual instance int32 - GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 45 (0x2d) - .maxstack 7 - .locals init (int32 V_0, - class [mscorlib]System.Collections.IEqualityComparer V_1) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_002b - - IL_000b: ldc.i4.0 - IL_000c: stloc.0 - IL_000d: ldc.i4 0x9e3779b9 - IL_0012: ldarg.1 - IL_0013: stloc.1 - IL_0014: ldarg.0 - IL_0015: castclass XYZ.ABC/ABC/MyExn - IL_001a: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldloc.0 - IL_002a: ret - - IL_002b: ldc.i4.0 - IL_002c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance int32 - GetHashCode() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 8 - .line 24,24 : 23,28 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: callvirt instance int32 XYZ.ABC/ABC/MyExn::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_000c: ret - } // end of method MyExn::GetHashCode - - .method public hidebysig virtual instance bool - Equals(object obj, - class [mscorlib]System.Collections.IEqualityComparer comp) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0, - class [mscorlib]System.Exception V_1, - class [mscorlib]System.Collections.IEqualityComparer V_2) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0044 - - IL_000b: ldarg.1 - IL_000c: isinst [mscorlib]System.Exception - IL_0011: stloc.0 - IL_0012: ldloc.0 - IL_0013: brfalse.s IL_0017 - - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0042 - - IL_0019: ldloc.0 - IL_001a: stloc.1 - IL_001b: ldloc.0 - IL_001c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_0021: brtrue.s IL_0025 - - IL_0023: br.s IL_0040 - - IL_0025: ldarg.2 - IL_0026: stloc.2 - IL_0027: ldarg.0 - IL_0028: castclass XYZ.ABC/ABC/MyExn - IL_002d: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - IL_0032: ldloc.1 - IL_0033: castclass XYZ.ABC/ABC/MyExn - IL_0038: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - IL_003d: ceq - IL_003f: ret - - IL_0040: ldc.i4.0 - IL_0041: ret - - IL_0042: ldc.i4.0 - IL_0043: ret - - IL_0044: ldarg.1 - IL_0045: ldnull - IL_0046: cgt.un - IL_0048: ldc.i4.0 - IL_0049: ceq - IL_004b: ret - } // end of method MyExn::Equals - - .method public hidebysig instance bool - Equals(class [mscorlib]System.Exception obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) - .maxstack 4 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldnull - IL_0003: cgt.un - IL_0005: brfalse.s IL_0009 - - IL_0007: br.s IL_000b - - IL_0009: br.s IL_003c - - IL_000b: ldarg.1 - IL_000c: ldnull - IL_000d: cgt.un - IL_000f: brfalse.s IL_0013 - - IL_0011: br.s IL_0015 - - IL_0013: br.s IL_003a - - IL_0015: ldarg.1 - IL_0016: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) - IL_001b: brtrue.s IL_001f - - IL_001d: br.s IL_0038 - - IL_001f: ldarg.0 - IL_0020: castclass XYZ.ABC/ABC/MyExn - IL_0025: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - IL_002a: ldarg.1 - IL_002b: castclass XYZ.ABC/ABC/MyExn - IL_0030: call instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - IL_0035: ceq - IL_0037: ret - - IL_0038: ldc.i4.0 - IL_0039: ret - - IL_003a: ldc.i4.0 - IL_003b: ret - - IL_003c: ldarg.1 - IL_003d: ldnull - IL_003e: cgt.un - IL_0040: ldc.i4.0 - IL_0041: ceq - IL_0043: ret - } // end of method MyExn::Equals - - .method public hidebysig virtual instance bool - Equals(object obj) cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 25 (0x19) - .maxstack 4 - .locals init (class [mscorlib]System.Exception V_0) - IL_0000: nop - IL_0001: ldarg.1 - IL_0002: isinst [mscorlib]System.Exception - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_0017 - - IL_000f: ldarg.0 - IL_0010: ldloc.0 - IL_0011: callvirt instance bool XYZ.ABC/ABC/MyExn::Equals(class [mscorlib]System.Exception) - IL_0016: ret - - IL_0017: ldc.i4.0 - IL_0018: ret - } // end of method MyExn::Equals - - .property instance int32 Data0() - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, - int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 ) - .get instance int32 XYZ.ABC/ABC/MyExn::get_Data0() - } // end of property MyExn::Data0 - } // end of class MyExn - - .class auto ansi nested public A - extends [mscorlib]System.Object - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .field assembly string x - .method public specialname rtspecialname - instance void .ctor(string x) cil managed - { - // Code size 17 (0x11) - .maxstack 8 - .line 25,25 : 20,21 - IL_0000: ldarg.0 - IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() - IL_0006: ldarg.0 - IL_0007: pop - IL_0008: nop - IL_0009: ldarg.0 - IL_000a: ldarg.1 - IL_000b: stfld string XYZ.ABC/ABC/A::x - .line 25,25 : 18,19 - IL_0010: ret - } // end of method A::.ctor - - .method public hidebysig specialname - instance string get_X() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - .line 25,25 : 46,47 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldfld string XYZ.ABC/ABC/A::x - IL_0007: ret - } // end of method A::get_X - - .property instance string X() - { - .get instance string XYZ.ABC/ABC/A::get_X() - } // end of property A::X - } // end of class A - - .method public static int32 'add'(int32 x, - int32 y) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 5 (0x5) - .maxstack 8 - .line 28,28 : 27,32 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: add - IL_0004: ret - } // end of method ABC::'add' - - .method public specialname static string - get_greeting() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: nop - IL_0001: ldstr "hello" - IL_0006: ret - } // end of method ABC::get_greeting - - .property string greeting() - { - .get string XYZ.ABC/ABC::get_greeting() - } // end of property ABC::greeting - } // end of class ABC - - .method public static int32 'add'(int32 x, - int32 y) cil managed - { - .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 5 (0x5) - .maxstack 8 - .line 18,18 : 23,28 - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldarg.1 - IL_0003: add - IL_0004: ret - } // end of method ABC::'add' - - .method public specialname static string - get_greeting() cil managed - { - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 7 (0x7) - .maxstack 8 - IL_0000: nop - IL_0001: ldstr "hello" - IL_0006: ret - } // end of method ABC::get_greeting - - .property string greeting() - { - .get string XYZ.ABC::get_greeting() - } // end of property ABC::greeting -} // end of class XYZ.ABC - -.class private abstract auto ansi sealed ''.$ToplevelNamespace - extends [mscorlib]System.Object -{ - .field static assembly int32 init@ - .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method private specialname rtspecialname static - void .cctor() cil managed - { - // Code size 14 (0xe) - .maxstack 3 - .locals init ([0] string greeting, - [1] string V_1) - .line 19,19 : 9,31 '' - IL_0000: nop - IL_0001: call string XYZ.ABC::get_greeting() - IL_0006: stloc.0 - .line 29,29 : 13,35 '' - IL_0007: call string XYZ.ABC/ABC::get_greeting() - IL_000c: stloc.1 - IL_000d: ret - } // end of method $ToplevelNamespace::.cctor -} // end of class ''.$ToplevelNamespace - - -// ============================================================= - -// *********** DISASSEMBLY COMPLETE *********************** diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/env.lst b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/env.lst index 3a3631b97e8..02b9c03bb30 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/env.lst +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/env.lst @@ -1,5 +1,5 @@ - SOURCE=ToplevelModule.fs SCFLAGS="-a -g --out:desktop\\TopLevelModule.dll --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd ToplevelModule.dll NetFx20 desktop" # ToplevelModule.fs - Desktop - SOURCE=ToplevelNamespace.fs SCFLAGS="-a -g --out:desktop\\ToplevelNamespace.dll --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd ToplevelNamespace.dll NetFx20 desktop" # ToplevelNamespace.fs - Desktop + SOURCE=ToplevelModule.fs SCFLAGS="-a -g --out:TopLevelModule.dll --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd ToplevelModule.dll" # ToplevelModule.fs - Desktop + SOURCE=ToplevelNamespace.fs SCFLAGS="-a -g --out:ToplevelNamespace.dll --test:EmitFeeFeeAs100001 --optimize-" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd ToplevelNamespace.dll" # ToplevelNamespace.fs - Desktop diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/LetBinding01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/LetBinding01.il.bsl index c29de0c7bdc..849857520b5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/LetBinding01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/LetBinding01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly LetBinding01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.LetBinding01 { - // Offset: 0x00000000 Length: 0x000001B4 + // Offset: 0x00000000 Length: 0x000001B0 } .mresource public FSharpOptimizationData.LetBinding01 { // Offset: 0x000001B8 Length: 0x00000070 } .module LetBinding01.exe -// MVID: {59B19250-269D-BEEF-A745-03835092B159} +// MVID: {608C050A-269D-BEEF-A745-03830A058C60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01570000 +// Image base: 0x066B0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -79,25 +79,20 @@ .method public static void main@() cil managed { .entrypoint - // Code size 37 (0x25) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_0) + // Code size 33 (0x21) + .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 1,11 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\StaticInit\\LetBinding01.fs' + .line 5,5 : 1,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\StaticInit\\LetBinding01.fs' IL_0000: call class [FSharp.Core]Microsoft.FSharp.Core.Unit LetBinding01::get_x() IL_0005: pop .line 6,6 : 1,17 '' IL_0006: ldstr "x = %A" IL_000b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string) IL_0010: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0015: stloc.0 - IL_0016: call class [FSharp.Core]Microsoft.FSharp.Core.Unit LetBinding01::get_x() - IL_001b: pop - IL_001c: ldloc.0 - IL_001d: ldnull - IL_001e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0023: pop - IL_0024: ret + IL_0015: call class [FSharp.Core]Microsoft.FSharp.Core.Unit LetBinding01::get_x() + IL_001a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001f: pop + IL_0020: ret } // end of method $LetBinding01::main@ } // end of class ''.$LetBinding01 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Class01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Class01.il.bsl index 2dd345fe2d4..d65cdab3db2 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Class01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Class01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly StaticInit_Class01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.StaticInit_Class01 { - // Offset: 0x00000000 Length: 0x00000335 + // Offset: 0x00000000 Length: 0x0000032F } .mresource public FSharpOptimizationData.StaticInit_Class01 { - // Offset: 0x00000340 Length: 0x000000AD + // Offset: 0x00000338 Length: 0x000000AD } .module StaticInit_Class01.dll -// MVID: {59B19250-EC34-E66E-A745-03835092B159} +// MVID: {611C4D99-EC34-E66E-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00FE0000 +// Image base: 0x06F20000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,14 +56,14 @@ { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) .field static assembly int32 x - .field static assembly int32 'init@4-1' + .field static assembly int32 init@4 .method public specialname rtspecialname instance void .ctor(valuetype [mscorlib]System.DateTime s) cil managed { // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Class01.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Class01.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 @@ -75,32 +75,30 @@ .method assembly static int32 f() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 41 (0x29) + // Code size 38 (0x26) .maxstack 8 .line 7,7 : 23,37 '' - IL_0000: volatile. - IL_0002: ldsfld int32 StaticInit_ClassS01/C::'init@4-1' - IL_0007: ldc.i4.1 - IL_0008: bge.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0017 + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: volatile. + IL_0003: ldsfld int32 StaticInit_ClassS01/C::init@4 + IL_0008: ldc.i4.1 + IL_0009: bge.s IL_0014 .line 100001,100001 : 0,0 '' - IL_000e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() - IL_0013: nop + IL_000b: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_0010: nop .line 100001,100001 : 0,0 '' - IL_0014: nop - IL_0015: br.s IL_0018 + IL_0011: nop + IL_0012: br.s IL_0015 .line 100001,100001 : 0,0 '' - IL_0017: nop - IL_0018: ldsfld int32 StaticInit_ClassS01/C::x - IL_001d: ldstr "2" - IL_0022: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_0027: add - IL_0028: ret + IL_0014: nop + IL_0015: ldsfld int32 StaticInit_ClassS01/C::x + IL_001a: ldstr "2" + IL_001f: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_0024: add + IL_0025: ret } // end of method C::f .method private specialname rtspecialname static @@ -138,7 +136,7 @@ IL_000a: stsfld int32 StaticInit_ClassS01/C::x IL_000f: ldc.i4.1 IL_0010: volatile. - IL_0012: stsfld int32 StaticInit_ClassS01/C::'init@4-1' + IL_0012: stsfld int32 StaticInit_ClassS01/C::init@4 .line 4,4 : 6,7 '' IL_0017: ret } // end of method $StaticInit_ClassS01::.cctor diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.il.bsl index c9cd745c46a..bbe78bc0de6 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly StaticInit_Module01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.StaticInit_Module01 { - // Offset: 0x00000000 Length: 0x000002A7 + // Offset: 0x00000000 Length: 0x000002A3 } .mresource public FSharpOptimizationData.StaticInit_Module01 { - // Offset: 0x000002B0 Length: 0x000000DF + // Offset: 0x000002A8 Length: 0x000000DF } .module StaticInit_Module01.dll -// MVID: {59B19250-705F-DF4F-A745-03835092B159} +// MVID: {60B68B90-705F-DF4F-A745-0383908BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00370000 +// Image base: 0x050C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -94,7 +94,7 @@ { // Code size 6 (0x6) .maxstack 8 - IL_0000: ldsfld int32 ''.$StaticInit_Module01::'x@5-1' + IL_0000: ldsfld int32 ''.$StaticInit_Module01::x@5 IL_0005: ret } // end of method M::get_x @@ -110,7 +110,7 @@ .class private abstract auto ansi sealed ''.$StaticInit_Module01 extends [mscorlib]System.Object { - .field static assembly initonly int32 'x@5-1' + .field static assembly initonly int32 x@5 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .field static assembly initonly int32 y@7 .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) @@ -129,11 +129,11 @@ [1] int32 y, [2] int32 z) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 3,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Module01.fs' + .line 5,5 : 3,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Module01.fs' IL_0000: ldstr "1" IL_0005: callvirt instance int32 [mscorlib]System.String::get_Length() IL_000a: dup - IL_000b: stsfld int32 ''.$StaticInit_Module01::'x@5-1' + IL_000b: stsfld int32 ''.$StaticInit_Module01::x@5 IL_0010: stloc.0 .line 7,7 : 5,27 '' IL_0011: call int32 StaticInit_Module01/M::get_x() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Struct01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Struct01.il.bsl index 55664ad8b3a..589b435e0d9 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Struct01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Struct01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly StaticInit_Struct01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.StaticInit_Struct01 { - // Offset: 0x00000000 Length: 0x000007B1 + // Offset: 0x00000000 Length: 0x000007A1 } .mresource public FSharpOptimizationData.StaticInit_Struct01 { - // Offset: 0x000007B8 Length: 0x0000021F + // Offset: 0x000007A8 Length: 0x0000021F } .module StaticInit_Struct01.dll -// MVID: {59B19250-05F6-D6CB-A745-03835092B159} +// MVID: {611C52B1-05F6-D6CB-A745-0383B1521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02BA0000 +// Image base: 0x06550000 // =============== CLASS MEMBERS DECLARATION =================== @@ -67,23 +72,23 @@ instance int32 CompareTo(valuetype StaticInit_Struct01/C obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 28 (0x1c) - .maxstack 5 - .locals init ([0] valuetype StaticInit_Struct01/C& V_0) + // Code size 27 (0x1b) + .maxstack 4 + .locals init ([0] valuetype StaticInit_Struct01/C& V_0, + [1] class [mscorlib]System.Collections.IComparer V_1) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 6,7 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Struct01.fs' + .line 4,4 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\StaticInit\\StaticInit_Struct01.fs' IL_0000: ldarga.s obj IL_0002: stloc.0 IL_0003: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0008: ldarg.0 - IL_0009: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_000e: ldloc.0 - IL_000f: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_0014: tail. - IL_0016: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, - !!0, - !!0) - IL_001b: ret + IL_0008: stloc.1 + IL_0009: ldarg.0 + IL_000a: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_000f: ldloc.0 + IL_0010: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_0015: call int32 [netstandard]System.DateTime::Compare(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_001a: ret } // end of method C::CompareTo .method public hidebysig virtual final @@ -105,10 +110,11 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 31 (0x1f) - .maxstack 5 + // Code size 30 (0x1e) + .maxstack 4 .locals init ([0] valuetype StaticInit_Struct01/C V_0, - [1] valuetype StaticInit_Struct01/C& V_1) + [1] valuetype StaticInit_Struct01/C& V_1, + [2] class [mscorlib]System.Collections.IComparer V_2) .line 4,4 : 6,7 '' IL_0000: ldarg.1 IL_0001: unbox.any StaticInit_Struct01/C @@ -116,15 +122,14 @@ IL_0007: ldloca.s V_0 IL_0009: stloc.1 IL_000a: ldarg.2 - IL_000b: ldarg.0 - IL_000c: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_0011: ldloc.1 - IL_0012: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_0017: tail. - IL_0019: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, - !!0, - !!0) - IL_001e: ret + IL_000b: stloc.2 + IL_000c: ldarg.0 + IL_000d: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_0012: ldloc.1 + IL_0013: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_0018: call int32 [netstandard]System.DateTime::Compare(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_001d: ret } // end of method C::CompareTo .method public hidebysig virtual final @@ -175,16 +180,17 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 43 (0x2b) - .maxstack 5 + // Code size 42 (0x2a) + .maxstack 4 .locals init ([0] valuetype StaticInit_Struct01/C V_0, - [1] valuetype StaticInit_Struct01/C& V_1) + [1] valuetype StaticInit_Struct01/C& V_1, + [2] class [mscorlib]System.Collections.IEqualityComparer V_2) .line 100001,100001 : 0,0 '' IL_0000: ldarg.1 IL_0001: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) IL_0006: brtrue.s IL_000a - IL_0008: br.s IL_0029 + IL_0008: br.s IL_0028 .line 100001,100001 : 0,0 '' IL_000a: ldarg.1 @@ -193,19 +199,18 @@ IL_0011: ldloca.s V_0 IL_0013: stloc.1 IL_0014: ldarg.2 - IL_0015: ldarg.0 - IL_0016: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_001b: ldloc.1 - IL_001c: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_0021: tail. - IL_0023: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, - !!0, - !!0) - IL_0028: ret + IL_0015: stloc.2 + IL_0016: ldarg.0 + IL_0017: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_001c: ldloc.1 + IL_001d: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s + IL_0022: call bool [netstandard]System.DateTime::Equals(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_0027: ret .line 100001,100001 : 0,0 '' - IL_0029: ldc.i4.0 - IL_002a: ret + IL_0028: ldc.i4.0 + IL_0029: ret } // end of method C::Equals .method public specialname rtspecialname @@ -224,39 +229,37 @@ .method assembly static int32 f() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 41 (0x29) + // Code size 38 (0x26) .maxstack 8 .line 7,7 : 23,37 '' - IL_0000: volatile. - IL_0002: ldsfld int32 StaticInit_Struct01/C::init@4 - IL_0007: ldc.i4.1 - IL_0008: bge.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0017 + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: volatile. + IL_0003: ldsfld int32 StaticInit_Struct01/C::init@4 + IL_0008: ldc.i4.1 + IL_0009: bge.s IL_0014 .line 100001,100001 : 0,0 '' - IL_000e: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() - IL_0013: nop + IL_000b: call void [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::FailStaticInit() + IL_0010: nop .line 100001,100001 : 0,0 '' - IL_0014: nop - IL_0015: br.s IL_0018 + IL_0011: nop + IL_0012: br.s IL_0015 .line 100001,100001 : 0,0 '' - IL_0017: nop - IL_0018: ldsfld int32 StaticInit_Struct01/C::x - IL_001d: ldstr "2" - IL_0022: callvirt instance int32 [mscorlib]System.String::get_Length() - IL_0027: add - IL_0028: ret + IL_0014: nop + IL_0015: ldsfld int32 StaticInit_Struct01/C::x + IL_001a: ldstr "2" + IL_001f: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_0024: add + IL_0025: ret } // end of method C::f .method public hidebysig virtual final instance bool Equals(valuetype StaticInit_Struct01/C obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 23 (0x17) + // Code size 21 (0x15) .maxstack 4 .locals init ([0] valuetype StaticInit_Struct01/C& V_0) .line 4,4 : 6,7 '' @@ -266,10 +269,9 @@ IL_0004: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s IL_0009: ldloc.0 IL_000a: ldfld valuetype [mscorlib]System.DateTime StaticInit_Struct01/C::s - IL_000f: tail. - IL_0011: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, - !!0) - IL_0016: ret + IL_000f: call bool [netstandard]System.DateTime::Equals(valuetype [netstandard]System.DateTime, + valuetype [netstandard]System.DateTime) + IL_0014: ret } // end of method C::Equals .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch01.il.bsl index aa77b1c7e0e..090ace0a0d5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch01 { - // Offset: 0x00000000 Length: 0x0000021C + // Offset: 0x00000000 Length: 0x00000210 } .mresource public FSharpOptimizationData.SteppingMatch01 { - // Offset: 0x00000220 Length: 0x0000007A + // Offset: 0x00000218 Length: 0x0000007A } .module SteppingMatch01.dll -// MVID: {59B19213-ABFD-13F6-A745-03831392B159} +// MVID: {611C4D99-ABFD-13F6-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00CA0000 +// Image base: 0x05320000 // =============== CLASS MEMBERS DECLARATION =================== @@ -59,15 +59,17 @@ [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2 V_1, [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice1Of2 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch01.fs' + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch01.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice1Of2 IL_0008: brfalse.s IL_000c IL_000a: br.s IL_001e + .line 100001,100001 : 0,0 '' IL_000c: ldloc.0 IL_000d: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2 IL_0012: stloc.1 @@ -76,7 +78,7 @@ IL_0018: call void [mscorlib]System.Console::WriteLine(string) IL_001d: ret - .line 5,5 : 9,21 '' + .line 100001,100001 : 0,0 '' IL_001e: ldloc.0 IL_001f: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice1Of2 IL_0024: stloc.2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch02.il.bsl index 453261211ee..d29ae57f651 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch02 { - // Offset: 0x00000000 Length: 0x0000021C + // Offset: 0x00000000 Length: 0x00000210 } .mresource public FSharpOptimizationData.SteppingMatch02 { - // Offset: 0x00000220 Length: 0x0000007A + // Offset: 0x00000218 Length: 0x0000007A } .module SteppingMatch02.dll -// MVID: {59B19213-CAC2-C63D-A745-03831392B159} +// MVID: {611C4D99-CAC2-C63D-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01090000 +// Image base: 0x06CD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -59,15 +59,17 @@ [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice1Of2 V_1, [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch02.fs' + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch02.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2 IL_0008: brfalse.s IL_000c IL_000a: br.s IL_001e + .line 100001,100001 : 0,0 '' IL_000c: ldloc.0 IL_000d: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice1Of2 IL_0012: stloc.1 @@ -76,7 +78,7 @@ IL_0018: call void [mscorlib]System.Console::WriteLine(string) IL_001d: ret - .line 5,5 : 9,21 '' + .line 100001,100001 : 0,0 '' IL_001e: ldloc.0 IL_001f: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2/Choice2Of2 IL_0024: stloc.2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch03.il.bsl index f2ced1b23d2..224265a3987 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch03 { - // Offset: 0x00000000 Length: 0x00000231 + // Offset: 0x00000000 Length: 0x00000225 } .mresource public FSharpOptimizationData.SteppingMatch03 { - // Offset: 0x00000238 Length: 0x0000007A + // Offset: 0x00000230 Length: 0x0000007A } .module SteppingMatch03.dll -// MVID: {59B19213-4E87-D110-A745-03831392B159} +// MVID: {611C4D99-4E87-D110-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00D00000 +// Image base: 0x06F80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void funcC(class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 n) cil managed { - // Code size 81 (0x51) + // Code size 75 (0x4b) .maxstack 3 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_1, @@ -61,50 +61,46 @@ [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 V_3, [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 V_4) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch03.fs' + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch03.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: stloc.1 IL_0004: ldloc.1 IL_0005: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 - IL_000a: brtrue.s IL_0016 + IL_000a: brtrue.s IL_0026 IL_000c: ldloc.1 IL_000d: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 - IL_0012: brtrue.s IL_0018 + IL_0012: brtrue.s IL_0038 - IL_0014: br.s IL_001a - - IL_0016: br.s IL_002c - - IL_0018: br.s IL_003e - - IL_001a: ldloc.0 - IL_001b: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 - IL_0020: stloc.2 + .line 100001,100001 : 0,0 '' + IL_0014: ldloc.0 + IL_0015: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 + IL_001a: stloc.2 .line 7,7 : 13,35 '' - IL_0021: ldstr "A" - IL_0026: call void [mscorlib]System.Console::WriteLine(string) - IL_002b: ret - - .line 5,5 : 9,21 '' - IL_002c: ldloc.0 - IL_002d: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 - IL_0032: stloc.3 + IL_001b: ldstr "A" + IL_0020: call void [mscorlib]System.Console::WriteLine(string) + IL_0025: ret + + .line 100001,100001 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 + IL_002c: stloc.3 .line 9,9 : 13,35 '' - IL_0033: ldstr "B" - IL_0038: call void [mscorlib]System.Console::WriteLine(string) - IL_003d: ret - - .line 5,5 : 9,21 '' - IL_003e: ldloc.0 - IL_003f: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 - IL_0044: stloc.s V_4 + IL_002d: ldstr "B" + IL_0032: call void [mscorlib]System.Console::WriteLine(string) + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.0 + IL_0039: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 + IL_003e: stloc.s V_4 .line 11,11 : 13,35 '' - IL_0046: ldstr "C" - IL_004b: call void [mscorlib]System.Console::WriteLine(string) - IL_0050: ret + IL_0040: ldstr "C" + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: ret } // end of method SteppingMatch03::funcC } // end of class SteppingMatch03 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch04.il.bsl index dc909634a1a..b1afa2fc791 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch04 { - // Offset: 0x00000000 Length: 0x00000232 + // Offset: 0x00000000 Length: 0x00000226 } .mresource public FSharpOptimizationData.SteppingMatch04 { - // Offset: 0x00000238 Length: 0x0000007B + // Offset: 0x00000230 Length: 0x0000007B } .module SteppingMatch04.dll -// MVID: {59B19213-6D4C-8357-A745-03831392B159} +// MVID: {611C4D99-6D4C-8357-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02770000 +// Image base: 0x06E30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void funcC2(class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 n) cil managed { - // Code size 81 (0x51) + // Code size 75 (0x4b) .maxstack 3 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_1, @@ -61,50 +61,46 @@ [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 V_3, [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 V_4) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch04.fs' + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch04.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: stloc.1 IL_0004: ldloc.1 IL_0005: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 - IL_000a: brtrue.s IL_0016 + IL_000a: brtrue.s IL_0026 IL_000c: ldloc.1 IL_000d: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 - IL_0012: brtrue.s IL_0018 + IL_0012: brtrue.s IL_0038 - IL_0014: br.s IL_001a - - IL_0016: br.s IL_002c - - IL_0018: br.s IL_003e - - IL_001a: ldloc.0 - IL_001b: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 - IL_0020: stloc.2 + .line 100001,100001 : 0,0 '' + IL_0014: ldloc.0 + IL_0015: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 + IL_001a: stloc.2 .line 7,7 : 13,35 '' - IL_0021: ldstr "B" - IL_0026: call void [mscorlib]System.Console::WriteLine(string) - IL_002b: ret - - .line 5,5 : 9,21 '' - IL_002c: ldloc.0 - IL_002d: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 - IL_0032: stloc.3 + IL_001b: ldstr "B" + IL_0020: call void [mscorlib]System.Console::WriteLine(string) + IL_0025: ret + + .line 100001,100001 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 + IL_002c: stloc.3 .line 9,9 : 13,35 '' - IL_0033: ldstr "C" - IL_0038: call void [mscorlib]System.Console::WriteLine(string) - IL_003d: ret - - .line 5,5 : 9,21 '' - IL_003e: ldloc.0 - IL_003f: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 - IL_0044: stloc.s V_4 + IL_002d: ldstr "C" + IL_0032: call void [mscorlib]System.Console::WriteLine(string) + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.0 + IL_0039: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 + IL_003e: stloc.s V_4 .line 11,11 : 13,35 '' - IL_0046: ldstr "A" - IL_004b: call void [mscorlib]System.Console::WriteLine(string) - IL_0050: ret + IL_0040: ldstr "A" + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: ret } // end of method SteppingMatch04::funcC2 } // end of class SteppingMatch04 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch05.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch05.il.bsl index 8da1f763ae7..948bd3d9f92 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch05.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch05 { - // Offset: 0x00000000 Length: 0x00000232 + // Offset: 0x00000000 Length: 0x00000226 } .mresource public FSharpOptimizationData.SteppingMatch05 { - // Offset: 0x00000238 Length: 0x0000007B + // Offset: 0x00000230 Length: 0x0000007B } .module SteppingMatch05.dll -// MVID: {59B19213-30E9-4ADA-A745-03831392B159} +// MVID: {611C4D99-30E9-4ADA-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02FF0000 +// Image base: 0x064D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void funcC3(class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 n) cil managed { - // Code size 81 (0x51) + // Code size 75 (0x4b) .maxstack 3 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3 V_1, @@ -61,50 +61,46 @@ [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 V_3, [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 V_4) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch05.fs' + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch05.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: stloc.1 IL_0004: ldloc.1 IL_0005: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 - IL_000a: brtrue.s IL_0016 + IL_000a: brtrue.s IL_0026 IL_000c: ldloc.1 IL_000d: isinst class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 - IL_0012: brtrue.s IL_0018 + IL_0012: brtrue.s IL_0038 - IL_0014: br.s IL_001a - - IL_0016: br.s IL_002c - - IL_0018: br.s IL_003e - - IL_001a: ldloc.0 - IL_001b: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 - IL_0020: stloc.2 + .line 100001,100001 : 0,0 '' + IL_0014: ldloc.0 + IL_0015: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice3Of3 + IL_001a: stloc.2 .line 7,7 : 13,35 '' - IL_0021: ldstr "C" - IL_0026: call void [mscorlib]System.Console::WriteLine(string) - IL_002b: ret - - .line 5,5 : 9,21 '' - IL_002c: ldloc.0 - IL_002d: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 - IL_0032: stloc.3 + IL_001b: ldstr "C" + IL_0020: call void [mscorlib]System.Console::WriteLine(string) + IL_0025: ret + + .line 100001,100001 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice2Of3 + IL_002c: stloc.3 .line 9,9 : 13,35 '' - IL_0033: ldstr "B" - IL_0038: call void [mscorlib]System.Console::WriteLine(string) - IL_003d: ret - - .line 5,5 : 9,21 '' - IL_003e: ldloc.0 - IL_003f: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 - IL_0044: stloc.s V_4 + IL_002d: ldstr "B" + IL_0032: call void [mscorlib]System.Console::WriteLine(string) + IL_0037: ret + + .line 100001,100001 : 0,0 '' + IL_0038: ldloc.0 + IL_0039: castclass class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`3/Choice1Of3 + IL_003e: stloc.s V_4 .line 11,11 : 13,35 '' - IL_0046: ldstr "A" - IL_004b: call void [mscorlib]System.Console::WriteLine(string) - IL_0050: ret + IL_0040: ldstr "A" + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: ret } // end of method SteppingMatch05::funcC3 } // end of class SteppingMatch05 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl index 078b8cd73e3..9a549b41ea9 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch06 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch06 { - // Offset: 0x00000000 Length: 0x0000067D + // Offset: 0x00000000 Length: 0x00000675 } .mresource public FSharpOptimizationData.SteppingMatch06 { - // Offset: 0x00000688 Length: 0x000001D9 + // Offset: 0x00000680 Length: 0x000001D9 } .module SteppingMatch06.dll -// MVID: {59B19213-4FAE-FD21-A745-03831392B159} +// MVID: {611C4D99-4FAE-FD21-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x028F0000 +// Image base: 0x05850000 // =============== CLASS MEMBERS DECLARATION =================== @@ -205,77 +205,64 @@ instance int32 CompareTo(class SteppingMatch06/Discr obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 64 (0x40) + // Code size 49 (0x31) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch06.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0032 - + .line 4,4 : 6,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch06.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0030 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 SteppingMatch06/Discr::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 SteppingMatch06/Discr::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 SteppingMatch06/Discr::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: bne.un.s IL_0028 - - IL_0026: br.s IL_002a - - IL_0028: br.s IL_002c - + IL_001a: stloc.1 .line 100001,100001 : 0,0 '' - IL_002a: ldc.i4.0 - IL_002b: ret + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: bne.un.s IL_0021 .line 100001,100001 : 0,0 '' - IL_002c: ldloc.0 - IL_002d: ldloc.1 - IL_002e: sub - IL_002f: ret + IL_001f: ldc.i4.0 + IL_0020: ret .line 100001,100001 : 0,0 '' - IL_0030: ldc.i4.1 - IL_0031: ret + IL_0021: ldloc.0 + IL_0022: ldloc.1 + IL_0023: sub + IL_0024: ret .line 100001,100001 : 0,0 '' - IL_0032: ldarg.1 - IL_0033: ldnull - IL_0034: cgt.un - IL_0036: brfalse.s IL_003a - - IL_0038: br.s IL_003c + IL_0025: ldc.i4.1 + IL_0026: ret - IL_003a: br.s IL_003e + .line 100001,100001 : 0,0 '' + IL_0027: ldarg.1 + IL_0028: ldnull + IL_0029: cgt.un + IL_002b: brfalse.s IL_002f .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.m1 - IL_003d: ret + IL_002d: ldc.i4.m1 + IL_002e: ret .line 100001,100001 : 0,0 '' - IL_003e: ldc.i4.0 - IL_003f: ret + IL_002f: ldc.i4.0 + IL_0030: ret } // end of method Discr::CompareTo .method public hidebysig virtual final @@ -297,7 +284,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) + // Code size 65 (0x41) .maxstack 4 .locals init ([0] class SteppingMatch06/Discr V_0, [1] int32 V_1, @@ -306,102 +293,86 @@ IL_0000: ldarg.1 IL_0001: unbox.any SteppingMatch06/Discr IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0011 - - IL_000f: br.s IL_003e + IL_000b: brfalse.s IL_0032 .line 100001,100001 : 0,0 '' - IL_0011: ldarg.1 - IL_0012: unbox.any SteppingMatch06/Discr - IL_0017: ldnull - IL_0018: cgt.un - IL_001a: brfalse.s IL_001e - - IL_001c: br.s IL_0020 - - IL_001e: br.s IL_003c + IL_000d: ldarg.1 + IL_000e: unbox.any SteppingMatch06/Discr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_0030 .line 100001,100001 : 0,0 '' - IL_0020: ldarg.0 - IL_0021: ldfld int32 SteppingMatch06/Discr::_tag - IL_0026: stloc.1 - IL_0027: ldloc.0 - IL_0028: ldfld int32 SteppingMatch06/Discr::_tag - IL_002d: stloc.2 - IL_002e: ldloc.1 - IL_002f: ldloc.2 - IL_0030: bne.un.s IL_0034 - - IL_0032: br.s IL_0036 - - IL_0034: br.s IL_0038 - + IL_0018: ldarg.0 + IL_0019: ldfld int32 SteppingMatch06/Discr::_tag + IL_001e: stloc.1 + IL_001f: ldloc.0 + IL_0020: ldfld int32 SteppingMatch06/Discr::_tag + IL_0025: stloc.2 .line 100001,100001 : 0,0 '' - IL_0036: ldc.i4.0 - IL_0037: ret + IL_0026: ldloc.1 + IL_0027: ldloc.2 + IL_0028: bne.un.s IL_002c .line 100001,100001 : 0,0 '' - IL_0038: ldloc.1 - IL_0039: ldloc.2 - IL_003a: sub - IL_003b: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.1 - IL_003d: ret + IL_002c: ldloc.1 + IL_002d: ldloc.2 + IL_002e: sub + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003e: ldarg.1 - IL_003f: unbox.any SteppingMatch06/Discr - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d + IL_0030: ldc.i4.1 + IL_0031: ret - IL_004b: br.s IL_004f + .line 100001,100001 : 0,0 '' + IL_0032: ldarg.1 + IL_0033: unbox.any SteppingMatch06/Discr + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f .line 100001,100001 : 0,0 '' - IL_004d: ldc.i4.m1 - IL_004e: ret + IL_003d: ldc.i4.m1 + IL_003e: ret .line 100001,100001 : 0,0 '' - IL_004f: ldc.i4.0 - IL_0050: ret + IL_003f: ldc.i4.0 + IL_0040: ret } // end of method Discr::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 21 (0x15) + // Code size 18 (0x12) .maxstack 3 .locals init ([0] int32 V_0) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0013 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0010 .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: ldfld int32 SteppingMatch06/Discr::_tag - IL_0012: ret + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: ldfld int32 SteppingMatch06/Discr::_tag + IL_000f: ret .line 100001,100001 : 0,0 '' - IL_0013: ldc.i4.0 - IL_0014: ret + IL_0010: ldc.i4.0 + IL_0011: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final @@ -422,140 +393,128 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 55 (0x37) + // Code size 48 (0x30) .maxstack 4 .locals init ([0] class SteppingMatch06/Discr V_0, [1] class SteppingMatch06/Discr V_1, [2] int32 V_2, [3] int32 V_3) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_002f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst SteppingMatch06/Discr - IL_0010: stloc.0 - IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_002d + IL_0007: ldarg.1 + IL_0008: isinst SteppingMatch06/Discr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0026 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.0 + IL_0011: ldloc.0 + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 SteppingMatch06/Discr::_tag + IL_0019: stloc.2 + IL_001a: ldloc.1 IL_001b: ldfld int32 SteppingMatch06/Discr::_tag - IL_0020: stloc.2 - IL_0021: ldloc.1 - IL_0022: ldfld int32 SteppingMatch06/Discr::_tag - IL_0027: stloc.3 - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: ceq - IL_002c: ret + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: ceq + IL_0025: ret .line 100001,100001 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_0026: ldc.i4.0 + IL_0027: ret .line 100001,100001 : 0,0 '' - IL_002f: ldarg.1 - IL_0030: ldnull - IL_0031: cgt.un - IL_0033: ldc.i4.0 - IL_0034: ceq - IL_0036: ret + IL_0028: ldarg.1 + IL_0029: ldnull + IL_002a: cgt.un + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: ret } // end of method Discr::Equals .method public hidebysig virtual final instance bool Equals(class SteppingMatch06/Discr obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 49 (0x31) + // Code size 42 (0x2a) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0029 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0022 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0027 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0020 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 SteppingMatch06/Discr::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 SteppingMatch06/Discr::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 SteppingMatch06/Discr::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: ceq - IL_0026: ret + IL_001a: stloc.1 + .line 100001,100001 : 0,0 '' + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: ceq + IL_001f: ret .line 100001,100001 : 0,0 '' - IL_0027: ldc.i4.0 - IL_0028: ret + IL_0020: ldc.i4.0 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0029: ldarg.1 - IL_002a: ldnull - IL_002b: cgt.un - IL_002d: ldc.i4.0 - IL_002e: ceq - IL_0030: ret + IL_0022: ldarg.1 + IL_0023: ldnull + IL_0024: cgt.un + IL_0026: ldc.i4.0 + IL_0027: ceq + IL_0029: ret } // end of method Discr::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class SteppingMatch06/Discr V_0) .line 4,4 : 6,11 '' IL_0000: ldarg.1 IL_0001: isinst SteppingMatch06/Discr IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool SteppingMatch06/Discr::Equals(class SteppingMatch06/Discr) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool SteppingMatch06/Discr::Equals(class SteppingMatch06/Discr) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method Discr::Equals .property instance int32 Tag() @@ -599,25 +558,27 @@ .method public static void funcD(class SteppingMatch06/Discr n) cil managed { - // Code size 33 (0x21) + // Code size 34 (0x22) .maxstack 8 .line 6,6 : 9,21 '' - IL_0000: ldarg.0 - IL_0001: call instance int32 SteppingMatch06/Discr::get_Tag() - IL_0006: ldc.i4.0 - IL_0007: bne.un.s IL_000b + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: call instance int32 SteppingMatch06/Discr::get_Tag() + IL_0007: ldc.i4.0 + IL_0008: bne.un.s IL_000c - IL_0009: br.s IL_0016 + IL_000a: br.s IL_0017 .line 8,8 : 13,35 '' - IL_000b: ldstr "B" - IL_0010: call void [mscorlib]System.Console::WriteLine(string) - IL_0015: ret + IL_000c: ldstr "B" + IL_0011: call void [mscorlib]System.Console::WriteLine(string) + IL_0016: ret .line 10,10 : 13,35 '' - IL_0016: ldstr "A" - IL_001b: call void [mscorlib]System.Console::WriteLine(string) - IL_0020: ret + IL_0017: ldstr "A" + IL_001c: call void [mscorlib]System.Console::WriteLine(string) + IL_0021: ret } // end of method SteppingMatch06::funcD } // end of class SteppingMatch06 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl index a897b0908a0..76a3997425f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch07 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch07 { - // Offset: 0x00000000 Length: 0x0000067D + // Offset: 0x00000000 Length: 0x00000675 } .mresource public FSharpOptimizationData.SteppingMatch07 { - // Offset: 0x00000688 Length: 0x000001D9 + // Offset: 0x00000680 Length: 0x000001D9 } .module SteppingMatch07.dll -// MVID: {59B19213-D373-07F3-A745-03831392B159} +// MVID: {611C4D99-D373-07F3-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03330000 +// Image base: 0x06780000 // =============== CLASS MEMBERS DECLARATION =================== @@ -205,77 +205,64 @@ instance int32 CompareTo(class SteppingMatch07/Discr obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 64 (0x40) + // Code size 49 (0x31) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch07.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0032 - + .line 4,4 : 6,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch07.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0027 - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0030 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0025 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 SteppingMatch07/Discr::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 SteppingMatch07/Discr::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 SteppingMatch07/Discr::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: bne.un.s IL_0028 - - IL_0026: br.s IL_002a - - IL_0028: br.s IL_002c - + IL_001a: stloc.1 .line 100001,100001 : 0,0 '' - IL_002a: ldc.i4.0 - IL_002b: ret + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: bne.un.s IL_0021 .line 100001,100001 : 0,0 '' - IL_002c: ldloc.0 - IL_002d: ldloc.1 - IL_002e: sub - IL_002f: ret + IL_001f: ldc.i4.0 + IL_0020: ret .line 100001,100001 : 0,0 '' - IL_0030: ldc.i4.1 - IL_0031: ret + IL_0021: ldloc.0 + IL_0022: ldloc.1 + IL_0023: sub + IL_0024: ret .line 100001,100001 : 0,0 '' - IL_0032: ldarg.1 - IL_0033: ldnull - IL_0034: cgt.un - IL_0036: brfalse.s IL_003a - - IL_0038: br.s IL_003c + IL_0025: ldc.i4.1 + IL_0026: ret - IL_003a: br.s IL_003e + .line 100001,100001 : 0,0 '' + IL_0027: ldarg.1 + IL_0028: ldnull + IL_0029: cgt.un + IL_002b: brfalse.s IL_002f .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.m1 - IL_003d: ret + IL_002d: ldc.i4.m1 + IL_002e: ret .line 100001,100001 : 0,0 '' - IL_003e: ldc.i4.0 - IL_003f: ret + IL_002f: ldc.i4.0 + IL_0030: ret } // end of method Discr::CompareTo .method public hidebysig virtual final @@ -297,7 +284,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 81 (0x51) + // Code size 65 (0x41) .maxstack 4 .locals init ([0] class SteppingMatch07/Discr V_0, [1] int32 V_1, @@ -306,102 +293,86 @@ IL_0000: ldarg.1 IL_0001: unbox.any SteppingMatch07/Discr IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0011 - - IL_000f: br.s IL_003e + IL_000b: brfalse.s IL_0032 .line 100001,100001 : 0,0 '' - IL_0011: ldarg.1 - IL_0012: unbox.any SteppingMatch07/Discr - IL_0017: ldnull - IL_0018: cgt.un - IL_001a: brfalse.s IL_001e - - IL_001c: br.s IL_0020 - - IL_001e: br.s IL_003c + IL_000d: ldarg.1 + IL_000e: unbox.any SteppingMatch07/Discr + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_0030 .line 100001,100001 : 0,0 '' - IL_0020: ldarg.0 - IL_0021: ldfld int32 SteppingMatch07/Discr::_tag - IL_0026: stloc.1 - IL_0027: ldloc.0 - IL_0028: ldfld int32 SteppingMatch07/Discr::_tag - IL_002d: stloc.2 - IL_002e: ldloc.1 - IL_002f: ldloc.2 - IL_0030: bne.un.s IL_0034 - - IL_0032: br.s IL_0036 - - IL_0034: br.s IL_0038 - + IL_0018: ldarg.0 + IL_0019: ldfld int32 SteppingMatch07/Discr::_tag + IL_001e: stloc.1 + IL_001f: ldloc.0 + IL_0020: ldfld int32 SteppingMatch07/Discr::_tag + IL_0025: stloc.2 .line 100001,100001 : 0,0 '' - IL_0036: ldc.i4.0 - IL_0037: ret + IL_0026: ldloc.1 + IL_0027: ldloc.2 + IL_0028: bne.un.s IL_002c .line 100001,100001 : 0,0 '' - IL_0038: ldloc.1 - IL_0039: ldloc.2 - IL_003a: sub - IL_003b: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.1 - IL_003d: ret + IL_002c: ldloc.1 + IL_002d: ldloc.2 + IL_002e: sub + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003e: ldarg.1 - IL_003f: unbox.any SteppingMatch07/Discr - IL_0044: ldnull - IL_0045: cgt.un - IL_0047: brfalse.s IL_004b - - IL_0049: br.s IL_004d + IL_0030: ldc.i4.1 + IL_0031: ret - IL_004b: br.s IL_004f + .line 100001,100001 : 0,0 '' + IL_0032: ldarg.1 + IL_0033: unbox.any SteppingMatch07/Discr + IL_0038: ldnull + IL_0039: cgt.un + IL_003b: brfalse.s IL_003f .line 100001,100001 : 0,0 '' - IL_004d: ldc.i4.m1 - IL_004e: ret + IL_003d: ldc.i4.m1 + IL_003e: ret .line 100001,100001 : 0,0 '' - IL_004f: ldc.i4.0 - IL_0050: ret + IL_003f: ldc.i4.0 + IL_0040: ret } // end of method Discr::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 21 (0x15) + // Code size 18 (0x12) .maxstack 3 .locals init ([0] int32 V_0) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0013 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0010 .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: ldfld int32 SteppingMatch07/Discr::_tag - IL_0012: ret + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldarg.0 + IL_000a: ldfld int32 SteppingMatch07/Discr::_tag + IL_000f: ret .line 100001,100001 : 0,0 '' - IL_0013: ldc.i4.0 - IL_0014: ret + IL_0010: ldc.i4.0 + IL_0011: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final @@ -422,140 +393,128 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 55 (0x37) + // Code size 48 (0x30) .maxstack 4 .locals init ([0] class SteppingMatch07/Discr V_0, [1] class SteppingMatch07/Discr V_1, [2] int32 V_2, [3] int32 V_3) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_002f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0028 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst SteppingMatch07/Discr - IL_0010: stloc.0 - IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_002d + IL_0007: ldarg.1 + IL_0008: isinst SteppingMatch07/Discr + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0026 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.0 + IL_0011: ldloc.0 + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 SteppingMatch07/Discr::_tag + IL_0019: stloc.2 + IL_001a: ldloc.1 IL_001b: ldfld int32 SteppingMatch07/Discr::_tag - IL_0020: stloc.2 - IL_0021: ldloc.1 - IL_0022: ldfld int32 SteppingMatch07/Discr::_tag - IL_0027: stloc.3 - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: ceq - IL_002c: ret + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: ceq + IL_0025: ret .line 100001,100001 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_0026: ldc.i4.0 + IL_0027: ret .line 100001,100001 : 0,0 '' - IL_002f: ldarg.1 - IL_0030: ldnull - IL_0031: cgt.un - IL_0033: ldc.i4.0 - IL_0034: ceq - IL_0036: ret + IL_0028: ldarg.1 + IL_0029: ldnull + IL_002a: cgt.un + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: ret } // end of method Discr::Equals .method public hidebysig virtual final instance bool Equals(class SteppingMatch07/Discr obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 49 (0x31) + // Code size 42 (0x2a) .maxstack 4 .locals init ([0] int32 V_0, [1] int32 V_1) + .line 4,4 : 6,11 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0029 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0022 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0027 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0020 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 + IL_000d: ldarg.0 + IL_000e: ldfld int32 SteppingMatch07/Discr::_tag + IL_0013: stloc.0 + IL_0014: ldarg.1 IL_0015: ldfld int32 SteppingMatch07/Discr::_tag - IL_001a: stloc.0 - IL_001b: ldarg.1 - IL_001c: ldfld int32 SteppingMatch07/Discr::_tag - IL_0021: stloc.1 - IL_0022: ldloc.0 - IL_0023: ldloc.1 - IL_0024: ceq - IL_0026: ret + IL_001a: stloc.1 + .line 100001,100001 : 0,0 '' + IL_001b: ldloc.0 + IL_001c: ldloc.1 + IL_001d: ceq + IL_001f: ret .line 100001,100001 : 0,0 '' - IL_0027: ldc.i4.0 - IL_0028: ret + IL_0020: ldc.i4.0 + IL_0021: ret .line 100001,100001 : 0,0 '' - IL_0029: ldarg.1 - IL_002a: ldnull - IL_002b: cgt.un - IL_002d: ldc.i4.0 - IL_002e: ceq - IL_0030: ret + IL_0022: ldarg.1 + IL_0023: ldnull + IL_0024: cgt.un + IL_0026: ldc.i4.0 + IL_0027: ceq + IL_0029: ret } // end of method Discr::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class SteppingMatch07/Discr V_0) .line 4,4 : 6,11 '' IL_0000: ldarg.1 IL_0001: isinst SteppingMatch07/Discr IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool SteppingMatch07/Discr::Equals(class SteppingMatch07/Discr) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool SteppingMatch07/Discr::Equals(class SteppingMatch07/Discr) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method Discr::Equals .property instance int32 Tag() @@ -599,25 +558,27 @@ .method public static void funcE(class SteppingMatch07/Discr n) cil managed { - // Code size 33 (0x21) + // Code size 34 (0x22) .maxstack 8 .line 6,6 : 9,21 '' - IL_0000: ldarg.0 - IL_0001: call instance int32 SteppingMatch07/Discr::get_Tag() - IL_0006: ldc.i4.1 - IL_0007: bne.un.s IL_000b + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: call instance int32 SteppingMatch07/Discr::get_Tag() + IL_0007: ldc.i4.1 + IL_0008: bne.un.s IL_000c - IL_0009: br.s IL_0016 + IL_000a: br.s IL_0017 .line 8,8 : 13,35 '' - IL_000b: ldstr "A" - IL_0010: call void [mscorlib]System.Console::WriteLine(string) - IL_0015: ret + IL_000c: ldstr "A" + IL_0011: call void [mscorlib]System.Console::WriteLine(string) + IL_0016: ret .line 10,10 : 13,35 '' - IL_0016: ldstr "B" - IL_001b: call void [mscorlib]System.Console::WriteLine(string) - IL_0020: ret + IL_0017: ldstr "B" + IL_001c: call void [mscorlib]System.Console::WriteLine(string) + IL_0021: ret } // end of method SteppingMatch07::funcE } // end of class SteppingMatch07 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch08.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch08.il.bsl index 5d87f08136f..53a1dcd156f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch08.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch08.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch08 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch08 { - // Offset: 0x00000000 Length: 0x000001DF + // Offset: 0x00000000 Length: 0x000001DB } .mresource public FSharpOptimizationData.SteppingMatch08 { - // Offset: 0x000001E8 Length: 0x00000079 + // Offset: 0x000001E0 Length: 0x00000079 } .module SteppingMatch08.dll -// MVID: {59B19213-F238-BA3A-A745-03831392B159} +// MVID: {611C4D99-F238-BA3A-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00C70000 +// Image base: 0x05A00000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,30 +53,32 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void test(int32 x) cil managed { - // Code size 20 (0x14) + // Code size 21 (0x15) .maxstack 3 .locals init ([0] int32 b) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch08.fs' - IL_0000: ldarg.0 - IL_0001: switch ( - IL_000c) - IL_000a: br.s IL_0010 + .line 5,5 : 9,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch08.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: switch ( + IL_000d) + IL_000b: br.s IL_0011 .line 6,6 : 16,17 '' - IL_000c: ldc.i4.2 + IL_000d: ldc.i4.2 .line 100001,100001 : 0,0 '' - IL_000d: nop - IL_000e: br.s IL_0012 + IL_000e: nop + IL_000f: br.s IL_0013 .line 7,7 : 18,19 '' - IL_0010: ldc.i4.0 + IL_0011: ldc.i4.0 .line 100001,100001 : 0,0 '' - IL_0011: nop + IL_0012: nop .line 100001,100001 : 0,0 '' - IL_0012: stloc.0 + IL_0013: stloc.0 .line 10,10 : 5,38 '' - IL_0013: ret + IL_0014: ret } // end of method SteppingMatch08::test } // end of class SteppingMatch08 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch09.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch09.il.bsl index 5baef73c908..0a66e664385 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch09.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch09.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly SteppingMatch09 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.SteppingMatch09 { - // Offset: 0x00000000 Length: 0x00000318 + // Offset: 0x00000000 Length: 0x0000030C } .mresource public FSharpOptimizationData.SteppingMatch09 { - // Offset: 0x00000320 Length: 0x000000EB + // Offset: 0x00000310 Length: 0x000000EB } .module SteppingMatch09.dll -// MVID: {59B19213-4935-D6AC-A745-03831392B159} +// MVID: {611C4D99-4935-D6AC-A745-0383994D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00390000 +// Image base: 0x07080000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +54,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit GenericInner@15 extends [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc { + .field static assembly initonly class SteppingMatch09/GenericInner@15 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -81,6 +82,18 @@ IL_000b: ret } // end of method GenericInner@15::Specialize + .method private specialname rtspecialname static + void .cctor() cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void SteppingMatch09/GenericInner@15::.ctor() + IL_0005: stsfld class SteppingMatch09/GenericInner@15 SteppingMatch09/GenericInner@15::@_instance + IL_000a: ret + } // end of method GenericInner@15::.cctor + } // end of class GenericInner@15 .class auto ansi serializable sealed nested assembly beforefieldinit GenericInner@15T @@ -108,29 +121,27 @@ .method public strict virtual instance int32 Invoke(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed { - // Code size 23 (0x17) + // Code size 20 (0x14) .maxstack 6 .locals init ([0] class SteppingMatch09/GenericInner@15 V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16,16 : 6,21 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch09.fs' + .line 16,16 : 6,21 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\SteppingMatch\\SteppingMatch09.fs' IL_0000: ldarg.0 IL_0001: ldfld class SteppingMatch09/GenericInner@15 class SteppingMatch09/GenericInner@15T::self0@ IL_0006: stloc.0 - IL_0007: ldarg.1 - IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_000d: brtrue.s IL_0011 - - IL_000f: br.s IL_0013 - - IL_0011: br.s IL_0015 + IL_0007: nop + .line 100001,100001 : 0,0 '' + IL_0008: ldarg.1 + IL_0009: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_000e: brtrue.s IL_0012 .line 17,17 : 14,15 '' - IL_0013: ldc.i4.1 - IL_0014: ret + IL_0010: ldc.i4.1 + IL_0011: ret .line 18,18 : 13,14 '' - IL_0015: ldc.i4.2 - IL_0016: ret + IL_0012: ldc.i4.2 + IL_0013: ret } // end of method GenericInner@15T::Invoke } // end of class GenericInner@15T @@ -138,6 +149,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit NonGenericInner@25 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32> { + .field static assembly initonly class SteppingMatch09/NonGenericInner@25 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -153,26 +165,34 @@ .method public strict virtual instance int32 Invoke(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed { - // Code size 16 (0x10) + // Code size 13 (0xd) .maxstack 8 .line 25,25 : 6,21 '' - IL_0000: ldarg.1 - IL_0001: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0006: brtrue.s IL_000a - - IL_0008: br.s IL_000c - - IL_000a: br.s IL_000e + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.1 + IL_0002: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0007: brtrue.s IL_000b .line 26,26 : 14,15 '' - IL_000c: ldc.i4.1 - IL_000d: ret + IL_0009: ldc.i4.1 + IL_000a: ret .line 27,27 : 13,14 '' - IL_000e: ldc.i4.2 - IL_000f: ret + IL_000b: ldc.i4.2 + IL_000c: ret } // end of method NonGenericInner@25::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void SteppingMatch09/NonGenericInner@25::.ctor() + IL_0005: stsfld class SteppingMatch09/NonGenericInner@25 SteppingMatch09/NonGenericInner@25::@_instance + IL_000a: ret + } // end of method NonGenericInner@25::.cctor + } // end of class NonGenericInner@25 .class auto ansi serializable sealed nested assembly beforefieldinit NonGenericInnerWithCapture@34 @@ -197,25 +217,23 @@ .method public strict virtual instance int32 Invoke(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed { - // Code size 21 (0x15) + // Code size 18 (0x12) .maxstack 8 .line 34,34 : 6,21 '' - IL_0000: ldarg.1 - IL_0001: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0006: brtrue.s IL_000a - - IL_0008: br.s IL_000c - - IL_000a: br.s IL_000e + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.1 + IL_0002: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0007: brtrue.s IL_000b .line 35,35 : 14,15 '' - IL_000c: ldc.i4.1 - IL_000d: ret + IL_0009: ldc.i4.1 + IL_000a: ret .line 36,36 : 13,14 '' - IL_000e: ldarg.0 - IL_000f: ldfld int32 SteppingMatch09/NonGenericInnerWithCapture@34::x - IL_0014: ret + IL_000b: ldarg.0 + IL_000c: ldfld int32 SteppingMatch09/NonGenericInnerWithCapture@34::x + IL_0011: ret } // end of method NonGenericInnerWithCapture@34::Invoke } // end of class NonGenericInnerWithCapture@34 @@ -223,34 +241,32 @@ .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 funcA(int32 n) cil managed { - // Code size 40 (0x28) + // Code size 37 (0x25) .maxstack 8 .line 5,5 : 9,21 '' - IL_0000: ldarg.0 - IL_0001: ldc.i4.1 - IL_0002: sub - IL_0003: switch ( - IL_0012, - IL_0014) - IL_0010: br.s IL_0020 - - IL_0012: br.s IL_0016 - - IL_0014: br.s IL_001e + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldc.i4.1 + IL_0003: sub + IL_0004: switch ( + IL_0013, + IL_001b) + IL_0011: br.s IL_001d .line 7,7 : 13,21 '' - IL_0016: ldc.i4.s 10 - IL_0018: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_001d: ret + IL_0013: ldc.i4.s 10 + IL_0015: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) + IL_001a: ret .line 9,9 : 13,17 '' - IL_001e: ldnull - IL_001f: ret + IL_001b: ldnull + IL_001c: ret .line 11,11 : 20,34 '' - IL_0020: ldc.i4.s 22 - IL_0022: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) - IL_0027: ret + IL_001d: ldc.i4.s 22 + IL_001f: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::Some(!0) + IL_0024: ret } // end of method SteppingMatch09::funcA .method public static int32 OuterWithGenericInner(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 list) cil managed @@ -260,7 +276,7 @@ .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpTypeFunc GenericInner, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1) .line 100001,100001 : 0,0 '' - IL_0000: newobj instance void SteppingMatch09/GenericInner@15::.ctor() + IL_0000: ldsfld class SteppingMatch09/GenericInner@15 SteppingMatch09/GenericInner@15::@_instance IL_0005: stloc.0 .line 20,20 : 3,20 '' IL_0006: ldloc.0 @@ -280,7 +296,7 @@ .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32> NonGenericInner) .line 100001,100001 : 0,0 '' - IL_0000: newobj instance void SteppingMatch09/NonGenericInner@25::.ctor() + IL_0000: ldsfld class SteppingMatch09/NonGenericInner@25 SteppingMatch09/NonGenericInner@25::@_instance IL_0005: stloc.0 .line 29,29 : 3,23 '' IL_0006: ldloc.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction1.il.bsl index 6a80341afe9..f50ff82be7f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction1.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction1 { - // Offset: 0x00000000 Length: 0x000001CA + // Offset: 0x00000000 Length: 0x000001C6 } .mresource public FSharpOptimizationData.TestFunction1 { // Offset: 0x000001D0 Length: 0x00000070 } .module TestFunction1.exe -// MVID: {59B19208-65FC-8929-A745-03830892B159} +// MVID: {60B68B97-65FC-8929-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03230000 +// Image base: 0x054C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction1.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction1.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction10.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction10.il.bsl index 868ca11e97b..d25fd60cf44 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction10.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction10.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction10 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction10 { - // Offset: 0x00000000 Length: 0x000001C9 + // Offset: 0x00000000 Length: 0x000001C5 } .mresource public FSharpOptimizationData.TestFunction10 { // Offset: 0x000001D0 Length: 0x00000072 } .module TestFunction10.exe -// MVID: {59B199CC-A624-44FB-A745-0383CC99B159} +// MVID: {60B68B97-A624-44FB-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00DA0000 +// Image base: 0x066D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -61,7 +61,7 @@ [2] int32 y, [3] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction10.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction10.fs' IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction13.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction13.il.bsl index a23943d01bf..b3bb8d0a49b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction13.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction13.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction13 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction13 { - // Offset: 0x00000000 Length: 0x0000020F + // Offset: 0x00000000 Length: 0x00000203 } .mresource public FSharpOptimizationData.TestFunction13 { - // Offset: 0x00000218 Length: 0x00000072 + // Offset: 0x00000208 Length: 0x00000072 } .module TestFunction13.exe -// MVID: {59B199CC-A624-451C-A745-0383CC99B159} +// MVID: {60B68B97-A624-451C-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01000000 +// Image base: 0x00EC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,7 +57,7 @@ // Code size 30 (0x1e) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,16 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction13.fs' + .line 5,5 : 5,16 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction13.fs' IL_0000: ldarg.0 IL_0001: ldarg.0 IL_0002: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction14.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction14.il.bsl index a139e414063..b849fc36afb 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction14.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction14.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction14 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction14 { - // Offset: 0x00000000 Length: 0x000001EA + // Offset: 0x00000000 Length: 0x000001E6 } .mresource public FSharpOptimizationData.TestFunction14 { // Offset: 0x000001F0 Length: 0x00000072 } .module TestFunction14.exe -// MVID: {59B19208-A624-4587-A745-03830892B159} +// MVID: {60B68B97-A624-4587-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x006B0000 +// Image base: 0x00F10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +54,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit TestFunction14@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32> { + .field static assembly initonly class TestFunction14/TestFunction14@5 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -72,7 +73,7 @@ // Code size 10 (0xa) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 24,27 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction14.fs' + .line 5,5 : 24,27 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction14.fs' IL_0000: ldarg.1 IL_0001: ldc.i4.2 IL_0002: tail. @@ -80,11 +81,22 @@ IL_0009: ret } // end of method TestFunction14@5::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void TestFunction14/TestFunction14@5::.ctor() + IL_0005: stsfld class TestFunction14/TestFunction14@5 TestFunction14/TestFunction14@5::@_instance + IL_000a: ret + } // end of method TestFunction14@5::.cctor + } // end of class TestFunction14@5 .class auto ansi serializable sealed nested assembly beforefieldinit 'TestFunction14@5-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class TestFunction14/'TestFunction14@5-1' @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -109,6 +121,16 @@ IL_0003: ret } // end of method 'TestFunction14@5-1'::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void TestFunction14/'TestFunction14@5-1'::.ctor() + IL_0005: stsfld class TestFunction14/'TestFunction14@5-1' TestFunction14/'TestFunction14@5-1'::@_instance + IL_000a: ret + } // end of method 'TestFunction14@5-1'::.cctor + } // end of class 'TestFunction14@5-1' .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 @@ -117,8 +139,8 @@ // Code size 28 (0x1c) .maxstack 8 .line 5,5 : 5,47 '' - IL_0000: newobj instance void TestFunction14/TestFunction14@5::.ctor() - IL_0005: newobj instance void TestFunction14/'TestFunction14@5-1'::.ctor() + IL_0000: ldsfld class TestFunction14/TestFunction14@5 TestFunction14/TestFunction14@5::@_instance + IL_0005: ldsfld class TestFunction14/'TestFunction14@5-1' TestFunction14/'TestFunction14@5-1'::@_instance IL_000a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>::get_Empty() IL_000f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction16.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction16.il.bsl index 35254e97c34..053da8e2bc1 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction16.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction16.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction16 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction16 { - // Offset: 0x00000000 Length: 0x00000693 + // Offset: 0x00000000 Length: 0x00000683 } .mresource public FSharpOptimizationData.TestFunction16 { - // Offset: 0x00000698 Length: 0x000001CD + // Offset: 0x00000688 Length: 0x000001CD } .module TestFunction16.exe -// MVID: {59B199CC-A624-45C5-A745-0383CC99B159} +// MVID: {611C52B3-A624-45C5-A745-0383B3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01940000 +// Image base: 0x07120000 // =============== CLASS MEMBERS DECLARATION =================== @@ -174,7 +174,7 @@ instance int32 CompareTo(class TestFunction16/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 154 (0x9a) + // Code size 121 (0x79) .maxstack 4 .locals init ([0] class TestFunction16/U V_0, [1] class TestFunction16/U V_1, @@ -186,137 +186,114 @@ [7] int32 V_7, [8] int32 V_8) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction16.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_008c - + .line 4,4 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction16.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_001a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006f - IL_0015: br IL_008a + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006d .line 100001,100001 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: pop + IL_000d: ldarg.0 + IL_000e: pop .line 100001,100001 : 0,0 '' - IL_001c: ldarg.0 - IL_001d: stloc.0 - IL_001e: ldarg.1 - IL_001f: stloc.1 - IL_0020: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0025: stloc.3 - IL_0026: ldloc.0 - IL_0027: ldfld int32 TestFunction16/U::item1 - IL_002c: stloc.s V_4 - IL_002e: ldloc.1 - IL_002f: ldfld int32 TestFunction16/U::item1 - IL_0034: stloc.s V_5 - IL_0036: ldloc.s V_4 - IL_0038: ldloc.s V_5 - IL_003a: bge.s IL_003e - - IL_003c: br.s IL_0040 - - IL_003e: br.s IL_0044 + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 TestFunction16/U::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 TestFunction16/U::item1 + IL_0027: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 100001,100001 : 0,0 '' - IL_0040: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_0041: nop - IL_0042: br.s IL_004b + IL_0030: nop + IL_0031: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_0044: ldloc.s V_4 - IL_0046: ldloc.s V_5 - IL_0048: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 100001,100001 : 0,0 '' - IL_004a: nop + IL_0039: nop .line 100001,100001 : 0,0 '' - IL_004b: stloc.2 - IL_004c: ldloc.2 - IL_004d: ldc.i4.0 - IL_004e: bge.s IL_0052 - - IL_0050: br.s IL_0054 - - IL_0052: br.s IL_0056 - + IL_003a: stloc.2 .line 100001,100001 : 0,0 '' - IL_0054: ldloc.2 - IL_0055: ret + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0056: ldloc.2 - IL_0057: ldc.i4.0 - IL_0058: ble.s IL_005c - - IL_005a: br.s IL_005e - - IL_005c: br.s IL_0060 + IL_003f: ldloc.2 + IL_0040: ret .line 100001,100001 : 0,0 '' - IL_005e: ldloc.2 - IL_005f: ret + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 100001,100001 : 0,0 '' - IL_0060: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0065: stloc.s V_6 - IL_0067: ldloc.0 - IL_0068: ldfld int32 TestFunction16/U::item2 - IL_006d: stloc.s V_7 - IL_006f: ldloc.1 - IL_0070: ldfld int32 TestFunction16/U::item2 - IL_0075: stloc.s V_8 - IL_0077: ldloc.s V_7 - IL_0079: ldloc.s V_8 - IL_007b: bge.s IL_007f - - IL_007d: br.s IL_0081 - - IL_007f: br.s IL_0083 + IL_0045: ldloc.2 + IL_0046: ret .line 100001,100001 : 0,0 '' - IL_0081: ldc.i4.m1 - IL_0082: ret - + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.s V_6 + IL_004e: ldloc.0 + IL_004f: ldfld int32 TestFunction16/U::item2 + IL_0054: stloc.s V_7 + IL_0056: ldloc.1 + IL_0057: ldfld int32 TestFunction16/U::item2 + IL_005c: stloc.s V_8 .line 100001,100001 : 0,0 '' - IL_0083: ldloc.s V_7 - IL_0085: ldloc.s V_8 - IL_0087: cgt - IL_0089: ret + IL_005e: ldloc.s V_7 + IL_0060: ldloc.s V_8 + IL_0062: bge.s IL_0066 .line 100001,100001 : 0,0 '' - IL_008a: ldc.i4.1 - IL_008b: ret + IL_0064: ldc.i4.m1 + IL_0065: ret .line 100001,100001 : 0,0 '' - IL_008c: ldarg.1 - IL_008d: ldnull - IL_008e: cgt.un - IL_0090: brfalse.s IL_0094 + IL_0066: ldloc.s V_7 + IL_0068: ldloc.s V_8 + IL_006a: cgt + IL_006c: ret - IL_0092: br.s IL_0096 + .line 100001,100001 : 0,0 '' + IL_006d: ldc.i4.1 + IL_006e: ret - IL_0094: br.s IL_0098 + .line 100001,100001 : 0,0 '' + IL_006f: ldarg.1 + IL_0070: ldnull + IL_0071: cgt.un + IL_0073: brfalse.s IL_0077 .line 100001,100001 : 0,0 '' - IL_0096: ldc.i4.m1 - IL_0097: ret + IL_0075: ldc.i4.m1 + IL_0076: ret .line 100001,100001 : 0,0 '' - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0077: ldc.i4.0 + IL_0078: ret } // end of method U::CompareTo .method public hidebysig virtual final @@ -338,7 +315,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 164 (0xa4) + // Code size 130 (0x82) .maxstack 4 .locals init ([0] class TestFunction16/U V_0, [1] class TestFunction16/U V_1, @@ -354,206 +331,181 @@ IL_0000: ldarg.1 IL_0001: unbox.any TestFunction16/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0014 - - IL_000f: br IL_0091 + IL_000b: brfalse.s IL_0073 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.1 - IL_0015: unbox.any TestFunction16/U - IL_001a: ldnull - IL_001b: cgt.un - IL_001d: brfalse.s IL_0021 - - IL_001f: br.s IL_0026 - - IL_0021: br IL_008f + IL_000d: ldarg.1 + IL_000e: unbox.any TestFunction16/U + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_0071 .line 100001,100001 : 0,0 '' - IL_0026: ldarg.0 - IL_0027: pop + IL_0018: ldarg.0 + IL_0019: pop .line 100001,100001 : 0,0 '' - IL_0028: ldarg.0 - IL_0029: stloc.1 - IL_002a: ldloc.0 - IL_002b: stloc.2 - IL_002c: ldarg.2 - IL_002d: stloc.s V_4 - IL_002f: ldloc.1 - IL_0030: ldfld int32 TestFunction16/U::item1 - IL_0035: stloc.s V_5 - IL_0037: ldloc.2 - IL_0038: ldfld int32 TestFunction16/U::item1 - IL_003d: stloc.s V_6 - IL_003f: ldloc.s V_5 - IL_0041: ldloc.s V_6 - IL_0043: bge.s IL_0047 - - IL_0045: br.s IL_0049 - - IL_0047: br.s IL_004d + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 TestFunction16/U::item1 + IL_0027: stloc.s V_5 + IL_0029: ldloc.2 + IL_002a: ldfld int32 TestFunction16/U::item1 + IL_002f: stloc.s V_6 + .line 100001,100001 : 0,0 '' + IL_0031: ldloc.s V_5 + IL_0033: ldloc.s V_6 + IL_0035: bge.s IL_003b .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.m1 + IL_0037: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_004a: nop - IL_004b: br.s IL_0054 + IL_0038: nop + IL_0039: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_004d: ldloc.s V_5 - IL_004f: ldloc.s V_6 - IL_0051: cgt + IL_003b: ldloc.s V_5 + IL_003d: ldloc.s V_6 + IL_003f: cgt .line 100001,100001 : 0,0 '' - IL_0053: nop + IL_0041: nop .line 100001,100001 : 0,0 '' - IL_0054: stloc.3 - IL_0055: ldloc.3 - IL_0056: ldc.i4.0 - IL_0057: bge.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - + IL_0042: stloc.3 .line 100001,100001 : 0,0 '' - IL_005d: ldloc.3 - IL_005e: ret + IL_0043: ldloc.3 + IL_0044: ldc.i4.0 + IL_0045: bge.s IL_0049 .line 100001,100001 : 0,0 '' - IL_005f: ldloc.3 - IL_0060: ldc.i4.0 - IL_0061: ble.s IL_0065 - - IL_0063: br.s IL_0067 - - IL_0065: br.s IL_0069 + IL_0047: ldloc.3 + IL_0048: ret .line 100001,100001 : 0,0 '' - IL_0067: ldloc.3 - IL_0068: ret + IL_0049: ldloc.3 + IL_004a: ldc.i4.0 + IL_004b: ble.s IL_004f .line 100001,100001 : 0,0 '' - IL_0069: ldarg.2 - IL_006a: stloc.s V_7 - IL_006c: ldloc.1 - IL_006d: ldfld int32 TestFunction16/U::item2 - IL_0072: stloc.s V_8 - IL_0074: ldloc.2 - IL_0075: ldfld int32 TestFunction16/U::item2 - IL_007a: stloc.s V_9 - IL_007c: ldloc.s V_8 - IL_007e: ldloc.s V_9 - IL_0080: bge.s IL_0084 - - IL_0082: br.s IL_0086 - - IL_0084: br.s IL_0088 + IL_004d: ldloc.3 + IL_004e: ret .line 100001,100001 : 0,0 '' - IL_0086: ldc.i4.m1 - IL_0087: ret - + IL_004f: ldarg.2 + IL_0050: stloc.s V_7 + IL_0052: ldloc.1 + IL_0053: ldfld int32 TestFunction16/U::item2 + IL_0058: stloc.s V_8 + IL_005a: ldloc.2 + IL_005b: ldfld int32 TestFunction16/U::item2 + IL_0060: stloc.s V_9 .line 100001,100001 : 0,0 '' - IL_0088: ldloc.s V_8 - IL_008a: ldloc.s V_9 - IL_008c: cgt - IL_008e: ret + IL_0062: ldloc.s V_8 + IL_0064: ldloc.s V_9 + IL_0066: bge.s IL_006a .line 100001,100001 : 0,0 '' - IL_008f: ldc.i4.1 - IL_0090: ret + IL_0068: ldc.i4.m1 + IL_0069: ret .line 100001,100001 : 0,0 '' - IL_0091: ldarg.1 - IL_0092: unbox.any TestFunction16/U - IL_0097: ldnull - IL_0098: cgt.un - IL_009a: brfalse.s IL_009e + IL_006a: ldloc.s V_8 + IL_006c: ldloc.s V_9 + IL_006e: cgt + IL_0070: ret - IL_009c: br.s IL_00a0 + .line 100001,100001 : 0,0 '' + IL_0071: ldc.i4.1 + IL_0072: ret - IL_009e: br.s IL_00a2 + .line 100001,100001 : 0,0 '' + IL_0073: ldarg.1 + IL_0074: unbox.any TestFunction16/U + IL_0079: ldnull + IL_007a: cgt.un + IL_007c: brfalse.s IL_0080 .line 100001,100001 : 0,0 '' - IL_00a0: ldc.i4.m1 - IL_00a1: ret + IL_007e: ldc.i4.m1 + IL_007f: ret .line 100001,100001 : 0,0 '' - IL_00a2: ldc.i4.0 - IL_00a3: ret + IL_0080: ldc.i4.0 + IL_0081: ret } // end of method U::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) + // Code size 65 (0x41) .maxstack 7 .locals init ([0] int32 V_0, [1] class TestFunction16/U V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2, [3] class [mscorlib]System.Collections.IEqualityComparer V_3) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0042 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003f .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: pop + IL_0007: ldc.i4.0 + IL_0008: stloc.0 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.1 - IL_0010: ldc.i4.0 - IL_0011: stloc.0 - IL_0012: ldc.i4 0x9e3779b9 - IL_0017: ldarg.1 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld int32 TestFunction16/U::item2 + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 TestFunction16/U::item2 + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldc.i4 0x9e3779b9 - IL_002e: ldarg.1 - IL_002f: stloc.3 - IL_0030: ldloc.1 - IL_0031: ldfld int32 TestFunction16/U::item1 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldc.i4 0x9e3779b9 + IL_002b: ldarg.1 + IL_002c: stloc.3 + IL_002d: ldloc.1 + IL_002e: ldfld int32 TestFunction16/U::item1 + IL_0033: ldloc.0 + IL_0034: ldc.i4.6 + IL_0035: shl IL_0036: ldloc.0 - IL_0037: ldc.i4.6 - IL_0038: shl - IL_0039: ldloc.0 - IL_003a: ldc.i4.2 - IL_003b: shr - IL_003c: add - IL_003d: add - IL_003e: add - IL_003f: stloc.0 - IL_0040: ldloc.0 - IL_0041: ret + IL_0037: ldc.i4.2 + IL_0038: shr + IL_0039: add + IL_003a: add + IL_003b: add + IL_003c: stloc.0 + IL_003d: ldloc.0 + IL_003e: ret .line 100001,100001 : 0,0 '' - IL_0042: ldc.i4.0 - IL_0043: ret + IL_003f: ldc.i4.0 + IL_0040: ret } // end of method U::GetHashCode .method public hidebysig virtual final @@ -574,7 +526,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 85 (0x55) + // Code size 74 (0x4a) .maxstack 4 .locals init ([0] class TestFunction16/U V_0, [1] class TestFunction16/U V_1, @@ -582,175 +534,156 @@ [3] class TestFunction16/U V_3, [4] class [mscorlib]System.Collections.IEqualityComparer V_4, [5] class [mscorlib]System.Collections.IEqualityComparer V_5) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0042 - IL_0006: br.s IL_000a - - IL_0008: br.s IL_004d + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst TestFunction16/U + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0040 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst TestFunction16/U - IL_0010: stloc.0 IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_004b - + IL_0012: stloc.1 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.0 - IL_001b: pop + IL_0013: ldarg.0 + IL_0014: pop .line 100001,100001 : 0,0 '' - IL_001c: ldarg.0 - IL_001d: stloc.2 - IL_001e: ldloc.1 - IL_001f: stloc.3 - IL_0020: ldarg.2 - IL_0021: stloc.s V_4 - IL_0023: ldloc.2 - IL_0024: ldfld int32 TestFunction16/U::item1 - IL_0029: ldloc.3 - IL_002a: ldfld int32 TestFunction16/U::item1 - IL_002f: ceq - IL_0031: brfalse.s IL_0035 - - IL_0033: br.s IL_0037 - - IL_0035: br.s IL_0049 + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 TestFunction16/U::item1 + IL_0022: ldloc.3 + IL_0023: ldfld int32 TestFunction16/U::item1 + IL_0028: ceq + IL_002a: brfalse.s IL_003e .line 100001,100001 : 0,0 '' - IL_0037: ldarg.2 - IL_0038: stloc.s V_5 - IL_003a: ldloc.2 - IL_003b: ldfld int32 TestFunction16/U::item2 - IL_0040: ldloc.3 - IL_0041: ldfld int32 TestFunction16/U::item2 - IL_0046: ceq - IL_0048: ret + IL_002c: ldarg.2 + IL_002d: stloc.s V_5 + IL_002f: ldloc.2 + IL_0030: ldfld int32 TestFunction16/U::item2 + IL_0035: ldloc.3 + IL_0036: ldfld int32 TestFunction16/U::item2 + IL_003b: ceq + IL_003d: ret .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.0 - IL_004a: ret + IL_003e: ldc.i4.0 + IL_003f: ret .line 100001,100001 : 0,0 '' - IL_004b: ldc.i4.0 - IL_004c: ret + IL_0040: ldc.i4.0 + IL_0041: ret .line 100001,100001 : 0,0 '' - IL_004d: ldarg.1 - IL_004e: ldnull - IL_004f: cgt.un - IL_0051: ldc.i4.0 - IL_0052: ceq - IL_0054: ret + IL_0042: ldarg.1 + IL_0043: ldnull + IL_0044: cgt.un + IL_0046: ldc.i4.0 + IL_0047: ceq + IL_0049: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(class TestFunction16/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 71 (0x47) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class TestFunction16/U V_0, [1] class TestFunction16/U V_1) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_003f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_003d + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: pop + IL_000d: ldarg.0 + IL_000e: pop .line 100001,100001 : 0,0 '' - IL_0016: ldarg.0 - IL_0017: stloc.0 - IL_0018: ldarg.1 - IL_0019: stloc.1 - IL_001a: ldloc.0 - IL_001b: ldfld int32 TestFunction16/U::item1 - IL_0020: ldloc.1 - IL_0021: ldfld int32 TestFunction16/U::item1 - IL_0026: bne.un.s IL_002a - - IL_0028: br.s IL_002c - - IL_002a: br.s IL_003b + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld int32 TestFunction16/U::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 TestFunction16/U::item1 + IL_001f: bne.un.s IL_0030 .line 100001,100001 : 0,0 '' - IL_002c: ldloc.0 - IL_002d: ldfld int32 TestFunction16/U::item2 - IL_0032: ldloc.1 - IL_0033: ldfld int32 TestFunction16/U::item2 - IL_0038: ceq - IL_003a: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 TestFunction16/U::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 TestFunction16/U::item2 + IL_002d: ceq + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003b: ldc.i4.0 - IL_003c: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 100001,100001 : 0,0 '' - IL_003d: ldc.i4.0 - IL_003e: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 100001,100001 : 0,0 '' - IL_003f: ldarg.1 - IL_0040: ldnull - IL_0041: cgt.un - IL_0043: ldc.i4.0 - IL_0044: ceq - IL_0046: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class TestFunction16/U V_0) .line 4,4 : 6,7 '' IL_0000: ldarg.1 IL_0001: isinst TestFunction16/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool TestFunction16/U::Equals(class TestFunction16/U) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool TestFunction16/U::Equals(class TestFunction16/U) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method U::Equals .property instance int32 Tag() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction17.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction17.il.bsl index cc502982e7b..5b097b711ff 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction17.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction17.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction17 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction17 { - // Offset: 0x00000000 Length: 0x0000067E + // Offset: 0x00000000 Length: 0x0000066E } .mresource public FSharpOptimizationData.TestFunction17 { - // Offset: 0x00000688 Length: 0x000001CD + // Offset: 0x00000678 Length: 0x000001CD } .module TestFunction17.exe -// MVID: {59B199CC-A624-45A8-A745-0383CC99B159} +// MVID: {611C52B3-A624-45A8-A745-0383B3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x027C0000 +// Image base: 0x06B30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -119,7 +119,7 @@ instance int32 CompareTo(class TestFunction17/R obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 142 (0x8e) + // Code size 109 (0x6d) .maxstack 4 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IComparer V_1, @@ -129,130 +129,107 @@ [5] int32 V_5, [6] int32 V_6) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction17.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_0080 - + .line 4,4 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction17.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_001a - - IL_0015: br IL_007e + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0063 .line 100001,100001 : 0,0 '' - IL_001a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_001f: stloc.1 - IL_0020: ldarg.0 - IL_0021: ldfld int32 TestFunction17/R::x@ - IL_0026: stloc.2 - IL_0027: ldarg.1 - IL_0028: ldfld int32 TestFunction17/R::x@ - IL_002d: stloc.3 - IL_002e: ldloc.2 - IL_002f: ldloc.3 - IL_0030: bge.s IL_0034 - - IL_0032: br.s IL_0036 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0061 - IL_0034: br.s IL_003a + .line 100001,100001 : 0,0 '' + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 TestFunction17/R::x@ + IL_0019: stloc.2 + IL_001a: ldarg.1 + IL_001b: ldfld int32 TestFunction17/R::x@ + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: bge.s IL_0029 .line 100001,100001 : 0,0 '' - IL_0036: ldc.i4.m1 + IL_0025: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_003f + IL_0026: nop + IL_0027: br.s IL_002e .line 100001,100001 : 0,0 '' - IL_003a: ldloc.2 - IL_003b: ldloc.3 - IL_003c: cgt + IL_0029: ldloc.2 + IL_002a: ldloc.3 + IL_002b: cgt .line 100001,100001 : 0,0 '' - IL_003e: nop + IL_002d: nop .line 100001,100001 : 0,0 '' - IL_003f: stloc.0 - IL_0040: ldloc.0 - IL_0041: ldc.i4.0 - IL_0042: bge.s IL_0046 - - IL_0044: br.s IL_0048 - - IL_0046: br.s IL_004a - + IL_002e: stloc.0 .line 100001,100001 : 0,0 '' - IL_0048: ldloc.0 - IL_0049: ret + IL_002f: ldloc.0 + IL_0030: ldc.i4.0 + IL_0031: bge.s IL_0035 .line 100001,100001 : 0,0 '' - IL_004a: ldloc.0 - IL_004b: ldc.i4.0 - IL_004c: ble.s IL_0050 - - IL_004e: br.s IL_0052 - - IL_0050: br.s IL_0054 + IL_0033: ldloc.0 + IL_0034: ret .line 100001,100001 : 0,0 '' - IL_0052: ldloc.0 - IL_0053: ret + IL_0035: ldloc.0 + IL_0036: ldc.i4.0 + IL_0037: ble.s IL_003b .line 100001,100001 : 0,0 '' - IL_0054: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0059: stloc.s V_4 - IL_005b: ldarg.0 - IL_005c: ldfld int32 TestFunction17/R::y@ - IL_0061: stloc.s V_5 - IL_0063: ldarg.1 - IL_0064: ldfld int32 TestFunction17/R::y@ - IL_0069: stloc.s V_6 - IL_006b: ldloc.s V_5 - IL_006d: ldloc.s V_6 - IL_006f: bge.s IL_0073 - - IL_0071: br.s IL_0075 - - IL_0073: br.s IL_0077 + IL_0039: ldloc.0 + IL_003a: ret .line 100001,100001 : 0,0 '' - IL_0075: ldc.i4.m1 - IL_0076: ret - + IL_003b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0040: stloc.s V_4 + IL_0042: ldarg.0 + IL_0043: ldfld int32 TestFunction17/R::y@ + IL_0048: stloc.s V_5 + IL_004a: ldarg.1 + IL_004b: ldfld int32 TestFunction17/R::y@ + IL_0050: stloc.s V_6 .line 100001,100001 : 0,0 '' - IL_0077: ldloc.s V_5 - IL_0079: ldloc.s V_6 - IL_007b: cgt - IL_007d: ret + IL_0052: ldloc.s V_5 + IL_0054: ldloc.s V_6 + IL_0056: bge.s IL_005a .line 100001,100001 : 0,0 '' - IL_007e: ldc.i4.1 - IL_007f: ret + IL_0058: ldc.i4.m1 + IL_0059: ret .line 100001,100001 : 0,0 '' - IL_0080: ldarg.1 - IL_0081: ldnull - IL_0082: cgt.un - IL_0084: brfalse.s IL_0088 + IL_005a: ldloc.s V_5 + IL_005c: ldloc.s V_6 + IL_005e: cgt + IL_0060: ret - IL_0086: br.s IL_008a + .line 100001,100001 : 0,0 '' + IL_0061: ldc.i4.1 + IL_0062: ret - IL_0088: br.s IL_008c + .line 100001,100001 : 0,0 '' + IL_0063: ldarg.1 + IL_0064: ldnull + IL_0065: cgt.un + IL_0067: brfalse.s IL_006b .line 100001,100001 : 0,0 '' - IL_008a: ldc.i4.m1 - IL_008b: ret + IL_0069: ldc.i4.m1 + IL_006a: ret .line 100001,100001 : 0,0 '' - IL_008c: ldc.i4.0 - IL_008d: ret + IL_006b: ldc.i4.0 + IL_006c: ret } // end of method R::CompareTo .method public hidebysig virtual final @@ -274,7 +251,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 159 (0x9f) + // Code size 125 (0x7d) .maxstack 4 .locals init ([0] class TestFunction17/R V_0, [1] class TestFunction17/R V_1, @@ -291,191 +268,165 @@ IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: stloc.1 + .line 100001,100001 : 0,0 '' IL_0009: ldarg.0 IL_000a: ldnull IL_000b: cgt.un - IL_000d: brfalse.s IL_0011 - - IL_000f: br.s IL_0016 - - IL_0011: br IL_008c + IL_000d: brfalse.s IL_006e .line 100001,100001 : 0,0 '' - IL_0016: ldarg.1 - IL_0017: unbox.any TestFunction17/R - IL_001c: ldnull - IL_001d: cgt.un - IL_001f: brfalse.s IL_0023 - - IL_0021: br.s IL_0028 - - IL_0023: br IL_008a + IL_000f: ldarg.1 + IL_0010: unbox.any TestFunction17/R + IL_0015: ldnull + IL_0016: cgt.un + IL_0018: brfalse.s IL_006c .line 100001,100001 : 0,0 '' - IL_0028: ldarg.2 - IL_0029: stloc.3 - IL_002a: ldarg.0 - IL_002b: ldfld int32 TestFunction17/R::x@ - IL_0030: stloc.s V_4 - IL_0032: ldloc.1 - IL_0033: ldfld int32 TestFunction17/R::x@ - IL_0038: stloc.s V_5 - IL_003a: ldloc.s V_4 - IL_003c: ldloc.s V_5 - IL_003e: bge.s IL_0042 - - IL_0040: br.s IL_0044 - - IL_0042: br.s IL_0048 + IL_001a: ldarg.2 + IL_001b: stloc.3 + IL_001c: ldarg.0 + IL_001d: ldfld int32 TestFunction17/R::x@ + IL_0022: stloc.s V_4 + IL_0024: ldloc.1 + IL_0025: ldfld int32 TestFunction17/R::x@ + IL_002a: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_002c: ldloc.s V_4 + IL_002e: ldloc.s V_5 + IL_0030: bge.s IL_0036 .line 100001,100001 : 0,0 '' - IL_0044: ldc.i4.m1 + IL_0032: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004f + IL_0033: nop + IL_0034: br.s IL_003d .line 100001,100001 : 0,0 '' - IL_0048: ldloc.s V_4 - IL_004a: ldloc.s V_5 - IL_004c: cgt + IL_0036: ldloc.s V_4 + IL_0038: ldloc.s V_5 + IL_003a: cgt .line 100001,100001 : 0,0 '' - IL_004e: nop + IL_003c: nop .line 100001,100001 : 0,0 '' - IL_004f: stloc.2 - IL_0050: ldloc.2 - IL_0051: ldc.i4.0 - IL_0052: bge.s IL_0056 - - IL_0054: br.s IL_0058 - - IL_0056: br.s IL_005a - + IL_003d: stloc.2 .line 100001,100001 : 0,0 '' - IL_0058: ldloc.2 - IL_0059: ret + IL_003e: ldloc.2 + IL_003f: ldc.i4.0 + IL_0040: bge.s IL_0044 .line 100001,100001 : 0,0 '' - IL_005a: ldloc.2 - IL_005b: ldc.i4.0 - IL_005c: ble.s IL_0060 - - IL_005e: br.s IL_0062 - - IL_0060: br.s IL_0064 + IL_0042: ldloc.2 + IL_0043: ret .line 100001,100001 : 0,0 '' - IL_0062: ldloc.2 - IL_0063: ret + IL_0044: ldloc.2 + IL_0045: ldc.i4.0 + IL_0046: ble.s IL_004a .line 100001,100001 : 0,0 '' - IL_0064: ldarg.2 - IL_0065: stloc.s V_6 - IL_0067: ldarg.0 - IL_0068: ldfld int32 TestFunction17/R::y@ - IL_006d: stloc.s V_7 - IL_006f: ldloc.1 - IL_0070: ldfld int32 TestFunction17/R::y@ - IL_0075: stloc.s V_8 - IL_0077: ldloc.s V_7 - IL_0079: ldloc.s V_8 - IL_007b: bge.s IL_007f - - IL_007d: br.s IL_0081 - - IL_007f: br.s IL_0083 + IL_0048: ldloc.2 + IL_0049: ret .line 100001,100001 : 0,0 '' - IL_0081: ldc.i4.m1 - IL_0082: ret - + IL_004a: ldarg.2 + IL_004b: stloc.s V_6 + IL_004d: ldarg.0 + IL_004e: ldfld int32 TestFunction17/R::y@ + IL_0053: stloc.s V_7 + IL_0055: ldloc.1 + IL_0056: ldfld int32 TestFunction17/R::y@ + IL_005b: stloc.s V_8 .line 100001,100001 : 0,0 '' - IL_0083: ldloc.s V_7 - IL_0085: ldloc.s V_8 - IL_0087: cgt - IL_0089: ret + IL_005d: ldloc.s V_7 + IL_005f: ldloc.s V_8 + IL_0061: bge.s IL_0065 .line 100001,100001 : 0,0 '' - IL_008a: ldc.i4.1 - IL_008b: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 100001,100001 : 0,0 '' - IL_008c: ldarg.1 - IL_008d: unbox.any TestFunction17/R - IL_0092: ldnull - IL_0093: cgt.un - IL_0095: brfalse.s IL_0099 + IL_0065: ldloc.s V_7 + IL_0067: ldloc.s V_8 + IL_0069: cgt + IL_006b: ret - IL_0097: br.s IL_009b + .line 100001,100001 : 0,0 '' + IL_006c: ldc.i4.1 + IL_006d: ret - IL_0099: br.s IL_009d + .line 100001,100001 : 0,0 '' + IL_006e: ldarg.1 + IL_006f: unbox.any TestFunction17/R + IL_0074: ldnull + IL_0075: cgt.un + IL_0077: brfalse.s IL_007b .line 100001,100001 : 0,0 '' - IL_009b: ldc.i4.m1 - IL_009c: ret + IL_0079: ldc.i4.m1 + IL_007a: ret .line 100001,100001 : 0,0 '' - IL_009d: ldc.i4.0 - IL_009e: ret + IL_007b: ldc.i4.0 + IL_007c: ret } // end of method R::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 62 (0x3e) + // Code size 59 (0x3b) .maxstack 7 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IEqualityComparer V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2) - .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_003c - - .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldc.i4 0x9e3779b9 - IL_0011: ldarg.1 - IL_0012: stloc.1 - IL_0013: ldarg.0 - IL_0014: ldfld int32 TestFunction17/R::y@ + .line 4,4 : 6,7 '' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0039 + + .line 100001,100001 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: ldfld int32 TestFunction17/R::y@ + IL_0016: ldloc.0 + IL_0017: ldc.i4.6 + IL_0018: shl IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add - IL_0020: add - IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldarg.1 - IL_0029: stloc.2 - IL_002a: ldarg.0 - IL_002b: ldfld int32 TestFunction17/R::x@ + IL_001a: ldc.i4.2 + IL_001b: shr + IL_001c: add + IL_001d: add + IL_001e: add + IL_001f: stloc.0 + IL_0020: ldc.i4 0x9e3779b9 + IL_0025: ldarg.1 + IL_0026: stloc.2 + IL_0027: ldarg.0 + IL_0028: ldfld int32 TestFunction17/R::x@ + IL_002d: ldloc.0 + IL_002e: ldc.i4.6 + IL_002f: shl IL_0030: ldloc.0 - IL_0031: ldc.i4.6 - IL_0032: shl - IL_0033: ldloc.0 - IL_0034: ldc.i4.2 - IL_0035: shr - IL_0036: add - IL_0037: add - IL_0038: add - IL_0039: stloc.0 - IL_003a: ldloc.0 - IL_003b: ret - - .line 100001,100001 : 0,0 '' - IL_003c: ldc.i4.0 - IL_003d: ret + IL_0031: ldc.i4.2 + IL_0032: shr + IL_0033: add + IL_0034: add + IL_0035: add + IL_0036: stloc.0 + IL_0037: ldloc.0 + IL_0038: ret + + .line 100001,100001 : 0,0 '' + IL_0039: ldc.i4.0 + IL_003a: ret } // end of method R::GetHashCode .method public hidebysig virtual final @@ -496,165 +447,144 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 77 (0x4d) + // Code size 66 (0x42) .maxstack 4 .locals init ([0] class TestFunction17/R V_0, [1] class TestFunction17/R V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2, [3] class [mscorlib]System.Collections.IEqualityComparer V_3) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003a - IL_0008: br.s IL_0045 + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst TestFunction17/R + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0038 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst TestFunction17/R - IL_0010: stloc.0 IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_0043 - + IL_0012: stloc.1 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.2 - IL_001b: stloc.2 - IL_001c: ldarg.0 - IL_001d: ldfld int32 TestFunction17/R::x@ - IL_0022: ldloc.1 - IL_0023: ldfld int32 TestFunction17/R::x@ - IL_0028: ceq - IL_002a: brfalse.s IL_002e - - IL_002c: br.s IL_0030 - - IL_002e: br.s IL_0041 + IL_0013: ldarg.2 + IL_0014: stloc.2 + IL_0015: ldarg.0 + IL_0016: ldfld int32 TestFunction17/R::x@ + IL_001b: ldloc.1 + IL_001c: ldfld int32 TestFunction17/R::x@ + IL_0021: ceq + IL_0023: brfalse.s IL_0036 .line 100001,100001 : 0,0 '' - IL_0030: ldarg.2 - IL_0031: stloc.3 - IL_0032: ldarg.0 - IL_0033: ldfld int32 TestFunction17/R::y@ - IL_0038: ldloc.1 - IL_0039: ldfld int32 TestFunction17/R::y@ - IL_003e: ceq - IL_0040: ret + IL_0025: ldarg.2 + IL_0026: stloc.3 + IL_0027: ldarg.0 + IL_0028: ldfld int32 TestFunction17/R::y@ + IL_002d: ldloc.1 + IL_002e: ldfld int32 TestFunction17/R::y@ + IL_0033: ceq + IL_0035: ret .line 100001,100001 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 100001,100001 : 0,0 '' - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0038: ldc.i4.0 + IL_0039: ret .line 100001,100001 : 0,0 '' - IL_0045: ldarg.1 - IL_0046: ldnull - IL_0047: cgt.un - IL_0049: ldc.i4.0 - IL_004a: ceq - IL_004c: ret + IL_003a: ldarg.1 + IL_003b: ldnull + IL_003c: cgt.un + IL_003e: ldc.i4.0 + IL_003f: ceq + IL_0041: ret } // end of method R::Equals .method public hidebysig virtual final instance bool Equals(class TestFunction17/R obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 65 (0x41) - .maxstack 4 + // Code size 54 (0x36) + .maxstack 8 + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0039 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002e .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0037 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_002c .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: ldfld int32 TestFunction17/R::x@ - IL_001a: ldarg.1 - IL_001b: ldfld int32 TestFunction17/R::x@ - IL_0020: bne.un.s IL_0024 - - IL_0022: br.s IL_0026 - - IL_0024: br.s IL_0035 + IL_000d: ldarg.0 + IL_000e: ldfld int32 TestFunction17/R::x@ + IL_0013: ldarg.1 + IL_0014: ldfld int32 TestFunction17/R::x@ + IL_0019: bne.un.s IL_002a .line 100001,100001 : 0,0 '' - IL_0026: ldarg.0 - IL_0027: ldfld int32 TestFunction17/R::y@ - IL_002c: ldarg.1 - IL_002d: ldfld int32 TestFunction17/R::y@ - IL_0032: ceq - IL_0034: ret + IL_001b: ldarg.0 + IL_001c: ldfld int32 TestFunction17/R::y@ + IL_0021: ldarg.1 + IL_0022: ldfld int32 TestFunction17/R::y@ + IL_0027: ceq + IL_0029: ret .line 100001,100001 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 100001,100001 : 0,0 '' - IL_0037: ldc.i4.0 - IL_0038: ret + IL_002c: ldc.i4.0 + IL_002d: ret .line 100001,100001 : 0,0 '' - IL_0039: ldarg.1 - IL_003a: ldnull - IL_003b: cgt.un - IL_003d: ldc.i4.0 - IL_003e: ceq - IL_0040: ret + IL_002e: ldarg.1 + IL_002f: ldnull + IL_0030: cgt.un + IL_0032: ldc.i4.0 + IL_0033: ceq + IL_0035: ret } // end of method R::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class TestFunction17/R V_0) .line 4,4 : 6,7 '' IL_0000: ldarg.1 IL_0001: isinst TestFunction17/R IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool TestFunction17/R::Equals(class TestFunction17/R) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool TestFunction17/R::Equals(class TestFunction17/R) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method R::Equals .property instance int32 x() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction19.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction19.il.bsl index f5468bf0fd6..a6b8e845ea4 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction19.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction19.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction19 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction19 { - // Offset: 0x00000000 Length: 0x00000352 + // Offset: 0x00000000 Length: 0x0000034E } .mresource public FSharpOptimizationData.TestFunction19 { // Offset: 0x00000358 Length: 0x00000100 } .module TestFunction19.exe -// MVID: {59B19208-A624-46AE-A745-03830892B159} +// MVID: {60B68B97-A624-46AE-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x016D0000 +// Image base: 0x00E60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ // Code size 23 (0x17) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction19.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction19.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction20.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction20.il.bsl index 5b65668cd8c..4126263a239 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction20.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction20.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction20 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction20 { - // Offset: 0x00000000 Length: 0x00000393 + // Offset: 0x00000000 Length: 0x0000038F } .mresource public FSharpOptimizationData.TestFunction20 { // Offset: 0x00000398 Length: 0x00000100 } .module TestFunction20.exe -// MVID: {59B19208-A643-44FB-A745-03830892B159} +// MVID: {60B68B97-A643-44FB-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01320000 +// Image base: 0x06B80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ .locals init ([0] int32 z, [1] int32 w) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction20.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction20.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction21.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction21.il.bsl index 30b59304c56..3b768e614ef 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction21.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction21.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction21 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction21 { - // Offset: 0x00000000 Length: 0x00000685 + // Offset: 0x00000000 Length: 0x00000675 } .mresource public FSharpOptimizationData.TestFunction21 { - // Offset: 0x00000690 Length: 0x000001CD + // Offset: 0x00000680 Length: 0x000001CD } .module TestFunction21.exe -// MVID: {59B19208-A643-45E6-A745-03830892B159} +// MVID: {611C52B3-A643-45E6-A745-0383B3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F80000 +// Image base: 0x06DD0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -174,7 +174,7 @@ instance int32 CompareTo(class TestFunction21/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 154 (0x9a) + // Code size 121 (0x79) .maxstack 4 .locals init ([0] class TestFunction21/U V_0, [1] class TestFunction21/U V_1, @@ -186,137 +186,114 @@ [7] int32 V_7, [8] int32 V_8) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction21.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_008c - + .line 4,4 : 6,7 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction21.fs' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_001a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006f - IL_0015: br IL_008a + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006d .line 100001,100001 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: pop + IL_000d: ldarg.0 + IL_000e: pop .line 100001,100001 : 0,0 '' - IL_001c: ldarg.0 - IL_001d: stloc.0 - IL_001e: ldarg.1 - IL_001f: stloc.1 - IL_0020: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0025: stloc.3 - IL_0026: ldloc.0 - IL_0027: ldfld int32 TestFunction21/U::item1 - IL_002c: stloc.s V_4 - IL_002e: ldloc.1 - IL_002f: ldfld int32 TestFunction21/U::item1 - IL_0034: stloc.s V_5 - IL_0036: ldloc.s V_4 - IL_0038: ldloc.s V_5 - IL_003a: bge.s IL_003e - - IL_003c: br.s IL_0040 - - IL_003e: br.s IL_0044 + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 TestFunction21/U::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 TestFunction21/U::item1 + IL_0027: stloc.s V_5 + .line 100001,100001 : 0,0 '' + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 100001,100001 : 0,0 '' - IL_0040: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_0041: nop - IL_0042: br.s IL_004b + IL_0030: nop + IL_0031: br.s IL_003a .line 100001,100001 : 0,0 '' - IL_0044: ldloc.s V_4 - IL_0046: ldloc.s V_5 - IL_0048: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 100001,100001 : 0,0 '' - IL_004a: nop + IL_0039: nop .line 100001,100001 : 0,0 '' - IL_004b: stloc.2 - IL_004c: ldloc.2 - IL_004d: ldc.i4.0 - IL_004e: bge.s IL_0052 - - IL_0050: br.s IL_0054 - - IL_0052: br.s IL_0056 - + IL_003a: stloc.2 .line 100001,100001 : 0,0 '' - IL_0054: ldloc.2 - IL_0055: ret + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 100001,100001 : 0,0 '' - IL_0056: ldloc.2 - IL_0057: ldc.i4.0 - IL_0058: ble.s IL_005c - - IL_005a: br.s IL_005e - - IL_005c: br.s IL_0060 + IL_003f: ldloc.2 + IL_0040: ret .line 100001,100001 : 0,0 '' - IL_005e: ldloc.2 - IL_005f: ret + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 100001,100001 : 0,0 '' - IL_0060: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0065: stloc.s V_6 - IL_0067: ldloc.0 - IL_0068: ldfld int32 TestFunction21/U::item2 - IL_006d: stloc.s V_7 - IL_006f: ldloc.1 - IL_0070: ldfld int32 TestFunction21/U::item2 - IL_0075: stloc.s V_8 - IL_0077: ldloc.s V_7 - IL_0079: ldloc.s V_8 - IL_007b: bge.s IL_007f - - IL_007d: br.s IL_0081 - - IL_007f: br.s IL_0083 + IL_0045: ldloc.2 + IL_0046: ret .line 100001,100001 : 0,0 '' - IL_0081: ldc.i4.m1 - IL_0082: ret - + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.s V_6 + IL_004e: ldloc.0 + IL_004f: ldfld int32 TestFunction21/U::item2 + IL_0054: stloc.s V_7 + IL_0056: ldloc.1 + IL_0057: ldfld int32 TestFunction21/U::item2 + IL_005c: stloc.s V_8 .line 100001,100001 : 0,0 '' - IL_0083: ldloc.s V_7 - IL_0085: ldloc.s V_8 - IL_0087: cgt - IL_0089: ret + IL_005e: ldloc.s V_7 + IL_0060: ldloc.s V_8 + IL_0062: bge.s IL_0066 .line 100001,100001 : 0,0 '' - IL_008a: ldc.i4.1 - IL_008b: ret + IL_0064: ldc.i4.m1 + IL_0065: ret .line 100001,100001 : 0,0 '' - IL_008c: ldarg.1 - IL_008d: ldnull - IL_008e: cgt.un - IL_0090: brfalse.s IL_0094 + IL_0066: ldloc.s V_7 + IL_0068: ldloc.s V_8 + IL_006a: cgt + IL_006c: ret - IL_0092: br.s IL_0096 + .line 100001,100001 : 0,0 '' + IL_006d: ldc.i4.1 + IL_006e: ret - IL_0094: br.s IL_0098 + .line 100001,100001 : 0,0 '' + IL_006f: ldarg.1 + IL_0070: ldnull + IL_0071: cgt.un + IL_0073: brfalse.s IL_0077 .line 100001,100001 : 0,0 '' - IL_0096: ldc.i4.m1 - IL_0097: ret + IL_0075: ldc.i4.m1 + IL_0076: ret .line 100001,100001 : 0,0 '' - IL_0098: ldc.i4.0 - IL_0099: ret + IL_0077: ldc.i4.0 + IL_0078: ret } // end of method U::CompareTo .method public hidebysig virtual final @@ -338,7 +315,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 164 (0xa4) + // Code size 130 (0x82) .maxstack 4 .locals init ([0] class TestFunction21/U V_0, [1] class TestFunction21/U V_1, @@ -354,206 +331,181 @@ IL_0000: ldarg.1 IL_0001: unbox.any TestFunction21/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un - IL_000b: brfalse.s IL_000f - - IL_000d: br.s IL_0014 - - IL_000f: br IL_0091 + IL_000b: brfalse.s IL_0073 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.1 - IL_0015: unbox.any TestFunction21/U - IL_001a: ldnull - IL_001b: cgt.un - IL_001d: brfalse.s IL_0021 - - IL_001f: br.s IL_0026 - - IL_0021: br IL_008f + IL_000d: ldarg.1 + IL_000e: unbox.any TestFunction21/U + IL_0013: ldnull + IL_0014: cgt.un + IL_0016: brfalse.s IL_0071 .line 100001,100001 : 0,0 '' - IL_0026: ldarg.0 - IL_0027: pop + IL_0018: ldarg.0 + IL_0019: pop .line 100001,100001 : 0,0 '' - IL_0028: ldarg.0 - IL_0029: stloc.1 - IL_002a: ldloc.0 - IL_002b: stloc.2 - IL_002c: ldarg.2 - IL_002d: stloc.s V_4 - IL_002f: ldloc.1 - IL_0030: ldfld int32 TestFunction21/U::item1 - IL_0035: stloc.s V_5 - IL_0037: ldloc.2 - IL_0038: ldfld int32 TestFunction21/U::item1 - IL_003d: stloc.s V_6 - IL_003f: ldloc.s V_5 - IL_0041: ldloc.s V_6 - IL_0043: bge.s IL_0047 - - IL_0045: br.s IL_0049 - - IL_0047: br.s IL_004d + IL_001a: ldarg.0 + IL_001b: stloc.1 + IL_001c: ldloc.0 + IL_001d: stloc.2 + IL_001e: ldarg.2 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 TestFunction21/U::item1 + IL_0027: stloc.s V_5 + IL_0029: ldloc.2 + IL_002a: ldfld int32 TestFunction21/U::item1 + IL_002f: stloc.s V_6 + .line 100001,100001 : 0,0 '' + IL_0031: ldloc.s V_5 + IL_0033: ldloc.s V_6 + IL_0035: bge.s IL_003b .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.m1 + IL_0037: ldc.i4.m1 .line 100001,100001 : 0,0 '' - IL_004a: nop - IL_004b: br.s IL_0054 + IL_0038: nop + IL_0039: br.s IL_0042 .line 100001,100001 : 0,0 '' - IL_004d: ldloc.s V_5 - IL_004f: ldloc.s V_6 - IL_0051: cgt + IL_003b: ldloc.s V_5 + IL_003d: ldloc.s V_6 + IL_003f: cgt .line 100001,100001 : 0,0 '' - IL_0053: nop + IL_0041: nop .line 100001,100001 : 0,0 '' - IL_0054: stloc.3 - IL_0055: ldloc.3 - IL_0056: ldc.i4.0 - IL_0057: bge.s IL_005b - - IL_0059: br.s IL_005d - - IL_005b: br.s IL_005f - + IL_0042: stloc.3 .line 100001,100001 : 0,0 '' - IL_005d: ldloc.3 - IL_005e: ret + IL_0043: ldloc.3 + IL_0044: ldc.i4.0 + IL_0045: bge.s IL_0049 .line 100001,100001 : 0,0 '' - IL_005f: ldloc.3 - IL_0060: ldc.i4.0 - IL_0061: ble.s IL_0065 - - IL_0063: br.s IL_0067 - - IL_0065: br.s IL_0069 + IL_0047: ldloc.3 + IL_0048: ret .line 100001,100001 : 0,0 '' - IL_0067: ldloc.3 - IL_0068: ret + IL_0049: ldloc.3 + IL_004a: ldc.i4.0 + IL_004b: ble.s IL_004f .line 100001,100001 : 0,0 '' - IL_0069: ldarg.2 - IL_006a: stloc.s V_7 - IL_006c: ldloc.1 - IL_006d: ldfld int32 TestFunction21/U::item2 - IL_0072: stloc.s V_8 - IL_0074: ldloc.2 - IL_0075: ldfld int32 TestFunction21/U::item2 - IL_007a: stloc.s V_9 - IL_007c: ldloc.s V_8 - IL_007e: ldloc.s V_9 - IL_0080: bge.s IL_0084 - - IL_0082: br.s IL_0086 - - IL_0084: br.s IL_0088 + IL_004d: ldloc.3 + IL_004e: ret .line 100001,100001 : 0,0 '' - IL_0086: ldc.i4.m1 - IL_0087: ret - + IL_004f: ldarg.2 + IL_0050: stloc.s V_7 + IL_0052: ldloc.1 + IL_0053: ldfld int32 TestFunction21/U::item2 + IL_0058: stloc.s V_8 + IL_005a: ldloc.2 + IL_005b: ldfld int32 TestFunction21/U::item2 + IL_0060: stloc.s V_9 .line 100001,100001 : 0,0 '' - IL_0088: ldloc.s V_8 - IL_008a: ldloc.s V_9 - IL_008c: cgt - IL_008e: ret + IL_0062: ldloc.s V_8 + IL_0064: ldloc.s V_9 + IL_0066: bge.s IL_006a .line 100001,100001 : 0,0 '' - IL_008f: ldc.i4.1 - IL_0090: ret + IL_0068: ldc.i4.m1 + IL_0069: ret .line 100001,100001 : 0,0 '' - IL_0091: ldarg.1 - IL_0092: unbox.any TestFunction21/U - IL_0097: ldnull - IL_0098: cgt.un - IL_009a: brfalse.s IL_009e + IL_006a: ldloc.s V_8 + IL_006c: ldloc.s V_9 + IL_006e: cgt + IL_0070: ret - IL_009c: br.s IL_00a0 + .line 100001,100001 : 0,0 '' + IL_0071: ldc.i4.1 + IL_0072: ret - IL_009e: br.s IL_00a2 + .line 100001,100001 : 0,0 '' + IL_0073: ldarg.1 + IL_0074: unbox.any TestFunction21/U + IL_0079: ldnull + IL_007a: cgt.un + IL_007c: brfalse.s IL_0080 .line 100001,100001 : 0,0 '' - IL_00a0: ldc.i4.m1 - IL_00a1: ret + IL_007e: ldc.i4.m1 + IL_007f: ret .line 100001,100001 : 0,0 '' - IL_00a2: ldc.i4.0 - IL_00a3: ret + IL_0080: ldc.i4.0 + IL_0081: ret } // end of method U::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 68 (0x44) + // Code size 65 (0x41) .maxstack 7 .locals init ([0] int32 V_0, [1] class TestFunction21/U V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2, [3] class [mscorlib]System.Collections.IEqualityComparer V_3) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0042 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003f .line 100001,100001 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldarg.0 - IL_000d: pop + IL_0007: ldc.i4.0 + IL_0008: stloc.0 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.1 - IL_0010: ldc.i4.0 - IL_0011: stloc.0 - IL_0012: ldc.i4 0x9e3779b9 - IL_0017: ldarg.1 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld int32 TestFunction21/U::item2 + IL_0009: ldarg.0 + IL_000a: pop + .line 100001,100001 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldarg.1 + IL_0015: stloc.2 + IL_0016: ldloc.1 + IL_0017: ldfld int32 TestFunction21/U::item2 + IL_001c: ldloc.0 + IL_001d: ldc.i4.6 + IL_001e: shl IL_001f: ldloc.0 - IL_0020: ldc.i4.6 - IL_0021: shl - IL_0022: ldloc.0 - IL_0023: ldc.i4.2 - IL_0024: shr - IL_0025: add - IL_0026: add - IL_0027: add - IL_0028: stloc.0 - IL_0029: ldc.i4 0x9e3779b9 - IL_002e: ldarg.1 - IL_002f: stloc.3 - IL_0030: ldloc.1 - IL_0031: ldfld int32 TestFunction21/U::item1 + IL_0020: ldc.i4.2 + IL_0021: shr + IL_0022: add + IL_0023: add + IL_0024: add + IL_0025: stloc.0 + IL_0026: ldc.i4 0x9e3779b9 + IL_002b: ldarg.1 + IL_002c: stloc.3 + IL_002d: ldloc.1 + IL_002e: ldfld int32 TestFunction21/U::item1 + IL_0033: ldloc.0 + IL_0034: ldc.i4.6 + IL_0035: shl IL_0036: ldloc.0 - IL_0037: ldc.i4.6 - IL_0038: shl - IL_0039: ldloc.0 - IL_003a: ldc.i4.2 - IL_003b: shr - IL_003c: add - IL_003d: add - IL_003e: add - IL_003f: stloc.0 - IL_0040: ldloc.0 - IL_0041: ret + IL_0037: ldc.i4.2 + IL_0038: shr + IL_0039: add + IL_003a: add + IL_003b: add + IL_003c: stloc.0 + IL_003d: ldloc.0 + IL_003e: ret .line 100001,100001 : 0,0 '' - IL_0042: ldc.i4.0 - IL_0043: ret + IL_003f: ldc.i4.0 + IL_0040: ret } // end of method U::GetHashCode .method public hidebysig virtual final @@ -574,7 +526,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 85 (0x55) + // Code size 74 (0x4a) .maxstack 4 .locals init ([0] class TestFunction21/U V_0, [1] class TestFunction21/U V_1, @@ -582,175 +534,156 @@ [3] class TestFunction21/U V_3, [4] class [mscorlib]System.Collections.IEqualityComparer V_4, [5] class [mscorlib]System.Collections.IEqualityComparer V_5) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0042 - IL_0008: br.s IL_004d + .line 100001,100001 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst TestFunction21/U + IL_000d: stloc.0 + .line 100001,100001 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0040 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst TestFunction21/U - IL_0010: stloc.0 IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_004b - + IL_0012: stloc.1 .line 100001,100001 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.0 - IL_001b: pop + IL_0013: ldarg.0 + IL_0014: pop .line 100001,100001 : 0,0 '' - IL_001c: ldarg.0 - IL_001d: stloc.2 - IL_001e: ldloc.1 - IL_001f: stloc.3 - IL_0020: ldarg.2 - IL_0021: stloc.s V_4 - IL_0023: ldloc.2 - IL_0024: ldfld int32 TestFunction21/U::item1 - IL_0029: ldloc.3 - IL_002a: ldfld int32 TestFunction21/U::item1 - IL_002f: ceq - IL_0031: brfalse.s IL_0035 - - IL_0033: br.s IL_0037 - - IL_0035: br.s IL_0049 + IL_0015: ldarg.0 + IL_0016: stloc.2 + IL_0017: ldloc.1 + IL_0018: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0019: ldarg.2 + IL_001a: stloc.s V_4 + IL_001c: ldloc.2 + IL_001d: ldfld int32 TestFunction21/U::item1 + IL_0022: ldloc.3 + IL_0023: ldfld int32 TestFunction21/U::item1 + IL_0028: ceq + IL_002a: brfalse.s IL_003e .line 100001,100001 : 0,0 '' - IL_0037: ldarg.2 - IL_0038: stloc.s V_5 - IL_003a: ldloc.2 - IL_003b: ldfld int32 TestFunction21/U::item2 - IL_0040: ldloc.3 - IL_0041: ldfld int32 TestFunction21/U::item2 - IL_0046: ceq - IL_0048: ret + IL_002c: ldarg.2 + IL_002d: stloc.s V_5 + IL_002f: ldloc.2 + IL_0030: ldfld int32 TestFunction21/U::item2 + IL_0035: ldloc.3 + IL_0036: ldfld int32 TestFunction21/U::item2 + IL_003b: ceq + IL_003d: ret .line 100001,100001 : 0,0 '' - IL_0049: ldc.i4.0 - IL_004a: ret + IL_003e: ldc.i4.0 + IL_003f: ret .line 100001,100001 : 0,0 '' - IL_004b: ldc.i4.0 - IL_004c: ret + IL_0040: ldc.i4.0 + IL_0041: ret .line 100001,100001 : 0,0 '' - IL_004d: ldarg.1 - IL_004e: ldnull - IL_004f: cgt.un - IL_0051: ldc.i4.0 - IL_0052: ceq - IL_0054: ret + IL_0042: ldarg.1 + IL_0043: ldnull + IL_0044: cgt.un + IL_0046: ldc.i4.0 + IL_0047: ceq + IL_0049: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(class TestFunction21/U obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 71 (0x47) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class TestFunction21/U V_0, [1] class TestFunction21/U V_1) + .line 4,4 : 6,7 '' + IL_0000: nop .line 100001,100001 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_003f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 100001,100001 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_003d + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 100001,100001 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: pop + IL_000d: ldarg.0 + IL_000e: pop .line 100001,100001 : 0,0 '' - IL_0016: ldarg.0 - IL_0017: stloc.0 - IL_0018: ldarg.1 - IL_0019: stloc.1 - IL_001a: ldloc.0 - IL_001b: ldfld int32 TestFunction21/U::item1 - IL_0020: ldloc.1 - IL_0021: ldfld int32 TestFunction21/U::item1 - IL_0026: bne.un.s IL_002a - - IL_0028: br.s IL_002c - - IL_002a: br.s IL_003b + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 100001,100001 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld int32 TestFunction21/U::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 TestFunction21/U::item1 + IL_001f: bne.un.s IL_0030 .line 100001,100001 : 0,0 '' - IL_002c: ldloc.0 - IL_002d: ldfld int32 TestFunction21/U::item2 - IL_0032: ldloc.1 - IL_0033: ldfld int32 TestFunction21/U::item2 - IL_0038: ceq - IL_003a: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 TestFunction21/U::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 TestFunction21/U::item2 + IL_002d: ceq + IL_002f: ret .line 100001,100001 : 0,0 '' - IL_003b: ldc.i4.0 - IL_003c: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 100001,100001 : 0,0 '' - IL_003d: ldc.i4.0 - IL_003e: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 100001,100001 : 0,0 '' - IL_003f: ldarg.1 - IL_0040: ldnull - IL_0041: cgt.un - IL_0043: ldc.i4.0 - IL_0044: ceq - IL_0046: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method U::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class TestFunction21/U V_0) .line 4,4 : 6,7 '' IL_0000: ldarg.1 IL_0001: isinst TestFunction21/U IL_0006: stloc.0 + .line 100001,100001 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 100001,100001 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool TestFunction21/U::Equals(class TestFunction21/U) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool TestFunction21/U::Equals(class TestFunction21/U) + IL_0011: ret .line 100001,100001 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method U::Equals .property instance int32 Tag() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction23.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction23.il.bsl index fffbcac4e2f..53cfd72c55c 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction23.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction23.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction23 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction23 { - // Offset: 0x00000000 Length: 0x00000346 + // Offset: 0x00000000 Length: 0x0000033A } .mresource public FSharpOptimizationData.TestFunction23 { - // Offset: 0x00000350 Length: 0x000000E3 + // Offset: 0x00000340 Length: 0x000000E3 } .module TestFunction23.exe -// MVID: {59B19208-A643-451C-A745-03830892B159} +// MVID: {6124063B-A643-451C-A745-03833B062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02D60000 +// Image base: 0x05750000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,7 +63,7 @@ // Code size 31 (0x1f) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction23.fs' + .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction23.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 @@ -83,16 +83,20 @@ .method public hidebysig instance string M() cil managed { - // Code size 18 (0x12) - .maxstack 8 - .line 9,9 : 23,30 '' + // Code size 20 (0x14) + .maxstack 4 + .locals init ([0] class TestFunction23/C self) + .line 100001,100001 : 0,0 '' IL_0000: ldarg.0 - IL_0001: ldfld string TestFunction23/C::x@8 - IL_0006: ldarg.0 - IL_0007: callvirt instance string TestFunction23/C::g() - IL_000c: call string [mscorlib]System.String::Concat(string, + IL_0001: stloc.0 + .line 9,9 : 23,30 '' + IL_0002: ldarg.0 + IL_0003: ldfld string TestFunction23/C::x@8 + IL_0008: ldarg.0 + IL_0009: callvirt instance string TestFunction23/C::g() + IL_000e: call string [mscorlib]System.String::Concat(string, string) - IL_0011: ret + IL_0013: ret } // end of method C::M .method assembly hidebysig instance string @@ -112,6 +116,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit g@13 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class TestFunction23/g@13 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -142,6 +147,16 @@ IL_0021: ret } // end of method g@13::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void TestFunction23/g@13::.ctor() + IL_0005: stsfld class TestFunction23/g@13 TestFunction23/g@13::@_instance + IL_000a: ret + } // end of method g@13::.cctor + } // end of class g@13 .method public static class [mscorlib]System.Tuple`2 @@ -151,7 +166,7 @@ .maxstack 5 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 g) .line 100001,100001 : 0,0 '' - IL_0000: newobj instance void TestFunction23/g@13::.ctor() + IL_0000: ldsfld class TestFunction23/g@13 TestFunction23/g@13::@_instance IL_0005: stloc.0 .line 15,15 : 5,13 '' IL_0006: ldloc.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction24.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction24.il.bsl index bdbd5f41fc7..d946a530d89 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction24.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction24.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction24 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction24 { - // Offset: 0x00000000 Length: 0x0000075B + // Offset: 0x00000000 Length: 0x00000742 } .mresource public FSharpOptimizationData.TestFunction24 { - // Offset: 0x00000760 Length: 0x00000228 + // Offset: 0x00000748 Length: 0x00000228 } .module TestFunction24.exe -// MVID: {59B19208-A643-4587-A745-03830892B159} +// MVID: {611C52B3-A643-4587-A745-0383B3521C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x07110000 // =============== CLASS MEMBERS DECLARATION =================== @@ -141,7 +141,7 @@ instance int32 CompareTo(class TestFunction24/Point obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 142 (0x8e) + // Code size 109 (0x6d) .maxstack 4 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IComparer V_1, @@ -151,130 +151,107 @@ [5] int32 V_5, [6] int32 V_6) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction24.fs' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000d - - IL_0008: br IL_0080 - + .line 4,4 : 6,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction24.fs' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_000d: ldarg.1 - IL_000e: ldnull - IL_000f: cgt.un - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_001a - - IL_0015: br IL_007e + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0063 .line 16707566,16707566 : 0,0 '' - IL_001a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_001f: stloc.1 - IL_0020: ldarg.0 - IL_0021: ldfld int32 TestFunction24/Point::x@ - IL_0026: stloc.2 - IL_0027: ldarg.1 - IL_0028: ldfld int32 TestFunction24/Point::x@ - IL_002d: stloc.3 - IL_002e: ldloc.2 - IL_002f: ldloc.3 - IL_0030: bge.s IL_0034 - - IL_0032: br.s IL_0036 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0061 - IL_0034: br.s IL_003a + .line 16707566,16707566 : 0,0 '' + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 TestFunction24/Point::x@ + IL_0019: stloc.2 + IL_001a: ldarg.1 + IL_001b: ldfld int32 TestFunction24/Point::x@ + IL_0020: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: bge.s IL_0029 .line 16707566,16707566 : 0,0 '' - IL_0036: ldc.i4.m1 + IL_0025: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_0037: nop - IL_0038: br.s IL_003f + IL_0026: nop + IL_0027: br.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_003a: ldloc.2 - IL_003b: ldloc.3 - IL_003c: cgt + IL_0029: ldloc.2 + IL_002a: ldloc.3 + IL_002b: cgt .line 16707566,16707566 : 0,0 '' - IL_003e: nop + IL_002d: nop .line 16707566,16707566 : 0,0 '' - IL_003f: stloc.0 - IL_0040: ldloc.0 - IL_0041: ldc.i4.0 - IL_0042: bge.s IL_0046 - - IL_0044: br.s IL_0048 - - IL_0046: br.s IL_004a - + IL_002e: stloc.0 .line 16707566,16707566 : 0,0 '' - IL_0048: ldloc.0 - IL_0049: ret + IL_002f: ldloc.0 + IL_0030: ldc.i4.0 + IL_0031: bge.s IL_0035 .line 16707566,16707566 : 0,0 '' - IL_004a: ldloc.0 - IL_004b: ldc.i4.0 - IL_004c: ble.s IL_0050 - - IL_004e: br.s IL_0052 - - IL_0050: br.s IL_0054 + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0052: ldloc.0 - IL_0053: ret + IL_0035: ldloc.0 + IL_0036: ldc.i4.0 + IL_0037: ble.s IL_003b .line 16707566,16707566 : 0,0 '' - IL_0054: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0059: stloc.s V_4 - IL_005b: ldarg.0 - IL_005c: ldfld int32 TestFunction24/Point::y@ - IL_0061: stloc.s V_5 - IL_0063: ldarg.1 - IL_0064: ldfld int32 TestFunction24/Point::y@ - IL_0069: stloc.s V_6 - IL_006b: ldloc.s V_5 - IL_006d: ldloc.s V_6 - IL_006f: bge.s IL_0073 - - IL_0071: br.s IL_0075 - - IL_0073: br.s IL_0077 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.m1 - IL_0076: ret - + IL_003b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0040: stloc.s V_4 + IL_0042: ldarg.0 + IL_0043: ldfld int32 TestFunction24/Point::y@ + IL_0048: stloc.s V_5 + IL_004a: ldarg.1 + IL_004b: ldfld int32 TestFunction24/Point::y@ + IL_0050: stloc.s V_6 .line 16707566,16707566 : 0,0 '' - IL_0077: ldloc.s V_5 - IL_0079: ldloc.s V_6 - IL_007b: cgt - IL_007d: ret + IL_0052: ldloc.s V_5 + IL_0054: ldloc.s V_6 + IL_0056: bge.s IL_005a .line 16707566,16707566 : 0,0 '' - IL_007e: ldc.i4.1 - IL_007f: ret + IL_0058: ldc.i4.m1 + IL_0059: ret .line 16707566,16707566 : 0,0 '' - IL_0080: ldarg.1 - IL_0081: ldnull - IL_0082: cgt.un - IL_0084: brfalse.s IL_0088 + IL_005a: ldloc.s V_5 + IL_005c: ldloc.s V_6 + IL_005e: cgt + IL_0060: ret - IL_0086: br.s IL_008a + .line 16707566,16707566 : 0,0 '' + IL_0061: ldc.i4.1 + IL_0062: ret - IL_0088: br.s IL_008c + .line 16707566,16707566 : 0,0 '' + IL_0063: ldarg.1 + IL_0064: ldnull + IL_0065: cgt.un + IL_0067: brfalse.s IL_006b .line 16707566,16707566 : 0,0 '' - IL_008a: ldc.i4.m1 - IL_008b: ret + IL_0069: ldc.i4.m1 + IL_006a: ret .line 16707566,16707566 : 0,0 '' - IL_008c: ldc.i4.0 - IL_008d: ret + IL_006b: ldc.i4.0 + IL_006c: ret } // end of method Point::CompareTo .method public hidebysig virtual final @@ -296,7 +273,7 @@ class [mscorlib]System.Collections.IComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 159 (0x9f) + // Code size 125 (0x7d) .maxstack 4 .locals init ([0] class TestFunction24/Point V_0, [1] class TestFunction24/Point V_1, @@ -313,191 +290,165 @@ IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: stloc.1 + .line 16707566,16707566 : 0,0 '' IL_0009: ldarg.0 IL_000a: ldnull IL_000b: cgt.un - IL_000d: brfalse.s IL_0011 - - IL_000f: br.s IL_0016 - - IL_0011: br IL_008c + IL_000d: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0016: ldarg.1 - IL_0017: unbox.any TestFunction24/Point - IL_001c: ldnull - IL_001d: cgt.un - IL_001f: brfalse.s IL_0023 - - IL_0021: br.s IL_0028 - - IL_0023: br IL_008a + IL_000f: ldarg.1 + IL_0010: unbox.any TestFunction24/Point + IL_0015: ldnull + IL_0016: cgt.un + IL_0018: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_0028: ldarg.2 - IL_0029: stloc.3 - IL_002a: ldarg.0 - IL_002b: ldfld int32 TestFunction24/Point::x@ - IL_0030: stloc.s V_4 - IL_0032: ldloc.1 - IL_0033: ldfld int32 TestFunction24/Point::x@ - IL_0038: stloc.s V_5 - IL_003a: ldloc.s V_4 - IL_003c: ldloc.s V_5 - IL_003e: bge.s IL_0042 - - IL_0040: br.s IL_0044 - - IL_0042: br.s IL_0048 + IL_001a: ldarg.2 + IL_001b: stloc.3 + IL_001c: ldarg.0 + IL_001d: ldfld int32 TestFunction24/Point::x@ + IL_0022: stloc.s V_4 + IL_0024: ldloc.1 + IL_0025: ldfld int32 TestFunction24/Point::x@ + IL_002a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_002c: ldloc.s V_4 + IL_002e: ldloc.s V_5 + IL_0030: bge.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0044: ldc.i4.m1 + IL_0032: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_0045: nop - IL_0046: br.s IL_004f + IL_0033: nop + IL_0034: br.s IL_003d .line 16707566,16707566 : 0,0 '' - IL_0048: ldloc.s V_4 - IL_004a: ldloc.s V_5 - IL_004c: cgt + IL_0036: ldloc.s V_4 + IL_0038: ldloc.s V_5 + IL_003a: cgt .line 16707566,16707566 : 0,0 '' - IL_004e: nop + IL_003c: nop .line 16707566,16707566 : 0,0 '' - IL_004f: stloc.2 - IL_0050: ldloc.2 - IL_0051: ldc.i4.0 - IL_0052: bge.s IL_0056 - - IL_0054: br.s IL_0058 - - IL_0056: br.s IL_005a - + IL_003d: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0058: ldloc.2 - IL_0059: ret + IL_003e: ldloc.2 + IL_003f: ldc.i4.0 + IL_0040: bge.s IL_0044 .line 16707566,16707566 : 0,0 '' - IL_005a: ldloc.2 - IL_005b: ldc.i4.0 - IL_005c: ble.s IL_0060 - - IL_005e: br.s IL_0062 - - IL_0060: br.s IL_0064 + IL_0042: ldloc.2 + IL_0043: ret .line 16707566,16707566 : 0,0 '' - IL_0062: ldloc.2 - IL_0063: ret + IL_0044: ldloc.2 + IL_0045: ldc.i4.0 + IL_0046: ble.s IL_004a .line 16707566,16707566 : 0,0 '' - IL_0064: ldarg.2 - IL_0065: stloc.s V_6 - IL_0067: ldarg.0 - IL_0068: ldfld int32 TestFunction24/Point::y@ - IL_006d: stloc.s V_7 - IL_006f: ldloc.1 - IL_0070: ldfld int32 TestFunction24/Point::y@ - IL_0075: stloc.s V_8 - IL_0077: ldloc.s V_7 - IL_0079: ldloc.s V_8 - IL_007b: bge.s IL_007f - - IL_007d: br.s IL_0081 - - IL_007f: br.s IL_0083 + IL_0048: ldloc.2 + IL_0049: ret .line 16707566,16707566 : 0,0 '' - IL_0081: ldc.i4.m1 - IL_0082: ret - + IL_004a: ldarg.2 + IL_004b: stloc.s V_6 + IL_004d: ldarg.0 + IL_004e: ldfld int32 TestFunction24/Point::y@ + IL_0053: stloc.s V_7 + IL_0055: ldloc.1 + IL_0056: ldfld int32 TestFunction24/Point::y@ + IL_005b: stloc.s V_8 .line 16707566,16707566 : 0,0 '' - IL_0083: ldloc.s V_7 - IL_0085: ldloc.s V_8 - IL_0087: cgt - IL_0089: ret + IL_005d: ldloc.s V_7 + IL_005f: ldloc.s V_8 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_008a: ldc.i4.1 - IL_008b: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_008c: ldarg.1 - IL_008d: unbox.any TestFunction24/Point - IL_0092: ldnull - IL_0093: cgt.un - IL_0095: brfalse.s IL_0099 + IL_0065: ldloc.s V_7 + IL_0067: ldloc.s V_8 + IL_0069: cgt + IL_006b: ret - IL_0097: br.s IL_009b + .line 16707566,16707566 : 0,0 '' + IL_006c: ldc.i4.1 + IL_006d: ret - IL_0099: br.s IL_009d + .line 16707566,16707566 : 0,0 '' + IL_006e: ldarg.1 + IL_006f: unbox.any TestFunction24/Point + IL_0074: ldnull + IL_0075: cgt.un + IL_0077: brfalse.s IL_007b .line 16707566,16707566 : 0,0 '' - IL_009b: ldc.i4.m1 - IL_009c: ret + IL_0079: ldc.i4.m1 + IL_007a: ret .line 16707566,16707566 : 0,0 '' - IL_009d: ldc.i4.0 - IL_009e: ret + IL_007b: ldc.i4.0 + IL_007c: ret } // end of method Point::CompareTo .method public hidebysig virtual final instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 62 (0x3e) + // Code size 59 (0x3b) .maxstack 7 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IEqualityComparer V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_003c - - .line 16707566,16707566 : 0,0 '' - IL_000a: ldc.i4.0 - IL_000b: stloc.0 - IL_000c: ldc.i4 0x9e3779b9 - IL_0011: ldarg.1 - IL_0012: stloc.1 - IL_0013: ldarg.0 - IL_0014: ldfld int32 TestFunction24/Point::y@ + .line 4,4 : 6,11 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0039 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.1 + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: ldfld int32 TestFunction24/Point::y@ + IL_0016: ldloc.0 + IL_0017: ldc.i4.6 + IL_0018: shl IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add - IL_0020: add - IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldarg.1 - IL_0029: stloc.2 - IL_002a: ldarg.0 - IL_002b: ldfld int32 TestFunction24/Point::x@ + IL_001a: ldc.i4.2 + IL_001b: shr + IL_001c: add + IL_001d: add + IL_001e: add + IL_001f: stloc.0 + IL_0020: ldc.i4 0x9e3779b9 + IL_0025: ldarg.1 + IL_0026: stloc.2 + IL_0027: ldarg.0 + IL_0028: ldfld int32 TestFunction24/Point::x@ + IL_002d: ldloc.0 + IL_002e: ldc.i4.6 + IL_002f: shl IL_0030: ldloc.0 - IL_0031: ldc.i4.6 - IL_0032: shl - IL_0033: ldloc.0 - IL_0034: ldc.i4.2 - IL_0035: shr - IL_0036: add - IL_0037: add - IL_0038: add - IL_0039: stloc.0 - IL_003a: ldloc.0 - IL_003b: ret - - .line 16707566,16707566 : 0,0 '' - IL_003c: ldc.i4.0 - IL_003d: ret + IL_0031: ldc.i4.2 + IL_0032: shr + IL_0033: add + IL_0034: add + IL_0035: add + IL_0036: stloc.0 + IL_0037: ldloc.0 + IL_0038: ret + + .line 16707566,16707566 : 0,0 '' + IL_0039: ldc.i4.0 + IL_003a: ret } // end of method Point::GetHashCode .method public hidebysig virtual final @@ -518,165 +469,144 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 77 (0x4d) + // Code size 66 (0x42) .maxstack 4 .locals init ([0] class TestFunction24/Point V_0, [1] class TestFunction24/Point V_1, [2] class [mscorlib]System.Collections.IEqualityComparer V_2, [3] class [mscorlib]System.Collections.IEqualityComparer V_3) + .line 4,4 : 6,11 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003a - IL_0008: br.s IL_0045 + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst TestFunction24/Point + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: isinst TestFunction24/Point - IL_0010: stloc.0 IL_0011: ldloc.0 - IL_0012: brfalse.s IL_0016 - - IL_0014: br.s IL_0018 - - IL_0016: br.s IL_0043 - + IL_0012: stloc.1 .line 16707566,16707566 : 0,0 '' - IL_0018: ldloc.0 - IL_0019: stloc.1 - IL_001a: ldarg.2 - IL_001b: stloc.2 - IL_001c: ldarg.0 - IL_001d: ldfld int32 TestFunction24/Point::x@ - IL_0022: ldloc.1 - IL_0023: ldfld int32 TestFunction24/Point::x@ - IL_0028: ceq - IL_002a: brfalse.s IL_002e - - IL_002c: br.s IL_0030 - - IL_002e: br.s IL_0041 + IL_0013: ldarg.2 + IL_0014: stloc.2 + IL_0015: ldarg.0 + IL_0016: ldfld int32 TestFunction24/Point::x@ + IL_001b: ldloc.1 + IL_001c: ldfld int32 TestFunction24/Point::x@ + IL_0021: ceq + IL_0023: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0030: ldarg.2 - IL_0031: stloc.3 - IL_0032: ldarg.0 - IL_0033: ldfld int32 TestFunction24/Point::y@ - IL_0038: ldloc.1 - IL_0039: ldfld int32 TestFunction24/Point::y@ - IL_003e: ceq - IL_0040: ret + IL_0025: ldarg.2 + IL_0026: stloc.3 + IL_0027: ldarg.0 + IL_0028: ldfld int32 TestFunction24/Point::y@ + IL_002d: ldloc.1 + IL_002e: ldfld int32 TestFunction24/Point::y@ + IL_0033: ceq + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0038: ldc.i4.0 + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0045: ldarg.1 - IL_0046: ldnull - IL_0047: cgt.un - IL_0049: ldc.i4.0 - IL_004a: ceq - IL_004c: ret + IL_003a: ldarg.1 + IL_003b: ldnull + IL_003c: cgt.un + IL_003e: ldc.i4.0 + IL_003f: ceq + IL_0041: ret } // end of method Point::Equals .method public hidebysig virtual final instance bool Equals(class TestFunction24/Point obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 65 (0x41) - .maxstack 4 + // Code size 54 (0x36) + .maxstack 8 + .line 4,4 : 6,11 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0008 - - IL_0006: br.s IL_000a - - IL_0008: br.s IL_0039 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.1 - IL_000b: ldnull - IL_000c: cgt.un - IL_000e: brfalse.s IL_0012 - - IL_0010: br.s IL_0014 - - IL_0012: br.s IL_0037 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_002c .line 16707566,16707566 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: ldfld int32 TestFunction24/Point::x@ - IL_001a: ldarg.1 - IL_001b: ldfld int32 TestFunction24/Point::x@ - IL_0020: bne.un.s IL_0024 - - IL_0022: br.s IL_0026 - - IL_0024: br.s IL_0035 + IL_000d: ldarg.0 + IL_000e: ldfld int32 TestFunction24/Point::x@ + IL_0013: ldarg.1 + IL_0014: ldfld int32 TestFunction24/Point::x@ + IL_0019: bne.un.s IL_002a .line 16707566,16707566 : 0,0 '' - IL_0026: ldarg.0 - IL_0027: ldfld int32 TestFunction24/Point::y@ - IL_002c: ldarg.1 - IL_002d: ldfld int32 TestFunction24/Point::y@ - IL_0032: ceq - IL_0034: ret + IL_001b: ldarg.0 + IL_001c: ldfld int32 TestFunction24/Point::y@ + IL_0021: ldarg.1 + IL_0022: ldfld int32 TestFunction24/Point::y@ + IL_0027: ceq + IL_0029: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldc.i4.0 - IL_0038: ret + IL_002c: ldc.i4.0 + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldarg.1 - IL_003a: ldnull - IL_003b: cgt.un - IL_003d: ldc.i4.0 - IL_003e: ceq - IL_0040: ret + IL_002e: ldarg.1 + IL_002f: ldnull + IL_0030: cgt.un + IL_0032: ldc.i4.0 + IL_0033: ceq + IL_0035: ret } // end of method Point::Equals .method public hidebysig virtual final instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 24 (0x18) + // Code size 20 (0x14) .maxstack 4 .locals init ([0] class TestFunction24/Point V_0) .line 4,4 : 6,11 '' IL_0000: ldarg.1 IL_0001: isinst TestFunction24/Point IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 - IL_0008: brfalse.s IL_000c - - IL_000a: br.s IL_000e - - IL_000c: br.s IL_0016 + IL_0008: brfalse.s IL_0012 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: ldloc.0 - IL_0010: callvirt instance bool TestFunction24/Point::Equals(class TestFunction24/Point) - IL_0015: ret + IL_000a: ldarg.0 + IL_000b: ldloc.0 + IL_000c: callvirt instance bool TestFunction24/Point::Equals(class TestFunction24/Point) + IL_0011: ret .line 16707566,16707566 : 0,0 '' - IL_0016: ldc.i4.0 - IL_0017: ret + IL_0012: ldc.i4.0 + IL_0013: ret } // end of method Point::Equals .property instance int32 x() @@ -775,7 +705,7 @@ .method public static float64 pinArray1() cil managed { - // Code size 196 (0xc4) + // Code size 188 (0xbc) .maxstack 6 .locals init ([0] float64[] arr, [1] native int p1, @@ -816,72 +746,65 @@ .line 18,18 : 5,23 '' IL_0067: ldloc.0 IL_0068: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_0069: ldloc.2 - IL_006a: brfalse.s IL_006e - - IL_006c: br.s IL_0070 - - IL_006e: br.s IL_008e + IL_006a: brfalse.s IL_0086 .line 16707566,16707566 : 0,0 '' - IL_0070: ldloc.2 - IL_0071: call int32 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Length(!!0[]) - IL_0076: brfalse.s IL_007a - - IL_0078: br.s IL_007c - - IL_007a: br.s IL_0089 + IL_006c: ldloc.2 + IL_006d: call int32 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Length(!!0[]) + IL_0072: brfalse.s IL_0081 .line 16707566,16707566 : 0,0 '' - IL_007c: ldloc.2 - IL_007d: ldc.i4.0 - IL_007e: ldelema [mscorlib]System.Double - IL_0083: stloc.3 - IL_0084: ldloc.3 - IL_0085: conv.i + IL_0074: ldloc.2 + IL_0075: ldc.i4.0 + IL_0076: ldelema [mscorlib]System.Double + IL_007b: stloc.3 + IL_007c: ldloc.3 + IL_007d: conv.i .line 16707566,16707566 : 0,0 '' - IL_0086: nop - IL_0087: br.s IL_0091 + IL_007e: nop + IL_007f: br.s IL_0089 .line 16707566,16707566 : 0,0 '' - IL_0089: ldc.i4.0 - IL_008a: conv.i + IL_0081: ldc.i4.0 + IL_0082: conv.i .line 16707566,16707566 : 0,0 '' - IL_008b: nop - IL_008c: br.s IL_0091 + IL_0083: nop + IL_0084: br.s IL_0089 .line 16707566,16707566 : 0,0 '' - IL_008e: ldc.i4.0 - IL_008f: conv.i + IL_0086: ldc.i4.0 + IL_0087: conv.i .line 16707566,16707566 : 0,0 '' - IL_0090: nop + IL_0088: nop .line 16707566,16707566 : 0,0 '' - IL_0091: stloc.1 + IL_0089: stloc.1 .line 19,19 : 5,44 '' - IL_0092: ldloc.1 - IL_0093: stloc.s V_4 - IL_0095: ldc.i4.0 - IL_0096: stloc.s V_5 - IL_0098: ldloc.s V_4 - IL_009a: ldloc.s V_5 - IL_009c: conv.i - IL_009d: sizeof [mscorlib]System.Double - IL_00a3: mul - IL_00a4: add - IL_00a5: ldobj [mscorlib]System.Double - IL_00aa: ldloc.1 - IL_00ab: stloc.s V_6 - IL_00ad: ldc.i4.1 - IL_00ae: stloc.s V_7 - IL_00b0: ldloc.s V_6 - IL_00b2: ldloc.s V_7 - IL_00b4: conv.i - IL_00b5: sizeof [mscorlib]System.Double - IL_00bb: mul - IL_00bc: add - IL_00bd: ldobj [mscorlib]System.Double - IL_00c2: add - IL_00c3: ret + IL_008a: ldloc.1 + IL_008b: stloc.s V_4 + IL_008d: ldc.i4.0 + IL_008e: stloc.s V_5 + IL_0090: ldloc.s V_4 + IL_0092: ldloc.s V_5 + IL_0094: conv.i + IL_0095: sizeof [mscorlib]System.Double + IL_009b: mul + IL_009c: add + IL_009d: ldobj [mscorlib]System.Double + IL_00a2: ldloc.1 + IL_00a3: stloc.s V_6 + IL_00a5: ldc.i4.1 + IL_00a6: stloc.s V_7 + IL_00a8: ldloc.s V_6 + IL_00aa: ldloc.s V_7 + IL_00ac: conv.i + IL_00ad: sizeof [mscorlib]System.Double + IL_00b3: mul + IL_00b4: add + IL_00b5: ldobj [mscorlib]System.Double + IL_00ba: add + IL_00bb: ret } // end of method TestFunction24::pinArray1 .method public static float64 pinArray2() cil managed @@ -961,7 +884,7 @@ .method public static class [mscorlib]System.Tuple`2 pinString() cil managed { - // Code size 81 (0x51) + // Code size 77 (0x4d) .maxstack 6 .locals init ([0] string str, [1] native int pChar, @@ -976,54 +899,51 @@ .line 30,30 : 5,26 '' IL_0006: ldloc.0 IL_0007: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_0008: ldloc.2 - IL_0009: brfalse.s IL_000d - - IL_000b: br.s IL_000f - - IL_000d: br.s IL_001a + IL_0009: brfalse.s IL_0016 .line 16707566,16707566 : 0,0 '' - IL_000f: ldloc.2 - IL_0010: conv.i - IL_0011: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() - IL_0016: add + IL_000b: ldloc.2 + IL_000c: conv.i + IL_000d: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData() + IL_0012: add .line 16707566,16707566 : 0,0 '' - IL_0017: nop - IL_0018: br.s IL_001c + IL_0013: nop + IL_0014: br.s IL_0018 .line 16707566,16707566 : 0,0 '' - IL_001a: ldloc.2 + IL_0016: ldloc.2 .line 16707566,16707566 : 0,0 '' - IL_001b: nop + IL_0017: nop .line 16707566,16707566 : 0,0 '' - IL_001c: stloc.1 + IL_0018: stloc.1 .line 31,31 : 5,50 '' - IL_001d: ldloc.1 - IL_001e: stloc.3 - IL_001f: ldc.i4.0 - IL_0020: stloc.s V_4 - IL_0022: ldloc.3 - IL_0023: ldloc.s V_4 - IL_0025: conv.i - IL_0026: sizeof [mscorlib]System.Char - IL_002c: mul - IL_002d: add - IL_002e: ldobj [mscorlib]System.Char - IL_0033: ldloc.1 - IL_0034: stloc.s V_5 - IL_0036: ldc.i4.1 - IL_0037: stloc.s V_6 - IL_0039: ldloc.s V_5 - IL_003b: ldloc.s V_6 - IL_003d: conv.i - IL_003e: sizeof [mscorlib]System.Char - IL_0044: mul - IL_0045: add - IL_0046: ldobj [mscorlib]System.Char - IL_004b: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_0019: ldloc.1 + IL_001a: stloc.3 + IL_001b: ldc.i4.0 + IL_001c: stloc.s V_4 + IL_001e: ldloc.3 + IL_001f: ldloc.s V_4 + IL_0021: conv.i + IL_0022: sizeof [mscorlib]System.Char + IL_0028: mul + IL_0029: add + IL_002a: ldobj [mscorlib]System.Char + IL_002f: ldloc.1 + IL_0030: stloc.s V_5 + IL_0032: ldc.i4.1 + IL_0033: stloc.s V_6 + IL_0035: ldloc.s V_5 + IL_0037: ldloc.s V_6 + IL_0039: conv.i + IL_003a: sizeof [mscorlib]System.Char + IL_0040: mul + IL_0041: add + IL_0042: ldobj [mscorlib]System.Char + IL_0047: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0050: ret + IL_004c: ret } // end of method TestFunction24::pinString } // end of class TestFunction24 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3b.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3b.il.bsl index d543e2e48bb..605bb5ca37b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3b.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3b.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction3b { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction3b { - // Offset: 0x00000000 Length: 0x00000200 + // Offset: 0x00000000 Length: 0x000001FC } .mresource public FSharpOptimizationData.TestFunction3b { - // Offset: 0x00000208 Length: 0x0000008A + // Offset: 0x00000200 Length: 0x0000008A } .module TestFunction3b.exe -// MVID: {59B19208-A662-4FC9-A745-03830892B159} +// MVID: {611C4D9E-A662-4FC9-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00BB0000 +// Image base: 0x053D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3b.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3b.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -75,60 +75,56 @@ .method public static void TestFunction3b() cil managed { - // Code size 73 (0x49) + // Code size 66 (0x42) .maxstack 3 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] int32 x, - [2] string V_2, - [3] class [mscorlib]System.Exception V_3, - [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4) - .line 11,11 : 8,31 '' + .locals init ([0] int32 x, + [1] string V_1, + [2] class [mscorlib]System.Exception V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_3) + .line 10,10 : 5,8 '' .try { - IL_0000: call int32 TestFunction3b::TestFunction1() - IL_0005: stloc.1 + IL_0000: nop + .line 11,11 : 8,31 '' + IL_0001: call int32 TestFunction3b::TestFunction1() + IL_0006: stloc.0 .line 12,12 : 8,24 '' - IL_0006: ldstr "hello" - IL_000b: stloc.2 - IL_000c: ldloc.2 - IL_000d: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0012: throw + IL_0007: ldstr "hello" + IL_000c: stloc.1 + IL_000d: ldloc.1 + IL_000e: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0013: throw .line 13,13 : 5,9 '' } // end .try catch [mscorlib]System.Object { - IL_0013: castclass [mscorlib]System.Exception - IL_0018: stloc.3 - IL_0019: ldloc.3 - IL_001a: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) - IL_001f: stloc.s V_4 - IL_0021: ldloc.s V_4 - IL_0023: brfalse.s IL_0027 - - IL_0025: br.s IL_0029 - - IL_0027: br.s IL_003b + IL_0014: castclass [mscorlib]System.Exception + IL_0019: stloc.2 + IL_001a: ldloc.2 + IL_001b: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.3 + IL_0022: brfalse.s IL_0036 .line 14,14 : 8,23 '' - IL_0029: ldstr "World" - IL_002e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0033: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0038: stloc.0 - IL_0039: leave.s IL_0046 + IL_0024: ldstr "World" + IL_0029: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_002e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0033: pop + IL_0034: leave.s IL_0041 .line 100001,100001 : 0,0 '' - IL_003b: rethrow - IL_003d: ldnull - IL_003e: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit - IL_0043: stloc.0 - IL_0044: leave.s IL_0046 + IL_0036: rethrow + IL_0038: ldnull + IL_0039: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit + IL_003e: pop + IL_003f: leave.s IL_0041 .line 100001,100001 : 0,0 '' } // end handler - IL_0046: ldloc.0 - IL_0047: pop - IL_0048: ret + IL_0041: ret } // end of method TestFunction3b::TestFunction3b } // end of class TestFunction3b diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3c.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3c.il.bsl index dc790e1200b..66623938655 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3c.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction3c.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly TestFunction3c { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.TestFunction3c { - // Offset: 0x00000000 Length: 0x00000200 + // Offset: 0x00000000 Length: 0x000001FC } .mresource public FSharpOptimizationData.TestFunction3c { - // Offset: 0x00000208 Length: 0x0000008A + // Offset: 0x00000200 Length: 0x0000008A } .module TestFunction3c.exe -// MVID: {59B19208-A662-4FAC-A745-03830892B159} +// MVID: {611C4D9E-A662-4FAC-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02B20000 +// Image base: 0x06740000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +61,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3c.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3c.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -75,74 +80,74 @@ .method public static void TestFunction3c() cil managed { - // Code size 105 (0x69) + // Code size 97 (0x61) .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] int32 x, - [2] string V_2, - [3] class [mscorlib]System.Exception V_3, - [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_4, - [5] string msg, - [6] string V_6) - .line 11,11 : 8,31 '' + .locals init ([0] int32 x, + [1] string V_1, + [2] class [mscorlib]System.Exception V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_3, + [4] string msg, + [5] string V_5) + .line 10,10 : 5,8 '' .try { - IL_0000: call int32 TestFunction3c::TestFunction1() - IL_0005: stloc.1 + IL_0000: nop + .line 11,11 : 8,31 '' + IL_0001: call int32 TestFunction3c::TestFunction1() + IL_0006: stloc.0 .line 12,12 : 8,24 '' - IL_0006: ldstr "hello" - IL_000b: stloc.2 - IL_000c: ldloc.2 - IL_000d: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) - IL_0012: throw + IL_0007: ldstr "hello" + IL_000c: stloc.1 + IL_000d: ldloc.1 + IL_000e: call class [mscorlib]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0013: throw .line 13,13 : 5,9 '' } // end .try catch [mscorlib]System.Object { - IL_0013: castclass [mscorlib]System.Exception - IL_0018: stloc.3 - IL_0019: ldloc.3 - IL_001a: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) - IL_001f: stloc.s V_4 - IL_0021: ldloc.s V_4 - IL_0023: brfalse.s IL_005b - - IL_0025: ldloc.s V_4 - IL_0027: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_002c: stloc.s msg - IL_002e: ldloc.s msg - IL_0030: ldstr "hello" - IL_0035: call bool [mscorlib]System.String::Equals(string, - string) - IL_003a: brfalse.s IL_003e - - IL_003c: br.s IL_0040 - - IL_003e: br.s IL_005b - - IL_0040: ldloc.s V_4 - IL_0042: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0047: stloc.s V_6 + IL_0014: castclass [mscorlib]System.Exception + IL_0019: stloc.2 + IL_001a: ldloc.2 + IL_001b: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::FailurePattern(class [mscorlib]System.Exception) + IL_0020: stloc.3 + .line 100001,100001 : 0,0 '' + IL_0021: ldloc.3 + IL_0022: brfalse.s IL_0055 + + .line 13,13 : 27,40 '' + IL_0024: nop + .line 100001,100001 : 0,0 '' + IL_0025: ldloc.3 + IL_0026: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_002b: stloc.s msg + IL_002d: ldloc.s msg + IL_002f: ldstr "hello" + IL_0034: call bool [netstandard]System.String::Equals(string, + string) + IL_0039: brfalse.s IL_0055 + + .line 100001,100001 : 0,0 '' + IL_003b: ldloc.3 + IL_003c: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_0041: stloc.s V_5 .line 14,14 : 8,23 '' - IL_0049: ldstr "World" - IL_004e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0053: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0058: stloc.0 - IL_0059: leave.s IL_0066 + IL_0043: ldstr "World" + IL_0048: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_004d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0052: pop + IL_0053: leave.s IL_0060 .line 100001,100001 : 0,0 '' - IL_005b: rethrow - IL_005d: ldnull - IL_005e: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit - IL_0063: stloc.0 - IL_0064: leave.s IL_0066 + IL_0055: rethrow + IL_0057: ldnull + IL_0058: unbox.any [FSharp.Core]Microsoft.FSharp.Core.Unit + IL_005d: pop + IL_005e: leave.s IL_0060 .line 100001,100001 : 0,0 '' } // end handler - IL_0066: ldloc.0 - IL_0067: pop - IL_0068: ret + IL_0060: ret } // end of method TestFunction3c::TestFunction3c } // end of class TestFunction3c diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction9b4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction9b4.il.bsl index a92010a91c4..1aede1f2c26 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction9b4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/TestFunction9b4.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly TestFunction9b4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9b4 { - // Offset: 0x00000000 Length: 0x0000024C + // Offset: 0x00000000 Length: 0x00000240 } .mresource public FSharpOptimizationData.TestFunction9b4 { - // Offset: 0x00000250 Length: 0x00000085 + // Offset: 0x00000248 Length: 0x00000085 } .module TestFunction9b4.exe -// MVID: {5B17FC67-A091-56C1-A745-038367FC175B} +// MVID: {611C4D9E-A091-56C1-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026C0000 +// Image base: 0x07100000 // =============== CLASS MEMBERS DECLARATION =================== @@ -58,7 +58,7 @@ .maxstack 3 .locals init ([0] !!a V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 8,8 : 12,16 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b4.fs' + .line 8,8 : 12,16 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b4.fs' IL_0000: ldloc.0 IL_0001: ret } // end of method TestFunction9b4::Null @@ -90,33 +90,35 @@ .method public static void main@() cil managed { .entrypoint - // Code size 42 (0x2a) + // Code size 43 (0x2b) .maxstack 3 .locals init ([0] int32 x) .line 10,10 : 1,10 '' IL_0000: call int32 TestFunction9b4::get_x() IL_0005: stloc.0 .line 12,12 : 1,17 '' - IL_0006: call int32 TestFunction9b4::get_x() - IL_000b: box [mscorlib]System.Int32 - IL_0010: brfalse.s IL_0014 + IL_0006: nop + .line 100001,100001 : 0,0 '' + IL_0007: call int32 TestFunction9b4::get_x() + IL_000c: box [mscorlib]System.Int32 + IL_0011: brfalse.s IL_0015 - IL_0012: br.s IL_0027 + IL_0013: br.s IL_0028 .line 13,13 : 13,30 '' - IL_0014: ldstr "Is null" - IL_0019: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_001e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0023: pop + IL_0015: ldstr "Is null" + IL_001a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_001f: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0024: pop .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: br.s IL_0029 + IL_0025: nop + IL_0026: br.s IL_002a .line 14,14 : 10,12 '' - IL_0027: nop - .line 100001,100001 : 0,0 '' IL_0028: nop - IL_0029: ret + .line 100001,100001 : 0,0 '' + IL_0029: nop + IL_002a: ret } // end of method $TestFunction9b4::main@ } // end of class ''.$TestFunction9b4 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction11.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction11.il.bsl index 5fc9397c162..98835e2b7b8 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction11.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction11.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction11 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction11 { - // Offset: 0x00000000 Length: 0x000001E8 + // Offset: 0x00000000 Length: 0x000001E4 } .mresource public FSharpOptimizationData.TestFunction11 { - // Offset: 0x000001F0 Length: 0x00000072 + // Offset: 0x000001E8 Length: 0x00000072 } .module TestFunction11.exe -// MVID: {59B19208-A624-45E6-A745-03830892B159} +// MVID: {60B68B97-A624-45E6-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x064D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,7 +57,7 @@ // Code size 30 (0x1e) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,27 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction11.fs' + .line 5,5 : 5,27 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction11.fs' IL_0000: ldarg.0 IL_0001: ldarg.0 IL_0002: ldarg.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction12.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction12.il.bsl index 2f7b3efff8e..2a841ada06d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction12.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction12.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction12 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction12 { - // Offset: 0x00000000 Length: 0x000001DB + // Offset: 0x00000000 Length: 0x000001D7 } .mresource public FSharpOptimizationData.TestFunction12 { // Offset: 0x000001E0 Length: 0x00000072 } .module TestFunction12.exe -// MVID: {59B19208-A624-4539-A745-03830892B159} +// MVID: {60B68B97-A624-4539-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x070C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,7 +57,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction12.fs' + .line 5,5 : 5,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction12.fs' IL_0000: ldarg.0 IL_0001: ldarg.0 IL_0002: add diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction15.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction15.il.bsl index ae9215ad18e..9138937e22e 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction15.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction15.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction15 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction15 { - // Offset: 0x00000000 Length: 0x000001EA + // Offset: 0x00000000 Length: 0x000001E6 } .mresource public FSharpOptimizationData.TestFunction15 { // Offset: 0x000001F0 Length: 0x00000072 } .module TestFunction15.exe -// MVID: {59B19208-A624-4662-A745-03830892B159} +// MVID: {611B0ED4-A624-4662-A745-0383D40E1B61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02B10000 +// Image base: 0x07120000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +54,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit TestFunction15@6 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class TestFunction15/TestFunction15@6 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -72,39 +73,52 @@ // Code size 4 (0x4) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 35,40 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction15.fs' + .line 6,6 : 35,40 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction15.fs' IL_0000: ldarg.1 IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret } // end of method TestFunction15@6::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void TestFunction15/TestFunction15@6::.ctor() + IL_0005: stsfld class TestFunction15/TestFunction15@6 TestFunction15/TestFunction15@6::@_instance + IL_000a: ret + } // end of method TestFunction15@6::.cctor + } // end of class TestFunction15@6 .method public static class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 TestFunction15(int32 inp) cil managed { // Code size 40 (0x28) - .maxstack 7 - .locals init ([0] int32 x) + .maxstack 6 + .locals init ([0] int32 x, + [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 'Pipe #1 input at line 6') .line 5,5 : 5,18 '' IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: add IL_0003: stloc.0 - .line 6,6 : 5,41 '' - IL_0004: newobj instance void TestFunction15/TestFunction15@6::.ctor() - IL_0009: ldc.i4.1 - IL_000a: ldc.i4.2 - IL_000b: ldc.i4.3 - IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + .line 6,6 : 5,12 '' + IL_0004: ldc.i4.1 + IL_0005: ldc.i4.2 + IL_0006: ldc.i4.3 + IL_0007: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0011: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0016: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_001b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, - class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0020: tail. + IL_001b: stloc.1 + .line 6,6 : 16,41 '' + IL_001c: ldsfld class TestFunction15/TestFunction15@6 TestFunction15/TestFunction15@6::@_instance + IL_0021: ldloc.1 IL_0022: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [FSharp.Core]Microsoft.FSharp.Collections.ListModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) IL_0027: ret diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction18.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction18.il.bsl index 80848608547..17e117dad82 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction18.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction18.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction18 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction18 { - // Offset: 0x00000000 Length: 0x000001ED + // Offset: 0x00000000 Length: 0x000001E1 } .mresource public FSharpOptimizationData.TestFunction18 { - // Offset: 0x000001F8 Length: 0x00000072 + // Offset: 0x000001E8 Length: 0x00000072 } .module TestFunction18.exe -// MVID: {59B19208-A624-4603-A745-03830892B159} +// MVID: {60B68B97-A624-4603-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x019B0000 +// Image base: 0x09850000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 11 (0xb) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,38 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction18.fs' + .line 5,5 : 5,38 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction18.fs' IL_0000: ldstr "hello" IL_0005: call void [mscorlib]System.Console::WriteLine(string) IL_000a: ret diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction2.il.bsl index 92ec82161db..21e84cf567b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction2.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction2 { - // Offset: 0x00000000 Length: 0x000001FD + // Offset: 0x00000000 Length: 0x000001F9 } .mresource public FSharpOptimizationData.TestFunction2 { - // Offset: 0x00000208 Length: 0x00000088 + // Offset: 0x00000200 Length: 0x00000088 } .module TestFunction2.exe -// MVID: {59B19208-661D-8929-A745-03830892B159} +// MVID: {60B68B97-661D-8929-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x071A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction2.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction2.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22.il.bsl index 3c7a947a3b4..23600d9913f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22 { - // Offset: 0x00000000 Length: 0x0000015B + // Offset: 0x00000000 Length: 0x00000157 } .mresource public FSharpOptimizationData.Testfunction22 { // Offset: 0x00000160 Length: 0x00000055 } .module Testfunction22.exe -// MVID: {59B199CC-5AA3-4518-A745-0383CC99B159} +// MVID: {60B68B97-5AA3-4518-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x05220000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 6 (0x6) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 1,27 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22.fs' + .line 3,3 : 1,27 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22.fs' IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret } // end of method $Testfunction22::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22b.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22b.il.bsl index ac3e76f8f2e..aea4e753718 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22b.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22b.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22b { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22b { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22b { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22b.exe -// MVID: {59B19208-8504-18B7-A745-03830892B159} +// MVID: {60B68B97-8504-18B7-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x00AF0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 6 (0x6) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,35 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22b.fs' + .line 3,3 : 9,35 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22b.fs' IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret } // end of method $Testfunction22b::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22c.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22c.il.bsl index e5640da7b20..19f08efe5bf 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22c.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22c.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22c { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22c { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22c { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22c.exe -// MVID: {59B19208-459D-3DF8-A745-03830892B159} +// MVID: {60B68B97-459D-3DF8-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03000000 +// Image base: 0x00F10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 6 (0x6) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 10,36 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22c.fs' + .line 3,3 : 10,36 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22c.fs' IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret } // end of method $Testfunction22c::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22d.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22d.il.bsl index 06dc2c7b954..1621b79b127 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22d.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22d.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22d { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22d { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22d { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22d.exe -// MVID: {59B19208-FDCA-89B1-A745-03830892B159} +// MVID: {60B68B97-FDCA-89B1-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00720000 +// Image base: 0x00E60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 6 (0x6) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 4,30 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22d.fs' + .line 3,3 : 4,30 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22d.fs' IL_0000: call void [mscorlib]System.Console::WriteLine() IL_0005: ret } // end of method $Testfunction22d::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22e.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22e.il.bsl index ed2dae30740..d3e72f97117 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22e.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22e.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22e { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22e { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22e { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22e.exe -// MVID: {59B19208-C83B-1CB9-A745-03830892B159} +// MVID: {60B68B97-C83B-1CB9-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x05440000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 12 (0xc) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 1,11 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22e.fs' + .line 3,3 : 1,11 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22e.fs' IL_0000: ldc.i4.1 IL_0001: brfalse.s IL_000b diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22f.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22f.il.bsl index 2dd07a07bb2..1d17863b463 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22f.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22f.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Testfunction22f { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Testfunction22f { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22f { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22f.exe -// MVID: {59B19208-C040-2523-A745-03830892B159} +// MVID: {611C4D9E-C040-2523-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x012C0000 +// Image base: 0x04D20000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,34 +68,31 @@ .method public static void main@() cil managed { .entrypoint - // Code size 38 (0x26) + // Code size 34 (0x22) .maxstack 4 .locals init ([0] string V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 1,15 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22f.fs' + .line 3,3 : 1,15 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22f.fs' IL_0000: ldstr "A" IL_0005: stloc.0 + .line 100001,100001 : 0,0 '' IL_0006: ldloc.0 IL_0007: ldstr "A" - IL_000c: call bool [mscorlib]System.String::Equals(string, - string) - IL_0011: brfalse.s IL_0015 - - IL_0013: br.s IL_0017 - - IL_0015: br.s IL_001f + IL_000c: call bool [netstandard]System.String::Equals(string, + string) + IL_0011: brfalse.s IL_001b .line 4,4 : 12,38 '' - IL_0017: call void [mscorlib]System.Console::WriteLine() + IL_0013: call void [mscorlib]System.Console::WriteLine() .line 100001,100001 : 0,0 '' - IL_001c: nop - IL_001d: br.s IL_0025 + IL_0018: nop + IL_0019: br.s IL_0021 .line 5,5 : 10,36 '' - IL_001f: call void [mscorlib]System.Console::WriteLine() + IL_001b: call void [mscorlib]System.Console::WriteLine() .line 100001,100001 : 0,0 '' - IL_0024: nop - IL_0025: ret + IL_0020: nop + IL_0021: ret } // end of method $Testfunction22f::main@ } // end of class ''.$Testfunction22f diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22g.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22g.il.bsl index 629593f6e0a..67305e6544f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22g.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22g.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22g { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22g { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22g { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22g.exe -// MVID: {59B19208-CA89-74DB-A745-03830892B159} +// MVID: {611C4D9E-CA89-74DB-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x012F0000 +// Image base: 0x04D30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,28 +63,26 @@ .method public static void main@() cil managed { .entrypoint - // Code size 22 (0x16) + // Code size 19 (0x13) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 1,13 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22g.fs' - IL_0000: ldc.i4.1 - IL_0001: brfalse.s IL_0005 - - IL_0003: br.s IL_0007 - - IL_0005: br.s IL_000f + .line 3,3 : 1,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22g.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldc.i4.1 + IL_0002: brfalse.s IL_000c .line 3,3 : 14,40 '' - IL_0007: call void [mscorlib]System.Console::WriteLine() + IL_0004: call void [mscorlib]System.Console::WriteLine() .line 100001,100001 : 0,0 '' - IL_000c: nop - IL_000d: br.s IL_0015 + IL_0009: nop + IL_000a: br.s IL_0012 .line 3,3 : 46,72 '' - IL_000f: call void [mscorlib]System.Console::WriteLine() + IL_000c: call void [mscorlib]System.Console::WriteLine() .line 100001,100001 : 0,0 '' - IL_0014: nop - IL_0015: ret + IL_0011: nop + IL_0012: ret } // end of method $Testfunction22g::main@ } // end of class ''.$Testfunction22g diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22h.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22h.il.bsl index 7fcae895abd..48655e7bedf 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22h.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction22h.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Testfunction22h { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Testfunction22h { - // Offset: 0x00000000 Length: 0x0000015D + // Offset: 0x00000000 Length: 0x00000159 } .mresource public FSharpOptimizationData.Testfunction22h { - // Offset: 0x00000168 Length: 0x00000056 + // Offset: 0x00000160 Length: 0x00000056 } .module Testfunction22h.exe -// MVID: {59B19208-0266-39F6-A745-03830892B159} +// MVID: {611C4D9E-0266-39F6-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00370000 +// Image base: 0x066F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,36 +63,31 @@ .method public static void main@() cil managed { .entrypoint - // Code size 27 (0x1b) + // Code size 22 (0x16) .maxstack 3 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] class [mscorlib]System.Exception V_1) + .locals init ([0] class [mscorlib]System.Exception V_0) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 4,4 : 4,30 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22h.fs' + .line 3,3 : 1,4 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\Testfunction22h.fs' .try { - IL_0000: call void [mscorlib]System.Console::WriteLine() - IL_0005: ldnull - IL_0006: stloc.0 - IL_0007: leave.s IL_0018 + IL_0000: nop + .line 4,4 : 4,30 '' + IL_0001: call void [mscorlib]System.Console::WriteLine() + IL_0006: leave.s IL_0015 .line 5,5 : 1,5 '' } // end .try catch [mscorlib]System.Object { - IL_0009: castclass [mscorlib]System.Exception - IL_000e: stloc.1 + IL_0008: castclass [mscorlib]System.Exception + IL_000d: stloc.0 .line 6,6 : 11,37 '' - IL_000f: call void [mscorlib]System.Console::WriteLine() - IL_0014: ldnull - IL_0015: stloc.0 - IL_0016: leave.s IL_0018 + IL_000e: call void [mscorlib]System.Console::WriteLine() + IL_0013: leave.s IL_0015 .line 100001,100001 : 0,0 '' } // end handler - IL_0018: ldloc.0 - IL_0019: pop - IL_001a: ret + IL_0015: ret } // end of method $Testfunction22h::main@ } // end of class ''.$Testfunction22h diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction3.il.bsl index 2a64c727d05..35c8295e14c 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction3.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction3 { - // Offset: 0x00000000 Length: 0x000001FD + // Offset: 0x00000000 Length: 0x000001F9 } .mresource public FSharpOptimizationData.TestFunction3 { - // Offset: 0x00000208 Length: 0x00000088 + // Offset: 0x00000200 Length: 0x00000088 } .module TestFunction3.exe -// MVID: {59B19208-663A-8929-A745-03830892B159} +// MVID: {611C4D9E-663A-8929-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x013E0000 +// Image base: 0x07360000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction3.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -75,41 +75,40 @@ .method public static void TestFunction3() cil managed { - // Code size 51 (0x33) + // Code size 50 (0x32) .maxstack 3 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] int32 x, - [2] class [mscorlib]System.Exception V_2) - .line 11,11 : 8,31 '' + .locals init ([0] int32 x, + [1] class [mscorlib]System.Exception V_1) + .line 10,10 : 5,8 '' .try { - IL_0000: call int32 TestFunction3::TestFunction1() - IL_0005: stloc.1 + IL_0000: nop + .line 11,11 : 8,31 '' + IL_0001: call int32 TestFunction3::TestFunction1() + IL_0006: stloc.0 .line 12,12 : 8,23 '' - IL_0006: ldstr "Hello" - IL_000b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0010: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0015: stloc.0 - IL_0016: leave.s IL_0030 + IL_0007: ldstr "Hello" + IL_000c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: leave.s IL_0031 .line 13,13 : 5,9 '' } // end .try catch [mscorlib]System.Object { - IL_0018: castclass [mscorlib]System.Exception - IL_001d: stloc.2 + IL_0019: castclass [mscorlib]System.Exception + IL_001e: stloc.1 .line 14,14 : 8,23 '' - IL_001e: ldstr "World" - IL_0023: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0028: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_002d: stloc.0 - IL_002e: leave.s IL_0030 + IL_001f: ldstr "World" + IL_0024: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0029: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_002e: pop + IL_002f: leave.s IL_0031 .line 100001,100001 : 0,0 '' } // end handler - IL_0030: ldloc.0 - IL_0031: pop - IL_0032: ret + IL_0031: ret } // end of method TestFunction3::TestFunction3 } // end of class TestFunction3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction4.il.bsl index 0b9818bebb3..d2e49c8e9de 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction4.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction4 { - // Offset: 0x00000000 Length: 0x000001FD + // Offset: 0x00000000 Length: 0x000001F9 } .mresource public FSharpOptimizationData.TestFunction4 { - // Offset: 0x00000208 Length: 0x00000088 + // Offset: 0x00000200 Length: 0x00000088 } .module TestFunction4.exe -// MVID: {59B19208-665B-8929-A745-03830892B159} +// MVID: {611C4D9E-665B-8929-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x026C0000 +// Image base: 0x067E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction4.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction4.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -75,38 +75,37 @@ .method public static void TestFunction4() cil managed { - // Code size 45 (0x2d) + // Code size 44 (0x2c) .maxstack 3 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.Unit V_0, - [1] int32 x) - .line 11,11 : 8,31 '' + .locals init ([0] int32 x) + .line 10,10 : 5,8 '' .try { - IL_0000: call int32 TestFunction4::TestFunction1() - IL_0005: stloc.1 + IL_0000: nop + .line 11,11 : 8,31 '' + IL_0001: call int32 TestFunction4::TestFunction1() + IL_0006: stloc.0 .line 12,12 : 8,23 '' - IL_0006: ldstr "Hello" - IL_000b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0010: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0015: stloc.0 - IL_0016: leave.s IL_002a + IL_0007: ldstr "Hello" + IL_000c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0016: pop + IL_0017: leave.s IL_002b .line 13,13 : 5,12 '' } // end .try finally { - IL_0018: nop + IL_0019: nop .line 14,14 : 8,23 '' - IL_0019: ldstr "World" - IL_001e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) - IL_0023: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0028: pop - IL_0029: endfinally + IL_001a: ldstr "World" + IL_001f: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) + IL_0024: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0029: pop + IL_002a: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_002a: ldloc.0 - IL_002b: pop - IL_002c: ret + IL_002b: ret } // end of method TestFunction4::TestFunction4 } // end of class TestFunction4 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction5.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction5.il.bsl index fb983f1af1e..f03b113a1f8 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction5.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction5.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction5 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction5 { - // Offset: 0x00000000 Length: 0x000001FD + // Offset: 0x00000000 Length: 0x000001F9 } .mresource public FSharpOptimizationData.TestFunction5 { - // Offset: 0x00000208 Length: 0x00000088 + // Offset: 0x00000200 Length: 0x00000088 } .module TestFunction5.exe -// MVID: {59B19208-6570-8929-A745-03830892B159} +// MVID: {60B68B97-6570-8929-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010A0000 +// Image base: 0x00AB0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -56,7 +56,7 @@ // Code size 36 (0x24) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction5.fs' + .line 5,5 : 5,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction5.fs' IL_0000: ldstr "Hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction6.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction6.il.bsl index dcb8a71396b..90d8b294ee0 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction6.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction6.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly TestFunction6 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction6 { - // Offset: 0x00000000 Length: 0x00000205 + // Offset: 0x00000000 Length: 0x000001F9 } .mresource public FSharpOptimizationData.TestFunction6 { - // Offset: 0x00000210 Length: 0x00000088 + // Offset: 0x00000200 Length: 0x00000088 } .module TestFunction6.exe -// MVID: {5B17FC67-6591-8929-A745-038367FC175B} +// MVID: {60B68B97-6591-8929-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03360000 +// Image base: 0x072D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +54,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit f@11 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class TestFunction6/f@11 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -73,7 +74,7 @@ .maxstack 6 .locals init ([0] int32 y) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 11,11 : 8,31 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction6.fs' + .line 11,11 : 8,31 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction6.fs' IL_0000: call int32 TestFunction6::TestFunction1() IL_0005: stloc.0 .line 12,12 : 8,23 '' @@ -88,6 +89,16 @@ IL_0019: ret } // end of method f@11::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void TestFunction6/f@11::.ctor() + IL_0005: stsfld class TestFunction6/f@11 TestFunction6/f@11::@_instance + IL_000a: ret + } // end of method f@11::.cctor + } // end of class f@11 .method public static int32 TestFunction1() cil managed @@ -117,7 +128,7 @@ .maxstack 5 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) .line 100001,100001 : 0,0 '' - IL_0000: newobj instance void TestFunction6/f@11::.ctor() + IL_0000: ldsfld class TestFunction6/f@11 TestFunction6/f@11::@_instance IL_0005: stloc.0 .line 14,14 : 5,14 '' IL_0006: ldloc.0 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction7.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction7.il.bsl index a9af9b236e4..be6eb321a0b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction7.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction7.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction7 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction7 { - // Offset: 0x00000000 Length: 0x000001BF + // Offset: 0x00000000 Length: 0x000001BB } .mresource public FSharpOptimizationData.TestFunction7 { - // Offset: 0x000001C8 Length: 0x00000070 + // Offset: 0x000001C0 Length: 0x00000070 } .module TestFunction7.exe -// MVID: {59B19208-65AE-8929-A745-03830892B159} +// MVID: {60B68B97-65AE-8929-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00E30000 +// Image base: 0x051F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,7 +57,7 @@ .maxstack 4 .locals init ([0] int32 r) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,22 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction7.fs' + .line 5,5 : 5,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction7.fs' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 6,6 : 5,16 '' diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction8.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction8.il.bsl index 328e4809402..4cb5c39cf67 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction8.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction8.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction8 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction8 { - // Offset: 0x00000000 Length: 0x000001C8 + // Offset: 0x00000000 Length: 0x000001C4 } .mresource public FSharpOptimizationData.TestFunction8 { - // Offset: 0x000001D0 Length: 0x00000070 + // Offset: 0x000001C8 Length: 0x00000070 } .module TestFunction8.exe -// MVID: {59B19208-65CF-8929-A745-03830892B159} +// MVID: {611C4D9E-65CF-8929-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01010000 +// Image base: 0x06DC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,29 +53,27 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static int32 TestFunction8(int32 x) cil managed { - // Code size 16 (0x10) + // Code size 13 (0xd) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,18 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction8.fs' - IL_0000: ldarg.0 - IL_0001: ldc.i4.3 - IL_0002: ble.s IL_0006 - - IL_0004: br.s IL_0008 - - IL_0006: br.s IL_000c + .line 5,5 : 5,18 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction8.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldc.i4.3 + IL_0003: ble.s IL_0009 .line 6,6 : 9,12 '' - IL_0008: ldarg.0 - IL_0009: ldc.i4.4 - IL_000a: add - IL_000b: ret + IL_0005: ldarg.0 + IL_0006: ldc.i4.4 + IL_0007: add + IL_0008: ret .line 7,7 : 10,13 '' - IL_000c: ldarg.0 - IL_000d: ldc.i4.4 - IL_000e: sub - IL_000f: ret + IL_0009: ldarg.0 + IL_000a: ldc.i4.4 + IL_000b: sub + IL_000c: ret } // end of method TestFunction8::TestFunction8 } // end of class TestFunction8 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9.il.bsl index b7e4921fdc3..85f0521e674 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction9 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9 { - // Offset: 0x00000000 Length: 0x000001D6 + // Offset: 0x00000000 Length: 0x000001D2 } .mresource public FSharpOptimizationData.TestFunction9 { - // Offset: 0x000001E0 Length: 0x00000070 + // Offset: 0x000001D8 Length: 0x00000070 } .module TestFunction9.exe -// MVID: {59B19208-64F4-8929-A745-03830892B159} +// MVID: {611C4D9E-64F4-8929-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x016E0000 +// Image base: 0x05890000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,33 +53,31 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static string TestFunction9(int32 x) cil managed { - // Code size 40 (0x28) + // Code size 37 (0x25) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9.fs' - IL_0000: ldarg.0 - IL_0001: ldc.i4.3 - IL_0002: sub - IL_0003: switch ( - IL_0012, - IL_0014) - IL_0010: br.s IL_0022 - - IL_0012: br.s IL_0016 - - IL_0014: br.s IL_001c + .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9.fs' + IL_0000: nop + .line 100001,100001 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldc.i4.3 + IL_0003: sub + IL_0004: switch ( + IL_0013, + IL_0019) + IL_0011: br.s IL_001f .line 6,6 : 12,19 '' - IL_0016: ldstr "three" - IL_001b: ret + IL_0013: ldstr "three" + IL_0018: ret .line 7,7 : 12,18 '' - IL_001c: ldstr "four" - IL_0021: ret + IL_0019: ldstr "four" + IL_001e: ret .line 8,8 : 12,18 '' - IL_0022: ldstr "five" - IL_0027: ret + IL_001f: ldstr "five" + IL_0024: ret } // end of method TestFunction9::TestFunction9 } // end of class TestFunction9 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b.il.bsl index a4168bde720..f9085d417db 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction9b { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9b { - // Offset: 0x00000000 Length: 0x000001F6 + // Offset: 0x00000000 Length: 0x000001F2 } .mresource public FSharpOptimizationData.TestFunction9b { - // Offset: 0x00000200 Length: 0x00000072 + // Offset: 0x000001F8 Length: 0x00000072 } .module TestFunction9b.exe -// MVID: {59B19208-A52C-4FC9-A745-03830892B159} +// MVID: {611C4D9E-A52C-4FC9-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01AA0000 +// Image base: 0x06EC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static string TestFunction9b(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 x) cil managed { - // Code size 411 (0x19b) + // Code size 412 (0x19c) .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, @@ -69,76 +69,88 @@ [11] int32 V_11, [12] int32 V_12) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b.fs' + .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0008: brfalse IL_0195 + IL_0008: brfalse IL_0196 IL_000d: ldloc.0 IL_000e: stloc.1 + .line 100001,100001 : 0,0 '' IL_000f: ldloc.1 IL_0010: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0015: ldc.i4.1 IL_0016: sub IL_0017: switch ( IL_00ff) + .line 100001,100001 : 0,0 '' IL_0020: ldloc.1 IL_0021: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0026: ldc.i4.3 IL_0027: sub IL_0028: switch ( - IL_007a) + IL_0079) + .line 100001,100001 : 0,0 '' IL_0031: ldloc.1 IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_003c: brfalse IL_0195 + IL_003c: brfalse IL_0196 IL_0041: ldloc.1 IL_0042: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0047: stloc.2 + .line 100001,100001 : 0,0 '' IL_0048: ldloc.2 IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_004e: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0053: brtrue IL_0195 - - IL_0058: ldloc.2 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_005e: stloc.3 - IL_005f: ldloc.1 - IL_0060: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0065: stloc.s a - IL_0067: ldloc.s a - IL_0069: ldloc.3 - IL_006a: add - IL_006b: ldc.i4.4 - IL_006c: ceq - IL_006e: brfalse.s IL_0075 - - IL_0070: br IL_017f - - IL_0075: br IL_0195 - - IL_007a: ldloc.1 - IL_007b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0080: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0085: brfalse IL_0195 - - IL_008a: ldloc.1 - IL_008b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0090: stloc.s V_7 - IL_0092: ldloc.s V_7 - IL_0094: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0099: ldc.i4.4 - IL_009a: sub - IL_009b: switch ( + IL_0053: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_0058: nop + .line 100001,100001 : 0,0 '' + IL_0059: ldloc.2 + IL_005a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_005f: stloc.3 + IL_0060: ldloc.1 + IL_0061: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0066: stloc.s a + IL_0068: ldloc.s a + IL_006a: ldloc.3 + IL_006b: add + IL_006c: ldc.i4.4 + IL_006d: ceq + IL_006f: brfalse IL_0196 + + IL_0074: br IL_0180 + + .line 100001,100001 : 0,0 '' + IL_0079: ldloc.1 + IL_007a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_007f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0084: brfalse IL_0196 + + IL_0089: ldloc.1 + IL_008a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_008f: stloc.s V_7 + .line 100001,100001 : 0,0 '' + IL_0091: ldloc.s V_7 + IL_0093: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0098: ldc.i4.4 + IL_0099: sub + IL_009a: switch ( IL_00e9) - IL_00a4: ldloc.s V_7 - IL_00a6: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00ab: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00b0: brtrue IL_0195 - + .line 100001,100001 : 0,0 '' + IL_00a3: ldloc.s V_7 + IL_00a5: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00af: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_00b4: nop + .line 100001,100001 : 0,0 '' IL_00b5: ldloc.s V_7 IL_00b7: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00bc: stloc.s V_8 @@ -150,90 +162,100 @@ IL_00ca: add IL_00cb: ldc.i4.4 IL_00cc: ceq - IL_00ce: brfalse IL_0195 + IL_00ce: brfalse IL_0196 + .line 100001,100001 : 0,0 '' IL_00d3: ldloc.s V_7 IL_00d5: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00da: ldloc.1 IL_00db: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00e0: stloc.s V_6 IL_00e2: stloc.s V_5 - IL_00e4: br IL_018f + IL_00e4: br IL_0190 + .line 100001,100001 : 0,0 '' IL_00e9: ldloc.s V_7 IL_00eb: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_00f0: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00f5: brtrue IL_0195 + IL_00f5: brtrue IL_0196 - IL_00fa: br IL_0179 + IL_00fa: br IL_017a + .line 100001,100001 : 0,0 '' IL_00ff: ldloc.1 IL_0100: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0105: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_010a: brfalse IL_0195 + IL_010a: brfalse IL_0196 IL_010f: ldloc.1 IL_0110: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0115: stloc.s V_10 + .line 100001,100001 : 0,0 '' IL_0117: ldloc.s V_10 IL_0119: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_011e: ldc.i4.2 IL_011f: sub IL_0120: switch ( - IL_0165) + IL_0166) + .line 100001,100001 : 0,0 '' IL_0129: ldloc.s V_10 IL_012b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0130: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0135: brtrue.s IL_0195 - - IL_0137: ldloc.s V_10 - IL_0139: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_013e: stloc.s V_11 - IL_0140: ldloc.1 - IL_0141: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0146: stloc.s V_12 - IL_0148: ldloc.s V_12 - IL_014a: ldloc.s V_11 - IL_014c: add - IL_014d: ldc.i4.4 - IL_014e: ceq - IL_0150: brfalse.s IL_0195 - - IL_0152: ldloc.s V_10 - IL_0154: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0159: ldloc.1 - IL_015a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_015f: stloc.s V_6 - IL_0161: stloc.s V_5 - IL_0163: br.s IL_018f - - IL_0165: ldloc.s V_10 - IL_0167: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_016c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0171: brtrue.s IL_0195 + IL_0135: brtrue.s IL_0196 + + .line 8,8 : 18,25 '' + IL_0137: nop + .line 100001,100001 : 0,0 '' + IL_0138: ldloc.s V_10 + IL_013a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_013f: stloc.s V_11 + IL_0141: ldloc.1 + IL_0142: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0147: stloc.s V_12 + IL_0149: ldloc.s V_12 + IL_014b: ldloc.s V_11 + IL_014d: add + IL_014e: ldc.i4.4 + IL_014f: ceq + IL_0151: brfalse.s IL_0196 + + .line 100001,100001 : 0,0 '' + IL_0153: ldloc.s V_10 + IL_0155: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_015a: ldloc.1 + IL_015b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0160: stloc.s V_6 + IL_0162: stloc.s V_5 + IL_0164: br.s IL_0190 + + .line 100001,100001 : 0,0 '' + IL_0166: ldloc.s V_10 + IL_0168: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_016d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0172: brtrue.s IL_0196 .line 6,6 : 16,23 '' - IL_0173: ldstr "three" - IL_0178: ret + IL_0174: ldstr "three" + IL_0179: ret .line 7,7 : 16,23 '' - IL_0179: ldstr "seven" - IL_017e: ret - - .line 5,5 : 5,17 '' - IL_017f: ldloc.2 - IL_0180: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0185: stloc.s V_5 - IL_0187: ldloc.1 - IL_0188: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_018d: stloc.s V_6 + IL_017a: ldstr "seven" + IL_017f: ret + + .line 100001,100001 : 0,0 '' + IL_0180: ldloc.2 + IL_0181: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0186: stloc.s V_5 + IL_0188: ldloc.1 + IL_0189: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_018e: stloc.s V_6 .line 8,8 : 29,35 '' - IL_018f: ldstr "four" - IL_0194: ret + IL_0190: ldstr "four" + IL_0195: ret .line 9,9 : 12,17 '' - IL_0195: ldstr "big" - IL_019a: ret + IL_0196: ldstr "big" + IL_019b: ret } // end of method TestFunction9b::TestFunction9b } // end of class TestFunction9b diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b1.il.bsl index 28857893620..1c6f085474a 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b1.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction9b1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9b1 { - // Offset: 0x00000000 Length: 0x00000208 + // Offset: 0x00000000 Length: 0x00000204 } .mresource public FSharpOptimizationData.TestFunction9b1 { - // Offset: 0x00000210 Length: 0x00000083 + // Offset: 0x00000208 Length: 0x00000083 } .module TestFunction9b1.exe -// MVID: {59B19208-A406-DAF4-A745-03830892B159} +// MVID: {611C4D9E-A406-DAF4-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02730000 +// Image base: 0x052D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static string TestFunction9b(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 x) cil managed { - // Code size 411 (0x19b) + // Code size 412 (0x19c) .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, @@ -69,76 +69,88 @@ [11] int32 V_11, [12] int32 V_12) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b1.fs' + .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b1.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0008: brfalse IL_0195 + IL_0008: brfalse IL_0196 IL_000d: ldloc.0 IL_000e: stloc.1 + .line 100001,100001 : 0,0 '' IL_000f: ldloc.1 IL_0010: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0015: ldc.i4.1 IL_0016: sub IL_0017: switch ( IL_00ff) + .line 100001,100001 : 0,0 '' IL_0020: ldloc.1 IL_0021: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0026: ldc.i4.3 IL_0027: sub IL_0028: switch ( - IL_007a) + IL_0079) + .line 100001,100001 : 0,0 '' IL_0031: ldloc.1 IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_003c: brfalse IL_0195 + IL_003c: brfalse IL_0196 IL_0041: ldloc.1 IL_0042: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0047: stloc.2 + .line 100001,100001 : 0,0 '' IL_0048: ldloc.2 IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_004e: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0053: brtrue IL_0195 - - IL_0058: ldloc.2 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_005e: stloc.3 - IL_005f: ldloc.1 - IL_0060: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0065: stloc.s a - IL_0067: ldloc.s a - IL_0069: ldloc.3 - IL_006a: add - IL_006b: ldc.i4.4 - IL_006c: ceq - IL_006e: brfalse.s IL_0075 - - IL_0070: br IL_017f - - IL_0075: br IL_0195 - - IL_007a: ldloc.1 - IL_007b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0080: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0085: brfalse IL_0195 - - IL_008a: ldloc.1 - IL_008b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0090: stloc.s V_7 - IL_0092: ldloc.s V_7 - IL_0094: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0099: ldc.i4.4 - IL_009a: sub - IL_009b: switch ( + IL_0053: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_0058: nop + .line 100001,100001 : 0,0 '' + IL_0059: ldloc.2 + IL_005a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_005f: stloc.3 + IL_0060: ldloc.1 + IL_0061: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0066: stloc.s a + IL_0068: ldloc.s a + IL_006a: ldloc.3 + IL_006b: add + IL_006c: ldc.i4.4 + IL_006d: ceq + IL_006f: brfalse IL_0196 + + IL_0074: br IL_0180 + + .line 100001,100001 : 0,0 '' + IL_0079: ldloc.1 + IL_007a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_007f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0084: brfalse IL_0196 + + IL_0089: ldloc.1 + IL_008a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_008f: stloc.s V_7 + .line 100001,100001 : 0,0 '' + IL_0091: ldloc.s V_7 + IL_0093: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0098: ldc.i4.4 + IL_0099: sub + IL_009a: switch ( IL_00e9) - IL_00a4: ldloc.s V_7 - IL_00a6: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00ab: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00b0: brtrue IL_0195 - + .line 100001,100001 : 0,0 '' + IL_00a3: ldloc.s V_7 + IL_00a5: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00af: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_00b4: nop + .line 100001,100001 : 0,0 '' IL_00b5: ldloc.s V_7 IL_00b7: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00bc: stloc.s V_8 @@ -150,90 +162,100 @@ IL_00ca: add IL_00cb: ldc.i4.4 IL_00cc: ceq - IL_00ce: brfalse IL_0195 + IL_00ce: brfalse IL_0196 + .line 100001,100001 : 0,0 '' IL_00d3: ldloc.s V_7 IL_00d5: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00da: ldloc.1 IL_00db: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00e0: stloc.s V_6 IL_00e2: stloc.s V_5 - IL_00e4: br IL_018f + IL_00e4: br IL_0190 + .line 100001,100001 : 0,0 '' IL_00e9: ldloc.s V_7 IL_00eb: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_00f0: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00f5: brtrue IL_0195 + IL_00f5: brtrue IL_0196 - IL_00fa: br IL_0179 + IL_00fa: br IL_017a + .line 100001,100001 : 0,0 '' IL_00ff: ldloc.1 IL_0100: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0105: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_010a: brfalse IL_0195 + IL_010a: brfalse IL_0196 IL_010f: ldloc.1 IL_0110: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0115: stloc.s V_10 + .line 100001,100001 : 0,0 '' IL_0117: ldloc.s V_10 IL_0119: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_011e: ldc.i4.2 IL_011f: sub IL_0120: switch ( - IL_0165) + IL_0166) + .line 100001,100001 : 0,0 '' IL_0129: ldloc.s V_10 IL_012b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0130: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0135: brtrue.s IL_0195 - - IL_0137: ldloc.s V_10 - IL_0139: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_013e: stloc.s V_11 - IL_0140: ldloc.1 - IL_0141: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0146: stloc.s V_12 - IL_0148: ldloc.s V_12 - IL_014a: ldloc.s V_11 - IL_014c: add - IL_014d: ldc.i4.4 - IL_014e: ceq - IL_0150: brfalse.s IL_0195 - - IL_0152: ldloc.s V_10 - IL_0154: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0159: ldloc.1 - IL_015a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_015f: stloc.s V_6 - IL_0161: stloc.s V_5 - IL_0163: br.s IL_018f - - IL_0165: ldloc.s V_10 - IL_0167: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_016c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0171: brtrue.s IL_0195 + IL_0135: brtrue.s IL_0196 + + .line 8,8 : 18,25 '' + IL_0137: nop + .line 100001,100001 : 0,0 '' + IL_0138: ldloc.s V_10 + IL_013a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_013f: stloc.s V_11 + IL_0141: ldloc.1 + IL_0142: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0147: stloc.s V_12 + IL_0149: ldloc.s V_12 + IL_014b: ldloc.s V_11 + IL_014d: add + IL_014e: ldc.i4.4 + IL_014f: ceq + IL_0151: brfalse.s IL_0196 + + .line 100001,100001 : 0,0 '' + IL_0153: ldloc.s V_10 + IL_0155: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_015a: ldloc.1 + IL_015b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0160: stloc.s V_6 + IL_0162: stloc.s V_5 + IL_0164: br.s IL_0190 + + .line 100001,100001 : 0,0 '' + IL_0166: ldloc.s V_10 + IL_0168: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_016d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0172: brtrue.s IL_0196 .line 6,6 : 16,23 '' - IL_0173: ldstr "three" - IL_0178: ret + IL_0174: ldstr "three" + IL_0179: ret .line 7,7 : 16,23 '' - IL_0179: ldstr "seven" - IL_017e: ret - - .line 5,5 : 5,17 '' - IL_017f: ldloc.2 - IL_0180: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0185: stloc.s V_5 - IL_0187: ldloc.1 - IL_0188: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_018d: stloc.s V_6 + IL_017a: ldstr "seven" + IL_017f: ret + + .line 100001,100001 : 0,0 '' + IL_0180: ldloc.2 + IL_0181: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0186: stloc.s V_5 + IL_0188: ldloc.1 + IL_0189: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_018e: stloc.s V_6 .line 8,8 : 29,35 '' - IL_018f: ldstr "four" - IL_0194: ret + IL_0190: ldstr "four" + IL_0195: ret .line 9,9 : 12,17 '' - IL_0195: ldstr "big" - IL_019a: ret + IL_0196: ldstr "big" + IL_019b: ret } // end of method TestFunction9b1::TestFunction9b } // end of class TestFunction9b1 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b2.il.bsl index 005b49c3081..2552f87ab2d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b2.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction9b2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9b2 { - // Offset: 0x00000000 Length: 0x00000208 + // Offset: 0x00000000 Length: 0x00000204 } .mresource public FSharpOptimizationData.TestFunction9b2 { - // Offset: 0x00000210 Length: 0x00000083 + // Offset: 0x00000208 Length: 0x00000083 } .module TestFunction9b2.exe -// MVID: {59B19208-9C0B-E35E-A745-03830892B159} +// MVID: {611C4D9E-9C0B-E35E-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00730000 +// Image base: 0x06C20000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static string TestFunction9b(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 x) cil managed { - // Code size 411 (0x19b) + // Code size 412 (0x19c) .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, @@ -69,76 +69,88 @@ [11] int32 V_11, [12] int32 V_12) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b2.fs' + .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b2.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0008: brfalse IL_0195 + IL_0008: brfalse IL_0196 IL_000d: ldloc.0 IL_000e: stloc.1 + .line 100001,100001 : 0,0 '' IL_000f: ldloc.1 IL_0010: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0015: ldc.i4.1 IL_0016: sub IL_0017: switch ( IL_00ff) + .line 100001,100001 : 0,0 '' IL_0020: ldloc.1 IL_0021: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0026: ldc.i4.3 IL_0027: sub IL_0028: switch ( - IL_007a) + IL_0079) + .line 100001,100001 : 0,0 '' IL_0031: ldloc.1 IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_003c: brfalse IL_0195 + IL_003c: brfalse IL_0196 IL_0041: ldloc.1 IL_0042: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0047: stloc.2 + .line 100001,100001 : 0,0 '' IL_0048: ldloc.2 IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_004e: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0053: brtrue IL_0195 - - IL_0058: ldloc.2 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_005e: stloc.3 - IL_005f: ldloc.1 - IL_0060: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0065: stloc.s a - IL_0067: ldloc.s a - IL_0069: ldloc.3 - IL_006a: add - IL_006b: ldc.i4.4 - IL_006c: ceq - IL_006e: brfalse.s IL_0075 - - IL_0070: br IL_017f - - IL_0075: br IL_0195 - - IL_007a: ldloc.1 - IL_007b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0080: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0085: brfalse IL_0195 - - IL_008a: ldloc.1 - IL_008b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0090: stloc.s V_7 - IL_0092: ldloc.s V_7 - IL_0094: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0099: ldc.i4.4 - IL_009a: sub - IL_009b: switch ( + IL_0053: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_0058: nop + .line 100001,100001 : 0,0 '' + IL_0059: ldloc.2 + IL_005a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_005f: stloc.3 + IL_0060: ldloc.1 + IL_0061: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0066: stloc.s a + IL_0068: ldloc.s a + IL_006a: ldloc.3 + IL_006b: add + IL_006c: ldc.i4.4 + IL_006d: ceq + IL_006f: brfalse IL_0196 + + IL_0074: br IL_0180 + + .line 100001,100001 : 0,0 '' + IL_0079: ldloc.1 + IL_007a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_007f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0084: brfalse IL_0196 + + IL_0089: ldloc.1 + IL_008a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_008f: stloc.s V_7 + .line 100001,100001 : 0,0 '' + IL_0091: ldloc.s V_7 + IL_0093: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0098: ldc.i4.4 + IL_0099: sub + IL_009a: switch ( IL_00e9) - IL_00a4: ldloc.s V_7 - IL_00a6: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00ab: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00b0: brtrue IL_0195 - + .line 100001,100001 : 0,0 '' + IL_00a3: ldloc.s V_7 + IL_00a5: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00af: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_00b4: nop + .line 100001,100001 : 0,0 '' IL_00b5: ldloc.s V_7 IL_00b7: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00bc: stloc.s V_8 @@ -150,90 +162,100 @@ IL_00ca: add IL_00cb: ldc.i4.4 IL_00cc: ceq - IL_00ce: brfalse IL_0195 + IL_00ce: brfalse IL_0196 + .line 100001,100001 : 0,0 '' IL_00d3: ldloc.s V_7 IL_00d5: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00da: ldloc.1 IL_00db: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00e0: stloc.s V_6 IL_00e2: stloc.s V_5 - IL_00e4: br IL_018f + IL_00e4: br IL_0190 + .line 100001,100001 : 0,0 '' IL_00e9: ldloc.s V_7 IL_00eb: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_00f0: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00f5: brtrue IL_0195 + IL_00f5: brtrue IL_0196 - IL_00fa: br IL_0179 + IL_00fa: br IL_017a + .line 100001,100001 : 0,0 '' IL_00ff: ldloc.1 IL_0100: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0105: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_010a: brfalse IL_0195 + IL_010a: brfalse IL_0196 IL_010f: ldloc.1 IL_0110: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0115: stloc.s V_10 + .line 100001,100001 : 0,0 '' IL_0117: ldloc.s V_10 IL_0119: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_011e: ldc.i4.2 IL_011f: sub IL_0120: switch ( - IL_0165) + IL_0166) + .line 100001,100001 : 0,0 '' IL_0129: ldloc.s V_10 IL_012b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0130: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0135: brtrue.s IL_0195 - - IL_0137: ldloc.s V_10 - IL_0139: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_013e: stloc.s V_11 - IL_0140: ldloc.1 - IL_0141: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0146: stloc.s V_12 - IL_0148: ldloc.s V_12 - IL_014a: ldloc.s V_11 - IL_014c: add - IL_014d: ldc.i4.4 - IL_014e: ceq - IL_0150: brfalse.s IL_0195 - - IL_0152: ldloc.s V_10 - IL_0154: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0159: ldloc.1 - IL_015a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_015f: stloc.s V_6 - IL_0161: stloc.s V_5 - IL_0163: br.s IL_018f - - IL_0165: ldloc.s V_10 - IL_0167: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_016c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0171: brtrue.s IL_0195 + IL_0135: brtrue.s IL_0196 + + .line 8,8 : 18,25 '' + IL_0137: nop + .line 100001,100001 : 0,0 '' + IL_0138: ldloc.s V_10 + IL_013a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_013f: stloc.s V_11 + IL_0141: ldloc.1 + IL_0142: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0147: stloc.s V_12 + IL_0149: ldloc.s V_12 + IL_014b: ldloc.s V_11 + IL_014d: add + IL_014e: ldc.i4.4 + IL_014f: ceq + IL_0151: brfalse.s IL_0196 + + .line 100001,100001 : 0,0 '' + IL_0153: ldloc.s V_10 + IL_0155: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_015a: ldloc.1 + IL_015b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0160: stloc.s V_6 + IL_0162: stloc.s V_5 + IL_0164: br.s IL_0190 + + .line 100001,100001 : 0,0 '' + IL_0166: ldloc.s V_10 + IL_0168: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_016d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0172: brtrue.s IL_0196 .line 6,6 : 16,23 '' - IL_0173: ldstr "three" - IL_0178: ret + IL_0174: ldstr "three" + IL_0179: ret .line 7,7 : 16,23 '' - IL_0179: ldstr "seven" - IL_017e: ret - - .line 5,5 : 5,17 '' - IL_017f: ldloc.2 - IL_0180: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0185: stloc.s V_5 - IL_0187: ldloc.1 - IL_0188: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_018d: stloc.s V_6 + IL_017a: ldstr "seven" + IL_017f: ret + + .line 100001,100001 : 0,0 '' + IL_0180: ldloc.2 + IL_0181: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0186: stloc.s V_5 + IL_0188: ldloc.1 + IL_0189: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_018e: stloc.s V_6 .line 8,8 : 29,35 '' - IL_018f: ldstr "four" - IL_0194: ret + IL_0190: ldstr "four" + IL_0195: ret .line 9,9 : 12,17 '' - IL_0195: ldstr "big" - IL_019a: ret + IL_0196: ldstr "big" + IL_019b: ret } // end of method TestFunction9b2::TestFunction9b } // end of class TestFunction9b2 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b3.il.bsl index dc4f68ffb80..27c44babf31 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/TestFunctions/Testfunction9b3.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TestFunction9b3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TestFunction9b3 { - // Offset: 0x00000000 Length: 0x00000208 + // Offset: 0x00000000 Length: 0x00000204 } .mresource public FSharpOptimizationData.TestFunction9b3 { - // Offset: 0x00000210 Length: 0x00000083 + // Offset: 0x00000208 Length: 0x00000083 } .module TestFunction9b3.exe -// MVID: {59B19208-C1A4-612A-A745-03830892B159} +// MVID: {611C4D9E-C1A4-612A-A745-03839E4D1C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00680000 +// Image base: 0x06690000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,7 +53,7 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static string TestFunction9b(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 x) cil managed { - // Code size 411 (0x19b) + // Code size 412 (0x19c) .maxstack 4 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_0, [1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 V_1, @@ -69,76 +69,88 @@ [11] int32 V_11, [12] int32 V_12) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b3.fs' + .line 5,5 : 5,17 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\TestFunctions\\TestFunction9b3.fs' IL_0000: ldarg.0 IL_0001: stloc.0 + .line 100001,100001 : 0,0 '' IL_0002: ldloc.0 IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0008: brfalse IL_0195 + IL_0008: brfalse IL_0196 IL_000d: ldloc.0 IL_000e: stloc.1 + .line 100001,100001 : 0,0 '' IL_000f: ldloc.1 IL_0010: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0015: ldc.i4.1 IL_0016: sub IL_0017: switch ( IL_00ff) + .line 100001,100001 : 0,0 '' IL_0020: ldloc.1 IL_0021: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_0026: ldc.i4.3 IL_0027: sub IL_0028: switch ( - IL_007a) + IL_0079) + .line 100001,100001 : 0,0 '' IL_0031: ldloc.1 IL_0032: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0037: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_003c: brfalse IL_0195 + IL_003c: brfalse IL_0196 IL_0041: ldloc.1 IL_0042: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0047: stloc.2 + .line 100001,100001 : 0,0 '' IL_0048: ldloc.2 IL_0049: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_004e: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0053: brtrue IL_0195 - - IL_0058: ldloc.2 - IL_0059: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_005e: stloc.3 - IL_005f: ldloc.1 - IL_0060: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0065: stloc.s a - IL_0067: ldloc.s a - IL_0069: ldloc.3 - IL_006a: add - IL_006b: ldc.i4.4 - IL_006c: ceq - IL_006e: brfalse.s IL_0075 - - IL_0070: br IL_017f - - IL_0075: br IL_0195 - - IL_007a: ldloc.1 - IL_007b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0080: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0085: brfalse IL_0195 - - IL_008a: ldloc.1 - IL_008b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0090: stloc.s V_7 - IL_0092: ldloc.s V_7 - IL_0094: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0099: ldc.i4.4 - IL_009a: sub - IL_009b: switch ( + IL_0053: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_0058: nop + .line 100001,100001 : 0,0 '' + IL_0059: ldloc.2 + IL_005a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_005f: stloc.3 + IL_0060: ldloc.1 + IL_0061: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0066: stloc.s a + IL_0068: ldloc.s a + IL_006a: ldloc.3 + IL_006b: add + IL_006c: ldc.i4.4 + IL_006d: ceq + IL_006f: brfalse IL_0196 + + IL_0074: br IL_0180 + + .line 100001,100001 : 0,0 '' + IL_0079: ldloc.1 + IL_007a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_007f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0084: brfalse IL_0196 + + IL_0089: ldloc.1 + IL_008a: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_008f: stloc.s V_7 + .line 100001,100001 : 0,0 '' + IL_0091: ldloc.s V_7 + IL_0093: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0098: ldc.i4.4 + IL_0099: sub + IL_009a: switch ( IL_00e9) - IL_00a4: ldloc.s V_7 - IL_00a6: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00ab: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00b0: brtrue IL_0195 - + .line 100001,100001 : 0,0 '' + IL_00a3: ldloc.s V_7 + IL_00a5: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_00af: brtrue IL_0196 + + .line 8,8 : 18,25 '' + IL_00b4: nop + .line 100001,100001 : 0,0 '' IL_00b5: ldloc.s V_7 IL_00b7: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00bc: stloc.s V_8 @@ -150,90 +162,100 @@ IL_00ca: add IL_00cb: ldc.i4.4 IL_00cc: ceq - IL_00ce: brfalse IL_0195 + IL_00ce: brfalse IL_0196 + .line 100001,100001 : 0,0 '' IL_00d3: ldloc.s V_7 IL_00d5: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00da: ldloc.1 IL_00db: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_00e0: stloc.s V_6 IL_00e2: stloc.s V_5 - IL_00e4: br IL_018f + IL_00e4: br IL_0190 + .line 100001,100001 : 0,0 '' IL_00e9: ldloc.s V_7 IL_00eb: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_00f0: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_00f5: brtrue IL_0195 + IL_00f5: brtrue IL_0196 - IL_00fa: br IL_0179 + IL_00fa: br IL_017a + .line 100001,100001 : 0,0 '' IL_00ff: ldloc.1 IL_0100: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0105: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_010a: brfalse IL_0195 + IL_010a: brfalse IL_0196 IL_010f: ldloc.1 IL_0110: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0115: stloc.s V_10 + .line 100001,100001 : 0,0 '' IL_0117: ldloc.s V_10 IL_0119: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() IL_011e: ldc.i4.2 IL_011f: sub IL_0120: switch ( - IL_0165) + IL_0166) + .line 100001,100001 : 0,0 '' IL_0129: ldloc.s V_10 IL_012b: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() IL_0130: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0135: brtrue.s IL_0195 - - IL_0137: ldloc.s V_10 - IL_0139: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_013e: stloc.s V_11 - IL_0140: ldloc.1 - IL_0141: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0146: stloc.s V_12 - IL_0148: ldloc.s V_12 - IL_014a: ldloc.s V_11 - IL_014c: add - IL_014d: ldc.i4.4 - IL_014e: ceq - IL_0150: brfalse.s IL_0195 - - IL_0152: ldloc.s V_10 - IL_0154: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0159: ldloc.1 - IL_015a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_015f: stloc.s V_6 - IL_0161: stloc.s V_5 - IL_0163: br.s IL_018f - - IL_0165: ldloc.s V_10 - IL_0167: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_016c: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() - IL_0171: brtrue.s IL_0195 + IL_0135: brtrue.s IL_0196 + + .line 8,8 : 18,25 '' + IL_0137: nop + .line 100001,100001 : 0,0 '' + IL_0138: ldloc.s V_10 + IL_013a: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_013f: stloc.s V_11 + IL_0141: ldloc.1 + IL_0142: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0147: stloc.s V_12 + IL_0149: ldloc.s V_12 + IL_014b: ldloc.s V_11 + IL_014d: add + IL_014e: ldc.i4.4 + IL_014f: ceq + IL_0151: brfalse.s IL_0196 + + .line 100001,100001 : 0,0 '' + IL_0153: ldloc.s V_10 + IL_0155: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_015a: ldloc.1 + IL_015b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0160: stloc.s V_6 + IL_0162: stloc.s V_5 + IL_0164: br.s IL_0190 + + .line 100001,100001 : 0,0 '' + IL_0166: ldloc.s V_10 + IL_0168: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_016d: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_TailOrNull() + IL_0172: brtrue.s IL_0196 .line 6,6 : 16,23 '' - IL_0173: ldstr "three" - IL_0178: ret + IL_0174: ldstr "three" + IL_0179: ret .line 7,7 : 16,23 '' - IL_0179: ldstr "seven" - IL_017e: ret - - .line 5,5 : 5,17 '' - IL_017f: ldloc.2 - IL_0180: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_0185: stloc.s V_5 - IL_0187: ldloc.1 - IL_0188: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() - IL_018d: stloc.s V_6 + IL_017a: ldstr "seven" + IL_017f: ret + + .line 100001,100001 : 0,0 '' + IL_0180: ldloc.2 + IL_0181: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_0186: stloc.s V_5 + IL_0188: ldloc.1 + IL_0189: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_HeadOrDefault() + IL_018e: stloc.s V_6 .line 8,8 : 29,35 '' - IL_018f: ldstr "four" - IL_0194: ret + IL_0190: ldstr "four" + IL_0195: ret .line 9,9 : 12,17 '' - IL_0195: ldstr "big" - IL_019a: ret + IL_0196: ldstr "big" + IL_019b: ret } // end of method TestFunction9b3::TestFunction9b } // end of class TestFunction9b3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/OptionalArg01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/OptionalArg01.il.bsl index 4474ab67ae3..6db863794d5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/OptionalArg01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/OptionalArg01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.7.3081.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:6:0:0 + .ver 5:0:0:0 } .assembly OptionalArg01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.OptionalArg01 { - // Offset: 0x00000000 Length: 0x00000466 + // Offset: 0x00000000 Length: 0x0000045A } .mresource public FSharpOptimizationData.OptionalArg01 { - // Offset: 0x00000470 Length: 0x00000445 + // Offset: 0x00000460 Length: 0x00000445 } .module OptionalArg01.exe -// MVID: {5CB489E1-4F48-B5AF-A745-0383E189B45C} +// MVID: {6124063B-4F48-B5AF-A745-03833B062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x067B0000 +// Image base: 0x04EE0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -61,7 +61,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\OptionalArg01.fs' + .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\OptionalArg01.fs' IL_0000: ldarg.0 IL_0001: callvirt instance void [mscorlib]System.Object::.ctor() IL_0006: ldarg.0 @@ -98,94 +98,110 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.OptionalArgumentAttribute::.ctor() = ( 01 00 00 00 ) .param [2] .custom instance void [FSharp.Core]Microsoft.FSharp.Core.OptionalArgumentAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 83 (0x53) + // Code size 93 (0x5d) .maxstack 4 - .locals init ([0] int32 count, - [1] int32 V_1, + .locals init ([0] int32 'count (shadowed)', + [1] int32 count, [2] class [mscorlib]System.Collections.Generic.List`1 attribs, [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 V_3, [4] class OptionalArg01/A v2) .line 10,10 : 9,44 '' - IL_0000: ldarg.0 - IL_0001: brfalse.s IL_0007 - - .line 8,8 : 61,70 '' - IL_0003: ldc.i4.1 + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0004: nop - IL_0005: br.s IL_0009 + IL_0001: ldarg.0 + IL_0002: brfalse.s IL_0006 + + IL_0004: br.s IL_000a .line 8,8 : 43,48 '' - IL_0007: ldc.i4.0 + IL_0006: ldc.i4.0 + .line 16707566,16707566 : 0,0 '' + IL_0007: nop + IL_0008: br.s IL_000c + + .line 8,8 : 61,70 '' + IL_000a: ldc.i4.1 .line 16707566,16707566 : 0,0 '' - IL_0008: nop + IL_000b: nop .line 16707566,16707566 : 0,0 '' - IL_0009: stloc.0 + IL_000c: stloc.0 .line 10,10 : 9,44 '' - IL_000a: ldarg.1 - IL_000b: brfalse.s IL_0013 - - .line 9,9 : 61,70 '' - IL_000d: ldloc.0 - IL_000e: ldc.i4.1 - IL_000f: add + IL_000d: nop .line 16707566,16707566 : 0,0 '' - IL_0010: nop - IL_0011: br.s IL_0015 + IL_000e: ldarg.1 + IL_000f: brfalse.s IL_0013 + + IL_0011: br.s IL_0017 .line 9,9 : 43,48 '' IL_0013: ldloc.0 .line 16707566,16707566 : 0,0 '' IL_0014: nop + IL_0015: br.s IL_001b + + .line 9,9 : 61,70 '' + IL_0017: ldloc.0 + IL_0018: ldc.i4.1 + IL_0019: add + .line 16707566,16707566 : 0,0 '' + IL_001a: nop .line 16707566,16707566 : 0,0 '' - IL_0015: stloc.1 + IL_001b: stloc.1 .line 10,10 : 9,44 '' - IL_0016: ldloc.1 - IL_0017: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor(int32) - IL_001c: stloc.2 - IL_001d: ldarg.0 - IL_001e: brfalse.s IL_0035 - - IL_0020: ldarg.0 - IL_0021: stloc.3 - IL_0022: ldloc.3 - IL_0023: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0028: stloc.s v2 - .line 11,11 : 47,62 '' - IL_002a: ldloc.2 - IL_002b: ldloc.s v2 - IL_002d: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_001c: ldloc.1 + IL_001d: newobj instance void class [mscorlib]System.Collections.Generic.List`1::.ctor(int32) + IL_0022: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0032: nop - IL_0033: br.s IL_0037 + IL_0023: ldarg.0 + IL_0024: brfalse.s IL_0028 + + IL_0026: br.s IL_002c .line 11,11 : 31,33 '' - IL_0035: nop + IL_0028: nop .line 16707566,16707566 : 0,0 '' - IL_0036: nop - IL_0037: ldarg.1 - IL_0038: brfalse.s IL_004f - - IL_003a: ldarg.1 - IL_003b: stloc.3 - IL_003c: ldloc.3 - IL_003d: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() - IL_0042: stloc.s v2 - .line 12,12 : 47,62 '' - IL_0044: ldloc.2 - IL_0045: ldloc.s v2 - IL_0047: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0029: nop + IL_002a: br.s IL_003f + + .line 16707566,16707566 : 0,0 '' + IL_002c: ldarg.0 + IL_002d: stloc.3 + IL_002e: ldloc.3 + IL_002f: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_0034: stloc.s v2 + .line 11,11 : 47,62 '' + IL_0036: ldloc.2 + IL_0037: ldloc.s v2 + IL_0039: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) .line 16707566,16707566 : 0,0 '' - IL_004c: nop - IL_004d: br.s IL_0051 + IL_003e: nop + .line 16707566,16707566 : 0,0 '' + IL_003f: ldarg.1 + IL_0040: brfalse.s IL_0044 + + IL_0042: br.s IL_0048 .line 12,12 : 31,33 '' - IL_004f: nop + IL_0044: nop + .line 16707566,16707566 : 0,0 '' + IL_0045: nop + IL_0046: br.s IL_005b + + .line 16707566,16707566 : 0,0 '' + IL_0048: ldarg.1 + IL_0049: stloc.3 + IL_004a: ldloc.3 + IL_004b: call instance !0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1::get_Value() + IL_0050: stloc.s v2 + .line 12,12 : 47,62 '' + IL_0052: ldloc.2 + IL_0053: ldloc.s v2 + IL_0055: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) .line 16707566,16707566 : 0,0 '' - IL_0050: nop + IL_005a: nop .line 13,13 : 9,16 '' - IL_0051: ldloc.2 - IL_0052: ret + IL_005b: ldloc.2 + IL_005c: ret } // end of method C::F } // end of class C diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple01.il.bsl index 36d04a11dc5..6b7cc9c8d49 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple01 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple01 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple01.exe -// MVID: {59B19208-6FDB-3E0B-A745-03830892B159} +// MVID: {60B68B97-6FDB-3E0B-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x07270000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ // Code size 1 (0x1) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,10 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple01.fs' + .line 3,3 : 9,10 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple01.fs' IL_0000: ret } // end of method $Tuple01::main@ diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple02.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple02.il.bsl index a668638daa3..3f0835a20bc 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple02.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple02 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple02 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple02.exe -// MVID: {59B19208-ECCC-7D58-A745-03830892B159} +// MVID: {60B68B97-ECCC-7D58-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02C00000 +// Image base: 0x070F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,12 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple02.fs' + .line 3,3 : 9,12 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple02.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple03.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple03.il.bsl index db8af4b0cfa..694e959cf21 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple03.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple03 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple03 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple03 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple03.exe -// MVID: {59B19208-AD65-A299-A745-03830892B159} +// MVID: {60B68B97-AD65-A299-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AF0000 +// Image base: 0x05690000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 10 (0xa) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,14 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple03.fs' + .line 3,3 : 9,14 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple03.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple04.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple04.il.bsl index a35c62c665d..67ffcf00724 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple04.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple04 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple04 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple04.exe -// MVID: {59B19208-6A2E-9E97-A745-03830892B159} +// MVID: {60B68B97-6A2E-9E97-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x001E0000 +// Image base: 0x06E90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 11 (0xb) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,16 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple04.fs' + .line 3,3 : 9,16 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple04.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple05.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple05.il.bsl index 07388eb7f39..0626f63d7be 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple05.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple05 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple05 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple05.exe -// MVID: {59B19208-349F-319F-A745-03830892B159} +// MVID: {60B68B97-349F-319F-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00730000 +// Image base: 0x06BA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 12 (0xc) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,18 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple05.fs' + .line 3,3 : 9,18 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple05.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple06.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple06.il.bsl index adbe519a887..26e99d88dca 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple06.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple06 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple06 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple06 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple06.exe -// MVID: {59B19208-67E0-4675-A745-03830892B159} +// MVID: {60B68B97-67E0-4675-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02A20000 +// Image base: 0x06A80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 13 (0xd) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,20 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple06.fs' + .line 3,3 : 9,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple06.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple07.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple07.il.bsl index e42f75990a8..c4d97daf2ef 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple07.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple07 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple07 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple07 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple07.exe -// MVID: {59B19208-7229-962D-A745-03830892B159} +// MVID: {60B68B97-7229-962D-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x017A0000 +// Image base: 0x00F10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 14 (0xe) .maxstack 9 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,22 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple07.fs' + .line 3,3 : 9,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple07.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple08.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple08.il.bsl index d029623cf32..72e7d3feed7 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple08.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/Tuple08.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Tuple08 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Tuple08 { - // Offset: 0x00000000 Length: 0x0000013F + // Offset: 0x00000000 Length: 0x0000013B } .mresource public FSharpOptimizationData.Tuple08 { - // Offset: 0x00000148 Length: 0x0000004E + // Offset: 0x00000140 Length: 0x0000004E } .module Tuple08.exe -// MVID: {59B19208-E542-67B3-A745-03830892B159} +// MVID: {60B68B97-E542-67B3-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00390000 +// Image base: 0x00E80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 20 (0x14) .maxstack 10 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,24 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\Tuple08.fs' + .line 3,3 : 9,24 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\Tuple08.fs' IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: ldc.i4.3 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleElimination.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleElimination.il.bsl index 8feaefd480e..f04b9c743b8 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleElimination.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleElimination.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly TupleElimination { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.TupleElimination { - // Offset: 0x00000000 Length: 0x00000236 + // Offset: 0x00000000 Length: 0x0000022A } .mresource public FSharpOptimizationData.TupleElimination { - // Offset: 0x00000240 Length: 0x0000007B + // Offset: 0x00000230 Length: 0x0000007B } .module TupleElimination.exe -// MVID: {5B17FC67-DFDD-92DF-A745-038367FC175B} +// MVID: {6124063B-DFDD-92DF-A745-03833B062461} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02760000 +// Image base: 0x06D10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -51,83 +56,109 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) - .method assembly static void p@5(!!a v) cil managed - { - // Code size 30 (0x1e) - .maxstack 4 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_0) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 15,27 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\TupleElimination.fs' - IL_0000: ldstr "%A" - IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,!!a>::.ctor(string) - IL_000a: stloc.0 - IL_000b: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() - IL_0010: ldloc.0 - IL_0011: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, - class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) - IL_0016: ldarg.0 - IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_001c: pop - IL_001d: ret - } // end of method TupleElimination::p@5 - .method public static int32 main(string[] argv) cil managed { .entrypoint .custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 79 (0x4f) + // Code size 205 (0xcd) .maxstack 5 .locals init ([0] class [mscorlib]System.Collections.Generic.Dictionary`2 dic, - [1] int32 V_1, - [2] bool V_2, - [3] int64 V_3, - [4] bool V_4, - [5] class [mscorlib]System.Tuple`2 t) - .line 7,7 : 5,64 '' + [1] int32 i, + [2] bool 'b (shadowed)', + [3] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_3, + [4] int32 V_4, + [5] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_5, + [6] int64 l, + [7] bool b, + [8] class [mscorlib]System.Tuple`2 t, + [9] int64 V_9, + [10] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_10, + [11] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [FSharp.Core]Microsoft.FSharp.Core.Unit>,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_11) + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 7,7 : 5,64 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\TupleElimination.fs' IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.Dictionary`2::.ctor() IL_0005: stloc.0 .line 9,9 : 31,48 '' IL_0006: ldloc.0 IL_0007: ldc.i4.1 - IL_0008: ldloca.s V_1 + IL_0008: ldloca.s i IL_000a: callvirt instance bool class [mscorlib]System.Collections.Generic.Dictionary`2::TryGetValue(!0, !1&) IL_000f: stloc.2 - .line 10,10 : 5,6 '' - IL_0010: ldloc.2 - IL_0011: call void TupleElimination::p@5(!!0) - IL_0016: nop - .line 11,11 : 5,6 '' - IL_0017: ldloc.1 - IL_0018: call void TupleElimination::p@5(!!0) - IL_001d: nop + .line 10,10 : 5,8 '' + IL_0010: ldstr "%A" + IL_0015: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,bool>::.ctor(string) + IL_001a: stloc.3 + IL_001b: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0020: ldloc.3 + IL_0021: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0026: ldloc.2 + IL_0027: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_002c: pop + .line 11,11 : 5,8 '' + IL_002d: ldloc.1 + IL_002e: stloc.s V_4 + IL_0030: ldstr "%A" + IL_0035: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) + IL_003a: stloc.s V_5 + IL_003c: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0041: ldloc.s V_5 + IL_0043: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_0048: ldloc.s V_4 + IL_004a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_004f: pop .line 14,14 : 38,65 '' - IL_001e: ldstr "123" - IL_0023: ldloca.s V_3 - IL_0025: call bool [mscorlib]System.Int64::TryParse(string, + IL_0050: ldstr "123" + IL_0055: ldloca.s l + IL_0057: call bool [mscorlib]System.Int64::TryParse(string, int64&) - IL_002a: stloc.s V_4 + IL_005c: stloc.s b .line 14,14 : 5,65 '' - IL_002c: ldloc.s V_4 - IL_002e: ldloc.3 - IL_002f: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, + IL_005e: ldloc.s b + IL_0060: ldloc.s l + IL_0062: newobj instance void class [mscorlib]System.Tuple`2::.ctor(!0, !1) - IL_0034: stloc.s t - .line 15,15 : 5,6 '' - IL_0036: ldloc.s V_4 - IL_0038: call void TupleElimination::p@5(!!0) - IL_003d: nop - .line 16,16 : 5,6 '' - IL_003e: ldloc.3 - IL_003f: call void TupleElimination::p@5(!!0) - IL_0044: nop - .line 21,21 : 5,6 '' - IL_0045: ldloc.s t - IL_0047: call void TupleElimination::p@5>(!!0) - IL_004c: nop + IL_0067: stloc.s t + .line 15,15 : 5,8 '' + IL_0069: ldstr "%A" + IL_006e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,bool>::.ctor(string) + IL_0073: stloc.3 + IL_0074: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_0079: ldloc.3 + IL_007a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_007f: ldloc.s b + IL_0081: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0086: pop + .line 16,16 : 5,8 '' + IL_0087: ldloc.s l + IL_0089: stloc.s V_9 + IL_008b: ldstr "%A" + IL_0090: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int64>::.ctor(string) + IL_0095: stloc.s V_10 + IL_0097: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_009c: ldloc.s V_10 + IL_009e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00a3: ldloc.s V_9 + IL_00a5: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_00aa: pop + .line 21,21 : 5,9 '' + IL_00ab: ldstr "%A" + IL_00b0: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [FSharp.Core]Microsoft.FSharp.Core.Unit>,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [mscorlib]System.Tuple`2>::.ctor(string) + IL_00b5: stloc.s V_11 + IL_00b7: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() + IL_00bc: ldloc.s V_11 + IL_00be: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [mscorlib]System.IO.TextWriter, + class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) + IL_00c3: ldloc.s t + IL_00c5: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0) + IL_00ca: pop .line 23,23 : 5,6 '' - IL_004d: ldc.i4.0 - IL_004e: ret + IL_00cb: ldc.i4.0 + IL_00cc: ret } // end of method TupleElimination::main } // end of class TupleElimination diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleMonster.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleMonster.il.bsl index 1626f867b9d..0a2af12cc38 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleMonster.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/TupleMonster.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly TupleMonster { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.TupleMonster { - // Offset: 0x00000000 Length: 0x00000149 + // Offset: 0x00000000 Length: 0x00000145 } .mresource public FSharpOptimizationData.TupleMonster { // Offset: 0x00000150 Length: 0x00000053 } .module TupleMonster.exe -// MVID: {59B19208-1552-41D8-A745-03830892B159} +// MVID: {60B68B97-1552-41D8-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010B0000 +// Image base: 0x07110000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +66,7 @@ // Code size 74 (0x4a) .maxstack 28 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,137 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\TupleMonster.fs' + .line 3,3 : 9,137 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\TupleMonster.fs' IL_0000: ldc.i4.s 97 IL_0002: ldc.i4.s 98 IL_0004: ldc.i4.s 99 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/ValueTupleAliasConstructor.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/ValueTupleAliasConstructor.il.bsl index 768deb722a1..7682c8bfd4f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/ValueTupleAliasConstructor.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Tuples/ValueTupleAliasConstructor.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,12 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:5:0:0 -} -.assembly extern System.ValueTuple -{ - .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q - .ver 4:0:1:0 + .ver 5:0:0:0 } .assembly ValueTupleAliasConstructor { @@ -34,20 +29,20 @@ } .mresource public FSharpSignatureData.ValueTupleAliasConstructor { - // Offset: 0x00000000 Length: 0x000001EA + // Offset: 0x00000000 Length: 0x000001E0 } .mresource public FSharpOptimizationData.ValueTupleAliasConstructor { - // Offset: 0x000001F0 Length: 0x00000061 + // Offset: 0x000001E8 Length: 0x00000061 } .module ValueTupleAliasConstructor.exe -// MVID: {5B9C53DD-A8CF-BB34-A745-0383DD539C5B} +// MVID: {60B68B97-A8CF-BB34-A745-0383978BB660} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01B00000 +// Image base: 0x00B60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -71,11 +66,11 @@ // Code size 9 (0x9) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 3,3 : 9,22 'c:\\kevinransom\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\Tuples\\ValueTupleAliasConstructor.fs' + .line 3,3 : 9,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\Tuples\\ValueTupleAliasConstructor.fs' IL_0000: ldc.i4.2 IL_0001: ldc.i4.2 - IL_0002: newobj instance void valuetype [System.ValueTuple]System.ValueTuple`2::.ctor(!0, - !1) + IL_0002: newobj instance void valuetype [mscorlib]System.ValueTuple`2::.ctor(!0, + !1) IL_0007: pop IL_0008: ret } // end of method $ValueTupleAliasConstructor::main@ diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs index 0c3c619c33e..324a05b273f 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs @@ -7,7 +7,6 @@ //section='- OUTPUT FILES - ' ! option=delaysign kind=OptionSwitch //section='- OUTPUT FILES - ' ! option=doc kind=OptionString //section='- OUTPUT FILES - ' ! option=keyfile kind=OptionString -//section='- OUTPUT FILES - ' ! option=keycontainer kind=OptionString //section='- OUTPUT FILES - ' ! option=platform kind=OptionString //section='- OUTPUT FILES - ' ! option=nooptimizationdata kind=OptionUnit //section='- OUTPUT FILES - ' ! option=nointerfacedata kind=OptionUnit diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx index e0d7d42cc87..bfc350a2b86 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx @@ -107,7 +107,6 @@ //section='- OUTPUT FILES - ' ! option=delaysign kind=OptionSwitch //section='- OUTPUT FILES - ' ! option=doc kind=OptionString //section='- OUTPUT FILES - ' ! option=keyfile kind=OptionString -//section='- OUTPUT FILES - ' ! option=keycontainer kind=OptionString //section='- OUTPUT FILES - ' ! option=platform kind=OptionString //section='- OUTPUT FILES - ' ! option=nooptimizationdata kind=OptionUnit //section='- OUTPUT FILES - ' ! option=nointerfacedata kind=OptionUnit diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine01.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine01.fs index b2c362464ac..fcb5e10f2ae 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine01.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine01.fs @@ -1,6 +1,6 @@ // #Regression #NoMT #CompilerOptions #RequiresENU // Test that without [--flaterrors] flag multi-line errors are emitted in a regular way, i.e. spanned to more that one line -//This expression was expected to have type +//This expression was expected to have type // ''a list' //but here has type // 'seq<'b>' diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine02.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine02.fs index 8bcc6e508ac..511987567fc 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine02.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/flaterrors/E_MultiLine02.fs @@ -1,5 +1,5 @@ // #Regression #NoMT #CompilerOptions // Test that using [--flaterrors] flag multi-line errors are flattened, i.e. concatenated into one-line error message. -//This expression was expected to have type. ''a list' .but here has type. 'seq<'b>' +//This expression was expected to have type. ''a list' .but here has type. 'seq<'b>' List.rev {1..10} |> ignore diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl index 2ef3abcd84a..853541eca4d 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl @@ -20,7 +20,6 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. --doc: Write the xmldoc of the assembly to the given file --keyfile: Specify a strong name key file ---keycontainer: Specify a strong name key container --platform: Limit which platforms this code can run on: x86, Itanium, x64, anycpu32bitpreferred, or anycpu. The @@ -35,6 +34,9 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. F#-specific metadata --sig: Print the inferred interface of the assembly to a file +--allsigs Print the inferred interfaces of all + compilation files to associated + signature files --nocopyfsharpcore Don't copy FSharp.Core.dll along the produced binaries @@ -48,6 +50,7 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. - RESOURCES - +--win32icon: Specify a Win32 icon file (.ico) --win32res: Specify a Win32 resource file (.res) --win32manifest: Specify a Win32 manifest file --nowin32manifest Do not include the default Win32 @@ -113,6 +116,8 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. - MISCELLANEOUS - --nologo Suppress compiler copyright message +--version Display compiler version banner and + exit --help Display this usage message (Short form: -?) --@ Read response file for more options diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl index 83fd0bfa996..b7f6805220b 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/langversion/langversionhelp.437.1033.bsl @@ -4,4 +4,5 @@ default latest latestmajor 4.6 -4.7 (Default) \ No newline at end of file +4.7 +5.0 (Default) \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/env.lst index 10a5d4db368..46f6ce80202 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/env.lst @@ -1,7 +1,6 @@ # Functional: the option does what it is meant to do - SOURCE=noframework01.fs # noframework01.fs - SOURCE=noframework01.fsx COMPILE_ONLY=1 FSIMODE=PIPE # noframework01.fsx + SOURCE=noframework01.fs # noframework01.fs + SOURCE=noframework01.fsx COMPILE_ONLY=1 FSIMODE=PIPE # noframework01.fsx - SOURCE=noframework02.fs COMPILE_ONLY=1 SCFLAGS="--noframework" # noframework02.fs SOURCE=noframework02.fsx COMPILE_ONLY=1 SCFLAGS="--noframework" FSIMODE=FEED # noframework02.fsx diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework01.fsx b/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework01.fsx index 758e6cfc2ae..6799d820b70 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework01.fsx +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/noframework/noframework01.fsx @@ -3,8 +3,8 @@ // System.Func<...> is in System.Core.dll (NetFx3.5) -//val f : d:System\.Func -> int -//val it : int = 11 +//val f: d: System\.Func -> int +//val it: int = 11 let f ( d : System.Func ) = d.Invoke() + 1;; diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/out/invalidchar.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/out/invalidchar.fs index 9bad8413f89..5de2702d52d 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/out/invalidchar.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/out/invalidchar.fs @@ -1,3 +1,3 @@ // #NoMT #CompilerOptions -// -exit 0 \ No newline at end of file +// +exit 0 diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/platform/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/platform/env.lst index 7db5fbb8069..5948713b607 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/platform/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/platform/env.lst @@ -27,7 +27,6 @@ SOURCE=platf_01.fs COMPILE_ONLY=1 POSTCMD="\$FSI_PIPE --nologo --quiet --debug- --exec bitnesscheck.fsx" SCFLAGS="--target:library --platform:x86" # library - x86 SOURCE=platf_01.fs COMPILE_ONLY=1 POSTCMD="\$FSI_PIPE --nologo --quiet --debug- --exec bitnesscheck.fsx" SCFLAGS="--target:library --platform:x64" # library - x64 SOURCE=platf_01.fs COMPILE_ONLY=1 POSTCMD="\$FSI_PIPE --nologo --quiet --debug- --exec bitnesscheck.fsx" SCFLAGS="--target:library --platform:Itanium" # library - Itanium - SOURCE=error_16.fs COMPILE_ONLY=1 SCFLAGS="--target:library --platform:anycpu32bitpreferred" # library - anycpu32bitpreferred # Last one wins... SOURCE=platf_01.fs COMPILE_ONLY=1 POSTCMD="\$FSI_PIPE --nologo --quiet --debug- --exec bitnesscheck.fsx" SCFLAGS="--platform:anycpu --platform:x64" @@ -38,25 +37,11 @@ SOURCE=platf_01.fs COMPILE_ONLY=1 POSTCMD="\$FSI_PIPE --nologo --quiet --debug- --exec bitnesscheck.fsx" SCFLAGS="--platform:Itanium --platform:anycpu32bitpreferred" # Option is case sentitive - SOURCE=error_01.fs COMPILE_ONLY=1 SCFLAGS="--PLATFORM:anycpu" - SOURCE=error_02.fs COMPILE_ONLY=1 SCFLAGS="--PlatForm:anycpu" - SOURCE=error_03.fs COMPILE_ONLY=1 SCFLAGS="--platform:ITANIUM" - SOURCE=error_04.fs COMPILE_ONLY=1 SCFLAGS="--platform:ANYCPU" - SOURCE=error_05.fs COMPILE_ONLY=1 SCFLAGS="--platform:X86" - SOURCE=error_06.fs COMPILE_ONLY=1 SCFLAGS="--platform:X64" # Incorrect platform - SOURCE=error_07.fs COMPILE_ONLY=1 SCFLAGS="--platform:IA64" - SOURCE=error_08.fs COMPILE_ONLY=1 SCFLAGS="--platform:i386" - SOURCE=error_09.fs COMPILE_ONLY=1 SCFLAGS="--platform:AMD64" - SOURCE=error_10.fs COMPILE_ONLY=1 SCFLAGS="--platform:PPC" - SOURCE=error_15.fs COMPILE_ONLY=1 SCFLAGS="--platform:ARM" # Mispelled options - SOURCE=error_11.fs COMPILE_ONLY=1 SCFLAGS="--platform-:anycpu" - SOURCE=error_12.fs COMPILE_ONLY=1 SCFLAGS="--PLATFORM+:anycpu" - SOURCE=error_13.fs COMPILE_ONLY=1 SCFLAGS="---platform:anycpu" # Missing argument SOURCE=error_14.fs COMPILE_ONLY=1 TAILFLAGS="--platform" diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/times/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/times/env.lst index 31c2becd404..a66f99f264f 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/times/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/times/env.lst @@ -6,11 +6,8 @@ SOURCE=times01.fs COMPILE_ONLY=1 SCFLAGS="--times --times" # Option is case sentitive - SOURCE=error_01.fs COMPILE_ONLY=1 SCFLAGS="--Times" # Mispelled options - SOURCE=error_02.fs COMPILE_ONLY=1 SCFLAGS="--times-" - SOURCE=error_03.fs COMPILE_ONLY=1 SCFLAGS="--times+" # Missing argument SOURCE=error_04.fs COMPILE_ONLY=1 TAILFLAGS="--times:0" diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/times/times01.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/times/times01.fs index b01b7a501da..63a3663ff4d 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/times/times01.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/times/times01.fs @@ -20,7 +20,6 @@ namespace N2 //TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Typecheck\] //TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Typechecked\] //TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Write XML docs\] -//TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Write HTML docs\] //TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[Encode Interface Data\] //TIME:.+Delta:.+Mem:.+G0:.+G1:.+G2:.+\[TAST -> IL\] //ilwrite: TIME.+Write Started diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/env.lst new file mode 100644 index 00000000000..5016280a55a --- /dev/null +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/env.lst @@ -0,0 +1,3 @@ +# Test tokenize outputs tokens + SOURCE=tokenize01.fs COMPILE_ONLY=1 SCFLAGS="--tokenize" + SOURCE=tokenize02.fs COMPILE_ONLY=1 SCFLAGS="--tokenize-unfiltered" \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize01.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize01.fs new file mode 100644 index 00000000000..48c56e06129 --- /dev/null +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize01.fs @@ -0,0 +1,60 @@ +// #NoMT #CompilerOptions +#light + +namespace N + module M = + let f x = () + f 10 + +//tokenize - got NAMESPACE +//tokenize - got IDENT +//tokenize - got OBLOCKBEGIN +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_COMING_SOON +//tokenize - got MODULE_IS_HERE +//tokenize - got IDENT +//tokenize - got EQUALS +//tokenize - got OBLOCKBEGIN +//tokenize - got OLET +//tokenize - got IDENT +//tokenize - got IDENT +//tokenize - got EQUALS +//tokenize - got OBLOCKBEGIN +//tokenize - got LPAREN +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_COMING_SOON +//tokenize - got RPAREN_IS_HERE +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_IS_HERE +//tokenize - got ODECLEND +//tokenize - got OBLOCKSEP +//tokenize - got IDENT +//tokenize - got INT32 +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_IS_HERE +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_COMING_SOON +//tokenize - got OBLOCKEND_IS_HERE +//tokenize - got EOF \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize02.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize02.fs new file mode 100644 index 00000000000..d139e72caee --- /dev/null +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/tokenize/tokenize02.fs @@ -0,0 +1,22 @@ +// #NoMT #CompilerOptions +#light + +namespace N + module M = + let f x = () + f 10 + +//tokenize - got NAMESPACE +//tokenize - got IDENT +//tokenize - got MODULE +//tokenize - got IDENT +//tokenize - got EQUALS +//tokenize - got LET +//tokenize - got IDENT +//tokenize - got IDENT +//tokenize - got EQUALS +//tokenize - got LPAREN +//tokenize - got RPAREN +//tokenize - got IDENT +//tokenize - got INT32 +//tokenize - got EOF \ No newline at end of file diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/env.lst index 7c71fc18546..f2662fec8b1 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/env.lst @@ -7,7 +7,6 @@ NoMT SOURCE=warn2_level5.fs SCFLAGS="--warn:2 --warnaserror" COMPILE_ONLY=1 # w NoMT SOURCE=warn3_level5.fs SCFLAGS="--warn:3 --warnaserror" COMPILE_ONLY=1 # warn5_level3.fs NoMT SOURCE=warn4_level5.fs SCFLAGS="--warn:4 --warnaserror" COMPILE_ONLY=1 # warn5_level4.fs NoMT SOURCE=warn5_level5.fs SCFLAGS="--warn:5 --warnaserror" COMPILE_ONLY=1 # warn5_level5.fs -NoMT SOURCE=warn5_level5w.fs SCFLAGS="--warn:5" COMPILE_ONLY=1 # warn5_level5w.fs SOURCE=invalid_warning_level_6.fs SCFLAGS="--warn:6" # invalid_warning_level_6.fs SOURCE=nowarn.fs SCFLAGS="--warnaserror" # nowarn.fs @@ -21,6 +20,4 @@ NoMT SOURCE=warn5_level5w.fs SCFLAGS="--warn:5" COMPILE_ONLY=1 # w SOURCE=nowarn_with_warnaserror01.fs SCFLAGS="--warnaserror:FS0040 --warn:4" COMPILE_ONLY=1 # nowarn_with_warnaserror01a.fs SOURCE=nowarn_with_warnaserror02.fs SCFLAGS="--warnaserror:FS0040 --warn:4" COMPILE_ONLY=1 # nowarn_with_warnaserror02a.fs SOURCE=nowarn_with_warnaserror03.fs SCFLAGS="--warnaserror:FS0040 --warn:4" COMPILE_ONLY=1 # nowarn_with_warnaserror03a.fs - SOURCE=nowarn_with_warnaserror01.fs SCFLAGS="--warnaserror:FS0040 --warn:4" COMPILE_ONLY=1 # nowarn_with_warnaserror01b.fs - SOURCE=nowarn_with_warnaserror02.fs SCFLAGS="--warnaserror:FS0040 --warn:4" COMPILE_ONLY=1 # nowarn_with_warnaserror02b.fs diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs index a829eea182e..475d86a7456 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/nowarn_with_warnaserror03.fs @@ -1,8 +1,8 @@ // #Regression #NoMT #CompilerOptions // Regression test for FSHARP1.0:4867 // nowarn has no effect if "Warning level = 4" and "Warnings as errors" -//FS0040 -//FS0021 +//FS0040 +//FS0021 #nowarn "21" #nowarn "40" diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warnaserror/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/warnaserror/env.lst index fa1ebe0260c..815335d76d3 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/warnaserror/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warnaserror/env.lst @@ -1,21 +1,19 @@ - SOURCE=t1.fs SCFLAGS="--warnaserror+ --warnaserror-:FS25,FS26,FS988 # t1a.fs enabled, ex with all warnings, list with >1 element - - SOURCE=t1.fs SCFLAGS="--warnaserror+ --warnaserror-:25,26,988 # t1.fs enabled, excl list with all warnings, list with >1 element - SOURCE=t2.fs SCFLAGS="--warnaserror+ --warnaserror-:25,26 # t2.fs enabled, excl list with some warning, list with >1 element - SOURCE=t3.fs SCFLAGS="--warnaserror+ --warnaserror-:25 # t3.fs enabled, excl list with one warning, list with 1 element - - SOURCE=t4.fs SCFLAGS="--warnaserror+ --warnaserror+:25,26,988 # t4.fs enabled, incl list with all warnings, list with >1 element - SOURCE=t5.fs SCFLAGS="--warnaserror+ --warnaserror+:25,26 # t5.fs enabled, incl list with some warning, list with >1 element - SOURCE=t6.fs SCFLAGS="--warnaserror+ --warnaserror+:25 # t6.fs enabled, incl list with one warning, list with 1 element - - SOURCE=t7.fs SCFLAGS="--warnaserror- --warnaserror-:25,26,988 # t7.fs disabled, excl list with all warnings, list with >1 element - SOURCE=t8.fs SCFLAGS="--warnaserror- --warnaserror-:25,26 # t8.fs disabled, excl list with some warning, list with >1 element - SOURCE=t9.fs SCFLAGS="--warnaserror- --warnaserror-:25 # t9.fs disabled, excl list with one warning, list with 1 element - - SOURCE=t10.fs SCFLAGS="--warnaserror- --warnaserror+:25,26,988 # t10.fs disabled, incl list with all warnings, list with >1 element - SOURCE=t11.fs SCFLAGS="--warnaserror- --warnaserror+:25,26 # t11.fs disabled, incl list with some warning, list with >1 element - SOURCE=t12.fs SCFLAGS="--warnaserror- --warnaserror+:25 # t12.fs disabled, incl list with one warning, list with 1 element + SOURCE=t1.fs SCFLAGS="--warnaserror+ --warnaserror-:FS25,FS26,FS988" # t1a.fs enabled, ex with all warnings, list with >1 element + SOURCE=t1.fs SCFLAGS="--warnaserror+ --warnaserror-:25,26,988" # t1.fs enabled, excl list with all warnings, list with >1 element + SOURCE=t2.fs SCFLAGS="--warnaserror+ --warnaserror-:25,26" # t2.fs enabled, excl list with some warning, list with >1 element + SOURCE=t3.fs SCFLAGS="--warnaserror+ --warnaserror-:25" # t3.fs enabled, excl list with one warning, list with 1 element + SOURCE=t4.fs SCFLAGS="--warnaserror+ --warnaserror+:25,26,988" # t4.fs enabled, incl list with all warnings, list with >1 element + SOURCE=t5.fs SCFLAGS="--warnaserror+ --warnaserror+:25,26" # t5.fs enabled, incl list with some warning, list with >1 element + SOURCE=t6.fs SCFLAGS="--warnaserror+ --warnaserror+:25" # t6.fs enabled, incl list with one warning, list with 1 element + SOURCE=t7.fs SCFLAGS="--warnaserror- --warnaserror-:25,26,988" # t7.fs disabled, excl list with all warnings, list with >1 element + SOURCE=t8.fs SCFLAGS="--warnaserror- --warnaserror-:25,26" # t8.fs disabled, excl list with some warning, list with >1 element + SOURCE=t9.fs SCFLAGS="--warnaserror- --warnaserror-:25" # t9.fs disabled, excl list with one warning, list with 1 element + SOURCE=t10.fs SCFLAGS="--warnaserror- --warnaserror+:25,26,988" # t10.fs disabled, incl list with all warnings, list with >1 element + SOURCE=t11.fs SCFLAGS="--warnaserror- --warnaserror+:25,26" # t11.fs disabled, incl list with some warning, list with >1 element + SOURCE=t12.fs SCFLAGS="--warnaserror- --warnaserror+:25" # t12.fs disabled, incl list with one warning, list with 1 element + + SOURCE=t12.fs SCFLAGS="--warnaserror- --warnaserror+:25,nu0001,fs0001" # t12a.fs disabled, incl list with one warning, list with 1 element diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warnon/env.lst b/tests/fsharpqa/Source/CompilerOptions/fsc/warnon/env.lst index b570c0a1a62..849ff47d61b 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/warnon/env.lst +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warnon/env.lst @@ -1,5 +1,3 @@ - SOURCE=warnon01.fs SCFLAGS="--warnon:1182 --test:ErrorRanges" COMPILE_ONLY=1 # warnon01.fs SOURCE=warnon01.fsx SCFLAGS="--warnon:1182" COMPILE_ONLY=1 FSIMODE=PIPE # warnon01.fsx - SOURCE=warnon01.fs SCFLAGS="--warnon:NU0001;FS1182;NU0001 --test:ErrorRanges" COMPILE_ONLY=1 # warnon01a.fs SOURCE=warnon01.fsx SCFLAGS="--warnon:FS1182" COMPILE_ONLY=1 FSIMODE=PIPE # warnon01a.fsx diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl index cf97598d925..b4c1b490400 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl @@ -64,6 +64,8 @@ Usage: fsharpi [script.fsx []] - MISCELLANEOUS - --nologo Suppress compiler copyright message +--version Display compiler version banner and + exit --help Display this usage message (Short form: -?) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl index 230f23f0f92..d95678648c7 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl @@ -1,5 +1,5 @@ -Usage: fsi.exe [script.fsx []] +Usage: fsiAnyCpu [script.fsx []] - INPUT FILES - @@ -64,6 +64,8 @@ Usage: fsi.exe [script.fsx []] - MISCELLANEOUS - --nologo Suppress compiler copyright message +--version Display compiler version banner and + exit --help Display this usage message (Short form: -?) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl index 9e8af92856a..cbedecea482 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl @@ -1,7 +1,7 @@ Microsoft (R) F# Interactive version 10.2.3 for F# 4.5 Copyright (c) Microsoft Corporation. All Rights Reserved. -Usage: fsi.exe [script.fsx []] +Usage: fsiAnyCpu [script.fsx []] - INPUT FILES - @@ -66,6 +66,8 @@ Usage: fsi.exe [script.fsx []] - MISCELLANEOUS - --nologo Suppress compiler copyright message +--version Display compiler version banner and + exit --help Display this usage message (Short form: -?) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl index 83fd0bfa996..b7f6805220b 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/langversion/langversionhelp.437.1033.bsl @@ -4,4 +4,5 @@ default latest latestmajor 4.6 -4.7 (Default) \ No newline at end of file +4.7 +5.0 (Default) \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs deleted file mode 100644 index f78853a422b..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals01.fs +++ /dev/null @@ -1,26 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -#light - -// Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents - -let oneOfOneMiDec = 1.0E-6M -let oneMiDec = 1.0E+6M - -let one = oneOfOneMiDec * oneMiDec - -if one <> 1.0M then exit 1 - -let result = 1.0E0M + 2.0E1M + 3.0E2M + 4.0E3M + 5.0E4M + 6.0E5M + 7.0E6M + 8.0E7M + 9.0E8M + - 1.0E-1M + 2.0E-2M + 3.0E-3M + 4.0E-4M + 5.0E-5M + 6.0E-6M + 7.0E-7M + 8.0E-8M + 9.0E-9M - -if result <> 987654321.123456789M then exit 1 - -// Test boundary case -let xMax = 1.0E28M -let XMin = 1.0E-28M - -// Test with leading zeros in exponential and -let y = 1.0E00M + 2.0E01M + 3.E02M + 1.E-01M + 2.0E-02M -if y <> 321.12M then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs deleted file mode 100644 index ff61e0a1b47..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/DecimalLiterals02.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono -// This is a positive test on Dev10, at least until -// FSHARP1.0:4523 gets resolved. -// - -let ok = 1.0E-50M // parses ok on Dev10 - -if ok <> 0.0M then - exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx deleted file mode 100644 index acc2c91301a..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum01.fsx +++ /dev/null @@ -1,7 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -// Verify the ability to specify basic constants - continued - - -//This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope - -let bignumConst = 1N diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx deleted file mode 100644 index 8060826cfbd..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_BasicConstantsBigNum40.fsx +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono #ReqNOMT - -// Verify the ability to specify basic constants - continued - - -// error FS0191: This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope -//This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope - -let bignumConst = 1N - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs deleted file mode 100644 index 18849f241c0..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_DecimalLiterals02.fs +++ /dev/null @@ -1,9 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants #NoMono -#light - -// Negative Regressiont test for FSharp1.0: 2543 - Decimal literals do not support exponents -//This number is outside the allowable range for decimal literals - -let invalidDec = 1.0E-50M - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs deleted file mode 100644 index 7f7e1745b8c..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/E_UnderscoreLiterals.fs +++ /dev/null @@ -1,30 +0,0 @@ -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include -//This is not a valid numeric literal. Valid numeric literals include - -let pi1 = 3_.1415F -let pi2 = 3._1415F -let socialSecurityNumber1 = 999_99_9999_L -let x1 = _52 -let x2 = 52_ -let x3 = 0_x52 -let x4 = 0x_52 -let x5 = 0x52_ -let x6 = 052_ -let x7 = 0_o52 -let x8 = 0o_52 -let x9 = 0o52_ -let x10 = 2.1_e2F -let x11 = 2.1e_2F -let x12 = 1.0_F \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs deleted file mode 100644 index e3015854a5e..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/FullSetOfEscapeCharacters.fs +++ /dev/null @@ -1,21 +0,0 @@ -// #Regression #Conformance #BasicGrammarElements #Constants -#light - -// Regression test for FSharp1.0: 2956 - F# should have parity with C# wrt escape characters - -let isEscape = - true - && ('\a' = char 7 ) // alert - && ('\b' = char 8 ) // backspace - && ('\t' = char 9 ) // horizontal tab - && ('\n' = char 10) // new line - && ('\v' = char 11) // vertical tab - && ('\f' = char 12) // form feed - && ('\r' = char 13) // return - && ('\"' = char 34) // double quote - && ('\'' = char 39) // single quote - && ('\\' = char 92) // backslash - -if not isEscape then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs deleted file mode 100644 index 1291c1377b5..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers01.fs +++ /dev/null @@ -1,14 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let x = -1 - -if x + x <> -2 then exit 1 -if x - x <> 0 then exit 1 -if x * x <> 1 then exit 1 -if x / x <> 1 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs deleted file mode 100644 index c9b43056971..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers02.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let fiveMinusSix = 5 - 6 -let fiveMinusSeven = 5-7 -let negativeSeven = -7 - -if fiveMinusSix <> -1 then exit 1 -if fiveMinusSeven <> -2 then exit 1 -if negativeSeven <> -1 * 7 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs deleted file mode 100644 index 751d026a469..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/NegativeNumbers03.fs +++ /dev/null @@ -1,13 +0,0 @@ -// #Conformance #BasicGrammarElements #Constants -#light - -// Verify the ability to specify negative numbers -// (And not get confused wrt subtraction.) - -let ident x = x -let add x y = x + y - -if ident -10 <> -10 then exit 1 -if add -5 -5 <> -10 then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst deleted file mode 100644 index 97183b49781..00000000000 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/Constants/env.lst +++ /dev/null @@ -1,15 +0,0 @@ -NOMONO,NoMT SOURCE=E_BasicConstantsBigNum40.fsx SCFLAGS="--test:ErrorRanges" # E_BasicConstantsBigNum40.fsx - - - SOURCE=NegativeNumbers01.fs # NegativeNumbers01.fs - SOURCE=NegativeNumbers02.fs # NegativeNumbers02.fs - SOURCE=NegativeNumbers03.fs # NegativeNumbers03.fs - - SOURCE=DecimalLiterals01.fs # DecimalLiterals01.fs - -# DecimalLiteral02.fs involves rounding of decimals. The F# design is to follow the BCL. -# This means that the behavior is not deterministic, e.g. Mono and NetFx4 round; NetFx2 gives an error - SOURCE=DecimalLiterals02.fs # DecimalLiterals02.fs - - SOURCE=FullSetOfEscapeCharacters.fs # FullSetOfEscapeCharacters.fs - SOURCE=E_UnderscoreLiterals.fs SCFLAGS="--test:ErrorRanges" # E_UnderscoreLiterals.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/Atat.fsx b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/Atat.fsx index 30256aecd5a..54ff6d02a51 100644 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/Atat.fsx +++ b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/Atat.fsx @@ -1,6 +1,6 @@ // Regression test for DevDiv:20718 // The following code was triggering a Watson error -// Watson Clr20r3 across buckets with: Application fsc.exe from Dev10 RTM; Exception system.exception; UNKNOWN!FSharp.Compiler.Tastops.dest_fun_typ +// Watson Clr20r3 across buckets with: Application fsc.exe from Dev10 RTM; Exception system.exception; UNKNOWN!FSharp.Compiler.TypedTreeOps.dest_fun_typ let main() = let (@@) = id diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/env.lst b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/env.lst index 73d31516ef3..cf0e963f982 100644 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/OperatorNames/env.lst @@ -6,4 +6,4 @@ NoMT SOURCE=Atat.fsx FSIMODE=FEED COMPILE_ONLY=1 # Atat - fsi SOURCE=EqualOperatorsOverloading.fs # EqualOperatorsOverloading.fs SOURCE=E_BasicOperatorNames01.fs SCFLAGS="--test:ErrorRanges" # E_BasicOperatorNames01.fs - SOURCE=RefAssignment01.fs # RefAssignment01.fs \ No newline at end of file + SOURCE=RefAssignment01.fs # RefAssignment01.fs diff --git a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/PrecedenceAndOperators/env.lst b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/PrecedenceAndOperators/env.lst index 3fedc495431..95dd52c6a7e 100644 --- a/tests/fsharpqa/Source/Conformance/BasicGrammarElements/PrecedenceAndOperators/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicGrammarElements/PrecedenceAndOperators/env.lst @@ -13,4 +13,4 @@ SOURCE=VerticalbarOptionalinDU.fs # VerticalbarOptionalinDU.fs SOURCE=DotNotationAfterGenericMethod01.fs # DotNotationAfterGenericMethod01.fs SOURCE=checkedOperatorsOverflow.fs # checkedOperatorsOverflow.fs - SOURCE=checkedOperatorsNoOverflow.fs # checkedOperatorsNoOverflow.fs \ No newline at end of file + SOURCE=checkedOperatorsNoOverflow.fs # checkedOperatorsNoOverflow.fs diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/ExceptionDefinitions/env.lst b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/ExceptionDefinitions/env.lst index 6c137516743..f21b8b78cf4 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/ExceptionDefinitions/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/ExceptionDefinitions/env.lst @@ -39,4 +39,4 @@ SOURCE=E_ExnConstructorBadFieldName.fs SCFLAGS="--test:ErrorRanges" # E_ExnConstructorBadFieldName.fs SOURCE=E_ExnFieldConflictingName.fs SCFLAGS="--test:ErrorRanges" # E_ExnFieldConflictingName.fs SOURCE=E_FieldNameUsedMulti.fs SCFLAGS="--test:ErrorRanges" # E_FieldNameUsedMulti.fs - SOURCE=E_FieldMemberClash.fs SCFLAGS="--test:ErrorRanges" # E_FieldMemberClash.fs \ No newline at end of file + SOURCE=E_FieldMemberClash.fs SCFLAGS="--test:ErrorRanges" # E_FieldMemberClash.fs diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01a.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01a.fs index f4099f83728..f0faca0ad5d 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01a.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01a.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes #Diagnostics // Regression test for FSHARP1.0:5406 // Scenario #2: I'm writing my own custom IComparable implementation - don't bother giving me one -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ [] [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01b.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01b.fs index 93b928b3daa..9ba57bfab71 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01b.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/E_AdjustUses01b.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes #Diagnostics // Regression test for FSHARP1.0:5406 // Scenario #1: I'm not writing my own custom IComparable implementation, assume the reference equality -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ [] [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test01.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test01.fs index 1fea4b200e3..d12d3d698de 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test01.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test01.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M01 = [] [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test02.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test02.fs index a8a78e3effe..5d8333b5d08 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test02.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test02.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M02 = diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test03.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test03.fs index 02ef7b86a0e..c071eedb65c 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test03.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test03.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M03 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test04.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test04.fs index af9e0cb3309..85202dc8748 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test04.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test04.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M04 = [] [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test05.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test05.fs index d1661a1301b..492b5ee68f0 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test05.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test05.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M05 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test06.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test06.fs index a0786a43e36..403fb94ec01 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test06.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test06.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M06 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test07.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test07.fs index 1182c2fc956..b27c1436f56 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test07.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test07.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M07 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test08.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test08.fs index 71f99fac753..f39da31e12c 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test08.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test08.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M08 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test09.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test09.fs index 871605c9c7d..2602e7e2786 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test09.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test09.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ module M09 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test10.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test10.fs index 745dfee5fed..c16191409eb 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test10.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test10.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M10 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test11.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test11.fs index 6938b15b8fd..df83ca304ee 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test11.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test11.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M11 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test12.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test12.fs index 40c055ab904..83f9928cf71 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test12.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test12.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M12 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test13.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test13.fs index 83cb6602d79..71d0643581c 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test13.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test13.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M13 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test14.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test14.fs index 712a36ce9bd..32c58d9e597 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test14.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test14.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M14 = diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test15.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test15.fs index e4653388628..84cd5fd9a15 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test15.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test15.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M15 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test16.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test16.fs index 13017437bf9..6a251bfc8a8 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test16.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test16.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M16 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test17.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test17.fs index 40c619cc110..31fce549b22 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test17.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test17.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M17 = [] (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test18.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test18.fs index 6baa497d41f..f2feefd8eb3 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test18.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test18.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> ReferenceEqualityAttribute'\.$ +//The object constructor 'ReferenceEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> ReferenceEqualityAttribute'\.$ module M18 = [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test19.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test19.fs index e456ae03d45..678e24b9409 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test19.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test19.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M19 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test20.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test20.fs index ca4624c96f1..3fc566826a2 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test20.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test20.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M20 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test21.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test21.fs index 62190a2edec..264fbf884ef 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test21.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test21.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M21 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test22.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test22.fs index 5c646bf10b7..cafe723d9b1 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test22.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test22.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M22 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test23.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test23.fs index 36ac19e1e99..01c0e359acf 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test23.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test23.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M23 = diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test24.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test24.fs index 3ac68f9b637..d95e67e960f 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test24.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test24.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralComparisonAttribute'\.$ +//The object constructor 'StructuralComparisonAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralComparisonAttribute'\.$ module M24 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test25.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test25.fs index a4a8db15d12..a3ccd10c520 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test25.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test25.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M25 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test26.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test26.fs index 3d9ef4ac930..08725d8ccbd 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test26.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test26.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ module M26 = (* [] *) diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test28.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test28.fs index d9cbc3500ba..8d1990fbe1e 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test28.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Test28.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypesAndModules #GeneratedEqualityAndHashing #Attributes // Regression test for FSHARP1.0:4571 -//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new : unit -> StructuralEqualityAttribute'\.$ +//The object constructor 'StructuralEqualityAttribute' takes 0 argument\(s\) but is here given 1\. The required signature is 'new: unit -> StructuralEqualityAttribute'\.$ [] //[] [] diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Basic/env.lst b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Basic/env.lst index 9d26bef77ad..f61cc16a1ca 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Basic/env.lst @@ -23,4 +23,4 @@ SOURCE=E_CustomEqualityEquals01.fs SCFLAGS="--test:ErrorRanges" # E_CustomEqualityEquals01.fs SOURCE=E_CustomEqualityGetHashCode01.fs SCFLAGS="--test:ErrorRanges" # E_CustomEqualityGetHashCode01.fs - SOURCE=CustomEquality01.fs # CustomEquality01.fs \ No newline at end of file + SOURCE=CustomEquality01.fs # CustomEquality01.fs diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/env.lst b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/env.lst index 30f2f6611c3..7fe3d1ffa2e 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/RecordTypes/env.lst @@ -5,9 +5,6 @@ SOURCE=NoClashMemberIFaceMember.fs SCFLAGS="--warnaserror+" # NoClashMemberIFaceMember.fs - SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_Equals.fs - SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_GetHashCode.fs - SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_ToString.fs NoMT SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_Equals.fs - fsi NoMT SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_GetHashCode.fs - fsi @@ -36,7 +33,6 @@ NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMOD SOURCE=Scoping03.fsx # Scoping03.fsx SOURCE=Scoping04.fsx # Scoping04.fsx SOURCE=E_UnitType01.fsx SCFLAGS="-a --test:ErrorRanges" # E_UnitType01.fsx - SOURCE=UnitType01.fsx COMPILE_ONLY=1 SCFLAGS=-a # UnitType01.fsx SOURCE=W_Overrides01.fsx SCFLAGS="--test:ErrorRanges" # W_Overrides01.fsx SOURCE=ImplicitEquals001.fs # ImplicitEquals001.fs @@ -67,4 +63,4 @@ NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMOD SOURCE=E_InheritRecord01.fs SCFLAGS="--test:ErrorRanges" # E_InheritRecord01.fs # Fails due to stack overflow. #ReqNOCov SOURCE=BigRecord01.fs # BigRecord01.fs - SOURCE=DuckTypingRecords01.fs # DuckTypingRecords01.fs \ No newline at end of file + SOURCE=DuckTypingRecords01.fs # DuckTypingRecords01.fs diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/E_GenericFunctionValuedStaticProp01.fs b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/E_GenericFunctionValuedStaticProp01.fs index 5543c4f888d..41f12af15af 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/E_GenericFunctionValuedStaticProp01.fs +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/E_GenericFunctionValuedStaticProp01.fs @@ -1,6 +1,6 @@ // Regression test for DEV11:5949 - "generic function-valued static property raises "error FS0073: internal error: Undefined or unsolved type variable: 'a"" //The instantiation of the generic type 'list1' is missing and can't be inferred from the arguments or return type of this member\. Consider providing a type instantiation when accessing this type, e\.g\. 'list1<_>'\.$ -//The function or member 'toList' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private list1\.toList : \('a list1 -> 'a list\)'\.$ +//The function or member 'toList' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private list1\.toList: \('a list1 -> 'a list\)'\.$ open System open System.Collections diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/W_UnionCaseProduction01.fsx b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/W_UnionCaseProduction01.fsx index 2efcd15a035..9b9226b076e 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/W_UnionCaseProduction01.fsx +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/W_UnionCaseProduction01.fsx @@ -4,7 +4,8 @@ // | id -- nullary union case // | id of type * ... * type -- n-ary union case // | id : sig-spec -- n-ary union case -//This construct is deprecated: it is only for use in the F# library +//This construct is deprecated: it is only for use in the F# library +//This construct is deprecated: it is only for use in the F# library #light type T = | D : int -> T diff --git a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/env.lst b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/env.lst index c979c25d016..55b56d6e047 100644 --- a/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/BasicTypeAndModuleDefinitions/UnionTypes/env.lst @@ -6,13 +6,9 @@ SOURCE=EqualAndBoxing01.fs # EqualAndBoxing01.fs - SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_Equals.fs - SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_GetHashCode.fs - SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_ToString.fs NoMT SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_Equals.fs - fsi NoMT SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_GetHashCode.fs - fsi -NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_ToString.fs - fsi SOURCE=E_LowercaseDT.fs # E_LowercaseDT.fs SOURCE=ImplicitEquals001.fs # ImplicitEquals001.fs @@ -99,4 +95,4 @@ NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMOD SOURCE=E_UnionFieldConflictingName.fs SCFLAGS="--test:ErrorRanges" # E_UnionFieldConflictingName.fs SOURCE=E_UnionConstructorBadFieldName.fs SCFLAGS="--test:ErrorRanges" # E_UnionConstructorBadFieldName.fs SOURCE=E_FieldNameUsedMulti.fs SCFLAGS="--test:ErrorRanges" # E_FieldNameUsedMulti.fs - SOURCE=E_FieldMemberClash.fs SCFLAGS="--test:ErrorRanges" # E_FieldMemberClash.fs \ No newline at end of file + SOURCE=E_FieldMemberClash.fs SCFLAGS="--test:ErrorRanges" # E_FieldMemberClash.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface01.fs index 40cec2bcb60..05329b5bf9b 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DeclarationElements #Accessibility // -//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type +//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type // type public IDoStuffAsWell = diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface02.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface02.fs index ab527b1127c..6555f0a48c7 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface02.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface02.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DeclarationElements #Accessibility // -//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type +//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type // #light diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface03.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface03.fs index 16ce8bc909f..ba68769ef64 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface03.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/AccessibilityAnnotations/PermittedLocations/E_accessibilityOnInterface03.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DeclarationElements #Accessibility // -//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type +//Accessibility modifiers are not allowed on this member\. Abstract slots always have the same visibility as the enclosing type // #light diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/ArgumentsOfAllTypes/Generator/Generator.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/ArgumentsOfAllTypes/Generator/Generator.fs index 2a4dfb3b27e..fe688dcec26 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/ArgumentsOfAllTypes/Generator/Generator.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/ArgumentsOfAllTypes/Generator/Generator.fs @@ -5,7 +5,7 @@ // type T1() = class end // let t1 = (typeof.GetCustomAttributes(false) |> Array.map (fun x -> x :?> System.Attribute)).[0] // t1 -// // val it : System.Attribute = +// // val it: System.Attribute = // // CSAttributes.A1Attribute {PositionalString = "X"; // // TypeId = CSAttributes.A1Attribute; // // pa_int = 1;} @@ -15,7 +15,7 @@ // type T1() = class end // let t1 = (typeof.GetCustomAttributes(false) |> Array.map (fun x -> x :?> System.Attribute)).[0] // t1 -// // val it : System.Attribute = +// // val it: System.Attribute = // // CSAttributes.A1Attribute {PositionalString = "A"; // // TypeId = CSAttributes.A1Attribute; // // pa_int = 2;} diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/env.lst index 18d4f2837b0..24fb0680fc6 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/env.lst @@ -21,4 +21,4 @@ SOURCE=W_AssemblyVersion01.fs SCFLAGS="--test:ErrorRanges" # W_AssemblyVersion01.fs SOURCE=W_AssemblyVersion02.fs SCFLAGS="--test:ErrorRanges" # W_AssemblyVersion02.fs SOURCE=X_AssemblyVersion01.fs SCFLAGS="--test:ErrorRanges" # X_AssemblyVersion01.fs - SOURCE=X_AssemblyVersion02.fs SCFLAGS="--test:ErrorRanges" # X_AssemblyVersion02.fs \ No newline at end of file + SOURCE=X_AssemblyVersion02.fs SCFLAGS="--test:ErrorRanges" # X_AssemblyVersion02.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/Basic/E_StructLayout.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/Basic/E_StructLayout.fs index 7a31a7e5a4d..3a3c7a5419a 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/Basic/E_StructLayout.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/Basic/E_StructLayout.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #DeclarationElements #Attributes // Tests to ensure that you can't use StructLayout inappropriately // Regression tests for FSHARP1.0:5931 -//The type 'SExplicitBroken' has been marked as having an Explicit layout, but the field 'v2' has not been marked with the 'FieldOffset' attribute$ -//The FieldOffset attribute can only be placed on members of types marked with the StructLayout\(LayoutKind\.Explicit\)$ +//The type 'SExplicitBroken' has been marked as having an Explicit layout, but the field 'v2' has not been marked with the 'FieldOffset' attribute$ +//The FieldOffset attribute can only be placed on members of types marked with the StructLayout\(LayoutKind\.Explicit\)$ module M diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/Events/basic/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/Events/basic/env.lst index 674a6116f6d..1df23a91d54 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/Events/basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/Events/basic/env.lst @@ -15,4 +15,4 @@ NoMT SOURCE=Regression03.fsx COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo" # Re SOURCE=EventWithGenericTypeAsUnit01.fs # EventWithGenericTypeAsUnit01.fs - SOURCE=CLIEvent01.fs # CLIEvent01.fs \ No newline at end of file + SOURCE=CLIEvent01.fs # CLIEvent01.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/FieldMembers/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/FieldMembers/env.lst index ee798e5f777..f41e8c2b232 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/FieldMembers/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/FieldMembers/env.lst @@ -5,4 +5,4 @@ SOURCE=E_StaticField01.fs # E_StaticField01.fs SOURCE=E_StaticField02a.fs # E_StaticField02a.fs - SOURCE=DefaultValue01.fs # DefaultValue01.fs \ No newline at end of file + SOURCE=DefaultValue01.fs # DefaultValue01.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/ImportDeclarations/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/ImportDeclarations/env.lst index e368127c7a2..88eb884dc3f 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/ImportDeclarations/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/ImportDeclarations/env.lst @@ -10,4 +10,4 @@ SOURCE=E_openModInFun.fs SCFLAGS="--test:ErrorRanges" # E_openModInFun.fs SOURCE=E_OpenUnknownNS.fs # E_OpenUnknownNS.fs - SOURCE=W_OpenUnqualifiedNamespace01.fs # W_OpenUnqualifiedNamespace01.fs \ No newline at end of file + SOURCE=W_OpenUnqualifiedNamespace01.fs # W_OpenUnqualifiedNamespace01.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_AttributesOnLet01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_AttributesOnLet01.fs index 23ce8e6a083..88b6421e126 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_AttributesOnLet01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_AttributesOnLet01.fs @@ -4,7 +4,10 @@ // Regression test for FSharp1.0:3744 - Unable to apply attributes on individual patterns in a tupled pattern match let binding - Implementation doesn't match spec // Test against error emitted when attributes applied within pattern -//Attributes are not allowed within patterns +//Attributes are not allowed within patterns +//This attribute is not valid for use on this language element +//Attributes are not allowed within patterns +//This attribute is not valid for use on this language element open System diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_ErrorsforIncompleteTryCatch.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_ErrorsforIncompleteTryWith.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_ErrorsforIncompleteTryCatch.fs rename to tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_ErrorsforIncompleteTryWith.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_Literals02.fsi b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_Literals02.fsi index e4ad6249a54..7e04ac9de15 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_Literals02.fsi +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/E_Literals02.fsi @@ -1,6 +1,6 @@ // #Regression #Conformance #DeclarationElements #LetBindings -//A declaration may only be the \[\] attribute if a constant value is also given, e\.g\. 'val x : int = 1'$ -//A declaration may only be the \[\] attribute if a constant value is also given, e\.g\. 'val x : int = 1'$ +//A declaration may only be the \[\] attribute if a constant value is also given, e\.g\. 'val x: int = 1'$ +//A declaration may only be the \[\] attribute if a constant value is also given, e\.g\. 'val x: int = 1'$ // FSB 1981, Signature must contain the literal value diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst index 7685eb450c1..6304d0ac601 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/Basic/env.lst @@ -25,7 +25,7 @@ SOURCE=E_GenericTypeAnnotations01.fs SCFLAGS="--test:ErrorRanges" # E_GenericTypeAnnotations01.fs SOURCE=E_AttributesOnLet01.fs SCFLAGS="--test:ErrorRanges" # E_AttributesOnLet01.fs - SOURCE=E_ErrorsforIncompleteTryCatch.fs SCFLAGS="--test:ErrorRanges" # E_ErrorsforIncompleteTryCatch.fs + SOURCE=E_ErrorsforIncompleteTryWith.fs SCFLAGS="--test:ErrorRanges" # E_ErrorsforIncompleteTryWith.fs SOURCE=E_InvalidInnerRecursiveBinding.fs SCFLAGS="--test:ErrorRanges" #E_InvalidInnerRecursiveBinding.fs SOURCE=E_InvalidInnerRecursiveBinding2.fs SCFLAGS="--test:ErrorRanges" #E_InvalidInnerRecursiveBinding2.fs - SOURCE=RecursiveBindingGroup.fs SCFLAGS="" #RecursiveBindingGroup.fs \ No newline at end of file + SOURCE=RecursiveBindingGroup.fs SCFLAGS="" #RecursiveBindingGroup.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/ExplicitTypeParameters/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/ExplicitTypeParameters/env.lst index 9909abff409..93735d6bb1a 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/ExplicitTypeParameters/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/ExplicitTypeParameters/env.lst @@ -1,3 +1,3 @@ SOURCE=SanityCheck.fs # SanityCheck.fs SOURCE=SanityCheck2.fs # SanityCheck2.fs - SOURCE=W_TypeParamsWhenNotNeeded.fs # W_TypeParamsWhenNotNeeded.fs \ No newline at end of file + SOURCE=W_TypeParamsWhenNotNeeded.fs # W_TypeParamsWhenNotNeeded.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/env.lst index 880bba8aadf..05554c44d99 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/LetBindings/TypeFunctions/env.lst @@ -1,15 +1,8 @@ SOURCE=typeofBasic001.fs # typeofBasic001.fs - SOURCE=typeofInCustomAttributes001.fs COMPILE_ONLY=1 # typeofInCustomAttributes001.fs - SOURCE=E_typeof_measure_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # E_typeof_measure_01.fs - SOURCE=E_typeof_undefined_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # E_typeof_undefined_01.fs - SOURCE=typeof_anonymous_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # typeof_anonymous_01.fs - SOURCE=typeof_class_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # typeof_class_01.fs - SOURCE=typeof_interface_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # typeof_interface_01.fs - SOURCE=typeof_struct_01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # typeof_struct_01.fs SOURCE=E_NoTypeFuncsInTypes.fs # E_NoTypeFuncsInTypes.fs SOURCE=SizeOf01.fs # SizeOf01.fs - SOURCE=typeofAsArgument.fs # typeofAsArgument.fs \ No newline at end of file + SOURCE=typeofAsArgument.fs # typeofAsArgument.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember01.fs index 7bbb5cddd94..04530ed20ef 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_ActivePatternMember01.fs @@ -2,7 +2,7 @@ // Regression for FSHARP1.0:6168 // Active patterns should not be allowed as members - they don't work , but currently can be defined //This is not a valid name for an active pattern -//The field, constructor or member 'Foo' is not defined +//The type 'FaaBor' does not define the field, constructor or member 'Foo' module M @@ -18,7 +18,7 @@ type FaaBor() = | Bar -> () match 1,2 with -| FaaBor.Foo -> printfn "hi" // The field, constructor or member 'Foo' is not defined +| FaaBor.Foo -> printfn "hi" // The type 'FaaBor' does not define a field, constructor or member 'Foo' | _ -> () exit 1 diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch01.fs index 3263f7f4d40..092d929ca34 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch01.fs @@ -1,10 +1,10 @@ // #Regression #Conformance #DeclarationElements #MemberDefinitions #MethodsAndProperties // Regression test for FSHARP1.0:1407 (Poor error message when arguments do not match signature of overloaded operator. Also incorrect span.) -//This expression was expected to have type. ''a \[,\]' .but here has type. 'int \[\]' -//This expression was expected to have type. ''a \[\]' .but here has type. 'int \[,\]' -//This expression was expected to have type. ''a \[\]' .but here has type. 'int \[,,\]' -//This expression was expected to have type. ''a \[\]' .but here has type. 'int \[,,,\]' +//This expression was expected to have type. ''a\[,\]' .but here has type. 'int\[\]' +//This expression was expected to have type. ''a\[\]' .but here has type. 'int\[,\]' +//This expression was expected to have type. ''a\[\]' .but here has type. 'int\[,,\]' +//This expression was expected to have type. ''a\[\]' .but here has type. 'int\[,,,\]' let foo (arr : int[,]) = arr.[1,2] // ok diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch02.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch02.fs index ddbfc1ef785..5dc4df4da21 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch02.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerArityMismatch02.fs @@ -1,10 +1,10 @@ // #Regression #Conformance #DeclarationElements #MemberDefinitions #MethodsAndProperties // Regression test for FSHARP1.0:1407 (Poor error message when arguments do not match signature of overloaded operator. Also incorrect span.) -//This expression was expected to have type. ''a \[,,\]' .but here has type. 'int \[\]' -//This expression was expected to have type. ''a \[\]' .but here has type. 'int \[,\]' -//This expression was expected to have type. ''a \[,,\]' .but here has type. 'int \[,,,\]' -//This expression was expected to have type. ''a \[,\]' .but here has type. 'int \[,,,]' +//This expression was expected to have type. ''a\[,,\]' .but here has type. 'int\[\]' +//This expression was expected to have type. ''a\[\]' .but here has type. 'int\[,\]' +//This expression was expected to have type. ''a\[,,\]' .but here has type. 'int\[,,,\]' +//This expression was expected to have type. ''a\[,\]' .but here has type. 'int\[,,,]' let foo (arr : int[,]) = arr.[1,2] // ok diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerNotSpecified01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerNotSpecified01.fs index 9a258a6d1a4..61615c02ee9 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerNotSpecified01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/E_IndexerNotSpecified01.fs @@ -2,7 +2,7 @@ #light // Verify error if the type doesn't support an indexer -//The field, constructor or member 'Item' is not defined +//The type 'Foo' does not define the field, constructor or member 'Item' type Foo(x : int) = member this.Value = x diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/env.lst index db1705426a3..c26d2595ede 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/env.lst @@ -33,7 +33,7 @@ SOURCE=E_Properties06.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_Properties06.fs SOURCE=AbstractProperties01.fs # AbstractProperties01.fs - SOURCE=E_AbstractProperties02.fs SCFLAGS="--test:ErrorRanges --flaterrors # E_AbstractProperties02.fs + SOURCE=E_AbstractProperties02.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_AbstractProperties02.fs SOURCE=E_AbstractProperties03.fs SCFLAGS="--test:ErrorRanges" # E_AbstractProperties03.fs SOURCE=E_SettersMustHaveUnit01.fs # E_SettersMustHaveUnit01.fs SOURCE=E_SettersMustHaveUnit02.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_SettersMustHaveUnit02.fs @@ -67,4 +67,4 @@ SOURCE=RecursiveLetValues.fs # RecursiveLetValues.fs SOURCE=E_ActivePatternMember01.fs SCFLAGS="--test:ErrorRanges" # E_ActivePatternMember01.fs - SOURCE=E_ActivePatternMember02.fs SCFLAGS="--test:ErrorRanges" # E_ActivePatternMember02.fs \ No newline at end of file + SOURCE=E_ActivePatternMember02.fs SCFLAGS="--test:ErrorRanges" # E_ActivePatternMember02.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/StaticMembers-instance.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/staticMembers-instance.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/StaticMembers-instance.fs rename to tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/staticMembers-instance.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/tupledValueProperties02.fsx b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/tupledValueProperties02.fsx index e791267da8f..56c262747ed 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/tupledValueProperties02.fsx +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/MethodsAndProperties/tupledValueProperties02.fsx @@ -4,12 +4,10 @@ // Note: the non-curried syntax ((x:decimal, y:decimal)) is expected // Run thru fsi // type x = -// class -// new : unit -> x -// member Verify : int -// member X : decimal \* decimal with set -// member Y : decimal \* decimal with set -// end +// new: unit -> x +// member Verify: int +// member X: decimal \* decimal with set +// member Y: decimal \* decimal with set #light type x ()= class diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_NumParamMismatch01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_NumParamMismatch01.fs index 110e06ddc4f..62e9d270297 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_NumParamMismatch01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_NumParamMismatch01.fs @@ -1,8 +1,8 @@ // #Regression #Conformance #DeclarationElements #MemberDefinitions #NamedArguments // FSB 1433, Count of supplied parameters incorrect in error message if named parameters are used. //Accessibility modifiers are not permitted on overrides or interface implementations -//The member or object constructor 'NamedMeth1' requires 1 additional argument\(s\)\. The required signature is 'abstract member IFoo\.NamedMeth1 : arg1:int \* arg2:int \* arg3:int \* arg4:int -> float' -//The member or object constructor 'NamedMeth1' requires 4 argument\(s\) but is here given 2 unnamed and 3 named argument\(s\)\. The required signature is 'abstract member IFoo\.NamedMeth1 : arg1:int \* arg2:int \* arg3:int \* arg4:int -> float' +//The member or object constructor 'NamedMeth1' requires 1 additional argument\(s\)\. The required signature is 'abstract IFoo\.NamedMeth1: arg1: int \* arg2: int \* arg3: int \* arg4: int -> float' +//The member or object constructor 'NamedMeth1' requires 4 argument\(s\) but is here given 2 unnamed and 3 named argument\(s\)\. The required signature is 'abstract IFoo\.NamedMeth1: arg1: int \* arg2: int \* arg3: int \* arg4: int -> float' type IFoo = interface abstract NamedMeth1 : arg1:int * arg2:int * arg3:int * arg4:int-> float diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_ReusedParam.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_ReusedParam.fs index 55b57598deb..6b04da4fc31 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_ReusedParam.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/E_ReusedParam.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #DeclarationElements #MemberDefinitions #NamedArguments -//A named argument has been assigned more than one value +//The named argument 'param1' has been assigned more than one value type Foo = static member DoStuff (param1:int, param2:int) = param1 + param2 diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/env.lst index 02dbe48692d..6c6772314b8 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/NamedArguments/env.lst @@ -14,4 +14,4 @@ SOURCE=PropertySetterAfterConstruction01.fs # PropertySetterAfterConstruction01.fs SOURCE=PropertySetterAfterConstruction02.fs # PropertySetterAfterConstruction02.fs SOURCE=E_MisspeltParam01.fs # E_MisspeltParam01.fs - SOURCE=E_MustBePrefix.fs # E_MustBePrefix.fs \ No newline at end of file + SOURCE=E_MustBePrefix.fs # E_MustBePrefix.fs diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OptionalArguments/E_OptionalNamedArgs.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OptionalArguments/E_OptionalNamedArgs.fs index 7049e3413e1..11cb8d88671 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OptionalArguments/E_OptionalNamedArgs.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OptionalArguments/E_OptionalNamedArgs.fs @@ -1,8 +1,7 @@ // #435263: compiler crash with .net optional parameters and F# optional syntax -//Type constraint mismatch\. The type -// 'a option -//is not compatible with type -// string -//The type ''a option' is not compatible with the type 'string' +//This expression was expected to have type +// 'string option' +//but here has type +// 'string' let _ = (TestLib.T()).NonNullOptArg(?x = "text") \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/E_ReturnGenericUnit01.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/E_ReturnGenericUnit01.fs index 1e0b8557a8d..70f2a159199 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/E_ReturnGenericUnit01.fs +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/E_ReturnGenericUnit01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DeclarationElements #MemberDefinitions #Overloading // Verify error message when returning a 'a which is of type unit -//The member 'M : unit -> unit' does not have the correct type to override the corresponding abstract method +//The member 'M: unit -> unit' does not have the correct type to override the corresponding abstract method [] type 'a ``base`` = diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs deleted file mode 100644 index 5737cdebf2c..00000000000 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/SlowOverloadResolution.fs +++ /dev/null @@ -1,25 +0,0 @@ -// #Conformance #DeclarationElements #MemberDefinitions #Overloading -// https://github.com/Microsoft/visualfsharp/issues/351 - slow overlaod resolution -//This value is not a function and cannot be applied -type Switcher = Switcher - -let inline checker< ^s, ^r when (^s or ^r) : (static member pass : ^r -> unit)> (s : ^s) (r : ^r) = () - -let inline format () : ^r = - checker Switcher Unchecked.defaultof< ^r> - () :> obj :?> ^r - -type Switcher with - static member inline pass(_ : string -> ^r) = - checker Switcher Unchecked.defaultof< ^r> - static member inline pass(_ : int -> ^r) = - checker Switcher Unchecked.defaultof< ^r> - static member inline pass(_ : unit) = () - static member inline pass(_ : int) = () - -[] -let main argv = - let res : unit = format () "text" 5 "more text" () - printfn "%A" res - System.Console.ReadKey() - 0 // return an integer exit code diff --git a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/env.lst b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/env.lst index a7384556634..44481e7ef72 100644 --- a/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/env.lst +++ b/tests/fsharpqa/Source/Conformance/DeclarationElements/MemberDefinitions/OverloadingMembers/env.lst @@ -26,8 +26,6 @@ NOMONO,NoMT SOURCE=ConsumeOverloadGenericMethods.fs SCFLAGS="-r:lib.dll" PRECMD= SOURCE=InferenceForLambdaArgs.fs # InferenceForLambdaArgs.fs - SOURCE=SlowOverloadResolution.fs # SlowOverloadResolution.fs - SOURCE=E_OverloadCurriedFunc.fs # E_OverloadCurriedFunc.fs SOURCE=E_OverloadMismatch.fs # E_OverloadMismatch.fs SOURCE=NoWarningWhenOverloadingInSubClass01.fs SCFLAGS="--warnaserror" # NoWarningWhenOverloadingInSubClass01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/env.lst index 090a5f17297..70c1788b63e 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/BasicApplication/env.lst @@ -1,3 +1,2 @@ SOURCE=PostfixType02.fs SCFLAGS=--test:ErrorRanges COMPILE_ONLY=1 # PostfixType02.fs SOURCE=E_PostfixType01.fs SCFLAGS=--test:ErrorRanges COMPILE_ONLY=1 # E_PostfixType01.fs - SOURCE=E_PostfixType03.fs SCFLAGS=--test:ErrorRanges COMPILE_ONLY=1 # E_PostfixType03.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/ObjectConstruction/E_ObjectConstruction01.fs b/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/ObjectConstruction/E_ObjectConstruction01.fs index 48489bfd986..cf368bdfbb0 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/ObjectConstruction/E_ObjectConstruction01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/ApplicationExpressions/ObjectConstruction/E_ObjectConstruction01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #ApplicationExpressions #ObjectConstructors // Verify error for inaccessible constructor -//The field, constructor or member 'BitArrayEnumeratorSimple' is not defined +//The type 'BitArray' does not define the field, constructor or member 'BitArrayEnumeratorSimple' let y = System.Collections.BitArray.BitArrayEnumeratorSimple () diff --git a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/MutableLocals01.fs b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/MutableLocals01.fs index 1009b7443b6..6f33820c47e 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/MutableLocals01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/MutableLocals01.fs @@ -265,7 +265,7 @@ module AsyncExpr = -module TryCatch = +module TryWith = let foo o s = let mutable x_NO = 1 try diff --git a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/env.lst index e912c777041..d9b2eac2e98 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/env.lst @@ -12,4 +12,4 @@ NoMT SOURCE=in05.fsx FSIMODE=PIPE SCFLAGS="--warnaserror+ --test:ErrorRanges --f SOURCE=AmbigLetBinding.fs # AmbigLetBinding SOURCE=W_TypeInferforGenericType.fs SCFLAGS="--test:ErrorRanges" # W_TypeInferforGenericType.fs - SOURCE=MutableLocals01.fs SCFLAGS="--warnon:3180 --optimize+ --test:ErrorRanges" \ No newline at end of file + SOURCE=MutableLocals01.fs SCFLAGS="--warnon:3180 --optimize+ --test:ErrorRanges" diff --git a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in02.fsx b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in02.fsx index e05b179a9d8..49d6d21c084 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in02.fsx +++ b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in02.fsx @@ -4,7 +4,7 @@ // I'm adding these cases to make sure we do not accidentally change the behavior from version to version // Eventually, we will deprecated them - and the specs will be updated. // -//val it : bool = false$ +//val it: bool = false$ // let a = 3 in a + 1 |> ignore diff --git a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in03.fsx b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in03.fsx index 586a72d51d1..1965ad97351 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in03.fsx +++ b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in03.fsx @@ -4,7 +4,7 @@ // I'm adding these cases to make sure we do not accidentally change the behavior from version to version // Eventually, we will deprecated them - and the specs will be updated. // -//val a : int = 3 +//val a: int = 3 // let a = 3 a + 1 |> ignore diff --git a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in04.fsx b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in04.fsx index 85337766783..ef2162aa647 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in04.fsx +++ b/tests/fsharpqa/Source/Conformance/Expressions/BindingExpressions/Binding/in04.fsx @@ -4,7 +4,7 @@ // I'm adding these cases to make sure we do not accidentally change the behavior from version to version // Eventually, we will deprecated them - and the specs will be updated. // -//val it : bool = false +//val it: bool = false // let a = 3 in diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/env.lst index e7fe8c65cfa..460beb62fec 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/PatternMatching/env.lst @@ -1,6 +1,3 @@ SOURCE=LiteralNull01.fs # LiteralNull01.fs SOURCE=W_Function01.fs SCFLAGS="--test:ErrorRanges" # W_Function01.fs - SOURCE=W_PatternMatchingCounterExample01.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_PatternMatchingCounterExample01.fs - SOURCE=W_PatternMatchingCounterExample02.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_PatternMatchingCounterExample02.fs - SOURCE=W_PatternMatchingCounterExample03.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_PatternMatchingCounterExample03.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/env.lst index 9d77ce60403..ab339d13ab1 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SequenceIteration/env.lst @@ -1,4 +1,3 @@ SOURCE=SequenceIteration01.fs # SequenceIteration01 - SOURCE=W_IncompleteMatchFor01.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_IncompleteMatchFor01.fs SOURCE=IEnumerableIteration01.fs # IEnumerableIteration01.fs - SOURCE=E_BadIEnumerable01.fs SCFLAGS="--test:ErrorRanges" # E_BadIEnumerable01.fs \ No newline at end of file + SOURCE=E_BadIEnumerable01.fs SCFLAGS="--test:ErrorRanges" # E_BadIEnumerable01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SimpleFor/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SimpleFor/env.lst index 878e69b929d..85882926972 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SimpleFor/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/SimpleFor/env.lst @@ -1,3 +1,3 @@ SOURCE=Downto01.fs # Downto01.fs SOURCE=E_ForRequiresInt01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_ForRequiresInt01.fs - SOURCE=ForWithUppercaseIdentifier01.fs # ForWithUppercaseIdentifier01.fs \ No newline at end of file + SOURCE=ForWithUppercaseIdentifier01.fs # ForWithUppercaseIdentifier01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch01.fs b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch01.fs deleted file mode 100644 index 2769f89a449..00000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch01.fs +++ /dev/null @@ -1,17 +0,0 @@ -// #Conformance #ControlFlow #Exceptions -#light - -// Verify simple try catch blogs work - -let testPassed = - try - failwith "epicfail" - false - with - | Failure "non-epicfail" -> false - | Failure "epicfail" -> true - | _ -> false - -if not testPassed then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/env.lst deleted file mode 100644 index 59763263ce8..00000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/env.lst +++ /dev/null @@ -1,5 +0,0 @@ - SOURCE=TryCatch01.fs # TryCatch01.fs - SOURCE=TryCatch02.fs # TryCatch02.fs - SOURCE=TryCatch03.fs # TryCatch03.fs - - SOURCE=E_RethrowOutsideCatch01.fs # E_RethrowOutsideCatch01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryFinally/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryFinally/env.lst index d5e598e1dff..58ee8504399 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryFinally/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryFinally/env.lst @@ -1,2 +1,2 @@ SOURCE=W-TryFinallyNotUnit.fs # W-TryFinallyNotUnit - SOURCE=TryFinallyInSequence01.fs # TryFinallyInSequence01.fs \ No newline at end of file + SOURCE=TryFinallyInSequence01.fs # TryFinallyInSequence01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/E_RethrowOutsideCatch01.fs b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/E_RethrowOutsideWith01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/E_RethrowOutsideCatch01.fs rename to tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/E_RethrowOutsideWith01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith01.fs b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith01.fs new file mode 100644 index 00000000000..869e6b65ab0 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith01.fs @@ -0,0 +1,17 @@ +// #Conformance #ControlFlow #Exceptions +#light + +// Verify simple try with blogs work + +let testPassed = + try + failwith "epicfail" + false + with + | Failure "non-epicfail" -> false + | Failure "epicfail" -> true + | _ -> false + +if not testPassed then exit 1 + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch02.fs b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith02.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch02.fs rename to tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch03.fs b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith03.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryCatch/TryCatch03.fs rename to tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/TryWith03.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/env.lst new file mode 100644 index 00000000000..fde9dddd0a3 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/ControlFlowExpressions/TryWith/env.lst @@ -0,0 +1,5 @@ + SOURCE=TryWith01.fs # TryWith01.fs + SOURCE=TryWith02.fs # TryWith02.fs + SOURCE=TryWith03.fs # TryWith03.fs + + SOURCE=E_RethrowOutsideWith01.fs # E_RethrowOutsideWith01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/CompExprMethods02.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/CompExprMethods02.fs index aa06d1bb679..97791246153 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/CompExprMethods02.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/CompExprMethods02.fs @@ -46,11 +46,11 @@ let result = for Char(c) in [| Char('a'); Char('b') |] do () } - -if result <> () then exit 1 +if result <> () then printfn "failed"; exit 1 + +if workflow.CombineCalledWith <> [| "()"; "()" |] then printfn "failed"; exit 1 -if workflow.CombineCalledWith <> [|""; ""|] then exit 1 if workflow.LoopedElements <> [| "1"; @@ -64,6 +64,7 @@ if workflow.LoopedElements <> "Int 1"; "Char 'a'"; "Char 'b'"; "Int 2"; - "Char 'a'"; "Char 'b'" |] then exit 1 - -exit 0 + "Char 'a'"; "Char 'b'" |] then printfn "failed"; exit 1 + +printfn "Succeded" +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/env.lst index f9dfe24dbc4..ad4c32d6e78 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/env.lst @@ -40,4 +40,4 @@ ReqRetail SOURCE=Capacity01.fs # Capacity01.fs SOURCE=E_MissingYield.fs SCFLAGS=--test:ErrorRanges # E_MissingYield.fs SOURCE=E_MissingYieldFrom.fs SCFLAGS=--test:ErrorRanges # E_MissingYieldFrom.fs SOURCE=E_MissingZero.fs SCFLAGS=--test:ErrorRanges # E_MissingZero.fs - SOURCE=E_TypeAlias01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_TypeAlias01.fs \ No newline at end of file + SOURCE=E_TypeAlias01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_TypeAlias01.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs deleted file mode 100644 index 2fd34fa161a..00000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs +++ /dev/null @@ -1,7 +0,0 @@ -// #Regression #Conformance #DataExpressions -// Verify that nameof doesn't work on const string -//Expression does not have a name. - -let x = nameof(1+2) - -exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst index 9d473234e60..c9cae6382fa 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst @@ -1,11 +1,10 @@ - SOURCE=E_NameOfIntConst.fs SCFLAGS="--langversion:preview" # E_NameOfIntConst.fs - SOURCE=E_NameOfStringConst.fs SCFLAGS="--langversion:preview" # E_NameOfStringConst.fs - SOURCE=E_NameOfAppliedFunction.fs SCFLAGS="--langversion:preview" # E_NameOfAppliedFunction.fs - SOURCE=E_NameOfIntegerAppliedFunction.fs SCFLAGS="--langversion:preview" # E_NameOfIntegerAppliedFunction.fs - SOURCE=E_NameOfPartiallyAppliedFunction.fs SCFLAGS="--langversion:preview" # E_NameOfPartiallyAppliedFunction.fs - SOURCE=E_NameOfDictLookup.fs SCFLAGS="--langversion:preview" # E_NameOfDictLookup.fs - SOURCE=E_NameOfAdditionExpr.fs SCFLAGS="--langversion:preview" # E_NameOfAdditionExpr.fs - SOURCE=E_NameOfParameterAppliedFunction.fs SCFLAGS="--langversion:preview" # E_NameOfParameterAppliedFunction.fs - SOURCE=E_NameOfAsAFunction.fs SCFLAGS="--langversion:preview" # E_NameOfAsAFunction.fs - SOURCE=E_NameOfWithPipe.fs SCFLAGS="--langversion:preview" # E_NameOfWithPipe.fs - SOURCE=E_NameOfUnresolvableName.fs SCFLAGS="--langversion:preview" # E_NameOfUnresolvableName.fs + SOURCE=E_NameOfIntConst.fs SCFLAGS="--langversion:5.0" # E_NameOfIntConst.fs + SOURCE=E_NameOfStringConst.fs SCFLAGS="--langversion:5.0" # E_NameOfStringConst.fs + SOURCE=E_NameOfAppliedFunction.fs SCFLAGS="--langversion:5.0" # E_NameOfAppliedFunction.fs + SOURCE=E_NameOfIntegerAppliedFunction.fs SCFLAGS="--langversion:5.0" # E_NameOfIntegerAppliedFunction.fs + SOURCE=E_NameOfPartiallyAppliedFunction.fs SCFLAGS="--langversion:5.0" # E_NameOfPartiallyAppliedFunction.fs + SOURCE=E_NameOfDictLookup.fs SCFLAGS="--langversion:5.0" # E_NameOfDictLookup.fs + SOURCE=E_NameOfParameterAppliedFunction.fs SCFLAGS="--langversion:5.0" # E_NameOfParameterAppliedFunction.fs + SOURCE=E_NameOfAsAFunction.fs SCFLAGS="--langversion:5.0" # E_NameOfAsAFunction.fs + SOURCE=E_NameOfWithPipe.fs SCFLAGS="--langversion:5.0" # E_NameOfWithPipe.fs + SOURCE=E_NameOfUnresolvableName.fs SCFLAGS="--langversion:5.0" # E_NameOfUnresolvableName.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_InvalidSelfReferentialStructConstructor.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_InvalidSelfReferentialStructConstructor.fs index f48786e0b7a..2a74365591c 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_InvalidSelfReferentialStructConstructor.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_InvalidSelfReferentialStructConstructor.fs @@ -2,8 +2,8 @@ // FSB 6350, Compiler crash on invalid code: Crash by invalid type definition //Structs may only bind a 'this' parameter at member declarations$ -//The field, constructor or member 'dt' is not defined //This is not a valid object construction expression\. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor\.$ +//The type 'byref<_,_>' does not define the field, constructor or member 'dt' module mod6350 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_MembersMustBeVirtual01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_MembersMustBeVirtual01.fs index 41badad221f..23564654982 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_MembersMustBeVirtual01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_MembersMustBeVirtual01.fs @@ -2,7 +2,7 @@ // FSB 1683, dispatch slot checking in object expression manages to match non-virtual member //The type Foo contains the member 'MyX' but it is not a virtual or abstract method that is available to override or implement. -//The member 'MyX : unit -> int' does not have the correct type to override any given virtual method$ +//The member 'MyX: unit -> int' does not have the correct type to override any given virtual method$ //At least one override did not correctly implement its corresponding abstract member$ type Foo(x : int) = diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithDuplOverride01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithDuplOverride01.fs index 7af5108124a..10c4974b6a8 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithDuplOverride01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithDuplOverride01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #DataExpressions #ObjectConstructors // Regression test for FSharp1.0:4593 - Internal compiler error on typechecking object expressions with duplicate overrides -//More than one override implements 'Next : StrongToWeakEntry<'a> array -> int when 'a : not struct' +//More than one override implements 'Next: StrongToWeakEntry<'a> array -> int when 'a: not struct' #light diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs new file mode 100644 index 00000000000..6db29506422 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.4.7.fs @@ -0,0 +1,20 @@ +// #Regression #Conformance #DataExpressions #ObjectConstructors +// This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + +type IQueue<'a> = + abstract Addd: 'a -> IQueue<'a> + +type IQueueEx<'a> = + inherit IQueue<'a> + abstract Add: 'a -> IQueueEx<'a> + +let makeQueueEx2() = + {new IQueueEx<'T> with + member q.Add(x) = q + interface IQueue with + member q.Addd(x) = q } + +makeQueueEx2() |> ignore + +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs new file mode 100644 index 00000000000..8a47580aaf8 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.5.0.fs @@ -0,0 +1,20 @@ +// #Regression #Conformance #DataExpressions #ObjectConstructors +// This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. +//You cannot implement the interface 'IQueue<_>' with the two instantiations 'IQueue<'T>' and 'IQueue' because they may unify. + +type IQueue<'a> = + abstract Addd: 'a -> IQueue<'a> + +type IQueueEx<'a> = + inherit IQueue<'a> + abstract Add: 'a -> IQueueEx<'a> + +let makeQueueEx2() = + {new IQueueEx<'T> with + member q.Add(x) = q + interface IQueue with + member q.Addd(x) = q } + +makeQueueEx2() |> ignore + +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs deleted file mode 100644 index 45f0de9b487..00000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/E_ObjExprWithSameInterface01.fs +++ /dev/null @@ -1,20 +0,0 @@ -// #Regression #Conformance #DataExpressions #ObjectConstructors -// This was Dev10:854519 and Dev11:5525. The fix was to make this a compile error to avoid a runtime exception. -//This type implements the same interface at different generic instantiations 'IQueue<'T>' and 'IQueue'\. This is not permitted in this version of F#\.$ - -type IQueue<'a> = - abstract Addd: 'a -> IQueue<'a> - -type IQueueEx<'a> = - inherit IQueue<'a> - abstract Add: 'a -> IQueueEx<'a> - -let makeQueueEx2() = - {new IQueueEx<'T> with - member q.Add(x) = q - interface IQueue with - member q.Addd(x) = q } - -makeQueueEx2() |> ignore - -exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst index 3d53d8a24bf..97d50b142e2 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ObjectExpressions/env.lst @@ -17,5 +17,6 @@ SOURCE=ObjExprWithOverride01.fs # ObjExprWithOverride01.fs SOURCE=E_ObjExprWithOverride01.fs SCFLAGS="-r:Helper.dll --test:ErrorRanges" PRECMD="\$CSC_PIPE /t:library Helper.cs" # E_ObjExprWithOverride01.fs SOURCE=InterfaceObjectExpression01.fs # InterfaceObjectExpression01.fs - SOURCE=E_ObjExprWithSameInterface01.fs SCFLAGS="--test:ErrorRanges" # E_ObjExprWithSameInterface01.fs + SOURCE=E_ObjExprWithSameInterface01.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_ObjExprWithSameInterface01.4.7.fs + SOURCE=E_ObjExprWithSameInterface01.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:5.0" # E_ObjExprWithSameInterface01.5.0.fs SOURCE=MultipleInterfacesInObjExpr.fs # MultipleInterfacesInObjExpr.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier01.fs index 0cef114e774..1a425cc70ac 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier01.fs @@ -1,7 +1,7 @@ // Regression test for DevDiv:305886 // [QueryExpressions] Identifiers for range variables in for-join queries cannot be uppercase! // We expect a simple warning. -//Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name\.$ +//Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name\.$ module M // Warning diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier02.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier02.fs index 2b39d70970f..b7bcb21fffb 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier02.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier02.fs @@ -1,7 +1,7 @@ // Regression test for DevDiv:305886 // [QueryExpressions] Identifiers for range variables in for-join queries cannot be uppercase! // We expect a simple warning. -//Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name\.$ +//Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name\.$ module M // Warning diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier03.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier03.fs index 740d188c8e9..0df77bb848e 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier03.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/W_UppercaseIdentifier03.fs @@ -1,7 +1,7 @@ // Regression test for DevDiv:305886 // [QueryExpressions] Identifiers for range variables in for-join queries cannot be uppercase! // We expect a simple warning. -//Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name\.$ +//Uppercase variable identifiers should not generally be used in patterns, and may indicate a missing open declaration or a misspelt pattern name\.$ module M // Warning diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/RangeExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/RangeExpressions/env.lst index 20fb11fa5b1..7cf554cd2e0 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/RangeExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/RangeExpressions/env.lst @@ -1,4 +1,4 @@ SOURCE=FloatingPointRangeExp01.fs # FloatingPointRangeExp01.fs SOURCE=CustomType01.fs # CustomType01.fs - SOURCE=CustomType02.fs # CustomType02.fs \ No newline at end of file + SOURCE=CustomType02.fs # CustomType02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/SequenceExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/SequenceExpressions/env.lst index c769c0a0950..af6f01d76d3 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/SequenceExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/SequenceExpressions/env.lst @@ -23,4 +23,4 @@ SOURCE=E_ReallyLongList01.fs # E_ReallyLongList01.fs SOURCE=ReallyLongArray01.fs # ReallyLongArray01.fs - SOURCE=YieldInsideFlowControl.fs # YieldInsideFlowControl.fs \ No newline at end of file + SOURCE=YieldInsideFlowControl.fs # YieldInsideFlowControl.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/TupleExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/TupleExpressions/env.lst index fd95e483232..12c00d5862f 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/TupleExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/TupleExpressions/env.lst @@ -1,3 +1,3 @@ SOURCE=EqualityDifferentRuntimeType01.fs # EqualityDifferentRuntimeType01.fs SOURCE=Tuples01.fs # Tuples01.fs - SOURCE=Tuples02.fs # Tuples02.fs \ No newline at end of file + SOURCE=Tuples02.fs # Tuples02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Baselines/E_Cast.fs b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Baselines/E_Cast.fs index e55f2d161e0..fdfeed0171e 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Baselines/E_Cast.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Baselines/E_Cast.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #Quotations // Verify type annotation is required for casting quotes -//Value restriction\. The value 'tq' has been inferred to have generic type. val tq : Expr<'_a> .Either define 'tq' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation\.$ +//Value restriction\. The value 'tq' has been inferred to have generic type. val tq: Expr<'_a> .Either define 'tq' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation\.$ // open Microsoft.FSharp.Quotations diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/E_InvalidQuotationLiteral01.fs b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/E_InvalidQuotationLiteral01.fs index f7a76742279..98d1f8fdcd5 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/E_InvalidQuotationLiteral01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/E_InvalidQuotationLiteral01.fs @@ -1,6 +1,10 @@ // #Regression #Conformance #Quotations // Verify restrictions for what can be written in a quotation -//Unexpected keyword 'type' in quotation literal +//Incomplete structured construct at or before this point in quotation literal +//Unmatched '<@ @>' +//Unexpected keyword 'type' in binding +//Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword. +//Unexpected end of quotation in expression. Expected incomplete structured construct at or before this point or other token. let _ = <@ type Foo(x : int) = member this.Length = x @> diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/QuotationRegressions05.fs b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/QuotationRegressions05.fs index dd32e7d370c..6e8d20f25f1 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/QuotationRegressions05.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/QuotationRegressions05.fs @@ -5,5 +5,5 @@ let quote = <@@ try () with _ -> () @@> -// Problem was that we blew up when quoting trycatch blocks +// Problem was that we blew up when quoting trywith blocks exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/env.lst index b3340008f23..591171d0080 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/ExpressionQuotations/Regressions/env.lst @@ -40,7 +40,7 @@ SOURCE=EnumFromCSQuote01.fs SCFLAGS="-r:SimpleEnum.dll" PRECMD="\$CSC_PIPE /t:library SimpleEnum.cs" # EnumFromCSQuote01.fs SOURCE=QuoteDynamic01.fs # QuoteDynamic01.fs - SOURCE=E_QuoteDynamic01.fs SCFLAGS="--test:ErrorRanges" # E_QuoteDynamic01.fs + SOURCE=E_QuoteDynamic01.fs SCFLAGS="--langversion:4.6 --test:ErrorRanges" # E_QuoteDynamic01.fs SOURCE=ReflectedDefinitionConstructor01.fs # ReflectedDefinitionConstructor01.fs SOURCE=ReflectedDefinitionConstructor02.fs # ReflectedDefinitionConstructor02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef01.fs b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef01.fs index 2e2cd1cbf0f..7a080ac6342 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef01.fs @@ -2,7 +2,7 @@ #light // Verify error if GetSlice is not defined -//The field, constructor or member 'GetSlice' is not defined +//The type 'DU' does not define the field, constructor or member 'GetSlice' type DU = A | B of int | C diff --git a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef02.fs b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef02.fs index 0c728456047..ce67de40860 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef02.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/E_GetSliceNotDef02.fs @@ -2,7 +2,7 @@ #light // Verify error using a 1D slice if only a 2D version added -//The member or object constructor 'GetSlice' takes 4 argument\(s\) but is here given 2\. The required signature is 'member Foo\.GetSlice : lb1:'a option \* ub1:'a option \* lb2:'a option \* ub2:'a option -> unit' +//The member or object constructor 'GetSlice' takes 4 argument\(s\) but is here given 2\. The required signature is 'member Foo\.GetSlice: lb1: 'a option \* ub1: 'a option \* lb2: 'a option \* ub2: 'a option -> unit' type Foo<'a>() = let mutable m_lastLB1 : 'a option = None diff --git a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/env.lst index 306d1afce91..ce140ce1056 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/SyntacticSugar/env.lst @@ -14,4 +14,4 @@ NoMT SOURCE=Slices03.fs # Slices03.fs SOURCE=Slices07.fs # Slices07.fs SOURCE=E_GetSliceNotDef01.fs # E_GetSliceNotDef01.fs - SOURCE=E_GetSliceNotDef02.fs # E_GetSliceNotDef02.fs \ No newline at end of file + SOURCE=E_GetSliceNotDef02.fs # E_GetSliceNotDef02.fs diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst index 53addca20e6..32ad3087012 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst @@ -12,13 +12,9 @@ SOURCE=RigidTypeAnnotation02.fsx # RigidTypeAnnotation02.fsx SOURCE=RigidTypeAnnotation03.fsx # RigidTypeAnnotation03.fsx - SOURCE=rigidtypeannotation01.fs COMPILE_ONLY=1 # rigidtypeannotation01.fs SOURCE=E_RigidTypeAnnotation01.fsx SCFLAGS="--test:ErrorRanges --flaterrors" # E_RigidTypeAnnotation01.fsx SOURCE=E_RigidTypeAnnotation02.fsx SCFLAGS="--test:ErrorRanges --flaterrors" # E_RigidTypeAnnotation02.fsx - SOURCE=E_RigidTypeAnnotation03.fsx SCFLAGS="--test:ErrorRanges --flaterrors" # E_RigidTypeAnnotation03.fsx - SOURCE=E_rigidtypeannotation02.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges --flaterrors" # E_rigidtypeannotation02.fs - SOURCE=E_rigidtypeannotation02b.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges --flaterrors" # E_rigidtypeannotation02b.fs SOURCE=E_RigidTypeAnnotation03.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_RigidTypeAnnotation03.fs SOURCE=staticcoercion01.fs COMPILE_ONLY=1 # staticcoercion01.fs diff --git a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_GenericTypeConstraint02.fsi b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_GenericTypeConstraint02.fsi index 6373c0fd989..90982433631 100644 --- a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_GenericTypeConstraint02.fsi +++ b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_GenericTypeConstraint02.fsi @@ -2,8 +2,8 @@ module Test // Regression test for FSharp1.0:5834 - Generic constraints on explictly specified type parameters work differently in fsi and fs -//A type parameter is missing a constraint 'when 'a : struct' -//The signature and implementation are not compatible because the declaration of the type parameter 'a' requires a constraint of the form 'a : struct +//A type parameter is missing a constraint 'when 'a: struct' +//The signature and implementation are not compatible because the declaration of the type parameter 'a' requires a constraint of the form 'a: struct type G<'a when 'a : struct> val h<'a> : 'a -> G<'a> diff --git a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MatchOnProperCtor.fsi b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MatchOnProperCtor.fsi index ca8d30cdc78..bea7555b1e4 100644 --- a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MatchOnProperCtor.fsi +++ b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MatchOnProperCtor.fsi @@ -1,5 +1,5 @@ // Regression test for bug 6465 -//Module 'MyNamespace' requires a value 'new : \(int \* int\) -> MyType' +//Module 'MyNamespace' requires a value 'new: \(int \* int\) -> MyType' namespace MyNamespace type MyType = diff --git a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MemberNotImplemented01.fsi b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MemberNotImplemented01.fsi index 7f41f8ca056..5c2886da572 100644 --- a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MemberNotImplemented01.fsi +++ b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/CheckingOfImplementationFiles/E_MemberNotImplemented01.fsi @@ -2,7 +2,7 @@ // Regression test for FSharp1.0:5628 // Title: incorrect signature check: implementation file missing implementation of method declared in signature file -//Module 'Test' contains. static member C1\.op_Explicit : x:C1 -> float .but its signature specifies. static member C1\.op_Explicit : x:C1 -> int .The types differ$ +//Module 'Test' contains. static member C1\.op_Explicit: x: C1 -> float .but its signature specifies. static member C1\.op_Explicit: x: C1 -> int .The types differ$ diff --git a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/NamespacesFragmentsAndImplementationFiles/basic/env.lst b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/NamespacesFragmentsAndImplementationFiles/basic/env.lst index b3c80e6dd7c..1b53f4790e6 100644 --- a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/NamespacesFragmentsAndImplementationFiles/basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/NamespacesFragmentsAndImplementationFiles/basic/env.lst @@ -22,4 +22,4 @@ SOURCE="E_LastFileDllCantBeAnona.fs E_LastFileDllCantBeAnonb.fs" SCFLAGS=-a # E_LastFileDllCantBeAnona.fs SOURCE="E_NoNamespaceModuleDec01a.fs E_NoNamespaceModuleDec01b.fs" # E_NoNamespaceModuleDec01a.fs - SOURCE="E_NoNamespaceModuleDec02a.fs E_NoNamespaceModuleDec02b.fs" # E_NoNamespaceModuleDec02a.fs \ No newline at end of file + SOURCE="E_NoNamespaceModuleDec02a.fs E_NoNamespaceModuleDec02b.fs" # E_NoNamespaceModuleDec02a.fs diff --git a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/SignatureFiles/E_MissingSourceFile01.fsi b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/SignatureFiles/E_MissingSourceFile01.fsi index f5f53a17593..efa1bd825eb 100644 --- a/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/SignatureFiles/E_MissingSourceFile01.fsi +++ b/tests/fsharpqa/Source/Conformance/ImplementationFilesAndSignatureFiles/SignatureFiles/E_MissingSourceFile01.fsi @@ -1,7 +1,7 @@ // #Regression #Conformance #SignatureFiles // Test you get an error if you specify an .fsi file but not the corresponding .fs file. -//The signature file 'E_MissingSourceFile01' does not have a corresponding implementation file\. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match +//The signature file 'E_MissingSourceFile01' does not have a corresponding implementation file\. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match namespace FSharp.Testing.MissingSourceFile01 diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/env.lst index 4f2d53076b2..6668f957844 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/env.lst @@ -14,4 +14,4 @@ NoMT SOURCE=ByrefInFSI1.fsx FSIMODE=PIPE COMPILE_ONLY=1 # ByrefInFSI1.fsx SOURCE=E_StaticallyResolvedByRef01.fs SCFLAGS="--test:ErrorRanges" # E_StaticallyResolvedByRef01.fs - SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs \ No newline at end of file + SOURCE=E_ByrefAsArrayElement.fs SCFLAGS="--test:ErrorRanges" # E_ByrefAsArrayElement.fs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/E_NoImplicitDowncast01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/E_NoImplicitDowncast01.fs deleted file mode 100644 index dcdb70a86cc..00000000000 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/E_NoImplicitDowncast01.fs +++ /dev/null @@ -1,14 +0,0 @@ -// #Regression #Conformance #TypeInference #TypeConstraints -// Verify no implicit downlcast -//This expression was expected to have type. 'Foo' .but here has type. 'Bar' - -type Foo() = - override this.ToString() = "Foo" - -type Bar() = - inherit Foo() - override this.ToString() = "Bar" - - -let a = new Foo() -let b : Foo = new Bar() // Should fail diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/env.lst index 041ba830d0b..09bfdb1fb25 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/env.lst @@ -1,5 +1,3 @@ - SOURCE=E_NoImplicitDowncast01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_NoImplicitDowncast01.fs - SOURCE=E_TypeFuncDeclaredExplicit01.fs # E_TypeFuncDeclaredExplicit01.fs SOURCE=ValueRestriction01.fs # ValueRestriction01.fs @@ -11,4 +9,4 @@ SOURCE=DelegateConstraint01.fs # DelegateConstraint01.fs SOURCE=E_DelegateConstraint01.fs # E_DelegateConstraint01.fs - SOURCE=ConstructorConstraint01.fs # ConstructorConstraint01.fs \ No newline at end of file + SOURCE=ConstructorConstraint01.fs # ConstructorConstraint01.fs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_GenInterfaceWGenMethods01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_GenInterfaceWGenMethods01.fs index 509ca899548..5d87e71957e 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_GenInterfaceWGenMethods01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_GenInterfaceWGenMethods01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypeInference // FSHARP1.0:1445. See also FSHARP1.0:4721 // Failure when generating code for generic interface with generic method -//Value restriction\. The value 'result' has been inferred to have generic type. val result : '_a array when '_a : equality and '_a : null .Either define 'result' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation\.$ +//Value restriction\. The value 'result' has been inferred to have generic type. val result: '_a array when '_a: equality and '_a: null .Either define 'result' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation\.$ type 'a IFoo = interface abstract DoStuff<'b> : 'a -> 'b array end diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_MoreThanOneDispatchSlotMatch01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_MoreThanOneDispatchSlotMatch01.fs index a92bd56dce5..42c921ab237 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_MoreThanOneDispatchSlotMatch01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/DispatchSlotInference/E_MoreThanOneDispatchSlotMatch01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypeInference // FSB 1625, fsc generates assemblies that don't load/peverify -//The override 'M : int -> int' implements more than one abstract slot, e\.g\. 'abstract member IB\.M : int -> int' and 'abstract member IA\.M : int -> int' +//The override 'M: int -> int' implements more than one abstract slot, e\.g\. 'abstract IB\.M: int -> int' and 'abstract IA\.M: int -> int' type IA = abstract M : int -> int diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/FunctionApplicationResolution/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/FunctionApplicationResolution/env.lst index 3a4e92efe97..9356898dc59 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/FunctionApplicationResolution/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/FunctionApplicationResolution/env.lst @@ -5,4 +5,4 @@ # in MT scenarios because of an external bug (see FSHARP1.0:5678) # For this reason, we give up the full peverification in MT runs. NoMT SOURCE=InferGenericArgAsTuple02.fs # InferGenericArgAsTuple02.fs - SOURCE=InferGenericArgAsTuple02.fs PEVER=/MD # InferGenericArgAsTuple02.fs - /MD \ No newline at end of file + SOURCE=InferGenericArgAsTuple02.fs PEVER=/MD # InferGenericArgAsTuple02.fs - /MD diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_GeneralizeMemberInGeneric01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_GeneralizeMemberInGeneric01.fs index 1ba1bf5c15e..db79a5bb18e 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_GeneralizeMemberInGeneric01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_GeneralizeMemberInGeneric01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #TypeInference // Regression for Dev11:10649, we used to generalize some members too early which could be unsound if that member was in a generic type -//The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private Foo\.Inf : \('T list -> 'T list\)'\.$ -//The function or member 'Foo' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private Qux\.Foo : \('T list -> 'T list\)'\.$ +//The function or member 'Inf' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private Foo\.Inf: \('T list -> 'T list\)'\.$ +//The function or member 'Foo' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member private Qux\.Foo: \('T list -> 'T list\)'\.$ // Used to ICE type Foo<'T> = FooCase of 'T diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_NoMoreValueRestriction01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_NoMoreValueRestriction01.fs index bda8af6bac2..eb925d7537c 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_NoMoreValueRestriction01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/E_NoMoreValueRestriction01.fs @@ -2,9 +2,9 @@ // Verify error if you only specify some, but not all, type args //This expression was expected to have type 'char' but here has type 'float32' -let f<'a> x (y : 'a) = (x, y) // used to be error "Value restriction...". In Beta2, it is ok (val f : obj -> 'a -> obj * 'a) +let f<'a> x (y : 'a) = (x, y) // used to be error "Value restriction...". In Beta2, it is ok (val f: obj -> 'a -> obj * 'a) -let p = f 'a' 1 // At this point, (val f : char -> 'a -> char * 'a) +let p = f 'a' 1 // At this point, (val f: char -> 'a -> char * 'a) let q = f 1.f 1 // This is an error! diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/NoMoreValueRestriction01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/NoMoreValueRestriction01.fs index 97af65cbebd..57b549b2e24 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/NoMoreValueRestriction01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/NoMoreValueRestriction01.fs @@ -2,7 +2,7 @@ // Verify error if you only specify some, but not all, type args // -let f<'a> x (y : 'a) = (x, y) // used to be error "Value restriction...". In Beta2, it is ok (val f : obj -> 'a -> obj * 'a) +let f<'a> x (y : 'a) = (x, y) // used to be error "Value restriction...". In Beta2, it is ok (val f: obj -> 'a -> obj * 'a) let p = f 'a' 1 diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/RecordProperty01.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/RecordProperty01.fs index 609d43bc0a0..be701527266 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/RecordProperty01.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/RecordProperty01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #TypeInference // Regression for Dev11:41009, this class definition used to generate an error. Make sure we can use it too. -//The function or member 'Empty' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member Rope\.Empty : Rope<'T>'\. +//The function or member 'Empty' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types\. The inferred signature is 'static member Rope\.Empty: Rope<'T>'\. type Rope<'T> = | Sub of 'T[] diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/env.lst index 67a343da886..670bbc913ce 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/Generalization/env.lst @@ -4,8 +4,9 @@ SOURCE=E_DynamicTypeTestOverFreeArg01.fs SCFLAGS="--test:ErrorRanges" # E_DynamicTypeTestOverFreeArg01.fs SOURCE=LessRestrictive01.fs # LessRestrictive01.fs SOURCE=LessRestrictive02.fs # LessRestrictive02.fs - SOURCE=LessRestrictive02.fs # LessRestrictive03.fs + SOURCE=LessRestrictive03.fs # LessRestrictive03.fs SOURCE=TypeAnnotation01.fs # TypeAnnotation01.fs SOURCE=E_GeneralizeMemberInGeneric01.fs SCFLAGS="--test:ErrorRanges" # E_GeneralizeMemberInGeneric01.fs SOURCE=RecordProperty01.fs SCFLAGS="--test:ErrorRanges" # RecordProperty01.fs - SOURCE=PropertyCOnstraint01.fs # PropertyConstraint01.fs \ No newline at end of file + SOURCE=PropertyConstraint01.fs # PropertyConstraint01.fs + diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/Misc/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/Misc/env.lst index 0f04fbbc93e..43ffd8a2679 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/Misc/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/Misc/env.lst @@ -5,4 +5,4 @@ NoMT SOURCE=NoPartiallyQualifiedPathWarning01.fsx SCFLAGS="--warnaserror+" FSIMO SOURCE=E_ClashingIdentifiersDU02.fs SCFLAGS="--test:ErrorRanges" # E_ClashingIdentifiersDU02.fs SOURCE=recordlabels.fs # recordlabels.fs - SOURCE=RecordInference01.fs # RecordInference01.fs \ No newline at end of file + SOURCE=RecordInference01.fs # RecordInference01.fs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/env.lst index dadbaeb4e55..69673ec37a1 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/NameResolution/RequireQualifiedAccess/env.lst @@ -9,4 +9,4 @@ SOURCE=OnRecordVsUnion_NoRQA.fs # OnRecordVsUnion_NoRQA.fs SOURCE=OnRecordVsUnion_NoRQA2.fs # OnRecordVsUnion_NoRQA2.fs SOURCE=OnUnionWithCaseOfSameName.fs # OnUnionWithCaseOfSameName.fs - SOURCE=OnUnionWithCaseOfSameName2.fs # OnUnionWithCaseOfSameName2.fs \ No newline at end of file + SOURCE=OnUnionWithCaseOfSameName2.fs # OnUnionWithCaseOfSameName2.fs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/env.lst index ef81bbb415c..2d2aea97e7b 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/RecursiveSafetyAnalysis/env.lst @@ -3,9 +3,6 @@ SOURCE=RecursiveTypeDeclarations01.fs # RecursiveTypeDeclarations01.fs SOURCE=RecursiveTypeDeclarations02.fs # RecursiveTypeDeclarations02.fs SOURCE=RecursiveValueDeclarations01.fs # RecursiveValueDeclarations01.fs - SOURCE=E_RecursiveInline.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_RecursiveInline.fs - SOURCE=InfiniteRecursiveExplicitConstructor.fs COMPILE_ONLY=1 # InfiniteRecursiveExplicitConstructor.fs SOURCE=E_VariationsOnRecursiveStruct.fs SCFLAGS="--test:ErrorRanges" # E_VariationsOnRecursiveStruct.fs SOURCE=E_TypeDeclaration01.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_TypeDeclaration01.fs - SOURCE=E_TypeDeclaration02.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_TypeDeclaration02.fs - SOURCE=E_DuplicateRecursiveRecords.fs SCFLAGS="--test:ErrorRanges" # E_DuplicateRecursiveRecords.fs \ No newline at end of file + SOURCE=E_DuplicateRecursiveRecords.fs SCFLAGS="--test:ErrorRanges" # E_DuplicateRecursiveRecords.fs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/E_TwoDifferentTypeVariablesGen00.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/E_TwoDifferentTypeVariablesGen00.fs deleted file mode 100644 index a567c6e395d..00000000000 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/E_TwoDifferentTypeVariablesGen00.fs +++ /dev/null @@ -1,120 +0,0 @@ -// #Regression #TypeInference -// Regression test for FSHARP1.0:4758 -// Type Inference -// Check Method Disambiguation When User Generic Variable Get Instantiated By Overload Resolution - -//This expression was expected to have type. ''a' .but here has type. ''b' -//This expression was expected to have type. 'int' .but here has type. ''b' -//A type parameter is missing a constraint 'when 'b :> C' -//Type constraint mismatch. The type.+''b'.+is not compatible with type -//No overloads match for method 'M'\. The available overloads are shown below\. - - - -//No overloads match for method 'M'\. The available overloads are shown below\. - - - -//This expression was expected to have type. ''a' .but here has type. ''b' -//This expression was expected to have type. ''b' .but here has type. ''a' -//This expression was expected to have type. 'int' .but here has type. ''b' -//A type parameter is missing a constraint 'when 'b :> C' -//Type constraint mismatch. The type.+''b'.+is not compatible with type -//No overloads match for method 'M'\. The available overloads are shown below\. - - - - -//No overloads match for method 'M'\. The available overloads are shown below\. - - - - -//This expression was expected to have type. ''a' .but here has type. ''b' -//This expression was expected to have type. 'int' .but here has type. ''b' -//A type parameter is missing a constraint 'when 'b :> C' -//Type constraint mismatch. The type.+''b'.+is not compatible with type -//No overloads match for method 'M'\. The available overloads are shown below\. - - - - -//No overloads match for method 'M'\. The available overloads are shown below\. - - - - -//A type parameter is missing a constraint 'when 'b :> C' -//Type constraint mismatch. The type.+''b'.+is not compatible with type - -// These different return types are used to determine which overload got chosen -type One = | One -type Two = | Two -type Three = | Three -type Four = | Four - -// An unsealed type -type C() = - member x.P = 1 - -type C1 = - static member M<'a>(x:'a,y:'a) = One - -type C2 = - static member M<'a,'b>(x:'a,y:'b) = Two - -type C3 = - static member M<'a>(x:'a,y:int) = Three - -type C4 = - static member M<'a>(x:'a,y:C) = Four - -type C12 = - static member M<'a>(x:'a,y:'a) = One - static member M<'a,'b>(x:'a,y:'b) = Two - -type C23 = - static member M<'a,'b>(x:'a,y:'b) = Two - static member M<'a>(x:'a,y:int) = Three - -type C13 = - static member M<'a>(x:'a,y:'a) = One - static member M<'a>(x:'a,y:int) = Three - -type C14 = - static member M<'a>(x:'a,y:'a) = One - static member M<'a>(x:'a,y:C) = Four - -type C24 = - static member M<'a,'b>(x:'a,y:'b) = Two - static member M<'a>(x:'a,y:C) = Four - -type C123 = - static member M<'a>(x:'a,y:'a) = One - static member M<'a,'b>(x:'a,y:'b) = Two - static member M<'a>(x:'a,y:int) = Three - -type C1234 = - static member M<'a>(x:'a,y:'a) = One - static member M<'a,'b>(x:'a,y:'b) = Two - static member M<'a>(x:'a,y:int) = Three - static member M<'a>(x:'a,y:C) = Four - -module M0 = - let gB1 <'a,'b> (x:'a) (y:'b) = C1.M(x,y) = One // expect: type error - let gB3 <'a,'b> (x:'a) (y:'b) = C3.M(x,y) = Three // expect: type error - let gB4 <'a,'b> (x:'a) (y:'b) = C4.M(x,y) = Four // expect: type error - let gB13 <'a,'b> (x:'a) (y:'b) = C13.M(x,y) // expect: ambiguity error (and note: both would instantiate 'a or 'b) - let gB14 <'a,'b> (x:'a) (y:'b) = C14.M(x,y) = Four // expect: ambiguity error - let gC1 <'a,'b> (x:'a) (y:'b) = C1.M<'a>(x,y) = One // expect: type error - let gC3 <'a,'b> (x:'a) (y:'b) = C3.M<'b>(x,y) = Three // expect: type error - let gC4 <'a,'b> (x:'a) (y:'b) = C4.M<'a>(x,y) = Four // expect: type error - let gC13 <'a,'b> (x:'a) (y:'b) = C13.M<'a>(x,y) // expect: ambiguity error - let gC14 <'a,'b> (x:'a) (y:'b) = C14.M<'a>(x,y) // expect: ambiguity error - let gD1 <'a,'b> (x:'a) (y:'b) = C1.M<_>(x,y) = One // expect: type error - let gD3 <'a,'b> (x:'a) (y:'b) = C3.M<_>(x,y) = Three // expect: type error - let gD4 <'a,'b> (x:'a) (y:'b) = C4.M<_>(x,y) = Four // expect: type error - let gD13 <'a,'b> (x:'a) (y:'b) = C13.M<_>(x,y) // expect: ambiguity error (and note: both would instantiate 'a or 'b) - let gD14 <'a,'b> (x:'a) (y:'b) = C14.M<_>(x,y) // expect: type error - let gD24 <'a,'b> (x:'a) (y:'b) = C24.M<_>(x,y) // expect: type error - diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/env.lst b/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/env.lst index 72da539ce69..1c1ac1a7516 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/env.lst +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/TypeInference/env.lst @@ -16,7 +16,6 @@ SOURCE=OneTypeVariable03.fs SCFLAGS="-a --test:ErrorRanges --warnaserror+" # OneTypeVariable03.fs SOURCE=OneTypeVariable03rec.fs SCFLAGS="-a --test:ErrorRanges --warnaserror+" # OneTypeVariable03rec.fs - SOURCE=E_TwoDifferentTypeVariablesGen00.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_TwoDifferentTypeVariablesGen00.fs SOURCE=E_TwoDifferentTypeVariablesGen01rec.fs SCFLAGS="-a --test:ErrorRanges --flaterrors" # E_TwoDifferentTypeVariablesGen01rec.fs SOURCE=W_OneTypeVariable03.fs SCFLAGS="-a --test:ErrorRanges" # W_OneTypeVariable03.fs SOURCE=W_OneTypeVariable03rec.fs SCFLAGS="-a --test:ErrorRanges" # W_OneTypeVariable03rec.fs @@ -28,4 +27,4 @@ SOURCE=E_PrettifyForall.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_PrettifyForall.fs SOURCE=IgnoreUnitParameters.fs # IgnoreUnitParameters.fs - SOURCE=IgnoreUnitParameters.fs SCFLAGS="--optimize- -g" # IgnoreUnitParameters2.fs \ No newline at end of file + SOURCE=IgnoreUnitParameters.fs SCFLAGS="--optimize- -g" # IgnoreUnitParameters2.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/env.lst index 8f25ff36dd9..a477a0bb909 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Comments/env.lst @@ -1,6 +1,3 @@ - SOURCE=star01.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # star01.fs - SOURCE=E_star02.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_star02.fs - SOURCE=star03.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # star03.fs SOURCE=embeddedString001.fs # embeddedString001.fs SOURCE=embeddedString002.fs # embeddedString002.fs @@ -26,4 +23,4 @@ SOURCE=E_ocamlstyle_nested007.fs # E_ocamlstyle_nested007.fs SOURCE=XmlDocComments01.fs # XmlDocComments01.fs - SOURCE=DontEscapeCommentFromString01.fs # DontEscapeCommentFromString01.fs \ No newline at end of file + SOURCE=DontEscapeCommentFromString01.fs # DontEscapeCommentFromString01.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/ConditionalCompilation/E_MustBeIdent02.fs b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/ConditionalCompilation/E_MustBeIdent02.fs index 8e204947133..09dee4fbf57 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/ConditionalCompilation/E_MustBeIdent02.fs +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/ConditionalCompilation/E_MustBeIdent02.fs @@ -1,10 +1,9 @@ -// #Regression #Conformance #LexicalAnalysis +// #Regression #Conformance #LexicalAnalysis // Regression test for FSHARP1.0:1419 -//#if directive should be immediately followed by an identifier -//#endif has no matching #if in pattern -//Unmatched '\(' +//The type 'if_' is not defined. +//The type 'endif_' is not defined. #light let t8 (x : #if_) = () let t7 (x : #endif_) = () -exit 1 +exit 1 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs index 7c185078802..5aeec2e163f 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/IdentifiersAndKeywords/E_KeywordIdent01.fs @@ -2,7 +2,7 @@ #light //Unexpected keyword 'type' in binding -//Unexpected keyword 'class' in pattern +//Unexpected keyword 'class' in binding. Expected '=' or other token. let type = 2 diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/env.lst index 17880073bf3..683b2c7652d 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/NumericLiterals/env.lst @@ -7,16 +7,6 @@ SOURCE=casingIEEE-lf-LF03a.fs SCFLAGS="--test:ErrorRanges" # casingIEEE-lf-LF03a.fs SOURCE=casingIEEE-lf-LF03b.fs SCFLAGS="--test:ErrorRanges" # casingIEEE-lf-LF03b.fs - SOURCE=enumNegativeLiterals001.fs COMPILE_ONLY=1 # enumNegativeLiterals001.fs - SOURCE=E_enumNegativeLiterals001.fs COMPILE_ONLY=1 # E_enumNegativeLiterals001.fs - SOURCE=E_enumNegativeLiterals002.fs COMPILE_ONLY=1 # E_enumNegativeLiterals002.fs - SOURCE=E_enumNegativeLiterals003.fs COMPILE_ONLY=1 # E_enumNegativeLiterals003.fs - SOURCE=E_enumNegativeLiterals004.fs COMPILE_ONLY=1 # E_enumNegativeLiterals004.fs - SOURCE=E_enumNegativeLiterals005.fs COMPILE_ONLY=1 # E_enumNegativeLiterals005.fs - SOURCE=E_enumNegativeLiterals006.fs COMPILE_ONLY=1 # E_enumNegativeLiterals006.fs - SOURCE=E_enumNegativeLiterals007.fs COMPILE_ONLY=1 # E_enumNegativeLiterals007.fs - SOURCE=E_enumNegativeLiterals008.fs COMPILE_ONLY=1 # E_enumNegativeLiterals008.fs - SOURCE=E_enumNegativeLiterals009.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # E_enumNegativeLiterals009.fs SOURCE=NumericaLiterals01.fs # NumericaLiterals01.fs SOURCE=MaxLiterals01.fs # MaxLiterals01.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/env.lst index 83c576158aa..9af659e6c2b 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/Shift/Generics/env.lst @@ -1,2 +1 @@ SOURCE=RightShift001.fs COMPILE_ONLY=1 # RightShift001.fs - SOURCE=RightShift002.fs COMPILE_ONLY=1 # RightShift002.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/byteChars01.fs b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/ByteChars01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/byteChars01.fs rename to tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/ByteChars01.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/env.lst index ba30f476068..86c12665c04 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/StringsAndCharacters/env.lst @@ -32,4 +32,4 @@ SOURCE=TripleQuoteString01.fs # TripleQuoteString01.fs SOURCE=TripleQuoteString02.fs # TripleQuoteString02.fs NoMT SOURCE=TripleQuoteStringInFSI01.fsx FSIMODE=PIPE COMPILE_ONLY=1 # TripleQuoteStringInFSI01.fsx -NoMT SOURCE=TripleQuoteStringInFSI02.fsx FSIMODE=FEED COMPILE_ONLY=1 # TripleQuoteStringInFSI02.fsx \ No newline at end of file +NoMT SOURCE=TripleQuoteStringInFSI02.fsx FSIMODE=FEED COMPILE_ONLY=1 # TripleQuoteStringInFSI02.fsx diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/env.lst index 6897e417205..e4b17f97b7d 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicKeywords/env.lst @@ -1,10 +1,4 @@ - SOURCE=GreaterThanClosedCurly01.fs COMPILE_ONLY=1 # GreaterThanClosedCurly01.fs - SOURCE=GreaterThanClosedCurly02.fs COMPILE_ONLY=1 # GreaterThanClosedCurly02.fs - SOURCE=GreaterThanClosedCurly03.fs COMPILE_ONLY=1 # GreaterThanClosedCurly03.fs - SOURCE=GreaterThanClosedCurly04.fs COMPILE_ONLY=1 # GreaterThanClosedCurly04.fs - SOURCE=GreaterThanClosedCurly05.fs COMPILE_ONLY=1 # GreaterThanClosedCurly05.fs SOURCE=GreaterThanClosedParenthesis01.fs COMPILE_ONLY=1 # GreaterThanClosedParenthesis01.fs - SOURCE=GreaterThanClosedSquare01.fs COMPILE_ONLY=1 # GreaterThanClosedSquare01.fs SOURCE=GreaterThanClosedSquare02.fs COMPILE_ONLY=1 # GreaterThanClosedSquare02.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs index b7c161c5620..a8cf50ea24b 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/E_LessThanDotOpenParen001.fs @@ -4,10 +4,7 @@ // want to verify we do not crash! //This construct causes code to be less generic than indicated by the type annotations\. The type variable 'S has been constrained to be type 'int' //This code is not sufficiently generic\. The type variable \^T when \^T : \(static member \( \+ \) : \^T \* \^T -> \^a\) could not be generalized because it would escape its scope -//No overloads match for method 'op_PlusPlusPlus'\. The available overloads are shown below\. -//No overloads match for method 'op_PlusPlusPlus'\. The available overloads are shown below\. -//No overloads match for method 'op_PlusPlusPlus'\. The available overloads are shown below\. - + type public TestType<'T,'S>() = member public s.Value with get() = Unchecked.defaultof<'T> diff --git a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/env.lst b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/env.lst index 2cd6bea7068..c9475b971b2 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalAnalysis/SymbolicOperators/env.lst @@ -1,11 +1,6 @@ - SOURCE=GreaterThanDotParen01.fs COMPILE_ONLY=1 # GreaterThanDotParen01.fs - SOURCE=E_GreaterThanDotParen01.fs COMPILE_ONLY=1 # E_GreaterThanDotParen01.fs - SOURCE=E_LessThanDotOpenParen001.fs COMPILE_ONLY=1 SCFLAGS=--flaterrors # E_LessThanDotOpenParen001.fs SOURCE=LessThanDotOpenParen001.fs COMPILE_ONLY=1 # LessThanDotOpenParen001.fs - SOURCE=GreaterThanColon001.fs COMPILE_ONLY=1 # GreaterThanColon001.fs - SOURCE=E_GreaterThanColon002.fs COMPILE_ONLY=1 # E_GreaterThanColon002.fs SOURCE=QMarkSimple.fs # QMarkSimple.fs SOURCE=QMarkNested.fs # QMarkNested.fs SOURCE=QMarkArguments.fs # QMarkArguments.fs @@ -23,4 +18,4 @@ SOURCE=QMarkExpressionAsArgument.fs # QMarkExpressionAsArgument.fs SOURCE=QMarkExpressionAsArgument2.fs # QMarkExpressionAsArgument2.fs - SOURCE=E_CantUseDollarSign.fs # E_CantUseDollarSign.fs \ No newline at end of file + SOURCE=E_CantUseDollarSign.fs # E_CantUseDollarSign.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/env.lst b/tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/env.lst index 61344aacac0..ce379245e34 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalFiltering/Basic/OffsideExceptions/env.lst @@ -2,4 +2,3 @@ SOURCE=Offside01b.fs SCFLAGS=--test:ErrorRanges # Offside01b.fs SOURCE=Offside01c.fs SCFLAGS=--test:ErrorRanges # Offside01c.fs - SOURCE=InfixTokenPlusOne.fs COMPILE_ONLY=1 # InfixTokenPlusOne.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/env.lst b/tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/env.lst index e441945cf48..b8388cdb3f3 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalFiltering/HashLight/env.lst @@ -1,4 +1,3 @@ - SOURCE=IndentationWithComputationExpression01.fs SCFLAGS=--warnaserror+ COMPILE_ONLY=1 # IndentationWithComputationExpression01.fs SOURCE=MissingEndToken01.fs # MissingEndToken01.fs SOURCE=OffsideAccessibility01.fs # OffsideAccessibility01.fs @@ -24,4 +23,4 @@ NoMT SOURCE=default_in_fsi02.fs COMPILE_ONLY=1 FSIMODE=EXEC # default_in_fsi02 SOURCE=E_TABsNotAllowedIndentOff.fs SCFLAGS="--test:ErrorRanges" # E_TABsNotAllowedIndentOff.fs - SOURCE=CastOperators01.fs # CastOperators01.fs \ No newline at end of file + SOURCE=CastOperators01.fs # CastOperators01.fs diff --git a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/env.lst b/tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/env.lst index 87898e0cd9d..b298d3ab8ff 100644 --- a/tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/env.lst +++ b/tests/fsharpqa/Source/Conformance/LexicalFiltering/HighPrecedenceApplication/env.lst @@ -1,4 +1,3 @@ SOURCE=BasicCheck01.fs # BasicCheck01.fs SOURCE=BasicCheck02.fs # BasicCheck02.fs - SOURCE=RangeOperator01.fs COMPILE_ONLY=1 SCFLAGS=-a # RangeOperator01.fs NoMT SOURCE=RangeOperator01.fsx COMPILE_ONLY=1 FSIMODE=EXEC # RangeOperator01.fsx diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember02.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember02.fs index 66dae444a7f..901344e7715 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember02.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember02.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #MethodsAndProperties #MemberDefinitions // Regression test for TFS bug Dev10:834160 // This test would fail if we don't set the IsImplemented bit for the abstract slot -//No implementation was given for 'abstract member B\.M : string -> unit'$ +//No implementation was given for 'abstract B\.M: string -> unit'$ [] type B() = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember03.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember03.fs index 85a28e93d52..277ed73ab9d 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember03.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/AbstractMembers/E_CallToAbstractMember03.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #MethodsAndProperties #MemberDefinitions // Regression test for TFS bug Dev10:834160 // This test would fail if we don't set the IsImplemented bit for the abstract slot -//No implementation was given for 'abstract member B\.M : int -> float'$ +//No implementation was given for 'abstract B\.M: int -> float'$ //This type is 'abstract' since some abstract members have not been given an implementation\. If this is intentional then add the '\[\]' attribute to your type\.$ [] type B() = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/AutoProperties/E_PrivateProperty01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/AutoProperties/E_PrivateProperty01.fs index d99c71b9bff..acb21f79b71 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/AutoProperties/E_PrivateProperty01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/AutoProperties/E_PrivateProperty01.fs @@ -1,5 +1,5 @@ // #Conformance #ObjectOrientedTypes #Classes #MethodsAndProperties #Accessibility -//The type 'X' is less accessible than the value, member or type 'member XX\.PublicProperty : X' it is used in.$ +//The type 'X' is less accessible than the value, member or type 'member XX\.PublicProperty: X' it is used in.$ type private X() = class end type XX() = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/env.lst index 342c0138117..21f374266c6 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ExplicitObjectConstructors/env.lst @@ -1,4 +1 @@ # We should have tests for all the other constructs that can be put in an explicit object constructor! - SOURCE=new_while_01.fs COMPILE_ONLY=1 # new_while_01.fs - SOURCE=WithAttribute01.fs COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges" # WithAttribute01.fs - SOURCE=WithAttribute02.fs COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges" # WithAttribute02.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/env.lst index 3e23c2d7cda..ddb777feb12 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ImplicitObjectConstructors/env.lst @@ -1,2 +1 @@ - SOURCE=WithAttribute.fs COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges" # WithAttribute.fs SOURCE=E_AddExplicitWithImplicit.fs # E_AddExplicitWithImplicit.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs index 0be9356eab4..9c9455c5887 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #ObjectOrientedTypes #Classes #MethodsAndProperties #MemberDefinitions // Regression test for FSHARP1.0:5475 -//Duplicate property\. The property 'M' has the same name and signature as another property in type 'C'\.$ +//Duplicate property\. The property 'M' has the same name and signature as another property in type 'C'\.$ type C = class member __.M = () static member M = () diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs index 29a80736286..94fe834a998 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs @@ -2,7 +2,7 @@ // Verify that one should not be able to have two properties called �X� with different arities (number of arguments). // This is regression test for FSHARP1.0:4529 -//The property 'X' has the same name as another property in type 'TestType1' +//The property 'X' has the same name as another property in type 'TestType1' type TestType1( x : int ) = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_AbstractClass01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_AbstractClass01.fs index 0f793996c1c..ce38600f850 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_AbstractClass01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_AbstractClass01.fs @@ -4,9 +4,9 @@ // FSB 1272, New-ing a sub class with unimplemented abstract members should not be allowed. //This type is 'abstract' since some abstract members have not been given an implementation\. If this is intentional then add the '\[\]' attribute to your type -//No implementation was given for 'abstract member Foo\.f : int -> int' +//No implementation was given for 'abstract Foo\.f: int -> int' //This type is 'abstract' since some abstract members have not been given an implementation\. If this is intentional then add the '\[\]' attribute to your type -//No implementation was given for 'abstract member Foo\.f : int -> int' +//No implementation was given for 'abstract Foo\.f: int -> int' type Foo = class diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/StaticLetDoDeclarations/E_RecMutable01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/StaticLetDoDeclarations/E_RecMutable01.fs index 7adf9a2e1dc..547b14724c1 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/StaticLetDoDeclarations/E_RecMutable01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/StaticLetDoDeclarations/E_RecMutable01.fs @@ -2,7 +2,7 @@ // rec (mutable) // See FSHARP1.0:2329 -//Only record fields and simple, non-recursive 'let' bindings may be marked mutable +//Mutable 'let' bindings can't be recursive or defined in recursive modules or namespaces type C() = class static let rec mutable m = 0 // only record fields and simple 'let' bindings may be marked mutable. end diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx index 9a3d2351965..182fb04be48 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/E_NotMemberOrFunction01.fsx @@ -1,9 +1,9 @@ // #Conformance #ObjectOrientedTypes #Classes #TypeInference #ValueRestriction -//Value restriction\. The value 'x1' has been inferred to have generic type. val x1 : \('_a -> unit\) .Either make the arguments to 'x1' explicit or, if you do not intend for it to be generic, add a type annotation\.$ +//Value restriction\. The value 'x1' has been inferred to have generic type. val x1: \('_a -> unit\) .Either make the arguments to 'x1' explicit or, if you do not intend for it to be generic, add a type annotation\.$ // We expect a value restriction here. The inferred signature is: -// val x1 : (?1 -> unit) +// val x1: (?1 -> unit) // Here 'x1' is not a member/function. Further, looking at the signature alone, the type inference // variable could have feasibly be genrealized at 'x1' (c.f. the case above, where it // was generalized). diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx index baceab8e5db..56b49d2466d 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/TypeInferenceVariable01.fsx @@ -3,7 +3,7 @@ // // We expect no value restriction here. The inferred signature is: -// val x0 : ('T -> unit) +// val x0: ('T -> unit) // Here the type inference variable is generalized at 'x0'. let f0 (x:obj) = () let x0 = f0 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/env.lst index 3343c47a418..356efb7ae93 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/ValueRestriction/env.lst @@ -1,10 +1,4 @@ - SOURCE=TypeArgs01.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # TypeArgs01.fsx - SOURCE=MemberOrFunction01.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # MemberOrFunction01.fsx - SOURCE=MemberOrFunction01Gen.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # MemberOrFunction01Gen.fsx - SOURCE=MemberOrFunction02.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # MemberOrFunction02.fsx - SOURCE=MemberOrFunction02Gen.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # MemberOrFunction02Gen.fsx SOURCE=E_NotMemberOrFunction01.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+ --flaterrors" # E_NotMemberOrFunction01.fsx - SOURCE=TypeFunction01.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # TypeFunction01.fsx SOURCE=TypeInferenceVariable01.fsx COMPILE_ONLY=1 SCFLAGS="-a --test:ErrorRanges --warnaserror+" # TypeInferenceVariable01.fsx diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_NoValueFieldOnEnum.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_NoValueFieldOnEnum.fs index c9811b9d66e..a3fb2787598 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_NoValueFieldOnEnum.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_NoValueFieldOnEnum.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #ObjectOrientedTypes #Enums // FS1 992: ilreflect error triggered with Enum value__ calls. -//The field, constructor or member 'value__' is not defined +//The type 'EnumType' does not define the field, constructor or member 'value__' type EnumType = | A = 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs new file mode 100644 index 00000000000..ec6bc99e266 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ClassConsumeMultipleInterfaceFromCS.5.0.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT +#light + +let mutable res = true + +type D() = + inherit T() + interface I_003 with + member xxx.Home(i) = i + +if (D() :> I_003).Home(5) <> 5 then + System.Console.WriteLine("D.Home failed") + res <- false + + +if (res = true) then + exit 0 + +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.5.0.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ConsumeMultipleInterfaceFromCS.5.0.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs new file mode 100644 index 00000000000..5c47e255fa6 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.4.7.fs @@ -0,0 +1,22 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. +#light + +let mutable res = true + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +type D() = + inherit T() + interface I_003 with + member xxx.Home(i) = i + +if (D() :> I_003).Home(5) <> 5 then + System.Console.WriteLine("D.Home failed") + res <- false + + +if (res = true) then + exit 0 + +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs deleted file mode 100644 index ed87e24dbda..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ClassConsumeMultipleInterfaceFromCS.fs +++ /dev/null @@ -1,23 +0,0 @@ -// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT -// This type implements the same interface at different generic instantiations 'I_002\' and 'I_002\'\. This is not permitted in this version of F#\. -#light - -let mutable res = true - -// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type -type D() = - inherit T() - interface I_003 with - member xxx.Home(i) = i - -if (D() :> I_003).Home(5) <> 5 then - System.Console.WriteLine("D.Home failed") - res <- false - - -if (res = true) then - exit 0 - - -exit 1 - diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs new file mode 100644 index 00000000000..7f3c57e8b84 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.4.7.fs @@ -0,0 +1,67 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations #ReqNOMT +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. +// Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. +#light + +let mutable res = true +let t = new T() +if (t.Me("F#") <> 2) then + System.Console.WriteLine("t.Me(string) failed") + res <- false + +if (t.Me('a') <> 1) then + System.Console.WriteLine("t.Me(char) failed") + res <- false + +if (t.Home(0) <> 0) then + System.Console.WriteLine("t.Home failed") + res <- false + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression implementing a C# interface type +if ( {new I_003 with + member xxx.Home(i) = i + member xxx.Me(c:char) = 0 + member xxx.Me(s:string) = 0 + }.Home ( + {new I_002 with + member x.Me (s) = s + }.Me(0) ) <> 0 ) then + System.Console.WriteLine("I_003.Home failed") + res <- false + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +if (({new T() with + member x.ToString() = "a" + interface I_003 with + member xxx.Home(i) = i + member xxx.Me(c:char) = 0 + member xxx.Me(s:string) = 0 + } :> I_003).Home ( + {new I_002 with + member x.Me (s) = s + }.Me(0) ) <> 0 ) then + System.Console.WriteLine("T.Home obj expr failed") + res <- false + +// Check we can create an object of a C# type implementing multiple instantiations of an interface +if T().Home(4) <> 0 then + System.Console.WriteLine("T.Home failed") + res <- false + + +// Check we can't implement an interface inheriting from multiple instantiations of an interface when defining an object expression inheriting from a C# class type +type D() = + inherit T() + interface I_003 with + member xxx.Home(i) = i + +if (D() :> I_003).Home(5) <> 5 then + System.Console.WriteLine("D.Home failed") + res <- false + + +if (res = true) then + exit 0 +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.5.0.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.fs rename to tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ConsumeMultipleInterfaceFromCS.5.0.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs deleted file mode 100644 index 10927e41457..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01.fs +++ /dev/null @@ -1,27 +0,0 @@ -// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations - - -// Verify error when trying to implement the same generic interface twice. -// Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# - -type IA<'b> = - interface - abstract Foo : int -> int - end -type IB<'b> = - interface - inherit IA<'b> - inherit IA - end - -type A() = - class - interface IB with - member obj.Foo (x : int) = x - end - end - -let x = A() - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs new file mode 100644 index 00000000000..4664b911684 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_4.7.fs @@ -0,0 +1,25 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Verify error when trying to implement the same generic interface twice. +// Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + +type IA<'b> = + interface + abstract Foo : int -> int + end +type IB<'b> = + interface + inherit IA<'b> + inherit IA + end + +type A() = + class + interface IB with + member obj.Foo (x : int) = x + end + end + +let x = A() + +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs new file mode 100644 index 00000000000..638eda79518 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice01_5.0.fs @@ -0,0 +1,27 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + + +// Verify error when trying to implement the same generic interface twice. +// Regression for FSB 3574, PE Verification failure when implementing multiple generic interfaces (one generic, one specifc) +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. + +type IA<'b> = + interface + abstract Foo : int -> int + end +type IB<'b> = + interface + inherit IA<'b> + inherit IA + end + +type A() = + class + interface IB with + member obj.Foo (x : int) = x + end + end + +let x = A() + +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs deleted file mode 100644 index 560cb715586..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02.fs +++ /dev/null @@ -1,22 +0,0 @@ -// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Verify error when trying to implement the same generic -// interface twice -//This type implements the same interface at different generic instantiations 'IFoo' and 'IFoo'\. This is not permitted in this version of F# - -type IFoo<'a> = - interface - abstract DoStuff : unit -> unit - end - -type Bar() = - interface IFoo with - member this.DoStuff() = printfn "IFoo" - interface IFoo with - member this.DoStuff() = printfn "IFoo" - - -let t = new Bar() -(t :> IFoo).DoStuff() -(t :> IFoo).DoStuff() - -exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs new file mode 100644 index 00000000000..b49cb87db36 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_ImplementGenIFaceTwice02_4.7.fs @@ -0,0 +1,21 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Verify error when trying to implement the same generic interface twice +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + +type IFoo<'a> = + interface + abstract DoStuff : unit -> unit + end + +type Bar() = + interface IFoo with + member this.DoStuff() = printfn "IFoo" + interface IFoo with + member this.DoStuff() = printfn "IFoo" + + +let t = new Bar() +(t :> IFoo).DoStuff() +(t :> IFoo).DoStuff() + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl01.fs index 24403ca6c8b..feaa5cc7cb0 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl01.fs @@ -3,7 +3,7 @@ // This code used to compile and then throw at runtime // Now we emit an error. -//No implementation was given for 'abstract member INodeWrapper\.Node : Node'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' +//No implementation was given for 'abstract INodeWrapper\.Node: Node'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' namespace Foo diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl03.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl03.fs index f31102e81de..e0e48592464 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl03.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_InterfaceNotFullyImpl03.fs @@ -2,7 +2,7 @@ // Regression test for FSHARP1.0:3748 // Now we emit an error. -//No implementation was given for 'abstract member IThing\.Name : string'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' +//No implementation was given for 'abstract IThing\.Name: string'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' open System type IThing = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs new file mode 100644 index 00000000000..f3a3babb559 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst01.4.7.fs @@ -0,0 +1,13 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Regression test for FSHARP1.0:5540 +// Prior to F# 5.0 it was forbidden to implement an interface at multiple instantiations +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + +type IA<'a> = + interface + //abstract X : unit -> 'a + end + +type C() = + interface IA + interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs new file mode 100644 index 00000000000..71eb461b57b --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst04.4.7.fs @@ -0,0 +1,19 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Regression test for FSHARP1.0:5540 +// It is forbidden to implement an interface at multiple instantiations +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + + +type IA<'a, 'b> = + interface + abstract X : 'a -> 'b + end + +type C<'a>() = + interface IA with + member m.X(x) = 'a' + + interface IA with + member m.X(c) = 10 + + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs new file mode 100644 index 00000000000..9abd5c567c3 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.4.7.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Aliased types should correctly unify, even in combination with a measure. + +//Feature 'interfaces with multiple generic instantiation' is not available in F# 4.7. Please use language version 5.0 or greater. + +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB> with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.5.0.fs new file mode 100644 index 00000000000..73d0be3c7aa --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInst07.5.0.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// int does not unify with in. + +//'C' cannot implement the interface 'IB<_>' with the two instantiations 'IB' and 'IB>' because they may unify. + +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB> with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInterfaceInheritance.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInterfaceInheritance.fs index b4415a7bc0e..df1d97e60d0 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInterfaceInheritance.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/E_MultipleInterfaceInheritance.fs @@ -60,12 +60,12 @@ if ( {new I_003 with System.Console.WriteLine("I_003.Home failed") res <- false -//The field, constructor or member 'Me' is not defined -//The field, constructor or member 'Me' is not defined -//The field, constructor or member 'Home' is not defined +//The type 'T' does not define the field, constructor or member 'Me' +//The type 'T' does not define the field, constructor or member 'Me' +//The type 'T' does not define the field, constructor or member 'Home' //No implementation was given for those members: -//'abstract member I_002\.Me : 'a -> int'\. -//'abstract member I_002\.Me : 'a -> int'\. +//'abstract I_002\.Me: 'a -> int'\. +//'abstract I_002\.Me: 'a -> int'\. //Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.'\. //This expression was expected to have type. 'int' .but here has type. 'string' //This expression was expected to have type. 'int' .but here has type. 'char' diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs new file mode 100644 index 00000000000..86acf7b2926 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/ImplementGenIFaceTwice02_5.0.fs @@ -0,0 +1,11 @@ +// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +type IFoo<'a> = + interface + abstract DoStuff : unit -> string + end + +type Bar() = + interface IFoo with + member this.DoStuff() = "IFoo" + interface IFoo with + member this.DoStuff() = "IFoo" diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs new file mode 100644 index 00000000000..e1d05457214 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/Inheritance_OverrideInterface.fs @@ -0,0 +1,47 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// It should be possible to override interface implementations + + +type MyInt = int +[] type kg + +type IB<'a> = + interface + abstract X : unit -> int + end + +type CBase() = + interface IB with + member x.X() = 1 + interface IB with + member x.X() = 2 + +type C2() = + inherit CBase() + interface IB with + member x.X() = 3 + +type C3() = + inherit C2() + interface IB with + member x.X() = 4 + +type C4() = + inherit C3() + interface IB with + member x.X() = 5 + interface IB with + member x.X() = 6 + interface IB with + member x.X() = 7 + +type C5() = + inherit C4() + interface IB with + member x.X() = 8 + interface IB> with + member x.X() = 9 + interface IB with + member x.X() = 10 + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs new file mode 100644 index 00000000000..ba560d0b300 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/InterfaceMember_NameCollisions.fs @@ -0,0 +1,45 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// There should be no method-name duplication + +// we need to ensure there are no collisions between (for example) +// - ``IB`` (non-generic) +// - IB<'T> instantiated with 'T = GlobalType +// This is only an issue for types inside the global namespace, because '.' is invalid even in a quoted identifier. +// So if the type is in the global namespace, prepend 'global`', because '`' is also illegal -> there can be no quoted identifer with that name. + +// without the prefix, the compiler would error out with +//> output error FS2014: A problem occurred writing the binary 'FsTest.exe': Error in pass2 for type C, error: duplicate entry 'IB.X' in method table + +namespace global + +type GlobalType() = class end + + +type ``IB`` = + interface + abstract X : unit -> int + end + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface ``IB`` with + member x.X() = 1 + interface IB with + member x.X() = 2 + +module M = + + let c = C() + let x1 = (c :> ``IB``).X() + let x2 = (c :> IB).X() + + if x1 <> 1 then + failwithf "expected 1, but got %i" x1 + + if x2 <> 2 then + failwithf "expected 2, but got %i" x2 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs new file mode 100644 index 00000000000..762f164bd9f --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.5.0.fs @@ -0,0 +1,10 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + +type IA<'a> = + interface + //abstract X : unit -> 'a + end + +type C() = + interface IA + interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs deleted file mode 100644 index 057d2da039d..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst01.fs +++ /dev/null @@ -1,13 +0,0 @@ -// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Regression test for FSHARP1.0:5540 -// It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ - -type IA<'a> = - interface - //abstract X : unit -> 'a - end - -type C() = - interface IA - interface IA diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs new file mode 100644 index 00000000000..85769553a57 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.5.0.fs @@ -0,0 +1,15 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations + +type IA<'a, 'b> = + interface + abstract X : 'a -> 'b + end + +type C<'a>() = + interface IA with + member m.X(x) = 'a' + + interface IA with + member m.X(c) = 10 + + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs deleted file mode 100644 index f1a2bc33753..00000000000 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst04.fs +++ /dev/null @@ -1,19 +0,0 @@ -// #Regression #Conformance #ObjectOrientedTypes #InterfacesAndImplementations -// Regression test for FSHARP1.0:5540 -// It is forbidden to implement an interface at multiple instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA'\. This is not permitted in this version of F#\.$ - - -type IA<'a, 'b> = - interface - abstract X : 'a -> 'b - end - -type C<'a>() = - interface IA with - member m.X(x) = 'a' - - interface IA with - member m.X(c) = 10 - - diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs new file mode 100644 index 00000000000..53d943f2c9b --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/MultipleInst06.fs @@ -0,0 +1,27 @@ +// #Conformance #ObjectOrientedTypes #InterfacesAndImplementations +// Aliased types should correctly unify + +// These errors could be improved, but verify that it errors out at all. +//Duplicate specification of an interface +//Duplicate or redundant interface +//Duplicate or redundant interface +//No abstract or interface member was found that corresponds to this override +//No abstract or interface member was found that corresponds to this override + + +type MyInt = int + + +type IB<'a> = + interface + abstract X : unit -> int + end + +type C() = + interface IB with + member x.X() = 1 + interface IB with + member x.X() = 2 + +exit 1 + diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst index 864b76bfbc8..81e96337788 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/InterfaceTypes/env.lst @@ -1,41 +1,53 @@ - SOURCE=E_InheritInterface.fs SCFLAGS=--test:ErrorRanges # E_InheritInterface.fs + SOURCE=E_InheritInterface.fs SCFLAGS=--test:ErrorRanges # E_InheritInterface.fs - SOURCE=TwoInstantiationOfTheSameInterface.fs COMPILE_ONLY=1 PRECMD="\$CSC_PIPE /t:library TwoInstantiationOfTheSameInterfaceDLL.cs" SCFLAGS=-r:TwoInstantiationOfTheSameInterfaceDLL.dll # TwoInstantiationOfTheSameInterface.fs + SOURCE=TwoInstantiationOfTheSameInterface.fs COMPILE_ONLY=1 PRECMD="\$CSC_PIPE /t:library TwoInstantiationOfTheSameInterfaceDLL.cs" SCFLAGS=-r:TwoInstantiationOfTheSameInterfaceDLL.dll # TwoInstantiationOfTheSameInterface.fs - SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs + SOURCE=ObjImplementsInterfaceGenWithConstraint.fs COMPILE_ONLY=1 # ObjImplementsInterfaceGenWithConstraint.fs - SOURCE=MultipleInst01.fs SCFLAGS=--test:ErrorRanges # MultipleInst01.fs - SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs - SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs - SOURCE=MultipleInst04.fs SCFLAGS=--test:ErrorRanges # MultipleInst04.fs - SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs + SOURCE=InterfaceMember_NameCollisions.fs SCFLAGS=--test:ErrorRanges # InterfaceMember_NameCollisions.fs - SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs - SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs - SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs - SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs + SOURCE=E_MultipleInst01.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst01.4.7.fs + SOURCE=MultipleInst01.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:5.0" # MultipleInst01.5.0.fs + SOURCE=MultipleInst02.fs SCFLAGS=--test:ErrorRanges # MultipleInst02.fs + SOURCE=MultipleInst03.fs SCFLAGS=--test:ErrorRanges # MultipleInst03.fs + SOURCE=E_MultipleInst04.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7" # E_MultipleInst04.4.7.fs + SOURCE=MultipleInst04.5.0.fs SCFLAGS=--test:ErrorRanges --langversion:5.0" # MultipleInst04.5.0.fs + SOURCE=MultipleInst05.fs SCFLAGS=--test:ErrorRanges # MultipleInst05.fs + SOURCE=MultipleInst06.fs SCFLAGS="--test:ErrorRanges" # MultipleInst06.fs + SOURCE=E_MultipleInst07.4.7.fs SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_MultipleInst07.4.7.fs + SOURCE=E_MultipleInst07.5.0.fs SCFLAGS="--test:ErrorRanges --langversion:5.0 --nowarn:221" # E_MultipleInst07.5.0.fs - SOURCE=InheritedInterface.fs # InheritedInterface - SOURCE=ObjImplementsInterface.fs # ObjImplementsInterface.fs - SOURCE=interface001.fs # interface001.fs - SOURCE=interface002.fs # interface002.fs - SOURCE=interface001e.fs SCFLAGS="--test:ErrorRanges" # interface001e.fs - SOURCE=interface002e.fs # interface002e.fs - SOURCE=interface003.fs # interface003.fs + SOURCE=Inheritance_OverrideInterface.fs SCFLAGS="--test:ErrorRanges --langversion:5.0" # Inheritance_OverrideInterface.fs + SOURCE=InheritFromIComparable01.fs SCFLAGS=-a # InheritFromIComparable01.fs + SOURCE=E_InterfaceNotFullyImpl01.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl01.fs + SOURCE=E_InterfaceNotFullyImpl02.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl02.fs + SOURCE=E_InterfaceNotFullyImpl03.fs SCFLAGS="--test:ErrorRanges" # E_InterfaceNotFullyImpl03.fs - SOURCE=ConsumeFromCS.fs POSTCMD="\$CSC_PIPE -r:ConsumeFromCS.dll CallFSharpInterface.cs && CallFSharpInterface.exe" SCFLAGS=-a # ConsumeFromCS.fs -NoMT SOURCE=CallCSharpInterface.fs PRECMD="\$CSC_PIPE /t:library ConsumeFromFS.cs" SCFLAGS="-r:ConsumeFromFS.dll" # CallCSharpInterface.fs + SOURCE=InheritedInterface.fs # InheritedInterface + SOURCE=ObjImplementsInterface.fs # ObjImplementsInterface.fs + SOURCE=interface001.fs # interface001.fs + SOURCE=interface002.fs # interface002.fs + SOURCE=interface001e.fs SCFLAGS="--test:ErrorRanges" # interface001e.fs + SOURCE=interface002e.fs # interface002e.fs + SOURCE=interface003.fs # interface003.fs - SOURCE=E_MultipleInterfaceInheritance.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_MultipleInterfaceInheritance.fs + SOURCE=ConsumeFromCS.fs POSTCMD="\$CSC_PIPE -r:ConsumeFromCS.dll CallFSharpInterface.cs && CallFSharpInterface.exe" SCFLAGS=-a # ConsumeFromCS.fs +NoMT SOURCE=CallCSharpInterface.fs PRECMD="\$CSC_PIPE /t:library ConsumeFromFS.cs" SCFLAGS="-r:ConsumeFromFS.dll" # CallCSharpInterface.fs -NoMT SOURCE=ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll" # ConsumeMultipleInterfaceFromCS.fs -NoMT SOURCE=E_ConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ConsumeMultipleInterfaceFromCS.fs -NoMT SOURCE=E_ClassConsumeMultipleInterfaceFromCS.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges" # E_ClassConsumeMultipleInterfaceFromCS.fs + SOURCE=E_MultipleInterfaceInheritance.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_MultipleInterfaceInheritance.fs - SOURCE="E_ImplementGenIFaceTwice01.fs" # E_ImplementGenIFaceTwice01.fs - SOURCE="E_ImplementGenIFaceTwice02.fs" # E_ImplementGenIFaceTwice02.fs +NoMT SOURCE=E_ConsumeMultipleInterfaceFromCS.4.7.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:4.7" # E_ConsumeMultipleInterfaceFromCS.4.7.fs +NoMT SOURCE=ConsumeMultipleInterfaceFromCS.5.0.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --langversion:5.0" # ConsumeMultipleInterfaceFromCS.5.0.fs - SOURCE=EmptyInterface01.fs # EmptyInterface01.fs +NoMT SOURCE=E_ClassConsumeMultipleInterfaceFromCS.4.7.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:4.7" # E_ClassConsumeMultipleInterfaceFromCS.4.7.fs +NoMT SOURCE=ClassConsumeMultipleInterfaceFromCS.5.0.fs PRECMD="\$CSC_PIPE /t:library MultipleInterfaceInheritanceFromCS.cs" SCFLAGS="-r:MultipleInterfaceInheritanceFromCS.dll --test:ErrorRanges --langversion:5.0" # ClassConsumeMultipleInterfaceFromCS.5.0.fs + + SOURCE="E_ImplementGenIFaceTwice01_4.7.fs" SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_ImplementGenIFaceTwice01_4.7.fs + SOURCE="E_ImplementGenIFaceTwice01_5.0.fs" SCFLAGS="--test:ErrorRanges --langversion:5.0 --nowarn:221" # E_ImplementGenIFaceTwice01_5.0.fs + SOURCE="E_ImplementGenIFaceTwice02_4.7.fs" SCFLAGS="--test:ErrorRanges --langversion:4.7 --nowarn:221" # E_ImplementGenIFaceTwice02_4.7.fs + SOURCE="ImplementGenIFaceTwice02_5.0.fs" SCFLAGS="--test:ErrorRanges --langversion:5.0 --nowarn:221" # ImplementGenIFaceTwice02_5.0.fs + + SOURCE=EmptyInterface01.fs # EmptyInterface01.fs SOURCE=InheritDotNetInterface.fs # InheritDotNetInterface.fs SOURCE=E_AnonymousTypeInInterface01.fs SCFLAGS="--test:ErrorRanges" # E_AnonymousTypeInInterface01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/StructTypes/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/StructTypes/env.lst index ca8f40efaeb..434fa6a2931 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/StructTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/StructTypes/env.lst @@ -13,9 +13,6 @@ NoMT SOURCE=E_Overload_GetHashCode.fsx SCFLAGS="--test:ErrorRanges" FSIMODE=PIPE SOURCE=NoClashMemberIFaceMember.fs SCFLAGS=--warnaserror+ # NoClashMemberIFaceMember.fs - SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_Equals.fs - SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_GetHashCode.fs - SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror+ --nowarn:988" # Overload_ToString.fs NoMT SOURCE=Overload_Equals.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_Equals.fs - fsi NoMT SOURCE=Overload_GetHashCode.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_GetHashCode.fs - fsi NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMODE=PIPE # Overload_ToString.fs - fsi @@ -58,4 +55,4 @@ NoMT SOURCE=Overload_ToString.fs COMPILE_ONLY=1 SCFLAGS=--warnaserror+ FSIMOD SOURCE=E_InvalidRecursiveGeneric01.fs # E_InvalidRecursiveGeneric01.fs - SOURCE=E_InvalidRecursiveGeneric02.fs # E_InvalidRecursiveGeneric02.fs \ No newline at end of file + SOURCE=E_InvalidRecursiveGeneric02.fs # E_InvalidRecursiveGeneric02.fs diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/E_InvalidForwardRef01.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/E_InvalidForwardRef01.fs index 97636a4a522..bdbe89f20b1 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/E_InvalidForwardRef01.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/E_InvalidForwardRef01.fs @@ -2,7 +2,7 @@ #light // Regression test for FSHARP1.0:575 - Augmentations lead to unsoundnesses in the treatment of constraints. Availalbe instances should be lexically scoped -//The member '\( \+ \)' is used in an invalid way\. A use of '\( \+ \)' has been inferred prior to its definition.+ +//The member '\(\+\)' is used in an invalid way\. A use of '\(\+\)' has been inferred prior to its definition.+ type genmat = M of int let x = Unchecked.defaultof<_> // generate an inference variable diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/env.lst b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/env.lst index 6f56022cdb7..2c69e759506 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/basic/env.lst @@ -30,4 +30,4 @@ NOMONO SOURCE=E_ProtectedMemberInExtentionMember01.fs SCFLAGS="--test:ErrorRange # These tests have a dependency on NetFx3.5 (i.e. CSC_PIPE must be 3.5 or better) # For this reason, we exclude it from MT NoMT SOURCE=FSUsingExtendedTypes.fs SCFLAGS="--test:ErrorRanges -r:fslib.dll -r:CSLibExtendingFS.dll" PRECMD="\$CSC_PIPE /t:library /r:fslib.dll CSLibExtendingFS.cs" # FSUsingExtendedTypes.fs -NoMT SOURCE="GenericExtensions.fs" SCFLAGS="--reference:GenericExtensionsCSLib.dll" PRECMD="\$CSC_PIPE /r:\"%FSCOREDLLPATH%\" /t:library /reference:System.Core.dll GenericExtensionsCSLib.cs" # GenericExtensions.fs \ No newline at end of file +NoMT SOURCE="GenericExtensions.fs" SCFLAGS="--reference:GenericExtensionsCSLib.dll" PRECMD="\$CSC_PIPE /r:\"%FSCOREDLLPATH%\" /t:library /reference:System.Core.dll /reference:netstandard.dll GenericExtensionsCSLib.cs" # GenericExtensions.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_typeext_opt005.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_typeext_opt005.fs index 4f9afc41f42..6f15a839266 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_typeext_opt005.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeExtensions/optional/E_typeext_opt005.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #ObjectOrientedTypes #TypeExtensions // Error when trying to use member overloading when some overloads are specified using curried arguments -//One or more of the overloads of this method has curried arguments\. Consider redesigning these members to take arguments in tupled form -//One or more of the overloads of this method has curried arguments\. Consider redesigning these members to take arguments in tupled form +//One or more of the overloads of this method has curried arguments\. Consider redesigning these members to take arguments in tupled form +//One or more of the overloads of this method has curried arguments\. Consider redesigning these members to take arguments in tupled form namespace NS module M = diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface003e.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface003e.fs index 3d8a7a4b907..7240d11d5fa 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface003e.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface003e.fs @@ -2,9 +2,9 @@ // attribute must match inferred type -//No implementation was given for 'abstract member TK_I_005\.M : unit -> unit'$ +//No implementation was given for 'abstract TK_I_005\.M: unit -> unit'$ //This type is 'abstract' since some abstract members have not been given an implementation\. If this is intentional then add the '\[\]' attribute to your type\.$ -//No implementation was given for 'abstract member TK_C_000\.M : int -> int'$ +//No implementation was given for 'abstract TK_C_000\.M: int -> int'$ //This type is 'abstract' since some abstract members have not been given an implementation\. If this is intentional then add the '\[\]' attribute to your type\.$ [] diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Array/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Array/env.lst index 0cd9da0f029..af0497ed76f 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Array/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Array/env.lst @@ -2,4 +2,4 @@ SOURCE="arrayMatch02.fs" # ArrayMatch02 SOURCE="arrayMatch03.fs" # ArrayMatch03 - SOURCE="TrailingSemi01.fs" # TrailingSemi01 \ No newline at end of file + SOURCE="TrailingSemi01.fs" # TrailingSemi01 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/As/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/As/env.lst index baff7b5d77f..3e158fa9c48 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/As/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/As/env.lst @@ -1,2 +1,2 @@ SOURCE="asPattern01.fs" # AsPattern01 - SOURCE="asPattern02.fs" # AsPattern02 \ No newline at end of file + SOURCE="asPattern02.fs" # AsPattern02 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/ConsList/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/ConsList/env.lst index ce53e422a11..a5920b6ae4f 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/ConsList/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/ConsList/env.lst @@ -3,4 +3,4 @@ SOURCE=E_consPattern01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_consPattern01.fs SOURCE=E_consOnNonList.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_consOnNonList.fs - SOURCE=OutsideMatch01.fs # OutsideMatch01.fs \ No newline at end of file + SOURCE=OutsideMatch01.fs # OutsideMatch01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/DynamicTypeTest/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/DynamicTypeTest/env.lst index c2e157ddaae..b16bb25ba59 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/DynamicTypeTest/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/DynamicTypeTest/env.lst @@ -16,4 +16,4 @@ SOURCE=E_DynamTyTestVarType01.fs # E_DynamTyTestVarType01.fs SOURCE=Regression01.fs # Regression01.fs - SOURCE=TwoAtOnce01.fs # TwoAtOnce01.fs \ No newline at end of file + SOURCE=TwoAtOnce01.fs # TwoAtOnce01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Expression/NoCounterExampleTryWith01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Expression/NoCounterExampleTryWith01.fs index 46fa8b2950b..920200ca911 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Expression/NoCounterExampleTryWith01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Expression/NoCounterExampleTryWith01.fs @@ -5,7 +5,7 @@ module M -// Unterminated try-catch +// Unterminated try-with let h1 = try () @@ -13,7 +13,7 @@ let h1 = with | :? System.NotFiniteNumberException -> () -// Unterminated try-catch in a computation expr +// Unterminated try-with in a computation expr let a = async { try diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns01.fs index c2cb3823771..19bf8faee6c 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns01.fs @@ -1,12 +1,13 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Verify error if Active Patterns do not start with an upper case letter -//Active pattern case identifiers must begin with an uppercase letter -//Active pattern case identifiers must begin with an uppercase letter //Active pattern case identifiers must begin with an uppercase letter -//Active pattern case identifiers must begin with an uppercase letter -//Active pattern case identifiers must begin with an uppercase letter -//The '\|' character is not permitted in active pattern case identifiers -//The '\|' character is not permitted in active pattern case identifiers +//Active pattern case identifiers must begin with an uppercase letter +//Active pattern case identifiers must begin with an uppercase letter +//Active pattern case identifiers must begin with an uppercase letter +//Active pattern case identifiers must begin with an uppercase letter +//The '\|' character is not permitted in active pattern case identifiers +//The '\|' character is not permitted in active pattern case identifiers +//Active pattern case identifiers must begin with an uppercase letter let (|positive|negative|) n = if n < 0 then positive else negative let (|`` A``|) (x:int) = x @@ -14,5 +15,6 @@ let (|B1|``+B2``|) (x:int) = if x = 0 then OneA else ``+B2`` let (|`` C``|_|) (x:int) = if x = 0 then Some(x) else None let (|``D|E``|F|) (x:int) = if x = 0 then D elif x = 1 then E else F let (|G|``H||I``|) (x:int) = if x = 0 then G elif x = 1 then H else ``|I`` +let (|_J|) (x:int) = _J exit 1 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec01.fs index ad44bfc85ba..7269796810b 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' +//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' let rec (|Foo|Bar|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec02.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec02.fs index 1e2d83477a8..c135beefc1a 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec02.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec02.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let rec (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec03.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec03.fs index dcae474e228..e39c8fb59bd 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec03.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec03.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let rec (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec04.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec04.fs index 25a7343ffd5..5ed84d6a36e 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec04.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_LetRec04.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. ''a option' .but here has type. 'string' +//This expression was expected to have type. ''a option' .but here has type. 'string' let rec (|Foo3|_|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam01.fs index e8f77849d35..25f75485341 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam01.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' +//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' let (|Foo|Bar|) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam02.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam02.fs index 6d310e4e9f8..1ed1e40e379 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam02.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam02.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let (|Foo2|Bar2|_|) x = "BAD DOG!" // expect: invalid name for an active pattern diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam03.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam03.fs index 3791cfb83eb..4387147760d 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam03.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam03.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let (|Foo2b|Bar2b|Baz2b|_|) x = "BAD DOG!" // expect: type string doesn't match type 'choice' diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam04.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam04.fs index b164c604c20..0553d6f6892 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam04.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_NonParam04.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. ''a option' .but here has type. 'string' +//This expression was expected to have type. ''a option' .but here has type. 'string' let (|Foo3|_|) x = "BAD DOG!" // expect: type string doesn't match type 'option' diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param01.fs index d1fd1f3e712..067d07a46aa 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param01.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' +//This expression was expected to have type. 'Choice<'a,'b>' .but here has type. 'string' let (|Foo|Bar|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param02.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param02.fs index 36985891c50..74ced64a2ed 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param02.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param02.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let (|Foo2|Bar2|_|) (a:int) x = "BAD DOG!" // expect: invalid name for an active pattern diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param03.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param03.fs index 25bf8af83dc..372bde3ce8c 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param03.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param03.fs @@ -1,4 +1,4 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This is not a valid name for an active pattern +//This is not a valid name for an active pattern let (|Foo2b|Bar2b|Baz2b|_|) (a:int) x = "BAD DOG!" // expect: type string doesn't match type 'choice' diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param04.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param04.fs index 02a9fd6ba01..4467425d462 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param04.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_Error_Param04.fs @@ -1,5 +1,5 @@ // #Regression #Conformance #PatternMatching #ActivePatterns // Regression test for FSHARP1.0:4621 -//This expression was expected to have type. ''a option' .but here has type. 'string' +//This expression was expected to have type. ''a option' .but here has type. 'string' let (|Foo3|_|) (a:int) x = "BAD DOG!" diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_patternMatchRegressions02.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_PatternMatchRegressions02.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_patternMatchRegressions02.fs rename to tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_PatternMatchRegressions02.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/namedLiteral01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/NamedLiteral01.fs similarity index 100% rename from tests/fsharpqa/Source/Conformance/PatternMatching/Named/namedLiteral01.fs rename to tests/fsharpqa/Source/Conformance/PatternMatching/Named/NamedLiteral01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/discUnion01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/discUnion01.fs index 89832cc9100..c1a896978cb 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/discUnion01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/discUnion01.fs @@ -6,17 +6,17 @@ type Foo = | A of int | B of string * int - + let test x = match x with | A(1) | B(_,1) -> 1 | A(2) | B(_,2) -> 2 | B(_, _) -> -1 | A(_) -> -2 - + if test (A(1)) <> 1 then exit 1 if test (B("",1)) <> 1 then exit 1 - + if test (A(2)) <> 2 then exit 1 if test (B("",2)) <> 2 then exit 1 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst index f88ce34f50b..7c5f143e98e 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst @@ -49,4 +49,4 @@ SOURCE=E_ActivePatternNotAFuncion.fs SCFLAGS=--test:ErrorRanges # E_ActivePatternNotAFuncion.fs SOURCE=E_LargeActivePat01.fs # E_LargeActivePat01.fs - SOURCE=ParamertizedPartialActivePattern01.fs # ParamertizedPartialActivePattern01.fs \ No newline at end of file + SOURCE=ParamertizedPartialActivePattern01.fs # ParamertizedPartialActivePattern01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Null/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Null/env.lst index 861c42c446b..24c524049e1 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Null/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Null/env.lst @@ -1,3 +1,3 @@ SOURCE=matchNull01.fs # MatchNull01.fs - SOURCE=E_notNullCompatible01.fs # E_notNullCompatible01.fs \ No newline at end of file + SOURCE=E_notNullCompatible01.fs # E_notNullCompatible01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Record/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Record/env.lst index 36e0494dd25..34a172bf716 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Record/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Record/env.lst @@ -6,4 +6,4 @@ SOURCE=E_SyntaxError01.fs # E_SyntaxError01.fs SOURCE=E_RecordFieldNotDefined01.fs # E_RecordFieldNotDefined01.fs - SOURCE=E_RecTypesNotMatch01.fs # E_RecTypesNotMatch01.fs \ No newline at end of file + SOURCE=E_RecTypesNotMatch01.fs # E_RecTypesNotMatch01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs deleted file mode 100644 index 48f95c5ef28..00000000000 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/W_BindCaptialIdent.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Conformance #PatternMatching -// Verify warning when capturing values with captial identifier -// FSB 3954 - -//Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name -//Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name - -let test x = function - | Foo :: [] -> 1 - | Bar :: _ :: [] -> 2 - | _ -> 3 diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/env.lst index ab4e02d45ae..7a8347b35e2 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Simple/env.lst @@ -1,10 +1,7 @@ SOURCE=E_constPattern01.fs # E_constPattern01.fs SOURCE=E_namedLiberal01.fs # E_namedLiberal01.fs - SOURCE=W_Incomplete01.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_Incomplete01.fs - SOURCE=W_Incomplete02.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_Incomplete02.fs SOURCE=E_SyntaxError01.fs # E_SyntaxError01.fs - SOURCE=W_BindCaptialIdent.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # W_BindCaptialIdent.fs SOURCE=CodeGenReg01.fs # CodeGenReg01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Tuple/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Tuple/env.lst index b8b44cb2ab8..1aa69ff867a 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Tuple/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Tuple/env.lst @@ -4,4 +4,4 @@ SOURCE=W_RedundantPattern01.fs # W_RedundantPattern01.fs SOURCE=W_RedundantPattern02.fs # W_RedundantPattern02.fs - SOURCE=E_TupleMismatch01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_TupleMismatch01.fs \ No newline at end of file + SOURCE=E_TupleMismatch01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_TupleMismatch01.fs diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeAnnotated/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeAnnotated/env.lst index bc63beba4a2..1bb8bf6d7fd 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeAnnotated/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeAnnotated/env.lst @@ -1 +1 @@ -# empty \ No newline at end of file +# empty diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs index b43a8a2927d..4ce19c52666 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/TypeConstraint/E_typecontraint01.fs @@ -2,8 +2,9 @@ // Regression test for FSHARP1.0:1525 // type constraints on pattern matching are deprecated and are now errors (used to be warnings) // As of Beta2, we are not even giving the deprecation error. -//Unexpected symbol ':>' in pattern$ -//Unmatched '\('$ +//Unexpected symbol ':>' in pattern. Expected '\)' or other token. +//Unmatched '\('$ +//Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. type A() = class end diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Union/E_UnionCapturesDiffType01.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Union/E_UnionCapturesDiffType01.fs index b96c7a37045..def92d6297b 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Union/E_UnionCapturesDiffType01.fs +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Union/E_UnionCapturesDiffType01.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #PatternMatching #Unions // Verify error if two union rules capture values with different types -//This expression was expected to have type. 'int' .but here has type. 'float' +//This expression was expected to have type. 'int' .but here has type. 'float' let testMatch x = match x with diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Wildcard/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Wildcard/env.lst index 425c9daa41d..7b32de49ca7 100644 --- a/tests/fsharpqa/Source/Conformance/PatternMatching/Wildcard/env.lst +++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Wildcard/env.lst @@ -1 +1 @@ - SOURCE=wildCardPatterns01.fs # wildCardPatterns01.fs \ No newline at end of file + SOURCE=wildCardPatterns01.fs # wildCardPatterns01.fs diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructConstructor01.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructConstructor01.fsi index 991c81ee5b4..fb4fe9384a6 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructConstructor01.fsi +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructConstructor01.fsi @@ -1,6 +1,6 @@ // #Conformance #Signatures #Structs #Regression // Regression for Dev11:137930, structs used to not give errors on unimplemented constructors in the signature file -//Module 'M' requires a value 'new : unit -> Foo<'T>' +//Module 'M' requires a value 'new: unit -> Foo<'T>' module M diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict01.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict01.fsi index f39854e2e1b..b784cb1e69d 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict01.fsi +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict01.fsi @@ -1,6 +1,6 @@ // #Conformance #Signatures #Structs #Regression // Regression for Dev11:137942, structs used to not give errors on when member names conflicted with interface members -//Module 'M' contains. override Foo\.GetEnumerator : unit -> IEnumerator<'T> .but its signature specifies. member Foo\.GetEnumerator : unit -> IEnumerator<'T> .The compiled names differ +//Module 'M' contains. override Foo\.GetEnumerator: unit -> IEnumerator<'T> .but its signature specifies. member Foo\.GetEnumerator: unit -> IEnumerator<'T> .The compiled names differ //The field, constructor or member 'GetEnumerator' is not defined$ module M diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi index 76a9a314b53..f94ece27d76 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi @@ -1,6 +1,6 @@ // #Conformance #Signatures #Structs #Regression // Regression for Dev11:137942, structs used to not give errors on when member names conflicted with interface members -//The field, constructor or member 'GetEnumerator' is not defined +//The type 'Foo<_>' does not define the field, constructor or member 'GetEnumerator' //Module 'M' contains override Foo\.GetEnumerator : unit -> IEnumerator<'T> but its signature specifies member Foo\.GetEnumerator : unit -> IEnumerator<'T> The compiled names differ module M diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fs b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fs index 30a1ac473fd..e1e7c4e31ef 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fs +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #SignatureFiles // Regression for 5618 // Used to get a bad error message here, LSS doesn't implement member Bar with is in the .fsi but also on another type -//Module 'MyNS\.File2' requires a value 'member File2\.LSS\.Bar : string -> int'$ +//Module 'MyNS\.File2' requires a value 'member File2\.LSS\.Bar: string -> int'$ namespace MyNS module File2 = diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fsi index 9a1d2a61eea..7ac32f02f2e 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fsi +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/MissingMethodInImplementation01.fsi @@ -1,7 +1,7 @@ // #Regression #Conformance #SignatureFiles // Regression for 5618 // Used to get a bad error message here, LSS doesn't implement member Bar with is in the .fsi but also on another type -//Module 'MyNS\.File2' requires a value 'member File2\.LSS\.Bar : string -> int'$ +//Module 'MyNS\.File2' requires a value 'member File2\.LSS\.Bar: string -> int'$ namespace MyNS diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/env.lst b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/env.lst index 5fe2a190c21..8a19b629153 100644 --- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/env.lst +++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/env.lst @@ -7,4 +7,4 @@ SOURCE="AttributeMatching01.fsi AttributeMatching01.fs" SCFLAGS="--test:ErrorRanges --warnaserror" # AttributeMatching01.fs SOURCE="E_StructConstructor01.fsi E_StructConstructor01.fs" SCFLAGS="--test:ErrorRanges" # E_StructConstructor01.fs SOURCE="E_StructWithNameConflict01.fsi E_StructWithNameConflict01.fs" SCFLAGS="--test:ErrorRanges --flaterrors" # E_StructWithNameConflict01.fs - SOURCE="E_StructWithNameConflict02.fsi E_StructWithNameConflict02.fs" SCFLAGS="--test:ErrorRanges --flaterrors" # E_StructWithNameConflict02.fs \ No newline at end of file + SOURCE="E_StructWithNameConflict02.fsi E_StructWithNameConflict02.fs" SCFLAGS="--test:ErrorRanges --flaterrors" # E_StructWithNameConflict02.fs diff --git a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs index fab0d7f9e46..60f29755a2a 100644 --- a/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs +++ b/tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #Attributes // Regression test for FSHARP1.0:4226 // We want to make sure the warning emits the correct suggestion (val and mutable were swapped) -//Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable : ' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$ +//Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable : ' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$ module M module Foo = [] diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/ByRef04.fsx b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/ByRef04.fsx index 1cac208d4d6..99363967af9 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/ByRef04.fsx +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/ByRef04.fsx @@ -1,9 +1,9 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//val inline f : -// x:string -> y:nativeptr< \^a> -> bool -// when \^a : unmanaged and -// \^a : \(static member TryParse : string \* nativeptr< \^a> -> bool\) +//val inline f: +// x: string -> y: nativeptr< \^a> -> bool +// when \^a: unmanaged and +// \^a: \(static member TryParse: string \* nativeptr< \^a> -> bool\) // Should compile just fine let inline f x (y:_ nativeptr) = (^a : (static member TryParse : string * ^a nativeptr -> bool)(x,y)) diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/env.lst b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/env.lst index 1c7f13eeeba..03ea5d45f5b 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/env.lst @@ -41,8 +41,6 @@ NoMT SOURCE=ByRef04.fsx FSIMODE=PIPE COMPILE_ONLY=1 # ByRef04.fsx SOURCE=E_EqualityConstraint01.fs SCFLAGS="--test:ErrorRanges" # E_EqualityConstraint01.fs SOURCE=E_ComparisonConstraint01.fs SCFLAGS="--test:ErrorRanges" # E_ComparisonConstraint01.fs SOURCE=ComparisonConstraint01.fs # ComparisonConstraint01.fs - SOURCE=E_CannotInlineVirtualMethods1.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_CannotInlineVirtualMethods1.fs - SOURCE=E_CannotInlineVirtualMethod2.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 # E_CannotInlineVirtualMethod2.fs x SOURCE=NativePtrArrayElementUsage.fs SCFLAGS="--test:ErrorRanges" COMPILE_ONLY=1 PEVER=/MD # NativePtrArrayElementUsage.fs SOURCE=ExplicitMemberConstraints1.fs # ExplicitMemberConstraints1.fs SOURCE=ExplicitMemberConstraints2.fs # ExplicitMemberConstraints2.fs @@ -53,4 +51,4 @@ x SOURCE=NativePtrArrayElementUsage.fs SCFLAGS="--test:ErrorRanges" COMPILE_O SOURCE=E_ConstraintCall1.fs # E_ConstraintCall1.fs SOURCE=E_ConstraintCall2.fs # E_ConstraintCall2.fs SOURCE=StructConstraint01.fs # StructConstraint01.fs - SOURCE=StructConstraint02.fs # StructConstraint02.fs \ No newline at end of file + SOURCE=StructConstraint02.fs # StructConstraint02.fs diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullAsRepresentationValue.fsx b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullAsRepresentationValue.fsx index 656e442419a..5e1731a3a93 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullAsRepresentationValue.fsx +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/TypeWithNullAsRepresentationValue.fsx @@ -16,10 +16,13 @@ type DU = | NULL let du = NULL +printfn "%A" u +printfn "%A" o +printfn "%A" du let test = [ - (sprintf "%A" u) = ""; - (sprintf "%A" o) = ""; - (sprintf "%A" du) = ""; + (sprintf "%A" u) = "()"; + (sprintf "%A" o) = "None"; + (sprintf "%A" du) = "NULL"; ] |> List.forall (fun e -> e=true) (if test then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/env.lst b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/env.lst index 700b014da49..0c8930e3ce8 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/env.lst +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/LogicalPropertiesOfTypes/env.lst @@ -4,7 +4,6 @@ SOURCE=TypeWithNullAsRepresentationValue.fsx # TypeWithNullAsRepresentationValue.fsx SOURCE=E_TypeWithNullAsRepresentationValue.fsx SCFLAGS="--test:ErrorRanges" # E_TypeWithNullAsRepresentationValue.fsx - SOURCE=TypeWithNullLiteral_NetRef.fsx COMPILE_ONLY=1 SCFLAGS="-a" # TypeWithNullLiteral_NetRef.fsx SOURCE=E_TypeWithNullLiteral_NetVal.fsx SCFLAGS="--test:ErrorRanges" # E_TypeWithNullLiteral_NetVal.fsx SOURCE=GenericTypeDef.fs # GenericTypeDef.fs diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeConstraints/env.lst b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeConstraints/env.lst index c1cfdf4b4c4..8db82fbbbad 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeConstraints/env.lst +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeConstraints/env.lst @@ -1,2 +1,2 @@ SOURCE=E_ConstructorConstraint01.fs # E_ConstructorConstraint01.fs - SOURCE=Constraints01.fs # Constraints01.fs \ No newline at end of file + SOURCE=Constraints01.fs # Constraints01.fs diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/HashConstraint02.fs b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/HashConstraint02.fs index 24f94f08d3e..fe215d60f9e 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/HashConstraint02.fs +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/HashConstraint02.fs @@ -1,8 +1,7 @@ // #Regression #Conformance #TypeConstraints // Regression test for FSHARP1.0:1419 // Tokens beginning with # should not match greedily with directives -// The only case where we are still a bit confused is #light: for this reason the code -// below compiles just fine (it would not work if I replace #light with #r for example) +//The type 'float' is not compatible with the type 'light_' #light type light_() = class diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/env.lst index 63da9ec715d..378c1aa2247 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Basic/env.lst @@ -7,18 +7,12 @@ SOURCE=Ints01.fs # Ints01.fs - SOURCE=Misc01.fs COMPILE_ONLY=1 # Misc01.fs SOURCE=Misc02.fs # Misc02.fs - SOURCE=Misc03.fs COMPILE_ONLY=1 # Misc03.fs SOURCE=Misc04.fs # Misc04.fs - SOURCE=Stats.fs COMPILE_ONLY=1 # Stats.fs - SOURCE=SI.fs COMPILE_ONLY=1 # SI.fs - SOURCE=RationalExponents01.fs COMPILE_ONLY=1 # RationalExponents01.fs - SOURCE=Quotation04_hidden.fs COMPILE_ONLY=1 # Quotation04_hidden.fs SOURCE=DynamicTypeTest.fs # DynamicTypeTest.fs SOURCE=OnDecimals01.fs # OnDecimals01.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Bounds/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Bounds/env.lst index 60100662c9c..ea51d725c9e 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Bounds/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Bounds/env.lst @@ -1,2 +1,2 @@ SOURCE=infinity_01.fs SCFLAGS="--test:ErrorRanges" # infinity_01.fs - SOURCE=nan_01.fs SCFLAGS="--test:ErrorRanges" # nan_01.fs \ No newline at end of file + SOURCE=nan_01.fs SCFLAGS="--test:ErrorRanges" # nan_01.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Constants/E_UnsupportedTypes01.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Constants/E_UnsupportedTypes01.fs index 25d9a0c1ac7..47eef066ae0 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Constants/E_UnsupportedTypes01.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Constants/E_UnsupportedTypes01.fs @@ -2,11 +2,8 @@ // Constants with measures // unsupported types // Loosely related to regression tests for FSHARP1.0:2918 -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types +//Units-of-measure are only supported on float, float32, decimal, and integer types. +//Units-of-measure are only supported on float, float32, decimal, and integer types. module M [] type kg @@ -24,6 +21,3 @@ let _ = 4L // Err let _ = 4I let _ = 4N -let _ = 4UL -let _ = 4u -let _ = 4us diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/E_UnsupportedType01.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/E_UnsupportedType01.fs index f79ae83f076..fcda0d5bd7c 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/E_UnsupportedType01.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/E_UnsupportedType01.fs @@ -1,21 +1,9 @@ // #Regression #Conformance #UnitsOfMeasure #Diagnostics // Regression test for FSHARP1.0:2345 -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types -//Units-of-measure supported only on float, float32, decimal and signed integer types +//Units-of-measure are only supported on float, float32, decimal, and integer types. [] type Kg let x = 1 // ok -let a = 1ul // unsigned int64 -let b = 1u // unsigned int=int32 -let c = 1us // unsigned int16 -let d = 1uy // unsigned int8 - - - - - - +let a = 1I // BigInt diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/W_NonGenVarInValueRestrictionWarning.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/W_NonGenVarInValueRestrictionWarning.fs index 671316e2316..12ca2be2ce8 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/W_NonGenVarInValueRestrictionWarning.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/W_NonGenVarInValueRestrictionWarning.fs @@ -1,7 +1,7 @@ // #Regression #Conformance #UnitsOfMeasure #Diagnostics // Regression test for FSHARP1.0:4969 // Non-generalized unit-of-measure variables should display with "_" in value restriction warning -//.+val x : float<'_u> list ref -//.+val y : '_a list ref +//.+val x: float<'_u> list ref +//.+val y: '_a list ref let x = ref ([] : float<_> list) let y = ref ([] : _ list) diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/env.lst index 10f38bbc83b..8b92be2e707 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Diagnostics/env.lst @@ -1,5 +1,4 @@ SOURCE=E_RangeExpression01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_RangeExpression01.fs - SOURCE=RangeExpression01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # RangeExpression01.fs SOURCE=W_NonGenVarInValueRestrictionWarning.fs SCFLAGS="--test:ErrorRanges --flaterrors" # W_NonGenVarInValueRestrictionWarning.fs SOURCE=E_CantBeUsedAsPrefixArgToAType01.fsx SCFLAGS="--test:ErrorRanges" # E_CantBeUsedAsPrefixArgToAType01.fsx @@ -27,4 +26,4 @@ SOURCE=E_UnsupportedType01.fs SCFLAGS="--test:ErrorRanges" # E_UnsupportedType01.fs SOURCE=E_RangeOfDecimals01.fs SCFLAGS="--test:ErrorRanges" # E_RangeOfDecimals01.fs - SOURCE=IntTypes01.fs SCFLAGS="--test:ErrorRanges -a" # IntTypes01.fs \ No newline at end of file + SOURCE=IntTypes01.fs SCFLAGS="--test:ErrorRanges -a" # IntTypes01.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/env.lst index 1db2cfa22bb..fcc63fee947 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/Parsing/env.lst @@ -1,8 +1,3 @@ - SOURCE=GreaterBarRBrack01.fs COMPILE_ONLY=1 # GreaterBarRBrack01.fs - SOURCE=Reciprocal01.fs COMPILE_ONLY=1 # Reciprocal01.fs - SOURCE=QuotientAssoc.fs COMPILE_ONLY=1 # QuotientAssoc.fs - SOURCE=Quotient.fs COMPILE_ONLY=1 # Quotient.fs - SOURCE=PowerSynonym.fs COMPILE_ONLY=1 # PowerSynonym.fs SOURCE=KnownTypeAsUnit01.fs SCFLAGS="--test:ErrorRanges" # KnownTypeAsUnit01.fs SOURCE=KnownTypeAsUnit01b.fs SCFLAGS="--test:ErrorRanges" # KnownTypeAsUnit01b.fs SOURCE=E_Nesting01.fs SCFLAGS="--test:ErrorRanges" # E_Nesting01.fs.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs index b948171d4d1..485d8a2f5e9 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/E_GenInterfaceWithDifferentGenInstantiations.fs @@ -1,13 +1,13 @@ // #Regression #Conformance #UnitsOfMeasure #TypeInference #TypeConstraints // Regression test for FSHARP1.0:4782 // It is illegal to implement or inherit the same interface at different generic instantiations -//This type implements the same interface at different generic instantiations 'IA' and 'IA<'b>'\. This is not permitted in this version of F# +//'IB<'b>' cannot implement the interface 'IA<_>' with the two instantiations 'IA' and 'IA<'b>' because they may unify. [] type kg type IA<[] 'b> = interface - abstract Foo : float <'b> -> int + abstract Foo : float<'b> -> int end type IB<[] 'b> = diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/W_LessGeneric01.fsx b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/W_LessGeneric01.fsx index a0e07fc02dd..93a352702da 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/W_LessGeneric01.fsx +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/W_LessGeneric01.fsx @@ -5,8 +5,8 @@ // let fn \(x:float<'u>\) = // ----------------\^\^ //This construct causes code to be less generic than indicated by the type annotations\. The unit-of-measure variable 'u has been constrained to be measure '1'\.$ -//val loop : f:\('a -> 'a\) -> init:'a -> comp:\('a -> 'a -> bool\) -> 'a -//val fn : x:float -> float +//val loop: f: \('a -> 'a\) -> init: 'a -> comp: \('a -> 'a -> bool\) -> 'a +//val fn: x: float -> float let rec loop f init comp = let next = f init diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst index d93fddc74b6..d04c05dff72 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/TypeChecker/env.lst @@ -1,11 +1,10 @@ - SOURCE=GenericSubType01.fs COMPILE_ONLY=1 # GenericSubType01.fs SOURCE=Slash_InFunction01.fs SCFLAGS=--warnaserror+ # Slash_InFunction01.fs SOURCE=Slash_InMethod01.fs SCFLAGS=--warnaserror+ # Slash_InMethod01.fs SOURCE=Generalization01.fs SCFLAGS=--warnaserror # Generalization01.fs - SOURCE=E_GenInterfaceWithDifferentGenInstantiations.fs SCFLAGS="--test:ErrorRanges" # E_GenInterfaceWithDifferentGenInstantiations.fs + SOURCE=E_GenInterfaceWithDifferentGenInstantiations.fs SCFLAGS="--test:ErrorRanges --langversion:5.0" # E_GenInterfaceWithDifferentGenInstantiations.fs SOURCE=TypeAbbreviation_decimal_01.fs # TypeAbbreviation_decimal_01.fs SOURCE=TypeAbbreviation_float32_01.fs # TypeAbbreviation_float32_01.fs diff --git a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/WithOOP/E_Polymorphism01.fsx b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/WithOOP/E_Polymorphism01.fsx index 622077860ae..961af529c02 100644 --- a/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/WithOOP/E_Polymorphism01.fsx +++ b/tests/fsharpqa/Source/Conformance/UnitsOfMeasure/WithOOP/E_Polymorphism01.fsx @@ -1,7 +1,7 @@ // #Regression #Conformance #UnitsOfMeasure #ObjectOrientedTypes #ReqNOMT //interface Unit -//No implementation was given for 'abstract member Unit\.Factor : unit -> float'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' +//No implementation was given for 'abstract Unit\.Factor: unit -> float'\. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e\.g\. 'interface \.\.\. with member \.\.\.' [] type length diff --git a/tests/fsharpqa/Source/Diagnostics/General/e_big_int01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_Big_int01.fs similarity index 100% rename from tests/fsharpqa/Source/Diagnostics/General/e_big_int01.fs rename to tests/fsharpqa/Source/Diagnostics/General/E_Big_int01.fs diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_MemberObjectctorTakeGiven.fs b/tests/fsharpqa/Source/Diagnostics/General/E_MemberObjectctorTakeGiven.fs index 0b896f194d4..fc095c9a225 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_MemberObjectctorTakeGiven.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_MemberObjectctorTakeGiven.fs @@ -4,9 +4,9 @@ // bad error message: The member or object constructor 'Random' takes 1 arguments but is here supplied with 1. // // Now we should diplay: -// The member or object constructor 'Random' takes 0 type argument(s) but is here given 1. The required signature is 'static member Variable.Random : y:Variable<'a> -> Variable<'a>'. E:\dd\fsharp_1\src\qa\md\src\fsh\Compiler\fsharp\Source\Conformance\DeclarationElements\ObjectConstructors\E-ImplicitExplicitCTors.fs +// The member or object constructor 'Random' takes 0 type argument(s) but is here given 1. The required signature is 'static member Variable.Random: y: Variable<'a> -> Variable<'a>'. E:\dd\fsharp_1\src\qa\md\src\fsh\Compiler\fsharp\Source\Conformance\DeclarationElements\ObjectConstructors\E-ImplicitExplicitCTors.fs // -//The member or object constructor 'Random' takes 0 type argument\(s\) but is here given 1\. The required signature is 'static member Variable\.Random : y:Variable<'a> -> Variable<'a>' +//The member or object constructor 'Random' takes 0 type argument\(s\) but is here given 1\. The required signature is 'static member Variable\.Random: y: Variable<'a> -> Variable<'a>' #light diff --git a/tests/fsharpqa/Source/Diagnostics/General/e_ocamlcompatibility01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_OCamlCompatibility01.fs similarity index 100% rename from tests/fsharpqa/Source/Diagnostics/General/e_ocamlcompatibility01.fs rename to tests/fsharpqa/Source/Diagnostics/General/E_OCamlCompatibility01.fs diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_SpanExtendsToNextToken01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_SpanExtendsToNextToken01.fs index c12c0836205..28246eb1965 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_SpanExtendsToNextToken01.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_SpanExtendsToNextToken01.fs @@ -13,4 +13,4 @@ namespace N2 // Regression test for FSHARP1.0:4995 // Note that what we are really testing in this case is the span (which was incorrectly (3,1-7-10)) -//Namespaces cannot contain values\. Consider using a module to hold your value declarations\.$ +//Namespaces cannot contain values\. Consider using a module to hold your value declarations\.$ diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_ThisValueIsNotAFunctionAndCannotBeApplied01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_ThisValueIsNotAFunctionAndCannotBeApplied01.fs deleted file mode 100644 index cf15f433544..00000000000 --- a/tests/fsharpqa/Source/Diagnostics/General/E_ThisValueIsNotAFunctionAndCannotBeApplied01.fs +++ /dev/null @@ -1,7 +0,0 @@ -// #Regression #Diagnostics -// Regression test for FSHARP1.0:1406 -// - - - -let foo (arr : int[,]) = arr[1,2] diff --git a/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs b/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs index 67024e490cc..cd83283d263 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/E_UnexpectedSymbol01.fs @@ -1,7 +1,7 @@ // #Regression #Diagnostics // Regression test for FSHARP1.0:2099 // Regression test for FSHARP1.0:2670 -//Unexpected symbol '<-' in pattern +//Unexpected symbol '<-' in binding. Expected '=' or other token. //The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result. //lambda diff --git a/tests/fsharpqa/Source/Diagnostics/General/W_LowercaseLiteralNotIgnored.fs b/tests/fsharpqa/Source/Diagnostics/General/W_LowercaseLiteralNotIgnored.fs index 6e45e9cff04..7e77c8228be 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/W_LowercaseLiteralNotIgnored.fs +++ b/tests/fsharpqa/Source/Diagnostics/General/W_LowercaseLiteralNotIgnored.fs @@ -1,5 +1,5 @@ // #Regression #Diagnostics -//This rule will never be matched$ +//This rule will never be matched$ module M0 module m1 = diff --git a/tests/fsharpqa/Source/Diagnostics/General/env.lst b/tests/fsharpqa/Source/Diagnostics/General/env.lst index 7e4126f622e..d77d0099a55 100644 --- a/tests/fsharpqa/Source/Diagnostics/General/env.lst +++ b/tests/fsharpqa/Source/Diagnostics/General/env.lst @@ -82,15 +82,12 @@ SOURCE="E_MissingSourceFile03.fs \\\\qwerty\\y\\doesnotexist.fs" # E_MissingSourceFile03.fs NoMT SOURCE=E_MissingSourceFile04.fs SCFLAGS="--exec doesnotexist.fs" FSIMODE=PIPE # E_MissingSourceFile04.fs - SOURCE=W_Keyword_tailcall01.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # W_Keyword_tailcall01.fs SOURCE=E_OCamlStylePolymorficRecordFields01.fs SCFLAGS="--test:ErrorRanges" # E_OCamlStylePolymorficRecordFields01.fs SOURCE=E_IncompleteConstruct01.fs # E_IncompleteConstruct01.fs SOURCE=E_IncompleteConstruct01b.fs # E_IncompleteConstruct01b.fs - SOURCE=E_ThisValueIsNotAFunctionAndCannotBeApplied01.fs SCFLAGS="--test:ErrorRanges" # E_ThisValueIsNotAFunctionAndCannotBeApplied01.fs - SOURCE=E_UnexpectedKeyworkWith01.fs SCFLAGS="--test:ErrorRanges" # E_UnexpectedKeyworkWith01.fs SOURCE=E_MemberObjectctorTakeGiven.fs # E_MemberObjectctorTakeGiven.fs SOURCE=E_StructMustHaveAtLeastOneField.fs SCFLAGS="--test:ErrorRanges" # E_StructMustHaveAtLeastOneField.fs diff --git a/tests/fsharpqa/Source/Diagnostics/NONTERM/env.lst b/tests/fsharpqa/Source/Diagnostics/NONTERM/env.lst index 9c2034726a2..a6aa35ba77f 100644 --- a/tests/fsharpqa/Source/Diagnostics/NONTERM/env.lst +++ b/tests/fsharpqa/Source/Diagnostics/NONTERM/env.lst @@ -65,4 +65,4 @@ NoMT SOURCE=fileModuleImpl03b.fs FSIMODE=PIPE COMPILE_ONLY=1 # fileModuleImpl SOURCE=fileNamespaceImpl01b.fs SCFLAGS="--test:ErrorRanges" # fileNamespaceImpl01b.fs SOURCE=memberDefinitionWithoutType01.fs SCFLAGS="--test:ErrorRanges" # memberDefinitionWithoutType01.fs - SOURCE=memberDefinitionWithoutType01b.fs SCFLAGS="--test:ErrorRanges" # memberDefinitionWithoutType01b.fs \ No newline at end of file + SOURCE=memberDefinitionWithoutType01b.fs SCFLAGS="--test:ErrorRanges" # memberDefinitionWithoutType01b.fs diff --git a/tests/fsharpqa/Source/Diagnostics/NONTERM/fileModuleImpl03b.fs b/tests/fsharpqa/Source/Diagnostics/NONTERM/fileModuleImpl03b.fs index 5ead465dd99..ea3b05a44ae 100644 --- a/tests/fsharpqa/Source/Diagnostics/NONTERM/fileModuleImpl03b.fs +++ b/tests/fsharpqa/Source/Diagnostics/NONTERM/fileModuleImpl03b.fs @@ -1,6 +1,6 @@ // #Regression #Diagnostics #ReqNOMT // Regression test for FSHARP1.0:2681 //NONTERM -//val it : char = +//val it: char = '\U00002620';; exit 0;; diff --git a/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs b/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs index 74f2176d4cf..ecc1175241d 100644 --- a/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs +++ b/tests/fsharpqa/Source/Diagnostics/async/ReturnBangNonAsync_IfThenElse.fs @@ -1,6 +1,6 @@ // #Regression #Diagnostics #Async // Regression tests for FSHARP1.0:4394 -//All branches of an 'if' expression must return values of the same type as the first branch +//All branches of an 'if' expression must return values implicitly convertible to the type of the first branch async { if true then return () else diff --git a/tests/fsharpqa/Source/Diagnostics/async/env.lst b/tests/fsharpqa/Source/Diagnostics/async/env.lst index ff3efcad322..7a5be4cdc13 100644 --- a/tests/fsharpqa/Source/Diagnostics/async/env.lst +++ b/tests/fsharpqa/Source/Diagnostics/async/env.lst @@ -1,6 +1,4 @@ SOURCE=LetBangNonAsync.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # LetBangNonAsync.fs - SOURCE=MissingBangForLoop01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # MissingBangForLoop01.fs - SOURCE=MissingBangForLoop02.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # MissingBangForLoop02.fs SOURCE=MissingIgnore.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # MissingIgnore.fs SOURCE=MissingReturnBangForLoop01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # MissingReturnBangForLoop01.fs SOURCE=MissingReturnBangForLoop02.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # MissingReturnBangForLoop02.fs @@ -9,11 +7,9 @@ SOURCE=ReturnBangNonAsync01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync01.fs SOURCE=ReturnBangNonAsync02.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync02.fs SOURCE=ReturnBangNonAsync_For.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync_For.fs - SOURCE=ReturnBangNonAsync_IfThenElse.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync_IfThenElse.fs SOURCE=ReturnBangNonAsync_TryFinally.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync_TryFinally.fs SOURCE=ReturnBangNonAsync_TryWith.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync_TryWith.fs SOURCE=ReturnBangNonAsync_While.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # ReturnBangNonAsync_While.fs SOURCE=UsingReturnInAWhileLoop.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # UsingReturnInAWhileLoop.fs SOURCE=UsingReturnInIfThenElse.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # UsingReturnInIfThenElse.fs - SOURCE=UseBindingWrongForm01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # UseBindingWrongForm01.fs - SOURCE=IncompleteMatchInAsync01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # IncompleteMatchInAsync01.fs \ No newline at end of file + SOURCE=IncompleteMatchInAsync01.fs SCFLAGS="--warnaserror+ --test:ErrorRanges --flaterrors" COMPILE_ONLY=1 # IncompleteMatchInAsync01.fs diff --git a/tests/fsharpqa/Source/EntryPoint/E_twoentrypoints001.fs b/tests/fsharpqa/Source/EntryPoint/E_twoentrypoints001.fs index 2570a557776..ab5028ccc8a 100644 --- a/tests/fsharpqa/Source/EntryPoint/E_twoentrypoints001.fs +++ b/tests/fsharpqa/Source/EntryPoint/E_twoentrypoints001.fs @@ -3,7 +3,7 @@ // Explicit program entry point: [] // attribute on multiple functions //Hello -//A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence. +//A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence. #light module M = diff --git a/tests/fsharpqa/Source/EntryPoint/env.lst b/tests/fsharpqa/Source/EntryPoint/env.lst index 1055220f89d..7d37209c97e 100644 --- a/tests/fsharpqa/Source/EntryPoint/env.lst +++ b/tests/fsharpqa/Source/EntryPoint/env.lst @@ -20,4 +20,4 @@ NoMT SOURCE=entrypointandFSI02.fsx FSIMODE=EXEC COMPILE_ONLY=1 # entrypointan SOURCE=W_NoEntryPointInLastModuleInsideMultipleNamespace.fs SCFLAGS="--test:ErrorRanges" # W_NoEntryPointInLastModuleInsideMultipleNamespace.fs SOURCE=W_NoEntryPointModuleInNamespace.fs SCFLAGS="--test:ErrorRanges" # W_NoEntryPointModuleInNamespace.fs SOURCE=W_NoEntryPointMultipleModules.fs SCFLAGS="--test:ErrorRanges" # W_NoEntryPointMultipleModules.fs - SOURCE=W_NoEntryPointTypeInNamespace.fs SCFLAGS="--test:ErrorRanges" # W_NoEntryPointTypeInNamespace.fs \ No newline at end of file + SOURCE=W_NoEntryPointTypeInNamespace.fs SCFLAGS="--test:ErrorRanges" # W_NoEntryPointTypeInNamespace.fs diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs deleted file mode 100644 index 130c63a7d55..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/app.fs +++ /dev/null @@ -1,22 +0,0 @@ -//This expression was expected to have type -//'A (liba, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' -//but here has type -//'A (libb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' - - -//This expression was expected to have type -//'B (liba, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' -//but here has type -//'B (libb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' - - -let a = AMaker.makeA() -let otherA = OtherAMaker.makeOtherA() -printfn "%A %A" (a.GetType().AssemblyQualifiedName) (otherA.GetType().AssemblyQualifiedName) -printfn "%A" (a = otherA) - -let b = AMaker.makeB() -let otherB = OtherAMaker.makeOtherB() -printfn "%A %A" (b.GetType().AssemblyQualifiedName) (otherB.GetType().AssemblyQualifiedName) -printfn "%A" (b = otherB) - \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat deleted file mode 100644 index abcfa42e592..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/compile.bat +++ /dev/null @@ -1,6 +0,0 @@ -rem if you want to try it out without running the whole suite -csc -t:library -out:liba.dll liba-and-b.cs -csc -t:library -out:libb.dll liba-and-b.cs -fsc --target:library -r:liba.dll --out:libc.dll libc.fs -fsc --target:library -r:libb.dll --out:libd.dll libd.fs -fsc -r:liba.dll -r:libb.dll -r:libc.dll -r:libd.dll app.fs diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst deleted file mode 100644 index 8189ed0b1f8..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/env.lst +++ /dev/null @@ -1,3 +0,0 @@ -# see compile.bat for clearer steps, aim is to get message highlighting fix for https://github.com/Microsoft/visualfsharp/issues/2561 - SOURCE="app.fs" SCFLAGS="-r:liba.dll -r:libb.dll -r:libc.dll -r:libd.dll" PRECMD="\$CSC_PIPE -t:library -out:liba.dll liba-and-b.cs && \$CSC_PIPE -t:library -out:libb.dll liba-and-b.cs && fsc --target:library -r:liba.dll --out:libc.dll libc.fs && fsc --target:library -r:libb.dll --out:libd.dll libd.fs" - \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs deleted file mode 100644 index 9e1d2d24b31..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/liba-and-b.cs +++ /dev/null @@ -1,2 +0,0 @@ -public class A { } -public class B { } \ No newline at end of file diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs deleted file mode 100644 index 4e1450a4149..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libc.fs +++ /dev/null @@ -1,3 +0,0 @@ -module AMaker -let makeA () : A = A() -let makeB () = B<_>() diff --git a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs b/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs deleted file mode 100644 index 5458451d7cb..00000000000 --- a/tests/fsharpqa/Source/ErrorMessages/ConfusingTypeName/libd.fs +++ /dev/null @@ -1,3 +0,0 @@ -module OtherAMaker -let makeOtherA () : A = A() -let makeOtherB () = B<_>() \ No newline at end of file diff --git a/tests/fsharpqa/Source/Globalization/Hindi.fs b/tests/fsharpqa/Source/Globalization/Hindi.fs index 3c041c812fd..63a33edbdd7 100644 --- a/tests/fsharpqa/Source/Globalization/Hindi.fs +++ b/tests/fsharpqa/Source/Globalization/Hindi.fs @@ -14,8 +14,8 @@ module पिछले = // DU type ख़तरxनाक = - | Uअलगाववादी // There's no uppercase/lowercase in Hindi, so I'm adding a latin char - | Aमिलती of ख़तरनाक + | अलगाववादी // There's no uppercase/lowercase in Hindi, ensure that a Hindi character will suffice to start the DU case name + | मिलती of ख़तरनाक | X // Record diff --git a/tests/fsharpqa/Source/Import/E_InternalsConsumer.fs b/tests/fsharpqa/Source/Import/E_InternalsConsumer.fs index ffc1a2e8ae1..211b2a613f0 100644 --- a/tests/fsharpqa/Source/Import/E_InternalsConsumer.fs +++ b/tests/fsharpqa/Source/Import/E_InternalsConsumer.fs @@ -4,7 +4,7 @@ // Test that even if we have InternalsVisibleTo() attribute for this friendly assembly, private members won't be still accessible //The type 'CalcBeta' is not accessible from this code location$ //Method or object constructor 'CalcBeta' not found$ -//The field, constructor or member 'Mod' is not defined +//The type 'CalcBeta' does not define the field, constructor or member 'Mod' (new CalcBeta()).Mod(1,1) |> ignore exit 1 diff --git a/tests/fsharpqa/Source/Import/FamAndAssembly_NoIVT.fs b/tests/fsharpqa/Source/Import/FamAndAssembly_NoIVT.fs index cf4a423707d..a13f0b57173 100644 --- a/tests/fsharpqa/Source/Import/FamAndAssembly_NoIVT.fs +++ b/tests/fsharpqa/Source/Import/FamAndAssembly_NoIVT.fs @@ -1,5 +1,5 @@ // #Regression #NoMT #Import -//The field, constructor or member 'FamAndAssembly' is not defined. +//The type 'Accessibility' does not define the field, constructor or member 'FamAndAssembly'. Maybe you want one of the following: namespace NS type T() = diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/DeclareEvent.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/DeclareEvent.fsx index 52467c23a68..563a64c1f20 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/DeclareEvent.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/DeclareEvent.fsx @@ -1,5 +1,5 @@ // #NoMT #FSI -//EventName: Event +//EventName: Event type T() = do diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/DefaultReferences.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/DefaultReferences.fsx index ed595872da4..1ebbd0291dc 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/DefaultReferences.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/DefaultReferences.fsx @@ -2,10 +2,10 @@ // Regression for FSB 3594 // Verify System.Core.dll is referenced in FSI by default -//val a : System\.Action +//val a: System\.Action //stuff -//val it : unit = \(\) -//val hs : Collections\.Generic\.HashSet +//val it: unit = \(\) +//val hs: Collections\.Generic\.HashSet //type A = Action //type B = Action diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/DontShowCompilerGenNames01.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/DontShowCompilerGenNames01.fsx index 9b2bd981e96..71aba802477 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/DontShowCompilerGenNames01.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/DontShowCompilerGenNames01.fsx @@ -2,13 +2,12 @@ // Regression test for FSHARP1.0:2549 // See also CL:14579 -//type T = -//class -//member M1 : x:int \* y:string -> \('a -> unit\) -//member M2 : \(int \* string\) -> \('a -> unit\) -//exception ExnType of int \* string -//type DiscUnion = \| DataTag of int \* string -//val f : x:int -> y:int -> int +//type T = +//member M1: x: int \* y: string -> \('a -> unit\) +//member M2: \(int \* string\) -> \('a -> unit\) +//exception ExnType of int \* string +//type DiscUnion = \| DataTag of int \* string +//val f: x: int -> y: int -> int type T = diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/E_RangeOperator01.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/E_RangeOperator01.fsx index 004ef985471..8f3bdfa834e 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/E_RangeOperator01.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/E_RangeOperator01.fsx @@ -3,7 +3,7 @@ //fsbug //nonTerminalId\.GetTag -//Unexpected symbol '\.\.' in interaction\. Expected incomplete structured construct at or before this point, ';', ';;' or other token\.$ +//Incomplete expression or invalid use of indexer syntax aaaa..;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx index 9fac116ed39..09150ddb8e8 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/E_let_id.fsx @@ -1,5 +1,5 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:5629 -//Incomplete structured construct at or before this point in pattern$ +//Incomplete structured construct at or before this point in binding. Expected '=' or other token. let f;; exit 1;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/EmptyList.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/EmptyList.fsx index da1df59524e..da86405eec7 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/EmptyList.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/EmptyList.fsx @@ -1,7 +1,7 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:5599 // -//val it : 'a list$ +//val it: 'a list$ [];; #q;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/GenericConstraintWoes/issue2411/env.lst b/tests/fsharpqa/Source/InteractiveSession/Misc/GenericConstraintWoes/issue2411/env.lst index 6ec14cc9a8f..6200512365f 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/GenericConstraintWoes/issue2411/env.lst +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/GenericConstraintWoes/issue2411/env.lst @@ -1 +1 @@ - SOURCE=app.fsx COMPILE_ONLY=1 FSIMODE=EXEC SCFLAGS="--nologo" PRECMD="\$CSC_PIPE -t:library lib.cs" # mode exec: used to produce internal error \ No newline at end of file + SOURCE=app.fsx COMPILE_ONLY=1 FSIMODE=EXEC SCFLAGS="--nologo" PRECMD="\$CSC_PIPE -t:library lib.cs" # mode exec: used to produce internal error diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained01.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained01.fsx index 430983dd657..abf11037679 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained01.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained01.fsx @@ -3,13 +3,9 @@ // Interfaces cross-constrained via method gps //type IA = -// interface -// abstract member M : #IB -> int -// end +// abstract M: #IB -> int //and IB = -// interface -// abstract member M : #IA -> int -// end +// abstract M: #IA -> int type IA = abstract M : 'a -> int when 'a :> IB diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained02.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained02.fsx index 4b87394c7aa..e82db517e57 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained02.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/InterfaceCrossConstrained02.fsx @@ -1,13 +1,9 @@ // #Regression #NoMT #FSI #RequiresENU // Regression test for DEV10#832789 //type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = -// interface -// abstract member M : int -// end +// abstract M: int //and IB2<'b when 'b :> IA2<'b> and 'b :> IB2<'b>> = -// interface -// abstract member M : int -// end +// abstract M: int type IA2<'a when 'a :> IB2<'a> and 'a :> IA2<'a>> = abstract M : int diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/NativeIntSuffix01.fs b/tests/fsharpqa/Source/InteractiveSession/Misc/NativeIntSuffix01.fs index 9ee7197ebea..21c0a233b2b 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/NativeIntSuffix01.fs +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/NativeIntSuffix01.fs @@ -1,7 +1,7 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:4118 // FSI: PrettyPrinting of nativeint or unativeint does not emit the suffix (n or un, respectively) -//val it : nativeint = 2n +//val it: nativeint = 2n nativeint 2;; #q;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/NoExpansionOfAbbrevUoMInFSI.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/NoExpansionOfAbbrevUoMInFSI.fsx index a4566d84d22..13b2502a64e 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/NoExpansionOfAbbrevUoMInFSI.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/NoExpansionOfAbbrevUoMInFSI.fsx @@ -1,7 +1,7 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:5056 // F# expands unit-of-measure abbreviations unnecessarily -//val it : float \* float = \(2\.0, 2\.0\) +//val it: float \* float = \(2\.0, 2\.0\) [] type kg [] type m diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx index d3ac670bff1..35488259541 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx @@ -1,6 +1,6 @@ // #Regression #NoMT #FSI // Public fields did not print. -//val it : PublicField = FSI_0002+PublicField \{X = 2; +//val it: PublicField = FSI_0002+PublicField \{X = 2; // Y = 1;\} [] type PublicField = diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/ReferenceFullPathGenTest.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/ReferenceFullPathGenTest.fsx index fc7b8cd5391..badd72da55a 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/ReferenceFullPathGenTest.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/ReferenceFullPathGenTest.fsx @@ -3,8 +3,8 @@ let fwkdir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirecto let path = System.IO.Path.Combine(fwkdir, "System.Security.dll") printfn "//.+System\\.Security\\.dll" -printfn "//val f : unit -> System\\.Security\\.Cryptography\\.Xml\\.Signature" -printfn "//val it : System\\.Security\\.Cryptography\\.Xml\\.Signature =" +printfn "//val f: unit -> System\\.Security\\.Cryptography\\.Xml\\.Signature" +printfn "//val it: System\\.Security\\.Cryptography\\.Xml\\.Signature =" //printfn "//System\\.Security\\.Cryptography\\.Xml\\.Signature {Id = null;" printfn "//KeyInfo = seq \\[\\];" printfn "//ObjectList = seq \\[\\];" diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/References.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/References.fsx index e78bd6d32f9..b683e9b2123 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/References.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/References.fsx @@ -1,4 +1,4 @@ // #NoMT #FSI -//System\.Core\.dll +//System\.Core\.dll #r "System.Core.dll";; exit 0;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/References35.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/References35.fsx index 1e09e7ca7f1..cd90f8baa0c 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/References35.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/References35.fsx @@ -1,4 +1,4 @@ // #NoMT #FSI #NoMono -//v3\.5.+System\.Core\.dll +//v3\.5.+System\.Core\.dll #r "System.Core.dll";; exit 0;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/References40.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/References40.fsx index c56ce024ff3..021cafa5c85 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/References40.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/References40.fsx @@ -1,4 +1,4 @@ // #NoMT #FSI #NoMono -//v4\.0.+System\.Core\.dll +//v4\.0.+System\.Core\.dll #r "System.Core.dll";; exit 0;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionBugOnMono6433.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionBugOnMono6433.fsx index f809bb5df31..30f2110fbd0 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionBugOnMono6433.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionBugOnMono6433.fsx @@ -1,8 +1,8 @@ // Regression test for FSHARP1.0:6433 // This is really a bug in Mono -//val mul : MM -//val factorial : x:int -> int -//val k : int = 120 +//val mul: MM +//val factorial: x: int -> int +//val k: int = 120 type MM() = member x.Combine(a,b) = a * b diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionTypeNameMangling01.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionTypeNameMangling01.fsx index f58e33aa758..ee90c7fe432 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionTypeNameMangling01.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/ReflectionTypeNameMangling01.fsx @@ -8,23 +8,17 @@ //This type test or downcast will always hold // match paintObject with // ---------------------\^\^\^\^\^\^\^\^\^\^\^ -//Incomplete pattern matches on this expression\. For example, the value '\( some-other-subtype \)' may indicate a case not covered by the pattern\(s\) +//Incomplete pattern matches on this expression\. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern\(s\) // match lastTimeOption with // --------------\^\^\^\^\^\^\^\^\^\^\^\^\^\^ //Incomplete pattern matches on this expression\. For example, the value 'None' may indicate a case not covered by the pattern\(s\) //type Planet = -// class -// new : ipx:float \* ivx:float -> Planet -// member VX : float -// member X : float -// member VX : float with set -// member X : float with set -// end -//val paintObjects : Planet list +// new: ipx: float \* ivx: float -> Planet +// member VX: float +// member X: float +//val paintObjects: Planet list //type Simulator = -// class -// new : unit -> Simulator -// end +// new: unit -> Simulator type Planet(ipx:float,ivx:float) = diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/SubtypeArgInterfaceWithAbstractMember.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/SubtypeArgInterfaceWithAbstractMember.fsx index a824235dde4..584847e4ed6 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/SubtypeArgInterfaceWithAbstractMember.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/SubtypeArgInterfaceWithAbstractMember.fsx @@ -2,15 +2,11 @@ // Regression test for FSHARP1.0:5825 //type I = -// interface -// abstract member m : unit -// end +// abstract m: unit //type C = -// class -// interface I -// new : unit -> C -// end -//val f : c:#C -> unit +// interface I +// new: unit -> C +//val f: c: #C -> unit type I = abstract member m : unit diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/TimeToggles.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/TimeToggles.fsx index a764279c7f5..31a4e1d087e 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/TimeToggles.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/TimeToggles.fsx @@ -1,7 +1,7 @@ // #Regression #NoMT #FSI #RequiresENU // Regression test for FSharp1.0:4164 - FSI emit "please report to fsbugs" error on malformed usage of .. operator -// Timing now on -// Timing now off +// Timing now on +// Timing now off #time "on" #time "off" diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/ToStringNull.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/ToStringNull.fsx index cef700e20c5..2f43e9c8d1b 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/ToStringNull.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/ToStringNull.fsx @@ -2,7 +2,7 @@ // Microsoft.Analysis.Server overrides ToString() to return isNull // instead of a string. This would make FSI fail in pretty-printing // when displaying results. -//val n : NullToString = +//val n: NullToString = type NullToString() = override __.ToString() = null;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/UNativeIntSuffix01.fs b/tests/fsharpqa/Source/InteractiveSession/Misc/UNativeIntSuffix01.fs index 2c074746de7..a3e991331c5 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/UNativeIntSuffix01.fs +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/UNativeIntSuffix01.fs @@ -1,7 +1,7 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:4118 // FSI: PrettyPrinting of nativeint or unativeint does not emit the suffix (n or un, respectively) -//val it : unativeint = 2un +//val it: unativeint = 2un unativeint 2;; #q;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323.fsx index 40280db551c..4e9a6318878 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323.fsx @@ -1,4 +1,4 @@ // #NoMT #FSI -//val it : unit = \(\) +//val it: unit = \(\) ();; #q;; \ No newline at end of file diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323b.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323b.fsx index 9947eb92f90..961fbb20bc9 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323b.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/UnitConstInput_6323b.fsx @@ -1,6 +1,6 @@ // #NoMT #FSI -//val it : int = 42 -//val it : unit = \(\) +//val it: int = 42 +//val it: unit = \(\) 42;; ();; #q;; \ No newline at end of file diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/VerbatimIdentifier01.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/VerbatimIdentifier01.fsx index ccc2e903593..e0d3100b557 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/VerbatimIdentifier01.fsx +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/VerbatimIdentifier01.fsx @@ -1,12 +1,42 @@ // #Regression #NoMT #FSI // Regression test for FSHARP1.0:5675 -//val \( A\.B \) : bool = true -//val \( \.\. \) : bool = true -//val A : bool = true +//val ``A\.B`` : bool = true +//val ``+`` : bool = true +//val ``\.\.`` : bool = true +//val ``\.\. \.\.`` : bool = true +//val ``(+)`` : bool = true +//val ``land`` : bool = true +//val ``type`` : bool = true +//val ``or`` : bool = true +//val ``params`` : bool = true +//val A: bool = true +//val ``'A`` : bool = true +//val A' : bool = true +//val ``0A`` : bool = true +//val A0 : bool = true +//val ``A-B`` : bool = true +//val ``A B`` : bool = true +//val ``base`` : bool = true +//val ``or`` : bool = true let ``A.B`` = true;; +let ``+`` = true;; let ``..`` = true;; +let ``.. ..`` = true;; +let ``(+)`` = true;; +let ``land`` = true;; +let ``type`` = true;; +let ``or`` = true;; +let ``params`` = true;; let ``A`` = true;; +let ``'A`` = true;; +let ``A'`` = true;; +let ``0A`` = true;; +let ``A0`` = true;; +let ``A-B`` = true;; +let ``A B`` = true;; +let ``base`` = true;; +let ``or`` = true;; exit 0;; diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst b/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst index f18e59e67d6..c3cf858c21b 100644 --- a/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst +++ b/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst @@ -167,4 +167,4 @@ NOMONO SOURCE=Regressions01.fs COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo" SOURCE=..\\Misc\\aaa\\bbb\\RelativeHashRResolution05_1.fsx COMPILE_ONLY=1 SCFLAGS="--nologo --simpleresolution --noframework -r:\"%FSCOREDLLPATH%\"" # RelativeHashRResolution05_fscrelativesimple # dependency managers -SOURCE="UnknownDependencyManager\\script1.fsx" COMPILE_ONLY=1 FSIMODE=FEED SCFLAGS="--nologo" # with unknown manager \ No newline at end of file +SOURCE="UnknownDependencyManager\\script1.fsx" COMPILE_ONLY=1 FSIMODE=FEED SCFLAGS="--nologo" # with unknown manager diff --git a/tests/fsharpqa/Source/KnownFail.txt b/tests/fsharpqa/Source/KnownFail.txt index f2a3f0dc6ec..51e03a36340 100644 --- a/tests/fsharpqa/Source/KnownFail.txt +++ b/tests/fsharpqa/Source/KnownFail.txt @@ -86,7 +86,7 @@ CHK Stress (2766.fs) -- failed # compiler/runtime unit test known failures -!NETFX35 FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.SeqModule2.SystemLinqSelectWithException -- failed -!NETFX35 FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Collections.SeqModule2.SystemLinqSelectWithSideEffects -- failed -!CURRENTUICULTURE1033 FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control.AsyncModule.ContinuationsThreadingDetails.AsyncSansSyncContext -- failed -!CURRENTUICULTURE1033 FSharp.Core.UnitTests.FSharp_Core.Microsoft_FSharp_Control.AsyncModule.ContinuationsThreadingDetails.AsyncWithSyncContext -- failed \ No newline at end of file +!NETFX35 FSharp.Core.UnitTests.Collections.SeqModule2.SystemLinqSelectWithException -- failed +!NETFX35 FSharp.Core.UnitTests.Collections.SeqModule2.SystemLinqSelectWithSideEffects -- failed +!CURRENTUICULTURE1033 FSharp.Core.UnitTests.Control.AsyncModule.ContinuationsThreadingDetails.AsyncSansSyncContext -- failed +!CURRENTUICULTURE1033 FSharp.Core.UnitTests.Control.AsyncModule.ContinuationsThreadingDetails.AsyncWithSyncContext -- failed diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter01.fs b/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter01.fs deleted file mode 100644 index d230135a676..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter01.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Collections -// Regression for FSHARP1.0: 5919 -// bug in array2D functions would cause iter to blow up - -module M - -let a = Array2D.createBased 1 5 10 10 0.0 -a |> Array2D.iter (printf "%f") - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter02.fs b/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter02.fs deleted file mode 100644 index 95de7ed0009..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/Array2DIter02.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Collections -// Regression for FSHARP1.0: 5919 -// bug in array2D functions would cause iteri to blow up - -module M - -let a = Array2D.createBased 1 5 10 10 0.0 -a |> Array2D.iteri (fun i j x -> printf "%f" x) - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/EqualityOnMap01.fs b/tests/fsharpqa/Source/Libraries/Core/Collections/EqualityOnMap01.fs deleted file mode 100644 index 2b665710186..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/EqualityOnMap01.fs +++ /dev/null @@ -1,5 +0,0 @@ -// #Regression #Libraries #Collections -// Dev11:19569 - this used to throw an ArgumentException saying Object didn't implement IComparable - -let m = Map.ofArray [| 1, obj() |] -exit <| if (m = m) then 0 else 1 diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/Seq_Cast_Dispose01.fs b/tests/fsharpqa/Source/Libraries/Core/Collections/Seq_Cast_Dispose01.fs deleted file mode 100644 index 9ad88b379ad..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/Seq_Cast_Dispose01.fs +++ /dev/null @@ -1,38 +0,0 @@ -// #Regression #Libraries #Collections -// -// Regression test for FSHARP1.0:4726 -// Makes sure that the .Dispose() method, if available, in invoked on IEnumerable -// -// This test should probably go under the SystematicUnitTests suite, but -// I could not decide how to make it fit... so I'm leaving it here. -// -// - -let mutable dispose_called_in_E = 0 // we expect this to be incremented 3 times -let mutable dispose_called_in_C = 0 // we expect this to be incremented once (=this is what the bug was about, i.e. .Dispose() was never invoked) - -type E(c:int) = class - interface System.IDisposable with - member x.Dispose () = dispose_called_in_E <- dispose_called_in_E + 1 - end - -type C() = class - let mutable i = 0 - interface System.Collections.IEnumerator with - member x.Current with get () = new E(i) :> obj - member x.MoveNext () = i <- i+1 - i<4 - member x.Reset () = i <- 0 - interface System.Collections.IEnumerable with - member x.GetEnumerator () = x :> System.Collections.IEnumerator - - interface System.IDisposable with - member x.Dispose () = dispose_called_in_C <- dispose_called_in_C + 1 - end - - end - -let _ = Seq.cast (new C()) |> Seq.map (fun x -> use o = x; - o) |> Seq.length - -(if (dispose_called_in_E<>3 && dispose_called_in_C<>1) then 1 else 0) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/env.lst b/tests/fsharpqa/Source/Libraries/Core/Collections/env.lst deleted file mode 100644 index 11b81762be6..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/env.lst +++ /dev/null @@ -1,5 +0,0 @@ - SOURCE=seq_cast_dispose01.fs # seq_cast_dispose01.fs - SOURCE=list_head_tail01.fs SCFLAGS="--test:ErrorRanges" # list_head_tail01.fs - SOURCE=Array2DIter01.fs # Array2DIter01.fs - SOURCE=Array2DIter02.fs # Array2DIter02.fs - SOURCE=EqualityOnMap01.fs # EqualityOnMap01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Libraries/Core/Collections/list_head_tail01.fs b/tests/fsharpqa/Source/Libraries/Core/Collections/list_head_tail01.fs deleted file mode 100644 index c8ef0126e5d..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Collections/list_head_tail01.fs +++ /dev/null @@ -1,33 +0,0 @@ -// #Regression #Libraries #Collections -// Regression test for FSharp1.0:5641 -// Title: List.hd/tl --> List.head/tail - -//The value, constructor, namespace or type 'hd' is not defined -//The value, constructor, namespace or type 'tl' is not defined - -// Positive tests... -if (List.head [1 .. 10] <> 1) - || (List.head ["a"] <> "a") - || (List.tail [1 .. 10] <> [2 .. 10]) - || (List.tail [1] <> []) - || (List.head ['a'; 'a'] <> List.head (List.tail ['a'; 'a'])) -then exit 1 - -// Negative tests... -try - List.head [] |> ignore - exit 1 -with - | :? System.ArgumentException -> () - -try - List.tail [] |> ignore - exit 1 -with - | :? System.ArgumentException -> () - -// Test deprecation message (now it's an error!) -List.hd [1] |> ignore -List.tl [1] |> ignore - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck01.fs b/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck01.fs deleted file mode 100644 index b381e4993ae..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck01.fs +++ /dev/null @@ -1,16 +0,0 @@ -// #Regression #Llibraries -// Regression test for FSHARP1.0:5365 -// - -module N.M - - open System - open System.Collections.Generic - - type ICloneable<'a> = - abstract Clone : unit -> 'a - - type DictionaryFeature<'key, 'dict when 'dict :> IDictionary<'key, int> and 'dict :> ICloneable<'dict>> (dict: 'dict) = - member this.Add key value = - dict.[key] <- value // use to give error: value must be local and mutable in order to mutate the contents of a value type, e.g. 'let mutable x = ...' - diff --git a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck02.fs b/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck02.fs deleted file mode 100644 index 2068f55ece7..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/dict_typecheck02.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Regression #Llibraries -// Regression test for FSHARP1.0:5365 -// - -module N.M - - open System - open System.Collections.Generic - - type ICloneable<'a> = - abstract Clone : unit -> 'a - - type DictionaryFeature<'key> (dict: IDictionary<'key, int>) = - member this.Add key value = - dict.[key] <- value diff --git a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/env.lst b/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/env.lst deleted file mode 100644 index 777dd651096..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/ExtraTopLevelOperators/env.lst +++ /dev/null @@ -1,2 +0,0 @@ - SOURCE=dict_typecheck01.fs SCFLAGS="-a --warnaserror+" # dict_typecheck01.fs - SOURCE=dict_typecheck02.fs SCFLAGS="-a --warnaserror+" # dict_typecheck02.fs diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/CastToUnits01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/CastToUnits01.fs deleted file mode 100644 index 571c788c397..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/CastToUnits01.fs +++ /dev/null @@ -1,20 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives -// Regression for FSHARP1.0:5794 -// New functions to cast dimensionless value to unitful value - -module M - -open Microsoft.FSharp.Core.LanguagePrimitives - -[] -type M - -let r1 = SByteWithMeasure 1y + 2y -let r2 = Int16WithMeasure 2s - 2s -let r3 = Int32WithMeasure 3 * 3 -let r4 = Int64WithMeasure 5L / 5L -let r5 = FloatWithMeasure 11.11 + 1.1 -let r6 = Float32WithMeasure 22.22f - 11.11f -let r7 = DecimalWithMeasure 33.33M * 44.44M - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_d_01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_d_01.fs deleted file mode 100644 index 17ae0d72847..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_d_01.fs +++ /dev/null @@ -1,32 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives -// Regression test for FSHARP1.0:4120 -// format specifier %d does not work correctly with UInt64 values - -// -// This test covers the usage of %d -// All kinds of valid input are provided -// - -let test = [ ((sprintf "%d" System.UInt64.MaxValue), "18446744073709551615"); - ((sprintf "%d" System.UInt64.MinValue), "0"); - ((sprintf "%d" System.UInt32.MaxValue), "4294967295"); - ((sprintf "%d" System.UInt32.MinValue), "0"); - ((sprintf "%d" System.UInt16.MaxValue), "65535"); - ((sprintf "%d" System.UInt16.MinValue), "0"); - ((sprintf "%d" System.Byte.MaxValue), "255"); - ((sprintf "%d" System.Byte.MinValue), "0"); - ((sprintf "%d" System.Int64.MaxValue), "9223372036854775807"); - ((sprintf "%d" System.Int64.MinValue), "-9223372036854775808"); - ((sprintf "%d" System.Int32.MaxValue), "2147483647"); - ((sprintf "%d" System.Int32.MinValue), "-2147483648"); - ((sprintf "%d" System.Int16.MaxValue), "32767"); - ((sprintf "%d" System.Int16.MinValue), "-32768"); - ((sprintf "%d" System.SByte.MaxValue), "127"); - ((sprintf "%d" System.SByte.MinValue), "-128"); - ((sprintf "%d" 1un), "1"); - ((sprintf "%d" -1n), "-1"); - ] - -let res = List.forall (fun x -> (fst x) = (snd x)) test - -(if res then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_i_01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_i_01.fs deleted file mode 100644 index e5fa47c4143..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_i_01.fs +++ /dev/null @@ -1,32 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives -// Regression test for FSHARP1.0:4120 -// format specifier %i does not work correctly with UInt64 values - -// -// This test covers the usage of %i -// All kinds of valid input are provided -// - -let test = [ ((sprintf "%i" System.UInt64.MaxValue), "18446744073709551615"); - ((sprintf "%i" System.UInt64.MinValue), "0"); - ((sprintf "%i" System.UInt32.MaxValue), "4294967295"); - ((sprintf "%i" System.UInt32.MinValue), "0"); - ((sprintf "%i" System.UInt16.MaxValue), "65535"); - ((sprintf "%i" System.UInt16.MinValue), "0"); - ((sprintf "%i" System.Byte.MaxValue), "255"); - ((sprintf "%i" System.Byte.MinValue), "0"); - ((sprintf "%i" System.Int64.MaxValue), "9223372036854775807"); - ((sprintf "%i" System.Int64.MinValue), "-9223372036854775808"); - ((sprintf "%i" System.Int32.MaxValue), "2147483647"); - ((sprintf "%i" System.Int32.MinValue), "-2147483648"); - ((sprintf "%i" System.Int16.MaxValue), "32767"); - ((sprintf "%i" System.Int16.MinValue), "-32768"); - ((sprintf "%i" System.SByte.MaxValue), "127"); - ((sprintf "%i" System.SByte.MinValue), "-128"); - ((sprintf "%i" 1un), "1"); - ((sprintf "%i" -1n), "-1"); - ] - -let res = List.forall (fun x -> (fst x) = (snd x)) test - -(if res then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_u_01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_u_01.fs deleted file mode 100644 index 240b9ef9a08..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/FormatSpec_u_01.fs +++ /dev/null @@ -1,32 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives -// Regression test for FSHARP1.0:4120 -// format specifier %u does not work correctly with UInt64 values - -// -// This test covers the usage of %u -// All kinds of valid input are provided -// - -let test = [ ((sprintf "%u" System.UInt64.MaxValue), "18446744073709551615"); - ((sprintf "%u" System.UInt64.MinValue), "0"); - ((sprintf "%u" System.UInt32.MaxValue), "4294967295"); - ((sprintf "%u" System.UInt32.MinValue), "0"); - ((sprintf "%u" System.UInt16.MaxValue), "65535"); - ((sprintf "%u" System.UInt16.MinValue), "0"); - ((sprintf "%u" System.Byte.MaxValue), "255"); - ((sprintf "%u" System.Byte.MinValue), "0"); - ((sprintf "%u" System.Int64.MaxValue), "9223372036854775807"); - ((sprintf "%u" System.Int64.MinValue), "9223372036854775808"); - ((sprintf "%u" System.Int32.MaxValue), "2147483647"); - ((sprintf "%u" System.Int32.MinValue), "2147483648"); - ((sprintf "%u" System.Int16.MaxValue), "32767"); - ((sprintf "%u" System.Int16.MinValue), "32768"); - ((sprintf "%u" System.SByte.MaxValue), "127"); - ((sprintf "%u" System.SByte.MinValue), "128"); - ((sprintf "%u" 1un), "1"); - ((sprintf "%u" -1n), if System.IntPtr.Size = 4 then "4294967295" else "18446744073709551615"); - ] - -let res = List.forall (fun x -> (fst x) = (snd x)) test - -(if res then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fs deleted file mode 100644 index 59ff2ee3409..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fs +++ /dev/null @@ -1,87 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives #ReqNOMT -// Regression test for FSHARP1.0:5894 -// - -let v = [ - (string 1.0f); - (string 1.00001f); - (string -1.00001f); - - (string 1.0); - (string 1.00001); - (string -1.00001); - - (string System.SByte.MaxValue); - (string System.SByte.MinValue); - (string 0y); - (string -1y); - (string 1y); - - (string System.Byte.MaxValue); - (string System.Byte.MinValue); - (string 0uy); - (string 1uy); - - (string System.Int16.MaxValue); - (string System.Int16.MinValue); - (string 0s); - (string -10s); - (string 10s); - - (string System.UInt16.MaxValue); - (string System.UInt16.MinValue); - (string 0us); - (string 110us); - - (string System.Int32.MaxValue); - (string System.Int32.MinValue); - (string 0); - (string -10); - (string 10); - - (string System.UInt32.MaxValue); - (string System.UInt32.MinValue); - (string 0u); - (string 10u); - - (string System.Int64.MaxValue); - (string System.Int64.MinValue); - (string 0L); - (string -10L); - (string 10L); - - (string System.UInt64.MaxValue); - (string System.UInt64.MinValue); - (string 0UL); - (string 10UL); - - (string System.Decimal.MaxValue); - (string System.Decimal.MinValue); - (string System.Decimal.Zero); - (string 12345678M); - (string -12345678M); - - (string -infinity); - (string infinity); - (string nan); - - (string -infinityf); - (string infinityf); - (string nanf); - - (string (new System.Guid("210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0"))) - - ] - -let expected = ["1"; "1.00001"; "-1.00001"; "1"; "1.00001"; "-1.00001"; "127"; "-128"; "0"; - "-1"; "1"; "255"; "0"; "0"; "1"; "32767"; "-32768"; "0"; "-10"; "10"; - "65535"; "0"; "0"; "110"; "2147483647"; "-2147483648"; "0"; "-10"; "10"; - "4294967295"; "0"; "0"; "10"; "9223372036854775807"; "-9223372036854775808"; - "0"; "-10"; "10"; "18446744073709551615"; "0"; "0"; "10"; - "79228162514264337593543950335"; "-79228162514264337593543950335"; "0"; - "12345678"; "-12345678"; "-Infinity"; "Infinity"; "NaN"; "-Infinity"; - "Infinity"; "NaN"; - "210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0"] - -exit <| if v = expected then 0 else 1 - diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fsx b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fsx deleted file mode 100644 index ba675c60d73..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/anytostring01.fsx +++ /dev/null @@ -1,128 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives #ReqNOMT -// Regression test for FSHARP1.0:5894 - -//val it : string = "1" -//val it : string = "1.00001" -//val it : string = "-1.00001" -//val it : string = "1" -//val it : string = "1.00001" -//val it : string = "-1.00001" -//val it : string = "127" -//val it : string = "-128" -//val it : string = "0" -//val it : string = "-1" -//val it : string = "1" -//val it : string = "255" -//val it : string = "0" -//val it : string = "0" -//val it : string = "1" -//val it : string = "32767" -//val it : string = "-32768" -//val it : string = "0" -//val it : string = "-10" -//val it : string = "10" -//val it : string = "65535" -//val it : string = "0" -//val it : string = "0" -//val it : string = "110" -//val it : string = "2147483647" -//val it : string = "-2147483648" -//val it : string = "0" -//val it : string = "-10" -//val it : string = "10" -//val it : string = "4294967295" -//val it : string = "0" -//val it : string = "0" -//val it : string = "10" -//val it : string = "9223372036854775807" -//val it : string = "-9223372036854775808" -//val it : string = "0" -//val it : string = "-10" -//val it : string = "10" -//val it : string = "18446744073709551615" -//val it : string = "0" -//val it : string = "0" -//val it : string = "10" -//val it : string = "79228162514264337593543950335" -//val it : string = "-79228162514264337593543950335" -//val it : string = "0" -//val it : string = "12345678" -//val it : string = "-12345678" -//val it : string = "-Infinity" -//val it : string = "Infinity" -//val it : string = "NaN" -//val it : string = "-Infinity" -//val it : string = "Infinity" -//val it : string = "NaN" -//val it : string = "210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0" - - (string 1.0f);; - (string 1.00001f);; - (string -1.00001f);; - - (string 1.0);; - (string 1.00001);; - (string -1.00001);; - - (string System.SByte.MaxValue);; - (string System.SByte.MinValue);; - (string 0y);; - (string -1y);; - (string 1y);; - - (string System.Byte.MaxValue);; - (string System.Byte.MinValue);; - (string 0uy);; - (string 1uy);; - - (string System.Int16.MaxValue);; - (string System.Int16.MinValue);; - (string 0s);; - (string -10s);; - (string 10s);; - - (string System.UInt16.MaxValue);; - (string System.UInt16.MinValue);; - (string 0us);; - (string 110us);; - - (string System.Int32.MaxValue);; - (string System.Int32.MinValue);; - (string 0);; - (string -10);; - (string 10);; - - (string System.UInt32.MaxValue);; - (string System.UInt32.MinValue);; - (string 0u);; - (string 10u);; - - (string System.Int64.MaxValue);; - (string System.Int64.MinValue);; - (string 0L);; - (string -10L);; - (string 10L);; - - (string System.UInt64.MaxValue);; - (string System.UInt64.MinValue);; - (string 0UL);; - (string 10UL);; - - (string System.Decimal.MaxValue);; - (string System.Decimal.MinValue);; - (string System.Decimal.Zero);; - (string 12345678M);; - (string -12345678M);; - - (string -infinity);; - (string infinity);; - (string nan);; - - (string -infinityf);; - (string infinityf);; - (string nanf);; - - (string (new System.Guid("210f4d6b-cb42-4b09-baa1-f1aa8e59d4b0")));; - -#q;; - diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fs b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fs deleted file mode 100644 index 4ff6d56b57c..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives #ReqNOMT -// Regression test for FSHARP1.0:5640 -// This is a sanity test: more coverage in FSHARP suite... -// - -type 'a www = W of 'a -let p = W System.Double.NaN = W System.Double.NaN // false (PER semantic) -let q = (W System.Double.NaN).Equals(W System.Double.NaN) // true (ER semantic) -let z = compare (W System.Double.NaN) (W System.Double.NaN) // 0 - -(if (not p) && q && (z=0) then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fsx b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fsx deleted file mode 100644 index ec7f3be5534..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/compare01.fsx +++ /dev/null @@ -1,22 +0,0 @@ -// #Regression #Libraries #LanguagePrimitives #ReqNOMT -// Regression test for FSHARP1.0:5640 -// This is a sanity test: more coverage in FSHARP suite... -//type 'a www = \| W of 'a -//val p : bool = false -//val q : bool = true -//val z : int = 0 -//0 -//val it : unit = \(\) - -type 'a www = W of 'a -let p = W System.Double.NaN = W System.Double.NaN;; - -let q = (W System.Double.NaN).Equals(W System.Double.NaN);; - -let z = compare (W System.Double.NaN) (W System.Double.NaN);; - -printfn "%A" (if (not p) && q && (z=0) then 0 else 1);; - -#q;; - - diff --git a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/env.lst b/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/env.lst deleted file mode 100644 index 16d6bcc4799..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/LanguagePrimitives/env.lst +++ /dev/null @@ -1,9 +0,0 @@ - SOURCE=anytostring01.fs # anytostring01.fs -NoMT SOURCE=anytostring01.fsx FSIMODE=PIPE COMPILE_ONLY=1 # anytostring01.fsx - - SOURCE=compare01.fs # compare01.fs -NoMT SOURCE=compare01.fsx FSIMODE=PIPE COMPILE_ONLY=1 # compare01.fsx - - SOURCE=FormatSpec_d_01.fs # FormatSpec_d_01.fs - SOURCE=FormatSpec_i_01.fs # FormatSpec_i_01.fs - SOURCE=FormatSpec_u_01.fs # FormatSpec_u_01.fs diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint02.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint02.fs deleted file mode 100644 index 2b903eb4ac1..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint02.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Stackalloc -// Regression test for FSHARP1.0:5595 -// stackalloc on imported types -//A generic construct requires that the type 'C' is an unmanaged type$ -//A generic construct requires that the type 'I' is an unmanaged type$ -//A generic construct requires that the type 'D' is an unmanaged type$ - -#nowarn "9" - -let _ = NativeInterop.NativePtr.stackalloc 1 -let _ = NativeInterop.NativePtr.stackalloc 1 -let _ = NativeInterop.NativePtr.stackalloc 1 diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint03.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint03.fs deleted file mode 100644 index a784a875f44..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/E_constraint03.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Regression #Libraries #Stackalloc -// Regression test for FSHARP1.0:5595 -// stackalloc on managed types (record and class) -//A generic construct requires that the type 'R' is an unmanaged type$ -//A generic construct requires that the type 'C' is an unmanaged type$ -#nowarn "9" - - type R = { A : int } - - type C() = class - member __.M = 10 - member __.N(x) = x + 1 - end - let data = NativeInterop.NativePtr.stackalloc 10 - let data2 = NativeInterop.NativePtr.stackalloc 10 diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/constraint01.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/constraint01.fs deleted file mode 100644 index e830655422f..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/constraint01.fs +++ /dev/null @@ -1,9 +0,0 @@ -// #Regression #Libraries #Stackalloc -// Regression test for FSHARP1.0:5595 -// stackalloc on imported types (C# struct and enum) -> OK -// - -let _ = NativeInterop.NativePtr.stackalloc 1 -let _ = NativeInterop.NativePtr.stackalloc 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/env.lst b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/env.lst index 1545ec101b8..96c34db48d5 100644 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/env.lst +++ b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/env.lst @@ -1,10 +1 @@ - SOURCE=constraint01.fs PRECMD="\$CSC_PIPE /target:library publictypes.cs" PEVER=/MD COMPILE_ONLY=1 SCFLAGS="-r:publictypes.dll" # constraint01.fs - SOURCE=E_constraint02.fs PRECMD="\$CSC_PIPE /target:library publictypes.cs" PEVER=/MD COMPILE_ONLY=1 SCFLAGS="-r:publictypes.dll --test:ErrorRanges" # E_constraint02.fs - SOURCE=E_constraint03.fs PEVER=/MD COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # E_constraint03.fs - SOURCE=negativesize01.fs PEVER=/MD COMPILE_ONLY=1 # negativesize01.fs - SOURCE=ofDateTime01.fs PEVER=/MD # ofDateTime01.fs - SOURCE=ofenum01.fs PEVER=/MD # ofenum01.fs - SOURCE=ofint01.fs PEVER=/MD # ofint01.fs - SOURCE=ofint6401.fs PEVER=/MD # ofint6401.fs - SOURCE=zerosize01.fs PEVER=/MD # zerosize01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofDateTime01.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofDateTime01.fs deleted file mode 100644 index 19c259bb0c7..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofDateTime01.fs +++ /dev/null @@ -1,27 +0,0 @@ -// #Libraries #Stackalloc -#nowarn "9" -module M3 = -// Regression test for FSHARP1.0: -// stackalloc -// - - let mutable noerr = true - - let data = NativeInterop.NativePtr.stackalloc 100 - let now = System.DateTime.Now - for i = 0 to 99 do - NativeInterop.NativePtr.set data i now - for i = 0 to 99 do - if not (NativeInterop.NativePtr.get data i = now) then - noerr <- false - - let later = now.AddDays 1. - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - datai <- later - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - if not (datai = later) then - noerr <- false - - (if noerr then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofenum01.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofenum01.fs deleted file mode 100644 index 885f3b88ac3..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofenum01.fs +++ /dev/null @@ -1,31 +0,0 @@ -// #Libraries #Stackalloc -#nowarn "9" -module M6 = -// Regression test for FSHARP1.0: -// stackalloc 10 -// - - type E = | A = 1 - | B = 2 - - let mutable noerr = true - - let data = NativeInterop.NativePtr.stackalloc 10 - - for i = 0 to 9 do - NativeInterop.NativePtr.set data i (if (i % 2)=0 then E.A else E.B) - - for i = 0 to 9 do - if not (NativeInterop.NativePtr.get data i = (if (i % 2)=0 then E.A else E.B)) then - noerr <- false - - for i = 0 to 9 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - datai <- (if (i % 2)=1 then E.A else E.B) - - for i = 0 to 9 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - if not (datai = (if (i % 2)=1 then E.A else E.B)) then - noerr <- false - - (if noerr then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint01.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint01.fs deleted file mode 100644 index e81be3fa1b2..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint01.fs +++ /dev/null @@ -1,29 +0,0 @@ -// #Libraries #Stackalloc -#nowarn "9" -// Regression test for FSHARP1.0: -// stackalloc -// -module M1 = - - let mutable noerr = true - - let data = NativeInterop.NativePtr.stackalloc 100 - - for i = 0 to 99 do - NativeInterop.NativePtr.set data i (i*i) - - for i = 0 to 99 do - if not (NativeInterop.NativePtr.get data i = (i*i)) then - noerr <- false - - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - datai <- 1-i - - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - if not (datai = 1-i) then - noerr <- false - - (if noerr then 0 else 1) |> exit - diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint6401.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint6401.fs deleted file mode 100644 index 401855c5de5..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/ofint6401.fs +++ /dev/null @@ -1,27 +0,0 @@ -// #Libraries #Stackalloc -#nowarn "9" -module M2 = -// Regression test for FSHARP1.0: -// stackalloc -// - let mutable noerr = true - - let data = NativeInterop.NativePtr.stackalloc 100 - - for i = 0 to 99 do - NativeInterop.NativePtr.set data i (int64 (i*i)) - for i = 0 to 99 do - if not (NativeInterop.NativePtr.get data i = (int64 (i*i))) then - noerr <- false - - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - datai <- int64 (1-i) - - for i = 0 to 99 do - let datai = NativeInterop.NativePtr.toByRef (NativeInterop.NativePtr.add data i) - if not (datai = int64 (1-i)) then - noerr <- false - - (if noerr then 0 else 1) |> exit - diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/publictypes.cs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/publictypes.cs deleted file mode 100644 index 004ae623ba8..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/publictypes.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Some public types - -public class C {} - -public enum E { } - -public struct S { } - -public interface I { } - -public delegate void D(); - diff --git a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/zerosize01.fs b/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/zerosize01.fs deleted file mode 100644 index a00cb54a8ba..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/NativeInterop/stackalloc/zerosize01.fs +++ /dev/null @@ -1,16 +0,0 @@ -// #Libraries #Stackalloc -#nowarn "9" -module M4 = -// Regression test for FSHARP1.0: -// stackalloc 0 -// - - // check stackalloc 0 -- ok - let data = NativeInterop.NativePtr.stackalloc 0 - - // The returned pointer is undefined - // No allocation should happen - let q = NativeInterop.NativePtr.toNativeInt data - - - exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs deleted file mode 100644 index 76687657876..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/AbsOnIntegers01.fs +++ /dev/null @@ -1,15 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:3470 - exception on abs of native integer - -#light - -let res = - abs -1y = 1y // signed byte - && abs -1s = 1s // int16 - && abs -1l = 1l // int32 - && abs -1n = 1n // nativeint - && abs -1L = 1L // int64 - && abs -1I = 1I // bigint - -if not res then exit 1 -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs deleted file mode 100644 index a79a04119b2..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/CastOperator.fs +++ /dev/null @@ -1,11 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:1247 -// Precedence of type annotations :> and :?> over preceeding expression forms, e.g. if-then-else etc. -// - -open System -let x = 2 :> Object -let y = [(2 :> Object)] -let z = [2 :> Object] - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs deleted file mode 100644 index 46f3d2cd725..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/E_EqualityAndHash01.fs +++ /dev/null @@ -1,8 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:5436 -// You should not be able to hash F# function values) -// Note: most positive cases already covered under fsharp\typecheck\sigs -// I'm adding this simple one since I did not see it there. -//The type '\('a -> 'a\)' does not support the 'equality' constraint because it is a function type - -let q = hash id diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs deleted file mode 100644 index 7a368182e02..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/E_sign02.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Operators -// Test sign function on unsigned primitives, should get error. - -//The type 'byte' does not support the operator 'get_Sign'$ -//The type 'uint16' does not support the operator 'get_Sign'$ -//The type 'uint32' does not support the operator 'get_Sign'$ -//The type 'uint64' does not support the operator 'get_Sign'$ - -if sign 0uy <> 0 then exit 1 // byte -if sign 0us <> 0 then exit 1 // int16 -if sign 0u <> 0 then exit 1 // int32 -if sign 0uL <> 0 then exit 1 // int64 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs deleted file mode 100644 index 7ae622955eb..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/EqualityAndUncheckedHash01.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:5436 -// You should not be able to hash F# function values -// Note: most positive cases already covered under fsharp\typecheck\sigs -// I'm adding this simple one since I did not see it there. -// -module TestModule - -// This is ok (unchecked) -let p = Unchecked.hash id diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs deleted file mode 100644 index f54171f6ccf..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/Pow_Constrains.fs +++ /dev/null @@ -1,16 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:4487 -// Feature request: loosen Pow operator constraints - -type T(x : float, y : float) = - static let mutable m = false - static member Pow (g: T, e: float) = m <- true - g - static member Check() = m - -let t = new T(1.,2.) - -let c = t ** 3. // OK! - -exit <| if T.Check() then 0 else 1 - diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs deleted file mode 100644 index 7fd2ceccddb..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/StringOnEnum01.fs +++ /dev/null @@ -1,68 +0,0 @@ -// #Regression #Libraries #Operators -// Regression for FSHARP1.0:5995 -// Calling "string" on an enum results in the integer value rather than the ToString name (possibly other static optimization issues?) - -module M - -// int32 -type Foo = - | A = 1 - | B = 2 - -let a = Foo.A -let r = a :> System.IFormattable -if (string a) <> (string r) then exit 1 - -// uint32 -type Foo2 = - | A = 3u - | B = 4u - -let a2 = Foo2.A -let r2 = a :> System.IFormattable -if (string a2) <> (string r2) then exit 1 - -// char : see FSHARP1.0:6228 -//type Foo3 = -// | A = 'a' -// | B = 'b' - -//let a3 = Foo3.A -//let r3 = a :> System.IFormattable -//if (string a3) <> (string r3) then exit 1 - -// int16 -type Foo4 = - | A = 1s - | B = 2s - -let a4 = Foo4.A -let r4 = a :> System.IFormattable -if (string a4) <> (string r4) then exit 1 - -// uint16 -type Foo5 = - | A = 1us - | B = 2us - -let a5 = Foo5.A -let r5 = a :> System.IFormattable -if (string a5) <> (string r5) then exit 1 - -// sbyte -type Foo6 = - | A = 1y - | B = 2y - -let a6 = Foo6.A -let r6 = a :> System.IFormattable -if (string a6) <> (string r6) then exit 1 - -// byte -type Foo7 = - | A = 1uy - | B = 2uy - -let a7 = Foo7.A -let r7 = a :> System.IFormattable -if (string a7) <> (string r7) then exit 1 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs deleted file mode 100644 index 60ec1eb5da6..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/e_AbsOnIntegers02.fs +++ /dev/null @@ -1,17 +0,0 @@ -// #Regression #Libraries #Operators -// Regression test for FSHARP1.0:3470 - exception on abs of native integer -//The type 'byte' does not support the operator 'Abs'$ -//The type 'uint16' does not support the operator 'Abs'$ -//The type 'uint32' does not support the operator 'Abs'$ -//The type 'uint32' does not support the operator 'Abs'$ -//The type 'unativeint' does not support the operator 'Abs'$ -//The type 'uint64' does not support the operator 'Abs'$ -//The type 'uint64' does not support the operator 'Abs'$ - -abs -1uy // byte -abs -1us // uint16 -abs -1ul // uint32 -abs -1u // uint32 -abs -1un // unativeint -abs -1uL // uint64 -abs -1UL // uint64 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst b/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst deleted file mode 100644 index 3b893973508..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/env.lst +++ /dev/null @@ -1,13 +0,0 @@ - SOURCE=Pow_Constrains.fs SCFLAGS=--warnaserror # Pow_Constrains.fs - SOURCE=sign01.fs # sign01.fs - SOURCE=E_sign02.fs SCFLAGS=--test:ErrorRanges # E_sign02.fs - SOURCE=round01.fs # round01.fs - SOURCE=string01.fs # string01.fs - SOURCE=AbsOnIntegers01.fs # AbsOnIntegers01.fs - SOURCE=E_AbsOnIntegers02.fs SCFLAGS="--test:ErrorRanges --nowarn:20" # E_AbsOnIntegers02.fs - SOURCE=CastOperator.fs # CastOperator.fs - - SOURCE=EqualityAndUncheckedHash01.fs SCFLAGS=-a # EqualityAndUncheckedHash01.fs - SOURCE=E_EqualityAndHash01.fs SCFLAGS=--test:ErrorRanges # E_EqualityAndHash01.fs - - SOURCE=StringOnEnum01.fs # StringOnEnum01.fs \ No newline at end of file diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs deleted file mode 100644 index a9287100a85..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/round01.fs +++ /dev/null @@ -1,60 +0,0 @@ -// #Libraries #Operators -#light - -// Test the round function - -// Identity -for i in [1 .. 10000] do - if i |> float |> round <> float i then exit 1 - if i |> float32 |> round <> float32 i then exit 1 - if i |> decimal |> round <> decimal i then exit 1 - -// Round down -if round 1.1 <> 1.0 then exit 1 -if round 1.2 <> 1.0 then exit 1 -if round 1.3 <> 1.0 then exit 1 -if round 1.4 <> 1.0 then exit 1 - -if round 1.1f <> 1.0f then exit 1 -if round 1.2f <> 1.0f then exit 1 -if round 1.3f <> 1.0f then exit 1 -if round 1.4f <> 1.0f then exit 1 - -if round 1.1m <> 1.0m then exit 1 -if round 1.2m <> 1.0m then exit 1 -if round 1.3m <> 1.0m then exit 1 -if round 1.4m <> 1.0m then exit 1 - -// Round down -if round 1.6 <> 2.0 then exit 1 -if round 1.7 <> 2.0 then exit 1 -if round 1.8 <> 2.0 then exit 1 -if round 1.9 <> 2.0 then exit 1 - -if round 1.6f <> 2.0f then exit 1 -if round 1.7f <> 2.0f then exit 1 -if round 1.8f <> 2.0f then exit 1 -if round 1.9f <> 2.0f then exit 1 - -if round 1.6m <> 2.0m then exit 1 -if round 1.7m <> 2.0m then exit 1 -if round 1.8m <> 2.0m then exit 1 -if round 1.9m <> 2.0m then exit 1 - -// Midpoint rounding. If between two numbers, round to the 'even' one. - -if round 1.5 <> 2.0 then exit 1 -if round 1.5f <> 2.0f then exit 1 -if round 1.5m <> 2.0m then exit 1 - -if round 2.5 <> 2.0 then exit 1 -if round 2.5f <> 2.0f then exit 1 -if round 2.5m <> 2.0m then exit 1 - -// If not midpoint, round to nearest as usual - -if round 2.500001 <> 3.0 then exit 1 -if round 2.500001f <> 3.0f then exit 1 -if round 2.500001m <> 3.0m then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs deleted file mode 100644 index f181ba4ca89..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/sign01.fs +++ /dev/null @@ -1,34 +0,0 @@ -// #Libraries #Operators -#light - -// Test the 'sign' library function - -// Positive sign -if sign 1y <> 1 then exit 1 // byte -if sign 1s <> 1 then exit 1 // int16 -if sign 1 <> 1 then exit 1 // int32 -if sign 1L <> 1 then exit 1 // int64 -if sign 1.0f <> 1 then exit 1 // float -if sign 1.0 <> 1 then exit 1 // double -if sign 1.0m <> 1 then exit 1 // decimal - -// Zero -if sign 0y <> 0 then exit 1 // byte -if sign 0s <> 0 then exit 1 // int16 -if sign 0 <> 0 then exit 1 // int32 -if sign 0L <> 0 then exit 1 // int64 -if sign 0.0f <> 0 then exit 1 // float -if sign 0.0 <> 0 then exit 1 // double -if sign 0.0m <> 0 then exit 1 // decimal - -// Negative sign -if sign -1y <> -1 then exit 1 // byte -if sign -1s <> -1 then exit 1 // int16 -if sign -1 <> -1 then exit 1 // int32 -if sign -1L <> -1 then exit 1 // int64 -if sign -1.0f <> -1 then exit 1 // float -if sign -1.0 <> -1 then exit 1 // double -if sign -1.0m <> -1 then exit 1 // decimal - -// All clear! -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs b/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs deleted file mode 100644 index 881cd5c28a2..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Operators/string01.fs +++ /dev/null @@ -1,44 +0,0 @@ -// #Regression #Libraries #Operators -open System - -// Regression test for FSHARP1.0:3977 - Make "string" function work for decimal and user-defined IFormattable types. - -type CalcSum(x : int, y: int) = - let mutable x = x - let mutable y = y - - member this.Sum () = x + y - - interface IFormattable with - member x.ToString (format: string, provider : IFormatProvider) = - match format with - | null | "" - | "g" | "G" -> - String.Format("X + Y = {0}", x.Sum()) - | "s" | "S" -> - // Short form - x.Sum().ToString() - | _ -> - invalidArg format "Format is wrong!" - - override x.ToString() = (x :> IFormattable).ToString(null, null) - -let calc = CalcSum(10, 20) - -// test string function -match string calc with -| "X + Y = 30" -> () -| _ -> exit 1 - -// test with Console.WriteLine -try - printfn "%s" (calc.ToString()) - Console.WriteLine("{0:S}", calc) - Console.Write("{0} {1} {2:D}", 10, 20, calc) -with - | :? ArgumentException as e -> - match e.ParamName with - | "D" -> exit 0 - | _ -> exit 2 - -exit 1 diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs deleted file mode 100644 index 21c9ad64d92..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/DU.fs +++ /dev/null @@ -1,8 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 - -type MyT = MyC of int * string * bool - -let DU = MyC (1,"2",true) - -(if (sprintf "%A" DU) = "MyC (1,\"2\",true)" then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs deleted file mode 100644 index 0b179241cec..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor01.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 -// MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler - -let test1 = try - Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box 12; box "text" |] |> ignore - true - with - | _ -> false - - -(if test1 then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs deleted file mode 100644 index 50b1d7bad63..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/PreComputeTupleConstructor02.fs +++ /dev/null @@ -1,12 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 -// MT DCR: Reflection.FSharpValue.PreComputeTupleConstructor fails when executed for NetFx 2.0 by a Dev10 compiler - -let test1 = try - Reflection.FSharpValue.PreComputeTupleConstructor(typeof) [| box "text"; box 12; |] |> ignore - false - with - | _ -> true // yes, we expect the call above to throw since the types are swapped! - - -(if test1 then 0 else 1) |> exit diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs b/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs deleted file mode 100644 index 8c780033a77..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/Record.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Libraries #Reflection -// Regression test for FSHARP1.0:5113 - -type MyR = {c:int;b:int;a:int} - -let s1 = sprintf "%A" {a=1;b=2;c=3} -let s2 = sprintf "%A" {c=3;b=2;a=1} - -(if s1 = s2 then 0 else 1) |> exit - diff --git a/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst b/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst deleted file mode 100644 index bf3361d68e3..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Reflection/env.lst +++ /dev/null @@ -1,4 +0,0 @@ - SOURCE=DU.fs # DU.fs - SOURCE=PreComputeTupleConstructor01.fs # PreComputeTupleConstructor01.fs - SOURCE=PreComputeTupleConstructor02.fs # PreComputeTupleConstructor02.fs - SOURCE=Record.fs # Record.fs diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs b/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs deleted file mode 100644 index 196448fc4bf..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf01.fs +++ /dev/null @@ -1,51 +0,0 @@ -// #Regression #Libraries #Unchecked -#light - -// 1760, Implement Unchecked.defaultof<_> (delete LanguagePrimitives.DefaultValueUnchecked) - -// Test the 'defaultof<_>' function - -// Reference types --------------------------- -type DUType = - | A - | B of int - | C of DUType * DUType - -type RecordType = { A : int; B : string; C : DUType } - -type ClassType = string - -type InterfaceType = - abstract DoStuff : unit -> unit - -// Stack types ------------------------------- -type EnumType = - | A = 1 - | B = 2 - | C = 4 - -type StructType = struct - val m_ivalue : int - val m_svalue : string - member this.IValue = this.m_ivalue - member this.SValue = this.m_svalue -end - -// Test reference types -if Unchecked.defaultof <> null then exit 1 -// This behaivor for DU, Records, and Interfaces is bey design (need to box to get null) -if box(Unchecked.defaultof) <> null then exit 1 -if box(Unchecked.defaultof) <> null then exit 1 -if box(Unchecked.defaultof) <> null then exit 1 - -let p = Unchecked.defaultof - -// Test stack types -if Unchecked.defaultof <> 0 then exit 1 -if Unchecked.defaultof <> 0.0 then exit 1 -if Unchecked.defaultof <> enum 0 then exit 1 - -if (Unchecked.defaultof).IValue <> 0 then exit 1 -if (Unchecked.defaultof).SValue <> null then exit 1 - -exit 0 diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs b/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs deleted file mode 100644 index 00414dd8cc8..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/DefaultOf02.fs +++ /dev/null @@ -1,17 +0,0 @@ -// #Regression #Libraries #Unchecked -#light - -// FSharp1.0:5417 - Unchecked.defaultof<_> on records/unions can cause structural equality check to throw -// Check that Unchecked.defaultof<_> works correctly on various types, mostly structs/unions/records - -type R = { x : int; y : string } -type U = | A of int | B of string -type S = struct val mutable x : int end -type C() = class end - -let shouldBeTrue = - Unchecked.defaultof = Unchecked.defaultof // Records as null - && Unchecked.defaultof = Unchecked.defaultof // Unions as null - && Unchecked.defaultof = Unchecked.defaultof // Structs as null - && Unchecked.defaultof = Unchecked.defaultof // Classes as null - && Unchecked.defaultof = Unchecked.defaultof diff --git a/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst b/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst deleted file mode 100644 index b5cefff3c2e..00000000000 --- a/tests/fsharpqa/Source/Libraries/Core/Unchecked/env.lst +++ /dev/null @@ -1,2 +0,0 @@ - SOURCE=DefaultOf01.fs # DefaultOf01 - SOURCE=DefaultOf02.fs # DefaultOf02 \ No newline at end of file diff --git a/tests/fsharpqa/Source/OCamlCompat/env.lst b/tests/fsharpqa/Source/OCamlCompat/env.lst index d8cb2ea092b..e9ade14c1a2 100644 --- a/tests/fsharpqa/Source/OCamlCompat/env.lst +++ b/tests/fsharpqa/Source/OCamlCompat/env.lst @@ -3,8 +3,6 @@ SOURCE=W_mlExtention03.ml COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # W_mlExtention03.ml SOURCE=E_IndentOff01.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror --test:ErrorRanges" # E_IndentOff01.fs - SOURCE=IndentOff02.fs COMPILE_ONLY=1 SCFLAGS="--warnaserror --mlcompatibility" # IndentOff02.fs - SOURCE=W_IndentOff03.fs COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" # W_IndentOff03.fs NoMT SOURCE=IndentOff04.fsx COMPILE_ONLY=1 SCFLAGS="--warnaserror --mlcompatibility" FSIMODE=PIPE # IndentOff04.fsx NoMT SOURCE=W_IndentOff05.fsx COMPILE_ONLY=1 SCFLAGS="--test:ErrorRanges" FSIMODE=PIPE # W_IndentOff05.fsx NoMT SOURCE=E_IndentOff06.fsx COMPILE_ONLY=1 SCFLAGS="--warnaserror" FSIMODE=PIPE # E_IndentOff06.fsx diff --git a/tests/fsharpqa/Source/Optimizations/CompareIL.cmd b/tests/fsharpqa/Source/Optimizations/CompareIL.cmd index 0462386d285..b8d70002021 100644 --- a/tests/fsharpqa/Source/Optimizations/CompareIL.cmd +++ b/tests/fsharpqa/Source/Optimizations/CompareIL.cmd @@ -1,9 +1,17 @@ REM == %1 --> assembly ildasm /TEXT /LINENUM /NOBAR "%~nx1" >"%~n1.il" -IF NOT ERRORLEVEL 0 exit 1 +IF %ERRORLEVEL% NEQ 0 exit /b 1 -echo ..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" -..\..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" -exit /b %ERRORLEVEL% +echo %~dp0..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" + %~dp0..\..\testenv\bin\ILComparer.exe "%~n1.il.bsl" "%~n1.il" + +IF %ERRORLEVEL% EQU 0 exit /b 0 + +if /i "%TEST_UPDATE_BSL%" == "1" ( + echo copy /y "%~n1.il" "%~n1.il.bsl" + copy /y "%~n1.il" "%~n1.il.bsl" +) + +exit /b 1 diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnArray01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnArray01.il.bsl index 38b3a3aa80c..46d1b653558 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnArray01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnArray01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ForEachOnArray01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ForEachOnArray01 { - // Offset: 0x00000000 Length: 0x000001E0 + // Offset: 0x00000000 Length: 0x000001DC } .mresource public FSharpOptimizationData.ForEachOnArray01 { - // Offset: 0x000001E8 Length: 0x0000007C + // Offset: 0x000001E0 Length: 0x0000007C } .module ForEachOnArray01.dll -// MVID: {59B18AEE-7E2E-D3AE-A745-0383EE8AB159} +// MVID: {60BE1F17-7E2E-D3AE-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00D00000 +// Image base: 0x06F50000 // =============== CLASS MEMBERS DECLARATION =================== @@ -59,7 +59,7 @@ [1] int32 V_1, [2] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 6,23 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\ForEachOnArray01.fs' + .line 6,6 : 6,23 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\ForEachOnArray01.fs' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 7,7 : 6,21 '' diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnList01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnList01.il.bsl index 14d6a854963..3621bd1889e 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnList01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnList01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly ForEachOnList01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.ForEachOnList01 { - // Offset: 0x00000000 Length: 0x000002ED + // Offset: 0x00000000 Length: 0x000002E9 } .mresource public FSharpOptimizationData.ForEachOnList01 { - // Offset: 0x000002F8 Length: 0x000000DB + // Offset: 0x000002F0 Length: 0x000000DB } .module ForEachOnList01.dll -// MVID: {59B18AEE-56DF-F74F-A745-0383EE8AB159} +// MVID: {60BE1F17-56DF-F74F-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x06EA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +59,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit test6@38 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class ForEachOnList01/test6@38 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -72,18 +78,29 @@ // Code size 4 (0x4) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 39,39 : 21,26 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\ForEachOnList01.fs' + .line 39,39 : 21,26 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\ForEachOnList01.fs' IL_0000: ldarg.1 IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret } // end of method test6@38::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void ForEachOnList01/test6@38::.ctor() + IL_0005: stsfld class ForEachOnList01/test6@38 ForEachOnList01/test6@38::@_instance + IL_000a: ret + } // end of method test6@38::.cctor + } // end of class test6@38 .class auto ansi serializable sealed nested assembly beforefieldinit test7@47 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class ForEachOnList01/test7@47 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -108,6 +125,16 @@ IL_0003: ret } // end of method test7@47::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void ForEachOnList01/test7@47::.ctor() + IL_0005: stsfld class ForEachOnList01/test7@47 ForEachOnList01/test7@47::@_instance + IL_000a: ret + } // end of method test7@47::.cctor + } // end of class test7@47 .method public static void test1(class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 lst) cil managed @@ -362,7 +389,7 @@ IL_002e: ldstr "%A" IL_0033: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_0038: stloc.s V_4 - IL_003a: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_003a: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_003f: ldloc.s V_4 IL_0041: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -390,7 +417,7 @@ [2] int32 i, [3] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_3) .line 36,40 : 5,21 '' - IL_0000: newobj instance void ForEachOnList01/test6@38::.ctor() + IL_0000: ldsfld class ForEachOnList01/test6@38 ForEachOnList01/test6@38::@_instance IL_0005: ldc.i4.1 IL_0006: ldc.i4.2 IL_0007: ldc.i4.3 @@ -424,7 +451,7 @@ IL_003c: ldstr "%O" IL_0041: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_0046: stloc.3 - IL_0047: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0047: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_004c: ldloc.3 IL_004d: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -453,7 +480,7 @@ [3] int32 tmp, [4] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_4) .line 45,49 : 5,21 '' - IL_0000: newobj instance void ForEachOnList01/test7@47::.ctor() + IL_0000: ldsfld class ForEachOnList01/test7@47 ForEachOnList01/test7@47::@_instance IL_0005: ldc.i4.1 IL_0006: ldc.i4.2 IL_0007: ldc.i4.3 @@ -493,7 +520,7 @@ IL_0040: ldstr "%O" IL_0045: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,int32>::.ctor(string) IL_004a: stloc.s V_4 - IL_004c: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_004c: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0051: ldloc.s V_4 IL_0053: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnString01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnString01.il.bsl index 0db8de85fcc..0724c4fc823 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnString01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/ForEachOnString01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly ForEachOnString01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.ForEachOnString01 { - // Offset: 0x00000000 Length: 0x00000354 + // Offset: 0x00000000 Length: 0x00000350 } .mresource public FSharpOptimizationData.ForEachOnString01 { // Offset: 0x00000358 Length: 0x000000FF } .module ForEachOnString01.dll -// MVID: {59B18AEE-105C-852B-A745-0383EE8AB159} +// MVID: {60BE1F17-105C-852B-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x057C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -54,6 +59,7 @@ .class auto ansi serializable sealed nested assembly beforefieldinit test8@54 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class ForEachOnString01/test8@54 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -72,7 +78,7 @@ // Code size 6 (0x6) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 55,55 : 21,39 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\ForEachOnString01.fs' + .line 55,55 : 21,39 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\ForEachOnString01.fs' IL_0000: ldarg.1 IL_0001: conv.i4 IL_0002: ldc.i4.1 @@ -81,11 +87,22 @@ IL_0005: ret } // end of method test8@54::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void ForEachOnString01/test8@54::.ctor() + IL_0005: stsfld class ForEachOnString01/test8@54 ForEachOnString01/test8@54::@_instance + IL_000a: ret + } // end of method test8@54::.cctor + } // end of class test8@54 .class auto ansi serializable sealed nested assembly beforefieldinit test9@63 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { + .field static assembly initonly class ForEachOnString01/test9@63 @_instance .method assembly specialname rtspecialname instance void .ctor() cil managed { @@ -112,6 +129,16 @@ IL_0005: ret } // end of method test9@63::Invoke + .method private specialname rtspecialname static + void .cctor() cil managed + { + // Code size 11 (0xb) + .maxstack 10 + IL_0000: newobj instance void ForEachOnString01/test9@63::.ctor() + IL_0005: stsfld class ForEachOnString01/test9@63 ForEachOnString01/test9@63::@_instance + IL_000a: ret + } // end of method test9@63::.cctor + } // end of class test9@63 .method public static void test1(string str) cil managed @@ -140,7 +167,7 @@ .line 9,9 : 6,21 '' IL_0011: ldarg.0 IL_0012: ldloc.2 - IL_0013: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0013: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0018: stloc.3 IL_0019: ldloc.0 IL_001a: ldloc.3 @@ -187,7 +214,7 @@ .line 14,14 : 6,23 '' IL_0015: ldstr "123" IL_001a: ldloc.2 - IL_001b: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_001b: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0020: stloc.3 IL_0021: ldloc.0 IL_0022: ldloc.3 @@ -234,7 +261,7 @@ .line 20,20 : 6,20 '' IL_0015: ldstr "123" IL_001a: ldloc.2 - IL_001b: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_001b: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0020: stloc.3 IL_0021: ldloc.0 IL_0022: ldloc.3 @@ -281,7 +308,7 @@ .line 26,26 : 6,20 '' IL_0015: ldstr "123" IL_001a: ldloc.2 - IL_001b: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_001b: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0020: stloc.3 IL_0021: ldloc.0 IL_0022: ldloc.3 @@ -325,12 +352,12 @@ .line 31,31 : 6,20 '' IL_0013: ldstr "123" IL_0018: ldloc.1 - IL_0019: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0019: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_001e: stloc.2 IL_001f: ldstr "%A" IL_0024: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,char>::.ctor(string) IL_0029: stloc.3 - IL_002a: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_002a: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_002f: ldloc.3 IL_0030: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -377,7 +404,7 @@ .line 41,41 : 6,21 '' IL_0011: ldarg.0 IL_0012: ldloc.2 - IL_0013: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0013: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0018: stloc.3 IL_0019: ldloc.0 IL_001a: ldloc.3 @@ -424,7 +451,7 @@ .line 47,47 : 6,20 '' IL_0015: ldstr "123" IL_001a: ldloc.2 - IL_001b: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_001b: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0020: stloc.3 IL_0021: ldloc.0 IL_0022: ldloc.3 @@ -455,7 +482,7 @@ [3] char i, [4] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_4) .line 53,55 : 17,40 '' - IL_0000: newobj instance void ForEachOnString01/test8@54::.ctor() + IL_0000: ldsfld class ForEachOnString01/test8@54 ForEachOnString01/test8@54::@_instance IL_0005: ldstr "1234" IL_000a: call string [FSharp.Core]Microsoft.FSharp.Core.StringModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, string) @@ -475,12 +502,12 @@ .line 52,56 : 5,21 '' IL_001f: ldloc.0 IL_0020: ldloc.2 - IL_0021: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0021: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0026: stloc.3 IL_0027: ldstr "%O" IL_002c: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,char>::.ctor(string) IL_0031: stloc.s V_4 - IL_0033: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0033: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0038: ldloc.s V_4 IL_003a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) @@ -512,7 +539,7 @@ [4] string tmp, [5] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_5) .line 62,64 : 17,40 '' - IL_0000: newobj instance void ForEachOnString01/test9@63::.ctor() + IL_0000: ldsfld class ForEachOnString01/test9@63 ForEachOnString01/test9@63::@_instance IL_0005: ldstr "1234" IL_000a: call string [FSharp.Core]Microsoft.FSharp.Core.StringModule::Map(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, string) @@ -532,7 +559,7 @@ .line 61,65 : 5,21 '' IL_001f: ldloc.0 IL_0020: ldloc.2 - IL_0021: callvirt instance char [mscorlib]System.String::get_Chars(int32) + IL_0021: callvirt instance char [netstandard]System.String::get_Chars(int32) IL_0026: stloc.3 .line 66,66 : 9,53 '' IL_0027: ldstr "{0} foo" @@ -545,7 +572,7 @@ IL_0039: ldstr "%O" IL_003e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string>::.ctor(string) IL_0043: stloc.s V_5 - IL_0045: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0045: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_004a: ldloc.s V_5 IL_004c: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter>(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/NoAllocationOfTuple01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/NoAllocationOfTuple01.il.bsl index 4dd6df631f0..86b17c9f28d 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/NoAllocationOfTuple01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/NoAllocationOfTuple01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly NoAllocationOfTuple01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.NoAllocationOfTuple01 { - // Offset: 0x00000000 Length: 0x000001E0 + // Offset: 0x00000000 Length: 0x000001DC } .mresource public FSharpOptimizationData.NoAllocationOfTuple01 { - // Offset: 0x000001E8 Length: 0x00000085 + // Offset: 0x000001E0 Length: 0x00000085 } .module NoAllocationOfTuple01.dll -// MVID: {59B18AEE-13B5-F699-A745-0383EE8AB159} +// MVID: {60BE1F17-13B5-F699-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03460000 +// Image base: 0x08DC0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,7 +60,7 @@ [2] int32 V_2, [3] int32 j) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 5,31 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\NoAllocationOfTuple01.fs' + .line 6,6 : 5,31 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\NoAllocationOfTuple01.fs' IL_0000: ldarg.0 IL_0001: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::ZeroCreate(int32) IL_0006: stloc.0 diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable01.il.bsl index 41dcfaf2ed2..f3218f9ca6a 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly NoIEnumerable01 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.NoIEnumerable01 { - // Offset: 0x00000000 Length: 0x000001D1 + // Offset: 0x00000000 Length: 0x000001CD } .mresource public FSharpOptimizationData.NoIEnumerable01 { // Offset: 0x000001D8 Length: 0x0000006C } .module NoIEnumerable01.dll -// MVID: {59B18AEE-31A1-8DCB-A745-0383EE8AB159} +// MVID: {60BE1F17-31A1-8DCB-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x013E0000 +// Image base: 0x06B80000 // =============== CLASS MEMBERS DECLARATION =================== @@ -59,7 +64,7 @@ [1] int32 i, [2] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 4,22 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\NoIEnumerable01.fsx' + .line 7,7 : 4,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\NoIEnumerable01.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.1 IL_0002: ldarg.0 @@ -72,7 +77,7 @@ IL_0008: ldstr "aaa" IL_000d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_0012: stloc.2 - IL_0013: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0013: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0018: ldloc.2 IL_0019: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable02.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable02.il.bsl index 12424f0aa91..1076cf2598b 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly NoIEnumerable02 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.NoIEnumerable02 { - // Offset: 0x00000000 Length: 0x000001D1 + // Offset: 0x00000000 Length: 0x000001CD } .mresource public FSharpOptimizationData.NoIEnumerable02 { // Offset: 0x000001D8 Length: 0x0000006C } .module NoIEnumerable02.dll -// MVID: {59B18AEE-5066-4012-A745-0383EE8AB159} +// MVID: {60BE1F17-5066-4012-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00720000 +// Image base: 0x05170000 // =============== CLASS MEMBERS DECLARATION =================== @@ -59,7 +64,7 @@ [1] int32 i, [2] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 4,24 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\NoIEnumerable02.fsx' + .line 7,7 : 4,24 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\NoIEnumerable02.fsx' IL_0000: ldc.i4.s 100 IL_0002: stloc.1 IL_0003: ldarg.0 @@ -72,7 +77,7 @@ IL_0009: ldstr "aaa" IL_000e: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_0013: stloc.2 - IL_0014: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0014: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0019: ldloc.2 IL_001a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable03.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable03.il.bsl index 7223d4a04bd..dc81a5ebb66 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable03.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/NoIEnumerable03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly NoIEnumerable03 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.NoIEnumerable03 { - // Offset: 0x00000000 Length: 0x000001DF + // Offset: 0x00000000 Length: 0x000001DB } .mresource public FSharpOptimizationData.NoIEnumerable03 { - // Offset: 0x000001E8 Length: 0x0000006C + // Offset: 0x000001E0 Length: 0x0000006C } .module NoIEnumerable03.dll -// MVID: {59B18AEE-7903-6020-A745-0383EE8AB159} +// MVID: {60BE1F17-7903-6020-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01970000 +// Image base: 0x069A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -61,7 +66,7 @@ [1] int32 i, [2] class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 4,22 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\NoIEnumerable03.fsx' + .line 7,7 : 4,22 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\NoIEnumerable03.fsx' IL_0000: ldarg.0 IL_0001: stloc.1 IL_0002: ldarg.1 @@ -74,7 +79,7 @@ IL_0008: ldstr "aaa" IL_000d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_0012: stloc.2 - IL_0013: call class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out() + IL_0013: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out() IL_0018: ldloc.2 IL_0019: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatLineToTextWriter(class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength01.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength01.il.bsl index a27da5651f5..c8029558865 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ZeroToArrLength01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ZeroToArrLength01 { - // Offset: 0x00000000 Length: 0x000001E0 + // Offset: 0x00000000 Length: 0x000001DC } .mresource public FSharpOptimizationData.ZeroToArrLength01 { - // Offset: 0x000001E8 Length: 0x0000007B + // Offset: 0x000001E0 Length: 0x0000007B } .module ZeroToArrLength01.dll -// MVID: {59B18AEE-A3D0-03A7-A745-0383EE8AB159} +// MVID: {60BE1F17-A3D0-03A7-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02E70000 +// Image base: 0x06B20000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,7 +57,7 @@ .maxstack 5 .locals init ([0] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 5,35 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\ZeroToArrLength01.fs' + .line 6,6 : 5,35 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\ZeroToArrLength01.fs' IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0010 diff --git a/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength02.il.bsl b/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength02.il.bsl index eedc9d7bee3..2d3d3f44e26 100644 --- a/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/ForLoop/ZeroToArrLength02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly ZeroToArrLength02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.ZeroToArrLength02 { - // Offset: 0x00000000 Length: 0x000001E0 + // Offset: 0x00000000 Length: 0x000001DC } .mresource public FSharpOptimizationData.ZeroToArrLength02 { - // Offset: 0x000001E8 Length: 0x0000007B + // Offset: 0x000001E0 Length: 0x0000007B } .module ZeroToArrLength02.dll -// MVID: {59B18AEE-A36B-03A7-A745-0383EE8AB159} +// MVID: {60BE1F17-A36B-03A7-A745-0383171FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01550000 +// Image base: 0x05860000 // =============== CLASS MEMBERS DECLARATION =================== @@ -53,32 +53,40 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static void f1(int32[] arr) cil managed { - // Code size 23 (0x17) + // Code size 34 (0x22) .maxstack 5 - .locals init ([0] int32 i) + .locals init ([0] int32 V_0, + [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 5,41 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\ForLoop\\ZeroToArrLength02.fs' + .line 6,6 : 5,41 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\ForLoop\\ZeroToArrLength02.fs' IL_0000: ldc.i4.0 - IL_0001: stloc.0 - IL_0002: br.s IL_0010 + IL_0001: stloc.1 + IL_0002: ldarg.0 + IL_0003: call int32 [FSharp.Core]Microsoft.FSharp.Collections.ArrayModule::Length(!!0[]) + IL_0008: ldc.i4.1 + IL_0009: sub + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldloc.1 + IL_000d: blt.s IL_0021 .line 7,7 : 9,21 '' - IL_0004: ldarg.0 - IL_0005: ldloc.0 - IL_0006: ldloc.0 - IL_0007: stelem [mscorlib]System.Int32 - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: add - IL_000f: stloc.0 + IL_000f: ldarg.0 + IL_0010: ldloc.1 + IL_0011: ldloc.1 + IL_0012: stelem [mscorlib]System.Int32 + IL_0017: ldloc.1 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.1 .line 6,6 : 5,41 '' - IL_0010: ldloc.0 - IL_0011: ldarg.0 - IL_0012: ldlen - IL_0013: conv.i4 - IL_0014: blt.s IL_0004 + IL_001b: ldloc.1 + IL_001c: ldloc.0 + IL_001d: ldc.i4.1 + IL_001e: add + IL_001f: bne.un.s IL_000f - IL_0016: ret + IL_0021: ret } // end of method ZeroToArrLength02::f1 } // end of class ZeroToArrLength02 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare01.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare01.il.bsl index 974905405eb..3b7ce524486 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare01 { - // Offset: 0x00000000 Length: 0x00000225 + // Offset: 0x00000000 Length: 0x00000221 } .mresource public FSharpOptimizationData.Compare01 { - // Offset: 0x00000230 Length: 0x000000B2 + // Offset: 0x00000228 Length: 0x000000B2 } .module Compare01.dll -// MVID: {59B18AEE-04A0-F88E-A745-0383EE8AB159} +// MVID: {611C550D-04A0-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00FF0000 +// Image base: 0x09070000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,7 +63,7 @@ [1] int32 i, [2] int32 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare01.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare01.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 9,9 : 8,32 '' @@ -76,6 +76,7 @@ IL_0007: ldc.i4.1 IL_0008: cgt IL_000a: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_000b: ldloc.2 IL_000c: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare02.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare02.il.bsl index 74bd16af665..f9763f7b1b8 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare02 { - // Offset: 0x00000000 Length: 0x0000022C + // Offset: 0x00000000 Length: 0x00000228 } .mresource public FSharpOptimizationData.Compare02 { // Offset: 0x00000230 Length: 0x000000B9 } .module Compare02.dll -// MVID: {59B18AEE-0481-F88E-A745-0383EE8AB159} +// MVID: {611C550D-0481-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00BA0000 +// Image base: 0x05530000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare02.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare02.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 8,8 : 8,32 '' @@ -77,6 +77,7 @@ IL_0007: ldc.i4.1 IL_0008: cgt IL_000a: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_000b: ldloc.2 IL_000c: brfalse.s IL_0012 @@ -91,6 +92,7 @@ IL_0013: ldc.i4.2 IL_0014: cgt IL_0016: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0017: ldloc.3 IL_0018: brfalse.s IL_001e diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare03.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare03.il.bsl index c31f8088d27..2c32497fb46 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare03.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Compare03 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Compare03 { - // Offset: 0x00000000 Length: 0x00000237 + // Offset: 0x00000000 Length: 0x00000233 } .mresource public FSharpOptimizationData.Compare03 { - // Offset: 0x00000240 Length: 0x000000B9 + // Offset: 0x00000238 Length: 0x000000B9 } .module Compare03.dll -// MVID: {59B18AEE-0562-F88E-A745-0383EE8AB159} +// MVID: {611C550D-0562-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x05000000 // =============== CLASS MEMBERS DECLARATION =================== @@ -65,7 +70,7 @@ [3] int32 V_3, [4] int32 V_4) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare03.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare03.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 8,8 : 8,32 '' @@ -78,6 +83,7 @@ IL_0007: ldc.i4.1 IL_0008: cgt IL_000a: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_000b: ldloc.2 IL_000c: brfalse.s IL_0012 @@ -92,6 +98,7 @@ IL_0013: ldc.i4.2 IL_0014: cgt IL_0016: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0017: ldloc.3 IL_0018: brfalse.s IL_001e @@ -106,6 +113,7 @@ IL_001f: ldc.i4.4 IL_0020: cgt IL_0022: stloc.s V_4 + .line 16707566,16707566 : 0,0 '' IL_0024: ldloc.s V_4 IL_0026: brfalse.s IL_002d @@ -118,8 +126,8 @@ .line 16707566,16707566 : 0,0 '' IL_002d: ldstr "five" IL_0032: ldstr "5" - IL_0037: call int32 [mscorlib]System.String::CompareOrdinal(string, - string) + IL_0037: call int32 [netstandard]System.String::CompareOrdinal(string, + string) .line 16707566,16707566 : 0,0 '' IL_003c: nop .line 16707566,16707566 : 0,0 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare04.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare04.il.bsl index 0a5d7ed4b4f..81438746bfa 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare04.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Compare04 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Compare04 { - // Offset: 0x00000000 Length: 0x00000237 + // Offset: 0x00000000 Length: 0x00000233 } .mresource public FSharpOptimizationData.Compare04 { - // Offset: 0x00000240 Length: 0x000000B9 + // Offset: 0x00000238 Length: 0x000000B9 } .module Compare04.dll -// MVID: {59B18AEE-053B-F88E-A745-0383EE8AB159} +// MVID: {611C550D-053B-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x013E0000 +// Image base: 0x071C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -66,7 +71,7 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare04.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare04.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 8,8 : 8,32 '' @@ -79,6 +84,7 @@ IL_000a: ldc.i4.1 IL_000b: cgt IL_000d: stloc.2 + .line 16707566,16707566 : 0,0 '' IL_000e: ldloc.2 IL_000f: brfalse.s IL_0018 @@ -93,6 +99,7 @@ IL_0019: ldc.i4.2 IL_001a: cgt IL_001c: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_001d: ldloc.3 IL_001e: brfalse.s IL_0027 @@ -107,6 +114,7 @@ IL_0028: ldc.i4.4 IL_0029: cgt IL_002b: stloc.s V_4 + .line 16707566,16707566 : 0,0 '' IL_002d: ldloc.s V_4 IL_002f: brfalse.s IL_0039 @@ -119,9 +127,10 @@ .line 16707566,16707566 : 0,0 '' IL_0039: ldstr "5" IL_003e: ldstr "5" - IL_0043: call int32 [mscorlib]System.String::CompareOrdinal(string, - string) + IL_0043: call int32 [netstandard]System.String::CompareOrdinal(string, + string) IL_0048: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_004a: ldloc.s V_5 IL_004c: brfalse.s IL_0053 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare05.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare05.il.bsl index 1b66e37d298..7920cf478b6 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare05.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare05 { - // Offset: 0x00000000 Length: 0x000006EC + // Offset: 0x00000000 Length: 0x000006DC } .mresource public FSharpOptimizationData.Compare05 { - // Offset: 0x000006F0 Length: 0x000003BA + // Offset: 0x000006E0 Length: 0x000003BA } .module Compare05.dll -// MVID: {59B18AEE-051C-F88E-A745-0383EE8AB159} +// MVID: {611C550D-051C-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x070E0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Compare05/CompareMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare05.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare05.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Compare05/CompareMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_1, [2] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Compare05/CompareMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Compare05/CompareMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0017: ldloc.1 + IL_0018: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Compare05/CompareMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare05/CompareMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_0013: ldloc.0 + IL_0014: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Compare05/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Compare05/CompareMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare06.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare06.il.bsl index 49c709033de..0e4e347ea04 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare06.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare06 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare06 { - // Offset: 0x00000000 Length: 0x000006DF + // Offset: 0x00000000 Length: 0x000006CF } .mresource public FSharpOptimizationData.Compare06 { - // Offset: 0x000006E8 Length: 0x000003BC + // Offset: 0x000006D8 Length: 0x000003BC } .module Compare06.dll -// MVID: {59B18AEE-04FD-F88E-A745-0383EE8AB159} +// MVID: {611C550D-04FD-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02E80000 +// Image base: 0x04F30000 // =============== CLASS MEMBERS DECLARATION =================== @@ -123,109 +123,114 @@ instance int32 CompareTo(class Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 101 (0x65) + // Code size 102 (0x66) .maxstack 4 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare06.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_005b + .line 4,4 : 10,14 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare06.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_005c .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0059 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_005a .line 16707566,16707566 : 0,0 '' - IL_000c: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0011: stloc.1 - IL_0012: ldarg.0 - IL_0013: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: stloc.2 - IL_0019: ldarg.1 - IL_001a: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: bge.s IL_0028 + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: stloc.2 + IL_001a: ldarg.1 + IL_001b: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0020: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: bge.s IL_0029 .line 16707566,16707566 : 0,0 '' - IL_0024: ldc.i4.m1 + IL_0025: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002d + IL_0026: nop + IL_0027: br.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: cgt + IL_0029: ldloc.2 + IL_002a: ldloc.3 + IL_002b: cgt .line 16707566,16707566 : 0,0 '' - IL_002c: nop + IL_002d: nop .line 16707566,16707566 : 0,0 '' - IL_002d: stloc.0 - IL_002e: ldloc.0 - IL_002f: ldc.i4.0 - IL_0030: bge.s IL_0034 + IL_002e: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_002f: ldloc.0 + IL_0030: ldc.i4.0 + IL_0031: bge.s IL_0035 .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.0 - IL_0033: ret + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldloc.0 - IL_0035: ldc.i4.0 - IL_0036: ble.s IL_003a + IL_0035: ldloc.0 + IL_0036: ldc.i4.0 + IL_0037: ble.s IL_003b .line 16707566,16707566 : 0,0 '' - IL_0038: ldloc.0 - IL_0039: ret + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_003f: stloc.1 - IL_0040: ldarg.0 - IL_0041: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0046: stloc.2 - IL_0047: ldarg.1 - IL_0048: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_004d: stloc.3 - IL_004e: ldloc.2 - IL_004f: ldloc.3 - IL_0050: bge.s IL_0054 + IL_003b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0040: stloc.1 + IL_0041: ldarg.0 + IL_0042: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0047: stloc.2 + IL_0048: ldarg.1 + IL_0049: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_004e: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_004f: ldloc.2 + IL_0050: ldloc.3 + IL_0051: bge.s IL_0055 .line 16707566,16707566 : 0,0 '' - IL_0052: ldc.i4.m1 - IL_0053: ret + IL_0053: ldc.i4.m1 + IL_0054: ret .line 16707566,16707566 : 0,0 '' - IL_0054: ldloc.2 - IL_0055: ldloc.3 - IL_0056: cgt - IL_0058: ret + IL_0055: ldloc.2 + IL_0056: ldloc.3 + IL_0057: cgt + IL_0059: ret .line 16707566,16707566 : 0,0 '' - IL_0059: ldc.i4.1 - IL_005a: ret + IL_005a: ldc.i4.1 + IL_005b: ret .line 16707566,16707566 : 0,0 '' - IL_005b: ldarg.1 - IL_005c: ldnull - IL_005d: cgt.un - IL_005f: brfalse.s IL_0063 + IL_005c: ldarg.1 + IL_005d: ldnull + IL_005e: cgt.un + IL_0060: brfalse.s IL_0064 .line 16707566,16707566 : 0,0 '' - IL_0061: ldc.i4.m1 - IL_0062: ret + IL_0062: ldc.i4.m1 + IL_0063: ret .line 16707566,16707566 : 0,0 '' - IL_0063: ldc.i4.0 - IL_0064: ret + IL_0064: ldc.i4.0 + IL_0065: ret } // end of method KeyR::CompareTo .method public hidebysig virtual final @@ -257,6 +262,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -276,6 +282,7 @@ IL_001f: ldloc.0 IL_0020: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ IL_0025: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0026: ldloc.2 IL_0027: ldloc.3 IL_0028: bge.s IL_002e @@ -294,6 +301,7 @@ IL_0032: nop .line 16707566,16707566 : 0,0 '' IL_0033: stloc.1 + .line 16707566,16707566 : 0,0 '' IL_0034: ldloc.1 IL_0035: ldc.i4.0 IL_0036: bge.s IL_003a @@ -318,6 +326,7 @@ IL_0047: ldloc.0 IL_0048: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ IL_004d: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_004e: ldloc.2 IL_004f: ldloc.3 IL_0050: bge.s IL_0054 @@ -356,50 +365,52 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 54 (0x36) + // Code size 55 (0x37) .maxstack 7 .locals init ([0] int32 V_0) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0034 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldc.i4 0x9e3779b9 - IL_000d: ldarg.0 - IL_000e: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0013: ldloc.0 - IL_0014: ldc.i4.6 - IL_0015: shl - IL_0016: ldloc.0 - IL_0017: ldc.i4.2 - IL_0018: shr - IL_0019: add + .line 4,4 : 10,14 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0035 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.0 + IL_000f: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0014: ldloc.0 + IL_0015: ldc.i4.6 + IL_0016: shl + IL_0017: ldloc.0 + IL_0018: ldc.i4.2 + IL_0019: shr IL_001a: add IL_001b: add - IL_001c: stloc.0 - IL_001d: ldc.i4 0x9e3779b9 - IL_0022: ldarg.0 - IL_0023: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0028: ldloc.0 - IL_0029: ldc.i4.6 - IL_002a: shl - IL_002b: ldloc.0 - IL_002c: ldc.i4.2 - IL_002d: shr - IL_002e: add + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldc.i4 0x9e3779b9 + IL_0023: ldarg.0 + IL_0024: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0029: ldloc.0 + IL_002a: ldc.i4.6 + IL_002b: shl + IL_002c: ldloc.0 + IL_002d: ldc.i4.2 + IL_002e: shr IL_002f: add IL_0030: add - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ret + IL_0031: add + IL_0032: stloc.0 + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldc.i4.0 - IL_0035: ret + IL_0035: ldc.i4.0 + IL_0036: ret } // end of method KeyR::GetHashCode .method public hidebysig virtual final @@ -420,102 +431,107 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 57 (0x39) + // Code size 58 (0x3a) .maxstack 4 .locals init ([0] class Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR V_0) + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0031 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_002f + IL_0007: ldarg.1 + IL_0008: isinst Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0016: ldloc.0 - IL_0017: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001c: bne.un.s IL_002d + IL_0011: ldarg.0 + IL_0012: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0017: ldloc.0 + IL_0018: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_001d: bne.un.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_001e: ldarg.0 - IL_001f: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0024: ldloc.0 - IL_0025: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_002a: ceq - IL_002c: ret + IL_001f: ldarg.0 + IL_0020: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0025: ldloc.0 + IL_0026: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_002b: ceq + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_002e: ldc.i4.0 + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldarg.1 - IL_0032: ldnull - IL_0033: cgt.un - IL_0035: ldc.i4.0 - IL_0036: ceq - IL_0038: ret + IL_0032: ldarg.1 + IL_0033: ldnull + IL_0034: cgt.un + IL_0036: ldc.i4.0 + IL_0037: ceq + IL_0039: ret } // end of method KeyR::Equals .method public hidebysig virtual final instance bool Equals(class Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 53 (0x35) + // Code size 54 (0x36) .maxstack 8 + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_002d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_002b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_002c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0012: ldarg.1 - IL_0013: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: bne.un.s IL_0029 + IL_000d: ldarg.0 + IL_000e: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0013: ldarg.1 + IL_0014: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: bne.un.s IL_002a .line 16707566,16707566 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0020: ldarg.1 - IL_0021: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0026: ceq - IL_0028: ret + IL_001b: ldarg.0 + IL_001c: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0021: ldarg.1 + IL_0022: ldfld int32 Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0027: ceq + IL_0029: ret .line 16707566,16707566 : 0,0 '' - IL_0029: ldc.i4.0 - IL_002a: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 16707566,16707566 : 0,0 '' - IL_002b: ldc.i4.0 - IL_002c: ret + IL_002c: ldc.i4.0 + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldarg.1 - IL_002e: ldnull - IL_002f: cgt.un - IL_0031: ldc.i4.0 - IL_0032: ceq - IL_0034: ret + IL_002e: ldarg.1 + IL_002f: ldnull + IL_0030: cgt.un + IL_0032: ldc.i4.0 + IL_0033: ceq + IL_0035: ret } // end of method KeyR::Equals .method public hidebysig virtual final @@ -529,6 +545,7 @@ IL_0000: ldarg.1 IL_0001: isinst Compare06/CompareMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare07.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare07.il.bsl index 70335b05d20..400de5cfc7b 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare07.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare07 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare07 { - // Offset: 0x00000000 Length: 0x0000089A + // Offset: 0x00000000 Length: 0x0000088A } .mresource public FSharpOptimizationData.Compare07 { - // Offset: 0x000008A0 Length: 0x00000692 + // Offset: 0x00000890 Length: 0x0000068C } .module Compare07.dll -// MVID: {59B18AEE-05DE-F88E-A745-0383EE8AB159} +// MVID: {611C550D-05DE-F88E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02BA0000 +// Image base: 0x058A0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 110 (0x6e) + // Code size 111 (0x6f) .maxstack 5 .locals init ([0] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, @@ -187,93 +187,96 @@ [4] !a V_4, [5] !a V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare07.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0064 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0062 - - .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop - .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldloc.s V_5 - IL_002d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + .line 4,4 : 10,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare07.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0065 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0063 + + .line 16707566,16707566 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0027: stloc.s V_5 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldloc.s V_5 + IL_002e: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0032: stloc.2 - IL_0033: ldloc.2 - IL_0034: ldc.i4.0 - IL_0035: bge.s IL_0039 + IL_0033: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0034: ldloc.2 + IL_0035: ldc.i4.0 + IL_0036: bge.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0037: ldloc.2 - IL_0038: ret + IL_0038: ldloc.2 + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: ble.s IL_003f + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: ble.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0044: stloc.3 - IL_0045: ldloc.0 - IL_0046: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_004b: stloc.s V_4 - IL_004d: ldloc.1 - IL_004e: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0053: stloc.s V_5 - IL_0055: ldloc.3 - IL_0056: ldloc.s V_4 - IL_0058: ldloc.s V_5 - IL_005a: tail. - IL_005c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + IL_0040: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0045: stloc.3 + IL_0046: ldloc.0 + IL_0047: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_004c: stloc.s V_4 + IL_004e: ldloc.1 + IL_004f: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0054: stloc.s V_5 + IL_0056: ldloc.3 + IL_0057: ldloc.s V_4 + IL_0059: ldloc.s V_5 + IL_005b: tail. + IL_005d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0061: ret + IL_0062: ret .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.1 - IL_0063: ret + IL_0063: ldc.i4.1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldarg.1 - IL_0065: ldnull - IL_0066: cgt.un - IL_0068: brfalse.s IL_006c + IL_0065: ldarg.1 + IL_0066: ldnull + IL_0067: cgt.un + IL_0069: brfalse.s IL_006d .line 16707566,16707566 : 0,0 '' - IL_006a: ldc.i4.m1 - IL_006b: ret + IL_006b: ldc.i4.m1 + IL_006c: ret .line 16707566,16707566 : 0,0 '' - IL_006c: ldc.i4.0 - IL_006d: ret + IL_006d: ldc.i4.0 + IL_006e: ret } // end of method GenericKey`1::CompareTo .method public hidebysig virtual final @@ -308,6 +311,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -341,6 +345,7 @@ !!0, !!0) IL_0038: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0039: ldloc.3 IL_003a: ldc.i4.0 IL_003b: bge.s IL_003f @@ -398,69 +403,72 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) + // Code size 77 (0x4d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0019: stloc.2 - IL_001a: ldarg.1 - IL_001b: ldloc.2 - IL_001c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + .line 4,4 : 10,20 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_004b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_001a: stloc.2 + IL_001b: ldarg.1 + IL_001c: ldloc.2 + IL_001d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_0021: ldloc.0 - IL_0022: ldc.i4.6 - IL_0023: shl - IL_0024: ldloc.0 - IL_0025: ldc.i4.2 - IL_0026: shr - IL_0027: add + IL_0022: ldloc.0 + IL_0023: ldc.i4.6 + IL_0024: shl + IL_0025: ldloc.0 + IL_0026: ldc.i4.2 + IL_0027: shr IL_0028: add IL_0029: add - IL_002a: stloc.0 - IL_002b: ldc.i4 0x9e3779b9 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0036: stloc.2 - IL_0037: ldarg.1 - IL_0038: ldloc.2 - IL_0039: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002a: add + IL_002b: stloc.0 + IL_002c: ldc.i4 0x9e3779b9 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0037: stloc.2 + IL_0038: ldarg.1 + IL_0039: ldloc.2 + IL_003a: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_003e: ldloc.0 - IL_003f: ldc.i4.6 - IL_0040: shl - IL_0041: ldloc.0 - IL_0042: ldc.i4.2 - IL_0043: shr - IL_0044: add + IL_003f: ldloc.0 + IL_0040: ldc.i4.6 + IL_0041: shl + IL_0042: ldloc.0 + IL_0043: ldc.i4.2 + IL_0044: shr IL_0045: add IL_0046: add - IL_0047: stloc.0 - IL_0048: ldloc.0 - IL_0049: ret + IL_0047: add + IL_0048: stloc.0 + IL_0049: ldloc.0 + IL_004a: ret .line 16707566,16707566 : 0,0 '' - IL_004a: ldc.i4.0 - IL_004b: ret + IL_004b: ldc.i4.0 + IL_004c: ret } // end of method GenericKey`1::GetHashCode .method public hidebysig virtual final @@ -481,152 +489,159 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 87 (0x57) + // Code size 88 (0x58) .maxstack 5 .locals init ([0] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_2, [3] !a V_3, [4] !a V_4) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004f - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_004d - - .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop - .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001c: stloc.3 - IL_001d: ldloc.2 - IL_001e: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0023: stloc.s V_4 - IL_0025: ldarg.2 - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0050 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_004e + + .line 16707566,16707566 : 0,0 '' + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001d: stloc.3 + IL_001e: ldloc.2 + IL_001f: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0024: stloc.s V_4 + IL_0026: ldarg.2 + IL_0027: ldloc.3 + IL_0028: ldloc.s V_4 + IL_002a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_002e: brfalse.s IL_004b - - .line 16707566,16707566 : 0,0 '' - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_003d: stloc.s V_4 - IL_003f: ldarg.2 - IL_0040: ldloc.3 - IL_0041: ldloc.s V_4 - IL_0043: tail. - IL_0045: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002f: brfalse.s IL_004c + + .line 16707566,16707566 : 0,0 '' + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_003e: stloc.s V_4 + IL_0040: ldarg.2 + IL_0041: ldloc.3 + IL_0042: ldloc.s V_4 + IL_0044: tail. + IL_0046: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_004a: ret + IL_004b: ret .line 16707566,16707566 : 0,0 '' - IL_004b: ldc.i4.0 - IL_004c: ret + IL_004c: ldc.i4.0 + IL_004d: ret .line 16707566,16707566 : 0,0 '' - IL_004d: ldc.i4.0 - IL_004e: ret + IL_004e: ldc.i4.0 + IL_004f: ret .line 16707566,16707566 : 0,0 '' - IL_004f: ldarg.1 - IL_0050: ldnull - IL_0051: cgt.un - IL_0053: ldc.i4.0 - IL_0054: ceq - IL_0056: ret + IL_0050: ldarg.1 + IL_0051: ldnull + IL_0052: cgt.un + IL_0054: ldc.i4.0 + IL_0055: ceq + IL_0057: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final instance bool Equals(class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 77 (0x4d) + // Code size 78 (0x4e) .maxstack 4 .locals init ([0] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2, [3] !a V_3) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0045 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0043 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0044 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0019: stloc.2 + IL_001a: ldloc.1 + IL_001b: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0027: brfalse.s IL_0041 - - .line 16707566,16707566 : 0,0 '' - IL_0029: ldloc.0 - IL_002a: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_002f: stloc.2 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldloc.3 - IL_0039: tail. - IL_003b: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_0028: brfalse.s IL_0042 + + .line 16707566,16707566 : 0,0 '' + IL_002a: ldloc.0 + IL_002b: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0030: stloc.2 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldloc.3 + IL_003a: tail. + IL_003c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0040: ret + IL_0041: ret .line 16707566,16707566 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0042: ldc.i4.0 + IL_0043: ret .line 16707566,16707566 : 0,0 '' - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0044: ldc.i4.0 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: ldarg.1 - IL_0046: ldnull - IL_0047: cgt.un - IL_0049: ldc.i4.0 - IL_004a: ceq - IL_004c: ret + IL_0046: ldarg.1 + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: ldc.i4.0 + IL_004b: ceq + IL_004d: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final @@ -640,6 +655,7 @@ IL_0000: ldarg.1 IL_0001: isinst class Compare07/CompareMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare08.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare08.il.bsl index 29f55a0cb58..008f1eb52b1 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare08.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare08.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare08 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare08 { - // Offset: 0x00000000 Length: 0x00000230 + // Offset: 0x00000000 Length: 0x0000022C } .mresource public FSharpOptimizationData.Compare08 { - // Offset: 0x00000238 Length: 0x000000B2 + // Offset: 0x00000230 Length: 0x000000B2 } .module Compare08.dll -// MVID: {59B18AEE-03E7-F88E-A745-0383EE8AB159} +// MVID: {60BE1F16-03E7-F88E-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01590000 +// Image base: 0x06D10000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ [2] uint8[] t2, [3] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare08.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare08.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 6,6 : 8,35 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare09.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare09.il.bsl index 4d890783eed..f8a93849b92 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare09.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare09.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare09 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare09 { - // Offset: 0x00000000 Length: 0x00000230 + // Offset: 0x00000000 Length: 0x0000022C } .mresource public FSharpOptimizationData.Compare09 { - // Offset: 0x00000238 Length: 0x000000B2 + // Offset: 0x00000230 Length: 0x000000B2 } .module Compare09.dll -// MVID: {59B18AEE-03C8-F88E-A745-0383EE8AB159} +// MVID: {60BE1F16-03C8-F88E-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01020000 +// Image base: 0x06710000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ [2] int32[] t2, [3] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare09.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare09.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 6,6 : 8,31 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare10.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare10.il.bsl index 16bada503c5..8184984ccad 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare10.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare10.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare10 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare10 { - // Offset: 0x00000000 Length: 0x00000AA4 + // Offset: 0x00000000 Length: 0x00000A94 } .mresource public FSharpOptimizationData.Compare10 { - // Offset: 0x00000AA8 Length: 0x0000058E + // Offset: 0x00000A98 Length: 0x0000058E } .module Compare10.dll -// MVID: {59B18AEE-04BF-1753-A745-0383EE8AB159} +// MVID: {611C550D-04BF-1753-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002E0000 +// Image base: 0x07060000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Compare10/CompareMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare10.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare10.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Compare10/CompareMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_1, [2] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Compare10/CompareMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 @@ -792,7 +812,7 @@ instance int32 CompareTo(class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 169 (0xa9) + // Code size 170 (0xaa) .maxstack 5 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -805,116 +825,120 @@ [8] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_8, [9] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_9, [10] int32 V_10) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_009f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_00a0 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: ldnull - IL_000b: cgt.un - IL_000d: brfalse IL_009d + IL_000a: ldarg.1 + IL_000b: ldnull + IL_000c: cgt.un + IL_000e: brfalse IL_009e .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: pop + IL_0013: ldarg.0 + IL_0014: pop .line 16707566,16707566 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: stloc.0 - IL_0016: ldarg.1 - IL_0017: stloc.1 - IL_0018: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_001d: stloc.3 - IL_001e: ldloc.0 - IL_001f: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0024: stloc.s V_4 - IL_0026: ldloc.1 - IL_0027: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_002c: stloc.s V_5 - IL_002e: ldloc.s V_4 - IL_0030: ldloc.s V_5 - IL_0032: ldloc.3 - IL_0033: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0015: ldarg.0 + IL_0016: stloc.0 + IL_0017: ldarg.1 + IL_0018: stloc.1 + IL_0019: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_001e: stloc.3 + IL_001f: ldloc.0 + IL_0020: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0025: stloc.s V_4 + IL_0027: ldloc.1 + IL_0028: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_002d: stloc.s V_5 + IL_002f: ldloc.s V_4 + IL_0031: ldloc.s V_5 + IL_0033: ldloc.3 + IL_0034: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0038: stloc.2 - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: bge.s IL_003f + IL_0039: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: bge.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: ldloc.2 - IL_0040: ldc.i4.0 - IL_0041: ble.s IL_0045 + IL_0040: ldloc.2 + IL_0041: ldc.i4.0 + IL_0042: ble.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0043: ldloc.2 - IL_0044: ret + IL_0044: ldloc.2 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004a: stloc.3 - IL_004b: ldloc.0 - IL_004c: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0051: stloc.s V_6 - IL_0053: ldloc.1 - IL_0054: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0059: stloc.s V_7 - IL_005b: ldloc.s V_6 - IL_005d: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0062: stloc.s V_4 - IL_0064: ldloc.s V_6 - IL_0066: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_006b: stloc.s V_5 - IL_006d: ldloc.s V_7 - IL_006f: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0074: stloc.s V_8 - IL_0076: ldloc.s V_7 - IL_0078: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_007d: stloc.s V_9 - IL_007f: ldloc.s V_4 - IL_0081: ldloc.s V_8 - IL_0083: ldloc.3 - IL_0084: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004b: stloc.3 + IL_004c: ldloc.0 + IL_004d: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0052: stloc.s V_6 + IL_0054: ldloc.1 + IL_0055: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_005a: stloc.s V_7 + IL_005c: ldloc.s V_6 + IL_005e: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0063: stloc.s V_4 + IL_0065: ldloc.s V_6 + IL_0067: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_006c: stloc.s V_5 + IL_006e: ldloc.s V_7 + IL_0070: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0075: stloc.s V_8 + IL_0077: ldloc.s V_7 + IL_0079: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_007e: stloc.s V_9 + IL_0080: ldloc.s V_4 + IL_0082: ldloc.s V_8 + IL_0084: ldloc.3 + IL_0085: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0089: stloc.s V_10 - IL_008b: ldloc.s V_10 - IL_008d: brfalse.s IL_0092 + IL_008a: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' + IL_008c: ldloc.s V_10 + IL_008e: brfalse.s IL_0093 .line 16707566,16707566 : 0,0 '' - IL_008f: ldloc.s V_10 - IL_0091: ret + IL_0090: ldloc.s V_10 + IL_0092: ret .line 16707566,16707566 : 0,0 '' - IL_0092: ldloc.s V_5 - IL_0094: ldloc.s V_9 - IL_0096: ldloc.3 - IL_0097: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0093: ldloc.s V_5 + IL_0095: ldloc.s V_9 + IL_0097: ldloc.3 + IL_0098: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_009c: ret + IL_009d: ret .line 16707566,16707566 : 0,0 '' - IL_009d: ldc.i4.1 - IL_009e: ret + IL_009e: ldc.i4.1 + IL_009f: ret .line 16707566,16707566 : 0,0 '' - IL_009f: ldarg.1 - IL_00a0: ldnull - IL_00a1: cgt.un - IL_00a3: brfalse.s IL_00a7 + IL_00a0: ldarg.1 + IL_00a1: ldnull + IL_00a2: cgt.un + IL_00a4: brfalse.s IL_00a8 .line 16707566,16707566 : 0,0 '' - IL_00a5: ldc.i4.m1 - IL_00a6: ret + IL_00a6: ldc.i4.m1 + IL_00a7: ret .line 16707566,16707566 : 0,0 '' - IL_00a7: ldc.i4.0 - IL_00a8: ret + IL_00a8: ldc.i4.0 + IL_00a9: ret } // end of method KeyWithInnerKeys::CompareTo .method public hidebysig virtual final @@ -953,6 +977,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -985,6 +1010,7 @@ IL_0039: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_003e: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_003f: ldloc.3 IL_0040: ldc.i4.0 IL_0041: bge.s IL_0045 @@ -1027,6 +1053,7 @@ IL_0084: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_0089: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' IL_008b: ldloc.s V_10 IL_008d: brfalse.s IL_0092 @@ -1066,7 +1093,7 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 107 (0x6b) + // Code size 108 (0x6c) .maxstack 7 .locals init ([0] int32 V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1074,76 +1101,79 @@ [3] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_3, [4] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_4, [5] int32 V_5) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0069 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0019: stloc.2 - IL_001a: ldloc.2 - IL_001b: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0020: stloc.3 - IL_0021: ldloc.2 - IL_0022: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0027: stloc.s V_4 - IL_0029: ldloc.3 - IL_002a: ldarg.1 - IL_002b: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0030: stloc.s V_5 - IL_0032: ldloc.s V_5 - IL_0034: ldc.i4.5 - IL_0035: shl - IL_0036: ldloc.s V_5 - IL_0038: add - IL_0039: ldloc.s V_4 - IL_003b: ldarg.1 - IL_003c: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0041: xor - IL_0042: ldloc.0 - IL_0043: ldc.i4.6 - IL_0044: shl - IL_0045: ldloc.0 - IL_0046: ldc.i4.2 - IL_0047: shr - IL_0048: add + .line 5,5 : 10,26 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006a + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0021: stloc.3 + IL_0022: ldloc.2 + IL_0023: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0028: stloc.s V_4 + IL_002a: ldloc.3 + IL_002b: ldarg.1 + IL_002c: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0031: stloc.s V_5 + IL_0033: ldloc.s V_5 + IL_0035: ldc.i4.5 + IL_0036: shl + IL_0037: ldloc.s V_5 + IL_0039: add + IL_003a: ldloc.s V_4 + IL_003c: ldarg.1 + IL_003d: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0042: xor + IL_0043: ldloc.0 + IL_0044: ldc.i4.6 + IL_0045: shl + IL_0046: ldloc.0 + IL_0047: ldc.i4.2 + IL_0048: shr IL_0049: add IL_004a: add - IL_004b: stloc.0 - IL_004c: ldc.i4 0x9e3779b9 - IL_0051: ldloc.1 - IL_0052: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0057: ldarg.1 - IL_0058: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_005d: ldloc.0 - IL_005e: ldc.i4.6 - IL_005f: shl - IL_0060: ldloc.0 - IL_0061: ldc.i4.2 - IL_0062: shr - IL_0063: add + IL_004b: add + IL_004c: stloc.0 + IL_004d: ldc.i4 0x9e3779b9 + IL_0052: ldloc.1 + IL_0053: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0058: ldarg.1 + IL_0059: callvirt instance int32 Compare10/CompareMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_005e: ldloc.0 + IL_005f: ldc.i4.6 + IL_0060: shl + IL_0061: ldloc.0 + IL_0062: ldc.i4.2 + IL_0063: shr IL_0064: add IL_0065: add - IL_0066: stloc.0 - IL_0067: ldloc.0 - IL_0068: ret + IL_0066: add + IL_0067: stloc.0 + IL_0068: ldloc.0 + IL_0069: ret .line 16707566,16707566 : 0,0 '' - IL_0069: ldc.i4.0 - IL_006a: ret + IL_006a: ldc.i4.0 + IL_006b: ret } // end of method KeyWithInnerKeys::GetHashCode .method public hidebysig virtual final @@ -1164,7 +1194,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 138 (0x8a) + // Code size 139 (0x8b) .maxstack 5 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1175,155 +1205,163 @@ [6] class [mscorlib]System.Tuple`2 V_6, [7] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_7, [8] class Compare10/CompareMicroPerfAndCodeGenerationTests/Key V_8) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_0082 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_0083 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: brfalse.s IL_0080 + IL_000a: ldarg.1 + IL_000b: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys + IL_0010: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: brfalse.s IL_0081 .line 16707566,16707566 : 0,0 '' - IL_0013: ldarg.0 - IL_0014: pop + IL_0014: ldarg.0 + IL_0015: pop .line 16707566,16707566 : 0,0 '' - IL_0015: ldarg.0 - IL_0016: stloc.1 - IL_0017: ldloc.0 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0026: stloc.s V_4 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldarg.2 - IL_002c: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0016: ldarg.0 + IL_0017: stloc.1 + IL_0018: ldloc.0 + IL_0019: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_001a: ldloc.1 + IL_001b: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0027: stloc.s V_4 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldarg.2 + IL_002d: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_0031: brfalse.s IL_007e + IL_0032: brfalse.s IL_007f .line 16707566,16707566 : 0,0 '' - IL_0033: ldloc.1 - IL_0034: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0039: stloc.s V_5 - IL_003b: ldloc.2 - IL_003c: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0041: stloc.s V_6 - IL_0043: ldloc.s V_5 - IL_0045: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_004a: stloc.3 - IL_004b: ldloc.s V_5 - IL_004d: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0052: stloc.s V_4 - IL_0054: ldloc.s V_6 - IL_0056: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_005b: stloc.s V_7 - IL_005d: ldloc.s V_6 - IL_005f: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0064: stloc.s V_8 - IL_0066: ldloc.3 - IL_0067: ldloc.s V_7 - IL_0069: ldarg.2 - IL_006a: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0034: ldloc.1 + IL_0035: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_003a: stloc.s V_5 + IL_003c: ldloc.2 + IL_003d: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0042: stloc.s V_6 + IL_0044: ldloc.s V_5 + IL_0046: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_004b: stloc.3 + IL_004c: ldloc.s V_5 + IL_004e: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0053: stloc.s V_4 + IL_0055: ldloc.s V_6 + IL_0057: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_005c: stloc.s V_7 + IL_005e: ldloc.s V_6 + IL_0060: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0065: stloc.s V_8 + .line 16707566,16707566 : 0,0 '' + IL_0067: ldloc.3 + IL_0068: ldloc.s V_7 + IL_006a: ldarg.2 + IL_006b: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_006f: brfalse.s IL_007c + IL_0070: brfalse.s IL_007d .line 16707566,16707566 : 0,0 '' - IL_0071: ldloc.s V_4 - IL_0073: ldloc.s V_8 - IL_0075: ldarg.2 - IL_0076: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0072: ldloc.s V_4 + IL_0074: ldloc.s V_8 + IL_0076: ldarg.2 + IL_0077: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_007b: ret + IL_007c: ret .line 16707566,16707566 : 0,0 '' - IL_007c: ldc.i4.0 - IL_007d: ret + IL_007d: ldc.i4.0 + IL_007e: ret .line 16707566,16707566 : 0,0 '' - IL_007e: ldc.i4.0 - IL_007f: ret + IL_007f: ldc.i4.0 + IL_0080: ret .line 16707566,16707566 : 0,0 '' - IL_0080: ldc.i4.0 - IL_0081: ret + IL_0081: ldc.i4.0 + IL_0082: ret .line 16707566,16707566 : 0,0 '' - IL_0082: ldarg.1 - IL_0083: ldnull - IL_0084: cgt.un - IL_0086: ldc.i4.0 - IL_0087: ceq - IL_0089: ret + IL_0083: ldarg.1 + IL_0084: ldnull + IL_0085: cgt.un + IL_0087: ldc.i4.0 + IL_0088: ceq + IL_008a: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final instance bool Equals(class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 69 (0x45) + // Code size 70 (0x46) .maxstack 4 .locals init ([0] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_003b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_003c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0018: ldloc.1 - IL_0019: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001e: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(class Compare10/CompareMicroPerfAndCodeGenerationTests/Key) - IL_0023: brfalse.s IL_0039 - - .line 16707566,16707566 : 0,0 '' - IL_0025: ldloc.0 - IL_0026: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_002b: ldloc.1 - IL_002c: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0031: tail. - IL_0033: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0019: ldloc.1 + IL_001a: ldfld class Compare10/CompareMicroPerfAndCodeGenerationTests/Key Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_001f: callvirt instance bool Compare10/CompareMicroPerfAndCodeGenerationTests/Key::Equals(class Compare10/CompareMicroPerfAndCodeGenerationTests/Key) + IL_0024: brfalse.s IL_003a + + .line 16707566,16707566 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_002c: ldloc.1 + IL_002d: ldfld class [mscorlib]System.Tuple`2 Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0032: tail. + IL_0034: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, !!0) - IL_0038: ret + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldc.i4.0 - IL_003a: ret + IL_003a: ldc.i4.0 + IL_003b: ret .line 16707566,16707566 : 0,0 '' - IL_003b: ldc.i4.0 - IL_003c: ret + IL_003c: ldc.i4.0 + IL_003d: ret .line 16707566,16707566 : 0,0 '' - IL_003d: ldarg.1 - IL_003e: ldnull - IL_003f: cgt.un - IL_0041: ldc.i4.0 - IL_0042: ceq - IL_0044: ret + IL_003e: ldarg.1 + IL_003f: ldnull + IL_0040: cgt.un + IL_0042: ldc.i4.0 + IL_0043: ceq + IL_0045: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final @@ -1337,6 +1375,7 @@ IL_0000: ldarg.1 IL_0001: isinst Compare10/CompareMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare11.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare11.il.bsl index 7f37b719bb4..4293dce0c19 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare11.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Compare11.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Compare11 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Compare11 { - // Offset: 0x00000000 Length: 0x00000230 + // Offset: 0x00000000 Length: 0x0000022C } .mresource public FSharpOptimizationData.Compare11 { - // Offset: 0x00000238 Length: 0x000000B1 + // Offset: 0x00000230 Length: 0x000000B1 } .module Compare11.dll -// MVID: {59B18AEE-04A0-1753-A745-0383EE8AB159} +// MVID: {60BE1F16-04A0-1753-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010A0000 +// Image base: 0x068D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ .locals init ([0] bool x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Compare11.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Compare11.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 9,9 : 8,32 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals01.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals01.il.bsl index c722fc2d31f..6cd820bc0f7 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals01 { - // Offset: 0x00000000 Length: 0x00000234 + // Offset: 0x00000000 Length: 0x00000230 } .mresource public FSharpOptimizationData.Equals01 { // Offset: 0x00000238 Length: 0x000000B6 } .module Equals01.dll -// MVID: {59B18AEE-0759-50B1-A745-0383EE8AB159} +// MVID: {60BE1F16-0759-50B1-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02D70000 +// Image base: 0x06A90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ .locals init ([0] bool x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals01.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals01.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 8,8 : 8,32 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals02.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals02.il.bsl index aa7bbc68da5..10efc022f68 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Equals02 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Equals02 { - // Offset: 0x00000000 Length: 0x0000023C + // Offset: 0x00000000 Length: 0x00000230 } .mresource public FSharpOptimizationData.Equals02 { - // Offset: 0x00000240 Length: 0x000000B6 + // Offset: 0x00000238 Length: 0x000000B6 } .module Equals02.dll -// MVID: {5B18753B-0759-B6D8-A745-03833B75185B} +// MVID: {60BE1F16-0759-B6D8-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F20000 +// Image base: 0x05340000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,23 +62,24 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static bool f4_tuple4() cil managed { - // Code size 44 (0x2c) + // Code size 36 (0x24) .maxstack 4 .locals init ([0] bool x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals02.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals02.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 8,8 : 8,32 '' IL_0002: ldc.i4.0 IL_0003: stloc.1 IL_0004: br.s IL_001a + .line 9,9 : 12,26 '' IL_0006: ldstr "five" IL_000b: ldstr "5" - IL_0010: call bool [mscorlib]System.String::Equals(string, - string) + IL_0010: call bool [netstandard]System.String::Equals(string, + string) IL_0015: stloc.0 IL_0016: ldloc.1 IL_0017: ldc.i4.1 @@ -83,17 +89,22 @@ IL_001a: ldloc.1 IL_001b: ldc.i4 0x989681 IL_0020: blt.s IL_0006 + .line 10,10 : 8,9 '' IL_0022: ldloc.0 IL_0023: ret } // end of method EqualsMicroPerfAndCodeGenerationTests::f4_tuple4 + } // end of class EqualsMicroPerfAndCodeGenerationTests + } // end of class Equals02 + .class private abstract auto ansi sealed ''.$Equals02$fsx extends [mscorlib]System.Object { } // end of class ''.$Equals02$fsx + // ============================================================= // *********** DISASSEMBLY COMPLETE *********************** diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals03.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals03.il.bsl index e222d314825..cc4f7494b64 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals03.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Equals03 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Equals03 { - // Offset: 0x00000000 Length: 0x0000023C + // Offset: 0x00000000 Length: 0x00000230 } .mresource public FSharpOptimizationData.Equals03 { - // Offset: 0x00000240 Length: 0x000000B6 + // Offset: 0x00000238 Length: 0x000000B6 } .module Equals03.dll -// MVID: {5B18753B-0759-3313-A745-03833B75185B} +// MVID: {611C550D-0759-3313-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02630000 +// Image base: 0x07160000 // =============== CLASS MEMBERS DECLARATION =================== @@ -57,52 +62,54 @@ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) .method public static bool f4_tuple5() cil managed { - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] bool x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals03.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals03.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 8,8 : 8,32 '' IL_0002: ldc.i4.0 IL_0003: stloc.1 - IL_0004: br.s IL_0035 + IL_0004: br.s IL_0036 .line 9,9 : 12,26 '' - IL_0006: ldstr "5" - IL_000b: ldstr "5" - IL_0010: call bool [mscorlib]System.String::Equals(string, - string) - IL_0015: brfalse.s IL_002e + IL_0006: nop + .line 16707566,16707566 : 0,0 '' + IL_0007: ldstr "5" + IL_000c: ldstr "5" + IL_0011: call bool [netstandard]System.String::Equals(string, + string) + IL_0016: brfalse.s IL_002f .line 16707566,16707566 : 0,0 '' - IL_0017: ldc.r8 6. - IL_0020: ldc.r8 7. - IL_0029: ceq + IL_0018: ldc.r8 6. + IL_0021: ldc.r8 7. + IL_002a: ceq .line 16707566,16707566 : 0,0 '' - IL_002b: nop - IL_002c: br.s IL_0030 + IL_002c: nop + IL_002d: br.s IL_0031 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.0 + IL_002f: ldc.i4.0 .line 16707566,16707566 : 0,0 '' - IL_002f: nop + IL_0030: nop .line 16707566,16707566 : 0,0 '' - IL_0030: stloc.0 - IL_0031: ldloc.1 - IL_0032: ldc.i4.1 - IL_0033: add - IL_0034: stloc.1 + IL_0031: stloc.0 + IL_0032: ldloc.1 + IL_0033: ldc.i4.1 + IL_0034: add + IL_0035: stloc.1 .line 8,8 : 8,32 '' - IL_0035: ldloc.1 - IL_0036: ldc.i4 0x989681 - IL_003b: blt.s IL_0006 + IL_0036: ldloc.1 + IL_0037: ldc.i4 0x989681 + IL_003c: blt.s IL_0006 .line 10,10 : 8,9 '' - IL_003d: ldloc.0 - IL_003e: ret + IL_003e: ldloc.0 + IL_003f: ret } // end of method EqualsMicroPerfAndCodeGenerationTests::f4_tuple5 } // end of class EqualsMicroPerfAndCodeGenerationTests diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals04.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals04.il.bsl index 6ad198b4879..b2b49483a4b 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals04.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals04 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals04 { - // Offset: 0x00000000 Length: 0x000006E8 + // Offset: 0x00000000 Length: 0x000006D8 } .mresource public FSharpOptimizationData.Equals04 { - // Offset: 0x000006F0 Length: 0x000003B7 + // Offset: 0x000006E0 Length: 0x000003B7 } .module Equals04.dll -// MVID: {59B18AEE-0759-EA8A-A745-0383EE8AB159} +// MVID: {611C550D-0759-EA8A-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x071F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals04.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals04.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Equals04/EqualsMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_1, [2] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Equals04/EqualsMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Equals04/EqualsMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0017: ldloc.1 + IL_0018: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals04/EqualsMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_0013: ldloc.0 + IL_0014: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Equals04/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Equals04/EqualsMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals05.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals05.il.bsl index ecc013d450a..6bdcdf1022c 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals05.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals05 { - // Offset: 0x00000000 Length: 0x000006DB + // Offset: 0x00000000 Length: 0x000006CB } .mresource public FSharpOptimizationData.Equals05 { - // Offset: 0x000006E0 Length: 0x000003B9 + // Offset: 0x000006D0 Length: 0x000003B9 } .module Equals05.dll -// MVID: {59B18AEE-0759-CBC5-A745-0383EE8AB159} +// MVID: {611C550D-0759-CBC5-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x033B0000 +// Image base: 0x053D0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -123,109 +123,114 @@ instance int32 CompareTo(class Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 101 (0x65) + // Code size 102 (0x66) .maxstack 4 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals05.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_005b + .line 4,4 : 10,14 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals05.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_005c .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0059 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_005a .line 16707566,16707566 : 0,0 '' - IL_000c: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0011: stloc.1 - IL_0012: ldarg.0 - IL_0013: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: stloc.2 - IL_0019: ldarg.1 - IL_001a: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: bge.s IL_0028 + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: stloc.2 + IL_001a: ldarg.1 + IL_001b: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0020: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: bge.s IL_0029 .line 16707566,16707566 : 0,0 '' - IL_0024: ldc.i4.m1 + IL_0025: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002d + IL_0026: nop + IL_0027: br.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: cgt + IL_0029: ldloc.2 + IL_002a: ldloc.3 + IL_002b: cgt .line 16707566,16707566 : 0,0 '' - IL_002c: nop + IL_002d: nop .line 16707566,16707566 : 0,0 '' - IL_002d: stloc.0 - IL_002e: ldloc.0 - IL_002f: ldc.i4.0 - IL_0030: bge.s IL_0034 + IL_002e: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_002f: ldloc.0 + IL_0030: ldc.i4.0 + IL_0031: bge.s IL_0035 .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.0 - IL_0033: ret + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldloc.0 - IL_0035: ldc.i4.0 - IL_0036: ble.s IL_003a + IL_0035: ldloc.0 + IL_0036: ldc.i4.0 + IL_0037: ble.s IL_003b .line 16707566,16707566 : 0,0 '' - IL_0038: ldloc.0 - IL_0039: ret + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_003f: stloc.1 - IL_0040: ldarg.0 - IL_0041: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0046: stloc.2 - IL_0047: ldarg.1 - IL_0048: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_004d: stloc.3 - IL_004e: ldloc.2 - IL_004f: ldloc.3 - IL_0050: bge.s IL_0054 + IL_003b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0040: stloc.1 + IL_0041: ldarg.0 + IL_0042: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0047: stloc.2 + IL_0048: ldarg.1 + IL_0049: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_004e: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_004f: ldloc.2 + IL_0050: ldloc.3 + IL_0051: bge.s IL_0055 .line 16707566,16707566 : 0,0 '' - IL_0052: ldc.i4.m1 - IL_0053: ret + IL_0053: ldc.i4.m1 + IL_0054: ret .line 16707566,16707566 : 0,0 '' - IL_0054: ldloc.2 - IL_0055: ldloc.3 - IL_0056: cgt - IL_0058: ret + IL_0055: ldloc.2 + IL_0056: ldloc.3 + IL_0057: cgt + IL_0059: ret .line 16707566,16707566 : 0,0 '' - IL_0059: ldc.i4.1 - IL_005a: ret + IL_005a: ldc.i4.1 + IL_005b: ret .line 16707566,16707566 : 0,0 '' - IL_005b: ldarg.1 - IL_005c: ldnull - IL_005d: cgt.un - IL_005f: brfalse.s IL_0063 + IL_005c: ldarg.1 + IL_005d: ldnull + IL_005e: cgt.un + IL_0060: brfalse.s IL_0064 .line 16707566,16707566 : 0,0 '' - IL_0061: ldc.i4.m1 - IL_0062: ret + IL_0062: ldc.i4.m1 + IL_0063: ret .line 16707566,16707566 : 0,0 '' - IL_0063: ldc.i4.0 - IL_0064: ret + IL_0064: ldc.i4.0 + IL_0065: ret } // end of method KeyR::CompareTo .method public hidebysig virtual final @@ -257,6 +262,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -276,6 +282,7 @@ IL_001f: ldloc.0 IL_0020: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ IL_0025: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0026: ldloc.2 IL_0027: ldloc.3 IL_0028: bge.s IL_002e @@ -294,6 +301,7 @@ IL_0032: nop .line 16707566,16707566 : 0,0 '' IL_0033: stloc.1 + .line 16707566,16707566 : 0,0 '' IL_0034: ldloc.1 IL_0035: ldc.i4.0 IL_0036: bge.s IL_003a @@ -318,6 +326,7 @@ IL_0047: ldloc.0 IL_0048: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ IL_004d: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_004e: ldloc.2 IL_004f: ldloc.3 IL_0050: bge.s IL_0054 @@ -356,50 +365,52 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 54 (0x36) + // Code size 55 (0x37) .maxstack 7 .locals init ([0] int32 V_0) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0034 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldc.i4 0x9e3779b9 - IL_000d: ldarg.0 - IL_000e: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0013: ldloc.0 - IL_0014: ldc.i4.6 - IL_0015: shl - IL_0016: ldloc.0 - IL_0017: ldc.i4.2 - IL_0018: shr - IL_0019: add + .line 4,4 : 10,14 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0035 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.0 + IL_000f: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0014: ldloc.0 + IL_0015: ldc.i4.6 + IL_0016: shl + IL_0017: ldloc.0 + IL_0018: ldc.i4.2 + IL_0019: shr IL_001a: add IL_001b: add - IL_001c: stloc.0 - IL_001d: ldc.i4 0x9e3779b9 - IL_0022: ldarg.0 - IL_0023: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0028: ldloc.0 - IL_0029: ldc.i4.6 - IL_002a: shl - IL_002b: ldloc.0 - IL_002c: ldc.i4.2 - IL_002d: shr - IL_002e: add + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldc.i4 0x9e3779b9 + IL_0023: ldarg.0 + IL_0024: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0029: ldloc.0 + IL_002a: ldc.i4.6 + IL_002b: shl + IL_002c: ldloc.0 + IL_002d: ldc.i4.2 + IL_002e: shr IL_002f: add IL_0030: add - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ret + IL_0031: add + IL_0032: stloc.0 + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldc.i4.0 - IL_0035: ret + IL_0035: ldc.i4.0 + IL_0036: ret } // end of method KeyR::GetHashCode .method public hidebysig virtual final @@ -420,102 +431,107 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 57 (0x39) + // Code size 58 (0x3a) .maxstack 4 .locals init ([0] class Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR V_0) + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0031 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_002f + IL_0007: ldarg.1 + IL_0008: isinst Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0016: ldloc.0 - IL_0017: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001c: bne.un.s IL_002d + IL_0011: ldarg.0 + IL_0012: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0017: ldloc.0 + IL_0018: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_001d: bne.un.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_001e: ldarg.0 - IL_001f: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0024: ldloc.0 - IL_0025: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_002a: ceq - IL_002c: ret + IL_001f: ldarg.0 + IL_0020: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0025: ldloc.0 + IL_0026: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_002b: ceq + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_002e: ldc.i4.0 + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldarg.1 - IL_0032: ldnull - IL_0033: cgt.un - IL_0035: ldc.i4.0 - IL_0036: ceq - IL_0038: ret + IL_0032: ldarg.1 + IL_0033: ldnull + IL_0034: cgt.un + IL_0036: ldc.i4.0 + IL_0037: ceq + IL_0039: ret } // end of method KeyR::Equals .method public hidebysig virtual final instance bool Equals(class Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 53 (0x35) + // Code size 54 (0x36) .maxstack 8 + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_002d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_002b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_002c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0012: ldarg.1 - IL_0013: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: bne.un.s IL_0029 + IL_000d: ldarg.0 + IL_000e: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0013: ldarg.1 + IL_0014: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: bne.un.s IL_002a .line 16707566,16707566 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0020: ldarg.1 - IL_0021: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0026: ceq - IL_0028: ret + IL_001b: ldarg.0 + IL_001c: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0021: ldarg.1 + IL_0022: ldfld int32 Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0027: ceq + IL_0029: ret .line 16707566,16707566 : 0,0 '' - IL_0029: ldc.i4.0 - IL_002a: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 16707566,16707566 : 0,0 '' - IL_002b: ldc.i4.0 - IL_002c: ret + IL_002c: ldc.i4.0 + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldarg.1 - IL_002e: ldnull - IL_002f: cgt.un - IL_0031: ldc.i4.0 - IL_0032: ceq - IL_0034: ret + IL_002e: ldarg.1 + IL_002f: ldnull + IL_0030: cgt.un + IL_0032: ldc.i4.0 + IL_0033: ceq + IL_0035: ret } // end of method KeyR::Equals .method public hidebysig virtual final @@ -529,6 +545,7 @@ IL_0000: ldarg.1 IL_0001: isinst Equals05/EqualsMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals06.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals06.il.bsl index 91247bff24d..1aa09e5000a 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals06.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals06 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals06 { - // Offset: 0x00000000 Length: 0x00000896 + // Offset: 0x00000000 Length: 0x00000886 } .mresource public FSharpOptimizationData.Equals06 { - // Offset: 0x000008A0 Length: 0x0000068E + // Offset: 0x00000890 Length: 0x00000688 } .module Equals06.dll -// MVID: {59B18AEE-0759-31EC-A745-0383EE8AB159} +// MVID: {611C550D-0759-31EC-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01B90000 +// Image base: 0x056C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 110 (0x6e) + // Code size 111 (0x6f) .maxstack 5 .locals init ([0] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, @@ -187,93 +187,96 @@ [4] !a V_4, [5] !a V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals06.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0064 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0062 - - .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop - .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldloc.s V_5 - IL_002d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + .line 4,4 : 10,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals06.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0065 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0063 + + .line 16707566,16707566 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0027: stloc.s V_5 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldloc.s V_5 + IL_002e: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0032: stloc.2 - IL_0033: ldloc.2 - IL_0034: ldc.i4.0 - IL_0035: bge.s IL_0039 + IL_0033: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0034: ldloc.2 + IL_0035: ldc.i4.0 + IL_0036: bge.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0037: ldloc.2 - IL_0038: ret + IL_0038: ldloc.2 + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: ble.s IL_003f + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: ble.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0044: stloc.3 - IL_0045: ldloc.0 - IL_0046: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_004b: stloc.s V_4 - IL_004d: ldloc.1 - IL_004e: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0053: stloc.s V_5 - IL_0055: ldloc.3 - IL_0056: ldloc.s V_4 - IL_0058: ldloc.s V_5 - IL_005a: tail. - IL_005c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + IL_0040: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0045: stloc.3 + IL_0046: ldloc.0 + IL_0047: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_004c: stloc.s V_4 + IL_004e: ldloc.1 + IL_004f: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0054: stloc.s V_5 + IL_0056: ldloc.3 + IL_0057: ldloc.s V_4 + IL_0059: ldloc.s V_5 + IL_005b: tail. + IL_005d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0061: ret + IL_0062: ret .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.1 - IL_0063: ret + IL_0063: ldc.i4.1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldarg.1 - IL_0065: ldnull - IL_0066: cgt.un - IL_0068: brfalse.s IL_006c + IL_0065: ldarg.1 + IL_0066: ldnull + IL_0067: cgt.un + IL_0069: brfalse.s IL_006d .line 16707566,16707566 : 0,0 '' - IL_006a: ldc.i4.m1 - IL_006b: ret + IL_006b: ldc.i4.m1 + IL_006c: ret .line 16707566,16707566 : 0,0 '' - IL_006c: ldc.i4.0 - IL_006d: ret + IL_006d: ldc.i4.0 + IL_006e: ret } // end of method GenericKey`1::CompareTo .method public hidebysig virtual final @@ -308,6 +311,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -341,6 +345,7 @@ !!0, !!0) IL_0038: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0039: ldloc.3 IL_003a: ldc.i4.0 IL_003b: bge.s IL_003f @@ -398,69 +403,72 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) + // Code size 77 (0x4d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0019: stloc.2 - IL_001a: ldarg.1 - IL_001b: ldloc.2 - IL_001c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + .line 4,4 : 10,20 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_004b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_001a: stloc.2 + IL_001b: ldarg.1 + IL_001c: ldloc.2 + IL_001d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_0021: ldloc.0 - IL_0022: ldc.i4.6 - IL_0023: shl - IL_0024: ldloc.0 - IL_0025: ldc.i4.2 - IL_0026: shr - IL_0027: add + IL_0022: ldloc.0 + IL_0023: ldc.i4.6 + IL_0024: shl + IL_0025: ldloc.0 + IL_0026: ldc.i4.2 + IL_0027: shr IL_0028: add IL_0029: add - IL_002a: stloc.0 - IL_002b: ldc.i4 0x9e3779b9 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0036: stloc.2 - IL_0037: ldarg.1 - IL_0038: ldloc.2 - IL_0039: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002a: add + IL_002b: stloc.0 + IL_002c: ldc.i4 0x9e3779b9 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0037: stloc.2 + IL_0038: ldarg.1 + IL_0039: ldloc.2 + IL_003a: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_003e: ldloc.0 - IL_003f: ldc.i4.6 - IL_0040: shl - IL_0041: ldloc.0 - IL_0042: ldc.i4.2 - IL_0043: shr - IL_0044: add + IL_003f: ldloc.0 + IL_0040: ldc.i4.6 + IL_0041: shl + IL_0042: ldloc.0 + IL_0043: ldc.i4.2 + IL_0044: shr IL_0045: add IL_0046: add - IL_0047: stloc.0 - IL_0048: ldloc.0 - IL_0049: ret + IL_0047: add + IL_0048: stloc.0 + IL_0049: ldloc.0 + IL_004a: ret .line 16707566,16707566 : 0,0 '' - IL_004a: ldc.i4.0 - IL_004b: ret + IL_004b: ldc.i4.0 + IL_004c: ret } // end of method GenericKey`1::GetHashCode .method public hidebysig virtual final @@ -481,152 +489,159 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 87 (0x57) + // Code size 88 (0x58) .maxstack 5 .locals init ([0] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_2, [3] !a V_3, [4] !a V_4) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004f - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_004d - - .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop - .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001c: stloc.3 - IL_001d: ldloc.2 - IL_001e: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0023: stloc.s V_4 - IL_0025: ldarg.2 - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0050 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_004e + + .line 16707566,16707566 : 0,0 '' + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001d: stloc.3 + IL_001e: ldloc.2 + IL_001f: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0024: stloc.s V_4 + IL_0026: ldarg.2 + IL_0027: ldloc.3 + IL_0028: ldloc.s V_4 + IL_002a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_002e: brfalse.s IL_004b - - .line 16707566,16707566 : 0,0 '' - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_003d: stloc.s V_4 - IL_003f: ldarg.2 - IL_0040: ldloc.3 - IL_0041: ldloc.s V_4 - IL_0043: tail. - IL_0045: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002f: brfalse.s IL_004c + + .line 16707566,16707566 : 0,0 '' + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_003e: stloc.s V_4 + IL_0040: ldarg.2 + IL_0041: ldloc.3 + IL_0042: ldloc.s V_4 + IL_0044: tail. + IL_0046: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_004a: ret + IL_004b: ret .line 16707566,16707566 : 0,0 '' - IL_004b: ldc.i4.0 - IL_004c: ret + IL_004c: ldc.i4.0 + IL_004d: ret .line 16707566,16707566 : 0,0 '' - IL_004d: ldc.i4.0 - IL_004e: ret + IL_004e: ldc.i4.0 + IL_004f: ret .line 16707566,16707566 : 0,0 '' - IL_004f: ldarg.1 - IL_0050: ldnull - IL_0051: cgt.un - IL_0053: ldc.i4.0 - IL_0054: ceq - IL_0056: ret + IL_0050: ldarg.1 + IL_0051: ldnull + IL_0052: cgt.un + IL_0054: ldc.i4.0 + IL_0055: ceq + IL_0057: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final instance bool Equals(class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 77 (0x4d) + // Code size 78 (0x4e) .maxstack 4 .locals init ([0] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2, [3] !a V_3) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0045 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0043 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0044 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0019: stloc.2 + IL_001a: ldloc.1 + IL_001b: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0027: brfalse.s IL_0041 - - .line 16707566,16707566 : 0,0 '' - IL_0029: ldloc.0 - IL_002a: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_002f: stloc.2 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldloc.3 - IL_0039: tail. - IL_003b: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_0028: brfalse.s IL_0042 + + .line 16707566,16707566 : 0,0 '' + IL_002a: ldloc.0 + IL_002b: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0030: stloc.2 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldloc.3 + IL_003a: tail. + IL_003c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0040: ret + IL_0041: ret .line 16707566,16707566 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0042: ldc.i4.0 + IL_0043: ret .line 16707566,16707566 : 0,0 '' - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0044: ldc.i4.0 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: ldarg.1 - IL_0046: ldnull - IL_0047: cgt.un - IL_0049: ldc.i4.0 - IL_004a: ceq - IL_004c: ret + IL_0046: ldarg.1 + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: ldc.i4.0 + IL_004b: ceq + IL_004d: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final @@ -640,6 +655,7 @@ IL_0000: ldarg.1 IL_0001: isinst class Equals06/EqualsMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals07.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals07.il.bsl index 91f97c289a2..e652f362b84 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals07.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals07 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals07 { - // Offset: 0x00000000 Length: 0x0000022D + // Offset: 0x00000000 Length: 0x00000229 } .mresource public FSharpOptimizationData.Equals07 { - // Offset: 0x00000238 Length: 0x000000AF + // Offset: 0x00000230 Length: 0x000000AF } .module Equals07.dll -// MVID: {59B18AEE-0759-AE27-A745-0383EE8AB159} +// MVID: {60BE1F16-0759-AE27-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01C80000 +// Image base: 0x06B40000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ [2] uint8[] t2, [3] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals07.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals07.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 6,6 : 8,35 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals08.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals08.il.bsl index 55da6ee102e..2a51fe48508 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals08.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals08.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals08 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals08 { - // Offset: 0x00000000 Length: 0x0000022D + // Offset: 0x00000000 Length: 0x00000229 } .mresource public FSharpOptimizationData.Equals08 { - // Offset: 0x00000238 Length: 0x000000AF + // Offset: 0x00000230 Length: 0x000000AF } .module Equals08.dll -// MVID: {59B18AEE-0759-659E-A745-0383EE8AB159} +// MVID: {60BE1F16-0759-659E-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01090000 +// Image base: 0x05730000 // =============== CLASS MEMBERS DECLARATION =================== @@ -64,7 +64,7 @@ [2] int32[] t2, [3] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals08.fsx' + .line 5,5 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals08.fsx' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 6,6 : 8,31 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals09.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals09.il.bsl index 8985acaa02b..bf09abc529f 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals09.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Equals09.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Equals09 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Equals09 { - // Offset: 0x00000000 Length: 0x00000AA0 + // Offset: 0x00000000 Length: 0x00000A90 } .mresource public FSharpOptimizationData.Equals09 { - // Offset: 0x00000AA8 Length: 0x0000058B + // Offset: 0x00000A98 Length: 0x0000058B } .module Equals09.dll -// MVID: {59B18AEE-0759-46D9-A745-0383EE8AB159} +// MVID: {611C550D-0759-46D9-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02720000 +// Image base: 0x06950000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Equals09.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Equals09.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Equals09/EqualsMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_1, [2] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 @@ -792,7 +812,7 @@ instance int32 CompareTo(class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 169 (0xa9) + // Code size 170 (0xaa) .maxstack 5 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -805,116 +825,120 @@ [8] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_8, [9] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_9, [10] int32 V_10) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_009f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_00a0 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: ldnull - IL_000b: cgt.un - IL_000d: brfalse IL_009d + IL_000a: ldarg.1 + IL_000b: ldnull + IL_000c: cgt.un + IL_000e: brfalse IL_009e .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: pop + IL_0013: ldarg.0 + IL_0014: pop .line 16707566,16707566 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: stloc.0 - IL_0016: ldarg.1 - IL_0017: stloc.1 - IL_0018: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_001d: stloc.3 - IL_001e: ldloc.0 - IL_001f: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0024: stloc.s V_4 - IL_0026: ldloc.1 - IL_0027: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_002c: stloc.s V_5 - IL_002e: ldloc.s V_4 - IL_0030: ldloc.s V_5 - IL_0032: ldloc.3 - IL_0033: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0015: ldarg.0 + IL_0016: stloc.0 + IL_0017: ldarg.1 + IL_0018: stloc.1 + IL_0019: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_001e: stloc.3 + IL_001f: ldloc.0 + IL_0020: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0025: stloc.s V_4 + IL_0027: ldloc.1 + IL_0028: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_002d: stloc.s V_5 + IL_002f: ldloc.s V_4 + IL_0031: ldloc.s V_5 + IL_0033: ldloc.3 + IL_0034: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0038: stloc.2 - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: bge.s IL_003f + IL_0039: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: bge.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: ldloc.2 - IL_0040: ldc.i4.0 - IL_0041: ble.s IL_0045 + IL_0040: ldloc.2 + IL_0041: ldc.i4.0 + IL_0042: ble.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0043: ldloc.2 - IL_0044: ret + IL_0044: ldloc.2 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004a: stloc.3 - IL_004b: ldloc.0 - IL_004c: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0051: stloc.s V_6 - IL_0053: ldloc.1 - IL_0054: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0059: stloc.s V_7 - IL_005b: ldloc.s V_6 - IL_005d: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0062: stloc.s V_4 - IL_0064: ldloc.s V_6 - IL_0066: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_006b: stloc.s V_5 - IL_006d: ldloc.s V_7 - IL_006f: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0074: stloc.s V_8 - IL_0076: ldloc.s V_7 - IL_0078: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_007d: stloc.s V_9 - IL_007f: ldloc.s V_4 - IL_0081: ldloc.s V_8 - IL_0083: ldloc.3 - IL_0084: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004b: stloc.3 + IL_004c: ldloc.0 + IL_004d: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0052: stloc.s V_6 + IL_0054: ldloc.1 + IL_0055: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_005a: stloc.s V_7 + IL_005c: ldloc.s V_6 + IL_005e: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0063: stloc.s V_4 + IL_0065: ldloc.s V_6 + IL_0067: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_006c: stloc.s V_5 + IL_006e: ldloc.s V_7 + IL_0070: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0075: stloc.s V_8 + IL_0077: ldloc.s V_7 + IL_0079: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_007e: stloc.s V_9 + IL_0080: ldloc.s V_4 + IL_0082: ldloc.s V_8 + IL_0084: ldloc.3 + IL_0085: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0089: stloc.s V_10 - IL_008b: ldloc.s V_10 - IL_008d: brfalse.s IL_0092 + IL_008a: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' + IL_008c: ldloc.s V_10 + IL_008e: brfalse.s IL_0093 .line 16707566,16707566 : 0,0 '' - IL_008f: ldloc.s V_10 - IL_0091: ret + IL_0090: ldloc.s V_10 + IL_0092: ret .line 16707566,16707566 : 0,0 '' - IL_0092: ldloc.s V_5 - IL_0094: ldloc.s V_9 - IL_0096: ldloc.3 - IL_0097: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0093: ldloc.s V_5 + IL_0095: ldloc.s V_9 + IL_0097: ldloc.3 + IL_0098: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_009c: ret + IL_009d: ret .line 16707566,16707566 : 0,0 '' - IL_009d: ldc.i4.1 - IL_009e: ret + IL_009e: ldc.i4.1 + IL_009f: ret .line 16707566,16707566 : 0,0 '' - IL_009f: ldarg.1 - IL_00a0: ldnull - IL_00a1: cgt.un - IL_00a3: brfalse.s IL_00a7 + IL_00a0: ldarg.1 + IL_00a1: ldnull + IL_00a2: cgt.un + IL_00a4: brfalse.s IL_00a8 .line 16707566,16707566 : 0,0 '' - IL_00a5: ldc.i4.m1 - IL_00a6: ret + IL_00a6: ldc.i4.m1 + IL_00a7: ret .line 16707566,16707566 : 0,0 '' - IL_00a7: ldc.i4.0 - IL_00a8: ret + IL_00a8: ldc.i4.0 + IL_00a9: ret } // end of method KeyWithInnerKeys::CompareTo .method public hidebysig virtual final @@ -953,6 +977,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -985,6 +1010,7 @@ IL_0039: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_003e: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_003f: ldloc.3 IL_0040: ldc.i4.0 IL_0041: bge.s IL_0045 @@ -1027,6 +1053,7 @@ IL_0084: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_0089: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' IL_008b: ldloc.s V_10 IL_008d: brfalse.s IL_0092 @@ -1066,7 +1093,7 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 107 (0x6b) + // Code size 108 (0x6c) .maxstack 7 .locals init ([0] int32 V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1074,76 +1101,79 @@ [3] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_3, [4] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_4, [5] int32 V_5) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0069 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0019: stloc.2 - IL_001a: ldloc.2 - IL_001b: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0020: stloc.3 - IL_0021: ldloc.2 - IL_0022: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0027: stloc.s V_4 - IL_0029: ldloc.3 - IL_002a: ldarg.1 - IL_002b: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0030: stloc.s V_5 - IL_0032: ldloc.s V_5 - IL_0034: ldc.i4.5 - IL_0035: shl - IL_0036: ldloc.s V_5 - IL_0038: add - IL_0039: ldloc.s V_4 - IL_003b: ldarg.1 - IL_003c: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0041: xor - IL_0042: ldloc.0 - IL_0043: ldc.i4.6 - IL_0044: shl - IL_0045: ldloc.0 - IL_0046: ldc.i4.2 - IL_0047: shr - IL_0048: add + .line 5,5 : 10,26 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006a + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0021: stloc.3 + IL_0022: ldloc.2 + IL_0023: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0028: stloc.s V_4 + IL_002a: ldloc.3 + IL_002b: ldarg.1 + IL_002c: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0031: stloc.s V_5 + IL_0033: ldloc.s V_5 + IL_0035: ldc.i4.5 + IL_0036: shl + IL_0037: ldloc.s V_5 + IL_0039: add + IL_003a: ldloc.s V_4 + IL_003c: ldarg.1 + IL_003d: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0042: xor + IL_0043: ldloc.0 + IL_0044: ldc.i4.6 + IL_0045: shl + IL_0046: ldloc.0 + IL_0047: ldc.i4.2 + IL_0048: shr IL_0049: add IL_004a: add - IL_004b: stloc.0 - IL_004c: ldc.i4 0x9e3779b9 - IL_0051: ldloc.1 - IL_0052: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0057: ldarg.1 - IL_0058: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_005d: ldloc.0 - IL_005e: ldc.i4.6 - IL_005f: shl - IL_0060: ldloc.0 - IL_0061: ldc.i4.2 - IL_0062: shr - IL_0063: add + IL_004b: add + IL_004c: stloc.0 + IL_004d: ldc.i4 0x9e3779b9 + IL_0052: ldloc.1 + IL_0053: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0058: ldarg.1 + IL_0059: callvirt instance int32 Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_005e: ldloc.0 + IL_005f: ldc.i4.6 + IL_0060: shl + IL_0061: ldloc.0 + IL_0062: ldc.i4.2 + IL_0063: shr IL_0064: add IL_0065: add - IL_0066: stloc.0 - IL_0067: ldloc.0 - IL_0068: ret + IL_0066: add + IL_0067: stloc.0 + IL_0068: ldloc.0 + IL_0069: ret .line 16707566,16707566 : 0,0 '' - IL_0069: ldc.i4.0 - IL_006a: ret + IL_006a: ldc.i4.0 + IL_006b: ret } // end of method KeyWithInnerKeys::GetHashCode .method public hidebysig virtual final @@ -1164,7 +1194,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 138 (0x8a) + // Code size 139 (0x8b) .maxstack 5 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1175,155 +1205,163 @@ [6] class [mscorlib]System.Tuple`2 V_6, [7] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_7, [8] class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key V_8) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_0082 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_0083 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: brfalse.s IL_0080 + IL_000a: ldarg.1 + IL_000b: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys + IL_0010: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: brfalse.s IL_0081 .line 16707566,16707566 : 0,0 '' - IL_0013: ldarg.0 - IL_0014: pop + IL_0014: ldarg.0 + IL_0015: pop .line 16707566,16707566 : 0,0 '' - IL_0015: ldarg.0 - IL_0016: stloc.1 - IL_0017: ldloc.0 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0026: stloc.s V_4 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldarg.2 - IL_002c: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0016: ldarg.0 + IL_0017: stloc.1 + IL_0018: ldloc.0 + IL_0019: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_001a: ldloc.1 + IL_001b: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0027: stloc.s V_4 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldarg.2 + IL_002d: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_0031: brfalse.s IL_007e + IL_0032: brfalse.s IL_007f .line 16707566,16707566 : 0,0 '' - IL_0033: ldloc.1 - IL_0034: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0039: stloc.s V_5 - IL_003b: ldloc.2 - IL_003c: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0041: stloc.s V_6 - IL_0043: ldloc.s V_5 - IL_0045: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_004a: stloc.3 - IL_004b: ldloc.s V_5 - IL_004d: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0052: stloc.s V_4 - IL_0054: ldloc.s V_6 - IL_0056: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_005b: stloc.s V_7 - IL_005d: ldloc.s V_6 - IL_005f: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0064: stloc.s V_8 - IL_0066: ldloc.3 - IL_0067: ldloc.s V_7 - IL_0069: ldarg.2 - IL_006a: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0034: ldloc.1 + IL_0035: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_003a: stloc.s V_5 + IL_003c: ldloc.2 + IL_003d: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0042: stloc.s V_6 + IL_0044: ldloc.s V_5 + IL_0046: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_004b: stloc.3 + IL_004c: ldloc.s V_5 + IL_004e: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0053: stloc.s V_4 + IL_0055: ldloc.s V_6 + IL_0057: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_005c: stloc.s V_7 + IL_005e: ldloc.s V_6 + IL_0060: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0065: stloc.s V_8 + .line 16707566,16707566 : 0,0 '' + IL_0067: ldloc.3 + IL_0068: ldloc.s V_7 + IL_006a: ldarg.2 + IL_006b: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_006f: brfalse.s IL_007c + IL_0070: brfalse.s IL_007d .line 16707566,16707566 : 0,0 '' - IL_0071: ldloc.s V_4 - IL_0073: ldloc.s V_8 - IL_0075: ldarg.2 - IL_0076: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0072: ldloc.s V_4 + IL_0074: ldloc.s V_8 + IL_0076: ldarg.2 + IL_0077: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_007b: ret + IL_007c: ret .line 16707566,16707566 : 0,0 '' - IL_007c: ldc.i4.0 - IL_007d: ret + IL_007d: ldc.i4.0 + IL_007e: ret .line 16707566,16707566 : 0,0 '' - IL_007e: ldc.i4.0 - IL_007f: ret + IL_007f: ldc.i4.0 + IL_0080: ret .line 16707566,16707566 : 0,0 '' - IL_0080: ldc.i4.0 - IL_0081: ret + IL_0081: ldc.i4.0 + IL_0082: ret .line 16707566,16707566 : 0,0 '' - IL_0082: ldarg.1 - IL_0083: ldnull - IL_0084: cgt.un - IL_0086: ldc.i4.0 - IL_0087: ceq - IL_0089: ret + IL_0083: ldarg.1 + IL_0084: ldnull + IL_0085: cgt.un + IL_0087: ldc.i4.0 + IL_0088: ceq + IL_008a: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final instance bool Equals(class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 69 (0x45) + // Code size 70 (0x46) .maxstack 4 .locals init ([0] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_003b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_003c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0018: ldloc.1 - IL_0019: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001e: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key) - IL_0023: brfalse.s IL_0039 - - .line 16707566,16707566 : 0,0 '' - IL_0025: ldloc.0 - IL_0026: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_002b: ldloc.1 - IL_002c: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0031: tail. - IL_0033: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0019: ldloc.1 + IL_001a: ldfld class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_001f: callvirt instance bool Equals09/EqualsMicroPerfAndCodeGenerationTests/Key::Equals(class Equals09/EqualsMicroPerfAndCodeGenerationTests/Key) + IL_0024: brfalse.s IL_003a + + .line 16707566,16707566 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_002c: ldloc.1 + IL_002d: ldfld class [mscorlib]System.Tuple`2 Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0032: tail. + IL_0034: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, !!0) - IL_0038: ret + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldc.i4.0 - IL_003a: ret + IL_003a: ldc.i4.0 + IL_003b: ret .line 16707566,16707566 : 0,0 '' - IL_003b: ldc.i4.0 - IL_003c: ret + IL_003c: ldc.i4.0 + IL_003d: ret .line 16707566,16707566 : 0,0 '' - IL_003d: ldarg.1 - IL_003e: ldnull - IL_003f: cgt.un - IL_0041: ldc.i4.0 - IL_0042: ceq - IL_0044: ret + IL_003e: ldarg.1 + IL_003f: ldnull + IL_0040: cgt.un + IL_0042: ldc.i4.0 + IL_0043: ceq + IL_0045: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final @@ -1337,6 +1375,7 @@ IL_0000: ldarg.1 IL_0001: isinst Equals09/EqualsMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash01.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash01.il.bsl index cb63a42741b..5d4ed72b3e4 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash01 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash01 { - // Offset: 0x00000000 Length: 0x00000219 + // Offset: 0x00000000 Length: 0x00000215 } .mresource public FSharpOptimizationData.Hash01 { // Offset: 0x00000220 Length: 0x000000A9 } .module Hash01.dll -// MVID: {59B18AEE-9642-78D3-A745-0383EE8AB159} +// MVID: {60BE1F16-9642-78D3-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02FB0000 +// Image base: 0x06B70000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ .locals init ([0] int32 x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash01.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash01.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 6,6 : 8,32 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash02.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash02.il.bsl index 985bcae6f37..48f1c42fb76 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash02 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash02 { - // Offset: 0x00000000 Length: 0x00000220 + // Offset: 0x00000000 Length: 0x0000021C } .mresource public FSharpOptimizationData.Hash02 { - // Offset: 0x00000228 Length: 0x0000010B + // Offset: 0x00000220 Length: 0x0000010B } .module Hash02.dll -// MVID: {59B18AEE-9642-796E-A745-0383EE8AB159} +// MVID: {60BE1F16-9642-796E-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01920000 +// Image base: 0x05400000 // =============== CLASS MEMBERS DECLARATION =================== @@ -60,7 +60,7 @@ // Code size 1 (0x1) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,8 : 8,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash02.fsx' + .line 7,8 : 8,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash02.fsx' IL_0000: ret } // end of method HashMicroPerfAndCodeGenerationTests::f4_triple diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash03.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash03.il.bsl index 4a2c0b76fb2..08951863dfe 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash03.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash03.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Hash03 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Hash03 { - // Offset: 0x00000000 Length: 0x00000220 + // Offset: 0x00000000 Length: 0x0000021C } .mresource public FSharpOptimizationData.Hash03 { - // Offset: 0x00000228 Length: 0x000000B0 + // Offset: 0x00000220 Length: 0x000000B0 } .module Hash03.dll -// MVID: {59B18AEE-9642-788D-A745-0383EE8AB159} +// MVID: {60BE1F16-9642-788D-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02DA0000 +// Image base: 0x06A60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +67,7 @@ .locals init ([0] int32 x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash03.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash03.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 7,7 : 8,32 '' @@ -74,7 +79,7 @@ IL_0006: ldc.i4 0x483 IL_000b: ldc.i4.s 99 IL_000d: ldstr "5" - IL_0012: callvirt instance int32 [mscorlib]System.Object::GetHashCode() + IL_0012: callvirt instance int32 [netstandard]System.Object::GetHashCode() IL_0017: xor IL_0018: xor IL_0019: stloc.0 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash04.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash04.il.bsl index 550faa686b6..e48efdc6f7a 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash04.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash04.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,12 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 +} +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) // .{...-.Q + .ver 2:0:0:0 } .assembly Hash04 { @@ -29,20 +34,20 @@ } .mresource public FSharpSignatureData.Hash04 { - // Offset: 0x00000000 Length: 0x00000220 + // Offset: 0x00000000 Length: 0x0000021C } .mresource public FSharpOptimizationData.Hash04 { - // Offset: 0x00000228 Length: 0x000000B0 + // Offset: 0x00000220 Length: 0x000000B0 } .module Hash04.dll -// MVID: {59B18AEE-9642-7838-A745-0383EE8AB159} +// MVID: {60BE1F16-9642-7838-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x012B0000 +// Image base: 0x05A90000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +67,7 @@ .locals init ([0] int32 x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash04.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash04.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 7,7 : 8,32 '' @@ -74,7 +79,7 @@ IL_0006: ldc.i4 0x483 IL_000b: ldc.i4.s 99 IL_000d: ldstr "5" - IL_0012: callvirt instance int32 [mscorlib]System.Object::GetHashCode() + IL_0012: callvirt instance int32 [netstandard]System.Object::GetHashCode() IL_0017: xor IL_0018: xor IL_0019: stloc.0 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash05.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash05.il.bsl index 50ea47e8580..aa19d121fe8 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash05.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash05.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash05 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash05 { - // Offset: 0x00000000 Length: 0x000006E0 + // Offset: 0x00000000 Length: 0x000006D0 } .mresource public FSharpOptimizationData.Hash05 { - // Offset: 0x000006E8 Length: 0x000003B1 + // Offset: 0x000006D8 Length: 0x000003B1 } .module Hash05.dll -// MVID: {59B18AEE-9642-7857-A745-0383EE8AB159} +// MVID: {611C550D-9642-7857-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01AC0000 +// Image base: 0x06960000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Hash05/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash05.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 5,5 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash05.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Hash05/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 5,5 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_1, [2] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_2) + .line 5,5 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Hash05/HashMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Hash05/HashMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0017: ldloc.1 + IL_0018: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Hash05/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash05/HashMicroPerfAndCodeGenerationTests/Key V_1) + .line 5,5 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_0013: ldloc.0 + IL_0014: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Hash05/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Hash05/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash06.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash06.il.bsl index df45d5ddbdb..bad5e3f191b 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash06.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash06.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash06 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash06 { - // Offset: 0x00000000 Length: 0x000006E1 + // Offset: 0x00000000 Length: 0x000006D1 } .mresource public FSharpOptimizationData.Hash06 { - // Offset: 0x000006E8 Length: 0x000003B2 + // Offset: 0x000006D8 Length: 0x000003B2 } .module Hash06.dll -// MVID: {59B18AEE-9642-78F2-A745-0383EE8AB159} +// MVID: {611C550D-9642-78F2-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01040000 +// Image base: 0x06F60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Hash06/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash06.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash06.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Hash06/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_1, [2] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Hash06/HashMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Hash06/HashMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0017: ldloc.1 + IL_0018: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Hash06/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash06/HashMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_0013: ldloc.0 + IL_0014: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Hash06/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Hash06/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash07.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash07.il.bsl index b57640a2818..ab4e803086f 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash07.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash07.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash07 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash07 { - // Offset: 0x00000000 Length: 0x0000021A + // Offset: 0x00000000 Length: 0x00000216 } .mresource public FSharpOptimizationData.Hash07 { // Offset: 0x00000220 Length: 0x000000AA } .module Hash07.dll -// MVID: {59B18AEE-9642-7811-A745-0383EE8AB159} +// MVID: {60BE1F16-9642-7811-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x010A0000 +// Image base: 0x06740000 // =============== CLASS MEMBERS DECLARATION =================== @@ -62,7 +62,7 @@ .locals init ([0] int32 x, [1] int32 i) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash07.fsx' + .line 5,5 : 8,25 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash07.fsx' IL_0000: ldc.i4.1 IL_0001: stloc.0 .line 6,6 : 8,32 '' diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash08.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash08.il.bsl index a0945b3885d..b8dedc27dc9 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash08.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash08.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash08 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash08 { - // Offset: 0x00000000 Length: 0x000006D3 + // Offset: 0x00000000 Length: 0x000006C3 } .mresource public FSharpOptimizationData.Hash08 { - // Offset: 0x000006D8 Length: 0x000003B3 + // Offset: 0x000006C8 Length: 0x000003B3 } .module Hash08.dll -// MVID: {59B18AEE-9642-77BC-A745-0383EE8AB159} +// MVID: {611C550D-9642-77BC-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01AA0000 +// Image base: 0x06580000 // =============== CLASS MEMBERS DECLARATION =================== @@ -123,109 +123,114 @@ instance int32 CompareTo(class Hash08/HashMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 101 (0x65) + // Code size 102 (0x66) .maxstack 4 .locals init ([0] int32 V_0, [1] class [mscorlib]System.Collections.IComparer V_1, [2] int32 V_2, [3] int32 V_3) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash08.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_005b + .line 4,4 : 10,14 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash08.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_005c .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0059 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_005a .line 16707566,16707566 : 0,0 '' - IL_000c: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0011: stloc.1 - IL_0012: ldarg.0 - IL_0013: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: stloc.2 - IL_0019: ldarg.1 - IL_001a: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: bge.s IL_0028 + IL_000d: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0012: stloc.1 + IL_0013: ldarg.0 + IL_0014: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: stloc.2 + IL_001a: ldarg.1 + IL_001b: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0020: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: bge.s IL_0029 .line 16707566,16707566 : 0,0 '' - IL_0024: ldc.i4.m1 + IL_0025: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_0025: nop - IL_0026: br.s IL_002d + IL_0026: nop + IL_0027: br.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0028: ldloc.2 - IL_0029: ldloc.3 - IL_002a: cgt + IL_0029: ldloc.2 + IL_002a: ldloc.3 + IL_002b: cgt .line 16707566,16707566 : 0,0 '' - IL_002c: nop + IL_002d: nop .line 16707566,16707566 : 0,0 '' - IL_002d: stloc.0 - IL_002e: ldloc.0 - IL_002f: ldc.i4.0 - IL_0030: bge.s IL_0034 + IL_002e: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_002f: ldloc.0 + IL_0030: ldc.i4.0 + IL_0031: bge.s IL_0035 .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.0 - IL_0033: ret + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldloc.0 - IL_0035: ldc.i4.0 - IL_0036: ble.s IL_003a + IL_0035: ldloc.0 + IL_0036: ldc.i4.0 + IL_0037: ble.s IL_003b .line 16707566,16707566 : 0,0 '' - IL_0038: ldloc.0 - IL_0039: ret + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_003f: stloc.1 - IL_0040: ldarg.0 - IL_0041: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0046: stloc.2 - IL_0047: ldarg.1 - IL_0048: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_004d: stloc.3 - IL_004e: ldloc.2 - IL_004f: ldloc.3 - IL_0050: bge.s IL_0054 + IL_003b: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0040: stloc.1 + IL_0041: ldarg.0 + IL_0042: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0047: stloc.2 + IL_0048: ldarg.1 + IL_0049: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_004e: stloc.3 + .line 16707566,16707566 : 0,0 '' + IL_004f: ldloc.2 + IL_0050: ldloc.3 + IL_0051: bge.s IL_0055 .line 16707566,16707566 : 0,0 '' - IL_0052: ldc.i4.m1 - IL_0053: ret + IL_0053: ldc.i4.m1 + IL_0054: ret .line 16707566,16707566 : 0,0 '' - IL_0054: ldloc.2 - IL_0055: ldloc.3 - IL_0056: cgt - IL_0058: ret + IL_0055: ldloc.2 + IL_0056: ldloc.3 + IL_0057: cgt + IL_0059: ret .line 16707566,16707566 : 0,0 '' - IL_0059: ldc.i4.1 - IL_005a: ret + IL_005a: ldc.i4.1 + IL_005b: ret .line 16707566,16707566 : 0,0 '' - IL_005b: ldarg.1 - IL_005c: ldnull - IL_005d: cgt.un - IL_005f: brfalse.s IL_0063 + IL_005c: ldarg.1 + IL_005d: ldnull + IL_005e: cgt.un + IL_0060: brfalse.s IL_0064 .line 16707566,16707566 : 0,0 '' - IL_0061: ldc.i4.m1 - IL_0062: ret + IL_0062: ldc.i4.m1 + IL_0063: ret .line 16707566,16707566 : 0,0 '' - IL_0063: ldc.i4.0 - IL_0064: ret + IL_0064: ldc.i4.0 + IL_0065: ret } // end of method KeyR::CompareTo .method public hidebysig virtual final @@ -257,6 +262,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Hash08/HashMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -276,6 +282,7 @@ IL_001f: ldloc.0 IL_0020: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ IL_0025: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0026: ldloc.2 IL_0027: ldloc.3 IL_0028: bge.s IL_002e @@ -294,6 +301,7 @@ IL_0032: nop .line 16707566,16707566 : 0,0 '' IL_0033: stloc.1 + .line 16707566,16707566 : 0,0 '' IL_0034: ldloc.1 IL_0035: ldc.i4.0 IL_0036: bge.s IL_003a @@ -318,6 +326,7 @@ IL_0047: ldloc.0 IL_0048: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ IL_004d: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_004e: ldloc.2 IL_004f: ldloc.3 IL_0050: bge.s IL_0054 @@ -356,50 +365,52 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 54 (0x36) + // Code size 55 (0x37) .maxstack 7 .locals init ([0] int32 V_0) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0034 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldc.i4 0x9e3779b9 - IL_000d: ldarg.0 - IL_000e: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0013: ldloc.0 - IL_0014: ldc.i4.6 - IL_0015: shl - IL_0016: ldloc.0 - IL_0017: ldc.i4.2 - IL_0018: shr - IL_0019: add + .line 4,4 : 10,14 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0035 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + IL_0009: ldc.i4 0x9e3779b9 + IL_000e: ldarg.0 + IL_000f: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0014: ldloc.0 + IL_0015: ldc.i4.6 + IL_0016: shl + IL_0017: ldloc.0 + IL_0018: ldc.i4.2 + IL_0019: shr IL_001a: add IL_001b: add - IL_001c: stloc.0 - IL_001d: ldc.i4 0x9e3779b9 - IL_0022: ldarg.0 - IL_0023: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0028: ldloc.0 - IL_0029: ldc.i4.6 - IL_002a: shl - IL_002b: ldloc.0 - IL_002c: ldc.i4.2 - IL_002d: shr - IL_002e: add + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldc.i4 0x9e3779b9 + IL_0023: ldarg.0 + IL_0024: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0029: ldloc.0 + IL_002a: ldc.i4.6 + IL_002b: shl + IL_002c: ldloc.0 + IL_002d: ldc.i4.2 + IL_002e: shr IL_002f: add IL_0030: add - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ret + IL_0031: add + IL_0032: stloc.0 + IL_0033: ldloc.0 + IL_0034: ret .line 16707566,16707566 : 0,0 '' - IL_0034: ldc.i4.0 - IL_0035: ret + IL_0035: ldc.i4.0 + IL_0036: ret } // end of method KeyR::GetHashCode .method public hidebysig virtual final @@ -420,102 +431,107 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 57 (0x39) + // Code size 58 (0x3a) .maxstack 4 .locals init ([0] class Hash08/HashMicroPerfAndCodeGenerationTests/KeyR V_0) + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0031 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Hash08/HashMicroPerfAndCodeGenerationTests/KeyR - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_002f + IL_0007: ldarg.1 + IL_0008: isinst Hash08/HashMicroPerfAndCodeGenerationTests/KeyR + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0016: ldloc.0 - IL_0017: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_001c: bne.un.s IL_002d + IL_0011: ldarg.0 + IL_0012: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0017: ldloc.0 + IL_0018: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_001d: bne.un.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_001e: ldarg.0 - IL_001f: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0024: ldloc.0 - IL_0025: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_002a: ceq - IL_002c: ret + IL_001f: ldarg.0 + IL_0020: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0025: ldloc.0 + IL_0026: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_002b: ceq + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldc.i4.0 - IL_002e: ret + IL_002e: ldc.i4.0 + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldarg.1 - IL_0032: ldnull - IL_0033: cgt.un - IL_0035: ldc.i4.0 - IL_0036: ceq - IL_0038: ret + IL_0032: ldarg.1 + IL_0033: ldnull + IL_0034: cgt.un + IL_0036: ldc.i4.0 + IL_0037: ceq + IL_0039: ret } // end of method KeyR::Equals .method public hidebysig virtual final instance bool Equals(class Hash08/HashMicroPerfAndCodeGenerationTests/KeyR obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 53 (0x35) + // Code size 54 (0x36) .maxstack 8 + .line 4,4 : 10,14 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_002d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_002e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_002b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_002c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0012: ldarg.1 - IL_0013: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ - IL_0018: bne.un.s IL_0029 + IL_000d: ldarg.0 + IL_000e: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0013: ldarg.1 + IL_0014: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key1@ + IL_0019: bne.un.s IL_002a .line 16707566,16707566 : 0,0 '' - IL_001a: ldarg.0 - IL_001b: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0020: ldarg.1 - IL_0021: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ - IL_0026: ceq - IL_0028: ret + IL_001b: ldarg.0 + IL_001c: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0021: ldarg.1 + IL_0022: ldfld int32 Hash08/HashMicroPerfAndCodeGenerationTests/KeyR::key2@ + IL_0027: ceq + IL_0029: ret .line 16707566,16707566 : 0,0 '' - IL_0029: ldc.i4.0 - IL_002a: ret + IL_002a: ldc.i4.0 + IL_002b: ret .line 16707566,16707566 : 0,0 '' - IL_002b: ldc.i4.0 - IL_002c: ret + IL_002c: ldc.i4.0 + IL_002d: ret .line 16707566,16707566 : 0,0 '' - IL_002d: ldarg.1 - IL_002e: ldnull - IL_002f: cgt.un - IL_0031: ldc.i4.0 - IL_0032: ceq - IL_0034: ret + IL_002e: ldarg.1 + IL_002f: ldnull + IL_0030: cgt.un + IL_0032: ldc.i4.0 + IL_0033: ceq + IL_0035: ret } // end of method KeyR::Equals .method public hidebysig virtual final @@ -529,6 +545,7 @@ IL_0000: ldarg.1 IL_0001: isinst Hash08/HashMicroPerfAndCodeGenerationTests/KeyR IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash09.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash09.il.bsl index df7b115d207..1de6d054801 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash09.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash09.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash09 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash09 { - // Offset: 0x00000000 Length: 0x0000088E + // Offset: 0x00000000 Length: 0x0000087E } .mresource public FSharpOptimizationData.Hash09 { - // Offset: 0x00000898 Length: 0x00000686 + // Offset: 0x00000888 Length: 0x00000680 } .module Hash09.dll -// MVID: {59B18AEE-9642-77DB-A745-0383EE8AB159} +// MVID: {611C550D-9642-77DB-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00690000 +// Image base: 0x07230000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 110 (0x6e) + // Code size 111 (0x6f) .maxstack 5 .locals init ([0] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, @@ -187,93 +187,96 @@ [4] !a V_4, [5] !a V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash09.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0064 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0062 - - .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop - .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldloc.s V_5 - IL_002d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + .line 4,4 : 10,20 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash09.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0065 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0063 + + .line 16707566,16707566 : 0,0 '' + IL_000d: ldarg.0 + IL_000e: pop + .line 16707566,16707566 : 0,0 '' + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0027: stloc.s V_5 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldloc.s V_5 + IL_002e: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0032: stloc.2 - IL_0033: ldloc.2 - IL_0034: ldc.i4.0 - IL_0035: bge.s IL_0039 + IL_0033: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0034: ldloc.2 + IL_0035: ldc.i4.0 + IL_0036: bge.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0037: ldloc.2 - IL_0038: ret + IL_0038: ldloc.2 + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: ble.s IL_003f + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: ble.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0044: stloc.3 - IL_0045: ldloc.0 - IL_0046: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_004b: stloc.s V_4 - IL_004d: ldloc.1 - IL_004e: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0053: stloc.s V_5 - IL_0055: ldloc.3 - IL_0056: ldloc.s V_4 - IL_0058: ldloc.s V_5 - IL_005a: tail. - IL_005c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, + IL_0040: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0045: stloc.3 + IL_0046: ldloc.0 + IL_0047: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_004c: stloc.s V_4 + IL_004e: ldloc.1 + IL_004f: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0054: stloc.s V_5 + IL_0056: ldloc.3 + IL_0057: ldloc.s V_4 + IL_0059: ldloc.s V_5 + IL_005b: tail. + IL_005d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericComparisonWithComparerIntrinsic(class [mscorlib]System.Collections.IComparer, !!0, !!0) - IL_0061: ret + IL_0062: ret .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.1 - IL_0063: ret + IL_0063: ldc.i4.1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldarg.1 - IL_0065: ldnull - IL_0066: cgt.un - IL_0068: brfalse.s IL_006c + IL_0065: ldarg.1 + IL_0066: ldnull + IL_0067: cgt.un + IL_0069: brfalse.s IL_006d .line 16707566,16707566 : 0,0 '' - IL_006a: ldc.i4.m1 - IL_006b: ret + IL_006b: ldc.i4.m1 + IL_006c: ret .line 16707566,16707566 : 0,0 '' - IL_006c: ldc.i4.0 - IL_006d: ret + IL_006d: ldc.i4.0 + IL_006e: ret } // end of method GenericKey`1::CompareTo .method public hidebysig virtual final @@ -308,6 +311,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -341,6 +345,7 @@ !!0, !!0) IL_0038: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0039: ldloc.3 IL_003a: ldc.i4.0 IL_003b: bge.s IL_003f @@ -398,69 +403,72 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 76 (0x4c) + // Code size 77 (0x4d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0019: stloc.2 - IL_001a: ldarg.1 - IL_001b: ldloc.2 - IL_001c: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + .line 4,4 : 10,20 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_004b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_001a: stloc.2 + IL_001b: ldarg.1 + IL_001c: ldloc.2 + IL_001d: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_0021: ldloc.0 - IL_0022: ldc.i4.6 - IL_0023: shl - IL_0024: ldloc.0 - IL_0025: ldc.i4.2 - IL_0026: shr - IL_0027: add + IL_0022: ldloc.0 + IL_0023: ldc.i4.6 + IL_0024: shl + IL_0025: ldloc.0 + IL_0026: ldc.i4.2 + IL_0027: shr IL_0028: add IL_0029: add - IL_002a: stloc.0 - IL_002b: ldc.i4 0x9e3779b9 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0036: stloc.2 - IL_0037: ldarg.1 - IL_0038: ldloc.2 - IL_0039: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002a: add + IL_002b: stloc.0 + IL_002c: ldc.i4 0x9e3779b9 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0037: stloc.2 + IL_0038: ldarg.1 + IL_0039: ldloc.2 + IL_003a: call int32 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericHashWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0) - IL_003e: ldloc.0 - IL_003f: ldc.i4.6 - IL_0040: shl - IL_0041: ldloc.0 - IL_0042: ldc.i4.2 - IL_0043: shr - IL_0044: add + IL_003f: ldloc.0 + IL_0040: ldc.i4.6 + IL_0041: shl + IL_0042: ldloc.0 + IL_0043: ldc.i4.2 + IL_0044: shr IL_0045: add IL_0046: add - IL_0047: stloc.0 - IL_0048: ldloc.0 - IL_0049: ret + IL_0047: add + IL_0048: stloc.0 + IL_0049: ldloc.0 + IL_004a: ret .line 16707566,16707566 : 0,0 '' - IL_004a: ldc.i4.0 - IL_004b: ret + IL_004b: ldc.i4.0 + IL_004c: ret } // end of method GenericKey`1::GetHashCode .method public hidebysig virtual final @@ -481,152 +489,159 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 87 (0x57) + // Code size 88 (0x58) .maxstack 5 .locals init ([0] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_2, [3] !a V_3, [4] !a V_4) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_004f - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_004d - - .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop - .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001c: stloc.3 - IL_001d: ldloc.2 - IL_001e: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0023: stloc.s V_4 - IL_0025: ldarg.2 - IL_0026: ldloc.3 - IL_0027: ldloc.s V_4 - IL_0029: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0050 + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldarg.1 + IL_0008: isinst class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_004e + + .line 16707566,16707566 : 0,0 '' + IL_0011: ldarg.0 + IL_0012: pop + .line 16707566,16707566 : 0,0 '' + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_001d: stloc.3 + IL_001e: ldloc.2 + IL_001f: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0024: stloc.s V_4 + IL_0026: ldarg.2 + IL_0027: ldloc.3 + IL_0028: ldloc.s V_4 + IL_002a: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_002e: brfalse.s IL_004b - - .line 16707566,16707566 : 0,0 '' - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_003d: stloc.s V_4 - IL_003f: ldarg.2 - IL_0040: ldloc.3 - IL_0041: ldloc.s V_4 - IL_0043: tail. - IL_0045: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, + IL_002f: brfalse.s IL_004c + + .line 16707566,16707566 : 0,0 '' + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_003e: stloc.s V_4 + IL_0040: ldarg.2 + IL_0041: ldloc.3 + IL_0042: ldloc.s V_4 + IL_0044: tail. + IL_0046: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [mscorlib]System.Collections.IEqualityComparer, !!0, !!0) - IL_004a: ret + IL_004b: ret .line 16707566,16707566 : 0,0 '' - IL_004b: ldc.i4.0 - IL_004c: ret + IL_004c: ldc.i4.0 + IL_004d: ret .line 16707566,16707566 : 0,0 '' - IL_004d: ldc.i4.0 - IL_004e: ret + IL_004e: ldc.i4.0 + IL_004f: ret .line 16707566,16707566 : 0,0 '' - IL_004f: ldarg.1 - IL_0050: ldnull - IL_0051: cgt.un - IL_0053: ldc.i4.0 - IL_0054: ceq - IL_0056: ret + IL_0050: ldarg.1 + IL_0051: ldnull + IL_0052: cgt.un + IL_0054: ldc.i4.0 + IL_0055: ceq + IL_0057: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final instance bool Equals(class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 77 (0x4d) + // Code size 78 (0x4e) .maxstack 4 .locals init ([0] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_0, [1] class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 V_1, [2] !a V_2, [3] !a V_3) + .line 4,4 : 10,20 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0045 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0043 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0044 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldloc.3 - IL_0022: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0019: stloc.2 + IL_001a: ldloc.1 + IL_001b: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0027: brfalse.s IL_0041 - - .line 16707566,16707566 : 0,0 '' - IL_0029: ldloc.0 - IL_002a: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_002f: stloc.2 - IL_0030: ldloc.1 - IL_0031: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 - IL_0036: stloc.3 - IL_0037: ldloc.2 - IL_0038: ldloc.3 - IL_0039: tail. - IL_003b: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, + IL_0028: brfalse.s IL_0042 + + .line 16707566,16707566 : 0,0 '' + IL_002a: ldloc.0 + IL_002b: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0030: stloc.2 + IL_0031: ldloc.1 + IL_0032: ldfld !0 class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1::item2 + IL_0037: stloc.3 + IL_0038: ldloc.2 + IL_0039: ldloc.3 + IL_003a: tail. + IL_003c: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic(!!0, !!0) - IL_0040: ret + IL_0041: ret .line 16707566,16707566 : 0,0 '' - IL_0041: ldc.i4.0 - IL_0042: ret + IL_0042: ldc.i4.0 + IL_0043: ret .line 16707566,16707566 : 0,0 '' - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0044: ldc.i4.0 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: ldarg.1 - IL_0046: ldnull - IL_0047: cgt.un - IL_0049: ldc.i4.0 - IL_004a: ceq - IL_004c: ret + IL_0046: ldarg.1 + IL_0047: ldnull + IL_0048: cgt.un + IL_004a: ldc.i4.0 + IL_004b: ceq + IL_004d: ret } // end of method GenericKey`1::Equals .method public hidebysig virtual final @@ -640,6 +655,7 @@ IL_0000: ldarg.1 IL_0001: isinst class Hash09/HashMicroPerfAndCodeGenerationTests/GenericKey`1 IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash10.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash10.il.bsl index 20c3ceeb8f6..a592e836742 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash10.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash10.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash10 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash10 { - // Offset: 0x00000000 Length: 0x00000219 + // Offset: 0x00000000 Length: 0x00000215 } .mresource public FSharpOptimizationData.Hash10 { // Offset: 0x00000220 Length: 0x000000A9 } .module Hash10.dll -// MVID: {59B18AEE-9661-78B4-A745-0383EE8AB159} +// MVID: {60BE1F16-9661-78B4-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x00BB0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,7 +63,7 @@ [1] int32 i, [2] int32 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 8,36 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash10.fsx' + .line 6,6 : 8,36 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash10.fsx' IL_0000: ldc.i4.0 IL_0001: ldc.i4.1 IL_0002: ldc.i4.s 100 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash11.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash11.il.bsl index f4eb5020175..e01d5bc6aad 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash11.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash11.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash11 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash11 { - // Offset: 0x00000000 Length: 0x00000219 + // Offset: 0x00000000 Length: 0x00000215 } .mresource public FSharpOptimizationData.Hash11 { // Offset: 0x00000220 Length: 0x000000A9 } .module Hash11.dll -// MVID: {59B18AEE-9661-78D3-A745-0383EE8AB159} +// MVID: {60BE1F16-9661-78D3-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x002D0000 +// Image base: 0x06C60000 // =============== CLASS MEMBERS DECLARATION =================== @@ -63,7 +63,7 @@ [1] int32 i, [2] int32 V_2) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 8,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash11.fsx' + .line 6,6 : 8,32 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash11.fsx' IL_0000: ldc.i4.0 IL_0001: ldc.i4.1 IL_0002: ldc.i4.s 100 diff --git a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash12.il.bsl b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash12.il.bsl index 9c5bfb73cf3..dd4511bb604 100644 --- a/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash12.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/GenericComparison/Hash12.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Hash12 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.Hash12 { - // Offset: 0x00000000 Length: 0x00000A98 + // Offset: 0x00000000 Length: 0x00000A88 } .mresource public FSharpOptimizationData.Hash12 { - // Offset: 0x00000AA0 Length: 0x00000585 + // Offset: 0x00000A90 Length: 0x00000585 } .module Hash12.dll -// MVID: {59B18AEE-9661-796E-A745-0383EE8AB159} +// MVID: {611C550D-9661-796E-A745-03830D551C61} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01080000 +// Image base: 0x05130000 // =============== CLASS MEMBERS DECLARATION =================== @@ -178,7 +178,7 @@ instance int32 CompareTo(class Hash12/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 119 (0x77) + // Code size 120 (0x78) .maxstack 4 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_1, @@ -187,109 +187,114 @@ [4] int32 V_4, [5] int32 V_5) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 16707566,16707566 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\Optimizations\\GenericComparison\\Hash12.fsx' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_006d + .line 4,4 : 10,13 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\Optimizations\\GenericComparison\\Hash12.fsx' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_006b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_006c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_0017: stloc.3 - IL_0018: ldloc.0 - IL_0019: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: stloc.s V_4 - IL_0020: ldloc.1 - IL_0021: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0026: stloc.s V_5 - IL_0028: ldloc.s V_4 - IL_002a: ldloc.s V_5 - IL_002c: bge.s IL_0032 + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + IL_0013: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_0018: stloc.3 + IL_0019: ldloc.0 + IL_001a: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: stloc.s V_4 + IL_0021: ldloc.1 + IL_0022: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0027: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_0029: ldloc.s V_4 + IL_002b: ldloc.s V_5 + IL_002d: bge.s IL_0033 .line 16707566,16707566 : 0,0 '' - IL_002e: ldc.i4.m1 + IL_002f: ldc.i4.m1 .line 16707566,16707566 : 0,0 '' - IL_002f: nop - IL_0030: br.s IL_0039 + IL_0030: nop + IL_0031: br.s IL_003a .line 16707566,16707566 : 0,0 '' - IL_0032: ldloc.s V_4 - IL_0034: ldloc.s V_5 - IL_0036: cgt + IL_0033: ldloc.s V_4 + IL_0035: ldloc.s V_5 + IL_0037: cgt .line 16707566,16707566 : 0,0 '' - IL_0038: nop + IL_0039: nop .line 16707566,16707566 : 0,0 '' - IL_0039: stloc.2 - IL_003a: ldloc.2 - IL_003b: ldc.i4.0 - IL_003c: bge.s IL_0040 + IL_003a: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003b: ldloc.2 + IL_003c: ldc.i4.0 + IL_003d: bge.s IL_0041 .line 16707566,16707566 : 0,0 '' - IL_003e: ldloc.2 - IL_003f: ret + IL_003f: ldloc.2 + IL_0040: ret .line 16707566,16707566 : 0,0 '' - IL_0040: ldloc.2 - IL_0041: ldc.i4.0 - IL_0042: ble.s IL_0046 + IL_0041: ldloc.2 + IL_0042: ldc.i4.0 + IL_0043: ble.s IL_0047 .line 16707566,16707566 : 0,0 '' - IL_0044: ldloc.2 - IL_0045: ret + IL_0045: ldloc.2 + IL_0046: ret .line 16707566,16707566 : 0,0 '' - IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004b: stloc.3 - IL_004c: ldloc.0 - IL_004d: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0052: stloc.s V_4 - IL_0054: ldloc.1 - IL_0055: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_005a: stloc.s V_5 - IL_005c: ldloc.s V_4 - IL_005e: ldloc.s V_5 - IL_0060: bge.s IL_0064 + IL_0047: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004c: stloc.3 + IL_004d: ldloc.0 + IL_004e: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0053: stloc.s V_4 + IL_0055: ldloc.1 + IL_0056: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_005b: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' + IL_005d: ldloc.s V_4 + IL_005f: ldloc.s V_5 + IL_0061: bge.s IL_0065 .line 16707566,16707566 : 0,0 '' - IL_0062: ldc.i4.m1 - IL_0063: ret + IL_0063: ldc.i4.m1 + IL_0064: ret .line 16707566,16707566 : 0,0 '' - IL_0064: ldloc.s V_4 - IL_0066: ldloc.s V_5 - IL_0068: cgt - IL_006a: ret + IL_0065: ldloc.s V_4 + IL_0067: ldloc.s V_5 + IL_0069: cgt + IL_006b: ret .line 16707566,16707566 : 0,0 '' - IL_006b: ldc.i4.1 - IL_006c: ret + IL_006c: ldc.i4.1 + IL_006d: ret .line 16707566,16707566 : 0,0 '' - IL_006d: ldarg.1 - IL_006e: ldnull - IL_006f: cgt.un - IL_0071: brfalse.s IL_0075 + IL_006e: ldarg.1 + IL_006f: ldnull + IL_0070: cgt.un + IL_0072: brfalse.s IL_0076 .line 16707566,16707566 : 0,0 '' - IL_0073: ldc.i4.m1 - IL_0074: ret + IL_0074: ldc.i4.m1 + IL_0075: ret .line 16707566,16707566 : 0,0 '' - IL_0075: ldc.i4.0 - IL_0076: ret + IL_0076: ldc.i4.0 + IL_0077: ret } // end of method Key::CompareTo .method public hidebysig virtual final @@ -323,6 +328,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Hash12/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -349,6 +355,7 @@ IL_0026: ldloc.2 IL_0027: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 IL_002c: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_002e: ldloc.s V_4 IL_0030: ldloc.s V_5 IL_0032: bge.s IL_0038 @@ -367,6 +374,7 @@ IL_003e: nop .line 16707566,16707566 : 0,0 '' IL_003f: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_0040: ldloc.3 IL_0041: ldc.i4.0 IL_0042: bge.s IL_0046 @@ -391,6 +399,7 @@ IL_0054: ldloc.2 IL_0055: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 IL_005a: stloc.s V_5 + .line 16707566,16707566 : 0,0 '' IL_005c: ldloc.s V_4 IL_005e: ldloc.s V_5 IL_0060: bge.s IL_0064 @@ -429,58 +438,61 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 60 (0x3c) + // Code size 61 (0x3d) .maxstack 7 .locals init ([0] int32 V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_1) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003a - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0019: ldloc.0 - IL_001a: ldc.i4.6 - IL_001b: shl - IL_001c: ldloc.0 - IL_001d: ldc.i4.2 - IL_001e: shr - IL_001f: add + .line 4,4 : 10,13 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003b + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_001a: ldloc.0 + IL_001b: ldc.i4.6 + IL_001c: shl + IL_001d: ldloc.0 + IL_001e: ldc.i4.2 + IL_001f: shr IL_0020: add IL_0021: add - IL_0022: stloc.0 - IL_0023: ldc.i4 0x9e3779b9 - IL_0028: ldloc.1 - IL_0029: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_002e: ldloc.0 - IL_002f: ldc.i4.6 - IL_0030: shl - IL_0031: ldloc.0 - IL_0032: ldc.i4.2 - IL_0033: shr - IL_0034: add + IL_0022: add + IL_0023: stloc.0 + IL_0024: ldc.i4 0x9e3779b9 + IL_0029: ldloc.1 + IL_002a: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr IL_0035: add IL_0036: add - IL_0037: stloc.0 - IL_0038: ldloc.0 - IL_0039: ret + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret .line 16707566,16707566 : 0,0 '' - IL_003a: ldc.i4.0 - IL_003b: ret + IL_003b: ldc.i4.0 + IL_003c: ret } // end of method Key::GetHashCode .method public hidebysig virtual final @@ -501,120 +513,127 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 63 (0x3f) + // Code size 64 (0x40) .maxstack 4 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_1, [2] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_2) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0037 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0038 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: isinst Hash12/HashMicroPerfAndCodeGenerationTests/Key - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: brfalse.s IL_0035 + IL_0007: ldarg.1 + IL_0008: isinst Hash12/HashMicroPerfAndCodeGenerationTests/Key + IL_000d: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0036 .line 16707566,16707566 : 0,0 '' - IL_0010: ldarg.0 - IL_0011: pop + IL_0011: ldarg.0 + IL_0012: pop .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: stloc.1 - IL_0014: ldloc.0 - IL_0015: stloc.2 - IL_0016: ldloc.1 - IL_0017: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001c: ldloc.2 - IL_001d: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0022: bne.un.s IL_0033 + IL_0013: ldarg.0 + IL_0014: stloc.1 + IL_0015: ldloc.0 + IL_0016: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_0017: ldloc.1 + IL_0018: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001d: ldloc.2 + IL_001e: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0023: bne.un.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0024: ldloc.1 - IL_0025: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002a: ldloc.2 - IL_002b: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0030: ceq - IL_0032: ret + IL_0025: ldloc.1 + IL_0026: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002b: ldloc.2 + IL_002c: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0031: ceq + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldc.i4.0 - IL_0034: ret + IL_0034: ldc.i4.0 + IL_0035: ret .line 16707566,16707566 : 0,0 '' - IL_0035: ldc.i4.0 - IL_0036: ret + IL_0036: ldc.i4.0 + IL_0037: ret .line 16707566,16707566 : 0,0 '' - IL_0037: ldarg.1 - IL_0038: ldnull - IL_0039: cgt.un - IL_003b: ldc.i4.0 - IL_003c: ceq - IL_003e: ret + IL_0038: ldarg.1 + IL_0039: ldnull + IL_003a: cgt.un + IL_003c: ldc.i4.0 + IL_003d: ceq + IL_003f: ret } // end of method Key::Equals .method public hidebysig virtual final instance bool Equals(class Hash12/HashMicroPerfAndCodeGenerationTests/Key obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 59 (0x3b) + // Code size 60 (0x3c) .maxstack 4 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_1) + .line 4,4 : 10,13 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0033 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_0034 .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_0031 + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_0032 .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_0018: ldloc.1 - IL_0019: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 - IL_001e: bne.un.s IL_002f + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_0019: ldloc.1 + IL_001a: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item1 + IL_001f: bne.un.s IL_0030 .line 16707566,16707566 : 0,0 '' - IL_0020: ldloc.0 - IL_0021: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_0026: ldloc.1 - IL_0027: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 - IL_002c: ceq - IL_002e: ret + IL_0021: ldloc.0 + IL_0022: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_0027: ldloc.1 + IL_0028: ldfld int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::item2 + IL_002d: ceq + IL_002f: ret .line 16707566,16707566 : 0,0 '' - IL_002f: ldc.i4.0 - IL_0030: ret + IL_0030: ldc.i4.0 + IL_0031: ret .line 16707566,16707566 : 0,0 '' - IL_0031: ldc.i4.0 - IL_0032: ret + IL_0032: ldc.i4.0 + IL_0033: ret .line 16707566,16707566 : 0,0 '' - IL_0033: ldarg.1 - IL_0034: ldnull - IL_0035: cgt.un - IL_0037: ldc.i4.0 - IL_0038: ceq - IL_003a: ret + IL_0034: ldarg.1 + IL_0035: ldnull + IL_0036: cgt.un + IL_0038: ldc.i4.0 + IL_0039: ceq + IL_003b: ret } // end of method Key::Equals .method public hidebysig virtual final @@ -628,6 +647,7 @@ IL_0000: ldarg.1 IL_0001: isinst Hash12/HashMicroPerfAndCodeGenerationTests/Key IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0012 @@ -792,7 +812,7 @@ instance int32 CompareTo(class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 169 (0xa9) + // Code size 170 (0xaa) .maxstack 5 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -805,116 +825,120 @@ [8] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_8, [9] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_9, [10] int32 V_10) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_009f + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_00a0 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: ldnull - IL_000b: cgt.un - IL_000d: brfalse IL_009d + IL_000a: ldarg.1 + IL_000b: ldnull + IL_000c: cgt.un + IL_000e: brfalse IL_009e .line 16707566,16707566 : 0,0 '' - IL_0012: ldarg.0 - IL_0013: pop + IL_0013: ldarg.0 + IL_0014: pop .line 16707566,16707566 : 0,0 '' - IL_0014: ldarg.0 - IL_0015: stloc.0 - IL_0016: ldarg.1 - IL_0017: stloc.1 - IL_0018: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_001d: stloc.3 - IL_001e: ldloc.0 - IL_001f: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0024: stloc.s V_4 - IL_0026: ldloc.1 - IL_0027: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_002c: stloc.s V_5 - IL_002e: ldloc.s V_4 - IL_0030: ldloc.s V_5 - IL_0032: ldloc.3 - IL_0033: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0015: ldarg.0 + IL_0016: stloc.0 + IL_0017: ldarg.1 + IL_0018: stloc.1 + IL_0019: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_001e: stloc.3 + IL_001f: ldloc.0 + IL_0020: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0025: stloc.s V_4 + IL_0027: ldloc.1 + IL_0028: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_002d: stloc.s V_5 + IL_002f: ldloc.s V_4 + IL_0031: ldloc.s V_5 + IL_0033: ldloc.3 + IL_0034: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0038: stloc.2 - IL_0039: ldloc.2 - IL_003a: ldc.i4.0 - IL_003b: bge.s IL_003f + IL_0039: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_003a: ldloc.2 + IL_003b: ldc.i4.0 + IL_003c: bge.s IL_0040 .line 16707566,16707566 : 0,0 '' - IL_003d: ldloc.2 - IL_003e: ret + IL_003e: ldloc.2 + IL_003f: ret .line 16707566,16707566 : 0,0 '' - IL_003f: ldloc.2 - IL_0040: ldc.i4.0 - IL_0041: ble.s IL_0045 + IL_0040: ldloc.2 + IL_0041: ldc.i4.0 + IL_0042: ble.s IL_0046 .line 16707566,16707566 : 0,0 '' - IL_0043: ldloc.2 - IL_0044: ret + IL_0044: ldloc.2 + IL_0045: ret .line 16707566,16707566 : 0,0 '' - IL_0045: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() - IL_004a: stloc.3 - IL_004b: ldloc.0 - IL_004c: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0051: stloc.s V_6 - IL_0053: ldloc.1 - IL_0054: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0059: stloc.s V_7 - IL_005b: ldloc.s V_6 - IL_005d: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0062: stloc.s V_4 - IL_0064: ldloc.s V_6 - IL_0066: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_006b: stloc.s V_5 - IL_006d: ldloc.s V_7 - IL_006f: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0074: stloc.s V_8 - IL_0076: ldloc.s V_7 - IL_0078: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_007d: stloc.s V_9 - IL_007f: ldloc.s V_4 - IL_0081: ldloc.s V_8 - IL_0083: ldloc.3 - IL_0084: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0046: call class [mscorlib]System.Collections.IComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericComparer() + IL_004b: stloc.3 + IL_004c: ldloc.0 + IL_004d: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0052: stloc.s V_6 + IL_0054: ldloc.1 + IL_0055: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_005a: stloc.s V_7 + IL_005c: ldloc.s V_6 + IL_005e: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0063: stloc.s V_4 + IL_0065: ldloc.s V_6 + IL_0067: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_006c: stloc.s V_5 + IL_006e: ldloc.s V_7 + IL_0070: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0075: stloc.s V_8 + IL_0077: ldloc.s V_7 + IL_0079: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_007e: stloc.s V_9 + IL_0080: ldloc.s V_4 + IL_0082: ldloc.s V_8 + IL_0084: ldloc.3 + IL_0085: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_0089: stloc.s V_10 - IL_008b: ldloc.s V_10 - IL_008d: brfalse.s IL_0092 + IL_008a: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' + IL_008c: ldloc.s V_10 + IL_008e: brfalse.s IL_0093 .line 16707566,16707566 : 0,0 '' - IL_008f: ldloc.s V_10 - IL_0091: ret + IL_0090: ldloc.s V_10 + IL_0092: ret .line 16707566,16707566 : 0,0 '' - IL_0092: ldloc.s V_5 - IL_0094: ldloc.s V_9 - IL_0096: ldloc.3 - IL_0097: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, + IL_0093: ldloc.s V_5 + IL_0095: ldloc.s V_9 + IL_0097: ldloc.3 + IL_0098: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) - IL_009c: ret + IL_009d: ret .line 16707566,16707566 : 0,0 '' - IL_009d: ldc.i4.1 - IL_009e: ret + IL_009e: ldc.i4.1 + IL_009f: ret .line 16707566,16707566 : 0,0 '' - IL_009f: ldarg.1 - IL_00a0: ldnull - IL_00a1: cgt.un - IL_00a3: brfalse.s IL_00a7 + IL_00a0: ldarg.1 + IL_00a1: ldnull + IL_00a2: cgt.un + IL_00a4: brfalse.s IL_00a8 .line 16707566,16707566 : 0,0 '' - IL_00a5: ldc.i4.m1 - IL_00a6: ret + IL_00a6: ldc.i4.m1 + IL_00a7: ret .line 16707566,16707566 : 0,0 '' - IL_00a7: ldc.i4.0 - IL_00a8: ret + IL_00a8: ldc.i4.0 + IL_00a9: ret } // end of method KeyWithInnerKeys::CompareTo .method public hidebysig virtual final @@ -953,6 +977,7 @@ IL_0000: ldarg.1 IL_0001: unbox.any Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldarg.0 IL_0008: ldnull IL_0009: cgt.un @@ -985,6 +1010,7 @@ IL_0039: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_003e: stloc.3 + .line 16707566,16707566 : 0,0 '' IL_003f: ldloc.3 IL_0040: ldc.i4.0 IL_0041: bge.s IL_0045 @@ -1027,6 +1053,7 @@ IL_0084: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::CompareTo(object, class [mscorlib]System.Collections.IComparer) IL_0089: stloc.s V_10 + .line 16707566,16707566 : 0,0 '' IL_008b: ldloc.s V_10 IL_008d: brfalse.s IL_0092 @@ -1066,7 +1093,7 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 107 (0x6b) + // Code size 108 (0x6c) .maxstack 7 .locals init ([0] int32 V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1074,76 +1101,79 @@ [3] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_3, [4] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_4, [5] int32 V_5) - .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_0069 - - .line 16707566,16707566 : 0,0 '' - IL_0006: ldc.i4.0 - IL_0007: stloc.0 - IL_0008: ldarg.0 - IL_0009: pop - .line 16707566,16707566 : 0,0 '' - IL_000a: ldarg.0 - IL_000b: stloc.1 - IL_000c: ldc.i4.0 - IL_000d: stloc.0 - IL_000e: ldc.i4 0x9e3779b9 - IL_0013: ldloc.1 - IL_0014: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0019: stloc.2 - IL_001a: ldloc.2 - IL_001b: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_0020: stloc.3 - IL_0021: ldloc.2 - IL_0022: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0027: stloc.s V_4 - IL_0029: ldloc.3 - IL_002a: ldarg.1 - IL_002b: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0030: stloc.s V_5 - IL_0032: ldloc.s V_5 - IL_0034: ldc.i4.5 - IL_0035: shl - IL_0036: ldloc.s V_5 - IL_0038: add - IL_0039: ldloc.s V_4 - IL_003b: ldarg.1 - IL_003c: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_0041: xor - IL_0042: ldloc.0 - IL_0043: ldc.i4.6 - IL_0044: shl - IL_0045: ldloc.0 - IL_0046: ldc.i4.2 - IL_0047: shr - IL_0048: add + .line 5,5 : 10,26 '' + IL_0000: nop + .line 16707566,16707566 : 0,0 '' + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_006a + + .line 16707566,16707566 : 0,0 '' + IL_0007: ldc.i4.0 + IL_0008: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0009: ldarg.0 + IL_000a: pop + .line 16707566,16707566 : 0,0 '' + IL_000b: ldarg.0 + IL_000c: stloc.1 + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: ldc.i4 0x9e3779b9 + IL_0014: ldloc.1 + IL_0015: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_0021: stloc.3 + IL_0022: ldloc.2 + IL_0023: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0028: stloc.s V_4 + IL_002a: ldloc.3 + IL_002b: ldarg.1 + IL_002c: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0031: stloc.s V_5 + IL_0033: ldloc.s V_5 + IL_0035: ldc.i4.5 + IL_0036: shl + IL_0037: ldloc.s V_5 + IL_0039: add + IL_003a: ldloc.s V_4 + IL_003c: ldarg.1 + IL_003d: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0042: xor + IL_0043: ldloc.0 + IL_0044: ldc.i4.6 + IL_0045: shl + IL_0046: ldloc.0 + IL_0047: ldc.i4.2 + IL_0048: shr IL_0049: add IL_004a: add - IL_004b: stloc.0 - IL_004c: ldc.i4 0x9e3779b9 - IL_0051: ldloc.1 - IL_0052: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0057: ldarg.1 - IL_0058: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) - IL_005d: ldloc.0 - IL_005e: ldc.i4.6 - IL_005f: shl - IL_0060: ldloc.0 - IL_0061: ldc.i4.2 - IL_0062: shr - IL_0063: add + IL_004b: add + IL_004c: stloc.0 + IL_004d: ldc.i4 0x9e3779b9 + IL_0052: ldloc.1 + IL_0053: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0058: ldarg.1 + IL_0059: callvirt instance int32 Hash12/HashMicroPerfAndCodeGenerationTests/Key::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_005e: ldloc.0 + IL_005f: ldc.i4.6 + IL_0060: shl + IL_0061: ldloc.0 + IL_0062: ldc.i4.2 + IL_0063: shr IL_0064: add IL_0065: add - IL_0066: stloc.0 - IL_0067: ldloc.0 - IL_0068: ret + IL_0066: add + IL_0067: stloc.0 + IL_0068: ldloc.0 + IL_0069: ret .line 16707566,16707566 : 0,0 '' - IL_0069: ldc.i4.0 - IL_006a: ret + IL_006a: ldc.i4.0 + IL_006b: ret } // end of method KeyWithInnerKeys::GetHashCode .method public hidebysig virtual final @@ -1164,7 +1194,7 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 138 (0x8a) + // Code size 139 (0x8b) .maxstack 5 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1, @@ -1175,155 +1205,163 @@ [6] class [mscorlib]System.Tuple`2 V_6, [7] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_7, [8] class Hash12/HashMicroPerfAndCodeGenerationTests/Key V_8) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse IL_0082 + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse IL_0083 .line 16707566,16707566 : 0,0 '' - IL_0009: ldarg.1 - IL_000a: isinst Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: brfalse.s IL_0080 + IL_000a: ldarg.1 + IL_000b: isinst Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys + IL_0010: stloc.0 + .line 16707566,16707566 : 0,0 '' + IL_0011: ldloc.0 + IL_0012: brfalse.s IL_0081 .line 16707566,16707566 : 0,0 '' - IL_0013: ldarg.0 - IL_0014: pop + IL_0014: ldarg.0 + IL_0015: pop .line 16707566,16707566 : 0,0 '' - IL_0015: ldarg.0 - IL_0016: stloc.1 - IL_0017: ldloc.0 - IL_0018: stloc.2 - IL_0019: ldloc.1 - IL_001a: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001f: stloc.3 - IL_0020: ldloc.2 - IL_0021: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0026: stloc.s V_4 - IL_0028: ldloc.3 - IL_0029: ldloc.s V_4 - IL_002b: ldarg.2 - IL_002c: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0016: ldarg.0 + IL_0017: stloc.1 + IL_0018: ldloc.0 + IL_0019: stloc.2 + .line 16707566,16707566 : 0,0 '' + IL_001a: ldloc.1 + IL_001b: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0027: stloc.s V_4 + IL_0029: ldloc.3 + IL_002a: ldloc.s V_4 + IL_002c: ldarg.2 + IL_002d: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_0031: brfalse.s IL_007e + IL_0032: brfalse.s IL_007f .line 16707566,16707566 : 0,0 '' - IL_0033: ldloc.1 - IL_0034: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0039: stloc.s V_5 - IL_003b: ldloc.2 - IL_003c: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0041: stloc.s V_6 - IL_0043: ldloc.s V_5 - IL_0045: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_004a: stloc.3 - IL_004b: ldloc.s V_5 - IL_004d: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0052: stloc.s V_4 - IL_0054: ldloc.s V_6 - IL_0056: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() - IL_005b: stloc.s V_7 - IL_005d: ldloc.s V_6 - IL_005f: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() - IL_0064: stloc.s V_8 - IL_0066: ldloc.3 - IL_0067: ldloc.s V_7 - IL_0069: ldarg.2 - IL_006a: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0034: ldloc.1 + IL_0035: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_003a: stloc.s V_5 + IL_003c: ldloc.2 + IL_003d: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0042: stloc.s V_6 + IL_0044: ldloc.s V_5 + IL_0046: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_004b: stloc.3 + IL_004c: ldloc.s V_5 + IL_004e: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0053: stloc.s V_4 + IL_0055: ldloc.s V_6 + IL_0057: call instance !0 class [mscorlib]System.Tuple`2::get_Item1() + IL_005c: stloc.s V_7 + IL_005e: ldloc.s V_6 + IL_0060: call instance !1 class [mscorlib]System.Tuple`2::get_Item2() + IL_0065: stloc.s V_8 + .line 16707566,16707566 : 0,0 '' + IL_0067: ldloc.3 + IL_0068: ldloc.s V_7 + IL_006a: ldarg.2 + IL_006b: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_006f: brfalse.s IL_007c + IL_0070: brfalse.s IL_007d .line 16707566,16707566 : 0,0 '' - IL_0071: ldloc.s V_4 - IL_0073: ldloc.s V_8 - IL_0075: ldarg.2 - IL_0076: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, + IL_0072: ldloc.s V_4 + IL_0074: ldloc.s V_8 + IL_0076: ldarg.2 + IL_0077: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(object, class [mscorlib]System.Collections.IEqualityComparer) - IL_007b: ret + IL_007c: ret .line 16707566,16707566 : 0,0 '' - IL_007c: ldc.i4.0 - IL_007d: ret + IL_007d: ldc.i4.0 + IL_007e: ret .line 16707566,16707566 : 0,0 '' - IL_007e: ldc.i4.0 - IL_007f: ret + IL_007f: ldc.i4.0 + IL_0080: ret .line 16707566,16707566 : 0,0 '' - IL_0080: ldc.i4.0 - IL_0081: ret + IL_0081: ldc.i4.0 + IL_0082: ret .line 16707566,16707566 : 0,0 '' - IL_0082: ldarg.1 - IL_0083: ldnull - IL_0084: cgt.un - IL_0086: ldc.i4.0 - IL_0087: ceq - IL_0089: ret + IL_0083: ldarg.1 + IL_0084: ldnull + IL_0085: cgt.un + IL_0087: ldc.i4.0 + IL_0088: ceq + IL_008a: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final instance bool Equals(class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 69 (0x45) + // Code size 70 (0x46) .maxstack 4 .locals init ([0] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_0, [1] class Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys V_1) + .line 5,5 : 10,26 '' + IL_0000: nop .line 16707566,16707566 : 0,0 '' - IL_0000: ldarg.0 - IL_0001: ldnull - IL_0002: cgt.un - IL_0004: brfalse.s IL_003d + IL_0001: ldarg.0 + IL_0002: ldnull + IL_0003: cgt.un + IL_0005: brfalse.s IL_003e .line 16707566,16707566 : 0,0 '' - IL_0006: ldarg.1 - IL_0007: ldnull - IL_0008: cgt.un - IL_000a: brfalse.s IL_003b + IL_0007: ldarg.1 + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_003c .line 16707566,16707566 : 0,0 '' - IL_000c: ldarg.0 - IL_000d: pop + IL_000d: ldarg.0 + IL_000e: pop .line 16707566,16707566 : 0,0 '' - IL_000e: ldarg.0 - IL_000f: stloc.0 - IL_0010: ldarg.1 - IL_0011: stloc.1 - IL_0012: ldloc.0 - IL_0013: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_0018: ldloc.1 - IL_0019: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 - IL_001e: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(class Hash12/HashMicroPerfAndCodeGenerationTests/Key) - IL_0023: brfalse.s IL_0039 - - .line 16707566,16707566 : 0,0 '' - IL_0025: ldloc.0 - IL_0026: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_002b: ldloc.1 - IL_002c: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 - IL_0031: tail. - IL_0033: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, + IL_000f: ldarg.0 + IL_0010: stloc.0 + IL_0011: ldarg.1 + IL_0012: stloc.1 + .line 16707566,16707566 : 0,0 '' + IL_0013: ldloc.0 + IL_0014: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_0019: ldloc.1 + IL_001a: ldfld class Hash12/HashMicroPerfAndCodeGenerationTests/Key Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item1 + IL_001f: callvirt instance bool Hash12/HashMicroPerfAndCodeGenerationTests/Key::Equals(class Hash12/HashMicroPerfAndCodeGenerationTests/Key) + IL_0024: brfalse.s IL_003a + + .line 16707566,16707566 : 0,0 '' + IL_0026: ldloc.0 + IL_0027: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_002c: ldloc.1 + IL_002d: ldfld class [mscorlib]System.Tuple`2 Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys::item2 + IL_0032: tail. + IL_0034: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityERIntrinsic>(!!0, !!0) - IL_0038: ret + IL_0039: ret .line 16707566,16707566 : 0,0 '' - IL_0039: ldc.i4.0 - IL_003a: ret + IL_003a: ldc.i4.0 + IL_003b: ret .line 16707566,16707566 : 0,0 '' - IL_003b: ldc.i4.0 - IL_003c: ret + IL_003c: ldc.i4.0 + IL_003d: ret .line 16707566,16707566 : 0,0 '' - IL_003d: ldarg.1 - IL_003e: ldnull - IL_003f: cgt.un - IL_0041: ldc.i4.0 - IL_0042: ceq - IL_0044: ret + IL_003e: ldarg.1 + IL_003f: ldnull + IL_0040: cgt.un + IL_0042: ldc.i4.0 + IL_0043: ceq + IL_0045: ret } // end of method KeyWithInnerKeys::Equals .method public hidebysig virtual final @@ -1337,6 +1375,7 @@ IL_0000: ldarg.1 IL_0001: isinst Hash12/HashMicroPerfAndCodeGenerationTests/KeyWithInnerKeys IL_0006: stloc.0 + .line 16707566,16707566 : 0,0 '' IL_0007: ldloc.0 IL_0008: brfalse.s IL_0014 diff --git a/tests/fsharpqa/Source/Optimizations/Inlining/Match01.il.bsl b/tests/fsharpqa/Source/Optimizations/Inlining/Match01.il.bsl index aa979cf89ae..cc844fbd85e 100644 --- a/tests/fsharpqa/Source/Optimizations/Inlining/Match01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/Inlining/Match01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Match01 { @@ -25,20 +25,20 @@ } .mresource public FSharpSignatureData.Match01 { - // Offset: 0x00000000 Length: 0x000006F6 + // Offset: 0x00000000 Length: 0x000006E6 } .mresource public FSharpOptimizationData.Match01 { - // Offset: 0x00000700 Length: 0x000003B7 + // Offset: 0x000006F0 Length: 0x000003B7 } .module Match01.dll -// MVID: {59B18AF8-FAFE-C8E4-A745-0383F88AB159} +// MVID: {60BE1F16-FAFE-C8E4-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01790000 +// Image base: 0x09680000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/tests/fsharpqa/Source/Optimizations/Inlining/Match02.il.bsl b/tests/fsharpqa/Source/Optimizations/Inlining/Match02.il.bsl index a22def741ec..92c0efac716 100644 --- a/tests/fsharpqa/Source/Optimizations/Inlining/Match02.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/Inlining/Match02.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 5:0:0:0 } .assembly Match02 { @@ -25,20 +25,20 @@ } .mresource public FSharpSignatureData.Match02 { - // Offset: 0x00000000 Length: 0x00000490 + // Offset: 0x00000000 Length: 0x00000484 } .mresource public FSharpOptimizationData.Match02 { - // Offset: 0x00000498 Length: 0x000002EE + // Offset: 0x00000488 Length: 0x000002EE } .module Match02.dll -// MVID: {59B18AF8-6125-4D81-A745-0383F88AB159} +// MVID: {60BE1F16-6125-4D81-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x015D0000 +// Image base: 0x06770000 // =============== CLASS MEMBERS DECLARATION =================== diff --git a/tests/fsharpqa/Source/Optimizations/Inlining/StructUnion01.il.bsl b/tests/fsharpqa/Source/Optimizations/Inlining/StructUnion01.il.bsl index 7e07ff48ffd..32e3a02a228 100644 --- a/tests/fsharpqa/Source/Optimizations/Inlining/StructUnion01.il.bsl +++ b/tests/fsharpqa/Source/Optimizations/Inlining/StructUnion01.il.bsl @@ -1,5 +1,5 @@ -// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0 // Copyright (c) Microsoft Corporation. All rights reserved. @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:3:0 + .ver 5:0:0:0 } .assembly StructUnion01 { @@ -25,20 +25,20 @@ } .mresource public FSharpSignatureData.StructUnion01 { - // Offset: 0x00000000 Length: 0x0000087E + // Offset: 0x00000000 Length: 0x0000087A } .mresource public FSharpOptimizationData.StructUnion01 { - // Offset: 0x00000888 Length: 0x00000421 + // Offset: 0x00000880 Length: 0x00000421 } .module StructUnion01.dll -// MVID: {5B1ED843-D3E9-6B24-A745-038343D81E5B} +// MVID: {60BE1F16-D3E9-6B24-A745-0383161FBE60} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x017F0000 +// Image base: 0x065C0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -374,15 +374,14 @@ class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 52 (0x34) + // Code size 54 (0x36) .maxstack 4 .locals init (valuetype StructUnion01/U V_0) IL_0000: ldarg.1 IL_0001: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) IL_0006: brtrue.s IL_000a - IL_0008: ldc.i4.0 - IL_0009: ret + IL_0008: br.s IL_0034 IL_000a: ldarg.1 IL_000b: unbox.any StructUnion01/U @@ -404,6 +403,9 @@ IL_0032: ldc.i4.0 IL_0033: ret + + IL_0034: ldc.i4.0 + IL_0035: ret } // end of method U::Equals .method public hidebysig virtual final @@ -435,20 +437,22 @@ instance bool Equals(object obj) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 23 (0x17) + // Code size 25 (0x19) .maxstack 8 IL_0000: ldarg.1 IL_0001: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::TypeTestGeneric(object) IL_0006: brtrue.s IL_000a - IL_0008: ldc.i4.0 - IL_0009: ret + IL_0008: br.s IL_0017 IL_000a: ldarg.0 IL_000b: ldarg.1 IL_000c: unbox.any StructUnion01/U IL_0011: call instance bool StructUnion01/U::Equals(valuetype StructUnion01/U) IL_0016: ret + + IL_0017: ldc.i4.0 + IL_0018: ret } // end of method U::Equals .property instance int32 Tag() @@ -504,31 +508,33 @@ .method public static int32 g3(valuetype StructUnion01/U x) cil managed { - // Code size 42 (0x2a) + // Code size 44 (0x2c) .maxstack 8 IL_0000: ldarga.s x IL_0002: ldfld int32 StructUnion01/U::item1 IL_0007: ldc.i4.3 IL_0008: sub IL_0009: switch ( - IL_0022) - IL_0012: ldarga.s x - IL_0014: ldfld int32 StructUnion01/U::item1 - IL_0019: ldarga.s x - IL_001b: ldfld int32 StructUnion01/U::item2 - IL_0020: add - IL_0021: ret - - IL_0022: ldarga.s x - IL_0024: ldfld int32 StructUnion01/U::item2 - IL_0029: ret + IL_0014) + IL_0012: br.s IL_001c + + IL_0014: ldarga.s x + IL_0016: ldfld int32 StructUnion01/U::item2 + IL_001b: ret + + IL_001c: ldarga.s x + IL_001e: ldfld int32 StructUnion01/U::item1 + IL_0023: ldarga.s x + IL_0025: ldfld int32 StructUnion01/U::item2 + IL_002a: add + IL_002b: ret } // end of method StructUnion01::g3 .method public static int32 g4(valuetype StructUnion01/U x, valuetype StructUnion01/U y) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 126 (0x7e) + // Code size 128 (0x80) .maxstack 6 .locals init (int32 V_0, int32 V_1, @@ -539,54 +545,56 @@ IL_0007: ldc.i4.3 IL_0008: sub IL_0009: switch ( - IL_003a) - IL_0012: ldarga.s y - IL_0014: ldfld int32 StructUnion01/U::item2 - IL_0019: stloc.0 - IL_001a: ldarga.s y - IL_001c: ldfld int32 StructUnion01/U::item1 - IL_0021: stloc.1 - IL_0022: ldarga.s x - IL_0024: ldfld int32 StructUnion01/U::item2 - IL_0029: stloc.2 - IL_002a: ldarga.s x - IL_002c: ldfld int32 StructUnion01/U::item1 - IL_0031: stloc.3 - IL_0032: ldloc.3 - IL_0033: ldloc.2 - IL_0034: add - IL_0035: ldloc.1 - IL_0036: add - IL_0037: ldloc.0 - IL_0038: add - IL_0039: ret - - IL_003a: ldarga.s y - IL_003c: ldfld int32 StructUnion01/U::item1 - IL_0041: ldc.i4.5 - IL_0042: sub - IL_0043: switch ( - IL_006e) - IL_004c: ldarga.s y - IL_004e: ldfld int32 StructUnion01/U::item2 - IL_0053: ldarga.s y - IL_0055: ldfld int32 StructUnion01/U::item1 - IL_005a: ldarga.s x - IL_005c: ldfld int32 StructUnion01/U::item2 - IL_0061: ldarga.s x - IL_0063: ldfld int32 StructUnion01/U::item1 - IL_0068: stloc.3 - IL_0069: stloc.2 - IL_006a: stloc.1 - IL_006b: stloc.0 - IL_006c: br.s IL_0032 - - IL_006e: ldarga.s x - IL_0070: ldfld int32 StructUnion01/U::item2 - IL_0075: ldarga.s y - IL_0077: ldfld int32 StructUnion01/U::item2 + IL_0014) + IL_0012: br.s IL_0058 + + IL_0014: ldarga.s y + IL_0016: ldfld int32 StructUnion01/U::item1 + IL_001b: ldc.i4.5 + IL_001c: sub + IL_001d: switch ( + IL_0048) + IL_0026: ldarga.s y + IL_0028: ldfld int32 StructUnion01/U::item2 + IL_002d: ldarga.s y + IL_002f: ldfld int32 StructUnion01/U::item1 + IL_0034: ldarga.s x + IL_0036: ldfld int32 StructUnion01/U::item2 + IL_003b: ldarga.s x + IL_003d: ldfld int32 StructUnion01/U::item1 + IL_0042: stloc.3 + IL_0043: stloc.2 + IL_0044: stloc.1 + IL_0045: stloc.0 + IL_0046: br.s IL_0078 + + IL_0048: ldarga.s x + IL_004a: ldfld int32 StructUnion01/U::item2 + IL_004f: ldarga.s y + IL_0051: ldfld int32 StructUnion01/U::item2 + IL_0056: add + IL_0057: ret + + IL_0058: ldarga.s y + IL_005a: ldfld int32 StructUnion01/U::item2 + IL_005f: stloc.0 + IL_0060: ldarga.s y + IL_0062: ldfld int32 StructUnion01/U::item1 + IL_0067: stloc.1 + IL_0068: ldarga.s x + IL_006a: ldfld int32 StructUnion01/U::item2 + IL_006f: stloc.2 + IL_0070: ldarga.s x + IL_0072: ldfld int32 StructUnion01/U::item1 + IL_0077: stloc.3 + IL_0078: ldloc.3 + IL_0079: ldloc.2 + IL_007a: add + IL_007b: ldloc.1 IL_007c: add - IL_007d: ret + IL_007d: ldloc.0 + IL_007e: add + IL_007f: ret } // end of method StructUnion01::g4 .method public static int32 f1(valuetype StructUnion01/U& x) cil managed @@ -615,31 +623,33 @@ .method public static int32 f3(valuetype StructUnion01/U& x) cil managed { - // Code size 38 (0x26) + // Code size 40 (0x28) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldfld int32 StructUnion01/U::item1 IL_0006: ldc.i4.3 IL_0007: sub IL_0008: switch ( - IL_001f) - IL_0011: ldarg.0 - IL_0012: ldfld int32 StructUnion01/U::item1 - IL_0017: ldarg.0 - IL_0018: ldfld int32 StructUnion01/U::item2 - IL_001d: add - IL_001e: ret - - IL_001f: ldarg.0 - IL_0020: ldfld int32 StructUnion01/U::item2 - IL_0025: ret + IL_0013) + IL_0011: br.s IL_001a + + IL_0013: ldarg.0 + IL_0014: ldfld int32 StructUnion01/U::item2 + IL_0019: ret + + IL_001a: ldarg.0 + IL_001b: ldfld int32 StructUnion01/U::item1 + IL_0020: ldarg.0 + IL_0021: ldfld int32 StructUnion01/U::item2 + IL_0026: add + IL_0027: ret } // end of method StructUnion01::f3 .method public static int32 f4(valuetype StructUnion01/U& x, valuetype StructUnion01/U& y) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) - // Code size 146 (0x92) + // Code size 148 (0x94) .maxstack 6 .locals init (valuetype StructUnion01/U V_0, valuetype StructUnion01/U V_1, @@ -658,54 +668,56 @@ IL_0015: ldc.i4.3 IL_0016: sub IL_0017: switch ( - IL_004c) - IL_0020: ldloca.s V_1 - IL_0022: ldfld int32 StructUnion01/U::item2 - IL_0027: stloc.2 - IL_0028: ldloca.s V_1 - IL_002a: ldfld int32 StructUnion01/U::item1 - IL_002f: stloc.3 - IL_0030: ldloca.s V_0 - IL_0032: ldfld int32 StructUnion01/U::item2 - IL_0037: stloc.s V_4 - IL_0039: ldloca.s V_0 - IL_003b: ldfld int32 StructUnion01/U::item1 - IL_0040: stloc.s V_5 - IL_0042: ldloc.s V_5 - IL_0044: ldloc.s V_4 - IL_0046: add - IL_0047: ldloc.3 - IL_0048: add - IL_0049: ldloc.2 - IL_004a: add - IL_004b: ret - - IL_004c: ldloca.s V_1 - IL_004e: ldfld int32 StructUnion01/U::item1 - IL_0053: ldc.i4.5 - IL_0054: sub - IL_0055: switch ( - IL_0082) - IL_005e: ldloca.s V_1 - IL_0060: ldfld int32 StructUnion01/U::item2 - IL_0065: ldloca.s V_1 - IL_0067: ldfld int32 StructUnion01/U::item1 - IL_006c: ldloca.s V_0 - IL_006e: ldfld int32 StructUnion01/U::item2 - IL_0073: ldloca.s V_0 - IL_0075: ldfld int32 StructUnion01/U::item1 - IL_007a: stloc.s V_5 - IL_007c: stloc.s V_4 - IL_007e: stloc.3 - IL_007f: stloc.2 - IL_0080: br.s IL_0042 - - IL_0082: ldloca.s V_0 - IL_0084: ldfld int32 StructUnion01/U::item2 - IL_0089: ldloca.s V_1 - IL_008b: ldfld int32 StructUnion01/U::item2 + IL_0022) + IL_0020: br.s IL_0068 + + IL_0022: ldloca.s V_1 + IL_0024: ldfld int32 StructUnion01/U::item1 + IL_0029: ldc.i4.5 + IL_002a: sub + IL_002b: switch ( + IL_0058) + IL_0034: ldloca.s V_1 + IL_0036: ldfld int32 StructUnion01/U::item2 + IL_003b: ldloca.s V_1 + IL_003d: ldfld int32 StructUnion01/U::item1 + IL_0042: ldloca.s V_0 + IL_0044: ldfld int32 StructUnion01/U::item2 + IL_0049: ldloca.s V_0 + IL_004b: ldfld int32 StructUnion01/U::item1 + IL_0050: stloc.s V_5 + IL_0052: stloc.s V_4 + IL_0054: stloc.3 + IL_0055: stloc.2 + IL_0056: br.s IL_008a + + IL_0058: ldloca.s V_0 + IL_005a: ldfld int32 StructUnion01/U::item2 + IL_005f: ldloca.s V_1 + IL_0061: ldfld int32 StructUnion01/U::item2 + IL_0066: add + IL_0067: ret + + IL_0068: ldloca.s V_1 + IL_006a: ldfld int32 StructUnion01/U::item2 + IL_006f: stloc.2 + IL_0070: ldloca.s V_1 + IL_0072: ldfld int32 StructUnion01/U::item1 + IL_0077: stloc.3 + IL_0078: ldloca.s V_0 + IL_007a: ldfld int32 StructUnion01/U::item2 + IL_007f: stloc.s V_4 + IL_0081: ldloca.s V_0 + IL_0083: ldfld int32 StructUnion01/U::item1 + IL_0088: stloc.s V_5 + IL_008a: ldloc.s V_5 + IL_008c: ldloc.s V_4 + IL_008e: add + IL_008f: ldloc.3 IL_0090: add - IL_0091: ret + IL_0091: ldloc.2 + IL_0092: add + IL_0093: ret } // end of method StructUnion01::f4 } // end of class StructUnion01 diff --git a/tests/fsharpqa/Source/Printing/BindingsWithValues01.fsx b/tests/fsharpqa/Source/Printing/BindingsWithValues01.fsx index 30b453b9fc6..655a9f0524d 100644 --- a/tests/fsharpqa/Source/Printing/BindingsWithValues01.fsx +++ b/tests/fsharpqa/Source/Printing/BindingsWithValues01.fsx @@ -9,52 +9,52 @@ // \| House // \| Museum // \| Office -//val a : int = 1 -//val B : string = "Hello" -//val c' : RecT = { Name = "F#" } -//val _d : Bldg = Office -//val e : seq -//val F'F : int list = \[3; 2; 1] -//val g : Set -//val g' : Set<'a> -//val getPointF : x:float32 \* y:float32 -> System\.Drawing\.PointF -//val h : System\.Drawing\.PointF = {X=.+, Y=.+} -//val i : int \* RecT \* Bldg = \(1, { Name = "F#" }, Office\) -//val J_ : int \[\] = \[\|1; 2; 3\|] -//val j_' : float \[\] = \[\|1\.0; 1\.0\|] -//val j_'_ : RecT \[\] = \[\|\|] -//val j_'' : string \[\] = \[\|"0"; "1"; "2"; "3"; "4"\|] +//val a: int = 1 +//val B: string = "Hello" +//val c': RecT = { Name = "F#" } +//val _d: Bldg = Office +//val e: seq +//val F'F: int list = \[3; 2; 1] +//val g: Set +//val g': Set<'a> +//val getPointF: x: float32 \* y: float32 -> System\.Drawing\.PointF +//val h: System\.Drawing\.PointF = {X=.+, Y=.+} +//val i: int \* RecT \* Bldg = \(1, { Name = "F#" }, Office\) +//val J_: int\[\] = \[\|1; 2; 3\|] +//val j_': float\[\] = \[\|1\.0; 1\.0\|] +//val j_'_: RecT\[\] = \[\|\|] +//val j_'': string\[\] = \[\|"0"; "1"; "2"; "3"; "4"\|] type RecT = { Name : string } type Bldg = House | Museum | Office -let a = 1 // int - val a : int = 1 -let B = "Hello" // reference type - val B : string = "Hello" +let a = 1 // int - val a: int = 1 +let B = "Hello" // reference type - val B: string = "Hello" -let c' = { Name = "F#" } // record - val c' : RecT = { Name = "F#" } +let c' = { Name = "F#" } // record - val c': RecT = { Name = "F#" } -let _d = Office // disc unioin - val _d : Bldg = Office +let _d = Office // disc unioin - val _d: Bldg = Office -let e = {1..2..100} // sequence - val e : seq = -let F'F = [3..-1..1] // list - val F'F : int list = [3; 2; 1] +let e = {1..2..100} // sequence - val e: seq = +let F'F = [3..-1..1] // list - val F'F: int list = [3; 2; 1] let g = (Set.ofSeq e) - |> Set.intersect (Set.ofList F'F) // set - val g : Set = + |> Set.intersect (Set.ofList F'F) // set - val g: Set = -let g' = Set.empty // another set - val g' : Set<'a> +let g' = Set.empty // another set - val g': Set<'a> let getPointF (x, y) = System.Drawing.PointF(x, y) - // function value - val getPointF : float32 * float32 -> System.Drawing.PointF + // function value - val getPointF: float32 * float32 -> System.Drawing.PointF -let h = getPointF (1.5f, -1.5f) // PointF structure - val h : System.Drawing.PointF = {X=1.5, Y=-1.5} +let h = getPointF (1.5f, -1.5f) // PointF structure - val h: System.Drawing.PointF = {X=1.5, Y=-1.5} -let i = (1, c', _d) // tuple - val i : int * RecT * Bldg = (1, { Name = "F#" }, Office) +let i = (1, c', _d) // tuple - val i: int * RecT * Bldg = (1, { Name = "F#" }, Office) -let J_ = [| 1; 2; 3; |] // array - val J_ : int array = [|1; 2; 3|] -let j_' = Array.create 2 1.0 // another array - val j_' : float array = [|1.0; 1.0|] -let j_'_ = Array.empty // empty RecT array - val j_'_ : RecT array = [||] -let j_'' = Array.init 5 (fun i -> i.ToString()) // string array - val j_'' : string array = [|"0"; "1"; "2"; "3"; "4"|] +let J_ = [| 1; 2; 3; |] // array - val J_: int array = [|1; 2; 3|] +let j_' = Array.create 2 1.0 // another array - val j_': float array = [|1.0; 1.0|] +let j_'_ = Array.empty // empty RecT array - val j_'_: RecT array = [||] +let j_'' = Array.init 5 (fun i -> i.ToString()) // string array - val j_'': string array = [|"0"; "1"; "2"; "3"; "4"|] ;; diff --git a/tests/fsharpqa/Source/Printing/Choice01.fsx b/tests/fsharpqa/Source/Printing/Choice01.fsx index 4cb82419193..de37e652529 100644 --- a/tests/fsharpqa/Source/Printing/Choice01.fsx +++ b/tests/fsharpqa/Source/Printing/Choice01.fsx @@ -1,8 +1,8 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:5510 -// val it : Choice -// val it : Choice -// val it : Choice<'a,'b,Choice<'c,decimal,'d,'e,'f,'g,'h>,'i> +// val it: Choice +// val it: Choice +// val it: Choice<'a,'b,Choice<'c,decimal,'d,'e,'f,'g,'h>,'i> Choice1Of2("a");; Choice1Of2(1s);; diff --git a/tests/fsharpqa/Source/Printing/DisposeOnSprintfA.fs b/tests/fsharpqa/Source/Printing/DisposeOnSprintfA.fs index 41af243eb38..fdcfd17f413 100644 --- a/tests/fsharpqa/Source/Printing/DisposeOnSprintfA.fs +++ b/tests/fsharpqa/Source/Printing/DisposeOnSprintfA.fs @@ -1,7 +1,7 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:4725 // F# is not disposing an IEnumerator in implementation of sprintf "%A" -//Done +//Done let x = seq { try yield 1; yield 2; finally printfn "Done" } diff --git a/tests/fsharpqa/Source/Printing/LazyValues01.fsx b/tests/fsharpqa/Source/Printing/LazyValues01.fsx index 1b3b6a18766..0cefa561d0c 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues01.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues01.fsx @@ -1,9 +1,9 @@ // #Regression #NoMT #Printing // Regression test for FSharp1.0:3981 - Lazy gets NullReferenceException when displayed -// val a : Lazy = -// val b : unit list = \[null\] -// val c : unit \[\] = \[\|null; null; null\|] -// val d : unit = \(\) +// val a: Lazy = +// val b: unit list = \[null\] +// val c: unit \[\] = \[\|null; null; null\|] +// val d: unit = \(\) let a = lazy() let b = [ () ] diff --git a/tests/fsharpqa/Source/Printing/LazyValues01NetFx4.fsx b/tests/fsharpqa/Source/Printing/LazyValues01NetFx4.fsx index 1967a9c7fd8..651ba156c30 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues01NetFx4.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues01NetFx4.fsx @@ -1,9 +1,9 @@ // #Regression #NoMT #Printing #RequiresENU // Regression test for FSharp1.0:3981 - Lazy gets NullReferenceException when displayed -// val a : Lazy = Value is not created -// val b : unit list = \[\(\)\] -// val c : unit \[\] = \[\|\(\); \(\); \(\)\|] -// val d : unit = \(\) +// val a: Lazy = Value is not created +// val b: unit list = \[\(\)\] +// val c: unit\[\] = \[\|\(\); \(\); \(\)\|] +// val d: unit = \(\) let a = lazy() let b = [ () ] diff --git a/tests/fsharpqa/Source/Printing/LazyValues02.fsx b/tests/fsharpqa/Source/Printing/LazyValues02.fsx index cf312ad3a1b..8f172c6ab1d 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues02.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues02.fsx @@ -2,12 +2,12 @@ // Regression test for FSHARP1.0:4068 // Title: printing lazy property values forces the lazy value -//val lazy12 : Lazy = -//val it : Lazy = -//val it : Lazy = -//val it : Lazy = -//val it : Lazy = -//val it : Lazy = +//val lazy12: Lazy = +//val it: Lazy = +//val it: Lazy = +//val it: Lazy = +//val it: Lazy = +//val it: Lazy = let lazy12 = lazy 12;; lazy12;; diff --git a/tests/fsharpqa/Source/Printing/LazyValues02NetFx4.fsx b/tests/fsharpqa/Source/Printing/LazyValues02NetFx4.fsx index 38535a71120..8252336a7dd 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues02NetFx4.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues02NetFx4.fsx @@ -2,12 +2,12 @@ // Regression test for FSHARP1.0:4068 // Title: printing lazy property values forces the lazy value -//val lazy12 : Lazy = Value is not created\. -//val it : Lazy = Value is not created\. -//val it : Lazy = Value is not created\. -//val it : Lazy = Value is not created\. -//val it : Lazy = Value is not created\. -//val it : Lazy = Value is not created\. +//val lazy12: Lazy = Value is not created\. +//val it: Lazy = Value is not created\. +//val it: Lazy = Value is not created\. +//val it: Lazy = Value is not created\. +//val it: Lazy = Value is not created\. +//val it: Lazy = Value is not created\. let lazy12 = lazy 12;; lazy12;; diff --git a/tests/fsharpqa/Source/Printing/LazyValues03.fsx b/tests/fsharpqa/Source/Printing/LazyValues03.fsx index 2c9074bfb50..ecdd992b799 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues03.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues03.fsx @@ -1,7 +1,7 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:4068 -//val lazyExit : Lazy = +//val lazyExit: Lazy = let lazyExit = lazy (exit 1; "this should never be forced");; diff --git a/tests/fsharpqa/Source/Printing/LazyValues03NetFx4.fsx b/tests/fsharpqa/Source/Printing/LazyValues03NetFx4.fsx index 59095a2f175..3b34b564732 100644 --- a/tests/fsharpqa/Source/Printing/LazyValues03NetFx4.fsx +++ b/tests/fsharpqa/Source/Printing/LazyValues03NetFx4.fsx @@ -1,7 +1,7 @@ // #Regression #NoMT #Printing #RequiresENU // Regression test for FSHARP1.0:4068 -//val lazyExit : Lazy = Value is not created\. +//val lazyExit: Lazy = Value is not created\. let lazyExit = lazy (exit 1; "this should never be forced");; diff --git a/tests/fsharpqa/Source/Printing/ParamArrayInSignatures.fsx b/tests/fsharpqa/Source/Printing/ParamArrayInSignatures.fsx index c68d6bbb8e2..f948cbeef58 100644 --- a/tests/fsharpqa/Source/Printing/ParamArrayInSignatures.fsx +++ b/tests/fsharpqa/Source/Printing/ParamArrayInSignatures.fsx @@ -3,9 +3,7 @@ // pretty printing signatures with params arguments //type Heterogeneous = -// class -// static member Echo : \[\] args:obj \[\] -> obj \[\] -// end +// static member Echo: \[\] args: obj\[\] -> obj\[\] type Heterogeneous = static member Echo([] args: obj[]) = args diff --git a/tests/fsharpqa/Source/Printing/Quotation01.fs b/tests/fsharpqa/Source/Printing/Quotation01.fs index c34e1e78fbb..283408df9e1 100644 --- a/tests/fsharpqa/Source/Printing/Quotation01.fs +++ b/tests/fsharpqa/Source/Printing/Quotation01.fs @@ -1,7 +1,5 @@ // #NoMT #Printing // Regression test for FSHARP1.0:524 -//val it : Quotations.Expr = Value \(1\) {CustomAttributes = \[||\]; -// Raw = \.\.\.; -// Type = System\.Int32;} +//val it: Quotations.Expr = Value \(1\) <@ 1 @>;; exit 0;; diff --git a/tests/fsharpqa/Source/Printing/SignatureWithOptionalArgs01.fs b/tests/fsharpqa/Source/Printing/SignatureWithOptionalArgs01.fs index 5605d46d4d0..234db8784e1 100644 --- a/tests/fsharpqa/Source/Printing/SignatureWithOptionalArgs01.fs +++ b/tests/fsharpqa/Source/Printing/SignatureWithOptionalArgs01.fs @@ -3,19 +3,16 @@ // pretty printing signatures with optional arguments //type AsyncTimer = -// class -// new : f:\(unit -> unit\) \* \?delay:int -> AsyncTimer -// member Start : unit -> unit -// member Stop : unit -> unit -// member Delay : int option -// member Delay : int option with set -// end +// new: f: \(unit -> unit\) \* \?delay: int -> AsyncTimer +// member Start: unit -> unit +// member Stop: unit -> unit +// member Delay: int option open Microsoft.FSharp.Control type AsyncTimer(f, ?delay ) = let mutable does_again = true - let mutable delay = delay + let mutable delay: int option = delay member t.Delay with get() = delay diff --git a/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip01.fsx b/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip01.fsx index d4643be3c79..46f4b7348fa 100644 --- a/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip01.fsx +++ b/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip01.fsx @@ -1,9 +1,9 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:3300 // Verify that Pretty-printing of measure identifiers round-trips, i.e. displays the long identified (Namespace.Module.Type) -//val it : decimal = -2\.0M -//val it : float32 = 2\.0f -//val it : float = 1\.2 +//val it: decimal = -2\.0M +//val it: float32 = 2\.0f +//val it: float = 1\.2 #light module M1 = diff --git a/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip02.fsx b/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip02.fsx index b9b5d7d8385..18d70091258 100644 --- a/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip02.fsx +++ b/tests/fsharpqa/Source/Printing/UnitsOfMeasureIdentifiersRoundTrip02.fsx @@ -1,9 +1,9 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:3300 // Verify that Pretty-printing of measure identifiers round-trips, i.e. displays the long identified (Namespace.Module.Type) -//val it : decimal+ -//val it : float32+ -//val it : float+ +//val it: decimal+ +//val it: float32+ +//val it: float+ #light #r "UnitsOfMeasureIdentifiersRoundTrip02.dll" diff --git a/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature01.fsx b/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature01.fsx index e4a11a88618..ab7c8f1b8dc 100644 --- a/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature01.fsx +++ b/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature01.fsx @@ -3,6 +3,6 @@ // Make sure the generic type variable is echoed back // (notice that the next time we evaluate 'f' this // goes back to 'u) -//val f : x:float+ +//val f: x: float+ let f(x:float<'a>) = x*x;; exit 0;; diff --git a/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature02.fsx b/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature02.fsx index b71e606a9f1..5913d74fea0 100644 --- a/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature02.fsx +++ b/tests/fsharpqa/Source/Printing/UnitsOfMeasuresGenericSignature02.fsx @@ -4,6 +4,6 @@ // (notice that the next time we evaluate 'f' this // goes back to 'u, 'v) // This is the case where the generic function takes 2 args -//val g : x:float+ +//val g: x: float+ let g (x:float<'a>) (y:float32<'b>) = x * float y;; exit 0;; diff --git a/tests/fsharpqa/Source/Printing/VariantTypes01.fs b/tests/fsharpqa/Source/Printing/VariantTypes01.fs index 074e72da981..3f88be9b22f 100644 --- a/tests/fsharpqa/Source/Printing/VariantTypes01.fs +++ b/tests/fsharpqa/Source/Printing/VariantTypes01.fs @@ -2,6 +2,6 @@ // Regression test for FSHARP1.0:1401 // incorrect pretty printing of variant types // The issue here was the missing parens around the nested Some ... -//val it : int option option = Some \(Some 1\) +//val it: int option option = Some \(Some 1\) Some(Some(1));; exit 0;; diff --git a/tests/fsharpqa/Source/Printing/array2D.blit_01.fsx b/tests/fsharpqa/Source/Printing/array2D.blit_01.fsx index 742bec179d9..8860f195e01 100644 --- a/tests/fsharpqa/Source/Printing/array2D.blit_01.fsx +++ b/tests/fsharpqa/Source/Printing/array2D.blit_01.fsx @@ -3,17 +3,17 @@ // Covering the blit between zero-based and non-zero based Array2D // The rest of the tests are Unittests. // -//val it : bool = true +//val it: bool = true -//val a : string [,] = [bound1=1 -// bound2=2 -// ["a12"; "a13"] -// ["a22"; "a23"] -// ["a32"; "a33"]] +//val a: string[,] = [bound1=1 +// bound2=2 +// ["a12"; "a13"] +// ["a22"; "a23"] +// ["a32"; "a33"]] // -//val b : string [,] = [["b00"; "b01"] -// ["b10"; "b11"] -// ["b20"; "b21"]] +//val b: string[,] = [["b00"; "b01"] +// ["b10"; "b11"] +// ["b20"; "b21"]] let a = Array2D.initBased 1 2 3 2 (fun a b -> "a" + string a + string b) diff --git a/tests/fsharpqa/Source/Printing/array2D_01.fsx b/tests/fsharpqa/Source/Printing/array2D_01.fsx index 34a6b4c79ae..4e27059db65 100644 --- a/tests/fsharpqa/Source/Printing/array2D_01.fsx +++ b/tests/fsharpqa/Source/Printing/array2D_01.fsx @@ -1,12 +1,12 @@ // #Regression #NoMT #Printing // Regression test for FSHARP1.0:5231 // -//val s : int list = \[1; 2\] -//val q : int list list = \[\[1; 2\]; \[1; 2\]; \[1; 2\]\] -//val a : int \[,\] = \[\[1; 2\] -// \[1; 2\] -// \[1; 2\]\] -//val v : bool = false +//val s: int list = \[1; 2\] +//val q: int list list = \[\[1; 2\]; \[1; 2\]; \[1; 2\]\] +//val a: int\[,\] = \[\[1; 2\] +// \[1; 2\] +// \[1; 2\]\] +//val v: bool = false let s = [1 .. 2] let q = [s; s; s] diff --git a/tests/fsharpqa/Source/TemplatesAndSnippets/PInvokeExample.fs b/tests/fsharpqa/Source/TemplatesAndSnippets/PInvokeExample.fs index ec10870fe49..c897344704b 100644 --- a/tests/fsharpqa/Source/TemplatesAndSnippets/PInvokeExample.fs +++ b/tests/fsharpqa/Source/TemplatesAndSnippets/PInvokeExample.fs @@ -24,7 +24,7 @@ open System.IO open System.Runtime.InteropServices // Get two temp files, write data into one of them -let tempFile1, tempFile2 = Path.GetTempFileName(), Path.GetTempFileName() +let tempFile1, tempFile2 = tryCreateTemporaryFileName (), tryCreateTemporaryFileName () let writer = new StreamWriter (tempFile1) writer.WriteLine("Some Data") writer.Close() diff --git a/tests/fsharpqa/Source/Warnings/MissingExpressionAfterLet.fs b/tests/fsharpqa/Source/Warnings/MissingExpressionAfterLet.fs deleted file mode 100644 index 041e5fd35b8..00000000000 --- a/tests/fsharpqa/Source/Warnings/MissingExpressionAfterLet.fs +++ /dev/null @@ -1,8 +0,0 @@ -// #Warnings -//The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result. - -let sum = 0 -for x in 0 .. 10 do - let sum = sum + x - -exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/ModuleAbbreviationsArePrivate.fs b/tests/fsharpqa/Source/Warnings/ModuleAbbreviationsArePrivate.fs deleted file mode 100644 index 75d33073f45..00000000000 --- a/tests/fsharpqa/Source/Warnings/ModuleAbbreviationsArePrivate.fs +++ /dev/null @@ -1,6 +0,0 @@ -// #Warnings -//The 'Public' accessibility attribute is not allowed on module abbreviation. - -module public L1 = List - -exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/WrongNumericLiteral.fs b/tests/fsharpqa/Source/Warnings/WrongNumericLiteral.fs deleted file mode 100644 index c6b3514e1ce..00000000000 --- a/tests/fsharpqa/Source/Warnings/WrongNumericLiteral.fs +++ /dev/null @@ -1,6 +0,0 @@ -// #Warnings -//This is not a valid numeric literal. Valid numeric literals include - -let foo = 1up - -exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Warnings/env.lst b/tests/fsharpqa/Source/Warnings/env.lst index 4d6ba629e17..a9751119f86 100644 --- a/tests/fsharpqa/Source/Warnings/env.lst +++ b/tests/fsharpqa/Source/Warnings/env.lst @@ -1,5 +1,2 @@ - SOURCE=WrongNumericLiteral.fs # WrongNumericLiteral.fs SOURCE=FS0988AtEndOfFile.fs # FS0988AtEndOfFile.fs - SOURCE=MissingExpressionAfterLet.fs # MissingExpressionAfterLet.fs SOURCE=Repro1548.fs SCFLAGS="-r:Repro1548.dll" # Repro1548.fs - SOURCE=ModuleAbbreviationsArePrivate.fs diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 8a3aeac76b2..5a8307bdb9f 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -31,7 +31,6 @@ CodeGen01,NoMT,CodeGen CodeGen\EmittedIL\Tuples CodeGen01,NoMT,CodeGen CodeGen\StringEncoding CodeGen01,NoMT,CodeGen CodeGen\Structure - CompilerOptions01,NoMT CompilerOptions\fsc\checked CompilerOptions01,NoMT CompilerOptions\fsc\cliversion CompilerOptions01,NoMT CompilerOptions\fsc\codepage @@ -58,6 +57,7 @@ CompilerOptions01,NoMT CompilerOptions\fsc\subsystemversion CompilerOptions01,NoMT CompilerOptions\fsc\tailcalls CompilerOptions01,NoMT CompilerOptions\fsc\target CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\times +CompilerOptions01,NoMT,NoHostedCompiler CompilerOptions\fsc\tokenize CompilerOptions01,NoMT CompilerOptions\fsc\warn CompilerOptions01,NoMT CompilerOptions\fsc\warnaserror CompilerOptions01,NoMT CompilerOptions\fsc\warnon @@ -127,7 +127,7 @@ Conformance03 Conformance\Expressions\ControlFlowExpressions\PatternMatching Conformance03 Conformance\Expressions\ControlFlowExpressions\SequenceIteration Conformance03 Conformance\Expressions\ControlFlowExpressions\SequentialExecution Conformance03 Conformance\Expressions\ControlFlowExpressions\SimpleFor -Conformance03 Conformance\Expressions\ControlFlowExpressions\TryCatch +Conformance03 Conformance\Expressions\ControlFlowExpressions\TryWith Conformance03 Conformance\Expressions\ControlFlowExpressions\TryFinally Conformance03 Conformance\Expressions\ControlFlowExpressions\While Conformance03 Conformance\Expressions\DataExpressions\AddressOf @@ -266,8 +266,6 @@ Misc01 Libraries\Core\Operators Misc01 Libraries\Core\Reflection Misc01 Libraries\Core\Unchecked Misc01 Warnings -Misc01 ErrorMessages\UnitGenericAbstractType -Misc01 ErrorMessages\ConfusingTypeName Misc02 Libraries\Portable Misc02 Misc diff --git a/tests/fsharpqa/run.fsharpqa.test.fsx b/tests/fsharpqa/run.fsharpqa.test.fsx index 18a2e118b81..48f58e145b4 100644 --- a/tests/fsharpqa/run.fsharpqa.test.fsx +++ b/tests/fsharpqa/run.fsharpqa.test.fsx @@ -15,7 +15,10 @@ let addToPath path = if not(Array.contains path splits) then setEnvVar "PATH" (path + (string Path.PathSeparator) + currentPath) -let nugetCache = Path.Combine(System.Environment.GetEnvironmentVariable "USERPROFILE", ".nuget", "packages") +let nugetCache = + match System.Environment.GetEnvironmentVariable("NUGET_PACKAGES") with + | null -> Path.Combine(System.Environment.GetEnvironmentVariable "USERPROFILE", ".nuget", "packages") + | path -> path let rootFolder = Path.Combine(__SOURCE_DIRECTORY__, "..", "..") let compilerBinFolder = Path.Combine(rootFolder, "artifacts", "bin", "fsc", releaseOrDebug, "net472") setEnvVar "CSC_PIPE" (Path.Combine(nugetCache, "Microsoft.Net.Compilers", "2.7.0", "tools", "csc.exe")) diff --git a/tests/fsharpqa/testenv/bin/KnownFailRewriter.fsx b/tests/fsharpqa/testenv/bin/KnownFailRewriter.fsx index df8ec8f2ad8..e2a5ebfb331 100644 --- a/tests/fsharpqa/testenv/bin/KnownFailRewriter.fsx +++ b/tests/fsharpqa/testenv/bin/KnownFailRewriter.fsx @@ -102,7 +102,7 @@ module FSharpInfo = let IsFSharpCompilerDebug () = let o = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\FSharp\4.1\Runtime\v4.0", null, null) if o <> null then - let path = System.IO.Path.Combine( o :?> string, "FSharp.Compiler.Private.dll") + let path = System.IO.Path.Combine( o :?> string, "FSharp.Compiler.Service.dll") let asm = System.Reflection.Assembly.LoadFrom(path) match asm.GetCustomAttributes(typeof, false) with diff --git a/tests/fsharpqa/testenv/src/HostedCompilerServer/App.config b/tests/fsharpqa/testenv/src/HostedCompilerServer/App.config index ab88e62ffc5..ac648e17666 100644 --- a/tests/fsharpqa/testenv/src/HostedCompilerServer/App.config +++ b/tests/fsharpqa/testenv/src/HostedCompilerServer/App.config @@ -7,13 +7,9 @@ - - - - - - + + diff --git a/tests/fsharpqa/testenv/src/HostedCompilerServer/HostedCompilerServer.fsproj b/tests/fsharpqa/testenv/src/HostedCompilerServer/HostedCompilerServer.fsproj index f89e94f3e05..eb1bde254d8 100644 --- a/tests/fsharpqa/testenv/src/HostedCompilerServer/HostedCompilerServer.fsproj +++ b/tests/fsharpqa/testenv/src/HostedCompilerServer/HostedCompilerServer.fsproj @@ -8,8 +8,10 @@ true false $(RepoRoot)tests\fsharpqa\testenv\bin + $(NoWarn);44 AnyCPU true + true @@ -19,7 +21,7 @@ - + diff --git a/tests/fsharpqa/testenv/src/HostedCompilerServer/Program.fs b/tests/fsharpqa/testenv/src/HostedCompilerServer/Program.fs index 858382b9f26..775e3897901 100644 --- a/tests/fsharpqa/testenv/src/HostedCompilerServer/Program.fs +++ b/tests/fsharpqa/testenv/src/HostedCompilerServer/Program.fs @@ -1,14 +1,11 @@ namespace MLang.Test open System -open System.IO open System.Net open System.Net.Sockets open System.Text -open System.Threading -open System.Linq -open FSharp.Compiler -open Legacy.FSharp.Compiler.Hosted +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CodeAnalysis.Hosted [] module Log = diff --git a/tests/fsharpqa/testenv/src/ILComparer/ILComparer.fsproj b/tests/fsharpqa/testenv/src/ILComparer/ILComparer.fsproj index c530b623a40..80b7af8303a 100644 --- a/tests/fsharpqa/testenv/src/ILComparer/ILComparer.fsproj +++ b/tests/fsharpqa/testenv/src/ILComparer/ILComparer.fsproj @@ -2,7 +2,7 @@ - net45 + net472 Exe true true diff --git a/tests/fsharpqa/testenv/src/PEVerify/PEVerify.csproj b/tests/fsharpqa/testenv/src/PEVerify/PEVerify.csproj index 47555139254..affe87d5293 100644 --- a/tests/fsharpqa/testenv/src/PEVerify/PEVerify.csproj +++ b/tests/fsharpqa/testenv/src/PEVerify/PEVerify.csproj @@ -2,7 +2,8 @@ Exe - net472 + net472;net5.0 + net5.0 $(NoWarn);1591 diff --git a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.sln b/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.sln deleted file mode 100644 index 9b2e1f91dc2..00000000000 --- a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{4925A630-B079-445d-BCD4-3A9C94FE9307}") = "Sample_MonoDevelop_3_2_8_Console", "Sample_MonoDevelop_3_2_8_Console\Sample_MonoDevelop_3_2_8_Console.fsproj", "{6A6B7AF8-C2FB-4271-A1D1-0D16C3770949}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6A6B7AF8-C2FB-4271-A1D1-0D16C3770949}.Debug|x86.ActiveCfg = Debug|x86 - {6A6B7AF8-C2FB-4271-A1D1-0D16C3770949}.Debug|x86.Build.0 = Debug|x86 - {6A6B7AF8-C2FB-4271-A1D1-0D16C3770949}.Release|x86.ActiveCfg = Release|x86 - {6A6B7AF8-C2FB-4271-A1D1-0D16C3770949}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Sample_MonoDevelop_3_2_8_Console\Sample_MonoDevelop_3_2_8_Console.fsproj - EndGlobalSection -EndGlobal diff --git a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/AssemblyInfo.fs b/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/AssemblyInfo.fs deleted file mode 100644 index 4032d7ae0b6..00000000000 --- a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/AssemblyInfo.fs +++ /dev/null @@ -1,22 +0,0 @@ -module Sample_MonoDevelop_3_2_8_Console.AssemblyInfo -open System.Reflection -open System.Runtime.CompilerServices - - -[] -[] -[] -[] -[] -[] -[] - -// The assembly version has the format {Major}.{Minor}.{Build}.{Revision} - -[] - -//[] -//[] - -() - diff --git a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Program.fs b/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Program.fs deleted file mode 100644 index 36739ce1622..00000000000 --- a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Program.fs +++ /dev/null @@ -1,16 +0,0 @@ - -// NOTE: If warnings appear, you may need to retarget this project to .NET 4.0. Show the Solution -// Pad, right-click on the project node, choose 'Options --> Build --> General' and change the target -// framework to .NET 4.0 or .NET 4.5. - -module Sample_MonoDevelop_3_2_8_Console.Main - -open System - -let someFunction x y = x + y - -[] -let main args = - Console.WriteLine("Hello world!") - 0 - diff --git a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.fsproj b/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.fsproj deleted file mode 100644 index 1a3952c46c3..00000000000 --- a/tests/projects/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console/Sample_MonoDevelop_3_2_8_Console.fsproj +++ /dev/null @@ -1,45 +0,0 @@ - - - - Debug - x86 - 10.0.0 - 2.0 - {6A6B7AF8-C2FB-4271-A1D1-0D16C3770949} - Exe - Sample_MonoDevelop_3_2_8_Console - Sample_MonoDevelop_3_2_8_Console - v4.5 - - - true - full - bin\Debug - DEBUG - prompt - True - x86 - - - true - pdbonly - true - bin\Release - prompt - True - x86 - true - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props index aa744e6acad..8c119d5413b 100644 --- a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props +++ b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props @@ -1,4 +1,2 @@ - - diff --git a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets index 4d469fc9359..8c119d5413b 100644 --- a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets +++ b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets @@ -1,4 +1,2 @@ - - diff --git a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj index 5581f3419b8..621cb1ecb89 100644 --- a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj +++ b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj @@ -1,8 +1,7 @@ netstandard2.0 - 4.6.* - 4.5.* + true diff --git a/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Program.fs b/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Program.fs new file mode 100644 index 00000000000..bbdd1d9e0a0 --- /dev/null +++ b/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Program.fs @@ -0,0 +1,9 @@ +// Learn more about F# at http://fsharp.org + +open System + + +[] +let main argv = + printfn "Hello World from F#!" + 0 // return an integer exit code diff --git a/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core.fsproj b/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core.fsproj new file mode 100644 index 00000000000..d47c2dfe412 --- /dev/null +++ b/tests/projects/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core/Sample_VS2017_FSharp_ConsoleApp_net35_old_fsharp_core.fsproj @@ -0,0 +1,16 @@ + + + + Exe + net35 + + + + + + + + + + + diff --git a/tests/scripts/DeployProj.fsx b/tests/scripts/DeployProj.fsx deleted file mode 100644 index 27a64946add..00000000000 --- a/tests/scripts/DeployProj.fsx +++ /dev/null @@ -1,41 +0,0 @@ -#load "../../src/scripts/scriptlib.fsx" -#load "crackProjectJson.fsx" - -open System -open System.IO -open FSharp.Data -open FSharp.Data.JsonExtensions -let root = Path.GetFullPath (__SOURCE_DIRECTORY__ ++ ".." ++ "..") - -try - let ProjectJsonLock = getCmdLineArg "--projectJsonLock:" (root ++ "tests" ++ "fsharp" ++ "project.lock.json") - let PackagesDir = getCmdLineArg "--packagesDir:" (root ++ "packages") - let Framework = getCmdLineArg "--framework:" ".NETCoreApp,Version=v1.0" - let Platform = getCmdLineArg "--platform:" defaultPlatform - let FSharpCore = getCmdLineArg "--fsharpCore:" @"release/coreclr/bin/FSharp.Core.dll" - let Output = getCmdLineArg "--output:" @"." - let Verbosity = getCmdLineArg "--v:" @"quiet" - let CopyCompiler = getCmdLineArg "--copyCompiler:" @"no" - - let FSharpCompilerFiles = - let FSharpCoreDir = getDirectoryName FSharpCore - [ FSharpCoreDir ++ "fsc.exe" - FSharpCoreDir ++ "FSharp.Compiler.dll" - FSharpCoreDir ++ "default.win32manifest" - FSharpCoreDir ++ "fsi.exe" - FSharpCoreDir ++ "FSharp.Compiler.Interactive.Settings.dll" ] - - let isVerbose = Verbosity = "verbose" - - let dependencies = CrackProjectJson.collectReferences (isVerbose, PackagesDir, Framework + "/" + Platform, ProjectJsonLock, true, true) - - //Okay copy everything - makeDirectory Output - dependencies |> Seq.iter(fun source -> copyFile source Output) - if CopyCompiler = "yes" then - copyFile FSharpCore Output - FSharpCompilerFiles |> Seq.iter(fun source -> copyFile source Output) - exit 0 -with e -> - printfn "%s" (e.ToString()) - exit 1 \ No newline at end of file diff --git a/tests/scripts/codingConventions.fsx b/tests/scripts/codingConventions.fsx index 02e0dc541a3..f4b1df2fddf 100644 --- a/tests/scripts/codingConventions.fsx +++ b/tests/scripts/codingConventions.fsx @@ -3,7 +3,7 @@ open System.IO let lines = - [| for dir in [ "src/fsharp"; "src/fsharp/FSharp.Core"; "src/fsharp/symbols"; "src/fsharp/service"; "src/absil" ]do + [| for dir in [ "src/fsharp"; "src/fsharp/FSharp.Core"; "src/fsharp/symbols"; "src/fsharp/service"; "src/fsharp/absil" ]do for file in Directory.EnumerateFiles(__SOURCE_DIRECTORY__ + "/../../" + dir, "*.fs") do // TcGlobals.fs gets an exception let lines = File.ReadAllLines file diff --git a/tests/scripts/compiler-perf-bigfiles.cmd b/tests/scripts/compiler-perf-bigfiles.cmd index 312befdf033..a143cef9f74 100644 --- a/tests/scripts/compiler-perf-bigfiles.cmd +++ b/tests/scripts/compiler-perf-bigfiles.cmd @@ -1,22 +1,22 @@ setlocal -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out -Release\net40\bin\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\libtest\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\printf\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw\test.fsx 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\core\members\basics-hw-mutrec\test.fs 2>> log.err 1>> log.out +artifacts\bin\fsc\Release\net472\fsc.exe /out:tmp.dll %* tests\fsharp\tools\eval\test.fsx 2>> log.err 1>> log.out REM compiler-perf-bigfiles.log diff --git a/tests/scripts/compiler-perf-results.txt b/tests/scripts/compiler-perf-results.txt index c10207ef164..1e158cb388f 100644 --- a/tests/scripts/compiler-perf-results.txt +++ b/tests/scripts/compiler-perf-results.txt @@ -197,21 +197,38 @@ https://github.com/dsyme/visualfsharp.git fix-5136 c9a7678e5 https://github.com/Microsoft/visualfsharp master 7bcbd1abbace1a41e0c6e12723957d87405c4cba 7bcbd1abbace1a41e0c6e12723957d87405c4cba MSRC-3617253 251.16 9.83 34.52 45.45 57.97 58.65 https://github.com/dsyme/visualfsharp.git fix-5136 c9a7678e508dc2ff847c82ee4933f464aa23bee0 7bcbd1abbace1a41e0c6e12723957d87405c4cba MSRC-3617253 257.62 10.34 35.18 45.40 56.07 57.88 https://github.com/Microsoft/visualfsharp master 7bcbd1abbace1a41e0c6e12723957d87405c4cba 7bcbd1abbace1a41e0c6e12723957d87405c4cba MSRC-3617253 250.59 10.10 34.82 45.33 58.62 63.86 -https://github.com/Microsoft/visualfsharp master d38481ed20fc27af9e767646b22e8da5fb037689 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 264.61 10.62 36.12 45.58 56.80 58.41 -https://github.com/Microsoft/visualfsharp master 24ed23a4f277fa24b23a93494770b1ced6a02c5c 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 266.80 10.34 37.16 47.67 58.73 58.82 -https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 279.33 10.53 35.73 42.43 52.15 59.65 -https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f f3d55f286278fcd7dc81fc3636e4b1fdc16218e0 MSRC-3617253 263.89 10.19 34.69 41.24 51.90 59.00 -https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 264.92 10.70 34.44 41.29 52.49 59.16 -https://github.com/manofstick/visualfsharp.git nobox_comparer f5298fd5e407956d506da6e14623c1f698f90113 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 266.58 10.38 36.33 41.24 52.01 58.60 -https://github.com/manofstick/visualfsharp.git nobox_comparer f5298fd5e407956d506da6e14623c1f698f90113 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 266.91 10.36 34.71 41.20 52.88 59.43 -https://github.com/manofstick/visualfsharp.git nobox 5b80e902e50d9ffc43de1d48748ad735d6319403 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 269.76 10.40 35.36 42.61 51.98 58.77 -https://github.com/manofstick/visualfsharp.git nobox 5b80e902e50d9ffc43de1d48748ad735d6319403 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 263.90 10.33 35.20 42.92 53.58 56.52 -https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 275.17 10.24 35.76 44.80 55.18 58.95 -https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 260.77 10.01 35.35 45.31 56.67 59.00 -https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 f3d55f286278fcd7dc81fc3636e4b1fdc16218e0 MSRC-3617253 270.06 10.33 35.78 46.71 57.46 59.77 -https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 273.90 10.79 35.08 46.55 58.12 59.74 -https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 263.89 10.44 34.44 42.21 51.63 60.27 -https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c f3d55f286278fcd7dc81fc3636e4b1fdc16218e0 MSRC-3617253 259.13 10.44 34.32 41.14 51.28 58.82 -https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 274.98 10.69 36.03 43.64 52.48 57.74 -https://github.com/manofstick/visualfsharp.git nobox_reflection 3a4f0b7356fafb2f8aef9f6360ab26585a3a20f8 24ed23a4f277fa24b23a93494770b1ced6a02c5c MSRC-3617253 262.95 10.58 34.71 43.21 53.43 59.23 -https://github.com/manofstick/visualfsharp.git nobox_reflection 3a4f0b7356fafb2f8aef9f6360ab26585a3a20f8 d38481ed20fc27af9e767646b22e8da5fb037689 MSRC-3617253 265.57 10.24 36.23 42.52 59.23 59.87 +https://github.com/Microsoft/visualfsharp master d38481ed20fc27af9e767646b22e8da5fb037689 d38481ed20fc27af9e767646 MSRC-3617253 264.61 10.62 36.12 45.58 56.80 58.41 +https://github.com/Microsoft/visualfsharp master 24ed23a4f277fa24b23a93494770b1ced6a02c5c 24ed23a4f277fa24b23a9349 MSRC-3617253 266.80 10.34 37.16 47.67 58.73 58.82 +https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f d38481ed20fc27af9e767646 MSRC-3617253 279.33 10.53 35.73 42.43 52.15 59.65 +https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f f3d55f286278fcd7dc81fc36 MSRC-3617253 263.89 10.19 34.69 41.24 51.90 59.00 +https://github.com/manofstick/visualfsharp.git notagged 73faf347d22716da3a7e1d3bcfabeeb505b8c80f 24ed23a4f277fa24b23a9349 MSRC-3617253 264.92 10.70 34.44 41.29 52.49 59.16 +https://github.com/manofstick/visualfsharp.git nobox_comparer f5298fd5e407956d506da6e14623c1f698f90113 d38481ed20fc27af9e767646 MSRC-3617253 266.58 10.38 36.33 41.24 52.01 58.60 +https://github.com/manofstick/visualfsharp.git nobox_comparer f5298fd5e407956d506da6e14623c1f698f90113 24ed23a4f277fa24b23a9349 MSRC-3617253 266.91 10.36 34.71 41.20 52.88 59.43 +https://github.com/manofstick/visualfsharp.git nobox 5b80e902e50d9ffc43de1d48748ad735d6319403 d38481ed20fc27af9e767646 MSRC-3617253 269.76 10.40 35.36 42.61 51.98 58.77 +https://github.com/manofstick/visualfsharp.git nobox 5b80e902e50d9ffc43de1d48748ad735d6319403 24ed23a4f277fa24b23a9349 MSRC-3617253 263.90 10.33 35.20 42.92 53.58 56.52 +https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 d38481ed20fc27af9e767646 MSRC-3617253 275.17 10.24 35.76 44.80 55.18 58.95 +https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 d38481ed20fc27af9e767646 MSRC-3617253 260.77 10.01 35.35 45.31 56.67 59.00 +https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 f3d55f286278fcd7dc81fc36 MSRC-3617253 270.06 10.33 35.78 46.71 57.46 59.77 +https://github.com/realvictorprm/visualfsharp.git 20181011_ConstraintSolverRefactoring e531753de12e648cef21b8d7feff2c4619f1fbe4 24ed23a4f277fa24b23a9349 MSRC-3617253 273.90 10.79 35.08 46.55 58.12 59.74 +https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c 24ed23a4f277fa24b23a9349 MSRC-3617253 263.89 10.44 34.44 42.21 51.63 60.27 +https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c f3d55f286278fcd7dc81fc36 MSRC-3617253 259.13 10.44 34.32 41.14 51.28 58.82 +https://github.com/manofstick/visualfsharp.git faster_map_3 df2e8dd09726e86ef62b71b23f8c14bbf9bd540c d38481ed20fc27af9e767646 MSRC-3617253 274.98 10.69 36.03 43.64 52.48 57.74 +https://github.com/manofstick/visualfsharp.git nobox_reflection 3a4f0b7356fafb2f8aef9f6360ab26585a3a20f8 24ed23a4f277fa24b23a9349 MSRC-3617253 262.95 10.58 34.71 43.21 53.43 59.23 +https://github.com/manofstick/visualfsharp.git nobox_reflection 3a4f0b7356fafb2f8aef9f6360ab26585a3a20f8 d38481ed20fc27af9e767646 MSRC-3617253 265.57 10.24 36.23 42.52 59.23 59.87 + +https://github.com/dotnet/fsharp 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 663.14 33.32 40.00 53.75 58.66 60.69 +https://github.com/dotnet/fsharp 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 679.69 33.60 41.28 49.24 56.43 57.23 +https://github.com/dotnet/fsharp 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 684.70 29.05 39.98 51.56 64.27 60.45 + +https://github.com/dotnet/fsharp 1d36c75225436f8a7d30c4691f20d6118b657fec 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 697.57 31.67 40.01 48.07 57.25 59.68 +https://github.com/dotnet/fsharp 1d36c75225436f8a7d30c4691f20d6118b657fec 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 666.30 31.62 36.15 50.29 60.55 60.03 +https://github.com/dotnet/fsharp 1d36c75225436f8a7d30c4691f20d6118b657fec 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 674.49 31.67 39.16 48.85 57.78 58.98 +https://github.com/dotnet/fsharp 1d36c75225436f8a7d30c4691f20d6118b657fec 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 677.11 30.66 36.62 50.07 62.00 60.23 + +https://github.com/dotnet/fsharp 2e4096153972abedae142da85cac2ffbcf57fe0a 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 689.09 32.10 36.98 48.74 59.72 61.07 +https://github.com/dotnet/fsharp 2e4096153972abedae142da85cac2ffbcf57fe0a 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 659.94 31.81 35.24 50.47 61.89 60.14 +https://github.com/dotnet/fsharp 2e4096153972abedae142da85cac2ffbcf57fe0a 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 664.71 31.92 35.74 50.02 61.34 61.10 + +https://github.com/dotnet/fsharp af6ff33b5bc15951a6854bdf3b226db8f0e28b56 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 658.64 31.69 35.81 49.64 61.53 60.58 +https://github.com/dotnet/fsharp af6ff33b5bc15951a6854bdf3b226db8f0e28b56 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 616.64 33.38 33.35 49.66 62.25 61.35 +https://github.com/dotnet/fsharp af6ff33b5bc15951a6854bdf3b226db8f0e28b56 81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa MSRC-3617253 674.67 30.59 38.61 54.18 64.22 61.73 diff --git a/tests/scripts/compiler-perf.fsx b/tests/scripts/compiler-perf.fsx index 04b27703713..0c6f742be20 100644 --- a/tests/scripts/compiler-perf.fsx +++ b/tests/scripts/compiler-perf.fsx @@ -1,49 +1,21 @@ -#if FETCH_PACKAGES -open System -open System.IO - -Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ - -if not (File.Exists "paket.exe") then let url = "https://github.com/fsprojects/Paket/releases/download/3.4.0/paket.exe" in use wc = new Net.WebClient() in let tmp = Path.GetTempFileName() in wc.DownloadFile(url, tmp); File.Move(tmp,Path.GetFileName url);; - -// Step 1. Resolve and install the packages - -#r "paket.exe" - -if not (Directory.Exists "script-packages") then Directory.CreateDirectory("script-packages") |> ignore -Paket.Dependencies.Install(""" -source https://nuget.org/api/v2 -nuget FSharp.Data -nuget FAKE -""","script-packages");; - -#else - - - -#I "script-packages/packages/FAKE/tools" -#I "script-packages/packages/FSharp.Data/lib/net45" -#r "script-packages/packages/FAKE/tools/FakeLib.dll" -#r "script-packages/packages/FSharp.Data/lib/net45/FSharp.Data.dll" +#r "nuget: FSharp.Data, 3.3.3" open System open System.IO -open Fake -open Fake.Git +open System.Diagnostics open FSharp.Data -Fake.Git.Information.describe [] -let repo = "https://github.com/Microsoft/visualfsharp" +let repo = "https://github.com/dotnet/fsharp" [] -let repoApi = "https://api.github.com/repos/Microsoft/visualfsharp" +let repoApi = "https://api.github.com/repos/dotnet/fsharp" type Commits = JsonProvider< const (repoApi + "/commits")> type Pulls = JsonProvider< const (repoApi + "/pulls")> -//type Comments = JsonProvider< "https://api.github.com/repos/Microsoft/visualfsharp/issues/848/comments"> +//type Comments = JsonProvider< "https://api.github.com/repos/dotnet/fsharp/issues/848/comments"> //let comments = Comments.GetSamples() let commits = Commits.GetSamples() @@ -53,13 +25,15 @@ let repoHeadSha = commits.[0].Sha // Do performance testing on all open PRs that have [CompilerPerf] in the title let buildSpecs = - [ for pr in pulls do - //let comments = Comments.Load(pr.CommentsUrl) - if pr.Title.Contains("[CompilerPerf]") then - yield (pr.Head.Repo.CloneUrl, pr.Head.Sha, repoHeadSha, pr.Head.Ref, pr.Number) - // ("https://github.com/dsyme/visualfsharp.git","53d633d6dba0d8f5fcd80f47f588d21cd7a2cff9", repoHeadSha, "no-casts", 1308); - //yield ("https://github.com/forki/visualfsharp.git", "d0ab5fec77482e1280578f47e3257cf660d7f1b2", repoHeadSha, "foreach_optimization", 1303); - yield (repo, repoHeadSha, repoHeadSha, "master", 0); + [ //for pr in pulls do + // if pr.Title.Contains("[CompilerPerf]") then + // yield (pr.Head.Repo.CloneUrl, repoHeadSha, pr.Head.Ref, pr.Number) + // ("https://github.com/dsyme/fsharp.git","53d633d6dba0d8f5fcd80f47f588d21cd7a2cff9", repoHeadSha, "no-casts", 1308); + //yield ("https://github.com/forki/fsharp.git", "d0ab5fec77482e1280578f47e3257cf660d7f1b2", repoHeadSha, "foreach_optimization", 1303); + yield (repo, "81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa", "81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa", 0); + yield (repo, "81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa", "1d36c75225436f8a7d30c4691f20d6118b657fec", 0); + yield (repo, "81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa", "2e4096153972abedae142da85cac2ffbcf57fe0a", 0); + yield (repo, "81d1d918740e9ba3cb2eb063b6f28c3139ca9cfa", "af6ff33b5bc15951a6854bdf3b226db8f0e28b56", 0); ] @@ -69,15 +43,39 @@ let time f = let finish = DateTime.UtcNow res, finish - start +let runProc filename args startDir = + let timer = Stopwatch.StartNew() + let procStartInfo = + ProcessStartInfo( + UseShellExecute = false, + FileName = filename, + Arguments = args + ) + match startDir with | Some d -> procStartInfo.WorkingDirectory <- d | _ -> () + + let p = new Process(StartInfo = procStartInfo) + let started = + try + p.Start() + with | ex -> + ex.Data.Add("filename", filename) + reraise() + if not started then + failwithf "Failed to start process %s" filename + printfn "Started %s with pid %i" p.ProcessName p.Id + p.WaitForExit() + timer.Stop() + printfn "Finished %s after %A milliseconds" filename timer.ElapsedMilliseconds + p.ExitCode let exec cmd args dir = printfn "%s> %s %s" dir cmd args - let result = Shell.Exec(cmd,args,dir) + let result = runProc cmd args (Some dir) if result <> 0 then failwith (sprintf "FAILED: %s> %s %s" dir cmd args) /// Build a specific version of the repo, run compiler perf tests and record the result -let build(cloneUrl,sha:string,baseSha,ref,prNumber) = - let branch = "build-" + string prNumber + "-" + ref + "-" + sha.[0..7] +let build(cloneUrl, baseSha, ref, prNumber) = + let branch = "build-" + string prNumber + "-" + baseSha + "-" + ref let dirBase = __SOURCE_DIRECTORY__ let dirBuild = "current" let dir = Path.Combine(dirBase, dirBuild) // "build-" + ref + "-" + sha.[0..7] @@ -85,12 +83,12 @@ let build(cloneUrl,sha:string,baseSha,ref,prNumber) = if not (Directory.Exists dir) then exec "git" ("clone " + repo + " " + dirBuild) dirBase |> ignore let result = exec "git" "reset --merge" dir - let result = exec "git" "checkout master" dir - let result = exec "git" "clean -f -x" dir - let result = exec "git" ("checkout -B " + branch + " master") dir + let result = exec "git" "checkout main" dir + let result = exec "git" "clean -xfd artifacts src vsintegration tests" dir + let result = exec "git" ("checkout -B " + branch + " " + baseSha) dir let result = exec "git" ("pull " + cloneUrl + " " + ref) dir - let result, buildTime = time (fun () -> exec "cmd" "/C build.cmd release proto net40 notests" dir ) - let result, ngenTime = time (fun () -> exec "ngen" @"install Release\net40\bin\fsc.exe" dir ) + let result, buildTime = time (fun () -> exec "cmd" "/C build.cmd -c Release" dir ) + let result, ngenTime = time (fun () -> exec "ngen" @"install artifacts\bin\fsc\Release\net472\fsc.exe" dir ) let runPhase (test:string) (flags:string)= printfn "copying compiler-perf-%s.cmd to %s" test dir @@ -122,9 +120,9 @@ let build(cloneUrl,sha:string,baseSha,ref,prNumber) = let timesHeaderText, timesText = runScenario "bigfiles" let logFile = "compiler-perf-results.txt" - let logHeader = sprintf "url ref sha base computer build %s" timesHeaderText + let logHeader = sprintf "url ref base computer build %s" timesHeaderText let computer = System.Environment.GetEnvironmentVariable("COMPUTERNAME") - let logLine = sprintf "%s %-28s %s %s %s %0.2f %s" cloneUrl ref sha baseSha computer buildTime.TotalSeconds timesText + let logLine = sprintf "%s %-28s %s %s %0.2f %s" cloneUrl ref baseSha computer buildTime.TotalSeconds timesText let existing = if File.Exists logFile then File.ReadAllLines(logFile) else [| logHeader |] printfn "writing results %s" logLine @@ -139,4 +137,3 @@ for info in buildSpecs do printfn "ERROR: %A - %s" info e.Message -#endif diff --git a/tests/scripts/crackProjectJson.fsx b/tests/scripts/crackProjectJson.fsx deleted file mode 100644 index 20f287b98b6..00000000000 --- a/tests/scripts/crackProjectJson.fsx +++ /dev/null @@ -1,67 +0,0 @@ -module CrackProjectJson - -#load "../../src/scripts/scriptlib.fsx" -#r "../../packages/FSharp.Data.2.2.5/lib/net40/FSharp.Data.dll" - -open FSharp.Data -open FSharp.Data.JsonExtensions - -/// Collects references from project.json.lock -let collectReferences (isVerbose, packagesDir, targetPlatformName, lockFile:string, isForExecute, collectNative) = - let setPathSeperators (path:string) = path.Replace('/', '\\') - - let splitNameAndVersion (ref:string) = - let elements = ref.Split [| '/' |] - if elements.Length >= 2 then - Some(elements.[0], elements.[1]) - else - None - - let getReferencedFiles (referencedFiles:JsonValue) = - seq { - for path, _ in referencedFiles.Properties do - let path = setPathSeperators path - if getFilename path = "_._" then () - else yield setPathSeperators path - } - - let buildReferencePaths name version paths = - seq { - for path in paths do - yield sprintf @"%s\%s\%s\%s" packagesDir name version path - } - - let getAssemblyReferenciesFromTargets (targets:JsonValue) = - seq { - let target = targets.TryGetProperty(targetPlatformName) - match target with - | Some t -> - for ref, value in t.Properties do - match splitNameAndVersion ref with - | Some(name, version) -> - if isVerbose then - printfn "name: %A" name - printfn "version: %A" version - if not isForExecute then - match value.TryGetProperty("compile") with - | None -> () - | Some x -> yield! buildReferencePaths name version (getReferencedFiles x) - else - match value.TryGetProperty("runtime") with - | None -> () - | Some x -> yield! buildReferencePaths name version (getReferencedFiles value?runtime) - if collectNative then - match value.TryGetProperty("native") with - | None -> () - | Some x -> yield! buildReferencePaths name version (getReferencedFiles value?native) - | _ -> () - | None -> failwith (sprintf "Target patform %s not found in %s" targetPlatformName lockFile) - } - - if isVerbose then - printfn "lockFile: %A" lockFile - printfn "targetPlatformName: %A" targetPlatformName - printfn "packagesDir: %A" packagesDir - let projectJson = JsonValue.Load(lockFile) - getAssemblyReferenciesFromTargets projectJson?targets |> Seq.distinct - diff --git a/tests/scripts/fscc.fsx b/tests/scripts/fscc.fsx deleted file mode 100644 index d37aa18e09a..00000000000 --- a/tests/scripts/fscc.fsx +++ /dev/null @@ -1,69 +0,0 @@ -// Simulate fsc.exe on .NET Core - -#load "../../src/scripts/scriptlib.fsx" -#load "crackProjectJson.fsx" - -open System -open System.IO - -let root = Path.GetFullPath (__SOURCE_DIRECTORY__ ++ ".." ++ "..") - -// %USERPROFILE%/.nuget/packages -let defaultPackagesDir = - match System.Environment.GetEnvironmentVariable("USERPROFILE") with - | p -> p ++ @".nuget\packages" - | _ -> root ++ "packages" - -let Platform = getCmdLineArg "--platform:" "win7-x64" -let ProjectJsonLock = getCmdLineArg "--projectJsonLock:" (root ++ "tests" ++ "fsharp" ++ "FSharp.Tests.FSharpSuite.DrivingCoreCLR" ++ "project.lock.json") -let PackagesDir = getCmdLineArg "--packagesDir:" (root ++ "packages") -let FrameworkName = getCmdLineArg "--framework:" ".NETCoreApp,Version=v1.0" -let Verbosity = getCmdLineArg "--verbose:" "quiet" -let CompilerPathOpt = getCmdLineArgOptional "--compilerPath:" -let Flavour = getCmdLineArg "--flavour:" "release" -let TestName = getCmdLineArg "--TestName:" "test" -let OutputDir = getCmdLineArg "--OutputDir:" ("bin" ++ Flavour) -let CopyDlls = getCmdLineArg "--CopyDlls:" "" -let ExtraArgs = getCmdLineExtraArgs (fun x -> List.exists x.StartsWith ["--platform:";"--projectJsonLock:";"--packagesDir:";"--framework:";"--verbose:";"--compilerPath:";"--flavour:";"--TestName:";"--OutputDir:";"--CopyDlls:"]) - -let CompilerPath = defaultArg CompilerPathOpt (root ++ "tests" ++ "testbin" ++ Flavour ++ "coreclr" ++ "fsc") -let Win32Manifest = CompilerPath ++ "default.win32manifest" - -let isRepro = Verbosity = "repro" || Verbosity = "verbose" -let isVerbose = Verbosity = "verbose" - -let dependencies = CrackProjectJson.collectReferences (isVerbose, PackagesDir, FrameworkName + "/" + Platform, ProjectJsonLock, false, false) - -let runtimeConfigLines = - [| "{"; - " \"runtimeOptions\": {"; - " \"framework\": {"; - " \"name\": \"Microsoft.NETCore.App\","; - " \"version\": \"1.0.1\""; - " }"; - " }"; - "}" |] - -let executeCompiler references = - let Win32manifest=Path.Combine(CompilerPath, "default.win32manifest") - let addReferenceSwitch list = list |> Seq.map(fun i -> sprintf "-r:%s" i) - let arguments = - [ yield "--noframework" - yield "--simpleresolution" - yield "--targetprofile:netcore" - yield "--win32manifest:" + Win32Manifest - yield! addReferenceSwitch references - yield! ExtraArgs ] - - let coreRunExe = (root ++ "Tools" ++ "dotnetcli" ++ "dotnet.exe") - let fscExe = (CompilerPath ++ "fsc.exe") - let arguments2 = sprintf @"%s %s" fscExe (String.concat " " arguments) - if isVerbose then - log "%s %s" coreRunExe arguments2 - log "%s %s @fsc.cmd.args" coreRunExe fscExe - File.WriteAllLines(OutputDir ++ "fsc.cmd.args", arguments) - File.WriteAllLines(OutputDir ++ (TestName + ".runtimeconfig.json"), runtimeConfigLines) - CopyDlls.Split(';') |> Array.iter(fun s -> if not (System.String.IsNullOrWhiteSpace(s)) then File.Copy(s, OutputDir ++ Path.GetFileName(s), true)) - executeProcess coreRunExe arguments2 - -exit (executeCompiler dependencies) diff --git a/tests/scripts/fsci.fsx b/tests/scripts/fsci.fsx deleted file mode 100644 index a21acd1a73b..00000000000 --- a/tests/scripts/fsci.fsx +++ /dev/null @@ -1,65 +0,0 @@ -#load "../../src/scripts/scriptlib.fsx" -#load "crackProjectJson.fsx" - -open System -open System.IO -open System.Diagnostics - -let root = Path.GetFullPath (__SOURCE_DIRECTORY__ ++ ".." ++ "..") -// %USERPROFILE%/.nuget/packages -let defaultPackagesDir = - match System.Environment.GetEnvironmentVariable("USERPROFILE") with - | p -> p ++ @".nuget\packages" - | _ -> root ++ "packages" - -let Platform = getCmdLineArg "--platform:" "win7-x64" -let ProjectJsonLock = getCmdLineArg "--projectJsonLock:" (root ++ "tests" ++ "fsharp" ++ "FSharp.Tests.FSharpSuite.DrivingCoreCLR" ++ "project.lock.json") -let PackagesDir = getCmdLineArg "--packagesDir:" (root ++ "packages") -let FrameworkName = getCmdLineArg "--framework:" ".NETCoreApp,Version=v1.0" -let Verbosity = getCmdLineArg "--verbose:" "quiet" -let CompilerPathOpt = getCmdLineArgOptional "--compilerPath:" -let Flavour = getCmdLineArg "--flavour:" "release" -let TestName = getCmdLineArg "--TestName:" "test" -let OutputDir = getCmdLineArg "--OutputDir:" ("bin" ++ Flavour) -let CopyDlls = getCmdLineArg "--CopyDlls:" "" -let ExtraArgs = getCmdLineExtraArgs (fun x -> List.exists x.StartsWith ["--platform:";"--projectJsonLock:";"--packagesDir:";"--framework:";"--verbose:";"--compilerPath:";"--flavour:";"--TestName:";"--OutputDir:";"--CopyDlls:"]) - -let CompilerPath = defaultArg CompilerPathOpt (root ++ "tests" ++ "testbin" ++ Flavour ++ "coreclr" ++ "fsc") -let Win32Manifest = CompilerPath ++ "default.win32manifest" - -let isRepro = Verbosity = "repro" || Verbosity = "verbose" -let isVerbose = Verbosity = "verbose" - -let dependencies = CrackProjectJson.collectReferences (isVerbose, PackagesDir, FrameworkName + "/" + Platform, ProjectJsonLock, false, false) - -let runtimeConfigLines = - [| "{"; - " \"runtimeOptions\": {"; - " \"framework\": {"; - " \"name\": \"Microsoft.NETCore.App\","; - " \"version\": \"1.0.1\""; - " }"; - " }"; - "}" |] - -let executeFsi references = - let addReferenceSwitch list = list |> Seq.map(fun i -> sprintf "-r:%s" i) - let arguments = - [ yield "--noframework" - yield "--simpleresolution" - yield "--targetprofile:netcore" - yield! addReferenceSwitch references - yield! ExtraArgs ] - - let coreRunExe = (root ++ "Tools" ++ "dotnetcli" ++ "dotnet.exe") - let fsiExe = (CompilerPath ++ "fsi.exe") - let arguments2 = sprintf @"%s %s" fsiExe (String.concat " " arguments) - if isVerbose then - log "%s %s" coreRunExe arguments2 - log "%s %s @fsi.cmd.args" coreRunExe fsiExe - File.WriteAllLines(OutputDir ++ "fsi.cmd.args", arguments) - File.WriteAllLines(OutputDir ++ (TestName + ".runtimeconfig.json"), runtimeConfigLines) - CopyDlls.Split(';') |> Array.iter(fun s -> if not (System.String.IsNullOrWhiteSpace(s)) then File.Copy(s, OutputDir ++ Path.GetFileName(s), true)) - executeProcess coreRunExe arguments2 - -exit (executeFsi dependencies) diff --git a/tests/scripts/update-baselines.fsx b/tests/scripts/update-baselines.fsx index 389517a9c3e..06e9c13ef80 100644 --- a/tests/scripts/update-baselines.fsx +++ b/tests/scripts/update-baselines.fsx @@ -53,11 +53,11 @@ let fsdiff actualFile expectedFile = let directories = [ - "../fsharp/typecheck/sigs" - "../fsharp/typeProviders/negTests" - "../fsharpqa/Source" + "fsharp/typecheck/sigs" + "fsharp/typecheck/overloads" + "fsharpqa/Source" ] - |> List.map (fun d -> Path.Combine(__SOURCE_DIRECTORY__, d) |> DirectoryInfo) + |> List.map (fun d -> Path.Combine(__SOURCE_DIRECTORY__, ".." , d) |> DirectoryInfo) let extensionPatterns = ["*.bsl"; "*.vsbsl"; "*.il.bsl"] for d in directories do diff --git a/tests/service/AssemblyContentProviderTests.fs b/tests/service/AssemblyContentProviderTests.fs index 1a940aaf4c4..64759a07d1f 100644 --- a/tests/service/AssemblyContentProviderTests.fs +++ b/tests/service/AssemblyContentProviderTests.fs @@ -11,7 +11,9 @@ open System open System.IO open System.Text open NUnit.Framework -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Service.Tests.Common let private filePath = "C:\\test.fs" @@ -26,7 +28,6 @@ let private projectOptions : FSharpProjectOptions = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } let private checker = FSharpChecker.Create() @@ -34,16 +35,16 @@ let private checker = FSharpChecker.Create() let (=>) (source: string) (expected: string list) = let lines = use reader = new StringReader(source) - [| let line = ref (reader.ReadLine()) - while not (isNull !line) do - yield !line - line := reader.ReadLine() + [| let mutable line = reader.ReadLine() + while not (isNull line) do + yield line + line <- reader.ReadLine() if source.EndsWith "\n" then // last trailing space not returned // http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak yield "" |] - let _, checkFileAnswer = checker.ParseAndCheckFileInProject(filePath, 0, FSharp.Compiler.Text.SourceText.ofString source, projectOptions) |> Async.RunSynchronously + let _, checkFileAnswer = checker.ParseAndCheckFileInProject(filePath, 0, FSharp.Compiler.Text.SourceText.ofString source, projectOptions) |> Async.RunImmediate let checkFileResults = match checkFileAnswer with @@ -51,7 +52,7 @@ let (=>) (source: string) (expected: string list) = | FSharpCheckFileAnswer.Succeeded(checkFileResults) -> checkFileResults let actual = - AssemblyContentProvider.getAssemblySignatureContent AssemblyContentType.Full checkFileResults.PartialAssemblySignature + AssemblyContent.GetAssemblySignatureContent AssemblyContentType.Full checkFileResults.PartialAssemblySignature |> List.map (fun x -> x.CleanedIdents |> String.concat ".") |> List.sort @@ -73,7 +74,7 @@ module MyType = "Test.MyType.func123"] [] -let ``Module suffix added by an xplicitly applied MuduleSuffix attribute is removed``() = +let ``Module suffix added by an explicitly applied ModuleSuffix attribute is removed``() = """ [] module MyType = @@ -83,4 +84,12 @@ module MyType = "Test.MyType" "Test.MyType.func123" ] - +[] +let ``Property getters and setters are removed``() = + """ + type MyType() = + static member val MyProperty = 0 with get,set +""" + => [ "Test" + "Test.MyType" + "Test.MyType.MyProperty" ] diff --git a/tests/service/AssemblyReaderShim.fs b/tests/service/AssemblyReaderShim.fs index 71ad67809db..797005f46a8 100644 --- a/tests/service/AssemblyReaderShim.fs +++ b/tests/service/AssemblyReaderShim.fs @@ -8,12 +8,13 @@ module FSharp.Compiler.Service.Tests.AssemblyReaderShim #endif open FsUnit +open FSharp.Compiler.Text open FSharp.Compiler.AbstractIL.ILBinaryReader open NUnit.Framework [] let ``Assembly reader shim gets requests`` () = - let defaultReader = Shim.AssemblyReader + let defaultReader = AssemblyReader let mutable gotRequest = false let reader = { new IAssemblyReader with @@ -21,12 +22,12 @@ let ``Assembly reader shim gets requests`` () = gotRequest <- true defaultReader.GetILModuleReader(path, opts) } - Shim.AssemblyReader <- reader + AssemblyReader <- reader let source = """ module M let x = 123 """ - let fileName, options = Common.mkTestFileAndOptions source [| |] - Common.checker.ParseAndCheckFileInProject(fileName, 0, FSharp.Compiler.Text.SourceText.ofString source, options) |> Async.RunSynchronously |> ignore + let fileName, options = mkTestFileAndOptions source [| |] + checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString source, options) |> Async.RunImmediate |> ignore gotRequest |> should be True diff --git a/tests/service/CSharpProjectAnalysis.fs b/tests/service/CSharpProjectAnalysis.fs index 5c0d2474b94..72ebc1d7607 100644 --- a/tests/service/CSharpProjectAnalysis.fs +++ b/tests/service/CSharpProjectAnalysis.fs @@ -9,43 +9,45 @@ module FSharp.Compiler.Service.Tests.CSharpProjectAnalysis #endif - open NUnit.Framework open FsUnit open System.IO -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.IO open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open TestFramework -let internal getProjectReferences (content, dllFiles, libDirs, otherFlags) = +let internal getProjectReferences (content: string, dllFiles, libDirs, otherFlags) = let otherFlags = defaultArg otherFlags [] let libDirs = defaultArg libDirs [] - let base1 = Path.GetTempFileName() + let base1 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base1, ".dll") let fileName1 = Path.ChangeExtension(base1, ".fs") let projFileName = Path.ChangeExtension(base1, ".fsproj") - File.WriteAllText(fileName1, content) + FileSystem.OpenFileForWriteShim(fileName1).Write(content) let options = checker.GetProjectOptionsFromCommandLineArgs(projFileName, - [| yield "--debug:full" - yield "--define:DEBUG" - yield "--optimize-" + [| yield "--debug:full" + yield "--define:DEBUG" + yield "--optimize-" yield "--out:" + dllName - yield "--doc:test.xml" - yield "--warn:3" - yield "--fullpaths" - yield "--flaterrors" - yield "--target:library" + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" for dllFile in dllFiles do yield "-r:"+dllFile for libDir in libDirs do yield "-I:"+libDir yield! otherFlags yield fileName1 |]) - let results = checker.ParseAndCheckProject(options) |> Async.RunSynchronously + let results = checker.ParseAndCheckProject(options) |> Async.RunImmediate if results.HasCriticalErrors then - let builder = new System.Text.StringBuilder() - for err in results.Errors do - builder.AppendLine(sprintf "**** %s: %s" (if err.Severity = FSharpErrorSeverity.Error then "error" else "warning") err.Message) + let builder = System.Text.StringBuilder() + for err in results.Diagnostics do + builder.AppendLine(sprintf "**** %s: %s" (if err.Severity = FSharpDiagnosticSeverity.Error then "error" else "warning") err.Message) |> ignore failwith (builder.ToString()) let assemblies = @@ -58,16 +60,16 @@ let internal getProjectReferences (content, dllFiles, libDirs, otherFlags) = #if NETCOREAPP [] #endif -let ``Test that csharp references are recognized as such`` () = +let ``Test that csharp references are recognized as such`` () = let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" let _, table = getProjectReferences("""module M""", [csharpAssembly], None, None) let assembly = table.["CSharp_Analysis"] - let search = assembly.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") + let search = assembly.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") Assert.True search.IsSome let found = search.Value // this is no F# thing found.IsFSharp |> shouldEqual false - + // Check that we have members let members = found.MembersFunctionsAndValues |> Seq.map (fun e -> e.CompiledName, e) |> dict members.ContainsKey ".ctor" |> shouldEqual true @@ -86,6 +88,10 @@ let ``Test that csharp references are recognized as such`` () = //// Check that we get xml docs members.[".ctor"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.#ctor(System.Int32,System.String)" members.["Method"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.Method(System.String)" + members.["Method2"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.Method2(System.String)" + members.["Method3"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.Method3(System.String[])" + members.["MethodWithOutref"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.MethodWithOutref(System.Int32@)" + members.["MethodWithInref"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.MethodWithInref(System.Int32@)" members.["Property"].XmlDocSig |> shouldEqual "P:FSharp.Compiler.Service.Tests.CSharpClass.Property" members.["Event"].XmlDocSig |> shouldEqual "E:FSharp.Compiler.Service.Tests.CSharpClass.Event" members.["InterfaceMethod"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.InterfaceMethod(System.String)" @@ -96,7 +102,7 @@ let ``Test that csharp references are recognized as such`` () = #if NETCOREAPP [] #endif -let ``Test that symbols of csharp inner classes/enums are reported`` () = +let ``Test that symbols of csharp inner classes/enums are reported`` () = let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" let content = """ module NestedEnumClass @@ -108,9 +114,8 @@ let _ = CSharpOuterClass.InnerClass.StaticMember() let results, _ = getProjectReferences(content, [csharpAssembly], None, None) results.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously |> Array.map (fun su -> su.Symbol.ToString()) - |> shouldEqual + |> shouldEqual [|"FSharp"; "Compiler"; "Service"; "Tests"; "FSharp"; "InnerEnum"; "CSharpOuterClass"; "field Case1"; "InnerClass"; "CSharpOuterClass"; "member StaticMember"; "NestedEnumClass"|] @@ -130,10 +135,9 @@ let _ = CSharpClass(0) let results, _ = getProjectReferences(content, [csharpAssembly], None, None) let ctor = results.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously |> Seq.map (fun su -> su.Symbol) |> Seq.find (function :? FSharpMemberOrFunctionOrValue as mfv -> mfv.IsConstructor | _ -> false) - match (ctor :?> FSharpMemberOrFunctionOrValue).DeclaringEntity with + match (ctor :?> FSharpMemberOrFunctionOrValue).DeclaringEntity with | Some e -> let members = e.MembersFunctionsAndValues Seq.exists (fun (mfv : FSharpMemberOrFunctionOrValue) -> mfv.IsConstructor) members |> should be True @@ -144,7 +148,6 @@ let getEntitiesUses source = let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" let results, _ = getProjectReferences(source, [csharpAssembly], None, None) results.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously |> Seq.choose (fun su -> match su.Symbol with | :? FSharpEntity as entity -> Some entity diff --git a/tests/service/Common.fs b/tests/service/Common.fs index cd180a09003..770a8741197 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -1,16 +1,38 @@ +[] module internal FSharp.Compiler.Service.Tests.Common open System +open System.Diagnostics open System.IO open System.Collections.Generic -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open System.Threading.Tasks +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open TestFramework open FsUnit +open NUnit.Framework + +type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result #if NETCOREAPP let readRefs (folder : string) (projectFile: string) = let runProcess (workingDir: string) (exePath: string) (args: string) = - let psi = System.Diagnostics.ProcessStartInfo() + let psi = ProcessStartInfo() psi.FileName <- exePath psi.WorkingDirectory <- workingDir psi.RedirectStandardOutput <- false @@ -19,7 +41,7 @@ let readRefs (folder : string) (projectFile: string) = psi.CreateNoWindow <- true psi.UseShellExecute <- false - use p = new System.Diagnostics.Process() + use p = new Process() p.StartInfo <- psi p.Start() |> ignore p.WaitForExit() @@ -28,7 +50,7 @@ let readRefs (folder : string) (projectFile: string) = exitCode, () let projFilePath = Path.Combine(folder, projectFile) - let runCmd exePath args = runProcess folder exePath (args |> String.concat " ") + let runCmd exePath args = runProcess folder exePath ((args |> String.concat " ") + " -restore") let msbuildExec = Dotnet.ProjInfo.Inspect.dotnetMsbuild runCmd let result = Dotnet.ProjInfo.Inspect.getProjectInfo ignore msbuildExec Dotnet.ProjInfo.Inspect.getFscArgs [] projFilePath match result with @@ -43,47 +65,48 @@ let readRefs (folder : string) (projectFile: string) = // Create one global interactive checker instance let checker = FSharpChecker.Create() -type TempFile(ext, contents) = - let tmpFile = Path.ChangeExtension(System.IO.Path.GetTempFileName() , ext) - do File.WriteAllText(tmpFile, contents) - interface System.IDisposable with - member x.Dispose() = try File.Delete tmpFile with _ -> () +type TempFile(ext, contents: string) = + let tmpFile = Path.ChangeExtension(tryCreateTemporaryFileName (), ext) + do FileSystem.OpenFileForWriteShim(tmpFile).Write(contents) + + interface IDisposable with + member x.Dispose() = try FileSystem.FileDeleteShim tmpFile with _ -> () member x.Name = tmpFile #nowarn "57" -let getBackgroundParseResultsForScriptText (input) = +let getBackgroundParseResultsForScriptText (input: string) = use file = new TempFile("fsx", input) - let checkOptions, _diagnostics = checker.GetProjectOptionsFromScript(file.Name, FSharp.Compiler.Text.SourceText.ofString input) |> Async.RunSynchronously - checker.GetBackgroundParseResultsForFileInProject(file.Name, checkOptions) |> Async.RunSynchronously + let checkOptions, _diagnostics = checker.GetProjectOptionsFromScript(file.Name, SourceText.ofString input) |> Async.RunImmediate + checker.GetBackgroundParseResultsForFileInProject(file.Name, checkOptions) |> Async.RunImmediate -let getBackgroundCheckResultsForScriptText (input) = +let getBackgroundCheckResultsForScriptText (input: string) = use file = new TempFile("fsx", input) - let checkOptions, _diagnostics = checker.GetProjectOptionsFromScript(file.Name, FSharp.Compiler.Text.SourceText.ofString input) |> Async.RunSynchronously - checker.GetBackgroundCheckResultsForFileInProject(file.Name, checkOptions) |> Async.RunSynchronously + let checkOptions, _diagnostics = checker.GetProjectOptionsFromScript(file.Name, SourceText.ofString input) |> Async.RunImmediate + checker.GetBackgroundCheckResultsForFileInProject(file.Name, checkOptions) |> Async.RunImmediate -let sysLib nm = +let sysLib nm = #if !NETCOREAPP - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows + if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows let programFilesx86Folder = System.Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") programFilesx86Folder + @"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\" + nm + ".dll" else #endif - let sysDir = System.AppContext.BaseDirectory - let (++) a b = System.IO.Path.Combine(a,b) - sysDir ++ nm + ".dll" + let sysDir = AppContext.BaseDirectory + let (++) a b = Path.Combine(a,b) + sysDir ++ nm + ".dll" [] -module Helpers = +module Helpers = type DummyType = A | B - let PathRelativeToTestAssembly p = Path.Combine(Path.GetDirectoryName(Uri(typeof.Assembly.CodeBase).LocalPath), p) + let PathRelativeToTestAssembly p = Path.Combine(Path.GetDirectoryName(Uri(typeof.Assembly.Location).LocalPath), p) -let fsCoreDefaultReference() = +let fsCoreDefaultReference() = PathRelativeToTestAssembly "FSharp.Core.dll" -let mkStandardProjectReferences () = +let mkStandardProjectReferences () = #if NETCOREAPP let file = "Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj" let projDir = Path.Combine(__SOURCE_DIRECTORY__, "../projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0") @@ -92,26 +115,28 @@ let mkStandardProjectReferences () = [ yield sysLib "mscorlib" yield sysLib "System" yield sysLib "System.Core" + yield sysLib "System.Numerics" yield fsCoreDefaultReference() ] -#endif - -let mkProjectCommandLineArgsSilent (dllName, fileNames) = - let args = - [| yield "--simpleresolution" - yield "--noframework" - yield "--debug:full" - yield "--define:DEBUG" +#endif + +let mkProjectCommandLineArgsSilent (dllName, fileNames) = + let args = + [| yield "--simpleresolution" + yield "--noframework" + yield "--debug:full" + yield "--define:DEBUG" #if NETCOREAPP - yield "--targetprofile:netcore" + yield "--targetprofile:netcore" + yield "--langversion:preview" #endif - yield "--optimize-" + yield "--optimize-" yield "--out:" + dllName - yield "--doc:test.xml" - yield "--warn:3" - yield "--fullpaths" - yield "--flaterrors" - yield "--target:library" - for x in fileNames do + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + for x in fileNames do yield x let references = mkStandardProjectReferences () for r in references do @@ -119,26 +144,26 @@ let mkProjectCommandLineArgsSilent (dllName, fileNames) = |] args -let mkProjectCommandLineArgs (dllName, fileNames) = +let mkProjectCommandLineArgs (dllName, fileNames) = let args = mkProjectCommandLineArgsSilent (dllName, fileNames) printfn "dllName = %A, args = %A" dllName args args #if NETCOREAPP -let mkProjectCommandLineArgsForScript (dllName, fileNames) = - [| yield "--simpleresolution" - yield "--noframework" - yield "--debug:full" - yield "--define:DEBUG" - yield "--targetprofile:netcore" - yield "--optimize-" +let mkProjectCommandLineArgsForScript (dllName, fileNames) = + [| yield "--simpleresolution" + yield "--noframework" + yield "--debug:full" + yield "--define:DEBUG" + yield "--targetprofile:netcore" + yield "--optimize-" yield "--out:" + dllName - yield "--doc:test.xml" - yield "--warn:3" - yield "--fullpaths" - yield "--flaterrors" - yield "--target:library" - for x in fileNames do + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + for x in fileNames do yield x let references = mkStandardProjectReferences () for r in references do @@ -147,38 +172,50 @@ let mkProjectCommandLineArgsForScript (dllName, fileNames) = #endif let mkTestFileAndOptions source additionalArgs = - let fileName = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let project = Path.GetTempFileName() + let fileName = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let project = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(project, ".dll") let projFileName = Path.ChangeExtension(project, ".fsproj") let fileSource1 = "module M" - File.WriteAllText(fileName, fileSource1) + FileSystem.OpenFileForWriteShim(fileName).Write(fileSource1) let args = Array.append (mkProjectCommandLineArgs (dllName, [fileName])) additionalArgs let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) fileName, options let parseAndCheckFile fileName source options = - match checker.ParseAndCheckFileInProject(fileName, 0, FSharp.Compiler.Text.SourceText.ofString source, options) |> Async.RunSynchronously with + match checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString source, options) |> Async.RunImmediate with | parseResults, FSharpCheckFileAnswer.Succeeded(checkResults) -> parseResults, checkResults | _ -> failwithf "Parsing aborted unexpectedly..." -let parseAndCheckScript (file, input) = +let parseAndCheckScriptWithOptions (file:string, input, opts) = #if NETCOREAPP - let dllName = Path.ChangeExtension(file, ".dll") - let projName = Path.ChangeExtension(file, ".fsproj") - let args = mkProjectCommandLineArgsForScript (dllName, [file]) - printfn "file = %A, args = %A" file args - let projectOptions = checker.GetProjectOptionsFromCommandLineArgs (projName, args) - -#else - let projectOptions, _diagnostics = checker.GetProjectOptionsFromScript(file, FSharp.Compiler.Text.SourceText.ofString input) |> Async.RunSynchronously - printfn "projectOptions = %A" projectOptions + let projectOptions = + let path = Path.Combine(Path.GetTempPath(), "tests", Process.GetCurrentProcess().Id.ToString() + "--"+ Guid.NewGuid().ToString()) + try + if not (Directory.Exists(path)) then + Directory.CreateDirectory(path) |> ignore + + let fname = Path.Combine(path, Path.GetFileName(file)) + let dllName = Path.ChangeExtension(fname, ".dll") + let projName = Path.ChangeExtension(fname, ".fsproj") + let args = mkProjectCommandLineArgsForScript (dllName, [file]) + printfn "file = %A, args = %A" file args + checker.GetProjectOptionsFromCommandLineArgs (projName, args) + + finally + if Directory.Exists(path) then + Directory.Delete(path, true) + +#else + let projectOptions, _diagnostics = checker.GetProjectOptionsFromScript(file, SourceText.ofString input) |> Async.RunImmediate + //printfn "projectOptions = %A" projectOptions #endif - let parseResult, typedRes = checker.ParseAndCheckFileInProject(file, 0, FSharp.Compiler.Text.SourceText.ofString input, projectOptions) |> Async.RunSynchronously - + let projectOptions = { projectOptions with OtherOptions = Array.append opts projectOptions.OtherOptions } + let parseResult, typedRes = checker.ParseAndCheckFileInProject(file, 0, SourceText.ofString input, projectOptions) |> Async.RunImmediate + // if parseResult.Errors.Length > 0 then // printfn "---> Parse Input = %A" input // printfn "---> Parse Error = %A" parseResult.Errors @@ -187,40 +224,70 @@ let parseAndCheckScript (file, input) = | FSharpCheckFileAnswer.Succeeded(res) -> parseResult, res | res -> failwithf "Parsing did not finish... (%A)" res +let parseAndCheckScript (file, input) = parseAndCheckScriptWithOptions (file, input, [| |]) +let parseAndCheckScriptPreview (file, input) = parseAndCheckScriptWithOptions (file, input, [| "--langversion:preview" |]) + let parseSourceCode (name: string, code: string) = let location = Path.Combine(Path.GetTempPath(),"test"+string(hash (name, code))) try Directory.CreateDirectory(location) |> ignore with _ -> () - let filePath = Path.Combine(location, name + ".fs") + let filePath = Path.Combine(location, name) let dllPath = Path.Combine(location, name + ".dll") let args = mkProjectCommandLineArgs(dllPath, [filePath]) let options, errors = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) - let parseResults = checker.ParseFile(filePath, FSharp.Compiler.Text.SourceText.ofString code, options) |> Async.RunSynchronously + let parseResults = checker.ParseFile(filePath, SourceText.ofString code, options) |> Async.RunImmediate parseResults.ParseTree -open FSharp.Compiler.Ast +let matchBraces (name: string, code: string) = + let location = Path.Combine(Path.GetTempPath(),"test"+string(hash (name, code))) + try Directory.CreateDirectory(location) |> ignore with _ -> () + let filePath = Path.Combine(location, name + ".fs") + let dllPath = Path.Combine(location, name + ".dll") + let args = mkProjectCommandLineArgs(dllPath, [filePath]) + let options, errors = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) + let braces = checker.MatchBraces(filePath, SourceText.ofString code, options) |> Async.RunImmediate + braces -let parseSourceCodeAndGetModule (source: string) = - match parseSourceCode ("test", source) with - | Some (ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, [ moduleOrNamespace ], _))) -> moduleOrNamespace + +let getSingleModuleLikeDecl (input: ParsedInput) = + match input with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ decl ])) -> decl | _ -> failwith "Could not get module decls" -/// Extract range info -let tups (m:Range.range) = (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn) +let getSingleModuleMemberDecls (input: ParsedInput) = + let (SynModuleOrNamespace (decls = decls)) = getSingleModuleLikeDecl input + decls + +let getSingleDeclInModule (input: ParsedInput) = + match getSingleModuleMemberDecls input with + | [ decl ] -> decl + | _ -> failwith "Can't get single module member declaration" + +let getSingleExprInModule (input: ParsedInput) = + match getSingleDeclInModule input with + | SynModuleDecl.DoExpr (_, expr, _) -> expr + | _ -> failwith "Unexpected expression" + + +let parseSourceCodeAndGetModule (source: string) = + parseSourceCode ("test.fsx", source) |> getSingleModuleLikeDecl + +/// Extract range info +let tups (m: range) = (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn) /// Extract range info and convert to zero-based line - please don't use this one any more -let tupsZ (m:Range.range) = (m.StartLine-1, m.StartColumn), (m.EndLine-1, m.EndColumn) +let tupsZ (m: range) = (m.StartLine-1, m.StartColumn), (m.EndLine-1, m.EndColumn) -let attribsOfSymbolUse (s:FSharpSymbolUse) = - [ if s.IsFromDefinition then yield "defn" +let attribsOfSymbolUse (s:FSharpSymbolUse) = + [ if s.IsFromDefinition then yield "defn" if s.IsFromType then yield "type" if s.IsFromAttribute then yield "attribute" if s.IsFromDispatchSlotImplementation then yield "override" - if s.IsFromPattern then yield "pattern" - if s.IsFromComputationExpression then yield "compexpr" ] + if s.IsFromPattern then yield "pattern" + if s.IsFromComputationExpression then yield "compexpr" ] -let attribsOfSymbol (s:FSharpSymbol) = - [ match s with - | :? FSharpField as v -> +let attribsOfSymbol (s:FSharpSymbol) = + [ match s with + | :? FSharpField as v -> yield "field" if v.IsCompilerGenerated then yield "compgen" if v.IsDefaultValue then yield "default" @@ -228,12 +295,12 @@ let attribsOfSymbol (s:FSharpSymbol) = if v.IsVolatile then yield "volatile" if v.IsStatic then yield "static" if v.IsLiteral then yield sprintf "%A" v.LiteralValue.Value - if v.IsAnonRecordField then + if v.IsAnonRecordField then let info, tys, i = v.AnonRecordFieldDetails yield "anon(" + string i + ", [" + info.Assembly.QualifiedName + "/" + String.concat "+" info.EnclosingCompiledTypeNames + "/" + info.CompiledName + "]" + String.concat "," info.SortedFieldNames + ")" - | :? FSharpEntity as v -> + | :? FSharpEntity as v -> v.TryFullName |> ignore // check there is no failure here if v.IsNamespace then yield "namespace" if v.IsFSharpModule then yield "module" @@ -256,7 +323,7 @@ let attribsOfSymbol (s:FSharpSymbol) = if v.IsUnresolved then yield "unresolved" if v.IsValueType then yield "valuetype" - | :? FSharpMemberOrFunctionOrValue as v -> + | :? FSharpMemberOrFunctionOrValue as v -> if v.IsActivePattern then yield "apat" if v.IsDispatchSlot then yield "slot" if v.IsModuleValueOrMember && not v.IsMember then yield "val" @@ -272,7 +339,7 @@ let attribsOfSymbol (s:FSharpSymbol) = if v.IsTypeFunction then yield "typefun" if v.IsCompilerGenerated then yield "compgen" if v.IsImplicitConstructor then yield "ctor" - if v.IsMutable then yield "mutable" + if v.IsMutable then yield "mutable" if v.IsOverrideOrExplicitInterfaceImplementation then yield "overridemem" if v.IsInstanceMember && not v.IsInstanceMemberInCompiledCode && not v.IsExtensionMember then yield "funky" if v.IsExplicitInterfaceImplementation then yield "intfmem" @@ -281,39 +348,60 @@ let attribsOfSymbol (s:FSharpSymbol) = // if v.LiteralValue.IsSome then yield "literal" | _ -> () ] -let rec allSymbolsInEntities compGen (entities: IList) = - [ for e in entities do - yield (e :> FSharpSymbol) - for gp in e.GenericParameters do - if compGen || not gp.IsCompilerGenerated then +let rec allSymbolsInEntities compGen (entities: IList) = + [ for e in entities do + yield (e :> FSharpSymbol) + for gp in e.GenericParameters do + if compGen || not gp.IsCompilerGenerated then yield (gp :> FSharpSymbol) for x in e.MembersFunctionsAndValues do - if compGen || not x.IsCompilerGenerated then + if compGen || not x.IsCompilerGenerated then yield (x :> FSharpSymbol) - for gp in x.GenericParameters do - if compGen || not gp.IsCompilerGenerated then + for gp in x.GenericParameters do + if compGen || not gp.IsCompilerGenerated then yield (gp :> FSharpSymbol) for x in e.UnionCases do yield (x :> FSharpSymbol) - for f in x.UnionCaseFields do - if compGen || not f.IsCompilerGenerated then + for f in x.Fields do + if compGen || not f.IsCompilerGenerated then yield (f :> FSharpSymbol) for x in e.FSharpFields do - if compGen || not x.IsCompilerGenerated then + if compGen || not x.IsCompilerGenerated then yield (x :> FSharpSymbol) yield! allSymbolsInEntities compGen e.NestedEntities ] +let getParseResults (source: string) = + parseSourceCode("/home/user/Test.fsx", source) + +let getParseResultsOfSignatureFile (source: string) = + parseSourceCode("/home/user/Test.fsi", source) + let getParseAndCheckResults (source: string) = - parseAndCheckScript("/home/user/Test.fsx", source) + parseAndCheckScript("/home/user/Test.fsx", source) + +let getParseAndCheckResultsPreview (source: string) = + parseAndCheckScriptPreview("/home/user/Test.fsx", source) + +let inline dumpErrors results = + (^TResults: (member Diagnostics: FSharpDiagnostic[]) results) + |> Array.map (fun e -> + let message = + e.Message.Split('\n') + |> Array.map (fun s -> s.Trim()) + |> String.concat " " + sprintf "%s: %s" (e.Range.ToShortString()) message) + |> List.ofArray -let getSymbolUses (source: string) = - let _, typeCheckResults = parseAndCheckScript("/home/user/Test.fsx", source) - typeCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously +let getSymbolUses (results: FSharpCheckFileResults) = + results.GetAllUsesOfAllSymbolsInFile() -let getSymbols (source: string) = - getSymbolUses source - |> Array.map (fun symbolUse -> symbolUse.Symbol) +let getSymbolUsesFromSource (source: string) = + let _, typeCheckResults = getParseAndCheckResults source + typeCheckResults.GetAllUsesOfAllSymbolsInFile() + +let getSymbols (symbolUses: seq) = + symbolUses |> Seq.map (fun symbolUse -> symbolUse.Symbol) let getSymbolName (symbol: FSharpSymbol) = @@ -330,10 +418,47 @@ let getSymbolName (symbol: FSharpSymbol) = let assertContainsSymbolWithName name source = getSymbols source - |> Array.choose getSymbolName - |> Array.contains name + |> Seq.choose getSymbolName + |> Seq.contains name |> shouldEqual true +let assertContainsSymbolsWithNames (names: string list) source = + let symbolNames = + getSymbols source + |> Seq.choose getSymbolName + + for name in names do + symbolNames + |> Seq.contains name + |> shouldEqual true + +let assertHasSymbolUsages (names: string list) (results: FSharpCheckFileResults) = + let symbolNames = + getSymbolUses results + |> getSymbols + |> Seq.choose getSymbolName + |> set + + for name in names do + Assert.That(Set.contains name symbolNames, name) + + +let findSymbolUseByName (name: string) (results: FSharpCheckFileResults) = + getSymbolUses results + |> Seq.find (fun symbolUse -> + match getSymbolName symbolUse.Symbol with + | Some symbolName -> symbolName = name + | _ -> false) + +let findSymbolByName (name: string) (results: FSharpCheckFileResults) = + let symbolUse = findSymbolUseByName name results + symbolUse.Symbol + +let taggedTextToString (tts: TaggedText[]) = + tts |> Array.map (fun tt -> tt.Text) |> String.concat "" + +let getRangeCoords (r: range) = + (r.StartLine, r.StartColumn), (r.EndLine, r.EndColumn) let coreLibAssemblyName = #if NETCOREAPP @@ -342,3 +467,10 @@ let coreLibAssemblyName = "mscorlib" #endif +let assertRange + (expectedStartLine: int, expectedStartColumn: int) + (expectedEndLine: int, expectedEndColumn: int) + (actualRange: range) + : unit = + Assert.AreEqual(Position.mkPos expectedStartLine expectedStartColumn, actualRange.Start) + Assert.AreEqual(Position.mkPos expectedEndLine expectedEndColumn, actualRange.End) diff --git a/tests/service/EditorTests.fs b/tests/service/EditorTests.fs index 9ed74c96f20..3a5ad1277b7 100644 --- a/tests/service/EditorTests.fs +++ b/tests/service/EditorTests.fs @@ -5,17 +5,17 @@ // // Technique 2: // -// Enable some tests in the #if EXE section at the end of the file, +// Enable some tests in the #if EXE section at the end of the file, // then compile this file as an EXE that has InternalsVisibleTo access into the // appropriate DLLs. This can be the quickest way to get turnaround on updating the tests // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.LanguageService.Compiler.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\tests\service\EditorTests.fs - .\VisualFSharp.UnitTests.exe + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.LanguageService.Compiler.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\tests\service\EditorTests.fs + .\VisualFSharp.UnitTests.exe *) -// Technique 3: -// +// Technique 3: +// // Use F# Interactive. This only works for FSHarp.Compiler.Service.dll which has a public API #if INTERACTIVE @@ -29,12 +29,14 @@ module Tests.Service.Editor open NUnit.Framework open FsUnit -open System -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization -let stringMethods = +let stringMethods = ["Chars"; "Clone"; "CompareTo"; "Contains"; "CopyTo"; "EndsWith"; "Equals"; "GetEnumerator"; "GetHashCode"; "GetReverseIndex"; "GetType"; "GetTypeCode"; "IndexOf"; "IndexOfAny"; "Insert"; "IsNormalized"; "LastIndexOf"; "LastIndexOfAny"; @@ -42,13 +44,13 @@ let stringMethods = "StartsWith"; "Substring"; "ToCharArray"; "ToLower"; "ToLowerInvariant"; "ToString"; "ToUpper"; "ToUpperInvariant"; "Trim"; "TrimEnd"; "TrimStart"] -let input = +let input = """ open System - - let foo() = + + let foo() = let msg = String.Concat("Hello"," ","world") - if true then + if true then printfn "%s" msg. """ @@ -56,46 +58,46 @@ let input = #if COMPILED [] #endif -let ``Intro test`` () = +let ``Intro test`` () = // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) let identToken = FSharpTokenTag.IDENT -// let projectOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously +// let projectOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunImmediate // So we check that the messages are the same - for msg in typeCheckResults.Errors do + for msg in typeCheckResults.Diagnostics do printfn "Got an error, hopefully with the right text: %A" msg - printfn "typeCheckResults.Errors.Length = %d" typeCheckResults.Errors.Length + printfn "typeCheckResults.Diagnostics.Length = %d" typeCheckResults.Diagnostics.Length // We only expect one reported error. However, // on Unix, using filenames like /home/user/Test.fsx gives a second copy of all parse errors due to the // way the load closure for scripts is generated. So this returns two identical errors - (match typeCheckResults.Errors.Length with 1 | 2 -> true | _ -> false) |> shouldEqual true + (match typeCheckResults.Diagnostics.Length with 1 | 2 -> true | _ -> false) |> shouldEqual true // So we check that the messages are the same - for msg in typeCheckResults.Errors do + for msg in typeCheckResults.Diagnostics do printfn "Good! got an error, hopefully with the right text: %A" msg msg.Message.Contains("Missing qualification after '.'") |> shouldEqual true // Get tool tip at the specified location - let tip = typeCheckResults.GetToolTipText(4, 7, inputLines.[1], ["foo"], identToken) |> Async.RunSynchronously - // (sprintf "%A" tip).Replace("\n","") |> shouldEqual """FSharpToolTipText [Single ("val foo : unit -> unitFull name: Test.foo",None)]""" + let tip = typeCheckResults.GetToolTip(4, 7, inputLines.[1], ["foo"], identToken) + // (sprintf "%A" tip).Replace("\n","") |> shouldEqual """ToolTipText [Single ("val foo: unit -> unitFull name: Test.foo",None)]""" // Get declarations (autocomplete) for a location let partialName = { QualifyingIdents = []; PartialIdent = "msg"; EndColumn = 22; LastDotPos = None } - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines.[6], partialName, (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines.[6], partialName, (fun _ -> [])) CollectionAssert.AreEquivalent(stringMethods,[ for item in decls.Items -> item.Name ]) // Get overloads of the String.Concat method - let methods = typeCheckResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) |> Async.RunSynchronously + let methods = typeCheckResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) methods.MethodName |> shouldEqual "Concat" // Print concatenated parameter lists [ for mi in methods.Methods do - yield methods.MethodName , [ for p in mi.Parameters do yield p.Display ] ] + yield methods.MethodName , [ for p in mi.Parameters do yield p.Display |> taggedTextToString ] ] |> shouldEqual [("Concat", ["[] args: obj []"]); ("Concat", ["[] values: string []"]); @@ -107,48 +109,26 @@ let ``Intro test`` () = ("Concat", ["str0: string"; "str1: string"; "str2: string"]); #if !NETCOREAPP // TODO: check why this is needed for .NET Core testing of FSharp.Compiler.Service ("Concat", ["arg0: obj"; "arg1: obj"; "arg2: obj"; "arg3: obj"]); -#endif +#endif ("Concat", ["str0: string"; "str1: string"; "str2: string"; "str3: string"])] -// TODO: check if this can be enabled in .NET Core testing of FSharp.Compiler.Service -#if !INTERACTIVE && !NETCOREAPP // InternalsVisibleTo on IncrementalBuild.LocallyInjectCancellationFault not working for some reason? -[] -let ``Basic cancellation test`` () = - try - printfn "locally injecting a cancellation condition in incremental building" - use _holder = IncrementalBuild.LocallyInjectCancellationFault() - - // Split the input & define file name - let inputLines = input.Split('\n') - let file = "/home/user/Test.fsx" - async { - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - let! checkOptions, _diagnostics = checker.GetProjectOptionsFromScript(file, FSharp.Compiler.Text.SourceText.ofString input) - let! parseResult, typedRes = checker.ParseAndCheckFileInProject(file, 0, FSharp.Compiler.Text.SourceText.ofString input, checkOptions) - return parseResult, typedRes - } |> Async.RunSynchronously - |> ignore - Assert.Fail("expected a cancellation") - with :? OperationCanceledException -> () -#endif - [] let ``GetMethodsAsSymbols should return all overloads of a method as FSharpSymbolUse`` () = let extractCurriedParams (symbol:FSharpSymbolUse) = match symbol.Symbol with | :? FSharpMemberOrFunctionOrValue as mvf -> - [for pg in mvf.CurriedParameterGroups do - for (p:FSharpParameter) in pg do - yield p.DisplayName, p.Type.Format (symbol.DisplayContext)] + [for pg in mvf.CurriedParameterGroups do + for p:FSharpParameter in pg do + yield p.DisplayName, p.Type.Format symbol.DisplayContext] | _ -> [] // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let methodsSymbols = typeCheckResults.GetMethodsAsSymbols(5, 27, inputLines.[4], ["String"; "Concat"]) |> Async.RunSynchronously + let methodsSymbols = typeCheckResults.GetMethodsAsSymbols(5, 27, inputLines.[4], ["String"; "Concat"]) match methodsSymbols with | Some methods -> [ for ms in methods do @@ -158,8 +138,8 @@ let ``GetMethodsAsSymbols should return all overloads of a method as FSharpSymbo [("Concat", [("values", "Collections.Generic.IEnumerable<'T>")]); ("Concat", [("values", "Collections.Generic.IEnumerable")]); ("Concat", [("arg0", "obj")]); - ("Concat", [("args", "obj []")]); - ("Concat", [("values", "string []")]); + ("Concat", [("args", "obj[]")]); + ("Concat", [("values", "string[]")]); ("Concat", [("arg0", "obj"); ("arg1", "obj")]); ("Concat", [("str0", "string"); ("str1", "string")]); ("Concat", [("arg0", "obj"); ("arg1", "obj"); ("arg2", "obj")]); @@ -171,37 +151,37 @@ let ``GetMethodsAsSymbols should return all overloads of a method as FSharpSymbo | None -> failwith "No symbols returned" -let input2 = +let input2 = """ [] -let foo(x, y) = +let foo(x, y) = let msg = String.Concat("Hello"," ","world") - if true then - printfn "x = %d, y = %d" x y + if true then + printfn "x = %d, y = %d" x y printfn "%s" msg -type C() = +type C() = member x.P = 1 """ [] -let ``Symbols basic test`` () = +let ``Symbols basic test`` () = let file = "/home/user/Test.fsx" let untyped2, typeCheckResults2 = parseAndCheckScript(file, input2) let partialAssemblySignature = typeCheckResults2.PartialAssemblySignature - + partialAssemblySignature.Entities.Count |> shouldEqual 1 // one entity [] -let ``Symbols many tests`` () = +let ``Symbols many tests`` () = let file = "/home/user/Test.fsx" let untyped2, typeCheckResults2 = parseAndCheckScript(file, input2) let partialAssemblySignature = typeCheckResults2.PartialAssemblySignature - + partialAssemblySignature.Entities.Count |> shouldEqual 1 // one entity let moduleEntity = partialAssemblySignature.Entities.[0] @@ -239,7 +219,7 @@ let ``Symbols many tests`` () = fnVal.IsTypeFunction |> shouldEqual false fnVal.FullType.IsFunctionType |> shouldEqual true // int * int -> unit - fnVal.FullType.GenericArguments.[0].IsTupleType |> shouldEqual true // int * int + fnVal.FullType.GenericArguments.[0].IsTupleType |> shouldEqual true // int * int let argTy1 = fnVal.FullType.GenericArguments.[0].GenericArguments.[0] argTy1.TypeDefinition.DisplayName |> shouldEqual "int" // int @@ -249,129 +229,126 @@ let ``Symbols many tests`` () = let argTy1b = argTy1.TypeDefinition.AbbreviatedType argTy1b.TypeDefinition.Namespace |> shouldEqual (Some "Microsoft.FSharp.Core") - argTy1b.TypeDefinition.CompiledName |> shouldEqual "int32" + argTy1b.TypeDefinition.CompiledName |> shouldEqual "int32" let argTy1c = argTy1b.TypeDefinition.AbbreviatedType argTy1c.TypeDefinition.Namespace |> shouldEqual (Some "System") - argTy1c.TypeDefinition.CompiledName |> shouldEqual "Int32" + argTy1c.TypeDefinition.CompiledName |> shouldEqual "Int32" let typeCheckContext = typeCheckResults2.ProjectContext - + typeCheckContext.GetReferencedAssemblies() |> List.exists (fun s -> s.FileName.Value.Contains(coreLibAssemblyName)) |> shouldEqual true - -let input3 = + +let input3 = """ let date = System.DateTime.Now.ToString().PadRight(25) """ [] -#if COMPILED -[] -#endif -let ``Expression typing test`` () = +let ``Expression typing test`` () = printfn "------ Expression typing test -----------------" // Split the input & define file name let inputLines = input3.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input3) + let parseResult, typeCheckResults = parseAndCheckScript(file, input3) let identToken = FSharpTokenTag.IDENT - for msg in typeCheckResults.Errors do + for msg in typeCheckResults.Diagnostics do printfn "***Expression typing test: Unexpected error: %A" msg.Message - typeCheckResults.Errors.Length |> shouldEqual 0 + typeCheckResults.Diagnostics.Length |> shouldEqual 0 // Get declarations (autocomplete) for a location // - // Getting the declarations at columns 42 to 43 with [], "" for the names and residue - // gives the results for the string type. - // - for col in 42..43 do - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 2, inputLines.[1], PartialLongName.Empty(col), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + // Getting the declarations at columns 42 to 43 with [], "" for the names and residue + // gives the results for the string type. + // + for col in 42..43 do + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 2, inputLines.[1], PartialLongName.Empty(col), (fun _ -> [])) let autoCompleteSet = set [ for item in decls.Items -> item.Name ] autoCompleteSet |> shouldEqual (set stringMethods) // The underlying problem is that the parser error recovery doesn't include _any_ information for // the incomplete member: -// member x.Test = +// member x.Test = [] -let ``Find function from member 1`` () = - let input = +let ``Find function from member 1`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - member x.Test = """ + member x.Test = """ // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), (fun _ -> [])) let item = decls.Items |> Array.tryFind (fun d -> d.Name = "abc") decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true [] -let ``Find function from member 2`` () = - let input = +let ``Find function from member 2`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - member x.Test = a""" + member x.Test = a""" // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), (fun _ -> [])) let item = decls.Items |> Array.tryFind (fun d -> d.Name = "abc") decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true - + [] -let ``Find function from var`` () = - let input = +let ``Find function from var`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - let test = """ + let test = """ // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), (fun _ -> [])) decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true [] -let ``Completion in base constructor`` () = - let input = +let ``Completion in base constructor`` () = + let input = """ type A(foo) = class end type B(bar) = - inherit A(bar)""" + inherit A(bar)""" // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines.[6], PartialLongName.Empty(17), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines.[6], PartialLongName.Empty(17), (fun _ -> [])) decls.Items |> Seq.exists (fun d -> d.Name = "bar") |> shouldEqual true [] -let ``Completion in do in base constructor`` () = - let input = +let ``Completion in do in base constructor`` () = + let input = """ type A() = class @@ -379,72 +356,72 @@ type A() = type B(bar) = inherit A() - - do bar""" + + do bar""" // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 9, inputLines.[8], PartialLongName.Empty(7), (fun _ -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 9, inputLines.[8], PartialLongName.Empty(7), (fun _ -> [])) decls.Items |> Seq.exists (fun d -> d.Name = "bar") |> shouldEqual true [] -let ``Symbol based find function from member 1`` () = - let input = +let ``Symbol based find function from member 1`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - member x.Test = """ + member x.Test = """ // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), (fun () -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), (fun () -> [])) //decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A" decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true [] -let ``Symbol based find function from member 2`` () = - let input = +let ``Symbol based find function from member 2`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - member x.Test = a""" + member x.Test = a""" // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), (fun () -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), (fun () -> [])) //decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A" decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true [] -let ``Symbol based find function from var`` () = - let input = +let ``Symbol based find function from var`` () = + let input = """ -type Test() = +type Test() = let abc a b c = a + b + c - let test = """ + let test = """ // Split the input & define file name let inputLines = input.Split('\n') let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), (fun () -> []), fun _ -> false)|> Async.RunSynchronously + let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), (fun () -> [])) //decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A" decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true [] -let ``Printf specifiers for regular and verbatim strings`` () = - let input = +let ``Printf specifiers for regular and verbatim strings`` () = + let input = """let os = System.Text.StringBuilder() let _ = Microsoft.FSharp.Core.Printf.printf "%A" 0 let _ = Printf.printf "%A" 0 @@ -465,7 +442,7 @@ let _ = List.map (sprintf @"%A let _ = (10, 12) ||> sprintf "%A %O" let _ = sprintf "\n%-8.1e+567" 1.0 -let _ = sprintf @"%O\n%-5s" "1" "2" +let _ = sprintf @"%O\n%-5s" "1" "2" let _ = sprintf "%%" let _ = sprintf " %*%" 2 let _ = sprintf " %.*%" 2 @@ -482,10 +459,10 @@ let _ = printf " %*a" 3 (fun _ _ -> ()) 2 """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - typeCheckResults.Errors |> shouldEqual [||] - typeCheckResults.GetFormatSpecifierLocationsAndArity() + typeCheckResults.Diagnostics |> shouldEqual [||] + typeCheckResults.GetFormatSpecifierLocationsAndArity() |> Array.map (fun (range,numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) |> shouldEqual [|(2, 45, 2, 47, 1); (3, 23, 3, 25, 1); (4, 38, 4, 40, 1); (5, 27, 5, 29, 1); @@ -500,8 +477,8 @@ let _ = printf " %*a" 3 (fun _ _ -> ()) 2 (34, 29, 34, 32, 3)|] [] -let ``Printf specifiers for triple-quote strings`` () = - let input = +let ``Printf specifiers for triple-quote strings`` () = + let input = " let _ = sprintf \"\"\"%-A\"\"\" -10 let _ = printfn \"\"\" @@ -512,20 +489,20 @@ let _ = List.iter(printfn \"\"\"%-A \"\"\" 1 2)" let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - typeCheckResults.Errors |> shouldEqual [||] - typeCheckResults.GetFormatSpecifierLocationsAndArity() + typeCheckResults.Diagnostics |> shouldEqual [||] + typeCheckResults.GetFormatSpecifierLocationsAndArity() |> Array.map (fun (range,numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) |> shouldEqual [|(2, 19, 2, 22, 1); (4, 12, 4, 15, 1); (6, 29, 6, 32, 1); - (7, 29, 7, 31, 1); + (7, 29, 7, 31, 1); (7, 33, 7, 35,1 )|] - + [] -let ``Printf specifiers for user-defined functions`` () = - let input = +let ``Printf specifiers for user-defined functions`` () = + let input = """ let debug msg = Printf.kprintf System.Diagnostics.Debug.WriteLine msg let _ = debug "Message: %i - %O" 1 "Ok" @@ -533,51 +510,107 @@ let _ = debug "[LanguageService] Type checking fails for '%s' with content=%A an """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) - typeCheckResults.Errors |> shouldEqual [||] - typeCheckResults.GetFormatSpecifierLocationsAndArity() + typeCheckResults.Diagnostics |> shouldEqual [||] + typeCheckResults.GetFormatSpecifierLocationsAndArity() |> Array.map (fun (range, numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) - |> shouldEqual [|(3, 24, 3, 26, 1); + |> shouldEqual [|(3, 24, 3, 26, 1); (3, 29, 3, 31, 1); - (4, 58, 4, 60, 1); - (4, 75, 4, 77, 1); - (4, 82, 4, 84, 1); + (4, 58, 4, 60, 1); + (4, 75, 4, 77, 1); + (4, 82, 4, 84, 1); (4, 108, 4, 110, 1)|] +#if ASSUME_PREVIEW_FSHARP_CORE [] -let ``should not report format specifiers for illformed format strings`` () = - let input = +let ``Printf specifiers for regular and verbatim interpolated strings`` () = + let input = + """let os = System.Text.StringBuilder() // line 1 +let _ = $"{0}" // line 2 +let _ = $"%A{0}" // line 3 +let _ = $"%7.1f{1.0}" // line 4 +let _ = $"%-8.1e{1.0}+567" // line 5 +let s = "value" // line 6 +let _ = $@"%-5s{s}" // line 7 +let _ = $@"%-A{-10}" // line 8 +let _ = @$" + %-O{-10}" // line 10 +let _ = $" + + %-O{-10}" // line 13 +let _ = List.map (fun x -> sprintf $@"%A{x} + ") // line 15 +let _ = $"\n%-8.1e{1.0}+567" // line 16 +let _ = $@"%O{1}\n%-5s{s}" // line 17 +let _ = $"%%" // line 18 +let s2 = $"abc %d{s.Length} and %d{s.Length}def" // line 19 +let s3 = $"abc %d{s.Length} + and %d{s.Length}def" // line 21 +""" + + let file = "/home/user/Test.fsx" + let parseResult, typeCheckResults = parseAndCheckScriptWithOptions(file, input, [| "/langversion:preview" |]) + + typeCheckResults.Diagnostics |> shouldEqual [||] + typeCheckResults.GetFormatSpecifierLocationsAndArity() + |> Array.map (fun (range,numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) + |> shouldEqual + [|(3, 10, 3, 12, 1); (4, 10, 4, 15, 1); (5, 10, 5, 16, 1); (7, 11, 7, 15, 1); + (8, 11, 8, 14, 1); (10, 12, 10, 15, 1); (13, 12, 13, 15, 1); + (14, 38, 14, 40, 1); (16, 12, 16, 18, 1); (17, 11, 17, 13, 1); + (17, 18, 17, 22, 1); (18, 10, 18, 12, 0); (19, 15, 19, 17, 1); + (19, 32, 19, 34, 1); (20, 15, 20, 17, 1); (21, 20, 21, 22, 1)|] + +[] +let ``Printf specifiers for triple quote interpolated strings`` () = + let input = + "let _ = $\"\"\"abc %d{1} and %d{2+3}def\"\"\" " + + let file = "/home/user/Test.fsx" + let parseResult, typeCheckResults = parseAndCheckScriptWithOptions(file, input, [| "/langversion:preview" |]) + + typeCheckResults.Diagnostics |> shouldEqual [||] + typeCheckResults.GetFormatSpecifierLocationsAndArity() + |> Array.map (fun (range,numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) + |> shouldEqual + [|(1, 16, 1, 18, 1); (1, 26, 1, 28, 1)|] +#endif // ASSUME_PREVIEW_FSHARP_CORE + + +[] +let ``should not report format specifiers for illformed format strings`` () = + let input = """ let _ = sprintf "%.7f %7.1A %7.f %--8.1f" let _ = sprintf "ABCDE" """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) - typeCheckResults.GetFormatSpecifierLocationsAndArity() + let parseResult, typeCheckResults = parseAndCheckScript(file, input) + typeCheckResults.GetFormatSpecifierLocationsAndArity() |> Array.map (fun (range, numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) |> shouldEqual [||] [] -let ``Single case discreminated union type definition`` () = - let input = +let ``Single case discreminated union type definition`` () = + let input = """ type DU = Case1 """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range r.StartLine, r.StartColumn, r.EndLine, r.EndColumn) |> shouldEqual [|(2, 10, 2, 15); (2, 5, 2, 7); (1, 0, 1, 0)|] [] -let ``Synthetic symbols should not be reported`` () = - let input = +let ``Synthetic symbols should not be reported`` () = + let input = """ let arr = [|1|] let number1, number2 = 1, 2 @@ -586,29 +619,19 @@ let _ = arr.[..number2] """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) - |> shouldEqual + |> shouldEqual [|("val arr", (2, 4, 2, 7)) ("val number2", (3, 13, 3, 20)) ("val number1", (3, 4, 3, 11)) ("val arr", (4, 8, 4, 11)) - ("Microsoft", (4, 11, 4, 12)) - ("OperatorIntrinsics", (4, 11, 4, 12)) - ("Operators", (4, 11, 4, 12)) - ("Core", (4, 11, 4, 12)) - ("FSharp", (4, 11, 4, 12)) ("val number1", (4, 16, 4, 23)) ("val arr", (5, 8, 5, 11)) - ("Microsoft", (5, 11, 5, 12)) - ("OperatorIntrinsics", (5, 11, 5, 12)) - ("Operators", (5, 11, 5, 12)) - ("Core", (5, 11, 5, 12)) - ("FSharp", (5, 11, 5, 12)) ("val number2", (5, 15, 5, 22)) ("Test", (1, 0, 1, 0))|] @@ -621,10 +644,11 @@ let test2 = System.StringComparison.CurrentCulture let test3 = System.Text.RegularExpressions.RegexOptions.Compiled """ let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) - let allSymbols = typeCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously + let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let allSymbols = typeCheckResults.GetAllUsesOfAllSymbolsInFile() let enums = allSymbols + |> Array.ofSeq |> Array.choose(fun s -> match s.Symbol with :? FSharpEntity as e when e.IsEnum -> Some e | _ -> None) |> Array.distinct |> Array.map(fun e -> (e.DisplayName, e.FSharpFields @@ -661,8 +685,8 @@ let test3 = System.Text.RegularExpressions.RegexOptions.Compiled |] [] -let ``IL enum fields should be reported`` () = - let input = +let ``IL enum fields should be reported`` () = + let input = """ open System @@ -673,29 +697,29 @@ let _ = """ let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, input) + let _, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) |> Array.distinct - |> shouldEqual + |> shouldEqual // note: these "System" sysbol uses are not duplications because each of them corresponts to different namespaces [|("System", (2, 5, 2, 11)) ("ConsoleKey", (5, 10, 5, 20)); - ("field Tab", (5, 10, 5, 24)); + ("field Tab", (5, 10, 5, 24)); ("ConsoleKey", (6, 6, 6, 16)); - ("field OemClear", (6, 6, 6, 25)); + ("field OemClear", (6, 6, 6, 25)); ("ConsoleKey", (6, 29, 6, 39)); - ("field A", (6, 29, 6, 41)); + ("field A", (6, 29, 6, 41)); ("ConsoleKey", (7, 11, 7, 21)); - ("field B", (7, 11, 7, 23)); + ("field B", (7, 11, 7, 23)); ("Test", (1, 0, 1, 0))|] [] -let ``Literal values should be reported`` () = - let input = +let ``Literal values should be reported`` () = + let input = """ module Module1 = let [] ModuleValue = 1 @@ -708,7 +732,7 @@ module Module1 = type Class1() = let [] ClassValue = 1 static let [] StaticClassValue = 2 - + let _ = ClassValue let _ = StaticClassValue @@ -720,13 +744,13 @@ type Class1() = """ let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, input) + let _, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) - |> shouldEqual + |> shouldEqual [|("LiteralAttribute", (3, 10, 3, 17)) ("LiteralAttribute", (3, 10, 3, 17)) ("member .ctor", (3, 10, 3, 17)) @@ -762,26 +786,26 @@ type Class1() = ("Test", (1, 0, 1, 0))|] [] -let ``IsConstructor property should return true for constructors`` () = - let input = +let ``IsConstructor property should return true for constructors`` () = + let input = """ type T(x: int) = new() = T(0) let x: T() """ let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, input) + let _, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range let isConstructor = match su.Symbol with | :? FSharpMemberOrFunctionOrValue as f -> f.IsConstructor | _ -> false su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn), isConstructor) |> Array.distinct - |> shouldEqual + |> shouldEqual [|("T", (2, 5, 2, 6), false) ("int", (2, 10, 2, 13), false) ("val x", (2, 7, 2, 8), false) @@ -793,22 +817,22 @@ let x: T() ("Test", (1, 0, 1, 0), false)|] [] -let ``ValidateBreakpointLocation tests A`` () = - let input = +let ``ValidateBreakpointLocation tests A`` () = + let input = """ -let f x = +let f x = let y = z + 1 y + y )""" let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) let lines = input.Replace("\r", "").Split( [| '\n' |]) - let positions = [ for (i,line) in Seq.indexed lines do for (j, c) in Seq.indexed line do yield Range.mkPos (Range.Line.fromZ i) j, line ] - let results = [ for pos, line in positions do - match parseResult.ValidateBreakpointLocation pos with - | Some r -> yield ((line, pos.Line, pos.Column), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) + let positions = [ for i,line in Seq.indexed lines do for j, c in Seq.indexed line do yield Position.mkPos (Line.fromZ i) j, line ] + let results = [ for pos, line in positions do + match parseResult.ValidateBreakpointLocation pos with + | Some r -> yield ((line, pos.Line, pos.Column), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) | None -> ()] - results |> shouldEqual + results |> shouldEqual [((" let y = z + 1", 3, 0), (3, 4, 3, 17)); ((" let y = z + 1", 3, 1), (3, 4, 4, 9)); ((" let y = z + 1", 3, 2), (3, 4, 4, 9)); @@ -834,9 +858,9 @@ let f x = [] -let ``ValidateBreakpointLocation tests for object expressions`` () = +let ``ValidateBreakpointLocation tests for object expressions`` () = // fsi.PrintLength <- 1000 - let input = + let input = """ type IFoo = abstract member Foo: int -> int @@ -855,14 +879,14 @@ type FooImpl() = } )""" let file = "/home/user/Test.fsx" - let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let parseResult, typeCheckResults = parseAndCheckScript(file, input) let lines = input.Replace("\r", "").Split( [| '\n' |]) - let positions = [ for (i,line) in Seq.indexed lines do for (j, c) in Seq.indexed line do yield Range.mkPos (Range.Line.fromZ i) j, line ] - let results = [ for pos, line in positions do - match parseResult.ValidateBreakpointLocation pos with - | Some r -> yield ((line, pos.Line, pos.Column), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) + let positions = [ for i,line in Seq.indexed lines do for j, c in Seq.indexed line do yield Position.mkPos (Line.fromZ i) j, line ] + let results = [ for pos, line in positions do + match parseResult.ValidateBreakpointLocation pos with + | Some r -> yield ((line, pos.Line, pos.Column), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) | None -> ()] - results |> shouldEqual + results |> shouldEqual [(("type FooBase(foo:IFoo) =", 5, 5), (5, 5, 5, 12)); (("type FooBase(foo:IFoo) =", 5, 6), (5, 5, 5, 12)); (("type FooBase(foo:IFoo) =", 5, 7), (5, 5, 5, 12)); @@ -1072,9 +1096,468 @@ type FooImpl() = ((" )", 17, 7), (10, 8, 17, 9)); ((" )", 17, 8), (10, 8, 17, 9))] +let getBreakpointLocations (input: string) (parseResult: FSharpParseFileResults) = + let lines = input.Replace("\r", "").Split( [| '\n' |]) + let positions = [ for i,line in Seq.indexed lines do for j, c in Seq.indexed line do yield Position.mkPos (Line.fromZ i) j, line ] + [ for pos, line in positions do + match parseResult.ValidateBreakpointLocation pos with + | Some r -> + let text = + [ if r.StartLine = r.EndLine then + lines.[r.StartLine-1].[r.StartColumn..r.EndColumn-1] + else + lines.[r.StartLine-1].[r.StartColumn..] + for l in r.StartLine..r.EndLine-2 do + lines.[l] + lines.[r.EndLine-1].[..r.EndColumn-1] ] + |> String.concat "$" + ((pos.Line, pos.Column), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn, text)) + | None -> + ()] + +[] +let ``ValidateBreakpointLocation tests for pipe`` () = + let input = + """ +let f () = + [2] + |> List.map (fun b -> b+1) + |> List.map (fun b -> b+1)""" + let file = "/home/user/Test.fsx" + let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let results = getBreakpointLocations input parseResult + printfn "%A" results + results |> shouldEqual + [((3, 0), (3, 4, 3, 7, "[2]")); + ((3, 1), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((3, 2), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((3, 3), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((3, 4), (3, 4, 3, 7, "[2]")); ((3, 5), (3, 4, 3, 7, "[2]")); + ((3, 6), (3, 4, 3, 7, "[2]")); + ((4, 0), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 1), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 2), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 3), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 4), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 5), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 6), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((4, 7), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 8), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 9), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 10), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 11), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 12), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 13), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 14), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 15), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 16), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 17), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 18), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 19), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 20), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 21), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 22), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 23), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 24), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 25), (4, 7, 4, 30, "List.map (fun b -> b+1)")); + ((4, 26), (4, 26, 4, 29, "b+1")); ((4, 27), (4, 26, 4, 29, "b+1")); + ((4, 28), (4, 26, 4, 29, "b+1")); ((4, 29), (4, 26, 4, 29, "b+1")); + ((5, 0), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 1), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 2), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 3), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 4), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 5), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 6), + (3, 4, 5, 30, + "[2]$ |> List.map (fun b -> b+1)$ |> List.map (fun b -> b+1)")); + ((5, 7), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 8), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 9), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 10), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 11), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 12), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 13), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 14), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 15), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 16), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 17), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 18), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 19), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 20), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 21), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 22), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 23), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 24), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 25), (5, 7, 5, 30, "List.map (fun b -> b+1)")); + ((5, 26), (5, 26, 5, 29, "b+1")); ((5, 27), (5, 26, 5, 29, "b+1")); + ((5, 28), (5, 26, 5, 29, "b+1")); ((5, 29), (5, 26, 5, 29, "b+1"))] + +[] +let ``ValidateBreakpointLocation tests for pipe2`` () = + let input = + """ +let f () = + ([1],[2]) + ||> List.zip + |> List.map (fun (b,c) -> (c,b)) + |> List.unzip""" + let file = "/home/user/Test.fsx" + let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let results = getBreakpointLocations input parseResult + printfn "%A" results + results |> shouldEqual + [((3, 0), (3, 5, 3, 8, "[1]")); + ((3, 1), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((3, 2), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((3, 3), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((3, 4), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((3, 5), (3, 5, 3, 8, "[1]")); ((3, 6), (3, 5, 3, 8, "[1]")); + ((3, 7), (3, 5, 3, 8, "[1]")); ((3, 8), (3, 5, 3, 8, "[1]")); + ((3, 9), (3, 9, 3, 12, "[2]")); ((3, 10), (3, 9, 3, 12, "[2]")); + ((3, 11), (3, 9, 3, 12, "[2]")); ((3, 12), (3, 9, 3, 12, "[2]")); + ((3, 13), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 0), (4, 8, 4, 16, "List.zip")); + ((4, 1), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 2), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 3), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 4), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 5), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 6), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 7), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((4, 8), (4, 8, 4, 16, "List.zip")); ((4, 9), (4, 8, 4, 16, "List.zip")); + ((4, 10), (4, 8, 4, 16, "List.zip")); ((4, 11), (4, 8, 4, 16, "List.zip")); + ((4, 12), (4, 8, 4, 16, "List.zip")); ((4, 13), (4, 8, 4, 16, "List.zip")); + ((4, 14), (4, 8, 4, 16, "List.zip")); ((4, 15), (4, 8, 4, 16, "List.zip")); + ((5, 0), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 1), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 2), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 3), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 4), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 5), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 6), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((5, 7), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 8), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 9), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 10), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 11), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 12), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 13), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 14), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 15), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 16), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 17), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 18), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 19), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 20), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 21), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 22), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 23), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 24), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 25), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 26), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 27), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 28), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 29), (5, 7, 5, 36, "List.map (fun (b,c) -> (c,b))")); + ((5, 30), (5, 30, 5, 35, "(c,b)")); ((5, 31), (5, 30, 5, 35, "(c,b)")); + ((5, 32), (5, 30, 5, 35, "(c,b)")); ((5, 33), (5, 30, 5, 35, "(c,b)")); + ((5, 34), (5, 30, 5, 35, "(c,b)")); ((5, 35), (5, 30, 5, 35, "(c,b)")); + ((6, 0), (6, 7, 6, 17, "List.unzip")); + ((6, 1), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 2), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 3), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 4), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 5), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 6), + (3, 4, 6, 17, + "([1],[2]) $ ||> List.zip$ |> List.map (fun (b,c) -> (c,b))$ |> List.unzip")); + ((6, 7), (6, 7, 6, 17, "List.unzip")); ((6, 8), (6, 7, 6, 17, "List.unzip")); + ((6, 9), (6, 7, 6, 17, "List.unzip")); ((6, 10), (6, 7, 6, 17, "List.unzip")); + ((6, 11), (6, 7, 6, 17, "List.unzip")); ((6, 12), (6, 7, 6, 17, "List.unzip")); + ((6, 13), (6, 7, 6, 17, "List.unzip")); ((6, 14), (6, 7, 6, 17, "List.unzip")); + ((6, 15), (6, 7, 6, 17, "List.unzip")); ((6, 16), (6, 7, 6, 17, "List.unzip"))] + +[] +let ``ValidateBreakpointLocation tests for pipe3`` () = + let input = + """ +let f () = + ([1],[2],[3]) + |||> List.zip3 + |> List.map (fun (a,b,c) -> (c,b,a)) + |> List.unzip3""" + let file = "/home/user/Test.fsx" + let parseResult, typeCheckResults = parseAndCheckScript(file, input) + let results = getBreakpointLocations input parseResult + printfn "%A" results + results |> shouldEqual + [((3, 0), (3, 5, 3, 8, "[1]")); + ((3, 1), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((3, 2), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((3, 3), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((3, 4), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((3, 5), (3, 5, 3, 8, "[1]")); ((3, 6), (3, 5, 3, 8, "[1]")); + ((3, 7), (3, 5, 3, 8, "[1]")); ((3, 8), (3, 5, 3, 8, "[1]")); + ((3, 9), (3, 9, 3, 12, "[2]")); ((3, 10), (3, 9, 3, 12, "[2]")); + ((3, 11), (3, 9, 3, 12, "[2]")); ((3, 12), (3, 9, 3, 12, "[2]")); + ((3, 13), (3, 13, 3, 16, "[3]")); ((3, 14), (3, 13, 3, 16, "[3]")); + ((3, 15), (3, 13, 3, 16, "[3]")); ((3, 16), (3, 13, 3, 16, "[3]")); + ((3, 17), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 0), (4, 9, 4, 18, "List.zip3")); + ((4, 1), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 2), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 3), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 4), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 5), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 6), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 7), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 8), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((4, 9), (4, 9, 4, 18, "List.zip3")); ((4, 10), (4, 9, 4, 18, "List.zip3")); + ((4, 11), (4, 9, 4, 18, "List.zip3")); ((4, 12), (4, 9, 4, 18, "List.zip3")); + ((4, 13), (4, 9, 4, 18, "List.zip3")); ((4, 14), (4, 9, 4, 18, "List.zip3")); + ((4, 15), (4, 9, 4, 18, "List.zip3")); ((4, 16), (4, 9, 4, 18, "List.zip3")); + ((4, 17), (4, 9, 4, 18, "List.zip3")); + ((5, 0), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 1), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 2), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 3), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 4), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 5), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 6), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((5, 7), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 8), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 9), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 10), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 11), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 12), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 13), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 14), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 15), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 16), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 17), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 18), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 19), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 20), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 21), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 22), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 23), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 24), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 25), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 26), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 27), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 28), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 29), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 30), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 31), (5, 7, 5, 40, "List.map (fun (a,b,c) -> (c,b,a))")); + ((5, 32), (5, 32, 5, 39, "(c,b,a)")); ((5, 33), (5, 32, 5, 39, "(c,b,a)")); + ((5, 34), (5, 32, 5, 39, "(c,b,a)")); ((5, 35), (5, 32, 5, 39, "(c,b,a)")); + ((5, 36), (5, 32, 5, 39, "(c,b,a)")); ((5, 37), (5, 32, 5, 39, "(c,b,a)")); + ((5, 38), (5, 32, 5, 39, "(c,b,a)")); ((5, 39), (5, 32, 5, 39, "(c,b,a)")); + ((6, 0), (6, 7, 6, 18, "List.unzip3")); + ((6, 1), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 2), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 3), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 4), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 5), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 6), + (3, 4, 6, 18, + "([1],[2],[3]) $ |||> List.zip3$ |> List.map (fun (a,b,c) -> (c,b,a))$ |> List.unzip3")); + ((6, 7), (6, 7, 6, 18, "List.unzip3")); ((6, 8), (6, 7, 6, 18, "List.unzip3")); + ((6, 9), (6, 7, 6, 18, "List.unzip3")); ((6, 10), (6, 7, 6, 18, "List.unzip3")); + ((6, 11), (6, 7, 6, 18, "List.unzip3")); + ((6, 12), (6, 7, 6, 18, "List.unzip3")); + ((6, 13), (6, 7, 6, 18, "List.unzip3")); + ((6, 14), (6, 7, 6, 18, "List.unzip3")); + ((6, 15), (6, 7, 6, 18, "List.unzip3")); + ((6, 16), (6, 7, 6, 18, "List.unzip3")); + ((6, 17), (6, 7, 6, 18, "List.unzip3"))] + [] -let ``Partially valid namespaces should be reported`` () = - let input = +let ``ValidateBreakpointLocation tests for lambda with pattern arg`` () = + let input = + """ +let bodyWrapper () = + id (fun (A(b,c)) -> + let x = 1 + x)""" + let file = "/home/user/Test.fsx" + let parseResult, _typeCheckResults = parseAndCheckScript(file, input) + let results = getBreakpointLocations input parseResult + printfn "%A" results + // The majority of the breakpoints here get the entire expression, except the start-of-line ones + // on line 4 and 5, and the ones actually on the interior text of the lambda. + // + // This is correct + results |> shouldEqual + [((3, 0), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 1), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 2), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 3), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 4), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 5), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 6), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 7), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 8), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 9), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 10), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 11), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 12), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 13), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 14), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 15), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 16), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 17), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 18), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 19), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 20), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((3, 21), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 0), (4, 8, 4, 17, "let x = 1")); + ((4, 1), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 2), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 3), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 4), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 5), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 6), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 7), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((4, 8), (4, 8, 4, 17, "let x = 1")); ((4, 9), (4, 8, 4, 17, "let x = 1")); + ((4, 10), (4, 8, 4, 17, "let x = 1")); ((4, 11), (4, 8, 4, 17, "let x = 1")); + ((4, 12), (4, 8, 4, 17, "let x = 1")); ((4, 13), (4, 8, 4, 17, "let x = 1")); + ((4, 14), (4, 8, 4, 17, "let x = 1")); ((4, 15), (4, 8, 4, 17, "let x = 1")); + ((4, 16), (4, 8, 4, 17, "let x = 1")); ((5, 0), (5, 8, 5, 9, "x")); + ((5, 1), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 2), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 3), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 4), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 5), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 6), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 7), (3, 3, 5, 10, "id (fun (A(b,c)) ->$ let x = 1$ x)")); + ((5, 8), (5, 8, 5, 9, "x")); ((5, 9), (5, 8, 5, 9, "x"))] + +[] +let ``Partially valid namespaces should be reported`` () = + let input = """ open System.Threading.Foo open System @@ -1084,14 +1567,14 @@ let _ = Threading.Buzz = null """ let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, input) + let _, typeCheckResults = parseAndCheckScript(file, input) typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun su -> - let r = su.RangeAlternate + |> Array.ofSeq + |> Array.map (fun su -> + let r = su.Range su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) |> Array.distinct - |> shouldEqual + |> shouldEqual // note: these "System" sysbol uses are not duplications because each of them corresponts to different namespaces [|("System", (2, 5, 2, 11)) ("Threading", (2, 12, 2, 21)) @@ -1104,26 +1587,25 @@ let _ = Threading.Buzz = null ("Test", (1, 0, 1, 0))|] [] -let ``GetDeclarationLocation should not require physical file`` () = +let ``GetDeclarationLocation should not require physical file`` () = let input = "let abc = 1\nlet xyz = abc" let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, input) - let location = typeCheckResults.GetDeclarationLocation(2, 13, "let xyz = abc", ["abc"]) |> Async.RunSynchronously + let _, typeCheckResults = parseAndCheckScript(file, input) + let location = typeCheckResults.GetDeclarationLocation(2, 13, "let xyz = abc", ["abc"]) match location with - | FSharpFindDeclResult.DeclFound r -> Some (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn, "<=== Found here." ) + | FindDeclResult.DeclFound r -> Some (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn, "<=== Found here." ) | _ -> Some (0 , 0 , 0 , 0 , "Not Found. Should not require physical file." ) |> shouldEqual (Some (1 , 4 , 1 , 7 , "<=== Found here." )) //------------------------------------------------------------------------------- - #if TEST_TP_PROJECTS -module internal TPProject = +module internal TPProject = open System.IO - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -1144,19 +1626,20 @@ let _ = RegexTypedStatic.IsMatch<"ABC", (*$ *) >( ) // TEST: param info on Ctrl let _ = RegexTypedStatic.IsMatch<"ABC" >( (*$*) ) // TEST: no assert on Ctrl-space at $ """ - File.WriteAllText(fileName1, fileSource1) - let fileLines1 = File.ReadAllLines(fileName1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) + let fileLines1 = FileSystem.OpenFileForReadShim(fileName1).AsStream().ReadLines() + let fileNames = [fileName1] let args = Array.append (mkProjectCommandLineArgs (dllName, fileNames)) [| "-r:" + PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll") |] let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test TPProject all symbols`` () = +let ``Test TPProject all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunSynchronously - let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - let allSymbolUsesInfo = [ for s in allSymbolUses -> s.Symbol.DisplayName, tups s.RangeAlternate, attribsOfSymbol s.Symbol ] + let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunImmediate + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let allSymbolUsesInfo = [ for s in allSymbolUses -> s.Symbol.DisplayName, tups s.Range, attribsOfSymbol s.Symbol ] //printfn "allSymbolUsesInfo = \n----\n%A\n----" allSymbolUsesInfo allSymbolUsesInfo |> shouldEqual @@ -1191,15 +1674,15 @@ let ``Test TPProject all symbols`` () = [] -let ``Test TPProject errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunSynchronously - let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunSynchronously - let typeCheckResults = +let ``Test TPProject errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunImmediate + let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunImmediate + let typeCheckResults = match typeCheckAnswer with | FSharpCheckFileAnswer.Succeeded(res) -> res | res -> failwithf "Parsing did not finish... (%A)" res - let errorMessages = [ for msg in typeCheckResults.Errors -> msg.StartLineAlternate, msg.StartColumn, msg.EndLineAlternate, msg.EndColumn, msg.Message.Replace("\r","").Replace("\n","") ] + let errorMessages = [ for msg in typeCheckResults.Diagnostics -> msg.StartLine, msg.StartColumn, msg.EndLine, msg.EndColumn, msg.Message.Replace("\r","").Replace("\n","") ] //printfn "errorMessages = \n----\n%A\n----" errorMessages errorMessages |> shouldEqual @@ -1214,28 +1697,28 @@ let ``Test TPProject errors`` () = (15, 33, 15, 38, "No static parameter exists with name ''"); (16, 40, 16, 50, "This expression was expected to have type 'string' but here has type 'unit' ")] -let internal extractToolTipText (FSharpToolTipText(els)) = - [ for e in els do +let internal extractToolTipText (ToolTipText(els)) = + [ for e in els do match e with - | FSharpToolTipElement.Group txts -> for item in txts do yield item.MainDescription - | FSharpToolTipElement.CompositionError err -> yield err - | FSharpToolTipElement.None -> yield "NONE!" ] + | ToolTipElement.Group txts -> for item in txts do yield item.MainDescription + | ToolTipElement.CompositionError err -> yield err + | ToolTipElement.None -> yield "NONE!" ] [] -let ``Test TPProject quick info`` () = - let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunSynchronously - let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunSynchronously - let typeCheckResults = +let ``Test TPProject quick info`` () = + let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunImmediate + let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunImmediate + let typeCheckResults = match typeCheckAnswer with | FSharpCheckFileAnswer.Succeeded(res) -> res | res -> failwithf "Parsing did not finish... (%A)" res let toolTips = - [ for lineNum in 0 .. TPProject.fileLines1.Length - 1 do + [ for lineNum in 0 .. TPProject.fileLines1.Length - 1 do let lineText = TPProject.fileLines1.[lineNum] - if lineText.Contains(".IsMatch") then + if lineText.Contains(".IsMatch") then let colAtEndOfNames = lineText.IndexOf(".IsMatch") + ".IsMatch".Length - let res = typeCheckResults.GetToolTipTextAlternate(lineNum, colAtEndOfNames, lineText, ["RegexTypedStatic";"IsMatch"], FSharpTokenTag.IDENT) |> Async.RunSynchronously + let res = typeCheckResults.GetToolTipTextAlternate(lineNum, colAtEndOfNames, lineText, ["RegexTypedStatic";"IsMatch"], FSharpTokenTag.IDENT) yield lineNum, extractToolTipText res ] //printfn "toolTips = \n----\n%A\n----" toolTips @@ -1256,25 +1739,25 @@ let ``Test TPProject quick info`` () = [] -let ``Test TPProject param info`` () = - let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunSynchronously - let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunSynchronously - let typeCheckResults = +let ``Test TPProject param info`` () = + let wholeProjectResults = checker.ParseAndCheckProject(TPProject.options) |> Async.RunImmediate + let parseResult, typeCheckAnswer = checker.ParseAndCheckFileInProject(TPProject.fileName1, 0, TPProject.fileSource1, TPProject.options) |> Async.RunImmediate + let typeCheckResults = match typeCheckAnswer with | FSharpCheckFileAnswer.Succeeded(res) -> res | res -> failwithf "Parsing did not finish... (%A)" res let paramInfos = - [ for lineNum in 0 .. TPProject.fileLines1.Length - 1 do + [ for lineNum in 0 .. TPProject.fileLines1.Length - 1 do let lineText = TPProject.fileLines1.[lineNum] - if lineText.Contains(".IsMatch") then + if lineText.Contains(".IsMatch") then let colAtEndOfNames = lineText.IndexOf(".IsMatch") + ".IsMatch".Length - let meths = typeCheckResults.GetMethodsAlternate(lineNum, colAtEndOfNames, lineText, Some ["RegexTypedStatic";"IsMatch"]) |> Async.RunSynchronously - let elems = - [ for meth in meths.Methods do + let meths = typeCheckResults.GetMethodsAlternate(lineNum, colAtEndOfNames, lineText, Some ["RegexTypedStatic";"IsMatch"]) + let elems = + [ for meth in meths.Methods do yield extractToolTipText meth.Description, meth.HasParameters, [ for p in meth.Parameters -> p.ParameterName ], [ for p in meth.StaticParameters -> p.ParameterName ] ] yield lineNum, elems] - //printfn "paramInfos = \n----\n%A\n----" paramInfos + //printfn "paramInfos = \n----\n%A\n----" paramInfos // This tests that properly statically-instantiated methods have the right method lists and parameter info paramInfos |> shouldEqual @@ -1298,26 +1781,26 @@ let ``Test TPProject param info`` () = let ``FSharpField.IsNameGenerated`` () = let checkFields source = let file = "/home/user/Test.fsx" - let _, typeCheckResults = parseAndCheckScript(file, source) + let _, typeCheckResults = parseAndCheckScript(file, source) let symbols = typeCheckResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously symbols + |> Array.ofSeq |> Array.choose (fun su -> match su.Symbol with | :? FSharpEntity as entity -> Some entity.FSharpFields - | :? FSharpUnionCase as unionCase -> Some unionCase.UnionCaseFields + | :? FSharpUnionCase as unionCase -> Some unionCase.Fields | _ -> None) |> Seq.concat |> Seq.map (fun (field: FSharpField) -> field.Name, field.IsNameGenerated) |> List.ofSeq - + ["exception E of string", ["Data0", true] "exception E of Data0: string", ["Data0", false] "exception E of Name: string", ["Name", false] "exception E of string * Data2: string * Data1: string * Name: string * Data4: string", ["Data0", true; "Data2", false; "Data1", false; "Name", false; "Data4", false] - + "type U = Case of string", ["Item", true] "type U = Case of Item: string", ["Item", false] "type U = Case of Name: string", ["Name", false] @@ -1328,18 +1811,18 @@ let ``FSharpField.IsNameGenerated`` () = [] let ``ValNoMutable recovery`` () = - let source = """ + let _, checkResults = getParseAndCheckResults """ let x = 1 x <- let y = 1 y """ - assertContainsSymbolWithName "y" source + assertHasSymbolUsages ["y"] checkResults [] let ``PropertyCannotBeSet recovery`` () = - let source = """ + let _, checkResults = getParseAndCheckResults """ type T = static member P = 1 @@ -1347,12 +1830,12 @@ T.P <- let y = 1 y """ - assertContainsSymbolWithName "y" source + assertHasSymbolUsages ["y"] checkResults [] let ``FieldNotMutable recovery`` () = - let source = """ + let _, checkResults = getParseAndCheckResults """ type R = { F: int } @@ -1360,4 +1843,71 @@ type R = let y = 1 y """ - assertContainsSymbolWithName "y" source + assertHasSymbolUsages ["y"] checkResults + + +[] +let ``Inherit ctor arg recovery`` () = + let _, checkResults = getParseAndCheckResults """ + type T() as this = + inherit System.Exception('a', 'a') + + let x = this + """ + assertHasSymbolUsages ["x"] checkResults + +[] +let ``Missing this recovery`` () = + let _, checkResults = getParseAndCheckResults """ + type T() = + member M() = + let x = 1 in () + """ + assertHasSymbolUsages ["x"] checkResults + +[] +let ``Brace matching smoke test`` () = + let input = + """ +let x1 = { contents = 1 } +let x2 = {| contents = 1 |} +let x3 = [ 1 ] +let x4 = [| 1 |] +let x5 = $"abc{1}def" +""" + let file = "/home/user/Test.fsx" + let braces = matchBraces(file, input) + + braces + |> Array.map (fun (r1,r2) -> + (r1.StartLine, r1.StartColumn, r1.EndLine, r1.EndColumn), + (r2.StartLine, r2.StartColumn, r2.EndLine, r2.EndColumn)) + |> shouldEqual + [|((2, 9, 2, 10), (2, 24, 2, 25)); + ((3, 9, 3, 11), (3, 25, 3, 27)); + ((4, 9, 4, 10), (4, 13, 4, 14)); + ((5, 9, 5, 11), (5, 14, 5, 16)); + ((6, 14, 6, 15), (6, 16, 6, 17))|] + + +[] +let ``Brace matching in interpolated strings`` () = + let input = + " +let x5 = $\"abc{1}def\" +let x6 = $\"abc{1}def{2}hij\" +let x7 = $\"\"\"abc{1}def{2}hij\"\"\" +let x8 = $\"\"\"abc{ {contents=1} }def{2}hij\"\"\" +" + let file = "/home/user/Test.fsx" + let braces = matchBraces(file, input) + + braces + |> Array.map (fun (r1,r2) -> + (r1.StartLine, r1.StartColumn, r1.EndLine, r1.EndColumn), + (r2.StartLine, r2.StartColumn, r2.EndLine, r2.EndColumn)) + |> shouldEqual + [|((2, 14, 2, 15), (2, 16, 2, 17)); ((3, 14, 3, 15), (3, 16, 3, 17)); + ((3, 20, 3, 21), (3, 22, 3, 23)); ((4, 16, 4, 17), (4, 18, 4, 19)); + ((4, 22, 4, 23), (4, 24, 4, 25)); ((5, 19, 5, 20), (5, 30, 5, 31)); + ((5, 16, 5, 17), (5, 32, 5, 33)); ((5, 36, 5, 37), (5, 38, 5, 39))|] diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 284bc72e482..8713bb41e96 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -1,84 +1,159 @@  #if INTERACTIVE -#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive -#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.ProjectCracker.dll" -#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" +#r "../../artifacts/bin/FSharp.Compiler.Service/Debug/netstandard2.0/FSharp.Compiler.Service.dll" +#r "../../artifacts/bin/FSharp.Compiler.UnitTests/Debug/net472/nunit.framework.dll" #load "FsUnit.fs" #load "Common.fs" #else module FSharp.Compiler.Service.Tests.ExprTests #endif - open NUnit.Framework open FsUnit open System open System.IO +open System.Text open System.Collections.Generic -open FSharp.Compiler.SourceCodeServices +open System.Diagnostics +open System.Threading +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.IO open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open FSharp.Compiler.Symbols.FSharpExprPatterns +open TestFramework + +type FSharpCore = + | FC45 + | FC46 + | FC47 + | FC50 -let internal exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + static member fsharpVersion fc = + match fc with + | FC45 -> "FSharp.Core 4.5" + | FC46 -> "FSharp.Core 4.6" + | FC47 -> "FSharp.Core 4.7" + | FC50 -> "FSharp.Core 5.0" [] -module internal Utils = - let rec printExpr low (e:FSharpExpr) = - match e with - | BasicPatterns.AddressOf(e1) -> "&"+printExpr 0 e1 - | BasicPatterns.AddressSet(e1,e2) -> printExpr 0 e1 + " <- " + printExpr 0 e2 - | BasicPatterns.Application(f,tyargs,args) -> quote low (printExpr 10 f + printTyargs tyargs + " " + printCurriedArgs args) - | BasicPatterns.BaseValue(_) -> "base" - | BasicPatterns.Call(Some obj,v,tyargs1,tyargs2,argsL) -> printObjOpt (Some obj) + v.CompiledName + printTyargs tyargs2 + printTupledArgs argsL - | BasicPatterns.Call(None,v,tyargs1,tyargs2,argsL) -> v.DeclaringEntity.Value.CompiledName + printTyargs tyargs1 + "." + v.CompiledName + printTyargs tyargs2 + " " + printTupledArgs argsL - | BasicPatterns.Coerce(ty1,e1) -> quote low (printExpr 10 e1 + " :> " + printTy ty1) - | BasicPatterns.DefaultValue(ty1) -> "dflt" - | BasicPatterns.FastIntegerForLoop _ -> "for-loop" - | BasicPatterns.ILAsm(s,tyargs,args) -> s + printTupledArgs args - | BasicPatterns.ILFieldGet _ -> "ILFieldGet" - | BasicPatterns.ILFieldSet _ -> "ILFieldSet" - | BasicPatterns.IfThenElse (a,b,c) -> "(if " + printExpr 0 a + " then " + printExpr 0 b + " else " + printExpr 0 c + ")" - | BasicPatterns.Lambda(v,e1) -> "fun " + v.CompiledName + " -> " + printExpr 0 e1 - | BasicPatterns.Let((v,e1),b) -> "let " + (if v.IsMutable then "mutable " else "") + v.CompiledName + ": " + printTy v.FullType + " = " + printExpr 0 e1 + " in " + printExpr 0 b - | BasicPatterns.LetRec(vse,b) -> "let rec ... in " + printExpr 0 b - | BasicPatterns.NewArray(ty,es) -> "[|" + (es |> Seq.map (printExpr 0) |> String.concat "; ") + "|]" - | BasicPatterns.NewDelegate(ty,es) -> "new-delegate" - | BasicPatterns.NewObject(v,tys,args) -> "new " + v.DeclaringEntity.Value.CompiledName + printTupledArgs args - | BasicPatterns.NewRecord(v,args) -> +module internal Utils = + let getTempPath() = + Path.Combine(Path.GetTempPath(), "ExprTests") + + /// If it doesn't exists, create a folder 'ExprTests' in local user's %TEMP% folder + let createTempDir() = + let tempPath = getTempPath() + do + if Directory.Exists tempPath then () + else Directory.CreateDirectory tempPath |> ignore + + /// Returns the filename part of a temp file name created with tryCreateTemporaryFileName () + /// and an added process id and thread id to ensure uniqueness between threads. + let getTempFileName() = + let tempFileName = tryCreateTemporaryFileName () + try + let tempFile, tempExt = Path.GetFileNameWithoutExtension tempFileName, Path.GetExtension tempFileName + let procId, threadId = Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId + String.concat "" [tempFile; "_"; string procId; "_"; string threadId; tempExt] // ext includes dot + finally + try + FileSystem.FileDeleteShim tempFileName + with _ -> () + + /// Clean up after a test is run. If you need to inspect the create *.fs files, change this function to do nothing, or just break here. + let cleanupTempFiles files = + { new IDisposable with + member _.Dispose() = + for fileName in files do + try + // cleanup: only the source file is written to the temp dir. + FileSystem.FileDeleteShim fileName + with _ -> () + + try + // remove the dir when empty + let tempPath = getTempPath() + if Directory.GetFiles tempPath |> Array.isEmpty then + Directory.Delete tempPath + with _ -> () } + + /// Given just a filename, returns it with changed extension located in %TEMP%\ExprTests + let getTempFilePathChangeExt tmp ext = + Path.Combine(getTempPath(), Path.ChangeExtension(tmp, ext)) + + // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times + // Presumably this is very small differences in Mono reflection causing F# printing to change behaviour + // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 + let filterHack l = + l |> List.map (fun (s:string) -> + // potential difference on Mono + s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShape [(Some 0, null)]") + // spacing difference when run locally in VS + .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, null)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)]") + // local VS IDE vs CI env difference + .Replace("Operators.Hash (x)", "x.GetHashCode()")) + + let rec printExpr low (e:FSharpExpr) = + match e with + | AddressOf(e1) -> "&"+printExpr 0 e1 + | AddressSet(e1,e2) -> printExpr 0 e1 + " <- " + printExpr 0 e2 + | Application(f,tyargs,args) -> quote low (printExpr 10 f + printTyargs tyargs + " " + printCurriedArgs args) + | BaseValue _ -> "base" + | CallWithWitnesses(Some obj,v,tyargs1,tyargs2,witnessL,argsL) -> printObjOpt (Some obj) + v.CompiledName + printTyargs tyargs2 + printTupledArgs (witnessL @ argsL) + | CallWithWitnesses(None,v,tyargs1,tyargs2,witnessL,argsL) -> v.DeclaringEntity.Value.CompiledName + printTyargs tyargs1 + "." + v.CompiledName + printTyargs tyargs2 + " " + printTupledArgs (witnessL @ argsL) + | Call(Some obj,v,tyargs1,tyargs2,argsL) -> printObjOpt (Some obj) + v.CompiledName + printTyargs tyargs2 + printTupledArgs argsL + | Call(None,v,tyargs1,tyargs2,argsL) -> v.DeclaringEntity.Value.CompiledName + printTyargs tyargs1 + "." + v.CompiledName + printTyargs tyargs2 + " " + printTupledArgs argsL + | Coerce(ty1,e1) -> quote low (printExpr 10 e1 + " :> " + printTy ty1) + | DefaultValue(ty1) -> "dflt" + | FastIntegerForLoop _ -> "for-loop" + | ILAsm(s,tyargs,args) -> s + printTupledArgs args + | ILFieldGet _ -> "ILFieldGet" + | ILFieldSet _ -> "ILFieldSet" + | IfThenElse (a,b,c) -> "(if " + printExpr 0 a + " then " + printExpr 0 b + " else " + printExpr 0 c + ")" + | Lambda(v,e1) -> "fun " + v.CompiledName + " -> " + printExpr 0 e1 + | Let((v,e1),b) -> "let " + (if v.IsMutable then "mutable " else "") + v.CompiledName + ": " + printTy v.FullType + " = " + printExpr 0 e1 + " in " + printExpr 0 b + | LetRec(vse,b) -> "let rec ... in " + printExpr 0 b + | NewArray(ty,es) -> "[|" + (es |> Seq.map (printExpr 0) |> String.concat "; ") + "|]" + | NewDelegate(ty,es) -> "new-delegate" + | NewObject(v,tys,args) -> "new " + v.DeclaringEntity.Value.CompiledName + printTupledArgs args + | NewRecord(v,args) -> let fields = v.TypeDefinition.FSharpFields - "{" + ((fields, args) ||> Seq.map2 (fun f a -> f.Name + " = " + printExpr 0 a) |> String.concat "; ") + "}" - | BasicPatterns.NewAnonRecord(v,args) -> - let fields = v.AnonRecordTypeDetails.SortedFieldNames - "{" + ((fields, args) ||> Seq.map2 (fun f a -> f+ " = " + printExpr 0 a) |> String.concat "; ") + "}" - | BasicPatterns.NewTuple(v,args) -> printTupledArgs args - | BasicPatterns.NewUnionCase(ty,uc,args) -> uc.CompiledName + printTupledArgs args - | BasicPatterns.Quote(e1) -> "quote" + printTupledArgs [e1] - | BasicPatterns.FSharpFieldGet(obj, ty,f) -> printObjOpt obj + f.Name - | BasicPatterns.AnonRecordGet(obj, ty, n) -> printExpr 0 obj + "." + ty.AnonRecordTypeDetails.SortedFieldNames.[n] - | BasicPatterns.FSharpFieldSet(obj, ty,f,arg) -> printObjOpt obj + f.Name + " <- " + printExpr 0 arg - | BasicPatterns.Sequential(e1,e2) -> "(" + printExpr 0 e1 + "; " + printExpr 0 e2 + ")" - | BasicPatterns.ThisValue _ -> "this" - | BasicPatterns.TryFinally(e1,e2) -> "try " + printExpr 0 e1 + " finally " + printExpr 0 e2 - | BasicPatterns.TryWith(e1,_,_,vC,eC) -> "try " + printExpr 0 e1 + " with " + vC.CompiledName + " -> " + printExpr 0 eC - | BasicPatterns.TupleGet(ty,n,e1) -> printExpr 10 e1 + ".Item" + string n - | BasicPatterns.DecisionTree(dtree,targets) -> "match " + printExpr 10 dtree + " targets ..." - | BasicPatterns.DecisionTreeSuccess (tg,es) -> "$" + string tg - | BasicPatterns.TypeLambda(gp1,e1) -> "FUN ... -> " + printExpr 0 e1 - | BasicPatterns.TypeTest(ty,e1) -> printExpr 10 e1 + " :? " + printTy ty - | BasicPatterns.UnionCaseSet(obj,ty,uc,f1,e1) -> printExpr 10 obj + "." + f1.Name + " <- " + printExpr 0 e1 - | BasicPatterns.UnionCaseGet(obj,ty,uc,f1) -> printExpr 10 obj + "." + f1.Name - | BasicPatterns.UnionCaseTest(obj,ty,f1) -> printExpr 10 obj + ".Is" + f1.Name - | BasicPatterns.UnionCaseTag(obj,ty) -> printExpr 10 obj + ".Tag" - | BasicPatterns.ObjectExpr(ty,basecall,overrides,iimpls) -> "{ " + printExpr 10 basecall + " with " + printOverrides overrides + " " + printIimpls iimpls + " }" - | BasicPatterns.TraitCall(tys,nm,_,argtys,tinst,args) -> "trait call " + nm + printTupledArgs args - | BasicPatterns.Const(obj,ty) -> - match obj with + "{" + ((fields, args) ||> Seq.map2 (fun f a -> f.Name + " = " + printExpr 0 a) |> String.concat "; ") + "}" + | NewAnonRecord(v,args) -> + let fields = v.AnonRecordTypeDetails.SortedFieldNames + "{" + ((fields, args) ||> Seq.map2 (fun f a -> f+ " = " + printExpr 0 a) |> String.concat "; ") + "}" + | NewTuple(v,args) -> printTupledArgs args + | NewUnionCase(ty,uc,args) -> uc.CompiledName + printTupledArgs args + | Quote(e1) -> "quote" + printTupledArgs [e1] + | FSharpFieldGet(obj, ty,f) -> printObjOpt obj + f.Name + | AnonRecordGet(obj, ty, n) -> printExpr 0 obj + "." + ty.AnonRecordTypeDetails.SortedFieldNames.[n] + | FSharpFieldSet(obj, ty,f,arg) -> printObjOpt obj + f.Name + " <- " + printExpr 0 arg + | Sequential(e1,e2) -> "(" + printExpr 0 e1 + "; " + printExpr 0 e2 + ")" + | ThisValue _ -> "this" + | TryFinally(e1,e2) -> "try " + printExpr 0 e1 + " finally " + printExpr 0 e2 + | TryWith(e1,_,_,vC,eC) -> "try " + printExpr 0 e1 + " with " + vC.CompiledName + " -> " + printExpr 0 eC + | TupleGet(ty,n,e1) -> printExpr 10 e1 + ".Item" + string n + | DecisionTree(dtree,targets) -> "match " + printExpr 10 dtree + " targets ..." + | DecisionTreeSuccess (tg,es) -> "$" + string tg + | TypeLambda(gp1,e1) -> "FUN ... -> " + printExpr 0 e1 + | TypeTest(ty,e1) -> printExpr 10 e1 + " :? " + printTy ty + | UnionCaseSet(obj,ty,uc,f1,e1) -> printExpr 10 obj + "." + f1.Name + " <- " + printExpr 0 e1 + | UnionCaseGet(obj,ty,uc,f1) -> printExpr 10 obj + "." + f1.Name + | UnionCaseTest(obj,ty,f1) -> printExpr 10 obj + ".Is" + f1.Name + | UnionCaseTag(obj,ty) -> printExpr 10 obj + ".Tag" + | ObjectExpr(ty,basecall,overrides,iimpls) -> "{ " + printExpr 10 basecall + " with " + printOverrides overrides + " " + printIimpls iimpls + " }" + | TraitCall(tys,nm,_,argtys,tinst,args) -> "trait call " + nm + printTupledArgs args + | Const(obj,ty) -> + match obj with | :? string as s -> "\"" + s + "\"" | null -> "()" | _ -> string obj - | BasicPatterns.Value(v) -> v.CompiledName - | BasicPatterns.ValueSet(v,e1) -> quote low (v.CompiledName + " <- " + printExpr 0 e1) - | BasicPatterns.WhileLoop(e1,e2) -> "while " + printExpr 0 e1 + " do " + printExpr 0 e2 + " done" + | Value(v) -> v.CompiledName + | ValueSet(v,e1) -> quote low (v.CompiledName + " <- " + printExpr 0 e1) + | WhileLoop(e1,e2) -> "while " + printExpr 0 e1 + " do " + printExpr 0 e2 + " done" | _ -> failwith (sprintf "unrecognized %+A" e) and quote low s = if low > 0 then "(" + s + ")" else s @@ -90,7 +165,7 @@ module internal Utils = and printTy ty = ty.Format(FSharpDisplayContext.Empty) and printTyargs tyargs = match tyargs with [] -> "" | args -> "<" + String.concat "," (List.map printTy tyargs) + ">" and printOverrides ors = String.concat ";" (List.map printOverride ors) - and printOverride o = + and printOverride o = match o.CurriedParameterGroups with | [t] :: a -> "member " + t.CompiledName + "." + o.Signature.Name + printCurriedParams a + " = " + printExpr 10 o.Body @@ -119,42 +194,43 @@ module internal Utils = // if not meth.IsCompilerGenerated then yield sprintf "%sbody: %A" prefix body yield "" - | FSharpImplementationFileDeclaration.InitAction (expr) -> + | FSharpImplementationFileDeclaration.InitAction expr -> yield sprintf "%s%i) ACTION" prefix i yield sprintf "%s%A" prefix expr yield "" } - let rec printDeclaration (excludes:HashSet<_> option) (d: FSharpImplementationFileDeclaration) = + let rec printDeclaration (excludes:HashSet<_> option) (d: FSharpImplementationFileDeclaration) = seq { - match d with + match d with | FSharpImplementationFileDeclaration.Entity(e,ds) -> yield sprintf "type %s" e.LogicalName yield! printDeclarations excludes ds | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v,vs,e) -> - - if not v.IsCompilerGenerated && + + if not v.IsCompilerGenerated && not (match excludes with None -> false | Some t -> t.Contains v.CompiledName) then - let text = + let text = //printfn "%s" v.CompiledName // try - if v.IsMember then + if v.IsMember then sprintf "member %s%s = %s @ %s" v.CompiledName (printCurriedParams vs) (printExpr 0 e) (e.Range.ToShortString()) - else + else sprintf "let %s%s = %s @ %s" v.CompiledName (printCurriedParams vs) (printExpr 0 e) (e.Range.ToShortString()) -// with e -> +// with e -> // printfn "FAILURE STACK: %A" e // sprintf "!!!!!!!!!! FAILED on %s @ %s, message: %s" v.CompiledName (v.DeclarationLocation.ToString()) e.Message yield text | FSharpImplementationFileDeclaration.InitAction(e) -> yield sprintf "do %s" (printExpr 0 e) } - and printDeclarations excludes ds = - seq { for d in ds do + + and printDeclarations excludes ds = + seq { for d in ds do yield! printDeclaration excludes d } - let rec exprsOfDecl (d: FSharpImplementationFileDeclaration) = + let rec exprsOfDecl (d: FSharpImplementationFileDeclaration) = seq { - match d with + match d with | FSharpImplementationFileDeclaration.Entity(e,ds) -> yield! exprsOfDecls ds | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v,vs,e) -> @@ -162,14 +238,14 @@ module internal Utils = yield e, e.Range | FSharpImplementationFileDeclaration.InitAction(e) -> yield e, e.Range } - and exprsOfDecls ds = - seq { for d in ds do + and exprsOfDecls ds = + seq { for d in ds do yield! exprsOfDecl d } let printGenericConstraint name (p: FSharpGenericParameterConstraint) = if p.IsCoercesToConstraint then - Some <| name + " :> " + printTy p.CoercesToTarget - elif p.IsComparisonConstraint then + Some <| name + " :> " + printTy p.CoercesToTarget + elif p.IsComparisonConstraint then Some <| name + " : comparison" elif p.IsEqualityConstraint then Some <| name + " : equality" @@ -184,69 +260,69 @@ module internal Utils = else None let printGenericParameter (p: FSharpGenericParameter) = - let name = + let name = if p.Name.StartsWith("?", StringComparison.Ordinal) then "_" - elif p.IsSolveAtCompileTime then "^" + p.Name + elif p.IsSolveAtCompileTime then "^" + p.Name else "'" + p.Name let constraints = p.Constraints |> Seq.choose (printGenericConstraint name) |> List.ofSeq name, constraints - + let printMemberSignature (v: FSharpMemberOrFunctionOrValue) = let genParams = let ps = v.GenericParameters |> Seq.map printGenericParameter |> List.ofSeq if List.isEmpty ps then "" else let constraints = ps |> List.collect snd - "<" + (ps |> Seq.map fst |> String.concat ", ") + + "<" + (ps |> Seq.map fst |> String.concat ", ") + (if List.isEmpty constraints then "" else " when " + String.concat " and " constraints) + ">" v.CompiledName + genParams + ": " + printTy v.FullType - let rec collectMembers (e:FSharpExpr) = - match e with - | BasicPatterns.AddressOf(e) -> collectMembers e - | BasicPatterns.AddressSet(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) - | BasicPatterns.Application(f,_,args) -> Seq.append (collectMembers f) (Seq.collect collectMembers args) - | BasicPatterns.BaseValue(_) -> Seq.empty - | BasicPatterns.Call(Some obj,v,_,_,argsL) -> Seq.concat [ collectMembers obj; Seq.singleton v; Seq.collect collectMembers argsL ] - | BasicPatterns.Call(None,v,_,_,argsL) -> Seq.concat [ Seq.singleton v; Seq.collect collectMembers argsL ] - | BasicPatterns.Coerce(_,e) -> collectMembers e - | BasicPatterns.DefaultValue(_) -> Seq.empty - | BasicPatterns.FastIntegerForLoop (fromArg, toArg, body, _) -> Seq.collect collectMembers [ fromArg; toArg; body ] - | BasicPatterns.ILAsm(_,_,args) -> Seq.collect collectMembers args - | BasicPatterns.ILFieldGet (Some e,_,_) -> collectMembers e - | BasicPatterns.ILFieldGet _ -> Seq.empty - | BasicPatterns.ILFieldSet (Some e,_,_,v) -> Seq.append (collectMembers e) (collectMembers v) - | BasicPatterns.ILFieldSet _ -> Seq.empty - | BasicPatterns.IfThenElse (a,b,c) -> Seq.collect collectMembers [ a; b; c ] - | BasicPatterns.Lambda(v,e1) -> collectMembers e1 - | BasicPatterns.Let((v,e1),b) -> Seq.append (collectMembers e1) (collectMembers b) - | BasicPatterns.LetRec(vse,b) -> Seq.append (vse |> Seq.collect (snd >> collectMembers)) (collectMembers b) - | BasicPatterns.NewArray(_,es) -> Seq.collect collectMembers es - | BasicPatterns.NewDelegate(ty,es) -> collectMembers es - | BasicPatterns.NewObject(v,tys,args) -> Seq.append (Seq.singleton v) (Seq.collect collectMembers args) - | BasicPatterns.NewRecord(v,args) -> Seq.collect collectMembers args - | BasicPatterns.NewTuple(v,args) -> Seq.collect collectMembers args - | BasicPatterns.NewUnionCase(ty,uc,args) -> Seq.collect collectMembers args - | BasicPatterns.Quote(e1) -> collectMembers e1 - | BasicPatterns.FSharpFieldGet(Some obj, _,_) -> collectMembers obj - | BasicPatterns.FSharpFieldGet _ -> Seq.empty - | BasicPatterns.FSharpFieldSet(Some obj,_,_,arg) -> Seq.append (collectMembers obj) (collectMembers arg) - | BasicPatterns.FSharpFieldSet(None,_,_,arg) -> collectMembers arg - | BasicPatterns.Sequential(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) - | BasicPatterns.ThisValue _ -> Seq.empty - | BasicPatterns.TryFinally(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) - | BasicPatterns.TryWith(e1,_,f,_,eC) -> Seq.collect collectMembers [ e1; f; eC ] - | BasicPatterns.TupleGet(ty,n,e1) -> collectMembers e1 - | BasicPatterns.DecisionTree(dtree,targets) -> Seq.append (collectMembers dtree) (targets |> Seq.collect (snd >> collectMembers)) - | BasicPatterns.DecisionTreeSuccess (tg,es) -> Seq.collect collectMembers es - | BasicPatterns.TypeLambda(gp1,e1) -> collectMembers e1 - | BasicPatterns.TypeTest(ty,e1) -> collectMembers e1 - | BasicPatterns.UnionCaseSet(obj,ty,uc,f1,e1) -> Seq.append (collectMembers obj) (collectMembers e1) - | BasicPatterns.UnionCaseGet(obj,ty,uc,f1) -> collectMembers obj - | BasicPatterns.UnionCaseTest(obj,ty,f1) -> collectMembers obj - | BasicPatterns.UnionCaseTag(obj,ty) -> collectMembers obj - | BasicPatterns.ObjectExpr(ty,basecall,overrides,iimpls) -> + let rec collectMembers (e:FSharpExpr) = + match e with + | AddressOf(e) -> collectMembers e + | AddressSet(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) + | Application(f,_,args) -> Seq.append (collectMembers f) (Seq.collect collectMembers args) + | BaseValue _ -> Seq.empty + | Call(Some obj,v,_,_,argsL) -> Seq.concat [ collectMembers obj; Seq.singleton v; Seq.collect collectMembers argsL ] + | Call(None,v,_,_,argsL) -> Seq.concat [ Seq.singleton v; Seq.collect collectMembers argsL ] + | Coerce(_,e) -> collectMembers e + | DefaultValue _ -> Seq.empty + | FastIntegerForLoop (fromArg, toArg, body, _) -> Seq.collect collectMembers [ fromArg; toArg; body ] + | ILAsm(_,_,args) -> Seq.collect collectMembers args + | ILFieldGet (Some e,_,_) -> collectMembers e + | ILFieldGet _ -> Seq.empty + | ILFieldSet (Some e,_,_,v) -> Seq.append (collectMembers e) (collectMembers v) + | ILFieldSet _ -> Seq.empty + | IfThenElse (a,b,c) -> Seq.collect collectMembers [ a; b; c ] + | Lambda(v,e1) -> collectMembers e1 + | Let((v,e1),b) -> Seq.append (collectMembers e1) (collectMembers b) + | LetRec(vse,b) -> Seq.append (vse |> Seq.collect (snd >> collectMembers)) (collectMembers b) + | NewArray(_,es) -> Seq.collect collectMembers es + | NewDelegate(ty,es) -> collectMembers es + | NewObject(v,tys,args) -> Seq.append (Seq.singleton v) (Seq.collect collectMembers args) + | NewRecord(v,args) -> Seq.collect collectMembers args + | NewTuple(v,args) -> Seq.collect collectMembers args + | NewUnionCase(ty,uc,args) -> Seq.collect collectMembers args + | Quote(e1) -> collectMembers e1 + | FSharpFieldGet(Some obj, _,_) -> collectMembers obj + | FSharpFieldGet _ -> Seq.empty + | FSharpFieldSet(Some obj,_,_,arg) -> Seq.append (collectMembers obj) (collectMembers arg) + | FSharpFieldSet(None,_,_,arg) -> collectMembers arg + | Sequential(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) + | ThisValue _ -> Seq.empty + | TryFinally(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) + | TryWith(e1,_,f,_,eC) -> Seq.collect collectMembers [ e1; f; eC ] + | TupleGet(ty,n,e1) -> collectMembers e1 + | DecisionTree(dtree,targets) -> Seq.append (collectMembers dtree) (targets |> Seq.collect (snd >> collectMembers)) + | DecisionTreeSuccess (tg,es) -> Seq.collect collectMembers es + | TypeLambda(gp1,e1) -> collectMembers e1 + | TypeTest(ty,e1) -> collectMembers e1 + | UnionCaseSet(obj,ty,uc,f1,e1) -> Seq.append (collectMembers obj) (collectMembers e1) + | UnionCaseGet(obj,ty,uc,f1) -> collectMembers obj + | UnionCaseTest(obj,ty,f1) -> collectMembers obj + | UnionCaseTag(obj,ty) -> collectMembers obj + | ObjectExpr(ty,basecall,overrides,iimpls) -> seq { yield! collectMembers basecall for o in overrides do @@ -255,17 +331,17 @@ module internal Utils = for o in i do yield! collectMembers o.Body } - | BasicPatterns.TraitCall(tys,nm,_,argtys,tinst,args) -> Seq.collect collectMembers args - | BasicPatterns.Const(obj,ty) -> Seq.empty - | BasicPatterns.Value(v) -> Seq.singleton v - | BasicPatterns.ValueSet(v,e1) -> Seq.append (Seq.singleton v) (collectMembers e1) - | BasicPatterns.WhileLoop(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) + | TraitCall(tys,nm,_,argtys,tinst,args) -> Seq.collect collectMembers args + | Const(obj,ty) -> Seq.empty + | Value(v) -> Seq.singleton v + | ValueSet(v,e1) -> Seq.append (Seq.singleton v) (collectMembers e1) + | WhileLoop(e1,e2) -> Seq.append (collectMembers e1) (collectMembers e2) | _ -> failwith (sprintf "unrecognized %+A" e) - let rec printMembersOfDeclatations ds = - seq { - for d in ds do - match d with + let rec printMembersOfDeclatations ds = + seq { + for d in ds do + match d with | FSharpImplementationFileDeclaration.Entity(_,ds) -> yield! printMembersOfDeclatations ds | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v,vs,e) -> @@ -276,16 +352,26 @@ module internal Utils = } +let createOptionsAux fileSources extraArgs = + let fileNames = fileSources |> List.map (fun _ -> Utils.getTempFileName()) + let temp2 = Utils.getTempFileName() + let fileNames = fileNames |> List.map (fun temp1 -> Utils.getTempFilePathChangeExt temp1 ".fs") + let dllName = Utils.getTempFilePathChangeExt temp2 ".dll" + let projFileName = Utils.getTempFilePathChangeExt temp2 ".fsproj" + + Utils.createTempDir() + for fileSource: string, fileName in List.zip fileSources fileNames do + FileSystem.OpenFileForWriteShim(fileName).Write(fileSource) + let args = [| yield! extraArgs; yield! mkProjectCommandLineArgs (dllName, fileNames) |] + let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + + Utils.cleanupTempFiles (fileNames @ [dllName; projFileName]), options + //--------------------------------------------------------------------------------------------------------- // This project is a smoke test for a whole range of standard and obscure expressions -module internal Project1 = +module internal Project1 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() - let fileName2 = Path.ChangeExtension(base2, ".fs") - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module M @@ -298,12 +384,12 @@ let tupleEx1 = (1, 1L) let tupleEx2 = (1, 1L, 1u) let tupleEx3 = (1, 1L, 1u, 1s) -let localExample = +let localExample = let y = 1 let z = 1 y, z -let localGenericFunctionExample() = +let localGenericFunctionExample() = let y = 1 let compiledAsLocalGenericFunction x = x compiledAsLocalGenericFunction y, compiledAsLocalGenericFunction 1.0 @@ -319,14 +405,14 @@ let testILCall2 = System.Console.WriteLine("176") let rec recValNeverUsedAtRuntime = recFuncIgnoresFirstArg (fun _ -> recValNeverUsedAtRuntime) 1 and recFuncIgnoresFirstArg g v = v -let testFun4() = +let testFun4() = // Test recursive values in expression position let rec recValNeverUsedAtRuntime = recFuncIgnoresFirstArg (fun _ -> recValNeverUsedAtRuntime) 1 and recFuncIgnoresFirstArg g v = v recValNeverUsedAtRuntime -type ClassWithImplicitConstructor(compiledAsArg: int) = +type ClassWithImplicitConstructor(compiledAsArg: int) = inherit obj() let compiledAsField = 1 let compiledAsLocal = 1 @@ -342,9 +428,9 @@ type ClassWithImplicitConstructor(compiledAsArg: int) = member __.M1() = compiledAsField + compiledAsGenericInstanceMethod compiledAsField + compiledAsArg member __.M2() = compiledAsInstanceMethod() - static member SM1() = compiledAsStaticField + compiledAsGenericStaticMethod compiledAsStaticField + static member SM1() = compiledAsStaticField + compiledAsGenericStaticMethod compiledAsStaticField static member SM2() = compiledAsStaticMethod() - //override __.ToString() = base.ToString() + string 999 + //override _.ToString() = base.ToString() + string 999 member this.TestCallinToString() = this.ToString() exception Error of int * int @@ -353,17 +439,17 @@ let err = Error(3,4) let matchOnException err = match err with Error(a,b) -> 3 | e -> raise e -let upwardForLoop () = +let upwardForLoop () = let mutable a = 1 for i in 0 .. 10 do a <- a + 1 a -let upwardForLoop2 () = +let upwardForLoop2 () = let mutable a = 1 for i = 0 to 10 do a <- a + 1 a -let downwardForLoop () = +let downwardForLoop () = let mutable a = 1 for i = 10 downto 1 do a <- a + 1 a @@ -372,9 +458,9 @@ let quotationTest1() = <@ 1 + 1 @> let quotationTest2 v = <@ %v + 1 @> type RecdType = { Field1: int; Field2: int } -type UnionType = Case1 of int | Case2 | Case3 of int * string +type UnionType = Case1 of int | Case2 | Case3 of int * string -type ClassWithEventsAndProperties() = +type ClassWithEventsAndProperties() = let ev = new Event<_>() static let sev = new Event<_>() member x.InstanceProperty = ev.Trigger(1); 1 @@ -390,26 +476,26 @@ System.Console.WriteLine("777") // do a top-levl action let functionWithSubmsumption(x:obj) = x :?> string //let functionWithCoercion(x:string) = (x :> obj) :?> string |> functionWithSubmsumption |> functionWithSubmsumption -type MultiArgMethods(c:int,d:int) = +type MultiArgMethods(c:int,d:int) = member x.Method(a:int, b : int) = 1 member x.CurriedMethod(a1:int, b1: int) (a2:int, b2:int) = 1 -let testFunctionThatCallsMultiArgMethods() = +let testFunctionThatCallsMultiArgMethods() = let m = MultiArgMethods(3,4) (m.Method(7,8) + m.CurriedMethod (9,10) (11,12)) -//let functionThatUsesObjectExpression() = -// { new obj() with member x.ToString() = string 888 } +//let functionThatUsesObjectExpression() = +// { new obj() with member x.ToString() = string 888 } // -//let functionThatUsesObjectExpressionWithInterfaceImpl() = -// { new obj() with -// member x.ToString() = string 888 -// interface System.IComparable with -// member x.CompareTo(y:obj) = 0 } +//let functionThatUsesObjectExpressionWithInterfaceImpl() = +// { new obj() with +// member x.ToString() = string 888 +// interface System.IComparable with +// member x.CompareTo(y:obj) = 0 } let testFunctionThatUsesUnitsOfMeasure (x : float<_>) (y: float<_>) = x + y -let testFunctionThatUsesAddressesAndByrefs (x: byref) = +let testFunctionThatUsesAddressesAndByrefs (x: byref) = let mutable w = 4 let y1 = &x // address-of let y2 = &w // address-of @@ -417,7 +503,7 @@ let testFunctionThatUsesAddressesAndByrefs (x: byref) = let r = ref 3 // address-of let y3 = &arr.[0] // address-of array let y4 = &r.contents // address-of field - let z = x + y1 + y2 + y3 // dereference + let z = x + y1 + y2 + y3 // dereference w <- 3 // assign to pointer x <- 4 // assign to byref y2 <- 4 // assign to byref @@ -426,7 +512,7 @@ let testFunctionThatUsesAddressesAndByrefs (x: byref) = let testFunctionThatUsesStructs1 (dt:System.DateTime) = dt.AddDays(3.0) -let testFunctionThatUsesStructs2 () = +let testFunctionThatUsesStructs2 () = let dt1 = System.DateTime.Now let mutable dt2 = System.DateTime.Now let dt3 = dt1 - dt2 @@ -436,20 +522,20 @@ let testFunctionThatUsesStructs2 () = let dt7 = dt6 - dt4 dt7 -let testFunctionThatUsesWhileLoop() = +let testFunctionThatUsesWhileLoop() = let mutable x = 1 while x < 100 do x <- x + 1 x -let testFunctionThatUsesTryWith() = - try +let testFunctionThatUsesTryWith() = + try testFunctionThatUsesWhileLoop() with :? System.ArgumentException as e -> e.Message.Length -let testFunctionThatUsesTryFinally() = - try +let testFunctionThatUsesTryFinally() = + try testFunctionThatUsesWhileLoop() finally System.Console.WriteLine("8888") @@ -460,36 +546,36 @@ type System.Console with type System.DateTime with member x.TwoMinute = x.Minute + x.Minute -let testFunctionThatUsesExtensionMembers() = +let testFunctionThatUsesExtensionMembers() = System.Console.WriteTwoLines() let v = System.DateTime.Now.TwoMinute System.Console.WriteTwoLines() -let testFunctionThatUsesOptionMembers() = +let testFunctionThatUsesOptionMembers() = let x = Some(3) (x.IsSome, x.IsNone) -let testFunctionThatUsesOverAppliedFunction() = +let testFunctionThatUsesOverAppliedFunction() = id id 3 -let testFunctionThatUsesPatternMatchingOnLists(x) = - match x with +let testFunctionThatUsesPatternMatchingOnLists(x) = + match x with | [] -> 1 | [h] -> 2 | [h;h2] -> 3 | _ -> 4 -let testFunctionThatUsesPatternMatchingOnOptions(x) = - match x with +let testFunctionThatUsesPatternMatchingOnOptions(x) = + match x with | None -> 1 | Some h -> 2 + h -let testFunctionThatUsesPatternMatchingOnOptions2(x) = - match x with +let testFunctionThatUsesPatternMatchingOnOptions2(x) = + match x with | None -> 1 | Some _ -> 2 -let testFunctionThatUsesConditionalOnOptions2(x: int option) = +let testFunctionThatUsesConditionalOnOptions2(x: int option) = if x.IsSome then 1 else 2 let f x y = x+y @@ -527,20 +613,20 @@ let test11(s:string) = let rec badLoop : (int -> int) = () // so that it is a function value - fun x -> badLoop (x + 1) + fun x -> badLoop (x + 1) module LetLambda = let f = () // so that it is a function value fun a b -> a + b -let letLambdaRes = [ 1, 2 ] |> List.map (fun (a, b) -> LetLambda.f a b) +let letLambdaRes = [ 1, 2 ] |> List.map (fun (a, b) -> LetLambda.f a b) let anonRecd = {| X = 1; Y = 2 |} let anonRecdGet = (anonRecd.X, anonRecd.Y) """ - File.WriteAllText(fileName1, fileSource1) + let fileSource2 = """ module N @@ -573,11 +659,7 @@ let testMutableVar = mutableVar 1 let testMutableConst = mutableConst () """ - File.WriteAllText(fileName2, fileSource2) - - let fileNames = [fileName1; fileName2] - let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + let createOptions() = createOptionsAux [fileSource1; fileSource2] [] let operatorTests = """ module OperatorTests{0} @@ -638,323 +720,390 @@ let test{0}ToStringOperator (e1:{1}) = string e1 """ -//<@ let x = Some(3) in x.IsSome @> +/// This test is run in unison with its optimized counterpart below [] let ``Test Unoptimized Declarations Project1`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let cleanup, options = Project1.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate - for e in wholeProjectResults.Errors do + for e in wholeProjectResults.Diagnostics do printfn "Project1 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 3 // recursive value warning - wholeProjectResults.Errors.[0].Severity |> shouldEqual FSharpErrorSeverity.Warning - wholeProjectResults.Errors.[1].Severity |> shouldEqual FSharpErrorSeverity.Warning - wholeProjectResults.Errors.[2].Severity |> shouldEqual FSharpErrorSeverity.Warning + wholeProjectResults.Diagnostics.Length |> shouldEqual 3 // recursive value warning + wholeProjectResults.Diagnostics.[0].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning + wholeProjectResults.Diagnostics.[1].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning + wholeProjectResults.Diagnostics.[2].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 2 let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] let file2 = wholeProjectResults.AssemblyContents.ImplementationFiles.[1] - // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times - // Presumably this is very small differences in Mono reflection causing F# printing to change behavious - // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 - let filterHack l = - l |> List.map (fun (s:string) -> - s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShapeFIX") - .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX")) - - let expected = [ - "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; - "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; - "let tupleEx1 = (1,1) @ (9,16--9,21)"; - "let tupleEx2 = (1,1,1) @ (10,16--10,25)"; - "let tupleEx3 = (1,1,1,1) @ (11,16--11,29)"; - "let localExample = let y: Microsoft.FSharp.Core.int = 1 in let z: Microsoft.FSharp.Core.int = 1 in (y,z) @ (14,7--14,8)"; - "let localGenericFunctionExample(unitVar0) = let y: Microsoft.FSharp.Core.int = 1 in let compiledAsLocalGenericFunction: 'a -> 'a = FUN ... -> fun x -> x in (compiledAsLocalGenericFunction y,compiledAsLocalGenericFunction 1) @ (19,7--19,8)"; - "let funcEx1(x) = x @ (23,23--23,24)"; - "let genericFuncEx1(x) = x @ (24,29--24,30)"; - "let topPair1b = M.patternInput@25 ().Item1 @ (25,4--25,26)"; - "let topPair1a = M.patternInput@25 ().Item0 @ (25,4--25,26)"; - "let testILCall1 = new Object() @ (27,18--27,27)"; - "let testILCall2 = Console.WriteLine (\"176\") @ (28,18--28,49)"; - "let recValNeverUsedAtRuntime = recValNeverUsedAtRuntime@31.Force(()) @ (31,8--31,32)"; - "let recFuncIgnoresFirstArg(g) (v) = v @ (32,33--32,34)"; - "let testFun4(unitVar0) = let rec ... in recValNeverUsedAtRuntime @ (36,4--39,28)"; - "type ClassWithImplicitConstructor"; - "member .ctor(compiledAsArg) = (new Object(); (this.compiledAsArg <- compiledAsArg; (this.compiledAsField <- 1; let compiledAsLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (compiledAsLocal,compiledAsLocal) in ()))) @ (41,5--41,33)"; - "member .cctor(unitVar) = (compiledAsStaticField <- 1; let compiledAsStaticLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsStaticLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (compiledAsStaticLocal,compiledAsStaticLocal) in ()) @ (49,11--49,40)"; - "member M1(__) (unitVar1) = Operators.op_Addition (Operators.op_Addition (__.compiledAsField,let x: Microsoft.FSharp.Core.int = __.compiledAsField in __.compiledAsGenericInstanceMethod(x)),__.compiledAsArg) @ (55,21--55,102)"; - "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; - "member SM1(unitVar0) = Operators.op_Addition (compiledAsStaticField,let x: Microsoft.FSharp.Core.int = compiledAsStaticField in ClassWithImplicitConstructor.compiledAsGenericStaticMethod (x)) @ (57,26--57,101)"; - "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; - "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; - "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; - "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; - "let upwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (69,16--69,17)"; - "let upwardForLoop2(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (74,16--74,17)"; - "let downwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (79,16--79,17)"; - "let quotationTest1(unitVar0) = quote(Operators.op_Addition (1,1)) @ (83,24--83,35)"; - "let quotationTest2(v) = quote(Operators.op_Addition (ExtraTopLevelOperators.SpliceExpression (v),1)) @ (84,24--84,36)"; - "type RecdType"; "type UnionType"; "type ClassWithEventsAndProperties"; - "member .ctor(unitVar0) = (new Object(); (this.ev <- new FSharpEvent`1(()); ())) @ (89,5--89,33)"; - "member .cctor(unitVar) = (sev <- new FSharpEvent`1(()); ()) @ (91,11--91,35)"; - "member get_InstanceProperty(x) (unitVar1) = (x.ev.Trigger(1); 1) @ (92,32--92,48)"; - "member get_StaticProperty(unitVar0) = (sev.Trigger(1); 1) @ (93,35--93,52)"; - "member get_InstanceEvent(x) (unitVar1) = x.ev.get_Publish(()) @ (94,29--94,39)"; - "member get_StaticEvent(x) (unitVar1) = sev.get_Publish(()) @ (95,27--95,38)"; - "let c = new ClassWithEventsAndProperties(()) @ (97,8--97,38)"; - "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; - "do Console.WriteLine (\"777\")"; - "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric (x) @ (102,40--102,52)"; - "type MultiArgMethods"; - "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; - "member Method(x) (a,b) = 1 @ (106,37--106,38)"; - "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; - "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)"; - "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; - "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; - "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = Operators.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = Operators.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; - "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; - "let testFunctionThatUsesTryWith(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) with matchValue -> match (if matchValue :? System.ArgumentException then $0 else $1) targets ... @ (158,3--160,60)"; - "let testFunctionThatUsesTryFinally(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) finally Console.WriteLine (\"8888\") @ (164,3--167,37)"; - "member Console.WriteTwoLines.Static(unitVar0) = (Console.WriteLine (); Console.WriteLine ()) @ (170,36--170,90)"; - "member DateTime.get_TwoMinute(x) (unitVar1) = Operators.op_Addition (x.get_Minute(),x.get_Minute()) @ (173,25--173,44)"; - "let testFunctionThatUsesExtensionMembers(unitVar0) = (M.Console.WriteTwoLines.Static (()); let v: Microsoft.FSharp.Core.int = DateTime.get_Now ().DateTime.get_TwoMinute(()) in M.Console.WriteTwoLines.Static (())) @ (176,3--178,33)"; - "let testFunctionThatUsesOptionMembers(unitVar0) = let x: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.option = Some(3) in (x.get_IsSome() (),x.get_IsNone() ()) @ (181,7--181,8)"; - "let testFunctionThatUsesOverAppliedFunction(unitVar0) = Operators.Identity Microsoft.FSharp.Core.int> (fun x -> Operators.Identity (x)) 3 @ (185,3--185,10)"; - "let testFunctionThatUsesPatternMatchingOnLists(x) = match (if x.Isop_ColonColon then (if x.Tail.Isop_ColonColon then (if x.Tail.Tail.Isop_Nil then $2 else $3) else $1) else $0) targets ... @ (188,10--188,11)"; - "let testFunctionThatUsesPatternMatchingOnOptions(x) = match (if x.IsSome then $1 else $0) targets ... @ (195,10--195,11)"; - "let testFunctionThatUsesPatternMatchingOnOptions2(x) = match (if x.IsSome then $1 else $0) targets ... @ (200,10--200,11)"; - "let testFunctionThatUsesConditionalOnOptions2(x) = (if x.get_IsSome() () then 1 else 2) @ (205,4--205,29)"; - "let f(x) (y) = Operators.op_Addition (x,y) @ (207,12--207,15)"; - "let g = let x: Microsoft.FSharp.Core.int = 1 in fun y -> M.f (x,y) @ (208,8--208,11)"; - "let h = Operators.op_Addition (M.g () 2,3) @ (209,8--209,17)"; - "type TestFuncProp"; - "member .ctor(unitVar0) = (new Object(); ()) @ (211,5--211,17)"; - "member get_Id(this) (unitVar1) = fun x -> x @ (212,21--212,31)"; - "let wrong = Operators.op_Equality (new TestFuncProp(()).get_Id(()) 0,0) @ (214,12--214,35)"; - "let start(name) = (name,name) @ (217,4--217,14)"; - "let last(name,values) = Operators.Identity ((name,values)) @ (220,4--220,21)"; - "let last2(name) = Operators.Identity (name) @ (223,4--223,11)"; - "let test7(s) = Operators.op_PipeRight (M.start (s),fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values)) @ (226,4--226,19)"; - "let test8(unitVar0) = fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values) @ (229,4--229,8)"; - "let test9(s) = Operators.op_PipeRight ((s,s),fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values)) @ (232,4--232,17)"; - "let test10(unitVar0) = fun name -> M.last2 (name) @ (235,4--235,9)"; - "let test11(s) = Operators.op_PipeRight (s,fun name -> M.last2 (name)) @ (238,4--238,14)"; - "let badLoop = badLoop@240.Force Microsoft.FSharp.Core.int>(()) @ (240,8--240,15)"; - "type LetLambda"; - "let f = ((); fun a -> fun b -> Operators.op_Addition (a,b)) @ (246,8--247,24)"; - "let letLambdaRes = Operators.op_PipeRight<(Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int) Microsoft.FSharp.Collections.list,Microsoft.FSharp.Core.int Microsoft.FSharp.Collections.list> (Cons((1,2),Empty()),let mapping: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.int = fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b in fun list -> ListModule.Map (mapping,list)) @ (249,19--249,71)"; - "let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)" - "let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)" - ] - - let expected2 = [ - "type N"; "type IntAbbrev"; "let bool2 = False @ (6,12--6,17)"; - "let testHashChar(x) = Operators.Hash (x) @ (8,28--8,34)"; - "let testHashSByte(x) = Operators.Hash (x) @ (9,30--9,36)"; - "let testHashInt16(x) = Operators.Hash (x) @ (10,30--10,36)"; - "let testHashInt64(x) = Operators.Hash (x) @ (11,30--11,36)"; - "let testHashUInt64(x) = Operators.Hash (x) @ (12,32--12,38)"; - "let testHashIntPtr(x) = Operators.Hash (x) @ (13,35--13,41)"; - "let testHashUIntPtr(x) = Operators.Hash (x) @ (14,37--14,43)"; - "let testHashString(x) = Operators.Hash (x) @ (16,32--16,38)"; - "let testTypeOf(x) = Operators.TypeOf<'T> () @ (17,24--17,30)"; - "let mutableVar(x) = (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (20,4--22,16)"; - "let mutableConst(unitVar0) = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (25,16--25,19)"; - "let testMutableVar = N.mutableVar (1) @ (28,21--28,33)"; - "let testMutableConst = N.mutableConst (()) @ (29,23--29,38)"; - ] - - printDeclarations None (List.ofSeq file1.Declarations) - |> Seq.toList - |> filterHack - |> shouldEqual (filterHack expected) - - printDeclarations None (List.ofSeq file2.Declarations) - |> Seq.toList - |> filterHack - |> shouldEqual (filterHack expected2) + let expected = + ["type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; + "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; + "let tupleEx1 = (1,1) @ (9,16--9,21)"; + "let tupleEx2 = (1,1,1) @ (10,16--10,25)"; + "let tupleEx3 = (1,1,1,1) @ (11,16--11,29)"; + "let localExample = let y: Microsoft.FSharp.Core.int = 1 in let z: Microsoft.FSharp.Core.int = 1 in (y,z) @ (14,7--14,8)"; + "let localGenericFunctionExample(unitVar0) = let y: Microsoft.FSharp.Core.int = 1 in let compiledAsLocalGenericFunction: 'a -> 'a = FUN ... -> fun x -> x in (compiledAsLocalGenericFunction y,compiledAsLocalGenericFunction 1) @ (19,7--19,8)"; + "let funcEx1(x) = x @ (23,23--23,24)"; + "let genericFuncEx1(x) = x @ (24,29--24,30)"; + "let topPair1b = M.patternInput@25 ().Item1 @ (25,4--25,26)"; + "let topPair1a = M.patternInput@25 ().Item0 @ (25,4--25,26)"; + "let testILCall1 = new Object() @ (27,18--27,27)"; + "let testILCall2 = Console.WriteLine (\"176\") @ (28,18--28,49)"; + "let recValNeverUsedAtRuntime = recValNeverUsedAtRuntime@31.Force(()) @ (31,8--31,32)"; + "let recFuncIgnoresFirstArg(g) (v) = v @ (32,33--32,34)"; + "let testFun4(unitVar0) = let rec ... in recValNeverUsedAtRuntime @ (36,4--39,28)"; + "type ClassWithImplicitConstructor"; + "member .ctor(compiledAsArg) = (new Object(); (this.compiledAsArg <- compiledAsArg; (this.compiledAsField <- 1; let compiledAsLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsLocal,compiledAsLocal) in ()))) @ (41,5--41,33)"; + "member .cctor(unitVar) = (compiledAsStaticField <- 1; let compiledAsStaticLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsStaticLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsStaticLocal,compiledAsStaticLocal) in ()) @ (49,11--49,40)"; + "member M1(__) (unitVar1) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),__.compiledAsField,let x: Microsoft.FSharp.Core.int = __.compiledAsField in __.compiledAsGenericInstanceMethod(x)),__.compiledAsArg) @ (55,21--55,102)"; + "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; + "member SM1(unitVar0) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsStaticField,let x: Microsoft.FSharp.Core.int = compiledAsStaticField in ClassWithImplicitConstructor.compiledAsGenericStaticMethod (x)) @ (57,26--57,101)"; + "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; + "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; + "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; + "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; + "let upwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (69,16--69,17)"; + "let upwardForLoop2(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (74,16--74,17)"; + "let downwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (79,16--79,17)"; + "let quotationTest1(unitVar0) = quote(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),1,1)) @ (83,24--83,35)"; + "let quotationTest2(v) = quote(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),ExtraTopLevelOperators.SpliceExpression (v),1)) @ (84,24--84,36)"; + "type RecdType"; "type UnionType"; "type ClassWithEventsAndProperties"; + "member .ctor(unitVar0) = (new Object(); (this.ev <- new FSharpEvent`1(()); ())) @ (89,5--89,33)"; + "member .cctor(unitVar) = (sev <- new FSharpEvent`1(()); ()) @ (91,11--91,35)"; + "member get_InstanceProperty(x) (unitVar1) = (x.ev.Trigger(1); 1) @ (92,32--92,48)"; + "member get_StaticProperty(unitVar0) = (sev.Trigger(1); 1) @ (93,35--93,52)"; + "member get_InstanceEvent(x) (unitVar1) = x.ev.get_Publish(()) @ (94,29--94,39)"; + "member get_StaticEvent(x) (unitVar1) = sev.get_Publish(()) @ (95,27--95,38)"; + "let c = new ClassWithEventsAndProperties(()) @ (97,8--97,38)"; + "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; + "do Console.WriteLine (\"777\")"; + "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric (x) @ (102,40--102,52)"; + "type MultiArgMethods"; + "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; + "member Method(x) (a,b) = 1 @ (106,37--106,38)"; + "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; + "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)"; + "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (arg0_0,arg1_0),x,y) @ (122,70--122,75)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; + "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> DateTime.op_Subtraction (arg0_0,arg1_0),dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> DateTime.op_Subtraction (arg0_0,arg1_0),dt6,dt4) in dt7 @ (142,7--142,10)"; + "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,1) done; x) @ (152,15--152,16)"; + "let testFunctionThatUsesTryWith(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) with matchValue -> match (if matchValue :? System.ArgumentException then $0 else $1) targets ... @ (158,3--160,60)"; + "let testFunctionThatUsesTryFinally(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) finally Console.WriteLine (\"8888\") @ (164,3--167,37)"; + "member Console.WriteTwoLines.Static(unitVar0) = (Console.WriteLine (); Console.WriteLine ()) @ (170,36--170,90)"; + "member DateTime.get_TwoMinute(x) (unitVar1) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x.get_Minute(),x.get_Minute()) @ (173,25--173,44)"; + "let testFunctionThatUsesExtensionMembers(unitVar0) = (M.Console.WriteTwoLines.Static (()); let v: Microsoft.FSharp.Core.int = DateTime.get_Now ().DateTime.get_TwoMinute(()) in M.Console.WriteTwoLines.Static (())) @ (176,3--178,33)"; + "let testFunctionThatUsesOptionMembers(unitVar0) = let x: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.option = Some(3) in (x.get_IsSome() (),x.get_IsNone() ()) @ (181,7--181,8)"; + "let testFunctionThatUsesOverAppliedFunction(unitVar0) = Operators.Identity Microsoft.FSharp.Core.int> (fun x -> Operators.Identity (x)) 3 @ (185,3--185,10)"; + "let testFunctionThatUsesPatternMatchingOnLists(x) = match (if x.Isop_ColonColon then (if x.Tail.Isop_ColonColon then (if x.Tail.Tail.Isop_Nil then $2 else $3) else $1) else $0) targets ... @ (188,10--188,11)"; + "let testFunctionThatUsesPatternMatchingOnOptions(x) = match (if x.IsSome then $1 else $0) targets ... @ (195,10--195,11)"; + "let testFunctionThatUsesPatternMatchingOnOptions2(x) = match (if x.IsSome then $1 else $0) targets ... @ (200,10--200,11)"; + "let testFunctionThatUsesConditionalOnOptions2(x) = (if x.get_IsSome() () then 1 else 2) @ (205,4--205,29)"; + "let f(x) (y) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y) @ (207,12--207,15)"; + "let g = let x: Microsoft.FSharp.Core.int = 1 in fun y -> M.f (x,y) @ (208,8--208,11)"; + "let h = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),M.g () 2,3) @ (209,8--209,17)"; + "type TestFuncProp"; + "member .ctor(unitVar0) = (new Object(); ()) @ (211,5--211,17)"; + "member get_Id(this) (unitVar1) = fun x -> x @ (212,21--212,31)"; + "let wrong = Operators.op_Equality (new TestFuncProp(()).get_Id(()) 0,0) @ (214,12--214,35)"; + "let start(name) = (name,name) @ (217,4--217,14)"; + "let last(name,values) = Operators.Identity ((name,values)) @ (220,4--220,21)"; + "let last2(name) = Operators.Identity (name) @ (223,4--223,11)"; + "let test7(s) = Operators.op_PipeRight (M.start (s),fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values)) @ (226,4--226,19)"; + "let test8(unitVar0) = fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values) @ (229,4--229,8)"; + "let test9(s) = Operators.op_PipeRight ((s,s),fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values)) @ (232,4--232,17)"; + "let test10(unitVar0) = fun name -> M.last2 (name) @ (235,4--235,9)"; + "let test11(s) = Operators.op_PipeRight (s,fun name -> M.last2 (name)) @ (238,4--238,14)"; + "let badLoop = badLoop@240.Force Microsoft.FSharp.Core.int>(()) @ (240,8--240,15)"; + "type LetLambda"; + "let f = ((); fun a -> fun b -> Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),a,b)) @ (246,8--247,24)"; + "let letLambdaRes = Operators.op_PipeRight<(Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int) Microsoft.FSharp.Collections.list,Microsoft.FSharp.Core.int Microsoft.FSharp.Collections.list> (Cons((1,2),Empty()),let mapping: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.int = fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b in fun list -> ListModule.Map (mapping,list)) @ (249,19--249,71)"; + "let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)"; + "let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)"] + let expected2 = + ["type N"; "type IntAbbrev"; "let bool2 = False @ (6,12--6,17)"; + "let testHashChar(x) = Operators.Hash (x) @ (8,28--8,34)"; + "let testHashSByte(x) = Operators.Hash (x) @ (9,30--9,36)"; + "let testHashInt16(x) = Operators.Hash (x) @ (10,30--10,36)"; + "let testHashInt64(x) = Operators.Hash (x) @ (11,30--11,36)"; + "let testHashUInt64(x) = Operators.Hash (x) @ (12,32--12,38)"; + "let testHashIntPtr(x) = Operators.Hash (x) @ (13,35--13,41)"; + "let testHashUIntPtr(x) = Operators.Hash (x) @ (14,37--14,43)"; + "let testHashString(x) = Operators.Hash (x) @ (16,32--16,38)"; + "let testTypeOf(x) = Operators.TypeOf<'T> () @ (17,24--17,30)"; + "let mutableVar(x) = (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (20,4--22,16)"; + "let mutableConst(unitVar0) = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (25,16--25,19)"; + "let testMutableVar = N.mutableVar (1) @ (28,21--28,33)"; + "let testMutableConst = N.mutableConst (()) @ (29,23--29,38)"] + + printfn "// unoptimized" + printfn "let expected =\n%A" (printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList) + printfn "let expected2 =\n%A" (printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList) + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected) + + printDeclarations None (List.ofSeq file2.Declarations) + |> Seq.toList + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected2) () - [] -//#if NETCOREAPP -//[] -//#endif -[] let ``Test Optimized Declarations Project1`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let cleanup, options = Project1.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate - for e in wholeProjectResults.Errors do + for e in wholeProjectResults.Diagnostics do printfn "Project1 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 3 // recursive value warning - wholeProjectResults.Errors.[0].Severity |> shouldEqual FSharpErrorSeverity.Warning - wholeProjectResults.Errors.[1].Severity |> shouldEqual FSharpErrorSeverity.Warning - wholeProjectResults.Errors.[2].Severity |> shouldEqual FSharpErrorSeverity.Warning + wholeProjectResults.Diagnostics.Length |> shouldEqual 3 // recursive value warning + wholeProjectResults.Diagnostics.[0].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning + wholeProjectResults.Diagnostics.[1].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning + wholeProjectResults.Diagnostics.[2].Severity |> shouldEqual FSharpDiagnosticSeverity.Warning wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.Length |> shouldEqual 2 let file1 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] let file2 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[1] - // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times - // Presumably this is very small differences in Mono reflection causing F# printing to change behavious - // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 - let filterHack l = - l |> List.map (fun (s:string) -> - s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShapeFIX") - .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX")) - - let expected = [ - "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; - "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; - "let tupleEx1 = (1,1) @ (9,16--9,21)"; - "let tupleEx2 = (1,1,1) @ (10,16--10,25)"; - "let tupleEx3 = (1,1,1,1) @ (11,16--11,29)"; - "let localExample = let y: Microsoft.FSharp.Core.int = 1 in let z: Microsoft.FSharp.Core.int = 1 in (y,z) @ (14,7--14,8)"; - "let localGenericFunctionExample(unitVar0) = let y: Microsoft.FSharp.Core.int = 1 in let compiledAsLocalGenericFunction: 'a -> 'a = FUN ... -> fun x -> x in (compiledAsLocalGenericFunction y,compiledAsLocalGenericFunction 1) @ (19,7--19,8)"; - "let funcEx1(x) = x @ (23,23--23,24)"; - "let genericFuncEx1(x) = x @ (24,29--24,30)"; - "let topPair1b = M.patternInput@25 ().Item1 @ (25,4--25,26)"; - "let topPair1a = M.patternInput@25 ().Item0 @ (25,4--25,26)"; - "let testILCall1 = new Object() @ (27,18--27,27)"; - "let testILCall2 = Console.WriteLine (\"176\") @ (28,18--28,49)"; - "let recValNeverUsedAtRuntime = recValNeverUsedAtRuntime@31.Force(()) @ (31,8--31,32)"; - "let recFuncIgnoresFirstArg(g) (v) = v @ (32,33--32,34)"; - "let testFun4(unitVar0) = let rec ... in recValNeverUsedAtRuntime @ (36,4--39,28)"; - "type ClassWithImplicitConstructor"; - "member .ctor(compiledAsArg) = (new Object(); (this.compiledAsArg <- compiledAsArg; (this.compiledAsField <- 1; let compiledAsLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (compiledAsLocal,compiledAsLocal) in ()))) @ (41,5--41,33)"; - "member .cctor(unitVar) = (compiledAsStaticField <- 1; let compiledAsStaticLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsStaticLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (compiledAsStaticLocal,compiledAsStaticLocal) in ()) @ (49,11--49,40)"; - "member M1(__) (unitVar1) = Operators.op_Addition (Operators.op_Addition (__.compiledAsField,__.compiledAsGenericInstanceMethod(__.compiledAsField)),__.compiledAsArg) @ (55,21--55,102)"; - "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; - "member SM1(unitVar0) = Operators.op_Addition (compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod (compiledAsStaticField)) @ (57,26--57,101)"; - "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; - "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; - "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; - "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; - "let upwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (69,16--69,17)"; - "let upwardForLoop2(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (74,16--74,17)"; - "let downwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (79,16--79,17)"; - "let quotationTest1(unitVar0) = quote(Operators.op_Addition (1,1)) @ (83,24--83,35)"; - "let quotationTest2(v) = quote(Operators.op_Addition (ExtraTopLevelOperators.SpliceExpression (v),1)) @ (84,24--84,36)"; - "type RecdType"; "type UnionType"; "type ClassWithEventsAndProperties"; - "member .ctor(unitVar0) = (new Object(); (this.ev <- new FSharpEvent`1(()); ())) @ (89,5--89,33)"; - "member .cctor(unitVar) = (sev <- new FSharpEvent`1(()); ()) @ (91,11--91,35)"; - "member get_InstanceProperty(x) (unitVar1) = (x.ev.Trigger(1); 1) @ (92,32--92,48)"; - "member get_StaticProperty(unitVar0) = (sev.Trigger(1); 1) @ (93,35--93,52)"; - "member get_InstanceEvent(x) (unitVar1) = x.ev.get_Publish(()) @ (94,29--94,39)"; - "member get_StaticEvent(x) (unitVar1) = sev.get_Publish(()) @ (95,27--95,38)"; - "let c = new ClassWithEventsAndProperties(()) @ (97,8--97,38)"; - "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; - "do Console.WriteLine (\"777\")"; - "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric (x) @ (102,40--102,52)"; - "type MultiArgMethods"; - "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; - "member Method(x) (a,b) = 1 @ (106,37--106,38)"; - "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; - "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; - "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; - "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; - "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; - "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; - "let testFunctionThatUsesTryWith(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) with matchValue -> match (if matchValue :? System.ArgumentException then $0 else $1) targets ... @ (158,3--160,60)"; - "let testFunctionThatUsesTryFinally(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) finally Console.WriteLine (\"8888\") @ (164,3--167,37)"; - "member Console.WriteTwoLines.Static(unitVar0) = (Console.WriteLine (); Console.WriteLine ()) @ (170,36--170,90)"; - "member DateTime.get_TwoMinute(x) (unitVar1) = Operators.op_Addition (x.get_Minute(),x.get_Minute()) @ (173,25--173,44)"; - "let testFunctionThatUsesExtensionMembers(unitVar0) = (M.Console.WriteTwoLines.Static (()); let v: Microsoft.FSharp.Core.int = DateTime.get_Now ().DateTime.get_TwoMinute(()) in M.Console.WriteTwoLines.Static (())) @ (176,3--178,33)"; - "let testFunctionThatUsesOptionMembers(unitVar0) = let x: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.option = Some(3) in (x.get_IsSome() (),x.get_IsNone() ()) @ (181,7--181,8)"; - "let testFunctionThatUsesOverAppliedFunction(unitVar0) = Operators.Identity Microsoft.FSharp.Core.int> (fun x -> Operators.Identity (x)) 3 @ (185,3--185,10)"; - "let testFunctionThatUsesPatternMatchingOnLists(x) = match (if x.Isop_ColonColon then (if x.Tail.Isop_ColonColon then (if x.Tail.Tail.Isop_Nil then $2 else $3) else $1) else $0) targets ... @ (188,10--188,11)"; - "let testFunctionThatUsesPatternMatchingOnOptions(x) = match (if x.IsSome then $1 else $0) targets ... @ (195,10--195,11)"; - "let testFunctionThatUsesPatternMatchingOnOptions2(x) = match (if x.IsSome then $1 else $0) targets ... @ (200,10--200,11)"; - "let testFunctionThatUsesConditionalOnOptions2(x) = (if x.get_IsSome() () then 1 else 2) @ (205,4--205,29)"; - "let f(x) (y) = Operators.op_Addition (x,y) @ (207,12--207,15)"; - "let g = let x: Microsoft.FSharp.Core.int = 1 in fun y -> M.f (x,y) @ (208,8--208,11)"; - "let h = Operators.op_Addition (M.g () 2,3) @ (209,8--209,17)"; - "type TestFuncProp"; - "member .ctor(unitVar0) = (new Object(); ()) @ (211,5--211,17)"; - "member get_Id(this) (unitVar1) = fun x -> x @ (212,21--212,31)"; - "let wrong = Operators.op_Equality (new TestFuncProp(()).get_Id(()) 0,0) @ (214,12--214,35)"; - "let start(name) = (name,name) @ (217,4--217,14)"; - "let last(name,values) = Operators.Identity ((name,values)) @ (220,4--220,21)"; - "let last2(name) = Operators.Identity (name) @ (223,4--223,11)"; - "let test7(s) = let tupledArg: Microsoft.FSharp.Core.string * Microsoft.FSharp.Core.string = M.start (s) in let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values) @ (226,4--226,19)"; - "let test8(unitVar0) = fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values) @ (229,4--229,8)"; - "let test9(s) = M.last (s,s) @ (232,4--232,17)"; - "let test10(unitVar0) = fun name -> M.last2 (name) @ (235,4--235,9)"; - "let test11(s) = M.last2 (s) @ (238,4--238,14)"; - "let badLoop = badLoop@240.Force Microsoft.FSharp.Core.int>(()) @ (240,8--240,15)"; - "type LetLambda"; - "let f = fun a -> fun b -> Operators.op_Addition (a,b) @ (247,8--247,24)"; - "let letLambdaRes = ListModule.Map (fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b,Cons((1,2),Empty())) @ (249,19--249,71)"; - "let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)" - "let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)" - ] - - let expected2 = [ - "type N"; "type IntAbbrev"; "let bool2 = False @ (6,12--6,17)"; - "let testHashChar(x) = Operators.op_BitwiseOr (Operators.op_LeftShift (x,16),x) @ (8,28--8,34)"; - "let testHashSByte(x) = Operators.op_ExclusiveOr (Operators.op_LeftShift (x,8),x) @ (9,30--9,36)"; - "let testHashInt16(x) = Operators.op_BitwiseOr (Operators.ToUInt16 (x),Operators.op_LeftShift (x,16)) @ (10,30--10,36)"; - "let testHashInt64(x) = Operators.op_ExclusiveOr (Operators.ToInt32 (x),Operators.ToInt32 (Operators.op_RightShift (x,32))) @ (11,30--11,36)"; - "let testHashUInt64(x) = Operators.op_ExclusiveOr (Operators.ToInt32 (x),Operators.ToInt32 (Operators.op_RightShift (x,32))) @ (12,32--12,38)"; - "let testHashIntPtr(x) = Operators.ToInt32 (Operators.ToUInt64 (x)) @ (13,35--13,41)"; - "let testHashUIntPtr(x) = Operators.op_BitwiseAnd (Operators.ToInt32 (Operators.ToUInt64 (x)),2147483647) @ (14,37--14,43)"; - "let testHashString(x) = (if Operators.op_Equality (x,dflt) then 0 else x.GetHashCode()) @ (16,32--16,38)"; - "let testTypeOf(x) = Operators.TypeOf<'T> () @ (17,24--17,30)"; - "let mutableVar(x) = (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (20,4--22,16)"; - "let mutableConst(unitVar0) = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (25,16--25,19)"; - "let testMutableVar = let x: Microsoft.FSharp.Core.int = 1 in (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (28,21--28,33)"; - "let testMutableConst = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (29,23--29,38)"; - ] + let expected = + ["type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; + "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; + "let tupleEx1 = (1,1) @ (9,16--9,21)"; + "let tupleEx2 = (1,1,1) @ (10,16--10,25)"; + "let tupleEx3 = (1,1,1,1) @ (11,16--11,29)"; + "let localExample = let y: Microsoft.FSharp.Core.int = 1 in let z: Microsoft.FSharp.Core.int = 1 in (y,z) @ (14,7--14,8)"; + "let localGenericFunctionExample(unitVar0) = let y: Microsoft.FSharp.Core.int = 1 in let compiledAsLocalGenericFunction: 'a -> 'a = FUN ... -> fun x -> x in (compiledAsLocalGenericFunction y,compiledAsLocalGenericFunction 1) @ (19,7--19,8)"; + "let funcEx1(x) = x @ (23,23--23,24)"; + "let genericFuncEx1(x) = x @ (24,29--24,30)"; + "let topPair1b = M.patternInput@25 ().Item1 @ (25,4--25,26)"; + "let topPair1a = M.patternInput@25 ().Item0 @ (25,4--25,26)"; + "let testILCall1 = new Object() @ (27,18--27,27)"; + "let testILCall2 = Console.WriteLine (\"176\") @ (28,18--28,49)"; + "let recValNeverUsedAtRuntime = recValNeverUsedAtRuntime@31.Force(()) @ (31,8--31,32)"; + "let recFuncIgnoresFirstArg(g) (v) = v @ (32,33--32,34)"; + "let testFun4(unitVar0) = let rec ... in recValNeverUsedAtRuntime @ (36,4--39,28)"; + "type ClassWithImplicitConstructor"; + "member .ctor(compiledAsArg) = (new Object(); (this.compiledAsArg <- compiledAsArg; (this.compiledAsField <- 1; let compiledAsLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsLocal,compiledAsLocal) in ()))) @ (41,5--41,33)"; + "member .cctor(unitVar) = (compiledAsStaticField <- 1; let compiledAsStaticLocal: Microsoft.FSharp.Core.int = 1 in let compiledAsStaticLocal2: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsStaticLocal,compiledAsStaticLocal) in ()) @ (49,11--49,40)"; + "member M1(__) (unitVar1) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),__.compiledAsField,__.compiledAsGenericInstanceMethod(__.compiledAsField)),__.compiledAsArg) @ (55,21--55,102)"; + "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; + "member SM1(unitVar0) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod (compiledAsStaticField)) @ (57,26--57,101)"; + "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; + "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; + "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; + "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; + "let upwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (69,16--69,17)"; + "let upwardForLoop2(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (74,16--74,17)"; + "let downwardForLoop(unitVar0) = let mutable a: Microsoft.FSharp.Core.int = 1 in (for-loop; a) @ (79,16--79,17)"; + "let quotationTest1(unitVar0) = quote(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),1,1)) @ (83,24--83,35)"; + "let quotationTest2(v) = quote(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),ExtraTopLevelOperators.SpliceExpression (v),1)) @ (84,24--84,36)"; + "type RecdType"; "type UnionType"; "type ClassWithEventsAndProperties"; + "member .ctor(unitVar0) = (new Object(); (this.ev <- new FSharpEvent`1(()); ())) @ (89,5--89,33)"; + "member .cctor(unitVar) = (sev <- new FSharpEvent`1(()); ()) @ (91,11--91,35)"; + "member get_InstanceProperty(x) (unitVar1) = (x.ev.Trigger(1); 1) @ (92,32--92,48)"; + "member get_StaticProperty(unitVar0) = (sev.Trigger(1); 1) @ (93,35--93,52)"; + "member get_InstanceEvent(x) (unitVar1) = x.ev.get_Publish(()) @ (94,29--94,39)"; + "member get_StaticEvent(x) (unitVar1) = sev.get_Publish(()) @ (95,27--95,38)"; + "let c = new ClassWithEventsAndProperties(()) @ (97,8--97,38)"; + "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; + "do Console.WriteLine (\"777\")"; + "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric (x) @ (102,40--102,52)"; + "type MultiArgMethods"; + "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; + "member Method(x) (a,b) = 1 @ (106,37--106,38)"; + "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; + "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; + "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (arg0_0,arg1_0),x,y) @ (122,70--122,75)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; + "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; + "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,1) done; x) @ (152,15--152,16)"; + "let testFunctionThatUsesTryWith(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) with matchValue -> match (if matchValue :? System.ArgumentException then $0 else $1) targets ... @ (158,3--160,60)"; + "let testFunctionThatUsesTryFinally(unitVar0) = try M.testFunctionThatUsesWhileLoop (()) finally Console.WriteLine (\"8888\") @ (164,3--167,37)"; + "member Console.WriteTwoLines.Static(unitVar0) = (Console.WriteLine (); Console.WriteLine ()) @ (170,36--170,90)"; + "member DateTime.get_TwoMinute(x) (unitVar1) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x.get_Minute(),x.get_Minute()) @ (173,25--173,44)"; + "let testFunctionThatUsesExtensionMembers(unitVar0) = (M.Console.WriteTwoLines.Static (()); let v: Microsoft.FSharp.Core.int = DateTime.get_Now ().DateTime.get_TwoMinute(()) in M.Console.WriteTwoLines.Static (())) @ (176,3--178,33)"; + "let testFunctionThatUsesOptionMembers(unitVar0) = let x: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.option = Some(3) in (x.get_IsSome() (),x.get_IsNone() ()) @ (181,7--181,8)"; + "let testFunctionThatUsesOverAppliedFunction(unitVar0) = Operators.Identity Microsoft.FSharp.Core.int> (fun x -> Operators.Identity (x)) 3 @ (185,3--185,10)"; + "let testFunctionThatUsesPatternMatchingOnLists(x) = match (if x.Isop_ColonColon then (if x.Tail.Isop_ColonColon then (if x.Tail.Tail.Isop_Nil then $2 else $3) else $1) else $0) targets ... @ (188,10--188,11)"; + "let testFunctionThatUsesPatternMatchingOnOptions(x) = match (if x.IsSome then $1 else $0) targets ... @ (195,10--195,11)"; + "let testFunctionThatUsesPatternMatchingOnOptions2(x) = match (if x.IsSome then $1 else $0) targets ... @ (200,10--200,11)"; + "let testFunctionThatUsesConditionalOnOptions2(x) = (if x.get_IsSome() () then 1 else 2) @ (205,4--205,29)"; + "let f(x) (y) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y) @ (207,12--207,15)"; + "let g = let x: Microsoft.FSharp.Core.int = 1 in fun y -> M.f (x,y) @ (208,8--208,11)"; + "let h = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),M.g () 2,3) @ (209,8--209,17)"; + "type TestFuncProp"; + "member .ctor(unitVar0) = (new Object(); ()) @ (211,5--211,17)"; + "member get_Id(this) (unitVar1) = fun x -> x @ (212,21--212,31)"; + "let wrong = Operators.op_Equality (new TestFuncProp(()).get_Id(()) 0,0) @ (214,12--214,35)"; + "let start(name) = (name,name) @ (217,4--217,14)"; + "let last(name,values) = Operators.Identity ((name,values)) @ (220,4--220,21)"; + "let last2(name) = Operators.Identity (name) @ (223,4--223,11)"; + "let test7(s) = let Pipe #1 input at line 226: Microsoft.FSharp.Core.string * Microsoft.FSharp.Core.string = M.start (s) in (let name: Microsoft.FSharp.Core.string = Pipe #1 input at line 226.Item0 in let values: Microsoft.FSharp.Core.string = Pipe #1 input at line 226.Item1 in M.last (name,values); ()) @ (226,4--226,19)"; + "let test8(unitVar0) = fun tupledArg -> let name: Microsoft.FSharp.Core.string = tupledArg.Item0 in let values: Microsoft.FSharp.Core.string = tupledArg.Item1 in M.last (name,values) @ (229,4--229,8)"; + "let test9(s) = let Pipe #1 input at line 232: Microsoft.FSharp.Core.string * Microsoft.FSharp.Core.string = (s,s) in (let name: Microsoft.FSharp.Core.string = Pipe #1 input at line 232.Item0 in let values: Microsoft.FSharp.Core.string = Pipe #1 input at line 232.Item1 in M.last (name,values); ()) @ (232,4--232,17)"; + "let test10(unitVar0) = fun name -> M.last2 (name) @ (235,4--235,9)"; + "let test11(s) = let Pipe #1 input at line 238: Microsoft.FSharp.Core.string = s in (M.last2 (Pipe #1 input at line 238); ()) @ (238,4--238,14)"; + "let badLoop = badLoop@240.Force Microsoft.FSharp.Core.int>(()) @ (240,8--240,15)"; + "type LetLambda"; + "let f = fun a -> fun b -> Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),a,b) @ (247,8--247,24)"; + "let letLambdaRes = let Pipe #1 input at line 249: (Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int) Microsoft.FSharp.Collections.list = Cons((1,2),Empty()) in (ListModule.Map (fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b,Pipe #1 input at line 249); ()) @ (249,19--249,71)"; + "let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)"; + "let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)"] + let expected2 = + ["type N"; "type IntAbbrev"; "let bool2 = False @ (6,12--6,17)"; + "let testHashChar(x) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),Operators.op_LeftShift (x,16),x) @ (8,28--8,34)"; + "let testHashSByte(x) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),x,8),x) @ (9,30--9,36)"; + "let testHashInt16(x) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),x),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),x,16)) @ (10,30--10,36)"; + "let testHashInt64(x) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),x),Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),x,32))) @ (11,30--11,36)"; + "let testHashUInt64(x) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),x),Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),x,32))) @ (12,32--12,38)"; + "let testHashIntPtr(x) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),x)) @ (13,35--13,41)"; + "let testHashUIntPtr(x) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),x)),2147483647) @ (14,37--14,43)"; + "let testHashString(x) = (if Operators.op_Equality (x,dflt) then 0 else x.GetHashCode()) @ (16,32--16,38)"; + "let testTypeOf(x) = Operators.TypeOf<'T> () @ (17,24--17,30)"; + "let mutableVar(x) = (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (20,4--22,16)"; + "let mutableConst(unitVar0) = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (25,16--25,19)"; + "let testMutableVar = let x: Microsoft.FSharp.Core.int = 1 in (if Operators.op_GreaterThan (x,0) then let mutable acc: Microsoft.FSharp.Core.int = x in acc <- x else ()) @ (28,21--28,33)"; + "let testMutableConst = let mutable acc: Microsoft.FSharp.Core.unit = () in acc <- () @ (29,23--29,38)"] // printFSharpDecls "" file2.Declarations |> Seq.iter (printfn "%s") - - printDeclarations None (List.ofSeq file1.Declarations) - |> Seq.toList - |> filterHack - |> shouldEqual (filterHack expected) - - printDeclarations None (List.ofSeq file2.Declarations) - |> Seq.toList - |> filterHack - |> shouldEqual (filterHack expected2) + printfn "// optimized" + printfn "let expected =\n%A" (printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList) + printfn "let expected2 =\n%A" (printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList) + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected) + + printDeclarations None (List.ofSeq file2.Declarations) + |> Seq.toList + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected2) () let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimized = - let basePath = Path.GetTempFileName() - let fileName = Path.ChangeExtension(basePath, ".fs") - let dllName = Path.ChangeExtension(basePath, ".dll") - let projFileName = Path.ChangeExtension(basePath, ".fsproj") - let source = System.String.Format(Project1.operatorTests, dnName, fsName) - let replace (s:string) r = s.Replace("let " + r, "// let " + r) - let fileSource = excludedTests |> List.fold replace source - File.WriteAllText(fileName, fileSource) - - let args = mkProjectCommandLineArgsSilent (dllName, [fileName]) - let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously - - for e in wholeProjectResults.Errors do - printfn "%s Operator Tests error: <<<%s>>>" dnName e.Message - - wholeProjectResults.Errors.Length |> shouldEqual 0 - - let fileUnoptimized = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] - let fileOptimized = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] - - printDeclarations None (List.ofSeq fileUnoptimized.Declarations) - |> Seq.toList |> shouldEqual expectedUnoptimized - printDeclarations None (List.ofSeq fileOptimized.Declarations) - |> Seq.toList |> shouldEqual expectedOptimized - - () + let tempFileName = Utils.getTempFileName() + let filePath = Utils.getTempFilePathChangeExt tempFileName ".fs" + let dllPath =Utils.getTempFilePathChangeExt tempFileName ".dll" + let projFilePath = Utils.getTempFilePathChangeExt tempFileName ".fsproj" + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + + begin + use _cleanup = Utils.cleanupTempFiles [filePath; dllPath; projFilePath] + createTempDir() + let source = String.Format(Project1.operatorTests, dnName, fsName) + let replace (s:string) r = s.Replace("let " + r, "// let " + r) + let fileSource = excludedTests |> List.fold replace source + FileSystem.OpenFileForWriteShim(filePath).Write(fileSource) + + let args = mkProjectCommandLineArgsSilent (dllPath, [filePath]) + + let options = checker.GetProjectOptionsFromCommandLineArgs (projFilePath, args) + + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + let referencedAssemblies = wholeProjectResults.ProjectContext.GetReferencedAssemblies() + let currentAssemblyToken = + let fsCore = referencedAssemblies |> List.tryFind (fun asm -> asm.SimpleName = "FSharp.Core") + match fsCore with + | Some core -> + if core.QualifiedName.StartsWith("FSharp.Core, Version=5.0") then FC50 + elif core.QualifiedName.StartsWith("FSharp.Core, Version=4.7") then FC47 + elif core.QualifiedName.StartsWith("FSharp.Core, Version=4.6") then FC46 + else FC45 + | None -> FC45 + + for r in referencedAssemblies do + printfn "Referenced assembly %s: %O" r.QualifiedName r.FileName + + let errors = StringBuilder() + for e in wholeProjectResults.Diagnostics do + printfn "%s Operator Tests error: <<<%s>>>" dnName e.Message + errors.AppendLine e.Message |> ignore + + errors.ToString() |> shouldEqual "" + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 + + let resultUnoptimized = + wholeProjectResults.AssemblyContents.ImplementationFiles.[0].Declarations + |> printDeclarations None + |> Seq.toList + + let resultOptimized = + wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0].Declarations + |> printDeclarations None + |> Seq.toList + + printfn " let expectedUnoptimized = [" + for s in resultUnoptimized do + printfn " [], %A" s + printfn " ]" + + printfn " let expectedOptimized = [" + for s in resultOptimized do + printfn " [%s], %A" (if s.Contains("ToStringOperator") then "FC47; FC50" else "") s + printfn " ]" + + let mutable countFC45 = 0 + let mutable countFC46 = 0 + let mutable countFC47 = 0 + let mutable countFC50 = 0 + + /// Filter for allowed FSharp.Core definition. Optimizations can differ between Core versions + let filterTests result expected = + List.zip result expected + |> List.choose (fun (result, (when', s)) -> + if List.isEmpty when' then + countFC45 <- countFC45 + 1 + countFC46 <- countFC46 + 1 + countFC47 <- countFC47 + 1 + countFC50 <- countFC50 + 1 + Some(result, s) + else + if when' |> List.contains FC45 then countFC45 <- countFC45 + 1 + if when' |> List.contains FC46 then countFC46 <- countFC46 + 1 + if when' |> List.contains FC47 then countFC47 <- countFC47 + 1 + if when' |> List.contains FC50 then countFC50 <- countFC50 + 1 + if when' |> List.contains currentAssemblyToken then + Some(result, s) + else + None) + |> List.unzip + + printfn "" + printfn "Running in %O mode (%s)" currentAssemblyToken (FSharpCore.fsharpVersion currentAssemblyToken) + + let resultUnoptFiltered, expectedUnoptFiltered = filterTests resultUnoptimized expectedUnoptimized + printfn "Unoptimized FC45 tests: %i, FC46 tests: %i, FC47 tests: %i, FC50 tests: %i" countFC45 countFC46 countFC47 countFC50 + printfn "Unfiltered unoptimized: %i, filtered: %i" (List.length expectedUnoptimized) (List.length expectedUnoptFiltered) + + countFC45 <- 0 + countFC46 <- 0 + countFC47 <- 0 + countFC50 <- 0 + let resultOptFiltered, expectedOptFiltered = filterTests resultOptimized expectedOptimized + printfn "Optimized FC45 tests: %i, FC46 tests: %i, FC47 tests: %i, FC50 tests: %i" countFC45 countFC46 countFC47 countFC50 + printfn "Unfiltered optimized: %i, filtered: %i" (List.length expectedOptimized) (List.length expectedOptFiltered) + + // fail test on first line that fails, show difference in output window + resultUnoptFiltered + |> shouldPairwiseEqual expectedUnoptFiltered + + // fail test on first line that fails, show difference in output window + resultOptFiltered + |> shouldPairwiseEqual expectedOptFiltered + end [] let ``Test Operator Declarations for Byte`` () = @@ -962,110 +1111,106 @@ let ``Test Operator Declarations for Byte`` () = "testByteUnaryNegOperator"; "testByteUnaryNegChecked"; ] - + let expectedUnoptimized = [ - "type OperatorTestsByte"; - "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,64--4,72)"; - "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,64--5,73)"; - "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,64--6,72)"; - "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,64--7,73)"; - "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,64--8,72)"; - "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,64--9,73)"; - "let testByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,56--11,64)"; - "let testByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,56--12,64)"; - "let testByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,55--13,64)"; - "let testByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,56--14,64)"; - "let testByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,56--15,64)"; - "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,56--16,66)"; - "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,56--17,66)"; - "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,56--18,66)"; - "let testByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,55--19,65)"; - "let testByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,55--20,65)"; - "let testByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)"; - "let testByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,53--25,70)"; - "let testByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,53--26,70)"; - "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)"; - "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)"; - "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)"; - "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)"; - "let testByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)"; - "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)"; - "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)"; - "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)"; - "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)"; - "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)"; - "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)"; - "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)"; - "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)"; - "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)"; - "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)"; - "let testByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)"; - "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)"; - "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)"; - "let testByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)"; - "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)"; - "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)"; - "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)"; - "let testByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)"; - "let testByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)"; - "let testByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,43--54,53)"; - "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)"; - "let testByteToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)"; + [], "type OperatorTestsByte" + [], "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)" + [], "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)" + [], "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)" + [], "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)" + [], "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)" + [], "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)" + [], "let testByteAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,55--11,64)" + [], "let testByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,55--12,64)" + [], "let testByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,55--13,64)" + [], "let testByteDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,55--14,64)" + [], "let testByteModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,55--15,64)" + [], "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,55--16,66)" + [], "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,55--17,66)" + [], "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,55--18,66)" + [], "let testByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,54--19,65)" + [], "let testByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,54--20,65)" + [], "let testByteAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,53--24,70)" + [], "let testByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,53--25,70)" + [], "let testByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,53--26,70)" + [], "let testByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" + [], "let testByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" + [], "let testByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" + [], "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" + [], "let testByteToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" + [], "let testByteToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" + [], "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" + [], "let testByteToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,43--36,59)" + [], "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,43--37,60)" + [], "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,43--38,63)" + [], "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,43--39,64)" + [], "let testByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,43--41,50)" + [], "let testByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,43--42,51)" + [], "let testByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,43--43,51)" + [], "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,43--44,52)" + [], "let testByteToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,43--45,49)" + [], "let testByteToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,43--46,51)" + [], "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,43--47,52)" + [], "let testByteToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,43--48,51)" + [], "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,43--49,52)" + [], "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,43--50,55)" + [], "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,43--51,56)" + [], "let testByteToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,43--52,53)" + [], "let testByteToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,43--53,51)" + [], "let testByteToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,43--54,53)" + [], "let testByteToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,43--55,50)" + [], "let testByteToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)" ] - let expectedOptimized = [ - "type OperatorTestsByte"; - "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,64--4,72)"; - "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,64--5,73)"; - "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,64--6,72)"; - "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,64--7,73)"; - "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,64--8,72)"; - "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,64--9,73)"; - "let testByteAdditionOperator(e1) (e2) = Operators.ToByte (Operators.op_Addition (e1,e2)) @ (11,56--11,64)"; - "let testByteSubtractionOperator(e1) (e2) = Operators.ToByte (Operators.op_Subtraction (e1,e2)) @ (12,56--12,64)"; - "let testByteMultiplyOperator(e1) (e2) = Operators.ToByte (Operators.op_Multiply (e1,e2)) @ (13,55--13,64)"; - "let testByteDivisionOperator(e1) (e2) = Operators.ToByte (Operators.op_Division (e1,e2)) @ (14,56--14,64)"; - "let testByteModulusOperator(e1) (e2) = Operators.ToByte (Operators.op_Modulus (e1,e2)) @ (15,56--15,64)"; - "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,56--16,66)"; - "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,56--17,66)"; - "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,56--18,66)"; - "let testByteShiftLeftOperator(e1) (e2) = Operators.ToByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,55--19,65)"; - "let testByteShiftRightOperator(e1) (e2) = Operators.ToByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,55--20,65)"; - "let testByteAdditionChecked(e1) (e2) = Checked.ToByte (Checked.op_Addition (e1,e2)) @ (24,53--24,70)"; - "let testByteSubtractionChecked(e1) (e2) = Checked.ToByte (Checked.op_Subtraction (e1,e2)) @ (25,53--25,70)"; - "let testByteMultiplyChecked(e1) (e2) = Checked.ToByte (Checked.op_Multiply (e1,e2)) @ (26,53--26,70)"; - "let testByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)"; - "let testByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)"; - "let testByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)"; - "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)"; - "let testByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)"; - "let testByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)"; - "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)"; - "let testByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)"; - "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)"; - "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)"; - "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)"; - "let testByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)"; - "let testByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)"; - "let testByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)"; - "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)"; - "let testByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)"; - "let testByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)"; - "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)"; - "let testByteToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)"; - "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)"; - "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)"; - "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)"; - "let testByteToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)"; - "let testByteToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)"; - "let testByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,43--54,53)"; - "let testByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)"; -#if DEBUG - @"let testByteToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)"; -#else - "let testByteToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)"; -#endif - ] + [], "type OperatorTestsByte" + [], "let testByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)" + [], "let testByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)" + [], "let testByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)" + [], "let testByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)" + [], "let testByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)" + [], "let testByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)" + [], "let testByteAdditionOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (11,55--11,64)" + [], "let testByteSubtractionOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (12,55--12,64)" + [], "let testByteMultiplyOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (13,55--13,64)" + [], "let testByteDivisionOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2)) @ (14,55--14,64)" + [], "let testByteModulusOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2)) @ (15,55--15,64)" + [], "let testByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,55--16,66)" + [], "let testByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,55--17,66)" + [], "let testByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,55--18,66)" + [], "let testByteShiftLeftOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,7))) @ (19,54--19,65)" + [], "let testByteShiftRightOperator(e1) (e2) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,7))) @ (20,54--20,65)" + [], "let testByteAdditionChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,53--24,70)" + [], "let testByteSubtractionChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (25,53--25,70)" + [], "let testByteMultiplyChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,53--26,70)" + [], "let testByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" + [], "let testByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" + [], "let testByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" + [], "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" + [], "let testByteToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" + [], "let testByteToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" + [], "let testByteToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" + [], "let testByteToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,43--36,59)" + [], "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,43--37,60)" + [], "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,43--38,63)" + [], "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,43--39,64)" + [], "let testByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,43--41,50)" + [], "let testByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,43--42,51)" + [], "let testByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,43--43,51)" + [], "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,43--44,52)" + [], "let testByteToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,43--45,49)" + [], "let testByteToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,43--46,51)" + [], "let testByteToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,43--47,52)" + [], "let testByteToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,43--48,51)" + [], "let testByteToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,43--49,52)" + [], "let testByteToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,43--50,55)" + [], "let testByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,43--51,56)" + [], "let testByteToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,43--52,53)" + [], "let testByteToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,43--53,51)" + [], "let testByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,43--54,53)" + [], "let testByteToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,43--55,50)" + [FC47; FC50], "let testByteToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.byte = e1 in copyOfStruct.ToString() @ (56,43--56,52)" + ] + testOperators "Byte" "byte" excludedTests expectedUnoptimized expectedOptimized @@ -1073,226 +1218,217 @@ let ``Test Operator Declarations for Byte`` () = [] let ``Test Operator Declarations for SByte`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsSByte"; - "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,76)"; - "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,76)"; - "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,76)"; - "let testSByteAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; "let testSByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testSByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testSByteDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testSByteModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testSByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,57--19,67)"; - "let testSByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,57--20,67)"; - "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testSByteAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testSByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testSByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testSByteUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)"; - "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testSByteToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)"; - "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testSByteToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)"; - "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testSByteToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)"; - "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testSByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)"; - "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testSByteToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)"; - "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; - "let testSByteToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)"; + [], "type OperatorTestsSByte" + [], "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)" + [], "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)" + [], "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)" + [], "let testSByteAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testSByteSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testSByteMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testSByteDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testSByteModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testSByteShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,56--19,67)" + [], "let testSByteShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,56--20,67)" + [], "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testSByteAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testSByteSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testSByteMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testSByteUnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,45--27,60)" + [], "let testSByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testSByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testSByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testSByteToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testSByteToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testSByteToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testSByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testSByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testSByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testSByteToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testSByteToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testSByteToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testSByteToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testSByteToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testSByteToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testSByteToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testSByteToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,45--54,55)" + [], "let testSByteToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [], "let testSByteToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)" ] - let expectedOptimized = [ - "type OperatorTestsSByte"; - "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,76)"; - "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,76)"; - "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,76)"; - "let testSByteAdditionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Addition (e1,e2)) @ (11,59--11,67)"; - "let testSByteSubtractionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Subtraction (e1,e2)) @ (12,59--12,67)"; - "let testSByteMultiplyOperator(e1) (e2) = Operators.ToSByte (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)"; - "let testSByteDivisionOperator(e1) (e2) = Operators.ToSByte (Operators.op_Division (e1,e2)) @ (14,59--14,67)"; - "let testSByteModulusOperator(e1) (e2) = Operators.ToSByte (Operators.op_Modulus (e1,e2)) @ (15,59--15,67)"; - "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testSByteShiftLeftOperator(e1) (e2) = Operators.ToSByte (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (19,57--19,67)"; - "let testSByteShiftRightOperator(e1) (e2) = Operators.ToSByte (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,7))) @ (20,57--20,67)"; - "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testSByteAdditionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Addition (e1,e2)) @ (24,56--24,73)"; - "let testSByteSubtractionChecked(e1) (e2) = Checked.ToSByte (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)"; - "let testSByteMultiplyChecked(e1) (e2) = Checked.ToSByte (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)"; - "let testSByteUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)"; - "let testSByteToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testSByteToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testSByteToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testSByteToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)"; - "let testSByteToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testSByteToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testSByteToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testSByteToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testSByteToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testSByteToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)"; - "let testSByteToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testSByteToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testSByteToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)"; - "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testSByteToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)"; - "let testSByteToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testSByteToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testSByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)"; - "let testSByteToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; -#if DEBUG - @"let testSByteToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#else - "let testSByteToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#endif - ] + [], "type OperatorTestsSByte" + [], "let testSByteEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testSByteNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)" + [], "let testSByteLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testSByteLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)" + [], "let testSByteGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testSByteGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)" + [], "let testSByteAdditionOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (11,58--11,67)" + [], "let testSByteSubtractionOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (12,58--12,67)" + [], "let testSByteMultiplyOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (13,58--13,67)" + [], "let testSByteDivisionOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2)) @ (14,58--14,67)" + [], "let testSByteModulusOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2)) @ (15,58--15,67)" + [], "let testSByteBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testSByteBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testSByteBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testSByteShiftLeftOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,7))) @ (19,56--19,67)" + [], "let testSByteShiftRightOperator(e1) (e2) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,7))) @ (20,56--20,67)" + [], "let testSByteUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testSByteAdditionChecked(e1) (e2) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,56--24,73)" + [], "let testSByteSubtractionChecked(e1) (e2) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (25,56--25,73)" + [], "let testSByteMultiplyChecked(e1) (e2) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,56--26,73)" + [], "let testSByteUnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" + [], "let testSByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testSByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testSByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testSByteToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testSByteToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testSByteToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testSByteToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testSByteToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testSByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testSByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testSByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testSByteToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testSByteToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testSByteToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testSByteToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testSByteToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testSByteToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testSByteToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testSByteToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testSByteToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testSByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)" + [], "let testSByteToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [FC47; FC50], "let testSByteToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)" + ] testOperators "SByte" "sbyte" excludedTests expectedUnoptimized expectedOptimized [] let ``Test Operator Declarations for Int16`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsInt16"; - "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,76)"; - "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,76)"; - "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,76)"; - "let testInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; - "let testInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,57--19,67)"; - "let testInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,57--20,67)"; - "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testInt16UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)"; - "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)"; - "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)"; - "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)"; - "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)"; - "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; - "let testInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)"; + [], "type OperatorTestsInt16" + [], "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)" + [], "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)" + [], "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)" + [], "let testInt16AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testInt16DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,56--19,67)" + [], "let testInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,56--20,67)" + [], "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt16AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testInt16UnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,45--27,60)" + [], "let testInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt16ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt16ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt16ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt16ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt16ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,45--54,55)" + [], "let testInt16ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [], "let testInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)" ] - let expectedOptimized = [ - "type OperatorTestsInt16"; - "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,76)"; - "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,76)"; - "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,76)"; - "let testInt16AdditionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Addition (e1,e2)) @ (11,59--11,67)"; - "let testInt16SubtractionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Subtraction (e1,e2)) @ (12,59--12,67)"; - "let testInt16MultiplyOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Multiply (e1,e2)) @ (13,58--13,67)"; - "let testInt16DivisionOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Division (e1,e2)) @ (14,59--14,67)"; - "let testInt16ModulusOperator(e1) (e2) = Operators.ToInt16 (Operators.op_Modulus (e1,e2)) @ (15,59--15,67)"; - "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt16ShiftLeftOperator(e1) (e2) = Operators.ToInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,57--19,67)"; - "let testInt16ShiftRightOperator(e1) (e2) = Operators.ToInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,57--20,67)"; - "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt16AdditionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Addition (e1,e2)) @ (24,56--24,73)"; - "let testInt16SubtractionChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Subtraction (e1,e2)) @ (25,56--25,73)"; - "let testInt16MultiplyChecked(e1) (e2) = Checked.ToInt16 (Checked.op_Multiply (e1,e2)) @ (26,56--26,73)"; - "let testInt16UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)"; - "let testInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)"; - "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)"; - "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt16ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)"; - "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt16ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)"; - "let testInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; -#if DEBUG - @"let testInt16ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#else - "let testInt16ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#endif + [], "type OperatorTestsInt16" + [], "let testInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)" + [], "let testInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)" + [], "let testInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)" + [], "let testInt16AdditionOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (11,58--11,67)" + [], "let testInt16SubtractionOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (12,58--12,67)" + [], "let testInt16MultiplyOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (13,58--13,67)" + [], "let testInt16DivisionOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2)) @ (14,58--14,67)" + [], "let testInt16ModulusOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2)) @ (15,58--15,67)" + [], "let testInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt16ShiftLeftOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,15))) @ (19,56--19,67)" + [], "let testInt16ShiftRightOperator(e1) (e2) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,15))) @ (20,56--20,67)" + [], "let testInt16UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt16AdditionChecked(e1) (e2) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,56--24,73)" + [], "let testInt16SubtractionChecked(e1) (e2) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (25,56--25,73)" + [], "let testInt16MultiplyChecked(e1) (e2) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,56--26,73)" + [], "let testInt16UnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" + [], "let testInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt16ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt16ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt16ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt16ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testInt16ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt16ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt16ToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt16ToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt16ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt16ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)" + [], "let testInt16ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [FC47; FC50], "let testInt16ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)" ] testOperators "Int16" "int16" excludedTests expectedUnoptimized expectedOptimized @@ -1303,109 +1439,104 @@ let ``Test Operator Declarations for UInt16`` () = "testUInt16UnaryNegOperator"; "testUInt16UnaryNegChecked"; ] - + let expectedUnoptimized = [ - "type OperatorTestsUInt16"; - "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,70--5,79)"; - "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,70--7,79)"; - "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,70--9,79)"; - "let testUInt16AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testUInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,62--12,70)"; - "let testUInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)"; - "let testUInt16DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,62--14,70)"; - "let testUInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,62--15,70)"; - "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,59--19,69)"; - "let testUInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,59--20,69)"; - "let testUInt16AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testUInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)"; - "let testUInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)"; - "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt16ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)"; - "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt16ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)"; - "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt16ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)"; - "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testUInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)"; - "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)"; - "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)"; - "let testUInt16ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; - "let testUInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)"; + [], "type OperatorTestsUInt16" + [], "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)" + [], "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)" + [], "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)" + [], "let testUInt16AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testUInt16SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,61--12,70)" + [], "let testUInt16MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,61--13,70)" + [], "let testUInt16DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,61--14,70)" + [], "let testUInt16ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,61--15,70)" + [], "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,58--19,69)" + [], "let testUInt16ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,58--20,69)" + [], "let testUInt16AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testUInt16SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,59--25,76)" + [], "let testUInt16MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,59--26,76)" + [], "let testUInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt16ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt16ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt16ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testUInt16ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,47--52,57)" + [], "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,47--53,55)" + [], "let testUInt16ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,47--54,57)" + [], "let testUInt16ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [], "let testUInt16ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)" ] - let expectedOptimized = [ - "type OperatorTestsUInt16"; - "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,70--5,79)"; - "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,70--7,79)"; - "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,70--9,79)"; - "let testUInt16AdditionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Addition (e1,e2)) @ (11,62--11,70)"; - "let testUInt16SubtractionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Subtraction (e1,e2)) @ (12,62--12,70)"; - "let testUInt16MultiplyOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Multiply (e1,e2)) @ (13,61--13,70)"; - "let testUInt16DivisionOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Division (e1,e2)) @ (14,62--14,70)"; - "let testUInt16ModulusOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_Modulus (e1,e2)) @ (15,62--15,70)"; - "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (19,59--19,69)"; - "let testUInt16ShiftRightOperator(e1) (e2) = Operators.ToUInt16 (Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,15))) @ (20,59--20,69)"; - "let testUInt16AdditionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Addition (e1,e2)) @ (24,59--24,76)"; - "let testUInt16SubtractionChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Subtraction (e1,e2)) @ (25,59--25,76)"; - "let testUInt16MultiplyChecked(e1) (e2) = Checked.ToUInt16 (Checked.op_Multiply (e1,e2)) @ (26,59--26,76)"; - "let testUInt16ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt16ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)"; - "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt16ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt16ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)"; - "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt16ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)"; - "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testUInt16ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)"; - "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)"; - "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)"; - "let testUInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt16ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; -#if DEBUG - @"let testUInt16ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)" -#else - "let testUInt16ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"; -#endif + [], "type OperatorTestsUInt16" + [], "let testUInt16EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt16NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)" + [], "let testUInt16LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt16LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)" + [], "let testUInt16GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt16GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)" + [], "let testUInt16AdditionOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (11,61--11,70)" + [], "let testUInt16SubtractionOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (12,61--12,70)" + [], "let testUInt16MultiplyOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (13,61--13,70)" + [], "let testUInt16DivisionOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2)) @ (14,61--14,70)" + [], "let testUInt16ModulusOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2)) @ (15,61--15,70)" + [], "let testUInt16BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt16BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt16BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt16ShiftLeftOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,15))) @ (19,58--19,69)" + [], "let testUInt16ShiftRightOperator(e1) (e2) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,15))) @ (20,58--20,69)" + [], "let testUInt16AdditionChecked(e1) (e2) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,59--24,76)" + [], "let testUInt16SubtractionChecked(e1) (e2) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (25,59--25,76)" + [], "let testUInt16MultiplyChecked(e1) (e2) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,59--26,76)" + [], "let testUInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt16ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt16ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt16ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt16ToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt16ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testUInt16ToIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt16ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,47--52,57)" + [], "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,47--53,55)" + [], "let testUInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)" + [], "let testUInt16ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [FC47; FC50], "let testUInt16ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint16 = e1 in copyOfStruct.ToString() @ (56,47--56,56)" ] testOperators "UInt16" "uint16" excludedTests expectedUnoptimized expectedOptimized @@ -1413,113 +1544,108 @@ let ``Test Operator Declarations for UInt16`` () = [] let ``Test Operator Declarations for Int`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsInt"; - "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,61--4,69)"; - "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,61--5,70)"; - "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,61--6,69)"; - "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,61--7,70)"; - "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,61--8,69)"; - "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,61--9,70)"; - "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,53--11,61)"; - "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,53--12,61)"; - "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)"; - "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,53--14,61)"; - "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,53--15,61)"; - "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,53--16,63)"; - "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,53--17,63)"; - "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,53--18,63)"; - "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,53--19,63)"; - "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,53--20,63)"; - "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,42--22,48)"; - "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)"; - "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)"; - "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)"; - "let testIntUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,41--27,56)"; - "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)"; - "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)"; - "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)"; - "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)"; - "let testIntToIntChecked(e1) = Checked.ToInt (e1) @ (33,41--33,55)"; - "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)"; - "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)"; - "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)"; - "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)"; - "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)"; - "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)"; - "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)"; - "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)"; - "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)"; - "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)"; - "let testIntToIntOperator(e1) = Operators.ToInt (e1) @ (45,41--45,47)"; - "let testIntToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,41--46,49)"; - "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)"; - "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)"; - "let testIntToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,41--49,50)"; - "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)"; - "let testIntToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,41--51,54)"; - "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)"; - "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)"; - "let testIntToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,41--54,51)"; - "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)"; - "let testIntToStringOperator(e1) = Operators.ToString (e1) @ (56,41--56,50)"; + [], "type OperatorTestsInt" + [], "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)" + [], "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,60--5,70)" + [], "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)" + [], "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,60--7,70)" + [], "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)" + [], "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,60--9,70)" + [], "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,52--11,61)" + [], "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,52--12,61)" + [], "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,52--13,61)" + [], "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,52--14,61)" + [], "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,52--15,61)" + [], "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,52--16,63)" + [], "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,52--17,63)" + [], "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,52--18,63)" + [], "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,52--19,63)" + [], "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,52--20,63)" + [], "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,41--22,48)" + [], "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,50--24,67)" + [], "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,50--25,67)" + [], "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,50--26,67)" + [], "let testIntUnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,41--27,56)" + [], "let testIntToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,41--29,56)" + [], "let testIntToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,41--30,57)" + [], "let testIntToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,41--31,57)" + [], "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,41--32,58)" + [], "let testIntToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,41--33,55)" + [], "let testIntToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,41--34,57)" + [], "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,41--35,58)" + [], "let testIntToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,41--36,57)" + [], "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,41--37,58)" + [], "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,41--38,61)" + [], "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,41--39,62)" + [], "let testIntToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,41--41,48)" + [], "let testIntToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,41--42,49)" + [], "let testIntToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,41--43,49)" + [], "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,41--44,50)" + [], "let testIntToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,41--45,47)" + [], "let testIntToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,41--46,49)" + [], "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,41--47,50)" + [], "let testIntToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,41--48,49)" + [], "let testIntToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,41--49,50)" + [], "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,41--50,53)" + [], "let testIntToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,41--51,54)" + [], "let testIntToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,41--52,51)" + [], "let testIntToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,41--53,49)" + [], "let testIntToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,41--54,51)" + [], "let testIntToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,41--55,48)" + [], "let testIntToStringOperator(e1) = Operators.ToString (e1) @ (56,41--56,50)" ] - let expectedOptimized = [ - "type OperatorTestsInt"; - "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,61--4,69)"; - "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,61--5,70)"; - "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,61--6,69)"; - "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,61--7,70)"; - "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,61--8,69)"; - "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,61--9,70)"; - "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,53--11,61)"; - "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,53--12,61)"; - "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,52--13,61)"; - "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,53--14,61)"; - "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,53--15,61)"; - "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,53--16,63)"; - "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,53--17,63)"; - "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,53--18,63)"; - "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,53--19,63)"; - "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,53--20,63)"; - "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,42--22,48)"; - "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,50--24,67)"; - "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,50--25,67)"; - "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,50--26,67)"; - "let testIntUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,41--27,56)"; - "let testIntToByteChecked(e1) = Checked.ToByte (e1) @ (29,41--29,56)"; - "let testIntToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,41--30,57)"; - "let testIntToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,41--31,57)"; - "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,41--32,58)"; - "let testIntToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,41--33,55)"; - "let testIntToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,41--34,57)"; - "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,41--35,58)"; - "let testIntToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,41--36,57)"; - "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,41--37,58)"; - "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,41--38,61)"; - "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,41--39,62)"; - "let testIntToByteOperator(e1) = Operators.ToByte (e1) @ (41,41--41,48)"; - "let testIntToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,41--42,49)"; - "let testIntToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,41--43,49)"; - "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,41--44,50)"; - "let testIntToIntOperator(e1) = e1 @ (45,45--45,47)"; - "let testIntToInt32Operator(e1) = e1 @ (46,47--46,49)"; - "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,41--47,50)"; - "let testIntToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,41--48,49)"; - "let testIntToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,41--49,50)"; - "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,41--50,53)"; - "let testIntToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,41--51,54)"; - "let testIntToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,41--52,51)"; - "let testIntToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,41--53,49)"; - "let testIntToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,41--54,51)"; - "let testIntToCharOperator(e1) = Operators.ToChar (e1) @ (55,41--55,48)"; -#if DEBUG - @"let testIntToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,41--56,50)" -#else - "let testIntToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,41--56,50)"; -#endif + [], "type OperatorTestsInt" + [], "let testIntEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,60--4,69)" + [], "let testIntNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,60--5,70)" + [], "let testIntLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,60--6,69)" + [], "let testIntLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,60--7,70)" + [], "let testIntGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,60--8,69)" + [], "let testIntGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,60--9,70)" + [], "let testIntAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,52--11,61)" + [], "let testIntSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,52--12,61)" + [], "let testIntMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,52--13,61)" + [], "let testIntDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,52--14,61)" + [], "let testIntModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,52--15,61)" + [], "let testIntBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,52--16,63)" + [], "let testIntBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,52--17,63)" + [], "let testIntBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,52--18,63)" + [], "let testIntShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (19,52--19,63)" + [], "let testIntShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (20,52--20,63)" + [], "let testIntUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,41--22,48)" + [], "let testIntAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,50--24,67)" + [], "let testIntSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,50--25,67)" + [], "let testIntMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,50--26,67)" + [], "let testIntUnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,41--27,56)" + [], "let testIntToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,41--29,56)" + [], "let testIntToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,41--30,57)" + [], "let testIntToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,41--31,57)" + [], "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,41--32,58)" + [], "let testIntToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,41--33,55)" + [], "let testIntToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,41--34,57)" + [], "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,41--35,58)" + [], "let testIntToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,41--36,57)" + [], "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,41--37,58)" + [], "let testIntToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,41--38,61)" + [], "let testIntToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,41--39,62)" + [], "let testIntToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,41--41,48)" + [], "let testIntToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,41--42,49)" + [], "let testIntToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,41--43,49)" + [], "let testIntToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,41--44,50)" + [], "let testIntToIntOperator(e1) = e1 @ (45,45--45,47)" + [], "let testIntToInt32Operator(e1) = e1 @ (46,47--46,49)" + [], "let testIntToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,41--47,50)" + [], "let testIntToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,41--48,49)" + [], "let testIntToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,41--49,50)" + [], "let testIntToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,41--50,53)" + [], "let testIntToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,41--51,54)" + [], "let testIntToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,41--52,51)" + [], "let testIntToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,41--53,49)" + [], "let testIntToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,41--54,51)" + [], "let testIntToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,41--55,48)" + [FC47; FC50], "let testIntToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,41--56,50)" ] testOperators "Int" "int" excludedTests expectedUnoptimized expectedOptimized @@ -1527,115 +1653,111 @@ let ``Test Operator Declarations for Int`` () = [] let ``Test Operator Declarations for Int32`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsInt32"; - "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,76)"; - "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,76)"; - "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,76)"; - "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; - "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,57--19,67)"; - "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,57--20,67)"; - "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testInt32UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)"; - "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)"; - "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)"; - "let testInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)"; - "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)"; - "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; - "let testInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)"; + [], "type OperatorTestsInt32" + [], "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)" + [], "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)" + [], "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)" + [], "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,56--19,67)" + [], "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,56--20,67)" + [], "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testInt32UnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,45--27,60)" + [], "let testInt32ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt32ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt32ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt32ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt32ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt32ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testInt32ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt32ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt32ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt32ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,45--54,55)" + [], "let testInt32ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [], "let testInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)" ] - let expectedOptimized = [ - "type OperatorTestsInt32"; - "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,76)"; - "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,76)"; - "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,76)"; - "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; - "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,57--19,67)"; - "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,57--20,67)"; - "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testInt32UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)"; - "let testInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)"; - "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt32ToIntOperator(e1) = e1 @ (45,49--45,51)"; - "let testInt32ToInt32Operator(e1) = e1 @ (46,51--46,53)"; - "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt32ToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,45--49,54)"; - "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt32ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)"; - "let testInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; -#if DEBUG - @"let testInt32ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)" -#else - "let testInt32ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#endif + [], "type OperatorTestsInt32" + [], "let testInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)" + [], "let testInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)" + [], "let testInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)" + [], "let testInt32AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testInt32DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (19,56--19,67)" + [], "let testInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (20,56--20,67)" + [], "let testInt32UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt32AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testInt32UnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" + [], "let testInt32ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt32ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt32ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt32ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt32ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt32ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt32ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt32ToIntOperator(e1) = e1 @ (45,49--45,51)" + [], "let testInt32ToInt32Operator(e1) = e1 @ (46,51--46,53)" + [], "let testInt32ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt32ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt32ToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt32ToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt32ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt32ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)" + [], "let testInt32ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [FC47; FC50], "let testInt32ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)" ] + testOperators "Int32" "int32" excludedTests expectedUnoptimized expectedOptimized [] @@ -1644,109 +1766,104 @@ let ``Test Operator Declarations for UInt32`` () = "testUInt32UnaryNegOperator"; "testUInt32UnaryNegChecked"; ] - + let expectedUnoptimized = [ - "type OperatorTestsUInt32"; - "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,70--5,79)"; - "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,70--7,79)"; - "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,70--9,79)"; - "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,62--12,70)"; - "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)"; - "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,62--14,70)"; - "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,62--15,70)"; - "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,59--19,69)"; - "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,59--20,69)"; - "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)"; - "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)"; - "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt32ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)"; - "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt32ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)"; - "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt32ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)"; - "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testUInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)"; - "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)"; - "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)"; - "let testUInt32ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; - "let testUInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)"; + [], "type OperatorTestsUInt32" + [], "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)" + [], "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)" + [], "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)" + [], "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,61--12,70)" + [], "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,61--13,70)" + [], "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,61--14,70)" + [], "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,61--15,70)" + [], "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,58--19,69)" + [], "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,58--20,69)" + [], "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,59--25,76)" + [], "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,59--26,76)" + [], "let testUInt32ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt32ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt32ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt32ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt32ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testUInt32ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,47--52,57)" + [], "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,47--53,55)" + [], "let testUInt32ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,47--54,57)" + [], "let testUInt32ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [], "let testUInt32ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)" ] - let expectedOptimized = [ - "type OperatorTestsUInt32"; - "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,70--5,79)"; - "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,70--7,79)"; - "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,70--9,79)"; - "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,62--12,70)"; - "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)"; - "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,62--14,70)"; - "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,62--15,70)"; - "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (19,59--19,69)"; - "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,31)) @ (20,59--20,69)"; - "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)"; - "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)"; - "let testUInt32ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt32ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)"; - "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt32ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt32ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)"; - "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt32ToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,47--48,55)"; - "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testUInt32ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)"; - "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)"; - "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)"; - "let testUInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt32ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; -#if DEBUG - @"let testUInt32ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)" -#else - "let testUInt32ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"; -#endif + [], "type OperatorTestsUInt32" + [], "let testUInt32EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt32NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)" + [], "let testUInt32LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt32LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)" + [], "let testUInt32GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt32GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)" + [], "let testUInt32AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testUInt32SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,61--12,70)" + [], "let testUInt32MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,61--13,70)" + [], "let testUInt32DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,61--14,70)" + [], "let testUInt32ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,61--15,70)" + [], "let testUInt32BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt32BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt32BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt32ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (19,58--19,69)" + [], "let testUInt32ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,31)) @ (20,58--20,69)" + [], "let testUInt32AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testUInt32SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,59--25,76)" + [], "let testUInt32MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,59--26,76)" + [], "let testUInt32ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt32ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt32ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt32ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt32ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt32ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt32ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt32ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt32ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt32ToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testUInt32ToIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt32ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt32ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,47--52,57)" + [], "let testUInt32ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,47--53,55)" + [], "let testUInt32ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)" + [], "let testUInt32ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [FC47; FC50], "let testUInt32ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint32 = e1 in copyOfStruct.ToString() @ (56,47--56,56)" ] testOperators "UInt32" "uint32" excludedTests expectedUnoptimized expectedOptimized @@ -1754,115 +1871,111 @@ let ``Test Operator Declarations for UInt32`` () = [] let ``Test Operator Declarations for Int64`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsInt64"; - "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,76)"; - "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,76)"; - "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,76)"; - "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; - "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,57--19,67)"; - "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,57--20,67)"; - "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testInt64UnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,45--27,60)"; - "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,45--33,59)"; - "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,45--45,51)"; - "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)"; - "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,45--51,58)"; - "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; - "let testInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)"; + [], "type OperatorTestsInt64" + [], "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,66--5,76)" + [], "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,66--7,76)" + [], "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,66--9,76)" + [], "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,56--19,67)" + [], "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,56--20,67)" + [], "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testInt64UnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,45--27,60)" + [], "let testInt64ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt64ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt64ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt64ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt64ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt64ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt64ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt64ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,45--54,55)" + [], "let testInt64ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [], "let testInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,45--56,54)" ] - let expectedOptimized = [ - "type OperatorTestsInt64"; - "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,75)"; - "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,76)"; - "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,75)"; - "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,76)"; - "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,75)"; - "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,76)"; - "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,59--11,67)"; - "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,59--12,67)"; - "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,58--13,67)"; - "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,59--14,67)"; - "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,59--15,67)"; - "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,59--16,69)"; - "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,59--17,69)"; - "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,59--18,69)"; - "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,57--19,67)"; - "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,57--20,67)"; - "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,46--22,52)"; - "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,56--24,73)"; - "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,56--25,73)"; - "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,56--26,73)"; - "let testInt64UnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,45--27,60)"; - "let testInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,45--29,60)"; - "let testInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,45--30,61)"; - "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,45--31,61)"; - "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,45--32,62)"; - "let testInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,45--33,59)"; - "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,45--34,61)"; - "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,45--35,62)"; - "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,45--36,61)"; - "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,45--37,62)"; - "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,45--38,65)"; - "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,45--39,66)"; - "let testInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,45--41,52)"; - "let testInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,45--42,53)"; - "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,45--43,53)"; - "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,45--44,54)"; - "let testInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,45--45,51)"; - "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,45--46,53)"; - "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,45--47,54)"; - "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,45--48,53)"; - "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,45--49,54)"; - "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,45--50,57)"; - "let testInt64ToUIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (51,45--51,58)"; - "let testInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,45--52,55)"; - "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,45--53,53)"; - "let testInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)"; - "let testInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,45--55,52)"; -#if DEBUG - @"let testInt64ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)" -#else - "let testInt64ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,45--56,54)"; -#endif + [], "type OperatorTestsInt64" + [], "let testInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,66--4,75)" + [], "let testInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,66--5,76)" + [], "let testInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,66--6,75)" + [], "let testInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,66--7,76)" + [], "let testInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,66--8,75)" + [], "let testInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,66--9,76)" + [], "let testInt64AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,58--11,67)" + [], "let testInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,58--12,67)" + [], "let testInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,58--13,67)" + [], "let testInt64DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,58--14,67)" + [], "let testInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,58--15,67)" + [], "let testInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,58--16,69)" + [], "let testInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,58--17,69)" + [], "let testInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,58--18,69)" + [], "let testInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,63)) @ (19,56--19,67)" + [], "let testInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,63)) @ (20,56--20,67)" + [], "let testInt64UnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,45--22,52)" + [], "let testInt64AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,56--24,73)" + [], "let testInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,56--25,73)" + [], "let testInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,56--26,73)" + [], "let testInt64UnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" + [], "let testInt64ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" + [], "let testInt64ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testInt64ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt64ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" + [], "let testInt64ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" + [], "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" + [], "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" + [], "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" + [], "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" + [], "let testInt64ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" + [], "let testInt64ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testInt64ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt64ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" + [], "let testInt64ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" + [], "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" + [], "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" + [], "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" + [], "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" + [], "let testInt64ToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" + [], "let testInt64ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,45--52,55)" + [], "let testInt64ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,45--53,53)" + [], "let testInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,45--54,55)" + [], "let testInt64ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,45--55,52)" + [FC47; FC50], "let testInt64ToStringOperator(e1) = IntrinsicFunctions.UnboxGeneric (Operators.Box (e1)).ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,45--56,54)" ] + testOperators "Int64" "int64" excludedTests expectedUnoptimized expectedOptimized [] @@ -1871,109 +1984,104 @@ let ``Test Operator Declarations for UInt64`` () = "testUInt64UnaryNegOperator"; "testUInt64UnaryNegChecked"; ] - + let expectedUnoptimized = [ - "type OperatorTestsUInt64"; - "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,70--5,79)"; - "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,70--7,79)"; - "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,70--9,79)"; - "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,62--12,70)"; - "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)"; - "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,62--14,70)"; - "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,62--15,70)"; - "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,59--19,69)"; - "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,59--20,69)"; - "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)"; - "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)"; - "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt64ToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)"; - "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt64ToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)"; - "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)"; - "let testUInt64ToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testUInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,47--50,59)"; - "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)"; - "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)"; - "let testUInt64ToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; - "let testUInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)"; + [], "type OperatorTestsUInt64" + [], "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)" + [], "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)" + [], "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)" + [], "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,61--12,70)" + [], "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,61--13,70)" + [], "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,61--14,70)" + [], "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,61--15,70)" + [], "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,58--19,69)" + [], "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,58--20,69)" + [], "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,59--25,76)" + [], "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,59--26,76)" + [], "let testUInt64ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt64ToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt64ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt64ToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt64ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testUInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,47--52,57)" + [], "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,47--53,55)" + [], "let testUInt64ToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,47--54,57)" + [], "let testUInt64ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [], "let testUInt64ToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)" ] - let expectedOptimized = [ - "type OperatorTestsUInt64"; - "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,70--5,79)"; - "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,70--7,79)"; - "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,70--9,79)"; - "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,62--12,70)"; - "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,61--13,70)"; - "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,62--14,70)"; - "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,62--15,70)"; - "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,62--16,72)"; - "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,62--17,72)"; - "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,62--18,72)"; - "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (19,59--19,69)"; - "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,Operators.op_BitwiseAnd (e2,63)) @ (20,59--20,69)"; - "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,59--25,76)"; - "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,59--26,76)"; - "let testUInt64ToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testUInt64ToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,47--33,61)"; - "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,47--38,67)"; - "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,47--39,68)"; - "let testUInt64ToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testUInt64ToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,47--45,53)"; - "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)"; - "let testUInt64ToUInt64Operator(e1) = e1 @ (49,54--49,56)"; - "let testUInt64ToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,47--50,59)"; - "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,47--51,60)"; - "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,47--52,57)"; - "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,47--53,55)"; - "let testUInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)"; - "let testUInt64ToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; -#if DEBUG - @"let testUInt64ToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)" -#else - "let testUInt64ToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"; -#endif + [], "type OperatorTestsUInt64" + [], "let testUInt64EqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testUInt64NotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,69--5,79)" + [], "let testUInt64LessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testUInt64LessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,69--7,79)" + [], "let testUInt64GreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testUInt64GreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,69--9,79)" + [], "let testUInt64AdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testUInt64SubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,61--12,70)" + [], "let testUInt64MultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,61--13,70)" + [], "let testUInt64DivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,61--14,70)" + [], "let testUInt64ModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,61--15,70)" + [], "let testUInt64BitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,61--16,72)" + [], "let testUInt64BitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,61--17,72)" + [], "let testUInt64BitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,61--18,72)" + [], "let testUInt64ShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,63)) @ (19,58--19,69)" + [], "let testUInt64ShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e2,63)) @ (20,58--20,69)" + [], "let testUInt64AdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testUInt64SubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,59--25,76)" + [], "let testUInt64MultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,59--26,76)" + [], "let testUInt64ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testUInt64ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testUInt64ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testUInt64ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt64ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" + [], "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt64ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testUInt64ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testUInt64ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testUInt64ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt64ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testUInt64ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testUInt64ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt64ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testUInt64ToUInt64Operator(e1) = e1 @ (49,54--49,56)" + [], "let testUInt64ToIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" + [], "let testUInt64ToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,47--51,60)" + [], "let testUInt64ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,47--52,57)" + [], "let testUInt64ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,47--53,55)" + [], "let testUInt64ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)" + [], "let testUInt64ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [FC47; FC50], "let testUInt64ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint64 = e1 in copyOfStruct.ToString() @ (56,47--56,56)" ] testOperators "UInt64" "uint64" excludedTests expectedUnoptimized expectedOptimized @@ -1981,113 +2089,108 @@ let ``Test Operator Declarations for UInt64`` () = [] let ``Test Operator Declarations for IntPtr`` () = let excludedTests = [ ] - + let expectedUnoptimized = [ - "type OperatorTestsIntPtr"; - "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,76--4,84)"; - "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,76--5,85)"; - "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,76--6,84)"; - "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,76--7,85)"; - "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,76--8,84)"; - "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,76--9,85)"; - "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,68--11,76)"; - "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,68--12,76)"; - "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)"; - "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,68--14,76)"; - "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,68--15,76)"; - "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,68--16,78)"; - "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,68--17,78)"; - "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,68--18,78)"; - "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,62--19,72)"; - "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,62--20,72)"; - "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,51--22,57)"; - "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)"; - "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)"; - "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)"; - "let testIntPtrUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,50--27,65)"; - "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)"; - "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)"; - "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)"; - "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)"; - "let testIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,50--33,64)"; - "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)"; - "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)"; - "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)"; - "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)"; - "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)"; - "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)"; - "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)"; - "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)"; - "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)"; - "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)"; - "let testIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,50--45,56)"; - "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)"; - "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)"; - "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)"; - "let testIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,50--49,59)"; - "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)"; - "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)"; - "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)"; - "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)"; - "let testIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,50--54,60)"; - "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)"; - "let testIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,50--56,59)"; + [], "type OperatorTestsIntPtr" + [], "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)" + [], "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,75--5,85)" + [], "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)" + [], "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,75--7,85)" + [], "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)" + [], "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,75--9,85)" + [], "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,67--11,76)" + [], "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,67--12,76)" + [], "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,67--13,76)" + [], "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,67--14,76)" + [], "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,67--15,76)" + [], "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,67--16,78)" + [], "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,67--17,78)" + [], "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,67--18,78)" + [], "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,61--19,72)" + [], "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,61--20,72)" + [], "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,50--22,57)" + [], "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,65--24,82)" + [], "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,65--25,82)" + [], "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,65--26,82)" + [], "let testIntPtrUnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,50--27,65)" + [], "let testIntPtrToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,50--29,65)" + [], "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,50--30,66)" + [], "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,50--31,66)" + [], "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,50--32,67)" + [], "let testIntPtrToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,50--33,64)" + [], "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,50--34,66)" + [], "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,50--35,67)" + [], "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,50--36,66)" + [], "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,50--37,67)" + [], "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,50--38,70)" + [], "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,50--39,71)" + [], "let testIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,50--41,57)" + [], "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,50--42,58)" + [], "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,50--43,58)" + [], "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,50--44,59)" + [], "let testIntPtrToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,50--45,56)" + [], "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,50--46,58)" + [], "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,50--47,59)" + [], "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,50--48,58)" + [], "let testIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,50--49,59)" + [], "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,50--50,62)" + [], "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,50--51,63)" + [], "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,50--52,60)" + [], "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,50--53,58)" + [], "let testIntPtrToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,50--54,60)" + [], "let testIntPtrToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,50--55,57)" + [], "let testIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,50--56,59)" ] - let expectedOptimized = [ - "type OperatorTestsIntPtr"; - "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,76--4,84)"; - "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,76--5,85)"; - "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,76--6,84)"; - "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,76--7,85)"; - "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,76--8,84)"; - "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,76--9,85)"; - "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,68--11,76)"; - "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,68--12,76)"; - "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,67--13,76)"; - "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,68--14,76)"; - "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,68--15,76)"; - "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,68--16,78)"; - "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,68--17,78)"; - "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,68--18,78)"; - "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,62--19,72)"; - "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,62--20,72)"; - "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,51--22,57)"; - "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,65--24,82)"; - "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,65--25,82)"; - "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,65--26,82)"; - "let testIntPtrUnaryNegChecked(e1) = Checked.op_Subtraction (0,e1) @ (27,50--27,65)"; - "let testIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,50--29,65)"; - "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,50--30,66)"; - "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,50--31,66)"; - "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,50--32,67)"; - "let testIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,50--33,64)"; - "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,50--34,66)"; - "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,50--35,67)"; - "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,50--36,66)"; - "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,50--37,67)"; - "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,50--38,70)"; - "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,50--39,71)"; - "let testIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,50--41,57)"; - "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,50--42,58)"; - "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,50--43,58)"; - "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,50--44,59)"; - "let testIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,50--45,56)"; - "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,50--46,58)"; - "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,50--47,59)"; - "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,50--48,58)"; - "let testIntPtrToUInt64Operator(e1) = Operators.ToInt64 (e1) @ (49,50--49,59)"; - "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,50--50,62)"; - "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,50--51,63)"; - "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,50--52,60)"; - "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,50--53,58)"; - "let testIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToInt64 (e1)) @ (54,50--54,60)"; - "let testIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,50--55,57)"; -#if DEBUG - @"let testIntPtrToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,50--56,59)" -#else - "let testIntPtrToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,50--56,59)"; -#endif + [], "type OperatorTestsIntPtr" + [], "let testIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,75--4,84)" + [], "let testIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,75--5,85)" + [], "let testIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,75--6,84)" + [], "let testIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,75--7,85)" + [], "let testIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,75--8,84)" + [], "let testIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,75--9,85)" + [], "let testIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,67--11,76)" + [], "let testIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,67--12,76)" + [], "let testIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,67--13,76)" + [], "let testIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,67--14,76)" + [], "let testIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,67--15,76)" + [], "let testIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,67--16,78)" + [], "let testIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,67--17,78)" + [], "let testIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,67--18,78)" + [], "let testIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,61--19,72)" + [], "let testIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,61--20,72)" + [], "let testIntPtrUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,50--22,57)" + [], "let testIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,65--24,82)" + [], "let testIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,65--25,82)" + [], "let testIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,65--26,82)" + [], "let testIntPtrUnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,50--27,65)" + [], "let testIntPtrToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,50--29,65)" + [], "let testIntPtrToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,50--30,66)" + [], "let testIntPtrToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,50--31,66)" + [], "let testIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,50--32,67)" + [], "let testIntPtrToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,50--33,64)" + [], "let testIntPtrToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,50--34,66)" + [], "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,50--35,67)" + [], "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,50--36,66)" + [], "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,50--37,67)" + [], "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,50--38,70)" + [], "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,50--39,71)" + [], "let testIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,50--41,57)" + [], "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,50--42,58)" + [], "let testIntPtrToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,50--43,58)" + [], "let testIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,50--44,59)" + [], "let testIntPtrToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,50--45,56)" + [], "let testIntPtrToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,50--46,58)" + [], "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,50--47,59)" + [], "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,50--48,58)" + [], "let testIntPtrToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,50--49,59)" + [], "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,50--50,62)" + [], "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,50--51,63)" + [], "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,50--52,60)" + [], "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,50--53,58)" + [], "let testIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (54,50--54,60)" + [], "let testIntPtrToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,50--55,57)" + [FC47; FC50], "let testIntPtrToStringOperator(e1) = e1.ToString() @ (56,50--56,59)" ] testOperators "IntPtr" "nativeint" excludedTests expectedUnoptimized expectedOptimized @@ -2098,109 +2201,104 @@ let ``Test Operator Declarations for UIntPtr`` () = "testUIntPtrUnaryNegOperator"; "testUIntPtrUnaryNegChecked"; ] - + let expectedUnoptimized = [ - "type OperatorTestsUIntPtr"; - "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,79--4,87)"; - "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,79--5,88)"; - "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,79--6,87)"; - "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,79--7,88)"; - "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,79--8,87)"; - "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,79--9,88)"; - "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,71--11,79)"; - "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,71--12,79)"; - "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)"; - "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,71--14,79)"; - "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,71--15,79)"; - "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,71--16,81)"; - "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,71--17,81)"; - "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,71--18,81)"; - "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,64--19,74)"; - "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,64--20,74)"; - "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)"; - "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)"; - "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)"; - "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)"; - "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)"; - "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)"; - "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)"; - "let testUIntPtrToIntChecked(e1) = Checked.ToInt (e1) @ (33,52--33,66)"; - "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)"; - "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)"; - "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)"; - "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)"; - "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)"; - "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)"; - "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)"; - "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)"; - "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)"; - "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)"; - "let testUIntPtrToIntOperator(e1) = Operators.ToInt (e1) @ (45,52--45,58)"; - "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)"; - "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)"; - "let testUIntPtrToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,52--48,60)"; - "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)"; - "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)"; - "let testUIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,52--51,65)"; - "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,52--52,62)"; - "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,52--53,60)"; - "let testUIntPtrToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,52--54,62)"; - "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)"; - "let testUIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,52--56,61)"; + [], "type OperatorTestsUIntPtr" + [], "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)" + [], "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,78--5,88)" + [], "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)" + [], "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,78--7,88)" + [], "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)" + [], "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,78--9,88)" + [], "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,70--11,79)" + [], "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,70--12,79)" + [], "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,70--13,79)" + [], "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,70--14,79)" + [], "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,70--15,79)" + [], "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,70--16,81)" + [], "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,70--17,81)" + [], "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,70--18,81)" + [], "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,63--19,74)" + [], "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,63--20,74)" + [], "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,68--24,85)" + [], "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,68--25,85)" + [], "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,68--26,85)" + [], "let testUIntPtrToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,52--29,67)" + [], "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,52--30,68)" + [], "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,52--31,68)" + [], "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,52--32,69)" + [], "let testUIntPtrToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,52--33,66)" + [], "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,52--34,68)" + [], "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,52--35,69)" + [], "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,52--36,68)" + [], "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,52--37,69)" + [], "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,52--38,72)" + [], "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,52--39,73)" + [], "let testUIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,52--41,59)" + [], "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,52--42,60)" + [], "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,52--43,60)" + [], "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,52--44,61)" + [], "let testUIntPtrToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,52--45,58)" + [], "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,52--46,60)" + [], "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,52--47,61)" + [], "let testUIntPtrToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,52--48,60)" + [], "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,52--49,61)" + [], "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,52--50,64)" + [], "let testUIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,52--51,65)" + [], "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,52--52,62)" + [], "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,52--53,60)" + [], "let testUIntPtrToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,52--54,62)" + [], "let testUIntPtrToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,52--55,59)" + [], "let testUIntPtrToStringOperator(e1) = Operators.ToString (e1) @ (56,52--56,61)" ] - let expectedOptimized = [ - "type OperatorTestsUIntPtr"; - "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,79--4,87)"; - "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,79--5,88)"; - "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,79--6,87)"; - "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,79--7,88)"; - "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,79--8,87)"; - "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,79--9,88)"; - "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,71--11,79)"; - "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,71--12,79)"; - "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,70--13,79)"; - "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,71--14,79)"; - "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,71--15,79)"; - "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (e1,e2) @ (16,71--16,81)"; - "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (e1,e2) @ (17,71--17,81)"; - "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (e1,e2) @ (18,71--18,81)"; - "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (e1,e2) @ (19,64--19,74)"; - "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (e1,e2) @ (20,64--20,74)"; - "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,68--24,85)"; - "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,68--25,85)"; - "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,68--26,85)"; - "let testUIntPtrToByteChecked(e1) = Checked.ToByte (e1) @ (29,52--29,67)"; - "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,52--30,68)"; - "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,52--31,68)"; - "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,52--32,69)"; - "let testUIntPtrToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,52--33,66)"; - "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,52--34,68)"; - "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,52--35,69)"; - "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,52--36,68)"; - "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,52--37,69)"; - "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,52--38,72)"; - "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,52--39,73)"; - "let testUIntPtrToByteOperator(e1) = Operators.ToByte (e1) @ (41,52--41,59)"; - "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,52--42,60)"; - "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,52--43,60)"; - "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,52--44,61)"; - "let testUIntPtrToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,52--45,58)"; - "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,52--46,60)"; - "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,52--47,61)"; - "let testUIntPtrToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,52--48,60)"; - "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,52--49,61)"; - "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,52--50,64)"; - "let testUIntPtrToUIntPtrOperator(e1) = e1 @ (51,63--51,65)"; - "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,52--52,62)"; - "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,52--53,60)"; - "let testUIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToUInt64 (e1)) @ (54,52--54,62)"; - "let testUIntPtrToCharOperator(e1) = Operators.ToChar (e1) @ (55,52--55,59)"; -#if DEBUG - @"let testUIntPtrToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,52--56,61)" -#else - "let testUIntPtrToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,52--56,61)"; -#endif + [], "type OperatorTestsUIntPtr" + [], "let testUIntPtrEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,78--4,87)" + [], "let testUIntPtrNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,78--5,88)" + [], "let testUIntPtrLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,78--6,87)" + [], "let testUIntPtrLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,78--7,88)" + [], "let testUIntPtrGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,78--8,87)" + [], "let testUIntPtrGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,78--9,88)" + [], "let testUIntPtrAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,70--11,79)" + [], "let testUIntPtrSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,70--12,79)" + [], "let testUIntPtrMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,70--13,79)" + [], "let testUIntPtrDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,70--14,79)" + [], "let testUIntPtrModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,70--15,79)" + [], "let testUIntPtrBitwiseAndOperator(e1) (e2) = Operators.op_BitwiseAnd (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseAndDynamic (arg0_0,arg1_0),e1,e2) @ (16,70--16,81)" + [], "let testUIntPtrBitwiseOrOperator(e1) (e2) = Operators.op_BitwiseOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.BitwiseOrDynamic (arg0_0,arg1_0),e1,e2) @ (17,70--17,81)" + [], "let testUIntPtrBitwiseXorOperator(e1) (e2) = Operators.op_ExclusiveOr (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ExclusiveOrDynamic (arg0_0,arg1_0),e1,e2) @ (18,70--18,81)" + [], "let testUIntPtrShiftLeftOperator(e1) (e2) = Operators.op_LeftShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.LeftShiftDynamic (arg0_0,arg1_0),e1,e2) @ (19,63--19,74)" + [], "let testUIntPtrShiftRightOperator(e1) (e2) = Operators.op_RightShift (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.RightShiftDynamic (arg0_0,arg1_0),e1,e2) @ (20,63--20,74)" + [], "let testUIntPtrAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,68--24,85)" + [], "let testUIntPtrSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,68--25,85)" + [], "let testUIntPtrMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,68--26,85)" + [], "let testUIntPtrToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,52--29,67)" + [], "let testUIntPtrToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,52--30,68)" + [], "let testUIntPtrToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,52--31,68)" + [], "let testUIntPtrToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,52--32,69)" + [], "let testUIntPtrToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,52--33,66)" + [], "let testUIntPtrToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,52--34,68)" + [], "let testUIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,52--35,69)" + [], "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,52--36,68)" + [], "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,52--37,69)" + [], "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,52--38,72)" + [], "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,52--39,73)" + [], "let testUIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,52--41,59)" + [], "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,52--42,60)" + [], "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,52--43,60)" + [], "let testUIntPtrToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,52--44,61)" + [], "let testUIntPtrToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,52--45,58)" + [], "let testUIntPtrToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,52--46,60)" + [], "let testUIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,52--47,61)" + [], "let testUIntPtrToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,52--48,60)" + [], "let testUIntPtrToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,52--49,61)" + [], "let testUIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,52--50,64)" + [], "let testUIntPtrToUIntPtrOperator(e1) = e1 @ (51,63--51,65)" + [], "let testUIntPtrToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,52--52,62)" + [], "let testUIntPtrToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,52--53,60)" + [], "let testUIntPtrToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (54,52--54,62)" + [], "let testUIntPtrToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,52--55,59)" + [FC47; FC50], "let testUIntPtrToStringOperator(e1) = e1.ToString() @ (56,52--56,61)" ] testOperators "UIntPtr" "unativeint" excludedTests expectedUnoptimized expectedOptimized @@ -2216,105 +2314,205 @@ let ``Test Operator Declarations for Single`` () = ] let expectedUnoptimized = [ - "type OperatorTestsSingle"; - "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,72--4,80)"; - "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,72--5,81)"; - "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,72--6,80)"; - "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,72--7,81)"; - "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,72--8,80)"; - "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,81)"; - "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,64--11,72)"; - "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,64--12,72)"; - "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)"; - "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,64--14,72)"; - "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,64--15,72)"; - "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,49--22,55)"; - "let testSingleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,61--24,78)"; - "let testSingleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,61--25,78)"; - "let testSingleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,61--26,78)"; - "let testSingleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,48--27,63)"; - "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)"; - "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)"; - "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)"; - "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)"; - "let testSingleToIntChecked(e1) = Checked.ToInt (e1) @ (33,48--33,62)"; - "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)"; - "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)"; - "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)"; - "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)"; - "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)"; - "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)"; - "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)"; - "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)"; - "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)"; - "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)"; - "let testSingleToIntOperator(e1) = Operators.ToInt (e1) @ (45,48--45,54)"; - "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)"; - "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)"; - "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)"; - "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)"; - "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)"; - "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)"; - "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)"; - "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)"; - "let testSingleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,48--54,58)"; - "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)"; - "let testSingleToStringOperator(e1) = Operators.ToString (e1) @ (56,48--56,57)"; + [], "type OperatorTestsSingle" + [], "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)" + [], "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,71--5,81)" + [], "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)" + [], "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,71--7,81)" + [], "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)" + [], "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,71--9,81)" + [], "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,63--11,72)" + [], "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,63--12,72)" + [], "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,63--13,72)" + [], "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,63--14,72)" + [], "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,63--15,72)" + [], "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,48--22,55)" + [], "let testSingleAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,61--24,78)" + [], "let testSingleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,61--25,78)" + [], "let testSingleMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,61--26,78)" + [], "let testSingleUnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,48--27,63)" + [], "let testSingleToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,48--29,63)" + [], "let testSingleToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,48--30,64)" + [], "let testSingleToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,48--31,64)" + [], "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,48--32,65)" + [], "let testSingleToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,48--33,62)" + [], "let testSingleToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,48--34,64)" + [], "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,48--35,65)" + [], "let testSingleToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,48--36,64)" + [], "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,48--37,65)" + [], "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,48--38,68)" + [], "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,48--39,69)" + [], "let testSingleToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,48--41,55)" + [], "let testSingleToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,48--42,56)" + [], "let testSingleToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,48--43,56)" + [], "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,48--44,57)" + [], "let testSingleToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,48--45,54)" + [], "let testSingleToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,48--46,56)" + [], "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,48--47,57)" + [], "let testSingleToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,48--48,56)" + [], "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,48--49,57)" + [], "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,48--50,60)" + [], "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,48--51,61)" + [], "let testSingleToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,48--52,58)" + [], "let testSingleToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,48--53,56)" + [], "let testSingleToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,48--54,58)" + [], "let testSingleToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,48--55,55)" + [], "let testSingleToStringOperator(e1) = Operators.ToString (e1) @ (56,48--56,57)" ] - let expectedOptimized = [ - "type OperatorTestsSingle"; - "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,72--4,80)"; - "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,72--5,81)"; - "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,72--6,80)"; - "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,72--7,81)"; - "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,72--8,80)"; - "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,72--9,81)"; - "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,64--11,72)"; - "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,64--12,72)"; - "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,63--13,72)"; - "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,64--14,72)"; - "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,64--15,72)"; - "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,49--22,55)"; - "let testSingleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,61--24,78)"; - "let testSingleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,61--25,78)"; - "let testSingleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,61--26,78)"; - "let testSingleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,48--27,63)"; - "let testSingleToByteChecked(e1) = Checked.ToByte (e1) @ (29,48--29,63)"; - "let testSingleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,48--30,64)"; - "let testSingleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,48--31,64)"; - "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,48--32,65)"; - "let testSingleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,48--33,62)"; - "let testSingleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,48--34,64)"; - "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,48--35,65)"; - "let testSingleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,48--36,64)"; - "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,48--37,65)"; - "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,48--38,68)"; - "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,48--39,69)"; - "let testSingleToByteOperator(e1) = Operators.ToByte (e1) @ (41,48--41,55)"; - "let testSingleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,48--42,56)"; - "let testSingleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,48--43,56)"; - "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,48--44,57)"; - "let testSingleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,48--45,54)"; - "let testSingleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,48--46,56)"; - "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,48--47,57)"; - "let testSingleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,48--48,56)"; - "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,48--49,57)"; - "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,48--50,60)"; - "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,48--51,61)"; - "let testSingleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,48--52,58)"; - "let testSingleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,48--53,56)"; - "let testSingleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,48--54,58)"; - "let testSingleToCharOperator(e1) = Operators.ToChar (e1) @ (55,48--55,55)"; -#if DEBUG - @"let testSingleToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,48--56,57)" -#else - "let testSingleToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,48--56,57)"; -#endif + [], "type OperatorTestsSingle" + [], "let testSingleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,71--4,80)" + [], "let testSingleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,71--5,81)" + [], "let testSingleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,71--6,80)" + [], "let testSingleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,71--7,81)" + [], "let testSingleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,71--8,80)" + [], "let testSingleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,71--9,81)" + [], "let testSingleAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,63--11,72)" + [], "let testSingleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,63--12,72)" + [], "let testSingleMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,63--13,72)" + [], "let testSingleDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,63--14,72)" + [], "let testSingleModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,63--15,72)" + [], "let testSingleUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,48--22,55)" + [], "let testSingleAdditionChecked(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,61--24,78)" + [], "let testSingleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,61--25,78)" + [], "let testSingleMultiplyChecked(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,61--26,78)" + [], "let testSingleUnaryNegChecked(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,48--27,63)" + [], "let testSingleToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,48--29,63)" + [], "let testSingleToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,48--30,64)" + [], "let testSingleToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,48--31,64)" + [], "let testSingleToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,48--32,65)" + [], "let testSingleToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,48--33,62)" + [], "let testSingleToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,48--34,64)" + [], "let testSingleToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,48--35,65)" + [], "let testSingleToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,48--36,64)" + [], "let testSingleToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,48--37,65)" + [], "let testSingleToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,48--38,68)" + [], "let testSingleToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,48--39,69)" + [], "let testSingleToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,48--41,55)" + [], "let testSingleToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,48--42,56)" + [], "let testSingleToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,48--43,56)" + [], "let testSingleToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,48--44,57)" + [], "let testSingleToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,48--45,54)" + [], "let testSingleToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,48--46,56)" + [], "let testSingleToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,48--47,57)" + [], "let testSingleToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,48--48,56)" + [], "let testSingleToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,48--49,57)" + [], "let testSingleToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,48--50,60)" + [], "let testSingleToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,48--51,61)" + [], "let testSingleToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,48--52,58)" + [], "let testSingleToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,48--53,56)" + [], "let testSingleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,48--54,58)" + [], "let testSingleToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,48--55,55)" + [FC47; FC50], "let testSingleToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,48--56,57)" ] testOperators "Single" "float32" excludedTests expectedUnoptimized expectedOptimized +[] +let ``Test Operator Declarations for Single with unit of measure`` () = + let excludedTests = [ + "testSingleUnitizedBitwiseAndOperator"; + "testSingleUnitizedBitwiseOrOperator"; + "testSingleUnitizedBitwiseXorOperator"; + "testSingleUnitizedShiftLeftOperator"; + "testSingleUnitizedShiftRightOperator"; + ] + + let expectedUnoptimized = [ + [], "type OperatorTestsSingleUnitized" + [], "let testSingleUnitizedEqualsOperator(e1) (e2) = Operators.op_Equality> (e1,e2) @ (4,163--4,172)" + [], "let testSingleUnitizedNotEqualsOperator(e1) (e2) = Operators.op_Inequality> (e1,e2) @ (5,163--5,173)" + [], "let testSingleUnitizedLessThanOperator(e1) (e2) = Operators.op_LessThan> (e1,e2) @ (6,163--6,172)" + [], "let testSingleUnitizedLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual> (e1,e2) @ (7,163--7,173)" + [], "let testSingleUnitizedGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan> (e1,e2) @ (8,163--8,172)" + [], "let testSingleUnitizedGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual> (e1,e2) @ (9,163--9,173)" + [], "let testSingleUnitizedAdditionOperator(e1) (e2) = Operators.op_Addition,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (11,155--11,164)" + [], "let testSingleUnitizedSubtractionOperator(e1) (e2) = Operators.op_Subtraction,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (12,155--12,164)" + [], "let testSingleUnitizedMultiplyOperator(e1) (e2) = Operators.op_Multiply,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (13,155--13,164)" + [], "let testSingleUnitizedDivisionOperator(e1) (e2) = Operators.op_Division,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (14,155--14,164)" + [], "let testSingleUnitizedModulusOperator(e1) (e2) = Operators.op_Modulus,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (15,155--15,164)" + [], "let testSingleUnitizedUnaryNegOperator(e1) = Operators.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (22,98--22,105)" + [], "let testSingleUnitizedAdditionChecked(e1) (e2) = Checked.op_Addition,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (24,153--24,170)" + [], "let testSingleUnitizedSubtractionChecked(e1) (e2) = Checked.op_Subtraction,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (25,153--25,170)" + [], "let testSingleUnitizedMultiplyChecked(e1) (e2) = Checked.op_Multiply,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (26,153--26,170)" + [], "let testSingleUnitizedUnaryNegChecked(e1) = Checked.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (27,98--27,113)" + [], "let testSingleUnitizedToByteChecked(e1) = Checked.ToByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.byte> (arg0_0),e1) @ (29,98--29,113)" + [], "let testSingleUnitizedToSByteChecked(e1) = Checked.ToSByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.sbyte> (arg0_0),e1) @ (30,98--30,114)" + [], "let testSingleUnitizedToInt16Checked(e1) = Checked.ToInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int16> (arg0_0),e1) @ (31,98--31,114)" + [], "let testSingleUnitizedToUInt16Checked(e1) = Checked.ToUInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint16> (arg0_0),e1) @ (32,98--32,115)" + [], "let testSingleUnitizedToIntChecked(e1) = Checked.ToInt> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int> (arg0_0),e1) @ (33,98--33,112)" + [], "let testSingleUnitizedToInt32Checked(e1) = Checked.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (34,98--34,114)" + [], "let testSingleUnitizedToUInt32Checked(e1) = Checked.ToUInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint32> (arg0_0),e1) @ (35,98--35,115)" + [], "let testSingleUnitizedToInt64Checked(e1) = Checked.ToInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int64> (arg0_0),e1) @ (36,98--36,114)" + [], "let testSingleUnitizedToUInt64Checked(e1) = Checked.ToUInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint64> (arg0_0),e1) @ (37,98--37,115)" + [], "let testSingleUnitizedToIntPtrChecked(e1) = Checked.ToIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.nativeint> (arg0_0),e1) @ (38,98--38,118)" + [], "let testSingleUnitizedToUIntPtrChecked(e1) = Checked.ToUIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.unativeint> (arg0_0),e1) @ (39,98--39,119)" + [], "let testSingleUnitizedToByteOperator(e1) = Operators.ToByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.byte> (arg0_0),e1) @ (41,98--41,105)" + [], "let testSingleUnitizedToSByteOperator(e1) = Operators.ToSByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.sbyte> (arg0_0),e1) @ (42,98--42,106)" + [], "let testSingleUnitizedToInt16Operator(e1) = Operators.ToInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int16> (arg0_0),e1) @ (43,98--43,106)" + [], "let testSingleUnitizedToUInt16Operator(e1) = Operators.ToUInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint16> (arg0_0),e1) @ (44,98--44,107)" + [], "let testSingleUnitizedToIntOperator(e1) = Operators.ToInt> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int> (arg0_0),e1) @ (45,98--45,104)" + [], "let testSingleUnitizedToInt32Operator(e1) = Operators.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (46,98--46,106)" + [], "let testSingleUnitizedToUInt32Operator(e1) = Operators.ToUInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint32> (arg0_0),e1) @ (47,98--47,107)" + [], "let testSingleUnitizedToInt64Operator(e1) = Operators.ToInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int64> (arg0_0),e1) @ (48,98--48,106)" + [], "let testSingleUnitizedToUInt64Operator(e1) = Operators.ToUInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint64> (arg0_0),e1) @ (49,98--49,107)" + [], "let testSingleUnitizedToIntPtrOperator(e1) = Operators.ToIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.nativeint> (arg0_0),e1) @ (50,98--50,110)" + [], "let testSingleUnitizedToUIntPtrOperator(e1) = Operators.ToUIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.unativeint> (arg0_0),e1) @ (51,98--51,111)" + [], "let testSingleUnitizedToSingleOperator(e1) = Operators.ToSingle> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (52,98--52,108)" + [], "let testSingleUnitizedToDoubleOperator(e1) = Operators.ToDouble> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float> (arg0_0),e1) @ (53,98--53,106)" + [], "let testSingleUnitizedToDecimalOperator(e1) = Operators.ToDecimal> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.decimal> (arg0_0),e1) @ (54,98--54,108)" + [], "let testSingleUnitizedToCharOperator(e1) = Operators.ToChar> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.char> (arg0_0),e1) @ (55,98--55,105)" + [], "let testSingleUnitizedToStringOperator(e1) = Operators.ToString> (e1) @ (56,98--56,107)" + ] + let expectedOptimized = [ + [], "type OperatorTestsSingleUnitized" + [], "let testSingleUnitizedEqualsOperator(e1) (e2) = Operators.op_Equality> (e1,e2) @ (4,163--4,172)" + [], "let testSingleUnitizedNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality> (e1,e2),False) @ (5,163--5,173)" + [], "let testSingleUnitizedLessThanOperator(e1) (e2) = Operators.op_LessThan> (e1,e2) @ (6,163--6,172)" + [], "let testSingleUnitizedLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan> (e1,e2),False) @ (7,163--7,173)" + [], "let testSingleUnitizedGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan> (e1,e2) @ (8,163--8,172)" + [], "let testSingleUnitizedGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan> (e1,e2),False) @ (9,163--9,173)" + [], "let testSingleUnitizedAdditionOperator(e1) (e2) = Operators.op_Addition,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (11,155--11,164)" + [], "let testSingleUnitizedSubtractionOperator(e1) (e2) = Operators.op_Subtraction,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (12,155--12,164)" + [], "let testSingleUnitizedMultiplyOperator(e1) (e2) = Operators.op_Multiply,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (13,155--13,164)" + [], "let testSingleUnitizedDivisionOperator(e1) (e2) = Operators.op_Division,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (14,155--14,164)" + [], "let testSingleUnitizedModulusOperator(e1) (e2) = Operators.op_Modulus,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (15,155--15,164)" + [], "let testSingleUnitizedUnaryNegOperator(e1) = Operators.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (22,98--22,105)" + [], "let testSingleUnitizedAdditionChecked(e1) (e2) = Operators.op_Addition,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (24,153--24,170)" + [], "let testSingleUnitizedSubtractionChecked(e1) (e2) = Operators.op_Subtraction,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (25,153--25,170)" + [], "let testSingleUnitizedMultiplyChecked(e1) (e2) = Operators.op_Multiply,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.float32,Microsoft.FSharp.Core.float32> (arg0_0,arg1_0),e1,e2) @ (26,153--26,170)" + [], "let testSingleUnitizedUnaryNegChecked(e1) = Operators.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (27,98--27,113)" + [], "let testSingleUnitizedToByteChecked(e1) = Checked.ToByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.byte> (arg0_0),e1) @ (29,98--29,113)" + [], "let testSingleUnitizedToSByteChecked(e1) = Checked.ToSByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.sbyte> (arg0_0),e1) @ (30,98--30,114)" + [], "let testSingleUnitizedToInt16Checked(e1) = Checked.ToInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int16> (arg0_0),e1) @ (31,98--31,114)" + [], "let testSingleUnitizedToUInt16Checked(e1) = Checked.ToUInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint16> (arg0_0),e1) @ (32,98--32,115)" + [], "let testSingleUnitizedToIntChecked(e1) = Checked.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (33,98--33,112)" + [], "let testSingleUnitizedToInt32Checked(e1) = Checked.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (34,98--34,114)" + [], "let testSingleUnitizedToUInt32Checked(e1) = Checked.ToUInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint32> (arg0_0),e1) @ (35,98--35,115)" + [], "let testSingleUnitizedToInt64Checked(e1) = Checked.ToInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int64> (arg0_0),e1) @ (36,98--36,114)" + [], "let testSingleUnitizedToUInt64Checked(e1) = Checked.ToUInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint64> (arg0_0),e1) @ (37,98--37,115)" + [], "let testSingleUnitizedToIntPtrChecked(e1) = Checked.ToIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.nativeint> (arg0_0),e1) @ (38,98--38,118)" + [], "let testSingleUnitizedToUIntPtrChecked(e1) = Checked.ToUIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.unativeint> (arg0_0),e1) @ (39,98--39,119)" + [], "let testSingleUnitizedToByteOperator(e1) = Operators.ToByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.byte> (arg0_0),e1) @ (41,98--41,105)" + [], "let testSingleUnitizedToSByteOperator(e1) = Operators.ToSByte> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.sbyte> (arg0_0),e1) @ (42,98--42,106)" + [], "let testSingleUnitizedToInt16Operator(e1) = Operators.ToInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int16> (arg0_0),e1) @ (43,98--43,106)" + [], "let testSingleUnitizedToUInt16Operator(e1) = Operators.ToUInt16> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint16> (arg0_0),e1) @ (44,98--44,107)" + [], "let testSingleUnitizedToIntOperator(e1) = Operators.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (45,98--45,104)" + [], "let testSingleUnitizedToInt32Operator(e1) = Operators.ToInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int32> (arg0_0),e1) @ (46,98--46,106)" + [], "let testSingleUnitizedToUInt32Operator(e1) = Operators.ToUInt32> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint32> (arg0_0),e1) @ (47,98--47,107)" + [], "let testSingleUnitizedToInt64Operator(e1) = Operators.ToInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.int64> (arg0_0),e1) @ (48,98--48,106)" + [], "let testSingleUnitizedToUInt64Operator(e1) = Operators.ToUInt64> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.uint64> (arg0_0),e1) @ (49,98--49,107)" + [], "let testSingleUnitizedToIntPtrOperator(e1) = Operators.ToIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.nativeint> (arg0_0),e1) @ (50,98--50,110)" + [], "let testSingleUnitizedToUIntPtrOperator(e1) = Operators.ToUIntPtr> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.unativeint> (arg0_0),e1) @ (51,98--51,111)" + [], "let testSingleUnitizedToSingleOperator(e1) = Operators.ToSingle> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) @ (52,98--52,108)" + [], "let testSingleUnitizedToDoubleOperator(e1) = Operators.ToDouble> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float> (arg0_0),e1) @ (53,98--53,106)" + [], "let testSingleUnitizedToDecimalOperator(e1) = Convert.ToDecimal (Operators.ToSingle> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1)) @ (54,98--54,108)" + [], "let testSingleUnitizedToCharOperator(e1) = Operators.ToChar> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.char> (arg0_0),e1) @ (55,98--55,105)" + [FC47; FC50], "let testSingleUnitizedToStringOperator(e1) = let x: Microsoft.FSharp.Core.float32 = Operators.ToSingle> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.float32> (arg0_0),e1) in x.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,98--56,107)" + ] + + testOperators "SingleUnitized" "float32" excludedTests expectedUnoptimized expectedOptimized + [] let ``Test Operator Declarations for Double`` () = let excludedTests = [ @@ -2324,110 +2522,107 @@ let ``Test Operator Declarations for Double`` () = "testDoubleShiftLeftOperator"; "testDoubleShiftRightOperator"; ] - + let expectedUnoptimized = [ - "type OperatorTestsDouble"; - "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,68--4,76)"; - "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,68--5,77)"; - "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,68--6,76)"; - "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,68--7,77)"; - "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,68--8,76)"; - "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,68--9,77)"; - "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,60--11,68)"; - "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,60--12,68)"; - "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)"; - "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,60--14,68)"; - "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,60--15,68)"; - "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,47--22,53)"; - "let testDoubleAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,57--24,74)"; - "let testDoubleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (e1,e2) @ (25,57--25,74)"; - "let testDoubleMultiplyChecked(e1) (e2) = Checked.op_Multiply (e1,e2) @ (26,57--26,74)"; - "let testDoubleUnaryNegChecked(e1) = Checked.op_UnaryNegation (e1) @ (27,46--27,61)"; - "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)"; - "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)"; - "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)"; - "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)"; - "let testDoubleToIntChecked(e1) = Checked.ToInt (e1) @ (33,46--33,60)"; - "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)"; - "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)"; - "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)"; - "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)"; - "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)"; - "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)"; - "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)"; - "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)"; - "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)"; - "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)"; - "let testDoubleToIntOperator(e1) = Operators.ToInt (e1) @ (45,46--45,52)"; - "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)"; - "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)"; - "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)"; - "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)"; - "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)"; - "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)"; - "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)"; - "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)"; - "let testDoubleToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,46--54,56)"; - "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)"; - "let testDoubleToStringOperator(e1) = Operators.ToString (e1) @ (56,46--56,55)"; + [], "type OperatorTestsDouble" + [], "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)" + [], "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,67--5,77)" + [], "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)" + [], "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,67--7,77)" + [], "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)" + [], "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,67--9,77)" + [], "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,59--11,68)" + [], "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,59--12,68)" + [], "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,59--13,68)" + [], "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,59--14,68)" + [], "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,59--15,68)" + [], "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,46--22,53)" + [], "let testDoubleAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,57--24,74)" + [], "let testDoubleSubtractionChecked(e1) (e2) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,57--25,74)" + [], "let testDoubleMultiplyChecked(e1) (e2) = Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,57--26,74)" + [], "let testDoubleUnaryNegChecked(e1) = Checked.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,46--27,61)" + [], "let testDoubleToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,46--29,61)" + [], "let testDoubleToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,46--30,62)" + [], "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,46--31,62)" + [], "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,46--32,63)" + [], "let testDoubleToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,46--33,60)" + [], "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,46--34,62)" + [], "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,46--35,63)" + [], "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,46--36,62)" + [], "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,46--37,63)" + [], "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,46--38,66)" + [], "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,46--39,67)" + [], "let testDoubleToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,46--41,53)" + [], "let testDoubleToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,46--42,54)" + [], "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,46--43,54)" + [], "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,46--44,55)" + [], "let testDoubleToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,46--45,52)" + [], "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,46--46,54)" + [], "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,46--47,55)" + [], "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,46--48,54)" + [], "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,46--49,55)" + [], "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,46--50,58)" + [], "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,46--51,59)" + [], "let testDoubleToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,46--52,56)" + [], "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,46--53,54)" + [], "let testDoubleToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,46--54,56)" + [], "let testDoubleToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,46--55,53)" + [], "let testDoubleToStringOperator(e1) = Operators.ToString (e1) @ (56,46--56,55)" ] - let expectedOptimized = [ - "type OperatorTestsDouble"; - "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,68--4,76)"; - "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,68--5,77)"; - "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,68--6,76)"; - "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,68--7,77)"; - "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,68--8,76)"; - "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,68--9,77)"; - "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,60--11,68)"; - "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,60--12,68)"; - "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,59--13,68)"; - "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,60--14,68)"; - "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,60--15,68)"; - "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (e1) @ (22,47--22,53)"; - "let testDoubleAdditionChecked(e1) (e2) = Operators.op_Addition (e1,e2) @ (24,57--24,74)"; - "let testDoubleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (25,57--25,74)"; - "let testDoubleMultiplyChecked(e1) (e2) = Operators.op_Multiply (e1,e2) @ (26,57--26,74)"; - "let testDoubleUnaryNegChecked(e1) = Operators.op_UnaryNegation (e1) @ (27,46--27,61)"; - "let testDoubleToByteChecked(e1) = Checked.ToByte (e1) @ (29,46--29,61)"; - "let testDoubleToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,46--30,62)"; - "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,46--31,62)"; - "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,46--32,63)"; - "let testDoubleToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,46--33,60)"; - "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,46--34,62)"; - "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,46--35,63)"; - "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,46--36,62)"; - "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,46--37,63)"; - "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,46--38,66)"; - "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,46--39,67)"; - "let testDoubleToByteOperator(e1) = Operators.ToByte (e1) @ (41,46--41,53)"; - "let testDoubleToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,46--42,54)"; - "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,46--43,54)"; - "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,46--44,55)"; - "let testDoubleToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,46--45,52)"; - "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,46--46,54)"; - "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,46--47,55)"; - "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,46--48,54)"; - "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,46--49,55)"; - "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,46--50,58)"; - "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,46--51,59)"; - "let testDoubleToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,46--52,56)"; - "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,46--53,54)"; - "let testDoubleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,46--54,56)"; - "let testDoubleToCharOperator(e1) = Operators.ToChar (e1) @ (55,46--55,53)"; -#if DEBUG - @"let testDoubleToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,46--56,55)" -#else - "let testDoubleToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,46--56,55)"; -#endif + [], "type OperatorTestsDouble" + [], "let testDoubleEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,67--4,76)" + [], "let testDoubleNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,67--5,77)" + [], "let testDoubleLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,67--6,76)" + [], "let testDoubleLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,67--7,77)" + [], "let testDoubleGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,67--8,76)" + [], "let testDoubleGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,67--9,77)" + [], "let testDoubleAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,59--11,68)" + [], "let testDoubleSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (12,59--12,68)" + [], "let testDoubleMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (13,59--13,68)" + [], "let testDoubleDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),e1,e2) @ (14,59--14,68)" + [], "let testDoubleModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic (arg0_0,arg1_0),e1,e2) @ (15,59--15,68)" + [], "let testDoubleUnaryNegOperator(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (22,46--22,53)" + [], "let testDoubleAdditionChecked(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,57--24,74)" + [], "let testDoubleSubtractionChecked(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2) @ (25,57--25,74)" + [], "let testDoubleMultiplyChecked(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2) @ (26,57--26,74)" + [], "let testDoubleUnaryNegChecked(e1) = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),e1) @ (27,46--27,61)" + [], "let testDoubleToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,46--29,61)" + [], "let testDoubleToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,46--30,62)" + [], "let testDoubleToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,46--31,62)" + [], "let testDoubleToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,46--32,63)" + [], "let testDoubleToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,46--33,60)" + [], "let testDoubleToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,46--34,62)" + [], "let testDoubleToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,46--35,63)" + [], "let testDoubleToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,46--36,62)" + [], "let testDoubleToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,46--37,63)" + [], "let testDoubleToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,46--38,66)" + [], "let testDoubleToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,46--39,67)" + [], "let testDoubleToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,46--41,53)" + [], "let testDoubleToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,46--42,54)" + [], "let testDoubleToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,46--43,54)" + [], "let testDoubleToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,46--44,55)" + [], "let testDoubleToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,46--45,52)" + [], "let testDoubleToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,46--46,54)" + [], "let testDoubleToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,46--47,55)" + [], "let testDoubleToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,46--48,54)" + [], "let testDoubleToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,46--49,55)" + [], "let testDoubleToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,46--50,58)" + [], "let testDoubleToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,46--51,59)" + [], "let testDoubleToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,46--52,56)" + [], "let testDoubleToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,46--53,54)" + [], "let testDoubleToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,46--54,56)" + [], "let testDoubleToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,46--55,53)" + [FC47; FC50], "let testDoubleToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,46--56,55)" ] + testOperators "Double" "float" excludedTests expectedUnoptimized expectedOptimized [] let ``Test Operator Declarations for Decimal`` () = let excludedTests = [ + // None of these are supported for decimals "testDecimalBitwiseAndOperator"; "testDecimalBitwiseOrOperator"; "testDecimalBitwiseXorOperator"; @@ -2444,89 +2639,166 @@ let ``Test Operator Declarations for Decimal`` () = ] let expectedUnoptimized = [ - "type OperatorTestsDecimal"; - "let testDecimalEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,73--4,81)"; - "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,73--5,82)"; - "let testDecimalLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,73--6,81)"; - "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,73--7,82)"; - "let testDecimalGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,73--8,81)"; - "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,73--9,82)"; - "let testDecimalAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,65--11,73)"; - "let testDecimalSubtractionOperator(e1) (e2) = Operators.op_Subtraction (e1,e2) @ (12,65--12,73)"; - "let testDecimalMultiplyOperator(e1) (e2) = Operators.op_Multiply (e1,e2) @ (13,64--13,73)"; - "let testDecimalDivisionOperator(e1) (e2) = Operators.op_Division (e1,e2) @ (14,65--14,73)"; - "let testDecimalModulusOperator(e1) (e2) = Operators.op_Modulus (e1,e2) @ (15,65--15,73)"; - "let testDecimalAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,62--24,79)"; - "let testDecimalToByteChecked(e1) = Checked.ToByte (e1) @ (29,49--29,64)"; - "let testDecimalToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,49--30,65)"; - "let testDecimalToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,49--31,65)"; - "let testDecimalToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,49--32,66)"; - "let testDecimalToIntChecked(e1) = Checked.ToInt (e1) @ (33,49--33,63)"; - "let testDecimalToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,49--34,65)"; - "let testDecimalToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,49--35,66)"; - "let testDecimalToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,49--36,65)"; - "let testDecimalToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,49--37,66)"; - "let testDecimalToByteOperator(e1) = Operators.ToByte (e1) @ (41,49--41,56)"; - "let testDecimalToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,49--42,57)"; - "let testDecimalToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,49--43,57)"; - "let testDecimalToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,49--44,58)"; - "let testDecimalToIntOperator(e1) = Operators.ToInt (e1) @ (45,49--45,55)"; - "let testDecimalToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,49--46,57)"; - "let testDecimalToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,49--47,58)"; - "let testDecimalToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,49--48,57)"; - "let testDecimalToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,49--49,58)"; - "let testDecimalToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,49--52,59)"; - "let testDecimalToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,49--53,57)"; - "let testDecimalToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,49--54,59)"; - "let testDecimalToCharOperator(e1) = Operators.ToChar (e1) @ (55,49--55,56)"; - "let testDecimalToStringOperator(e1) = Operators.ToString (e1) @ (56,49--56,58)"; + [], "type OperatorTestsDecimal" + [], "let testDecimalEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,72--4,81)" + [], "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,72--5,82)" + [], "let testDecimalLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,72--6,81)" + [], "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)" + [], "let testDecimalGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,72--8,81)" + [], "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)" + [], "let testDecimalAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> Decimal.op_Addition (arg0_0,arg1_0),e1,e2) @ (11,64--11,73)" + [], "let testDecimalSubtractionOperator(e1) (e2) = Operators.op_Subtraction (fun arg0_0 -> fun arg1_0 -> Decimal.op_Subtraction (arg0_0,arg1_0),e1,e2) @ (12,64--12,73)" + [], "let testDecimalMultiplyOperator(e1) (e2) = Operators.op_Multiply (fun arg0_0 -> fun arg1_0 -> Decimal.op_Multiply (arg0_0,arg1_0),e1,e2) @ (13,64--13,73)" + [], "let testDecimalDivisionOperator(e1) (e2) = Operators.op_Division (fun arg0_0 -> fun arg1_0 -> Decimal.op_Division (arg0_0,arg1_0),e1,e2) @ (14,64--14,73)" + [], "let testDecimalModulusOperator(e1) (e2) = Operators.op_Modulus (fun arg0_0 -> fun arg1_0 -> Decimal.op_Modulus (arg0_0,arg1_0),e1,e2) @ (15,64--15,73)" + [], "let testDecimalAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> Decimal.op_Addition (arg0_0,arg1_0),e1,e2) @ (24,62--24,79)" + [], "let testDecimalToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (29,49--29,64)" + [], "let testDecimalToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (30,49--30,65)" + [], "let testDecimalToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (31,49--31,65)" + [], "let testDecimalToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (32,49--32,66)" + [], "let testDecimalToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (33,49--33,63)" + [], "let testDecimalToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (34,49--34,65)" + [], "let testDecimalToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (35,49--35,66)" + [], "let testDecimalToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (36,49--36,65)" + [], "let testDecimalToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (37,49--37,66)" + [], "let testDecimalToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (41,49--41,56)" + [], "let testDecimalToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (42,49--42,57)" + [], "let testDecimalToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (43,49--43,57)" + [], "let testDecimalToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (44,49--44,58)" + [], "let testDecimalToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (45,49--45,55)" + [], "let testDecimalToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (46,49--46,57)" + [], "let testDecimalToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (47,49--47,58)" + [], "let testDecimalToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (48,49--48,57)" + [], "let testDecimalToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (49,49--49,58)" + [], "let testDecimalToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (52,49--52,59)" + [], "let testDecimalToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (53,49--53,57)" + [], "let testDecimalToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,49--54,59)" + [], "let testDecimalToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> Decimal.op_Explicit (arg0_0),e1) @ (55,49--55,56)" + [], "let testDecimalToStringOperator(e1) = Operators.ToString (e1) @ (56,49--56,58)" ] - let expectedOptimized = [ - "type OperatorTestsDecimal"; - "let testDecimalEqualsOperator(e1) (e2) = Decimal.op_Equality (e1,e2) @ (4,73--4,81)"; - "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Equality (Decimal.op_Equality (e1,e2),False) @ (5,73--5,82)"; - "let testDecimalLessThanOperator(e1) (e2) = Decimal.op_LessThan (e1,e2) @ (6,73--6,81)"; - "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Decimal.op_LessThanOrEqual (e1,e2) @ (7,73--7,82)"; - "let testDecimalGreaterThanOperator(e1) (e2) = Decimal.op_GreaterThan (e1,e2) @ (8,73--8,81)"; - "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Decimal.op_GreaterThanOrEqual (e1,e2) @ (9,73--9,82)"; - "let testDecimalAdditionOperator(e1) (e2) = Decimal.op_Addition (e1,e2) @ (11,65--11,73)"; - "let testDecimalSubtractionOperator(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (12,65--12,73)"; - "let testDecimalMultiplyOperator(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (13,64--13,73)"; - "let testDecimalDivisionOperator(e1) (e2) = Decimal.op_Division (e1,e2) @ (14,65--14,73)"; - "let testDecimalModulusOperator(e1) (e2) = Decimal.op_Modulus (e1,e2) @ (15,65--15,73)"; - "let testDecimalAdditionChecked(e1) (e2) = Decimal.op_Addition (e1,e2) @ (24,62--24,79)"; - "let testDecimalToByteChecked(e1) = Decimal.op_Explicit (e1) @ (29,49--29,64)"; - "let testDecimalToSByteChecked(e1) = Decimal.op_Explicit (e1) @ (30,49--30,65)"; - "let testDecimalToInt16Checked(e1) = Decimal.op_Explicit (e1) @ (31,49--31,65)"; - "let testDecimalToUInt16Checked(e1) = Decimal.op_Explicit (e1) @ (32,49--32,66)"; - "let testDecimalToIntChecked(e1) = Decimal.op_Explicit (e1) @ (33,49--33,63)"; - "let testDecimalToInt32Checked(e1) = Decimal.op_Explicit (e1) @ (34,49--34,65)"; - "let testDecimalToUInt32Checked(e1) = Decimal.op_Explicit (e1) @ (35,49--35,66)"; - "let testDecimalToInt64Checked(e1) = Decimal.op_Explicit (e1) @ (36,49--36,65)"; - "let testDecimalToUInt64Checked(e1) = Decimal.op_Explicit (e1) @ (37,49--37,66)"; - "let testDecimalToByteOperator(e1) = Decimal.op_Explicit (e1) @ (41,49--41,56)"; - "let testDecimalToSByteOperator(e1) = Decimal.op_Explicit (e1) @ (42,49--42,57)"; - "let testDecimalToInt16Operator(e1) = Decimal.op_Explicit (e1) @ (43,49--43,57)"; - "let testDecimalToUInt16Operator(e1) = Decimal.op_Explicit (e1) @ (44,49--44,58)"; - "let testDecimalToIntOperator(e1) = Decimal.op_Explicit (e1) @ (45,49--45,55)"; - "let testDecimalToInt32Operator(e1) = Decimal.op_Explicit (e1) @ (46,49--46,57)"; - "let testDecimalToUInt32Operator(e1) = Decimal.op_Explicit (e1) @ (47,49--47,58)"; - "let testDecimalToInt64Operator(e1) = Decimal.op_Explicit (e1) @ (48,49--48,57)"; - "let testDecimalToUInt64Operator(e1) = Decimal.op_Explicit (e1) @ (49,49--49,58)"; - "let testDecimalToSingleOperator(e1) = Decimal.op_Explicit (e1) @ (52,49--52,59)"; - "let testDecimalToDoubleOperator(e1) = Convert.ToDouble (e1) @ (53,49--53,57)"; - "let testDecimalToDecimalOperator(e1) = e1 @ (54,57--54,59)"; - "let testDecimalToCharOperator(e1) = Decimal.op_Explicit (e1) @ (55,49--55,56)"; -#if DEBUG - @"let testDecimalToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,49--56,58)" -#else - "let testDecimalToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,49--56,58)"; -#endif + [], "type OperatorTestsDecimal" + [], "let testDecimalEqualsOperator(e1) (e2) = Decimal.op_Equality (e1,e2) @ (4,72--4,81)" + [], "let testDecimalNotEqualsOperator(e1) (e2) = Operators.op_Equality (Decimal.op_Equality (e1,e2),False) @ (5,72--5,82)" + [], "let testDecimalLessThanOperator(e1) (e2) = Decimal.op_LessThan (e1,e2) @ (6,72--6,81)" + [], "let testDecimalLessThanOrEqualsOperator(e1) (e2) = Decimal.op_LessThanOrEqual (e1,e2) @ (7,72--7,82)" + [], "let testDecimalGreaterThanOperator(e1) (e2) = Decimal.op_GreaterThan (e1,e2) @ (8,72--8,81)" + [], "let testDecimalGreaterThanOrEqualsOperator(e1) (e2) = Decimal.op_GreaterThanOrEqual (e1,e2) @ (9,72--9,82)" + [], "let testDecimalAdditionOperator(e1) (e2) = Decimal.op_Addition (e1,e2) @ (11,64--11,73)" + [], "let testDecimalSubtractionOperator(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (12,64--12,73)" + [], "let testDecimalMultiplyOperator(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (13,64--13,73)" + [], "let testDecimalDivisionOperator(e1) (e2) = Decimal.op_Division (e1,e2) @ (14,64--14,73)" + [], "let testDecimalModulusOperator(e1) (e2) = Decimal.op_Modulus (e1,e2) @ (15,64--15,73)" + [], "let testDecimalAdditionChecked(e1) (e2) = Decimal.op_Addition (e1,e2) @ (24,62--24,79)" + [], "let testDecimalToByteChecked(e1) = Decimal.op_Explicit (e1) @ (29,49--29,64)" + [], "let testDecimalToSByteChecked(e1) = Decimal.op_Explicit (e1) @ (30,49--30,65)" + [], "let testDecimalToInt16Checked(e1) = Decimal.op_Explicit (e1) @ (31,49--31,65)" + [], "let testDecimalToUInt16Checked(e1) = Decimal.op_Explicit (e1) @ (32,49--32,66)" + [], "let testDecimalToIntChecked(e1) = Decimal.op_Explicit (e1) @ (33,49--33,63)" + [], "let testDecimalToInt32Checked(e1) = Decimal.op_Explicit (e1) @ (34,49--34,65)" + [], "let testDecimalToUInt32Checked(e1) = Decimal.op_Explicit (e1) @ (35,49--35,66)" + [], "let testDecimalToInt64Checked(e1) = Decimal.op_Explicit (e1) @ (36,49--36,65)" + [], "let testDecimalToUInt64Checked(e1) = Decimal.op_Explicit (e1) @ (37,49--37,66)" + [], "let testDecimalToByteOperator(e1) = Decimal.op_Explicit (e1) @ (41,49--41,56)" + [], "let testDecimalToSByteOperator(e1) = Decimal.op_Explicit (e1) @ (42,49--42,57)" + [], "let testDecimalToInt16Operator(e1) = Decimal.op_Explicit (e1) @ (43,49--43,57)" + [], "let testDecimalToUInt16Operator(e1) = Decimal.op_Explicit (e1) @ (44,49--44,58)" + [], "let testDecimalToIntOperator(e1) = Decimal.op_Explicit (e1) @ (45,49--45,55)" + [], "let testDecimalToInt32Operator(e1) = Decimal.op_Explicit (e1) @ (46,49--46,57)" + [], "let testDecimalToUInt32Operator(e1) = Decimal.op_Explicit (e1) @ (47,49--47,58)" + [], "let testDecimalToInt64Operator(e1) = Decimal.op_Explicit (e1) @ (48,49--48,57)" + [], "let testDecimalToUInt64Operator(e1) = Decimal.op_Explicit (e1) @ (49,49--49,58)" + [], "let testDecimalToSingleOperator(e1) = Decimal.op_Explicit (e1) @ (52,49--52,59)" + [], "let testDecimalToDoubleOperator(e1) = Convert.ToDouble (e1) @ (53,49--53,57)" + [], "let testDecimalToDecimalOperator(e1) = e1 @ (54,57--54,59)" + [], "let testDecimalToCharOperator(e1) = Decimal.op_Explicit (e1) @ (55,49--55,56)" + [FC47; FC50], "let testDecimalToStringOperator(e1) = e1.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,49--56,58)" ] + testOperators "Decimal" "decimal" excludedTests expectedUnoptimized expectedOptimized +[] +let ``Test Operator Declarations for Decimal unitized`` () = + let excludedTests = [ + // None of these are supported for unitized decimals + "testDecimalUnitizedBitwiseAndOperator"; + "testDecimalUnitizedBitwiseOrOperator"; + "testDecimalUnitizedBitwiseXorOperator"; + "testDecimalUnitizedShiftLeftOperator"; + "testDecimalUnitizedShiftRightOperator"; + "testDecimalUnitizedToSByte"; + "testDecimalUnitizedToIntPtrChecked"; + "testDecimalUnitizedToUIntPtrChecked"; + "testDecimalUnitizedToIntPtrOperator"; + "testDecimalUnitizedToUIntPtrOperator"; + "testDecimalUnitizedToByteChecked"; + "testDecimalUnitizedToSByteChecked"; + "testDecimalUnitizedToInt16Checked"; + "testDecimalUnitizedToUInt16Checked"; + "testDecimalUnitizedToIntChecked"; + "testDecimalUnitizedToInt32Checked"; + "testDecimalUnitizedToUInt32Checked"; + "testDecimalUnitizedToInt64Checked"; + "testDecimalUnitizedToUInt64Checked"; + "testDecimalUnitizedToByteOperator"; + "testDecimalUnitizedToSByteOperator"; + "testDecimalUnitizedToInt16Operator"; + "testDecimalUnitizedToUInt16Operator"; + "testDecimalUnitizedToIntOperator"; + "testDecimalUnitizedToInt32Operator"; + "testDecimalUnitizedToUInt32Operator"; + "testDecimalUnitizedToInt64Operator"; + "testDecimalUnitizedToUInt64Operator"; + "testDecimalUnitizedToSingleOperator"; + "testDecimalUnitizedToDoubleOperator"; + "testDecimalUnitizedToCharOperator"; + ] + + let expectedUnoptimized = [ + [], "type OperatorTestsDecimalUnitized" + [], "let testDecimalUnitizedEqualsOperator(e1) (e2) = Operators.op_Equality> (e1,e2) @ (4,164--4,173)" + [], "let testDecimalUnitizedNotEqualsOperator(e1) (e2) = Operators.op_Inequality> (e1,e2) @ (5,164--5,174)" + [], "let testDecimalUnitizedLessThanOperator(e1) (e2) = Operators.op_LessThan> (e1,e2) @ (6,164--6,173)" + [], "let testDecimalUnitizedLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual> (e1,e2) @ (7,164--7,174)" + [], "let testDecimalUnitizedGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan> (e1,e2) @ (8,164--8,173)" + [], "let testDecimalUnitizedGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual> (e1,e2) @ (9,164--9,174)" + [], "let testDecimalUnitizedAdditionOperator(e1) (e2) = Operators.op_Addition,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (11,156--11,165)" + [], "let testDecimalUnitizedSubtractionOperator(e1) (e2) = Operators.op_Subtraction,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (12,156--12,165)" + [], "let testDecimalUnitizedMultiplyOperator(e1) (e2) = Operators.op_Multiply,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (13,156--13,165)" + [], "let testDecimalUnitizedDivisionOperator(e1) (e2) = Operators.op_Division,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (14,156--14,165)" + [], "let testDecimalUnitizedModulusOperator(e1) (e2) = Operators.op_Modulus,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.ModulusDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (15,156--15,165)" + [], "let testDecimalUnitizedUnaryNegOperator(e1) = Operators.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.decimal> (arg0_0),e1) @ (22,99--22,106)" + [], "let testDecimalUnitizedAdditionChecked(e1) (e2) = Checked.op_Addition,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (24,154--24,171)" + [], "let testDecimalUnitizedSubtractionChecked(e1) (e2) = Checked.op_Subtraction,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (25,154--25,171)" + [], "let testDecimalUnitizedMultiplyChecked(e1) (e2) = Checked.op_Multiply,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic,Microsoft.FSharp.Core.decimal,Microsoft.FSharp.Core.decimal> (arg0_0,arg1_0),e1,e2) @ (26,154--26,171)" + [], "let testDecimalUnitizedUnaryNegChecked(e1) = Checked.op_UnaryNegation> (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic,Microsoft.FSharp.Core.decimal> (arg0_0),e1) @ (27,99--27,114)" + [], "let testDecimalUnitizedToDecimalOperator(e1) = Operators.ToDecimal> (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic,Microsoft.FSharp.Core.decimal> (arg0_0),e1) @ (54,99--54,109)" + [], "let testDecimalUnitizedToStringOperator(e1) = Operators.ToString> (e1) @ (56,99--56,108)" + ] + let expectedOptimized = [ + [], "type OperatorTestsDecimalUnitized" + [], "let testDecimalUnitizedEqualsOperator(e1) (e2) = Decimal.op_Equality (e1,e2) @ (4,164--4,173)" + [], "let testDecimalUnitizedNotEqualsOperator(e1) (e2) = Operators.op_Equality (Decimal.op_Equality (e1,e2),False) @ (5,164--5,174)" + [], "let testDecimalUnitizedLessThanOperator(e1) (e2) = Decimal.op_LessThan (e1,e2) @ (6,164--6,173)" + [], "let testDecimalUnitizedLessThanOrEqualsOperator(e1) (e2) = Decimal.op_LessThanOrEqual (e1,e2) @ (7,164--7,174)" + [], "let testDecimalUnitizedGreaterThanOperator(e1) (e2) = Decimal.op_GreaterThan (e1,e2) @ (8,164--8,173)" + [], "let testDecimalUnitizedGreaterThanOrEqualsOperator(e1) (e2) = Decimal.op_GreaterThanOrEqual (e1,e2) @ (9,164--9,174)" + [], "let testDecimalUnitizedAdditionOperator(e1) (e2) = Decimal.op_Addition (e1,e2) @ (11,156--11,165)" + [], "let testDecimalUnitizedSubtractionOperator(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (12,156--12,165)" + [], "let testDecimalUnitizedMultiplyOperator(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (13,156--13,165)" + [], "let testDecimalUnitizedDivisionOperator(e1) (e2) = Decimal.op_Division (e1,e2) @ (14,156--14,165)" + [], "let testDecimalUnitizedModulusOperator(e1) (e2) = Decimal.op_Modulus (e1,e2) @ (15,156--15,165)" + [], "let testDecimalUnitizedUnaryNegOperator(e1) = Decimal.op_UnaryNegation (e1) @ (22,99--22,106)" + [], "let testDecimalUnitizedAdditionChecked(e1) (e2) = Decimal.op_Addition (e1,e2) @ (24,154--24,171)" + [], "let testDecimalUnitizedSubtractionChecked(e1) (e2) = Decimal.op_Subtraction (e1,e2) @ (25,154--25,171)" + [], "let testDecimalUnitizedMultiplyChecked(e1) (e2) = Decimal.op_Multiply (e1,e2) @ (26,154--26,171)" + [], "let testDecimalUnitizedUnaryNegChecked(e1) = Decimal.op_UnaryNegation (e1) @ (27,99--27,114)" + [], "let testDecimalUnitizedToDecimalOperator(e1) = e1 @ (54,99--54,109)" + [FC47; FC50], "let testDecimalUnitizedToStringOperator(e1) = let x: Microsoft.FSharp.Core.decimal = e1 in x.ToString(dflt,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (56,99--56,108)" + ] + testOperators "DecimalUnitized" "decimal" excludedTests expectedUnoptimized expectedOptimized + [] let ``Test Operator Declarations for Char`` () = let excludedTests = [ @@ -2547,85 +2819,81 @@ let ``Test Operator Declarations for Char`` () = ] let expectedUnoptimized = [ - "type OperatorTestsChar"; - "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,64--4,72)"; - "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,64--5,73)"; - "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,64--6,72)"; - "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,64--7,73)"; - "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,64--8,72)"; - "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,64--9,73)"; - "let testCharAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,56--11,64)"; - "let testCharAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,53--24,70)"; - "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)"; - "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)"; - "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)"; - "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)"; - "let testCharToIntChecked(e1) = Checked.ToInt (e1) @ (33,43--33,57)"; - "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)"; - "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)"; - "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)"; - "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)"; - "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)"; - "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)"; - "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)"; - "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)"; - "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)"; - "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)"; - "let testCharToIntOperator(e1) = Operators.ToInt (e1) @ (45,43--45,49)"; - "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)"; - "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)"; - "let testCharToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,43--48,51)"; - "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)"; - "let testCharToIntPtrOperator(e1) = Operators.ToIntPtr (e1) @ (50,43--50,55)"; - "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)"; - "let testCharToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,43--52,53)"; - "let testCharToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,43--53,51)"; - "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)"; - "let testCharToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)"; + [], "type OperatorTestsChar" + [], "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)" + [], "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,63--5,73)" + [], "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)" + [], "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,63--7,73)" + [], "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)" + [], "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,63--9,73)" + [], "let testCharAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,55--11,64)" + [], "let testCharAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,53--24,70)" + [], "let testCharToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" + [], "let testCharToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" + [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" + [], "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" + [], "let testCharToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" + [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" + [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" + [], "let testCharToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,43--36,59)" + [], "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,43--37,60)" + [], "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,43--38,63)" + [], "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,43--39,64)" + [], "let testCharToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,43--41,50)" + [], "let testCharToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,43--42,51)" + [], "let testCharToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,43--43,51)" + [], "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,43--44,52)" + [], "let testCharToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,43--45,49)" + [], "let testCharToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,43--46,51)" + [], "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,43--47,52)" + [], "let testCharToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,43--48,51)" + [], "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,43--49,52)" + [], "let testCharToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,43--50,55)" + [], "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,43--51,56)" + [], "let testCharToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,43--52,53)" + [], "let testCharToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,43--53,51)" + [], "let testCharToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,43--55,50)" + [], "let testCharToStringOperator(e1) = Operators.ToString (e1) @ (56,43--56,52)" ] - let expectedOptimized = [ - "type OperatorTestsChar"; - "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,64--4,72)"; - "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,64--5,73)"; - "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,64--6,72)"; - "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,64--7,73)"; - "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,64--8,72)"; - "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,64--9,73)"; - "let testCharAdditionOperator(e1) (e2) = Operators.ToChar (Operators.op_Addition (e1,e2)) @ (11,56--11,64)"; - "let testCharAdditionChecked(e1) (e2) = Operators.ToChar (Checked.op_Addition (e1,e2)) @ (24,53--24,70)"; - "let testCharToByteChecked(e1) = Checked.ToByte (e1) @ (29,43--29,58)"; - "let testCharToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,43--30,59)"; - "let testCharToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,43--31,59)"; - "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,43--32,60)"; - "let testCharToIntChecked(e1) = Checked.ToInt32 (e1) @ (33,43--33,57)"; - "let testCharToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,43--34,59)"; - "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,43--35,60)"; - "let testCharToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,43--36,59)"; - "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,43--37,60)"; - "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (e1) @ (38,43--38,63)"; - "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (e1) @ (39,43--39,64)"; - "let testCharToByteOperator(e1) = Operators.ToByte (e1) @ (41,43--41,50)"; - "let testCharToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,43--42,51)"; - "let testCharToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,43--43,51)"; - "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,43--44,52)"; - "let testCharToIntOperator(e1) = Operators.ToInt32 (e1) @ (45,43--45,49)"; - "let testCharToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,43--46,51)"; - "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,43--47,52)"; - "let testCharToInt64Operator(e1) = Operators.ToUInt64 (e1) @ (48,43--48,51)"; - "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,43--49,52)"; - "let testCharToIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (50,43--50,55)"; - "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (e1) @ (51,43--51,56)"; - "let testCharToSingleOperator(e1) = Operators.ToSingle (Operators.ToDouble (e1)) @ (52,43--52,53)"; - "let testCharToDoubleOperator(e1) = Operators.ToDouble (Operators.ToDouble (e1)) @ (53,43--53,51)"; - "let testCharToCharOperator(e1) = Operators.ToChar (e1) @ (55,43--55,50)"; -#if DEBUG - @"let testCharToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)" -#else - "let testCharToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)"; -#endif + [], "type OperatorTestsChar" + [], "let testCharEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,63--4,72)" + [], "let testCharNotEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_Equality (e1,e2),False) @ (5,63--5,73)" + [], "let testCharLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,63--6,72)" + [], "let testCharLessThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_GreaterThan (e1,e2),False) @ (7,63--7,73)" + [], "let testCharGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,63--8,72)" + [], "let testCharGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_Equality (Operators.op_LessThan (e1,e2),False) @ (9,63--9,73)" + [], "let testCharAdditionOperator(e1) (e2) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (11,55--11,64)" + [], "let testCharAdditionChecked(e1) (e2) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,53--24,70)" + [], "let testCharToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" + [], "let testCharToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" + [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" + [], "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" + [], "let testCharToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" + [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" + [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" + [], "let testCharToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,43--36,59)" + [], "let testCharToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,43--37,60)" + [], "let testCharToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,43--38,63)" + [], "let testCharToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,43--39,64)" + [], "let testCharToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,43--41,50)" + [], "let testCharToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,43--42,51)" + [], "let testCharToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,43--43,51)" + [], "let testCharToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,43--44,52)" + [], "let testCharToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,43--45,49)" + [], "let testCharToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,43--46,51)" + [], "let testCharToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,43--47,52)" + [], "let testCharToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,43--48,51)" + [], "let testCharToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,43--49,52)" + [], "let testCharToIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,43--50,55)" + [], "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,43--51,56)" + [], "let testCharToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,43--52,53)" + [], "let testCharToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,43--53,51)" + [], "let testCharToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,43--55,50)" + [FC47; FC50], "let testCharToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.char = e1 in copyOfStruct.ToString() @ (56,43--56,52)" ] + testOperators "Char" "char" excludedTests expectedUnoptimized expectedOptimized [] @@ -2651,77 +2919,72 @@ let ``Test Operator Declarations for String`` () = ] let expectedUnoptimized = [ - "type OperatorTestsString"; - "let testStringEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,70--4,78)"; - "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,70--5,79)"; - "let testStringLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,70--6,78)"; - "let testStringLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,70--7,79)"; - "let testStringGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,70--8,78)"; - "let testStringGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,70--9,79)"; - "let testStringAdditionOperator(e1) (e2) = Operators.op_Addition (e1,e2) @ (11,62--11,70)"; - "let testStringAdditionChecked(e1) (e2) = Checked.op_Addition (e1,e2) @ (24,59--24,76)"; - "let testStringToByteChecked(e1) = Checked.ToByte (e1) @ (29,47--29,62)"; - "let testStringToSByteChecked(e1) = Checked.ToSByte (e1) @ (30,47--30,63)"; - "let testStringToInt16Checked(e1) = Checked.ToInt16 (e1) @ (31,47--31,63)"; - "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (e1) @ (32,47--32,64)"; - "let testStringToIntChecked(e1) = Checked.ToInt (e1) @ (33,47--33,61)"; - "let testStringToInt32Checked(e1) = Checked.ToInt32 (e1) @ (34,47--34,63)"; - "let testStringToUInt32Checked(e1) = Checked.ToUInt32 (e1) @ (35,47--35,64)"; - "let testStringToInt64Checked(e1) = Checked.ToInt64 (e1) @ (36,47--36,63)"; - "let testStringToUInt64Checked(e1) = Checked.ToUInt64 (e1) @ (37,47--37,64)"; - "let testStringToByteOperator(e1) = Operators.ToByte (e1) @ (41,47--41,54)"; - "let testStringToSByteOperator(e1) = Operators.ToSByte (e1) @ (42,47--42,55)"; - "let testStringToInt16Operator(e1) = Operators.ToInt16 (e1) @ (43,47--43,55)"; - "let testStringToUInt16Operator(e1) = Operators.ToUInt16 (e1) @ (44,47--44,56)"; - "let testStringToIntOperator(e1) = Operators.ToInt (e1) @ (45,47--45,53)"; - "let testStringToInt32Operator(e1) = Operators.ToInt32 (e1) @ (46,47--46,55)"; - "let testStringToUInt32Operator(e1) = Operators.ToUInt32 (e1) @ (47,47--47,56)"; - "let testStringToInt64Operator(e1) = Operators.ToInt64 (e1) @ (48,47--48,55)"; - "let testStringToUInt64Operator(e1) = Operators.ToUInt64 (e1) @ (49,47--49,56)"; - "let testStringToSingleOperator(e1) = Operators.ToSingle (e1) @ (52,47--52,57)"; - "let testStringToDoubleOperator(e1) = Operators.ToDouble (e1) @ (53,47--53,55)"; - "let testStringToDecimalOperator(e1) = Operators.ToDecimal (e1) @ (54,47--54,57)"; - "let testStringToCharOperator(e1) = Operators.ToChar (e1) @ (55,47--55,54)"; - "let testStringToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)"; + [], "type OperatorTestsString" + [], "let testStringEqualsOperator(e1) (e2) = Operators.op_Equality (e1,e2) @ (4,69--4,78)" + [], "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Inequality (e1,e2) @ (5,69--5,79)" + [], "let testStringLessThanOperator(e1) (e2) = Operators.op_LessThan (e1,e2) @ (6,69--6,78)" + [], "let testStringLessThanOrEqualsOperator(e1) (e2) = Operators.op_LessThanOrEqual (e1,e2) @ (7,69--7,79)" + [], "let testStringGreaterThanOperator(e1) (e2) = Operators.op_GreaterThan (e1,e2) @ (8,69--8,78)" + [], "let testStringGreaterThanOrEqualsOperator(e1) (e2) = Operators.op_GreaterThanOrEqual (e1,e2) @ (9,69--9,79)" + [], "let testStringAdditionOperator(e1) (e2) = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (11,61--11,70)" + [], "let testStringAdditionChecked(e1) (e2) = Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2) @ (24,59--24,76)" + [], "let testStringToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" + [], "let testStringToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" + [], "let testStringToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" + [], "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testStringToIntChecked(e1) = Checked.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" + [], "let testStringToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" + [], "let testStringToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testStringToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" + [], "let testStringToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testStringToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" + [], "let testStringToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" + [], "let testStringToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" + [], "let testStringToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testStringToIntOperator(e1) = Operators.ToInt (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" + [], "let testStringToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" + [], "let testStringToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testStringToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" + [], "let testStringToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" + [], "let testStringToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,47--52,57)" + [], "let testStringToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,47--53,55)" + [], "let testStringToDecimalOperator(e1) = Operators.ToDecimal (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (54,47--54,57)" + [], "let testStringToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [], "let testStringToStringOperator(e1) = Operators.ToString (e1) @ (56,47--56,56)" ] - let expectedOptimized = [ - "type OperatorTestsString"; - "let testStringEqualsOperator(e1) (e2) = String.Equals (e1,e2) @ (4,70--4,78)"; - "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Equality (String.Equals (e1,e2),False) @ (5,70--5,79)"; - "let testStringLessThanOperator(e1) (e2) = HashCompare.GenericLessThanIntrinsic (e1,e2) @ (6,70--6,78)"; - "let testStringLessThanOrEqualsOperator(e1) (e2) = HashCompare.GenericLessOrEqualIntrinsic (e1,e2) @ (7,70--7,79)"; - "let testStringGreaterThanOperator(e1) (e2) = HashCompare.GenericGreaterThanIntrinsic (e1,e2) @ (8,70--8,78)"; - "let testStringGreaterThanOrEqualsOperator(e1) (e2) = HashCompare.GenericGreaterOrEqualIntrinsic (e1,e2) @ (9,70--9,79)"; - "let testStringAdditionOperator(e1) (e2) = String.Concat (e1,e2) @ (11,62--11,70)"; - "let testStringAdditionChecked(e1) (e2) = String.Concat (e1,e2) @ (24,59--24,76)"; - "let testStringToByteChecked(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (29,47--29,62)"; - "let testStringToSByteChecked(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (30,47--30,63)"; - "let testStringToInt16Checked(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (31,47--31,63)"; - "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (32,47--32,64)"; - "let testStringToIntChecked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (33,47--33,61)"; - "let testStringToInt32Checked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (34,47--34,63)"; - "let testStringToUInt32Checked(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (35,47--35,64)"; - "let testStringToInt64Checked(e1) = LanguagePrimitives.ParseInt64 (e1) @ (36,47--36,63)"; - "let testStringToUInt64Checked(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (37,47--37,64)"; - "let testStringToByteOperator(e1) = Checked.ToByte (LanguagePrimitives.ParseUInt32 (e1)) @ (41,47--41,54)"; - "let testStringToSByteOperator(e1) = Checked.ToSByte (LanguagePrimitives.ParseInt32 (e1)) @ (42,47--42,55)"; - "let testStringToInt16Operator(e1) = Checked.ToInt16 (LanguagePrimitives.ParseInt32 (e1)) @ (43,47--43,55)"; - "let testStringToUInt16Operator(e1) = Checked.ToUInt16 (LanguagePrimitives.ParseUInt32 (e1)) @ (44,47--44,56)"; - "let testStringToIntOperator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (45,47--45,53)"; - "let testStringToInt32Operator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (46,47--46,55)"; - "let testStringToUInt32Operator(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (47,47--47,56)"; - "let testStringToInt64Operator(e1) = LanguagePrimitives.ParseInt64 (e1) @ (48,47--48,55)"; - "let testStringToUInt64Operator(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (49,47--49,56)"; - "let testStringToSingleOperator(e1) = Single.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (52,47--52,57)"; - "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (53,47--53,55)"; - "let testStringToDecimalOperator(e1) = Decimal.Parse (e1,167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (54,47--54,57)"; - "let testStringToCharOperator(e1) = Char.Parse (e1) @ (55,47--55,54)"; -#if DEBUG - @"let testStringToStringOperator(e1) = let nullStr: Microsoft.FSharp.Core.string = """" in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)" -#else - "let testStringToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box (e1) in match (if Operators.op_Equality (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,47--56,56)"; -#endif + [], "type OperatorTestsString" + [], "let testStringEqualsOperator(e1) (e2) = String.Equals (e1,e2) @ (4,69--4,78)" + [], "let testStringNotEqualsOperator(e1) (e2) = Operators.op_Equality (String.Equals (e1,e2),False) @ (5,69--5,79)" + [], "let testStringLessThanOperator(e1) (e2) = HashCompare.GenericLessThanIntrinsic (e1,e2) @ (6,69--6,78)" + [], "let testStringLessThanOrEqualsOperator(e1) (e2) = HashCompare.GenericLessOrEqualIntrinsic (e1,e2) @ (7,69--7,79)" + [], "let testStringGreaterThanOperator(e1) (e2) = HashCompare.GenericGreaterThanIntrinsic (e1,e2) @ (8,69--8,78)" + [], "let testStringGreaterThanOrEqualsOperator(e1) (e2) = HashCompare.GenericGreaterOrEqualIntrinsic (e1,e2) @ (9,69--9,79)" + [], "let testStringAdditionOperator(e1) (e2) = String.Concat (e1,e2) @ (11,61--11,70)" + [], "let testStringAdditionChecked(e1) (e2) = String.Concat (e1,e2) @ (24,59--24,76)" + [], "let testStringToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseUInt32 (e1)) @ (29,47--29,62)" + [], "let testStringToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseInt32 (e1)) @ (30,47--30,63)" + [], "let testStringToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseInt32 (e1)) @ (31,47--31,63)" + [], "let testStringToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseUInt32 (e1)) @ (32,47--32,64)" + [], "let testStringToIntChecked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (33,47--33,61)" + [], "let testStringToInt32Checked(e1) = LanguagePrimitives.ParseInt32 (e1) @ (34,47--34,63)" + [], "let testStringToUInt32Checked(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (35,47--35,64)" + [], "let testStringToInt64Checked(e1) = LanguagePrimitives.ParseInt64 (e1) @ (36,47--36,63)" + [], "let testStringToUInt64Checked(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (37,47--37,64)" + [], "let testStringToByteOperator(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseUInt32 (e1)) @ (41,47--41,54)" + [], "let testStringToSByteOperator(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseInt32 (e1)) @ (42,47--42,55)" + [], "let testStringToInt16Operator(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseInt32 (e1)) @ (43,47--43,55)" + [], "let testStringToUInt16Operator(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),LanguagePrimitives.ParseUInt32 (e1)) @ (44,47--44,56)" + [], "let testStringToIntOperator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (45,47--45,53)" + [], "let testStringToInt32Operator(e1) = LanguagePrimitives.ParseInt32 (e1) @ (46,47--46,55)" + [], "let testStringToUInt32Operator(e1) = LanguagePrimitives.ParseUInt32 (e1) @ (47,47--47,56)" + [], "let testStringToInt64Operator(e1) = LanguagePrimitives.ParseInt64 (e1) @ (48,47--48,55)" + [], "let testStringToUInt64Operator(e1) = LanguagePrimitives.ParseUInt64 (e1) @ (49,47--49,56)" + [], "let testStringToSingleOperator(e1) = Single.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (52,47--52,57)" + [], "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (53,47--53,55)" + [], "let testStringToDecimalOperator(e1) = Decimal.Parse (e1,167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (54,47--54,57)" + [], "let testStringToCharOperator(e1) = Char.Parse (e1) @ (55,47--55,54)" + [FC47; FC50], """let testStringToStringOperator(e1) = (if String.Equals (e1,dflt) then "" else e1) @ (56,47--56,56)""" ] testOperators "String" "string" excludedTests expectedUnoptimized expectedOptimized @@ -2730,20 +2993,16 @@ let ``Test Operator Declarations for String`` () = //--------------------------------------------------------------------------------------------------------- // This big list expression was causing us trouble -module internal ProjectStressBigExpressions = +module internal ProjectStressBigExpressions = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ -module StressBigExpressions +module StressBigExpressions -let BigListExpression = +let BigListExpression = [("C", "M.C", "file1", ((3, 5), (3, 6)), ["class"]); - ("( .ctor )", "M.C.( .ctor )", "file1", ((3, 5), (3, 6)),["member"; "ctor"]); + ("``.ctor``", "M.C.``.ctor``", "file1", ((3, 5), (3, 6)),["member"; "ctor"]); ("P", "M.C.P", "file1", ((4, 13), (4, 14)), ["member"; "getter"]); ("x", "x", "file1", ((4, 11), (4, 12)), []); ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file1",((6, 12), (6, 13)), ["val"]); @@ -2759,13 +3018,13 @@ let BigListExpression = ("CAbbrev", "M.CAbbrev", "file1", ((9, 5), (9, 12)), ["abbrev"]); ("M", "M", "file1", ((1, 7), (1, 8)), ["module"]); ("D1", "N.D1", "file2", ((5, 5), (5, 7)), ["class"]); - ("( .ctor )", "N.D1.( .ctor )", "file2", ((5, 5), (5, 7)),["member"; "ctor"]); - ("SomeProperty", "N.D1.SomeProperty", "file2", ((6, 13), (6, 25)),["member"; "getter"]); + ("``.ctor``", "N.D1.``.ctor``", "file2", ((5, 5), (5, 7)),["member"; "ctor"]); + ("SomeProperty", "N.D1.SomeProperty", "file2", ((6, 13), (6, 25)),["member"; "getter"]); ("x", "x", "file2", ((6, 11), (6, 12)), []); ("M", "M", "file2", ((6, 28), (6, 29)), ["module"]); ("xxx", "M.xxx", "file2", ((6, 28), (6, 33)), ["val"]); ("D2", "N.D2", "file2", ((8, 5), (8, 7)), ["class"]); - ("( .ctor )", "N.D2.( .ctor )", "file2", ((8, 5), (8, 7)),["member"; "ctor"]); + ("``.ctor``", "N.D2.``.ctor``", "file2", ((8, 5), (8, 7)),["member"; "ctor"]); ("SomeProperty", "N.D2.SomeProperty", "file2", ((9, 13), (9, 25)),["member"; "getter"]); ("x", "x", "file2", ((9, 11), (9, 12)), []); ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2",((9, 36), (9, 37)), ["val"]); ("M", "M", "file2", ((9, 28), (9, 29)), ["module"]); @@ -2784,7 +3043,7 @@ let BigListExpression = ("x", "N.D3.x", "file2", ((19, 16), (19, 17)),["field"; "default"; "mutable"]); ("D3", "N.D3", "file2", ((15, 5), (15, 7)), ["class"]); ("int", "Microsoft.FSharp.Core.int", "file2", ((15, 10), (15, 13)),["abbrev"]); ("a", "a", "file2", ((15, 8), (15, 9)), []); - ("( .ctor )", "N.D3.( .ctor )", "file2", ((15, 5), (15, 7)),["member"; "ctor"]); + ("``.ctor``", "N.D3.``.ctor``", "file2", ((15, 5), (15, 7)),["member"; "ctor"]); ("SomeProperty", "N.D3.SomeProperty", "file2", ((21, 13), (21, 25)),["member"; "getter"]); ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2",((16, 14), (16, 15)), ["val"]); ("a", "a", "file2", ((16, 12), (16, 13)), []); @@ -2833,7 +3092,7 @@ let BigListExpression = ("mmmm2", "N.mmmm2", "file2", ((39, 4), (39, 9)), ["val"]); ("N", "N", "file2", ((1, 7), (1, 8)), ["module"])] -let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = +let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = [ yield "--simpleresolution" yield "--noframework" match outFileOpt with @@ -2876,7 +3135,7 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = yield "--fullpaths" yield "--flaterrors" if true then yield "--warnaserror" - yield + yield if true then "--target:library" else "--target:exe" for symbol in [] do @@ -2893,7 +3152,7 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = else "--tailcalls-" match baseAddressOpt with | None -> () - | Some debugType -> + | Some debugType -> match "" with | "NONE" -> () | "PDBONLY" -> yield "--debug:pdbonly" @@ -2916,25 +3175,26 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = for f in [] do yield "--resource:" + f for i in [] do - yield "--lib:" + yield "--lib:" for r in [] do - yield "-r:" + r + yield "-r:" + r yield! [] ] - + """ - File.WriteAllText(fileName1, fileSource1) - let fileNames = [fileName1] - let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = exprChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + + let createOptions() = createOptionsAux [fileSource1] [] [] let ``Test expressions of declarations stress big expressions`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(ProjectStressBigExpressions.options) |> Async.RunSynchronously - - wholeProjectResults.Errors.Length |> shouldEqual 0 + let cleanup, options = ProjectStressBigExpressions.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 1 let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] @@ -2945,9 +3205,12 @@ let ``Test expressions of declarations stress big expressions`` () = [] let ``Test expressions of optimized declarations stress big expressions`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(ProjectStressBigExpressions.options) |> Async.RunSynchronously - - wholeProjectResults.Errors.Length |> shouldEqual 0 + let cleanup, options = ProjectStressBigExpressions.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.Length |> shouldEqual 1 let file1 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] @@ -2955,316 +3218,348 @@ let ``Test expressions of optimized declarations stress big expressions`` () = // This should not stack overflow printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList |> ignore +//--------------------------------------------------------------------------------------------------------- +// This project is for witness arguments (CallWithWitnesses) -#if NOT_YET_ENABLED +module internal ProjectForWitnesses1 = -#if !NO_PROJECTCRACKER && !NETCOREAPP + let fileSource1 = """ +module M + +/// One witness +let inline callX (x: ^T) (y: ^U) = ((^T or ^U): (static member X : ^T * ^U -> ^V) (x,y)) + +/// Two witnesses +let inline callXY (x: ^T) (y: ^U) = + ((^T or ^U): (static member Y1 : ^T * ^U -> unit) (x,y)) + ((^T or ^U): (static member Y2 : ^T * ^U -> unit) (x,y)) + +type C() = + static member X(a: C, b: C) = C() + static member X(a: C, b: D) = D() + static member Y1(a: C, b: C) = () + static member Y1(a: C, b: D) = () + static member Y2(a: C, b: C) = () + static member Y2(a: C, b: D) = () + +and D() = + static member X(a: D, b: D) = D() + static member X(a: D, b: C) = C() + static member Y1(a: D, b: D) = () + static member Y1(a: D, b: C) = () + static member Y2(a: D, b: D) = () + static member Y2(a: D, b: C) = () + +let f1() = callX (C()) (C()) +let f2() = callX (D()) (D()) +let f3() = callX (C()) (D()) +let f4() = callX (D()) (C()) + +let f5() = callXY (C()) (C()) +let f6() = callXY (D()) (D()) +let f7() = callXY (C()) (D()) +let f8() = callXY (D()) (C()) + """ + + let createOptions() = createOptionsAux [fileSource1] ["--langversion:preview"] [] -let ``Check use of type provider that provides calls to F# code`` () = - let config = -#if DEBUG - ["Configuration", "Debug"] -#else - ["Configuration", "Release"] -#endif - let options = - ProjectCracker.GetProjectOptionsFromProjectFile (Path.Combine(Path.Combine(Path.Combine(__SOURCE_DIRECTORY__, "data"),"TestProject"),"TestProject.fsproj"), config) - - let res = - options - |> exprChecker.ParseAndCheckProject - |> Async.RunSynchronously - - Assert.AreEqual ([||], res.Errors, sprintf "Should not be errors, but: %A" res.Errors) - - let results = - [ for f in res.AssemblyContents.ImplementationFiles do - for d in f.Declarations do - for line in d |> printDeclaration None do - yield line ] - - results |> List.iter (printfn "%s") - - results |> shouldEqual - ["type TestProject"; "type AssemblyInfo"; "type TestProject"; "type T"; - """type Class1"""; - """member .ctor(unitVar0) = (new Object(); ()) @ (5,5--5,11)"""; - """member get_X1(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothing () @ (6,21--6,36)""" - """member get_X2(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingGeneric (3) @ (7,21--7,43)""" - """member get_X3(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingOneArg (3) @ (8,21--8,42)""" - """member get_X4(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in C.DoNothing () @ (9,21--9,41)""" - """member get_X5(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in C.DoNothingGeneric (3) @ (10,21--10,48)""" - """member get_X6(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in C.DoNothingOneArg (3) @ (11,21--11,47)""" - """member get_X7(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in C.DoNothingTwoArg (new C(),3) @ (12,21--12,47)""" - """member get_X8(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().InstanceDoNothing() @ (13,21--13,49)""" - """member get_X9(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().InstanceDoNothingGeneric(3) @ (14,21--14,56)""" - """member get_X10(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().InstanceDoNothingOneArg(3) @ (15,22--15,56)""" - """member get_X11(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().InstanceDoNothingTwoArg(new C(),3) @ (16,22--16,56)""" - """member get_X12(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in G`1.DoNothing () @ (17,22--17,49)""" - """member get_X13(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in G`1.DoNothingOneArg (3) @ (18,22--18,55)""" - """member get_X14(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in G`1.DoNothingTwoArg (new C(),3) @ (19,22--19,55)""" - """member get_X15(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let matchValue: Microsoft.FSharp.Core.Option = FSharpOption`1.Some (1) in (if Operators.op_Equality (matchValue.Tag,1) then let x: Microsoft.FSharp.Core.int = matchValue.get_Value() in x else 0) @ (20,22--20,54)""" - """member get_X16(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let matchValue: Microsoft.FSharp.Core.Choice = Choice1Of2(1) in (if Operators.op_Equality (matchValue.Tag,0) then 1 else 0) @ (21,22--21,54)""" - """member get_X17(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let r: TestTP.Helper.R = {A = 1; B = 0} in (r.B <- 1; r.A) @ (22,22--22,60)""" - """member get_X18(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingTwoArg (3,4) @ (23,22--23,43)""" - """member get_X19(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingTwoArgCurried (3,4) @ (24,22--24,50)""" - """member get_X21(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (fun arg00 -> fun arg10 -> C.DoNothingTwoArgCurried (arg00,arg10) new C()) 3 @ (25,22--25,55)""" - """member get_X23(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (let objectArg: TestTP.Helper.C = new C() in fun arg00 -> fun arg10 -> objectArg.InstanceDoNothingTwoArgCurried(arg00,arg10) new C()) 3 @ (26,22--26,63)""" - """member get_X24(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingGenericWithConstraint (3) @ (27,22--27,58)""" - """member get_X25(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingGenericWithTypeConstraint,Microsoft.FSharp.Core.int> (FSharpList`1.Cons (3,FSharpList`1.get_Empty ())) @ (28,22--28,62)""" - """member get_X26(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.doNothingGenericWithTypeConstraint,Microsoft.FSharp.Core.int> (FSharpList`1.Cons (3,FSharpList`1.get_Empty ())) @ (29,22--29,62)""" - """member get_X27(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Helper.DoNothingReally () @ (30,22--30,53)""" - """member get_X28(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new CSharpClass(0).Method("x") :> Microsoft.FSharp.Core.Unit @ (31,22--31,40)""" - """member get_X29(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in Operators.op_Addition (new CSharpClass(0).Method2("x"),new CSharpClass(0).Method2("empty")) :> Microsoft.FSharp.Core.Unit @ (32,22--32,53)""" - """member get_X30(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new CSharpClass(0).Method3([|"x"; "y"|]) :> Microsoft.FSharp.Core.Unit @ (33,22--33,50)""" - """member get_X31(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new CSharpClass(0).GenericMethod(2) @ (34,22--34,47)""" - """member get_X32(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new CSharpClass(0).GenericMethod2(new Object()) @ (35,22--35,61)""" - """member get_X33(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new CSharpClass(0).GenericMethod3(3) @ (36,22--36,65)""" - """member get_X34(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in C.DoNothingReally () @ (37,22--37,58)""" - """member get_X35(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().DoNothingReallyInst() @ (38,22--38,66)""" - """member get_X36(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (new CSharpClass(0) :> FSharp.Compiler.Service.Tests.ICSharpExplicitInterface).ExplicitMethod("x") :> Microsoft.FSharp.Core.Unit @ (39,22--39,62)""" - """member get_X37(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (new C() :> TestTP.Helper.I).DoNothing() @ (40,22--40,46)""" - """member get_X38(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in new C().VirtualDoNothing() @ (41,22--41,45)""" - """member get_X39(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let t: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int = (1,2,3) in let i: Microsoft.FSharp.Core.int = t.Item1 in i @ (42,22--42,51)""" - """member get_X40(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (moduleValue <- 1; moduleValue) @ (43,22--43,39)""" - """member get_X41(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let x: TestTP.Helper.C = new C() in (x.set_Property(1); x.get_Property()) @ (44,22--44,41)""" - """member get_X42(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in let x: TestTP.Helper.C = new C() in (x.set_AutoProperty(1); x.get_AutoProperty()) @ (45,22--45,45)""" - """member get_X43(this) (unitVar1) = let this: Microsoft.FSharp.Core.obj = ("My internal state" :> Microsoft.FSharp.Core.obj) :> ErasedWithConstructor.Provided.MyType in (C.set_StaticAutoProperty (1); C.get_StaticAutoProperty ()) @ (46,22--46,51)""" - ] +let ``Test ProjectForWitnesses1`` () = + let cleanup, options = ProjectForWitnesses1.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate - let members = - [ for f in res.AssemblyContents.ImplementationFiles do yield! printMembersOfDeclatations f.Declarations ] - - members |> List.iter (printfn "%s") - - members |> shouldEqual - [ - ".ctor: Microsoft.FSharp.Core.unit -> TestProject.Class1" - ".ctor: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X1: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X2: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingGeneric<'T>: 'T -> Microsoft.FSharp.Core.unit" - "get_X3: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingOneArg: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X4: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X5: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingGeneric<'T>: 'T -> Microsoft.FSharp.Core.unit" - "get_X6: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingOneArg: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X7: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingTwoArg: TestTP.Helper.C * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "get_X8: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "InstanceDoNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X9: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "InstanceDoNothingGeneric<'T>: 'T -> Microsoft.FSharp.Core.unit" - "get_X10: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "InstanceDoNothingOneArg: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X11: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "InstanceDoNothingTwoArg: TestTP.Helper.C * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "get_X12: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X13: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingOneArg: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X14: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingTwoArg: TestTP.Helper.C * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "get_X15: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "Some: 'T -> 'T Microsoft.FSharp.Core.option" - "op_Equality<'T when 'T : equality>: 'T -> 'T -> Microsoft.FSharp.Core.bool" - "matchValue: Microsoft.FSharp.Core.Option" - "matchValue: Microsoft.FSharp.Core.Option" - "get_Value: Microsoft.FSharp.Core.unit -> 'T" - "x: Microsoft.FSharp.Core.int" - "get_X16: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "op_Equality<'T when 'T : equality>: 'T -> 'T -> Microsoft.FSharp.Core.bool" - "matchValue: Microsoft.FSharp.Core.Choice" - "get_X17: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "r: TestTP.Helper.R" - "r: TestTP.Helper.R" - "get_X18: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingTwoArg: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X19: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingTwoArgCurried: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_X21: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingTwoArgCurried: TestTP.Helper.C -> Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "arg00: TestTP.Helper.C" - "arg10: Microsoft.FSharp.Core.int" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "get_X23: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "objectArg: TestTP.Helper.C" - "InstanceDoNothingTwoArgCurried: TestTP.Helper.C -> Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "arg00: TestTP.Helper.C" - "arg10: Microsoft.FSharp.Core.int" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "get_X24: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingGenericWithConstraint<'T when 'T : equality>: 'T -> Microsoft.FSharp.Core.unit" - "get_X25: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingGenericWithTypeConstraint<'T, _ when 'T :> Microsoft.FSharp.Collections.seq<'a>>: 'T -> Microsoft.FSharp.Core.unit" - "Cons: 'T * 'T Microsoft.FSharp.Collections.list -> 'T Microsoft.FSharp.Collections.list" - "get_Empty: Microsoft.FSharp.Core.unit -> 'T Microsoft.FSharp.Collections.list" - "get_X26: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "doNothingGenericWithTypeConstraint<'T, _ when 'T :> Microsoft.FSharp.Collections.seq<'a>>: 'T -> Microsoft.FSharp.Core.unit" - "Cons: 'T * 'T Microsoft.FSharp.Collections.list -> 'T Microsoft.FSharp.Collections.list" - "get_Empty: Microsoft.FSharp.Core.unit -> 'T Microsoft.FSharp.Collections.list" - "get_X27: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingReally: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X28: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "Method: Microsoft.FSharp.Core.string -> Microsoft.FSharp.Core.int" - "get_X29: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "op_Addition<^T1, ^T2, ^T3>: ^T1 -> ^T2 -> ^T3" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "Method2: Microsoft.FSharp.Core.string -> Microsoft.FSharp.Core.int" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "Method2: Microsoft.FSharp.Core.string -> Microsoft.FSharp.Core.int" - "get_X30: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "Method3: Microsoft.FSharp.Core.string Microsoft.FSharp.Core.[] -> Microsoft.FSharp.Core.int" - "get_X31: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "GenericMethod<'T>: 'T -> Microsoft.FSharp.Core.unit" - "get_X32: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "GenericMethod2<'T when 'T : class>: 'T -> Microsoft.FSharp.Core.unit" - ".ctor: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X33: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "GenericMethod3<'T when 'T :> System.IComparable<'T>>: 'T -> Microsoft.FSharp.Core.unit" - "get_X34: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - "DoNothingReally: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X35: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "DoNothingReallyInst: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X36: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "ExplicitMethod: Microsoft.FSharp.Core.string -> Microsoft.FSharp.Core.int" - "get_X37: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "DoNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X38: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.Unit" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "VirtualDoNothing: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.unit" - "get_X39: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "t: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int" - "i: Microsoft.FSharp.Core.int" - "get_X40: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "moduleValue: Microsoft.FSharp.Core.int" - "moduleValue: Microsoft.FSharp.Core.int" - "get_X41: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "x: TestTP.Helper.C" - "set_Property: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "x: TestTP.Helper.C" - "get_Property: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "get_X42: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - ".ctor: Microsoft.FSharp.Core.unit -> TestTP.Helper.C" - "x: TestTP.Helper.C" - "set_AutoProperty: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "x: TestTP.Helper.C" - "get_AutoProperty: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "get_X43: TestProject.Class1 -> Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - "set_StaticAutoProperty: Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.unit" - "get_StaticAutoProperty: Microsoft.FSharp.Core.unit -> Microsoft.FSharp.Core.int" - ] + for e in wholeProjectResults.Diagnostics do + printfn "Project1 error: <<<%s>>>" e.Message -#endif -#endif + wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 1 + let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] + let expected = + ["type M"; "let callX(x) (y) = trait call X(x,y) @ (5,35--5,88)"; + "let callXY(x) (y) = (trait call Y1(x,y); trait call Y2(x,y)) @ (9,4--10,60)"; + "type C"; "type D"; + "member .ctor(unitVar0) = (new Object(); ()) @ (12,5--12,6)"; + "member X(a,b) = new C(()) @ (13,34--13,37)"; + "member X(a,b) = new D(()) @ (14,34--14,37)"; + "member Y1(a,b) = () @ (15,35--15,37)"; "member Y1(a,b) = () @ (16,35--16,37)"; + "member Y2(a,b) = () @ (17,35--17,37)"; "member Y2(a,b) = () @ (18,35--18,37)"; + "member .ctor(unitVar0) = (new Object(); ()) @ (20,4--20,5)"; + "member X(a,b) = new D(()) @ (21,34--21,37)"; + "member X(a,b) = new C(()) @ (22,34--22,37)"; + "member Y1(a,b) = () @ (23,35--23,37)"; "member Y1(a,b) = () @ (24,35--24,37)"; + "member Y2(a,b) = () @ (25,35--25,37)"; "member Y2(a,b) = () @ (26,35--26,37)"; + "let f1(unitVar0) = M.callX (fun arg0_0 -> fun arg1_0 -> C.X (arg0_0,arg1_0),new C(()),new C(())) @ (28,11--28,28)"; + "let f2(unitVar0) = M.callX (fun arg0_0 -> fun arg1_0 -> D.X (arg0_0,arg1_0),new D(()),new D(())) @ (29,11--29,28)"; + "let f3(unitVar0) = M.callX (fun arg0_0 -> fun arg1_0 -> C.X (arg0_0,arg1_0),new C(()),new D(())) @ (30,11--30,28)"; + "let f4(unitVar0) = M.callX (fun arg0_0 -> fun arg1_0 -> D.X (arg0_0,arg1_0),new D(()),new C(())) @ (31,11--31,28)"; + "let f5(unitVar0) = M.callXY (fun arg0_0 -> fun arg1_0 -> C.Y1 (arg0_0,arg1_0),fun arg0_0 -> fun arg1_0 -> C.Y2 (arg0_0,arg1_0),new C(()),new C(())) @ (33,11--33,29)"; + "let f6(unitVar0) = M.callXY (fun arg0_0 -> fun arg1_0 -> D.Y1 (arg0_0,arg1_0),fun arg0_0 -> fun arg1_0 -> D.Y2 (arg0_0,arg1_0),new D(()),new D(())) @ (34,11--34,29)"; + "let f7(unitVar0) = M.callXY (fun arg0_0 -> fun arg1_0 -> C.Y1 (arg0_0,arg1_0),fun arg0_0 -> fun arg1_0 -> C.Y2 (arg0_0,arg1_0),new C(()),new D(())) @ (35,11--35,29)"; + "let f8(unitVar0) = M.callXY (fun arg0_0 -> fun arg1_0 -> D.Y1 (arg0_0,arg1_0),fun arg0_0 -> fun arg1_0 -> D.Y2 (arg0_0,arg1_0),new D(()),new C(())) @ (36,11--36,29)"] + + let actual = + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + printfn "actual:\n\n%A" actual + actual + |> shouldPairwiseEqual expected -#if SELF_HOST_STRESS - [] -let ``Test Declarations selfhost`` () = - let projectFile = __SOURCE_DIRECTORY__ + @"/FSharp.Compiler.Service.Tests.fsproj" - // Check with Configuration = Release - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Debug")]) - let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously - - wholeProjectResults.Errors.Length |> shouldEqual 0 +let ``Test ProjectForWitnesses1 GetWitnessPassingInfo`` () = + let cleanup, options = ProjectForWitnesses1.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForWitnesses1 error: <<<%s>>>" e.Message + + begin + let symbol = + wholeProjectResults.GetAllUsesOfAllSymbols() + |> Array.tryFind (fun su -> su.Symbol.DisplayName = "callX") + |> Option.orElseWith (fun _ -> failwith "Could not get symbol") + |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) + |> Option.get + printfn "symbol = %s" symbol.FullName + let wpi = (symbol.GetWitnessPassingInfo()) + match wpi with + | None -> failwith "witness passing info expected" + | Some (nm, argTypes) -> + nm |> shouldEqual "callX$W" + argTypes.Count |> shouldEqual 1 + let argText = argTypes.[0].Type.ToString() + argText |> shouldEqual "type ^T -> ^U -> ^V" + end + + + begin + let symbol = + wholeProjectResults.GetAllUsesOfAllSymbols() + |> Array.tryFind (fun su -> su.Symbol.DisplayName = "callXY") + |> Option.orElseWith (fun _ -> failwith "Could not get symbol") + |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) + |> Option.get + printfn "symbol = %s" symbol.FullName + let wpi = (symbol.GetWitnessPassingInfo()) + match wpi with + | None -> failwith "witness passing info expected" + | Some (nm, argTypes) -> + nm |> shouldEqual "callXY$W" + argTypes.Count |> shouldEqual 2 + let argName1 = argTypes.[0].Name + let argText1 = argTypes.[0].Type.ToString() + let argName2 = argTypes.[1].Name + let argText2 = argTypes.[1].Type.ToString() + argText1 |> shouldEqual "type ^T -> ^U -> Microsoft.FSharp.Core.unit" + argText2 |> shouldEqual "type ^T -> ^U -> Microsoft.FSharp.Core.unit" + end + - wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 13 +//--------------------------------------------------------------------------------------------------------- +// This project is for witness arguments (CallWithWitnesses) - let textOfAll = [ for file in wholeProjectResults.AssemblyContents.ImplementationFiles -> Array.ofSeq (printDeclarations None (List.ofSeq file.Declarations)) ] +module internal ProjectForWitnesses2 = - () + let fileSource1 = """ +module M + +type Point = + { x: int; y: int } + static member Zero = { x=0; y=0 } + static member Neg(p: Point) = { x = -p.x; y = -p.y } + static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y } + +type MyNumber = + | MyNumber of int + static member Zero = MyNumber 0 + static member (+) (MyNumber x, MyNumber y) = + MyNumber(x + y) + static member DivideByInt (MyNumber x, i: int) = + MyNumber(x / i) + +type MyNumberWrapper = + { MyNumber: MyNumber } + """ + let createOptions() = createOptionsAux [fileSource1] ["--langversion:preview"] [] -let ``Test Declarations selfhost whole compiler`` () = - - Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__ + @"/../../src/fsharp/FSharp.Compiler.Service") - let projectFile = __SOURCE_DIRECTORY__ + @"/../../src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj" - - //let v = FSharpProjectFileInfo.Parse(projectFile, [("Configuration", "Debug"); ("NoFsSrGenTask", "true")],enableLogging=true) - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Debug"); ("NoFsSrGenTask", "true")]) - - // For subsets of the compiler: - //let options = { options with OtherOptions = options.OtherOptions.[0..51] } - - //for x in options.OtherOptions do printfn "%s" x - - let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously - - (wholeProjectResults.Errors |> Array.filter (fun x -> x.Severity = FSharpErrorSeverity.Error)).Length |> shouldEqual 0 - - for file in (wholeProjectResults.AssemblyContents.ImplementationFiles |> List.toArray) do - for d in file.Declarations do - for s in printDeclaration None d do - () //printfn "%s" s - - // Very Quick (1 sec - expressions are computed on demand) - for file in (wholeProjectResults.AssemblyContents.ImplementationFiles |> List.toArray) do - for d in file.Declarations do - for s in exprsOfDecl d do - () - - // Quickish (~4.5 seconds for all of FSharp.Compiler.Service.dll) - #time "on" - for file in (wholeProjectResults.AssemblyContents.ImplementationFiles |> List.toArray) do - for d in file.Declarations do - for (e,m) in exprsOfDecl d do - // This forces the computation of the expression - match e with - | BasicPatterns.Const _ -> () //printfn "%s" s - | _ -> () //printfn "%s" s +let ``Test ProjectForWitnesses2`` () = + let cleanup, options = ProjectForWitnesses2.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForWitnesses2 error: <<<%s>>>" e.Message + + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 + wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 1 + let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] + + let expected = + ["type M"; "type Point"; + "member get_Zero(unitVar0) = {x = 0; y = 0} @ (6,25--6,37)"; + "member Neg(p) = {x = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),p.x); y = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),p.y)} @ (7,34--7,56)"; + "member op_Addition(p1,p2) = {x = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.x,p2.x); y = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.y,p2.y)} @ (8,33--8,68)"; + "type MyNumber"; "member get_Zero(unitVar0) = MyNumber(0) @ (12,25--12,35)"; + "member op_Addition(_arg1,_arg2) = let x: Microsoft.FSharp.Core.int = _arg1.Item in let y: Microsoft.FSharp.Core.int = _arg2.Item in MyNumber(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y)) @ (13,23--13,33)"; + "member DivideByInt(_arg3,i) = let x: Microsoft.FSharp.Core.int = _arg3.Item in MyNumber(Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),x,i)) @ (15,31--15,41)"; + "type MyNumberWrapper"] + + let actual = + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + printfn "actual:\n\n%A" actual + actual + |> shouldPairwiseEqual expected + +//--------------------------------------------------------------------------------------------------------- +// This project is for witness arguments, testing for https://github.com/dotnet/fsharp/issues/10364 + +module internal ProjectForWitnesses3 = + + let fileSource1 = """ +module M + +type Point = + { x: int; y: int } + static member Zero = { x=0; y=0 } + member p.Sign = sign p.x + + static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y } + +let p1 = {x=1; y=10} +let p2 = {x=2; y=20} +let s = List.sum [p1; p2] +let s2 = sign p1 + + """ + + let createOptions() = createOptionsAux [fileSource1] ["--langversion:preview"] [] -let ``Test Declarations selfhost FSharp.Core`` () = - - Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__ + @"/../../../fsharp/src/fsharp/FSharp.Core") - let projectFile = __SOURCE_DIRECTORY__ + @"/../../../fsharp/src/fsharp/FSharp.Core/FSharp.Core.fsproj" +let ``Test ProjectForWitnesses3`` () = + let cleanup, options = createOptionsAux [ ProjectForWitnesses3.fileSource1 ] ["--langversion:preview"] + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForWitnesses3 error: <<<%s>>>" e.Message + + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 + wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 1 + let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Debug")]) + let expected = + ["type M"; "type Point"; + "member get_Zero(unitVar0) = {x = 0; y = 0} @ (6,25--6,37)"; + "member get_Sign(p) (unitVar1) = Operators.Sign (fun arg0_0 -> Operators.Sign (arg0_0),p.x) @ (7,20--7,28)"; + "member op_Addition(p1,p2) = {x = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.x,p2.x); y = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.y,p2.y)} @ (9,33--9,68)"; + "let p1 = {x = 1; y = 10} @ (11,9--11,20)"; + "let p2 = {x = 2; y = 20} @ (12,9--12,20)"; + "let s = ListModule.Sum (fun arg0_0 -> Point.get_Zero (()),fun arg0_0 -> fun arg1_0 -> Point.op_Addition (arg0_0,arg1_0),Cons(M.p1 (),Cons(M.p2 (),Empty()))) @ (13,8--13,25)"; + "let s2 = Operators.Sign (fun arg0_0 -> arg0_0.get_Sign(()),M.p1 ()) @ (14,9--14,16)"] + + let actual = + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + printfn "actual:\n\n%A" actual + actual + |> shouldPairwiseEqual expected - let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously - - //(wholeProjectResults.Errors |> Array.filter (fun x -> x.Severity = FSharpErrorSeverity.Error)).Length |> shouldEqual 0 +[] +let ``Test ProjectForWitnesses3 GetWitnessPassingInfo`` () = + let cleanup, options = ProjectForWitnesses3.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForWitnesses3 error: <<<%s>>>" e.Message + + begin + let symbol = + wholeProjectResults.GetAllUsesOfAllSymbols() + |> Array.tryFind (fun su -> su.Symbol.DisplayName = "sum") + |> Option.orElseWith (fun _ -> failwith "Could not get symbol") + |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) + |> Option.get + printfn "symbol = %s" symbol.FullName + let wpi = (symbol.GetWitnessPassingInfo()) + match wpi with + | None -> failwith "witness passing info expected" + | Some (nm, argTypes) -> + nm |> shouldEqual "Sum$W" + argTypes.Count |> shouldEqual 2 + let argName1 = argTypes.[0].Name + let argText1 = argTypes.[0].Type.ToString() + let argName2 = argTypes.[1].Name + let argText2 = argTypes.[1].Type.ToString() + argName1 |> shouldEqual (Some "get_Zero") + argText1 |> shouldEqual "type Microsoft.FSharp.Core.unit -> ^T" + argName2 |> shouldEqual (Some "op_Addition") + argText2 |> shouldEqual "type ^T -> ^T -> ^T" + end + +//--------------------------------------------------------------------------------------------------------- +// This project is for witness arguments, testing for https://github.com/dotnet/fsharp/issues/10364 - for file in (wholeProjectResults.AssemblyContents.ImplementationFiles |> List.toArray) do - for d in file.Declarations do - for s in printDeclaration (Some (HashSet [])) d do - printfn "%s" s +module internal ProjectForWitnesses4 = - #time "on" + let fileSource1 = """ +module M - for file in (wholeProjectResults.AssemblyContents.ImplementationFiles |> List.toArray) do - for d in file.Declarations do - for (e,m) in exprsOfDecl d do - // This forces the computation of the expression - match e with - | BasicPatterns.Const _ -> () - | _ -> () +let isEmptyArray x = + match x with + | [| |] -> x + | _ -> x -#endif +let isNull (ts : 't[]) = + match ts with + | null -> true + | _ -> false + +let isNullQuoted (ts : 't[]) = + <@ + match ts with + | null -> true + | _ -> false + @> + +""" + + let createOptions() = createOptionsAux [fileSource1] ["--langversion:preview"] + +[] +let ``Test ProjectForWitnesses4 GetWitnessPassingInfo`` () = + let cleanup, options = ProjectForWitnesses4.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForWitnesses4 error: <<<%s>>>" e.Message + + Assert.AreEqual(wholeProjectResults.Diagnostics.Length, 0) + + wholeProjectResults.AssemblyContents.ImplementationFiles.Length |> shouldEqual 1 + let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] + let expected = + ["type M"; + "let isEmptyArray(x) = (if (if Operators.op_Inequality<'a Microsoft.FSharp.Core.[]> (x,dflt) then Operators.op_Equality (ArrayModule.Length<'a> (x),0) else False) then x else x) @ (5,10--5,11)"; + "let isNull(ts) = (if Operators.op_Equality<'t Microsoft.FSharp.Core.[]> (ts,dflt) then True else False) @ (10,10--10,12)"; + "let isNullQuoted(ts) = quote((if Operators.op_Equality<'t Microsoft.FSharp.Core.[]> (ts,dflt) then True else False)) @ (15,4--19,6)"] + + let actual = + printDeclarations None (List.ofSeq file1.Declarations) + |> Seq.toList + printfn "actual:\n\n%A" actual + actual + |> shouldPairwiseEqual expected diff --git a/tests/service/ExtensionTypingProviderTests.fs b/tests/service/ExtensionTypingProviderTests.fs new file mode 100644 index 00000000000..f8a48574b07 --- /dev/null +++ b/tests/service/ExtensionTypingProviderTests.fs @@ -0,0 +1,114 @@ +#if INTERACTIVE +#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive +#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" +#load "FsUnit.fs" +#load "Common.fs" +#else +module FSharp.Compiler.Service.Tests.ExtensionTypingProvider +#endif + +open System +open System.Collections.Generic +open System.IO +open FsUnit +open NUnit.Framework +open FSharp.Compiler.ExtensionTyping +open FSharp.Compiler.Service.Tests.Common +open Microsoft.FSharp.Core.CompilerServices + +let fileName, options = + mkTestFileAndOptions "" + [| @"-r:" + Path.Combine(__SOURCE_DIRECTORY__, Path.Combine("data", "FSharp.Data.dll")) + @"-r:" + sysLib "System.Xml.Linq" |] + +type ProxyProvidedNamespace(pn: IProvidedNamespace, typesCache: Dictionary<_, _>) = + interface IProvidedNamespace with + member this.GetNestedNamespaces() = [| |] + member this.GetTypes() = + let types = pn.GetTypes() + for t in types do typesCache.Add(t.Name, t) + types + member this.ResolveTypeName(name) = + if typesCache.ContainsKey(name) then typesCache.[name] else null + member this.NamespaceName = pn.NamespaceName + +type ProxyTypeProvider(tp: ITypeProvider, typesCache: Dictionary<_,_>) = + interface ITypeProvider with + member this.GetStaticParameters t = tp.GetStaticParameters t + member this.ApplyStaticArguments(a,b,c) = tp.ApplyStaticArguments(a, b, c) + member this.GetNamespaces() = tp.GetNamespaces() |> Array.map(fun pn -> ProxyProvidedNamespace(pn, typesCache) :> _) + member this.GetInvokerExpression(methodBase, args) = tp.GetInvokerExpression(methodBase, args) + + [] + member this.Invalidate = tp.Invalidate + member this.GetGeneratedAssemblyContents(a) = tp.GetGeneratedAssemblyContents(a) + + interface ITypeProvider2 with + member this.GetStaticParametersForMethod t = (tp :?> ITypeProvider2).GetStaticParametersForMethod t + member this.ApplyStaticArgumentsForMethod(a,b,c) = (tp :?> ITypeProvider2).ApplyStaticArgumentsForMethod(a,b,c) + + interface IDisposable with + member this.Dispose() = tp.Dispose() + +[] +#if NETCOREAPP +[] +#endif +let ``Extension typing proxy shim gets requests`` () = + let mutable gotInstantiateTypeProvidersOfAssemblyRequest = false + let mutable gotGetProvidedTypesRequest = false + let mutable gotResolveTypeNameRequest = false + let mutable gotGetInvokerExpressionRequest = false + let mutable gotDisplayNameOfTypeProviderRequest = false + + let defaultExtensionTypingShim = ExtensionTypingProvider + + let extensionTypingProvider = + { new IExtensionTypingProvider with + member this.InstantiateTypeProvidersOfAssembly(context) = + gotInstantiateTypeProvidersOfAssemblyRequest <- true + defaultExtensionTypingShim.InstantiateTypeProvidersOfAssembly(context) + |> List.map(fun tp -> new ProxyTypeProvider(tp, Dictionary<_,_>()) :> _) + + member this.GetProvidedTypes(pn: IProvidedNamespace) = + gotGetProvidedTypesRequest <- true + pn :? ProxyProvidedNamespace |> should be True + defaultExtensionTypingShim.GetProvidedTypes(pn) + + member this.ResolveTypeName(pn: IProvidedNamespace, typeName: string) = + gotResolveTypeNameRequest <- true + pn :? ProxyProvidedNamespace |> should be True + defaultExtensionTypingShim.ResolveTypeName(pn, typeName) + + member this.GetInvokerExpression(provider: ITypeProvider, methodBase: ProvidedMethodBase, paramExprs: ProvidedVar[]) = + gotGetInvokerExpressionRequest <- true + provider :? ProxyTypeProvider |> should be True + defaultExtensionTypingShim.GetInvokerExpression(provider, methodBase, paramExprs) + + member this.DisplayNameOfTypeProvider(tp: ITypeProvider, fullName: bool) = + gotDisplayNameOfTypeProviderRequest <- true + tp :? ProxyTypeProvider |> should be True + defaultExtensionTypingShim.DisplayNameOfTypeProvider(tp, fullName) + } + + ExtensionTypingProvider <- extensionTypingProvider + + let result = + parseAndCheckFile fileName """ +module TypeProviderTests +open FSharp.Data + +type Detailed = XmlProvider<"Alex"> +let info = Detailed.Parse("Eugene") +""" options + |> snd + + gotInstantiateTypeProvidersOfAssemblyRequest |> should be True + gotGetProvidedTypesRequest |> should be True + gotResolveTypeNameRequest |> should be True + gotGetInvokerExpressionRequest |> should be True + //TODO: example with gotDisplayNameOfTypeProviderRequest |> should be True + + result.Diagnostics.Length = 0 |> should be True + + ExtensionTypingProvider <- defaultExtensionTypingShim diff --git a/tests/service/FileSystemTests.fs b/tests/service/FileSystemTests.fs index 59bb29f0553..cfc66c64e88 100644 --- a/tests/service/FileSystemTests.fs +++ b/tests/service/FileSystemTests.fs @@ -13,107 +13,82 @@ open FsUnit open System open System.IO open System.Text -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO open FSharp.Compiler.Service.Tests.Common + let fileName1 = @"c:\mycode\test1.fs" // note, the path doesn' exist let fileName2 = @"c:\mycode\test2.fs" // note, the path doesn' exist -type internal MyFileSystem(defaultFileSystem:IFileSystem) = - let file1 = """ +#nowarn "57" + +let file1 = """ module File1 let A = 1""" - let file2 = """ + +let file2 = """ module File2 let B = File1.A + File1.A""" - let files = dict [(fileName1, file1); (fileName2, file2)] - interface IFileSystem with +type internal MyFileSystem() = + inherit DefaultFileSystem() + static member FilesCache = dict [(fileName1, file1); (fileName2, file2)] // Implement the service to open files for reading and writing - member __.FileStreamReadShim(fileName) = - match files.TryGetValue fileName with - | true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream - | _ -> defaultFileSystem.FileStreamReadShim(fileName) - - member __.FileStreamCreateShim(fileName) = - defaultFileSystem.FileStreamCreateShim(fileName) - - member __.IsStableFileHeuristic(fileName) = - defaultFileSystem.IsStableFileHeuristic(fileName) - - member __.FileStreamWriteExistingShim(fileName) = - defaultFileSystem.FileStreamWriteExistingShim(fileName) - - member __.ReadAllBytesShim(fileName) = - match files.TryGetValue fileName with - | true, text -> Encoding.UTF8.GetBytes(text) - | _ -> defaultFileSystem.ReadAllBytesShim(fileName) - - // Implement the service related to temporary paths and file time stamps - member __.GetTempPathShim() = defaultFileSystem.GetTempPathShim() - member __.GetLastWriteTimeShim(fileName) = defaultFileSystem.GetLastWriteTimeShim(fileName) - member __.GetFullPathShim(fileName) = defaultFileSystem.GetFullPathShim(fileName) - member __.IsInvalidPathShim(fileName) = defaultFileSystem.IsInvalidPathShim(fileName) - member __.IsPathRootedShim(fileName) = defaultFileSystem.IsPathRootedShim(fileName) - - // Implement the service related to file existence and deletion - member __.SafeExists(fileName) = files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName) - member __.FileDelete(fileName) = defaultFileSystem.FileDelete(fileName) - - // Implement the service related to assembly loading, used to load type providers - // and for F# interactive. - member __.AssemblyLoadFrom(fileName) = defaultFileSystem.AssemblyLoadFrom fileName - member __.AssemblyLoad(assemblyName) = defaultFileSystem.AssemblyLoad assemblyName - -let UseMyFileSystem() = - let myFileSystem = MyFileSystem(Shim.FileSystem) - Shim.FileSystem <- myFileSystem - { new IDisposable with member x.Dispose() = Shim.FileSystem <- myFileSystem } - + override _.OpenFileForReadShim(filePath, ?useMemoryMappedFile: bool, ?shouldShadowCopy: bool) = + let shouldShadowCopy = defaultArg shouldShadowCopy false + let useMemoryMappedFile = defaultArg useMemoryMappedFile false + match MyFileSystem.FilesCache.TryGetValue filePath with + | true, text -> + new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream + | _ -> base.OpenFileForReadShim(filePath, useMemoryMappedFile, shouldShadowCopy) + override _.FileExistsShim(fileName) = MyFileSystem.FilesCache.ContainsKey(fileName) || base.FileExistsShim(fileName) + +let UseMyFileSystem() = + let myFileSystem = MyFileSystem() + FileSystemAutoOpens.FileSystem <- myFileSystem + { new IDisposable with member x.Dispose() = FileSystemAutoOpens.FileSystem <- myFileSystem } [] #if NETCOREAPP [] #endif -let ``FileSystem compilation test``() = - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows +let ``FileSystem compilation test``() = + if Environment.OSVersion.Platform = PlatformID.Win32NT then // file references only valid on Windows use myFileSystem = UseMyFileSystem() - let programFilesx86Folder = System.Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") - - let projectOptions = - let allFlags = - [| yield "--simpleresolution"; - yield "--noframework"; - yield "--debug:full"; - yield "--define:DEBUG"; - yield "--optimize-"; - yield "--doc:test.xml"; - yield "--warn:3"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:library"; - for r in [ sysLib "mscorlib"; sysLib "System"; sysLib "System.Core"; fsCoreDefaultReference() ] do + let programFilesx86Folder = Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") + + let projectOptions = + let allFlags = + [| yield "--simpleresolution"; + yield "--noframework"; + yield "--debug:full"; + yield "--define:DEBUG"; + yield "--optimize-"; + yield "--doc:test.xml"; + yield "--warn:3"; + yield "--fullpaths"; + yield "--flaterrors"; + yield "--target:library"; + for r in [ sysLib "mscorlib"; sysLib "System"; sysLib "System.Core"; fsCoreDefaultReference() ] do yield "-r:" + r |] - + { ProjectFileName = @"c:\mycode\compilation.fsproj" // Make a name that is unique in this directory. ProjectId = None SourceFiles = [| fileName1; fileName2 |] - OtherOptions = allFlags + OtherOptions = allFlags ReferencedProjects = [| |]; IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = true - LoadTime = System.DateTime.Now // Not 'now', we don't want to force reloading - UnresolvedReferences = None + UseScriptResolutionRules = true + LoadTime = DateTime.Now // Not 'now', we don't want to force reloading + UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo = None Stamp = None } - let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously + let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunImmediate - results.Errors.Length |> shouldEqual 0 + results.Diagnostics.Length |> shouldEqual 0 results.AssemblySignature.Entities.Count |> shouldEqual 2 results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count |> shouldEqual 1 results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName |> shouldEqual "B" - diff --git a/tests/service/FsUnit.fs b/tests/service/FsUnit.fs index 497b492cc5d..fc4964c574f 100644 --- a/tests/service/FsUnit.fs +++ b/tests/service/FsUnit.fs @@ -9,39 +9,57 @@ let should (f : 'a -> #Constraint) x (y : obj) = let c = f x let y = match y with - | :? (unit -> unit) -> box (new TestDelegate(y :?> unit -> unit)) + | :? (unit -> unit) -> box (TestDelegate(y :?> unit -> unit)) | _ -> y Assert.That(y, c) -let equal x = new EqualConstraint(x) +let equal x = EqualConstraint(x) -// like "should equal", but validates same-type +/// like "should equal", but validates same-type let shouldEqual (x: 'a) (y: 'a) = Assert.AreEqual(x, y, sprintf "Expected: %A\nActual: %A" x y) -let notEqual x = new NotConstraint(new EqualConstraint(x)) +/// Same as 'shouldEqual' but goes pairwise over the collections. Lengths must be equal. +let shouldPairwiseEqual (x: seq<_>) (y: seq<_>) = + // using enumerators, because Seq.iter2 allows different lengths silently + let ex = x.GetEnumerator() + let ey = y.GetEnumerator() + let mutable countx = 0 + let mutable county = 0 + while ex.MoveNext() do + countx <- countx + 1 + if ey.MoveNext() then + county <- county + 1 + ey.Current |> shouldEqual ex.Current -let contain x = new ContainsConstraint(x) + while ex.MoveNext() do countx <- countx + 1 + while ey.MoveNext() do county <- county + 1 + if countx <> county then + Assert.Fail("Collections are of unequal lengths, expected length {0}, actual length is {1}.", countx, county) + +let notEqual x = NotConstraint(EqualConstraint(x)) + +let contain x = ContainsConstraint(x) let haveLength n = Has.Length.EqualTo(n) let haveCount n = Has.Count.EqualTo(n) -let endWith (s:string) = new EndsWithConstraint(s) +let endWith (s:string) = EndsWithConstraint(s) -let startWith (s:string) = new StartsWithConstraint(s) +let startWith (s:string) = StartsWithConstraint(s) let be = id -let Null = new NullConstraint() +let Null = NullConstraint() -let Empty = new EmptyConstraint() +let Empty = EmptyConstraint() -let EmptyString = new EmptyStringConstraint() +let EmptyString = EmptyStringConstraint() -let True = new TrueConstraint() +let True = TrueConstraint() -let False = new FalseConstraint() +let False = FalseConstraint() -let sameAs x = new SameAsConstraint(x) +let sameAs x = SameAsConstraint(x) let throw = Throws.TypeOf \ No newline at end of file diff --git a/tests/service/FscTests.fs b/tests/service/FscTests.fs deleted file mode 100644 index bcd1cb2cbac..00000000000 --- a/tests/service/FscTests.fs +++ /dev/null @@ -1,376 +0,0 @@ - -#if INTERACTIVE -#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive -#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" -#load "FsUnit.fs" -#load "Common.fs" -#else -module FSharp.Compiler.Service.Tests.FscTests -#endif - - -open System -open System.Diagnostics -open System.IO - -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Service.Tests -open FSharp.Compiler.Service.Tests.Common - -open NUnit.Framework - -exception - VerificationException of (*assembly:*)string * (*errorCode:*)int * (*output:*)string - with override e.Message = sprintf "Verification of '%s' failed with code %d, message <<<%s>>>" e.Data0 e.Data1 e.Data2 - -exception - CompilationError of (*assembly:*)string * (*errorCode:*)int * (*info:*)FSharpErrorInfo [] - with override e.Message = sprintf "Compilation of '%s' failed with code %d (%A)" e.Data0 e.Data1 e.Data2 - -let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e-> false -let pdbExtension isDll = (if runningOnMono then (if isDll then ".dll.mdb" else ".exe.mdb") else ".pdb") - -type PEVerifier () = - - static let expectedExitCode = 0 - static let runsOnMono = try System.Type.GetType("Mono.Runtime") <> null with _ -> false - - let verifierInfo = -#if NETCOREAPP - None -#else - if runsOnMono then - Some ("pedump", "--verify all") - else - let peverifyPath configuration = - Path.Combine(__SOURCE_DIRECTORY__, "..", "..", "artifacts", "bin", "PEVerify", configuration, "net472", "PEVerify.exe") - let peverify = - if File.Exists(peverifyPath "Debug") then peverifyPath "Debug" - else peverifyPath "Release" - Some (peverify, "/UNIQUE /IL /NOLOGO") -#endif - - static let execute (fileName : string, arguments : string) = - // Peverify may run quite a while some assemblies are pretty big. Make the timeout 3 minutes just in case. - let longtime = int (TimeSpan.FromMinutes(3.0).TotalMilliseconds) - printfn "executing '%s' with arguments %s" fileName arguments - let psi = new ProcessStartInfo(fileName, arguments) - psi.UseShellExecute <- false - //psi.ErrorDialog <- false - psi.CreateNoWindow <- true - psi.RedirectStandardOutput <- true - psi.RedirectStandardError <- true - - use proc = Process.Start(psi) - let stdOut = proc.StandardOutput.ReadToEnd() - let stdErr = proc.StandardError.ReadToEnd() - proc.WaitForExit(longtime) - proc.ExitCode, stdOut, stdErr - - member __.Verify(assemblyPath : string) = - match verifierInfo with - | Some (verifierPath, switches) -> - let id,stdOut,stdErr = execute(verifierPath, sprintf "%s \"%s\"" switches assemblyPath) - if id = expectedExitCode && String.IsNullOrWhiteSpace stdErr then () - else - printfn "Verification failure, stdout: <<<%s>>>" stdOut - printfn "Verification failure, stderr: <<<%s>>>" stdErr - raise <| VerificationException(assemblyPath, id, stdOut + "\n" + stdErr) - | None -> - printfn "Skipping verification part of test because verifier not found" - - - -type DebugMode = - | Off - | PdbOnly - | Full - -let checker = FSharpChecker.Create() - -/// Ensures the default FSharp.Core referenced by the F# compiler service (if none is -/// provided explicitly) is available in the output directory. -let ensureDefaultFSharpCoreAvailable tmpDir = -#if NETCOREAPP - ignore tmpDir -#else - // FSharp.Compiler.Service references FSharp.Core 4.3.0.0 by default. That's wrong? But the output won't verify - // or run on a system without FSharp.Core 4.3.0.0 in the GAC or in the same directory, or with a binding redirect in place. - // - // So just copy the FSharp.Core 4.3.0.0 to the tmp directory. Only need to do this on Windows. - if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows - File.Copy(fsCoreDefaultReference(), Path.Combine(tmpDir, Path.GetFileName(fsCoreDefaultReference())), overwrite = true) -#endif - -let compile isDll debugMode (assemblyName : string) (ext: string) (code : string) (dependencies : string list) (extraArgs: string list) = - let tmp = Path.Combine(Path.GetTempPath(),"test"+string(hash (isDll,debugMode,assemblyName,code,dependencies))) - try Directory.CreateDirectory(tmp) |> ignore with _ -> () - let sourceFile = Path.Combine(tmp, assemblyName + "." + ext) - let outFile = Path.Combine(tmp, assemblyName + if isDll then ".dll" else ".exe") - let pdbFile = Path.Combine(tmp, assemblyName + pdbExtension isDll) - do File.WriteAllText(sourceFile, code) - let args = - [| - // fsc parser skips the first argument by default; - // perhaps this shouldn't happen in library code. - yield "fsc.exe" - - if isDll then yield "--target:library" - - match debugMode with - | Off -> () // might need to include some switches here - | PdbOnly -> - yield "--debug:pdbonly" - if not runningOnMono then // on Mono, the debug file name is not configurable - yield sprintf "--pdb:%s" pdbFile - | Full -> - yield "--debug:full" - if not runningOnMono then // on Mono, the debug file name is not configurable - yield sprintf "--pdb:%s" pdbFile - - for d in dependencies do - yield sprintf "-r:%s" d - - yield sprintf "--out:%s" outFile - - yield! extraArgs - - yield sourceFile - - |] - - ensureDefaultFSharpCoreAvailable tmp - - printfn "args: %A" args - let errorInfo, id = checker.Compile args |> Async.RunSynchronously - for err in errorInfo do - printfn "error: %A" err - if id <> 0 then raise <| CompilationError(assemblyName, id, errorInfo) - Assert.AreEqual (errorInfo.Length, 0) - outFile - -//sizeof -let compileAndVerify isDll debugMode assemblyName ext code dependencies = - let verifier = new PEVerifier () - let outFile = compile isDll debugMode assemblyName ext code dependencies [] - verifier.Verify outFile - outFile - -let compileAndVerifyAst (name : string, ast : Ast.ParsedInput list, references : string list) = - let outDir = Path.Combine(Path.GetTempPath(),"test"+string(hash (name, references))) - try Directory.CreateDirectory(outDir) |> ignore with _ -> () - - let outFile = Path.Combine(outDir, name + ".dll") - - ensureDefaultFSharpCoreAvailable outDir - - let errors, id = checker.Compile(ast, name, outFile, references, executable = false) |> Async.RunSynchronously - for err in errors do printfn "error: %A" err - Assert.AreEqual (errors.Length, 0) - if id <> 0 then raise <| CompilationError(name, id, errors) - - // copy local explicit references for verification - for ref in references do - let name = Path.GetFileName ref - File.Copy(ref, Path.Combine(outDir, name), overwrite = true) - - let verifier = new PEVerifier() - - verifier.Verify outFile - -[] -let ``1. PEVerifier sanity check`` () = - let verifier = new PEVerifier() - - let fscorlib = typeof.Assembly - verifier.Verify fscorlib.Location - - let nonAssembly = Path.Combine(Directory.GetCurrentDirectory(), typeof.Assembly.GetName().Name + ".pdb") - Assert.Throws(fun () -> verifier.Verify nonAssembly |> ignore) |> ignore - - -[] -let ``2. Simple FSC library test`` () = - let code = """ -module Foo - - let f x = (x,x) - - type Foo = class end - - exception E of int * string - - printfn "done!" // make the code have some initialization effect -""" - - compileAndVerify true PdbOnly "Foo" "fs" code [] |> ignore - -[] -let ``3. Simple FSC executable test`` () = - let code = """ -module Bar - - [] - let main _ = printfn "Hello, World!" ; 42 - -""" - let outFile = compileAndVerify false PdbOnly "Bar" "fs" code [] - - use proc = Process.Start(outFile, "") - proc.WaitForExit() - Assert.AreEqual(proc.ExitCode, 42) - - - -[] -let ``4. Compile from simple AST`` () = - let code = """ -module Foo - - let f x = (x,x) - - type Foo = class end - - exception E of int * string - - printfn "done!" // make the code have some initialization effect -""" - let ast = parseSourceCode("foo", code) |> Option.toList - compileAndVerifyAst("foo", ast, []) - -[] -let ``5. Compile from AST with explicit assembly reference`` () = - let code = """ -module Bar - - open FSharp.Compiler.SourceCodeServices - - let f x = (x,x) - - type Bar = class end - - exception E of int * string - - // depends on FSharp.Compiler.Service - // note : mono's pedump fails if this is a value; will not verify type initializer for module - let checker () = FSharpChecker.Create() - - printfn "done!" // make the code have some initialization effect -""" - let serviceAssembly = typeof.Assembly.Location - let ast = parseSourceCode("bar", code) |> Option.toList - compileAndVerifyAst("bar", ast, [serviceAssembly]) - - -[] -let ``Check line nos are indexed by 1`` () = - let code = """ -module Bar - let doStuff a b = - a + b - - let sum = doStuff "1" 2 - -""" - try - let outFile : string = compile false PdbOnly "Bar" "fs" code [] [] - () - with - | :? CompilationError as exn -> - Assert.AreEqual(6,exn.Data2.[0].StartLineAlternate) - Assert.True(exn.Data2.[0].ToString().Contains("Bar.fs (6,27)-(6,28)")) - | _ -> failwith "No compilation error" - -[] -let ``Check cols are indexed by 1`` () = - let code = "let x = 1 + a" - - try - let outFile : string = compile false PdbOnly "Foo" "fs" code [] [] - () - with - | :? CompilationError as exn -> - Assert.True(exn.Data2.[0].ToString().Contains("Foo.fs (1,13)-(1,14)")) - | _ -> failwith "No compilation error" - - -[] -let ``Check compile of bad fsx`` () = - let code = """ -#load "missing.fsx" -#r "missing.dll" - """ - - try - let outFile : string = compile false PdbOnly "Foo" "fsx" code [] [] - () - with - | :? CompilationError as exn -> - let errorText1 = exn.Data2.[0].ToString() - let errorText2 = exn.Data2.[1].ToString() - printfn "errorText1 = <<<%s>>>" errorText1 - printfn "errorText2 = <<<%s>>>" errorText2 - Assert.True(errorText1.Contains("Could not load file '")) - Assert.True(errorText1.Contains("missing.fsx")) - //Assert.True(errorText2.Contains("Could not locate the assembly \"missing.dll\"")) - | _ -> failwith "No compilation error" - - -[] -let ``Check compile of good fsx with bad option`` () = - let code = """ -let x = 1 - """ - - try - let outFile : string = compile false PdbOnly "Foo" "fsx" code [] ["-r:missing.dll"] - () - with - | :? CompilationError as exn -> - let contains (s1:string) s2 = - Assert.True(s1.Contains(s2), sprintf "Expected '%s' to contain '%s'" s1 s2) - contains (exn.Data2.[0].ToString()) "startup (1,1)-(1,1) parameter error" - contains (exn.Data2.[0].ToString()) "missing.dll" - | _ -> failwith "No compilation error" - - -#if STRESS -// For this stress test the aim is to check if we have a memory leak - -module StressTest1 = - open System.IO - - [] - let ``stress test repeated in-memory compilation``() = - for i = 1 to 500 do - printfn "stress test iteration %d" i - let code = """ -module M - -type C() = - member x.P = 1 - -let x = 3 + 4 -""" - - let outFile : string = compile true PdbOnly "Foo" "fs" code [] [] - () - -#endif - -(* - -[] -let ``Check read of mscorlib`` () = - let options = FSharp.Compiler.AbstractIL.ILBinaryReader.mkDefault FSharp.Compiler.AbstractIL.IL.EcmaILGlobals - let options = { options with optimizeForMemory=true} - let reader = FSharp.Compiler.AbstractIL.ILBinaryReader.OpenILModuleReaderAfterReadingAllBytes "C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.5\\mscorlib.dll" options - let greg = reader.ILModuleDef.TypeDefs.FindByName "System.Globalization.GregorianCalendar" - for attr in greg.CustomAttrs.AsList do - printfn "%A" attr.Method - -*) - - - \ No newline at end of file diff --git a/tests/service/FsiTests.fs b/tests/service/FsiTests.fs index 39ff624fbf2..7069354acd8 100644 --- a/tests/service/FsiTests.fs +++ b/tests/service/FsiTests.fs @@ -40,8 +40,8 @@ let evalExpression text = | Some value -> sprintf "%A" value.ReflectionValue | None -> sprintf "null or no result" -let formatErrors (errs: FSharpErrorInfo[]) = - [ for err in errs do yield sprintf "%s %d,%d - %d,%d; %s" (match err.Severity with FSharpErrorSeverity.Error -> "error" | FSharpErrorSeverity.Warning -> "warning") err.StartLineAlternate err.StartColumn err.EndLineAlternate err.EndColumn err.Message ] +let formatErrors (errs: FSharpDiagnostic[]) = + [ for err in errs do yield sprintf "%s %d,%d - %d,%d; %s" (match err.Severity with FSharpDiagnosticSeverity.Error -> "error" | FSharpDiagnosticSeverity.Warning -> "warning") err.StartLineAlternate err.StartColumn err.EndLineAlternate err.EndColumn err.Message ] let showErrorsAndResult (x, errs) = [ match x with @@ -49,7 +49,7 @@ let showErrorsAndResult (x, errs) = | Choice2Of2 (exn:exn) -> yield sprintf "exception %s" exn.Message yield! formatErrors errs ] -let showErrors (x, errs: FSharpErrorInfo[]) = +let showErrors (x, errs: FSharpDiagnostic[]) = [ match x with | Choice1Of2 () -> () | Choice2Of2 (exn:exn) -> yield sprintf "exception %s" exn.Message @@ -282,7 +282,7 @@ let ``ParseAndCheckInteraction test 1``() = | FSharpToolTipText [FSharpToolTipElement.Single(text, FSharpXmlDoc.None)] -> text | _ -> failwith "incorrect tool tip" - Assert.True(tooltip.Contains("val xxxxxx : int")) + Assert.True(tooltip.Contains("val xxxxxx: int")) [] let ``ParseAndCheckInteraction test 2``() = diff --git a/tests/service/InteractiveCheckerTests.fs b/tests/service/InteractiveCheckerTests.fs index 3d7e13769bd..9daf0ff95bd 100644 --- a/tests/service/InteractiveCheckerTests.fs +++ b/tests/service/InteractiveCheckerTests.fs @@ -11,56 +11,57 @@ module FSharp.Compiler.Service.Tests.InteractiveChecker open NUnit.Framework open FsUnit open System -open FSharp.Compiler open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range -let internal longIdentToString (longIdent: Ast.LongIdent) = +let internal longIdentToString (longIdent: LongIdent) = String.Join(".", longIdent |> List.map (fun ident -> ident.ToString())) -let internal longIdentWithDotsToString (Ast.LongIdentWithDots (longIdent, _)) = longIdentToString longIdent +let internal longIdentWithDotsToString (LongIdentWithDots (longIdent, _)) = longIdentToString longIdent -let internal posToTuple (pos: Range.pos) = (pos.Line, pos.Column) -let internal rangeToTuple (range: Range.range) = (posToTuple range.Start, posToTuple range.End) +let internal posToTuple (pos: pos) = (pos.Line, pos.Column) +let internal rangeToTuple (range: range) = (posToTuple range.Start, posToTuple range.End) -let internal identsAndRanges (input: Ast.ParsedInput) = - let identAndRange ident (range: Range.range) = +let internal identsAndRanges (input: ParsedInput) = + let identAndRange ident (range: range) = (ident, rangeToTuple range) - let extractFromComponentInfo (componentInfo: Ast.SynComponentInfo) = - let ((Ast.SynComponentInfo.ComponentInfo(_attrs, _typarDecls, _typarConstraints, longIdent, _, _, _, range))) = componentInfo + let extractFromComponentInfo (componentInfo: SynComponentInfo) = + let (SynComponentInfo.SynComponentInfo(_attrs, _typarDecls, _typarConstraints, longIdent, _, _, _, range)) = componentInfo // TODO : attrs, typarDecls and typarConstraints [identAndRange (longIdentToString longIdent) range] - let extractFromTypeDefn (typeDefn: Ast.SynTypeDefn) = - let (Ast.SynTypeDefn.TypeDefn(componentInfo, _repr, _members, _)) = typeDefn + let extractFromTypeDefn (typeDefn: SynTypeDefn) = + let (SynTypeDefn(componentInfo, _repr, _members, _, _)) = typeDefn // TODO : repr and members extractFromComponentInfo componentInfo - let rec extractFromModuleDecl (moduleDecl: Ast.SynModuleDecl) = + let rec extractFromModuleDecl (moduleDecl: SynModuleDecl) = match moduleDecl with - | Ast.SynModuleDecl.Types(typeDefns, _) -> (typeDefns |> List.collect extractFromTypeDefn) - | Ast.SynModuleDecl.ModuleAbbrev(ident, _, range) -> [ identAndRange (ident.ToString()) range ] - | Ast.SynModuleDecl.NestedModule(componentInfo, _, decls, _, _) -> (extractFromComponentInfo componentInfo) @ (decls |> List.collect extractFromModuleDecl) - | Ast.SynModuleDecl.Let(_, _, _) -> failwith "Not implemented yet" - | Ast.SynModuleDecl.DoExpr(_, _, _range) -> failwith "Not implemented yet" - | Ast.SynModuleDecl.Exception(_, _range) -> failwith "Not implemented yet" - | Ast.SynModuleDecl.Open(longIdentWithDots, range) -> [ identAndRange (longIdentWithDotsToString longIdentWithDots) range ] - | Ast.SynModuleDecl.Attributes(_attrs, _range) -> failwith "Not implemented yet" - | Ast.SynModuleDecl.HashDirective(_, _range) -> failwith "Not implemented yet" - | Ast.SynModuleDecl.NamespaceFragment(moduleOrNamespace) -> extractFromModuleOrNamespace moduleOrNamespace - and extractFromModuleOrNamespace (Ast.SynModuleOrNamespace(longIdent, _, _, moduleDecls, _, _, _, _)) = + | SynModuleDecl.Types(typeDefns, _) -> (typeDefns |> List.collect extractFromTypeDefn) + | SynModuleDecl.ModuleAbbrev(ident, _, range) -> [ identAndRange (ident.ToString()) range ] + | SynModuleDecl.NestedModule(componentInfo, _, decls, _, _) -> (extractFromComponentInfo componentInfo) @ (decls |> List.collect extractFromModuleDecl) + | SynModuleDecl.Let(_, _, _) -> failwith "Not implemented yet" + | SynModuleDecl.DoExpr(_, _, _range) -> failwith "Not implemented yet" + | SynModuleDecl.Exception(_, _range) -> failwith "Not implemented yet" + | SynModuleDecl.Open(SynOpenDeclTarget.ModuleOrNamespace (lid, range), _) -> [ identAndRange (longIdentToString lid) range ] + | SynModuleDecl.Open(SynOpenDeclTarget.Type _, _) -> failwith "Not implemented yet" + | SynModuleDecl.Attributes(_attrs, _range) -> failwith "Not implemented yet" + | SynModuleDecl.HashDirective(_, _range) -> failwith "Not implemented yet" + | SynModuleDecl.NamespaceFragment(moduleOrNamespace) -> extractFromModuleOrNamespace moduleOrNamespace + and extractFromModuleOrNamespace (SynModuleOrNamespace(longIdent, _, _, moduleDecls, _, _, _, _)) = let xs = moduleDecls |> List.collect extractFromModuleDecl if longIdent.IsEmpty then xs else - (identAndRange (longIdentToString longIdent) (longIdent |> List.map (fun id -> id.idRange) |> List.reduce Range.unionRanges)) :: xs + (identAndRange (longIdentToString longIdent) (longIdent |> List.map (fun id -> id.idRange) |> List.reduce unionRanges)) :: xs match input with - | Ast.ParsedInput.ImplFile(Ast.ParsedImplFileInput(_, _, _, _, _, modulesOrNamespaces, _)) -> + | ParsedInput.ImplFile(ParsedImplFileInput(_, _, _, _, _, modulesOrNamespaces, _)) -> modulesOrNamespaces |> List.collect extractFromModuleOrNamespace - | Ast.ParsedInput.SigFile _ -> [] + | ParsedInput.SigFile _ -> [] let internal parseAndExtractRanges code = - let file = "Test" + let file = "Test.fs" let result = parseSourceCode (file, code) - match result with - | Some tree -> tree |> identsAndRanges - | None -> failwith "fail to parse..." + result |> identsAndRanges let input = """ diff --git a/tests/service/MultiProjectAnalysisTests.fs b/tests/service/MultiProjectAnalysisTests.fs index a4ba694cfa8..ab9136c8c47 100644 --- a/tests/service/MultiProjectAnalysisTests.fs +++ b/tests/service/MultiProjectAnalysisTests.fs @@ -8,33 +8,37 @@ module Tests.Service.MultiProjectAnalysisTests #endif -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices - open NUnit.Framework open FsUnit open System.IO - +open System.Collections.Generic +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.IO +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text open FSharp.Compiler.Service.Tests.Common +open TestFramework +let toIList (x: _ array) = x :> IList<_> let numProjectsForStressTest = 100 let internal checker = FSharpChecker.Create(projectCacheSize=numProjectsForStressTest + 10) -/// Extract range info -let internal tups (m:Range.range) = (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn) +/// Extract range info +let internal tups (m:range) = (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn) -module internal Project1A = +module internal Project1A = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileSource1 = """ module Project1A /// This is type C -type C() = +type C() = static member M(arg1: int, arg2: int, ?arg3 : int) = arg1 + arg2 + defaultArg arg3 4 /// This is x1 @@ -43,8 +47,15 @@ let x1 = C.M(arg1 = 3, arg2 = 4, arg3 = 5) /// This is x2 let x2 = C.M(arg1 = 3, arg2 = 4, ?arg3 = Some 5) +/// This is +/// x3 +let x3 ( + /// This is not x3 + p: int + ) = () + /// This is type U -type U = +type U = /// This is Case1 | Case1 of int @@ -52,7 +63,7 @@ type U = /// This is Case2 | Case2 of string """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -63,10 +74,10 @@ type U = //----------------------------------------------------------------------------------------- -module internal Project1B = +module internal Project1B = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileSource1 = """ @@ -75,12 +86,12 @@ module Project1B type A = B of xxx: int * yyy : int let b = B(xxx=1, yyy=2) -let x = +let x = match b with // does not find usage here | B (xxx = a; yyy = b) -> () """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -90,10 +101,10 @@ let x = // A project referencing two sub-projects -module internal MultiProject1 = +module internal MultiProject1 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileSource1 = """ @@ -107,163 +118,170 @@ let p = (Project1A.x1, Project1B.b) let c = C() let u = Case1 3 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = + let options = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| ("-r:" + Project1A.dllName); ("-r:" + Project1B.dllName) |] - ReferencedProjects = [| (Project1A.dllName, Project1A.options); - (Project1B.dllName, Project1B.options); |] } + ReferencedProjects = [| FSharpReferencedProject.CreateFSharp(Project1A.dllName, Project1A.options); + FSharpReferencedProject.CreateFSharp(Project1B.dllName, Project1B.options); |] } let cleanFileName a = if a = fileName1 then "file1" else "??" - - [] -#if NETCOREAPP -[] -#endif -let ``Test multi project 1 whole project errors`` () = - - let wholeProjectResults = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunSynchronously - - for e in wholeProjectResults.Errors do - printfn "multi project 1 error: <<<%s>>>" e.Message +let ``Test multi project 1 basic`` () = - wholeProjectResults .Errors.Length |> shouldEqual 0 - wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual 6 - -[] -let ``Test multi project 1 basic`` () = - - let wholeProjectResults = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunImmediate [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual ["MultiProject1"] [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual [] - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual ["p"; "c"; "u"] [] -let ``Test multi project 1 all symbols`` () = +let ``Test multi project 1 all symbols`` () = - let p1A = checker.ParseAndCheckProject(Project1A.options) |> Async.RunSynchronously - let p1B = checker.ParseAndCheckProject(Project1B.options) |> Async.RunSynchronously - let mp = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunSynchronously + let p1A = checker.ParseAndCheckProject(Project1A.options) |> Async.RunImmediate + let p1B = checker.ParseAndCheckProject(Project1B.options) |> Async.RunImmediate + let mp = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunImmediate - let x1FromProject1A = - [ for s in p1A.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "x1" then + let x1FromProject1A = + [ for s in p1A.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "x1" then yield s.Symbol ] |> List.head - let x1FromProjectMultiProject = - [ for s in mp.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "x1" then + let x1FromProjectMultiProject = + [ for s in mp.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "x1" then yield s.Symbol ] |> List.head - let bFromProjectMultiProject = - [ for s in mp.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "b" then + let bFromProjectMultiProject = + [ for s in mp.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "b" then yield s.Symbol ] |> List.head x1FromProject1A.Assembly.FileName.IsNone |> shouldEqual true // For now, the assembly being analyzed doesn't return a filename x1FromProject1A.Assembly.QualifiedName |> shouldEqual "" // For now, the assembly being analyzed doesn't return a qualified name - x1FromProject1A.Assembly.SimpleName |> shouldEqual (Path.GetFileNameWithoutExtension Project1A.dllName) + x1FromProject1A.Assembly.SimpleName |> shouldEqual (Path.GetFileNameWithoutExtension Project1A.dllName) x1FromProjectMultiProject.Assembly.FileName |> shouldEqual (Some Project1A.dllName) bFromProjectMultiProject.Assembly.FileName |> shouldEqual (Some Project1B.dllName) - let usesOfx1FromProject1AInMultiProject1 = - mp.GetUsesOfSymbol(x1FromProject1A) - |> Async.RunSynchronously - |> Array.map (fun s -> s.Symbol.DisplayName, MultiProject1.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) + let usesOfx1FromProject1AInMultiProject1 = + mp.GetUsesOfSymbol(x1FromProject1A) + |> Array.map (fun s -> s.Symbol.DisplayName, MultiProject1.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) - let usesOfx1FromMultiProject1InMultiProject1 = - mp.GetUsesOfSymbol(x1FromProjectMultiProject) - |> Async.RunSynchronously - |> Array.map (fun s -> s.Symbol.DisplayName, MultiProject1.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) + let usesOfx1FromMultiProject1InMultiProject1 = + mp.GetUsesOfSymbol(x1FromProjectMultiProject) + |> Array.map (fun s -> s.Symbol.DisplayName, MultiProject1.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) usesOfx1FromProject1AInMultiProject1 |> shouldEqual usesOfx1FromMultiProject1InMultiProject1 [] -let ``Test multi project 1 xmldoc`` () = +let ``Test multi project 1 xmldoc`` () = - let p1A = checker.ParseAndCheckProject(Project1A.options) |> Async.RunSynchronously - let p1B = checker.ParseAndCheckProject(Project1B.options) |> Async.RunSynchronously - let mp = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunSynchronously + let p1A = checker.ParseAndCheckProject(Project1A.options) |> Async.RunImmediate + let p1B = checker.ParseAndCheckProject(Project1B.options) |> Async.RunImmediate + let mp = checker.ParseAndCheckProject(MultiProject1.options) |> Async.RunImmediate - let x1FromProject1A = - [ for s in p1A.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "x1" then + let symbolFromProject1A sym = + [ for s in p1A.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = sym then yield s.Symbol ] |> List.head - let x1FromProjectMultiProject = - [ for s in mp.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "x1" then + let x1FromProject1A = symbolFromProject1A "x1" + let x3FromProject1A = symbolFromProject1A "x3" + + let x1FromProjectMultiProject = + [ for s in mp.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "x1" then yield s.Symbol ] |> List.head - let ctorFromProjectMultiProject = - [ for s in mp.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "C" then + let ctorFromProjectMultiProject = + [ for s in mp.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "C" then yield s.Symbol ] |> List.head - let case1FromProjectMultiProject = - [ for s in mp.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "Case1" then + let case1FromProjectMultiProject = + [ for s in mp.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "Case1" then yield s.Symbol ] |> List.head - match x1FromProject1A with - | :? FSharpMemberOrFunctionOrValue as v -> v.XmlDoc.Count |> shouldEqual 1 + match x1FromProject1A with + | :? FSharpMemberOrFunctionOrValue as v -> + match v.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines.Length |> shouldEqual 1 + | _ -> failwith "wrong kind" | _ -> failwith "odd symbol!" - match x1FromProjectMultiProject with - | :? FSharpMemberOrFunctionOrValue as v -> v.XmlDoc.Count |> shouldEqual 1 + match x3FromProject1A with + | :? FSharpMemberOrFunctionOrValue as v -> + match v.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> shouldEqual [|" This is"; " x3"|] + | _ -> failwith "wrong kind" | _ -> failwith "odd symbol!" - match ctorFromProjectMultiProject with - | :? FSharpMemberOrFunctionOrValue as c -> c.XmlDoc.Count |> shouldEqual 0 + match x3FromProject1A with + | :? FSharpMemberOrFunctionOrValue as v -> + match v.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.GetElaboratedXmlLines() |> shouldEqual [|""; " This is"; " x3"; "" |] + | _ -> failwith "wrong kind" | _ -> failwith "odd symbol!" - match ctorFromProjectMultiProject with - | :? FSharpMemberOrFunctionOrValue as c -> c.DeclaringEntity.Value.XmlDoc.Count |> shouldEqual 1 + match x1FromProjectMultiProject with + | :? FSharpMemberOrFunctionOrValue as v -> + match v.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines.Length |> shouldEqual 1 + | _ -> failwith "wrong kind" | _ -> failwith "odd symbol!" - match case1FromProjectMultiProject with - | :? FSharpUnionCase as c -> c.XmlDoc.Count |> shouldEqual 1 + match ctorFromProjectMultiProject with + | :? FSharpMemberOrFunctionOrValue as c -> + match c.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines.Length |> shouldEqual 0 + | _ -> failwith "wrong kind" + | _ -> failwith "odd symbol!" + + match case1FromProjectMultiProject with + | :? FSharpUnionCase as c -> + match c.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines.Length |> shouldEqual 1 + | _ -> failwith "wrong kind" | _ -> failwith "odd symbol!" //------------------------------------------------------------------------------------ // A project referencing many sub-projects -module internal ManyProjectsStressTest = +module internal ManyProjectsStressTest = let numProjectsForStressTest = 100 - - type Project = { ModuleName: string; FileName: string; Options: FSharpProjectOptions; DllName: string } - let projects = - [ for i in 1 .. numProjectsForStressTest do - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + + type Project = { ModuleName: string; FileName: string; Options: FSharpProjectOptions; DllName: string } + let projects = + [ for i in 1 .. numProjectsForStressTest do + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") let moduleName = "Project" + string i let fileSource1 = "module " + moduleName + """ // Some random code open System -type C() = +type C() = static member Print() = System.Console.WriteLine("Hello World") - + let v = C() let p = C.Print() """ - File.WriteAllText(fileName1, fileSource1) - let baseName = Path.GetTempFileName() + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileNames = [fileName1 ] @@ -271,145 +289,128 @@ let p = C.Print() let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) yield { ModuleName = moduleName; FileName=fileName1; Options = options; DllName=dllName } ] - let jointProject = - let fileName = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let dllBase = Path.GetTempFileName() + let jointProject = + let fileName = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let dllBase = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(dllBase, ".dll") let projFileName = Path.ChangeExtension(dllBase, ".fsproj") - let fileSource = + let fileSource = """ module JointProject """ + String.concat "\r\n" [ for p in projects -> "open " + p.ModuleName ] + """ -let p = (""" +let p = (""" + String.concat ",\r\n " [ for p in projects -> p.ModuleName + ".v" ] + ")" - File.WriteAllText(fileName, fileSource) + FileSystem.OpenFileForWriteShim(fileName).Write(fileSource) let fileNames = [fileName] let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = + let options = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| for p in projects -> ("-r:" + p.DllName) |] - ReferencedProjects = [| for p in projects -> (p.DllName, p.Options); |] } - { ModuleName = "JointProject"; FileName=fileName; Options = options; DllName=dllName } + ReferencedProjects = [| for p in projects -> FSharpReferencedProject.CreateFSharp(p.DllName, p.Options); |] } + { ModuleName = "JointProject"; FileName=fileName; Options = options; DllName=dllName } - let cleanFileName a = + let cleanFileName a = projects |> List.tryPick (fun m -> if a = m.FileName then Some m.ModuleName else None) |> function Some x -> x | None -> if a = jointProject.FileName then "fileN" else "??" - let makeCheckerForStressTest ensureBigEnough = + let makeCheckerForStressTest ensureBigEnough = let size = (if ensureBigEnough then numProjectsForStressTest + 10 else numProjectsForStressTest / 2 ) FSharpChecker.Create(projectCacheSize=size) [] -#if NETCOREAPP -[] -#endif -let ``Test ManyProjectsStressTest whole project errors`` () = - - let checker = ManyProjectsStressTest.makeCheckerForStressTest true - let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunSynchronously - let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunSynchronously - - for e in wholeProjectResults.Errors do - printfn "ManyProjectsStressTest error: <<<%s>>>" e.Message - - wholeProjectResults .Errors.Length |> shouldEqual 0 - wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual (ManyProjectsStressTest.numProjectsForStressTest + 4) - -[] -let ``Test ManyProjectsStressTest basic`` () = +let ``Test ManyProjectsStressTest basic`` () = let checker = ManyProjectsStressTest.makeCheckerForStressTest true - let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunImmediate [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual ["JointProject"] [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual [] - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual ["p"] [] -let ``Test ManyProjectsStressTest cache too small`` () = +let ``Test ManyProjectsStressTest cache too small`` () = let checker = ManyProjectsStressTest.makeCheckerForStressTest false - let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunImmediate [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual ["JointProject"] [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual [] - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual ["p"] [] -let ``Test ManyProjectsStressTest all symbols`` () = +let ``Test ManyProjectsStressTest all symbols`` () = let checker = ManyProjectsStressTest.makeCheckerForStressTest true - for i in 1 .. 10 do + for i in 1 .. 10 do printfn "stress test iteration %d (first may be slow, rest fast)" i - let projectsResults = [ for p in ManyProjectsStressTest.projects -> p, checker.ParseAndCheckProject(p.Options) |> Async.RunSynchronously ] - let jointProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunSynchronously - - let vsFromJointProject = - [ for s in jointProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "v" then - yield s.Symbol ] - - for (p,pResults) in projectsResults do - let vFromProject = - [ for s in pResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "v" then - yield s.Symbol ] |> List.head + let projectsResults = [ for p in ManyProjectsStressTest.projects -> p, checker.ParseAndCheckProject(p.Options) |> Async.RunImmediate ] + let jointProjectResults = checker.ParseAndCheckProject(ManyProjectsStressTest.jointProject.Options) |> Async.RunImmediate + + let vsFromJointProject = + [ for s in jointProjectResults.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "v" then + yield s.Symbol ] + + for p,pResults in projectsResults do + let vFromProject = + [ for s in pResults.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "v" then + yield s.Symbol ] |> List.head vFromProject.Assembly.FileName.IsNone |> shouldEqual true // For now, the assembly being analyzed doesn't return a filename vFromProject.Assembly.QualifiedName |> shouldEqual "" // For now, the assembly being analyzed doesn't return a qualified name - vFromProject.Assembly.SimpleName |> shouldEqual (Path.GetFileNameWithoutExtension p.DllName) + vFromProject.Assembly.SimpleName |> shouldEqual (Path.GetFileNameWithoutExtension p.DllName) - let usesFromJointProject = - jointProjectResults.GetUsesOfSymbol(vFromProject) - |> Async.RunSynchronously - |> Array.map (fun s -> s.Symbol.DisplayName, ManyProjectsStressTest.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) + let usesFromJointProject = + jointProjectResults.GetUsesOfSymbol(vFromProject) + |> Array.map (fun s -> s.Symbol.DisplayName, ManyProjectsStressTest.cleanFileName s.FileName, tups s.Symbol.DeclarationLocation.Value) usesFromJointProject.Length |> shouldEqual 1 //----------------------------------------------------------------------------------------- -module internal MultiProjectDirty1 = +module internal MultiProjectDirty1 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName() let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let content = """module Project1 let x = "F#" -""" - - File.WriteAllText(fileName1, content) +""" + + FileSystem.OpenFileForWriteShim(fileName1).Write(content) let cleanFileName a = if a = fileName1 then "Project1" else "??" let fileNames = [fileName1] - - let getOptions() = + + let getOptions() = let args = mkProjectCommandLineArgs (dllName, fileNames) checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) -module internal MultiProjectDirty2 = +module internal MultiProjectDirty2 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") - + let content = """module Project2 open Project1 @@ -417,21 +418,21 @@ open Project1 let y = x let z = Project1.x """ - File.WriteAllText(fileName1, content) + FileSystem.OpenFileForWriteShim(fileName1).Write(content) let cleanFileName a = if a = fileName1 then "Project2" else "??" - let fileNames = [fileName1] - - let getOptions() = + let fileNames = [fileName1] + + let getOptions() = let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| ("-r:" + MultiProjectDirty1.dllName) |] - ReferencedProjects = [| (MultiProjectDirty1.dllName, MultiProjectDirty1.getOptions()) |] } + ReferencedProjects = [| FSharpReferencedProject.CreateFSharp(MultiProjectDirty1.dllName, MultiProjectDirty1.getOptions()) |] } [] -let ``Test multi project symbols should pick up changes in dependent projects`` () = +let ``Test multi project symbols should pick up changes in dependent projects`` () = // register to count the file checks let count = ref 0 @@ -441,155 +442,148 @@ let ``Test multi project symbols should pick up changes in dependent projects`` let proj1options = MultiProjectDirty1.getOptions() - let wholeProjectResults1 = checker.ParseAndCheckProject(proj1options) |> Async.RunSynchronously + let wholeProjectResults1 = checker.ParseAndCheckProject(proj1options) |> Async.RunImmediate count.Value |> shouldEqual 1 - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) - |> Async.RunSynchronously + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) + |> Async.RunImmediate count.Value |> shouldEqual 1 //---------------- Get a symbol from project 1 and look up its uses in both projects -------------------- - let xSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(3, 4, "", ["x"]) |> Async.RunSynchronously - xSymbolUse.IsSome |> shouldEqual true + let xSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(3, 4, "", ["x"]) + xSymbolUse.IsSome |> shouldEqual true let xSymbol = xSymbolUse.Value.Symbol printfn "Symbol found. Checking symbol uses in another project..." let proj2options = MultiProjectDirty2.getOptions() - let wholeProjectResults2 = checker.ParseAndCheckProject(proj2options) |> Async.RunSynchronously + let wholeProjectResults2 = checker.ParseAndCheckProject(proj2options) |> Async.RunImmediate count.Value |> shouldEqual 2 - - let _ = checker.ParseAndCheckProject(proj2options) |> Async.RunSynchronously + + let _ = checker.ParseAndCheckProject(proj2options) |> Async.RunImmediate count.Value |> shouldEqual 2 // cached - let usesOfXSymbolInProject1 = - wholeProjectResults1.GetUsesOfSymbol(xSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfXSymbolInProject1 = + wholeProjectResults1.GetUsesOfSymbol(xSymbol) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.Range) usesOfXSymbolInProject1 - |> shouldEqual + |> shouldEqual [|("val x", "Project1", ((3, 4), (3, 5))) |] - let usesOfXSymbolInProject2 = - wholeProjectResults2.GetUsesOfSymbol(xSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfXSymbolInProject2 = + wholeProjectResults2.GetUsesOfSymbol(xSymbol) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.Range) - usesOfXSymbolInProject2 - |> shouldEqual + usesOfXSymbolInProject2 + |> shouldEqual [|("val x", "Project2", ((5, 8), (5, 9))); ("val x", "Project2", ((6, 8), (6, 18)))|] //---------------- Change the file by adding a line, then re-check everything -------------------- - + let wt0 = System.DateTime.UtcNow - let wt1 = File.GetLastWriteTimeUtc MultiProjectDirty1.fileName1 + let wt1 = FileSystem.GetLastWriteTimeShim MultiProjectDirty1.fileName1 printfn "Writing new content to file '%s'" MultiProjectDirty1.fileName1 System.Threading.Thread.Sleep(1000) - File.WriteAllText(MultiProjectDirty1.fileName1, System.Environment.NewLine + MultiProjectDirty1.content) + FileSystem.OpenFileForWriteShim(MultiProjectDirty1.fileName1).Write(System.Environment.NewLine + MultiProjectDirty1.content) printfn "Wrote new content to file '%s'" MultiProjectDirty1.fileName1 - let wt2 = File.GetLastWriteTimeUtc MultiProjectDirty1.fileName1 + let wt2 = FileSystem.GetLastWriteTimeShim MultiProjectDirty1.fileName1 printfn "Current time: '%A', ticks = %d" wt0 wt0.Ticks printfn "Old write time: '%A', ticks = %d" wt1 wt1.Ticks printfn "New write time: '%A', ticks = %d" wt2 wt2.Ticks - let wholeProjectResults1AfterChange1 = checker.ParseAndCheckProject(proj1options) |> Async.RunSynchronously + let wholeProjectResults1AfterChange1 = checker.ParseAndCheckProject(proj1options) |> Async.RunImmediate count.Value |> shouldEqual 3 - let backgroundParseResults1AfterChange1, backgroundTypedParse1AfterChange1 = - checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) - |> Async.RunSynchronously + let backgroundParseResults1AfterChange1, backgroundTypedParse1AfterChange1 = + checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) + |> Async.RunImmediate - let xSymbolUseAfterChange1 = backgroundTypedParse1AfterChange1.GetSymbolUseAtLocation(4, 4, "", ["x"]) |> Async.RunSynchronously - xSymbolUseAfterChange1.IsSome |> shouldEqual true + let xSymbolUseAfterChange1 = backgroundTypedParse1AfterChange1.GetSymbolUseAtLocation(4, 4, "", ["x"]) + xSymbolUseAfterChange1.IsSome |> shouldEqual true let xSymbolAfterChange1 = xSymbolUseAfterChange1.Value.Symbol printfn "Checking project 2 after first change, options = '%A'" proj2options - let wholeProjectResults2AfterChange1 = checker.ParseAndCheckProject(proj2options) |> Async.RunSynchronously + let wholeProjectResults2AfterChange1 = checker.ParseAndCheckProject(proj2options) |> Async.RunImmediate count.Value |> shouldEqual 4 - let usesOfXSymbolInProject1AfterChange1 = - wholeProjectResults1AfterChange1.GetUsesOfSymbol(xSymbolAfterChange1) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.RangeAlternate) - + let usesOfXSymbolInProject1AfterChange1 = + wholeProjectResults1AfterChange1.GetUsesOfSymbol(xSymbolAfterChange1) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.Range) + usesOfXSymbolInProject1AfterChange1 - |> shouldEqual + |> shouldEqual [|("val x", "Project1", ((4, 4), (4, 5))) |] - let usesOfXSymbolInProject2AfterChange1 = - wholeProjectResults2AfterChange1.GetUsesOfSymbol(xSymbolAfterChange1) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfXSymbolInProject2AfterChange1 = + wholeProjectResults2AfterChange1.GetUsesOfSymbol(xSymbolAfterChange1) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.Range) - usesOfXSymbolInProject2AfterChange1 - |> shouldEqual + usesOfXSymbolInProject2AfterChange1 + |> shouldEqual [|("val x", "Project2", ((5, 8), (5, 9))); ("val x", "Project2", ((6, 8), (6, 18)))|] //---------------- Revert the change to the file -------------------- let wt0b = System.DateTime.UtcNow - let wt1b = File.GetLastWriteTimeUtc MultiProjectDirty1.fileName1 + let wt1b = FileSystem.GetLastWriteTimeShim MultiProjectDirty1.fileName1 printfn "Writing old content to file '%s'" MultiProjectDirty1.fileName1 System.Threading.Thread.Sleep(1000) - File.WriteAllText(MultiProjectDirty1.fileName1, MultiProjectDirty1.content) + FileSystem.OpenFileForWriteShim(MultiProjectDirty1.fileName1).Write(MultiProjectDirty1.content) printfn "Wrote old content to file '%s'" MultiProjectDirty1.fileName1 - let wt2b = File.GetLastWriteTimeUtc MultiProjectDirty1.fileName1 + let wt2b = FileSystem.GetLastWriteTimeShim MultiProjectDirty1.fileName1 printfn "Current time: '%A', ticks = %d" wt0b wt0b.Ticks printfn "Old write time: '%A', ticks = %d" wt1b wt1b.Ticks printfn "New write time: '%A', ticks = %d" wt2b wt2b.Ticks count.Value |> shouldEqual 4 - - let wholeProjectResults2AfterChange2 = checker.ParseAndCheckProject(proj2options) |> Async.RunSynchronously + let wholeProjectResults2AfterChange2 = checker.ParseAndCheckProject(proj2options) |> Async.RunImmediate System.Threading.Thread.Sleep(1000) count.Value |> shouldEqual 6 // note, causes two files to be type checked, one from each project - let wholeProjectResults1AfterChange2 = checker.ParseAndCheckProject(proj1options) |> Async.RunSynchronously + let wholeProjectResults1AfterChange2 = checker.ParseAndCheckProject(proj1options) |> Async.RunImmediate count.Value |> shouldEqual 6 // the project is already checked - let backgroundParseResults1AfterChange2, backgroundTypedParse1AfterChange2 = - checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) - |> Async.RunSynchronously + let backgroundParseResults1AfterChange2, backgroundTypedParse1AfterChange2 = + checker.GetBackgroundCheckResultsForFileInProject(MultiProjectDirty1.fileName1, proj1options) + |> Async.RunImmediate - let xSymbolUseAfterChange2 = backgroundTypedParse1AfterChange2.GetSymbolUseAtLocation(4, 4, "", ["x"]) |> Async.RunSynchronously - xSymbolUseAfterChange2.IsSome |> shouldEqual true + let xSymbolUseAfterChange2 = backgroundTypedParse1AfterChange2.GetSymbolUseAtLocation(4, 4, "", ["x"]) + xSymbolUseAfterChange2.IsSome |> shouldEqual true let xSymbolAfterChange2 = xSymbolUseAfterChange2.Value.Symbol - let usesOfXSymbolInProject1AfterChange2 = - wholeProjectResults1AfterChange2.GetUsesOfSymbol(xSymbolAfterChange2) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfXSymbolInProject1AfterChange2 = + wholeProjectResults1AfterChange2.GetUsesOfSymbol(xSymbolAfterChange2) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty1.cleanFileName su.FileName, tups su.Range) usesOfXSymbolInProject1AfterChange2 - |> shouldEqual + |> shouldEqual [|("val x", "Project1", ((3, 4), (3, 5))) |] - let usesOfXSymbolInProject2AfterChange2 = - wholeProjectResults2AfterChange2.GetUsesOfSymbol(xSymbolAfterChange2) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfXSymbolInProject2AfterChange2 = + wholeProjectResults2AfterChange2.GetUsesOfSymbol(xSymbolAfterChange2) + |> Array.map (fun su -> su.Symbol.ToString(), MultiProjectDirty2.cleanFileName su.FileName, tups su.Range) usesOfXSymbolInProject2AfterChange2 - |> shouldEqual + |> shouldEqual [|("val x", "Project2", ((5, 8), (5, 9))); ("val x", "Project2", ((6, 8), (6, 18)))|] @@ -597,12 +591,12 @@ let ``Test multi project symbols should pick up changes in dependent projects`` //------------------------------------------------------------------ -module internal Project2A = +module internal Project2A = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName1 = Path.GetTempFileName() - let baseName2 = Path.GetTempFileName() - let baseName3 = Path.GetTempFileName() // this one doesn't get InternalsVisibleTo rights + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName(), ".fs") + let baseName1 = tryCreateTemporaryFileName () + let baseName2 = tryCreateTemporaryFileName () + let baseName3 = tryCreateTemporaryFileName () // this one doesn't get InternalsVisibleTo rights let dllShortName = Path.GetFileNameWithoutExtension(baseName2) let dllName = Path.ChangeExtension(baseName1, ".dll") let projFileName = Path.ChangeExtension(baseName1, ".fsproj") @@ -612,11 +606,11 @@ module Project2A [] do() -type C() = +type C() = member internal x.InternalMember = 1 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -626,9 +620,9 @@ type C() = //Project2A.fileSource1 // A project referencing Project2A -module internal Project2B = +module internal Project2B = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") let dllName = Path.ChangeExtension(Project2A.baseName2, ".dll") let projFileName = Path.ChangeExtension(Project2A.baseName2, ".fsproj") let fileSource1 = """ @@ -637,22 +631,22 @@ module Project2B let v = Project2A.C().InternalMember // access an internal symbol """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = + let options = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| ("-r:" + Project2A.dllName); |] - ReferencedProjects = [| (Project2A.dllName, Project2A.options); |] } + ReferencedProjects = [| FSharpReferencedProject.CreateFSharp(Project2A.dllName, Project2A.options); |] } let cleanFileName a = if a = fileName1 then "file1" else "??" //Project2A.fileSource1 // A project referencing Project2A but without access to the internals of A -module internal Project2C = +module internal Project2C = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") let dllName = Path.ChangeExtension(Project2A.baseName3, ".dll") let projFileName = Path.ChangeExtension(Project2A.baseName3, ".fsproj") let fileSource1 = """ @@ -661,48 +655,48 @@ module Project2C let v = Project2A.C().InternalMember // access an internal symbol """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = + let options = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| ("-r:" + Project2A.dllName); |] - ReferencedProjects = [| (Project2A.dllName, Project2A.options); |] } + ReferencedProjects = [| FSharpReferencedProject.CreateFSharp(Project2A.dllName, Project2A.options); |] } let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test multi project2 errors`` () = +let ``Test multi project2 errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2B.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project2B.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "multi project2 error: <<<%s>>>" e.Message - wholeProjectResults .Errors.Length |> shouldEqual 0 + wholeProjectResults .Diagnostics.Length |> shouldEqual 0 - let wholeProjectResultsC = checker.ParseAndCheckProject(Project2C.options) |> Async.RunSynchronously - wholeProjectResultsC.Errors.Length |> shouldEqual 1 + let wholeProjectResultsC = checker.ParseAndCheckProject(Project2C.options) |> Async.RunImmediate + wholeProjectResultsC.Diagnostics.Length |> shouldEqual 1 [] -let ``Test multi project 2 all symbols`` () = +let ``Test multi project 2 all symbols`` () = - let mpA = checker.ParseAndCheckProject(Project2A.options) |> Async.RunSynchronously - let mpB = checker.ParseAndCheckProject(Project2B.options) |> Async.RunSynchronously - let mpC = checker.ParseAndCheckProject(Project2C.options) |> Async.RunSynchronously + let mpA = checker.ParseAndCheckProject(Project2A.options) |> Async.RunImmediate + let mpB = checker.ParseAndCheckProject(Project2B.options) |> Async.RunImmediate + let mpC = checker.ParseAndCheckProject(Project2C.options) |> Async.RunImmediate // These all get the symbol in A, but from three different project compilations/checks - let symFromA = - [ for s in mpA.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "InternalMember" then + let symFromA = + [ for s in mpA.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "InternalMember" then yield s.Symbol ] |> List.head - let symFromB = - [ for s in mpB.GetAllUsesOfAllSymbols() |> Async.RunSynchronously do - if s.Symbol.DisplayName = "InternalMember" then + let symFromB = + [ for s in mpB.GetAllUsesOfAllSymbols() do + if s.Symbol.DisplayName = "InternalMember" then yield s.Symbol ] |> List.head symFromA.IsAccessible(mpA.ProjectContext.AccessibilityRights) |> shouldEqual true @@ -711,23 +705,23 @@ let ``Test multi project 2 all symbols`` () = symFromB.IsAccessible(mpA.ProjectContext.AccessibilityRights) |> shouldEqual true symFromB.IsAccessible(mpB.ProjectContext.AccessibilityRights) |> shouldEqual true symFromB.IsAccessible(mpC.ProjectContext.AccessibilityRights) |> shouldEqual false - + //------------------------------------------------------------------------------------ -module internal Project3A = +module internal Project3A = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileSource1 = """ module Project3A ///A parameterized active pattern of divisibility -let (|DivisibleBy|_|) by n = +let (|DivisibleBy|_|) by n = if n % by = 0 then Some DivisibleBy else None """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -737,10 +731,10 @@ let (|DivisibleBy|_|) by n = // A project referencing a sub-project -module internal MultiProject3 = +module internal MultiProject3 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let baseName = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let baseName = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(baseName, ".dll") let projFileName = Path.ChangeExtension(baseName, ".fsproj") let fileSource1 = """ @@ -748,47 +742,51 @@ module MultiProject3 open Project3A -let fizzBuzz = function - | DivisibleBy 3 & DivisibleBy 5 -> "FizzBuzz" - | DivisibleBy 3 -> "Fizz" - | DivisibleBy 5 -> "Buzz" - | _ -> "" +let fizzBuzz = function + | DivisibleBy 3 & DivisibleBy 5 -> "FizzBuzz" + | DivisibleBy 3 -> "Fizz" + | DivisibleBy 5 -> "Buzz" + | _ -> "" """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = + let options = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - { options with + { options with OtherOptions = Array.append options.OtherOptions [| ("-r:" + Project3A.dllName) |] - ReferencedProjects = [| (Project3A.dllName, Project3A.options) |] } + ReferencedProjects = [| FSharpReferencedProject.CreateFSharp(Project3A.dllName, Project3A.options) |] } let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test multi project 3 whole project errors`` () = +let ``Test multi project 3 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "multi project 3 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test active patterns' XmlDocSig declared in referenced projects`` () = - let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(MultiProject3.fileName1, MultiProject3.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(MultiProject3.fileName1, MultiProject3.options) + |> Async.RunImmediate - let divisibleBySymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(7,7,"",["DivisibleBy"]) |> Async.RunSynchronously - divisibleBySymbolUse.IsSome |> shouldEqual true - let divisibleBySymbol = divisibleBySymbolUse.Value.Symbol + let divisibleBySymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(7,7,"",["DivisibleBy"]) + divisibleBySymbolUse.IsSome |> shouldEqual true + let divisibleBySymbol = divisibleBySymbolUse.Value.Symbol divisibleBySymbol.ToString() |> shouldEqual "symbol DivisibleBy" let divisibleByActivePatternCase = divisibleBySymbol :?> FSharpActivePatternCase - divisibleByActivePatternCase.XmlDoc |> Seq.toList |> shouldEqual [ "A parameterized active pattern of divisibility" ] + match divisibleByActivePatternCase.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> + t.UnprocessedLines |> shouldEqual [| "A parameterized active pattern of divisibility" |] + t.GetElaboratedXmlLines() |> shouldEqual [| ""; "A parameterized active pattern of divisibility"; "" |] + | _ -> failwith "wrong kind" divisibleByActivePatternCase.XmlDocSig |> shouldEqual "M:Project3A.|DivisibleBy|_|(System.Int32,System.Int32)" let divisibleByGroup = divisibleByActivePatternCase.Group divisibleByGroup.IsTotal |> shouldEqual false @@ -804,14 +802,14 @@ let ``Test active patterns' XmlDocSig declared in referenced projects`` () = [] let ``Test max memory gets triggered`` () = let checker = FSharpChecker.Create() - let reached = ref false + let reached = ref false checker.MaxMemoryReached.Add (fun () -> reached := true) - let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunImmediate reached.Value |> shouldEqual false checker.MaxMemory <- 0 - let wholeProjectResults2 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously + let wholeProjectResults2 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunImmediate reached.Value |> shouldEqual true - let wholeProjectResults3 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunSynchronously + let wholeProjectResults3 = checker.ParseAndCheckProject(MultiProject3.options) |> Async.RunImmediate reached.Value |> shouldEqual true @@ -819,185 +817,151 @@ let ``Test max memory gets triggered`` () = [] -#if NETCOREAPP -[] +let ``In-memory cross-project references to projects using generative type provides should fallback to on-disk references`` () = + // The type provider and its dependency are compiled as part of the solution build +#if DEBUG + let csDLL = __SOURCE_DIRECTORY__ + @"/../../artifacts/bin/TestTP/Debug/netstandard2.0/CSharp_Analysis.dll" + let tpDLL = __SOURCE_DIRECTORY__ + @"/../../artifacts/bin/TestTP/Debug/netstandard2.0/TestTP.dll" +#else + let csDLL = __SOURCE_DIRECTORY__ + @"/../../artifacts/bin/TestTP/Release/netstandard2.0/CSharp_Analysis.dll" + let tpDLL = __SOURCE_DIRECTORY__ + @"/../../artifacts/bin/TestTP/Release/netstandard2.0/TestTP.dll" #endif -let ``Type provider project references should not throw exceptions`` () = - //let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Debug")]) - let options = - {ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/TypeProviderConsole.fsproj"; - ProjectId = None - SourceFiles = [|__SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/Program.fs"|]; - Stamp = None - OtherOptions = - [|yield "--simpleresolution"; - yield "--noframework"; - yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/bin/Debug/TypeProviderConsole.exe"; - yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/bin/Debug/TypeProviderConsole.xml"; - yield "--subsystemversion:6.00"; - yield "--highentropyva+"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:exe"; - yield "--define:DEBUG"; - yield "--define:TRACE"; - yield "--debug+"; - yield "--optimize-"; - yield "--tailcalls-"; - yield "--debug:full"; - yield "--platform:anycpu"; - for r in mkStandardProjectReferences () do - yield "-r:" + r - yield "-r:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll"|]; - ReferencedProjects = - [|(__SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll", - {ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.fsproj"; +// These two projects should have been built before the test executes + if not (File.Exists csDLL) then + failwith $"expect {csDLL} to exist" + if not (File.Exists tpDLL) then + failwith $"expect {tpDLL} to exist" + let optionsTestProject = + { ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TestProject/TestProject.fsproj" ProjectId = None - SourceFiles = [|__SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/Library1.fs"|]; + SourceFiles = + [| __SOURCE_DIRECTORY__ + @"/data/TestProject/TestProject.fs" |] Stamp = None OtherOptions = - [|yield "--simpleresolution"; - yield "--noframework"; - yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll"; - yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/bin/Debug/TypeProviderLibrary.xml"; - yield "--subsystemversion:6.00"; - yield "--highentropyva+"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:library"; - yield "--define:DEBUG"; - yield "--define:TRACE"; - yield "--debug+"; - yield "--optimize-"; - yield "--tailcalls-"; - yield "--debug:full"; - yield "--platform:anycpu"; + [|yield "--simpleresolution" + yield "--noframework" + yield "--out:" + __SOURCE_DIRECTORY__ + @"/../../artifacts/bin/TestProject/Debug/netstandard2.0/TestProject.dll" + yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TestProject/bin/Debug/TestProject.xml" + yield "--subsystemversion:6.00" + yield "--highentropyva+" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + yield "--define:DEBUG" + yield "--define:TRACE" + yield "--debug+" + yield "--optimize-" + yield "--tailcalls-" + yield "--debug:full" + yield "--platform:anycpu" for r in mkStandardProjectReferences () do yield "-r:" + r - yield "-r:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/FSharp.Data.TypeProviders.dll"; - |]; - ReferencedProjects = [||]; - IsIncompleteTypeCheckEnvironment = false; - UseScriptResolutionRules = false; + // Make use of the type provider and reference its dependency + yield "-r:" + csDLL + yield "-r:" + tpDLL + |] + ReferencedProjects = [||] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false LoadTime = System.DateTime.Now - UnresolvedReferences = None; - OriginalLoadReferences = []; - ExtraProjectInfo = None;})|]; - IsIncompleteTypeCheckEnvironment = false; - UseScriptResolutionRules = false; - LoadTime = System.DateTime.Now - UnresolvedReferences = None; - OriginalLoadReferences = []; - ExtraProjectInfo = None;} - - //printfn "options: %A" options - let fileName = __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/Program.fs" - let fileSource = File.ReadAllText(fileName) - let fileParseResults, fileCheckAnswer = checker.ParseAndCheckFileInProject(fileName, 0, FSharp.Compiler.Text.SourceText.ofString fileSource, options) |> Async.RunSynchronously - let fileCheckResults = - match fileCheckAnswer with - | FSharpCheckFileAnswer.Succeeded(res) -> res - | res -> failwithf "Parsing did not finish... (%A)" res - - printfn "Parse Errors: %A" fileParseResults.Errors - printfn "Errors: %A" fileCheckResults.Errors - fileCheckResults.Errors |> Array.exists (fun error -> error.Severity = FSharpErrorSeverity.Error) |> shouldEqual false + UnresolvedReferences = None + OriginalLoadReferences = [] } - - - -//------------------------------------------------------------------------------------ - -[] -#if NETCOREAPP -[] -#else -[] -#endif -let ``Projects creating generated types should not utilize cross-project-references but should still analyze oK once project is built`` () = - //let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Debug")]) - let options = - {ProjectFileName = - __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/TestConsole.fsproj"; + let optionsTestProject2 testProjectOutput = + {ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TestProject2/TestProject2.fsproj" ProjectId = None - SourceFiles = - [|__SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/AssemblyInfo.fs"; - __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/Program.fs"|]; + SourceFiles = [|__SOURCE_DIRECTORY__ + @"/data/TestProject2/TestProject2.fs"|] + Stamp = None OtherOptions = - [|yield "--simpleresolution"; - yield "--noframework"; - yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/bin/Debug/TestConsole.exe"; - yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/bin/Debug/TestConsole.XML"; - yield "--subsystemversion:6.00"; - yield "--highentropyva+"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:exe"; - yield "--define:DEBUG"; - yield "--define:TRACE"; - yield "--debug+"; - yield "--optimize-"; - yield "--tailcalls-"; - yield "--debug:full"; - yield "--platform:anycpu"; - yield "-r:" + __SOURCE_DIRECTORY__ + @"/../../packages/FSharp.Configuration.1.3.0/lib/net45/FSharp.Configuration.dll"; + [|yield "--simpleresolution" + yield "--noframework" + yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TestProject2/bin/Debug/TestProject2.dll" + yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TestProject2/bin/Debug/TestProject2.xml" + yield "--subsystemversion:6.00" + yield "--highentropyva+" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + yield "--define:DEBUG" + yield "--define:TRACE" + yield "--debug+" + yield "--optimize-" + yield "--tailcalls-" + yield "--debug:full" + yield "--platform:anycpu" for r in mkStandardProjectReferences () do yield "-r:" + r - yield "-r:" + __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll"|]; + // Make use of the type provider and reference its dependency + yield "-r:" + csDLL + yield "-r:" + tpDLL + // Make an in-memory reference to TestProject, which itself makes use of a type provider + // NOTE TestProject may not actually have been compiled + yield "-r:" + testProjectOutput|] ReferencedProjects = - [|(__SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll", - {ProjectFileName = - __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/TypeProvidersBug.fsproj"; - ProjectId = None - SourceFiles = - [|__SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/AssemblyInfo.fs"; - __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/Library1.fs"|]; - OtherOptions = - [|yield "--simpleresolution"; - yield "--noframework"; - yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll"; - yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.XML"; - yield "--subsystemversion:6.00"; - yield "--highentropyva+"; - yield "--fullpaths"; - yield "--flaterrors"; - yield "--target:library"; - yield "--define:DEBUG"; - yield "--define:TRACE"; - yield "--debug+"; - yield "--optimize-"; - yield "--tailcalls-"; - yield "--debug:full"; - yield "--platform:anycpu"; - yield "-r:" + __SOURCE_DIRECTORY__ + @"/../../packages/FSharp.Configuration.1.3.0/lib/net45/FSharp.Configuration.dll"; - for r in mkStandardProjectReferences () do - yield "-r:" + r |]; - ReferencedProjects = [||]; - IsIncompleteTypeCheckEnvironment = false; - UseScriptResolutionRules = false; - LoadTime = System.DateTime.Now - UnresolvedReferences = None; - OriginalLoadReferences = []; - Stamp = None; - ExtraProjectInfo = None;})|]; - IsIncompleteTypeCheckEnvironment = false; - UseScriptResolutionRules = false; + [|FSharpReferencedProject.CreateFSharp(testProjectOutput, optionsTestProject )|] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false LoadTime = System.DateTime.Now - UnresolvedReferences = None; - Stamp = None; - OriginalLoadReferences = []; - ExtraProjectInfo = None;} + UnresolvedReferences = None + OriginalLoadReferences = []} + //printfn "options: %A" options - let fileName = __SOURCE_DIRECTORY__ + @"/data/TypeProvidersBug/TestConsole/Program.fs" - let fileSource = File.ReadAllText(fileName) - let fileParseResults, fileCheckAnswer = checker.ParseAndCheckFileInProject(fileName, 0, FSharp.Compiler.Text.SourceText.ofString fileSource, options) |> Async.RunSynchronously - let fileCheckResults = - match fileCheckAnswer with - | FSharpCheckFileAnswer.Succeeded(res) -> res - | res -> failwithf "Parsing did not finish... (%A)" res - - printfn "Parse Errors: %A" fileParseResults.Errors - printfn "Errors: %A" fileCheckResults.Errors - fileCheckResults.Errors |> Array.exists (fun error -> error.Severity = FSharpErrorSeverity.Error) |> shouldEqual false + begin + let fileName = __SOURCE_DIRECTORY__ + @"/data/TestProject/TestProject.fs" + let fileSource = FileSystem.OpenFileForReadShim(fileName).ReadAllText() + let fileParseResults, fileCheckAnswer = checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString fileSource, optionsTestProject) |> Async.RunImmediate + let fileCheckResults = + match fileCheckAnswer with + | FSharpCheckFileAnswer.Succeeded(res) -> res + | res -> failwithf "Parsing did not finish... (%A)" res + + printfn "Parse Diagnostics (TestProject): %A" fileParseResults.Diagnostics + printfn "Check Diagnostics (TestProject): %A" fileCheckResults.Diagnostics + fileCheckResults.Diagnostics |> Array.exists (fun error -> error.Severity = FSharpDiagnosticSeverity.Error) |> shouldEqual false + end + + // Set up a TestProject2 using an in-memory reference to TestProject but where TestProject has not + // compiled to be on-disk. In this case, we expect an error, because TestProject uses a generative + // type provider, and in-memory cross-references to projects using generative type providers are + // not yet supported. + begin + let testProjectNotCompiledSimulatedOutput = __SOURCE_DIRECTORY__ + @"/DUMMY/TestProject.dll" + let options = optionsTestProject2 testProjectNotCompiledSimulatedOutput + let fileName = __SOURCE_DIRECTORY__ + @"/data/TestProject2/TestProject2.fs" + let fileSource = FileSystem.OpenFileForReadShim(fileName).ReadAllText() + let fileParseResults, fileCheckAnswer = checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString fileSource, options) |> Async.RunImmediate + let fileCheckResults = + match fileCheckAnswer with + | FSharpCheckFileAnswer.Succeeded(res) -> res + | res -> failwithf "Parsing did not finish... (%A)" res + + printfn "Parse Diagnostics (TestProject2 without compiled TestProject): %A" fileParseResults.Diagnostics + printfn "Check Diagnostics (TestProject2 without compiled TestProject): %A" fileCheckResults.Diagnostics + fileCheckResults.Diagnostics + |> Array.exists (fun diag -> + diag.Severity = FSharpDiagnosticSeverity.Error && + diag.Message.Contains("TestProject.dll")) + |> shouldEqual true + end + + // Do the same check with an in-memory reference to TestProject where TestProject exists + // compiled to disk. In this case, we expect no error, because even though TestProject uses a generative + // type provider, the in-memory cross-reference is ignored and an on-disk reference is used instead. + begin + let testProjectCompiledOutput = __SOURCE_DIRECTORY__ + @"/data/TestProject/netstandard2.0/TestProject.dll" + if not (File.Exists testProjectCompiledOutput) then + failwith $"expect {testProjectCompiledOutput} to exist" + let options = optionsTestProject2 testProjectCompiledOutput + let fileName = __SOURCE_DIRECTORY__ + @"/data/TestProject2/TestProject2.fs" + let fileSource = FileSystem.OpenFileForReadShim(fileName).ReadAllText() + let fileParseResults, fileCheckAnswer = checker.ParseAndCheckFileInProject(fileName, 0, SourceText.ofString fileSource, options) |> Async.RunImmediate + let fileCheckResults = + match fileCheckAnswer with + | FSharpCheckFileAnswer.Succeeded(res) -> res + | res -> failwithf "Parsing did not finish... (%A)" res + + printfn "Parse Diagnostics (TestProject2 with compiled TestProject): %A" fileParseResults.Diagnostics + printfn "Check Diagnostics (TestProject2 with compiled TestProject): %A" fileCheckResults.Diagnostics + fileCheckResults.Diagnostics.Length |> shouldEqual 0 + end -//------------------------------------------------------------------------------------ diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs new file mode 100644 index 00000000000..003092a758b --- /dev/null +++ b/tests/service/ParserTests.fs @@ -0,0 +1,175 @@ +module FSharp.Compiler.Service.Tests.Parser.Recovery + +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open NUnit.Framework + +[] +let ``Interface impl - No members`` () = + let parseResults = getParseResults """ +type T = + interface I with + member x.P2 = () + +let x = () +""" + match getSingleModuleMemberDecls parseResults with + | [ SynModuleDecl.Types ([ SynTypeDefn (typeRepr = SynTypeDefnRepr.ObjectModel (members = [ _; _ ])) ], _) + SynModuleDecl.Let _ ] -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Union case 01 - of`` () = + let parseResults = getParseResults """ +type U1 = + | A of + +type U2 = + | B of + | C + +let x = () +""" + let (|UnionWithCases|_|) typeDefn = + match typeDefn with + | SynTypeDefn (typeRepr = SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (unionCases = cases), _)) -> + cases |> List.map (fun (SynUnionCase (ident = ident)) -> ident.idText) |> Some + | _ -> None + + match getSingleModuleMemberDecls parseResults with + | [ SynModuleDecl.Types ([ UnionWithCases ["A"]], _) + SynModuleDecl.Types ([ UnionWithCases ["B"; "C"] ], _) + SynModuleDecl.Let _ ] -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Match clause 01`` () = + let parseResults = getParseResults """ +match () with +| x +""" + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + + +[] +let ``Match clause 02 - When`` () = + let parseResults = getParseResults """ +match () with +| x when true +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 03 - When`` () = + let parseResults = getParseResults """ +match () with +| x when true +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _); _ ], _) -> () + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 04 - Or pat`` () = + let parseResults = getParseResults """ +match () with +| x +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (SynPat.Or _, _, _, SynExpr.Const _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 05 - Missing body`` () = + let parseResults = getParseResults """ +match () with +| x -> +| _ -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (_, _, _, SynExpr.ArbitraryAfterError _, _, _) + SynMatchClause (_, _, _, SynExpr.Const _, _, _) ], _) -> () + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 06`` () = + let parseResults = getParseResults """ +match () with +| (x +| y -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (pat = pat) ], _) -> + match pat with + | SynPat.FromParseError (SynPat.Paren (SynPat.Or (SynPat.Named _, SynPat.Named _, _), _), _) -> () + | _ -> failwith "Unexpected pattern" + | _ -> failwith "Unexpected tree" + +[] +let ``Match clause 07`` () = + let parseResults = getParseResults """ +match () with +| (x, +| y -> () +""" + + match getSingleExprInModule parseResults with + | SynExpr.Match (_, _, [ SynMatchClause (pat = pat) ], _) -> + match pat with + | SynPat.Or + (SynPat.FromParseError (SynPat.Paren (SynPat.FromParseError (SynPat.Wild _, _), _), _), + SynPat.Named _, _) -> () + | _ -> failwith "Unexpected pattern" + | _ -> failwith "Unexpected tree" + +[] +let ``Let - Parameter - Paren 01`` () = + let parseResults = getParseResults """ +let f (x +""" + + match getSingleDeclInModule parseResults with + | SynModuleDecl.Let (_, [ SynBinding (headPat = headPat) ], _) -> + match headPat with + | SynPat.LongIdent (_, _, _, SynArgPats.Pats [ SynPat.FromParseError (SynPat.Paren (SynPat.Named _, _), _) ], _, _) -> () + | _ -> failwith "Unexpected tree" + | _ -> failwith "Unexpected tree" + +[] +let ``Let - Parameter - Paren 02 - Tuple`` () = + let parseResults = getParseResults """ +let f (x, y +""" + + match getSingleDeclInModule parseResults with + | SynModuleDecl.Let (_, [ SynBinding (headPat = headPat) ], _) -> + match headPat with + | SynPat.LongIdent (_, _, _, SynArgPats.Pats [ SynPat.FromParseError (SynPat.Paren (SynPat.Tuple _, _), _) ], _, _) -> () + | _ -> failwith "Unexpected tree" + | _ -> failwith "Unexpected tree" + +[] +let ``Let - Parameter - Paren 03 - Tuple`` () = + let parseResults = getParseResults """ +let f (x, +""" + + match getSingleDeclInModule parseResults with + | SynModuleDecl.Let (_, [ SynBinding (headPat = SynPat.LongIdent (argPats = SynArgPats.Pats [ pat ])) ], _) -> + match pat with + | SynPat.FromParseError (SynPat.Paren (SynPat.FromParseError (SynPat.Wild _, _), _), _) -> () + | _ -> failwith "Unexpected tree" + | _ -> failwith "Unexpected tree" diff --git a/tests/service/PatternMatchCompilationTests.fs b/tests/service/PatternMatchCompilationTests.fs new file mode 100644 index 00000000000..25a6e240072 --- /dev/null +++ b/tests/service/PatternMatchCompilationTests.fs @@ -0,0 +1,1271 @@ +module FSharp.Compiler.Service.Tests.PatternMatchCompilationTests + +open FsUnit +open NUnit.Framework + +[] +#if !NETCOREAPP +[] +#endif +let ``Wrong type 01 - Match`` () = + let _, checkResults = getParseAndCheckResults """ +match () with +| "" -> () +| x -> let y = () in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(3,2--3,4): This expression was expected to have type 'unit' but here has type 'string'" + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``Wrong type 02 - Binding`` () = + let _, checkResults = getParseAndCheckResults """ +let ("": unit), (x: int) = let y = () in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(2,5--2,7): This expression was expected to have type 'unit' but here has type 'string'" + "(2,41--2,43): This expression was expected to have type 'unit * int' but here has type 'unit'" + "(2,4--2,24): Incomplete pattern matches on this expression." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Attributes 01 `` () = + let _, checkResults = getParseAndCheckResults """ +match () with +| [] x -> let y = () in () +""" + assertHasSymbolUsages ["x"; "y"; "CompiledNameAttribute"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(3,2--3,25): Attributes are not allowed within patterns" + "(3,4--3,16): This attribute is not valid for use on this language element" + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Optional val 01 `` () = + let _, checkResults = getParseAndCheckResults """ +match () with +| ?x -> let y = () in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(3,2--3,4): Optional arguments are only permitted on type members" + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Null 01`` () = + let _, checkResults = getParseAndCheckResults """ +match 1, 2 with +| null -> let y = () in () +""" + assertHasSymbolUsages ["y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(3,2--3,6): The type '(int * int)' does not have 'null' as a proper value" + "(2,6--2,10): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 01 - Missing field`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int * int * int + +match A with +| B (x, _) -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,2--7,10): This union case expects 3 arguments in tupled form" + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 02 - Extra args`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int + +match A with +| B (_, _, x) -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,5--7,12): This expression was expected to have type 'int' but here has type ''a * 'b * 'c'" + "(6,6--6,7): Incomplete pattern matches on this expression." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 03 - Extra args`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int * int + +match A with +| B (_, _, x) -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,11--7,12): This constructor is applied to 3 argument(s) but expects 2" + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 04 - Extra args`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int + +match A with +| A x -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,2--7,5): This union case does not take arguments" + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'B (_)' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 05 - Single arg, no errors`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int + +match A with +| B x -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 06 - Named args - Wrong field name`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of field: int + +match A with +| B (name = x) -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,5--7,9): The union case 'B' does not have a field named 'name'." + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 07 - Named args - Name used twice`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of field: int * int + +match A with +| B (field = x; field = z) -> let y = x + z + 1 in () +""" + assertHasSymbolUsages ["x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,16--7,21): Union case/exception field 'field' cannot be used more than once." + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Union case 08 - Multiple tupled args`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of field: int * int + +match A with +| B x z -> let y = x + z + 1 in () +""" + assertHasSymbolUsages ["x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,2--7,7): This union case expects 2 arguments in tupled form" + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + + +[] +let ``Union case 09 - Single arg`` () = + let _, checkResults = getParseAndCheckResults """ +match None with +| None -> () +| Some (x, z) -> let y = x + z + 1 in () +""" + assertHasSymbolUsages ["x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [ + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Active pattern 01 - Named args`` () = + let _, checkResults = getParseAndCheckResults """ +let (|Foo|) x = x + +match 1 with +| Foo (field = x) -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,2--5,17): Foo is an active pattern and cannot be treated as a discriminated union case with named fields." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Literal 01 - Args - F#`` () = + let _, checkResults = getParseAndCheckResults """ +let [] Foo = 1 + +match 1 with +| Foo x -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,2--5,7): This literal pattern does not take arguments" + "(4,6--4,7): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Literal 02 - Args - IL`` () = + let _, checkResults = getParseAndCheckResults """ +open System.Diagnostics + +match TraceLevel.Off with +| TraceLevel.Off x -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,2--5,18): This literal pattern does not take arguments" + "(4,6--4,20): Incomplete pattern matches on this expression. For example, the value 'TraceLevel.Error' may indicate a case not covered by the pattern(s)." + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Caseless DU`` () = + let _, checkResults = getParseAndCheckResults """ +type DU = Case of int + +let f du = + match du with + | Case -> () + +let dowork () = + f (Case 1) + 0 // return an integer exit code""" + assertHasSymbolUsages ["DU"; "dowork"; "du"; "f"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(6,6--6,10): This constructor is applied to 0 argument(s) but expects 1" + ] + +[] +let ``Or 01 - No errors`` () = + let _, checkResults = getParseAndCheckResults """ +match 1 with +| x | x -> let y = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"] checkResults + dumpErrors checkResults |> shouldEqual [] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Or 02 - Different names`` () = + let _, checkResults = getParseAndCheckResults """ +match 1 with +| x | z -> let y = x + z + 1 in () +""" + assertHasSymbolUsages ["x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(3,2--3,7): The two sides of this 'or' pattern bind different sets of variables" + ] + + +[] +#if !NETCOREAPP +[] +#endif +let ``Or 03 - Different names and types`` () = + let _, checkResults = getParseAndCheckResults """ +type U = + | A + | B of int * string + +match A with +| B (x, y) | B (a, x) -> let z = x + 1 in () +""" + assertHasSymbolUsages ["x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(7,2--7,21): The two sides of this 'or' pattern bind different sets of variables" + "(7,19--7,20): This expression was expected to have type 'int' but here has type 'string'" + "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)." + ] + +[] +let ``As 01 - names and wildcards`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +match 1 with +| _ as w -> let x = w + 1 in () + +match 2 with +| y as _ -> let z = y + 1 in () + +match 3 with +| a as b -> let c = a + b in () +""" + assertHasSymbolUsages ["a"; "b"; "c"; "w"; "x"; "y"; "z"] checkResults + dumpErrors checkResults |> shouldEqual [] + + +[] +#if !NETCOREAPP +[] +#endif +let ``As 02 - type testing`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let (|Id|) = id +match box 1 with +| :? int as a -> let b = a + 1 in () +| c & d as :? uint -> let z = c + d + 2u in () // Tighten typing left-to-right: https://github.com/fsharp/fslang-design/pull/595#issuecomment-860591709 +| :? int64 as Id e -> let f = e + 3L in () +| :? uint64 as Id g & h -> let y = g + 4UL + h in () // (:? uint64 as Id h) & (i : obj) +| :? int8 as Id i as j -> let x = i + 5y + j in () // Only the first "as" will have the derived type +""" + assertHasSymbolUsages (List.map string ['a'..'j']) checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,34--5,35): The type 'obj' does not support the operator '+'" + "(5,32--5,33): The type 'obj' does not support the operator '+'" + "(7,45--7,46): The type 'obj' does not match the type 'uint64'" + "(7,43--7,44): The type 'obj' does not match the type 'uint64'" + "(8,43--8,44): The type 'obj' does not match the type 'int8'" + "(8,41--8,42): The type 'obj' does not match the type 'int8'" + "(3,6--3,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 03 - impossible type testing`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +match Unchecked.defaultof with +| :? System.Enum as (:? System.ConsoleKey as a) -> let b = a + enum 1 in () +| :? System.Enum as (:? System.ConsoleKey as c) -> let d = c + enum 1 in () +| :? System.Enum as (:? int as x) -> let w = x + 1 in () +| :? string as y -> let z = y + "" in () +| _ -> () +""" + assertHasSymbolUsages ["a"; "b"; "c"; "d"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,21--5,27): Type constraint mismatch. The type 'int' is not compatible with type 'System.Enum' " + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 04 - duplicate type testing`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +match Unchecked.defaultof with +| :? System.Enum as (a & b) -> let c = a = b in () +| :? System.Enum as (:? System.ConsoleKey as (d & e)) -> let f = d + e + enum 1 in () +| g -> () +""" + assertHasSymbolUsages ["a"; "b"; "c"; "d"; "e"; "f"; "g"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(4,2--4,85): This rule will never be matched" + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 05 - inferred type testing`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +match Unchecked.defaultof with +| :? _ as a -> let _ = a in () + +match Unchecked.defaultof with +| :? _ as z -> let _ = z in () +""" + assertHasSymbolUsages ["a"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(2,6--2,25): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(6,2--6,6): The type 'int' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + ] + +[] +let ``As 06 - completeness`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +match Unchecked.defaultof with +| true as a -> if a then () +| b as false -> if not b then () + +match Unchecked.defaultof with +| c as true as d -> if c && d then () +| e as (f as false) -> if e || f then () + +match Unchecked.defaultof with +| (g & h) as (i as true) as (_ as j) -> if g && h && i && j then () +| k & l as (m as (false as n)) as (o as _) -> if k || l || m || n || o then () +""" + assertHasSymbolUsages (List.map string ['a'..'o']) checkResults + dumpErrors checkResults |> shouldEqual [] + +[] +let ``As 07 - syntactical precedence matrix testing right - total patterns`` () = + (* +bindingPattern: + | headBindingPattern +headBindingPattern: + | headBindingPattern AS constrPattern + | headBindingPattern BAR headBindingPattern + | headBindingPattern COLON_COLON headBindingPattern + | tuplePatternElements %prec pat_tuple + | conjPatternElements %prec pat_conj + | constrPattern +constrPattern: + | atomicPatternLongIdent explicitValTyparDecls + | atomicPatternLongIdent opt_explicitValTyparDecls2 atomicPatsOrNamePatPairs %prec pat_app + | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_PAREN_APP atomicPatsOrNamePatPairs + | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs + | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst + | atomicPattern +atomicPattern: + | quoteExpr + | CHAR DOT_DOT CHAR + | LBRACE recordPatternElementsAux rbrace + | LBRACK listPatternElements RBRACK + | LBRACK_BAR listPatternElements BAR_RBRACK + | UNDERSCORE + | QMARK ident + | atomicPatternLongIdent %prec prec_atompat_pathop + | constant + | FALSE + | TRUE + | NULL + | LPAREN parenPatternBody rparen + | LPAREN parenPatternBody recover + | LPAREN error rparen + | LPAREN recover + | STRUCT LPAREN tupleParenPatternElements rparen + | STRUCT LPAREN tupleParenPatternElements recover + | STRUCT LPAREN error rparen + | STRUCT LPAREN recover +parenPatternBody: + | parenPattern + | /* EMPTY */ +parenPattern: + | parenPattern AS constrPattern + | parenPattern BAR parenPattern + | tupleParenPatternElements + | conjParenPatternElements + | parenPattern COLON typeWithTypeConstraints %prec paren_pat_colon + | attributes parenPattern %prec paren_pat_attribs + | parenPattern COLON_COLON parenPattern + | constrPattern + *) + let _, checkResults = getParseAndCheckResultsPreview $""" +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Id0|) = ignore +let (|Id1|) = id +let (|Id2|) _ = id +type AAA = {{ aaa : int }} +let a = 1 +let b as c = 2 +let d as e | d & e = 3 +let f as g, h = 4, 5 +let i as j & k = 6 +let l as Id1 m = 7 +let n as Id2 a o = 8 +let p as {{ aaa = q }} = {{ aaa = 9 }} +let r as _ = 10 +let s as Id0 = 11 +let t as (u) = 12 +let v as struct(w, x) = 13, 14 +let y as z : int = 15{set { 'a'..'x' } - set [ 'p'; 'v' ] |> Set.map (sprintf " + %c") |> System.String.Concat} +Some p |> eq +Some v |> eq +() +""" + assertHasSymbolUsages (List.map string ['a'..'z']) checkResults + dumpErrors checkResults |> shouldEqual [] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 08 - syntactical precedence matrix testing right - partial patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Unit1|_|) x = if System.Random().NextDouble() < 0.5 then Some Unit1 else None +let (|Unit2|_|) _ = (|Unit1|_|) +let (|Id1|_|) x = if System.Random().NextDouble() < 0.5 then Some x else None +let (|Id2|_|) _ = (|Id1|_|) +let a = 1 +let b as c::d as e = 2::[3] +let f as Unit1 = 4 +let g as Unit2 a h = 5 +let i as Id1 j = 6 +let k as Id2 a l = 7 +box 8 |> function +| m as :? int -> +box {| aaa = 9 |} |> function +| n as :? {| aaa : int |} -> +let o as [p] = [10] +let q as [|r|] = [|11|] +let s as 12 = 12 +let t as false = false +let u as true = true +let v as null = null +let w as (null) = null +let x as y : int = 13 + a + b + c + f + g + i + j + k + l + p + r + s +Some d |> eq +Some e |> eq +Some h |> eq +Some m |> eq +Some n |> eq +Some o |> eq +Some q |> eq +Some t |> eq +Some u |> eq +Some v |> eq +Some w |> eq +() +""" + assertHasSymbolUsages (List.map string ['a'..'y']) checkResults + dumpErrors checkResults |> shouldEqual [ + "(8,4--8,18): Incomplete pattern matches on this expression. For example, the value '[]' may indicate a case not covered by the pattern(s)." + "(9,4--9,14): Incomplete pattern matches on this expression." + "(10,4--10,18): Incomplete pattern matches on this expression." + "(11,4--11,14): Incomplete pattern matches on this expression." + "(12,4--12,16): Incomplete pattern matches on this expression." + "(23,4--23,15): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(22,4--22,13): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(21,4--21,13): Incomplete pattern matches on this expression. For example, the value 'false' may indicate a case not covered by the pattern(s)." + "(20,4--20,14): Incomplete pattern matches on this expression. For example, the value 'true' may indicate a case not covered by the pattern(s)." + "(19,4--19,11): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + "(18,4--18,14): Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s)." + "(17,4--17,12): Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s)." + "(15,21--15,29): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(13,9--13,17): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 09 - syntactical precedence matrix testing right - erroneous patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let (|DefinedPattern|) = id +let a as 1 = true +let b as true = 2 +let c as :? int = box 3 +let d as :? int = 4 +let e as UndefinedPattern = 5 +let f as DefinedPattern () = 6 +let g as DefinedPattern = 7 +let h as , i = 8 +let j as : k = 9 +let l as :: m = 10 +let n as & o = 11 +let p as | q = 12 +let r as ( s = 13 +let t as ) u = 14 +let v as struct w = 15 +let x as () = y +let z as +""" + dumpErrors checkResults |> shouldEqual [ + "(10,9--10,10): Unexpected symbol ',' in binding" + "(11,9--11,10): Unexpected symbol ':' in binding" + "(12,9--12,11): Unexpected symbol '::' in binding" + "(13,9--13,10): Unexpected symbol '&' in binding" + "(14,9--14,10): Unexpected symbol '|' in binding" + "(15,13--15,14): Unexpected symbol '=' in pattern. Expected ')' or other token." + "(15,9--15,10): Unmatched '('" + "(16,0--16,3): Possible incorrect indentation: this token is offside of context started at position (15:1). Try indenting this token further or using standard formatting conventions." + "(17,16--17,17): Unexpected identifier in pattern. Expected '(' or other token." + "(20,0--20,0): Incomplete structured construct at or before this point in binding" + "(3,13--3,17): This expression was expected to have type 'int' but here has type 'bool'" + "(3,4--3,10): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + "(4,16--4,17): This expression was expected to have type 'bool' but here has type 'int'" + "(4,4--4,13): Incomplete pattern matches on this expression. For example, the value 'false' may indicate a case not covered by the pattern(s)." + "(5,9--5,15): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(6,9--6,15): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(8,29--8,30): This expression was expected to have type 'unit' but here has type 'int'" + "(9,26--9,27): This expression was expected to have type 'unit' but here has type 'int'" + "(18,14--18,15): The value or constructor 'y' is not defined." + ] + +[] +let ``As 10 - syntactical precedence matrix testing left - total patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview $""" +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Id0|) = ignore +let (|Id1|) = id +let (|Id2|) _ = id +type AAA = {{ aaa : int }} +let a = 1 +let b as c = 2 +let d | d as e = 3 +let f, g as h = 4, 5 +let i & j as k = 6 +let Id1 l as m = 7 +let Id2 a n as o = 8 +let {{ aaa = p }} as q = {{ aaa = 9 }} +let _ as r = 10 +let Id0 as s = 11 +let (t) as u = 12 +let struct(w, v) as x = 13, 14 +let (y : int) as z = 15{set { 'a'..'v' } - set [ 'h'; 'q' ] |> Set.map (sprintf " + %c") |> System.String.Concat} +Some h |> eq +Some q |> eq +Some x |> eq +() +""" + assertHasSymbolUsages (List.map string ['a'..'z']) checkResults + dumpErrors checkResults |> shouldEqual [] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 11 - syntactical precedence matrix testing left - partial patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Unit1|_|) x = if System.Random().NextDouble() < 0.5 then Some Unit1 else None +let (|Unit2|_|) _ = (|Unit1|_|) +let (|Id1|_|) x = if System.Random().NextDouble() < 0.5 then Some x else None +let (|Id2|_|) _ = (|Id1|_|) +let a = 1 +let b as (c::d as e) = 2::[3] +let Unit1 as f = 4 +let Unit2 a g as h = 5 +let Id1 i as j = 6 +let Id2 a k as l = 7 +box 8 |> function +| :? int as m -> +box {| aaa = 9 |} |> function +| :? {| aaa : int |} as n -> +let [o] as p = [10] +let [|q|] as r = [|11|] +let 12 as s = 12 +let false as t = false +let true as u = true +let null as v = null +let (null) as w = null +let (x : int) as y = 13 + a + c + f + h + i + j + k + l + m + o + q + s +Some b |> eq +Some d |> eq +Some e |> eq +Some g |> eq +Some n |> eq<{| aaa : int |}> +Some p |> eq +Some r |> eq +Some t |> eq +Some u |> eq +Some v |> eq +Some w |> eq +() +""" + assertHasSymbolUsages (List.map string ['a'..'y']) checkResults + dumpErrors checkResults |> shouldEqual [ + "(8,4--8,20): Incomplete pattern matches on this expression. For example, the value '[]' may indicate a case not covered by the pattern(s)." + "(9,4--9,14): Incomplete pattern matches on this expression." + "(10,4--10,18): Incomplete pattern matches on this expression." + "(11,4--11,14): Incomplete pattern matches on this expression." + "(12,4--12,16): Incomplete pattern matches on this expression." + "(23,4--23,15): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(22,4--22,13): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(21,4--21,13): Incomplete pattern matches on this expression. For example, the value 'false' may indicate a case not covered by the pattern(s)." + "(20,4--20,14): Incomplete pattern matches on this expression. For example, the value 'true' may indicate a case not covered by the pattern(s)." + "(19,4--19,11): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + "(18,4--18,14): Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s)." + "(17,4--17,12): Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s)." + "(15,21--15,29): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(13,9--13,17): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 12 - syntactical precedence matrix testing left - erroneous patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let (|DefinedPattern|) = id +let 1 as a = true +let true as b = 2 +let :? int as c = box 3 +let :? int as d = 4 +let UndefinedPattern as e = 5 +let DefinedPattern () as f = 6 +let DefinedPattern as g = 7 +let h, as i = 8 +let j : _ as k = 9 +let l :: as m = 10 +let n & as o = 11 +let p | as q = 12 +let r ( as s = 13 +let t ) as u = 14 +let v struct as w = 15 +let () as x = y +let z as = +""" + dumpErrors checkResults |> shouldEqual [ + "(10,7--10,9): Unexpected keyword 'as' in binding" + "(11,10--11,12): Unexpected keyword 'as' in binding. Expected '=' or other token." + "(12,9--12,11): Unexpected keyword 'as' in binding" + "(13,8--13,10): Unexpected keyword 'as' in binding" + "(14,8--14,10): Unexpected keyword 'as' in binding" + "(15,8--15,10): Unexpected keyword 'as' in pattern. Expected ')' or other token." + "(15,6--15,7): Unmatched '('" + "(16,0--16,3): Possible incorrect indentation: this token is offside of context started at position (15:1). Try indenting this token further or using standard formatting conventions." + "(16,0--16,3): Unexpected keyword 'let' or 'use' in binding. Expected incomplete structured construct at or before this point or other token." + "(15,0--15,3): Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword." + "(17,0--17,3): Incomplete structured construct at or before this point in implementation file" + "(20,0--20,0): Possible incorrect indentation: this token is offside of context started at position (19:1). Try indenting this token further or using standard formatting conventions." + "(20,0--20,0): Possible incorrect indentation: this token is offside of context started at position (19:1). Try indenting this token further or using standard formatting conventions." + "(3,13--3,17): This expression was expected to have type 'int' but here has type 'bool'" + "(3,4--3,10): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + "(4,16--4,17): This expression was expected to have type 'bool' but here has type 'int'" + "(4,4--4,13): Incomplete pattern matches on this expression. For example, the value 'false' may indicate a case not covered by the pattern(s)." + "(5,4--5,10): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(6,4--6,10): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(8,29--8,30): This expression was expected to have type 'unit' but here has type 'int'" + "(9,26--9,27): This expression was expected to have type 'unit' but here has type 'int'" + "(15,4--15,5): The pattern discriminator 'r' is not defined." + "(15,4--15,12): Incomplete pattern matches on this expression." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 13 - syntactical precedence matrix testing right with type tests - total patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview $""" +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Id0|) = ignore +let (|Id1|) = id +let (|Id2|) _ = id +type AAA = {{ aaa : int }} +let a = 1 +match box 2 with +| :? int as b as c -> +match box 3 with +| :? int as d | :? int & d as e -> // The left d has type 'int', the right d has type 'obj' +match box 4, 5 with +| :? int as f, g & h -> +match box 6 with +| :? int as i & j as k -> +match box 7 with +| :? int as Id1 l as m -> +match box 8 with +| :? int as Id2 a n as o -> +match box {{ aaa = 9 }} with +| :? AAA as {{ aaa = p }} as q -> +match box 10 with +| :? int as _ as r -> +match box 11 with +| :? int as Id0 as s -> +match box 12 with +| :? int as (t) as u -> +match box struct(13, 14) with +| :? struct(int * int) as struct(v, w) as x -> +let y as z : int = 15 + a + b + d + f + g + h + i + l + n + p + t + v + w +Some c |> eq +Some e |> eq +Some j |> eq +Some k |> eq +Some m |> eq +Some o |> eq +Some q |> eq +Some r |> eq +Some s |> eq +Some u |> eq +Some x |> eq +() +""" + assertHasSymbolUsages (List.map string ['a'..'z']) checkResults + dumpErrors checkResults |> shouldEqual [ + "(11,25--11,26): This expression was expected to have type 'int' but here has type 'obj'" + "(28,6--28,24): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(26,6--26,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(24,6--24,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(22,6--22,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(20,6--20,21): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(18,6--18,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(16,6--16,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(14,6--14,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(12,6--12,14): Incomplete pattern matches on this expression. For example, the value '(``some-other-subtype``,_)' may indicate a case not covered by the pattern(s)." + "(10,6--10,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(8,6--8,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 14 - syntactical precedence matrix testing right with type tests - partial patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Unit1|_|) x = if System.Random().NextDouble() < 0.5 then Some Unit1 else None +let (|Unit2|_|) _ = (|Unit1|_|) +let (|Id1|_|) x = if System.Random().NextDouble() < 0.5 then Some x else None +let (|Id2|_|) _ = (|Id1|_|) +let a = 1 +match box 2::[box 3] with +| :? int as b as c::d as e -> +match box 4 with +| :? int as Unit1 as f -> +match box 5 with +| :? int as Unit2 a g as h -> +match box 6 with +| :? int as Id1 i as j -> +match box 7 with +| :? int as Id2 a k as l -> +match box 8 with +| :? System.ValueType as :? int as m -> +match box {| aaa = 9 |} with +| :? obj as :? {| aaa : int |} as n -> +match box [10] with +| :? (int list) as [o] as p -> +match box [|11|] with +| :? (int[]) as [|q|] as r -> +match box 12 with +| :? int as 12 as s -> +match box false with +| :? bool as false as t -> +match box true with +| :? bool as true as u -> +match box null with +| :? System.ValueType as null as v -> +match box null with +| :? System.ValueType as (null) as w -> +let x as y : int = 13 + a + b + i + k + o + q +Some c |> eq +Some d |> eq +Some e |> eq +Some f |> eq +Some g |> eq +Some h |> eq +Some j |> eq +Some l |> eq +Some m |> eq +Some n |> eq +Some p |> eq +Some r |> eq +Some s |> eq +Some t |> eq +Some u |> eq +Some v |> eq +Some w |> eq +() +""" + assertHasSymbolUsages (set ['a' .. 'y'] |> Set.remove 'n' |> Set.map string |> Set.toList) checkResults + dumpErrors checkResults |> shouldEqual [ + "(21,2--21,8): This type test or downcast will always hold" + "(34,6--34,14): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(32,6--32,14): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." + "(30,6--30,14): Incomplete pattern matches on this expression. For example, the value 'false' may indicate a case not covered by the pattern(s)." + "(28,6--28,15): Incomplete pattern matches on this expression. For example, the value 'true' may indicate a case not covered by the pattern(s)." + "(26,6--26,12): Incomplete pattern matches on this expression. For example, the value '0' may indicate a case not covered by the pattern(s)." + "(24,6--24,16): Incomplete pattern matches on this expression. For example, the value '[|_; _|]' may indicate a case not covered by the pattern(s)." + "(22,6--22,14): Incomplete pattern matches on this expression. For example, the value '[_;_]' may indicate a case not covered by the pattern(s)." + "(20,6--20,23): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(18,6--18,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(16,6--16,11): Incomplete pattern matches on this expression." + "(14,6--14,11): Incomplete pattern matches on this expression." + "(12,6--12,11): Incomplete pattern matches on this expression." + "(10,6--10,11): Incomplete pattern matches on this expression." + "(8,6--8,20): Incomplete pattern matches on this expression. For example, the value '[``some-other-subtype``]' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 15 - syntactical precedence matrix testing right with type tests - erroneous patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let (|DefinedPattern|) = id +let :? a as 1 = true +let :? b as true = 2 +let :? c as :? int = box 3 +let :? d as :? int = 4 +let :? e as UndefinedPattern = 5 +let :? f as DefinedPattern () = 6 +let :? g as DefinedPattern = 7 +let :? h as , i = 8 +let :? j as : k = 9 +let :? l as :: m = 10 +let :? n as & o = 11 +let :? p as | q = 12 +let :? r as ( s = 13 +let :? t as ) u = 14 +let :? v as struct w = 15 +let :? x as () = y +let :? z as +""" + dumpErrors checkResults |> shouldEqual [ + "(10,12--10,13): Unexpected symbol ',' in binding" + "(11,12--11,13): Unexpected symbol ':' in binding" + "(12,12--12,14): Unexpected symbol '::' in binding" + "(13,12--13,13): Unexpected symbol '&' in binding" + "(14,12--14,13): Unexpected symbol '|' in binding" + "(15,16--15,17): Unexpected symbol '=' in pattern. Expected ')' or other token." + "(15,12--15,13): Unmatched '('" + "(16,0--16,3): Possible incorrect indentation: this token is offside of context started at position (15:1). Try indenting this token further or using standard formatting conventions." + "(17,19--17,20): Unexpected identifier in pattern. Expected '(' or other token." + "(20,0--20,0): Incomplete structured construct at or before this point in binding" + "(3,7--3,8): The type 'a' is not defined." + "(3,4--3,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(4,7--4,8): The type 'b' is not defined." + "(4,4--4,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(5,7--5,8): The type 'c' is not defined." + "(5,4--5,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(6,7--6,8): The type 'd' is not defined." + "(6,4--6,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(7,7--7,8): The type 'e' is not defined." + "(7,4--7,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(8,7--8,8): The type 'f' is not defined." + "(8,4--8,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(9,7--9,8): The type 'g' is not defined." + "(9,4--9,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(15,7--15,8): The type 'r' is not defined." + "(15,4--15,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(18,7--18,8): The type 'x' is not defined." + "(18,4--18,8): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 16 - syntactical precedence matrix testing left with type tests - total patterns`` () = + let validSet = set { 'a'..'x' } - set [ 'p'; 'q' ] |> Set.map string + let _, checkResults = getParseAndCheckResultsPreview $""" +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Id0|) = ignore +let (|Id1|) = id +let (|Id2|) _ = id +type AAA = {{ aaa : int }} +let a = 1 +match box 2 with +| b as :? int as c -> +match box 3 with +| d as :? int | d & :? int as e -> +match box 4, 5 with +| f as :? int, g as h -> +match box 6 with +| i as :? int & j as k -> +match box 7 with +| Id1 l as :? int as m -> +match box 8 with +| Id2 a n as :? int as o -> +match box 10 with +| _ as :? int as r -> +match box 11 with +| Id0 as :? int as s -> +match box 12 with +| (t) as :? int as u -> +match box struct(13, 14) with +| struct(v, w) as :? struct(int * int) as x -> +Some a |> eq +Some g |> eq +Some h |> eq +{validSet - set [ "a"; "g"; "h" ] |> Set.map (sprintf "Some %s |> eq\n") |> System.String.Concat} +match box {{ aaa = 9 }} with +| {{ aaa = p }} as :? AAA as q -> +Some "" |> eq // No more type checks after the above line? +""" + assertHasSymbolUsages (Set.toList validSet) checkResults + dumpErrors checkResults |> shouldEqual [ + "(27,2--27,14): This expression was expected to have type 'obj' but here has type 'struct ('a * 'b)'" + "(52,2--52,13): This expression was expected to have type 'obj' but here has type 'AAA'" + "(26,6--26,24): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(24,6--24,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(22,6--22,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(20,6--20,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(18,6--18,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(16,6--16,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(14,6--14,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(12,6--12,14): Incomplete pattern matches on this expression. For example, the value '(``some-other-subtype``,_)' may indicate a case not covered by the pattern(s)." + "(10,6--10,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(8,6--8,11): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 17 - syntactical precedence matrix testing left with type tests - partial patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let eq<'T> (x:'T option) = () // FS-1093-safe type assert function +let (|Unit1|_|) x = if System.Random().NextDouble() < 0.5 then Some Unit1 else None +let (|Unit2|_|) _ = (|Unit1|_|) +let (|Id1|_|) x = if System.Random().NextDouble() < 0.5 then Some x else None +let (|Id2|_|) _ = (|Id1|_|) +let a = 1 +match box 2::[box 3] with +| b as :? int as c::d as e -> +match box 4 with +| Unit1 as :? int as f -> +match box 5 with +| Unit2 a g as :? int as h -> +match box 6 with +| Id1 i as :? int as j -> +match box 7 with +| Id2 a k as :? int as l -> +match box 12 with +| 12 as :? int as s -> +match box false with +| false as :? bool as t -> +match box true with +| true as :? bool as u -> +match box null with +| null as :? System.ValueType as v -> +match box null with +| (null) as :? System.ValueType as w -> +let x as y : int = 13 + a + b +Some a |> eq +Some b |> eq +Some c |> eq +Some d |> eq +Some e |> eq +Some f |> eq +Some g |> eq +Some h |> eq +Some i |> eq +Some j |> eq +Some k |> eq +Some l |> eq +Some m |> eq +Some n |> eq +Some o |> eq +Some p |> eq +Some q |> eq +Some r |> eq +Some s |> eq +Some t |> eq +Some u |> eq +Some v |> eq +Some w |> eq +Some x |> eq +Some y |> eq +match box 8 with +| :? int as :? System.ValueType as m -> +match box {| aaa = 9 |} with +| :? {| aaa : int |} as :? obj as n -> +match box [10] with +| [o] as :? (int list) as p -> +match box [|11|] with +| [|q|] as :? (int[]) as r -> +// No more type checking after the above 4 matches +Some "" |> eq +""" + assertHasSymbolUsages (set ['a'..'y'] - set [ 'm'..'r' ] |> Set.map string |> Set.toList) checkResults + dumpErrors checkResults |> shouldEqual [ + "(19,2--19,4): This expression was expected to have type 'obj' but here has type 'int'" + "(21,2--21,7): This expression was expected to have type 'obj' but here has type 'bool'" + "(23,2--23,6): This expression was expected to have type 'obj' but here has type 'bool'" + "(28,28--28,29): The type 'obj' does not match the type 'int'" + "(41,5--41,6): The value or constructor 'm' is not defined." + "(42,5--42,6): The value or constructor 'n' is not defined." + "(43,5--43,6): The value or constructor 'o' is not defined." + "(44,5--44,6): The value or constructor 'p' is not defined." + "(45,5--45,6): The value or constructor 'q' is not defined." + "(46,5--46,6): The value or constructor 'r' is not defined." + "(55,12--55,31): The type 'int' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + "(26,6--26,14): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(24,6--24,14): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(22,6--22,14): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(20,6--20,15): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(18,6--18,12): Incomplete pattern matches on this expression. For example, the value '``some-other-subtype``' may indicate a case not covered by the pattern(s)." + "(16,6--16,11): Incomplete pattern matches on this expression." + "(14,6--14,11): Incomplete pattern matches on this expression." + "(12,6--12,11): Incomplete pattern matches on this expression." + "(10,6--10,11): Incomplete pattern matches on this expression." + "(8,6--8,20): Incomplete pattern matches on this expression. For example, the value '[``some-other-subtype``]' may indicate a case not covered by the pattern(s)." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 18 - syntactical precedence matrix testing left with type tests - erroneous patterns`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +let (|DefinedPattern|) = id +let 1 as :? a = true +let true as :? b = 2 +let :? int as :? c = box 3 +let :? int as :? d = 4 +let UndefinedPattern as :? e = 5 +let DefinedPattern () as :? f = 6 +let DefinedPattern as :? g = 7 +let h, as :? i = 8 +let j : _ as :? k = 9 +let l :: as :? m = 10 +let n & as :? o = 11 +let p | as :? q = 12 +let r struct as :? s = 13 +let t ( as :? u = 14 +let v [ as :? w = 15 +let () as :? x = y +let as :? z = +""" + dumpErrors checkResults |> shouldEqual [ + "(10,7--10,9): Unexpected keyword 'as' in binding" + "(11,10--11,12): Unexpected keyword 'as' in binding. Expected '=' or other token." + "(12,9--12,11): Unexpected keyword 'as' in binding" + "(13,8--13,10): Unexpected keyword 'as' in binding" + "(14,8--14,10): Unexpected keyword 'as' in binding" + "(15,13--15,15): Unexpected keyword 'as' in pattern. Expected '(' or other token." + "(16,8--16,10): Unexpected keyword 'as' in pattern. Expected ')' or other token." + "(16,6--16,7): Unmatched '('" + "(17,0--17,3): Possible incorrect indentation: this token is offside of context started at position (16:1). Try indenting this token further or using standard formatting conventions." + "(17,0--17,3): Unexpected keyword 'let' or 'use' in binding. Expected incomplete structured construct at or before this point or other token." + "(16,0--16,3): Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword." + "(17,8--17,10): Unexpected keyword 'as' in pattern. Expected ']' or other token." + "(18,0--18,3): Possible incorrect indentation: this token is offside of context started at position (17:1). Try indenting this token further or using standard formatting conventions." + "(19,0--19,3): Possible incorrect indentation: this token is offside of context started at position (18:1). Try indenting this token further or using standard formatting conventions." + "(20,0--20,0): Possible incorrect indentation: this token is offside of context started at position (19:1). Try indenting this token further or using standard formatting conventions." + "(20,0--20,0): Possible incorrect indentation: this token is offside of context started at position (19:1). Try indenting this token further or using standard formatting conventions." + "(3,12--3,13): The type 'a' is not defined." + "(3,9--3,13): The type 'int' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + "(4,15--4,16): The type 'b' is not defined." + "(4,12--4,16): The type 'bool' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + "(5,4--5,10): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(6,4--6,10): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(7,27--7,28): The type 'e' is not defined." + "(7,24--7,28): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + "(8,28--8,29): The type 'f' is not defined." + "(8,25--8,29): The type 'unit' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + "(9,25--9,26): The type 'g' is not defined." + "(9,22--9,26): The type 'unit' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion." + "(16,4--16,5): The pattern discriminator 't' is not defined." + "(16,14--16,15): The type 'u' is not defined." + "(16,11--16,15): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed." + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 19 - syntactical precedence matrix testing - valid syntactic patterns that cause type errors later`` () = + let _, checkResults = getParseAndCheckResultsPreview """ +type I() = inherit System.Attribute() +type M() = inherit I() +let 'a'..'b' as c = 'd' +let e as 'f'..'g' = 'h' +let [] j as k = 1 +let l as [] n = 2 +let <@ o @> as p = 3 +let q as <@ r @> = 4 +let <@@ s @@> as t = 5 +let u as <@@ v @@> = 6 +let ?w as x = 7 +let y as ?z = 8 +() +""" + dumpErrors checkResults |> shouldEqual [ + "(7,9--7,11): Unexpected symbol '[<' in binding" + "(4,4--4,12): This construct is deprecated: Character range matches have been removed in F#. Consider using a 'when' pattern guard instead." + "(4,4--4,17): Incomplete pattern matches on this expression. For example, the value '' '' may indicate a case not covered by the pattern(s)." + "(5,9--5,17): This construct is deprecated: Character range matches have been removed in F#. Consider using a 'when' pattern guard instead." + "(5,4--5,17): Incomplete pattern matches on this expression. For example, the value '' '' may indicate a case not covered by the pattern(s)." + "(8,4--8,11): This is not a valid pattern" + "(8,4--8,16): Incomplete pattern matches on this expression." + "(9,9--9,16): This is not a valid pattern" + "(9,4--9,16): Incomplete pattern matches on this expression." + "(10,4--10,13): This is not a valid pattern" + "(10,4--10,18): Incomplete pattern matches on this expression." + "(11,9--11,18): This is not a valid pattern" + "(11,4--11,18): Incomplete pattern matches on this expression." + "(12,4--12,6): Optional arguments are only permitted on type members" + "(13,9--13,11): Optional arguments are only permitted on type members" + ] + +[] +#if !NETCOREAPP +[] +#endif +let ``As 20 - limit the right of 'as' patterns to only variable patterns in F# 5`` () = + let _, checkResults = getParseAndCheckResults """ +let f : obj -> _ = + function + | :? int as i -> i + | :? uint as _ -> 0 + | a as :? int64 -> -1 +() +""" + assertHasSymbolUsages ["i"] checkResults + dumpErrors checkResults |> shouldEqual [ + "(5,6--5,18): Feature 'non-variable patterns to the right of 'as' patterns' is not available in F# 5.0. Please use language version 'preview' or greater." + ] \ No newline at end of file diff --git a/tests/service/PerfTests.fs b/tests/service/PerfTests.fs index ffffa412a36..cb0852f941e 100644 --- a/tests/service/PerfTests.fs +++ b/tests/service/PerfTests.fs @@ -11,45 +11,47 @@ module FSharp.Compiler.Service.Tests.PerfTests open NUnit.Framework open FsUnit open System.IO - -open FSharp.Compiler.SourceCodeServices - +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO +open FSharp.Compiler.Text open FSharp.Compiler.Service.Tests.Common +open TestFramework -// Create an interactive checker instance +// Create an interactive checker instance let internal checker = FSharpChecker.Create() -module internal Project1 = +module internal Project1 = - let fileNamesI = [ for i in 1 .. 10 -> (i, Path.ChangeExtension(Path.GetTempFileName(), ".fs")) ] - let base2 = Path.GetTempFileName() + let fileNamesI = [ for i in 1 .. 10 -> (i, Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs")) ] + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") - let fileSources = [ for (i,f) in fileNamesI -> (f, "module M" + string i) ] - for (f,text) in fileSources do File.WriteAllText(f, text) - let fileSources2 = [ for (i,f) in fileSources -> FSharp.Compiler.Text.SourceText.ofString f ] + let fileSources = [ for i,f in fileNamesI -> (f, "module M" + string i) ] + for f,text in fileSources do FileSystem.OpenFileForWriteShim(f).Write(text) + let fileSources2 = [ for i,f in fileSources -> SourceText.ofString f ] - let fileNames = [ for (_,f) in fileNamesI -> f ] + let fileNames = [ for _,f in fileNamesI -> f ] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let parsingOptions, _ = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) [] -let ``Test request for parse and check doesn't check whole project`` () = +[] +let ``Test request for parse and check doesn't check whole project`` () = printfn "starting test..." - let backgroundParseCount = ref 0 - let backgroundCheckCount = ref 0 + let backgroundParseCount = ref 0 + let backgroundCheckCount = ref 0 checker.FileChecked.Add (fun x -> incr backgroundCheckCount) checker.FileParsed.Add (fun x -> incr backgroundParseCount) checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - let pB, tB = FSharpChecker.GlobalForegroundParseCountStatistic, FSharpChecker.GlobalForegroundTypeCheckCountStatistic + let pB, tB = FSharpChecker.ActualParseFileCount, FSharpChecker.ActualCheckFileCount printfn "ParseFile()..." - let parseResults1 = checker.ParseFile(Project1.fileNames.[5], Project1.fileSources2.[5], Project1.parsingOptions) |> Async.RunSynchronously - let pC, tC = FSharpChecker.GlobalForegroundParseCountStatistic, FSharpChecker.GlobalForegroundTypeCheckCountStatistic + let parseResults1 = checker.ParseFile(Project1.fileNames.[5], Project1.fileSources2.[5], Project1.parsingOptions) |> Async.RunImmediate + let pC, tC = FSharpChecker.ActualParseFileCount, FSharpChecker.ActualCheckFileCount (pC - pB) |> shouldEqual 1 (tC - tB) |> shouldEqual 0 printfn "checking backgroundParseCount.Value = %d" backgroundParseCount.Value @@ -58,8 +60,8 @@ let ``Test request for parse and check doesn't check whole project`` () = backgroundCheckCount.Value |> shouldEqual 0 printfn "CheckFileInProject()..." - let checkResults1 = checker.CheckFileInProject(parseResults1, Project1.fileNames.[5], 0, Project1.fileSources2.[5], Project1.options) |> Async.RunSynchronously - let pD, tD = FSharpChecker.GlobalForegroundParseCountStatistic, FSharpChecker.GlobalForegroundTypeCheckCountStatistic + let checkResults1 = checker.CheckFileInProject(parseResults1, Project1.fileNames.[5], 0, Project1.fileSources2.[5], Project1.options) |> Async.RunImmediate + let pD, tD = FSharpChecker.ActualParseFileCount, FSharpChecker.ActualCheckFileCount printfn "checking background parsing happened...., backgroundParseCount.Value = %d" backgroundParseCount.Value (backgroundParseCount.Value >= 5) |> shouldEqual true // but note, the project does not get reparsed @@ -77,8 +79,8 @@ let ``Test request for parse and check doesn't check whole project`` () = (tD - tC) |> shouldEqual 1 printfn "CheckFileInProject()..." - let checkResults2 = checker.CheckFileInProject(parseResults1, Project1.fileNames.[7], 0, Project1.fileSources2.[7], Project1.options) |> Async.RunSynchronously - let pE, tE = FSharpChecker.GlobalForegroundParseCountStatistic, FSharpChecker.GlobalForegroundTypeCheckCountStatistic + let checkResults2 = checker.CheckFileInProject(parseResults1, Project1.fileNames.[7], 0, Project1.fileSources2.[7], Project1.options) |> Async.RunImmediate + let pE, tE = FSharpChecker.ActualParseFileCount, FSharpChecker.ActualCheckFileCount printfn "checking no extra foreground parsing...., (pE - pD) = %d" (pE - pD) (pE - pD) |> shouldEqual 0 printfn "checking one foreground typecheck...., tE - tD = %d" (tE - tD) @@ -90,8 +92,8 @@ let ``Test request for parse and check doesn't check whole project`` () = printfn "ParseAndCheckFileInProject()..." // A subsequent ParseAndCheck of identical source code doesn't do any more anything - let checkResults2 = checker.ParseAndCheckFileInProject(Project1.fileNames.[7], 0, Project1.fileSources2.[7], Project1.options) |> Async.RunSynchronously - let pF, tF = FSharpChecker.GlobalForegroundParseCountStatistic, FSharpChecker.GlobalForegroundTypeCheckCountStatistic + let checkResults2 = checker.ParseAndCheckFileInProject(Project1.fileNames.[7], 0, Project1.fileSources2.[7], Project1.options) |> Async.RunImmediate + let pF, tF = FSharpChecker.ActualParseFileCount, FSharpChecker.ActualCheckFileCount printfn "checking no extra foreground parsing...." (pF - pE) |> shouldEqual 0 // note, no new parse of the file printfn "checking no extra foreground typechecks...." @@ -101,4 +103,3 @@ let ``Test request for parse and check doesn't check whole project`` () = printfn "checking no extra background typechecks...., backgroundCheckCount.Value = %d" backgroundCheckCount.Value (backgroundCheckCount.Value <= 10) |> shouldEqual true // only two extra typechecks of files () - diff --git a/tests/service/Program.fs b/tests/service/Program.fs index c94e2a49931..b40faa11800 100644 --- a/tests/service/Program.fs +++ b/tests/service/Program.fs @@ -1,5 +1,4 @@ -open System - + [] let main argv = printfn "Dotnet Core NUnit Tests..." diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index bce8dd133c2..6f3c81e62be 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -13,23 +13,27 @@ open NUnit.Framework open FsUnit open System open System.IO - -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices - +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.IO +open FSharp.Compiler.Text open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open FSharp.Compiler.Symbols.FSharpExprPatterns +open TestFramework -module internal Project1 = +module internal Project1 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let fileName2 = Path.ChangeExtension(base2, ".fs") let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ module M -type C() = +type C() = member x.P = 1 let xxx = 3 + 4 @@ -37,25 +41,25 @@ let fff () = xxx + xxx type CAbbrev = C """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileSource2Text = """ module N open M -type D1() = +type D1() = member x.SomeProperty = M.xxx -type D2() = +type D2() = member x.SomeProperty = M.fff() + D1().P // Generate a warning let y2 = match 1 with 1 -> M.xxx // A class with some 'let' bindings -type D3(a:int) = +type D3(a:int) = let b = a + 4 [] @@ -66,14 +70,14 @@ type D3(a:int) = let pair1,pair2 = (3 + 4 + int32 System.DateTime.Now.Ticks, 5 + 6) // Check enum values -type SaveOptions = +type SaveOptions = | None = 0 | DisableFormatting = 1 let enumValue = SaveOptions.DisableFormatting let (++) x y = x + y - + let c1 = 1 ++ 2 let c2 = 1 ++ 2 @@ -82,8 +86,8 @@ let mmmm1 : M.C = new M.C() // note, these don't count as uses of CA let mmmm2 : M.CAbbrev = new M.CAbbrev() // note, these don't count as uses of C """ - let fileSource2 = FSharp.Compiler.Text.SourceText.ofString fileSource2Text - File.WriteAllText(fileName2, fileSource2Text) + let fileSource2 = SourceText.ofString fileSource2Text + FileSystem.OpenFileForWriteShim(fileName2).Write(fileSource2Text) let fileNames = [fileName1; fileName2] let args = mkProjectCommandLineArgs (dllName, fileNames) @@ -92,23 +96,23 @@ let mmmm2 : M.CAbbrev = new M.CAbbrev() // note, these don't count as uses of C let cleanFileName a = if a = fileName1 then "file1" else if a = fileName2 then "file2" else "??" [] -let ``Test project1 whole project errors`` () = +let ``Test project1 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - wholeProjectResults .Errors.Length |> shouldEqual 2 - wholeProjectResults.Errors.[1].Message.Contains("Incomplete pattern matches on this expression") |> shouldEqual true // yes it does - wholeProjectResults.Errors.[1].ErrorNumber |> shouldEqual 25 + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + wholeProjectResults .Diagnostics.Length |> shouldEqual 2 + wholeProjectResults.Diagnostics.[1].Message.Contains("Incomplete pattern matches on this expression") |> shouldEqual true // yes it does + wholeProjectResults.Diagnostics.[1].ErrorNumber |> shouldEqual 25 - wholeProjectResults.Errors.[0].StartLineAlternate |> shouldEqual 10 - wholeProjectResults.Errors.[0].EndLineAlternate |> shouldEqual 10 - wholeProjectResults.Errors.[0].StartColumn |> shouldEqual 43 - wholeProjectResults.Errors.[0].EndColumn |> shouldEqual 44 + wholeProjectResults.Diagnostics.[0].Range.StartLine |> shouldEqual 10 + wholeProjectResults.Diagnostics.[0].Range.EndLine |> shouldEqual 10 + wholeProjectResults.Diagnostics.[0].Range.StartColumn |> shouldEqual 43 + wholeProjectResults.Diagnostics.[0].Range.EndColumn |> shouldEqual 44 [] -let ``Test project1 and make sure TcImports gets cleaned up`` () = +let ``Test project1 and make sure TcImports gets cleaned up`` () = let test () = - let (_, checkFileAnswer) = checker.ParseAndCheckFileInProject(Project1.fileName1, 0, Project1.fileSource1, Project1.options) |> Async.RunSynchronously + let _, checkFileAnswer = checker.ParseAndCheckFileInProject(Project1.fileName1, 0, Project1.fileSource1, Project1.options) |> Async.RunImmediate match checkFileAnswer with | FSharpCheckFileAnswer.Aborted -> failwith "should not be aborted" | FSharpCheckFileAnswer.Succeeded checkFileResults -> @@ -117,17 +121,18 @@ let ``Test project1 and make sure TcImports gets cleaned up`` () = let weakTcImports = WeakReference tcImportsOpt.Value Assert.True weakTcImports.IsAlive weakTcImports - + + // Here we are only keeping a handle to weakTcImports and nothing else let weakTcImports = test () - checker.InvalidateConfiguration (Project1.options) + checker.InvalidateConfiguration Project1.options checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() GC.Collect(2, GCCollectionMode.Forced, blocking = true) Assert.False weakTcImports.IsAlive [] let ``Test Project1 should have protected FullName and TryFullName return same results`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - let rec getFullNameComparisons (entity: FSharpEntity) = + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + let rec getFullNameComparisons (entity: FSharpEntity) = #if !NO_EXTENSIONTYPING seq { if not entity.IsProvided && entity.Accessibility.IsPublic then #else @@ -136,7 +141,7 @@ let ``Test Project1 should have protected FullName and TryFullName return same r yield (entity.TryFullName = try Some entity.FullName with _ -> None) for e in entity.NestedEntities do yield! getFullNameComparisons e } - + wholeProjectResults.ProjectContext.GetReferencedAssemblies() |> List.map (fun asm -> asm.Contents.Entities) |> Seq.collect (Seq.collect getFullNameComparisons) @@ -145,7 +150,7 @@ let ``Test Project1 should have protected FullName and TryFullName return same r [] [] let ``Test project1 should not throw exceptions on entities from referenced assemblies`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate let rec getAllBaseTypes (entity: FSharpEntity) = seq { if not entity.IsProvided && entity.Accessibility.IsPublic then if not entity.IsUnresolved then yield entity.BaseType @@ -159,10 +164,10 @@ let ``Test project1 should not throw exceptions on entities from referenced asse Assert.DoesNotThrow(fun () -> Seq.iter (fun _ -> ()) allBaseTypes) [] -let ``Test project1 basic`` () = +let ``Test project1 basic`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate set [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual (set ["N"; "M"]) @@ -170,27 +175,27 @@ let ``Test project1 basic`` () = [ for x in wholeProjectResults.AssemblySignature.Entities.[1].NestedEntities -> x.DisplayName ] |> shouldEqual ["C"; "CAbbrev"] - set [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] - |> shouldEqual (set ["y2"; "pair2"; "pair1"; "( ++ )"; "c1"; "c2"; "mmmm1"; "mmmm2"; "enumValue" ]) + set [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + |> shouldEqual (set ["y2"; "pair2"; "pair1"; "(++)"; "c1"; "c2"; "mmmm1"; "mmmm2"; "enumValue" ]) [] -let ``Test project1 all symbols`` () = +let ``Test project1 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities - for s in allSymbols do + for s in allSymbols do s.DeclarationLocation.IsSome |> shouldEqual true - for s in allSymbols do - match s with - | :? FSharpMemberOrFunctionOrValue as v when v.IsModuleValueOrMember -> + for s in allSymbols do + match s with + | :? FSharpMemberOrFunctionOrValue as v when v.IsModuleValueOrMember -> s.IsAccessible(wholeProjectResults.ProjectContext.AccessibilityRights) |> shouldEqual true - | :? FSharpEntity -> + | :? FSharpEntity -> s.IsAccessible(wholeProjectResults.ProjectContext.AccessibilityRights) |> shouldEqual true | _ -> () - let allDeclarationLocations = - [ for s in allSymbols do + let allDeclarationLocations = + [ for s in allSymbols do let m = s.DeclarationLocation.Value yield s.ToString(), Project1.cleanFileName m.FileName, (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn ), attribsOfSymbol s ] @@ -237,11 +242,11 @@ let ``Test project1 all symbols`` () = ("CAbbrev", "file1", (10, 5), (10, 12), ["abbrev"]); ("property P", "file1", (5, 13), (5, 14), ["member"; "prop"])] - for s in allSymbols do + for s in allSymbols do s.ImplementationLocation.IsSome |> shouldEqual true - let allImplementationLocations = - [ for s in allSymbols do + let allImplementationLocations = + [ for s in allSymbols do let m = s.ImplementationLocation.Value yield s.ToString(), Project1.cleanFileName m.FileName, (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn ), attribsOfSymbol s ] @@ -288,8 +293,8 @@ let ``Test project1 all symbols`` () = ("CAbbrev", "file1", (10, 5), (10, 12), ["abbrev"]); ("property P", "file1", (5, 13), (5, 14), ["member"; "prop"])] - [ for x in allSymbols -> x.ToString() ] - |> shouldEqual + [ for x in allSymbols -> x.ToString() ] + |> shouldEqual ["N"; "val y2"; "val pair2"; "val pair1"; "val enumValue"; "val op_PlusPlus"; "val c1"; "val c2"; "val mmmm1"; "val mmmm2"; "D1"; "member .ctor"; "member get_SomeProperty"; "property SomeProperty"; "D2"; "member .ctor"; @@ -300,12 +305,12 @@ let ``Test project1 all symbols`` () = "member get_P"; "property P"; "CAbbrev"; "property P"] [] -let ``Test project1 all symbols excluding compiler generated`` () = +let ``Test project1 all symbols excluding compiler generated`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate let allSymbolsNoCompGen = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbolsNoCompGen -> x.ToString() ] - |> shouldEqual + [ for x in allSymbolsNoCompGen -> x.ToString() ] + |> shouldEqual ["N"; "val y2"; "val pair2"; "val pair1"; "val enumValue"; "val op_PlusPlus"; "val c1"; "val c2"; "val mmmm1"; "val mmmm2"; "D1"; "member .ctor"; "member get_SomeProperty"; "property SomeProperty"; "D2"; "member .ctor"; @@ -316,22 +321,22 @@ let ``Test project1 all symbols excluding compiler generated`` () = "property P"] [] -let ``Test project1 xxx symbols`` () = +let ``Test project1 xxx symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project1.fileName1, Project1.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project1.fileName1, Project1.options) + |> Async.RunImmediate - let xSymbolUseOpt = backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) |> Async.RunSynchronously + let xSymbolUseOpt = backgroundTypedParse1.GetSymbolUseAtLocation(9,9,"",["xxx"]) let xSymbolUse = xSymbolUseOpt.Value let xSymbol = xSymbolUse.Symbol xSymbol.ToString() |> shouldEqual "val xxx" - let usesOfXSymbol = - [ for su in wholeProjectResults.GetUsesOfSymbol(xSymbol) |> Async.RunSynchronously do - yield Project1.cleanFileName su.FileName , tups su.RangeAlternate, attribsOfSymbol su.Symbol ] + let usesOfXSymbol = + [ for su in wholeProjectResults.GetUsesOfSymbol(xSymbol) do + yield Project1.cleanFileName su.FileName , tups su.Range, attribsOfSymbol su.Symbol ] usesOfXSymbol |> shouldEqual [("file1", ((7, 4), (7, 7)), ["val"]); @@ -341,16 +346,16 @@ let ``Test project1 xxx symbols`` () = ("file2", ((13, 27), (13, 32)), ["val"])] [] -let ``Test project1 all uses of all signature symbols`` () = +let ``Test project1 all uses of all signature symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities - let allUsesOfAllSymbols = - [ for s in allSymbols do - yield s.ToString(), - [ for s in wholeProjectResults.GetUsesOfSymbol(s) |> Async.RunSynchronously -> - (Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate) ] ] - let expected = + let allUsesOfAllSymbols = + [ for s in allSymbols do + yield s.ToString(), + [ for s in wholeProjectResults.GetUsesOfSymbol(s) -> + (Project1.cleanFileName s.FileName, tupsZ s.Range) ] ] + let expected = [("N", [("file2", ((1, 7), (1, 8)))]); ("val y2", [("file2", ((12, 4), (12, 6)))]); ("val pair2", [("file2", ((23, 10), (23, 15)))]); @@ -409,22 +414,22 @@ let ``Test project1 all uses of all signature symbols`` () = (set expected = set allUsesOfAllSymbols) |> shouldEqual true [] -let ``Test project1 all uses of all symbols`` () = +let ``Test project1 all uses of all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - let allUsesOfAllSymbols = - [ for s in wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously -> - s.Symbol.DisplayName, s.Symbol.FullName, Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate, attribsOfSymbol s.Symbol ] - let expected = + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + let allUsesOfAllSymbols = + [ for s in wholeProjectResults.GetAllUsesOfAllSymbols() -> + s.Symbol.DisplayName, s.Symbol.FullName, Project1.cleanFileName s.FileName, tupsZ s.Range, attribsOfSymbol s.Symbol ] + let expected = [("C", "M.C", "file1", ((3, 5), (3, 6)), ["class"]); - ("( .ctor )", "M.C.( .ctor )", "file1", ((3, 5), (3, 6)), + ("``.ctor``", "M.C.``.ctor``", "file1", ((3, 5), (3, 6)), ["member"; "ctor"]); ("P", "M.C.P", "file1", ((4, 13), (4, 14)), ["member"; "getter"]); ("x", "x", "file1", ((4, 11), (4, 12)), []); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file1", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file1", ((6, 12), (6, 13)), ["val"]); ("xxx", "M.xxx", "file1", ((6, 4), (6, 7)), ["val"]); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file1", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file1", ((7, 17), (7, 18)), ["val"]); ("xxx", "M.xxx", "file1", ((7, 13), (7, 16)), ["val"]); ("xxx", "M.xxx", "file1", ((7, 19), (7, 22)), ["val"]); @@ -437,18 +442,18 @@ let ``Test project1 all uses of all symbols`` () = ("M", "M", "file1", ((1, 7), (1, 8)), ["module"]); ("M", "M", "file2", ((3, 5), (3, 6)), ["module"]); ("D1", "N.D1", "file2", ((5, 5), (5, 7)), ["class"]); - ("( .ctor )", "N.D1.( .ctor )", "file2", ((5, 5), (5, 7)), + ("``.ctor``", "N.D1.``.ctor``", "file2", ((5, 5), (5, 7)), ["member"; "ctor"]); ("SomeProperty", "N.D1.SomeProperty", "file2", ((6, 13), (6, 25)), ["member"; "getter"]); ("x", "x", "file2", ((6, 11), (6, 12)), []); ("M", "M", "file2", ((6, 28), (6, 29)), ["module"]); ("xxx", "M.xxx", "file2", ((6, 28), (6, 33)), ["val"]); ("D2", "N.D2", "file2", ((8, 5), (8, 7)), ["class"]); - ("( .ctor )", "N.D2.( .ctor )", "file2", ((8, 5), (8, 7)), + ("``.ctor``", "N.D2.``.ctor``", "file2", ((8, 5), (8, 7)), ["member"; "ctor"]); ("SomeProperty", "N.D2.SomeProperty", "file2", ((9, 13), (9, 25)), ["member"; "getter"]); ("x", "x", "file2", ((9, 11), (9, 12)), []); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((9, 36), (9, 37)), ["val"]); ("M", "M", "file2", ((9, 28), (9, 29)), ["module"]); ("fff", "M.fff", "file2", ((9, 28), (9, 33)), ["val"]); @@ -475,22 +480,22 @@ let ``Test project1 all uses of all symbols`` () = ("D3", "N.D3", "file2", ((15, 5), (15, 7)), ["class"]); ("int", "Microsoft.FSharp.Core.int", "file2", ((15, 10), (15, 13)), ["abbrev"]); ("a", "a", "file2", ((15, 8), (15, 9)), []); - ("( .ctor )", "N.D3.( .ctor )", "file2", ((15, 5), (15, 7)), + ("``.ctor``", "N.D3.``.ctor``", "file2", ((15, 5), (15, 7)), ["member"; "ctor"]); ("SomeProperty", "N.D3.SomeProperty", "file2", ((21, 13), (21, 25)), ["member"; "getter"]); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((16, 14), (16, 15)), ["val"]); ("a", "a", "file2", ((16, 12), (16, 13)), []); ("b", "b", "file2", ((16, 8), (16, 9)), []); ("x", "x", "file2", ((21, 11), (21, 12)), []); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((21, 30), (21, 31)), ["val"]); ("a", "a", "file2", ((21, 28), (21, 29)), []); ("b", "b", "file2", ((21, 32), (21, 33)), []); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((23, 25), (23, 26)), ["val"]); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((23, 21), (23, 22)), ["val"]); ("int32", "Microsoft.FSharp.Core.Operators.int32", "file2", ((23, 27), (23, 32)), ["val"]); @@ -501,7 +506,7 @@ let ``Test project1 all uses of all symbols`` () = ["member"; "prop"]); ("Ticks", "System.DateTime.Ticks", "file2", ((23, 33), (23, 58)), ["member"; "prop"]); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((23, 62), (23, 63)), ["val"]); ("pair2", "N.pair2", "file2", ((23, 10), (23, 15)), ["val"]); ("pair1", "N.pair1", "file2", ((23, 4), (23, 9)), ["val"]); @@ -518,14 +523,14 @@ let ``Test project1 all uses of all symbols`` () = ("enumValue", "N.enumValue", "file2", ((30, 4), (30, 13)), ["val"]); ("x", "x", "file2", ((32, 9), (32, 10)), []); ("y", "y", "file2", ((32, 11), (32, 12)), []); - ("( + )", "Microsoft.FSharp.Core.Operators.( + )", "file2", + ("(+)", "Microsoft.FSharp.Core.Operators.(+)", "file2", ((32, 17), (32, 18)), ["val"]); ("x", "x", "file2", ((32, 15), (32, 16)), []); ("y", "y", "file2", ((32, 19), (32, 20)), []); - ("( ++ )", "N.( ++ )", "file2", ((32, 5), (32, 7)), ["val"]); - ("( ++ )", "N.( ++ )", "file2", ((34, 11), (34, 13)), ["val"]); + ("(++)", "N.(++)", "file2", ((32, 5), (32, 7)), ["val"]); + ("(++)", "N.(++)", "file2", ((34, 11), (34, 13)), ["val"]); ("c1", "N.c1", "file2", ((34, 4), (34, 6)), ["val"]); - ("( ++ )", "N.( ++ )", "file2", ((36, 11), (36, 13)), ["val"]); + ("(++)", "N.(++)", "file2", ((36, 11), (36, 13)), ["val"]); ("c2", "N.c2", "file2", ((36, 4), (36, 6)), ["val"]); ("M", "M", "file2", ((38, 12), (38, 13)), ["module"]); ("C", "M.C", "file2", ((38, 12), (38, 15)), ["class"]); @@ -547,33 +552,33 @@ let ``Test project1 all uses of all symbols`` () = #if !NO_EXTENSIONTYPING [] -let ``Test file explicit parse symbols`` () = +let ``Test file explicit parse symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - let parseResults1 = checker.ParseFile(Project1.fileName1, Project1.fileSource1, Project1.parsingOptions) |> Async.RunSynchronously - let parseResults2 = checker.ParseFile(Project1.fileName2, Project1.fileSource2, Project1.parsingOptions) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + let parseResults1 = checker.ParseFile(Project1.fileName1, Project1.fileSource1, Project1.parsingOptions) |> Async.RunImmediate + let parseResults2 = checker.ParseFile(Project1.fileName2, Project1.fileSource2, Project1.parsingOptions) |> Async.RunImmediate - let checkResults1 = - checker.CheckFileInProject(parseResults1, Project1.fileName1, 0, Project1.fileSource1, Project1.options) - |> Async.RunSynchronously + let checkResults1 = + checker.CheckFileInProject(parseResults1, Project1.fileName1, 0, Project1.fileSource1, Project1.options) + |> Async.RunImmediate |> function FSharpCheckFileAnswer.Succeeded x -> x | _ -> failwith "unexpected aborted" - let checkResults2 = + let checkResults2 = checker.CheckFileInProject(parseResults2, Project1.fileName2, 0, Project1.fileSource2, Project1.options) - |> Async.RunSynchronously + |> Async.RunImmediate |> function FSharpCheckFileAnswer.Succeeded x -> x | _ -> failwith "unexpected aborted" - let xSymbolUse2Opt = checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) |> Async.RunSynchronously + let xSymbolUse2Opt = checkResults1.GetSymbolUseAtLocation(9,9,"",["xxx"]) let xSymbol2 = xSymbolUse2Opt.Value.Symbol - let usesOfXSymbol2 = - [| for s in wholeProjectResults.GetUsesOfSymbol(xSymbol2) |> Async.RunSynchronously -> (Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate) |] + let usesOfXSymbol2 = + [| for s in wholeProjectResults.GetUsesOfSymbol(xSymbol2) -> (Project1.cleanFileName s.FileName, tupsZ s.Range) |] - let usesOfXSymbol21 = - [| for s in checkResults1.GetUsesOfSymbolInFile(xSymbol2) |> Async.RunSynchronously -> (Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate) |] + let usesOfXSymbol21 = + [| for s in checkResults1.GetUsesOfSymbolInFile(xSymbol2) -> (Project1.cleanFileName s.FileName, tupsZ s.Range) |] - let usesOfXSymbol22 = - [| for s in checkResults2.GetUsesOfSymbolInFile(xSymbol2) |> Async.RunSynchronously -> (Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate) |] + let usesOfXSymbol22 = + [| for s in checkResults2.GetUsesOfSymbolInFile(xSymbol2) -> (Project1.cleanFileName s.FileName, tupsZ s.Range) |] usesOfXSymbol2 |> shouldEqual [|("file1", ((6, 4), (6, 7))); @@ -593,36 +598,36 @@ let ``Test file explicit parse symbols`` () = [] -let ``Test file explicit parse all symbols`` () = +let ``Test file explicit parse all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously - let parseResults1 = checker.ParseFile(Project1.fileName1, Project1.fileSource1, Project1.parsingOptions) |> Async.RunSynchronously - let parseResults2 = checker.ParseFile(Project1.fileName2, Project1.fileSource2, Project1.parsingOptions) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunImmediate + let parseResults1 = checker.ParseFile(Project1.fileName1, Project1.fileSource1, Project1.parsingOptions) |> Async.RunImmediate + let parseResults2 = checker.ParseFile(Project1.fileName2, Project1.fileSource2, Project1.parsingOptions) |> Async.RunImmediate - let checkResults1 = - checker.CheckFileInProject(parseResults1, Project1.fileName1, 0, Project1.fileSource1, Project1.options) - |> Async.RunSynchronously + let checkResults1 = + checker.CheckFileInProject(parseResults1, Project1.fileName1, 0, Project1.fileSource1, Project1.options) + |> Async.RunImmediate |> function FSharpCheckFileAnswer.Succeeded x -> x | _ -> failwith "unexpected aborted" - let checkResults2 = + let checkResults2 = checker.CheckFileInProject(parseResults2, Project1.fileName2, 0, Project1.fileSource2, Project1.options) - |> Async.RunSynchronously + |> Async.RunImmediate |> function FSharpCheckFileAnswer.Succeeded x -> x | _ -> failwith "unexpected aborted" - let usesOfSymbols = checkResults1.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously - let cleanedUsesOfSymbols = - [ for s in usesOfSymbols -> s.Symbol.DisplayName, Project1.cleanFileName s.FileName, tupsZ s.RangeAlternate, attribsOfSymbol s.Symbol ] + let usesOfSymbols = checkResults1.GetAllUsesOfAllSymbolsInFile() + let cleanedUsesOfSymbols = + [ for s in usesOfSymbols -> s.Symbol.DisplayName, Project1.cleanFileName s.FileName, tupsZ s.Range, attribsOfSymbol s.Symbol ] - cleanedUsesOfSymbols - |> shouldEqual + cleanedUsesOfSymbols + |> shouldEqual [("C", "file1", ((3, 5), (3, 6)), ["class"]); - ("( .ctor )", "file1", ((3, 5), (3, 6)), ["member"; "ctor"]); + ("``.ctor``", "file1", ((3, 5), (3, 6)), ["member"; "ctor"]); ("P", "file1", ((4, 13), (4, 14)), ["member"; "getter"]); ("x", "file1", ((4, 11), (4, 12)), []); - ("( + )", "file1", ((6, 12), (6, 13)), ["val"]); + ("(+)", "file1", ((6, 12), (6, 13)), ["val"]); ("xxx", "file1", ((6, 4), (6, 7)), ["val"]); - ("( + )", "file1", ((7, 17), (7, 18)), ["val"]); + ("(+)", "file1", ((7, 17), (7, 18)), ["val"]); ("xxx", "file1", ((7, 13), (7, 16)), ["val"]); ("xxx", "file1", ((7, 19), (7, 22)), ["val"]); ("fff", "file1", ((7, 4), (7, 7)), ["val"]); @@ -636,16 +641,16 @@ let ``Test file explicit parse all symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project2 = +module internal Project2 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module M -type DUWithNormalFields = +type DUWithNormalFields = | DU1 of int * int | DU2 of int * int | D of int * int @@ -658,7 +663,7 @@ type DUWithNamedFields = DU of x : int * y : int let _ = DU(x=1, y=2) -type GenericClass<'T>() = +type GenericClass<'T>() = member x.GenericMethod<'U>(t: 'T, u: 'U) = 1 let c = GenericClass() @@ -668,7 +673,7 @@ let GenericFunction (x:'T, y: 'T) = (x,y) : ('T * 'T) let _ = GenericFunction(3, 4) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) @@ -678,32 +683,32 @@ let _ = GenericFunction(3, 4) [] -let ``Test project2 whole project errors`` () = +let ``Test project2 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunSynchronously - wholeProjectResults .Errors.Length |> shouldEqual 0 + let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunImmediate + wholeProjectResults .Diagnostics.Length |> shouldEqual 0 [] -let ``Test project2 basic`` () = +let ``Test project2 basic`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunImmediate set [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual (set ["M"]) [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual ["DUWithNormalFields"; "DUWithNamedFields"; "GenericClass" ] - set [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + set [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual (set ["c"; "GenericFunction"]) [] -let ``Test project2 all symbols in signature`` () = +let ``Test project2 all symbols in signature`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbols -> x.ToString() ] - |> shouldEqual + [ for x in allSymbols -> x.ToString() ] + |> shouldEqual ["M"; "val c"; "val GenericFunction"; "generic parameter T"; "DUWithNormalFields"; "DU1"; "field Item1"; "field Item2"; "DU2"; "field Item1"; "field Item2"; "D"; "field Item1"; "field Item2"; @@ -712,14 +717,14 @@ let ``Test project2 all symbols in signature`` () = "generic parameter U"] [] -let ``Test project2 all uses of all signature symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunSynchronously +let ``Test project2 all uses of all signature symbols`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities - let allUsesOfAllSymbols = - [ for s in allSymbols do - let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) |> Async.RunSynchronously -> (if s.FileName = Project2.fileName1 then "file1" else "??"), tupsZ s.RangeAlternate ] + let allUsesOfAllSymbols = + [ for s in allSymbols do + let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) -> (if s.FileName = Project2.fileName1 then "file1" else "??"), tupsZ s.Range ] yield s.ToString(), uses ] - let expected = + let expected = [("M", [("file1", ((1, 7), (1, 8)))]); ("val c", [("file1", ((19, 4), (19, 5))); ("file1", ((20, 8), (20, 9)))]); ("val GenericFunction", @@ -729,22 +734,13 @@ let ``Test project2 all uses of all signature symbols`` () = ("file1", ((22, 45), (22, 47))); ("file1", ((22, 50), (22, 52)))]); ("DUWithNormalFields", [("file1", ((3, 5), (3, 23)))]); ("DU1", [("file1", ((4, 6), (4, 9))); ("file1", ((8, 8), (8, 11)))]); - ("field Item1", [("file1", ((4, 6), (4, 9))); ("file1", ((8, 8), (8, 11)))]); - ("field Item2", [("file1", ((4, 6), (4, 9))); ("file1", ((8, 8), (8, 11)))]); + ("field Item1", []); ("field Item2", []); ("DU2", [("file1", ((5, 6), (5, 9))); ("file1", ((9, 8), (9, 11)))]); - ("field Item1", [("file1", ((5, 6), (5, 9))); ("file1", ((9, 8), (9, 11)))]); - ("field Item2", [("file1", ((5, 6), (5, 9))); ("file1", ((9, 8), (9, 11)))]); ("D", [("file1", ((6, 6), (6, 7))); ("file1", ((10, 8), (10, 9)))]); - ("field Item1", - [("file1", ((6, 6), (6, 7))); ("file1", ((10, 8), (10, 9)))]); - ("field Item2", - [("file1", ((6, 6), (6, 7))); ("file1", ((10, 8), (10, 9)))]); ("DUWithNamedFields", [("file1", ((12, 5), (12, 22)))]); ("DU", [("file1", ((12, 25), (12, 27))); ("file1", ((14, 8), (14, 10)))]); - ("field x", - [("file1", ((12, 25), (12, 27))); ("file1", ((14, 8), (14, 10)))]); - ("field y", - [("file1", ((12, 25), (12, 27))); ("file1", ((14, 8), (14, 10)))]); + ("field x", [("file1", ((12, 31), (12, 32))); ("file1", ((14, 11), (14, 12)))]); + ("field y", [("file1", ((12, 41), (12, 42))); ("file1", ((14, 16), (14, 17)))]); ("GenericClass`1", [("file1", ((16, 5), (16, 17))); ("file1", ((19, 8), (19, 20)))]); ("generic parameter T", @@ -760,13 +756,13 @@ let ``Test project2 all uses of all signature symbols`` () = (set expected = set allUsesOfAllSymbols) |> shouldEqual true [] -let ``Test project2 all uses of all symbols`` () = +let ``Test project2 all uses of all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunSynchronously - let allUsesOfAllSymbols = - [ for s in wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously -> - s.Symbol.DisplayName, (if s.FileName = Project2.fileName1 then "file1" else "???"), tupsZ s.RangeAlternate, attribsOfSymbol s.Symbol ] - let expected = + let wholeProjectResults = checker.ParseAndCheckProject(Project2.options) |> Async.RunImmediate + let allUsesOfAllSymbols = + [ for s in wholeProjectResults.GetAllUsesOfAllSymbols() -> + s.Symbol.DisplayName, (if s.FileName = Project2.fileName1 then "file1" else "???"), tupsZ s.Range, attribsOfSymbol s.Symbol ] + let expected = [("int", "file1", ((4, 13), (4, 16)), ["abbrev"]); ("int", "file1", ((4, 19), (4, 22)), ["abbrev"]); ("int", "file1", ((5, 13), (5, 16)), ["abbrev"]); @@ -789,17 +785,17 @@ let ``Test project2 all uses of all symbols`` () = ("int", "file1", ((12, 35), (12, 38)), ["abbrev"]); ("int", "file1", ((12, 45), (12, 48)), ["abbrev"]); ("int", "file1", ((12, 35), (12, 38)), ["abbrev"]); - ("x", "file1", ((12, 31), (12, 32)), []); + ("x", "file1", ((12, 31), (12, 32)), ["field"]); ("int", "file1", ((12, 45), (12, 48)), ["abbrev"]); - ("y", "file1", ((12, 41), (12, 42)), []); + ("y", "file1", ((12, 41), (12, 42)), ["field"]); ("DU", "file1", ((12, 25), (12, 27)), []); ("DUWithNamedFields", "file1", ((12, 5), (12, 22)), ["union"]); ("DU", "file1", ((14, 8), (14, 10)), []); - ("x", "file1", ((14, 11), (14, 12)), []); - ("y", "file1", ((14, 16), (14, 17)), []); + ("x", "file1", ((14, 11), (14, 12)), ["field"]); + ("y", "file1", ((14, 16), (14, 17)), ["field"]); ("T", "file1", ((16, 18), (16, 20)), []); ("GenericClass", "file1", ((16, 5), (16, 17)), ["class"]); - ("( .ctor )", "file1", ((16, 5), (16, 17)), ["member"; "ctor"]); + ("``.ctor``", "file1", ((16, 5), (16, 17)), ["member"; "ctor"]); ("U", "file1", ((17, 27), (17, 29)), []); ("T", "file1", ((17, 34), (17, 36)), []); ("U", "file1", ((17, 41), (17, 43)), []); @@ -832,10 +828,10 @@ let ``Test project2 all uses of all symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project3 = +module internal Project3 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -919,7 +915,7 @@ let setP (foo: IFoo) v = foo.InterfacePropertySet <- v let getE (foo: IFoo) = foo.InterfaceEvent let getM (foo: IFoo) = foo.InterfaceMethod("d") """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) @@ -929,120 +925,123 @@ let getM (foo: IFoo) = foo.InterfaceMethod("d") [] -let ``Test project3 whole project errors`` () = +let ``Test project3 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunSynchronously - wholeProjectResults .Errors.Length |> shouldEqual 0 + let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunImmediate + wholeProjectResults .Diagnostics.Length |> shouldEqual 0 [] -let ``Test project3 basic`` () = +let ``Test project3 basic`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunImmediate set [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual (set ["M"]) - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual ["IFoo"; "CFoo"; "CBaseFoo"; "IFooImpl"; "CFooImpl"; "CBaseFooImpl"] - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual ["IFooImplObjectExpression"; "CFooImplObjectExpression"; "getP"; "setP"; "getE";"getM"] [] -let ``Test project3 all symbols in signature`` () = +let ``Test project3 all symbols in signature`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] - |> shouldEqual - [("M", ["module"]); - ("val IFooImplObjectExpression", ["val"]); - ("val CFooImplObjectExpression", ["val"]); - ("val getP", ["val"]); - ("val setP", ["val"]); ("val getE", ["val"]); - ("val getM", ["val"]); - ("IFoo", ["interface"]); - ("member InterfaceMethod", ["slot"; "member"]); - ("member add_InterfaceEvent", ["slot"; "member"; "add"]); - ("member get_InterfaceEvent", ["slot"; "member"; "getter"]); - ("member get_InterfaceProperty", ["slot"; "member"; "getter"]); - ("member remove_InterfaceEvent", ["slot"; "member"; "remove"]); - ("member set_InterfacePropertySet", ["slot"; "member"; "setter"]); - ("property InterfacePropertySet", ["slot"; "member"; "prop"]); - ("property InterfaceProperty", ["slot"; "member"; "prop"]); - ("property InterfaceEvent", ["slot"; "member"; "prop"; "clievent"]); - ("CFoo", ["class"]); - ("member .ctor", ["member"; "ctor"]); - ("member AbstractClassMethod", ["slot"; "member"]); - ("member add_AbstractClassEvent", ["slot"; "member"; "add"]); - ("member get_AbstractClassEvent", ["slot"; "member"; "getter"]); - ("member get_AbstractClassProperty", ["slot"; "member"; "getter"]); - ("member remove_AbstractClassEvent", ["slot"; "member"; "remove"]); - ("member set_AbstractClassPropertySet", ["slot"; "member"; "setter"]); - ("property AbstractClassPropertySet", ["slot"; "member"; "prop"]); - ("property AbstractClassProperty", ["slot"; "member"; "prop"]); - ("property AbstractClassEvent", ["slot"; "member"; "prop"; "clievent"]); - ("CBaseFoo", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member BaseClassMethod", ["slot"; "member"]); - ("member BaseClassMethod", ["member"; "overridemem"]); - ("member add_BaseClassEvent", ["slot"; "member"; "add"]); - ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); - ("member get_BaseClassEvent", ["slot"; "member"; "getter"]); - ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_BaseClassProperty", ["slot"; "member"; "getter"]); - ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_BaseClassEvent", ["slot"; "member"; "remove"]); - ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_BaseClassPropertySet", ["slot"; "member"; "setter"]); - ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property BaseClassPropertySet", ["slot"; "member"; "prop"]); - ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); - ("property BaseClassProperty", ["slot"; "member"; "prop"]); - ("property BaseClassEvent", ["member"; "prop"; "overridemem"]); - ("property BaseClassEvent", ["slot"; "member"; "prop"]); - ("IFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member InterfaceMethod", ["member"; "overridemem"; "intfmem"]); - ("member add_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member get_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member get_InterfaceProperty", ["member"; "overridemem"; "intfmem"]); - ("member remove_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member set_InterfacePropertySet", ["member"; "overridemem"; "intfmem"]); - ("CFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member AbstractClassMethod", ["member"; "overridemem"]); - ("member add_AbstractClassEvent", ["member"; "add"; "overridemem"]); - ("member get_AbstractClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_AbstractClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_AbstractClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_AbstractClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property AbstractClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property AbstractClassProperty", ["member"; "prop"; "overridemem"]); - ("property AbstractClassEvent", ["member"; "prop"; "clievent"; "overridemem"]); - ("CBaseFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member BaseClassMethod", ["member"; "overridemem"]); - ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); - ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); - ("property BaseClassEvent", ["member"; "prop"; "clievent"; "overridemem"])] + let results = [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] + [("M", ["module"]); + ("val IFooImplObjectExpression", ["val"]); + ("val CFooImplObjectExpression", ["val"]); + ("val getP", ["val"]); + ("val setP", ["val"]); ("val getE", ["val"]); + ("val getM", ["val"]); + ("IFoo", ["interface"]); + ("member InterfaceMethod", ["slot"; "member"]); + ("member add_InterfaceEvent", ["slot"; "member"; "add"]); + ("member get_InterfaceEvent", ["slot"; "member"; "getter"]); + ("member get_InterfaceProperty", ["slot"; "member"; "getter"]); + ("member remove_InterfaceEvent", ["slot"; "member"; "remove"]); + ("member set_InterfacePropertySet", ["slot"; "member"; "setter"]); + ("property InterfacePropertySet", ["slot"; "member"; "prop"]); + ("property InterfaceProperty", ["slot"; "member"; "prop"]); + ("property InterfaceEvent", ["slot"; "member"; "prop"; "clievent"]); + ("CFoo", ["class"]); + ("member .ctor", ["member"; "ctor"]); + ("member AbstractClassMethod", ["slot"; "member"]); + ("member add_AbstractClassEvent", ["slot"; "member"; "add"]); + ("member get_AbstractClassEvent", ["slot"; "member"; "getter"]); + ("member get_AbstractClassProperty", ["slot"; "member"; "getter"]); + ("member remove_AbstractClassEvent", ["slot"; "member"; "remove"]); + ("member set_AbstractClassPropertySet", ["slot"; "member"; "setter"]); + ("property AbstractClassPropertySet", ["slot"; "member"; "prop"]); + ("property AbstractClassProperty", ["slot"; "member"; "prop"]); + ("property AbstractClassEvent", ["slot"; "member"; "prop"; "clievent"]); + ("CBaseFoo", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member BaseClassMethod", ["slot"; "member"]); + ("member BaseClassMethod", ["member"; "overridemem"]); + ("member add_BaseClassEvent", ["slot"; "member"; "add"]); + ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); + ("member get_BaseClassEvent", ["slot"; "member"; "getter"]); + ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_BaseClassProperty", ["slot"; "member"; "getter"]); + ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_BaseClassEvent", ["slot"; "member"; "remove"]); + ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_BaseClassPropertySet", ["slot"; "member"; "setter"]); + ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property BaseClassPropertySet", ["slot"; "member"; "prop"]); + ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); + ("property BaseClassProperty", ["slot"; "member"; "prop"]); + ("property BaseClassEvent", ["member"; "prop"; "overridemem"]); + ("property BaseClassEvent", ["slot"; "member"; "prop"]); + ("IFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member InterfaceMethod", ["member"; "overridemem"; "intfmem"]); + ("member add_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member get_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member get_InterfaceProperty", ["member"; "overridemem"; "intfmem"]); + ("member remove_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member set_InterfacePropertySet", ["member"; "overridemem"; "intfmem"]); + ("CFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member AbstractClassMethod", ["member"; "overridemem"]); + ("member add_AbstractClassEvent", ["member"; "add"; "overridemem"]); + ("member get_AbstractClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_AbstractClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_AbstractClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_AbstractClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property AbstractClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property AbstractClassProperty", ["member"; "prop"; "overridemem"]); + ("property AbstractClassEvent", ["member"; "prop"; "clievent"; "overridemem"]); + ("CBaseFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member BaseClassMethod", ["member"; "overridemem"]); + ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); + ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); + ("property BaseClassEvent", ["member"; "prop"; "clievent"; "overridemem"])] + |> List.iter (fun x -> + if results |> List.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) [] -let ``Test project3 all uses of all signature symbols`` () = +let ``Test project3 all uses of all signature symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - let allUsesOfAllSymbols = - [ for s in allSymbols do - let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) |> Async.RunSynchronously -> - ((if s.FileName = Project3.fileName1 then "file1" else "??"), - tupsZ s.RangeAlternate, attribsOfSymbolUse s, attribsOfSymbol s.Symbol) ] + let allUsesOfAllSymbols = + [ for s in allSymbols do + let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) -> + ((if s.FileName = Project3.fileName1 then "file1" else "??"), + tupsZ s.Range, attribsOfSymbolUse s, attribsOfSymbol s.Symbol) ] yield s.ToString(), uses ] - let expected = + let expected = [("M", [("file1", ((1, 7), (1, 8)), ["defn"], ["module"])]); ("val IFooImplObjectExpression", [("file1", ((58, 4), (58, 28)), ["defn"], ["val"])]); @@ -1272,10 +1271,10 @@ let ``Test project3 all uses of all signature symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project4 = +module internal Project4 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -1285,7 +1284,7 @@ type Foo<'T>(x : 'T, y : Foo<'T>) = class end let inline twice(x : ^U, y : ^U) = x + y """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) @@ -1295,43 +1294,43 @@ let inline twice(x : ^U, y : ^U) = x + y [] -let ``Test project4 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunSynchronously - wholeProjectResults .Errors.Length |> shouldEqual 0 +let ``Test project4 whole project errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunImmediate + wholeProjectResults .Diagnostics.Length |> shouldEqual 0 [] -let ``Test project4 basic`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunSynchronously +let ``Test project4 basic`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunImmediate set [ for x in wholeProjectResults.AssemblySignature.Entities -> x.DisplayName ] |> shouldEqual (set ["M"]) - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].NestedEntities -> x.DisplayName ] |> shouldEqual ["Foo"] - [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] + [ for x in wholeProjectResults.AssemblySignature.Entities.[0].MembersFunctionsAndValues -> x.DisplayName ] |> shouldEqual ["twice"] [] -let ``Test project4 all symbols in signature`` () = +let ``Test project4 all symbols in signature`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbols -> x.ToString() ] - |> shouldEqual + [ for x in allSymbols -> x.ToString() ] + |> shouldEqual ["M"; "val twice"; "generic parameter U"; "Foo`1"; "generic parameter T"; "member .ctor"] [] -let ``Test project4 all uses of all signature symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunSynchronously +let ``Test project4 all uses of all signature symbols`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - let allUsesOfAllSymbols = - [ for s in allSymbols do - let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) |> Async.RunSynchronously -> (if s.FileName = Project4.fileName1 then "file1" else "??"), tupsZ s.RangeAlternate ] + let allUsesOfAllSymbols = + [ for s in allSymbols do + let uses = [ for s in wholeProjectResults.GetUsesOfSymbol(s) -> (if s.FileName = Project4.fileName1 then "file1" else "??"), tupsZ s.Range ] yield s.ToString(), uses ] - let expected = + let expected = [("M", [("file1", ((1, 7), (1, 8)))]); ("val twice", [("file1", ((5, 11), (5, 16)))]); ("generic parameter U", @@ -1342,29 +1341,29 @@ let ``Test project4 all uses of all signature symbols`` () = ("file1", ((3, 29), (3, 31)))]); ("member .ctor", [("file1", ((3, 5), (3, 8))); ("file1", ((3, 25), (3, 28)))])] - + set allUsesOfAllSymbols - set expected |> shouldEqual Set.empty set expected - set allUsesOfAllSymbols |> shouldEqual Set.empty (set expected = set allUsesOfAllSymbols) |> shouldEqual true [] -let ``Test project4 T symbols`` () = +let ``Test project4 T symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project4.fileName1, Project4.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project4.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project4.fileName1, Project4.options) + |> Async.RunImmediate - let tSymbolUse2 = backgroundTypedParse1.GetSymbolUseAtLocation(4,19,"",["T"]) |> Async.RunSynchronously + let tSymbolUse2 = backgroundTypedParse1.GetSymbolUseAtLocation(4,19,"",["T"]) tSymbolUse2.IsSome |> shouldEqual true - let tSymbol2 = tSymbolUse2.Value.Symbol + let tSymbol2 = tSymbolUse2.Value.Symbol tSymbol2.ToString() |> shouldEqual "generic parameter T" tSymbol2.ImplementationLocation.IsSome |> shouldEqual true - let uses = backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously - let allUsesOfAllSymbols = - [ for s in uses -> s.Symbol.ToString(), (if s.FileName = Project4.fileName1 then "file1" else "??"), tupsZ s.RangeAlternate ] + let uses = backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() + let allUsesOfAllSymbols = + [ for s in uses -> s.Symbol.ToString(), (if s.FileName = Project4.fileName1 then "file1" else "??"), tupsZ s.Range ] allUsesOfAllSymbols |> shouldEqual [("generic parameter T", "file1", ((3, 9), (3, 11))); ("Foo`1", "file1", ((3, 5), (3, 8))); @@ -1384,41 +1383,41 @@ let ``Test project4 T symbols`` () = ("val twice", "file1", ((5, 11), (5, 16))); ("M", "file1", ((1, 7), (1, 8)))] - let tSymbolUse3 = backgroundTypedParse1.GetSymbolUseAtLocation(4,11,"",["T"]) |> Async.RunSynchronously + let tSymbolUse3 = backgroundTypedParse1.GetSymbolUseAtLocation(4,11,"",["T"]) tSymbolUse3.IsSome |> shouldEqual true let tSymbol3 = tSymbolUse3.Value.Symbol tSymbol3.ToString() |> shouldEqual "generic parameter T" tSymbol3.ImplementationLocation.IsSome |> shouldEqual true - let usesOfTSymbol2 = - wholeProjectResults.GetUsesOfSymbol(tSymbol2) |> Async.RunSynchronously - |> Array.map (fun su -> su.FileName , tupsZ su.RangeAlternate) + let usesOfTSymbol2 = + wholeProjectResults.GetUsesOfSymbol(tSymbol2) + |> Array.map (fun su -> su.FileName , tupsZ su.Range) |> Array.map (fun (a,b) -> (if a = Project4.fileName1 then "file1" else "??"), b) - usesOfTSymbol2 |> shouldEqual + usesOfTSymbol2 |> shouldEqual [|("file1", ((3, 9), (3, 11))); ("file1", ((3, 17), (3, 19))); ("file1", ((3, 29), (3, 31)))|] - let usesOfTSymbol3 = - wholeProjectResults.GetUsesOfSymbol(tSymbol3) - |> Async.RunSynchronously - |> Array.map (fun su -> su.FileName , tupsZ su.RangeAlternate) + let usesOfTSymbol3 = + wholeProjectResults.GetUsesOfSymbol(tSymbol3) + + |> Array.map (fun su -> su.FileName , tupsZ su.Range) |> Array.map (fun (a,b) -> (if a = Project4.fileName1 then "file1" else "??"), b) usesOfTSymbol3 |> shouldEqual usesOfTSymbol2 - let uSymbolUse2 = backgroundTypedParse1.GetSymbolUseAtLocation(6,23,"",["U"]) |> Async.RunSynchronously + let uSymbolUse2 = backgroundTypedParse1.GetSymbolUseAtLocation(6,23,"",["U"]) uSymbolUse2.IsSome |> shouldEqual true let uSymbol2 = uSymbolUse2.Value.Symbol uSymbol2.ToString() |> shouldEqual "generic parameter U" uSymbol2.ImplementationLocation.IsSome |> shouldEqual true - let usesOfUSymbol2 = - wholeProjectResults.GetUsesOfSymbol(uSymbol2) - |> Async.RunSynchronously - |> Array.map (fun su -> su.FileName , tupsZ su.RangeAlternate) + let usesOfUSymbol2 = + wholeProjectResults.GetUsesOfSymbol(uSymbol2) + + |> Array.map (fun su -> su.FileName , tupsZ su.Range) |> Array.map (fun (a,b) -> (if a = Project4.fileName1 then "file1" else "??"), b) usesOfUSymbol2 |> shouldEqual [|("file1", ((5, 21), (5, 23))); ("file1", ((5, 29), (5, 31)))|] @@ -1426,15 +1425,15 @@ let ``Test project4 T symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project5 = +module internal Project5 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ -module ActivePatterns +module ActivePatterns ///Total active pattern for even/odd integers let (|Even|Odd|) input = if input % 2 = 0 then Even else Odd @@ -1457,7 +1456,7 @@ let parseNumeric str = | Float f -> printfn "%f : Floating point" f | _ -> printfn "%s : Not matched." str """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1467,44 +1466,44 @@ let parseNumeric str = [] -let ``Test project5 whole project errors`` () = +let ``Test project5 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project5 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test project 5 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.FullName, Project5.cleanFileName su.FileName, tupsZ su.RangeAlternate, attribsOfSymbolUse su) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.FullName, Project5.cleanFileName su.FileName, tupsZ su.Range, attribsOfSymbolUse su) allUsesOfAllSymbols |> shouldEqual [|("symbol ", "Even", "file1", ((4, 6), (4, 10)), ["defn"]); ("symbol ", "Odd", "file1", ((4, 11), (4, 14)), ["defn"]); ("val input", "input", "file1", ((4, 17), (4, 22)), ["defn"]); - ("val op_Equality", "Microsoft.FSharp.Core.Operators.( = )", "file1", + ("val op_Equality", "Microsoft.FSharp.Core.Operators.(=)", "file1", ((4, 38), (4, 39)), []); - ("val op_Modulus", "Microsoft.FSharp.Core.Operators.( % )", "file1", + ("val op_Modulus", "Microsoft.FSharp.Core.Operators.(%)", "file1", ((4, 34), (4, 35)), []); ("val input", "input", "file1", ((4, 28), (4, 33)), []); ("symbol ", "Even", "file1", ((4, 47), (4, 51)), ["defn"]); ("symbol ", "Odd", "file1", ((4, 57), (4, 60)), ["defn"]); - ("val |Even|Odd|", "ActivePatterns.( |Even|Odd| )", "file1", ((4, 5), (4, 15)), + ("val |Even|Odd|", "ActivePatterns.(|Even|Odd|)", "file1", ((4, 5), (4, 15)), ["defn"]); ("val input", "input", "file1", ((7, 15), (7, 20)), ["defn"]); ("val input", "input", "file1", ((8, 9), (8, 14)), []); - ("symbol Even", "ActivePatterns.( |Even|Odd| ).Even", "file1", + ("symbol Even", "ActivePatterns.(|Even|Odd|).Even", "file1", ((9, 5), (9, 9)), ["pattern"]); ("val printfn", "Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn", "file1", ((9, 13), (9, 20)), []); ("val input", "input", "file1", ((9, 34), (9, 39)), []); - ("symbol Odd", "ActivePatterns.( |Even|Odd| ).Odd", "file1", + ("symbol Odd", "ActivePatterns.(|Even|Odd|).Odd", "file1", ((10, 5), (10, 8)), ["pattern"]); ("val printfn", "Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn", "file1", ((10, 12), (10, 19)), []); @@ -1518,7 +1517,7 @@ let ``Test project 5 all symbols`` () = ("Double", "System.Double", "file1", ((15, 13), (15, 19)), []); ("val str", "str", "file1", ((15, 29), (15, 32)), []); ("val op_AddressOf", - "Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators.( ~& )", "file1", + "Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators.(~&)", "file1", ((15, 34), (15, 35)), []); ("val floatvalue", "floatvalue", "file1", ((15, 35), (15, 45)), []); ("member TryParse", "System.Double.TryParse", "file1", ((15, 6), (15, 28)), []); @@ -1526,12 +1525,12 @@ let ``Test project 5 all symbols`` () = []); ("val floatvalue", "floatvalue", "file1", ((15, 57), (15, 67)), []); ("None", "Microsoft.FSharp.Core.Option<_>.None", "file1", ((16, 8), (16, 12)), []); - ("val |Float|_|", "ActivePatterns.( |Float|_| )", "file1", ((13, 5), (13, 14)), + ("val |Float|_|", "ActivePatterns.(|Float|_|)", "file1", ((13, 5), (13, 14)), ["defn"]); ("val str", "str", "file1", ((19, 17), (19, 20)), ["defn"]); ("val str", "str", "file1", ((20, 9), (20, 12)), []); - ("val f", "f", "file1", ((21, 11), (21, 12)), ["defn"]); - ("symbol Float", "ActivePatterns.( |Float|_| ).Float", "file1", + ("symbol Float", "ActivePatterns.(|Float|_|).Float", "file1", ((21, 5), (21, 10)), ["pattern"]); + ("val f", "f", "file1", ((21, 11), (21, 12)), ["defn"]); ("val printfn", "Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn", "file1", ((21, 16), (21, 23)), []); ("val f", "f", "file1", ((21, 46), (21, 47)), []); @@ -1545,19 +1544,24 @@ let ``Test project 5 all symbols`` () = [] let ``Test complete active patterns' exact ranges from uses of symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project5.fileName1, Project5.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project5.fileName1, Project5.options) + |> Async.RunImmediate - let oddSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(11,8,"",["Odd"]) |> Async.RunSynchronously - oddSymbolUse.IsSome |> shouldEqual true + let oddSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(11,8,"",["Odd"]) + oddSymbolUse.IsSome |> shouldEqual true let oddSymbol = oddSymbolUse.Value.Symbol oddSymbol.ToString() |> shouldEqual "symbol Odd" let oddActivePatternCase = oddSymbol :?> FSharpActivePatternCase - oddActivePatternCase.XmlDoc |> Seq.toList |> shouldEqual ["Total active pattern for even/odd integers"] - oddActivePatternCase.XmlDocSig |> shouldEqual "" + match oddActivePatternCase.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> shouldEqual [| "Total active pattern for even/odd integers" |] + | _ -> failwith "wrong kind" + match oddActivePatternCase.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> t.GetElaboratedXmlLines() |> shouldEqual [|""; "Total active pattern for even/odd integers"; "" |] + | _ -> failwith "wrong kind" + oddActivePatternCase.XmlDocSig |> shouldEqual "M:ActivePatterns.|Even|Odd|(System.Int32)" let oddGroup = oddActivePatternCase.Group oddGroup.IsTotal |> shouldEqual true oddGroup.Names |> Seq.toList |> shouldEqual ["Even"; "Odd"] @@ -1565,13 +1569,17 @@ let ``Test complete active patterns' exact ranges from uses of symbols`` () = let oddEntity = oddGroup.DeclaringEntity.Value oddEntity.ToString() |> shouldEqual "ActivePatterns" - let evenSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(10,9,"",["Even"]) |> Async.RunSynchronously - evenSymbolUse.IsSome |> shouldEqual true + let evenSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(10,9,"",["Even"]) + evenSymbolUse.IsSome |> shouldEqual true let evenSymbol = evenSymbolUse.Value.Symbol evenSymbol.ToString() |> shouldEqual "symbol Even" let evenActivePatternCase = evenSymbol :?> FSharpActivePatternCase - evenActivePatternCase.XmlDoc |> Seq.toList |> shouldEqual ["Total active pattern for even/odd integers"] - evenActivePatternCase.XmlDocSig |> shouldEqual "" + match evenActivePatternCase.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> + t.UnprocessedLines |> shouldEqual [| "Total active pattern for even/odd integers" |] + t.GetElaboratedXmlLines() |> shouldEqual [| ""; "Total active pattern for even/odd integers"; "" |] + | _ -> failwith "wrong kind" + evenActivePatternCase.XmlDocSig |> shouldEqual "M:ActivePatterns.|Even|Odd|(System.Int32)" let evenGroup = evenActivePatternCase.Group evenGroup.IsTotal |> shouldEqual true evenGroup.Names |> Seq.toList |> shouldEqual ["Even"; "Odd"] @@ -1579,22 +1587,22 @@ let ``Test complete active patterns' exact ranges from uses of symbols`` () = let evenEntity = evenGroup.DeclaringEntity.Value evenEntity.ToString() |> shouldEqual "ActivePatterns" - let usesOfEvenSymbol = - wholeProjectResults.GetUsesOfSymbol(evenSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tupsZ su.RangeAlternate) + let usesOfEvenSymbol = + wholeProjectResults.GetUsesOfSymbol(evenSymbol) + + |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tupsZ su.Range) - let usesOfOddSymbol = - wholeProjectResults.GetUsesOfSymbol(oddSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tupsZ su.RangeAlternate) + let usesOfOddSymbol = + wholeProjectResults.GetUsesOfSymbol(oddSymbol) - usesOfEvenSymbol |> shouldEqual + |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tupsZ su.Range) + + usesOfEvenSymbol |> shouldEqual [|("symbol Even", "file1", ((4, 6), (4, 10))); ("symbol Even", "file1", ((4, 47), (4, 51))); ("symbol Even", "file1", ((9, 5), (9, 9)))|] - usesOfOddSymbol |> shouldEqual + usesOfOddSymbol |> shouldEqual [|("symbol Odd", "file1", ((4, 11), (4, 14))); ("symbol Odd", "file1", ((4, 57), (4, 60))); ("symbol Odd", "file1", ((10, 5), (10, 8)))|] @@ -1603,19 +1611,23 @@ let ``Test complete active patterns' exact ranges from uses of symbols`` () = [] let ``Test partial active patterns' exact ranges from uses of symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project5.fileName1, Project5.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project5.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project5.fileName1, Project5.options) + |> Async.RunImmediate - let floatSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(22,10,"",["Float"]) |> Async.RunSynchronously - floatSymbolUse.IsSome |> shouldEqual true - let floatSymbol = floatSymbolUse.Value.Symbol + let floatSymbolUse = backgroundTypedParse1.GetSymbolUseAtLocation(22,10,"",["Float"]) + floatSymbolUse.IsSome |> shouldEqual true + let floatSymbol = floatSymbolUse.Value.Symbol floatSymbol.ToString() |> shouldEqual "symbol Float" let floatActivePatternCase = floatSymbol :?> FSharpActivePatternCase - floatActivePatternCase.XmlDoc |> Seq.toList |> shouldEqual ["Partial active pattern for floats"] - floatActivePatternCase.XmlDocSig |> shouldEqual "" + match floatActivePatternCase.XmlDoc with + | FSharpXmlDoc.FromXmlText t -> + t.UnprocessedLines |> shouldEqual [| "Partial active pattern for floats" |] + t.GetElaboratedXmlLines() |> shouldEqual [| ""; "Partial active pattern for floats"; "" |] + | _ -> failwith "wrong kind" + floatActivePatternCase.XmlDocSig |> shouldEqual "M:ActivePatterns.|Float|_|(System.String)" let floatGroup = floatActivePatternCase.Group floatGroup.IsTotal |> shouldEqual false floatGroup.Names |> Seq.toList |> shouldEqual ["Float"] @@ -1623,28 +1635,28 @@ let ``Test partial active patterns' exact ranges from uses of symbols`` () = let evenEntity = floatGroup.DeclaringEntity.Value evenEntity.ToString() |> shouldEqual "ActivePatterns" - let usesOfFloatSymbol = - wholeProjectResults.GetUsesOfSymbol(floatSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tups su.RangeAlternate) + let usesOfFloatSymbol = + wholeProjectResults.GetUsesOfSymbol(floatSymbol) + + |> Array.map (fun su -> su.Symbol.ToString(), Project5.cleanFileName su.FileName, tups su.Range) - usesOfFloatSymbol |> shouldEqual + usesOfFloatSymbol |> shouldEqual [|("symbol Float", "file1", ((14, 6), (14, 11))); ("symbol Float", "file1", ((22, 5), (22, 10)))|] // Should also return its definition - let floatSymUseOpt = + let floatSymUseOpt = backgroundTypedParse1.GetSymbolUseAtLocation(14,11,"",["Float"]) - |> Async.RunSynchronously + floatSymUseOpt.IsSome |> shouldEqual true //----------------------------------------------------------------------------------------- -module internal Project6 = +module internal Project6 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -1655,7 +1667,7 @@ exception Fail of string let f () = raise (Fail "unknown") """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1665,23 +1677,23 @@ let f () = [] -let ``Test project6 whole project errors`` () = +let ``Test project6 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project6.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project6.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project6 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test project 6 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project6.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project6.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), Project6.cleanFileName su.FileName, tupsZ su.RangeAlternate, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), Project6.cleanFileName su.FileName, tupsZ su.Range, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("string", "file1", ((3, 18), (3, 24)), ["abbrev"]); @@ -1694,16 +1706,16 @@ let ``Test project 6 all symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project7 = +module internal Project7 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module NamedArgs -type C() = +type C() = static member M(arg1: int, arg2: int, ?arg3 : int) = arg1 + arg2 + defaultArg arg3 4 let x1 = C.M(arg1 = 3, arg2 = 4, arg3 = 5) @@ -1711,7 +1723,7 @@ let x1 = C.M(arg1 = 3, arg2 = 4, arg3 = 5) let x2 = C.M(arg1 = 3, arg2 = 4, ?arg3 = Some 5) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1721,32 +1733,32 @@ let x2 = C.M(arg1 = 3, arg2 = 4, ?arg3 = Some 5) [] -let ``Test project7 whole project errors`` () = +let ``Test project7 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project7.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project7.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project7 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test project 7 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project7.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project7.options) |> Async.RunImmediate + + let allUsesOfAllSymbols = + wholeProjectResults.GetAllUsesOfAllSymbols() + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project7.cleanFileName su.FileName, tups su.Range) - let allUsesOfAllSymbols = + let arg1symbol = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project7.cleanFileName su.FileName, tups su.RangeAlternate) - let arg1symbol = - wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously |> Array.pick (fun x -> if x.Symbol.DisplayName = "arg1" then Some x.Symbol else None) - let arg1uses = - wholeProjectResults.GetUsesOfSymbol(arg1symbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), Option.map tups su.Symbol.DeclarationLocation, Project7.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbol su.Symbol) + let arg1uses = + wholeProjectResults.GetUsesOfSymbol(arg1symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), Option.map tups su.Symbol.DeclarationLocation, Project7.cleanFileName su.FileName, tups su.Range, attribsOfSymbol su.Symbol) arg1uses |> shouldEqual [|("val arg1", Some ((5, 20), (5, 24)), "file1", ((5, 20), (5, 24)), []); ("val arg1", Some ((5, 20), (5, 24)), "file1", ((5, 57), (5, 61)), []); @@ -1755,10 +1767,10 @@ let ``Test project 7 all symbols`` () = //----------------------------------------------------------------------------------------- -module internal Project8 = +module internal Project8 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -1767,12 +1779,12 @@ module NamedUnionFields type A = B of xxx: int * yyy : int let b = B(xxx=1, yyy=2) -let x = +let x = match b with // does not find usage here | B (xxx = a; yyy = b) -> () """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1782,56 +1794,56 @@ let x = [] -let ``Test project8 whole project errors`` () = +let ``Test project8 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project8.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project8.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project8 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test project 8 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project8.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project8.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project8.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) - allUsesOfAllSymbols + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project8.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + allUsesOfAllSymbols |> shouldEqual [|("int", "int", "file1", ((4, 19), (4, 22)), ["type"], ["abbrev"]); ("int", "int", "file1", ((4, 31), (4, 34)), ["type"], ["abbrev"]); + ("field xxx", "xxx", "file1", ((4, 14), (4, 17)), ["defn"], ["field"]); ("int", "int", "file1", ((4, 19), (4, 22)), ["type"], ["abbrev"]); - ("parameter xxx", "xxx", "file1", ((4, 14), (4, 17)), ["defn"], []); + ("field yyy", "yyy", "file1", ((4, 25), (4, 28)), ["defn"], ["field"]); ("int", "int", "file1", ((4, 31), (4, 34)), ["type"], ["abbrev"]); - ("parameter yyy", "yyy", "file1", ((4, 25), (4, 28)), ["defn"], []); ("B", "B", "file1", ((4, 9), (4, 10)), ["defn"], []); ("A", "A", "file1", ((4, 5), (4, 6)), ["defn"], ["union"]); ("B", "B", "file1", ((5, 8), (5, 9)), [], []); - ("parameter xxx", "xxx", "file1", ((5, 10), (5, 13)), [], []); - ("parameter yyy", "yyy", "file1", ((5, 17), (5, 20)), [], []); + ("field xxx", "xxx", "file1", ((5, 10), (5, 13)), [], ["field"]); + ("field yyy", "yyy", "file1", ((5, 17), (5, 20)), [], ["field"]); ("val b", "b", "file1", ((5, 4), (5, 5)), ["defn"], ["val"]); ("val b", "b", "file1", ((8, 10), (8, 11)), [], ["val"]); - ("parameter xxx", "xxx", "file1", ((10, 9), (10, 12)), ["pattern"], []); - ("parameter yyy", "yyy", "file1", ((10, 18), (10, 21)), ["pattern"], []); + ("B", "B", "file1", ((10, 6), (10, 7)), ["pattern"], []); + ("field xxx", "xxx", "file1", ((10, 9), (10, 12)), ["pattern"], ["field"]); + ("field yyy", "yyy", "file1", ((10, 18), (10, 21)), ["pattern"], ["field"]); ("val b", "b", "file1", ((10, 24), (10, 25)), ["defn"], []); ("val a", "a", "file1", ((10, 15), (10, 16)), ["defn"], []); - ("B", "B", "file1", ((10, 6), (10, 7)), ["pattern"], []); ("val x", "x", "file1", ((7, 4), (7, 5)), ["defn"], ["val"]); ("NamedUnionFields", "NamedUnionFields", "file1", ((2, 7), (2, 23)), ["defn"], ["module"])|] - let arg1symbol = - wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously + let arg1symbol = + wholeProjectResults.GetAllUsesOfAllSymbols() + |> Array.pick (fun x -> if x.Symbol.DisplayName = "xxx" then Some x.Symbol else None) - let arg1uses = - wholeProjectResults.GetUsesOfSymbol(arg1symbol) - |> Async.RunSynchronously - |> Array.map (fun su -> Option.map tups su.Symbol.DeclarationLocation, Project8.cleanFileName su.FileName, tups su.RangeAlternate) + let arg1uses = + wholeProjectResults.GetUsesOfSymbol(arg1symbol) + + |> Array.map (fun su -> Option.map tups su.Symbol.DeclarationLocation, Project8.cleanFileName su.FileName, tups su.Range) arg1uses |> shouldEqual [|(Some ((4, 14), (4, 17)), "file1", ((4, 14), (4, 17))); @@ -1839,10 +1851,10 @@ let ``Test project 8 all symbols`` () = (Some ((4, 14), (4, 17)), "file1", ((10, 9), (10, 12)))|] //----------------------------------------------------------------------------------------- -module internal Project9 = +module internal Project9 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -1852,7 +1864,7 @@ let inline check< ^T when ^T : (static member IsInfinity : ^T -> bool)> (num: ^T if (^T : (static member IsInfinity: ^T -> bool) (num)) then None else Some num """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1862,23 +1874,23 @@ let inline check< ^T when ^T : (static member IsInfinity : ^T -> bool)> (num: ^T [] -let ``Test project9 whole project errors`` () = +let ``Test project9 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project9.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project9.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project9 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test project 9 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project9.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project9.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project9.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project9.cleanFileName su.FileName, tups su.Range, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("generic parameter T", "T", "file1", ((4, 18), (4, 20)), []); @@ -1901,14 +1913,14 @@ let ``Test project 9 all symbols`` () = ("val check", "check", "file1", ((4, 11), (4, 16)), ["val"]); ("Constraints", "Constraints", "file1", ((2, 7), (2, 18)), ["module"])|] - let arg1symbol = - wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously + let arg1symbol = + wholeProjectResults.GetAllUsesOfAllSymbols() + |> Array.pick (fun x -> if x.Symbol.DisplayName = "IsInfinity" then Some x.Symbol else None) - let arg1uses = - wholeProjectResults.GetUsesOfSymbol(arg1symbol) - |> Async.RunSynchronously - |> Array.map (fun su -> Option.map tups su.Symbol.DeclarationLocation, Project9.cleanFileName su.FileName, tups su.RangeAlternate) + let arg1uses = + wholeProjectResults.GetUsesOfSymbol(arg1symbol) + + |> Array.map (fun su -> Option.map tups su.Symbol.DeclarationLocation, Project9.cleanFileName su.FileName, tups su.Range) arg1uses |> shouldEqual [|(Some ((4, 46), (4, 56)), "file1", ((4, 46), (4, 56)))|] @@ -1916,22 +1928,22 @@ let ``Test project 9 all symbols`` () = //----------------------------------------------------------------------------------------- // see https://github.com/fsharp/FSharp.Compiler.Service/issues/95 -module internal Project10 = +module internal Project10 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module NamedArgs -type C() = +type C() = static member M(url: string, query: int) = () C.M("http://goo", query = 1) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -1941,27 +1953,27 @@ C.M("http://goo", query = 1) [] -let ``Test Project10 whole project errors`` () = +let ``Test Project10 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project10.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project10.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project10 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project10 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project10.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project10.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project10.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project10.cleanFileName su.FileName, tups su.Range, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("C", "C", "file1", ((4, 5), (4, 6)), ["class"]); - ("member .ctor", "( .ctor )", "file1", ((4, 5), (4, 6)), + ("member .ctor", "``.ctor``", "file1", ((4, 5), (4, 6)), ["member"; "ctor"]); ("string", "string", "file1", ((5, 25), (5, 31)), ["abbrev"]); ("int", "int", "file1", ((5, 40), (5, 43)), ["abbrev"]); @@ -1975,21 +1987,21 @@ let ``Test Project10 all symbols`` () = ("parameter query", "query", "file1", ((7, 18), (7, 23)), []); ("NamedArgs", "NamedArgs", "file1", ((2, 7), (2, 16)), ["module"])|] - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project10.fileName1, Project10.options) - |> Async.RunSynchronously + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project10.fileName1, Project10.options) + |> Async.RunImmediate + + let querySymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(7,23,"",["query"]) - let querySymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(7,23,"",["query"]) - |> Async.RunSynchronously let querySymbolUse = querySymbolUseOpt.Value let querySymbol = querySymbolUse.Symbol querySymbol.ToString() |> shouldEqual "parameter query" - let querySymbolUse2Opt = + let querySymbolUse2Opt = backgroundTypedParse1.GetSymbolUseAtLocation(7,22,"",["query"]) - |> Async.RunSynchronously + let querySymbolUse2 = querySymbolUse2Opt.Value let querySymbol2 = querySymbolUse2.Symbol @@ -1998,10 +2010,10 @@ let ``Test Project10 all symbols`` () = //----------------------------------------------------------------------------------------- // see https://github.com/fsharp/FSharp.Compiler.Service/issues/92 -module internal Project11 = +module internal Project11 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2011,7 +2023,7 @@ let enum = new System.Collections.Generic.Dictionary.Enumerator() let fff (x:System.Collections.Generic.Dictionary.Enumerator) = () """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -2021,23 +2033,23 @@ let fff (x:System.Collections.Generic.Dictionary.Enumerator) = () [] -let ``Test Project11 whole project errors`` () = +let ``Test Project11 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project11.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project11.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project11 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project11 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project11.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project11.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project11.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project11.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("System", "System", "file1", ((4, 15), (4, 21)), [], ["namespace"]); @@ -2065,10 +2077,10 @@ let ``Test Project11 all symbols`` () = //----------------------------------------------------------------------------------------- // see https://github.com/fsharp/FSharp.Compiler.Service/issues/92 -module internal Project12 = +module internal Project12 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2080,7 +2092,7 @@ let x2 = query { for i in 0 .. 100 do select (i,i) } """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -2090,27 +2102,27 @@ let x2 = query { for i in 0 .. 100 do [] -let ``Test Project12 whole project errors`` () = +let ``Test Project12 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project12.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project12.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project12 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project12 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project12.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project12.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project12.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project12.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("val seq", "seq", "file1", ((4, 9), (4, 12)), ["compexpr"], ["val"]); - ("val op_Range", "( .. )", "file1", ((4, 26), (4, 28)), [], ["val"]); + ("val op_Range", "(..)", "file1", ((4, 26), (4, 28)), [], ["val"]); ("val i", "i", "file1", ((4, 19), (4, 20)), ["defn"], []); ("val i", "i", "file1", ((4, 36), (4, 37)), [], []); ("val x1", "x1", "file1", ((4, 4), (4, 6)), ["defn"], ["val"]); @@ -2120,9 +2132,9 @@ let ``Test Project12 all symbols`` () = ["member"]); ("member Select", "select", "file1", ((7, 17), (7, 23)), ["compexpr"], ["member"]); - ("val op_Range", "( .. )", "file1", ((5, 28), (5, 30)), [], ["val"]); + ("val op_Range", "(..)", "file1", ((5, 28), (5, 30)), [], ["val"]); ("val i", "i", "file1", ((5, 21), (5, 22)), ["defn"], []); - ("val op_Equality", "( = )", "file1", ((6, 26), (6, 27)), [], ["val"]); + ("val op_Equality", "(=)", "file1", ((6, 26), (6, 27)), [], ["val"]); ("val i", "i", "file1", ((6, 24), (6, 25)), [], []); ("val i", "i", "file1", ((7, 25), (7, 26)), [], []); ("val i", "i", "file1", ((7, 27), (7, 28)), [], []); @@ -2133,10 +2145,10 @@ let ``Test Project12 all symbols`` () = //----------------------------------------------------------------------------------------- // Test fetching information about some external types (e.g. System.Object, System.DateTime) -module internal Project13 = +module internal Project13 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2147,7 +2159,7 @@ let x2 = new System.DateTime(1,1,1) let x3 = new System.DateTime() """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -2157,23 +2169,23 @@ let x3 = new System.DateTime() [] -let ``Test Project13 whole project errors`` () = +let ``Test Project13 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project13.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project13.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project13 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project13 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project13.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project13.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project13.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project13.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("System", "System", "file1", ((4, 14), (4, 20)), [], ["namespace"]); @@ -2191,12 +2203,12 @@ let ``Test Project13 all symbols`` () = ("ExternalTypes", "ExternalTypes", "file1", ((2, 7), (2, 20)), ["defn"], ["module"])|] - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Object") + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Object") let objEntity = objSymbol.Symbol :?> FSharpEntity let objMemberNames = [ for x in objEntity.MembersFunctionsAndValues -> x.DisplayName ] - set objMemberNames |> shouldEqual (set [".ctor"; "ToString"; "Equals"; "Equals"; "ReferenceEquals"; "GetHashCode"; "GetType"; "Finalize"; "MemberwiseClone"]) - - let dtSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "DateTime") + set objMemberNames |> shouldEqual (set ["``.ctor``"; "ToString"; "Equals"; "Equals"; "ReferenceEquals"; "GetHashCode"; "GetType"; "Finalize"; "MemberwiseClone"]) + + let dtSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "DateTime") let dtEntity = dtSymbol.Symbol :?> FSharpEntity let dtPropNames = [ for x in dtEntity.MembersFunctionsAndValues do if x.IsProperty then yield x.DisplayName ] @@ -2204,7 +2216,7 @@ let ``Test Project13 all symbols`` () = set [ for i in dtType.DeclaredInterfaces -> i.ToString() ] |> shouldEqual (set - ["type System.IComparable"; + ["type System.IComparable"; "type System.IFormattable"; "type System.IConvertible"; "type System.Runtime.Serialization.ISerializable"; @@ -2212,23 +2224,23 @@ let ``Test Project13 all symbols`` () = "type System.IEquatable"]) dtType.BaseType.ToString() |> shouldEqual "Some(type System.ValueType)" - - set ["Date"; "Day"; "DayOfWeek"; "DayOfYear"; "Hour"; "Kind"; "Millisecond"; "Minute"; "Month"; "Now"; "Second"; "Ticks"; "TimeOfDay"; "Today"; "Year"] - - set dtPropNames + + set ["Date"; "Day"; "DayOfWeek"; "DayOfYear"; "Hour"; "Kind"; "Millisecond"; "Minute"; "Month"; "Now"; "Second"; "Ticks"; "TimeOfDay"; "Today"; "Year"] + - set dtPropNames |> shouldEqual (set []) let objDispatchSlotNames = [ for x in objEntity.MembersFunctionsAndValues do if x.IsDispatchSlot then yield x.DisplayName ] - + set objDispatchSlotNames |> shouldEqual (set ["ToString"; "Equals"; "GetHashCode"; "Finalize"]) // check we can get the CurriedParameterGroups - let objMethodsCurriedParameterGroups = - [ for x in objEntity.MembersFunctionsAndValues do - for pg in x.CurriedParameterGroups do - for p in pg do + let objMethodsCurriedParameterGroups = + [ for x in objEntity.MembersFunctionsAndValues do + for pg in x.CurriedParameterGroups do + for p in pg do yield x.CompiledName, p.Name, p.Type.ToString(), p.Type.Format(dtSymbol.DisplayContext) ] - objMethodsCurriedParameterGroups |> shouldEqual + objMethodsCurriedParameterGroups |> shouldEqual [("Equals", Some "obj", "type Microsoft.FSharp.Core.obj", "obj"); ("Equals", Some "objA", "type Microsoft.FSharp.Core.obj", "obj"); ("Equals", Some "objB", "type Microsoft.FSharp.Core.obj", "obj"); @@ -2236,13 +2248,13 @@ let ``Test Project13 all symbols`` () = ("ReferenceEquals", Some "objB", "type Microsoft.FSharp.Core.obj", "obj")] // check we can get the ReturnParameter - let objMethodsReturnParameter = - [ for x in objEntity.MembersFunctionsAndValues do - let p = x.ReturnParameter + let objMethodsReturnParameter = + [ for x in objEntity.MembersFunctionsAndValues do + let p = x.ReturnParameter yield x.DisplayName, p.Name, p.Type.ToString(), p.Type.Format(dtSymbol.DisplayContext) ] set objMethodsReturnParameter |> shouldEqual (set - [(".ctor", None, "type Microsoft.FSharp.Core.unit", "unit"); + [("``.ctor``", None, "type Microsoft.FSharp.Core.unit", "unit"); ("ToString", None, "type Microsoft.FSharp.Core.string", "string"); ("Equals", None, "type Microsoft.FSharp.Core.bool", "bool"); ("Equals", None, "type Microsoft.FSharp.Core.bool", "bool"); @@ -2253,20 +2265,20 @@ let ``Test Project13 all symbols`` () = ("MemberwiseClone", None, "type Microsoft.FSharp.Core.obj", "obj")]) // check we can get the CurriedParameterGroups - let dtMethodsCurriedParameterGroups = - [ for x in dtEntity.MembersFunctionsAndValues do - if x.CompiledName = "FromFileTime" || x.CompiledName = "AddMilliseconds" then - for pg in x.CurriedParameterGroups do - for p in pg do + let dtMethodsCurriedParameterGroups = + [ for x in dtEntity.MembersFunctionsAndValues do + if x.CompiledName = "FromFileTime" || x.CompiledName = "AddMilliseconds" then + for pg in x.CurriedParameterGroups do + for p in pg do yield x.CompiledName, p.Name, p.Type.ToString(), p.Type.Format(dtSymbol.DisplayContext) ] - dtMethodsCurriedParameterGroups |> shouldEqual + dtMethodsCurriedParameterGroups |> shouldEqual [("AddMilliseconds", Some "value", "type Microsoft.FSharp.Core.float","float"); ("FromFileTime", Some "fileTime", "type Microsoft.FSharp.Core.int64","int64")] let _test1 = [ for x in objEntity.MembersFunctionsAndValues -> x.FullType ] - for x in objEntity.MembersFunctionsAndValues do + for x in objEntity.MembersFunctionsAndValues do x.IsCompilerGenerated |> shouldEqual false x.IsExtensionMember |> shouldEqual false x.IsEvent |> shouldEqual false @@ -2281,24 +2293,24 @@ let ``Test Project13 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - structs -module internal Project14 = +module internal Project14 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Structs [] -type S(p:int) = +type S(p:int) = member x.P = p let x1 = S() let x2 = S(3) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -2308,23 +2320,23 @@ let x2 = S(3) [] -let ``Test Project14 whole project errors`` () = +let ``Test Project14 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project14.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project14.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project14 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project14 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project14.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project14.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project14.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project14.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su) allUsesOfAllSymbols |> shouldEqual [|("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), @@ -2336,37 +2348,37 @@ let ``Test Project14 all symbols`` () = ("S", "S", "file1", ((5, 5), (5, 6)), ["defn"]); ("int", "int", "file1", ((5, 9), (5, 12)), ["type"]); ("val p", "p", "file1", ((5, 7), (5, 8)), ["defn"]); - ("member .ctor", "( .ctor )", "file1", ((5, 5), (5, 6)), ["defn"]); + ("member .ctor", "``.ctor``", "file1", ((5, 5), (5, 6)), ["defn"]); ("member get_P", "P", "file1", ((6, 12), (6, 13)), ["defn"]); ("val x", "x", "file1", ((6, 10), (6, 11)), ["defn"]); ("val p", "p", "file1", ((6, 16), (6, 17)), []); - ("member .ctor", ".ctor", "file1", ((8, 10), (8, 11)), []); + ("member .ctor", "``.ctor``", "file1", ((8, 10), (8, 11)), []); ("val x1", "x1", "file1", ((8, 4), (8, 6)), ["defn"]); - ("member .ctor", ".ctor", "file1", ((9, 10), (9, 11)), []); + ("member .ctor", "``.ctor``", "file1", ((9, 10), (9, 11)), []); ("val x2", "x2", "file1", ((9, 4), (9, 6)), ["defn"]); ("Structs", "Structs", "file1", ((2, 7), (2, 14)), ["defn"])|] //----------------------------------------------------------------------------------------- // Misc - union patterns -module internal Project15 = +module internal Project15 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module UnionPatterns -let f x = - match x with - | [h] - | [_; h] - | [_; _; h] -> h +let f x = + match x with + | [h] + | [_; h] + | [_; _; h] -> h | _ -> 0 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -2376,23 +2388,23 @@ let f x = [] -let ``Test Project15 whole project errors`` () = +let ``Test Project15 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project15.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project15.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project15 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project15 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project15.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project15.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project15.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project15.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su) allUsesOfAllSymbols |> shouldEqual [|("val x", "x", "file1", ((4, 6), (4, 7)), ["defn"]); @@ -2408,44 +2420,44 @@ let ``Test Project15 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - signature files -module internal Project16 = +module internal Project16 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") let sigFileName1 = Path.ChangeExtension(fileName1, ".fsi") - let base2 = Path.GetTempFileName() + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ module Impl -type C() = +type C() = member x.PC = 1 -and D() = +and D() = member x.PD = 1 -and E() = +and E() = member x.PE = 1 and F = { Field1 : int; Field2 : int } and G = Case1 | Case2 of int """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let sigFileSource1Text = """ module Impl -type C = +type C = new : unit -> C member PC : int -and [] D = +and [] D = new : unit -> D member PD : int -and [] E = +and [] E = new : unit -> E member PE : int @@ -2453,8 +2465,8 @@ and F = { Field1 : int; Field2 : int } and G = Case1 | Case2 of int """ - let sigFileSource1 = FSharp.Compiler.Text.SourceText.ofString sigFileSource1Text - File.WriteAllText(sigFileName1, sigFileSource1Text) + let sigFileSource1 = SourceText.ofString sigFileSource1Text + FileSystem.OpenFileForWriteShim(sigFileName1).Write(sigFileSource1Text) let cleanFileName a = if a = fileName1 then "file1" elif a = sigFileName1 then "sig1" else "??" let fileNames = [sigFileName1; fileName1] @@ -2463,23 +2475,23 @@ and G = Case1 | Case2 of int [] -let ``Test Project16 whole project errors`` () = +let ``Test Project16 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project16 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project16 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project16.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project16.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), @@ -2509,7 +2521,7 @@ let ``Test Project16 all symbols`` () = ("C", "C", "sig1", ((4, 5), (4, 6)), ["defn"], ["class"]); ("unit", "unit", "sig1", ((5, 10), (5, 14)), ["type"], ["abbrev"]); ("C", "C", "sig1", ((5, 18), (5, 19)), ["type"], ["class"]); - ("member .ctor", "( .ctor )", "sig1", ((5, 4), (5, 7)), ["defn"], + ("member .ctor", "``.ctor``", "sig1", ((5, 4), (5, 7)), ["defn"], ["member"]); ("int", "int", "sig1", ((6, 16), (6, 19)), ["type"], ["abbrev"]); ("member get_PC", "PC", "sig1", ((6, 11), (6, 13)), ["defn"], @@ -2517,7 +2529,7 @@ let ``Test Project16 all symbols`` () = ("D", "D", "sig1", ((8, 14), (8, 15)), ["defn"], ["class"]); ("unit", "unit", "sig1", ((9, 10), (9, 14)), ["type"], ["abbrev"]); ("D", "D", "sig1", ((9, 18), (9, 19)), ["type"], ["class"]); - ("member .ctor", "( .ctor )", "sig1", ((9, 4), (9, 7)), ["defn"], + ("member .ctor", "``.ctor``", "sig1", ((9, 4), (9, 7)), ["defn"], ["member"]); ("int", "int", "sig1", ((10, 16), (10, 19)), ["type"], ["abbrev"]); ("member get_PD", "PD", "sig1", ((10, 11), (10, 13)), ["defn"], @@ -2525,7 +2537,7 @@ let ``Test Project16 all symbols`` () = ("E", "E", "sig1", ((12, 14), (12, 15)), ["defn"], ["class"]); ("unit", "unit", "sig1", ((13, 10), (13, 14)), ["type"], ["abbrev"]); ("E", "E", "sig1", ((13, 18), (13, 19)), ["type"], ["class"]); - ("member .ctor", "( .ctor )", "sig1", ((13, 4), (13, 7)), ["defn"], + ("member .ctor", "``.ctor``", "sig1", ((13, 4), (13, 7)), ["defn"], ["member"]); ("int", "int", "sig1", ((14, 16), (14, 19)), ["type"], ["abbrev"]); ("member get_PE", "PE", "sig1", ((14, 11), (14, 13)), ["defn"], @@ -2550,15 +2562,15 @@ let ``Test Project16 all symbols`` () = ("E", "E", "file1", ((10, 4), (10, 5)), ["defn"], ["class"]); ("F", "F", "file1", ((13, 4), (13, 5)), ["defn"], ["record"]); ("G", "G", "file1", ((14, 4), (14, 5)), ["defn"], ["union"]); - ("member .ctor", "( .ctor )", "file1", ((4, 5), (4, 6)), ["defn"], + ("member .ctor", "``.ctor``", "file1", ((4, 5), (4, 6)), ["defn"], ["member"; "ctor"]); ("member get_PC", "PC", "file1", ((5, 13), (5, 15)), ["defn"], ["member"; "getter"]); - ("member .ctor", "( .ctor )", "file1", ((7, 4), (7, 5)), ["defn"], + ("member .ctor", "``.ctor``", "file1", ((7, 4), (7, 5)), ["defn"], ["member"; "ctor"]); ("member get_PD", "PD", "file1", ((8, 13), (8, 15)), ["defn"], ["member"; "getter"]); - ("member .ctor", "( .ctor )", "file1", ((10, 4), (10, 5)), ["defn"], + ("member .ctor", "``.ctor``", "file1", ((10, 4), (10, 5)), ["defn"], ["member"; "ctor"]); ("member get_PE", "PE", "file1", ((11, 13), (11, 15)), ["defn"], ["member"; "getter"]); @@ -2570,44 +2582,44 @@ let ``Test Project16 all symbols`` () = [] let ``Test Project16 sig symbols are equal to impl symbols`` () = - let checkResultsSig = - checker.ParseAndCheckFileInProject(Project16.sigFileName1, 0, Project16.sigFileSource1, Project16.options) |> Async.RunSynchronously - |> function + let checkResultsSig = + checker.ParseAndCheckFileInProject(Project16.sigFileName1, 0, Project16.sigFileSource1, Project16.options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res - | _ -> failwithf "Parsing aborted unexpectedly..." + | _ -> failwithf "Parsing aborted unexpectedly..." - let checkResultsImpl = - checker.ParseAndCheckFileInProject(Project16.fileName1, 0, Project16.fileSource1, Project16.options) |> Async.RunSynchronously - |> function + let checkResultsImpl = + checker.ParseAndCheckFileInProject(Project16.fileName1, 0, Project16.fileSource1, Project16.options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res - | _ -> failwithf "Parsing aborted unexpectedly..." + | _ -> failwithf "Parsing aborted unexpectedly..." - let symbolsSig = checkResultsSig.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously - let symbolsImpl = checkResultsImpl.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously + let symbolsSig = checkResultsSig.GetAllUsesOfAllSymbolsInFile() + let symbolsImpl = checkResultsImpl.GetAllUsesOfAllSymbolsInFile() - // Test that all 'definition' symbols in the signature (or implementation) have a matching symbol in the + // Test that all 'definition' symbols in the signature (or implementation) have a matching symbol in the // implementation (or signature). - let testFind (tag1,symbols1) (tag2,symbols2) = - for (symUse1: FSharpSymbolUse) in symbols1 do + let testFind (tag1,symbols1) (tag2,symbols2) = + for symUse1: FSharpSymbolUse in symbols1 do - if symUse1.IsFromDefinition && - (match symUse1.Symbol with + if symUse1.IsFromDefinition && + (match symUse1.Symbol with | :? FSharpMemberOrFunctionOrValue as m -> m.IsModuleValueOrMember | :? FSharpEntity -> true | _ -> false) then - let ok = - symbols2 - |> Seq.filter (fun (symUse2:FSharpSymbolUse) -> - //if symUse2.IsFromDefinition && symUse1.Symbol.DisplayName = symUse2.Symbol.DisplayName then + let ok = + symbols2 + |> Seq.filter (fun (symUse2:FSharpSymbolUse) -> + //if symUse2.IsFromDefinition && symUse1.Symbol.DisplayName = symUse2.Symbol.DisplayName then // printfn "Comparing \n\t'%A' \n\t\t@ %A \n\t\t@@ %A and \n\t'%A' \n\t\t@ %A \n\t\t@@ %A" symUse1.Symbol symUse1.Symbol.ImplementationLocation symUse1.Symbol.SignatureLocation symUse2.Symbol symUse2.Symbol.ImplementationLocation symUse2.Symbol.SignatureLocation symUse2.Symbol.IsEffectivelySameAs(symUse1.Symbol) ) |> Seq.toList - match ok with + match ok with | [] -> failwith (sprintf "Didn't find symbol equivalent to %s symbol '%A' in %s" tag1 symUse1.Symbol tag2) - | [sym] -> () + | [sym] -> () | [sym1;sym2] when sym1.Symbol.DisplayName = sym2.Symbol.DisplayName -> () // constructor and type | syms -> failwith (sprintf "Found multiple symbols for %s '%A' in %s: '%A'" tag1 symUse1.Symbol tag2 [for sym in syms -> sym.Symbol ] ) @@ -2620,21 +2632,21 @@ let ``Test Project16 sig symbols are equal to impl symbols`` () = [] let ``Test Project16 sym locations`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) |> Async.RunImmediate - let fmtLoc (mOpt: Range.range option) = - match mOpt with + let fmtLoc (mOpt: range option) = + match mOpt with | None -> None - | Some m -> + | Some m -> let file = Project16.cleanFileName m.FileName if file = "??" then None else Some (file, (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn )) - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.choose (fun su -> - match fmtLoc su.Symbol.SignatureLocation, fmtLoc su.Symbol.DeclarationLocation, fmtLoc su.Symbol.ImplementationLocation with + + |> Array.choose (fun su -> + match fmtLoc su.Symbol.SignatureLocation, fmtLoc su.Symbol.DeclarationLocation, fmtLoc su.Symbol.ImplementationLocation with | Some a, Some b, Some c -> Some (su.Symbol.ToString(), a, b, c) | _ -> None) @@ -2682,23 +2694,23 @@ let ``Test Project16 sym locations`` () = let ``Test project16 DeclaringEntity`` () = let wholeProjectResults = checker.ParseAndCheckProject(Project16.options) - |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously + |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() for sym in allSymbolsUses do - match sym.Symbol with - | :? FSharpEntity as e when not e.IsNamespace || e.AccessPath.Contains(".") -> + match sym.Symbol with + | :? FSharpEntity as e when not e.IsNamespace || e.AccessPath.Contains(".") -> printfn "checking declaring type of entity '%s' --> '%s', assembly = '%s'" e.AccessPath e.CompiledName (e.Assembly.ToString()) shouldEqual e.DeclaringEntity.IsSome (e.AccessPath <> "global") - match e.AccessPath with - | "C" | "D" | "E" | "F" | "G" -> + match e.AccessPath with + | "C" | "D" | "E" | "F" | "G" -> shouldEqual e.AccessPath "Impl" shouldEqual e.DeclaringEntity.Value.IsFSharpModule true shouldEqual e.DeclaringEntity.Value.IsNamespace false - | "int" -> + | "int" -> shouldEqual e.AccessPath "Microsoft.FSharp.Core" shouldEqual e.DeclaringEntity.Value.AccessPath "Microsoft.FSharp" | _ -> () - | :? FSharpMemberOrFunctionOrValue as e when e.IsModuleValueOrMember -> + | :? FSharpMemberOrFunctionOrValue as e when e.IsModuleValueOrMember -> printfn "checking declaring type of value '%s', assembly = '%s'" e.CompiledName (e.Assembly.ToString()) shouldEqual e.DeclaringEntity.IsSome true | _ -> () @@ -2707,10 +2719,10 @@ let ``Test project16 DeclaringEntity`` () = //----------------------------------------------------------------------------------------- // Misc - namespace symbols -module internal Project17 = +module internal Project17 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2724,7 +2736,7 @@ let f2 (x: System.Collections.Generic.IList) = x.[3] <- 4 // check use of let f3 (x: System.Exception) = x.HelpLink <- "" // check use of .NET setter property """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -2733,25 +2745,25 @@ let f3 (x: System.Exception) = x.HelpLink <- "" // check use of .NET setter prop [] -let ``Test Project17 whole project errors`` () = +let ``Test Project17 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project17.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project17.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project17 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project17 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project17.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project17.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project17.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) - allUsesOfAllSymbols + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project17.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + allUsesOfAllSymbols |> shouldEqual [|("Microsoft", "Microsoft", "file1", ((4, 8), (4, 17)), [], ["namespace"]); ("Collections", "Collections", "file1", ((4, 25), (4, 36)), [], ["namespace"]); @@ -2799,10 +2811,10 @@ let ``Test Project17 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - generic type definnitions -module internal Project18 = +module internal Project18 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2810,7 +2822,7 @@ module Impl let _ = list<_>.Empty """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -2819,23 +2831,23 @@ let _ = list<_>.Empty [] -let ``Test Project18 whole project errors`` () = +let ``Test Project18 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project18.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project18.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project18 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project18 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project18.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project18.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project18.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project18.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, (match su.Symbol with :? FSharpEntity as e -> e.IsNamespace | _ -> false)) allUsesOfAllSymbols |> shouldEqual @@ -2849,10 +2861,10 @@ let ``Test Project18 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - enums -module internal Project19 = +module internal Project19 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -2866,7 +2878,7 @@ let f x = match x with Enum.EnumCase1 -> 1 | Enum.EnumCase2 -> 2 | _ -> 3 let s = System.DayOfWeek.Monday """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -2875,23 +2887,23 @@ let s = System.DayOfWeek.Monday [] -let ``Test Project19 whole project errors`` () = +let ``Test Project19 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project19.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project19.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project19 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project19 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project19.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project19.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project19.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project19.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("field EnumCase1", "EnumCase1", "file1", ((4, 14), (4, 23)), ["defn"], @@ -2927,20 +2939,20 @@ let ``Test Project19 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - https://github.com/fsharp/FSharp.Compiler.Service/issues/109 -module internal Project20 = +module internal Project20 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Impl -type A<'T>() = +type A<'T>() = member x.M() : 'T = failwith "" """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -2949,28 +2961,28 @@ type A<'T>() = [] -let ``Test Project20 whole project errors`` () = +let ``Test Project20 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project20.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project20.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project20 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project20 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project20.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project20.options) |> Async.RunImmediate - let tSymbolUse = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.RangeAlternate.StartLine = 5 && su.Symbol.ToString() = "generic parameter T") + let tSymbolUse = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Range.StartLine = 5 && su.Symbol.ToString() = "generic parameter T") let tSymbol = tSymbolUse.Symbol - let allUsesOfTSymbol = + let allUsesOfTSymbol = wholeProjectResults.GetUsesOfSymbol(tSymbol) - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project20.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project20.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfTSymbol |> shouldEqual [|("generic parameter T", "T", "file1", ((4, 7), (4, 9)), ["type"], []); @@ -2979,29 +2991,29 @@ let ``Test Project20 all symbols`` () = //----------------------------------------------------------------------------------------- // Misc - https://github.com/fsharp/FSharp.Compiler.Service/issues/137 -module internal Project21 = +module internal Project21 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Impl -type IMyInterface<'a> = +type IMyInterface<'a> = abstract Method1: 'a -> unit abstract Method2: 'a -> unit let _ = { new IMyInterface with - member x.Method1(arg1: string): unit = + member x.Method1(arg1: string): unit = raise (System.NotImplementedException()) - member x.Method2(arg1: int): unit = + member x.Method2(arg1: int): unit = raise (System.NotImplementedException()) } """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -3010,23 +3022,23 @@ let _ = { new IMyInterface with [] -let ``Test Project21 whole project errors`` () = +let ``Test Project21 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project21.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project21.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project21 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 2 + wholeProjectResults.Diagnostics.Length |> shouldEqual 2 [] let ``Test Project21 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project21.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project21.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project21.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project21.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual [|("generic parameter a", "a", "file1", ((4, 18), (4, 20)), ["type"], []); @@ -3051,22 +3063,22 @@ let ``Test Project21 all symbols`` () = ("unit", "unit", "file1", ((12, 43), (12, 47)), ["type"], ["abbrev"]); ("val raise", "raise", "file1", ((13, 18), (13, 23)), [], ["val"]); ("System", "System", "file1", ((13, 25), (13, 31)), [], ["namespace"]); - ("member .ctor", ".ctor", "file1", ((13, 25), (13, 55)), [], ["member"]); + ("member .ctor", "``.ctor``", "file1", ((13, 25), (13, 55)), [], ["member"]); ("Impl", "Impl", "file1", ((2, 7), (2, 11)), ["defn"], ["module"])|] //----------------------------------------------------------------------------------------- // Misc - namespace symbols -module internal Project22 = +module internal Project22 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Impl -type AnotherMutableList() = +type AnotherMutableList() = member x.Item with get() = 3 and set (v:int) = () let f1 (x: System.Collections.Generic.IList<'T>) = () // grab the IList symbol and look into it @@ -3075,7 +3087,7 @@ let f3 (x: System.Collections.ObjectModel.ObservableCollection<'T>) = () // grab let f4 (x: int[]) = () // test a one-dimensional array let f5 (x: int[,,]) = () // test a multi-dimensional array """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -3085,32 +3097,32 @@ let f5 (x: int[,,]) = () // test a multi-dimensional array [] -let ``Test Project22 whole project errors`` () = +let ``Test Project22 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project22 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project22 IList contents`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - let ilistTypeUse = + + let ilistTypeUse = allUsesOfAllSymbols |> Array.find (fun su -> su.Symbol.DisplayName = "IList") - let ocTypeUse = + let ocTypeUse = allUsesOfAllSymbols |> Array.find (fun su -> su.Symbol.DisplayName = "ObservableCollection") - let alistTypeUse = + let alistTypeUse = allUsesOfAllSymbols |> Array.find (fun su -> su.Symbol.DisplayName = "AnotherMutableList") @@ -3120,7 +3132,7 @@ let ``Test Project22 IList contents`` () = let arrayTypes = allTypes - |> Array.choose (fun t -> + |> Array.choose (fun t -> if t.HasTypeDefinition then let td = t.TypeDefinition if td.IsArrayType then Some (td.DisplayName, td.ArrayRank) else None @@ -3133,39 +3145,39 @@ let ``Test Project22 IList contents`` () = set [ for x in ilistTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] |> shouldEqual (set [("get_Item", ["slot"; "member"; "getter"]); - ("set_Item", ["slot"; "member"; "setter"]); + ("set_Item", ["slot"; "member"; "setter"]); ("IndexOf", ["slot"; "member"]); - ("Insert", ["slot"; "member"]); + ("Insert", ["slot"; "member"]); ("RemoveAt", ["slot"; "member"]); ("Item", ["slot"; "member"; "prop"])]) set [ for x in ocTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] |> shouldEqual - (set [(".ctor", ["member"]); - (".ctor", ["member"]); + (set [(".ctor", ["member"]); + (".ctor", ["member"]); (".ctor", ["member"]); - ("Move", ["member"]); + ("Move", ["member"]); ("add_CollectionChanged", ["slot"; "member"; "add"]); ("remove_CollectionChanged", ["slot"; "member"; "remove"]); - ("ClearItems", ["slot"; "member"]); + ("ClearItems", ["slot"; "member"]); ("RemoveItem", ["slot"; "member"]); - ("InsertItem", ["slot"; "member"]); + ("InsertItem", ["slot"; "member"]); ("SetItem", ["slot"; "member"]); - ("MoveItem", ["slot"; "member"]); + ("MoveItem", ["slot"; "member"]); ("OnPropertyChanged", ["slot"; "member"]); ("add_PropertyChanged", ["slot"; "member"; "add"]); ("remove_PropertyChanged", ["slot"; "member"; "remove"]); ("OnCollectionChanged", ["slot"; "member"]); - ("BlockReentrancy", ["member"]); + ("BlockReentrancy", ["member"]); ("CheckReentrancy", ["member"]); ("CollectionChanged", ["slot"; "member"; "event"]); ("PropertyChanged", ["slot"; "member"; "event"])]) set [ for x in alistTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] |> shouldEqual - (set [(".ctor", ["member"; "ctor"]); + (set [(".ctor", ["member"; "ctor"]); ("get_Item", ["member"; "getter"]); - ("set_Item", ["member"; "setter"]); + ("set_Item", ["member"; "setter"]); ("Item", ["member"; "prop"])]) set [ for x in ilistTypeDefn.AllInterfaces -> x.TypeDefinition.DisplayName, attribsOfSymbol x.TypeDefinition ] @@ -3178,11 +3190,11 @@ let ``Test Project22 IList contents`` () = [] let ``Test Project22 IList properties`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project22.options) |> Async.RunImmediate - let ilistTypeUse = + let ilistTypeUse = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously + |> Array.find (fun su -> su.Symbol.DisplayName = "IList") let ilistTypeDefn = ilistTypeUse.Symbol :?> FSharpEntity @@ -3196,10 +3208,10 @@ let ``Test Project22 IList properties`` () = //----------------------------------------------------------------------------------------- // Misc - properties -module internal Project23 = +module internal Project23 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3212,7 +3224,7 @@ type Class() = module Getter = type System.Int32 with static member Zero = 0 - member x.Value = 0 + member x.Value = 0 let _ = 0 .Value @@ -3222,7 +3234,7 @@ module Setter = 0 .Value <- 0 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -3230,44 +3242,47 @@ module Setter = let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] -let ``Test Project23 whole project errors`` () = +let ``Test Project23 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project23 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project23 property`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - + let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let classTypeUse = allSymbolsUses |> Array.find (fun su -> su.Symbol.DisplayName = "Class") let classTypeDefn = classTypeUse.Symbol :?> FSharpEntity - [ for x in classTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] - |> shouldEqual - [(".ctor", ["member"; "ctor"]); - ("get_Property", ["member"; "getter"]); - ("get_StaticProperty", ["member"; "getter"]); - ("StaticProperty", ["member"; "prop"]); - ("Property", ["member"; "prop"])] + let results = [ for x in classTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] + [(".ctor", ["member"; "ctor"]); + ("get_Property", ["member"; "getter"]); + ("get_StaticProperty", ["member"; "getter"]); + ("StaticProperty", ["member"; "prop"]); + ("Property", ["member"; "prop"])] + |> List.iter (fun x -> + if results |> List.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) let getterModuleUse = allSymbolsUses |> Array.find (fun su -> su.Symbol.DisplayName = "Getter") let getterModuleDefn = getterModuleUse.Symbol :?> FSharpEntity [ for x in getterModuleDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] - |> shouldEqual + |> shouldEqual [("get_Zero", ["member"; "extmem"; "getter"]); ("Zero", ["member"; "prop"; "extmem"]); ("get_Value", ["member"; "extmem"; "getter"]); ("Value", ["member"; "prop"; "extmem"])] let extensionProps = getterModuleDefn.MembersFunctionsAndValues |> Seq.toArray |> Array.filter (fun su -> su.LogicalName = "Value" || su.LogicalName = "Zero" ) - let extensionPropsRelated = + let extensionPropsRelated = extensionProps - |> Array.collect (fun f -> + |> Array.collect (fun f -> [| if f.HasGetterMethod then yield (f.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.GetterMethod.CompiledName, f.GetterMethod.DeclaringEntity.Value.FullName, attribsOfSymbol f) if f.HasSetterMethod then @@ -3279,59 +3294,58 @@ let ``Test Project23 property`` () = [("Impl.Getter", "System.Int32", "Int32.get_Zero.Static", "Impl.Getter", ["member"; "prop"; "extmem"]); ("Impl.Getter", "System.Int32", "Int32.get_Value", "Impl.Getter", - ["member"; "prop"; "extmem"])] + ["member"; "prop"; "extmem"])] - allSymbolsUses + allSymbolsUses |> Array.map (fun x -> x.Symbol) - |> Array.choose (function + |> Array.choose (function | :? FSharpMemberOrFunctionOrValue as f -> Some (f.LogicalName, attribsOfSymbol f) | _ -> None) |> Array.toList - |> shouldEqual - [(".ctor", ["member"; "ctor"]); + |> shouldEqual + [(".ctor", ["member"; "ctor"]); ("get_StaticProperty", ["member"; "getter"]); - ("get_Property", ["member"; "getter"]); + ("get_Property", ["member"; "getter"]); ("x", []); ("get_Zero", ["member"; "extmem"; "getter"]); - ("get_Value", ["member"; "extmem"; "getter"]); + ("get_Value", ["member"; "extmem"; "getter"]); ("x", []); ("Value", ["member"; "prop"; "extmem"]); - ("set_Value", ["member"; "extmem"; "setter"]); + ("set_Value", ["member"; "extmem"; "setter"]); ("x", []); - ("_arg1", ["compgen"]); ("Value", ["member"; "prop"; "extmem"])] [] let ``Test Project23 extension properties' getters/setters should refer to the correct declaring entities`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project23.options) |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() let extensionMembers = allSymbolsUses |> Array.rev |> Array.filter (fun su -> su.Symbol.DisplayName = "Value") extensionMembers - |> Array.collect (fun memb -> wholeProjectResults.GetUsesOfSymbol(memb.Symbol) |> Async.RunSynchronously) - |> Array.collect (fun x -> + |> Array.collect (fun memb -> wholeProjectResults.GetUsesOfSymbol(memb.Symbol) ) + |> Array.collect (fun x -> [| match x.Symbol with - | :? FSharpMemberOrFunctionOrValue as f -> + | :? FSharpMemberOrFunctionOrValue as f -> if f.HasGetterMethod then yield (f.DeclaringEntity.Value.FullName, f.GetterMethod.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.GetterMethod.ApparentEnclosingEntity.FullName, attribsOfSymbol f) if f.HasSetterMethod then yield (f.DeclaringEntity.Value.FullName, f.SetterMethod.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.SetterMethod.ApparentEnclosingEntity.FullName, attribsOfSymbol f) - | _ -> () + | _ -> () |]) |> Array.toList - |> shouldEqual + |> shouldEqual [ ("Impl.Setter", "Impl.Setter", "System.Int32", "System.Int32", ["member"; "prop"; "extmem"]); ("Impl.Setter", "Impl.Setter", "System.Int32", "System.Int32", ["member"; "prop"; "extmem"]); ("Impl.Getter", "Impl.Getter", "System.Int32", "System.Int32", ["member"; "prop"; "extmem"]) ("Impl.Getter", "Impl.Getter", "System.Int32", "System.Int32", ["member"; "prop"; "extmem"]) ] // Misc - property symbols -module internal Project24 = +module internal Project24 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3366,21 +3380,21 @@ type TypeWithProperties() = static member val StaticAutoPropGet = 0 with get static member val StaticAutoPropGetSet = 0 with get, set -let v1 = TypeWithProperties().NameGetSet +let v1 = TypeWithProperties().NameGetSet TypeWithProperties().NameGetSet <- 3 let v2 = TypeWithProperties().NameGet TypeWithProperties().NameSet <- 3 -let v3 = TypeWithProperties.StaticNameGetSet +let v3 = TypeWithProperties.StaticNameGetSet TypeWithProperties.StaticNameGetSet <- 3 let v4 = TypeWithProperties.StaticNameGet TypeWithProperties.StaticNameSet <- 3 -let v5 = TypeWithProperties().AutoPropGet +let v5 = TypeWithProperties().AutoPropGet let v6 = TypeWithProperties().AutoPropGetSet TypeWithProperties().AutoPropGetSet <- 3 @@ -3391,35 +3405,35 @@ let v8 = TypeWithProperties.StaticAutoPropGetSet TypeWithProperties.StaticAutoPropGetSet <- 3 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] - let args = mkProjectCommandLineArgs (dllName, fileNames) + let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] -let ``Test Project24 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do +let ``Test Project24 whole project errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project24 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] -let ``Test Project24 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project24.fileName1, Project24.options) - |> Async.RunSynchronously - - let allUses = - backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun s -> (s.Symbol.DisplayName, Project24.cleanFileName s.FileName, tups s.RangeAlternate, attribsOfSymbolUse s, attribsOfSymbol s.Symbol)) - - allUses |> shouldEqual +let ``Test Project24 all symbols`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project24.fileName1, Project24.options) + |> Async.RunImmediate + + let allUses = + backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() + |> Array.ofSeq + |> Array.map (fun s -> (s.Symbol.DisplayName, Project24.cleanFileName s.FileName, tups s.Range, attribsOfSymbolUse s, attribsOfSymbol s.Symbol)) + + allUses |> shouldEqual [|("TypeWithProperties", "file1", ((4, 5), (4, 23)), ["defn"], ["class"]); - ("( .ctor )", "file1", ((4, 5), (4, 23)), ["defn"], ["member"; "ctor"]); + ("``.ctor``", "file1", ((4, 5), (4, 23)), ["defn"], ["member"; "ctor"]); ("NameGetSet", "file1", ((5, 13), (5, 23)), ["defn"], ["member"; "getter"]); ("int", "file1", ((7, 20), (7, 23)), ["type"], ["abbrev"]); ("NameGet", "file1", ((9, 13), (9, 20)), ["defn"], ["member"; "getter"]); @@ -3458,13 +3472,13 @@ let ``Test Project24 all symbols`` () = ("v", "file1", ((22, 17), (22, 18)), ["defn"], []); ("int", "file1", ((25, 21), (25, 24)), ["type"], ["abbrev"]); ("v", "file1", ((25, 18), (25, 19)), ["defn"], []); - ("( AutoPropGet@ )", "file1", ((27, 15), (27, 26)), [], ["compgen"]); - ("( AutoPropGetSet@ )", "file1", ((28, 15), (28, 29)), [], ["compgen";"mutable"]); + ("``AutoPropGet@``", "file1", ((27, 15), (27, 26)), [], ["compgen"]); + ("``AutoPropGetSet@``", "file1", ((28, 15), (28, 29)), [], ["compgen";"mutable"]); ("v", "file1", ((28, 15), (28, 29)), ["defn"], []); - ("( StaticAutoPropGet@ )", "file1", ((30, 22), (30, 39)), [], ["compgen"]); - ("( StaticAutoPropGetSet@ )", "file1", ((31, 22), (31, 42)), [], + ("``StaticAutoPropGet@``", "file1", ((30, 22), (30, 39)), [], ["compgen"]); + ("``StaticAutoPropGetSet@``", "file1", ((31, 22), (31, 42)), [], ["compgen";"mutable"]); ("v", "file1", ((31, 22), (31, 42)), ["defn"], []); - ("( .cctor )", "file1", ((4, 5), (4, 23)), ["defn"], ["member"]); + ("``.cctor``", "file1", ((4, 5), (4, 23)), ["defn"], ["member"]); ("TypeWithProperties", "file1", ((33, 9), (33, 27)), [], ["member"; "ctor"]); ("NameGetSet", "file1", ((33, 9), (33, 40)), [], ["member"; "prop"]); @@ -3513,20 +3527,20 @@ let ``Test Project24 all symbols`` () = ("PropertyTest", "file1", ((2, 7), (2, 19)), ["defn"], ["module"])|] [] -let ``Test symbol uses of properties with both getters and setters`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project24.fileName1, Project24.options) - |> Async.RunSynchronously +let ``Test symbol uses of properties with both getters and setters`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project24.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project24.fileName1, Project24.options) + |> Async.RunImmediate - let getAllSymbolUses = - backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun s -> (s.Symbol.DisplayName, Project24.cleanFileName s.FileName, tups s.RangeAlternate, attribsOfSymbol s.Symbol)) + let getAllSymbolUses = + backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() + |> Array.ofSeq + |> Array.map (fun s -> (s.Symbol.DisplayName, Project24.cleanFileName s.FileName, tups s.Range, attribsOfSymbol s.Symbol)) getAllSymbolUses |> shouldEqual [|("TypeWithProperties", "file1", ((4, 5), (4, 23)), ["class"]); - ("( .ctor )", "file1", ((4, 5), (4, 23)), ["member"; "ctor"]); + ("``.ctor``", "file1", ((4, 5), (4, 23)), ["member"; "ctor"]); ("NameGetSet", "file1", ((5, 13), (5, 23)), ["member"; "getter"]); ("int", "file1", ((7, 20), (7, 23)), ["abbrev"]); ("NameGet", "file1", ((9, 13), (9, 20)), ["member"; "getter"]); @@ -3559,13 +3573,13 @@ let ``Test symbol uses of properties with both getters and setters`` () = ("v", "file1", ((22, 17), (22, 18)), []); ("int", "file1", ((25, 21), (25, 24)), ["abbrev"]); ("v", "file1", ((25, 18), (25, 19)), []); - ("( AutoPropGet@ )", "file1", ((27, 15), (27, 26)), ["compgen"]); - ("( AutoPropGetSet@ )", "file1", ((28, 15), (28, 29)), ["compgen";"mutable"]); + ("``AutoPropGet@``", "file1", ((27, 15), (27, 26)), ["compgen"]); + ("``AutoPropGetSet@``", "file1", ((28, 15), (28, 29)), ["compgen";"mutable"]); ("v", "file1", ((28, 15), (28, 29)), []); - ("( StaticAutoPropGet@ )", "file1", ((30, 22), (30, 39)), ["compgen"]); - ("( StaticAutoPropGetSet@ )", "file1", ((31, 22), (31, 42)), ["compgen";"mutable"]); + ("``StaticAutoPropGet@``", "file1", ((30, 22), (30, 39)), ["compgen"]); + ("``StaticAutoPropGetSet@``", "file1", ((31, 22), (31, 42)), ["compgen";"mutable"]); ("v", "file1", ((31, 22), (31, 42)), []); - ("( .cctor )", "file1", ((4, 5), (4, 23)), ["member"]); + ("``.cctor``", "file1", ((4, 5), (4, 23)), ["member"]); ("TypeWithProperties", "file1", ((33, 9), (33, 27)), ["member"; "ctor"]); ("NameGetSet", "file1", ((33, 9), (33, 40)), ["member"; "prop"]); ("v1", "file1", ((33, 4), (33, 6)), ["val"]); @@ -3604,26 +3618,26 @@ let ``Test symbol uses of properties with both getters and setters`` () = ("StaticAutoPropGetSet", "file1", ((55, 0), (55, 39)), ["member"; "prop"]); ("PropertyTest", "file1", ((2, 7), (2, 19)), ["module"])|] - let getSampleSymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(9,20,"",["NameGet"]) - |> Async.RunSynchronously + let getSampleSymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(9,20,"",["NameGet"]) + let getSampleSymbol = getSampleSymbolUseOpt.Value.Symbol - - let usesOfGetSampleSymbol = - backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) - |> Async.RunSynchronously - |> Array.map (fun s -> (Project24.cleanFileName s.FileName, tups s.RangeAlternate)) + + let usesOfGetSampleSymbol = + backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) + + |> Array.map (fun s -> (Project24.cleanFileName s.FileName, tups s.Range)) usesOfGetSampleSymbol |> shouldEqual [|("file1", ((9, 13), (9, 20))); ("file1", ((36, 9), (36, 37)))|] #if NO_CHECK_USE_OF_FSHARP_DATA_DLL #endif // Misc - type provider symbols -module internal Project25 = +module internal Project25 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3637,12 +3651,12 @@ let r = { Record.Field = 1 } let _ = XmlProvider<"13">.GetSample() """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] - let args = - [| yield! mkProjectCommandLineArgs (dllName, fileNames) + let args = + [| yield! mkProjectCommandLineArgs (dllName, fileNames) yield @"-r:" + Path.Combine(__SOURCE_DIRECTORY__, Path.Combine("data", "FSharp.Data.dll")) yield @"-r:" + sysLib "System.Xml.Linq" |] let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) @@ -3651,28 +3665,28 @@ let _ = XmlProvider<"13">.GetSample() #if NETCOREAPP [] #endif -let ``Test Project25 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do +let ``Test Project25 whole project errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project25 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] #if NETCOREAPP [] #endif -let ``Test Project25 symbol uses of type-provided members`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) - |> Async.RunSynchronously +let ``Test Project25 symbol uses of type-provided members`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) + |> Async.RunImmediate - let allUses = - backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.map (fun s -> (s.Symbol.FullName, Project25.cleanFileName s.FileName, tups s.RangeAlternate, attribsOfSymbol s.Symbol)) + let allUses = + backgroundTypedParse1.GetAllUsesOfAllSymbolsInFile() + |> Array.ofSeq + |> Array.map (fun s -> (s.Symbol.FullName, Project25.cleanFileName s.FileName, tups s.Range, attribsOfSymbol s.Symbol)) - allUses |> shouldEqual + allUses |> shouldEqual [|("FSharp", "file1", ((3, 5), (3, 11)), ["namespace"]); ("FSharp.Data", "file1", ((3, 12), (3, 16)), ["namespace"; "provided"]); @@ -3703,16 +3717,16 @@ let ``Test Project25 symbol uses of type-provided members`` () = ["class"; "provided"; "staticinst"; "erased"]); ("FSharp.Data.XmlProvider<...>.GetSample", "file1", ((10, 8), (10, 78)), ["member"]); ("TypeProviderTests", "file1", ((2, 7), (2, 24)), ["module"])|] - let getSampleSymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(5,25,"",["GetSample"]) - |> Async.RunSynchronously + let getSampleSymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(5,25,"",["GetSample"]) + let getSampleSymbol = getSampleSymbolUseOpt.Value.Symbol - - let usesOfGetSampleSymbol = - backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) - |> Async.RunSynchronously - |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.RangeAlternate)) + + let usesOfGetSampleSymbol = + backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) + + |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.Range)) usesOfGetSampleSymbol |> shouldEqual [|("file1", ((5, 8), (5, 25))); ("file1", ((10, 8), (10, 78)))|] @@ -3720,50 +3734,50 @@ let ``Test Project25 symbol uses of type-provided members`` () = #if NETCOREAPP [] #endif -let ``Test symbol uses of type-provided types`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) - |> Async.RunSynchronously +let ``Test symbol uses of type-provided types`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) + |> Async.RunImmediate + + let getSampleSymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(4,26,"",["XmlProvider"]) - let getSampleSymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(4,26,"",["XmlProvider"]) - |> Async.RunSynchronously let getSampleSymbol = getSampleSymbolUseOpt.Value.Symbol - - let usesOfGetSampleSymbol = - backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) - |> Async.RunSynchronously - |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.RangeAlternate)) + + let usesOfGetSampleSymbol = + backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) + + |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.Range)) usesOfGetSampleSymbol |> shouldEqual [|("file1", ((4, 15), (4, 26))); ("file1", ((10, 8), (10, 19)))|] [] -let ``Test symbol uses of fully-qualified records`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunSynchronously - let backgroundParseResults1, backgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) - |> Async.RunSynchronously +let ``Test symbol uses of fully-qualified records`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project25.options) |> Async.RunImmediate + let backgroundParseResults1, backgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project25.fileName1, Project25.options) + |> Async.RunImmediate + + let getSampleSymbolUseOpt = + backgroundTypedParse1.GetSymbolUseAtLocation(7,11,"",["Record"]) - let getSampleSymbolUseOpt = - backgroundTypedParse1.GetSymbolUseAtLocation(7,11,"",["Record"]) - |> Async.RunSynchronously let getSampleSymbol = getSampleSymbolUseOpt.Value.Symbol - - let usesOfGetSampleSymbol = - backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) - |> Async.RunSynchronously - |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.RangeAlternate)) + + let usesOfGetSampleSymbol = + backgroundTypedParse1.GetUsesOfSymbolInFile(getSampleSymbol) + + |> Array.map (fun s -> (Project25.cleanFileName s.FileName, tups s.Range)) usesOfGetSampleSymbol |> shouldEqual [|("file1", ((7, 5), (7, 11))); ("file1", ((8, 10), (8, 16)))|] -module internal Project26 = +module internal Project26 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3776,7 +3790,7 @@ type Class() = member x.M2([] arg1, [] arg2) = () member x.M3([] arg: byref) = () """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" @@ -3786,37 +3800,37 @@ type Class() = [] -let ``Test Project26 whole project errors`` () = +let ``Test Project26 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project26.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project26.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project26 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project26 parameter symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project26.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project26.options) |> Async.RunImmediate - let allUsesOfAllSymbols = + let allUsesOfAllSymbols = wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously - |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project13.cleanFileName su.FileName, tups su.RangeAlternate, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) + |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project13.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Class") + + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Class") let objEntity = objSymbol.Symbol :?> FSharpEntity - - let rec isByRef (ty: FSharpType) = - if ty.IsAbbreviation then isByRef ty.AbbreviatedType - else ty.IsNamedType && ty.NamedEntity.IsByRef + + let rec isByRef (ty: FSharpType) = + if ty.IsAbbreviation then isByRef ty.AbbreviatedType + else ty.HasTypeDefinition && ty.TypeDefinition.IsByRef // check we can get the CurriedParameterGroups - let objMethodsCurriedParameterGroups = - [ for x in objEntity.MembersFunctionsAndValues do - for pg in x.CurriedParameterGroups do + let objMethodsCurriedParameterGroups = + [ for x in objEntity.MembersFunctionsAndValues do + for pg in x.CurriedParameterGroups do for p in pg do - let attributeNames = + let attributeNames = seq { if p.IsParamArrayArg then yield "params" if p.IsOutArg then yield "out" @@ -3825,7 +3839,7 @@ let ``Test Project26 parameter symbols`` () = |> String.concat "," yield x.CompiledName, p.Name, p.Type.ToString(), isByRef p.Type, attributeNames ] - objMethodsCurriedParameterGroups |> shouldEqual + objMethodsCurriedParameterGroups |> shouldEqual [("M1", Some "arg1", "type 'c", false, ""); ("M1", Some "arg2", "type 'd Microsoft.FSharp.Core.option", false, "optional"); ("M2", Some "arg1", "type 'a", false, "params"); @@ -3833,10 +3847,10 @@ let ``Test Project26 parameter symbols`` () = ("M3", Some "arg", "type Microsoft.FSharp.Core.byref", true, "out")] // check we can get the ReturnParameter - let objMethodsReturnParameter = - [ for x in objEntity.MembersFunctionsAndValues do - let p = x.ReturnParameter - let attributeNames = + let objMethodsReturnParameter = + [ for x in objEntity.MembersFunctionsAndValues do + let p = x.ReturnParameter + let attributeNames = seq { if p.IsParamArrayArg then yield "params" if p.IsOutArg then yield "out" @@ -3846,15 +3860,15 @@ let ``Test Project26 parameter symbols`` () = yield x.DisplayName, p.Name, p.Type.ToString(), attributeNames ] set objMethodsReturnParameter |> shouldEqual (set - [("( .ctor )", None, "type FSharpParameter.Class", ""); + [("``.ctor``", None, "type FSharpParameter.Class", ""); ("M1", None, "type Microsoft.FSharp.Core.unit", ""); ("M2", None, "type Microsoft.FSharp.Core.unit", ""); ("M3", None, "type Microsoft.FSharp.Core.unit", "")]) -module internal Project27 = +module internal Project27 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3862,44 +3876,44 @@ module M type CFoo() = abstract AbstractMethod: int -> string - default __.AbstractMethod _ = "dflt" - + default _.AbstractMethod _ = "dflt" + type CFooImpl() = inherit CFoo() - override __.AbstractMethod _ = "v" + override _.AbstractMethod _ = "v" """ - File.WriteAllText(fileName1, fileSource1) - + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) + let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] -let ``Test project27 whole project errors`` () = +let ``Test project27 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project27.options) |> Async.RunSynchronously - wholeProjectResults .Errors.Length |> shouldEqual 0 + let wholeProjectResults = checker.ParseAndCheckProject(Project27.options) |> Async.RunImmediate + wholeProjectResults .Diagnostics.Length |> shouldEqual 0 [] -let ``Test project27 all symbols in signature`` () = +let ``Test project27 all symbols in signature`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project27.options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project27.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] - |> shouldEqual - [("M", ["module"]); - ("CFoo", ["class"]); + [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] + |> shouldEqual + [("M", ["module"]); + ("CFoo", ["class"]); ("member .ctor", ["member"; "ctor"]); ("member AbstractMethod", ["slot"; "member"]); - ("member AbstractMethod", ["member"; "overridemem"]); + ("member AbstractMethod", ["member"; "overridemem"]); ("CFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); ("member AbstractMethod", ["member"; "overridemem"])] -module internal Project28 = +module internal Project28 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -3933,15 +3947,15 @@ type Use() = member x.Test number = TestNumber 42 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) #if !NO_EXTENSIONTYPING [] -let ``Test project28 all symbols in signature`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project28.options) |> Async.RunSynchronously +let ``Test project28 all symbols in signature`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project28.options) |> Async.RunImmediate let allSymbols = allSymbolsInEntities true wholeProjectResults.AssemblySignature.Entities let xmlDocSigs = allSymbols @@ -3963,53 +3977,55 @@ let ``Test project28 all symbols in signature`` () = | _ -> typeName, s.DisplayName, "unknown") |> Seq.toArray - xmlDocSigs - |> shouldEqual - [|("FSharpEntity", "M", "T:M"); - ("FSharpMemberOrFunctionOrValue", "( |Even|Odd| )", "M:M.|Even|Odd|(System.Int32)"); - ("FSharpMemberOrFunctionOrValue", "TestNumber", "M:M.TestNumber(System.Int32)"); - ("FSharpEntity", "DU", "T:M.DU"); - ("FSharpUnionCase", "A", "T:M.DU.A"); - ("FSharpField", "A", "T:M.DU.A"); - ("FSharpUnionCase", "B", "T:M.DU.B"); - ("FSharpField", "B", "T:M.DU.B"); - ("FSharpEntity", "XmlDocSigTest", "T:M.XmlDocSigTest"); - ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.XmlDocSigTest.#ctor"); - ("FSharpMemberOrFunctionOrValue", "AMethod", "M:M.XmlDocSigTest.AMethod"); - ("FSharpMemberOrFunctionOrValue", "AnotherMethod", "M:M.XmlDocSigTest.AnotherMethod"); - ("FSharpMemberOrFunctionOrValue", "TestEvent1", "M:M.XmlDocSigTest.TestEvent1(System.Object)"); - ("FSharpMemberOrFunctionOrValue", "TestEvent2", "M:M.XmlDocSigTest.TestEvent2(System.Object)"); - ("FSharpMemberOrFunctionOrValue", "add_AnEvent", "M:M.XmlDocSigTest.add_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); - ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); - ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); - ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); - ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); - ("FSharpMemberOrFunctionOrValue", "remove_AnEvent", "M:M.XmlDocSigTest.remove_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); - ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); - ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); - ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); - ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); - ("FSharpField", "event1", "P:M.XmlDocSigTest.event1"); - ("FSharpField", "event2", "P:M.XmlDocSigTest.event2"); - ("FSharpField", "aString", "P:M.XmlDocSigTest.aString"); - ("FSharpField", "anInt", "P:M.XmlDocSigTest.anInt"); - ("FSharpEntity", "Use", "T:M.Use"); - ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.Use.#ctor"); - ("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)"); - ("FSharpGenericParameter", "?", "")|] + [|("FSharpEntity", "M", "T:M"); + ("FSharpMemberOrFunctionOrValue", "(|Even|Odd|)", "M:M.|Even|Odd|(System.Int32)"); + ("FSharpMemberOrFunctionOrValue", "TestNumber", "M:M.TestNumber(System.Int32)"); + ("FSharpEntity", "DU", "T:M.DU"); + ("FSharpUnionCase", "A", "T:M.DU.A"); + ("FSharpField", "Item", "T:M.DU.A"); + ("FSharpUnionCase", "B", "T:M.DU.B"); + ("FSharpField", "Item", "T:M.DU.B"); + ("FSharpEntity", "XmlDocSigTest", "T:M.XmlDocSigTest"); + ("FSharpMemberOrFunctionOrValue", "``.ctor``", "M:M.XmlDocSigTest.#ctor"); + ("FSharpMemberOrFunctionOrValue", "AMethod", "M:M.XmlDocSigTest.AMethod"); + ("FSharpMemberOrFunctionOrValue", "AnotherMethod", "M:M.XmlDocSigTest.AnotherMethod"); + ("FSharpMemberOrFunctionOrValue", "TestEvent1", "M:M.XmlDocSigTest.TestEvent1(System.Object)"); + ("FSharpMemberOrFunctionOrValue", "TestEvent2", "M:M.XmlDocSigTest.TestEvent2(System.Object)"); + ("FSharpMemberOrFunctionOrValue", "add_AnEvent", "M:M.XmlDocSigTest.add_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); + ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); + ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); + ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); + ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); + ("FSharpMemberOrFunctionOrValue", "remove_AnEvent", "M:M.XmlDocSigTest.remove_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); + ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); + ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); + ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); + ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); + ("FSharpField", "event1", "P:M.XmlDocSigTest.event1"); + ("FSharpField", "event2", "P:M.XmlDocSigTest.event2"); + ("FSharpField", "aString", "P:M.XmlDocSigTest.aString"); + ("FSharpField", "anInt", "P:M.XmlDocSigTest.anInt"); + ("FSharpEntity", "Use", "T:M.Use"); + ("FSharpMemberOrFunctionOrValue", "``.ctor``", "M:M.Use.#ctor"); + ("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)"); + ("FSharpGenericParameter", "?", "")|] + |> Array.iter (fun x -> + if xmlDocSigs |> Array.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) #endif -module internal Project29 = +module internal Project29 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module M open System.ComponentModel -let f (x: INotifyPropertyChanged) = failwith "" +let f (x: INotifyPropertyChanged) = failwith "" """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) @@ -4017,35 +4033,35 @@ let f (x: INotifyPropertyChanged) = failwith "" [] -let ``Test project29 whole project errors`` () = +let ``Test project29 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project29.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project29.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project29 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] -let ``Test project29 event symbols`` () = +let ``Test project29 event symbols`` () = + + let wholeProjectResults = checker.ParseAndCheckProject(Project29.options) |> Async.RunImmediate - let wholeProjectResults = checker.ParseAndCheckProject(Project29.options) |> Async.RunSynchronously - - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "INotifyPropertyChanged") + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "INotifyPropertyChanged") let objEntity = objSymbol.Symbol :?> FSharpEntity - let objMethodsCurriedParameterGroups = - [ for x in objEntity.MembersFunctionsAndValues do - for pg in x.CurriedParameterGroups do + let objMethodsCurriedParameterGroups = + [ for x in objEntity.MembersFunctionsAndValues do + for pg in x.CurriedParameterGroups do for p in pg do yield x.CompiledName, p.Name, p.Type.Format(objSymbol.DisplayContext) ] - objMethodsCurriedParameterGroups |> shouldEqual + objMethodsCurriedParameterGroups |> shouldEqual [("add_PropertyChanged", Some "value", "PropertyChangedEventHandler"); ("remove_PropertyChanged", Some "value", "PropertyChangedEventHandler")] - + // check we can get the ReturnParameter - let objMethodsReturnParameter = - [ for x in objEntity.MembersFunctionsAndValues do - let p = x.ReturnParameter + let objMethodsReturnParameter = + [ for x in objEntity.MembersFunctionsAndValues do + let p = x.ReturnParameter yield x.DisplayName, p.Name, p.Type.Format(objSymbol.DisplayContext) ] set objMethodsReturnParameter |> shouldEqual (set @@ -4054,70 +4070,70 @@ let ``Test project29 event symbols`` () = ("remove_PropertyChanged", None, "unit")]) -module internal Project30 = +module internal Project30 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ [] module Module open System -type T() = +type T() = [] - member __.Member = 0 + member _.Member = 0 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) -let ``Test project30 whole project errors`` () = +let ``Test project30 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project30.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project30.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project30 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] -let ``Test project30 Format attributes`` () = +let ``Test project30 Format attributes`` () = + + let wholeProjectResults = checker.ParseAndCheckProject(Project30.options) |> Async.RunImmediate - let wholeProjectResults = checker.ParseAndCheckProject(Project30.options) |> Async.RunSynchronously - - let moduleSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Module") + let moduleSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Module") let moduleEntity = moduleSymbol.Symbol :?> FSharpEntity - - let moduleAttributes = - [ for x in moduleEntity.Attributes do + + let moduleAttributes = + [ for x in moduleEntity.Attributes do yield x.Format(moduleSymbol.DisplayContext), x.Format(FSharpDisplayContext.Empty) ] - moduleAttributes + moduleAttributes |> set - |> shouldEqual + |> shouldEqual (set - [("[ (4))>]", - "[ (4))>]")]) - - let memberSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Member") + [("[ (4))>]", + "[ (4))>]")]) + + let memberSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Member") let memberEntity = memberSymbol.Symbol :?> FSharpMemberOrFunctionOrValue - - let memberAttributes = - [ for x in memberEntity.Attributes do + + let memberAttributes = + [ for x in memberEntity.Attributes do yield x.Format(memberSymbol.DisplayContext), x.Format(FSharpDisplayContext.Empty) ] memberAttributes - |> set - |> shouldEqual + |> set + |> shouldEqual (set - [("""[]""", + [("""[]""", """[]""")]) -module internal Project31 = +module internal Project31 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -4126,34 +4142,34 @@ open System open System.Collections.Generic open System.Diagnostics let f (x: List<'T>) = failwith "" -let g = Console.ReadKey() +let g = Console.ReadKey() """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) -let ``Test project31 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do +let ``Test project31 whole project errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project31 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] #if NETCOREAPP [] #endif let ``Test project31 C# type attributes`` () = - if not runningOnMono then - let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunSynchronously - - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "List") + if not runningOnMono then + let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunImmediate + + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "List") let objEntity = objSymbol.Symbol :?> FSharpEntity let attributes = objEntity.Attributes |> Seq.filter (fun attrib -> attrib.AttributeType.DisplayName <> "__DynamicallyInvokableAttribute") - [ for attrib in attributes do + [ for attrib in attributes do let args = try Seq.toList attrib.ConstructorArguments with _ -> [] let namedArgs = try Seq.toList attrib.NamedArguments with _ -> [] let output = sprintf "%A" (attrib.AttributeType, args, namedArgs) @@ -4168,22 +4184,22 @@ let ``Test project31 C# type attributes`` () = [] let ``Test project31 C# method attributes`` () = - if not runningOnMono then - let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunSynchronously - - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Console") + if not runningOnMono then + let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunImmediate + + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Console") let objEntity = objSymbol.Symbol :?> FSharpEntity - - let objMethodsAttributes = - [ for x in objEntity.MembersFunctionsAndValues do - for attrib in x.Attributes do + + let objMethodsAttributes = + [ for x in objEntity.MembersFunctionsAndValues do + for attrib in x.Attributes do let args = try Seq.toList attrib.ConstructorArguments with _ -> [] let namedArgs = try Seq.toList attrib.NamedArguments with _ -> [] yield sprintf "%A" (attrib.AttributeType, args, namedArgs) ] - objMethodsAttributes + objMethodsAttributes |> set - |> shouldEqual + |> shouldEqual (set [ #if !NETCOREAPP "(SecuritySafeCriticalAttribute, [], [])"; @@ -4195,10 +4211,10 @@ let ``Test project31 C# method attributes`` () = [] #endif let ``Test project31 Format C# type attributes`` () = - if not runningOnMono then - let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunSynchronously - - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "List") + if not runningOnMono then + let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunImmediate + + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "List") let objEntity = objSymbol.Symbol :?> FSharpEntity let attributes = objEntity.Attributes |> Seq.filter (fun attrib -> attrib.AttributeType.DisplayName <> "__DynamicallyInvokableAttribute") @@ -4212,44 +4228,44 @@ let ``Test project31 Format C# type attributes`` () = [] let ``Test project31 Format C# method attributes`` () = - if not runningOnMono then - let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunSynchronously - - let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Console") + if not runningOnMono then + let wholeProjectResults = checker.ParseAndCheckProject(Project31.options) |> Async.RunImmediate + + let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.find (fun su -> su.Symbol.DisplayName = "Console") let objEntity = objSymbol.Symbol :?> FSharpEntity - - let objMethodsAttributes = - [ for x in objEntity.MembersFunctionsAndValues do + + let objMethodsAttributes = + [ for x in objEntity.MembersFunctionsAndValues do for attrib in x.Attributes -> attrib.Format(objSymbol.DisplayContext) ] - objMethodsAttributes + objMethodsAttributes |> set - |> shouldEqual + |> shouldEqual (set ["[]"; #if !NETCOREAPP "[]"; #endif ]) -module internal Project32 = +module internal Project32 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") let sigFileName1 = Path.ChangeExtension(fileName1, ".fsi") - let base2 = Path.GetTempFileName() + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Sample let func x = x + 1 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let sigFileSource1 = """ module Sample val func : int -> int """ - File.WriteAllText(sigFileName1, sigFileSource1) + FileSystem.OpenFileForWriteShim(sigFileName1).Write(sigFileSource1) let cleanFileName a = if a = fileName1 then "file1" elif a = sigFileName1 then "sig1" else "??" let fileNames = [sigFileName1; fileName1] @@ -4258,55 +4274,55 @@ val func : int -> int [] -let ``Test Project32 whole project errors`` () = +let ``Test Project32 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project32 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project32 should be able to find sig symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunSynchronously - let _sigBackgroundParseResults1, sigBackgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project32.sigFileName1, Project32.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunImmediate + let _sigBackgroundParseResults1, sigBackgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project32.sigFileName1, Project32.options) + |> Async.RunImmediate - let sigSymbolUseOpt = sigBackgroundTypedParse1.GetSymbolUseAtLocation(4,5,"",["func"]) |> Async.RunSynchronously + let sigSymbolUseOpt = sigBackgroundTypedParse1.GetSymbolUseAtLocation(4,5,"",["func"]) let sigSymbol = sigSymbolUseOpt.Value.Symbol - - let usesOfSigSymbol = - [ for su in wholeProjectResults.GetUsesOfSymbol(sigSymbol) |> Async.RunSynchronously do - yield Project32.cleanFileName su.FileName , tups su.RangeAlternate, attribsOfSymbol su.Symbol ] + + let usesOfSigSymbol = + [ for su in wholeProjectResults.GetUsesOfSymbol(sigSymbol) do + yield Project32.cleanFileName su.FileName , tups su.Range, attribsOfSymbol su.Symbol ] usesOfSigSymbol |> shouldEqual - [("sig1", ((4, 4), (4, 8)), ["val"]); + [("sig1", ((4, 4), (4, 8)), ["val"]); ("file1", ((3, 4), (3, 8)), ["val"])] [] let ``Test Project32 should be able to find impl symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunSynchronously - let _implBackgroundParseResults1, implBackgroundTypedParse1 = - checker.GetBackgroundCheckResultsForFileInProject(Project32.fileName1, Project32.options) - |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(Project32.options) |> Async.RunImmediate + let _implBackgroundParseResults1, implBackgroundTypedParse1 = + checker.GetBackgroundCheckResultsForFileInProject(Project32.fileName1, Project32.options) + |> Async.RunImmediate - let implSymbolUseOpt = implBackgroundTypedParse1.GetSymbolUseAtLocation(3,5,"",["func"]) |> Async.RunSynchronously + let implSymbolUseOpt = implBackgroundTypedParse1.GetSymbolUseAtLocation(3,5,"",["func"]) let implSymbol = implSymbolUseOpt.Value.Symbol - - let usesOfImplSymbol = - [ for su in wholeProjectResults.GetUsesOfSymbol(implSymbol) |> Async.RunSynchronously do - yield Project32.cleanFileName su.FileName , tups su.RangeAlternate, attribsOfSymbol su.Symbol ] + + let usesOfImplSymbol = + [ for su in wholeProjectResults.GetUsesOfSymbol(implSymbol) do + yield Project32.cleanFileName su.FileName , tups su.Range, attribsOfSymbol su.Symbol ] usesOfImplSymbol |> shouldEqual - [("sig1", ((4, 4), (4, 8)), ["val"]); + [("sig1", ((4, 4), (4, 8)), ["val"]); ("file1", ((3, 4), (3, 8)), ["val"])] -module internal Project33 = +module internal Project33 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -4317,7 +4333,7 @@ type System.Int32 with member x.SetValue (_: int) = () member x.GetValue () = x """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -4325,43 +4341,43 @@ type System.Int32 with let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] -let ``Test Project33 whole project errors`` () = +let ``Test Project33 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project33.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do + let wholeProjectResults = checker.ParseAndCheckProject(Project33.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project33 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] let ``Test Project33 extension methods`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project33.options) |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - + let wholeProjectResults = checker.ParseAndCheckProject(Project33.options) |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let implModuleUse = allSymbolsUses |> Array.find (fun su -> su.Symbol.DisplayName = "Impl") let implModuleDefn = implModuleUse.Symbol :?> FSharpEntity - [ + [ for x in implModuleDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] - |> shouldEqual - [("SetValue", ["member"; "extmem"]); + |> shouldEqual + [("SetValue", ["member"; "extmem"]); ("GetValue", ["member"; "extmem"])] -module internal Project34 = +module internal Project34 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module Dummy """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] - let args = + let args = [| yield! mkProjectCommandLineArgs (dllName, fileNames) // We use .NET-buit version of System.Data.dll since the tests depend on implementation details @@ -4371,19 +4387,19 @@ module Dummy let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] -let ``Test Project34 whole project errors`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project34.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do +let ``Test Project34 whole project errors`` () = + let wholeProjectResults = checker.ParseAndCheckProject(Project34.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do printfn "Project34 error: <<<%s>>>" e.Message - wholeProjectResults.Errors.Length |> shouldEqual 0 + wholeProjectResults.Diagnostics.Length |> shouldEqual 0 [] #if NETCOREAPP [] #endif let ``Test project34 should report correct accessibility for System.Data.Listeners`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project34.options) |> Async.RunSynchronously - let rec getNestedEntities (entity: FSharpEntity) = + let wholeProjectResults = checker.ParseAndCheckProject(Project34.options) |> Async.RunImmediate + let rec getNestedEntities (entity: FSharpEntity) = seq { yield entity for e in entity.NestedEntities do yield! getNestedEntities e } @@ -4392,18 +4408,18 @@ let ``Test project34 should report correct accessibility for System.Data.Listene |> List.tryPick (fun asm -> if asm.SimpleName.Contains("System.Data") then Some asm.Contents.Entities else None) |> Option.get |> Seq.collect getNestedEntities - |> Seq.tryFind (fun entity -> - entity.TryFullName - |> Option.map (fun s -> s.Contains("System.Data.Listeners")) + |> Seq.tryFind (fun entity -> + entity.TryFullName + |> Option.map (fun s -> s.Contains("System.Data.Listeners")) |> fun arg -> defaultArg arg false) |> Option.get listenerEntity.Accessibility.IsPrivate |> shouldEqual true let listenerFuncEntity = listenerEntity.NestedEntities - |> Seq.tryFind (fun entity -> - entity.TryFullName - |> Option.map (fun s -> s.Contains("Func")) + |> Seq.tryFind (fun entity -> + entity.TryFullName + |> Option.map (fun s -> s.Contains("Func")) |> fun arg -> defaultArg arg false) |> Option.get @@ -4412,10 +4428,10 @@ let ``Test project34 should report correct accessibility for System.Data.Listene //------------------------------------------------------ -module internal Project35 = +module internal Project35 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -4425,7 +4441,7 @@ type Test = let tupleFunction (one:int, two:float, three:string) = float32 (one + int two + int three) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -4435,11 +4451,11 @@ type Test = [] let ``Test project35 CurriedParameterGroups should be available for nested functions`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project35.options) |> Async.RunSynchronously - let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - let findByDisplayName name = + let wholeProjectResults = checker.ParseAndCheckProject(Project35.options) |> Async.RunImmediate + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let findByDisplayName name = Array.find (fun (su:FSharpSymbolUse) -> su.Symbol.DisplayName = name) - + let curriedFunction = allSymbolUses |> findByDisplayName "curriedFunction" match curriedFunction.Symbol with @@ -4489,15 +4505,15 @@ let ``Test project35 CurriedParameterGroups should be available for nested funct //------------------------------------------------------ -module internal Project35b = +module internal Project35b = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fsx") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fsx") let fileSource1Text = """ #r "System.dll" #r "notexist.dll" """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] @@ -4507,18 +4523,18 @@ module internal Project35b = let args = mkProjectCommandLineArgs(dllPath, fileNames) let args2 = Array.append args [| "-r:notexist.dll" |] let options = checker.GetProjectOptionsFromCommandLineArgs (projPath, args2) -#else - let options = checker.GetProjectOptionsFromScript(fileName1, fileSource1) |> Async.RunSynchronously |> fst +#else + let options = checker.GetProjectOptionsFromScript(fileName1, fileSource1) |> Async.RunImmediate |> fst #endif [] let ``Test project35b Dependency files for ParseAndCheckFileInProject`` () = - let checkFileResults = - checker.ParseAndCheckFileInProject(Project35b.fileName1, 0, Project35b.fileSource1, Project35b.options) |> Async.RunSynchronously - |> function + let checkFileResults = + checker.ParseAndCheckFileInProject(Project35b.fileName1, 0, Project35b.fileSource1, Project35b.options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res - | _ -> failwithf "Parsing aborted unexpectedly..." - for d in checkFileResults.DependencyFiles do + | _ -> failwithf "Parsing aborted unexpectedly..." + for d in checkFileResults.DependencyFiles do printfn "ParseAndCheckFileInProject dependency: %s" d checkFileResults.DependencyFiles |> Array.exists (fun s -> s.Contains "notexist.dll") |> shouldEqual true // The file itself is not a dependency since it is never read from the file system when using ParseAndCheckFileInProject @@ -4526,8 +4542,8 @@ let ``Test project35b Dependency files for ParseAndCheckFileInProject`` () = [] let ``Test project35b Dependency files for GetBackgroundCheckResultsForFileInProject`` () = - let _,checkFileResults = checker.GetBackgroundCheckResultsForFileInProject(Project35b.fileName1, Project35b.options) |> Async.RunSynchronously - for d in checkFileResults.DependencyFiles do + let _,checkFileResults = checker.GetBackgroundCheckResultsForFileInProject(Project35b.fileName1, Project35b.options) |> Async.RunImmediate + for d in checkFileResults.DependencyFiles do printfn "GetBackgroundCheckResultsForFileInProject dependency: %s" d checkFileResults.DependencyFiles |> Array.exists (fun s -> s.Contains "notexist.dll") |> shouldEqual true // The file is a dependency since it is read from the file system when using GetBackgroundCheckResultsForFileInProject @@ -4535,8 +4551,8 @@ let ``Test project35b Dependency files for GetBackgroundCheckResultsForFileInPro [] let ``Test project35b Dependency files for check of project`` () = - let checkResults = checker.ParseAndCheckProject(Project35b.options) |> Async.RunSynchronously - for d in checkResults.DependencyFiles do + let checkResults = checker.ParseAndCheckProject(Project35b.options) |> Async.RunImmediate + for d in checkResults.DependencyFiles do printfn "ParseAndCheckProject dependency: %s" d checkResults.DependencyFiles |> Array.exists (fun s -> s.Contains "notexist.dll") |> shouldEqual true checkResults.DependencyFiles |> Array.exists (fun s -> s.Contains Project35b.fileName1) |> shouldEqual true @@ -4545,11 +4561,11 @@ let ``Test project35b Dependency files for check of project`` () = module internal Project36 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") - let fileSource1 = """ + let fileSource1 = """module Project36 type A(i:int) = member x.Value = i @@ -4564,31 +4580,21 @@ let [] lit = 1.0 let notLit = 1.0 let callToOverload = B(5).Overload(4) """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let cleanFileName a = if a = fileName1 then "file1" else "??" let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) + +[] +let ``Test project36 FSharpMemberOrFunctionOrValue.IsBaseValue`` () = let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) - let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (Project36.projFileName, Project36.args) let wholeProjectResults = keepAssemblyContentsChecker.ParseAndCheckProject(options) - |> Async.RunSynchronously - let declarations = - let checkedFile = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] - match checkedFile.Declarations.[0] with - | FSharpImplementationFileDeclaration.Entity (_, subDecls) -> subDecls - | _ -> failwith "unexpected declaration" - let getExpr exprIndex = - match declarations.[exprIndex] with - | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(_,_,e) -> e - | FSharpImplementationFileDeclaration.InitAction e -> e - | _ -> failwith "unexpected declaration" + |> Async.RunImmediate -[] -let ``Test project36 FSharpMemberOrFunctionOrValue.IsBaseValue`` () = - Project36.wholeProjectResults.GetAllUsesOfAllSymbols() - |> Async.RunSynchronously + wholeProjectResults.GetAllUsesOfAllSymbols() |> Array.pick (fun (su:FSharpSymbolUse) -> if su.Symbol.DisplayName = "base" then Some (su.Symbol :?> FSharpMemberOrFunctionOrValue) @@ -4597,7 +4603,9 @@ let ``Test project36 FSharpMemberOrFunctionOrValue.IsBaseValue`` () = [] let ``Test project36 FSharpMemberOrFunctionOrValue.IsConstructorThisValue & IsMemberThisValue`` () = - let wholeProjectResults = Project36.keepAssemblyContentsChecker.ParseAndCheckProject(Project36.options) |> Async.RunSynchronously + let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) + let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (Project36.projFileName, Project36.args) + let wholeProjectResults = keepAssemblyContentsChecker.ParseAndCheckProject(options) |> Async.RunImmediate let declarations = let checkedFile = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] match checkedFile.Declarations.[0] with @@ -4610,29 +4618,31 @@ let ``Test project36 FSharpMemberOrFunctionOrValue.IsConstructorThisValue & IsMe | _ -> failwith "unexpected declaration" // Instead of checking the symbol uses directly, walk the typed tree to check // the correct values are also visible from there. Also note you cannot use - // BasicPatterns.ThisValue in these cases, this is only used when the symbol + // ThisValue in these cases, this is only used when the symbol // is implicit in the constructor - match Project36.getExpr 4 with - | BasicPatterns.Let((b,_),_) -> + match getExpr 4 with + | Let((b,_),_) -> b.IsConstructorThisValue && not b.IsMemberThisValue | _ -> failwith "unexpected expression" |> shouldEqual true - match Project36.getExpr 5 with - | BasicPatterns.FSharpFieldGet(Some(BasicPatterns.Value x),_,_) -> + match getExpr 5 with + | FSharpFieldGet(Some(Value x),_,_) -> x.IsMemberThisValue && not x.IsConstructorThisValue | _ -> failwith "unexpected expression" |> shouldEqual true - match Project36.getExpr 6 with - | BasicPatterns.Call(_,_,_,_,[BasicPatterns.Value s;_]) -> + match getExpr 6 with + | Call(_,_,_,_,[Value s;_]) -> not s.IsMemberThisValue && not s.IsConstructorThisValue | _ -> failwith "unexpected expression" |> shouldEqual true [] let ``Test project36 FSharpMemberOrFunctionOrValue.LiteralValue`` () = - let wholeProjectResults = Project36.keepAssemblyContentsChecker.ParseAndCheckProject(Project36.options) |> Async.RunSynchronously + let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) + let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (Project36.projFileName, Project36.args) + let wholeProjectResults = keepAssemblyContentsChecker.ParseAndCheckProject(options) |> Async.RunImmediate let project36Module = wholeProjectResults.AssemblySignature.Entities.[0] let lit = project36Module.MembersFunctionsAndValues.[0] shouldEqual true (lit.LiteralValue.Value |> unbox |> (=) 1.) @@ -4640,10 +4650,10 @@ let ``Test project36 FSharpMemberOrFunctionOrValue.LiteralValue`` () = let notLit = project36Module.MembersFunctionsAndValues.[1] shouldEqual true notLit.LiteralValue.IsNone -module internal Project37 = +module internal Project37 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let fileName2 = Path.ChangeExtension(base2, ".fs") let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") @@ -4678,20 +4688,20 @@ module Test = let withTypeArray = 0 [] let withIntArray = 0 - module NestedModule = + module NestedModule = type NestedRecordType = { B : int } [] do () """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileSource2 = """ namespace AttrTests [] do () """ - File.WriteAllText(fileName2, fileSource2) + FileSystem.OpenFileForWriteShim(fileName2).Write(fileSource2) let fileNames = [fileName1; fileName2] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) @@ -4700,14 +4710,14 @@ do () let ``Test project37 typeof and arrays in attribute constructor arguments`` () = let wholeProjectResults = checker.ParseAndCheckProject(Project37.options) - |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously + |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() for su in allSymbolsUses do match su.Symbol with | :? FSharpMemberOrFunctionOrValue as funcSymbol -> let getAttrArg() = - let arg = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd - arg :?> FSharpType + let arg = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd + arg :?> FSharpType match funcSymbol.DisplayName with | "withType" -> let t = getAttrArg() @@ -4727,25 +4737,25 @@ let ``Test project37 typeof and arrays in attribute constructor arguments`` () = t.GenericArguments.[0].TypeDefinition.DisplayName |> shouldEqual "int" t.GenericArguments.[1].TypeDefinition.DisplayName |> shouldEqual "int" | "withTypeArray" -> - let attr = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd + let attr = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd let ta = attr :?> obj[] |> Array.map (fun t -> t :?> FSharpType) ta.[0].TypeDefinition.DisplayName |> shouldEqual "TestUnion" ta.[1].TypeDefinition.DisplayName |> shouldEqual "TestRecord" | "withIntArray" -> - let attr = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd + let attr = funcSymbol.Attributes.[0].ConstructorArguments.[0] |> snd let a = attr :?> obj[] |> Array.map (fun t -> t :?> int) - a |> shouldEqual [| 0; 1; 2 |] + a |> shouldEqual [| 0; 1; 2 |] | _ -> () | _ -> () - let mscorlibAsm = - wholeProjectResults.ProjectContext.GetReferencedAssemblies() + let mscorlibAsm = + wholeProjectResults.ProjectContext.GetReferencedAssemblies() |> Seq.find (fun a -> a.SimpleName = "mscorlib") printfn "Attributes found in mscorlib: %A" mscorlibAsm.Contents.Attributes shouldEqual (mscorlibAsm.Contents.Attributes.Count > 0) true - let fsharpCoreAsm = - wholeProjectResults.ProjectContext.GetReferencedAssemblies() + let fsharpCoreAsm = + wholeProjectResults.ProjectContext.GetReferencedAssemblies() |> Seq.find (fun a -> a.SimpleName = "FSharp.Core") printfn "Attributes found in FSharp.Core: %A" fsharpCoreAsm.Contents.Attributes shouldEqual (fsharpCoreAsm.Contents.Attributes.Count > 0) true @@ -4754,36 +4764,36 @@ let ``Test project37 typeof and arrays in attribute constructor arguments`` () = let ``Test project37 DeclaringEntity`` () = let wholeProjectResults = checker.ParseAndCheckProject(Project37.options) - |> Async.RunSynchronously - let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously + |> Async.RunImmediate + let allSymbolsUses = wholeProjectResults.GetAllUsesOfAllSymbols() for sym in allSymbolsUses do - match sym.Symbol with - | :? FSharpEntity as e when not e.IsNamespace || e.AccessPath.Contains(".") -> + match sym.Symbol with + | :? FSharpEntity as e when not e.IsNamespace || e.AccessPath.Contains(".") -> printfn "checking declaring type of entity '%s' --> '%s', assembly = '%s'" e.AccessPath e.CompiledName (e.Assembly.ToString()) shouldEqual e.DeclaringEntity.IsSome true - match e.CompiledName with - | "AttrTestAttribute" -> + match e.CompiledName with + | "AttrTestAttribute" -> shouldEqual e.AccessPath "AttrTests" - | "int" -> + | "int" -> shouldEqual e.AccessPath "Microsoft.FSharp.Core" shouldEqual e.DeclaringEntity.Value.AccessPath "Microsoft.FSharp" - | "list`1" -> + | "list`1" -> shouldEqual e.AccessPath "Microsoft.FSharp.Collections" shouldEqual e.DeclaringEntity.Value.AccessPath "Microsoft.FSharp" shouldEqual e.DeclaringEntity.Value.DeclaringEntity.IsSome true shouldEqual e.DeclaringEntity.Value.DeclaringEntity.Value.IsNamespace true shouldEqual e.DeclaringEntity.Value.DeclaringEntity.Value.AccessPath "Microsoft" shouldEqual e.DeclaringEntity.Value.DeclaringEntity.Value.DeclaringEntity.Value.DeclaringEntity.IsSome false - | "Attribute" -> + | "Attribute" -> shouldEqual e.AccessPath "System" shouldEqual e.DeclaringEntity.Value.AccessPath "global" - | "NestedRecordType" -> + | "NestedRecordType" -> shouldEqual e.AccessPath "AttrTests.Test.NestedModule" shouldEqual e.DeclaringEntity.Value.AccessPath "AttrTests.Test" shouldEqual e.DeclaringEntity.Value.DeclaringEntity.Value.AccessPath "AttrTests" shouldEqual e.DeclaringEntity.Value.DeclaringEntity.Value.DeclaringEntity.Value.AccessPath "global" | _ -> () - | :? FSharpMemberOrFunctionOrValue as e when e.IsModuleValueOrMember -> + | :? FSharpMemberOrFunctionOrValue as e when e.IsModuleValueOrMember -> printfn "checking declaring type of value '%s', assembly = '%s'" e.CompiledName (e.Assembly.ToString()) shouldEqual e.DeclaringEntity.IsSome true | _ -> () @@ -4793,8 +4803,8 @@ let ``Test project37 DeclaringEntity`` () = module internal Project38 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -4804,7 +4814,7 @@ type I<'X> = abstract Method : unit -> unit abstract Generic : named:'X -> unit abstract Generic<'Y> : 'X * 'Y -> unit - abstract Property : int + abstract Property : int [] type B<'Y>() = @@ -4816,7 +4826,7 @@ type B<'Y>() = type A<'XX, 'YY>() = inherit B<'YY>() - + let ev = Event() override this.Method() = () @@ -4833,7 +4843,7 @@ type A<'XX, 'YY>() = member this.Generic<'Y> (a: 'XX, b: 'Y) = () member this.Property = 1 """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) @@ -4842,98 +4852,103 @@ type A<'XX, 'YY>() = let ``Test project38 abstract slot information`` () = let wholeProjectResults = checker.ParseAndCheckProject(Project38.options) - |> Async.RunSynchronously + |> Async.RunImmediate let printAbstractSignature (s: FSharpAbstractSignature) = - let printType (t: FSharpType) = + let printType (t: FSharpType) = hash t |> ignore // smoke test to check hash code doesn't loop - (string t).[5 ..] - let args = - (s.AbstractArguments |> Seq.concat |> Seq.map (fun a -> + (string t).[5 ..] + let args = + (s.AbstractArguments |> Seq.concat |> Seq.map (fun a -> (match a.Name with Some n -> n + ":" | _ -> "") + printType a.Type) |> String.concat " * ") |> function "" -> "()" | a -> a let tgen = match s.DeclaringTypeGenericParameters |> Seq.map (fun m -> "'" + m.Name) |> String.concat "," with | "" -> "" - | g -> " original generics: <" + g + ">" + | g -> " original generics: <" + g + ">" let mgen = match s.MethodGenericParameters |> Seq.map (fun m -> "'" + m.Name) |> String.concat "," with | "" -> "" - | g -> "<" + g + ">" + | g -> "<" + g + ">" "type " + printType s.DeclaringType + tgen + " with member " + s.Name + mgen + " : " + args + " -> " + printType s.AbstractReturnType - - let a2ent = wholeProjectResults.AssemblySignature.Entities |> Seq.find (fun e -> e.FullName = "OverrideTests.A`2") - a2ent.MembersFunctionsAndValues |> Seq.map (fun m -> - m.CompiledName, (m.ImplementedAbstractSignatures |> Seq.map printAbstractSignature |> List.ofSeq) + + let results = + let a2ent = wholeProjectResults.AssemblySignature.Entities |> Seq.find (fun e -> e.FullName = "OverrideTests.A`2") + a2ent.MembersFunctionsAndValues |> Seq.map (fun m -> + m.CompiledName, (m.ImplementedAbstractSignatures |> Seq.map printAbstractSignature |> List.ofSeq) + ) + |> Array.ofSeq + + [| + ".ctor", [] + "Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] + "Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] + "NotOverride", [] + "add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] + "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] + "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "OverrideTests.I<'XX>.get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] + "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] + |] + |> Array.iter (fun x -> + if results |> Array.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x ) - |> Array.ofSeq - |> shouldEqual - [| - ".ctor", [] - "Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] - "Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"] - "OverrideTests-I`1-Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] - "NotOverride", [] - "add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] - "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] - "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "OverrideTests-I`1-get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] - "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] - |] //-------------------------------------------- -module internal Project39 = +module internal Project39 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module M let functionWithIncompleteSignature x = System.ThisDoesntExist.SomeMethod(x) -let curriedFunctionWithIncompleteSignature (x1:'a) x2 (x3:'a,x4) = +let curriedFunctionWithIncompleteSignature (x1:'a) x2 (x3:'a,x4) = (x2 = x4) |> ignore System.ThisDoesntExist.SomeMethod(x1,x2,x3,x4) -type C() = +type C() = member x.MemberWithIncompleteSignature x = System.ThisDoesntExist.SomeMethod(x) - member x.CurriedMemberWithIncompleteSignature (x1:'a) x2 (x3:'a,x4) = + member x.CurriedMemberWithIncompleteSignature (x1:'a) x2 (x3:'a,x4) = (x2 = x4) |> ignore System.ThisDoesntExist.SomeMethod(x1,x2,x3,x4) -let uses () = +let uses () = functionWithIncompleteSignature (failwith "something") curriedFunctionWithIncompleteSignature (failwith "x1") (failwith "x2") (failwith "x3", failwith "x4") C().MemberWithIncompleteSignature (failwith "something") C().CurriedMemberWithIncompleteSignature (failwith "x1") (failwith "x2") (failwith "x3", failwith "x4") """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test project39 all symbols`` () = +let ``Test project39 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project39.options) |> Async.RunSynchronously - let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - let typeTextOfAllSymbolUses = + let wholeProjectResults = checker.ParseAndCheckProject(Project39.options) |> Async.RunImmediate + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let typeTextOfAllSymbolUses = [ for s in allSymbolUses do - match s.Symbol with - | :? FSharpMemberOrFunctionOrValue as mem -> + match s.Symbol with + | :? FSharpMemberOrFunctionOrValue as mem -> if s.Symbol.DisplayName.Contains "Incomplete" then - yield s.Symbol.DisplayName, tups s.RangeAlternate, + yield s.Symbol.DisplayName, tups s.Range, ("full", mem.FullType |> FSharpType.Prettify |> fun p -> p.Format(s.DisplayContext)), ("params", mem.CurriedParameterGroups |> FSharpType.Prettify |> Seq.toList |> List.map (Seq.toList >> List.map (fun p -> p.Type.Format(s.DisplayContext)))), - ("return", mem.ReturnParameter |> FSharpType.Prettify |> fun p -> p.Type.Format(s.DisplayContext)) + ("return", mem.ReturnParameter |> FSharpType.Prettify |> fun p -> p.Type.Format(s.DisplayContext)) | _ -> () ] typeTextOfAllSymbolUses |> shouldEqual [("functionWithIncompleteSignature", ((4, 4), (4, 35)), @@ -4968,10 +4983,10 @@ let ``Test project39 all symbols`` () = //-------------------------------------------- -module internal Project40 = +module internal Project40 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -4979,28 +4994,28 @@ module M let f (x: option<_>) = x.IsSome, x.IsNone -[] -type C = - | A +[] +type C = + | A | B of string member x.IsItAnA = match x with A -> true | B _ -> false member x.IsItAnAMethod() = match x with A -> true | B _ -> false -let g (x: C) = x.IsItAnA,x.IsItAnAMethod() +let g (x: C) = x.IsItAnA,x.IsItAnAMethod() """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test Project40 all symbols`` () = +let ``Test Project40 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project40.options) |> Async.RunSynchronously - let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - let allSymbolUsesInfo = [ for s in allSymbolUses -> s.Symbol.DisplayName, tups s.RangeAlternate, attribsOfSymbol s.Symbol ] + let wholeProjectResults = checker.ParseAndCheckProject(Project40.options) |> Async.RunImmediate + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let allSymbolUsesInfo = [ for s in allSymbolUses -> s.Symbol.DisplayName, tups s.Range, attribsOfSymbol s.Symbol ] allSymbolUsesInfo |> shouldEqual [("option", ((4, 10), (4, 16)), ["abbrev"]); ("x", ((4, 7), (4, 8)), []); ("x", ((4, 23), (4, 24)), []); @@ -5032,11 +5047,11 @@ let ``Test Project40 all symbols`` () = //-------------------------------------------- -module internal Project41 = +module internal Project41 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") // We need to us a stable name to keep the hashes stable - let base2 = Path.Combine(Path.GetDirectoryName(Path.GetTempFileName()), "stabletmp.tmp") + let base2 = Path.Combine(Path.GetDirectoryName(tryCreateTemporaryFileName ()), "stabletmp.tmp") let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -5059,24 +5074,24 @@ module M let f3 (v : {| X: {| X : int; Y : string |} |}) = v.X.X """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let cleanFileName a = if a = fileName1 then "file1" else "??" [] -let ``Test project41 all symbols`` () = +let ``Test project41 all symbols`` () = - let wholeProjectResults = checker.ParseAndCheckProject(Project41.options) |> Async.RunSynchronously - let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously - let allSymbolUsesInfo = + let wholeProjectResults = checker.ParseAndCheckProject(Project41.options) |> Async.RunImmediate + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() + let allSymbolUsesInfo = [ for s in allSymbolUses do - let pos = - match s.Symbol.DeclarationLocation with + let pos = + match s.Symbol.DeclarationLocation with | Some r when r.FileName = Project41.fileName1 -> r.StartLine, r.StartColumn | _ -> (0,0) - yield (s.Symbol.DisplayName, tups s.RangeAlternate, attribsOfSymbol s.Symbol, pos) ] + yield (s.Symbol.DisplayName, tups s.Range, attribsOfSymbol s.Symbol, pos) ] allSymbolUsesInfo |> shouldEqual [("X", ((4, 19), (4, 20)), ["field"; "anon(0, [//<>f__AnonymousType1416859829`1]X)"], (4, 19)); @@ -5125,17 +5140,63 @@ let ``Test project41 all symbols`` () = ("M", ((2, 7), (2, 8)), ["module"], (2, 7))] -module internal ProjectBig = +module internal Project42 = + + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let fileName2 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + // We need to us a stable name to keep the hashes stable + let base2 = Path.Combine(Path.GetDirectoryName(tryCreateTemporaryFileName ()), "stabletmp.tmp") + let dllName = Path.ChangeExtension(base2, ".dll") + let projFileName = Path.ChangeExtension(base2, ".fsproj") + let fileSource1 = """ +module File1 + +let test() = () + """ + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) + let fileSource2 = """ +module File2 + +open File1 + +let test2() = test() + """ + FileSystem.OpenFileForWriteShim(fileName2).Write(fileSource2) + let fileNames = [fileName1;fileName2] + let args = mkProjectCommandLineArgs (dllName, fileNames) + let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - let fileNamesI = [ for i in 1 .. 10 -> (i, Path.ChangeExtension(Path.GetTempFileName(), ".fs")) ] - let base2 = Path.GetTempFileName() +[] +let ``Test project42 to ensure cached checked results are invalidated`` () = + let text2 = SourceText.ofString(FileSystem.OpenFileForReadShim(Project42.fileName2).ReadAllText()) + let checkedFile2 = checker.ParseAndCheckFileInProject(Project42.fileName2, text2.GetHashCode(), text2, Project42.options) |> Async.RunImmediate + match checkedFile2 with + | _, FSharpCheckFileAnswer.Succeeded(checkedFile2Results) -> + Assert.IsEmpty(checkedFile2Results.Diagnostics) + FileSystem.OpenFileForWriteShim(Project42.fileName1).Write("""module File1""") + try + let checkedFile2Again = checker.ParseAndCheckFileInProject(Project42.fileName2, text2.GetHashCode(), text2, Project42.options) |> Async.RunImmediate + match checkedFile2Again with + | _, FSharpCheckFileAnswer.Succeeded(checkedFile2AgainResults) -> + Assert.IsNotEmpty(checkedFile2AgainResults.Diagnostics) // this should contain errors as File1 does not contain the function `test()` + | _ -> + failwith "Project42 failed to check." + finally + FileSystem.OpenFileForWriteShim(Project42.fileName1).Write(Project42.fileSource1) // Revert to the original state of the file + | _ -> + failwith "Project42 failed to check." + +module internal ProjectBig = + + let fileNamesI = [ for i in 1 .. 10 -> (i, Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs")) ] + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") - let fileSources = [ for (i,f) in fileNamesI -> (f, "module M" + string i) ] - for (f,text) in fileSources do File.WriteAllText(f, text) - let fileSources2 = [ for (i,f) in fileSources -> FSharp.Compiler.Text.SourceText.ofString f ] + let fileSources = [ for i,f in fileNamesI -> (f, "module M" + string i) ] + for f,text in fileSources do FileSystem.OpenFileForWriteShim(f).Write(text) + let fileSources2 = [ for i,f in fileSources -> SourceText.ofString f ] - let fileNames = [ for (_,f) in fileNamesI -> f ] + let fileNames = [ for _,f in fileNamesI -> f ] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let parsingOptions, _ = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) @@ -5144,27 +5205,27 @@ module internal ProjectBig = [] // Simplified repro for https://github.com/Microsoft/visualfsharp/issues/2679 -let ``add files with same name from different folders`` () = +let ``add files with same name from different folders`` () = let fileNames = [ __SOURCE_DIRECTORY__ + "/data/samename/folder1/a.fs" __SOURCE_DIRECTORY__ + "/data/samename/folder2/a.fs" ] let projFileName = __SOURCE_DIRECTORY__ + "/data/samename/tempet.fsproj" let args = mkProjectCommandLineArgs ("test.dll", fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - let wholeProjectResults = checker.ParseAndCheckProject(options) |> Async.RunSynchronously + let wholeProjectResults = checker.ParseAndCheckProject(options) |> Async.RunImmediate let errors = - wholeProjectResults.Errors - |> Array.filter (fun x -> x.Severity = FSharpErrorSeverity.Error) + wholeProjectResults.Diagnostics + |> Array.filter (fun x -> x.Severity = FSharpDiagnosticSeverity.Error) if errors.Length > 0 then printfn "add files with same name from different folders" for err in errors do printfn "ERROR: %s" err.Message shouldEqual 0 errors.Length -module internal ProjectStructUnions = +module internal ProjectStructUnions = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ @@ -5182,14 +5243,15 @@ let foo (a: Foo): bool = | _ -> false """ - File.WriteAllText(fileName1, fileSource1) + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) [] let ``Test typed AST for struct unions`` () = // See https://github.com/fsharp/FSharp.Compiler.Service/issues/756 - let wholeProjectResults = Project36.keepAssemblyContentsChecker.ParseAndCheckProject(ProjectStructUnions.options) |> Async.RunSynchronously + let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) + let wholeProjectResults = keepAssemblyContentsChecker.ParseAndCheckProject(ProjectStructUnions.options) |> Async.RunImmediate let declarations = let checkedFile = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] match checkedFile.Declarations.[0] with @@ -5201,16 +5263,16 @@ let ``Test typed AST for struct unions`` () = // See https://github.com/fsharp/F | FSharpImplementationFileDeclaration.InitAction e -> e | _ -> failwith "unexpected declaration" match getExpr (declarations.Length - 1) with - | BasicPatterns.IfThenElse(BasicPatterns.UnionCaseTest(BasicPatterns.AddressOf(BasicPatterns.UnionCaseGet _),_,uci), - BasicPatterns.Const(trueValue, _), BasicPatterns.Const(falseValue, _)) + | IfThenElse(UnionCaseTest(AddressOf(UnionCaseGet _),_,uci), + Const(trueValue, _), Const(falseValue, _)) when uci.Name = "Ok" && obj.Equals(trueValue, true) && obj.Equals(falseValue, false) -> true | _ -> failwith "unexpected expression" |> shouldEqual true -module internal ProjectLineDirectives = +module internal ProjectLineDirectives = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ @@ -5219,8 +5281,8 @@ module M # 10 "Test.fsy" let x = (1 = 3.0) """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) @@ -5229,48 +5291,48 @@ let x = (1 = 3.0) let ``Test line directives in foreground analysis`` () = // see https://github.com/Microsoft/visualfsharp/issues/3317 // In background analysis and normal compiler checking, the errors are reported w.r.t. the line directives - let wholeProjectResults = checker.ParseAndCheckProject(ProjectLineDirectives.options) |> Async.RunSynchronously - for e in wholeProjectResults.Errors do - printfn "ProjectLineDirectives wholeProjectResults error file: <<<%s>>>" e.FileName + let wholeProjectResults = checker.ParseAndCheckProject(ProjectLineDirectives.options) |> Async.RunImmediate + for e in wholeProjectResults.Diagnostics do + printfn "ProjectLineDirectives wholeProjectResults error file: <<<%s>>>" e.Range.FileName - [ for e in wholeProjectResults.Errors -> e.StartLineAlternate, e.EndLineAlternate, e.FileName ] |> shouldEqual [(10, 10, "Test.fsy")] + [ for e in wholeProjectResults.Diagnostics -> e.Range.StartLine, e.Range.EndLine, e.Range.FileName ] |> shouldEqual [(10, 10, "Test.fsy")] // In foreground analysis routines, used by visual editing tools, the errors are reported w.r.t. the source // file, which is assumed to be in the editor, not the other files referred to by line directives. - let checkResults1 = - checker.ParseAndCheckFileInProject(ProjectLineDirectives.fileName1, 0, ProjectLineDirectives.fileSource1, ProjectLineDirectives.options) - |> Async.RunSynchronously - |> function (_,FSharpCheckFileAnswer.Succeeded x) -> x | _ -> failwith "unexpected aborted" + let checkResults1 = + checker.ParseAndCheckFileInProject(ProjectLineDirectives.fileName1, 0, ProjectLineDirectives.fileSource1, ProjectLineDirectives.options) + |> Async.RunImmediate + |> function _,FSharpCheckFileAnswer.Succeeded x -> x | _ -> failwith "unexpected aborted" - for e in checkResults1.Errors do - printfn "ProjectLineDirectives checkResults1 error file: <<<%s>>>" e.FileName + for e in checkResults1.Diagnostics do + printfn "ProjectLineDirectives checkResults1 error file: <<<%s>>>" e.Range.FileName - [ for e in checkResults1.Errors -> e.StartLineAlternate, e.EndLineAlternate, e.FileName ] |> shouldEqual [(5, 5, ProjectLineDirectives.fileName1)] + [ for e in checkResults1.Diagnostics -> e.Range.StartLine, e.Range.EndLine, e.Range.FileName ] |> shouldEqual [(5, 5, ProjectLineDirectives.fileName1)] //------------------------------------------------------ [] let ``ParseAndCheckFileResults contains ImplFile list if FSharpChecker is created with keepAssemblyContent flag set to true``() = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ type A(i:int) = member x.Value = i """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - - let fileCheckResults = - keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunSynchronously - |> function + + let fileCheckResults = + keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res | _ -> failwithf "Parsing aborted unexpectedly..." @@ -5302,7 +5364,7 @@ let ``#4030, Incremental builder creation warnings`` (args, errorSeverities) = let fileName, options = mkTestFileAndOptions source args let _, checkResults = parseAndCheckFile fileName source options - checkResults.Errors |> Array.map (fun e -> e.Severity = FSharpErrorSeverity.Error) |> shouldEqual errorSeverities + checkResults.Diagnostics |> Array.map (fun e -> e.Severity = FSharpDiagnosticSeverity.Error) |> shouldEqual errorSeverities //------------------------------------------------------ @@ -5310,8 +5372,8 @@ let ``#4030, Incremental builder creation warnings`` (args, errorSeverities) = [] let ``Unused opens in rec module smoke test 1``() = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ @@ -5323,19 +5385,19 @@ open FSharp.Control // unused open FSharp.Data // unused open System.Globalization // unused -module SomeUnusedModule = +module SomeUnusedModule = let f x = x -module SomeUsedModuleContainingFunction = +module SomeUsedModuleContainingFunction = let g x = x -module SomeUsedModuleContainingActivePattern = +module SomeUsedModuleContainingActivePattern = let (|ActivePattern|) x = x -module SomeUsedModuleContainingExtensionMember = +module SomeUsedModuleContainingExtensionMember = type System.Int32 with member x.Q = 1 -module SomeUsedModuleContainingUnion = +module SomeUsedModuleContainingUnion = type Q = A | B open SomeUnusedModule @@ -5351,28 +5413,28 @@ type UseTheThings(i:int) = member x.UseSomeUsedModuleContainingExtensionMember() = (3).Q member x.UseSomeUsedModuleContainingUnion() = A """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - - let fileCheckResults = - keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunSynchronously - |> function + + let fileCheckResults = + keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res | _ -> failwithf "Parsing aborted unexpectedly..." - //let symbolUses = fileCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously |> Array.indexed + //let symbolUses = fileCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunImmediate |> Array.indexed // Fragments used to check hash codes: //(snd symbolUses.[42]).Symbol.IsEffectivelySameAs((snd symbolUses.[37]).Symbol) //(snd symbolUses.[42]).Symbol.GetEffectivelySameAsHash() //(snd symbolUses.[37]).Symbol.GetEffectivelySameAsHash() - let lines = File.ReadAllLines(fileName1) - let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunSynchronously + let lines = FileSystem.OpenFileForReadShim(fileName1).ReadAllLines() + let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunImmediate let unusedOpensData = [ for uo in unusedOpens -> tups uo, lines.[uo.StartLine-1] ] - let expected = + let expected = [(((4, 5), (4, 23)), "open System.Collections // unused"); (((6, 5), (6, 19)), "open FSharp.Control // unused"); (((7, 5), (7, 16)), "open FSharp.Data // unused"); @@ -5383,8 +5445,8 @@ type UseTheThings(i:int) = [] let ``Unused opens in non rec module smoke test 1``() = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ @@ -5396,19 +5458,19 @@ open FSharp.Control // unused open FSharp.Data // unused open System.Globalization // unused -module SomeUnusedModule = +module SomeUnusedModule = let f x = x -module SomeUsedModuleContainingFunction = +module SomeUsedModuleContainingFunction = let g x = x -module SomeUsedModuleContainingActivePattern = +module SomeUsedModuleContainingActivePattern = let (|ActivePattern|) x = x -module SomeUsedModuleContainingExtensionMember = +module SomeUsedModuleContainingExtensionMember = type System.Int32 with member x.Q = 1 -module SomeUsedModuleContainingUnion = +module SomeUsedModuleContainingUnion = type Q = A | B open SomeUnusedModule @@ -5424,28 +5486,28 @@ type UseTheThings(i:int) = member x.UseSomeUsedModuleContainingExtensionMember() = (3).Q member x.UseSomeUsedModuleContainingUnion() = A """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - - let fileCheckResults = - keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunSynchronously - |> function + + let fileCheckResults = + keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res | _ -> failwithf "Parsing aborted unexpectedly..." - //let symbolUses = fileCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunSynchronously |> Array.indexed + //let symbolUses = fileCheckResults.GetAllUsesOfAllSymbolsInFile() |> Async.RunImmediate |> Array.indexed // Fragments used to check hash codes: //(snd symbolUses.[42]).Symbol.IsEffectivelySameAs((snd symbolUses.[37]).Symbol) //(snd symbolUses.[42]).Symbol.GetEffectivelySameAsHash() //(snd symbolUses.[37]).Symbol.GetEffectivelySameAsHash() - let lines = File.ReadAllLines(fileName1) - let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunSynchronously + let lines = FileSystem.OpenFileForReadShim(fileName1).ReadAllLines() + let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunImmediate let unusedOpensData = [ for uo in unusedOpens -> tups uo, lines.[uo.StartLine-1] ] - let expected = + let expected = [(((4, 5), (4, 23)), "open System.Collections // unused"); (((6, 5), (6, 19)), "open FSharp.Control // unused"); (((7, 5), (7, 16)), "open FSharp.Data // unused"); @@ -5456,8 +5518,8 @@ type UseTheThings(i:int) = [] let ``Unused opens smoke test auto open``() = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() + let fileName1 = Path.ChangeExtension(tryCreateTemporaryFileName (), ".fs") + let base2 = tryCreateTemporaryFileName () let dllName = Path.ChangeExtension(base2, ".dll") let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1Text = """ @@ -5468,20 +5530,20 @@ open FSharp.Data // unused open System.Globalization // unused [] -module Helpers = - module SomeUnusedModule = +module Helpers = + module SomeUnusedModule = let f x = x - module SomeUsedModuleContainingFunction = + module SomeUsedModuleContainingFunction = let g x = x - module SomeUsedModuleContainingActivePattern = + module SomeUsedModuleContainingActivePattern = let (|ActivePattern|) x = x - module SomeUsedModuleContainingExtensionMember = + module SomeUsedModuleContainingExtensionMember = type System.Int32 with member x.Q = 1 - module SomeUsedModuleContainingUnion = + module SomeUsedModuleContainingUnion = type Q = A | B open SomeUnusedModule @@ -5505,23 +5567,23 @@ module M2 = let foo x = x.Field """ - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - File.WriteAllText(fileName1, fileSource1Text) + let fileSource1 = SourceText.ofString fileSource1Text + FileSystem.OpenFileForWriteShim(fileName1).Write(fileSource1Text) let fileNames = [fileName1] let args = mkProjectCommandLineArgs (dllName, fileNames) let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true) let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - - let fileCheckResults = - keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunSynchronously - |> function + + let fileCheckResults = + keepAssemblyContentsChecker.ParseAndCheckFileInProject(fileName1, 0, fileSource1, options) |> Async.RunImmediate + |> function | _, FSharpCheckFileAnswer.Succeeded(res) -> res | _ -> failwithf "Parsing aborted unexpectedly..." - let lines = File.ReadAllLines(fileName1) - let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunSynchronously + let lines = FileSystem.OpenFileForReadShim(fileName1).ReadAllLines() + let unusedOpens = UnusedOpens.getUnusedOpens (fileCheckResults, (fun i -> lines.[i-1])) |> Async.RunImmediate let unusedOpensData = [ for uo in unusedOpens -> tups uo, lines.[uo.StartLine-1] ] - let expected = + let expected = [(((2, 5), (2, 23)), "open System.Collections // unused"); (((4, 5), (4, 19)), "open FSharp.Control // unused"); (((5, 5), (5, 16)), "open FSharp.Data // unused"); @@ -5577,7 +5639,36 @@ module Nested = |> List.ofSeq |> List.map(fun openDeclaration -> tups openDeclaration.AppliedScope) |> shouldEqual - [ (4, 5), (7, 15) + [ (4, 0), (7, 15) (6, 0), (7, 15) - (11, 5), (14, 15) + (11, 0), (14, 15) (13, 0), (14, 15) ] + +let checkContentAsScript content = + // can't use the helper function in these tests because `getParseAndCheckResults` doesn't seem to operate in a mode + // that uses the dependency manager (possibly because `useSdkScripts` isn't set/`assumeDotNetFramework` is implicitly + // set). + // because of this we have to do it all manually + let scriptName = "test.fsx" + let tempDir = Path.GetTempPath() + let scriptFullPath = Path.Combine(tempDir, scriptName) + let sourceText = SourceText.ofString content + let projectOptions, _ = checker.GetProjectOptionsFromScript(scriptFullPath, sourceText, useSdkRefs = true, assumeDotNetFramework = false) |> Async.RunImmediate + let parseOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions + let parseResults = checker.ParseFile(scriptFullPath, sourceText, parseOptions) |> Async.RunImmediate + let checkResults = checker.CheckFileInProject(parseResults, scriptFullPath, 0, sourceText, projectOptions) |> Async.RunImmediate + match checkResults with + | FSharpCheckFileAnswer.Aborted -> failwith "no check results" + | FSharpCheckFileAnswer.Succeeded r -> r + +[] +let ``References from #r nuget are included in script project options`` () = + let checkResults = checkContentAsScript """ +#r "nuget: Dapper" +""" + let assemblyNames = + checkResults.ProjectContext.GetReferencedAssemblies() + |> Seq.choose (fun f -> f.FileName |> Option.map Path.GetFileName) + |> Seq.distinct + printfn "%s" (assemblyNames |> String.concat "\n") + assemblyNames |> should contain "Dapper.dll" diff --git a/tests/service/ProjectOptionsTests.fs b/tests/service/ProjectOptionsTests.fs deleted file mode 100644 index ed30de97dc3..00000000000 --- a/tests/service/ProjectOptionsTests.fs +++ /dev/null @@ -1,578 +0,0 @@ -#if INTERACTIVE -#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive -#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.ProjectCracker.dll" -#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" -#load "FsUnit.fs" -#load "Common.fs" -#else -module FSharp.Compiler.Service.Tests.ProjectOptionsTests -#endif - -let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e -> false - -open System.IO -open NUnit.Framework -open FsUnit -open FSharp.Compiler.Ast -open FSharp.Compiler.SourceCodeServices - -open FSharp.Compiler.Service.Tests.Common - -#if !NO_PROJECTCRACKER && DISABLED // Disabled tests because of MSBuild API dependencies. The ProjectCracker is basically deprecated in any case - -let hasMSBuild14 = - use engine = new Microsoft.Build.Evaluation.ProjectCollection() - engine.Toolsets |> Seq.exists (fun x -> x.ToolsPath.Contains "v14.0") - -let normalizePath s = (new Uri(s)).LocalPath - -let checkOption (opts:string[]) s = - let found = "Found '"+s+"'" - (if opts |> Array.exists (fun o -> o.EndsWith(s)) then found else "Failed to find '"+s+"'") - |> shouldEqual found - -let checkOptionNotPresent (opts:string[]) s = - let found = "Found '"+s+"'" - let notFound = "Did not expect to find '"+s+"'" - (if opts |> Array.exists (fun o -> o.EndsWith(s)) then found else notFound) - |> shouldEqual notFound - -let getReferencedFilenames = Array.choose (fun (o:string) -> if o.StartsWith("-r:") then o.[3..] |> (Path.GetFileName >> Some) else None) -let getReferencedFilenamesAndContainingFolders = Array.choose (fun (o:string) -> if o.StartsWith("-r:") then o.[3..] |> (fun r -> ((r |> Path.GetFileName), (r |> Path.GetDirectoryName |> Path.GetFileName)) |> Some) else None) -let getOutputFile = Array.pick (fun (o:string) -> if o.StartsWith("--out:") then o.[6..] |> Some else None) - -let getCompiledFilenames = - Array.choose (fun (opt: string) -> - if opt.EndsWith ".fs" then - opt |> Path.GetFileName |> Some - else None) - >> Array.distinct - -(* -[] - let ``Project file parsing example 1 Default Configuration`` () = - let projectFile = __SOURCE_DIRECTORY__ + @"/FSharp.Compiler.Service.Tests.fsproj" - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile) - - checkOption options.SourceFiles "FileSystemTests.fs" - - checkOption options.OtherOptions "FSharp.Compiler.Service.dll" - checkOption options.OtherOptions "--define:TRACE" - checkOption options.OtherOptions "--define:DEBUG" - checkOption options.OtherOptions "--flaterrors" - checkOption options.OtherOptions "--simpleresolution" - checkOption options.OtherOptions "--noframework" - -[] -let ``Project file parsing example 1 Release Configuration`` () = - let projectFile = __SOURCE_DIRECTORY__ + @"/FSharp.Compiler.Service.Tests.fsproj" - // Check with Configuration = Release - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, [("Configuration", "Release")]) - - checkOption options.SourceFiles "FileSystemTests.fs" - - checkOption options.OtherOptions "FSharp.Compiler.Service.dll" - checkOption options.OtherOptions "--define:TRACE" - checkOptionNotPresent options.OtherOptions "--define:DEBUG" - checkOption options.OtherOptions "--debug:pdbonly" - -[] -let ``Project file parsing example 1 Default configuration relative path`` () = - let projectFile = "FSharp.Compiler.Service.Tests.fsproj" - Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__) - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile) - - checkOption options.SourceFiles "FileSystemTests.fs" - - checkOption options.OtherOptions "FSharp.Compiler.Service.dll" - checkOption options.OtherOptions "--define:TRACE" - checkOption options.OtherOptions "--define:DEBUG" - checkOption options.OtherOptions "--flaterrors" - checkOption options.OtherOptions "--simpleresolution" - checkOption options.OtherOptions "--noframework" -*) - -[] -let ``Project file parsing VS2013_FSharp_Portable_Library_net45``() = - if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok - - let projectFile = __SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net45/Sample_VS2013_FSharp_Portable_Library_net45.fsproj" - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, []) - - checkOption options.OtherOptions "--targetprofile:netcore" - checkOption options.OtherOptions "--tailcalls-" - - checkOption options.OtherOptions "FSharp.Core.dll" - checkOption options.OtherOptions "Microsoft.CSharp.dll" - checkOption options.OtherOptions "System.Runtime.dll" - checkOption options.OtherOptions "System.Net.Requests.dll" - checkOption options.OtherOptions "System.Xml.XmlSerializer.dll" - -[] -let ``Project file parsing Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78``() = - if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok - - let projectFile = __SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/Sample_VS2013_FSharp_Portable_Library_net451.fsproj" - Directory.SetCurrentDirectory(__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/") - let options = ProjectCracker.GetProjectOptionsFromProjectFile(projectFile, []) - - checkOption options.OtherOptions "--targetprofile:netcore" - checkOption options.OtherOptions "--tailcalls-" - - checkOption options.OtherOptions "FSharp.Core.dll" - checkOption options.OtherOptions "Microsoft.CSharp.dll" - checkOption options.OtherOptions "System.Runtime.dll" - checkOption options.OtherOptions "System.Net.Requests.dll" - checkOption options.OtherOptions "System.Xml.XmlSerializer.dll" - -[] -let ``Project file parsing -- compile files 1``() = - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj") - CollectionAssert.AreEqual (["Test1File2.fs"; "Test1File1.fs"], opts.SourceFiles |> Array.map Path.GetFileName) - CollectionAssert.IsEmpty (getCompiledFilenames opts.OtherOptions) - -[] -let ``Project file parsing -- compile files 2``() = - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj") - - CollectionAssert.AreEqual (["Test2File2.fs"; "Test2File1.fs"], opts.SourceFiles |> Array.map Path.GetFileName) - CollectionAssert.IsEmpty (getCompiledFilenames opts.OtherOptions) - -[] -let ``Project file parsing -- bad project file``() = - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/Malformed.fsproj") - try - ProjectCracker.GetProjectOptionsFromProjectFileLogged(f) |> ignore - failwith "Expected exception" - with e -> - Assert.That(e.Message, Contains.Substring "Could not load project") - Assert.That(e.Message, Contains.Substring "Malformed.fsproj") - -[] -let ``Project file parsing -- non-existent project file``() = - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/DoesNotExist.fsproj") - try - ProjectCracker.GetProjectOptionsFromProjectFileLogged(f, enableLogging=true) |> ignore - with e -> - Assert.That(e.Message, Contains.Substring "DoesNotExist.fsproj") - -[] -let ``Project file parsing -- output file``() = - let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj") - - let expectedOutputPath = - normalizePath (__SOURCE_DIRECTORY__ + "/data/bin/Debug/Test1.dll") - - p.OtherOptions - |> getOutputFile - |> should equal expectedOutputPath - -[] -let ``Project file parsing -- references``() = - let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj") - - let references = getReferencedFilenames p.OtherOptions - checkOption references "FSharp.Core.dll" - checkOption references "mscorlib.dll" - checkOption references "System.Core.dll" - checkOption references "System.dll" - printfn "Project file parsing -- references: references = %A" references - references |> should haveLength 4 - p.ReferencedProjects |> should be Empty - -[] -let ``Project file parsing -- no project references``() = - let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Test3.fsproj") - - let references = getReferencedFilenames p.OtherOptions - checkOption references "FSharp.Core.dll" - checkOption references "mscorlib.dll" - checkOption references "System.Core.dll" - checkOption references "System.dll" - p.ReferencedProjects |> should haveLength 0 - -[] -let ``Project file parsing -- 2nd level references``() = - let p,_ = ProjectCracker.GetProjectOptionsFromProjectFileLogged(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj", enableLogging=true) - - let references = getReferencedFilenames p.OtherOptions - checkOption references "FSharp.Core.dll" - checkOption references "mscorlib.dll" - checkOption references "System.Core.dll" - checkOption references "System.dll" - checkOption references "Test1.dll" - printfn "Project file parsing -- references: references = %A" references - references |> should haveLength 5 - p.ReferencedProjects |> should haveLength 1 - (snd p.ReferencedProjects.[0]).ProjectFileName |> should contain (normalizePath (__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj")) - - -[] -let ``Project file parsing -- reference project output file``() = - let p = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/DifferingOutputDir/Dir2/Test2.fsproj") - - let expectedOutputPath = - normalizePath (__SOURCE_DIRECTORY__ + "/data/DifferingOutputDir/Dir2/OutputDir2/Test2.exe") - - p.OtherOptions - |> getOutputFile - |> should equal expectedOutputPath - - p.OtherOptions - |> Array.choose (fun (o:string) -> if o.StartsWith("-r:") then o.[3..] |> Some else None) - |> should contain (normalizePath (__SOURCE_DIRECTORY__ + @"/data/DifferingOutputDir/Dir1/OutputDir1/Test1.dll")) - -[] -let ``Project file parsing -- Tools Version 12``() = - if not hasMSBuild14 then () else - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj") - checkOption (getReferencedFilenames opts.OtherOptions) "System.Core.dll" - -[] -let ``Project file parsing -- Logging``() = - if not hasMSBuild14 then () else - let projectFileName = normalizePath (__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj") - let _, logMap = ProjectCracker.GetProjectOptionsFromProjectFileLogged(projectFileName, enableLogging=true) - let log = logMap.[projectFileName] - - Assert.That(log, Does.Contain("ResolveAssemblyReference")) - if runningOnMono then - Assert.That(log, Does.Contain("System.Core")) - Assert.That(log, Does.Contain("Microsoft.Build.Tasks.ResolveAssemblyReference")) - else - Assert.That(log, Does.Contain("Microsoft.Build.Tasks.Core")) - -[] -let ``Project file parsing -- FSharpProjectOptions.SourceFiles contains both fs and fsi files``() = - let projectFileName = normalizePath (__SOURCE_DIRECTORY__ + @"/data/FsAndFsiFiles.fsproj") - let options, log = ProjectCracker.GetProjectOptionsFromProjectFileLogged(projectFileName, enableLogging=true) - printfn "%A" log - let expectedSourceFiles = - [| "Test1File2.fsi" - "Test1File2.fs" - "Test1File1.fs" - "Test1File0.fsi" - "Test1File0.fs" |] - Assert.That(options.SourceFiles |> Array.map Path.GetFileName, Is.EqualTo expectedSourceFiles, "source files") - -[] -let ``Project file parsing -- Full path``() = - if not hasMSBuild14 then () else - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/ToolsVersion12.fsproj") - let p = ProjectCracker.GetProjectOptionsFromProjectFile(f) - p.ProjectFileName |> should equal f - -[] -let ``Project file parsing -- project references``() = - let f1 = normalizePath (__SOURCE_DIRECTORY__ + @"/data/Test1.fsproj") - let f2 = normalizePath (__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj") - let options = ProjectCracker.GetProjectOptionsFromProjectFile(f2) - - options.ReferencedProjects |> should haveLength 1 - fst options.ReferencedProjects.[0] |> should endWith "Test1.dll" - snd options.ReferencedProjects.[0] |> should equal (ProjectCracker.GetProjectOptionsFromProjectFile(f1)) - -[] -let ``Project file parsing -- multi language project``() = - if not hasMSBuild14 then () else - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/data/MultiLanguageProject/ConsoleApplication1.fsproj") - - let options = ProjectCracker.GetProjectOptionsFromProjectFile(f) - - options.ReferencedProjects |> should haveLength 1 - options.ReferencedProjects.[0] |> fst |> should endWith "ConsoleApplication2.exe" - - checkOption options.OtherOptions "ConsoleApplication2.exe" - checkOption options.OtherOptions "ConsoleApplication3.exe" - -[] -let ``Project file parsing -- PCL profile7 project``() = - if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok - - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net45/Sample_VS2013_FSharp_Portable_Library_net45.fsproj") - - let options = ProjectCracker.GetProjectOptionsFromProjectFile(f) - let references = - options.OtherOptions - |> getReferencedFilenames - |> Set.ofArray - references - |> shouldEqual - (set [|"FSharp.Core.dll"; "Microsoft.CSharp.dll"; "Microsoft.VisualBasic.dll"; - "System.Collections.Concurrent.dll"; "System.Collections.dll"; - "System.ComponentModel.Annotations.dll"; - "System.ComponentModel.DataAnnotations.dll"; - "System.ComponentModel.EventBasedAsync.dll"; "System.ComponentModel.dll"; - "System.Core.dll"; "System.Diagnostics.Contracts.dll"; - "System.Diagnostics.Debug.dll"; "System.Diagnostics.Tools.dll"; - "System.Diagnostics.Tracing.dll"; "System.Dynamic.Runtime.dll"; - "System.Globalization.dll"; "System.IO.Compression.dll"; "System.IO.dll"; - "System.Linq.Expressions.dll"; "System.Linq.Parallel.dll"; - "System.Linq.Queryable.dll"; "System.Linq.dll"; "System.Net.Http.dll"; - "System.Net.NetworkInformation.dll"; "System.Net.Primitives.dll"; - "System.Net.Requests.dll"; "System.Net.dll"; "System.Numerics.dll"; - "System.ObjectModel.dll"; "System.Reflection.Context.dll"; - "System.Reflection.Extensions.dll"; "System.Reflection.Primitives.dll"; - "System.Reflection.dll"; "System.Resources.ResourceManager.dll"; - "System.Runtime.Extensions.dll"; - "System.Runtime.InteropServices.WindowsRuntime.dll"; - "System.Runtime.InteropServices.dll"; "System.Runtime.Numerics.dll"; - "System.Runtime.Serialization.Json.dll"; - "System.Runtime.Serialization.Primitives.dll"; - "System.Runtime.Serialization.Xml.dll"; "System.Runtime.Serialization.dll"; - "System.Runtime.dll"; "System.Security.Principal.dll"; - "System.ServiceModel.Duplex.dll"; "System.ServiceModel.Http.dll"; - "System.ServiceModel.NetTcp.dll"; "System.ServiceModel.Primitives.dll"; - "System.ServiceModel.Security.dll"; "System.ServiceModel.Web.dll"; - "System.ServiceModel.dll"; "System.Text.Encoding.Extensions.dll"; - "System.Text.Encoding.dll"; "System.Text.RegularExpressions.dll"; - "System.Threading.Tasks.Parallel.dll"; "System.Threading.Tasks.dll"; - "System.Threading.dll"; "System.Windows.dll"; "System.Xml.Linq.dll"; - "System.Xml.ReaderWriter.dll"; "System.Xml.Serialization.dll"; - "System.Xml.XDocument.dll"; "System.Xml.XmlSerializer.dll"; "System.Xml.dll"; - "System.dll"; "mscorlib.dll"|]) - - checkOption options.OtherOptions "--targetprofile:netcore" - -[] -let ``Project file parsing -- PCL profile78 project``() = - if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok - - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile78/Sample_VS2013_FSharp_Portable_Library_net451.fsproj") - - let options = ProjectCracker.GetProjectOptionsFromProjectFile(f) - let references = - options.OtherOptions - |> getReferencedFilenames - |> Set.ofArray - references - |> shouldEqual - (set [|"FSharp.Core.dll"; "Microsoft.CSharp.dll"; "System.Collections.dll"; - "System.ComponentModel.EventBasedAsync.dll"; "System.ComponentModel.dll"; - "System.Core.dll"; "System.Diagnostics.Contracts.dll"; - "System.Diagnostics.Debug.dll"; "System.Diagnostics.Tools.dll"; - "System.Dynamic.Runtime.dll"; "System.Globalization.dll"; "System.IO.dll"; - "System.Linq.Expressions.dll"; "System.Linq.Queryable.dll"; "System.Linq.dll"; - "System.Net.NetworkInformation.dll"; "System.Net.Primitives.dll"; - "System.Net.Requests.dll"; "System.Net.dll"; "System.ObjectModel.dll"; - "System.Reflection.Extensions.dll"; "System.Reflection.Primitives.dll"; - "System.Reflection.dll"; "System.Resources.ResourceManager.dll"; - "System.Runtime.Extensions.dll"; - "System.Runtime.InteropServices.WindowsRuntime.dll"; - "System.Runtime.Serialization.Json.dll"; - "System.Runtime.Serialization.Primitives.dll"; - "System.Runtime.Serialization.Xml.dll"; "System.Runtime.Serialization.dll"; - "System.Runtime.dll"; "System.Security.Principal.dll"; - "System.ServiceModel.Http.dll"; "System.ServiceModel.Primitives.dll"; - "System.ServiceModel.Security.dll"; "System.ServiceModel.Web.dll"; - "System.ServiceModel.dll"; "System.Text.Encoding.Extensions.dll"; - "System.Text.Encoding.dll"; "System.Text.RegularExpressions.dll"; - "System.Threading.Tasks.dll"; "System.Threading.dll"; "System.Windows.dll"; - "System.Xml.Linq.dll"; "System.Xml.ReaderWriter.dll"; - "System.Xml.Serialization.dll"; "System.Xml.XDocument.dll"; - "System.Xml.XmlSerializer.dll"; "System.Xml.dll"; "System.dll"; "mscorlib.dll"|]) - - checkOption options.OtherOptions "--targetprofile:netcore" - -[] -let ``Project file parsing -- PCL profile259 project``() = - if (not hasMSBuild14) || runningOnMono then () else // Disabled on Mono due to lack of installed PCL reference libraries - the modern way is to reference the FSHarp.Core nuget package so this is ok - let f = normalizePath (__SOURCE_DIRECTORY__ + @"/../projects/Sample_VS2013_FSharp_Portable_Library_net451_adjusted_to_profile259/Sample_VS2013_FSharp_Portable_Library_net451.fsproj") - - let options = ProjectCracker.GetProjectOptionsFromProjectFile(f) - let references = - options.OtherOptions - |> getReferencedFilenames - |> Set.ofArray - references - |> shouldEqual - (set [|"FSharp.Core.dll"; "Microsoft.CSharp.dll"; "System.Collections.dll"; - "System.ComponentModel.EventBasedAsync.dll"; "System.ComponentModel.dll"; - "System.Core.dll"; "System.Diagnostics.Contracts.dll"; - "System.Diagnostics.Debug.dll"; "System.Diagnostics.Tools.dll"; - "System.Dynamic.Runtime.dll"; "System.Globalization.dll"; "System.IO.dll"; - "System.Linq.Expressions.dll"; "System.Linq.Queryable.dll"; "System.Linq.dll"; - "System.Net.NetworkInformation.dll"; "System.Net.Primitives.dll"; - "System.Net.Requests.dll"; "System.Net.dll"; "System.ObjectModel.dll"; - "System.Reflection.Extensions.dll"; "System.Reflection.Primitives.dll"; - "System.Reflection.dll"; "System.Resources.ResourceManager.dll"; - "System.Runtime.Extensions.dll"; - "System.Runtime.InteropServices.WindowsRuntime.dll"; - "System.Runtime.Serialization.Json.dll"; - "System.Runtime.Serialization.Primitives.dll"; - "System.Runtime.Serialization.Xml.dll"; "System.Runtime.Serialization.dll"; - "System.Runtime.dll"; "System.Security.Principal.dll"; - "System.ServiceModel.Web.dll"; "System.Text.Encoding.Extensions.dll"; - "System.Text.Encoding.dll"; "System.Text.RegularExpressions.dll"; - "System.Threading.Tasks.dll"; "System.Threading.dll"; "System.Windows.dll"; - "System.Xml.Linq.dll"; "System.Xml.ReaderWriter.dll"; - "System.Xml.Serialization.dll"; "System.Xml.XDocument.dll"; - "System.Xml.XmlSerializer.dll"; "System.Xml.dll"; "System.dll"; "mscorlib.dll"|]) - - checkOption options.OtherOptions "--targetprofile:netcore" - -(* -[] -let ``Project file parsing -- Exe with a PCL reference``() = - - let f = normalizePath(__SOURCE_DIRECTORY__ + @"/data/sqlite-net-spike/sqlite-net-spike.fsproj") - - let p = ProjectCracker.GetProjectOptionsFromProjectFile(f) - let references = getReferencedFilenames p.OtherOptions |> set - references |> should contain "FSharp.Core.dll" - references |> should contain "SQLite.Net.Platform.Generic.dll" - references |> should contain "SQLite.Net.Platform.Win32.dll" - references |> should contain "SQLite.Net.dll" - references |> should contain "System.Collections.Concurrent.dll" - references |> should contain "System.Linq.Queryable.dll" - references |> should contain "System.Resources.ResourceManager.dll" - references |> should contain "System.Threading.dll" - references |> should contain "System.dll" - references |> should contain "mscorlib.dll" - references |> should contain "System.Reflection.dll" - references |> should contain "System.Reflection.Emit.Lightweight.dll" -*) - -[] -let ``Project file parsing -- project file contains project reference to out-of-solution project and is used in release mode``() = - let projectFileName = normalizePath(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj") - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(projectFileName,[("Configuration","Release")]) - let references = getReferencedFilenamesAndContainingFolders opts.OtherOptions |> set - // Check the reference is to a release DLL - references |> should contain ("Test1.dll", "Release") - -[] -let ``Project file parsing -- project file contains project reference to out-of-solution project and is used in debug mode``() = - - let projectFileName = normalizePath(__SOURCE_DIRECTORY__ + @"/data/Test2.fsproj") - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(projectFileName,[("Configuration","Debug")]) - let references = getReferencedFilenamesAndContainingFolders opts.OtherOptions |> set - // Check the reference is to a debug DLL - references |> should contain ("Test1.dll", "Debug") - -[] -let ``Project file parsing -- space in file name``() = - let opts = ProjectCracker.GetProjectOptionsFromProjectFile(__SOURCE_DIRECTORY__ + @"/data/Space in name.fsproj") - CollectionAssert.AreEqual (["Test2File2.fs"; "Test2File1.fs"], opts.SourceFiles |> Array.map Path.GetFileName) - CollectionAssert.IsEmpty (getCompiledFilenames opts.OtherOptions) - -[] -let ``Project file parsing -- report files``() = - let programFilesx86Folder = System.Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") - if not runningOnMono then - - let dirRefs = programFilesx86Folder + @"\Reference Assemblies\Microsoft\FSharp\" - printfn "Enumerating %s" dirRefs - if Directory.Exists(dirRefs) then - for f in Directory.EnumerateFiles(dirRefs,"*",SearchOption.AllDirectories) do - printfn "File: %s" f - - let dir40 = programFilesx86Folder + @"\Microsoft SDKs\F#\4.0\" - printfn "Enumerating %s" dir40 - if Directory.Exists(dir40) then - for f in Directory.EnumerateFiles(dir40,"*",SearchOption.AllDirectories) do - printfn "File: %s" f - - let dir41 = programFilesx86Folder + @"\Microsoft SDKs\F#\4.1\" - printfn "Enumerating %s" dir41 - if Directory.Exists(dir41) then - for f in Directory.EnumerateFiles(dir41,"*",SearchOption.AllDirectories) do - printfn "File: %s" f - -[] -let ``Test OtherOptions order for GetProjectOptionsFromScript`` () = - let test scriptName expected2 = - let scriptPath = __SOURCE_DIRECTORY__ + @"/data/ScriptProject/" + scriptName + ".fsx" - let scriptSource = File.ReadAllText scriptPath - let projOpts, _diagnostics = checker.GetProjectOptionsFromScript(scriptPath, scriptSource) |> Async.RunSynchronously - projOpts.OtherOptions - |> Array.map (fun s -> if s.StartsWith "--" then s else Path.GetFileNameWithoutExtension s) - |> Array.forall (fun s -> Set.contains s expected2) - |> shouldEqual true - - let otherArgs = [|"--noframework"; "--warn:3"; "System.Numerics"; "System.ValueTuple"; "mscorlib"; "FSharp.Core"; "System"; "System.Xml"; "System.Runtime.Remoting"; "System.Runtime.Serialization.Formatters.Soap"; "System.Data"; "System.Drawing"; "System.Core"; "System.Runtime"; "System.Linq"; "System.Reflection"; "System.Linq.Expressions"; "System.Threading.Tasks"; "System.IO"; "System.Net.Requests"; "System.Collections"; "System.Runtime.Numerics"; "System.Threading"; "System.Web"; "System.Web.Services"; "System.Windows.Forms"; "FSharp.Compiler.Interactive.Settings"|] |> Set.ofArray - - test "Main1" otherArgs - test "Main2" otherArgs - test "Main3" otherArgs - test "Main4" otherArgs - test "MainBad" otherArgs - - -#endif - -[] -let ``Test SourceFiles order for GetProjectOptionsFromScript`` () = // See #594 - let test scriptName expected = - let scriptPath = __SOURCE_DIRECTORY__ + @"/data/ScriptProject/" + scriptName + ".fsx" - let scriptSource = File.ReadAllText scriptPath - let projOpts, _diagnostics = - checker.GetProjectOptionsFromScript(scriptPath, FSharp.Compiler.Text.SourceText.ofString scriptSource) - |> Async.RunSynchronously - projOpts.SourceFiles - |> Array.map Path.GetFileNameWithoutExtension - |> shouldEqual expected - test "Main1" [|"BaseLib1"; "Lib1"; "Lib2"; "Main1"|] - test "Main2" [|"BaseLib1"; "Lib1"; "Lib2"; "Lib3"; "Main2"|] - test "Main3" [|"Lib3"; "Lib4"; "Main3"|] - test "Main4" [|"BaseLib2"; "Lib5"; "BaseLib1"; "Lib1"; "Lib2"; "Main4"|] - test "MainBad" [|"MainBad"|] - -[] -#if NETCOREAPP -[] -#endif -let ``Script load closure project`` () = - let fileName1 = Path.GetTempPath() + Path.DirectorySeparatorChar.ToString() + "Impl.fs" - let fileName2 = Path.ChangeExtension(Path.GetTempFileName(), ".fsx") - - let fileSource1Text = """ -module ImplFile - -#if INTERACTIVE -let x = 42 -#endif -""" - let fileSource1 = FSharp.Compiler.Text.SourceText.ofString fileSource1Text - let fileSource2Text = """ -#load "Impl.fs" -ImplFile.x -""" - let fileSource2 = FSharp.Compiler.Text.SourceText.ofString fileSource2Text - File.WriteAllText(fileName1, fileSource1Text) - File.WriteAllText(fileName2, fileSource2Text) - - printfn "------Starting Script load closure project----" - printfn "Getting project options..." - let projectOptions, diagnostics = - checker.GetProjectOptionsFromScript(fileName2, fileSource2, useFsiAuxLib=false) |> Async.RunSynchronously - for d in diagnostics do - printfn "ERROR: %A" d - diagnostics.IsEmpty |> shouldEqual true - - printfn "Parse and check..." - let _, checkResults = - checker.ParseAndCheckFileInProject(fileName2, 0, fileSource2, projectOptions) |> Async.RunSynchronously - - match checkResults with - | FSharpCheckFileAnswer.Succeeded results -> - results.Errors |> shouldEqual [| |] - | _ -> failwith "type check was aborted" - - printfn "Getting parsing options..." - let parsingOptions, diagnostics = checker.GetParsingOptionsFromProjectOptions(projectOptions) - for d in diagnostics do - printfn "ERROR: %A" d - diagnostics.IsEmpty |> shouldEqual true - - printfn "Parsing file..." - let parseResults = checker.ParseFile(fileName1, fileSource1, parsingOptions) |> Async.RunSynchronously - printfn "Checking parsetree..." - parseResults.ParseTree.IsSome |> shouldEqual true - printfn "Checking decls..." - match parseResults.ParseTree.Value with - | ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, modules, _)) -> - let (SynModuleOrNamespace (_, _, _, decls, _, _, _, _)) = modules.Head - decls.Length |> shouldEqual 1 - | _ -> failwith "got sig file" - printfn "------Finished Script load closure project----" diff --git a/tests/service/ScriptOptionsTests.fs b/tests/service/ScriptOptionsTests.fs new file mode 100644 index 00000000000..9b94aedd922 --- /dev/null +++ b/tests/service/ScriptOptionsTests.fs @@ -0,0 +1,97 @@ +#if INTERACTIVE +#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive +#r "../../artifacts/bin/fcs/net461/nunit.framework.dll" +#load "FsUnit.fs" +#load "Common.fs" +#else +module Tests.Service.ScriptOptions +#endif + +open NUnit.Framework +open System.IO +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.IO +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Text +open TestFramework + +// Add additional imports/constructs into this script text to verify that common scenarios +// for FCS script typechecking can be supported +let scriptSource = """ +open System +let pi = Math.PI +""" + +[] +[] +[] +let ``can generate options for different frameworks regardless of execution environment``(assumeNetFx, useSdk, flags) = + let path = Path.GetTempPath() + let file = tryCreateTemporaryFileName () + let tempFile = Path.Combine(path, file) + let _, errors = + checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdk, otherFlags = flags) + |> Async.RunImmediate + match errors with + | [] -> () + | errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdk flags errors + +[] +[] +[] +let ``all default assembly references are system assemblies``(assumeNetFx, useSdkRefs, flags) = + let tempFile = tryCreateTemporaryFileName () + ".fsx" + let options, errors = + checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdkRefs, otherFlags = flags) + |> Async.RunImmediate + match errors with + | [] -> () + | errors -> failwithf "Error while parsing script with assumeNetFx:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdkRefs flags errors + for r in options.OtherOptions do + if r.StartsWith("-r:") then + let ref = Path.GetFullPath(r.[3..]) + let baseName = Path.GetFileNameWithoutExtension(ref) + let projectDir = System.Environment.CurrentDirectory + if not (FSharp.Compiler.FxResolver(assumeNetFx, projectDir, rangeForErrors=range0, useSdkRefs=useSdkRefs, isInteractive=false, sdkDirOverride=None).GetSystemAssemblies().Contains(baseName)) then + printfn "Failing, printing options from GetProjectOptionsFromScript..." + for opt in options.OtherOptions do + printfn "option: %s" opt + failwithf "expected FSharp.Compiler.DotNetFrameworkDependencies.systemAssemblies to contain '%s' because '%s' is a default reference for a script, (assumeNetFx, useSdk, flags) = %A" baseName ref (assumeNetFx, useSdkRefs, flags) + +// This test atempts to use a bad SDK number 666.666.666 +// +// It's disabled because on CI server the SDK is still being resolved to 5.0.101 by `dotnet --version`. +// +// This must be because of some setting in the CI build scripts - e.g. an environment variable +// that allows SDK resolution to be overriden. I've tried to track this down by looking through +// https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet resolution rules +// and the F# and CI settings but can't find the setting that is causing this. +// +// Because of this the test has been manually verified by running locally. +//[] +let ``sdk dir with dodgy global json gives warning``() = + let tempFile = tryCreateTemporaryFileName () + ".fsx" + let tempPath = Path.GetDirectoryName(tempFile) + let globalJsonPath = Path.Combine(tempPath, "global.json") + FileSystem.OpenFileForWriteShim(globalJsonPath).Write("""{ "sdk": { "version": "666.666.666" } }""") + let options, errors = + checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = false, useSdkRefs = true, otherFlags = [| |]) + |> Async.RunImmediate + FileSystem.FileDeleteShim(globalJsonPath) + match errors with + | [] -> + printfn "Failure!" + printfn "tempPath = %A" tempPath + printfn "options = %A" options + let fxResolver = FSharp.Compiler.FxResolver(false, tempPath, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let result = fxResolver.TryGetDesiredDotNetSdkVersionForDirectory() + printfn "sdkVersion = %A" result + + printfn "options = %A" options + failwith "Expected error while parsing script" + | errors -> + for error in errors do + // {C:\Users\Administrator\AppData\Local\Temp\tmp6F0F.tmp.fsx (0,1)-(0,1) The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' ensure the relevant .NET SDK is installed. The output from 'C:\Program Files\dotnet\dotnet.exe --version' in the script directory was: ' 2.1.300 [C:\Program Files\dotnet\sdk] + Assert.AreEqual(3384, error.ErrorNumber) + Assert.AreEqual(tempFile, error.FileName) diff --git a/tests/service/ServiceUntypedParseTests.fs b/tests/service/ServiceUntypedParseTests.fs index ecf91ee4cab..f87580fce66 100644 --- a/tests/service/ServiceUntypedParseTests.fs +++ b/tests/service/ServiceUntypedParseTests.fs @@ -9,10 +9,11 @@ module Tests.Service.ServiceUntypedParseTests open System.IO open FsUnit -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position open NUnit.Framework let [] private Marker = "(* marker *)" @@ -39,14 +40,12 @@ let private (=>) (source: string) (expected: CompletionContext option) = match markerPos with | None -> failwithf "Marker '%s' was not found in the source code" Marker | Some markerPos -> - match parseSourceCode("C:\\test.fs", source) with - | None -> failwith "No parse tree" - | Some parseTree -> - let actual = UntypedParseImpl.TryGetCompletionContext(markerPos, parseTree, lines.[Line.toZ markerPos.Line]) - try Assert.AreEqual(expected, actual) - with e -> - printfn "ParseTree: %A" parseTree - reraise() + let parseTree = parseSourceCode("C:\\test.fs", source) + let actual = ParsedInput.TryGetCompletionContext(markerPos, parseTree, lines.[Line.toZ markerPos.Line]) + try Assert.AreEqual(expected, actual) + with e -> + printfn "ParseTree: %A" parseTree + reraise() module AttributeCompletion = [] @@ -126,17 +125,15 @@ let foo6 = () [<>] let foo7 = () + +[] +let foo8 = () """ - let (SynModuleOrNamespace (_, _, _, decls, _, _, _, _)) = parseSourceCodeAndGetModule source + let (SynModuleOrNamespace (decls = decls)) = parseSourceCodeAndGetModule source decls |> List.map (fun decl -> match decl with - | SynModuleDecl.Let (_,[Binding(_,_,_,_,attributeLists,_,_,_,_,_,_,_)],_) -> - attributeLists |> List.map (fun list -> - let r = list.Range - - list.Attributes.Length, - ((r.StartLine, r.StartColumn), (r.EndLine, r.EndColumn))) - + | SynModuleDecl.Let (_, [SynBinding (attributes = attributeLists)], _) -> + attributeLists |> List.map (fun list -> list.Attributes.Length, getRangeCoords list.Range) | _ -> failwith "Could not get binding") |> shouldEqual [ [ (1, ((2, 0), (2, 5))) ] @@ -145,19 +142,63 @@ let foo7 = () [ (1, ((12, 0), (13, 0))) ] [ (1, ((15, 0), (15, 4))) ] [ (0, ((18, 0), (18, 2))) ] - [ (0, ((21, 0), (21, 4))) ] ] + [ (0, ((21, 0), (21, 4))) ] + [ (1, ((24, 0), (24, 6))) ] ] + + +let rec getParenTypes (synType: SynType): SynType list = + [ match synType with + | SynType.Paren (innerType, _) -> + yield synType + yield! getParenTypes innerType + + | SynType.Fun (argType, returnType, _) -> + yield! getParenTypes argType + yield! getParenTypes returnType + + | SynType.Tuple (_, types, _) -> + for _, synType in types do + yield! getParenTypes synType + + | SynType.AnonRecd (_, fields, _) -> + for _, synType in fields do + yield! getParenTypes synType + + | SynType.App (typeName = typeName; typeArgs = typeArgs) + | SynType.LongIdentApp (typeName = typeName; typeArgs = typeArgs) -> + yield! getParenTypes typeName + for synType in typeArgs do + yield! getParenTypes synType + + | _ -> () ] + +[] +let ``SynType.Paren ranges`` () = + let source = """ +((): int * (int * int)) +((): (int -> int) -> int) +((): ((int))) +""" + let (SynModuleOrNamespace (decls = decls)) = parseSourceCodeAndGetModule source + decls |> List.map (fun decl -> + match decl with + | SynModuleDecl.DoExpr (expr = SynExpr.Paren (expr = SynExpr.Typed (_, synType ,_))) -> + getParenTypes synType + |> List.map (fun synType -> getRangeCoords synType.Range) + | _ -> failwith "Could not get binding") + |> shouldEqual + [ [ (2, 11), (2, 22) ] + [ (3, 5), (3, 17) ] + [ (4, 5), (4, 12); (4, 6), (4, 11) ] ] module TypeMemberRanges = let getTypeMemberRange source = - let (SynModuleOrNamespace (_, _, _, decls, _, _, _, _)) = parseSourceCodeAndGetModule source + let (SynModuleOrNamespace (decls = decls)) = parseSourceCodeAndGetModule source match decls with - | [ SynModuleDecl.Types ([ TypeDefn (_, SynTypeDefnRepr.ObjectModel (_, memberDecls, _), _, _) ], _) ] -> - memberDecls |> List.map (fun memberDecl -> - let range = memberDecl.Range - (range.StartLine, range.StartColumn), (range.EndLine, range.EndColumn)) - + | [ SynModuleDecl.Types ([ SynTypeDefn (_, SynTypeDefnRepr.ObjectModel (_, memberDecls, _), _, _, _) ], _) ] -> + memberDecls |> List.map (fun memberDecl -> getRangeCoords memberDecl.Range) | _ -> failwith "Could not get member" @@ -263,3 +304,1174 @@ type T = new (x:int) = () """ getTypeMemberRange source |> shouldEqual [ (3, 4), (3, 20) ] + + +[] +let ``TryRangeOfRefCellDereferenceContainingPos - simple``() = + let source = """ +let x = false +let y = !x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfRefCellDereferenceContainingPos (mkPos 3 9) + match res with + | Some res -> + res + |> tups + |> fst + |> shouldEqual (3, 8) + | None -> + Assert.Fail("No deref operator found in source.") + +[] +let ``TryRangeOfRefCellDereferenceContainingPos - parens``() = + let source = """ +let x = false +let y = !(x) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfRefCellDereferenceContainingPos (mkPos 3 10) + match res with + | Some res -> + res + |> tups + |> fst + |> shouldEqual (3, 8) + | None -> + Assert.Fail("No deref operator found in source.") + + +[] +let ``TryRangeOfRefCellDereferenceContainingPos - binary expr``() = + let source = """ +let x = false +let y = !(x = false) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfRefCellDereferenceContainingPos (mkPos 3 10) + match res with + | Some res -> + res + |> tups + |> fst + |> shouldEqual (3, 8) + | None -> + Assert.Fail("No deref operator found in source.") + +[] +let ``TryRangeOfRecordExpressionContainingPos - contained``() = + let source = """ +let x = { Name = "Hello" } +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfRecordExpressionContainingPos (mkPos 2 10) + match res with + | Some res -> + res + |> tups + |> shouldEqual ((2, 8), (2, 26)) + | None -> + Assert.Fail("No range of record found in source.") + +[] +let ``TryRangeOfRecordExpressionContainingPos - not contained``() = + let source = """ +let x = { Name = "Hello" } +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfRecordExpressionContainingPos (mkPos 2 7) + Assert.True(res.IsNone, "Expected not to find a range.") + +module FunctionApplicationArguments = + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - Single arg``() = + let source = """ +let f x = () +f 12 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 2)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - Multi arg``() = + let source = """ +let f x y z = () +f 1 2 3 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 2); (3, 4); (3, 6)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - Multi arg parentheses``() = + let source = """ +let f x y z = () +f (1) (2) (3) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 2); (3, 6); (3, 10)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - Multi arg nested parentheses``() = + let source = """ +let f x y z = () +f ((1)) (((2))) ((((3)))) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 3); (3, 10); (3, 19)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - unit``() = + let source = """ +let f () = () +f () +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + Assert.IsTrue(res.IsNone, "Found argument for unit-accepting function, which shouldn't be the case.") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - curried function``() = + let source = """ +let f x y = x + y +f 12 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 2)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - tuple value``() = + let source = """ +let f (t: int * int) = () +let t = (1, 2) +f t +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 4 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(4, 2)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - tuple literal``() = + let source = """ +let f (t: int * int) = () +f (1, 2) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 3); (3, 6)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - tuple value with definition that has explicit names``() = + let source = """ +let f ((x, y): int * int) = () +let t = (1, 2) +f t +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 4 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(4, 2)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - tuple literal inside parens``() = + let source = """ +let f (x, y) = () +f ((1, 2)) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 4); (3, 7)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - tuples with elements as arguments``() = + let source = """ +let f (a, b) = () +f (1, 2) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 3); (3, 6)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - top-level arguments with nested function call``() = + let source = """ +let f x y = x + y +f (f 1 2) 3 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 0) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 2); (3, 10)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - nested function argument positions``() = + let source = """ +let f x y = x + y +f (f 1 2) 3 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 3 3) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(3, 5); (3, 7)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - nested function application in infix expression``() = + let source = """ +let addStr x y = string x + y +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 2 17) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(2, 24)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - nested function application outside of infix expression``() = + let source = """ +let addStr x y = x + string y +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 2 21) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(2, 28)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``GetAllArgumentsForFunctionApplicationAtPostion - nested function applications both inside and outside of infix expression``() = + let source = """ +let addStr x y = string x + string y +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 2 17) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(2, 24)] + | None -> + Assert.Fail("No arguments found in source code") + + + let res = parseFileResults.GetAllArgumentsForFunctionApplicationAtPostion (mkPos 2 28) + match res with + | Some res -> + res + |> List.map (tups >> fst) + |> shouldEqual [(2, 35)] + | None -> + Assert.Fail("No arguments found in source code") + + [] + let ``IsPosContainedInApplication - no``() = + let source = """ +sqrt x +12 +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 3 2), "Pos should not be in application") + + [] + let ``IsPosContainedInApplication - yes, single arg``() = + let source = """ +sqrt x +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.True(parseFileResults.IsPosContainedInApplication (mkPos 2 5), "Pos should be in application") + + [] + let ``IsPosContainedInApplication - yes, multi arg``() = + let source = """ +let add2 x y = x + y +add2 x y +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.True(parseFileResults.IsPosContainedInApplication (mkPos 3 6), "Pos should be in application") + + [] + let ``IsPosContainedInApplication - inside computation expression - no``() = + let source = """ +async { + sqrt +} +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 2 5), "Pos should not be in application") + + [] + let ``IsPosContainedInApplication - inside CE return - no``() = + let source = """ +async { + return sqrt +} +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 2 5), "Pos should not be in application") + + [] + let ``IsPosContainedInApplication - inside CE - yes``() = + let source = """ +let myAdd x y = x + y +async { + return myAdd 1 +} + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 3 18), "Pos should not be in application") + + [] + let ``IsPosContainedInApplication - inside type application``() = + let source = """ +let f<'x> x = () +f + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.True(parseFileResults.IsPosContainedInApplication (mkPos 3 6), "A type application is an application, expected True.") + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - no application``() = + let source = """ +let add2 x y = x + y +add2 x y +12 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 4 2) + Assert.IsTrue(res.IsNone, "Not in a function application but got one") + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - single arg application``() = + let source = """ +sqrt 12.0 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 2 9) + match res with + | None -> Assert.Fail("Expected 'sqrt' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((2, 0), (2, 4)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - multi arg application``() = + let source = """ +let f x y z = () +f 1 2 3 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 5) + match res with + | None -> Assert.Fail("Expected 'f' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 0), (3, 1)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - multi arg application but at function itself``() = + let source = """ +let f x y z = () +f 1 2 3 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 1) + match res with + | None -> Assert.Fail("Expected 'f' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 0), (3, 1)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - function in pipeline``() = + let source = """ +[1..10] |> List.map id +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 2 20) + match res with + | None -> Assert.Fail("Expected 'List.map' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((2, 11), (2, 19)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - function in middle of pipeline``() = + let source = """ +[1..10] +|> List.filter (fun x -> x > 3) +|> List.map id +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 14) + match res with + | None -> Assert.Fail("Expected 'List.filter' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 3), (3, 14)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - function in middle of pipeline, no qualification``() = + let source = """ +[1..10] +|> id +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 5) + match res with + | None -> Assert.Fail("Expected 'id' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 3), (3, 5)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - incomplete infix app``() = + let source = """ +let add2 x y = x + y +let square x = x * +add2 1 2 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 18) + match res with + | None -> Assert.Fail("Expected '*' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 17), (3, 18)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside CE``() = + let source = """ +let myAdd x y = x + y +async { + return myAdd 1 +} +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 4 18) + match res with + | None -> Assert.Fail("Expected 'myAdd' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((4, 11), (4, 16)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda - binding``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + let sum = add + n.ToString() + ) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 6 21) + match res with + | None -> Assert.Fail("Expected 'add' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((6, 18), (6, 21)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda - if expression``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + if true then + add + else + match add 1 2 with + | 0 when 0 = 0 -> add 1 2 + | _ -> add 1 2 + ) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 7 15) + match res with + | None -> Assert.Fail("Expected 'add' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((7, 12), (7, 15)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda - match expression``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + if true then + add + else + match add 1 2 with + | 0 when 0 = 0 -> add 1 2 + | _ -> add 1 2 + ) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 7 15) + match res with + | None -> Assert.Fail("Expected 'add' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((7, 12), (7, 15)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda - match expr``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + if true then + add + else + match add with + | 0 when 0 = 0 -> add 1 2 + | _ -> add 1 2 + ) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 9 21) + match res with + | None -> Assert.Fail("Expected 'add' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((9, 18), (9, 21)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda - match case``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + if true then + add + else + match add 1 2 with + | 0 when 0 = 0 -> add 1 2 + | _ -> add + ) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 11 22) + match res with + | None -> Assert.Fail("Expected 'add' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((11, 19), (11, 22)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside method call``() = + let source = """ +type C() = static member Yeet(x, y, z) = () +C.Yeet(1, 2, sqrt) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 17) + match res with + | None -> Assert.Fail("Expected 'sqrt' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 13), (3, 17)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - inside method call - parenthesized lambda``() = + let source = """ +type C() = static member Yeet(x, y, z) = () +C.Yeet(1, 2, (fun x -> sqrt)) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 27) + match res with + | None -> Assert.Fail("Expected 'sqrt' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 23), (3, 27)) + + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - generic-typed app``() = + let source = """ +let f<'x> x = () +f +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 6) + match res with + | None -> Assert.Fail("Expected 'f' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 0), (3, 1)) + +module PipelinesAndArgs = + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - No pipeline, no infix app``() = + let source = """ +let f x = () +f 12 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 3 0) + Assert.True(res.IsNone, sprintf "Got a result, did not expect one: %A" res) + + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - No pipeline, but infix app``() = + let source = """ +let square x = x * +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 2 18) + Assert.True(res.IsNone, sprintf "Got a result, did not expect one: %A" res) + + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - Single pipeline``() = + let source = """ +[1..10] |> List.map +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 2 19) + match res with + | Some (ident, numArgs) -> + (ident.idText, numArgs) + |> shouldEqual ("op_PipeRight", 1) + | None -> + Assert.Fail("No pipeline found") + + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - Double pipeline``() = + let source = """ +([1..10], 1) ||> List.fold +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 2 26) + match res with + | Some (ident, numArgs) -> + (ident.idText, numArgs) + |> shouldEqual ("op_PipeRight2", 2) + | None -> + Assert.Fail("No pipeline found") + + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - Triple pipeline``() = + let source = """ +([1..10], [1..10], 3) |||> List.fold2 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 2 37) + match res with + | Some (ident, numArgs) -> + (ident.idText, numArgs) + |> shouldEqual ("op_PipeRight3", 3) + | None -> + Assert.Fail("No pipeline found") + + [] + let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - none when inside lambda``() = + let source = """ +let add n1 n2 = n1 + n2 +let lst = [1; 2; 3] +let mapped = + lst |> List.map (fun n -> + let sum = add 1 + n.ToString() + ) + """ + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 6 22) + Assert.IsTrue(res.IsNone, "Inside a lambda but counted the pipeline outside of that lambda.") + +[] +let ``TryRangeOfExprInYieldOrReturn - not contained``() = + let source = """ +let f x = + x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfExprInYieldOrReturn (mkPos 3 4) + Assert.True(res.IsNone, "Expected not to find a range.") + +[] +let ``TryRangeOfExprInYieldOrReturn - contained``() = + let source = """ +let f x = + return x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfExprInYieldOrReturn (mkPos 3 4) + match res with + | Some range -> + range + |> tups + |> shouldEqual ((3, 11), (3, 12)) + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfParenEnclosingOpEqualsGreaterUsage - not correct operator``() = + let source = """ +let x = y |> y + 1 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfParenEnclosingOpEqualsGreaterUsage (mkPos 2 8) + Assert.True(res.IsNone, "Expected not to find any ranges.") + +[] +let ``TryRangeOfParenEnclosingOpEqualsGreaterUsage - error arg pos``() = + let source = """ +let x = y => y + 1 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfParenEnclosingOpEqualsGreaterUsage (mkPos 2 8) + match res with + | Some (overallRange, argRange, exprRange) -> + [overallRange; argRange; exprRange] + |> List.map tups + |> shouldEqual [((2, 8), (2, 18)); ((2, 8), (2, 9)); ((2, 13), (2, 18))] + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfParenEnclosingOpEqualsGreaterUsage - error expr pos``() = + let source = """ +let x = y => y + 1 +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfParenEnclosingOpEqualsGreaterUsage (mkPos 2 13) + match res with + | Some (overallRange, argRange, exprRange) -> + [overallRange; argRange; exprRange] + |> List.map tups + |> shouldEqual [((2, 8), (2, 18)); ((2, 8), (2, 9)); ((2, 13), (2, 18))] + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfParenEnclosingOpEqualsGreaterUsage - parenthesized lambda``() = + let source = """ +[1..10] |> List.map (x => x + 1) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfParenEnclosingOpEqualsGreaterUsage (mkPos 2 21) + match res with + | Some (overallRange, argRange, exprRange) -> + [overallRange; argRange; exprRange] + |> List.map tups + |> shouldEqual [((2, 21), (2, 31)); ((2, 21), (2, 22)); ((2, 26), (2, 31))] + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfNameOfNearestOuterBindingContainingPos - simple``() = + let source = """ +let x = nameof x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfNameOfNearestOuterBindingContainingPos (mkPos 2 15) + match res with + | Some range -> + range + |> tups + |> shouldEqual ((2, 4), (2, 5)) + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfNameOfNearestOuterBindingContainingPos - inside match``() = + let source = """ +let mySum xs acc = + match xs with + | [] -> acc + | _ :: tail -> + mySum tail (acc + 1) +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfNameOfNearestOuterBindingContainingPos (mkPos 6 8) + match res with + | Some range -> + range + |> tups + |> shouldEqual ((2, 4), (2, 9)) + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfNameOfNearestOuterBindingContainingPos - nested binding``() = + let source = """ +let f x = + let z = 12 + let h x = + h x + g x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfNameOfNearestOuterBindingContainingPos (mkPos 5 8) + match res with + | Some range -> + range + |> tups + |> shouldEqual ((4, 8), (4, 9)) + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +[] +let ``TryRangeOfNameOfNearestOuterBindingContainingPos - nested and after other statements``() = + let source = """ +let f x = + printfn "doot doot" + printfn "toot toot" + let z = 12 + let h x = + h x + g x +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfNameOfNearestOuterBindingContainingPos (mkPos 7 8) + match res with + | Some range -> + range + |> tups + |> shouldEqual ((6, 8), (6, 9)) + | None -> + Assert.Fail("Expected to get a range back, but got none.") + +module TypeAnnotations = + [] + let ``IsTypeAnnotationGivenAtPosition - function - no annotation``() = + let source = """ +let f x = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 6), "Expected no annotation for argument 'x'") + + [] + let ``IsTypeAnnotationGivenAtPosition - function - single arg annotation``() = + let source = """ +let f (x: int) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected annotation for argument 'x'") + + [] + let ``IsTypeAnnotationGivenAtPosition - function - first arg annotated``() = + let source = """ +let f (x: int) y = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 15), "Expected no annotation for argument 'x'") + + [] + let ``IsTypeAnnotationGivenAtPosition - function - second arg annotated``() = + let source = """ +let f x (y: string) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.False(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected no annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 9), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - function - all args annotated``() = + let source = """ +let f (x: int) (y: string) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 16), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - lambda function - all args annotated``() = + let source = """ +let f = fun (x: int) (y: string) -> () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 13), "Expected a annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 22), "Expected a annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - constuctor - arg no annotations``() = + let source = """ +type C(x) = class end +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected no annotation for argument 'x'") + + [] + let ``IsTypeAnnotationGivenAtPosition - constuctor - first arg unannotated``() = + let source = """ +type C(x, y: string) = class end +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected no annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 10), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - constuctor - second arg unannotated``() = + let source = """ +type C(x: int, y) = class end + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 15), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - constuctor - both args annotated``() = + let source = """ +type C(x: int, y: int) = class end + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 7), "Expected annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 15), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method - args no unannotions``() = + let source = """ +type C() = + member _.M(x, y) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected no annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 18), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method - first arg annotated``() = + let source = """ +type C() = + member _.M(x: int, y) = () + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 23), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method - second arg annotated``() = + let source = """ +type C() = + member _.M(x, y: int) = () + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected no annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 18), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method - both args annotated``() = + let source = """ +type C() = + member _.M(x: int, y: string) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 23), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method currying - args no unannotions``() = + let source = """ +type C() = + member _.M x y = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected no annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 17), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method currying - first arg annotated``() = + let source = """ +type C() = + member _.M (x: int) y = () + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 16), "Expected annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 24), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method currying - second arg annotated``() = + let source = """ +type C() = + member _.M x (y: int) = () + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 16), "Expected no annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 18), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method currying - both args annotated``() = + let source = """ +type C() = + member _.M (x: int) (y: string) = () +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 16), "Expected annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 25), "Expected annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - method - only return type annotated``() = + let source = """ +type C() = + member _.M(x): string = "hello" + x +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 3 15), "Expected no annotation for argument 'x'") + + [] + let ``IsTypeAnnotationGivenAtPosition - tuple - no annotations``() = + let source = """ +let (x, y) = (12, "hello") +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 5), "Expected no annotation for value 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 8), "Expected no annotation for value 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - tuple - first value annotated``() = + let source = """ +let (x: int, y) = (12, "hello") +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 5), "Expected annotation for argument 'x'") + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 13), "Expected no annotation for argument 'y'") + + [] + let ``IsTypeAnnotationGivenAtPosition - tuple - second value annotated``() = + let source = """ +let (x, y: string) = (12, "hello") +""" + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 5), "Expected no annotation for argument 'x'") + Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 8), "Expected annotation for argument 'y'") + +module LambdaRecognition = + [] + let ``IsBindingALambdaAtPosition - recognize a lambda``() = + let source = """ +let f = fun x y -> x + y + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsBindingALambdaAtPosition (mkPos 2 4), "Expected 'f' to be a lambda expression") + + [] + let ``IsBindingALambdaAtPosition - recognize a nested lambda``() = + let source = """ +let f = + fun x -> + fun y -> + x + y + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsBindingALambdaAtPosition (mkPos 2 4), "Expected 'f' to be a lambda expression") + + [] + let ``IsBindingALambdaAtPosition - recognize a "partial" lambda``() = + let source = """ +let f x = + fun y -> + x + y + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsTrue(parseFileResults.IsBindingALambdaAtPosition (mkPos 2 4), "Expected 'f' to be a lambda expression") + + [] + let ``IsBindingALambdaAtPosition - not a lambda``() = + let source = """ +let f x y = x + y + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.IsFalse(parseFileResults.IsBindingALambdaAtPosition (mkPos 2 4), "'f' is not a lambda expression'") diff --git a/tests/service/StructureTests.fs b/tests/service/StructureTests.fs index c3583fe5ab1..345450e2827 100644 --- a/tests/service/StructureTests.fs +++ b/tests/service/StructureTests.fs @@ -9,10 +9,10 @@ module Tests.Service.StructureTests open System.IO open NUnit.Framework -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.SourceCodeServices.Structure +open FSharp.Compiler.EditorServices +open FSharp.Compiler.EditorServices.Structure open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Text open System.Text let fileName = Path.Combine (__SOURCE_DIRECTORY__, __SOURCE_FILE__) @@ -42,18 +42,15 @@ let (=>) (source: string) (expectedRanges: (Range * Range) list) = let ast = parseSourceCode(fileName, source) try - match ast with - | Some tree -> - let actual = - Structure.getOutliningRanges lines tree - |> Seq.filter (fun sr -> sr.Range.StartLine <> sr.Range.EndLine) - |> Seq.map (fun sr -> getRange sr.Range, getRange sr.CollapseRange) - |> Seq.sort - |> List.ofSeq - let expected = List.sort expectedRanges - if actual <> expected then - failwithf "Expected %s, but was %s" (formatList expected) (formatList actual) - | None -> failwithf "Expected there to be a parse tree for source:\n%s" source + let actual = + getOutliningRanges lines ast + |> Seq.filter (fun sr -> sr.Range.StartLine <> sr.Range.EndLine) + |> Seq.map (fun sr -> getRange sr.Range, getRange sr.CollapseRange) + |> Seq.sort + |> List.ofSeq + let expected = List.sort expectedRanges + if actual <> expected then + failwithf "Expected %s, but was %s" (formatList expected) (formatList actual) with _ -> printfn "AST:\n%+A" ast reraise() @@ -66,8 +63,13 @@ let ``nested module``() = """ module MyModule = () + +[] +module Module = + () """ - => [ (2, 0, 3, 6), (2, 15, 3, 6) ] + => [ (2, 0, 3, 6), (2, 15, 3, 6) + (5, 0, 7, 6), (6, 13, 7, 6) ] [] let ``module with multiline function``() = @@ -113,10 +115,10 @@ type Color = let ``record with interface``() = """ type Color = - { Red: int - Green: int - Blue: int - } + { Red: + int + mutable Blue: + int } interface IDisposable with member __.Dispose() = @@ -124,8 +126,9 @@ type Color = """ => [ (2, 5, 10, 55), (2, 11, 10, 55) - (3, 4, 4, 14), (3, 4, 4, 14) + (3, 4, 6, 15), (3, 4, 6, 15) (3, 6, 4, 13), (3, 6, 4, 13) + (5, 6, 6, 13), (5, 6, 6, 13) (8, 4, 10, 55), (8, 25, 10, 55) (9, 8, 10, 55), (9, 27, 10, 55) (9, 15, 10, 55), (9, 27, 10, 55) ] @@ -220,13 +223,13 @@ open H open G open H """ - => [ (2, 5, 3, 6), (2, 5, 3, 6) + => [ (2, 0, 3, 6), (2, 0, 3, 6) (5, 0, 19, 17), (5, 8, 19, 17) - (8, 9, 9, 10), (8, 9, 9, 10) + (8, 4, 9, 10), (8, 4, 9, 10) (11, 4, 14, 17), (11, 12, 14, 17) (16, 4, 19, 17), (16, 12, 19, 17) - (17, 13, 18, 14), (17, 13, 18, 14) - (21, 5, 26, 6), (21, 5, 26, 6) ] + (17, 8, 18, 14), (17, 8, 18, 14) + (21, 0, 26, 6), (21, 0, 26, 6) ] [] let ``hash directives``() = @@ -607,3 +610,65 @@ module NestedModule = """ => [ (4, 0, 5, 15), (4, 13, 5, 15) (9, 0, 10, 15), (9, 19, 10, 15) ] + +[] +let ``Member val`` () = + """ +type T() = + member val field1 = + () + + [] + member val field2 = + () + + static member val field3 = + () + + [] + static member val field4 = + () +""" + => [ (2, 5, 15, 10), (2, 7, 15, 10) + (3, 4, 4, 10), (3, 4, 4, 10) + (6, 4, 8, 10), (6, 4, 8, 10) + (10, 4, 11, 10), (10, 4, 11, 10) + (13, 4, 15, 10), (13, 4, 15, 10) ] + +[] +let ``Secondary constructors`` () = + """ +type T() = + new () = + T () + + internal new () = + T () + + [] + new () = + T () +""" + => [ (2, 5, 11, 12), (2, 7, 11, 12) + (3, 4, 4, 12), (3, 7, 4, 12) + (3, 4, 4, 12), (3, 10, 4, 12) + (6, 4, 7, 12), (6, 16, 7, 12) + (6, 4, 7, 12), (6, 19, 7, 12) + (9, 4, 11, 12), (10, 7, 11, 12) + (9, 4, 11, 12), (10, 10, 11, 12) ] + + +[] +let ``Abstract members`` () = + """ +type T() = + abstract Foo: + int + + [] + abstract Foo: + int +""" + => [ (2, 5, 8, 11), (2, 7, 8, 11) + (3, 4, 4, 11), (4, 8, 4, 11) + (6, 4, 8, 11), (8, 8, 8, 11) ] diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index b0932e9075d..85df60c7af4 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -8,9 +8,10 @@ module Tests.Service.Symbols #endif open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax open FsUnit open NUnit.Framework -open FSharp.Compiler.SourceCodeServices module ActivePatterns = @@ -38,8 +39,8 @@ match "foo" with let _, checkResults = parseAndCheckFile fileName source options checkResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.filter (fun su -> su.RangeAlternate.StartLine = line && su.Symbol :? FSharpActivePatternCase) + |> Array.ofSeq + |> Array.filter (fun su -> su.Range.StartLine = line && su.Symbol :? FSharpActivePatternCase) |> Array.map (fun su -> su.Symbol :?> FSharpActivePatternCase) [] @@ -56,6 +57,51 @@ match "foo" with getCaseUsages completePatternInput 7 |> Array.head |> getGroupName |> shouldEqual "|True|False|" getCaseUsages partialPatternInput 7 |> Array.head |> getGroupName |> shouldEqual "|String|_|" +module ExternDeclarations = + [] + let ``Access modifier`` () = + let parseResults, checkResults = getParseAndCheckResults """ +extern int a() +extern int public b() +extern int private c() +""" + let (SynModuleOrNamespace (decls = decls)) = getSingleModuleLikeDecl parseResults.ParseTree + + [ None + Some SynAccess.Public + Some SynAccess.Private ] + |> List.zip decls + |> List.iter (fun (actual, expected) -> + match actual with + | SynModuleDecl.Let (_, [SynBinding (accessibility = access)], _) -> access |> should equal expected + | decl -> Assert.Fail (sprintf "unexpected decl: %O" decl)) + + [ "a", (true, false, false, false) + "b", (true, false, false, false) + "c", (false, false, false, true) ] + |> List.iter (fun (name, expected) -> + match findSymbolByName name checkResults with + | :? FSharpMemberOrFunctionOrValue as mfv -> + let access = mfv.Accessibility + (access.IsPublic, access.IsProtected, access.IsInternal, access.IsPrivate) + |> should equal expected + | _ -> Assert.Fail (sprintf "Couldn't get mfv: %s" name)) + + [] + let ``Range of attribute should be included in SynDecl.Let and SynBinding`` () = + let parseResults = + getParseResults + """ +[] +extern int AccessibleChildren()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(false, [ SynBinding(range = mb) ] , ml) + ]) ])) -> + assertRange (2, 0) (3, 31) ml + assertRange (2, 0) (3, 31) mb + | _ -> Assert.Fail "Could not get valid AST" module XmlDocSig = @@ -100,7 +146,6 @@ module Mod2 = mod1val1.XmlDocSig |> shouldEqual "P:Mod1.val1" mod2func2.XmlDocSig |> shouldEqual "M:Mod1.Mod2.func2" - module Attributes = [] let ``Emit conditional attributes`` () = @@ -119,8 +164,1422 @@ let x = 123 let _, checkResults = parseAndCheckFile fileName source options checkResults.GetAllUsesOfAllSymbolsInFile() - |> Async.RunSynchronously - |> Array.tryFind (fun su -> su.Symbol.DisplayName = "x") - |> Option.orElseWith (fun _ -> failwith "Could not get symbol") - |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) - |> Option.iter (fun symbol -> symbol.Attributes.Count |> shouldEqual 1) + |> Array.ofSeq + |> Array.tryFind (fun su -> su.Symbol.DisplayName = "x") + |> Option.orElseWith (fun _ -> failwith "Could not get symbol") + |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) + |> Option.iter (fun symbol -> symbol.Attributes.Count |> shouldEqual 1) + +module Types = + [] + let ``FSharpType.Print parent namespace qualifiers`` () = + let _, checkResults = getParseAndCheckResults """ +namespace Ns1.Ns2 +type T() = class end +type A = T + +namespace Ns1.Ns3 +type B = Ns1.Ns2.T + +namespace Ns1.Ns4 +open Ns1.Ns2 +type C = Ns1.Ns2.T + +namespace Ns1.Ns5 +open Ns1 +type D = Ns1.Ns2.T + +namespace Ns1.Ns2.Ns6 +type E = Ns1.Ns2.T +""" + [| "A", "T" + "B", "Ns1.Ns2.T" + "C", "T" + "D", "Ns2.T" + "E", "Ns1.Ns2.T" |] + |> Array.iter (fun (symbolName, expectedPrintedType) -> + let symbolUse = findSymbolUseByName symbolName checkResults + match symbolUse.Symbol with + | :? FSharpEntity as entity -> + entity.AbbreviatedType.Format(symbolUse.DisplayContext) + |> should equal expectedPrintedType + + | _ -> Assert.Fail (sprintf "Couldn't get entity: %s" symbolName)) + + [] + let ``FSharpType.Format can use prefix representations`` () = + let _, checkResults = getParseAndCheckResults """ +type 't folks = +| Nil +| Cons of 't * 't folks + +let tester: int folks = Cons(1, Nil) +""" + let prefixForm = "folks" + let entity = "tester" + let symbolUse = findSymbolUseByName entity checkResults + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as v -> + v.FullType.Format (symbolUse.DisplayContext.WithPrefixGenericParameters()) + |> should equal prefixForm + | _ -> Assert.Fail (sprintf "Couldn't get member: %s" entity) + + [] + let ``FSharpType.Format can use suffix representations`` () = + let _, checkResults = getParseAndCheckResults """ +type Folks<'t> = +| Nil +| Cons of 't * Folks<'t> + +let tester: Folks = Cons(1, Nil) +""" + let suffixForm = "int Folks" + let entity = "tester" + let symbolUse = findSymbolUseByName entity checkResults + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as v -> + v.FullType.Format (symbolUse.DisplayContext.WithSuffixGenericParameters()) + |> should equal suffixForm + | _ -> Assert.Fail (sprintf "Couldn't get member: %s" entity) + + [] + let ``FSharpType.Format defaults to derived suffix representations`` () = + let _, checkResults = getParseAndCheckResults """ +type Folks<'t> = +| Nil +| Cons of 't * Folks<'t> + +type 't Group = 't list + +let tester: Folks = Cons(1, Nil) + +let tester2: int Group = [] +""" + let cases = + ["tester", "Folks" + "tester2", "int Group"] + cases + |> List.iter (fun (entityName, expectedTypeFormat) -> + let symbolUse = findSymbolUseByName entityName checkResults + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as v -> + v.FullType.Format symbolUse.DisplayContext + |> should equal expectedTypeFormat + | _ -> Assert.Fail (sprintf "Couldn't get member: %s" entityName) + ) + + [] + let ``Single SynEnumCase contains range of constant`` () = + let parseResults = + getParseResults + """ +type Foo = One = 0x00000001 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [ + SynTypeDefn.SynTypeDefn(typeRepr = + SynTypeDefnRepr.Simple(simpleRepr = SynTypeDefnSimpleRepr.Enum(cases = [ SynEnumCase.SynEnumCase(valueRange = r) ])))]) + ]) ])) -> + assertRange (2, 17) (2, 27) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Multiple SynEnumCase contains range of constant`` () = + let parseResults = + getParseResults + """ +type Foo = + | One = 0x00000001 + | Two = 2 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [ + SynTypeDefn.SynTypeDefn(typeRepr = + SynTypeDefnRepr.Simple(simpleRepr = SynTypeDefnSimpleRepr.Enum(cases = [ SynEnumCase.SynEnumCase(valueRange = r1) + SynEnumCase.SynEnumCase(valueRange = r2) ])))]) + ]) ])) -> + assertRange (3, 13) (3, 23) r1 + assertRange (4, 12) (4, 13) r2 + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynTypeDefn`` () = + let parseResults = + getParseResults + """ +[] +type Bar = + class + end""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [t]) as types + ]) ])) -> + assertRange (2, 0) (5, 7) types.Range + assertRange (2, 0) (5, 7) t.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attributes should be included in recursive types`` () = + let parseResults = + getParseResults + """ +[] +type Foo<'context, 'a> = + | Apply of ApplyCrate<'context, 'a> + +and [] Bar<'context, 'a> = + internal { + Hash : int + Foo : Foo<'a, 'b> + }""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [t1;t2]) as types + ]) ])) -> + assertRange (2, 0) (10, 5) types.Range + assertRange (2, 0) (4, 39) t1.Range + assertRange (6, 4) (10, 5) t2.Range + | _ -> Assert.Fail "Could not get valid AST" + +module SyntaxExpressions = + [] + let ``SynExpr.Do contains the range of the do keyword`` () = + let ast = """let a = + do + foobar + do! + foobarBang +""" + |> getParseResults + + match ast with + | ParsedInput.ImplFile(ParsedImplFileInput(modules = [ + SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [ + SynBinding(expr = SynExpr.Sequential(expr1 = SynExpr.Do(_, doRange) ; expr2 = SynExpr.DoBang(_, doBangRange))) + ]) + ]) + ])) -> + assertRange (2, 4) (3, 14) doRange + assertRange (4, 4) (5, 18) doBangRange + | _ -> + Assert.Fail "Could not find SynExpr.Do" + +module Strings = + let getBindingExpressionValue (parseResults: ParsedInput) = + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules)) -> + modules |> List.tryPick (fun (SynModuleOrNamespace (decls = decls)) -> + decls |> List.tryPick (fun decl -> + match decl with + | SynModuleDecl.Let (bindings = bindings) -> + bindings |> List.tryPick (fun binding -> + match binding with + | SynBinding.SynBinding (_,_,_,_,_,_,_,(SynPat.Named _|SynPat.As(_,SynPat.Named _,_)),_,e,_,_) -> Some e + | _ -> None) + | _ -> None)) + | _ -> None + + let getBindingConstValue parseResults = + match getBindingExpressionValue parseResults with + | Some (SynExpr.Const(c,_)) -> Some c + | _ -> None + + [] + let ``SynConst.String with SynStringKind.Regular`` () = + let parseResults = + getParseResults + """ + let s = "yo" + """ + + match getBindingConstValue parseResults with + | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.Regular + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynConst.String with SynStringKind.Verbatim`` () = + let parseResults = + getParseResults + """ + let s = @"yo" + """ + + match getBindingConstValue parseResults with + | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.Verbatim + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynConst.String with SynStringKind.TripleQuote`` () = + let parseResults = + getParseResults + " + let s = \"\"\"yo\"\"\" + " + + match getBindingConstValue parseResults with + | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.TripleQuote + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynConst.Bytes with SynByteStringKind.Regular`` () = + let parseResults = + getParseResults + """ +let bytes = "yo"B + """ + + match getBindingConstValue parseResults with + | Some (SynConst.Bytes (_, kind, _)) -> kind |> should equal SynByteStringKind.Regular + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynConst.Bytes with SynByteStringKind.Verbatim`` () = + let parseResults = + getParseResults + """ +let bytes = @"yo"B + """ + + match getBindingConstValue parseResults with + | Some (SynConst.Bytes (_, kind, _)) -> kind |> should equal SynByteStringKind.Verbatim + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynExpr.InterpolatedString with SynStringKind.TripleQuote`` () = + let parseResults = + getParseResults + " + let s = $\"\"\"yo {42}\"\"\" + " + + match getBindingExpressionValue parseResults with + | Some (SynExpr.InterpolatedString(_, kind, _)) -> kind |> should equal SynStringKind.TripleQuote + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynExpr.InterpolatedString with SynStringKind.Regular`` () = + let parseResults = + getParseResults + """ + let s = $"yo {42}" + """ + + match getBindingExpressionValue parseResults with + | Some (SynExpr.InterpolatedString(_, kind, _)) -> kind |> should equal SynStringKind.Regular + | _ -> Assert.Fail "Couldn't find const" + + [] + let ``SynExpr.InterpolatedString with SynStringKind.Verbatim`` () = + let parseResults = + getParseResults + """ + let s = $@"Migrate notes of file ""{oldId}"" to new file ""{newId}""." + """ + + match getBindingExpressionValue parseResults with + | Some (SynExpr.InterpolatedString(_, kind, _)) -> kind |> should equal SynStringKind.Verbatim + | _ -> Assert.Fail "Couldn't find const" + +module SynModuleOrNamespace = + [] + let ``DeclaredNamespace range should start at namespace keyword`` () = + let parseResults = + getParseResults + """namespace TypeEquality + +/// A type for witnessing type equality between 'a and 'b +type Teq<'a, 'b> +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.DeclaredNamespace; range = r) ])) -> + assertRange (1, 0) (4, 8) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Multiple DeclaredNamespaces should have a range that starts at the namespace keyword`` () = + let parseResults = + getParseResults + """namespace TypeEquality + +/// A type for witnessing type equality between 'a and 'b +type Teq = class end + +namespace Foobar + +let x = 42 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ + SynModuleOrNamespace.SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.DeclaredNamespace; range = r1) + SynModuleOrNamespace.SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.DeclaredNamespace; range = r2) ])) -> + assertRange (1, 0) (4, 20) r1 + assertRange (6, 0) (8, 10) r2 + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``GlobalNamespace should start at namespace keyword`` () = + let parseResults = + getParseResults + """// foo +// bar +namespace global + +type X = int +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ + SynModuleOrNamespace.SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.GlobalNamespace; range = r) ])) -> + assertRange (3, 0) (5, 12) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Module range should start at first attribute`` () = + let parseResults = + getParseResults + """ +[< Foo >] +module Bar + +let s : string = "s" +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ + SynModuleOrNamespace.SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.NamedModule; range = r) ])) -> + assertRange (2, 0) (5, 20) r + | _ -> Assert.Fail "Could not get valid AST" + +module SynConsts = + [] + let ``Measure contains the range of the constant`` () = + let parseResults = + getParseResults + """ +let n = 1.0m +let m = 7.000 +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [ SynBinding.SynBinding(expr = SynExpr.Const(SynConst.Measure(constantRange = r1), _)) ]) + SynModuleDecl.Let(bindings = [ SynBinding.SynBinding(expr = SynExpr.Const(SynConst.Measure(constantRange = r2), _)) ]) + ]) ])) -> + assertRange (2, 8) (2, 12) r1 + assertRange (3, 8) (3, 13) r2 + | _ -> Assert.Fail "Could not get valid AST" + +module SynModuleOrNamespaceSig = + [] + let ``Range member returns range of SynModuleOrNamespaceSig`` () = + let parseResults = + getParseResultsOfSignatureFile + """ +namespace Foobar + +type Bar = | Bar of string * int +""" + + match parseResults with + | ParsedInput.SigFile(ParsedSigFileInput(modules = [ + SynModuleOrNamespaceSig(kind = SynModuleOrNamespaceKind.DeclaredNamespace) as singleModule + ])) -> + assertRange (2,0) (4,32) singleModule.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``GlobalNamespace should start at namespace keyword`` () = + let parseResults = + getParseResultsOfSignatureFile + """// foo +// bar +namespace global + +type Bar = | Bar of string * int +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(kind = SynModuleOrNamespaceKind.GlobalNamespace; range = r) ])) -> + assertRange (3, 0) (5, 32) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Module range should start at first attribute`` () = + let parseResults = + getParseResultsOfSignatureFile + """ + [< Foo >] +module Bar + +val s : string +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig.SynModuleOrNamespaceSig(kind = SynModuleOrNamespaceKind.NamedModule; range = r) ])) -> + assertRange (2, 1) (5, 14) r + | _ -> Assert.Fail "Could not get valid AST" + +module SignatureTypes = + [] + let ``Range of Type should end at end keyword`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace GreatProjectThing + +type Meh = + class + end + + +// foo""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(range = r)]) ])) -> + assertRange (3, 0) (5,11) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of SynTypeDefnSig record should end at last member`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace X +type MyRecord = + { Level: int } + member Score : unit -> int""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) -> + assertRange (2, 0) (4, 30) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of SynTypeDefnSig object model should end at last member`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace X +type MyRecord = + class + end + member Score : unit -> int""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) -> + assertRange (2, 0) (5, 30) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of SynTypeDefnSig delegate of should start from name`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace Y +type MyFunction = + delegate of int -> string""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) -> + assertRange (2, 0) (3, 29) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of SynTypeDefnSig simple should end at last val`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace Z +type SomeCollection with + val LastIndex : int + val SomeThingElse : int -> string""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) -> + assertRange (2, 0) (4, 37) r + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynTypeDefnSig`` () = + let parseResults = + getParseResultsOfSignatureFile + """ +namespace SomeNamespace + +[] +type MyType = + class + end +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)]) as t]) ])) -> + assertRange (4, 0) (7, 7) r + assertRange (4, 0) (7, 7) t.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attributes should be included in recursive types`` () = + let parseResults = + getParseResultsOfSignatureFile + """ +namespace SomeNamespace + +type Foo = + | Bar + +and [] Bang = + internal + { + LongNameBarBarBarBarBarBarBar: int + } + override GetHashCode : unit -> int +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [ + SynTypeDefnSig.SynTypeDefnSig(range = r1) + SynTypeDefnSig.SynTypeDefnSig(range = r2) + ]) as t]) ])) -> + assertRange (4, 0) (5, 9) r1 + assertRange (7, 4) (12, 42) r2 + assertRange (4, 0) (12, 42) t.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynValSpfn and Member`` () = + let parseResults = + getParseResultsOfSignatureFile + """ +namespace SomeNamespace + +type FooType = + [] // ValSpfn + abstract x : int +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ + SynModuleOrNamespaceSig(decls = + [ SynModuleSigDecl.Types(types = [ + SynTypeDefnSig.SynTypeDefnSig(typeRepr = + SynTypeDefnSigRepr.ObjectModel(memberSigs = [ + SynMemberSig.Member(range = mr; memberSig = SynValSig(range = mv)) ])) + ]) ]) ])) -> + assertRange (5, 4) (6, 20) mr + assertRange (5, 4) (6, 20) mv + | _ -> Assert.Fail "Could not get valid AST" + +module SynMatchClause = + [] + let ``Range of single SynMatchClause`` () = + let parseResults = + getParseResults + """ +try + let content = tryDownloadFile url + Some content +with ex -> + Infrastructure.ReportWarning ex + None""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.TryWith(withCases = [ SynMatchClause(range = range) as clause ])) + ]) ])) -> + assertRange (5, 5) (7, 8) range + assertRange (5, 5) (7, 8) clause.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of multiple SynMatchClause`` () = + let parseResults = + getParseResults + """ +try + let content = tryDownloadFile url + Some content +with +| ex -> + Infrastructure.ReportWarning ex + None +| exx -> + None""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.TryWith(withCases = [ SynMatchClause(range = r1) as clause1 + SynMatchClause(range = r2) as clause2 ])) + ]) ])) -> + assertRange (6, 2) (8, 8) r1 + assertRange (6, 2) (8, 8) clause1.Range + + assertRange (9, 2) (10, 8) r2 + assertRange (9, 2) (10, 8) clause2.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of single SynMatchClause followed by bar`` () = + let parseResults = + getParseResults + """ +try + let content = tryDownloadFile url + Some content +with +| ex -> + () +| """ + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.TryWith(withCases = [ SynMatchClause(range = range) as clause ])) + ]) ])) -> + assertRange (6, 2) (7, 6) range + assertRange (6, 2) (7, 6) clause.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of single SynMatchClause with missing body`` () = + let parseResults = + getParseResults + """ +try + let content = tryDownloadFile url + Some content +with +| ex ->""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.TryWith(withCases = [ SynMatchClause(range = range) as clause ])) + ]) ])) -> + assertRange (6, 2) (6, 4) range + assertRange (6, 2) (6, 4) clause.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of single SynMatchClause with missing body and when expr`` () = + let parseResults = + getParseResults + """ +try + let content = tryDownloadFile url + Some content +with +| ex when (isNull ex) ->""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.TryWith(withCases = [ SynMatchClause(range = range) as clause ])) + ]) ])) -> + assertRange (6, 2) (6, 21) range + assertRange (6, 2) (6, 21) clause.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of arrow in SynMatchClause`` () = + let parseResults = + getParseResults + """ +match foo with +| Bar bar -> ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.Match(clauses = [ SynMatchClause(arrow = Some mArrow) ])) + ]) ])) -> + assertRange (3, 10) (3, 12) mArrow + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of arrow in SynMatchClause with when clause`` () = + let parseResults = + getParseResults + """ +match foo with +| Bar bar when (someCheck bar) -> ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.Match(clauses = [ SynMatchClause(arrow = Some mArrow) ])) + ]) ])) -> + assertRange (3, 31) (3, 33) mArrow + | _ -> Assert.Fail "Could not get valid AST" + +module SourceIdentifiers = + [] + let ``__LINE__`` () = + let parseResults = + getParseResults + """ +__LINE__""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.Const(SynConst.SourceIdentifier("__LINE__", "2", range), _)) + ]) ])) -> + assertRange (2, 0) (2, 8) range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``__SOURCE_DIRECTORY__`` () = + let parseResults = + getParseResults + """ +__SOURCE_DIRECTORY__""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.Const(SynConst.SourceIdentifier("__SOURCE_DIRECTORY__", _, range), _)) + ]) ])) -> + assertRange (2, 0) (2, 20) range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``__SOURCE_FILE__`` () = + let parseResults = + getParseResults + """ +__SOURCE_FILE__""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.Const(SynConst.SourceIdentifier("__SOURCE_FILE__", _, range), _)) + ]) ])) -> + assertRange (2, 0) (2, 15) range + | _ -> Assert.Fail "Could not get valid AST" + +module NestedModules = + + [] + let ``Range of attribute should be included in SynModuleSigDecl.NestedModule`` () = + let parseResults = + getParseResultsOfSignatureFile + """ +namespace SomeNamespace + +[] +module Nested = + val x : int +""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (modules = [ SynModuleOrNamespaceSig(decls = [ + SynModuleSigDecl.NestedModule _ as nm + ]) as sigModule ])) -> + assertRange (4, 0) (6, 15) nm.Range + assertRange (2, 0) (6, 15) sigModule.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynModuleDecl.NestedModule`` () = + let parseResults = + getParseResults + """ +module TopLevel + +[] +module Nested = + ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.NestedModule _ as nm + ]) ])) -> + assertRange (4, 0) (6, 6) nm.Range + | _ -> Assert.Fail "Could not get valid AST" + +module SynBindings = + [] + let ``Range of attribute should be included in SynModuleDecl.Let`` () = + let parseResults = + getParseResults + """ +[] +let a = 0""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [SynBinding(range = mb)]) as lt + ]) ])) -> + assertRange (2, 0) (3, 5) mb + assertRange (2, 0) (3, 9) lt.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute between let keyword and pattern should be included in SynModuleDecl.Let`` () = + let parseResults = + getParseResults + """ +let [] (A x) = 1""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [SynBinding(range = mb)]) as lt + ]) ])) -> + assertRange (2, 4) (2, 21) mb + assertRange (2, 0) (2, 25) lt.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynMemberDefn.LetBindings`` () = + let parseResults = + getParseResults + """ +type Bar = + [] + let x = 8""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [SynMemberDefn.LetBindings(bindings = [SynBinding(range = mb)]) as m]))]) + ]) ])) -> + assertRange (3, 4) (4, 9) mb + assertRange (3, 4) (4, 13) m.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in SynMemberDefn.Member`` () = + let parseResults = + getParseResults + """ +type Bar = + [] + member this.Something () = ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [SynMemberDefn.Member(memberDefn = SynBinding(range = mb)) as m]))]) + ]) ])) -> + assertRange (3, 4) (4, 28) mb + assertRange (3, 4) (4, 33) m.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in binding of SynExpr.ObjExpr`` () = + let parseResults = + getParseResults + """ +{ new System.Object() with + [] + member x.ToString() = "F#" }""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr(expr = SynExpr.ObjExpr(bindings = [SynBinding(range = mb)])) + ]) ])) -> + assertRange (3, 4) (4, 23) mb + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in constructor SynMemberDefn.Member`` () = + let parseResults = + getParseResults + """ +type Tiger = + [] + new () = ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [SynMemberDefn.Member(memberDefn = SynBinding(range = mb)) as m]))]) + ]) ])) -> + assertRange (3, 4) (4, 10) mb + assertRange (3, 4) (4, 15) m.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in constructor SynMemberDefn.Member, optAsSpec`` () = + let parseResults = + getParseResults + """ +type Tiger = + [] + new () as tony = ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [SynMemberDefn.Member(memberDefn = SynBinding(range = mb)) as m]))]) + ]) ])) -> + assertRange (3, 4) (4, 18) mb + assertRange (3, 4) (4, 23) m.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in secondary constructor`` () = + let parseResults = + getParseResults + """ +type T() = + new () = + T () + + internal new () = + T () + + [] + new () = + T ()""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.ImplicitCtor _ + SynMemberDefn.Member(memberDefn = SynBinding(range = mb1)) as m1 + SynMemberDefn.Member(memberDefn = SynBinding(range = mb2)) as m2 + SynMemberDefn.Member(memberDefn = SynBinding(range = mb3)) as m3 + ]))]) + ]) ])) -> + assertRange (3, 4) (3, 10) mb1 + assertRange (3, 4) (4, 12) m1.Range + assertRange (6, 4) (6, 19) mb2 + assertRange (6, 4) (7, 12) m2.Range + assertRange (9, 4) (10, 10) mb3 + assertRange (9, 4) (11, 12) m3.Range + | _ -> Assert.Fail "Could not get valid AST" + + + [] + let ``Range of attribute should be included in write only SynMemberDefn.Member property`` () = + let parseResults = + getParseResults + """ +type Crane = + [] + member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [SynMemberDefn.Member(memberDefn = SynBinding(range = mb)) as m]))]) + ]) ])) -> + assertRange (3, 4) (4, 52) mb + assertRange (3, 4) (4, 79) m.Range + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Range of attribute should be included in full SynMemberDefn.Member property`` () = + let parseResults = + getParseResults + """ +type Bird = + [] + member this.TheWord + with get () = myInternalValue + and set (value) = myInternalValue <- value""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types(typeDefns = [SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.Member(memberDefn = SynBinding(range = mb1)) as getter + SynMemberDefn.Member(memberDefn = SynBinding(range = mb2)) as setter + ]))]) + ]) ])) -> + assertRange (3, 4) (5, 19) mb1 + assertRange (3, 4) (6, 50) getter.Range + assertRange (3, 4) (6, 23) mb2 + assertRange (3, 4) (6, 50) setter.Range + | _ -> Assert.Fail "Could not get valid AST" + +module ParsedHashDirective = + [] + let ``SourceIdentifier as ParsedHashDirectiveArgument`` () = + let parseResults = + getParseResults + "#I __SOURCE_DIRECTORY__" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.SourceIdentifier(c,_,m) ] , _), _) + ]) ])) -> + Assert.AreEqual("__SOURCE_DIRECTORY__", c) + assertRange (1, 3) (1, 23) m + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Regular String as ParsedHashDirectiveArgument`` () = + let parseResults = + getParseResults + "#I \"/tmp\"" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.String(v, SynStringKind.Regular, m) ] , _), _) + ]) ])) -> + Assert.AreEqual("/tmp", v) + assertRange (1, 3) (1, 9) m + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Verbatim String as ParsedHashDirectiveArgument`` () = + let parseResults = + getParseResults + "#I @\"C:\\Temp\"" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.String(v, SynStringKind.Verbatim, m) ] , _), _) + ]) ])) -> + Assert.AreEqual("C:\\Temp", v) + assertRange (1, 3) (1, 13) m + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Triple quote String as ParsedHashDirectiveArgument`` () = + let parseResults = + getParseResults + "#nowarn \"\"\"40\"\"\"" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.HashDirective(ParsedHashDirective("nowarn", [ ParsedHashDirectiveArgument.String(v, SynStringKind.TripleQuote, m) ] , _), _) + ]) ])) -> + Assert.AreEqual("40", v) + assertRange (1, 8) (1, 16) m + | _ -> Assert.Fail "Could not get valid AST" + +module Lambdas = + [] + let ``Lambda with two parameters gives correct body`` () = + let parseResults = + getParseResults + "fun a b -> x" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(parsedData = Some([SynPat.Named _; SynPat.Named _], SynExpr.Ident(ident))) + ) + ]) ])) -> + Assert.AreEqual("x", ident.idText) + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Lambda with wild card parameter gives correct body`` () = + let parseResults = + getParseResults + "fun a _ b -> x" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(parsedData = Some([SynPat.Named _; SynPat.Wild _; SynPat.Named _], SynExpr.Ident(ident))) + ) + ]) ])) -> + Assert.AreEqual("x", ident.idText) + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Lambda with tuple parameter with wild card gives correct body`` () = + let parseResults = + getParseResults + "fun a (b, _) c -> x" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(parsedData = Some([SynPat.Named _; SynPat.Paren(SynPat.Tuple _,_); SynPat.Named _], SynExpr.Ident(ident))) + ) + ]) ])) -> + Assert.AreEqual("x", ident.idText) + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Lambda with wild card that returns a lambda gives correct body`` () = + let parseResults = + getParseResults + "fun _ -> fun _ -> x" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(parsedData = Some([SynPat.Wild _], SynExpr.Lambda(parsedData = Some([SynPat.Wild _], SynExpr.Ident(ident))))) + ) + ]) ])) -> + Assert.AreEqual("x", ident.idText) + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Simple lambda has arrow range`` () = + let parseResults = + getParseResults + "fun x -> x" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(arrow = Some mArrow) + ) + ]) ])) -> + assertRange (1, 6) (1, 8) mArrow + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Multiline lambda has arrow range`` () = + let parseResults = + getParseResults + "fun x y z + -> + x * y * z" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(arrow = Some mArrow) + ) + ]) ])) -> + assertRange (2, 28) (2, 30) mArrow + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Destructed lambda has arrow range`` () = + let parseResults = + getParseResults + "fun { X = x } -> x * 2" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(arrow = Some mArrow) + ) + ]) ])) -> + assertRange (1, 14) (1, 16) mArrow + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Tuple in lambda has arrow range`` () = + let parseResults = + getParseResults + "fun (x, _) -> x * 3" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(arrow = Some mArrow) + ) + ]) ])) -> + assertRange (1, 11) (1, 13) mArrow + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Complex arguments lambda has arrow range`` () = + let parseResults = + getParseResults + "fun (x, _) + ({ Y = h::_ }) + (SomePattern(z)) + -> + x * y + z" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.Lambda(arrow = Some mArrow) + ) + ]) ])) -> + assertRange (4, 4) (4, 6) mArrow + | _ -> Assert.Fail "Could not get valid AST" + +module IfThenElse = + [] + let ``If keyword in IfThenElse`` () = + let parseResults = + getParseResults + "if a then b" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw; isElif = false; thenKeyword = mThenKw; elseKeyword = None) + ) + ]) ])) -> + assertRange (1, 0) (1, 2) mIfKw + assertRange (1, 5) (1, 9) mThenKw + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Else keyword in simple IfThenElse`` () = + let parseResults = + getParseResults + "if a then b else c" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw; isElif = false; thenKeyword = mThenKw; elseKeyword = Some mElse) + ) + ]) ])) -> + assertRange (1, 0) (1, 2) mIfKw + assertRange (1, 5) (1, 9) mThenKw + assertRange (1, 12) (1, 16) mElse + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``If, Then and Else keyword on separate lines`` () = + let parseResults = + getParseResults + """ +if a +then b +else c""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw; isElif = false; thenKeyword = mThenKw; elseKeyword = Some mElse) + ) + ]) ])) -> + assertRange (2, 0) (2, 2) mIfKw + assertRange (3, 0) (3, 4) mThenKw + assertRange (4, 0) (4, 4) mElse + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Nested elif in IfThenElse`` () = + let parseResults = + getParseResults + """ +if a then + b +elif c then d""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw + isElif = false + thenKeyword = mThenKw + elseKeyword = None + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mElif; isElif = true))) + ) + ]) ])) -> + assertRange (2, 0) (2, 2) mIfKw + assertRange (2, 5) (2, 9) mThenKw + assertRange (4, 0) (4, 4) mElif + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Nested else if in IfThenElse`` () = + let parseResults = + getParseResults + """ +if a then + b +else + if c then d""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw + isElif = false + thenKeyword = mThenKw + elseKeyword = Some mElse + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mElseIf; isElif = false))) + ) + ]) ])) -> + assertRange (2, 0) (2, 2) mIfKw + assertRange (2, 5) (2, 9) mThenKw + assertRange (4, 0) (4, 4) mElse + assertRange (5, 4) (5, 6) mElseIf + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Nested else if on the same line in IfThenElse`` () = + let parseResults = + getParseResults + """ +if a then + b +else if c then + d""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIfKw + isElif = false + thenKeyword = mThenKw + elseKeyword = Some mElse + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mElseIf; isElif = false))) + ) + ]) ])) -> + assertRange (2, 0) (2, 2) mIfKw + assertRange (2, 5) (2, 9) mThenKw + assertRange (4, 0) (4, 4) mElse + assertRange (4, 5) (4, 7) mElseIf + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Deeply nested IfThenElse`` () = + let parseResults = + getParseResults + """ +if a then + b +elif c then + d +else + if e then + f + else + g""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIf1 + isElif = false + elseKeyword = None + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mElif + isElif = true + elseKeyword = Some mElse1 + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mIf2 + isElif = false + elseKeyword = Some mElse2)))))) + ]) ])) -> + assertRange (2, 0) (2, 2) mIf1 + assertRange (4, 0) (4, 4) mElif + assertRange (6, 0) (6, 4) mElse1 + assertRange (7, 8) (7, 10) mIf2 + assertRange (9, 8) (9, 12) mElse2 + + | _ -> Assert.Fail "Could not get valid AST" + + [] + let ``Comment between else and if`` () = + let parseResults = + getParseResults + """ +if a then + b +else (* some long comment here *) if c then + d""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.DoExpr( + expr = SynExpr.IfThenElse(ifKeyword = mIf1 + isElif = false + elseKeyword = Some mElse + elseExpr = Some (SynExpr.IfThenElse(ifKeyword = mIf2; isElif = false)))) + ]) ])) -> + assertRange (2, 0) (2, 2) mIf1 + assertRange (4, 0) (4, 4) mElse + assertRange (4, 34) (4, 36) mIf2 + + | _ -> Assert.Fail "Could not get valid AST" diff --git a/tests/service/TokenizerTests.fs b/tests/service/TokenizerTests.fs index 0827ff35027..34e17a552d1 100644 --- a/tests/service/TokenizerTests.fs +++ b/tests/service/TokenizerTests.fs @@ -8,11 +8,10 @@ module FSharp.Compiler.Service.Tests.TokenizerTests #endif -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Tokenization open NUnit.Framework - let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") let rec parseLine(line: string, state: FSharpTokenizerLexState ref, tokenizer: FSharpLineTokenizer) = seq { @@ -32,7 +31,7 @@ let tokenizeLines (lines:string[]) = yield n, parseLine(line, state, tokenizer) |> List.ofSeq ] [] -let ``Tokenizer test 1``() = +let ``Tokenizer test - simple let with string``() = let tokenizedLines = tokenizeLines [| "// Sets the hello wrold variable" @@ -54,5 +53,164 @@ let ``Tokenizer test 1``() = ("STRING_TEXT", "\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); ("STRING_TEXT", "world"); ("STRING", "\""); ("WHITESPACE", " ")])] - Assert.AreEqual(actual, expected) + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) + +[] +let ``Tokenizer test 2 - single line non-nested string interpolation``() = + let tokenizedLines = + tokenizeLines + [| "// Tests tokenizing string interpolation" + "let hello0 = $\"\"" + "let hello1 = $\"Hello world\" " + "let hello2 = $\"Hello world {1+1} = {2}\" " + "let hello0v = @$\"\"" + "let hello1v = @$\"Hello world\" " + "let hello2v = @$\"Hello world {1+1} = {2}\" " |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("LINE_COMMENT", "//"); ("LINE_COMMENT", " "); ("LINE_COMMENT", "Tests"); + ("LINE_COMMENT", " "); ("LINE_COMMENT", "tokenizing"); ("LINE_COMMENT", " "); + ("LINE_COMMENT", "string"); ("LINE_COMMENT", " "); + ("LINE_COMMENT", "interpolation")]); + (1, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello0"); ("WHITESPACE", " "); + ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "$\""); + ("INTERP_STRING_BEGIN_END", "\"")]); + (2, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1"); ("WHITESPACE", " "); + ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "$\""); + ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); ("STRING_TEXT", "world"); + ("INTERP_STRING_BEGIN_END", "\""); ("WHITESPACE", " ")]); + (3, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello2"); ("WHITESPACE", " "); + ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "$\""); + ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); ("STRING_TEXT", "world"); + ("STRING_TEXT", " "); ("INTERP_STRING_BEGIN_PART", "{"); ("INT32", "1"); + ("PLUS_MINUS_OP", "+"); ("INT32", "1"); ("STRING_TEXT", "}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "="); ("STRING_TEXT", " "); + ("INTERP_STRING_PART", "{"); ("INT32", "2"); ("STRING_TEXT", "}"); + ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")]); + (4, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello0v"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "@$\""); ("INTERP_STRING_BEGIN_END", "\"")]); + (5, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1v"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "@$\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); + ("STRING_TEXT", "world"); ("INTERP_STRING_BEGIN_END", "\""); + ("WHITESPACE", " ")]); + (6, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello2v"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "@$\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); + ("STRING_TEXT", "world"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{"); ("INT32", "1"); ("PLUS_MINUS_OP", "+"); + ("INT32", "1"); ("STRING_TEXT", "}"); ("STRING_TEXT", " "); + ("STRING_TEXT", "="); ("STRING_TEXT", " "); ("INTERP_STRING_PART", "{"); + ("INT32", "2"); ("STRING_TEXT", "}"); ("INTERP_STRING_END", "\""); + ("WHITESPACE", " ")]);] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) + + +[] +let ``Tokenizer test - multiline non-nested string interpolation``() = + let tokenizedLines = + tokenizeLines + [| "let hello1t = $\"\"\"abc {1+" + " 1} def\"\"\"" |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1t"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "$\"\"\""); ("STRING_TEXT", "abc"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{"); ("INT32", "1"); ("PLUS_MINUS_OP", "+")]); + (1, + [("WHITESPACE", " "); ("INT32", "1"); ("STRING_TEXT", "}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "def"); ("INTERP_STRING_END", "\"\"\"")])] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) + +[] +// checks nested '{' and nested single-quote strings +let ``Tokenizer test - multi-line nested string interpolation``() = + let tokenizedLines = + tokenizeLines + [| "let hello1t = $\"\"\"abc {\"a\" + " + " { " + " contents = \"b\" " + " }.contents " + " } def\"\"\"" |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1t"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "$\"\"\""); ("STRING_TEXT", "abc"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{"); ("STRING_TEXT", "\""); ("STRING_TEXT", "a"); + ("STRING", "\""); ("WHITESPACE", " "); ("PLUS_MINUS_OP", "+"); + ("WHITESPACE", " ")]); + (1, + [("WHITESPACE", " "); ("LBRACE", "{"); + ("WHITESPACE", " ")]); + (2, + [("WHITESPACE", " "); ("IDENT", "contents"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "\""); ("STRING_TEXT", "b"); ("STRING", "\""); + ("WHITESPACE", " ")]); + (3, + [("WHITESPACE", " "); ("RBRACE", "}"); ("DOT", "."); + ("IDENT", "contents"); ("WHITESPACE", " ")]); + (4, + [("WHITESPACE", " "); ("STRING_TEXT", "}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "def"); ("INTERP_STRING_END", "\"\"\"")])] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) + +[] +let ``Tokenizer test - single-line nested string interpolation``() = + let tokenizedLines = + tokenizeLines + [| " $\"abc { { contents = 1 } }\" " |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("WHITESPACE", " "); ("STRING_TEXT", "$\""); ("STRING_TEXT", "abc"); + ("STRING_TEXT", " "); ("INTERP_STRING_BEGIN_PART", "{"); ("WHITESPACE", " "); + ("LBRACE", "{"); ("WHITESPACE", " "); ("IDENT", "contents"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); ("INT32", "1"); + ("WHITESPACE", " "); ("RBRACE", "}"); ("WHITESPACE", " "); + ("STRING_TEXT", "}"); ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")])] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) diff --git a/tests/service/TreeVisitorTests.fs b/tests/service/TreeVisitorTests.fs index 6ff20227235..206b7daaf8e 100644 --- a/tests/service/TreeVisitorTests.fs +++ b/tests/service/TreeVisitorTests.fs @@ -1,25 +1,22 @@ module Tests.Service.TreeVisitorTests open FSharp.Compiler.Service.Tests.Common -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices.AstTraversal +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Syntax open NUnit.Framework [] let ``Visit type test`` () = let visitor = - { new AstVisitorBase<_>() with + { new SyntaxVisitorBase<_>() with member x.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr - member x.VisitType(_, _) = Some () } + member x.VisitType(_, _, _) = Some () } let source = "123 :? int" - let parseTree = - match parseSourceCode("C:\\test.fs", source) with - | None -> failwith "No parse tree" - | Some parseTree -> parseTree + let parseTree = parseSourceCode("C:\\test.fs", source) - Traverse(mkPos 1 11, parseTree, visitor) + SyntaxTraversal.Traverse(mkPos 1 11, parseTree, visitor) |> Option.defaultWith (fun _ -> failwith "Did not visit type") - Traverse(mkPos 1 3, parseTree, visitor) + SyntaxTraversal.Traverse(mkPos 1 3, parseTree, visitor) |> Option.iter (fun _ -> failwith "Should not visit type") diff --git a/tests/service/data/CSharp_Analysis/CSharpClass.cs b/tests/service/data/CSharp_Analysis/CSharpClass.cs index 13a9e257642..9324b71815f 100644 --- a/tests/service/data/CSharp_Analysis/CSharpClass.cs +++ b/tests/service/data/CSharp_Analysis/CSharpClass.cs @@ -47,21 +47,36 @@ public CSharpClass(int first, string param) } + /// Some docs for Method public int Method(string parameter) { throw new NotImplementedException(); } + /// Some docs for Method2 public int Method2(string optParameter = "empty") { throw new NotImplementedException(); } + /// Some docs for Method3 public int Method3(params string[] variadicParameter) { throw new NotImplementedException(); } + /// Some docs for MethodWithOutref + public int MethodWithOutref(out int outParameter) + { + throw new NotImplementedException(); + } + + /// Some docs for MethodWithInref + public int MethodWithInref(in int outParameter) + { + throw new NotImplementedException(); + } + public void GenericMethod(T input) { throw new NotImplementedException(); diff --git a/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj b/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj index 4fc4184b23d..2053b1138bb 100644 --- a/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj +++ b/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj @@ -2,10 +2,11 @@ - net45 + netstandard2.0 1.0.0.0 - nunit + none $(NoWarn);0067;1591 + true diff --git a/tests/service/data/TestProject/Library.fs b/tests/service/data/TestProject/Library.fs deleted file mode 100644 index b4d48c00f14..00000000000 --- a/tests/service/data/TestProject/Library.fs +++ /dev/null @@ -1,46 +0,0 @@ -namespace TestProject - -type T = ErasedWithConstructor.Provided.MyType - -type Class1() = - member this.X1 = T().DoNothing() - member this.X2 = T().DoNothingGeneric() - member this.X3 = T().DoNothingOneArg() - member this.X4 = T().ClassDoNothing() - member this.X5 = T().ClassDoNothingGeneric() - member this.X6 = T().ClassDoNothingOneArg() - member this.X7 = T().ClassDoNothingTwoArg() - member this.X8 = T().ClassInstanceDoNothing() - member this.X9 = T().ClassInstanceDoNothingGeneric() - member this.X10 = T().ClassInstanceDoNothingOneArg() - member this.X11 = T().ClassInstanceDoNothingTwoArg() - member this.X12 = T().GenericClassDoNothing() - member this.X13 = T().GenericClassDoNothingOneArg() - member this.X14 = T().GenericClassDoNothingTwoArg() - member this.X15 = T().OptionConstructionAndMatch() - member this.X16 = T().ChoiceConstructionAndMatch() - member this.X17 = T().RecordConstructionAndFieldGetSet() - member this.X18 = T().DoNothingTwoArg() - member this.X19 = T().DoNothingTwoArgCurried() - member this.X21 = T().ClassDoNothingTwoArgCurried() - member this.X23 = T().ClassInstanceDoNothingTwoArgCurried() - member this.X24 = T().DoNothingGenericWithConstraint() - member this.X25 = T().DoNothingGenericWithTypeConstraint() - member this.X26 = T().DoNothingGenericWithTypeConstraint() - member this.X27 = T().DoNothingWithCompiledName() - member this.X28 = T().CSharpMethod() - member this.X29 = T().CSharpMethodOptionalParam() - member this.X30 = T().CSharpMethodParamArray() - member this.X31 = T().CSharpMethodGeneric() - member this.X32 = T().CSharpMethodGenericWithConstraint() - member this.X33 = T().CSharpMethodGenericWithTypeConstraint() - member this.X34 = T().ClassDoNothingWithCompiledName() - member this.X35 = T().ClassInstanceDoNothingWithCompiledName() - member this.X36 = T().CSharpExplicitImplementationMethod() - member this.X37 = T().InterfaceDoNothing() - member this.X38 = T().OverrideDoNothing() - member this.X39 = T().TupleConstructionAndGet() - member this.X40 = T().ModuleValue() - member this.X41 = T().ClassProperty() - member this.X42 = T().ClassAutoProperty() - member this.X43 = T().ClassStaticAutoProperty() diff --git a/tests/service/data/TestProject/TestProject.fs b/tests/service/data/TestProject/TestProject.fs new file mode 100644 index 00000000000..ebf81723cb0 --- /dev/null +++ b/tests/service/data/TestProject/TestProject.fs @@ -0,0 +1,51 @@ +namespace TestProject + +type T = ErasedWithConstructor.Provided.MyType + +type Class1() = + member this.X1 = T().DoNothing() + member this.X2 = T().DoNothingGeneric() + member this.X3 = T().DoNothingOneArg() + member this.X4 = T().ClassDoNothing() + member this.X5 = T().ClassDoNothingGeneric() + member this.X6 = T().ClassDoNothingOneArg() + member this.X7 = T().ClassDoNothingTwoArg() + member this.X8 = T().ClassInstanceDoNothing() + member this.X9 = T().ClassInstanceDoNothingGeneric() + member this.X10 = T().ClassInstanceDoNothingOneArg() + member this.X11 = T().ClassInstanceDoNothingTwoArg() + member this.X12 = T().GenericClassDoNothing() + member this.X13 = T().GenericClassDoNothingOneArg() + member this.X14 = T().GenericClassDoNothingTwoArg() + member this.X15 = T().OptionConstructionAndMatch() + member this.X16 = T().ChoiceConstructionAndMatch() + member this.X17 = T().RecordConstructionAndFieldGetSet() + member this.X18 = T().DoNothingTwoArg() + member this.X19 = T().DoNothingTwoArgCurried() + member this.X21 = T().ClassDoNothingTwoArgCurried() + member this.X23 = T().ClassInstanceDoNothingTwoArgCurried() + member this.X24 = T().DoNothingGenericWithConstraint() + member this.X25 = T().DoNothingGenericWithTypeConstraint() + member this.X26 = T().DoNothingGenericWithTypeConstraint() + member this.X27 = T().DoNothingWithCompiledName() + member this.X28 = T().CSharpMethod() + member this.X29 = T().CSharpMethodOptionalParam() + member this.X30 = T().CSharpMethodParamArray() + member this.X31 = T().CSharpMethodGeneric() + member this.X32 = T().CSharpMethodGenericWithConstraint() + member this.X33 = T().CSharpMethodGenericWithTypeConstraint() + member this.X34 = T().ClassDoNothingWithCompiledName() + member this.X35 = T().ClassInstanceDoNothingWithCompiledName() + member this.X36 = T().CSharpExplicitImplementationMethod() + member this.X37 = T().InterfaceDoNothing() + member this.X38 = T().OverrideDoNothing() + member this.X39 = T().TupleConstructionAndGet() + member this.X40 = T().ModuleValue() + member this.X41 = T().ClassProperty() + member this.X42 = T().ClassAutoProperty() + member this.X43 = T().ClassStaticAutoProperty() + +type T2 = GeneratedWithConstructor.Provided.GenerativeProvider<3> + +type Class2() = + member this.X1 = T2() diff --git a/tests/service/data/TestProject/TestProject.fsproj b/tests/service/data/TestProject/TestProject.fsproj index b58304907f3..3a7fc90b94c 100644 --- a/tests/service/data/TestProject/TestProject.fsproj +++ b/tests/service/data/TestProject/TestProject.fsproj @@ -1,71 +1,23 @@  - - - - Debug - AnyCPU - 2.0 - ed64425e-b549-439a-b105-6c921a81f31a - Library - TestProject - TestProject - v4.5 - true - TestProject - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - bin\Debug\TestProject.xml - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - bin\Release\TestProject.xml - - - - - ..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - ..\TestTP\TestTP.dll - - - - - - - - - - - - CSharp_Analysis - {887630a3-4b1d-40ea-b8b3-2d842e9c40db} - True - - - - - - - - ..\..\..\..\packages\NUnit\lib\nunit.framework.dll - True - True - - - - - \ No newline at end of file + + + + netstandard2.0 + true + $(OtherFlags) --nowarn:3390 --nowarn:3218 + .\ + + + + + + + + + + + ..\..\..\..\artifacts\bin\TestTP\$(Configuration)\netstandard2.0\TestTP.dll + + + + diff --git a/tests/service/data/TestProject/netstandard2.0/README.md b/tests/service/data/TestProject/netstandard2.0/README.md new file mode 100644 index 00000000000..682cea0b9c1 --- /dev/null +++ b/tests/service/data/TestProject/netstandard2.0/README.md @@ -0,0 +1,10 @@ + + +The file in this directory is a checked-in copy of the output of + + msbuild VisualFSharp.sln + msbuild C:\GitHub\dsyme\fsharp\tests\service\data\TestProject + +Note "TestProject" is not part of VisualFSharp.sln to prevent problems where the type provider DLL gets locked when +using VisualFSharp.sln. + diff --git a/tests/service/data/TestProject/netstandard2.0/TestProject.dll b/tests/service/data/TestProject/netstandard2.0/TestProject.dll new file mode 100644 index 00000000000..388a9cb27a2 Binary files /dev/null and b/tests/service/data/TestProject/netstandard2.0/TestProject.dll differ diff --git a/tests/service/data/TestProject2/AssemblyInfo.fs b/tests/service/data/TestProject2/AssemblyInfo.fs new file mode 100644 index 00000000000..5c62ae5770c --- /dev/null +++ b/tests/service/data/TestProject2/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace TestProject.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/tests/service/data/TestProject2/TestProject2.fs b/tests/service/data/TestProject2/TestProject2.fs new file mode 100644 index 00000000000..b1e2fb49a91 --- /dev/null +++ b/tests/service/data/TestProject2/TestProject2.fs @@ -0,0 +1,7 @@ +namespace TestProject2 + +// This is code in one project making use of another project that uses a generative type provider + +type Class1() = + member this.X1 = TestProject.T() + member this.X2 = TestProject.T2() diff --git a/tests/service/data/TestProject2/TestProject2.fsproj b/tests/service/data/TestProject2/TestProject2.fsproj new file mode 100644 index 00000000000..0d01be5217b --- /dev/null +++ b/tests/service/data/TestProject2/TestProject2.fsproj @@ -0,0 +1,23 @@ + + + + + netstandard2.0 + true + $(OtherFlags) --nowarn:3390 --nowarn:3218 + + + + + + + + + + + + ..\..\..\..\artifacts\bin\TestTP\$(Configuration)\netstandard2.0\TestTP.dll + + + + diff --git a/tests/service/data/TestTP/Library.fs b/tests/service/data/TestTP/Library.fs deleted file mode 100644 index 3d5474e50bf..00000000000 --- a/tests/service/data/TestTP/Library.fs +++ /dev/null @@ -1,291 +0,0 @@ -namespace TestTP - -open ProviderImplementation.ProvidedTypes -open Microsoft.FSharp.Core.CompilerServices -open System.Reflection - -module Helper = - let doNothing() = () - let doNothingOneArg(x:int) = () - let doNothingTwoArg(x:int, y: int) = () - let doNothingTwoArgCurried(x:int) (y: int) = () - [] - let doNothingWithCompiledName() = () - let doNothingGeneric(x:'T) = () - let doNothingGenericWithConstraint(x: 'T when 'T: equality) = () - let doNothingGenericWithTypeConstraint(x: 'T when 'T :> _ seq) = () - - let mutable moduleValue = 0 - - type I = - abstract DoNothing: unit -> unit - - type B() = - abstract VirtualDoNothing: unit -> unit - default this.VirtualDoNothing() = () - - type C() = - inherit B() - let mutable p = 0 - static member DoNothing() = () - static member DoNothingOneArg(x:int) = () - static member DoNothingOneArg(x:string) = () - static member DoNothingTwoArg(c:C, x:int) = () - static member DoNothingTwoArgCurried (c:C) (x:int) = () - static member DoNothingGeneric(x:'T) = () - [] - static member DoNothingWithCompiledName() = () - member __.InstanceDoNothing() = () - member __.InstanceDoNothingOneArg(x:int) = () - member __.InstanceDoNothingOneArg(x:string) = () - member __.InstanceDoNothingTwoArg(c:C, x:int) = () - member __.InstanceDoNothingTwoArgCurried(c:C) (x:int) = () - member __.InstanceDoNothingGeneric(x:'T) = () - [] - member __.InstanceDoNothingWithCompiledName() = () - override __.VirtualDoNothing() = () - - member __.Property with get() = p and set v = p <- v - member val AutoProperty = 0 with get, set - static member val StaticAutoProperty = 0 with get, set - - interface I with - member this.DoNothing() = () - - type G<'U>() = - static member DoNothing() = () - static member DoNothingOneArg(x:int) = () - static member DoNothingTwoArg(c:C, x:int) = () - static member DoNothingGeneric(x:'T) = () - member __.InstanceDoNothing() = () - member __.InstanceDoNothingOneArg(x:int) = () - member __.InstanceDoNothingTwoArg(c:C, x:int) = () - member __.InstanceDoNothingGeneric(x:'U) = () - - type R = { A : int; mutable B : int } - -open FSharp.Compiler.Service.Tests - -[] -type BasicProvider (config : TypeProviderConfig) as this = - inherit TypeProviderForNamespaces () - - // resolve CSharp_Analysis from referenced assemblies - do System.AppDomain.CurrentDomain.add_AssemblyResolve(fun _ args -> - let name = AssemblyName(args.Name).Name.ToLowerInvariant() - let an = - config.ReferencedAssemblies - |> Seq.tryFind (fun an -> - System.IO.Path.GetFileNameWithoutExtension(an).ToLowerInvariant() = name) - match an with - | Some f -> Assembly.LoadFrom f - | None -> null - ) - - let ns = "ErasedWithConstructor.Provided" - let asm = Assembly.GetExecutingAssembly() - - let createTypes () = - let myType = ProvidedTypeDefinition(asm, ns, "MyType", Some typeof) - - let ctor = ProvidedConstructor([], InvokeCode = fun args -> <@@ "My internal state" :> obj @@>) - myType.AddMember(ctor) - - let ctor2 = ProvidedConstructor( - [ProvidedParameter("InnerState", typeof)], - InvokeCode = fun args -> <@@ (%%(args.[0]):string) :> obj @@>) - myType.AddMember(ctor2) - - let innerState = ProvidedProperty("InnerState", typeof, - GetterCode = fun args -> <@@ (%%(args.[0]) :> obj) :?> string @@>) - myType.AddMember(innerState) - - let someMethod = ProvidedMethod("DoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingOneArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingOneArg(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingTwoArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingTwoArg(3, 4) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingTwoArgCurried", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingTwoArgCurried 3 4 @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingWithCompiledName", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingWithCompiledName() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingGeneric", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingGeneric(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingGenericWithConstraint", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingGenericWithConstraint(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("DoNothingGenericWithTypeConstraint", [], typeof, - InvokeCode = fun args -> <@@ Helper.doNothingGenericWithTypeConstraint([3]) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothingGeneric", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothingGeneric(3) @@>) - - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothingOneArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothingOneArg(3) @@>) - - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothingTwoArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothingTwoArg(Helper.C(), 3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothingTwoArgCurried", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothingTwoArgCurried (Helper.C()) 3 @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassDoNothingWithCompiledName", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.DoNothingWithCompiledName() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothingGeneric", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothingGeneric(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothingOneArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothingOneArg(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothingTwoArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothingTwoArg(Helper.C(), 3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothingTwoArgCurried", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothingTwoArgCurried (Helper.C()) 3 @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassInstanceDoNothingWithCompiledName", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().InstanceDoNothingWithCompiledName() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("InterfaceDoNothing", [], typeof, - InvokeCode = fun args -> <@@ (Helper.C() :> Helper.I).DoNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("OverrideDoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.C().VirtualDoNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("GenericClassDoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.G.DoNothing() @@>) - myType.AddMember(someMethod) - - // These do not seem to compile correctly when used in provided expressions: - //Helper.G.DoNothingGeneric(3) - - // These do not seem to compile correctly when used in provided expressions: - //Helper.G().InstanceDoNothingGeneric(3) - - let someMethod = ProvidedMethod("GenericClassDoNothingOneArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.G.DoNothingOneArg(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("GenericClassDoNothingTwoArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.G.DoNothingTwoArg(Helper.C(), 3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("GenericClassInstanceDoNothing", [], typeof, - InvokeCode = fun args -> <@@ Helper.G().InstanceDoNothing() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("GenericClassInstanceDoNothingOneArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.G().InstanceDoNothingOneArg(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("GenericClassInstanceDoNothingTwoArg", [], typeof, - InvokeCode = fun args -> <@@ Helper.G().InstanceDoNothingTwoArg(Helper.C(), 3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("OptionConstructionAndMatch", [], typeof, - InvokeCode = fun args -> <@@ match Some 1 with None -> 0 | Some x -> x @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ChoiceConstructionAndMatch", [], typeof, - InvokeCode = fun args -> <@@ match Choice1Of2 1 with Choice2Of2 _ -> 0 | Choice1Of2 _ -> 1 @@>) - // TODO: fix type checker to recognize union generated subclasses coming from TPs -// InvokeCode = fun args -> <@@ match Choice1Of2 1 with Choice2Of2 _ -> 0 | Choice1Of2 x -> x @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("RecordConstructionAndFieldGetSet", [], typeof, - InvokeCode = fun args -> <@@ let r : Helper.R = { A = 1; B = 0 } in r.B <- 1; r.A @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("TupleConstructionAndGet", [], typeof, - InvokeCode = fun args -> <@@ let t = (1, 2, 3) in (let (_, i, _) = t in i) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethod", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).Method("x") @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethodOptionalParam", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).Method2("x") + CSharpClass(0).Method2() @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethodParamArray", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).Method3("x", "y") @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethodGeneric", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).GenericMethod(2) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethodGenericWithConstraint", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).GenericMethod2(obj()) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpMethodGenericWithTypeConstraint", [], typeof, - InvokeCode = fun args -> <@@ CSharpClass(0).GenericMethod3(3) @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("CSharpExplicitImplementationMethod", [], typeof, - InvokeCode = fun args -> <@@ (CSharpClass(0) :> ICSharpExplicitInterface).ExplicitMethod("x") @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ModuleValue", [], typeof, - InvokeCode = fun args -> <@@ Helper.moduleValue <- 1; Helper.moduleValue @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassProperty", [], typeof, - InvokeCode = fun args -> <@@ let x = Helper.C() in x.Property <- 1; x.Property @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassAutoProperty", [], typeof, - InvokeCode = fun args -> <@@ let x = Helper.C() in x.AutoProperty <- 1; x.AutoProperty @@>) - myType.AddMember(someMethod) - - let someMethod = ProvidedMethod("ClassStaticAutoProperty", [], typeof, - InvokeCode = fun args -> <@@ Helper.C.StaticAutoProperty <- 1; Helper.C.StaticAutoProperty @@>) - myType.AddMember(someMethod) - - [myType] - - do - this.AddNamespace(ns, createTypes()) - -[] -do () \ No newline at end of file diff --git a/tests/service/data/TestTP/ProvidedTypes.fs b/tests/service/data/TestTP/ProvidedTypes.fs index 51cdb0bddd0..6e9cded9199 100644 --- a/tests/service/data/TestTP/ProvidedTypes.fs +++ b/tests/service/data/TestTP/ProvidedTypes.fs @@ -1,2736 +1,15993 @@ -#nowarn "40" -#nowarn "52" -// Based on code for the F# 3.0 Developer Preview release of September 2011, -// Copyright (c) Microsoft Corporation 2005-2012. -// This sample code is provided "as is" without warranty of any kind. -// We disclaim all warranties, either express or implied, including the -// warranties of merchantability and fitness for a particular purpose. - -// This file contains a set of helper types and methods for providing types in an implementation -// of ITypeProvider. - -// This code has been modified and is appropriate for use in conjunction with the F# 3.0, F# 3.1, and F# 3.1.1 releases +// Copyright (c) Microsoft Corporation, Tomas Petricek, Gustavo Guerra, and other contributors +// +// Licensed under the MIT License see LICENSE.md in this project namespace ProviderImplementation.ProvidedTypes +#nowarn "1182" + +// This file contains a set of helper types and methods for providing types in an implementation +// of ITypeProvider. +// +// This code has been modified and is appropriate for use in conjunction with the F# 4.x releases + open System -open System.Text -open System.IO open System.Reflection -open System.Reflection.Emit -open System.Linq.Expressions open System.Collections.Generic -open Microsoft.FSharp.Core.CompilerServices +open System.Diagnostics -type E = Quotations.Expr -module P = Quotations.Patterns -module ES = Quotations.ExprShape -module DP = Quotations.DerivedPatterns - -type internal ExpectedStackState = - | Empty = 1 - | Address = 2 - | Value = 3 +open Microsoft.FSharp.Quotations +open Microsoft.FSharp.Quotations.Patterns +open Microsoft.FSharp.Core.CompilerServices [] -module internal Misc = - - let TypeBuilderInstantiationType = - let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e -> false - let typeName = if runningOnMono then "System.Reflection.MonoGenericClass" else "System.Reflection.Emit.TypeBuilderInstantiation" - typeof.Assembly.GetType(typeName) - - let GetTypeFromHandleMethod = typeof.GetMethod("GetTypeFromHandle") - let LanguagePrimitivesType = typedefof>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives") - let ParseInt32Method = LanguagePrimitivesType.GetMethod "ParseInt32" - let DecimalConstructor = typeof.GetConstructor([| typeof; typeof; typeof; typeof; typeof |]) - let DateTimeConstructor = typeof.GetConstructor([| typeof; typeof |]) - let DateTimeOffsetConstructor = typeof.GetConstructor([| typeof; typeof |]) - let TimeSpanConstructor = typeof.GetConstructor([|typeof|]) - let isEmpty s = s = ExpectedStackState.Empty - let isAddress s = s = ExpectedStackState.Address - - let nonNull str x = if x=null then failwith ("Null in " + str) else x - - let notRequired opname item = - let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item - System.Diagnostics.Debug.Assert (false, msg) - raise (System.NotSupportedException msg) - - let mkParamArrayCustomAttributeData() = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = upcast [| |] } - -#if FX_NO_CUSTOMATTRIBUTEDATA - let CustomAttributeTypedArgument(ty,v) = - { new IProvidedCustomAttributeTypedArgument with - member x.ArgumentType = ty - member x.Value = v } - let CustomAttributeNamedArgument(memb,arg:IProvidedCustomAttributeTypedArgument) = - { new IProvidedCustomAttributeNamedArgument with - member x.MemberInfo = memb - member x.ArgumentType = arg.ArgumentType - member x.TypedValue = arg } - type CustomAttributeData = Microsoft.FSharp.Core.CompilerServices.IProvidedCustomAttributeData -#endif - - let mkEditorHideMethodsCustomAttributeData() = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = upcast [| |] } - - let mkAllowNullLiteralCustomAttributeData value = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, value) |] - member __.NamedArguments = upcast [| |] } - - /// This makes an xml doc attribute w.r.t. an amortized computation of an xml doc string. - /// It is important that the text of the xml doc only get forced when poking on the ConstructorArguments - /// for the CustomAttributeData object. - let mkXmlDocCustomAttributeDataLazy(lazyText: Lazy) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, lazyText.Force()) |] - member __.NamedArguments = upcast [| |] } - - let mkXmlDocCustomAttributeData(s:string) = mkXmlDocCustomAttributeDataLazy (lazy s) - - let mkDefinitionLocationAttributeCustomAttributeData(line:int,column:int,filePath:string) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = - upcast [| CustomAttributeNamedArgument(typeof.GetProperty("FilePath"), CustomAttributeTypedArgument(typeof, filePath)); - CustomAttributeNamedArgument(typeof.GetProperty("Line"), CustomAttributeTypedArgument(typeof, line)) ; - CustomAttributeNamedArgument(typeof.GetProperty("Column"), CustomAttributeTypedArgument(typeof, column)) - |] } - let mkObsoleteAttributeCustomAttributeData(message:string, isError: bool) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors() |> Array.find (fun x -> x.GetParameters().Length = 1) - member __.ConstructorArguments = upcast [|CustomAttributeTypedArgument(typeof, message) ; CustomAttributeTypedArgument(typeof, isError) |] - member __.NamedArguments = upcast [| |] } - - type CustomAttributesImpl() = - let customAttributes = ResizeArray() - let mutable hideObjectMethods = false - let mutable nonNullable = false - let mutable obsoleteMessage = None - let mutable xmlDocDelayed = None - let mutable xmlDocAlwaysRecomputed = None - let mutable hasParamArray = false - - // XML doc text that we only compute once, if any. This must _not_ be forced until the ConstructorArguments - // property of the custom attribute is foced. - let xmlDocDelayedText = - lazy - (match xmlDocDelayed with None -> assert false; "" | Some f -> f()) - - // Custom atttributes that we only compute once - let customAttributesOnce = - lazy - [| if hideObjectMethods then yield mkEditorHideMethodsCustomAttributeData() - if nonNullable then yield mkAllowNullLiteralCustomAttributeData false - match xmlDocDelayed with None -> () | Some _ -> customAttributes.Add(mkXmlDocCustomAttributeDataLazy xmlDocDelayedText) - match obsoleteMessage with None -> () | Some s -> customAttributes.Add(mkObsoleteAttributeCustomAttributeData s) - if hasParamArray then yield mkParamArrayCustomAttributeData() - yield! customAttributes |] - - member __.AddDefinitionLocation(line:int,column:int,filePath:string) = customAttributes.Add(mkDefinitionLocationAttributeCustomAttributeData(line, column, filePath)) - member __.AddObsolete(message : string, isError) = obsoleteMessage <- Some (message,isError) - member __.HasParamArray with get() = hasParamArray and set(v) = hasParamArray <- v - member __.AddXmlDocComputed xmlDocFunction = xmlDocAlwaysRecomputed <- Some xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = xmlDocDelayed <- Some xmlDocFunction - member __.AddXmlDoc xmlDoc = xmlDocDelayed <- Some (fun () -> xmlDoc) - member __.HideObjectMethods with set v = hideObjectMethods <- v - member __.NonNullable with set v = nonNullable <- v - member __.AddCustomAttribute(attribute) = customAttributes.Add(attribute) - member __.GetCustomAttributesData() = - [| yield! customAttributesOnce.Force() - match xmlDocAlwaysRecomputed with None -> () | Some f -> customAttributes.Add(mkXmlDocCustomAttributeData (f())) |] - :> IList<_> - - let transExpr isGenerated q = - let rec trans q = - match q with - // convert NewTuple to the call to the constructor of the Tuple type (only for generated types) - | Quotations.Patterns.NewTuple(items) when isGenerated -> - let rec mkCtor args ty = - let ctor, restTyOpt = Reflection.FSharpValue.PreComputeTupleConstructorInfo ty - match restTyOpt with - | None -> Quotations.Expr.NewObject(ctor, List.map trans args) - | Some restTy -> - let curr = [for a in Seq.take 7 args -> trans a] - let rest = List.ofSeq (Seq.skip 7 args) - Quotations.Expr.NewObject(ctor, curr @ [mkCtor rest restTy]) - let tys = [| for e in items -> e.Type |] - let tupleTy = Reflection.FSharpType.MakeTupleType tys - trans (mkCtor items tupleTy) - // convert TupleGet to the chain of PropertyGet calls (only for generated types) - | Quotations.Patterns.TupleGet(e, i) when isGenerated -> - let rec mkGet ty i (e : Quotations.Expr) = - let pi, restOpt = Reflection.FSharpValue.PreComputeTuplePropertyInfo(ty, i) - let propGet = Quotations.Expr.PropertyGet(e, pi) - match restOpt with - | None -> propGet - | Some (restTy, restI) -> mkGet restTy restI propGet - trans (mkGet e.Type i (trans e)) - | Quotations.Patterns.Value(value, ty) -> - if value <> null then - let tyOfValue = value.GetType() - transValue(value, tyOfValue, ty) - else q - // Eliminate F# property gets to method calls - | Quotations.Patterns.PropertyGet(obj,propInfo,args) -> - match obj with - | None -> trans (Quotations.Expr.Call(propInfo.GetGetMethod(),args)) - | Some o -> trans (Quotations.Expr.Call(trans o,propInfo.GetGetMethod(),args)) - // Eliminate F# property sets to method calls - | Quotations.Patterns.PropertySet(obj,propInfo,args,v) -> - match obj with - | None -> trans (Quotations.Expr.Call(propInfo.GetSetMethod(),args@[v])) - | Some o -> trans (Quotations.Expr.Call(trans o,propInfo.GetSetMethod(),args@[v])) - // Eliminate F# function applications to FSharpFunc<_,_>.Invoke calls - | Quotations.Patterns.Application(f,e) -> - trans (Quotations.Expr.Call(trans f, f.Type.GetMethod "Invoke", [ e ]) ) - | Quotations.Patterns.NewUnionCase(ci, es) -> - trans (Quotations.Expr.Call(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) - | Quotations.Patterns.NewRecord(ci, es) -> - trans (Quotations.Expr.NewObject(Reflection.FSharpValue.PreComputeRecordConstructorInfo ci, es) ) - | Quotations.Patterns.UnionCaseTest(e,uc) -> - let tagInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType - let tagExpr = - match tagInfo with - | :? PropertyInfo as tagProp -> - trans (Quotations.Expr.PropertyGet(e,tagProp) ) - | :? MethodInfo as tagMeth -> - if tagMeth.IsStatic then trans (Quotations.Expr.Call(tagMeth, [e])) - else trans (Quotations.Expr.Call(e,tagMeth,[])) - | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo" - let tagNumber = uc.Tag - trans <@@ (%%(tagExpr) : int) = tagNumber @@> - - // Explicitly handle weird byref variables in lets (used to populate out parameters), since the generic handlers can't deal with byrefs - | Quotations.Patterns.Let(v,vexpr,bexpr) when v.Type.IsByRef -> - - // the binding must have leaves that are themselves variables (due to the limited support for byrefs in expressions) - // therefore, we can perform inlining to translate this to a form that can be compiled - inlineByref v vexpr bexpr - - // Eliminate recursive let bindings (which are unsupported by the type provider API) to regular let bindings - | Quotations.Patterns.LetRecursive(bindings, expr) -> - // This uses a "lets and sets" approach, converting something like - // let rec even = function - // | 0 -> true - // | n -> odd (n-1) - // and odd = function - // | 0 -> false - // | n -> even (n-1) - // X - // to something like - // let even = ref Unchecked.defaultof<_> - // let odd = ref Unchecked.defaultof<_> - // even := function - // | 0 -> true - // | n -> !odd (n-1) - // odd := function - // | 0 -> false - // | n -> !even (n-1) - // X' - // where X' is X but with occurrences of even/odd substituted by !even and !odd (since now even and odd are references) - // Translation relies on typedefof<_ ref> - does this affect ability to target different runtime and design time environments? - let vars = List.map fst bindings - let vars' = vars |> List.map (fun v -> Quotations.Var(v.Name, typedefof<_ ref>.MakeGenericType(v.Type))) - - // init t generates the equivalent of <@ ref Unchecked.defaultof @> - let init (t:Type) = - let r = match <@ ref 1 @> with Quotations.Patterns.Call(None, r, [_]) -> r | _ -> failwith "Extracting MethodInfo from <@ 1 @> failed" - let d = match <@ Unchecked.defaultof<_> @> with Quotations.Patterns.Call(None, d, []) -> d | _ -> failwith "Extracting MethodInfo from <@ Unchecked.defaultof<_> @> failed" - Quotations.Expr.Call(r.GetGenericMethodDefinition().MakeGenericMethod(t), [Quotations.Expr.Call(d.GetGenericMethodDefinition().MakeGenericMethod(t),[])]) - - // deref v generates the equivalent of <@ !v @> - // (so v's type must be ref) - let deref (v:Quotations.Var) = - let m = match <@ !(ref 1) @> with Quotations.Patterns.Call(None, m, [_]) -> m | _ -> failwith "Extracting MethodInfo from <@ !(ref 1) @> failed" - let tyArgs = v.Type.GetGenericArguments() - Quotations.Expr.Call(m.GetGenericMethodDefinition().MakeGenericMethod(tyArgs), [Quotations.Expr.Var v]) - - // substitution mapping a variable v to the expression <@ !v' @> using the corresponding new variable v' of ref type - let subst = - let map = - vars' - |> List.map deref - |> List.zip vars - |> Map.ofList - fun v -> Map.tryFind v map - - let expr' = expr.Substitute(subst) - - // maps variables to new variables - let varDict = List.zip vars vars' |> dict - - // given an old variable v and an expression e, returns a quotation like <@ v' := e @> using the corresponding new variable v' of ref type - let setRef (v:Quotations.Var) e = - let m = match <@ (ref 1) := 2 @> with Quotations.Patterns.Call(None, m, [_;_]) -> m | _ -> failwith "Extracting MethodInfo from <@ (ref 1) := 2 @> failed" - Quotations.Expr.Call(m.GetGenericMethodDefinition().MakeGenericMethod(v.Type), [Quotations.Expr.Var varDict.[v]; e]) - - // Something like - // <@ - // v1 := e1' - // v2 := e2' - // ... - // expr' - // @> - // Note that we must substitute our new variable dereferences into the bound expressions - let body = - bindings - |> List.fold (fun b (v,e) -> Quotations.Expr.Sequential(setRef v (e.Substitute subst), b)) expr' - - // Something like - // let v1 = ref Unchecked.defaultof - // let v2 = ref Unchecked.defaultof - // ... - // body - vars - |> List.fold (fun b v -> Quotations.Expr.Let(varDict.[v], init v.Type, b)) body - |> trans - - // Handle the generic cases - | Quotations.ExprShape.ShapeLambda(v,body) -> - Quotations.Expr.Lambda(v, trans body) - | Quotations.ExprShape.ShapeCombination(comb,args) -> - Quotations.ExprShape.RebuildShapeCombination(comb,List.map trans args) - | Quotations.ExprShape.ShapeVar _ -> q - and inlineByref v vexpr bexpr = - match vexpr with - | Quotations.Patterns.Sequential(e',vexpr') -> - (* let v = (e'; vexpr') in bexpr => e'; let v = vexpr' in bexpr *) - Quotations.Expr.Sequential(e', inlineByref v vexpr' bexpr) - |> trans - | Quotations.Patterns.IfThenElse(c,b1,b2) -> - (* let v = if c then b1 else b2 in bexpr => if c then let v = b1 in bexpr else let v = b2 in bexpr *) - Quotations.Expr.IfThenElse(c, inlineByref v b1 bexpr, inlineByref v b2 bexpr) - |> trans - | Quotations.Patterns.Var _ -> - (* let v = v1 in bexpr => bexpr[v/v1] *) - bexpr.Substitute(fun v' -> if v = v' then Some vexpr else None) - |> trans - | _ -> - failwith (sprintf "Unexpected byref binding: %A = %A" v vexpr) - and transValue (v : obj, tyOfValue : Type, expectedTy : Type) = - let rec transArray (o : Array, ty : Type) = - let elemTy = ty.GetElementType() - let converter = getConverterForType elemTy - let elements = - [ - for el in o do - yield converter el - ] - Quotations.Expr.NewArray(elemTy, elements) - and transList(o, ty : Type, nil, cons) = - let converter = getConverterForType (ty.GetGenericArguments().[0]) - o - |> Seq.cast - |> List.ofSeq - |> fun l -> List.foldBack(fun o s -> Quotations.Expr.NewUnionCase(cons, [ converter(o); s ])) l (Quotations.Expr.NewUnionCase(nil, [])) - |> trans - and getConverterForType (ty : Type) = - if ty.IsArray then - fun (v : obj) -> transArray(v :?> Array, ty) - elif ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ list> then - let nil, cons = - let cases = Reflection.FSharpType.GetUnionCases(ty) - let a = cases.[0] - let b = cases.[1] - if a.Name = "Empty" then a,b - else b,a - - fun v -> transList (v :?> System.Collections.IEnumerable, ty, nil, cons) - else - fun v -> Quotations.Expr.Value(v, ty) - let converter = getConverterForType tyOfValue - let r = converter v - if tyOfValue <> expectedTy then Quotations.Expr.Coerce(r, expectedTy) - else r - trans q - - let getFastFuncType (args : list) resultType = - let types = - [| - for arg in args -> arg.Type - yield resultType - |] - let fastFuncTy = - match List.length args with - | 2 -> typedefof>.MakeGenericType(types) - | 3 -> typedefof>.MakeGenericType(types) - | 4 -> typedefof>.MakeGenericType(types) - | 5 -> typedefof>.MakeGenericType(types) - | _ -> invalidArg "args" "incorrect number of arguments" - fastFuncTy.GetMethod("Adapt") - - let inline (===) a b = LanguagePrimitives.PhysicalEquality a b - - let traverse f = - let rec fallback e = - match e with - | P.Let(v, value, body) -> - let fixedValue = f fallback value - let fixedBody = f fallback body - if fixedValue === value && fixedBody === body then - e - else - E.Let(v, fixedValue, fixedBody) - | ES.ShapeVar _ -> e - | ES.ShapeLambda(v, body) -> - let fixedBody = f fallback body - if fixedBody === body then - e - else - E.Lambda(v, fixedBody) - | ES.ShapeCombination(shape, exprs) -> - let exprs1 = List.map (f fallback) exprs - if List.forall2 (===) exprs exprs1 then - e - else - ES.RebuildShapeCombination(shape, exprs1) - fun e -> f fallback e - - let RightPipe = <@@ (|>) @@> - let inlineRightPipe expr = - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | DP.SpecificCall RightPipe (None, _, [operand; applicable]) -> - let fixedOperand = loop operand - match loop applicable with - | P.Lambda(arg, body) -> - let v = Quotations.Var("__temp", operand.Type) - let ev = E.Var v +module Utils = + let K x = (fun () -> x) + let isNull x = match x with null -> true | _ -> false + let isNil x = match x with [] -> true | _ -> false + let isEmpty x = match x with [| |] -> true | _ -> false + + module Option = + let toObj x = match x with None -> null | Some x -> x + let ofObj x = match x with null -> None | _ -> Some x + + [] + type StructOption<'T> (hasValue: bool, value: 'T) = + member __.IsNone = not hasValue + member __.HasValue = hasValue + member __.Value = value + override __.ToString() = if hasValue then match box value with null -> "null" | x -> x.ToString() else "" + + type uoption<'T> = StructOption<'T> + + let UNone<'T> = uoption<'T>(false, Unchecked.defaultof<'T>) + let USome v = uoption<'T>(true, v) + let (|UNone|USome|) (x:uoption<'T>) = if x.HasValue then USome x.Value else UNone + + module StructOption = + let toObj x = match x with UNone -> null | USome x -> x + let ofObj x = match x with null -> UNone | x -> USome x + + + let tryFindMulti k map = match Map.tryFind k map with Some res -> res | None -> [| |] + + let splitNameAt (nm:string) idx = + if idx < 0 then failwith "splitNameAt: idx < 0"; + let last = nm.Length - 1 + if idx > last then failwith "splitNameAt: idx > last"; + (nm.Substring(0, idx)), + (if idx < last then nm.Substring (idx+1, last - idx) else "") + + let splitILTypeName (nm:string) = + match nm.LastIndexOf '.' with + | -1 -> UNone, nm + | idx -> let a, b = splitNameAt nm idx in USome a, b + + let joinILTypeName (nspace: string uoption) (nm:string) = + match nspace with + | UNone -> nm + | USome ns -> ns + "." + nm + + let lengthsEqAndForall2 (arr1: 'T1[]) (arr2: 'T2[]) f = + (arr1.Length = arr2.Length) && + (arr1, arr2) ||> Array.forall2 f + + /// General implementation of .Equals(Type) logic for System.Type over symbol types. You can use this with other types too. + let rec eqTypes (ty1: Type) (ty2: Type) = + if Object.ReferenceEquals(ty1, ty2) then true + elif ty1.IsGenericTypeDefinition then ty2.IsGenericTypeDefinition && ty1.Equals(ty2) + elif ty1.IsGenericType then ty2.IsGenericType && not ty2.IsGenericTypeDefinition && eqTypes (ty1.GetGenericTypeDefinition()) (ty2.GetGenericTypeDefinition()) && lengthsEqAndForall2 (ty1.GetGenericArguments()) (ty2.GetGenericArguments()) eqTypes + elif ty1.IsArray then ty2.IsArray && ty1.GetArrayRank() = ty2.GetArrayRank() && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + elif ty1.IsPointer then ty2.IsPointer && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + elif ty1.IsByRef then ty2.IsByRef && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + else ty1.Equals(box ty2) + + /// General implementation of .Equals(obj) logic for System.Type over symbol types. You can use this with other types too. + let eqTypeObj (this: Type) (other: obj) = + match other with + | :? Type as otherTy -> eqTypes this otherTy + | _ -> false - let fixedBody = loop body - E.Let(v, fixedOperand, fixedBody.Substitute(fun v1 -> if v1 = arg then Some ev else None)) - | fixedApplicable -> E.Application(fixedApplicable, fixedOperand) - | x -> fallback x - loop expr - - let inlineValueBindings e = - let map = Dictionary(HashIdentity.Reference) - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | P.Let(id, (P.Value(_) as v), body) when not id.IsMutable -> - map.[id] <- v - let fixedBody = loop body - map.Remove(id) |> ignore - fixedBody - | ES.ShapeVar v -> - match map.TryGetValue v with - | true, e -> e - | _ -> orig - | x -> fallback x - loop e - - - let optimizeCurriedApplications expr = - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | P.Application(e, arg) -> - let e1 = tryPeelApplications e [loop arg] - if e1 === e then - orig - else - e1 - | x -> fallback x - and tryPeelApplications orig args = - let n = List.length args - match orig with - | P.Application(e, arg) -> - let e1 = tryPeelApplications e ((loop arg)::args) - if e1 === e then - orig - else - e1 - | P.Let(id, applicable, (P.Lambda(_) as body)) when n > 0 -> - let numberOfApplication = countPeelableApplications body id 0 - if numberOfApplication = 0 then orig - elif n = 1 then E.Application(applicable, List.head args) - elif n <= 5 then - let resultType = - applicable.Type - |> Seq.unfold (fun t -> - if not t.IsGenericType then None - else - let args = t.GetGenericArguments() - if args.Length <> 2 then None - else - Some (args.[1], args.[1]) - ) - |> Seq.item (n - 1) - - let adaptMethod = getFastFuncType args resultType - let adapted = E.Call(adaptMethod, [loop applicable]) - let invoke = adapted.Type.GetMethod("Invoke", [| for arg in args -> arg.Type |]) - E.Call(adapted, invoke, args) - else - (applicable, args) ||> List.fold (fun e a -> E.Application(e, a)) - | _ -> - orig - and countPeelableApplications expr v n = - match expr with - // v - applicable entity obtained on the prev step - // \arg -> let v1 = (f arg) in rest ==> f - | P.Lambda(arg, P.Let(v1, P.Application(P.Var f, P.Var arg1), rest)) when v = f && arg = arg1 -> countPeelableApplications rest v1 (n + 1) - // \arg -> (f arg) ==> f - | P.Lambda(arg, P.Application(P.Var f, P.Var arg1)) when v = f && arg = arg1 -> n - | _ -> n - loop expr - - // FSharp.Data change: use the real variable names instead of indices, to improve output of Debug.fs - let transQuotationToCode isGenerated qexprf (paramNames: string[]) (argExprs: Quotations.Expr[]) = - // add let bindings for arguments to ensure that arguments will be evaluated - let vars = argExprs |> Array.mapi (fun i e -> Quotations.Var(paramNames.[i], e.Type)) - let expr = qexprf ([for v in vars -> Quotations.Expr.Var v]) - - let pairs = Array.zip argExprs vars - let expr = Array.foldBack (fun (arg, var) e -> Quotations.Expr.Let(var, arg, e)) pairs expr - let expr = - if isGenerated then - let e1 = inlineRightPipe expr - let e2 = optimizeCurriedApplications e1 - let e3 = inlineValueBindings e2 - e3 - else - expr + /// General implementation of .IsAssignableFrom logic for System.Type, regardless of specific implementation + let isAssignableFrom (ty: Type) (otherTy: Type) = + eqTypes ty otherTy || (match otherTy.BaseType with null -> false | bt -> ty.IsAssignableFrom(bt)) + + /// General implementation of .IsSubclassOf logic for System.Type, regardless of specific implementation, with + /// an added hack to make the types usable with the FSharp.Core quotations implementation + let isSubclassOf (this: Type) (otherTy: Type) = + (this.IsClass && otherTy.IsClass && this.IsAssignableFrom(otherTy) && not (eqTypes this otherTy)) + // The FSharp.Core implementation of FSharp.Quotations uses + // let isDelegateType (typ:Type) = + // if typ.IsSubclassOf(typeof) then ... + // This means even target type definitions must process the case where ``otherTy`` is typeof rather than + // the System.Delegate type for the target assemblies. + || (match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.MulticastDelegate" && (let fn = otherTy.FullName in fn = "System.Delegate" || fn = "System.MulticastDelegate" )) + + + /// General implementation of .GetAttributeFlags logic for System.Type over symbol types + let getAttributeFlagsImpl (ty: Type) = + if ty.IsGenericType then ty.GetGenericTypeDefinition().Attributes + elif ty.IsArray then typeof.Attributes + elif ty.IsPointer then typeof.MakePointerType().Attributes + elif ty.IsByRef then typeof.MakeByRefType().Attributes + else Unchecked.defaultof + + let bindAll = BindingFlags.DeclaredOnly ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Static ||| BindingFlags.Instance + let bindCommon = BindingFlags.DeclaredOnly ||| BindingFlags.Static ||| BindingFlags.Instance ||| BindingFlags.Public + let bindSome isStatic = BindingFlags.DeclaredOnly ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| (if isStatic then BindingFlags.Static else BindingFlags.Instance) + let inline hasFlag e flag = (e &&& flag) <> enum 0 + + let memberBinds isType (bindingFlags: BindingFlags) isStatic isPublic = + (isType || hasFlag bindingFlags (if isStatic then BindingFlags.Static else BindingFlags.Instance)) && + ((hasFlag bindingFlags BindingFlags.Public && isPublic) || (hasFlag bindingFlags BindingFlags.NonPublic && not isPublic)) + + [] + type ITypeBuilder = + abstract MakeGenericType: Type * Type[] -> Type + abstract MakeArrayType: Type -> Type + abstract MakeRankedArrayType: Type*int -> Type + abstract MakeByRefType: Type -> Type + abstract MakePointerType: Type -> Type + + let defaultTypeBuilder = + { new ITypeBuilder with + member __.MakeGenericType(typeDef, args) = typeDef.MakeGenericType(args) + member __.MakeArrayType(typ) = typ.MakeArrayType() + member __.MakeRankedArrayType(typ, rank) = typ.MakeArrayType(rank) + member __.MakeByRefType(typ) = typ.MakeByRefType() + member __.MakePointerType(typ) = typ.MakePointerType() } + + let rec instType (typeBuilder: ITypeBuilder) inst (ty:Type) = + if isNull ty then null + elif ty.IsGenericType then + let typeArgs = Array.map (instType typeBuilder inst) (ty.GetGenericArguments()) + typeBuilder.MakeGenericType(ty.GetGenericTypeDefinition(), typeArgs) + elif ty.HasElementType then + let ety : Type = instType typeBuilder inst (ty.GetElementType()) + if ty.IsArray then + let rank = ty.GetArrayRank() + if rank = 1 then typeBuilder.MakeArrayType(ety) + else typeBuilder.MakeRankedArrayType(ety,rank) + elif ty.IsPointer then typeBuilder.MakePointerType(ety) + elif ty.IsByRef then typeBuilder.MakeByRefType(ety) + else ty + elif ty.IsGenericParameter then + let pos = ty.GenericParameterPosition + let (inst1: Type[], inst2: Type[]) = inst + if pos < inst1.Length then inst1.[pos] + elif pos < inst1.Length + inst2.Length then inst2.[pos - inst1.Length] + else ty + else ty - transExpr isGenerated expr - let adjustTypeAttributes attributes isNested = - let visibilityAttributes = - match attributes &&& TypeAttributes.VisibilityMask with + let mutable token = 0 + let genToken() = token <- token + 1; token + /// Internal code of .NET expects the obj[] returned by GetCustomAttributes to be an Attribute[] even in the case of empty arrays + let emptyAttributes = (([| |]: Attribute[]) |> box |> unbox) + + type Attributes<'T when 'T :> Attribute>() = + static let empty = ([| |] : 'T []) |> box |> unbox + static member Empty() = empty + + type Attributes = + static member CreateEmpty (typ : Type) = + let gtype = typedefof>.MakeGenericType([| typ |]) + // the Empty member is private due to the presence of the fsi file + // but when getting rid of the fsi for diagnostic purpose, it becomes public + // this is the reason for having both Public and NonPublic flag bellow + let gmethod = gtype.GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) + gmethod.Invoke(null, [||]) :?> obj array + + let nonNull str x = if isNull x then failwithf "Null in '%s', stacktrace = '%s'" str Environment.StackTrace else x + let nonNone str x = match x with None -> failwithf "No value has been specified for '%s', stacktrace = '%s'" str Environment.StackTrace | Some v -> v + let patchOption v f = match v with None -> f() | Some _ -> failwithf "Already patched, stacktrace = '%s'" Environment.StackTrace + + let notRequired this opname item = + let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter of type '%O'. Stack trace:\n%s" opname item (this.GetType()) Environment.StackTrace + Debug.Assert (false, msg) + raise (NotSupportedException msg) + + + let adjustTypeAttributes isNested attrs = + let visibilityAttributes = + match attrs &&& TypeAttributes.VisibilityMask with | TypeAttributes.Public when isNested -> TypeAttributes.NestedPublic | TypeAttributes.NotPublic when isNested -> TypeAttributes.NestedAssembly | TypeAttributes.NestedPublic when not isNested -> TypeAttributes.Public - | TypeAttributes.NestedAssembly - | TypeAttributes.NestedPrivate + | TypeAttributes.NestedAssembly + | TypeAttributes.NestedPrivate | TypeAttributes.NestedFamORAssem | TypeAttributes.NestedFamily | TypeAttributes.NestedFamANDAssem when not isNested -> TypeAttributes.NotPublic | a -> a - (attributes &&& ~~~TypeAttributes.VisibilityMask) ||| visibilityAttributes - -type ProvidedStaticParameter(parameterName:string,parameterType:Type,?parameterDefaultValue:obj) = - inherit System.Reflection.ParameterInfo() + (attrs &&& ~~~TypeAttributes.VisibilityMask) ||| visibilityAttributes + + + type ConstructorInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetConstructors(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic constructor definition via metadata token, stacktrace = '%s'" m.DeclaringType m.Name Environment.StackTrace + else + m + + type PropertyInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetProperties(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic property definition via metadata token" m.DeclaringType m.Name + else + m + + member p.IsStatic = p.CanRead && p.GetGetMethod(true).IsStatic || p.CanWrite && p.GetSetMethod(true).IsStatic + member p.IsPublic = p.CanRead && p.GetGetMethod(true).IsPublic || p.CanWrite && p.GetSetMethod(true).IsPublic + + type EventInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetEvents(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic event definition via metadata token" m.DeclaringType m.Name + else + m + + member p.IsStatic = p.GetAddMethod().IsStatic || p.GetRemoveMethod().IsStatic + member p.IsPublic = p.GetAddMethod().IsPublic || p.GetRemoveMethod().IsPublic + + type FieldInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetFields(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic event definition via metadata token" m.DeclaringType m.Name + else + m + + type MethodInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (m.IsGenericMethod && not dty.IsGenericType) then m.GetGenericMethodDefinition() + elif (m.IsGenericMethod && (not m.IsGenericMethodDefinition || not dty.IsGenericTypeDefinition)) || + (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + + // Search through ALL the methods on the original type definition looking for the one + // with a matching metadata token + let gdty = if dty.IsGenericType then dty.GetGenericTypeDefinition() else dty + gdty.GetMethods(bindSome m.IsStatic) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind generic instantiation of %O::%s back to generic method definition via metadata token" m.DeclaringType m.Name - let customAttributesImpl = CustomAttributesImpl() + else + m - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + let canBindConstructor (bindingFlags: BindingFlags) (c: ConstructorInfo) = + hasFlag bindingFlags BindingFlags.Public && c.IsPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsPublic - override __.RawDefaultValue = defaultArg parameterDefaultValue null - override __.Attributes = if parameterDefaultValue.IsNone then enum 0 else ParameterAttributes.Optional - override __.Position = 0 - override __.ParameterType = parameterType - override __.Name = parameterName + let canBindMethod (bindingFlags: BindingFlags) (c: MethodInfo) = + hasFlag bindingFlags BindingFlags.Public && c.IsPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsPublic - override __.GetCustomAttributes(_inherit) = ignore(_inherit); notRequired "GetCustomAttributes" parameterName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" parameterName + let canBindProperty (bindingFlags: BindingFlags) (c: PropertyInfo) = + hasFlag bindingFlags BindingFlags.Public && c.IsPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsPublic -type ProvidedParameter(name:string,parameterType:Type,?isOut:bool,?optionalValue:obj) = - inherit System.Reflection.ParameterInfo() - let customAttributesImpl = CustomAttributesImpl() - let isOut = defaultArg isOut false - member __.IsParamArray with get() = customAttributesImpl.HasParamArray and set(v) = customAttributesImpl.HasParamArray <- v - override __.Name = name - override __.ParameterType = parameterType - override __.Attributes = (base.Attributes ||| (if isOut then ParameterAttributes.Out else enum 0) - ||| (match optionalValue with None -> enum 0 | Some _ -> ParameterAttributes.Optional ||| ParameterAttributes.HasDefault)) - override __.RawDefaultValue = defaultArg optionalValue null - member __.HasDefaultParameterValue = Option.isSome optionalValue - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let canBindField (bindingFlags: BindingFlags) (c: FieldInfo) = + hasFlag bindingFlags BindingFlags.Public && c.IsPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsPublic -type ProvidedConstructor(parameters : ProvidedParameter list) = - inherit ConstructorInfo() - let parameters = parameters |> List.map (fun p -> p :> ParameterInfo) - let mutable baseCall = None - - let mutable declaringType = null : System.Type - let mutable invokeCode = None : option Quotations.Expr> - let mutable isImplicitCtor = false - let mutable ctorAttributes = MethodAttributes.Public ||| MethodAttributes.RTSpecialName - let nameText () = sprintf "constructor for %s" (if declaringType=null then "" else declaringType.FullName) - let isStatic() = ctorAttributes.HasFlag(MethodAttributes.Static) - - let customAttributesImpl = CustomAttributesImpl() - member __.IsTypeInitializer - with get() = isStatic() && ctorAttributes.HasFlag(MethodAttributes.Private) - and set(v) = - let typeInitializerAttributes = MethodAttributes.Static ||| MethodAttributes.Private - ctorAttributes <- if v then ctorAttributes ||| typeInitializerAttributes else ctorAttributes &&& ~~~typeInitializerAttributes - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let canBindEvent (bindingFlags: BindingFlags) (c: EventInfo) = + hasFlag bindingFlags BindingFlags.Public && c.IsPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsPublic - member __.DeclaringTypeImpl - with set x = - if declaringType<>null then failwith (sprintf "ProvidedConstructor: declaringType already set on '%s'" (nameText())); - declaringType <- x + let canBindNestedType (bindingFlags: BindingFlags) (c: Type) = + hasFlag bindingFlags BindingFlags.Public && c.IsNestedPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsNestedPublic - member __.InvokeCode - with set (q:Quotations.Expr list -> Quotations.Expr) = - match invokeCode with - | None -> invokeCode <- Some q - | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for '%s'" (nameText())) + // We only want to return source types "typeof" values as _target_ types in one very specific location due to a limitation in the + // F# compiler code for multi-targeting. + let ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() = + let rec loop i = + if i > 9 then + false + else + let frame = StackFrame(i, true) + match frame.GetMethod() with + | null -> loop (i+1) + | m -> m.Name = "ImportProvidedMethodBaseAsILMethodRef" || loop (i+1) + loop 1 + +//-------------------------------------------------------------------------------- +// UncheckedQuotations + +// The FSharp.Core 2.0 - 4.0 (4.0.0.0 - 4.4.0.0) quotations implementation is overly strict in that it doesn't allow +// generation of quotations for cross-targeted FSharp.Core. Below we define a series of Unchecked methods +// implemented via reflection hacks to allow creation of various nodes when using a cross-targets FSharp.Core and +// mscorlib.dll. +// +// - Most importantly, these cross-targeted quotations can be provided to the F# compiler by a type provider. +// They are generally produced via the AssemblyReplacer.fs component through a process of rewriting design-time quotations that +// are not cross-targeted. +// +// - However, these quotation values are a bit fragile. Using existing FSharp.Core.Quotations.Patterns +// active patterns on these quotation nodes will generally work correctly. But using ExprShape.RebuildShapeCombination +// on these new nodes will not succed, nor will operations that build new quotations such as Expr.Call. +// Instead, use the replacement provided in this module. +// +// - Likewise, some operations in these quotation values like "expr.Type" may be a bit fragile, possibly returning non cross-targeted types in +// the result. However those operations are not used by the F# compiler. +[] +module UncheckedQuotations = - member __.BaseConstructorCall - with set (d:Quotations.Expr list -> (ConstructorInfo * Quotations.Expr list)) = - match baseCall with - | None -> baseCall <- Some d - | Some _ -> failwith (sprintf "ProvidedConstructor: base call already given for '%s'" (nameText())) - - member __.GetInvokeCodeInternal isGenerated = - match invokeCode with - | Some f -> - // FSharp.Data change: use the real variable names instead of indices, to improve output of Debug.fs - let paramNames = - parameters - |> List.map (fun p -> p.Name) - |> List.append (if not isGenerated || isStatic() then [] else ["this"]) - |> Array.ofList - transQuotationToCode isGenerated f paramNames - | None -> failwith (sprintf "ProvidedConstructor: no invoker for '%s'" (nameText())) + let qTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.ExprConstInfo") + assert (not (isNull qTy)) - member __.GetBaseConstructorCallInternal isGenerated = - match baseCall with - | Some f -> Some(fun ctorArgs -> let c,baseCtorArgExprs = f ctorArgs in c, List.map (transExpr isGenerated) baseCtorArgExprs) - | None -> None - member __.IsImplicitCtor with get() = isImplicitCtor and set v = isImplicitCtor <- v + let pTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.PatternsModule") + assert (not (isNull pTy)) - // Implement overloads - override __.GetParameters() = parameters |> List.toArray - override __.Attributes = ctorAttributes - override __.Name = if isStatic() then ".cctor" else ".ctor" - override __.DeclaringType = declaringType |> nonNull "ProvidedConstructor.DeclaringType" - override __.IsDefined(_attributeType, _inherit) = true - - override __.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" (nameText()) - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" (nameText()) - override __.ReflectedType = notRequired "ReflectedType" (nameText()) - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" (nameText()) - override __.MethodHandle = notRequired "MethodHandle" (nameText()) - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" (nameText()) - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" (nameText()) - -type ProvidedMethod(methodName: string, parameters: ProvidedParameter list, returnType: Type) = - inherit System.Reflection.MethodInfo() - let argParams = parameters |> List.map (fun p -> p :> ParameterInfo) - - // State - let mutable declaringType : Type = null - let mutable methodAttrs = MethodAttributes.Public - let mutable invokeCode = None : option Quotations.Expr> - let mutable staticParams = [ ] - let mutable staticParamsApply = None - let isStatic() = methodAttrs.HasFlag(MethodAttributes.Static) - let customAttributesImpl = CustomAttributesImpl() - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + // These are handles to the internal functions that create quotation nodes of different sizes. Although internal, + // these function names have been stable since F# 2.0. + let mkFE0 = pTy.GetMethod("mkFE0", bindAll) + assert (not (isNull mkFE0)) - member __.SetMethodAttrs m = methodAttrs <- m - member __.AddMethodAttrs m = methodAttrs <- methodAttrs ||| m - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - member __.IsStaticMethod - with get() = isStatic() - and set x = if x then methodAttrs <- methodAttrs ||| MethodAttributes.Static - else methodAttrs <- methodAttrs &&& (~~~ MethodAttributes.Static) + let mkFE1 = pTy.GetMethod("mkFE1", bindAll) + assert (not (isNull mkFE1)) - member __.InvokeCode - with set (q:Quotations.Expr list -> Quotations.Expr) = - match invokeCode with - | None -> invokeCode <- Some q - | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for %s on type %s" methodName (if declaringType=null then "" else declaringType.FullName)) + let mkFE2 = pTy.GetMethod("mkFE2", bindAll) + assert (mkFE2 |> isNull |> not) + let mkFE3 = pTy.GetMethod("mkFE3", bindAll) + assert (mkFE3 |> isNull |> not) - /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". - member __.DefineStaticParameters(staticParameters : list, apply : (string -> obj[] -> ProvidedMethod)) = - staticParams <- staticParameters - staticParamsApply <- Some apply - - /// Get ParameterInfo[] for the parametric type parameters (//s GetGenericParameters) - member __.GetStaticParameters() = [| for p in staticParams -> p :> ParameterInfo |] - - /// Instantiate parametrics type - member __.ApplyStaticArguments(mangledName:string, args:obj[]) = - if staticParams.Length>0 then - if staticParams.Length <> args.Length then - failwith (sprintf "ProvidedTypeDefinition: expecting %d static parameters but given %d for method %s" staticParams.Length args.Length methodName) - match staticParamsApply with - | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" - | Some f -> f mangledName args - else - failwith (sprintf "ProvidedTypeDefinition: static parameters supplied but not expected for method %s" methodName) - - member __.GetInvokeCodeInternal isGenerated = - match invokeCode with - | Some f -> - // FSharp.Data change: use the real variable names instead of indices, to improve output of Debug.fs - let paramNames = - parameters - |> List.map (fun p -> p.Name) - |> List.append (if isStatic() then [] else ["this"]) - |> Array.ofList - transQuotationToCode isGenerated f paramNames - | None -> failwith (sprintf "ProvidedMethod: no invoker for %s on type %s" methodName (if declaringType=null then "" else declaringType.FullName)) + let mkFEN = pTy.GetMethod("mkFEN", bindAll) + assert (mkFEN |> isNull |> not) - // Implement overloads - override __.GetParameters() = argParams |> Array.ofList - override __.Attributes = methodAttrs - override __.Name = methodName - override __.DeclaringType = declaringType |> nonNull "ProvidedMethod.DeclaringType" - override __.IsDefined(_attributeType, _inherit) : bool = true - override __.MemberType = MemberTypes.Method - override __.CallingConvention = - let cc = CallingConventions.Standard - let cc = if not (isStatic()) then cc ||| CallingConventions.HasThis else cc - cc - override __.ReturnType = returnType - override __.ReturnParameter = null // REVIEW: Give it a name and type? - override __.ToString() = "Method " + methodName - - // These don't have to return fully accurate results - they are used - // by the F# Quotations library function SpecificCall as a pre-optimization - // when comparing methods - override __.MetadataToken = hash declaringType + hash methodName - override __.MethodHandle = RuntimeMethodHandle() + // These are handles to the internal tags attached to quotation nodes of different sizes. Although internal, + // these function names have been stable since F# 2.0. + let newDelegateOp = qTy.GetMethod("NewNewDelegateOp", bindAll) + assert (newDelegateOp |> isNull |> not) - override __.ReturnTypeCustomAttributes = notRequired "ReturnTypeCustomAttributes" methodName - override __.GetBaseDefinition() = notRequired "GetBaseDefinition" methodName - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" methodName - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" methodName - override __.ReflectedType = notRequired "ReflectedType" methodName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" methodName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" methodName + let instanceCallOp = qTy.GetMethod("NewInstanceMethodCallOp", bindAll) + assert (instanceCallOp |> isNull |> not) + let staticCallOp = qTy.GetMethod("NewStaticMethodCallOp", bindAll) + assert (staticCallOp |> isNull |> not) -type ProvidedProperty(propertyName: string, propertyType: Type, ?parameters: ProvidedParameter list) = - inherit System.Reflection.PropertyInfo() - // State + let newObjectOp = qTy.GetMethod("NewNewObjectOp", bindAll) + assert (newObjectOp |> isNull |> not) - let parameters = defaultArg parameters [] - let mutable declaringType = null - let mutable isStatic = false - let mutable getterCode = None : option Quotations.Expr> - let mutable setterCode = None : option Quotations.Expr> + let newArrayOp = qTy.GetMethod("NewNewArrayOp", bindAll) + assert (newArrayOp |> isNull |> not) - let hasGetter() = getterCode.IsSome - let hasSetter() = setterCode.IsSome + let appOp = qTy.GetMethod("get_AppOp", bindAll) + assert (appOp |> isNull |> not) - // Delay construction - to pick up the latest isStatic - let markSpecialName (m:ProvidedMethod) = m.AddMethodAttrs(MethodAttributes.SpecialName); m - let getter = lazy (ProvidedMethod("get_" + propertyName,parameters,propertyType,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=getterCode.Value) |> markSpecialName) - let setter = lazy (ProvidedMethod("set_" + propertyName,parameters @ [ProvidedParameter("value",propertyType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=setterCode.Value) |> markSpecialName) - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() - member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let instancePropGetOp = qTy.GetMethod("NewInstancePropGetOp", bindAll) + assert (instancePropGetOp |> isNull |> not) - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice + let staticPropGetOp = qTy.GetMethod("NewStaticPropGetOp", bindAll) + assert (staticPropGetOp |> isNull |> not) - member __.IsStatic - with get() = isStatic - and set x = isStatic <- x + let instancePropSetOp = qTy.GetMethod("NewInstancePropSetOp", bindAll) + assert (instancePropSetOp |> isNull |> not) - member __.GetterCode - with set (q:Quotations.Expr list -> Quotations.Expr) = - if not getter.IsValueCreated then getterCode <- Some q else failwith "ProvidedProperty: getter MethodInfo has already been created" + let staticPropSetOp = qTy.GetMethod("NewStaticPropSetOp", bindAll) + assert (staticPropSetOp |> isNull |> not) - member __.SetterCode - with set (q:Quotations.Expr list -> Quotations.Expr) = - if not (setter.IsValueCreated) then setterCode <- Some q else failwith "ProvidedProperty: setter MethodInfo has already been created" + let instanceFieldGetOp = qTy.GetMethod("NewInstanceFieldGetOp", bindAll) + assert (instanceFieldGetOp |> isNull |> not) - // Implement overloads - override __.PropertyType = propertyType - override __.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired "SetValue" propertyName - override __.GetAccessors _nonPublic = notRequired "nonPublic" propertyName - override __.GetGetMethod _nonPublic = if hasGetter() then getter.Force() :> MethodInfo else null - override __.GetSetMethod _nonPublic = if hasSetter() then setter.Force() :> MethodInfo else null - override __.GetIndexParameters() = [| for p in parameters -> upcast p |] - override __.Attributes = PropertyAttributes.None - override __.CanRead = hasGetter() - override __.CanWrite = hasSetter() - override __.GetValue(_obj, _invokeAttr, _binder, _index, _culture) : obj = notRequired "GetValue" propertyName - override __.Name = propertyName - override __.DeclaringType = declaringType |> nonNull "ProvidedProperty.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Property - - override __.ReflectedType = notRequired "ReflectedType" propertyName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" propertyName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" propertyName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" propertyName - -type ProvidedEvent(eventName:string,eventHandlerType:Type) = - inherit System.Reflection.EventInfo() - // State - - let mutable declaringType = null - let mutable isStatic = false - let mutable adderCode = None : option Quotations.Expr> - let mutable removerCode = None : option Quotations.Expr> - - // Delay construction - to pick up the latest isStatic - let markSpecialName (m:ProvidedMethod) = m.AddMethodAttrs(MethodAttributes.SpecialName); m - let adder = lazy (ProvidedMethod("add_" + eventName, [ProvidedParameter("handler", eventHandlerType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=adderCode.Value) |> markSpecialName) - let remover = lazy (ProvidedMethod("remove_" + eventName, [ProvidedParameter("handler", eventHandlerType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=removerCode.Value) |> markSpecialName) - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let staticFieldGetOp = qTy.GetMethod("NewStaticFieldGetOp", bindAll) + assert (staticFieldGetOp |> isNull |> not) - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - member __.IsStatic - with get() = isStatic - and set x = isStatic <- x + let instanceFieldSetOp = qTy.GetMethod("NewInstanceFieldSetOp", bindAll) + assert (instanceFieldSetOp |> isNull |> not) - member __.AdderCode - with get() = adderCode.Value - and set f = - if not adder.IsValueCreated then adderCode <- Some f else failwith "ProvidedEvent: Add MethodInfo has already been created" + let staticFieldSetOp = qTy.GetMethod("NewStaticFieldSetOp", bindAll) + assert (staticFieldSetOp |> isNull |> not) - member __.RemoverCode - with get() = removerCode.Value - and set f = - if not (remover.IsValueCreated) then removerCode <- Some f else failwith "ProvidedEvent: Remove MethodInfo has already been created" + let tupleGetOp = qTy.GetMethod("NewTupleGetOp", bindAll) + assert (tupleGetOp |> isNull |> not) - // Implement overloads - override __.EventHandlerType = eventHandlerType - override __.GetAddMethod _nonPublic = adder.Force() :> MethodInfo - override __.GetRemoveMethod _nonPublic = remover.Force() :> MethodInfo - override __.Attributes = EventAttributes.None - override __.Name = eventName - override __.DeclaringType = declaringType |> nonNull "ProvidedEvent.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Event - - override __.GetRaiseMethod _nonPublic = notRequired "GetRaiseMethod" eventName - override __.ReflectedType = notRequired "ReflectedType" eventName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" eventName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" eventName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" eventName - -type ProvidedLiteralField(fieldName:string,fieldType:Type,literalValue:obj) = - inherit System.Reflection.FieldInfo() - // State - - let mutable declaringType = null - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let letOp = qTy.GetMethod("get_LetOp", bindAll) + assert (letOp |> isNull |> not) - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice + let forIntegerRangeLoopOp = qTy.GetMethod("get_ForIntegerRangeLoopOp", bindAll) + assert (forIntegerRangeLoopOp |> isNull |> not) + let whileLoopOp = qTy.GetMethod("get_WhileLoopOp", bindAll) + assert (whileLoopOp |> isNull |> not) - // Implement overloads - override __.FieldType = fieldType - override __.GetRawConstantValue() = literalValue - override __.Attributes = FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public - override __.Name = fieldName - override __.DeclaringType = declaringType |> nonNull "ProvidedLiteralField.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Field - - override __.ReflectedType = notRequired "ReflectedType" fieldName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" fieldName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" fieldName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" fieldName - - override __.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired "SetValue" fieldName - override __.GetValue(_obj) : obj = notRequired "GetValue" fieldName - override __.FieldHandle = notRequired "FieldHandle" fieldName - -type ProvidedField(fieldName:string,fieldType:Type) = - inherit System.Reflection.FieldInfo() - // State - - let mutable declaringType = null - - let customAttributesImpl = CustomAttributesImpl() - let mutable fieldAttrs = FieldAttributes.Private - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif + let ifThenElseOp = qTy.GetMethod("get_IfThenElseOp", bindAll) + assert (ifThenElseOp |> isNull |> not) - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice + let newUnionCaseOp = qTy.GetMethod("NewNewUnionCaseOp", bindAll) + assert (newUnionCaseOp |> isNull |> not) - member __.SetFieldAttributes attrs = fieldAttrs <- attrs - // Implement overloads - override __.FieldType = fieldType - override __.GetRawConstantValue() = null - override __.Attributes = fieldAttrs - override __.Name = fieldName - override __.DeclaringType = declaringType |> nonNull "ProvidedField.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Field + let newRecordOp = qTy.GetMethod("NewNewRecordOp", bindAll) + assert (newRecordOp |> isNull |> not) + + type Microsoft.FSharp.Quotations.Expr with - override __.ReflectedType = notRequired "ReflectedType" fieldName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" fieldName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" fieldName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" fieldName + static member NewDelegateUnchecked (ty: Type, vs: Var list, body: Expr) = + let e = List.foldBack (fun v acc -> Expr.Lambda(v, acc)) vs body + let op = newDelegateOp.Invoke(null, [| box ty |]) + mkFE1.Invoke(null, [| box op; box e |]) :?> Expr - override __.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired "SetValue" fieldName - override __.GetValue(_obj) : obj = notRequired "GetValue" fieldName - override __.FieldHandle = notRequired "FieldHandle" fieldName + static member NewObjectUnchecked (cinfo: ConstructorInfo, args: Expr list) = + let op = newObjectOp.Invoke(null, [| box cinfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member NewArrayUnchecked (elementType: Type, elements: Expr list) = + let op = newArrayOp.Invoke(null, [| box elementType |]) + mkFEN.Invoke(null, [| box op; box elements |]) :?> Expr + + static member CallUnchecked (minfo: MethodInfo, args: Expr list) = + let op = staticCallOp.Invoke(null, [| box minfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member CallUnchecked (obj: Expr, minfo: MethodInfo, args: Expr list) = + let op = instanceCallOp.Invoke(null, [| box minfo |]) + mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + + static member ApplicationUnchecked (f: Expr, x: Expr) = + let op = appOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box f; box x |]) :?> Expr + + static member PropertyGetUnchecked (pinfo: PropertyInfo, args: Expr list) = + let op = staticPropGetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member PropertyGetUnchecked (obj: Expr, pinfo: PropertyInfo, ?args: Expr list) = + let args = defaultArg args [] + let op = instancePropGetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + + static member PropertySetUnchecked (pinfo: PropertyInfo, value: Expr, ?args: Expr list) = + let args = defaultArg args [] + let op = staticPropSetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (args@[value]) |]) :?> Expr + + static member PropertySetUnchecked (obj: Expr, pinfo: PropertyInfo, value: Expr, ?args: Expr list) = + let args = defaultArg args [] + let op = instancePropSetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (obj::(args@[value])) |]) :?> Expr + + static member FieldGetUnchecked (pinfo: FieldInfo) = + let op = staticFieldGetOp.Invoke(null, [| box pinfo |]) + mkFE0.Invoke(null, [| box op; |]) :?> Expr + + static member FieldGetUnchecked (obj: Expr, pinfo: FieldInfo) = + let op = instanceFieldGetOp.Invoke(null, [| box pinfo |]) + mkFE1.Invoke(null, [| box op; box obj |]) :?> Expr + + static member FieldSetUnchecked (pinfo: FieldInfo, value: Expr) = + let op = staticFieldSetOp.Invoke(null, [| box pinfo |]) + mkFE1.Invoke(null, [| box op; box value |]) :?> Expr + + static member FieldSetUnchecked (obj: Expr, pinfo: FieldInfo, value: Expr) = + let op = instanceFieldSetOp.Invoke(null, [| box pinfo |]) + mkFE2.Invoke(null, [| box op; box obj; box value |]) :?> Expr + + static member TupleGetUnchecked (e: Expr, n:int) = + let op = tupleGetOp.Invoke(null, [| box e.Type; box n |]) + mkFE1.Invoke(null, [| box op; box e |]) :?> Expr + + static member LetUnchecked (v:Var, e: Expr, body:Expr) = + let lam = Expr.Lambda(v, body) + let op = letOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box e; box lam |]) :?> Expr + + static member ForIntegerRangeLoopUnchecked (loopVariable, startExpr:Expr, endExpr:Expr, body:Expr) = + let lam = Expr.Lambda(loopVariable, body) + let op = forIntegerRangeLoopOp.Invoke(null, [| |]) + mkFE3.Invoke(null, [| box op; box startExpr; box endExpr; box lam |] ) :?> Expr + + static member WhileLoopUnchecked (guard:Expr, body:Expr) = + let op = whileLoopOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box guard; box body |] ):?> Expr + + static member IfThenElseUnchecked (e:Expr, t:Expr, f:Expr) = + let op = ifThenElseOp.Invoke(null, [| |]) + mkFE3.Invoke(null, [| box op; box e; box t; box f |] ):?> Expr + + static member NewUnionCaseUnchecked (uci:Reflection.UnionCaseInfo, args:Expr list) = + let op = newUnionCaseOp.Invoke(null, [| box uci |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member NewRecordUnchecked (ty:Type, args:Expr list) = + let op = newRecordOp.Invoke(null, [| box ty |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + type Shape = Shape of (Expr list -> Expr) + + let (|ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked|) e = + match e with + | NewObject (cinfo, args) -> + ShapeCombinationUnchecked (Shape (function args -> Expr.NewObjectUnchecked (cinfo, args)), args) + | NewArray (ty, args) -> + ShapeCombinationUnchecked (Shape (function args -> Expr.NewArrayUnchecked (ty, args)), args) + | NewDelegate (t, vars, expr) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.NewDelegateUnchecked (t, vars, expr) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | TupleGet (expr, n) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, n) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | Application (f, x) -> + ShapeCombinationUnchecked (Shape (function [f; x] -> Expr.ApplicationUnchecked (f, x) | _ -> invalidArg "expr" "invalid shape"), [f; x]) + | Call (objOpt, minfo, args) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.CallUnchecked (minfo, args)), args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.CallUnchecked (obj, minfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) + | PropertyGet (objOpt, pinfo, args) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.PropertyGetUnchecked (pinfo, args)), args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.PropertyGetUnchecked (obj, pinfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) + | PropertySet (objOpt, pinfo, args, value) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function (value::args) -> Expr.PropertySetUnchecked (pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), value::args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::value::args) -> Expr.PropertySetUnchecked (obj, pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), obj::value::args) + | FieldGet (objOpt, pinfo) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function _ -> Expr.FieldGetUnchecked (pinfo)), []) + | Some obj -> ShapeCombinationUnchecked (Shape (function [obj] -> Expr.FieldGetUnchecked (obj, pinfo) | _ -> invalidArg "expr" "invalid shape"), [obj]) + | FieldSet (objOpt, pinfo, value) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function [value] -> Expr.FieldSetUnchecked (pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [value]) + | Some obj -> ShapeCombinationUnchecked (Shape (function [obj;value] -> Expr.FieldSetUnchecked (obj, pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [obj; value]) + | Let (var, value, body) -> + ShapeCombinationUnchecked (Shape (function [value;Lambda(var, body)] -> Expr.LetUnchecked(var, value, body) | _ -> invalidArg "expr" "invalid shape"), [value; Expr.Lambda(var, body)]) + | ForIntegerRangeLoop (loopVar, first, last, body) -> + ShapeCombinationUnchecked (Shape (function [first; last; Lambda(loopVar, body)] -> Expr.ForIntegerRangeLoopUnchecked (loopVar, first, last, body) | _ -> invalidArg "expr" "invalid shape"), [first; last; Expr.Lambda(loopVar, body)]) + | WhileLoop (cond, body) -> + ShapeCombinationUnchecked (Shape (function [cond; body] -> Expr.WhileLoopUnchecked (cond, body) | _ -> invalidArg "expr" "invalid shape"), [cond; body]) + | IfThenElse (g, t, e) -> + ShapeCombinationUnchecked (Shape (function [g; t; e] -> Expr.IfThenElseUnchecked (g, t, e) | _ -> invalidArg "expr" "invalid shape"), [g; t; e]) + | TupleGet (expr, i) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, i) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | ExprShape.ShapeCombination (comb, args) -> + ShapeCombinationUnchecked (Shape (fun args -> ExprShape.RebuildShapeCombination(comb, args)), args) + | ExprShape.ShapeVar v -> ShapeVarUnchecked v + | ExprShape.ShapeLambda (v, e) -> ShapeLambdaUnchecked (v, e) + + let RebuildShapeCombinationUnchecked (Shape comb, args) = comb args + +//-------------------------------------------------------------------------------- +// Instantiated symbols +// /// Represents the type constructor in a provided symbol type. [] -type SymbolKind = - | SDArray - | Array of int - | Pointer - | ByRef - | Generic of System.Type - | FSharpTypeAbbreviation of (System.Reflection.Assembly * string * string[]) +type ProvidedTypeSymbolKind = + | SDArray + | Array of int + | Pointer + | ByRef + | Generic of Type + | FSharpTypeAbbreviation of (Assembly * string * string[]) /// Represents an array or other symbolic type involving a provided type as the argument. /// See the type provider spec for the methods that must be implemented. /// Note that the type provider specification does not require us to implement pointer-equality for provided types. -type ProvidedSymbolType(kind: SymbolKind, args: Type list) = - inherit Type() - - let rec isEquivalentTo (thisTy: Type) (otherTy: Type) = - match thisTy, otherTy with - | (:? ProvidedSymbolType as thisTy), (:? ProvidedSymbolType as thatTy) -> (thisTy.Kind,thisTy.Args) = (thatTy.Kind, thatTy.Args) - | (:? ProvidedSymbolType as thisTy), otherTy | otherTy, (:? ProvidedSymbolType as thisTy) -> - match thisTy.Kind, thisTy.Args with - | SymbolKind.SDArray, [ty] | SymbolKind.Array _, [ty] when otherTy.IsArray-> ty.Equals(otherTy.GetElementType()) - | SymbolKind.ByRef, [ty] when otherTy.IsByRef -> ty.Equals(otherTy.GetElementType()) - | SymbolKind.Pointer, [ty] when otherTy.IsPointer -> ty.Equals(otherTy.GetElementType()) - | SymbolKind.Generic baseTy, args -> otherTy.IsGenericType && isEquivalentTo baseTy (otherTy.GetGenericTypeDefinition()) && Seq.forall2 isEquivalentTo args (otherTy.GetGenericArguments()) - | _ -> false - | a, b -> a.Equals b - - let nameText() = - match kind,args with - | SymbolKind.SDArray,[arg] -> arg.Name + "[]" - | SymbolKind.Array _,[arg] -> arg.Name + "[*]" - | SymbolKind.Pointer,[arg] -> arg.Name + "*" - | SymbolKind.ByRef,[arg] -> arg.Name + "&" - | SymbolKind.Generic gty, args -> gty.Name + (sprintf "%A" args) - | SymbolKind.FSharpTypeAbbreviation (_,_,path),_ -> path.[path.Length-1] +type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list, typeBuilder: ITypeBuilder) as this = + inherit TypeDelegator() + let typeArgs = Array.ofList typeArgs + + do this.typeImpl <- this + + /// Substitute types for type variables. + override __.FullName = + match kind, typeArgs with + | ProvidedTypeSymbolKind.SDArray, [| arg |] -> arg.FullName + "[]" + | ProvidedTypeSymbolKind.Array _, [| arg |] -> arg.FullName + "[*]" + | ProvidedTypeSymbolKind.Pointer, [| arg |] -> arg.FullName + "*" + | ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.FullName + "&" + | ProvidedTypeSymbolKind.Generic gty, typeArgs -> gty.FullName + "[" + (typeArgs |> Array.map (fun arg -> arg.ToString()) |> String.concat ",") + "]" + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_, nsp, path), typeArgs -> String.concat "." (Array.append [| nsp |] path) + (match typeArgs with [| |] -> "" | _ -> typeArgs.ToString()) | _ -> failwith "unreachable" - static member convType (parameters: Type list) (ty:Type) = - if ty = null then null - elif ty.IsGenericType then - let args = Array.map (ProvidedSymbolType.convType parameters) (ty.GetGenericArguments()) - ProvidedSymbolType(Generic (ty.GetGenericTypeDefinition()), Array.toList args) :> Type - elif ty.HasElementType then - let ety = ProvidedSymbolType.convType parameters (ty.GetElementType()) - if ty.IsArray then - let rank = ty.GetArrayRank() - if rank = 1 then ProvidedSymbolType(SDArray,[ety]) :> Type - else ProvidedSymbolType(Array rank,[ety]) :> Type - elif ty.IsPointer then ProvidedSymbolType(Pointer,[ety]) :> Type - elif ty.IsByRef then ProvidedSymbolType(ByRef,[ety]) :> Type - else ty - elif ty.IsGenericParameter then - if ty.GenericParameterPosition <= parameters.Length - 1 then - parameters.[ty.GenericParameterPosition] - else - ty - else ty - - override __.FullName = - match kind,args with - | SymbolKind.SDArray,[arg] -> arg.FullName + "[]" - | SymbolKind.Array _,[arg] -> arg.FullName + "[*]" - | SymbolKind.Pointer,[arg] -> arg.FullName + "*" - | SymbolKind.ByRef,[arg] -> arg.FullName + "&" - | SymbolKind.Generic gty, args -> gty.FullName + "[" + (args |> List.map (fun arg -> arg.ToString()) |> String.concat ",") + "]" - | SymbolKind.FSharpTypeAbbreviation (_,nsp,path),args -> String.concat "." (Array.append [| nsp |] path) + args.ToString() - | _ -> failwith "unreachable" - /// Although not strictly required by the type provider specification, this is required when doing basic operations like FullName on /// .NET symbolic types made from this type, e.g. when building Nullable.FullName - override __.DeclaringType = - match kind,args with - | SymbolKind.SDArray,[arg] -> arg - | SymbolKind.Array _,[arg] -> arg - | SymbolKind.Pointer,[arg] -> arg - | SymbolKind.ByRef,[arg] -> arg - | SymbolKind.Generic gty,_ -> gty - | SymbolKind.FSharpTypeAbbreviation _,_ -> null - | _ -> failwith "unreachable" - - override __.IsAssignableFrom(otherTy) = + override __.DeclaringType = match kind with - | Generic gtd -> - if otherTy.IsGenericType then - let otherGtd = otherTy.GetGenericTypeDefinition() - let otherArgs = otherTy.GetGenericArguments() - let yes = gtd.Equals(otherGtd) && Seq.forall2 isEquivalentTo args otherArgs - yes - else - base.IsAssignableFrom(otherTy) - | _ -> base.IsAssignableFrom(otherTy) - - override __.Name = nameText() + | ProvidedTypeSymbolKind.SDArray -> null + | ProvidedTypeSymbolKind.Array _ -> null + | ProvidedTypeSymbolKind.Pointer -> null + | ProvidedTypeSymbolKind.ByRef -> null + | ProvidedTypeSymbolKind.Generic gty -> gty.DeclaringType + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> null + + override __.Name = + match kind, typeArgs with + | ProvidedTypeSymbolKind.SDArray, [| arg |] -> arg.Name + "[]" + | ProvidedTypeSymbolKind.Array _, [| arg |] -> arg.Name + "[*]" + | ProvidedTypeSymbolKind.Pointer, [| arg |] -> arg.Name + "*" + | ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.Name + "&" + | ProvidedTypeSymbolKind.Generic gty, _typeArgs -> gty.Name + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_, _, path), _ -> path.[path.Length-1] + | _ -> failwith "unreachable" override __.BaseType = - match kind with - | SymbolKind.SDArray -> typeof - | SymbolKind.Array _ -> typeof - | SymbolKind.Pointer -> typeof - | SymbolKind.ByRef -> typeof - | SymbolKind.Generic gty -> - if gty.BaseType = null then null else - ProvidedSymbolType.convType args gty.BaseType - | SymbolKind.FSharpTypeAbbreviation _ -> typeof - - override __.GetArrayRank() = (match kind with SymbolKind.Array n -> n | SymbolKind.SDArray -> 1 | _ -> invalidOp "non-array type") - override __.IsArrayImpl() = (match kind with SymbolKind.Array _ | SymbolKind.SDArray -> true | _ -> false) - override __.IsByRefImpl() = (match kind with SymbolKind.ByRef _ -> true | _ -> false) - override __.IsPointerImpl() = (match kind with SymbolKind.Pointer _ -> true | _ -> false) + match kind with + | ProvidedTypeSymbolKind.SDArray -> typeof + | ProvidedTypeSymbolKind.Array _ -> typeof + | ProvidedTypeSymbolKind.Pointer -> typeof + | ProvidedTypeSymbolKind.ByRef -> typeof + | ProvidedTypeSymbolKind.Generic gty -> + if isNull gty.BaseType then null else + instType typeBuilder (typeArgs, [| |]) gty.BaseType + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> typeof + + override __.GetArrayRank() = (match kind with ProvidedTypeSymbolKind.Array n -> n | ProvidedTypeSymbolKind.SDArray -> 1 | _ -> failwithf "non-array type '%O'" this) + override __.IsValueTypeImpl() = (match kind with ProvidedTypeSymbolKind.Generic gtd -> gtd.IsValueType | _ -> false) + override __.IsArrayImpl() = (match kind with ProvidedTypeSymbolKind.Array _ | ProvidedTypeSymbolKind.SDArray -> true | _ -> false) + override __.IsByRefImpl() = (match kind with ProvidedTypeSymbolKind.ByRef _ -> true | _ -> false) + override __.IsPointerImpl() = (match kind with ProvidedTypeSymbolKind.Pointer _ -> true | _ -> false) override __.IsPrimitiveImpl() = false - override __.IsGenericType = (match kind with SymbolKind.Generic _ -> true | _ -> false) - override __.GetGenericArguments() = (match kind with SymbolKind.Generic _ -> args |> List.toArray | _ -> invalidOp "non-generic type") - override __.GetGenericTypeDefinition() = (match kind with SymbolKind.Generic e -> e | _ -> invalidOp "non-generic type") + override __.IsGenericType = (match kind with ProvidedTypeSymbolKind.Generic _ -> true | _ -> false) + override this.GetGenericArguments() = (match kind with ProvidedTypeSymbolKind.Generic _ -> typeArgs | _ -> failwithf "non-generic type '%O'" this) + override this.GetGenericTypeDefinition() = (match kind with ProvidedTypeSymbolKind.Generic e -> e | _ -> failwithf "non-generic type '%O'" this) override __.IsCOMObjectImpl() = false - override __.HasElementTypeImpl() = (match kind with SymbolKind.Generic _ -> false | _ -> true) - override __.GetElementType() = (match kind,args with (SymbolKind.Array _ | SymbolKind.SDArray | SymbolKind.ByRef | SymbolKind.Pointer),[e] -> e | _ -> invalidOp "not an array, pointer or byref type") - override this.ToString() = this.FullName + override __.HasElementTypeImpl() = (match kind with ProvidedTypeSymbolKind.Generic _ -> false | _ -> true) + override __.GetElementType() = (match kind, typeArgs with (ProvidedTypeSymbolKind.Array _ | ProvidedTypeSymbolKind.SDArray | ProvidedTypeSymbolKind.ByRef | ProvidedTypeSymbolKind.Pointer), [| e |] -> e | _ -> failwithf "not an array, pointer or byref type") + + override this.Assembly = + match kind, typeArgs with + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (assembly, _nsp, _path), _ -> assembly + | ProvidedTypeSymbolKind.Generic gty, _ -> gty.Assembly + | ProvidedTypeSymbolKind.SDArray, [| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.Array _, [| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.Pointer, [| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.Assembly + | _ -> notRequired this "Assembly" this.FullName + + override this.Namespace = + match kind, typeArgs with + | ProvidedTypeSymbolKind.SDArray, [| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Array _, [| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Pointer, [| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Generic gty, _ -> gty.Namespace + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_assembly, nsp, _path), _ -> nsp + | _ -> notRequired this "Namespace" this.FullName + + override x.Module = x.Assembly.ManifestModule + + override __.GetHashCode() = + match kind, typeArgs with + | ProvidedTypeSymbolKind.SDArray, [| arg |] -> 10 + hash arg + | ProvidedTypeSymbolKind.Array _, [| arg |] -> 163 + hash arg + | ProvidedTypeSymbolKind.Pointer, [| arg |] -> 283 + hash arg + | ProvidedTypeSymbolKind.ByRef, [| arg |] -> 43904 + hash arg + | ProvidedTypeSymbolKind.Generic gty, _ -> 9797 + hash gty + Array.sumBy hash typeArgs + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _, _ -> 3092 + | _ -> failwith "unreachable" - override __.Assembly = - match kind with - | SymbolKind.FSharpTypeAbbreviation (assembly,_nsp,_path) -> assembly - | SymbolKind.Generic gty -> gty.Assembly - | _ -> notRequired "Assembly" (nameText()) + override this.Equals(other: obj) = eqTypeObj this other - override __.Namespace = - match kind with - | SymbolKind.FSharpTypeAbbreviation (_assembly,nsp,_path) -> nsp - | _ -> notRequired "Namespace" (nameText()) - - override __.GetHashCode() = - match kind,args with - | SymbolKind.SDArray,[arg] -> 10 + hash arg - | SymbolKind.Array _,[arg] -> 163 + hash arg - | SymbolKind.Pointer,[arg] -> 283 + hash arg - | SymbolKind.ByRef,[arg] -> 43904 + hash arg - | SymbolKind.Generic gty,_ -> 9797 + hash gty + List.sumBy hash args - | SymbolKind.FSharpTypeAbbreviation _,_ -> 3092 - | _ -> failwith "unreachable" - - override __.Equals(other: obj) = - match other with - | :? ProvidedSymbolType as otherTy -> (kind, args) = (otherTy.Kind, otherTy.Args) - | _ -> false + override this.Equals(otherTy: Type) = eqTypes this otherTy + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy member __.Kind = kind - member __.Args = args - - override __.Module : Module = notRequired "Module" (nameText()) - override __.GetConstructors _bindingAttr = notRequired "GetConstructors" (nameText()) - override __.GetMethodImpl(_name, _bindingAttr, _binderBinder, _callConvention, _types, _modifiers) = + + member __.Args = typeArgs + + member __.IsFSharpTypeAbbreviation = match kind with FSharpTypeAbbreviation _ -> true | _ -> false + + // For example, int + member __.IsFSharpUnitAnnotated = match kind with ProvidedTypeSymbolKind.Generic gtd -> not gtd.IsGenericTypeDefinition | _ -> false + + override __.GetConstructorImpl(_bindingFlags, _binder, _callConventions, _types, _modifiers) = null + + override this.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, _types, _modifiers) = match kind with - | Generic gtd -> - let ty = gtd.GetGenericTypeDefinition().MakeGenericType(Array.ofList args) - ty.GetMethod(_name, _bindingAttr) - | _ -> notRequired "GetMethodImpl" (nameText()) - override __.GetMembers _bindingAttr = notRequired "GetMembers" (nameText()) - override __.GetMethods _bindingAttr = notRequired "GetMethods" (nameText()) - override __.GetField(_name, _bindingAttr) = notRequired "GetField" (nameText()) - override __.GetFields _bindingAttr = notRequired "GetFields" (nameText()) - override __.GetInterface(_name, _ignoreCase) = notRequired "GetInterface" (nameText()) - override __.GetInterfaces() = notRequired "GetInterfaces" (nameText()) - override __.GetEvent(_name, _bindingAttr) = notRequired "GetEvent" (nameText()) - override __.GetEvents _bindingAttr = notRequired "GetEvents" (nameText()) - override __.GetProperties _bindingAttr = notRequired "GetProperties" (nameText()) - override __.GetPropertyImpl(_name, _bindingAttr, _binder, _returnType, _types, _modifiers) = notRequired "GetPropertyImpl" (nameText()) - override __.GetNestedTypes _bindingAttr = notRequired "GetNestedTypes" (nameText()) - override __.GetNestedType(_name, _bindingAttr) = notRequired "GetNestedType" (nameText()) - override __.GetAttributeFlagsImpl() = notRequired "GetAttributeFlagsImpl" (nameText()) - override this.UnderlyingSystemType = - match kind with - | SymbolKind.SDArray - | SymbolKind.Array _ - | SymbolKind.Pointer - | SymbolKind.FSharpTypeAbbreviation _ - | SymbolKind.ByRef -> upcast this - | SymbolKind.Generic gty -> gty.UnderlyingSystemType -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = ([| |] :> IList<_>) -#endif - override __.MemberType = notRequired "MemberType" (nameText()) - override __.GetMember(_name,_mt,_bindingAttr) = notRequired "GetMember" (nameText()) - override __.GUID = notRequired "GUID" (nameText()) - override __.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "InvokeMember" (nameText()) - override __.AssemblyQualifiedName = notRequired "AssemblyQualifiedName" (nameText()) - override __.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers) = notRequired "GetConstructorImpl" (nameText()) - override __.GetCustomAttributes(_inherit) = [| |] - override __.GetCustomAttributes(_attributeType, _inherit) = [| |] - override __.IsDefined(_attributeType, _inherit) = false - // FSharp.Data addition: this was added to support arrays of arrays - override this.MakeArrayType() = ProvidedSymbolType(SymbolKind.SDArray, [this]) :> Type - override this.MakeArrayType arg = ProvidedSymbolType(SymbolKind.Array arg, [this]) :> Type - -type ProvidedSymbolMethod(genericMethodDefinition: MethodInfo, parameters: Type list) = - inherit System.Reflection.MethodInfo() - - let convParam (p:ParameterInfo) = - { new System.Reflection.ParameterInfo() with - override __.Name = p.Name - override __.ParameterType = ProvidedSymbolType.convType parameters p.ParameterType - override __.Attributes = p.Attributes - override __.RawDefaultValue = p.RawDefaultValue -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = p.GetCustomAttributesData() -#endif - } + | Generic gtd -> + let ty = gtd.GetGenericTypeDefinition().MakeGenericType(typeArgs) + ty.GetMethod(name, bindingFlags) + | _ -> notRequired this "GetMethodImpl" this.FullName - override this.IsGenericMethod = - (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) < parameters.Length - override this.GetGenericArguments() = - Seq.skip (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) parameters |> Seq.toArray + override this.GetField(_name, _bindingFlags) = notRequired this "GetField" this.FullName - override __.GetGenericMethodDefinition() = genericMethodDefinition + override this.GetPropertyImpl(_name, _bindingFlags, _binder, _returnType, _types, _modifiers) = notRequired this "GetPropertyImpl" this.FullName - override __.DeclaringType = ProvidedSymbolType.convType parameters genericMethodDefinition.DeclaringType - override __.ToString() = "Method " + genericMethodDefinition.Name - override __.Name = genericMethodDefinition.Name - override __.MetadataToken = genericMethodDefinition.MetadataToken - override __.Attributes = genericMethodDefinition.Attributes - override __.CallingConvention = genericMethodDefinition.CallingConvention - override __.MemberType = genericMethodDefinition.MemberType + override this.GetEvent(_name, _bindingFlags) = notRequired this "GetEvent" this.FullName - override __.IsDefined(_attributeType, _inherit) : bool = notRequired "IsDefined" genericMethodDefinition.Name - override __.ReturnType = ProvidedSymbolType.convType parameters genericMethodDefinition.ReturnType - override __.GetParameters() = genericMethodDefinition.GetParameters() |> Array.map convParam - override __.ReturnParameter = genericMethodDefinition.ReturnParameter |> convParam - override __.ReturnTypeCustomAttributes = notRequired "ReturnTypeCustomAttributes" genericMethodDefinition.Name - override __.GetBaseDefinition() = notRequired "GetBaseDefinition" genericMethodDefinition.Name - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" genericMethodDefinition.Name - override __.MethodHandle = notRequired "MethodHandle" genericMethodDefinition.Name - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" genericMethodDefinition.Name - override __.ReflectedType = notRequired "ReflectedType" genericMethodDefinition.Name - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" genericMethodDefinition.Name - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" genericMethodDefinition.Name + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.FullName + override this.GetConstructors _bindingFlags = notRequired this "GetConstructors" this.FullName + override this.GetMethods _bindingFlags = notRequired this "GetMethods" this.FullName -type ProvidedTypeBuilder() = - static member MakeGenericType(genericTypeDefinition, genericArguments) = ProvidedSymbolType(Generic genericTypeDefinition, genericArguments) :> Type - static member MakeGenericMethod(genericMethodDefinition, genericArguments) = ProvidedSymbolMethod(genericMethodDefinition, genericArguments) :> MethodInfo + override this.GetFields _bindingFlags = notRequired this "GetFields" this.FullName -[] -type ProvidedMeasureBuilder() = + override this.GetProperties _bindingFlags = notRequired this "GetProperties" this.FullName - // TODO: this shouldn't be hardcoded, but without creating a dependency on FSharp.Compiler.Service - // there seems to be no way to check if a type abbreviation exists - let unitNamesTypeAbbreviations = - [ "meter"; "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb"; - "volt"; "farad"; "ohm"; "siemens"; "weber"; "tesla"; "henry" - "lumen"; "lux"; "becquerel"; "gray"; "sievert"; "katal" ] - |> Set.ofList + override this.GetEvents _bindingFlags = notRequired this "GetEvents" this.FullName - let unitSymbolsTypeAbbreviations = - [ "m"; "kg"; "s"; "A"; "K"; "mol"; "cd"; "Hz"; "N"; "Pa"; "J"; "W"; "C" - "V"; "F"; "S"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H" ] - |> Set.ofList + override this.GetNestedTypes _bindingFlags = notRequired this "GetNestedTypes" this.FullName - static let theBuilder = ProvidedMeasureBuilder() - static member Default = theBuilder - member __.One = typeof - member __.Product (m1,m2) = typedefof>.MakeGenericType [| m1;m2 |] - member __.Inverse m = typedefof>.MakeGenericType [| m |] - member b.Ratio (m1, m2) = b.Product(m1, b.Inverse m2) - member b.Square m = b.Product(m, m) + override this.GetMembers _bindingFlags = notRequired this "GetMembers" this.FullName - // FSharp.Data change: if the unit is not a valid type, instead - // of assuming it's a type abbreviation, which may not be the case and cause a - // problem later on, check the list of valid abbreviations - member __.SI (m:string) = - let mLowerCase = m.ToLowerInvariant() - let abbreviation = - if unitNamesTypeAbbreviations.Contains mLowerCase then - Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames", mLowerCase) - elif unitSymbolsTypeAbbreviations.Contains m then - Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols", m) - else - None + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.FullName + + override this.GetInterfaces() = notRequired this "GetInterfaces" this.FullName + + override this.GetAttributeFlagsImpl() = getAttributeFlagsImpl this + + override this.UnderlyingSystemType = + match kind with + | ProvidedTypeSymbolKind.SDArray + | ProvidedTypeSymbolKind.Array _ + | ProvidedTypeSymbolKind.Pointer + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ + | ProvidedTypeSymbolKind.ByRef -> upcast this + | ProvidedTypeSymbolKind.Generic gty -> gty.UnderlyingSystemType + + override __.GetCustomAttributesData() = ([| |] :> IList<_>) + + override this.MemberType = notRequired this "MemberType" this.FullName + + override this.GetMember(_name, _mt, _bindingFlags) = notRequired this "GetMember" this.FullName + + override this.GUID = notRequired this "GUID" this.FullName + + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" this.FullName + + override this.AssemblyQualifiedName = notRequired this "AssemblyQualifiedName" this.FullName + + override __.GetCustomAttributes(_inherit) = emptyAttributes + + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + + override __.IsDefined(_attributeType, _inherit) = false + + override this.MakeArrayType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.SDArray, [this], typeBuilder) :> Type + + override this.MakeArrayType arg = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Array arg, [this], typeBuilder) :> Type + +#if NETCOREAPP + // See bug https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues/236 + override __.IsSZArray = + match kind with + | ProvidedTypeSymbolKind.SDArray -> true + | _ -> false +#endif + + override __.MetadataToken = + match kind with + | ProvidedTypeSymbolKind.SDArray -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Array _ -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Pointer -> typeof.MetadataToken + | ProvidedTypeSymbolKind.ByRef -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Generic gty -> gty.MetadataToken + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> typeof.MetadataToken + + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + override this.ToString() = this.FullName + +type ProvidedSymbolMethod(genericMethodDefinition: MethodInfo, parameters: Type[], typeBuilder: ITypeBuilder) = + inherit MethodInfo() + + let convParam (p:ParameterInfo) = + { new ParameterInfo() with + override __.Name = p.Name + override __.ParameterType = instType typeBuilder (parameters, [| |]) p.ParameterType + override __.Attributes = p.Attributes + override __.RawDefaultValue = p.RawDefaultValue + override __.GetCustomAttributesData() = p.GetCustomAttributesData() + } + + override this.IsGenericMethod = + (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) < parameters.Length + + override this.GetGenericArguments() = + Seq.skip (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) parameters |> Seq.toArray + + override __.GetGenericMethodDefinition() = genericMethodDefinition + + override __.DeclaringType = instType typeBuilder (parameters, [| |]) genericMethodDefinition.DeclaringType + override __.ToString() = "Method " + genericMethodDefinition.Name + override __.Name = genericMethodDefinition.Name + override __.MetadataToken = genericMethodDefinition.MetadataToken + override __.Attributes = genericMethodDefinition.Attributes + override __.CallingConvention = genericMethodDefinition.CallingConvention + override __.MemberType = genericMethodDefinition.MemberType + + override this.IsDefined(_attributeType, _inherit): bool = notRequired this "IsDefined" genericMethodDefinition.Name + override __.ReturnType = instType typeBuilder (parameters, [| |]) genericMethodDefinition.ReturnType + override __.GetParameters() = genericMethodDefinition.GetParameters() |> Array.map convParam + override __.ReturnParameter = genericMethodDefinition.ReturnParameter |> convParam + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" genericMethodDefinition.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" genericMethodDefinition.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" genericMethodDefinition.Name + override this.MethodHandle = notRequired this "MethodHandle" genericMethodDefinition.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" genericMethodDefinition.Name + override this.ReflectedType = notRequired this "ReflectedType" genericMethodDefinition.Name + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + +//-------------------------------------------------------------------------------- +// ProvidedMethod, ProvidedConstructor, ProvidedTypeDefinition and other provided objects + + +[] +module Misc = + + + let mkParamArrayCustomAttributeData() = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| |] + member __.NamedArguments = upcast [| |] } + + let mkEditorHideMethodsCustomAttributeData() = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| |] + member __.NamedArguments = upcast [| |] } + + let mkAllowNullLiteralCustomAttributeData value = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, value) |] + member __.NamedArguments = upcast [| |] } + + /// This makes an xml doc attribute w.r.t. an amortized computation of an xml doc string. + /// It is important that the text of the xml doc only get forced when poking on the ConstructorArguments + /// for the CustomAttributeData object. + let mkXmlDocCustomAttributeDataLazy(lazyText: Lazy) = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, lazyText.Force()) |] + member __.NamedArguments = upcast [| |] } + + let mkXmlDocCustomAttributeData(s:string) = mkXmlDocCustomAttributeDataLazy (lazy s) + + let mkDefinitionLocationAttributeCustomAttributeData(line:int, column:int, filePath:string) = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| |] + member __.NamedArguments = + upcast [| CustomAttributeNamedArgument(typeof.GetProperty("FilePath"), CustomAttributeTypedArgument(typeof, filePath)); + CustomAttributeNamedArgument(typeof.GetProperty("Line"), CustomAttributeTypedArgument(typeof, line)) ; + CustomAttributeNamedArgument(typeof.GetProperty("Column"), CustomAttributeTypedArgument(typeof, column)) + |] } + let mkObsoleteAttributeCustomAttributeData(message:string, isError: bool) = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors() |> Array.find (fun x -> x.GetParameters().Length = 2) + member __.ConstructorArguments = upcast [|CustomAttributeTypedArgument(typeof, message) ; CustomAttributeTypedArgument(typeof, isError) |] + member __.NamedArguments = upcast [| |] } + + let mkReflectedDefinitionCustomAttributeData() = + { new CustomAttributeData() with + member __.Constructor = typeof.GetConstructors().[0] + member __.ConstructorArguments = upcast [| |] + member __.NamedArguments = upcast [| |] } + + type CustomAttributesImpl(isTgt, customAttributesData) = + let customAttributes = ResizeArray() + let mutable hideObjectMethods = false + let mutable nonNullable = false + let mutable obsoleteMessage = None + let mutable xmlDocDelayed = None + let mutable xmlDocAlwaysRecomputed = None + let mutable hasParamArray = false + let mutable hasReflectedDefinition = false + + // XML doc text that we only compute once, if any. This must _not_ be forced until the ConstructorArguments + // property of the custom attribute is foced. + let xmlDocDelayedText = + lazy + (match xmlDocDelayed with None -> assert false; "" | Some f -> f()) + + // Custom atttributes that we only compute once + let customAttributesOnce = + lazy + [| + if not isTgt then + if hideObjectMethods then yield mkEditorHideMethodsCustomAttributeData() + if nonNullable then yield mkAllowNullLiteralCustomAttributeData false + match xmlDocDelayed with None -> () | Some _ -> customAttributes.Add(mkXmlDocCustomAttributeDataLazy xmlDocDelayedText) + match xmlDocAlwaysRecomputed with None -> () | Some f -> yield mkXmlDocCustomAttributeData (f()) + match obsoleteMessage with None -> () | Some s -> customAttributes.Add(mkObsoleteAttributeCustomAttributeData s) + if hasParamArray then yield mkParamArrayCustomAttributeData() + if hasReflectedDefinition then yield mkReflectedDefinitionCustomAttributeData() + yield! customAttributes + yield! customAttributesData() + |] + + member __.AddDefinitionLocation(line:int, column:int, filePath:string) = customAttributes.Add(mkDefinitionLocationAttributeCustomAttributeData(line, column, filePath)) + member __.AddObsolete(message: string, isError) = obsoleteMessage <- Some (message, isError) + member __.HasParamArray with get() = hasParamArray and set(v) = hasParamArray <- v + member __.HasReflectedDefinition with get() = hasReflectedDefinition and set(v) = hasReflectedDefinition <- v + member __.AddXmlDocComputed xmlDocFunction = xmlDocAlwaysRecomputed <- Some xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = xmlDocDelayed <- Some xmlDocFunction + member __.AddXmlDoc xmlDoc = xmlDocDelayed <- Some (K xmlDoc) + member __.HideObjectMethods with get() = hideObjectMethods and set v = hideObjectMethods <- v + member __.NonNullable with get () = nonNullable and set v = nonNullable <- v + member __.AddCustomAttribute(attribute) = customAttributes.Add(attribute) + member __.GetCustomAttributesData() = + let attrs = customAttributesOnce.Force() + let attrsWithDocHack = + match xmlDocAlwaysRecomputed with + | None -> + attrs + | Some f -> + // Recomputed XML doc is evaluated on every call to GetCustomAttributesData() when in the IDE + [| for ca in attrs -> + if ca.Constructor.DeclaringType.Name = typeof.Name then + { new CustomAttributeData() with + member __.Constructor = ca.Constructor + member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, f()) |] + member __.NamedArguments = upcast [| |] } + else ca |] + attrsWithDocHack :> IList<_> + + +type ProvidedStaticParameter(isTgt: bool, parameterName:string, parameterType:Type, parameterDefaultValue:obj option, customAttributesData) = + inherit ParameterInfo() + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + new (parameterName:string, parameterType:Type, ?parameterDefaultValue:obj) = + ProvidedStaticParameter(false, parameterName, parameterType, parameterDefaultValue, (K [| |])) + + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + + member __.ParameterDefaultValue = parameterDefaultValue + member __.BelongsToTargetModel = isTgt + + override __.RawDefaultValue = defaultArg parameterDefaultValue null + override __.Attributes = if parameterDefaultValue.IsNone then enum 0 else ParameterAttributes.Optional + override __.Position = 0 + override __.ParameterType = parameterType + override __.Name = parameterName + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + +type ProvidedParameter(isTgt: bool, parameterName:string, attrs, parameterType:Type, optionalValue:obj option, customAttributesData) = + + inherit ParameterInfo() + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + new (parameterName:string, parameterType:Type, ?isOut:bool, ?optionalValue:obj) = + ProvidedParameter(false, parameterName, parameterType, isOut, optionalValue) + + new (_isTgt, parameterName:string, parameterType:Type, isOut:bool option, optionalValue:obj option) = + let isOut = defaultArg isOut false + let attrs = (if isOut then ParameterAttributes.Out else enum 0) ||| + (match optionalValue with None -> enum 0 | Some _ -> ParameterAttributes.Optional ||| ParameterAttributes.HasDefault) + ProvidedParameter(false, parameterName, attrs, parameterType, optionalValue, K [| |]) + + member __.IsParamArray with set(v) = customAttributesImpl.HasParamArray <- v + member __.IsReflectedDefinition with set(v) = customAttributesImpl.HasReflectedDefinition <- v + member __.OptionalValue = optionalValue + member __.HasDefaultParameterValue = Option.isSome optionalValue + member __.BelongsToTargetModel = isTgt + member __.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) + + override __.Name = parameterName + override __.ParameterType = parameterType + override __.Attributes = attrs + override __.RawDefaultValue = defaultArg optionalValue null + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + +and ProvidedConstructor(isTgt: bool, attrs: MethodAttributes, parameters: ProvidedParameter[], invokeCode: (Expr list -> Expr), baseCall, isImplicitCtor, customAttributesData) = + + inherit ConstructorInfo() + let parameterInfos = parameters |> Array.map (fun p -> p :> ParameterInfo) + let mutable baseCall = baseCall + let mutable declaringType : ProvidedTypeDefinition option = None + let mutable isImplicitCtor = isImplicitCtor + let mutable attrs = attrs + let isStatic() = hasFlag attrs MethodAttributes.Static + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + new (parameters, invokeCode) = + ProvidedConstructor(false, MethodAttributes.Public ||| MethodAttributes.RTSpecialName ||| MethodAttributes.HideBySig, Array.ofList parameters, invokeCode, None, false, K [| |]) + + member __.IsTypeInitializer + with get() = isStatic() && hasFlag attrs MethodAttributes.Private + and set(v) = + let typeInitializerAttributes = MethodAttributes.Static ||| MethodAttributes.Private + attrs <- if v then attrs ||| typeInitializerAttributes else attrs &&& ~~~typeInitializerAttributes + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddObsoleteAttribute (message, ?isError) = customAttributesImpl.AddObsolete (message, defaultArg isError false) + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + + member __.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + member this.BaseConstructorCall + with set (d:Expr list -> (ConstructorInfo * Expr list)) = + match baseCall with + | None -> baseCall <- Some d + | Some _ -> failwithf "ProvidedConstructor: base call already given for '%s'" this.Name + + member __.IsImplicitConstructor with get() = isImplicitCtor and set v = isImplicitCtor <- v + member __.BaseCall = baseCall + member __.Parameters = parameters + member __.GetInvokeCode args = invokeCode args + member __.BelongsToTargetModel = isTgt + member __.DeclaringProvidedType = declaringType + member this.IsErased = (nonNone "DeclaringType" this.DeclaringProvidedType).IsErased + + // Implement overloads + override __.GetParameters() = parameterInfos + override __.Attributes = attrs + override __.Name = if isStatic() then ".cctor" else ".ctor" + override __.DeclaringType = declaringType |> nonNone "DeclaringType" :> Type + override __.IsDefined(_attributeType, _inherit) = true + + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + +and ProvidedMethod(isTgt: bool, methodName: string, attrs: MethodAttributes, parameters: ProvidedParameter[], returnType: Type, invokeCode: (Expr list -> Expr) option, staticParams, staticParamsApply, customAttributesData) = + inherit MethodInfo() + let parameterInfos = parameters |> Array.map (fun p -> p :> ParameterInfo) + + let mutable declaringType : ProvidedTypeDefinition option = None + let mutable attrs = attrs + let mutable staticParams = staticParams + let mutable staticParamsApply = staticParamsApply + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + let mutable returnTypeFixCache = None + + /// The public constructor for the design-time/source model + new (methodName, parameters, returnType, ?invokeCode, ?isStatic) = + let isStatic = defaultArg isStatic false + let attrs = if isStatic then MethodAttributes.Public ||| MethodAttributes.Static else MethodAttributes.Public + ProvidedMethod(false, methodName, attrs, Array.ofList parameters, returnType, invokeCode, [], None, K [| |]) + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddObsoleteAttribute (message, ?isError) = customAttributesImpl.AddObsolete (message, defaultArg isError false) + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member __.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) + + member __.SetMethodAttrs attributes = attrs <- attributes + member __.AddMethodAttrs attributes = attrs <- attrs ||| attributes + member __.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + + /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". + member __.DefineStaticParameters(parameters: ProvidedStaticParameter list, instantiationFunction: (string -> obj[] -> ProvidedMethod)) = + staticParams <- parameters + staticParamsApply <- Some instantiationFunction + + /// Get ParameterInfo[] for the parametric type parameters + member __.GetStaticParametersInternal() = [| for p in staticParams -> p :> ParameterInfo |] + + /// Instantiate parametric method + member this.ApplyStaticArguments(mangledName:string, args:obj[]) = + if staticParams.Length <> args.Length then + failwithf "ProvidedMethod: expecting %d static parameters but given %d for method %s" staticParams.Length args.Length methodName + if staticParams.Length > 0 then + match staticParamsApply with + | None -> failwith "ProvidedMethod: DefineStaticParameters was not called" + | Some f -> f mangledName args + else + this + + member __.Parameters = parameters + member __.GetInvokeCode = invokeCode + member __.StaticParams = staticParams + member __.StaticParamsApply = staticParamsApply + member __.BelongsToTargetModel = isTgt + member __.DeclaringProvidedType = declaringType + member this.IsErased = (nonNone "DeclaringType" this.DeclaringProvidedType).IsErased + + // Implement overloads + override __.GetParameters() = parameterInfos + + override this.Attributes = + match invokeCode, this.DeclaringProvidedType with + | None, Some pt when pt.IsInterface || pt.IsAbstract -> + attrs ||| MethodAttributes.Abstract ||| MethodAttributes.Virtual ||| MethodAttributes.HideBySig ||| MethodAttributes.NewSlot + | _ -> attrs + + + override __.Name = methodName + + override __.DeclaringType = declaringType |> nonNone "DeclaringType" :> Type + + override __.IsDefined(_attributeType, _inherit): bool = true + + override __.MemberType = MemberTypes.Method + + override x.CallingConvention = + let cc = CallingConventions.Standard + let cc = if not x.IsStatic then cc ||| CallingConventions.HasThis else cc + cc + + override __.ReturnType = + if isTgt then + match returnTypeFixCache with + | Some returnTypeFix -> returnTypeFix + | None -> + let returnTypeFix = + match returnType.Namespace, returnType.Name with + | "System", "Void"-> + if ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() then + typeof + else + returnType + | _ -> returnType + returnTypeFixCache <- Some returnTypeFix + returnTypeFix + else + returnType + + override __.ReturnParameter = null // REVIEW: Give it a name and type? + + override __.ToString() = "Method " + methodName + + // These don't have to return fully accurate results - they are used + // by the F# Quotations library function SpecificCall as a pre-optimization + // when comparing methods + override __.MetadataToken = genToken() + override __.MethodHandle = RuntimeMethodHandle() + + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" methodName + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" methodName + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" methodName + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" methodName + override this.ReflectedType = notRequired this "ReflectedType" methodName + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + +and ProvidedProperty(isTgt: bool, propertyName: string, attrs: PropertyAttributes, propertyType: Type, isStatic: bool, getter: (unit -> MethodInfo) option, setter: (unit -> MethodInfo) option, indexParameters: ProvidedParameter[], customAttributesData) = + inherit PropertyInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + /// The public constructor for the design-time/source model + new (propertyName, propertyType, ?getterCode, ?setterCode, ?isStatic, ?indexParameters) = + let isStatic = defaultArg isStatic false + let indexParameters = defaultArg indexParameters [] + let pattrs = (if isStatic then MethodAttributes.Static else enum(0)) ||| MethodAttributes.Public ||| MethodAttributes.SpecialName + let getter = getterCode |> Option.map (fun _ -> ProvidedMethod(false, "get_" + propertyName, pattrs, Array.ofList indexParameters, propertyType, getterCode, [], None, K [| |]) :> MethodInfo) + let setter = setterCode |> Option.map (fun _ -> ProvidedMethod(false, "set_" + propertyName, pattrs, [| yield! indexParameters; yield ProvidedParameter(false, "value", propertyType, isOut=Some false, optionalValue=None) |], typeof, setterCode, [], None, K [| |]) :> MethodInfo) + ProvidedProperty(false, propertyName, PropertyAttributes.None, propertyType, isStatic, Option.map K getter, Option.map K setter, Array.ofList indexParameters, K [| |]) + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddObsoleteAttribute (message, ?isError) = customAttributesImpl.AddObsolete (message, defaultArg isError false) + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + member __.PatchDeclaringType x = + if not isTgt then + match getter with Some f -> (match f() with (:? ProvidedMethod as g) -> g.PatchDeclaringType x | _ -> ()) | _ -> () + match setter with Some f -> (match f() with (:? ProvidedMethod as s) -> s.PatchDeclaringType x | _ -> ()) | _ -> () + patchOption declaringType (fun () -> declaringType <- Some x) + + member __.IsStatic = isStatic + member __.IndexParameters = indexParameters + member __.BelongsToTargetModel = isTgt + member __.Getter = getter + member __.Setter = setter + + override __.PropertyType = propertyType + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" propertyName + override this.GetAccessors _nonPublic = notRequired this "nonPublic" propertyName + override __.GetGetMethod _nonPublic = match getter with None -> null | Some g -> g() + override __.GetSetMethod _nonPublic = match setter with None -> null | Some s -> s() + override __.GetIndexParameters() = [| for p in indexParameters -> upcast p |] + override __.Attributes = attrs + override __.CanRead = getter.IsSome + override __.CanWrite = setter.IsSome + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture): obj = notRequired this "GetValue" propertyName + override __.Name = propertyName + override __.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override __.MemberType: MemberTypes = MemberTypes.Property + + override this.ReflectedType = notRequired this "ReflectedType" propertyName + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" propertyName + +and ProvidedEvent(isTgt: bool, eventName:string, attrs: EventAttributes, eventHandlerType:Type, isStatic: bool, adder: (unit -> MethodInfo), remover: (unit -> MethodInfo), customAttributesData) = + inherit EventInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + new (eventName, eventHandlerType, adderCode, removerCode, ?isStatic) = + let isStatic = defaultArg isStatic false + let pattrs = (if isStatic then MethodAttributes.Static else enum(0)) ||| MethodAttributes.Public ||| MethodAttributes.SpecialName + let adder = ProvidedMethod(false, "add_" + eventName, pattrs, [| ProvidedParameter(false, "handler", eventHandlerType, isOut=Some false, optionalValue=None) |], typeof, Some adderCode, [], None, K [| |]) :> MethodInfo + let remover = ProvidedMethod(false, "remove_" + eventName, pattrs, [| ProvidedParameter(false, "handler", eventHandlerType, isOut=Some false, optionalValue=None) |], typeof, Some removerCode, [], None, K [| |]) :> MethodInfo + ProvidedEvent(false, eventName, EventAttributes.None, eventHandlerType, isStatic, K adder, K remover, K [| |]) + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + + member __.PatchDeclaringType x = + if not isTgt then + match adder() with :? ProvidedMethod as a -> a.PatchDeclaringType x | _ -> () + match remover() with :? ProvidedMethod as r -> r.PatchDeclaringType x | _ -> () + patchOption declaringType (fun () -> declaringType <- Some x) + + member __.IsStatic = isStatic + member __.Adder = adder() + member __.Remover = remover() + member __.BelongsToTargetModel = isTgt + + override __.EventHandlerType = eventHandlerType + override __.GetAddMethod _nonPublic = adder() + override __.GetRemoveMethod _nonPublic = remover() + override __.Attributes = attrs + override __.Name = eventName + override __.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override __.MemberType: MemberTypes = MemberTypes.Event + + override this.GetRaiseMethod _nonPublic = notRequired this "GetRaiseMethod" eventName + override this.ReflectedType = notRequired this "ReflectedType" eventName + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" eventName + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + +and ProvidedField(isTgt: bool, fieldName:string, attrs, fieldType:Type, rawConstantValue: obj, customAttributesData) = + inherit FieldInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + let mutable attrs = attrs + + new (fieldName:string, fieldType:Type) = ProvidedField(false, fieldName, FieldAttributes.Private, fieldType, null, (K [| |])) + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddObsoleteAttribute (message, ?isError) = customAttributesImpl.AddObsolete (message, defaultArg isError false) + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member __.SetFieldAttributes attributes = attrs <- attributes + member __.BelongsToTargetModel = isTgt + + member __.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + + member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + // Implement overloads + override __.FieldType = fieldType + override __.GetRawConstantValue() = rawConstantValue + override __.Attributes = attrs + override __.Name = fieldName + override __.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override __.MemberType: MemberTypes = MemberTypes.Field + + override this.ReflectedType = notRequired this "ReflectedType" fieldName + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" fieldName + + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" fieldName + override this.GetValue(_obj): obj = notRequired this "GetValue" fieldName + override this.FieldHandle = notRequired this "FieldHandle" fieldName + + static member Literal(fieldName:string, fieldType:Type, literalValue: obj) = + ProvidedField(false, fieldName, (FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public), fieldType, literalValue, K [| |]) + + +and ProvidedMeasureBuilder() = + + // TODO: this shouldn't be hardcoded, but without creating a dependency on FSharp.Compiler.Service + // there seems to be no way to check if a type abbreviation exists + static let unitNamesTypeAbbreviations = + [ + "meter"; "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb"; + "volt"; "farad"; "ohm"; "siemens"; "weber"; "tesla"; "henry" + "lumen"; "lux"; "becquerel"; "gray"; "sievert"; "katal" + ] + |> Set.ofList + + static let unitSymbolsTypeAbbreviations = + [ + "m"; "kg"; "s"; "A"; "K"; "mol"; "cd"; "Hz"; "N"; "Pa"; "J"; "W"; "C" + "V"; "F"; "S"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H" + ] + |> Set.ofList + + static member One = typeof + static member Product (measure1, measure2) = typedefof>.MakeGenericType [| measure1;measure2 |] + static member Inverse denominator = typedefof>.MakeGenericType [| denominator |] + static member Ratio (numerator, denominator) = ProvidedMeasureBuilder.Product(numerator, ProvidedMeasureBuilder.Inverse denominator) + static member Square measure = ProvidedMeasureBuilder.Product(measure, measure) + + // If the unit is not a valid type, instead + // of assuming it's a type abbreviation, which may not be the case and cause a + // problem later on, check the list of valid abbreviations + static member SI (unitName:string) = + let mLowerCase = unitName.ToLowerInvariant() + let abbreviation = + if unitNamesTypeAbbreviations.Contains mLowerCase then + Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames", mLowerCase) + elif unitSymbolsTypeAbbreviations.Contains unitName then + Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols", unitName) + else + None match abbreviation with | Some (ns, unitName) -> - ProvidedSymbolType - (SymbolKind.FSharpTypeAbbreviation - (typeof.Assembly, - ns, - [| unitName |]), - []) :> Type + ProvidedTypeSymbol(ProvidedTypeSymbolKind.FSharpTypeAbbreviation(typeof.Assembly, ns, [| unitName |]), [], defaultTypeBuilder) :> Type | None -> typedefof>.Assembly.GetType("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames." + mLowerCase) - member __.AnnotateType (basicType, annotation) = ProvidedSymbolType(Generic basicType, annotation) :> Type + static member AnnotateType (basic, argument) = ProvidedTypeSymbol(Generic basic, argument, defaultTypeBuilder) :> Type +and + [] + TypeContainer = + | Namespace of (unit -> Assembly) * string // namespace + | Type of ProvidedTypeDefinition + | TypeToBeDecided +/// backingDataSource is a set of functions to fetch backing data for the ProvidedTypeDefinition, +/// and allows us to reuse this type for both target and source models, even when the +/// source model is being incrementally updates by further .AddMember calls +and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: string, getBaseType: (unit -> Type option), attrs: TypeAttributes, getEnumUnderlyingType, staticParams, staticParamsApply, backingDataSource, customAttributesData, nonNullable, hideObjectMethods, typeBuilder: ITypeBuilder) as this = + inherit TypeDelegator() + + do match container, !ProvidedTypeDefinition.Logger with + | TypeContainer.Namespace _, Some logger when not isTgt -> logger (sprintf "Creating ProvidedTypeDefinition %s [%d]" className (System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode this)) + | _ -> () + + static let defaultAttributes (isErased, isSealed, isInterface, isAbstract) = + TypeAttributes.Public ||| + (if isInterface then TypeAttributes.Interface ||| TypeAttributes.Abstract + elif isAbstract then TypeAttributes.Abstract + else TypeAttributes.Class) ||| + (if isSealed && not isInterface && not isAbstract then TypeAttributes.Sealed else enum 0) ||| + enum (if isErased then int32 TypeProviderTypeAttributes.IsErased else 0) + + // state + let mutable attrs = attrs + let mutable enumUnderlyingType = lazy getEnumUnderlyingType() + let mutable baseType = lazy getBaseType() + + /// Represents the evaluated members so far + let members = ResizeArray() + + /// Represents delayed members, as yet uncomputed + let membersQueue = ResizeArray<(unit -> MemberInfo[])>() + + let mutable staticParamsDefined = false + let mutable staticParams = staticParams + let mutable staticParamsApply = staticParamsApply + let mutable container = container + let interfaceImpls = ResizeArray() + let interfacesQueue = ResizeArray Type[]>() + let methodOverrides = ResizeArray() + let methodOverridesQueue = ResizeArray (ProvidedMethod * MethodInfo)[]>() + + do match backingDataSource with + | None -> () + | Some (_, getFreshMembers, getFreshInterfaces, getFreshMethodOverrides) -> + membersQueue.Add getFreshMembers + interfacesQueue.Add getFreshInterfaces + methodOverridesQueue.Add getFreshMethodOverrides + + let checkFreshMembers() = + match backingDataSource with + | None -> false + | Some (checkFreshMembers, _getFreshMembers, _getFreshInterfaces, _getFreshMethodOverrides) -> checkFreshMembers() + + let moreMembers() = + membersQueue.Count > 0 || checkFreshMembers() + + let evalMembers() = + if moreMembers() then + // re-add the getFreshMembers call from the backingDataSource to make sure we fetch the latest translated members from the source model + match backingDataSource with + | None -> () + | Some (_, getFreshMembers, _getFreshInterfaces, _getFreshMethodOverrides) -> + membersQueue.Add getFreshMembers + + let elems = membersQueue |> Seq.toArray // take a copy in case more elements get added + membersQueue.Clear() + for f in elems do + for m in f() do + members.Add m + + // Implicitly add the property and event methods (only for the source model where they are not explicitly declared) + match m with + | :? ProvidedProperty as p -> + if not p.BelongsToTargetModel then + if p.CanRead then members.Add (p.GetGetMethod true) + if p.CanWrite then members.Add (p.GetSetMethod true) + | :? ProvidedEvent as e -> + if not e.BelongsToTargetModel then + members.Add (e.GetAddMethod true) + members.Add (e.GetRemoveMethod true) + | _ -> () + + let getMembers() = + evalMembers() + members.ToArray() + + // Save some common lookups for provided types with lots of members + let mutable bindings : Dictionary = null + + let save (key: BindingFlags) f : 'T = + let key = int key + + if bindings = null then + bindings <- Dictionary<_, _>(HashIdentity.Structural) + + if not (moreMembers()) && bindings.ContainsKey(key) then + bindings.[key] :?> 'T + else + let res = f () // this will refresh the members + bindings.[key] <- box res + res + + let evalInterfaces() = + if interfacesQueue.Count > 0 then + let elems = interfacesQueue |> Seq.toArray // take a copy in case more elements get added + interfacesQueue.Clear() + for f in elems do + for i in f() do + interfaceImpls.Add i + match backingDataSource with + | None -> () + | Some (_, _getFreshMembers, getInterfaces, _getFreshMethodOverrides) -> + interfacesQueue.Add getInterfaces + + let getInterfaces() = + evalInterfaces() + interfaceImpls.ToArray() + + let evalMethodOverrides () = + if methodOverridesQueue.Count > 0 then + let elems = methodOverridesQueue |> Seq.toArray // take a copy in case more elements get added + methodOverridesQueue.Clear() + for f in elems do + for i in f() do + methodOverrides.Add i + match backingDataSource with + | None -> () + | Some (_, _getFreshMembers, _getFreshInterfaces, getFreshMethodOverrides) -> + methodOverridesQueue.Add getFreshMethodOverrides + + let getFreshMethodOverrides () = + evalMethodOverrides () + methodOverrides.ToArray() + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + do if nonNullable then customAttributesImpl.NonNullable <- true + do if hideObjectMethods then customAttributesImpl.HideObjectMethods <- true + do this.typeImpl <- this + + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + new (assembly:Assembly, namespaceName, className, baseType, ?hideObjectMethods, ?nonNullable, ?isErased, ?isSealed, ?isInterface, ?isAbstract) = + let isErased = defaultArg isErased true + let isSealed = defaultArg isSealed true + let isInterface = defaultArg isInterface false + let isAbstract = defaultArg isAbstract false + let nonNullable = defaultArg nonNullable false + let hideObjectMethods = defaultArg hideObjectMethods false + let attrs = defaultAttributes (isErased, isSealed, isInterface, isAbstract) + //if not isErased && assembly.GetType().Name <> "ProvidedAssembly" then failwithf "a non-erased (i.e. generative) ProvidedTypeDefinition '%s.%s' was placed in an assembly '%s' that is not a ProvidedAssembly" namespaceName className (assembly.GetName().Name) + ProvidedTypeDefinition(false, TypeContainer.Namespace (K assembly, namespaceName), className, K baseType, attrs, K None, [], None, None, K [| |], nonNullable, hideObjectMethods, defaultTypeBuilder) + + new (className:string, baseType, ?hideObjectMethods, ?nonNullable, ?isErased, ?isSealed, ?isInterface, ?isAbstract) = + let isErased = defaultArg isErased true + let isSealed = defaultArg isSealed true + let isInterface = defaultArg isInterface false + let isAbstract = defaultArg isAbstract false + let nonNullable = defaultArg nonNullable false + let hideObjectMethods = defaultArg hideObjectMethods false + let attrs = defaultAttributes (isErased, isSealed, isInterface, isAbstract) + ProvidedTypeDefinition(false, TypeContainer.TypeToBeDecided, className, K baseType, attrs, K None, [], None, None, K [| |], nonNullable, hideObjectMethods, defaultTypeBuilder) + + // state ops + + override __.UnderlyingSystemType = typeof + + // Implement overloads + override __.Assembly = + match container with + | TypeContainer.Namespace (theAssembly, _) -> theAssembly() + | TypeContainer.Type t -> t.Assembly + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not yet added as a member to a declaring type, stacktrace = %s" className Environment.StackTrace + + override __.FullName = + match container with + | TypeContainer.Type declaringType -> declaringType.FullName + "+" + className + | TypeContainer.Namespace (_, namespaceName) -> + if namespaceName="" then failwith "use null for global namespace" + match namespaceName with + | null -> className + | _ -> namespaceName + "." + className + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override __.Namespace = + match container with + | TypeContainer.Namespace (_, nsp) -> nsp + | TypeContainer.Type t -> t.Namespace + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override __.BaseType = match baseType.Value with Some ty -> ty | None -> null + + override __.GetConstructors bindingFlags = + (//save ("ctor", bindingFlags, None) (fun () -> + getMembers() + |> Array.choose (function :? ConstructorInfo as c when memberBinds false bindingFlags c.IsStatic c.IsPublic -> Some c | _ -> None)) + + override this.GetMethods bindingFlags = + (//save ("methods", bindingFlags, None) (fun () -> + getMembers() + |> Array.choose (function :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags))))) + + override this.GetFields bindingFlags = + (//save ("fields", bindingFlags, None) (fun () -> + getMembers() + |> Array.choose (function :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags))))) + + override this.GetProperties bindingFlags = + (//save ("props", bindingFlags, None) (fun () -> + let staticOrPublic = + getMembers() + |> Array.choose (function :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + staticOrPublic + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null + then id + else (fun mems -> Array.append mems (this.ErasedBaseType.GetProperties(bindingFlags))))) + + override this.GetEvents bindingFlags = + (//save ("events", bindingFlags, None) (fun () -> + getMembers() + |> Array.choose (function :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags))))) + + override __.GetNestedTypes bindingFlags = + (//save ("nested", bindingFlags, None) (fun () -> + getMembers() + |> Array.choose (function :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> Some m | _ -> None) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags))))) + + override this.GetConstructorImpl(bindingFlags, _binder, _callConventions, _types, _modifiers) = + let xs = this.GetConstructors bindingFlags |> Array.filter (fun m -> m.Name = ".ctor") + if xs.Length > 1 then failwith "GetConstructorImpl. not support overloads" + if xs.Length > 0 then xs.[0] else null + + override __.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, _types, _modifiers): MethodInfo = + (//save ("methimpl", bindingFlags, Some name) (fun () -> + // This is performance critical for large spaces of provided methods and properties + // Save a table of the methods grouped by name + let table = + save (bindingFlags ||| BindingFlags.InvokeMethod) (fun () -> + let methods = this.GetMethods bindingFlags + methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict) + + let xs = if table.ContainsKey name then table.[name] else [| |] + //let xs = this.GetMethods bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 1 then failwithf "GetMethodImpl. not support overloads, name = '%s', methods - '%A', callstack = '%A'" name xs Environment.StackTrace + if xs.Length > 0 then xs.[0] else null) + + override this.GetField(name, bindingFlags) = + (//save ("field1", bindingFlags, Some name) (fun () -> + let xs = this.GetFields bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null) + + override __.GetPropertyImpl(name, bindingFlags, _binder, _returnType, _types, _modifiers) = + (//save ("prop1", bindingFlags, Some name) (fun () -> + let table = + save (bindingFlags ||| BindingFlags.GetProperty) (fun () -> + let methods = this.GetProperties bindingFlags + methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict) + let xs = if table.ContainsKey name then table.[name] else [| |] + //let xs = this.GetProperties bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null) + + override __.GetEvent(name, bindingFlags) = + (//save ("event1", bindingFlags, Some name) (fun () -> + let xs = this.GetEvents bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null) + + override __.GetNestedType(name, bindingFlags) = + (//save ("nested1", bindingFlags, Some name) (fun () -> + let xs = this.GetNestedTypes bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null) + + override __.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.Name + + override __.GetInterfaces() = getInterfaces() + + + override __.MakeArrayType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.SDArray, [this], typeBuilder) :> Type + + override __.MakeArrayType arg = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Array arg, [this], typeBuilder) :> Type + + override __.MakePointerType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Pointer, [this], typeBuilder) :> Type + + override __.MakeByRefType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.ByRef, [this], typeBuilder) :> Type + + // The binding attributes are always set to DeclaredOnly ||| Static ||| Instance ||| Public when GetMembers is called directly by the F# compiler + // However, it's possible for the framework to generate other sets of flags in some corner cases (e.g. via use of `enum` with a provided type as the target) + override __.GetMembers bindingFlags = + [| for m in getMembers() do + match m with + | :? ConstructorInfo as c when memberBinds false bindingFlags c.IsStatic c.IsPublic -> yield (c :> MemberInfo) + | :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> yield (m :> _) + | _ -> () |] + + override this.GetMember(name, mt, _bindingFlags) = + let mt = if hasFlag mt MemberTypes.NestedType then mt ||| MemberTypes.TypeInfo else mt + this.GetMembers() |> Array.filter (fun m -> 0 <> int(m.MemberType &&& mt) && m.Name = name) + + // Attributes, etc.. + override __.GetAttributeFlagsImpl() = adjustTypeAttributes this.IsNested attrs + + override this.IsValueTypeImpl() = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.FullName = "System.ValueType" || bt.IsValueType + + override __.IsEnum = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.IsEnum + + override __.GetEnumUnderlyingType() = + if this.IsEnum then + match enumUnderlyingType.Force() with + | None -> typeof + | Some ty -> ty + else failwithf "not enum type" + + override __.IsArrayImpl() = false + override __.IsByRefImpl() = false + override __.IsPointerImpl() = false + override __.IsPrimitiveImpl() = false + override __.IsCOMObjectImpl() = false + override __.HasElementTypeImpl() = false + override __.Name = className + + override __.DeclaringType = + match container with + | TypeContainer.Namespace _ -> null + | TypeContainer.Type enclosingTyp -> (enclosingTyp :> Type) + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override __.MemberType = if this.IsNested then MemberTypes.NestedType else MemberTypes.TypeInfo + +#if NETCOREAPP + // See bug https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues/236 + override __.IsSZArray = false +#endif + + override x.GetHashCode() = x.Namespace.GetHashCode() ^^^ className.GetHashCode() + override this.Equals(that: obj) = Object.ReferenceEquals(this, that) + override this.Equals(that: Type) = Object.ReferenceEquals(this, that) + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + override __.GetGenericArguments() = [||] + + override __.ToString() = this.Name + + override x.Module = x.Assembly.ManifestModule + + override __.GUID = Guid.Empty + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override __.IsDefined(_attributeType: Type, _inherit) = false + + override __.GetElementType() = notRequired this "Module" this.Name + override __.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "Module" this.Name + override __.AssemblyQualifiedName = notRequired this "Module" this.Name + // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + // Get the model + member __.BelongsToTargetModel = isTgt + member __.AttributesRaw = attrs + member __.EnumUnderlyingTypeRaw() = enumUnderlyingType.Force() + member __.Container = container + member __.BaseTypeRaw() = baseType.Force() + member __.StaticParams = staticParams + member __.StaticParamsApply = staticParamsApply + + // Count the members declared since the indicated position in the members list. This allows the target model to observe + // incremental additions made to the source model + member __.CountMembersFromCursor(idx: int) = evalMembers(); members.Count - idx + + // Fetch the members declared since the indicated position in the members list. This allows the target model to observe + // incremental additions made to the source model + member __.GetMembersFromCursor(idx: int) = evalMembers(); members.GetRange(idx, members.Count - idx).ToArray(), members.Count + + // Fetch the interfaces declared since the indicated position in the interfaces list + member __.GetInterfaceImplsFromCursor(idx: int) = evalInterfaces(); interfaceImpls.GetRange(idx, interfaceImpls.Count - idx).ToArray(), interfaceImpls.Count + + // Fetch the method overrides declared since the indicated position in the list + member __.GetMethodOverridesFromCursor(idx: int) = evalMethodOverrides(); methodOverrides.GetRange(idx, methodOverrides.Count - idx).ToArray(), methodOverrides.Count + + // Fetch the method overrides + member __.GetMethodOverrides() = getFreshMethodOverrides() + + member this.ErasedBaseType : Type = ProvidedTypeDefinition.EraseType(this.BaseType) + + member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member __.AddObsoleteAttribute (message, ?isError) = customAttributesImpl.AddObsolete (message, defaultArg isError false) + member __.AddDefinitionLocation(line, column, filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member __.HideObjectMethods with get() = customAttributesImpl.HideObjectMethods and set v = customAttributesImpl.HideObjectMethods <- v + member __.NonNullable with get() = customAttributesImpl.NonNullable and set v = customAttributesImpl.NonNullable <- v + member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute + + member __.SetEnumUnderlyingType(ty) = enumUnderlyingType <- lazy Some ty + member __.SetBaseType t = + if baseType.IsValueCreated then failwithf "The base type has already been evaluated for this type. Please call SetBaseType before any operations which traverse the type hierarchy. stacktrace = %A" Environment.StackTrace + baseType <- lazy Some t + member __.SetBaseTypeDelayed baseTypeFunction = + if baseType.IsValueCreated then failwithf "The base type has already been evaluated for this type. Please call SetBaseType before any operations which traverse the type hierarchy. stacktrace = %A" Environment.StackTrace + baseType <- lazy (Some (baseTypeFunction())) + member __.AddAttributes x = attrs <- attrs ||| x + member __.SetAttributes x = attrs <- x + + member this.AddMembers(memberInfos:list<#MemberInfo>) = + memberInfos |> List.iter this.PatchDeclaringTypeOfMember + membersQueue.Add (fun () -> memberInfos |> List.toArray |> Array.map (fun x -> x :> MemberInfo )) + + member __.AddMember(memberInfo:MemberInfo) = + this.AddMembers [memberInfo] + + member __.AddMembersDelayed(membersFunction: unit -> list<#MemberInfo>) = + membersQueue.Add (fun () -> membersFunction() |> List.toArray |> Array.map (fun x -> this.PatchDeclaringTypeOfMember x; x :> MemberInfo )) + + member __.AddMemberDelayed(memberFunction: unit -> #MemberInfo) = + this.AddMembersDelayed(fun () -> [memberFunction()]) + + member __.AddAssemblyTypesAsNestedTypesDelayed (assemblyFunction: unit -> Assembly) = + let bucketByPath nodef tipf (items: (string list * 'Value) list) = + // Find all the items with an empty key list and call 'tipf' + let tips = + [ for (keylist, v) in items do + match keylist with + | [] -> yield tipf v + | _ -> () ] + + // Find all the items with a non-empty key list. Bucket them together by + // the first key. For each bucket, call 'nodef' on that head key and the bucket. + let nodes = + let buckets = new Dictionary<_, _>(10) + for (keylist, v) in items do + match keylist with + | [] -> () + | key::rest -> + buckets.[key] <- (rest, v) :: (if buckets.ContainsKey key then buckets.[key] else []); + + [ for (KeyValue(key, items)) in buckets -> nodef key items ] + + tips @ nodes + this.AddMembersDelayed (fun _ -> + let topTypes = [ for ty in assemblyFunction().GetTypes() do + if not ty.IsNested then + let namespaceParts = match ty.Namespace with null -> [] | s -> s.Split '.' |> Array.toList + yield namespaceParts, ty ] + let rec loop types = + types + |> bucketByPath + (fun namespaceComponent typesUnderNamespaceComponent -> + let t = ProvidedTypeDefinition(namespaceComponent, baseType = Some typeof) + t.AddMembers (loop typesUnderNamespaceComponent) + (t :> Type)) + id + loop topTypes) + + /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". + member __.DefineStaticParameters(parameters: ProvidedStaticParameter list, instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition)) = + if staticParamsDefined then failwithf "Static parameters have already been defined for this type. stacktrace = %A" Environment.StackTrace + staticParamsDefined <- true + staticParams <- parameters + staticParamsApply <- Some instantiationFunction + + /// Get ParameterInfo[] for the parametric type parameters + member __.GetStaticParametersInternal() = [| for p in staticParams -> p :> ParameterInfo |] + + /// Instantiate parametric type + member this.ApplyStaticArguments(name:string, args:obj[]) = + if staticParams.Length <> args.Length then + failwithf "ProvidedTypeDefinition: expecting %d static parameters but given %d for type %s" staticParams.Length args.Length this.FullName + if staticParams.Length > 0 then + match staticParamsApply with + | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" + | Some f -> f name args + else + this + + member __.PatchDeclaringType x = container <- TypeContainer.Type x + + member __.IsErased + with get() = (attrs &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 + and set v = + if v then attrs <- attrs ||| enum (int32 TypeProviderTypeAttributes.IsErased) + else attrs <- attrs &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) + + member __.SuppressRelocation + with get() = (attrs &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 + and set v = + if v then attrs <- attrs ||| enum (int32 TypeProviderTypeAttributes.SuppressRelocate) + else attrs <- attrs &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) + + member __.AddInterfaceImplementation interfaceType = interfaceImpls.Add interfaceType + + member __.AddInterfaceImplementationsDelayed interfacesFunction = interfacesQueue.Add (interfacesFunction >> Array.ofList) + + member __.SetAssemblyInternal (assembly: unit -> Assembly) = + match container with + | TypeContainer.Namespace (_, ns) -> container <- TypeContainer.Namespace (assembly, ns) + | TypeContainer.Type _ -> failwithf "can't set assembly of nested type '%s'" className + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + member __.DefineMethodOverride (methodInfoBody, methodInfoDeclaration) = methodOverrides.Add (methodInfoBody, methodInfoDeclaration) + member __.DefineMethodOverridesDelayed f = methodOverridesQueue.Add (f >> Array.ofList) + + // This method is used by Debug.fs and QuotationBuilder.fs. + // Emulate the F# type provider type erasure mechanism to get the + // actual (erased) type. We erase ProvidedTypes to their base type + // and we erase array of provided type to array of base type. In the + // case of generics all the generic type arguments are also recursively + // replaced with the erased-to types + static member EraseType(typ:Type): Type = + match typ with + | :? ProvidedTypeDefinition as ptd when ptd.IsErased -> ProvidedTypeDefinition.EraseType typ.BaseType + | t when t.IsArray -> + let rank = t.GetArrayRank() + let et = ProvidedTypeDefinition.EraseType (t.GetElementType()) + if rank = 0 then et.MakeArrayType() else et.MakeArrayType(rank) + | :? ProvidedTypeSymbol as sym when sym.IsFSharpUnitAnnotated -> + typ.UnderlyingSystemType + | t when t.IsGenericType && not t.IsGenericTypeDefinition -> + let genericTypeDefinition = t.GetGenericTypeDefinition() + let genericArguments = t.GetGenericArguments() |> Array.map ProvidedTypeDefinition.EraseType + genericTypeDefinition.MakeGenericType(genericArguments) + | t -> t + + + member this.PatchDeclaringTypeOfMember (m:MemberInfo) = + match m with + | :? ProvidedConstructor as c -> c.PatchDeclaringType this + | :? ProvidedMethod as m -> m.PatchDeclaringType this + | :? ProvidedProperty as p -> p.PatchDeclaringType this + | :? ProvidedEvent as e -> e.PatchDeclaringType this + | :? ProvidedTypeDefinition as t -> t.PatchDeclaringType this + | :? ProvidedField as l -> l.PatchDeclaringType this + | _ -> () + + static member Logger: (string -> unit) option ref = ref None + + +//==================================================================================================== +// AssemblyReader for ProvidedTypesContext +// +// A lightweight .NET assembly reader that fits in a single F# file. Based on the well-tested Abstract IL +// binary reader code. Used by the type provider to read referenced asssemblies. + +module internal AssemblyReader = + + open System + open System.Collections.Generic + open System.Collections.Concurrent + open System.Collections.ObjectModel + open System.IO + open System.Reflection + open System.Text + //open ProviderImplementation.ProvidedTypes + + [] + module Utils = + + let singleOfBits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x), 0) + let doubleOfBits (x:int64) = System.BitConverter.Int64BitsToDouble(x) + + //--------------------------------------------------------------------- + // SHA1 hash-signing algorithm. Used to get the public key token from + // the public key. + //--------------------------------------------------------------------- + + // Little-endian encoding of int32 + let b0 n = byte (n &&& 0xFF) + let b1 n = byte ((n >>> 8) &&& 0xFF) + let b2 n = byte ((n >>> 16) &&& 0xFF) + let b3 n = byte ((n >>> 24) &&& 0xFF) + + // Little-endian encoding of int64 + let dw7 n = byte ((n >>> 56) &&& 0xFFL) + let dw6 n = byte ((n >>> 48) &&& 0xFFL) + let dw5 n = byte ((n >>> 40) &&& 0xFFL) + let dw4 n = byte ((n >>> 32) &&& 0xFFL) + let dw3 n = byte ((n >>> 24) &&& 0xFFL) + let dw2 n = byte ((n >>> 16) &&& 0xFFL) + let dw1 n = byte ((n >>> 8) &&& 0xFFL) + let dw0 n = byte (n &&& 0xFFL) + + + module SHA1 = + let inline (>>>&) (x:int) (y:int) = int32 (uint32 x >>> y) + let f(t, b, c, d) = + if t < 20 then (b &&& c) ||| ((~~~b) &&& d) + elif t < 40 then b ^^^ c ^^^ d + elif t < 60 then (b &&& c) ||| (b &&& d) ||| (c &&& d) + else b ^^^ c ^^^ d + + let [] k0to19 = 0x5A827999 + let [] k20to39 = 0x6ED9EBA1 + let [] k40to59 = 0x8F1BBCDC + let [] k60to79 = 0xCA62C1D6 + + let k t = + if t < 20 then k0to19 + elif t < 40 then k20to39 + elif t < 60 then k40to59 + else k60to79 + + type SHAStream = + { stream: byte[]; + mutable pos: int; + mutable eof: bool; } + + let rotLeft32 x n = (x <<< n) ||| (x >>>& (32-n)) + + // padding and length (in bits!) recorded at end + let shaAfterEof sha = + let n = sha.pos + let len = sha.stream.Length + if n = len then 0x80 + else + let paddedLen = (((len + 9 + 63) / 64) * 64) - 8 + if n < paddedLen - 8 then 0x0 + elif (n &&& 63) = 56 then int32 ((int64 len * int64 8) >>> 56) &&& 0xff + elif (n &&& 63) = 57 then int32 ((int64 len * int64 8) >>> 48) &&& 0xff + elif (n &&& 63) = 58 then int32 ((int64 len * int64 8) >>> 40) &&& 0xff + elif (n &&& 63) = 59 then int32 ((int64 len * int64 8) >>> 32) &&& 0xff + elif (n &&& 63) = 60 then int32 ((int64 len * int64 8) >>> 24) &&& 0xff + elif (n &&& 63) = 61 then int32 ((int64 len * int64 8) >>> 16) &&& 0xff + elif (n &&& 63) = 62 then int32 ((int64 len * int64 8) >>> 8) &&& 0xff + elif (n &&& 63) = 63 then (sha.eof <- true; int32 (int64 len * int64 8) &&& 0xff) + else 0x0 + + let shaRead8 sha = + let s = sha.stream + let b = if sha.pos >= s.Length then shaAfterEof sha else int32 s.[sha.pos] + sha.pos <- sha.pos + 1 + b + + let shaRead32 sha = + let b0 = shaRead8 sha + let b1 = shaRead8 sha + let b2 = shaRead8 sha + let b3 = shaRead8 sha + let res = (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3 + res + + let sha1Hash sha = + let mutable h0 = 0x67452301 + let mutable h1 = 0xEFCDAB89 + let mutable h2 = 0x98BADCFE + let mutable h3 = 0x10325476 + let mutable h4 = 0xC3D2E1F0 + let mutable a = 0 + let mutable b = 0 + let mutable c = 0 + let mutable d = 0 + let mutable e = 0 + let w = Array.create 80 0x00 + while (not sha.eof) do + for i = 0 to 15 do + w.[i] <- shaRead32 sha + for t = 16 to 79 do + w.[t] <- rotLeft32 (w.[t-3] ^^^ w.[t-8] ^^^ w.[t-14] ^^^ w.[t-16]) 1 + a <- h0 + b <- h1 + c <- h2 + d <- h3 + e <- h4 + for t = 0 to 79 do + let temp = (rotLeft32 a 5) + f(t, b, c, d) + e + w.[t] + k(t) + e <- d + d <- c + c <- rotLeft32 b 30 + b <- a + a <- temp + h0 <- h0 + a + h1 <- h1 + b + h2 <- h2 + c + h3 <- h3 + d + h4 <- h4 + e + h0, h1, h2, h3, h4 + + let sha1HashBytes s = + let (_h0, _h1, _h2, h3, h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 + Array.map byte [| b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |] + + + let sha1HashBytes s = SHA1.sha1HashBytes s + + + [] + type PublicKey = + | PublicKey of byte[] + | PublicKeyToken of byte[] + member x.IsKey=match x with PublicKey _ -> true | _ -> false + member x.IsKeyToken=match x with PublicKeyToken _ -> true | _ -> false + member x.Key=match x with PublicKey b -> b | _ -> failwithf "not a key" + member x.KeyToken=match x with PublicKeyToken b -> b | _ -> failwithf"not a key token" + + member x.ToToken() = + match x with + | PublicKey bytes -> SHA1.sha1HashBytes bytes + | PublicKeyToken token -> token + static member KeyAsToken(k) = PublicKeyToken(PublicKey(k).ToToken()) + + [] + type ILAssemblyRef(name: string, hash: byte[] uoption, publicKey: PublicKey uoption, retargetable: bool, version: Version uoption, locale: string uoption) = + member __.Name=name + member __.Hash=hash + member __.PublicKey=publicKey + member __.Retargetable=retargetable + member __.Version=version + member __.Locale=locale + + member x.ToAssemblyName() = + let asmName = AssemblyName(Name=x.Name) + match x.PublicKey with + | USome bytes -> asmName.SetPublicKeyToken(bytes.ToToken()) + | UNone -> () + match x.Version with + | USome v -> asmName.Version <- v + | UNone -> () + asmName.CultureName <- System.Globalization.CultureInfo.InvariantCulture.Name + asmName + + static member FromAssemblyName (aname:AssemblyName) = + let locale = UNone + let publicKey = + match aname.GetPublicKey() with + | null | [| |] -> + match aname.GetPublicKeyToken() with + | null | [| |] -> UNone + | bytes -> USome (PublicKeyToken bytes) + | bytes -> + USome (PublicKey.KeyAsToken(bytes)) + + let version = + match aname.Version with + | null -> UNone + | v -> USome (Version(v.Major, v.Minor, v.Build, v.Revision)) + + let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable + + ILAssemblyRef(aname.Name, UNone, publicKey, retargetable, version, locale) + + member aref.QualifiedName = + let b = new StringBuilder(100) + let add (s:string) = (b.Append(s) |> ignore) + let addC (s:char) = (b.Append(s) |> ignore) + add(aref.Name); + match aref.Version with + | UNone -> () + | USome v -> + add ", Version="; + add (string v.Major) + add "."; + add (string v.Minor) + add "."; + add (string v.Build) + add "."; + add (string v.Revision) + add ", Culture=" + match aref.Locale with + | UNone -> add "neutral" + | USome b -> add b + add ", PublicKeyToken=" + match aref.PublicKey with + | UNone -> add "null" + | USome pki -> + let pkt = pki.ToToken() + let convDigit(digit) = + let digitc = + if digit < 10 + then System.Convert.ToInt32 '0' + digit + else System.Convert.ToInt32 'a' + (digit - 10) + System.Convert.ToChar(digitc) + for i = 0 to pkt.Length-1 do + let v = pkt.[i] + addC (convDigit(System.Convert.ToInt32(v)/16)) + addC (convDigit(System.Convert.ToInt32(v)%16)) + // retargetable can be true only for system assemblies that definitely have Version + if aref.Retargetable then + add ", Retargetable=Yes" + b.ToString() + override x.ToString() = x.QualifiedName + + override __.GetHashCode() = + + name.GetHashCode() + + 137 * (hash.GetHashCode() + + 137 * (publicKey.GetHashCode() + + 137 * ( retargetable.GetHashCode() + + 137 * ( version.GetHashCode() + + 137 * locale.GetHashCode())))) + + override __.Equals(obj: obj) = + match obj with + | :? ILAssemblyRef as y -> + name = y.Name + && hash = y.Hash + && publicKey = y.PublicKey + && retargetable = y.Retargetable + && version = y.Version + && locale = y.Locale + | _ -> false + + type ILModuleRef(name:string, hasMetadata: bool, hash: byte[] uoption) = + member __.Name=name + member __.HasMetadata=hasMetadata + member __.Hash=hash + override __.ToString() = "module " + name + + override __.GetHashCode() = + name.GetHashCode() + + 137 * (hasMetadata.GetHashCode() + + 137 * hash.GetHashCode()) + + override __.Equals(obj: obj) = + match obj with + | :? ILModuleRef as y -> + name = y.Name + && hasMetadata = y.HasMetadata + && hash = y.Hash + | _ -> false + + + [] + type ILScopeRef = + | Local + | Module of ILModuleRef + | Assembly of ILAssemblyRef + member x.IsLocalRef = match x with ILScopeRef.Local -> true | _ -> false + member x.IsModuleRef = match x with ILScopeRef.Module _ -> true | _ -> false + member x.IsAssemblyRef= match x with ILScopeRef.Assembly _ -> true | _ -> false + member x.ModuleRef = match x with ILScopeRef.Module x -> x | _ -> failwith "not a module reference" + member x.AssemblyRef = match x with ILScopeRef.Assembly x -> x | _ -> failwith "not an assembly reference" + + member x.QualifiedName = + match x with + | ILScopeRef.Local -> "" + | ILScopeRef.Module mref -> "module "+mref.Name + | ILScopeRef.Assembly aref -> aref.QualifiedName + + override x.ToString() = x.QualifiedName + + type ILArrayBound = int32 option + type ILArrayBounds = ILArrayBound * ILArrayBound + + [] + type ILArrayShape = + | ILArrayShape of ILArrayBounds[] (* lobound/size pairs *) + member x.Rank = (let (ILArrayShape l) = x in l.Length) + static member SingleDimensional = ILArrayShapeStatics.SingleDimensional + static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (Some 0, None) |> List.toArray) + + + and ILArrayShapeStatics() = + static let singleDimensional = ILArrayShape [| (Some 0, None) |] + static member SingleDimensional = singleDimensional + + /// Calling conventions. These are used in method pointer types. + [] + type ILArgConvention = + | Default + | CDecl + | StdCall + | ThisCall + | FastCall + | VarArg + + [] + type ILThisConvention = + | Instance + | InstanceExplicit + | Static + + [] + type ILCallingConv = + | Callconv of ILThisConvention * ILArgConvention + member x.ThisConv = let (Callconv(a, _b)) = x in a + member x.BasicConv = let (Callconv(_a, b)) = x in b + member x.IsInstance = match x.ThisConv with ILThisConvention.Instance -> true | _ -> false + member x.IsInstanceExplicit = match x.ThisConv with ILThisConvention.InstanceExplicit -> true | _ -> false + member x.IsStatic = match x.ThisConv with ILThisConvention.Static -> true | _ -> false + + static member Instance = ILCallingConvStatics.Instance + static member Static = ILCallingConvStatics.Static + + /// Static storage to amortize the allocation of ILCallingConv.Instance and ILCallingConv.Static + and ILCallingConvStatics() = + static let instanceCallConv = Callconv(ILThisConvention.Instance, ILArgConvention.Default) + static let staticCallConv = Callconv(ILThisConvention.Static, ILArgConvention.Default) + static member Instance = instanceCallConv + static member Static = staticCallConv + + type ILBoxity = + | AsObject + | AsValue + + [] + type ILTypeRefScope = + | Top of ILScopeRef + | Nested of ILTypeRef + member x.QualifiedNameExtension = + match x with + | Top scoref -> + let sco = scoref.QualifiedName + if sco = "" then "" else ", " + sco + | Nested tref -> + tref.QualifiedNameExtension + + + // IL type references have a pre-computed hash code to enable quick lookup tables during binary generation. + and ILTypeRef(enc: ILTypeRefScope, nsp: string uoption, name: string) = + let hashCode = hash enc + 137 *( 137 *(hash name) + hash nsp) + + member __.Scope = enc + member __.Name = name + member __.Namespace = nsp + + member tref.FullName = + match enc with + | ILTypeRefScope.Top _ -> joinILTypeName tref.Namespace tref.Name + | ILTypeRefScope.Nested enc -> enc.FullName + "." + tref.Name + + member tref.BasicQualifiedName = + match enc with + | ILTypeRefScope.Top _ -> joinILTypeName tref.Namespace tref.Name + | ILTypeRefScope.Nested enc -> enc.BasicQualifiedName + "+" + tref.Name + + member __.QualifiedNameExtension = enc.QualifiedNameExtension + + member tref.QualifiedName = tref.BasicQualifiedName + enc.QualifiedNameExtension + + override x.ToString() = x.FullName + + override __.GetHashCode() = hashCode + + override __.Equals(obj: obj) = + match obj with + | :? ILTypeRef as y -> + enc = y.Scope + && name = y.Name + && nsp = y.Namespace + | _ -> false + + + and ILTypeSpec(typeRef: ILTypeRef, inst: ILGenericArgs) = + let hashCode = hash typeRef + 137 * (hash inst) + + member __.TypeRef = typeRef + member x.Scope = x.TypeRef.Scope + member x.Name = x.TypeRef.Name + member x.Namespace = x.TypeRef.Namespace + member __.GenericArgs = inst + member x.BasicQualifiedName = + let tc = x.TypeRef.BasicQualifiedName + if x.GenericArgs.Length = 0 then + tc + else + tc + "[" + String.concat ", " (x.GenericArgs |> Array.map (fun arg -> "[" + arg.QualifiedName + "]")) + "]" + + member x.QualifiedNameExtension = + x.TypeRef.QualifiedNameExtension + + member x.FullName = x.TypeRef.FullName + + override x.ToString() = x.TypeRef.ToString() + (if x.GenericArgs.Length = 0 then "" else "<...>") + + override __.GetHashCode() = hashCode + override __.Equals(obj: obj) = + match obj with + | :? ILTypeSpec as y -> + typeRef = y.TypeRef + && inst = y.GenericArgs + | _ -> false + + and [] + ILType = + | Void + | Array of ILArrayShape * ILType + | Value of ILTypeSpec + | Boxed of ILTypeSpec + | Ptr of ILType + | Byref of ILType + | FunctionPointer of ILCallingSignature + | Var of int + | Modified of bool * ILTypeRef * ILType + + member x.BasicQualifiedName = + match x with + | ILType.Var n -> "!" + string n + | ILType.Modified(_, _ty1, ty2) -> ty2.BasicQualifiedName + | ILType.Array (ILArrayShape(s), ty) -> ty.BasicQualifiedName + "[" + System.String(',', s.Length-1) + "]" + | ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName + | ILType.Void -> "void" + | ILType.Ptr _ty -> failwith "unexpected pointer type" + | ILType.Byref _ty -> failwith "unexpected byref type" + | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + + member x.QualifiedNameExtension = + match x with + | ILType.Var _n -> "" + | ILType.Modified(_, _ty1, ty2) -> ty2.QualifiedNameExtension + | ILType.Array (ILArrayShape(_s), ty) -> ty.QualifiedNameExtension + | ILType.Value tr | ILType.Boxed tr -> tr.QualifiedNameExtension + | ILType.Void -> failwith "void" + | ILType.Ptr _ty -> failwith "unexpected pointer type" + | ILType.Byref _ty -> failwith "unexpected byref type" + | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + + member x.QualifiedName = + x.BasicQualifiedName + x.QualifiedNameExtension + + member x.TypeSpec = + match x with + | ILType.Boxed tr | ILType.Value tr -> tr + | _ -> failwithf "not a nominal type" + + member x.Boxity = + match x with + | ILType.Boxed _ -> AsObject + | ILType.Value _ -> AsValue + | _ -> failwithf "not a nominal type" + + member x.TypeRef = + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef + | _ -> failwithf "not a nominal type" + + member x.IsNominal = + match x with + | ILType.Boxed _ | ILType.Value _ -> true + | _ -> false + + member x.GenericArgs = + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.GenericArgs + | _ -> [| |] + + member x.IsTyvar = + match x with + | ILType.Var _ -> true | _ -> false + + override x.ToString() = x.QualifiedName + + and ILCallingSignature(callingConv: ILCallingConv, argTypes: ILTypes, returnType: ILType) = + member __.CallingConv = callingConv + member __.ArgTypes = argTypes + member __.ReturnType = returnType + + and ILGenericArgs = ILType[] + and ILTypes = ILType[] + + + type ILMethodRef(parent: ILTypeRef, callconv: ILCallingConv, genericArity: int, name: string, args: ILTypes, ret: ILType) = + member __.EnclosingTypeRef = parent + member __.CallingConv = callconv + member __.Name = name + member __.GenericArity = genericArity + member __.ArgCount = args.Length + member __.ArgTypes = args + member __.ReturnType = ret + + member x.CallingSignature = ILCallingSignature (x.CallingConv, x.ArgTypes, x.ReturnType) + override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + "(...)" + + + type ILFieldRef(enclosingTypeRef: ILTypeRef, name: string, typ: ILType) = + member __.EnclosingTypeRef = enclosingTypeRef + member __.Name = name + member __.Type = typ + override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + + type ILMethodSpec(methodRef: ILMethodRef, enclosingType: ILType, methodInst: ILGenericArgs) = + member __.MethodRef = methodRef + member __.EnclosingType = enclosingType + member __.GenericArgs = methodInst + member x.Name = x.MethodRef.Name + member x.CallingConv = x.MethodRef.CallingConv + member x.GenericArity = x.MethodRef.GenericArity + member x.FormalArgTypes = x.MethodRef.ArgTypes + member x.FormalReturnType = x.MethodRef.ReturnType + override x.ToString() = x.MethodRef.ToString() + "(...)" + + type ILFieldSpec(fieldRef: ILFieldRef, enclosingType: ILType) = + member __.FieldRef = fieldRef + member __.EnclosingType = enclosingType + member __.FormalType = fieldRef.Type + member __.Name = fieldRef.Name + member __.EnclosingTypeRef = fieldRef.EnclosingTypeRef + override x.ToString() = x.FieldRef.ToString() + + type ILCodeLabel = int + + // -------------------------------------------------------------------- + // Instruction set. + // -------------------------------------------------------------------- + + type ILBasicType = + | DT_R + | DT_I1 + | DT_U1 + | DT_I2 + | DT_U2 + | DT_I4 + | DT_U4 + | DT_I8 + | DT_U8 + | DT_R4 + | DT_R8 + | DT_I + | DT_U + | DT_REF + + [] + type ILToken = + | ILType of ILType + | ILMethod of ILMethodSpec + | ILField of ILFieldSpec + + [] + type ILConst = + | I4 of int32 + | I8 of int64 + | R4 of single + | R8 of double + + type ILTailcall = + | Tailcall + | Normalcall + + type ILAlignment = + | Aligned + | Unaligned1 + | Unaligned2 + | Unaligned4 + + type ILVolatility = + | Volatile + | Nonvolatile + + type ILReadonly = + | ReadonlyAddress + | NormalAddress + + type ILVarArgs = ILTypes option + + [] + type ILComparisonInstr = + | I_beq + | I_bge + | I_bge_un + | I_bgt + | I_bgt_un + | I_ble + | I_ble_un + | I_blt + | I_blt_un + | I_bne_un + | I_brfalse + | I_brtrue + + +#if DEBUG_INFO + type ILDebugPoint = + { sourceDocument: ILSourceDocument; + sourceLine: int; + sourceColumn: int; + sourceEndLine: int; + sourceEndColumn: int } + static member Create(document, line, column, endLine, endColumn) = + { sourceDocument=document; + sourceLine=line; + sourceColumn=column; + sourceEndLine=endLine; + sourceEndColumn=endColumn } + member x.Document=x.sourceDocument + member x.Line=x.sourceLine + member x.Column=x.sourceColumn + member x.EndLine=x.sourceEndLine + member x.EndColumn=x.sourceEndColumn + override x.ToString() = sprintf "(%d, %d)-(%d, %d)" x.Line x.Column x.EndLine x.EndColumn +#endif + + [] + type ILInstr = + | I_add + | I_add_ovf + | I_add_ovf_un + | I_and + | I_div + | I_div_un + | I_ceq + | I_cgt + | I_cgt_un + | I_clt + | I_clt_un + | I_conv of ILBasicType + | I_conv_ovf of ILBasicType + | I_conv_ovf_un of ILBasicType + | I_mul + | I_mul_ovf + | I_mul_ovf_un + | I_rem + | I_rem_un + | I_shl + | I_shr + | I_shr_un + | I_sub + | I_sub_ovf + | I_sub_ovf_un + | I_xor + | I_or + | I_neg + | I_not + | I_ldnull + | I_dup + | I_pop + | I_ckfinite + | I_nop + | I_ldc of ILBasicType * ILConst + | I_ldarg of int + | I_ldarga of int + | I_ldind of ILAlignment * ILVolatility * ILBasicType + | I_ldloc of int + | I_ldloca of int + | I_starg of int + | I_stind of ILAlignment * ILVolatility * ILBasicType + | I_stloc of int + + | I_br of ILCodeLabel + | I_jmp of ILMethodSpec + | I_brcmp of ILComparisonInstr * ILCodeLabel + | I_switch of ILCodeLabel list + | I_ret + + | I_call of ILTailcall * ILMethodSpec * ILVarArgs + | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs + | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs + | I_calli of ILTailcall * ILCallingSignature * ILVarArgs + | I_ldftn of ILMethodSpec + | I_newobj of ILMethodSpec * ILVarArgs + + | I_throw + | I_endfinally + | I_endfilter + | I_leave of ILCodeLabel + | I_rethrow + + | I_ldsfld of ILVolatility * ILFieldSpec + | I_ldfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldsflda of ILFieldSpec + | I_ldflda of ILFieldSpec + | I_stsfld of ILVolatility * ILFieldSpec + | I_stfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldstr of string + | I_isinst of ILType + | I_castclass of ILType + | I_ldtoken of ILToken + | I_ldvirtftn of ILMethodSpec + + | I_cpobj of ILType + | I_initobj of ILType + | I_ldobj of ILAlignment * ILVolatility * ILType + | I_stobj of ILAlignment * ILVolatility * ILType + | I_box of ILType + | I_unbox of ILType + | I_unbox_any of ILType + | I_sizeof of ILType + + | I_ldelem of ILBasicType + | I_stelem of ILBasicType + | I_ldelema of ILReadonly * ILArrayShape * ILType + | I_ldelem_any of ILArrayShape * ILType + | I_stelem_any of ILArrayShape * ILType + | I_newarr of ILArrayShape * ILType + | I_ldlen + + | I_mkrefany of ILType + | I_refanytype + | I_refanyval of ILType + + | I_break +#if EMIT_DEBUG_INFO + | I_seqpoint of ILDebugPoint +#endif + | I_arglist + + | I_localloc + | I_cpblk of ILAlignment * ILVolatility + | I_initblk of ILAlignment * ILVolatility + + (* FOR EXTENSIONS, e.g. MS-ILX *) + | EI_ilzero of ILType + | EI_ldlen_multi of int32 * int32 + + + [] + type ILExceptionClause = + | Finally of (ILCodeLabel * ILCodeLabel) + | Fault of (ILCodeLabel * ILCodeLabel) + | FilterCatch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel) + | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel) + + [] + type ILExceptionSpec = + { Range: (ILCodeLabel * ILCodeLabel); + Clause: ILExceptionClause } + + /// Indicates that a particular local variable has a particular source + /// language name within a given set of ranges. This does not effect local + /// variable numbering, which is global over the whole method. + [] + type ILLocalDebugMapping = + { LocalIndex: int; + LocalName: string; } + + [] + type ILLocalDebugInfo = + { Range: (ILCodeLabel * ILCodeLabel); + DebugMappings: ILLocalDebugMapping[] } + + [] + type ILCode = + { Labels: Dictionary + Instrs:ILInstr[] + Exceptions: ILExceptionSpec[] + Locals: ILLocalDebugInfo[] } + + [] + type ILLocal = + { Type: ILType; + IsPinned: bool; + DebugInfo: (string * int * int) option } + + type ILLocals = ILLocal[] + + [] + type ILMethodBody = + { IsZeroInit: bool + MaxStack: int32 + Locals: ILLocals + Code: ILCode +#if EMIT_DEBUG_INFO + DebugPoint: ILDebugPoint option +#endif + } + + type ILPlatform = + | X86 + | AMD64 + | IA64 + + type ILCustomAttrNamedArg = ILCustomAttrNamedArg of (string * ILType * obj) + + type ILCustomAttribute = + { Method: ILMethodSpec + Data: byte[] + Elements: obj list} + + type ILCustomAttrs = + abstract Entries: ILCustomAttribute[] + + type ILCustomAttrsStatics() = + static let empty = { new ILCustomAttrs with member __.Entries = [| |] } + static member Empty = empty + + [] + type ILMemberAccess = + | Assembly + | CompilerControlled + | FamilyAndAssembly + | FamilyOrAssembly + | Family + | Private + | Public + static member OfFlags (flags: int) = + let f = (flags &&& 0x00000007) + if f = 0x00000001 then ILMemberAccess.Private + elif f = 0x00000006 then ILMemberAccess.Public + elif f = 0x00000004 then ILMemberAccess.Family + elif f = 0x00000002 then ILMemberAccess.FamilyAndAssembly + elif f = 0x00000005 then ILMemberAccess.FamilyOrAssembly + elif f = 0x00000003 then ILMemberAccess.Assembly + else ILMemberAccess.CompilerControlled + + [] + type ILFieldInit = obj + + type ILParameter = + { Name: string uoption + ParameterType: ILType + Default: ILFieldInit uoption + //Marshal: ILNativeType option + Attributes: ParameterAttributes + CustomAttrs: ILCustomAttrs } + member x.IsIn = ((x.Attributes &&& ParameterAttributes.In) <> enum 0) + member x.IsOut = ((x.Attributes &&& ParameterAttributes.Out) <> enum 0) + member x.IsOptional = ((x.Attributes &&& ParameterAttributes.Optional) <> enum 0) + + type ILParameters = ILParameter[] + + type ILReturn = + { //Marshal: ILNativeType option; + Type: ILType; + CustomAttrs: ILCustomAttrs } + + type ILOverridesSpec = + | OverridesSpec of ILMethodRef * ILType + member x.MethodRef = let (OverridesSpec(mr, _ty)) = x in mr + member x.EnclosingType = let (OverridesSpec(_mr, ty)) = x in ty + + [] + type ILGenericVariance = + | NonVariant + | CoVariant + | ContraVariant + + type ILGenericParameterDef = + { Name: string + Constraints: ILTypes + Attributes: GenericParameterAttributes + CustomAttrs: ILCustomAttrs + Token: int } + + member x.HasReferenceTypeConstraint= (x.Attributes &&& GenericParameterAttributes.ReferenceTypeConstraint) <> enum 0 + member x.HasNotNullableValueTypeConstraint= (x.Attributes &&& GenericParameterAttributes.NotNullableValueTypeConstraint) <> enum 0 + member x.HasDefaultConstructorConstraint= (x.Attributes &&& GenericParameterAttributes.DefaultConstructorConstraint) <> enum 0 + member x.IsCovariant = (x.Attributes &&& GenericParameterAttributes.Covariant) <> enum 0 + member x.IsContravariant = (x.Attributes &&& GenericParameterAttributes.Contravariant) <> enum 0 + override x.ToString() = x.Name + + type ILGenericParameterDefs = ILGenericParameterDef[] + + [] + type ILMethodDef = + { Token: int32 + Name: string + CallingConv: ILCallingConv + Parameters: ILParameters + Return: ILReturn + Body: ILMethodBody option + ImplAttributes: MethodImplAttributes + //SecurityDecls: ILPermissions + //HasSecurity: bool + IsEntryPoint:bool + Attributes: MethodAttributes + GenericParams: ILGenericParameterDefs + CustomAttrs: ILCustomAttrs } + member x.ParameterTypes = x.Parameters |> Array.map (fun p -> p.ParameterType) + static member ComputeIsStatic attrs = attrs &&& MethodAttributes.Static <> enum 0 + member x.IsStatic = ILMethodDef.ComputeIsStatic x.Attributes + member x.IsAbstract = x.Attributes &&& MethodAttributes.Abstract <> enum 0 + member x.IsVirtual = x.Attributes &&& MethodAttributes.Virtual <> enum 0 + member x.IsCheckAccessOnOverride = x.Attributes &&& MethodAttributes.CheckAccessOnOverride <> enum 0 + member x.IsNewSlot = x.Attributes &&& MethodAttributes.NewSlot <> enum 0 + member x.IsFinal = x.Attributes &&& MethodAttributes.Final <> enum 0 + member x.IsSpecialName = x.Attributes &&& MethodAttributes.SpecialName <> enum 0 + member x.IsRTSpecialName = x.Attributes &&& MethodAttributes.RTSpecialName <> enum 0 + member x.IsHideBySig = x.Attributes &&& MethodAttributes.HideBySig <> enum 0 + member x.IsClassInitializer = x.Name = ".cctor" + member x.IsConstructor = x.Name = ".ctor" + member x.IsInternalCall = (int x.ImplAttributes &&& 0x1000 <> 0) + member x.IsManaged = (int x.ImplAttributes &&& 0x0004 = 0) + member x.IsForwardRef = (int x.ImplAttributes &&& 0x0010 <> 0) + member x.IsPreserveSig = (int x.ImplAttributes &&& 0x0080 <> 0) + member x.IsMustRun = (int x.ImplAttributes &&& 0x0040 <> 0) + member x.IsSynchronized = (int x.ImplAttributes &&& 0x0020 <> 0) + member x.IsNoInline = (int x.ImplAttributes &&& 0x0008 <> 0) + member x.Access = ILMemberAccess.OfFlags (int x.Attributes) + + member md.CallingSignature = ILCallingSignature (md.CallingConv, md.ParameterTypes, md.Return.Type) + override x.ToString() = "method " + x.Name + + type ILMethodDefs(larr: Lazy) = + + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for y in larr.Force() do + let key = y.Name + if lmap.ContainsKey key then + lmap.[key] <- Array.append [| y |] lmap.[key] + else + lmap.[key] <- [| y |] + lmap + + member __.Entries = larr.Force() + member __.FindByName nm = + let scc, ys = getmap().TryGetValue(nm) + if scc then ys else Array.empty + member x.FindByNameAndArity (nm, arity) = x.FindByName nm |> Array.filter (fun x -> x.Parameters.Length = arity) + member x.TryFindUniqueByName name = + match x.FindByName(name) with + | [| md |] -> Some md + | [| |] -> None + | _ -> failwithf "multiple methods exist with name %s" name + + [] + type ILEventDef = + { //EventHandlerType: ILType option + Name: string + Attributes: System.Reflection.EventAttributes + AddMethod: ILMethodRef + RemoveMethod: ILMethodRef + //FireMethod: ILMethodRef option + //OtherMethods: ILMethodRef[] + CustomAttrs: ILCustomAttrs + Token: int } + member x.EventHandlerType = x.AddMethod.ArgTypes.[0] + member x.IsStatic = x.AddMethod.CallingConv.IsStatic + member x.IsSpecialName = (x.Attributes &&& EventAttributes.SpecialName) <> enum<_>(0) + member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0) + override x.ToString() = "event " + x.Name + + type ILEventDefs = + abstract Entries: ILEventDef[] + + [] + type ILPropertyDef = + { Name: string + Attributes: System.Reflection.PropertyAttributes + SetMethod: ILMethodRef option + GetMethod: ILMethodRef option + CallingConv: ILThisConvention + PropertyType: ILType + Init: ILFieldInit option + IndexParameterTypes: ILTypes + CustomAttrs: ILCustomAttrs + Token: int } + member x.IsStatic = (match x.CallingConv with ILThisConvention.Static -> true | _ -> false) + member x.IndexParameters = + x.IndexParameterTypes |> Array.mapi (fun i ty -> + { Name = USome("arg"+string i) + ParameterType = ty + Default = UNone + Attributes = ParameterAttributes.None + CustomAttrs = ILCustomAttrsStatics.Empty }) + member x.IsSpecialName = x.Attributes &&& PropertyAttributes.SpecialName <> enum 0 + member x.IsRTSpecialName = x.Attributes &&& PropertyAttributes.RTSpecialName <> enum 0 + override x.ToString() = "property " + x.Name + + type ILPropertyDefs = + abstract Entries: ILPropertyDef[] + + [] + type ILFieldDef = + { Name: string + FieldType: ILType + Attributes: FieldAttributes + //Data: byte[] option + LiteralValue: ILFieldInit option + Offset: int32 option + //Marshal: ILNativeType option + CustomAttrs: ILCustomAttrs + Token: int } + member x.IsStatic = x.Attributes &&& FieldAttributes.Static <> enum 0 + member x.IsInitOnly = x.Attributes &&& FieldAttributes.InitOnly <> enum 0 + member x.IsLiteral = x.Attributes &&& FieldAttributes.Literal <> enum 0 + member x.NotSerialized = x.Attributes &&& FieldAttributes.NotSerialized <> enum 0 + member x.IsSpecialName = x.Attributes &&& FieldAttributes.SpecialName <> enum 0 + //let isStatic = (flags &&& 0x0010) <> 0 + //{ Name = nm + // FieldType = readBlobHeapAsFieldSig numtypars typeIdx + // IsInitOnly = (flags &&& 0x0020) <> 0 + // IsLiteral = (flags &&& 0x0040) <> 0 + // NotSerialized = (flags &&& 0x0080) <> 0 + // IsSpecialName = (flags &&& 0x0200) <> 0 || (flags &&& 0x0400) <> 0 (* REVIEW: RTSpecialName *) + member x.Access = ILMemberAccess.OfFlags (int x.Attributes) + override x.ToString() = "field " + x.Name + + + type ILFieldDefs = + abstract Entries: ILFieldDef[] + + type ILMethodImplDef = + { Overrides: ILOverridesSpec + OverrideBy: ILMethodSpec } + + // Index table by name and arity. + type ILMethodImplDefs = + abstract Entries: ILMethodImplDef[] + + [] + type ILTypeInit = + | BeforeField + | OnAny + + [] + type ILDefaultPInvokeEncoding = + | Ansi + | Auto + | Unicode + + [] + type ILTypeDefLayout = + | Auto + | Sequential of ILTypeDefLayoutInfo + | Explicit of ILTypeDefLayoutInfo + + and ILTypeDefLayoutInfo = + { Size: int32 option + Pack: uint16 option } + + type ILTypeDefAccess = + | Public + | Private + | Nested of ILMemberAccess + static member OfFlags flags = + let f = (flags &&& 0x00000007) + if f = 0x00000001 then ILTypeDefAccess.Public + elif f = 0x00000002 then ILTypeDefAccess.Nested ILMemberAccess.Public + elif f = 0x00000003 then ILTypeDefAccess.Nested ILMemberAccess.Private + elif f = 0x00000004 then ILTypeDefAccess.Nested ILMemberAccess.Family + elif f = 0x00000006 then ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly + elif f = 0x00000007 then ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly + elif f = 0x00000005 then ILTypeDefAccess.Nested ILMemberAccess.Assembly + else ILTypeDefAccess.Private + + [] + type ILTypeDefKind = + | Class + | ValueType + | Interface + | Enum + | Delegate + + [] + type ILTypeDef = + { Namespace: string uoption + Name: string + GenericParams: ILGenericParameterDefs + Attributes: TypeAttributes + NestedTypes: ILTypeDefs + Layout: ILTypeDefLayout + Implements: ILTypes + Extends: ILType option + Methods: ILMethodDefs + Fields: ILFieldDefs + MethodImpls: ILMethodImplDefs + Events: ILEventDefs + Properties: ILPropertyDefs + CustomAttrs: ILCustomAttrs + Token: int } + static member ComputeKind flags (super: ILType option) (nsp: string uoption) (nm: string) = + if (flags &&& 0x00000020) <> 0x0 then ILTypeDefKind.Interface else + let isEnum = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "Enum") + let isDelegate = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "Delegate") + let isMulticastDelegate = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "MulticastDelegate") + let selfIsMulticastDelegate = (nsp = USome "System" && nm = "MulticastDelegate") + let isValueType = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "ValueType" && not (nsp = USome "System" && nm = "Enum")) + if isEnum then ILTypeDefKind.Enum + elif (isDelegate && not selfIsMulticastDelegate) || isMulticastDelegate then ILTypeDefKind.Delegate + elif isValueType then ILTypeDefKind.ValueType + else ILTypeDefKind.Class + + member x.Kind = ILTypeDef.ComputeKind (int x.Attributes) x.Extends x.Namespace x.Name + member x.IsClass = (match x.Kind with ILTypeDefKind.Class -> true | _ -> false) + member x.IsInterface = (match x.Kind with ILTypeDefKind.Interface -> true | _ -> false) + member x.IsEnum = (match x.Kind with ILTypeDefKind.Enum -> true | _ -> false) + member x.IsDelegate = (match x.Kind with ILTypeDefKind.Delegate -> true | _ -> false) + member x.IsAbstract= (x.Attributes &&& TypeAttributes.Abstract) <> enum 0 + member x.IsSealed= (x.Attributes &&& TypeAttributes.Sealed) <> enum 0 + member x.IsSerializable= (x.Attributes &&& TypeAttributes.Serializable) <> enum 0 + member x.IsComInterop= (x.Attributes &&& TypeAttributes.Import) <> enum 0 + member x.IsSpecialName= (x.Attributes &&& TypeAttributes.SpecialName) <> enum 0 + member x.Access = ILTypeDefAccess.OfFlags (int x.Attributes) + + member x.IsNested = + match x.Access with + | ILTypeDefAccess.Nested _ -> true + | _ -> false + + member tdef.IsStructOrEnum = + match tdef.Kind with + | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> true + | _ -> false + + member x.Encoding = + let f = (int x.Attributes &&& 0x00030000) + if f = 0x00020000 then ILDefaultPInvokeEncoding.Auto + elif f = 0x00010000 then ILDefaultPInvokeEncoding.Unicode + else ILDefaultPInvokeEncoding.Ansi + + member x.InitSemantics = + if x.Kind = ILTypeDefKind.Interface then ILTypeInit.OnAny + elif (int x.Attributes &&& 0x00100000) <> 0x0 then ILTypeInit.BeforeField + else ILTypeInit.OnAny + + override x.ToString() = "type " + x.Name + + and ILTypeDefs(larr: Lazy<(string uoption * string * Lazy)[]>) = + + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for (nsp, nm, ltd) in larr.Force() do + let key = nsp, nm + lmap.[key] <- ltd + lmap + + member __.Entries = + [| for (_, _, td) in larr.Force() -> td.Force() |] + + member __.TryFindByName (nsp, nm) = + let tdefs = getmap() + let key = (nsp, nm) + if tdefs.ContainsKey key then + Some (tdefs.[key].Force()) + else + None + + type ILNestedExportedType = + { Name: string + Access: ILMemberAccess + Nested: ILNestedExportedTypesAndForwarders + CustomAttrs: ILCustomAttrs } + override x.ToString() = "nested fwd " + x.Name + + and ILNestedExportedTypesAndForwarders(larr:Lazy) = + let lmap = lazy ((Map.empty, larr.Force()) ||> Array.fold (fun m x -> m.Add(x.Name, x))) + member __.Entries = larr.Force() + member __.TryFindByName nm = lmap.Force().TryFind nm + + and [] + ILExportedTypeOrForwarder = + { ScopeRef: ILScopeRef + Namespace: string uoption + Name: string + IsForwarder: bool + Access: ILTypeDefAccess; + Nested: ILNestedExportedTypesAndForwarders; + CustomAttrs: ILCustomAttrs } + override x.ToString() = "fwd " + x.Name + + and ILExportedTypesAndForwarders(larr:Lazy) = + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for ltd in larr.Force() do + let key = ltd.Namespace, ltd.Name + lmap.[key] <- ltd + lmap + member __.Entries = larr.Force() + member __.TryFindByName (nsp, nm) = match getmap().TryGetValue ((nsp, nm)) with true, v -> Some v | false, _ -> None + + [] + type ILResourceAccess = + | Public + | Private + + [] + type ILResourceLocation = + | Local of (unit -> byte[]) + | File of ILModuleRef * int32 + | Assembly of ILAssemblyRef + + type ILResource = + { Name: string + Location: ILResourceLocation + Access: ILResourceAccess + CustomAttrs: ILCustomAttrs } + override x.ToString() = "resource " + x.Name + + type ILResources(larr: Lazy) = + member __.Entries = larr.Force() + + type ILAssemblyManifest = + { Name: string + AuxModuleHashAlgorithm: int32 + PublicKey: byte[] uoption + Version: Version uoption + Locale: string uoption + CustomAttrs: ILCustomAttrs + //AssemblyLongevity: ILAssemblyLongevity + DisableJitOptimizations: bool + JitTracking: bool + IgnoreSymbolStoreSequencePoints: bool + Retargetable: bool + ExportedTypes: ILExportedTypesAndForwarders + EntrypointElsewhere: ILModuleRef option } + + member x.GetName() = + let asmName = AssemblyName(Name=x.Name) + match x.PublicKey with + | USome bytes -> asmName.SetPublicKey(bytes) + | UNone -> () + match x.Version with + | USome v -> asmName.Version <- v + | UNone -> () + asmName.CultureName <- System.Globalization.CultureInfo.InvariantCulture.Name + asmName + + override x.ToString() = "manifest " + x.Name + + type ILModuleDef = + { Manifest: ILAssemblyManifest option + CustomAttrs: ILCustomAttrs + Name: string + TypeDefs: ILTypeDefs + SubsystemVersion: int * int + UseHighEntropyVA: bool + (* Random bits of relatively uninteresting data *) + SubSystemFlags: int32 + IsDLL: bool + IsILOnly: bool + Platform: ILPlatform option + StackReserveSize: int32 option + Is32Bit: bool + Is32BitPreferred: bool + Is64Bit: bool + VirtualAlignment: int32 + PhysicalAlignment: int32 + ImageBase: int32 + MetadataVersion: string + Resources: ILResources } + + member x.ManifestOfAssembly = + match x.Manifest with + | Some m -> m + | None -> failwith "no manifest" + + member m.HasManifest = m.Manifest.IsSome + + override x.ToString() = "module " + x.Name + + + [] + type ILGlobals = + { typ_Object: ILType + typ_String: ILType + typ_Void: ILType + typ_Type: ILType + typ_TypedReference: ILType option + typ_SByte: ILType + typ_Int16: ILType + typ_Int32: ILType + typ_Array: ILType + typ_Int64: ILType + typ_Byte: ILType + typ_UInt16: ILType + typ_UInt32: ILType + typ_UInt64: ILType + typ_Single: ILType + typ_Double: ILType + typ_Boolean: ILType + typ_Char: ILType + typ_IntPtr: ILType + typ_UIntPtr: ILType + systemRuntimeScopeRef: ILScopeRef } + override __.ToString() = "" + + [] + + [] + type ILTableName(idx: int) = + member __.Index = idx + static member FromIndex n = ILTableName n + + module ILTableNames = + let Module = ILTableName 0 + let TypeRef = ILTableName 1 + let TypeDef = ILTableName 2 + let FieldPtr = ILTableName 3 + let Field = ILTableName 4 + let MethodPtr = ILTableName 5 + let Method = ILTableName 6 + let ParamPtr = ILTableName 7 + let Param = ILTableName 8 + let InterfaceImpl = ILTableName 9 + let MemberRef = ILTableName 10 + let Constant = ILTableName 11 + let CustomAttribute = ILTableName 12 + let FieldMarshal = ILTableName 13 + let Permission = ILTableName 14 + let ClassLayout = ILTableName 15 + let FieldLayout = ILTableName 16 + let StandAloneSig = ILTableName 17 + let EventMap = ILTableName 18 + let EventPtr = ILTableName 19 + let Event = ILTableName 20 + let PropertyMap = ILTableName 21 + let PropertyPtr = ILTableName 22 + let Property = ILTableName 23 + let MethodSemantics = ILTableName 24 + let MethodImpl = ILTableName 25 + let ModuleRef = ILTableName 26 + let TypeSpec = ILTableName 27 + let ImplMap = ILTableName 28 + let FieldRVA = ILTableName 29 + let ENCLog = ILTableName 30 + let ENCMap = ILTableName 31 + let Assembly = ILTableName 32 + let AssemblyProcessor = ILTableName 33 + let AssemblyOS = ILTableName 34 + let AssemblyRef = ILTableName 35 + let AssemblyRefProcessor = ILTableName 36 + let AssemblyRefOS = ILTableName 37 + let File = ILTableName 38 + let ExportedType = ILTableName 39 + let ManifestResource = ILTableName 40 + let Nested = ILTableName 41 + let GenericParam = ILTableName 42 + let MethodSpec = ILTableName 43 + let GenericParamConstraint = ILTableName 44 + let UserStrings = ILTableName 0x70 (* Special encoding of embedded UserString tokens - See 1.9 Partition III *) + + /// Which tables are sorted and by which column. + // + // Sorted bit-vector as stored by CLR V1: 00fa 0133 0002 0000 + // But what does this mean? The ECMA spec does not say! + // Metainfo -schema reports sorting as shown below. + // But some sorting, e.g. EventMap does not seem to show + let sortedTableInfo = + [ (InterfaceImpl, 0) + (Constant, 1) + (CustomAttribute, 0) + (FieldMarshal, 0) + (Permission, 1) + (ClassLayout, 2) + (FieldLayout, 1) + (MethodSemantics, 2) + (MethodImpl, 0) + (ImplMap, 1) + (FieldRVA, 1) + (Nested, 0) + (GenericParam, 2) + (GenericParamConstraint, 0) ] + + [] + type TypeDefOrRefOrSpecTag(tag: int32) = + member __.Tag = tag + static member TypeDef = TypeDefOrRefOrSpecTag 0x00 + static member TypeRef = TypeDefOrRefOrSpecTag 0x01 + static member TypeSpec = TypeDefOrRefOrSpecTag 0x2 + + [] + type HasConstantTag(tag: int32) = + member __.Tag = tag + static member FieldDef = HasConstantTag 0x0 + static member ParamDef = HasConstantTag 0x1 + static member Property = HasConstantTag 0x2 + + [] + type HasCustomAttributeTag(tag: int32) = + member __.Tag = tag + static member MethodDef = HasCustomAttributeTag 0x0 + static member FieldDef = HasCustomAttributeTag 0x1 + static member TypeRef = HasCustomAttributeTag 0x2 + static member TypeDef = HasCustomAttributeTag 0x3 + static member ParamDef = HasCustomAttributeTag 0x4 + static member InterfaceImpl = HasCustomAttributeTag 0x5 + static member MemberRef = HasCustomAttributeTag 0x6 + static member Module = HasCustomAttributeTag 0x7 + static member Permission = HasCustomAttributeTag 0x8 + static member Property = HasCustomAttributeTag 0x9 + static member Event = HasCustomAttributeTag 0xa + static member StandAloneSig = HasCustomAttributeTag 0xb + static member ModuleRef = HasCustomAttributeTag 0xc + static member TypeSpec = HasCustomAttributeTag 0xd + static member Assembly = HasCustomAttributeTag 0xe + static member AssemblyRef = HasCustomAttributeTag 0xf + static member File = HasCustomAttributeTag 0x10 + static member ExportedType = HasCustomAttributeTag 0x11 + static member ManifestResource = HasCustomAttributeTag 0x12 + static member GenericParam = HasCustomAttributeTag 0x13 + static member GenericParamConstraint = HasCustomAttributeTag 0x14 + static member MethodSpec = HasCustomAttributeTag 0x15 + + [] + type HasFieldMarshalTag(tag: int32) = + member __.Tag = tag + static member FieldDef = HasFieldMarshalTag 0x00 + static member ParamDef = HasFieldMarshalTag 0x01 + + [] + type HasDeclSecurityTag(tag: int32) = + member __.Tag = tag + static member TypeDef = HasDeclSecurityTag 0x00 + static member MethodDef = HasDeclSecurityTag 0x01 + static member Assembly = HasDeclSecurityTag 0x02 + + [] + type MemberRefParentTag(tag: int32) = + member __.Tag = tag + static member TypeRef = MemberRefParentTag 0x01 + static member ModuleRef = MemberRefParentTag 0x02 + static member MethodDef = MemberRefParentTag 0x03 + static member TypeSpec = MemberRefParentTag 0x04 + + [] + type HasSemanticsTag(tag: int32) = + member __.Tag = tag + static member Event = HasSemanticsTag 0x00 + static member Property = HasSemanticsTag 0x01 + + [] + type MethodDefOrRefTag(tag: int32) = + member __.Tag = tag + static member MethodDef = MethodDefOrRefTag 0x00 + static member MemberRef = MethodDefOrRefTag 0x01 + static member MethodSpec = MethodDefOrRefTag 0x02 + + [] + type MemberForwardedTag(tag: int32) = + member __.Tag = tag + static member FieldDef = MemberForwardedTag 0x00 + static member MethodDef = MemberForwardedTag 0x01 + + [] + type ImplementationTag(tag: int32) = + member __.Tag = tag + static member File = ImplementationTag 0x00 + static member AssemblyRef = ImplementationTag 0x01 + static member ExportedType = ImplementationTag 0x02 + + [] + type CustomAttributeTypeTag(tag: int32) = + member __.Tag = tag + static member MethodDef = CustomAttributeTypeTag 0x02 + static member MemberRef = CustomAttributeTypeTag 0x03 + + [] + type ResolutionScopeTag(tag: int32) = + member __.Tag = tag + static member Module = ResolutionScopeTag 0x00 + static member ModuleRef = ResolutionScopeTag 0x01 + static member AssemblyRef = ResolutionScopeTag 0x02 + static member TypeRef = ResolutionScopeTag 0x03 + + [] + type TypeOrMethodDefTag(tag: int32) = + member __.Tag = tag + static member TypeDef = TypeOrMethodDefTag 0x00 + static member MethodDef = TypeOrMethodDefTag 0x01 + + [] + type TaggedIndex<'T> = + val tag: 'T + val index: int32 + new(tag, index) = { tag=tag; index=index } + + + type ILImageChunk = { size: int32; addr: int32 } + + type ILRowElementKind = + | UShort + | ULong + | Byte + | Data + | GGuid + | Blob + | SString + | SimpleIndex of ILTableName + | TypeDefOrRefOrSpec + | TypeOrMethodDef + | HasConstant + | HasCustomAttribute + | HasFieldMarshal + | HasDeclSecurity + | MemberRefParent + | HasSemantics + | MethodDefOrRef + | MemberForwarded + | Implementation + | CustomAttributeType + | ResolutionScope + + type ILRowKind = ILRowKind of ILRowElementKind list + + type TypeDefAsTypIdx = TypeDefAsTypIdx of ILBoxity * ILGenericArgs * int + type TypeRefAsTypIdx = TypeRefAsTypIdx of ILBoxity * ILGenericArgs * int + type BlobAsMethodSigIdx = BlobAsMethodSigIdx of int * int32 + type BlobAsFieldSigIdx = BlobAsFieldSigIdx of int * int32 + type BlobAsPropSigIdx = BlobAsPropSigIdx of int * int32 + type BlobAsLocalSigIdx = BlobAsLocalSigIdx of int * int32 + type MemberRefAsMspecIdx = MemberRefAsMspecIdx of int * int + type MethodSpecAsMspecIdx = MethodSpecAsMspecIdx of int * int + type MemberRefAsFspecIdx = MemberRefAsFspecIdx of int * int + type CustomAttrIdx = CustomAttrIdx of CustomAttributeTypeTag * int * int32 + type SecurityDeclIdx = SecurityDeclIdx of uint16 * int32 + type GenericParamsIdx = GenericParamsIdx of int * TypeOrMethodDefTag * int + + type MethodData = MethodData of ILType * ILCallingConv * string * ILTypes * ILType * ILTypes + type VarArgMethodData = VarArgMethodData of ILType * ILCallingConv * string * ILTypes * ILVarArgs * ILType * ILTypes + + [] + module Constants = + let et_END = 0x00uy + let et_VOID = 0x01uy + let et_BOOLEAN = 0x02uy + let et_CHAR = 0x03uy + let et_I1 = 0x04uy + let et_U1 = 0x05uy + let et_I2 = 0x06uy + let et_U2 = 0x07uy + let et_I4 = 0x08uy + let et_U4 = 0x09uy + let et_I8 = 0x0Auy + let et_U8 = 0x0Buy + let et_R4 = 0x0Cuy + let et_R8 = 0x0Duy + let et_STRING = 0x0Euy + let et_PTR = 0x0Fuy + let et_BYREF = 0x10uy + let et_VALUETYPE = 0x11uy + let et_CLASS = 0x12uy + let et_VAR = 0x13uy + let et_ARRAY = 0x14uy + let et_WITH = 0x15uy + let et_TYPEDBYREF = 0x16uy + let et_I = 0x18uy + let et_U = 0x19uy + let et_FNPTR = 0x1Buy + let et_OBJECT = 0x1Cuy + let et_SZARRAY = 0x1Duy + let et_MVAR = 0x1euy + let et_CMOD_REQD = 0x1Fuy + let et_CMOD_OPT = 0x20uy + + let et_SENTINEL = 0x41uy // sentinel for varargs + let et_PINNED = 0x45uy + + let e_IMAGE_CEE_CS_CALLCONV_FASTCALL = 0x04uy + let e_IMAGE_CEE_CS_CALLCONV_STDCALL = 0x02uy + let e_IMAGE_CEE_CS_CALLCONV_THISCALL = 0x03uy + let e_IMAGE_CEE_CS_CALLCONV_CDECL = 0x01uy + let e_IMAGE_CEE_CS_CALLCONV_VARARG = 0x05uy + let e_IMAGE_CEE_CS_CALLCONV_FIELD = 0x06uy + let e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x07uy + let e_IMAGE_CEE_CS_CALLCONV_PROPERTY = 0x08uy + + let e_IMAGE_CEE_CS_CALLCONV_GENERICINST = 0x0auy + let e_IMAGE_CEE_CS_CALLCONV_GENERIC = 0x10uy + let e_IMAGE_CEE_CS_CALLCONV_INSTANCE = 0x20uy + let e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT = 0x40uy + + + // Logical shift right treating int32 as unsigned integer. + // Code that uses this should probably be adjusted to use unsigned integer types. + let (>>>&) (x:int32) (n:int32) = int32 (uint32 x >>> n) + + let align alignment n = ((n + alignment - 0x1) / alignment) * alignment + + let uncodedToken (tab:ILTableName) idx = ((tab.Index <<< 24) ||| idx) + + let i32ToUncodedToken tok = + let idx = tok &&& 0xffffff + let tab = tok >>>& 24 + (ILTableName.FromIndex tab, idx) + + + let uncodedTokenToTypeDefOrRefOrSpec (tab, tok) = + let tag = + if tab = ILTableNames.TypeDef then TypeDefOrRefOrSpecTag.TypeDef + elif tab = ILTableNames.TypeRef then TypeDefOrRefOrSpecTag.TypeRef + elif tab = ILTableNames.TypeSpec then TypeDefOrRefOrSpecTag.TypeSpec + else failwith "bad table in uncodedTokenToTypeDefOrRefOrSpec" + TaggedIndex(tag, tok) + + let uncodedTokenToMethodDefOrRef (tab, tok) = + let tag = + if tab = ILTableNames.Method then MethodDefOrRefTag.MethodDef + elif tab = ILTableNames.MemberRef then MethodDefOrRefTag.MemberRef + else failwith "bad table in uncodedTokenToMethodDefOrRef" + TaggedIndex(tag, tok) + + let (|TaggedIndex|) (x:TaggedIndex<'T>) = x.tag, x.index + let tokToTaggedIdx f nbits tok = + let tagmask = + if nbits = 1 then 1 + elif nbits = 2 then 3 + elif nbits = 3 then 7 + elif nbits = 4 then 15 + elif nbits = 5 then 31 + else failwith "too many nbits" + let tag = tok &&& tagmask + let idx = tok >>>& nbits + TaggedIndex(f tag, idx) + + let i_nop = 0x00 + let i_break = 0x01 + let i_ldarg_0 = 0x02 + let i_ldarg_1 = 0x03 + let i_ldarg_2 = 0x04 + let i_ldarg_3 = 0x05 + let i_ldloc_0 = 0x06 + let i_ldloc_1 = 0x07 + let i_ldloc_2 = 0x08 + let i_ldloc_3 = 0x09 + let i_stloc_0 = 0x0a + let i_stloc_1 = 0x0b + let i_stloc_2 = 0x0c + let i_stloc_3 = 0x0d + let i_ldarg_s = 0x0e + let i_ldarga_s = 0x0f + let i_starg_s = 0x10 + let i_ldloc_s = 0x11 + let i_ldloca_s = 0x12 + let i_stloc_s = 0x13 + let i_ldnull = 0x14 + let i_ldc_i4_m1 = 0x15 + let i_ldc_i4_0 = 0x16 + let i_ldc_i4_1 = 0x17 + let i_ldc_i4_2 = 0x18 + let i_ldc_i4_3 = 0x19 + let i_ldc_i4_4 = 0x1a + let i_ldc_i4_5 = 0x1b + let i_ldc_i4_6 = 0x1c + let i_ldc_i4_7 = 0x1d + let i_ldc_i4_8 = 0x1e + let i_ldc_i4_s = 0x1f + let i_ldc_i4 = 0x20 + let i_ldc_i8 = 0x21 + let i_ldc_r4 = 0x22 + let i_ldc_r8 = 0x23 + let i_dup = 0x25 + let i_pop = 0x26 + let i_jmp = 0x27 + let i_call = 0x28 + let i_calli = 0x29 + let i_ret = 0x2a + let i_br_s = 0x2b + let i_brfalse_s = 0x2c + let i_brtrue_s = 0x2d + let i_beq_s = 0x2e + let i_bge_s = 0x2f + let i_bgt_s = 0x30 + let i_ble_s = 0x31 + let i_blt_s = 0x32 + let i_bne_un_s = 0x33 + let i_bge_un_s = 0x34 + let i_bgt_un_s = 0x35 + let i_ble_un_s = 0x36 + let i_blt_un_s = 0x37 + let i_br = 0x38 + let i_brfalse = 0x39 + let i_brtrue = 0x3a + let i_beq = 0x3b + let i_bge = 0x3c + let i_bgt = 0x3d + let i_ble = 0x3e + let i_blt = 0x3f + let i_bne_un = 0x40 + let i_bge_un = 0x41 + let i_bgt_un = 0x42 + let i_ble_un = 0x43 + let i_blt_un = 0x44 + let i_switch = 0x45 + let i_ldind_i1 = 0x46 + let i_ldind_u1 = 0x47 + let i_ldind_i2 = 0x48 + let i_ldind_u2 = 0x49 + let i_ldind_i4 = 0x4a + let i_ldind_u4 = 0x4b + let i_ldind_i8 = 0x4c + let i_ldind_i = 0x4d + let i_ldind_r4 = 0x4e + let i_ldind_r8 = 0x4f + let i_ldind_ref = 0x50 + let i_stind_ref = 0x51 + let i_stind_i1 = 0x52 + let i_stind_i2 = 0x53 + let i_stind_i4 = 0x54 + let i_stind_i8 = 0x55 + let i_stind_r4 = 0x56 + let i_stind_r8 = 0x57 + let i_add = 0x58 + let i_sub = 0x59 + let i_mul = 0x5a + let i_div = 0x5b + let i_div_un = 0x5c + let i_rem = 0x5d + let i_rem_un = 0x5e + let i_and = 0x5f + let i_or = 0x60 + let i_xor = 0x61 + let i_shl = 0x62 + let i_shr = 0x63 + let i_shr_un = 0x64 + let i_neg = 0x65 + let i_not = 0x66 + let i_conv_i1 = 0x67 + let i_conv_i2 = 0x68 + let i_conv_i4 = 0x69 + let i_conv_i8 = 0x6a + let i_conv_r4 = 0x6b + let i_conv_r8 = 0x6c + let i_conv_u4 = 0x6d + let i_conv_u8 = 0x6e + let i_callvirt = 0x6f + let i_cpobj = 0x70 + let i_ldobj = 0x71 + let i_ldstr = 0x72 + let i_newobj = 0x73 + let i_castclass = 0x74 + let i_isinst = 0x75 + let i_conv_r_un = 0x76 + let i_unbox = 0x79 + let i_throw = 0x7a + let i_ldfld = 0x7b + let i_ldflda = 0x7c + let i_stfld = 0x7d + let i_ldsfld = 0x7e + let i_ldsflda = 0x7f + let i_stsfld = 0x80 + let i_stobj = 0x81 + let i_conv_ovf_i1_un= 0x82 + let i_conv_ovf_i2_un= 0x83 + let i_conv_ovf_i4_un= 0x84 + let i_conv_ovf_i8_un= 0x85 + let i_conv_ovf_u1_un= 0x86 + let i_conv_ovf_u2_un= 0x87 + let i_conv_ovf_u4_un= 0x88 + let i_conv_ovf_u8_un= 0x89 + let i_conv_ovf_i_un = 0x8a + let i_conv_ovf_u_un = 0x8b + let i_box = 0x8c + let i_newarr = 0x8d + let i_ldlen = 0x8e + let i_ldelema = 0x8f + let i_ldelem_i1 = 0x90 + let i_ldelem_u1 = 0x91 + let i_ldelem_i2 = 0x92 + let i_ldelem_u2 = 0x93 + let i_ldelem_i4 = 0x94 + let i_ldelem_u4 = 0x95 + let i_ldelem_i8 = 0x96 + let i_ldelem_i = 0x97 + let i_ldelem_r4 = 0x98 + let i_ldelem_r8 = 0x99 + let i_ldelem_ref = 0x9a + let i_stelem_i = 0x9b + let i_stelem_i1 = 0x9c + let i_stelem_i2 = 0x9d + let i_stelem_i4 = 0x9e + let i_stelem_i8 = 0x9f + let i_stelem_r4 = 0xa0 + let i_stelem_r8 = 0xa1 + let i_stelem_ref = 0xa2 + let i_conv_ovf_i1 = 0xb3 + let i_conv_ovf_u1 = 0xb4 + let i_conv_ovf_i2 = 0xb5 + let i_conv_ovf_u2 = 0xb6 + let i_conv_ovf_i4 = 0xb7 + let i_conv_ovf_u4 = 0xb8 + let i_conv_ovf_i8 = 0xb9 + let i_conv_ovf_u8 = 0xba + let i_refanyval = 0xc2 + let i_ckfinite = 0xc3 + let i_mkrefany = 0xc6 + let i_ldtoken = 0xd0 + let i_conv_u2 = 0xd1 + let i_conv_u1 = 0xd2 + let i_conv_i = 0xd3 + let i_conv_ovf_i = 0xd4 + let i_conv_ovf_u = 0xd5 + let i_add_ovf = 0xd6 + let i_add_ovf_un = 0xd7 + let i_mul_ovf = 0xd8 + let i_mul_ovf_un = 0xd9 + let i_sub_ovf = 0xda + let i_sub_ovf_un = 0xdb + let i_endfinally = 0xdc + let i_leave = 0xdd + let i_leave_s = 0xde + let i_stind_i = 0xdf + let i_conv_u = 0xe0 + let i_arglist = 0xfe00 + let i_ceq = 0xfe01 + let i_cgt = 0xfe02 + let i_cgt_un = 0xfe03 + let i_clt = 0xfe04 + let i_clt_un = 0xfe05 + let i_ldftn = 0xfe06 + let i_ldvirtftn = 0xfe07 + let i_ldarg = 0xfe09 + let i_ldarga = 0xfe0a + let i_starg = 0xfe0b + let i_ldloc = 0xfe0c + let i_ldloca = 0xfe0d + let i_stloc = 0xfe0e + let i_localloc = 0xfe0f + let i_endfilter = 0xfe11 + let i_unaligned = 0xfe12 + let i_volatile = 0xfe13 + let i_constrained = 0xfe16 + let i_readonly = 0xfe1e + let i_tail = 0xfe14 + let i_initobj = 0xfe15 + let i_cpblk = 0xfe17 + let i_initblk = 0xfe18 + let i_rethrow = 0xfe1a + let i_sizeof = 0xfe1c + let i_refanytype = 0xfe1d + + let i_ldelem_any = 0xa3 + let i_stelem_any = 0xa4 + let i_unbox_any = 0xa5 + + let mk_ldc i = I_ldc (DT_I4, ILConst.I4 i) + let mk_ldc_i8 i = I_ldc (DT_I8, ILConst.I8 i) + let mkNormalCall mspec = I_call (Normalcall, mspec, None) + let mkILFormalGenericArgs numtypars (n:int) = + Array.init n (fun i -> ILType.Var (numtypars + i)) + + + let noArgInstrs = + lazy [ i_ldc_i4_0, mk_ldc 0 + i_ldc_i4_1, mk_ldc 1 + i_ldc_i4_2, mk_ldc 2 + i_ldc_i4_3, mk_ldc 3 + i_ldc_i4_4, mk_ldc 4 + i_ldc_i4_5, mk_ldc 5 + i_ldc_i4_6, mk_ldc 6 + i_ldc_i4_7, mk_ldc 7 + i_ldc_i4_8, mk_ldc 8 + i_ldc_i4_m1, mk_ldc -1 + 0x0a, I_stloc 0 + 0x0b, I_stloc 1 + 0x0c, I_stloc 2 + 0x0d, I_stloc 3 + 0x06, I_ldloc 0 + 0x07, I_ldloc 1 + 0x08, I_ldloc 2 + 0x09, I_ldloc 3 + 0x02, I_ldarg 0 + 0x03, I_ldarg 1 + 0x04, I_ldarg 2 + 0x05, I_ldarg 3 + 0x2a, I_ret + 0x58, I_add + 0xd6, I_add_ovf + 0xd7, I_add_ovf_un + 0x5f, I_and + 0x5b, I_div + 0x5c, I_div_un + 0xfe01, I_ceq + 0xfe02, I_cgt + 0xfe03, I_cgt_un + 0xfe04, I_clt + 0xfe05, I_clt_un + 0x67, I_conv DT_I1 + 0x68, I_conv DT_I2 + 0x69, I_conv DT_I4 + 0x6a, I_conv DT_I8 + 0xd3, I_conv DT_I + 0x6b, I_conv DT_R4 + 0x6c, I_conv DT_R8 + 0xd2, I_conv DT_U1 + 0xd1, I_conv DT_U2 + 0x6d, I_conv DT_U4 + 0x6e, I_conv DT_U8 + 0xe0, I_conv DT_U + 0x76, I_conv DT_R + 0xb3, I_conv_ovf DT_I1 + 0xb5, I_conv_ovf DT_I2 + 0xb7, I_conv_ovf DT_I4 + 0xb9, I_conv_ovf DT_I8 + 0xd4, I_conv_ovf DT_I + 0xb4, I_conv_ovf DT_U1 + 0xb6, I_conv_ovf DT_U2 + 0xb8, I_conv_ovf DT_U4 + 0xba, I_conv_ovf DT_U8 + 0xd5, I_conv_ovf DT_U + 0x82, I_conv_ovf_un DT_I1 + 0x83, I_conv_ovf_un DT_I2 + 0x84, I_conv_ovf_un DT_I4 + 0x85, I_conv_ovf_un DT_I8 + 0x8a, I_conv_ovf_un DT_I + 0x86, I_conv_ovf_un DT_U1 + 0x87, I_conv_ovf_un DT_U2 + 0x88, I_conv_ovf_un DT_U4 + 0x89, I_conv_ovf_un DT_U8 + 0x8b, I_conv_ovf_un DT_U + 0x9c, I_stelem DT_I1 + 0x9d, I_stelem DT_I2 + 0x9e, I_stelem DT_I4 + 0x9f, I_stelem DT_I8 + 0xa0, I_stelem DT_R4 + 0xa1, I_stelem DT_R8 + 0x9b, I_stelem DT_I + 0xa2, I_stelem DT_REF + 0x90, I_ldelem DT_I1 + 0x92, I_ldelem DT_I2 + 0x94, I_ldelem DT_I4 + 0x96, I_ldelem DT_I8 + 0x91, I_ldelem DT_U1 + 0x93, I_ldelem DT_U2 + 0x95, I_ldelem DT_U4 + 0x98, I_ldelem DT_R4 + 0x99, I_ldelem DT_R8 + 0x97, I_ldelem DT_I + 0x9a, I_ldelem DT_REF + 0x5a, I_mul + 0xd8, I_mul_ovf + 0xd9, I_mul_ovf_un + 0x5d, I_rem + 0x5e, I_rem_un + 0x62, I_shl + 0x63, I_shr + 0x64, I_shr_un + 0x59, I_sub + 0xda, I_sub_ovf + 0xdb, I_sub_ovf_un + 0x61, I_xor + 0x60, I_or + 0x65, I_neg + 0x66, I_not + i_ldnull, I_ldnull + i_dup, I_dup + i_pop, I_pop + i_ckfinite, I_ckfinite + i_nop, I_nop + i_break, I_break + i_arglist, I_arglist + i_endfilter, I_endfilter + i_endfinally, I_endfinally + i_refanytype, I_refanytype + i_localloc, I_localloc + i_throw, I_throw + i_ldlen, I_ldlen + i_rethrow, I_rethrow ] + + let isNoArgInstr i = + match i with + | I_ldc (DT_I4, ILConst.I4 n) when -1 <= n && n <= 8 -> true + | I_stloc n | I_ldloc n | I_ldarg n when n <= 3 -> true + | I_ret + | I_add + | I_add_ovf + | I_add_ovf_un + | I_and + | I_div + | I_div_un + | I_ceq + | I_cgt + | I_cgt_un + | I_clt + | I_clt_un + | I_conv DT_I1 + | I_conv DT_I2 + | I_conv DT_I4 + | I_conv DT_I8 + | I_conv DT_I + | I_conv DT_R4 + | I_conv DT_R8 + | I_conv DT_U1 + | I_conv DT_U2 + | I_conv DT_U4 + | I_conv DT_U8 + | I_conv DT_U + | I_conv DT_R + | I_conv_ovf DT_I1 + | I_conv_ovf DT_I2 + | I_conv_ovf DT_I4 + | I_conv_ovf DT_I8 + | I_conv_ovf DT_I + | I_conv_ovf DT_U1 + | I_conv_ovf DT_U2 + | I_conv_ovf DT_U4 + | I_conv_ovf DT_U8 + | I_conv_ovf DT_U + | I_conv_ovf_un DT_I1 + | I_conv_ovf_un DT_I2 + | I_conv_ovf_un DT_I4 + | I_conv_ovf_un DT_I8 + | I_conv_ovf_un DT_I + | I_conv_ovf_un DT_U1 + | I_conv_ovf_un DT_U2 + | I_conv_ovf_un DT_U4 + | I_conv_ovf_un DT_U8 + | I_conv_ovf_un DT_U + | I_stelem DT_I1 + | I_stelem DT_I2 + | I_stelem DT_I4 + | I_stelem DT_I8 + | I_stelem DT_R4 + | I_stelem DT_R8 + | I_stelem DT_I + | I_stelem DT_REF + | I_ldelem DT_I1 + | I_ldelem DT_I2 + | I_ldelem DT_I4 + | I_ldelem DT_I8 + | I_ldelem DT_U1 + | I_ldelem DT_U2 + | I_ldelem DT_U4 + | I_ldelem DT_R4 + | I_ldelem DT_R8 + | I_ldelem DT_I + | I_ldelem DT_REF + | I_mul + | I_mul_ovf + | I_mul_ovf_un + | I_rem + | I_rem_un + | I_shl + | I_shr + | I_shr_un + | I_sub + | I_sub_ovf + | I_sub_ovf_un + | I_xor + | I_or + | I_neg + | I_not + | I_ldnull + | I_dup + | I_pop + | I_ckfinite + | I_nop + | I_break + | I_arglist + | I_endfilter + | I_endfinally + | I_refanytype + | I_localloc + | I_throw + | I_ldlen + | I_rethrow -> true + | _ -> false + + let ILCmpInstrMap = + lazy ( + let dict = Dictionary 12 + dict.Add (I_beq , i_beq ) + dict.Add (I_bgt , i_bgt ) + dict.Add (I_bgt_un , i_bgt_un ) + dict.Add (I_bge , i_bge ) + dict.Add (I_bge_un , i_bge_un ) + dict.Add (I_ble , i_ble ) + dict.Add (I_ble_un , i_ble_un ) + dict.Add (I_blt , i_blt ) + dict.Add (I_blt_un , i_blt_un ) + dict.Add (I_bne_un , i_bne_un ) + dict.Add (I_brfalse , i_brfalse ) + dict.Add (I_brtrue , i_brtrue ) + dict + ) + + let ILCmpInstrRevMap = + lazy ( + let dict = Dictionary 12 + dict.Add ( I_beq , i_beq_s ) + dict.Add ( I_bgt , i_bgt_s ) + dict.Add ( I_bgt_un , i_bgt_un_s ) + dict.Add ( I_bge , i_bge_s ) + dict.Add ( I_bge_un , i_bge_un_s ) + dict.Add ( I_ble , i_ble_s ) + dict.Add ( I_ble_un , i_ble_un_s ) + dict.Add ( I_blt , i_blt_s ) + dict.Add ( I_blt_un , i_blt_un_s ) + dict.Add ( I_bne_un , i_bne_un_s ) + dict.Add ( I_brfalse , i_brfalse_s ) + dict.Add ( I_brtrue , i_brtrue_s ) + dict + ) + + // From corhdr.h + + let nt_VOID = 0x1uy + let nt_BOOLEAN = 0x2uy + let nt_I1 = 0x3uy + let nt_U1 = 0x4uy + let nt_I2 = 0x5uy + let nt_U2 = 0x6uy + let nt_I4 = 0x7uy + let nt_U4 = 0x8uy + let nt_I8 = 0x9uy + let nt_U8 = 0xAuy + let nt_R4 = 0xBuy + let nt_R8 = 0xCuy + let nt_SYSCHAR = 0xDuy + let nt_VARIANT = 0xEuy + let nt_CURRENCY = 0xFuy + let nt_PTR = 0x10uy + let nt_DECIMAL = 0x11uy + let nt_DATE = 0x12uy + let nt_BSTR = 0x13uy + let nt_LPSTR = 0x14uy + let nt_LPWSTR = 0x15uy + let nt_LPTSTR = 0x16uy + let nt_FIXEDSYSSTRING = 0x17uy + let nt_OBJECTREF = 0x18uy + let nt_IUNKNOWN = 0x19uy + let nt_IDISPATCH = 0x1Auy + let nt_STRUCT = 0x1Buy + let nt_INTF = 0x1Cuy + let nt_SAFEARRAY = 0x1Duy + let nt_FIXEDARRAY = 0x1Euy + let nt_INT = 0x1Fuy + let nt_UINT = 0x20uy + let nt_NESTEDSTRUCT = 0x21uy + let nt_BYVALSTR = 0x22uy + let nt_ANSIBSTR = 0x23uy + let nt_TBSTR = 0x24uy + let nt_VARIANTBOOL = 0x25uy + let nt_FUNC = 0x26uy + let nt_ASANY = 0x28uy + let nt_ARRAY = 0x2Auy + let nt_LPSTRUCT = 0x2Buy + let nt_CUSTOMMARSHALER = 0x2Cuy + let nt_ERROR = 0x2Duy + let nt_MAX = 0x50uy + + // From c:/clrenv.i386/Crt/Inc/i386/hs.h + + let vt_EMPTY = 0 + let vt_NULL = 1 + let vt_I2 = 2 + let vt_I4 = 3 + let vt_R4 = 4 + let vt_R8 = 5 + let vt_CY = 6 + let vt_DATE = 7 + let vt_BSTR = 8 + let vt_DISPATCH = 9 + let vt_ERROR = 10 + let vt_BOOL = 11 + let vt_VARIANT = 12 + let vt_UNKNOWN = 13 + let vt_DECIMAL = 14 + let vt_I1 = 16 + let vt_UI1 = 17 + let vt_UI2 = 18 + let vt_UI4 = 19 + let vt_I8 = 20 + let vt_UI8 = 21 + let vt_INT = 22 + let vt_UINT = 23 + let vt_VOID = 24 + let vt_HRESULT = 25 + let vt_PTR = 26 + let vt_SAFEARRAY = 27 + let vt_CARRAY = 28 + let vt_USERDEFINED = 29 + let vt_LPSTR = 30 + let vt_LPWSTR = 31 + let vt_RECORD = 36 + let vt_FILETIME = 64 + let vt_BLOB = 65 + let vt_STREAM = 66 + let vt_STORAGE = 67 + let vt_STREAMED_OBJECT = 68 + let vt_STORED_OBJECT = 69 + let vt_BLOB_OBJECT = 70 + let vt_CF = 71 + let vt_CLSID = 72 + let vt_VECTOR = 0x1000 + let vt_ARRAY = 0x2000 + let vt_BYREF = 0x4000 + + + + let e_CorILMethod_TinyFormat = 0x02uy + let e_CorILMethod_FatFormat = 0x03uy + let e_CorILMethod_FormatMask = 0x03uy + let e_CorILMethod_MoreSects = 0x08uy + let e_CorILMethod_InitLocals = 0x10uy + + + let e_CorILMethod_Sect_EHTable = 0x1uy + let e_CorILMethod_Sect_FatFormat = 0x40uy + let e_CorILMethod_Sect_MoreSects = 0x80uy + + let e_COR_ILEXCEPTION_CLAUSE_EXCEPTION = 0x0 + let e_COR_ILEXCEPTION_CLAUSE_FILTER = 0x1 + let e_COR_ILEXCEPTION_CLAUSE_FINALLY = 0x2 + let e_COR_ILEXCEPTION_CLAUSE_FAULT = 0x4 + + + module Bytes = + + let dWw1 n = int32 ((n >>> 32) &&& 0xFFFFFFFFL) + let dWw0 n = int32 (n &&& 0xFFFFFFFFL) + + let get (b:byte[]) n = int32 (Array.get b n) + let zeroCreate n: byte[] = Array.zeroCreate n + + let sub ( b:byte[]) s l = Array.sub b s l + let blit (a:byte[]) b c d e = Array.blit a b c d e + + let ofInt32Array (arr:int[]) = Array.init arr.Length (fun i -> byte arr.[i]) + + let stringAsUtf8NullTerminated (s:string) = + Array.append (Encoding.UTF8.GetBytes s) (ofInt32Array [| 0x0 |]) + + let stringAsUnicodeNullTerminated (s:string) = + Array.append (Encoding.Unicode.GetBytes s) (ofInt32Array [| 0x0;0x0 |]) + + type ByteStream = + { bytes: byte[] + mutable pos: int + max: int } + member b.ReadByte() = + if b.pos >= b.max then failwith "end of stream" + let res = b.bytes.[b.pos] + b.pos <- b.pos + 1 + res + member b.ReadUtf8String n = + let res = Encoding.UTF8.GetString(b.bytes, b.pos, n) + b.pos <- b.pos + n; res + + static member FromBytes (b:byte[], n, len) = + if n < 0 || (n+len) > b.Length then failwith "FromBytes" + { bytes = b; pos = n; max = n+len } + + member b.ReadBytes n = + if b.pos + n > b.max then failwith "ReadBytes: end of stream" + let res = Bytes.sub b.bytes b.pos n + b.pos <- b.pos + n + res + + member b.Position = b.pos + + + type ByteBuffer = + { mutable bbArray: byte[] + mutable bbCurrent: int } + + member buf.Ensure newSize = + let oldBufSize = buf.bbArray.Length + if newSize > oldBufSize then + let old = buf.bbArray + buf.bbArray <- Bytes.zeroCreate (max newSize (oldBufSize * 2)) + Bytes.blit old 0 buf.bbArray 0 buf.bbCurrent + + member buf.Close () = Bytes.sub buf.bbArray 0 buf.bbCurrent + + member buf.EmitIntAsByte (i:int) = + let newSize = buf.bbCurrent + 1 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- byte i + buf.bbCurrent <- newSize + + member buf.EmitByte (b:byte) = buf.EmitIntAsByte (int b) + + member buf.EmitIntsAsBytes (arr:int[]) = + let n = arr.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + let bbarr = buf.bbArray + let bbbase = buf.bbCurrent + for i = 0 to n - 1 do + bbarr.[bbbase + i] <- byte arr.[i] + buf.bbCurrent <- newSize + + member bb.FixupInt32 pos n = + bb.bbArray.[pos] <- (b0 n |> byte) + bb.bbArray.[pos + 1] <- (b1 n |> byte) + bb.bbArray.[pos + 2] <- (b2 n |> byte) + bb.bbArray.[pos + 3] <- (b3 n |> byte) + + member buf.EmitInt32 n = + let newSize = buf.bbCurrent + 4 + buf.Ensure newSize + buf.FixupInt32 buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitBytes (i:byte[]) = + let n = i.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + Bytes.blit i 0 buf.bbArray buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitInt32AsUInt16 n = + let newSize = buf.bbCurrent + 2 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- (b0 n |> byte) + buf.bbArray.[buf.bbCurrent + 1] <- (b1 n |> byte) + buf.bbCurrent <- newSize + + member buf.EmitBoolAsByte (b:bool) = buf.EmitIntAsByte (if b then 1 else 0) + + member buf.EmitUInt16 (x:uint16) = buf.EmitInt32AsUInt16 (int32 x) + + member buf.EmitInt64 x = + buf.EmitInt32 (Bytes.dWw0 x) + buf.EmitInt32 (Bytes.dWw1 x) + + member buf.Position = buf.bbCurrent + + static member Create sz = + { bbArray=Bytes.zeroCreate sz + bbCurrent = 0 } + + /// Z32 = compressed unsigned integer + static member Z32Size n = + if n <= 0x7F then 1 + elif n <= 0x3FFF then 2 + else 4 + + /// Emit int32 as compressed unsigned integer + member buf.EmitZ32 n = + if n >= 0 && n <= 0x7F then + buf.EmitIntAsByte n + elif n >= 0x80 && n <= 0x3FFF then + buf.EmitIntAsByte (0x80 ||| (n >>> 8)) + buf.EmitIntAsByte (n &&& 0xFF) + else + buf.EmitIntAsByte (0xc0l ||| ((n >>> 24) &&& 0xFF)) + buf.EmitIntAsByte ( (n >>> 16) &&& 0xFF) + buf.EmitIntAsByte ( (n >>> 8) &&& 0xFF) + buf.EmitIntAsByte ( n &&& 0xFF) + + static member Z32 n = let bb = ByteBuffer.Create (ByteBuffer.Z32Size n) in bb.EmitZ32 n; bb.Close() + + member buf.EmitPadding n = + for i = 0 to n-1 do + buf.EmitByte 0x0uy + + // Emit compressed untagged integer + member buf.EmitZUntaggedIndex big idx = + if big then buf.EmitInt32 idx + elif idx > 0xffff then failwith "EmitZUntaggedIndex: too big for small address or simple index" + else buf.EmitInt32AsUInt16 idx + + // Emit compressed tagged integer + member buf.EmitZTaggedIndex tag nbits big idx = + let idx2 = (idx <<< nbits) ||| tag + if big then buf.EmitInt32 idx2 + else buf.EmitInt32AsUInt16 idx2 + + //--------------------------------------------------------------------- + // Byte, byte array fragments and other concrete representations + // manipulations. + //--------------------------------------------------------------------- + + let bitsOfSingle (x:float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x), 0) + let bitsOfDouble (x:float) = System.BitConverter.DoubleToInt64Bits(x) + + type ByteFile(bytes:byte[]) = + + member __.ReadByte addr = bytes.[addr] + + member __.ReadBytes addr len = Array.sub bytes addr len + + member __.CountUtf8String addr = + let mutable p = addr + while bytes.[p] <> 0uy do + p <- p + 1 + p - addr + + member m.ReadUTF8String addr = + let n = m.CountUtf8String addr + Encoding.UTF8.GetString (bytes, addr, n) + + member is.ReadInt32 addr = + let b0 = is.ReadByte addr + let b1 = is.ReadByte (addr+1) + let b2 = is.ReadByte (addr+2) + let b3 = is.ReadByte (addr+3) + int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) + + member is.ReadUInt16 addr = + let b0 = is.ReadByte addr + let b1 = is.ReadByte (addr+1) + uint16 b0 ||| (uint16 b1 <<< 8) + + [] + module Reader = + let seekReadByte (is:ByteFile) addr = is.ReadByte addr + let seekReadBytes (is:ByteFile) addr len = is.ReadBytes addr len + let seekReadInt32 (is:ByteFile) addr = is.ReadInt32 addr + let seekReadUInt16 (is:ByteFile) addr = is.ReadUInt16 addr + + let seekReadByteAsInt32 is addr = int32 (seekReadByte is addr) + + let seekReadInt64 is addr = + let b0 = seekReadByte is addr + let b1 = seekReadByte is (addr+1) + let b2 = seekReadByte is (addr+2) + let b3 = seekReadByte is (addr+3) + let b4 = seekReadByte is (addr+4) + let b5 = seekReadByte is (addr+5) + let b6 = seekReadByte is (addr+6) + let b7 = seekReadByte is (addr+7) + int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| + (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56) + + let seekReadUInt16AsInt32 is addr = int32 (seekReadUInt16 is addr) + + let seekReadCompressedUInt32 is addr = + let b0 = seekReadByte is addr + if b0 <= 0x7Fuy then int b0, addr+1 + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1 = seekReadByteAsInt32 is (addr+1) + (int b0 <<< 8) ||| int b1, addr+2 + else + let b0 = b0 &&& 0x3Fuy + let b1 = seekReadByteAsInt32 is (addr+1) + let b2 = seekReadByteAsInt32 is (addr+2) + let b3 = seekReadByteAsInt32 is (addr+3) + (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, addr+4 + + let seekReadSByte is addr = sbyte (seekReadByte is addr) + + let rec seekCountUtf8String is addr n = + let c = seekReadByteAsInt32 is addr + if c = 0 then n + else seekCountUtf8String is (addr+1) (n+1) + + let seekReadUTF8String is addr = + let n = seekCountUtf8String is addr 0 + let bytes = seekReadBytes is addr n + Encoding.UTF8.GetString (bytes, 0, bytes.Length) + + let seekReadBlob is addr = + let len, addr = seekReadCompressedUInt32 is addr + seekReadBytes is addr len + + let seekReadUserString is addr = + let len, addr = seekReadCompressedUInt32 is addr + let bytes = seekReadBytes is addr (len - 1) + Encoding.Unicode.GetString(bytes, 0, bytes.Length) + + let seekReadGuid is addr = seekReadBytes is addr 0x10 + + let seekReadUncodedToken is addr = + i32ToUncodedToken (seekReadInt32 is addr) + + let sigptrGetByte (bytes:byte[]) sigptr = + bytes.[sigptr], sigptr + 1 + + let sigptrGetBool bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + (b0 = 0x01uy) , sigptr + + let sigptrGetSByte bytes sigptr = + let i, sigptr = sigptrGetByte bytes sigptr + sbyte i, sigptr + + let sigptrGetUInt16 bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + let b1, sigptr = sigptrGetByte bytes sigptr + uint16 (int b0 ||| (int b1 <<< 8)), sigptr + + let sigptrGetInt16 bytes sigptr = + let u, sigptr = sigptrGetUInt16 bytes sigptr + int16 u, sigptr + + let sigptrGetInt32 (bytes: byte[]) sigptr = + let b0 = bytes.[sigptr] + let b1 = bytes.[sigptr+1] + let b2 = bytes.[sigptr+2] + let b3 = bytes.[sigptr+3] + let res = int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) + res, sigptr + 4 + + let sigptrGetUInt32 bytes sigptr = + let u, sigptr = sigptrGetInt32 bytes sigptr + uint32 u, sigptr + + let sigptrGetUInt64 bytes sigptr = + let u0, sigptr = sigptrGetUInt32 bytes sigptr + let u1, sigptr = sigptrGetUInt32 bytes sigptr + (uint64 u0 ||| (uint64 u1 <<< 32)), sigptr + + let sigptrGetInt64 bytes sigptr = + let u, sigptr = sigptrGetUInt64 bytes sigptr + int64 u, sigptr + + let sigptrGetSingle bytes sigptr = + let u, sigptr = sigptrGetInt32 bytes sigptr + singleOfBits u, sigptr + + let sigptrGetDouble bytes sigptr = + let u, sigptr = sigptrGetInt64 bytes sigptr + doubleOfBits u, sigptr + + let sigptrGetZInt32 bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + if b0 <= 0x7Fuy then int b0, sigptr + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1, sigptr = sigptrGetByte bytes sigptr + (int b0 <<< 8) ||| int b1, sigptr + else + let b0 = b0 &&& 0x3Fuy + let b1, sigptr = sigptrGetByte bytes sigptr + let b2, sigptr = sigptrGetByte bytes sigptr + let b3, sigptr = sigptrGetByte bytes sigptr + (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, sigptr + + let rec sigptrFoldAcc f n (bytes:byte[]) (sigptr:int) i acc = + if i < n then + let x, sp = f bytes sigptr + sigptrFoldAcc f n bytes sp (i+1) (x::acc) + else + Array.ofList (List.rev acc), sigptr + + let sigptrFold f n (bytes:byte[]) (sigptr:int) = + sigptrFoldAcc f n bytes sigptr 0 [] + + let sigptrGetBytes n (bytes:byte[]) sigptr = + let res = Array.zeroCreate n + for i = 0 to (n - 1) do + res.[i] <- bytes.[sigptr + i] + res, sigptr + n + + let sigptrGetString n bytes sigptr = + let bytearray, sigptr = sigptrGetBytes n bytes sigptr + (Encoding.UTF8.GetString(bytearray, 0, bytearray.Length)), sigptr + + let chunk sz next = ({addr=next; size=sz}, next + sz) + let nochunk next = ({addr= 0x0;size= 0x0; } , next) + + + let kindAssemblyRef = ILRowKind [ UShort; UShort; UShort; UShort; ULong; Blob; SString; SString; Blob; ] + let kindModuleRef = ILRowKind [ SString ] + let kindFileRef = ILRowKind [ ULong; SString; Blob ] + let kindTypeRef = ILRowKind [ ResolutionScope; SString; SString ] + let kindTypeSpec = ILRowKind [ Blob ] + let kindTypeDef = ILRowKind [ ULong; SString; SString; TypeDefOrRefOrSpec; SimpleIndex ILTableNames.Field; SimpleIndex ILTableNames.Method ] + let kindPropertyMap = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.Property ] + let kindEventMap = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.Event ] + let kindInterfaceImpl = ILRowKind [ SimpleIndex ILTableNames.TypeDef; TypeDefOrRefOrSpec ] + let kindNested = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.TypeDef ] + let kindCustomAttribute = ILRowKind [ HasCustomAttribute; CustomAttributeType; Blob ] + let kindDeclSecurity = ILRowKind [ UShort; HasDeclSecurity; Blob ] + let kindMemberRef = ILRowKind [ MemberRefParent; SString; Blob ] + let kindStandAloneSig = ILRowKind [ Blob ] + let kindFieldDef = ILRowKind [ UShort; SString; Blob ] + let kindFieldRVA = ILRowKind [ Data; SimpleIndex ILTableNames.Field ] + let kindFieldMarshal = ILRowKind [ HasFieldMarshal; Blob ] + let kindConstant = ILRowKind [ UShort;HasConstant; Blob ] + let kindFieldLayout = ILRowKind [ ULong; SimpleIndex ILTableNames.Field ] + let kindParam = ILRowKind [ UShort; UShort; SString ] + let kindMethodDef = ILRowKind [ ULong; UShort; UShort; SString; Blob; SimpleIndex ILTableNames.Param ] + let kindMethodImpl = ILRowKind [ SimpleIndex ILTableNames.TypeDef; MethodDefOrRef; MethodDefOrRef ] + let kindImplMap = ILRowKind [ UShort; MemberForwarded; SString; SimpleIndex ILTableNames.ModuleRef ] + let kindMethodSemantics = ILRowKind [ UShort; SimpleIndex ILTableNames.Method; HasSemantics ] + let kindProperty = ILRowKind [ UShort; SString; Blob ] + let kindEvent = ILRowKind [ UShort; SString; TypeDefOrRefOrSpec ] + let kindManifestResource = ILRowKind [ ULong; ULong; SString; Implementation ] + let kindClassLayout = ILRowKind [ UShort; ULong; SimpleIndex ILTableNames.TypeDef ] + let kindExportedType = ILRowKind [ ULong; ULong; SString; SString; Implementation ] + let kindAssembly = ILRowKind [ ULong; UShort; UShort; UShort; UShort; ULong; Blob; SString; SString ] + let kindGenericParam_v1_1 = ILRowKind [ UShort; UShort; TypeOrMethodDef; SString; TypeDefOrRefOrSpec ] + let kindGenericParam_v2_0 = ILRowKind [ UShort; UShort; TypeOrMethodDef; SString ] + let kindMethodSpec = ILRowKind [ MethodDefOrRef; Blob ] + let kindGenericParamConstraint = ILRowKind [ SimpleIndex ILTableNames.GenericParam; TypeDefOrRefOrSpec ] + let kindModule = ILRowKind [ UShort; SString; GGuid; GGuid; GGuid ] + let kindIllegal = ILRowKind [ ] + + let hcCompare (TaggedIndex((t1: HasConstantTag), (idx1:int))) (TaggedIndex((t2: HasConstantTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hsCompare (TaggedIndex((t1:HasSemanticsTag), (idx1:int))) (TaggedIndex((t2:HasSemanticsTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hcaCompare (TaggedIndex((t1:HasCustomAttributeTag), (idx1:int))) (TaggedIndex((t2:HasCustomAttributeTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let mfCompare (TaggedIndex((t1:MemberForwardedTag), (idx1:int))) (TaggedIndex((t2:MemberForwardedTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hdsCompare (TaggedIndex((t1:HasDeclSecurityTag), (idx1:int))) (TaggedIndex((t2:HasDeclSecurityTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hfmCompare (TaggedIndex((t1:HasFieldMarshalTag), idx1)) (TaggedIndex((t2:HasFieldMarshalTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let tomdCompare (TaggedIndex((t1:TypeOrMethodDefTag), idx1)) (TaggedIndex((t2:TypeOrMethodDefTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let simpleIndexCompare (idx1:int) (idx2:int) = + compare idx1 idx2 + + let mkCacheInt32 lowMem _infile _nm _sz = + if lowMem then (fun f x -> f x) else + let cache = ref null + fun f (idx:int32) -> + let cache = + match !cache with + | null -> cache := new Dictionary(11) + | _ -> () + !cache + let mutable res = Unchecked.defaultof<_> + let ok = cache.TryGetValue(idx, &res) + if ok then + res + else + let res = f idx + cache.[idx] <- res; + res + + let mkCacheGeneric lowMem _inbase _nm _sz = + if lowMem then (fun f x -> f x) else + let cache = ref null + fun f (idx :'T) -> + let cache = + match !cache with + | null -> cache := new Dictionary<_, _>(11 (* sz:int *) ) + | _ -> () + !cache + if cache.ContainsKey idx then cache.[idx] + else let res = f idx in cache.[idx] <- res; res + + let seekFindRow numRows rowChooser = + let mutable i = 1 + while (i <= numRows && not (rowChooser i)) do + i <- i + 1; + i + + // search for rows satisfying predicate + let seekReadIndexedRows (numRows, rowReader, keyFunc, keyComparer, binaryChop, rowConverter) = + if binaryChop then + let mutable low = 0 + let mutable high = numRows + 1 + begin + let mutable fin = false + while not fin do + if high - low <= 1 then + fin <- true + else + let mid = (low + high) / 2 + let midrow = rowReader mid + let c = keyComparer (keyFunc midrow) + if c > 0 then + low <- mid + elif c < 0 then + high <- mid + else + fin <- true + end; + let mutable res = [] + if high - low > 1 then + // now read off rows, forward and backwards + let mid = (low + high) / 2 + // read forward + begin + let mutable fin = false + let mutable curr = mid + while not fin do + if curr > numRows then + fin <- true; + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res; + else + fin <- true; + curr <- curr + 1; + done; + end; + res <- List.rev res; + // read backwards + begin + let mutable fin = false + let mutable curr = mid - 1 + while not fin do + if curr = 0 then + fin <- true + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res; + else + fin <- true; + curr <- curr - 1; + end; + res |> List.toArray + else + let res = ref [] + for i = 1 to numRows do + let rowinfo = rowReader i + if keyComparer (keyFunc rowinfo) = 0 then + res := rowConverter rowinfo :: !res; + List.rev !res |> List.toArray + + + let seekReadOptionalIndexedRow (info) = + match seekReadIndexedRows info with + | [| |] -> None + | xs -> Some xs.[0] + + let seekReadIndexedRow (info) = + match seekReadOptionalIndexedRow info with + | Some row -> row + | None -> failwith ("no row found for key when indexing table") + + let getName (ltd: Lazy) = + let td = ltd.Force() + (td.Name, ltd) + + let emptyILEvents = { new ILEventDefs with member __.Entries = [| |] } + let emptyILProperties = { new ILPropertyDefs with member __.Entries = [| |] } + let emptyILTypeDefs = ILTypeDefs (lazy [| |]) + let emptyILCustomAttrs = { new ILCustomAttrs with member __.Entries = [| |] } + let mkILCustomAttrs x = { new ILCustomAttrs with member __.Entries = x } + let emptyILMethodImpls = { new ILMethodImplDefs with member __.Entries = [| |] } + let emptyILMethods = ILMethodDefs (lazy [| |]) + let emptyILFields = { new ILFieldDefs with member __.Entries = [| |] } + + let mkILTy boxed tspec = + match boxed with + | AsObject -> ILType.Boxed tspec + | _ -> ILType.Value tspec + + let mkILArr1DTy ty = ILType.Array (ILArrayShape.SingleDimensional, ty) + + let typeNameForGlobalFunctions = "" + + let mkILNonGenericTySpec tref = ILTypeSpec (tref, [| |]) + let mkILTypeForGlobalFunctions scoref = ILType.Boxed (mkILNonGenericTySpec (ILTypeRef(ILTypeRefScope.Top scoref, UNone, typeNameForGlobalFunctions))) + let mkILArrTy (ty, shape) = ILType.Array(shape, ty) + + let mkILMethSpecInTyRaw (typ:ILType, cc, nm, args, rty, minst:ILGenericArgs) = + ILMethodSpec (ILMethodRef (typ.TypeRef, cc, minst.Length, nm, args, rty), typ, minst) + + let mkILFieldSpecInTy (typ:ILType, nm, fty) = + ILFieldSpec (ILFieldRef (typ.TypeRef, nm, fty), typ) + + let mkILGlobals systemRuntimeScopeRef = + let mkILTyspec nsp nm = mkILNonGenericTySpec(ILTypeRef(ILTypeRefScope.Top(systemRuntimeScopeRef), USome nsp, nm)) + { typ_Object = ILType.Boxed (mkILTyspec "System" "Object") + typ_String = ILType.Boxed (mkILTyspec "System" "String") + typ_Void = ILType.Value (mkILTyspec "System" "Void") + typ_Type = ILType.Boxed (mkILTyspec "System" "Type") + typ_Int64 = ILType.Value (mkILTyspec "System" "Int64") + typ_UInt64 = ILType.Value (mkILTyspec "System" "UInt64") + typ_Int32 = ILType.Value (mkILTyspec "System" "Int32") + typ_Array = ILType.Boxed (mkILTyspec "System" "Array") + typ_UInt32 = ILType.Value (mkILTyspec "System" "UInt32") + typ_Int16 = ILType.Value (mkILTyspec "System" "Int16") + typ_UInt16 = ILType.Value (mkILTyspec "System" "UInt16") + typ_SByte = ILType.Value (mkILTyspec "System" "SByte") + typ_Byte = ILType.Value (mkILTyspec "System" "Byte") + typ_Single = ILType.Value (mkILTyspec "System" "Single") + typ_Double = ILType.Value (mkILTyspec "System" "Double") + typ_Boolean = ILType.Value (mkILTyspec "System" "Boolean") + typ_Char = ILType.Value (mkILTyspec "System" "Char") + typ_IntPtr = ILType.Value (mkILTyspec "System" "IntPtr") + typ_TypedReference = Some (ILType.Value (mkILTyspec "System" "TypedReference")) + typ_UIntPtr = ILType.Value (mkILTyspec "System" "UIntPtr") + systemRuntimeScopeRef = systemRuntimeScopeRef } + + type PEReader(fileName: string, is: ByteFile) = + + //----------------------------------------------------------------------- + // Crack the binary headers, build a reader context and return the lazy + // read of the AbsIL module. + // ---------------------------------------------------------------------- + + (* MSDOS HEADER *) + let peSignaturePhysLoc = seekReadInt32 is 0x3c + + (* PE HEADER *) + let peFileHeaderPhysLoc = peSignaturePhysLoc + 0x04 + let peOptionalHeaderPhysLoc = peFileHeaderPhysLoc + 0x14 + let peSignature = seekReadInt32 is (peSignaturePhysLoc + 0) + do if peSignature <> 0x4550 then failwithf "not a PE file - bad magic PE number 0x%08x, is = %A" peSignature is; + + + (* PE SIGNATURE *) + let machine = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 0) + let numSections = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 2) + let optHeaderSize = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 16) + do if optHeaderSize <> 0xe0 && + optHeaderSize <> 0xf0 then failwith "not a PE file - bad optional header size"; + let x64adjust = optHeaderSize - 0xe0 + let only64 = (optHeaderSize = 0xf0) (* May want to read in the optional header Magic number and check that as well... *) + let platform = match machine with | 0x8664 -> Some(AMD64) | 0x200 -> Some(IA64) | _ -> Some(X86) + let sectionHeadersStartPhysLoc = peOptionalHeaderPhysLoc + optHeaderSize + + let flags = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 18) + let isDll = (flags &&& 0x2000) <> 0x0 + + (* OPTIONAL PE HEADER *) + (* x86: 000000a0 *) + (* x86: 000000b0 *) + let dataSegmentAddr = seekReadInt32 is (peOptionalHeaderPhysLoc + 24) (* e.g. 0x0000c000 *) + let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 is (peOptionalHeaderPhysLoc + 28) (* Image Base Always 0x400000 (see Section 23.1). - QUERY: no it's not always 0x400000, e.g. 0x034f0000 *) + let alignVirt = seekReadInt32 is (peOptionalHeaderPhysLoc + 32) (* Section Alignment Always 0x2000 (see Section 23.1). *) + let alignPhys = seekReadInt32 is (peOptionalHeaderPhysLoc + 36) (* File Alignment Either 0x200 or 0x1000. *) + (* x86: 000000c0 *) + let subsysMajor = seekReadUInt16AsInt32 is (peOptionalHeaderPhysLoc + 48) (* SubSys Major Always 4 (see Section 23.1). *) + let subsysMinor = seekReadUInt16AsInt32 is (peOptionalHeaderPhysLoc + 50) (* SubSys Minor Always 0 (see Section 23.1). *) + (* x86: 000000d0 *) + let subsys = seekReadUInt16 is (peOptionalHeaderPhysLoc + 68) (* SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (!0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (!0x2). QUERY: Why is this 3 on the images ILASM produces??? *) + let useHighEntropyVA = + let n = seekReadUInt16 is (peOptionalHeaderPhysLoc + 70) + let highEnthropyVA = 0x20us + (n &&& highEnthropyVA) = highEnthropyVA + + (* x86: 000000e0 *) + (* x86: 000000f0, x64: 00000100 *) + (* x86: 00000100 - these addresses are for x86 - for the x64 location, add x64adjust (0x10) *) + (* x86: 00000110 *) + (* x86: 00000120 *) + (* x86: 00000130 *) + (* x86: 00000140 *) + (* x86: 00000150 *) + (* x86: 00000160 *) + let cliHeaderAddr = seekReadInt32 is (peOptionalHeaderPhysLoc + 208 + x64adjust) + + let anyV2P (n, v) = + let rec look i pos = + if i >= numSections then (failwith (fileName + ": bad "+n+", rva "+string v); 0x0) + else + let virtSize = seekReadInt32 is (pos + 8) + let virtAddr = seekReadInt32 is (pos + 12) + let physLoc = seekReadInt32 is (pos + 20) + if (v >= virtAddr && (v < virtAddr + virtSize)) then (v - virtAddr) + physLoc + else look (i+1) (pos + 0x28) + look 0 sectionHeadersStartPhysLoc + + let cliHeaderPhysLoc = anyV2P ("cli header", cliHeaderAddr) + + let metadataAddr = seekReadInt32 is (cliHeaderPhysLoc + 8) + let metadataSize = seekReadInt32 is (cliHeaderPhysLoc + 12) + let cliFlags = seekReadInt32 is (cliHeaderPhysLoc + 16) + let ilOnly = (cliFlags &&& 0x01) <> 0x00 + let only32 = (cliFlags &&& 0x02) <> 0x00 + let is32bitpreferred = (cliFlags &&& 0x00020003) <> 0x00 + + let entryPointToken = seekReadUncodedToken is (cliHeaderPhysLoc + 20) + let resourcesAddr = seekReadInt32 is (cliHeaderPhysLoc + 24) + + let metadataPhysLoc = anyV2P ("metadata", metadataAddr) + let resourcePhysLoc offset = anyV2P ("resource", offset + resourcesAddr) + + member __.MetadataPhysLoc = metadataPhysLoc + member __.MetadataSize = metadataSize + member __.ResourcePhysLoc offset = resourcePhysLoc offset + + type ILModuleReader(fileName: string, is: ByteFile, ilg: ILGlobals, lowMem: bool) = + + let metadataPhysLoc = 0 + let magic = seekReadUInt16AsInt32 is metadataPhysLoc + do if magic <> 0x5342 then failwith (fileName + ": bad metadata magic number: " + string magic); + let magic2 = seekReadUInt16AsInt32 is (metadataPhysLoc + 2) + do if magic2 <> 0x424a then failwith "bad metadata magic number"; + + let versionLength = seekReadInt32 is (metadataPhysLoc + 12) + let ilMetadataVersion = seekReadBytes is (metadataPhysLoc + 16) versionLength |> Array.filter (fun b -> b <> 0uy) + let x = align 0x04 (16 + versionLength) + let numStreams = seekReadUInt16AsInt32 is (metadataPhysLoc + x + 2) + let streamHeadersStart = (metadataPhysLoc + x + 4) + + (* Crack stream headers *) + + let tryFindStream name = + let rec look i pos = + if i >= numStreams then None + else + let offset = seekReadInt32 is (pos + 0) + let length = seekReadInt32 is (pos + 4) + let res = ref true + let fin = ref false + let n = ref 0 + // read and compare the stream name byte by byte + while (not !fin) do + let c= seekReadByteAsInt32 is (pos + 8 + (!n)) + if c = 0 then + fin := true + elif !n >= Array.length name || c <> name.[!n] then + res := false; + incr n + if !res then Some(offset + metadataPhysLoc, length) + else look (i+1) (align 0x04 (pos + 8 + (!n))) + look 0 streamHeadersStart + + let findStream name = + match tryFindStream name with + | None -> (0x0, 0x0) + | Some positions -> positions + + let (tablesStreamPhysLoc, _tablesStreamSize) = + match tryFindStream [| 0x23; 0x7e |] (* #~ *) with + | Some res -> res + | None -> + match tryFindStream [| 0x23; 0x2d |] (* #-: at least one DLL I've seen uses this! *) with + | Some res -> res + | None -> + let firstStreamOffset = seekReadInt32 is (streamHeadersStart + 0) + let firstStreamLength = seekReadInt32 is (streamHeadersStart + 4) + firstStreamOffset, firstStreamLength + + let (stringsStreamPhysicalLoc, stringsStreamSize) = findStream [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; |] (* #Strings *) + let (blobsStreamPhysicalLoc, blobsStreamSize) = findStream [| 0x23; 0x42; 0x6c; 0x6f; 0x62; |] (* #Blob *) + + let tablesStreamMajorVersion = seekReadByteAsInt32 is (tablesStreamPhysLoc + 4) + let tablesStreamMinorVersion = seekReadByteAsInt32 is (tablesStreamPhysLoc + 5) + + let usingWhidbeyBeta1TableSchemeForGenericParam = (tablesStreamMajorVersion = 1) && (tablesStreamMinorVersion = 1) + + let tableKinds = + [|kindModule (* Table 0 *); + kindTypeRef (* Table 1 *); + kindTypeDef (* Table 2 *); + kindIllegal (* kindFieldPtr *) (* Table 3 *); + kindFieldDef (* Table 4 *); + kindIllegal (* kindMethodPtr *) (* Table 5 *); + kindMethodDef (* Table 6 *); + kindIllegal (* kindParamPtr *) (* Table 7 *); + kindParam (* Table 8 *); + kindInterfaceImpl (* Table 9 *); + kindMemberRef (* Table 10 *); + kindConstant (* Table 11 *); + kindCustomAttribute (* Table 12 *); + kindFieldMarshal (* Table 13 *); + kindDeclSecurity (* Table 14 *); + kindClassLayout (* Table 15 *); + kindFieldLayout (* Table 16 *); + kindStandAloneSig (* Table 17 *); + kindEventMap (* Table 18 *); + kindIllegal (* kindEventPtr *) (* Table 19 *); + kindEvent (* Table 20 *); + kindPropertyMap (* Table 21 *); + kindIllegal (* kindPropertyPtr *) (* Table 22 *); + kindProperty (* Table 23 *); + kindMethodSemantics (* Table 24 *); + kindMethodImpl (* Table 25 *); + kindModuleRef (* Table 26 *); + kindTypeSpec (* Table 27 *); + kindImplMap (* Table 28 *); + kindFieldRVA (* Table 29 *); + kindIllegal (* kindENCLog *) (* Table 30 *); + kindIllegal (* kindENCMap *) (* Table 31 *); + kindAssembly (* Table 32 *); + kindIllegal (* kindAssemblyProcessor *) (* Table 33 *); + kindIllegal (* kindAssemblyOS *) (* Table 34 *); + kindAssemblyRef (* Table 35 *); + kindIllegal (* kindAssemblyRefProcessor *) (* Table 36 *); + kindIllegal (* kindAssemblyRefOS *) (* Table 37 *); + kindFileRef (* Table 38 *); + kindExportedType (* Table 39 *); + kindManifestResource (* Table 40 *); + kindNested (* Table 41 *); + (if usingWhidbeyBeta1TableSchemeForGenericParam then kindGenericParam_v1_1 else kindGenericParam_v2_0); (* Table 42 *) + kindMethodSpec (* Table 43 *); + kindGenericParamConstraint (* Table 44 *); + kindIllegal (* Table 45 *); + kindIllegal (* Table 46 *); + kindIllegal (* Table 47 *); + kindIllegal (* Table 48 *); + kindIllegal (* Table 49 *); + kindIllegal (* Table 50 *); + kindIllegal (* Table 51 *); + kindIllegal (* Table 52 *); + kindIllegal (* Table 53 *); + kindIllegal (* Table 54 *); + kindIllegal (* Table 55 *); + kindIllegal (* Table 56 *); + kindIllegal (* Table 57 *); + kindIllegal (* Table 58 *); + kindIllegal (* Table 59 *); + kindIllegal (* Table 60 *); + kindIllegal (* Table 61 *); + kindIllegal (* Table 62 *); + kindIllegal (* Table 63 *); + |] + + let heapSizes = seekReadByteAsInt32 is (tablesStreamPhysLoc + 6) + let valid = seekReadInt64 is (tablesStreamPhysLoc + 8) + let sorted = seekReadInt64 is (tablesStreamPhysLoc + 16) + let tableRowCount, startOfTables = + let numRows = Array.create 64 0 + let prevNumRowIdx = ref (tablesStreamPhysLoc + 24) + for i = 0 to 63 do + if (valid &&& (int64 1 <<< i)) <> int64 0 then + numRows.[i] <- (seekReadInt32 is !prevNumRowIdx); + prevNumRowIdx := !prevNumRowIdx + 4 + numRows, !prevNumRowIdx + + let getNumRows (tab:ILTableName) = tableRowCount.[tab.Index] + let stringsBigness = (heapSizes &&& 1) <> 0 + let guidsBigness = (heapSizes &&& 2) <> 0 + let blobsBigness = (heapSizes &&& 4) <> 0 + + let tableBigness = Array.map (fun n -> n >= 0x10000) tableRowCount + + let codedBigness nbits tab = + let rows = getNumRows tab + rows >= (0x10000 >>>& nbits) + + let tdorBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.TypeRef || + codedBigness 2 ILTableNames.TypeSpec + + let tomdBigness = + codedBigness 1 ILTableNames.TypeDef || + codedBigness 1 ILTableNames.Method + + let hcBigness = + codedBigness 2 ILTableNames.Field || + codedBigness 2 ILTableNames.Param || + codedBigness 2 ILTableNames.Property + + let hcaBigness = + codedBigness 5 ILTableNames.Method || + codedBigness 5 ILTableNames.Field || + codedBigness 5 ILTableNames.TypeRef || + codedBigness 5 ILTableNames.TypeDef || + codedBigness 5 ILTableNames.Param || + codedBigness 5 ILTableNames.InterfaceImpl || + codedBigness 5 ILTableNames.MemberRef || + codedBigness 5 ILTableNames.Module || + codedBigness 5 ILTableNames.Permission || + codedBigness 5 ILTableNames.Property || + codedBigness 5 ILTableNames.Event || + codedBigness 5 ILTableNames.StandAloneSig || + codedBigness 5 ILTableNames.ModuleRef || + codedBigness 5 ILTableNames.TypeSpec || + codedBigness 5 ILTableNames.Assembly || + codedBigness 5 ILTableNames.AssemblyRef || + codedBigness 5 ILTableNames.File || + codedBigness 5 ILTableNames.ExportedType || + codedBigness 5 ILTableNames.ManifestResource || + codedBigness 5 ILTableNames.GenericParam || + codedBigness 5 ILTableNames.GenericParamConstraint || + codedBigness 5 ILTableNames.MethodSpec + + + let hfmBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Param + + let hdsBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.Method || + codedBigness 2 ILTableNames.Assembly + + let mrpBigness = + codedBigness 3 ILTableNames.TypeRef || + codedBigness 3 ILTableNames.ModuleRef || + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.TypeSpec + + let hsBigness = + codedBigness 1 ILTableNames.Event || + codedBigness 1 ILTableNames.Property + + let mdorBigness = + codedBigness 1 ILTableNames.Method || + codedBigness 1 ILTableNames.MemberRef + + let mfBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Method + + let iBigness = + codedBigness 2 ILTableNames.File || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.ExportedType + + let catBigness = + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.MemberRef + + let rsBigness = + codedBigness 2 ILTableNames.Module || + codedBigness 2 ILTableNames.ModuleRef || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.TypeRef + + let rowKindSize (ILRowKind kinds) = + kinds |> List.sumBy (fun x -> + match x with + | UShort -> 2 + | ULong -> 4 + | Byte -> 1 + | Data -> 4 + | GGuid -> (if guidsBigness then 4 else 2) + | Blob -> (if blobsBigness then 4 else 2) + | SString -> (if stringsBigness then 4 else 2) + | SimpleIndex tab -> (if tableBigness.[tab.Index] then 4 else 2) + | TypeDefOrRefOrSpec -> (if tdorBigness then 4 else 2) + | TypeOrMethodDef -> (if tomdBigness then 4 else 2) + | HasConstant -> (if hcBigness then 4 else 2) + | HasCustomAttribute -> (if hcaBigness then 4 else 2) + | HasFieldMarshal -> (if hfmBigness then 4 else 2) + | HasDeclSecurity -> (if hdsBigness then 4 else 2) + | MemberRefParent -> (if mrpBigness then 4 else 2) + | HasSemantics -> (if hsBigness then 4 else 2) + | MethodDefOrRef -> (if mdorBigness then 4 else 2) + | MemberForwarded -> (if mfBigness then 4 else 2) + | Implementation -> (if iBigness then 4 else 2) + | CustomAttributeType -> (if catBigness then 4 else 2) + | ResolutionScope -> (if rsBigness then 4 else 2)) + + let tableRowSizes = tableKinds |> Array.map rowKindSize + + let tablePhysLocations = + let res = Array.create 64 0x0 + let prevTablePhysLoc = ref startOfTables + for i = 0 to 63 do + res.[i] <- !prevTablePhysLoc; + prevTablePhysLoc := !prevTablePhysLoc + (tableRowCount.[i] * tableRowSizes.[i]); + res + + // All the caches. The sizes are guesstimates for the rough sharing-density of the assembly + let cacheAssemblyRef = mkCacheInt32 lowMem fileName "ILAssemblyRef" (getNumRows ILTableNames.AssemblyRef) + let cacheMemberRefAsMemberData = mkCacheGeneric lowMem fileName "MemberRefAsMemberData" (getNumRows ILTableNames.MemberRef / 20 + 1) + let cacheTypeRef = mkCacheInt32 lowMem fileName "ILTypeRef" (getNumRows ILTableNames.TypeRef / 20 + 1) + let cacheTypeRefAsType = mkCacheGeneric lowMem fileName "TypeRefAsType" (getNumRows ILTableNames.TypeRef / 20 + 1) + let cacheBlobHeapAsPropertySig = mkCacheGeneric lowMem fileName "BlobHeapAsPropertySig" (getNumRows ILTableNames.Property / 20 + 1) + let cacheBlobHeapAsFieldSig = mkCacheGeneric lowMem fileName "BlobHeapAsFieldSig" (getNumRows ILTableNames.Field / 20 + 1) + let cacheBlobHeapAsMethodSig = mkCacheGeneric lowMem fileName "BlobHeapAsMethodSig" (getNumRows ILTableNames.Method / 20 + 1) + let cacheTypeDefAsType = mkCacheGeneric lowMem fileName "TypeDefAsType" (getNumRows ILTableNames.TypeDef / 20 + 1) + let cacheMethodDefAsMethodData = mkCacheInt32 lowMem fileName "MethodDefAsMethodData" (getNumRows ILTableNames.Method / 20 + 1) + // nb. Lots and lots of cache hits on this cache, hence never optimize cache away + let cacheStringHeap = mkCacheInt32 false fileName "string heap" ( stringsStreamSize / 50 + 1) + let cacheBlobHeap = mkCacheInt32 lowMem fileName "blob heap" ( blobsStreamSize / 50 + 1) + + //----------------------------------------------------------------------- + + let rowAddr (tab:ILTableName) idx = tablePhysLocations.[tab.Index] + (idx - 1) * tableRowSizes.[tab.Index] + + let seekReadUInt16Adv (addr: byref) = + let res = seekReadUInt16 is addr + addr <- addr + 2 + res + + let seekReadInt32Adv (addr: byref) = + let res = seekReadInt32 is addr + addr <- addr+4 + res + + let seekReadUInt16AsInt32Adv (addr: byref) = + let res = seekReadUInt16AsInt32 is addr + addr <- addr+2 + res + + let seekReadTaggedIdx f nbits big (addr: byref) = + let tok = if big then seekReadInt32Adv &addr else seekReadUInt16AsInt32Adv &addr + tokToTaggedIdx f nbits tok + + + let seekReadIdx big (addr: byref) = + if big then seekReadInt32Adv &addr else seekReadUInt16AsInt32Adv &addr + + let seekReadUntaggedIdx (tab:ILTableName) (addr: byref) = + seekReadIdx tableBigness.[tab.Index] &addr + + + let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ResolutionScopeTag idx) 2 rsBigness &addr + let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeDefOrRefOrSpecTag idx) 2 tdorBigness &addr + let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeOrMethodDefTag idx) 1 tomdBigness &addr + let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasConstantTag idx) 2 hcBigness &addr + let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasCustomAttributeTag idx) 5 hcaBigness &addr + //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasFieldMarshalTag idx) 1 hfmBigness &addr + //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasDeclSecurityTag idx) 2 hdsBigness &addr + let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MemberRefParentTag idx) 3 mrpBigness &addr + let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasSemanticsTag idx) 1 hsBigness &addr + let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MethodDefOrRefTag idx) 1 mdorBigness &addr + let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ImplementationTag idx) 2 iBigness &addr + let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> CustomAttributeTypeTag idx) 3 catBigness &addr + let seekReadStringIdx (addr: byref) = seekReadIdx stringsBigness &addr + let seekReadGuidIdx (addr: byref) = seekReadIdx guidsBigness &addr + let seekReadBlobIdx (addr: byref) = seekReadIdx blobsBigness &addr + + let seekReadModuleRow idx = + if idx = 0 then failwith "cannot read Module table row 0"; + let mutable addr = rowAddr ILTableNames.Module idx + let generation = seekReadUInt16Adv &addr + let nameIdx = seekReadStringIdx &addr + let mvidIdx = seekReadGuidIdx &addr + let encidIdx = seekReadGuidIdx &addr + let encbaseidIdx = seekReadGuidIdx &addr + (generation, nameIdx, mvidIdx, encidIdx, encbaseidIdx) + + /// Read Table ILTypeRef + let seekReadTypeRefRow idx = + let mutable addr = rowAddr ILTableNames.TypeRef idx + let scopeIdx = seekReadResolutionScopeIdx &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + (scopeIdx, nameIdx, namespaceIdx) + + /// Read Table ILTypeDef + let seekReadTypeDefRow idx = + let mutable addr = rowAddr ILTableNames.TypeDef idx + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + let extendsIdx = seekReadTypeDefOrRefOrSpecIdx &addr + let fieldsIdx = seekReadUntaggedIdx ILTableNames.Field &addr + let methodsIdx = seekReadUntaggedIdx ILTableNames.Method &addr + (flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) + + /// Read Table Field + let seekReadFieldRow idx = + let mutable addr = rowAddr ILTableNames.Field idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + (flags, nameIdx, typeIdx) + + /// Read Table Method + let seekReadMethodRow idx = + let mutable addr = rowAddr ILTableNames.Method idx + let codeRVA = seekReadInt32Adv &addr + let implflags = seekReadUInt16AsInt32Adv &addr + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + let paramIdx = seekReadUntaggedIdx ILTableNames.Param &addr + (codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) + + /// Read Table Param + let seekReadParamRow idx = + let mutable addr = rowAddr ILTableNames.Param idx + let flags = seekReadUInt16AsInt32Adv &addr + let seq = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + (flags, seq, nameIdx) + + let seekReadInterfaceImplRow idx = + let mutable addr = rowAddr ILTableNames.InterfaceImpl idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let intfIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (tidx, intfIdx) + + /// Read Table MemberRef + let seekReadMemberRefRow idx = + let mutable addr = rowAddr ILTableNames.MemberRef idx + let mrpIdx = seekReadMemberRefParentIdx &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + (mrpIdx, nameIdx, typeIdx) + + /// Read Table Constant + let seekReadConstantRow idx = + let mutable addr = rowAddr ILTableNames.Constant idx + let kind = seekReadUInt16Adv &addr + let parentIdx = seekReadHasConstantIdx &addr + let valIdx = seekReadBlobIdx &addr + (kind, parentIdx, valIdx) + + /// Read Table CustomAttribute + let seekReadCustomAttributeRow idx = + let mutable addr = rowAddr ILTableNames.CustomAttribute idx + let parentIdx = seekReadHasCustomAttributeIdx &addr + let typeIdx = seekReadCustomAttributeTypeIdx &addr + let valIdx = seekReadBlobIdx &addr + (parentIdx, typeIdx, valIdx) + + //let seekReadFieldMarshalRow idx = + // let mutable addr = rowAddr TableNames.FieldMarshal idx + // let parentIdx = seekReadHasFieldMarshalIdx &addr + // let typeIdx = seekReadBlobIdx &addr + // (parentIdx, typeIdx) + + /// Read Table ClassLayout. + let seekReadClassLayoutRow idx = + let mutable addr = rowAddr ILTableNames.ClassLayout idx + let pack = seekReadUInt16Adv &addr + let size = seekReadInt32Adv &addr + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + (pack, size, tidx) + + /// Read Table FieldLayout. + let seekReadFieldLayoutRow idx = + let mutable addr = rowAddr ILTableNames.FieldLayout idx + let offset = seekReadInt32Adv &addr + let fidx = seekReadUntaggedIdx ILTableNames.Field &addr + (offset, fidx) + + /// Read Table EventMap + let seekReadEventMapRow idx = + let mutable addr = rowAddr ILTableNames.EventMap idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let eventsIdx = seekReadUntaggedIdx ILTableNames.Event &addr + (tidx, eventsIdx) + + /// Read Table Event + let seekReadEventRow idx = + let mutable addr = rowAddr ILTableNames.Event idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (flags, nameIdx, typIdx) + + /// Read Table PropertyMap + let seekReadPropertyMapRow idx = + let mutable addr = rowAddr ILTableNames.PropertyMap idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let propsIdx = seekReadUntaggedIdx ILTableNames.Property &addr + (tidx, propsIdx) + + /// Read Table Property + let seekReadPropertyRow idx = + let mutable addr = rowAddr ILTableNames.Property idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typIdx = seekReadBlobIdx &addr + (flags, nameIdx, typIdx) + + /// Read Table MethodSemantics + let seekReadMethodSemanticsRow idx = + let mutable addr = rowAddr ILTableNames.MethodSemantics idx + let flags = seekReadUInt16AsInt32Adv &addr + let midx = seekReadUntaggedIdx ILTableNames.Method &addr + let assocIdx = seekReadHasSemanticsIdx &addr + (flags, midx, assocIdx) + + let seekReadMethodImplRow idx = + let mutable addr = rowAddr ILTableNames.MethodImpl idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let mbodyIdx = seekReadMethodDefOrRefIdx &addr + let mdeclIdx = seekReadMethodDefOrRefIdx &addr + (tidx, mbodyIdx, mdeclIdx) + + /// Read Table ILModuleRef + let seekReadModuleRefRow idx = + let mutable addr = rowAddr ILTableNames.ModuleRef idx + let nameIdx = seekReadStringIdx &addr + nameIdx + + /// Read Table ILTypeSpec + let seekReadTypeSpecRow idx = + let mutable addr = rowAddr ILTableNames.TypeSpec idx + let blobIdx = seekReadBlobIdx &addr + blobIdx + + /// Read Table Assembly + let seekReadAssemblyRow idx = + let mutable addr = rowAddr ILTableNames.Assembly idx + let hash = seekReadInt32Adv &addr + let v1 = seekReadUInt16Adv &addr + let v2 = seekReadUInt16Adv &addr + let v3 = seekReadUInt16Adv &addr + let v4 = seekReadUInt16Adv &addr + let flags = seekReadInt32Adv &addr + let publicKeyIdx = seekReadBlobIdx &addr + let nameIdx = seekReadStringIdx &addr + let localeIdx = seekReadStringIdx &addr + (hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx) + + /// Read Table ILAssemblyRef + let seekReadAssemblyRefRow idx = + let mutable addr = rowAddr ILTableNames.AssemblyRef idx + let v1 = seekReadUInt16Adv &addr + let v2 = seekReadUInt16Adv &addr + let v3 = seekReadUInt16Adv &addr + let v4 = seekReadUInt16Adv &addr + let flags = seekReadInt32Adv &addr + let publicKeyOrTokenIdx = seekReadBlobIdx &addr + let nameIdx = seekReadStringIdx &addr + let localeIdx = seekReadStringIdx &addr + let hashValueIdx = seekReadBlobIdx &addr + (v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx) + + /// Read Table File + let seekReadFileRow idx = + let mutable addr = rowAddr ILTableNames.File idx + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let hashValueIdx = seekReadBlobIdx &addr + (flags, nameIdx, hashValueIdx) + + /// Read Table ILExportedTypeOrForwarder + let seekReadExportedTypeRow idx = + let mutable addr = rowAddr ILTableNames.ExportedType idx + let flags = seekReadInt32Adv &addr + let tok = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + let implIdx = seekReadImplementationIdx &addr + (flags, tok, nameIdx, namespaceIdx, implIdx) + + /// Read Table ManifestResource + let seekReadManifestResourceRow idx = + let mutable addr = rowAddr ILTableNames.ManifestResource idx + let offset = seekReadInt32Adv &addr + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let implIdx = seekReadImplementationIdx &addr + (offset, flags, nameIdx, implIdx) + + /// Read Table Nested + let seekReadNestedRow idx = + let mutable addr = rowAddr ILTableNames.Nested idx + let nestedIdx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let enclIdx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + (nestedIdx, enclIdx) + + /// Read Table GenericParam + let seekReadGenericParamRow idx = + let mutable addr = rowAddr ILTableNames.GenericParam idx + let seq = seekReadUInt16Adv &addr + let flags = seekReadUInt16Adv &addr + let ownerIdx = seekReadTypeOrMethodDefIdx &addr + let nameIdx = seekReadStringIdx &addr + (idx, seq, flags, ownerIdx, nameIdx) + + // Read Table GenericParamConstraint + let seekReadGenericParamConstraintRow idx = + let mutable addr = rowAddr ILTableNames.GenericParamConstraint idx + let pidx = seekReadUntaggedIdx ILTableNames.GenericParam &addr + let constraintIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (pidx, constraintIdx) + + //let readUserStringHeapUncached idx = seekReadUserString is (userStringsStreamPhysicalLoc + idx) + //let readUserStringHeap = cacheUserStringHeap readUserStringHeapUncached + + let readStringHeapUncached idx = seekReadUTF8String is (stringsStreamPhysicalLoc + idx) + let readStringHeap = cacheStringHeap readStringHeapUncached + let readStringHeapOption idx = if idx = 0 then UNone else USome (readStringHeap idx) + + let emptyByteArray: byte[] = [||] + let readBlobHeapUncached idx = + // valid index lies in range [1..streamSize) + // NOTE: idx cannot be 0 - Blob\String heap has first empty element that is one byte 0 + if idx <= 0 || idx >= blobsStreamSize then emptyByteArray + else seekReadBlob is (blobsStreamPhysicalLoc + idx) + let readBlobHeap = cacheBlobHeap readBlobHeapUncached + let readBlobHeapOption idx = if idx = 0 then UNone else USome (readBlobHeap idx) + + //let readGuidHeap idx = seekReadGuid is (guidsStreamPhysicalLoc + idx) + + // read a single value out of a blob heap using the given function + let readBlobHeapAsBool vidx = fst (sigptrGetBool (readBlobHeap vidx) 0) + let readBlobHeapAsSByte vidx = fst (sigptrGetSByte (readBlobHeap vidx) 0) + let readBlobHeapAsInt16 vidx = fst (sigptrGetInt16 (readBlobHeap vidx) 0) + let readBlobHeapAsInt32 vidx = fst (sigptrGetInt32 (readBlobHeap vidx) 0) + let readBlobHeapAsInt64 vidx = fst (sigptrGetInt64 (readBlobHeap vidx) 0) + let readBlobHeapAsByte vidx = fst (sigptrGetByte (readBlobHeap vidx) 0) + let readBlobHeapAsUInt16 vidx = fst (sigptrGetUInt16 (readBlobHeap vidx) 0) + let readBlobHeapAsUInt32 vidx = fst (sigptrGetUInt32 (readBlobHeap vidx) 0) + let readBlobHeapAsUInt64 vidx = fst (sigptrGetUInt64 (readBlobHeap vidx) 0) + let readBlobHeapAsSingle vidx = fst (sigptrGetSingle (readBlobHeap vidx) 0) + let readBlobHeapAsDouble vidx = fst (sigptrGetDouble (readBlobHeap vidx) 0) + + //----------------------------------------------------------------------- + // Read the AbsIL structure (lazily) by reading off the relevant rows. + // ---------------------------------------------------------------------- + + let isSorted (tab:ILTableName) = ((sorted &&& (int64 1 <<< tab.Index)) <> int64 0x0) + + //let subsysversion = (subsysMajor, subsysMinor) + let ilMetadataVersion = Encoding.UTF8.GetString (ilMetadataVersion, 0, ilMetadataVersion.Length) + + let rec seekReadModule (ilMetadataVersion) idx = + let (_generation, nameIdx, _mvidIdx, _encidIdx, _encbaseidIdx) = seekReadModuleRow idx + let ilModuleName = readStringHeap nameIdx + //let nativeResources = readNativeResources tgt + + { Manifest = + if getNumRows (ILTableNames.Assembly) > 0 then Some (seekReadAssemblyManifest 1) + else None; + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Module, idx)); + Name = ilModuleName; + //NativeResources=nativeResources; + TypeDefs = ILTypeDefs (lazy (seekReadTopTypeDefs ())); + SubsystemVersion = (4, 0) + UseHighEntropyVA = false + SubSystemFlags=3 + IsDLL=true + IsILOnly=true + Platform=None + StackReserveSize=None + Is32Bit=false + Is32BitPreferred=false + Is64Bit=false + PhysicalAlignment=512 + VirtualAlignment=0x2000 + ImageBase=0x034f0000 + MetadataVersion="" + Resources = seekReadManifestResources () + } + + and seekReadAssemblyManifest idx = + let (hash, v1, v2, v3, v4, flags, publicKeyIdx, nameIdx, localeIdx) = seekReadAssemblyRow idx + let name = readStringHeap nameIdx + let pubkey = readBlobHeapOption publicKeyIdx + { Name= name; + AuxModuleHashAlgorithm=hash + PublicKey= pubkey + Version= USome (Version(int v1, int v2, int v3, int v4)) + Locale= readStringHeapOption localeIdx + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Assembly, idx)) + ExportedTypes= seekReadTopExportedTypes () + EntrypointElsewhere=None + Retargetable = 0 <> (flags &&& 0x100); + DisableJitOptimizations = 0 <> (flags &&& 0x4000); + JitTracking = 0 <> (flags &&& 0x8000) + IgnoreSymbolStoreSequencePoints = 0 <> (flags &&& 0x2000) + } + + and seekReadAssemblyRef idx = cacheAssemblyRef seekReadAssemblyRefUncached idx + and seekReadAssemblyRefUncached idx = + let (v1, v2, v3, v4, flags, publicKeyOrTokenIdx, nameIdx, localeIdx, hashValueIdx) = seekReadAssemblyRefRow idx + let nm = readStringHeap nameIdx + let publicKey = + match readBlobHeapOption publicKeyOrTokenIdx with + | UNone -> UNone + | USome blob -> USome (if (flags &&& 0x0001) <> 0x0 then PublicKey blob else PublicKeyToken blob) + + ILAssemblyRef + (name=nm, + hash=readBlobHeapOption hashValueIdx, + publicKey=publicKey, + retargetable=((flags &&& 0x0100) <> 0x0), + version=USome(Version(int v1, int v2, int v3, int v4)), + locale=readStringHeapOption localeIdx;) + + and seekReadModuleRef idx = + let nameIdx = seekReadModuleRefRow idx + ILModuleRef(name=readStringHeap nameIdx, hasMetadata=true, hash=UNone) + + and seekReadFile idx = + let (flags, nameIdx, hashValueIdx) = seekReadFileRow idx + ILModuleRef(name = readStringHeap nameIdx, + hasMetadata= ((flags &&& 0x0001) = 0x0), + hash= readBlobHeapOption hashValueIdx) + + and seekReadClassLayout idx = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.ClassLayout, seekReadClassLayoutRow, (fun (_, _, tidx) -> tidx), simpleIndexCompare idx, isSorted ILTableNames.ClassLayout, (fun (pack, size, _) -> pack, size)) with + | None -> { Size = None; Pack = None } + | Some (pack, size) -> { Size = Some size; Pack = Some pack; } + + + and typeLayoutOfFlags flags tidx = + let f = (flags &&& 0x00000018) + if f = 0x00000008 then ILTypeDefLayout.Sequential (seekReadClassLayout tidx) + elif f = 0x00000010 then ILTypeDefLayout.Explicit (seekReadClassLayout tidx) + else ILTypeDefLayout.Auto + + and isTopTypeDef flags = + (ILTypeDefAccess.OfFlags flags = ILTypeDefAccess.Private) || + ILTypeDefAccess.OfFlags flags = ILTypeDefAccess.Public + + and seekIsTopTypeDefOfIdx idx = + let (flags, _, _, _, _, _) = seekReadTypeDefRow idx + isTopTypeDef flags + + and readStringHeapAsTypeName (nameIdx, namespaceIdx) = + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + nspace, name + + and seekReadTypeDefRowExtents _info (idx:int) = + if idx >= getNumRows ILTableNames.TypeDef then + getNumRows ILTableNames.Field + 1, + getNumRows ILTableNames.Method + 1 + else + let (_, _, _, _, fieldsIdx, methodsIdx) = seekReadTypeDefRow (idx + 1) + fieldsIdx, methodsIdx + + and seekReadTypeDefRowWithExtents (idx:int) = + let info= seekReadTypeDefRow idx + info, seekReadTypeDefRowExtents info idx + + and seekReadTypeDef toponly (idx:int) = + let (flags, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow idx + if toponly && not (isTopTypeDef flags) then None + else + + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + let rest = + lazy + let ((flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) as info) = seekReadTypeDefRow idx + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + let (endFieldsIdx, endMethodsIdx) = seekReadTypeDefRowExtents info idx + let typars = seekReadGenericParams 0 (TypeOrMethodDefTag.TypeDef, idx) + let numtypars = typars.Length + let super = seekReadOptionalTypeDefOrRef numtypars AsObject extendsIdx + let layout = typeLayoutOfFlags flags idx + //let hasLayout = (match layout with ILTypeDefLayout.Explicit _ -> true | _ -> false) + let hasLayout = false + let mdefs = seekReadMethods numtypars methodsIdx endMethodsIdx + let fdefs = seekReadFields (numtypars, hasLayout) fieldsIdx endFieldsIdx + let nested = seekReadNestedTypeDefs idx + let intfs = seekReadInterfaceImpls numtypars idx + //let sdecls = seekReadSecurityDecls (TaggedIndex(hds_TypeDef, idx)) + let mimpls = seekReadMethodImpls numtypars idx + let props = seekReadProperties numtypars idx + let events = seekReadEvents numtypars idx + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.TypeDef, idx)) + { Namespace=nspace + Name=name + GenericParams=typars + Attributes = enum flags + Layout = layout + NestedTypes= nested + Implements = intfs + Extends = super + Methods = mdefs + + //SecurityDecls = sdecls + //HasSecurity=(flags &&& 0x00040000) <> 0x0 + Fields=fdefs + MethodImpls=mimpls + Events= events + Properties=props + CustomAttrs=cas + Token = idx } + Some (nspace, name, rest) + + and seekReadTopTypeDefs () = + [| for i = 1 to getNumRows ILTableNames.TypeDef do + match seekReadTypeDef true i with + | None -> () + | Some td -> yield td |] + + and seekReadNestedTypeDefs tidx = + ILTypeDefs + (lazy + let nestedIdxs = seekReadIndexedRows (getNumRows ILTableNames.Nested, seekReadNestedRow, snd, simpleIndexCompare tidx, false, fst) + [| for i in nestedIdxs do + match seekReadTypeDef false i with + | None -> () + | Some td -> yield td |]) + + and seekReadInterfaceImpls numtypars tidx = + seekReadIndexedRows (getNumRows ILTableNames.InterfaceImpl, seekReadInterfaceImplRow , fst, simpleIndexCompare tidx, isSorted ILTableNames.InterfaceImpl, (snd >> seekReadTypeDefOrRef numtypars AsObject [| |])) + + and seekReadGenericParams numtypars (a, b): ILGenericParameterDefs = + let pars = + seekReadIndexedRows + (getNumRows ILTableNames.GenericParam, seekReadGenericParamRow, + (fun (_, _, _, tomd, _) -> tomd), + tomdCompare (TaggedIndex(a, b)), + isSorted ILTableNames.GenericParam, + (fun (gpidx, seq, flags, _, nameIdx) -> + let constraints = seekReadGenericParamConstraintsUncached numtypars gpidx + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.GenericParam, gpidx)) + seq, {Name=readStringHeap nameIdx + Constraints= constraints + CustomAttrs=cas + Attributes = enum (int32 flags) + Token=gpidx })) + pars |> Array.sortBy fst |> Array.map snd + + and seekReadGenericParamConstraintsUncached numtypars gpidx = + seekReadIndexedRows + (getNumRows ILTableNames.GenericParamConstraint, + seekReadGenericParamConstraintRow, + fst, + simpleIndexCompare gpidx, + isSorted ILTableNames.GenericParamConstraint, + (snd >> seekReadTypeDefOrRef numtypars AsObject (*ok*) [| |])) + + and seekReadTypeDefAsType boxity (ginst:ILTypes) idx = cacheTypeDefAsType seekReadTypeDefAsTypeUncached (TypeDefAsTypIdx (boxity, ginst, idx)) + + and seekReadTypeDefAsTypeUncached (TypeDefAsTypIdx (boxity, ginst, idx)) = + mkILTy boxity (ILTypeSpec(seekReadTypeDefAsTypeRef idx, ginst)) + + and seekReadTypeDefAsTypeRef idx = + let enc = + if seekIsTopTypeDefOfIdx idx then ILTypeRefScope.Top ILScopeRef.Local + else + let enclIdx = seekReadIndexedRow (getNumRows ILTableNames.Nested, seekReadNestedRow, fst, simpleIndexCompare idx, isSorted ILTableNames.Nested, snd) + let tref = seekReadTypeDefAsTypeRef enclIdx + ILTypeRefScope.Nested tref + let (_, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow idx + let nsp, nm = readStringHeapAsTypeName (nameIdx, namespaceIdx) + ILTypeRef(enc=enc, nsp = nsp, name = nm ) + + and seekReadTypeRef idx = cacheTypeRef seekReadTypeRefUncached idx + and seekReadTypeRefUncached idx = + let scopeIdx, nameIdx, namespaceIdx = seekReadTypeRefRow idx + let enc = seekReadTypeRefScope scopeIdx + let nsp, nm = readStringHeapAsTypeName (nameIdx, namespaceIdx) + ILTypeRef(enc, nsp, nm) + + and seekReadTypeRefAsType boxity ginst idx = cacheTypeRefAsType seekReadTypeRefAsTypeUncached (TypeRefAsTypIdx (boxity, ginst, idx)) + and seekReadTypeRefAsTypeUncached (TypeRefAsTypIdx (boxity, ginst, idx)) = + mkILTy boxity (ILTypeSpec(seekReadTypeRef idx, ginst)) + + and seekReadTypeDefOrRef numtypars boxity (ginst:ILTypes) (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = TypeDefOrRefOrSpecTag.TypeDef -> seekReadTypeDefAsType boxity ginst idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeRef -> seekReadTypeRefAsType boxity ginst idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeSpec -> readBlobHeapAsType numtypars (seekReadTypeSpecRow idx) + | _ -> failwith "seekReadTypeDefOrRef" + + and seekReadTypeDefOrRefAsTypeRef (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = TypeDefOrRefOrSpecTag.TypeDef -> seekReadTypeDefAsTypeRef idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeRef -> seekReadTypeRef idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeSpec -> ilg.typ_Object.TypeRef + | _ -> failwith "seekReadTypeDefOrRefAsTypeRef_readTypeDefOrRefOrSpec" + + and seekReadMethodRefParent numtypars (TaggedIndex(tag, idx)) = + match tag with + | tag when tag = MemberRefParentTag.TypeRef -> seekReadTypeRefAsType AsObject (* not ok - no way to tell if a member ref parent is a value type or not *) [| |] idx + | tag when tag = MemberRefParentTag.ModuleRef -> mkILTypeForGlobalFunctions (ILScopeRef.Module (seekReadModuleRef idx)) + | tag when tag = MemberRefParentTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + let mspec = mkILMethSpecInTyRaw(enclTyp, cc, nm, argtys, retty, minst) + mspec.EnclosingType + | tag when tag = MemberRefParentTag.TypeSpec -> readBlobHeapAsType numtypars (seekReadTypeSpecRow idx) + | _ -> failwith "seekReadMethodRefParent" + + + and seekReadMethodDefOrRef numtypars (TaggedIndex(tag, idx)) = + match tag with + | tag when tag = MethodDefOrRefTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + VarArgMethodData(enclTyp, cc, nm, argtys, None, retty, minst) + | tag when tag = MethodDefOrRefTag.MemberRef -> + seekReadMemberRefAsMethodData numtypars idx + | _ -> failwith "seekReadMethodDefOrRef ctxt" + + and seekReadMethodDefOrRefNoVarargs numtypars x = + let (VarArgMethodData(enclTyp, cc, nm, argtys, varargs, retty, minst)) = seekReadMethodDefOrRef numtypars x + MethodData(enclTyp, cc, nm, argtys, retty, minst) + + and seekReadCustomAttrType (TaggedIndex(tag, idx) ) = + match tag with + | tag when tag = CustomAttributeTypeTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst) + | tag when tag = CustomAttributeTypeTag.MemberRef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMemberRefAsMethDataNoVarArgs 0 idx + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst) + | _ -> failwith "seekReadCustomAttrType" + + and seekReadImplAsScopeRef (TaggedIndex(tag, idx) ) = + if idx = 0 then ILScopeRef.Local + else + match tag with + | tag when tag = ImplementationTag.File -> ILScopeRef.Module (seekReadFile idx) + | tag when tag = ImplementationTag.AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef idx) + | tag when tag = ImplementationTag.ExportedType -> failwith "seekReadImplAsScopeRef" + | _ -> failwith "seekReadImplAsScopeRef" + + and seekReadTypeRefScope (TaggedIndex(tag, idx) ): ILTypeRefScope = + match tag with + | tag when tag = ResolutionScopeTag.Module -> ILTypeRefScope.Top(ILScopeRef.Local) + | tag when tag = ResolutionScopeTag.ModuleRef -> ILTypeRefScope.Top(ILScopeRef.Module (seekReadModuleRef idx)) + | tag when tag = ResolutionScopeTag.AssemblyRef -> ILTypeRefScope.Top(ILScopeRef.Assembly (seekReadAssemblyRef idx)) + | tag when tag = ResolutionScopeTag.TypeRef -> ILTypeRefScope.Nested (seekReadTypeRef idx) + | _ -> failwith "seekReadTypeRefScope" + + and seekReadOptionalTypeDefOrRef numtypars boxity idx = + if idx = TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, 0) then None + else Some (seekReadTypeDefOrRef numtypars boxity [| |] idx) + + and seekReadField (numtypars, hasLayout) (idx:int) = + let (flags, nameIdx, typeIdx) = seekReadFieldRow idx + let nm = readStringHeap nameIdx + let isStatic = (flags &&& 0x0010) <> 0 + { Name = nm + FieldType = readBlobHeapAsFieldSig numtypars typeIdx + LiteralValue = if (flags &&& 0x8000) = 0 then None else Some (seekReadConstant (TaggedIndex(HasConstantTag.FieldDef, idx))) + //Marshal = + // if (flags &&& 0x1000) = 0 then None else + // Some (seekReadIndexedRow (getNumRows ILTableNames.FieldMarshal, seekReadFieldMarshalRow, + // fst, hfmCompare (TaggedIndex(hfm_FieldDef, idx)), + // isSorted ILTableNames.FieldMarshal, + // (snd >> readBlobHeapAsNativeType ctxt))) + //Data = + // if (flags &&& 0x0100) = 0 then None + // else + // let rva = seekReadIndexedRow (getNumRows ILTableNames.FieldRVA, seekReadFieldRVARow, + // snd, simpleIndexCompare idx, isSorted ILTableNames.FieldRVA, fst) + // Some (rvaToData "field" rva) + Attributes = enum(flags) + Offset = + if hasLayout && not isStatic then + Some (seekReadIndexedRow (getNumRows ILTableNames.FieldLayout, seekReadFieldLayoutRow, + snd, simpleIndexCompare idx, isSorted ILTableNames.FieldLayout, fst)) else None + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.FieldDef, idx)) + Token = idx } + + and seekReadFields (numtypars, hasLayout) fidx1 fidx2 = + { new ILFieldDefs with + member __.Entries = + [| for i = fidx1 to fidx2 - 1 do + yield seekReadField (numtypars, hasLayout) i |] } + + and seekReadMethods numtypars midx1 midx2 = + ILMethodDefs + (lazy + [| for i = midx1 to midx2 - 1 do + yield seekReadMethod numtypars i |]) + + and sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr = + let n, sigptr = sigptrGetZInt32 bytes sigptr + if (n &&& 0x01) = 0x0 then (* Type Def *) + TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, (n >>>& 2)), sigptr + else (* Type Ref *) + TaggedIndex(TypeDefOrRefOrSpecTag.TypeRef, (n >>>& 2)), sigptr + + and sigptrGetTy numtypars bytes sigptr = + let b0, sigptr = sigptrGetByte bytes sigptr + if b0 = et_OBJECT then ilg.typ_Object , sigptr + elif b0 = et_STRING then ilg.typ_String, sigptr + elif b0 = et_I1 then ilg.typ_SByte, sigptr + elif b0 = et_I2 then ilg.typ_Int16, sigptr + elif b0 = et_I4 then ilg.typ_Int32, sigptr + elif b0 = et_I8 then ilg.typ_Int64, sigptr + elif b0 = et_I then ilg.typ_IntPtr, sigptr + elif b0 = et_U1 then ilg.typ_Byte, sigptr + elif b0 = et_U2 then ilg.typ_UInt16, sigptr + elif b0 = et_U4 then ilg.typ_UInt32, sigptr + elif b0 = et_U8 then ilg.typ_UInt64, sigptr + elif b0 = et_U then ilg.typ_UIntPtr, sigptr + elif b0 = et_R4 then ilg.typ_Single, sigptr + elif b0 = et_R8 then ilg.typ_Double, sigptr + elif b0 = et_CHAR then ilg.typ_Char, sigptr + elif b0 = et_BOOLEAN then ilg.typ_Boolean, sigptr + elif b0 = et_WITH then + let b0, sigptr = sigptrGetByte bytes sigptr + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let n, sigptr = sigptrGetZInt32 bytes sigptr + let argtys, sigptr = sigptrFold (sigptrGetTy numtypars) n bytes sigptr + seekReadTypeDefOrRef numtypars (if b0 = et_CLASS then AsObject else AsValue) argtys tdorIdx, + sigptr + + elif b0 = et_CLASS then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef numtypars AsObject [| |] tdorIdx, sigptr + elif b0 = et_VALUETYPE then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef numtypars AsValue [| |] tdorIdx, sigptr + elif b0 = et_VAR then + let n, sigptr = sigptrGetZInt32 bytes sigptr + ILType.Var n, sigptr + elif b0 = et_MVAR then + let n, sigptr = sigptrGetZInt32 bytes sigptr + ILType.Var (n + numtypars), sigptr + elif b0 = et_BYREF then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Byref typ, sigptr + elif b0 = et_PTR then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Ptr typ, sigptr + elif b0 = et_SZARRAY then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + mkILArr1DTy typ, sigptr + elif b0 = et_ARRAY then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + let rank, sigptr = sigptrGetZInt32 bytes sigptr + let numSized, sigptr = sigptrGetZInt32 bytes sigptr + let sizes, sigptr = sigptrFold sigptrGetZInt32 numSized bytes sigptr + let numLoBounded, sigptr = sigptrGetZInt32 bytes sigptr + let lobounds, sigptr = sigptrFold sigptrGetZInt32 numLoBounded bytes sigptr + let shape = + let dim i = + (if i < numLoBounded then Some lobounds.[i] else None), + (if i < numSized then Some sizes.[i] else None) + ILArrayShape (Array.init rank dim) + ILType.Array (shape, typ), sigptr + + elif b0 = et_VOID then ILType.Void, sigptr + elif b0 = et_TYPEDBYREF then + match ilg.typ_TypedReference with + | Some t -> t, sigptr + | _ -> failwith "system runtime doesn't contain System.TypedReference" + elif b0 = et_CMOD_REQD || b0 = et_CMOD_OPT then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Modified((b0 = et_CMOD_REQD), seekReadTypeDefOrRefAsTypeRef tdorIdx, typ), sigptr + elif b0 = et_FNPTR then + let ccByte, sigptr = sigptrGetByte bytes sigptr + let generic, cc = byteAsCallConv ccByte + if generic then failwith "fptr sig may not be generic" + let numparams, sigptr = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy numtypars bytes sigptr + let argtys, sigptr = sigptrFold (sigptrGetTy numtypars) ( numparams) bytes sigptr + ILType.FunctionPointer (ILCallingSignature(cc, argtys, retty)), sigptr + elif b0 = et_SENTINEL then failwith "varargs NYI" + else ILType.Void , sigptr + + and sigptrGetVarArgTys n numtypars bytes sigptr = + sigptrFold (sigptrGetTy numtypars) n bytes sigptr + + and sigptrGetArgTys n numtypars bytes sigptr acc = + if n <= 0 then (Array.ofList (List.rev acc), None), sigptr + else + let b0, sigptr2 = sigptrGetByte bytes sigptr + if b0 = et_SENTINEL then + let varargs, sigptr = sigptrGetVarArgTys n numtypars bytes sigptr2 + (Array.ofList (List.rev acc), Some( varargs)), sigptr + else + let x, sigptr = sigptrGetTy numtypars bytes sigptr + sigptrGetArgTys (n-1) numtypars bytes sigptr (x::acc) + + and readBlobHeapAsMethodSig numtypars blobIdx = cacheBlobHeapAsMethodSig readBlobHeapAsMethodSigUncached (BlobAsMethodSigIdx (numtypars, blobIdx)) + + and readBlobHeapAsMethodSigUncached (BlobAsMethodSigIdx (numtypars, blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + let generic, cc = byteAsCallConv ccByte + let genarity, sigptr = if generic then sigptrGetZInt32 bytes sigptr else 0x0, sigptr + let numparams, sigptr = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy numtypars bytes sigptr + let (argtys, varargs), _sigptr = sigptrGetArgTys ( numparams) numtypars bytes sigptr [] + generic, genarity, cc, retty, argtys, varargs + + and readBlobHeapAsType numtypars blobIdx = + let bytes = readBlobHeap blobIdx + let ty, _sigptr = sigptrGetTy numtypars bytes 0 + ty + + and readBlobHeapAsFieldSig numtypars blobIdx = cacheBlobHeapAsFieldSig readBlobHeapAsFieldSigUncached (BlobAsFieldSigIdx (numtypars, blobIdx)) + + and readBlobHeapAsFieldSigUncached (BlobAsFieldSigIdx (numtypars, blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let _ccByte, sigptr = sigptrGetByte bytes sigptr + let retty, _sigptr = sigptrGetTy numtypars bytes sigptr + retty + + + and readBlobHeapAsPropertySig numtypars blobIdx = cacheBlobHeapAsPropertySig readBlobHeapAsPropertySigUncached (BlobAsPropSigIdx (numtypars, blobIdx)) + and readBlobHeapAsPropertySigUncached (BlobAsPropSigIdx (numtypars, blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let ccByte, sigptr = sigptrGetByte bytes sigptr + let hasthis = byteAsHasThis ccByte + let numparams, sigptr = sigptrGetZInt32 bytes sigptr + let retty, sigptr = sigptrGetTy numtypars bytes sigptr + let argtys, _sigptr = sigptrFold (sigptrGetTy numtypars) ( numparams) bytes sigptr + hasthis, retty, argtys + + and byteAsHasThis b = + let hasthis_masked = b &&& 0x60uy + if hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE then ILThisConvention.Instance + elif hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT then ILThisConvention.InstanceExplicit + else ILThisConvention.Static + + and byteAsCallConv b = + let cc = + let ccMaxked = b &&& 0x0Fuy + if ccMaxked = e_IMAGE_CEE_CS_CALLCONV_FASTCALL then ILArgConvention.FastCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_STDCALL then ILArgConvention.StdCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_THISCALL then ILArgConvention.ThisCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_CDECL then ILArgConvention.CDecl + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_VARARG then ILArgConvention.VarArg + else ILArgConvention.Default + let generic = (b &&& e_IMAGE_CEE_CS_CALLCONV_GENERIC) <> 0x0uy + generic, Callconv (byteAsHasThis b, cc) + + and seekReadMemberRefAsMethodData numtypars idx: VarArgMethodData = cacheMemberRefAsMemberData seekReadMemberRefAsMethodDataUncached (MemberRefAsMspecIdx (numtypars, idx)) + + and seekReadMemberRefAsMethodDataUncached (MemberRefAsMspecIdx (numtypars, idx)) = + let (mrpIdx, nameIdx, typeIdx) = seekReadMemberRefRow idx + let nm = readStringHeap nameIdx + let enclTyp = seekReadMethodRefParent numtypars mrpIdx + let _generic, genarity, cc, retty, argtys, varargs = readBlobHeapAsMethodSig enclTyp.GenericArgs.Length typeIdx + let minst = Array.init genarity (fun n -> ILType.Var (numtypars+n)) + (VarArgMethodData(enclTyp, cc, nm, argtys, varargs, retty, minst)) + + and seekReadMemberRefAsMethDataNoVarArgs numtypars idx: MethodData = + let (VarArgMethodData(enclTyp, cc, nm, argtys, _varargs, retty, minst)) = seekReadMemberRefAsMethodData numtypars idx + (MethodData(enclTyp, cc, nm, argtys, retty, minst)) + + // One extremely annoying aspect of the MD format is that given a + // ILMethodDef token it is non-trivial to find which ILTypeDef it belongs + // to. So we do a binary chop through the ILTypeDef table + // looking for which ILTypeDef has the ILMethodDef within its range. + // Although the ILTypeDef table is not "sorted", it is effectively sorted by + // method-range and field-range start/finish indexes + and seekReadMethodDefAsMethodData idx = cacheMethodDefAsMethodData seekReadMethodDefAsMethodDataUncached idx + and seekReadMethodDefAsMethodDataUncached idx = + let (_code_rva, _implflags, _flags, nameIdx, typeIdx, _paramIdx) = seekReadMethodRow idx + let nm = readStringHeap nameIdx + // Look for the method def parent. + let tidx = + seekReadIndexedRow (getNumRows ILTableNames.TypeDef, + (fun i -> i, seekReadTypeDefRowWithExtents i), + (fun r -> r), + (fun (_, ((_, _, _, _, _, methodsIdx), + (_, endMethodsIdx))) -> + if endMethodsIdx <= idx then 1 + elif methodsIdx <= idx && idx < endMethodsIdx then 0 + else -1), + true, fst) + let _generic, _genarity, cc, retty, argtys, _varargs = readBlobHeapAsMethodSig 0 typeIdx + let ctps = seekReadGenericParams 0 (TypeOrMethodDefTag.TypeDef, tidx) + let mtps = seekReadGenericParams ctps.Length (TypeOrMethodDefTag.MethodDef, idx) + let finst = mkILFormalGenericArgs 0 ctps.Length + let minst = mkILFormalGenericArgs ctps.Length mtps.Length + let enclTyp = seekReadTypeDefAsType AsObject finst tidx + MethodData(enclTyp, cc, nm, argtys, retty, minst) + + and seekReadMethod numtypars (idx:int) = + let (_codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) = seekReadMethodRow idx + let nm = readStringHeap nameIdx + let _generic, _genarity, cc, retty, argtys, _varargs = readBlobHeapAsMethodSig numtypars typeIdx + + let endParamIdx = + if idx >= getNumRows ILTableNames.Method then + getNumRows ILTableNames.Param + 1 + else + let (_, _, _, _, _, paramIdx) = seekReadMethodRow (idx + 1) + paramIdx + + let ret, ilParams = seekReadParams (retty, argtys) paramIdx endParamIdx + + { Token=idx // This value is not a strict metadata token but it's good enough (if needed we could get the real one pretty easily) + Name=nm + Attributes = enum(flags) + //SecurityDecls=seekReadSecurityDecls (TaggedIndex(hds_MethodDef, idx)) + //IsEntryPoint= (fst entryPointToken = ILTableNames.Method && snd entryPointToken = idx) + ImplAttributes= enum implflags + GenericParams=seekReadGenericParams numtypars (TypeOrMethodDefTag.MethodDef, idx) + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.MethodDef, idx)) + Parameters= ilParams + CallingConv=cc + Return=ret + Body= None + //SecurityDecls + //HasSecurity= false + IsEntryPoint= false (* unused by reader *) + } + + + and seekReadParams (retty, argtys) pidx1 pidx2 = + let retRes: ILReturn ref = ref { (* Marshal=None *) Type=retty; CustomAttrs=ILCustomAttrsStatics.Empty } + let paramsRes = + argtys + |> Array.map (fun ty -> + { Name=UNone + Default=UNone + //Marshal=None + Attributes= ParameterAttributes.None + ParameterType=ty + CustomAttrs=ILCustomAttrsStatics.Empty }) + for i = pidx1 to pidx2 - 1 do + seekReadParamExtras (retRes, paramsRes) i + !retRes, paramsRes + + and seekReadParamExtras (retRes, paramsRes) (idx:int) = + let (flags, seq, nameIdx) = seekReadParamRow idx + //let _hasMarshal = (flags &&& 0x2000) <> 0x0 + let hasDefault = (flags &&& 0x1000) <> 0x0 + //let fmReader idx = seekReadIndexedRow (getNumRows ILTableNames.FieldMarshal, seekReadFieldMarshalRow, fst, hfmCompare idx, isSorted ILTableNames.FieldMarshal, (snd >> readBlobHeapAsNativeType ctxt)) + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ParamDef, idx)) + if seq = 0 then + retRes := { !retRes with + //Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None); + CustomAttrs = cas } + else + paramsRes.[seq - 1] <- + { paramsRes.[seq - 1] with + //Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef, idx))) else None) + Default = (if hasDefault then USome (seekReadConstant (TaggedIndex(HasConstantTag.ParamDef, idx))) else UNone) + Name = readStringHeapOption nameIdx + Attributes = enum flags + CustomAttrs = cas } + + and seekReadMethodImpls numtypars tidx = + { new ILMethodImplDefs with + member __.Entries = + let mimpls = seekReadIndexedRows (getNumRows ILTableNames.MethodImpl, seekReadMethodImplRow, (fun (a, _, _) -> a), simpleIndexCompare tidx, isSorted ILTableNames.MethodImpl, (fun (_, b, c) -> b, c)) + mimpls |> Array.map (fun (b, c) -> + { OverrideBy= + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs numtypars b + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst); + Overrides= + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefOrRefNoVarargs numtypars c + let mspec = mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst) + OverridesSpec(mspec.MethodRef, mspec.EnclosingType) }) } + + and seekReadMultipleMethodSemantics (flags, id) = + seekReadIndexedRows + (getNumRows ILTableNames.MethodSemantics , + seekReadMethodSemanticsRow, + (fun (_flags, _, c) -> c), + hsCompare id, + isSorted ILTableNames.MethodSemantics, + (fun (a, b, _c) -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData b + a, (mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst)).MethodRef)) + |> Array.filter (fun (flags2, _) -> flags = flags2) + |> Array.map snd + + + and seekReadOptionalMethodSemantics id = + match seekReadMultipleMethodSemantics id with + | [| |] -> None + | xs -> Some xs.[0] + + and seekReadMethodSemantics id = + match seekReadOptionalMethodSemantics id with + | None -> failwith "seekReadMethodSemantics ctxt: no method found" + | Some x -> x + + and seekReadEvent _numtypars idx = + let (flags, nameIdx, _typIdx) = seekReadEventRow idx + { Name = readStringHeap nameIdx + //EventHandlerType = seekReadOptionalTypeDefOrRef numtypars AsObject typIdx + Attributes = enum(flags) + AddMethod= seekReadMethodSemantics (0x0008, TaggedIndex(HasSemanticsTag.Event, idx)) + RemoveMethod=seekReadMethodSemantics (0x0010, TaggedIndex(HasSemanticsTag.Event, idx)) + //FireMethod=seekReadOptionalMethodSemantics (0x0020, TaggedIndex(HasSemanticsTag.Event, idx)) + //OtherMethods = seekReadMultipleMethodSemantics (0x0004, TaggedIndex(HasSemanticsTag.Event, idx)) + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Event, idx)) + Token = idx} + + and seekReadEvents numtypars tidx = + { new ILEventDefs with + member __.Entries = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.EventMap, (fun i -> i, seekReadEventMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + | None -> [| |] + | Some (rowNum, beginEventIdx) -> + let endEventIdx = + if rowNum >= getNumRows ILTableNames.EventMap then + getNumRows ILTableNames.Event + 1 + else + let (_, endEventIdx) = seekReadEventMapRow (rowNum + 1) + endEventIdx + + [| for i in beginEventIdx .. endEventIdx - 1 do + yield seekReadEvent numtypars i |] } + + and seekReadProperty numtypars idx = + let (flags, nameIdx, typIdx) = seekReadPropertyRow idx + let cc, retty, argtys = readBlobHeapAsPropertySig numtypars typIdx + let setter= seekReadOptionalMethodSemantics (0x0001, TaggedIndex(HasSemanticsTag.Property, idx)) + let getter = seekReadOptionalMethodSemantics (0x0002, TaggedIndex(HasSemanticsTag.Property, idx)) + let cc2 = + match getter with + | Some mref -> mref.CallingConv.ThisConv + | None -> + match setter with + | Some mref -> mref.CallingConv .ThisConv + | None -> cc + { Name=readStringHeap nameIdx + CallingConv = cc2 + Attributes = enum(flags) + SetMethod=setter; + GetMethod=getter; + PropertyType=retty; + Init= if (flags &&& 0x1000) = 0 then None else Some (seekReadConstant (TaggedIndex(HasConstantTag.Property, idx))); + IndexParameterTypes=argtys; + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Property, idx)) + Token = idx } + + and seekReadProperties numtypars tidx = + { new ILPropertyDefs with + member __.Entries = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.PropertyMap, (fun i -> i, seekReadPropertyMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + | None -> [| |] + | Some (rowNum, beginPropIdx) -> + let endPropIdx = + if rowNum >= getNumRows ILTableNames.PropertyMap then + getNumRows ILTableNames.Property + 1 + else + let (_, endPropIdx) = seekReadPropertyMapRow (rowNum + 1) + endPropIdx + [| for i in beginPropIdx .. endPropIdx - 1 do + yield seekReadProperty numtypars i |] } + + + and seekReadCustomAttrs idx = + { new ILCustomAttrs with + member __.Entries = + seekReadIndexedRows (getNumRows ILTableNames.CustomAttribute, + seekReadCustomAttributeRow, (fun (a, _, _) -> a), + hcaCompare idx, + isSorted ILTableNames.CustomAttribute, + (fun (_, b, c) -> seekReadCustomAttr (b, c))) } + + and seekReadCustomAttr (catIdx, valIdx) = + let data = + match readBlobHeapOption valIdx with + | USome bytes -> bytes + | UNone -> [| |] + { Method=seekReadCustomAttrType catIdx; + Data= data + Elements = [] } + + (* + and seekReadSecurityDecls idx = + mkILLazySecurityDecls + (lazy + seekReadIndexedRows (getNumRows ILTableNames.Permission, + seekReadPermissionRow, + (fun (_, par, _) -> par), + hdsCompare idx, + isSorted ILTableNames.Permission, + (fun (act, _, ty) -> seekReadSecurityDecl (act, ty)))) + + and seekReadSecurityDecl (a, b) = + ctxt.seekReadSecurityDecl (SecurityDeclIdx (a, b)) + + and seekReadSecurityDeclUncached ctxtH (SecurityDeclIdx (act, ty)) = + PermissionSet ((if List.memAssoc (int act) (Lazy.force ILSecurityActionRevMap) then List.assoc (int act) (Lazy.force ILSecurityActionRevMap) else failwith "unknown security action"), + readBlobHeap ty) + + *) + + and seekReadConstant idx = + let kind, vidx = seekReadIndexedRow (getNumRows ILTableNames.Constant, + seekReadConstantRow, + (fun (_, key, _) -> key), + hcCompare idx, isSorted ILTableNames.Constant, (fun (kind, _, v) -> kind, v)) + match kind with + | x when x = uint16 et_STRING -> + let blobHeap = readBlobHeap vidx + let s = Encoding.Unicode.GetString(blobHeap, 0, blobHeap.Length) + box s + | x when x = uint16 et_BOOLEAN -> box (readBlobHeapAsBool vidx) + | x when x = uint16 et_CHAR -> box (readBlobHeapAsUInt16 vidx) + | x when x = uint16 et_I1 -> box (readBlobHeapAsSByte vidx) + | x when x = uint16 et_I2 -> box (readBlobHeapAsInt16 vidx) + | x when x = uint16 et_I4 -> box (readBlobHeapAsInt32 vidx) + | x when x = uint16 et_I8 -> box (readBlobHeapAsInt64 vidx) + | x when x = uint16 et_U1 -> box (readBlobHeapAsByte vidx) + | x when x = uint16 et_U2 -> box (readBlobHeapAsUInt16 vidx) + | x when x = uint16 et_U4 -> box (readBlobHeapAsUInt32 vidx) + | x when x = uint16 et_U8 -> box (readBlobHeapAsUInt64 vidx) + | x when x = uint16 et_R4 -> box (readBlobHeapAsSingle vidx) + | x when x = uint16 et_R8 -> box (readBlobHeapAsDouble vidx) + | x when x = uint16 et_CLASS || x = uint16 et_OBJECT -> null + | _ -> null + + and seekReadManifestResources () = + ILResources + (lazy + [| for i = 1 to getNumRows ILTableNames.ManifestResource do + let (offset, flags, nameIdx, implIdx) = seekReadManifestResourceRow i + let scoref = seekReadImplAsScopeRef implIdx + let datalab = + match scoref with + | ILScopeRef.Local -> + ILResourceLocation.Local (fun () -> + // We re-crack the PE file on each resource read, which is a bit dodgy + let bytes = File.ReadAllBytes fileName + let is = ByteFile(bytes) + let pe = PEReader(fileName, is) + let start = pe.ResourcePhysLoc offset + let len = seekReadInt32 is start + seekReadBytes is (start + 4) len) + | ILScopeRef.Module mref -> ILResourceLocation.File (mref, offset) + | ILScopeRef.Assembly aref -> ILResourceLocation.Assembly aref + + let r = + { Name= readStringHeap nameIdx; + Location = datalab; + Access = (if (flags &&& 0x01) <> 0x0 then ILResourceAccess.Public else ILResourceAccess.Private); + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ManifestResource, i)) } + yield r |]) + + and seekReadNestedExportedTypes parentIdx = + ILNestedExportedTypesAndForwarders + (lazy + [| for i = 1 to getNumRows ILTableNames.ExportedType do + let (flags, _tok, nameIdx, namespaceIdx, implIdx) = seekReadExportedTypeRow i + if not (isTopTypeDef flags) then + let (TaggedIndex(tag, idx) ) = implIdx + match tag with + | tag when tag = ImplementationTag.ExportedType && idx = parentIdx -> + let _nsp, nm = readStringHeapAsTypeName (nameIdx, namespaceIdx) + yield + { Name=nm + Access=(match ILTypeDefAccess.OfFlags flags with ILTypeDefAccess.Nested n -> n | _ -> failwith "non-nested access for a nested type described as being in an auxiliary module") + Nested=seekReadNestedExportedTypes i + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ExportedType, i)) } + | _ -> () |]) + + and seekReadTopExportedTypes () = + ILExportedTypesAndForwarders + (lazy + [| for i = 1 to getNumRows ILTableNames.ExportedType do + let (flags, _tok, nameIdx, namespaceIdx, implIdx) = seekReadExportedTypeRow i + if isTopTypeDef flags then + let (TaggedIndex(tag, _idx) ) = implIdx + + // the nested types will be picked up by their enclosing types + if tag <> ImplementationTag.ExportedType then + let nsp, nm = readStringHeapAsTypeName (nameIdx, namespaceIdx) + + let scoref = seekReadImplAsScopeRef implIdx + + let entry = + { ScopeRef=scoref + Namespace=nsp + Name=nm + IsForwarder = ((flags &&& 0x00200000) <> 0) + Access=ILTypeDefAccess.OfFlags flags + Nested=seekReadNestedExportedTypes i + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ExportedType, i)) } + yield entry |]) + + + let ilModule = seekReadModule (ilMetadataVersion) 1 + let ilAssemblyRefs = [ for i in 1 .. getNumRows ILTableNames.AssemblyRef do yield seekReadAssemblyRef i ] + + member __.ILGlobals = ilg + member __.ILModuleDef = ilModule + member __.ILAssemblyRefs = ilAssemblyRefs + + let sigptr_get_byte (bytes: byte[]) sigptr = + int bytes.[sigptr], sigptr + 1 + + let sigptr_get_u8 bytes sigptr = + let b0, sigptr = sigptr_get_byte bytes sigptr + byte b0, sigptr + + let sigptr_get_bool bytes sigptr = + let b0, sigptr = sigptr_get_byte bytes sigptr + (b0 = 0x01) , sigptr + + let sigptr_get_i8 bytes sigptr = + let i, sigptr = sigptr_get_u8 bytes sigptr + sbyte i, sigptr + + let sigptr_get_u16 bytes sigptr = + let b0, sigptr = sigptr_get_byte bytes sigptr + let b1, sigptr = sigptr_get_byte bytes sigptr + uint16 (b0 ||| (b1 <<< 8)), sigptr + + let sigptr_get_i16 bytes sigptr = + let u, sigptr = sigptr_get_u16 bytes sigptr + int16 u, sigptr + + let sigptr_get_i32 bytes sigptr = + let b0, sigptr = sigptr_get_byte bytes sigptr + let b1, sigptr = sigptr_get_byte bytes sigptr + let b2, sigptr = sigptr_get_byte bytes sigptr + let b3, sigptr = sigptr_get_byte bytes sigptr + b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24), sigptr + + let sigptr_get_u32 bytes sigptr = + let u, sigptr = sigptr_get_i32 bytes sigptr + uint32 u, sigptr + + let sigptr_get_i64 bytes sigptr = + let b0, sigptr = sigptr_get_byte bytes sigptr + let b1, sigptr = sigptr_get_byte bytes sigptr + let b2, sigptr = sigptr_get_byte bytes sigptr + let b3, sigptr = sigptr_get_byte bytes sigptr + let b4, sigptr = sigptr_get_byte bytes sigptr + let b5, sigptr = sigptr_get_byte bytes sigptr + let b6, sigptr = sigptr_get_byte bytes sigptr + let b7, sigptr = sigptr_get_byte bytes sigptr + int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| + (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56), + sigptr + + let sigptr_get_u64 bytes sigptr = + let u, sigptr = sigptr_get_i64 bytes sigptr + uint64 u, sigptr + + + let ieee32_of_bits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x), 0) + let ieee64_of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x) + + let sigptr_get_ieee32 bytes sigptr = + let u, sigptr = sigptr_get_i32 bytes sigptr + ieee32_of_bits u, sigptr + + let sigptr_get_ieee64 bytes sigptr = + let u, sigptr = sigptr_get_i64 bytes sigptr + ieee64_of_bits u, sigptr + + let u8AsBytes (i:byte) = [| i |] + let u16AsBytes x = let n = (int x) in [| b0 n; b1 n |] + let i32AsBytes i = [| b0 i; b1 i; b2 i; b3 i |] + let i64AsBytes i = [| dw0 i; dw1 i; dw2 i; dw3 i; dw4 i; dw5 i; dw6 i; dw7 i |] + + let i8AsBytes (i:sbyte) = u8AsBytes (byte i) + let i16AsBytes (i:int16) = u16AsBytes (uint16 i) + let u32AsBytes (i:uint32) = i32AsBytes (int32 i) + let u64AsBytes (i:uint64) = i64AsBytes (int64 i) + let bits_of_float32 (x:float32) = BitConverter.ToInt32(BitConverter.GetBytes(x), 0) + let bits_of_float (x:float) = BitConverter.DoubleToInt64Bits(x) + + let ieee32AsBytes i = i32AsBytes (bits_of_float32 i) + let ieee64AsBytes i = i64AsBytes (bits_of_float i) + + + let (|ElementType|_|) (ty: ILType) = + match ty with + | ILType.Boxed tspec -> + match tspec.Namespace, tspec.Name with + | USome "System", "String"-> Some et_STRING + | USome "System", "Object"-> Some et_OBJECT + | _ -> None + | ILType.Value tspec -> + match tspec.Namespace, tspec.Name with + | USome "System", "Int32" -> Some et_I4 + | USome "System", "SByte" -> Some et_I1 + | USome "System", "Int16"-> Some et_I2 + | USome "System", "Int64" -> Some et_I8 + | USome "System", "IntPtr" -> Some et_I + | USome "System", "Byte" -> Some et_U1 + | USome "System", "UInt16"-> Some et_U2 + | USome "System", "UInt32" -> Some et_U4 + | USome "System", "UInt64" -> Some et_U8 + | USome "System", "UIntPtr" -> Some et_U + | USome "System", "Double" -> Some et_R8 + | USome "System", "Single" -> Some et_R4 + | USome "System", "Char" -> Some et_CHAR + | USome "System", "Boolean" -> Some et_BOOLEAN + | USome "System", "TypedReference" -> Some et_TYPEDBYREF + | _ -> None + | _ -> None + + let encodeCustomAttrString (s: string) = + let arr = Encoding.UTF8.GetBytes s + Array.concat [ ByteBuffer.Z32 arr.Length; arr ] + + let rec encodeCustomAttrElemType x = + match x with + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Object" -> [| 0x51uy |] + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Type" -> [| 0x50uy |] + | ElementType et -> [| et |] + | ILType.Value tspec -> Array.append [| 0x55uy |] (encodeCustomAttrString tspec.TypeRef.QualifiedName) + | ILType.Array (shape, elemType) when shape = ILArrayShape.SingleDimensional -> + Array.append [| et_SZARRAY |] (encodeCustomAttrElemType elemType) + | _ -> failwith "encodeCustomAttrElemType: unrecognized custom element type" + + /// Given a custom attribute element, work out the type of the .NET argument for that element. + let rec encodeCustomAttrElemTypeForObject (x: obj) = + match x with + | :? string -> [| et_STRING |] + | :? bool -> [| et_BOOLEAN |] + | :? char -> [| et_CHAR |] + | :? sbyte -> [| et_I1 |] + | :? int16 -> [| et_I2 |] + | :? int32 -> [| et_I4 |] + | :? int64 -> [| et_I8 |] + | :? byte -> [| et_U1 |] + | :? uint16 -> [| et_U2 |] + | :? uint32 -> [| et_U4 |] + | :? uint64 -> [| et_U8 |] + | :? ILType -> [| 0x50uy |] + | :? Type -> [| 0x50uy |] + | null -> [| et_STRING |]// yes, the 0xe prefix is used when passing a "null" to a property or argument of type "object" here + | :? single -> [| et_R4 |] + | :? double -> [| et_R8 |] + | :? (obj[]) -> failwith "TODO: can't yet emit arrays in attrs" // [| yield et_SZARRAY; yield! encodeCustomAttrElemType elemTy |] + | _ -> failwith "unexpected value in custom attribute" + + /// Given a custom attribute element, encode it to a binary representation according to the rules in Ecma 335 Partition II. + let rec encodeCustomAttrPrimValue (c: obj) = + match c with + | :? bool as b -> [| (if b then 0x01uy else 0x00uy) |] + | null -> [| 0xFFuy |] + | :? string as s -> encodeCustomAttrString s + | :? char as x -> u16AsBytes (uint16 x) + | :? SByte as x -> i8AsBytes x + | :? Int16 as x -> i16AsBytes x + | :? Int32 as x -> i32AsBytes x + | :? Int64 as x -> i64AsBytes x + | :? Byte as x -> u8AsBytes x + | :? UInt16 as x -> u16AsBytes x + | :? UInt32 as x -> u32AsBytes x + | :? UInt64 as x -> u64AsBytes x + | :? Single as x -> ieee32AsBytes x + | :? Double as x -> ieee64AsBytes x + | :? ILType as ty -> encodeCustomAttrString ty.QualifiedName + | :? Type as ty -> encodeCustomAttrString ty.FullName + | :? (obj[]) as elems -> + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue elem |] + | _ -> failwith "unexpected value in custom attribute" + + and encodeCustomAttrValue ty (c: obj) = + match ty, c with + | ILType.Boxed tspec, _ when tspec.Namespace = USome "System" && tspec.Name = "Object" -> + [| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue c |] + | ILType.Array (shape, _), null when shape = ILArrayShape.SingleDimensional -> + [| yield! i32AsBytes 0xFFFFFFFF |] + | ILType.Array (shape, elemType), (:? (obj[]) as elems) when shape = ILArrayShape.SingleDimensional -> + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue elemType elem |] + | _ -> + encodeCustomAttrPrimValue c + + let encodeCustomAttrNamedArg prop (ILCustomAttrNamedArg (nm, ty, elem)) = + [| yield (if prop then 0x54uy else 0x53uy) + yield! encodeCustomAttrElemType ty + yield! encodeCustomAttrString nm + yield! encodeCustomAttrValue ty elem |] + + let mkILCustomAttribMethRef (mspec:ILMethodSpec, fixedArgs: obj list, propArgs: ILCustomAttrNamedArg list, fieldArgs: ILCustomAttrNamedArg list) = + let argtys = mspec.MethodRef.ArgTypes + let nnamed = propArgs.Length + fieldArgs.Length + let data = + [| yield! [| 0x01uy; 0x00uy; |] + for (argty, fixedArg) in Seq.zip argtys fixedArgs do + yield! encodeCustomAttrValue argty fixedArg + yield! u16AsBytes (uint16 nnamed ) + for arg in propArgs do + yield! encodeCustomAttrNamedArg true arg + for arg in fieldArgs do + yield! encodeCustomAttrNamedArg false arg |] + //printfn "mkILCustomAttribMethRef, nnamed = %d, data.Length = %d, data = %A" nnamed data.Length data + { Method = mspec; + Data = data; + Elements = fixedArgs @ (propArgs |> List.map(fun (ILCustomAttrNamedArg(_, _, e)) -> e)) @ (fieldArgs |> List.map(fun (ILCustomAttrNamedArg(_, _, e)) -> e)) } + + let rec decodeCustomAttrElemType ilg bytes sigptr x = + match x with + | x when x = et_I1 -> ilg.typ_SByte, sigptr + | x when x = et_U1 -> ilg.typ_Byte, sigptr + | x when x = et_I2 -> ilg.typ_Int16, sigptr + | x when x = et_U2 -> ilg.typ_UInt16, sigptr + | x when x = et_I4 -> ilg.typ_Int32, sigptr + | x when x = et_U4 -> ilg.typ_UInt32, sigptr + | x when x = et_I8 -> ilg.typ_Int64, sigptr + | x when x = et_U8 -> ilg.typ_UInt64, sigptr + | x when x = et_R8 -> ilg.typ_Double, sigptr + | x when x = et_R4 -> ilg.typ_Single, sigptr + | x when x = et_CHAR -> ilg.typ_Char, sigptr + | x when x = et_BOOLEAN -> ilg.typ_Boolean, sigptr + | x when x = et_STRING -> ilg.typ_String, sigptr + | x when x = et_OBJECT -> ilg.typ_Object, sigptr + | x when x = et_SZARRAY -> + let et, sigptr = sigptr_get_u8 bytes sigptr + let elemTy, sigptr = decodeCustomAttrElemType ilg bytes sigptr et + mkILArr1DTy elemTy, sigptr + | x when x = 0x50uy -> ilg.typ_Type, sigptr + | _ -> failwithf "decodeCustomAttrElemType ilg: sigptr = %d, unrecognized custom element type: %A, bytes = %A" sigptr x bytes + + // Parse an IL type signature argument within a custom attribute blob + type ILTypeSigParser(tstring: string) = + + let mutable startPos = 0 + let mutable currentPos = 0 + + //let reset() = startPos <- 0 ; currentPos <- 0 + let nil = '\r' // cannot appear in a type sig + + // take a look at the next value, but don't advance + let peek() = if currentPos < (tstring.Length-1) then tstring.[currentPos+1] else nil + let peekN(skip) = if currentPos < (tstring.Length - skip) then tstring.[currentPos+skip] else nil + // take a look at the current value, but don't advance + let here() = if currentPos < tstring.Length then tstring.[currentPos] else nil + // move on to the next character + let step() = currentPos <- currentPos+1 + // ignore the current lexeme + let skip() = startPos <- currentPos + // ignore the current lexeme, advance + let drop() = skip() ; step() ; skip() + // return the current lexeme, advance + let take() = + let s = if currentPos < tstring.Length then tstring.[startPos..currentPos] else "" + drop() + s + + // The format we accept is + // "{`[, +]}{}{}" E.g., + // + // System.Collections.Generic.Dictionary + // `2[ + // [System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], + // dev.virtualearth.net.webservices.v1.search.CategorySpecificPropertySet], + // mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" + // + // Note that + // Since we're only reading valid IL, we assume that the signature is properly formed + // For type parameters, if the type is non-local, it will be wrapped in brackets ([]) + member x.ParseType() = + + // Does the type name start with a leading '['? If so, ignore it + // (if the specialization type is in another module, it will be wrapped in bracket) + if here() = '[' then drop() + + // 1. Iterate over beginning of type, grabbing the type name and determining if it's generic or an array + let typeName = + while (peek() <> '`') && (peek() <> '[') && (peek() <> ']') && (peek() <> ',') && (peek() <> nil) do step() + take() + + // 2. Classify the type + + // Is the type generic? + let typeName, specializations = + if here() = '`' then + drop() // step to the number + // fetch the arity + let arity = + while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step() + System.Int32.Parse(take()) + + // typically types are saturated, i.e. if generic they have arguments. However, assembly metadata for reflectedDefinitions they occur free. + // this code takes care of exactly this case. + if here () = '[' then + // skip the '[' + drop() + // get the specializations + typeName+"`"+(arity.ToString()), Some(([| for _i in 0..arity-1 do yield x.ParseType() |])) + else + typeName+"`"+(arity.ToString()), None + else + typeName, None + + // Is the type an array? + let rank = + if here() = '[' then + let mutable rank = 0 + + while here() <> ']' do + rank <- rank + 1 + step() + drop() + + Some(ILArrayShape(Array.create rank (Some 0, None))) + else + None + + // Is there a scope? + let scope = + if (here() = ',' || here() = ' ') && (peek() <> '[' && peekN(2) <> '[') then + let grabScopeComponent() = + if here() = ',' then drop() // ditch the ',' + if here() = ' ' then drop() // ditch the ' ' + + while (peek() <> ',' && peek() <> ']' && peek() <> nil) do step() + take() + + let scope = + [ yield grabScopeComponent() // assembly + yield grabScopeComponent() // version + yield grabScopeComponent() // culture + yield grabScopeComponent() // public key token + ] |> String.concat "," + ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(scope))) + else + ILScopeRef.Local + + // strip any extraneous trailing brackets or commas + if (here() = ']') then drop() + if (here() = ',') then drop() + + // build the IL type + let tref = + let nsp, nm = splitILTypeName typeName + ILTypeRef(ILTypeRefScope.Top scope, nsp, nm) + + let genericArgs = + match specializations with + | None -> [| |] + | Some(genericArgs) -> genericArgs + let tspec = ILTypeSpec(tref, genericArgs) + let ilty = + match tspec.Name with + | "System.SByte" + | "System.Byte" + | "System.Int16" + | "System.UInt16" + | "System.Int32" + | "System.UInt32" + | "System.Int64" + | "System.UInt64" + | "System.Char" + | "System.Double" + | "System.Single" + | "System.Boolean" -> ILType.Value(tspec) + | _ -> ILType.Boxed(tspec) + + // if it's an array, wrap it - otherwise, just return the IL type + match rank with + | Some(r) -> ILType.Array(r, ilty) + | _ -> ilty + + + let sigptr_get_bytes n (bytes:byte[]) sigptr = + let res = Array.zeroCreate n + for i = 0 to n - 1 do + res.[i] <- bytes.[sigptr + i] + res, sigptr + n + + let sigptr_get_string n bytes sigptr = + let intarray, sigptr = sigptr_get_bytes n bytes sigptr + Encoding.UTF8.GetString(intarray , 0, intarray.Length), sigptr + + let sigptr_get_serstring bytes sigptr = + let len, sigptr = sigptrGetZInt32 bytes sigptr + sigptr_get_string len bytes sigptr + + let sigptr_get_serstring_possibly_null bytes sigptr = + let b0, new_sigptr = sigptr_get_byte bytes sigptr + if b0 = 0xFF then // null case + None, new_sigptr + else // throw away new_sigptr, getting length & text advance + let len, sigptr = sigptrGetZInt32 bytes sigptr + let s, sigptr = sigptr_get_string len bytes sigptr + Some(s), sigptr + + let decodeILCustomAttribData ilg (ca: ILCustomAttribute) = + let bytes = ca.Data + let sigptr = 0 + let bb0, sigptr = sigptr_get_byte bytes sigptr + let bb1, sigptr = sigptr_get_byte bytes sigptr + if not (bb0 = 0x01 && bb1 = 0x00) then failwith "decodeILCustomAttribData: invalid data"; + + let rec parseVal argty sigptr = + match argty with + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "SByte" -> + let n, sigptr = sigptr_get_i8 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Byte" -> + let n, sigptr = sigptr_get_u8 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int16" -> + let n, sigptr = sigptr_get_i16 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt16" -> + let n, sigptr = sigptr_get_u16 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int32" -> + let n, sigptr = sigptr_get_i32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt32" -> + let n, sigptr = sigptr_get_u32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int64" -> + let n, sigptr = sigptr_get_i64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt64" -> + let n, sigptr = sigptr_get_u64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Double" -> + let n, sigptr = sigptr_get_ieee64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Single" -> + let n, sigptr = sigptr_get_ieee32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Char" -> + let n, sigptr = sigptr_get_u16 bytes sigptr + (argty, box (char n)), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Boolean" -> + let n, sigptr = sigptr_get_byte bytes sigptr + (argty, box (not (n = 0))), sigptr + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "String" -> + //printfn "parsing string, sigptr = %d" sigptr + let n, sigptr = sigptr_get_serstring_possibly_null bytes sigptr + //printfn "got string, sigptr = %d" sigptr + (argty, box (match n with None -> null | Some s -> s)), sigptr + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Type" -> + let nOpt, sigptr = sigptr_get_serstring_possibly_null bytes sigptr + match nOpt with + | None -> (argty, box null) , sigptr // TODO: read System.Type attrs + | Some n -> + try + let parser = ILTypeSigParser(n) + parser.ParseType() |> ignore + (argty, box null) , sigptr // TODO: read System.Type attributes + with e -> + failwithf "decodeILCustomAttribData: error parsing type in custom attribute blob: %s" e.Message + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Object" -> + let et, sigptr = sigptr_get_u8 bytes sigptr + if et = 0xFFuy then + (argty, null), sigptr + else + let ty, sigptr = decodeCustomAttrElemType ilg bytes sigptr et + parseVal ty sigptr + | ILType.Array(shape, elemTy) when shape = ILArrayShape.SingleDimensional -> + let n, sigptr = sigptr_get_i32 bytes sigptr + if n = 0xFFFFFFFF then (argty, null), sigptr else + let rec parseElems acc n sigptr = + if n = 0 then List.rev acc, sigptr else + let v, sigptr = parseVal elemTy sigptr + parseElems (v ::acc) (n-1) sigptr + let elems, sigptr = parseElems [] n sigptr + let elems = elems |> List.map snd |> List.toArray + (argty, box elems), sigptr + | ILType.Value _ -> (* assume it is an enumeration *) + let n, sigptr = sigptr_get_i32 bytes sigptr + (argty, box n), sigptr + | _ -> failwith "decodeILCustomAttribData: attribute data involves an enum or System.Type value" + + let rec parseFixed argtys sigptr = + match argtys with + | [] -> [], sigptr + | h::t -> + let nh, sigptr = parseVal h sigptr + let nt, sigptr = parseFixed t sigptr + nh ::nt, sigptr + + let fixedArgs, sigptr = parseFixed (List.ofArray ca.Method.FormalArgTypes) sigptr + let nnamed, sigptr = sigptr_get_u16 bytes sigptr + //printfn "nnamed = %d" nnamed + + try + let rec parseNamed acc n sigptr = + if n = 0 then List.rev acc else + let isPropByte, sigptr = sigptr_get_u8 bytes sigptr + let isProp = (int isPropByte = 0x54) + let et, sigptr = sigptr_get_u8 bytes sigptr + // We have a named value + let ty, sigptr = + if ((* 0x50 = (int et) || *) 0x55 = (int et)) then + let qualified_tname, sigptr = sigptr_get_serstring bytes sigptr + let unqualified_tname, rest = + let pieces = qualified_tname.Split(',') + if pieces.Length > 1 then + pieces.[0], Some (String.concat "," pieces.[1..]) + else + pieces.[0], None + let scoref = + match rest with + | Some aname -> ILTypeRefScope.Top(ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))) + | None -> ilg.typ_Boolean.TypeSpec.Scope + + let nsp, nm = splitILTypeName unqualified_tname + let tref = ILTypeRef (scoref, nsp, nm) + let tspec = mkILNonGenericTySpec tref + ILType.Value(tspec), sigptr + else + decodeCustomAttrElemType ilg bytes sigptr et + let nm, sigptr = sigptr_get_serstring bytes sigptr + let (_, v), sigptr = parseVal ty sigptr + parseNamed ((nm, ty, isProp, v) :: acc) (n-1) sigptr + let named = parseNamed [] (int nnamed) sigptr + fixedArgs, named + + with err -> + failwithf "FAILED decodeILCustomAttribData, data.Length = %d, data = %A, meth = %A, argtypes = %A, fixedArgs=%A, nnamed = %A, sigptr before named = %A, innerError = %A" bytes.Length bytes ca.Method.EnclosingType ca.Method.FormalArgTypes fixedArgs nnamed sigptr (err.ToString()) + + // Share DLLs within a provider by weak-caching them. + let readerWeakCache = ConcurrentDictionary<(string * string), DateTime * WeakReference>(HashIdentity.Structural) + + // Share DLLs across providers by strong-caching them, but flushing regularly + let readerStrongCache = ConcurrentDictionary<(string * string), DateTime * int * ILModuleReader>(HashIdentity.Structural) + + type File with + static member ReadBinaryChunk (fileName: string, start, len) = + use stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) + stream.Seek(int64 start, SeekOrigin.Begin) |> ignore + let buffer = Array.zeroCreate len + let mutable n = 0 + while n < len do + n <- n + stream.Read(buffer, n, len-n) + buffer + + let createReader ilGlobals (fileName: string) = + let bytes = File.ReadAllBytes fileName + let is = ByteFile(bytes) + let pe = PEReader(fileName, is) + let mdchunk = File.ReadBinaryChunk (fileName, pe.MetadataPhysLoc, pe.MetadataSize) + let mdfile = ByteFile(mdchunk) + let reader = ILModuleReader(fileName, mdfile, ilGlobals, true) + reader + + let GetWeakReaderCache () = readerWeakCache + let GetStrongReaderCache () = readerStrongCache + + // Auto-clear the cache every 30.0 seconds. + // We would use System.Runtime.Caching but some version constraints make this difficult. + let enableAutoClear = try Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_OFF") = null with _ -> true + let clearSpanDefault = 30000 + let clearSpan = try (match Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_SPAN") with null -> clearSpanDefault | s -> int32 s) with _ -> clearSpanDefault + let lastAccessLock = obj() + let mutable lastAccess = DateTime.Now + + let StartClearReaderCache() = + if enableAutoClear then + async { + while true do + do! Async.Sleep clearSpan + let timeSinceLastAccess = DateTime.Now - lock lastAccessLock (fun () -> lastAccess) + if timeSinceLastAccess > TimeSpan.FromMilliseconds(float clearSpan) then + readerStrongCache.Clear() + } + |> Async.Start + + do StartClearReaderCache() + + let (|WeakReference|_|) (x: WeakReference<'T>) = + match x.TryGetTarget() with + | true, v -> Some v + | _ -> None + + let ILModuleReaderAfterReadingAllBytes (file:string, ilGlobals: ILGlobals) = + let key = (file, ilGlobals.systemRuntimeScopeRef.QualifiedName) + lock lastAccessLock (fun () -> lastAccess <- DateTime.Now) + + // Check the weak cache, to enable sharing within a provider, even if the strong cache is flushed. + match readerWeakCache.TryGetValue(key) with + | true, (currentLastWriteTime, WeakReference(reader)) when + let lastWriteTime = File.GetLastWriteTime(file) + currentLastWriteTime = lastWriteTime -> + + reader + + | _ -> + let add _ = + let lastWriteTime = File.GetLastWriteTime(file) + let reader = createReader ilGlobals file + // record in the weak cache, to enable sharing within a provider, even if the strong cache is flushed. + readerWeakCache.[key] <- (lastWriteTime, WeakReference<_>(reader)) + (lastWriteTime, 1, reader) + + let update _ (currentLastWriteTime, count, reader) = + let lastWriteTime = File.GetLastWriteTime(file) + if currentLastWriteTime <> lastWriteTime then + let reader = createReader ilGlobals file + // record in the weak cache, to enable sharing within a provider, even if the strong cache is flushed. + readerWeakCache.[key] <- (lastWriteTime, WeakReference<_>(reader)) + (lastWriteTime, count + 1, reader) + else + (lastWriteTime, count, reader) + let _, _, reader = readerStrongCache.AddOrUpdate(key, add, update) + reader + + (* NOTE: ecma_ prefix refers to the standard "mscorlib" *) + let EcmaPublicKey = PublicKeyToken ([|0xdeuy; 0xaduy; 0xbeuy; 0xefuy; 0xcauy; 0xfeuy; 0xfauy; 0xceuy |]) + let EcmaMscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef("mscorlib", UNone, USome EcmaPublicKey, true, UNone, UNone)) + +//==================================================================================================== +// TargetAssembly +// +// An implementation of reflection objects over on-disk assemblies, sufficient to give +// System.Type, System.MethodInfo, System.ConstructorInfo etc. objects +// that can be referred to in quotations and used as backing information for cross- +// targeting F# type providers. + + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + + // + // The on-disk assemblies are read by AssemblyReader. + // + // Background + // ---------- + // + // Provided type/member definitions need to refer to non-provided definitions like "System.Object" and "System.String". + // + // For cross-targeting F# type providers, these can be references to assemblies that can't easily be loaded by .NET + // reflection. For this reason, an implementation of the .NET reflection objects is needed. At minimum this + // implementation must support the operations used by the F# compiler to interrogate the reflection objects. + // + // For a System.Assembly, the information must be sufficient to allow the Assembly --> ILScopeRef conversion + // in ExtensionTyping.fs of the F# compiler. This requires: + // Assembly.GetName() + // + // For a System.Type representing a reference to a named type definition, the information must be sufficient + // to allow the Type --> ILTypeRef conversion in the F# compiler. This requires: + // typ.DeclaringType + // typ.Name + // typ.Namespace + // + // For a System.Type representing a type expression, the information must be sufficient to allow the Type --> ILType.Var conversion in the F# compiler. + // typeof.Equals(typ) + // typ.IsGenericParameter + // typ.GenericParameterPosition + // typ.IsArray + // typ.GetElementType() + // typ.GetArrayRank() + // typ.IsByRef + // typ.GetElementType() + // typ.IsPointer + // typ.GetElementType() + // typ.IsGenericType + // typ.GetGenericArguments() + // typ.GetGenericTypeDefinition() + // + // For a System.MethodBase --> ILType.ILMethodRef conversion: + // + // :?> MethodInfo as minfo + // + // minfo.IsGenericMethod || minfo.DeclaringType.IsGenericType + // minfo.DeclaringType.GetGenericTypeDefinition + // minfo.DeclaringType.GetMethods().MetadataToken + // minfo.MetadataToken + // minfo.IsGenericMethod + // minfo.GetGenericArguments().Length + // minfo.ReturnType + // minfo.GetParameters | .ParameterType + // minfo.Name + // + // :?> ConstructorInfo as cinfo + // + // cinfo.DeclaringType.IsGenericType + // cinfo.DeclaringType.GetGenericTypeDefinition + // cinfo.DeclaringType.GetConstructors() GetParameters | .ParameterType + // + + #nowarn "40" + + open System + open System.IO + open System.Collections.Generic + open System.Reflection + open ProviderImplementation.ProvidedTypes.AssemblyReader + + + [] + module Utils2 = + + // A table tracking how wrapped type definition objects are translated to cloned objects. + // Unique wrapped type definition objects must be translated to unique wrapper objects, based + // on object identity. + type TxTable<'T2>() = + let tab = Dictionary() + member __.Get inp f = + if tab.ContainsKey inp then + tab.[inp] + else + let res = f() + tab.[inp] <- res + res + + member __.ContainsKey inp = tab.ContainsKey inp + + + let instParameterInfo typeBuilder inst (inp: ParameterInfo) = + { new ParameterInfo() with + override __.Name = inp.Name + override __.ParameterType = inp.ParameterType |> instType typeBuilder inst + override __.Attributes = inp.Attributes + override __.RawDefaultValue = inp.RawDefaultValue + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.ToString() = inp.ToString() + "@inst" } + + let hashILParameterTypes (ps: ILParameters) = + // This hash code doesn't need to be very good as hashing by name is sufficient to give decent hash granularity + ps.Length + + let eqILScopeRef (_sco1: ILScopeRef) (_sco2: ILScopeRef) = + true // TODO (though omitting this is not a problem in practice since type equivalence by name is sufficient to bind methods) + + let eqAssemblyAndILScopeRef (_ass1: Assembly) (_sco2: ILScopeRef) = + true // TODO (though omitting this is not a problem in practice since type equivalence by name is sufficient to bind methods) + + + let rec eqILTypeRef (ty1: ILTypeRef) (ty2: ILTypeRef) = + ty1.Name = ty2.Name && eqILTypeRefScope ty1.Scope ty2.Scope + + and eqILTypeRefScope (ty1: ILTypeRefScope) (ty2: ILTypeRefScope) = + match ty1, ty2 with + | ILTypeRefScope.Top scoref1, ILTypeRefScope.Top scoref2 -> eqILScopeRef scoref1 scoref2 + | ILTypeRefScope.Nested tref1, ILTypeRefScope.Nested tref2 -> eqILTypeRef tref1 tref2 + | _ -> false + + and eqILTypes (tys1: ILType[]) (tys2: ILType[]) = + lengthsEqAndForall2 tys1 tys2 eqILType + + and eqILType (ty1: ILType) (ty2: ILType) = + match ty1, ty2 with + | (ILType.Value(tspec1) | ILType.Boxed(tspec1)), (ILType.Value(tspec2) | ILType.Boxed(tspec2))-> + eqILTypeRef tspec1.TypeRef tspec2.TypeRef && eqILTypes tspec1.GenericArgs tspec2.GenericArgs + | ILType.Array(rank1, arg1), ILType.Array(rank2, arg2) -> + rank1 = rank2 && eqILType arg1 arg2 + | ILType.Ptr(arg1), ILType.Ptr(arg2) -> + eqILType arg1 arg2 + | ILType.Byref(arg1), ILType.Byref(arg2) -> + eqILType arg1 arg2 + | ILType.Var(arg1), ILType.Var(arg2) -> + arg1 = arg2 + | _ -> false + + let rec eqTypeAndILTypeRef (ty1: Type) (ty2: ILTypeRef) = + ty1.Name = ty2.Name && + ty1.Namespace = (StructOption.toObj ty2.Namespace) && + match ty2.Scope with + | ILTypeRefScope.Top scoref2 -> eqAssemblyAndILScopeRef ty1.Assembly scoref2 + | ILTypeRefScope.Nested tref2 -> ty1.IsNested && eqTypeAndILTypeRef ty1.DeclaringType tref2 + + let rec eqTypesAndILTypes (tys1: Type[]) (tys2: ILType[]) = + eqTypesAndILTypesWithInst [| |] tys1 tys2 + + and eqTypesAndILTypesWithInst inst2 (tys1: Type[]) (tys2: ILType[]) = + lengthsEqAndForall2 tys1 tys2 (eqTypeAndILTypeWithInst inst2) + + and eqTypeAndILTypeWithInst inst2 (ty1: Type) (ty2: ILType) = + match ty2 with + | (ILType.Value(tspec2) | ILType.Boxed(tspec2))-> + if tspec2.GenericArgs.Length > 0 then + ty1.IsGenericType && eqTypeAndILTypeRef (ty1.GetGenericTypeDefinition()) tspec2.TypeRef && eqTypesAndILTypesWithInst inst2 (ty1.GetGenericArguments()) tspec2.GenericArgs + else + not ty1.IsGenericType && eqTypeAndILTypeRef ty1 tspec2.TypeRef + | ILType.Array(rank2, arg2) -> + ty1.IsArray && ty1.GetArrayRank() = rank2.Rank && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Ptr(arg2) -> + ty1.IsPointer && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Byref(arg2) -> + ty1.IsByRef && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Var(arg2) -> + if int arg2 < inst2.Length then + eqTypes ty1 inst2.[int arg2] + else + ty1.IsGenericParameter && ty1.GenericParameterPosition = int arg2 + + | _ -> false + + let eqParametersAndILParameterTypesWithInst inst2 (ps1: ParameterInfo[]) (ps2: ILParameters) = + lengthsEqAndForall2 ps1 ps2 (fun p1 p2 -> eqTypeAndILTypeWithInst inst2 p1.ParameterType p2.ParameterType) + + + type MethodSymbol2(gmd: MethodInfo, gargs: Type[], typeBuilder: ITypeBuilder) = + inherit MethodInfo() + let dty = gmd.DeclaringType + let dinst = (if dty.IsGenericType then dty.GetGenericArguments() else [| |]) + + override __.Attributes = gmd.Attributes + override __.Name = gmd.Name + override __.DeclaringType = dty + override __.MemberType = gmd.MemberType + + override __.GetParameters() = gmd.GetParameters() |> Array.map (instParameterInfo typeBuilder (dinst, gargs)) + override __.CallingConvention = gmd.CallingConvention + override __.ReturnType = gmd.ReturnType |> instType typeBuilder (dinst, gargs) + override __.GetGenericMethodDefinition() = gmd + override __.IsGenericMethod = gmd.IsGenericMethod + override __.GetGenericArguments() = gargs + override __.MetadataToken = gmd.MetadataToken + + override __.GetCustomAttributesData() = gmd.GetCustomAttributesData() + override __.MakeGenericMethod(typeArgs) = MethodSymbol2(gmd, typeArgs, typeBuilder) :> MethodInfo + override __.GetHashCode() = gmd.MetadataToken + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes dty that.DeclaringType && lengthsEqAndForall2 (gmd.GetGenericArguments()) (that.GetGenericArguments()) (=) + | _ -> false + + + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override __.GetCustomAttributes(inherited) = + gmd.GetCustomAttributes(inherited) + override __.GetCustomAttributes(attributeType, inherited) = + gmd.GetCustomAttributes(attributeType, inherited) + + override __.ToString() = gmd.ToString() + "@inst" + + + /// Represents a constructor in an instantiated type + type ConstructorSymbol (declTy: Type, inp: ConstructorInfo, typeBuilder: ITypeBuilder) = + inherit ConstructorInfo() + let gps = ((if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]), [| |]) + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Constructor + override __.DeclaringType = declTy + + override __.GetParameters() = inp.GetParameters() |> Array.map (instParameterInfo typeBuilder gps) + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.MetadataToken = inp.MetadataToken + + override __.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? ConstructorInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes declTy that.DeclaringType + | _ -> false + + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.GetCustomAttributes(inherited) = inp.GetCustomAttributes(inherited) + override this.GetCustomAttributes(attributeType, inherited) = inp.GetCustomAttributes(attributeType, inherited) + + override __.ToString() = sprintf "tgt constructor(...) in type %s" declTy.FullName + static member Make (typeBuilder: ITypeBuilder) (declTy: Type) md = ConstructorSymbol (declTy, md, typeBuilder) :> ConstructorInfo + + /// Represents a method in an instantiated type + type MethodSymbol (declTy: Type, inp: MethodInfo, typeBuilder: ITypeBuilder) = + inherit MethodInfo() + let gps1 = (if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]) + let gps2 = inp.GetGenericArguments() + let gps = (gps1, gps2) + + override __.Name = inp.Name + override __.DeclaringType = declTy + override __.MemberType = inp.MemberType + override __.Attributes = inp.Attributes + override __.GetParameters() = inp.GetParameters() |> Array.map (instParameterInfo typeBuilder gps) + override __.CallingConvention = inp.CallingConvention + override __.ReturnType = inp.ReturnType |> instType typeBuilder gps + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.GetGenericArguments() = gps2 + override __.IsGenericMethod = (gps2.Length <> 0) + override __.IsGenericMethodDefinition = __.IsGenericMethod + + override __.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.MakeGenericMethod(args) = MethodSymbol2(this, args, typeBuilder) :> MethodInfo + + override __.MetadataToken = inp.MetadataToken + + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(inherited) = inp.GetCustomAttributes(inherited) + override this.GetCustomAttributes(attributeType, inherited) = inp.GetCustomAttributes(attributeType, inherited) + + override __.ToString() = sprintf "tgt method %s(...) in type %s" inp.Name declTy.FullName + + static member Make (typeBuilder: ITypeBuilder) (declTy: Type) md = MethodSymbol (declTy, md, typeBuilder) :> MethodInfo + + /// Represents a property in an instantiated type + type PropertySymbol (declTy: Type, inp: PropertyInfo, typeBuilder: ITypeBuilder) = + inherit PropertyInfo() + let gps = ((if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]), [| |]) + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Property + override __.DeclaringType = declTy + + override __.PropertyType = inp.PropertyType |> instType typeBuilder gps + override __.GetGetMethod(nonPublic) = inp.GetGetMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make typeBuilder declTy) |> Option.toObj + override __.GetSetMethod(nonPublic) = inp.GetSetMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make typeBuilder declTy) |> Option.toObj + override __.GetIndexParameters() = inp.GetIndexParameters() |> Array.map (instParameterInfo typeBuilder gps) + override __.CanRead = inp.GetGetMethod(true) |> isNull |> not + override __.CanWrite = inp.GetSetMethod(true) |> isNull |> not + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.MetadataToken = inp.MetadataToken + + override __.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? PropertyInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture) = notRequired this "GetValue" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" this.Name + override this.GetAccessors(_nonPublic) = notRequired this "GetAccessors" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override __.ToString() = sprintf "tgt property %s(...) in type %s" inp.Name declTy.Name + + static member Make (typeBuilder: ITypeBuilder) (declTy: Type) md = PropertySymbol (declTy, md, typeBuilder) :> PropertyInfo + + /// Represents an event in an instantiated type + type EventSymbol (declTy: Type, inp: EventInfo, typeBuilder: ITypeBuilder) = + inherit EventInfo() + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Event + override __.DeclaringType = declTy + + override __.EventHandlerType = inp.EventHandlerType |> instType typeBuilder (gps, [| |]) + override __.GetAddMethod(nonPublic) = inp.GetAddMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make typeBuilder declTy) |> Option.toObj + override __.GetRemoveMethod(nonPublic) = inp.GetRemoveMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make typeBuilder declTy) |> Option.toObj + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.MetadataToken = inp.MetadataToken + + override __.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? EventInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetRaiseMethod(_nonPublic) = notRequired this "GetRaiseMethod" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override __.ToString() = sprintf "tgt event %s(...) in type %s" inp.Name declTy.FullName + + static member Make (typeBuilder: ITypeBuilder) (declTy: Type) md = EventSymbol (declTy, md, typeBuilder) :> EventInfo + + /// Represents a field in an instantiated type + type FieldSymbol (declTy: Type, inp: FieldInfo, typeBuilder: ITypeBuilder) = + inherit FieldInfo() + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Field + override __.DeclaringType = declTy + + override __.FieldType = inp.FieldType |> instType typeBuilder (gps, [| |]) + override __.GetRawConstantValue() = inp.GetRawConstantValue() + override __.GetCustomAttributesData() = inp.GetCustomAttributesData() + override __.MetadataToken = inp.MetadataToken + + override __.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? FieldInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" this.Name + override this.GetValue(_obj) = notRequired this "GetValue" this.Name + override this.FieldHandle = notRequired this "FieldHandle" this.Name + + override __.ToString() = sprintf "tgt literal field %s(...) in type %s" inp.Name declTy.FullName + + static member Make (typeBuilder: ITypeBuilder) (declTy: Type) md = FieldSymbol (declTy, md, typeBuilder) :> FieldInfo + + /// Represents the type constructor in a provided symbol type. + [] + type TypeSymbolKind = + | SDArray + | Array of int + | Pointer + | ByRef + | TargetGeneric of TargetTypeDefinition + | OtherGeneric of Type + + + /// Represents an array or other symbolic type involving a provided type as the argument. + /// See the type provider spec for the methods that must be implemented. + /// Note that the type provider specification does not require us to implement pointer-equality for provided types. + and TypeSymbol(kind: TypeSymbolKind, typeArgs: Type[], typeBuilder: ITypeBuilder) as this = + inherit TypeDelegator() + do this.typeImpl <- this + + override this.FullName = + if this.IsArray then this.GetElementType().FullName + "[]" + elif this.IsPointer then this.GetElementType().FullName + "*" + elif this.IsByRef then this.GetElementType().FullName + "&" + elif this.IsGenericType then this.GetGenericTypeDefinition().FullName + "[" + (this.GetGenericArguments() |> Array.map (fun arg -> arg.FullName) |> String.concat ",") + "]" + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.DeclaringType = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().DeclaringType + elif this.IsGenericType then this.GetGenericTypeDefinition().DeclaringType + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Name = + if this.IsArray then this.GetElementType().Name + "[]" + elif this.IsPointer then this.GetElementType().Name + "*" + elif this.IsByRef then this.GetElementType().Name + "&" + elif this.IsGenericType then this.GetGenericTypeDefinition().Name + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.BaseType = + if this.IsArray then typeof + elif this.IsPointer then typeof + elif this.IsByRef then typeof + elif this.IsGenericType then instType typeBuilder (this.GetGenericArguments(), [| |]) (this.GetGenericTypeDefinition().BaseType) + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.MetadataToken = + if this.IsArray then typeof.MetadataToken + elif this.IsPointer then typeof.MetadataToken + elif this.IsByRef then typeof.MetadataToken + elif this.IsGenericType then this.GetGenericTypeDefinition().MetadataToken + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Assembly = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().Assembly + elif this.IsGenericType then this.GetGenericTypeDefinition().Assembly + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Namespace = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().Namespace + elif this.IsGenericType then this.GetGenericTypeDefinition().Namespace + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override __.GetArrayRank() = (match kind with TypeSymbolKind.Array n -> n | TypeSymbolKind.SDArray -> 1 | _ -> failwithf "non-array type") + override __.IsValueTypeImpl() = this.IsGenericType && this.GetGenericTypeDefinition().IsValueType + override __.IsArrayImpl() = (match kind with TypeSymbolKind.Array _ | TypeSymbolKind.SDArray -> true | _ -> false) + override __.IsByRefImpl() = (match kind with TypeSymbolKind.ByRef _ -> true | _ -> false) + override __.IsPointerImpl() = (match kind with TypeSymbolKind.Pointer _ -> true | _ -> false) + override __.IsPrimitiveImpl() = false + override __.IsGenericType = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> true | _ -> false) + override __.GetGenericArguments() = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> typeArgs | _ -> [| |]) + override __.GetGenericTypeDefinition() = (match kind with TypeSymbolKind.TargetGeneric e -> (e :> Type) | TypeSymbolKind.OtherGeneric gtd -> gtd | _ -> failwithf "non-generic type") + override __.IsCOMObjectImpl() = false + override __.HasElementTypeImpl() = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> false | _ -> true) + override __.GetElementType() = (match kind, typeArgs with (TypeSymbolKind.Array _ | TypeSymbolKind.SDArray | TypeSymbolKind.ByRef | TypeSymbolKind.Pointer), [| e |] -> e | _ -> failwithf "%A, %A: not an array, pointer or byref type" kind typeArgs) + + override x.Module = x.Assembly.ManifestModule + + override this.GetHashCode() = + if this.IsArray then 10 + hash (this.GetElementType()) + elif this.IsPointer then 163 + hash (this.GetElementType()) + elif this.IsByRef then 283 + hash (this.GetElementType()) + else this.GetGenericTypeDefinition().MetadataToken + + override this.Equals(other: obj) = eqTypeObj this other + + override this.Equals(otherTy: Type) = eqTypes this otherTy + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + member __.Kind = kind + member __.Args = typeArgs + + override this.GetConstructors bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Methods.Entries + |> Array.filter (fun md -> md.Name = ".ctor" || md.Name = ".cctor") + |> Array.map (gtd.MakeConstructorInfo this) + |> Array.filter (canBindConstructor bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetConstructors(bindingFlags) + |> Array.map (ConstructorSymbol.Make typeBuilder this) + | _ -> notRequired this "GetConstructors" this.Name + + override this.GetMethods bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Methods.Entries + |> Array.filter (fun md -> md.Name <> ".ctor" && md.Name <> ".cctor") + |> Array.map (gtd.MakeMethodInfo this) + |> Array.filter (canBindMethod bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetMethods(bindingFlags) + |> Array.map (MethodSymbol.Make typeBuilder this) + | _ -> notRequired this "GetMethods" this.Name + + override this.GetFields bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Fields.Entries + |> Array.map (gtd.MakeFieldInfo this) + |> Array.filter (canBindField bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetFields(bindingFlags) + |> Array.map (FieldSymbol.Make typeBuilder this) + | _ -> notRequired this "GetFields" this.Name + + override this.GetProperties bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Properties.Entries + |> Array.map (gtd.MakePropertyInfo this) + |> Array.filter (canBindProperty bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetProperties(bindingFlags) + |> Array.map (PropertySymbol.Make typeBuilder this) + | _ -> notRequired this "GetProperties" this.Name + + override this.GetEvents bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Events.Entries + |> Array.map (gtd.MakeEventInfo this) + |> Array.filter (canBindEvent bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetEvents(bindingFlags) + |> Array.map (EventSymbol.Make typeBuilder this) + | _ -> notRequired this "GetEvents" this.Name + + override this.GetNestedTypes bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.NestedTypes.Entries + |> Array.map (gtd.MakeNestedTypeInfo this) + |> Array.filter (canBindNestedType bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetNestedTypes(bindingFlags) + | _ -> notRequired this "GetNestedTypes" this.Name + + override this.GetConstructorImpl(bindingFlags, _binderBinder, _callConvention, types, _modifiers) = + let ctors = this.GetConstructors(bindingFlags) |> Array.filter (fun c -> match types with null -> true | t -> let ps = c.GetParameters() in ps.Length = t.Length && (ps, t) ||> Seq.forall2 (fun p ty -> p.ParameterType = ty ) ) + match ctors with + | [| |] -> null + | [| ci |] -> ci + | _ -> failwithf "multiple constructors exist" + + override this.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, types, _modifiers) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + let md = + match types with + | null -> gtd.Metadata.Methods.TryFindUniqueByName(name) + | _ -> + let mds = gtd.Metadata.Methods.FindByNameAndArity(name, types.Length) + match mds |> Array.filter (fun md -> eqTypesAndILTypesWithInst typeArgs types md.ParameterTypes) with + | [| |] -> None + | [| md |] -> Some md + | _ -> failwithf "multiple methods exist with name %s" name + md |> Option.map (gtd.MakeMethodInfo this) |> Option.toObj + | TypeSymbolKind.OtherGeneric _ -> + match this.GetMethods(bindingFlags) |> Array.filter (fun c -> name = c.Name && match types with null -> true | t -> c.GetParameters().Length = t.Length) with + | [| |] -> null + | [| mi |] -> mi + | _ -> failwithf "multiple methods exist with name %s" name + | _ -> notRequired this "GetMethodImpl" this.Name + + override this.GetField(name, bindingFlags) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Fields.Entries |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakeFieldInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetFields(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (FieldSymbol.Make typeBuilder this) + |> Option.toObj + + | _ -> notRequired this "GetField" this.Name + + override this.GetPropertyImpl(name, bindingFlags, _binder, _returnType, _types, _modifiers) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Properties.Entries + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakePropertyInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetProperties(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (PropertySymbol.Make typeBuilder this) + |> Option.toObj + + | _ -> notRequired this "GetPropertyImpl" this.Name + + override this.GetEvent(name, bindingFlags) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Events.Entries + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakeEventInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetEvents(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (EventSymbol.Make typeBuilder this) + |> Option.toObj + | _ -> notRequired this "GetEvent" this.Name + + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.Name + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.GetAttributeFlagsImpl() = getAttributeFlagsImpl this + + override this.UnderlyingSystemType = (this :> Type) + + override __.GetCustomAttributesData() = ([| |] :> IList<_>) + + override this.GetMembers _bindingFlags = notRequired this "GetMembers" this.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.Name + override this.GetInterfaces() = notRequired this "GetInterfaces" this.Name + override __.GetCustomAttributes(_inherit) = emptyAttributes + override __.GetCustomAttributes(attributeType, _inherit) = Attributes.CreateEmpty attributeType + override __.IsDefined(_attributeType, _inherit) = false + + override this.MemberType = + match kind with + | TypeSymbolKind.OtherGeneric gtd -> gtd.MemberType + | _ -> notRequired this "MemberType" this.FullName + +#if NETCOREAPP + // See bug https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues/236 + override __.IsSZArray = + match kind with + | TypeSymbolKind.SDArray _ -> true + | _ -> false +#endif + override this.GetMember(_name, _mt, _bindingFlags) = notRequired this "GetMember" this.Name + override this.GUID = notRequired this "GUID" this.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" this.Name + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |], typeBuilder) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |], typeBuilder) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |], typeBuilder) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |], typeBuilder) :> Type + + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + override this.ToString() = this.FullName + + + /// Convert an ILGenericParameterDef read from a binary to a System.Type. + and TargetGenericParam (asm, gpsf, pos, inp: ILGenericParameterDef, txILType, txCustomAttributesData, typeBuilder: ITypeBuilder) as this = + inherit TypeDelegator() + do this.typeImpl <- this + override __.Name = inp.Name + override __.Assembly = (asm :> Assembly) + override __.FullName = inp.Name + override __.IsGenericParameter = true + override __.GenericParameterPosition = pos + override __.GetGenericParameterConstraints() = inp.Constraints |> Array.map (txILType (gpsf())) + + override __.MemberType = enum 0 + override __.MetadataToken = inp.Token + + override __.Namespace = null //notRequired this "Namespace" + override this.DeclaringType = notRequired this "DeclaringType" this.Name + override __.BaseType = null //notRequired this "BaseType" this.Name + override this.GetInterfaces() = notRequired this "GetInterfaces" this.Name + + override this.GetConstructors(_bindingFlags) = notRequired this "GetConstructors" this.Name + override this.GetMethods(_bindingFlags) = notRequired this "GetMethods" this.Name + override this.GetFields(_bindingFlags) = notRequired this "GetFields" this.Name + override this.GetProperties(_bindingFlags) = notRequired this "GetProperties" this.Name + override this.GetEvents(_bindingFlags) = notRequired this "GetEvents" this.Name + override this.GetNestedTypes(_bindingFlags) = notRequired this "GetNestedTypes" this.Name + + override this.GetConstructorImpl(_bindingFlags, _binder, _callConvention, _types, _modifiers) = notRequired this "GetConstructorImpl" this.Name + override this.GetMethodImpl(_name, _bindingFlags, _binder, _callConvention, _types, _modifiers) = notRequired this "GetMethodImpl" this.Name + override this.GetField(_name, _bindingFlags) = notRequired this "GetField" this.Name + override this.GetPropertyImpl(_name, _bindingFlags, _binder, _returnType, _types, _modifiers) = notRequired this "GetPropertyImpl" this.Name + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.Name + override this.GetEvent(_name, _bindingFlags) = notRequired this "GetEvent" this.Name + override this.GetMembers(_bindingFlags) = notRequired this "GetMembers" this.Name + override this.MakeGenericType(_args) = notRequired this "MakeGenericType" this.Name + + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |], typeBuilder) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |], typeBuilder) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |], typeBuilder) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |], typeBuilder) :> Type + + override __.GetAttributeFlagsImpl() = TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.Sealed + + override __.IsArrayImpl() = false + override __.IsByRefImpl() = false + override __.IsPointerImpl() = false + override __.IsPrimitiveImpl() = false + override __.IsCOMObjectImpl() = false + override __.IsGenericType = false + override __.IsGenericTypeDefinition = false + + override __.HasElementTypeImpl() = false + + override this.UnderlyingSystemType = (this :> Type) + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override this.Equals(that:obj) = System.Object.ReferenceEquals (this, that) + override this.GetHashCode() = hash inp.Name + + override __.ToString() = sprintf "tgt generic param %s" inp.Name + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.GetGenericArguments() = notRequired this "GetGenericArguments" this.Name + override this.GetGenericTypeDefinition() = notRequired this "GetGenericTypeDefinition" this.Name + override this.GetMember(_name, _mt, _bindingFlags) = notRequired this "txILGenericParam: GetMember" this.Name + override this.GUID = notRequired this "txILGenericParam: GUID" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "txILGenericParam: GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "txILGenericParam: GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "txILGenericParam: IsDefined" this.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "txILGenericParam: GetInterface" this.Name + override this.Module = notRequired this "txILGenericParam: Module" this.Name: Module + override this.GetElementType() = notRequired this "txILGenericParam: GetElementType" this.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "txILGenericParam: InvokeMember" this.Name + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + /// Clones namespaces, type providers, types and members provided by tp, renaming namespace nsp1 into namespace nsp2. + + /// Makes a type definition read from a binary available as a System.Type. Not all methods are implemented. + and TargetTypeDefinition(ilGlobals: ILGlobals, tryBindAssembly: ILAssemblyRef -> Choice, asm: TargetAssembly, declTyOpt: Type option, inp: ILTypeDef, typeBuilder: ITypeBuilder) as this = + inherit TypeDelegator() + + // Note: For F# type providers we never need to view the custom attributes + let rec txCustomAttributesArg ((ty:ILType, v:obj)) = + CustomAttributeTypedArgument(txILType ([| |], [| |]) ty, v) + + and txCustomAttributesDatum (inp: ILCustomAttribute) = + let args, namedArgs = decodeILCustomAttribData ilGlobals inp + { new CustomAttributeData () with + member __.Constructor = txILConstructorRef inp.Method.MethodRef + member __.ConstructorArguments = [| for arg in args -> txCustomAttributesArg arg |] :> IList<_> + // Note, named arguments of custom attributes are not required by F# compiler on binding context elements. + member __.NamedArguments = [| |] :> IList<_> + } + + and txCustomAttributesData (inp: ILCustomAttrs) = + [| for a in inp.Entries do + yield txCustomAttributesDatum a |] + :> IList + + /// Makes a parameter definition read from a binary available as a ParameterInfo. Not all methods are implemented. + and txILParameter gps (inp: ILParameter) = + { new ParameterInfo() with + + override __.Name = StructOption.toObj inp.Name + override __.ParameterType = inp.ParameterType |> txILType gps + override __.RawDefaultValue = (match inp.Default with UNone -> null | USome v -> v) + override __.Attributes = inp.Attributes + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override x.ToString() = sprintf "tgt parameter %s" x.Name } + + /// Makes a method definition read from a binary available as a ConstructorInfo. Not all methods are implemented. + and txILConstructorDef (declTy: Type) (inp: ILMethodDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new ConstructorInfo() with + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Constructor + override __.DeclaringType = declTy + + override __.GetParameters() = inp.Parameters |> Array.map (txILParameter (gps, [| |])) + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override __.MetadataToken = inp.Token + + override __.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? ConstructorInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes declTy that.DeclaringType + | _ -> false + + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override __.ToString() = sprintf "tgt constructor(...) in type %s" declTy.FullName } + + /// Makes a method definition read from a binary available as a MethodInfo. Not all methods are implemented. + and txILMethodDef (declTy: Type) (inp: ILMethodDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let rec gps2 = inp.GenericParams |> Array.mapi (fun i gp -> txILGenericParam (fun () -> gps, gps2) (i + gps.Length) gp) + let mutable returnTypeFixCache = None + { new MethodInfo() with + + override __.Name = inp.Name + override __.DeclaringType = declTy + override __.MemberType = MemberTypes.Method + override __.Attributes = inp.Attributes + override __.GetParameters() = inp.Parameters |> Array.map (txILParameter (gps, gps2)) + override __.CallingConvention = if inp.IsStatic then CallingConventions.Standard else CallingConventions.HasThis ||| CallingConventions.Standard + + override __.ReturnType = + match returnTypeFixCache with + | None -> + let returnType = inp.Return.Type |> txILType (gps, gps2) + let returnTypeFix = + match returnType.Namespace, returnType.Name with + | "System", "Void"-> + if ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() then + typeof + else + returnType + | t -> returnType + returnTypeFixCache <- Some returnTypeFix + returnTypeFix + | Some returnTypeFix -> + returnTypeFix + + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override __.GetGenericArguments() = gps2 + override __.IsGenericMethod = (gps2.Length <> 0) + override __.IsGenericMethodDefinition = __.IsGenericMethod + + override __.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.MakeGenericMethod(args) = MethodSymbol2(this, args, typeBuilder) :> MethodInfo + + override __.MetadataToken = inp.Token + + // unused + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override __.ToString() = sprintf "tgt method %s(...) in type %s" inp.Name declTy.FullName } + + /// Makes a property definition read from a binary available as a PropertyInfo. Not all methods are implemented. + and txILPropertyDef (declTy: Type) (inp: ILPropertyDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new PropertyInfo() with + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Property + override __.DeclaringType = declTy + + override __.PropertyType = inp.PropertyType |> txILType (gps, [| |]) + override __.GetGetMethod(_nonPublic) = inp.GetMethod |> Option.map (txILMethodRef declTy) |> Option.toObj + override __.GetSetMethod(_nonPublic) = inp.SetMethod |> Option.map (txILMethodRef declTy) |> Option.toObj + override __.GetIndexParameters() = inp.IndexParameters |> Array.map (txILParameter (gps, [| |])) + override __.CanRead = inp.GetMethod.IsSome + override __.CanWrite = inp.SetMethod.IsSome + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override __.MetadataToken = inp.Token + + override __.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? PropertyInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture) = notRequired this "GetValue" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" this.Name + override this.GetAccessors(nonPublic) = notRequired this "GetAccessors" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override __.ToString() = sprintf "tgt property %s(...) in type %s" inp.Name declTy.Name } + + /// Make an event definition read from a binary available as an EventInfo. Not all methods are implemented. + and txILEventDef (declTy: Type) (inp: ILEventDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new EventInfo() with + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Event + override __.DeclaringType = declTy + + override __.EventHandlerType = inp.EventHandlerType |> txILType (gps, [| |]) + override __.GetAddMethod(_nonPublic) = inp.AddMethod |> txILMethodRef declTy + override __.GetRemoveMethod(_nonPublic) = inp.RemoveMethod |> txILMethodRef declTy + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override __.MetadataToken = inp.Token + + override __.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? EventInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetRaiseMethod(_nonPublic) = notRequired this "GetRaiseMethod" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override __.ToString() = sprintf "tgt event %s(...) in type %s" inp.Name declTy.FullName } + + /// Makes a field definition read from a binary available as a FieldInfo. Not all methods are implemented. + and txILFieldDef (declTy: Type) (inp: ILFieldDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new FieldInfo() with + + override __.Name = inp.Name + override __.Attributes = inp.Attributes + override __.MemberType = MemberTypes.Field + override __.DeclaringType = declTy + + override __.FieldType = inp.FieldType |> txILType (gps, [| |]) + override __.GetRawConstantValue() = match inp.LiteralValue with None -> null | Some v -> v + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override __.MetadataToken = inp.Token + + override __.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? FieldInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" this.Name + override this.GetValue(_obj) = notRequired this "GetValue" this.Name + override this.FieldHandle = notRequired this "FieldHandle" this.Name + + override __.ToString() = sprintf "tgt literal field %s(...) in type %s" inp.Name declTy.FullName } + + /// Bind a reference to an assembly + and txScopeRef(sref: ILScopeRef) = + match sref with + | ILScopeRef.Assembly aref -> match tryBindAssembly aref with Choice1Of2 asm -> asm | Choice2Of2 exn -> raise exn + | ILScopeRef.Local -> (asm :> Assembly) + | ILScopeRef.Module _ -> (asm :> Assembly) + + /// Bind a reference to a type + and txILTypeRef(tref: ILTypeRef): Type = + match tref.Scope with + | ILTypeRefScope.Top scoref -> txScopeRef(scoref).GetType(joinILTypeName tref.Namespace tref.Name) + | ILTypeRefScope.Nested encl -> txILTypeRef(encl).GetNestedType(tref.Name, bindAll) + + /// Bind a reference to a constructor + and txILConstructorRef (mref: ILMethodRef) = + let declTy = txILTypeRef(mref.EnclosingTypeRef) + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let argTypes = Array.map (txILType (gps, [| |])) mref.ArgTypes + let cons = declTy.GetConstructor(bindAll, null, argTypes, null) + if isNull cons then failwithf "constructor reference '%A' not resolved" mref + cons + + /// Bind a reference to a method + and txILMethodRef (declTy: Type) (mref: ILMethodRef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let argTypes = mref.ArgTypes |> Array.map (txILType (gps, [| |])) + let meth = declTy.GetMethod(mref.Name, bindAll, null, argTypes, null) + if isNull meth then failwithf "method reference '%A' not resolved" mref + meth + + /// Convert an ILType read from a binary to a System.Type backed by TargetTypeDefinitions + and txILType gps (ty: ILType) = + + match ty with + | ILType.Void -> txILType gps ilGlobals.typ_Void + | ILType.Value tspec + | ILType.Boxed tspec -> + let tdefR = txILTypeRef tspec.TypeRef + match tspec.GenericArgs with + | [| |] -> tdefR + | args -> tdefR.MakeGenericType(Array.map (txILType gps) args) + | ILType.Array(rank, arg) -> + let argR = txILType gps arg + if rank.Rank = 1 then argR.MakeArrayType() + else argR.MakeArrayType(rank.Rank) + | ILType.FunctionPointer _ -> failwith "unexpected function type" + | ILType.Ptr(arg) -> (txILType gps arg).MakePointerType() + | ILType.Byref(arg) -> (txILType gps arg).MakeByRefType() + | ILType.Modified(_, _mod, arg) -> txILType gps arg + | ILType.Var(n) -> + let (gps1:Type[]), (gps2:Type[]) = gps + if n < gps1.Length then gps1.[n] + elif n < gps1.Length + gps2.Length then gps2.[n - gps1.Length] + else failwithf "generic parameter index out of range: %d" n + + /// Convert an ILGenericParameterDef read from a binary to a System.Type. + and txILGenericParam gpsf pos (inp: ILGenericParameterDef) = + TargetGenericParam (asm, gpsf, pos, inp, txILType, txCustomAttributesData, typeBuilder) :> Type + + let rec gps = inp.GenericParams |> Array.mapi (fun i gp -> txILGenericParam (fun () -> gps, [| |]) i gp) + + let isNested = declTyOpt.IsSome + + do this.typeImpl <- this + override __.Name = inp.Name + override __.Assembly = (asm :> Assembly) + override __.DeclaringType = declTyOpt |> Option.toObj + override __.MemberType = if isNested then MemberTypes.NestedType else MemberTypes.TypeInfo + override __.MetadataToken = inp.Token + + override __.FullName = + match declTyOpt with + | None -> + match inp.Namespace with + | UNone -> inp.Name + | USome nsp -> nsp + "." + inp.Name + | Some declTy -> + declTy.FullName + "+" + inp.Name + + override __.Namespace = inp.Namespace |> StructOption.toObj + override __.BaseType = inp.Extends |> Option.map (txILType (gps, [| |])) |> Option.toObj + override __.GetInterfaces() = inp.Implements |> Array.map (txILType (gps, [| |])) + + override this.GetConstructors(bindingFlags) = + inp.Methods.Entries + |> Array.filter (fun x -> x.Name = ".ctor" || x.Name = ".cctor") + |> Array.map (txILConstructorDef this) + |> Array.filter (canBindConstructor bindingFlags) + + override this.GetMethods(bindingFlags) = + inp.Methods.Entries + |> Array.filter (fun x -> x.Name <> ".ctor" && x.Name <> ".cctor") + |> Array.map (txILMethodDef this) + |> Array.filter (canBindMethod bindingFlags) + + override this.GetFields(bindingFlags) = + inp.Fields.Entries + |> Array.map (txILFieldDef this) + |> Array.filter (canBindField bindingFlags) + + override this.GetEvents(bindingFlags) = + inp.Events.Entries + |> Array.map (txILEventDef this) + |> Array.filter (canBindEvent bindingFlags) + + override this.GetProperties(bindingFlags) = + inp.Properties.Entries + |> Array.map (txILPropertyDef this) + |> Array.filter (canBindProperty bindingFlags) + + override this.GetNestedTypes(bindingFlags) = + inp.NestedTypes.Entries + |> Array.map (asm.TxILTypeDef (Some (this :> Type))) + |> Array.filter (canBindNestedType bindingFlags) + + override this.GetConstructorImpl(_bindingFlags, _binder, _callConvention, types, _modifiers) = + let md = + match types with + | null -> inp.Methods.TryFindUniqueByName(".ctor") + | _ -> + inp.Methods.FindByNameAndArity(".ctor", types.Length) + |> Array.tryFind (fun md -> eqTypesAndILTypes types md.ParameterTypes) + md + |> Option.map (txILConstructorDef this) + |> Option.toObj + + override this.GetMethodImpl(name, _bindingFlags, _binder, _callConvention, types, _modifiers) = + let md = + match types with + | null -> inp.Methods.TryFindUniqueByName(name) + | _ -> + inp.Methods.FindByNameAndArity(name, types.Length) + |> Array.tryFind (fun md -> eqTypesAndILTypes types md.ParameterTypes) + md |> Option.map (txILMethodDef this) |> Option.toObj + + override this.GetField(name, _bindingFlags) = + inp.Fields.Entries + |> Array.tryPick (fun p -> if p.Name = name then Some (txILFieldDef this p) else None) + |> Option.toObj + + override this.GetPropertyImpl(name, _bindingFlags, _binder, _returnType, _types, _modifiers) = + inp.Properties.Entries + |> Array.tryPick (fun p -> if p.Name = name then Some (txILPropertyDef this p) else None) + |> Option.toObj + + override this.GetEvent(name, _bindingFlags) = + inp.Events.Entries + |> Array.tryPick (fun ev -> if ev.Name = name then Some (txILEventDef this ev) else None) + |> Option.toObj + + override this.GetNestedType(name, _bindingFlags) = + inp.NestedTypes.TryFindByName(UNone, name) |> Option.map (asm.TxILTypeDef (Some (this :> Type))) |> Option.toObj + + + override this.GetMembers(bindingFlags) = + [| for x in this.GetConstructors(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetMethods(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetFields(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetProperties(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetEvents(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetNestedTypes(bindingFlags) do yield (x :> MemberInfo) |] + + override this.MakeGenericType(args) = TypeSymbol(TypeSymbolKind.TargetGeneric this, args, typeBuilder) :> Type + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |], typeBuilder) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |], typeBuilder) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |], typeBuilder) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |], typeBuilder) :> Type + + override __.GetAttributeFlagsImpl() = + let attr = TypeAttributes.Public ||| TypeAttributes.Class + let attr = if inp.IsSealed then attr ||| TypeAttributes.Sealed else attr + let attr = if inp.IsInterface then attr ||| TypeAttributes.Interface else attr + let attr = if inp.IsSerializable then attr ||| TypeAttributes.Serializable else attr + if isNested then adjustTypeAttributes isNested attr else attr + + override __.IsValueTypeImpl() = inp.IsStructOrEnum + + override __.IsEnum = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.IsEnum + + override __.GetEnumUnderlyingType() = + if this.IsEnum then + txILType ([| |], [| |]) ilGlobals.typ_Int32 // TODO: in theory the assumption of "Int32" is not accurate for all enums, howver in practice .NET only uses enums with backing field Int32 + else failwithf "not enum type" + + override __.IsArrayImpl() = false + override __.IsByRefImpl() = false + override __.IsPointerImpl() = false + override __.IsPrimitiveImpl() = false + override __.IsCOMObjectImpl() = false + override __.IsGenericType = (gps.Length <> 0) + override __.IsGenericTypeDefinition = (gps.Length <> 0) + override __.HasElementTypeImpl() = false + + override this.UnderlyingSystemType = (this :> Type) + override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override this.Equals(that:obj) = System.Object.ReferenceEquals (this, that) + override this.Equals(that:Type) = System.Object.ReferenceEquals (this, that) + override __.GetHashCode() = inp.Token + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.ToString() = sprintf "tgt type %s" this.FullName + + override __.GetGenericArguments() = gps + override this.GetGenericTypeDefinition() = (this :> Type) + + override x.Module = x.Assembly.ManifestModule + + override this.GetMember(_name, _memberType, _bindingFlags) = notRequired this "GetMember" inp.Name + override this.GUID = notRequired this "GUID" inp.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" inp.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" inp.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" inp.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" inp.Name + override this.GetElementType() = notRequired this "GetElementType" inp.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" inp.Name + + member __.Metadata: ILTypeDef = inp + member __.MakeMethodInfo (declTy: Type) md = txILMethodDef declTy md + member __.MakeConstructorInfo (declTy: Type) md = txILConstructorDef declTy md + member __.MakePropertyInfo (declTy: Type) md = txILPropertyDef declTy md + member __.MakeEventInfo (declTy: Type) md = txILEventDef declTy md + member __.MakeFieldInfo (declTy: Type) md = txILFieldDef declTy md + member __.MakeNestedTypeInfo (declTy: Type) md = asm.TxILTypeDef (Some declTy) md + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating +#if NETCOREAPP + // See bug https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues/236 + override __.IsSZArray = false +#endif + + and TargetModule(location: string) = + inherit Module() + override __.MetadataToken = hash location + + /// Implements System.Reflection.Assembly backed by .NET metadata provided by an ILModuleReader + and TargetAssembly(ilGlobals, tryBindAssembly: ILAssemblyRef -> Choice, reader: ILModuleReader option, location: string, typeBuilder: ITypeBuilder) as asm = + inherit Assembly() + + // A table tracking how type definition objects are translated. + let txTable = TxTable() + let mutable reader = reader + let manifestModule = TargetModule(location) + let getReader() = match reader with None -> failwith "the reader on the TargetAssembly has not been set" | Some r -> r + + let txILTypeDef (declTyOpt: Type option) (inp: ILTypeDef) = + txTable.Get inp.Token (fun () -> + // We never create target types for the types of primitive values that are accepted by the F# compiler as Expr.Value nodes, + // which fortunately also correspond to element types. We just use the design-time types instead. + // See convertConstExpr in the compiler, e.g. + // https://github.com/Microsoft/visualfsharp/blob/44fa027b308681a1b78a089e44fa1ab35ff77b41/src/fsharp/MethodCalls.fs#L842 + // for the accepted types. + match inp.Namespace, inp.Name with + //| USome "System", "Void"-> typeof + (* + | USome "System", "Boolean" -> typeof + | USome "System", "String"-> typeof + | USome "System", "Object"-> typeof + | USome "System", "Int32" -> typeof + | USome "System", "SByte" -> typeof + | USome "System", "Int16"-> typeof + | USome "System", "Int64" -> typeof + | USome "System", "IntPtr" -> typeof + | USome "System", "Byte" -> typeof + | USome "System", "UInt16"-> typeof + | USome "System", "UInt32" -> typeof + | USome "System", "UInt64" -> typeof + | USome "System", "UIntPtr" -> typeof + | USome "System", "Double" -> typeof + | USome "System", "Single" -> typeof + | USome "System", "Char" -> typeof + *) + | _ -> + TargetTypeDefinition(ilGlobals, tryBindAssembly, asm, declTyOpt, inp, typeBuilder) :> System.Type) + + let types = lazy [| for td in getReader().ILModuleDef.TypeDefs.Entries -> txILTypeDef None td |] + + + override __.GetReferencedAssemblies() = [| for aref in getReader().ILAssemblyRefs -> aref.ToAssemblyName() |] + + override __.GetTypes () = types.Force() + + override x.GetType (nm:string) = + if nm.Contains("+") then + let i = nm.LastIndexOf("+") + let enc, nm2 = nm.[0..i-1], nm.[i+1..] + match x.GetType(enc) with + | null -> null + | t -> t.GetNestedType(nm2, bindAll) + elif nm.Contains(".") then + let i = nm.LastIndexOf(".") + let nsp, nm2 = nm.[0..i-1], nm.[i+1..] + x.TryBindType(USome nsp, nm2) |> Option.toObj + else + x.TryBindType(UNone, nm) |> Option.toObj + + override __.GetName() = getReader().ILModuleDef.ManifestOfAssembly.GetName() + + override x.FullName = x.GetName().ToString() + + override __.Location = location + override __.ManifestModule = (manifestModule :> Module) + + override __.ReflectionOnly = true + + override x.GetManifestResourceStream(resourceName:string) = + let r = getReader().ILModuleDef.Resources.Entries |> Seq.find (fun r -> r.Name = resourceName) + match r.Location with + | ILResourceLocation.Local f -> new MemoryStream(f()) :> Stream + | _ -> + notRequired x "reading manifest resource %s" resourceName + + member __.TxILTypeDef declTyOpt inp = txILTypeDef declTyOpt inp + + member __.Reader with get() = reader and set v = (if reader.IsSome then failwith "reader on TargetAssembly already set"); reader <- v + + member __.TryBindType(nsp:string uoption, nm:string): Type option = + match getReader().ILModuleDef.TypeDefs.TryFindByName(nsp, nm) with + | Some td -> asm.TxILTypeDef None td |> Some + | None -> + match getReader().ILModuleDef.ManifestOfAssembly.ExportedTypes.TryFindByName(nsp, nm) with + | Some tref -> + match tref.ScopeRef with + | ILScopeRef.Assembly aref2 -> + let ass2opt = tryBindAssembly(aref2) + match ass2opt with + | Choice1Of2 ass2 -> + match ass2.GetType(joinILTypeName nsp nm) with + | null -> None + | ty -> Some ty + | Choice2Of2 _err -> None + | _ -> + printfn "unexpected non-forwarder during binding" + None + | None -> None + + member x.BindType(nsp:string uoption, nm:string) = + match x.TryBindType(nsp, nm) with + | None -> failwithf "failed to bind type %s in assembly %s" nm asm.FullName + | Some res -> res + + override x.ToString() = "tgt assembly " + x.FullName + + type ProvidedAssembly(isTgt: bool, assemblyName:AssemblyName, assemblyFileName: string, customAttributesData) = + + inherit Assembly() + + let customAttributesImpl = CustomAttributesImpl(isTgt, customAttributesData) + + let theTypes = ResizeArray() + + let addTypes (ptds:ProvidedTypeDefinition[], enclosingTypeNames: string list option) = + for pt in ptds do + if pt.IsErased then failwith ("The provided type "+pt.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased=false' on the ProvidedTypeDefinition") + if not isTgt && pt.BelongsToTargetModel then failwithf "Expected '%O' to be a source ProvidedTypeDefinition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pt + if isTgt && not pt.BelongsToTargetModel then failwithf "Expected '%O' to be a target ProvidedTypeDefinition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pt + theTypes.Add (ptds, enclosingTypeNames) + + let theTypesArray = lazy (theTypes.ToArray() |> Array.collect (function (ptds, None) -> Array.map (fun ptd -> (ptd :> Type)) ptds | _ -> [| |])) + + member __.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) + + override __.GetReferencedAssemblies() = [| |] //notRequired x "GetReferencedAssemblies" (assemblyName.ToString()) + + override __.GetName() = assemblyName + + override __.FullName = assemblyName.ToString() + + override __.Location = assemblyFileName + + override __.ReflectionOnly = true + + override __.GetTypes () = theTypesArray.Force() + + override __.ToString () = assemblyName.ToString() + + override x.GetType (nm: string) = + if nm.Contains("+") then + let i = nm.LastIndexOf("+") + let enc, nm2 = nm.[0..i-1], nm.[i+1..] + match x.GetType(enc) with + | null -> null + | t -> t.GetNestedType(nm2, bindAll) + else + theTypesArray.Force() + |> Array.tryPick (fun ty -> if ty.FullName = nm then Some ty else None) + |> Option.toObj + + new () = + let tmpFile = Path.GetTempFileName() + let assemblyFileName = Path.ChangeExtension(tmpFile, "dll") + File.Delete(tmpFile) + let simpleName = Path.GetFileNameWithoutExtension(assemblyFileName) + ProvidedAssembly(AssemblyName(simpleName), assemblyFileName) + + new (assemblyName, assemblyFileName) = + ProvidedAssembly(false, assemblyName, assemblyFileName, K [||]) + + member __.BelongsToTargetModel = isTgt + + member __.AddNestedTypes (types, enclosingGeneratedTypeNames) = + addTypes (Array.ofList types, Some enclosingGeneratedTypeNames) + + member __.AddTypes (types) = + addTypes (Array.ofList types, None) + + member __.AddTheTypes (types, enclosingGeneratedTypeNames) = + addTypes (types, enclosingGeneratedTypeNames) + + member __.GetTheTypes () = theTypes.ToArray() + + override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + +//==================================================================================================== +// ProvidedTypesContext +// +// A binding context for cross-targeting type providers + +namespace ProviderImplementation.ProvidedTypes + + + #nowarn "8796" + #nowarn "1182" + + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + + [] + module private ImplementationUtils = + type System.Object with + member x.GetProperty(nm) = + let ty = x.GetType() + let prop = ty.GetProperty(nm, bindAll) + let v = prop.GetValue(x, null) + v + + member x.GetField(nm) = + let ty = x.GetType() + let fld = ty.GetField(nm, bindAll) + let v = fld.GetValue(x) + v + + member x.HasProperty(nm) = + let ty = x.GetType() + let p = ty.GetProperty(nm, bindAll) + p |> isNull |> not + + member x.HasField(nm) = + let ty = x.GetType() + let fld = ty.GetField(nm, bindAll) + fld |> isNull |> not + + member x.GetElements() = [ for v in (x :?> System.Collections.IEnumerable) do yield v ] + + + + type ProvidedTypeBuilder() = + static let tupleNames = + [| "System.Tuple`1"; "System.Tuple`2"; "System.Tuple`3"; + "System.Tuple`4"; "System.Tuple`5"; "System.Tuple`6"; + "System.Tuple`7"; "System.Tuple`8"; "System.Tuple" + "System.ValueTuple`1"; "System.ValueTuple`2"; "System.ValueTuple`3"; + "System.ValueTuple`4"; "System.ValueTuple`5"; "System.ValueTuple`6"; + "System.ValueTuple`7"; "System.ValueTuple`8"; "System.ValueTuple" |] + + + static member MakeGenericType(genericTypeDefinition: Type, genericArguments: Type list) = + if genericArguments.Length = 0 then genericTypeDefinition else + match genericTypeDefinition with + | :? TargetTypeDefinition -> failwithf "unexpected target model in ProvidedTypeBuilder.MakeGenericType, stacktrace = %s " Environment.StackTrace + | :? ProvidedTypeDefinition as ptd when ptd.BelongsToTargetModel -> failwithf "unexpected target model ptd in MakeGenericType, stacktrace = %s " Environment.StackTrace + | :? ProvidedTypeDefinition -> ProvidedTypeSymbol(ProvidedTypeSymbolKind.Generic genericTypeDefinition, genericArguments, ProvidedTypeBuilder.typeBuilder) :> Type + | _ -> TypeSymbol(TypeSymbolKind.OtherGeneric genericTypeDefinition, List.toArray genericArguments, ProvidedTypeBuilder.typeBuilder) :> Type + + static member MakeGenericMethod(genericMethodDefinition, genericArguments: Type list) = + if genericArguments.Length = 0 then genericMethodDefinition else + MethodSymbol2(genericMethodDefinition, Array.ofList genericArguments, ProvidedTypeBuilder.typeBuilder) :> MethodInfo + + static member MakeTupleType(types, isStruct) = + let rec mkTupleType isStruct (asm:Assembly) (tys:Type list) = + let maxTuple = 8 + + let n = min tys.Length maxTuple + let tupleFullName = tupleNames.[n - 1 + (if isStruct then 9 else 0)] + let ty = asm.GetType(tupleFullName) + if tys.Length >= maxTuple then + let tysA = (Array.ofList tys).[0..maxTuple-2] |> List.ofArray + let tysB = (Array.ofList tys).[maxTuple-1..] |> List.ofArray + let tyB = mkTupleType isStruct asm tysB + ProvidedTypeBuilder.MakeGenericType(ty, List.append tysA [ tyB ]) + else + ProvidedTypeBuilder.MakeGenericType(ty, tys) + mkTupleType isStruct (typeof.Assembly) types + + static member MakeTupleType(types) = ProvidedTypeBuilder.MakeTupleType(types, false) + + static member typeBuilder = + { new ITypeBuilder with + member this.MakeGenericType(typeDef: Type, args)= + match typeDef with + | :? ProvidedTypeDefinition -> ProvidedTypeSymbol(ProvidedTypeSymbolKind.Generic typeDef, Array.toList args, this) :> Type + | _ -> + if args |> Array.exists (function :? ProvidedTypeDefinition -> true | _ -> false) then + TypeSymbol(TypeSymbolKind.OtherGeneric typeDef, args, this) :> Type + else + typeDef.MakeGenericType(args) + member this.MakeArrayType(typ) = + match typ with + | :? ProvidedTypeDefinition -> + TypeSymbol(TypeSymbolKind.SDArray, [| typ |], this) :> Type + | _ -> typ.MakeArrayType() + member this.MakeRankedArrayType(typ,rank) = + match typ with + | :? ProvidedTypeDefinition -> + TypeSymbol(TypeSymbolKind.Array rank, [| typ |], this) :> Type + | _ -> typ.MakeArrayType(rank) + member this.MakePointerType(typ) = + match typ with + | :? ProvidedTypeDefinition -> + TypeSymbol(TypeSymbolKind.Pointer, [| typ |], this) :> Type + | _ -> typ.MakePointerType() + member this.MakeByRefType(typ) = + match typ with + | :? ProvidedTypeDefinition -> + TypeSymbol(TypeSymbolKind.ByRef, [| typ |], this) :> Type + | _ -> typ.MakeByRefType() } + + //-------------------------------------------------------------------------------- + // The quotation simplifier + // + // This is invoked for each quotation specified by the type provider, as part of the translation to + /// the target model, i.e. before it is handed to the F# compiler (for erasing type providers) or + // the TPSDK IL code generator (for generative type providers). This allows a broader range of quotations + // to be used when authoring type providers than are strictly allowed by those tools. + // + // Specifically we accept: + // + // - NewTuple nodes (for generative type providers) + // - TupleGet nodes (for generative type providers) + // - array and list values as constants + // - PropertyGet and PropertySet nodes + // - Application, NewUnionCase, NewRecord, UnionCaseTest nodes + // - Let nodes (defining "byref" values) + // - LetRecursive nodes + // + // Additionally, a set of code optimizations are applied for generative type providers: + // - inlineRightPipe + // - optimizeCurriedApplications + // - inlineValueBindings + + // Note, the QuotationSimplifier works over source quotations, not target quotations + type QuotationSimplifier(isGenerated: bool) = + + let rec simplifyExpr q = + match q with + +#if !NO_GENERATIVE + // Convert NewTuple to the call to the constructor of the Tuple type (only for generated types, + // the F# compile does the job for erased types when it receives the quotation) + | NewTuple(items) when isGenerated -> + let rec mkCtor args ty = + let ctor, restTyOpt = Reflection.FSharpValue.PreComputeTupleConstructorInfo ty + match restTyOpt with + | None -> Expr.NewObjectUnchecked(ctor, List.map simplifyExpr args) + | Some restTy -> + let curr = [for a in Seq.take 7 args -> simplifyExpr a] + let rest = List.ofSeq (Seq.skip 7 args) + Expr.NewObjectUnchecked(ctor, curr @ [mkCtor rest restTy]) + let tys = [ for e in items -> e.Type ] + let tupleTy = ProvidedTypeBuilder.MakeTupleType(tys, q.Type.IsValueType) + simplifyExpr (mkCtor items tupleTy) + + // convert TupleGet to the chain of PropertyGet calls (only for generated types) + | TupleGet(e, i) when isGenerated -> + let rec mkGet (ty : Type) i (e: Expr) = + if ty.IsValueType then + let get index = + let fields = ty.GetFields() |> Array.sortBy (fun fi -> fi.Name) + if index >= fields.Length then + invalidArg "index" (sprintf "The tuple index '%d' was out of range for tuple type %s" index ty.Name) + fields.[index] + let tupleEncField = 7 + let fget = Expr.FieldGetUnchecked(e, get i) + if i < tupleEncField then + fget + else + let etys = ty.GetGenericArguments() + mkGet etys.[tupleEncField] (i - tupleEncField) fget + else + let pi, restOpt = Reflection.FSharpValue.PreComputeTuplePropertyInfo(ty, i) + let propGet = Expr.PropertyGetUnchecked(e, pi) + match restOpt with + | None -> propGet + | Some (restTy, restI) -> mkGet restTy restI propGet + simplifyExpr (mkGet e.Type i (simplifyExpr e)) +#endif + + | Value(value, ty) -> + if value |> isNull |> not then + let tyOfValue = value.GetType() + transValue(value, tyOfValue, ty) + else q + + // Eliminate F# property gets to method calls + | PropertyGet(obj, propInfo, args) -> + match obj with + | None -> simplifyExpr (Expr.CallUnchecked(propInfo.GetGetMethod(true), args)) + | Some o -> simplifyExpr (Expr.CallUnchecked(simplifyExpr o, propInfo.GetGetMethod(true), args)) + + // Eliminate F# property sets to method calls + | PropertySet(obj, propInfo, args, v) -> + match obj with + | None -> simplifyExpr (Expr.CallUnchecked(propInfo.GetSetMethod(true), args@[v])) + | Some o -> simplifyExpr (Expr.CallUnchecked(simplifyExpr o, propInfo.GetSetMethod(true), args@[v])) + + // Eliminate F# function applications to FSharpFunc<_, _>.Invoke calls + | Application(f, e) -> + simplifyExpr (Expr.CallUnchecked(simplifyExpr f, f.Type.GetMethod "Invoke", [ e ]) ) + + // Eliminate F# union operations + | NewUnionCase(ci, es) -> + simplifyExpr (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) + + // Eliminate F# union operations + | UnionCaseTest(e, uc) -> + let tagInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType + let tagExpr = + match tagInfo with + | :? PropertyInfo as tagProp -> + simplifyExpr (Expr.PropertyGet(e, tagProp) ) + | :? MethodInfo as tagMeth -> + if tagMeth.IsStatic then simplifyExpr (Expr.Call(tagMeth, [e])) + else simplifyExpr (Expr.Call(e, tagMeth, [])) + | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" + let tagNumber = uc.Tag + simplifyExpr <@@ (%%(tagExpr): int) = tagNumber @@> + + // Eliminate F# record operations + | NewRecord(ci, es) -> + simplifyExpr (Expr.NewObjectUnchecked(Reflection.FSharpValue.PreComputeRecordConstructorInfo ci, es) ) + + // Explicitly handle weird byref variables in lets (used to populate out parameters), since the generic handlers can't deal with byrefs. + // + // The binding must have leaves that are themselves variables (due to the limited support for byrefs in expressions) + // therefore, we can perform inlining to translate this to a form that can be compiled + | Let(v, vexpr, bexpr) when v.Type.IsByRef -> transLetOfByref v vexpr bexpr + + // Eliminate recursive let bindings (which are unsupported by the type provider API) to regular let bindings + | LetRecursive(bindings, expr) -> simplifyLetRec bindings expr + + // Handle the generic cases + | ShapeLambdaUnchecked(v, body) -> Expr.Lambda(v, simplifyExpr body) + | ShapeCombinationUnchecked(comb, args) -> RebuildShapeCombinationUnchecked(comb, List.map simplifyExpr args) + | ShapeVarUnchecked _ -> q + + and simplifyLetRec bindings expr = + // This uses a "lets and sets" approach, converting something like + // let rec even = function + // | 0 -> true + // | n -> odd (n-1) + // and odd = function + // | 0 -> false + // | n -> even (n-1) + // X + // to something like + // let even = ref Unchecked.defaultof<_> + // let odd = ref Unchecked.defaultof<_> + // even := function + // | 0 -> true + // | n -> !odd (n-1) + // odd := function + // | 0 -> false + // | n -> !even (n-1) + // X' + // where X' is X but with occurrences of even/odd substituted by !even and !odd (since now even and odd are references) + // Translation relies on typedefof<_ ref> - does this affect ability to target different runtime and design time environments? + let vars = List.map fst bindings + let refVars = vars |> List.map (fun v -> Var(v.Name, ProvidedTypeBuilder.MakeGenericType(typedefof<_ ref>, [v.Type]))) + + // "init t" generates the equivalent of <@ ref Unchecked.defaultof @> + let init (t:Type) = + let r = match <@ ref 1 @> with Call(None, r, [_]) -> r | _ -> failwith "Extracting MethodInfo from <@ 1 @> failed" + let d = match <@ Unchecked.defaultof<_> @> with Call(None, d, []) -> d | _ -> failwith "Extracting MethodInfo from <@ Unchecked.defaultof<_> @> failed" + let ir = ProvidedTypeBuilder.MakeGenericMethod(r.GetGenericMethodDefinition(), [ t ]) + let id = ProvidedTypeBuilder.MakeGenericMethod(d.GetGenericMethodDefinition(), [ t ]) + Expr.CallUnchecked(ir, [Expr.CallUnchecked(id, [])]) + + // deref v generates the equivalent of <@ !v @> + // (so v's type must be ref) + let deref (v:Var) = + let m = match <@ !(ref 1) @> with Call(None, m, [_]) -> m | _ -> failwith "Extracting MethodInfo from <@ !(ref 1) @> failed" + let tyArgs = v.Type.GetGenericArguments() + let im = ProvidedTypeBuilder.MakeGenericMethod(m.GetGenericMethodDefinition(), Array.toList tyArgs) + Expr.CallUnchecked(im, [Expr.Var v]) + + // substitution mapping a variable v to the expression <@ !v' @> using the corresponding new variable v' of ref type + let subst = + let map = [ for v in refVars -> v.Name, deref v ] |> Map.ofList + fun (v:Var) -> Map.tryFind v.Name map + + let refExpr = expr.Substitute(subst) + + // maps variables to new variables + let varDict = [ for (v, rv) in List.zip vars refVars -> v.Name, rv ] |> dict + + // given an old variable v and an expression e, returns a quotation like <@ v' := e @> using the corresponding new variable v' of ref type + let setRef (v:Var) e = + let m = match <@ (ref 1) := 2 @> with Call(None, m, [_;_]) -> m | _ -> failwith "Extracting MethodInfo from <@ (ref 1) := 2 @> failed" + let im = ProvidedTypeBuilder.MakeGenericMethod(m.GetGenericMethodDefinition(), [ v.Type ]) + Expr.CallUnchecked(im, [Expr.Var varDict.[v.Name]; e]) + + // Something like + // <@ + // v1 := e1' + // v2 := e2' + // ... + // refExpr + // @> + // Note that we must substitute our new variable dereferences into the bound expressions + let body = + bindings + |> List.fold (fun b (v, e) -> Expr.Sequential(setRef v (e.Substitute subst), b)) refExpr + + // Something like + // let v1 = ref Unchecked.defaultof + // let v2 = ref Unchecked.defaultof + // ... + // body + (body, vars) + ||> List.fold (fun b v -> Expr.LetUnchecked(varDict.[v.Name], init v.Type, b)) + |> simplifyExpr + + + and transLetOfByref v vexpr bexpr = + match vexpr with + | Sequential(e', vexpr') -> + (* let v = (e'; vexpr') in bexpr => e'; let v = vexpr' in bexpr *) + Expr.Sequential(e', transLetOfByref v vexpr' bexpr) + |> simplifyExpr + | IfThenElse(c, b1, b2) -> + (* let v = if c then b1 else b2 in bexpr => if c then let v = b1 in bexpr else let v = b2 in bexpr *) + // + // Note, this duplicates "bexpr" + Expr.IfThenElseUnchecked(c, transLetOfByref v b1 bexpr, transLetOfByref v b2 bexpr) + |> simplifyExpr + | Var _ -> + (* let v = v1 in bexpr => bexpr[v/v1] *) + bexpr.Substitute(fun v' -> if v = v' then Some vexpr else None) + |> simplifyExpr + | _ -> + failwithf "Unexpected byref binding: %A = %A. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" v vexpr + + and transValueArray (o: Array, ty: Type) = + let elemTy = ty.GetElementType() + let converter = getValueConverterForType elemTy + let elements = [ for el in o -> converter el ] + Expr.NewArrayUnchecked(elemTy, elements) + + and transValueList(o, ty: Type, nil, cons) = + let converter = getValueConverterForType (ty.GetGenericArguments().[0]) + o + |> Seq.cast + |> List.ofSeq + |> fun l -> List.foldBack(fun o s -> Expr.NewUnionCase(cons, [ converter(o); s ])) l (Expr.NewUnionCase(nil, [])) + |> simplifyExpr + + and getValueConverterForType (ty: Type) = + if ty.IsArray then + fun (v: obj) -> transValueArray(v :?> Array, ty) + elif ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ list> then + let nil, cons = + let cases = Reflection.FSharpType.GetUnionCases(ty) + let a = cases.[0] + let b = cases.[1] + if a.Name = "Empty" then a, b + else b, a + + fun v -> transValueList (v :?> System.Collections.IEnumerable, ty, nil, cons) + else + fun v -> Expr.Value(v, ty) + + and transValue (v: obj, tyOfValue: Type, expectedTy: Type) = + let converter = getValueConverterForType tyOfValue + let r = converter v + if tyOfValue <> expectedTy then Expr.Coerce(r, expectedTy) + else r + +#if !NO_GENERATIVE + let getFastFuncType (args: list) resultType = + let types = + [| for arg in args -> arg.Type + yield resultType |] + let fastFuncTy = + match List.length args with + | 2 -> typedefof>.MakeGenericType(types) + | 3 -> typedefof>.MakeGenericType(types) + | 4 -> typedefof>.MakeGenericType(types) + | 5 -> typedefof>.MakeGenericType(types) + | _ -> invalidArg "args" "incorrect number of arguments" + fastFuncTy.GetMethod("Adapt") + + let (===) a b = LanguagePrimitives.PhysicalEquality a b + + let traverse f = + let rec fallback e = + match e with + | Let(v, value, body) -> + let fixedValue = f fallback value + let fixedBody = f fallback body + if fixedValue === value && fixedBody === body then + e + else + Expr.LetUnchecked(v, fixedValue, fixedBody) + | ShapeVarUnchecked _ -> e + | ShapeLambdaUnchecked(v, body) -> + let fixedBody = f fallback body + if fixedBody === body then + e + else + Expr.Lambda(v, fixedBody) + | ShapeCombinationUnchecked(shape, exprs) -> + let exprs1 = List.map (f fallback) exprs + if List.forall2 (===) exprs exprs1 then + e + else + RebuildShapeCombinationUnchecked(shape, exprs1) + fun e -> f fallback e + + let rightPipe = <@@ (|>) @@> + let inlineRightPipe expr = + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | SpecificCall rightPipe (None, _, [operand; applicable]) -> + let fixedOperand = loop operand + match loop applicable with + | Lambda(arg, body) -> + let v = Var("__temp", operand.Type) + let ev = Expr.Var v + + let fixedBody = loop body + Expr.Let(v, fixedOperand, fixedBody.Substitute(fun v1 -> if v1 = arg then Some ev else None)) + | fixedApplicable -> Expr.Application(fixedApplicable, fixedOperand) + | x -> fallback x + loop expr + + + let inlineValueBindings e = + let map = Dictionary(HashIdentity.Reference) + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | Let(id, (Value(_) as v), body) when not id.IsMutable -> + map.[id] <- v + let fixedBody = loop body + map.Remove(id) |> ignore + fixedBody + | ShapeVarUnchecked v -> + match map.TryGetValue v with + | true, e -> e + | _ -> orig + | x -> fallback x + loop e + + + let optimizeCurriedApplications expr = + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | Application(e, arg) -> + let e1 = tryPeelApplications e [loop arg] + if e1 === e then + orig + else + e1 + | x -> fallback x + and tryPeelApplications orig args = + let n = List.length args + match orig with + | Application(e, arg) -> + let e1 = tryPeelApplications e ((loop arg)::args) + if e1 === e then + orig + else + e1 + | Let(id, applicable, (Lambda(_) as body)) when n > 0 -> + let numberOfApplication = countPeelableApplications body id 0 + if numberOfApplication = 0 then orig + elif n = 1 then Expr.Application(applicable, List.head args) + elif n <= 5 then + let resultType = + applicable.Type + |> Seq.unfold (fun t -> + if not t.IsGenericType then None else + let args = t.GetGenericArguments() + if args.Length <> 2 then None else + Some (args.[1], args.[1]) + ) + |> Seq.toArray + |> (fun arr -> arr.[n - 1]) + + let adaptMethod = getFastFuncType args resultType + let adapted = Expr.Call(adaptMethod, [loop applicable]) + let invoke = adapted.Type.GetMethod("Invoke", [| for arg in args -> arg.Type |]) + Expr.Call(adapted, invoke, args) + else + (applicable, args) ||> List.fold (fun e a -> Expr.Application(e, a)) + | _ -> + orig + and countPeelableApplications expr v n = + match expr with + // v - applicable entity obtained on the prev step + // \arg -> let v1 = (f arg) in rest ==> f + | Lambda(arg, Let(v1, Application(Var f, Var arg1), rest)) when v = f && arg = arg1 -> countPeelableApplications rest v1 (n + 1) + // \arg -> (f arg) ==> f + | Lambda(arg, Application(Var f, Var arg1)) when v = f && arg = arg1 -> n + | _ -> n + loop expr +#endif + + member __.TranslateExpression q = simplifyExpr q + + member __.TranslateQuotationToCode qexprf (paramNames: string[]) (argExprs: Expr[]) = + // Use the real variable names instead of indices, to improve output of Debug.fs + // Add let bindings for arguments to ensure that arguments will be evaluated + let varDecisions = argExprs |> Array.mapi (fun i e -> match e with Var v when v.Name = paramNames.[i] -> false, v | _ -> true, Var(paramNames.[i], e.Type)) + let vars = varDecisions |> Array.map snd + let expr = qexprf ([for v in vars -> Expr.Var v]) + + let pairs = Array.zip argExprs varDecisions + let expr = Array.foldBack (fun (arg, (replace, var)) e -> if replace then Expr.LetUnchecked(var, arg, e) else e) pairs expr +#if !NO_GENERATIVE + let expr = + if isGenerated then + let e1 = inlineRightPipe expr + let e2 = optimizeCurriedApplications e1 + let e3 = inlineValueBindings e2 + e3 + else + expr +#endif + + simplifyExpr expr + + /// A cross-targeting type provider must ultimately provide quotations and reflection objects w.r.t. + /// the type binding context for the target assembly reference set. + /// + /// To make building a cross-targeting type provider palatable, the type provider is written w.r.t. to + /// homogeneous quotations and reflection objects referring to a copy of the target runtime constructs held + /// in the design-time assembly itself. These are then systematically remapped (replaced/translated) to the + /// corresponding reflection objects in the target assembly reference set. + /// + /// The ProvidedTypesContext acts as a way of creating provided objects where the replacement is automatically and + /// systematically applied. + + + /// Represents the type binding context for the type provider based on the set of assemblies + /// referenced by the compilation. + type ProvidedTypesContext(referencedAssemblyPaths: string list, assemblyReplacementMap: (string*string) list, sourceAssemblies: Assembly list) as this = + + // A duplicate 'mscorlib' appears in the paths reported by the F# compiler + let referencedAssemblyPaths = referencedAssemblyPaths |> Seq.distinctBy Path.GetFileNameWithoutExtension |> Seq.toList + //do System.Diagnostics.Debugger.Break() + + /// Find which assembly defines System.Object etc. + let systemRuntimeScopeRef = + lazy + referencedAssemblyPaths |> List.tryPick (fun path -> + try + let simpleName = Path.GetFileNameWithoutExtension path + if simpleName = "mscorlib" || simpleName = "System.Runtime" || simpleName = "netstandard" || simpleName = "System.Private.CoreLib" then + let reader = ILModuleReaderAfterReadingAllBytes (path, mkILGlobals EcmaMscorlibScopeRef) + let mdef = reader.ILModuleDef + match mdef.TypeDefs.TryFindByName(USome "System", "Object") with + | None -> None + | Some _ -> + let m = mdef.ManifestOfAssembly + let assRef = ILAssemblyRef(m.Name, UNone, (match m.PublicKey with USome k -> USome (PublicKey.KeyAsToken(k)) | UNone -> UNone), m.Retargetable, m.Version, m.Locale) + Some (ILScopeRef.Assembly assRef) + else + None + with _ -> None ) + |> function + | None -> EcmaMscorlibScopeRef // failwith "no reference to mscorlib.dll or System.Runtime.dll or netstandard.dll found" + | Some r -> r + + let fsharpCoreRefVersion = + lazy + referencedAssemblyPaths |> List.tryPick (fun path -> + try + let simpleName = Path.GetFileNameWithoutExtension path + if simpleName = "FSharp.Core" then + let reader = ILModuleReaderAfterReadingAllBytes (path, mkILGlobals (systemRuntimeScopeRef.Force())) + match reader.ILModuleDef.Manifest with + | Some m -> match m.Version with USome v -> Some v | UNone -> None + | None -> None + else + None + with _ -> None ) + |> function + | None -> typeof.Assembly.GetName().Version // failwith "no reference to FSharp.Core found" + | Some r -> r + + let ilGlobals = + lazy mkILGlobals (systemRuntimeScopeRef.Force()) + + let mkReader ref = + try let reader = ILModuleReaderAfterReadingAllBytes(ref, ilGlobals.Force()) + Choice1Of2(TargetAssembly(ilGlobals.Force(), this.TryBindILAssemblyRefToTgt, Some reader, ref, ProvidedTypeBuilder.typeBuilder) :> Assembly) + with err -> Choice2Of2 err + + let targetAssembliesTable_ = ConcurrentDictionary>() + let targetAssemblies_ = ResizeArray() + let targetAssembliesQueue = ResizeArray<_>() + do targetAssembliesQueue.Add (fun () -> + for ref in referencedAssemblyPaths do + let reader = mkReader ref + let simpleName = Path.GetFileNameWithoutExtension ref + targetAssembliesTable_.[simpleName] <- reader + match reader with + | Choice2Of2 _ -> () + | Choice1Of2 asm -> targetAssemblies_.Add asm) + let flush() = + let qs = targetAssembliesQueue.ToArray() + targetAssembliesQueue.Clear() + for q in qs do q() + let getTargetAssemblies() = flush(); targetAssemblies_ + let getTargetAssembliesTable() = flush(); targetAssembliesTable_ + + let tryBindTargetAssemblySimple(simpleName:string): Choice = + let table = getTargetAssembliesTable() + if table.ContainsKey(simpleName) then table.[simpleName] + else Choice2Of2 (Exception(sprintf "assembly %s not found" simpleName)) + + let sourceAssembliesTable_ = ConcurrentDictionary() + let sourceAssemblies_ = ResizeArray<_>() + let sourceAssembliesQueue = ResizeArray<_>() + + let enqueueReferencedAssemblies(asm: Assembly) = + do sourceAssembliesQueue.Add (fun () -> + [| for referencedAssemblyName in asm.GetReferencedAssemblies() do + let referencedAssembly = try Assembly.Load(referencedAssemblyName) with _ -> null + if not (isNull referencedAssembly) then + yield referencedAssembly |]) + + do sourceAssembliesQueue.Add (fun () -> List.toArray sourceAssemblies) + + let getSourceAssemblies() = + while sourceAssembliesQueue.Count > 0 do + let qs = sourceAssembliesQueue.ToArray() + sourceAssembliesQueue.Clear() + for q in qs do + for asm in q() do + let simpleName = asm.GetName().Name + if not (sourceAssembliesTable_.ContainsKey(simpleName)) then + sourceAssembliesTable_.[simpleName] <- asm + sourceAssemblies_.Add asm + // Find the transitive closure of all referenced assemblies + enqueueReferencedAssemblies asm + + sourceAssemblies_ + + /// When translating quotations, Expr.Var's are translated to new variable respecting reference equality. + let varTableFwd = Dictionary() + let varTableBwd = Dictionary() + let assemblyTableFwd = Dictionary() + let typeTableFwd = Dictionary() + let typeTableBwd = Dictionary() + + let fixName (fullName:string) = + if fullName.StartsWith("FSI_") then + // when F# Interactive is the host of the design time assembly, + // all namespaces are prefixed with FSI_, in the runtime assembly + // the name won't have that prefix + fullName.Substring(fullName.IndexOf('.') + 1) + else + fullName + + let tryGetTypeFromAssembly toTgt (originalAssemblyName:string) fullName (asm:Assembly) = + // if the original assembly of the type being replaced is in `assemblyReplacementMap`, + // then we only map it to assemblies with a name specified in `assemblyReplacementMap` + let restrictedAndMatching = + assemblyReplacementMap + |> Seq.exists (fun (originalName:string, newName:string) -> + originalAssemblyName.StartsWith originalName && not (asm.FullName.StartsWith(newName))) + + // Check if the assembly can be queried for types yet. Cross-assembly recursive linking back to generated assemblies + // is not supported in some cases where recursive linking is needed during the process of generation itself. + let canQuery = (match asm with :? TargetAssembly as t -> t.Reader.IsSome | _ -> true) + + if not canQuery then None + elif restrictedAndMatching then None + elif asm.FullName.StartsWith "FSI-ASSEMBLY" then + // when F# Interactive is the host of the design time assembly, + // for each type in the runtime assembly there might be multiple + // versions (FSI_0001.FullTypeName, FSI_0002.FullTypeName, etc). + // Get the last one. + asm.GetTypes() + |> Seq.filter (fun t -> fixName t.FullName = fullName) + |> Seq.sortBy (fun t -> t.FullName) + |> Seq.toList + |> function [] -> None | xs -> Some (Seq.last xs, false) + else + asm.GetType fullName |> function null -> None | x -> Some (x, true) + + let typeBuilder = ProvidedTypeBuilder.typeBuilder + let rec convTypeRef toTgt (t:Type) = + let table = (if toTgt then typeTableFwd else typeTableBwd) + match table.TryGetValue(t) with + | true, newT -> newT + | false, _ -> + match t with + | :? ProvidedTypeDefinition as ptd when toTgt -> + if ptd.IsErased && ptd.BelongsToTargetModel then failwithf "unexpected erased target ProvidedTypeDefinition '%O'" ptd + // recursively get the provided type. + convTypeDefToTgt t + + | _ -> + let asms = (if toTgt then getTargetAssemblies() else getSourceAssemblies()) + let fullName = fixName t.FullName + + // TODO: this linear search through all available source/target assemblies feels as if it must be too slow in some cases. + // However, we store type translations in various tables (typeTableFwd and typeTableBwd) so perhaps it is not a problem + let rec loop i = + if i < 0 then + let msg = + if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList) + elif getSourceAssemblies() |> Seq.length = 0 then sprintf "A failure occured while determining compilation references" + else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList) + failwith msg + else + match tryGetTypeFromAssembly toTgt t.Assembly.FullName fullName asms.[i] with + | Some (newT, canSave) -> + if canSave then table.[t] <- newT + newT + | None -> loop (i - 1) + loop (asms.Count - 1) + + and convType toTgt (t:Type) = + let table = (if toTgt then typeTableFwd else typeTableBwd) + match table.TryGetValue(t) with + | true, newT -> newT + | false, _ -> + if t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpTypeAbbreviation then t + // Types annotated with units-of-measure + elif t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpUnitAnnotated then + let genericType = t.GetGenericTypeDefinition() + let newT = convTypeRef toTgt genericType + let typeArguments = t.GetGenericArguments() |> Array.map (convType toTgt) |> Array.toList + ProvidedMeasureBuilder.AnnotateType (newT, typeArguments) + elif t.IsGenericType && not t.IsGenericTypeDefinition then + let genericType = t.GetGenericTypeDefinition() + let newT = convTypeRef toTgt genericType + let typeArguments = t.GetGenericArguments() |> Array.map (convType toTgt) + typeBuilder.MakeGenericType(newT,typeArguments) + elif t.IsGenericParameter then t + elif t.IsArray || t.IsByRef || t.IsPointer then + let elemType = t.GetElementType() + let elemTypeT = convType toTgt elemType + if t.IsArray then + let rank = t.GetArrayRank() + if rank = 1 then typeBuilder.MakeArrayType(elemTypeT) else typeBuilder.MakeRankedArrayType(elemTypeT,t.GetArrayRank()) + elif t.IsByRef then typeBuilder.MakeByRefType(elemTypeT) + else typeBuilder.MakePointerType(elemTypeT) + + else + convTypeRef toTgt t + + and convTypeToTgt ty = convType true ty + and convTypeToSrc ty = convType false ty + + and convPropertyRefToTgt (p: PropertyInfo) = + Debug.Assert((match p with :? ProvidedProperty as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedProperty") + let t = convTypeToTgt p.DeclaringType + let bindingFlags = bindSome p.IsStatic + let pT = t.GetProperty(p.Name, bindingFlags) + if isNull pT then failwithf "Property '%O' of type '%O' not found. This property may be missing in the types available in the target assemblies." p t + Debug.Assert((match pT with :? ProvidedProperty as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedProperty") + pT + + and convFieldRefToTgt (f: FieldInfo) = + Debug.Assert((match f with :? ProvidedField as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedField") + let t = convTypeToTgt f.DeclaringType + let fT = t.GetField(f.Name, bindSome f.IsStatic) + if isNull fT then failwithf "Field '%O' of type '%O' not found. This field may be missing in the types available in the target assemblies." f t + Debug.Assert((match fT with :? ProvidedField as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedField") + fT + + and convMethodRefToTgt (m: MethodInfo) = + Debug.Assert((match m with :? ProvidedMethod as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedMethod") + //Debug.Assert (m.Name <> "get_Item1" || m.DeclaringType.Name <> "Tuple`2") + let declTyT = convTypeToTgt m.DeclaringType + let mT = + if m.IsGenericMethod then + let genericMethod = m.GetGenericMethodDefinition() + let parameterTypesT = genericMethod.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + let genericMethodT = declTyT.GetMethod(genericMethod.Name, bindSome m.IsStatic, null, parameterTypesT, null) + if isNull genericMethodT then null else + let typeArgumentsT = m.GetGenericArguments() |> Array.map convTypeToTgt + genericMethodT.MakeGenericMethod(typeArgumentsT) + else + let parameterTypesT = m.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + declTyT.GetMethod(m.Name, bindSome m.IsStatic, null, parameterTypesT, null) + match mT with + | null -> failwithf "Method '%O' not found in type '%O'. This method may be missing in the types available in the target assemblies." m mT + | _ -> + Debug.Assert((match mT with :? ProvidedMethod as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedMethod") + mT + + and tryConvConstructorRefToTgt (cons: ConstructorInfo) = + Debug.Assert((match cons with :? ProvidedConstructor as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedConstructor") + let declTyT = convTypeToTgt cons.DeclaringType + let parameterTypesT = cons.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + let flags = + (if cons.IsStatic then BindingFlags.Static else BindingFlags.Instance) + ||| (if cons.IsPublic then BindingFlags.Public else BindingFlags.NonPublic ) + let consT = declTyT.GetConstructor(flags, null,parameterTypesT, null ) + match consT with + | null -> Choice1Of2 (sprintf "Constructor '%O' not found in type '%O'. This constructor may be missing in the types available in the target assemblies." cons declTyT) + | _ -> + Debug.Assert((match consT with :? ProvidedConstructor as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedConstructor") + Choice2Of2 consT + + and convConstructorRefToTgt (cons: ConstructorInfo) = + match tryConvConstructorRefToTgt cons with + | Choice1Of2 err -> failwith err + | Choice2Of2 res -> res + + and convVarToSrc (v: Var) = + match varTableBwd.TryGetValue v with + | true, v -> v + | false, _ -> + let newVar = Var (v.Name, convTypeToSrc v.Type, v.IsMutable) + // store the original var as we'll have to revert to it later + varTableBwd.Add(v, newVar) + varTableFwd.Add(newVar, v) + newVar + + and convVarExprToSrc quotation = + match quotation with + | ShapeVarUnchecked v -> + Expr.Var (convVarToSrc v) + | _ -> failwithf "Unexpected non-variable argument: %A" quotation + + and convVarToTgt (v: Var) = + match varTableFwd.TryGetValue v with + | true, v -> v + | false, _ -> + // It's a variable local to the quotation + let newVar = Var (v.Name, convTypeToTgt v.Type, v.IsMutable) + // store it so we reuse it from now on + varTableFwd.Add(v, newVar) + varTableBwd.Add(newVar, v) + newVar + + + and convExprToTgt quotation = + match quotation with + | Call (obj, m, args) -> + let mR = convMethodRefToTgt m + let argsR = List.map convExprToTgt args + match obj with + | Some obj -> Expr.CallUnchecked (convExprToTgt obj, mR, argsR) + | None -> Expr.CallUnchecked (mR, argsR) + | PropertyGet (obj, p, indexArgs) -> + let pR = convPropertyRefToTgt p + let indexArgsR = List.map convExprToTgt indexArgs + match obj with + | Some obj -> Expr.PropertyGetUnchecked (convExprToTgt obj, pR, indexArgsR) + | None -> Expr.PropertyGetUnchecked (pR, indexArgsR) + | PropertySet (obj, p, indexArgs, value) -> + let pR = convPropertyRefToTgt p + let indexArgsR = List.map convExprToTgt indexArgs + match obj with + | Some obj -> Expr.PropertySetUnchecked (convExprToTgt obj, pR, convExprToTgt value, indexArgsR) + | None -> Expr.PropertySetUnchecked (pR, convExprToTgt value, indexArgsR) + | NewObject (c, exprs) -> + let exprsR = List.map convExprToTgt exprs + Expr.NewObjectUnchecked (convConstructorRefToTgt c, exprsR) + | DefaultValue (t) -> + Expr.DefaultValue (convTypeToTgt t) + | Coerce (expr, t) -> + Expr.Coerce (convExprToTgt expr, convTypeToTgt t) + | TypeTest (expr, t) -> + Expr.TypeTest (convExprToTgt expr, convTypeToTgt t) + | TryWith (body, filterVar, filterBody, catchVar, catchBody) -> + Expr.TryWith (convExprToTgt body, convVarToTgt filterVar, convExprToTgt filterBody, convVarToTgt catchVar, convExprToTgt catchBody) + | TryFinally (body, compensation) -> + Expr.TryFinally (convExprToTgt body, convExprToTgt compensation) + | NewArray (t, exprs) -> + Expr.NewArrayUnchecked (convTypeToTgt t, List.map convExprToTgt exprs) + | NewTuple (exprs) -> + Expr.NewTuple (List.map convExprToTgt exprs) + | Lambda (v, expr) -> + Expr.Lambda (convVarToTgt v, convExprToTgt expr) + | TupleGet (expr, i) -> + Expr.TupleGetUnchecked (convExprToTgt expr, i) + | NewDelegate (t, vars, expr) -> + Expr.NewDelegateUnchecked (convTypeToTgt t, List.map convVarToTgt vars, convExprToTgt expr) + | FieldGet (obj, f) -> + match obj with + | Some obj -> Expr.FieldGetUnchecked (convExprToTgt obj, convFieldRefToTgt f) + | None -> Expr.FieldGetUnchecked (convFieldRefToTgt f) + | FieldSet (obj, f, value) -> + match obj with + | Some obj -> Expr.FieldSetUnchecked (convExprToTgt obj, convFieldRefToTgt f, convExprToTgt value) + | None -> Expr.FieldSetUnchecked (convFieldRefToTgt f, convExprToTgt value) + | Let (var, value, body) -> + Expr.LetUnchecked(convVarToTgt var, convExprToTgt value, convExprToTgt body) + + // Eliminate some F# constructs which do not cross-target well + | Application(f, e) -> + convExprToTgt (Expr.CallUnchecked(f, f.Type.GetMethod "Invoke", [ e ]) ) + | NewUnionCase(ci, es) -> + convExprToTgt (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) + | NewRecord(ci, es) -> + convExprToTgt (Expr.NewObjectUnchecked(FSharpValue.PreComputeRecordConstructorInfo ci, es) ) + | UnionCaseTest(e, uc) -> + let tagInfo = FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType + let tagExpr = + match tagInfo with + | :? PropertyInfo as tagProp -> Expr.PropertyGetUnchecked(e, tagProp) + | :? MethodInfo as tagMeth -> + if tagMeth.IsStatic then Expr.CallUnchecked(tagMeth, [e]) + else Expr.CallUnchecked(e, tagMeth, []) + | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo" + let tagNumber = uc.Tag + convExprToTgt <@@ (%%(tagExpr): int) = tagNumber @@> + + | Value (obj, ty) -> + match obj with + | :? Type as vty -> Expr.Value(convTypeToTgt vty, ty) + | _ -> Expr.Value(obj, convTypeToTgt ty) + + // Traverse remaining constructs + | ShapeVarUnchecked v -> + Expr.Var (convVarToTgt v) + | ShapeLambdaUnchecked _ as d -> + failwithf "It's not possible to use construct %O when cross targetting to a different FSharp.Core. Make sure you're not calling a function with signature A->(B->C) instead of A->B->C (using |> causes this)." d + | ShapeCombinationUnchecked (o, exprs) -> + RebuildShapeCombinationUnchecked (o, List.map convExprToTgt exprs) + + and convCodeToTgt (codeFun: Expr list -> Expr, isStatic, isCtor, parameters: ProvidedParameter[], isGenerated) = + (fun argsT -> + // argsT: the target arg expressions coming from host tooling. Includes "this" for instance methods and generative constructors. + // parameters: the (source) parameters specific by the TPDTC. Does not include "this" + // paramNames: equal in length to argsT. The preferred named for the parameters. Seems to include "this" for instance methods and generative constructors. + let args = List.map convVarExprToSrc argsT + let paramNames = + // https://github.com/fsprojects/SwaggerProvider/blob/cfb7a665fada77fd0200591f62faba0ba44e172c/src/SwaggerProvider.DesignTime/SwaggerProviderConfig.fs#L79 + // "Erased constructors should not pass the instance as the first argument when calling invokeCode!" + // "Generated constructors should always pass the instance as the first argument when calling invokeCode!" + [| if not isStatic && (not isCtor || isGenerated) then yield "this" + for p in parameters do yield p.Name |] + let code2 = QuotationSimplifier(isGenerated).TranslateQuotationToCode codeFun paramNames (Array.ofList args) + let codeT = convExprToTgt code2 + codeT) + + and convBaseCallToTgt (codeFun: Expr list -> ConstructorInfo * Expr list, isGenerated) = + (fun argsT -> + let args = List.map convVarExprToSrc argsT + let ctor, argExprs = codeFun args + let argExprs2 = List.map (QuotationSimplifier(isGenerated).TranslateExpression) argExprs + //let code2 = QuotationSimplifier(false).TranslateQuotationToCode code paramNames + let ctorT = convConstructorRefToTgt ctor + let codeT = List.map convExprToTgt argExprs2 + ctorT, codeT) + + and convMemberRefToTgt (x: MemberInfo) = + match x with + | :? PropertyInfo as p -> convPropertyRefToTgt p :> MemberInfo + | :? FieldInfo as p -> convFieldRefToTgt p :> MemberInfo + | :? MethodInfo as p -> convMethodRefToTgt p :> MemberInfo + | :? ConstructorInfo as p -> convConstructorRefToTgt p :> MemberInfo + | :? Type as p -> convTypeToTgt p :> MemberInfo + | _ -> failwith "unknown member info" + + and convCustomAttributesTypedArg (x: CustomAttributeTypedArgument) = + CustomAttributeTypedArgument(convTypeToTgt x.ArgumentType, x.Value) + + and convCustomAttributesNamedArg (x: CustomAttributeNamedArgument) = + CustomAttributeNamedArgument(convMemberRefToTgt x.MemberInfo, convCustomAttributesTypedArg x.TypedValue) + + and tryConvCustomAttributeDataToTgt (x: CustomAttributeData) = + // Allow a fail on AllowNullLiteralAttribute. Some downlevel FSharp.Core don't have this. + // In this case just skip the attribute which means null is allowed when targeting downlevel FSharp.Core. + match tryConvConstructorRefToTgt x.Constructor with + | Choice1Of2 _ when x.Constructor.DeclaringType.Name = typeof.Name -> None + | Choice1Of2 msg -> failwith msg + | Choice2Of2 res -> + Some + { new CustomAttributeData () with + member __.Constructor = res + member __.ConstructorArguments = [| for arg in x.ConstructorArguments -> convCustomAttributesTypedArg arg |] :> IList<_> + member __.NamedArguments = [| for arg in x.NamedArguments -> convCustomAttributesNamedArg arg |] :> IList<_> } + + and convCustomAttributesDataToTgt (cattrs: IList) = + cattrs |> Array.ofSeq |> Array.choose tryConvCustomAttributeDataToTgt + + and convProvidedTypeDefToTgt (x: ProvidedTypeDefinition) = + if x.IsErased && x.BelongsToTargetModel then failwithf "unexpected target type definition '%O'" x + match typeTableFwd.TryGetValue(x) with + | true, newT -> (newT :?> ProvidedTypeDefinition) + | false, _ -> + let container = + match x.Container with + | TypeContainer.Namespace(assemf, nm) -> + TypeContainer.Namespace((fun () -> + match assemf() with + | :? ProvidedAssembly as assembly -> convProvidedAssembly assembly + | assembly -> + assemblyReplacementMap + |> Seq.tryPick (fun (originalName, newName) -> + if assembly.GetName().Name = originalName then + match this.TryBindSimpleAssemblyNameToTarget(newName) with + | Choice1Of2 replacementAssembly -> Some replacementAssembly + | Choice2Of2 _ -> None + else + None) + |> function None -> assembly | Some replacementAssembly -> replacementAssembly + ), nm) + | c -> c // nested types patched below + + // Create the type definition with contents mapped to the target + // Use a 'let rec' to allow access to the target as the declaring + // type of the contents in a delayed way. + let rec xT : ProvidedTypeDefinition = + let mutable methodsIdx = 0 + let checkFreshMethods() = + x.CountMembersFromCursor(methodsIdx) > 0 + + let getFreshMethods() = + let vs, idx2 = x.GetMembersFromCursor(methodsIdx) + methodsIdx <- idx2 + vs |> Array.map (convMemberDefToTgt xT) + + let mutable interfacesIdx = 0 + let getFreshInterfaces() = + let vs, idx2 = x.GetInterfaceImplsFromCursor(interfacesIdx) + interfacesIdx <- idx2 + vs |> Array.map convTypeToTgt + + let mutable overridesIdx = 0 + let getFreshMethodOverrides() = + let vs, idx2 = x.GetMethodOverridesFromCursor(overridesIdx) + overridesIdx <- idx2 + vs |> Array.map (fun (a, b) -> (convMethodRefToTgt a :?> ProvidedMethod), convMethodRefToTgt b) + + let backingDataSource = Some (checkFreshMethods, getFreshMethods, getFreshInterfaces, getFreshMethodOverrides) + + ProvidedTypeDefinition(true, container, x.Name, + (x.BaseTypeRaw >> Option.map convTypeToTgt), + x.AttributesRaw, + (x.EnumUnderlyingTypeRaw >> Option.map convTypeToTgt), + x.StaticParams |> List.map convStaticParameterDefToTgt, + x.StaticParamsApply |> Option.map (fun f s p -> + let t = f s p + let tT = convProvidedTypeDefToTgt t + tT), + backingDataSource, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt), + x.NonNullable, + x.HideObjectMethods, ProvidedTypeBuilder.typeBuilder) + + Debug.Assert(not (typeTableFwd.ContainsKey(x))) + typeTableFwd.[x] <- xT + if x.IsNested then + let parentT = (convTypeToTgt x.DeclaringType :?> ProvidedTypeDefinition) + parentT.PatchDeclaringTypeOfMember xT + xT + + and convTypeDefToTgt (x: Type) = + match x with + | :? ProvidedTypeDefinition as x -> convProvidedTypeDefToTgt x :> Type + | _ -> x + + and convParameterDefToTgt (x: ProvidedParameter) = + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedParameter") + ProvidedParameter(true, x.Name, x.Attributes, + x.ParameterType |> convTypeToTgt, + x.OptionalValue, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) + + and convStaticParameterDefToTgt (x: ProvidedStaticParameter) = + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedStaticParameter") + ProvidedStaticParameter(x.Name, convTypeToTgt x.ParameterType, ?parameterDefaultValue=x.ParameterDefaultValue) + + and convMemberDefToTgt declTyT (x: MemberInfo) = + let xT : MemberInfo = + match x with + | :? ProvidedField as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedField") + ProvidedField(true, x.Name, x.Attributes, + x.FieldType |> convTypeToTgt, + x.GetRawConstantValue(), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedProperty as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedProperty") + ProvidedProperty(true, x.Name, x.Attributes, + x.PropertyType |> convTypeToTgt, + x.IsStatic, + x.Getter |> Option.map (fun f -> f >> convMethodRefToTgt), + x.Setter |> Option.map (fun f -> f >> convMethodRefToTgt), + x.IndexParameters |> Array.map convParameterDefToTgt, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedEvent as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedEvent") + ProvidedEvent(true, x.Name, x.Attributes, + x.EventHandlerType |> convTypeToTgt, + x.IsStatic, + (fun () -> convMethodRefToTgt x.Adder), + (fun () -> convMethodRefToTgt x.Remover), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedConstructor as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedConstructor") + ProvidedConstructor(true, x.Attributes, + x.Parameters |> Array.map convParameterDefToTgt, + convCodeToTgt (x.GetInvokeCode, x.IsStatic, true, x.Parameters, not x.IsErased), + (match x.BaseCall with None -> None | Some f -> Some (convBaseCallToTgt(f, not x.IsErased))), + x.IsImplicitConstructor, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedMethod as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedMethod") + ProvidedMethod(true, x.Name, x.Attributes, + x.Parameters |> Array.map convParameterDefToTgt, + x.ReturnType |> convTypeToTgt, + x.GetInvokeCode |> Option.map (fun invokeCode -> convCodeToTgt (invokeCode, x.IsStatic, false, x.Parameters, not x.IsErased)), + x.StaticParams |> List.map convStaticParameterDefToTgt, + x.StaticParamsApply |> Option.map (fun f s p -> f s p |> convProvidedMethodDefToTgt declTyT), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedTypeDefinition as x -> convTypeDefToTgt x :> _ + | _ -> failwith "unknown member type" + Debug.Assert(declTyT.BelongsToTargetModel) + declTyT.PatchDeclaringTypeOfMember xT + Debug.Assert(xT.DeclaringType :? ProvidedTypeDefinition) + Debug.Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel) + xT + + and convProvidedMethodDefToTgt declTyT (x: ProvidedMethod) = + convMemberDefToTgt declTyT x :?> ProvidedMethod + + and convProvidedAssembly (assembly: ProvidedAssembly) = + match assemblyTableFwd.TryGetValue(assembly) with + | true, newT -> newT + | false, _ -> + let tgtAssembly = ProvidedAssembly(true, assembly.GetName(), assembly.Location, K(convCustomAttributesDataToTgt(assembly.GetCustomAttributesData()))) + + for (types, enclosingGeneratedTypeNames) in assembly.GetTheTypes() do + let typesT = Array.map convProvidedTypeDefToTgt types + tgtAssembly.AddTheTypes (typesT, enclosingGeneratedTypeNames) + + assemblyTableFwd.Add(assembly, tgtAssembly) + this.AddSourceAssembly(assembly) + this.AddTargetAssembly(assembly.GetName(), tgtAssembly) + (tgtAssembly :> Assembly) + + let rec convNamespaceToTgt (x: IProvidedNamespace) = + { new IProvidedNamespace with + member __.GetNestedNamespaces() = Array.map convNamespaceToTgt (x.GetNestedNamespaces()) + member __.NamespaceName = x.NamespaceName + member __.GetTypes() = Array.map convTypeDefToTgt (x.GetTypes()) + member __.ResolveTypeName typeName = convTypeDefToTgt (x.ResolveTypeName typeName) } + + /// Gets the equivalent target method + member __.ConvertSourceMethodRefToTarget t = convMethodRefToTgt t + + /// Gets the equivalent target constructor + member __.ConvertSourceConstructorRefToTarget t = convConstructorRefToTgt t + + /// Gets the equivalent target type + member __.ConvertSourceTypeToTarget t = convTypeToTgt t + + member __.ConvertTargetTypeToSource t = convTypeToSrc t + + member __.ConvertSourceExprToTarget e = convExprToTgt e + + member __.ConvertSourceNamespaceToTarget ns = convNamespaceToTgt ns + + member __.ConvertSourceProvidedTypeDefinitionToTarget ptd = convProvidedTypeDefToTgt ptd + + member __.TryBindILAssemblyRefToTgt(aref: ILAssemblyRef): Choice = tryBindTargetAssemblySimple(aref.Name) + + member __.TryBindAssemblyNameToTarget(aref: AssemblyName): Choice = tryBindTargetAssemblySimple(aref.Name) + + member __.TryBindSimpleAssemblyNameToTarget(assemblyName: string) = tryBindTargetAssemblySimple(assemblyName) + + member __.ILGlobals = ilGlobals.Value + + member __.ReferencedAssemblyPaths = referencedAssemblyPaths + + member __.GetTargetAssemblies() = getTargetAssemblies().ToArray() + + member __.GetSourceAssemblies() = getSourceAssemblies().ToArray() + + member __.FSharpCoreAssemblyVersion = fsharpCoreRefVersion.Force() + + member this.ReadRelatedAssembly(fileName) = + let ilg = ilGlobals.Force() + let reader = ILModuleReaderAfterReadingAllBytes(fileName, ilg) + TargetAssembly(ilg, this.TryBindILAssemblyRefToTgt, Some reader, fileName, ProvidedTypeBuilder.typeBuilder) :> Assembly + + member this.ReadRelatedAssembly(bytes:byte[]) = + let fileName = "file.dll" + let ilg = ilGlobals.Force() + let is = ByteFile(bytes) + let pe = PEReader(fileName, is) + let mdchunk = bytes.[pe.MetadataPhysLoc .. pe.MetadataPhysLoc + pe.MetadataSize - 1] + let mdfile = ByteFile(mdchunk) + let reader = ILModuleReader(fileName, mdfile, ilg, true) + TargetAssembly(ilg, this.TryBindILAssemblyRefToTgt, Some reader, fileName, ProvidedTypeBuilder.typeBuilder) :> Assembly + + member __.AddSourceAssembly(asm: Assembly) = + sourceAssembliesQueue.Add (fun () -> [| asm |]) + + member __.AddTargetAssembly(asmName: AssemblyName, asm: Assembly) = + targetAssembliesQueue.Add (fun () -> + targetAssembliesTable_.[asmName.Name] <- Choice1Of2 asm + targetAssemblies_.Add asm) + + static member Create (config: TypeProviderConfig, assemblyReplacementMap, sourceAssemblies) = + + // Use the reflection hack to determine the set of referenced assemblies by reflecting over the SystemRuntimeContainsType + // closure in the TypeProviderConfig object. + let referencedAssemblyPaths = config.ReferencedAssemblies |> Array.toList + ProvidedTypesContext(referencedAssemblyPaths, assemblyReplacementMap, sourceAssemblies) + + + +#if !NO_GENERATIVE + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + module BinaryWriter = + + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + open System.Text + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + + let formatCodeLabel (x:int) = "L"+string x + + let emitBytesViaBuffer f = let bb = ByteBuffer.Create 10 in f bb; bb.Close() + + /// Alignment and padding + let align alignment n = ((n + alignment - 1) / alignment) * alignment + + //--------------------------------------------------------------------- + // Concrete token representations etc. used in PE files + //--------------------------------------------------------------------- + + + let getUncodedToken (tab:ILTableName) idx = ((tab.Index <<< 24) ||| idx) + + let markerForUnicodeBytes (b:byte[]) = + let len = b.Length + let rec scan i = + i < len/2 && + (let b1 = Bytes.get b (i*2) + let b2 = Bytes.get b (i*2+1) + (b2 <> 0) + || (b1 >= 0x01 && b1 <= 0x08) // as per ECMA and C# + || (b1 >= 0xE && b1 <= 0x1F) // as per ECMA and C# + || (b1 = 0x27) // as per ECMA and C# + || (b1 = 0x2D) // as per ECMA and C# + || (b1 > 0x7F) // as per C# (but ECMA omits this) + || scan (i+1)) + let marker = if scan 0 then 0x01 else 0x00 + marker + + + // -------------------------------------------------------------------- + // Fixups + // -------------------------------------------------------------------- + + /// Check that the data held at a fixup is some special magic value, as a sanity check + /// to ensure the fixup is being placed at a ood location. + let checkFixup32 (data: byte[]) offset exp = + if data.[offset + 3] <> b3 exp then failwith "fixup sanity check failed" + if data.[offset + 2] <> b2 exp then failwith "fixup sanity check failed" + if data.[offset + 1] <> b1 exp then failwith "fixup sanity check failed" + if data.[offset] <> b0 exp then failwith "fixup sanity check failed" + + let applyFixup32 (data:byte[]) offset v = + data.[offset] <- b0 v + data.[offset+1] <- b1 v + data.[offset+2] <- b2 v + data.[offset+3] <- b3 v + + //--------------------------------------------------------------------- + // TYPES FOR TABLES + //--------------------------------------------------------------------- + + module RowElementTags = + let [] UShort = 0 + let [] ULong = 1 + let [] Data = 2 + let [] DataResources = 3 + let [] Guid = 4 + let [] Blob = 5 + let [] String = 6 + let [] SimpleIndexMin = 7 + let SimpleIndex (t: ILTableName) = assert (t.Index <= 112); SimpleIndexMin + t.Index + let [] SimpleIndexMax = 119 + + let [] TypeDefOrRefOrSpecMin = 120 + let TypeDefOrRefOrSpec (t: TypeDefOrRefOrSpecTag) = assert (t.Tag <= 2); TypeDefOrRefOrSpecMin + t.Tag (* + 111 + 1 = 0x70 + 1 = max ILTableName.Tndex + 1 *) + let [] TypeDefOrRefOrSpecMax = 122 + + let [] TypeOrMethodDefMin = 123 + let TypeOrMethodDef (t: TypeOrMethodDefTag) = assert (t.Tag <= 1); TypeOrMethodDefMin + t.Tag (* + 2 + 1 = max TypeDefOrRefOrSpec.Tag + 1 *) + let [] TypeOrMethodDefMax = 124 + + let [] HasConstantMin = 125 + let HasConstant (t: HasConstantTag) = assert (t.Tag <= 2); HasConstantMin + t.Tag (* + 1 + 1 = max TypeOrMethodDef.Tag + 1 *) + let [] HasConstantMax = 127 + + let [] HasCustomAttributeMin = 128 + let HasCustomAttribute (t: HasCustomAttributeTag) = assert (t.Tag <= 21); HasCustomAttributeMin + t.Tag (* + 2 + 1 = max HasConstant.Tag + 1 *) + let [] HasCustomAttributeMax = 149 + + let [] HasFieldMarshalMin = 150 + let HasFieldMarshal (t: HasFieldMarshalTag) = assert (t.Tag <= 1); HasFieldMarshalMin + t.Tag (* + 21 + 1 = max HasCustomAttribute.Tag + 1 *) + let [] HasFieldMarshalMax = 151 + + let [] HasDeclSecurityMin = 152 + let HasDeclSecurity (t: HasDeclSecurityTag) = assert (t.Tag <= 2); HasDeclSecurityMin + t.Tag (* + 1 + 1 = max HasFieldMarshal.Tag + 1 *) + let [] HasDeclSecurityMax = 154 + + let [] MemberRefParentMin = 155 + let MemberRefParent (t: MemberRefParentTag) = assert (t.Tag <= 4); MemberRefParentMin + t.Tag (* + 2 + 1 = max HasDeclSecurity.Tag + 1 *) + let [] MemberRefParentMax = 159 + + let [] HasSemanticsMin = 160 + let HasSemantics (t: HasSemanticsTag) = assert (t.Tag <= 1); HasSemanticsMin + t.Tag (* + 4 + 1 = max MemberRefParent.Tag + 1 *) + let [] HasSemanticsMax = 161 + + let [] MethodDefOrRefMin = 162 + let MethodDefOrRef (t: MethodDefOrRefTag) = assert (t.Tag <= 2); MethodDefOrRefMin + t.Tag (* + 1 + 1 = max HasSemantics.Tag + 1 *) + let [] MethodDefOrRefMax = 164 + + let [] MemberForwardedMin = 165 + let MemberForwarded (t: MemberForwardedTag) = assert (t.Tag <= 1); MemberForwardedMin + t.Tag (* + 2 + 1 = max MethodDefOrRef.Tag + 1 *) + let [] MemberForwardedMax = 166 + + let [] ImplementationMin = 167 + let Implementation (t: ImplementationTag) = assert (t.Tag <= 2); ImplementationMin + t.Tag (* + 1 + 1 = max MemberForwarded.Tag + 1 *) + let [] ImplementationMax = 169 + + let [] CustomAttributeTypeMin = 170 + let CustomAttributeType (t: CustomAttributeTypeTag) = assert (t.Tag <= 3); CustomAttributeTypeMin + t.Tag (* + 2 + 1 = max Implementation.Tag + 1 *) + let [] CustomAttributeTypeMax = 173 + + let [] ResolutionScopeMin = 174 + let ResolutionScope (t: ResolutionScopeTag) = assert (t.Tag <= 4); ResolutionScopeMin + t.Tag (* + 3 + 1 = max CustomAttributeType.Tag + 1 *) + let [] ResolutionScopeMax = 178 + + [] + type RowElement(tag:int32, idx: int32) = + + member __.Tag = tag + member __.Val = idx + + // These create RowElements + let UShort (x:uint16) = RowElement(RowElementTags.UShort, int32 x) + let ULong (x:int32) = RowElement(RowElementTags.ULong, x) + /// Index into cenv.data or cenv.resources. Gets fixed up later once we known an overall + /// location for the data section. flag indicates if offset is relative to cenv.resources. + let Data (x:int, k:bool) = RowElement((if k then RowElementTags.DataResources else RowElementTags.Data ), x) + /// pos. in guid array + let Guid (x:int) = RowElement(RowElementTags.Guid, x) + /// pos. in blob array + let Blob (x:int) = RowElement(RowElementTags.Blob, x) + /// pos. in string array + let StringE (x:int) = RowElement(RowElementTags.String, x) + /// pos. in some table + let SimpleIndex (t, x:int) = RowElement(RowElementTags.SimpleIndex t, x) + let TypeDefOrRefOrSpec (t, x:int) = RowElement(RowElementTags.TypeDefOrRefOrSpec t, x) + let TypeOrMethodDef (t, x:int) = RowElement(RowElementTags.TypeOrMethodDef t, x) + let HasConstant (t, x:int) = RowElement(RowElementTags.HasConstant t, x) + let HasCustomAttribute (t, x:int) = RowElement(RowElementTags.HasCustomAttribute t, x) + let HasFieldMarshal (t, x:int) = RowElement(RowElementTags.HasFieldMarshal t, x) + let HasDeclSecurity (t, x:int) = RowElement(RowElementTags.HasDeclSecurity t, x) + let MemberRefParent (t, x:int) = RowElement(RowElementTags.MemberRefParent t, x) + let HasSemantics (t, x:int) = RowElement(RowElementTags.HasSemantics t, x) + let MethodDefOrRef (t, x:int) = RowElement(RowElementTags.MethodDefOrRef t, x) + let MemberForwarded (t, x:int) = RowElement(RowElementTags.MemberForwarded t, x) + let Implementation (t, x:int) = RowElement(RowElementTags.Implementation t, x) + let CustomAttributeType (t, x:int) = RowElement(RowElementTags.CustomAttributeType t, x) + let ResolutionScope (t, x:int) = RowElement(RowElementTags.ResolutionScope t, x) + + type BlobIndex = int + type StringIndex = int + + let BlobIndex (x:BlobIndex): int = x + let StringIndex (x:StringIndex): int = x + + let inline combineHash x2 acc = 37 * acc + x2 // (acc <<< 6 + acc >>> 2 + x2 + 0x9e3779b9) + + let hashRow (elems:RowElement[]) = + let mutable acc = 0 + for i in 0 .. elems.Length - 1 do + acc <- (acc <<< 1) + elems.[i].Tag + elems.[i].Val + 631 + acc + + let equalRows (elems:RowElement[]) (elems2:RowElement[]) = + if elems.Length <> elems2.Length then false else + let mutable ok = true + let n = elems.Length + let mutable i = 0 + while ok && i < n do + if elems.[i].Tag <> elems2.[i].Tag || elems.[i].Val <> elems2.[i].Val then ok <- false + i <- i + 1 + ok + + + type GenericRow = RowElement[] + + /// This is the representation of shared rows is used for most shared row types. + /// Rows ILAssemblyRef and ILMethodRef are very common and are given their own + /// representations. + [] + type SharedRow(elems: RowElement[], hashCode: int) = + member __.GenericRow = elems + override __.GetHashCode() = hashCode + override __.Equals(obj:obj) = + match obj with + | :? SharedRow as y -> equalRows elems y.GenericRow + | _ -> false + + let SharedRow(elems: RowElement[]) = new SharedRow(elems, hashRow elems) + + /// Special representation: Note, only hashing by name + let AssemblyRefRow(s1, s2, s3, s4, l1, b1, nameIdx, str2, b2) = + let hashCode = hash nameIdx + let genericRow = [| UShort s1; UShort s2; UShort s3; UShort s4; ULong l1; Blob b1; StringE nameIdx; StringE str2; Blob b2 |] + new SharedRow(genericRow, hashCode) + + /// Special representation the computes the hash more efficiently + let MemberRefRow(mrp:RowElement, nmIdx:StringIndex, blobIdx:BlobIndex) = + let hashCode = combineHash (hash blobIdx) (combineHash (hash nmIdx) (hash mrp)) + let genericRow = [| mrp; StringE nmIdx; Blob blobIdx |] + new SharedRow(genericRow, hashCode) + + /// Unshared rows are used for definitional tables where elements do not need to be made unique + /// e.g. ILMethodDef and ILTypeDef. Most tables are like this. We don't precompute a + /// hash code for these rows, and indeed the GetHashCode and Equals should not be needed. + [] + type UnsharedRow(elems: RowElement[]) = + member __.GenericRow = elems + override __.GetHashCode() = hashRow elems + override __.Equals(obj:obj) = + match obj with + | :? UnsharedRow as y -> equalRows elems y.GenericRow + | _ -> false + + + //===================================================================== + //===================================================================== + // IL --> TABLES+CODE + //===================================================================== + //===================================================================== + + // This environment keeps track of how many generic parameters are in scope. + // This lets us translate AbsIL type variable number to IL type variable numbering + type ILTypeWriterEnv = { EnclosingTyparCount: int } + let envForTypeDef (td:ILTypeDef) = { EnclosingTyparCount=td.GenericParams.Length } + let envForMethodRef env (typ:ILType) = { EnclosingTyparCount=(match typ with ILType.Array _ -> env.EnclosingTyparCount | _ -> typ.GenericArgs.Length) } + let envForNonGenericMethodRef _mref = { EnclosingTyparCount=System.Int32.MaxValue } + let envForFieldSpec (fspec:ILFieldSpec) = { EnclosingTyparCount=fspec.EnclosingType.GenericArgs.Length } + let envForOverrideSpec (ospec:ILOverridesSpec) = { EnclosingTyparCount=ospec.EnclosingType.GenericArgs.Length } + + //--------------------------------------------------------------------- + // TABLES + //--------------------------------------------------------------------- + + [] + type MetadataTable<'T> = + { name: string + dict: Dictionary<'T, int> // given a row, find its entry number + mutable rows: ResizeArray<'T> } + member x.Count = x.rows.Count + + static member New(nm, hashEq) = + { name=nm + dict = new Dictionary<_, _>(100, hashEq) + rows= new ResizeArray<_>() } + + member tbl.EntriesAsArray = + tbl.rows.ToArray() + + member tbl.Entries = + tbl.rows.ToArray() |> Array.toList + + member tbl.AddSharedEntry x = + let n = tbl.rows.Count + 1 + tbl.dict.[x] <- n + tbl.rows.Add(x) + n + + member tbl.AddUnsharedEntry x = + let n = tbl.rows.Count + 1 + tbl.rows.Add(x) + n + + member tbl.FindOrAddSharedEntry x = + let mutable res = Unchecked.defaultof<_> + let ok = tbl.dict.TryGetValue(x, &res) + if ok then res + else tbl.AddSharedEntry x + + + /// This is only used in one special place - see further below. + member tbl.SetRowsOfTable (t: _[]) = + tbl.rows <- ResizeArray(t) + let h = tbl.dict + h.Clear() + t |> Array.iteri (fun i x -> h.[x] <- (i+1)) + + member tbl.AddUniqueEntry nm geterr x = + if tbl.dict.ContainsKey x then failwith ("duplicate entry '"+geterr x+"' in "+nm+" table") + else tbl.AddSharedEntry x + + member tbl.GetTableEntry x = tbl.dict.[x] + member tbl.GetTableKeys() = tbl.dict.Keys |> Seq.toArray + + //--------------------------------------------------------------------- + // Keys into some of the tables + //--------------------------------------------------------------------- + + /// We use this key type to help find ILMethodDefs for MethodRefs + type MethodDefKey(tidx:int, garity:int, nm:string, rty:ILType, argtys:ILTypes, isStatic:bool) = + // Precompute the hash. The hash doesn't include the return type or + // argument types (only argument type count). This is very important, since + // hashing these is way too expensive + let hashCode = + hash tidx + |> combineHash (hash garity) + |> combineHash (hash nm) + |> combineHash (hash argtys.Length) + |> combineHash (hash isStatic) + member __.TypeIdx = tidx + member __.GenericArity = garity + member __.Name = nm + member __.ReturnType = rty + member __.ArgTypes = argtys + member __.IsStatic = isStatic + override __.ToString() = sprintf "%A" (tidx, garity, nm, rty, argtys, isStatic) + override __.GetHashCode() = hashCode + override __.Equals(obj:obj) = + match obj with + | :? MethodDefKey as y -> + tidx = y.TypeIdx && + garity = y.GenericArity && + nm = y.Name && + // note: these next two use structural equality on AbstractIL ILType values + rty = y.ReturnType && + argtys = y.ArgTypes && + isStatic = y.IsStatic + | _ -> false + + /// We use this key type to help find ILFieldDefs for FieldRefs + type FieldDefKey(tidx:int, nm:string, ty:ILType) = + // precompute the hash. hash doesn't include the type + let hashCode = hash tidx |> combineHash (hash nm) + member __.TypeIdx = tidx + member __.Name = nm + member __.Type = ty + override __.GetHashCode() = hashCode + override __.Equals(obj:obj) = + match obj with + | :? FieldDefKey as y -> + tidx = y.TypeIdx && + nm = y.Name && + ty = y.Type + | _ -> false + + type PropertyTableKey = PropKey of int (* type. def. idx. *) * string * ILType * ILTypes + type EventTableKey = EventKey of int (* type. def. idx. *) * string + type TypeDefTableKey = TdKey of string list * string uoption * string + + //--------------------------------------------------------------------- + // The Writer Target + //--------------------------------------------------------------------- + + [] + type MetadataTable = + | Shared of MetadataTable + | Unshared of MetadataTable + member t.FindOrAddSharedEntry(x) = match t with Shared u -> u.FindOrAddSharedEntry(x) | Unshared u -> failwithf "FindOrAddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddSharedEntry(x) = match t with | Shared u -> u.AddSharedEntry(x) | Unshared u -> failwithf "AddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddUnsharedEntry(x) = match t with Unshared u -> u.AddUnsharedEntry(x) | Shared u -> failwithf "AddUnsharedEntry: incorrect table kind, u.name = %s" u.name + member t.GenericRowsOfTable = match t with Unshared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) | Shared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) + member t.SetRowsOfSharedTable rows = match t with Shared u -> u.SetRowsOfTable (Array.map SharedRow rows) | Unshared u -> failwithf "SetRowsOfSharedTable: incorrect table kind, u.name = %s" u.name + member t.Count = match t with Unshared u -> u.Count | Shared u -> u.Count + + + [] + type cenv = + { ilg: ILGlobals + emitTailcalls: bool + deterministic: bool + showTimes: bool + desiredMetadataVersion: Version + requiredDataFixups: ResizeArray<(int32 * (int * bool))> + /// References to strings in codestreams: offset of code and a (fixup-location , string token) list) + mutable requiredStringFixups: ResizeArray<(int32 * (int * int)[])> + codeChunks: ByteBuffer + mutable nextCodeAddr: int32 + + // Collected debug information + mutable moduleGuid: byte[] + generatePdb: bool + /// Raw data, to go into the data section + data: ByteBuffer + /// Raw resource data, to go into the data section + resources: ByteBuffer + mutable entrypoint: (bool * int) option + + /// Caches + trefCache: Dictionary + + /// The following are all used to generate unique items in the output + tables: MetadataTable[] + AssemblyRefs: MetadataTable + fieldDefs: MetadataTable + methodDefIdxsByKey: MetadataTable + methodDefIdxs: Dictionary + propertyDefs: MetadataTable + eventDefs: MetadataTable + typeDefs: MetadataTable + guids: MetadataTable + blobs: MetadataTable + strings: MetadataTable + userStrings: MetadataTable + } + member cenv.GetTable (tab:ILTableName) = cenv.tables.[tab.Index] + + + member cenv.AddCode ((reqdStringFixupsOffset, requiredStringFixups), code) = + cenv.requiredStringFixups.Add ((cenv.nextCodeAddr + reqdStringFixupsOffset, requiredStringFixups)) + cenv.codeChunks.EmitBytes code + cenv.nextCodeAddr <- cenv.nextCodeAddr + code.Length + + member cenv.GetCode() = cenv.codeChunks.Close() + + + let FindOrAddSharedRow (cenv:cenv) tbl x = cenv.GetTable(tbl).FindOrAddSharedEntry x + + // Shared rows must be hash-cons'd to be made unique (no duplicates according to contents) + let AddSharedRow (cenv:cenv) tbl x = cenv.GetTable(tbl).AddSharedEntry x + + // Unshared rows correspond to definition elements (e.g. a ILTypeDef or a ILMethodDef) + let AddUnsharedRow (cenv:cenv) tbl (x:UnsharedRow) = cenv.GetTable(tbl).AddUnsharedEntry x + + let metadataSchemaVersionSupportedByCLRVersion v = 2, 0 + + let headerVersionSupportedByCLRVersion v = + // The COM20HEADER version number + // Whidbey version numbers are 2.5 + // Earlier are 2.0 + // From an email from jeffschw: "Be built with a compiler that marks the COM20HEADER with Major >=2 and Minor >= 5. The V2.0 compilers produce images with 2.5, V1.x produces images with 2.0." + 2, 5 + + let peOptionalHeaderByteByCLRVersion v = + // A flag in the PE file optional header seems to depend on CLI version + // Whidbey version numbers are 8 + // Earlier are 6 + // Tools are meant to ignore this, but the VS Profiler wants it to have the right value + 8 + + // returned by writeBinaryAndReportMappings + [] + type ILTokenMappings = + { TypeDefTokenMap: ILTypeDef list * ILTypeDef -> int32 + FieldDefTokenMap: ILTypeDef list * ILTypeDef -> ILFieldDef -> int32 + MethodDefTokenMap: ILTypeDef list * ILTypeDef -> ILMethodDef -> int32 + PropertyTokenMap: ILTypeDef list * ILTypeDef -> ILPropertyDef -> int32 + EventTokenMap: ILTypeDef list * ILTypeDef -> ILEventDef -> int32 } + + let recordRequiredDataFixup (requiredDataFixups: ResizeArray<_>) (buf: ByteBuffer) pos lab = + requiredDataFixups.Add((pos, lab)) + // Write a special value in that we check later when applying the fixup + buf.EmitInt32 0xdeaddddd + + //--------------------------------------------------------------------- + // The UserString, BlobHeap, GuidHeap tables + //--------------------------------------------------------------------- + + let GetUserStringHeapIdx cenv s = + cenv.userStrings.FindOrAddSharedEntry s + + let GetBytesAsBlobIdx cenv (bytes:byte[]) = + if bytes.Length = 0 then 0 + else cenv.blobs.FindOrAddSharedEntry bytes + + let GetStringHeapIdx cenv s = + if s = "" then 0 + else cenv.strings.FindOrAddSharedEntry s + + let GetGuidIdx cenv info = cenv.guids.FindOrAddSharedEntry info + + let GetStringHeapIdxOption cenv sopt = + match sopt with + | USome ns -> GetStringHeapIdx cenv ns + | UNone -> 0 + + + let splitNameAt (nm:string) idx = + if idx < 0 then failwith "splitNameAt: idx < 0"; + let last = nm.Length - 1 + if idx > last then failwith "splitNameAt: idx > last"; + (nm.Substring(0, idx)), + (if idx < last then nm.Substring (idx+1, last - idx) else "") + + + module String = + let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index for the character was not found in the string")) + + let index (s:string) (c:char) = + let r = s.IndexOf(c) + if r = -1 then indexNotFound() else r + + let rindex (s:string) (c:char) = + let r = s.LastIndexOf(c) + if r = -1 then indexNotFound() else r + + let contains (s:string) (c:char) = + s.IndexOf(c, 0, String.length s) <> -1 + + let splitTypeNameRightAux nm = + if String.contains nm '.' then + let idx = String.rindex nm '.' + let s1, s2 = splitNameAt nm idx + Some s1, s2 + else None, nm + + let splitTypeNameRight nm = + splitTypeNameRightAux nm + + let GetTypeNameAsElemPair cenv (n1, n2) = + StringE (GetStringHeapIdxOption cenv n1), + StringE (GetStringHeapIdx cenv n2) + + //===================================================================== + // Pass 1 - allocate indexes for types + //===================================================================== + + let addILTypeName enc (td: ILTypeDef) = enc@[(if td.IsNested then td.Name else joinILTypeName td.Namespace td.Name)] + + let rec GenTypeDefPass1 enc cenv (td:ILTypeDef) = + ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, _, n)) -> n) (TdKey (enc, td.Namespace, td.Name))) + GenTypeDefsPass1 (addILTypeName enc td) cenv td.NestedTypes.Entries + + and GenTypeDefsPass1 enc cenv tds = Array.iter (GenTypeDefPass1 enc cenv) tds + + //===================================================================== + // Pass 2 - allocate indexes for methods and fields and write rows for types + //===================================================================== + + let rec GetIdxForTypeDef cenv key = + try cenv.typeDefs.GetTableEntry key + with + :? KeyNotFoundException -> + let (TdKey (enc, nsp, n) ) = key + failwithf "One of your modules expects the type '%s' to be defined within the module being emitted. keys = %A" (String.concat "." (enc@[joinILTypeName nsp n])) (cenv.typeDefs.GetTableKeys()) + 0 + + // -------------------------------------------------------------------- + // Assembly and module references + // -------------------------------------------------------------------- + + let rec GetAssemblyRefAsRow cenv (aref:ILAssemblyRef) = + AssemblyRefRow + ((match aref.Version with UNone -> 0us | USome v -> uint16 v.Major), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Minor), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Build), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Revision), + ((match aref.PublicKey with USome (PublicKey _) -> 0x0001 | _ -> 0x0000) + ||| (if aref.Retargetable then 0x0100 else 0x0000)), + BlobIndex (match aref.PublicKey with + | UNone -> 0 + | USome (PublicKey b | PublicKeyToken b) -> GetBytesAsBlobIdx cenv b), + StringIndex (GetStringHeapIdx cenv aref.Name), + StringIndex (match aref.Locale with UNone -> 0 | USome s -> GetStringHeapIdx cenv s), + BlobIndex (match aref.Hash with UNone -> 0 | USome s -> GetBytesAsBlobIdx cenv s)) + + and GetAssemblyRefAsIdx cenv aref = + FindOrAddSharedRow cenv ILTableNames.AssemblyRef (GetAssemblyRefAsRow cenv aref) + + and GetModuleRefAsRow cenv (mref:ILModuleRef) = + SharedRow + [| StringE (GetStringHeapIdx cenv mref.Name) |] + + and GetModuleRefAsFileRow cenv (mref:ILModuleRef) = + SharedRow + [| ULong (if mref.HasMetadata then 0x0000 else 0x0001) + StringE (GetStringHeapIdx cenv mref.Name) + (match mref.Hash with UNone -> Blob 0 | USome s -> Blob (GetBytesAsBlobIdx cenv s)) |] + + and GetModuleRefAsIdx cenv mref = + FindOrAddSharedRow cenv ILTableNames.ModuleRef (GetModuleRefAsRow cenv mref) + + and GetModuleRefAsFileIdx cenv mref = + FindOrAddSharedRow cenv ILTableNames.File (GetModuleRefAsFileRow cenv mref) + + // -------------------------------------------------------------------- + // Does a ILScopeRef point to this module? + // -------------------------------------------------------------------- + + let isScopeRefLocal scoref = (scoref = ILScopeRef.Local) + let rec isTypeRefLocal (tref:ILTypeRef) = + isILTypeScopeRefLocal tref.Scope + and isILTypeScopeRefLocal (scoref:ILTypeRefScope) = + match scoref with + | ILTypeRefScope.Top t -> isScopeRefLocal t + | ILTypeRefScope.Nested tref -> isTypeRefLocal tref + let rec enclosing (scoref:ILTypeRefScope) = + match scoref with + | ILTypeRefScope.Top _ -> [] + | ILTypeRefScope.Nested tref -> enclosing tref.Scope @ [joinILTypeName tref.Namespace tref.Name] + + let isTypeLocal (typ:ILType) = typ.IsNominal && isEmpty typ.GenericArgs && isTypeRefLocal typ.TypeRef + + // -------------------------------------------------------------------- + // Scopes to Implementation elements. + // -------------------------------------------------------------------- + + let GetScopeRefAsImplementationElem cenv scoref = + match scoref with + | ILScopeRef.Local -> (ImplementationTag.AssemblyRef, 0) + | ILScopeRef.Assembly aref -> (ImplementationTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (ImplementationTag.File, GetModuleRefAsFileIdx cenv mref) + + // -------------------------------------------------------------------- + // Type references, types etc. + // -------------------------------------------------------------------- + + let rec GetTypeRefAsTypeRefRow cenv (tref:ILTypeRef) = + let nselem, nelem = GetTypeNameAsElemPair cenv (tref.Namespace, tref.Name) + let rs1, rs2 = GetResolutionScopeAsElem cenv tref.Scope + SharedRow [| ResolutionScope (rs1, rs2); nelem; nselem |] + + and GetTypeRefAsTypeRefIdx cenv tref = + let mutable res = 0 + if cenv.trefCache.TryGetValue(tref, &res) then res else + let res = FindOrAddSharedRow cenv ILTableNames.TypeRef (GetTypeRefAsTypeRefRow cenv tref) + cenv.trefCache.[tref] <- res + res + + and GetTypeDescAsTypeRefIdx cenv (enc, nsp, n) = + GetTypeRefAsTypeRefIdx cenv (ILTypeRef (enc, nsp, n)) + + and GetResolutionScopeAsElem cenv scoref = + match scoref with + | ILTypeRefScope.Top s -> + match s with + | ILScopeRef.Local -> (ResolutionScopeTag.Module, 1) + | ILScopeRef.Assembly aref -> (ResolutionScopeTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (ResolutionScopeTag.ModuleRef, GetModuleRefAsIdx cenv mref) + + | ILTypeRefScope.Nested tref -> + (ResolutionScopeTag.TypeRef, GetTypeRefAsTypeRefIdx cenv tref) + + + let emitTypeInfoAsTypeDefOrRefEncoded cenv (bb: ByteBuffer) (scoref, nsp, nm) = + if isILTypeScopeRefLocal scoref then + let idx = GetIdxForTypeDef cenv (TdKey(enclosing scoref, nsp, nm)) + bb.EmitZ32 (idx <<< 2) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeDef + else + let idx = GetTypeDescAsTypeRefIdx cenv (scoref, nsp, nm) + bb.EmitZ32 ((idx <<< 2) ||| 0x01) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeRef + + let getTypeDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = TypeDefOrRefOrSpecTag.TypeDef then ILTableNames.TypeDef + elif tag = TypeDefOrRefOrSpecTag.TypeRef then ILTableNames.TypeRef + elif tag = TypeDefOrRefOrSpecTag.TypeSpec then ILTableNames.TypeSpec + else failwith "getTypeDefOrRefAsUncodedToken" + getUncodedToken tab idx + + // REVIEW: write into an accumuating buffer + let EmitArrayShape (bb: ByteBuffer) (ILArrayShape shape) = + let sized = Array.filter (function (_, Some _) -> true | _ -> false) shape + let lobounded = Array.filter (function (Some _, _) -> true | _ -> false) shape + bb.EmitZ32 shape.Length + bb.EmitZ32 sized.Length + sized |> Array.iter (function (_, Some sz) -> bb.EmitZ32 sz | _ -> failwith "?") + bb.EmitZ32 lobounded.Length + lobounded |> Array.iter (function (Some low, _) -> bb.EmitZ32 low | _ -> failwith "?") + + let hasthisToByte hasthis = + match hasthis with + | ILThisConvention.Instance -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE + | ILThisConvention.InstanceExplicit -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT + | ILThisConvention.Static -> 0x00uy + + let callconvToByte ntypars (Callconv (hasthis, bcc)) = + hasthisToByte hasthis ||| + (if ntypars > 0 then e_IMAGE_CEE_CS_CALLCONV_GENERIC else 0x00uy) ||| + (match bcc with + | ILArgConvention.FastCall -> e_IMAGE_CEE_CS_CALLCONV_FASTCALL + | ILArgConvention.StdCall -> e_IMAGE_CEE_CS_CALLCONV_STDCALL + | ILArgConvention.ThisCall -> e_IMAGE_CEE_CS_CALLCONV_THISCALL + | ILArgConvention.CDecl -> e_IMAGE_CEE_CS_CALLCONV_CDECL + | ILArgConvention.Default -> 0x00uy + | ILArgConvention.VarArg -> e_IMAGE_CEE_CS_CALLCONV_VARARG) + + + // REVIEW: write into an accumuating buffer + let rec EmitTypeSpec cenv env (bb: ByteBuffer) (et, tspec:ILTypeSpec) = + if isEmpty tspec.GenericArgs then + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Namespace, tspec.Name) + else + bb.EmitByte et_WITH + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Namespace, tspec.Name) + bb.EmitZ32 tspec.GenericArgs.Length + EmitTypes cenv env bb tspec.GenericArgs + + and GetTypeAsTypeDefOrRef cenv env (ty:ILType) = + if isTypeLocal ty then + let tref = ty.TypeRef + (TypeDefOrRefOrSpecTag.TypeDef, GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name))) + elif ty.IsNominal && isEmpty ty.GenericArgs then + (TypeDefOrRefOrSpecTag.TypeRef, GetTypeRefAsTypeRefIdx cenv ty.TypeRef) + else + (TypeDefOrRefOrSpecTag.TypeSpec, GetTypeAsTypeSpecIdx cenv env ty) + + and GetTypeAsBytes cenv env ty = emitBytesViaBuffer (fun bb -> EmitType cenv env bb ty) + + and GetTypeOfLocalAsBytes cenv env (l: ILLocal) = + emitBytesViaBuffer (fun bb -> EmitLocalInfo cenv env bb l) + + and GetTypeAsBlobIdx cenv env (ty:ILType) = + GetBytesAsBlobIdx cenv (GetTypeAsBytes cenv env ty) + + and GetTypeAsTypeSpecRow cenv env (ty:ILType) = + SharedRow [| Blob (GetTypeAsBlobIdx cenv env ty) |] + + and GetTypeAsTypeSpecIdx cenv env ty = + FindOrAddSharedRow cenv ILTableNames.TypeSpec (GetTypeAsTypeSpecRow cenv env ty) + + + and EmitType cenv env bb ty = + match ty with + | ElementType et -> bb.EmitByte et + | ILType.Boxed tspec -> EmitTypeSpec cenv env bb (et_CLASS, tspec) + | ILType.Value tspec -> EmitTypeSpec cenv env bb (et_VALUETYPE, tspec) + | ILType.Array (shape, ty) -> + if shape = ILArrayShape.SingleDimensional then (bb.EmitByte et_SZARRAY ; EmitType cenv env bb ty) + else (bb.EmitByte et_ARRAY; EmitType cenv env bb ty; EmitArrayShape bb shape) + | ILType.Var tv -> + let cgparams = env.EnclosingTyparCount + if int32 tv < cgparams then + bb.EmitByte et_VAR + bb.EmitZ32 (int32 tv) + else + bb.EmitByte et_MVAR + bb.EmitZ32 (int32 tv - cgparams) + + | ILType.Byref typ -> + bb.EmitByte et_BYREF + EmitType cenv env bb typ + | ILType.Ptr typ -> + bb.EmitByte et_PTR + EmitType cenv env bb typ + | ILType.Void -> + bb.EmitByte et_VOID + | ILType.FunctionPointer x -> + bb.EmitByte et_FNPTR + EmitCallsig cenv env bb (x.CallingConv, x.ArgTypes, x.ReturnType, None, 0) + | ILType.Modified (req, tref, ty) -> + bb.EmitByte (if req then et_CMOD_REQD else et_CMOD_OPT) + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tref.Scope, tref.Namespace, tref.Name) + EmitType cenv env bb ty + | _ -> failwith "EmitType" + + and EmitLocalInfo cenv env (bb:ByteBuffer) (l:ILLocal) = + if l.IsPinned then + bb.EmitByte et_PINNED + EmitType cenv env bb l.Type + + and EmitCallsig cenv env (bb:ByteBuffer) (callconv, args:ILTypes, ret, varargs:ILVarArgs, genarity) = + bb.EmitByte (callconvToByte genarity callconv) + if genarity > 0 then bb.EmitZ32 genarity + bb.EmitZ32 ((args.Length + (match varargs with None -> 0 | Some l -> l.Length))) + EmitType cenv env bb ret + args |> Array.iter (EmitType cenv env bb) + match varargs with + | None -> ()// no extra arg = no sentinel + | Some tys -> + if isEmpty tys then () // no extra arg = no sentinel + else + bb.EmitByte et_SENTINEL + Array.iter (EmitType cenv env bb) tys + + and GetCallsigAsBytes cenv env x = emitBytesViaBuffer (fun bb -> EmitCallsig cenv env bb x) + + and EmitTypes cenv env bb (inst: ILTypes) = + inst |> Array.iter (EmitType cenv env bb) + + let GetTypeAsMemberRefParent cenv env ty = + match GetTypeAsTypeDefOrRef cenv env ty with + | (tag, _) when tag = TypeDefOrRefOrSpecTag.TypeDef -> printfn "GetTypeAsMemberRefParent: mspec should have been encoded as mdtMethodDef?"; MemberRefParent (MemberRefParentTag.TypeRef, 1) + | (tag, tok) when tag = TypeDefOrRefOrSpecTag.TypeRef -> MemberRefParent (MemberRefParentTag.TypeRef, tok) + | (tag, tok) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> MemberRefParent (MemberRefParentTag.TypeSpec, tok) + | _ -> failwith "GetTypeAsMemberRefParent" + + + + + // -------------------------------------------------------------------- + // Native types + // -------------------------------------------------------------------- + + let rec GetFieldInitAsBlobIdx cenv (x:ILFieldInit) = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> GetFieldInit bb x)) + + // REVIEW: write into an accumuating buffer + and GetFieldInit (bb: ByteBuffer) x = + match x with + | :? string as b -> bb.EmitBytes (Encoding.Unicode.GetBytes b) + | :? bool as b -> bb.EmitByte (if b then 0x01uy else 0x00uy) + | :? char as x -> bb.EmitUInt16 (uint16 x) + | :? int8 as x -> bb.EmitByte (byte x) + | :? int16 as x -> bb.EmitUInt16 (uint16 x) + | :? int32 as x -> bb.EmitInt32 x + | :? int64 as x -> bb.EmitInt64 x + | :? uint8 as x -> bb.EmitByte x + | :? uint16 as x -> bb.EmitUInt16 x + | :? uint32 as x -> bb.EmitInt32 (int32 x) + | :? uint64 as x -> bb.EmitInt64 (int64 x) + | :? single as x -> bb.EmitInt32 (bitsOfSingle x) + | :? double as x -> bb.EmitInt64 (bitsOfDouble x) + | _ -> bb.EmitInt32 0 + + and GetFieldInitFlags (i: ILFieldInit) = + UShort + (uint16 + (match i with + | :? string -> et_STRING + | :? bool -> et_BOOLEAN + | :? char -> et_CHAR + | :? int8 -> et_I1 + | :? int16 -> et_I2 + | :? int32 -> et_I4 + | :? int64 -> et_I8 + | :? uint8 -> et_U1 + | :? uint16 -> et_U2 + | :? uint32 -> et_U4 + | :? uint64 -> et_U8 + | :? single -> et_R4 + | :? double -> et_R8 + | _ -> et_CLASS)) + + // -------------------------------------------------------------------- + // Type definitions + // -------------------------------------------------------------------- + + let GetMemberAccessFlags access = + match access with + | ILMemberAccess.CompilerControlled -> 0x00000000 + | ILMemberAccess.Public -> 0x00000006 + | ILMemberAccess.Private -> 0x00000001 + | ILMemberAccess.Family -> 0x00000004 + | ILMemberAccess.FamilyAndAssembly -> 0x00000002 + | ILMemberAccess.FamilyOrAssembly -> 0x00000005 + | ILMemberAccess.Assembly -> 0x00000003 + + let GetTypeAccessFlags access = + match access with + | ILTypeDefAccess.Public -> 0x00000001 + | ILTypeDefAccess.Private -> 0x00000000 + | ILTypeDefAccess.Nested ILMemberAccess.Public -> 0x00000002 + | ILTypeDefAccess.Nested ILMemberAccess.Private -> 0x00000003 + | ILTypeDefAccess.Nested ILMemberAccess.Family -> 0x00000004 + | ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly -> 0x00000006 + | ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> 0x00000007 + | ILTypeDefAccess.Nested ILMemberAccess.Assembly -> 0x00000005 + | ILTypeDefAccess.Nested ILMemberAccess.CompilerControlled -> failwith "bad type acccess" + + let rec GetTypeDefAsRow cenv env _enc (td:ILTypeDef) = + let nselem, nelem = GetTypeNameAsElemPair cenv (td.Namespace, td.Name) + let flags = + if td.Name = "" then 0x00000000 + else + + int td.Attributes ||| + begin + match td.Layout with + | ILTypeDefLayout.Auto -> 0x00000000 + | ILTypeDefLayout.Sequential _ -> 0x00000008 + | ILTypeDefLayout.Explicit _ -> 0x00000010 + end ||| + begin + match td.Kind with + | ILTypeDefKind.Interface -> 0x00000020 + | _ -> 0x00000000 + end ||| +#if EMIT_SECURITY_DECLS +// @REVIEW (if rtspecialname_of_tdef td then 0x00000800 else 0x00000000) ||| + (if td.HasSecurity || not td.SecurityDecls.Entries.IsEmpty then 0x00040000 else 0x00000000) +#endif + 0x0 + + let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env td.Extends + UnsharedRow + [| ULong flags + nelem + nselem + TypeDefOrRefOrSpec (tdorTag, tdorRow) + SimpleIndex (ILTableNames.Field, cenv.fieldDefs.Count + 1) + SimpleIndex (ILTableNames.Method, cenv.methodDefIdxsByKey.Count + 1) |] + + and GetTypeOptionAsTypeDefOrRef cenv env tyOpt = + match tyOpt with + | None -> (TypeDefOrRefOrSpecTag.TypeDef, 0) + | Some ty -> (GetTypeAsTypeDefOrRef cenv env ty) + + and GetTypeDefAsPropertyMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.Property, cenv.propertyDefs.Count + 1) |] + + and GetTypeDefAsEventMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.Event, cenv.eventDefs.Count + 1) |] + + and GetKeyForFieldDef tidx (fd: ILFieldDef) = + FieldDefKey (tidx, fd.Name, fd.FieldType) + + and GenFieldDefPass2 cenv tidx fd = + ignore (cenv.fieldDefs.AddUniqueEntry "field" (fun (fdkey:FieldDefKey) -> fdkey.Name) (GetKeyForFieldDef tidx fd)) + + and GetKeyForMethodDef tidx (md: ILMethodDef) = + MethodDefKey (tidx, md.GenericParams.Length, md.Name, md.Return.Type, md.ParameterTypes, md.CallingConv.IsStatic) + + and GenMethodDefPass2 cenv tidx md = + let idx = + cenv.methodDefIdxsByKey.AddUniqueEntry + "method" + (fun (key:MethodDefKey) -> + printfn "Duplicate in method table is:" + printfn "%s" (" Type index: "+string key.TypeIdx) + printfn "%s" (" Method name: "+key.Name) + printfn "%s" (" Method arity (num generic params): "+string key.GenericArity) + key.Name + ) + (GetKeyForMethodDef tidx md) + + cenv.methodDefIdxs.[md] <- idx + + and GetKeyForPropertyDef tidx (x: ILPropertyDef) = + PropKey (tidx, x.Name, x.PropertyType, x.IndexParameterTypes) + + and GenPropertyDefPass2 cenv tidx x = + ignore (cenv.propertyDefs.AddUniqueEntry "property" (fun (PropKey (_, n, _, _)) -> n) (GetKeyForPropertyDef tidx x)) + + and GetTypeAsImplementsRow cenv env tidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenImplementsPass2 cenv env tidx ty = + AddUnsharedRow cenv ILTableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) |> ignore + + and GetKeyForEvent tidx (x: ILEventDef) = + EventKey (tidx, x.Name) + + and GenEventDefPass2 cenv tidx x = + ignore (cenv.eventDefs.AddUniqueEntry "event" (fun (EventKey(_, b)) -> b) (GetKeyForEvent tidx x)) + + and GenTypeDefPass2 pidx enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + let tidx2 = AddUnsharedRow cenv ILTableNames.TypeDef (GetTypeDefAsRow cenv env enc td) + if tidx <> tidx2 then failwith "index of typedef on second pass does not match index on first pass" + + // Add entries to auxiliary mapping tables, e.g. Nested, PropertyMap etc. + // Note Nested is organised differently to the others... + if not (isNil enc) then + AddUnsharedRow cenv ILTableNames.Nested + (UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.TypeDef, pidx) |]) |> ignore + let props = td.Properties.Entries + if not (isEmpty props) then + AddUnsharedRow cenv ILTableNames.PropertyMap (GetTypeDefAsPropertyMapRow cenv tidx) |> ignore + let events = td.Events.Entries + if not (isEmpty events) then + AddUnsharedRow cenv ILTableNames.EventMap (GetTypeDefAsEventMapRow cenv tidx) |> ignore + + // Now generate or assign index numbers for tables referenced by the maps. + // Don't yet generate contents of these tables - leave that to pass3, as + // code may need to embed these entries. + td.Implements |> Array.iter (GenImplementsPass2 cenv env tidx) + props |> Array.iter (GenPropertyDefPass2 cenv tidx) + events |> Array.iter (GenEventDefPass2 cenv tidx) + td.Fields.Entries |> Array.iter (GenFieldDefPass2 cenv tidx) + td.Methods.Entries |> Array.iter (GenMethodDefPass2 cenv tidx) + td.NestedTypes.Entries |> GenTypeDefsPass2 tidx (addILTypeName enc td) cenv + with e -> + failwith ("Error in pass2 for type "+td.Name+", error: "+e.Message) + + and GenTypeDefsPass2 pidx enc cenv tds = + Array.iter (GenTypeDefPass2 pidx enc cenv) tds + + //===================================================================== + // Pass 3 - write details of methods, fields, IL code, custom attrs etc. + //===================================================================== + + exception MethodDefNotFound + let FindMethodDefIdx cenv mdkey = + try cenv.methodDefIdxsByKey.GetTableEntry mdkey + with :? KeyNotFoundException -> + let typeNameOfIdx i = + match + (cenv.typeDefs.dict + |> Seq.fold (fun sofar kvp -> + let tkey2 = kvp.Key + let tidx2 = kvp.Value + if i = tidx2 then + if sofar = None then + Some tkey2 + else failwith "multiple type names map to index" + else sofar) None) with + | Some x -> x + | None -> raise MethodDefNotFound + let (TdKey (tenc, tnsp, tname)) = typeNameOfIdx mdkey.TypeIdx + printfn "%s" ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") + printfn "generic arity: %s " (string mdkey.GenericArity) + cenv.methodDefIdxsByKey.dict |> Seq.iter (fun (KeyValue(mdkey2, _)) -> + if mdkey2.TypeIdx = mdkey.TypeIdx && mdkey.Name = mdkey2.Name then + let (TdKey (tenc2, tnsp2, tname2)) = typeNameOfIdx mdkey2.TypeIdx + printfn "%s" ("A method in '"+(String.concat "." (tenc2@[tname2]))+"' had the right name but the wrong signature:") + printfn "%s" ("generic arity: "+string mdkey2.GenericArity) + printfn "mdkey2 = %s" (mdkey2.ToString())) + raise MethodDefNotFound + + + let rec GetMethodDefIdx cenv md = + cenv.methodDefIdxs.[md] + + and FindFieldDefIdx cenv fdkey = + try cenv.fieldDefs.GetTableEntry fdkey + with :? KeyNotFoundException -> + failwith ("The local field "+fdkey.Name+" was referenced but not declared") + 1 + + and GetFieldDefAsFieldDefIdx cenv tidx fd = + FindFieldDefIdx cenv (GetKeyForFieldDef tidx fd) + + // -------------------------------------------------------------------- + // ILMethodRef --> ILMethodDef. + // + // Only successfuly converts ILMethodRef's referring to + // methods in the module being emitted. + // -------------------------------------------------------------------- + + let GetMethodRefAsMethodDefIdx cenv (mref:ILMethodRef) = + let tref = mref.EnclosingTypeRef + try + if not (isTypeRefLocal tref) then + failwithf "method referred to by method impl, event or property is not in a type defined in this module, method ref is %A" mref + let tidx = GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name)) + let mdkey = MethodDefKey (tidx, mref.GenericArity, mref.Name, mref.ReturnType, mref.ArgTypes, mref.CallingConv.IsStatic) + FindMethodDefIdx cenv mdkey + with e -> + failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" (mref.Name, tref.Name) e.Message + + let rec MethodRefInfoAsMemberRefRow cenv env fenv (nm, typ, callconv, args, ret, varargs, genarity) = + MemberRefRow(GetTypeAsMemberRefParent cenv env typ, + GetStringHeapIdx cenv nm, + GetMethodRefInfoAsBlobIdx cenv fenv (callconv, args, ret, varargs, genarity)) + + and GetMethodRefInfoAsBlobIdx cenv env info = + GetBytesAsBlobIdx cenv (GetCallsigAsBytes cenv env info) + + let GetMethodRefInfoAsMemberRefIdx cenv env ((_, typ, _, _, _, _, _) as minfo) = + let fenv = envForMethodRef env typ + FindOrAddSharedRow cenv ILTableNames.MemberRef (MethodRefInfoAsMemberRefRow cenv env fenv minfo) + + let GetMethodRefInfoAsMethodRefOrDef isAlwaysMethodDef cenv env ((nm, typ:ILType, cc, args, ret, varargs, genarity) as minfo) = + if Option.isNone varargs && (isAlwaysMethodDef || isTypeLocal typ) then + if not typ.IsNominal then failwith "GetMethodRefInfoAsMethodRefOrDef: unexpected local tref-typ" + try (MethodDefOrRefTag.MethodDef, GetMethodRefAsMethodDefIdx cenv (ILMethodRef (typ.TypeRef, cc, genarity, nm, args, ret))) + with MethodDefNotFound -> (MethodDefOrRefTag.MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + else (MethodDefOrRefTag.MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + + + // -------------------------------------------------------------------- + // ILMethodSpec --> ILMethodRef/ILMethodDef/ILMethodSpec + // -------------------------------------------------------------------- + + let rec GetMethodSpecInfoAsMethodSpecIdx cenv env (nm, typ, cc, args, ret, varargs, minst:ILGenericArgs) = + let mdorTag, mdorRow = GetMethodRefInfoAsMethodRefOrDef false cenv env (nm, typ, cc, args, ret, varargs, minst.Length) + let blob = + emitBytesViaBuffer (fun bb -> + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_GENERICINST + bb.EmitZ32 minst.Length + minst |> Array.iter (EmitType cenv env bb)) + FindOrAddSharedRow cenv ILTableNames.MethodSpec + (SharedRow + [| MethodDefOrRef (mdorTag, mdorRow) + Blob (GetBytesAsBlobIdx cenv blob) |]) + + and GetMethodDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = MethodDefOrRefTag.MethodDef then ILTableNames.Method + elif tag = MethodDefOrRefTag.MemberRef then ILTableNames.MemberRef + else failwith "GetMethodDefOrRefAsUncodedToken" + getUncodedToken tab idx + + and GetMethodSpecInfoAsUncodedToken cenv env ((_, _, _, _, _, _, minst:ILGenericArgs) as minfo) = + if minst.Length > 0 then + getUncodedToken ILTableNames.MethodSpec (GetMethodSpecInfoAsMethodSpecIdx cenv env minfo) + else + GetMethodDefOrRefAsUncodedToken (GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo minfo)) + + and GetMethodSpecAsUncodedToken cenv env mspec = + GetMethodSpecInfoAsUncodedToken cenv env (InfoOfMethodSpec mspec) + + and GetMethodRefInfoOfMethodSpecInfo (nm, typ, cc, args, ret, varargs, minst:ILGenericArgs) = + (nm, typ, cc, args, ret, varargs, minst.Length) + + and GetMethodSpecAsMethodDefOrRef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + + and GetMethodSpecAsMethodDef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef true cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + + and InfoOfMethodSpec (mspec:ILMethodSpec, varargs) = + (mspec.Name, + mspec.EnclosingType, + mspec.CallingConv, + mspec.MethodRef.ArgTypes, + mspec.FormalReturnType, + varargs, + mspec.GenericArgs) + + // -------------------------------------------------------------------- + // method_in_parent --> ILMethodRef/ILMethodDef + // + // Used for MethodImpls. + // -------------------------------------------------------------------- + + let rec GetOverridesSpecAsMemberRefIdx cenv env ospec = + let fenv = envForOverrideSpec ospec + let row = MethodRefInfoAsMemberRefRow cenv env fenv (ospec.MethodRef.Name, ospec.EnclosingType, ospec.MethodRef.CallingConv, ospec.MethodRef.ArgTypes, ospec.MethodRef.ReturnType, None, ospec.MethodRef.GenericArity) + FindOrAddSharedRow cenv ILTableNames.MemberRef row + + and GetOverridesSpecAsMethodDefOrRef cenv env (ospec:ILOverridesSpec) = + let typ = ospec.EnclosingType + if isTypeLocal typ then + if not typ.IsNominal then failwith "GetOverridesSpecAsMethodDefOrRef: unexpected local tref-typ" + try (MethodDefOrRefTag.MethodDef, GetMethodRefAsMethodDefIdx cenv ospec.MethodRef) + with MethodDefNotFound -> (MethodDefOrRefTag.MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + else + (MethodDefOrRefTag.MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + + // -------------------------------------------------------------------- + // ILMethodRef --> ILMethodRef/ILMethodDef + // + // Used for Custom Attrs. + // -------------------------------------------------------------------- + + let rec GetMethodRefAsMemberRefIdx cenv env fenv (mref:ILMethodRef) = + let row = MethodRefInfoAsMemberRefRow cenv env fenv (mref.Name, ILType.Boxed (ILTypeSpec (mref.EnclosingTypeRef, [| |])), mref.CallingConv, mref.ArgTypes, mref.ReturnType, None, mref.GenericArity) + FindOrAddSharedRow cenv ILTableNames.MemberRef row + + and GetMethodRefAsCustomAttribType cenv (mref:ILMethodRef) = + let fenv = envForNonGenericMethodRef mref + let tref = mref.EnclosingTypeRef + if isTypeRefLocal tref then + try (CustomAttributeTypeTag.MethodDef, GetMethodRefAsMethodDefIdx cenv mref) + with MethodDefNotFound -> (CustomAttributeTypeTag.MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + else + (CustomAttributeTypeTag.MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + + // -------------------------------------------------------------------- + // ILCustomAttrs --> CustomAttribute rows + // -------------------------------------------------------------------- + + let rec GetCustomAttrDataAsBlobIdx cenv (data:byte[]) = + if data.Length = 0 then 0 else GetBytesAsBlobIdx cenv data + + and GetCustomAttrRow cenv hca attr = + let cat = GetMethodRefAsCustomAttribType cenv attr.Method.MethodRef + for element in attr.Elements do + match element with + | :? ILType as ty when ty.IsNominal -> GetTypeRefAsTypeRefIdx cenv ty.TypeRef |> ignore + | _ -> () + + UnsharedRow + [| HasCustomAttribute (fst hca, snd hca) + CustomAttributeType (fst cat, snd cat) + Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data) + |] + + and GenCustomAttrPass3Or4 cenv hca attr = + AddUnsharedRow cenv ILTableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore + + and GenCustomAttrsPass3Or4 cenv hca (attrs: ILCustomAttrs) = + attrs.Entries |> Array.iter (GenCustomAttrPass3Or4 cenv hca) + + // -------------------------------------------------------------------- + // ILPermissionSet --> DeclSecurity rows + // -------------------------------------------------------------------- *) + +#if EMIT_SECURITY_DECLS + let rec GetSecurityDeclRow cenv hds (PermissionSet (action, s)) = + UnsharedRow + [| UShort (uint16 (List.assoc action (Lazy.force ILSecurityActionMap))) + HasDeclSecurity (fst hds, snd hds) + Blob (GetBytesAsBlobIdx cenv s) |] + + and GenSecurityDeclPass3 cenv hds attr = + AddUnsharedRow cenv ILTableNames.Permission (GetSecurityDeclRow cenv hds attr) |> ignore + + and GenSecurityDeclsPass3 cenv hds attrs = + List.iter (GenSecurityDeclPass3 cenv hds) attrs +#endif + + // -------------------------------------------------------------------- + // ILFieldSpec --> FieldRef or ILFieldDef row + // -------------------------------------------------------------------- + + let rec GetFieldSpecAsMemberRefRow cenv env fenv (fspec:ILFieldSpec) = + MemberRefRow (GetTypeAsMemberRefParent cenv env fspec.EnclosingType, + GetStringHeapIdx cenv fspec.Name, + GetFieldSpecSigAsBlobIdx cenv fenv fspec) + + and GetFieldSpecAsMemberRefIdx cenv env fspec = + let fenv = envForFieldSpec fspec + FindOrAddSharedRow cenv ILTableNames.MemberRef (GetFieldSpecAsMemberRefRow cenv env fenv fspec) + + // REVIEW: write into an accumuating buffer + and EmitFieldSpecSig cenv env (bb: ByteBuffer) (fspec:ILFieldSpec) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb fspec.FormalType + + and GetFieldSpecSigAsBytes cenv env x = + emitBytesViaBuffer (fun bb -> EmitFieldSpecSig cenv env bb x) + + and GetFieldSpecSigAsBlobIdx cenv env x = + GetBytesAsBlobIdx cenv (GetFieldSpecSigAsBytes cenv env x) + + and GetFieldSpecAsFieldDefOrRef cenv env (fspec:ILFieldSpec) = + let typ = fspec.EnclosingType + if isTypeLocal typ then + if not typ.IsNominal then failwith "GetFieldSpecAsFieldDefOrRef: unexpected local tref-typ" + let tref = typ.TypeRef + let tidx = GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name)) + let fdkey = FieldDefKey (tidx, fspec.Name, fspec.FormalType) + (true, FindFieldDefIdx cenv fdkey) + else + (false, GetFieldSpecAsMemberRefIdx cenv env fspec) + + and GetFieldDefOrRefAsUncodedToken (tag, idx) = + let tab = if tag then ILTableNames.Field else ILTableNames.MemberRef + getUncodedToken tab idx + + // -------------------------------------------------------------------- + // callsig --> StandAloneSig + // -------------------------------------------------------------------- + + let GetCallsigAsBlobIdx cenv env (callsig:ILCallingSignature, varargs) = + GetBytesAsBlobIdx cenv + (GetCallsigAsBytes cenv env (callsig.CallingConv, + callsig.ArgTypes, + callsig.ReturnType, varargs, 0)) + + let GetCallsigAsStandAloneSigRow cenv env x = + SharedRow [| Blob (GetCallsigAsBlobIdx cenv env x) |] + + let GetCallsigAsStandAloneSigIdx cenv env info = + FindOrAddSharedRow cenv ILTableNames.StandAloneSig (GetCallsigAsStandAloneSigRow cenv env info) + + // -------------------------------------------------------------------- + // local signatures --> BlobHeap idx + // -------------------------------------------------------------------- + + let EmitLocalSig cenv env (bb: ByteBuffer) (locals: ILLocals) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG + bb.EmitZ32 locals.Length + locals |> Array.iter (EmitLocalInfo cenv env bb) + + let GetLocalSigAsBlobHeapIdx cenv env locals = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> EmitLocalSig cenv env bb locals)) + + let GetLocalSigAsStandAloneSigIdx cenv env locals = + SharedRow [| Blob (GetLocalSigAsBlobHeapIdx cenv env locals) |] + + + + type ExceptionClauseKind = + | FinallyClause + | FaultClause + | TypeFilterClause of int32 + | FilterClause of int + + type ExceptionClauseSpec = (int * int * int * int * ExceptionClauseKind) + + type CodeBuffer = + + // -------------------------------------------------------------------- + // Buffer to write results of emitting code into. Also record: + // - branch sources (where fixups will occur) + // - possible branch destinations + // - locations of embedded handles into the string table + // - the exception table + // -------------------------------------------------------------------- + { code: ByteBuffer + /// (instruction; optional short form); start of instr in code buffer; code loc for the end of the instruction the fixup resides in ; where is the destination of the fixup + mutable reqdBrFixups: ResizeArray<((int * int option) * int * ILCodeLabel list)> + availBrFixups: Dictionary + /// code loc to fixup in code buffer + mutable reqdStringFixupsInMethod: ResizeArray<(int * int)> + /// data for exception handling clauses + mutable seh: ResizeArray +#if DEBUG_INFO + seqpoints: ResizeArray +#endif + } + + static member Create _nm = + { seh = ResizeArray() + code= ByteBuffer.Create 200 + reqdBrFixups= ResizeArray() + reqdStringFixupsInMethod=ResizeArray() + availBrFixups = Dictionary<_, _>(10, HashIdentity.Structural) +#if DEBUG_INFO + seqpoints = new ResizeArray<_>(10) +#endif + } + + member codebuf.EmitExceptionClause seh = codebuf.seh.Add(seh) + +#if DEBUG_INFO + member codebuf.EmitSeqPoint cenv (m:ILDebugPoint) = () + if cenv.generatePdb then + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + codebuf.seqpoints.Add + { Document=doc + Offset= codebuf.code.Position + Line=m.Line + Column=m.Column + EndLine=m.EndLine + EndColumn=m.EndColumn } +#endif + + member codebuf.EmitByte x = codebuf.code.EmitIntAsByte x + member codebuf.EmitUInt16 x = codebuf.code.EmitUInt16 x + member codebuf.EmitInt32 x = codebuf.code.EmitInt32 x + member codebuf.EmitInt64 x = codebuf.code.EmitInt64 x + + member codebuf.EmitUncodedToken u = codebuf.EmitInt32 u + + member codebuf.RecordReqdStringFixup stringidx = + codebuf.reqdStringFixupsInMethod.Add((codebuf.code.Position, stringidx)) + // Write a special value in that we check later when applying the fixup + codebuf.EmitInt32 0xdeadbeef + + member codebuf.RecordReqdBrFixups i tgs = + codebuf.reqdBrFixups.Add ((i, codebuf.code.Position, tgs)) + // Write a special value in that we check later when applying the fixup + // Value is 0x11 {deadbbbb}* where 11 is for the instruction and deadbbbb is for each target + codebuf.EmitByte 0x11 // for the instruction + (if fst i = i_switch then + codebuf.EmitInt32 tgs.Length) + List.iter (fun _ -> codebuf.EmitInt32 0xdeadbbbb) tgs + + member codebuf.RecordReqdBrFixup i tg = codebuf.RecordReqdBrFixups i [tg] + member codebuf.RecordAvailBrFixup tg = + codebuf.availBrFixups.[tg] <- codebuf.code.Position + + module Codebuf = + // -------------------------------------------------------------------- + // Applying branch fixups. Use short versions of instructions + // wherever possible. Sadly we can only determine if we can use a short + // version after we've layed out the code for all other instructions. + // This in turn means that using a short version may change + // the various offsets into the code. + // -------------------------------------------------------------------- + + let binaryChop p (arr: 'T[]) = + let rec go n m = + if n > m then raise (KeyNotFoundException("binary chop did not find element")) + else + let i = (n+m)/2 + let c = p arr.[i] + if c = 0 then i elif c < 0 then go n (i-1) else go (i+1) m + go 0 (Array.length arr) + + let applyBrFixups (origCode :byte[]) origExnClauses origReqdStringFixups (origAvailBrFixups: Dictionary) origReqdBrFixups = + let orderedOrigReqdBrFixups = origReqdBrFixups |> Array.sortBy (fun (_, fixuploc, _) -> fixuploc) + + let newCode = ByteBuffer.Create origCode.Length + + // Copy over all the code, working out whether the branches will be short + // or long and adjusting the branch destinations. Record an adjust function to adjust all the other + // gumpf that refers to fixed offsets in the code stream. + let newCode, newReqdBrFixups, adjuster = + let remainingReqdFixups = ref (Array.toList orderedOrigReqdBrFixups) + let origWhere = ref 0 + let newWhere = ref 0 + let doneLast = ref false + let newReqdBrFixups = ref [] + + let adjustments = ref [] + + while (not (isNil !remainingReqdFixups) || not !doneLast) do + let doingLast = isNil !remainingReqdFixups + let origStartOfNoBranchBlock = !origWhere + let newStartOfNoBranchBlock = !newWhere + + let origEndOfNoBranchBlock = + if doingLast then origCode.Length + else + let (_, origStartOfInstr, _) = List.head !remainingReqdFixups + origStartOfInstr + + // Copy over a chunk of non-branching code + let nobranch_len = origEndOfNoBranchBlock - origStartOfNoBranchBlock + newCode.EmitBytes origCode.[origStartOfNoBranchBlock..origStartOfNoBranchBlock+nobranch_len-1] + + // Record how to adjust addresses in this range, including the branch instruction + // we write below, or the end of the method if we're doing the last bblock + adjustments := (origStartOfNoBranchBlock, origEndOfNoBranchBlock, newStartOfNoBranchBlock) :: !adjustments + + // Increment locations to the branch instruction we're really interested in + origWhere := origEndOfNoBranchBlock + newWhere := !newWhere + nobranch_len + + // Now do the branch instruction. Decide whether the fixup will be short or long in the new code + if doingLast then + doneLast := true + else + let (i, origStartOfInstr, tgs:ILCodeLabel list) = List.head !remainingReqdFixups + remainingReqdFixups := List.tail !remainingReqdFixups + if origCode.[origStartOfInstr] <> 0x11uy then failwith "br fixup sanity check failed (1)" + let i_length = if fst i = i_switch then 5 else 1 + origWhere := !origWhere + i_length + + let origEndOfInstr = origStartOfInstr + i_length + 4 * tgs.Length + let newEndOfInstrIfSmall = !newWhere + i_length + 1 + let newEndOfInstrIfBig = !newWhere + i_length + 4 * tgs.Length + + let short = + match i, tgs with + | (_, Some i_short), [tg] + when + begin + // Use the original offsets to compute if the branch is small or large. This is + // a safe approximation because code only gets smaller. + if not (origAvailBrFixups.ContainsKey tg) then + printfn "%s" ("branch target " + formatCodeLabel tg + " not found in code") + let origDest = + if origAvailBrFixups.ContainsKey tg then origAvailBrFixups.[tg] + else 666666 + let origRelOffset = origDest - origEndOfInstr + -128 <= origRelOffset && origRelOffset <= 127 + end + -> + newCode.EmitIntAsByte i_short + true + | (i_long, _), _ -> + newCode.EmitIntAsByte i_long + (if i_long = i_switch then + newCode.EmitInt32 tgs.Length) + false + + newWhere := !newWhere + i_length + if !newWhere <> newCode.Position then printfn "mismatch between newWhere and newCode" + + tgs |> List.iter (fun tg -> + let origFixupLoc = !origWhere + checkFixup32 origCode origFixupLoc 0xdeadbbbb + + if short then + newReqdBrFixups := (!newWhere, newEndOfInstrIfSmall, tg, true) :: !newReqdBrFixups + newCode.EmitIntAsByte 0x98 (* sanity check *) + newWhere := !newWhere + 1 + else + newReqdBrFixups := (!newWhere, newEndOfInstrIfBig, tg, false) :: !newReqdBrFixups + newCode.EmitInt32 0xf00dd00f (* sanity check *) + newWhere := !newWhere + 4 + if !newWhere <> newCode.Position then printfn "mismatch between newWhere and newCode" + origWhere := !origWhere + 4) + + if !origWhere <> origEndOfInstr then printfn "mismatch between origWhere and origEndOfInstr" + + let adjuster = + let arr = Array.ofList (List.rev !adjustments) + fun addr -> + let i = + try binaryChop (fun (a1, a2, _) -> if addr < a1 then -1 elif addr > a2 then 1 else 0) arr + with + :? KeyNotFoundException -> + failwith ("adjuster: address "+string addr+" is out of range") + let (origStartOfNoBranchBlock, _, newStartOfNoBranchBlock) = arr.[i] + addr - (origStartOfNoBranchBlock - newStartOfNoBranchBlock) + + newCode.Close(), + List.toArray !newReqdBrFixups, + adjuster + + // Now adjust everything + let newAvailBrFixups = + let tab = Dictionary<_, _>(10, HashIdentity.Structural) + for (KeyValue(tglab, origBrDest)) in origAvailBrFixups do + tab.[tglab] <- adjuster origBrDest + tab + let newReqdStringFixups = Array.map (fun (origFixupLoc, stok) -> adjuster origFixupLoc, stok) origReqdStringFixups +#if EMIT_DEBUG_INFO + let newSeqPoints = Array.map (fun (sp:PdbDebugPoint) -> {sp with Offset=adjuster sp.Offset}) origSeqPoints +#endif + let newExnClauses = + origExnClauses |> Array.map (fun (st1, sz1, st2, sz2, kind) -> + (adjuster st1, (adjuster (st1 + sz1) - adjuster st1), + adjuster st2, (adjuster (st2 + sz2) - adjuster st2), + (match kind with + | FinallyClause | FaultClause | TypeFilterClause _ -> kind + | FilterClause n -> FilterClause (adjuster n)))) + +#if EMIT_DEBUG_INFO + let newScopes = + let rec remap scope = + {scope with StartOffset = adjuster scope.StartOffset + EndOffset = adjuster scope.EndOffset + Children = Array.map remap scope.Children } + Array.map remap origScopes +#endif + + // Now apply the adjusted fixups in the new code + newReqdBrFixups |> Array.iter (fun (newFixupLoc, endOfInstr, tg, small) -> + if not (newAvailBrFixups.ContainsKey tg) then + failwith ("target "+formatCodeLabel tg+" not found in new fixups") + try + let n = newAvailBrFixups.[tg] + let relOffset = (n - endOfInstr) + if small then + if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixupsanity check failed" + newCode.[newFixupLoc] <- b0 relOffset + else + checkFixup32 newCode newFixupLoc 0xf00dd00fl + applyFixup32 newCode newFixupLoc relOffset + with :? KeyNotFoundException -> ()) + + newCode, newReqdStringFixups, newExnClauses + + + // -------------------------------------------------------------------- + // Structured residue of emitting instructions: SEH exception handling + // and scopes for local variables. + // -------------------------------------------------------------------- + + // Emitting instructions generates a tree of seh specifications + // We then emit the exception handling specs separately. + // nb. ECMA spec says the SEH blocks must be returned inside-out + type SEHTree = + | Node of ExceptionClauseSpec option * SEHTree[] + + + // -------------------------------------------------------------------- + // Table of encodings for instructions without arguments, also indexes + // for all instructions. + // -------------------------------------------------------------------- + + let encodingsForNoArgInstrs = Dictionary<_, _>(300, HashIdentity.Structural) + let _ = + List.iter + (fun (x, mk) -> encodingsForNoArgInstrs.[mk] <- x) + (noArgInstrs.Force()) + let encodingsOfNoArgInstr si = encodingsForNoArgInstrs.[si] + + // -------------------------------------------------------------------- + // Emit instructions + // -------------------------------------------------------------------- + + /// Emit the code for an instruction + let emitInstrCode (codebuf: CodeBuffer) i = + if i > 0xFF then + assert (i >>> 8 = 0xFE) + codebuf.EmitByte ((i >>> 8) &&& 0xFF) + codebuf.EmitByte (i &&& 0xFF) + else + codebuf.EmitByte i + + let emitTypeInstr cenv codebuf env i ty = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + + let emitMethodSpecInfoInstr cenv codebuf env i mspecinfo = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecInfoAsUncodedToken cenv env mspecinfo) + + let emitMethodSpecInstr cenv codebuf env i mspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecAsUncodedToken cenv env mspec) + + let emitFieldSpecInstr cenv codebuf env i fspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetFieldDefOrRefAsUncodedToken (GetFieldSpecAsFieldDefOrRef cenv env fspec)) + + let emitShortUInt16Instr codebuf (i_short, i) x = + let n = int32 x + if n <= 255 then + emitInstrCode codebuf i_short + codebuf.EmitByte n + else + emitInstrCode codebuf i + codebuf.EmitUInt16 x + + let emitShortInt32Instr codebuf (i_short, i) x = + if x >= (-128) && x <= 127 then + emitInstrCode codebuf i_short + codebuf.EmitByte (if x < 0x0 then x + 256 else x) + else + emitInstrCode codebuf i + codebuf.EmitInt32 x + + let emitTailness (cenv: cenv) codebuf tl = + if tl = Tailcall && cenv.emitTailcalls then emitInstrCode codebuf i_tail + + //let emitAfterTailcall codebuf tl = + // if tl = Tailcall then emitInstrCode codebuf i_ret + + let emitVolatility codebuf tl = + if tl = Volatile then emitInstrCode codebuf i_volatile + + let emitConstrained cenv codebuf env ty = + emitInstrCode codebuf i_constrained + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + + let emitAlignment codebuf tl = + match tl with + | Aligned -> () + | Unaligned1 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x1 + | Unaligned2 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x2 + | Unaligned4 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x4 + + let rec emitInstr cenv codebuf env instr = + match instr with + | si when isNoArgInstr si -> + emitInstrCode codebuf (encodingsOfNoArgInstr si) + | I_brcmp (cmp, tg1) -> + codebuf.RecordReqdBrFixup (ILCmpInstrMap.Value.[cmp], Some ILCmpInstrRevMap.Value.[cmp]) tg1 + | I_br tg -> codebuf.RecordReqdBrFixup (i_br, Some i_br_s) tg +#if EMIT_DEBUG_INFO + | I_seqpoint s -> codebuf.EmitSeqPoint cenv s +#endif + | I_leave tg -> codebuf.RecordReqdBrFixup (i_leave, Some i_leave_s) tg + | I_call (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_call (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callvirt (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callconstraint (tl, ty, mspec, varargs) -> + emitTailness cenv codebuf tl + emitConstrained cenv codebuf env ty + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_newobj (mspec, varargs) -> + emitMethodSpecInstr cenv codebuf env i_newobj (mspec, varargs) + | I_ldftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldftn (mspec, None) + | I_ldvirtftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldvirtftn (mspec, None) + + | I_calli (tl, callsig, varargs) -> + emitTailness cenv codebuf tl + emitInstrCode codebuf i_calli + codebuf.EmitUncodedToken (getUncodedToken ILTableNames.StandAloneSig (GetCallsigAsStandAloneSigIdx cenv env (callsig, varargs))) + //emitAfterTailcall codebuf tl + + | I_ldarg x -> emitShortUInt16Instr codebuf (i_ldarg_s, i_ldarg) (uint16 x) + | I_starg x -> emitShortUInt16Instr codebuf (i_starg_s, i_starg) (uint16 x) + | I_ldarga x -> emitShortUInt16Instr codebuf (i_ldarga_s, i_ldarga) (uint16 x) + | I_ldloc x -> emitShortUInt16Instr codebuf (i_ldloc_s, i_ldloc) (uint16 x) + | I_stloc x -> emitShortUInt16Instr codebuf (i_stloc_s, i_stloc) (uint16 x) + | I_ldloca x -> emitShortUInt16Instr codebuf (i_ldloca_s, i_ldloca) (uint16 x) + + | I_cpblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_cpblk + | I_initblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_initblk + + | (I_ldc (DT_I4, ILConst.I4 x)) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) x + | (I_ldc (DT_I8, ILConst.I8 x)) -> + emitInstrCode codebuf i_ldc_i8 + codebuf.EmitInt64 x + | (I_ldc (_, ILConst.R4 x)) -> + emitInstrCode codebuf i_ldc_r4 + codebuf.EmitInt32 (bitsOfSingle x) + | (I_ldc (_, ILConst.R8 x)) -> + emitInstrCode codebuf i_ldc_r8 + codebuf.EmitInt64 (bitsOfDouble x) + + | I_ldind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldind_i + | DT_I1 -> i_ldind_i1 + | DT_I2 -> i_ldind_i2 + | DT_I4 -> i_ldind_i4 + | DT_U1 -> i_ldind_u1 + | DT_U2 -> i_ldind_u2 + | DT_U4 -> i_ldind_u4 + | DT_I8 -> i_ldind_i8 + | DT_R4 -> i_ldind_r4 + | DT_R8 -> i_ldind_r8 + | DT_REF -> i_ldind_ref + | _ -> failwith "ldind") + + | I_stelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I | DT_U -> i_stelem_i + | DT_U1 | DT_I1 -> i_stelem_i1 + | DT_I2 | DT_U2 -> i_stelem_i2 + | DT_I4 | DT_U4 -> i_stelem_i4 + | DT_I8 | DT_U8 -> i_stelem_i8 + | DT_R4 -> i_stelem_r4 + | DT_R8 -> i_stelem_r8 + | DT_REF -> i_stelem_ref + | _ -> failwith "stelem") + + | I_ldelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldelem_i + | DT_I1 -> i_ldelem_i1 + | DT_I2 -> i_ldelem_i2 + | DT_I4 -> i_ldelem_i4 + | DT_I8 -> i_ldelem_i8 + | DT_U1 -> i_ldelem_u1 + | DT_U2 -> i_ldelem_u2 + | DT_U4 -> i_ldelem_u4 + | DT_R4 -> i_ldelem_r4 + | DT_R8 -> i_ldelem_r8 + | DT_REF -> i_ldelem_ref + | _ -> failwith "ldelem") + + | I_stind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_U | DT_I -> i_stind_i + | DT_U1 | DT_I1 -> i_stind_i1 + | DT_U2 | DT_I2 -> i_stind_i2 + | DT_U4 | DT_I4 -> i_stind_i4 + | DT_U8 | DT_I8 -> i_stind_i8 + | DT_R4 -> i_stind_r4 + | DT_R8 -> i_stind_r8 + | DT_REF -> i_stind_ref + | _ -> failwith "stelem") + + | I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs + + | I_ldfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldfld fspec + | I_ldflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldflda fspec + | I_ldsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldsfld fspec + | I_ldsflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldsflda fspec + | I_stfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stfld fspec + | I_stsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stsfld fspec + + | I_ldtoken tok -> + emitInstrCode codebuf i_ldtoken + codebuf.EmitUncodedToken + (match tok with + | ILToken.ILType typ -> + match GetTypeAsTypeDefOrRef cenv env typ with + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeDef -> getUncodedToken ILTableNames.TypeDef idx + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeRef -> getUncodedToken ILTableNames.TypeRef idx + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> getUncodedToken ILTableNames.TypeSpec idx + | _ -> failwith "?" + | ILToken.ILMethod mspec -> + match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with + | (tag, idx) when tag = MethodDefOrRefTag.MethodDef -> getUncodedToken ILTableNames.Method idx + | (tag, idx) when tag = MethodDefOrRefTag.MemberRef -> getUncodedToken ILTableNames.MemberRef idx + | _ -> failwith "?" + + | ILToken.ILField fspec -> + match GetFieldSpecAsFieldDefOrRef cenv env fspec with + | (true, idx) -> getUncodedToken ILTableNames.Field idx + | (false, idx) -> getUncodedToken ILTableNames.MemberRef idx) + | I_ldstr s -> + emitInstrCode codebuf i_ldstr + codebuf.RecordReqdStringFixup (GetUserStringHeapIdx cenv s) + + | I_box ty -> emitTypeInstr cenv codebuf env i_box ty + | I_unbox ty -> emitTypeInstr cenv codebuf env i_unbox ty + | I_unbox_any ty -> emitTypeInstr cenv codebuf env i_unbox_any ty + + | I_newarr (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_newarr ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_newobj (".ctor", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, [| |]) + + | I_stelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_stelem_any ty + else + let args = Array.init (shape.Rank+1) (fun i -> if i < shape.Rank then cenv.ilg.typ_Int32 else ty) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Set", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, [| |]) + + | I_ldelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelem_any ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Get", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ty, None, [| |]) + + | I_ldelema (ro, shape, ty) -> + if (ro = ReadonlyAddress) then + emitInstrCode codebuf i_readonly + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelema ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Address", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Byref ty, None, [| |]) + + | I_castclass ty -> emitTypeInstr cenv codebuf env i_castclass ty + | I_isinst ty -> emitTypeInstr cenv codebuf env i_isinst ty + | I_refanyval ty -> emitTypeInstr cenv codebuf env i_refanyval ty + | I_mkrefany ty -> emitTypeInstr cenv codebuf env i_mkrefany ty + | I_initobj ty -> emitTypeInstr cenv codebuf env i_initobj ty + | I_ldobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_ldobj ty + | I_stobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_stobj ty + | I_cpobj ty -> emitTypeInstr cenv codebuf env i_cpobj ty + | I_sizeof ty -> emitTypeInstr cenv codebuf env i_sizeof ty + | EI_ldlen_multi (_, m) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) m + let mspec = mkILMethSpecInTyRaw(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [|cenv.ilg.typ_Int32|], cenv.ilg.typ_Int32, [| |]) + emitInstr cenv codebuf env (mkNormalCall mspec) + + | _ -> failwith "an IL instruction cannot be emitted" + + + // Used to put local debug scopes and exception handlers into a tree form + let rangeInsideRange (start_pc1, end_pc1) (start_pc2, end_pc2) = + (start_pc1:int) >= start_pc2 && start_pc1 < end_pc2 && + (end_pc1:int) > start_pc2 && end_pc1 <= end_pc2 + + let lranges_of_clause cl = + match cl with + | ILExceptionClause.Finally r1 -> [r1] + | ILExceptionClause.Fault r1 -> [r1] + | ILExceptionClause.FilterCatch (r1, r2) -> [r1;r2] + | ILExceptionClause.TypeCatch (_ty, r1) -> [r1] + + + let labelsToRange (lab2pc: Dictionary) p = let (l1, l2) = p in lab2pc.[l1], lab2pc.[l2] + + let labelRangeInsideLabelRange lab2pc ls1 ls2 = + rangeInsideRange (labelsToRange lab2pc ls1) (labelsToRange lab2pc ls2) + +// This file still gets used when targeting FSharp.Core 3.1.0.0, e.g. in FSharp.Data +#if !ABOVE_FSCORE_4_0_0_0 + let mapFold f acc (array: _[]) = + match array.Length with + | 0 -> [| |], acc + | len -> + let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(f) + let mutable acc = acc + let res = Array.zeroCreate len + for i = 0 to array.Length-1 do + let h', s' = f.Invoke(acc, array.[i]) + res.[i] <- h' + acc <- s' + res, acc +#endif + let findRoots contains vs = + // For each item, either make it a root or make it a child of an existing root + let addToRoot roots x = + // Look to see if 'x' is inside one of the roots + let roots, found = + (false, roots) ||> mapFold (fun found (r, children) -> + if found then ((r, children), true) + elif contains x r then ((r, Array.append [| x |] children), true) + else ((r, children), false)) + + if found then roots + else + // Find the ones that 'x' encompasses and collapse them + let yes, others = roots |> Array.partition (fun (r, _) -> contains r x) + let yesChild = yes |> Array.collect (fun (r, ch) -> Array.append [| r |] ch) + Array.append [| (x, yesChild) |] others + + ([| |], vs) ||> Array.fold addToRoot + + let rec makeSEHTree cenv env (pc2pos: int[]) (lab2pc: Dictionary) (exs: ILExceptionSpec[]) = + + let clause_inside_lrange cl lr = + List.forall (fun lr1 -> labelRangeInsideLabelRange lab2pc lr1 lr) (lranges_of_clause cl) + + let tryspec_inside_lrange (tryspec1: ILExceptionSpec) lr = + (labelRangeInsideLabelRange lab2pc tryspec1.Range lr && clause_inside_lrange tryspec1.Clause lr) + + let tryspec_inside_clause tryspec1 cl = + List.exists (fun lr -> tryspec_inside_lrange tryspec1 lr) (lranges_of_clause cl) + + let tryspec_inside_tryspec tryspec1 (tryspec2: ILExceptionSpec) = + tryspec_inside_lrange tryspec1 tryspec2.Range || + tryspec_inside_clause tryspec1 tryspec2.Clause + + let roots = findRoots tryspec_inside_tryspec exs + let trees = + roots |> Array.map (fun (cl, ch) -> + let r1 = labelsToRange lab2pc cl.Range + let conv ((s1, e1), (s2, e2)) x = pc2pos.[s1], pc2pos.[e1] - pc2pos.[s1], pc2pos.[s2], pc2pos.[e2] - pc2pos.[s2], x + let children = makeSEHTree cenv env pc2pos lab2pc ch + let n = + match cl.Clause with + | ILExceptionClause.Finally r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FinallyClause + | ILExceptionClause.Fault r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FaultClause + | ILExceptionClause.FilterCatch ((filterStart, _), r3) -> + conv (r1, labelsToRange lab2pc r3) (ExceptionClauseKind.FilterClause (pc2pos.[lab2pc.[filterStart]])) + | ILExceptionClause.TypeCatch (typ, r2) -> + conv (r1, labelsToRange lab2pc r2) (TypeFilterClause (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env typ))) + SEHTree.Node (Some n, children) ) + + trees + +#if EMIT_DEBUG_INFO + let rec makeLocalsTree cenv localSigs (pc2pos: int[]) (lab2pc: Dictionary) (exs: ILLocalDebugInfo[]) = + let localInsideLocal (locspec1: ILLocalDebugInfo) (locspec2: ILLocalDebugInfo) = + labelRangeInsideLabelRange lab2pc locspec1.Range locspec2.Range + + let roots = findRoots localInsideLocal exs + + let trees = + roots |> Array.collect (fun (cl, ch) -> + let (s1, e1) = labelsToRange lab2pc cl.Range + let (s1, e1) = pc2pos.[s1], pc2pos.[e1] + let children = makeLocalsTree cenv localSigs pc2pos lab2pc ch + mkScopeNode cenv localSigs (s1, e1, cl.DebugMappings, children)) + trees +#endif + + + // Emit the SEH tree + let rec emitExceptionHandlerTree (codebuf: CodeBuffer) (Node (x, childSEH)) = + childSEH |> Array.iter (emitExceptionHandlerTree codebuf) // internal first + x |> Option.iter codebuf.EmitExceptionClause + + let emitCode cenv localSigs (codebuf: CodeBuffer) env (code: ILCode) = + let instrs = code.Instrs + + // Build a table mapping Abstract IL pcs to positions in the generated code buffer + let pc2pos = Array.zeroCreate (instrs.Length+1) + let pc2labs = Dictionary() + for (KeyValue(lab, pc)) in code.Labels do + if pc2labs.ContainsKey pc then pc2labs.[pc] <- lab :: pc2labs.[pc] else pc2labs.[pc] <- [lab] + + // Emit the instructions + for pc = 0 to instrs.Length do + if pc2labs.ContainsKey pc then + for lab in pc2labs.[pc] do + codebuf.RecordAvailBrFixup lab + pc2pos.[pc] <- codebuf.code.Position + if pc < instrs.Length then + match instrs.[pc] with + | I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction + | i -> emitInstr cenv codebuf env i + + // Build the exceptions and locals information, ready to emit + let SEHTree = makeSEHTree cenv env pc2pos code.Labels code.Exceptions + Array.iter (emitExceptionHandlerTree codebuf) SEHTree + +#if EMIT_DEBUG_INFO + // Build the locals information, ready to emit + let localsTree = makeLocalsTree cenv localSigs pc2pos code.Labels code.Locals + localsTree +#endif + + let EmitTopCode cenv localSigs env nm code = + let codebuf = CodeBuffer.Create nm + let origScopes = emitCode cenv localSigs codebuf env code + let origCode = codebuf.code.Close() + let origExnClauses = codebuf.seh.ToArray() + let origReqdStringFixups = codebuf.reqdStringFixupsInMethod.ToArray() + let origAvailBrFixups = codebuf.availBrFixups + let origReqdBrFixups = codebuf.reqdBrFixups.ToArray() +#if EMIT_DEBUG_INFO + let origSeqPoints = codebuf.seqpoints.ToArray() +#endif + + let newCode, newReqdStringFixups, newExnClauses = + applyBrFixups origCode origExnClauses origReqdStringFixups origAvailBrFixups origReqdBrFixups + +#if EMIT_DEBUG_INFO + let rootScope = + { Children= newScopes + StartOffset=0 + EndOffset=newCode.Length + Locals=[| |] } +#endif + + (newReqdStringFixups, newExnClauses, newCode) + + // -------------------------------------------------------------------- + // ILMethodBody --> bytes + // -------------------------------------------------------------------- + let GetFieldDefTypeAsBlobIdx cenv env ty = + let bytes = emitBytesViaBuffer (fun bb -> bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb ty) + GetBytesAsBlobIdx cenv bytes + + let GenILMethodBody mname cenv env (il: ILMethodBody) = + let localSigs = + if cenv.generatePdb then + il.Locals |> Array.map (fun l -> + // Write a fake entry for the local signature headed by e_IMAGE_CEE_CS_CALLCONV_FIELD. This is referenced by the PDB file + ignore (FindOrAddSharedRow cenv ILTableNames.StandAloneSig (SharedRow [| Blob (GetFieldDefTypeAsBlobIdx cenv env l.Type) |])) + // Now write the type + GetTypeOfLocalAsBytes cenv env l) + else + [| |] + + let requiredStringFixups, seh, code (* , seqpoints, scopes *) = Codebuf.EmitTopCode cenv localSigs env mname il.Code + let codeSize = code.Length + let methbuf = ByteBuffer.Create (codeSize * 3) + // Do we use the tiny format? + if isEmpty il.Locals && il.MaxStack <= 8 && isEmpty seh && codeSize < 64 then + // Use Tiny format + let alignedCodeSize = align 4 (codeSize + 1) + let codePadding = (alignedCodeSize - (codeSize + 1)) + let requiredStringFixups' = (1, requiredStringFixups) + methbuf.EmitByte (byte codeSize <<< 2 ||| e_CorILMethod_TinyFormat) + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + 0x0, (requiredStringFixups', methbuf.Close()) // , seqpoints, scopes + else + // Use Fat format + let flags = + e_CorILMethod_FatFormat ||| + (if not (isEmpty seh) then e_CorILMethod_MoreSects else 0x0uy) ||| + (if il.IsZeroInit then e_CorILMethod_InitLocals else 0x0uy) + + let localToken = + if isEmpty il.Locals then 0x0 else + getUncodedToken ILTableNames.StandAloneSig + (FindOrAddSharedRow cenv ILTableNames.StandAloneSig (GetLocalSigAsStandAloneSigIdx cenv env il.Locals)) + + let alignedCodeSize = align 0x4 codeSize + let codePadding = (alignedCodeSize - codeSize) + + methbuf.EmitByte flags + methbuf.EmitByte 0x30uy // last four bits record size of fat header in 4 byte chunks - this is always 12 bytes = 3 four word chunks + methbuf.EmitUInt16 (uint16 il.MaxStack) + methbuf.EmitInt32 codeSize + methbuf.EmitInt32 localToken + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + + if not (isEmpty seh) then + // Can we use the small exception handling table format? + let smallSize = (seh.Length * 12 + 4) + let canUseSmall = + smallSize <= 0xFF && + seh |> Array.forall (fun (st1, sz1, st2, sz2, _) -> + st1 <= 0xFFFF && st2 <= 0xFFFF && sz1 <= 0xFF && sz2 <= 0xFF) + + let kindAsInt32 k = + match k with + | FinallyClause -> e_COR_ILEXCEPTION_CLAUSE_FINALLY + | FaultClause -> e_COR_ILEXCEPTION_CLAUSE_FAULT + | FilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_FILTER + | TypeFilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_EXCEPTION + let kindAsExtraInt32 k = + match k with + | FinallyClause | FaultClause -> 0x0 + | FilterClause i -> i + | TypeFilterClause uncoded -> uncoded + + if canUseSmall then + methbuf.EmitByte e_CorILMethod_Sect_EHTable + methbuf.EmitByte (b0 smallSize |> byte) + methbuf.EmitByte 0x00uy + methbuf.EmitByte 0x00uy + seh |> Array.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32AsUInt16 k32 + methbuf.EmitInt32AsUInt16 st1 + methbuf.EmitByte (b0 sz1 |> byte) + methbuf.EmitInt32AsUInt16 st2 + methbuf.EmitByte (b0 sz2 |> byte) + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + else + let bigSize = (seh.Length * 24 + 4) + methbuf.EmitByte (e_CorILMethod_Sect_EHTable ||| e_CorILMethod_Sect_FatFormat) + methbuf.EmitByte (b0 bigSize |> byte) + methbuf.EmitByte (b1 bigSize |> byte) + methbuf.EmitByte (b2 bigSize |> byte) + seh |> Array.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32 k32 + methbuf.EmitInt32 st1 + methbuf.EmitInt32 sz1 + methbuf.EmitInt32 st2 + methbuf.EmitInt32 sz2 + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + + let requiredStringFixups' = (12, requiredStringFixups) + + localToken, (requiredStringFixups', methbuf.Close()) //, seqpoints, scopes + + // -------------------------------------------------------------------- + // ILFieldDef --> FieldDef Row + // -------------------------------------------------------------------- + + let rec GetFieldDefAsFieldDefRow cenv env (fd: ILFieldDef) = + let flags = int fd.Attributes ||| (if (fd.LiteralValue <> None) then 0x8000 else 0x0) //||| + //(if (fd.Marshal <> None) then 0x1000 else 0x0) ||| + //(if (fd.Data <> None) then 0x0100 else 0x0) + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv fd.Name) + Blob (GetFieldDefSigAsBlobIdx cenv env fd ) |] + + and GetFieldDefSigAsBlobIdx cenv env fd = GetFieldDefTypeAsBlobIdx cenv env fd.FieldType + + and GenFieldDefPass3 cenv env fd = + let fidx = AddUnsharedRow cenv ILTableNames.Field (GetFieldDefAsFieldDefRow cenv env fd) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.FieldDef, fidx) fd.CustomAttrs +#if EMIT_FIELD_DATA + // Write FieldRVA table - fixups into data section done later + match fd.Data with + | None -> () + | Some b -> + let offs = cenv.data.Position + cenv.data.EmitBytes b + AddUnsharedRow cenv ILTableNames.FieldRVA + (UnsharedRow [| Data (offs, false); SimpleIndex (ILTableNames.Field, fidx) |]) |> ignore + // Write FieldMarshal table + match fd.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_FieldDef, fidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore +#endif + // Write Content table + match fd.LiteralValue with + | None -> () + | Some i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.FieldDef, fidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + // Write FieldLayout table + match fd.Offset with + | None -> () + | Some offset -> + AddUnsharedRow cenv ILTableNames.FieldLayout + (UnsharedRow [| ULong offset; SimpleIndex (ILTableNames.Field, fidx) |]) |> ignore + + + // -------------------------------------------------------------------- + // ILGenericParameterDef --> GenericParam Row + // -------------------------------------------------------------------- + + let rec GetGenericParamAsGenericParamRow cenv _env idx owner (gp: ILGenericParameterDef) = + let flags = + (if gp.IsCovariant then 0x0001 else 0x0000) ||| + (if gp.IsContravariant then 0x0002 else 0x0000) ||| + (if gp.HasReferenceTypeConstraint then 0x0004 else 0x0000) ||| + (if gp.HasNotNullableValueTypeConstraint then 0x0008 else 0x0000) ||| + (if gp.HasDefaultConstructorConstraint then 0x0010 else 0x0000) + + let mdVersionMajor, _ = metadataSchemaVersionSupportedByCLRVersion cenv.desiredMetadataVersion + if (mdVersionMajor = 1) then + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) + TypeDefOrRefOrSpec (TypeDefOrRefOrSpecTag.TypeDef, 0) (* empty kind field in deprecated metadata *) |] + else + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) |] + + and GenTypeAsGenericParamConstraintRow cenv env gpidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (ILTableNames.GenericParam, gpidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenGenericParamConstraintPass4 cenv env gpidx ty = + AddUnsharedRow cenv ILTableNames.GenericParamConstraint (GenTypeAsGenericParamConstraintRow cenv env gpidx ty) |> ignore + + and GenGenericParamPass3 cenv env idx owner gp = + // here we just collect generic params, its constraints\custom attributes will be processed on pass4 + // shared since we look it up again below in GenGenericParamPass4 + AddSharedRow cenv ILTableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + |> ignore + + + and GenGenericParamPass4 cenv env idx owner (gp: ILGenericParameterDef) = + let gpidx = FindOrAddSharedRow cenv ILTableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.GenericParam, gpidx) gp.CustomAttrs + gp.Constraints |> Array.iter (GenGenericParamConstraintPass4 cenv env gpidx) + + // -------------------------------------------------------------------- + // param and return --> Param Row + // -------------------------------------------------------------------- + + let rec GetParamAsParamRow cenv _env seq (param: ILParameter) = + let flags = + (if param.IsIn then 0x0001 else 0x0000) ||| + (if param.IsOut then 0x0002 else 0x0000) ||| + (if param.IsOptional then 0x0010 else 0x0000) ||| + (if param.Default.HasValue then 0x1000 else 0x0000) //||| + //(if param.Marshal <> None then 0x2000 else 0x0000) + + UnsharedRow + [| UShort (uint16 flags) + UShort (uint16 seq) + StringE (GetStringHeapIdxOption cenv param.Name) |] + + and GenParamPass3 cenv env seq (param: ILParameter) = + if not param.IsIn && not param.IsOut && not param.IsOptional && param.Default.IsNone && param.Name.IsNone // && Option.isNone param.Marshal + then () + else + let pidx = AddUnsharedRow cenv ILTableNames.Param (GetParamAsParamRow cenv env seq param) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ParamDef, pidx) param.CustomAttrs +#if EMIT_FIELD_MARSHAL + // Write FieldRVA table - fixups into data section done later + match param.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_ParamDef, pidx); Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore + // Write Content table for DefaultParameterValue attr +#endif + match param.Default with + | UNone -> () + | USome i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.ParamDef, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + + let GenReturnAsParamRow (returnv: ILReturn) = + let flags = 0x0000 // || (if returnv.Marshal <> None then 0x2000 else 0x0000) + UnsharedRow + [| UShort (uint16 flags) + UShort 0us (* sequence num. *) + StringE 0 |] + + let GenReturnPass3 cenv (returnv: ILReturn) = + if (* Option.isSome returnv.Marshal || *) not (isEmpty returnv.CustomAttrs.Entries) then + let pidx = AddUnsharedRow cenv ILTableNames.Param (GenReturnAsParamRow returnv) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ParamDef, pidx) returnv.CustomAttrs +#if EMIT_MARSHAL + match returnv.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow + [| HasFieldMarshal (hfm_ParamDef, pidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore +#endif + + // -------------------------------------------------------------------- + // ILMethodDef --> ILMethodDef Row + // -------------------------------------------------------------------- + + let GetMethodDefSigAsBytes cenv env (mdef: ILMethodDef) = + emitBytesViaBuffer (fun bb -> + bb.EmitByte (callconvToByte mdef.GenericParams.Length mdef.CallingConv) + if mdef.GenericParams.Length > 0 then bb.EmitZ32 mdef.GenericParams.Length + bb.EmitZ32 mdef.Parameters.Length + EmitType cenv env bb mdef.Return.Type + mdef.ParameterTypes |> Array.iter (EmitType cenv env bb)) + + let GenMethodDefSigAsBlobIdx cenv env mdef = + GetBytesAsBlobIdx cenv (GetMethodDefSigAsBytes cenv env mdef) + + let GenMethodDefAsRow cenv env midx (md: ILMethodDef) = + let flags = int md.Attributes + let implflags = int md.ImplAttributes + + if md.IsEntryPoint then + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (true, midx) + let codeAddr = + (match md.Body with + | Some ilmbody -> + let addr = cenv.nextCodeAddr + let (localToken, code (* , seqpoints, rootScope *) ) = GenILMethodBody md.Name cenv env ilmbody + +#if EMIT_DEBUG_INFO + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken=getUncodedToken ILTableNames.Method midx + MethName=md.Name + LocalSignatureToken=localToken + Params= [| |] (* REVIEW *) + RootScope = Some rootScope + Range= + match ilmbody.DebugPoint with + | Some m when cenv.generatePdb -> + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + + Some ({ Document=doc + Line=m.Line + Column=m.Column }, + { Document=doc + Line=m.EndLine + Column=m.EndColumn }) + | _ -> None + DebugPoints=seqpoints } +#endif + + cenv.AddCode code + addr +#if EMIT_DEBUG_INFO + | MethodBody.Abstract -> + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken = getUncodedToken ILTableNames.Method midx + MethName = md.Name + LocalSignatureToken = 0x0 // No locals it's abstract + Params = [| |] + RootScope = None + Range = None + DebugPoints = [| |] } + 0x0000 + | MethodBody.Native -> + failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries" +#endif + | _ -> 0x0000) + + UnsharedRow + [| ULong codeAddr + UShort (uint16 implflags) + UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + Blob (GenMethodDefSigAsBlobIdx cenv env md) + SimpleIndex(ILTableNames.Param, cenv.GetTable(ILTableNames.Param).Count + 1) |] + + let GenMethodImplPass3 cenv env _tgparams tidx mimpl = + let midxTag, midxRow = GetMethodSpecAsMethodDef cenv env (mimpl.OverrideBy, None) + let midx2Tag, midx2Row = GetOverridesSpecAsMethodDefOrRef cenv env mimpl.Overrides + AddUnsharedRow cenv ILTableNames.MethodImpl + (UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + MethodDefOrRef (midxTag, midxRow) + MethodDefOrRef (midx2Tag, midx2Row) |]) |> ignore + + let GenMethodDefPass3 cenv env (md:ILMethodDef) = + let midx = GetMethodDefIdx cenv md + let idx2 = AddUnsharedRow cenv ILTableNames.Method (GenMethodDefAsRow cenv env midx md) + if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2" + GenReturnPass3 cenv md.Return + md.Parameters |> Array.iteri (fun n param -> GenParamPass3 cenv env (n+1) param) + md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.MethodDef, midx) +#if EMIT_SECURITY_DECLS + md.SecurityDecls.Entries |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx) +#endif + md.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass3 cenv env n (TypeOrMethodDefTag.MethodDef, midx) gp) +#if EMIT_PINVOKE + match md.Body.Contents with + | MethodBody.PInvoke attr -> + let flags = + begin match attr.CallingConv with + | PInvokeCallingConvention.None -> 0x0000 + | PInvokeCallingConvention.Cdecl -> 0x0200 + | PInvokeCallingConvention.Stdcall -> 0x0300 + | PInvokeCallingConvention.Thiscall -> 0x0400 + | PInvokeCallingConvention.Fastcall -> 0x0500 + | PInvokeCallingConvention.WinApi -> 0x0100 + end ||| + begin match attr.CharEncoding with + | PInvokeCharEncoding.None -> 0x0000 + | PInvokeCharEncoding.Ansi -> 0x0002 + | PInvokeCharEncoding.Unicode -> 0x0004 + | PInvokeCharEncoding.Auto -> 0x0006 + end ||| + begin match attr.CharBestFit with + | PInvokeCharBestFit.UseAssembly -> 0x0000 + | PInvokeCharBestFit.Enabled -> 0x0010 + | PInvokeCharBestFit.Disabled -> 0x0020 + end ||| + begin match attr.ThrowOnUnmappableChar with + | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000 + | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000 + | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000 + end ||| + (if attr.NoMangle then 0x0001 else 0x0000) ||| + (if attr.LastError then 0x0040 else 0x0000) + AddUnsharedRow cenv ILTableNames.ImplMap + (UnsharedRow + [| UShort (uint16 flags) + MemberForwarded (mf_MethodDef, midx) + StringE (GetStringHeapIdx cenv attr.Name) + SimpleIndex (ILTableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore + | _ -> () +#endif + + let GenMethodDefPass4 cenv env md = + let midx = GetMethodDefIdx cenv md + md.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass4 cenv env n (TypeOrMethodDefTag.MethodDef, midx) gp) + + let GenPropertyMethodSemanticsPass3 cenv pidx kind mref = + // REVIEW: why are we catching exceptions here? + let midx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv ILTableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (ILTableNames.Method, midx) + HasSemantics (HasSemanticsTag.Property, pidx) |]) |> ignore + + let rec GetPropertySigAsBlobIdx cenv env prop = + GetBytesAsBlobIdx cenv (GetPropertySigAsBytes cenv env prop) + + and GetPropertySigAsBytes cenv env prop = + emitBytesViaBuffer (fun bb -> + let b = ((hasthisToByte prop.CallingConv) ||| e_IMAGE_CEE_CS_CALLCONV_PROPERTY) + bb.EmitByte b + bb.EmitZ32 prop.IndexParameterTypes.Length + EmitType cenv env bb prop.PropertyType + prop.IndexParameterTypes |> Array.iter (EmitType cenv env bb)) + + and GetPropertyAsPropertyRow cenv env (prop:ILPropertyDef) = + let flags = + (if prop.IsSpecialName then 0x0200 else 0x0) ||| + (if prop.IsRTSpecialName then 0x0400 else 0x0) ||| + (if prop.Init <> None then 0x1000 else 0x0) + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv prop.Name) + Blob (GetPropertySigAsBlobIdx cenv env prop) |] + + /// ILPropertyDef --> Property Row + MethodSemantics entries + and GenPropertyPass3 cenv env prop = + let pidx = AddUnsharedRow cenv ILTableNames.Property (GetPropertyAsPropertyRow cenv env prop) + prop.SetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0001) + prop.GetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0002) + // Write Constant table + match prop.Init with + | None -> () + | Some i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.Property, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Property, pidx) prop.CustomAttrs + + let rec GenEventMethodSemanticsPass3 cenv eidx kind mref = + let addIdx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv ILTableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (ILTableNames.Method, addIdx) + HasSemantics (HasSemanticsTag.Event, eidx) |]) |> ignore + + /// ILEventDef --> Event Row + MethodSemantics entries + and GenEventAsEventRow cenv env (md: ILEventDef) = + let flags = + (if md.IsSpecialName then 0x0200 else 0x0) ||| + (if md.IsRTSpecialName then 0x0400 else 0x0) + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env md.EventHandlerType + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenEventPass3 cenv env (md: ILEventDef) = + let eidx = AddUnsharedRow cenv ILTableNames.Event (GenEventAsEventRow cenv env md) + md.AddMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0008 + md.RemoveMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0010 + //Option.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0020) md.FireMethod + //List.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0004) md.OtherMethods + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Event, eidx) md.CustomAttrs + + + // -------------------------------------------------------------------- + // resource --> generate ... + // -------------------------------------------------------------------- + + let rec GetResourceAsManifestResourceRow cenv r = + let data, impl = + match r.Location with + | ILResourceLocation.Local bf -> + let b = bf() + // Embedded managed resources must be word-aligned. However resource format is + // not specified in ECMA. Some mscorlib resources appear to be non-aligned - it seems it doesn't matter.. + let offset = cenv.resources.Position + let alignedOffset = (align 0x8 offset) + let pad = alignedOffset - offset + let resourceSize = b.Length + cenv.resources.EmitPadding pad + cenv.resources.EmitInt32 resourceSize + cenv.resources.EmitBytes b + Data (alignedOffset, true), (ImplementationTag.File, 0) + | ILResourceLocation.File (mref, offset) -> ULong offset, (ImplementationTag.File, GetModuleRefAsFileIdx cenv mref) + | ILResourceLocation.Assembly aref -> ULong 0x0, (ImplementationTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + UnsharedRow + [| data + ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02) + StringE (GetStringHeapIdx cenv r.Name) + Implementation (fst impl, snd impl) |] + + and GenResourcePass3 cenv r = + let idx = AddUnsharedRow cenv ILTableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ManifestResource, idx) r.CustomAttrs + + // -------------------------------------------------------------------- + // ILTypeDef --> generate ILFieldDef, ILMethodDef, ILPropertyDef etc. rows + // -------------------------------------------------------------------- + + let rec GenTypeDefPass3 enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + td.Properties.Entries |> Array.iter (GenPropertyPass3 cenv env) + td.Events.Entries |> Array.iter (GenEventPass3 cenv env) + td.Fields.Entries |> Array.iter (GenFieldDefPass3 cenv env) + td.Methods.Entries |> Array.iter (GenMethodDefPass3 cenv env) + td.MethodImpls.Entries |> Array.iter (GenMethodImplPass3 cenv env td.GenericParams.Length tidx) + // ClassLayout entry if needed + match td.Layout with + | ILTypeDefLayout.Auto -> () + | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> + if Option.isSome layout.Pack || Option.isSome layout.Size then + AddUnsharedRow cenv ILTableNames.ClassLayout + (UnsharedRow + [| UShort (defaultArg layout.Pack (uint16 0x0)) + ULong (defaultArg layout.Size 0x0) + SimpleIndex (ILTableNames.TypeDef, tidx) |]) |> ignore + +#if EMIT_SECURITY_DECLS + td.SecurityDecls.Entries |> GenSecurityDeclsPass3 cenv (hds_TypeDef, tidx) +#endif + td.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.TypeDef, tidx) + td.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass3 cenv env n (TypeOrMethodDefTag.TypeDef, tidx) gp) + td.NestedTypes.Entries |> GenTypeDefsPass3 (addILTypeName enc td) cenv + with e -> + failwith ("Error in pass3 for type "+td.Name+", error: "+e.ToString()) + reraise() + raise e + + and GenTypeDefsPass3 enc cenv tds = + Array.iter (GenTypeDefPass3 enc cenv) tds + + /// ILTypeDef --> generate generic params on ILMethodDef: ensures + /// GenericParam table is built sorted by owner. + + let rec GenTypeDefPass4 enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + td.Methods.Entries |> Array.iter (GenMethodDefPass4 cenv env) + td.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass4 cenv env n (TypeOrMethodDefTag.TypeDef, tidx) gp) + GenTypeDefsPass4 (addILTypeName enc td) cenv td.NestedTypes.Entries + with e -> + failwith ("Error in pass4 for type "+td.Name+", error: "+e.Message) + reraise() + raise e + + and GenTypeDefsPass4 enc cenv tds = + Array.iter (GenTypeDefPass4 enc cenv) tds + + + let DateTime1970Jan01 = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc) (* ECMA Spec (Oct2002), Part II, 24.2.2 PE File Header. *) + let timestamp = (System.DateTime.UtcNow - DateTime1970Jan01).TotalSeconds |> int + + // -------------------------------------------------------------------- + // ILExportedTypesAndForwarders --> ILExportedTypeOrForwarder table + // -------------------------------------------------------------------- + + let rec GenNestedExportedTypePass3 cenv cidx (ce: ILNestedExportedType) = + let flags = GetMemberAccessFlags ce.Access + let nidx = + AddUnsharedRow cenv ILTableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + StringE (GetStringHeapIdx cenv ce.Name) + StringE 0 + Implementation (ImplementationTag.ExportedType, cidx) |]) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, nidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv nidx ce.Nested + + and GenNestedExportedTypesPass3 cenv nidx (nce: ILNestedExportedTypesAndForwarders) = + nce.Entries |> Array.iter (GenNestedExportedTypePass3 cenv nidx) + + and GenExportedTypePass3 cenv (ce: ILExportedTypeOrForwarder) = + let nselem, nelem = GetTypeNameAsElemPair cenv (ce.Namespace, ce.Name) + let flags = GetTypeAccessFlags ce.Access + let flags = if ce.IsForwarder then 0x00200000 ||| flags else flags + let impl = GetScopeRefAsImplementationElem cenv ce.ScopeRef + let cidx = + AddUnsharedRow cenv ILTableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + nelem + nselem + Implementation (fst impl, snd impl) |]) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, cidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv cidx ce.Nested + + + + // -------------------------------------------------------------------- + // manifest --> generate Assembly row + // -------------------------------------------------------------------- + + and GetManifsetAsAssemblyRow cenv m = + UnsharedRow + [|ULong m.AuxModuleHashAlgorithm + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Major) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Minor) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Build) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Revision) + ULong + ( //(match m.AssemblyLongevity with + //| ILAssemblyLongevity.Unspecified -> 0x0000 + //| ILAssemblyLongevity.Library -> 0x0002 + //| ILAssemblyLongevity.PlatformAppDomain -> 0x0004 + // | ILAssemblyLongevity.PlatformProcess -> 0x0006 + // | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| + (if m.Retargetable then 0x100 else 0x0) ||| + // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. + // Any debugging customattributes will automatically propagate + // REVIEW: No longer appears to be the case + (if m.JitTracking then 0x8000 else 0x0) ||| + (match m.PublicKey with UNone -> 0x0000 | USome _ -> 0x0001) ||| 0x0000) + (match m.PublicKey with UNone -> Blob 0 | USome x -> Blob (GetBytesAsBlobIdx cenv x)) + StringE (GetStringHeapIdx cenv m.Name) + (match m.Locale with UNone -> StringE 0 | USome x -> StringE (GetStringHeapIdx cenv x)) |] + + and GenManifestPass3 cenv m = + let aidx = AddUnsharedRow cenv ILTableNames.Assembly (GetManifsetAsAssemblyRow cenv m) +#if EMIT_SECURITY_DECLS + GenSecurityDeclsPass3 cenv (hds_Assembly, aidx) m.SecurityDecls.Entries +#endif + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Assembly, aidx) m.CustomAttrs + m.ExportedTypes.Entries |> Array.iter (GenExportedTypePass3 cenv) + // Record the entrypoint decl if needed. + match m.EntrypointElsewhere with + | Some mref -> + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) + | None -> () + + and newGuid (modul: ILModuleDef) = + let n = timestamp + let m = hash n + let m2 = hash modul.Name + [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + + and deterministicGuid (modul: ILModuleDef) = + let n = 16909060 + let m = hash n + let m2 = hash modul.Name + [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + + and GetModuleAsRow (cenv:cenv) (modul: ILModuleDef) = + // Store the generated MVID in the environment (needed for generating debug information) + let modulGuid = if cenv.deterministic then deterministicGuid modul else newGuid modul + cenv.moduleGuid <- modulGuid + UnsharedRow + [| UShort (uint16 0x0) + StringE (GetStringHeapIdx cenv modul.Name) + Guid (GetGuidIdx cenv modulGuid) + Guid 0 + Guid 0 |] + + + let rowElemCompare (e1: RowElement) (e2: RowElement) = + let c = compare e1.Val e2.Val + if c <> 0 then c else + compare e1.Tag e2.Tag + + module List = + let rec assoc x l = + match l with + | [] -> failwith "index not found" + | ((h, r)::t) -> if x = h then r else assoc x t + + let rec memAssoc x l = + match l with + | [] -> false + | ((h, _)::t) -> x = h || memAssoc x t + + let TableRequiresSorting tab = + List.memAssoc tab ILTableNames.sortedTableInfo + + let SortTableRows tab (rows:GenericRow[]) = + assert (TableRequiresSorting tab) + let col = List.assoc tab ILTableNames.sortedTableInfo + rows + // This needs to be a stable sort, so we use List.sortWith + |> Array.toList + |> List.sortWith (fun r1 r2 -> rowElemCompare r1.[col] r2.[col]) + |> Array.ofList + //|> Array.map SharedRow + + + let mkILSimpleClass (ilg: ILGlobals) (nsp, nm, methods, fields, nestedTypes, props, events, attrs) = + { Namespace=nsp + Name=nm + GenericParams= [| |] + Implements = [| |] + Attributes = TypeAttributes.Class ||| TypeAttributes.BeforeFieldInit ||| TypeAttributes.Public + Layout=ILTypeDefLayout.Auto + Extends = Some ilg.typ_Object + Methods= methods + Fields= fields + NestedTypes=nestedTypes + CustomAttrs=attrs + MethodImpls=emptyILMethodImpls + Properties=props + Events=events + Token=0 + //SecurityDecls=emptyILSecurityDecls; + //HasSecurity=false; + } + let mkILTypeDefForGlobalFunctions ilg (methods, fields) = + mkILSimpleClass ilg (UNone, typeNameForGlobalFunctions, methods, fields, emptyILTypeDefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs) + + let destTypeDefsWithGlobalFunctionsFirst ilg (tdefs: ILTypeDefs) = + let l = tdefs.Entries + let top, nontop = l |> Array.partition (fun td -> td.Name = typeNameForGlobalFunctions) + let top2 = if isEmpty top then [| mkILTypeDefForGlobalFunctions ilg (emptyILMethods, emptyILFields) |] else top + Array.append top2 nontop + + let GenModule (cenv: cenv) (modul: ILModuleDef) = + let midx = AddUnsharedRow cenv ILTableNames.Module (GetModuleAsRow cenv modul) + Array.iter (GenResourcePass3 cenv) modul.Resources.Entries + let tds = destTypeDefsWithGlobalFunctionsFirst cenv.ilg modul.TypeDefs + GenTypeDefsPass1 [] cenv tds + GenTypeDefsPass2 0 [] cenv tds + (match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m) + GenTypeDefsPass3 [] cenv tds + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Module, midx) modul.CustomAttrs + // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes). + // Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params. + // Note this mutates the rows in a table. 'SetRowsOfTable' clears + // the key --> index map since it is no longer valid + cenv.GetTable(ILTableNames.GenericParam).SetRowsOfSharedTable (SortTableRows ILTableNames.GenericParam (cenv.GetTable(ILTableNames.GenericParam).GenericRowsOfTable)) + GenTypeDefsPass4 [] cenv tds + + let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg: ILGlobals, emitTailcalls, deterministic, showTimes) (m: ILModuleDef) cilStartAddress = + let isDll = m.IsDLL + + let cenv = + { emitTailcalls=emitTailcalls + deterministic = deterministic + showTimes=showTimes + ilg = ilg + desiredMetadataVersion=desiredMetadataVersion + requiredDataFixups= requiredDataFixups + requiredStringFixups = ResizeArray() + codeChunks=ByteBuffer.Create 40000 + nextCodeAddr = cilStartAddress + data = ByteBuffer.Create 200 + resources = ByteBuffer.Create 200 + tables= + Array.init 64 (fun i -> + if (i = ILTableNames.AssemblyRef.Index || + i = ILTableNames.MemberRef.Index || + i = ILTableNames.ModuleRef.Index || + i = ILTableNames.File.Index || + i = ILTableNames.TypeRef.Index || + i = ILTableNames.TypeSpec.Index || + i = ILTableNames.MethodSpec.Index || + i = ILTableNames.StandAloneSig.Index || + i = ILTableNames.GenericParam.Index) then + MetadataTable.Shared (MetadataTable.New ("row table "+string i, EqualityComparer.Default)) + else + MetadataTable.Unshared (MetadataTable.New ("row table "+string i, EqualityComparer.Default))) + + AssemblyRefs = MetadataTable<_>.New("ILAssemblyRef", EqualityComparer.Default) + //documents=MetadataTable<_>.New("pdbdocs", EqualityComparer.Default) + trefCache=new Dictionary<_, _>(100) +#if EMIT_DEBUG_INFO + pdbinfo= new ResizeArray<_>(200) +#endif + moduleGuid= Array.zeroCreate 16 + fieldDefs= MetadataTable<_>.New("field defs", EqualityComparer.Default) + methodDefIdxsByKey = MetadataTable<_>.New("method defs", EqualityComparer.Default) + // This uses reference identity on ILMethodDef objects + methodDefIdxs = new Dictionary<_, _>(100, HashIdentity.Reference) + propertyDefs = MetadataTable<_>.New("property defs", EqualityComparer.Default) + eventDefs = MetadataTable<_>.New("event defs", EqualityComparer.Default) + typeDefs = MetadataTable<_>.New("type defs", EqualityComparer.Default) + entrypoint=None + generatePdb=generatePdb + // These must use structural comparison since they are keyed by arrays + guids=MetadataTable<_>.New("guids", HashIdentity.Structural) + blobs= MetadataTable<_>.New("blobs", HashIdentity.Structural) + strings= MetadataTable<_>.New("strings", EqualityComparer.Default) + userStrings= MetadataTable<_>.New("user strings", EqualityComparer.Default) } + + // Now the main compilation step + GenModule cenv m + + // .exe files have a .entrypoint instruction. Do not write it to the entrypoint when writing dll. + let entryPointToken = + match cenv.entrypoint with + | Some (epHere, tok) -> + if isDll then 0x0 + else getUncodedToken (if epHere then ILTableNames.Method else ILTableNames.File) tok + | None -> + if not isDll then printfn "warning: no entrypoint specified in executable binary" + 0x0 + +#if EMIT_DEBUG_INFO + let pdbData = + { EntryPoint= (if isDll then None else Some entryPointToken) + Timestamp = timestamp + ModuleID = cenv.moduleGuid + Documents = cenv.documents.EntriesAsArray + Methods = cenv.pdbinfo.ToArray() + TableRowCounts = cenv.tables |> Seq.map(fun t -> t.Count) |> Seq.toArray } +#else + let pdbData = () +#endif -[] -type TypeContainer = - | Namespace of Assembly * string // namespace - | Type of System.Type - | TypeToBeDecided + let idxForNextedTypeDef (tds:ILTypeDef list, td:ILTypeDef) = + let enc = tds |> List.map (fun td -> td.Name) + GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + + let strings = Array.map Bytes.stringAsUtf8NullTerminated cenv.strings.EntriesAsArray + let userStrings = cenv.userStrings.EntriesAsArray |> Array.map Encoding.Unicode.GetBytes + let blobs = cenv.blobs.EntriesAsArray + let guids = cenv.guids.EntriesAsArray + let tables = cenv.tables + let code = cenv.GetCode() + // turn idx tbls into token maps + let mappings = + { TypeDefTokenMap = (fun t -> + getUncodedToken ILTableNames.TypeDef (idxForNextedTypeDef t)) + FieldDefTokenMap = (fun t fd -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Field (GetFieldDefAsFieldDefIdx cenv tidx fd)) + MethodDefTokenMap = (fun t md -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Method (FindMethodDefIdx cenv (GetKeyForMethodDef tidx md))) + PropertyTokenMap = (fun t pd -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Property (cenv.propertyDefs.GetTableEntry (GetKeyForPropertyDef tidx pd))) + EventTokenMap = (fun t ed -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Event (cenv.eventDefs.GetTableEntry (EventKey (tidx, ed.Name)))) } + // New return the results + let data = cenv.data.Close() + let resources = cenv.resources.Close() + (strings, userStrings, blobs, guids, tables, entryPointToken, code, cenv.requiredStringFixups, data, resources, pdbData, mappings) + + + //===================================================================== + // TABLES+BLOBS --> PHYSICAL METADATA+BLOBS + //===================================================================== + let chunk sz next = ({addr=next; size=sz}, next + sz) + let nochunk next = ({addr= 0x0;size= 0x0; } , next) + + let count f arr = + Array.fold (fun x y -> x + f y) 0x0 arr + + let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress = + + // When we know the real RVAs of the data section we fixup the references for the FieldRVA table. + // These references are stored as offsets into the metadata we return from this function + let requiredDataFixups = ResizeArray() + + let next = cilStartAddress + + let strings, userStrings, blobs, guids, tables, entryPointToken, code, requiredStringFixups, data, resources, pdbData, mappings = + generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress + + let tableSize (tab: ILTableName) = tables.[tab.Index].Count + + // Now place the code + let codeSize = code.Length + let alignedCodeSize = align 0x4 codeSize + let codep, next = chunk codeSize next + let codePadding = Array.create (alignedCodeSize - codeSize) 0x0uy + let _codePaddingChunk, next = chunk codePadding.Length next + + // Now layout the chunks of metadata and IL + let metadataHeaderStartChunk, _next = chunk 0x10 next + + let numStreams = 0x05 + + let (mdtableVersionMajor, mdtableVersionMinor) = metadataSchemaVersionSupportedByCLRVersion desiredMetadataVersion + + let version = + Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" desiredMetadataVersion.Major desiredMetadataVersion.Minor desiredMetadataVersion.Build) + + + let paddedVersionLength = align 0x4 (Array.length version) + + // Most addresses after this point are measured from the MD root + // Switch to md-rooted addresses + let next = metadataHeaderStartChunk.size + let _metadataHeaderVersionChunk, next = chunk paddedVersionLength next + let _metadataHeaderEndChunk, next = chunk 0x04 next + let _tablesStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#~".Length + 0x01))) next + let _stringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Strings".Length + 0x01))) next + let _userStringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#US".Length + 0x01))) next + let _guidsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#GUID".Length + 0x01))) next + let _blobsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Blob".Length + 0x01))) next + + let tablesStreamStart = next + + let stringsStreamUnpaddedSize = count (fun (s:byte[]) -> s.Length) strings + 1 + let stringsStreamPaddedSize = align 4 stringsStreamUnpaddedSize + + let userStringsStreamUnpaddedSize = count (fun (s:byte[]) -> let n = s.Length + 1 in n + ByteBuffer.Z32Size n) userStrings + 1 + let userStringsStreamPaddedSize = align 4 userStringsStreamUnpaddedSize + + let guidsStreamUnpaddedSize = (Array.length guids) * 0x10 + let guidsStreamPaddedSize = align 4 guidsStreamUnpaddedSize + + let blobsStreamUnpaddedSize = count (fun (blob:byte[]) -> let n = blob.Length in n + ByteBuffer.Z32Size n) blobs + 1 + let blobsStreamPaddedSize = align 4 blobsStreamUnpaddedSize + + let guidsBig = guidsStreamPaddedSize >= 0x10000 + let stringsBig = stringsStreamPaddedSize >= 0x10000 + let blobsBig = blobsStreamPaddedSize >= 0x10000 + + // 64bit bitvector indicating which tables are in the metadata. + let (valid1, valid2), _ = + (((0, 0), 0), tables) ||> Array.fold (fun ((valid1, valid2) as valid, n) rows -> + let valid = + if rows.Count = 0 then valid else + ( (if n < 32 then valid1 ||| (1 <<< n ) else valid1), + (if n >= 32 then valid2 ||| (1 <<< (n-32)) else valid2) ) + (valid, n+1)) + + // 64bit bitvector indicating which tables are sorted. + // Constant - REVIEW: make symbolic! compute from sorted table info! + let sorted1 = 0x3301fa00 + let sorted2 = + // If there are any generic parameters in the binary we're emitting then mark that + // table as sorted, otherwise don't. This maximizes the number of assemblies we emit + // which have an ECMA-v.1. compliant set of sorted tables. + (if tableSize (ILTableNames.GenericParam) > 0 then 0x00000400 else 0x00000000) ||| + (if tableSize (ILTableNames.GenericParamConstraint) > 0 then 0x00001000 else 0x00000000) ||| + 0x00000200 + -module GlobalProvidedAssemblyElementsTable = - let theTable = Dictionary>() + let guidAddress n = (if n = 0 then 0 else (n - 1) * 0x10 + 0x01) -type ProvidedTypeDefinition(container:TypeContainer,className : string, baseType : Type option) as this = - inherit Type() + let stringAddressTable = + let tab = Array.create (strings.Length + 1) 0 + let pos = ref 1 + for i = 1 to strings.Length do + tab.[i] <- !pos + let s = strings.[i - 1] + pos := !pos + s.Length + tab - do match container, !ProvidedTypeDefinition.Logger with - | TypeContainer.Namespace _, Some logger -> logger (sprintf "Creating ProvidedTypeDefinition %s [%d]" className (System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode this)) - | _ -> () + let stringAddress n = + if n >= Array.length stringAddressTable then failwith ("string index "+string n+" out of range") + stringAddressTable.[n] + + let userStringAddressTable = + let tab = Array.create (Array.length userStrings + 1) 0 + let pos = ref 1 + for i = 1 to Array.length userStrings do + tab.[i] <- !pos + let s = userStrings.[i - 1] + let n = s.Length + 1 + pos := !pos + n + ByteBuffer.Z32Size n + tab + + let userStringAddress n = + if n >= Array.length userStringAddressTable then failwith "userString index out of range" + userStringAddressTable.[n] + + let blobAddressTable = + let tab = Array.create (blobs.Length + 1) 0 + let pos = ref 1 + for i = 1 to blobs.Length do + tab.[i] <- !pos + let blob = blobs.[i - 1] + pos := !pos + blob.Length + ByteBuffer.Z32Size blob.Length + tab + + let blobAddress n = + if n >= blobAddressTable.Length then failwith "blob index out of range" + blobAddressTable.[n] + - // state - let mutable attributes = - TypeAttributes.Public ||| - TypeAttributes.Class ||| - TypeAttributes.Sealed ||| - enum (int32 TypeProviderTypeAttributes.IsErased) + let sortedTables = + Array.init 64 (fun i -> + let tab = tables.[i] + let tabName = ILTableName.FromIndex i + let rows = tab.GenericRowsOfTable + if TableRequiresSorting tabName then SortTableRows tabName rows else rows) + + + let codedTables = + + let bignessTable = Array.map (fun rows -> Array.length rows >= 0x10000) sortedTables + let bigness (tab:int32) = bignessTable.[tab] + + let codedBigness nbits tab = + (tableSize tab) >= (0x10000 >>> nbits) + + let tdorBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.TypeRef || + codedBigness 2 ILTableNames.TypeSpec + + let tomdBigness = + codedBigness 1 ILTableNames.TypeDef || + codedBigness 1 ILTableNames.Method + + let hcBigness = + codedBigness 2 ILTableNames.Field || + codedBigness 2 ILTableNames.Param || + codedBigness 2 ILTableNames.Property + + let hcaBigness = + codedBigness 5 ILTableNames.Method || + codedBigness 5 ILTableNames.Field || + codedBigness 5 ILTableNames.TypeRef || + codedBigness 5 ILTableNames.TypeDef || + codedBigness 5 ILTableNames.Param || + codedBigness 5 ILTableNames.InterfaceImpl || + codedBigness 5 ILTableNames.MemberRef || + codedBigness 5 ILTableNames.Module || + codedBigness 5 ILTableNames.Permission || + codedBigness 5 ILTableNames.Property || + codedBigness 5 ILTableNames.Event || + codedBigness 5 ILTableNames.StandAloneSig || + codedBigness 5 ILTableNames.ModuleRef || + codedBigness 5 ILTableNames.TypeSpec || + codedBigness 5 ILTableNames.Assembly || + codedBigness 5 ILTableNames.AssemblyRef || + codedBigness 5 ILTableNames.File || + codedBigness 5 ILTableNames.ExportedType || + codedBigness 5 ILTableNames.ManifestResource || + codedBigness 5 ILTableNames.GenericParam || + codedBigness 5 ILTableNames.GenericParamConstraint || + codedBigness 5 ILTableNames.MethodSpec + + let hfmBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Param + + let hdsBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.Method || + codedBigness 2 ILTableNames.Assembly + + let mrpBigness = + codedBigness 3 ILTableNames.TypeRef || + codedBigness 3 ILTableNames.ModuleRef || + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.TypeSpec + + let hsBigness = + codedBigness 1 ILTableNames.Event || + codedBigness 1 ILTableNames.Property + + let mdorBigness = + codedBigness 1 ILTableNames.Method || + codedBigness 1 ILTableNames.MemberRef + + let mfBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Method + + let iBigness = + codedBigness 2 ILTableNames.File || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.ExportedType + + let catBigness = + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.MemberRef + + let rsBigness = + codedBigness 2 ILTableNames.Module || + codedBigness 2 ILTableNames.ModuleRef || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.TypeRef + + let tablesBuf = ByteBuffer.Create 20000 + + // Now the coded tables themselves - first the schemata header + tablesBuf.EmitIntsAsBytes + [| 0x00; 0x00; 0x00; 0x00; + mdtableVersionMajor // major version of table schemata + mdtableVersionMinor // minor version of table schemata + + ((if stringsBig then 0x01 else 0x00) ||| // bit vector for heap size + (if guidsBig then 0x02 else 0x00) ||| + (if blobsBig then 0x04 else 0x00)) + 0x01 (* reserved, always 1 *) |] + + tablesBuf.EmitInt32 valid1 + tablesBuf.EmitInt32 valid2 + tablesBuf.EmitInt32 sorted1 + tablesBuf.EmitInt32 sorted2 + + // Numbers of rows in various tables + for rows in sortedTables do + if rows.Length <> 0 then + tablesBuf.EmitInt32 rows.Length + + - let mutable enumUnderlyingType = typeof - let mutable baseType = lazy baseType - let mutable membersKnown = ResizeArray() - let mutable membersQueue = ResizeArray<(unit -> list)>() - let mutable staticParams = [ ] - let mutable staticParamsApply = None - let mutable container = container - let mutable interfaceImpls = ResizeArray() - let mutable interfaceImplsDelayed = ResizeArray list>() - let mutable methodOverrides = ResizeArray() + // The tables themselves + for rows in sortedTables do + for row in rows do + for x in row do + // Emit the coded token for the array element + let t = x.Tag + let n = x.Val + match t with + | _ when t = RowElementTags.UShort -> tablesBuf.EmitUInt16 (uint16 n) + | _ when t = RowElementTags.ULong -> tablesBuf.EmitInt32 n + | _ when t = RowElementTags.Data -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, false) + | _ when t = RowElementTags.DataResources -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, true) + | _ when t = RowElementTags.Guid -> tablesBuf.EmitZUntaggedIndex guidsBig (guidAddress n) + | _ when t = RowElementTags.Blob -> tablesBuf.EmitZUntaggedIndex blobsBig (blobAddress n) + | _ when t = RowElementTags.String -> tablesBuf.EmitZUntaggedIndex stringsBig (stringAddress n) + | _ when t <= RowElementTags.SimpleIndexMax -> tablesBuf.EmitZUntaggedIndex (bigness (t - RowElementTags.SimpleIndexMin)) n + | _ when t <= RowElementTags.TypeDefOrRefOrSpecMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeDefOrRefOrSpecMin) 2 tdorBigness n + | _ when t <= RowElementTags.TypeOrMethodDefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeOrMethodDefMin) 1 tomdBigness n + | _ when t <= RowElementTags.HasConstantMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasConstantMin) 2 hcBigness n + | _ when t <= RowElementTags.HasCustomAttributeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasCustomAttributeMin) 5 hcaBigness n + | _ when t <= RowElementTags.HasFieldMarshalMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasFieldMarshalMin) 1 hfmBigness n + | _ when t <= RowElementTags.HasDeclSecurityMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasDeclSecurityMin) 2 hdsBigness n + | _ when t <= RowElementTags.MemberRefParentMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberRefParentMin) 3 mrpBigness n + | _ when t <= RowElementTags.HasSemanticsMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasSemanticsMin) 1 hsBigness n + | _ when t <= RowElementTags.MethodDefOrRefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MethodDefOrRefMin) 1 mdorBigness n + | _ when t <= RowElementTags.MemberForwardedMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberForwardedMin) 1 mfBigness n + | _ when t <= RowElementTags.ImplementationMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ImplementationMin) 2 iBigness n + | _ when t <= RowElementTags.CustomAttributeTypeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.CustomAttributeTypeMin) 3 catBigness n + | _ when t <= RowElementTags.ResolutionScopeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ResolutionScopeMin) 2 rsBigness n + | _ -> failwith "invalid tag in row element" + + tablesBuf.Close() + + + let tablesStreamUnpaddedSize = codedTables.Length + // QUERY: extra 4 empty bytes in array.exe - why? Include some extra padding after + // the tables just in case there is a mistake in the ECMA spec. + let tablesStreamPaddedSize = align 4 (tablesStreamUnpaddedSize + 4) + let tablesChunk, next = chunk tablesStreamPaddedSize next + let tablesStreamPadding = tablesChunk.size - tablesStreamUnpaddedSize + + let stringsChunk, next = chunk stringsStreamPaddedSize next + let stringsStreamPadding = stringsChunk.size - stringsStreamUnpaddedSize + let userStringsChunk, next = chunk userStringsStreamPaddedSize next + let userStringsStreamPadding = userStringsChunk.size - userStringsStreamUnpaddedSize + let guidsChunk, next = chunk (0x10 * guids.Length) next + let blobsChunk, _next = chunk blobsStreamPaddedSize next + let blobsStreamPadding = blobsChunk.size - blobsStreamUnpaddedSize + - // members API - let getMembers() = - if membersQueue.Count > 0 then - let elems = membersQueue |> Seq.toArray // take a copy in case more elements get added - membersQueue.Clear() - for f in elems do - for i in f() do - membersKnown.Add i - match i with - | :? ProvidedProperty as p -> - if p.CanRead then membersKnown.Add (p.GetGetMethod true) - if p.CanWrite then membersKnown.Add (p.GetSetMethod true) - | :? ProvidedEvent as e -> - membersKnown.Add (e.GetAddMethod true) - membersKnown.Add (e.GetRemoveMethod true) - | _ -> () - - membersKnown.ToArray() + let metadata, guidStart = + let mdbuf = ByteBuffer.Create 500000 + mdbuf.EmitIntsAsBytes + [| 0x42; 0x53; 0x4a; 0x42; // Magic signature + 0x01; 0x00; // Major version + 0x01; 0x00; // Minor version + |]; + mdbuf.EmitInt32 0x0; // Reserved + + mdbuf.EmitInt32 paddedVersionLength; + mdbuf.EmitBytes version; + for i = 1 to (paddedVersionLength - Array.length version) do + mdbuf.EmitIntAsByte 0x00; + + mdbuf.EmitBytes + [| 0x00uy; 0x00uy; // flags, reserved + b0 numStreams; b1 numStreams; |]; + mdbuf.EmitInt32 tablesChunk.addr; + mdbuf.EmitInt32 tablesChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x7e; 0x00; 0x00; (* #~00 *)|]; + mdbuf.EmitInt32 stringsChunk.addr; + mdbuf.EmitInt32 stringsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; 0x00; 0x00; 0x00; 0x00 (* "#Strings0000" *)|]; + mdbuf.EmitInt32 userStringsChunk.addr; + mdbuf.EmitInt32 userStringsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x55; 0x53; 0x00; (* #US0*) |]; + mdbuf.EmitInt32 guidsChunk.addr; + mdbuf.EmitInt32 guidsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x47; 0x55; 0x49; 0x44; 0x00; 0x00; 0x00; (* #GUID000 *)|]; + mdbuf.EmitInt32 blobsChunk.addr; + mdbuf.EmitInt32 blobsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x42; 0x6c; 0x6f; 0x62; 0x00; 0x00; 0x00; (* #Blob000 *)|]; + + // Now the coded tables themselves + mdbuf.EmitBytes codedTables; + for i = 1 to tablesStreamPadding do + mdbuf.EmitIntAsByte 0x00; + + // The string stream + mdbuf.EmitByte 0x00uy; + for s in strings do + mdbuf.EmitBytes s; + for i = 1 to stringsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + // The user string stream + mdbuf.EmitByte 0x00uy; + for s in userStrings do + mdbuf.EmitZ32 (s.Length + 1); + mdbuf.EmitBytes s; + mdbuf.EmitIntAsByte (markerForUnicodeBytes s) + for i = 1 to userStringsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + + // The GUID stream + let guidStart = mdbuf.Position + Array.iter mdbuf.EmitBytes guids; + + // The blob stream + mdbuf.EmitByte 0x00uy; + for s in blobs do + mdbuf.EmitZ32 s.Length; + mdbuf.EmitBytes s + for i = 1 to blobsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + // Done - close the buffer and return the result. + mdbuf.Close(), guidStart + - // members API - let getInterfaces() = - if interfaceImplsDelayed.Count > 0 then - let elems = interfaceImplsDelayed |> Seq.toArray // take a copy in case more elements get added - interfaceImplsDelayed.Clear() - for f in elems do - for i in f() do - interfaceImpls.Add i - - interfaceImpls.ToArray() + // Now we know the user string tables etc. we can fixup the + // uses of strings in the code + for (codeStartAddr, l) in requiredStringFixups do + for (codeOffset, userStringIndex) in l do + if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then failwith "strings-in-code fixup: a group of fixups is located outside the code array"; + let locInCode = ((codeStartAddr + codeOffset) - codep.addr) + checkFixup32 code locInCode 0xdeadbeef; + let token = getUncodedToken ILTableNames.UserStrings (userStringAddress userStringIndex) + if (Bytes.get code (locInCode-1) <> i_ldstr) then failwith "strings-in-code fixup: not at ldstr instruction!"; + applyFixup32 code locInCode token + + entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups.ToArray(), pdbData, mappings, guidStart + + //--------------------------------------------------------------------- + // PHYSICAL METADATA+BLOBS --> PHYSICAL PE FORMAT + //--------------------------------------------------------------------- + + // THIS LAYS OUT A 2-SECTION .NET PE BINARY + // SECTIONS + // TEXT: physical 0x0200 --> RVA 0x00020000 + // e.g. raw size 0x9600, + // e.g. virt size 0x9584 + // RELOC: physical 0x9800 --> RVA 0x0000c000 + // i.e. physbase --> rvabase + // where physbase = textbase + text raw size + // phsrva = roundup(0x2000, 0x0002000 + text virt size) + + let msdosHeader: byte[] = + [| 0x4duy; 0x5auy; 0x90uy; 0x00uy; 0x03uy; 0x00uy; 0x00uy; 0x00uy + 0x04uy; 0x00uy; 0x00uy; 0x00uy; 0xFFuy; 0xFFuy; 0x00uy; 0x00uy + 0xb8uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x40uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy + 0x0euy; 0x1fuy; 0xbauy; 0x0euy; 0x00uy; 0xb4uy; 0x09uy; 0xcduy + 0x21uy; 0xb8uy; 0x01uy; 0x4cuy; 0xcduy; 0x21uy; 0x54uy; 0x68uy + 0x69uy; 0x73uy; 0x20uy; 0x70uy; 0x72uy; 0x6fuy; 0x67uy; 0x72uy + 0x61uy; 0x6duy; 0x20uy; 0x63uy; 0x61uy; 0x6euy; 0x6euy; 0x6fuy + 0x74uy; 0x20uy; 0x62uy; 0x65uy; 0x20uy; 0x72uy; 0x75uy; 0x6euy + 0x20uy; 0x69uy; 0x6euy; 0x20uy; 0x44uy; 0x4fuy; 0x53uy; 0x20uy + 0x6duy; 0x6fuy; 0x64uy; 0x65uy; 0x2euy; 0x0duy; 0x0duy; 0x0auy + 0x24uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] + + let writeInt64 (os: BinaryWriter) x = + os.Write (dw0 x); + os.Write (dw1 x); + os.Write (dw2 x); + os.Write (dw3 x); + os.Write (dw4 x); + os.Write (dw5 x); + os.Write (dw6 x); + os.Write (dw7 x) + + let writeInt32 (os: BinaryWriter) x = + os.Write (b0 x) + os.Write (b1 x) + os.Write (b2 x) + os.Write (b3 x) + + let writeInt32AsUInt16 (os: BinaryWriter) x = + os.Write (b0 x) + os.Write (b1 x) + + let writeDirectory os dict = + writeInt32 os (if dict.size = 0x0 then 0x0 else dict.addr); + writeInt32 os dict.size + + let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk, 0, chunk.Length) + + let writeBinaryAndReportMappings (outfile: string, + ilg: ILGlobals, pdbfile: string option, (* signer: ILStrongNameSigner option, *) portablePDB, embeddedPDB, + embedAllSource, embedSourceList, sourceLink, emitTailcalls, deterministic, showTimes, dumpDebugInfo ) modul = + let isDll = modul.IsDLL + + let os = + try + // Ensure the output directory exists otherwise it will fail + let dir = Path.GetDirectoryName(outfile) + if not (Directory.Exists(dir)) then Directory.CreateDirectory(dir) |>ignore + new BinaryWriter(System.IO.File.OpenWrite(outfile)) + with e -> + failwith ("Could not open file for writing (binary mode): " + outfile + "\n" + e.ToString()) + + let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings = + try + + let imageBaseReal = modul.ImageBase // FIXED CHOICE + let alignVirt = modul.VirtualAlignment // FIXED CHOICE + let alignPhys = modul.PhysicalAlignment // FIXED CHOICE + + let isItanium = modul.Platform = Some(IA64) + + let numSections = 3 // .text, .sdata, .reloc + + + // HEADERS + let next = 0x0 + let headerSectionPhysLoc = 0x0 + let headerAddr = next + let next = headerAddr + + let msdosHeaderSize = 0x80 + let msdosHeaderChunk, next = chunk msdosHeaderSize next + + let peSignatureSize = 0x04 + let peSignatureChunk, next = chunk peSignatureSize next + + let peFileHeaderSize = 0x14 + let peFileHeaderChunk, next = chunk peFileHeaderSize next + + let peOptionalHeaderSize = if modul.Is64Bit then 0xf0 else 0xe0 + let peOptionalHeaderChunk, next = chunk peOptionalHeaderSize next + + let textSectionHeaderSize = 0x28 + let textSectionHeaderChunk, next = chunk textSectionHeaderSize next + + let dataSectionHeaderSize = 0x28 + let dataSectionHeaderChunk, next = chunk dataSectionHeaderSize next + + let relocSectionHeaderSize = 0x28 + let relocSectionHeaderChunk, next = chunk relocSectionHeaderSize next + + let headerSize = next - headerAddr + let nextPhys = align alignPhys (headerSectionPhysLoc + headerSize) + let headerSectionPhysSize = nextPhys - headerSectionPhysLoc + let next = align alignVirt (headerAddr + headerSize) + + // TEXT SECTION: 8 bytes IAT table 72 bytes CLI header + + let textSectionPhysLoc = nextPhys + let textSectionAddr = next + let next = textSectionAddr + + let importAddrTableChunk, next = chunk 0x08 next + let cliHeaderPadding = (if isItanium then (align 16 next) else next) - next + let next = next + cliHeaderPadding + let cliHeaderChunk, next = chunk 0x48 next + + let desiredMetadataVersion = + if modul.MetadataVersion <> "" then + Version.Parse modul.MetadataVersion + else + match ilg.systemRuntimeScopeRef with + | ILScopeRef.Local -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Local" + | ILScopeRef.Module(_) -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module" + | ILScopeRef.Assembly(aref) -> + match aref.Version with + | USome v -> v + | UNone -> failwith "Expected msorlib to have a version number" + + let entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups, pdbData, mappings, guidStart = + writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul next + + let _codeChunk, next = chunk code.Length next + let _codePaddingChunk, next = chunk codePadding.Length next + + let metadataChunk, next = chunk metadata.Length next + +#if EMIT_STRONG_NAME + let strongnameChunk, next = + match signer with + | None -> nochunk next + | Some s -> chunk s.SignatureSize next +#else + let strongnameChunk, next = nochunk next +#endif - let mutable theAssembly = - lazy - match container with - | TypeContainer.Namespace (theAssembly, rootNamespace) -> - if theAssembly = null then failwith "Null assemblies not allowed" - if rootNamespace<>null && rootNamespace.Length=0 then failwith "Use 'null' for global namespace" - theAssembly - | TypeContainer.Type superTy -> superTy.Assembly - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let rootNamespace = - lazy - match container with - | TypeContainer.Namespace (_,rootNamespace) -> rootNamespace - | TypeContainer.Type enclosingTyp -> enclosingTyp.Namespace - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) + let resourcesChunk, next = chunk resources.Length next + + let rawdataChunk, next = chunk data.Length next + + let vtfixupsChunk, next = nochunk next // Note: only needed for mixed mode assemblies + let importTableChunkPrePadding = (if isItanium then (align 16 next) else next) - next + let next = next + importTableChunkPrePadding + let importTableChunk, next = chunk 0x28 next + let importLookupTableChunk, next = chunk 0x14 next + let importNameHintTableChunk, next = chunk 0x0e next + let mscoreeStringChunk, next = chunk 0x0c next + + let next = align 0x10 (next + 0x05) - 0x05 + let importTableChunk = { addr=importTableChunk.addr; size = next - importTableChunk.addr} + let importTableChunkPadding = importTableChunk.size - (0x28 + 0x14 + 0x0e + 0x0c) + + let next = next + 0x03 + let entrypointCodeChunk, next = chunk 0x06 next + let globalpointerCodeChunk, next = chunk (if isItanium then 0x8 else 0x0) next + +#if EMIT_DEBUG_INFO + let pdbOpt = + match portablePDB with + | true -> + let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic + if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream) + else Some (pdbStream) + | _ -> None + + let debugDirectoryChunk, next = + chunk (if pdbfile = None then + 0x0 + else if embeddedPDB && portablePDB then + sizeof_IMAGE_DEBUG_DIRECTORY * 2 + else + sizeof_IMAGE_DEBUG_DIRECTORY + ) next + + // The debug data is given to us by the PDB writer and appears to + // typically be the type of the data plus the PDB file name. We fill + // this in after we've written the binary. We approximate the size according + // to what PDB writers seem to require and leave extra space just in case... + let debugDataJustInCase = 40 + let debugDataChunk, next = + chunk (align 0x4 (match pdbfile with + | None -> 0 + | Some f -> (24 + + Encoding.Unicode.GetByteCount(f) // See bug 748444 + + debugDataJustInCase))) next + + let debugEmbeddedPdbChunk, next = + let streamLength = + match pdbOpt with + | Some (_, _, stream) -> int(stream.Length) + | None -> 0 + chunk (align 0x4 (match embeddedPDB with + | true -> 8 + streamLength + | _ -> 0 )) next - let declaringType = - lazy - match container with - | TypeContainer.Namespace _ -> null - | TypeContainer.Type enclosingTyp -> enclosingTyp - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) +#else + let pdbOpt = None + let debugDirectoryChunk, next = chunk 0x0 next + let debugDataChunk, next = chunk (align 0x4 0) next + let debugEmbeddedPdbChunk, next = chunk (align 0x4 0) next +#endif - let fullName = - lazy - match container with - | TypeContainer.Type declaringType -> declaringType.FullName + "+" + className - | TypeContainer.Namespace (_,namespaceName) -> - if namespaceName="" then failwith "use null for global namespace" - match namespaceName with - | null -> className - | _ -> namespaceName + "." + className - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let patchUpAddedMemberInfo (this:Type) (m:MemberInfo) = - match m with - | :? ProvidedConstructor as c -> c.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedMethod as m -> m.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedProperty as p -> p.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedEvent as e -> e.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedTypeDefinition as t -> t.DeclaringTypeImpl <- this - | :? ProvidedLiteralField as l -> l.DeclaringTypeImpl <- this - | :? ProvidedField as l -> l.DeclaringTypeImpl <- this - | _ -> () + let textSectionSize = next - textSectionAddr + let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) + let textSectionPhysSize = nextPhys - textSectionPhysLoc + let next = align alignVirt (textSectionAddr + textSectionSize) + + // .RSRC SECTION (DATA) + let dataSectionPhysLoc = nextPhys + let dataSectionAddr = next + let dataSectionVirtToPhys v = v - dataSectionAddr + dataSectionPhysLoc + + +#if EMIT_NATIVE_RESOURCES + let resourceFormat = if modul.Is64Bit then Support.X64 else Support.X86 + let nativeResources = + match modul.NativeResources with + | [] -> [||] + | resources -> + if runningOnMono then + [||] + else + let unlinkedResources = List.map Lazy.force resources + begin + try linkNativeResources unlinkedResources next resourceFormat (Path.GetDirectoryName(outfile)) + with e -> failwith ("Linking a native resource failed: "+e.Message+"") + end + let nativeResourcesSize = nativeResources.Length + let nativeResourcesChunk, next = chunk nativeResourcesSize next +#else + let nativeResourcesChunk, next = chunk 0x0 next +#endif - let customAttributesImpl = CustomAttributesImpl() - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.HideObjectMethods with set v = customAttributesImpl.HideObjectMethods <- v - member __.NonNullable with set v = customAttributesImpl.NonNullable <- v - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() - member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute -#if FX_NO_CUSTOMATTRIBUTEDATA + + let dummydatap, next = chunk (if next = dataSectionAddr then 0x01 else 0x0) next + + let dataSectionSize = next - dataSectionAddr + let nextPhys = align alignPhys (dataSectionPhysLoc + dataSectionSize) + let dataSectionPhysSize = nextPhys - dataSectionPhysLoc + let next = align alignVirt (dataSectionAddr + dataSectionSize) + + // .RELOC SECTION base reloc table: 0x0c size + let relocSectionPhysLoc = nextPhys + let relocSectionAddr = next + let baseRelocTableChunk, next = chunk 0x0c next + + let relocSectionSize = next - relocSectionAddr + let nextPhys = align alignPhys (relocSectionPhysLoc + relocSectionSize) + let relocSectionPhysSize = nextPhys - relocSectionPhysLoc + let next = align alignVirt (relocSectionAddr + relocSectionSize) + + // Now we know where the data section lies we can fix up the + // references into the data section from the metadata tables. + begin + requiredDataFixups |> Array.iter + (fun (metadataOffset32, (dataOffset, kind)) -> + let metadataOffset = metadataOffset32 + if metadataOffset < 0 || metadataOffset >= metadata.Length - 4 then failwith "data RVA fixup: fixup located outside metadata"; + checkFixup32 metadata metadataOffset 0xdeaddddd; + let dataRva = + if kind then + let res = dataOffset + if res >= resourcesChunk.size then printfn ("resource offset bigger than resource data section"); + res + else + let res = rawdataChunk.addr + dataOffset + if res < rawdataChunk.addr then printfn ("data rva before data section"); + if res >= rawdataChunk.addr + rawdataChunk.size then printfn "%s" ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr+", rawdataChunk.size = "+string rawdataChunk.size); + res + applyFixup32 metadata metadataOffset dataRva); + end; + + // IMAGE TOTAL SIZE + let imageEndSectionPhysLoc = nextPhys + let imageEndAddr = next + + + let write p (os: BinaryWriter) chunkName chunk = + match p with + | None -> () + | Some pExpected -> + os.Flush(); + let pCurrent = int32 os.BaseStream.Position + if pCurrent <> pExpected then + failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected) + writeBytes os chunk + + let writePadding (os: BinaryWriter) _comment sz = + if sz < 0 then failwith "writePadding: size < 0"; + for i = 0 to sz - 1 do + os.Write 0uy + + // Now we've computed all the offsets, write the image + + write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader; + + write (Some peSignatureChunk.addr) os "pe signature" [| |]; + + writeInt32 os 0x4550; + + write (Some peFileHeaderChunk.addr) os "pe file header" [| |]; + + if (modul.Platform = Some(AMD64)) then + writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64 + elif isItanium then + writeInt32AsUInt16 os 0x200 + else + writeInt32AsUInt16 os 0x014c; // Machine - IMAGE_FILE_MACHINE_I386 + + writeInt32AsUInt16 os numSections; + +#if EMIT_DEBUG_INFO + let pdbData = + if deterministic then + // Hash code, data and metadata + use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only + let hCode = sha.ComputeHash code + let hData = sha.ComputeHash data + let hMeta = sha.ComputeHash metadata + let final = [| hCode; hData; hMeta |] |> Array.collect id |> sha.ComputeHash + + // Confirm we have found the correct data and aren't corrupting the metadata + if metadata.[ guidStart..guidStart+3] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + if metadata.[ guidStart+12..guidStart+15] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + + // Update MVID guid in metadata + Array.blit final 0 metadata guidStart 16 + + // Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused + let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24) + writeInt32 os timestamp + // Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID + // Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-determinsitic Windows native code + { pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp } + else + writeInt32 os timestamp // date since 1970 + pdbData #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + writeInt32 os timestamp // date since 1970 #endif - member __.ResetEnclosingType (ty) = - container <- TypeContainer.Type ty - new (assembly:Assembly,namespaceName,className,baseType) = new ProvidedTypeDefinition(TypeContainer.Namespace (assembly,namespaceName), className, baseType) - new (className,baseType) = new ProvidedTypeDefinition(TypeContainer.TypeToBeDecided, className, baseType) - // state ops + writeInt32 os 0x00; // Pointer to Symbol Table Always 0 + // 00000090 + writeInt32 os 0x00; // Number of Symbols Always 0 + writeInt32AsUInt16 os peOptionalHeaderSize; // Size of the optional header, the format is described below. + + // 64bit: IMAGE_FILE_32BIT_MACHINE ||| IMAGE_FILE_LARGE_ADDRESS_AWARE + // 32bit: IMAGE_FILE_32BIT_MACHINE + // Yes, 32BIT_MACHINE is set for AMD64... + let iMachineCharacteristic = match modul.Platform with | Some IA64 -> 0x20 | Some AMD64 -> 0x0120 | _ -> 0x0100 + + writeInt32AsUInt16 os ((if isDll then 0x2000 else 0x0000) ||| 0x0002 ||| 0x0004 ||| 0x0008 ||| iMachineCharacteristic); + + // Now comes optional header + + let peOptionalHeaderByte = peOptionalHeaderByteByCLRVersion desiredMetadataVersion + + write (Some peOptionalHeaderChunk.addr) os "pe optional header" [| |]; + if modul.Is64Bit then + writeInt32AsUInt16 os 0x020B // Magic number is 0x020B for 64-bit + else + writeInt32AsUInt16 os 0x010b; // Always 0x10B (see Section 23.1). + writeInt32AsUInt16 os peOptionalHeaderByte; // ECMA spec says 6, some binaries, e.g. fscmanaged.exe say 7, Whidbey binaries say 8 + writeInt32 os textSectionPhysSize; // Size of the code (text) section, or the sum of all code sections if there are multiple sections. + // 000000a0 + writeInt32 os dataSectionPhysSize; // Size of the initialized data section, or the sum of all such sections if there are multiple data sections. + writeInt32 os 0x00; // Size of the uninitialized data section, or the sum of all such sections if there are multiple uninitialized data sections. + writeInt32 os entrypointCodeChunk.addr; // RVA of entry point , needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 in a section marked execute/read for EXEs or 0 for DLLs e.g. 0x0000b57e + writeInt32 os textSectionAddr; // e.g. 0x0002000 + // 000000b0 + if modul.Is64Bit then + writeInt64 os ((int64)imageBaseReal) // REVIEW: For 64-bit, we should use a 64-bit image base + else + writeInt32 os dataSectionAddr; // e.g. 0x0000c000 + writeInt32 os imageBaseReal; // Image Base Always 0x400000 (see Section 23.1). - QUERY: no it's not always 0x400000, e.g. 0x034f0000 + + writeInt32 os alignVirt; // Section Alignment Always 0x2000 (see Section 23.1). + writeInt32 os alignPhys; // File Alignment Either 0x200 or 0x1000. + // 000000c0 + writeInt32AsUInt16 os 0x04; // OS Major Always 4 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // OS Minor Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // User Major Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // User Minor Always 0 (see Section 23.1). + do + let (major, minor) = modul.SubsystemVersion + writeInt32AsUInt16 os major; + writeInt32AsUInt16 os minor; + writeInt32 os 0x00; // Reserved Always 0 (see Section 23.1). + // 000000d0 + writeInt32 os imageEndAddr; // Image Size: Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment. e.g. 0x0000e000 + writeInt32 os headerSectionPhysSize; // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment. + writeInt32 os 0x00; // File Checksum Always 0 (see Section 23.1). QUERY: NOT ALWAYS ZERO + writeInt32AsUInt16 os modul.SubSystemFlags; // SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2). QUERY: Why is this 3 on the images ILASM produces + // DLL Flags Always 0x400 (no unmanaged windows exception handling - see Section 23.1). + // Itanium: see notes at end of file + // IMAGE_DLLCHARACTERISTICS_NX_COMPAT: See FSharp 1.0 bug 5019 and http://blogs.msdn.com/ed_maurer/archive/2007/12/14/nxcompat-and-the-c-compiler.aspx + // Itanium: IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE | IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x86: IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x64: IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + let dllCharacteristics = + let flags = + if modul.Is64Bit then (if isItanium then 0x8540 else 0x540) + else 0x540 + if modul.UseHighEntropyVA then flags ||| 0x20 // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA + else flags + writeInt32AsUInt16 os dllCharacteristics + // 000000e0 + // Note that the defaults differ between x86 and x64 + if modul.Is64Bit then + let size = defaultArg modul.StackReserveSize 0x400000 |> int64 + writeInt64 os size // Stack Reserve Size Always 0x400000 (4Mb) (see Section 23.1). + writeInt64 os 0x4000L // Stack Commit Size Always 0x4000 (16Kb) (see Section 23.1). + writeInt64 os 0x100000L // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt64 os 0x2000L // Heap Commit Size Always 0x800 (8Kb) (see Section 23.1). + else + let size = defaultArg modul.StackReserveSize 0x100000 + writeInt32 os size // Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). + writeInt32 os 0x100000 // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). + // 000000f0 - x86 location, moving on, for x64, add 0x10 + writeInt32 os 0x00 // Loader Flags Always 0 (see Section 23.1) + writeInt32 os 0x10 // Number of Data Directories: Always 0x10 (see Section 23.1). + writeInt32 os 0x00 + writeInt32 os 0x00 // Export Table Always 0 (see Section 23.1). + // 00000100 + writeDirectory os importTableChunk // Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 + // Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not. For the moment assume the resources table is always the first resource in the file. + writeDirectory os nativeResourcesChunk + + // 00000110 + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + // 00000120 + writeDirectory os baseRelocTableChunk + writeDirectory os debugDirectoryChunk // Debug Directory + // 00000130 + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + // 00000140 + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + // 00000150 + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeDirectory os importAddrTableChunk // Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 + // 00000160 + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeDirectory os cliHeaderChunk + // 00000170 + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + + write (Some textSectionHeaderChunk.addr) os "text section header" [| |] + + // 00000178 + writeBytes os [| 0x2euy; 0x74uy; 0x65uy; 0x78uy; 0x74uy; 0x00uy; 0x00uy; 0x00uy; |] // ".text\000\000\000" + // 00000180 + writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x00009584 + writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x00020000 + writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. 0x00009600 + writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 00000200 + // 00000190 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 00000198 + writeInt32AsUInt16 os 0x00// NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags describing section's characteristics, see below. IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ + + write (Some dataSectionHeaderChunk.addr) os "data section header" [| |] + + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x73uy; 0x72uy; 0x63uy; 0x00uy; 0x00uy; 0x00uy; |] // ".rsrc\000\000\000" + // writeBytes os [| 0x2e; 0x73; 0x64; 0x61; 0x74; 0x61; 0x00; 0x00; |] // ".sdata\000\000" + writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c + writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000 + // 000001b0 + writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. e.g. 0x00000200 + writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 0x00009800 + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x40uy |] // Characteristics Flags: IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA + + write (Some relocSectionHeaderChunk.addr) os "reloc section header" [| |] + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x65uy; 0x6cuy; 0x6fuy; 0x63uy; 0x00uy; 0x00uy; |] // ".reloc\000\000" + writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c + writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000 + // 000001b0 + writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00000200 + writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00009800 + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x42uy |] // Characteristics Flags: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | + + writePadding os "pad to text begin" (textSectionPhysLoc - headerSize) + + // TEXT SECTION: e.g. 0x200 + + let textV2P v = v - textSectionAddr + textSectionPhysLoc + + // e.g. 0x0200 + write (Some (textV2P importAddrTableChunk.addr)) os "import addr table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 // QUERY 4 bytes of zeros not 2 like ECMA 24.3.1 says + + // e.g. 0x0208 + + let flags = + (if modul.IsILOnly then 0x01 else 0x00) ||| + (if modul.Is32Bit then 0x02 else 0x00) ||| + (if modul.Is32BitPreferred then 0x00020003 else 0x00) ||| +#if EMIT_STRONG_NAME + (if (match signer with None -> false | Some s -> s.IsFullySigned) then 0x08 else 0x00) ||| +#endif + 0x0000 + + let headerVersionMajor, headerVersionMinor = headerVersionSupportedByCLRVersion desiredMetadataVersion + + writePadding os "pad to cli header" cliHeaderPadding + write (Some (textV2P cliHeaderChunk.addr)) os "cli header" [| |] + writeInt32 os 0x48 // size of header + writeInt32AsUInt16 os headerVersionMajor // Major part of minimum version of CLR reqd. + writeInt32AsUInt16 os headerVersionMinor // Minor part of minimum version of CLR reqd. ... + // e.g. 0x0210 + writeDirectory os metadataChunk + writeInt32 os flags + + writeInt32 os entryPointToken + write None os "rest of cli header" [| |] + + // e.g. 0x0220 + writeDirectory os resourcesChunk + writeDirectory os strongnameChunk + // e.g. 0x0230 + writeInt32 os 0x00 // code manager table, always 0 + writeInt32 os 0x00 // code manager table, always 0 + writeDirectory os vtfixupsChunk + // e.g. 0x0240 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // managed native header, always 0 + writeInt32 os 0x00 // managed native header, always 0 + + writeBytes os code + write None os "code padding" codePadding + + writeBytes os metadata + +#if EMIT_STRONG_NAME + // write 0x80 bytes of empty space for encrypted SHA1 hash, written by SN.EXE or call to signing API + if signer <> None then + write (Some (textV2P strongnameChunk.addr)) os "strongname" (Array.create strongnameChunk.size 0x0uy) +#endif - override __.UnderlyingSystemType = typeof + write (Some (textV2P resourcesChunk.addr)) os "raw resources" [| |] + writeBytes os resources + write (Some (textV2P rawdataChunk.addr)) os "raw data" [| |] + writeBytes os data + + writePadding os "start of import table" importTableChunkPrePadding + + // vtfixups would go here + write (Some (textV2P importTableChunk.addr)) os "import table" [| |] + + writeInt32 os importLookupTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os mscoreeStringChunk.addr + writeInt32 os importAddrTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + write (Some (textV2P importLookupTableChunk.addr)) os "import lookup table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + + write (Some (textV2P importNameHintTableChunk.addr)) os "import name hint table" [| |] + // Two zero bytes of hint, then Case sensitive, null-terminated ASCII string containing name to import. + // Shall _CorExeMain a .exe file _CorDllMain for a .dll file. + if isDll then + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy ; 0x6fuy; 0x72uy; 0x44uy; 0x6cuy; 0x6cuy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + else + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy; 0x6fuy; 0x72uy; 0x45uy; 0x78uy; 0x65uy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + + write (Some (textV2P mscoreeStringChunk.addr)) os "mscoree string" + [| 0x6duy; 0x73uy; 0x63uy; 0x6fuy ; 0x72uy; 0x65uy ; 0x65uy; 0x2euy ; 0x64uy; 0x6cuy ; 0x6cuy; 0x00uy ; |] + + writePadding os "end of import tab" importTableChunkPadding + + writePadding os "head of entrypoint" 0x03 + let ep = (imageBaseReal + textSectionAddr) + write (Some (textV2P entrypointCodeChunk.addr)) os " entrypoint code" + [| 0xFFuy; 0x25uy; (* x86 Instructions for entry *) b0 ep; b1 ep; b2 ep; b3 ep |] + if isItanium then + write (Some (textV2P globalpointerCodeChunk.addr)) os " itanium global pointer" + [| 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy |] + + if pdbfile.IsSome then + write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy) + write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy) + + if embeddedPDB then + write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy) + + writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize) + + // DATA SECTION +#if EMIT_NATIVE_RESOURCES + match nativeResources with + | [||] -> () + | resources -> + write (Some (dataSectionVirtToPhys nativeResourcesChunk.addr)) os "raw native resources" [| |] + writeBytes os resources +#endif - member __.SetEnumUnderlyingType(ty) = enumUnderlyingType <- ty + if dummydatap.size <> 0x0 then + write (Some (dataSectionVirtToPhys dummydatap.addr)) os "dummy data" [| 0x0uy |] + + writePadding os "end of .rsrc" (relocSectionPhysLoc - dataSectionPhysLoc - dataSectionSize) + + // RELOC SECTION + + // See ECMA 24.3.2 + let relocV2P v = v - relocSectionAddr + relocSectionPhysLoc + + let entrypointFixupAddr = entrypointCodeChunk.addr + 0x02 + let entrypointFixupBlock = (entrypointFixupAddr / 4096) * 4096 + let entrypointFixupOffset = entrypointFixupAddr - entrypointFixupBlock + let reloc = (if modul.Is64Bit then 0xA000 (* IMAGE_REL_BASED_DIR64 *) else 0x3000 (* IMAGE_REL_BASED_HIGHLOW *)) ||| entrypointFixupOffset + // For the itanium, you need to set a relocation entry for the global pointer + let reloc2 = + if not isItanium then + 0x0 + else + 0xA000 ||| (globalpointerCodeChunk.addr - ((globalpointerCodeChunk.addr / 4096) * 4096)) + + write (Some (relocV2P baseRelocTableChunk.addr)) os "base reloc table" + [| b0 entrypointFixupBlock; b1 entrypointFixupBlock; b2 entrypointFixupBlock; b3 entrypointFixupBlock; + 0x0cuy; 0x00uy; 0x00uy; 0x00uy; + b0 reloc; b1 reloc; + b0 reloc2; b1 reloc2; |] + writePadding os "end of .reloc" (imageEndSectionPhysLoc - relocSectionPhysLoc - relocSectionSize) + + os.Dispose() + + pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings + + // Looks like a finally + with e -> + (try + os.Dispose() + File.Delete outfile + with _ -> ()) + reraise() + + //Finished writing and signing the binary and debug info... + mappings + + type options = + { ilg: ILGlobals + pdbfile: string option + portablePDB: bool + embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list + sourceLink: string +#if EMIT_STRONG_NAME + signer: ILStrongNameSigner option +#endif + emitTailcalls: bool + deterministic: bool + showTimes: bool + dumpDebugInfo:bool } - override __.GetEnumUnderlyingType() = if this.IsEnum then enumUnderlyingType else invalidOp "not enum type" + let WriteILBinary (outfile, (args: options), modul) = + writeBinaryAndReportMappings (outfile, + args.ilg, args.pdbfile, (* args.signer, *) args.portablePDB, args.embeddedPDB, args.embedAllSource, + args.embedSourceList, args.sourceLink, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo) modul + |> ignore - member __.SetBaseType t = baseType <- lazy Some t +//==================================================================================================== +// ProvidedAssembly - model for generated assembly fragments - member __.SetBaseTypeDelayed baseTypeFunction = baseType <- lazy (Some (baseTypeFunction())) +namespace ProviderImplementation.ProvidedTypes - member __.SetAttributes x = attributes <- x + #nowarn "1182" + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + - // Add MemberInfos - member __.AddMembersDelayed(membersFunction : unit -> list<#MemberInfo>) = - membersQueue.Add (fun () -> membersFunction() |> List.map (fun x -> patchUpAddedMemberInfo this x; x :> MemberInfo )) + type ILLocalBuilder(i: int) = + member __.LocalIndex = i + + [] + type ILExceptionClauseBuilder = + | Finally of ILCodeLabel + | Fault of ILCodeLabel + | FilterCatch of ILCodeLabel * (ILCodeLabel * ILCodeLabel) + | TypeCatch of ILCodeLabel * ILType + + type ILExceptionBlockBuilder(i: ILCodeLabel, leave: ILCodeLabel) = + member __.StartIndex = i + member __.Leave = leave + member val EndIndex : int = 0 with get, set + member val Clause : ILExceptionClauseBuilder option = None with get, set + + type ILGenerator(methodName) = + let mutable locals = ResizeArray() + let mutable instrs = ResizeArray() + let mutable exceptions = ResizeArray() + let mutable labelCount = 0 + let mutable labels = Dictionary() + let mutable exceptionBlocks = Stack() + + member __.Content = + { IsZeroInit = true + MaxStack = instrs.Count + Locals = locals.ToArray() + Code = + { Labels = labels + Instrs = instrs.ToArray() + Exceptions = exceptions.ToArray() + Locals = [| |] (* TODO ILLocalDebugInfo *) } + } + + member __.DeclareLocal(ty: ILType) = + let idx = locals.Count + let local = { Type = ty; IsPinned = false; DebugInfo = None } + locals.Add(local) + ILLocalBuilder(idx) + + member ilg.BeginExceptionBlock() = + exceptionBlocks.Push(ILExceptionBlockBuilder(ilg.DefineLabelHere(), ilg.DefineLabel())) + + member ilg.EndGuardedBlock() = + let block = exceptionBlocks.Peek() + ilg.Emit(I_leave block.Leave) + block.EndIndex <- ilg.DefineLabelHere() + + member ilg.BeginCatchBlock(typ: ILType) = + exceptionBlocks.Peek().Clause <- Some <| + ILExceptionClauseBuilder.TypeCatch(ilg.DefineLabelHere(), typ) + + member ilg.BeginCatchFilterBlock(range: ILCodeLabel * ILCodeLabel) = + exceptionBlocks.Peek().Clause <- Some <| + ILExceptionClauseBuilder.FilterCatch(ilg.DefineLabelHere(), range) + + member ilg.BeginFinallyBlock() = + exceptionBlocks.Peek().Clause <- Some <| + ILExceptionClauseBuilder.Finally (ilg.DefineLabelHere()) + + member ilg.BeginFaultBlock() = + exceptionBlocks.Peek().Clause <- Some <| + ILExceptionClauseBuilder.Fault (ilg.DefineLabelHere()) + + member ilg.EndExceptionBlock() = + let exnBlock = exceptionBlocks.Pop() + match exnBlock.Clause.Value with + | ILExceptionClauseBuilder.Finally(start) -> + ilg.Emit(I_endfinally) + | ILExceptionClauseBuilder.Fault(start) -> + ilg.Emit(I_endfinally) + | ILExceptionClauseBuilder.FilterCatch _ -> + ilg.Emit(I_leave exnBlock.Leave) + | ILExceptionClauseBuilder.TypeCatch _ -> + ilg.Emit(I_leave exnBlock.Leave) + let endIndex = ilg.DefineLabelHere() + ilg.MarkLabel(exnBlock.Leave) + let clause = + match exnBlock.Clause.Value with + | ILExceptionClauseBuilder.Finally(start) -> + ILExceptionClause.Finally (start, endIndex) + | ILExceptionClauseBuilder.Fault(start) -> + ILExceptionClause.Fault (start, endIndex) + | ILExceptionClauseBuilder.FilterCatch(start, range) -> + ILExceptionClause.FilterCatch (range, (start, endIndex)) + | ILExceptionClauseBuilder.TypeCatch(start, typ) -> + ILExceptionClause.TypeCatch(typ, (start, endIndex)) + + exceptions.Add { Range = (exnBlock.StartIndex, exnBlock.EndIndex) + ; Clause = clause + } + + member __.DefineLabel() = labelCount <- labelCount + 1; labelCount + member __.MarkLabel(label) = labels.[label] <- instrs.Count + member this.DefineLabelHere() = let label = this.DefineLabel() in this.MarkLabel(label); label + member __.Emit(opcode) = instrs.Add(opcode) + override __.ToString() = "generator for " + methodName + + + type ILFieldBuilder(enclosing: ILType, nm: string, fty: ILType, attrs: FieldAttributes) = + + let mutable lit = None + let cattrs = ResizeArray() + + member __.SetConstant(lit2) = (lit <- Some lit2) + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + member __.FormalFieldRef = ILFieldRef(enclosing.TypeRef, nm, fty) + member this.FormalFieldSpec = ILFieldSpec(this.FormalFieldRef, enclosing) + member __.Name = nm + + member __.Content = + { Name = nm + FieldType = fty + LiteralValue = lit + Attributes = attrs + Offset = None + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken() } + override __.ToString() = "builder for " + nm + + type ILGenericParameterBuilder(nm, attrs: GenericParameterAttributes) = + + let mutable constraints = ResizeArray() + let cattrs = ResizeArray() + + member __.AddConstraint(ty) = constraints.Add(ty) + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + + member __.Content = + { Name=nm + Constraints= constraints.ToArray() + Attributes = attrs + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken() } + override __.ToString() = "builder for " + nm + + type ILParameterBuilder(ty: ILType) = + + let mutable attrs = ParameterAttributes.None + let mutable nm = UNone + let mutable dflt = UNone + let cattrs = ResizeArray() + + member __.SetData(attrs2, nm2) = attrs <- attrs2; nm <- USome nm2 + member __.SetConstant(obj) = dflt <- USome obj + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + + member __.Content = + { Name=nm + ParameterType=ty + Default=dflt + Attributes = attrs + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) } + + type ILMethodBuilder(enclosing: ILType, methodName: string, attrs: MethodAttributes, retty: ILType, argtys:ILType[]) = + + let ilParams = [| yield ILParameterBuilder(retty); for argty in argtys do yield ILParameterBuilder(argty) |] + let mutable implflags = MethodImplAttributes.IL + let gparams = ResizeArray() + let cattrs = ResizeArray() + let mutable body = None + + member __.DefineGenericParameter(name, attrs) = let eb = ILGenericParameterBuilder(name, attrs) in gparams.Add eb; eb + member __.DefineParameter(i, attrs, parameterName) = ilParams.[i].SetData(attrs, parameterName) ; ilParams.[i] + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + member __.GetILGenerator() = let ilg = ILGenerator(methodName) in body <- Some ilg; ilg + member __.FormalMethodRef = + let cc = (if ILMethodDef.ComputeIsStatic attrs then ILCallingConv.Static else ILCallingConv.Instance) + ILMethodRef (enclosing.TypeRef, cc, gparams.Count, methodName, argtys, retty) + member this.FormalMethodSpec = + ILMethodSpec(this.FormalMethodRef, enclosing, mkILFormalGenericArgs enclosing.TypeSpec.GenericArgs.Length gparams.Count) + + member __.Content = + { Token = genToken() + Name = methodName + Attributes = attrs + ImplAttributes = implflags + GenericParams = [| for x in gparams -> x.Content |] + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Parameters = [| for p in ilParams.[1..] -> p.Content |] + CallingConv = (if attrs &&& MethodAttributes.Static <> enum<_>(0) then ILCallingConv.Static else ILCallingConv.Instance) + Return = (let p = ilParams.[0].Content in { Type = p.ParameterType; CustomAttrs = p.CustomAttrs }) + Body = body |> Option.map (fun b -> b.Content) + IsEntryPoint = false } + override __.ToString() = "builder for " + methodName + + type ILPropertyBuilder(nm, attrs: PropertyAttributes, retty: ILType, argtys: ILType[]) = + + let mutable setMethod = None + let mutable getMethod = None + let cattrs = ResizeArray() + + member __.SetGetMethod(mb: ILMethodBuilder) = getMethod <- Some mb + member __.SetSetMethod(mb: ILMethodBuilder) = setMethod <- Some mb + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + + member __.Content = + { Name=nm + CallingConv = + (if (getMethod.IsSome && getMethod.Value.Content.IsStatic) || + (setMethod.IsSome && setMethod.Value.Content.IsStatic) then + ILThisConvention.Static + else ILThisConvention.Instance) + Attributes = attrs + GetMethod = (getMethod |> Option.map (fun mb -> mb.FormalMethodRef)) + SetMethod = (setMethod |> Option.map (fun mb -> mb.FormalMethodRef)) + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + PropertyType=retty + Init= None // TODO if (attrs &&& PropertyAttributes.HasDefault) = 0 then None else + IndexParameterTypes=argtys + Token = genToken() } + override __.ToString() = "builder for " + nm + + type ILEventBuilder(nm, attrs: EventAttributes) = + + let mutable addMethod = None + let mutable removeMethod = None + let cattrs = ResizeArray() + + member __.SetAddOnMethod(mb: ILMethodBuilder) = addMethod <- Some mb + member __.SetRemoveOnMethod(mb: ILMethodBuilder) = removeMethod <- Some mb + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + member __.Content = + { Name = nm + Attributes = attrs + AddMethod = addMethod.Value.FormalMethodRef + RemoveMethod = removeMethod.Value.FormalMethodRef + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken()} + override __.ToString() = "builder for " + nm + + type ILTypeBuilder(scoref, nsp: string uoption, nm: string, attrs: TypeAttributes) = + + let mutable extends = None + let implements = ResizeArray() + let nestedTypes = ResizeArray() + let methods = ResizeArray() + let fields = ResizeArray() + let props = ResizeArray() + let events = ResizeArray() + let gparams = ResizeArray() + let methodImpls = ResizeArray() + let cattrs = ResizeArray() + + member __.ILTypeRef = ILTypeRef(scoref, nsp, nm) + member this.ILTypeSpec = ILTypeSpec(this.ILTypeRef, mkILFormalGenericArgs 0 gparams.Count) + member this.ILType = + match ILTypeDef.ComputeKind (int attrs) extends nsp nm with + | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> ILType.Value this.ILTypeSpec + | _ -> ILType.Boxed this.ILTypeSpec + + member this.DefineNestedType(name, attrs) = let tb = ILTypeBuilder(ILTypeRefScope.Nested this.ILTypeRef, UNone, name, attrs) in nestedTypes.Add tb; tb + + member this.DefineField(name, retty, attrs) = let fb = ILFieldBuilder(this.ILType, name, retty, attrs) in fields.Add fb; fb + member this.DefineMethod(name, attrs, retty, argtys) = let mb = ILMethodBuilder(this.ILType, name, attrs, retty, argtys) in methods.Add mb; mb + member this.DefineConstructor(attrs, argtys) = let mb = ILMethodBuilder(this.ILType, ".ctor", attrs ||| MethodAttributes.SpecialName ||| MethodAttributes.RTSpecialName, ILType.Void, argtys) in methods.Add mb; mb + member __.DefineProperty(name, attrs, propty, argtys) = let pb = ILPropertyBuilder(name, attrs, propty, argtys) in props.Add pb; pb + member __.DefineEvent(name, attrs) = let eb = ILEventBuilder(name, attrs) in events.Add eb; eb + member __.DefineMethodOverride(mimpl) = methodImpls.Add (mimpl) + member __.DefineGenericParameter(name, attrs) = let eb = ILGenericParameterBuilder(name, attrs) in gparams.Add eb; eb + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + member __.AddInterfaceImplementation(ty) = implements.Add(ty) + member this.DefineTypeInitializer () = let mb = ILMethodBuilder(this.ILType, ".cctor", MethodAttributes.Static ||| MethodAttributes.SpecialName ||| MethodAttributes.RTSpecialName ||| MethodAttributes.Private, ILType.Void, [| |]) in methods.Add mb; mb + member __.SetParent ty = (extends <- Some ty) + member this.DefineDefaultConstructor(attrs, baseCtor: ILMethodSpec) = + let ctor = this.DefineConstructor(attrs, [| |]) + let ilg = ctor.GetILGenerator() + ilg.Emit(I_ldarg 0) + ilg.Emit(I_call (Normalcall, baseCtor, None)) + ilg.Emit(I_ret) + ctor + + + member __.Content = + { Namespace=nsp + Name=nm + GenericParams= [| for x in gparams -> x.Content |] + Implements = implements.ToArray() + Attributes = attrs + Layout=ILTypeDefLayout.Auto + Extends=extends + Token=genToken() + //SecurityDecls=emptyILSecurityDecls; + //HasSecurity=false; + NestedTypes = ILTypeDefs( lazy [| for x in nestedTypes -> let td = x.Content in td.Namespace, td.Name, lazy td |] ) + Fields = { new ILFieldDefs with member __.Entries = [| for x in fields -> x.Content |] } + Properties = { new ILPropertyDefs with member __.Entries = [| for x in props -> x.Content |] } + Events = { new ILEventDefs with member __.Entries = [| for x in events -> x.Content |] } + Methods = ILMethodDefs (lazy [| for x in methods -> x.Content |]) + MethodImpls = { new ILMethodImplDefs with member __.Entries = methodImpls.ToArray() } + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + } + override __.ToString() = "builder for " + joinILTypeName nsp nm + + type ILModuleBuilder(scoref, moduleName, manifest) = + let typeDefs = ResizeArray() + let cattrs = ResizeArray() + + member __.DefineType(nsp, name, attrs) = let tb = ILTypeBuilder(ILTypeRefScope.Top scoref, nsp, name, attrs) in typeDefs.Add tb; tb + member __.SetCustomAttribute(ca) = cattrs.Add(ca) + + member __.Content = + { Manifest=manifest + Name=moduleName + SubsystemVersion = (4, 0) + UseHighEntropyVA = false + SubSystemFlags=3 + IsDLL=true + IsILOnly=true + Platform=None + StackReserveSize=None + Is32Bit=false + Is32BitPreferred=false + Is64Bit=false + PhysicalAlignment=512 + VirtualAlignment=0x2000 + ImageBase=0x034f0000 + MetadataVersion="" + Resources=ILResources (lazy [| |]) + TypeDefs = ILTypeDefs( lazy [| for x in typeDefs-> let td = x.Content in td.Namespace, td.Name, lazy td |] ) + CustomAttrs = { new ILCustomAttrs with member __.Entries = cattrs.ToArray() } + } + override __.ToString() = "builder for " + moduleName + + type ILAssemblyBuilder(assemblyName: AssemblyName, fileName, ilg, attrs : ILCustomAttribute seq) = + let cattrs = ResizeArray(attrs) + let manifest = + { Name = assemblyName.Name + AuxModuleHashAlgorithm = 0x8004 // SHA1 + PublicKey = UNone + Version = UNone + Locale = UNone + CustomAttrs = { new ILCustomAttrs with member __.Entries = cattrs.ToArray() } + //AssemblyLongevity=ILAssemblyLongevity.Unspecified + DisableJitOptimizations = false + JitTracking = true + IgnoreSymbolStoreSequencePoints = false + Retargetable = false + ExportedTypes = ILExportedTypesAndForwarders (lazy [| |]) + EntrypointElsewhere=None } + let mb = ILModuleBuilder(ILScopeRef.Local, "MainModule", Some manifest) + member __.MainModule = mb + member __.Save() = + let il = mb.Content + let options: BinaryWriter.options = { ilg = ilg; pdbfile = None; portablePDB = false; embeddedPDB = false; embedAllSource = false; embedSourceList = []; sourceLink = ""; emitTailcalls = true; deterministic = false; showTimes = false; dumpDebugInfo = false } + BinaryWriter.WriteILBinary (fileName, options, il) + override __.ToString() = "builder for " + (assemblyName.ToString()) + - member __.AddMembers(memberInfos:list<#MemberInfo>) = (* strict *) - memberInfos |> List.iter (patchUpAddedMemberInfo this) // strict: patch up now - membersQueue.Add (fun () -> memberInfos |> List.map (fun x -> x :> MemberInfo)) + type ExpectedStackState = + | Empty = 1 + | Address = 2 + | Value = 3 + + type CodeGenerator(assemblyMainModule: ILModuleBuilder, + genUniqueTypeName: (unit -> string), + implicitCtorArgsAsFields: ILFieldBuilder list, + convTypeToTgt: Type -> Type, + transType: Type -> ILType, + transFieldSpec: FieldInfo -> ILFieldSpec, + transMeth: MethodInfo -> ILMethodSpec, + transMethRef: MethodInfo -> ILMethodRef, + transCtorSpec: ConstructorInfo -> ILMethodSpec, + ilg: ILGenerator, + localsMap:Dictionary, + parameterVars) = + + // TODO: this works over FSharp.Core 4.4.0.0 types and methods. These types need to be retargeted to the target runtime. + + let getTypeFromHandleMethod() = (convTypeToTgt typeof).GetMethod("GetTypeFromHandle") + let languagePrimitivesType() = (convTypeToTgt (typedefof>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives"))) + let parseInt32Method() = (convTypeToTgt (languagePrimitivesType())).GetMethod "ParseInt32" + let decimalConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof; typeof; typeof; typeof |]) + let dateTimeConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof |]) + let dateTimeOffsetConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof |]) + let timeSpanConstructor() = (convTypeToTgt typeof).GetConstructor([|typeof|]) + + let decimalTypeTgt = convTypeToTgt typeof + let convertTypeTgt = convTypeToTgt typeof + let stringTypeTgt = convTypeToTgt typeof + let mathTypeTgt = convTypeToTgt typeof + + let makeTypePattern tp = + let tt = convTypeToTgt tp + fun (t : Type) -> if t = tt then Some() else None + + let (|Bool|_|) = makeTypePattern(typeof) + let (|SByte|_|) = makeTypePattern(typeof) + let (|Int16|_|) = makeTypePattern(typeof) + let (|Int32|_|) = makeTypePattern(typeof) + let (|Int64|_|) = makeTypePattern(typeof) + let (|Byte|_|) = makeTypePattern(typeof) + let (|UInt16|_|) = makeTypePattern(typeof) + let (|UInt32|_|) = makeTypePattern(typeof) + let (|UInt64|_|) = makeTypePattern(typeof) + let (|Single|_|) = makeTypePattern(typeof) + let (|Double|_|) = makeTypePattern(typeof) + let (|Char|_|) = makeTypePattern(typeof) + let (|Decimal|_|) = makeTypePattern(typeof) + let (|String|_|) = makeTypePattern(typeof) + + let (|StaticMethod|_|) name tps (t : Type) = + match t.GetMethod(name, BindingFlags.Static ||| BindingFlags.Public, null, tps, null) with + | null -> None + | m -> Some m + + let (|StaticMethodWithReturnType|_|) name tps returnType (t : Type) = + t.GetMethods(BindingFlags.Static ||| BindingFlags.Public) + |> Array.tryFind + (fun x -> + x.Name = name + && x.ReturnType = returnType + && (x.GetParameters() |> Array.map (fun i -> i.ParameterType)) = tps) + - member __.AddMember(memberInfo:MemberInfo) = - this.AddMembers [memberInfo] + let (|SpecificCall|_|) templateParameter = + // Note: precomputation + match templateParameter with + | (Lambdas(_, Call(_, minfo1, _)) | Call(_, minfo1, _)) -> + let targetType = convTypeToTgt minfo1.DeclaringType + let minfo1 = targetType.GetMethod(minfo1.Name, bindAll) + let isg1 = minfo1.IsGenericMethod + let gmd = + if minfo1.IsGenericMethodDefinition then + minfo1 + elif isg1 then + minfo1.GetGenericMethodDefinition() + else null + + // end-of-precomputation + + (fun tm -> + match tm with + | Call(obj, minfo2, args) + #if FX_NO_REFLECTION_METADATA_TOKENS + when ( // if metadata tokens are not available we'll rely only on equality of method references + #else + when (minfo1.MetadataToken = minfo2.MetadataToken && + #endif + if isg1 then + minfo2.IsGenericMethod && gmd = minfo2.GetGenericMethodDefinition() + else + minfo1 = minfo2) -> + Some(obj, (minfo2.GetGenericArguments() |> Array.toList), args) + | _ -> None) + | _ -> + invalidArg "templateParameter" "The parameter is not a recognized method name" + + let (|MakeDecimal|_|) = + let minfo1 = languagePrimitivesType().GetNestedType("IntrinsicFunctions").GetMethod("MakeDecimal") + (fun tm -> + match tm with + | Call(None, minfo2, args) + #if FX_NO_REFLECTION_METADATA_TOKENS + when ( // if metadata tokens are not available we'll rely only on equality of method references + #else + when (minfo1.MetadataToken = minfo2.MetadataToken && + #endif + minfo1 = minfo2) -> + Some(args) + | _ -> None) + + let (|NaN|_|) = + let operatorsType = convTypeToTgt (typedefof>.Assembly.GetType("Microsoft.FSharp.Core.Operators")) + let minfo1 = operatorsType.GetProperty("NaN").GetGetMethod() + (fun e -> + match e with + | Call(None, minfo2, []) + #if FX_NO_REFLECTION_METADATA_TOKENS + when ( // if metadata tokens are not available we'll rely only on equality of method references + #else + when (minfo1.MetadataToken = minfo2.MetadataToken && + #endif + minfo1 = minfo2) -> + Some() + | _ -> None) + + let (|NaNSingle|_|) = + let operatorsType = convTypeToTgt (typedefof>.Assembly.GetType("Microsoft.FSharp.Core.Operators")) + let minfo1 = operatorsType.GetProperty("NaNSingle").GetGetMethod() + (fun e -> + match e with + | Call(None, minfo2, []) + #if FX_NO_REFLECTION_METADATA_TOKENS + when ( // if metadata tokens are not available we'll rely only on equality of method references + #else + when (minfo1.MetadataToken = minfo2.MetadataToken && + #endif + minfo1 = minfo2) -> + Some() + | _ -> None) + + let (|TypeOf|_|) = (|SpecificCall|_|) <@ typeof @> + + let (|LessThan|_|) = (|SpecificCall|_|) <@ (<) @> + let (|GreaterThan|_|) = (|SpecificCall|_|) <@ (>) @> + let (|LessThanOrEqual|_|) = (|SpecificCall|_|) <@ (<=) @> + let (|GreaterThanOrEqual|_|) = (|SpecificCall|_|) <@ (>=) @> + let (|Equals|_|) = (|SpecificCall|_|) <@ (=) @> + let (|NotEquals|_|) = (|SpecificCall|_|) <@ (<>) @> + let (|Multiply|_|) = (|SpecificCall|_|) <@ (*) @> + let (|Addition|_|) = (|SpecificCall|_|) <@ (+) @> + let (|Subtraction|_|) = (|SpecificCall|_|) <@ (-) @> + let (|UnaryNegation|_|) = (|SpecificCall|_|) <@ (~-) @> + let (|Division|_|) = (|SpecificCall|_|) <@ (/) @> + let (|UnaryPlus|_|) = (|SpecificCall|_|) <@ (~+) @> + let (|Modulus|_|) = (|SpecificCall|_|) <@ (%) @> + let (|LeftShift|_|) = (|SpecificCall|_|) <@ (<<<) @> + let (|RightShift|_|) = (|SpecificCall|_|) <@ (>>>) @> + let (|And|_|) = (|SpecificCall|_|) <@ (&&&) @> + let (|Or|_|) = (|SpecificCall|_|) <@ (|||) @> + let (|Xor|_|) = (|SpecificCall|_|) <@ (^^^) @> + let (|Not|_|) = (|SpecificCall|_|) <@ (~~~) @> + //let (|Compare|_|) = (|SpecificCall|_|) <@ compare @> + let (|Max|_|) = (|SpecificCall|_|) <@ max @> + let (|Min|_|) = (|SpecificCall|_|) <@ min @> + //let (|Hash|_|) = (|SpecificCall|_|) <@ hash @> + let (|CallByte|_|) = (|SpecificCall|_|) <@ byte @> + let (|CallSByte|_|) = (|SpecificCall|_|) <@ sbyte @> + let (|CallUInt16|_|) = (|SpecificCall|_|) <@ uint16 @> + let (|CallInt16|_|) = (|SpecificCall|_|) <@ int16 @> + let (|CallUInt32|_|) = (|SpecificCall|_|) <@ uint32 @> + let (|CallInt|_|) = (|SpecificCall|_|) <@ int @> + let (|CallInt32|_|) = (|SpecificCall|_|) <@ int32 @> + let (|CallUInt64|_|) = (|SpecificCall|_|) <@ uint64 @> + let (|CallInt64|_|) = (|SpecificCall|_|) <@ int64 @> + let (|CallSingle|_|) = (|SpecificCall|_|) <@ single @> + let (|CallFloat32|_|) = (|SpecificCall|_|) <@ float32 @> + let (|CallDouble|_|) = (|SpecificCall|_|) <@ double @> + let (|CallFloat|_|) = (|SpecificCall|_|) <@ float @> + let (|CallDecimal|_|) = (|SpecificCall|_|) <@ decimal @> + let (|CallChar|_|) = (|SpecificCall|_|) <@ char @> + let (|Ignore|_|) = (|SpecificCall|_|) <@ ignore @> + let (|GetArray|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray @> + let (|GetArray2D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray2D @> + let (|GetArray3D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray3D @> + let (|GetArray4D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray4D @> + + let (|Abs|_|) = (|SpecificCall|_|) <@ abs @> + let (|Acos|_|) = (|SpecificCall|_|) <@ acos @> + let (|Asin|_|) = (|SpecificCall|_|) <@ asin @> + let (|Atan|_|) = (|SpecificCall|_|) <@ atan @> + let (|Atan2|_|) = (|SpecificCall|_|) <@ atan2 @> + let (|Ceil|_|) = (|SpecificCall|_|) <@ ceil @> + let (|Exp|_|) = (|SpecificCall|_|) <@ exp @> + let (|Floor|_|) = (|SpecificCall|_|) <@ floor @> + let (|Truncate|_|) = (|SpecificCall|_|) <@ truncate @> + let (|Round|_|) = (|SpecificCall|_|) <@ round @> + let (|Sign|_|) = (|SpecificCall|_|) <@ sign @> + let (|Log|_|) = (|SpecificCall|_|) <@ log @> + let (|Log10|_|) = (|SpecificCall|_|) <@ log10 @> + let (|Sqrt|_|) = (|SpecificCall|_|) <@ sqrt @> + let (|Cos|_|) = (|SpecificCall|_|) <@ cos @> + let (|Cosh|_|) = (|SpecificCall|_|) <@ cosh @> + let (|Sin|_|) = (|SpecificCall|_|) <@ sin @> + let (|Sinh|_|) = (|SpecificCall|_|) <@ sinh @> + let (|Tan|_|) = (|SpecificCall|_|) <@ tan @> + let (|Tanh|_|) = (|SpecificCall|_|) <@ tanh @> + //let (|Range|_|) = (|SpecificCall|_|) <@ (..) @> + //let (|RangeStep|_|) = (|SpecificCall|_|) <@ (.. ..) @> + let (|Pow|_|) = (|SpecificCall|_|) <@ ( ** ) @> + //let (|Pown|_|) = (|SpecificCall|_|) <@ pown @> + + let mathOp t1 name = + match t1 with + | Double -> + let m = mathTypeTgt.GetMethod(name, [|t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + ilg.Emit(I_conv DT_R8) + let m = mathTypeTgt.GetMethod(name, [|convTypeToTgt typeof|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | StaticMethod name [|t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "%s not supported for type %s" name t1.Name + + let lessThan (a1 : Expr) (a2 : Expr) = + match <@@ (<) @@> with + | DerivedPatterns.Lambdas(vars, Call(None, meth, _)) -> + let targetType = convTypeToTgt meth.DeclaringType + let m = targetType.GetMethod(meth.Name, bindAll).MakeGenericMethod(a1.Type) + Expr.Call(m, [a1; a2]) + | _ -> failwith "Unreachable" + + let isEmpty s = (s = ExpectedStackState.Empty) + let isAddress s = (s = ExpectedStackState.Address) + let rec emitLambda(callSiteIlg: ILGenerator, v: Var, body: Expr, freeVars: seq, lambdaLocals: Dictionary<_, ILLocalBuilder>, parameters) = + let lambda: ILTypeBuilder = assemblyMainModule.DefineType(UNone, genUniqueTypeName(), TypeAttributes.Class) + + let fsharpFuncType = convTypeToTgt (typedefof>) + let voidType = convTypeToTgt typeof + let rec lambdaType (t : Type) = + if t.IsGenericType then + let args = t.GetGenericArguments() + let gdef = t.GetGenericTypeDefinition() + if args.Length = 2 && gdef.FullName = fsharpFuncType.FullName && args.[1] = voidType then + gdef.MakeGenericType(lambdaType args.[0], typeof) + else + gdef.MakeGenericType(args |> Array.map lambdaType) + else + t + + let baseType = convTypeToTgt (lambdaType (typedefof>.MakeGenericType(v.Type, body.Type))) + lambda.SetParent(transType baseType) + let baseCtor = baseType.GetConstructor(bindAll, null, [| |], null) + if isNull baseCtor then failwithf "Couldn't find default constructor on %O" baseType + let ctor = lambda.DefineDefaultConstructor(MethodAttributes.Public, transCtorSpec baseCtor) + let decl = baseType.GetMethod "Invoke" + let paramTypes = [| for p in decl.GetParameters() -> transType p.ParameterType |] + let retType = transType decl.ReturnType + let invoke = lambda.DefineMethod("Invoke", MethodAttributes.Virtual ||| MethodAttributes.Final ||| MethodAttributes.Public, retType, paramTypes) + lambda.DefineMethodOverride + { Overrides = OverridesSpec(transMethRef decl, transType decl.DeclaringType) + OverrideBy = invoke.FormalMethodSpec } + + // promote free vars to fields + let fields = ResizeArray() + for v in freeVars do + let f = lambda.DefineField(v.Name, transType v.Type, FieldAttributes.Assembly) + //Debug.Assert (v.Name <> "formatValue") + fields.Add(v, f) + + let lambdaLocals = Dictionary() + + let ilg = invoke.GetILGenerator() + for (v, f) in fields do + let l = ilg.DeclareLocal(transType v.Type) + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, f.FormalFieldSpec)) + ilg.Emit(I_stloc l.LocalIndex) + lambdaLocals.[v] <- l + + let unitType = transType (convTypeToTgt (typeof)) + let expectedState = if (retType = ILType.Void || retType.QualifiedName = unitType.QualifiedName) then ExpectedStackState.Empty else ExpectedStackState.Value + let lambadParamVars = [| Var("this", typeof); v|] + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, lambdaLocals, lambadParamVars) + codeGen.EmitExpr (expectedState, body) + if retType.QualifiedName = unitType.QualifiedName then + ilg.Emit(I_ldnull) + ilg.Emit(I_ret) + + callSiteIlg.Emit(I_newobj (ctor.FormalMethodSpec, None)) + for (v, f) in fields do + callSiteIlg.Emit(I_dup) + match localsMap.TryGetValue v with + | true, loc -> + callSiteIlg.Emit(I_ldloc loc.LocalIndex) + | false, _ -> + let index = parameters |> Array.findIndex ((=) v) + callSiteIlg.Emit(I_ldarg index) + callSiteIlg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, f.FormalFieldSpec)) + + and emitExpr expectedState expr = + let pop () = ilg.Emit(I_pop) + let popIfEmptyExpected s = if isEmpty s then pop() + let emitConvIfNecessary t1 = + if t1 = typeof then + ilg.Emit(I_conv DT_I2) + elif t1 = typeof then + ilg.Emit(I_conv DT_U2) + elif t1 = typeof then + ilg.Emit(I_conv DT_I1) + elif t1 = typeof then + ilg.Emit(I_conv DT_U1) + /// emits given expression to corresponding IL + match expr with + | ForIntegerRangeLoop(loopVar, first, last, body) -> + // for(loopVar = first..last) body + let lb = + match localsMap.TryGetValue loopVar with + | true, lb -> lb + | false, _ -> + let lb = ilg.DeclareLocal(transType loopVar.Type) + localsMap.Add(loopVar, lb) + lb + + // loopVar = first + emitExpr ExpectedStackState.Value first + ilg.Emit(I_stloc lb.LocalIndex) + + let before = ilg.DefineLabel() + let after = ilg.DefineLabel() + + ilg.MarkLabel before + ilg.Emit(I_ldloc lb.LocalIndex) + + emitExpr ExpectedStackState.Value last + ilg.Emit(I_brcmp (I_bgt, after)) + + emitExpr ExpectedStackState.Empty body + + // loopVar++ + ilg.Emit(I_ldloc lb.LocalIndex) + ilg.Emit(mk_ldc 1) + ilg.Emit(I_add) + ilg.Emit(I_stloc lb.LocalIndex) + + ilg.Emit(I_br before) + ilg.MarkLabel(after) + + | NewArray(elementTy, elements) -> + ilg.Emit(mk_ldc (List.length elements)) + ilg.Emit(I_newarr (ILArrayShape.SingleDimensional, transType elementTy)) + + elements + |> List.iteri (fun i el -> + ilg.Emit(I_dup) + ilg.Emit(mk_ldc i) + emitExpr ExpectedStackState.Value el + ilg.Emit(I_stelem_any (ILArrayShape.SingleDimensional, transType elementTy))) + + popIfEmptyExpected expectedState + + | WhileLoop(cond, body) -> + let before = ilg.DefineLabel() + let after = ilg.DefineLabel() + + ilg.MarkLabel before + emitExpr ExpectedStackState.Value cond + ilg.Emit(I_brcmp (I_brfalse, after)) + emitExpr ExpectedStackState.Empty body + ilg.Emit(I_br before) + + ilg.MarkLabel after + + | Var v -> + if isEmpty expectedState then () else + + // Try to interpret this as a method parameter + let methIdx = parameterVars |> Array.tryFindIndex (fun p -> p = v) + match methIdx with + | Some idx -> + ilg.Emit((if isAddress expectedState then I_ldarga idx else I_ldarg idx) ) + | None -> + + // Try to interpret this as an implicit field in a class + let implicitCtorArgFieldOpt = implicitCtorArgsAsFields |> List.tryFind (fun f -> f.Name = v.Name) + match implicitCtorArgFieldOpt with + | Some ctorArgField -> + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, ctorArgField.FormalFieldSpec)) + | None -> + + // Try to interpret this as a local + match localsMap.TryGetValue v with + | true, localBuilder -> + let idx = localBuilder.LocalIndex + ilg.Emit(if isAddress expectedState then I_ldloca idx else I_ldloc idx) + | false, _ -> + failwith "unknown parameter/field" + + | Coerce (arg, ty) -> + // castClass may lead to observable side-effects - InvalidCastException + emitExpr ExpectedStackState.Value arg + let argTy = arg.Type + let targetTy = ty + if argTy.IsValueType && not targetTy.IsValueType then + ilg.Emit(I_box (transType argTy)) + elif not argTy.IsValueType && targetTy.IsValueType then + ilg.Emit(I_unbox_any (transType targetTy)) + else + ilg.Emit(I_castclass (transType targetTy)) + + popIfEmptyExpected expectedState + + | TypeOf(None, [t1], []) -> emitExpr expectedState (Expr.Value(t1)) + + | NaN -> emitExpr ExpectedStackState.Value <@@ Double.NaN @@> + + | NaNSingle -> emitExpr ExpectedStackState.Value <@@ Single.NaN @@> + + | MakeDecimal(args) -> + emitExpr ExpectedStackState.Value (Expr.NewObjectUnchecked(decimalConstructor(), args)) + + | LessThan(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Double | Single + | Int16 | Int32 | Int64 -> ilg.Emit(I_clt) + | Byte + | UInt16 | UInt32 | UInt64 -> ilg.Emit(I_clt_un) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("CompareOrdinal", [|t1; t1|]) |> transMeth, None)) + emitExpr ExpectedStackState.Value <@@ 0 @@> + ilg.Emit(I_clt) + | StaticMethod "op_LessThan" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (<) not supported for type %s" t1.Name + + + | GreaterThan(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Double | Single + | Int16 | Int32 | Int64 -> ilg.Emit(I_cgt) + | Byte + | UInt16 | UInt32 | UInt64 -> ilg.Emit(I_cgt_un) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("CompareOrdinal", [|t1; t1|]) |> transMeth, None)) + emitExpr ExpectedStackState.Value <@@ 0 @@> + ilg.Emit(I_cgt) + | StaticMethod "op_GreaterThan" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (>) not supported for type %s" t1.Name + + + | LessThanOrEqual(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Int16 | Int32 | Int64 -> + ilg.Emit(I_cgt) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | Byte + | Double | Single + | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_cgt_un) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("CompareOrdinal", [|t1; t1|]) |> transMeth, None)) + emitExpr ExpectedStackState.Value <@@ 0 @@> + ilg.Emit(I_cgt) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | StaticMethod "op_LessThanOrEqual" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (<=) not supported for type %s" t1.Name + + + | GreaterThanOrEqual(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Int16 | Int32 | Int64 -> + ilg.Emit(I_clt) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | Byte + | Double | Single + | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_clt_un) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("CompareOrdinal", [|t1; t1|]) |> transMeth, None)) + emitExpr ExpectedStackState.Value <@@ 0 @@> + ilg.Emit(I_clt) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | StaticMethod "op_GreaterThanOrEqual" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (>=) not supported for type %s" t1.Name + + | Equals(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Double | Single + | Int16 | Int32 | Int64 + | Byte + | UInt16 | UInt32 | UInt64 -> ilg.Emit(I_ceq) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("Equals", [|t1; t1|]) |> transMeth, None)) + | StaticMethod "op_Equality" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (=) not supported for type %s" t1.Name + + | NotEquals(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Bool | SByte | Char + | Double | Single + | Int16 | Int32 | Int64 + | Byte + | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_ceq) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("Equals", [|t1; t1|]) |> transMeth, None)) + emitExpr ExpectedStackState.Value <@@ false @@> + ilg.Emit(I_ceq) + | StaticMethod "op_Inequality" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (<>) not supported for type %s" t1.Name + + | Multiply(None, [t1; t2; _], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | SByte | Byte + | Int16 | Int32 | Int64 + | UInt16 | UInt32 | UInt64 + | Double | Single -> + ilg.Emit(I_mul) + | StaticMethod "op_Multiply" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (*) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | Addition(None, [t1; t2; _], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | SByte | Byte + | Int16 | Int32 | Int64 + | UInt16 | UInt32 | UInt64 + | Double | Single + | Char -> + ilg.Emit(I_add) + | String -> + ilg.Emit(I_call(Normalcall, (convTypeToTgt typeof).GetMethod("Concat", [|t1; t1|]) |> transMeth, None)) + | StaticMethod "op_Addition" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (+) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | Subtraction(None, [t1; t2; _], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | SByte | Byte + | Int16 | Int32 | Int64 + | UInt16 | UInt32 | UInt64 + | Double | Single -> + ilg.Emit(I_sub) + | StaticMethod "op_Subtraction" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (-) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | UnaryNegation(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | SByte + | Int16 | Int32 | Int64 + | Double | Single -> + ilg.Emit(I_neg) + | StaticMethod "op_UnaryNegation" [|t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (~-) not supported for type %s" t1.Name + + | Division(None, [t1; t2; _], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Byte | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_div_un) + | SByte | Int16 | Int32 | Int64 + | Double | Single -> + ilg.Emit(I_div) + | StaticMethod "op_Division" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (/) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | UnaryPlus(None, [t1], [a1]) -> + match t1.GetMethod("op_UnaryPlus", [|t1|]) with + | null -> + emitExpr expectedState a1 + | m -> + emitExpr ExpectedStackState.Value a1 + ilg.Emit(I_call(Normalcall, transMeth m, None)) + + | Modulus(None, [t1; t2; _], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Byte | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_rem_un) + | SByte | Int16 | Int32 | Int64 + | Double | Single -> + ilg.Emit(I_rem) + | StaticMethod "op_Modulus" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (%%) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | LeftShift(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + let maskShift (x : int) = + match a2 with + | Patterns.Value(:? int as v , _) -> + emitExpr ExpectedStackState.Value (Expr.Value (v &&& x)) + | _ -> + emitExpr ExpectedStackState.Value a2 + emitExpr ExpectedStackState.Value (Expr.Value x) + ilg.Emit(I_and) + ilg.Emit(I_shl) + match t1 with + | Int32 | UInt32 -> maskShift 31 + | Int64 | UInt64 -> maskShift 63 + | Int16 | UInt16 -> maskShift 15 + | SByte | Byte -> maskShift 7 + | StaticMethod "op_LeftShift" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (<<<) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | RightShift(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + let maskShift (x : int) = + match a2 with + | Patterns.Value(:? int as v , _) -> + emitExpr ExpectedStackState.Value (Expr.Value (v &&& x)) + | _ -> + emitExpr ExpectedStackState.Value a2 + emitExpr ExpectedStackState.Value (Expr.Value x) + ilg.Emit(I_and) + ilg.Emit(I_shr) + match t1 with + | Int32 | UInt32 -> maskShift 31 + | Int64 | UInt64 -> maskShift 63 + | Int16 | UInt16 -> maskShift 15 + | SByte | Byte -> maskShift 7 + | StaticMethod "op_RightShift" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (>>>) not supported for type %s" t1.Name + emitConvIfNecessary t1 + + | And(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_and) + | StaticMethod "op_And" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (&&&) not supported for type %s" t1.Name + + | Or(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_or) + | StaticMethod "op_Or" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (|||) not supported for type %s" t1.Name + + | Xor(None, [t1], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_xor) + | StaticMethod "op_Xor" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (^^^) not supported for type %s" t1.Name + + | Not(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_not) + | StaticMethod "op_Not" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator (~~~) not supported for type %s" t1.Name + + | Max(None, [t1], [a1; a2]) -> + match t1 with + | Double -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + let m = mathTypeTgt.GetMethod("Max", [|t1; t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + ilg.Emit(I_conv DT_R8) + let t = convTypeToTgt typeof + let m = mathTypeTgt.GetMethod("Max", [|t;t|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | _ -> + match a1, a2 with + | (Var _ | Value _), (Var _ | Value _) -> + Expr.IfThenElseUnchecked(lessThan a1 a2, a2, a1) + |> emitExpr ExpectedStackState.Value + | (Var _ | Value _), _ -> + let e2 = Var("e2", a2.Type) + Expr.Let(e2, a2, + Expr.IfThenElseUnchecked(lessThan a1 (Expr.Var e2), Expr.Var e2, a1)) + |> emitExpr ExpectedStackState.Value + | _, (Var _ | Value _) -> + let e1 = Var("e1", a1.Type) + Expr.Let(e1, a1, + Expr.IfThenElseUnchecked((lessThan (Expr.Var e1) a2, a2, (Expr.Var e1)))) + |> emitExpr ExpectedStackState.Value + | _ -> + let e1 = Var("e1", a1.Type) + let e2 = Var("e2", a2.Type) + Expr.Let(e1, a1, + Expr.Let(e2, a2, + Expr.IfThenElseUnchecked(lessThan (Expr.Var e1) (Expr.Var e2), Expr.Var e2, Expr.Var e1))) + |> emitExpr ExpectedStackState.Value + + | Min(None, [t1], [a1; a2]) -> + match t1 with + | Double -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + let m = mathTypeTgt.GetMethod("Min", [|t1; t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + ilg.Emit(I_conv DT_R8) + let t = convTypeToTgt typeof + let m = mathTypeTgt.GetMethod("Min", [|t;t|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | _ -> + match a1, a2 with + | (Var _ | Value _), (Var _ | Value _) -> + Expr.IfThenElseUnchecked(lessThan a1 a2, a1, a2) + |> emitExpr ExpectedStackState.Value + | (Var _ | Value _), _ -> + let e2 = Var("e2", a2.Type) + Expr.Let(e2, a2, + Expr.IfThenElseUnchecked(lessThan a1 (Expr.Var e2), a1, Expr.Var e2)) + |> emitExpr ExpectedStackState.Value + | _, (Var _ | Value _) -> + let e1 = Var("e1", a1.Type) + Expr.Let(e1, a1, + Expr.IfThenElseUnchecked((lessThan (Expr.Var e1) a2, Expr.Var e1, a2))) + |> emitExpr ExpectedStackState.Value + | _ -> + let e1 = Var("e1", a1.Type) + let e2 = Var("e2", a2.Type) + Expr.Let(e1, a1, + Expr.Let(e2, a2, + Expr.IfThenElseUnchecked(lessThan (Expr.Var e1) (Expr.Var e2), Expr.Var e1, Expr.Var e2))) + |> emitExpr ExpectedStackState.Value + + | CallByte(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_conv DT_U1) + | String -> + let m = languagePrimitivesType().GetMethod("ParseUInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv_ovf DT_U1) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'byte' not supported for type %s" t1.Name + + | CallSByte(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_conv DT_I1) + | String -> + let m = languagePrimitivesType().GetMethod("ParseInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv_ovf DT_I1) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'sbyte' not supported for type %s" t1.Name + + | CallUInt16(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_conv DT_U2) + | String -> + let m = languagePrimitivesType().GetMethod("ParseUInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv_ovf DT_U2) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'uint16' not supported for type %s" t1.Name + + | CallInt16(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | Int32 | UInt32 + | Int64 | UInt64 + | Int16 | UInt16 + | SByte | Byte -> ilg.Emit(I_conv DT_I2) + | String -> + let m = languagePrimitivesType().GetMethod("ParseInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv_ovf DT_I2) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'int16' not supported for type %s" t1.Name + + | CallUInt32(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | UInt16 | UInt32 + | Int64 | UInt64 + | Byte -> ilg.Emit(I_conv DT_U4) + | Int32 | Int16 | SByte -> () + | String -> + let m = languagePrimitivesType().GetMethod("ParseUInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'uint32' not supported for type %s" t1.Name + + | CallInt(None, [t1], [a1]) + | CallInt32(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | UInt16 + | Int64 | UInt64 + | Byte -> ilg.Emit(I_conv DT_I4) + | UInt32 | Int32 | Int16 | SByte -> () + | String -> + let m = languagePrimitivesType().GetMethod("ParseInt32") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'int32' not supported for type %s" t1.Name + + | CallUInt64(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Char + | Double | Single + | UInt16 | UInt32 + | Byte -> ilg.Emit(I_conv DT_U8) + | SByte | Int32 | Int16 -> ilg.Emit(I_conv DT_I8) + | Int64 | UInt64 -> () + | String -> + let m = languagePrimitivesType().GetMethod("ParseUInt64") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'uint64' not supported for type %s" t1.Name + + | CallInt64(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Double | Single + | Int64 | Int32 | Int16 + | SByte -> ilg.Emit(I_conv DT_I8) + | Char | Byte | UInt16 | UInt32 -> + ilg.Emit(I_conv DT_U8) + | UInt64 -> () + | String -> + let m = languagePrimitivesType().GetMethod("ParseInt64") + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'int64' not supported for type %s" t1.Name + + | CallSingle(None, [t1], [a1]) + | CallFloat32(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Double | Single + | Int64 | Int32 | Int16 + | SByte -> ilg.Emit(I_conv DT_R4) + | Char | Byte | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_conv DT_R) + ilg.Emit(I_conv DT_R4) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> + match expr.Type with + | StaticMethodWithReturnType "Parse" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'float32' not supported for type %s" t1.Name + + | CallDouble(None, [t1], [a1]) + | CallFloat(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Double | Single + | Int64 | Int32 | Int16 + | SByte -> ilg.Emit(I_conv DT_R8) + | Char | Byte | UInt16 | UInt32 | UInt64 -> + ilg.Emit(I_conv DT_R) + ilg.Emit(I_conv DT_R8) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> + match expr.Type with + | StaticMethodWithReturnType "Parse" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'float' not supported for type %s" t1.Name + + | CallDecimal(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + let rtTgt = decimalTypeTgt + if t1 = stringTypeTgt then + let m = rtTgt.GetMethod("Parse", [|stringTypeTgt|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + else + match convertTypeTgt.GetMethod("ToDecimal", [|t1|]) with + | null -> + let m = + t1.GetMethods(BindingFlags.Static ||| BindingFlags.Public) + |> Array.tryFind + (fun x -> + x.Name = "op_Explicit" + && x.ReturnType = rtTgt + && (x.GetParameters() |> Array.map (fun i -> i.ParameterType)) = [|t1|]) + match m with + | None -> + failwithf "decimal operator on %s not supported" (t1.Name) + | Some m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | toDecimal -> ilg.Emit(I_call(Normalcall, transMeth toDecimal, None)) + + | CallChar(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Double | Single + | Int64 | Int32 | Int16 + | Char | Byte | UInt16 | UInt32 | UInt64 + | SByte -> ilg.Emit(I_conv DT_U2) + | StaticMethodWithReturnType "op_Explicit" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> + match expr.Type with + | StaticMethodWithReturnType "Parse" [|t1|] expr.Type m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Operator 'char' not supported for type %s" t1.Name + + | Ignore(None, [t1], [a1]) -> emitExpr expectedState a1 + + | GetArray(None, [ty], [arr; index]) -> + // observable side-effect - IndexOutOfRangeException + emitExpr ExpectedStackState.Value arr + emitExpr ExpectedStackState.Value index + if isAddress expectedState then + ilg.Emit(I_ldelema (ILReadonly.ReadonlyAddress, ILArrayShape.SingleDimensional, transType ty)) + else + ilg.Emit(I_ldelem_any (ILArrayShape.SingleDimensional, transType ty)) + + popIfEmptyExpected expectedState + + | GetArray2D(None, _ty, arr::indices) + | GetArray3D(None, _ty, arr::indices) + | GetArray4D(None, _ty, arr::indices) -> + + let meth = + let name = if isAddress expectedState then "Address" else "Get" + arr.Type.GetMethod(name) + + // observable side-effect - IndexOutOfRangeException + emitExpr ExpectedStackState.Value arr + for index in indices do + emitExpr ExpectedStackState.Value index + + //if isAddress expectedState then + // ilg.Emit(I_readonly) + + ilg.Emit(mkNormalCall (transMeth meth)) + + popIfEmptyExpected expectedState + + | Abs(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Int32 | Double | Single | Int64 | Int16 | SByte | Decimal -> + let m = mathTypeTgt.GetMethod("Abs", [|t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | StaticMethod "Abs" [|t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Abs not supported for type %s" t1.Name + + | Acos(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Acos" + + | Asin(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Asin" + + | Atan(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Atan" + + | Atan2(None, [t1;t2], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Double -> + let m = mathTypeTgt.GetMethod("Atan2", [|t1; t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + ilg.Emit(I_conv DT_R8) + let t = convTypeToTgt typeof + let m = mathTypeTgt.GetMethod("Atan2", [|t;t|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | StaticMethod "Atan2" [|t1; t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Atan2 not supported for type %s" t1.Name + + | Ceil(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Ceiling" + + | Exp(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Exp" + + | Floor(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Floor" + + | Truncate(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Truncate" + + | Round(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Round" + + | Sign(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + match t1 with + | Int32 | Double | Single | Int64 | Int16 | SByte | Decimal -> + let m = mathTypeTgt.GetMethod("Sign", [|t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + ilg.Emit(I_conv DT_R8) + let m = mathTypeTgt.GetMethod("Sign", [|convTypeToTgt typeof|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | StaticMethod "Sign" [|t1|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Sign not supported for type %s" t1.Name + + | Log(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Log" + + | Log10(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Log10" + + | Sqrt(None, [t1; t2], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Sqrt" + + | Cos(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Cos" + + | Cosh(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Cosh" + + | Sin(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Sin" + + | Sinh(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Sinh" + + | Tan(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Tan" + + | Tanh(None, [t1], [a1]) -> + emitExpr ExpectedStackState.Value a1 + mathOp t1 "Tanh" + + | Pow(None, [t1; t2], [a1; a2]) -> + emitExpr ExpectedStackState.Value a1 + emitExpr ExpectedStackState.Value a2 + match t1 with + | Double -> + let m = mathTypeTgt.GetMethod("Pow", [|t1; t1|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | Single -> + ilg.Emit(I_conv DT_R8) + let t = convTypeToTgt typeof + let m = mathTypeTgt.GetMethod("Pow", [|t;t|]) + ilg.Emit(I_call(Normalcall, transMeth m, None)) + ilg.Emit(I_conv DT_R4) + | StaticMethod "Pow" [|t1; t2|] m -> + ilg.Emit(I_call(Normalcall, transMeth m, None)) + | _ -> failwithf "Pow not supported for type %s" t1.Name + + | FieldGet (None, field) when field.DeclaringType.IsEnum -> + if expectedState <> ExpectedStackState.Empty then + emitExpr expectedState (Expr.Value(field.GetRawConstantValue(), field.FieldType.GetEnumUnderlyingType())) + + | FieldGet (objOpt, field) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + if field.IsStatic then + ilg.Emit(I_ldsfld (ILVolatility.Nonvolatile, transFieldSpec field)) + else + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, transFieldSpec field)) + + | FieldSet (objOpt, field, v) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + emitExpr ExpectedStackState.Value v + if field.IsStatic then + ilg.Emit(I_stsfld (ILVolatility.Nonvolatile, transFieldSpec field)) + else + ilg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, transFieldSpec field)) + + | Call (objOpt, meth, args) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + + for pe in args do + emitExpr ExpectedStackState.Value pe + + // Handle the case where this is a generic method instantiated at a type being compiled + let mappedMeth = transMeth meth + + match objOpt with + | Some obj when meth.IsAbstract || meth.IsVirtual -> + if obj.Type.IsValueType then + ilg.Emit(I_callconstraint (Normalcall, transType obj.Type, mappedMeth, None)) + else + ilg.Emit(I_callvirt (Normalcall, mappedMeth, None)) + | _ -> + ilg.Emit(mkNormalCall mappedMeth) + + let returnTypeIsVoid = (mappedMeth.FormalReturnType = ILType.Void) + match returnTypeIsVoid, (isEmpty expectedState) with + | false, true -> + // method produced something, but we don't need it + pop() + | true, false when expr.Type = typeof -> + // if we need result and method produce void and result should be unit - push null as unit value on stack + ilg.Emit(I_ldnull) + | _ -> () - member __.AddMemberDelayed(memberFunction : unit -> #MemberInfo) = - this.AddMembersDelayed(fun () -> [memberFunction()]) + | NewObject (ctor, args) -> + for pe in args do + emitExpr ExpectedStackState.Value pe + ilg.Emit(I_newobj (transCtorSpec ctor, None)) - member __.AddAssemblyTypesAsNestedTypesDelayed (assemblyf : unit -> System.Reflection.Assembly) = - let bucketByPath nodef tipf (items: (string list * 'Value) list) = - // Find all the items with an empty key list and call 'tipf' - let tips = - [ for (keylist,v) in items do - match keylist with - | [] -> yield tipf v - | _ -> () ] + popIfEmptyExpected expectedState + + | DefaultValue (t) -> + let ilt = transType t + let lb = ilg.DeclareLocal ilt + ilg.Emit(I_ldloca lb.LocalIndex) + ilg.Emit(I_initobj ilt) + ilg.Emit(I_ldloc lb.LocalIndex) + + | Value (obj, _ty) -> + let rec emitC (v:obj) = + match v with + | :? string as x -> ilg.Emit(I_ldstr x) + | :? int8 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? uint8 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int16 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? uint16 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int32 as x -> ilg.Emit(mk_ldc x) + | :? uint32 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int64 as x -> ilg.Emit(mk_ldc_i8 x) + | :? uint64 as x -> ilg.Emit(mk_ldc_i8 (int64 x)) + | :? char as x -> ilg.Emit(mk_ldc (int32 x)) + | :? bool as x -> ilg.Emit(mk_ldc (if x then 1 else 0)) + | :? float32 as x -> ilg.Emit(I_ldc (DT_R4, ILConst.R4 x)) + | :? float as x -> ilg.Emit(I_ldc(DT_R8, ILConst.R8 x)) + #if !FX_NO_GET_ENUM_UNDERLYING_TYPE + | :? Enum as x when x.GetType().GetEnumUnderlyingType() = typeof -> ilg.Emit(mk_ldc (unbox v)) + #endif + | :? Type as ty -> + ilg.Emit(I_ldtoken (ILToken.ILType (transType ty))) + ilg.Emit(mkNormalCall (transMeth (getTypeFromHandleMethod()))) + | :? decimal as x -> + let bits = Decimal.GetBits x + ilg.Emit(mk_ldc bits.[0]) + ilg.Emit(mk_ldc bits.[1]) + ilg.Emit(mk_ldc bits.[2]) + do + let sign = (bits.[3] &&& 0x80000000) <> 0 + ilg.Emit(if sign then mk_ldc 1 else mk_ldc 0) + do + let scale = (bits.[3] >>> 16) &&& 0x7F + ilg.Emit(mk_ldc scale) + ilg.Emit(I_newobj (transCtorSpec (decimalConstructor()), None)) + | :? DateTime as x -> + ilg.Emit(mk_ldc_i8 x.Ticks) + ilg.Emit(mk_ldc (int x.Kind)) + ilg.Emit(I_newobj (transCtorSpec (dateTimeConstructor()), None)) + | :? DateTimeOffset as x -> + ilg.Emit(mk_ldc_i8 x.Ticks) + ilg.Emit(mk_ldc_i8 x.Offset.Ticks) + ilg.Emit(I_newobj (transCtorSpec (timeSpanConstructor()), None)) + ilg.Emit(I_newobj (transCtorSpec (dateTimeOffsetConstructor()), None)) + | null -> ilg.Emit(I_ldnull) + | _ -> failwithf "unknown constant '%A' of type '%O' in generated method. You may need to avoid variable capture in a quotation specifying a type provider." v (v.GetType()) + if isEmpty expectedState then () + else emitC obj + + | Let(v, e, b) -> + let ty = transType v.Type + let lb = ilg.DeclareLocal ty + //printfn "declared local %d of original type %O and target type %O for variable %O" lb.LocalIndex v.Type ty v + localsMap.Add (v, lb) + emitExpr ExpectedStackState.Value e + ilg.Emit(I_stloc lb.LocalIndex) + emitExpr expectedState b + + | TypeTest(e, tgtTy) -> + let tgtTyT = transType tgtTy + emitExpr ExpectedStackState.Value e + ilg.Emit(I_isinst tgtTyT) + + | Sequential(e1, e2) -> + emitExpr ExpectedStackState.Empty e1 + emitExpr expectedState e2 + + | IfThenElse(cond, ifTrue, ifFalse) -> + let ifFalseLabel = ilg.DefineLabel() + let endLabel = ilg.DefineLabel() + + emitExpr ExpectedStackState.Value cond + + ilg.Emit(I_brcmp (I_brfalse, ifFalseLabel)) + + emitExpr expectedState ifTrue + ilg.Emit(I_br endLabel) + + ilg.MarkLabel(ifFalseLabel) + emitExpr expectedState ifFalse + + ilg.Emit(I_nop) + ilg.MarkLabel(endLabel) + + | TryWith(body, _filterVar, _filterBody, catchVar, catchBody) -> + + let stres, ldres = + if isEmpty expectedState then ignore, ignore + else + let local = ilg.DeclareLocal (transType body.Type) + let stres = fun () -> ilg.Emit(I_stloc local.LocalIndex) + let ldres = fun () -> ilg.Emit(I_ldloc local.LocalIndex) + stres, ldres - // Find all the items with a non-empty key list. Bucket them together by - // the first key. For each bucket, call 'nodef' on that head key and the bucket. - let nodes = - let buckets = new Dictionary<_,_>(10) - for (keylist,v) in items do - match keylist with - | [] -> () - | key::rest -> - buckets.[key] <- (rest,v) :: (if buckets.ContainsKey key then buckets.[key] else []); + let exceptionVar = ilg.DeclareLocal(transType catchVar.Type) + localsMap.Add(catchVar, exceptionVar) - [ for (KeyValue(key,items)) in buckets -> nodef key items ] + ilg.BeginExceptionBlock() - tips @ nodes - this.AddMembersDelayed (fun _ -> - let topTypes = [ for ty in assemblyf().GetTypes() do - if not ty.IsNested then - let namespaceParts = match ty.Namespace with null -> [] | s -> s.Split '.' |> Array.toList - yield namespaceParts, ty ] - let rec loop types = - types - |> bucketByPath - (fun namespaceComponent typesUnderNamespaceComponent -> - let t = ProvidedTypeDefinition(namespaceComponent, baseType = Some typeof) - t.AddMembers (loop typesUnderNamespaceComponent) - (t :> Type)) - (fun ty -> ty) - loop topTypes) + emitExpr expectedState body + stres() + ilg.EndGuardedBlock() - /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". - member __.DefineStaticParameters(staticParameters : list, apply : (string -> obj[] -> ProvidedTypeDefinition)) = - staticParams <- staticParameters - staticParamsApply <- Some apply - - /// Get ParameterInfo[] for the parametric type parameters (//s GetGenericParameters) - member __.GetStaticParameters() = [| for p in staticParams -> p :> ParameterInfo |] - - /// Instantiate parametrics type - member __.MakeParametricType(name:string,args:obj[]) = - if staticParams.Length>0 then - if staticParams.Length <> args.Length then - failwith (sprintf "ProvidedTypeDefinition: expecting %d static parameters but given %d for type %s" staticParams.Length args.Length (fullName.Force())) - match staticParamsApply with - | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" - | Some f -> f name args + ilg.BeginCatchBlock(transType catchVar.Type) + ilg.Emit(I_stloc exceptionVar.LocalIndex) + emitExpr expectedState catchBody + stres() + ilg.EndExceptionBlock() - else - failwith (sprintf "ProvidedTypeDefinition: static parameters supplied but not expected for %s" (fullName.Force())) + ldres() - member __.DeclaringTypeImpl - with set x = - match container with TypeContainer.TypeToBeDecided -> () | _ -> failwith (sprintf "container type for '%s' was already set to '%s'" this.FullName x.FullName); - container <- TypeContainer.Type x + | TryFinally(body, finallyBody) -> - // Implement overloads - override __.Assembly = theAssembly.Force() + let stres, ldres = + if isEmpty expectedState then ignore, ignore + else + let local = ilg.DeclareLocal (transType body.Type) + let stres = fun () -> ilg.Emit(I_stloc local.LocalIndex) + let ldres = fun () -> ilg.Emit(I_ldloc local.LocalIndex) + stres, ldres + + ilg.BeginExceptionBlock() |> ignore - member __.SetAssembly assembly = theAssembly <- lazy assembly + emitExpr expectedState body + stres() + ilg.EndGuardedBlock() - member __.SetAssemblyLazy assembly = theAssembly <- assembly + ilg.BeginFinallyBlock() |> ignore - override __.FullName = fullName.Force() + emitExpr expectedState finallyBody - override __.Namespace = rootNamespace.Force() + ilg.EndExceptionBlock() - override __.BaseType = match baseType.Value with Some ty -> ty | None -> null - - // Constructors - override __.GetConstructors bindingAttr = - [| for m in this.GetMembers bindingAttr do - if m.MemberType = MemberTypes.Constructor then - yield (m :?> ConstructorInfo) |] - // Methods - override __.GetMethodImpl(name, bindingAttr, _binderBinder, _callConvention, _types, _modifiers) : MethodInfo = - let membersWithName = - [ for m in this.GetMembers(bindingAttr) do - if m.MemberType.HasFlag(MemberTypes.Method) && m.Name = name then - yield m ] - match membersWithName with - | [] -> null - | [meth] -> meth :?> MethodInfo - | _several -> failwith "GetMethodImpl. not support overloads" - - override __.GetMethods bindingAttr = - this.GetMembers bindingAttr - |> Array.filter (fun m -> m.MemberType.HasFlag(MemberTypes.Method)) - |> Array.map (fun m -> m :?> MethodInfo) - - // Fields - override __.GetField(name, bindingAttr) = - let fields = [| for m in this.GetMembers bindingAttr do - if m.MemberType.HasFlag(MemberTypes.Field) && (name = null || m.Name = name) then // REVIEW: name = null. Is that a valid query?! - yield m |] - if fields.Length > 0 then fields.[0] :?> FieldInfo else null - - override __.GetFields bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Field) then yield m :?> FieldInfo |] - - override __.GetInterface(_name, _ignoreCase) = notRequired "GetInterface" this.Name - - override __.GetInterfaces() = - [| yield! getInterfaces() |] - - member __.GetInterfaceImplementations() = - [| yield! getInterfaces() |] - - member __.AddInterfaceImplementation ityp = interfaceImpls.Add ityp - - member __.AddInterfaceImplementationsDelayed itypf = interfaceImplsDelayed.Add itypf - - member __.GetMethodOverrides() = - [| yield! methodOverrides |] - - member __.DefineMethodOverride (bodyMethInfo,declMethInfo) = methodOverrides.Add (bodyMethInfo, declMethInfo) - - // Events - override __.GetEvent(name, bindingAttr) = - let events = this.GetMembers bindingAttr - |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Event) && (name = null || m.Name = name)) - if events.Length > 0 then events.[0] :?> EventInfo else null - - override __.GetEvents bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Event) then yield downcast m |] - - // Properties - override __.GetProperties bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Property) then yield downcast m |] - - override __.GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers) = - if returnType <> null then failwith "Need to handle specified return type in GetPropertyImpl" - if types <> null then failwith "Need to handle specified parameter types in GetPropertyImpl" - if modifiers <> null then failwith "Need to handle specified modifiers in GetPropertyImpl" - if binder <> null then failwith "Need to handle binder in GetPropertyImpl" - let props = this.GetMembers bindingAttr |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Property) && (name = null || m.Name = name)) // Review: nam = null, valid query!? - if props.Length > 0 then - props.[0] :?> PropertyInfo - else - null - // Nested Types - override __.MakeArrayType() = ProvidedSymbolType(SymbolKind.SDArray, [this]) :> Type - override __.MakeArrayType arg = ProvidedSymbolType(SymbolKind.Array arg, [this]) :> Type - override __.MakePointerType() = ProvidedSymbolType(SymbolKind.Pointer, [this]) :> Type - override __.MakeByRefType() = ProvidedSymbolType(SymbolKind.ByRef, [this]) :> Type - - // FSharp.Data addition: this method is used by Debug.fs and QuotationBuilder.fs - // Emulate the F# type provider type erasure mechanism to get the - // actual (erased) type. We erase ProvidedTypes to their base type - // and we erase array of provided type to array of base type. In the - // case of generics all the generic type arguments are also recursively - // replaced with the erased-to types - static member EraseType(t:Type) = - match t with - | :? ProvidedTypeDefinition -> ProvidedTypeDefinition.EraseType t.BaseType - | :? ProvidedSymbolType as sym -> - match sym.Kind, sym.Args with - | SymbolKind.SDArray, [typ] -> - let (t:Type) = ProvidedTypeDefinition.EraseType typ - t.MakeArrayType() - | SymbolKind.Generic genericTypeDefinition, _ when not genericTypeDefinition.IsGenericTypeDefinition -> - // Unit of measure parameters can match here, but not really generic types. - genericTypeDefinition.UnderlyingSystemType - | SymbolKind.Generic genericTypeDefinition, typeArgs -> - let genericArguments = - typeArgs - |> List.toArray - |> Array.map ProvidedTypeDefinition.EraseType - genericTypeDefinition.MakeGenericType(genericArguments) - | _ -> failwith "getTypeErasedTo: Unsupported ProvidedSymbolType" - | t when t.IsGenericType && not t.IsGenericTypeDefinition -> - let genericTypeDefinition = t.GetGenericTypeDefinition() - let genericArguments = - t.GetGenericArguments() - |> Array.map ProvidedTypeDefinition.EraseType - genericTypeDefinition.MakeGenericType(genericArguments) - | t -> t + ldres() - static member Logger : (string -> unit) option ref = ref None + | VarSet(v, e) -> + emitExpr ExpectedStackState.Value e + match localsMap.TryGetValue v with + | true, localBuilder -> + ilg.Emit(I_stloc localBuilder.LocalIndex) + | false, _ -> + failwith "unknown parameter/field in assignment. Only assignments to locals are currently supported by TypeProviderEmit" + | Lambda(v, body) -> + let lambdaLocals = Dictionary() + emitLambda(ilg, v, body, expr.GetFreeVars(), lambdaLocals, parameterVars) + popIfEmptyExpected expectedState - // The binding attributes are always set to DeclaredOnly ||| Static ||| Instance ||| Public when GetMembers is called directly by the F# compiler - // However, it's possible for the framework to generate other sets of flags in some corner cases (e.g. via use of `enum` with a provided type as the target) - override __.GetMembers bindingAttr = - let mems = - getMembers() - |> Array.filter (fun mem -> - let isStatic, isPublic = - match mem with - | :? FieldInfo as f -> f.IsStatic, f.IsPublic - | :? MethodInfo as m -> m.IsStatic, m.IsPublic - | :? ConstructorInfo as c -> c.IsStatic, c.IsPublic - | :? PropertyInfo as p -> - let m = if p.CanRead then p.GetGetMethod() else p.GetSetMethod() - m.IsStatic, m.IsPublic - | :? EventInfo as e -> - let m = e.GetAddMethod() - m.IsStatic, m.IsPublic - | :? Type as ty -> - true, ty.IsNestedPublic - | _ -> failwith (sprintf "Member %O is of unexpected type" mem) - bindingAttr.HasFlag(if isStatic then BindingFlags.Static else BindingFlags.Instance) && - ( - (bindingAttr.HasFlag(BindingFlags.Public) && isPublic) || (bindingAttr.HasFlag(BindingFlags.NonPublic) && not isPublic) - )) - - if bindingAttr.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then mems - else - // FSharp.Data change: just using this.BaseType is not enough in the case of CsvProvider, - // because the base type is CsvRow, so we have to erase recursively to CsvRow - let baseMems = (ProvidedTypeDefinition.EraseType this.BaseType).GetMembers bindingAttr - Array.append mems baseMems - - override __.GetNestedTypes bindingAttr = - this.GetMembers bindingAttr - |> Array.filter(fun m -> - m.MemberType.HasFlag(MemberTypes.NestedType) || - // Allow 'fake' nested types that are actually real .NET types - m.MemberType.HasFlag(MemberTypes.TypeInfo)) |> Array.map(fun m -> m :?> Type) - - override __.GetMember(name,mt,_bindingAttr) = - let mt = - if mt &&& MemberTypes.NestedType = MemberTypes.NestedType then - mt ||| MemberTypes.TypeInfo - else - mt - getMembers() |> Array.filter(fun m->0<>(int(m.MemberType &&& mt)) && m.Name = name) + | n -> + failwithf "unknown expression '%A' in generated method" n - override __.GetNestedType(name, bindingAttr) = - let nt = this.GetMember(name, MemberTypes.NestedType ||| MemberTypes.TypeInfo, bindingAttr) - match nt.Length with - | 0 -> null - | 1 -> downcast nt.[0] - | _ -> failwith (sprintf "There is more than one nested type called '%s' in type '%s'" name this.FullName) - - // Attributes, etc.. - override __.GetAttributeFlagsImpl() = adjustTypeAttributes attributes this.IsNested - override __.IsArrayImpl() = false - override __.IsByRefImpl() = false - override __.IsPointerImpl() = false - override __.IsPrimitiveImpl() = false - override __.IsCOMObjectImpl() = false - override __.HasElementTypeImpl() = false - override __.Name = className - override __.DeclaringType = declaringType.Force() - override __.MemberType = if this.IsNested then MemberTypes.NestedType else MemberTypes.TypeInfo - override __.GetHashCode() = rootNamespace.GetHashCode() ^^^ className.GetHashCode() - override __.Equals(that:obj) = - match that with - | null -> false - | :? ProvidedTypeDefinition as ti -> System.Object.ReferenceEquals(this,ti) - | _ -> false - - override __.GetGenericArguments() = [||] - override __.ToString() = this.Name - - - override __.Module : Module = notRequired "Module" this.Name - override __.GUID = Guid.Empty - override __.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers) = null - override __.GetCustomAttributes(_inherit) = [| |] - override __.GetCustomAttributes(_attributeType, _inherit) = [| |] - override __.IsDefined(_attributeType: Type, _inherit) = false - - override __.GetElementType() = notRequired "Module" this.Name - override __.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "Module" this.Name - override __.AssemblyQualifiedName = notRequired "Module" this.Name - member __.IsErased - with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 - and set v = - if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.IsErased) - else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) - - member __.SuppressRelocation - with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 - and set v = - if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.SuppressRelocate) - else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) - -type AssemblyGenerator(assemblyFileName) = - let assemblyShortName = Path.GetFileNameWithoutExtension assemblyFileName - let assemblyName = AssemblyName assemblyShortName -#if FX_NO_LOCAL_FILESYSTEM - let assembly = - System.AppDomain.CurrentDomain.DefineDynamicAssembly(name=assemblyName,access=AssemblyBuilderAccess.Run) - let assemblyMainModule = - assembly.DefineDynamicModule("MainModule") -#else - let assembly = - System.AppDomain.CurrentDomain.DefineDynamicAssembly(name=assemblyName,access=(AssemblyBuilderAccess.Save ||| AssemblyBuilderAccess.Run),dir=Path.GetDirectoryName assemblyFileName) - let assemblyMainModule = - assembly.DefineDynamicModule("MainModule", Path.GetFileName assemblyFileName) -#endif - let typeMap = Dictionary(HashIdentity.Reference) - let typeMapExtra = Dictionary(HashIdentity.Structural) - let uniqueLambdaTypeName() = - // lambda name should be unique across all types that all type provider might contribute in result assembly - sprintf "Lambda%O" (Guid.NewGuid()) - - member __.Assembly = assembly :> Assembly - - /// Emit the given provided type definitions into an assembly and adjust 'Assembly' property of all type definitions to return that - /// assembly. - member __.Generate(providedTypeDefinitions:(ProvidedTypeDefinition * string list option) list) = - let ALL = BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Static ||| BindingFlags.Instance - // phase 1 - set assembly fields and emit type definitions - begin - let rec typeMembers (tb:TypeBuilder) (td : ProvidedTypeDefinition) = - for ntd in td.GetNestedTypes(ALL) do - nestedType tb ntd - - and nestedType (tb:TypeBuilder) (ntd : Type) = - match ntd with - | :? ProvidedTypeDefinition as pntd -> - if pntd.IsErased then invalidOp ("The nested provided type "+pntd.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition") - // Adjust the attributes - we're codegen'ing this type as nested - let attributes = adjustTypeAttributes ntd.Attributes true - let ntb = tb.DefineNestedType(pntd.Name,attr=attributes) - pntd.SetAssembly null - typeMap.[pntd] <- ntb - typeMembers ntb pntd - | _ -> () - - for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitions do - match enclosingGeneratedTypeNames with - | None -> - // Filter out the additional TypeProviderTypeAttributes flags - let attributes = pt.Attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) - &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) - // Adjust the attributes - we're codegen'ing as non-nested - let attributes = adjustTypeAttributes attributes false - let tb = assemblyMainModule.DefineType(name=pt.FullName,attr=attributes) - pt.SetAssembly null - typeMap.[pt] <- tb - typeMembers tb pt - | Some ns -> - let otb,_ = - ((None,""),ns) ||> List.fold (fun (otb:TypeBuilder option,fullName) n -> - let fullName = if fullName = "" then n else fullName + "." + n - let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra.[fullName] else None - let tb = - match priorType with - | Some tbb -> tbb - | None -> - // OK, the implied nested type is not defined, define it now - let attributes = - TypeAttributes.Public ||| - TypeAttributes.Class ||| - TypeAttributes.Sealed - // Filter out the additional TypeProviderTypeAttributes flags - let attributes = adjustTypeAttributes attributes otb.IsSome - let tb = - match otb with - | None -> assemblyMainModule.DefineType(name=n,attr=attributes) - | Some (otb:TypeBuilder) -> otb.DefineNestedType(name=n,attr=attributes) - typeMapExtra.[fullName] <- tb - tb - (Some tb, fullName)) - nestedType otb.Value pt - end - let rec convType (ty:Type) = - match ty with - | :? ProvidedTypeDefinition as ptd -> - if typeMap.ContainsKey ptd then typeMap.[ptd] :> Type else ty - | _ -> - if ty.IsGenericType then ty.GetGenericTypeDefinition().MakeGenericType (Array.map convType (ty.GetGenericArguments())) - elif ty.HasElementType then - let ety = convType (ty.GetElementType()) - if ty.IsArray then - let rank = ty.GetArrayRank() - if rank = 1 then ety.MakeArrayType() - else ety.MakeArrayType rank - elif ty.IsPointer then ety.MakePointerType() - elif ty.IsByRef then ety.MakeByRefType() - else ty - else ty - - let ctorMap = Dictionary(HashIdentity.Reference) - let methMap = Dictionary(HashIdentity.Reference) - let fieldMap = Dictionary(HashIdentity.Reference) - - let iterateTypes f = - let rec typeMembers (ptd : ProvidedTypeDefinition) = - let tb = typeMap.[ptd] + member __.EmitExpr (expectedState, expr) = emitExpr expectedState expr + + //------------------------------------------------------------------------------------------------- + // AssemblyCompiler: the assembly compiler for generative type providers. + + /// Implements System.Reflection.Assembly backed by ILModuleReader over generated bytes + type AssemblyCompiler(targetAssembly: ProvidedAssembly, context: ProvidedTypesContext) = + + + let typeMap = Dictionary(HashIdentity.Reference) + let typeMapExtra = Dictionary(HashIdentity.Structural) + let ctorMap = Dictionary(HashIdentity.Reference) + let methMap = Dictionary(HashIdentity.Reference) + let fieldMap = Dictionary(HashIdentity.Reference) + let genUniqueTypeName() = + // lambda name should be unique across all types that all type provider might contribute in result assembly + sprintf "Lambda%O" (Guid.NewGuid()) + + let convTypeToTgt ty = context.ConvertSourceTypeToTarget ty + let rec defineNestedTypes (tb:ILTypeBuilder) (td: ProvidedTypeDefinition) = + Debug.Assert(td.BelongsToTargetModel, "expected a target ProvidedTypeDefinition in nested type") + for ntd in td.GetNestedTypes(bindAll) do + defineNestedType tb ntd + + and defineNestedType (tb:ILTypeBuilder) (ntd: Type) = + match ntd with + | :? ProvidedTypeDefinition as pntd -> + if pntd.IsErased then failwith ("The nested provided type "+pntd.Name+" is marked as erased and cannot be converted to a generated type. Set 'IsErased=false' on the ProvidedTypeDefinition") + Debug.Assert(pntd.BelongsToTargetModel, "expected a target ProvidedTypeDefinition in nested type") + // Adjust the attributes - we're codegen'ing this type as nested + let attributes = adjustTypeAttributes true ntd.Attributes + let ntb = tb.DefineNestedType(pntd.Name, attributes) + typeMap.[pntd] <- ntb + defineNestedTypes ntb pntd + | _ -> () + + let rec transType (ty:Type) = + if (match ty with :? ProvidedTypeDefinition as ty -> not ty.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" ty + if ty.IsGenericParameter then ILType.Var ty.GenericParameterPosition + elif ty.HasElementType then + let ety = transType (ty.GetElementType()) + if ty.IsArray then + let rank = ty.GetArrayRank() + if rank = 1 then ILType.Array(ILArrayShape.SingleDimensional, ety) + else ILType.Array(ILArrayShape.FromRank rank, ety) + elif ty.IsPointer then ILType.Ptr ety + elif ty.IsByRef then ILType.Byref ety + else failwith "unexpected type with element type" + elif ty.Namespace = "System" && ty.Name = "Void" then ILType.Void + elif ty.IsValueType then ILType.Value (transTypeSpec ty) + else ILType.Boxed (transTypeSpec ty) + + and transTypeSpec (ty: Type) = + if ty.IsGenericType then + ILTypeSpec(transTypeRef (ty.GetGenericTypeDefinition()), Array.map transType (ty.GetGenericArguments())) + else + ILTypeSpec(transTypeRef ty, [| |]) + + and transTypeRef (ty: Type) = + let ty = if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty + ILTypeRef(transTypeRefScope ty, StructOption.ofObj (if ty.IsNested then null else ty.Namespace), ty.Name) + + and transTypeRefScope (ty: Type): ILTypeRefScope = + match ty.DeclaringType with + | null -> + if ty.Assembly = null then failwithf "null assembly for type %s" ty.FullName + ILTypeRefScope.Top (transScopeRef ty.Assembly) + | dt -> ILTypeRefScope.Nested (transTypeRef dt) + + and transScopeRef (assem: Assembly): ILScopeRef = + // Note: this simple equality check on assembly objects doesn't work on Mono, there must be some small difference in the + // implementation of equality on System.Assembly objects + // if assem = (targetAssembly :> Assembly) then ILScopeRef.Local + if assem.GetName().Name = targetAssembly.GetName().Name then ILScopeRef.Local + else ILScopeRef.Assembly (ILAssemblyRef.FromAssemblyName (assem.GetName())) + + let transCtorRef (m:ConstructorInfo) = + // Remove the generic instantiations to get the uninstantiated identity of the method + let m2 = m.GetDefinition() + let cc = (if m2.IsStatic then ILCallingConv.Static else ILCallingConv.Instance) + let ptys = [| for p in m2.GetParameters() -> transType p.ParameterType |] + ILMethodRef (transTypeRef m2.DeclaringType, cc, 0, m2.Name, ptys, ILType.Void) + + let transCtorSpec (f:ConstructorInfo) = + if (match f with :? ProvidedConstructor as f -> not f.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" f + match f with + | :? ProvidedConstructor as pc when ctorMap.ContainsKey pc -> ctorMap.[pc].FormalMethodSpec + | m -> ILMethodSpec(transCtorRef f, transType m.DeclaringType, [| |]) + + let transFieldSpec (f:FieldInfo) = + if (match f with :? ProvidedField as f -> not f.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" f + match f with + | :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf].FormalFieldSpec + | f -> + let f2 = f.GetDefinition() + ILFieldSpec(ILFieldRef (transTypeRef f2.DeclaringType, f2.Name, transType f2.FieldType), transType f.DeclaringType) + + let transMethRef (m:MethodInfo) = + if (match m with :? ProvidedMethod as m -> not m.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" m + // Remove the generic instantiations to get the uninstantiated identity of the method + let m2 = m.GetDefinition() + let ptys = [| for p in m2.GetParameters() -> transType p.ParameterType |] + let genarity = (if m2.IsGenericMethod then m2.GetGenericArguments().Length else 0) + let cc = (if m2.IsStatic then ILCallingConv.Static else ILCallingConv.Instance) + ILMethodRef (transTypeRef m2.DeclaringType, cc, genarity, m2.Name, ptys, transType m2.ReturnType) + + let transMeth (m:MethodInfo): ILMethodSpec = + match m with + | :? ProvidedMethod as pm when methMap.ContainsKey pm -> methMap.[pm].FormalMethodSpec + | m -> + //Debug.Assert (m.Name <> "get_Item1" || m.DeclaringType.Name <> "Tuple`2") + let mref = transMethRef m + let minst = (if m.IsGenericMethod then Array.map transType (m.GetGenericArguments()) else [| |]) + ILMethodSpec(mref, transType m.DeclaringType, minst) + + let iterateTypes f providedTypeDefinitions = + let rec typeMembers (ptd: ProvidedTypeDefinition) = + let tb = typeMap.[ptd] f tb (Some ptd) - for ntd in ptd.GetNestedTypes(ALL) do + for ntd in ptd.GetNestedTypes(bindAll) do nestedType ntd - and nestedType (ntd : Type) = - match ntd with + and nestedType (ntd: Type) = + match ntd with | :? ProvidedTypeDefinition as pntd -> typeMembers pntd | _ -> () - - for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitions do - match enclosingGeneratedTypeNames with - | None -> - typeMembers pt - | Some ns -> - let _fullName = - ("",ns) ||> List.fold (fun fullName n -> - let fullName = if fullName = "" then n else fullName + "." + n - f typeMapExtra.[fullName] None - fullName) - nestedType pt - - - // phase 1b - emit base types - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - match ptd.BaseType with null -> () | bt -> tb.SetParent(convType bt)) - let defineCustomAttrs f (cattrs: IList) = + for (pt, enclosingGeneratedTypeNames) in providedTypeDefinitions do + match enclosingGeneratedTypeNames with + | None -> + typeMembers pt + | Some ns -> + let _fullName = + ("", ns) ||> List.fold (fun fullName n -> + let fullName = if fullName = "" then n else fullName + "." + n + f typeMapExtra.[fullName] None + fullName) + nestedType pt + + let defineCustomAttrs f (cattrs: IList) = for attr in cattrs do let constructorArgs = [ for x in attr.ConstructorArguments -> x.Value ] - let namedProps,namedPropVals = [ for x in attr.NamedArguments do match x.MemberInfo with :? PropertyInfo as pi -> yield (pi, x.TypedValue.Value) | _ -> () ] |> List.unzip - let namedFields,namedFieldVals = [ for x in attr.NamedArguments do match x.MemberInfo with :? FieldInfo as pi -> yield (pi, x.TypedValue.Value) | _ -> () ] |> List.unzip - let cab = CustomAttributeBuilder(attr.Constructor, Array.ofList constructorArgs, Array.ofList namedProps, Array.ofList namedPropVals, Array.ofList namedFields, Array.ofList namedFieldVals) - f cab - - // phase 2 - emit member definitions - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - for cinfo in ptd.GetConstructors(ALL) do - match cinfo with - | :? ProvidedConstructor as pcinfo when not (ctorMap.ContainsKey pcinfo) -> - let cb = - if pcinfo.IsTypeInitializer then - if (cinfo.GetParameters()).Length <> 0 then failwith "Type initializer should not have parameters" - tb.DefineTypeInitializer() - else - let cb = tb.DefineConstructor(cinfo.Attributes, CallingConventions.Standard, [| for p in cinfo.GetParameters() -> convType p.ParameterType |]) - for (i,p) in cinfo.GetParameters() |> Seq.mapi (fun i x -> (i,x)) do - cb.DefineParameter(i+1, ParameterAttributes.None, p.Name) |> ignore - cb - ctorMap.[pcinfo] <- cb - | _ -> () - - if ptd.IsEnum then - tb.DefineField("value__", ptd.GetEnumUnderlyingType(), FieldAttributes.Public ||| FieldAttributes.SpecialName ||| FieldAttributes.RTSpecialName) - |> ignore - - for finfo in ptd.GetFields(ALL) do - let fieldInfo = - match finfo with - | :? ProvidedField as pinfo -> - Some (pinfo.Name, convType finfo.FieldType, finfo.Attributes, pinfo.GetCustomAttributesDataImpl(), None) - | :? ProvidedLiteralField as pinfo -> - Some (pinfo.Name, convType finfo.FieldType, finfo.Attributes, pinfo.GetCustomAttributesDataImpl(), Some (pinfo.GetRawConstantValue())) - | _ -> None - match fieldInfo with - | Some (name, ty, attr, cattr, constantVal) when not (fieldMap.ContainsKey finfo) -> - let fb = tb.DefineField(name, ty, attr) - if constantVal.IsSome then - fb.SetConstant constantVal.Value - defineCustomAttrs fb.SetCustomAttribute cattr - fieldMap.[finfo] <- fb - | _ -> () - for minfo in ptd.GetMethods(ALL) do - match minfo with - | :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo) -> - let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, convType minfo.ReturnType, [| for p in minfo.GetParameters() -> convType p.ParameterType |]) - for (i, p) in minfo.GetParameters() |> Seq.mapi (fun i x -> (i,x :?> ProvidedParameter)) do - // TODO: check why F# compiler doesn't emit default value when just p.Attributes is used (thus bad metadata is emitted) -// let mutable attrs = ParameterAttributes.None -// -// if p.IsOut then attrs <- attrs ||| ParameterAttributes.Out -// if p.HasDefaultParameterValue then attrs <- attrs ||| ParameterAttributes.Optional - - let pb = mb.DefineParameter(i+1, p.Attributes, p.Name) - if p.HasDefaultParameterValue then - do - let ctor = typeof.GetConstructor([|typeof|]) - let builder = new CustomAttributeBuilder(ctor, [|p.RawDefaultValue|]) - pb.SetCustomAttribute builder - do - let ctor = typeof.GetConstructor([||]) - let builder = new CustomAttributeBuilder(ctor, [||]) - pb.SetCustomAttribute builder - pb.SetConstant p.RawDefaultValue - methMap.[pminfo] <- mb - | _ -> () - - for ityp in ptd.GetInterfaceImplementations() do - tb.AddInterfaceImplementation ityp) - - // phase 3 - emit member code - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - let cattr = ptd.GetCustomAttributesDataImpl() - defineCustomAttrs tb.SetCustomAttribute cattr - // Allow at most one constructor, and use its arguments as the fields of the type - let ctors = - ptd.GetConstructors(ALL) // exclude type initializer - |> Seq.choose (function :? ProvidedConstructor as pcinfo when not pcinfo.IsTypeInitializer -> Some pcinfo | _ -> None) - |> Seq.toList - let implictCtorArgs = - match ctors |> List.filter (fun x -> x.IsImplicitCtor) with - | [] -> [] - | [ pcinfo ] -> [ for p in pcinfo.GetParameters() -> p ] - | _ -> failwith "at most one implicit constructor allowed" - - let implicitCtorArgsAsFields = - [ for ctorArg in implictCtorArgs -> - tb.DefineField(ctorArg.Name, convType ctorArg.ParameterType, FieldAttributes.Private) ] - - let rec emitLambda(callSiteIlg : ILGenerator, v : Quotations.Var, body : Quotations.Expr, freeVars : seq, locals : Dictionary<_, LocalBuilder>, parameters) = - let lambda = assemblyMainModule.DefineType(uniqueLambdaTypeName(), TypeAttributes.Class) - let baseType = typedefof>.MakeGenericType(v.Type, body.Type) - lambda.SetParent(baseType) - let ctor = lambda.DefineDefaultConstructor(MethodAttributes.Public) - let decl = baseType.GetMethod "Invoke" - let paramTypes = [| for p in decl.GetParameters() -> p.ParameterType |] - let invoke = lambda.DefineMethod("Invoke", MethodAttributes.Virtual ||| MethodAttributes.Final ||| MethodAttributes.Public, decl.ReturnType, paramTypes) - lambda.DefineMethodOverride(invoke, decl) - - // promote free vars to fields - let fields = ResizeArray() - for v in freeVars do - let f = lambda.DefineField(v.Name, v.Type, FieldAttributes.Assembly) - fields.Add(v, f) - - let copyOfLocals = Dictionary() - - let ilg = invoke.GetILGenerator() - for (v, f) in fields do - let l = ilg.DeclareLocal(v.Type) - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldfld, f) - ilg.Emit(OpCodes.Stloc, l) - copyOfLocals.[v] <- l - - let expectedState = if (invoke.ReturnType = typeof) then ExpectedStackState.Empty else ExpectedStackState.Value - emitExpr (ilg, copyOfLocals, [| Quotations.Var("this", lambda); v|]) expectedState body - ilg.Emit(OpCodes.Ret) - - lambda.CreateType() |> ignore - - callSiteIlg.Emit(OpCodes.Newobj, ctor) - for (v, f) in fields do - callSiteIlg.Emit(OpCodes.Dup) - match locals.TryGetValue v with - | true, loc -> - callSiteIlg.Emit(OpCodes.Ldloc, loc) - | false, _ -> - let index = parameters |> Array.findIndex ((=) v) - callSiteIlg.Emit(OpCodes.Ldarg, index) - callSiteIlg.Emit(OpCodes.Stfld, f) - - and emitExpr (ilg: ILGenerator, locals:Dictionary, parameterVars) expectedState expr = - let pop () = ilg.Emit(OpCodes.Pop) - let popIfEmptyExpected s = if isEmpty s then pop() - let emitConvIfNecessary t1 = - if t1 = typeof then - ilg.Emit(OpCodes.Conv_I2) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_U2) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_I1) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_U1) - /// emits given expression to corresponding IL - let rec emit (expectedState : ExpectedStackState) (expr: Quotations.Expr) = - match expr with - | Quotations.Patterns.ForIntegerRangeLoop(loopVar, first, last, body) -> - // for(loopVar = first..last) body - let lb = - match locals.TryGetValue loopVar with - | true, lb -> lb - | false, _ -> - let lb = ilg.DeclareLocal(convType loopVar.Type) - locals.Add(loopVar, lb) - lb - - // loopVar = first - emit ExpectedStackState.Value first - ilg.Emit(OpCodes.Stloc, lb) - - let before = ilg.DefineLabel() - let after = ilg.DefineLabel() - - ilg.MarkLabel before - ilg.Emit(OpCodes.Ldloc, lb) - - emit ExpectedStackState.Value last - ilg.Emit(OpCodes.Bgt, after) - - emit ExpectedStackState.Empty body - - // loopVar++ - ilg.Emit(OpCodes.Ldloc, lb) - ilg.Emit(OpCodes.Ldc_I4_1) - ilg.Emit(OpCodes.Add) - ilg.Emit(OpCodes.Stloc, lb) - - ilg.Emit(OpCodes.Br, before) - ilg.MarkLabel(after) - - | Quotations.Patterns.NewArray(elementTy, elements) -> - ilg.Emit(OpCodes.Ldc_I4, List.length elements) - ilg.Emit(OpCodes.Newarr, convType elementTy) - - elements - |> List.iteri (fun i el -> - ilg.Emit(OpCodes.Dup) - ilg.Emit(OpCodes.Ldc_I4, i) - emit ExpectedStackState.Value el - ilg.Emit(OpCodes.Stelem, convType elementTy) - ) - - popIfEmptyExpected expectedState - - | Quotations.Patterns.WhileLoop(cond, body) -> - let before = ilg.DefineLabel() - let after = ilg.DefineLabel() - - ilg.MarkLabel before - emit ExpectedStackState.Value cond - ilg.Emit(OpCodes.Brfalse, after) - emit ExpectedStackState.Empty body - ilg.Emit(OpCodes.Br, before) - - ilg.MarkLabel after - - | Quotations.Patterns.Var v -> - if isEmpty expectedState then () else - let methIdx = parameterVars |> Array.tryFindIndex (fun p -> p = v) - match methIdx with - | Some idx -> - ilg.Emit((if isAddress expectedState then OpCodes.Ldarga else OpCodes.Ldarg), idx) - | None -> - let implicitCtorArgFieldOpt = implicitCtorArgsAsFields |> List.tryFind (fun f -> f.Name = v.Name) - match implicitCtorArgFieldOpt with - | Some ctorArgField -> - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldfld, ctorArgField) - | None -> - match locals.TryGetValue v with - | true, localBuilder -> - ilg.Emit((if isAddress expectedState then OpCodes.Ldloca else OpCodes.Ldloc), localBuilder.LocalIndex) - | false, _ -> - failwith "unknown parameter/field" - - | Quotations.Patterns.Coerce (arg,ty) -> - // castClass may lead to observable side-effects - InvalidCastException - emit ExpectedStackState.Value arg - let argTy = convType arg.Type - let targetTy = convType ty - if argTy.IsValueType && not targetTy.IsValueType then - ilg.Emit(OpCodes.Box, argTy) - elif not argTy.IsValueType && targetTy.IsValueType then - ilg.Emit(OpCodes.Unbox_Any, targetTy) - // emit castclass if - // - targettype is not obj (assume this is always possible for ref types) - // AND - // - HACK: targettype is TypeBuilderInstantiationType - // (its implementation of IsAssignableFrom raises NotSupportedException so it will be safer to always emit castclass) - // OR - // - not (argTy :> targetTy) - elif targetTy <> typeof && (Misc.TypeBuilderInstantiationType.Equals(targetTy.GetType()) || not (targetTy.IsAssignableFrom(argTy))) then - ilg.Emit(OpCodes.Castclass, targetTy) - - popIfEmptyExpected expectedState - | Quotations.DerivedPatterns.SpecificCall <@ (-) @>(None, [t1; t2; _], [a1; a2]) -> - assert(t1 = t2) - emit ExpectedStackState.Value a1 - emit ExpectedStackState.Value a2 - if t1 = typeof then - ilg.Emit(OpCodes.Call, typeof.GetMethod "op_Subtraction") - else - ilg.Emit(OpCodes.Sub) - emitConvIfNecessary t1 + let transValue (o:obj) = + match o with + | :? Type as t -> box (transType t) + | v -> v + let namedProps = [ for x in attr.NamedArguments do match x.MemberInfo with :? PropertyInfo as pi -> yield ILCustomAttrNamedArg(pi.Name, transType x.TypedValue.ArgumentType, x.TypedValue.Value) | _ -> () ] + let namedFields = [ for x in attr.NamedArguments do match x.MemberInfo with :? FieldInfo as pi -> yield ILCustomAttrNamedArg(pi.Name, transType x.TypedValue.ArgumentType, x.TypedValue.Value) | _ -> () ] + let ca = mkILCustomAttribMethRef (transCtorSpec attr.Constructor, constructorArgs, namedProps, namedFields) + f ca + + member __.Compile(isHostedExecution) = + let providedTypeDefinitionsT = targetAssembly.GetTheTypes() |> Array.collect (fun (tds, nsps) -> Array.map (fun td -> (td, nsps)) tds) + let ilg = context.ILGlobals + let assemblyName = targetAssembly.GetName() + let assemblyFileName = targetAssembly.Location + let assemblyBuilder = + let attrs = targetAssembly.GetCustomAttributesData() + let cattrs = ResizeArray() + defineCustomAttrs cattrs.Add attrs + ILAssemblyBuilder(assemblyName, assemblyFileName, ilg, cattrs) + let assemblyMainModule = assemblyBuilder.MainModule + + // Set the Assembly on the type definitions + for (ptdT, _) in providedTypeDefinitionsT do + if not ptdT.BelongsToTargetModel then failwithf "expected '%O' to belong to the target model" ptdT + ptdT.SetAssemblyInternal (K (targetAssembly :> Assembly)) + + // phase 1 - define types + for (pt, enclosingGeneratedTypeNames) in providedTypeDefinitionsT do + match enclosingGeneratedTypeNames with + | None -> + // Filter out the additional TypeProviderTypeAttributes flags + let attributes = pt.Attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) + &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) + // Adjust the attributes - we're codegen'ing as non-nested + let attributes = adjustTypeAttributes false attributes + let tb = assemblyMainModule.DefineType(StructOption.ofObj pt.Namespace, pt.Name, attributes) + typeMap.[pt] <- tb + defineNestedTypes tb pt + + | Some ns -> + let otb, _ = + ((None, ""), ns) ||> List.fold (fun (otb:ILTypeBuilder option, fullName) n -> + let fullName = if fullName = "" then n else fullName + "." + n + let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra.[fullName] else None + let tb = + match priorType with + | Some tbb -> tbb + | None -> + // OK, the implied nested type is not defined, define it now + let attributes = TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.Sealed + let attributes = adjustTypeAttributes otb.IsSome attributes + let tb = + match otb with + | None -> + let nsp, n = splitILTypeName n + assemblyMainModule.DefineType(nsp, n, attributes) + | Some (otb:ILTypeBuilder) -> + otb.DefineNestedType(n, attributes) + typeMapExtra.[fullName] <- tb + tb + (Some tb, fullName)) + defineNestedType otb.Value pt + + + // phase 1b - emit base types + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + match ptdT.BaseType with + | null -> () + | bt -> tb.SetParent(transType bt)) + + // phase 2 - emit member definitions + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + for cinfo in ptdT.GetConstructors(bindAll) do + match cinfo with + | :? ProvidedConstructor as pcinfo when not (ctorMap.ContainsKey pcinfo) -> + let cb = + if pcinfo.IsTypeInitializer then + if (cinfo.GetParameters()).Length <> 0 then failwith "Type initializer should not have parameters" + tb.DefineTypeInitializer() + else + let cb = tb.DefineConstructor(cinfo.Attributes, [| for p in cinfo.GetParameters() -> transType p.ParameterType |]) + for (i, p) in cinfo.GetParameters() |> Seq.mapi (fun i x -> (i, x)) do + cb.DefineParameter(i+1, ParameterAttributes.None, p.Name) |> ignore + cb + ctorMap.[pcinfo] <- cb + | _ -> () - popIfEmptyExpected expectedState + if ptdT.IsEnum then + tb.DefineField("value__", transType (ptdT.GetEnumUnderlyingType()), FieldAttributes.Public ||| FieldAttributes.SpecialName ||| FieldAttributes.RTSpecialName) + |> ignore - | Quotations.DerivedPatterns.SpecificCall <@ (/) @> (None, [t1; t2; _], [a1; a2]) -> - assert (t1 = t2) - emit ExpectedStackState.Value a1 - emit ExpectedStackState.Value a2 - if t1 = typeof then - ilg.Emit(OpCodes.Call, typeof.GetMethod "op_Division") - else - match Type.GetTypeCode t1 with - | TypeCode.UInt32 - | TypeCode.UInt64 - | TypeCode.UInt16 - | TypeCode.Byte - | _ when t1 = typeof -> ilg.Emit (OpCodes.Div_Un) - | _ -> ilg.Emit(OpCodes.Div) - - emitConvIfNecessary t1 - - popIfEmptyExpected expectedState - - | Quotations.DerivedPatterns.SpecificCall <@ int @>(None, [sourceTy], [v]) -> - emit ExpectedStackState.Value v - match Type.GetTypeCode(sourceTy) with - | TypeCode.String -> - ilg.Emit(OpCodes.Call, Misc.ParseInt32Method) - | TypeCode.Single - | TypeCode.Double - | TypeCode.Int64 - | TypeCode.UInt64 - | TypeCode.UInt16 - | TypeCode.Char - | TypeCode.Byte - | _ when sourceTy = typeof || sourceTy = typeof -> - ilg.Emit(OpCodes.Conv_I4) - | TypeCode.Int32 - | TypeCode.UInt32 - | TypeCode.Int16 - | TypeCode.SByte -> () // no op - | _ -> failwith "TODO: search for op_Explicit on sourceTy" - - | Quotations.DerivedPatterns.SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray @> (None, [ty], [arr; index]) -> - // observable side-effect - IndexOutOfRangeException - emit ExpectedStackState.Value arr - emit ExpectedStackState.Value index - if isAddress expectedState then - ilg.Emit(OpCodes.Readonly) - ilg.Emit(OpCodes.Ldelema, convType ty) - else - ilg.Emit(OpCodes.Ldelem, convType ty) - - popIfEmptyExpected expectedState - - | Quotations.DerivedPatterns.SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray2D @> (None, _ty, arr::indices) - | Quotations.DerivedPatterns.SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray3D @> (None, _ty, arr::indices) - | Quotations.DerivedPatterns.SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray4D @> (None, _ty, arr::indices) -> - - let meth = - let name = if isAddress expectedState then "Address" else "Get" - arr.Type.GetMethod(name) - - // observable side-effect - IndexOutOfRangeException - emit ExpectedStackState.Value arr - for index in indices do - emit ExpectedStackState.Value index - - if isAddress expectedState then - ilg.Emit(OpCodes.Readonly) - - ilg.Emit(OpCodes.Call, meth) - - popIfEmptyExpected expectedState - - | Quotations.Patterns.FieldGet (objOpt,field) -> - match field with - | :? ProvidedLiteralField as plf when plf.DeclaringType.IsEnum -> - if expectedState <> ExpectedStackState.Empty then - emit expectedState (Quotations.Expr.Value(field.GetRawConstantValue(), field.FieldType.GetEnumUnderlyingType())) - | _ -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - let field = - match field with - | :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf] :> FieldInfo - | m -> m - if field.IsStatic then - ilg.Emit(OpCodes.Ldsfld, field) - else - ilg.Emit(OpCodes.Ldfld, field) - - | Quotations.Patterns.FieldSet (objOpt,field,v) -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - emit ExpectedStackState.Value v - let field = match field with :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf] :> FieldInfo | m -> m - if field.IsStatic then - ilg.Emit(OpCodes.Stsfld, field) - else - ilg.Emit(OpCodes.Stfld, field) - | Quotations.Patterns.Call (objOpt,meth,args) -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - for pe in args do - emit ExpectedStackState.Value pe - let getMeth (m:MethodInfo) = match m with :? ProvidedMethod as pm when methMap.ContainsKey pm -> methMap.[pm] :> MethodInfo | m -> m - // Handle the case where this is a generic method instantiated at a type being compiled - let mappedMeth = - if meth.IsGenericMethod then - let args = meth.GetGenericArguments() |> Array.map convType - let gmd = meth.GetGenericMethodDefinition() |> getMeth - gmd.GetGenericMethodDefinition().MakeGenericMethod args - elif meth.DeclaringType.IsGenericType then - let gdty = convType (meth.DeclaringType.GetGenericTypeDefinition()) - let gdtym = gdty.GetMethods() |> Seq.find (fun x -> x.Name = meth.Name) - assert (gdtym <> null) // ?? will never happen - if method is not found - KeyNotFoundException will be raised - let dtym = - match convType meth.DeclaringType with - | :? TypeBuilder as dty -> TypeBuilder.GetMethod(dty, gdtym) - | dty -> MethodBase.GetMethodFromHandle(meth.MethodHandle, dty.TypeHandle) :?> _ - - assert (dtym <> null) - dtym - else - getMeth meth - match objOpt with - | Some obj when mappedMeth.IsAbstract || mappedMeth.IsVirtual -> - if obj.Type.IsValueType then ilg.Emit(OpCodes.Constrained, convType obj.Type) - ilg.Emit(OpCodes.Callvirt, mappedMeth) - | _ -> - ilg.Emit(OpCodes.Call, mappedMeth) - - let returnTypeIsVoid = mappedMeth.ReturnType = typeof - match returnTypeIsVoid, (isEmpty expectedState) with - | false, true -> - // method produced something, but we don't need it - pop() - | true, false when expr.Type = typeof -> - // if we need result and method produce void and result should be unit - push null as unit value on stack - ilg.Emit(OpCodes.Ldnull) - | _ -> () + for finfo in ptdT.GetFields(bindAll) do + match finfo with + | :? ProvidedField as pinfo -> + let fb = tb.DefineField(finfo.Name, transType finfo.FieldType, finfo.Attributes) - | Quotations.Patterns.NewObject (ctor,args) -> - for pe in args do - emit ExpectedStackState.Value pe - let meth = match ctor with :? ProvidedConstructor as pc when ctorMap.ContainsKey pc -> ctorMap.[pc] :> ConstructorInfo | c -> c - ilg.Emit(OpCodes.Newobj, meth) - - popIfEmptyExpected expectedState - - | Quotations.Patterns.Value (obj, _ty) -> - let rec emitC (v:obj) = - match v with - | :? string as x -> ilg.Emit(OpCodes.Ldstr, x) - | :? int8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? uint8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int8 x)) - | :? int16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? uint16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int16 x)) - | :? int32 as x -> ilg.Emit(OpCodes.Ldc_I4, x) - | :? uint32 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? int64 as x -> ilg.Emit(OpCodes.Ldc_I8, x) - | :? uint64 as x -> ilg.Emit(OpCodes.Ldc_I8, int64 x) - | :? char as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? bool as x -> ilg.Emit(OpCodes.Ldc_I4, if x then 1 else 0) - | :? float32 as x -> ilg.Emit(OpCodes.Ldc_R4, x) - | :? float as x -> ilg.Emit(OpCodes.Ldc_R8, x) -#if FX_NO_GET_ENUM_UNDERLYING_TYPE -#else - | :? System.Enum as x when x.GetType().GetEnumUnderlyingType() = typeof -> ilg.Emit(OpCodes.Ldc_I4, unbox v) -#endif - | :? Type as ty -> - ilg.Emit(OpCodes.Ldtoken, convType ty) - ilg.Emit(OpCodes.Call, Misc.GetTypeFromHandleMethod) - | :? decimal as x -> - let bits = System.Decimal.GetBits x - ilg.Emit(OpCodes.Ldc_I4, bits.[0]) - ilg.Emit(OpCodes.Ldc_I4, bits.[1]) - ilg.Emit(OpCodes.Ldc_I4, bits.[2]) - do - let sign = (bits.[3] &&& 0x80000000) <> 0 - ilg.Emit(if sign then OpCodes.Ldc_I4_1 else OpCodes.Ldc_I4_0) - do - let scale = byte ((bits.[3] >>> 16) &&& 0x7F) - ilg.Emit(OpCodes.Ldc_I4_S, scale) - ilg.Emit(OpCodes.Newobj, Misc.DecimalConstructor) - | :? DateTime as x -> - ilg.Emit(OpCodes.Ldc_I8, x.Ticks) - ilg.Emit(OpCodes.Ldc_I4, int x.Kind) - ilg.Emit(OpCodes.Newobj, Misc.DateTimeConstructor) - | :? DateTimeOffset as x -> - ilg.Emit(OpCodes.Ldc_I8, x.Ticks) - ilg.Emit(OpCodes.Ldc_I8, x.Offset.Ticks) - ilg.Emit(OpCodes.Newobj, Misc.TimeSpanConstructor) - ilg.Emit(OpCodes.Newobj, Misc.DateTimeOffsetConstructor) - | null -> ilg.Emit(OpCodes.Ldnull) - | _ -> failwithf "unknown constant '%A' in generated method" v - if isEmpty expectedState then () - else emitC obj - - | Quotations.Patterns.Let(v,e,b) -> - let lb = ilg.DeclareLocal (convType v.Type) - locals.Add (v, lb) - emit ExpectedStackState.Value e - ilg.Emit(OpCodes.Stloc, lb.LocalIndex) - emit expectedState b - - | Quotations.Patterns.Sequential(e1, e2) -> - emit ExpectedStackState.Empty e1 - emit expectedState e2 - - | Quotations.Patterns.IfThenElse(cond, ifTrue, ifFalse) -> - let ifFalseLabel = ilg.DefineLabel() - let endLabel = ilg.DefineLabel() - - emit ExpectedStackState.Value cond - - ilg.Emit(OpCodes.Brfalse, ifFalseLabel) - - emit expectedState ifTrue - ilg.Emit(OpCodes.Br, endLabel) - - ilg.MarkLabel(ifFalseLabel) - emit expectedState ifFalse - - ilg.Emit(OpCodes.Nop) - ilg.MarkLabel(endLabel) - - | Quotations.Patterns.TryWith(body, _filterVar, _filterBody, catchVar, catchBody) -> - - let stres, ldres = - if isEmpty expectedState then ignore, ignore - else - let local = ilg.DeclareLocal (convType body.Type) - let stres = fun () -> ilg.Emit(OpCodes.Stloc, local) - let ldres = fun () -> ilg.Emit(OpCodes.Ldloc, local) - stres, ldres - - let exceptionVar = ilg.DeclareLocal(convType catchVar.Type) - locals.Add(catchVar, exceptionVar) - - let _exnBlock = ilg.BeginExceptionBlock() - - emit expectedState body - stres() - - ilg.BeginCatchBlock(convType catchVar.Type) - ilg.Emit(OpCodes.Stloc, exceptionVar) - emit expectedState catchBody - stres() - ilg.EndExceptionBlock() - - ldres() - - | Quotations.Patterns.VarSet(v,e) -> - emit ExpectedStackState.Value e - match locals.TryGetValue v with - | true, localBuilder -> - ilg.Emit(OpCodes.Stloc, localBuilder.LocalIndex) - | false, _ -> - failwith "unknown parameter/field in assignment. Only assignments to locals are currently supported by TypeProviderEmit" - | Quotations.Patterns.Lambda(v, body) -> - emitLambda(ilg, v, body, expr.GetFreeVars(), locals, parameterVars) - popIfEmptyExpected expectedState - | n -> - failwith (sprintf "unknown expression '%A' in generated method" n) - emit expectedState expr - - - // Emit the constructor (if any) - for pcinfo in ctors do - assert ctorMap.ContainsKey pcinfo - let cb = ctorMap.[pcinfo] - let cattr = pcinfo.GetCustomAttributesDataImpl() - defineCustomAttrs cb.SetCustomAttribute cattr - let ilg = cb.GetILGenerator() - let locals = Dictionary() - let parameterVars = - [| yield Quotations.Var("this", pcinfo.DeclaringType) - for p in pcinfo.GetParameters() do - yield Quotations.Var(p.Name, p.ParameterType) |] - let parameters = - [| for v in parameterVars -> Quotations.Expr.Var v |] - match pcinfo.GetBaseConstructorCallInternal true with - | None -> - ilg.Emit(OpCodes.Ldarg_0) - let cinfo = ptd.BaseType.GetConstructor(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, null, [| |], null) - ilg.Emit(OpCodes.Call,cinfo) - | Some f -> - // argExprs should always include 'this' - let (cinfo,argExprs) = f (Array.toList parameters) - for argExpr in argExprs do - emitExpr (ilg, locals, parameterVars) ExpectedStackState.Value argExpr - ilg.Emit(OpCodes.Call,cinfo) - - if pcinfo.IsImplicitCtor then - for ctorArgsAsFieldIdx,ctorArgsAsField in List.mapi (fun i x -> (i,x)) implicitCtorArgsAsFields do - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldarg, ctorArgsAsFieldIdx+1) - ilg.Emit(OpCodes.Stfld, ctorArgsAsField) - else - let code = pcinfo.GetInvokeCodeInternal true - let code = code parameters - emitExpr (ilg, locals, parameterVars) ExpectedStackState.Empty code - ilg.Emit(OpCodes.Ret) - - match ptd.GetConstructors(ALL) |> Seq.tryPick (function :? ProvidedConstructor as pc when pc.IsTypeInitializer -> Some pc | _ -> None) with - | None -> () - | Some pc -> - let cb = ctorMap.[pc] - let ilg = cb.GetILGenerator() - let cattr = pc.GetCustomAttributesDataImpl() - defineCustomAttrs cb.SetCustomAttribute cattr - let expr = pc.GetInvokeCodeInternal true [||] - emitExpr(ilg, new Dictionary<_, _>(), [||]) ExpectedStackState.Empty expr - ilg.Emit OpCodes.Ret - - // Emit the methods - for minfo in ptd.GetMethods(ALL) do - match minfo with - | :? ProvidedMethod as pminfo -> - let mb = methMap.[pminfo] - let ilg = mb.GetILGenerator() - let cattr = pminfo.GetCustomAttributesDataImpl() - defineCustomAttrs mb.SetCustomAttribute cattr - - let parameterVars = - [| if not pminfo.IsStatic then - yield Quotations.Var("this", pminfo.DeclaringType) - for p in pminfo.GetParameters() do - yield Quotations.Var(p.Name, p.ParameterType) |] - let parameters = - [| for v in parameterVars -> Quotations.Expr.Var v |] - - let expr = pminfo.GetInvokeCodeInternal true parameters - - let locals = Dictionary() - //printfn "Emitting linqCode for %s::%s, code = %s" pminfo.DeclaringType.FullName pminfo.Name (try linqCode.ToString() with _ -> "") - - - let expectedState = if (minfo.ReturnType = typeof) then ExpectedStackState.Empty else ExpectedStackState.Value - emitExpr (ilg, locals, parameterVars) expectedState expr - ilg.Emit OpCodes.Ret - | _ -> () - - for (bodyMethInfo,declMethInfo) in ptd.GetMethodOverrides() do - let bodyMethBuilder = methMap.[bodyMethInfo] - tb.DefineMethodOverride(bodyMethBuilder,declMethInfo) - - for evt in ptd.GetEvents(ALL) |> Seq.choose (function :? ProvidedEvent as pe -> Some pe | _ -> None) do - let eb = tb.DefineEvent(evt.Name, evt.Attributes, evt.EventHandlerType) - defineCustomAttrs eb.SetCustomAttribute (evt.GetCustomAttributesDataImpl()) - eb.SetAddOnMethod(methMap.[evt.GetAddMethod(true) :?> _]) - eb.SetRemoveOnMethod(methMap.[evt.GetRemoveMethod(true) :?> _]) - // TODO: add raiser - - for pinfo in ptd.GetProperties(ALL) |> Seq.choose (function :? ProvidedProperty as pe -> Some pe | _ -> None) do - let pb = tb.DefineProperty(pinfo.Name, pinfo.Attributes, convType pinfo.PropertyType, [| for p in pinfo.GetIndexParameters() -> convType p.ParameterType |]) - let cattr = pinfo.GetCustomAttributesDataImpl() - defineCustomAttrs pb.SetCustomAttribute cattr - if pinfo.CanRead then - let minfo = pinfo.GetGetMethod(true) - pb.SetGetMethod (methMap.[minfo :?> ProvidedMethod ]) - if pinfo.CanWrite then - let minfo = pinfo.GetSetMethod(true) - pb.SetSetMethod (methMap.[minfo :?> ProvidedMethod ])) + if finfo.IsLiteral then + fb.SetConstant (pinfo.GetRawConstantValue()) + defineCustomAttrs fb.SetCustomAttribute (pinfo.GetCustomAttributesData()) - // phase 4 - complete types - iterateTypes (fun tb _ptd -> tb.CreateType() |> ignore) + fieldMap.[finfo] <- fb -#if FX_NO_LOCAL_FILESYSTEM -#else - assembly.Save (Path.GetFileName assemblyFileName) -#endif + | _ -> () - let assemblyLoadedInMemory = assemblyMainModule.Assembly + for minfo in ptdT.GetMethods(bindAll) do + match minfo with + | :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo) -> + let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, transType minfo.ReturnType, [| for p in minfo.GetParameters() -> transType p.ParameterType |]) - iterateTypes (fun _tb ptd -> - match ptd with - | None -> () - | Some ptd -> ptd.SetAssembly assemblyLoadedInMemory) + for (i, p) in minfo.GetParameters() |> Seq.mapi (fun i x -> (i, x :?> ProvidedParameter)) do -#if FX_NO_LOCAL_FILESYSTEM -#else - member __.GetFinalBytes() = - let assemblyBytes = File.ReadAllBytes assemblyFileName - let _assemblyLoadedInMemory = System.Reflection.Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain) - //printfn "final bytes in '%s'" assemblyFileName - //File.Delete assemblyFileName - assemblyBytes -#endif + let pb = mb.DefineParameter(i+1, p.Attributes, p.Name) + if p.HasDefaultParameterValue then + let ctorTy = typeof + let ctor = ctorTy.GetConstructor([|typeof|]) + let ctorTgt = context.ConvertSourceConstructorRefToTarget ctor -type ProvidedAssembly(assemblyFileName: string) = - let theTypes = ResizeArray<_>() - let assemblyGenerator = AssemblyGenerator(assemblyFileName) - let assemblyLazy = - lazy - assemblyGenerator.Generate(theTypes |> Seq.toList) - assemblyGenerator.Assembly -#if FX_NO_LOCAL_FILESYSTEM -#else - let theAssemblyBytesLazy = - lazy - assemblyGenerator.GetFinalBytes() + let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt, [p.RawDefaultValue], [], []) + pb.SetCustomAttribute ca - do - GlobalProvidedAssemblyElementsTable.theTable.Add(assemblyGenerator.Assembly, theAssemblyBytesLazy) + let ctorTy = typeof + let ctor = ctorTy.GetConstructor([||]) + let ctorTgt = context.ConvertSourceConstructorRefToTarget ctor + let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt, [], [], []) + pb.SetCustomAttribute ca -#endif + pb.SetConstant p.RawDefaultValue - let add (providedTypeDefinitions:ProvidedTypeDefinition list, enclosingTypeNames: string list option) = - for pt in providedTypeDefinitions do - if pt.IsErased then invalidOp ("The provided type "+pt.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition") - theTypes.Add(pt,enclosingTypeNames) - pt.SetAssemblyLazy assemblyLazy + methMap.[pminfo] <- mb - member x.AddNestedTypes (providedTypeDefinitions, enclosingTypeNames) = add (providedTypeDefinitions, Some enclosingTypeNames) - member x.AddTypes (providedTypeDefinitions) = add (providedTypeDefinitions, None) -#if FX_NO_LOCAL_FILESYSTEM + | _ -> () + + for ityp in ptdT.GetInterfaces() do + tb.AddInterfaceImplementation (transType ityp)) + + // phase 3 - emit member code + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + + defineCustomAttrs tb.SetCustomAttribute (ptdT.GetCustomAttributesData()) + + // Allow at most one constructor, and use its arguments as the fields of the type + let ctors = + ptdT.GetConstructors(bindAll) // exclude type initializer + |> Seq.choose (function :? ProvidedConstructor as pcinfo when not pcinfo.IsTypeInitializer -> Some pcinfo | _ -> None) + |> Seq.toList + + let implictCtorArgs = + match ctors |> List.filter (fun x -> x.IsImplicitConstructor) with + | [] -> [] + | [ pcinfo ] -> [ for p in pcinfo.GetParameters() -> p ] + | _ -> failwith "at most one implicit constructor allowed" + + let implicitCtorArgsAsFields = + [ for ctorArg in implictCtorArgs -> + tb.DefineField(ctorArg.Name, transType ctorArg.ParameterType, FieldAttributes.Private) ] + + + // Emit the constructor (if any) + for pcinfo in ctors do + assert ctorMap.ContainsKey pcinfo + if not pcinfo.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedConstructor. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pcinfo + let cb = ctorMap.[pcinfo] + + defineCustomAttrs cb.SetCustomAttribute (pcinfo.GetCustomAttributesData()) + + let ilg = cb.GetILGenerator() + let ctorLocals = Dictionary() + let parameterVars = + [| yield Var("this", pcinfo.DeclaringType) + for p in pcinfo.GetParameters() do + yield Var(p.Name, p.ParameterType) |] + + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, ctorLocals, parameterVars) + + let parameters = [ for v in parameterVars -> Expr.Var v ] + + match pcinfo.BaseCall with + | None -> + ilg.Emit(I_ldarg 0) + let cinfo = ptdT.BaseType.GetConstructor(bindAll, null, [| |], null) + ilg.Emit(mkNormalCall (transCtorSpec cinfo)) + | Some f -> + // argExprs should always include 'this' + let (cinfo, argExprs) = f parameters + for argExpr in argExprs do + codeGen.EmitExpr (ExpectedStackState.Value, argExpr) + ilg.Emit(mkNormalCall (transCtorSpec cinfo)) + + if pcinfo.IsImplicitConstructor then + for ctorArgsAsFieldIdx, ctorArgsAsField in List.mapi (fun i x -> (i, x)) implicitCtorArgsAsFields do + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldarg (ctorArgsAsFieldIdx+1)) + ilg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, ctorArgsAsField.FormalFieldSpec)) + else + let code = pcinfo.GetInvokeCode parameters + codeGen.EmitExpr (ExpectedStackState.Empty, code) + ilg.Emit(I_ret) + + match ptdT.GetConstructors(bindAll) |> Seq.tryPick (function :? ProvidedConstructor as pc when pc.IsTypeInitializer -> Some pc | _ -> None) with + | None -> () + | Some _ when ptdT.IsInterface -> + failwith "The provided type definition is an interface; therefore, it may not provide constructors." + | Some pc -> + let cb = ctorMap.[pc] + let ilg = cb.GetILGenerator() + + defineCustomAttrs cb.SetCustomAttribute (pc.GetCustomAttributesData()) + + let expr = pc.GetInvokeCode [ ] + let ctorLocals = new Dictionary<_, _>() + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, ctorLocals, [| |]) + codeGen.EmitExpr (ExpectedStackState.Empty, expr) + ilg.Emit I_ret + + // Emit the methods + for minfo in ptdT.GetMethods(bindAll) do + match minfo with + | :? ProvidedMethod as pminfo -> + if not pminfo.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedMethod. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pminfo + let mb = methMap.[pminfo] + defineCustomAttrs mb.SetCustomAttribute (pminfo.GetCustomAttributesData()) + + let parameterVars = + [| if not pminfo.IsStatic then + yield Var("this", pminfo.DeclaringType) + for p in pminfo.GetParameters() do + yield Var(p.Name, p.ParameterType) |] + let parameters = + [ for v in parameterVars -> Expr.Var v ] + + match pminfo.GetInvokeCode with + | Some _ when ptdT.IsInterface -> + failwith "The provided type definition is an interface; therefore, it should not define an implementation for its members." + | Some _ when pminfo.IsAbstract -> + failwith "The provided method is marked as an abstract method; therefore, it should not define an implementation." + | None when not (pminfo.IsAbstract || ptdT.IsAbstract ||ptdT.IsInterface) -> + failwith "The provided method is not marked as an abstract method; therefore, it should define an implementation." + | None when pminfo.IsAbstract || ptdT.IsInterface -> + // abstract and interface methods have no body at all + () + | None -> + let ilg = mb.GetILGenerator() + ilg.Emit I_ret + | Some invokeCode -> + let ilg = mb.GetILGenerator() + let expr = invokeCode parameters + + let methLocals = Dictionary() + + let expectedState = if (transType minfo.ReturnType = ILType.Void) then ExpectedStackState.Empty else ExpectedStackState.Value + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, methLocals, parameterVars) + codeGen.EmitExpr (expectedState, expr) + ilg.Emit I_ret + | _ -> () + + for (bodyMethInfo, declMethInfo) in ptdT.GetMethodOverrides() do + let bodyMethBuilder = methMap.[bodyMethInfo] + tb.DefineMethodOverride + { Overrides = OverridesSpec(transMethRef declMethInfo, transType declMethInfo.DeclaringType) + OverrideBy = bodyMethBuilder.FormalMethodSpec } + + for evt in ptdT.GetEvents(bindAll) |> Seq.choose (function :? ProvidedEvent as pe -> Some pe | _ -> None) do + if not evt.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedEvent. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" evt + let eb = tb.DefineEvent(evt.Name, evt.Attributes) + defineCustomAttrs eb.SetCustomAttribute (evt.GetCustomAttributesData()) + eb.SetAddOnMethod(methMap.[evt.GetAddMethod(true) :?> _]) + eb.SetRemoveOnMethod(methMap.[evt.GetRemoveMethod(true) :?> _]) + + for pinfo in ptdT.GetProperties(bindAll) |> Seq.choose (function :? ProvidedProperty as pe -> Some pe | _ -> None) do + + let pb = tb.DefineProperty(pinfo.Name, pinfo.Attributes, transType pinfo.PropertyType, [| for p in pinfo.GetIndexParameters() -> transType p.ParameterType |]) + + defineCustomAttrs pb.SetCustomAttribute (pinfo.GetCustomAttributesData()) + + if pinfo.CanRead then + let minfo = pinfo.GetGetMethod(true) + pb.SetGetMethod (methMap.[minfo :?> ProvidedMethod ]) + + if pinfo.CanWrite then + let minfo = pinfo.GetSetMethod(true) + pb.SetSetMethod (methMap.[minfo :?> ProvidedMethod ])) + + //printfn "saving generated binary to '%s'" assemblyFileName + assemblyBuilder.Save () + //printfn "re-reading generated binary from '%s'" assemblyFileName + let reader = ILModuleReaderAfterReadingAllBytes(assemblyFileName, ilg) + let bytes = File.ReadAllBytes(assemblyFileName) +#if DEBUG + printfn "generated binary is at '%s'" assemblyFileName #else - static member RegisterGenerated (fileName:string) = - //printfn "registered assembly in '%s'" fileName - let assemblyBytes = System.IO.File.ReadAllBytes fileName - let assembly = Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain) - GlobalProvidedAssemblyElementsTable.theTable.Add(assembly, Lazy<_>.CreateFromValue assemblyBytes) - assembly + File.Delete assemblyFileName #endif + // Use a real Reflection Load when running in F# Interactive + if isHostedExecution then + let realTargetAssembly = Assembly.Load(bytes) + for (ptdT, _) in providedTypeDefinitionsT do + ptdT.SetAssemblyInternal (K realTargetAssembly) -module Local = + bytes - let makeProvidedNamespace (namespaceName:string) (types:ProvidedTypeDefinition list) = - let types = [| for ty in types -> ty :> Type |] - {new IProvidedNamespace with - member __.GetNestedNamespaces() = [| |] - member __.NamespaceName = namespaceName - member __.GetTypes() = types |> Array.copy - member __.ResolveTypeName typeName : System.Type = - match types |> Array.tryFind (fun ty -> ty.Name = typeName) with - | Some ty -> ty - | None -> null - } +#endif // NO_GENERATIVE + +//------------------------------------------------------------------------------------------------- +// TypeProviderForNamespaces + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + + type TypeProviderForNamespaces(config: TypeProviderConfig, namespacesAndTypes: list<(string * list)>, assemblyReplacementMap: (string*string) list, sourceAssemblies: Assembly list, addDefaultProbingLocation: bool) as this = + + let ctxt = ProvidedTypesContext.Create (config, assemblyReplacementMap, sourceAssemblies) + +#if !NO_GENERATIVE + let theTable = ConcurrentDictionary() + + // When using hosted execution (i.e. in F# Interactive), ensure the generated assembly for a generated type is + // actually fully compiled and loaded as a reflection-load assembly before handing the type back to the API. + let ensureCompiled (t: Type) = + match t with + | :? ProvidedTypeDefinition as pt when pt.IsErased || pt.GetStaticParametersInternal().Length > 0 || not config.IsHostedExecution -> t + | _ -> + let origAssembly = t.Assembly + + // We expect the results reported by t.Assembly to actually change after this call, because the act of compilation + // when isHostedExecution=true replaces the Assembly object reported. + (this :> ITypeProvider).GetGeneratedAssemblyContents(origAssembly) |> ignore + + //printfn "t.Assembly = %O" t.Assembly + //printfn "t.Assembly.Location = %O" t.Assembly.Location + //printfn "t.FullName = %O" t.FullName + //printfn "t.Assembly.GetTypes() = %A" (t.Assembly.GetTypes()) + let tyName = t.FullName.Replace(",", "\\,") + let newAssembly = t.Assembly + let newAssemblyName = newAssembly.GetName().Name + let origAssemblyName = origAssembly.GetName().Name + // check the assembly was generated with the correct name + if newAssemblyName <> origAssemblyName then + failwithf "expected identical assembly name keys '%s' and '%s'" origAssemblyName newAssemblyName + + // check the type really exists + if t.Assembly.GetType(tyName) = null then + failwithf "couldn't find type '%s' in assembly '%O'" tyName t.Assembly + + t -#if FX_NO_LOCAL_FILESYSTEM -type TypeProviderForNamespaces(namespacesAndTypes : list<(string * list)>) = #else -type TypeProviderForNamespaces(namespacesAndTypes : list<(string * list)>) as this = + let ensureCompiled (t: Type) = t #endif - let otherNamespaces = ResizeArray>() - let providedNamespaces = - lazy [| for (namespaceName,types) in namespacesAndTypes do - yield Local.makeProvidedNamespace namespaceName types - for (namespaceName,types) in otherNamespaces do - yield Local.makeProvidedNamespace namespaceName types |] + let makeProvidedNamespace (namespaceName:string) (typesSrc:ProvidedTypeDefinition list) = + let typesSrc = [| for ty in typesSrc -> ty :> Type |] + let nsSrc = + { new IProvidedNamespace with + member __.GetNestedNamespaces() = [| |] + member __.NamespaceName = namespaceName + member __.GetTypes() = typesSrc |> Array.map ensureCompiled + member __.ResolveTypeName typeName = typesSrc |> Array.tryFind (fun ty -> ty.Name = typeName) |> Option.map ensureCompiled |> Option.toObj } + let nsT = ctxt.ConvertSourceNamespaceToTarget nsSrc + nsT - let invalidateE = new Event() + let namespacesT = ResizeArray() - let disposing = Event() + do for (namespaceName, types) in namespacesAndTypes do + namespacesT.Add (makeProvidedNamespace namespaceName types) -#if FX_NO_LOCAL_FILESYSTEM -#else - let probingFolders = ResizeArray() - let handler = ResolveEventHandler(fun _ args -> this.ResolveAssembly(args)) - do AppDomain.CurrentDomain.add_AssemblyResolve handler + let invalidateE = new Event() + + let disposing = Event() + + +#if !FX_NO_LOCAL_FILESYSTEM + let probingFolders = ResizeArray() + let handler = ResolveEventHandler(fun _ args -> this.ResolveAssembly(args)) + do AppDomain.CurrentDomain.add_AssemblyResolve handler #endif - new (namespaceName:string,types:list) = new TypeProviderForNamespaces([(namespaceName,types)]) - new () = new TypeProviderForNamespaces([]) + // By default add the location of the TPDTC assembly (which is assumed to contain this file) + // as a probing location. + do if addDefaultProbingLocation then + let thisAssembly = Assembly.GetExecutingAssembly() + let folder = thisAssembly.Location |> Path.GetDirectoryName + probingFolders.Add folder + + new (config, namespaceName, types, ?sourceAssemblies, ?assemblyReplacementMap, ?addDefaultProbingLocation) = + let sourceAssemblies = defaultArg sourceAssemblies [ Assembly.GetCallingAssembly() ] + let assemblyReplacementMap = defaultArg assemblyReplacementMap [] + let addDefaultProbingLocation = defaultArg addDefaultProbingLocation false + new TypeProviderForNamespaces(config, [(namespaceName, types)], assemblyReplacementMap=assemblyReplacementMap, sourceAssemblies=sourceAssemblies, addDefaultProbingLocation=addDefaultProbingLocation) - [] - member __.Disposing = disposing.Publish + new (config, ?sourceAssemblies, ?assemblyReplacementMap, ?addDefaultProbingLocation) = + let sourceAssemblies = defaultArg sourceAssemblies [ Assembly.GetCallingAssembly() ] + let assemblyReplacementMap = defaultArg assemblyReplacementMap [] + let addDefaultProbingLocation = defaultArg addDefaultProbingLocation false + new TypeProviderForNamespaces(config, [], assemblyReplacementMap=assemblyReplacementMap, sourceAssemblies=sourceAssemblies, addDefaultProbingLocation=addDefaultProbingLocation) + + member __.TargetContext = ctxt + + [] + member __.Disposing = disposing.Publish #if FX_NO_LOCAL_FILESYSTEM - interface System.IDisposable with - member x.Dispose() = - disposing.Trigger(x, EventArgs.Empty) + + interface IDisposable with + member x.Dispose() = + disposing.Trigger(x, EventArgs.Empty) + #else - abstract member ResolveAssembly : args : System.ResolveEventArgs -> Assembly - - default __.ResolveAssembly(args) = - let expectedName = (AssemblyName(args.Name)).Name + ".dll" - let expectedLocationOpt = - probingFolders - |> Seq.map (fun f -> IO.Path.Combine(f, expectedName)) - |> Seq.tryFind IO.File.Exists - match expectedLocationOpt with - | Some f -> Assembly.LoadFrom f - | None -> null - - member __.RegisterProbingFolder (folder) = - // use GetFullPath to ensure that folder is valid - ignore(IO.Path.GetFullPath folder) - probingFolders.Add folder - - member __.RegisterRuntimeAssemblyLocationAsProbingFolder (config : TypeProviderConfig) = - config.RuntimeAssembly - |> IO.Path.GetDirectoryName - |> this.RegisterProbingFolder - - interface System.IDisposable with - member x.Dispose() = - disposing.Trigger(x, EventArgs.Empty) - AppDomain.CurrentDomain.remove_AssemblyResolve handler -#endif - member __.AddNamespace (namespaceName,types:list<_>) = otherNamespaces.Add (namespaceName,types) + abstract member ResolveAssembly: args: ResolveEventArgs -> Assembly + + default __.ResolveAssembly(args) = + let expectedName = (AssemblyName(args.Name)).Name + ".dll" + let expectedLocationOpt = + probingFolders + |> Seq.map (fun f -> Path.Combine(f, expectedName)) + |> Seq.tryFind File.Exists + match expectedLocationOpt with + | Some f -> Assembly.LoadFrom f + | None -> null + + member __.RegisterProbingFolder (folder) = + // use GetFullPath to ensure that folder is valid + ignore(Path.GetFullPath folder) + probingFolders.Add folder + + member __.RegisterRuntimeAssemblyLocationAsProbingFolder (config: TypeProviderConfig) = + config.RuntimeAssembly + |> Path.GetDirectoryName + |> this.RegisterProbingFolder + + interface IDisposable with + member x.Dispose() = + disposing.Trigger(x, EventArgs.Empty) + AppDomain.CurrentDomain.remove_AssemblyResolve handler +#endif - // FSharp.Data addition: this method is used by Debug.fs - member __.Namespaces = Seq.readonly otherNamespaces + member __.AddNamespace (namespaceName, types) = + namespacesT.Add (makeProvidedNamespace namespaceName types) - member this.Invalidate() = invalidateE.Trigger(this,EventArgs()) + member __.Namespaces = + namespacesT.ToArray() - member __.GetStaticParametersForMethod(mb: MethodBase) = - printfn "In GetStaticParametersForMethod" - match mb with - | :? ProvidedMethod as t -> t.GetStaticParameters() - | _ -> [| |] + member this.Invalidate() = + invalidateE.Trigger(this, EventArgs()) - member __.ApplyStaticArgumentsForMethod(mb: MethodBase, mangledName, objs) = - printfn "In ApplyStaticArgumentsForMethod" - match mb with - | :? ProvidedMethod as t -> t.ApplyStaticArguments(mangledName, objs) :> MethodBase - | _ -> failwith (sprintf "ApplyStaticArguments: static parameters for method %s are unexpected" mb.Name) + member __.GetStaticParametersForMethod(mb: MethodBase) = + match mb with + | :? ProvidedMethod as t -> t.GetStaticParametersInternal() + | _ -> [| |] - interface ITypeProvider with + member __.ApplyStaticArgumentsForMethod(mb: MethodBase, mangledName, objs) = + match mb with + | :? ProvidedMethod as t -> t.ApplyStaticArguments(mangledName, objs) :> MethodBase + | _ -> failwithf "ApplyStaticArguments: static parameters for method %s are unexpected. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" mb.Name + + interface ITypeProvider with + + [] + member __.Invalidate = invalidateE.Publish + + member __.GetNamespaces() = namespacesT.ToArray() + + member __.GetInvokerExpression(methodBaseT, parametersT) = + + /// This checks that the GetInvokeCodeInternal doesn't return things containing calls to other provided methods or constructors. + let rec check expr = + match expr with + | NewObject((:? ProvidedConstructor), _) + | Call(_, :? ProvidedMethod, _) -> failwithf "The invokeCode for a ProvidedConstructor or ProvidedMethod included a use or another ProvidedConstructor or ProvidedMethod '%A'. This is not allowed. Instead, the invokeCode should be the compiled representation without invoking other provided objects" expr + | ShapeCombinationUnchecked(shape, args) -> RebuildShapeCombinationUnchecked(shape, List.map check args) + | ShapeVarUnchecked v -> Expr.Var v + | ShapeLambdaUnchecked(v, body) -> Expr.Lambda(v, check body) + + match methodBaseT with + | :? ProvidedMethod as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> + match mT.GetInvokeCode with + | Some _ when methodBaseT.DeclaringType.IsInterface -> + failwith "The provided type definition is an interface; therefore, it should not define an implementation for its members." + (* NOTE: These checks appear to fail for generative abstract and virtual methods. + | Some _ when mT.IsAbstract -> + failwith "The provided method is defined as abstract; therefore, it should not define an implementation." + | None when not mT.IsAbstract -> + failwith "The provided method is not defined as abstract; therefore it should define an implementation." + *) + | Some invokeCode -> + let exprT = invokeCode(Array.toList parametersT) + check exprT + | None -> <@@ () @@> + + | :? ProvidedConstructor as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> + if methodBaseT.DeclaringType.IsInterface then + failwith "The provided type definition is an interface; therefore, it should not define any constructors." + else + let exprT = mT.GetInvokeCode(Array.toList parametersT) + check exprT - [] - override __.Invalidate = invalidateE.Publish - - override __.GetNamespaces() = Array.copy providedNamespaces.Value - - member __.GetInvokerExpression(methodBase, parameters) = - let rec getInvokerExpression (methodBase : MethodBase) parameters = - match methodBase with - | :? ProvidedMethod as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> - m.GetInvokeCodeInternal false parameters - |> expand - | :? ProvidedConstructor as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> - m.GetInvokeCodeInternal false parameters - |> expand // Otherwise, assume this is a generative assembly and just emit a call to the constructor or method - | :? ConstructorInfo as cinfo -> - Quotations.Expr.NewObject(cinfo, Array.toList parameters) - | :? System.Reflection.MethodInfo as minfo -> - if minfo.IsStatic then - Quotations.Expr.Call(minfo, Array.toList parameters) + | :? ConstructorInfo as cinfoT -> + Expr.NewObjectUnchecked(cinfoT, Array.toList parametersT) + + | :? MethodInfo as minfoT -> + if minfoT.IsStatic then + Expr.CallUnchecked(minfoT, Array.toList parametersT) else - Quotations.Expr.Call(parameters.[0], minfo, Array.toList parameters.[1..]) - | _ -> failwith ("TypeProviderForNamespaces.GetInvokerExpression: not a ProvidedMethod/ProvidedConstructor/ConstructorInfo/MethodInfo, name=" + methodBase.Name + " class=" + methodBase.GetType().FullName) - and expand expr = - match expr with - | Quotations.Patterns.NewObject(ctor, args) -> getInvokerExpression ctor [| for arg in args -> expand arg|] - | Quotations.Patterns.Call(inst, mi, args) -> - let args = - [| - match inst with - | Some inst -> yield expand inst - | _ -> () - yield! List.map expand args - |] - getInvokerExpression mi args - | Quotations.ExprShape.ShapeVar v -> Quotations.Expr.Var v - | Quotations.ExprShape.ShapeLambda(v, body) -> Quotations.Expr.Lambda(v, expand body) - | Quotations.ExprShape.ShapeCombination(shape, args) -> Quotations.ExprShape.RebuildShapeCombination(shape, List.map expand args) - getInvokerExpression methodBase parameters -#if FX_NO_CUSTOMATTRIBUTEDATA - - member __.GetMemberCustomAttributesData(methodBase) = - match methodBase with - | :? ProvidedTypeDefinition as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedMethod as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedProperty as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedConstructor as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedEvent as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedLiteralField as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedField as m -> m.GetCustomAttributesDataImpl() - | _ -> [| |] :> IList<_> - - member __.GetParameterCustomAttributesData(methodBase) = - match methodBase with - | :? ProvidedParameter as m -> m.GetCustomAttributesDataImpl() - | _ -> [| |] :> IList<_> + Expr.CallUnchecked(parametersT.[0], minfoT, Array.toList parametersT.[1..]) + | _ -> failwith ("TypeProviderForNamespaces.GetInvokerExpression: not a ProvidedMethod/ProvidedConstructor/ConstructorInfo/MethodInfo, name=" + methodBaseT.Name + " class=" + methodBaseT.GetType().FullName) -#endif - override __.GetStaticParameters(ty) = - match ty with - | :? ProvidedTypeDefinition as t -> - if ty.Name = t.Name (* REVIEW: use equality? *) then - t.GetStaticParameters() - else - [| |] - | _ -> [| |] + member __.GetStaticParameters(ty) = + match ty with + | :? ProvidedTypeDefinition as t -> + if ty.Name = t.Name then + t.GetStaticParametersInternal() + else + [| |] + | _ -> [| |] - override __.ApplyStaticArguments(ty,typePathAfterArguments:string[],objs) = - let typePathAfterArguments = typePathAfterArguments.[typePathAfterArguments.Length-1] - match ty with - | :? ProvidedTypeDefinition as t -> (t.MakeParametricType(typePathAfterArguments,objs) :> Type) - | _ -> failwith (sprintf "ApplyStaticArguments: static params for type %s are unexpected" ty.FullName) + member __.ApplyStaticArguments(ty, typePathAfterArguments:string[], objs) = + let typePathAfterArguments = typePathAfterArguments.[typePathAfterArguments.Length-1] + match ty with + | :? ProvidedTypeDefinition as t -> + let ty = (t.ApplyStaticArguments(typePathAfterArguments, objs) :> Type) + ensureCompiled ty -#if FX_NO_LOCAL_FILESYSTEM - override __.GetGeneratedAssemblyContents(_assembly) = - // TODO: this is very fake, we rely on the fact it is never needed - match System.Windows.Application.GetResourceStream(System.Uri("FSharp.Core.dll",System.UriKind.Relative)) with - | null -> failwith "FSharp.Core.dll not found as Manifest Resource, we're just trying to read some random .NET assembly, ok?" - | resStream -> - use stream = resStream.Stream - let len = stream.Length - let buf = Array.zeroCreate (int len) - let rec loop where rem = - let n = stream.Read(buf, 0, int rem) - if n < rem then loop (where + n) (rem - n) - loop 0 (int len) - buf - - //failwith "no file system" + | _ -> failwithf "ApplyStaticArguments: static params for type %s are unexpected, it is not a provided type definition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" ty.FullName + + member __.GetGeneratedAssemblyContents(assembly:Assembly) = +#if NO_GENERATIVE + ignore assembly; failwith "no generative assemblies" #else - override __.GetGeneratedAssemblyContents(assembly:Assembly) = - //printfn "looking up assembly '%s'" assembly.FullName - match GlobalProvidedAssemblyElementsTable.theTable.TryGetValue assembly with - | true,bytes -> bytes.Force() - | _ -> - let bytes = System.IO.File.ReadAllBytes assembly.ManifestModule.FullyQualifiedName - GlobalProvidedAssemblyElementsTable.theTable.[assembly] <- Lazy<_>.CreateFromValue bytes - bytes + //printfn "looking up assembly '%s'" assembly.FullName + let key = assembly.GetName().Name + match theTable.TryGetValue key with + | true, bytes -> bytes + | _ -> + let bytes = + match assembly with + | :? ProvidedAssembly as targetAssembly -> AssemblyCompiler(targetAssembly, ctxt).Compile(config.IsHostedExecution) + | _ -> File.ReadAllBytes assembly.ManifestModule.FullyQualifiedName + theTable.[key] <- bytes + bytes + +#if !NO_GENERATIVE + member __.RegisterGeneratedTargetAssembly (fileName:string) = + let assemblyBytes = File.ReadAllBytes fileName + //printfn "registering assembly in '%s'" fileName + let assembly = + if config.IsHostedExecution then + Assembly.Load(assemblyBytes) // we need a real on-disk assembly + else + ctxt.ReadRelatedAssembly(fileName) + ctxt.AddTargetAssembly(assembly.GetName(), assembly) + let key = assembly.GetName().Name + theTable.[key] <- assemblyBytes + assembly + +#endif #endif diff --git a/tests/service/data/TestTP/ProvidedTypes.fsi b/tests/service/data/TestTP/ProvidedTypes.fsi index 3eb5025f6d4..c3adbe82831 100644 --- a/tests/service/data/TestTP/ProvidedTypes.fsi +++ b/tests/service/data/TestTP/ProvidedTypes.fsi @@ -1,260 +1,225 @@ // Copyright (c) Microsoft Corporation 2005-2014 and other contributors. -// This sample code is provided "as is" without warranty of any kind. -// We disclaim all warranties, either express or implied, including the -// warranties of merchantability and fitness for a particular purpose. +// This sample code is provided "as is" without warranty of any kind. +// We disclaim all warranties, either express or implied, including the +// warranties of merchantability and fitness for a particular purpose. // -// This file contains a set of helper types and methods for providing types in an implementation +// This file contains a set of helper types and methods for providing types in an implementation // of ITypeProvider. // // This code has been modified and is appropriate for use in conjunction with the F# 3.0-4.0 releases - namespace ProviderImplementation.ProvidedTypes open System open System.Reflection -open System.Linq.Expressions +open Microsoft.FSharp.Quotations open Microsoft.FSharp.Core.CompilerServices /// Represents an erased provided parameter +[] type ProvidedParameter = inherit ParameterInfo - new : parameterName: string * parameterType: Type * ?isOut:bool * ?optionalValue:obj -> ProvidedParameter - member IsParamArray : bool with get,set + + /// Create a new provided parameter. + new : parameterName: string * parameterType: Type * ?isOut: bool * ?optionalValue: obj -> ProvidedParameter + + /// Indicates if the parameter is marked as ParamArray + member IsParamArray: bool with set + + /// Indicates if the parameter is marked as ReflectedDefinition + member IsReflectedDefinition: bool with set + + /// Indicates if the parameter has a default value + member HasDefaultParameterValue: bool + + /// Add a custom attribute to the provided parameter. + member AddCustomAttribute: CustomAttributeData -> unit /// Represents a provided static parameter. +[] type ProvidedStaticParameter = inherit ParameterInfo - new : parameterName: string * parameterType:Type * ?parameterDefaultValue:obj -> ProvidedStaticParameter + + /// Create a new provided static parameter, for use with DefineStaticParamaeters on a provided type definition. + new: parameterName: string * parameterType: Type * ?parameterDefaultValue: obj -> ProvidedStaticParameter /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit /// Represents an erased provided constructor. -type ProvidedConstructor = +[] +type ProvidedConstructor = inherit ConstructorInfo - /// Create a new provided constructor. It is not initially associated with any specific provided type definition. - new : parameters: ProvidedParameter list -> ProvidedConstructor + /// When making a cross-targeting type provider, use this method instead of the ProvidedConstructor constructor from ProvidedTypes + new: parameters: ProvidedParameter list * invokeCode: (Expr list -> Expr) -> ProvidedConstructor + + /// Add a 'Obsolete' attribute to this provided constructor + member AddObsoleteAttribute: message: string * ?isError: bool -> unit - /// Add a 'System.Obsolete' attribute to this provided constructor - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - + member AddXmlDoc: xmlDoc: string -> unit + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Set the quotation used to compute the implementation of invocations of this constructor. - member InvokeCode : (Quotations.Expr list -> Quotations.Expr) with set + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit - /// FSharp.Data addition: this method is used by Debug.fs - member internal GetInvokeCodeInternal : bool -> (Quotations.Expr [] -> Quotations.Expr) + /// Add XML documentation information to this provided constructor, where the documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit /// Set the target and arguments of the base constructor call. Only used for generated types. - member BaseConstructorCall : (Quotations.Expr list -> ConstructorInfo * Quotations.Expr list) with set + member BaseConstructorCall: (Expr list -> ConstructorInfo * Expr list) with set /// Set a flag indicating that the constructor acts like an F# implicit constructor, so the /// parameters of the constructor become fields and can be accessed using Expr.GlobalVar with the /// same name. - member IsImplicitCtor : bool with get,set + member IsImplicitConstructor: bool with get,set /// Add definition location information to the provided constructor. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - member IsTypeInitializer : bool with get,set + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + member IsTypeInitializer: bool with get,set + + /// This method is for internal use only in the type provider SDK + member internal GetInvokeCode: Expr list -> Expr -type ProvidedMethod = +[] +type ProvidedMethod = inherit MethodInfo - /// Create a new provided method. It is not initially associated with any specific provided type definition. - new : methodName:string * parameters: ProvidedParameter list * returnType: Type -> ProvidedMethod + /// When making a cross-targeting type provider, use this method instead of the ProvidedMethod constructor from ProvidedTypes + new: methodName: string * parameters: ProvidedParameter list * returnType: Type * ?invokeCode: (Expr list -> Expr) * ?isStatic: bool -> ProvidedMethod /// Add XML documentation information to this provided method - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + member AddObsoleteAttribute: message: string * ?isError: bool -> unit /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - member AddMethodAttrs : attributes:MethodAttributes -> unit + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit - /// Set the method attributes of the method. By default these are simple 'MethodAttributes.Public' - member SetMethodAttrs : attributes:MethodAttributes -> unit - - /// Get or set a flag indicating if the property is static. - member IsStaticMethod : bool with get, set + member AddMethodAttrs: attributes:MethodAttributes -> unit - /// Set the quotation used to compute the implementation of invocations of this method. - member InvokeCode : (Quotations.Expr list -> Quotations.Expr) with set - - /// FSharp.Data addition: this method is used by Debug.fs - member internal GetInvokeCodeInternal : bool -> (Quotations.Expr [] -> Quotations.Expr) + /// Set the method attributes of the method. By default these are simple 'MethodAttributes.Public' + member SetMethodAttrs: attributes:MethodAttributes -> unit /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit /// Add a custom attribute to the provided method definition. - member AddCustomAttribute : CustomAttributeData -> unit + member AddCustomAttribute: CustomAttributeData -> unit /// Define the static parameters available on a statically parameterized method - member DefineStaticParameters : parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedMethod) -> unit + member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedMethod) -> unit + + /// This method is for internal use only in the type provider SDK + member internal GetInvokeCode: (Expr list -> Expr) option /// Represents an erased provided property. +[] type ProvidedProperty = inherit PropertyInfo - /// Create a new provided type. It is not initially associated with any specific provided type definition. - new : propertyName: string * propertyType: Type * ?parameters:ProvidedParameter list -> ProvidedProperty + /// Create a new provided property. It is not initially associated with any specific provided type definition. + new: propertyName: string * propertyType: Type * ?getterCode: (Expr list -> Expr) * ?setterCode: (Expr list -> Expr) * ?isStatic: bool * ?indexParameters: ProvidedParameter list -> ProvidedProperty - /// Add a 'System.Obsolete' attribute to this provided property - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + /// Add a 'Obsolete' attribute to this provided property + member AddObsoleteAttribute: message: string * ?isError: bool -> unit /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Get or set a flag indicating if the property is static. - /// FSharp.Data addition: the getter is used by Debug.fs - member IsStatic : bool with get,set - - /// Set the quotation used to compute the implementation of gets of this property. - member GetterCode : (Quotations.Expr list -> Quotations.Expr) with set + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit - /// Set the function used to compute the implementation of sets of this property. - member SetterCode : (Quotations.Expr list -> Quotations.Expr) with set + /// Get or set a flag indicating if the property is static. + member IsStatic: bool /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit /// Add a custom attribute to the provided property definition. - member AddCustomAttribute : CustomAttributeData -> unit + member AddCustomAttribute: CustomAttributeData -> unit /// Represents an erased provided property. +[] type ProvidedEvent = inherit EventInfo - /// Create a new provided type. It is not initially associated with any specific provided type definition. - new : propertyName: string * eventHandlerType: Type -> ProvidedEvent + /// Create a new provided event. It is not initially associated with any specific provided type definition. + new: eventName: string * eventHandlerType: Type * adderCode: (Expr list -> Expr) * removerCode: (Expr list -> Expr) * ?isStatic: bool -> ProvidedEvent /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Get or set a flag indicating if the property is static. - member IsStatic : bool with set - - /// Set the quotation used to compute the implementation of gets of this property. - member AdderCode : (Quotations.Expr list -> Quotations.Expr) with set + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit - /// Set the function used to compute the implementation of sets of this property. - member RemoverCode : (Quotations.Expr list -> Quotations.Expr) with set + /// Get a flag indicating if the property is static. + member IsStatic: bool with get /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit /// Represents an erased provided field. -type ProvidedLiteralField = +[] +type ProvidedField = inherit FieldInfo /// Create a new provided field. It is not initially associated with any specific provided type definition. - new : fieldName: string * fieldType: Type * literalValue: obj -> ProvidedLiteralField + new: fieldName: string * fieldType: Type -> ProvidedField - /// Add a 'System.Obsolete' attribute to this provided field - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + /// Add a 'Obsolete' attribute to this provided field + member AddObsoleteAttribute: message: string * ?isError: bool -> unit /// Add XML documentation information to this provided field - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Add definition location information to the provided field. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - -/// Represents an erased provided field. -type ProvidedField = - inherit FieldInfo - - /// Create a new provided field. It is not initially associated with any specific provided type definition. - new : fieldName: string * fieldType: Type -> ProvidedField + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit - /// Add a 'System.Obsolete' attribute to this provided field - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + /// Add definition location information to the provided field definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit - /// Add XML documentation information to this provided field - member AddXmlDoc : xmlDoc: string -> unit + member SetFieldAttributes: attributes: FieldAttributes -> unit - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit + /// Add a custom attribute to the provided property definition. + member AddCustomAttribute: CustomAttributeData -> unit - /// Add definition location information to the provided field definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - member SetFieldAttributes : attributes : FieldAttributes -> unit - -/// Represents the type constructor in a provided symbol type. -[] -type SymbolKind = - /// Indicates that the type constructor is for a single-dimensional array - | SDArray - /// Indicates that the type constructor is for a multi-dimensional array - | Array of int - /// Indicates that the type constructor is for pointer types - | Pointer - /// Indicates that the type constructor is for byref types - | ByRef - /// Indicates that the type constructor is for named generic types - | Generic of Type - /// Indicates that the type constructor is for abbreviated types - | FSharpTypeAbbreviation of (Assembly * string * string[]) + /// Create a new provided literal field. It is not initially associated with any specific provided type definition. + static member Literal : fieldName: string * fieldType: Type * literalValue:obj -> ProvidedField /// Represents an array or other symbolic type involving a provided type as the argument. /// See the type provider spec for the methods that must be implemented. /// Note that the type provider specification does not require us to implement pointer-equality for provided types. [] -type ProvidedSymbolType = - inherit Type - - /// Returns the kind of this symbolic type - member Kind : SymbolKind +type ProvidedTypeSymbol = + inherit TypeDelegator - /// Return the provided types used as arguments of this symbolic type - member Args : list + /// For example, kg + member IsFSharpTypeAbbreviation: bool + /// For example, int or int + member IsFSharpUnitAnnotated: bool /// Helpers to build symbolic provided types [] @@ -266,202 +231,330 @@ type ProvidedTypeBuilder = /// Like methodInfo.MakeGenericMethod, but will also work with unit-annotated types and provided types static member MakeGenericMethod: genericMethodDefinition: MethodInfo * genericArguments: Type list -> MethodInfo + /// Like FsharpType.MakeTupleType, but will also work with unit-annotated types and provided types + static member MakeTupleType: types: Type list*isStruct: bool -> Type + + /// Like FsharpType.MakeTupleType, but will also work with unit-annotated types and provided types + static member MakeTupleType: types: Type list -> Type + /// Helps create erased provided unit-of-measure annotations. [] type ProvidedMeasureBuilder = - - /// The ProvidedMeasureBuilder for building measures. - static member Default : ProvidedMeasureBuilder - /// Gets the measure indicating the "1" unit of measure, that is the unitless measure. - member One : Type + /// Gets the measure indicating the "1" unit of measure, that is the unitless measure. + static member One: Type /// Returns the measure indicating the product of two units of measure, e.g. kg * m - member Product : measure1: Type * measure1: Type -> Type + static member Product: measure1: Type * measure2: Type -> Type /// Returns the measure indicating the inverse of two units of measure, e.g. 1 / s - member Inverse : denominator: Type -> Type + static member Inverse: denominator: Type -> Type /// Returns the measure indicating the ratio of two units of measure, e.g. kg / m - member Ratio : numerator: Type * denominator: Type -> Type - + static member Ratio: numerator: Type * denominator: Type -> Type + /// Returns the measure indicating the square of a unit of measure, e.g. m * m - member Square : ``measure``: Type -> Type - + static member Square: ``measure``: Type -> Type + /// Returns the measure for an SI unit from the F# core library, where the string is in capitals and US spelling, e.g. Meter - member SI : unitName:string -> Type - + static member SI: unitName:string -> Type + /// Returns a type where the type has been annotated with the given types and/or units-of-measure. /// e.g. float, Vector - member AnnotateType : basic: Type * argument: Type list -> Type - + static member AnnotateType: basic: Type * argument: Type list -> Type /// Represents a provided type definition. +[] type ProvidedTypeDefinition = - inherit Type + inherit TypeDelegator - /// Create a new provided type definition in a namespace. - new : assembly: Assembly * namespaceName: string * className: string * baseType: Type option -> ProvidedTypeDefinition + /// When making a cross-targeting type provider, use this method instead of the corresponding ProvidedTypeDefinition constructor from ProvidedTypes + new: className: string * baseType: Type option * ?hideObjectMethods: bool * ?nonNullable: bool * ?isErased: bool * ?isSealed: bool * ?isInterface: bool * ?isAbstract: bool -> ProvidedTypeDefinition - /// Create a new provided type definition, to be located as a nested type in some type definition. - new : className : string * baseType: Type option -> ProvidedTypeDefinition + /// When making a cross-targeting type provider, use this method instead of the corresponding ProvidedTypeDefinition constructor from ProvidedTypes + new: assembly: Assembly * namespaceName: string * className: string * baseType: Type option * ?hideObjectMethods: bool * ?nonNullable: bool * ?isErased: bool * ?isSealed: bool * ?isInterface: bool * ?isAbstract: bool -> ProvidedTypeDefinition /// Add the given type as an implemented interface. - member AddInterfaceImplementation : interfaceType: Type -> unit + member AddInterfaceImplementation: interfaceType: Type -> unit /// Add the given function as a set of on-demand computed interfaces. - member AddInterfaceImplementationsDelayed : interfacesFunction:(unit -> Type list)-> unit + member AddInterfaceImplementationsDelayed: interfacesFunction:(unit -> Type list)-> unit /// Specifies that the given method body implements the given method declaration. - member DefineMethodOverride : methodInfoBody: ProvidedMethod * methodInfoDeclaration: MethodInfo -> unit + member DefineMethodOverride: methodInfoBody: ProvidedMethod * methodInfoDeclaration: MethodInfo -> unit + + /// Specifies that the given method bodies implement the given method declarations + member DefineMethodOverridesDelayed: (unit -> (ProvidedMethod * MethodInfo) list) -> unit - /// Add a 'System.Obsolete' attribute to this provided type definition - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + /// Add a 'Obsolete' attribute to this provided type definition + member AddObsoleteAttribute: message: string * ?isError: bool -> unit /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit + member AddXmlDoc: xmlDoc: string -> unit /// Set the base type - member SetBaseType : Type -> unit + member SetBaseType: Type -> unit /// Set the base type to a lazily evaluated value. Use this to delay realization of the base type as late as possible. - member SetBaseTypeDelayed : baseTypeFunction:(unit -> Type) -> unit + member SetBaseTypeDelayed: baseTypeFunction:(unit -> Type) -> unit /// Set underlying type for generated enums - member SetEnumUnderlyingType : Type -> unit + member SetEnumUnderlyingType: Type -> unit /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary. /// The documentation is only computed once. - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + /// Set the attributes on the provided type. This fully replaces the default TypeAttributes. - member SetAttributes : TypeAttributes -> unit - - /// Reset the enclosing type (for generated nested types) - member ResetEnclosingType: enclosingType:Type -> unit - + member SetAttributes: TypeAttributes -> unit + /// Add a method, property, nested type or other member to a ProvidedTypeDefinition - member AddMember : memberInfo:MemberInfo -> unit + member AddMember: memberInfo:MemberInfo -> unit /// Add a set of members to a ProvidedTypeDefinition - member AddMembers : memberInfos:list<#MemberInfo> -> unit + member AddMembers: memberInfos:list<#MemberInfo> -> unit /// Add a member to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. - member AddMemberDelayed : memberFunction:(unit -> #MemberInfo) -> unit + member AddMemberDelayed: memberFunction:(unit -> #MemberInfo) -> unit /// Add a set of members to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. - member AddMembersDelayed : membersFunction:(unit -> list<#MemberInfo>) -> unit - + member AddMembersDelayed: membersFunction:(unit -> list<#MemberInfo>) -> unit + /// Add the types of the generated assembly as generative types, where types in namespaces get hierarchically positioned as nested types. - member AddAssemblyTypesAsNestedTypesDelayed : assemblyFunction:(unit -> Assembly) -> unit + member AddAssemblyTypesAsNestedTypesDelayed: assemblyFunction:(unit -> Assembly) -> unit /// Define the static parameters available on a statically parameterized type - member DefineStaticParameters : parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition) -> unit + member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition) -> unit /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit - /// Suppress System.Object entries in intellisense menus in instances of this provided type - member HideObjectMethods : bool with set + /// Suppress Object entries in intellisense menus in instances of this provided type + member HideObjectMethods: bool - /// Disallows the use of the null literal. - member NonNullable : bool with set + /// Disallows the use of the null literal. + member NonNullable: bool - /// Get or set a flag indicating if the ProvidedTypeDefinition is erased - member IsErased : bool with get,set + /// Get a flag indicating if the ProvidedTypeDefinition is erased + member IsErased: bool /// Get or set a flag indicating if the ProvidedTypeDefinition has type-relocation suppressed [] - member SuppressRelocation : bool with get,set + member SuppressRelocation: bool with get,set - /// FSharp.Data addition: this method is used by Debug.fs - member MakeParametricType : name:string * args:obj[] -> ProvidedTypeDefinition + // This method is used by Debug.fs + member ApplyStaticArguments: name:string * args:obj[] -> ProvidedTypeDefinition /// Add a custom attribute to the provided type definition. - member AddCustomAttribute : CustomAttributeData -> unit + member AddCustomAttribute: CustomAttributeData -> unit - /// Emulate the F# type provider type erasure mechanism to get the + /// Emulate the F# type provider type erasure mechanism to get the /// actual (erased) type. We erase ProvidedTypes to their base type /// and we erase array of provided type to array of base type. In the /// case of generics all the generic type arguments are also recursively /// replaced with the erased-to types - static member EraseType : typ:Type -> Type + static member EraseType: typ:Type -> Type /// Get or set a utility function to log the creation of root Provided Type. Used to debug caching/invalidation. - static member Logger : (string -> unit) option ref + static member Logger: (string -> unit) option ref + +#if !NO_GENERATIVE /// A provided generated assembly type ProvidedAssembly = + + inherit Assembly + /// Create a provided generated assembly - new : assemblyFileName:string -> ProvidedAssembly + new: assemblyName: AssemblyName * assemblyFileName:string -> ProvidedAssembly + + /// Create a provided generated assembly using a temporary file as the interim assembly storage + new: unit -> ProvidedAssembly - /// Emit the given provided type definitions as part of the assembly + /// Emit the given provided type definitions as part of the assembly /// and adjust the 'Assembly' property of all provided type definitions to return that /// assembly. /// /// The assembly is only emitted when the Assembly property on the root type is accessed for the first time. /// The host F# compiler does this when processing a generative type declaration for the type. - member AddTypes : types : ProvidedTypeDefinition list -> unit + member AddTypes: types: ProvidedTypeDefinition list -> unit /// /// Emit the given nested provided type definitions as part of the assembly. /// and adjust the 'Assembly' property of all provided type definitions to return that /// assembly. /// - /// A path of type names to wrap the generated types. The generated types are then generated as nested types. - member AddNestedTypes : types : ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit + /// Provided type definitions. + /// A path of type names to wrap the generated types. The generated types are then generated as nested types. + member AddNestedTypes: types: ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit -#if FX_NO_LOCAL_FILESYSTEM -#else - /// Register that a given file is a provided generated assembly - static member RegisterGenerated : fileName:string -> Assembly #endif +[] +/// Represents the context for which code is to be generated. Normally you should not need to use this directly. +type ProvidedTypesContext = + + /// Try to find the given target assembly in the context + member TryBindAssemblyNameToTarget: aref: AssemblyName -> Choice -/// A base type providing default implementations of type provider functionality when all provided -/// types are of type ProvidedTypeDefinition. -type TypeProviderForNamespaces = + /// Try to find the given target assembly in the context + member TryBindSimpleAssemblyNameToTarget: assemblyName: string -> Choice + + /// Get the list of referenced assemblies determined by the type provider configuration + member ReferencedAssemblyPaths: string list + + /// Get the resolved referenced assemblies determined by the type provider configuration + member GetTargetAssemblies : unit -> Assembly[] + + /// Get the set of design-time assemblies available to use as a basis for authoring provided types. + member GetSourceAssemblies : unit -> Assembly[] + + /// Add an assembly to the set of design-time assemblies available to use as a basis for authoring provided types + member AddSourceAssembly : Assembly -> unit + + /// Try to get the version of FSharp.Core referenced. May raise an exception if FSharp.Core has not been correctly resolved + member FSharpCoreAssemblyVersion: Version - /// Initializes a type provider to provide the types in the given namespace. - new : namespaceName:string * types: ProvidedTypeDefinition list -> TypeProviderForNamespaces + /// Returns a type from the referenced assemblies that corresponds to the given design-time type. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertSourceTypeToTarget: Type -> Type - /// Initializes a type provider - new : unit -> TypeProviderForNamespaces + /// Returns the design-time type that corresponds to the given type from the target referenced assemblies. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertTargetTypeToSource: Type -> Type + + /// Returns a quotation rebuilt with resepct to the types from the target referenced assemblies. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertSourceExprToTarget: Expr -> Expr + + /// Read the assembly related to this context + member ReadRelatedAssembly: fileName: string -> Assembly + + /// Read the assembly related to this context + member ReadRelatedAssembly: bytes: byte[] -> Assembly + +/// A base type providing default implementations of type provider functionality. +type TypeProviderForNamespaces = + + /// Initializes a type provider to provide the types in the given namespace. + /// Type provider config. + /// Name of namespace. + /// Provided type definitions. + /// + /// + /// Optionally specify the design-time assemblies available to use as a basis for authoring provided types. + /// The transitive dependencies of these assemblies are also included. By default + /// Assembly.GetCallingAssembly() and its transitive dependencies are used. + /// + /// + /// + /// Optionally specify a map of assembly names from source model to referenced assemblies. + /// + /// + /// + /// Optionally specify that the location of the type provider design-time component should be used to resolve failing assembly resolutions. + /// This flag or an equivalent call to RegisterProbingFolder is generally needed for any type provider design-time components loaded into .NET Core tooling. + /// + new: config: TypeProviderConfig * namespaceName:string * types: ProvidedTypeDefinition list * ?sourceAssemblies: Assembly list * ?assemblyReplacementMap: (string * string) list * ?addDefaultProbingLocation: bool -> TypeProviderForNamespaces + + /// Initializes a type provider. + /// Type provider config. + /// + /// Optionally specify the design-time assemblies available to use as a basis for authoring provided types. + /// The transitive dependencies of these assemblies are also included. By default + /// Assembly.GetCallingAssembly() and its transitive dependencies are used. + /// + /// + /// + /// Optionally specify a map of assembly names from source model to referenced assemblies. + /// + /// + /// + /// Optionally specify that the location of the type provider design-time component should be used to resolve failing assembly resolutions. + /// This flag or an equivalent call to RegisterProbingFolder is generally needed for any type provider design-time components loaded into .NET Core tooling. + /// + new: config: TypeProviderConfig * ?sourceAssemblies: Assembly list * ?assemblyReplacementMap: (string * string) list * ?addDefaultProbingLocation: bool -> TypeProviderForNamespaces /// Invoked by the type provider to add a namespace of provided types in the specification of the type provider. - member AddNamespace : namespaceName:string * types: ProvidedTypeDefinition list -> unit + member AddNamespace: namespaceName:string * types: ProvidedTypeDefinition list -> unit /// Invoked by the type provider to get all provided namespaces with their provided types. - member Namespaces : seq + member Namespaces: IProvidedNamespace[] /// Invoked by the type provider to invalidate the information provided by the provider - member Invalidate : unit -> unit + member Invalidate: unit -> unit /// Invoked by the host of the type provider to get the static parameters for a method. - member GetStaticParametersForMethod : MethodBase -> ParameterInfo[] - + member GetStaticParametersForMethod: MethodBase -> ParameterInfo[] + /// Invoked by the host of the type provider to apply the static argumetns for a method. - member ApplyStaticArgumentsForMethod : MethodBase * string * obj[] -> MethodBase + member ApplyStaticArgumentsForMethod: MethodBase * string * obj[] -> MethodBase -#if FX_NO_LOCAL_FILESYSTEM -#else - /// AssemblyResolve handler. Default implementation searches .dll file in registered folders - abstract ResolveAssembly : System.ResolveEventArgs -> Assembly - default ResolveAssembly : System.ResolveEventArgs -> Assembly +#if !FX_NO_LOCAL_FILESYSTEM + /// AssemblyResolve handler. Default implementation searches .dll file in registered folders + abstract ResolveAssembly: ResolveEventArgs -> Assembly + default ResolveAssembly: ResolveEventArgs -> Assembly /// Registers custom probing path that can be used for probing assemblies - member RegisterProbingFolder : folder: string -> unit + member RegisterProbingFolder: folder: string -> unit /// Registers location of RuntimeAssembly (from TypeProviderConfig) as probing folder - member RegisterRuntimeAssemblyLocationAsProbingFolder : config: TypeProviderConfig -> unit + member RegisterRuntimeAssemblyLocationAsProbingFolder: config: TypeProviderConfig -> unit + +#endif +#if !NO_GENERATIVE + /// Register that a given file is a provided generated target assembly, e.g. an assembly produced by an external + /// code generation tool. This assembly should be a target assembly, i.e. use the same asssembly references + /// as given by TargetContext.ReferencedAssemblyPaths + member RegisterGeneratedTargetAssembly: fileName: string -> Assembly #endif [] - member Disposing : IEvent + member Disposing: IEvent + + /// The context for which code is eventually to be generated. You should not normally + /// need to use this property directly, as translation from the compiler-hosted context to + /// the design-time context will normally be performed automatically. + member TargetContext: ProvidedTypesContext interface ITypeProvider + +module internal UncheckedQuotations = + + type Expr with + static member NewDelegateUnchecked: ty:Type * vs:Var list * body:Expr -> Expr + static member NewObjectUnchecked: cinfo:ConstructorInfo * args:Expr list -> Expr + static member NewArrayUnchecked: elementType:Type * elements:Expr list -> Expr + static member CallUnchecked: minfo:MethodInfo * args:Expr list -> Expr + static member CallUnchecked: obj:Expr * minfo:MethodInfo * args:Expr list -> Expr + static member ApplicationUnchecked: f:Expr * x:Expr -> Expr + static member PropertyGetUnchecked: pinfo:PropertyInfo * args:Expr list -> Expr + static member PropertyGetUnchecked: obj:Expr * pinfo:PropertyInfo * ?args:Expr list -> Expr + static member PropertySetUnchecked: pinfo:PropertyInfo * value:Expr * ?args:Expr list -> Expr + static member PropertySetUnchecked: obj:Expr * pinfo:PropertyInfo * value:Expr * ?args:Expr list -> Expr + static member FieldGetUnchecked: pinfo:FieldInfo -> Expr + static member FieldGetUnchecked: obj:Expr * pinfo:FieldInfo -> Expr + static member FieldSetUnchecked: pinfo:FieldInfo * value:Expr -> Expr + static member FieldSetUnchecked: obj:Expr * pinfo:FieldInfo * value:Expr -> Expr + static member TupleGetUnchecked: e:Expr * n:int -> Expr + static member LetUnchecked: v:Var * e:Expr * body:Expr -> Expr + static member NewRecordUnchecked : ty:Type * args:Expr list -> Expr + + type Shape + val ( |ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked| ): e:Expr -> Choice + val RebuildShapeCombinationUnchecked: Shape * args:Expr list -> Expr + +module internal AssemblyReader = + + module Reader = + + type ILModuleReader = class end + + val GetWeakReaderCache : unit -> System.Collections.Concurrent.ConcurrentDictionary> + val GetStrongReaderCache : unit -> System.Collections.Concurrent.ConcurrentDictionary + \ No newline at end of file diff --git a/tests/service/data/TestTP/TestTP.dll b/tests/service/data/TestTP/TestTP.dll deleted file mode 100644 index 0b3e3fd7a16..00000000000 Binary files a/tests/service/data/TestTP/TestTP.dll and /dev/null differ diff --git a/tests/service/data/TestTP/TestTP.fs b/tests/service/data/TestTP/TestTP.fs new file mode 100644 index 00000000000..c853807ebb2 --- /dev/null +++ b/tests/service/data/TestTP/TestTP.fs @@ -0,0 +1,326 @@ +namespace TestTP + +open ProviderImplementation.ProvidedTypes +open Microsoft.FSharp.Core.CompilerServices +open System.Reflection +open FSharp.Quotations + +module Helper = + let doNothing() = () + let doNothingOneArg(x:int) = () + let doNothingTwoArg(x:int, y: int) = () + let doNothingTwoArgCurried(x:int) (y: int) = () + [] + let doNothingWithCompiledName() = () + let doNothingGeneric(x:'T) = () + let doNothingGenericWithConstraint(x: 'T when 'T: equality) = () + let doNothingGenericWithTypeConstraint(x: 'T when 'T :> _ seq) = () + + let mutable moduleValue = 0 + + type I = + abstract DoNothing: unit -> unit + + type B() = + abstract VirtualDoNothing: unit -> unit + default this.VirtualDoNothing() = () + + type C() = + inherit B() + let mutable p = 0 + static member DoNothing() = () + static member DoNothingOneArg(x:int) = () + static member DoNothingOneArg(x:string) = () + static member DoNothingTwoArg(c:C, x:int) = () + static member DoNothingTwoArgCurried (c:C) (x:int) = () + static member DoNothingGeneric(x:'T) = () + [] + static member DoNothingWithCompiledName() = () + member _.InstanceDoNothing() = () + member _.InstanceDoNothingOneArg(x:int) = () + member _.InstanceDoNothingOneArg(x:string) = () + member _.InstanceDoNothingTwoArg(c:C, x:int) = () + member _.InstanceDoNothingTwoArgCurried(c:C) (x:int) = () + member _.InstanceDoNothingGeneric(x:'T) = () + [] + member _.InstanceDoNothingWithCompiledName() = () + override _.VirtualDoNothing() = () + + member _.Property with get() = p and set v = p <- v + member val AutoProperty = 0 with get, set + static member val StaticAutoProperty = 0 with get, set + + interface I with + member this.DoNothing() = () + + type G<'U>() = + static member DoNothing() = () + static member DoNothingOneArg(x:int) = () + static member DoNothingTwoArg(c:C, x:int) = () + static member DoNothingGeneric(x:'T) = () + member _.InstanceDoNothing() = () + member _.InstanceDoNothingOneArg(x:int) = () + member _.InstanceDoNothingTwoArg(c:C, x:int) = () + member _.InstanceDoNothingGeneric(x:'U) = () + + type R = { A : int; mutable B : int } + +open FSharp.Compiler.Service.Tests + +[] +type BasicProvider (config : TypeProviderConfig) as this = + inherit TypeProviderForNamespaces (config) + + // resolve CSharp_Analysis from referenced assemblies + do System.AppDomain.CurrentDomain.add_AssemblyResolve(fun _ args -> + let name = AssemblyName(args.Name).Name.ToLowerInvariant() + let an = + config.ReferencedAssemblies + |> Seq.tryFind (fun an -> + System.IO.Path.GetFileNameWithoutExtension(an).ToLowerInvariant() = name) + match an with + | Some f -> Assembly.LoadFrom f + | None -> null + ) + + let ns = "ErasedWithConstructor.Provided" + let asm = Assembly.GetExecutingAssembly() + + let createTypes () = + let myType = ProvidedTypeDefinition(asm, ns, "MyType", Some typeof) + + let ctor = ProvidedConstructor([], invokeCode = fun args -> <@@ "My internal state" :> obj @@>) + myType.AddMember(ctor) + + let ctor2 = ProvidedConstructor( + [ProvidedParameter("InnerState", typeof)], + invokeCode = fun args -> <@@ (%%(args.[0]):string) :> obj @@>) + myType.AddMember(ctor2) + + let innerState = ProvidedProperty("InnerState", typeof, + getterCode = fun args -> <@@ (%%(args.[0]) :> obj) :?> string @@>) + myType.AddMember(innerState) + + let someMethod = ProvidedMethod("DoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingOneArg", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingOneArg(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingTwoArg", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingTwoArg(3, 4) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingTwoArgCurried", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingTwoArgCurried 3 4 @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingWithCompiledName", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingWithCompiledName() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingGeneric", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingGeneric(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingGenericWithConstraint", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingGenericWithConstraint(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("DoNothingGenericWithTypeConstraint", [], typeof, + invokeCode = fun args -> <@@ Helper.doNothingGenericWithTypeConstraint([3]) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothingGeneric", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothingGeneric(3) @@>) + + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothingOneArg", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothingOneArg(3) @@>) + + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothingTwoArg", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothingTwoArg(Helper.C(), 3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothingTwoArgCurried", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothingTwoArgCurried (Helper.C()) 3 @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassDoNothingWithCompiledName", [], typeof, + invokeCode = fun args -> <@@ Helper.C.DoNothingWithCompiledName() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothingGeneric", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothingGeneric(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothingOneArg", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothingOneArg(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothingTwoArg", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothingTwoArg(Helper.C(), 3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothingTwoArgCurried", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothingTwoArgCurried (Helper.C()) 3 @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassInstanceDoNothingWithCompiledName", [], typeof, + invokeCode = fun args -> <@@ Helper.C().InstanceDoNothingWithCompiledName() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("InterfaceDoNothing", [], typeof, + invokeCode = fun args -> <@@ (Helper.C() :> Helper.I).DoNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("OverrideDoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.C().VirtualDoNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("GenericClassDoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.G.DoNothing() @@>) + myType.AddMember(someMethod) + + // These do not seem to compile correctly when used in provided expressions: + //Helper.G.DoNothingGeneric(3) + + // These do not seem to compile correctly when used in provided expressions: + //Helper.G().InstanceDoNothingGeneric(3) + + let someMethod = ProvidedMethod("GenericClassDoNothingOneArg", [], typeof, + invokeCode = fun args -> <@@ Helper.G.DoNothingOneArg(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("GenericClassDoNothingTwoArg", [], typeof, + invokeCode = fun args -> <@@ Helper.G.DoNothingTwoArg(Helper.C(), 3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("GenericClassInstanceDoNothing", [], typeof, + invokeCode = fun args -> <@@ Helper.G().InstanceDoNothing() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("GenericClassInstanceDoNothingOneArg", [], typeof, + invokeCode = fun args -> <@@ Helper.G().InstanceDoNothingOneArg(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("GenericClassInstanceDoNothingTwoArg", [], typeof, + invokeCode = fun args -> <@@ Helper.G().InstanceDoNothingTwoArg(Helper.C(), 3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("OptionConstructionAndMatch", [], typeof, + invokeCode = fun args -> <@@ match Some 1 with None -> 0 | Some x -> x @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ChoiceConstructionAndMatch", [], typeof, + invokeCode = fun args -> <@@ match Choice1Of2 1 with Choice2Of2 _ -> 0 | Choice1Of2 _ -> 1 @@>) + // TODO: fix type checker to recognize union generated subclasses coming from TPs +// invokeCode = fun args -> <@@ match Choice1Of2 1 with Choice2Of2 _ -> 0 | Choice1Of2 x -> x @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("RecordConstructionAndFieldGetSet", [], typeof, + invokeCode = fun args -> <@@ let r : Helper.R = { A = 1; B = 0 } in r.B <- 1; r.A @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("TupleConstructionAndGet", [], typeof, + invokeCode = fun args -> <@@ let t = (1, 2, 3) in (let _, i, _ = t in i) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethod", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).Method("x") @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethodOptionalParam", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).Method2("x") + CSharpClass(0).Method2() @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethodParamArray", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).Method3("x", "y") @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethodGeneric", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).GenericMethod(2) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethodGenericWithConstraint", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).GenericMethod2(obj()) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpMethodGenericWithTypeConstraint", [], typeof, + invokeCode = fun args -> <@@ CSharpClass(0).GenericMethod3(3) @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("CSharpExplicitImplementationMethod", [], typeof, + invokeCode = fun args -> <@@ (CSharpClass(0) :> ICSharpExplicitInterface).ExplicitMethod("x") @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ModuleValue", [], typeof, + invokeCode = fun args -> <@@ Helper.moduleValue <- 1; Helper.moduleValue @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassProperty", [], typeof, + invokeCode = fun args -> <@@ let x = Helper.C() in x.Property <- 1; x.Property @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassAutoProperty", [], typeof, + invokeCode = fun args -> <@@ let x = Helper.C() in x.AutoProperty <- 1; x.AutoProperty @@>) + myType.AddMember(someMethod) + + let someMethod = ProvidedMethod("ClassStaticAutoProperty", [], typeof, + invokeCode = fun args -> <@@ Helper.C.StaticAutoProperty <- 1; Helper.C.StaticAutoProperty @@>) + myType.AddMember(someMethod) + + [myType] + + do + this.AddNamespace(ns, createTypes()) + +[] +type BasicGenerativeProvider (config : TypeProviderConfig) as this = + inherit TypeProviderForNamespaces (config) + + let ns = "GeneratedWithConstructor.Provided" + let asm = Assembly.GetExecutingAssembly() + + let createType typeName (count:int) = + let asm = ProvidedAssembly() + let myType = ProvidedTypeDefinition(asm, ns, typeName, Some typeof, isErased=false) + + let ctor = ProvidedConstructor([], invokeCode = fun args -> <@@ "My internal state" :> obj @@>) + myType.AddMember(ctor) + + let ctor2 = ProvidedConstructor([ProvidedParameter("InnerState", typeof)], invokeCode = fun args -> <@@ (%%(args.[1]):string) :> obj @@>) + myType.AddMember(ctor2) + + for i in 1 .. count do + let prop = ProvidedProperty("Property" + string i, typeof, getterCode = fun args -> <@@ i @@>) + myType.AddMember(prop) + + let meth = ProvidedMethod("StaticMethod", [], typeof, isStatic=true, invokeCode = (fun args -> Expr.Value(null, typeof))) + myType.AddMember(meth) + asm.AddTypes [ myType ] + + myType + + let myParamType = + let t = ProvidedTypeDefinition(asm, ns, "GenerativeProvider", Some typeof, isErased=false) + t.DefineStaticParameters( [ProvidedStaticParameter("Count", typeof)], fun typeName args -> createType typeName (unbox args.[0])) + t + do + this.AddNamespace(ns, [myParamType]) + +[] +do () \ No newline at end of file diff --git a/tests/service/data/TestTP/TestTP.fsproj b/tests/service/data/TestTP/TestTP.fsproj index c56ec5f349b..75b18586019 100644 --- a/tests/service/data/TestTP/TestTP.fsproj +++ b/tests/service/data/TestTP/TestTP.fsproj @@ -2,15 +2,15 @@ - net45 + netstandard2.0 true - nunit + $(OtherFlags) --nowarn:3390 --nowarn:3218 - + diff --git a/tests/service/data/ToolsVersion12.fsproj b/tests/service/data/ToolsVersion12.fsproj index e56a9961808..96156711bc4 100644 --- a/tests/service/data/ToolsVersion12.fsproj +++ b/tests/service/data/ToolsVersion12.fsproj @@ -9,7 +9,7 @@ Exe Main Main - v4.5.1 + v4.7.2 Main diff --git a/tests/service/data/TypeProviderConsole/Program.fs b/tests/service/data/TypeProviderConsole/Program.fs deleted file mode 100644 index 450b736fd6d..00000000000 --- a/tests/service/data/TypeProviderConsole/Program.fs +++ /dev/null @@ -1,6 +0,0 @@ -module Program - -[] -let main argv = - printfn "%A" argv - 0 // return an integer exit code diff --git a/tests/service/data/TypeProviderConsole/TypeProviderConsole.fsproj b/tests/service/data/TypeProviderConsole/TypeProviderConsole.fsproj deleted file mode 100644 index 144efa90d7d..00000000000 --- a/tests/service/data/TypeProviderConsole/TypeProviderConsole.fsproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - 39100933-24e2-4c64-9465-4996d3de52b2 - Exe - TypeProviderConsole - TypeProviderConsole - v4.5 - true - TypeProviderConsole - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - AnyCPU - bin\Debug\TypeProviderConsole.xml - true - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - AnyCPU - bin\Release\TypeProviderConsole.xml - true - - - - - ..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - - - - - - - - - TypeProviderLibrary - {1da23607-c5ef-42b7-b9a7-692572ad1b7b} - True - - - - - - - - ..\..\..\..\packages\NUnit\lib\nunit.framework.dll - True - True - - - - - \ No newline at end of file diff --git a/tests/service/data/TypeProviderLibrary/Library1.fs b/tests/service/data/TypeProviderLibrary/Library1.fs deleted file mode 100644 index ae9e9a1d784..00000000000 --- a/tests/service/data/TypeProviderLibrary/Library1.fs +++ /dev/null @@ -1,25 +0,0 @@ -namespace TypeProviderLibrary - -open Microsoft.FSharp.Core.CompilerServices -open System - -[] -type FakeTypeProvider() = - interface ITypeProvider with - member this.GetStaticParameters _ = [||] - member this.ApplyStaticArguments(_,_,_) = raise <| System.InvalidOperationException() - member this.GetNamespaces() = [| |] - member this.GetInvokerExpression(_,_) = failwith "GetInvokerExpression" - [] - member this.Invalidate = (new Event<_,_>()).Publish - member this.GetGeneratedAssemblyContents(assembly) = failwith "GetGeneratedAssemblyContents" - - interface ITypeProvider2 with - member this.GetStaticParametersForMethod _ = [||] - member this.ApplyStaticArgumentsForMethod(_,_,_) = raise <| System.InvalidOperationException() - - interface IDisposable with - member __.Dispose() = () - -[] -do() diff --git a/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.dll b/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.dll deleted file mode 100644 index 7dd893d01f4..00000000000 Binary files a/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.dll and /dev/null differ diff --git a/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.fsproj b/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.fsproj deleted file mode 100644 index f7125ac2d2b..00000000000 --- a/tests/service/data/TypeProviderLibrary/TypeProviderLibrary.fsproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - 1da23607-c5ef-42b7-b9a7-692572ad1b7b - Library - TypeProviderLibrary - TypeProviderLibrary - v4.5 - TypeProviderLibrary - - - true - full - false - false - .\ - DEBUG;TRACE - 3 - bin\Debug\TypeProviderLibrary.xml - - - pdbonly - true - true - .\ - TRACE - 3 - bin\Release\TypeProviderLibrary.xml - - - - - - - - ..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - - - - - \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TestConsole/App.config b/tests/service/data/TypeProvidersBug/TestConsole/App.config deleted file mode 100644 index 8324aa6ff15..00000000000 --- a/tests/service/data/TypeProvidersBug/TestConsole/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TestConsole/AssemblyInfo.fs b/tests/service/data/TypeProvidersBug/TestConsole/AssemblyInfo.fs deleted file mode 100644 index 7f520374db6..00000000000 --- a/tests/service/data/TypeProvidersBug/TestConsole/AssemblyInfo.fs +++ /dev/null @@ -1,41 +0,0 @@ -namespace TestConsole.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[] -[] -[] -[] -[] -[] -[] -[] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [] -[] -[] - -do - () \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TestConsole/Program.fs b/tests/service/data/TypeProvidersBug/TestConsole/Program.fs deleted file mode 100644 index 9b1e9f0ce97..00000000000 --- a/tests/service/data/TypeProvidersBug/TestConsole/Program.fs +++ /dev/null @@ -1,5 +0,0 @@ - -[] -let main _ = - let foo: string = TypeProvidersBug.Test.config.Foo - 0 \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TestConsole/TestConsole.fsproj b/tests/service/data/TypeProvidersBug/TestConsole/TestConsole.fsproj deleted file mode 100644 index 572852c0243..00000000000 --- a/tests/service/data/TypeProvidersBug/TestConsole/TestConsole.fsproj +++ /dev/null @@ -1,64 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - 247653e8-fba7-419b-8b7a-8b17ebfe2969 - Exe - TestConsole - TestConsole - v4.6 - true - TestConsole - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - AnyCPU - bin\Debug\TestConsole.XML - true - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - AnyCPU - bin\Release\TestConsole.XML - true - - - - - - - - - - - - - ..\..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - TypeProvidersBug - {7b36cdd5-14f3-42f0-8118-c279d2315a22} - True - - - ..\..\..\..\..\packages\FSharp.Configuration.1.3.0\lib\net45\FSharp.Configuration.dll - True - - - - \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TypeProvidersBug/AssemblyInfo.fs b/tests/service/data/TypeProvidersBug/TypeProvidersBug/AssemblyInfo.fs deleted file mode 100644 index 5552b38496a..00000000000 --- a/tests/service/data/TypeProvidersBug/TypeProvidersBug/AssemblyInfo.fs +++ /dev/null @@ -1,41 +0,0 @@ -namespace TypeProvidersBug.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[] -[] -[] -[] -[] -[] -[] -[] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [] -[] -[] - -do - () \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TypeProvidersBug/Library1.fs b/tests/service/data/TypeProvidersBug/TypeProvidersBug/Library1.fs deleted file mode 100644 index 531e89d8460..00000000000 --- a/tests/service/data/TypeProvidersBug/TypeProvidersBug/Library1.fs +++ /dev/null @@ -1,7 +0,0 @@ -module TypeProvidersBug.Test - -open FSharp.Configuration - -type Configuration = YamlConfig - -let config = Configuration() diff --git a/tests/service/data/TypeProvidersBug/TypeProvidersBug/TypeProvidersBug.fsproj b/tests/service/data/TypeProvidersBug/TypeProvidersBug/TypeProvidersBug.fsproj deleted file mode 100644 index 1ee42f8d19c..00000000000 --- a/tests/service/data/TypeProvidersBug/TypeProvidersBug/TypeProvidersBug.fsproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - - Debug - AnyCPU - 2.0 - 7b36cdd5-14f3-42f0-8118-c279d2315a22 - Library - TypeProvidersBug - TypeProvidersBug - v4.6 - true - TypeProvidersBug - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - bin\Debug\TypeProvidersBug.XML - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - bin\Release\TypeProvidersBug.XML - - - - - - - - - - - - ..\..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - ..\..\..\..\..\packages\FSharp.Configuration.1.3.0\lib\net45\FSharp.Configuration.dll - True - - - - \ No newline at end of file diff --git a/tests/service/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll b/tests/service/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll deleted file mode 100644 index 1ef8b4ae875..00000000000 Binary files a/tests/service/data/TypeProvidersBug/TypeProvidersBug/bin/Debug/TypeProvidersBug.dll and /dev/null differ diff --git a/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx b/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx index 6a99c01e5e7..4f2a37f6f2f 100644 --- a/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx +++ b/tests/walkthroughs/DebugStepping/TheBigFileOfDebugStepping.fsx @@ -1,6 +1,5 @@ // Instructions: -// Debug\net40\bin\fsc.exe --debug+ --tailcalls- --optimize- tests\walkthroughs\DebugStepping\TheBigFileOfDebugStepping.fsx -// Release\net40\bin\fsc.exe --debug+ --tailcalls- --optimize- tests\walkthroughs\DebugStepping\TheBigFileOfDebugStepping.fsx +// artifacts\bin\fsc\Debug\net472\fsc.exe --debug+ --tailcalls- --optimize- --langversion:preview tests\walkthroughs\DebugStepping\TheBigFileOfDebugStepping.fsx // devenv /debugexe TheBigFileOfDebugStepping.exe // // Repeat the above with @@ -11,10 +10,16 @@ // - Different visual debuggers open System +open System.Threading.Tasks type U2 = U2 of int * int +let (!) (r: 'T ref) = r.Value +let (:=) (r: 'T ref) (v: 'T) = r.Value <- v +let incr (r: int ref) = r.Value <- r.Value + 1 +let decr (r: int ref) = r.Value <- r.Value - 1 + let InnerRecursiveFunction (str: string) = let rec even n = if n = 0 then str else odd (n-1) and odd n = even (n-1) @@ -34,15 +39,15 @@ let rec TailcallRecursionTest2 (U2(a,b)) = TailcallRecursionTest2 (U2(a-1,b-1)) // check the 'a' and 'b' update correctly let AsyncExpressionSteppingTest1 () = - async { printfn "hello" - printfn "stuck in the middle" - printfn "goodbye"} + async { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + Console.WriteLine "goodbye"} let AsyncExpressionSteppingTest2 () = let x = ref 0 async { while !x < 4 do incr x - printfn "hello" } + Console.WriteLine "hello" } let AsyncExpressionSteppingTest3 () = @@ -62,17 +67,17 @@ let AsyncExpressionSteppingTest4 () = return z finally incr x - printfn "done" } + Console.WriteLine "done" } let es = [3;4;5] let AsyncExpressionSteppingTest5 () = async { for x in es do - printfn "hello" - printfn "hello 2" + Console.WriteLine "hello" + Console.WriteLine "hello 2" for x in es do - printfn "goodbye" - printfn "goodbye 2" } + Console.WriteLine "goodbye" + Console.WriteLine "goodbye 2" } let f2 () = @@ -123,9 +128,9 @@ let ListExpressionSteppingTest1 () = [ yield 1 ] let ListExpressionSteppingTest2 () = - [ printfn "hello" + [ Console.WriteLine "hello" yield 1 - printfn "goodbye" + Console.WriteLine "goodbye" yield 2] @@ -133,7 +138,7 @@ let ListExpressionSteppingTest3 () = let x = ref 0 [ while !x < 4 do incr x - printfn "hello" + Console.WriteLine "hello" yield x ] @@ -157,25 +162,43 @@ let ListExpressionSteppingTest5 () = yield z finally incr x - printfn "done" ] + Console.WriteLine "done" ] let ListExpressionSteppingTest6 () = [ for x in es do - printfn "hello" + Console.WriteLine "hello" yield x for x in es do - printfn "goodbye" + Console.WriteLine "goodbye" yield x ] +let ListExpressionSteppingTest7 () = + [ for x in 1..4 do + printfn "hello" + yield x ] + +let ListExpressionSteppingTest8 () = + [ for x in 1..4 do + match x with + | 1 -> + printfn "hello" + yield x + | 2 -> + printfn "hello" + yield x + | _ -> + yield x + ] + let SeqExpressionSteppingTest1 () = seq { yield 1 } let SeqExpressionSteppingTest2 () = - seq { printfn "hello" + seq { Console.WriteLine "hello" yield 1 - printfn "goodbye" + Console.WriteLine "goodbye" yield 2 } @@ -184,7 +207,7 @@ let SeqExpressionSteppingTest3 () = let x = ref 0 seq { while !x < 4 do incr x - printfn "hello" + Console.WriteLine "hello" yield x } @@ -209,15 +232,15 @@ let SeqExpressionSteppingTest5 () = yield z finally incr x - printfn "done" } + Console.WriteLine "done" } let SeqExpressionSteppingTest6 () = seq { for x in es do - printfn "hello" + Console.WriteLine "hello" yield x for x in es do - printfn "goodbye" + Console.WriteLine "goodbye" yield x } @@ -344,8 +367,8 @@ let OuterWithNonGenericInnerWithCapture x list = let TestFunction1() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 @@ -400,17 +423,17 @@ type C(x:int,y:int) = let TestFunction19(inp) = let c1 = C(inp,inp) let c2 = C(inp,inp) - printfn "c1 = %A, c2 = %A" c1 c2 + Console.WriteLine $"c1 = {c1}, c2 = {c2}" let TestFunction1_0() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction2() = let x = TestFunction1_0() - printfn "Hello"; - printfn "World" + Console.WriteLine "Hello"; + Console.WriteLine "World" type D(x:int,y:int) = @@ -423,27 +446,27 @@ type D(x:int,y:int) = let TestFunction20(inp) = let d1 = D(inp,inp) let d2 = D(inp,inp) - printfn "d1 = %A, d2 = %A" d1 d2 + Console.WriteLine $"done d1 = {d1}, d2 = {d2}" let TestFunction21(U2(a,b)) = - printfn "a = %A, a = %A" a b + Console.WriteLine $"a = {a}, b = {b}" let TestFunction1_1() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction3() = try let x = TestFunction1_1() - printfn "Hello"; + Console.WriteLine "Hello"; with _ -> - printfn "World" + Console.WriteLine "World" let TestFunction1_2() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction3b() = @@ -451,11 +474,11 @@ let TestFunction3b() = let x = TestFunction1_2() failwith "hello" with Failure _ -> - printfn "World" + Console.WriteLine "World" let TestFunction1_3() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction3c() = @@ -463,43 +486,43 @@ let TestFunction3c() = let x = TestFunction1_3() failwith "hello" with Failure msg when msg = "hello" -> - printfn "World" + Console.WriteLine "World" let TestFunction1_4() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction4() = try let x = TestFunction1_4() - printfn "Hello"; + Console.WriteLine "Hello"; finally - printfn "World" + Console.WriteLine "World" let TestFunction1_5() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction5() = let x = let y = TestFunction1_5() - printfn "Hello"; + Console.WriteLine "Hello"; y + y x + x let TestFunction1_6() = - printfn "Hello"; - printfn "World"; + Console.WriteLine "Hello"; + Console.WriteLine "World"; 3+4 let TestFunction6() = let f() = let y = TestFunction1_6() - printfn "Hello"; + Console.WriteLine "Hello"; y + y f() + f() @@ -608,6 +631,174 @@ let LocalValueShadowsArgument2 x = null // breakpoint 2 () +let TaskExpressionSteppingTest0 () = + task { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + Console.WriteLine "goodbye"} + +let TaskExpressionSteppingTest1 () = + task { Console.WriteLine "hello" + Console.WriteLine "stuck in the middle" + do! Task.Delay 100 + Console.WriteLine "goodbye"} + +let TaskExpressionSteppingTest2 () = + let x = ref 0 + task { while !x < 4 do + incr x + Console.WriteLine "hello" } + +let TaskExpressionSteppingTest3 () = + task { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let TaskExpressionSteppingTest4 () = + task { let x = ref 0 + try + let y = ref 0 + incr y + let z = !x + !y + return z + finally + incr x + Console.WriteLine "done" } + +let TaskExpressionSteppingTest5 () = + task { for x in es do + Console.WriteLine "hello" + Console.WriteLine "hello 2" + for x in es do + Console.WriteLine "goodbye" + Console.WriteLine "goodbye 2" } + +let tf2 () = + task { let x = ref 0 + incr x + let y = ref 0 + incr y + let z = !x + !y + return z } + +let TaskExpressionSteppingTest6b () = + task { let! x1 = tf2() + let! x2 = tf2() + let! x3 = tf2() + let y = ref 0 + incr y + let! x4 = tf2() + let z = x1 + !y + x4 + return z } + +let TaskExpressionSteppingTest7a () = + task { let x = ref 0 + try + let y = ref 0 + incr y + let z = !x + !y + return z + with exn -> + incr x + Console.WriteLine "done" + return 0 } + +let TaskExpressionSteppingTest7b () = + task { let x = ref 0 + try + let y = ref 0 + incr y + failwith "fail" + let z = !x + !y + return z + with exn -> + incr x + Console.WriteLine "done" + return 0 } + +let TaskBreakpoints1 () = + task { let! res1 = + tf2() + let! res2 = + match 1 with + | 1 -> tf2() + | _ -> tf2() + let! res3 = + match 1 with + | 1 -> + let x = + match 4 with + | 2 -> tf2() + | _ -> tf2() + tf2() + | _ -> + let x = + match 4 with + | 2 -> tf2() + | _ -> tf2() + tf2() + return () } + +module InlinedCode = + // NOTE: you can't place breakpoints in this method and hit them in either Debug and Release code + let inline bodyRunner z body = + let x = 1 + z + printfn "running" + body x + body x + + let test() = + let bodyWrapper = + let x = 1 + System.Random().Next() + bodyRunner 3 (fun n -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line1, x = %d" x + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line2, n = %d" n) + + let bodyWrapper2 = + // TEST: check you can place breakpoint here and hit it in both Debug and Release code + let x = 1 + System.Random().Next() + bodyRunner 3 <| (fun n -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line1, x = %d" x + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + printfn "line2, n = %d" n) + () + +module Pipelined = + let testListPipeline() = + let data = [ 1 .. 5 ] + + // MANUAL TEST: check stepping through this looks ok + let newData = + data + |> List.filter (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x > 3) + |> List.map (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x * x) + + printfn "%A" newData + + let testArrayPipeline() = + let data = [| 1 .. 5 |] + + let newData = + data + |> Array.filter (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug and Release code + x > 3) + |> Array.map (fun x -> + // MANUAL TEST: check you can place breakpoint here and hit it in both Debug code + // TODO: surprisingly no breakpoint hit here in release code + x * x) + + printfn "%A" newData + TailcallRecursionTest1 3 TailcallRecursionTest2 (U2(3,4)) SteppingMatch01 (Choice1Of2 3) @@ -674,6 +865,8 @@ ListExpressionSteppingTest3() ListExpressionSteppingTest4() ListExpressionSteppingTest5() ListExpressionSteppingTest6() +ListExpressionSteppingTest7() +ListExpressionSteppingTest8() SeqExpressionSteppingTest1()|> Seq.length SeqExpressionSteppingTest2()|> Seq.length SeqExpressionSteppingTest3()|> Seq.length @@ -685,3 +878,165 @@ InnerFunctionDefinitionHadTwoBreakpoints "aaaa" |> ignore InnerRecursiveFunctionDefinitionHadTwoBreakpoints "aaaa" |> ignore LocalValueShadowsArgument1 "123" LocalValueShadowsArgument2 "123" + +module Task = + let RunSynchronously (t: System.Threading.Tasks.Task<_>) = t.Wait(); t.Result + +TaskExpressionSteppingTest0() |> Task.RunSynchronously +TaskExpressionSteppingTest1() |> Task.RunSynchronously +TaskExpressionSteppingTest2() |> Task.RunSynchronously +TaskExpressionSteppingTest3() |> Task.RunSynchronously +TaskExpressionSteppingTest4() |> Task.RunSynchronously +TaskExpressionSteppingTest5() |> Task.RunSynchronously +TaskExpressionSteppingTest6b() |> Task.RunSynchronously +TaskExpressionSteppingTest7a() |> Task.RunSynchronously +TaskExpressionSteppingTest7b() |> Task.RunSynchronously +TaskBreakpoints1() |> Task.RunSynchronously +InlinedCode.test() +Pipelined.testListPipeline() +Pipelined.testArrayPipeline() + +module BooleanLogic = + + let testFunctionWithAnd x y = + x && y + + let testFunctionWithOr x y = + x || y + + let testFunctionWithMultipleAnd x y z = + x && y && z + + let testFunctionWithMultipleOr x y z = + x || y || z + + let testFunctionWithIfOfAnd x y = + if x && y then + 1 + else + 2 + + let testFunctionWithIfOfOr x y = + if x || y then + 1 + else + 2 + + testFunctionWithAnd true false + testFunctionWithMultipleAnd true true false + testFunctionWithMultipleOr false false true + testFunctionWithOr true false + testFunctionWithIfOfAnd true false + testFunctionWithIfOfOr false false + +// See https://github.com/dotnet/fsharp/issues/11977 +module FalseSteppingBug = + type U = + | A1 of int + | A2 of int + | A3 of int + | A4 of int + + let testFunc f u = + match u with + | A1 n -> f n + | A2 n when n > 4 -> f n // this was falsely hit + | A2 n -> f n + | A3 n -> f n + | A4 n -> f n + + testFunc id (A3 4) + + + +// https://github.com/dotnet/fsharp/pull/11981 +module MissingFirstTry = + let TestFunction3() = + try + let x = 1+1 + System.Console.WriteLine "Hello"; + with _ -> + System.Console.WriteLine "World" + + TestFunction3() + + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhen1 = + + let TestMatchWithWhen x y = + match x with + | [_] when y > 4 -> 5 + | [_] when y < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [1] 4 + TestMatchWithWhen [1] 5 + TestMatchWithWhen [1] 6 + + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhenWithVariableBinding = + + let TestMatchWithWhen x = + match x with + | [x] when x > 4 -> 5 + | [x] when x < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [4] + TestMatchWithWhen [5] + TestMatchWithWhen [6] + +// https://github.com/dotnet/fsharp/issues/11979 +// +// Check debug points exist for 'when' +module DebuggingSteppingForMatchWithWhenWithUnionClauses= + + let TestMatchWithWhen x = + match x with + | [_;x] + | [x] when x < 4 -> -5 + | _ -> 2 + + + TestMatchWithWhen [4;5] + TestMatchWithWhen [5;4] + TestMatchWithWhen [6] + +module NestedScopesWithShadowing = + + let f2 (a, b) = + let v1 = 1 + if a then + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + else + let v2 = 1.4 + if b then + let v1 = "3" + let v2 = 5 + v1 + else + let v1 = "3" + let v2 = 5 + v1 + + + f2 (true, true) + f2 (true, false) + f2 (false, true) + f2 (false, false) diff --git a/tests/walkthroughs/sdk-script-manual-tests/README.md.txt b/tests/walkthroughs/sdk-script-manual-tests/README.md.txt new file mode 100644 index 00000000000..643fece6fe5 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/README.md.txt @@ -0,0 +1,85 @@ +### NOTE +Before running tests, `.global.json` files should be renamed to `global.json`, this is needed to not confuse UseDotNet task of Azure Pipelies when installing SDK. + + +#### no warnings + +``` +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netcore-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netfx-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\neutral-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netcore-script-reference-netcore-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netcore-script-reference-neutral-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netfx-script-reference-netfx-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netfx-script-reference-neutral-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\neutral-script-reference-netcore-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\neutral-script-reference-netfx-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\neutral-script-reference-neutral-script.fsx +``` +#### warnings + +``` +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netcore-script-reference-netfx-script.fsx +artifacts\bin\fsc\Debug\net472\fsc.exe c:\misc\tests\netfx-script-reference-netcore-script.fsx +``` + + +``` +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netcore-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netfx-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\neutral-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netcore-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netcore-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netcore-script-reference-neutral-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netfx-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netfx-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\netfx-script-reference-neutral-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\neutral-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\neutral-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsc\Debug\netcoreapp3.1\fsc.exe c:\misc\tests\neutral-script-reference-neutral-script.fsx +``` + +#### no warnings + +``` +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netfx-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\neutral-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netfx-script-reference-netfx-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netfx-script-reference-neutral-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\neutral-script-reference-netfx-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\neutral-script-reference-neutral-script.fsx +``` + +#### warnings + +``` +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netcore-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netcore-script-reference-netcore-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netcore-script-reference-netfx-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netcore-script-reference-neutral-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\netfx-script-reference-netcore-script.fsx +artifacts\bin\fsi\Debug\net472\fsi.exe c:\misc\tests\neutral-script-reference-netcore-script.fsx +``` + +#### no warnings + +``` +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netcore-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\neutral-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netcore-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netcore-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netcore-script-reference-neutral-script.fsx +``` + +#### warnings + +``` +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netfx-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netfx-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netfx-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\netfx-script-reference-neutral-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\neutral-script-reference-netcore-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\neutral-script-reference-netfx-script.fsx +dotnet artifacts\bin\fsi\Debug\netcoreapp3.1\fsi.exe c:\misc\tests\neutral-script-reference-neutral-script.fsx + +``` \ No newline at end of file diff --git a/tests/walkthroughs/sdk-script-manual-tests/netcore-script-reference-netcore-script.fsx b/tests/walkthroughs/sdk-script-manual-tests/netcore-script-reference-netcore-script.fsx new file mode 100644 index 00000000000..c2dea42e0a1 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/netcore-script-reference-netcore-script.fsx @@ -0,0 +1,9 @@ + +#r "System.dll" +//#r "nuget: FSharp.Data" +//#r "nuget: Quack" +printfn "hello from %s" __SOURCE_FILE__ +#r "netstandard.dll" + +#load "netcore-script.fsx" + diff --git a/tests/walkthroughs/sdk-script-manual-tests/netcore-script.fsx b/tests/walkthroughs/sdk-script-manual-tests/netcore-script.fsx new file mode 100644 index 00000000000..025547c8450 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/netcore-script.fsx @@ -0,0 +1,26 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + +1+1 + + +//#r "nuget: DiffSharp.Core,1.0.0-preview-263264614" + +//#r "nuget: Quack" + + + + +//#r "System.EnterpriseServices.dll" +//// A netfx api +//let f2 (x: System.EnterpriseServices.Activity) = () + diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/.global.json b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/.global.json new file mode 100644 index 00000000000..c120c8115ea --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/.global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "3.1.301" + } +} \ No newline at end of file diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/netcore-script-sdk-3.1.0.fsx b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/netcore-script-sdk-3.1.0.fsx new file mode 100644 index 00000000000..14bc4a2334f --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-3.1.0/netcore-script-sdk-3.1.0.fsx @@ -0,0 +1,26 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + + +1+1 + +#r "nuget: DiffSharp.Core,1.0.0-preview-263264614" + +//#r "nuget: Quack" + + + + +//#r "System.EnterpriseServices.dll" +//// A netfx api +//let f2 (x: System.EnterpriseServices.Activity) = () + diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/.global.json b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/.global.json new file mode 100644 index 00000000000..fbb332028b9 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/.global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "5.0.101" + } +} \ No newline at end of file diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/netcore-script-sdk-5.0.101.fsx b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/netcore-script-sdk-5.0.101.fsx new file mode 100644 index 00000000000..53ee539c4a8 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-5.0.101/netcore-script-sdk-5.0.101.fsx @@ -0,0 +1,26 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + + +1+1 + +//#r "nuget: DiffSharp.Core,1.0.0-preview-263264614" + +//#r "nuget: Quack" + + + + +//#r "System.EnterpriseServices.dll" +//// A netfx api +//let f2 (x: System.EnterpriseServices.Activity) = () + diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/.global.json b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/.global.json new file mode 100644 index 00000000000..7337e805efb --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/.global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "666.666.666" + } +} \ No newline at end of file diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666 - Copy.fsx b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666 - Copy.fsx new file mode 100644 index 00000000000..53f3881d296 --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666 - Copy.fsx @@ -0,0 +1,13 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + +1+1 diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666.fsx b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666.fsx new file mode 100644 index 00000000000..7756ebcebbf --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.666/netcore-script-sdk-666.666.666.fsx @@ -0,0 +1,14 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + + +1+1 diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/.global.json b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/.global.json new file mode 100644 index 00000000000..7337e805efb --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/.global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "666.666.666" + } +} \ No newline at end of file diff --git a/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/netcore-script-sdk-666.666.666.fsx b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/netcore-script-sdk-666.666.666.fsx new file mode 100644 index 00000000000..7756ebcebbf --- /dev/null +++ b/tests/walkthroughs/sdk-script-manual-tests/with-sdk-666.666.667/netcore-script-sdk-666.666.666.fsx @@ -0,0 +1,14 @@ + +#r "System.dll" + +printfn "hello from %s" __SOURCE_FILE__ + +System.Environment.CurrentDirectory + +#r "netstandard.dll" + +// A .netcoreapp3.1 api +let f x = System.Runtime.InteropServices.NativeLibrary.Free(x) + + +1+1 diff --git a/vsintegration/Directory.Build.targets b/vsintegration/Directory.Build.targets index bc5c6d7195c..170ace14822 100644 --- a/vsintegration/Directory.Build.targets +++ b/vsintegration/Directory.Build.targets @@ -2,10 +2,6 @@ - - true - - @@ -17,7 +13,9 @@ - + + + diff --git a/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj b/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj index 82e55b95ec9..3b5fb34147b 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj +++ b/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj @@ -9,7 +9,6 @@ - Template\AssemblyInfo.fs; Template\Program.fs; diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/App.config b/vsintegration/ProjectTemplates/ConsoleProject/Template/App.config deleted file mode 100644 index 7301b903799..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - $if$ ($targetframeworkversion$ >= 4.0)$endif$$if$ ($targetframeworkversion$ < 4.0)$endif$ - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/AssemblyInfo.fs b/vsintegration/ProjectTemplates/ConsoleProject/Template/AssemblyInfo.fs deleted file mode 100644 index ae735840e65..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/AssemblyInfo.fs +++ /dev/null @@ -1,41 +0,0 @@ -namespace $safeprojectname$.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// @@@GeneralInfo-Line1|General Information about an assembly is controlled through the following@@@ -// @@@GeneralInfo-Line2|set of attributes. Change these attribute values to modify the information@@@ -// @@@GeneralInfo-Line3|associated with an assembly.@@@ -[] -[] -[] -[] -[] -[] -[] -[] - -// @@@ComVisible-Line1|Setting ComVisible to false makes the types in this assembly not visible@@@ -// @@@ComVisible-Line2|to COM components. If you need to access a type in this assembly from@@@ -// @@@ComVisible-Line3|COM, set the ComVisible attribute to true on that type.@@@ -[] - -// @@@Guid-Line1|The following GUID is for the ID of the typelib if this project is exposed to COM@@@ -[] - -// @@@VersionInfo-Line1|Version information for an assembly consists of the following four values:@@@ -// -// @@@MajorVersion|Major Version@@@ -// @@@MinorVersion|Minor Version@@@ -// @@@BuildNumber|Build Number@@@ -// @@@Revision|Revision@@@ -// -// @@@VersionInfo-Line2|You can specify all the values or you can default the Build and Revision Numbers@@@ -// @@@VersionInfo-Line3|by using the '*' as shown below:@@@ -// [] -[] -[] - -do - () \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj index 19c297de5e2..ee7baed3960 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj @@ -1,65 +1,12 @@ - - - + - Debug - AnyCPU - 2.0 - $guid1$ Exe - $safeprojectname$ - $safeprojectname$ - v$targetframeworkversion$ - true - true - 3239;$(WarningsAsErrors) +$if$ ($targetframeworkversion$ == 4.5) net45$endif$$if$ ($targetframeworkversion$ == 4.6) net46 $endif$$if$ ($targetframeworkversion$ == 4.6.1) net461 $endif$$if$ ($targetframeworkversion$ == 4.6.2) net462 $endif$$if$ ($targetframeworkversion$ == 4.7) net47 $endif$$if$ ($targetframeworkversion$ == 4.7.1) net471 $endif$$if$ ($targetframeworkversion$ == 4.7.2) net472 $endif$$if$ ($targetframeworkversion$ == 4.8) net48 $endif$ +$if$ ($safeprojectname$ != $projectname$) $safeprojectname$ $endif$ + 3390;$(WarnOn) - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - - - - - + - - - - 11 - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate index fea0279b943..37efa24da1f 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate @@ -15,19 +15,11 @@ - AssemblyInfo.fs Program.fs - App.config NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a NuGet.VisualStudio.TemplateWizard - - - - - - diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/Program.fs b/vsintegration/ProjectTemplates/ConsoleProject/Template/Program.fs index 93b72755103..6e5ebade443 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/Program.fs +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/Program.fs @@ -1,7 +1,12 @@ -// @@@LearnMore|Learn more about F# at https://fsharp.org@@@ +// @@@LearnMore|Learn more about F# at http://docs.microsoft.com/dotnet/fsharp@@@ // @@@SeeTutorial|See the 'F# Tutorial' project for more help.@@@ +// Define a function to construct a message to print +let from whom = + sprintf "from %s" whom + [] let main argv = - printfn "%A" argv + let message = from "F#" // Call the function + printfn "Hello world %s" message 0 // @@@Return|return an integer exit code@@@ diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.cs.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.cs.xlf deleted file mode 100644 index a580d9e396b..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.cs.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Obecné informace o sestavení se řídí přes následující - - - - set of attributes. Change these attribute values to modify the information - sadu atributů. Změnou hodnot těchto atributů se upraví informace - - - - associated with an assembly. - přidružené k sestavení. - - - - Setting ComVisible to false makes the types in this assembly not visible - Nastavením atributu ComVisible na hodnotu False budou typy v tomto sestavení neviditelné - - - - to COM components. If you need to access a type in this assembly from - pro komponenty modelu COM. Pokud potřebujete přistoupit k typu v tomto sestavení z - - - - COM, set the ComVisible attribute to true on that type. - modelu COM, nastavte atribut ComVisible daného typu na hodnotu True. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Následující GUID se používá pro ID knihovny typů, pokud je tento projekt vystavený pro COM. - - - - Version information for an assembly consists of the following four values: - Informace o verzi sestavení se skládá z těchto čtyř hodnot: - - - - Major Version - Hlavní verze - - - - Minor Version - Podverze - - - - Build Number - Číslo sestavení - - - - Revision - Revize - - - - You can specify all the values or you can default the Build and Revision Numbers - Můžete zadat všechny hodnoty nebo nechat nastavená výchozí čísla sestavení a revize - - - - by using the '*' as shown below: - pomocí zástupného znaku * takto: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.de.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.de.xlf deleted file mode 100644 index 8df6ae7fc3b..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.de.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Allgemeine Informationen über eine Assembly werden über die folgende - - - - set of attributes. Change these attribute values to modify the information - Attributgruppe gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, - - - - associated with an assembly. - die einer Assembly zugeordnet sind. - - - - Setting ComVisible to false makes the types in this assembly not visible - Durch Festlegen von ComVisible auf FALSE sind die Typen in dieser Assembly nicht - - - - to COM components. If you need to access a type in this assembly from - für COM-Komponenten sichtbar. Wenn Sie auf einen Typ in dieser Assembly von - - - - COM, set the ComVisible attribute to true on that type. - COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf TRUE festlegen. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird - - - - Version information for an assembly consists of the following four values: - Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: - - - - Major Version - Hauptversion - - - - Minor Version - Nebenversion - - - - Build Number - Buildnummer - - - - Revision - Revision - - - - You can specify all the values or you can default the Build and Revision Numbers - Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern - - - - by using the '*' as shown below: - übernehmen, indem Sie "*" eingeben: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.es.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.es.xlf deleted file mode 100644 index 9beb403796f..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.es.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - La información general de un ensamblado se controla mediante el siguiente - - - - set of attributes. Change these attribute values to modify the information - conjunto de atributos. Cambie estos valores de atributo para modificar la información - - - - associated with an assembly. - asociada con un ensamblado. - - - - Setting ComVisible to false makes the types in this assembly not visible - Si establece ComVisible en false, los tipos de este ensamblado no estarán visibles - - - - to COM components. If you need to access a type in this assembly from - para los componentes COM. Si necesita obtener acceso a un tipo de este ensamblado desde - - - - COM, set the ComVisible attribute to true on that type. - COM, establezca el atributo ComVisible en true en este tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - El siguiente GUID sirve como id. de typelib si este proyecto se expone a COM. - - - - Version information for an assembly consists of the following four values: - La información de versión de un ensamblado consta de los cuatro valores siguientes: - - - - Major Version - Versión principal - - - - Minor Version - Versión secundaria - - - - Build Number - Número de compilación - - - - Revision - Revisión - - - - You can specify all the values or you can default the Build and Revision Numbers - Puede especificar todos los valores o usar los valores predeterminados de número de compilación y de revisión - - - - by using the '*' as shown below: - mediante el carácter '*', como se muestra a continuación: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.fr.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.fr.xlf deleted file mode 100644 index a259bd30511..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.fr.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Les informations générales relatives à un assembly dépendent de - - - - set of attributes. Change these attribute values to modify the information - l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations - - - - associated with an assembly. - associées à un assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly - - - - to COM components. If you need to access a type in this assembly from - aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de - - - - COM, set the ComVisible attribute to true on that type. - COM, affectez la valeur true à l'attribut ComVisible sur ce type. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM - - - - Version information for an assembly consists of the following four values: - Les informations de version pour un assembly se composent des quatre valeurs suivantes : - - - - Major Version - Version principale - - - - Minor Version - Version secondaire - - - - Build Number - Numéro de build - - - - Revision - Révision - - - - You can specify all the values or you can default the Build and Revision Numbers - Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut - - - - by using the '*' as shown below: - en utilisant '*', comme indiqué ci-dessous : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.it.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.it.xlf deleted file mode 100644 index d5fc6c75583..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.it.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Le informazioni generali relative a un assembly sono controllate dal seguente - - - - set of attributes. Change these attribute values to modify the information - set di attributi. Modificare i valori di questi attributi per modificare le informazioni - - - - associated with an assembly. - associate a un assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili - - - - to COM components. If you need to access a type in this assembly from - ai componenti COM. Se è necessario accedere a un tipo in questo assembly da - - - - COM, set the ComVisible attribute to true on that type. - COM, impostare su true l'attributo ComVisible per tale tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Se il progetto viene esposto a COM, il seguente GUID verrà utilizzato come ID della libreria dei tipi - - - - Version information for an assembly consists of the following four values: - Le informazioni sulla versione di un assembly sono costituite dai quattro valori seguenti: - - - - Major Version - Versione principale - - - - Minor Version - Versione secondaria - - - - Build Number - Numero di build - - - - Revision - Revisione - - - - You can specify all the values or you can default the Build and Revision Numbers - È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build - - - - by using the '*' as shown below: - utilizzando l'asterisco (*) come illustrato di seguito: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ja.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ja.xlf deleted file mode 100644 index 1f413753d11..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ja.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - アセンブリに関する一般情報は、以下の属性セットによって - - - - set of attributes. Change these attribute values to modify the information - 制御されます。アセンブリに関連付けられている情報を変更するには、 - - - - associated with an assembly. - これらの属性値を変更します。 - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible を false に設定すると、COM コンポーネントがこのアセンブリ内のその型を認識 - - - - to COM components. If you need to access a type in this assembly from - できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 - - - - COM, set the ComVisible attribute to true on that type. - その型の ComVisible 属性を true に設定します。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - このプロジェクトが COM に公開される場合、次の GUID がタイプ ライブラリの ID になります - - - - Version information for an assembly consists of the following four values: - アセンブリのバージョン情報は、以下の 4 つの値で構成されます。: - - - - Major Version - メジャー バージョン - - - - Minor Version - マイナー バージョン - - - - Build Number - ビルド番号 - - - - Revision - リビジョン - - - - You can specify all the values or you can default the Build and Revision Numbers - すべての値を指定するか、下に示すように '*' を使用してビルドおよびリビジョン番号を - - - - by using the '*' as shown below: - 既定値にすることができます。: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ko.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ko.xlf deleted file mode 100644 index 258b4ebab29..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ko.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 어셈블리의 일반 정보는 다음 특성 집합을 통해 - - - - set of attributes. Change these attribute values to modify the information - 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 - - - - associated with an assembly. - 이러한 특성 값을 변경하세요. - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 - - - - to COM components. If you need to access a type in this assembly from - 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 - - - - COM, set the ComVisible attribute to true on that type. - 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. - - - - Version information for an assembly consists of the following four values: - 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.: - - - - Major Version - 주 버전 - - - - Minor Version - 부 버전 - - - - Build Number - 빌드 번호 - - - - Revision - 수정 버전 - - - - You can specify all the values or you can default the Build and Revision Numbers - 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 버전이 자동으로 - - - - by using the '*' as shown below: - 지정되도록 할 수 있습니다.: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pl.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pl.xlf deleted file mode 100644 index ee3471fb557..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pl.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Ogólne informacje o zestawie są kontrolowane poprzez następujący - - - - set of attributes. Change these attribute values to modify the information - zbiór atrybutów. Zmień wartości tych atrybutów by zmodyfikować informacje - - - - associated with an assembly. - powiązane z zestawem. - - - - Setting ComVisible to false makes the types in this assembly not visible - Ustawienie wartości ComVisible na false sprawia, że typy w tym zestawie nie będą widoczne - - - - to COM components. If you need to access a type in this assembly from - dla składników COM. Jeśli potrzebny jest dostęp do typu w tym zestawie z - - - - COM, set the ComVisible attribute to true on that type. - COM, ustaw atrybut ComVisible na true dla danego typu. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Następujący GUID jest dla ID typelib jeśli ten projekt jest dostępny dla COM - - - - Version information for an assembly consists of the following four values: - Informacje o wersji zestawu zawierają następujące cztery wartości: - - - - Major Version - Wersja główna - - - - Minor Version - Wersja pomocnicza - - - - Build Number - Numer kompilacji - - - - Revision - Poprawka - - - - You can specify all the values or you can default the Build and Revision Numbers - Można określać wszystkie wartości lub używać domyślnych numerów kompilacji i poprawki - - - - by using the '*' as shown below: - przy użyciu symbolu „*”, tak jak pokazano poniżej: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf deleted file mode 100644 index 48d258faa25..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - As informações gerais sobre um assembly são controladas por meio do seguinte - - - - set of attributes. Change these attribute values to modify the information - conjunto de atributos. Altere estes valores de atributo para modificar as informações - - - - associated with an assembly. - associados a um assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - Definir ComVisible como false oculta os tipos neste assembly - - - - to COM components. If you need to access a type in this assembly from - para componentes COM. Caso precise acessar um tipo neste assembly a partir de - - - - COM, set the ComVisible attribute to true on that type. - COM, defina o atributo ComVisible como true nesse tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - O GUID a seguir é para a ID de typelib quando este projeto é exposto a COM - - - - Version information for an assembly consists of the following four values: - As informações da versão de um assembly consistem nos quatro valores a seguir: - - - - Major Version - Versão Principal - - - - Minor Version - Versão Secundária - - - - Build Number - Número da Versão - - - - Revision - Revisão - - - - You can specify all the values or you can default the Build and Revision Numbers - É possível especificar todos os valores ou usar como padrão os Números da Versão e da Revisão - - - - by using the '*' as shown below: - utilizando o '*' como mostrado abaixo: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ru.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ru.xlf deleted file mode 100644 index c0f2735eae2..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.ru.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Общие сведения о сборке можно задать с помощью следующего - - - - set of attributes. Change these attribute values to modify the information - набора атрибутов. Отредактируйте эти значения атрибутов, чтобы изменить сведения, - - - - associated with an assembly. - связанные с этой сборкой. - - - - Setting ComVisible to false makes the types in this assembly not visible - При установке значения False в атрибуте ComVisible типы в этой сборке становятся невидимыми - - - - to COM components. If you need to access a type in this assembly from - для COM-компонентов. Если требуется обратиться к типу в этой сборке через - - - - COM, set the ComVisible attribute to true on that type. - COM, задайте для атрибута ComVisible значение True для этого типа. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Следующий GUID служит для идентификации библиотеки типов, если этот проект видим для COM - - - - Version information for an assembly consists of the following four values: - Сведения о версии сборки состоят из следующих четырех значений: - - - - Major Version - Основной номер версии - - - - Minor Version - Вспомогательная версия - - - - Build Number - Номер сборки - - - - Revision - Редакция - - - - You can specify all the values or you can default the Build and Revision Numbers - Можно задать все значения или принять номера сборки и редакции по умолчанию - - - - by using the '*' as shown below: - используя "*", как показано ниже: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.tr.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.tr.xlf deleted file mode 100644 index 906ec8f3ef1..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.tr.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Bir bütünleştirilmiş koda ilişkin Genel Bilgiler aşağıdaki - - - - set of attributes. Change these attribute values to modify the information - öznitelikler kümesi. Bilgileri değiştirmek için bu öznitelik değerlerini değiştirin - - - - associated with an assembly. - Bir bütünleştirilmiş kod ile ilişkilendirildi. - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible ayarının false olarak belirlenmesi bu derlemedeki türleri - - - - to COM components. If you need to access a type in this assembly from - COM bileşenlerine görünmez yapar. Bu derlemedeki bir türe COM'dan - - - - COM, set the ComVisible attribute to true on that type. - erişmeniz gerekirse ComVisible özniteliğini o türde true olarak ayarlayın. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Eğer bu proje COM'a maruz kaldıysa aşağıdaki GUID typelib'in IDsi içindir - - - - Version information for an assembly consists of the following four values: - Bir derlemenin sürüm bilgileri aşağıdaki dört değerden oluşur: - - - - Major Version - Birincil Sürüm - - - - Minor Version - İkincil Sürüm - - - - Build Number - Yapı Numarası - - - - Revision - Düzeltme - - - - You can specify all the values or you can default the Build and Revision Numbers - Tüm değerleri belirtebilir veya varsayılan Oluşturma ve Düzeltme Numaralarını kullanabilirsiniz - - - - by using the '*' as shown below: - '*' karakterini aşağıda gösterildiği gibi kullanarak: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf deleted file mode 100644 index d76c9dbd18c..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 有关程序集的一般信息由以下 - - - - set of attributes. Change these attribute values to modify the information - 控制。更改这些特性值可修改 - - - - associated with an assembly. - 与程序集关联的信息。 - - - - Setting ComVisible to false makes the types in this assembly not visible - 将 ComVisible 设置为 false 将使此程序集中的类型 - - - - to COM components. If you need to access a type in this assembly from - 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, - - - - COM, set the ComVisible attribute to true on that type. - 请将此类型的 ComVisible 特性设置为 true。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID - - - - Version information for an assembly consists of the following four values: - 程序集的版本信息由下列四个值组成: - - - - Major Version - 主版本 - - - - Minor Version - 次版本 - - - - Build Number - 生成号 - - - - Revision - 修订 - - - - You can specify all the values or you can default the Build and Revision Numbers - 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, - - - - by using the '*' as shown below: - 方法是按如下所示使用“*”: : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf deleted file mode 100644 index 477f8719df2..00000000000 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 組件的一般資訊是由下列的屬性集控制 - - - - set of attributes. Change these attribute values to modify the information - 變更這些屬性的值即可修改組件的相關 - - - - associated with an assembly. - 資訊。 - - - - Setting ComVisible to false makes the types in this assembly not visible - 將 ComVisible 設定為 false 會使得這個組件中的類型 - - - - to COM components. If you need to access a type in this assembly from - 對 COM 元件而言為不可見。如果您需要從 COM 存取這個組件中 - - - - COM, set the ComVisible attribute to true on that type. - 的類型,請在該類型上將 ComVisible 屬性設定為 true。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID - - - - Version information for an assembly consists of the following four values: - 組件的版本資訊由下列四個值所組成: : - - - - Major Version - 主要版本 - - - - Minor Version - 次要版本 - - - - Build Number - 組建編號 - - - - Revision - 修訂 - - - - You can specify all the values or you can default the Build and Revision Numbers - 您可以指定所有的值,也可以依照以下的方式,使用 '*' 將組建和修訂編號 - - - - by using the '*' as shown below: - 指定為預設值: : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.cs.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.cs.xlf index 0a1913fea3f..b54b6d53c3d 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.cs.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.cs.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Další informace o F# najdete na https://fsharp.org. + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Další informace o jazyce F# najdete tady: http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.de.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.de.xlf index 8c434e9d7d1..3573f5021b0 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.de.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.de.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Weitere Informationen zu F# unter https://fsharp.org. + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Weitere Informationen zu F# finden Sie unter http://docs.microsoft.com/dotnet/fsharp. diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.es.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.es.xlf index 1472966885a..3565bf48a71 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.es.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.es.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Más información sobre F# en https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Más información sobre F# en http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.fr.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.fr.xlf index 8052d98708d..06c45ec7743 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.fr.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.fr.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - En savoir plus sur F# : https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + En savoir plus sur F# via http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.it.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.it.xlf index c9027ad5b69..3385c6204c9 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.it.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.it.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Altre informazioni su F# disponibili all'indirizzo https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Per altre informazioni su F#, vedere http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ja.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ja.xlf index c24608aec3b..a25923007d1 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ja.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ja.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - F# の詳細については、https://fsharp.org をご覧ください + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + F# の詳細については、http://docs.microsoft.com/dotnet/fsharp をご覧ください diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ko.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ko.xlf index 7d9f7dc54e7..a9f8f539e2e 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ko.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ko.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - https://fsharp.org에서 F#에 대해 자세히 알아보기 + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + http://docs.microsoft.com/dotnet/fsharp에서 F#에 대해 자세히 알아보기 diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pl.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pl.xlf index 763d2db3df3..42fe1bd1ad6 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pl.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pl.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Dowiedz się więcej o języku F# na stronie https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Dowiedz się więcej o języku F# na stronie http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pt-BR.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pt-BR.xlf index 7af54cd8fd5..f0553f51b64 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pt-BR.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.pt-BR.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Saiba mais sobre o F# em https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Saiba mais sobre F# em http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ru.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ru.xlf index 54eb018503e..537eb62e114 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ru.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.ru.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - Дополнительные сведения об F# см. на странице https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + Дополнительные сведения о F#: http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.tr.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.tr.xlf index c584140b66b..1aa76c73bbe 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.tr.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.tr.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - F# hakkında daha fazla bilgi edinmek için bkz. https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + F# hakkında daha fazla bilgi için bkz. http://docs.microsoft.com/dotnet/fsharp diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hans.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hans.xlf index 27df727dbda..90e5612f980 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hans.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hans.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - 了解更多关于 F# 的信息,请访问 https://fsharp.org + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + 通过 http://docs.microsoft.com/dotnet/fsharp 详细了解 F# diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hant.xlf b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hant.xlf index 5f67238de8b..af978bf2e1a 100644 --- a/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hant.xlf +++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/xlf/Program.fs.zh-Hant.xlf @@ -3,8 +3,8 @@ - Learn more about F# at https://fsharp.org - 前往 https://fsharp.org 深入了解 F# + Learn more about F# at http://docs.microsoft.com/dotnet/fsharp + 前往 http://docs.microsoft.com/dotnet/fsharp 深入了解 F# diff --git a/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj b/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj index 23239f00471..df4c0ed9ee8 100644 --- a/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj +++ b/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj @@ -9,7 +9,6 @@ - Template\AssemblyInfo.fs; Template\Script.fsx; diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/AssemblyInfo.fs b/vsintegration/ProjectTemplates/LibraryProject/Template/AssemblyInfo.fs deleted file mode 100644 index ae735840e65..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/AssemblyInfo.fs +++ /dev/null @@ -1,41 +0,0 @@ -namespace $safeprojectname$.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// @@@GeneralInfo-Line1|General Information about an assembly is controlled through the following@@@ -// @@@GeneralInfo-Line2|set of attributes. Change these attribute values to modify the information@@@ -// @@@GeneralInfo-Line3|associated with an assembly.@@@ -[] -[] -[] -[] -[] -[] -[] -[] - -// @@@ComVisible-Line1|Setting ComVisible to false makes the types in this assembly not visible@@@ -// @@@ComVisible-Line2|to COM components. If you need to access a type in this assembly from@@@ -// @@@ComVisible-Line3|COM, set the ComVisible attribute to true on that type.@@@ -[] - -// @@@Guid-Line1|The following GUID is for the ID of the typelib if this project is exposed to COM@@@ -[] - -// @@@VersionInfo-Line1|Version information for an assembly consists of the following four values:@@@ -// -// @@@MajorVersion|Major Version@@@ -// @@@MinorVersion|Minor Version@@@ -// @@@BuildNumber|Build Number@@@ -// @@@Revision|Revision@@@ -// -// @@@VersionInfo-Line2|You can specify all the values or you can default the Build and Revision Numbers@@@ -// @@@VersionInfo-Line3|by using the '*' as shown below:@@@ -// [] -[] -[] - -do - () \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj index 5878583967c..736dff548d6 100644 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj +++ b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj @@ -1,61 +1,13 @@ - - - + - Debug - AnyCPU - 2.0 - $guid1$ - Library - $safeprojectname$ - $safeprojectname$ - true - v$targetframeworkversion$ - true - 3239;$(WarningsAsErrors) +$if$ ($targetframeworkversion$ == 4.5) net45$endif$$if$ ($targetframeworkversion$ == 4.6) net46 $endif$$if$ ($targetframeworkversion$ == 4.6.1) net461 $endif$$if$ ($targetframeworkversion$ == 4.6.2) net462 $endif$$if$ ($targetframeworkversion$ == 4.7) net47 $endif$$if$ ($targetframeworkversion$ == 4.7.1) net471 $endif$$if$ ($targetframeworkversion$ == 4.7.2) net472 $endif$$if$ ($targetframeworkversion$ == 4.8) net48 $endif$ +$if$ ($safeprojectname$ != $projectname$) $safeprojectname$ $endif$ + true + 3390;$(WarnOn) - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - - - - - + - - - 11 - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate index d7f9a14d8d2..a04914c2eea 100644 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate +++ b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate @@ -15,7 +15,6 @@ - AssemblyInfo.fs Library1.fs Script.fsx @@ -24,10 +23,4 @@ NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a NuGet.VisualStudio.TemplateWizard - - - - - - diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.cs.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.cs.xlf deleted file mode 100644 index a580d9e396b..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.cs.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Obecné informace o sestavení se řídí přes následující - - - - set of attributes. Change these attribute values to modify the information - sadu atributů. Změnou hodnot těchto atributů se upraví informace - - - - associated with an assembly. - přidružené k sestavení. - - - - Setting ComVisible to false makes the types in this assembly not visible - Nastavením atributu ComVisible na hodnotu False budou typy v tomto sestavení neviditelné - - - - to COM components. If you need to access a type in this assembly from - pro komponenty modelu COM. Pokud potřebujete přistoupit k typu v tomto sestavení z - - - - COM, set the ComVisible attribute to true on that type. - modelu COM, nastavte atribut ComVisible daného typu na hodnotu True. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Následující GUID se používá pro ID knihovny typů, pokud je tento projekt vystavený pro COM. - - - - Version information for an assembly consists of the following four values: - Informace o verzi sestavení se skládá z těchto čtyř hodnot: - - - - Major Version - Hlavní verze - - - - Minor Version - Podverze - - - - Build Number - Číslo sestavení - - - - Revision - Revize - - - - You can specify all the values or you can default the Build and Revision Numbers - Můžete zadat všechny hodnoty nebo nechat nastavená výchozí čísla sestavení a revize - - - - by using the '*' as shown below: - pomocí zástupného znaku * takto: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.de.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.de.xlf deleted file mode 100644 index 8df6ae7fc3b..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.de.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Allgemeine Informationen über eine Assembly werden über die folgende - - - - set of attributes. Change these attribute values to modify the information - Attributgruppe gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, - - - - associated with an assembly. - die einer Assembly zugeordnet sind. - - - - Setting ComVisible to false makes the types in this assembly not visible - Durch Festlegen von ComVisible auf FALSE sind die Typen in dieser Assembly nicht - - - - to COM components. If you need to access a type in this assembly from - für COM-Komponenten sichtbar. Wenn Sie auf einen Typ in dieser Assembly von - - - - COM, set the ComVisible attribute to true on that type. - COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf TRUE festlegen. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird - - - - Version information for an assembly consists of the following four values: - Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: - - - - Major Version - Hauptversion - - - - Minor Version - Nebenversion - - - - Build Number - Buildnummer - - - - Revision - Revision - - - - You can specify all the values or you can default the Build and Revision Numbers - Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern - - - - by using the '*' as shown below: - übernehmen, indem Sie "*" eingeben: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.es.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.es.xlf deleted file mode 100644 index 9beb403796f..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.es.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - La información general de un ensamblado se controla mediante el siguiente - - - - set of attributes. Change these attribute values to modify the information - conjunto de atributos. Cambie estos valores de atributo para modificar la información - - - - associated with an assembly. - asociada con un ensamblado. - - - - Setting ComVisible to false makes the types in this assembly not visible - Si establece ComVisible en false, los tipos de este ensamblado no estarán visibles - - - - to COM components. If you need to access a type in this assembly from - para los componentes COM. Si necesita obtener acceso a un tipo de este ensamblado desde - - - - COM, set the ComVisible attribute to true on that type. - COM, establezca el atributo ComVisible en true en este tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - El siguiente GUID sirve como id. de typelib si este proyecto se expone a COM. - - - - Version information for an assembly consists of the following four values: - La información de versión de un ensamblado consta de los cuatro valores siguientes: - - - - Major Version - Versión principal - - - - Minor Version - Versión secundaria - - - - Build Number - Número de compilación - - - - Revision - Revisión - - - - You can specify all the values or you can default the Build and Revision Numbers - Puede especificar todos los valores o usar los valores predeterminados de número de compilación y de revisión - - - - by using the '*' as shown below: - mediante el carácter '*', como se muestra a continuación: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.fr.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.fr.xlf deleted file mode 100644 index a259bd30511..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.fr.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Les informations générales relatives à un assembly dépendent de - - - - set of attributes. Change these attribute values to modify the information - l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations - - - - associated with an assembly. - associées à un assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly - - - - to COM components. If you need to access a type in this assembly from - aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de - - - - COM, set the ComVisible attribute to true on that type. - COM, affectez la valeur true à l'attribut ComVisible sur ce type. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM - - - - Version information for an assembly consists of the following four values: - Les informations de version pour un assembly se composent des quatre valeurs suivantes : - - - - Major Version - Version principale - - - - Minor Version - Version secondaire - - - - Build Number - Numéro de build - - - - Revision - Révision - - - - You can specify all the values or you can default the Build and Revision Numbers - Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut - - - - by using the '*' as shown below: - en utilisant '*', comme indiqué ci-dessous : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.it.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.it.xlf deleted file mode 100644 index d5fc6c75583..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.it.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Le informazioni generali relative a un assembly sono controllate dal seguente - - - - set of attributes. Change these attribute values to modify the information - set di attributi. Modificare i valori di questi attributi per modificare le informazioni - - - - associated with an assembly. - associate a un assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili - - - - to COM components. If you need to access a type in this assembly from - ai componenti COM. Se è necessario accedere a un tipo in questo assembly da - - - - COM, set the ComVisible attribute to true on that type. - COM, impostare su true l'attributo ComVisible per tale tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Se il progetto viene esposto a COM, il seguente GUID verrà utilizzato come ID della libreria dei tipi - - - - Version information for an assembly consists of the following four values: - Le informazioni sulla versione di un assembly sono costituite dai quattro valori seguenti: - - - - Major Version - Versione principale - - - - Minor Version - Versione secondaria - - - - Build Number - Numero di build - - - - Revision - Revisione - - - - You can specify all the values or you can default the Build and Revision Numbers - È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build - - - - by using the '*' as shown below: - utilizzando l'asterisco (*) come illustrato di seguito: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ja.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ja.xlf deleted file mode 100644 index 1f413753d11..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ja.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - アセンブリに関する一般情報は、以下の属性セットによって - - - - set of attributes. Change these attribute values to modify the information - 制御されます。アセンブリに関連付けられている情報を変更するには、 - - - - associated with an assembly. - これらの属性値を変更します。 - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible を false に設定すると、COM コンポーネントがこのアセンブリ内のその型を認識 - - - - to COM components. If you need to access a type in this assembly from - できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 - - - - COM, set the ComVisible attribute to true on that type. - その型の ComVisible 属性を true に設定します。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - このプロジェクトが COM に公開される場合、次の GUID がタイプ ライブラリの ID になります - - - - Version information for an assembly consists of the following four values: - アセンブリのバージョン情報は、以下の 4 つの値で構成されます。: - - - - Major Version - メジャー バージョン - - - - Minor Version - マイナー バージョン - - - - Build Number - ビルド番号 - - - - Revision - リビジョン - - - - You can specify all the values or you can default the Build and Revision Numbers - すべての値を指定するか、下に示すように '*' を使用してビルドおよびリビジョン番号を - - - - by using the '*' as shown below: - 既定値にすることができます。: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ko.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ko.xlf deleted file mode 100644 index 258b4ebab29..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ko.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 어셈블리의 일반 정보는 다음 특성 집합을 통해 - - - - set of attributes. Change these attribute values to modify the information - 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 - - - - associated with an assembly. - 이러한 특성 값을 변경하세요. - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 - - - - to COM components. If you need to access a type in this assembly from - 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 - - - - COM, set the ComVisible attribute to true on that type. - 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. - - - - Version information for an assembly consists of the following four values: - 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.: - - - - Major Version - 주 버전 - - - - Minor Version - 부 버전 - - - - Build Number - 빌드 번호 - - - - Revision - 수정 버전 - - - - You can specify all the values or you can default the Build and Revision Numbers - 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 버전이 자동으로 - - - - by using the '*' as shown below: - 지정되도록 할 수 있습니다.: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pl.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pl.xlf deleted file mode 100644 index ee3471fb557..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pl.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Ogólne informacje o zestawie są kontrolowane poprzez następujący - - - - set of attributes. Change these attribute values to modify the information - zbiór atrybutów. Zmień wartości tych atrybutów by zmodyfikować informacje - - - - associated with an assembly. - powiązane z zestawem. - - - - Setting ComVisible to false makes the types in this assembly not visible - Ustawienie wartości ComVisible na false sprawia, że typy w tym zestawie nie będą widoczne - - - - to COM components. If you need to access a type in this assembly from - dla składników COM. Jeśli potrzebny jest dostęp do typu w tym zestawie z - - - - COM, set the ComVisible attribute to true on that type. - COM, ustaw atrybut ComVisible na true dla danego typu. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Następujący GUID jest dla ID typelib jeśli ten projekt jest dostępny dla COM - - - - Version information for an assembly consists of the following four values: - Informacje o wersji zestawu zawierają następujące cztery wartości: - - - - Major Version - Wersja główna - - - - Minor Version - Wersja pomocnicza - - - - Build Number - Numer kompilacji - - - - Revision - Poprawka - - - - You can specify all the values or you can default the Build and Revision Numbers - Można określać wszystkie wartości lub używać domyślnych numerów kompilacji i poprawki - - - - by using the '*' as shown below: - przy użyciu symbolu „*”, tak jak pokazano poniżej: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf deleted file mode 100644 index 48d258faa25..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.pt-BR.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - As informações gerais sobre um assembly são controladas por meio do seguinte - - - - set of attributes. Change these attribute values to modify the information - conjunto de atributos. Altere estes valores de atributo para modificar as informações - - - - associated with an assembly. - associados a um assembly. - - - - Setting ComVisible to false makes the types in this assembly not visible - Definir ComVisible como false oculta os tipos neste assembly - - - - to COM components. If you need to access a type in this assembly from - para componentes COM. Caso precise acessar um tipo neste assembly a partir de - - - - COM, set the ComVisible attribute to true on that type. - COM, defina o atributo ComVisible como true nesse tipo. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - O GUID a seguir é para a ID de typelib quando este projeto é exposto a COM - - - - Version information for an assembly consists of the following four values: - As informações da versão de um assembly consistem nos quatro valores a seguir: - - - - Major Version - Versão Principal - - - - Minor Version - Versão Secundária - - - - Build Number - Número da Versão - - - - Revision - Revisão - - - - You can specify all the values or you can default the Build and Revision Numbers - É possível especificar todos os valores ou usar como padrão os Números da Versão e da Revisão - - - - by using the '*' as shown below: - utilizando o '*' como mostrado abaixo: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ru.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ru.xlf deleted file mode 100644 index c0f2735eae2..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.ru.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Общие сведения о сборке можно задать с помощью следующего - - - - set of attributes. Change these attribute values to modify the information - набора атрибутов. Отредактируйте эти значения атрибутов, чтобы изменить сведения, - - - - associated with an assembly. - связанные с этой сборкой. - - - - Setting ComVisible to false makes the types in this assembly not visible - При установке значения False в атрибуте ComVisible типы в этой сборке становятся невидимыми - - - - to COM components. If you need to access a type in this assembly from - для COM-компонентов. Если требуется обратиться к типу в этой сборке через - - - - COM, set the ComVisible attribute to true on that type. - COM, задайте для атрибута ComVisible значение True для этого типа. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Следующий GUID служит для идентификации библиотеки типов, если этот проект видим для COM - - - - Version information for an assembly consists of the following four values: - Сведения о версии сборки состоят из следующих четырех значений: - - - - Major Version - Основной номер версии - - - - Minor Version - Вспомогательная версия - - - - Build Number - Номер сборки - - - - Revision - Редакция - - - - You can specify all the values or you can default the Build and Revision Numbers - Можно задать все значения или принять номера сборки и редакции по умолчанию - - - - by using the '*' as shown below: - используя "*", как показано ниже: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.tr.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.tr.xlf deleted file mode 100644 index 906ec8f3ef1..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.tr.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - Bir bütünleştirilmiş koda ilişkin Genel Bilgiler aşağıdaki - - - - set of attributes. Change these attribute values to modify the information - öznitelikler kümesi. Bilgileri değiştirmek için bu öznitelik değerlerini değiştirin - - - - associated with an assembly. - Bir bütünleştirilmiş kod ile ilişkilendirildi. - - - - Setting ComVisible to false makes the types in this assembly not visible - ComVisible ayarının false olarak belirlenmesi bu derlemedeki türleri - - - - to COM components. If you need to access a type in this assembly from - COM bileşenlerine görünmez yapar. Bu derlemedeki bir türe COM'dan - - - - COM, set the ComVisible attribute to true on that type. - erişmeniz gerekirse ComVisible özniteliğini o türde true olarak ayarlayın. - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - Eğer bu proje COM'a maruz kaldıysa aşağıdaki GUID typelib'in IDsi içindir - - - - Version information for an assembly consists of the following four values: - Bir derlemenin sürüm bilgileri aşağıdaki dört değerden oluşur: - - - - Major Version - Birincil Sürüm - - - - Minor Version - İkincil Sürüm - - - - Build Number - Yapı Numarası - - - - Revision - Düzeltme - - - - You can specify all the values or you can default the Build and Revision Numbers - Tüm değerleri belirtebilir veya varsayılan Oluşturma ve Düzeltme Numaralarını kullanabilirsiniz - - - - by using the '*' as shown below: - '*' karakterini aşağıda gösterildiği gibi kullanarak: - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf deleted file mode 100644 index d76c9dbd18c..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hans.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 有关程序集的一般信息由以下 - - - - set of attributes. Change these attribute values to modify the information - 控制。更改这些特性值可修改 - - - - associated with an assembly. - 与程序集关联的信息。 - - - - Setting ComVisible to false makes the types in this assembly not visible - 将 ComVisible 设置为 false 将使此程序集中的类型 - - - - to COM components. If you need to access a type in this assembly from - 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, - - - - COM, set the ComVisible attribute to true on that type. - 请将此类型的 ComVisible 特性设置为 true。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID - - - - Version information for an assembly consists of the following four values: - 程序集的版本信息由下列四个值组成: - - - - Major Version - 主版本 - - - - Minor Version - 次版本 - - - - Build Number - 生成号 - - - - Revision - 修订 - - - - You can specify all the values or you can default the Build and Revision Numbers - 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, - - - - by using the '*' as shown below: - 方法是按如下所示使用“*”: : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf b/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf deleted file mode 100644 index 477f8719df2..00000000000 --- a/vsintegration/ProjectTemplates/LibraryProject/Template/xlf/AssemblyInfo.fs.zh-Hant.xlf +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - General Information about an assembly is controlled through the following - 組件的一般資訊是由下列的屬性集控制 - - - - set of attributes. Change these attribute values to modify the information - 變更這些屬性的值即可修改組件的相關 - - - - associated with an assembly. - 資訊。 - - - - Setting ComVisible to false makes the types in this assembly not visible - 將 ComVisible 設定為 false 會使得這個組件中的類型 - - - - to COM components. If you need to access a type in this assembly from - 對 COM 元件而言為不可見。如果您需要從 COM 存取這個組件中 - - - - COM, set the ComVisible attribute to true on that type. - 的類型,請在該類型上將 ComVisible 屬性設定為 true。 - - - - The following GUID is for the ID of the typelib if this project is exposed to COM - 下列 GUID 為專案公開 (Expose) 至 COM 時所要使用的 typelib ID - - - - Version information for an assembly consists of the following four values: - 組件的版本資訊由下列四個值所組成: : - - - - Major Version - 主要版本 - - - - Minor Version - 次要版本 - - - - Build Number - 組建編號 - - - - Revision - 修訂 - - - - You can specify all the values or you can default the Build and Revision Numbers - 您可以指定所有的值,也可以依照以下的方式,使用 '*' 將組建和修訂編號 - - - - by using the '*' as shown below: - 指定為預設值: : - - - - - \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj index dd2eed1525f..83103261b80 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj @@ -1,66 +1,12 @@ - - - + - Debug - AnyCPU - 2.0 - $guid1$ Exe - $safeprojectname$ - $safeprojectname$ - v$targetframeworkversion$ - true - true - true - 3239;$(WarningsAsErrors) +$if$ ($targetframeworkversion$ == 4.5) net45$endif$$if$ ($targetframeworkversion$ == 4.6) net46 $endif$$if$ ($targetframeworkversion$ == 4.6.1) net461 $endif$$if$ ($targetframeworkversion$ == 4.6.2) net462 $endif$$if$ ($targetframeworkversion$ == 4.7) net47 $endif$$if$ ($targetframeworkversion$ == 4.7.1) net471 $endif$$if$ ($targetframeworkversion$ == 4.7.2) net472 $endif$$if$ ($targetframeworkversion$ == 4.8) net48 $endif$ +$if$ ($safeprojectname$ != $projectname$) $safeprojectname$ $endif$ + 3390;$(WarnOn) - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - - - - - - - + - - - 11 - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + + \ No newline at end of file diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx index 52b6649ca38..741e8c5a866 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx @@ -1,4 +1,4 @@ -// @@@SampleHeader|This sample will guide you through elements of the F# language.@@@ +// @@@SampleHeader|This sample will guide you through elements of the F# language.@@@ // // ******************************************************************************************************* // @@@Instructions-Line1|To execute the code in F# Interactive, highlight a section of code and press Alt-Enter or right-click@@@ @@ -986,12 +986,3 @@ module Events = // @@@TriggerEventWithArgs|Next, trigger this event (note that sender argument should be set).@@@ eventForDelegateType.Trigger(null, EventArgs.Empty) - - - -#if COMPILED -module BoilerPlateForForm = - [] - do () - do System.Windows.Forms.Application.Run() -#endif diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate index adb7d6e2306..2fbdb597665 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate @@ -22,10 +22,4 @@ NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a NuGet.VisualStudio.TemplateWizard - - - - - - diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf index 0908855049f..610ce9ef2be 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf @@ -29,12 +29,12 @@ To learn more about applied F# programming, use - Verwenden Sie Folgendes, um weitere Informationen zur praktischen F#-Programmierung zu erhalten: + Verwenden Sie Folgendes, um weitere Informationen zur praktischen F#-Programmierung zu erhalten To install the Visual F# Power Tools, use - Verwenden Sie Folgendes, um die Visual F# Power Tools zu installieren: + Verwenden Sie Folgendes, um die Visual F# Power Tools zu installieren @@ -669,7 +669,7 @@ This definition produces a new list by squaring the numbers in numberList, using the pipeline - Diese Definition erzeugt eine neue Liste, indem die Zahlen in "numberList" quadriert werden. Dabei wird der Pipeline- + Diese Definition erzeugt eine neue Liste, indem die Zahlen in "numberList" quadriert werden. Dabei wird der Pipeline diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf index ecd508e58b0..67464ae660a 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf @@ -1464,7 +1464,7 @@ Get a new scaled vector object, without modifying the original object. - Consente di ottenere un nuovo oggetto vettore scalato senza modificare l'oggetto originale. + Consente di ottenere un nuovo oggetto vettore dimensionato senza modificare l'oggetto originale. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf index 0eda61edb13..d65696afff3 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf @@ -14,7 +14,7 @@ and select "Execute in Interactive". You can open the F# Interactive Window from the "View" menu. - [対話形式で実行]5D; を選択します。[表示]5D; メニューから F# インタラクティブ ウィンドウを開くことができます。 + [対話形式で実行] を選択します。[表示] メニューから F# インタラクティブ ウィンドウを開くことができます。 @@ -39,7 +39,7 @@ 'Tools' --> 'Extensions and Updates' --> `Online` and search - [ツール]5D; --> [拡張機能と更新プログラム]5D; --> [オンライン]5D; と検索 + [ツール] --> [拡張機能と更新プログラム] --> [オンライン] と検索 @@ -49,7 +49,7 @@ 'New Project' --> 'Online Templates' - ([新しいプロジェクト]5D; --> [オンライン テンプレート]5D;) を参照してください。 + ([新しいプロジェクト] --> [オンライン テンプレート]) を参照してください。 @@ -639,7 +639,7 @@ Lists can also be generated by computations. This is a list containing - リストは計算によっても生成できます。これは、次を含むリストです: + リストは計算によっても生成できます。これは、次を含むリストです @@ -679,7 +679,7 @@ There are many other list combinations. The following computes the sum of the squares of the - 他に多くのリストの組み合わせがあります。次の二乗和をコンピューティングします: + 他に多くのリストの組み合わせがあります。次の二乗和をコンピューティングします @@ -929,17 +929,17 @@ This example shows how to use "copy-and-update" on record values. It creates - この例では、レコード値で "copy-and-update" を使用する方法を示します。次を作成します: + この例では、レコード値で "copy-and-update" を使用する方法を示します。次を作成します a new record value that is a copy of contact1, but has different values for - contact1 のコピーであるレコード値。ただし、次の値は異なります: + contact1 のコピーであるレコード値。ただし、次の値は異なります the 'Phone' and 'Verified' fields. - [電話番号]5D; および [検証済み]5D; フィールド。 + [電話番号] および [検証済み] フィールド。 @@ -1434,7 +1434,7 @@ This internal field stores the length of the vector, computed when the - この内部フィールドはベクトルの長さを格納します。これは、次の時点でにコンピューティングされます: + この内部フィールドはベクトルの長さを格納します。これは、次の時点でにコンピューティングされます @@ -1464,7 +1464,7 @@ Get a new scaled vector object, without modifying the original object. - 元のオブジェクトを変更せずに、新しく調節されたベクター オブジェクトを取得します。 + 元のオブジェクトを変更せずに、新しくスケーリングされたベクター オブジェクトを取得します。 diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf index 7e8e4a4de40..4a3ca2fc756 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf @@ -19,12 +19,12 @@ For more about F#, see: - F#에 대한 자세한 내용은 다음을 참조하세요. + F#에 대한 자세한 내용은 다음을 참조하세요: To see this tutorial in documentation form, see: - 이 자습서를 설명서 형식으로 보려면 다음을 참조하세요. + 이 자습서를 설명서 형식으로 보려면 다음을 참조하세요: @@ -54,7 +54,7 @@ F# supports three kinds of comments: - F#에서는 세 가지 종류의 주석을 지원합니다. + F#에서는 세 가지 종류의 주석을 지원합니다: @@ -279,7 +279,7 @@ To learn more, see: - 자세히 알아보려면 다음을 참조하세요. + 자세히 알아보려면 다음을 참조하세요: @@ -1169,7 +1169,7 @@ However, there are two important things to know when doing this: - 하지만 이 작업을 수행할 때는 다음 두 가지 중요한 사항을 알고 있어야 합니다. + 하지만 이 작업을 수행할 때는 다음 두 가지 중요한 사항을 알고 있어야 합니다: diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf index 64df6c8506c..1e305245465 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf @@ -1464,7 +1464,7 @@ Get a new scaled vector object, without modifying the original object. - Obter um novo objeto de vetor em escala, sem modificar o objeto original. + Obter um novo objeto de vetor escalado, sem modificar o objeto original. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf index 2fcd8d0f2c2..780ba42bac5 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf @@ -29,7 +29,7 @@ To learn more about applied F# programming, use - Uygulamalı F# programlama hakkında daha fazla bilgi edinmek için şunu kullanın: + Uygulamalı F# programlama hakkında daha fazla bilgi edinmek için şunu kullanın @@ -279,7 +279,7 @@ To learn more, see: - Daha fazla bilgi için bkz. + Daha fazla bilgi için bkz: diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf index cb0a1983afd..5df1fe3de9d 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf @@ -679,7 +679,7 @@ There are many other list combinations. The following computes the sum of the squares of the - 还有许多其他列表组合。下面计算以下内容的平方和: + 还有许多其他列表组合。下面计算以下内容的平方和 @@ -849,7 +849,7 @@ This example shows a recursive function that computes the factorial of an - 此示例演示递归函数,计算以下内容的阶乘: + 此示例演示递归函数,计算以下内容的阶乘 @@ -934,7 +934,7 @@ a new record value that is a copy of contact1, but has different values for - 新的记录值,该值是 contact1 的副本,但对以下内容具有不同的值: + 新的记录值,该值是 contact1 的副本,但对以下内容具有不同的值 @@ -1434,7 +1434,7 @@ This internal field stores the length of the vector, computed when the - 此内部字段存储矢量的长度,当发生以下情况时进行计算: + 此内部字段存储矢量的长度,当发生以下情况时进行计算 diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf index fd33d17fa37..0df179cdd76 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf @@ -39,17 +39,17 @@ 'Tools' --> 'Extensions and Updates' --> `Online` and search - [工具]5D; --> [延伸模組和更新]5D; --> [連線]5D; 並搜尋 + [工具] --> [延伸模組和更新] --> [連線] 並搜尋 For additional templates to use with F#, see the 'Online Templates' in Visual Studio, - 如需有關搭配 F# 一起使用的其他範本,請參閱 Visual Studio 中的 [線上範本]5D;, + 如需有關搭配 F# 一起使用的其他範本,請參閱 Visual Studio 中的 [線上範本], 'New Project' --> 'Online Templates' - [新增專案]5D; --> [線上範本]5D; + [新增專案] --> [線上範本] @@ -679,7 +679,7 @@ There are many other list combinations. The following computes the sum of the squares of the - 還有許多其他清單組合。以下會計算下項的平方總和: + 還有許多其他清單組合。以下會計算下項的平方總和 @@ -849,7 +849,7 @@ This example shows a recursive function that computes the factorial of an - 此範例顯示遞迴函式,其可計算下項的階乘: + 此範例顯示遞迴函式,其可計算下項的階乘 @@ -934,12 +934,12 @@ a new record value that is a copy of contact1, but has different values for - 新記錄值,其為 contact1 的複本,但對於下項有不同的值: + 新記錄值,其為 contact1 的複本,但對於下項有不同的值 the 'Phone' and 'Verified' fields. - [Phone]5D; 與 [Verified]5D; 欄位。 + [Phone] 與 [Verified] 欄位。 @@ -1339,7 +1339,7 @@ This uses combinators in the Option module to allow a functional pipeline for - 這會在 Option 模組中使用結合器,以允許在執行下列功能時使用功能管線: + 這會在 Option 模組中使用結合器,以允許在執行下列功能時使用功能管線 @@ -1464,7 +1464,7 @@ Get a new scaled vector object, without modifying the original object. - 取得全新且可調整大小的向量物件,但不修改原始物件。 + 取得全新且可縮放大小的向量物件,但不修改原始物件。 diff --git a/vsintegration/Utils/LanguageServiceProfiling/App.config b/vsintegration/Utils/LanguageServiceProfiling/App.config deleted file mode 100644 index 8324aa6ff15..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/vsintegration/Utils/LanguageServiceProfiling/AssemblyInfo.fs b/vsintegration/Utils/LanguageServiceProfiling/AssemblyInfo.fs deleted file mode 100644 index f67c0c9e9b4..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/AssemblyInfo.fs +++ /dev/null @@ -1,28 +0,0 @@ -namespace LanguageServiceProfiling.AssemblyInfo - -open System.Reflection -open System.Runtime.CompilerServices -open System.Runtime.InteropServices - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[] -[] -[] -[] -[] -[] -[] -[] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[] - - -do () \ No newline at end of file diff --git a/vsintegration/Utils/LanguageServiceProfiling/LanguageServiceProfiling.fsproj b/vsintegration/Utils/LanguageServiceProfiling/LanguageServiceProfiling.fsproj deleted file mode 100644 index 1b2f4b81dde..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/LanguageServiceProfiling.fsproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Exe - true - true - $(SystemValueTupleVersion) - true - - - - - - - - - - - - - - - - diff --git a/vsintegration/Utils/LanguageServiceProfiling/Options.fs b/vsintegration/Utils/LanguageServiceProfiling/Options.fs deleted file mode 100644 index 0662f09dd7d..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/Options.fs +++ /dev/null @@ -1,430 +0,0 @@ -module internal LanguageServiceProfiling.Options - -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open System -open System.IO - -let private () x y = Path.Combine(x, y) - -type CompletionPosition = { - Position: pos - QualifyingNames : string list - PartialName : string -} - -type Options = - { Options: FSharpProjectOptions - FileToCheck: string - FilesToCheck: string list - SymbolText: string - SymbolPos: pos - CompletionPositions: CompletionPosition list } - - -let FCS (repositoryDir: string) : Options = - let files = - [| @"src\fsharp\FSharp.Compiler.Service\obj\Release\FSComp.fs" - @"src\fsharp\FSharp.Compiler.Service\obj\Release\FSIstrings.fs" - @"src\assemblyinfo\assemblyinfo.FSharp.Compiler.Private.dll.fs" - @"src\assemblyinfo\assemblyinfo.shared.fs" - @"src\utils\sformat.fsi" - @"src\utils\sformat.fs" - @"src\fsharp\sr.fsi" - @"src\fsharp\sr.fs" - @"src\utils\prim-lexing.fsi" - @"src\utils\prim-lexing.fs" - @"src\utils\prim-parsing.fsi" - @"src\utils\prim-parsing.fs" - @"src\utils\ResizeArray.fsi" - @"src\utils\ResizeArray.fs" - @"src\utils\HashMultiMap.fsi" - @"src\utils\HashMultiMap.fs" - @"src\utils\EditDistance.fs" - @"src\utils\TaggedCollections.fsi" - @"src\utils\TaggedCollections.fs" - @"src\fsharp\QueueList.fs" - @"src\absil\ildiag.fsi" - @"src\absil\ildiag.fs" - @"src\absil\illib.fs" - @"src\utils\filename.fsi" - @"src\utils\filename.fs" - @"src\absil\zmap.fsi" - @"src\absil\zmap.fs" - @"src\absil\zset.fsi" - @"src\absil\zset.fs" - @"src\absil\bytes.fsi" - @"src\absil\bytes.fs" - @"src\fsharp\lib.fs" - @"src\fsharp\ErrorResolutionHints.fs" - @"src\fsharp\InternalCollections.fsi" - @"src\fsharp\InternalCollections.fs" - @"src\fsharp\rational.fsi" - @"src\fsharp\rational.fs" - @"src\fsharp\range.fsi" - @"src\fsharp\range.fs" - @"src\fsharp\ErrorLogger.fs" - @"src\fsharp\ReferenceResolver.fs" - @"src\absil\il.fsi" - @"src\absil\il.fs" - @"src\absil\ilx.fsi" - @"src\absil\ilx.fs" - @"src\absil\ilascii.fsi" - @"src\absil\ilascii.fs" - @"src\absil\ilprint.fsi" - @"src\absil\ilprint.fs" - @"src\absil\ilmorph.fsi" - @"src\absil\ilmorph.fs" - @"src\absil\ilwritenativeres.fsi" - @"src\absil\ilwritenativeres.fs" - @"src\absil\ilsupp.fsi" - @"src\absil\ilsupp.fs" - @"src\fsharp\FSharp.Compiler.Service\ilpars.fs" - @"src\fsharp\FSharp.Compiler.Service\illex.fs" - @"src\absil\ilbinary.fsi" - @"src\absil\ilbinary.fs" - @"src\absil\ilread.fsi" - @"src\absil\ilread.fs" - @"src\absil\ilwritepdb.fsi" - @"src\absil\ilwritepdb.fs" - @"src\absil\ilwrite.fsi" - @"src\absil\ilwrite.fs" - @"src\absil\ilreflect.fs" - @"src\utils\CompilerLocationUtils.fs" - @"src\fsharp\PrettyNaming.fs" - @"src\ilx\ilxsettings.fs" - @"src\ilx\EraseClosures.fsi" - @"src\ilx\EraseClosures.fs" - @"src\ilx\EraseUnions.fsi" - @"src\ilx\EraseUnions.fs" - @"src\fsharp\UnicodeLexing.fsi" - @"src\fsharp\UnicodeLexing.fs" - @"src\fsharp\layout.fsi" - @"src\fsharp\layout.fs" - @"src\fsharp\ast.fs" - @"src\fsharp\FSharp.Compiler.Service\pppars.fs" - @"src\fsharp\FSharp.Compiler.Service\pars.fs" - @"src\fsharp\lexhelp.fsi" - @"src\fsharp\lexhelp.fs" - @"src\fsharp\FSharp.Compiler.Service\pplex.fs" - @"src\fsharp\FSharp.Compiler.Service\lex.fs" - @"src\fsharp\LexFilter.fs" - @"src\fsharp\tainted.fsi" - @"src\fsharp\tainted.fs" - @"src\fsharp\ExtensionTyping.fsi" - @"src\fsharp\ExtensionTyping.fs" - @"src\fsharp\QuotationPickler.fsi" - @"src\fsharp\QuotationPickler.fs" - @"src\fsharp\tast.fs" - @"src\fsharp\TcGlobals.fs" - @"src\fsharp\TastOps.fsi" - @"src\fsharp\TastOps.fs" - @"src\fsharp\TastPickle.fsi" - @"src\fsharp\TastPickle.fs" - @"src\fsharp\import.fsi" - @"src\fsharp\import.fs" - @"src\fsharp\infos.fs" - @"src\fsharp\AccessibilityLogic.fs" - @"src\fsharp\AttributeChecking.fs" - @"src\fsharp\InfoReader.fs" - @"src\fsharp\NicePrint.fs" - @"src\fsharp\AugmentWithHashCompare.fsi" - @"src\fsharp\AugmentWithHashCompare.fs" - @"src\fsharp\NameResolution.fsi" - @"src\fsharp\NameResolution.fs" - @"src\fsharp\TypeRelations.fs" - @"src\fsharp\SignatureConformance.fs" - @"src\fsharp\MethodOverrides.fs" - @"src\fsharp\MethodCalls.fs" - @"src\fsharp\PatternMatchCompilation.fsi" - @"src\fsharp\PatternMatchCompilation.fs" - @"src\fsharp\ConstraintSolver.fsi" - @"src\fsharp\ConstraintSolver.fs" - @"src\fsharp\CheckFormatStrings.fsi" - @"src\fsharp\CheckFormatStrings.fs" - @"src\fsharp\FindUnsolved.fsi" - @"src\fsharp\FindUnsolved.fs" - @"src\fsharp\QuotationTranslator.fsi" - @"src\fsharp\QuotationTranslator.fs" - @"src\fsharp\PostInferenceChecks.fsi" - @"src\fsharp\PostInferenceChecks.fs" - @"src\fsharp\TypeChecker.fsi" - @"src\fsharp\TypeChecker.fs" - @"src\fsharp\Optimizer.fsi" - @"src\fsharp\Optimizer.fs" - @"src\fsharp\DetupleArgs.fsi" - @"src\fsharp\DetupleArgs.fs" - @"src\fsharp\InnerLambdasToTopLevelFuncs.fsi" - @"src\fsharp\InnerLambdasToTopLevelFuncs.fs" - @"src\fsharp\LowerCallsAndSeqs.fsi" - @"src\fsharp\LowerCallsAndSeqs.fs" - @"src\fsharp\autobox.fsi" - @"src\fsharp\autobox.fs" - @"src\fsharp\IlxGen.fsi" - @"src\fsharp\IlxGen.fs" - @"src\fsharp\CompileOps.fsi" - @"src\fsharp\CompileOps.fs" - @"src\fsharp\CompileOptions.fsi" - @"src\fsharp\CompileOptions.fs" - @"src\fsharp\fsc.fsi" - @"src\fsharp\fsc.fs" - @"src\fsharp\service\IncrementalBuild.fsi" - @"src\fsharp\service\IncrementalBuild.fs" - @"src\fsharp\service\Reactor.fsi" - @"src\fsharp\service\Reactor.fs" - @"src\fsharp\service\ServiceConstants.fs" - @"src\fsharp\symbols\SymbolHelpers.fsi" - @"src\fsharp\symbols\SymbolHelpers.fs" - @"src\fsharp\symbols\Symbols.fsi" - @"src\fsharp\symbols\Symbols.fs" - @"src\fsharp\symbols\Exprs.fsi" - @"src\fsharp\symbols\Exprs.fs" - @"src\fsharp\service\ServiceLexing.fsi" - @"src\fsharp\service\ServiceLexing.fs" - @"src\fsharp\service\ServiceParseTreeWalk.fs" - @"src\fsharp\service\ServiceNavigation.fsi" - @"src\fsharp\service\ServiceNavigation.fs" - @"src\fsharp\service\ServiceParamInfoLocations.fsi" - @"src\fsharp\service\ServiceParamInfoLocations.fs" - @"src\fsharp\service\ServiceUntypedParse.fsi" - @"src\fsharp\service\ServiceUntypedParse.fs" - @"src\fsharp\SimulatedMSBuildReferenceResolver.fs" - @"src\fsharp\service\FSharpCheckerResults.fsi" - @"src\fsharp\service\FSharpCheckerResults.fs" - @"src\fsharp\service\service.fsi" - @"src\fsharp\service\service.fs" - @"src\fsharp\service\SimpleServices.fsi" - @"src\fsharp\service\SimpleServices.fs" - @"src\fsharp\fsi\fsi.fsi" - @"src\fsharp\fsi\fsi.fs" |] - - { Options = - {ProjectFileName = repositoryDir @"src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj" - ProjectId = None - SourceFiles = files |> Array.map (fun x -> repositoryDir x) - OtherOptions = - [|@"-o:obj\Release\FSharp.Compiler.Private.dll"; "-g"; "--noframework"; - @"--baseaddress:0x06800000"; "--define:DEBUG"; - @"--define:CROSS_PLATFORM_COMPILER"; - @"--define:FX_ATLEAST_40"; - @"--define:COMPILER"; - @"--define:ENABLE_MONO_SUPPORT"; "--define:FX_MSBUILDRESOLVER_RUNTIMELIKE"; - @"--define:FX_RESX_RESOURCE_READER"; "--define:FX_RESIDENT_COMPILER"; - @"--define:SHADOW_COPY_REFERENCES"; "--define:EXTENSIONTYPING"; - @"--define:COMPILER_SERVICE_DLL_ASSUMES_FSHARP_CORE_4_4_0_0"; - @"--define:COMPILER_SERVICE_DLL"; "--define:NO_STRONG_NAMES"; "--define:TRACE"; - @"--doc:..\..\..\bin\v4.5\FSharp.Compiler.Service.xml"; "--optimize-"; - @"--platform:anycpu"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll"; - @"-r:" + (repositoryDir @"packages\System.Collections.Immutable\lib\netstandard1.0\System.Collections.Immutable.dll"); - @"-r:" + (repositoryDir @"packages\FSharp.Core\lib\net40\FSharp.Core.dll"); - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Numerics.dll"; - @"-r:" + (repositoryDir @"packages\System.Reflection.Metadata\lib\portable-net45+win8\System.Reflection.Metadata.dll"); - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Runtime.Serialization.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Collections.Concurrent.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Collections.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.Annotations.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.EventBasedAsync.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Contracts.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Debug.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tools.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Dynamic.Runtime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Globalization.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.IO.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Expressions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Parallel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Queryable.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.NetworkInformation.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.Requests.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ObjectModel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.ILGeneration.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.Lightweight.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Resources.ResourceManager.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.InteropServices.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.InteropServices.WindowsRuntime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Numerics.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Json.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Xml.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Security.Principal.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Duplex.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Http.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.NetTcp.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Security.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.Encoding.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.Encoding.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.RegularExpressions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.Tasks.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.Tasks.Parallel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.ReaderWriter.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.XDocument.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.XmlSerializer.dll"; - @"--target:library"; "--nowarn:44,62,9,69,65,54,61,75"; "--warnaserror:76"; - @"--vserrors"; "--utf8output"; "--fullpaths"; "--flaterrors"; - @"--subsystemversion:6.00"; "--highentropyva+"; "/warnon:1182"; "--times"; - @"--no-jit-optimize"; "--jit-tracking"|] - ReferencedProjects = [||] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime.Now - UnresolvedReferences = None; - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = None } - FilesToCheck = - files - |> Array.filter (fun s -> s.Contains "TypeChecker.fs" || - s.Contains "Optimizer.fs" || - s.Contains "IlxGen.fs" || - s.Contains "TastOps.fs" || - s.Contains "TcGlobals.fs" || - s.Contains "CompileOps.fs" || - s.Contains "CompileOptions.fs") - |> Array.map (fun x -> repositoryDir x) - |> Array.toList - FileToCheck = repositoryDir @"src\fsharp\TypeChecker.fs" - SymbolText = "Some" - SymbolPos = mkPos 120 7 - CompletionPositions = [] } - -let VFPT (repositoryDir: string) : Options = - { Options = - {ProjectFileName = repositoryDir @"src\FSharp.Editing\FSharp.Editing.fsproj" - ProjectId = None - SourceFiles = - [|@"src\FSharp.Editing\AssemblyInfo.fs"; - @"src\FSharp.Editing\Common\Utils.fs"; - @"src\FSharp.Editing\Common\CompilerLocationUtils.fs"; - @"src\FSharp.Editing\Common\UntypedAstUtils.fs"; - @"src\FSharp.Editing\Common\TypedAstUtils.fs"; - @"src\FSharp.Editing\Common\Lexer.fs"; - @"src\FSharp.Editing\Common\XmlDocParser.fs"; - @"src\FSharp.Editing\Common\IdentifierUtils.fs"; - @"src\FSharp.Editing\ProjectSystem\AssemblyContentProvider.fs"; - @"src\FSharp.Editing\ProjectSystem\OpenDocumentsTracker.fs"; - @"src\FSharp.Editing\ProjectSystem\LanguageService.fs"; - @"src\FSharp.Editing\ProjectSystem\SolutionProvider.fs"; - @"src\FSharp.Editing\Navigation\NavigableItemsCollector.fs"; - @"src\FSharp.Editing\Navigation\NavigateToIndex.fs"; - @"src\FSharp.Editing\Coloring\DepthParser.fs"; - @"src\FSharp.Editing\Coloring\OpenDeclarationsGetter.fs"; - @"src\FSharp.Editing\Coloring\UnopenedNamespacesResolver.fs"; - @"src\FSharp.Editing\Coloring\HighlightUsageInFile.fs"; - @"src\FSharp.Editing\Coloring\PrintfSpecifiersUsageGetter.fs"; - @"src\FSharp.Editing\Symbols\SourceCodeClassifier.fs"; - @"src\FSharp.Editing\CodeGeneration\CodeGeneration.fs"; - @"src\FSharp.Editing\CodeGeneration\SignatureGenerator.fs"; - @"src\FSharp.Editing\CodeGeneration\UnionPatternMatchCaseGenerator.fs"; - @"src\FSharp.Editing\CodeGeneration\InterfaceStubGenerator.fs"; - @"src\FSharp.Editing\CodeGeneration\RecordStubGenerator.fs"; - @"src\FSharp.Editing\TaskListCommentExtractor.fs"|] - |> Array.map (fun x -> repositoryDir x) - OtherOptions = - [|@"-o:obj\Release\FSharp.Editing.dll"; "--debug:pdbonly"; "--noframework"; - @"--define:TRACE"; "--doc:bin\Release\FSharp.Editing.XML"; "--optimize+"; - @"-r:" + (repositoryDir @"packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Private.dll"); - @"-r:" + (repositoryDir @"packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.MSBuild.v12.dll"); - @"-r:" + (repositoryDir @"packages\FSharp.Core\lib\net40\FSharp.Core.dll"); - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll"; - @"-r:" + (repositoryDir @"packages\System.Collections.Immutable\lib\netstandard1.0\System.Collections.Immutable.dll"); - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Numerics.dll"; - @"-r:" + (repositoryDir @"packages\System.Reflection.Metadata\lib\netstandard1.1\System.Reflection.Metadata.dll"); - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Collections.Concurrent.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Collections.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.Annotations.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ComponentModel.EventBasedAsync.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Contracts.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Debug.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tools.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Diagnostics.Tracing.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Dynamic.Runtime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Globalization.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.IO.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Expressions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Parallel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Linq.Queryable.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.NetworkInformation.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Net.Requests.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ObjectModel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.ILGeneration.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Emit.Lightweight.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Reflection.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Resources.ResourceManager.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.InteropServices.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.InteropServices.WindowsRuntime.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Numerics.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Json.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Runtime.Serialization.Xml.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Security.Principal.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Duplex.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Http.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.NetTcp.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Primitives.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.ServiceModel.Security.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.Encoding.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.Encoding.Extensions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Text.RegularExpressions.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.Tasks.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Threading.Tasks.Parallel.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.ReaderWriter.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.XDocument.dll"; - @"-r:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\System.Xml.XmlSerializer.dll"; - @"--target:library"; "--nowarn:52"; "--warn:5"; "--warnaserror"; - @"--warnaserror:76"; "--vserrors"; "--utf8output"; "--fullpaths"; - @"--flaterrors"; "--subsystemversion:6.00"; "--highentropyva+"; - @"--warnon:1182"|]; - ReferencedProjects = [||] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime.Now - UnresolvedReferences = None - OriginalLoadReferences = [] - ExtraProjectInfo = None - Stamp = None } - FilesToCheck = [] - FileToCheck = repositoryDir @"src\FSharp.Editing\CodeGeneration\RecordStubGenerator.fs" - SymbolText = "option" - SymbolPos = mkPos 19 23 - CompletionPositions = - [{ - Position = mkPos 20 4 - QualifyingNames = [] - PartialName = "" - }] - } - -let get (repositoryDir: string) : Options = - let repositoryDir = Path.GetFullPath(repositoryDir) - match DirectoryInfo(Path.GetFullPath(repositoryDir)).Name.ToLower() with - | "fsharp.compiler.service" -> FCS(repositoryDir) - | "fsharpvspowertools" -> VFPT(repositoryDir) - | _ -> failwithf "%s is not supported" repositoryDir - diff --git a/vsintegration/Utils/LanguageServiceProfiling/Program.fs b/vsintegration/Utils/LanguageServiceProfiling/Program.fs deleted file mode 100644 index fc33ebc7d2d..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/Program.fs +++ /dev/null @@ -1,279 +0,0 @@ -(* - -Background check a project "CXGSCGS" (Check, Flush, GC, Stats, Check, GC, Stats) - - .\Release\net40\bin\LanguageServiceProfiling.exe ..\FSharp.Compiler.Service CXGSCGS - -Foreground check new versions of multiple files in an already-checked project and keep intellisense info "CGSFGS" (Check, GC, Stats, File, GC, Stats) - - .\Release\net40\bin\LanguageServiceProfiling.exe ..\FSharp.Compiler.Service CGSFGS - - - -Use the following to collect memory usage stats, appending to the existing stats files: - - git clone https://github.com/fsharp/FSharp.Compiler.Service tests\scripts\tmp\FSharp.Compiler.Service - pushd tests\scripts\tmp\FSharp.Compiler.Service - git checkout 2d51df21ca1d86d4d6676ead3b1fb125b2a0d1ba - .\build Build.NetFx - popd - - git rev-parse HEAD > gitrev.txt - set /P gitrev=> tests\scripts\service-fcs-project-check-mem-results.txt - .\Release\net40\bin\LanguageServiceProfiling.exe ..\FSharp.Compiler.Service CGSFGS %gitrev% >> tests\scripts\service-fcs-file-check-mem-results.txt - -Results look like this: - - Background FCS project: - master: TimeDelta: 24.70 MemDelta: 318 G0: 880 G1: 696 G2: 8 - - Background FCS project (with keepAllBackgroundResolutions=true) : - master: TimeDelta: 23.84 MemDelta: 448 G0: 877 G1: 702 G2: 6 - - Multiple foreground files from FCS project keeping all results: - statistics: TimeDelta: 8.58 MemDelta: 143 G0: 260 G1: 192 G2: 4 - - - -*) - -open FSharp.Compiler -open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices -open System -open System.IO -open LanguageServiceProfiling -open System.Diagnostics -open System.Collections.Generic -// ---- taken from QuickInfoProviderTests.fs -let normalizeLineEnds (s: string) = s.Replace("\r\n", "\n").Replace("\n\n", "\n") -let internal getQuickInfoText (FSharpToolTipText.FSharpToolTipText elements) : string = - let rec parseElement = function - | FSharpToolTipElement.None -> "" - | FSharpToolTipElement.Group(xs) -> xs |> List.map (fun item -> item.MainDescription) |> String.concat "\n" - | FSharpToolTipElement.CompositionError(error) -> error - elements |> List.map (parseElement) |> String.concat "\n" |> normalizeLineEnds - -[] -let main argv = - let rootDir = argv.[0] - let scriptOpt = if argv.Length >= 2 then Some argv.[1] else None - let msgOpt = if argv.Length >= 3 then Some argv.[2] else None - let useConsole = scriptOpt.IsNone - let options = Options.get rootDir - let getFileLines () = File.ReadAllLines(options.FileToCheck) - let getFileText () = File.ReadAllText(options.FileToCheck) - let getLine line = (getFileLines ()).[line] - - eprintfn "Found options for %s." options.Options.ProjectFileName - let checker = FSharpChecker.Create(projectCacheSize = 200, keepAllBackgroundResolutions = false) - let waste = new ResizeArray() - - let checkProject() : Async = - async { - eprintfn "ParseAndCheckProject(%s)..." (Path.GetFileName options.Options.ProjectFileName) - let sw = Stopwatch.StartNew() - let! result = checker.ParseAndCheckProject(options.Options) - if result.HasCriticalErrors then - eprintfn "Finished with ERRORS: %+A" result.Errors - return None - else - eprintfn "Finished successfully in %O" sw.Elapsed - return Some result - } - - let checkFile (fileVersion: int) : Async = - async { - eprintfn "ParseAndCheckFileInProject(%s)..." options.FileToCheck - let sw = Stopwatch.StartNew() - let! _, answer = checker.ParseAndCheckFileInProject(options.FileToCheck, fileVersion, SourceText.ofString (File.ReadAllText options.FileToCheck), options.Options) - match answer with - | FSharpCheckFileAnswer.Aborted -> - eprintfn "Abortedin %O!" sw.Elapsed - return None - | FSharpCheckFileAnswer.Succeeded results -> - if results.Errors |> Array.exists (fun x -> x.Severity = FSharpErrorSeverity.Error) then - eprintfn "Finished with ERRORS in %O: %+A" sw.Elapsed results.Errors - return None - else - eprintfn "Finished successfully in %O" sw.Elapsed - return Some results - } - - let checkFiles (fileVersion: int) = - async { - eprintfn "multiple ParseAndCheckFileInProject(...)..." - let sw = Stopwatch.StartNew() - let answers = - options.FilesToCheck |> List.map (fun file -> - eprintfn "doing %s" file - checker.ParseAndCheckFileInProject(file, fileVersion, SourceText.ofString (File.ReadAllText file), options.Options) |> Async.RunSynchronously) - for _,answer in answers do - match answer with - | FSharpCheckFileAnswer.Aborted -> - eprintfn "Aborted!" - | FSharpCheckFileAnswer.Succeeded results -> - if results.Errors |> Array.exists (fun x -> x.Severity = FSharpErrorSeverity.Error) then - eprintfn "Finished with ERRORS: %+A" results.Errors - eprintfn "Finished in %O" sw.Elapsed - } - - let findAllReferences (fileVersion: int) : Async = - async { - eprintfn "Find all references (symbol = '%s', file = '%s')" options.SymbolText options.FileToCheck - let! projectResults = checkProject() - match projectResults with - | Some projectResults -> - let! fileResults = checkFile fileVersion - match fileResults with - | Some fileResults -> - let! symbolUse = fileResults.GetSymbolUseAtLocation(options.SymbolPos.Line, options.SymbolPos.Column, getLine(options.SymbolPos.Line),[options.SymbolText]) - match symbolUse with - | Some symbolUse -> - eprintfn "Found symbol %s" symbolUse.Symbol.FullName - let sw = Stopwatch.StartNew() - let! symbolUses = projectResults.GetUsesOfSymbol(symbolUse.Symbol) - eprintfn "Found %d symbol uses in %O" symbolUses.Length sw.Elapsed - return symbolUses - | None -> - eprintfn "Symbol '%s' was not found at (%d, %d) in %s" options.SymbolText options.SymbolPos.Line options.SymbolPos.Column options.FileToCheck - return [||] - | None -> - eprintfn "No file check results for %s" options.FileToCheck - return [||] - | None -> - eprintfn "No project results for %s" options.Options.ProjectFileName - return [||] - } - let getDeclarations (fileVersion: int) = - async { - let! projectResults = checkProject() - match projectResults with - | Some projectResults -> - let! fileResults = checkFile fileVersion - match fileResults with - | Some fileResults -> - let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions(options.Options) - let! parseResult = checker.ParseFile(options.FileToCheck, SourceText.ofString (getFileText()), parsingOptions) - for completion in options.CompletionPositions do - eprintfn "querying %A %s" completion.QualifyingNames completion.PartialName - let! listInfo = - fileResults.GetDeclarationListInfo( - Some parseResult, - completion.Position.Line, - getLine (completion.Position.Line), - { QualifyingIdents = completion.QualifyingNames - PartialIdent = completion.PartialName - EndColumn = completion.Position.Column - 1 - LastDotPos = None }, - fun() -> []) - - for i in listInfo.Items do - eprintfn "%s" (getQuickInfoText i.DescriptionText) - - | None -> eprintfn "no declarations" - | None -> eprintfn "no declarations" - } - - let wasteMemory () = - waste.Add(Array.zeroCreate (1024 * 1024 * 25)) - - if useConsole then - eprintfn """Press: - - for check the project - for GC.Collect(2) - for check TypeChecker.fs (you need to change it before rechecking) - for find all references - for completion lists - for wasting 100M of memory - to clear all caches -

to pause for key entry - to reclaim waste - for exit.""" - - let mutable tPrev = None - let stats() = - // Note that timing calls are relatively expensive on the startup path so we don't - // make this call unless showTimes has been turned on. - let uproc = System.Diagnostics.Process.GetCurrentProcess() - let timeNow = uproc.UserProcessorTime.TotalSeconds - let maxGen = System.GC.MaxGeneration - let gcNow = [| for i in 0 .. maxGen -> System.GC.CollectionCount(i) |] - let wsNow = uproc.WorkingSet64/1000000L - - match tPrev with - | Some (timePrev, gcPrev:int[], wsPrev)-> - let spanGC = [| for i in 0 .. maxGen -> System.GC.CollectionCount(i) - gcPrev.[i] |] - printfn "%s TimeDelta: %4.2f MemDelta: %4d G0: %4d G1: %4d G2: %4d" - (match msgOpt with Some msg -> msg | None -> "statistics:") - (timeNow - timePrev) - (wsNow - wsPrev) - spanGC.[min 0 maxGen] spanGC.[min 1 maxGen] spanGC.[min 2 maxGen] - - | _ -> () - tPrev <- Some (timeNow, gcNow, wsNow) - - let processCmd (fileVersion: int) c = - match c with - | 'C' -> - checkProject() |> Async.RunSynchronously |> ignore - fileVersion - | 'G' -> - eprintfn "GC is running..." - let sw = Stopwatch.StartNew() - GC.Collect 2 - eprintfn "GC is done in %O" sw.Elapsed - fileVersion - | 'F' -> - checkFiles fileVersion |> Async.RunSynchronously |> ignore - (fileVersion + 1) - | 'R' -> - findAllReferences fileVersion |> Async.RunSynchronously |> ignore - fileVersion - | 'L' -> - getDeclarations fileVersion |> Async.RunSynchronously - fileVersion - | 'W' -> - wasteMemory() - fileVersion - | 'M' -> - waste.Clear() - fileVersion - | 'S' -> - stats() - fileVersion - | 'X' -> - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - fileVersion - | 'P' -> - eprintfn "pausing (press any key)..."; - System.Console.ReadKey() |> ignore - fileVersion - | _ -> fileVersion - - let rec console fileVersion = - match Console.ReadKey().Key with - | ConsoleKey.C -> processCmd fileVersion 'C' |> console - | ConsoleKey.G -> processCmd fileVersion 'G' |> console - | ConsoleKey.F -> processCmd fileVersion 'F' |> console - | ConsoleKey.R -> processCmd fileVersion 'R' |> console - | ConsoleKey.L -> processCmd fileVersion 'L' |> console - | ConsoleKey.W -> processCmd fileVersion 'W' |> console - | ConsoleKey.M -> processCmd fileVersion 'M' |> console - | ConsoleKey.X -> processCmd fileVersion 'X' |> console - | ConsoleKey.P -> processCmd fileVersion 'P' |> console - | ConsoleKey.Enter -> () - | _ -> console fileVersion - - let runScript (script:string) = - (0,script) ||> Seq.fold processCmd |> ignore - - match scriptOpt with - | None -> console 0 - | Some s -> runScript s - 0 \ No newline at end of file diff --git a/vsintegration/Utils/LanguageServiceProfiling/ProjectCracker.fs b/vsintegration/Utils/LanguageServiceProfiling/ProjectCracker.fs deleted file mode 100644 index 787527bbe95..00000000000 --- a/vsintegration/Utils/LanguageServiceProfiling/ProjectCracker.fs +++ /dev/null @@ -1,2 +0,0 @@ -namespace FSharp.Compiler.SourceCodeServices.ProjectCrackerTool - diff --git a/vsintegration/Vsix/VisualFSharpFull/Properties/launchSettings.json b/vsintegration/Vsix/VisualFSharpFull/Properties/launchSettings.json index 18d884aa2e7..a3e00ad6bec 100644 --- a/vsintegration/Vsix/VisualFSharpFull/Properties/launchSettings.json +++ b/vsintegration/Vsix/VisualFSharpFull/Properties/launchSettings.json @@ -1,6 +1,6 @@ { "profiles": { - "VisualFSharpFull": { + "VisualFSharpDebug": { "commandName": "Executable", "executablePath": "$(DevEnvDir)devenv.exe", "commandLineArgs": "/rootsuffix $(VSSDKTargetPlatformRegRootSuffix) /log" diff --git a/vsintegration/Vsix/VisualFSharpFull/Source.extension.vsixmanifest b/vsintegration/Vsix/VisualFSharpFull/Source.extension.vsixmanifest index cae75397665..c6294c49632 100644 --- a/vsintegration/Vsix/VisualFSharpFull/Source.extension.vsixmanifest +++ b/vsintegration/Vsix/VisualFSharpFull/Source.extension.vsixmanifest @@ -15,10 +15,12 @@ - + + + @@ -28,10 +30,6 @@ - - diff --git a/vsintegration/Vsix/VisualFSharpFull/VisualFSharp.Core.targets b/vsintegration/Vsix/VisualFSharpFull/VisualFSharp.Core.targets new file mode 100644 index 00000000000..3650e6ef923 --- /dev/null +++ b/vsintegration/Vsix/VisualFSharpFull/VisualFSharp.Core.targets @@ -0,0 +1,256 @@ + + + + + + + Designer + + + + RegisterFsharpPackage.pkgdef + {{FSProductVersion}} + $(FSProductVersion) + {{FSLanguageVersion}} + $(FSLanguageVersion) + true + RegisterFsharpPackage.pkgdef + + + + PreserveNewest + License.txt + true + + + + + + {702A7979-BCF9-4C41-853E-3ADFC9897890} + FSharp.Build + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + TargetFramework=$(DependencyTargetFramework) + + + + {649FA588-F02E-457C-9FCF-87E46407481E} + FSharp.Compiler.Interactive.Settings + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + TargetFramework=netstandard2.0 + + + + {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06} + FSharp.Compiler.Server.Shared + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + TargetFramework=$(DependencyTargetFramework) + + + + {A59DB8AE-8044-41A5-848A-800A7FF31C93} + FSharp.Compiler.Service + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + TargetFramework=$(DependencyTargetFramework) + + + + {DED3BBD7-53F4-428A-8C9F-27968E768605} + FSharp.Core + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + TargetFramework=netstandard2.0 + + + + false + False + + + + false + False + + + + false + False + + + + {65e0e82a-eace-4787-8994-888674c2fe87} + FSharp.Editor + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {c4586a06-1402-48bc-8e35-a1b8642f895b} + FSharp.UIResources + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + True + + + + {1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF} + FSharp.LanguageService.Base + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {EE85AAB7-CDA0-4C4E-BDA0-A64CCC413E3F} + FSharp.LanguageService + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7} + ProjectSystem.Base + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {6196B0F8-CAEA-4CF1-AF82-1B520F77FE44} + ProjectSystem + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {FCFB214C-462E-42B3-91CA-FC557EFEE74F} + FSharp.PropertiesPages + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {991DCF75-C2EB-42B6-9A0D-AA1D2409D519} + FSharp.VS.FSI + BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b + DebugSymbolsProjectOutputGroup%3b + true + All + 2 + True + + + + {6ba13aa4-c25f-480f-856b-8e8000299a72} + AppConfig + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {12ac2813-e895-4aaa-ae6c-94e21da09f64} + CodeFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {0385564F-07B4-4264-AB8A-17C393E9140C} + ResourceFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {a333b85a-dc23-49b6-9797-b89a7951e92d} + ScriptFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {e3fdd4ac-46b6-4b9f-b672-317d1202cc50} + SignatureFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {d11fc318-8f5d-4c8c-9287-ab40a016d13c} + TextFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + {1fb1dd07-06aa-45b4-b5ac-20ff5bee98b6} + XMLFile + ItemTemplates + TemplateProjectOutputGroup%3b + false + True + + + + + + + + + \ No newline at end of file diff --git a/vsintegration/Vsix/VisualFSharpFull/VisualFSharpDebug.csproj b/vsintegration/Vsix/VisualFSharpFull/VisualFSharpDebug.csproj new file mode 100644 index 00000000000..3c667559ccb --- /dev/null +++ b/vsintegration/Vsix/VisualFSharpFull/VisualFSharpDebug.csproj @@ -0,0 +1,55 @@ + + + + + + Library + Microsoft\FSharp + netcoreapp1.0 + true + net472 + + + + + + + + + + + + + + Tools/%(_XlfLanguages.Identity) + true + + + + Tools/%(_XlfLanguages.Identity) + true + + + + Tools/%(_XlfLanguages.Identity) + true + + + + Tools + true + + + + Tools + true + + + + Tools + true + + + + + diff --git a/vsintegration/Vsix/VisualFSharpFull/VisualFSharpFull.csproj b/vsintegration/Vsix/VisualFSharpFull/VisualFSharpFull.csproj index d68067fe1e1..10c18b8530e 100644 --- a/vsintegration/Vsix/VisualFSharpFull/VisualFSharpFull.csproj +++ b/vsintegration/Vsix/VisualFSharpFull/VisualFSharpFull.csproj @@ -8,295 +8,10 @@ netcoreapp1.0 true net472 + + false - - - Designer - + - - RegisterFsharpPackage.pkgdef - {{FSProductVersion}} - $(FSProductVersion) - {{FSLanguageVersion}} - $(FSLanguageVersion) - true - RegisterFsharpPackage.pkgdef - - - - PreserveNewest - License.txt - true - - - - PreserveNewest - FSharp.Data.TypeProviders.dll - true - - - - - - {702A7979-BCF9-4C41-853E-3ADFC9897890} - FSharp.Build - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {649FA588-F02E-457C-9FCF-87E46407481E} - FSharp.Compiler.Interactive.Settings - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {60BAFFA5-6631-4328-B044-2E012AB76DCA} - FSharp.Compiler.LanguageServer - PublishedProjectOutputGroup%3b - false - Build;Publish - TargetFramework=$(DependencyTargetFramework) - - - {D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06} - FSharp.Compiler.Server.Shared - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3} - FSharp.Compiler.Private - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - FSharp.DependencyManager - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=net472 - - - {DED3BBD7-53F4-428A-8C9F-27968E768605} - FSharp.Core - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - TargetFramework=net45 - - - {8B3E283D-B5FE-4055-9D80-7E3A32F3967B} - FsiAnyCpu - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - [installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsiAnyCpu.exe - X64 - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {D0E98C0D-490B-4C61-9329-0862F6E87645} - Fsi - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - [installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsi.exe - X86 - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {C94C257C-3C0A-4858-B5D8-D746498D1F08} - fsc - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3b - DebugSymbolsProjectOutputGroup%3b - true - [installDir]\Common7\IDE\CommonExtensions\Microsoft\FSharp\fsc.exe - All - 2 - True - TargetFramework=$(DependencyTargetFramework) - - - {65e0e82a-eace-4787-8994-888674c2fe87} - FSharp.Editor - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {0A3099F1-F0C7-4ADE-AB9B-526EF193A56F} - FSharp.Editor.Helpers - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {c4586a06-1402-48bc-8e35-a1b8642f895b} - FSharp.UIResources - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - True - - - {1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF} - FSharp.LanguageService.Base - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {EE85AAB7-CDA0-4C4E-BDA0-A64CCC413E3F} - FSharp.LanguageService - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7} - ProjectSystem.Base - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {6196B0F8-CAEA-4CF1-AF82-1B520F77FE44} - ProjectSystem - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {FCFB214C-462E-42B3-91CA-FC557EFEE74F} - FSharp.PropertiesPages - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - {991DCF75-C2EB-42B6-9A0D-AA1D2409D519} - FSharp.VS.FSI - BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - true - All - 2 - True - - - - {6ba13aa4-c25f-480f-856b-8e8000299a72} - AppConfig - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {12ac2813-e895-4aaa-ae6c-94e21da09f64} - CodeFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {0385564F-07B4-4264-AB8A-17C393E9140C} - ResourceFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {a333b85a-dc23-49b6-9797-b89a7951e92d} - ScriptFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {e3fdd4ac-46b6-4b9f-b672-317d1202cc50} - SignatureFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {d11fc318-8f5d-4c8c-9287-ab40a016d13c} - TextFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - {1fb1dd07-06aa-45b4-b5ac-20ff5bee98b6} - XMLFile - ItemTemplates - TemplateProjectOutputGroup%3b - false - True - - - - - - - - - + \ No newline at end of file diff --git a/vsintegration/Vsix/VisualFSharpTemplates/VisualFSharpTemplates.csproj b/vsintegration/Vsix/VisualFSharpTemplates/VisualFSharpTemplates.csproj index cfab3f5dfa6..95a5b470ee9 100644 --- a/vsintegration/Vsix/VisualFSharpTemplates/VisualFSharpTemplates.csproj +++ b/vsintegration/Vsix/VisualFSharpTemplates/VisualFSharpTemplates.csproj @@ -10,26 +10,11 @@ - - PreserveNewest - packages\System.ValueTuple.4.4.0.nupkg - true - - - PreserveNewest - packages\FSharp.Core.$(FSharpCoreShippedPackageVersion).nupkg - true - Designer - - - - - {604f0daa-2d33-48dd-b162-edf0b672803d} diff --git a/vsintegration/src/FSharp.Editor.Helpers/FSharp.Editor.Helpers.csproj b/vsintegration/src/FSharp.Editor.Helpers/FSharp.Editor.Helpers.csproj deleted file mode 100644 index cb6cfb36cb0..00000000000 --- a/vsintegration/src/FSharp.Editor.Helpers/FSharp.Editor.Helpers.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - Library - net472 - - - - - - - - - - - FSharp.Editor.Helpers - $(VSAssemblyVersion) - $PackageFolder$\FSharp.Editor.Helpers.dll - - - - diff --git a/vsintegration/src/FSharp.Editor.Helpers/LanguageClient.cs b/vsintegration/src/FSharp.Editor.Helpers/LanguageClient.cs deleted file mode 100644 index 87759ceef7b..00000000000 --- a/vsintegration/src/FSharp.Editor.Helpers/LanguageClient.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.LanguageServer.Client; -using Microsoft.VisualStudio.Threading; - -namespace Microsoft.VisualStudio.FSharp.Editor.Helpers -{ - ///

- /// Exists as an abstract implementor of purely to manage the non-standard async - /// event handlers. - /// - public abstract class LanguageClient : ILanguageClient - { - public abstract string Name { get; } - - public abstract IEnumerable ConfigurationSections { get; } - - public abstract object InitializationOptions { get; } - - public abstract IEnumerable FilesToWatch { get; } - - public event AsyncEventHandler StartAsync; - -#pragma warning disable 67 // The event 'LanguageClient.StopAsync' is never used - public event AsyncEventHandler StopAsync; -#pragma warning restore 67 - - public abstract Task ActivateAsync(CancellationToken token); - - protected abstract Task DoLoadAsync(); - - public async Task OnLoadedAsync() - { - await DoLoadAsync(); - await StartAsync.InvokeAsync(this, EventArgs.Empty); - } - - public abstract Task OnServerInitializeFailedAsync(Exception e); - - public abstract Task OnServerInitializedAsync(); - } -} diff --git a/vsintegration/src/FSharp.Editor/AutomaticCompletion/BraceCompletionSessionProvider.fs b/vsintegration/src/FSharp.Editor/AutomaticCompletion/BraceCompletionSessionProvider.fs index dd3be821094..184dbcf959d 100644 --- a/vsintegration/src/FSharp.Editor/AutomaticCompletion/BraceCompletionSessionProvider.fs +++ b/vsintegration/src/FSharp.Editor/AutomaticCompletion/BraceCompletionSessionProvider.fs @@ -76,11 +76,11 @@ type BraceCompletionSession let mutable openingPoint : ITrackingPoint = null let editorOperations = editorOperationsFactoryService.GetEditorOperations(textView) - member __.EndSession() = + member _.EndSession() = closingPoint <- null openingPoint <- null - member __.CreateUndoTransaction() = + member _.CreateUndoTransaction() = undoHistory.CreateTransaction(BraceCompletion) member this.Start (cancellationToken: CancellationToken) = @@ -148,7 +148,7 @@ type BraceCompletionSession undo.Complete() - member __.HasNoForwardTyping(caretPoint: SnapshotPoint, endPoint: SnapshotPoint) = + member _.HasNoForwardTyping(caretPoint: SnapshotPoint, endPoint: SnapshotPoint) = Debug.Assert(caretPoint.Snapshot = endPoint.Snapshot, "snapshots do not match") if caretPoint.Snapshot = endPoint.Snapshot then @@ -173,7 +173,7 @@ type BraceCompletionSession else false - member __.MoveCaretToClosingPoint() = + member _.MoveCaretToClosingPoint() = let closingSnapshotPoint = closingPoint.GetPoint(subjectBuffer.CurrentSnapshot) // find the position just after the closing brace in the view's text buffer @@ -217,7 +217,7 @@ type BraceCompletionSession undo.Complete() this.EndSession() - member __.PostBackspace() = () + member _.PostBackspace() = () member this.PreOverType handledCommand = handledCommand <- false @@ -259,7 +259,7 @@ type BraceCompletionSession undo.Complete() | _ -> () - member __.PostOverType() = () + member _.PostOverType() = () member this.PreTab handledCommand = handledCommand <- false @@ -274,7 +274,7 @@ type BraceCompletionSession editorOperations.AddAfterTextBufferChangePrimitive() undo.Complete() - member __.PreReturn handledCommand = + member _.PreReturn handledCommand = handledCommand <- false member this.PostReturn() = @@ -286,26 +286,26 @@ type BraceCompletionSession session.AfterReturn(this, CancellationToken.None) | _ -> () - member __.Finish() = () + member _.Finish() = () - member __.PostTab() = () + member _.PostTab() = () - member __.PreDelete handledCommand = + member _.PreDelete handledCommand = handledCommand <- false - member __.PostDelete() = () + member _.PostDelete() = () - member __.OpeningBrace = openingBrace + member _.OpeningBrace = openingBrace - member __.ClosingBrace = closingBrace + member _.ClosingBrace = closingBrace - member __.OpeningPoint = openingPoint + member _.OpeningPoint = openingPoint - member __.ClosingPoint = closingPoint + member _.ClosingPoint = closingPoint - member __.SubjectBuffer = subjectBuffer + member _.SubjectBuffer = subjectBuffer - member __.TextView = textView + member _.TextView = textView module Parenthesis = @@ -372,50 +372,50 @@ type ParenthesisCompletionSession() = interface IEditorBraceCompletionSession with - member __.AfterReturn(_session, _cancellationToken) = + member _.AfterReturn(_session, _cancellationToken) = () - member __.AfterStart(_session, _cancellationToken) = + member _.AfterStart(_session, _cancellationToken) = () - member __.AllowOverType(_session, _cancellationToken) = + member _.AllowOverType(_session, _cancellationToken) = true - member __.CheckOpeningPoint(_session, _cancellationToken) = + member _.CheckOpeningPoint(_session, _cancellationToken) = true type DoubleQuoteCompletionSession() = interface IEditorBraceCompletionSession with - member __.AfterReturn(_session, _cancellationToken) = + member _.AfterReturn(_session, _cancellationToken) = () - member __.AfterStart(_session, _cancellationToken) = + member _.AfterStart(_session, _cancellationToken) = () - member __.AllowOverType(_session, _cancellationToken) = + member _.AllowOverType(_session, _cancellationToken) = true - member __.CheckOpeningPoint(_session, _cancellationToken) = + member _.CheckOpeningPoint(_session, _cancellationToken) = true type VerticalBarCompletionSession() = interface IEditorBraceCompletionSession with - member __.AfterReturn(_session, _cancellationToken) = + member _.AfterReturn(_session, _cancellationToken) = () - member __.AfterStart(_session, _cancellationToken) = + member _.AfterStart(_session, _cancellationToken) = () - member __.AllowOverType(_session, _cancellationToken) = + member _.AllowOverType(_session, _cancellationToken) = true (* This is for [| |] and {| |} , since the implementation deals with chars only. We have to test if there is a { or [ before the cursor position and insert the closing '|'. *) - member __.CheckOpeningPoint(session, _cancellationToken) = + member _.CheckOpeningPoint(session, _cancellationToken) = tryInsertAdditionalBracePair session CurlyBrackets.OpenCharacter CurlyBrackets.CloseCharacter || tryInsertAdditionalBracePair session SquareBrackets.OpenCharacter SquareBrackets.CloseCharacter @@ -423,18 +423,18 @@ type AngleBracketCompletionSession() = interface IEditorBraceCompletionSession with - member __.AfterReturn(_session, _cancellationToken) = + member _.AfterReturn(_session, _cancellationToken) = () - member __.AfterStart(_session, _cancellationToken) = + member _.AfterStart(_session, _cancellationToken) = () - member __.AllowOverType(_session, _cancellationToken) = + member _.AllowOverType(_session, _cancellationToken) = true (* This is for attributes [< >] , since the implementation deals with chars only. We have to test if there is a [ before the cursor position and insert the closing '>'. *) - member __.CheckOpeningPoint(session, _cancellationToken) = + member _.CheckOpeningPoint(session, _cancellationToken) = tryInsertAdditionalBracePair session SquareBrackets.OpenCharacter SquareBrackets.CloseCharacter (* For multi-line comments, test if it is between "()" *) @@ -442,49 +442,69 @@ type AsteriskCompletionSession() = interface IEditorBraceCompletionSession with - member __.AfterReturn(_session, _cancellationToken) = + member _.AfterReturn(_session, _cancellationToken) = () - member __.AfterStart(_session, _cancellationToken) = + member _.AfterStart(_session, _cancellationToken) = () - member __.AllowOverType(_session, _cancellationToken) = + member _.AllowOverType(_session, _cancellationToken) = true (* This is for attributes [< >] , since the implementation deals with chars only. We have to test if there is a [ before the cursor position and insert the closing '>'. *) - member __.CheckOpeningPoint(session, _cancellationToken) = + member _.CheckOpeningPoint(session, _cancellationToken) = tryInsertAdditionalBracePair session Parenthesis.OpenCharacter Parenthesis.CloseCharacter [, FSharpConstants.FSharpLanguageName)>] type EditorBraceCompletionSessionFactory() = - member __.IsSupportedOpeningBrace openingBrace = + let spanIsNotCommentOrString (span: ClassifiedSpan) = + match span.ClassificationType with + | ClassificationTypeNames.Comment + | ClassificationTypeNames.StringLiteral -> false + | _ -> true + + member _.IsSupportedOpeningBrace openingBrace = match openingBrace with | Parenthesis.OpenCharacter | CurlyBrackets.OpenCharacter | SquareBrackets.OpenCharacter | DoubleQuote.OpenCharacter | VerticalBar.OpenCharacter | AngleBrackets.OpenCharacter | Asterisk.OpenCharacter -> true | _ -> false - member __.CheckCodeContext(document: Document, position: int, _openingBrace, cancellationToken) = - // We need to know if we are inside a F# comment. If we are, then don't do automatic completion. + member _.CheckCodeContext(document: Document, position: int, _openingBrace:char, cancellationToken) = + // We need to know if we are inside a F# string or comment. If we are, then don't do automatic completion. let sourceCodeTask = document.GetTextAsync(cancellationToken) sourceCodeTask.Wait(cancellationToken) let sourceCode = sourceCodeTask.Result position = 0 - || let colorizationData = Tokenizer.getClassifiedSpans(document.Id, sourceCode, TextSpan(position - 1, 1), Some (document.FilePath), [ ], cancellationToken) - in colorizationData.Count = 0 - || colorizationData.Exists(fun classifiedSpan -> - classifiedSpan.TextSpan.IntersectsWith position && - ( - match classifiedSpan.ClassificationType with - | ClassificationTypeNames.Comment - | ClassificationTypeNames.StringLiteral -> false - | _ -> true // anything else is a valid classification type - )) - - member __.CreateEditorSession(_document, _openingPosition, openingBrace, _cancellationToken) = + || (let colorizationData = Tokenizer.getClassifiedSpans(document.Id, sourceCode, TextSpan(position - 1, 1), Some (document.FilePath), [ ], cancellationToken) + colorizationData.Count = 0 + || + colorizationData.Exists(fun classifiedSpan -> + classifiedSpan.TextSpan.IntersectsWith position && + spanIsNotCommentOrString classifiedSpan)) + + // This would be the case where '{' has been pressed in a string and the next position + // is known not to be a string. This corresponds to the end of an interpolated string part. + // + // However, Roslyn doesn't activate BraceCompletionSessionProvider for string text at all (and at the time '{ + // is pressed the text is classified as a string). So this code doesn't get called at all and so + // no brace completion is available inside interpolated strings. + // + // || (openingBrace = '{' && + // colorizationData.Exists(fun classifiedSpan -> + // classifiedSpan.TextSpan.IntersectsWith (position-1) && + // spanIsString classifiedSpan) && + // let colorizationData2 = Tokenizer.getClassifiedSpans(document.Id, sourceCode, TextSpan(position, 1), Some (document.FilePath), [ ], cancellationToken) + // (colorizationData2.Count = 0 + // || + // colorizationData2.Exists(fun classifiedSpan -> + // classifiedSpan.TextSpan.IntersectsWith position && + // not (spanIsString classifiedSpan))))) + + member _.CreateEditorSession(_document, _openingPosition, openingBrace, _cancellationToken) = match openingBrace with | Parenthesis.OpenCharacter -> ParenthesisCompletionSession() :> IEditorBraceCompletionSession | CurlyBrackets.OpenCharacter -> ParenthesisCompletionSession() :> IEditorBraceCompletionSession @@ -521,7 +541,7 @@ type BraceCompletionSessionProvider interface IBraceCompletionSessionProvider with - member __.TryCreateSession(textView, openingPoint, openingBrace, closingBrace, session) = + member _.TryCreateSession(textView, openingPoint, openingBrace, closingBrace, session) = session <- maybe { let! document = openingPoint.Snapshot.GetOpenDocumentInCurrentContextWithChanges() |> Option.ofObj diff --git a/vsintegration/src/FSharp.Editor/Build/SetGlobalPropertiesForSdkProjects.fs b/vsintegration/src/FSharp.Editor/Build/SetGlobalPropertiesForSdkProjects.fs index dde8fbc04bc..6aa643def1d 100644 --- a/vsintegration/src/FSharp.Editor/Build/SetGlobalPropertiesForSdkProjects.fs +++ b/vsintegration/src/FSharp.Editor/Build/SetGlobalPropertiesForSdkProjects.fs @@ -22,6 +22,6 @@ type internal SetGlobalPropertiesForSdkProjects ) = inherit StaticGlobalPropertiesProviderBase(projectService.Services) - override __.GetGlobalPropertiesAsync(_cancellationToken: CancellationToken): Task> = - let properties = Empty.PropertiesMap.Add("FSharpCompilerPath", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) + override _.GetGlobalPropertiesAsync(_cancellationToken: CancellationToken): Task> = + let properties = Empty.PropertiesMap.Add("FSharpCompilerPath", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Tools")) Task.FromResult>(properties) diff --git a/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs b/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs index 749c3ceed7a..c3dfc687224 100644 --- a/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs +++ b/vsintegration/src/FSharp.Editor/Classification/ClassificationDefinitions.fs @@ -17,40 +17,57 @@ open Microsoft.VisualStudio.Text.Classification open Microsoft.VisualStudio.Utilities open Microsoft.CodeAnalysis.Classification -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices [] module internal FSharpClassificationTypes = let [] Function = "FSharp.Function" let [] MutableVar = "FSharp.MutableVar" + let [] DisposableType = "FSharp.DisposableType" let [] Printf = "FSharp.Printf" - let [] ReferenceType = ClassificationTypeNames.ClassName - let [] Module = ClassificationTypeNames.ModuleName - let [] ValueType = ClassificationTypeNames.StructName - let [] Keyword = ClassificationTypeNames.Keyword - let [] Enum = ClassificationTypeNames.EnumName - let [] Property = "FSharp.Property" - let [] Interface = ClassificationTypeNames.InterfaceName - let [] TypeArgument = ClassificationTypeNames.TypeParameterName - let [] Operator = ClassificationTypeNames.Operator - let [] Disposable = "FSharp.Disposable" + let [] DisposableLocalValue = "FSharp.DisposableLocalValue" + let [] DisposableTopLevelValue = "FSharp.DisposableTopLevelValue" let getClassificationTypeName = function - | SemanticClassificationType.ReferenceType -> ReferenceType - | SemanticClassificationType.Module -> Module - | SemanticClassificationType.ValueType -> ValueType - | SemanticClassificationType.Function -> Function + | SemanticClassificationType.MutableRecordField | SemanticClassificationType.MutableVar -> MutableVar + | SemanticClassificationType.DisposableType -> DisposableType + | SemanticClassificationType.Namespace -> ClassificationTypeNames.NamespaceName | SemanticClassificationType.Printf -> Printf + | SemanticClassificationType.Exception + | SemanticClassificationType.Module + | SemanticClassificationType.Type + | SemanticClassificationType.TypeDef + | SemanticClassificationType.ConstructorForReferenceType + | SemanticClassificationType.ReferenceType -> ClassificationTypeNames.ClassName + | SemanticClassificationType.ConstructorForValueType + | SemanticClassificationType.ValueType -> ClassificationTypeNames.StructName | SemanticClassificationType.ComputationExpression - | SemanticClassificationType.IntrinsicFunction -> Keyword + | SemanticClassificationType.IntrinsicFunction -> ClassificationTypeNames.Keyword | SemanticClassificationType.UnionCase - | SemanticClassificationType.Enumeration -> Enum - | SemanticClassificationType.Property -> Property - | SemanticClassificationType.Interface -> Interface - | SemanticClassificationType.TypeArgument -> TypeArgument - | SemanticClassificationType.Operator -> Operator - | SemanticClassificationType.Disposable -> Disposable + | SemanticClassificationType.Enumeration -> ClassificationTypeNames.EnumName + | SemanticClassificationType.Field + | SemanticClassificationType.UnionCaseField -> ClassificationTypeNames.FieldName + | SemanticClassificationType.Interface -> ClassificationTypeNames.InterfaceName + | SemanticClassificationType.TypeArgument -> ClassificationTypeNames.TypeParameterName + | SemanticClassificationType.Operator -> ClassificationTypeNames.Operator + | SemanticClassificationType.Function -> Function + | SemanticClassificationType.Method -> ClassificationTypeNames.MethodName + | SemanticClassificationType.ExtensionMethod -> ClassificationTypeNames.ExtensionMethodName + | SemanticClassificationType.Literal -> ClassificationTypeNames.ConstantName + | SemanticClassificationType.Property + | SemanticClassificationType.RecordFieldAsFunction + | SemanticClassificationType.RecordField -> ClassificationTypeNames.PropertyName // TODO - maybe pick something that isn't white by default like Property? + | SemanticClassificationType.NamedArgument -> ClassificationTypeNames.LabelName + | SemanticClassificationType.Event -> ClassificationTypeNames.EventName + | SemanticClassificationType.Delegate -> ClassificationTypeNames.DelegateName + | SemanticClassificationType.DisposableTopLevelValue -> DisposableTopLevelValue + | SemanticClassificationType.Value -> ClassificationTypeNames.Identifier + | SemanticClassificationType.DisposableLocalValue -> DisposableLocalValue + | SemanticClassificationType.LocalValue -> ClassificationTypeNames.LocalName + | SemanticClassificationType.Plaintext -> ClassificationTypeNames.Text + | _ -> failwith "Compiler Bug: Unknown classification type" module internal ClassificationDefinitions = @@ -73,74 +90,101 @@ module internal ClassificationDefinitions = let themeService = serviceProvider.GetService(typeof) :?> IVsColorThemeService themeService.CurrentTheme.ThemeId - let colorData = // name, (light, dark) - [ FSharpClassificationTypes.Function, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy)) - FSharpClassificationTypes.MutableVar, (Color.FromRgb(160uy, 128uy, 0uy), Color.FromRgb(255uy, 210uy, 28uy)) - FSharpClassificationTypes.Printf, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy)) - FSharpClassificationTypes.Property, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy)) - FSharpClassificationTypes.Disposable, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy)) ] - + let customColorData = + [ + {| ClassificationName = FSharpClassificationTypes.MutableVar + LightThemeColor = Color.FromRgb(160uy, 128uy, 0uy) + DarkThemeColor = Color.FromRgb(255uy, 210uy, 28uy) |} + {| ClassificationName = FSharpClassificationTypes.DisposableLocalValue + LightThemeColor = Color.FromRgb(31uy, 55uy, 127uy) + DarkThemeColor = Color.FromRgb(156uy, 220uy, 254uy) |} + {| ClassificationName = FSharpClassificationTypes.DisposableTopLevelValue + LightThemeColor = Colors.Black + DarkThemeColor = Color.FromRgb(220uy, 220uy, 220uy) |} + {| ClassificationName = FSharpClassificationTypes.DisposableType + LightThemeColor = Color.FromRgb(43uy, 145uy, 175uy) + DarkThemeColor = Color.FromRgb(78uy, 220uy, 176uy) |} + {| ClassificationName = FSharpClassificationTypes.Function + LightThemeColor = Color.FromRgb(116uy, 83uy, 31uy) + DarkThemeColor = Color.FromRgb(220uy, 220uy, 170uy) |} + {| ClassificationName = FSharpClassificationTypes.Printf + LightThemeColor = Color.FromRgb(43uy, 145uy, 175uy) + DarkThemeColor = Color.FromRgb(78uy, 220uy, 176uy) |} + ] let setColors _ = let fontAndColorStorage = serviceProvider.GetService(typeof) :?> IVsFontAndColorStorage let fontAndColorCacheManager = serviceProvider.GetService(typeof) :?> IVsFontAndColorCacheManager - fontAndColorCacheManager.CheckCache( ref DefGuidList.guidTextEditorFontCategory) |> ignore + fontAndColorCacheManager.CheckCache(ref DefGuidList.guidTextEditorFontCategory) |> ignore fontAndColorStorage.OpenCategory(ref DefGuidList.guidTextEditorFontCategory, uint32 __FCSTORAGEFLAGS.FCSF_READONLY) |> ignore let formatMap = classificationformatMapService.GetClassificationFormatMap(category = "text") try formatMap.BeginBatchUpdate() - for ctype, (light, dark) in colorData do + for item in customColorData do // we don't touch the changes made by the user - if fontAndColorStorage.GetItem(ctype, Array.zeroCreate 1) <> VSConstants.S_OK then - let ict = classificationTypeRegistry.GetClassificationType(ctype) + if fontAndColorStorage.GetItem(item.ClassificationName, Array.zeroCreate 1) <> VSConstants.S_OK then + let ict = classificationTypeRegistry.GetClassificationType(item.ClassificationName) let oldProps = formatMap.GetTextProperties(ict) - let newProps = match getCurrentThemeId() with - | LightTheme -> oldProps.SetForeground light - | DarkTheme -> oldProps.SetForeground dark - | UnknownTheme -> oldProps + let newProps = + match getCurrentThemeId() with + | LightTheme -> oldProps.SetForeground item.LightThemeColor + | DarkTheme -> oldProps.SetForeground item.DarkThemeColor + | UnknownTheme -> oldProps formatMap.SetTextProperties(ict, newProps) fontAndColorStorage.CloseCategory() |> ignore finally formatMap.EndBatchUpdate() let handler = ThemeChangedEventHandler setColors + do VSColorTheme.add_ThemeChanged handler - interface IDisposable with member __.Dispose() = VSColorTheme.remove_ThemeChanged handler - member __.GetColor(ctype) = - let light, dark = colorData |> Map.ofList |> Map.find ctype - match getCurrentThemeId() with - | LightTheme -> Nullable light - | DarkTheme -> Nullable dark - | UnknownTheme -> Nullable() + member _.GetColor(ctype) = + match customColorData |> List.tryFind (fun item -> item.ClassificationName = ctype) with + | Some item -> + let light, dark = item.LightThemeColor, item.DarkThemeColor + match getCurrentThemeId() with + | LightTheme -> Nullable light + | DarkTheme -> Nullable dark + | UnknownTheme -> Nullable() + | None -> + Nullable() + + interface ISetThemeColors with + member _.SetColors() = setColors() + + interface IDisposable with + member _.Dispose() = VSColorTheme.remove_ThemeChanged handler + + [] + let FSharpMutableVarClassificationType : ClassificationTypeDefinition = null - interface ISetThemeColors with member this.SetColors() = setColors() + [] + let FSharpDisposableClassificationType : ClassificationTypeDefinition = null + + [] + let FSharpDisposableLocalValueClassificationType : ClassificationTypeDefinition = null + [] + let FSharpDisposableTopLevelValueClassificationType : ClassificationTypeDefinition = null [] let FSharpFunctionClassificationType : ClassificationTypeDefinition = null - [] - let FSharpMutableVarClassificationType : ClassificationTypeDefinition = null - [] let FSharpPrintfClassificationType : ClassificationTypeDefinition = null - [] - let FSharpPropertyClassificationType : ClassificationTypeDefinition = null - - [] - let FSharpDisposableClassificationType : ClassificationTypeDefinition = null - [)>] [] [] [] [] - type internal FSharpFunctionTypeFormat() as self = + type internal FSharpFunctionTypeFormat [](theme: ThemeColors) as self = inherit ClassificationFormatDefinition() - do self.DisplayName <- SR.FSharpFunctionsOrMethodsClassificationType() + do + self.DisplayName <- SR.FSharpFunctionsClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Function [)>] [] @@ -150,8 +194,9 @@ module internal ClassificationDefinitions = type internal FSharpMutableVarTypeFormat [](theme: ThemeColors) as self = inherit ClassificationFormatDefinition() - do self.DisplayName <- SR.FSharpMutableVarsClassificationType() - self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.MutableVar + do + self.DisplayName <- SR.FSharpMutableVarsClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.MutableVar [)>] [] @@ -160,27 +205,43 @@ module internal ClassificationDefinitions = [] type internal FSharpPrintfTypeFormat [](theme: ThemeColors) as self = inherit ClassificationFormatDefinition() + + do + self.DisplayName <- SR.FSharpPrintfFormatClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Printf - do self.DisplayName <- SR.FSharpPrintfFormatClassificationType() - self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Printf + [)>] + [] + [] + [] + [] + type internal FSharpDisposableFormat [](theme: ThemeColors) as self = + inherit ClassificationFormatDefinition() + + do + self.DisplayName <- SR.FSharpDisposableTypesClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.DisposableType [)>] - [] - [] + [] + [] [] [] - type internal FSharpPropertyFormat() as self = + type internal FSharpDisposableLocalValueFormat [](theme: ThemeColors) as self = inherit ClassificationFormatDefinition() - do self.DisplayName <- SR.FSharpPropertiesClassificationType() + do + self.DisplayName <- SR.FSharpDisposableLocalValuesClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.DisposableLocalValue [)>] - [] - [] + [] + [] [] [] - type internal FSharpDisposableFormat [](theme: ThemeColors) as self = + type internal FSharpDisposableTopLevelValueFormat [](theme: ThemeColors) as self = inherit ClassificationFormatDefinition() - do self.DisplayName <- SR.FSharpDisposablesClassificationType() - self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Disposable \ No newline at end of file + do + self.DisplayName <- SR.FSharpDisposableTopLevelValuesClassificationType() + self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.DisposableTopLevelValue \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs index d950a0abbf5..bb16634ff28 100644 --- a/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs +++ b/vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs @@ -5,8 +5,10 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System open System.Composition open System.Collections.Generic +open System.Collections.Immutable open System.Diagnostics open System.Threading +open System.Runtime.Caching open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Classification @@ -15,59 +17,170 @@ open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Classification +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Tokenization + // IEditorClassificationService is marked as Obsolete, but is still supported. The replacement (IClassificationService) // is internal to Microsoft.CodeAnalysis.Workspaces which we don't have internals visible to. Rather than add yet another // IVT, we'll maintain the status quo. #nowarn "44" -open FSharp.Compiler.SourceCodeServices +#nowarn "57" + +type SemanticClassificationData = SemanticClassificationView +type SemanticClassificationLookup = IReadOnlyDictionary> + +[] +type DocumentCache<'Value when 'Value : not struct>() = + /// Anything under two seconds, the caching stops working, meaning it won't actually cache the item. + /// Two seconds is just enough to keep the data around long enough to handle a flood of a requests asking for the same data + /// in a short period of time. + [] + let slidingExpirationSeconds = 2. + let cache = new MemoryCache("fsharp-cache") + let policy = CacheItemPolicy(SlidingExpiration = TimeSpan.FromSeconds slidingExpirationSeconds) + + member _.TryGetValueAsync(doc: Document) = async { + let! ct = Async.CancellationToken + let! currentVersion = doc.GetTextVersionAsync ct |> Async.AwaitTask + + match cache.Get(doc.Id.ToString()) with + | null -> return ValueNone + | :? (VersionStamp * 'Value) as value -> + if fst value = currentVersion then + return ValueSome(snd value) + else + return ValueNone + | _ -> + return ValueNone } + + member _.SetAsync(doc: Document, value: 'Value) = async { + let! ct = Async.CancellationToken + let! currentVersion = doc.GetTextVersionAsync ct |> Async.AwaitTask + cache.Set(doc.Id.ToString(), (currentVersion, value), policy) } + + interface IDisposable with + + member _.Dispose() = cache.Dispose() [)>] type internal FSharpClassificationService [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = - static let userOpName = "SemanticColorization" + + static let getLexicalClassifications(filePath: string, defines, text: SourceText, textSpan: TextSpan, ct) = + let text = text.GetSubText(textSpan) + let result = ImmutableArray.CreateBuilder() + let tokenCallback = + fun (tok: FSharpToken) -> + let spanKind = + if tok.IsKeyword then + ClassificationTypeNames.Keyword + elif tok.IsNumericLiteral then + ClassificationTypeNames.NumericLiteral + elif tok.IsCommentTrivia then + ClassificationTypeNames.Comment + elif tok.IsStringLiteral then + ClassificationTypeNames.StringLiteral + else + ClassificationTypeNames.Text + match RoslynHelpers.TryFSharpRangeToTextSpan(text, tok.Range) with + | Some span -> result.Add(ClassifiedSpan(TextSpan(textSpan.Start + span.Start, span.Length), spanKind)) + | _ -> () + + let flags = FSharpLexerFlags.Default &&& ~~~FSharpLexerFlags.Compiling &&& ~~~FSharpLexerFlags.UseLexFilter + FSharpLexer.Tokenize(text.ToFSharpSourceText(), tokenCallback, filePath = filePath, conditionalCompilationDefines = defines, flags = flags, ct = ct) + + result.ToImmutable() + + static let addSemanticClassification sourceText (targetSpan: TextSpan) (items: seq) (outputResult: List) = + for item in items do + match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, item.Range) with + | None -> () + | Some span -> + let span = + match item.Type with + | SemanticClassificationType.Printf -> span + | _ -> Tokenizer.fixupSpan(sourceText, span) + if targetSpan.Contains span then + outputResult.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(item.Type))) + + static let addSemanticClassificationByLookup sourceText (targetSpan: TextSpan) (lookup: SemanticClassificationLookup) (outputResult: List) = + let r = RoslynHelpers.TextSpanToFSharpRange("", targetSpan, sourceText) + for i = r.StartLine to r.EndLine do + match lookup.TryGetValue i with + | true, items -> addSemanticClassification sourceText targetSpan items outputResult + | _ -> () + + static let toSemanticClassificationLookup (d: SemanticClassificationData) = + let lookup = System.Collections.Generic.Dictionary>() + let f (dataItem: SemanticClassificationItem) = + let items = + match lookup.TryGetValue dataItem.Range.StartLine with + | true, items -> items + | _ -> + let items = ResizeArray() + lookup.[dataItem.Range.StartLine] <- items + items + + items.Add dataItem + + d.ForEach(f) + + System.Collections.ObjectModel.ReadOnlyDictionary lookup :> IReadOnlyDictionary<_, _> + + let semanticClassificationCache = new DocumentCache() interface IFSharpClassificationService with // Do not perform classification if we don't have project options (#defines matter) - member __.AddLexicalClassifications(_: SourceText, _: TextSpan, _: List, _: CancellationToken) = () + member _.AddLexicalClassifications(_: SourceText, _: TextSpan, _: List, _: CancellationToken) = () - member __.AddSyntacticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = + member _.AddSyntacticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = async { use _logBlock = Logger.LogBlock(LogEditorFunctionId.Classification_Syntactic) - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) - let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - result.AddRange(Tokenizer.getClassifiedSpans(document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken)) - } |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken + let defines = document.GetFSharpQuickDefines() + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask - member __.AddSemanticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = - asyncMaybe { + // For closed documents, only get classification for the text within the span. + // This may be inaccurate for multi-line tokens such as string literals, but this is ok for now + // as it's better than having to tokenize a big part of a file which in return will allocate a lot and hurt find all references performance. + if not (document.Project.Solution.Workspace.IsDocumentOpen document.Id) then + result.AddRange(getLexicalClassifications(document.FilePath, defines, sourceText, textSpan, cancellationToken)) + else + result.AddRange(Tokenizer.getClassifiedSpans(document.Id, sourceText, textSpan, Some(document.FilePath), defines, cancellationToken)) + } + |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken + + member this.AddSemanticClassificationsAsync(document: Document, textSpan: TextSpan, result: List, cancellationToken: CancellationToken) = + async { use _logBlock = Logger.LogBlock(LogEditorFunctionId.Classification_Semantic) - let! _, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) - let! sourceText = document.GetTextAsync(cancellationToken) - let! _, _, checkResults = checkerProvider.Checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, allowStaleResults = false, userOpName=userOpName) - // it's crucial to not return duplicated or overlapping `ClassifiedSpan`s because Find Usages service crashes. - let targetRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, textSpan, sourceText) - let classificationData = checkResults.GetSemanticClassification (Some targetRange) |> Array.distinctBy fst - - for (range, classificationType) in classificationData do - match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with - | None -> () - | Some span -> - let span = - match classificationType with - | SemanticClassificationType.Printf -> span - | _ -> Tokenizer.fixupSpan(sourceText, span) - result.Add(ClassifiedSpan(span, FSharpClassificationTypes.getClassificationTypeName(classificationType))) + let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask + + // If we are trying to get semantic classification for a document that is not open, get the results from the background and cache it. + // We do this for find all references when it is populating results. + // We cache it temporarily so we do not have to continously call into the checker and perform a background operation. + if not (document.Project.Solution.Workspace.IsDocumentOpen document.Id) then + match! semanticClassificationCache.TryGetValueAsync document with + | ValueSome classificationDataLookup -> + addSemanticClassificationByLookup sourceText textSpan classificationDataLookup result + | _ -> + let! classificationData = document.GetFSharpSemanticClassificationAsync(nameof(FSharpClassificationService)) + let classificationDataLookup = toSemanticClassificationLookup classificationData + do! semanticClassificationCache.SetAsync(document, classificationDataLookup) + addSemanticClassificationByLookup sourceText textSpan classificationDataLookup result + else + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(IFSharpClassificationService)) + let targetRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, textSpan, sourceText) + let classificationData = checkResults.GetSemanticClassification (Some targetRange) + addSemanticClassification sourceText textSpan classificationData result } |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask cancellationToken // Do not perform classification if we don't have project options (#defines matter) - member __.AdjustStaleClassification(_: SourceText, classifiedSpan: ClassifiedSpan) : ClassifiedSpan = classifiedSpan + member _.AdjustStaleClassification(_: SourceText, classifiedSpan: ClassifiedSpan) : ClassifiedSpan = classifiedSpan diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddInstanceMemberParameter.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddInstanceMemberParameter.fs new file mode 100644 index 00000000000..d0845021ce0 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddInstanceMemberParameter.fs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpAddInstanceMemberParameterCodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0673"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = SR.AddMissingInstanceMemberParameter() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(context.Span.Start, 0), "x.") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddMissingEqualsToTypeDefinition.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingEqualsToTypeDefinition.fs new file mode 100644 index 00000000000..5994ff7cae9 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingEqualsToTypeDefinition.fs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition +open System.Threading.Tasks + +open Microsoft.VisualStudio.FSharp.Editor.Logging + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpAddMissingEqualsToTypeDefinitionCodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS3360"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + + let mutable pos = context.Span.Start - 1 + + // This won't ever actually happen, but eh why not + do! Option.guard (pos > 0) + + let mutable ch = sourceText.[pos] + while pos > 0 && Char.IsWhiteSpace(ch) do + pos <- pos - 1 + ch <- sourceText.[pos] + + let title = SR.AddMissingEqualsToTypeDefinition() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + // 'pos + 1' is here because 'pos' is now the position of the first non-whitespace character. + // Using just 'pos' will creat uncompilable code. + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(pos + 1, 0), " =") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddMissingFunKeyword.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingFunKeyword.fs new file mode 100644 index 00000000000..14149d507f1 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingFunKeyword.fs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis + +[] +type internal FSharpAddMissingFunKeywordCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0010"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context = + asyncMaybe { + let document = context.Document + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let textOfError = sourceText.GetSubText(context.Span).ToString() + + // Only trigger when failing to parse `->`, which arises when `fun` is missing + do! Option.guard (textOfError = "->") + + let! defines = document.GetFSharpCompilationDefinesAsync(nameof(FSharpAddMissingFunKeywordCodeFixProvider)) |> liftAsync + + let adjustedPosition = + let rec loop ch pos = + if not (Char.IsWhiteSpace(ch)) then + pos + else + loop sourceText.[pos] (pos - 1) + + loop sourceText.[context.Span.Start - 1] context.Span.Start + + let! intendedArgLexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, adjustedPosition, document.FilePath, defines, SymbolLookupKind.Greedy, false, false) + let! intendedArgSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, intendedArgLexerSymbol.Range) + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = SR.AddMissingFunKeyword() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(intendedArgSpan.Start, 0), "fun ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddMissingRecToMutuallyRecFunctions.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingRecToMutuallyRecFunctions.fs new file mode 100644 index 00000000000..55b73b1fee6 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddMissingRecToMutuallyRecFunctions.fs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Collections.Immutable +open System.Composition +open System.Threading + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis + +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.CodeActions + +[] +type internal FSharpAddMissingRecToMutuallyRecFunctionsCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0576"] + + let createCodeFix (context: CodeFixContext, symbolName: string, titleFormat: string, textChange: TextChange, diagnostics: ImmutableArray) = + let title = String.Format(titleFormat, symbolName) + let codeAction = + CodeAction.Create( + title, + (fun (cancellationToken: CancellationToken) -> + async { + let cancellationToken = context.CancellationToken + let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask + return context.Document.WithText(sourceText.WithChanges(textChange)) + } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), + title) + context.RegisterCodeFix(codeAction, diagnostics) + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context = + asyncMaybe { + let! defines = context.Document.GetFSharpCompilationDefinesAsync(nameof(FSharpAddMissingRecToMutuallyRecFunctionsCodeFixProvider)) |> liftAsync + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + + let funcStartPos = + let rec loop ch pos = + if not (Char.IsWhiteSpace(ch)) then + pos + else + loop sourceText.[pos + 1] (pos + 1) + + loop sourceText.[context.Span.End + 1] (context.Span.End + 1) + + let! funcLexerSymbol = Tokenizer.getSymbolAtPosition (context.Document.Id, sourceText, funcStartPos, context.Document.FilePath, defines, SymbolLookupKind.Greedy, false, false) + let! funcNameSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, funcLexerSymbol.Range) + let funcName = sourceText.GetSubText(funcNameSpan).ToString() + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + createCodeFix(context, funcName, SR.MakeOuterBindingRecursive(), TextChange(TextSpan(context.Span.End, 0), " rec"), diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddNewKeywordToDisposableConstructorInvocation.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddNewKeywordToDisposableConstructorInvocation.fs index 0253a220ae7..fc9a46b9029 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/AddNewKeywordToDisposableConstructorInvocation.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddNewKeywordToDisposableConstructorInvocation.fs @@ -3,32 +3,33 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System.Composition -open System.Collections.Immutable -open System.Threading open System.Threading.Tasks open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open Microsoft.CodeAnalysis.CodeActions [] type internal FSharpAddNewKeywordCodeFixProvider() = inherit CodeFixProvider() - override __.FixableDiagnosticIds = ImmutableArray.Create "FS0760" + static let fixableDiagnosticIds = set ["FS0760"] - override this.RegisterCodeFixesAsync context : Task = + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = async { let title = SR.AddNewKeyword() - context.RegisterCodeFix( - CodeAction.Create( + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( title, - (fun (cancellationToken: CancellationToken) -> - async { - let! cancellationToken = Async.CancellationToken - let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask - return context.Document.WithText(sourceText.WithChanges(TextChange(TextSpan(context.Span.Start, 0), "new "))) - } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), - title), context.Diagnostics |> Seq.filter (fun x -> this.FixableDiagnosticIds.Contains x.Id) |> Seq.toImmutableArray) + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(context.Span.Start, 0), "new ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs index 902d32357f0..392773a637a 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs @@ -13,56 +13,44 @@ open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeActions open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text [] type internal FSharpAddOpenCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, assemblyContentProvider: AssemblyContentProvider ) = inherit CodeFixProvider() - static let userOpName = "FSharpAddOpenCodeFixProvider" let fixableDiagnosticIds = ["FS0039"; "FS0043"] - let checker = checkerProvider.Checker let fixUnderscoresInMenuText (text: string) = text.Replace("_", "__") - let qualifySymbolFix (context: CodeFixContext) (fullName, qualifier) = - CodeAction.Create( + let qualifySymbolFix (context: CodeFixContext) (fullName, qualifier) = + CodeFixHelpers.createTextChangeCodeFix( fixUnderscoresInMenuText fullName, - fun (cancellationToken: CancellationToken) -> - async { - let! cancellationToken = Async.CancellationToken - let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask - return context.Document.WithText(sourceText.Replace(context.Span, qualifier)) - } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)) + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, qualifier) |])) let openNamespaceFix (context: CodeFixContext) ctx name ns multipleNames = let displayText = "open " + ns + if multipleNames then " (" + name + ")" else "" - // TODO when fresh Roslyn NuGet packages are published, assign "Namespace" Tag to this CodeAction to show proper glyph. CodeAction.Create( fixUnderscoresInMenuText displayText, (fun (cancellationToken: CancellationToken) -> async { - let! cancellationToken = Async.CancellationToken let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask let changedText, _ = OpenDeclarationHelper.insertOpenDeclaration sourceText ctx ns return context.Document.WithText(changedText) } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), displayText) - let getSuggestions (context: CodeFixContext) (candidates: (Entity * InsertContext) list) : unit = - //Logging.Logging.logInfof "Candidates: %+A" candidates - + let addSuggestionsAsCodeFixes (context: CodeFixContext) (candidates: (InsertionContextEntity * InsertionContext) list) = let openNamespaceFixes = candidates - |> Seq.choose (fun (entity, ctx) -> entity.Namespace |> Option.map (fun ns -> ns, entity.Name, ctx)) + |> Seq.choose (fun (entity, ctx) -> entity.Namespace |> Option.map (fun ns -> ns, entity.FullDisplayName, ctx)) |> Seq.groupBy (fun (ns, _, _) -> ns) |> Seq.map (fun (ns, xs) -> ns, @@ -91,34 +79,34 @@ type internal FSharpAddOpenCodeFixProvider for codeFix in openNamespaceFixes @ qualifiedSymbolFixes do context.RegisterCodeFix(codeFix, context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray) - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { let document = context.Document - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) - let! sourceText = context.Document.GetTextAsync(context.CancellationToken) - let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName) + + let! sourceText = document.GetTextAsync(context.CancellationToken) + let! parseResults, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpAddOpenCodeFixProvider)) |> liftAsync let line = sourceText.Lines.GetLineFromPosition(context.Span.End) let linePos = sourceText.Lines.GetLinePosition(context.Span.End) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions + let! defines = document.GetFSharpCompilationDefinesAsync(nameof(FSharpAddOpenCodeFixProvider)) |> liftAsync let! symbol = - asyncMaybe { - let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, SymbolLookupKind.Greedy, false) - return! checkResults.GetSymbolUseAtLocation(Line.fromZ linePos.Line, lexerSymbol.Ident.idRange.EndColumn, line.ToString(), lexerSymbol.FullIsland, userOpName=userOpName) - } |> liftAsync + maybe { + let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, context.Span.End, document.FilePath, defines, SymbolLookupKind.Greedy, false, false) + return checkResults.GetSymbolUseAtLocation(Line.fromZ linePos.Line, lexerSymbol.Ident.idRange.EndColumn, line.ToString(), lexerSymbol.FullIsland) + } do! Option.guard symbol.IsNone let unresolvedIdentRange = let startLinePos = sourceText.Lines.GetLinePosition context.Span.Start - let startPos = Pos.fromZ startLinePos.Line startLinePos.Character + let startPos = Position.fromZ startLinePos.Line startLinePos.Character let endLinePos = sourceText.Lines.GetLinePosition context.Span.End - let endPos = Pos.fromZ endLinePos.Line endLinePos.Character + let endPos = Position.fromZ endLinePos.Line endLinePos.Character Range.mkRange context.Document.FilePath startPos endPos - let isAttribute = UntypedParseImpl.GetEntityKind(unresolvedIdentRange.Start, parsedInput) = Some EntityKind.Attribute + let isAttribute = ParsedInput.GetEntityKind(unresolvedIdentRange.Start, parseResults.ParseTree) = Some EntityKind.Attribute let entities = assemblyContentProvider.GetAllEntitiesInProjectAndReferencedAssemblies checkResults @@ -134,7 +122,7 @@ type internal FSharpAddOpenCodeFixProvider s.CleanedIdents |> Array.replace (s.CleanedIdents.Length - 1) (lastIdent.Substring(0, lastIdent.Length - 9)) ]) - let longIdent = ParsedInput.getLongIdentAt parsedInput unresolvedIdentRange.End + let longIdent = ParsedInput.GetLongIdentAt parseResults.ParseTree unresolvedIdentRange.End let! maybeUnresolvedIdents = longIdent @@ -146,11 +134,11 @@ type internal FSharpAddOpenCodeFixProvider |> List.toArray) let insertionPoint = - if document.FSharpOptions.CodeFixes.AlwaysPlaceOpensAtTopLevel then OpenStatementInsertionPoint.TopLevel + if document.Project.IsFSharpCodeFixesAlwaysPlaceOpensAtTopLevelEnabled then OpenStatementInsertionPoint.TopLevel else OpenStatementInsertionPoint.Nearest - let createEntity = ParsedInput.tryFindInsertionContext unresolvedIdentRange.StartLine parsedInput maybeUnresolvedIdents insertionPoint - return entities |> Seq.map createEntity |> Seq.concat |> Seq.toList |> getSuggestions context + let createEntity = ParsedInput.TryFindInsertionContext unresolvedIdentRange.StartLine parseResults.ParseTree maybeUnresolvedIdents insertionPoint + return entities |> Seq.map createEntity |> Seq.concat |> Seq.toList |> addSuggestionsAsCodeFixes context } |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddTypeAnnotationToObjectOfIndeterminateType.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddTypeAnnotationToObjectOfIndeterminateType.fs new file mode 100644 index 00000000000..9f5c441cb83 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddTypeAnnotationToObjectOfIndeterminateType.fs @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Symbols +open Microsoft.CodeAnalysis.CodeActions + +[] +type internal FSharpAddTypeAnnotationToObjectOfIndeterminateTypeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0072"; "FS3245"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let document = context.Document + let position = context.Span.Start + + let! sourceText = document.GetTextAsync(context.CancellationToken) + let textLine = sourceText.Lines.GetLineFromPosition position + let textLinePos = sourceText.Lines.GetLinePosition position + let fcsTextLineNumber = Line.fromZ textLinePos.Line + let! lexerSymbol = document.TryFindFSharpLexerSymbolAsync(position, SymbolLookupKind.Greedy, false, false, nameof(FSharpAddTypeAnnotationToObjectOfIndeterminateTypeFixProvider)) + + let! _, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpAddTypeAnnotationToObjectOfIndeterminateTypeFixProvider)) |> liftAsync + let decl = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland, false) + + match decl with + | FindDeclResult.DeclFound declRange when declRange.FileName = document.FilePath -> + let! declSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, declRange) + let declTextLine = sourceText.Lines.GetLineFromPosition declSpan.Start + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(declRange.StartLine, declRange.EndColumn, declTextLine.ToString(), lexerSymbol.FullIsland) + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv -> + let typeString = mfv.FullType.FormatWithConstraints symbolUse.DisplayContext + + let alreadyWrappedInParens = + let rec leftLoop ch pos = + if not (Char.IsWhiteSpace(ch)) then + ch = '(' + else + leftLoop sourceText.[pos - 1] (pos - 1) + + let rec rightLoop ch pos = + if not (Char.IsWhiteSpace(ch)) then + ch = ')' + else + rightLoop sourceText.[pos + 1] (pos + 1) + + let hasLeftParen = leftLoop sourceText.[declSpan.Start - 1] (declSpan.Start - 1) + let hasRightParen = rightLoop sourceText.[declSpan.End] declSpan.End + hasLeftParen && hasRightParen + + let getChangedText (sourceText: SourceText) = + if alreadyWrappedInParens then + sourceText.WithChanges(TextChange(TextSpan(declSpan.End, 0), ": " + typeString)) + else + sourceText.WithChanges(TextChange(TextSpan(declSpan.Start, 0), "(")) + .WithChanges(TextChange(TextSpan(declSpan.End + 1, 0), ": " + typeString + ")")) + + let title = SR.AddTypeAnnotation() + let codeAction = + CodeAction.Create( + title, + (fun (cancellationToken: CancellationToken) -> + async { + let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask + return context.Document.WithText(getChangedText sourceText) + } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), + title) + + context.RegisterCodeFix(codeAction, diagnostics) + |_ -> () + | _ -> () + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ChangePrefixNegationToInfixSubtraction.fs b/vsintegration/src/FSharp.Editor/CodeFix/ChangePrefixNegationToInfixSubtraction.fs new file mode 100644 index 00000000000..793cc92a4b1 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ChangePrefixNegationToInfixSubtraction.fs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpChangePrefixNegationToInfixSubtractionodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0003"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + + let mutable pos = context.Span.End + 1 + + // This won't ever actually happen, but eh why not + do! Option.guard (pos < sourceText.Length) + + let mutable ch = sourceText.[pos] + while pos < sourceText.Length && Char.IsWhiteSpace(ch) do + pos <- pos + 1 + ch <- sourceText.[pos] + + // Bail if this isn't a negation + do! Option.guard (ch = '-') + + let title = SR.ChangePrefixNegationToInfixSubtraction() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(pos, 1), "- ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ChangeRefCellDerefToNotExpression.fs b/vsintegration/src/FSharp.Editor/CodeFix/ChangeRefCellDerefToNotExpression.fs new file mode 100644 index 00000000000..f7f33d4c198 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ChangeRefCellDerefToNotExpression.fs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpChangeRefCellDerefToNotExpressionCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0001"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override this.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let document = context.Document + let! parseResults = document.GetFSharpParseResultsAsync(nameof(FSharpChangeRefCellDerefToNotExpressionCodeFixProvider)) |> liftAsync + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + + let errorRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) + let! derefRange = parseResults.TryRangeOfRefCellDereferenceContainingPos errorRange.Start + let! derefSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, derefRange) + + let title = SR.UseNotForNegation() + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(derefSpan, "not ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ChangeToUpcast.fs b/vsintegration/src/FSharp.Editor/CodeFix/ChangeToUpcast.fs new file mode 100644 index 00000000000..cdc95a9e643 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ChangeToUpcast.fs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpChangeToUpcastCodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS3198"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override this.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let text = sourceText.GetSubText(context.Span).ToString() + + // Only works if it's one or the other + let isDowncastOperator = text.Contains(":?>") + let isDowncastKeyword = text.Contains("downcast") + do! Option.guard ((isDowncastOperator || isDowncastKeyword) && not (isDowncastOperator && isDowncastKeyword)) + + let replacement = + if isDowncastOperator then + text.Replace(":?>", ":>") + else + text.Replace("downcast", "upcast") + + let title = + if isDowncastOperator then + SR.UseUpcastOperator() + else + SR.UseUpcastKeyword() + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, replacement) |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs b/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs index cbd96b860ef..fb311ae60e2 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/CodeFixHelpers.fs @@ -15,7 +15,6 @@ module internal CodeFixHelpers = title, (fun (cancellationToken: CancellationToken) -> async { - let! cancellationToken = Async.CancellationToken let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask let! changesOpt = computeTextChanges() match changesOpt with diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ConvertCSharpLambdaToFSharpLambda.fs b/vsintegration/src/FSharp.Editor/CodeFix/ConvertCSharpLambdaToFSharpLambda.fs new file mode 100644 index 00000000000..824bc52e2a6 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ConvertCSharpLambdaToFSharpLambda.fs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpConvertCSharpLambdaToFSharpLambdaCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0039"; "FS0043"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context = + asyncMaybe { + let! parseResults = context.Document.GetFSharpParseResultsAsync(nameof(FSharpConvertCSharpLambdaToFSharpLambdaCodeFixProvider)) |> liftAsync + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let errorRange = RoslynHelpers.TextSpanToFSharpRange(context.Document.FilePath, context.Span, sourceText) + + let! fullParenRange, lambdaArgRange, lambdaBodyRange = parseResults.TryRangeOfParenEnclosingOpEqualsGreaterUsage errorRange.Start + + let! fullParenSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, fullParenRange) + let! lambdaArgSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, lambdaArgRange) + let! lambdaBodySpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, lambdaBodyRange) + + let replacement = + let argText = sourceText.GetSubText(lambdaArgSpan).ToString() + let bodyText = sourceText.GetSubText(lambdaBodySpan).ToString() + TextChange(fullParenSpan, "fun " + argText + " -> " + bodyText) + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = SR.UseFSharpLambda() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| replacement |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ConvertToAnonymousRecord.fs b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToAnonymousRecord.fs new file mode 100644 index 00000000000..3250e7e33f5 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToAnonymousRecord.fs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes +open Microsoft.CodeAnalysis.CodeActions + +[] +type internal FSharpConvertToAnonymousRecordCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0039"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let document = context.Document + let! parseResults = document.GetFSharpParseResultsAsync(nameof(FSharpConvertToAnonymousRecordCodeFixProvider)) |> liftAsync + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let errorRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) + let! recordRange = parseResults.TryRangeOfRecordExpressionContainingPos errorRange.Start + let! recordSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, recordRange) + + let getChangedText () = + sourceText.WithChanges(TextChange(TextSpan(recordSpan.Start + 1, 0), "|")) + .WithChanges(TextChange(TextSpan(recordSpan.End, 0), "|")) + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = SR.ConvertToAnonymousRecord() + + let codeFix = + CodeAction.Create( + title, + (fun (cancellationToken: CancellationToken) -> + async { + return context.Document.WithText(getChangedText()) + } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), + title) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ConvertToNotEqualsEqualityExpression.fs b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToNotEqualsEqualityExpression.fs new file mode 100644 index 00000000000..debdda8a021 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToNotEqualsEqualityExpression.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpConvertToNotEqualsEqualityExpressionCodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0043"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override this.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let text = sourceText.GetSubText(context.Span).ToString() + + // We're converting '!=' into '<>', a common new user mistake. + // If this is an FS00043 that is anything other than that, bail out + do! Option.guard (text = "!=") + + let title = SR.ConvertToNotEqualsEqualityExpression() + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, "<>") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ConvertToSingleEqualsEqualityExpression.fs b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToSingleEqualsEqualityExpression.fs new file mode 100644 index 00000000000..18e14e6cc05 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/ConvertToSingleEqualsEqualityExpression.fs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpConvertToSingleEqualsEqualityExpressionCodeFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0043"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override this.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let text = sourceText.GetSubText(context.Span).ToString() + + // We're converting '==' into '=', a common new user mistake. + // If this is an FS00043 that is anything other than that, bail out + do! Option.guard (text = "==") + + let title = SR.ConvertToSingleEqualsEqualityExpression() + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, "=") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/FixIndexerAccess.fs b/vsintegration/src/FSharp.Editor/CodeFix/FixIndexerAccess.fs index eb9a49c0fad..b41eb1e94ad 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/FixIndexerAccess.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/FixIndexerAccess.fs @@ -8,16 +8,16 @@ open System.Threading.Tasks open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics [] type internal FSharpFixIndexerAccessCodeFixProvider() = inherit CodeFixProvider() let fixableDiagnosticIds = set ["FS3217"] - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = async { let diagnostics = context.Diagnostics @@ -34,9 +34,8 @@ type internal FSharpFixIndexerAccessCodeFixProvider() = let mutable span = context.Span let notStartOfBracket (span: TextSpan) = - let t = TextSpan(span.Start, span.Length + 1) - let s = sourceText.GetSubText(t).ToString() - s.[s.Length-1] <> '[' + let t = sourceText.GetSubText(TextSpan(span.Start, span.Length + 1)) + t.[t.Length-1] <> '[' // skip all braces and blanks until we find [ while span.End < sourceText.Length && notStartOfBracket span do @@ -48,7 +47,7 @@ type internal FSharpFixIndexerAccessCodeFixProvider() = let codefix = CodeFixHelpers.createTextChangeCodeFix( - CompilerDiagnostics.getErrorMessage AddIndexerDot, + CompilerDiagnostics.GetErrorMessage FSharpDiagnosticKind.AddIndexerDot, context, (fun () -> asyncMaybe.Return [| TextChange(span, replacement.TrimEnd() + ".") |])) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs index 032ae032b66..93d2686c5c9 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs @@ -13,8 +13,13 @@ open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeActions open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization [] type internal InterfaceState = @@ -27,23 +32,19 @@ type internal InterfaceState = type internal FSharpImplementInterfaceCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() let fixableDiagnosticIds = ["FS0366"] - let checker = checkerProvider.Checker - static let userOpName = "ImplementInterfaceCodeFixProvider" - let queryInterfaceState appendBracketAt (pos: pos) (tokens: Tokenizer.SavedTokenInfo[]) (ast: Ast.ParsedInput) = + let queryInterfaceState appendBracketAt (pos: pos) (tokens: Tokenizer.SavedTokenInfo[]) (ast: ParsedInput) = asyncMaybe { let line = pos.Line - 1 - let! iface = InterfaceStubGenerator.tryFindInterfaceDeclaration pos ast + let! iface = InterfaceStubGenerator.TryFindInterfaceDeclaration pos ast let endPosOfWidth = tokens |> Array.tryPick (fun (t: Tokenizer.SavedTokenInfo) -> if t.Tag = FSharpTokenTag.WITH || t.Tag = FSharpTokenTag.OWITH then - Some (Pos.fromZ line (t.RightColumn + 1)) + Some (Position.fromZ line (t.RightColumn + 1)) else None) let appendBracketAt = match iface, appendBracketAt with @@ -56,7 +57,7 @@ type internal FSharpImplementInterfaceCodeFixProvider lineStr.Length - lineStr.TrimStart(' ').Length let inferStartColumn indentSize state (sourceText: SourceText) = - match InterfaceStubGenerator.getMemberNameAndRanges state.InterfaceData with + match InterfaceStubGenerator.GetMemberNameAndRanges state.InterfaceData with | (_, range) :: _ -> let lineStr = sourceText.Lines.[range.StartLine-1].ToString() getLineIdent lineStr @@ -81,7 +82,7 @@ type internal FSharpImplementInterfaceCodeFixProvider let defaultBody = "raise (System.NotImplementedException())" let typeParams = state.InterfaceData.TypeParameters let stub = - let stub = InterfaceStubGenerator.formatInterface + let stub = InterfaceStubGenerator.FormatInterface startColumn indentSize typeParams objectIdentifier defaultBody displayContext implementedMemberSignatures entity verboseMode stub.TrimEnd(Environment.NewLine.ToCharArray()) @@ -101,12 +102,12 @@ type internal FSharpImplementInterfaceCodeFixProvider sourceText.WithChanges(stubChange) let registerSuggestions (context: CodeFixContext, results: FSharpCheckFileResults, state: InterfaceState, displayContext, entity, indentSize) = - if InterfaceStubGenerator.hasNoInterfaceMember entity then + if InterfaceStubGenerator.HasNoInterfaceMember entity then () else - let membersAndRanges = InterfaceStubGenerator.getMemberNameAndRanges state.InterfaceData - let interfaceMembers = InterfaceStubGenerator.getInterfaceMembers entity - let hasTypeCheckError = results.Errors |> Array.exists (fun e -> e.Severity = FSharpErrorSeverity.Error) + let membersAndRanges = InterfaceStubGenerator.GetMemberNameAndRanges state.InterfaceData + let interfaceMembers = InterfaceStubGenerator.GetInterfaceMembers entity + let hasTypeCheckError = results.Diagnostics |> Array.exists (fun e -> e.Severity = FSharpDiagnosticSeverity.Error) // This comparison is a bit expensive if hasTypeCheckError && List.length membersAndRanges <> Seq.length interfaceMembers then let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray @@ -119,9 +120,9 @@ type internal FSharpImplementInterfaceCodeFixProvider let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask let getMemberByLocation(name, range: range) = let lineStr = sourceText.Lines.[range.EndLine-1].ToString() - results.GetSymbolUseAtLocation(range.EndLine, range.EndColumn, lineStr, [name], userOpName=userOpName) + results.GetSymbolUseAtLocation(range.EndLine, range.EndColumn, lineStr, [name]) let! implementedMemberSignatures = - InterfaceStubGenerator.getImplementedMemberSignatures getMemberByLocation displayContext state.InterfaceData + InterfaceStubGenerator.GetImplementedMemberSignatures getMemberByLocation displayContext state.InterfaceData let newSourceText = applyImplementInterface sourceText state displayContext implementedMemberSignatures entity indentSize verboseMode return context.Document.WithText(newSourceText) } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), @@ -133,15 +134,15 @@ type internal FSharpImplementInterfaceCodeFixProvider else () - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(context.Document, context.CancellationToken) + let! parseResults, checkFileResults = context.Document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpImplementInterfaceCodeFixProvider)) |> liftAsync let cancellationToken = context.CancellationToken let! sourceText = context.Document.GetTextAsync(cancellationToken) - let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, userOpName = userOpName) let textLine = sourceText.Lines.GetLineFromPosition context.Span.Start + let! _, _, parsingOptions, _ = context.Document.GetFSharpCompilationOptionsAsync(nameof(FSharpImplementInterfaceCodeFixProvider)) |> liftAsync let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions // Notice that context.Span doesn't return reliable ranges to find tokens at exact positions. // That's why we tokenize the line and try to find the last successive identifier token @@ -160,24 +161,24 @@ type internal FSharpImplementInterfaceCodeFixProvider | _ -> acc let! token = tryFindIdentifierToken None 0 let fixupPosition = textLine.Start + token.RightColumn - let interfacePos = Pos.fromZ textLine.LineNumber token.RightColumn + let interfacePos = Position.fromZ textLine.LineNumber token.RightColumn // We rely on the observation that the lastChar of the context should be '}' if that character is present let appendBracketAt = match sourceText.[context.Span.End-1] with | '}' -> None | _ -> Some context.Span.End - let! interfaceState = queryInterfaceState appendBracketAt interfacePos tokens parsedInput - let! symbol = Tokenizer.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, SymbolLookupKind.Greedy, false) + let! interfaceState = queryInterfaceState appendBracketAt interfacePos tokens parseResults.ParseTree + let! symbol = Tokenizer.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, SymbolLookupKind.Greedy, false, false) let fcsTextLineNumber = textLine.LineNumber + 1 let lineContents = textLine.ToString() let! options = context.Document.GetOptionsAsync(cancellationToken) let tabSize = options.GetOption(FormattingOptions.TabSize, FSharpConstants.FSharpLanguageName) - let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, lineContents, symbol.FullIsland, userOpName=userOpName) + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, lineContents, symbol.FullIsland) let! entity, displayContext = match symbolUse.Symbol with | :? FSharpEntity as entity -> - if InterfaceStubGenerator.isInterface entity then + if InterfaceStubGenerator.IsInterface entity then Some (entity, symbolUse.DisplayContext) else None | _ -> None diff --git a/vsintegration/src/FSharp.Editor/CodeFix/MakeDeclarationMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/MakeDeclarationMutable.fs new file mode 100644 index 00000000000..e93e9f4db13 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/MakeDeclarationMutable.fs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text + +[] +type internal FSharpMakeDeclarationMutableFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0027"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let document = context.Document + do! Option.guard (not(isSignatureFile document.FilePath)) + let position = context.Span.Start + + let! lexerSymbol = document.TryFindFSharpLexerSymbolAsync(position, SymbolLookupKind.Greedy, false, false, nameof(FSharpMakeDeclarationMutableFixProvider)) + let! sourceText = document.GetTextAsync () |> liftTaskAsync + let textLine = sourceText.Lines.GetLineFromPosition position + let textLinePos = sourceText.Lines.GetLinePosition position + let fcsTextLineNumber = Line.fromZ textLinePos.Line + let! parseFileResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpMakeDeclarationMutableFixProvider)) |> liftAsync + let decl = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland, false) + + match decl with + // Only do this for symbols in the same file. That covers almost all cases anyways. + // We really shouldn't encourage making values mutable outside of local scopes anyways. + | FindDeclResult.DeclFound declRange when declRange.FileName = document.FilePath -> + let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, declRange) + + // Bail if it's a parameter, because like, that ain't allowed + do! Option.guard (not (parseFileResults.IsPositionContainedInACurriedParameter declRange.Start)) + + let title = SR.MakeDeclarationMutable() + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(span.Start, 0), "mutable ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + | _ -> + () + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/MakeOuterBindingRecursive.fs b/vsintegration/src/FSharp.Editor/CodeFix/MakeOuterBindingRecursive.fs new file mode 100644 index 00000000000..842de538108 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/MakeOuterBindingRecursive.fs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpMakeOuterBindingRecursiveCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0039"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context = + asyncMaybe { + let! parseResults = context.Document.GetFSharpParseResultsAsync(nameof(FSharpMakeOuterBindingRecursiveCodeFixProvider)) |> liftAsync + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let diagnosticRange = RoslynHelpers.TextSpanToFSharpRange(context.Document.FilePath, context.Span, sourceText) + do! Option.guard (parseResults.IsPosContainedInApplication diagnosticRange.Start) + + let! outerBindingRange = parseResults.TryRangeOfNameOfNearestOuterBindingContainingPos diagnosticRange.Start + let! outerBindingNameSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, outerBindingRange) + + // One last check to verify the names are the same + do! Option.guard (sourceText.GetSubText(outerBindingNameSpan).ContentEquals(sourceText.GetSubText(context.Span))) + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = String.Format(SR.MakeOuterBindingRecursive(), sourceText.GetSubText(outerBindingNameSpan).ToString()) + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(outerBindingNameSpan.Start, 0), "rec ") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/MissingReferenceCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/MissingReferenceCodeFixProvider.fs index 91bfc716b15..9f9ab08d51d 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/MissingReferenceCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/MissingReferenceCodeFixProvider.fs @@ -14,8 +14,8 @@ open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeActions type private ReferenceType = -| AddProjectRef of ProjectReference -| AddMetadataRef of MetadataReference + | AddProjectRef of ProjectReference + | AddMetadataRef of MetadataReference [] type internal MissingReferenceCodeFixProvider() = @@ -46,9 +46,9 @@ type internal MissingReferenceCodeFixProvider() = ), title) - override __.FixableDiagnosticIds = Seq.toImmutableArray [fixableDiagnosticId] + override _.FixableDiagnosticIds = Seq.toImmutableArray [fixableDiagnosticId] - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = async { let solution = context.Document.Project.Solution diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ProposeUppercaseLabel.fs b/vsintegration/src/FSharp.Editor/CodeFix/ProposeUppercaseLabel.fs index 8b46a80b7d9..65ebe4edb33 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ProposeUppercaseLabel.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ProposeUppercaseLabel.fs @@ -6,26 +6,23 @@ open System.Composition open System.Threading.Tasks open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.CodeActions -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics [] type internal FSharpProposeUpperCaseLabelCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() let fixableDiagnosticIds = ["FS0053"] - static let userOpName = "ProposeUpperCaseLabel" - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { let textChanger (originalText: string) = originalText.[0].ToString().ToUpper() + originalText.Substring(1) - let! solutionChanger, originalText = SymbolHelpers.changeAllSymbolReferences(context.Document, context.Span, textChanger, projectInfoManager, checkerProvider.Checker, userOpName) - let title = CompilerDiagnostics.getErrorMessage (ReplaceWithSuggestion <| textChanger originalText) + let! solutionChanger, originalText = SymbolHelpers.changeAllSymbolReferences(context.Document, context.Span, textChanger) + let title = CompilerDiagnostics.GetErrorMessage (FSharpDiagnosticKind.ReplaceWithSuggestion <| textChanger originalText) context.RegisterCodeFix( CodeAction.Create(title, solutionChanger, title), context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RemoveReturnOrYield.fs b/vsintegration/src/FSharp.Editor/CodeFix/RemoveReturnOrYield.fs new file mode 100644 index 00000000000..863a9343e72 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/RemoveReturnOrYield.fs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpRemoveReturnOrYieldCodeFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0748"; "FS0747"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context = + asyncMaybe { + let! parseResults = context.Document.GetFSharpParseResultsAsync(nameof(FSharpRemoveReturnOrYieldCodeFixProvider)) |> liftAsync + + let! sourceText = context.Document.GetTextAsync(context.CancellationToken) + let errorRange = RoslynHelpers.TextSpanToFSharpRange(context.Document.FilePath, context.Span, sourceText) + let! exprRange = parseResults.TryRangeOfExprInYieldOrReturn errorRange.Start + let! exprSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, exprRange) + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let title = + let text = sourceText.GetSubText(context.Span).ToString() + if text.StartsWith("return!") then + SR.RemoveReturnBang() + elif text.StartsWith("return") then + SR.RemoveReturn() + elif text.StartsWith("yield!") then + SR.RemoveYieldBang() + else + SR.RemoveYield() + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, sourceText.GetSubText(exprSpan).ToString()) |])) + + context.RegisterCodeFix(codeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedBinding.fs b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedBinding.fs new file mode 100644 index 00000000000..fe0a4200e47 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedBinding.fs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +[] +type internal FSharpRemoveUnusedBindingCodeFixProvider + [] + ( + ) = + + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS1182"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + // Don't show code fixes for unused values, even if they are compiler-generated. + do! Option.guard context.Document.Project.IsFSharpCodeFixesUnusedDeclarationsEnabled + + let document = context.Document + let! sourceText = document.GetTextAsync(context.CancellationToken) + + let! parseResults = context.Document.GetFSharpParseResultsAsync(nameof(FSharpRemoveUnusedBindingCodeFixProvider)) |> liftAsync + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let symbolRange = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) + let! rangeOfBinding = parseResults.TryRangeOfBindingWithHeadPatternWithPos(symbolRange.Start) + let! spanOfBinding = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, rangeOfBinding) + + let keywordEndColumn = + let rec loop ch pos = + if not (Char.IsWhiteSpace(ch)) then + pos + else + loop sourceText.[pos - 1] (pos - 1) + loop sourceText.[spanOfBinding.Start - 1] (spanOfBinding.Start - 1) + + // This is safe, since we could never have gotten here unless there was a `let` or `use` + let keywordStartColumn = keywordEndColumn - 2 + let fullSpan = TextSpan(keywordStartColumn, spanOfBinding.End - keywordStartColumn) + + let prefixTitle = SR.RemoveUnusedBinding() + let removalCodeFix = + CodeFixHelpers.createTextChangeCodeFix( + prefixTitle, + context, + (fun () -> asyncMaybe.Return [| TextChange(fullSpan, "") |])) + context.RegisterCodeFix(removalCodeFix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs index 8b659aafb32..9bc06368210 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RemoveUnusedOpens.fs @@ -3,57 +3,54 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System.Composition -open System.Threading open System.Threading.Tasks -open Microsoft.CodeAnalysis.Diagnostics open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open Microsoft.CodeAnalysis.CodeActions open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics -open FSharp.Compiler.Range +open FSharp.Compiler.Text [] type internal FSharpRemoveUnusedOpensCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() + let fixableDiagnosticIds = [FSharpIDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId] - - let createCodeFix (title: string, context: CodeFixContext) = - CodeAction.Create( - title, - (fun (cancellationToken: CancellationToken) -> - asyncMaybe { - let document = context.Document - let! sourceText = document.GetTextAsync() - let checker = checkerProvider.Checker - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) - let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker) - let changes = - unusedOpens - |> List.map (fun m -> - let span = sourceText.Lines.[Line.toZ m.StartLine].SpanIncludingLineBreak - TextChange(span, "")) - |> List.toArray - - return document.WithText(sourceText.WithChanges(changes)) - } - |> Async.map (Option.defaultValue context.Document) - |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), - title) - - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - - override __.RegisterCodeFixesAsync context : Task = - async { - let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray - context.RegisterCodeFix(createCodeFix(SR.RemoveUnusedOpens(), context), diagnostics) - } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) - - override __.GetFixAllProvider() = WellKnownFixAllProviders.BatchFixer + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let document = context.Document + let! sourceText = document.GetTextAsync() + let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document) + let changes = + unusedOpens + |> List.map (fun m -> + let span = sourceText.Lines.[Line.toZ m.StartLine].SpanIncludingLineBreak + TextChange(span, "")) + |> List.toArray + + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) + |> Seq.toImmutableArray + + let title = SR.RemoveUnusedOpens() + + let codefix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return changes)) + + context.RegisterCodeFix(codefix, diagnostics) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) + + override _.GetFixAllProvider() = WellKnownFixAllProviders.BatchFixer \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RenameParamToMatchSignature.fs b/vsintegration/src/FSharp.Editor/CodeFix/RenameParamToMatchSignature.fs index 245c1ff1405..2564dd3af4b 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RenameParamToMatchSignature.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RenameParamToMatchSignature.fs @@ -9,26 +9,24 @@ open System.Threading.Tasks open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open FSharp.Compiler.SourceCodeServices open Microsoft.VisualStudio.FSharp.Editor.SymbolHelpers -open FSharp.Compiler.SourceCodeServices.Keywords +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Tokenization.FSharpKeywords [] type internal FSharpRenameParamToMatchSignature [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() - static let userOpName = "RenameParamToMatchSignature" + let fixableDiagnosticIds = ["FS3218"] - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { match context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toList with | [diagnostic] -> @@ -38,23 +36,23 @@ type internal FSharpRenameParamToMatchSignature let diagnostics = ImmutableArray.Create diagnostic let suggestion = parts.Groups.[1].Value - let replacement = QuoteIdentifierIfNeeded suggestion + let replacement = AddBackticksToIdentifierIfNeeded suggestion let computeChanges() = asyncMaybe { let document = context.Document let! cancellationToken = Async.CancellationToken |> liftAsync let! sourceText = document.GetTextAsync(cancellationToken) - let! symbolUses = getSymbolUsesOfSymbolAtLocationInDocument (document, context.Span.Start, projectInfoManager, checkerProvider.Checker, userOpName) + let! symbolUses = getSymbolUsesOfSymbolAtLocationInDocument (document, context.Span.Start) let changes = [| for symbolUse in symbolUses do - match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) with + match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.Range) with | None -> () | Some span -> let textSpan = Tokenizer.fixupSpan(sourceText, span) yield TextChange(textSpan, replacement) |] return changes } - let title = CompilerDiagnostics.getErrorMessage (ReplaceWithSuggestion suggestion) + let title = CompilerDiagnostics.GetErrorMessage (FSharpDiagnosticKind.ReplaceWithSuggestion suggestion) let codefix = CodeFixHelpers.createTextChangeCodeFix(title, context, computeChanges) context.RegisterCodeFix(codefix, diagnostics) | _ -> () diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs index 67379326323..4da45f8b9bc 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs @@ -4,72 +4,70 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System open System.Composition -open System.Threading open System.Threading.Tasks -open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open Microsoft.CodeAnalysis.CodeActions open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax [] type internal FSharpRenameUnusedValueCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = inherit CodeFixProvider() - static let userOpName = "RenameUnusedValueCodeFix" - let fixableDiagnosticIds = ["FS1182"] - let checker = checkerProvider.Checker - - let createCodeFix (context: CodeFixContext, symbolName: string, titleFormat: string, textChange: TextChange) = - let title = String.Format(titleFormat, symbolName) - let codeAction = - CodeAction.Create( - title, - (fun (cancellationToken: CancellationToken) -> - async { - let! cancellationToken = Async.CancellationToken - let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask - return context.Document.WithText(sourceText.WithChanges(textChange)) - } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), - title) - let diagnostics = context.Diagnostics |> Seq.filter (fun x -> fixableDiagnosticIds |> List.contains x.Id) |> Seq.toImmutableArray - context.RegisterCodeFix(codeAction, diagnostics) - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + let fixableDiagnosticIds = set ["FS1182"] - override __.RegisterCodeFixesAsync context : Task = + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { // Don't show code fixes for unused values, even if they are compiler-generated. - do! Option.guard context.Document.FSharpOptions.CodeFixes.UnusedDeclarations + do! Option.guard context.Document.Project.IsFSharpCodeFixesUnusedDeclarationsEnabled let document = context.Document - let! sourceText = document.GetTextAsync() + let! sourceText = document.GetTextAsync(context.CancellationToken) let ident = sourceText.ToString(context.Span) + // Prefixing operators and backticked identifiers does not make sense. - // We have to use the additional check for backtickes because `IsOperatorOrBacktickedName` operates on display names - // where backtickes are replaced with parens. - if not (PrettyNaming.IsOperatorOrBacktickedName ident) && not (ident.StartsWith "``") then - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) - let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName=userOpName) + // We have to use the additional check for backtickes + if PrettyNaming.IsIdentifierName ident then + let! lexerSymbol = document.TryFindFSharpLexerSymbolAsync(context.Span.Start, SymbolLookupKind.Greedy, false, false, nameof(FSharpRenameUnusedValueCodeFixProvider)) let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions - let! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, context.Span.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false) let lineText = (sourceText.Lines.GetLineFromPosition context.Span.Start).ToString() - let! symbolUse = checkResults.GetSymbolUseAtLocation(m.StartLine, m.EndColumn, lineText, lexerSymbol.FullIsland, userOpName=userOpName) + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpRenameUnusedValueCodeFixProvider)) |> liftAsync + let! symbolUse = checkResults.GetSymbolUseAtLocation(m.StartLine, m.EndColumn, lineText, lexerSymbol.FullIsland) let symbolName = symbolUse.Symbol.DisplayName + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as func -> - createCodeFix(context, symbolName, SR.PrefixValueNameWithUnderscore(), TextChange(TextSpan(context.Span.Start, 0), "_")) - if func.IsValue then createCodeFix(context, symbolName, SR.RenameValueToUnderscore(), TextChange(context.Span, "_")) + let prefixTitle = String.Format(SR.PrefixValueNameWithUnderscore(), symbolName) + let prefixCodeFix = + CodeFixHelpers.createTextChangeCodeFix( + prefixTitle, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(context.Span.Start, 0), "_") |])) + context.RegisterCodeFix(prefixCodeFix, diagnostics) + + if func.IsValue then + let replaceTitle = String.Format(SR.RenameValueToUnderscore(), symbolName) + let replaceCodeFix = + CodeFixHelpers.createTextChangeCodeFix( + replaceTitle, + context, + (fun () -> asyncMaybe.Return [| TextChange(context.Span, "_") |])) + context.RegisterCodeFix(replaceCodeFix, diagnostics) | _ -> () } |> Async.Ignore diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs b/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs index 969cfb55a16..3e4a6e1c57a 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs @@ -8,33 +8,30 @@ open System.Threading.Tasks open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization [] type internal FSharpReplaceWithSuggestionCodeFixProvider [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, settings: EditorOptions ) = inherit CodeFixProvider() - static let userOpName = "ReplaceWithSuggestionCodeFix" let fixableDiagnosticIds = set ["FS0039"; "FS1129"; "FS0495"] - let checker = checkerProvider.Checker - override __.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds - override __.RegisterCodeFixesAsync context : Task = + override _.RegisterCodeFixesAsync context : Task = asyncMaybe { do! Option.guard settings.CodeFixes.SuggestNamesForErrors let document = context.Document - let! _, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) - let! parseFileResults, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, userOpName=userOpName) + let! parseFileResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpReplaceWithSuggestionCodeFixProvider)) |> liftAsync // This is all needed to get a declaration list let! sourceText = document.GetTextAsync(context.CancellationToken) @@ -43,9 +40,10 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider let caretLinePos = sourceText.Lines.GetLinePosition(pos) let caretLine = sourceText.Lines.GetLineFromPosition(pos) let fcsCaretLineNumber = Line.fromZ caretLinePos.Line - let partialName = QuickParse.GetPartialLongNameEx(caretLine.ToString(), caretLinePos.Character - 1) + let lineText = caretLine.ToString() + let partialName = QuickParse.GetPartialLongNameEx(lineText, caretLinePos.Character - 1) - let! declInfo = checkFileResults.GetDeclarationListInfo(Some parseFileResults, fcsCaretLineNumber, caretLine.ToString(), partialName, userOpName=userOpName) |> liftAsync + let declInfo = checkFileResults.GetDeclarationListInfo(Some parseFileResults, fcsCaretLineNumber, lineText, partialName) let addNames (addToBuffer:string -> unit) = for item in declInfo.Items do addToBuffer item.Name @@ -55,11 +53,11 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) |> Seq.toImmutableArray - for suggestion in ErrorResolutionHints.getSuggestedNames addNames unresolvedIdentifierText do - let replacement = Keywords.QuoteIdentifierIfNeeded suggestion + for suggestion in CompilerDiagnostics.GetSuggestedNames addNames unresolvedIdentifierText do + let replacement = PrettyNaming.AddBackticksToIdentifierIfNeeded suggestion let codeFix = CodeFixHelpers.createTextChangeCodeFix( - CompilerDiagnostics.getErrorMessage (ReplaceWithSuggestion suggestion), + CompilerDiagnostics.GetErrorMessage (FSharpDiagnosticKind.ReplaceWithSuggestion suggestion), context, (fun () -> asyncMaybe.Return [| TextChange(context.Span, replacement) |])) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/SimplifyName.fs b/vsintegration/src/FSharp.Editor/CodeFix/SimplifyName.fs index a2768640387..115cb41d6de 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/SimplifyName.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/SimplifyName.fs @@ -6,21 +6,18 @@ open System.Composition open System.Collections.Immutable open System.Threading.Tasks -open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Diagnostics open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.CodeFixes open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics -open SymbolHelpers [] type internal FSharpSimplifyNameCodeFixProvider() = inherit CodeFixProvider() let fixableDiagnosticId = FSharpIDEDiagnosticIds.SimplifyNamesDiagnosticId - override __.FixableDiagnosticIds = ImmutableArray.Create(fixableDiagnosticId) + override _.FixableDiagnosticIds = ImmutableArray.Create(fixableDiagnosticId) - override __.RegisterCodeFixesAsync(context: CodeFixContext) : Task = + override _.RegisterCodeFixesAsync(context: CodeFixContext) : Task = async { for diagnostic in context.Diagnostics |> Seq.filter (fun x -> x.Id = fixableDiagnosticId) do let title = diff --git a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs new file mode 100644 index 00000000000..ecf9c59708b --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes + +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text + +[] +type internal FSharpUseMutationWhenValueIsMutableFixProvider + [] + ( + ) = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0020"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override _.RegisterCodeFixesAsync context : Task = + asyncMaybe { + let diagnostics = + context.Diagnostics + |> Seq.filter (fun x -> fixableDiagnosticIds |> Set.contains x.Id) + |> Seq.toImmutableArray + + let document = context.Document + do! Option.guard (not(isSignatureFile document.FilePath)) + + let! sourceText = document.GetTextAsync(context.CancellationToken) + + let adjustedPosition = + let rec loop ch pos = + if Char.IsWhiteSpace(ch) then + pos + else + loop sourceText.[pos + 1] (pos + 1) + + loop sourceText.[context.Span.Start] context.Span.Start + + let textLine = sourceText.Lines.GetLineFromPosition adjustedPosition + let textLinePos = sourceText.Lines.GetLinePosition adjustedPosition + let fcsTextLineNumber = Line.fromZ textLinePos.Line + let! lexerSymbol = document.TryFindFSharpLexerSymbolAsync(adjustedPosition, SymbolLookupKind.Greedy, false, false, nameof(FSharpUseMutationWhenValueIsMutableFixProvider)) + let! _, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpUseMutationWhenValueIsMutableFixProvider)) |> liftAsync + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland) + + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsMutable || mfv.HasSetterMethod -> + let title = SR.UseMutationWhenValueIsMutable() + let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.Range) + let mutable pos = symbolSpan.End + let mutable ch = sourceText.[pos] + + // We're looking for the possibly erroneous '=' + while pos <= context.Span.Length && ch <> '=' do + pos <- pos + 1 + ch <- sourceText.[pos] + + let codeFix = + CodeFixHelpers.createTextChangeCodeFix( + title, + context, + (fun () -> asyncMaybe.Return [| TextChange(TextSpan(pos + 1, 1), "<-") |])) + + context.RegisterCodeFix(codeFix, diagnostics) + | _ -> () + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeFix/WrapExpressionInParentheses.fs b/vsintegration/src/FSharp.Editor/CodeFix/WrapExpressionInParentheses.fs new file mode 100644 index 00000000000..07ec5a24c4a --- /dev/null +++ b/vsintegration/src/FSharp.Editor/CodeFix/WrapExpressionInParentheses.fs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System.Composition +open System.Threading +open System.Threading.Tasks + +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.CodeFixes +open Microsoft.CodeAnalysis.CodeActions + +[] +type internal FSharpWrapExpressionInParenthesesFixProvider() = + inherit CodeFixProvider() + + let fixableDiagnosticIds = set ["FS0597"] + + override _.FixableDiagnosticIds = Seq.toImmutableArray fixableDiagnosticIds + + override this.RegisterCodeFixesAsync context : Task = + async { + let title = SR.WrapExpressionInParentheses() + + let getChangedText (sourceText: SourceText) = + sourceText.WithChanges(TextChange(TextSpan(context.Span.Start, 0), "(")) + .WithChanges(TextChange(TextSpan(context.Span.End + 1, 0), ")")) + + context.RegisterCodeFix( + CodeAction.Create( + title, + (fun (cancellationToken: CancellationToken) -> + async { + let! sourceText = context.Document.GetTextAsync(cancellationToken) |> Async.AwaitTask + return context.Document.WithText(getChangedText sourceText) + } |> RoslynHelpers.StartAsyncAsTask(cancellationToken)), + title), context.Diagnostics |> Seq.filter (fun x -> this.FixableDiagnosticIds.Contains x.Id) |> Seq.toImmutableArray) + } |> RoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken) diff --git a/vsintegration/src/FSharp.Editor/CodeLens/AbstractCodeLensDisplayService.fs b/vsintegration/src/FSharp.Editor/CodeLens/AbstractCodeLensDisplayService.fs index b5c4b8fb905..ba21dabebde 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/AbstractCodeLensDisplayService.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/AbstractCodeLensDisplayService.fs @@ -20,7 +20,7 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam buffer.Changed.Add self.HandleBufferChanged view.LayoutChanged.Add self.HandleLayoutChanged ) - + /// /// Enqueing an unit signals to the tagger that all visible line lens must be layouted again, /// to respect single line changes. @@ -64,11 +64,11 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam member val CurrentBufferSnapshot = null with get, set /// Helper method which returns the start line number of a tracking span - member __.GetTrackingSpanStartLine (snapshot:ITextSnapshot) (trackingSpan:ITrackingSpan) = + member _.GetTrackingSpanStartLine (snapshot:ITextSnapshot) (trackingSpan:ITrackingSpan) = snapshot.GetLineNumberFromPosition(trackingSpan.GetStartPoint(snapshot).Position) /// Helper method which returns the start line number of a tracking span - member __.TryGetTSpanStartLine (snapshot:ITextSnapshot) (trackingSpan:ITrackingSpan) = + member _.TryGetTSpanStartLine (snapshot:ITextSnapshot) (trackingSpan:ITrackingSpan) = let pos = trackingSpan.GetStartPoint(snapshot).Position if snapshot.Length - 1 < pos then None else pos |> snapshot.GetLineNumberFromPosition |> Some @@ -110,7 +110,7 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam let mutable element = self.UiElements.[trackingSpan] element.Visibility <- Visibility.Hidden - member __.CreateDefaultStackPanel () = + member _.CreateDefaultStackPanel () = let grid = Grid(Visibility = Visibility.Hidden) Canvas.SetLeft(grid, 0.) Canvas.SetTop(grid, 0.) @@ -159,10 +159,9 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam #else ignore e #endif - + /// Public non-thread-safe method to add line lens for a given tracking span. /// Returns an UIElement which can be used to add Ui elements and to remove the line lens later. - member self.AddCodeLens (trackingSpan:ITrackingSpan) = if trackingSpan.TextBuffer <> buffer then failwith "TrackingSpan text buffer does not equal with CodeLens text buffer" let Grid = self.AddTrackingSpan trackingSpan @@ -220,8 +219,12 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam member self.HandleLayoutChanged (e:TextViewLayoutChangedEventArgs) = try + // We can cancel existing stuff because the algorithm supports abortion without any data loss + self.LayoutChangedCts.Cancel() + self.LayoutChangedCts.Dispose() + self.LayoutChangedCts <- new CancellationTokenSource() let buffer = e.NewSnapshot - let recentVisibleLineNumbers = Set [self.RecentLastVsblLineNmbr .. self.RecentLastVsblLineNmbr] + let recentVisibleLineNumbers = Set [self.RecentFirstVsblLineNmbr .. self.RecentLastVsblLineNmbr] let firstVisibleLineNumber, lastVisibleLineNumber = let first, last = view.TextViewLines.FirstVisibleLine, @@ -286,10 +289,6 @@ type CodeLensDisplayService (view : IWpfTextView, buffer : ITextBuffer, layerNam // Save the new first and last visible lines for tracking self.RecentFirstVsblLineNmbr <- firstVisibleLineNumber self.RecentLastVsblLineNmbr <- lastVisibleLineNumber - // We can cancel existing stuff because the algorithm supports abortion without any data loss - self.LayoutChangedCts.Cancel() - self.LayoutChangedCts.Dispose() - self.LayoutChangedCts <- new CancellationTokenSource() self.AsyncCustomLayoutOperation visibleLineNumbers buffer |> RoslynHelpers.StartAsyncSafe self.LayoutChangedCts.Token "HandleLayoutChanged" diff --git a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs index 3702ac62878..fbc54c1e5fc 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs @@ -114,11 +114,11 @@ type CodeLensGeneralTagger (view, buffer) as self = interface ITagger with [] - override __.TagsChanged = tagsChangedEvent.Publish + override _.TagsChanged = tagsChangedEvent.Publish /// Returns the tags which reserve the correct space for adornments /// Notice, it's asumed that the data in the collection is valid. - override __.GetTags spans = + override _.GetTags spans = try seq { for span in spans do diff --git a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs index eaf4b541a84..8d3be2fcf35 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs @@ -23,8 +23,7 @@ type internal CodeLensProvider ( [)>] serviceProvider: IServiceProvider, textDocumentFactory: ITextDocumentFactoryService, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, + metadataAsSource: FSharpMetadataAsSourceService, typeMap : FSharpClassificationTypeMap Lazy, settings: EditorOptions ) = @@ -50,7 +49,7 @@ type internal CodeLensProvider ) let tagger = CodeLensGeneralTagger(wpfView, buffer) - let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, checkerProvider.Checker, projectInfoManager, componentModel.GetService(), typeMap, tagger, settings) + let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, tagger, settings) let provider = (wpfView, (tagger, service)) wpfView.Closed.Add (fun _ -> taggers.Remove provider |> ignore) taggers.Add((wpfView, (tagger, service))) @@ -69,7 +68,7 @@ type internal CodeLensProvider | _ -> None |> Option.get ) - let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, checkerProvider.Checker, projectInfoManager, componentModel.GetService(), typeMap, LineLensDisplayService(wpfView, buffer), settings) + let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, LineLensDisplayService(wpfView, buffer), settings) let provider = (wpfView, service) wpfView.Closed.Add (fun _ -> lineLensProvider.Remove provider |> ignore) lineLensProvider.Add(provider) @@ -86,7 +85,7 @@ type internal CodeLensProvider member val LineLensAdornmentLayerDefinition : AdornmentLayerDefinition = null with get, set interface IViewTaggerProvider with - override __.CreateTagger(view, buffer) = + override _.CreateTagger(view, buffer) = if settings.CodeLens.Enabled && not settings.CodeLens.ReplaceWithLineLens then let wpfView = match view with @@ -98,6 +97,6 @@ type internal CodeLensProvider null interface IWpfTextViewCreationListener with - override __.TextViewCreated view = + override _.TextViewCreated view = if settings.CodeLens.Enabled && settings.CodeLens.ReplaceWithLineLens then addLineLensProviderOnce view (view.TextBuffer) |> ignore \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs index 21a70f89e2e..ac322ac733f 100644 --- a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs +++ b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs @@ -16,23 +16,24 @@ open Microsoft.CodeAnalysis.Editor.Shared.Extensions open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Classification open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Shared.Extensions -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization open Microsoft.VisualStudio.FSharp.Editor.Logging - open Microsoft.VisualStudio.Shell.Interop - open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.Text.Classification -open Internal.Utilities.StructuredFormat - open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Shared.Utilities type internal CodeLens(taggedText, computed, fullTypeSignature, uiElement) = - member val TaggedText: Async<(ResizeArray * QuickInfoNavigation) option> = taggedText + member val TaggedText: Async<(ResizeArray * QuickInfoNavigation) option> = taggedText member val Computed: bool = computed with get, set member val FullTypeSignature: string = fullTypeSignature member val UiElement: UIElement = uiElement with get, set @@ -43,8 +44,7 @@ type internal FSharpCodeLensService workspace: Workspace, documentId: Lazy, buffer: ITextBuffer, - checker: FSharpChecker, - projectInfoManager: FSharpProjectOptionsManager, + metadataAsSource: FSharpMetadataAsSourceService, classificationFormatMapService: IClassificationFormatMapService, typeMap: Lazy, codeLens : CodeLensDisplayService, @@ -54,18 +54,26 @@ type internal FSharpCodeLensService let lineLens = codeLens let visit pos parseTree = - AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with - member __.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + SyntaxTraversal.Traverse(pos, parseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = defaultTraverse(expr) - override __.VisitInheritSynMemberDefn (_, _, _, _, range) = Some range + override _.VisitInheritSynMemberDefn (_, _, _, _, _, range) = Some range - override __.VisitTypeAbbrev( _, range) = Some range + override _.VisitTypeAbbrev(_, _, range) = Some range - override __.VisitLetOrUse(_, _, _, range) = Some range + override _.VisitLetOrUse(_, _, _, bindings, range) = + match bindings |> Seq.tryFind (fun b -> b.RangeOfHeadPattern.StartLine = pos.Line) with + | Some entry -> + Some entry.RangeOfBindingWithRhs + | None -> + // We choose to use the default range because + // it wasn't possible to find the complete range + // including implementation code. + Some range - override __.VisitBinding (fn, binding) = - Some binding.RangeOfBindingAndRhs + override _.VisitBinding (_, fn, binding) = + Some binding.RangeOfBindingWithRhs }) let formatMap = lazy classificationFormatMapService.GetClassificationFormatMap "tooltip" @@ -75,7 +83,7 @@ type internal FSharpCodeLensService let mutable bufferChangedCts = new CancellationTokenSource() let uiContext = SynchronizationContext.Current - let layoutTagToFormatting (layoutTag: LayoutTag) = + let layoutTagToFormatting (layoutTag: TextTag) = layoutTag |> RoslynHelpers.roslynTag |> FSharpClassificationTags.GetClassificationTypeName @@ -121,7 +129,7 @@ type internal FSharpCodeLensService let inl = match text with - | :? Layout.NavigableTaggedText as nav when navigation.IsTargetValid nav.Range -> + | :? NavigableTaggedText as nav when navigation.IsTargetValid nav.Range -> let h = Documents.Hyperlink(run, ToolTip = nav.Range.FileName) h.Click.Add (fun _ -> navigation.NavigateTo nav.Range) @@ -146,12 +154,13 @@ type internal FSharpCodeLensService logInfof "Rechecking code due to buffer edit!" #endif let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj - let! _, options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, bufferChangedCts.Token) - let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(document, options, "LineLens", allowStaleResults=true) + let! parseFileResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpUseMutationWhenValueIsMutableFixProvider)) |> liftAsync + let parsedInput = parseFileResults.ParseTree #if DEBUG logInfof "Getting uses of all symbols!" #endif - let! symbolUses = checkFileResults.GetAllUsesOfAllSymbolsInFile() |> liftAsync + let! ct = Async.CancellationToken |> liftAsync + let symbolUses = checkFileResults.GetAllUsesOfAllSymbolsInFile(ct) let textSnapshot = buffer.CurrentSnapshot #if DEBUG logInfof "Updating due to buffer edit!" @@ -175,15 +184,14 @@ type internal FSharpCodeLensService if (lineNumber >= 0 || lineNumber < textSnapshot.LineCount) then match func.FullTypeSafe with | Some _ -> - let! maybeContext = checkFileResults.GetDisplayContextForPos(func.DeclarationLocation.Start) + let maybeContext = checkFileResults.GetDisplayContextForPos(func.DeclarationLocation.Start) let displayContext = Option.defaultValue displayContext maybeContext let typeLayout = func.FormatLayout displayContext - let taggedText = ResizeArray() - - Layout.renderL (Layout.taggedTextListR taggedText.Add) typeLayout |> ignore + let taggedText = ResizeArray() + typeLayout |> Seq.iter taggedText.Add let statusBar = StatusBar(serviceProvider.GetService()) - let navigation = QuickInfoNavigation(statusBar, checker, projectInfoManager, document, realPosition) + let navigation = QuickInfoNavigation(statusBar, metadataAsSource, document, realPosition) // Because the data is available notify that this line should be updated, displaying the results return Some (taggedText, navigation) | None -> @@ -192,7 +200,7 @@ type internal FSharpCodeLensService #endif return None else return None - with e -> + with e -> #if DEBUG logErrorf "Error in lazy line lens computation. %A" e #else @@ -200,29 +208,29 @@ type internal FSharpCodeLensService #endif return None } - + let inline setNewResultsAndWarnIfOverriden fullDeclarationText value = #if DEBUG if newResults.ContainsKey fullDeclarationText then logWarningf "New results already contains: %A" fullDeclarationText #endif newResults.[fullDeclarationText] <- value - + for symbolUse in symbolUses do if symbolUse.IsFromDefinition then match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as func when func.IsModuleValueOrMember || func.IsProperty -> - let funcID = func.FullName - let fullDeclarationText = funcID + let funcID = func.LogicalName + (func.FullType.ToString() |> hash |> string) + // Use a combination of the the function name + the hashed value of the type signature let fullTypeSignature = func.FullType.ToString() // Try to re-use the last results - if lastResults.ContainsKey fullDeclarationText then + if lastResults.ContainsKey funcID then // Make sure that the results are usable - let inline setNewResultsAndWarnIfOverridenLocal value = setNewResultsAndWarnIfOverriden fullDeclarationText value - let lastTrackingSpan, codeLens as lastResult = lastResults.[fullDeclarationText] + let inline setNewResultsAndWarnIfOverridenLocal value = setNewResultsAndWarnIfOverriden funcID value + let lastTrackingSpan, codeLens as lastResult = lastResults.[funcID] if codeLens.FullTypeSignature = fullTypeSignature then setNewResultsAndWarnIfOverridenLocal lastResult - oldResults.Remove fullDeclarationText |> ignore + oldResults.Remove funcID |> ignore else let declarationLine, range = match visit func.DeclarationLocation.Start parsedInput with @@ -242,19 +250,19 @@ type internal FSharpCodeLensService fullTypeSignature, null) // The old results aren't computed at all, because the line might have changed create new results - tagsToUpdate.[lastTrackingSpan] <- (newTrackingSpan, fullDeclarationText, res) + tagsToUpdate.[lastTrackingSpan] <- (newTrackingSpan, funcID, res) setNewResultsAndWarnIfOverridenLocal (newTrackingSpan, res) - oldResults.Remove fullDeclarationText |> ignore + oldResults.Remove funcID |> ignore else // The symbol might be completely new or has slightly changed. // We need to track this and iterate over the left entries to ensure that there isn't anything - unattachedSymbols.Add((symbolUse, func, fullDeclarationText, fullTypeSignature)) + unattachedSymbols.Add((symbolUse, func, funcID, fullTypeSignature)) | _ -> () // In best case this works quite `covfefe` fine because often enough we change only a small part of the file and not the complete. for unattachedSymbol in unattachedSymbols do - let symbolUse, func, fullDeclarationText, fullTypeSignature = unattachedSymbol + let symbolUse, func, funcID, fullTypeSignature = unattachedSymbol let declarationLine, range = match visit func.DeclarationLocation.Start parsedInput with | Some range -> range.StartLine - 1, range @@ -273,8 +281,8 @@ type internal FSharpCodeLensService let newTrackingSpan = textSnapshot.CreateTrackingSpan(declarationSpan, SpanTrackingMode.EdgeExclusive) if codeLens.Computed && (isNull codeLens.UiElement |> not) then - newResults.[fullDeclarationText] <- (newTrackingSpan, codeLens) - tagsToUpdate.[trackingSpan] <- (newTrackingSpan, fullDeclarationText, codeLens) + newResults.[funcID] <- (newTrackingSpan, codeLens) + tagsToUpdate.[trackingSpan] <- (newTrackingSpan, funcID, codeLens) else let res = CodeLens( @@ -283,8 +291,8 @@ type internal FSharpCodeLensService fullTypeSignature, null) // The tag might be still valid but it hasn't been computed yet so create fresh results - tagsToUpdate.[trackingSpan] <- (newTrackingSpan, fullDeclarationText, res) - newResults.[fullDeclarationText] <- (newTrackingSpan, res) + tagsToUpdate.[trackingSpan] <- (newTrackingSpan, funcID, res) + newResults.[funcID] <- (newTrackingSpan, res) let key = res.Key oldResults.Remove key |> ignore // no need to check this entry again | None -> @@ -305,7 +313,7 @@ type internal FSharpCodeLensService let trackingSpan = textSnapshot.CreateTrackingSpan(declarationSpan, SpanTrackingMode.EdgeExclusive) codeLensToAdd.Add (trackingSpan, res) - newResults.[fullDeclarationText] <- (trackingSpan, res) + newResults.[funcID] <- (trackingSpan, res) with e -> #if DEBUG logExceptionWithContext (e, "Line Lens tracking tag span creation") @@ -398,8 +406,8 @@ type internal FSharpCodeLensService } |> Async.Start end - member __.BufferChanged ___ = + member _.BufferChanged ___ = bufferChangedCts.Cancel() // Stop all ongoing async workflow. bufferChangedCts.Dispose() bufferChangedCts <- new CancellationTokenSource() - executeCodeLenseAsync () |> Async.Ignore |> RoslynHelpers.StartAsyncSafe bufferChangedCts.Token "Buffer Changed" \ No newline at end of file + executeCodeLenseAsync () |> Async.Ignore |> RoslynHelpers.StartAsyncSafe bufferChangedCts.Token "Buffer Changed" diff --git a/vsintegration/src/FSharp.Editor/Commands/FsiCommandService.fs b/vsintegration/src/FSharp.Editor/Commands/FsiCommandService.fs index 389d50b3cba..81dccba08ed 100644 --- a/vsintegration/src/FSharp.Editor/Commands/FsiCommandService.fs +++ b/vsintegration/src/FSharp.Editor/Commands/FsiCommandService.fs @@ -82,7 +82,7 @@ type internal FsiCommandFilterProvider [] ([)>] serviceProvider: System.IServiceProvider, editorFactory: IVsEditorAdaptersFactoryService) = interface IWpfTextViewCreationListener with - member __.TextViewCreated(textView) = + member _.TextViewCreated(textView) = match editorFactory.GetViewAdapter(textView) with | null -> () | textViewAdapter -> diff --git a/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs b/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs index 1683cb6a4a7..3b1afa222a2 100644 --- a/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs +++ b/vsintegration/src/FSharp.Editor/Commands/HelpContextService.fs @@ -9,23 +9,23 @@ open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Classification open Microsoft.VisualStudio.LanguageServices.Implementation.F1Help open Microsoft.CodeAnalysis.Host.Mef -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open Microsoft.CodeAnalysis [] [, FSharpConstants.FSharpLanguageName)>] type internal FSharpHelpContextService [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = - static let userOpName = "ImplementInterfaceCodeFix" - static member GetHelpTerm(checker: FSharpChecker, sourceText : SourceText, fileName, options, span: TextSpan, tokens: List, textVersion, perfOptions) : Async = + static member GetHelpTerm(document: Document, span: TextSpan, tokens: List) : Async = asyncMaybe { - let! _, _, check = checker.ParseAndCheckDocument(fileName, textVersion, sourceText, options, perfOptions, userOpName = userOpName) + let! _, check = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpHelpContextService)) |> liftAsync + let! sourceText = document.GetTextAsync() |> liftTaskAsync let textLines = sourceText.Lines let lineInfo = textLines.GetLineFromPosition(span.Start) let line = lineInfo.LineNumber @@ -98,14 +98,11 @@ type internal FSharpHelpContextService member this.GetHelpTermAsync(document, textSpan, cancellationToken) = asyncMaybe { - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! sourceText = document.GetTextAsync(cancellationToken) - let! textVersion = document.GetTextVersionAsync(cancellationToken) - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + let defines = document.GetFSharpQuickDefines() let textLine = sourceText.Lines.GetLineFromPosition(textSpan.Start) let classifiedSpans = Tokenizer.getClassifiedSpans(document.Id, sourceText, textLine.Span, Some document.Name, defines, cancellationToken) - let perfOptions = document.FSharpOptions.LanguageServicePerformance - return! FSharpHelpContextService.GetHelpTerm(checkerProvider.Checker, sourceText, document.FilePath, projectOptions, textSpan, classifiedSpans, textVersion.GetHashCode(), perfOptions) + return! FSharpHelpContextService.GetHelpTerm(document, textSpan, classifiedSpans) } |> Async.map (Option.defaultValue "") |> RoslynHelpers.StartAsyncAsTask cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs b/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs index 11922d0d0d0..0771f84d4d8 100644 --- a/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs +++ b/vsintegration/src/FSharp.Editor/Commands/XmlDocCommandService.fs @@ -13,23 +13,17 @@ open Microsoft.VisualStudio.OLE.Interop open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.Text.Editor open Microsoft.VisualStudio.TextManager.Interop +open Microsoft.VisualStudio.LanguageServices open Microsoft.VisualStudio.Utilities -open Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices type internal XmlDocCommandFilter ( wpfTextView: IWpfTextView, - filePath: string, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, - workspace: VisualStudioWorkspaceImpl + filePath: string, + workspace: VisualStudioWorkspace ) = - static let userOpName = "XmlDocCommand" - - let checker = checkerProvider.Checker - let document = // There may be multiple documents with the same file path. // However, for the purpose of generating XmlDoc comments, it is ok to keep only the first document. @@ -51,7 +45,7 @@ type internal XmlDocCommandFilter ErrorHandler.ThrowOnFailure errorCode |> ignore interface IOleCommandTarget with - member __.Exec(pguidCmdGroup: byref, nCmdID: uint32, nCmdexecopt: uint32, pvaIn: IntPtr, pvaOut: IntPtr) = + member _.Exec(pguidCmdGroup: byref, nCmdID: uint32, nCmdexecopt: uint32, pvaIn: IntPtr, pvaOut: IntPtr) = if pguidCmdGroup = VSConstants.VSStd2K && nCmdID = uint32 VSConstants.VSStd2KCmdID.TYPECHAR then match getTypedChar pvaIn with | ('/' | '<') as lastChar -> @@ -60,17 +54,17 @@ type internal XmlDocCommandFilter let curLine = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().GetText() let lineWithLastCharInserted = curLine.Insert (indexOfCaret, string lastChar) - match XmlDocComment.isBlank lineWithLastCharInserted with + match XmlDocComment.IsBlank lineWithLastCharInserted with | Some i when i = indexOfCaret -> asyncMaybe { try // XmlDocable line #1 are 1-based, editor is 0-based let curLineNum = wpfTextView.Caret.Position.BufferPosition.GetContainingLine().LineNumber + 1 let! document = document.Value - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None) - let! sourceText = document.GetTextAsync(CancellationToken.None) - let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName) - let xmlDocables = XmlDocParser.getXmlDocables (sourceText.ToFSharpSourceText(), Some parsedInput) + let! cancellationToken = Async.CancellationToken |> liftAsync + let! sourceText = document.GetTextAsync(cancellationToken) + let! parseResults = document.GetFSharpParseResultsAsync(nameof(XmlDocCommandFilter)) |> liftAsync + let xmlDocables = XmlDocParser.GetXmlDocables (sourceText.ToFSharpSourceText(), parseResults.ParseTree) let xmlDocablesBelowThisLine = // +1 because looking below current line for e.g. a 'member' xmlDocables |> List.filter (fun (XmlDocable(line,_indent,_paramNames)) -> line = curLineNum+1) @@ -106,33 +100,29 @@ type internal XmlDocCommandFilter else VSConstants.E_FAIL - member __.QueryStatus(pguidCmdGroup: byref, cCmds: uint32, prgCmds: OLECMD [], pCmdText: IntPtr) = + member _.QueryStatus(pguidCmdGroup: byref, cCmds: uint32, prgCmds: OLECMD [], pCmdText: IntPtr) = if not (isNull nextTarget) then nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText) else VSConstants.E_FAIL -// Disabled: -// - https://github.com/Microsoft/visualfsharp/issues/6076 -// - The feature does not work; it should probably use an exposed Roslyn API of some sort -// - Despite not working, it is a source of UI delays -//[)>] -//[] -//[] +[)>] +[] +[] type internal XmlDocCommandFilterProvider [] - (checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, - workspace: VisualStudioWorkspaceImpl, + ( + workspace: VisualStudioWorkspace, textDocumentFactoryService: ITextDocumentFactoryService, - editorFactory: IVsEditorAdaptersFactoryService) = + editorFactory: IVsEditorAdaptersFactoryService + ) = interface IWpfTextViewCreationListener with - member __.TextViewCreated(textView) = + member _.TextViewCreated(textView) = match editorFactory.GetViewAdapter(textView) with | null -> () | textViewAdapter -> match textDocumentFactoryService.TryGetTextDocument(textView.TextBuffer) with | true, doc -> - let commandFilter = XmlDocCommandFilter(textView, doc.FilePath, checkerProvider, projectInfoManager, workspace) + let commandFilter = XmlDocCommandFilter(textView, doc.FilePath, workspace) commandFilter.AttachToViewAdapter textViewAdapter | _ -> () \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Common/CodeAnalysisExtensions.fs b/vsintegration/src/FSharp.Editor/Common/CodeAnalysisExtensions.fs index fb69b161093..8f40f743507 100644 --- a/vsintegration/src/FSharp.Editor/Common/CodeAnalysisExtensions.fs +++ b/vsintegration/src/FSharp.Editor/Common/CodeAnalysisExtensions.fs @@ -2,7 +2,7 @@ module internal Microsoft.VisualStudio.FSharp.Editor.CodeAnalysisExtensions open Microsoft.CodeAnalysis -open FSharp.Compiler.Range +open FSharp.Compiler.Text open System.IO type Project with @@ -11,29 +11,30 @@ type Project with member this.GetDependentProjectIds () = this.Solution.GetProjectDependencyGraph().GetProjectsThatDirectlyDependOnThisProject this.Id - /// Returns all projects within the same solution that directly reference this project. member this.GetDependentProjects () = this.Solution.GetProjectDependencyGraph().GetProjectsThatDirectlyDependOnThisProject this.Id |> Seq.map this.Solution.GetProject - /// Returns the ProjectIds of all of the projects that this project directly or transitively depneds on member this.GetProjectIdsOfAllProjectsThisProjectDependsOn () = let graph = this.Solution.GetProjectDependencyGraph() let transitiveDependencies = graph.GetProjectsThatThisProjectTransitivelyDependsOn this.Id let directDependencies = graph.GetProjectsThatThisProjectDirectlyDependsOn this.Id Seq.append directDependencies transitiveDependencies - /// The list all of the projects that this project directly or transitively depneds on member this.GetAllProjectsThisProjectDependsOn () = this.GetProjectIdsOfAllProjectsThisProjectDependsOn () |> Seq.map this.Solution.GetProject - type Solution with + /// Checks if the file path is associated with a document in the solution. + member self.ContainsDocumentWithFilePath filePath = + self.GetDocumentIdsWithFilePath(filePath).IsEmpty + |> not + /// Try to get a document inside the solution using the document's name member self.TryGetDocumentNamed docName = self.Projects |> Seq.tryPick (fun proj -> @@ -47,23 +48,27 @@ type Solution with self.GetDocumentIdsWithFilePath (Path.GetFullPath filePath) |> Seq.tryHead |> Option.map (fun docId -> self.GetDocument docId) + /// Try to find the documentId corresponding to the provided filepath and ProjectId within this solution + member self.TryGetDocumentFromPath(filePath, projId: ProjectId) = + // It's crucial to normalize file path here (specificaly, remove relative parts), + // otherwise Roslyn does not find documents. + self.GetDocumentIdsWithFilePath (Path.GetFullPath filePath) + |> Seq.filter (fun x -> x.ProjectId = projId) + |> Seq.tryHead |> Option.map (fun docId -> self.GetDocument docId) /// Try to get a project inside the solution using the project's id member self.TryGetProject (projId:ProjectId) = if self.ContainsProject projId then Some (self.GetProject projId) else None - /// Returns the projectIds of all projects within this solution that directly reference the provided project member self.GetDependentProjects (projectId:ProjectId) = self.GetProjectDependencyGraph().GetProjectsThatDirectlyDependOnThisProject projectId |> Seq.map self.GetProject - /// Returns the projectIds of all projects within this solution that directly reference the provided project member self.GetDependentProjectIds (projectId:ProjectId) = self.GetProjectDependencyGraph().GetProjectsThatDirectlyDependOnThisProject projectId - /// Returns the ProjectIds of all of the projects that directly or transitively depends on member self.GetProjectIdsOfAllProjectReferences (projectId:ProjectId) = let graph = self.GetProjectDependencyGraph() @@ -71,13 +76,11 @@ type Solution with let directDependencies = graph.GetProjectsThatThisProjectDirectlyDependsOn projectId Seq.append directDependencies transitiveDependencies - /// Returns all of the projects that this project that directly or transitively depends on member self.GetAllProjectsThisProjectDependsOn (projectId:ProjectId) = self.GetProjectIdsOfAllProjectReferences projectId |> Seq.map self.GetProject - /// Try to retrieve the corresponding DocumentId for the range's file in the solution /// and if a projectId is provided, only try to find the document within that project /// or a project referenced by that project @@ -101,7 +104,6 @@ type Solution with self.GetDocumentIdsWithFilePath filePath |> List.ofSeq |> matchingDoc - /// Try to retrieve the corresponding Document for the range's file in the solution /// and if a projectId is provided, only try to find the document within that project /// or a project referenced by that project diff --git a/vsintegration/src/FSharp.Editor/Common/Constants.fs b/vsintegration/src/FSharp.Editor/Common/Constants.fs index 2c6e7c58fdc..75ad88e3379 100644 --- a/vsintegration/src/FSharp.Editor/Common/Constants.fs +++ b/vsintegration/src/FSharp.Editor/Common/Constants.fs @@ -51,6 +51,10 @@ module internal FSharpConstants = /// "F# Miscellaneous Files" let FSharpMiscellaneousFilesName = "F# Miscellaneous Files" + [] + /// "F# Metadata" + let FSharpMetadataName = "F# Metadata" + [] module internal FSharpProviderConstants = diff --git a/vsintegration/src/FSharp.Editor/Common/Extensions.fs b/vsintegration/src/FSharp.Editor/Common/Extensions.fs index 894ef61b23b..6315654f56a 100644 --- a/vsintegration/src/FSharp.Editor/Common/Extensions.fs +++ b/vsintegration/src/FSharp.Editor/Common/Extensions.fs @@ -5,16 +5,22 @@ module internal Microsoft.VisualStudio.FSharp.Editor.Extensions open System open System.IO +open System.Collections.Immutable +open System.Threading +open System.Threading.Tasks + open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.Host + +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.Ast -open FSharp.Compiler.SourceCodeServices -type private FSharpGlyph = FSharp.Compiler.SourceCodeServices.FSharpGlyph -type private FSharpRoslynGlyph = Microsoft.CodeAnalysis.ExternalAccess.FSharp.FSharpGlyph +open Microsoft.VisualStudio.FSharp.Editor +type private FSharpGlyph = FSharp.Compiler.EditorServices.FSharpGlyph +type private FSharpRoslynGlyph = Microsoft.CodeAnalysis.ExternalAccess.FSharp.FSharpGlyph type Path with static member GetFullPathSafe path = @@ -34,6 +40,12 @@ type ProjectId with member this.ToFSharpProjectIdString() = this.Id.ToString("D").ToLowerInvariant() +type Project with + member this.IsFSharpMiscellaneous = this.Name = FSharpConstants.FSharpMiscellaneousFilesName + member this.IsFSharpMetadata = this.Name.StartsWith(FSharpConstants.FSharpMetadataName) + member this.IsFSharpMiscellaneousOrMetadata = this.IsFSharpMiscellaneous || this.IsFSharpMetadata + member this.IsFSharp = this.Language = LanguageNames.FSharp + type Document with member this.TryGetLanguageService<'T when 'T :> ILanguageService>() = match this.Project with @@ -45,6 +57,9 @@ type Document with languageServices.GetService<'T>() |> Some + member this.IsFSharpScript = + isScriptFile this.FilePath + module private SourceText = open System.Runtime.CompilerServices @@ -64,7 +79,7 @@ module private SourceText = let sourceText = { new Object() with - override __.GetHashCode() = + override _.GetHashCode() = let checksum = sourceText.GetChecksum() let contentsHash = if not checksum.IsDefault then Hash.combineValues checksum else 0 let encodingHash = if not (isNull sourceText.Encoding) then sourceText.Encoding.GetHashCode() else 0 @@ -76,24 +91,24 @@ module private SourceText = interface ISourceText with - member __.Item with get index = sourceText.[index] + member _.Item with get index = sourceText.[index] - member __.GetLineString(lineIndex) = + member _.GetLineString(lineIndex) = sourceText.Lines.[lineIndex].ToString() - member __.GetLineCount() = + member _.GetLineCount() = sourceText.Lines.Count - member __.GetLastCharacterPosition() = + member _.GetLastCharacterPosition() = if sourceText.Lines.Count > 0 then (sourceText.Lines.Count, sourceText.Lines.[sourceText.Lines.Count - 1].Span.Length) else (0, 0) - member __.GetSubTextString(start, length) = + member _.GetSubTextString(start, length) = sourceText.GetSubText(TextSpan(start, length)).ToString() - member __.SubTextEquals(target, startIndex) = + member _.SubTextEquals(target, startIndex) = if startIndex < 0 || startIndex >= sourceText.Length then invalidArg "startIndex" "Out of range." @@ -116,14 +131,14 @@ module private SourceText = didEqual - member __.ContentEquals(sourceText) = + member _.ContentEquals(sourceText) = match sourceText with | :? SourceText as sourceText -> sourceText.ContentEquals(sourceText) | _ -> false - member __.Length = sourceText.Length + member _.Length = sourceText.Length - member __.CopyTo(sourceIndex, destination, destinationIndex, count) = + member _.CopyTo(sourceIndex, destination, destinationIndex, count) = sourceText.CopyTo(sourceIndex, destination, destinationIndex, count) } @@ -134,7 +149,7 @@ type SourceText with member this.ToFSharpSourceText() = SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create)) -type FSharpNavigationDeclarationItem with +type NavigationItem with member x.RoslynGlyph : FSharpRoslynGlyph = match x.Glyph with | FSharpGlyph.Class @@ -241,7 +256,6 @@ module Option = [] module Seq = - open System.Collections.Immutable let toImmutableArray (xs: seq<'a>) : ImmutableArray<'a> = xs.ToImmutableArray() @@ -255,6 +269,8 @@ module Array = i <- i + 1 state + let toImmutableArray (xs: 'T[]) = xs.ToImmutableArray() + [] module Exception = @@ -276,3 +292,19 @@ module Exception = | _ -> root |> flattenInner |> String.concat " ---> " + +type Async with + static member RunImmediateExceptOnUI (computation: Async<'T>, ?cancellationToken ) = + match SynchronizationContext.Current with + | null -> + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + | _ -> Async.RunSynchronously(computation, ?cancellationToken=cancellationToken) diff --git a/vsintegration/src/FSharp.Editor/Common/FSharpCodeAnalysisExtensions.fs b/vsintegration/src/FSharp.Editor/Common/FSharpCodeAnalysisExtensions.fs new file mode 100644 index 00000000000..2ee5e4c64f2 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/Common/FSharpCodeAnalysisExtensions.fs @@ -0,0 +1,49 @@ +[] +module internal FSharpParseFileResultsExtensions + +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text + +type FSharpParseFileResults with + member this.TryRangeOfBindingWithHeadPatternWithPos pos = + let input = this.ParseTree + SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + defaultTraverse expr + + override _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding(_, SynBindingKind.Normal, _, _, _, _, _, pat, _, _, _, _) as binding -> + if Position.posEq binding.RangeOfHeadPattern.Start pos then + Some binding.RangeOfBindingWithRhs + else + // Check if it's an operator + match pat with + | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) when id.idText.StartsWith("op_") -> + if Position.posEq id.idRange.Start pos then + Some binding.RangeOfBindingWithRhs + else + defaultTraverse binding + | _ -> defaultTraverse binding + + | _ -> defaultTraverse binding }) + + member this.TryRangeOfTypeofWithNameAndTypeExpr pos = + SyntaxTraversal.Traverse(pos, this.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _, defaultTraverse, expr) = + match expr with + | SynExpr.DotGet(expr, _, _, range) -> + match expr with + | SynExpr.TypeApp(SynExpr.Ident(ident), _, typeArgs, _, _, _, _) -> + let onlyOneTypeArg = + match typeArgs with + | [] -> false + | [_] -> true + | _ -> false + if ident.idText = "typeof" && onlyOneTypeArg then + Some {| NamedIdentRange = typeArgs.Head.Range; FullExpressionRange = range |} + else + defaultTraverse expr + | _ -> defaultTraverse expr + | _ -> defaultTraverse expr }) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Common/Logger.fs b/vsintegration/src/FSharp.Editor/Common/Logger.fs index 03a507bf74a..3488917ae4f 100644 --- a/vsintegration/src/FSharp.Editor/Common/Logger.fs +++ b/vsintegration/src/FSharp.Editor/Common/Logger.fs @@ -77,12 +77,12 @@ module Logger = let LogBlock(functionId) = FSharpEditorEventSource.Instance.BlockStart(functionId) { new IDisposable with - member __.Dispose() = + member _.Dispose() = FSharpEditorEventSource.Instance.BlockStop(functionId) } let LogBlockMessage message functionId = FSharpEditorEventSource.Instance.BlockMessageStart(message, functionId) { new IDisposable with - member __.Dispose() = + member _.Dispose() = FSharpEditorEventSource.Instance.BlockMessageStop(message, functionId) } \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Common/Logger.fsi b/vsintegration/src/FSharp.Editor/Common/Logger.fsi index b86ea148252..1e70b8a6a0d 100644 --- a/vsintegration/src/FSharp.Editor/Common/Logger.fsi +++ b/vsintegration/src/FSharp.Editor/Common/Logger.fsi @@ -4,9 +4,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System -// FIXME: We cannot make this internal yet until F# gets a compiler switch to make cases public when the type itself is internal. -// https://github.com/Microsoft/visualfsharp/issues/4821 -type (* internal *) LogEditorFunctionId = +type internal LogEditorFunctionId = | Classification_Semantic = 1 | Classification_Syntactic = 2 | LanguageService_HandleCommandLineArgs = 3 diff --git a/vsintegration/src/FSharp.Editor/Common/Logging.fs b/vsintegration/src/FSharp.Editor/Common/Logging.fs index cc37f948f42..67dd99f6615 100644 --- a/vsintegration/src/FSharp.Editor/Common/Logging.fs +++ b/vsintegration/src/FSharp.Editor/Common/Logging.fs @@ -20,7 +20,6 @@ type LogType = | Warn -> "Warning" | Error -> "Error" - module Config = let [] fsharpOutputGuidString = "E721F849-446C-458C-997A-99E14A04CFD3" let fsharpOutputGuid = Guid fsharpOutputGuidString @@ -50,7 +49,7 @@ type [] Logger [] with get () = globalServiceProvider |> Option.defaultValue (ServiceProvider.GlobalProvider :> IServiceProvider) and set v = globalServiceProvider <- Some v - member __.FSharpLoggingPane + member _.FSharpLoggingPane with get () = getPane () |> function diff --git a/vsintegration/src/FSharp.Editor/Common/LspService.fs b/vsintegration/src/FSharp.Editor/Common/LspService.fs deleted file mode 100644 index 433f8338394..00000000000 --- a/vsintegration/src/FSharp.Editor/Common/LspService.fs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Microsoft.VisualStudio.FSharp.Editor - -open System.ComponentModel.Composition -open FSharp.Compiler.LanguageServer -open FSharp.Compiler.LanguageServer.Extensions -open StreamJsonRpc - -[)>] -type LspService() = - let mutable options = Options.Default() - let mutable jsonRpc: JsonRpc option = None - - let sendOptions () = - async { - match jsonRpc with - | None -> () - | Some rpc -> do! rpc.SetOptionsAsync(options) - } - - member __.SetJsonRpc(rpc: JsonRpc) = - jsonRpc <- Some rpc - sendOptions() - - member __.SetOptions(opt: Options) = - options <- opt - sendOptions() diff --git a/vsintegration/src/FSharp.Editor/Common/Pervasive.fs b/vsintegration/src/FSharp.Editor/Common/Pervasive.fs index 9dd525d609c..fc38c56885b 100644 --- a/vsintegration/src/FSharp.Editor/Common/Pervasive.fs +++ b/vsintegration/src/FSharp.Editor/Common/Pervasive.fs @@ -20,29 +20,29 @@ type internal ISetThemeColors = abstract member SetColors: unit -> unit type MaybeBuilder () = // 'T -> M<'T> [] - member inline __.Return value: 'T option = + member inline _.Return value: 'T option = Some value // M<'T> -> M<'T> [] - member inline __.ReturnFrom value: 'T option = + member inline _.ReturnFrom value: 'T option = value // unit -> M<'T> [] - member inline __.Zero (): unit option = + member inline _.Zero (): unit option = Some () // TODO: Should this be None? // (unit -> M<'T>) -> M<'T> [] - member __.Delay (f: unit -> 'T option): 'T option = + member _.Delay (f: unit -> 'T option): 'T option = f () // M<'T> -> M<'T> -> M<'T> // or // M -> M<'T> -> M<'T> [] - member inline __.Combine (r1, r2: 'T option): 'T option = + member inline _.Combine (r1, r2: 'T option): 'T option = match r1 with | None -> None @@ -51,12 +51,12 @@ type MaybeBuilder () = // M<'T> * ('T -> M<'U>) -> M<'U> [] - member inline __.Bind (value, f: 'T -> 'U option): 'U option = + member inline _.Bind (value, f: 'T -> 'U option): 'U option = Option.bind f value // 'T * ('T -> M<'U>) -> M<'U> when 'U :> IDisposable [] - member __.Using (resource: ('T :> System.IDisposable), body: _ -> _ option): _ option = + member _.Using (resource: ('T :> System.IDisposable), body: _ -> _ option): _ option = try body resource finally if not <| obj.ReferenceEquals (null, box resource) then @@ -88,23 +88,23 @@ let maybe = MaybeBuilder() [] type AsyncMaybeBuilder () = [] - member __.Return value : Async<'T option> = Some value |> async.Return + member _.Return value : Async<'T option> = Some value |> async.Return [] - member __.ReturnFrom value : Async<'T option> = value + member _.ReturnFrom value : Async<'T option> = value [] - member __.ReturnFrom (value: 'T option) : Async<'T option> = async.Return value + member _.ReturnFrom (value: 'T option) : Async<'T option> = async.Return value [] - member __.Zero () : Async = + member _.Zero () : Async = Some () |> async.Return [] - member __.Delay (f : unit -> Async<'T option>) : Async<'T option> = async.Delay f + member _.Delay (f : unit -> Async<'T option>) : Async<'T option> = async.Delay f [] - member __.Combine (r1, r2 : Async<'T option>) : Async<'T option> = + member _.Combine (r1, r2 : Async<'T option>) : Async<'T option> = async { let! r1' = r1 match r1' with @@ -113,7 +113,7 @@ type AsyncMaybeBuilder () = } [] - member __.Bind (value: Async<'T option>, f : 'T -> Async<'U option>) : Async<'U option> = + member _.Bind (value: Async<'T option>, f : 'T -> Async<'U option>) : Async<'U option> = async { let! value' = value match value' with @@ -122,14 +122,14 @@ type AsyncMaybeBuilder () = } [] - member __.Bind (value: System.Threading.Tasks.Task<'T>, f : 'T -> Async<'U option>) : Async<'U option> = + member _.Bind (value: System.Threading.Tasks.Task<'T>, f : 'T -> Async<'U option>) : Async<'U option> = async { let! value' = Async.AwaitTask value return! f value' } [] - member __.Bind (value: 'T option, f : 'T -> Async<'U option>) : Async<'U option> = + member _.Bind (value: 'T option, f : 'T -> Async<'U option>) : Async<'U option> = async { match value with | None -> return None @@ -137,7 +137,7 @@ type AsyncMaybeBuilder () = } [] - member __.Using (resource : ('T :> IDisposable), body : 'T -> Async<'U option>) : Async<'U option> = + member _.Using (resource : ('T :> IDisposable), body : 'T -> Async<'U option>) : Async<'U option> = async { use resource = resource return! body resource @@ -156,11 +156,11 @@ type AsyncMaybeBuilder () = x.While (enum.MoveNext, x.Delay (fun () -> body enum.Current))) [] - member inline __.TryWith (computation : Async<'T option>, catchHandler : exn -> Async<'T option>) : Async<'T option> = + member inline _.TryWith (computation : Async<'T option>, catchHandler : exn -> Async<'T option>) : Async<'T option> = async.TryWith (computation, catchHandler) [] - member inline __.TryFinally (computation : Async<'T option>, compensation : unit -> unit) : Async<'T option> = + member inline _.TryFinally (computation : Async<'T option>, compensation : unit -> unit) : Async<'T option> = async.TryFinally (computation, compensation) let asyncMaybe = AsyncMaybeBuilder() @@ -173,6 +173,14 @@ let inline liftAsync (computation : Async<'T>) : Async<'T option> = let liftTaskAsync task = task |> Async.AwaitTask |> liftAsync +module Array = + /// Returns a new array with an element replaced with a given value. + let replace index value (array: _ []) = + if index >= array.Length then raise (IndexOutOfRangeException "index") + let res = Array.copy array + res.[index] <- value + res + module Async = let map (f: 'T -> 'U) (a: Async<'T>) : Async<'U> = async { diff --git a/vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs b/vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs index ae8c5fe4fb6..f2cb16164a9 100644 --- a/vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs +++ b/vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs @@ -3,22 +3,29 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System -open System.Collections.Immutable open System.Collections.Generic +open System.Collections.Immutable open System.Threading open System.Threading.Tasks open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.Layout -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Range open Microsoft.VisualStudio.FSharp.Editor.Logging open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics +type RoslynTaggedText = Microsoft.CodeAnalysis.TaggedText + [] module internal RoslynHelpers = + let joinWithLineBreaks segments = + let lineBreak = TaggedText.lineBreak + match segments |> List.filter (Seq.isEmpty >> not) with + | [] -> Seq.empty + | xs -> xs |> List.reduce (fun acc elem -> seq { yield! acc; yield lineBreak; yield! elem }) let FSharpRangeToTextSpan(sourceText: SourceText, range: range) = // Roslyn TextLineCollection is zero-based, F# range lines are one-based @@ -37,8 +44,8 @@ module internal RoslynHelpers = let endLine = sourceText.Lines.GetLineFromPosition textSpan.End mkRange fileName - (Pos.fromZ startLine.LineNumber (textSpan.Start - startLine.Start)) - (Pos.fromZ endLine.LineNumber (textSpan.End - endLine.Start)) + (Position.fromZ startLine.LineNumber (textSpan.Start - startLine.Start)) + (Position.fromZ endLine.LineNumber (textSpan.End - endLine.Start)) let GetCompletedTaskResult(task: Task<'TResult>) = if task.Status = TaskStatus.RanToCompletion then @@ -47,65 +54,81 @@ module internal RoslynHelpers = Assert.Exception(task.Exception.GetBaseException()) raise(task.Exception.GetBaseException()) - - - /// maps from `LayoutTag` of the F# Compiler to Roslyn `TextTags` for use in tooltips + /// maps from `TextTag` of the F# Compiler to Roslyn `TextTags` for use in tooltips let roslynTag = function - | LayoutTag.ActivePatternCase - | LayoutTag.ActivePatternResult - | LayoutTag.UnionCase - | LayoutTag.Enum -> TextTags.Enum - | LayoutTag.Alias - | LayoutTag.Class - | LayoutTag.Union - | LayoutTag.Record - | LayoutTag.UnknownType -> TextTags.Class - | LayoutTag.Delegate -> TextTags.Delegate - | LayoutTag.Event -> TextTags.Event - | LayoutTag.Field -> TextTags.Field - | LayoutTag.Interface -> TextTags.Interface - | LayoutTag.Struct -> TextTags.Struct - | LayoutTag.Keyword -> TextTags.Keyword - | LayoutTag.Local -> TextTags.Local - | LayoutTag.Member - | LayoutTag.ModuleBinding - | LayoutTag.RecordField - | LayoutTag.Property -> TextTags.Property - | LayoutTag.Method -> TextTags.Method - | LayoutTag.Namespace -> TextTags.Namespace - | LayoutTag.Module -> TextTags.Module - | LayoutTag.LineBreak -> TextTags.LineBreak - | LayoutTag.Space -> TextTags.Space - | LayoutTag.NumericLiteral -> TextTags.NumericLiteral - | LayoutTag.Operator -> TextTags.Operator - | LayoutTag.Parameter -> TextTags.Parameter - | LayoutTag.TypeParameter -> TextTags.TypeParameter - | LayoutTag.Punctuation -> TextTags.Punctuation - | LayoutTag.StringLiteral -> TextTags.StringLiteral - | LayoutTag.Text - | LayoutTag.UnknownEntity -> TextTags.Text - - let CollectTaggedText (list: List<_>) (t:TaggedText) = list.Add(TaggedText(roslynTag t.Tag, t.Text)) + | TextTag.ActivePatternCase + | TextTag.ActivePatternResult + | TextTag.UnionCase + | TextTag.Enum -> TextTags.Enum + | TextTag.Struct -> TextTags.Struct + | TextTag.TypeParameter -> TextTags.TypeParameter + | TextTag.Alias + | TextTag.Class + | TextTag.Union + | TextTag.Record + | TextTag.UnknownType // Default to class until/unless we use classification data + | TextTag.Module -> TextTags.Class + | TextTag.Interface -> TextTags.Interface + | TextTag.Keyword -> TextTags.Keyword + | TextTag.Member + | TextTag.Function + | TextTag.Method -> TextTags.Method + | TextTag.RecordField + | TextTag.Property -> TextTags.Property + | TextTag.Parameter // parameter? + | TextTag.Local -> TextTags.Local + | TextTag.Namespace -> TextTags.Namespace + | TextTag.Delegate -> TextTags.Delegate + | TextTag.Event -> TextTags.Event + | TextTag.Field -> TextTags.Field + | TextTag.LineBreak -> TextTags.LineBreak + | TextTag.Space -> TextTags.Space + | TextTag.NumericLiteral -> TextTags.NumericLiteral + | TextTag.Operator -> TextTags.Operator + | TextTag.StringLiteral -> TextTags.StringLiteral + | TextTag.Punctuation -> TextTags.Punctuation + | TextTag.Text + | TextTag.ModuleBinding // why no 'Identifier'? Does it matter? + | TextTag.UnknownEntity -> TextTags.Text + + let CollectTaggedText (list: List<_>) (t:TaggedText) = list.Add(RoslynTaggedText(roslynTag t.Tag, t.Text)) type VolatileBarrier() = [] let mutable isStopped = false - member __.Proceed = not isStopped - member __.Stop() = isStopped <- true + member _.Proceed = not isStopped + member _.Stop() = isStopped <- true // This is like Async.StartAsTask, but - // 1. if cancellation occurs we explicitly associate the cancellation with cancellationToken - // 2. if exception occurs then set result to Unchecked.defaultof<_>, i.e. swallow exceptions + // 1. If cancellation occurs we explicitly associate the cancellation with cancellationToken + // 2. If exception occurs then set result to Unchecked.defaultof<_>, i.e. swallow exceptions // and hope that Roslyn copes with the null + // 3. Never, ever run the computation on the UI thread - switch to thread pool if necessary + // This is because Roslyn makes blocking invocations of tasks from the UI thread at + // several points, and relies on those tasks completing in the thread pool if necessary. + // See for example https://github.com/dotnet/fsharp/issues/11946#issuecomment-896071454 + // Note that no async { ... } code in FSharp.Editor is ever intended to run on the UI + // thread in any form. That is, our async code in FSharp.Editor is always "backgroundAsync" + // in the sense that it is valid switch away from the UI thread if it is ever started on + // the UI thread, e.g. see the corresponding backgroundTask { ... } in RFC FS-1097 + let StartAsyncAsTask (cancellationToken: CancellationToken) computation = + // Protect against blocking the UI thread by switching to thread pool + let computation = + match SynchronizationContext.Current with + | null -> computation + | _ -> + async { + do! Async.SwitchToThreadPool() + return! computation + } let tcs = new TaskCompletionSource<_>(TaskCreationOptions.None) let barrier = VolatileBarrier() let reg = cancellationToken.Register(fun _ -> if barrier.Proceed then tcs.TrySetCanceled(cancellationToken) |> ignore) let task = tcs.Task let disposeReg() = barrier.Stop(); if not task.IsCanceled then reg.Dispose() Async.StartWithContinuations( - async { do! Async.SwitchToThreadPool() - return! computation }, + computation, continuation=(fun result -> disposeReg() tcs.TrySetResult(result) |> ignore @@ -130,16 +153,21 @@ module internal RoslynHelpers = let StartAsyncUnitAsTask cancellationToken (computation:Async) = StartAsyncAsTask cancellationToken computation :> Task - let ConvertError(error: FSharpErrorInfo, location: Location) = + let ConvertError(error: FSharpDiagnostic, location: Location) = // Normalize the error message into the same format that we will receive it from the compiler. // This ensures that IntelliSense and Compiler errors in the 'Error List' are de-duplicated. // (i.e the same error does not appear twice, where the only difference is the line endings.) - let normalizedMessage = error.Message |> ErrorLogger.NormalizeErrorString |> ErrorLogger.NewlineifyErrorString + let normalizedMessage = error.Message |> FSharpDiagnostic.NormalizeErrorString |> FSharpDiagnostic.NewlineifyErrorString - let id = "FS" + error.ErrorNumber.ToString("0000") + let id = error.ErrorNumberText let emptyString = LocalizableString.op_Implicit("") let description = LocalizableString.op_Implicit(normalizedMessage) - let severity = if error.Severity = FSharpErrorSeverity.Error then DiagnosticSeverity.Error else DiagnosticSeverity.Warning + let severity = + match error.Severity with + | FSharpDiagnosticSeverity.Error -> DiagnosticSeverity.Error + | FSharpDiagnosticSeverity.Warning -> DiagnosticSeverity.Warning + | FSharpDiagnosticSeverity.Info -> DiagnosticSeverity.Info + | FSharpDiagnosticSeverity.Hidden -> DiagnosticSeverity.Hidden let customTags = match error.ErrorNumber with | 1182 -> FSharpDiagnosticCustomTags.Unnecessary @@ -171,7 +199,7 @@ module internal OpenDeclarationHelper = /// SourceText. /// Insertion context. Typically returned from tryGetInsertionContext /// Namespace to open. - let insertOpenDeclaration (sourceText: SourceText) (ctx: InsertContext) (ns: string) : SourceText * int = + let insertOpenDeclaration (sourceText: SourceText) (ctx: InsertionContext) (ns: string) : SourceText * int = let mutable minPos = None let insert line lineStr (sourceText: SourceText) : SourceText = @@ -186,20 +214,36 @@ module internal OpenDeclarationHelper = sourceText.WithChanges(TextChange(TextSpan(pos, 0), lineStr + lineBreak)) let getLineStr line = sourceText.Lines.[line].ToString().Trim() - let pos = ParsedInput.adjustInsertionPoint getLineStr ctx - let docLine = pos.Line - 1 + let pos = ParsedInput.AdjustInsertionPoint getLineStr ctx + let docLine = Line.toZ pos.Line let lineStr = (String.replicate pos.Column " ") + "open " + ns - let sourceText = sourceText |> insert docLine lineStr + + // If we're at the top of a file (e.g., F# script) then add a newline before adding the open declaration + let sourceText = + if docLine = 0 then + sourceText + |> insert docLine Environment.NewLine + |> insert docLine lineStr + else + sourceText |> insert docLine lineStr + // if there's no a blank line between open declaration block and the rest of the code, we add one let sourceText = if sourceText.Lines.[docLine + 1].ToString().Trim() <> "" then sourceText |> insert (docLine + 1) "" else sourceText + let sourceText = // for top level module we add a blank line between the module declaration and first open statement if (pos.Column = 0 || ctx.ScopeKind = ScopeKind.Namespace) && docLine > 0 && not (sourceText.Lines.[docLine - 1].ToString().Trim().StartsWith "open") then sourceText |> insert docLine "" else sourceText + sourceText, minPos |> Option.defaultValue 0 +[] +module internal TaggedText = + let toString (tts: TaggedText[]) = + tts |> Array.map (fun tt -> tt.Text) |> String.concat "" + diff --git a/vsintegration/src/FSharp.Editor/Common/Vs.fs b/vsintegration/src/FSharp.Editor/Common/Vs.fs index ee17ab8b381..7fd2095f855 100644 --- a/vsintegration/src/FSharp.Editor/Common/Vs.fs +++ b/vsintegration/src/FSharp.Editor/Common/Vs.fs @@ -15,19 +15,19 @@ module internal Com = ErrorHandler.ThrowOnFailure(hr) |> ignore let ThrowOnFailure1(hr,res) = - ErrorHandler.ThrowOnFailure(hr) |> ignore; + ErrorHandler.ThrowOnFailure(hr) |> ignore res let ThrowOnFailure2(hr,res1,res2) = - ErrorHandler.ThrowOnFailure(hr) |> ignore; + ErrorHandler.ThrowOnFailure(hr) |> ignore res1,res2 let ThrowOnFailure3(hr,res1,res2,res3) = - ErrorHandler.ThrowOnFailure(hr) |> ignore; + ErrorHandler.ThrowOnFailure(hr) |> ignore res1,res2,res3 let ThrowOnFailure4(hr,res1,res2,res3,res4) = - ErrorHandler.ThrowOnFailure(hr) |> ignore; + ErrorHandler.ThrowOnFailure(hr) |> ignore res1,res2,res3,res4 let Succeeded hr = diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs index 9ec89f069dd..353f9e4f39d 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs @@ -16,9 +16,11 @@ open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion open Microsoft.VisualStudio.Shell -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization module Logger = Microsoft.VisualStudio.FSharp.Editor.Logger @@ -26,34 +28,33 @@ type internal FSharpCompletionProvider ( workspace: Workspace, serviceProvider: SVsServiceProvider, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, assemblyContentProvider: AssemblyContentProvider ) = inherit CompletionProvider() - static let userOpName = "CompletionProvider" // Save the backing data in a cache, we need to save for at least the length of the completion session // See https://github.com/Microsoft/visualfsharp/issues/4714 - static let mutable declarationItems: FSharpDeclarationListItem[] = [||] + static let mutable declarationItems: DeclarationListItem[] = [||] static let [] NameInCodePropName = "NameInCode" static let [] FullNamePropName = "FullName" static let [] IsExtensionMemberPropName = "IsExtensionMember" static let [] NamespaceToOpenPropName = "NamespaceToOpen" - static let [] IsKeywordPropName = "IsKeyword" static let [] IndexPropName = "Index" + static let [] KeywordDescription = "KeywordDescription" static let keywordCompletionItems = - Keywords.KeywordsWithDescription - |> List.filter (fun (keyword, _) -> not (PrettyNaming.IsOperatorName keyword)) + FSharpKeywords.KeywordsWithDescription + |> List.filter (fun (keyword, _) -> not (PrettyNaming.IsOperatorDisplayName keyword)) |> List.sortBy (fun (keyword, _) -> keyword) |> List.mapi (fun n (keyword, description) -> - FSharpCommonCompletionItem.Create(keyword, null, CompletionItemRules.Default, Nullable Glyph.Keyword, sortText = sprintf "%06d" (1000000 + n)) - .AddProperty("description", description) - .AddProperty(IsKeywordPropName, "")) - - let checker = checkerProvider.Checker + FSharpCommonCompletionItem.Create( + displayText = keyword, + displayTextSuffix = "", + rules = CompletionItemRules.Default, + glyph = Nullable Glyph.Keyword, + sortText = sprintf "%06d" (1000000 + n)) + .AddProperty(KeywordDescription, description)) let settings: EditorOptions = workspace.Services.GetService() @@ -101,25 +102,23 @@ type internal FSharpCompletionProvider (triggerChar = '.' || (intelliSenseOptions.ShowAfterCharIsTyped && CompletionUtils.isStartingNewWord(sourceText, triggerPosition))) - static member ProvideCompletionsAsyncAux(checker: FSharpChecker, sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, filePath: string, - textVersionHash: int, getAllSymbols: FSharpCheckFileResults -> AssemblySymbol list, languageServicePerformanceOptions: LanguageServicePerformanceOptions, intellisenseOptions: IntelliSenseOptions) = - asyncMaybe { - let! parseResults, _, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText, options, languageServicePerformanceOptions, userOpName = userOpName) + static member ProvideCompletionsAsyncAux(document: Document, caretPosition: int, getAllSymbols: FSharpCheckFileResults -> AssemblySymbol list, intellisenseOptions: IntelliSenseOptions) = + asyncMaybe { + let! parseResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync("ProvideCompletionsAsyncAux") |> liftAsync + let! sourceText = document.GetTextAsync() let textLines = sourceText.Lines let caretLinePos = textLines.GetLinePosition(caretPosition) let caretLine = textLines.GetLineFromPosition(caretPosition) let fcsCaretLineNumber = Line.fromZ caretLinePos.Line // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based let caretLineColumn = caretLinePos.Character - let partialName = QuickParse.GetPartialLongNameEx(caretLine.ToString(), caretLineColumn - 1) - + let line = caretLine.ToString() + let partialName = QuickParse.GetPartialLongNameEx(line, caretLineColumn - 1) let getAllSymbols() = getAllSymbols checkFileResults - |> List.filter (fun assemblySymbol -> - assemblySymbol.FullName.Contains "." && not (PrettyNaming.IsOperatorName assemblySymbol.Symbol.DisplayName)) - - let! declarations = checkFileResults.GetDeclarationListInfo(Some(parseResults), fcsCaretLineNumber, caretLine.ToString(), - partialName, getAllSymbols, userOpName=userOpName) |> liftAsync + |> List.filter (fun assemblySymbol -> + assemblySymbol.FullName.Contains "." && not (PrettyNaming.IsOperatorDisplayName assemblySymbol.Symbol.DisplayName)) + let declarations = checkFileResults.GetDeclarationListInfo(Some(parseResults), fcsCaretLineNumber, line, partialName, getAllSymbols) let results = List() declarationItems <- @@ -139,10 +138,10 @@ type internal FSharpCompletionProvider declarationItems |> Array.iteri (fun number declarationItem -> let glyph = Tokenizer.FSharpGlyphToRoslynGlyph (declarationItem.Glyph, declarationItem.Accessibility) - let name = + let namespaceName = match declarationItem.NamespaceToOpen with - | Some namespaceToOpen -> sprintf "%s (open %s)" declarationItem.Name namespaceToOpen - | _ -> declarationItem.Name + | Some namespaceToOpen -> namespaceToOpen + | _ -> null // Icky, but this is how roslyn handles it let filterText = match declarationItem.NamespaceToOpen, declarationItem.Name.Split '.' with @@ -153,8 +152,14 @@ type internal FSharpCompletionProvider | _, idents -> Array.last idents let completionItem = - FSharpCommonCompletionItem.Create(name, null, rules = getRules intellisenseOptions.ShowAfterCharIsTyped, glyph = Nullable glyph, filterText = filterText) - .AddProperty(FullNamePropName, declarationItem.FullName) + FSharpCommonCompletionItem.Create( + declarationItem.Name, + null, + rules = getRules intellisenseOptions.ShowAfterCharIsTyped, + glyph = Nullable glyph, + filterText = filterText, + inlineDescription = namespaceName) + .AddProperty(FullNamePropName, declarationItem.FullName) let completionItem = match declarationItem.Kind with @@ -163,7 +168,7 @@ type internal FSharpCompletionProvider | _ -> completionItem let completionItem = - if name <> declarationItem.NameInCode then + if declarationItem.Name <> declarationItem.NameInCode then completionItem.AddProperty(NameInCodePropName, declarationItem.NameInCode) else completionItem @@ -183,14 +188,10 @@ type internal FSharpCompletionProvider let completionItem = completionItem.WithSortText(sortText) results.Add(completionItem)) + if results.Count > 0 && not declarations.IsForType && not declarations.IsError && List.isEmpty partialName.QualifyingIdents then - let lineStr = textLines.[caretLinePos.Line].ToString() - - let completionContext = - parseResults.ParseTree - |> Option.bind (fun parseTree -> - UntypedParseImpl.TryGetCompletionContext(Pos.fromZ caretLinePos.Line caretLinePos.Character, parseTree, lineStr)) - + let completionContext = ParsedInput.TryGetCompletionContext(Position.fromZ caretLinePos.Line caretLinePos.Character, parseResults.ParseTree, line) + match completionContext with | None -> results.AddRange(keywordCompletionItems) | _ -> () @@ -198,39 +199,34 @@ type internal FSharpCompletionProvider return results } - override this.ShouldTriggerCompletion(sourceText: SourceText, caretPosition: int, trigger: CompletionTrigger, _: OptionSet) = + override _.ShouldTriggerCompletion(sourceText: SourceText, caretPosition: int, trigger: CompletionTrigger, _: OptionSet) = use _logBlock = Logger.LogBlock LogEditorFunctionId.Completion_ShouldTrigger let getInfo() = let documentId = workspace.GetDocumentIdInCurrentContext(sourceText.Container) let document = workspace.CurrentSolution.GetDocument(documentId) - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + let defines = document.GetFSharpQuickDefines() (documentId, document.FilePath, defines) FSharpCompletionProvider.ShouldTriggerCompletionAux(sourceText, caretPosition, trigger.Kind, getInfo, settings.IntelliSense) - override this.ProvideCompletionsAsync(context: Completion.CompletionContext) = + override _.ProvideCompletionsAsync(context: Completion.CompletionContext) = asyncMaybe { use _logBlock = Logger.LogBlockMessage context.Document.Name LogEditorFunctionId.Completion_ProvideCompletionsAsync - let document = context.Document let! sourceText = context.Document.GetTextAsync(context.CancellationToken) - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + let defines = document.GetFSharpQuickDefines() do! Option.guard (CompletionUtils.shouldProvideCompletion(document.Id, document.FilePath, defines, sourceText, context.Position)) - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, context.CancellationToken) - let! textVersion = context.Document.GetTextVersionAsync(context.CancellationToken) let getAllSymbols(fileCheckResults: FSharpCheckFileResults) = if settings.IntelliSense.IncludeSymbolsFromUnopenedNamespacesOrModules then assemblyContentProvider.GetAllEntitiesInProjectAndReferencedAssemblies(fileCheckResults) else [] let! results = - FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, sourceText, context.Position, projectOptions, document.FilePath, - textVersion.GetHashCode(), getAllSymbols, settings.LanguageServicePerformance, settings.IntelliSense) - + FSharpCompletionProvider.ProvideCompletionsAsyncAux(context.Document, context.Position, getAllSymbols, settings.IntelliSense) context.AddItems(results) } |> Async.Ignore |> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken - - override this.GetDescriptionAsync(document: Document, completionItem: Completion.CompletionItem, cancellationToken: CancellationToken): Task = + + override _.GetDescriptionAsync(document: Document, completionItem: Completion.CompletionItem, cancellationToken: CancellationToken): Task = async { use _logBlock = Logger.LogBlockMessage document.Name LogEditorFunctionId.Completion_GetDescriptionAsync match completionItem.Properties.TryGetValue IndexPropName with @@ -238,19 +234,24 @@ type internal FSharpCompletionProvider let completionItemIndex = int completionItemIndexStr if completionItemIndex < declarationItems.Length then let declarationItem = declarationItems.[completionItemIndex] - let! description = declarationItem.StructuredDescriptionTextAsync + let description = declarationItem.Description let documentation = List() let collector = RoslynHelpers.CollectTaggedText documentation // mix main description and xmldoc by using one collector XmlDocumentation.BuildDataTipText(documentationBuilder, collector, collector, collector, collector, collector, description) return CompletionDescription.Create(documentation.ToImmutableArray()) - else + else + return CompletionDescription.Empty + | _ -> + // Try keyword descriptions if they exist + match completionItem.Properties.TryGetValue KeywordDescription with + | true, keywordDescription -> + return CompletionDescription.FromText(keywordDescription) + | false, _ -> return CompletionDescription.Empty - | _ -> - return CompletionDescription.Empty } |> RoslynHelpers.StartAsyncAsTask cancellationToken - override this.GetChangeAsync(document, item, _, cancellationToken) : Task = + override _.GetChangeAsync(document, item, _, cancellationToken) : Task = async { use _logBlock = Logger.LogBlockMessage document.Name LogEditorFunctionId.Completion_GetChangeAsync @@ -259,9 +260,8 @@ type internal FSharpCompletionProvider | true, x -> Some x | _ -> None - // do not add extension members, keywords and not yet resolved symbols to the MRU list - if not (item.Properties.ContainsKey NamespaceToOpenPropName) && not (item.Properties.ContainsKey IsExtensionMemberPropName) && - not (item.Properties.ContainsKey IsKeywordPropName) then + // do not add extension members and unresolved symbols to the MRU list + if not (item.Properties.ContainsKey NamespaceToOpenPropName) && not (item.Properties.ContainsKey IsExtensionMemberPropName) then match fullName with | Some fullName -> match mruItems.TryGetValue fullName with @@ -283,15 +283,14 @@ type internal FSharpCompletionProvider let! sourceText = document.GetTextAsync(cancellationToken) let textWithItemCommitted = sourceText.WithChanges(TextChange(item.Span, nameInCode)) let line = sourceText.Lines.GetLineFromPosition(item.Span.Start) - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let! parsedInput = checker.ParseDocument(document, parsingOptions, sourceText, userOpName) + let! parseResults = document.GetFSharpParseResultsAsync(nameof(FSharpCompletionProvider)) |> liftAsync let fullNameIdents = fullName |> Option.map (fun x -> x.Split '.') |> Option.defaultValue [||] let insertionPoint = if settings.CodeFixes.AlwaysPlaceOpensAtTopLevel then OpenStatementInsertionPoint.TopLevel else OpenStatementInsertionPoint.Nearest - let ctx = ParsedInput.findNearestPointToInsertOpenDeclaration line.LineNumber parsedInput fullNameIdents insertionPoint + let ctx = ParsedInput.FindNearestPointToInsertOpenDeclaration line.LineNumber parseResults.ParseTree fullNameIdents insertionPoint let finalSourceText, changedSpanStartPos = OpenDeclarationHelper.insertOpenDeclaration textWithItemCommitted ctx ns let fullChangingSpan = TextSpan.FromBounds(changedSpanStartPos, item.Span.End) let changedSpan = TextSpan.FromBounds(changedSpanStartPos, item.Span.End + (finalSourceText.Length - sourceText.Length)) diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionService.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionService.fs index 6303e2498d2..ccdadf504f7 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionService.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionService.fs @@ -17,25 +17,21 @@ type internal FSharpCompletionService ( workspace: Workspace, serviceProvider: SVsServiceProvider, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, assemblyContentProvider: AssemblyContentProvider, settings: EditorOptions ) = inherit CompletionServiceWithProviders(workspace) + let projectInfoManager = workspace.Services.GetRequiredService().FSharpProjectOptionsManager + let builtInProviders = ImmutableArray.Create( - FSharpCompletionProvider(workspace, serviceProvider, checkerProvider, projectInfoManager, assemblyContentProvider), - FSharpCommonCompletionProvider.Create( - HashDirectiveCompletionProvider(workspace, projectInfoManager, - [ Completion.Create("""\s*#load\s+(@?"*(?"[^"]*"?))""", [".fs"; ".fsx"], useIncludeDirectives = true) - Completion.Create("""\s*#r\s+(@?"*(?"[^"]*"?))""", [".dll"; ".exe"], useIncludeDirectives = true) - Completion.Create("""\s*#I\s+(@?"*(?"[^"]*"?))""", ["\x00"], useIncludeDirectives = false) ]))) + FSharpCompletionProvider(workspace, serviceProvider, assemblyContentProvider), + FSharpCommonCompletionProvider.Create(HashDirectiveCompletionProvider.Create(workspace, projectInfoManager))) - override this.Language = FSharpConstants.FSharpLanguageName - override this.GetBuiltInProviders() = builtInProviders - override this.GetRules() = + override _.Language = FSharpConstants.FSharpLanguageName + override _.GetBuiltInProviders() = builtInProviders + override _.GetRules() = let enterKeyRule = match settings.IntelliSense.EnterKeySetting with | NeverNewline -> EnterKeyRule.Never @@ -47,19 +43,24 @@ type internal FSharpCompletionService .WithDismissIfLastCharacterDeleted(true) .WithDefaultEnterKeyRule(enterKeyRule) + /// Indicates the text span to be replaced by a committed completion list item. + override _.GetDefaultCompletionListSpan(sourceText, caretIndex) = + let documentId = workspace.GetDocumentIdInCurrentContext(sourceText.Container) + let document = workspace.CurrentSolution.GetDocument(documentId) + let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + CompletionUtils.getDefaultCompletionListSpan(sourceText, caretIndex, documentId, document.FilePath, defines) + [] [, FSharpConstants.FSharpLanguageName)>] type internal FSharpCompletionServiceFactory [] ( serviceProvider: SVsServiceProvider, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager, assemblyContentProvider: AssemblyContentProvider, settings: EditorOptions ) = interface ILanguageServiceFactory with - member this.CreateLanguageService(hostLanguageServices: HostLanguageServices) : ILanguageService = - upcast new FSharpCompletionService(hostLanguageServices.WorkspaceServices.Workspace, serviceProvider, checkerProvider, projectInfoManager, assemblyContentProvider, settings) + member _.CreateLanguageService(hostLanguageServices: HostLanguageServices) : ILanguageService = + upcast new FSharpCompletionService(hostLanguageServices.WorkspaceServices.Workspace, serviceProvider, assemblyContentProvider, settings) diff --git a/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs b/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs index 5d210d5f363..48ddb9ce974 100644 --- a/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs +++ b/vsintegration/src/FSharp.Editor/Completion/CompletionUtils.fs @@ -7,10 +7,10 @@ open System.Threading open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Classification open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.Completion open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion open System.Globalization -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax.PrettyNaming module internal CompletionUtils = @@ -89,7 +89,8 @@ module internal CompletionUtils = let triggerLine = textLines.GetLineFromPosition triggerPosition let classifiedSpans = Tokenizer.getClassifiedSpans(documentId, sourceText, triggerLine.Span, Some filePath, defines, CancellationToken.None) classifiedSpans.Count = 0 || // we should provide completion at the start of empty line, where there are no tokens at all - classifiedSpans.Exists (fun classifiedSpan -> + let result = + classifiedSpans.Exists (fun classifiedSpan -> classifiedSpan.TextSpan.IntersectsWith triggerPosition && ( match classifiedSpan.ClassificationType with @@ -100,6 +101,7 @@ module internal CompletionUtils = | ClassificationTypeNames.NumericLiteral -> false | _ -> true // anything else is a valid classification type )) + result let inline getKindPriority kind = match kind with @@ -110,4 +112,59 @@ module internal CompletionUtils = | CompletionItemKind.Event -> 4 | CompletionItemKind.Argument -> 5 | CompletionItemKind.Other -> 6 - | CompletionItemKind.Method (isExtension = true) -> 7 \ No newline at end of file + | CompletionItemKind.Method (isExtension = true) -> 7 + + /// Indicates the text span to be replaced by a committed completion list item. + let getDefaultCompletionListSpan(sourceText: SourceText, caretIndex, documentId, filePath, defines) = + + // Gets connected identifier-part characters backward and forward from caret. + let getIdentifierChars() = + let mutable startIndex = caretIndex + let mutable endIndex = caretIndex + while startIndex > 0 && IsIdentifierPartCharacter sourceText.[startIndex - 1] do startIndex <- startIndex - 1 + if startIndex <> caretIndex then + while endIndex < sourceText.Length && IsIdentifierPartCharacter sourceText.[endIndex] do endIndex <- endIndex + 1 + TextSpan.FromBounds(startIndex, endIndex) + + let line = sourceText.Lines.GetLineFromPosition(caretIndex) + if line.ToString().IndexOf "``" < 0 then + // No backticks on the line, capture standard identifier chars. + getIdentifierChars() + else + // Line contains backticks. + // Use tokenizer to check for identifier, in order to correctly handle extraneous backticks in comments, strings, etc. + + // If caret is at a backtick-identifier, then that is our span. + + // Else, check if we are after an unclosed ``, to support the common case of a manually typed leading ``. + // Tokenizer will not consider this an identifier, it will consider the bare `` a Keyword, followed by + // arbitrary tokens (Identifier, Operator, Text, etc.) depending on the trailing text. + + // Else, backticks are not involved in caret location, fall back to standard identifier character scan. + + // There may still be edge cases where backtick related spans are incorrectly captured, such as unclosed + // backticks before later valid backticks on a line, this is an acceptable compromise in order to support + // the majority of common cases. + + let classifiedSpans = Tokenizer.getClassifiedSpans(documentId, sourceText, line.Span, Some filePath, defines, CancellationToken.None) + + let isBacktickIdentifier (classifiedSpan: ClassifiedSpan) = + classifiedSpan.ClassificationType = ClassificationTypeNames.Identifier + && Tokenizer.isDoubleBacktickIdent (sourceText.ToString(classifiedSpan.TextSpan)) + let isUnclosedBacktick (classifiedSpan: ClassifiedSpan) = + classifiedSpan.ClassificationType = ClassificationTypeNames.Keyword + && sourceText.ToString(classifiedSpan.TextSpan) = "``" + + match classifiedSpans |> Seq.tryFind (fun cs -> isBacktickIdentifier cs && cs.TextSpan.IntersectsWith caretIndex) with + | Some backtickIdentifier -> + // Backtick enclosed identifier found intersecting with caret, use its span. + backtickIdentifier.TextSpan + | _ -> + match classifiedSpans |> Seq.tryFindBack (fun cs -> isUnclosedBacktick cs && caretIndex >= cs.TextSpan.Start) with + | Some unclosedBacktick -> + // Unclosed backtick found before caret, use span from backtick to end of line. + let lastSpan = classifiedSpans.[classifiedSpans.Count - 1] + TextSpan.FromBounds(unclosedBacktick.TextSpan.Start, lastSpan.TextSpan.End) + | _ -> + // No backticks involved at caret position, fall back to standard identifier chars. + getIdentifierChars() diff --git a/vsintegration/src/FSharp.Editor/Completion/FileSystemCompletion.fs b/vsintegration/src/FSharp.Editor/Completion/FileSystemCompletion.fs deleted file mode 100644 index d8028425009..00000000000 --- a/vsintegration/src/FSharp.Editor/Completion/FileSystemCompletion.fs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Microsoft.VisualStudio.FSharp.Editor - -open System -open System.Text.RegularExpressions -open System.IO -open System.Collections.Immutable -open System.Threading -open System.Threading.Tasks -open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Completion -open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.Classification -open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion - -type internal Completion = - { DirectiveRegex: Regex - AllowableExtensions: string list - UseIncludeDirectives: bool } - static member Create(directiveRegex, allowableExtensions, useIncludeDirectives) = - { DirectiveRegex = Regex(directiveRegex, RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) - AllowableExtensions = allowableExtensions - UseIncludeDirectives = useIncludeDirectives } - -type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoManager: FSharpProjectOptionsManager, completions: Completion list) = - - let [] NetworkPath = "\\\\" - let commitRules = ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, '"', '\\', ',', '/')) - let rules = CompletionItemRules.Create(commitCharacterRules = commitRules) - - let getQuotedPathStart(text: SourceText, position: int, quotedPathGroup: Group) = - text.Lines.GetLineFromPosition(position).Start + quotedPathGroup.Index - - let getPathThroughLastSlash(text: SourceText, position: int, quotedPathGroup: Group) = - PathCompletionUtilities.GetPathThroughLastSlash( - quotedPathGroup.Value, - getQuotedPathStart(text, position, quotedPathGroup), - position) - - let getFileGlyph (extention: string) = - match extention with - | ".exe" | ".dll" -> Some Glyph.Assembly - | _ -> None - - let includeDirectiveCleanRegex = Regex("""#I\s+(@?"*(?[^"]*)"?)""", RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) - - let getClassifiedSpans(text: SourceText, position: int) : ResizeArray = - let documentId = workspace.GetDocumentIdInCurrentContext(text.Container) - let document = workspace.CurrentSolution.GetDocument(documentId) - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) - let textLines = text.Lines - let triggerLine = textLines.GetLineFromPosition(position) - Tokenizer.getClassifiedSpans(documentId, text, triggerLine.Span, Some document.FilePath, defines, CancellationToken.None) - - let isInStringLiteral(text: SourceText, position: int) : bool = - getClassifiedSpans(text, position) - |> Seq.exists(fun classifiedSpan -> - classifiedSpan.TextSpan.IntersectsWith position && - classifiedSpan.ClassificationType = ClassificationTypeNames.StringLiteral) - - let getIncludeDirectives (text: SourceText, position: int) = - let lines = text.Lines - let caretLine = text.Lines.GetLinePosition(position).Line - lines - |> Seq.filter (fun x -> x.LineNumber < caretLine) - |> Seq.choose (fun line -> - let lineStr = line.ToString().Trim() - // optimization: fail fast if the line does not start with "(optional spaces) #I" - if not (lineStr.StartsWith "#I") then None - else - match includeDirectiveCleanRegex.Match lineStr with - | m when m.Success -> - getClassifiedSpans(text, line.Start) - |> Seq.tryPick (fun span -> - if span.TextSpan.IntersectsWith line.Start && - (span.ClassificationType <> ClassificationTypeNames.Comment && - span.ClassificationType <> ClassificationTypeNames.ExcludedCode) then - Some (m.Groups.["literal"].Value) - else None) - | _ -> None - ) - |> Seq.toList - - interface IFSharpCommonCompletionProvider with - - member this.ProvideCompletionsAsync(context) = - asyncMaybe { - let document = context.Document - let position = context.Position - do! let extension = Path.GetExtension document.FilePath - Option.guard (extension = ".fsx" || extension = ".fsscript") - - let! ct = liftAsync Async.CancellationToken - let! text = document.GetTextAsync(ct) - do! Option.guard (isInStringLiteral(text, position)) - let line = text.Lines.GetLineFromPosition(position) - let lineText = text.ToString(TextSpan.FromBounds(line.Start, position)) - - let! completion, quotedPathGroup = - completions |> List.tryPick (fun completion -> - match completion.DirectiveRegex.Match lineText with - | m when m.Success -> - let quotedPathGroup = m.Groups.["literal"] - let endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPathGroup.Value) - if endsWithQuote && (position >= line.Start + m.Length) then - None - else - Some (completion, quotedPathGroup) - | _ -> None) - - let snapshot = text.FindCorrespondingEditorTextSnapshot() - - do! Option.guard (not (isNull snapshot)) - - let extraSearchPaths = - if completion.UseIncludeDirectives then - getIncludeDirectives (text, position) - else [] - - let defaultSearchPath = Path.GetDirectoryName document.FilePath - let searchPaths = defaultSearchPath :: extraSearchPaths - - let helper = - FSharpFileSystemCompletionHelper( - Glyph.OpenFolder, - completion.AllowableExtensions |> List.tryPick getFileGlyph |> Option.defaultValue Glyph.None, - Seq.toImmutableArray searchPaths, - null, - completion.AllowableExtensions |> Seq.toImmutableArray, - rules) - - let pathThroughLastSlash = getPathThroughLastSlash(text, position, quotedPathGroup) - let! items = helper.GetItemsAsync(pathThroughLastSlash, ct) |> Async.AwaitTask |> liftAsync - context.AddItems(items) - } - |> Async.Ignore - |> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken - - member __.IsInsertionTrigger(text, position, _) = - // Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash - // path separator character, or if they type a comma (#r "foo,version..."). - // Also, if they're starting a word. i.e. #r "c:\W - let ch = text.[position] - let isTriggerChar = - ch = '"' || ch = '\\' || ch = ',' || ch = '/' || - FSharpCommonCompletionUtilities.IsStartingNewWord(text, position, (fun x -> Char.IsLetter x), (fun x -> Char.IsLetterOrDigit x)) - isTriggerChar && isInStringLiteral(text, position) - - member __.GetTextChangeAsync(baseGetTextChangeAsync, selectedItem, ch, cancellationToken) = - // When we commit "\\" when the user types \ we have to adjust for the fact that the - // controller will automatically append \ after we commit. Because of that, we don't - // want to actually commit "\\" as we'll end up with "\\\". So instead we just commit - // "\" and know that controller will append "\" and give us "\\". - if selectedItem.DisplayText = NetworkPath && ch = Nullable '\\' then - Task.FromResult(Nullable(TextChange(selectedItem.Span, "\\"))) - else - baseGetTextChangeAsync.Invoke(selectedItem, ch, cancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Completion/HashDirectiveCompletionProvider.fs b/vsintegration/src/FSharp.Editor/Completion/HashDirectiveCompletionProvider.fs new file mode 100644 index 00000000000..26ed5f76115 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/Completion/HashDirectiveCompletionProvider.fs @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor + +open System +open System.Text.RegularExpressions +open System.IO +open System.Collections.Immutable +open System.Threading +open System.Threading.Tasks +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.Completion +open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.Classification +open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Completion + +type internal HashCompletion = + { DirectiveRegex: Regex + AllowableExtensions: string list + UseIncludeDirectives: bool } + static member Create(directiveRegex, allowableExtensions, useIncludeDirectives) = + { DirectiveRegex = Regex(directiveRegex, RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) + AllowableExtensions = allowableExtensions + UseIncludeDirectives = useIncludeDirectives } + +type internal HashDirectiveCompletionProvider(workspace: Workspace, projectInfoManager: FSharpProjectOptionsManager, completions: HashCompletion list) = + + let [] NetworkPath = "\\\\" + let commitRules = ImmutableArray.Create(CharacterSetModificationRule.Create(CharacterSetModificationKind.Replace, '"', '\\', ',', '/')) + let rules = CompletionItemRules.Create(commitCharacterRules = commitRules) + + let getQuotedPathStart(text: SourceText, position: int, quotedPathGroup: Group) = + text.Lines.GetLineFromPosition(position).Start + quotedPathGroup.Index + + let getPathThroughLastSlash(text: SourceText, position: int, quotedPathGroup: Group) = + PathCompletionUtilities.GetPathThroughLastSlash( + quotedPathGroup.Value, + getQuotedPathStart(text, position, quotedPathGroup), + position) + + let getFileGlyph (extention: string) = + match extention with + | ".exe" | ".dll" -> Some Glyph.Assembly + | _ -> None + + let includeDirectiveCleanRegex = Regex("""#I\s+(@?"*(?[^"]*)"?)""", RegexOptions.Compiled ||| RegexOptions.ExplicitCapture) + + let getClassifiedSpans(text: SourceText, position: int) : ResizeArray = + let documentId = workspace.GetDocumentIdInCurrentContext(text.Container) + let document = workspace.CurrentSolution.GetDocument(documentId) + let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + let textLines = text.Lines + let triggerLine = textLines.GetLineFromPosition(position) + Tokenizer.getClassifiedSpans(documentId, text, triggerLine.Span, Some document.FilePath, defines, CancellationToken.None) + + let isInStringLiteral(text: SourceText, position: int) : bool = + getClassifiedSpans(text, position) + |> Seq.exists(fun classifiedSpan -> + classifiedSpan.TextSpan.IntersectsWith position && + classifiedSpan.ClassificationType = ClassificationTypeNames.StringLiteral) + + let getIncludeDirectives (text: SourceText, position: int) = + let lines = text.Lines + let caretLine = text.Lines.GetLinePosition(position).Line + lines + |> Seq.filter (fun x -> x.LineNumber < caretLine) + |> Seq.choose (fun line -> + let lineStr = line.ToString().Trim() + // optimization: fail fast if the line does not start with "(optional spaces) #I" + if not (lineStr.StartsWith "#I") then None + else + match includeDirectiveCleanRegex.Match lineStr with + | m when m.Success -> + getClassifiedSpans(text, line.Start) + |> Seq.tryPick (fun span -> + if span.TextSpan.IntersectsWith line.Start && + (span.ClassificationType <> ClassificationTypeNames.Comment && + span.ClassificationType <> ClassificationTypeNames.ExcludedCode) then + Some (m.Groups.["literal"].Value) + else None) + | _ -> None + ) + |> Seq.toList + + static member Create(workspace: Workspace, projectInfoManager: FSharpProjectOptionsManager) = + let completions = + [ + HashCompletion.Create("""\s*#load\s+(@?"*(?"[^"]*"?))""", [ ".fs"; ".fsx" ], useIncludeDirectives = true) + HashCompletion.Create("""\s*#r\s+(@?"*(?"[^"]*"?))""", [ ".dll"; ".exe" ], useIncludeDirectives = true) + HashCompletion.Create("""\s*#I\s+(@?"*(?"[^"]*"?))""", [ "\x00" ], useIncludeDirectives = false) + ] + HashDirectiveCompletionProvider(workspace, projectInfoManager, completions) + + interface IFSharpCommonCompletionProvider with + + member _.ProvideCompletionsAsync(context) = + asyncMaybe { + let document = context.Document + let position = context.Position + do! let extension = Path.GetExtension document.FilePath + Option.guard (extension = ".fsx" || extension = ".fsscript") + + let! ct = liftAsync Async.CancellationToken + let! text = document.GetTextAsync(ct) + do! Option.guard (isInStringLiteral(text, position)) + let line = text.Lines.GetLineFromPosition(position) + let lineText = text.ToString(TextSpan.FromBounds(line.Start, position)) + + let! completion, quotedPathGroup = + completions |> List.tryPick (fun completion -> + match completion.DirectiveRegex.Match lineText with + | m when m.Success -> + let quotedPathGroup = m.Groups.["literal"] + let endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPathGroup.Value) + if endsWithQuote && (position >= line.Start + m.Length) then + None + else + Some (completion, quotedPathGroup) + | _ -> None) + + let snapshot = text.FindCorrespondingEditorTextSnapshot() + + do! Option.guard (not (isNull snapshot)) + + let extraSearchPaths = + if completion.UseIncludeDirectives then + getIncludeDirectives (text, position) + else [] + + let defaultSearchPath = Path.GetDirectoryName document.FilePath + let searchPaths = defaultSearchPath :: extraSearchPaths + + let helper = + FSharpFileSystemCompletionHelper( + Glyph.OpenFolder, + completion.AllowableExtensions |> List.tryPick getFileGlyph |> Option.defaultValue Glyph.None, + Seq.toImmutableArray searchPaths, + null, + completion.AllowableExtensions |> Seq.toImmutableArray, + rules) + + let pathThroughLastSlash = getPathThroughLastSlash(text, position, quotedPathGroup) + let! items = helper.GetItemsAsync(pathThroughLastSlash, ct) |> Async.AwaitTask |> liftAsync + context.AddItems(items) + } + |> Async.Ignore + |> RoslynHelpers.StartAsyncUnitAsTask context.CancellationToken + + member _.IsInsertionTrigger(text, position, _) = + // Bring up completion when the user types a quote (i.e.: #r "), or if they type a slash + // path separator character, or if they type a comma (#r "foo,version..."). + // Also, if they're starting a word. i.e. #r "c:\W + let ch = text.[position] + let isTriggerChar = + ch = '"' || ch = '\\' || ch = ',' || ch = '/' || + FSharpCommonCompletionUtilities.IsStartingNewWord(text, position, (fun x -> Char.IsLetter x), (fun x -> Char.IsLetterOrDigit x)) + isTriggerChar && isInStringLiteral(text, position) + + member _.GetTextChangeAsync(baseGetTextChangeAsync, selectedItem, ch, cancellationToken) = + // When we commit "\\" when the user types \ we have to adjust for the fact that the + // controller will automatically append \ after we commit. Because of that, we don't + // want to actually commit "\\" as we'll end up with "\\\". So instead we just commit + // "\" and know that controller will append "\" and give us "\\". + if selectedItem.DisplayText = NetworkPath && ch = Nullable '\\' then + Task.FromResult(Nullable(TextChange(selectedItem.Span, "\\"))) + else + baseGetTextChangeAsync.Invoke(selectedItem, ch, cancellationToken) \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Completion/PathCompletionUtilities.fs b/vsintegration/src/FSharp.Editor/Completion/PathCompletionUtilities.fs index e2dc84e64e7..737bffb7553 100644 --- a/vsintegration/src/FSharp.Editor/Completion/PathCompletionUtilities.fs +++ b/vsintegration/src/FSharp.Editor/Completion/PathCompletionUtilities.fs @@ -6,6 +6,7 @@ open System open System.IO module PathCompletionUtilities = + let GetPathThroughLastSlash(quotedPath: string, quotedPathStart: int, position: int) = let quoteLength = "\"".Length let positionInQuotedPath = position - quotedPathStart @@ -15,5 +16,6 @@ module PathCompletionUtilities = let index = path.LastIndexOf(Path.DirectorySeparatorChar, position) if index >= 0 then index + 1 else -1 if afterLastSlashIndex >= 0 then path.Substring(0, afterLastSlashIndex) else path + let EndsWithQuote(quotedPath: string) = quotedPath.Length >= 2 && quotedPath.[quotedPath.Length - 1] = '"' diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs index cde4f1d22dd..c7c521400eb 100644 --- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs @@ -4,221 +4,630 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System open System.Composition -open System.Collections.Generic open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.SignatureHelp open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.SignatureHelp -open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.Shell -open Microsoft.VisualStudio.Shell.Interop -open FSharp.Compiler.Layout -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open FSharp.Compiler.Text.Range +open FSharp.Compiler.Tokenization + +type SignatureHelpParameterInfo = + { ParameterName: string + IsOptional: bool + CanonicalTypeTextForSorting: string + Documentation: ResizeArray + DisplayParts: ResizeArray } + +type SignatureHelpItem = + { HasParamArrayArg: bool + Documentation: ResizeArray + PrefixParts: RoslynTaggedText[] + SeparatorParts: RoslynTaggedText[] + SuffixParts: RoslynTaggedText[] + Parameters: SignatureHelpParameterInfo[] + MainDescription: ResizeArray } + +type CurrentSignatureHelpSessionKind = + | FunctionApplication + | MethodCall + +type SignatureHelpData = + { SignatureHelpItems: SignatureHelpItem[] + ApplicableSpan: TextSpan + ArgumentIndex: int + ArgumentCount: int + ArgumentName: string option + CurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind } [] [)>] type internal FSharpSignatureHelpProvider [] ( - serviceProvider: SVsServiceProvider, - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager + serviceProvider: SVsServiceProvider ) = - static let userOpName = "SignatureHelpProvider" let documentationBuilder = XmlDocumentation.CreateDocumentationBuilder(serviceProvider.XMLMemberIndexService) static let oneColAfter (lp: LinePosition) = LinePosition(lp.Line,lp.Character+1) static let oneColBefore (lp: LinePosition) = LinePosition(lp.Line,max 0 (lp.Character-1)) - // Unit-testable core routine - static member internal ProvideMethodsAsyncAux(checker: FSharpChecker, documentationBuilder: IDocumentationBuilder, sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, triggerIsTypedChar: char option, filePath: string, textVersionHash: int) = async { - let! parseResults, checkFileAnswer = checker.ParseAndCheckFileInProject(filePath, textVersionHash, sourceText.ToFSharpSourceText(), options, userOpName = userOpName) - match checkFileAnswer with - | FSharpCheckFileAnswer.Aborted -> return None - | FSharpCheckFileAnswer.Succeeded(checkFileResults) -> - - let textLines = sourceText.Lines - let caretLinePos = textLines.GetLinePosition(caretPosition) - let caretLineColumn = caretLinePos.Character - - // Get the parameter locations - let paramLocations = parseResults.FindNoteworthyParamInfoLocations(Pos.fromZ caretLinePos.Line caretLineColumn) - - match paramLocations with - | None -> return None // no locations = no help - | Some nwpl -> - let names = nwpl.LongId - let lidEnd = nwpl.LongIdEndLocation - - // Get the methods - let! methodGroup = checkFileResults.GetMethods(lidEnd.Line, lidEnd.Column, "", Some names) - - let methods = methodGroup.Methods - - if (methods.Length = 0 || methodGroup.MethodName.EndsWith("> )")) then return None else - - let isStaticArgTip = - let parenLine, parenCol = Pos.toZ nwpl.OpenParenLocation - assert (parenLine < textLines.Count) - let parenLineText = textLines.[parenLine].ToString() - parenCol < parenLineText.Length && parenLineText.[parenCol] = '<' - - let filteredMethods = - [| for m in methods do - if (isStaticArgTip && m.StaticParameters.Length > 0) || - (not isStaticArgTip && m.HasParameters) then // need to distinguish TP<...>(...) angle brackets tip from parens tip - yield m |] - - if filteredMethods.Length = 0 then return None else - - let posToLinePosition pos = - let (l,c) = Pos.toZ pos - // FSROSLYNTODO: FCS gives back line counts that are too large. Really, this shouldn't happen - let result =LinePosition(l,c) - let lastPosInDocument = textLines.GetLinePosition(textLines.[textLines.Count-1].End) - if lastPosInDocument.CompareTo(result) > 0 then result else lastPosInDocument - - // Compute the start position - let startPos = nwpl.LongIdStartLocation |> posToLinePosition - - // Compute the end position - let endPos = - let last = nwpl.TupleEndLocations.[nwpl.TupleEndLocations.Length-1] |> posToLinePosition - (if nwpl.IsThereACloseParen then oneColBefore last else last) - - assert (startPos.CompareTo(endPos) <= 0) - - // Compute the applicable span between the parentheses - let applicableSpan = - textLines.GetTextSpan(LinePositionSpan(startPos, endPos)) - - let startOfArgs = nwpl.OpenParenLocation |> posToLinePosition |> oneColAfter - - let tupleEnds = - [| yield startOfArgs - for i in 0..nwpl.TupleEndLocations.Length-2 do - yield nwpl.TupleEndLocations.[i] |> posToLinePosition - yield endPos |] - - // If we are pressing "(" or "<" or ",", then only pop up the info if this is one of the actual, real detected positions in the detected promptable call - // - // For example the last "(" in - // List.map (fun a -> ( - // should not result in a prompt. - // - // Likewise the last "," in - // Console.WriteLine( [(1, - // should not result in a prompt, whereas this one will: - // Console.WriteLine( [(1,2)], - - match triggerIsTypedChar with - | Some ('<' | '(' | ',') when not (tupleEnds |> Array.exists (fun lp -> lp.Character = caretLineColumn)) -> - return None // comma or paren at wrong location = remove help display - | _ -> - - // Compute the argument index by working out where the caret is between the various commas. - let argumentIndex = - let computedTextSpans = - tupleEnds - |> Array.pairwise - |> Array.map (fun (lp1, lp2) -> textLines.GetTextSpan(LinePositionSpan(lp1, lp2))) - - match (computedTextSpans|> Array.tryFindIndex (fun t -> t.Contains(caretPosition))) with - | None -> - // Because 'TextSpan.Contains' only succeeds if 'TextSpan.Start <= caretPosition < TextSpan.End' is true, - // we need to check if the caret is at the very last position in the TextSpan. - // - // We default to 0, which is the first argument, if the caret position was nowhere to be found. - if computedTextSpans.[computedTextSpans.Length-1].End = caretPosition then - computedTextSpans.Length-1 - else 0 - | Some n -> n - - // Compute the overall argument count - let argumentCount = - match nwpl.TupleEndLocations.Length with - | 1 when caretLinePos.Character = startOfArgs.Character -> 0 // count "WriteLine(" as zero arguments - | n -> n - - // Compute the current argument name, if any - let argumentName = - if argumentIndex < nwpl.NamedParamNames.Length then - nwpl.NamedParamNames.[argumentIndex] - else - None // not a named argument - - // Prepare the results - let results = ResizeArray() - - for method in methods do - // Create the documentation. Note, do this on the background thread, since doing it in the documentationBuild fails to build the XML index - let mainDescription = ResizeArray() - let documentation = ResizeArray() - XmlDocumentation.BuildMethodOverloadTipText(documentationBuilder, RoslynHelpers.CollectTaggedText mainDescription, RoslynHelpers.CollectTaggedText documentation, method.StructuredDescription, false) - - let parameters = - let parameters = if isStaticArgTip then method.StaticParameters else method.Parameters - [| for p in parameters do - let doc = List() - // FSROSLYNTODO: compute the proper help text for parameters, c.f. AppendParameter in XmlDocumentation.fs - XmlDocumentation.BuildMethodParamText(documentationBuilder, RoslynHelpers.CollectTaggedText doc, method.XmlDoc, p.ParameterName) - let parts = List() - renderL (taggedTextListR (RoslynHelpers.CollectTaggedText parts)) p.StructuredDisplay |> ignore - yield (p.ParameterName, p.IsOptional, p.CanonicalTypeTextForSorting, doc, parts) + let mutable possibleCurrentSignatureHelpSessionKind = None + + static member internal ProvideMethodsAsyncAux + ( + caretLinePos: LinePosition, + caretLineColumn: int, + paramLocations: ParameterLocations, + checkFileResults: FSharpCheckFileResults, + documentationBuilder: IDocumentationBuilder, + sourceText: SourceText, + caretPosition: int, + triggerIsTypedChar: char option + ) = + asyncMaybe { + let textLines = sourceText.Lines + let names = paramLocations.LongId + let lidEnd = paramLocations.LongIdEndLocation + + let methodGroup = checkFileResults.GetMethods(lidEnd.Line, lidEnd.Column, "", Some names) + + let methods = methodGroup.Methods + + do! Option.guard (methods.Length > 0 && not(methodGroup.MethodName.EndsWith("> )"))) + + let isStaticArgTip = + let parenLine, parenCol = Position.toZ paramLocations.OpenParenLocation + assert (parenLine < textLines.Count) + let parenLineText = sourceText.GetSubText(textLines.[parenLine].Span) + parenCol < parenLineText.Length && parenLineText.[parenCol] = '<' + + let filteredMethods = + [| + for m in methods do + if (isStaticArgTip && m.StaticParameters.Length > 0) || + (not isStaticArgTip && m.HasParameters) then // need to distinguish TP<...>(...) angle brackets tip from parens tip + m |] - let prefixParts = - [| TaggedText(TextTags.Method, methodGroup.MethodName); - TaggedText(TextTags.Punctuation, (if isStaticArgTip then "<" else "(")) |] - let separatorParts = [| TaggedText(TextTags.Punctuation, ","); TaggedText(TextTags.Space, " ") |] - let suffixParts = [| TaggedText(TextTags.Punctuation, (if isStaticArgTip then ">" else ")")) |] + do! Option.guard (filteredMethods.Length > 0) + + let posToLinePosition pos = + let (l,c) = Position.toZ pos + let result = LinePosition(l,c) + let lastPosInDocument = textLines.GetLinePosition(textLines.[textLines.Count-1].End) + if lastPosInDocument.CompareTo(result) > 0 then result else lastPosInDocument + + let startPos = paramLocations.LongIdStartLocation |> posToLinePosition + let endPos = + let last = paramLocations.TupleEndLocations.[paramLocations.TupleEndLocations.Length-1] |> posToLinePosition + (if paramLocations.IsThereACloseParen then oneColBefore last else last) - let completionItem = (method.HasParamArrayArg, documentation, prefixParts, separatorParts, suffixParts, parameters, mainDescription) - // FSROSLYNTODO: Do we need a cache like for completion? - //declarationItemsCache.Remove(completionItem.DisplayText) |> ignore // clear out stale entries if they exist - //declarationItemsCache.Add(completionItem.DisplayText, declarationItem) - results.Add(completionItem) + assert (startPos.CompareTo(endPos) <= 0) + let applicableSpan = + textLines.GetTextSpan(LinePositionSpan(startPos, endPos)) + + let startOfArgs = paramLocations.OpenParenLocation |> posToLinePosition |> oneColAfter + + let tupleEnds = + [| + startOfArgs + for i in 0..paramLocations.TupleEndLocations.Length-2 do + paramLocations.TupleEndLocations.[i] |> posToLinePosition + endPos + |] - let items = (results.ToArray(),applicableSpan,argumentIndex,argumentCount,argumentName) - return Some items + // If we are pressing "(" or "<" or ",", then only pop up the info if this is one of the actual, real detected positions in the detected promptable call + // + // For example the last "(" in + // List.map (fun a -> ( + // should not result in a prompt. + // + // Likewise the last "," in + // Console.WriteLine( [(1, + // should not result in a prompt, whereas this one will: + // Console.WriteLine( [(1,2)], + match triggerIsTypedChar with + | Some('<' | '(' | ',') when not (tupleEnds |> Array.exists (fun lp -> lp.Character = caretLineColumn)) -> + return! None // comma or paren at wrong location = remove help display + | _ -> + + // Compute the argument index by working out where the caret is between the various commas. + let argumentIndex = + let computedTextSpans = + tupleEnds + |> Array.pairwise + |> Array.map (fun (lp1, lp2) -> textLines.GetTextSpan(LinePositionSpan(lp1, lp2))) + + match (computedTextSpans|> Array.tryFindIndex (fun t -> t.Contains(caretPosition))) with + | None -> + // Because 'TextSpan.Contains' only succeeds if 'TextSpan.Start <= caretPosition < TextSpan.End' is true, + // we need to check if the caret is at the very last position in the TextSpan. + // + // We default to 0, which is the first argument, if the caret position was nowhere to be found. + if computedTextSpans.[computedTextSpans.Length-1].End = caretPosition then + computedTextSpans.Length-1 + else 0 + | Some n -> n + + let argumentCount = + match paramLocations.TupleEndLocations.Length with + | 1 when caretLinePos.Character = startOfArgs.Character -> 0 // count "WriteLine(" as zero arguments + | n -> n + + // Compute the current argument name if it is named. + let namedArgumentName = + if argumentIndex < paramLocations.NamedParamNames.Length then + paramLocations.NamedParamNames.[argumentIndex] + else + None + + let results = + [| + for method in methods do + let mainDescription = ResizeArray() + let documentation = ResizeArray() + XmlDocumentation.BuildMethodOverloadTipText( + documentationBuilder, + RoslynHelpers.CollectTaggedText mainDescription, + RoslynHelpers.CollectTaggedText documentation, + method.Description, false) + + let parameters = + let parameters = if isStaticArgTip then method.StaticParameters else method.Parameters + [| + for p in parameters do + let doc = ResizeArray() + let parts = ResizeArray() + XmlDocumentation.BuildMethodParamText(documentationBuilder, RoslynHelpers.CollectTaggedText doc, method.XmlDoc, p.ParameterName) + p.Display |> Seq.iter (RoslynHelpers.CollectTaggedText parts) + { ParameterName = p.ParameterName + IsOptional = p.IsOptional + CanonicalTypeTextForSorting = p.CanonicalTypeTextForSorting + Documentation = doc + DisplayParts = parts } + |] + + let prefixParts = + [| RoslynTaggedText(TextTags.Method, methodGroup.MethodName); + RoslynTaggedText(TextTags.Punctuation, (if isStaticArgTip then "<" else "(")) |] + + let separatorParts = [| RoslynTaggedText(TextTags.Punctuation, ","); RoslynTaggedText(TextTags.Space, " ") |] + let suffixParts = [| RoslynTaggedText(TextTags.Punctuation, (if isStaticArgTip then ">" else ")")) |] + + { HasParamArrayArg = method.HasParamArrayArg + Documentation = documentation + PrefixParts = prefixParts + SeparatorParts = separatorParts + SuffixParts = suffixParts + Parameters = parameters + MainDescription = mainDescription } + |] + + let data = + { SignatureHelpItems = results + ApplicableSpan = applicableSpan + ArgumentIndex = argumentIndex + ArgumentCount = argumentCount + ArgumentName = namedArgumentName + CurrentSignatureHelpSessionKind = MethodCall } + + return! Some data } + static member internal ProvideParametersAsyncAux + ( + parseResults: FSharpParseFileResults, + checkFileResults: FSharpCheckFileResults, + documentId: DocumentId, + defines: string list, + documentationBuilder: IDocumentationBuilder, + sourceText: SourceText, + caretPosition: int, + adjustedColumnInSource: int, + filePath: string + ) = + asyncMaybe { + let textLine = sourceText.Lines.GetLineFromPosition(adjustedColumnInSource) + let textLinePos = sourceText.Lines.GetLinePosition(adjustedColumnInSource) + let textLineText = textLine.ToString() + let pos = mkPos (Line.fromZ textLinePos.Line) textLinePos.Character + let textLinePos = sourceText.Lines.GetLinePosition(adjustedColumnInSource) + let fcsTextLineNumber = Line.fromZ textLinePos.Line + + let! possibleApplicableSymbolEndColumn = + maybe { + if parseResults.IsPosContainedInApplication pos then + let! funcRange = parseResults.TryRangeOfFunctionOrMethodBeingApplied pos + let! funcSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, funcRange) + return funcSpan.End + else + return adjustedColumnInSource + } + + let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentId, sourceText, possibleApplicableSymbolEndColumn, filePath, defines, SymbolLookupKind.Greedy, false, false) + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLineText, lexerSymbol.FullIsland) + + let isValid (mfv: FSharpMemberOrFunctionOrValue) = + not (PrettyNaming.IsOperatorDisplayName mfv.DisplayName) && + not mfv.IsProperty && + mfv.CurriedParameterGroups.Count > 0 + + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv when isValid mfv -> + let tooltip = checkFileResults.GetToolTip(fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLineText, lexerSymbol.FullIsland, FSharpTokenTag.IDENT) + match tooltip with + | ToolTipText [] + | ToolTipText [ToolTipElement.None] -> return! None + | _ -> + let possiblePipelineIdent = parseResults.TryIdentOfPipelineContainingPosAndNumArgsApplied symbolUse.Range.Start + let numArgsAlreadyApplied = + match possiblePipelineIdent with + | None -> 0 + | Some (_, numArgsApplied) -> numArgsApplied + + let definedArgs = mfv.CurriedParameterGroups |> Array.ofSeq + + let numDefinedArgs = definedArgs.Length + + let curriedArgsInSource = + parseResults.GetAllArgumentsForFunctionApplicationAtPostion symbolUse.Range.Start + |> Option.defaultValue [] + |> Array.ofList + + do! Option.guard (numDefinedArgs >= curriedArgsInSource.Length) + + (* + Calculate the argument index for fun and profit! It's a doozy... + + Firstly, we need to use the caret position unlike before. + + If the caret position is exactly in range of an existing argument, pick its index. + + The rest answers the question of, "what is the NEXT index to show?", because + when you're not cycling through parameters with the caret, you're typing, + and you want to know what the next argument should be. + + A possibility is you've deleted a parameter and want to enter a new one that + corresponds to the argument you're "at". We need to find the correct next index. + This could also correspond to an existing argument application. Buuuuuut that's okay. + If you want the "used to be 3rd arg, but is now 2nd arg" to remain, when you cycle + past the "now 2nd arg", it will calculate the 3rd arg as the next argument. + + If none of that applies, then we apply the magic of arithmetic + to find the next index if we're not at the max defined args for the application. + Otherwise, we're outa here! + *) + let! argumentIndex = + let caretTextLinePos = sourceText.Lines.GetLinePosition(caretPosition) + let caretPos = mkPos (Line.fromZ caretTextLinePos.Line) caretTextLinePos.Character + + let possibleExactIndex = + curriedArgsInSource + |> Array.tryFindIndex(fun argRange -> rangeContainsPos argRange caretPos) + + match possibleExactIndex with + | Some index -> Some index + | None -> + let possibleNextIndex = + curriedArgsInSource + |> Array.tryFindIndex(fun argRange -> Position.posGeq argRange.Start caretPos) + + match possibleNextIndex with + | Some index -> Some index + | None -> + if numDefinedArgs - numArgsAlreadyApplied > curriedArgsInSource.Length then + Some (numDefinedArgs - (numDefinedArgs - curriedArgsInSource.Length)) + else + None + + let mainDescription, documentation, typeParameterMap, usage, exceptions = + ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray() + + XmlDocumentation.BuildDataTipText( + documentationBuilder, + mainDescription.Add, + documentation.Add, + typeParameterMap.Add, + usage.Add, + exceptions.Add, + tooltip) + + let fsharpDocs = RoslynHelpers.joinWithLineBreaks [documentation; typeParameterMap; usage; exceptions] + + let docs = ResizeArray() + fsharpDocs |> Seq.iter (RoslynHelpers.CollectTaggedText docs) + + let parts = ResizeArray() + mainDescription |> Seq.iter (RoslynHelpers.CollectTaggedText parts) + + let displayArgs = ResizeArray() + + // Offset by 1 here until we support reverse indexes in this codebase + definedArgs.[.. definedArgs.Length - 1 - numArgsAlreadyApplied] |> Array.iteri (fun index argument -> + let tt = ResizeArray() + + if argument.Count = 1 then + let argument = argument.[0] + let taggedText = argument.Type.FormatLayout symbolUse.DisplayContext + taggedText |> Seq.iter (RoslynHelpers.CollectTaggedText tt) + + let name = + if String.IsNullOrWhiteSpace(argument.DisplayName) then + "arg" + string index + else + argument.DisplayName + + let display = + [| + RoslynTaggedText(TextTags.Local, name) + RoslynTaggedText(TextTags.Punctuation, ":") + RoslynTaggedText(TextTags.Space, " ") + |] + |> ResizeArray + + if argument.Type.IsFunctionType then + display.Add(RoslynTaggedText(TextTags.Punctuation, "(")) + + display.AddRange(tt) + + if argument.Type.IsFunctionType then + display.Add(RoslynTaggedText(TextTags.Punctuation, ")")) + + let info = + { ParameterName = name + IsOptional = false + CanonicalTypeTextForSorting = name + Documentation = ResizeArray() + DisplayParts = display } + + displayArgs.Add(info) + else + let display = ResizeArray() + display.Add(RoslynTaggedText(TextTags.Punctuation, "(")) + + let separatorParts = + [| + RoslynTaggedText(TextTags.Space, " ") + RoslynTaggedText(TextTags.Operator, "*") + RoslynTaggedText(TextTags.Space, " ") + |] + + let mutable first = true + argument |> Seq.iteri (fun index arg -> + if first then + first <- false + else + display.AddRange(separatorParts) + let tt = ResizeArray() + + let taggedText = arg.Type.FormatLayout symbolUse.DisplayContext + taggedText |> Seq.iter (RoslynHelpers.CollectTaggedText tt) + + let name = + if String.IsNullOrWhiteSpace(arg.DisplayName) then + "arg" + string index + else + arg.DisplayName + + let namePart = + [| + RoslynTaggedText(TextTags.Local, name) + RoslynTaggedText(TextTags.Punctuation, ":") + RoslynTaggedText(TextTags.Space, " ") + |] + + display.AddRange(namePart) + + if arg.Type.IsFunctionType then + display.Add(RoslynTaggedText(TextTags.Punctuation, "(")) + + display.AddRange(tt) + + if arg.Type.IsFunctionType then + display.Add(RoslynTaggedText(TextTags.Punctuation, ")"))) + + display.Add(RoslynTaggedText(TextTags.Punctuation, ")")) + + let info = + { ParameterName = "" // No name here, since it's a tuple of arguments has no name in the F# symbol info + IsOptional = false + CanonicalTypeTextForSorting = "" + Documentation = ResizeArray() + DisplayParts = display } + + displayArgs.Add(info)) + + do! Option.guard (displayArgs.Count > 0) + + let prefixParts = + [| + if mfv.IsMember then + RoslynTaggedText(TextTags.Keyword, "member") + else + RoslynTaggedText(TextTags.Keyword, "val") + RoslynTaggedText(TextTags.Space, " ") + RoslynTaggedText(TextTags.Method, mfv.DisplayName) + RoslynTaggedText(TextTags.Punctuation, ":") + RoslynTaggedText(TextTags.Space, " ") + |] + + let separatorParts = + [| + RoslynTaggedText(TextTags.Space, " ") + RoslynTaggedText(TextTags.Operator, "->") + RoslynTaggedText(TextTags.Space, " ") + |] + + let sigHelpItem = + { HasParamArrayArg = false + Documentation = docs + PrefixParts = prefixParts + SeparatorParts = separatorParts + SuffixParts = [||] + Parameters = displayArgs.ToArray() + MainDescription = ResizeArray() } + + let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.Range) + + let data = + { SignatureHelpItems = [| sigHelpItem |] + ApplicableSpan = TextSpan(symbolSpan.End, caretPosition - symbolSpan.End) + ArgumentIndex = argumentIndex + ArgumentCount = displayArgs.Count + ArgumentName = None + CurrentSignatureHelpSessionKind = FunctionApplication } + + return! Some data + | _ -> + return! None + } + + static member ProvideSignatureHelp + ( + document: Document, + defines: string list, + documentationBuilder: IDocumentationBuilder, + caretPosition: int, + triggerTypedChar: char option, + possibleCurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind option + ) = + asyncMaybe { + let! parseResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync("ProvideSignatureHelp") |> liftAsync + + let! sourceText = document.GetTextAsync() |> liftTaskAsync + + let textLines = sourceText.Lines + let caretLinePos = textLines.GetLinePosition(caretPosition) + let caretLineColumn = caretLinePos.Character + + let adjustedColumnInSource = + let rec loop ch pos = + if Char.IsWhiteSpace(ch) then + loop sourceText.[pos - 1] (pos - 1) + else + pos + loop sourceText.[caretPosition - 1] (caretPosition - 1) + + let adjustedColumnChar = sourceText.[adjustedColumnInSource] + + match triggerTypedChar, possibleCurrentSignatureHelpSessionKind with + // Generally ' ' indicates a function application, but it's also used commonly after a comma in a method call. + // This means that the adjusted position relative to the caret could be a ',' or a '(' or '<', + // which would mean we're already inside of a method call - not a function argument. So we bail if that's the case. + | Some ' ', _ when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' -> + return! + FSharpSignatureHelpProvider.ProvideParametersAsyncAux( + parseResults, + checkFileResults, + document.Id, + defines, + documentationBuilder, + sourceText, + caretPosition, + adjustedColumnInSource, + document.FilePath) + | _, Some FunctionApplication when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' -> + return! + FSharpSignatureHelpProvider.ProvideParametersAsyncAux( + parseResults, + checkFileResults, + document.Id, + defines, + documentationBuilder, + sourceText, + caretPosition, + adjustedColumnInSource, + document.FilePath) + | _ -> + let! paramInfoLocations = parseResults.FindParameterLocations(Position.fromZ caretLinePos.Line caretLineColumn) + return! + FSharpSignatureHelpProvider.ProvideMethodsAsyncAux( + caretLinePos, + caretLineColumn, + paramInfoLocations, + checkFileResults, + documentationBuilder, + sourceText, + caretPosition, + triggerTypedChar) + } + interface IFSharpSignatureHelpProvider with - member this.IsTriggerCharacter(c) = c ='(' || c = '<' || c = ',' - member this.IsRetriggerCharacter(c) = c = ')' || c = '>' || c = '=' + member _.IsTriggerCharacter(c) = c ='(' || c = '<' || c = ',' || c = ' ' + member _.IsRetriggerCharacter(c) = c = ')' || c = '>' || c = '=' - member this.GetItemsAsync(document, position, triggerInfo, cancellationToken) = + member _.GetItemsAsync(document, position, triggerInfo, cancellationToken) = asyncMaybe { - try - let! _parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let! sourceText = document.GetTextAsync(cancellationToken) - let! textVersion = document.GetTextVersionAsync(cancellationToken) + let defines = document.GetFSharpQuickDefines() let triggerTypedChar = if triggerInfo.TriggerCharacter.HasValue && triggerInfo.TriggerReason = FSharpSignatureHelpTriggerReason.TypeCharCommand then Some triggerInfo.TriggerCharacter.Value else None - let! (results,applicableSpan,argumentIndex,argumentCount,argumentName) = - FSharpSignatureHelpProvider.ProvideMethodsAsyncAux(checkerProvider.Checker, documentationBuilder, sourceText, position, projectOptions, triggerTypedChar, document.FilePath, textVersion.GetHashCode()) - let items = - results - |> Array.map (fun (hasParamArrayArg, doc, prefixParts, separatorParts, suffixParts, parameters, descriptionParts) -> - let parameters = parameters - |> Array.map (fun (paramName, isOptional, _typeText, paramDoc, displayParts) -> - FSharpSignatureHelpParameter(paramName,isOptional,documentationFactory=(fun _ -> paramDoc :> seq<_>),displayParts=displayParts)) - FSharpSignatureHelpItem(isVariadic=hasParamArrayArg, documentationFactory=(fun _ -> doc :> seq<_>),prefixParts=prefixParts,separatorParts=separatorParts,suffixParts=suffixParts,parameters=parameters,descriptionParts=descriptionParts)) - - return FSharpSignatureHelpItems(items,applicableSpan,argumentIndex,argumentCount,Option.toObj argumentName) - with ex -> - Assert.Exception(ex) - return! None + let doWork () = + async { + let! signatureHelpDataOpt = + FSharpSignatureHelpProvider.ProvideSignatureHelp( + document, + defines, + documentationBuilder, + position, + triggerTypedChar, + possibleCurrentSignatureHelpSessionKind) + match signatureHelpDataOpt with + | None -> + possibleCurrentSignatureHelpSessionKind <- None + return None + | Some signatureHelpData -> + let items = + signatureHelpData.SignatureHelpItems + |> Array.map (fun item -> + let parameters = + item.Parameters + |> Array.map (fun paramInfo -> + FSharpSignatureHelpParameter( + paramInfo.ParameterName, + paramInfo.IsOptional, + documentationFactory = (fun _ -> paramInfo.Documentation :> seq<_>), + displayParts = paramInfo.DisplayParts)) + + FSharpSignatureHelpItem( + isVariadic=item.HasParamArrayArg, + documentationFactory=(fun _ -> item.Documentation :> seq<_>), + prefixParts=item.PrefixParts, + separatorParts=item.SeparatorParts, + suffixParts=item.SuffixParts, + parameters=parameters, + descriptionParts=item.MainDescription)) + + match signatureHelpData.CurrentSignatureHelpSessionKind with + | MethodCall -> + possibleCurrentSignatureHelpSessionKind <- Some MethodCall + | FunctionApplication -> + possibleCurrentSignatureHelpSessionKind <- Some FunctionApplication + + return + FSharpSignatureHelpItems( + items, + signatureHelpData.ApplicableSpan, + signatureHelpData.ArgumentIndex, + signatureHelpData.ArgumentCount, + Option.toObj signatureHelpData.ArgumentName) + |> Some + } + return! doWork () } |> Async.map Option.toObj |> RoslynHelpers.StartAsyncAsTask cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs b/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs index 42bd5f9282d..f0fe54af81d 100644 --- a/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs +++ b/vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs @@ -10,25 +10,25 @@ open System.Threading.Tasks open System.Linq open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Editor.Implementation.Debugging -open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Implementation.Debugging -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position [)>] type internal FSharpBreakpointResolutionService [] ( - checkerProvider: FSharpCheckerProvider, - projectInfoManager: FSharpProjectOptionsManager ) = - static let userOpName = "BreakpointResolution" - static member GetBreakpointLocation(checker: FSharpChecker, sourceText: SourceText, fileName: string, textSpan: TextSpan, parsingOptions: FSharpParsingOptions) = + static member GetBreakpointLocation(document: Document, textSpan: TextSpan) = async { + let! ct = Async.CancellationToken + + let! sourceText = document.GetTextAsync(ct) |> Async.AwaitTask + let textLinePos = sourceText.Lines.GetLinePosition(textSpan.Start) let textInLine = sourceText.GetSubText(sourceText.Lines.[textLinePos.Line].Span).ToString() @@ -37,16 +37,17 @@ type internal FSharpBreakpointResolutionService else let textLineColumn = textLinePos.Character let fcsTextLineNumber = Line.fromZ textLinePos.Line // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based - let! parseResults = checker.ParseFile(fileName, sourceText.ToFSharpSourceText(), parsingOptions, userOpName = userOpName) - return parseResults.ValidateBreakpointLocation(mkPos fcsTextLineNumber textLineColumn) + let! parseResults = document.GetFSharpParseResultsAsync(nameof(FSharpBreakpointResolutionService)) |> liftAsync + match parseResults with + | Some parseResults -> return parseResults.ValidateBreakpointLocation(mkPos fcsTextLineNumber textLineColumn) + | _ -> return None } interface IFSharpBreakpointResolutionService with member this.ResolveBreakpointAsync(document: Document, textSpan: TextSpan, cancellationToken: CancellationToken): Task = asyncMaybe { - let! parsingOptions, _options = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) + let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(document, textSpan) let! sourceText = document.GetTextAsync(cancellationToken) - let! range = FSharpBreakpointResolutionService.GetBreakpointLocation(checkerProvider.Checker, sourceText, document.Name, textSpan, parsingOptions) let! span = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) return FSharpBreakpointResolutionResult.CreateSpanResult(document, span) } diff --git a/vsintegration/src/FSharp.Editor/Debugging/LanguageDebugInfoService.fs b/vsintegration/src/FSharp.Editor/Debugging/LanguageDebugInfoService.fs index cf37cf08aa6..d2b30fc01bb 100644 --- a/vsintegration/src/FSharp.Editor/Debugging/LanguageDebugInfoService.fs +++ b/vsintegration/src/FSharp.Editor/Debugging/LanguageDebugInfoService.fs @@ -10,15 +10,12 @@ open System.Threading.Tasks open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Classification -open Microsoft.CodeAnalysis.Editor.Implementation.Debugging -open Microsoft.CodeAnalysis.Host.Mef +open FSharp.Compiler.EditorServices open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Implementation.Debugging -open FSharp.Compiler - [)>] -type internal FSharpLanguageDebugInfoService [](projectInfoManager: FSharpProjectOptionsManager) = +type internal FSharpLanguageDebugInfoService []() = static member GetDataTipInformation(sourceText: SourceText, position: int, tokens: List): TextSpan option = let tokenIndex = tokens |> Seq.tryFindIndex(fun t -> t.TextSpan.Contains(position)) @@ -52,7 +49,7 @@ type internal FSharpLanguageDebugInfoService [](projectInf member this.GetDataTipInfoAsync(document: Document, position: int, cancellationToken: CancellationToken): Task = async { - let defines = projectInfoManager.GetCompilationDefinesForEditingDocument(document) + let defines = document.GetFSharpQuickDefines() let! cancellationToken = Async.CancellationToken let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask let textSpan = TextSpan.FromBounds(0, sourceText.Length) diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs index 0d92ce047be..4f8e55f23fd 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/DocumentDiagnosticAnalyzer.fs @@ -10,14 +10,11 @@ open System.Threading open System.Threading.Tasks open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Diagnostics open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices - +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics [] type internal DiagnosticsType = @@ -25,34 +22,27 @@ type internal DiagnosticsType = | Semantic [)>] -type internal FSharpDocumentDiagnosticAnalyzer [] () = - - static let userOpName = "DocumentDiagnosticAnalyzer" - let getChecker(document: Document) = - document.Project.Solution.Workspace.Services.GetService().Checker - - let getProjectInfoManager(document: Document) = - document.Project.Solution.Workspace.Services.GetService().FSharpProjectOptionsManager - - let getSettings(document: Document) = - document.Project.Solution.Workspace.Services.GetService() +type internal FSharpDocumentDiagnosticAnalyzer + [] + ( + ) = static let errorInfoEqualityComparer = - { new IEqualityComparer with - member __.Equals (x, y) = + { new IEqualityComparer with + member _.Equals (x, y) = x.FileName = y.FileName && - x.StartLineAlternate = y.StartLineAlternate && - x.EndLineAlternate = y.EndLineAlternate && + x.StartLine = y.StartLine && + x.EndLine = y.EndLine && x.StartColumn = y.StartColumn && x.EndColumn = y.EndColumn && x.Severity = y.Severity && x.Message = y.Message && x.Subcategory = y.Subcategory && x.ErrorNumber = y.ErrorNumber - member __.GetHashCode x = + member _.GetHashCode x = let mutable hash = 17 - hash <- hash * 23 + x.StartLineAlternate.GetHashCode() - hash <- hash * 23 + x.EndLineAlternate.GetHashCode() + hash <- hash * 23 + x.StartLine.GetHashCode() + hash <- hash * 23 + x.EndLine.GetHashCode() hash <- hash * 23 + x.StartColumn.GetHashCode() hash <- hash * 23 + x.EndColumn.GetHashCode() hash <- hash * 23 + x.Severity.GetHashCode() @@ -62,35 +52,37 @@ type internal FSharpDocumentDiagnosticAnalyzer [] () = hash } - static member GetDiagnostics(checker: FSharpChecker, filePath: string, sourceText: SourceText, textVersionHash: int, parsingOptions: FSharpParsingOptions, options: FSharpProjectOptions, diagnosticType: DiagnosticsType) = + static member GetDiagnostics(document: Document, diagnosticType: DiagnosticsType) = async { - let fsSourceText = sourceText.ToFSharpSourceText() - let! parseResults = checker.ParseFile(filePath, fsSourceText, parsingOptions, userOpName=userOpName) + let! ct = Async.CancellationToken + + let! parseResults = document.GetFSharpParseResultsAsync("GetDiagnostics") + + let! sourceText = document.GetTextAsync(ct) |> Async.AwaitTask + let filePath = document.FilePath + let! errors = async { match diagnosticType with | DiagnosticsType.Semantic -> - let! checkResultsAnswer = checker.CheckFileInProject(parseResults, filePath, textVersionHash, fsSourceText, options, userOpName=userOpName) - match checkResultsAnswer with - | FSharpCheckFileAnswer.Aborted -> return [||] - | FSharpCheckFileAnswer.Succeeded results -> - // In order to eleminate duplicates, we should not return parse errors here because they are returned by `AnalyzeSyntaxAsync` method. - let allErrors = HashSet(results.Errors, errorInfoEqualityComparer) - allErrors.ExceptWith(parseResults.Errors) - return Seq.toArray allErrors + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync("GetDiagnostics") + // In order to eleminate duplicates, we should not return parse errors here because they are returned by `AnalyzeSyntaxAsync` method. + let allErrors = HashSet(checkResults.Diagnostics, errorInfoEqualityComparer) + allErrors.ExceptWith(parseResults.Diagnostics) + return Seq.toArray allErrors | DiagnosticsType.Syntax -> - return parseResults.Errors + return parseResults.Diagnostics } let results = HashSet(errors, errorInfoEqualityComparer) |> Seq.choose(fun error -> - if error.StartLineAlternate = 0 || error.EndLineAlternate = 0 then + if error.StartLine = 0 || error.EndLine = 0 then // F# error line numbers are one-based. Compiler returns 0 for global errors (reported by ProjectDiagnosticAnalyzer) None else // Roslyn line numbers are zero-based - let linePositionSpan = LinePositionSpan(LinePosition(error.StartLineAlternate - 1, error.StartColumn), LinePosition(error.EndLineAlternate - 1, error.EndColumn)) + let linePositionSpan = LinePositionSpan(LinePosition(error.StartLine - 1, error.StartColumn), LinePosition(error.EndLine - 1, error.EndColumn)) let textSpan = sourceText.Lines.GetTextSpan(linePositionSpan) // F# compiler report errors at end of file if parsing fails. It should be corrected to match Roslyn boundaries @@ -113,38 +105,25 @@ type internal FSharpDocumentDiagnosticAnalyzer [] () = interface IFSharpDocumentDiagnosticAnalyzer with member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task> = - // if using LSP, just bail early - let settings = getSettings document - if settings.Advanced.UsePreviewDiagnostics then Task.FromResult(ImmutableArray.Empty) + if document.Project.IsFSharpMetadata then Task.FromResult(ImmutableArray.Empty) else - let projectInfoManager = getProjectInfoManager document + asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let! sourceText = document.GetTextAsync(cancellationToken) - let! textVersion = document.GetTextVersionAsync(cancellationToken) return! - FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(getChecker document, document.FilePath, sourceText, textVersion.GetHashCode(), parsingOptions, projectOptions, DiagnosticsType.Syntax) + FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(document, DiagnosticsType.Syntax) |> liftAsync } |> Async.map (Option.defaultValue ImmutableArray.Empty) |> RoslynHelpers.StartAsyncAsTask cancellationToken member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task> = - // if using LSP, just bail early - let settings = getSettings document - if settings.Advanced.UsePreviewDiagnostics then Task.FromResult(ImmutableArray.Empty) + if document.Project.IsFSharpMiscellaneousOrMetadata && not document.IsFSharpScript then Task.FromResult(ImmutableArray.Empty) else - let projectInfoManager = getProjectInfoManager document + asyncMaybe { - let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken) - let! sourceText = document.GetTextAsync(cancellationToken) - let! textVersion = document.GetTextVersionAsync(cancellationToken) - if document.Project.Name <> FSharpConstants.FSharpMiscellaneousFilesName || isScriptFile document.FilePath then - return! - FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(getChecker document, document.FilePath, sourceText, textVersion.GetHashCode(), parsingOptions, projectOptions, DiagnosticsType.Semantic) - |> liftAsync - else - return ImmutableArray.Empty + return! + FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(document, DiagnosticsType.Semantic) + |> liftAsync } |> Async.map (Option.defaultValue ImmutableArray.Empty) |> RoslynHelpers.StartAsyncAsTask cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/ProjectDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/ProjectDiagnosticAnalyzer.fs deleted file mode 100644 index 544039aa36a..00000000000 --- a/vsintegration/src/FSharp.Editor/Diagnostics/ProjectDiagnosticAnalyzer.fs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Microsoft.VisualStudio.FSharp.Editor - -open System -open System.Composition -open System.Collections.Immutable -open System.IO -open System.Threading -open System.Threading.Tasks - -open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Diagnostics -open Microsoft.CodeAnalysis.Host.Mef -open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.SolutionCrawler -open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics - -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range - -// Project-wide error analysis. We don't enable this because ParseAndCheckProject checks projects against the versions of the files -// saves to the file system. This is different to the versions of the files active in the editor. This results in out-of-sync error -// messages while files are being edited - -[)>] -type internal FSharpProjectDiagnosticAnalyzer [] () = - -#if PROJECT_ANALYSIS - static member GetDiagnostics(options: FSharpProjectOptions) = async { - let! checkProjectResults = FSharpLanguageService.Checker.ParseAndCheckProject(options) - let results = - checkProjectResults.Errors - |> Seq.choose(fun (error) -> - if error.StartLineAlternate = 0 || error.EndLineAlternate = 0 then - Some(CommonRoslynHelpers.ConvertError(error, Location.None)) - else - // F# error line numbers are one-based. Errors that have a valid line number are reported by DocumentDiagnosticAnalyzer - None - ) - |> Seq.toImmutableArray - return results - } -#endif - - interface IFSharpProjectDiagnosticAnalyzer with - - member this.AnalyzeProjectAsync(_project: Project, _cancellationToken: CancellationToken): Task> = -#if PROJECT_ANALYSIS - async { - match FSharpLanguageService.GetOptionsForProject(project.Id) with - | Some options -> return! FSharpProjectDiagnosticAnalyzer.GetDiagnostics(options) - | None -> return ImmutableArray.Empty - } |> CommonRoslynHelpers.StartAsyncAsTask cancellationToken -#else - Task.FromResult(ImmutableArray.Empty) -#endif diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs index f90717522a5..0c853a404cf 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs @@ -7,26 +7,22 @@ open System.Composition open System.Collections.Immutable open System.Diagnostics open System.Threading -open System.Threading.Tasks open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.Range open System.Runtime.Caching -open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text -type private TextVersionHash = int type private PerDocumentSavedData = { Hash: int; Diagnostics: ImmutableArray } [)>] -type internal SimplifyNameDiagnosticAnalyzer [] () = +type internal SimplifyNameDiagnosticAnalyzer + [] + ( + ) = static let userOpName = "SimplifyNameDiagnosticAnalyzer" - let getProjectInfoManager (document: Document) = document.Project.Solution.Workspace.Services.GetService().FSharpProjectOptionsManager - let getChecker (document: Document) = document.Project.Solution.Workspace.Services.GetService().Checker - let getPlidLength (plid: string list) = (plid |> List.sumBy String.length) + plid.Length static let cache = new MemoryCache("FSharp.Editor." + userOpName) // Make sure only one document is being analyzed at a time, to be nice static let guard = new SemaphoreSlim(1) @@ -35,12 +31,13 @@ type internal SimplifyNameDiagnosticAnalyzer [] () = interface IFSharpSimplifyNameDiagnosticAnalyzer with - member this.AnalyzeSemanticsAsync(descriptor, document: Document, cancellationToken: CancellationToken) = + member _.AnalyzeSemanticsAsync(descriptor, document: Document, cancellationToken: CancellationToken) = + if document.Project.IsFSharpMiscellaneousOrMetadata && not document.IsFSharpScript then Tasks.Task.FromResult(ImmutableArray.Empty) + else + asyncMaybe { - do! Option.guard document.FSharpOptions.CodeFixes.SimplifyName + do! Option.guard document.Project.IsFSharpCodeFixesSimplifyNameEnabled do Trace.TraceInformation("{0:n3} (start) SimplifyName", DateTime.Now.TimeOfDay.TotalSeconds) - do! Async.Sleep DefaultTuning.SimplifyNameInitialDelay |> liftAsync - let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) let textVersionHash = textVersion.GetHashCode() let! _ = guard.WaitAsync(cancellationToken) |> Async.AwaitTask |> liftAsync @@ -50,64 +47,16 @@ type internal SimplifyNameDiagnosticAnalyzer [] () = | :? PerDocumentSavedData as data when data.Hash = textVersionHash -> return data.Diagnostics | _ -> let! sourceText = document.GetTextAsync() - let checker = getChecker document - let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName=userOpName) - let! symbolUses = checkResults.GetAllUsesOfAllSymbolsInFile() |> liftAsync - let mutable result = ResizeArray() - let symbolUses = - symbolUses - |> Array.filter (fun symbolUse -> not symbolUse.IsFromOpenStatement) - |> Array.Parallel.map (fun symbolUse -> - let lineStr = sourceText.Lines.[Line.toZ symbolUse.RangeAlternate.StartLine].ToString() - // for `System.DateTime.Now` it returns ([|"System"; "DateTime"|], "Now") - let partialName = QuickParse.GetPartialLongNameEx(lineStr, symbolUse.RangeAlternate.EndColumn - 1) - // `symbolUse.RangeAlternate.Start` does not point to the start of plid, it points to start of `name`, - // so we have to calculate plid's start ourselves. - let plidStartCol = symbolUse.RangeAlternate.EndColumn - partialName.PartialIdent.Length - (getPlidLength partialName.QualifyingIdents) - symbolUse, partialName.QualifyingIdents, plidStartCol, partialName.PartialIdent) - |> Array.filter (fun (_, plid, _, name) -> name <> "" && not (List.isEmpty plid)) - |> Array.groupBy (fun (symbolUse, _, plidStartCol, _) -> symbolUse.RangeAlternate.StartLine, plidStartCol) - |> Array.map (fun (_, xs) -> xs |> Array.maxBy (fun (symbolUse, _, _, _) -> symbolUse.RangeAlternate.EndColumn)) - - for symbolUse, plid, plidStartCol, name in symbolUses do - if not symbolUse.IsFromDefinition then - let posAtStartOfName = - let r = symbolUse.RangeAlternate - if r.StartLine = r.EndLine then Range.mkPos r.StartLine (r.EndColumn - name.Length) - else r.Start - - let getNecessaryPlid (plid: string list) : Async = - let rec loop (rest: string list) (current: string list) = - async { - match rest with - | [] -> return current - | headIdent :: restPlid -> - let! res = checkResults.IsRelativeNameResolvableFromSymbol(posAtStartOfName, current, symbolUse.Symbol, userOpName=userOpName) - if res then return current - else return! loop restPlid (headIdent :: current) - } - loop (List.rev plid) [] - - do! Async.Sleep DefaultTuning.SimplifyNameEachItemDelay |> liftAsync // be less intrusive, give other work priority most of the time - let! necessaryPlid = getNecessaryPlid plid |> liftAsync - - match necessaryPlid with - | necessaryPlid when necessaryPlid = plid -> () - | necessaryPlid -> - let r = symbolUse.RangeAlternate - let necessaryPlidStartCol = r.EndColumn - name.Length - (getPlidLength necessaryPlid) - - let unnecessaryRange = - Range.mkRange r.FileName (Range.mkPos r.StartLine plidStartCol) (Range.mkPos r.EndLine necessaryPlidStartCol) - - let relativeName = (String.concat "." plid) + "." + name - result.Add( - Diagnostic.Create( - descriptor, - RoslynHelpers.RangeToLocation(unnecessaryRange, sourceText, document.FilePath), - properties = (dict [SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, relativeName]).ToImmutableDictionary())) - - let diagnostics = result.ToImmutableArray() + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(SimplifyNameDiagnosticAnalyzer)) |> liftAsync + let! result = SimplifyNames.getSimplifiableNames(checkResults, fun lineNumber -> sourceText.Lines.[Line.toZ lineNumber].ToString()) |> liftAsync + let mutable diag = ResizeArray() + for r in result do + diag.Add( + Diagnostic.Create( + descriptor, + RoslynHelpers.RangeToLocation(r.Range, sourceText, document.FilePath), + properties = (dict [SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, r.RelativeName]).ToImmutableDictionary())) + let diagnostics = diag.ToImmutableArray() cache.Remove(key) |> ignore let data = { Hash = textVersionHash; Diagnostics=diagnostics } let cacheItem = CacheItem(key, data) diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs index ff7c43839d0..c94b193e6aa 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedDeclarationsAnalyzer.fs @@ -4,106 +4,36 @@ namespace rec Microsoft.VisualStudio.FSharp.Editor open System open System.Composition -open System.Collections.Generic open System.Collections.Immutable open System.Diagnostics -open System.Threading.Tasks open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Diagnostics -open Microsoft.CodeAnalysis.Host.Mef -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics [)>] -type internal UnusedDeclarationsAnalyzer [] () = - - static let userOpName = "UnusedDeclarationsAnalyzer" - let getProjectInfoManager (document: Document) = document.Project.Solution.Workspace.Services.GetService().FSharpProjectOptionsManager - let getChecker (document: Document) = document.Project.Solution.Workspace.Services.GetService().Checker - - let isPotentiallyUnusedDeclaration (symbol: FSharpSymbol) : bool = - match symbol with - // Determining that a record, DU or module is used anywhere requires inspecting all their enclosed entities (fields, cases and func / vals) - // for usages, which is too expensive to do. Hence we never gray them out. - | :? FSharpEntity as e when e.IsFSharpRecord || e.IsFSharpUnion || e.IsInterface || e.IsFSharpModule || e.IsClass || e.IsNamespace -> false - // FCS returns inconsistent results for override members; we're skipping these symbols. - | :? FSharpMemberOrFunctionOrValue as f when - f.IsOverrideOrExplicitInterfaceImplementation || - f.IsBaseValue || - f.IsConstructor -> false - // Usage of DU case parameters does not give any meaningful feedback; we never gray them out. - | :? FSharpParameter -> false - | _ -> true - - let getUnusedDeclarationRanges (symbolsUses: FSharpSymbolUse[]) (isScript: bool) = - let definitions = - symbolsUses - |> Array.filter (fun su -> - su.IsFromDefinition && - su.Symbol.DeclarationLocation.IsSome && - (isScript || su.IsPrivateToFile) && - not (su.Symbol.DisplayName.StartsWith "_") && - isPotentiallyUnusedDeclaration su.Symbol) - - let usages = - let usages = - symbolsUses - |> Array.filter (fun su -> not su.IsFromDefinition) - |> Array.choose (fun su -> su.Symbol.DeclarationLocation) - HashSet(usages) - - let unusedRanges = - definitions - |> Array.map (fun defSu -> defSu, usages.Contains defSu.Symbol.DeclarationLocation.Value) - |> Array.groupBy (fun (defSu, _) -> defSu.RangeAlternate) - |> Array.filter (fun (_, defSus) -> defSus |> Array.forall (fun (_, isUsed) -> not isUsed)) - |> Array.map (fun (m, _) -> m) - - //#if DEBUG - //let formatRange (x: FSharp.Compiler.Range.range) = sprintf "(%d, %d) - (%d, %d)" x.StartLine x.StartColumn x.EndLine x.EndColumn - - //symbolsUses - //|> Array.map (fun su -> sprintf "%s, %s, is definition = %b, Symbol (def range = %A)" - // (formatRange su.RangeAlternate) su.Symbol.DisplayName su.IsFromDefinition - // (su.Symbol.DeclarationLocation |> Option.map formatRange)) - //|> Logging.Logging.logInfof "SymbolUses:\n%+A" - // - //definitions - //|> Seq.map (fun su -> sprintf "su range = %s, symbol range = %A, symbol name = %s" - // (formatRange su.RangeAlternate) (su.Symbol.DeclarationLocation |> Option.map formatRange) su.Symbol.DisplayName) - //|> Logging.Logging.logInfof "Definitions:\n%A" - // - //usages - //|> Seq.map formatRange - //|> Seq.toArray - //|> Logging.Logging.logInfof "Used ranges:\n%A" - // - //unusedRanges - //|> Array.map formatRange - //|> Logging.Logging.logInfof "Unused ranges: %A" - //#endif - unusedRanges +type internal UnusedDeclarationsAnalyzer + [] + ( + ) = interface IFSharpUnusedDeclarationsDiagnosticAnalyzer with - member __.AnalyzeSemanticsAsync(descriptor, document, cancellationToken) = + member _.AnalyzeSemanticsAsync(descriptor, document, cancellationToken) = + if document.Project.IsFSharpMiscellaneousOrMetadata && not document.IsFSharpScript then Threading.Tasks.Task.FromResult(ImmutableArray.Empty) + else + asyncMaybe { - do! Option.guard document.FSharpOptions.CodeFixes.UnusedDeclarations + do! Option.guard document.Project.IsFSharpCodeFixesUnusedDeclarationsEnabled do Trace.TraceInformation("{0:n3} (start) UnusedDeclarationsAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) - do! Async.Sleep DefaultTuning.UnusedDeclarationsAnalyzerInitialDelay |> liftAsync // be less intrusive, give other work priority most of the time - match! getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) with - | (_parsingOptions, projectOptions) -> - let! sourceText = document.GetTextAsync() - let checker = getChecker document - let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, userOpName = userOpName) - let! allSymbolUsesInFile = checkResults.GetAllUsesOfAllSymbolsInFile() |> liftAsync - let unusedRanges = getUnusedDeclarationRanges allSymbolUsesInFile (isScriptFile document.FilePath) - return - unusedRanges - |> Seq.map (fun m -> Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) - |> Seq.toImmutableArray + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(UnusedDeclarationsAnalyzer)) |> liftAsync + let! unusedRanges = UnusedDeclarations.getUnusedDeclarations( checkResults, (isScriptFile document.FilePath)) |> liftAsync + let! sourceText = document.GetTextAsync() + return + unusedRanges + |> Seq.map (fun m -> Diagnostic.Create(descriptor, RoslynHelpers.RangeToLocation(m, sourceText, document.FilePath))) + |> Seq.toImmutableArray } |> Async.map (Option.defaultValue ImmutableArray.Empty) |> RoslynHelpers.StartAsyncAsTask cancellationToken diff --git a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs index c79027b0dff..9c75bab971e 100644 --- a/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs +++ b/vsintegration/src/FSharp.Editor/Diagnostics/UnusedOpensDiagnosticAnalyzer.fs @@ -7,52 +7,40 @@ open System.Composition open System.Collections.Immutable open System.Diagnostics open System.Threading -open System.Threading.Tasks open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Text -open Microsoft.CodeAnalysis.Diagnostics -open FSharp.Compiler -open FSharp.Compiler.Ast -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices -open Microsoft.VisualStudio.FSharp.Editor.Symbols -open Microsoft.CodeAnalysis.Host.Mef -open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics -[)>] -type internal UnusedOpensDiagnosticAnalyzer [] () = +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text - let getProjectInfoManager (document: Document) = document.Project.Solution.Workspace.Services.GetService().FSharpProjectOptionsManager - let getChecker (document: Document) = document.Project.Solution.Workspace.Services.GetService().Checker +open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Diagnostics - static let userOpName = "UnusedOpensAnalyzer" +[)>] +type internal UnusedOpensDiagnosticAnalyzer + [] + ( + ) = - static member GetUnusedOpenRanges(document: Document, options, checker: FSharpChecker) : Async> = + static member GetUnusedOpenRanges(document: Document) : Async> = asyncMaybe { - do! Option.guard document.FSharpOptions.CodeFixes.UnusedOpens + do! Option.guard document.Project.IsFSharpCodeFixesUnusedOpensEnabled let! sourceText = document.GetTextAsync() - let! _, _, checkResults = checker.ParseAndCheckDocument(document, options, sourceText = sourceText, userOpName = userOpName) -#if DEBUG - let sw = Stopwatch.StartNew() -#endif + let! _, checkResults = document.GetFSharpParseAndCheckResultsAsync(nameof(UnusedOpensDiagnosticAnalyzer)) |> liftAsync let! unusedOpens = UnusedOpens.getUnusedOpens(checkResults, fun lineNumber -> sourceText.Lines.[Line.toZ lineNumber].ToString()) |> liftAsync -#if DEBUG - Logging.Logging.logInfof "*** Got %d unused opens in %O" unusedOpens.Length sw.Elapsed -#endif return unusedOpens } interface IFSharpUnusedOpensDiagnosticAnalyzer with - member this.AnalyzeSemanticsAsync(descriptor, document: Document, cancellationToken: CancellationToken) = + member _.AnalyzeSemanticsAsync(descriptor, document: Document, cancellationToken: CancellationToken) = + if document.Project.IsFSharpMiscellaneousOrMetadata && not document.IsFSharpScript then Tasks.Task.FromResult(ImmutableArray.Empty) + else + asyncMaybe { do Trace.TraceInformation("{0:n3} (start) UnusedOpensAnalyzer", DateTime.Now.TimeOfDay.TotalSeconds) - do! Async.Sleep DefaultTuning.UnusedOpensAnalyzerInitialDelay |> liftAsync // be less intrusive, give other work priority most of the time - let! _parsingOptions, projectOptions = getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) let! sourceText = document.GetTextAsync() - let checker = getChecker document - let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document, projectOptions, checker) + let! unusedOpens = UnusedOpensDiagnosticAnalyzer.GetUnusedOpenRanges(document) return unusedOpens diff --git a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs index 09a7951e047..3eddf9a3ec8 100644 --- a/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs +++ b/vsintegration/src/FSharp.Editor/DocComments/XMLDocumentation.fs @@ -3,13 +3,17 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System +open System.Collections.Immutable open System.Runtime.CompilerServices open System.Text.RegularExpressions open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.Shell.Interop -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.TaggedText open System.Collections.Generic type internal ITaggedTextCollector = @@ -32,7 +36,7 @@ type internal TextSanitizingCollector(collector, ?lineLimit: int) = count <- count + 1 | _ -> isEmpty <- false - endsWithLineBreak <- text.Tag = LayoutTag.LineBreak + endsWithLineBreak <- text.Tag = TextTag.LineBreak if endsWithLineBreak then count <- count + 1 collector text @@ -57,14 +61,14 @@ type internal TextSanitizingCollector(collector, ?lineLimit: int) = addTaggedTextEntry (tagText paragraph) if i < paragraphs.Length - 1 then // insert two line breaks to separate paragraphs - addTaggedTextEntry Literals.lineBreak - addTaggedTextEntry Literals.lineBreak) + addTaggedTextEntry TaggedText.lineBreak + addTaggedTextEntry TaggedText.lineBreak) interface ITaggedTextCollector with member this.Add taggedText = // TODO: bail out early if line limit is already hit match taggedText.Tag with - | LayoutTag.Text -> reportTextLines taggedText.Text + | TextTag.Text -> reportTextLines taggedText.Text | _ -> addTaggedTextEntry taggedText member this.IsEmpty = isEmpty @@ -101,7 +105,7 @@ module internal XmlDocumentation = else xml let AppendHardLine(collector: ITaggedTextCollector) = - collector.Add Literals.lineBreak + collector.Add TaggedText.lineBreak let EnsureHardLine(collector: ITaggedTextCollector) = if not collector.EndsWithLineBreak then AppendHardLine collector @@ -109,7 +113,7 @@ module internal XmlDocumentation = let AppendOnNewLine (collector: ITaggedTextCollector) (line:string) = if line.Length > 0 then EnsureHardLine collector - collector.Add(TaggedTextOps.tagText line) + collector.Add(TaggedText.tagText line) open System.Xml open System.Xml.Linq @@ -149,7 +153,7 @@ module internal XmlDocumentation = let parts = typeName.Split([|'.'|]) for i = 0 to parts.Length - 2 do collector.Add(tagNamespace parts.[i]) - collector.Add(Literals.dot) + collector.Add(TaggedText.dot) collector.Add(tagClass parts.[parts.Length - 1]) type XmlDocReader private (doc: XElement) = @@ -164,7 +168,7 @@ module internal XmlDocumentation = static member TryCreate (xml: string) = try Some (XmlDocReader(XElement.Parse(ProcessXml xml))) with _ -> None - member __.CollectSummary(collector: ITaggedTextCollector) = + member _.CollectSummary(collector: ITaggedTextCollector) = match Seq.tryHead (doc.Descendants(XName.op_Implicit "summary")) with | None -> () | Some el -> @@ -185,8 +189,8 @@ module internal XmlDocumentation = | name -> EnsureHardLine collector collector.Add(tagParameter name.Value) - collector.Add(Literals.colon) - collector.Add(Literals.space) + collector.Add(TaggedText.colon) + collector.Add(TaggedText.space) WriteNodes collector (p.Nodes()) member this.CollectExceptions(collector: ITaggedTextCollector) = @@ -203,9 +207,9 @@ module internal XmlDocumentation = collector.Add(tagSpace " ") WriteTypeName collector exnType.Value if not (Seq.isEmpty (p.Nodes())) then - collector.Add Literals.space - collector.Add Literals.minus - collector.Add Literals.space + collector.Add TaggedText.space + collector.Add TaggedText.minus + collector.Add TaggedText.space WriteNodes collector (p.Nodes()) type VsThreadToken() = class end @@ -244,7 +248,7 @@ module internal XmlDocumentation = interface IDocumentationBuilder with /// Append the given processed XML formatted into the string builder - override __.AppendDocumentationFromProcessedXML(xmlCollector, exnCollector, processedXml, showExceptions, showParameters, paramName) = + override _.AppendDocumentationFromProcessedXML(xmlCollector, exnCollector, processedXml, showExceptions, showParameters, paramName) = match XmlDocReader.TryCreate processedXml with | Some xmlDocReader -> match paramName with @@ -286,10 +290,11 @@ module internal XmlDocumentation = let AppendXmlComment(documentationProvider:IDocumentationBuilder, xmlCollector: ITaggedTextCollector, exnCollector: ITaggedTextCollector, xml, showExceptions, showParameters, paramName) = match xml with | FSharpXmlDoc.None -> () - | FSharpXmlDoc.XmlDocFileSignature(filename,signature) -> + | FSharpXmlDoc.FromXmlFile(filename,signature) -> documentationProvider.AppendDocumentation(xmlCollector, exnCollector, filename, signature, showExceptions, showParameters, paramName) - | FSharpXmlDoc.Text(rawXml) -> - let processedXml = ProcessXml(rawXml) + | FSharpXmlDoc.FromXmlText(xmlDoc) -> + let elaboratedXml = xmlDoc.GetElaboratedXmlLines() + let processedXml = ProcessXml("\n\n" + String.concat "\n" elaboratedXml) documentationProvider.AppendDocumentationFromProcessedXML(xmlCollector, exnCollector, processedXml, showExceptions, showParameters, paramName) let private AddSeparator (collector: ITaggedTextCollector) = @@ -300,7 +305,7 @@ module internal XmlDocumentation = /// Build a data tip text string with xml comments injected. let BuildTipText(documentationProvider:IDocumentationBuilder, - dataTipText: FSharpStructuredToolTipElement list, + dataTipText: ToolTipElement list, textCollector, xmlCollector, typeParameterMapCollector, usageCollector, exnCollector, showText, showExceptions, showParameters) = let textCollector: ITaggedTextCollector = TextSanitizingCollector(textCollector, lineLimit = 45) :> _ @@ -314,32 +319,32 @@ module internal XmlDocumentation = AddSeparator textCollector AddSeparator xmlCollector - let ProcessGenericParameters (tps: Layout list) = + let ProcessGenericParameters (tps: TaggedText[] list) = if not tps.IsEmpty then AppendHardLine typeParameterMapCollector AppendOnNewLine typeParameterMapCollector (SR.GenericParametersHeader()) for tp in tps do AppendHardLine typeParameterMapCollector typeParameterMapCollector.Add(tagSpace " ") - renderL (taggedTextListR typeParameterMapCollector.Add) tp |> ignore + tp |> Array.iter typeParameterMapCollector.Add - let Process add (dataTipElement: FSharpStructuredToolTipElement) = + let Process add (dataTipElement: ToolTipElement) = match dataTipElement with - | FSharpStructuredToolTipElement.None -> + | ToolTipElement.None -> false - | FSharpStructuredToolTipElement.Group (overloads) -> + | ToolTipElement.Group (overloads) -> let overloads = Array.ofList overloads let len = overloads.Length if len >= 1 then addSeparatorIfNecessary add if showText then - let AppendOverload (item: FSharpToolTipElementData<_>) = - if not(isEmptyL item.MainDescription) then + let AppendOverload (item: ToolTipElementData) = + if TaggedText.toString item.MainDescription <> "" then if not textCollector.IsEmpty then AppendHardLine textCollector - renderL (taggedTextListR textCollector.Add) item.MainDescription |> ignore + item.MainDescription |> Seq.iter textCollector.Add AppendOverload(overloads.[0]) if len >= 2 then AppendOverload(overloads.[1]) @@ -353,9 +358,9 @@ module internal XmlDocumentation = let item0 = overloads.[0] item0.Remarks |> Option.iter (fun r -> - if not(isEmptyL r) then + if TaggedText.toString r <> "" then AppendHardLine usageCollector - renderL (taggedTextListR usageCollector.Add) r |> ignore) + r |> Seq.iter usageCollector.Add) AppendXmlComment(documentationProvider, xmlCollector, exnCollector, item0.XmlDoc, showExceptions, showParameters, item0.ParamName) @@ -366,16 +371,16 @@ module internal XmlDocumentation = else false - | FSharpStructuredToolTipElement.CompositionError(errText) -> + | ToolTipElement.CompositionError(errText) -> textCollector.Add(tagText errText) true List.fold Process false dataTipText |> ignore - let BuildDataTipText(documentationProvider, textCollector, xmlCollector, typeParameterMapCollector, usageCollector, exnCollector, FSharpToolTipText(dataTipText)) = + let BuildDataTipText(documentationProvider, textCollector, xmlCollector, typeParameterMapCollector, usageCollector, exnCollector, ToolTipText(dataTipText)) = BuildTipText(documentationProvider, dataTipText, textCollector, xmlCollector, typeParameterMapCollector, usageCollector, exnCollector, true, true, false) - let BuildMethodOverloadTipText(documentationProvider, textCollector, xmlCollector, FSharpToolTipText(dataTipText), showParams) = + let BuildMethodOverloadTipText(documentationProvider, textCollector, xmlCollector, ToolTipText(dataTipText), showParams) = BuildTipText(documentationProvider, dataTipText, textCollector, xmlCollector, xmlCollector, ignore, ignore, false, false, showParams) let BuildMethodParamText(documentationProvider, xmlCollector, xml, paramName) = diff --git a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs index 10ee6533790..207c1dd1e5c 100644 --- a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs +++ b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs @@ -8,13 +8,12 @@ open System.Collections.Immutable open System.Threading.Tasks open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.DocumentHighlighting -open Microsoft.CodeAnalysis.Host.Mef open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.ExternalAccess.FSharp.DocumentHighlighting -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text type internal FSharpHighlightSpan = { IsDefinition: bool @@ -22,9 +21,7 @@ type internal FSharpHighlightSpan = override this.ToString() = sprintf "%+A" this [)>] -type internal FSharpDocumentHighlightsService [] (checkerProvider: FSharpCheckerProvider, projectInfoManager: FSharpProjectOptionsManager) = - - static let userOpName = "DocumentHighlights" +type internal FSharpDocumentHighlightsService [] () = /// Fix invalid spans if they appear to have redundant suffix and prefix. static let fixInvalidSymbolSpans (sourceText: SourceText) (lastIdent: string) (spans: FSharpHighlightSpan []) = @@ -52,19 +49,22 @@ type internal FSharpDocumentHighlightsService [] (checkerP |> Seq.distinctBy (fun span -> span.TextSpan.Start) |> Seq.toArray - static member GetDocumentHighlights(checker: FSharpChecker, documentKey: DocumentId, sourceText: SourceText, filePath: string, position: int, - defines: string list, options: FSharpProjectOptions, textVersionHash: int, languageServicePerformanceOptions: LanguageServicePerformanceOptions) : Async = + static member GetDocumentHighlights(document: Document, position: int) : Async = asyncMaybe { + let! symbol = document.TryFindFSharpLexerSymbolAsync(position, SymbolLookupKind.Greedy, false, false, nameof(FSharpDocumentHighlightsService.GetDocumentHighlights)) + + let! ct = Async.CancellationToken |> liftAsync + let! sourceText = document.GetTextAsync(ct) let textLine = sourceText.Lines.GetLineFromPosition(position) let textLinePos = sourceText.Lines.GetLinePosition(position) let fcsTextLineNumber = Line.fromZ textLinePos.Line - let! symbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy, false) - let! _, _, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText, options, languageServicePerformanceOptions, userOpName = userOpName) - let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, userOpName=userOpName) - let! symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) |> liftAsync + + let! _, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpDocumentHighlightsService)) |> liftAsync + let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland) + let symbolUses = checkFileResults.GetUsesOfSymbolInFile(symbolUse.Symbol) return [| for symbolUse in symbolUses do - match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate) with + match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.Range) with | None -> () | Some span -> yield { IsDefinition = symbolUse.IsFromDefinition @@ -73,15 +73,9 @@ type internal FSharpDocumentHighlightsService [] (checkerP } interface IFSharpDocumentHighlightsService with - member __.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task> = + member _.GetDocumentHighlightsAsync(document, position, _documentsToSearch, cancellationToken) : Task> = asyncMaybe { - let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken) - let! sourceText = document.GetTextAsync(cancellationToken) - let! textVersion = document.GetTextVersionAsync(cancellationToken) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions - let perfOptions = document.FSharpOptions.LanguageServicePerformance - let! spans = FSharpDocumentHighlightsService.GetDocumentHighlights(checkerProvider.Checker, document.Id, sourceText, document.FilePath, - position, defines, projectOptions, textVersion.GetHashCode(), perfOptions) + let! spans = FSharpDocumentHighlightsService.GetDocumentHighlights(document, position) let highlightSpans = spans |> Array.map (fun span -> diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj index 77add187654..da325f32a96 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj @@ -1,4 +1,4 @@ - + @@ -7,8 +7,6 @@ $(NoWarn);75 $(NoWarn);44 true - true - $(SystemValueTupleVersion) $(OtherFlags) --warnon:1182 --subsystemversion:6.00 false @@ -28,17 +26,14 @@ - + + - - Common\LspExternalAccess.fs - - @@ -47,18 +42,16 @@ - - + + + - - LanguageService\JsonOptionConverter.fs - - + @@ -69,7 +62,6 @@ - @@ -77,7 +69,7 @@ - + @@ -97,11 +89,32 @@ + + + + + + + + + + + + + + + + + + + + + @@ -121,8 +134,7 @@ - - + @@ -151,7 +163,6 @@ - @@ -169,9 +180,8 @@ - - + diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx index 3675912ce61..bb52e1a6d80 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx @@ -1,4 +1,4 @@ - + ExecuteBackgroundRequest is equivalent to fetching a recent, // perhaps out-of-date scope. - member __.IsRecentScopeSufficientForBackgroundRequest(reason:BackgroundRequestReason) = + member _.IsRecentScopeSufficientForBackgroundRequest(reason:BackgroundRequestReason) = match reason with | BackgroundRequestReason.MatchBraces diff --git a/vsintegration/src/FSharp.LanguageService/Colorize.fs b/vsintegration/src/FSharp.LanguageService/Colorize.fs index 65fe7bbd5a4..fd6c8dd6b46 100644 --- a/vsintegration/src/FSharp.LanguageService/Colorize.fs +++ b/vsintegration/src/FSharp.LanguageService/Colorize.fs @@ -13,9 +13,10 @@ open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.TextManager.Interop open Microsoft.VisualStudio open Microsoft.VisualStudio.Text -open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization #nowarn "45" // This method will be made public in the underlying IL because it may implement an interface or override a method @@ -87,7 +88,7 @@ module internal ColorStateLookup_DEPRECATED = type internal FSharpScanner_DEPRECATED(makeLineTokenizer : string -> FSharpLineTokenizer) = let mutable lineTokenizer = makeLineTokenizer "" - let mutable extraColorizations : IDictionary option = None + let mutable extraColorizations : IDictionary option = None /// Decode compiler FSharpTokenColorKind into VS TokenColor. let lookupTokenColor colorKind = @@ -148,11 +149,11 @@ type internal FSharpScanner_DEPRECATED(makeLineTokenizer : string -> FSharpLineT lineTokenizer <- makeLineTokenizer lineText /// Adjust the set of extra colorizations and return a sorted list of affected lines. - member __.SetExtraColorizations (tokens: (Range.range * SemanticClassificationType)[]) = + member _.SetExtraColorizations (tokens: SemanticClassificationItem[]) = if tokens.Length = 0 && extraColorizations.IsNone then [| |] else - let newExtraColorizationsKeyed = dict (tokens |> Array.groupBy (fun (r, _) -> Range.Line.toZ r.StartLine)) + let newExtraColorizationsKeyed = dict (tokens |> Array.groupBy (fun item -> Line.toZ item.Range.StartLine)) let oldExtraColorizationsKeyedOpt = extraColorizations extraColorizations <- Some newExtraColorizationsKeyed let changedLines = @@ -352,7 +353,7 @@ type internal FSharpColorizer_DEPRECATED member c.Buffer = buffer - member __.SetExtraColorizations tokens = scanner.SetExtraColorizations tokens + member _.SetExtraColorizations tokens = scanner.SetExtraColorizations tokens /// Implements IVsColorableItem and IVsMergeableUIItem, for colored text items diff --git a/vsintegration/src/FSharp.LanguageService/FSharp.LanguageService.fsproj b/vsintegration/src/FSharp.LanguageService/FSharp.LanguageService.fsproj index 7692f24fcb1..20cfe642326 100644 --- a/vsintegration/src/FSharp.LanguageService/FSharp.LanguageService.fsproj +++ b/vsintegration/src/FSharp.LanguageService/FSharp.LanguageService.fsproj @@ -7,8 +7,6 @@ $(NoWarn);75 $(NoWarn);44 true - true - $(SystemValueTupleVersion) $(OtherFlags) --warnon:1182 --subsystemversion:6.00 false @@ -47,7 +45,7 @@ - + @@ -78,10 +76,9 @@ - - + diff --git a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs index 446fcfffb77..ac33dca38c6 100644 --- a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs +++ b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs @@ -20,8 +20,10 @@ open Microsoft.VisualStudio.Text.Editor open Microsoft.VisualStudio.Text.Formatting open Microsoft.VisualStudio.TextManager.Interop open Microsoft.VisualStudio.OLE.Interop -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text #nowarn "45" // This method will be made public in the underlying IL because it may implement an interface or override a method @@ -334,12 +336,12 @@ type internal FSharpSource_DEPRECATED(service:LanguageService_DEPRECATED, textLi let iSource = new FSharpSourceTestable_DEPRECATED(recolorizeWholeFile,recolorizeLine,(fun () -> VsTextLines.GetFilename textLines),(fun () -> source.IsClosed),vsFileWatch, depFileChange) :> IFSharpSource_DEPRECATED - override source.NormalizeErrorString(message) = ErrorLogger.NormalizeErrorString message - override source.NewlineifyErrorString(message) = ErrorLogger.NewlineifyErrorString message + override source.NormalizeErrorString(message) = FSharpDiagnostic.NormalizeErrorString message + override source.NewlineifyErrorString(message) = FSharpDiagnostic.NewlineifyErrorString message override source.GetExpressionAtPosition(line, col) = let upi = source.GetParseTree() - match UntypedParseImpl.TryFindExpressionIslandInPosition(Range.Pos.fromZ line col, upi.ParseTree) with + match ParsedInput.TryFindExpressionIslandInPosition(Position.fromZ line col, upi.ParseTree) with | Some islandToEvaluate -> islandToEvaluate | None -> null @@ -353,6 +355,7 @@ type internal FSharpSource_DEPRECATED(service:LanguageService_DEPRECATED, textLi yield! pi.CompilationOptions |> Array.filter(fun flag -> flag.StartsWith("--define:")) | None -> () yield "--noframework" + yield "--define:COMPILED" |] // get a sync parse of the file @@ -367,11 +370,10 @@ type internal FSharpSource_DEPRECATED(service:LanguageService_DEPRECATED, textLi LoadTime = new System.DateTime(2000,1,1) // dummy data, just enough to get a parse UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo=None Stamp = None } |> ic.GetParsingOptionsFromProjectOptions - ic.ParseFile(fileName, FSharp.Compiler.Text.SourceText.ofString (source.GetText()), co) |> Async.RunSynchronously + ic.ParseFile(fileName, FSharp.Compiler.Text.SourceText.ofString (source.GetText()), co) |> Async.RunImmediate override source.GetCommentFormat() = let mutable info = new CommentInfo() @@ -445,7 +447,7 @@ type internal FSharpSource_DEPRECATED(service:LanguageService_DEPRECATED, textLi if reason = BackgroundRequestReason.CompleteWord then let upi = source.GetParseTree() let isBetweenDotAndIdent = - match FSharp.Compiler.SourceCodeServices.UntypedParseImpl.TryFindExpressionASTLeftOfDotLeftOfCursor(Range.Pos.fromZ !line !idx, upi.ParseTree) with + match ParsedInput.TryFindExpressionASTLeftOfDotLeftOfCursor(Position.fromZ !line !idx, upi.ParseTree) with | Some(_,isBetweenDotAndIdent) -> isBetweenDotAndIdent | None -> false if isBetweenDotAndIdent then diff --git a/vsintegration/src/FSharp.LanguageService/GotoDefinition.fs b/vsintegration/src/FSharp.LanguageService/GotoDefinition.fs index aa4e9441f8a..8f575af130a 100644 --- a/vsintegration/src/FSharp.LanguageService/GotoDefinition.fs +++ b/vsintegration/src/FSharp.LanguageService/GotoDefinition.fs @@ -8,8 +8,9 @@ open System open System.Diagnostics open Microsoft.VisualStudio open Microsoft.VisualStudio.TextManager.Interop -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Tokenization module internal OperatorToken = @@ -72,24 +73,24 @@ module internal GotoDefinition = Strings.GotoDefinitionFailed_NotIdentifier() |> GotoDefinitionResult_DEPRECATED.MakeError else - match typedResults.GetDeclarationLocation (line+1, colIdent, lineStr, qualId, false) |> Async.RunSynchronously with - | FSharpFindDeclResult.DeclNotFound(reason) -> + match typedResults.GetDeclarationLocation (line+1, colIdent, lineStr, qualId, false) with + | FindDeclResult.DeclNotFound(reason) -> if makeAnotherAttempt then gotoDefinition true else Trace.Write("LanguageService", sprintf "Goto definition failed: Reason %+A" reason) let text = match reason with - | FSharpFindDeclFailureReason.Unknown _message -> Strings.GotoDefinitionFailed_Generic() - | FSharpFindDeclFailureReason.NoSourceCode -> Strings.GotoDefinitionFailed_NotSourceCode() - | FSharpFindDeclFailureReason.ProvidedType(typeName) -> String.Format(Strings.GotoDefinitionFailed_ProvidedType(), typeName) - | FSharpFindDeclFailureReason.ProvidedMember(name) -> String.Format(Strings.GotoDefinitionFailed_ProvidedMember(), name) + | FindDeclFailureReason.Unknown _message -> Strings.GotoDefinitionFailed_Generic() + | FindDeclFailureReason.NoSourceCode -> Strings.GotoDefinitionFailed_NotSourceCode() + | FindDeclFailureReason.ProvidedType(typeName) -> String.Format(Strings.GotoDefinitionFailed_ProvidedType(), typeName) + | FindDeclFailureReason.ProvidedMember(name) -> String.Format(Strings.GotoDefinitionFailed_ProvidedMember(), name) GotoDefinitionResult_DEPRECATED.MakeError text - | FSharpFindDeclResult.DeclFound m when System.IO.File.Exists m.FileName -> + | FindDeclResult.DeclFound m when System.IO.File.Exists m.FileName -> let span = TextSpan (iStartLine = m.StartLine-1, iEndLine = m.StartLine-1, iStartIndex = m.StartColumn, iEndIndex = m.StartColumn) GotoDefinitionResult_DEPRECATED.MakeSuccess(m.FileName, span) - | FSharpFindDeclResult.DeclFound _ (* File does not exist *) -> + | FindDeclResult.DeclFound _ (* File does not exist *) -> GotoDefinitionResult_DEPRECATED.MakeError(Strings.GotoDefinitionFailed_NotSourceCode()) - | FSharpFindDeclResult.ExternalDecl _ -> + | FindDeclResult.ExternalDecl _ -> GotoDefinitionResult_DEPRECATED.MakeError(Strings.GotoDefinitionFailed_NotSourceCode()) else Trace.Write("LanguageService", "Goto definition: No 'TypeCheckInfo' available") diff --git a/vsintegration/src/FSharp.LanguageService/Intellisense.fs b/vsintegration/src/FSharp.LanguageService/Intellisense.fs index dbf9d7fa5ab..82e48f7a9db 100644 --- a/vsintegration/src/FSharp.LanguageService/Intellisense.fs +++ b/vsintegration/src/FSharp.LanguageService/Intellisense.fs @@ -8,18 +8,24 @@ namespace Microsoft.VisualStudio.FSharp.LanguageService open System open System.Collections.Generic +open System.Collections.Immutable open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.TextManager.Interop open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.OLE.Interop open FSharp.Compiler -open FSharp.Compiler.Range -open FSharp.Compiler.SourceCodeServices - +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization module internal TaggedText = - let appendTo (sb: System.Text.StringBuilder) (t: Layout.TaggedText) = sb.Append t.Text |> ignore + let appendTo (sb: System.Text.StringBuilder) (t: TaggedText) = sb.Append t.Text |> ignore + let toString (tts: TaggedText[]) = + tts |> Array.map (fun tt -> tt.Text) |> String.concat "" // Note: DEPRECATED CODE ONLY ACTIVE IN UNIT TESTING VIA "UNROSLYNIZED" UNIT TESTS. // @@ -28,19 +34,19 @@ module internal TaggedText = // functionality and thus have considerable value, they should ony be deleted if we are sure this // is not the case. // -type internal FSharpMethodListForAMethodTip_DEPRECATED(documentationBuilder: IDocumentationBuilder_DEPRECATED, methodsName, methods: FSharpMethodGroupItem[], nwpl: FSharpNoteworthyParamInfoLocations, snapshot: ITextSnapshot, isThisAStaticArgumentsTip: bool) = +type internal FSharpMethodListForAMethodTip_DEPRECATED(documentationBuilder: IDocumentationBuilder_DEPRECATED, methodsName, methods: MethodGroupItem[], nwpl: ParameterLocations, snapshot: ITextSnapshot, isThisAStaticArgumentsTip: bool) = inherit MethodListForAMethodTip_DEPRECATED() // Compute the tuple end points let tupleEnds = - let oneColAfter ((l,c): Pos01) = (l,c+1) - let oneColBefore ((l,c): Pos01) = (l,c-1) - [| yield Pos.toZ nwpl.LongIdStartLocation - yield Pos.toZ nwpl.LongIdEndLocation - yield oneColAfter (Pos.toZ nwpl.OpenParenLocation) + let oneColAfter ((l,c): Position01) = (l,c+1) + let oneColBefore ((l,c): Position01) = (l,c-1) + [| yield Position.toZ nwpl.LongIdStartLocation + yield Position.toZ nwpl.LongIdEndLocation + yield oneColAfter (Position.toZ nwpl.OpenParenLocation) for i in 0..nwpl.TupleEndLocations.Length-2 do - yield Pos.toZ nwpl.TupleEndLocations.[i] - let last = Pos.toZ nwpl.TupleEndLocations.[nwpl.TupleEndLocations.Length-1] + yield Position.toZ nwpl.TupleEndLocations.[i] + let last = Position.toZ nwpl.TupleEndLocations.[nwpl.TupleEndLocations.Length-1] yield if nwpl.IsThereACloseParen then oneColBefore last else last |] let safe i dflt f = if 0 <= i && i < methods.Length then f methods.[i] else dflt @@ -52,7 +58,7 @@ type internal FSharpMethodListForAMethodTip_DEPRECATED(documentationBuilder: IDo let span = ss.CreateTrackingSpan(MakeSpan(ss,sl,sc,el,ec), SpanTrackingMode.EdgeInclusive) yield span |] - let getParameters (m : FSharpMethodGroupItem) = if isThisAStaticArgumentsTip then m.StaticParameters else m.Parameters + let getParameters (m : MethodGroupItem) = if isThisAStaticArgumentsTip then m.StaticParameters else m.Parameters do assert(methods.Length > 0) @@ -60,7 +66,7 @@ type internal FSharpMethodListForAMethodTip_DEPRECATED(documentationBuilder: IDo override x.IsThereACloseParen() = nwpl.IsThereACloseParen - override x.GetNoteworthyParamInfoLocations() = tupleEnds + override x.GetParameterLocations() = tupleEnds override x.GetParameterNames() = nwpl.NamedParamNames |> Array.map Option.toObj @@ -70,16 +76,16 @@ type internal FSharpMethodListForAMethodTip_DEPRECATED(documentationBuilder: IDo override x.GetDescription(methodIndex) = safe methodIndex "" (fun m -> let buf = Text.StringBuilder() - XmlDocumentation.BuildMethodOverloadTipText_DEPRECATED(documentationBuilder, TaggedText.appendTo buf, TaggedText.appendTo buf, m.StructuredDescription, true) + XmlDocumentation.BuildMethodOverloadTipText_DEPRECATED(documentationBuilder, TaggedText.appendTo buf, TaggedText.appendTo buf, m.Description, true) buf.ToString() ) - override x.GetReturnTypeText(methodIndex) = safe methodIndex "" (fun m -> m.ReturnTypeText) + override x.GetReturnTypeText(methodIndex) = safe methodIndex "" (fun m -> m.ReturnTypeText |> TaggedText.toString) override x.GetParameterCount(methodIndex) = safe methodIndex 0 (fun m -> getParameters(m).Length) override x.GetParameterInfo(methodIndex, parameterIndex, nameOut, displayOut, descriptionOut) = - let name,display = safe methodIndex ("","") (fun m -> let p = getParameters(m).[parameterIndex] in p.ParameterName, p.Display ) + let name,display = safe methodIndex ("","") (fun m -> let p = getParameters(m).[parameterIndex] in p.ParameterName, TaggedText.toString p.Display ) nameOut <- name displayOut <- display @@ -116,7 +122,7 @@ type internal ObsoleteGlyph = // functionality and thus have considerable value, they should ony be deleted if we are sure this // is not the case. // -type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations: FSharpDeclarationListItem[], reason: BackgroundRequestReason) = +type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations: DeclarationListItem[], reason: BackgroundRequestReason) = inherit Declarations_DEPRECATED() @@ -125,7 +131,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations: let mutable lastBestMatch = "" let isEmpty = (declarations.Length = 0) - let tab = Dictionary() + let tab = Dictionary() // Given a prefix, narrow the items to the include the ones containing that prefix, and store in a lookaside table // attached to this declaration set. @@ -183,7 +189,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations: let decls = trimmedDeclarations filterText if (index >= 0 && index < decls.Length) then let buf = Text.StringBuilder() - XmlDocumentation.BuildDataTipText_DEPRECATED(documentationBuilder, TaggedText.appendTo buf, TaggedText.appendTo buf, decls.[index].StructuredDescriptionText) + XmlDocumentation.BuildDataTipText_DEPRECATED(documentationBuilder, TaggedText.appendTo buf, TaggedText.appendTo buf, decls.[index].Description) buf.ToString() else "" @@ -224,7 +230,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations: // We intercept this call only to get the initial extent // of what was committed to the source buffer. let result = decl.GetName(filterText, index) - Keywords.QuoteIdentifierIfNeeded result + PrettyNaming.AddBackticksToIdentifierIfNeeded result override decl.IsCommitChar(commitCharacter) = // Usual language identifier rules... @@ -314,7 +320,7 @@ type internal FSharpIntellisenseInfo_DEPRECATED if provideMethodList then try // go ahead and compute this now, on this background thread, so will have info ready when UI thread asks - let noteworthyParamInfoLocations = untypedResults.FindNoteworthyParamInfoLocations(Range.Pos.fromZ brLine brCol) + let noteworthyParamInfoLocations = untypedResults.FindParameterLocations(Position.fromZ brLine brCol) // we need some typecheck info, even if stale, in order to look up e.g. method overload types/xmldocs if typedResults.HasFullTypeCheckInfo then @@ -329,7 +335,7 @@ type internal FSharpIntellisenseInfo_DEPRECATED // This can happen e.g. if you are typing quickly and the typecheck results are stale enough that you don't have a captured resolution for // the name you just typed, but fresh enough that you do have the right name-resolution-environment to look up the name. let lidEnd = nwpl.LongIdEndLocation - let methods = typedResults.GetMethods(lidEnd.Line, lidEnd.Column, "", Some names) |> Async.RunSynchronously + let methods = typedResults.GetMethods(lidEnd.Line, lidEnd.Column, "", Some names) // If the name is an operator ending with ">" then it is a mistake // we can't tell whether " >(" is a generic method call or an operator use @@ -344,7 +350,7 @@ type internal FSharpIntellisenseInfo_DEPRECATED // both point to the same longId. However we can look at the character at the 'OpenParen' location and see if it is a '(' or a '<' and then // filter the "methods" list accordingly. let isThisAStaticArgumentsTip = - let parenLine, parenCol = Pos.toZ nwpl.OpenParenLocation + let parenLine, parenCol = Position.toZ nwpl.OpenParenLocation let textAtOpenParenLocation = if brSnapshot=null then // we are unit testing, use the view @@ -377,41 +383,6 @@ type internal FSharpIntellisenseInfo_DEPRECATED reraise() else None - let hasTextChangedSinceLastTypecheck (curTextSnapshot: ITextSnapshot, oldTextSnapshot: ITextSnapshot, ((sl:int,sc:int),(el:int,ec:int))) = - // compare the text from (sl,sc) to (el,ec) to see if it changed from the old snapshot to the current one - // (sl,sc)-(el,ec) are line/col positions in the current snapshot - if el >= oldTextSnapshot.LineCount then - true // old did not even have 'el' many lines, note 'el' is zero-based - else - assert(el < curTextSnapshot.LineCount) - let oldFirstLine = oldTextSnapshot.GetLineFromLineNumber sl - let oldLastLine = oldTextSnapshot.GetLineFromLineNumber el - if oldFirstLine.Length < sc || oldLastLine.Length < ec then - true // one of old lines was not even long enough to contain the position we're looking at - else - let posOfStartInOld = oldFirstLine.Start.Position + sc - let posOfEndInOld = oldLastLine.Start.Position + ec - let curFirstLine = curTextSnapshot.GetLineFromLineNumber sl - let curLastLine = curTextSnapshot.GetLineFromLineNumber el - assert(curFirstLine.Length >= sc) - assert(curLastLine.Length >= ec) - let posOfStartInCur = curFirstLine.Start.Position + sc - let posOfEndInCur = curLastLine.Start.Position + ec - if posOfEndInCur - posOfStartInCur <> posOfEndInOld - posOfStartInOld then - true // length of text between two endpoints changed - else - let mutable oldPos = posOfStartInOld - let mutable curPos = posOfStartInCur - let mutable ok = true - while ok && oldPos < posOfEndInOld do - let oldChar = oldTextSnapshot.[oldPos] - let curChar = curTextSnapshot.[curPos] - if oldChar <> curChar then - ok <- false - oldPos <- oldPos + 1 - curPos <- curPos + 1 - not ok - /// Implements the corresponding abstract member from IntellisenseInfo in MPF. override scope.GetDataTipText(line, col) = // in cases like 'A' when cursor in on '<' there is an ambiguity that cannot be resolved based only on lexer information @@ -453,10 +424,10 @@ type internal FSharpIntellisenseInfo_DEPRECATED // Correct the identifier (e.g. to correctly handle active pattern names that end with "BAR" token) let tokenTag = QuickParse.CorrectIdentifierToken s tokenTag - let dataTip = typedResults.GetStructuredToolTipText(Range.Line.fromZ line, colAtEndOfNames, lineText, qualId, tokenTag) |> Async.RunSynchronously + let dataTip = typedResults.GetToolTip(Line.fromZ line, colAtEndOfNames, lineText, qualId, tokenTag) match dataTip with - | FSharpStructuredToolTipText.FSharpToolTipText [] when makeSecondAttempt -> getDataTip true + | ToolTipText.ToolTipText [] when makeSecondAttempt -> getDataTip true | _ -> let buf = Text.StringBuilder() XmlDocumentation.BuildDataTipText_DEPRECATED(documentationBuilder, TaggedText.appendTo buf, TaggedText.appendTo buf, dataTip) @@ -484,11 +455,11 @@ type internal FSharpIntellisenseInfo_DEPRECATED | BackgroundRequestReason.MethodTip // param info... | BackgroundRequestReason.MatchBracesAndMethodTip // param info... | BackgroundRequestReason.CompleteWord | BackgroundRequestReason.MemberSelect | BackgroundRequestReason.DisplayMemberList // and intellisense-completion... - -> true // ...require a sync parse (so as to call FindNoteworthyParamInfoLocations and GetRangeOfExprLeftOfDot, respectively) + -> true // ...require a sync parse (so as to call FindParameterLocations and GetRangeOfExprLeftOfDot, respectively) | _ -> false /// Implements the corresponding abstract member from IntellisenseInfo in MPF. - override scope.GetDeclarations(textSnapshot, line, col, reason) = + override scope.GetDeclarations(_textSnapshot, line, col, reason) = assert(FSharpIntellisenseInfo_DEPRECATED.IsReasonRequiringSyncParse(reason)) async { try @@ -531,11 +502,7 @@ type internal FSharpIntellisenseInfo_DEPRECATED let pname = QuickParse.GetPartialLongNameEx(lineText, col-1) let _x = 1 // for breakpoint - let detectTextChange (oldTextSnapshotInfo: obj, range) = - let oldTextSnapshot = oldTextSnapshotInfo :?> ITextSnapshot - hasTextChangedSinceLastTypecheck (textSnapshot, oldTextSnapshot, Range.Range.toZ range) - - let! decls = typedResults.GetDeclarationListInfo(untypedParseInfoOpt, Range.Line.fromZ line, lineText, pname, (fun() -> []), detectTextChange) + let decls = typedResults.GetDeclarationListInfo(untypedParseInfoOpt, Line.fromZ line, lineText, pname, (fun() -> [])) return (new FSharpDeclarations_DEPRECATED(documentationBuilder, decls.Items, reason) :> Declarations_DEPRECATED) else // no TypeCheckInfo in ParseResult. @@ -595,7 +562,7 @@ type internal FSharpIntellisenseInfo_DEPRECATED | Some(s,colAtEndOfNames, _) -> if typedResults.HasFullTypeCheckInfo then let qualId = PrettyNaming.GetLongNameFromString s - match typedResults.GetF1Keyword(Range.Line.fromZ line,colAtEndOfNames, lineText, qualId) |> Async.RunSynchronously with + match typedResults.GetF1Keyword(Line.fromZ line,colAtEndOfNames, lineText, qualId) with | Some s -> Some s | None -> None else None diff --git a/vsintegration/src/FSharp.LanguageService/LanguageServiceConstants.fs b/vsintegration/src/FSharp.LanguageService/LanguageServiceConstants.fs index 46bd6dd2f04..7a9cd796132 100644 --- a/vsintegration/src/FSharp.LanguageService/LanguageServiceConstants.fs +++ b/vsintegration/src/FSharp.LanguageService/LanguageServiceConstants.fs @@ -2,6 +2,8 @@ namespace Microsoft.VisualStudio.FSharp.LanguageService +open System.Threading.Tasks + [] module internal LanguageServiceConstants = @@ -11,4 +13,21 @@ module internal LanguageServiceConstants = [] /// "F# Language Service" - let FSharpLanguageServiceCallbackName = "F# Language Service" \ No newline at end of file + let FSharpLanguageServiceCallbackName = "F# Language Service" + + +[] +module AsyncExtensions = + type Async with + static member RunImmediate (computation: Async<'T>, ?cancellationToken ) = + let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken + let ts = TaskCompletionSource<'T>() + let task = ts.Task + Async.StartWithContinuations( + computation, + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), + (fun _ -> ts.SetCanceled()), + cancellationToken) + task.Result + diff --git a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs index 9909aaefa57..5200249efab 100644 --- a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs +++ b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs @@ -40,17 +40,12 @@ open System.Diagnostics open Microsoft.VisualStudio open Microsoft.VisualStudio.TextManager.Interop open Microsoft.VisualStudio.Shell.Interop -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis open Microsoft.CodeAnalysis -open Microsoft.VisualStudio.LanguageServices open Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem open Microsoft.VisualStudio.LanguageServices.Implementation.TaskList -open VSLangProj -open System.ComponentModel.Composition.Primitives -open Microsoft.VisualStudio.Shell -open System.Collections.Immutable - /// An additional interface that an IProjectSite object can implement to indicate it has an FSharpProjectOptions /// already available, so we don't have to recreate it @@ -141,7 +136,7 @@ type internal FSharpProjectOptionsTable () = projectTable.[otherProjectId] <- (refresh true, refresh) /// Add or update a project in the project table - member __.AddOrUpdateProject(projectId:ProjectId, refresh) = + member _.AddOrUpdateProject(projectId:ProjectId, refresh) = projectTable.[projectId] <- (refresh false, refresh) refreshInfoForProjectsThatReferenceThisProject(projectId) @@ -157,7 +152,7 @@ type internal FSharpProjectOptionsTable () = | _ -> None /// Given a projectId return the most recent set of command line options for it - member __.GetCommandLineOptionsWithProjectId(projectId:ProjectId) = + member _.GetCommandLineOptionsWithProjectId(projectId:ProjectId) = match commandLineOptions.TryGetValue projectId with | true, (sources, references, options) -> sources, references, options | _ -> [||], [||], [||] @@ -184,45 +179,45 @@ let internal provideProjectSiteProvider(workspace:VisualStudioWorkspaceImpl, pro { new IProjectSite with - member __.Description = project.Name - member __.CompilationSourceFiles = getCommandLineOptionsWithProjectId(project.Id) |> fst - member __.CompilationOptions = + member _.Description = project.Name + member _.CompilationSourceFiles = getCommandLineOptionsWithProjectId(project.Id) |> fst + member _.CompilationOptions = let _,references,options = getCommandLineOptionsWithProjectId(project.Id) Array.concat [options; references |> Array.map(fun r -> "-r:" + r)] - member __.CompilationReferences = getCommandLineOptionsWithProjectId(project.Id) |> snd + member _.CompilationReferences = getCommandLineOptionsWithProjectId(project.Id) |> snd member site.CompilationBinOutputPath = site.CompilationOptions |> Array.tryPick (fun s -> if s.StartsWith("-o:") then Some s.[3..] else None) - member __.ProjectFileName = project.FilePath - member __.AdviseProjectSiteChanges(_,_) = () - member __.AdviseProjectSiteCleaned(_,_) = () - member __.AdviseProjectSiteClosed(_,_) = () - member __.IsIncompleteTypeCheckEnvironment = false - member __.TargetFrameworkMoniker = "" - member __.ProjectGuid = project.Id.Id.ToString() - member __.LoadTime = System.DateTime.Now - member __.ProjectProvider = Some (x) - member __.BuildErrorReporter with get () = errorReporter and set (v) = errorReporter <- v + member _.ProjectFileName = project.FilePath + member _.AdviseProjectSiteChanges(_,_) = () + member _.AdviseProjectSiteCleaned(_,_) = () + member _.AdviseProjectSiteClosed(_,_) = () + member _.IsIncompleteTypeCheckEnvironment = false + member _.TargetFrameworkMoniker = "" + member _.ProjectGuid = project.Id.Id.ToString() + member _.LoadTime = System.DateTime.Now + member _.ProjectProvider = Some (x) + member _.BuildErrorReporter with get () = errorReporter and set (v) = errorReporter <- v } interface IVsHierarchy with - member __.SetSite(psp) = hier.SetSite(psp) - member __.GetSite(psp) = hier.GetSite(ref psp) - member __.QueryClose(pfCanClose) = hier.QueryClose(ref pfCanClose) - member __.Close() = hier.Close() - member __.GetGuidProperty(itemid, propid, pguid) = hier.GetGuidProperty(itemid, propid, ref pguid) - member __.SetGuidProperty(itemid, propid, rguid) = hier.SetGuidProperty(itemid, propid, ref rguid) - member __.GetProperty(itemid, propid, pvar) = hier.GetProperty(itemid, propid, ref pvar) - member __.SetProperty(itemid, propid, var) = hier.SetProperty(itemid, propid, var) - member __.GetNestedHierarchy(itemid, iidHierarchyNested, ppHierarchyNested, pitemidNested) = + member _.SetSite(psp) = hier.SetSite(psp) + member _.GetSite(psp) = hier.GetSite(ref psp) + member _.QueryClose(pfCanClose) = hier.QueryClose(ref pfCanClose) + member _.Close() = hier.Close() + member _.GetGuidProperty(itemid, propid, pguid) = hier.GetGuidProperty(itemid, propid, ref pguid) + member _.SetGuidProperty(itemid, propid, rguid) = hier.SetGuidProperty(itemid, propid, ref rguid) + member _.GetProperty(itemid, propid, pvar) = hier.GetProperty(itemid, propid, ref pvar) + member _.SetProperty(itemid, propid, var) = hier.SetProperty(itemid, propid, var) + member _.GetNestedHierarchy(itemid, iidHierarchyNested, ppHierarchyNested, pitemidNested) = hier.GetNestedHierarchy(itemid, ref iidHierarchyNested, ref ppHierarchyNested, ref pitemidNested) - member __.GetCanonicalName(itemid, pbstrName) = hier.GetCanonicalName(itemid, ref pbstrName) - member __.ParseCanonicalName(pszName, pitemid) = hier.ParseCanonicalName(pszName, ref pitemid) - member __.Unused0() = hier.Unused0() - member __.AdviseHierarchyEvents(pEventSink, pdwCookie) = hier.AdviseHierarchyEvents(pEventSink, ref pdwCookie) - member __.UnadviseHierarchyEvents(dwCookie) = hier.UnadviseHierarchyEvents(dwCookie) - member __.Unused1() = hier.Unused1() - member __.Unused2() = hier.Unused2() - member __.Unused3() = hier.Unused3() - member __.Unused4() = hier.Unused4() + member _.GetCanonicalName(itemid, pbstrName) = hier.GetCanonicalName(itemid, ref pbstrName) + member _.ParseCanonicalName(pszName, pitemid) = hier.ParseCanonicalName(pszName, ref pitemid) + member _.Unused0() = hier.Unused0() + member _.AdviseHierarchyEvents(pEventSink, pdwCookie) = hier.AdviseHierarchyEvents(pEventSink, ref pdwCookie) + member _.UnadviseHierarchyEvents(dwCookie) = hier.UnadviseHierarchyEvents(dwCookie) + member _.Unused1() = hier.Unused1() + member _.Unused2() = hier.Unused2() + member _.Unused3() = hier.Unused3() + member _.Unused4() = hier.Unused4() } /// Information about projects, open files and other active artifacts in visual studio. @@ -262,29 +257,16 @@ type internal ProjectSitesAndFiles() = | _ -> None | Some _ -> None - static let rec referencedProvideProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo:obj option, projectOptionsTable:FSharpProjectOptionsTable option) = + static let rec referencedProvideProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider) = let getReferencesForSolutionService (solutionService:IVsSolution) = [| - match referencedProjects projectSite, extraProjectInfo with - | None, Some (:? VisualStudioWorkspaceImpl as workspace) when not (isNull workspace.CurrentSolution)-> - let path = projectSite.ProjectFileName - if not (String.IsNullOrWhiteSpace(path)) then - let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(path, projectDisplayNameOf path) - let project = workspace.CurrentSolution.GetProject(projectId) - if not (isNull project) then - for reference in project.ProjectReferences do - let project = workspace.CurrentSolution.GetProject(reference.ProjectId) - if not (isNull project) && project.Language = LanguageServiceConstants.FSharpLanguageName then - let siteProvider = provideProjectSiteProvider (workspace, project, serviceProvider, projectOptionsTable) - let referenceProject = workspace.ProjectTracker.GetProject(reference.ProjectId) - let outputPath = referenceProject.BinOutputPath - yield Some projectId, project.FilePath, outputPath, siteProvider + match referencedProjects projectSite, None with | (Some references), _ -> for p in references do match solutionService.GetProjectOfUniqueName(p.UniqueName) with | VSConstants.S_OK, (:? IProvideProjectSite as ps) -> - yield None, p.FileName, (fullOutputAssemblyPath p) |> Option.defaultValue "", ps + yield p.FileName, (fullOutputAssemblyPath p) |> Option.defaultValue "", ps | _ -> () | None, _ -> () |] @@ -296,62 +278,48 @@ type internal ProjectSitesAndFiles() = | None -> () } - static let rec referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable, useUniqueStamp) = - [| for (projectId, projectFileName, outputPath, projectSiteProvider) in referencedProvideProjectSites (projectSite, serviceProvider, extraProjectInfo, projectOptionsTable) do + static let rec referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, useUniqueStamp) = + [| for (projectFileName, outputPath, projectSiteProvider) in referencedProvideProjectSites (projectSite, serviceProvider) do let referencedProjectOptions = // Lookup may not succeed if the project has not been established yet // In this case we go and compute the options recursively. match tryGetOptionsForReferencedProject projectFileName with - | None -> getProjectOptionsForProjectSite (enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSiteProvider.GetProjectSite(), serviceProvider, projectId, projectFileName, extraProjectInfo, projectOptionsTable, useUniqueStamp) |> snd + | None -> getProjectOptionsForProjectSite (enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSiteProvider.GetProjectSite(), serviceProvider, projectFileName, useUniqueStamp) |> snd | Some options -> options - yield projectFileName, (outputPath, referencedProjectOptions) |] + yield projectFileName, FSharpReferencedProject.CreateFSharp(outputPath, referencedProjectOptions) |] - and getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, fileName, extraProjectInfo, projectOptionsTable, useUniqueStamp) = + and getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, fileName, useUniqueStamp) = let referencedProjectFileNames, referencedProjectOptions = if enableInMemoryCrossProjectReferences then - referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable, useUniqueStamp) + referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, useUniqueStamp) |> Array.unzip else [| |], [| |] let option = - let newOption () = { + { ProjectFileName = projectSite.ProjectFileName ProjectId = None SourceFiles = projectSite.CompilationSourceFiles OtherOptions = projectSite.CompilationOptions ReferencedProjects = referencedProjectOptions IsIncompleteTypeCheckEnvironment = projectSite.IsIncompleteTypeCheckEnvironment - UseScriptResolutionRules = SourceFile.MustBeSingleFileProject fileName + UseScriptResolutionRules = CompilerEnvironment.MustBeSingleFileProject fileName LoadTime = projectSite.LoadTime UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo=extraProjectInfo Stamp = if useUniqueStamp then (stamp <- stamp + 1L; Some stamp) else None } - match projectId, projectOptionsTable with - | Some id, Some optionsTable -> - // Get options from cache - match optionsTable.TryGetOptionsForProject(id) with - | Some (_parsingOptions, _site, projectOptions) -> - if projectSite.CompilationSourceFiles <> projectOptions.SourceFiles || - projectSite.CompilationOptions <> projectOptions.OtherOptions || - referencedProjectOptions <> projectOptions.ReferencedProjects then - newOption() - else - projectOptions - | _ -> newOption() - | _ -> newOption() referencedProjectFileNames, option /// Construct a project site for a single file. May be a single file project (for scripts) or an orphan project site (for everything else). static member ProjectSiteOfSingleFile(filename:string) : IProjectSite = - if SourceFile.MustBeSingleFileProject(filename) then + if CompilerEnvironment.MustBeSingleFileProject(filename) then Debug.Assert(false, ".fsx or .fsscript should have been treated as implicit project") failwith ".fsx or .fsscript should have been treated as implicit project" new ProjectSiteOfSingleFile(filename) :> IProjectSite - static member GetReferencedProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo, projectOptions) = - referencedProvideProjectSites (projectSite, serviceProvider, extraProjectInfo, projectOptions) - |> Seq.map (fun (_, _, _, ps) -> ps.GetProjectSite()) + static member GetReferencedProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider) = + referencedProvideProjectSites (projectSite, serviceProvider) + |> Seq.map (fun (_, _, ps) -> ps.GetProjectSite()) |> Seq.toArray member art.SetSource_DEPRECATED(buffer:IVsTextLines, source:IFSharpSource_DEPRECATED) : unit = @@ -359,10 +327,10 @@ type internal ProjectSitesAndFiles() = (buffer :?> IVsUserData).SetData(&guid, source) |> ErrorHandler.ThrowOnFailure |> ignore /// Create project options for this project site. - static member GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite:IProjectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable, useUniqueStamp) = + static member GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite:IProjectSite, serviceProvider, filename, useUniqueStamp) = match projectSite with | :? IHaveCheckOptions as hco -> hco.OriginalCheckOptions() - | _ -> getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable, useUniqueStamp) + | _ -> getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, filename, useUniqueStamp) /// Create project site for these project options static member CreateProjectSiteForScript (filename, referencedProjectFileNames, checkOptions) = @@ -386,7 +354,7 @@ type internal ProjectSitesAndFiles() = member art.GetDefinesForFile_DEPRECATED(rdt:IVsRunningDocumentTable, filename : string, checker:FSharpChecker) = // The only caller of this function calls it each time it needs to colorize a line, so this call must execute very fast. - if SourceFile.MustBeSingleFileProject(filename) then + if CompilerEnvironment.MustBeSingleFileProject(filename) then let parsingOptions = { FSharpParsingOptions.Default with IsInteractive = true} CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions else @@ -404,7 +372,7 @@ type internal ProjectSitesAndFiles() = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions member art.TryFindOwningProject_DEPRECATED(rdt:IVsRunningDocumentTable, filename) = - if SourceFile.MustBeSingleFileProject(filename) then None + if CompilerEnvironment.MustBeSingleFileProject(filename) then None else match VsRunningDocumentTable.FindDocumentWithoutLocking(rdt,filename) with | Some(hier, _textLines) -> diff --git a/vsintegration/src/FSharp.LanguageService/Vs.fs b/vsintegration/src/FSharp.LanguageService/Vs.fs index 5ce30d677bd..95fae820b59 100644 --- a/vsintegration/src/FSharp.LanguageService/Vs.fs +++ b/vsintegration/src/FSharp.LanguageService/Vs.fs @@ -3,18 +3,12 @@ namespace Microsoft.VisualStudio.FSharp.LanguageService open System -open System.IO -open System.Collections -open System.Collections.Generic -open System.Reflection open Microsoft.VisualStudio open Microsoft.VisualStudio.Editor -open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.TextManager.Interop -open Microsoft.VisualStudio.OLE.Interop -open FSharp.Compiler.Range +open FSharp.Compiler.Text open System.Runtime.InteropServices /// Helper methods for interoperating with COM diff --git a/vsintegration/src/FSharp.LanguageService/XmlDocumentation.fs b/vsintegration/src/FSharp.LanguageService/XmlDocumentation.fs index 9ecbd65e9fa..d6871052665 100644 --- a/vsintegration/src/FSharp.LanguageService/XmlDocumentation.fs +++ b/vsintegration/src/FSharp.LanguageService/XmlDocumentation.fs @@ -6,10 +6,19 @@ namespace Microsoft.VisualStudio.FSharp.LanguageService open System +open System.Collections.Immutable open System.Text.RegularExpressions -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Layout -open FSharp.Compiler.Layout.TaggedTextOps +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.Text.TaggedText + +[] +module internal Utils2 = + let taggedTextToString (tts: TaggedText[]) = + tts |> Array.map (fun tt -> tt.Text) |> String.concat "" type internal ITaggedTextCollector_DEPRECATED = abstract Add: text: TaggedText -> unit @@ -31,7 +40,7 @@ type internal TextSanitizingCollector_DEPRECATED(collector, ?lineLimit: int) = count <- count + 1 | _ -> isEmpty <- false - endsWithLineBreak <- text.Tag = LayoutTag.LineBreak + endsWithLineBreak <- text.Tag = TextTag.LineBreak if endsWithLineBreak then count <- count + 1 collector text @@ -56,14 +65,14 @@ type internal TextSanitizingCollector_DEPRECATED(collector, ?lineLimit: int) = addTaggedTextEntry (tagText paragraph) if i < paragraphs.Length - 1 then // insert two line breaks to separate paragraphs - addTaggedTextEntry Literals.lineBreak - addTaggedTextEntry Literals.lineBreak) + addTaggedTextEntry TaggedText.lineBreak + addTaggedTextEntry TaggedText.lineBreak) interface ITaggedTextCollector_DEPRECATED with member this.Add taggedText = // TODO: bail out early if line limit is already hit match taggedText.Tag with - | LayoutTag.Text -> reportTextLines taggedText.Text + | TextTag.Text -> reportTextLines taggedText.Text | _ -> addTaggedTextEntry taggedText member this.IsEmpty = isEmpty @@ -99,7 +108,7 @@ module internal XmlDocumentation = else xml let AppendHardLine(collector: ITaggedTextCollector_DEPRECATED) = - collector.Add Literals.lineBreak + collector.Add TaggedText.lineBreak let EnsureHardLine(collector: ITaggedTextCollector_DEPRECATED) = if not collector.EndsWithLineBreak then AppendHardLine collector @@ -107,17 +116,17 @@ module internal XmlDocumentation = let AppendOnNewLine (collector: ITaggedTextCollector_DEPRECATED) (line:string) = if line.Length > 0 then EnsureHardLine collector - collector.Add(TaggedTextOps.tagText line) + collector.Add(TaggedText.tagText line) /// Append an XmlCommnet to the segment. let AppendXmlComment_DEPRECATED(documentationProvider:IDocumentationBuilder_DEPRECATED, sink: ITaggedTextCollector_DEPRECATED, xml, showExceptions, showParameters, paramName) = match xml with | FSharpXmlDoc.None -> () - | FSharpXmlDoc.XmlDocFileSignature(filename,signature) -> + | FSharpXmlDoc.FromXmlFile(filename,signature) -> documentationProvider.AppendDocumentation(sink, filename, signature, showExceptions, showParameters, paramName) - | FSharpXmlDoc.Text(rawXml) -> - let processedXml = ProcessXml(rawXml) + | FSharpXmlDoc.FromXmlText(xmlDoc) -> + let processedXml = ProcessXml("\n\n" + String.concat "\n" xmlDoc.UnprocessedLines) documentationProvider.AppendDocumentationFromProcessedXML(sink, processedXml, showExceptions, showParameters, paramName) let private AddSeparator (collector: ITaggedTextCollector_DEPRECATED) = @@ -127,7 +136,7 @@ module internal XmlDocumentation = AppendHardLine collector /// Build a data tip text string with xml comments injected. - let BuildTipText_DEPRECATED(documentationProvider:IDocumentationBuilder_DEPRECATED, dataTipText: FSharpStructuredToolTipElement list, textCollector, xmlCollector, showText, showExceptions, showParameters) = + let BuildTipText_DEPRECATED(documentationProvider:IDocumentationBuilder_DEPRECATED, dataTipText: ToolTipElement list, textCollector, xmlCollector, showText, showExceptions, showParameters) = let textCollector: ITaggedTextCollector_DEPRECATED = TextSanitizingCollector_DEPRECATED(textCollector, lineLimit = 45) :> _ let xmlCollector: ITaggedTextCollector_DEPRECATED = TextSanitizingCollector_DEPRECATED(xmlCollector, lineLimit = 45) :> _ @@ -136,21 +145,21 @@ module internal XmlDocumentation = AddSeparator textCollector AddSeparator xmlCollector - let Process add (dataTipElement: FSharpStructuredToolTipElement) = + let Process add (dataTipElement: ToolTipElement) = match dataTipElement with - | FSharpStructuredToolTipElement.None -> false + | ToolTipElement.None -> false - | FSharpStructuredToolTipElement.Group (overloads) -> + | ToolTipElement.Group (overloads) -> let overloads = Array.ofList overloads let len = overloads.Length if len >= 1 then addSeparatorIfNecessary add if showText then - let AppendOverload (item :FSharpToolTipElementData<_>) = - if not(FSharp.Compiler.Layout.isEmptyL item.MainDescription) then - if not textCollector.IsEmpty then textCollector.Add Literals.lineBreak - renderL (taggedTextListR textCollector.Add) item.MainDescription |> ignore + let AppendOverload (item :ToolTipElementData) = + if taggedTextToString item.MainDescription <> "" then + if not textCollector.IsEmpty then textCollector.Add TaggedText.lineBreak + item.MainDescription |> Seq.iter textCollector.Add AppendOverload(overloads.[0]) if len >= 2 then AppendOverload(overloads.[1]) @@ -158,14 +167,14 @@ module internal XmlDocumentation = if len >= 4 then AppendOverload(overloads.[3]) if len >= 5 then AppendOverload(overloads.[4]) if len >= 6 then - textCollector.Add Literals.lineBreak + textCollector.Add TaggedText.lineBreak textCollector.Add (tagText(PrettyNaming.FormatAndOtherOverloadsString(len-5))) let item0 = overloads.[0] item0.Remarks |> Option.iter (fun r -> - textCollector.Add Literals.lineBreak - renderL (taggedTextListR textCollector.Add) r |> ignore) + textCollector.Add TaggedText.lineBreak + r |> Seq.iter textCollector.Add |> ignore) AppendXmlComment_DEPRECATED(documentationProvider, xmlCollector, item0.XmlDoc, showExceptions, showParameters, item0.ParamName) @@ -173,16 +182,16 @@ module internal XmlDocumentation = else false - | FSharpStructuredToolTipElement.CompositionError(errText) -> + | ToolTipElement.CompositionError(errText) -> textCollector.Add(tagText errText) true List.fold Process false dataTipText |> ignore - let BuildDataTipText_DEPRECATED(documentationProvider, textCollector, xmlCollector, FSharpToolTipText(dataTipText)) = + let BuildDataTipText_DEPRECATED(documentationProvider, textCollector, xmlCollector, ToolTipText(dataTipText)) = BuildTipText_DEPRECATED(documentationProvider, dataTipText, textCollector, xmlCollector, true, true, false) - let BuildMethodOverloadTipText_DEPRECATED(documentationProvider, textCollector, xmlCollector, FSharpToolTipText(dataTipText), showParams) = + let BuildMethodOverloadTipText_DEPRECATED(documentationProvider, textCollector, xmlCollector, ToolTipText(dataTipText), showParams) = BuildTipText_DEPRECATED(documentationProvider, dataTipText, textCollector, xmlCollector, false, false, showParams) diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/AssemblyInfo.cs b/vsintegration/src/FSharp.ProjectSystem.Base/AssemblyInfo.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/AssemblyInfo.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/AssemblyInfo.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/AssemblyReferenceNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/AssemblyReferenceNode.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/AssemblyReferenceNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/AssemblyReferenceNode.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Attributes.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Attributes.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Attributes.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Attributes.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAFileItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAFileItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAFileItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAFileItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAFolderItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAFolderItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAFolderItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAFolderItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OANavigableProjectItems.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OANavigableProjectItems.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OANavigableProjectItems.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OANavigableProjectItems.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OANullProperty.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OANullProperty.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OANullProperty.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OANullProperty.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProject.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProject.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProject.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProject.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProjectItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProjectItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProjectItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProjectItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProjectItems.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProjectItems.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProjectItems.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProjectItems.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProperties.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProperties.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProperties.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProperties.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProperty.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProperty.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAProperty.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAProperty.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAReferenceFolderItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAReferenceFolderItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAReferenceFolderItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAReferenceFolderItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAReferenceItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAReferenceItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/OAReferenceItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/OAReferenceItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAAssemblyReference.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAAssemblyReference.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAAssemblyReference.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAAssemblyReference.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OABuildManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OABuildManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OABuildManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OABuildManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAComReference.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAComReference.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAComReference.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAComReference.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAProjectReference.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAProjectReference.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAProjectReference.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAProjectReference.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAReferenceBase.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAReferenceBase.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAReferenceBase.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAReferenceBase.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAReferences.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAReferences.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAReferences.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAReferences.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAVSProject.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAVSProject.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAVSProject.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAVSProject.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAVSProjectItem.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAVSProjectItem.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Automation/VSProject/OAVSProjectItem.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Automation/VSProject/OAVSProjectItem.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/BuildDependency.cs b/vsintegration/src/FSharp.ProjectSystem.Base/BuildDependency.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/BuildDependency.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/BuildDependency.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/BuildPropertyPage.cs b/vsintegration/src/FSharp.ProjectSystem.Base/BuildPropertyPage.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/BuildPropertyPage.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/BuildPropertyPage.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ComReferenceNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ComReferenceNode.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ComReferenceNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ComReferenceNode.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ConfigProvider.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ConfigProvider.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ConfigProvider.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ConfigProvider.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ConfigurationProperties.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ConfigurationProperties.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ConfigurationProperties.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ConfigurationProperties.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/DataObject.cs b/vsintegration/src/FSharp.ProjectSystem.Base/DataObject.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/DataObject.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/DataObject.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/DesignPropertyDescriptor.cs b/vsintegration/src/FSharp.ProjectSystem.Base/DesignPropertyDescriptor.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/DesignPropertyDescriptor.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/DesignPropertyDescriptor.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/DocumentManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/DocumentManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/DocumentManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/DocumentManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/EnumDependencies.cs b/vsintegration/src/FSharp.ProjectSystem.Base/EnumDependencies.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/EnumDependencies.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/EnumDependencies.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/FSharp.ProjectSystem.Base.csproj b/vsintegration/src/FSharp.ProjectSystem.Base/FSharp.ProjectSystem.Base.csproj new file mode 100644 index 00000000000..ce6326ead19 --- /dev/null +++ b/vsintegration/src/FSharp.ProjectSystem.Base/FSharp.ProjectSystem.Base.csproj @@ -0,0 +1,79 @@ + + + + + + Library + FSharp.ProjectSystem.Base + $(NoWarn),618,1570,1572,1573,1574,1591,3001,3002,3003,3005,3008,3009,3021,3024 + $(NoWarn);VSTHRD010 + $(DefineConstants);CODE_ANALYSIS + Microsoft.VisualStudio.FSharp.ProjectSystem + true + false + FSharp.ProjectSystem.Base.ruleset + + + + + + + + + + + + Microsoft.VisualStudio.Package.Project.resources + Designer + + + Resources.imagelis.bmp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FSharp.ProjectSystem.Base + $(VSAssemblyVersion) + $PackageFolder$\FSharp.ProjectSystem.Base.dll + + + + + + + + + + + diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FSharp.ProjectSystem.Base.ruleset b/vsintegration/src/FSharp.ProjectSystem.Base/FSharp.ProjectSystem.Base.ruleset similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/FSharp.ProjectSystem.Base.ruleset rename to vsintegration/src/FSharp.ProjectSystem.Base/FSharp.ProjectSystem.Base.ruleset diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FileChangeManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/FileChangeManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/FileChangeManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/FileChangeManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FileDocumentManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/FileDocumentManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/FileDocumentManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/FileDocumentManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FileNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/FileNode.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/FileNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/FileNode.cs index ae4e1084d87..3d595f79214 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FileNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/FileNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.Runtime.InteropServices; using System.Collections; @@ -370,7 +369,7 @@ public override string GetMkDocument() /// public override void DeleteFromStorage(string path) { - if (FSLib.Shim.FileSystem.SafeExists(path)) + if (File.Exists(path)) { File.SetAttributes(path, FileAttributes.Normal); // make sure it's not readonly. File.Delete(path); @@ -654,7 +653,7 @@ public override bool CanShowDefaultIcon() { string moniker = this.GetMkDocument(); - if (String.IsNullOrEmpty(moniker) || !FSLib.Shim.FileSystem.SafeExists(moniker)) + if (String.IsNullOrEmpty(moniker) || !File.Exists(moniker)) { return false; } @@ -704,7 +703,7 @@ public virtual bool IsFileOnDisk(bool showMessage) /// True if the file exist public virtual bool IsFileOnDisk(string path) { - return FSLib.Shim.FileSystem.SafeExists(path); + return File.Exists(path); } /// diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FolderNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/FolderNode.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/FolderNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/FolderNode.cs index f62c2530bfa..88603492629 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/FolderNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/FolderNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.Runtime.InteropServices; using System.Collections; @@ -393,7 +392,7 @@ private void RenameFolder(string newName) { // Verify that no directory/file already exists with the new name on disk. // If it does, just subsume that name if our directory is empty. - if (Directory.Exists(newFullPath) || FSLib.Shim.FileSystem.SafeExists(newFullPath)) + if (Directory.Exists(newFullPath) || File.Exists(newFullPath)) { // We can't delete our old directory as it is not empty if (Directory.EnumerateFileSystemEntries(this.Url).Any()) diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs b/vsintegration/src/FSharp.ProjectSystem.Base/GlobalSuppressions.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/GlobalSuppressions.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/GroupingReferenceNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/GroupingReferenceNode.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/GroupingReferenceNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/GroupingReferenceNode.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/HierarchyNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/HierarchyNode.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/HierarchyNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/HierarchyNode.cs index b17a2cdfc00..ea3b9777487 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/HierarchyNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/HierarchyNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using Microsoft.VisualStudio.Shell.Interop; using System; using System.Collections.Generic; @@ -2828,7 +2827,7 @@ public virtual int SaveItem(VSSAVEFLAGS saveFlag, string silentSaveAsName, uint { // Cleanup. this.DeleteFromStorage(docNew); - if (this is ProjectNode && FSLib.Shim.FileSystem.SafeExists(docNew)) + if (this is ProjectNode && File.Exists(docNew)) { File.Delete(docNew); } diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/IDEBuildLogger.cs b/vsintegration/src/FSharp.ProjectSystem.Base/IDEBuildLogger.cs similarity index 98% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/IDEBuildLogger.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/IDEBuildLogger.cs index 70b6cf6efaa..a223247668a 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/IDEBuildLogger.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/IDEBuildLogger.cs @@ -310,7 +310,10 @@ private void AddToErrorList( } // Add error to task list - var taskText = global::FSharp.Compiler.ErrorLogger.NewlineifyErrorString(errorEvent.Message); + // Code below is for --flaterrors flag that is only used by the IDE + + var stringThatIsAProxyForANewlineInFlatErrors = new string(new[] { (char)29 }); + var taskText = errorEvent.Message.Replace(stringThatIsAProxyForANewlineInFlatErrors, Environment.NewLine); if (errorReporter != null) { diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ImageHandler.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ImageHandler.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ImageHandler.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ImageHandler.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Interfaces.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Interfaces.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Interfaces.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Interfaces.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/LinkedFileNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/LinkedFileNode.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/LinkedFileNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/LinkedFileNode.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/LocalizableProperties.cs b/vsintegration/src/FSharp.ProjectSystem.Base/LocalizableProperties.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/LocalizableProperties.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/LocalizableProperties.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Microsoft.VisualStudio.Package.Project.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Microsoft.VisualStudio.Package.Project.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Microsoft.VisualStudio.Package.Project.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Microsoft.VisualStudio.Package.Project.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Microsoft.VisualStudio.Package.Project.resx b/vsintegration/src/FSharp.ProjectSystem.Base/Microsoft.VisualStudio.Package.Project.resx similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Microsoft.VisualStudio.Package.Project.resx rename to vsintegration/src/FSharp.ProjectSystem.Base/Microsoft.VisualStudio.Package.Project.resx diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/AutomationExtenderManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Misc/AutomationExtenderManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/AutomationExtenderManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Misc/AutomationExtenderManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/ConnectionPointContainer.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Misc/ConnectionPointContainer.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/ConnectionPointContainer.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Misc/ConnectionPointContainer.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/ExternDll.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Misc/ExternDll.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/ExternDll.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Misc/ExternDll.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/NativeMethods.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Misc/NativeMethods.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/NativeMethods.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Misc/NativeMethods.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/UnsafeNativeMethods.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Misc/UnsafeNativeMethods.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/UnsafeNativeMethods.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Misc/UnsafeNativeMethods.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/NodeProperties.cs b/vsintegration/src/FSharp.ProjectSystem.Base/NodeProperties.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/NodeProperties.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/NodeProperties.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/OleServiceProvider.cs b/vsintegration/src/FSharp.ProjectSystem.Base/OleServiceProvider.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/OleServiceProvider.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/OleServiceProvider.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Output.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Output.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Output.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Output.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/OutputGroup.cs b/vsintegration/src/FSharp.ProjectSystem.Base/OutputGroup.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/OutputGroup.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/OutputGroup.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectSystem.Base.csproj b/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectSystem.Base.csproj deleted file mode 100644 index 1604a94f3bd..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectSystem.Base.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - Library - FSharp.ProjectSystem.Base - $(NoWarn),618,1570,1572,1573,1574,1591,3001,3002,3003,3005,3008,3009,3021,3024 - $(NoWarn);VSTHRD010 - $(DefineConstants);CODE_ANALYSIS - Microsoft.VisualStudio.FSharp.ProjectSystem - true - false - FSharp.ProjectSystem.Base.ruleset - - - - - - - - - - - - Microsoft.VisualStudio.Package.Project.resources - Designer - - - Resources.imagelis.bmp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FSharp.ProjectSystem.Base - $(VSAssemblyVersion) - $PackageFolder$\FSharp.ProjectSystem.Base.dll - - - - - - - - - - - diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectBase.files b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectBase.files similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectBase.files rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectBase.files index 4343af2f328..ca2426e7221 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectBase.files +++ b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectBase.files @@ -18,9 +18,6 @@ $(FSharpSourcesRoot)\..\packages\Microsoft.Build.Framework.$(MicrosoftBuildFrameworkVersion)\lib\net46\Microsoft.Build.Framework.dll - - $(FSharpSourcesRoot)\..\packages\Microsoft.Build.$(MicrosoftBuildVersion)\lib\net46\Microsoft.Build.dll - $(FSharpSourcesRoot)\..\packages\Microsoft.Build.Utilities.Core.$(MicrosoftBuildUtilitiesCoreVersion)\lib\net46\Microsoft.Build.Utilities.Core.dll diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectConfig.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectConfig.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectConfig.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectConfig.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectDesignerDocumentManager.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectDesignerDocumentManager.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectDesignerDocumentManager.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectDesignerDocumentManager.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectElement.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectElement.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectElement.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectElement.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectFactory.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectFactory.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectFactory.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectFactory.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectFileConstants.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectFileConstants.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectFileConstants.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectFileConstants.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.CopyPaste.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.CopyPaste.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.CopyPaste.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.CopyPaste.cs index 238c2a715ca..6c5be3741c8 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.CopyPaste.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.CopyPaste.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.Collections; using System.Collections.Generic; @@ -569,7 +568,7 @@ public virtual HierarchyNode AddNodeIfTargetExistInStorage(HierarchyNode parentN { HierarchyNode newNode = parentNode; // If the file/directory exist, add a node for it - if (FSLib.Shim.FileSystem.SafeExists(targetPath)) + if (File.Exists(targetPath)) { VSADDRESULT[] result = new VSADDRESULT[1]; ErrorHandler.ThrowOnFailure(this.AddItem(parentNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, name, 1, new string[] { targetPath }, IntPtr.Zero, result)); diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.Events.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.Events.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.Events.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.Events.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.cs index 37f6af8e8e2..68b06543028 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.CodeDom.Compiler; using System.Collections; @@ -805,7 +804,7 @@ public virtual bool IsProjectFileDirty return this.isDirty; } - return (this.isDirty || !FSLib.Shim.FileSystem.SafeExists(document)); + return (this.isDirty || !File.Exists(document)); } } @@ -1272,7 +1271,7 @@ public override int SetEditLabel(string label) } // Now check whether the original file is still there. It could have been renamed. - if (!FSLib.Shim.FileSystem.SafeExists(this.Url)) + if (!File.Exists(this.Url)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileOrFolderCannotBeFound, CultureInfo.CurrentUICulture), this.ProjectFile)); } @@ -1961,7 +1960,7 @@ public virtual void Load(string fileName, string location, string name, uint fla // we also need to copy all the associated files with it. if ((flags & (uint)__VSCREATEPROJFLAGS.CPF_CLONEFILE) == (uint)__VSCREATEPROJFLAGS.CPF_CLONEFILE) { - Debug.Assert(!String.IsNullOrEmpty(fileName) && FSLib.Shim.FileSystem.SafeExists(fileName), "Invalid filename passed to load the project. A valid filename is expected"); + Debug.Assert(!String.IsNullOrEmpty(fileName) && File.Exists(fileName), "Invalid filename passed to load the project. A valid filename is expected"); this.isNewProject = true; @@ -2315,7 +2314,7 @@ public virtual void SetOrCreateBuildEventProperty(string propertyName, string pr } /// Support hex format (like 0xFF) - /// + /// /// Raise if invalid format /// The inner exception contains the real exception, of type FormatException, StackOverflowException /// @@ -2930,7 +2929,7 @@ public virtual void RenameProjectFile(string newFile) bool isFileSame = NativeMethods.IsSamePath(oldFile, newFile); // If file already exist and is not the same file with different casing - if (!isFileSame && FSLib.Shim.FileSystem.SafeExists(newFile)) + if (!isFileSame && File.Exists(newFile)) { // Prompt the user for replace string message = SR.GetString(SR.FileAlreadyExists, newFile); @@ -5009,7 +5008,7 @@ internal int AddItemWithSpecific(uint itemIdLoc, VSADDITEMOPERATION op, string i // If the file to be added is not in the same path copy it. if (NativeMethods.IsSamePath(file, newFileName) == false) { - if (!overwrite && FSLib.Shim.FileSystem.SafeExists(newFileName)) + if (!overwrite && File.Exists(newFileName)) { string message = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FileAlreadyExists, CultureInfo.CurrentUICulture), newFileName); string title = string.Empty; @@ -5239,7 +5238,7 @@ public virtual int GenerateUniqueItemName(uint itemIdLoc, string ext, string sug } else { - if (FSLib.Shim.FileSystem.SafeExists(checkFile)) + if (File.Exists(checkFile)) { found = false; break; diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectOptions.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectOptions.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectPackage.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectPackage.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectPackage.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectPackage.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectReferenceNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectReferenceNode.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectReferenceNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ProjectReferenceNode.cs index eddc77f41c8..792dd4ca796 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectReferenceNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/ProjectReferenceNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.Runtime.InteropServices; using System.Collections.Generic; @@ -713,7 +712,7 @@ public override bool CanShowDefaultIcon() return false; } - return (!String.IsNullOrEmpty(this.referencedProjectFullPath) && FSLib.Shim.FileSystem.SafeExists(this.referencedProjectFullPath)); + return (!String.IsNullOrEmpty(this.referencedProjectFullPath) && File.Exists(this.referencedProjectFullPath)); } /// diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/PropertiesEditorLauncher.cs b/vsintegration/src/FSharp.ProjectSystem.Base/PropertiesEditorLauncher.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/PropertiesEditorLauncher.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/PropertiesEditorLauncher.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ReferenceContainerNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ReferenceContainerNode.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ReferenceContainerNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ReferenceContainerNode.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ReferenceNode.cs b/vsintegration/src/FSharp.ProjectSystem.Base/ReferenceNode.cs similarity index 98% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/ReferenceNode.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/ReferenceNode.cs index bf284ad98d5..1adf2c73514 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ReferenceNode.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/ReferenceNode.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -using FSLib = FSharp.Compiler.AbstractIL.Internal.Library; using System; using System.Runtime.InteropServices; using System.Collections; @@ -305,7 +304,7 @@ public virtual Guid GetBrowseLibraryGuid() protected virtual bool CanShowUrlInOnObjectBrowser() { - return !string.IsNullOrEmpty(Url) && FSLib.Shim.FileSystem.SafeExists(Url); + return !string.IsNullOrEmpty(Url) && File.Exists(Url); } /// diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs deleted file mode 100644 index 83e17e61b8e..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute adds a custom file generator registry entry for specific file - /// type. - /// For Example: - /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\ - /// {fae04ec1-301f-11d3-bf4b-00c04f79efbc}\MyGenerator] - /// "CLSID"="{AAAA53CC-3D4F-40a2-BD4D-4F3419755476}" - /// "GeneratesDesignTimeSource" = d'1' - /// - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - public sealed class CodeGeneratorRegistrationAttribute : RegistrationAttribute - { - private string _contextGuid; - private Type _generatorType; - private Guid _generatorGuid; - private string _generatorName; - private string _generatorRegKeyName; - private bool _generatesDesignTimeSource = false; - private bool _generatesSharedDesignTimeSource = false; - /// - /// Creates a new CodeGeneratorRegistrationAttribute attribute to register a custom - /// code generator for the provided context. - /// - /// The type of Code generator. Type that implements IVsSingleFileGenerator - /// The generator name - /// The context GUID this code generator would appear under. - public CodeGeneratorRegistrationAttribute(Type generatorType, string generatorName, string contextGuid) - { - if (generatorType == null) - throw new ArgumentNullException("generatorType"); - if (generatorName == null) - throw new ArgumentNullException("generatorName"); - if (contextGuid == null) - throw new ArgumentNullException("contextGuid"); - - _contextGuid = contextGuid; - _generatorType = generatorType; - _generatorName = generatorName; - _generatorRegKeyName = generatorType.Name; - _generatorGuid = generatorType.GUID; - } - - /// - /// Get the generator Type - /// - public Type GeneratorType - { - get { return _generatorType; } - } - - /// - /// Get the Guid representing the project type - /// - public string ContextGuid - { - get { return _contextGuid; } - } - - /// - /// Get the Guid representing the generator type - /// - public Guid GeneratorGuid - { - get { return _generatorGuid; } - } - - /// - /// Get or Set the GeneratesDesignTimeSource value - /// - public bool GeneratesDesignTimeSource - { - get { return _generatesDesignTimeSource; } - set { _generatesDesignTimeSource = value; } - } - - /// - /// Get or Set the GeneratesSharedDesignTimeSource value - /// - public bool GeneratesSharedDesignTimeSource - { - get { return _generatesSharedDesignTimeSource; } - set { _generatesSharedDesignTimeSource = value; } - } - - - /// - /// Gets the Generator name - /// - public string GeneratorName - { - get { return _generatorName; } - } - - /// - /// Gets the Generator reg key name under - /// - public string GeneratorRegKeyName - { - get { return _generatorRegKeyName; } - set { _generatorRegKeyName = value; } - } - - /// - /// Property that gets the generator base key name - /// - private string GeneratorRegKey - { - get { return string.Format(CultureInfo.InvariantCulture, @"Generators\{0}\{1}", ContextGuid, GeneratorRegKeyName); } - } - /// - /// Called to register this attribute with the given context. The context - /// contains the location where the registration inforomation should be placed. - /// It also contains other information such as the type being registered and path information. - /// - public override void Register(RegistrationContext context) - { - using (Key childKey = context.CreateKey(GeneratorRegKey)) - { - childKey.SetValue(string.Empty, GeneratorName); - childKey.SetValue("CLSID", GeneratorGuid.ToString("B")); - - if (GeneratesDesignTimeSource) - childKey.SetValue("GeneratesDesignTimeSource", 1); - - if (GeneratesSharedDesignTimeSource) - childKey.SetValue("GeneratesSharedDesignTimeSource", 1); - - } - - } - - /// - /// Unregister this file extension. - /// - /// - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(GeneratorRegKey); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs deleted file mode 100644 index 0ab49e00e03..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute adds the property page registration for Component picker - /// For Example: - /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0Exp\ComponentPickerPages\My Component Page] - /// @="#13925" - /// "Package"="{B0002DC2-56EE-4931-93F7-70D6E9863940}" - /// "Page"="{0A9F3920-3881-4f50-8986-9EDEC7B33566}" - /// "Sort"=dword:00000014 - /// "AddToMru"=dword:00000000 - /// "ComponentType"=".Net Assembly" - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - public sealed class ComponentPickerPropertyPageAttribute : RegistrationAttribute - { - private string _packageGuid; - private string _pageGuid; - private string _pageRegKeyName; - - private string _componentType = null; - private int _sortOrder = -1; - private bool _addToMRU = false; - private string _defaultPageNameValue = ""; - - /// - /// Creates a new ComponentPicker page registration attribute to register a custom - /// component picker property page. - /// - /// The type of pacakge that provides the page - /// The page type that needs to be registered - /// Registry key name for the page. - public ComponentPickerPropertyPageAttribute(Type packageType, Type pageType, string pageRegKeyName) - { - if (packageType == null) - throw new ArgumentNullException("packageType"); - if (pageType == null) - throw new ArgumentNullException("pageType"); - if (pageRegKeyName == null) - throw new ArgumentNullException("pageName"); - - _packageGuid = packageType.GUID.ToString("B"); - _pageGuid = pageType.GUID.ToString("B"); - _pageRegKeyName = pageRegKeyName; - } - - /// - /// Get the pacakge Guid - /// - public string PacakgeGuid - { - get { return _packageGuid; } - } - - /// - /// Get the Guid representing the property page - /// - public string PageGuid - { - get { return _pageGuid; } - } - - /// - /// Get the property page reg key name. - /// - public string PageRegKeyName - { - get { return _pageRegKeyName; } - } - - /// - /// Get or Set the AddToMru value - /// - public bool AddToMru - { - get { return _addToMRU; } - set { _addToMRU = value; } - } - - /// - /// Get or set the Component Type value. - /// - public string ComponentType - { - get{ return _componentType; } - set{ _componentType = value; } - } - - /// - /// Get or Set the Sort reg value - /// - public int SortOrder - { - get { return _sortOrder; } - set { _sortOrder = value; } - } - - /// - /// get / sets default page name value - /// - public string DefaultPageNameValue - { - get { return _defaultPageNameValue; } - set { _defaultPageNameValue = value; } - } - - /// - /// Property that gets the page reg key name - /// - private string PageRegKey - { - get { return string.Format(CultureInfo.InvariantCulture, @"ComponentPickerPages\{0}", PageRegKeyName); } - } - /// - /// Called to register this attribute with the given context. The context - /// contains the location where the registration inforomation should be placed. - /// It also contains other information such as the type being registered and path information. - /// - public override void Register(RegistrationContext context) - { - using (Key childKey = context.CreateKey(PageRegKey)) - { - childKey.SetValue(string.Empty, DefaultPageNameValue); - childKey.SetValue("Package", PacakgeGuid); - childKey.SetValue("Page", PageGuid); - - if (SortOrder != -1) - childKey.SetValue("Sort", SortOrder); - if (AddToMru) - childKey.SetValue("AddToMru", Convert.ToInt32(AddToMru)); - if (ComponentType != null) - childKey.SetValue("ComponentType", ComponentType); - - } - - } - - /// - /// Unregister property page - /// - /// - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(PageRegKey); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs deleted file mode 100644 index ba43e3de099..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute adds a File Extension for a Project System so that the Project - /// will call IVsEditorFactoryNotify methods when an item of this type is added - /// or renamed. - /// - /// - /// For example: - /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\ - /// {F184B08F-C81C-45F6-A57F-5ABD9991F28F}\FileExtensions\.addin] - /// "EditorFactoryNotify"="{FA3CD31E-987B-443A-9B81-186104E8DAC1}" - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - [System.Runtime.InteropServices.ComVisibleAttribute(false)] - public sealed class EditorFactoryNotifyForProjectAttribute : RegistrationAttribute - { - #region Fields - private Guid projectType; - private Guid factoryType; - private string fileExtension; - #endregion - - #region Constructors - /// - /// Creates a new ProvideEditorFactoryNotifyForProject attribute to register a - /// file extension with a project. - /// - /// The type of project; can be a Type, a GUID or a string representation of a GUID - /// The type of factory; can be a Type, a GUID or a string representation of a GUID - /// The file extension the EditorFactoryNotify wants to handle - public EditorFactoryNotifyForProjectAttribute(object projectType, string fileExtension, object factoryType) - { - if (factoryType == null) - { - throw new ArgumentNullException("factoryType", "Factory type can not be null."); - } - if (projectType == null) - { - throw new ArgumentNullException("projectType", "Project type can not be null."); - } - - this.fileExtension = fileExtension; - - // figure out what type of object they passed in and get the GUID from it - if (factoryType is string) - { - this.factoryType = new Guid(factoryType.ToString()); - } - else if (factoryType is Type) - { - this.factoryType = ((Type)factoryType).GUID; - } - else if (factoryType is Guid) - { - this.factoryType = (Guid)factoryType; - } - else - { - throw new ArgumentException( "Parameter is expected to be an instance of the type 'Type' or 'Guid'.", "factoryType"); - } - - // figure out what type of object they passed in and get the GUID from it - if (projectType is string) - { - this.projectType = new Guid(projectType.ToString()); - } - else if (projectType is Type) - { - this.projectType = ((Type)projectType).GUID; - } - else if (projectType is Guid) - { - this.projectType = (Guid)projectType; - } - else - { - throw new ArgumentException("Parameter is expected to be an instance of the type 'Type' or 'Guid'.", "projectType"); - } - } - #endregion - - #region Properties - /// - /// Get the Guid representing the type of the editor factory - /// - //public Guid FactoryType - public object FactoryType - { - get { return factoryType; } - } - - /// - /// Get the Guid representing the project type - /// - public object ProjectType - { - get { return projectType; } - } - - /// - /// Get or Set the extension of the XML files that support this view - /// - public string FileExtension - { - get { return fileExtension; } - } - - /// - /// Extention path within the registration context - /// - private string ProjectFileExtensionPath - { - get - { - return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}\\FileExtensions\\{1}", projectType.ToString("B"), fileExtension); - } - } - #endregion - - #region Methods - /// - /// Called to register this attribute with the given context. The context - /// contains the location where the registration information should be placed. - /// It also contains other information such as the type being registered and path information. - /// - /// Given context to register in - public override void Register(RegistrationContext context) - { - if (context == null) - { - throw new ArgumentNullException("context"); - } - - context.Log.WriteLine(String.Format(CultureInfo.CurrentCulture, "EditorFactoryNoftifyForProject: {0} Extension = {1}\n", projectType.ToString(), fileExtension)); - - using (Key childKey = context.CreateKey(ProjectFileExtensionPath)) - { - childKey.SetValue("EditorFactoryNotify", factoryType.ToString("B")); - } - } - - /// - /// Unregister this file extension. - /// - /// Given context to unregister from - public override void Unregister(RegistrationContext context) - { - if (context != null) - { - context.RemoveKey(ProjectFileExtensionPath); - } - } - #endregion - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ProvideAppCommandLineAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ProvideAppCommandLineAttribute.cs deleted file mode 100644 index e6b95483994..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/ProvideAppCommandLineAttribute.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.ComponentModel.Design; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute adds a commandline option to devenv for a specfic package - /// type. - /// For Example: - /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\AppCommandLine\MyAppCommand - /// "Arguments"="*" - /// "DemandLoad"=dword:1 - /// "Package"="{5C48C732-5C7F-40f0-87A7-05C4F15BC8C3}" - /// "HelpString"="#200" - /// - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - public sealed class ProvideAppCommandLineAttribute : RegistrationAttribute - { - #region fields - private string _name = null; - private string _args = null; - private int _demandLoad = 0; - private Guid _pkgGuid = Guid.Empty; - private string _helpString = null; - #endregion - - #region ctors - /// - /// Constructor - /// - /// Name of new command line option - /// package type - public ProvideAppCommandLineAttribute(string name, Type packageType) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentNullException("Name is null"); - - if (packageType == null) - throw new ArgumentNullException("Package Type is null."); - - _name = name; - _pkgGuid = packageType.GUID; - } - #endregion - - #region Properties - /// - /// Name of the command line - /// - public string Name - { - get { return _name; } - set { _name = value; } - } - - /// - /// Default arguments for the command line - /// - public string Arguments - { - get { return _args; } - set { _args = value; } - } - - /// - /// Should the package be demand loaded. - /// - public int DemandLoad - { - get { return _demandLoad; } - set { _demandLoad = value; } - } - - /// - /// Guid of the package providing the command line - /// - public string PackageGuid - { - get { return _pkgGuid.ToString("B"); } - set { _pkgGuid = new Guid(value.ToString()); } - } - - /// - /// Help string to show for the command. Can be a resource id - /// - public string HelpString - { - get { return _helpString; } - set { _helpString = value; } - } - - #endregion - - #region overridden methods - /// - /// Called to register this attribute with the given context. The context - /// contains the location where the registration information should be placed. - /// it also contains such as the type being registered, and path information. - /// - public override void Register(RegistrationContext context) - { - - if (context == null) - { - throw new ArgumentNullException("context"); - } - - context.Log.WriteLine(String.Format(CultureInfo.CurrentCulture, "AppCommandLineKey: {0} \n", AppCommandLineRegKeyName)); - - using (Key childKey = context.CreateKey(AppCommandLineRegKeyName)) - { - childKey.SetValue("Arguments", Arguments); - childKey.SetValue("DemandLoad", DemandLoad); - childKey.SetValue("Package", PackageGuid); - childKey.SetValue("HelpString", HelpString); - } - } - - /// - /// Unregister this App command line - /// - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(AppCommandLineRegKeyName); - } - #endregion - - #region helpers - /// - /// The reg key name of this AppCommandLine. - /// - private string AppCommandLineRegKeyName - { - get - { - return string.Format(CultureInfo.InvariantCulture, @"AppCommandLine\{0}", Name); - } - } - #endregion - } -} - diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/SolutionPersistenceRegistrationAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/SolutionPersistenceRegistrationAttribute.cs deleted file mode 100644 index a5847ef6ab3..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/SolutionPersistenceRegistrationAttribute.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute adds a solution persistence property name and related Guid - /// type. - /// For Example: - /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0Exp\SolutionPersistence\MyProperty] - /// "Default"="{AAAA53CC-3D4F-40a2-BD4D-4F3419755476}" - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - internal sealed class SolutionPersistenceRegistrationAttribute : RegistrationAttribute - { - /// - /// Property name - /// - private string _propName; - - /// - /// Creates a new SolutionPersistenceRegistrationAttribute attribute to register a solution persistence attribute - /// for the provided context. - /// - /// Name of the property - public SolutionPersistenceRegistrationAttribute(string propName) - { - _propName = propName; - } - - /// - /// Get the property name - /// - public string PropName - { - get { return _propName; } - } - - /// - /// Property that gets the SolutionPersistence base key name - /// - private string SolutionPersistenceRegKey - { - get { return "SolutionPersistence"; } - } - - /// - /// Called to register this attribute with the given context. The context - /// contains the location where the registration inforomation should be placed. - /// It also contains other information such as the type being registered and path information. - /// - public override void Register(RegistrationContext context) - { - context.Log.WriteLine(string.Format(CultureInfo.InvariantCulture, "ProvideSolutionProps: ({0} = {1})", context.ComponentType.GUID.ToString("B"), PropName)); - Key childKey = null; - - try - { - childKey = context.CreateKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", SolutionPersistenceRegKey, PropName)); - childKey.SetValue(string.Empty, context.ComponentType.GUID.ToString("B")); - } - finally - { - if (childKey != null) childKey.Close(); - } - } - - /// - /// Unregister this property. - /// - /// - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", SolutionPersistenceRegKey, PropName)); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideLanguagePropertyAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideLanguagePropertyAttribute.cs deleted file mode 100644 index 046d45609cd..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideLanguagePropertyAttribute.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - - -using System; -using System.IO; -using System.ComponentModel; -using System.Globalization; -using Microsoft.Win32; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This class can be used for registering a Web Application Property for a project - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - internal sealed class WAProvideLanguagePropertyAttribute : RegistrationAttribute - { - private Type _languageTemplateFactoryType; - private string _propertyName; - private string _propertyValueString; - private int _propertyValueInt; - - - public WAProvideLanguagePropertyAttribute(Type languageTemplateFactoryType, string propertyName, string propertyValue) - { - _languageTemplateFactoryType = languageTemplateFactoryType; - _propertyName = propertyName; - _propertyValueString = propertyValue; - _propertyValueInt = 0; - } - - public WAProvideLanguagePropertyAttribute(Type languageTemplateFactoryType, string propertyName, int propertyValue) - { - _languageTemplateFactoryType = languageTemplateFactoryType; - _propertyName = propertyName; - _propertyValueString = null; - _propertyValueInt = propertyValue; - } - - public WAProvideLanguagePropertyAttribute(Type languageTemplateFactoryType, string propertyName, bool propertyValue) - { - _languageTemplateFactoryType = languageTemplateFactoryType; - _propertyName = propertyName; - _propertyValueString = null; - _propertyValueInt = propertyValue ? 1 : 0; - } - - public WAProvideLanguagePropertyAttribute(Type languageTemplateFactoryType, string propertyName, Type propertyValue) - { - _languageTemplateFactoryType = languageTemplateFactoryType; - _propertyName = propertyName; - _propertyValueString = propertyValue.GUID.ToString("B"); - _propertyValueInt = 0; - } - - public Type LanguageTemplateFactoryType - { - get - { - return _languageTemplateFactoryType; - } - } - - public string PropertyName - { - get - { - return _propertyName; - } - } - - public string PropertyValueString - { - get - { - return _propertyValueString; - } - } - - public int PropertyValueInt - { - get - { - return _propertyValueInt; - } - } - - private string LanguagePropertyKey - { - get { return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}\\WebApplicationProperties", LanguageTemplateFactoryType.GUID.ToString("B")); } - } - - - public override void Register(RegistrationContext context) - { - using (Key propertyKey = context.CreateKey(LanguagePropertyKey)) - { - if (PropertyValueString != null) - { - propertyKey.SetValue(PropertyName, PropertyValueString); - } - else - { - propertyKey.SetValue(PropertyName, PropertyValueInt); - } - } - } - - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(LanguagePropertyKey); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryAttribute.cs deleted file mode 100644 index 3979abce9b3..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryAttribute.cs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -extern alias ImmutableShell; - -using System; -using System.IO; -using System.ComponentModel; -using System.Globalization; -using Microsoft.Win32; - - - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute can be used to register information about a project system that supports - /// the WAP flavor/sub-type. - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - internal class WAProvideProjectFactoryAttribute : ImmutableShell::Microsoft.VisualStudio.Shell.RegistrationAttribute - { - private Type _factoryType; - private string _displayProjectFileExtensions = null; - private string _name; - private string _displayName = null; - private string _defaultProjectExtension = null; - private string _possibleProjectExtensions = null; - private string _projectTemplatesDirectory; - private int _sortPriority = 100; - private Guid _folderGuid = Guid.Empty; - private string _languageVsTemplate; - private string _templateGroupIDsVsTemplate; - private string _templateIDsVsTemplate; - private string _displayProjectTypeVsTemplate; - private string _projectSubTypeVsTemplate; - private bool _newProjectRequireNewFolderVsTemplate = false; - private bool _showOnlySpecifiedTemplatesVsTemplate = false; - - public WAProvideProjectFactoryAttribute(Type factoryType, string name) - { - if (factoryType == null) - { - throw new ArgumentNullException("factoryType"); - } - - _factoryType = factoryType; - _name = name; - } - - public WAProvideProjectFactoryAttribute(Type factoryType, - string name, - string languageVsTemplate, - bool showOnlySpecifiedTemplatesVsTemplate, - string templateGroupIDsVsTemplate, - string templateIDsVsTemplate) - { - if (factoryType == null) - { - throw new ArgumentNullException("factoryType"); - } - - _factoryType = factoryType; - _name = name; - _languageVsTemplate = languageVsTemplate; - _templateGroupIDsVsTemplate = templateGroupIDsVsTemplate; - _templateIDsVsTemplate = templateIDsVsTemplate; - _showOnlySpecifiedTemplatesVsTemplate = showOnlySpecifiedTemplatesVsTemplate; - } - - public string Name - { - get { return _name; } - } - - public string DisplayName - { - get { return _displayName; } - } - - public int SortPriority - { - get { return _sortPriority; } - set { _sortPriority = value; } - } - - public Type FactoryType - { - get - { - return _factoryType; - } - } - - public string DisplayProjectFileExtensions - { - get - { - return _displayProjectFileExtensions; - } - } - - public string DefaultProjectExtension - { - get - { - return _defaultProjectExtension; - } - } - - public string PossibleProjectExtensions - { - get - { - return _possibleProjectExtensions; - } - } - - public string ProjectTemplatesDirectory - { - get - { - return _projectTemplatesDirectory; - } - } - - public string FolderGuid - { - get { return _folderGuid.ToString("B"); } - set { _folderGuid = new Guid(value); } - } - - public string LanguageVsTemplate - { - get { return _languageVsTemplate; } - set { _languageVsTemplate = value; } - } - - public string DisplayProjectTypeVsTemplate - { - get { return _displayProjectTypeVsTemplate; } - set { _displayProjectTypeVsTemplate = value; } - } - - public string ProjectSubTypeVsTemplate - { - get { return _projectSubTypeVsTemplate; } - set { _projectSubTypeVsTemplate = value; } - } - - public bool NewProjectRequireNewFolderVsTemplate - { - get { return _newProjectRequireNewFolderVsTemplate; } - set { _newProjectRequireNewFolderVsTemplate = value; } - } - - public bool ShowOnlySpecifiedTemplatesVsTemplate - { - get { return _showOnlySpecifiedTemplatesVsTemplate; } - set { _showOnlySpecifiedTemplatesVsTemplate = value; } - } - - public string TemplateGroupIDsVsTemplate - { - get { return _templateGroupIDsVsTemplate; } - set { _templateGroupIDsVsTemplate = value; } - } - - public string TemplateIDsVsTemplate - { - get { return _templateIDsVsTemplate; } - set { _templateIDsVsTemplate = value; } - } - - private string ProjectRegKey - { - get { return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}", FactoryType.GUID.ToString("B")); } - } - - private string NewPrjTemplateRegKey(RegistrationContext context) - { - return string.Format(CultureInfo.InvariantCulture, "NewProjectTemplates\\TemplateDirs\\{0}\\/1", context.ComponentType.GUID.ToString("B")); - } - - public override void Register(RegistrationContext context) - { - //context.Log.WriteLine(SR.GetString(SR.Reg_NotifyProjectFactory, FactoryType.Name)); - - using (Key projectKey = context.CreateKey(ProjectRegKey)) - { - projectKey.SetValue(string.Empty, Name); - if (_displayName != null) - projectKey.SetValue("DisplayName", _displayName); - if (_displayProjectFileExtensions != null) - projectKey.SetValue("DisplayProjectFileExtensions", _displayProjectFileExtensions); - projectKey.SetValue("Package", context.ComponentType.GUID.ToString("B")); - if (_defaultProjectExtension != null) - projectKey.SetValue("DefaultProjectExtension", _defaultProjectExtension); - if (_possibleProjectExtensions != null) - projectKey.SetValue("PossibleProjectExtensions", _possibleProjectExtensions); - if (_projectTemplatesDirectory != null) - { - if (!System.IO.Path.IsPathRooted(_projectTemplatesDirectory)) - { - // If path is not rooted, make it relative to package path - _projectTemplatesDirectory = System.IO.Path.Combine(context.ComponentPath, _projectTemplatesDirectory); - } - projectKey.SetValue("ProjectTemplatesDir", context.EscapePath(_projectTemplatesDirectory)); - } - - // VsTemplate Specific Keys - // - if (_languageVsTemplate != null) - projectKey.SetValue("Language(VsTemplate)", _languageVsTemplate); - - if (_showOnlySpecifiedTemplatesVsTemplate || _templateGroupIDsVsTemplate != null || _templateIDsVsTemplate != null) - { - int showOnlySpecifiedTemplatesVsTemplate = _showOnlySpecifiedTemplatesVsTemplate ? 1 : 0; - projectKey.SetValue("ShowOnlySpecifiedTemplates(VsTemplate)", showOnlySpecifiedTemplatesVsTemplate); - } - - if (_templateGroupIDsVsTemplate != null) - projectKey.SetValue("TemplateGroupIDs(VsTemplate)", _templateGroupIDsVsTemplate); - - if (_templateIDsVsTemplate != null) - projectKey.SetValue("TemplateIDs(VsTemplate)", _templateIDsVsTemplate); - - if (_displayProjectTypeVsTemplate != null) - projectKey.SetValue("DisplayProjectType(VsTemplate)", _displayProjectTypeVsTemplate); - - if (_projectSubTypeVsTemplate != null) - projectKey.SetValue("ProjectSubType(VsTemplate)", _projectSubTypeVsTemplate); - - if (_newProjectRequireNewFolderVsTemplate) - projectKey.SetValue("NewProjectRequireNewFolder(VsTemplate)", (int)1); - } - } - - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(ProjectRegKey); - context.RemoveKey(NewPrjTemplateRegKey(context)); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryTemplateMappingAttribute.cs b/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryTemplateMappingAttribute.cs deleted file mode 100644 index e6f9f64707a..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.Base/RegistrationAttributes/WAProvideProjectFactoryTemplateMappingAttribute.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - - -using Microsoft.VisualStudio.Shell; -using System; -using System.ComponentModel; -using System.Globalization; - -namespace Microsoft.VisualStudio.Shell -{ - /// - /// This attribute is used to declare a new project system that supports Web Application Projects - /// and define a mapping between the real project system and the 'fake' one that is defined only - /// to store some WAP specific properties in the registry. - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - internal sealed class WAProvideProjectFactoryTemplateMappingAttribute : RegistrationAttribute - { - private const string WAPFactoryGuid = "{349c5851-65df-11da-9384-00065b846f21}"; - private string _flavoredFactoryGuid; - private Type _languageTemplateFactoryType; - - public WAProvideProjectFactoryTemplateMappingAttribute(string flavoredFactoryGuid, Type languageTemplateFactoryType) - { - _flavoredFactoryGuid = flavoredFactoryGuid; - _languageTemplateFactoryType = languageTemplateFactoryType; - } - - public string FlavoredFactoryGuid - { - get - { - return _flavoredFactoryGuid; - } - } - - public Type LanguageTemplateFactoryType - { - get - { - return _languageTemplateFactoryType; - } - } - - private string LanguageTemplatesKey - { - get { return string.Format(CultureInfo.InvariantCulture, "Projects\\{0}\\LanguageTemplates", WAPFactoryGuid); } - } - - - public override void Register(RegistrationContext context) - { - using (Key languageTemplatesKey = context.CreateKey(LanguageTemplatesKey)) - { - languageTemplatesKey.SetValue(FlavoredFactoryGuid, LanguageTemplateFactoryType.GUID.ToString("B")); - } - } - - public override void Unregister(RegistrationContext context) - { - context.RemoveKey(LanguageTemplatesKey); - } - } -} diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Resources/imagelis.bmp b/vsintegration/src/FSharp.ProjectSystem.Base/Resources/imagelis.bmp similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Resources/imagelis.bmp rename to vsintegration/src/FSharp.ProjectSystem.Base/Resources/imagelis.bmp diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SelectionListener.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SelectionListener.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SelectionListener.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SelectionListener.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListener.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SolutionListener.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListener.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SolutionListener.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectEvents.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectEvents.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectEvents.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectEvents.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectOpen.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectOpen.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectOpen.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectOpen.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectReferenceUpdate.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectReferenceUpdate.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SolutionListenerForProjectReferenceUpdate.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SolutionListenerForProjectReferenceUpdate.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/StructuresEnums.cs b/vsintegration/src/FSharp.ProjectSystem.Base/StructuresEnums.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/StructuresEnums.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/StructuresEnums.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/SuspendFileChanges.cs b/vsintegration/src/FSharp.ProjectSystem.Base/SuspendFileChanges.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/SuspendFileChanges.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/SuspendFileChanges.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Tracing.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Tracing.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Tracing.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Tracing.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/TrackDocumentsHelper.cs b/vsintegration/src/FSharp.ProjectSystem.Base/TrackDocumentsHelper.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/TrackDocumentsHelper.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/TrackDocumentsHelper.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/TypeConverters.cs b/vsintegration/src/FSharp.ProjectSystem.Base/TypeConverters.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/TypeConverters.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/TypeConverters.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/UIThread.cs b/vsintegration/src/FSharp.ProjectSystem.Base/UIThread.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/UIThread.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/UIThread.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/UpdateSolutionEventsListener.cs b/vsintegration/src/FSharp.ProjectSystem.Base/UpdateSolutionEventsListener.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/UpdateSolutionEventsListener.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/UpdateSolutionEventsListener.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Utilities.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Utilities.cs similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/Utilities.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/Utilities.cs index b638c4c69fb..00cf273f321 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/Utilities.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/Utilities.cs @@ -740,7 +740,7 @@ public static Microsoft.Build.Evaluation.Project InitializeMsBuildProject(Micros { var lclGlobalProperties = (null == globalProperties) ? new Dictionary() : new Dictionary(globalProperties) { - { "FSharpCompilerPath", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) } + { "FSharpCompilerPath", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Tools") } }; buildProject = buildEngine.LoadProject(fullProjectPath, lclGlobalProperties, null); buildProject.IsBuildEnabled = true; diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/VSMDCodeDomProvider.cs b/vsintegration/src/FSharp.ProjectSystem.Base/VSMDCodeDomProvider.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/VSMDCodeDomProvider.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/VSMDCodeDomProvider.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/VSProjectConstants.cs b/vsintegration/src/FSharp.ProjectSystem.Base/VSProjectConstants.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/VSProjectConstants.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/VSProjectConstants.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/VSShellUtilities.cs b/vsintegration/src/FSharp.ProjectSystem.Base/VSShellUtilities.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/VSShellUtilities.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/VSShellUtilities.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/VsCommands.cs b/vsintegration/src/FSharp.ProjectSystem.Base/VsCommands.cs similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/VsCommands.cs rename to vsintegration/src/FSharp.ProjectSystem.Base/VsCommands.cs diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.de.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.de.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf index d5de79f0e5c..500919c1429 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf @@ -612,7 +612,7 @@ A 'UsingTask' tag which registers the '{1}' task was found in the project file '{0}'. 'UsingTask' tags in the project file take precedence over those in the imported .TARGETS files, and therefore could be used to execute arbitrary code during an otherwise unmodified build process. - In der Projektdatei "{0}" wurde ein <UsingTask>-Tag gefunden, das die Aufgabe "{1}" registriert. <UsingTask>-Tags in der Projektdatei haben Vorrang gegenüber denen in importierten TARGETS-Dateien. Daher könnten sie dazu verwendet werden, willkürlichen Code während eines sonst unveränderten Buildprozesses auszuführen. + In der Projektdatei "{1}" wurde ein <UsingTask>-Tag gefunden, das die Aufgabe "{0}" registriert. <UsingTask>-Tags in der Projektdatei haben Vorrang gegenüber denen in importierten TARGETS-Dateien. Daher könnten sie dazu verwendet werden, willkürlichen Code während eines sonst unveränderten Buildprozesses auszuführen. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.es.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.es.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf index 98538c729e1..61528d55d61 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf @@ -131,8 +131,8 @@ Les noms de fichiers et de dossiers ne peuvent pas : - être des chaînes vides ; - être des noms réservés au système, notamment 'CON', 'AUX', PRN', 'COM1' ou 'LPT2' ; -- contenir uniquement '.' ; -- comporter les caractères suivants : / ? : & \ * " < > | # % +- contenir uniquement '.' +- comporter les caractères suivants : / ? : & \ * " < > | # % diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.it.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.it.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf similarity index 98% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf index 63dcd0ecdd7..f317034a109 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf @@ -287,7 +287,7 @@ A reference to library '{0}' cannot be added. Adding this project as a reference would cause a circular dependency. - ライブラリ '{0}' への参照を追加できません。このプロジェクトを参照として追加すると、循環する依存関係が発生します。 + ライブラリ '{0}' への参照を追加できません。このプロジェクトを参照として追加すると、循環する依存関係が発生します。 @@ -627,7 +627,7 @@ The project location is not trusted:{0}{0}{1}{0}{0}Running the application may result in security exceptions when it attempts to perform actions which require full trust.{0}{0}Click OK to ignore and continue. - プロジェクトの場所が信頼されていません: {0}{0}{1}{0}{0}このアプリケーションを実行すると、完全な信頼が必要なアクションが試行されたときに、セキュリティ例外が発生する可能性があります。{0}{0}無視して続行するには、[OK]5D; をクリックしてください。 + プロジェクトの場所が信頼されていません: {0}{0}{1}{0}{0}このアプリケーションを実行すると、完全な信頼が必要なアクションが試行されたときに、セキュリティ例外が発生する可能性があります。{0}{0}無視して続行するには、[OK] をクリックしてください。 @@ -672,7 +672,7 @@ Microsoft Visual F# does not support zero-impact projects. To create an F# project from this project template, either go to the Visual Studio menu 'Tools, Options..., Projects and Solutions, General' and check the box marked 'Save new projects when created', or specify <PromptForSaveOnCreation>true</PromptForSaveOnCreation> in the <TemplateData> section of this project template's .vstemplate file, and then retry this operation. - Microsoft Visual F# では、影響のないプロジェクトをサポートしていません。F# プロジェクトをこのプロジェクト テンプレートから作成するには、Visual Studio メニューの [ツール]5D; の [オプション]5D; をクリックし、[プロジェクトおよびソリューション]5D; の [全般]5D; の [作成時に新しいプロジェクトを保存]5D; チェック ボックスをオンにするか、またはプロジェクト テンプレートの .vstemplate ファイルの <TemplateData> セクションで <PromptForSaveOnCreation>true</PromptForSaveOnCreation> を指定し、この操作を再試行してください。 + Microsoft Visual F# では、影響のないプロジェクトをサポートしていません。F# プロジェクトをこのプロジェクト テンプレートから作成するには、Visual Studio メニューの [ツール] の [オプション] をクリックし、[プロジェクトおよびソリューション] の [全般] の [作成時に新しいプロジェクトを保存] チェック ボックスをオンにするか、またはプロジェクト テンプレートの .vstemplate ファイルの <TemplateData> セクションで <PromptForSaveOnCreation>true</PromptForSaveOnCreation> を指定し、この操作を再試行してください。 diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf similarity index 98% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf index d279159cd7d..88d0087541f 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf @@ -592,12 +592,12 @@ An 'Import' of the file '{1}' was found in the project file '{0}'. This file is not registered as a safe file to import, and could contain targets and tasks that are harmful. If this imported file is indeed considered safe, then it can be registered by writing to the registry key {2}. - В файле проекта "{0}" найден <Import> файла "{1}". Этот файл не зарегистрирован как безопасный для импорта, и может содержать опасные цели и задания. Если файл является безопасным, он может быть зарегистрирован при помощи записи в раздел реестра {2}. + В файле проекта "{1}" найден импорт файла "{0}". Этот файл не зарегистрирован как безопасный для импорта и может содержать уязвимые места или злонамеренные задачи. Если этот файл в самом деле безопасен, его можно зарегистрировать при помощи записи в раздел реестра {2}. An 'Import' of the file '{1}' was found in the user project file '{0}'. All imports in user project files are considered unsafe. - В файле проекта пользователя "{0}" найден <Import> файла "{1}". Весь импорт в пользовательских файлах проекта считается небезопасным. + В файле проекта пользователя "{0}" найден импорт файла "{1}". Весь импорт в пользовательских файлах проекта считается небезопасным. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf similarity index 100% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf similarity index 99% rename from vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf rename to vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf index ad597cad5bf..0578d7d62c6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf @@ -672,7 +672,7 @@ Microsoft Visual F# does not support zero-impact projects. To create an F# project from this project template, either go to the Visual Studio menu 'Tools, Options..., Projects and Solutions, General' and check the box marked 'Save new projects when created', or specify <PromptForSaveOnCreation>true</PromptForSaveOnCreation> in the <TemplateData> section of this project template's .vstemplate file, and then retry this operation. - Microsoft Visual F# 不支援零影響專案。若要從這個專案範本建立 F# 專案,您可以前往 Visual Studio 功能表 [工具]5D;、[選項...]5D;、[專案和方案]5D;、[一般]5D;,然後選取標記為 [建立時儲存新專案]5D;,或在這個專案範本的 .vstemplate 檔案的 <TemplateData> 區段中指定 <PromptForSaveOnCreation>true</PromptForSaveOnCreation>,然後重試這項作業。 + Microsoft Visual F# 不支援零影響專案。若要從這個專案範本建立 F# 專案,您可以前往 Visual Studio 功能表 [工具]、[選項...]、[專案和方案]、[一般],然後選取標記為 [建立時儲存新專案],或在這個專案範本的 .vstemplate 檔案的 <TemplateData> 區段中指定 <PromptForSaveOnCreation>true</PromptForSaveOnCreation>,然後重試這項作業。 diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/FSharp.ProjectSystem.FSharp.fsproj b/vsintegration/src/FSharp.ProjectSystem.FSharp/FSharp.ProjectSystem.FSharp.fsproj new file mode 100644 index 00000000000..0ab10a03ae5 --- /dev/null +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/FSharp.ProjectSystem.FSharp.fsproj @@ -0,0 +1,136 @@ + + + + + + Library + FSharp.ProjectSystem.FSharp + $(NoWarn);52;62;75 + true + $(OtherFlags) --warnon:1182 --subsystemversion:6.00 + false + + + + + + + + + + + Menus.ctmenu + Designer + + + + + + true + Microsoft.VisualStudio.FSharp.ProjectSystem.FSharpSR + true + VSPackage + Designer + $(IntermediateOutputPath)resources\ + {{FSProductVersion}} + $(FSProductVersion) + {{FSLanguageVersion}} + $(FSLanguageVersion) + + + + + + + + + + + + + FSharp.Core + 2.0.0.0 + $(FSCoreVersion) + $(FSCoreVersion) + + + FSharp.ProjectSystem.FSharp + 15.0.0.0 + $(VSAssemblyVersion) + $(VSAssemblyVersion) + + + FSharp.ProjectSystem.PropertyPages + 15.0.0.0 + $(VSAssemblyVersion) + $(VSAssemblyVersion) + + + + FSharp.Core + $(FSCoreVersion) + $PackageFolder$\FSharp.Core.dll + + + FSharp.ProjectSystem.FSharp + $(VSAssemblyVersion) + $PackageFolder$\FSharp.ProjectSystem.FSharp.dll + + + FSharp.Compiler.Service + $(FSharpCompilerServiceVersion) + $PackageFolder$\FSharp.Compiler.Service.dll + + + FSharp.Compiler.Server.Shared + $(FSProductVersion) + $PackageFolder$\FSharp.Compiler.Server.Shared.dll + + + FSharp.UIResources + $(VSAssemblyVersion) + $PackageFolder$\FSharp.UIResources.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct b/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct index 4a95e4cfcfc..b1e215a3db9 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct @@ -47,6 +47,9 @@ + + + @@ -126,6 +129,14 @@ DynamicVisibility | DefaultInvisible + + + + + + @@ -375,6 +390,7 @@ + diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml b/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml deleted file mode 100644 index c2837d0a6d5..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml +++ /dev/null @@ -1,257 +0,0 @@ - - - - - ../../../Common - - true - false - true - true - true - true - true - true - true - true - true - - - - C# Example.FSharpProject - FSharp Project - Integrating a project type for FSharp. - - - - This sample is a component of FSharp integration inside Visual Studio and it demostrates how to create a project type and a winforms designer. - The sample is based on the Project Framework and references the source code installed with the VSSDK. - Support is also included for the WPF designer. - The main goals of this sample are: - - Creating a Visual Studio project type for building Windows Forms applications using Iron FSharp - Creating a Visual Studio project type for building Web Application Projects using Iron FSharp - Creating a Visual Studio project type for building Web Site Projects using Iron FSharp - Creating a Visual Studio project type for building WPF Applications using Iron FSharp - Project.jpg - - - - - Example - 3 - Project.jpg - Iron FSharp - C# - VisualStudioIntegration\Samples\FSharpIntegration\ - Project\FSharpProject.sln - VisualStudioIntegration\Samples\FSharpIntegration\Project\TDD\ - FSharpProject.UnitTest.sln - - - Iron FSharp - Project - - - - - Open the FSharpProject.sln solution. - - - Press F5 to build the sample, register it in the experimental hive, and launch Visual Studio from the experimental hive. - - - - - - To see the sample's functionality... - - - On the File menu, click New Project to display the New Project dialog box. - - - Create a new FSharpProject Console Application. - The new solution appears in Solution Explorer, the file Program.py appears in the code editor, and the project - properties appear in the Properties Browser. - - - Right-click the project node and click Properties. - - - The Property Pages dialog box appears and displays the common and configuration properties. - - - Close the dialog box. Press F5 to build and run the FSharp program Program.py. - A console window opens, displays "Hello VSIP!", and closes. - - - - - - Visual Studio SDK Website - http://msdn.microsoft.com/vstudio/extend - - - - - Create an instance and make sure the instance implements IVsPackage. - - - Make sure that the project can add a reference. - - - - - Make sure that the project can add new FSharp items. - - - Make sure that the project can add a reference. - - - - - Automation.cs - - Contains a number of classes that enables automation of the FSharp project and py files in the Iron FSharp Project. Especially the project object enables the CodeModel - - - - ConfigurationPropertyPages.cs - - Contains a definition for the build property page in the Project Designer. - - - - EditorFactory.cs - - Contains a definition for the editor factory that creates the editor for editting iron python code files in code/design view - - - - Enums.cs - - Contains enumerations defined for the Iron FSharp Project. - - - - Guids.cs - - Defines the Package and Project guids. - - - - PkgCmd.vsct - - Defines the layout for Iron FSharp specific commands. - - - - ProjectDocumentsListenerForMainFileUpdates.cs - Implements a project listener that updates the mainfile project property in the iron python project whenever files are renamed/added/deleted - - - PropertyPages.cs - Contains the implementation for the General Tab in the Projct Designer - - - FSharpConfigProvider.cs - Enables the Any CPU Platform name for Iron FSharp Projects - - - FSharpFileNode.cs - Contains Iron FSharp specific implementation details of FileNode - - - FSharpFileNodeProperties.cs - Contains a definition of the Iron FSharp specific Node properties. The class derives from SingleFileNodeProperties which means that a Custom Tool can be associated with a py file. - - - FSharpMenus.cs - - Defines CommandIDs matching the commands defined symbols in PkgCmd.vsct. - - - - FSharpProjectFactory.cs - - Defines the Iron FSharp project factory. - - - - FSharpProjectFileConstants.cs - - Defines constants used by the Iron FSharp project file. - - - - FSharpProjectNode.cs - - Contains the implementation for the project node in the Iron FSharp Project. - - - - FSharpProjectNodeProperties.cs - Defines Iron FSharp specific Node Properties for the ProjectNode object - - - FSharpPrjectPackage.cs - - Defines the package object for Iron FSharp project package. - - - - FSharpProjectReferenceNode.cs - - Defines Iron FSharp Project specific requirements for project to project references. - - - - FSharpReferenceContainerNode.cs - - Defines the reference container node for Iron FSharp projects. - - - - SelectionElementValueChangedListener.cs - Defines a Selection changed listener that enables the RunGenerator on a python file node to be triggered when focus is removed from an active iron python document window - - - VSMDFSharpProvider.cs - Contains the definition of the FSharp CodeDOM Provider. The provider listen for reference event in order to stay in sync with list of references in the FSharp project - - - WPFProviders\FSharpEventBindingProvider.cs - Contains the FSharpEventBindingProvider which provides the communication between the WPF designer and the associated code file for adding and navigating to event handlers. - - - WPFProviders\FSharpRuntimeNameProvider.cs - Contains the FSharpRuntimeNameFactory which contains logic to generate uniquely named code fields for WPF designer scenarios. - - - WPFProviders\FSharpWPFFlavor.cs - - Contains the definition of the Iron FSharp project flavor of the WPFFlavor. - - - - WPFProviders\FSharpWPFProjectFactory.cs - - Defines the factory object for the Iron FSharp project flavor of the WPFFlavor. - - - - - - 2005-11-21 - Created this sample for the Visual Studio SDK. - - - 2007-07-19 - Added support for WPF Applications. - - - 2007-10-10 - Fixed bugs related to references. - - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs b/vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs index 3ec5d637660..38ad605c2bc 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs @@ -88,21 +88,21 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem // This interface is thread-safe, assuming "inner" is thread-safe interface Microsoft.VisualStudio.FSharp.Editor.IProjectSite with - member __.Description = inner.Description - member __.CompilationSourceFiles = inner.CompilationSourceFiles - member __.CompilationOptions = inner.CompilationOptions - member __.CompilationReferences = inner.CompilationReferences - member __.CompilationBinOutputPath = inner.CompilationBinOutputPath - member __.ProjectFileName = inner.ProjectFileName - member __.AdviseProjectSiteChanges(callbackOwnerKey,callback) = inner.AdviseProjectSiteChanges(callbackOwnerKey, callback) - member __.AdviseProjectSiteCleaned(callbackOwnerKey,callback) = inner.AdviseProjectSiteCleaned(callbackOwnerKey, callback) - member __.AdviseProjectSiteClosed(callbackOwnerKey,callback) = inner.AdviseProjectSiteClosed(callbackOwnerKey, callback) - member __.BuildErrorReporter with get() = inner.BuildErrorReporter and set v = inner.BuildErrorReporter <- v - member __.TargetFrameworkMoniker = inner.TargetFrameworkMoniker - member __.ProjectGuid = inner.ProjectGuid - member __.IsIncompleteTypeCheckEnvironment = false - member __.LoadTime = inner.LoadTime - member __.ProjectProvider = inner.ProjectProvider + member _.Description = inner.Description + member _.CompilationSourceFiles = inner.CompilationSourceFiles + member _.CompilationOptions = inner.CompilationOptions + member _.CompilationReferences = inner.CompilationReferences + member _.CompilationBinOutputPath = inner.CompilationBinOutputPath + member _.ProjectFileName = inner.ProjectFileName + member _.AdviseProjectSiteChanges(callbackOwnerKey,callback) = inner.AdviseProjectSiteChanges(callbackOwnerKey, callback) + member _.AdviseProjectSiteCleaned(callbackOwnerKey,callback) = inner.AdviseProjectSiteCleaned(callbackOwnerKey, callback) + member _.AdviseProjectSiteClosed(callbackOwnerKey,callback) = inner.AdviseProjectSiteClosed(callbackOwnerKey, callback) + member _.BuildErrorReporter with get() = inner.BuildErrorReporter and set v = inner.BuildErrorReporter <- v + member _.TargetFrameworkMoniker = inner.TargetFrameworkMoniker + member _.ProjectGuid = inner.ProjectGuid + member _.IsIncompleteTypeCheckEnvironment = false + member _.LoadTime = inner.LoadTime + member _.ProjectProvider = inner.ProjectProvider override x.ToString() = inner.ProjectFileName type internal ProjectSiteOptionLifetimeState = @@ -792,7 +792,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem /// Full path to template file /// Full path to destination file override x.AddFileFromTemplate(source:string, target:string ) = - if not (FSharp.Compiler.AbstractIL.Internal.Library.Shim.FileSystem.SafeExists(source)) then + if not (File.Exists(source)) then raise <| new FileNotFoundException(String.Format(FSharpSR.TemplateNotFound(), source)) // We assume that there is no token inside the file because the only @@ -1265,9 +1265,9 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem else 0 - member __.CompilationSourceFiles = match sourcesAndFlags with None -> [| |] | Some (sources,_) -> sources - member __.CompilationOptions = match sourcesAndFlags with None -> [| |] | Some (_,flags) -> flags - member __.CompilationReferences = match normalizedRefs with None -> [| |] | Some refs -> refs + member _.CompilationSourceFiles = match sourcesAndFlags with None -> [| |] | Some (sources,_) -> sources + member _.CompilationOptions = match sourcesAndFlags with None -> [| |] | Some (_,flags) -> flags + member _.CompilationReferences = match normalizedRefs with None -> [| |] | Some refs -> refs override x.ComputeSourcesAndFlags() = @@ -1386,32 +1386,32 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem let creationTime = System.DateTime.UtcNow { new Microsoft.VisualStudio.FSharp.Editor.IProjectSite with - member __.CompilationSourceFiles = x.CompilationSourceFiles - member __.CompilationOptions = x.CompilationOptions - member __.CompilationReferences = x.CompilationReferences - member __.CompilationBinOutputPath = + member _.CompilationSourceFiles = x.CompilationSourceFiles + member _.CompilationOptions = x.CompilationOptions + member _.CompilationReferences = x.CompilationReferences + member _.CompilationBinOutputPath = let outputPath = x.GetCurrentOutputAssembly() if String.IsNullOrWhiteSpace(outputPath) then None else Some(outputPath) - member __.Description = + member _.Description = match sourcesAndFlags with | Some (sources,flags) -> sprintf "Project System: flags(%A) sources:\n%A" flags sources | None -> sprintf "Project System, no flags available" - member __.ProjectFileName = MSBuildProject.GetFullPath(x.BuildProject) + member _.ProjectFileName = MSBuildProject.GetFullPath(x.BuildProject) - member __.BuildErrorReporter + member _.BuildErrorReporter with get() = buildErrorReporter and set v = buildErrorReporter <- v - member __.AdviseProjectSiteChanges(callbackOwnerKey,callback) = sourcesAndFlagsNotifier.Advise(callbackOwnerKey,callback) - member __.AdviseProjectSiteCleaned(callbackOwnerKey,callback) = cleanNotifier.Advise(callbackOwnerKey,callback) - member __.AdviseProjectSiteClosed(callbackOwnerKey,callback) = closeNotifier.Advise(callbackOwnerKey,callback) - member __.IsIncompleteTypeCheckEnvironment = false - member __.TargetFrameworkMoniker = x.GetTargetFrameworkMoniker() - member __.ProjectGuid = x.GetProjectGuid() - member __.LoadTime = creationTime - member __.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.Editor.IProvideProjectSite) + member _.AdviseProjectSiteChanges(callbackOwnerKey,callback) = sourcesAndFlagsNotifier.Advise(callbackOwnerKey,callback) + member _.AdviseProjectSiteCleaned(callbackOwnerKey,callback) = cleanNotifier.Advise(callbackOwnerKey,callback) + member _.AdviseProjectSiteClosed(callbackOwnerKey,callback) = closeNotifier.Advise(callbackOwnerKey,callback) + member _.IsIncompleteTypeCheckEnvironment = false + member _.TargetFrameworkMoniker = x.GetTargetFrameworkMoniker() + member _.ProjectGuid = x.GetProjectGuid() + member _.LoadTime = creationTime + member _.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.Editor.IProvideProjectSite) } // Snapshot-capture relevent values from "this", and returns an IProjectSite @@ -1430,23 +1430,23 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem // This object is thread-safe { new Microsoft.VisualStudio.FSharp.Editor.IProjectSite with - member __.Description = description - member __.CompilationSourceFiles = sourceFiles - member __.CompilationOptions = options - member __.CompilationReferences = refs - member __.CompilationBinOutputPath = if String.IsNullOrWhiteSpace(outputPath) then None else Some(outputPath) - member __.ProjectFileName = projFileName - member __.BuildErrorReporter + member _.Description = description + member _.CompilationSourceFiles = sourceFiles + member _.CompilationOptions = options + member _.CompilationReferences = refs + member _.CompilationBinOutputPath = if String.IsNullOrWhiteSpace(outputPath) then None else Some(outputPath) + member _.ProjectFileName = projFileName + member _.BuildErrorReporter with get() = staticBuildErrorReporter and set v = staticBuildErrorReporter <- v - member __.AdviseProjectSiteChanges(_,_) = () - member __.AdviseProjectSiteCleaned(_,_) = () - member __.AdviseProjectSiteClosed(_,_) = () - member __.IsIncompleteTypeCheckEnvironment = false - member __.TargetFrameworkMoniker = targetFrameworkMoniker - member __.ProjectGuid = x.GetProjectGuid() - member __.LoadTime = creationTime - member __.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.Editor.IProvideProjectSite) + member _.AdviseProjectSiteChanges(_,_) = () + member _.AdviseProjectSiteCleaned(_,_) = () + member _.AdviseProjectSiteClosed(_,_) = () + member _.IsIncompleteTypeCheckEnvironment = false + member _.TargetFrameworkMoniker = targetFrameworkMoniker + member _.ProjectGuid = x.GetProjectGuid() + member _.LoadTime = creationTime + member _.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.Editor.IProvideProjectSite) } // let the language service ask us questions diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj b/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj deleted file mode 100644 index 8408b7a2989..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - Library - FSharp.ProjectSystem.FSharp - $(NoWarn);52;62;75 - true - true - $(SystemValueTupleVersion) - $(OtherFlags) --warnon:1182 --subsystemversion:6.00 - false - - - - - - - - - - - Menus.ctmenu - Designer - - - - - - true - Microsoft.VisualStudio.FSharp.ProjectSystem.FSharpSR - true - VSPackage - Designer - $(IntermediateOutputPath)resources\ - {{FSProductVersion}} - $(FSProductVersion) - {{FSLanguageVersion}} - $(FSLanguageVersion) - - - - - - - - - - - - - FSharp.Core - 2.0.0.0 - $(FSCoreVersion) - $(FSCoreVersion) - - - FSharp.ProjectSystem.FSharp - 15.0.0.0 - $(VSAssemblyVersion) - $(VSAssemblyVersion) - - - FSharp.ProjectSystem.PropertyPages - 15.0.0.0 - $(VSAssemblyVersion) - $(VSAssemblyVersion) - - - - FSharp.Core - $(FSCoreVersion) - $PackageFolder$\FSharp.Core.dll - - - FSharp.ProjectSystem.FSharp - $(VSAssemblyVersion) - $PackageFolder$\FSharp.ProjectSystem.FSharp.dll - - - FSharp.Compiler.Private - $(FSProductVersion) - $PackageFolder$\FSharp.Compiler.Private.dll - - - FSharp.Compiler.Server.Shared - $(FSProductVersion) - $PackageFolder$\FSharp.Compiler.Server.Shared.dll - - - FSharp.UIResources - $(VSAssemblyVersion) - $PackageFolder$\FSharp.UIResources.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/Resources/FSharpTestLibrary.ico b/vsintegration/src/FSharp.ProjectSystem.FSharp/Resources/FSharpTestLibrary.ico index 671271e7595..8185c1548b6 100644 Binary files a/vsintegration/src/FSharp.ProjectSystem.FSharp/Resources/FSharpTestLibrary.ico and b/vsintegration/src/FSharp.ProjectSystem.FSharp/Resources/FSharpTestLibrary.ico differ diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/VSPackage.resx b/vsintegration/src/FSharp.ProjectSystem.FSharp/VSPackage.resx index f29e74b9ecb..8cc0c1c625e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/VSPackage.resx +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/VSPackage.resx @@ -464,10 +464,10 @@ Customizes the environment to maximize code editor screen space and improve the visibility of F# commands and tool windows. - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Microsoft Visual F# Tools 1.0 @@ -476,7 +476,7 @@ Microsoft Visual F# Tools - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Visual F# Tools F# Interactive diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/WaitDialog.fs b/vsintegration/src/FSharp.ProjectSystem.FSharp/WaitDialog.fs index 08b9de7f1d3..bd6451ef6d5 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/WaitDialog.fs +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/WaitDialog.fs @@ -38,7 +38,7 @@ module internal WaitDialog = |> Marshal.ThrowExceptionForHR { new IDisposable with - override __.Dispose () = + override _.Dispose () = let cancelled = ref 0 waitDialog.Value.EndWaitDialog cancelled |> Marshal.ThrowExceptionForHR } \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf index 02128b8f00d..80284f91346 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf @@ -247,6 +247,16 @@ Nová &složka + + Quit F# Interactive Process + Ukončit proces F# Interactive + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf index 74b69acd487..2024bc7ac4c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf @@ -247,6 +247,16 @@ &Neuer Ordner + + Quit F# Interactive Process + F# Interactive-Prozess beenden + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf index 5f286a95698..c58ac1a46fb 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf @@ -247,6 +247,16 @@ N&ueva carpeta + + Quit F# Interactive Process + Salir del proceso de F# interactivo + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf index 2e8a0c00453..4647c7fdbda 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf @@ -247,6 +247,16 @@ Nouveau &dossier + + Quit F# Interactive Process + Quitter le processus F# Interactive + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf index 5b59a67af85..231db14c05f 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf @@ -247,6 +247,16 @@ &Nuova cartella + + Quit F# Interactive Process + Chiudi il processo di F# Interactive + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf index 4266774b23c..27e442fa473 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf @@ -247,6 +247,16 @@ 新しいフォルダー(&D) + + Quit F# Interactive Process + F# インタラクティブ プロセスの終了 + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf index 1d311984cab..bd79a9f866b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf @@ -247,6 +247,16 @@ 새 폴더(&D) + + Quit F# Interactive Process + F# 대화형 프로세스 종료 + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf index 0b59a2dd7d2..265075d7f28 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf @@ -247,6 +247,16 @@ Nowy fol&der + + Quit F# Interactive Process + Zakończ proces narzędzia F# Interactive + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf index e2a2158cf9e..e7c689e5c64 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf @@ -247,6 +247,16 @@ Nova pa&sta + + Quit F# Interactive Process + Encerrar processo de F# Interativo + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf index 77e44dc54ee..c130a83a65e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf @@ -247,6 +247,16 @@ &Создать папку + + Quit F# Interactive Process + Выйти из процесса F# Interactive + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf index 4ac66f5451d..988963a34e1 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf @@ -247,6 +247,16 @@ Yeni &Klasör + + Quit F# Interactive Process + F# Etkileşimli İşleminden Çık + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf index 853138f9a59..676a80ada28 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf @@ -247,6 +247,16 @@ 新建文件夹(&D) + + Quit F# Interactive Process + 退出 F# 交互进程 + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf index 918c8824296..16e68bcc367 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf @@ -247,6 +247,16 @@ 新增資料夾(&D) + + Quit F# Interactive Process + 結束 F# 互動處理序 + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.cs.xlf index f047f0cf58d..e52a10e47bc 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.cs.xlf @@ -159,7 +159,7 @@ Script.fsx - Skript.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - Soubor.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Nástroje Microsoft Visual F# {{FSProductVersion}} pro F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Nástroje Microsoft Visual F# {{FSProductVersion}} pro F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Nástroje Visual F# {{FSProductVersion}} pro F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.de.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.de.xlf index cd550b54944..d7986c83cdc 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.de.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -304,7 +304,7 @@ Portable Library (.NET 4.5, Windows Store, Silverlight 5, Xamarin) - Portable Bibliothek (.NET 4.5, Windows Store, Silverlight 5, Xamarin) + Portierbare Bibliothek (.NET 4.5, Windows Store, Silverlight 5, Xamarin) @@ -364,7 +364,7 @@ Portable Library (.NET 4.5, Windows Store, Xamarin) - Portable Bibliothek (.NET 4.5, Windows Store, Xamarin) + Portierbare Bibliothek (.NET 4.5, Windows Store, Xamarin) @@ -374,7 +374,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin) - Portable Bibliothek (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin) + Portierbare Bibliothek (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin) @@ -384,7 +384,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) - Portable Bibliothek (.NET 4.5, Windows Store, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) + Portierbare Bibliothek (.NET 4.5, Windows Store, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} für f# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} für f# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} für F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.es.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.es.xlf index 2204dcdc7d1..1351f778505 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.es.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -304,7 +304,7 @@ Portable Library (.NET 4.5, Windows Store, Silverlight 5, Xamarin) - Biblioteca portátil (.NET 4.5, Tienda Windows, Silverlight 5, Xamarin) + Biblioteca portable (.NET 4.5, Tienda Windows, Silverlight 5, Xamarin) @@ -364,7 +364,7 @@ Portable Library (.NET 4.5, Windows Store, Xamarin) - Biblioteca portátil (.NET 4.5, Tienda Windows, Xamarin) + Biblioteca portable (.NET 4.5, Tienda Windows, Xamarin) @@ -374,7 +374,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin) - Biblioteca portátil (.NET 4.5, Tienda Windows, Windows Phone 8 Silverlight, Xamarin) + Biblioteca portable (.NET 4.5, Tienda Windows, Windows Phone 8 Silverlight, Xamarin) @@ -384,7 +384,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) - Biblioteca portátil (.NET 4.5, Tienda Windows, Windows Phone 8.1, Windows Phone Silverlight 8 y Xamarin) + Biblioteca portable (.NET 4.5, Tienda Windows, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Herramientas de Microsoft Visual F# {{FSProductVersion}} para F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Herramientas de Microsoft Visual F# - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Herramientas de Microsoft Visual F# {{FSProductVersion}} para F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Herramientas de Microsoft Visual F# @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} para F# {{FSLanguageVersion}} + Visual F# Tools + Herramientas de Visual F# diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.fr.xlf index a7bedb7cc55..1b0d94757e5 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.fr.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} pour F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} pour F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} pour F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.it.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.it.xlf index ba72bff02e0..8bd00bd0699 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.it.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} per F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} per F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} per F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ja.xlf index 710b54d5b70..d671a2f60f6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ja.xlf @@ -44,7 +44,7 @@ Specifies the default namespace for added items, such as classes, that are added via the Add New Item Dialog Box. - [新しい項目の追加]5D; ダイアログ ボックスで追加されるクラスのような、追加項目に対する既定の名前空間を指定します。 + [新しい項目の追加] ダイアログ ボックスで追加されるクラスのような、追加項目に対する既定の名前空間を指定します。 @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -304,7 +304,7 @@ Portable Library (.NET 4.5, Windows Store, Silverlight 5, Xamarin) - ポータブル ライブラリ (.NET 4.5、Windows ストア、Silverlight 5、Xamarin) + 移植可能なライブラリ (.NET 4.5、Windows ストア、Silverlight 5、Xamarin) @@ -319,7 +319,7 @@ OData Service Connection (LINQ, type provider) - OData サービス接続 (LINQ、型プロバイダー) + OData Service 接続 (LINQ、型プロバイダー) @@ -364,7 +364,7 @@ Portable Library (.NET 4.5, Windows Store, Xamarin) - ポータブル ライブラリ (.NET 4.5、Windows ストア、Xamarin) + 移植可能なライブラリ (.NET 4.5、Windows ストア、Xamarin) @@ -374,7 +374,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8 Silverlight, Xamarin) - ポータブル ライブラリ (.NET 4.5、Windows ストア、Windows Phone 8 Silverlight、Xamarin) + 移植可能なライブラリ (.NET 4.5、Windows ストア、Windows Phone 8 Silverlight、Xamarin) @@ -384,7 +384,7 @@ Portable Library (.NET 4.5, Windows Store, Windows Phone 8.1, Windows Phone Silverlight 8, Xamarin) - ポータブル ライブラリ (.NET 4.5、Windows ストア、Windows Phone 8.1、Windows Phone Silverlight 8、Xamarin) + 移植可能なライブラリ (.NET 4.5、Windows ストア、Windows Phone 8.1、Windows Phone Silverlight 8、Xamarin) @@ -429,17 +429,17 @@ Customizes the environment to maximize code editor screen space and improve the visibility of F# commands and tool windows. - コード エディターのスクリーン空間を最大化し、F# コマンドとツール ウィンドウの表示状態を改善するように環境をカスタマイズします。 + コード エディターのスクリーン空間を最大化し、F# コマンドとツール ウィンドウの表示範囲を改善するように環境をカスタマイズします。 - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} 用 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} 用 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} 用 Visual F# Tools {{FSProductVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ko.xlf index 588d5e014b9..4c029af56a6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ko.xlf @@ -44,7 +44,7 @@ Specifies the default namespace for added items, such as classes, that are added via the Add New Item Dialog Box. - 클래스처럼 [새 항목 추가]5D; 대화 상자를 통해 추가한 항목에 대해 기본 네임스페이스를 지정합니다. + 클래스처럼 [새 항목 추가] 대화 상자를 통해 추가한 항목에 대해 기본 네임스페이스를 지정합니다. @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}}용 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}}용 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}}용 Visual F# Tools {{FSProductVersion}} + Visual F# Tools + Visual F# Tools @@ -539,7 +539,7 @@ All of the Framework assemblies are already referenced. Please use the Object Browser to explore the references in the Framework. - 모든 Framework 어셈블리가 이미 참조되었습니다. [개체 브라우저]5D;를 사용하여 Framework에서 참조를 탐색하세요. + 모든 Framework 어셈블리가 이미 참조되었습니다. [개체 브라우저]를 사용하여 Framework에서 참조를 탐색하세요. diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pl.xlf index 08a4b45dfb4..3d4b03db13b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pl.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} dla języka F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} dla języka F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} dla języka F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pt-BR.xlf index 6ae72d28fde..40ee6efc5ec 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.pt-BR.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} para F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} para F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} para F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ru.xlf index 418494b459f..721ab93d325 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.ru.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} для F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} для F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} для F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.tr.xlf index 53643a6ae2a..44a3a85392c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.tr.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} için Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} için Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - F# {{FSLanguageVersion}} için Visual F# Araçları {{FSProductVersion}} + Visual F# Tools + Visual F# Tools @@ -499,7 +499,7 @@ Changing the Target Framework requires that the current project be closed and then reopened.\nAny unsaved changes within the project will be automatically saved.\n\nChanging Target Framework may require manual modification of project files in order to build.\n\nAre you sure you want to change the Target Framework for this project? - Hedef Framework'ü değiştirmek geçerli projenin kapatılıp yeniden açılmasını gerektiriyor.\nProje içindeki tüm kaydedilmemiş değişiklikler otomatik olarak kaydedilecek.\n\nHedef Framework'ü değiştirmek, yapı için proje dosyalarının el ile değiştirilmesini gerektirebilir.\nHedef Framework'ü bu proje için değiştirmek istediğinizden emin misiniz? + Hedef Framework'ü değiştirmek geçerli projenin kapatılıp yeniden açılmasını gerektiriyor.\nProje içindeki tüm kaydedilmemiş değişiklikler otomatik olarak kaydedilecek.\n\nHedef Framework'ü değiştirmek, yapı için proje dosyalarının el ile değiştirilmesini gerektirebilir.\n\nHedef Framework'ü bu proje için değiştirmek istediğinizden emin misiniz? diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hans.xlf index 4e3108b778f..bcee5688865 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hans.xlf @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -433,13 +433,13 @@ - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} + Visual F# Tools + Visual F# Tools diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hant.xlf index 7eb95bad0aa..1f70b076440 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/VSPackage.zh-Hant.xlf @@ -44,7 +44,7 @@ Specifies the default namespace for added items, such as classes, that are added via the Add New Item Dialog Box. - 為已經加入的項目指定預設命名空間,例如經由 [加入新項目]5D; 對話方塊加入的類別。 + 為已經加入的項目指定預設命名空間,例如經由 [加入新項目] 對話方塊加入的類別。 @@ -159,7 +159,7 @@ Script.fsx - Script.fsx + Script.fsx @@ -199,7 +199,7 @@ File.fs - File.fs + File.fs @@ -429,17 +429,17 @@ Customizes the environment to maximize code editor screen space and improve the visibility of F# commands and tool windows. - 自訂環境,將程式編輯器的螢幕空間最大化,並且改善 F# 命令及工具視窗的可視性。 + 自訂環境,將程式編輯器的螢幕空間最大化,並且改善 F# 命令及工具視窗的可見度。 - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - 適用於 F# {{FSLanguageVersion}} 的 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools - Microsoft Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - 適用於 F# {{FSLanguageVersion}} 的 Microsoft Visual F# Tools {{FSProductVersion}} + Microsoft Visual F# Tools + Microsoft Visual F# Tools @@ -453,8 +453,8 @@ - Visual F# Tools {{FSProductVersion}} for F# {{FSLanguageVersion}} - 適用於 F# {{FSLanguageVersion}} 的 Visual F# Tools {{FSProductVersion}} + Visual F# Tools + Visual F# 工具 diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.ProjectSystem.PropertyPages.vbproj b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.ProjectSystem.PropertyPages.vbproj new file mode 100644 index 00000000000..81fedfa6003 --- /dev/null +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.ProjectSystem.PropertyPages.vbproj @@ -0,0 +1,199 @@ + + + + + Library + + + true + FSharp.ProjectSystem.PropertyPages + true + _MYFORMS=True + false + 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 + 40026;42105;42107;42353 + net472 + win + true + false + false + true + false + false + true + 2.0 + {FCFB214C-462E-42B3-91CA-FC557EFEE74F} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7} + ProjectSystem.Base + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + Application.myapp + + + True + True + Resources.resx + + + + + + + + + ApplicationPropPage.vb + Designer + + + Designer + + + BuildEventCommandLineDialog.vb + Designer + + + BuildEventsPropPage.vb + Designer + + + BuildPropPage.vb + Designer + + + DebugPropPage.vb + Designer + + + FSharpApplicationPropPage.vb + Designer + + + ReferencePathsPropPage.vb + Designer + + + Designer + + + Designer + + + Designer + + + PropPageHostDialog.vb + Designer + + + PropPageUserControlBase.vb + Designer + + + + + MyApplicationCodeGenerator + Application.Designer.vb + + + SettingsSingleFileGenerator + My + Settings.Designer.vb + + + + + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj deleted file mode 100644 index 716a450a971..00000000000 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/FSharp.PropertiesPages.vbproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Library - - - true - FSharp.ProjectSystem.PropertyPages - true - _MYFORMS=True - false - 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 - 40026;42105;42107;42353 - net472 - win - true - false - false - true - false - false - true - 2.0 - {FCFB214C-462E-42B3-91CA-FC557EFEE74F} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {B700E38B-F8C0-4E49-B5EC-DB7B7AC0C4E7} - ProjectSystem.Base - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - - - - UserControl - - - UserControl - - - Form - - - - UserControl - - - UserControl - - - UserControl - - - - - UserControl - - - UserControl - - - - Form - - - - - - Form - - - UserControl - - - - - - - - - - - True - Application.myapp - - - True - True - Resources.resx - - - - - - - - - ApplicationPropPage.vb - Designer - - - Designer - - - BuildEventCommandLineDialog.vb - Designer - - - BuildEventsPropPage.vb - Designer - - - BuildPropPage.vb - Designer - - - DebugPropPage.vb - Designer - - - FSharpApplicationPropPage.vb - Designer - - - ReferencePathsPropPage.vb - Designer - - - Designer - - - Designer - - - Designer - - - PropPageHostDialog.vb - Designer - - - PropPageUserControlBase.vb - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - SettingsSingleFileGenerator - My - Settings.Designer.vb - - - - - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.cs.xlf index 704cd32f78d..706f0d7a5cf 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.cs.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.de.xlf index b106a3db12d..19ef6bea045 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.de.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.es.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.es.xlf index 67b3ae1eb31..46063685744 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.es.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.fr.xlf index aef6cabab2f..928faf64e3c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.fr.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.it.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.it.xlf index 8e8b37c8f64..fa96bf2e067 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.it.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ja.xlf index 4e403065188..759524df4d6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ja.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ko.xlf index 9039bb8ebaf..19d3b2c17c1 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ko.xlf @@ -9,12 +9,12 @@ ... - ... + ... Specify how application resources will be managed: - 애플리케이션 리소스 관리 방법을 지정하세요. + 애플리케이션 리소스 관리 방법을 지정하세요: diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pl.xlf index 4648179e594..1efcc0dd844 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pl.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pt-BR.xlf index 811f3f69dc9..dcf7f113984 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.pt-BR.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ru.xlf index ae557b63a14..0662d0b575c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.ru.xlf @@ -9,7 +9,7 @@ ... - ... + ... @@ -39,7 +39,7 @@ Tar&get Framework: - &Целевая рабочая среда + &Целевая рабочая среда: diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.tr.xlf index 328d27a356a..6c7eb9e57c0 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.tr.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hans.xlf index 907f66b7181..57d4baf7023 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hans.xlf @@ -9,7 +9,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hant.xlf index 990599ec5d9..8d8a26dc658 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ApplicationPropPage.zh-Hant.xlf @@ -4,12 +4,12 @@ Assembly &name: - 組件名稱(&N): + 組件名稱(&N): ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildEventsPropPage.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildEventsPropPage.tr.xlf index de0dc2a3539..42e5ebe2b78 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildEventsPropPage.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildEventsPropPage.tr.xlf @@ -44,7 +44,7 @@ Ru&n the post-build event: - Derleme sonrası olayını çalıştır: + Derle&me sonrası olayını çalıştır: diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildPropPage.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildPropPage.zh-Hans.xlf index e1ac0df50f5..7c2e31c6ad5 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildPropPage.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/BuildPropPage.zh-Hans.xlf @@ -34,7 +34,7 @@ &XML documentation file: - XML 文档文件(&X): + XML 文档文件(&X): @@ -44,7 +44,7 @@ &Output path: - 输出路径(&O): + 输出路径(&O): @@ -99,7 +99,7 @@ &Warning level: - 警告等级(&W): + 警告等级(&W): @@ -119,12 +119,12 @@ Platform tar&get: - 目标平台(&G): + 目标平台(&G): Other &flags: - 其他标志(&F): + 其他标志(&F): diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.cs.xlf index 4fbcdb22b63..7ac02a15aaa 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.cs.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.de.xlf index 2e570490493..1e54cbb6f28 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.de.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.es.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.es.xlf index 8e3b386fae2..ce87d42c672 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.es.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.fr.xlf index be876b43811..a2703f8b168 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.fr.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.it.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.it.xlf index cc4d9cd5c87..a4ef45e6f09 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.it.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ja.xlf index 0c2e2c27023..7337b3e56a6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ja.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ko.xlf index 58af1520f50..a3f48d5c264 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ko.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pl.xlf index bb6d9cc7666..58efaa7863a 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pl.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pt-BR.xlf index b65cfa5d6b3..81c8f03266e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.pt-BR.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ru.xlf index f45bb677f5c..e92b3e012f1 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.ru.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.tr.xlf index f719db87af3..cde43939c4e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.tr.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hans.xlf index d0d3cd5e240..b521bdb83f6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hans.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -39,7 +39,7 @@ Comma&nd line arguments: - 命令行参数(&N): + 命令行参数(&N): @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hant.xlf index 8d12410079c..63891fc007f 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/DebugPropPage.zh-Hant.xlf @@ -29,7 +29,7 @@ ... - ... + ... @@ -64,7 +64,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.cs.xlf index 5ef7195921c..73712c903e8 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.cs.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.de.xlf index 494cdfc5c08..bdf6fa581ca 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.de.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.es.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.es.xlf index f93118c9d9e..0bc8fc45c46 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.es.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.fr.xlf index 0424ecb7159..a37aeba751d 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.fr.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.it.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.it.xlf index 36cb07c84e8..c29a2e06ff4 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.it.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ja.xlf index 77ab12e8448..5a36dffabe9 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ja.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ko.xlf index 02369eb5f01..c4b968d9a9b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ko.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pl.xlf index 708a2d14223..a8dafc4a574 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pl.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pt-BR.xlf index 2fe1e1a6063..5f64224eb6e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.pt-BR.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ru.xlf index 9c9239c4c06..053dda2f8ac 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.ru.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.tr.xlf index 05e5266da15..53b066f77f4 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.tr.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hans.xlf index 107ed3689cd..fe4eee26c5e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hans.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hant.xlf index 910e618c7d0..b0535c113f6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/PropertyPages/xlf/ReferencePathsPropPage.zh-Hant.xlf @@ -24,7 +24,7 @@ ... - ... + ... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/Microsoft.VisualStudio.Editors.Designer.resx b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/Microsoft.VisualStudio.Editors.Designer.resx index 697e650fcbb..8701ba21d71 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/Microsoft.VisualStudio.Editors.Designer.resx +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/Microsoft.VisualStudio.Editors.Designer.resx @@ -1276,7 +1276,6 @@ CONSIDER: get this from CodeDom {0} x {1} Format string for showing a graphic's size - # {0} = width (as an integer) # {1} = height (as an integer) #Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456" diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.cs.xlf index b071e0c5f72..b45e36ef61b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.cs.xlf @@ -295,7 +295,7 @@ Vyberte prosím platnou cestu ke složce. Solution Explorer), and make changes on the Application tab. - Průzkumníku řešení), a proveďte změny v kartě Aplikace. + Průzkumníku řešení), a proveďte změny v kartě Aplikace. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.de.xlf index 4184f3edc59..0f2031ab4b6 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.de.xlf @@ -940,7 +940,7 @@ Fehler: The URL is invalid. Please enter a valid URL like "http://www.microsoft.com/" - Die URL ist ungültig. Geben Sie eine gültige URL (beispielsweise "http://www.microsoft.com/de/de/default.aspx") ein. + Die URL ist ungültig. Geben Sie eine gültige URL (beispielsweise "http://www.microsoft.com/") ein. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.fr.xlf index 99d34699194..20ea1fc286e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.fr.xlf @@ -330,7 +330,7 @@ Sélectionnez un chemin de dossier valide. Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally. - Shutdown : Déclenché après la fermeture de tous les formulaires de l'application. Cet événement n'est pas déclenché si l'application se termine de façon anormale. + Shutdown : Déclenché après la fermeture de tous les formulaires de l'application. Cet événement n'est pas déclenché si l'application se termine de façon anormale. @@ -1497,7 +1497,7 @@ Erreur : Name - Nom  + Nom @@ -1507,7 +1507,7 @@ Erreur : Name - Nom  + Nom @@ -1612,7 +1612,7 @@ Erreur : Name - Nom  + Nom Column names for the string table @@ -1798,7 +1798,7 @@ CONSIDER: get this from CodeDom Name - Nom  + Nom Columns for the "Details" view of the resource editor @@ -2335,7 +2335,7 @@ CONSIDER: get this from CodeDom Browse... - Parcourir… + Parcourir…... Added as the last item in the list of available types to let the user browse for a new type @@ -2350,7 +2350,7 @@ CONSIDER: get this from CodeDom Name - Nom  + Nom diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ja.xlf index de4d65e71f8..79837cc14b3 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ja.xlf @@ -1968,7 +1968,7 @@ CONSIDER: get this from CodeDom Portable Network Graphics - ポータブル ネットワーク グラフィックス + 移植可能なネットワーク グラフィックス Friendly Image types @@ -2062,7 +2062,7 @@ CONSIDER: get this from CodeDom Portable Network Graphics - ポータブル ネットワーク グラフィックス + 移植可能なネットワーク グラフィックス # File dialog filters # # E.g., for icons, the actual filter created would look like "Icons (*.ico)". These resources @@ -2729,7 +2729,7 @@ app.config ファイルでの新しい値は '{1}' です There was an error trying to open or create the application definition file for this project. {0} - このプロジェクトのアプリケーション定義ファイル {0} を開くときまたは作成するときにエラーが発生しました。{0} + このプロジェクトのアプリケーション定義ファイルを開くときまたは作成するときにエラーが発生しました。{0} @@ -2754,7 +2754,7 @@ app.config ファイルでの新しい値は '{1}' です An error occurred trying to create the application events file. {0} - アプリケーション イベント ファイル {0} を作成するときにエラーが発生しました。{0} + アプリケーション イベント ファイルを作成するときにエラーが発生しました。{0} @@ -2794,7 +2794,7 @@ app.config ファイルでの新しい値は '{1}' です Client application services enable your Windows-based applications to use the ASP.NET login (authentication), roles, and profile (settings) services. - クライアント アプリケーション サービスを使用すると、Windows ベースのアプリケーションから、ASP.NET ログイン (認証)、ロール、およびプロファイル (設定) サービスを使用できます。 + クライアント アプリケーション サービスを使用すると、Windows ベースのアプリケーションから、ASP.NET ログイン (認証)、ロール、およびプロファイル (設定) サービスを使用できます。 @@ -2839,7 +2839,7 @@ app.config ファイルでの新しい値は '{1}' です To enable client application services, you must set the Target Framework for your application to .NET Framework 3.5 or later. In C#, you can do this on the Application property page. In Visual Basic, you can do this one the Compile property page by clicking Advanced Compile Options. - クライアント アプリケーション サービスを有効にするには、アプリケーションのターゲット フレームワークを .NET Framework 3.5 以降に設定する必要があります。C# では、これはアプリケーション プロパティ ページで行います。Visual Basic では、[詳細コンパイル オプション]5D; をクリックしてコンパイル プロパティ ページで行います。 + クライアント アプリケーション サービスを有効にするには、アプリケーションのターゲット フレームワークを .NET Framework 3.5 以降に設定する必要があります。C# では、これはアプリケーション プロパティ ページで行います。Visual Basic では、[詳細コンパイル オプション] をクリックしてコンパイル プロパティ ページで行います。 diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ko.xlf index e7191ac3c4a..6bfd4d06886 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.ko.xlf @@ -320,7 +320,7 @@ Please select a valid folder path. The following events are available for MyApplication: - MyApplication에 대해 다음 이벤트를 사용할 수 있습니다. + MyApplication에 대해 다음 이벤트를 사용할 수 있습니다: @@ -2536,7 +2536,7 @@ app.config 파일의 새 값은 '{1}'입니다. This class allows you to handle specific events on the settings class: - 이 클래스를 사용하여 설정 클래스에 대한 특정 이벤트를 처리할 수 있습니다. + 이 클래스를 사용하여 설정 클래스에 대한 특정 이벤트를 처리할 수 있습니다: Comments for user part of extending generated settings class @@ -2561,7 +2561,7 @@ app.config 파일의 새 값은 '{1}'입니다. To add event handlers for saving and changing settings, uncomment the lines below: - 설정을 저장 및 변경하기 위한 이벤트 처리기를 추가하려면 아래 줄에서 주석 처리를 제거하세요. + 설정을 저장 및 변경하기 위한 이벤트 처리기를 추가하려면 아래 줄에서 주석 처리를 제거하세요: diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pl.xlf index 6936b8e97f5..63e978529d9 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pl.xlf @@ -547,12 +547,12 @@ Zmiana tego ustawienia spowoduje zresetowanie ustawień we wszystkich konfigurac Specify the code access security permissions that your ClickOnce application requires in order to run. Learn more about code access security... - Określ uprawnienia zabezpieczeń dostępu kodu, jakie musi spełniać aplikacja ClickOnce, aby mogła zostać uruchomiona. Dowiedz się więcej o zabezpieczeniach dostępu kodu… + Określ uprawnienia zabezpieczeń dostępu kodu, jakie musi spełniać aplikacja ClickOnce, aby mogła zostać uruchomiona. Dowiedz się więcej o zabezpieczeniach dostępu kodu... Learn more about code access security... - Dowiedz się więcej o zabezpieczeniach dostępu kodu… + Dowiedz się więcej o zabezpieczeniach dostępu kodu... @@ -975,7 +975,7 @@ Błąd: Gathering list of unused references... - Gromadzenie listy nieużywanych odwołań… + Gromadzenie listy nieużywanych odwołań... @@ -2521,7 +2521,7 @@ Czy chcesz zaktualizować wartość w pliku settings? Learn more about application settings... - Dowiedz się więcej o ustawieniach aplikacji… + Dowiedz się więcej o ustawieniach aplikacji... @@ -2799,7 +2799,7 @@ Czy chcesz zaktualizować wartość w pliku settings? Learn more about client application services... - Dowiedz się więcej o usługach aplikacji klienckich… + Dowiedz się więcej o usługach aplikacji klienckich... diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pt-BR.xlf index fefd197867e..be9117149fd 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.pt-BR.xlf @@ -108,7 +108,7 @@ Clique em OK para ignorar e continuar. Clique em CANCELAR para escolher um camin <Browse...> - <Procurar... > + <Procurar...> diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.zh-Hant.xlf index 17c64ffefb9..3943c717400 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/Microsoft.VisualStudio.Editors.Designer.zh-Hant.xlf @@ -2839,7 +2839,7 @@ app.config 檔的新值是 '{1}' To enable client application services, you must set the Target Framework for your application to .NET Framework 3.5 or later. In C#, you can do this on the Application property page. In Visual Basic, you can do this one the Compile property page by clicking Advanced Compile Options. - 若要啟用用戶端應用程式服務,必須將應用程式的目標 Framework 設定成 .NET Framework 3.5 (含) 以後版本。在 C#,您可以在 [應用程式]5D; 屬性頁上進行此設定。在 Visual Basic,您可以按一下 [進階編譯選項]5D;,在 [編譯]5D; 屬性頁上進行此設定。 + 若要啟用用戶端應用程式服務,必須將應用程式的目標 Framework 設定成 .NET Framework 3.5 (含) 以後版本。在 C#,您可以在 [應用程式] 屬性頁上進行此設定。在 Visual Basic,您可以按一下 [進階編譯選項],在 [編譯] 屬性頁上進行此設定。 @@ -2929,7 +2929,7 @@ app.config 檔的新值是 '{1}' The application will fail to run in the selected zone because of this requested elevated permission. Click the help link above for more info. - 由於這項要求的更高權限,此應用程式將無法在選取的區域中執行。如需詳細資訊,請按一下上方的 [說明]5D; 連結。 + 由於這項要求的更高權限,此應用程式將無法在選取的區域中執行。如需詳細資訊,請按一下上方的 [說明] 連結。 diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf index def3cf20486..58b9c54c371 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf @@ -134,7 +134,7 @@ Please wait for service information to be downloaded or click Stop. - サービス情報がダウンロードされるまでお待ちください。または [停止]5D; をクリックしてください。 + サービス情報がダウンロードされるまでお待ちください。または [停止] をクリックしてください。 diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf index 8ef523f70e7..26c1f9556df 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf @@ -134,7 +134,7 @@ Please wait for service information to be downloaded or click Stop. - 서비스 정보가 다운로드될 때까지 기다리거나 [중지]5D;를 클릭하세요. + 서비스 정보가 다운로드될 때까지 기다리거나 [중지]를 클릭하세요. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf index 57b2b4cfaee..458e66009a9 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf @@ -134,7 +134,7 @@ Please wait for service information to be downloaded or click Stop. - 請等候下載服務資訊,或者按一下 [停止]5D;。 + 請等候下載服務資訊,或者按一下 [停止]。 diff --git a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml index 57ca75df757..7126d6efb8b 100644 --- a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml +++ b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml @@ -24,17 +24,6 @@ - - diff --git a/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj b/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj index f5ad99e1796..05b7728d992 100644 --- a/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj +++ b/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj @@ -1,12 +1,13 @@  - + Library $(NoWarn);1591 Microsoft.VisualStudio.FSharp.UIResources false + true @@ -18,51 +19,4 @@ - - - - - - - - - - True - True - Strings.resx - - - FormattingOptionsControl.xaml - - - - - PublicResXFileCodeGenerator - Strings.Designer.cs - - - - - - - - - - - - - - - $(VS150COMNTOOLS)\..\..\MSBuild\$(VisualStudioVersion)\Bin - $(VSMSBuildBinDir)\Microsoft.CSharp.targets - - - - - false - - - - - - \ No newline at end of file + diff --git a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs index c03ff05d776..fd74fbb404f 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs +++ b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs @@ -419,14 +419,5 @@ public static string Unused_opens_code_fix { return ResourceManager.GetString("Unused_opens_code_fix", resourceCulture); } } - - /// - /// Looks up a localized string similar to (Preview) Use out of process language server. - /// - public static string Use_out_of_process_language_server { - get { - return ResourceManager.GetString("Use_out_of_process_language_server", resourceCulture); - } - } } } diff --git a/vsintegration/src/FSharp.UIResources/Strings.resx b/vsintegration/src/FSharp.UIResources/Strings.resx index 037596b7161..19f6d2658bc 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.resx +++ b/vsintegration/src/FSharp.UIResources/Strings.resx @@ -231,9 +231,6 @@ Suggest names for unresolved identifiers - - (Preview) Use out of process language server - Text hover diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf index a9808062bdd..da6e649a8ba 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf @@ -202,11 +202,6 @@ Navrhovat názvy pro nerozpoznané identifikátory - - (Preview) Use out of process language server - (Preview) Použít mimoprocesový jazykový server - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf index 9e48372cb23..653c542d13f 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf @@ -202,11 +202,6 @@ Namen für nicht aufgelöste Bezeichner vorschlagen - - (Preview) Use out of process language server - (Vorschauversion) Prozessexternen Sprachserver verwenden - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf index cd6b650ec60..39c2877127c 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf @@ -202,11 +202,6 @@ Sugerir nombres para los identificadores no resueltos - - (Preview) Use out of process language server - (Versión preliminar) Usar el servidor de lenguaje fuera del proceso - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf index 90b7e5b378c..3d73fe222b1 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf @@ -202,11 +202,6 @@ Suggérer des noms pour les identificateurs non résolus - - (Preview) Use out of process language server - (Préversion) Utiliser un serveur de langage hors processus - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf index 51b5a87f284..34d9ec67029 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf @@ -202,11 +202,6 @@ Suggerisci nomi per gli identificatori non risolti - - (Preview) Use out of process language server - (Anteprima) Usa server di linguaggio out-of-process - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf index 7a59c8c4d34..5771c8c5848 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf @@ -202,11 +202,6 @@ 未解決の識別子の名前を提案します - - (Preview) Use out of process language server - (プレビュー) プロセス外言語サーバーの使用 - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf index 8ba93bed1b4..dacb9996564 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf @@ -202,11 +202,6 @@ 확인되지 않은 식별자의 이름 제안 - - (Preview) Use out of process language server - (미리 보기) Out of Process 언어 서버 사용 - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf index 3d83c8f6ad3..4a205499f29 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf @@ -202,11 +202,6 @@ Sugeruj nazwy w przypadku nierozpoznanych identyfikatorów - - (Preview) Use out of process language server - (Wersja zapoznawcza) Korzystanie z serwera języka poza procesem - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf index e3a75c3136e..13cce041c99 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf @@ -202,11 +202,6 @@ Sugerir nomes para identificadores não resolvidos - - (Preview) Use out of process language server - (Versão Prévia) Usar um servidor de idioma fora do processo - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf index 106dcd8b87a..579c059dcd6 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf @@ -202,11 +202,6 @@ Предлагать имена для неразрешенных идентификаторов - - (Preview) Use out of process language server - (Предварительная версия) Использование сервера языка процессов - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf index 8525295e6e4..6ff42fad0e4 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf @@ -202,11 +202,6 @@ Çözümlenmemiş tanımlayıcılar için ad öner - - (Preview) Use out of process language server - (Önizleme) İşlem dışı dil sunucusunu kullanma - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf index ff0bad31447..6b0a4cd7d07 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf @@ -79,7 +79,7 @@ _Show completion list after a character is typed - 键入字符后显示完成列表 + 键入字符后显示完成列表(_S) @@ -202,11 +202,6 @@ 为未解析标识符建议名称 - - (Preview) Use out of process language server - (预览)使用进程外语言服务器 - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf index 1edc051a596..acbacbce081 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf @@ -202,11 +202,6 @@ 為未解析的識別碼建議名稱 - - (Preview) Use out of process language server - (預覽) 使用處理序語言伺服器 - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/FSharp.VS.FSI.fsproj b/vsintegration/src/FSharp.VS.FSI/FSharp.VS.FSI.fsproj index 28e4f314f5a..a3ce5bb52e2 100644 --- a/vsintegration/src/FSharp.VS.FSI/FSharp.VS.FSI.fsproj +++ b/vsintegration/src/FSharp.VS.FSI/FSharp.VS.FSI.fsproj @@ -6,8 +6,6 @@ Library $(NoWarn);47;75 true - true - $(SystemValueTupleVersion) $(OtherFlags) --subsystemversion:6.00 false @@ -23,7 +21,8 @@ - + + CompilerLocationUtils.fs @@ -44,8 +43,8 @@ - - + + @@ -70,10 +69,10 @@ - + diff --git a/vsintegration/src/FSharp.VS.FSI/Properties.resx b/vsintegration/src/FSharp.VS.FSI/Properties.resx index 8739ec83eee..ca594efbb3e 100644 --- a/vsintegration/src/FSharp.VS.FSI/Properties.resx +++ b/vsintegration/src/FSharp.VS.FSI/Properties.resx @@ -148,4 +148,20 @@ Debugging + + FSI Preview + + + Enable preview of in-development language features in F# Interactive + + + Enable preview language features + + + Use .NET Core Scripting + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt b/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt index 59f9615fffa..0e1e7979c8d 100644 --- a/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt +++ b/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt @@ -4,9 +4,10 @@ cannotCreateToolWindow,"Cannot create window F# Interactive ToolWindow" exceptionRaisedWhenCreatingRemotingClient,"Exception raised when creating remoting client for launched fsi.exe\n%s" exceptionRaisedWhenRequestingToolWindow,"Exception raised when requesting FSI ToolWindow.\n%s" couldNotObtainFSharpLS,"Could not load F# language service" -sessionTerminationDetected,"Session termination detected. Press Enter to restart." +sessionTerminationDetected,"Session termination detected." fsharpInteractive,"F# Interactive" couldNotFindFsiExe,"Could not find fsi.exe, the F# Interactive executable.\nThis file does not exist:\n\n%s\n" killingProcessRaisedException,"Killing process raised exception:\n%s" sessionIsNotDebugFriendly,"The current F# Interactive session is not configured for debugging. For the best experience, enable debugging in F# Interactive settings, then reset the session.\n\nAttempt debugging with current settings?" doNotShowWarningInFuture,"Don't show this warning again" +sessionInitialMessageNetCore,"Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings." diff --git a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs index ddff0481e7d..8e4d3974761 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs @@ -1,45 +1,18 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace Microsoft.VisualStudio.FSharp.Interactive -#if DESIGNER -#r "FSharp.Compiler.Server.Shared.dll" -#I @"C:\Program Files\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Common\Assemblies" -#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5" -#r "System.Core.dll" -#r "system.windows.forms.dll" -#r "Microsoft.VisualStudio.OLE.Interop.dll" -#r "Microsoft.VisualStudio.Package.LanguageService.9.0.dll" -#r "Microsoft.VisualStudio.Shell.9.0.dll" -#r "Microsoft.VisualStudio.Shell.Interop.dll" -#r "Microsoft.VisualStudio.Shell.Interop.8.0.dll" -#r "Microsoft.VisualStudio.Shell.Interop.9.0.dll" -#r "Microsoft.VisualStudio.TextManager.Interop.dll" -#r "Microsoft.VisualStudio.TextManager.Interop.8.0.dll" -#endif - open System -open System.IO -open System.Diagnostics -open System.Globalization open System.Text.RegularExpressions -open System.Windows.Forms open System.Runtime.InteropServices -open System.ComponentModel.Design open Microsoft.Win32 -open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.OLE.Interop -open Microsoft.VisualStudio.Shell -open Microsoft.VisualStudio.TextManager.Interop module internal AssemblyAttributes = [] do() module internal Guids = -#if FSI_SERVER_INTELLISENSE - let enable_fsi_intellisense = true -#endif // FSI Session command set let guidInteractiveCommands = Microsoft.VisualStudio.VSConstants.VsStd11 diff --git a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs index 6177d8bba25..160b7a204fa 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs @@ -3,18 +3,11 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.IO -open System.Diagnostics -open System.Globalization -open System.Windows.Forms open System.Runtime.InteropServices -open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.FSharp.Interactive open Microsoft.VisualStudio.OLE.Interop open Microsoft.VisualStudio.Shell -open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.Package open Microsoft.VisualStudio.TextManager.Interop open System.ComponentModel.Composition @@ -36,30 +29,40 @@ module internal ContentType = [] [] type FsiPropertyPage() = - inherit DialogPage() - + inherit DialogPage() + [] - [] - [] + [] + [] member this.FsiPreferAnyCPUVersion with get() = SessionsProperties.useAnyCpuVersion and set (x:bool) = SessionsProperties.useAnyCpuVersion <- x [] [] - [] + [] member this.FsiCommandLineArgs with get() = SessionsProperties.fsiArgs and set (x:string) = SessionsProperties.fsiArgs <- x [] [] - [] + [] member this.FsiShadowCopy with get() = SessionsProperties.fsiShadowCopy and set (x:bool) = SessionsProperties.fsiShadowCopy <- x [] [] - [] + [] member this.FsiDebugMode with get() = SessionsProperties.fsiDebugMode and set (x:bool) = SessionsProperties.fsiDebugMode <- x + [] + [] + [] + member this.FsiPreview with get() = SessionsProperties.fsiPreview and set (x:bool) = SessionsProperties.fsiPreview <- x + + [] + [] + [] + member this.FsiUseNetCore with get() = SessionsProperties.fsiUseNetCore and set (x:bool) = SessionsProperties.fsiUseNetCore <- x + // CompletionSet -type internal FsiCompletionSet(imageList,source:Source) = +type internal FsiCompletionSet(imageList,source:Source) = inherit CompletionSet(imageList, source) // Declarations @@ -114,26 +117,7 @@ type internal FsiAuthoringScope(sessions:FsiSessions option,readOnlySpanGetter:u null override this.GetDeclarations(_snapshot,line:int,col:int,info:TokenInfo,reason:ParseReason) = - match sessions with - | None -> (new FsiDeclarations() :> Declarations) - | Some sessions -> -#if FSI_SERVER_INTELLISENSE - if Guids.enable_fsi_intellisense then - let lines = view.GetBuffer() |> throwOnFailure1 - //NOTE: - // There is an issue of how much preceeding text to grab for the intellisense. - // Ideally, we want all text from the end of the last executed interaction. - // However, we do not have an interactive "scanner" yet. - //------ - // The decision is use the current "input area" as the source context. - // Multiline input is available to a limited degree (and could be improved). - let span = readOnlySpanGetter() - let str = lines.GetLineText(span.iEndLine,span.iEndIndex,line,col) |> throwOnFailure1 - let declInfos = sessions.GetDeclarationInfos (str:string) - new FsiDeclarations(declInfos) :> Declarations - else -#endif - (new FsiDeclarations() :> Declarations) + (new FsiDeclarations() :> Declarations) override this.GetMethods(line:int,col:int,name:string) = new FsiMethods() :> Methods diff --git a/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs b/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs index bbe816faf91..446c425a9c4 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs @@ -3,18 +3,12 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.Diagnostics -open System.Globalization -open System.Runtime.InteropServices open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop -open Microsoft.VisualStudio.OLE.Interop open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.TextManager.Interop open Util -open EnvDTE module internal Hooks = let fsiServiceCreatorCallback(package:Package) = diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs index eae479ef9e2..61ff177fd3b 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs @@ -4,10 +4,8 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System open System.Diagnostics -open System.Globalization open System.Runtime.InteropServices open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.OLE.Interop @@ -19,7 +17,6 @@ open EnvDTE open Microsoft.VisualStudio.ComponentModelHost open Microsoft.VisualStudio.Editor open Microsoft.VisualStudio.Text.Editor -open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.Utilities type VSStd2KCmdID = VSConstants.VSStd2KCmdID // nested type @@ -39,12 +36,12 @@ module internal Locals = let defaultVSRegistryRoot = @"Software\Microsoft\VisualStudio\15.0" let settingsRegistrySubKey = @"General" let debugPromptRegistryValue = "FSharpHideScriptDebugWarning" + // Prompts come through as "SERVER-PROMPT>\n" (when in "server mode"). + // In fsi.exe, the newline is needed to get the output send through to VS. + // Here the reverse mapping is applied. + let prompt = "SERVER-PROMPT>" let fixServerPrompt (str:string) = - // Prompts come through as "SERVER-PROMPT>\n" (when in "server mode"). - // In fsi.exe, the newline is needed to get the output send through to VS. - // Here the reverse mapping is applied. - let prompt = "SERVER-PROMPT>" in (* Replace 'prompt' by ">" throughout string, add newline, unless ending in prompt *) let str = if str.EndsWith(prompt) then str + " " else str + Environment.NewLine let str = str.Replace(prompt,">") @@ -197,14 +194,18 @@ type internal FsiToolWindow() as this = let history = HistoryBuffer() let sessions = Session.FsiSessions() do fsiLangService.Sessions <- sessions - let writeTextAndScroll (str:string) = + + let writeText scroll (str:string) = if str <> null && textLines <> null then lock textLines (fun () -> textStream.DirectWrite(fixServerPrompt str) - setScrollToEndOfBuffer() // I'm not convinced that users want jump to end on output. - ) // IP sample did it. Previously, VFSI did not. - // What if there is scrolling output on a timer and a user wants to look over it?? - // Maybe, if already at the end, then stay at the end? + if scroll then + setScrollToEndOfBuffer() + ) + + let writeTextAndScroll (str:string) = writeText true str + + let writeTextNoScroll (str:string) = writeText false str // Merge stdout/stderr events prior to buffering. Paired with StdOut/StdErr keys so we can split them afterwards. let responseE = Observable.merge (Observable.map (pair StdOut) sessions.Output) (Observable.map (pair StdErr) sessions.Error) @@ -222,19 +223,27 @@ type internal FsiToolWindow() as this = | StdErr,strs -> writeTextAndScroll (String.concat Environment.NewLine strs) // later: hence keep them split. do responseBufferE.Add(fun keyStrings -> let keyChunks : (Response * string list) list = chunkKeyValues keyStrings List.iter writeKeyChunk keyChunks) + let showInitialMessageNetCore scroll = + if Session.SessionsProperties.fsiUseNetCore then + writeText scroll ((VFSIstrings.SR.sessionInitialMessageNetCore()+Environment.NewLine+prompt)) // Write message on a session termination. Should be called on Gui thread. let recordTermination () = if not sessions.Alive then // check is likely redundant synchronizationContext.Post( System.Threading.SendOrPostCallback( - fun _ -> writeTextAndScroll ((VFSIstrings.SR.sessionTerminationDetected())+Environment.NewLine) + fun _ -> + writeTextAndScroll ((VFSIstrings.SR.sessionTerminationDetected())+Environment.NewLine) + showInitialMessageNetCore true ), null) do sessions.Exited.Add(fun _ -> recordTermination()) - - // finally, start the session - do sessions.Restart() + + // For .NET Core the session doesn't start automatically. Rather it may optionally be started by an Alt-Enter from a script, + // or else by pressing Enter in the REPL window. + do showInitialMessageNetCore false + if not Session.SessionsProperties.fsiUseNetCore then + sessions.Restart(null) let clearUndoStack (textLines:IVsTextLines) = // Clear the UNDO stack. let undoManager = textLines.GetUndoManager() |> throwOnFailure1 @@ -291,19 +300,15 @@ type internal FsiToolWindow() as this = strHandle.Free() ) - let executeTextNoHistory (text:string) = + let executeTextNoHistory sourceFile (text:string) = + sessions.Ensure(sourceFile) textStream.DirectWriteLine() sessions.SendInput(text) setCursorAtEndOfBuffer() - let executeText (text:string) = - textStream.DirectWriteLine() - history.Add(text) - sessions.SendInput(text) - setCursorAtEndOfBuffer() - let executeUserInput() = if isCurrentPositionInInputArea() then + sessions.Ensure(null) let text = getInputAreaText() textStream.ExtendReadOnlyMarker() textStream.DirectWriteLine() @@ -317,7 +322,8 @@ type internal FsiToolWindow() as this = let supportWhenInInputArea (sender:obj) (args:EventArgs) = let command = sender :?> MenuCommand if null <> command then // are these null checks needed? - command.Supported <- not source.IsCompletorActive && isCurrentPositionInInputArea() + let enabled = not source.IsCompletorActive && isCurrentPositionInInputArea() + command.Supported <- enabled /// Support command except when completion is active. let supportUnlessCompleting (sender:obj) (args:EventArgs) = @@ -333,13 +339,13 @@ type internal FsiToolWindow() as this = let supportWhenAtStartOfInputArea (sender:obj) (e:EventArgs) = let command = sender :?> MenuCommand if command <> null then - command.Supported <- isCurrentPositionAtStartOfInputArea() + command.Supported <- not source.IsCompletorActive && isCurrentPositionAtStartOfInputArea() /// Support when at the start of the input area AND no-selection (e.g. to enable NoAction on BACKSPACE). let supportWhenAtStartOfInputAreaAndNoSelection (sender:obj) (e:EventArgs) = let command = sender :?> MenuCommand if command <> null then - command.Supported <- isCurrentPositionAtStartOfInputArea() && not (haveTextViewSelection()) + command.Supported <- isCurrentPositionAtStartOfInputArea() let supportWhenSelectionIntersectsWithReadonlyOrNoSelection (sender:obj) (_:EventArgs) = let command = sender :?> MenuCommand @@ -414,13 +420,15 @@ type internal FsiToolWindow() as this = textLines.ReplaceLines(0, 0, lastLine, lastColumn, IntPtr.Zero, 0, null) |> throwOnFailure0 ) clearUndoStack textLines // The reset clear should not be undoable. - sessions.Restart() + showInitialMessageNetCore true + if not Session.SessionsProperties.fsiUseNetCore then + sessions.Restart(null) /// Handle RETURN, unless Intelisense completion is in progress. let onReturn (sender:obj) (e:EventArgs) = lock textLines (fun () -> if not sessions.Alive then - sessions.Restart() + sessions.Restart(null) else if isCurrentPositionInInputArea() then executeUserInput() @@ -520,10 +528,10 @@ type internal FsiToolWindow() as this = showNoActivate() let directiveC = sprintf "# 1 \"stdin\"" (* stdin line number reset code *) let text = "\n" + text + "\n" + directiveC + "\n;;\n" - executeTextNoHistory text + executeTextNoHistory null text with _ -> () - let executeInteraction dbgBreak dir filename topLine text = + let executeInteraction dbgBreak dir (filename: string) topLine text = // Preserving previous functionality, including the #directives... let interaction = "\n" @@ -534,7 +542,7 @@ type internal FsiToolWindow() as this = + "# 1 \"stdin\"" + "\n" (* stdin line number reset code *) + ";;" + "\n" - executeTextNoHistory interaction + executeTextNoHistory filename interaction let sendSelectionToFSI action = let dbgBreak,selectLine = @@ -667,7 +675,7 @@ type internal FsiToolWindow() as this = else new OleMenuCommandService(this, originalFilter) - let addCommand guid cmdId handler guard= + let addCommand guid cmdId handler guard = let id = new CommandID(guid,cmdId) let cmd = new OleMenuCommand(new EventHandler(handler),id) match guard with @@ -713,7 +721,7 @@ type internal FsiToolWindow() as this = context.AddAttribute(VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_LookupF1, "Keyword", "VS.FSharpInteractive") |> ignore | _ -> Debug.Assert(false) - member __.QueryCommandStatus(guidCmdGroup:Guid, nCmdId:uint32) = + member _.QueryCommandStatus(guidCmdGroup:Guid, nCmdId:uint32) = match () with | _ when guidCmdGroup = Guids.guidFsiConsoleCmdSet && nCmdId = uint32 Guids.cmdIDAttachDebugger -> if debuggerIsRunning () then Some(OLECMDF.OLECMDF_INVISIBLE) diff --git a/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs b/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs index 6bcac8c608e..a5e3128e872 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs @@ -3,22 +3,8 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.IO -open System.Diagnostics -open System.Globalization -open System.Windows.Forms -open System.Runtime.InteropServices -open System.ComponentModel.Design -open Microsoft.Win32 -open Microsoft.VisualStudio -open Microsoft.VisualStudio.Shell.Interop -open Microsoft.VisualStudio.OLE.Interop -open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.TextManager.Interop -open Util -open Microsoft.VisualStudio.Editor open Microsoft.VisualStudio.Text -open Microsoft.VisualStudio.Text.Editor open Microsoft.VisualStudio.Utilities // This type wraps the IVsTextLines which contains the FSI session (output and input). diff --git a/vsintegration/src/FSharp.VS.FSI/sessions.fs b/vsintegration/src/FSharp.VS.FSI/sessions.fs index b1b5a85616d..8758f3b062d 100644 --- a/vsintegration/src/FSharp.VS.FSI/sessions.fs +++ b/vsintegration/src/FSharp.VS.FSI/sessions.fs @@ -2,15 +2,12 @@ module internal Microsoft.VisualStudio.FSharp.Interactive.Session -open FSharp.Compiler open System open System.IO open System.Text open System.Diagnostics open System.Runtime.Remoting open System.Runtime.Remoting.Lifetime -open System.Windows.Forms -open Internal.Utilities #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation @@ -66,10 +63,12 @@ let timeoutApp descr timeoutMS (f : 'a -> 'b) (arg:'a) = r module SessionsProperties = - let mutable useAnyCpuVersion = true // 64-bit by default + let mutable useAnyCpuVersion = true // 64-bit by default + let mutable fsiUseNetCore = true // NetCore by default let mutable fsiArgs = "--optimize" let mutable fsiShadowCopy = true let mutable fsiDebugMode = false + let mutable fsiPreview = false // This code pre-dates the events/object system. // Later: Tidy up. @@ -129,37 +128,48 @@ let catchAll trigger x = try trigger x with err -> System.Windows.Forms.MessageBox.Show(err.ToString()) |> ignore -let fsiExeName () = - if SessionsProperties.useAnyCpuVersion then "fsiAnyCpu.exe" else "fsi.exe" - -// Use the VS-extension-installed development path if available, relative to the location of this assembly -let determineFsiRelativePath1 () = - let thisAssemblyDirectory = typeof.Assembly.Location |> Path.GetDirectoryName - Path.Combine(thisAssemblyDirectory,fsiExeName() ) - -// This path is relative to the location of "FSharp.Compiler.Interactive.Settings.dll" -let determineFsiRelativePath2 () = - let thisAssembly : System.Reflection.Assembly = typeof.Assembly - let thisAssemblyDirectory = thisAssembly.Location |> Path.GetDirectoryName - // Use the quick-development path if available - Path.Combine(thisAssemblyDirectory,fsiExeName() ) - let determineFsiPath () = - // Choose VS extension path, if it exists (for developers) - let fsiRelativePath1 = determineFsiRelativePath1() - if File.Exists fsiRelativePath1 then fsiRelativePath1 else - - // Choose relative path, if it exists (for developers), otherwise, the installed path. - let fsiRelativePath2 = determineFsiRelativePath2() - if File.Exists fsiRelativePath2 then fsiRelativePath2 else - - // Try the registry key - let fsbin = match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None) with Some(s) -> s | None -> "" - let fsiRegistryPath = Path.Combine(fsbin, fsiExeName() ) - if File.Exists(fsiRegistryPath) then fsiRegistryPath else - - // Otherwise give up - raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath)) + if SessionsProperties.fsiUseNetCore then + let pf = Environment.GetEnvironmentVariable("ProgramW6432") + let pf = if String.IsNullOrEmpty(pf) then Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) else pf + let exe = Path.Combine(pf,"dotnet","dotnet.exe") + let arg = "fsi" + if not (File.Exists exe) then + raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe exe)) + exe, arg, false, false + else + let fsiExeName () = + if SessionsProperties.useAnyCpuVersion then "fsiAnyCpu.exe" else "fsi.exe" + + // Use the VS-extension-installed development path if available, relative to the location of this assembly + let determineFsiRelativePath1 () = + let thisAssemblyDirectory = typeof.Assembly.Location |> Path.GetDirectoryName + Path.Combine(thisAssemblyDirectory,fsiExeName() ) + + // This path is relative to the location of "FSharp.Compiler.Interactive.Settings.dll" + let determineFsiRelativePath2 () = + let thisAssembly : System.Reflection.Assembly = typeof.Assembly + let thisAssemblyDirectory = thisAssembly.Location |> Path.GetDirectoryName + // Use the quick-development path if available + Path.Combine(thisAssemblyDirectory, "Tools", fsiExeName() ) + + let fsiExe = + // Choose VS extension path, if it exists (for developers) + let fsiRelativePath1 = determineFsiRelativePath1() + if File.Exists fsiRelativePath1 then fsiRelativePath1 else + + // Choose relative path, if it exists (for developers), otherwise, the installed path. + let fsiRelativePath2 = determineFsiRelativePath2() + if File.Exists fsiRelativePath2 then fsiRelativePath2 else + + // Try the registry key + let fsbin = match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None) with Some(s) -> s | None -> "" + let fsiRegistryPath = Path.Combine(fsbin, "Tools", fsiExeName() ) + if File.Exists(fsiRegistryPath) then fsiRegistryPath else + + // Otherwise give up + raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath)) + fsiExe, "", true, true let readLinesAsync (reader: StreamReader) trigger = let buffer = StringBuilder(1024) @@ -205,9 +215,9 @@ let readLinesAsync (reader: StreamReader) trigger = } Async.StartImmediate (read 0) -let fsiStartInfo channelName = +let fsiStartInfo channelName sourceFile = let procInfo = new ProcessStartInfo() - let fsiPath = determineFsiPath () + let fsiPath, fsiFirstArgs, fsiSupportsServer, fsiSupportsShadowcopy = determineFsiPath () procInfo.FileName <- fsiPath // Mismatched encoding on I/O streams between VS addin and it's FSI session. @@ -216,22 +226,23 @@ let fsiStartInfo channelName = // We also need to send fsi.exe the locale of the VS process let inCP,outCP = Encoding.UTF8.CodePage,Encoding.UTF8.CodePage - let addBoolOption name value args = sprintf "%s --%s%s" args name (if value then "+" else "-") - let addStringOption name value args = sprintf "%s --%s:%O" args name value - + let addBoolOption b name value args = if b then sprintf "%s --%s%s" args name (if value then "+" else "-") else args + let addStringOption b name value args = if b then sprintf "%s --%s:%O" args name value else args + let procArgs = - "" - |> addStringOption "fsi-server-output-codepage" outCP - |> addStringOption "fsi-server-input-codepage" inCP - |> addStringOption "fsi-server-lcid" System.Threading.Thread.CurrentThread.CurrentUICulture.LCID - |> addStringOption "fsi-server" channelName + fsiFirstArgs + |> addStringOption true "fsi-server-output-codepage" outCP + |> addStringOption true "fsi-server-input-codepage" inCP + |> addStringOption true "fsi-server-lcid" System.Threading.Thread.CurrentThread.CurrentUICulture.LCID + //|> addStringOption true "fsi-server-association-file" sourceFile + |> addStringOption true "fsi-server" channelName |> (fun s -> s + sprintf " %s" SessionsProperties.fsiArgs) - |> addBoolOption "shadowcopyreferences" SessionsProperties.fsiShadowCopy - |> (fun args -> if SessionsProperties.fsiDebugMode then - // for best debug experience, need optimizations OFF and debug info ON - // tack these on the the end, they will override whatever comes earlier - args |> addBoolOption "optimize" false |> addBoolOption "debug" true - else args) + |> addBoolOption fsiSupportsShadowcopy "shadowcopyreferences" SessionsProperties.fsiShadowCopy + // For best debug experience, need optimizations OFF and debug info ON + // tack these on the the end, they will override whatever comes earlier + |> addBoolOption SessionsProperties.fsiDebugMode "optimize" false + |> addBoolOption SessionsProperties.fsiDebugMode "debug" true + |> addStringOption SessionsProperties.fsiPreview "langversion" "preview" procInfo.Arguments <- procArgs procInfo.CreateNoWindow <- true @@ -241,16 +252,20 @@ let fsiStartInfo channelName = procInfo.RedirectStandardOutput <- true procInfo.StandardOutputEncoding <- Encoding.UTF8 procInfo.StandardErrorEncoding <- Encoding.UTF8 - let tmpPath = Path.GetTempPath() - if Directory.Exists(tmpPath) then - procInfo.WorkingDirectory <- tmpPath - procInfo + + let initialPath = + match sourceFile with + | path when path <> null && Directory.Exists(Path.GetDirectoryName(path)) -> Path.GetDirectoryName(path) + | _ -> Path.GetTempPath() + if Directory.Exists(initialPath) then + procInfo.WorkingDirectory <- initialPath + procInfo, fsiSupportsServer let nonNull = function null -> false | (s:string) -> true /// Represents an active F# Interactive process to which Visual Studio is connected via stdin/stdout/stderr and a remoting channel -type FsiSession() = +type FsiSession(sourceFile: string) = let randomSalt = System.Random() let channelName = let pid = System.Diagnostics.Process.GetCurrentProcess().Id @@ -258,7 +273,7 @@ type FsiSession() = let salt = randomSalt.Next() sprintf "FSIChannel_%d_%d_%d" pid tick salt - let procInfo = fsiStartInfo channelName + let procInfo, fsiSupportsServer = fsiStartInfo channelName sourceFile let cmdProcess = new Process(StartInfo=procInfo) let fsiOutput = Event<_>() let fsiError = Event<_>() @@ -285,26 +300,16 @@ type FsiSession() = do cmdProcess.EnableRaisingEvents <- true - let client = - try FSharp.Compiler.Server.Shared.FSharpInteractiveServer.StartClient(channelName) - with e -> raise (SessionError (VFSIstrings.SR.exceptionRaisedWhenCreatingRemotingClient(e.ToString()))) + let clientConnection = + if fsiSupportsServer then + try Some (FSharp.Compiler.Server.Shared.FSharpInteractiveServer.StartClient(channelName)) + with e -> raise (SessionError (VFSIstrings.SR.exceptionRaisedWhenCreatingRemotingClient(e.ToString()))) + else + None /// interrupt timeout in miliseconds let interruptTimeoutMS = 1000 -#if FSI_SERVER_INTELLISENSE - - // timeout in miliseconds. - // This timeout is to catch any issue with remoting becoming unresponsive. - // On it's duration, it is better from user POV to wait a few seconds and see, - // than to abort an intelisense request that would return, - // since an abort request has no useful information at all. - // 2 seconds seems to slow. (which was surprising, maybe - // the tcEnv were still being computed). - let completionsTimeoutMS = 3000 - -#endif - let checkLeaseStatus myService = if false then let myLease = RemotingServices.GetLifetimeService(myService) :?> ILease @@ -321,10 +326,13 @@ type FsiSession() = // Create session object member x.Interrupt() = - checkLeaseStatus client - match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with - | Some () -> true - | None -> false + match clientConnection with + | None -> false + | Some client -> + checkLeaseStatus client + match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with + | Some () -> true + | None -> false member x.SendInput (str: string) = inputQueue.Post(str) @@ -336,6 +344,8 @@ type FsiSession() = member x.Alive = not cmdProcess.HasExited + member x.SupportsInterrupt = not cmdProcess.HasExited && clientConnection.IsSome // clientConnection not on .NET Core + member x.ProcessID = cmdProcess.Id member x.ProcessArgs = procInfo.Arguments @@ -349,20 +359,6 @@ type FsiSession() = with e -> fsiOutput.Trigger (VFSIstrings.SR.killingProcessRaisedException (e.ToString())) -#if FSI_SERVER_INTELLISENSE - member x.Completions(s:string) = - checkLeaseStatus client - match timeoutApp "VFSI completions" completionsTimeoutMS (fun () -> client.Completions(s)) () with - | Some names -> names - | None -> [| |] - - member x.GetDeclarations(s: string, plid: string[]) = - checkLeaseStatus client - match timeoutApp "VFSI intelisense" completionsTimeoutMS (fun () -> client.GetDeclarations(s,plid)) () with - | Some results -> results - | None -> [| |] -#endif - //------------------------------------------------------------------------- // sessions //------------------------------------------------------------------------- @@ -386,10 +382,10 @@ type FsiSessions() = // clearing sessionR before kill() means session.Exited is ignored below session.Kill()) - let restart() = + let restart(sourceFile) = kill() try - let session = FsiSession() + let session = FsiSession(sourceFile) sessionR <- Some session // All response callbacks are guarded by checks that "session" is still THE ACTIVE session. session.Output.Add(fun s -> if isCurrentSession session then fsiOut.Trigger s) @@ -398,6 +394,9 @@ type FsiSessions() = with SessionError text -> fsiError.Trigger text + let ensure(sourceFile) = + if sessionR.IsNone then restart(sourceFile) + member x.Interrupt() = sessionR |> Option.forall (fun session -> session.Interrupt()) @@ -411,6 +410,9 @@ type FsiSessions() = member x.Alive = sessionR |> Option.exists (fun session -> session.Alive) + member x.SupportsInterrupt = + sessionR |> Option.exists (fun session -> session.SupportsInterrupt) + member x.ProcessID = match sessionR with | None -> -1 (* -1 assumed to never be a valid process ID *) @@ -422,28 +424,9 @@ type FsiSessions() = | Some session -> session.ProcessArgs member x.Kill() = kill() - member x.Restart() = restart() - member x.Exited = fsiExited.Publish - -#if FSI_SERVER_INTELLISENSE - member x.Completions(s) = - match sessionR with - | None -> [| |] - | Some session -> session.Completions(s) + + member x.Ensure(sourceFile) = ensure(sourceFile) - member x.GetDeclarations(s,plid) = - match sessionR with - | None -> [| |] - | Some session -> session.GetDeclarations(s,plid) - - member x.GetDeclarationInfos (str:string) = - // RPC to the session to get the completions based on the latest state. - let plid = Microsoft.VisualStudio.FSharp.Interactive.QuickParse.GetPartialLongName(str,str.Length-1) // Subtract one to convert to zero-relative - let project = function (name,None) -> [name] | (name,Some residue) -> [name;residue] - let plid = plid |> List.collect project |> List.toArray - // diagnostics.Log(sprintf "RPC GetDeclarations with str =[[%s]]" str) - // diagnostics.Log(sprintf "RPC GetDeclarations with plid=[[%s]]" (String.concat "." plid)) - let declInfos = x.GetDeclarations(str,plid) - declInfos - -#endif + member x.Restart(sourceFile) = restart(sourceFile) + + member x.Exited = fsiExited.Publish diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf index 33f237c69bb..ef9d28d48ae 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf @@ -12,6 +12,11 @@ V případě nastavení na true a za předpokladu, že aktuální počítač je 64bitový, se F# Interactive spustí jako 64bitový proces. (V opačném případě je F# Interactive 32bitový proces.) + + Misc + Různé + + F# Interactive options Možnost F# Interactive @@ -22,9 +27,19 @@ Další argumenty příkazového řádku předané F# Interactive a spustitelné v sadě Visual Studio. (Pokud se povolí ladění skriptů, ignorují se příznaky optimalizace a ladění.) - - Misc - Různé + + FSI Preview + FSI Preview + + + + Enable preview language features + Povolit funkce jazyka ve verzi Preview + + + + Enable preview of in-development language features in F# Interactive + Povolit vyvíjené funkce jazyka ve verzi Preview v jazyce F# Interactive @@ -52,6 +67,16 @@ Ladění + + Use .NET Core Scripting + Použít skriptování .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Povolit úpravy a provádění skriptů .NET Core pro všechny skripty F # a okno F# Interactive + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf index 989b2031fee..0f547bc7453 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf @@ -12,6 +12,11 @@ Wenn diese Einstellung auf "True" gesetzt ist und der aktuelle Computer eine 64-Bit-Version ist, müssen Sie F# Interactive als einen 64-Bit-Prozess ausführen (Andernfalls ist F# Interactive ein 32-Bit-Prozess). + + Misc + Verschiedene + + F# Interactive options F# Interactive-Optionen @@ -22,9 +27,19 @@ Die an die ausführbare F# Interactive-Datei von Visual Studio übergebenen zusätzlichen Befehlszeilenargumente. (Optimierungs- und Debugflags werden bei aktiviertem Skriptdebuggen ignoriert.) - - Misc - Verschiedene + + FSI Preview + FSI-Vorschau + + + + Enable preview language features + Vorschausprachfeatures aktivieren + + + + Enable preview of in-development language features in F# Interactive + Vorschau der in Entwicklung befindlichen Sprachfeatures in F# Interactive aktivieren @@ -52,6 +67,16 @@ Debuggen + + Use .NET Core Scripting + .NET Core-Skripts verwenden + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + .NET Core-Skriptbearbeitung und -ausführung für alle F#-Skripts und das F# Interactive-Fenster aktivieren + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf index 725e86521e8..84099f2ddc8 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf @@ -12,6 +12,11 @@ Si se establece en True y la máquina actual es de 64 bits, F# interactivo se ejecuta como proceso de 64 bits; de lo contrario, se ejecuta como proceso de 32 bits. + + Misc + Varios + + F# Interactive options Opciones de F# interactivo @@ -22,9 +27,19 @@ Argumentos de la línea de comandos adicional pasados al archivo ejecutable de F# interactivo por Visual Studio. (se prescinde de las marcas de optimización y depuración si la depuración de scripts está habilitada) - - Misc - Varios + + FSI Preview + Versión preliminar de FSI + + + + Enable preview language features + Habilitar las características del lenguaje de versión preliminar + + + + Enable preview of in-development language features in F# Interactive + Habilita la versión preliminar de las características del lenguaje en desarrollo de F# interactivo. @@ -52,6 +67,16 @@ Depuración + + Use .NET Core Scripting + Usar scripting de .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Habilita la ejecución y la edición de scripts de .NET Core para todos los scripts de F # y la ventana de F# interactivo. + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf index 1c66865aeaa..922cb52f629 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf @@ -12,6 +12,11 @@ Si la valeur est true et que l'ordinateur actuel est de type 64 bits, exécutez F# Interactive en tant que processus 64 bits. (Sinon, F# Interactive est un processus 32 bits.) + + Misc + Divers + + F# Interactive options Options de F# Interactive @@ -22,9 +27,19 @@ Arguments supplémentaires de la ligne de commande passés à l'exécutable F# Interactive par Visual Studio. (les indicateurs d'optimisation et de débogage sont ignorés si le débogage de script est activé) - - Misc - Divers + + FSI Preview + Préversion FSI + + + + Enable preview language features + Activer la préversion des fonctionnalités de langage + + + + Enable preview of in-development language features in F# Interactive + Activer la préversion des fonctionnalités de langage en développement dans F# Interactive @@ -52,6 +67,16 @@ Débogage + + Use .NET Core Scripting + Utiliser les scripts .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Activer l'édition et l'exécution de scripts .NET Core pour tous les scripts F# et la fenêtre F# Interactive + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf index 3ab00cc2b5c..0870d4eecbb 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf @@ -12,6 +12,11 @@ Se impostato su true, e il computer corrente è a 64 bit, eseguire F# Interactive come processo a 64 bit. In caso contrario, F# Interactive è un processo a 32 bit. + + Misc + Varie + + F# Interactive options Opzioni di F# Interactive @@ -22,9 +27,19 @@ Argomenti aggiuntivi della riga di comando passati all'eseguibile F# Interactive da Visual Studio. Se è abilitato il debug di script, i flag di ottimizzazione e debug vengono ignorati. - - Misc - Varie + + FSI Preview + Anteprima FSI + + + + Enable preview language features + Abilita le funzionalità del linguaggio in anteprima + + + + Enable preview of in-development language features in F# Interactive + Abilita l'anteprima delle funzionalità del linguaggio in fase di sviluppo in F# Interactive @@ -52,6 +67,16 @@ Debug + + Use .NET Core Scripting + Usa script di .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Abilita la modifica e l'esecuzione di script .NET Core per tutti gli script F# e la finestra F# Interactive + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf index 1b938bc2d4e..0ff78720e9f 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf @@ -12,6 +12,11 @@ true に設定されていて、現在のコンピューターが 64 ビットである場合は、F# インタラクティブを 64 ビット プロセスで実行してください (そうしないと、F# インタラクティブは 32 ビット プロセスになります)。 + + Misc + その他 + + F# Interactive options F# インタラクティブ オプション @@ -22,9 +27,19 @@ 追加のコマンド ライン引数が Visual Studio によって F# インタラクティブ実行可能ファイルに渡されました。(スクリプト デバッグが有効な場合、最適化とデバッグのフラグは無視されます) - - Misc - その他 + + FSI Preview + FSI プレビュー + + + + Enable preview language features + プレビュー言語機能を有効にする + + + + Enable preview of in-development language features in F# Interactive + F# インタラクティブの開発中の言語機能についてプレビューを有効にします @@ -52,6 +67,16 @@ デバッグ中 + + Use .NET Core Scripting + .Net Core スクリプトの使用 + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + すべての F# スクリプトと F# インタラクティブ ウィンドウで、.NET Core スクリプトの編集と実行を有効にします + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf index b030fad5e50..aa8ebcfefb7 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf @@ -12,6 +12,11 @@ true로 설정하는 경우 현재 컴퓨터가 64비트이면 F# 대화형을 64비트 프로세스로 실행하고, 그렇지 않으면 F# 대화형이 32비트 프로세스로 실행됩니다. + + Misc + 기타 + + F# Interactive options F# 대화형 옵션 @@ -22,9 +27,19 @@ Visual Studio에서 F# 대화형 실행 파일로 전달되는 추가 명령줄 인수입니다. 스크립트 디버깅을 사용하도록 설정한 경우 최적화 및 디버그 플래그는 무시됩니다. - - Misc - 기타 + + FSI Preview + FSI 미리 보기 + + + + Enable preview language features + 미리 보기 언어 기능 사용 + + + + Enable preview of in-development language features in F# Interactive + F# Interactive에서 개발 중인 언어 기능의 미리 보기를 사용하도록 설정합니다. @@ -52,6 +67,16 @@ 디버깅 + + Use .NET Core Scripting + .NET Core 스크립팅 사용 + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + 모든 F# 스크립트 및 F# 대화형 창에 대해 .NET Core 스크립트 편집 및 실행을 사용하도록 설정합니다. + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf index 48e1694269a..8730043dc07 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf @@ -12,6 +12,11 @@ Jeśli ustawiono wartość true i obecnie jest używany komputer 64-bitowy, należy uruchomić narzędzie F# Interactive jako proces 64-bitowy. W przeciwnym razie narzędzie F# Interactive zostanie uruchomione jako proces 32-bitowy. + + Misc + Różne + + F# Interactive options Opcje narzędzia F# Interactive @@ -22,9 +27,19 @@ Argumenty wiersza polecenia przekazywane do pliku wykonywalnego narzędzia F# Interactive przez program Visual Studio. (Flagi optymalizacji i debugowania są ignorowane, jeśli włączone jest debugowanie skryptów). - - Misc - Różne + + FSI Preview + FSI (wersja zapoznawcza) + + + + Enable preview language features + Włącz funkcje języka w wersji zapoznawczej + + + + Enable preview of in-development language features in F# Interactive + Włącz wersje zapoznawcze funkcji języka w trakcie opracowywania w oknie F# Interactive @@ -52,6 +67,16 @@ Debugowanie + + Use .NET Core Scripting + Użyj wykonywania skryptów .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Włącz edycję i wykonywanie skryptów .NET Core dla wszystkich skryptów języka F# i okna narzędzia F# Interactive + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf index 6099d3d9fda..406a9f20545 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf @@ -12,6 +12,11 @@ Se estiver definido como true, e o computador atual for 64 bits, execute o F# Interativo como um processo de 64 bits. (Caso contrário, o F# Interactive será um processo de 32 bits.) + + Misc + Diversos + + F# Interactive options Opções do F# Interativo @@ -22,9 +27,19 @@ Argumentos da linha de comando adicionais passados para o executável do F# Interativo pelo Visual Studio (sinalizadores de depuração e otimização são ignorados se a depuração do script estiver habilitada) - - Misc - Diversos + + FSI Preview + Versão prévia do FSI + + + + Enable preview language features + Habilitar versões prévias dos recursos de linguagem + + + + Enable preview of in-development language features in F# Interactive + Habilitar as versões prévias de recursos de linguagem em desenvolvimento no F# Interativo @@ -52,6 +67,16 @@ Depurando + + Use .NET Core Scripting + Usar o script do .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Habilitar a edição e a execução de scripts do .NET Core para todos os scripts F# e a janela do F# Interativo + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf index a4acb579585..4d25a0ea143 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf @@ -12,6 +12,11 @@ Если задано значение true и текущий компьютер является 64-разрядным, F# Interactive запускается как 64-разрядный процесс. (В остальных случая F# Interactive является 32-разрядным процессом.) + + Misc + Прочее + + F# Interactive options Параметры F# Interactive @@ -22,9 +27,19 @@ Дополнительные аргументы командной строки, передаваемые исполняемому файлу F# Interactive из Visual Studio. Оптимизация и флаги отладки игнорируются, если включена отладка скриптов. - - Misc - Прочее + + FSI Preview + Предварительная версия FSI + + + + Enable preview language features + Включить предварительные версии функций языка + + + + Enable preview of in-development language features in F# Interactive + Включить предварительный просмотр функций языка, находящихся в разработке, в F# Interactive @@ -52,6 +67,16 @@ Отладка + + Use .NET Core Scripting + Использовать сценарии .NET Core + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Включить редактирование и выполнение скриптов в .NET Core для всех скриптов F# и окна F# Interactive + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf index 5fef942b6e2..232fdbe676d 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf @@ -12,6 +12,11 @@ True olarak ayarlanırsa ve geçerli makine 64 bit ise F# Etkileşimli'yi 64 bit işlem olarak çalıştırın. (Aksi takdirde F# Etkileşimli 32 bit işlemdir.) + + Misc + Çeşitli + + F# Interactive options F# Etkileşimli seçenekleri @@ -22,9 +27,19 @@ Visual Studio tarafından çalıştırılabilen F# Etkileşimli'ye geçirilmiş ek komut satırı bağımsız değişkenleri. (Betik hata ayıklaması etkinleştirilmişse en iyi duruma getirme ve hata ayıklama bayrakları yok sayılır.) - - Misc - Çeşitli + + FSI Preview + FSI Önizleme + + + + Enable preview language features + Önizlemedeki dil özelliklerini etkinleştir + + + + Enable preview of in-development language features in F# Interactive + F# Interactive'deki geliştirme aşamasında olan dil özelliklerinin önizlemesini etkinleştir @@ -52,6 +67,16 @@ Hata Ayıklama + + Use .NET Core Scripting + .NET Core Betiği Kullan + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Tüm F# betikleri ile F# Etkileşimli penceresi için .NET Core betik düzenlemeyi ve yürütmeyi etkinleştirin + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf index fa1db48b940..50328a7aabd 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf @@ -12,6 +12,11 @@ 如果设为 true,且当前计算机是 64 位的,则将 F# 交互窗口作为 64 位进程运行。(否则,F# 交互为 32 位进程。) + + Misc + 杂项 + + F# Interactive options F# 交互窗口选项 @@ -22,9 +27,19 @@ 其他命令行参数传递到 Visual Studio 执行的 F# 交互窗口可执行文件。(若已启动脚本调试,则忽略优化和调试标志) - - Misc - 杂项 + + FSI Preview + FSI 预览 + + + + Enable preview language features + 启用预览语言功能 + + + + Enable preview of in-development language features in F# Interactive + 在 F# 交互中启用开发中语言功能的预览 @@ -52,6 +67,16 @@ 正在调试 + + Use .NET Core Scripting + 使用 .NET Core 脚本 + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + 对所有 F# 脚本和 F# 交互窗口启用 .NET Core 脚本编辑和执行 + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf index dd4f7af3268..01303e69aa0 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf @@ -12,6 +12,11 @@ 如果設為 true,並且目前電腦為 64 位元,則 F# 互動會當做 64 位元處理序來執行 (反之,F# 互動則為 32 位元處理序)。 + + Misc + 其他 + + F# Interactive options F# 互動選項 @@ -22,9 +27,19 @@ 由 Visual Studio 額外傳遞給 F# 互動可執行檔的命令列引數。(若啟用指令碼偵錯,則會忽略最佳化及偵錯旗標) - - Misc - 其他 + + FSI Preview + FSI 預覽 + + + + Enable preview language features + 啟用預覽語言功能 + + + + Enable preview of in-development language features in F# Interactive + 在 F# Interactive 中啟用開發中語言功能的預覽 @@ -52,6 +67,16 @@ 偵錯 + + Use .NET Core Scripting + 使用 .NET Core 指令碼 + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + 為所有 F# 指令碼及 F# 互動視窗啟用 .NET Core 指令碼編輯與執行 + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf index b79b747fad9..1d790e879b1 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf @@ -22,9 +22,14 @@ Nepovedlo se načíst službu jazyka F#. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Vítá vás F# Interactive pro .NET Core v sadě Visual Studio. Kód spustíte těmito způsoby:\n 1. Ve skriptu F # použijte možnost Odeslat do interaktivního okna (Alt-Enter nebo kliknutí pravým tlačítkem).\n Proces F# Interactive použije případné nastavení global.js přidružené k tomuto skriptu.\n 2. Začněte tím, že stisknete Enter. Proces F# Interactive použije výchozí nastavení. + + - Session termination detected. Press Enter to restart. - Zjistilo se ukončení relace. Pokračovat můžete stisknutím klávesy Enter. + Session termination detected. + Zjistilo se ukončení relace. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf index e8dabd63d6b..7e2462013ed 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf @@ -22,9 +22,14 @@ Der F#-Sprachendienst konnte nicht geladen werden. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Willkommen bei F# Interactive für .NET Core in Visual Studio. Führen Sie einen der folgenden Schritte durch, um Code auszuführen:\n 1. Verwenden Sie in einem F#-Skript "An Interactive senden" (ALT-EINGABETASTE oder Klick mit der rechten Maustaste). Der F# Interactive-Prozess\n verwendet keine global.json-Einstellungen, die diesem Skript zugeordnet sind.\n 2. Drücken Sie zum Starten die EINGABETASTE. Der F# Interactive-Prozess verwendet Standardeinstellungen. + + - Session termination detected. Press Enter to restart. - Es wurde eine Beendigung der Sitzung erkannt. Drücken Sie die EINGABETASTE, um neu zu starten. + Session termination detected. + Es wurde eine Beendigung der Sitzung erkannt. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf index 8fafdfe73df..9a12087f57c 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf @@ -22,9 +22,14 @@ No se pudo cargar el servicio del lenguaje F#. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Esto es F# interactivo para .NET Core en Visual Studio. Para ejecutar el código, puede realizar una de las acciones siguientes:\n 1. Use "Enviar a interactivo" (Alt-Entrar o hacer clic con el botón derecho) desde un script de F #. El proceso de F# interactivo\n usará cualquier configuración de global.json asociada a ese script.\n 2. Presione "Entrar" para empezar. El proceso de F# interactivo usará la configuración predeterminada. + + - Session termination detected. Press Enter to restart. - Se detectó una terminación de sesión. Presione Entrar para reiniciar. + Session termination detected. + Se detectó una terminación de sesión. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf index 14025011c11..8ef997c62c7 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf @@ -22,9 +22,14 @@ Impossible de charger le service de langage F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Bienvenue dans F# Interactive pour .NET Core dans Visual Studio. Pour exécuter du code, vous disposez de plusieurs possibilités\n 1. Utilisez 'Envoyer vers Interactive' (Alt-Entrée ou clic droit) à partir d'un script F#. Le processus F# Interactive va\n utiliser les paramètres global.json associés au script.\n 2. Appuyez sur 'Entrée' pour démarrer. Le processus F# Interactive va utiliser les paramètres par défaut. + + - Session termination detected. Press Enter to restart. - Fin de session détectée. Appuyez sur Entrée pour redémarrer. + Session termination detected. + Arrêt de session détectée. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf index 5f2b1b679c9..f9fdb9f3c6a 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf @@ -22,9 +22,14 @@ Non è stato possibile caricare il servizio di linguaggio F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Benvenuti in F# Interactive per .NET Core in Visual Studio. Per eseguire il codice:\n 1. Usare 'Invia a Interactive' (ALT-INVIO o clic con il pulsante destro del mouse) da uno script F#. Il processo di F# Interactive\n userà le eventuali impostazioni di global.json associate allo script.\n 2. Premere 'INVIO' per iniziare. Il processo di F# Interactive userà le impostazioni predefinite. + + - Session termination detected. Press Enter to restart. - Rilevata terminazione di sessione. Premere INVIO per riavviare. + Session termination detected. + È stata rilevata la terminazione della sessione. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf index 34c5ae7317f..568834e7f23 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf @@ -22,9 +22,14 @@ F# 言語サービスを読み込めませんでした + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Visual Studio の .NET Core の F# インタラクティブへようこそ。コードを実行するには、\n 1. F# スクリプトから [Interactive に送信] (Alt+Enter または右クリック) を使用します。F# インタラクティブ プロセスでは、\n そのスクリプトに関連付けられている任意の global.json 設定が使用されます。\n 2. 開始するには、Enter キーを押します。F# インタラクティブ プロセスでは、既定の設定が使用されます。 + + - Session termination detected. Press Enter to restart. - セッションの終了が検出されました。再開する場合は Enter キーを押してください。 + Session termination detected. + セッションの終了が検出されました。 diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf index a4aa68732a3..ca0309e1962 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf @@ -22,9 +22,14 @@ F# 언어 서비스를 로드할 수 없습니다. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Visual Studio의 .NET Core용 F# 대화형을 시작합니다. 코드를 실행하려면 다음 중 한 가지를 수행합니다.\n 1. F# 스크립트에서 '대화형으로 보내기'(Alt-Enter 또는 마우스 오른쪽 단추 클릭)를 사용합니다. F# 대화형 프로세스에서\n 해당 스크립트와 연결된 모든 global.json 설정을 사용합니다.\n 2. 'Enter' 키를 눌러 시작합니다. F# 대화형 프로세스에서 기본 설정을 사용합니다. + + - Session termination detected. Press Enter to restart. - 세션 종료가 검색되었습니다. 다시 시작하려면 <Enter> 키를 누르세요. + Session termination detected. + 세션 종료가 감지되었습니다. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf index 34a64865416..00f73c99b22 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf @@ -22,9 +22,14 @@ Nie można załadować usługi języka F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + F# Interactive dla platformy .NET Core w programie Visual Studio — Zapraszamy! Aby wykonać kod, wykonaj jedną z następujących akcji:\n 1. Użyj polecenia „Wyślij do interaktywnego” (Alt+Enter lub kliknij prawym przyciskiem myszy) z poziomu skryptu języka F#. Proces narzędzia F# Interactive\n użyje dowolnych ustawień global.json skojarzonych z tym skryptem.\n 2. Naciśnij klawisz „Enter”, aby rozpocząć. Proces narzędzia F# Interactive użyje ustawień domyślnych. + + - Session termination detected. Press Enter to restart. - Wykryto zakończenie sesji. Naciśnij klawisz Enter, aby uruchomić ją ponownie. + Session termination detected. + Wykryto zakończenie sesji. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf index a3d2f3edb35..5fdb3152e34 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf @@ -22,9 +22,14 @@ Não foi possível carregar o serviço de linguagem F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Bem-vindo(a) ao F# Interativo para .NET Core no Visual Studio. Para executar o código, ou\n 1. Use 'Enviar para Interativo' (Alt-Enter ou clique com o botão direito do mouse) de um script F#. O processo de F# Interativo\n usará quaisquer configurações global.json associadas a esse script.\n 2. Pressione 'Enter' para começar. O processo de F# Interativo usará as configurações padrão. + + - Session termination detected. Press Enter to restart. - Encerramento da sessão detectado. Pressione a tecla Enter para reiniciar. + Session termination detected. + Encerramento da sessão detectado. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf index c0b711f3b86..2b699562cab 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf @@ -22,9 +22,14 @@ Не удалось загрузить службу языка F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Добро пожаловать в F# Interactive для .NET Core в Visual Studio. Для выполнения кода используйте любой из двух следующих вариантов: \n 1. Используйте команду "Отправить в Interactive" для сценария F# (чтобы получить доступ к этой команде, нажмите ALT+ВВОД или правую кнопку мыши). Процесс F# Interactive \n будет использовать все параметры global.json, связанные с этим сценарием.\n 2. Нажмите клавишу ВВОД для запуска сценария. Процесс F# Interactive будет использовать параметры по умолчанию. + + - Session termination detected. Press Enter to restart. - Обнаружено прекращение сеанса. Нажмите клавишу ВВОД для перезапуска. + Session termination detected. + Обнаружено прекращение сеанса. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf index 6d80fb6bee6..972fae6d8e4 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf @@ -22,9 +22,14 @@ F# dil hizmeti yüklenemedi + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Visual Studio'daki .NET Core için F# Etkileşimli'ye hoş geldiniz. Kodu yürütmek için şunlardan birini yapın:\n 1. Bir F# betiğinden 'Etkileşimliye Gönder' (Alt+Enter veya sağ tıklama) seçeneğini kullanın. F# Etkileşimli işlemi\n bu betikle ilişkili tüm global.json ayarlarını kullanır.\n 2. Başlatmak için 'Enter' tuşuna basın. F# Etkileşimli işlemi varsayılan ayarları kullanır. + + - Session termination detected. Press Enter to restart. - Oturum sonlandırma algılandı. Yeniden başlatmak için Enter'a basın. + Session termination detected. + Oturumun sonlandırıldığı algılandı. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf index f4789a477c4..c8f65fa5dce 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf @@ -22,9 +22,14 @@ 未能加载 F# 语言服务 + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + 欢迎使用 Visual Studio 中 .NET Core 的 F# 交互窗口。若要执行代码,请\n 1. 从 F# 脚本中使用“发送到交互”(Alt-Enter 或右键单击)。F# 交互进程将\n 使用与该脚本关联的任何 global.json 设置。\n 2. 按 "Enter" 开始。F# 交互进程将使用默认设置。 + + - Session termination detected. Press Enter to restart. - 检测到会话已终止。请按 Enter 重新启动会话。 + Session termination detected. + 检测到会话已终止。 diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf index ba06ff32813..5eac45e87cb 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf @@ -22,9 +22,14 @@ 無法載入 F# 語言服務 + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + 歡迎使用 Visual Studio 中 .NET Core 的 F# 互動。若要執行程式碼,請選用其中一種方式:\n 1. 從 F# 指令碼使用 [傳送到互動] (按 Alt-Enter 鍵或滑鼠右鍵)。F# 互動處理序將會\n 使用任何與該指令碼相關的 global.json 設定。\n 2. 按下 'Enter' 鍵即可開始。F# 互動處理序將使用預設設定。 + + - Session termination detected. Press Enter to restart. - 偵測到工作階段終止。請按 Enter 重新啟動。 + Session termination detected. + 偵測到工作階段終止。 diff --git a/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj b/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj index d2613d8c217..4fa4549e645 100644 --- a/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj +++ b/vsintegration/tests/GetTypesVS.UnitTests/GetTypesVS.UnitTests.fsproj @@ -12,21 +12,18 @@ false true true + nunit true - + - - - - - + diff --git a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj +++ b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj +++ b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj +++ b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj +++ b/vsintegration/tests/MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs index 7c36d8f37e1..21edc0f1c5e 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs @@ -4,7 +4,13 @@ namespace DummyProviderForLanguageServiceTesting open Microsoft.FSharp.Core.CompilerServices open ProviderImplementation.ProvidedTypes + +open System.IO open System.Linq.Expressions +open System.Reflection + +open FSharp.Quotations +open FSharp.Core.CompilerServices // Runtime methods, these are called instead of “erased” methods type RuntimeAPI = @@ -47,49 +53,46 @@ module internal TPModule = [| :? string as value; :? int as ignoredvalue; |] -> let typeParam = ProvidedTypeDefinition(thisAssembly,namespaceName, typeName, Some typeof) let propParam = ProvidedProperty("Param1", typeof, - IsStatic = true, + isStatic = true, // A complicated was to basically return the constant value... Maybe there's a better/simpler way? - GetterCode = fun _ -> <@@ RuntimeAPI.Identity(value) @@>) + getterCode = fun _ -> <@@ RuntimeAPI.Identity(value) @@>) typeParam.AddMember(propParam :>System.Reflection.MemberInfo) - typeParam + typeParam | _ -> failwithf "instantiateParametricType: unexpected params %A" args - + // N1.T typeT.DefineStaticParameters( [ ProvidedStaticParameter("Param1", typeof); ProvidedStaticParameter("ParamIgnored", typeof) ], instantiateParametricType ) typeT.AddXmlDoc("""N1.T typeParam1 of stringIgnored""") // A non-parametric type N1.T1 let typeT1 = ProvidedTypeDefinition(thisAssembly,namespaceName,"T1",Some typeof) - - + // Two static methods: N1.T1.M1(int) and N1.T1.M2(int,int) - let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof)],typeof, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX) - let methM2 = ProvidedMethod("M2",[ProvidedParameter("arg1",typeof);ProvidedParameter("arg2", typeof)],typeof, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX) + let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof)],typeof, isStatic=true, invokeCode=InvokeAPI.addIntX) + let methM2 = ProvidedMethod("M2",[ProvidedParameter("arg1",typeof);ProvidedParameter("arg2", typeof)],typeof, isStatic=true, invokeCode=InvokeAPI.addIntX) //one Instance method:N1.T1().IM1(int) - let methIM1 = ProvidedMethod("IM1",[ProvidedParameter("arg1", typeof)],typeof,IsStaticMethod=false,InvokeCode=InvokeAPI.instanceX) - - // A method involving units-of-measure - let measures = ProvidedMeasureBuilder.Default - let kgAnnotation = measures.SI "kilogram" // a measure - let hzAnnotation = measures.SI "hertz" // a measure-abbreviation - let kg_per_hz_squared = measures.Ratio(kgAnnotation, measures.Square hzAnnotation) - let float_kg = measures.AnnotateType(typeof,[kgAnnotation]) - let decimal_kg_per_hz_squared = measures.AnnotateType(typeof,[kg_per_hz_squared]) + let methIM1 = ProvidedMethod("IM1",[ProvidedParameter("arg1", typeof)], typeof, isStatic=false, invokeCode=InvokeAPI.instanceX) + + let kgAnnotation = ProvidedMeasureBuilder.SI "kilogram" // a measure + let hzAnnotation = ProvidedMeasureBuilder.SI "hertz" // a measure-abbreviation + let kg_per_hz_squared = ProvidedMeasureBuilder.Ratio(kgAnnotation, ProvidedMeasureBuilder.Square hzAnnotation) + let float_kg = ProvidedMeasureBuilder.AnnotateType(typeof,[kgAnnotation]) + let decimal_kg_per_hz_squared = ProvidedMeasureBuilder.AnnotateType(typeof,[kg_per_hz_squared]) let nullable_decimal_kg_per_hz_squared = typedefof>.MakeGenericType [| decimal_kg_per_hz_squared |] - let methM3 = ProvidedMethod("MethodWithTypesInvolvingUnitsOfMeasure",[ProvidedParameter("arg1", float_kg)],nullable_decimal_kg_per_hz_squared, IsStaticMethod=true, InvokeCode=(fun args -> <@@ RuntimeAPI.Convert(%%(args.[0])) @@> )) + let methM3 = ProvidedMethod("MethodWithTypesInvolvingUnitsOfMeasure",[ProvidedParameter("arg1", float_kg)],nullable_decimal_kg_per_hz_squared, isStatic=true, invokeCode=(fun args -> <@@ RuntimeAPI.Convert(%%(args.[0])) @@> )) // an instance method using a conditional expression - let methM4 = ProvidedMethod("MethodWithErasedCodeUsingConditional",[],typeof,IsStaticMethod=false,InvokeCode=(fun _ -> <@@ if true then 1 else 2 @@>)) + let methM4 = ProvidedMethod("MethodWithErasedCodeUsingConditional", [], typeof, isStatic=false, invokeCode=(fun _ -> <@@ if true then 1 else 2 @@>)) // an instance method using a call and a type-as expression - let methM5 = ProvidedMethod("MethodWithErasedCodeUsingTypeAs",[],typeof,IsStaticMethod=false,InvokeCode=(fun _ -> <@@ box 1 :?> int @@>)) + let methM5 = ProvidedMethod("MethodWithErasedCodeUsingTypeAs", [], typeof, isStatic=false, invokeCode=(fun _ -> <@@ box 1 :?> int @@>)) // Three ctors - let ctorA = ProvidedConstructor([],InvokeCode=InvokeAPI.ctor) - let ctorB = ProvidedConstructor([ProvidedParameter("arg1",typeof)]) - let ctorC = ProvidedConstructor([ProvidedParameter("arg1",typeof); ProvidedParameter("arg2",typeof)]) + let ctorA = ProvidedConstructor([], invokeCode=InvokeAPI.ctor) + let ctorB = ProvidedConstructor([ ProvidedParameter("arg1", typeof) ], invokeCode = fun args -> <@@ (%%(args.[0]):double) :> obj @@>) + let ctorC = ProvidedConstructor([ ProvidedParameter("arg1", typeof); ProvidedParameter("arg2",typeof) ], invokeCode = fun args -> <@@ (%%(args.[0]):int), (%%(args.[1]):char) :> obj @@>) typeT1.AddMember methM1 typeT1.AddMember methM2 @@ -135,8 +138,9 @@ module GlobalCounters = () [] -type HelloWorldProvider(config: TypeProviderConfig) = - inherit TypeProviderForNamespaces(TPModule.namespaceName,TPModule.types) +type HelloWorldProvider(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, TPModule.namespaceName,TPModule.types) + do GlobalCounters.IncrementCreations() let mutable disposed = false do GlobalCounters.AddConfig config @@ -156,7 +160,7 @@ module internal SlowIntelliSenseTPModule = let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly() let typeT = ProvidedTypeDefinition(thisAssembly,namespaceName,"T",Some typeof) - let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof)],typeof, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX) + let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof)],typeof, isStatic=true, invokeCode=InvokeAPI.addIntX) typeT.AddMember methM1 let rec populate(t:ProvidedTypeDefinition, millisDelay:int) = @@ -182,20 +186,20 @@ module internal SlowIntelliSenseTPModule = let types = [ typeT ] [] -type SlowIntellisenseProvider() = - inherit TypeProviderForNamespaces(SlowIntelliSenseTPModule.namespaceName,SlowIntelliSenseTPModule.types) +type SlowIntellisenseProvider(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, SlowIntelliSenseTPModule.namespaceName,SlowIntelliSenseTPModule.types) do ignore() // for breakpoint [] -type ShowOffCreationTimeProvider() as this= - inherit TypeProviderForNamespaces() - let namespaceName = "ShowOffCreationTime" +type ShowOffCreationTimeProvider(config: TypeProviderConfig) as this= + inherit TypeProviderForNamespaces(config) + let namespaceName = "ShowOffCreationTime" let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly() let typeT = ProvidedTypeDefinition(thisAssembly,namespaceName,"T",Some typeof) let timeString = "CreatedAt" + System.DateTime.Now.ToLongTimeString() - let methM1 = ProvidedMethod(timeString,[ProvidedParameter("arg1", typeof)],typeof, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX) + let methM1 = ProvidedMethod(timeString,[ProvidedParameter("arg1", typeof)],typeof, isStatic=true, invokeCode=InvokeAPI.addIntX) let types = [ typeT ] do @@ -222,8 +226,8 @@ module TypeProviderThatThrowsErrorsModule = [t] [] -type TypeProviderThatThrowsErrors() = - inherit TypeProviderForNamespaces(TypeProviderThatThrowsErrorsModule.rootNamespace, TypeProviderThatThrowsErrorsModule.types) +type TypeProviderThatThrowsErrors(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, TypeProviderThatThrowsErrorsModule.rootNamespace, TypeProviderThatThrowsErrorsModule.types) open System.ComponentModel type TPBaseTy() = @@ -237,9 +241,9 @@ type TPBaseTy() = member this.ShowThisProp = () [] -type HiddenMembersInBaseClassProvider() as this = - inherit TypeProviderForNamespaces() - let namespaceName = "HiddenMembersInBaseClass" +type HiddenMembersInBaseClassProvider(config: TypeProviderConfig) as this = + inherit TypeProviderForNamespaces(config) + let namespaceName = "HiddenMembersInBaseClass" let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly() let typeT = ProvidedTypeDefinition(thisAssembly, namespaceName, "HiddenBaseMembersTP", Some typeof) @@ -260,18 +264,18 @@ module TypeProviderForTestingTuplesErasureModule = | _ -> failwith "One argument expected" let erasedTup = ProvidedTypeDefinition(assembly, rootNamespace, "TupleType", Some(typeof)) - erasedTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", typeof)], InvokeCode = handle (fun tup -> tup))) - erasedTup.AddMember(ProvidedProperty("SecondComponent", typeof, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1)))) + erasedTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", typeof)], invokeCode = handle (fun tup -> tup))) + erasedTup.AddMember(ProvidedProperty("SecondComponent", typeof, getterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1)))) let objT = typedefof.MakeGenericType(typeof, erasedTup) let erasedCompoundTup = ProvidedTypeDefinition(assembly, rootNamespace, "CompoundTupleType", Some(objT)) - erasedCompoundTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", objT)], InvokeCode = handle (fun tup -> tup))) - erasedCompoundTup.AddMember(ProvidedProperty("First", typeof, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 0)))) - erasedCompoundTup.AddMember(ProvidedProperty("Second", erasedTup, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1)))) + erasedCompoundTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", objT)], invokeCode = handle (fun tup -> tup))) + erasedCompoundTup.AddMember(ProvidedProperty("First", typeof, getterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 0)))) + erasedCompoundTup.AddMember(ProvidedProperty("Second", erasedTup, getterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1)))) [] -type TypeProviderForTestingTuplesErasure() = - inherit TypeProviderForNamespaces(TypeProviderForTestingTuplesErasureModule.rootNamespace, [TypeProviderForTestingTuplesErasureModule.erasedTup; TypeProviderForTestingTuplesErasureModule.erasedCompoundTup]) +type TypeProviderForTestingTuplesErasure(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, TypeProviderForTestingTuplesErasureModule.rootNamespace, [TypeProviderForTestingTuplesErasureModule.erasedTup; TypeProviderForTestingTuplesErasureModule.erasedCompoundTup]) module TypeProviderThatEmitsBadMethodsModule = let assembly = System.Reflection.Assembly.GetExecutingAssembly() @@ -285,66 +289,61 @@ module TypeProviderThatEmitsBadMethodsModule = methodName = "GetFirstElement", parameters = [ProvidedParameter("array", typeof)], returnType = typeof, - IsStaticMethod = true, - InvokeCode = function [arr] -> Quotations.Expr.Call(arr, get, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected") + isStatic = true, + invokeCode = function [arr] -> Quotations.Expr.Call(arr, get, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected") ) arrayUser.AddMember( ProvidedMethod( methodName = "SetFirstElement", parameters = [ProvidedParameter("array", typeof); ProvidedParameter("val", typeof)], returnType = typeof, - IsStaticMethod = true, - InvokeCode = function [arr; v] -> Quotations.Expr.Call(arr, set, [Quotations.Expr.Value 0; v]) | _ -> failwith "Two argument expected") + isStatic = true, + invokeCode = function [arr; v] -> Quotations.Expr.Call(arr, set, [Quotations.Expr.Value 0; v]) | _ -> failwith "Two argument expected") ) arrayUser.AddMember( ProvidedMethod( methodName = "AddressOfFirstElement", parameters = [ProvidedParameter("array", typeof)], returnType = typeof.MakeByRefType(), - IsStaticMethod = true, - InvokeCode = function [arr] -> Quotations.Expr.Call(arr, addr, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected") + isStatic = true, + invokeCode = function [arr] -> Quotations.Expr.Call(arr, addr, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected") ) [] -type TypeProviderThatEmitsBadMethods() = - inherit TypeProviderForNamespaces(TypeProviderThatEmitsBadMethodsModule.rootNamespace, [TypeProviderThatEmitsBadMethodsModule.arrayUser]) - -module TypeProvidersVisibilityChecks = - let assembly = System.Reflection.Assembly.GetExecutingAssembly() +type TypeProviderThatEmitsBadMethods(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, TypeProviderThatEmitsBadMethodsModule.rootNamespace, [TypeProviderThatEmitsBadMethodsModule.arrayUser]) +module TypeProvidersVisibilityChecks = let Namespace = "GeneratedType" let setMethodVisibility (m : ProvidedMethod) visibility = m.SetMethodAttrs((m.Attributes &&& ~~~System.Reflection.MethodAttributes.MemberAccessMask) ||| visibility) let addMethod name value visibility (ty : ProvidedTypeDefinition) = - let m = ProvidedMethod(name, [], value.GetType()) - m.IsStaticMethod <- false - m.InvokeCode <- fun _ -> Quotations.Expr.Value(value, value.GetType()) + let m = ProvidedMethod(name, [], value.GetType(), isStatic=false, invokeCode = (fun args -> Expr.Value(null, value.GetType()))) setMethodVisibility m visibility ty.AddMember m - let addGetProperty name value visibility (ty : ProvidedTypeDefinition) = - let prop = ProvidedProperty(name, value.GetType()) - prop.IsStatic <- false - prop.GetterCode <- fun _ -> Quotations.Expr.Value(value, value.GetType()) + let addGetProperty name value visibility (ty : ProvidedTypeDefinition) = + let prop = ProvidedProperty(name, value.GetType(), getterCode = fun _ -> <@@ value @@>) ty.AddMember prop let m = prop.GetGetMethod() :?> ProvidedMethod setMethodVisibility m visibility - let addLiteralField name value (ty : ProvidedTypeDefinition) = - let f = ProvidedLiteralField(name, value.GetType(), value) + let addLiteralField name value (ty : ProvidedTypeDefinition) = + let f = ProvidedField(name, value.GetType(), value) + f.SetFieldAttributes(FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public) ty.AddMember f + let assem = ProvidedAssembly() let providedTy = - let ty = ProvidedTypeDefinition(assembly, Namespace, "SampleType", Some typeof, IsErased=false) + let ty = ProvidedTypeDefinition(assem, Namespace, "SampleType", Some typeof, isErased=false) /// unseal type ty.SetAttributes(ty.Attributes &&& ~~~System.Reflection.TypeAttributes.Sealed) // add public literal field addLiteralField "PublicField" 100 ty - + // implicitly adds field - let ctor = ProvidedConstructor([ProvidedParameter("f", typeof)]) - ctor.InvokeCode <- fun _ -> <@@ () @@> + let ctor = ProvidedConstructor([ProvidedParameter("f", typeof)], invokeCode = fun args -> <@@ () @@>) ty.AddMember ctor // add properties @@ -356,22 +355,21 @@ module TypeProvidersVisibilityChecks = addMethod "PublicM" 510 (System.Reflection.MethodAttributes.Public) ty addMethod "ProtectedM" 5210 (System.Reflection.MethodAttributes.Family) ty addMethod "PrivateM" 5310 (System.Reflection.MethodAttributes.Private) ty - - let assem = ProvidedAssembly(System.IO.Path.GetTempFileName() + ".dll") assem.AddTypes [ty] ty + [] - type TypeProvider() = - inherit TypeProviderForNamespaces(Namespace, [providedTy]) + type TypeProvider(config: TypeProviderConfig) = + inherit TypeProviderForNamespaces(config, Namespace, [providedTy]) module RegexTypeProvider = open System.Text.RegularExpressions [] - type public CheckedRegexProvider() as this = - inherit TypeProviderForNamespaces() + type public CheckedRegexProvider(config: TypeProviderConfig) as this = + inherit TypeProviderForNamespaces(config) // Get the assembly and namespace used to house the provided types let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly() @@ -409,8 +407,8 @@ module RegexTypeProvider = methodName = "IsMatch", parameters = [ProvidedParameter("input", typeof)], returnType = typeof, - IsStaticMethod = true, - InvokeCode = fun args -> <@@ Regex.IsMatch(%%args.[0], pattern) @@>) + isStatic = true, + invokeCode = fun args -> <@@ Regex.IsMatch(%%args.[0], pattern) @@>) isMatch.AddXmlDoc "Indicates whether the regular expression finds a match in the specified input string" @@ -421,11 +419,11 @@ module RegexTypeProvider = let matchTy = ProvidedTypeDefinition( "MatchType", baseType = Some baseTy, - HideObjectMethods = true) + hideObjectMethods = true) // Nest the match type within parameterized Regex type ty.AddMember matchTy - + // Add group properties to match type for group in r.GetGroupNames() do // ignore the group named 0, which represents all input @@ -433,7 +431,7 @@ module RegexTypeProvider = let prop = ProvidedProperty( propertyName = group, propertyType = typeof, - GetterCode = fun args -> <@@ ((%%args.[0]:obj) :?> Match).Groups.[group] @@>) + getterCode = fun args -> <@@ ((%%args.[0]:obj) :?> Match).Groups.[group] @@>) prop.AddXmlDoc(sprintf @"Gets the ""%s"" group from this match" group) matchTy.AddMember(prop) @@ -442,7 +440,7 @@ module RegexTypeProvider = methodName = "Match", parameters = [ProvidedParameter("input", typeof)], returnType = matchTy, - InvokeCode = fun args -> <@@ ((%%args.[0]:obj) :?> Regex).Match(%%args.[1]) :> obj @@>) + invokeCode = fun args -> <@@ ((%%args.[0]:obj) :?> Regex).Match(%%args.[1]) :> obj @@>) matchMeth.AddXmlDoc "Searches the specified input string for the first occurence of this regular expression" ty.AddMember matchMeth @@ -450,7 +448,7 @@ module RegexTypeProvider = // Declare a constructor let ctor = ProvidedConstructor( parameters = [], - InvokeCode = fun args -> <@@ Regex(pattern) :> obj @@>) + invokeCode = fun args -> <@@ Regex(pattern) :> obj @@>) // Add documentation to the constructor ctor.AddXmlDoc "Initializes a regular expression instance" @@ -467,8 +465,8 @@ module RegexTypeProviderUsingMethod = open System.Text.RegularExpressions [] - type public CheckedRegexProvider() as this = - inherit TypeProviderForNamespaces() + type public CheckedRegexProvider(config: TypeProviderConfig) as this = + inherit TypeProviderForNamespaces(config) // Get the assembly and namespace used to house the provided types let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly() @@ -477,8 +475,7 @@ module RegexTypeProviderUsingMethod = let staticParams = [ProvidedStaticParameter("pattern1", typeof)] let regexTyStatic = ProvidedTypeDefinition(thisAssembly, rootNamespace, "RegexTypedStatic", Some baseTy) - - let meth = ProvidedMethod("IsMatch",[],typeof,IsStaticMethod=true) + let meth = ProvidedMethod("IsMatch", [], typeof, isStatic=true, invokeCode = fun _ -> <@@ true @@>) do meth.DefineStaticParameters( parameters=staticParams, instantiationFunction=(fun methName parameterValues -> @@ -489,8 +486,8 @@ module RegexTypeProviderUsingMethod = methodName = methName, parameters = [ProvidedParameter("input", typeof)], returnType = typeof, - IsStaticMethod = true, - InvokeCode = fun args -> <@@ true @@>) + isStatic = true, + invokeCode = fun args -> <@@ true @@>) isMatch.AddXmlDoc "Indicates whether the regular expression finds a match in the specified input string" regexTyStatic.AddMember isMatch diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj index 0fb60c539a1..84b50e8a6a7 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj @@ -3,8 +3,9 @@ - net45 + net472 true + $(OtherFlags) --nowarn:3390 --nowarn:3218 diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs index f01c8bdac18..70203708ee9 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs @@ -1,2928 +1,14438 @@ -// Copyright (c) Microsoft Corporation 2005-2012. -// This sample code is provided "as is" without warranty of any kind. -// We disclaim all warranties, either express or implied, including the -// warranties of merchantability and fitness for a particular purpose. +// Copyright (c) Microsoft Corporation, Tomas Petricek, Gustavo Guerra, and other contributors +// +// Licensed under the MIT License see LICENSE.md in this project -// This file contains a set of helper types and methods for providing types in an implementation -// of ITypeProvider. +namespace ProviderImplementation.ProvidedTypes -// This code has been modified and is appropriate for use in conjunction with the F# 3.0-4.0 releases + #nowarn "1182" + + // This file contains a set of helper types and methods for providing types in an implementation + // of ITypeProvider. + // + // This code has been modified and is appropriate for use in conjunction with the F# 4.x releases + + open System + open System.Reflection + open System.Collections.Generic + open System.Diagnostics + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Core.CompilerServices + + [] + module Utils = + let K x = (fun () -> x) + let isNull x = match x with null -> true | _ -> false + let isNil x = match x with [] -> true | _ -> false + let isEmpty x = match x with [| |] -> true | _ -> false + + module Option = + let toObj x = match x with None -> null | Some x -> x + let ofObj x = match x with null -> None | _ -> Some x + + [] + type StructOption<'T> (hasValue: bool, value: 'T) = + member _.IsNone = not hasValue + member _.HasValue = hasValue + member _.Value = value + override _.ToString() = if hasValue then match box value with null -> "null" | x -> x.ToString() else "" + + type uoption<'T> = StructOption<'T> + + let UNone<'T> = uoption<'T>(false, Unchecked.defaultof<'T>) + let USome v = uoption<'T>(true, v) + let (|UNone|USome|) (x:uoption<'T>) = if x.HasValue then USome x.Value else UNone + + module StructOption = + let toObj x = match x with UNone -> null | USome x -> x + let ofObj x = match x with null -> UNone | x -> USome x + + + let tryFindMulti k map = match Map.tryFind k map with Some res -> res | None -> [| |] + + let splitNameAt (nm:string) idx = + if idx < 0 then failwith "splitNameAt: idx < 0"; + let last = nm.Length - 1 + if idx > last then failwith "splitNameAt: idx > last"; + (nm.Substring(0,idx)), + (if idx < last then nm.Substring (idx+1,last - idx) else "") + + let splitILTypeName (nm:string) = + match nm.LastIndexOf '.' with + | -1 -> UNone, nm + | idx -> let a,b = splitNameAt nm idx in USome a, b + + let joinILTypeName (nspace: string uoption) (nm:string) = + match nspace with + | UNone -> nm + | USome ns -> ns + "." + nm + + let lengthsEqAndForall2 (arr1: 'T1[]) (arr2: 'T2[]) f = + (arr1.Length = arr2.Length) && + (arr1,arr2) ||> Array.forall2 f + + /// General implementation of .Equals(Type) logic for System.Type over symbol types. You can use this with other types too. + let rec eqTypes (ty1: Type) (ty2: Type) = + if Object.ReferenceEquals(ty1,ty2) then true + elif ty1.IsGenericTypeDefinition then ty2.IsGenericTypeDefinition && ty1.Equals(ty2) + elif ty1.IsGenericType then ty2.IsGenericType && not ty2.IsGenericTypeDefinition && eqTypes (ty1.GetGenericTypeDefinition()) (ty2.GetGenericTypeDefinition()) && lengthsEqAndForall2 (ty1.GetGenericArguments()) (ty2.GetGenericArguments()) eqTypes + elif ty1.IsArray then ty2.IsArray && ty1.GetArrayRank() = ty2.GetArrayRank() && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + elif ty1.IsPointer then ty2.IsPointer && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + elif ty1.IsByRef then ty2.IsByRef && eqTypes (ty1.GetElementType()) (ty2.GetElementType()) + else ty1.Equals(box ty2) + + /// General implementation of .Equals(obj) logic for System.Type over symbol types. You can use this with other types too. + let eqTypeObj (this: Type) (other: obj) = + match other with + | :? Type as otherTy -> eqTypes this otherTy + | _ -> false -namespace ProviderImplementation.ProvidedTypes + /// General implementation of .IsAssignableFrom logic for System.Type, regardless of specific implementation + let isAssignableFrom (ty: Type) (otherTy: Type) = + eqTypes ty otherTy || (match otherTy.BaseType with null -> false | bt -> ty.IsAssignableFrom(bt)) + + /// General implementation of .IsSubclassOf logic for System.Type, regardless of specific implementation, with + /// an added hack to make the types usable with the FSharp.Core quotations implementation + let isSubclassOf (this: Type) (otherTy: Type) = + (this.IsClass && otherTy.IsClass && this.IsAssignableFrom(otherTy) && not (eqTypes this otherTy)) + // The FSharp.Core implementation of FSharp.Quotations uses + // let isDelegateType (typ:Type) = + // if typ.IsSubclassOf(typeof) then ... + // This means even target type definitions must process the case where ``otherTy`` is typeof rather than + // the System.Delegate type for the target assemblies. + || (match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.MulticastDelegate" && (let fn = otherTy.FullName in fn = "System.Delegate" || fn = "System.MulticastDelegate" )) + + + /// General implementation of .GetAttributeFlags logic for System.Type over symbol types + let getAttributeFlagsImpl (ty: Type) = + if ty.IsGenericType then ty.GetGenericTypeDefinition().Attributes + elif ty.IsArray then typeof.Attributes + elif ty.IsPointer then typeof.MakePointerType().Attributes + elif ty.IsByRef then typeof.MakeByRefType().Attributes + else Unchecked.defaultof + + let bindAll = BindingFlags.DeclaredOnly ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Static ||| BindingFlags.Instance + let bindSome isStatic = BindingFlags.DeclaredOnly ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| (if isStatic then BindingFlags.Static else BindingFlags.Instance) + + let memberBinds isType (bindingFlags: BindingFlags) isStatic isPublic = + (isType || bindingFlags.HasFlag(if isStatic then BindingFlags.Static else BindingFlags.Instance)) && + ((bindingFlags.HasFlag(BindingFlags.Public) && isPublic) || (bindingFlags.HasFlag(BindingFlags.NonPublic) && not isPublic)) + + let rec instType inst (ty:Type) = + if isNull ty then null + elif ty.IsGenericType then + let typeArgs = Array.map (instType inst) (ty.GetGenericArguments()) + ty.GetGenericTypeDefinition().MakeGenericType(typeArgs) + elif ty.HasElementType then + let ety = instType inst (ty.GetElementType()) + if ty.IsArray then + let rank = ty.GetArrayRank() + if rank = 1 then ety.MakeArrayType() + else ety.MakeArrayType(rank) + elif ty.IsPointer then ety.MakePointerType() + elif ty.IsByRef then ety.MakeByRefType() + else ty + elif ty.IsGenericParameter then + let pos = ty.GenericParameterPosition + let (inst1: Type[], inst2: Type[]) = inst + if pos < inst1.Length then inst1.[pos] + elif pos < inst1.Length + inst2.Length then inst2.[pos - inst1.Length] + else ty + else ty -open System -open System.Text -open System.IO -open System.Reflection -open System.Reflection.Emit -open System.Linq.Expressions -open System.Collections.Generic -open Microsoft.FSharp.Quotations -open Microsoft.FSharp.Quotations.Patterns -open Microsoft.FSharp.Quotations.DerivedPatterns -open Microsoft.FSharp.Core.CompilerServices - -//-------------------------------------------------------------------------------- -// UncheckedQuotations - -// The FSharp.Core 2.0 - 4.0 (4.0.0.0 - 4.4.0.0) quotations implementation is overly strict in that it doesn't allow -// generation of quotations for cross-targeted FSharp.Core. Below we define a series of Unchecked methods -// implemented via reflection hacks to allow creation of various nodes when using a cross-targets FSharp.Core and -// mscorlib.dll. -// -// - Most importantly, these cross-targeted quotations can be provided to the F# compiler by a type provider. -// They are generally produced via the AssemblyReplacer.fs component through a process of rewriting design-time quotations that -// are not cross-targeted. -// -// - However, these quotation values are a bit fragile. Using existing FSharp.Core.Quotations.Patterns -// active patterns on these quotation nodes will generally work correctly. But using ExprShape.RebuildShapeCombination -// on these new nodes will not succed, nor will operations that build new quotations such as Expr.Call. -// Instead, use the replacement provided in this module. + + let mutable token = 0 + let genToken() = token <- token + 1; token + /// Internal code of .NET expects the obj[] returned by GetCustomAttributes to be an Attribute[] even in the case of empty arrays + let emptyAttributes = (([| |]: Attribute[]) |> box |> unbox) + + let nonNull str x = if isNull x then failwithf "Null in '%s', stacktrace = '%s'" str Environment.StackTrace else x + let nonNone str x = match x with None -> failwithf "No value has been specified for '%s', stacktrace = '%s'" str Environment.StackTrace | Some v -> v + let patchOption v f = match v with None -> f() | Some _ -> failwithf "Already patched, stacktrace = '%s'" Environment.StackTrace + + let notRequired this opname item = + let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter of type '%O'. Stack trace:\n%s" opname item (this.GetType()) Environment.StackTrace + Debug.Assert (false, msg) + raise (NotSupportedException msg) + + + let adjustTypeAttributes isNested attrs = + let visibilityAttributes = + match attrs &&& TypeAttributes.VisibilityMask with + | TypeAttributes.Public when isNested -> TypeAttributes.NestedPublic + | TypeAttributes.NotPublic when isNested -> TypeAttributes.NestedAssembly + | TypeAttributes.NestedPublic when not isNested -> TypeAttributes.Public + | TypeAttributes.NestedAssembly + | TypeAttributes.NestedPrivate + | TypeAttributes.NestedFamORAssem + | TypeAttributes.NestedFamily + | TypeAttributes.NestedFamANDAssem when not isNested -> TypeAttributes.NotPublic + | a -> a + (attrs &&& ~~~TypeAttributes.VisibilityMask) ||| visibilityAttributes + + + type ConstructorInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetConstructors(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic constructor definition via metadata token, stacktrace = '%s'" m.DeclaringType m.Name Environment.StackTrace + else + m + + type PropertyInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetProperties(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic property definition via metadata token" m.DeclaringType m.Name + else + m + + member p.IsStatic = p.CanRead && p.GetGetMethod().IsStatic || p.CanWrite && p.GetSetMethod().IsStatic + member p.IsPublic = p.CanRead && p.GetGetMethod().IsPublic || p.CanWrite && p.GetSetMethod().IsPublic + + type EventInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetEvents(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic event definition via metadata token" m.DeclaringType m.Name + else + m + + member p.IsStatic = p.GetAddMethod().IsStatic || p.GetRemoveMethod().IsStatic + member p.IsPublic = p.GetAddMethod().IsPublic || p.GetRemoveMethod().IsPublic + + type FieldInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + // Search through the original type definition looking for the one with a matching metadata token + let gdty = dty.GetGenericTypeDefinition() + gdty.GetFields(bindAll) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind %O::%s back to generic event definition via metadata token" m.DeclaringType m.Name + else + m + + type MethodInfo with + member m.GetDefinition() = + let dty = m.DeclaringType + if (m.IsGenericMethod && not dty.IsGenericType) then m.GetGenericMethodDefinition() + elif (m.IsGenericMethod && (not m.IsGenericMethodDefinition || not dty.IsGenericTypeDefinition)) || + (dty.IsGenericType && not dty.IsGenericTypeDefinition) then + + // Search through ALL the methods on the original type definition looking for the one + // with a matching metadata token + let gdty = if dty.IsGenericType then dty.GetGenericTypeDefinition() else dty + gdty.GetMethods(bindSome m.IsStatic) + |> Array.tryFind (fun c -> c.MetadataToken = m.MetadataToken) + |> function Some m2 -> m2 | None -> failwithf "couldn't rebind generic instantiation of %O::%s back to generic method definition via metadata token" m.DeclaringType m.Name + + else + m + + let canBindConstructor (bindingFlags: BindingFlags) (c: ConstructorInfo) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsPublic + + let canBindMethod (bindingFlags: BindingFlags) (c: MethodInfo) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsPublic + + let canBindProperty (bindingFlags: BindingFlags) (c: PropertyInfo) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsPublic + + let canBindField (bindingFlags: BindingFlags) (c: FieldInfo) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsPublic + + let canBindEvent (bindingFlags: BindingFlags) (c: EventInfo) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsPublic + + let canBindNestedType (bindingFlags: BindingFlags) (c: Type) = + bindingFlags.HasFlag(BindingFlags.Public) && c.IsNestedPublic || bindingFlags.HasFlag(BindingFlags.NonPublic) && not c.IsNestedPublic + + //-------------------------------------------------------------------------------- + // UncheckedQuotations + + // The FSharp.Core 2.0 - 4.0 (4.0.0.0 - 4.4.0.0) quotations implementation is overly strict in that it doesn't allow + // generation of quotations for cross-targeted FSharp.Core. Below we define a series of Unchecked methods + // implemented via reflection hacks to allow creation of various nodes when using a cross-targets FSharp.Core and + // mscorlib.dll. + // + // - Most importantly, these cross-targeted quotations can be provided to the F# compiler by a type provider. + // They are generally produced via the AssemblyReplacer.fs component through a process of rewriting design-time quotations that + // are not cross-targeted. + // + // - However, these quotation values are a bit fragile. Using existing FSharp.Core.Quotations.Patterns + // active patterns on these quotation nodes will generally work correctly. But using ExprShape.RebuildShapeCombination + // on these new nodes will not succed, nor will operations that build new quotations such as Expr.Call. + // Instead, use the replacement provided in this module. + // + // - Likewise, some operations in these quotation values like "expr.Type" may be a bit fragile, possibly returning non cross-targeted types in + // the result. However those operations are not used by the F# compiler. + [] + module UncheckedQuotations = + + let qTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.ExprConstInfo") + assert (not (isNull qTy)) + let pTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.PatternsModule") + assert (not (isNull pTy)) + + // These are handles to the internal functions that create quotation nodes of different sizes. Although internal, + // these function names have been stable since F# 2.0. + let mkFE0 = pTy.GetMethod("mkFE0", bindAll) + assert (not (isNull mkFE0)) + let mkFE1 = pTy.GetMethod("mkFE1", bindAll) + assert (not (isNull mkFE1)) + let mkFE2 = pTy.GetMethod("mkFE2", bindAll) + assert (mkFE2 |> isNull |> not) + let mkFE3 = pTy.GetMethod("mkFE3", bindAll) + assert (mkFE3 |> isNull |> not) + let mkFEN = pTy.GetMethod("mkFEN", bindAll) + assert (mkFEN |> isNull |> not) + + // These are handles to the internal tags attached to quotation nodes of different sizes. Although internal, + // these function names have been stable since F# 2.0. + let newDelegateOp = qTy.GetMethod("NewNewDelegateOp", bindAll) + assert (newDelegateOp |> isNull |> not) + let instanceCallOp = qTy.GetMethod("NewInstanceMethodCallOp", bindAll) + assert (instanceCallOp |> isNull |> not) + let staticCallOp = qTy.GetMethod("NewStaticMethodCallOp", bindAll) + assert (staticCallOp |> isNull |> not) + let newObjectOp = qTy.GetMethod("NewNewObjectOp", bindAll) + assert (newObjectOp |> isNull |> not) + let newArrayOp = qTy.GetMethod("NewNewArrayOp", bindAll) + assert (newArrayOp |> isNull |> not) + let appOp = qTy.GetMethod("get_AppOp", bindAll) + assert (appOp |> isNull |> not) + let instancePropGetOp = qTy.GetMethod("NewInstancePropGetOp", bindAll) + assert (instancePropGetOp |> isNull |> not) + let staticPropGetOp = qTy.GetMethod("NewStaticPropGetOp", bindAll) + assert (staticPropGetOp |> isNull |> not) + let instancePropSetOp = qTy.GetMethod("NewInstancePropSetOp", bindAll) + assert (instancePropSetOp |> isNull |> not) + let staticPropSetOp = qTy.GetMethod("NewStaticPropSetOp", bindAll) + assert (staticPropSetOp |> isNull |> not) + let instanceFieldGetOp = qTy.GetMethod("NewInstanceFieldGetOp", bindAll) + assert (instanceFieldGetOp |> isNull |> not) + let staticFieldGetOp = qTy.GetMethod("NewStaticFieldGetOp", bindAll) + assert (staticFieldGetOp |> isNull |> not) + let instanceFieldSetOp = qTy.GetMethod("NewInstanceFieldSetOp", bindAll) + assert (instanceFieldSetOp |> isNull |> not) + let staticFieldSetOp = qTy.GetMethod("NewStaticFieldSetOp", bindAll) + assert (staticFieldSetOp |> isNull |> not) + let tupleGetOp = qTy.GetMethod("NewTupleGetOp", bindAll) + assert (tupleGetOp |> isNull |> not) + let letOp = qTy.GetMethod("get_LetOp", bindAll) + assert (letOp |> isNull |> not) + let forIntegerRangeLoopOp = qTy.GetMethod("get_ForIntegerRangeLoopOp", bindAll) + assert (forIntegerRangeLoopOp |> isNull |> not) + let whileLoopOp = qTy.GetMethod("get_WhileLoopOp", bindAll) + assert (whileLoopOp |> isNull |> not) + let ifThenElseOp = qTy.GetMethod("get_IfThenElseOp", bindAll) + assert (ifThenElseOp |> isNull |> not) + + type Microsoft.FSharp.Quotations.Expr with + + static member NewDelegateUnchecked (ty: Type, vs: Var list, body: Expr) = + let e = List.foldBack (fun v acc -> Expr.Lambda(v,acc)) vs body + let op = newDelegateOp.Invoke(null, [| box ty |]) + mkFE1.Invoke(null, [| box op; box e |]) :?> Expr + + static member NewObjectUnchecked (cinfo: ConstructorInfo, args: Expr list) = + let op = newObjectOp.Invoke(null, [| box cinfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member NewArrayUnchecked (elementType: Type, elements: Expr list) = + let op = newArrayOp.Invoke(null, [| box elementType |]) + mkFEN.Invoke(null, [| box op; box elements |]) :?> Expr + + static member CallUnchecked (minfo: MethodInfo, args: Expr list) = + let op = staticCallOp.Invoke(null, [| box minfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member CallUnchecked (obj: Expr, minfo: MethodInfo, args: Expr list) = + let op = instanceCallOp.Invoke(null, [| box minfo |]) + mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + + static member ApplicationUnchecked (f: Expr, x: Expr) = + let op = appOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box f; box x |]) :?> Expr + + static member PropertyGetUnchecked (pinfo: PropertyInfo, args: Expr list) = + let op = staticPropGetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + + static member PropertyGetUnchecked (obj: Expr, pinfo: PropertyInfo, ?args: Expr list) = + let args = defaultArg args [] + let op = instancePropGetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + + static member PropertySetUnchecked (pinfo: PropertyInfo, value: Expr, ?args: Expr list) = + let args = defaultArg args [] + let op = staticPropSetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (args@[value]) |]) :?> Expr + + static member PropertySetUnchecked (obj: Expr, pinfo: PropertyInfo, value: Expr, args: Expr list) = + let op = instancePropSetOp.Invoke(null, [| box pinfo |]) + mkFEN.Invoke(null, [| box op; box (obj::(args@[value])) |]) :?> Expr + + static member FieldGetUnchecked (pinfo: FieldInfo) = + let op = staticFieldGetOp.Invoke(null, [| box pinfo |]) + mkFE0.Invoke(null, [| box op; |]) :?> Expr + + static member FieldGetUnchecked (obj: Expr, pinfo: FieldInfo) = + let op = instanceFieldGetOp.Invoke(null, [| box pinfo |]) + mkFE1.Invoke(null, [| box op; box obj |]) :?> Expr + + static member FieldSetUnchecked (pinfo: FieldInfo, value: Expr) = + let op = staticFieldSetOp.Invoke(null, [| box pinfo |]) + mkFE1.Invoke(null, [| box op; box value |]) :?> Expr + + static member FieldSetUnchecked (obj: Expr, pinfo: FieldInfo, value: Expr) = + let op = instanceFieldSetOp.Invoke(null, [| box pinfo |]) + mkFE2.Invoke(null, [| box op; box obj; box value |]) :?> Expr + + static member TupleGetUnchecked (e: Expr, n:int) = + let op = tupleGetOp.Invoke(null, [| box e.Type; box n |]) + mkFE1.Invoke(null, [| box op; box e |]) :?> Expr + + static member LetUnchecked (v:Var, e: Expr, body:Expr) = + let lam = Expr.Lambda(v,body) + let op = letOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box e; box lam |]) :?> Expr + + static member ForIntegerRangeLoopUnchecked (loopVariable, startExpr:Expr, endExpr:Expr, body:Expr) = + let lam = Expr.Lambda(loopVariable, body) + let op = forIntegerRangeLoopOp.Invoke(null, [| |]) + mkFE3.Invoke(null, [| box op; box startExpr; box endExpr; box lam |] ) :?> Expr + + static member WhileLoopUnchecked (guard:Expr, body:Expr) = + let op = whileLoopOp.Invoke(null, [| |]) + mkFE2.Invoke(null, [| box op; box guard; box body |] ):?> Expr + + static member IfThenElseUnchecked (e:Expr, t:Expr, f:Expr) = + let op = ifThenElseOp.Invoke(null, [| |]) + mkFE3.Invoke(null, [| box op; box e; box t; box f |] ):?> Expr + + type Shape = Shape of (Expr list -> Expr) + + let (|ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked|) e = + match e with + | NewObject (cinfo, args) -> + ShapeCombinationUnchecked (Shape (function args -> Expr.NewObjectUnchecked (cinfo, args)), args) + | NewArray (ty, args) -> + ShapeCombinationUnchecked (Shape (function args -> Expr.NewArrayUnchecked (ty, args)), args) + | NewDelegate (t, vars, expr) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.NewDelegateUnchecked (t, vars, expr) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | TupleGet (expr, n) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, n) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | Application (f, x) -> + ShapeCombinationUnchecked (Shape (function [f; x] -> Expr.ApplicationUnchecked (f, x) | _ -> invalidArg "expr" "invalid shape"), [f; x]) + | Call (objOpt, minfo, args) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.CallUnchecked (minfo, args)), args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.CallUnchecked (obj, minfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) + | PropertyGet (objOpt, pinfo, args) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.PropertyGetUnchecked (pinfo, args)), args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.PropertyGetUnchecked (obj, pinfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) + | PropertySet (objOpt, pinfo, args, value) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function (value::args) -> Expr.PropertySetUnchecked (pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), value::args) + | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::value::args) -> Expr.PropertySetUnchecked (obj, pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), obj::value::args) + | FieldGet (objOpt, pinfo) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function _ -> Expr.FieldGetUnchecked (pinfo)), []) + | Some obj -> ShapeCombinationUnchecked (Shape (function [obj] -> Expr.FieldGetUnchecked (obj, pinfo) | _ -> invalidArg "expr" "invalid shape"), [obj]) + | FieldSet (objOpt, pinfo, value) -> + match objOpt with + | None -> ShapeCombinationUnchecked (Shape (function [value] -> Expr.FieldSetUnchecked (pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [value]) + | Some obj -> ShapeCombinationUnchecked (Shape (function [obj;value] -> Expr.FieldSetUnchecked (obj, pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [obj; value]) + | Let (var, value, body) -> + ShapeCombinationUnchecked (Shape (function [value;Lambda(var, body)] -> Expr.LetUnchecked(var, value, body) | _ -> invalidArg "expr" "invalid shape"), [value; Expr.Lambda(var, body)]) + | ForIntegerRangeLoop (loopVar, first, last, body) -> + ShapeCombinationUnchecked (Shape (function [first; last; Lambda(loopVar, body)] -> Expr.ForIntegerRangeLoopUnchecked (loopVar, first, last, body) | _ -> invalidArg "expr" "invalid shape"), [first; last; Expr.Lambda(loopVar, body)]) + | WhileLoop (cond, body) -> + ShapeCombinationUnchecked (Shape (function [cond; body] -> Expr.WhileLoopUnchecked (cond, body) | _ -> invalidArg "expr" "invalid shape"), [cond; body]) + | IfThenElse (g, t, e) -> + ShapeCombinationUnchecked (Shape (function [g; t; e] -> Expr.IfThenElseUnchecked (g, t, e) | _ -> invalidArg "expr" "invalid shape"), [g; t; e]) + | TupleGet (expr, i) -> + ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, i) | _ -> invalidArg "expr" "invalid shape"), [expr]) + | ExprShape.ShapeCombination (comb,args) -> + ShapeCombinationUnchecked (Shape (fun args -> ExprShape.RebuildShapeCombination(comb, args)), args) + | ExprShape.ShapeVar v -> ShapeVarUnchecked v + | ExprShape.ShapeLambda (v, e) -> ShapeLambdaUnchecked (v,e) + + let RebuildShapeCombinationUnchecked (Shape comb,args) = comb args + + //-------------------------------------------------------------------------------- + // Instantiated symbols + // + + /// Represents the type constructor in a provided symbol type. + [] + type ProvidedTypeSymbolKind = + | SDArray + | Array of int + | Pointer + | ByRef + | Generic of Type + | FSharpTypeAbbreviation of (Assembly * string * string[]) + + + /// Represents an array or other symbolic type involving a provided type as the argument. + /// See the type provider spec for the methods that must be implemented. + /// Note that the type provider specification does not require us to implement pointer-equality for provided types. + type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list) as this = + inherit TypeDelegator() + let typeArgs = Array.ofList typeArgs + + do this.typeImpl <- this + + /// Substitute types for type variables. + override _.FullName = + match kind,typeArgs with + | ProvidedTypeSymbolKind.SDArray,[| arg |] -> arg.FullName + "[]" + | ProvidedTypeSymbolKind.Array _,[| arg |] -> arg.FullName + "[*]" + | ProvidedTypeSymbolKind.Pointer,[| arg |] -> arg.FullName + "*" + | ProvidedTypeSymbolKind.ByRef,[| arg |] -> arg.FullName + "&" + | ProvidedTypeSymbolKind.Generic gty, typeArgs -> gty.FullName + "[" + (typeArgs |> Array.map (fun arg -> arg.ToString()) |> String.concat ",") + "]" + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_,nsp,path),typeArgs -> String.concat "." (Array.append [| nsp |] path) + (match typeArgs with [| |] -> "" | _ -> typeArgs.ToString()) + | _ -> failwith "unreachable" + + /// Although not strictly required by the type provider specification, this is required when doing basic operations like FullName on + /// .NET symbolic types made from this type, e.g. when building Nullable.FullName + override _.DeclaringType = + match kind with + | ProvidedTypeSymbolKind.SDArray -> null + | ProvidedTypeSymbolKind.Array _ -> null + | ProvidedTypeSymbolKind.Pointer -> null + | ProvidedTypeSymbolKind.ByRef -> null + | ProvidedTypeSymbolKind.Generic gty -> gty.DeclaringType + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> null + + override _.Name = + match kind,typeArgs with + | ProvidedTypeSymbolKind.SDArray,[| arg |] -> arg.Name + "[]" + | ProvidedTypeSymbolKind.Array _,[| arg |] -> arg.Name + "[*]" + | ProvidedTypeSymbolKind.Pointer,[| arg |] -> arg.Name + "*" + | ProvidedTypeSymbolKind.ByRef,[| arg |] -> arg.Name + "&" + | ProvidedTypeSymbolKind.Generic gty, _typeArgs -> gty.Name + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_,_,path),_ -> path.[path.Length-1] + | _ -> failwith "unreachable" + + override _.BaseType = + match kind with + | ProvidedTypeSymbolKind.SDArray -> typeof + | ProvidedTypeSymbolKind.Array _ -> typeof + | ProvidedTypeSymbolKind.Pointer -> typeof + | ProvidedTypeSymbolKind.ByRef -> typeof + | ProvidedTypeSymbolKind.Generic gty -> + if isNull gty.BaseType then null else + instType (typeArgs, [| |]) gty.BaseType + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> typeof + + override _.GetArrayRank() = (match kind with ProvidedTypeSymbolKind.Array n -> n | ProvidedTypeSymbolKind.SDArray -> 1 | _ -> failwithf "non-array type '%O'" this) + override _.IsValueTypeImpl() = (match kind with ProvidedTypeSymbolKind.Generic gtd -> gtd.IsValueType | _ -> false) + override _.IsArrayImpl() = (match kind with ProvidedTypeSymbolKind.Array _ | ProvidedTypeSymbolKind.SDArray -> true | _ -> false) + override _.IsByRefImpl() = (match kind with ProvidedTypeSymbolKind.ByRef _ -> true | _ -> false) + override _.IsPointerImpl() = (match kind with ProvidedTypeSymbolKind.Pointer _ -> true | _ -> false) + override _.IsPrimitiveImpl() = false + override _.IsGenericType = (match kind with ProvidedTypeSymbolKind.Generic _ -> true | _ -> false) + override this.GetGenericArguments() = (match kind with ProvidedTypeSymbolKind.Generic _ -> typeArgs | _ -> failwithf "non-generic type '%O'" this) + override this.GetGenericTypeDefinition() = (match kind with ProvidedTypeSymbolKind.Generic e -> e | _ -> failwithf "non-generic type '%O'" this) + override _.IsCOMObjectImpl() = false + override _.HasElementTypeImpl() = (match kind with ProvidedTypeSymbolKind.Generic _ -> false | _ -> true) + override _.GetElementType() = (match kind,typeArgs with (ProvidedTypeSymbolKind.Array _ | ProvidedTypeSymbolKind.SDArray | ProvidedTypeSymbolKind.ByRef | ProvidedTypeSymbolKind.Pointer),[| e |] -> e | _ -> failwithf "not an array, pointer or byref type") + + override this.Assembly = + match kind, typeArgs with + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (assembly,_nsp,_path), _ -> assembly + | ProvidedTypeSymbolKind.Generic gty, _ -> gty.Assembly + | ProvidedTypeSymbolKind.SDArray,[| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.Array _,[| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.Pointer,[| arg |] -> arg.Assembly + | ProvidedTypeSymbolKind.ByRef,[| arg |] -> arg.Assembly + | _ -> notRequired this "Assembly" this.FullName + + override this.Namespace = + match kind,typeArgs with + | ProvidedTypeSymbolKind.SDArray,[| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Array _,[| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Pointer,[| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.ByRef,[| arg |] -> arg.Namespace + | ProvidedTypeSymbolKind.Generic gty,_ -> gty.Namespace + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_assembly,nsp,_path),_ -> nsp + | _ -> notRequired this "Namespace" this.FullName + + override x.Module = x.Assembly.ManifestModule + + override _.GetHashCode() = + match kind,typeArgs with + | ProvidedTypeSymbolKind.SDArray,[| arg |] -> 10 + hash arg + | ProvidedTypeSymbolKind.Array _,[| arg |] -> 163 + hash arg + | ProvidedTypeSymbolKind.Pointer,[| arg |] -> 283 + hash arg + | ProvidedTypeSymbolKind.ByRef,[| arg |] -> 43904 + hash arg + | ProvidedTypeSymbolKind.Generic gty,_ -> 9797 + hash gty + Array.sumBy hash typeArgs + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _,_ -> 3092 + | _ -> failwith "unreachable" + + override this.Equals(other: obj) = eqTypeObj this other + + override this.Equals(otherTy: Type) = eqTypes this otherTy + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + member _.Kind = kind + + member _.Args = typeArgs + + member _.IsFSharpTypeAbbreviation = match kind with FSharpTypeAbbreviation _ -> true | _ -> false + + // For example, int + member _.IsFSharpUnitAnnotated = match kind with ProvidedTypeSymbolKind.Generic gtd -> not gtd.IsGenericTypeDefinition | _ -> false + + override _.GetConstructorImpl(_bindingFlags, _binder, _callConventions, _types, _modifiers) = null + + override this.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, _types, _modifiers) = + match kind with + | Generic gtd -> + let ty = gtd.GetGenericTypeDefinition().MakeGenericType(typeArgs) + ty.GetMethod(name, bindingFlags) + | _ -> notRequired this "GetMethodImpl" this.FullName + + + override this.GetField(_name, _bindingFlags) = notRequired this "GetField" this.FullName + + override this.GetPropertyImpl(_name, _bindingFlags, _binder, _returnType, _types, _modifiers) = notRequired this "GetPropertyImpl" this.FullName + + override this.GetEvent(_name, _bindingFlags) = notRequired this "GetEvent" this.FullName + + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.FullName + + override this.GetConstructors _bindingFlags = notRequired this "GetConstructors" this.FullName + + override this.GetMethods _bindingFlags = notRequired this "GetMethods" this.FullName + + override this.GetFields _bindingFlags = notRequired this "GetFields" this.FullName + + override this.GetProperties _bindingFlags = notRequired this "GetProperties" this.FullName + + override this.GetEvents _bindingFlags = notRequired this "GetEvents" this.FullName + + override this.GetNestedTypes _bindingFlags = notRequired this "GetNestedTypes" this.FullName + + override this.GetMembers _bindingFlags = notRequired this "GetMembers" this.FullName + + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.FullName + + override this.GetInterfaces() = notRequired this "GetInterfaces" this.FullName + + override this.GetAttributeFlagsImpl() = getAttributeFlagsImpl this + + override this.UnderlyingSystemType = + match kind with + | ProvidedTypeSymbolKind.SDArray + | ProvidedTypeSymbolKind.Array _ + | ProvidedTypeSymbolKind.Pointer + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ + | ProvidedTypeSymbolKind.ByRef -> upcast this + | ProvidedTypeSymbolKind.Generic gty -> gty.UnderlyingSystemType + + override _.GetCustomAttributesData() = ([| |] :> IList<_>) + + override this.MemberType = notRequired this "MemberType" this.FullName + + override this.GetMember(_name,_mt,_bindingFlags) = notRequired this "GetMember" this.FullName + + override this.GUID = notRequired this "GUID" this.FullName + + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" this.FullName + + override this.AssemblyQualifiedName = notRequired this "AssemblyQualifiedName" this.FullName + + override _.GetCustomAttributes(_inherit) = emptyAttributes + + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + + override _.IsDefined(_attributeType, _inherit) = false + + override this.MakeArrayType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.SDArray, [this]) :> Type + + override this.MakeArrayType arg = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Array arg, [this]) :> Type + + override _.MetadataToken = + match kind with + | ProvidedTypeSymbolKind.SDArray -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Array _ -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Pointer -> typeof.MetadataToken + | ProvidedTypeSymbolKind.ByRef -> typeof.MetadataToken + | ProvidedTypeSymbolKind.Generic gty -> gty.MetadataToken + | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _ -> typeof.MetadataToken + + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + override this.ToString() = this.FullName + + type ProvidedSymbolMethod(genericMethodDefinition: MethodInfo, parameters: Type[]) = + inherit MethodInfo() + + let convParam (p:ParameterInfo) = + { new ParameterInfo() with + override _.Name = p.Name + override _.ParameterType = instType (parameters, [| |]) p.ParameterType + override _.Attributes = p.Attributes + override _.RawDefaultValue = p.RawDefaultValue + override _.GetCustomAttributesData() = p.GetCustomAttributesData() + } + + override this.IsGenericMethod = + (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) < parameters.Length + + override this.GetGenericArguments() = + Seq.skip (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) parameters |> Seq.toArray + + override _.GetGenericMethodDefinition() = genericMethodDefinition + + override _.DeclaringType = instType (parameters, [| |]) genericMethodDefinition.DeclaringType + override _.ToString() = "Method " + genericMethodDefinition.Name + override _.Name = genericMethodDefinition.Name + override _.MetadataToken = genericMethodDefinition.MetadataToken + override _.Attributes = genericMethodDefinition.Attributes + override _.CallingConvention = genericMethodDefinition.CallingConvention + override _.MemberType = genericMethodDefinition.MemberType + + override this.IsDefined(_attributeType, _inherit): bool = notRequired this "IsDefined" genericMethodDefinition.Name + override _.ReturnType = instType (parameters, [| |]) genericMethodDefinition.ReturnType + override _.GetParameters() = genericMethodDefinition.GetParameters() |> Array.map convParam + override _.ReturnParameter = genericMethodDefinition.ReturnParameter |> convParam + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" genericMethodDefinition.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" genericMethodDefinition.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" genericMethodDefinition.Name + override this.MethodHandle = notRequired this "MethodHandle" genericMethodDefinition.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" genericMethodDefinition.Name + override this.ReflectedType = notRequired this "ReflectedType" genericMethodDefinition.Name + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + + //-------------------------------------------------------------------------------- + // ProvidedMethod, ProvidedConstructor, ProvidedTypeDefinition and other provided objects + + + [] + module Misc = + + + let mkParamArrayCustomAttributeData() = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| |] + member _.NamedArguments = upcast [| |] } + + let mkEditorHideMethodsCustomAttributeData() = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| |] + member _.NamedArguments = upcast [| |] } + + let mkAllowNullLiteralCustomAttributeData value = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, value) |] + member _.NamedArguments = upcast [| |] } + + /// This makes an xml doc attribute w.r.t. an amortized computation of an xml doc string. + /// It is important that the text of the xml doc only get forced when poking on the ConstructorArguments + /// for the CustomAttributeData object. + let mkXmlDocCustomAttributeDataLazy(lazyText: Lazy) = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, lazyText.Force()) |] + member _.NamedArguments = upcast [| |] } + + let mkXmlDocCustomAttributeData(s:string) = mkXmlDocCustomAttributeDataLazy (lazy s) + + let mkDefinitionLocationAttributeCustomAttributeData(line:int,column:int,filePath:string) = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| |] + member _.NamedArguments = + upcast [| CustomAttributeNamedArgument(typeof.GetProperty("FilePath"), CustomAttributeTypedArgument(typeof, filePath)); + CustomAttributeNamedArgument(typeof.GetProperty("Line"), CustomAttributeTypedArgument(typeof, line)) ; + CustomAttributeNamedArgument(typeof.GetProperty("Column"), CustomAttributeTypedArgument(typeof, column)) + |] } + let mkObsoleteAttributeCustomAttributeData(message:string, isError: bool) = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors() |> Array.find (fun x -> x.GetParameters().Length = 2) + member _.ConstructorArguments = upcast [|CustomAttributeTypedArgument(typeof, message) ; CustomAttributeTypedArgument(typeof, isError) |] + member _.NamedArguments = upcast [| |] } + + let mkReflectedDefinitionCustomAttributeData() = + { new CustomAttributeData() with + member _.Constructor = typeof.GetConstructors().[0] + member _.ConstructorArguments = upcast [| |] + member _.NamedArguments = upcast [| |] } + + type CustomAttributesImpl(customAttributesData) = + let customAttributes = ResizeArray() + let mutable hideObjectMethods = false + let mutable nonNullable = false + let mutable obsoleteMessage = None + let mutable xmlDocDelayed = None + let mutable xmlDocAlwaysRecomputed = None + let mutable hasParamArray = false + let mutable hasReflectedDefinition = false + + // XML doc text that we only compute once, if any. This must _not_ be forced until the ConstructorArguments + // property of the custom attribute is foced. + let xmlDocDelayedText = + lazy + (match xmlDocDelayed with None -> assert false; "" | Some f -> f()) + + // Custom atttributes that we only compute once + let customAttributesOnce = + lazy + [| if hideObjectMethods then yield mkEditorHideMethodsCustomAttributeData() + if nonNullable then yield mkAllowNullLiteralCustomAttributeData false + match xmlDocDelayed with None -> () | Some _ -> customAttributes.Add(mkXmlDocCustomAttributeDataLazy xmlDocDelayedText) + match obsoleteMessage with None -> () | Some s -> customAttributes.Add(mkObsoleteAttributeCustomAttributeData s) + if hasParamArray then yield mkParamArrayCustomAttributeData() + if hasReflectedDefinition then yield mkReflectedDefinitionCustomAttributeData() + yield! customAttributesData() + yield! customAttributes |] + + member _.AddDefinitionLocation(line:int,column:int,filePath:string) = customAttributes.Add(mkDefinitionLocationAttributeCustomAttributeData(line, column, filePath)) + member _.AddObsolete(message: string, isError) = obsoleteMessage <- Some (message,isError) + member _.HasParamArray with get() = hasParamArray and set(v) = hasParamArray <- v + member _.HasReflectedDefinition with get() = hasReflectedDefinition and set(v) = hasReflectedDefinition <- v + member _.AddXmlDocComputed xmlDocFunction = xmlDocAlwaysRecomputed <- Some xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = xmlDocDelayed <- Some xmlDocFunction + member _.AddXmlDoc xmlDoc = xmlDocDelayed <- Some (K xmlDoc) + member _.HideObjectMethods with get() = hideObjectMethods and set v = hideObjectMethods <- v + member _.NonNullable with get () = nonNullable and set v = nonNullable <- v + member _.AddCustomAttribute(attribute) = customAttributes.Add(attribute) + member _.GetCustomAttributesData() = + [| yield! customAttributesOnce.Force() + // Recomputed XML doc is evaluated on every call to GetCustomAttributesData() + match xmlDocAlwaysRecomputed with None -> () | Some f -> yield mkXmlDocCustomAttributeData (f()) |] + :> IList<_> + + + type ProvidedStaticParameter(isTgt: bool, parameterName:string, parameterType:Type, parameterDefaultValue:obj option, customAttributesData) = + inherit ParameterInfo() + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + new (parameterName:string, parameterType:Type, ?parameterDefaultValue:obj) = + ProvidedStaticParameter(false, parameterName, parameterType, parameterDefaultValue, (K [| |])) + + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + + member _.ParameterDefaultValue = parameterDefaultValue + member _.BelongsToTargetModel = isTgt + + override _.RawDefaultValue = defaultArg parameterDefaultValue null + override _.Attributes = if parameterDefaultValue.IsNone then enum 0 else ParameterAttributes.Optional + override _.Position = 0 + override _.ParameterType = parameterType + override _.Name = parameterName + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + type ProvidedParameter(isTgt: bool, parameterName:string, attrs, parameterType:Type, optionalValue:obj option, customAttributesData) = + + inherit ParameterInfo() + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + new (parameterName:string, parameterType:Type, ?isOut:bool, ?optionalValue:obj) = + ProvidedParameter(false, parameterName, parameterType, isOut, optionalValue) + + new (_isTgt, parameterName:string, parameterType:Type, isOut:bool option, optionalValue:obj option) = + let isOut = defaultArg isOut false + let attrs = (if isOut then ParameterAttributes.Out else enum 0) ||| + (match optionalValue with None -> enum 0 | Some _ -> ParameterAttributes.Optional ||| ParameterAttributes.HasDefault) + ProvidedParameter(false, parameterName, attrs, parameterType, optionalValue, K [| |]) + + member _.IsParamArray with set(v) = customAttributesImpl.HasParamArray <- v + member _.IsReflectedDefinition with set(v) = customAttributesImpl.HasReflectedDefinition <- v + member _.OptionalValue = optionalValue + member _.HasDefaultParameterValue = Option.isSome optionalValue + member _.BelongsToTargetModel = isTgt + member _.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) + + override _.Name = parameterName + override _.ParameterType = parameterType + override _.Attributes = attrs + override _.RawDefaultValue = defaultArg optionalValue null + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + and ProvidedConstructor(isTgt: bool, attrs: MethodAttributes, parameters: ProvidedParameter[], invokeCode: (Expr list -> Expr), baseCall, isImplicitCtor, customAttributesData) = + + inherit ConstructorInfo() + let parameterInfos = parameters |> Array.map (fun p -> p :> ParameterInfo) + let mutable baseCall = baseCall + let mutable declaringType : ProvidedTypeDefinition option = None + let mutable isImplicitCtor = isImplicitCtor + let mutable attrs = attrs + let isStatic() = attrs.HasFlag(MethodAttributes.Static) + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + new (parameters, invokeCode) = + ProvidedConstructor(false, MethodAttributes.Public ||| MethodAttributes.RTSpecialName, Array.ofList parameters, invokeCode, None, false, K [| |]) + + member _.IsTypeInitializer + with get() = isStatic() && attrs.HasFlag(MethodAttributes.Private) + and set(v) = + let typeInitializerAttributes = MethodAttributes.Static ||| MethodAttributes.Private + attrs <- if v then attrs ||| typeInitializerAttributes else attrs &&& ~~~typeInitializerAttributes + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + + member _.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + member this.BaseConstructorCall + with set (d:Expr list -> (ConstructorInfo * Expr list)) = + match baseCall with + | None -> baseCall <- Some d + | Some _ -> failwithf "ProvidedConstructor: base call already given for '%s'" this.Name + + member _.IsImplicitConstructor with get() = isImplicitCtor and set v = isImplicitCtor <- v + member _.BaseCall = baseCall + member _.Parameters = parameters + member _.GetInvokeCode args = invokeCode args + member _.BelongsToTargetModel = isTgt + member _.DeclaringProvidedType = declaringType + member this.IsErased = (nonNone "DeclaringType" this.DeclaringProvidedType).IsErased + + // Implement overloads + override _.GetParameters() = parameterInfos + override _.Attributes = attrs + override _.Name = if isStatic() then ".cctor" else ".ctor" + override _.DeclaringType = declaringType |> nonNone "DeclaringType" :> Type + override _.IsDefined(_attributeType, _inherit) = true + + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + and ProvidedMethod(isTgt: bool, methodName: string, attrs: MethodAttributes, parameters: ProvidedParameter[], returnType: Type, invokeCode: (Expr list -> Expr), staticParams, staticParamsApply, customAttributesData) = + inherit MethodInfo() + let parameterInfos = parameters |> Array.map (fun p -> p :> ParameterInfo) + + let mutable declaringType : ProvidedTypeDefinition option = None + let mutable attrs = attrs + let mutable staticParams = staticParams + let mutable staticParamsApply = staticParamsApply + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + /// The public constructor for the design-time/source model + new (methodName, parameters, returnType, invokeCode, ?isStatic) = + let isStatic = defaultArg isStatic false + let attrs = if isStatic then MethodAttributes.Public ||| MethodAttributes.Static else MethodAttributes.Public + ProvidedMethod(false, methodName, attrs, Array.ofList parameters, returnType, invokeCode, [], None, K [| |]) + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member _.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) + + member _.SetMethodAttrs attributes = attrs <- attributes + member _.AddMethodAttrs attributes = attrs <- attrs ||| attributes + member _.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + + /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". + member _.DefineStaticParameters(parameters: ProvidedStaticParameter list, instantiationFunction: (string -> obj[] -> ProvidedMethod)) = + staticParams <- parameters + staticParamsApply <- Some instantiationFunction + + /// Get ParameterInfo[] for the parametric type parameters + member _.GetStaticParametersInternal() = [| for p in staticParams -> p :> ParameterInfo |] + + /// Instantiate parametric method + member this.ApplyStaticArguments(mangledName:string, args:obj[]) = + if staticParams.Length <> args.Length then + failwithf "ProvidedMethod: expecting %d static parameters but given %d for method %s" staticParams.Length args.Length methodName + if staticParams.Length > 0 then + match staticParamsApply with + | None -> failwith "ProvidedMethod: DefineStaticParameters was not called" + | Some f -> f mangledName args + else + this + + member _.Parameters = parameters + member _.GetInvokeCode args = invokeCode args + member _.StaticParams = staticParams + member _.StaticParamsApply = staticParamsApply + member _.BelongsToTargetModel = isTgt + member _.DeclaringProvidedType = declaringType + member this.IsErased = (nonNone "DeclaringType" this.DeclaringProvidedType).IsErased + + // Implement overloads + override _.GetParameters() = parameterInfos + override _.Attributes = attrs + override _.Name = methodName + override _.DeclaringType = declaringType |> nonNone "DeclaringType" :> Type + override _.IsDefined(_attributeType, _inherit): bool = true + override _.MemberType = MemberTypes.Method + override x.CallingConvention = + let cc = CallingConventions.Standard + let cc = if not x.IsStatic then cc ||| CallingConventions.HasThis else cc + cc + override _.ReturnType = returnType + override _.ReturnParameter = null // REVIEW: Give it a name and type? + override _.ToString() = "Method " + methodName + + // These don't have to return fully accurate results - they are used + // by the F# Quotations library function SpecificCall as a pre-optimization + // when comparing methods + override _.MetadataToken = genToken() + override _.MethodHandle = RuntimeMethodHandle() + + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" methodName + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" methodName + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" methodName + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" methodName + override this.ReflectedType = notRequired this "ReflectedType" methodName + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + + and ProvidedProperty(isTgt: bool, propertyName: string, attrs: PropertyAttributes, propertyType: Type, isStatic: bool, getter: (unit -> MethodInfo) option, setter: (unit -> MethodInfo) option, indexParameters: ProvidedParameter[], customAttributesData) = + inherit PropertyInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + /// The public constructor for the design-time/source model + new (propertyName, propertyType, ?getterCode, ?setterCode, ?isStatic, ?indexParameters) = + let isStatic = defaultArg isStatic false + let indexParameters = defaultArg indexParameters [] + let pattrs = (if isStatic then MethodAttributes.Static else enum(0)) ||| MethodAttributes.Public ||| MethodAttributes.SpecialName + let getter = getterCode |> Option.map (fun code -> ProvidedMethod(false, "get_" + propertyName, pattrs, Array.ofList indexParameters, propertyType, code, [], None, K [| |]) :> MethodInfo) + let setter = setterCode |> Option.map (fun code -> ProvidedMethod(false, "set_" + propertyName, pattrs, [| yield! indexParameters; yield ProvidedParameter(false, "value",propertyType,isOut=Some false,optionalValue=None) |], typeof,code, [], None, K [| |]) :> MethodInfo) + ProvidedProperty(false, propertyName, PropertyAttributes.None, propertyType, isStatic, Option.map K getter, Option.map K setter, Array.ofList indexParameters, K [| |]) + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member _.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + member _.PatchDeclaringType x = + if not isTgt then + match getter with Some f -> (match f() with (:? ProvidedMethod as g) -> g.PatchDeclaringType x | _ -> ()) | _ -> () + match setter with Some f -> (match f() with (:? ProvidedMethod as s) -> s.PatchDeclaringType x | _ -> ()) | _ -> () + patchOption declaringType (fun () -> declaringType <- Some x) + + member _.IsStatic = isStatic + member _.IndexParameters = indexParameters + member _.BelongsToTargetModel = isTgt + member _.Getter = getter + member _.Setter = setter + + override _.PropertyType = propertyType + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" propertyName + override this.GetAccessors _nonPublic = notRequired this "nonPublic" propertyName + override _.GetGetMethod _nonPublic = match getter with None -> null | Some g -> g() + override _.GetSetMethod _nonPublic = match setter with None -> null | Some s -> s() + override _.GetIndexParameters() = [| for p in indexParameters -> upcast p |] + override _.Attributes = attrs + override _.CanRead = getter.IsSome + override _.CanWrite = setter.IsSome + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture): obj = notRequired this "GetValue" propertyName + override _.Name = propertyName + override _.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override _.MemberType: MemberTypes = MemberTypes.Property + + override this.ReflectedType = notRequired this "ReflectedType" propertyName + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" propertyName + + and ProvidedEvent(isTgt: bool, eventName:string, attrs: EventAttributes, eventHandlerType:Type, isStatic: bool, adder: (unit -> MethodInfo), remover: (unit -> MethodInfo), customAttributesData) = + inherit EventInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + new (eventName, eventHandlerType, adderCode, removerCode, ?isStatic) = + let isStatic = defaultArg isStatic false + let pattrs = (if isStatic then MethodAttributes.Static else enum(0)) ||| MethodAttributes.Public ||| MethodAttributes.SpecialName + let adder = ProvidedMethod(false, "add_" + eventName, pattrs, [| ProvidedParameter(false, "handler", eventHandlerType, isOut=Some false, optionalValue=None) |], typeof, adderCode, [], None, K [| |]) :> MethodInfo + let remover = ProvidedMethod(false, "remove_" + eventName, pattrs, [| ProvidedParameter(false, "handler", eventHandlerType, isOut=Some false, optionalValue=None) |], typeof, removerCode, [], None, K [| |]) :> MethodInfo + ProvidedEvent(false, eventName, EventAttributes.None, eventHandlerType, isStatic, K adder, K remover, K [| |]) + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + + member _.PatchDeclaringType x = + if not isTgt then + match adder() with :? ProvidedMethod as a -> a.PatchDeclaringType x | _ -> () + match remover() with :? ProvidedMethod as r -> r.PatchDeclaringType x | _ -> () + patchOption declaringType (fun () -> declaringType <- Some x) + + member _.IsStatic = isStatic + member _.Adder = adder() + member _.Remover = remover() + member _.BelongsToTargetModel = isTgt + + override _.EventHandlerType = eventHandlerType + override _.GetAddMethod _nonPublic = adder() + override _.GetRemoveMethod _nonPublic = remover() + override _.Attributes = attrs + override _.Name = eventName + override _.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override _.MemberType: MemberTypes = MemberTypes.Event + + override this.GetRaiseMethod _nonPublic = notRequired this "GetRaiseMethod" eventName + override this.ReflectedType = notRequired this "ReflectedType" eventName + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" eventName + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + and ProvidedField(isTgt: bool, fieldName:string, attrs, fieldType:Type, rawConstantValue: obj, customAttributesData) = + inherit FieldInfo() + + let mutable declaringType : ProvidedTypeDefinition option = None + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + let mutable attrs = attrs + + new (fieldName:string, fieldType:Type, value:obj) = ProvidedField(false, fieldName, FieldAttributes.Private, fieldType, value, (K [| |])) + new (fieldName:string, fieldType:Type) = ProvidedField(fieldName, fieldType, null) + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + + member _.SetFieldAttributes attributes = attrs <- attributes + member _.BelongsToTargetModel = isTgt + + member _.PatchDeclaringType x = patchOption declaringType (fun () -> declaringType <- Some x) + + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + // Implement overloads + override _.FieldType = fieldType + override _.GetRawConstantValue() = rawConstantValue + override _.Attributes = attrs + override _.Name = fieldName + override _.DeclaringType = declaringType |> nonNone "DeclaringType":> Type + override _.MemberType: MemberTypes = MemberTypes.Field + + override this.ReflectedType = notRequired this "ReflectedType" fieldName + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override this.IsDefined(_attributeType, _inherit) = notRequired this "IsDefined" fieldName + + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" fieldName + override this.GetValue(_obj): obj = notRequired this "GetValue" fieldName + override this.FieldHandle = notRequired this "FieldHandle" fieldName + + static member Literal(fieldName:string, fieldType:Type, literalValue: obj) = + ProvidedField(false, fieldName, (FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public), fieldType, literalValue, K [| |]) + + + and ProvidedMeasureBuilder() = + + // TODO: this shouldn't be hardcoded, but without creating a dependency on FSharp.Compiler.Service + // there seems to be no way to check if a type abbreviation exists + static let unitNamesTypeAbbreviations = + [ "meter"; "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb"; + "volt"; "farad"; "ohm"; "siemens"; "weber"; "tesla"; "henry" + "lumen"; "lux"; "becquerel"; "gray"; "sievert"; "katal" ] + |> Set.ofList + + static let unitSymbolsTypeAbbreviations = + [ "m"; "kg"; "s"; "A"; "K"; "mol"; "cd"; "Hz"; "N"; "Pa"; "J"; "W"; "C" + "V"; "F"; "S"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H" ] + |> Set.ofList + + static member One = typeof + static member Product (measure1, measure2) = typedefof>.MakeGenericType [| measure1;measure2 |] + static member Inverse denominator = typedefof>.MakeGenericType [| denominator |] + static member Ratio (numerator, denominator) = ProvidedMeasureBuilder.Product(numerator, ProvidedMeasureBuilder.Inverse denominator) + static member Square m = ProvidedMeasureBuilder.Product(m, m) + + // If the unit is not a valid type, instead + // of assuming it's a type abbreviation, which may not be the case and cause a + // problem later on, check the list of valid abbreviations + static member SI (unitName:string) = + let mLowerCase = unitName.ToLowerInvariant() + let abbreviation = + if unitNamesTypeAbbreviations.Contains mLowerCase then + Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames", mLowerCase) + elif unitSymbolsTypeAbbreviations.Contains unitName then + Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols", unitName) + else + None + match abbreviation with + | Some (ns, unitName) -> + ProvidedTypeSymbol(ProvidedTypeSymbolKind.FSharpTypeAbbreviation(typeof.Assembly,ns,[| unitName |]), []) :> Type + | None -> + typedefof>.Assembly.GetType("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames." + mLowerCase) + + static member AnnotateType (basic, argument) = ProvidedTypeSymbol(Generic basic, argument) :> Type + + and + [] + TypeContainer = + | Namespace of (unit -> Assembly) * string // namespace + | Type of ProvidedTypeDefinition + | TypeToBeDecided + + and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: string, getBaseType: (unit -> Type option), attrs: TypeAttributes, getEnumUnderlyingType, staticParams, staticParamsApply, initialData, customAttributesData, nonNullable, hideObjectMethods) as this = + inherit TypeDelegator() + + do match container, !ProvidedTypeDefinition.Logger with + | TypeContainer.Namespace _, Some logger when not isTgt -> logger (sprintf "Creating ProvidedTypeDefinition %s [%d]" className (System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode this)) + | _ -> () + + static let defaultAttributes isErased = + TypeAttributes.Public ||| + TypeAttributes.Class ||| + TypeAttributes.Sealed ||| + enum (if isErased then int32 TypeProviderTypeAttributes.IsErased else 0) + + // state + let mutable attrs = attrs + let mutable enumUnderlyingType = lazy getEnumUnderlyingType() + let mutable baseType = lazy getBaseType() + + /// Represents the evaluated members so far + let members = ResizeArray() + + /// Represents delayed members, as yet uncomputed + let membersQueue = ResizeArray<(unit -> MemberInfo[])>() + + let mutable staticParamsDefined = false + let mutable staticParams = staticParams + let mutable staticParamsApply = staticParamsApply + let mutable container = container + let interfaceImpls = ResizeArray() + let interfacesQueue = ResizeArray Type[]>() + let methodOverrides = ResizeArray() + let methodOverridesQueue = ResizeArray (ProvidedMethod * MethodInfo)[]>() + + do match initialData with + | None -> () + | Some (getFreshMembers, getFreshInterfaces, getFreshMethodOverrides) -> + membersQueue.Add getFreshMembers + interfacesQueue.Add getFreshInterfaces + methodOverridesQueue.Add getFreshMethodOverrides + + let evalMembers() = + if membersQueue.Count > 0 then + let elems = membersQueue |> Seq.toArray // take a copy in case more elements get added + membersQueue.Clear() + for f in elems do + for m in f() do + members.Add m + + // Implicitly add the property and event methods (only for the source model where they are not explicitly declared) + match m with + | :? ProvidedProperty as p -> + if not p.BelongsToTargetModel then + if p.CanRead then members.Add (p.GetGetMethod true) + if p.CanWrite then members.Add (p.GetSetMethod true) + | :? ProvidedEvent as e -> + if not e.BelongsToTargetModel then + members.Add (e.GetAddMethod true) + members.Add (e.GetRemoveMethod true) + | _ -> () + + // re-add the getFreshMembers call from the initialData to make sure we fetch the latest translated members from the source model + match initialData with + | None -> () + | Some (getFreshMembers, _getInterfaceImpls, _getMethodOverrides) -> + membersQueue.Add getFreshMembers + + + let getMembers() = + evalMembers() + members.ToArray() + + let evalInterfaces() = + if interfacesQueue.Count > 0 then + let elems = interfacesQueue |> Seq.toArray // take a copy in case more elements get added + interfacesQueue.Clear() + for f in elems do + for i in f() do + interfaceImpls.Add i + match initialData with + | None -> () + | Some (_getFreshMembers, getInterfaces, _getMethodOverrides) -> + interfacesQueue.Add getInterfaces + + let getInterfaces() = + evalInterfaces() + interfaceImpls.ToArray() + + let evalMethodOverrides () = + if methodOverridesQueue.Count > 0 then + let elems = methodOverridesQueue |> Seq.toArray // take a copy in case more elements get added + methodOverridesQueue.Clear() + for f in elems do + for i in f() do + methodOverrides.Add i + match initialData with + | None -> () + | Some (_getFreshMembers, _getInterfaceImpls, getMethodOverrides) -> + methodOverridesQueue.Add getMethodOverrides + + let getMethodOverrides () = + evalMethodOverrides () + methodOverrides.ToArray() + + let customAttributesImpl = CustomAttributesImpl(customAttributesData) + + do if nonNullable then customAttributesImpl.NonNullable <- true + do if hideObjectMethods then customAttributesImpl.HideObjectMethods <- true + do this.typeImpl <- this + + override _.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + + new (assembly:Assembly, namespaceName, className, baseType, ?hideObjectMethods, ?nonNullable, ?isErased) = + let isErased = defaultArg isErased true + let nonNullable = defaultArg nonNullable false + let hideObjectMethods = defaultArg hideObjectMethods false + let attrs = defaultAttributes isErased + //if not isErased && assembly.GetType().Name <> "ProvidedAssembly" then failwithf "a non-erased (i.e. generative) ProvidedTypeDefinition '%s.%s' was placed in an assembly '%s' that is not a ProvidedAssembly" namespaceName className (assembly.GetName().Name) + ProvidedTypeDefinition(false, TypeContainer.Namespace (K assembly,namespaceName), className, K baseType, attrs, K None, [], None, None, K [| |], nonNullable, hideObjectMethods) + + new (className:string, baseType, ?hideObjectMethods, ?nonNullable, ?isErased) = + let isErased = defaultArg isErased true + let nonNullable = defaultArg nonNullable false + let hideObjectMethods = defaultArg hideObjectMethods false + let attrs = defaultAttributes isErased + ProvidedTypeDefinition(false, TypeContainer.TypeToBeDecided, className, K baseType, attrs, K None, [], None, None, K [| |], nonNullable, hideObjectMethods) + + // state ops + + override _.UnderlyingSystemType = typeof + + // Implement overloads + override _.Assembly = + match container with + | TypeContainer.Namespace (theAssembly,_) -> theAssembly() + | TypeContainer.Type t -> t.Assembly + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not yet added as a member to a declaring type, stacktrace = %s" className Environment.StackTrace + + override _.FullName = + match container with + | TypeContainer.Type declaringType -> declaringType.FullName + "+" + className + | TypeContainer.Namespace (_,namespaceName) -> + if namespaceName="" then failwith "use null for global namespace" + match namespaceName with + | null -> className + | _ -> namespaceName + "." + className + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override _.Namespace = + match container with + | TypeContainer.Namespace (_,nsp) -> nsp + | TypeContainer.Type t -> t.Namespace + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override _.BaseType = match baseType.Value with Some ty -> ty | None -> null + + override _.GetConstructors bindingFlags = + getMembers() + |> Array.choose (function :? ConstructorInfo as c when memberBinds false bindingFlags c.IsStatic c.IsPublic -> Some c | _ -> None) + + override this.GetMethods bindingFlags = + getMembers() + |> Array.choose (function :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if bindingFlags.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags)))) + + override this.GetFields bindingFlags = + getMembers() + |> Array.choose (function :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if bindingFlags.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags)))) + + override this.GetProperties bindingFlags = + getMembers() + |> Array.choose (function :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if bindingFlags.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetProperties(bindingFlags)))) + + override this.GetEvents bindingFlags = + getMembers() + |> Array.choose (function :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) + |> (if bindingFlags.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags)))) + + override _.GetNestedTypes bindingFlags = + getMembers() + |> Array.choose (function :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> Some m | _ -> None) + |> (if bindingFlags.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags)))) + + override this.GetConstructorImpl(bindingFlags, _binder, _callConventions, _types, _modifiers) = + let xs = this.GetConstructors bindingFlags |> Array.filter (fun m -> m.Name = ".ctor") + if xs.Length > 1 then failwith "GetConstructorImpl. not support overloads" + if xs.Length > 0 then xs.[0] else null + + override _.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, _types, _modifiers): MethodInfo = + let xs = this.GetMethods bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 1 then failwithf "GetMethodImpl. not support overloads, name = '%s', methods - '%A', callstack = '%A'" name xs Environment.StackTrace + if xs.Length > 0 then xs.[0] else null + + override this.GetField(name, bindingFlags) = + let xs = this.GetFields bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null + + override _.GetPropertyImpl(name, bindingFlags, _binder, _returnType, _types, _modifiers) = + let xs = this.GetProperties bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null + + override _.GetEvent(name, bindingFlags) = + let xs = this.GetEvents bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null + + override _.GetNestedType(name, bindingFlags) = + let xs = this.GetNestedTypes bindingFlags |> Array.filter (fun m -> m.Name = name) + if xs.Length > 0 then xs.[0] else null + + override _.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.Name + + override _.GetInterfaces() = getInterfaces() + + + override _.MakeArrayType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.SDArray, [this]) :> Type + + override _.MakeArrayType arg = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Array arg, [this]) :> Type + + override _.MakePointerType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.Pointer, [this]) :> Type + + override _.MakeByRefType() = ProvidedTypeSymbol(ProvidedTypeSymbolKind.ByRef, [this]) :> Type + + // The binding attributes are always set to DeclaredOnly ||| Static ||| Instance ||| Public when GetMembers is called directly by the F# compiler + // However, it's possible for the framework to generate other sets of flags in some corner cases (e.g. via use of `enum` with a provided type as the target) + override _.GetMembers bindingFlags = + [| for m in getMembers() do + match m with + | :? ConstructorInfo as c when memberBinds false bindingFlags c.IsStatic c.IsPublic -> yield (c :> MemberInfo) + | :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> yield (m :> _) + | :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> yield (m :> _) + | _ -> () |] + + override this.GetMember(name,mt,_bindingFlags) = + let mt = if mt.HasFlag(MemberTypes.NestedType) then mt ||| MemberTypes.TypeInfo else mt + this.GetMembers() |> Array.filter (fun m -> 0 <> int(m.MemberType &&& mt) && m.Name = name) + + // Attributes, etc.. + override _.GetAttributeFlagsImpl() = adjustTypeAttributes this.IsNested attrs + + override this.IsValueTypeImpl() = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.FullName = "System.ValueType" || bt.IsValueType + + override _.IsEnum = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.IsEnum + + override _.GetEnumUnderlyingType() = + if this.IsEnum then + match enumUnderlyingType.Force() with + | None -> typeof + | Some ty -> ty + else failwithf "not enum type" + + override _.IsArrayImpl() = false + override _.IsByRefImpl() = false + override _.IsPointerImpl() = false + override _.IsPrimitiveImpl() = false + override _.IsCOMObjectImpl() = false + override _.HasElementTypeImpl() = false + override _.Name = className + + override _.DeclaringType = + match container with + | TypeContainer.Namespace _ -> null + | TypeContainer.Type enclosingTyp -> (enclosingTyp :> Type) + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + override _.MemberType = if this.IsNested then MemberTypes.NestedType else MemberTypes.TypeInfo + + override x.GetHashCode() = x.Namespace.GetHashCode() ^^^ className.GetHashCode() + override this.Equals(that: obj) = Object.ReferenceEquals(this, that) + override this.Equals(that: Type) = Object.ReferenceEquals(this, that) + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + override _.GetGenericArguments() = [||] + + override _.ToString() = this.Name + + override x.Module = x.Assembly.ManifestModule + + override _.GUID = Guid.Empty + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override _.IsDefined(_attributeType: Type, _inherit) = false + + override _.GetElementType() = notRequired this "Module" this.Name + override _.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "Module" this.Name + override _.AssemblyQualifiedName = notRequired this "Module" this.Name + // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + // Get the model + member _.BelongsToTargetModel = isTgt + member _.AttributesRaw = attrs + member _.EnumUnderlyingTypeRaw() = enumUnderlyingType.Force() + member _.Container = container + member _.BaseTypeRaw() = baseType.Force() + member _.StaticParams = staticParams + member _.StaticParamsApply = staticParamsApply + + // Fetch the members declared since the indicated position in the members list. This allows the target model to observe + // incremental additions made to the source model + member _.GetMembersFromCursor(idx: int) = evalMembers(); members.GetRange(idx, members.Count - idx).ToArray(), members.Count + + // Fetch the interfaces declared since the indicated position in the interfaces list + member _.GetInterfaceImplsFromCursor(idx: int) = evalInterfaces(); interfaceImpls.GetRange(idx, interfaceImpls.Count - idx).ToArray(), interfaceImpls.Count + + // Fetch the method overrides declared since the indicated position in the list + member _.GetMethodOverridesFromCursor(idx: int) = evalMethodOverrides(); methodOverrides.GetRange(idx, methodOverrides.Count - idx).ToArray(), methodOverrides.Count + + // Fetch the method overrides + member _.GetMethodOverrides() = getMethodOverrides() + + member this.ErasedBaseType : Type = ProvidedTypeDefinition.EraseType(this.BaseType) + + member _.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction + member _.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction + member _.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc + member _.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) + member _.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) + member _.HideObjectMethods with get() = customAttributesImpl.HideObjectMethods and set v = customAttributesImpl.HideObjectMethods <- v + member _.NonNullable with get() = customAttributesImpl.NonNullable and set v = customAttributesImpl.NonNullable <- v + member _.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute + + member _.SetEnumUnderlyingType(ty) = enumUnderlyingType <- lazy Some ty + member _.SetBaseType t = + if baseType.IsValueCreated then failwithf "The base type has already been evaluated for this type. Please call SetBaseType before any operations which traverse the type hierarchy. stacktrace = %A" Environment.StackTrace + baseType <- lazy Some t + member _.SetBaseTypeDelayed baseTypeFunction = + if baseType.IsValueCreated then failwithf "The base type has already been evaluated for this type. Please call SetBaseType before any operations which traverse the type hierarchy. stacktrace = %A" Environment.StackTrace + baseType <- lazy (Some (baseTypeFunction())) + member _.SetAttributes x = attrs <- x + + member this.AddMembers(memberInfos:list<#MemberInfo>) = + memberInfos |> List.iter this.PatchDeclaringTypeOfMember + membersQueue.Add (fun () -> memberInfos |> List.toArray |> Array.map (fun x -> x :> MemberInfo )) + + member _.AddMember(memberInfo:MemberInfo) = + this.AddMembers [memberInfo] + + member _.AddMembersDelayed(membersFunction: unit -> list<#MemberInfo>) = + membersQueue.Add (fun () -> membersFunction() |> List.toArray |> Array.map (fun x -> this.PatchDeclaringTypeOfMember x; x :> MemberInfo )) + + member _.AddMemberDelayed(memberFunction: unit -> #MemberInfo) = + this.AddMembersDelayed(fun () -> [memberFunction()]) + + member _.AddAssemblyTypesAsNestedTypesDelayed (assemblyFunction: unit -> Assembly) = + let bucketByPath nodef tipf (items: (string list * 'Value) list) = + // Find all the items with an empty key list and call 'tipf' + let tips = + [ for (keylist,v) in items do + match keylist with + | [] -> yield tipf v + | _ -> () ] + + // Find all the items with a non-empty key list. Bucket them together by + // the first key. For each bucket, call 'nodef' on that head key and the bucket. + let nodes = + let buckets = new Dictionary<_,_>(10) + for (keylist,v) in items do + match keylist with + | [] -> () + | key::rest -> + buckets.[key] <- (rest,v) :: (if buckets.ContainsKey key then buckets.[key] else []); + + [ for (KeyValue(key,items)) in buckets -> nodef key items ] + + tips @ nodes + this.AddMembersDelayed (fun _ -> + let topTypes = [ for ty in assemblyFunction().GetTypes() do + if not ty.IsNested then + let namespaceParts = match ty.Namespace with null -> [] | s -> s.Split '.' |> Array.toList + yield namespaceParts, ty ] + let rec loop types = + types + |> bucketByPath + (fun namespaceComponent typesUnderNamespaceComponent -> + let t = ProvidedTypeDefinition(namespaceComponent, baseType = Some typeof) + t.AddMembers (loop typesUnderNamespaceComponent) + (t :> Type)) + id + loop topTypes) + + /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". + member _.DefineStaticParameters(parameters: ProvidedStaticParameter list, instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition)) = + if staticParamsDefined then failwithf "Static parameters have already been defined for this type. stacktrace = %A" Environment.StackTrace + staticParamsDefined <- true + staticParams <- parameters + staticParamsApply <- Some instantiationFunction + + /// Get ParameterInfo[] for the parametric type parameters + member _.GetStaticParametersInternal() = [| for p in staticParams -> p :> ParameterInfo |] + + /// Instantiate parametric type + member this.ApplyStaticArguments(name:string, args:obj[]) = + if staticParams.Length <> args.Length then + failwithf "ProvidedTypeDefinition: expecting %d static parameters but given %d for type %s" staticParams.Length args.Length this.FullName + if staticParams.Length > 0 then + match staticParamsApply with + | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" + | Some f -> f name args + else + this + + member _.PatchDeclaringType x = container <- TypeContainer.Type x + + member _.IsErased + with get() = (attrs &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 + and set v = + if v then attrs <- attrs ||| enum (int32 TypeProviderTypeAttributes.IsErased) + else attrs <- attrs &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) + + member _.SuppressRelocation + with get() = (attrs &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 + and set v = + if v then attrs <- attrs ||| enum (int32 TypeProviderTypeAttributes.SuppressRelocate) + else attrs <- attrs &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) + + member _.AddInterfaceImplementation interfaceType = interfaceImpls.Add interfaceType + + member _.AddInterfaceImplementationsDelayed interfacesFunction = interfacesQueue.Add (interfacesFunction >> Array.ofList) + + member _.SetAssemblyInternal (assembly: unit -> Assembly) = + match container with + | TypeContainer.Namespace (_, ns) -> container <- TypeContainer.Namespace (assembly, ns) + | TypeContainer.Type _ -> failwithf "can't set assembly of nested type '%s'" className + | TypeContainer.TypeToBeDecided -> failwithf "type '%s' was not added as a member to a declaring type" className + + member _.DefineMethodOverride (methodInfoBody,methodInfoDeclaration) = methodOverrides.Add (methodInfoBody, methodInfoDeclaration) + member _.DefineMethodOverridesDelayed f = methodOverridesQueue.Add (f >> Array.ofList) + + // This method is used by Debug.fs and QuotationBuilder.fs. + // Emulate the F# type provider type erasure mechanism to get the + // actual (erased) type. We erase ProvidedTypes to their base type + // and we erase array of provided type to array of base type. In the + // case of generics all the generic type arguments are also recursively + // replaced with the erased-to types + static member EraseType(typ:Type): Type = + match typ with + | :? ProvidedTypeDefinition as ptd when ptd.IsErased -> ProvidedTypeDefinition.EraseType typ.BaseType + | t when t.IsArray -> + let rank = t.GetArrayRank() + let et = ProvidedTypeDefinition.EraseType (t.GetElementType()) + if rank = 0 then et.MakeArrayType() else et.MakeArrayType(rank) + | :? ProvidedTypeSymbol as sym when sym.IsFSharpUnitAnnotated -> + typ.UnderlyingSystemType + | t when t.IsGenericType && not t.IsGenericTypeDefinition -> + let genericTypeDefinition = t.GetGenericTypeDefinition() + let genericArguments = t.GetGenericArguments() |> Array.map ProvidedTypeDefinition.EraseType + genericTypeDefinition.MakeGenericType(genericArguments) + | t -> t + + + member this.PatchDeclaringTypeOfMember (m:MemberInfo) = + match m with + | :? ProvidedConstructor as c -> c.PatchDeclaringType this + | :? ProvidedMethod as m -> m.PatchDeclaringType this + | :? ProvidedProperty as p -> p.PatchDeclaringType this + | :? ProvidedEvent as e -> e.PatchDeclaringType this + | :? ProvidedTypeDefinition as t -> t.PatchDeclaringType this + | :? ProvidedField as l -> l.PatchDeclaringType this + | _ -> () + + static member Logger: (string -> unit) option ref = ref None + + +//==================================================================================================== +// AssemblyReader for ProvidedTypesContext // -// - Likewise, some operations in these quotation values like "expr.Type" may be a bit fragile, possibly returning non cross-targeted types in -// the result. However those operations are not used by the F# compiler. -[] -module internal UncheckedQuotations = - - let qTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.ExprConstInfo") - assert (qTy <> null) - let pTy = typeof.Assembly.GetType("Microsoft.FSharp.Quotations.PatternsModule") - assert (pTy<> null) - - // These are handles to the internal functions that create quotation nodes of different sizes. Although internal, - // these function names have been stable since F# 2.0. - let mkFE0 = pTy.GetMethod("mkFE0", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (mkFE0 <> null) - let mkFE1 = pTy.GetMethod("mkFE1", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (mkFE1 <> null) - let mkFE2 = pTy.GetMethod("mkFE2", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (mkFE2 <> null) - let mkFEN = pTy.GetMethod("mkFEN", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (mkFEN <> null) - - // These are handles to the internal tags attached to quotation nodes of different sizes. Although internal, - // these function names have been stable since F# 2.0. - let newDelegateOp = qTy.GetMethod("NewNewDelegateOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (newDelegateOp <> null) - let instanceCallOp = qTy.GetMethod("NewInstanceMethodCallOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (instanceCallOp <> null) - let staticCallOp = qTy.GetMethod("NewStaticMethodCallOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (staticCallOp <> null) - let newObjectOp = qTy.GetMethod("NewNewObjectOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (newObjectOp <> null) - let newArrayOp = qTy.GetMethod("NewNewArrayOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (newArrayOp <> null) - let appOp = qTy.GetMethod("get_AppOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (appOp <> null) - let instancePropGetOp = qTy.GetMethod("NewInstancePropGetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (instancePropGetOp <> null) - let staticPropGetOp = qTy.GetMethod("NewStaticPropGetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (staticPropGetOp <> null) - let instancePropSetOp = qTy.GetMethod("NewInstancePropSetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (instancePropSetOp <> null) - let staticPropSetOp = qTy.GetMethod("NewStaticPropSetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (staticPropSetOp <> null) - let instanceFieldGetOp = qTy.GetMethod("NewInstanceFieldGetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (instanceFieldGetOp <> null) - let staticFieldGetOp = qTy.GetMethod("NewStaticFieldGetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (staticFieldGetOp <> null) - let instanceFieldSetOp = qTy.GetMethod("NewInstanceFieldSetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (instanceFieldSetOp <> null) - let staticFieldSetOp = qTy.GetMethod("NewStaticFieldSetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (staticFieldSetOp <> null) - let tupleGetOp = qTy.GetMethod("NewTupleGetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (tupleGetOp <> null) - let letOp = qTy.GetMethod("get_LetOp", BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) - assert (letOp <> null) +// A lightweight .NET assembly reader that fits in a single F# file. Based on the well-tested Abstract IL +// binary reader code. Used by the type provider to read referenced asssemblies. + +namespace ProviderImplementation.ProvidedTypes.AssemblyReader + + #nowarn "1182" + + open System + open System.Collections.Generic + open System.Collections.Concurrent + open System.IO + open System.Reflection + open System.Text + open ProviderImplementation.ProvidedTypes + + [] + module Utils = + + let singleOfBits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x),0) + let doubleOfBits (x:int64) = System.BitConverter.Int64BitsToDouble(x) + + //--------------------------------------------------------------------- + // SHA1 hash-signing algorithm. Used to get the public key token from + // the public key. + //--------------------------------------------------------------------- + + // Little-endian encoding of int32 + let b0 n = byte (n &&& 0xFF) + let b1 n = byte ((n >>> 8) &&& 0xFF) + let b2 n = byte ((n >>> 16) &&& 0xFF) + let b3 n = byte ((n >>> 24) &&& 0xFF) + + // Little-endian encoding of int64 + let dw7 n = byte ((n >>> 56) &&& 0xFFL) + let dw6 n = byte ((n >>> 48) &&& 0xFFL) + let dw5 n = byte ((n >>> 40) &&& 0xFFL) + let dw4 n = byte ((n >>> 32) &&& 0xFFL) + let dw3 n = byte ((n >>> 24) &&& 0xFFL) + let dw2 n = byte ((n >>> 16) &&& 0xFFL) + let dw1 n = byte ((n >>> 8) &&& 0xFFL) + let dw0 n = byte (n &&& 0xFFL) + + + module SHA1 = + let inline (>>>&) (x:int) (y:int) = int32 (uint32 x >>> y) + let f(t,b,c,d) = + if t < 20 then (b &&& c) ||| ((~~~b) &&& d) + elif t < 40 then b ^^^ c ^^^ d + elif t < 60 then (b &&& c) ||| (b &&& d) ||| (c &&& d) + else b ^^^ c ^^^ d + + let [] k0to19 = 0x5A827999 + let [] k20to39 = 0x6ED9EBA1 + let [] k40to59 = 0x8F1BBCDC + let [] k60to79 = 0xCA62C1D6 + + let k t = + if t < 20 then k0to19 + elif t < 40 then k20to39 + elif t < 60 then k40to59 + else k60to79 + + type SHAStream = + { stream: byte[]; + mutable pos: int; + mutable eof: bool; } + + let rotLeft32 x n = (x <<< n) ||| (x >>>& (32-n)) + + // padding and length (in bits!) recorded at end + let shaAfterEof sha = + let n = sha.pos + let len = sha.stream.Length + if n = len then 0x80 + else + let paddedLen = (((len + 9 + 63) / 64) * 64) - 8 + if n < paddedLen - 8 then 0x0 + elif (n &&& 63) = 56 then int32 ((int64 len * int64 8) >>> 56) &&& 0xff + elif (n &&& 63) = 57 then int32 ((int64 len * int64 8) >>> 48) &&& 0xff + elif (n &&& 63) = 58 then int32 ((int64 len * int64 8) >>> 40) &&& 0xff + elif (n &&& 63) = 59 then int32 ((int64 len * int64 8) >>> 32) &&& 0xff + elif (n &&& 63) = 60 then int32 ((int64 len * int64 8) >>> 24) &&& 0xff + elif (n &&& 63) = 61 then int32 ((int64 len * int64 8) >>> 16) &&& 0xff + elif (n &&& 63) = 62 then int32 ((int64 len * int64 8) >>> 8) &&& 0xff + elif (n &&& 63) = 63 then (sha.eof <- true; int32 (int64 len * int64 8) &&& 0xff) + else 0x0 + + let shaRead8 sha = + let s = sha.stream + let b = if sha.pos >= s.Length then shaAfterEof sha else int32 s.[sha.pos] + sha.pos <- sha.pos + 1 + b + + let shaRead32 sha = + let b0 = shaRead8 sha + let b1 = shaRead8 sha + let b2 = shaRead8 sha + let b3 = shaRead8 sha + let res = (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3 + res + + let sha1Hash sha = + let mutable h0 = 0x67452301 + let mutable h1 = 0xEFCDAB89 + let mutable h2 = 0x98BADCFE + let mutable h3 = 0x10325476 + let mutable h4 = 0xC3D2E1F0 + let mutable a = 0 + let mutable b = 0 + let mutable c = 0 + let mutable d = 0 + let mutable e = 0 + let w = Array.create 80 0x00 + while (not sha.eof) do + for i = 0 to 15 do + w.[i] <- shaRead32 sha + for t = 16 to 79 do + w.[t] <- rotLeft32 (w.[t-3] ^^^ w.[t-8] ^^^ w.[t-14] ^^^ w.[t-16]) 1 + a <- h0 + b <- h1 + c <- h2 + d <- h3 + e <- h4 + for t = 0 to 79 do + let temp = (rotLeft32 a 5) + f(t,b,c,d) + e + w.[t] + k(t) + e <- d + d <- c + c <- rotLeft32 b 30 + b <- a + a <- temp + h0 <- h0 + a + h1 <- h1 + b + h2 <- h2 + c + h3 <- h3 + d + h4 <- h4 + e + h0,h1,h2,h3,h4 + + let sha1HashBytes s = + let (_h0,_h1,_h2,h3,h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 + Array.map byte [| b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |] + + + let sha1HashBytes s = SHA1.sha1HashBytes s + + + [] + type PublicKey = + | PublicKey of byte[] + | PublicKeyToken of byte[] + member x.IsKey=match x with PublicKey _ -> true | _ -> false + member x.IsKeyToken=match x with PublicKeyToken _ -> true | _ -> false + member x.Key=match x with PublicKey b -> b | _ -> failwithf "not a key" + member x.KeyToken=match x with PublicKeyToken b -> b | _ -> failwithf"not a key token" + + member x.ToToken() = + match x with + | PublicKey bytes -> SHA1.sha1HashBytes bytes + | PublicKeyToken token -> token + static member KeyAsToken(k) = PublicKeyToken(PublicKey(k).ToToken()) + + [] + type ILAssemblyRef(name: string, hash: byte[] uoption, publicKey: PublicKey uoption, retargetable: bool, version: Version uoption, locale: string uoption) = + member _.Name=name + member _.Hash=hash + member _.PublicKey=publicKey + member _.Retargetable=retargetable + member _.Version=version + member _.Locale=locale + + member x.ToAssemblyName() = + let asmName = AssemblyName(Name=x.Name) + match x.PublicKey with + | USome bytes -> asmName.SetPublicKeyToken(bytes.ToToken()) + | UNone -> () + match x.Version with + | USome v -> asmName.Version <- v + | UNone -> () + #if NETSTANDARD + asmName.CultureName <- System.Globalization.CultureInfo.InvariantCulture.Name + #else + asmName.CultureInfo <- System.Globalization.CultureInfo.InvariantCulture + #endif + asmName + + static member FromAssemblyName (aname:AssemblyName) = + let locale = UNone + let publicKey = + match aname.GetPublicKey() with + | null | [| |] -> + match aname.GetPublicKeyToken() with + | null | [| |] -> UNone + | bytes -> USome (PublicKeyToken bytes) + | bytes -> + USome (PublicKey.KeyAsToken(bytes)) + + let version = + match aname.Version with + | null -> UNone + | v -> USome (Version(v.Major,v.Minor,v.Build,v.Revision)) + + let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable + + ILAssemblyRef(aname.Name,UNone,publicKey,retargetable,version,locale) + + member aref.QualifiedName = + let b = new StringBuilder(100) + let add (s:string) = (b.Append(s) |> ignore) + let addC (s:char) = (b.Append(s) |> ignore) + add(aref.Name); + match aref.Version with + | UNone -> () + | USome v -> + add ", Version="; + add (string v.Major) + add "."; + add (string v.Minor) + add "."; + add (string v.Build) + add "."; + add (string v.Revision) + add ", Culture=" + match aref.Locale with + | UNone -> add "neutral" + | USome b -> add b + add ", PublicKeyToken=" + match aref.PublicKey with + | UNone -> add "null" + | USome pki -> + let pkt = pki.ToToken() + let convDigit(digit) = + let digitc = + if digit < 10 + then System.Convert.ToInt32 '0' + digit + else System.Convert.ToInt32 'a' + (digit - 10) + System.Convert.ToChar(digitc) + for i = 0 to pkt.Length-1 do + let v = pkt.[i] + addC (convDigit(System.Convert.ToInt32(v)/16)) + addC (convDigit(System.Convert.ToInt32(v)%16)) + // retargetable can be true only for system assemblies that definitely have Version + if aref.Retargetable then + add ", Retargetable=Yes" + b.ToString() + override x.ToString() = x.QualifiedName + + + type ILModuleRef(name:string, hasMetadata: bool, hash: byte[] uoption) = + member _.Name=name + member _.HasMetadata=hasMetadata + member _.Hash=hash + override _.ToString() = "module " + name + + + [] + type ILScopeRef = + | Local + | Module of ILModuleRef + | Assembly of ILAssemblyRef + member x.IsLocalRef = match x with ILScopeRef.Local -> true | _ -> false + member x.IsModuleRef = match x with ILScopeRef.Module _ -> true | _ -> false + member x.IsAssemblyRef= match x with ILScopeRef.Assembly _ -> true | _ -> false + member x.ModuleRef = match x with ILScopeRef.Module x -> x | _ -> failwith "not a module reference" + member x.AssemblyRef = match x with ILScopeRef.Assembly x -> x | _ -> failwith "not an assembly reference" + + member x.QualifiedName = + match x with + | ILScopeRef.Local -> "" + | ILScopeRef.Module mref -> "module "+mref.Name + | ILScopeRef.Assembly aref -> aref.QualifiedName + + override x.ToString() = x.QualifiedName + + type ILArrayBound = int32 option + type ILArrayBounds = ILArrayBound * ILArrayBound + + [] + type ILArrayShape = + | ILArrayShape of ILArrayBounds[] (* lobound/size pairs *) + member x.Rank = (let (ILArrayShape l) = x in l.Length) + static member SingleDimensional = ILArrayShapeStatics.SingleDimensional + static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (Some 0,None) |> List.toArray) + + + and ILArrayShapeStatics() = + static let singleDimensional = ILArrayShape [| (Some 0, None) |] + static member SingleDimensional = singleDimensional + + /// Calling conventions. These are used in method pointer types. + [] + type ILArgConvention = + | Default + | CDecl + | StdCall + | ThisCall + | FastCall + | VarArg + + [] + type ILThisConvention = + | Instance + | InstanceExplicit + | Static + + [] + type ILCallingConv = + | Callconv of ILThisConvention * ILArgConvention + member x.ThisConv = let (Callconv(a,_b)) = x in a + member x.BasicConv = let (Callconv(_a,b)) = x in b + member x.IsInstance = match x.ThisConv with ILThisConvention.Instance -> true | _ -> false + member x.IsInstanceExplicit = match x.ThisConv with ILThisConvention.InstanceExplicit -> true | _ -> false + member x.IsStatic = match x.ThisConv with ILThisConvention.Static -> true | _ -> false + + static member Instance = ILCallingConvStatics.Instance + static member Static = ILCallingConvStatics.Static + + /// Static storage to amortize the allocation of ILCallingConv.Instance and ILCallingConv.Static + and ILCallingConvStatics() = + static let instanceCallConv = Callconv(ILThisConvention.Instance,ILArgConvention.Default) + static let staticCallConv = Callconv(ILThisConvention.Static,ILArgConvention.Default) + static member Instance = instanceCallConv + static member Static = staticCallConv + + type ILBoxity = + | AsObject + | AsValue + + [] + type ILTypeRefScope = + | Top of ILScopeRef + | Nested of ILTypeRef + member x.QualifiedNameExtension = + match x with + | Top scoref -> + let sco = scoref.QualifiedName + if sco = "" then "" else ", " + sco + | Nested tref -> + tref.QualifiedNameExtension + + + // IL type references have a pre-computed hash code to enable quick lookup tables during binary generation. + and ILTypeRef(enc: ILTypeRefScope, nsp: string uoption, name: string) = + + member _.Scope = enc + member _.Name = name + member _.Namespace = nsp + + member tref.FullName = + match enc with + | ILTypeRefScope.Top _ -> joinILTypeName tref.Namespace tref.Name + | ILTypeRefScope.Nested enc -> enc.FullName + "." + tref.Name + + member tref.BasicQualifiedName = + match enc with + | ILTypeRefScope.Top _ -> joinILTypeName tref.Namespace tref.Name + | ILTypeRefScope.Nested enc -> enc.BasicQualifiedName + "+" + tref.Name + + member _.QualifiedNameExtension = enc.QualifiedNameExtension + + member tref.QualifiedName = tref.BasicQualifiedName + enc.QualifiedNameExtension + + override x.ToString() = x.FullName + + + and ILTypeSpec(typeRef: ILTypeRef, inst: ILGenericArgs) = + member _.TypeRef = typeRef + member x.Scope = x.TypeRef.Scope + member x.Name = x.TypeRef.Name + member x.Namespace = x.TypeRef.Namespace + member _.GenericArgs = inst + member x.BasicQualifiedName = + let tc = x.TypeRef.BasicQualifiedName + if x.GenericArgs.Length = 0 then + tc + else + tc + "[" + String.concat "," (x.GenericArgs |> Array.map (fun arg -> "[" + arg.QualifiedName + "]")) + "]" + + member x.QualifiedNameExtension = + x.TypeRef.QualifiedNameExtension + + member x.FullName = x.TypeRef.FullName + + override x.ToString() = x.TypeRef.ToString() + (if x.GenericArgs.Length = 0 then "" else "<...>") + + and [] + ILType = + | Void + | Array of ILArrayShape * ILType + | Value of ILTypeSpec + | Boxed of ILTypeSpec + | Ptr of ILType + | Byref of ILType + | FunctionPointer of ILCallingSignature + | Var of int + | Modified of bool * ILTypeRef * ILType + + member x.BasicQualifiedName = + match x with + | ILType.Var n -> "!" + string n + | ILType.Modified(_,_ty1,ty2) -> ty2.BasicQualifiedName + | ILType.Array (ILArrayShape(s),ty) -> ty.BasicQualifiedName + "[" + System.String(',',s.Length-1) + "]" + | ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName + | ILType.Void -> "void" + | ILType.Ptr _ty -> failwith "unexpected pointer type" + | ILType.Byref _ty -> failwith "unexpected byref type" + | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + + member x.QualifiedNameExtension = + match x with + | ILType.Var _n -> "" + | ILType.Modified(_,_ty1,ty2) -> ty2.QualifiedNameExtension + | ILType.Array (ILArrayShape(_s),ty) -> ty.QualifiedNameExtension + | ILType.Value tr | ILType.Boxed tr -> tr.QualifiedNameExtension + | ILType.Void -> failwith "void" + | ILType.Ptr _ty -> failwith "unexpected pointer type" + | ILType.Byref _ty -> failwith "unexpected byref type" + | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + + member x.QualifiedName = + x.BasicQualifiedName + x.QualifiedNameExtension + + member x.TypeSpec = + match x with + | ILType.Boxed tr | ILType.Value tr -> tr + | _ -> failwithf "not a nominal type" + + member x.Boxity = + match x with + | ILType.Boxed _ -> AsObject + | ILType.Value _ -> AsValue + | _ -> failwithf "not a nominal type" + + member x.TypeRef = + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef + | _ -> failwithf "not a nominal type" + + member x.IsNominal = + match x with + | ILType.Boxed _ | ILType.Value _ -> true + | _ -> false + + member x.GenericArgs = + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.GenericArgs + | _ -> [| |] + + member x.IsTyvar = + match x with + | ILType.Var _ -> true | _ -> false + + override x.ToString() = x.QualifiedName + + and ILCallingSignature(callingConv: ILCallingConv, argTypes: ILTypes, returnType: ILType) = + member _.CallingConv = callingConv + member _.ArgTypes = argTypes + member _.ReturnType = returnType + + and ILGenericArgs = ILType[] + and ILTypes = ILType[] + + + type ILMethodRef(parent: ILTypeRef, callconv: ILCallingConv, genericArity: int, name: string, args: ILTypes, ret: ILType) = + member _.EnclosingTypeRef = parent + member _.CallingConv = callconv + member _.Name = name + member _.GenericArity = genericArity + member _.ArgCount = args.Length + member _.ArgTypes = args + member _.ReturnType = ret + + member x.CallingSignature = ILCallingSignature (x.CallingConv,x.ArgTypes,x.ReturnType) + override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + "(...)" + + + type ILFieldRef(enclosingTypeRef: ILTypeRef, name: string, typ: ILType) = + member _.EnclosingTypeRef = enclosingTypeRef + member _.Name = name + member _.Type = typ + override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + + type ILMethodSpec(methodRef: ILMethodRef, enclosingType: ILType, methodInst: ILGenericArgs) = + member _.MethodRef = methodRef + member _.EnclosingType = enclosingType + member _.GenericArgs = methodInst + member x.Name = x.MethodRef.Name + member x.CallingConv = x.MethodRef.CallingConv + member x.GenericArity = x.MethodRef.GenericArity + member x.FormalArgTypes = x.MethodRef.ArgTypes + member x.FormalReturnType = x.MethodRef.ReturnType + override x.ToString() = x.MethodRef.ToString() + "(...)" + + type ILFieldSpec(fieldRef: ILFieldRef, enclosingType: ILType) = + member _.FieldRef = fieldRef + member _.EnclosingType = enclosingType + member _.FormalType = fieldRef.Type + member _.Name = fieldRef.Name + member _.EnclosingTypeRef = fieldRef.EnclosingTypeRef + override x.ToString() = x.FieldRef.ToString() + + type ILCodeLabel = int + + // -------------------------------------------------------------------- + // Instruction set. + // -------------------------------------------------------------------- + + type ILBasicType = + | DT_R + | DT_I1 + | DT_U1 + | DT_I2 + | DT_U2 + | DT_I4 + | DT_U4 + | DT_I8 + | DT_U8 + | DT_R4 + | DT_R8 + | DT_I + | DT_U + | DT_REF + + [] + type ILToken = + | ILType of ILType + | ILMethod of ILMethodSpec + | ILField of ILFieldSpec + + [] + type ILConst = + | I4 of int32 + | I8 of int64 + | R4 of single + | R8 of double + + type ILTailcall = + | Tailcall + | Normalcall + + type ILAlignment = + | Aligned + | Unaligned1 + | Unaligned2 + | Unaligned4 + + type ILVolatility = + | Volatile + | Nonvolatile + + type ILReadonly = + | ReadonlyAddress + | NormalAddress + + type ILVarArgs = ILTypes option + + [] + type ILComparisonInstr = + | I_beq + | I_bge + | I_bge_un + | I_bgt + | I_bgt_un + | I_ble + | I_ble_un + | I_blt + | I_blt_un + | I_bne_un + | I_brfalse + | I_brtrue + + +#if DEBUG_INFO + type ILSourceMarker = + { sourceDocument: ILSourceDocument; + sourceLine: int; + sourceColumn: int; + sourceEndLine: int; + sourceEndColumn: int } + static member Create(document, line, column, endLine, endColumn) = + { sourceDocument=document; + sourceLine=line; + sourceColumn=column; + sourceEndLine=endLine; + sourceEndColumn=endColumn } + member x.Document=x.sourceDocument + member x.Line=x.sourceLine + member x.Column=x.sourceColumn + member x.EndLine=x.sourceEndLine + member x.EndColumn=x.sourceEndColumn + override x.ToString() = sprintf "(%d,%d)-(%d,%d)" x.Line x.Column x.EndLine x.EndColumn +#endif + + [] + type ILInstr = + | I_add + | I_add_ovf + | I_add_ovf_un + | I_and + | I_div + | I_div_un + | I_ceq + | I_cgt + | I_cgt_un + | I_clt + | I_clt_un + | I_conv of ILBasicType + | I_conv_ovf of ILBasicType + | I_conv_ovf_un of ILBasicType + | I_mul + | I_mul_ovf + | I_mul_ovf_un + | I_rem + | I_rem_un + | I_shl + | I_shr + | I_shr_un + | I_sub + | I_sub_ovf + | I_sub_ovf_un + | I_xor + | I_or + | I_neg + | I_not + | I_ldnull + | I_dup + | I_pop + | I_ckfinite + | I_nop + | I_ldc of ILBasicType * ILConst + | I_ldarg of int + | I_ldarga of int + | I_ldind of ILAlignment * ILVolatility * ILBasicType + | I_ldloc of int + | I_ldloca of int + | I_starg of int + | I_stind of ILAlignment * ILVolatility * ILBasicType + | I_stloc of int + + | I_br of ILCodeLabel + | I_jmp of ILMethodSpec + | I_brcmp of ILComparisonInstr * ILCodeLabel + | I_switch of ILCodeLabel list + | I_ret + + | I_call of ILTailcall * ILMethodSpec * ILVarArgs + | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs + | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs + | I_calli of ILTailcall * ILCallingSignature * ILVarArgs + | I_ldftn of ILMethodSpec + | I_newobj of ILMethodSpec * ILVarArgs + + | I_throw + | I_endfinally + | I_endfilter + | I_leave of ILCodeLabel + | I_rethrow + + | I_ldsfld of ILVolatility * ILFieldSpec + | I_ldfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldsflda of ILFieldSpec + | I_ldflda of ILFieldSpec + | I_stsfld of ILVolatility * ILFieldSpec + | I_stfld of ILAlignment * ILVolatility * ILFieldSpec + | I_ldstr of string + | I_isinst of ILType + | I_castclass of ILType + | I_ldtoken of ILToken + | I_ldvirtftn of ILMethodSpec + + | I_cpobj of ILType + | I_initobj of ILType + | I_ldobj of ILAlignment * ILVolatility * ILType + | I_stobj of ILAlignment * ILVolatility * ILType + | I_box of ILType + | I_unbox of ILType + | I_unbox_any of ILType + | I_sizeof of ILType + + | I_ldelem of ILBasicType + | I_stelem of ILBasicType + | I_ldelema of ILReadonly * ILArrayShape * ILType + | I_ldelem_any of ILArrayShape * ILType + | I_stelem_any of ILArrayShape * ILType + | I_newarr of ILArrayShape * ILType + | I_ldlen + + | I_mkrefany of ILType + | I_refanytype + | I_refanyval of ILType + + | I_break +#if EMIT_DEBUG_INFO + | I_seqpoint of ILSourceMarker +#endif + | I_arglist + + | I_localloc + | I_cpblk of ILAlignment * ILVolatility + | I_initblk of ILAlignment * ILVolatility + + (* FOR EXTENSIONS, e.g. MS-ILX *) + | EI_ilzero of ILType + | EI_ldlen_multi of int32 * int32 + + + [] + type ILExceptionClause = + | Finally of (ILCodeLabel * ILCodeLabel) + | Fault of (ILCodeLabel * ILCodeLabel) + | FilterCatch of (ILCodeLabel * ILCodeLabel) * (ILCodeLabel * ILCodeLabel) + | TypeCatch of ILType * (ILCodeLabel * ILCodeLabel) + + [] + type ILExceptionSpec = + { Range: (ILCodeLabel * ILCodeLabel); + Clause: ILExceptionClause } + + /// Indicates that a particular local variable has a particular source + /// language name within a given set of ranges. This does not effect local + /// variable numbering, which is global over the whole method. + [] + type ILLocalDebugMapping = + { LocalIndex: int; + LocalName: string; } + + [] + type ILLocalDebugInfo = + { Range: (ILCodeLabel * ILCodeLabel); + DebugMappings: ILLocalDebugMapping[] } + + [] + type ILCode = + { Labels: Dictionary + Instrs:ILInstr[] + Exceptions: ILExceptionSpec[] + Locals: ILLocalDebugInfo[] } + + [] + type ILLocal = + { Type: ILType; + IsPinned: bool; + DebugInfo: (string * int * int) option } - type Microsoft.FSharp.Quotations.Expr with + type ILLocals = ILLocal[] + + [] + type ILMethodBody = + { IsZeroInit: bool + MaxStack: int32 + Locals: ILLocals + Code: ILCode +#if EMIT_DEBUG_INFO + SourceMarker: ILSourceMarker option +#endif + } + + type ILPlatform = + | X86 + | AMD64 + | IA64 + + type ILCustomAttrNamedArg = ILCustomAttrNamedArg of (string * ILType * obj) + + type ILCustomAttribute = + { Method: ILMethodSpec + Data: byte[] + Elements: obj list} + + type ILCustomAttrs = + abstract Entries: ILCustomAttribute[] + + type ILCustomAttrsStatics() = + static let empty = { new ILCustomAttrs with member _.Entries = [| |] } + static member Empty = empty + + [] + type ILMemberAccess = + | Assembly + | CompilerControlled + | FamilyAndAssembly + | FamilyOrAssembly + | Family + | Private + | Public + static member OfFlags (flags: int) = + let f = (flags &&& 0x00000007) + if f = 0x00000001 then ILMemberAccess.Private + elif f = 0x00000006 then ILMemberAccess.Public + elif f = 0x00000004 then ILMemberAccess.Family + elif f = 0x00000002 then ILMemberAccess.FamilyAndAssembly + elif f = 0x00000005 then ILMemberAccess.FamilyOrAssembly + elif f = 0x00000003 then ILMemberAccess.Assembly + else ILMemberAccess.CompilerControlled + + [] + type ILFieldInit = obj + + type ILParameter = + { Name: string uoption + ParameterType: ILType + Default: ILFieldInit uoption + //Marshal: ILNativeType option + Attributes: ParameterAttributes + CustomAttrs: ILCustomAttrs } + member x.IsIn = ((x.Attributes &&& ParameterAttributes.In) <> enum 0) + member x.IsOut = ((x.Attributes &&& ParameterAttributes.Out) <> enum 0) + member x.IsOptional = ((x.Attributes &&& ParameterAttributes.Optional) <> enum 0) + + type ILParameters = ILParameter[] + + type ILReturn = + { //Marshal: ILNativeType option; + Type: ILType; + CustomAttrs: ILCustomAttrs } + + type ILOverridesSpec = + | OverridesSpec of ILMethodRef * ILType + member x.MethodRef = let (OverridesSpec(mr,_ty)) = x in mr + member x.EnclosingType = let (OverridesSpec(_mr,ty)) = x in ty + + [] + type ILGenericVariance = + | NonVariant + | CoVariant + | ContraVariant + + type ILGenericParameterDef = + { Name: string + Constraints: ILTypes + Attributes: GenericParameterAttributes + CustomAttrs: ILCustomAttrs + Token: int } + + member x.HasReferenceTypeConstraint= (x.Attributes &&& GenericParameterAttributes.ReferenceTypeConstraint) <> enum 0 + member x.HasNotNullableValueTypeConstraint= (x.Attributes &&& GenericParameterAttributes.NotNullableValueTypeConstraint) <> enum 0 + member x.HasDefaultConstructorConstraint= (x.Attributes &&& GenericParameterAttributes.DefaultConstructorConstraint) <> enum 0 + member x.IsCovariant = (x.Attributes &&& GenericParameterAttributes.Covariant) <> enum 0 + member x.IsContravariant = (x.Attributes &&& GenericParameterAttributes.Contravariant) <> enum 0 + override x.ToString() = x.Name + + type ILGenericParameterDefs = ILGenericParameterDef[] + + [] + type ILMethodDef = + { Token: int32 + Name: string + CallingConv: ILCallingConv + Parameters: ILParameters + Return: ILReturn + Body: ILMethodBody option + ImplAttributes: MethodImplAttributes + //SecurityDecls: ILPermissions + //HasSecurity: bool + IsEntryPoint:bool + Attributes: MethodAttributes + GenericParams: ILGenericParameterDefs + CustomAttrs: ILCustomAttrs } + member x.ParameterTypes = x.Parameters |> Array.map (fun p -> p.ParameterType) + static member ComputeIsStatic attrs = attrs &&& MethodAttributes.Static <> enum 0 + member x.IsStatic = ILMethodDef.ComputeIsStatic x.Attributes + member x.IsAbstract = x.Attributes &&& MethodAttributes.Abstract <> enum 0 + member x.IsVirtual = x.Attributes &&& MethodAttributes.Virtual <> enum 0 + member x.IsCheckAccessOnOverride = x.Attributes &&& MethodAttributes.CheckAccessOnOverride <> enum 0 + member x.IsNewSlot = x.Attributes &&& MethodAttributes.NewSlot <> enum 0 + member x.IsFinal = x.Attributes &&& MethodAttributes.Final <> enum 0 + member x.IsSpecialName = x.Attributes &&& MethodAttributes.SpecialName <> enum 0 + member x.IsRTSpecialName = x.Attributes &&& MethodAttributes.RTSpecialName <> enum 0 + member x.IsHideBySig = x.Attributes &&& MethodAttributes.HideBySig <> enum 0 + member x.IsClassInitializer = x.Name = ".cctor" + member x.IsConstructor = x.Name = ".ctor" + member x.IsInternalCall = (int x.ImplAttributes &&& 0x1000 <> 0) + member x.IsManaged = (int x.ImplAttributes &&& 0x0004 = 0) + member x.IsForwardRef = (int x.ImplAttributes &&& 0x0010 <> 0) + member x.IsPreserveSig = (int x.ImplAttributes &&& 0x0080 <> 0) + member x.IsMustRun = (int x.ImplAttributes &&& 0x0040 <> 0) + member x.IsSynchronized = (int x.ImplAttributes &&& 0x0020 <> 0) + member x.IsNoInline = (int x.ImplAttributes &&& 0x0008 <> 0) + member x.Access = ILMemberAccess.OfFlags (int x.Attributes) + + member md.CallingSignature = ILCallingSignature (md.CallingConv,md.ParameterTypes,md.Return.Type) + override x.ToString() = "method " + x.Name + + type ILMethodDefs(larr: Lazy) = + + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for y in larr.Force() do + let key = y.Name + if lmap.ContainsKey key then + lmap.[key] <- Array.append [| y |] lmap.[key] + else + lmap.[key] <- [| y |] + lmap + + member _.Entries = larr.Force() + member _.FindByName nm = getmap().[nm] + member x.FindByNameAndArity (nm,arity) = x.FindByName nm |> Array.filter (fun x -> x.Parameters.Length = arity) + member x.TryFindUniqueByName name = + match x.FindByName(name) with + | [| md |] -> Some md + | [| |] -> None + | _ -> failwithf "multiple methods exist with name %s" name + + [] + type ILEventDef = + { //EventHandlerType: ILType option + Name: string + Attributes: System.Reflection.EventAttributes + AddMethod: ILMethodRef + RemoveMethod: ILMethodRef + //FireMethod: ILMethodRef option + //OtherMethods: ILMethodRef[] + CustomAttrs: ILCustomAttrs + Token: int } + member x.EventHandlerType = x.AddMethod.ArgTypes.[0] + member x.IsStatic = x.AddMethod.CallingConv.IsStatic + member x.IsSpecialName = (x.Attributes &&& EventAttributes.SpecialName) <> enum<_>(0) + member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0) + override x.ToString() = "event " + x.Name + + type ILEventDefs = + abstract Entries: ILEventDef[] + + [] + type ILPropertyDef = + { Name: string + Attributes: System.Reflection.PropertyAttributes + SetMethod: ILMethodRef option + GetMethod: ILMethodRef option + CallingConv: ILThisConvention + PropertyType: ILType + Init: ILFieldInit option + IndexParameterTypes: ILTypes + CustomAttrs: ILCustomAttrs + Token: int } + member x.IsStatic = (match x.CallingConv with ILThisConvention.Static -> true | _ -> false) + member x.IndexParameters = + x.IndexParameterTypes |> Array.mapi (fun i ty -> + { Name = USome("arg"+string i) + ParameterType = ty + Default = UNone + Attributes = ParameterAttributes.None + CustomAttrs = ILCustomAttrsStatics.Empty }) + member x.IsSpecialName = x.Attributes &&& PropertyAttributes.SpecialName <> enum 0 + member x.IsRTSpecialName = x.Attributes &&& PropertyAttributes.RTSpecialName <> enum 0 + override x.ToString() = "property " + x.Name + + type ILPropertyDefs = + abstract Entries: ILPropertyDef[] + + [] + type ILFieldDef = + { Name: string + FieldType: ILType + Attributes: FieldAttributes + //Data: byte[] option + LiteralValue: ILFieldInit option + Offset: int32 option + //Marshal: ILNativeType option + CustomAttrs: ILCustomAttrs + Token: int } + member x.IsStatic = x.Attributes &&& FieldAttributes.Static <> enum 0 + member x.IsInitOnly = x.Attributes &&& FieldAttributes.InitOnly <> enum 0 + member x.IsLiteral = x.Attributes &&& FieldAttributes.Literal <> enum 0 + member x.NotSerialized = x.Attributes &&& FieldAttributes.NotSerialized <> enum 0 + member x.IsSpecialName = x.Attributes &&& FieldAttributes.SpecialName <> enum 0 + //let isStatic = (flags &&& 0x0010) <> 0 + //{ Name = nm + // FieldType = readBlobHeapAsFieldSig numtypars typeIdx + // IsInitOnly = (flags &&& 0x0020) <> 0 + // IsLiteral = (flags &&& 0x0040) <> 0 + // NotSerialized = (flags &&& 0x0080) <> 0 + // IsSpecialName = (flags &&& 0x0200) <> 0 || (flags &&& 0x0400) <> 0 (* REVIEW: RTSpecialName *) + member x.Access = ILMemberAccess.OfFlags (int x.Attributes) + override x.ToString() = "field " + x.Name + + + type ILFieldDefs = + abstract Entries: ILFieldDef[] + + type ILMethodImplDef = + { Overrides: ILOverridesSpec + OverrideBy: ILMethodSpec } + + // Index table by name and arity. + type ILMethodImplDefs = + abstract Entries: ILMethodImplDef[] + + [] + type ILTypeInit = + | BeforeField + | OnAny + + [] + type ILDefaultPInvokeEncoding = + | Ansi + | Auto + | Unicode + + [] + type ILTypeDefLayout = + | Auto + | Sequential of ILTypeDefLayoutInfo + | Explicit of ILTypeDefLayoutInfo + + and ILTypeDefLayoutInfo = + { Size: int32 option + Pack: uint16 option } + + type ILTypeDefAccess = + | Public + | Private + | Nested of ILMemberAccess + static member OfFlags flags = + let f = (flags &&& 0x00000007) + if f = 0x00000001 then ILTypeDefAccess.Public + elif f = 0x00000002 then ILTypeDefAccess.Nested ILMemberAccess.Public + elif f = 0x00000003 then ILTypeDefAccess.Nested ILMemberAccess.Private + elif f = 0x00000004 then ILTypeDefAccess.Nested ILMemberAccess.Family + elif f = 0x00000006 then ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly + elif f = 0x00000007 then ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly + elif f = 0x00000005 then ILTypeDefAccess.Nested ILMemberAccess.Assembly + else ILTypeDefAccess.Private + + [] + type ILTypeDefKind = + | Class + | ValueType + | Interface + | Enum + | Delegate + + [] + type ILTypeDef = + { Namespace: string uoption + Name: string + GenericParams: ILGenericParameterDefs + Attributes: TypeAttributes + NestedTypes: ILTypeDefs + Layout: ILTypeDefLayout + Implements: ILTypes + Extends: ILType option + Methods: ILMethodDefs + Fields: ILFieldDefs + MethodImpls: ILMethodImplDefs + Events: ILEventDefs + Properties: ILPropertyDefs + CustomAttrs: ILCustomAttrs + Token: int } + static member ComputeKind flags (super: ILType option) (nsp: string uoption) (nm: string) = + if (flags &&& 0x00000020) <> 0x0 then ILTypeDefKind.Interface else + let isEnum = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "Enum") + let isDelegate = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "Delegate") + let isMulticastDelegate = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "MulticastDelegate") + let selfIsMulticastDelegate = (nsp = USome "System" && nm = "MulticastDelegate") + let isValueType = (match super with None -> false | Some ty -> ty.TypeSpec.Namespace = USome "System" && ty.TypeSpec.Name = "ValueType" && not (nsp = USome "System" && nm = "Enum")) + if isEnum then ILTypeDefKind.Enum + elif (isDelegate && not selfIsMulticastDelegate) || isMulticastDelegate then ILTypeDefKind.Delegate + elif isValueType then ILTypeDefKind.ValueType + else ILTypeDefKind.Class + + member x.Kind = ILTypeDef.ComputeKind (int x.Attributes) x.Extends x.Namespace x.Name + member x.IsClass = (match x.Kind with ILTypeDefKind.Class -> true | _ -> false) + member x.IsInterface = (match x.Kind with ILTypeDefKind.Interface -> true | _ -> false) + member x.IsEnum = (match x.Kind with ILTypeDefKind.Enum -> true | _ -> false) + member x.IsDelegate = (match x.Kind with ILTypeDefKind.Delegate -> true | _ -> false) + member x.IsAbstract= (x.Attributes &&& TypeAttributes.Abstract) <> enum 0 + member x.IsSealed= (x.Attributes &&& TypeAttributes.Sealed) <> enum 0 + member x.IsSerializable= (x.Attributes &&& TypeAttributes.Serializable) <> enum 0 + member x.IsComInterop= (x.Attributes &&& TypeAttributes.Import) <> enum 0 + member x.IsSpecialName= (x.Attributes &&& TypeAttributes.SpecialName) <> enum 0 + member x.Access = ILTypeDefAccess.OfFlags (int x.Attributes) + + member x.IsNested = + match x.Access with + | ILTypeDefAccess.Nested _ -> true + | _ -> false - static member NewDelegateUnchecked (ty: Type, vs: Var list, body: Expr) = - let e = List.foldBack (fun v acc -> Expr.Lambda(v,acc)) vs body - let op = newDelegateOp.Invoke(null, [| box ty |]) - mkFE1.Invoke(null, [| box op; box e |]) :?> Expr + member tdef.IsStructOrEnum = + match tdef.Kind with + | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> true + | _ -> false - static member NewObjectUnchecked (cinfo: ConstructorInfo, args : Expr list) = - let op = newObjectOp.Invoke(null, [| box cinfo |]) - mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + member x.Encoding = + let f = (int x.Attributes &&& 0x00030000) + if f = 0x00020000 then ILDefaultPInvokeEncoding.Auto + elif f = 0x00010000 then ILDefaultPInvokeEncoding.Unicode + else ILDefaultPInvokeEncoding.Ansi + + member x.InitSemantics = + if x.Kind = ILTypeDefKind.Interface then ILTypeInit.OnAny + elif (int x.Attributes &&& 0x00100000) <> 0x0 then ILTypeInit.BeforeField + else ILTypeInit.OnAny + + override x.ToString() = "type " + x.Name + + and ILTypeDefs(larr: Lazy<(string uoption * string * Lazy)[]>) = + + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for (nsp, nm, ltd) in larr.Force() do + let key = nsp, nm + lmap.[key] <- ltd + lmap + + member _.Entries = + [| for (_,_,td) in larr.Force() -> td.Force() |] + + member _.TryFindByName (nsp,nm) = + let tdefs = getmap() + let key = (nsp,nm) + if tdefs.ContainsKey key then + Some (tdefs.[key].Force()) + else + None - static member NewArrayUnchecked (elementType: Type, elements : Expr list) = - let op = newArrayOp.Invoke(null, [| box elementType |]) - mkFEN.Invoke(null, [| box op; box elements |]) :?> Expr + type ILNestedExportedType = + { Name: string + Access: ILMemberAccess + Nested: ILNestedExportedTypesAndForwarders + CustomAttrs: ILCustomAttrs } + override x.ToString() = "nested fwd " + x.Name + + and ILNestedExportedTypesAndForwarders(larr:Lazy) = + let lmap = lazy ((Map.empty, larr.Force()) ||> Array.fold (fun m x -> m.Add(x.Name,x))) + member _.Entries = larr.Force() + member _.TryFindByName nm = lmap.Force().TryFind nm + + and [] + ILExportedTypeOrForwarder = + { ScopeRef: ILScopeRef + Namespace: string uoption + Name: string + IsForwarder: bool + Access: ILTypeDefAccess; + Nested: ILNestedExportedTypesAndForwarders; + CustomAttrs: ILCustomAttrs } + override x.ToString() = "fwd " + x.Name + + and ILExportedTypesAndForwarders(larr:Lazy) = + let mutable lmap = null + let getmap() = + if lmap = null then + lmap <- Dictionary() + for ltd in larr.Force() do + let key = ltd.Namespace, ltd.Name + lmap.[key] <- ltd + lmap + member _.Entries = larr.Force() + member _.TryFindByName (nsp,nm) = match getmap().TryGetValue ((nsp,nm)) with true,v -> Some v | false, _ -> None + + [] + type ILResourceAccess = + | Public + | Private + + [] + type ILResourceLocation = + | Local of (unit -> byte[]) + | File of ILModuleRef * int32 + | Assembly of ILAssemblyRef + + type ILResource = + { Name: string + Location: ILResourceLocation + Access: ILResourceAccess + CustomAttrs: ILCustomAttrs } + override x.ToString() = "resource " + x.Name + + type ILResources(larr: Lazy) = + member _.Entries = larr.Force() + + type ILAssemblyManifest = + { Name: string + AuxModuleHashAlgorithm: int32 + PublicKey: byte[] uoption + Version: Version uoption + Locale: string uoption + CustomAttrs: ILCustomAttrs + //AssemblyLongevity: ILAssemblyLongevity + DisableJitOptimizations: bool + JitTracking: bool + IgnoreSymbolStoreSequencePoints: bool + Retargetable: bool + ExportedTypes: ILExportedTypesAndForwarders + EntrypointElsewhere: ILModuleRef option } + + member x.GetName() = + let asmName = AssemblyName(Name=x.Name) + match x.PublicKey with + | USome bytes -> asmName.SetPublicKey(bytes) + | UNone -> () + match x.Version with + | USome v -> asmName.Version <- v + | UNone -> () + #if NETSTANDARD + asmName.CultureName <- System.Globalization.CultureInfo.InvariantCulture.Name + #else + asmName.CultureInfo <- System.Globalization.CultureInfo.InvariantCulture + #endif + asmName + + override x.ToString() = "manifest " + x.Name + + type ILModuleDef = + { Manifest: ILAssemblyManifest option + CustomAttrs: ILCustomAttrs + Name: string + TypeDefs: ILTypeDefs + SubsystemVersion: int * int + UseHighEntropyVA: bool + (* Random bits of relatively uninteresting data *) + SubSystemFlags: int32 + IsDLL: bool + IsILOnly: bool + Platform: ILPlatform option + StackReserveSize: int32 option + Is32Bit: bool + Is32BitPreferred: bool + Is64Bit: bool + VirtualAlignment: int32 + PhysicalAlignment: int32 + ImageBase: int32 + MetadataVersion: string + Resources: ILResources } + + member x.ManifestOfAssembly = + match x.Manifest with + | Some m -> m + | None -> failwith "no manifest" + + member m.HasManifest = m.Manifest.IsSome + + override x.ToString() = "module " + x.Name + + + [] + type ILGlobals = + { typ_Object: ILType + typ_String: ILType + typ_Type: ILType + typ_TypedReference: ILType option + typ_SByte: ILType + typ_Int16: ILType + typ_Int32: ILType + typ_Array: ILType + typ_Int64: ILType + typ_Byte: ILType + typ_UInt16: ILType + typ_UInt32: ILType + typ_UInt64: ILType + typ_Single: ILType + typ_Double: ILType + typ_Boolean: ILType + typ_Char: ILType + typ_IntPtr: ILType + typ_UIntPtr: ILType + systemRuntimeScopeRef: ILScopeRef } + override _.ToString() = "" + + [] + + [] + type ILTableName(idx: int) = + member _.Index = idx + static member FromIndex n = ILTableName n + + module ILTableNames = + let Module = ILTableName 0 + let TypeRef = ILTableName 1 + let TypeDef = ILTableName 2 + let FieldPtr = ILTableName 3 + let Field = ILTableName 4 + let MethodPtr = ILTableName 5 + let Method = ILTableName 6 + let ParamPtr = ILTableName 7 + let Param = ILTableName 8 + let InterfaceImpl = ILTableName 9 + let MemberRef = ILTableName 10 + let Constant = ILTableName 11 + let CustomAttribute = ILTableName 12 + let FieldMarshal = ILTableName 13 + let Permission = ILTableName 14 + let ClassLayout = ILTableName 15 + let FieldLayout = ILTableName 16 + let StandAloneSig = ILTableName 17 + let EventMap = ILTableName 18 + let EventPtr = ILTableName 19 + let Event = ILTableName 20 + let PropertyMap = ILTableName 21 + let PropertyPtr = ILTableName 22 + let Property = ILTableName 23 + let MethodSemantics = ILTableName 24 + let MethodImpl = ILTableName 25 + let ModuleRef = ILTableName 26 + let TypeSpec = ILTableName 27 + let ImplMap = ILTableName 28 + let FieldRVA = ILTableName 29 + let ENCLog = ILTableName 30 + let ENCMap = ILTableName 31 + let Assembly = ILTableName 32 + let AssemblyProcessor = ILTableName 33 + let AssemblyOS = ILTableName 34 + let AssemblyRef = ILTableName 35 + let AssemblyRefProcessor = ILTableName 36 + let AssemblyRefOS = ILTableName 37 + let File = ILTableName 38 + let ExportedType = ILTableName 39 + let ManifestResource = ILTableName 40 + let Nested = ILTableName 41 + let GenericParam = ILTableName 42 + let MethodSpec = ILTableName 43 + let GenericParamConstraint = ILTableName 44 + let UserStrings = ILTableName 0x70 (* Special encoding of embedded UserString tokens - See 1.9 Partition III *) + + /// Which tables are sorted and by which column. + // + // Sorted bit-vector as stored by CLR V1: 00fa 0133 0002 0000 + // But what does this mean? The ECMA spec does not say! + // Metainfo -schema reports sorting as shown below. + // But some sorting, e.g. EventMap does not seem to show + let sortedTableInfo = + [ (InterfaceImpl,0) + (Constant, 1) + (CustomAttribute, 0) + (FieldMarshal, 0) + (Permission, 1) + (ClassLayout, 2) + (FieldLayout, 1) + (MethodSemantics, 2) + (MethodImpl, 0) + (ImplMap, 1) + (FieldRVA, 1) + (Nested, 0) + (GenericParam, 2) + (GenericParamConstraint, 0) ] + + [] + type TypeDefOrRefOrSpecTag(tag: int32) = + member _.Tag = tag + static member TypeDef = TypeDefOrRefOrSpecTag 0x00 + static member TypeRef = TypeDefOrRefOrSpecTag 0x01 + static member TypeSpec = TypeDefOrRefOrSpecTag 0x2 + + [] + type HasConstantTag(tag: int32) = + member _.Tag = tag + static member FieldDef = HasConstantTag 0x0 + static member ParamDef = HasConstantTag 0x1 + static member Property = HasConstantTag 0x2 + + [] + type HasCustomAttributeTag(tag: int32) = + member _.Tag = tag + static member MethodDef = HasCustomAttributeTag 0x0 + static member FieldDef = HasCustomAttributeTag 0x1 + static member TypeRef = HasCustomAttributeTag 0x2 + static member TypeDef = HasCustomAttributeTag 0x3 + static member ParamDef = HasCustomAttributeTag 0x4 + static member InterfaceImpl = HasCustomAttributeTag 0x5 + static member MemberRef = HasCustomAttributeTag 0x6 + static member Module = HasCustomAttributeTag 0x7 + static member Permission = HasCustomAttributeTag 0x8 + static member Property = HasCustomAttributeTag 0x9 + static member Event = HasCustomAttributeTag 0xa + static member StandAloneSig = HasCustomAttributeTag 0xb + static member ModuleRef = HasCustomAttributeTag 0xc + static member TypeSpec = HasCustomAttributeTag 0xd + static member Assembly = HasCustomAttributeTag 0xe + static member AssemblyRef = HasCustomAttributeTag 0xf + static member File = HasCustomAttributeTag 0x10 + static member ExportedType = HasCustomAttributeTag 0x11 + static member ManifestResource = HasCustomAttributeTag 0x12 + static member GenericParam = HasCustomAttributeTag 0x13 + static member GenericParamConstraint = HasCustomAttributeTag 0x14 + static member MethodSpec = HasCustomAttributeTag 0x15 + + [] + type HasFieldMarshalTag(tag: int32) = + member _.Tag = tag + static member FieldDef = HasFieldMarshalTag 0x00 + static member ParamDef = HasFieldMarshalTag 0x01 + + [] + type HasDeclSecurityTag(tag: int32) = + member _.Tag = tag + static member TypeDef = HasDeclSecurityTag 0x00 + static member MethodDef = HasDeclSecurityTag 0x01 + static member Assembly = HasDeclSecurityTag 0x02 + + [] + type MemberRefParentTag(tag: int32) = + member _.Tag = tag + static member TypeRef = MemberRefParentTag 0x01 + static member ModuleRef = MemberRefParentTag 0x02 + static member MethodDef = MemberRefParentTag 0x03 + static member TypeSpec = MemberRefParentTag 0x04 + + [] + type HasSemanticsTag(tag: int32) = + member _.Tag = tag + static member Event = HasSemanticsTag 0x00 + static member Property = HasSemanticsTag 0x01 + + [] + type MethodDefOrRefTag(tag: int32) = + member _.Tag = tag + static member MethodDef = MethodDefOrRefTag 0x00 + static member MemberRef = MethodDefOrRefTag 0x01 + static member MethodSpec = MethodDefOrRefTag 0x02 + + [] + type MemberForwardedTag(tag: int32) = + member _.Tag = tag + static member FieldDef = MemberForwardedTag 0x00 + static member MethodDef = MemberForwardedTag 0x01 + + [] + type ImplementationTag(tag: int32) = + member _.Tag = tag + static member File = ImplementationTag 0x00 + static member AssemblyRef = ImplementationTag 0x01 + static member ExportedType = ImplementationTag 0x02 + + [] + type CustomAttributeTypeTag(tag: int32) = + member _.Tag = tag + static member MethodDef = CustomAttributeTypeTag 0x02 + static member MemberRef = CustomAttributeTypeTag 0x03 + + [] + type ResolutionScopeTag(tag: int32) = + member _.Tag = tag + static member Module = ResolutionScopeTag 0x00 + static member ModuleRef = ResolutionScopeTag 0x01 + static member AssemblyRef = ResolutionScopeTag 0x02 + static member TypeRef = ResolutionScopeTag 0x03 + + [] + type TypeOrMethodDefTag(tag: int32) = + member _.Tag = tag + static member TypeDef = TypeOrMethodDefTag 0x00 + static member MethodDef = TypeOrMethodDefTag 0x01 + + [] + type TaggedIndex<'T> = + val tag: 'T + val index: int32 + new(tag,index) = { tag=tag; index=index } + + + type ILImageChunk = { size: int32; addr: int32 } + + type ILRowElementKind = + | UShort + | ULong + | Byte + | Data + | GGuid + | Blob + | SString + | SimpleIndex of ILTableName + | TypeDefOrRefOrSpec + | TypeOrMethodDef + | HasConstant + | HasCustomAttribute + | HasFieldMarshal + | HasDeclSecurity + | MemberRefParent + | HasSemantics + | MethodDefOrRef + | MemberForwarded + | Implementation + | CustomAttributeType + | ResolutionScope + + type ILRowKind = ILRowKind of ILRowElementKind list + + type TypeDefAsTypIdx = TypeDefAsTypIdx of ILBoxity * ILGenericArgs * int + type TypeRefAsTypIdx = TypeRefAsTypIdx of ILBoxity * ILGenericArgs * int + type BlobAsMethodSigIdx = BlobAsMethodSigIdx of int * int32 + type BlobAsFieldSigIdx = BlobAsFieldSigIdx of int * int32 + type BlobAsPropSigIdx = BlobAsPropSigIdx of int * int32 + type BlobAsLocalSigIdx = BlobAsLocalSigIdx of int * int32 + type MemberRefAsMspecIdx = MemberRefAsMspecIdx of int * int + type MethodSpecAsMspecIdx = MethodSpecAsMspecIdx of int * int + type MemberRefAsFspecIdx = MemberRefAsFspecIdx of int * int + type CustomAttrIdx = CustomAttrIdx of CustomAttributeTypeTag * int * int32 + type SecurityDeclIdx = SecurityDeclIdx of uint16 * int32 + type GenericParamsIdx = GenericParamsIdx of int * TypeOrMethodDefTag * int + + type MethodData = MethodData of ILType * ILCallingConv * string * ILTypes * ILType * ILTypes + type VarArgMethodData = VarArgMethodData of ILType * ILCallingConv * string * ILTypes * ILVarArgs * ILType * ILTypes + + [] + module Constants = + let et_END = 0x00uy + let et_VOID = 0x01uy + let et_BOOLEAN = 0x02uy + let et_CHAR = 0x03uy + let et_I1 = 0x04uy + let et_U1 = 0x05uy + let et_I2 = 0x06uy + let et_U2 = 0x07uy + let et_I4 = 0x08uy + let et_U4 = 0x09uy + let et_I8 = 0x0Auy + let et_U8 = 0x0Buy + let et_R4 = 0x0Cuy + let et_R8 = 0x0Duy + let et_STRING = 0x0Euy + let et_PTR = 0x0Fuy + let et_BYREF = 0x10uy + let et_VALUETYPE = 0x11uy + let et_CLASS = 0x12uy + let et_VAR = 0x13uy + let et_ARRAY = 0x14uy + let et_WITH = 0x15uy + let et_TYPEDBYREF = 0x16uy + let et_I = 0x18uy + let et_U = 0x19uy + let et_FNPTR = 0x1Buy + let et_OBJECT = 0x1Cuy + let et_SZARRAY = 0x1Duy + let et_MVAR = 0x1euy + let et_CMOD_REQD = 0x1Fuy + let et_CMOD_OPT = 0x20uy + + let et_SENTINEL = 0x41uy // sentinel for varargs + let et_PINNED = 0x45uy + + let e_IMAGE_CEE_CS_CALLCONV_FASTCALL = 0x04uy + let e_IMAGE_CEE_CS_CALLCONV_STDCALL = 0x02uy + let e_IMAGE_CEE_CS_CALLCONV_THISCALL = 0x03uy + let e_IMAGE_CEE_CS_CALLCONV_CDECL = 0x01uy + let e_IMAGE_CEE_CS_CALLCONV_VARARG = 0x05uy + let e_IMAGE_CEE_CS_CALLCONV_FIELD = 0x06uy + let e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x07uy + let e_IMAGE_CEE_CS_CALLCONV_PROPERTY = 0x08uy + + let e_IMAGE_CEE_CS_CALLCONV_GENERICINST = 0x0auy + let e_IMAGE_CEE_CS_CALLCONV_GENERIC = 0x10uy + let e_IMAGE_CEE_CS_CALLCONV_INSTANCE = 0x20uy + let e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT = 0x40uy + + + // Logical shift right treating int32 as unsigned integer. + // Code that uses this should probably be adjusted to use unsigned integer types. + let (>>>&) (x:int32) (n:int32) = int32 (uint32 x >>> n) + + let align alignment n = ((n + alignment - 0x1) / alignment) * alignment + + let uncodedToken (tab:ILTableName) idx = ((tab.Index <<< 24) ||| idx) + + let i32ToUncodedToken tok = + let idx = tok &&& 0xffffff + let tab = tok >>>& 24 + (ILTableName.FromIndex tab, idx) + + + let uncodedTokenToTypeDefOrRefOrSpec (tab,tok) = + let tag = + if tab = ILTableNames.TypeDef then TypeDefOrRefOrSpecTag.TypeDef + elif tab = ILTableNames.TypeRef then TypeDefOrRefOrSpecTag.TypeRef + elif tab = ILTableNames.TypeSpec then TypeDefOrRefOrSpecTag.TypeSpec + else failwith "bad table in uncodedTokenToTypeDefOrRefOrSpec" + TaggedIndex(tag,tok) + + let uncodedTokenToMethodDefOrRef (tab,tok) = + let tag = + if tab = ILTableNames.Method then MethodDefOrRefTag.MethodDef + elif tab = ILTableNames.MemberRef then MethodDefOrRefTag.MemberRef + else failwith "bad table in uncodedTokenToMethodDefOrRef" + TaggedIndex(tag,tok) + + let (|TaggedIndex|) (x:TaggedIndex<'T>) = x.tag, x.index + let tokToTaggedIdx f nbits tok = + let tagmask = + if nbits = 1 then 1 + elif nbits = 2 then 3 + elif nbits = 3 then 7 + elif nbits = 4 then 15 + elif nbits = 5 then 31 + else failwith "too many nbits" + let tag = tok &&& tagmask + let idx = tok >>>& nbits + TaggedIndex(f tag, idx) + + let i_nop = 0x00 + let i_break = 0x01 + let i_ldarg_0 = 0x02 + let i_ldarg_1 = 0x03 + let i_ldarg_2 = 0x04 + let i_ldarg_3 = 0x05 + let i_ldloc_0 = 0x06 + let i_ldloc_1 = 0x07 + let i_ldloc_2 = 0x08 + let i_ldloc_3 = 0x09 + let i_stloc_0 = 0x0a + let i_stloc_1 = 0x0b + let i_stloc_2 = 0x0c + let i_stloc_3 = 0x0d + let i_ldarg_s = 0x0e + let i_ldarga_s = 0x0f + let i_starg_s = 0x10 + let i_ldloc_s = 0x11 + let i_ldloca_s = 0x12 + let i_stloc_s = 0x13 + let i_ldnull = 0x14 + let i_ldc_i4_m1 = 0x15 + let i_ldc_i4_0 = 0x16 + let i_ldc_i4_1 = 0x17 + let i_ldc_i4_2 = 0x18 + let i_ldc_i4_3 = 0x19 + let i_ldc_i4_4 = 0x1a + let i_ldc_i4_5 = 0x1b + let i_ldc_i4_6 = 0x1c + let i_ldc_i4_7 = 0x1d + let i_ldc_i4_8 = 0x1e + let i_ldc_i4_s = 0x1f + let i_ldc_i4 = 0x20 + let i_ldc_i8 = 0x21 + let i_ldc_r4 = 0x22 + let i_ldc_r8 = 0x23 + let i_dup = 0x25 + let i_pop = 0x26 + let i_jmp = 0x27 + let i_call = 0x28 + let i_calli = 0x29 + let i_ret = 0x2a + let i_br_s = 0x2b + let i_brfalse_s = 0x2c + let i_brtrue_s = 0x2d + let i_beq_s = 0x2e + let i_bge_s = 0x2f + let i_bgt_s = 0x30 + let i_ble_s = 0x31 + let i_blt_s = 0x32 + let i_bne_un_s = 0x33 + let i_bge_un_s = 0x34 + let i_bgt_un_s = 0x35 + let i_ble_un_s = 0x36 + let i_blt_un_s = 0x37 + let i_br = 0x38 + let i_brfalse = 0x39 + let i_brtrue = 0x3a + let i_beq = 0x3b + let i_bge = 0x3c + let i_bgt = 0x3d + let i_ble = 0x3e + let i_blt = 0x3f + let i_bne_un = 0x40 + let i_bge_un = 0x41 + let i_bgt_un = 0x42 + let i_ble_un = 0x43 + let i_blt_un = 0x44 + let i_switch = 0x45 + let i_ldind_i1 = 0x46 + let i_ldind_u1 = 0x47 + let i_ldind_i2 = 0x48 + let i_ldind_u2 = 0x49 + let i_ldind_i4 = 0x4a + let i_ldind_u4 = 0x4b + let i_ldind_i8 = 0x4c + let i_ldind_i = 0x4d + let i_ldind_r4 = 0x4e + let i_ldind_r8 = 0x4f + let i_ldind_ref = 0x50 + let i_stind_ref = 0x51 + let i_stind_i1 = 0x52 + let i_stind_i2 = 0x53 + let i_stind_i4 = 0x54 + let i_stind_i8 = 0x55 + let i_stind_r4 = 0x56 + let i_stind_r8 = 0x57 + let i_add = 0x58 + let i_sub = 0x59 + let i_mul = 0x5a + let i_div = 0x5b + let i_div_un = 0x5c + let i_rem = 0x5d + let i_rem_un = 0x5e + let i_and = 0x5f + let i_or = 0x60 + let i_xor = 0x61 + let i_shl = 0x62 + let i_shr = 0x63 + let i_shr_un = 0x64 + let i_neg = 0x65 + let i_not = 0x66 + let i_conv_i1 = 0x67 + let i_conv_i2 = 0x68 + let i_conv_i4 = 0x69 + let i_conv_i8 = 0x6a + let i_conv_r4 = 0x6b + let i_conv_r8 = 0x6c + let i_conv_u4 = 0x6d + let i_conv_u8 = 0x6e + let i_callvirt = 0x6f + let i_cpobj = 0x70 + let i_ldobj = 0x71 + let i_ldstr = 0x72 + let i_newobj = 0x73 + let i_castclass = 0x74 + let i_isinst = 0x75 + let i_conv_r_un = 0x76 + let i_unbox = 0x79 + let i_throw = 0x7a + let i_ldfld = 0x7b + let i_ldflda = 0x7c + let i_stfld = 0x7d + let i_ldsfld = 0x7e + let i_ldsflda = 0x7f + let i_stsfld = 0x80 + let i_stobj = 0x81 + let i_conv_ovf_i1_un= 0x82 + let i_conv_ovf_i2_un= 0x83 + let i_conv_ovf_i4_un= 0x84 + let i_conv_ovf_i8_un= 0x85 + let i_conv_ovf_u1_un= 0x86 + let i_conv_ovf_u2_un= 0x87 + let i_conv_ovf_u4_un= 0x88 + let i_conv_ovf_u8_un= 0x89 + let i_conv_ovf_i_un = 0x8a + let i_conv_ovf_u_un = 0x8b + let i_box = 0x8c + let i_newarr = 0x8d + let i_ldlen = 0x8e + let i_ldelema = 0x8f + let i_ldelem_i1 = 0x90 + let i_ldelem_u1 = 0x91 + let i_ldelem_i2 = 0x92 + let i_ldelem_u2 = 0x93 + let i_ldelem_i4 = 0x94 + let i_ldelem_u4 = 0x95 + let i_ldelem_i8 = 0x96 + let i_ldelem_i = 0x97 + let i_ldelem_r4 = 0x98 + let i_ldelem_r8 = 0x99 + let i_ldelem_ref = 0x9a + let i_stelem_i = 0x9b + let i_stelem_i1 = 0x9c + let i_stelem_i2 = 0x9d + let i_stelem_i4 = 0x9e + let i_stelem_i8 = 0x9f + let i_stelem_r4 = 0xa0 + let i_stelem_r8 = 0xa1 + let i_stelem_ref = 0xa2 + let i_conv_ovf_i1 = 0xb3 + let i_conv_ovf_u1 = 0xb4 + let i_conv_ovf_i2 = 0xb5 + let i_conv_ovf_u2 = 0xb6 + let i_conv_ovf_i4 = 0xb7 + let i_conv_ovf_u4 = 0xb8 + let i_conv_ovf_i8 = 0xb9 + let i_conv_ovf_u8 = 0xba + let i_refanyval = 0xc2 + let i_ckfinite = 0xc3 + let i_mkrefany = 0xc6 + let i_ldtoken = 0xd0 + let i_conv_u2 = 0xd1 + let i_conv_u1 = 0xd2 + let i_conv_i = 0xd3 + let i_conv_ovf_i = 0xd4 + let i_conv_ovf_u = 0xd5 + let i_add_ovf = 0xd6 + let i_add_ovf_un = 0xd7 + let i_mul_ovf = 0xd8 + let i_mul_ovf_un = 0xd9 + let i_sub_ovf = 0xda + let i_sub_ovf_un = 0xdb + let i_endfinally = 0xdc + let i_leave = 0xdd + let i_leave_s = 0xde + let i_stind_i = 0xdf + let i_conv_u = 0xe0 + let i_arglist = 0xfe00 + let i_ceq = 0xfe01 + let i_cgt = 0xfe02 + let i_cgt_un = 0xfe03 + let i_clt = 0xfe04 + let i_clt_un = 0xfe05 + let i_ldftn = 0xfe06 + let i_ldvirtftn = 0xfe07 + let i_ldarg = 0xfe09 + let i_ldarga = 0xfe0a + let i_starg = 0xfe0b + let i_ldloc = 0xfe0c + let i_ldloca = 0xfe0d + let i_stloc = 0xfe0e + let i_localloc = 0xfe0f + let i_endfilter = 0xfe11 + let i_unaligned = 0xfe12 + let i_volatile = 0xfe13 + let i_constrained = 0xfe16 + let i_readonly = 0xfe1e + let i_tail = 0xfe14 + let i_initobj = 0xfe15 + let i_cpblk = 0xfe17 + let i_initblk = 0xfe18 + let i_rethrow = 0xfe1a + let i_sizeof = 0xfe1c + let i_refanytype = 0xfe1d + + let i_ldelem_any = 0xa3 + let i_stelem_any = 0xa4 + let i_unbox_any = 0xa5 + + let mk_ldc i = I_ldc (DT_I4,ILConst.I4 i) + let mk_ldc_i8 i = I_ldc (DT_I8,ILConst.I8 i) + let mkNormalCall mspec = I_call (Normalcall, mspec, None) + let mkILFormalGenericArgs numtypars (n:int) = + Array.init n (fun i -> ILType.Var (numtypars + i)) + + + let noArgInstrs = + lazy [ i_ldc_i4_0, mk_ldc 0 + i_ldc_i4_1, mk_ldc 1 + i_ldc_i4_2, mk_ldc 2 + i_ldc_i4_3, mk_ldc 3 + i_ldc_i4_4, mk_ldc 4 + i_ldc_i4_5, mk_ldc 5 + i_ldc_i4_6, mk_ldc 6 + i_ldc_i4_7, mk_ldc 7 + i_ldc_i4_8, mk_ldc 8 + i_ldc_i4_m1, mk_ldc -1 + 0x0a, I_stloc 0 + 0x0b, I_stloc 1 + 0x0c, I_stloc 2 + 0x0d, I_stloc 3 + 0x06, I_ldloc 0 + 0x07, I_ldloc 1 + 0x08, I_ldloc 2 + 0x09, I_ldloc 3 + 0x02, I_ldarg 0 + 0x03, I_ldarg 1 + 0x04, I_ldarg 2 + 0x05, I_ldarg 3 + 0x2a, I_ret + 0x58, I_add + 0xd6, I_add_ovf + 0xd7, I_add_ovf_un + 0x5f, I_and + 0x5b, I_div + 0x5c, I_div_un + 0xfe01, I_ceq + 0xfe02, I_cgt + 0xfe03, I_cgt_un + 0xfe04, I_clt + 0xfe05, I_clt_un + 0x67, I_conv DT_I1 + 0x68, I_conv DT_I2 + 0x69, I_conv DT_I4 + 0x6a, I_conv DT_I8 + 0xd3, I_conv DT_I + 0x6b, I_conv DT_R4 + 0x6c, I_conv DT_R8 + 0xd2, I_conv DT_U1 + 0xd1, I_conv DT_U2 + 0x6d, I_conv DT_U4 + 0x6e, I_conv DT_U8 + 0xe0, I_conv DT_U + 0x76, I_conv DT_R + 0xb3, I_conv_ovf DT_I1 + 0xb5, I_conv_ovf DT_I2 + 0xb7, I_conv_ovf DT_I4 + 0xb9, I_conv_ovf DT_I8 + 0xd4, I_conv_ovf DT_I + 0xb4, I_conv_ovf DT_U1 + 0xb6, I_conv_ovf DT_U2 + 0xb8, I_conv_ovf DT_U4 + 0xba, I_conv_ovf DT_U8 + 0xd5, I_conv_ovf DT_U + 0x82, I_conv_ovf_un DT_I1 + 0x83, I_conv_ovf_un DT_I2 + 0x84, I_conv_ovf_un DT_I4 + 0x85, I_conv_ovf_un DT_I8 + 0x8a, I_conv_ovf_un DT_I + 0x86, I_conv_ovf_un DT_U1 + 0x87, I_conv_ovf_un DT_U2 + 0x88, I_conv_ovf_un DT_U4 + 0x89, I_conv_ovf_un DT_U8 + 0x8b, I_conv_ovf_un DT_U + 0x9c, I_stelem DT_I1 + 0x9d, I_stelem DT_I2 + 0x9e, I_stelem DT_I4 + 0x9f, I_stelem DT_I8 + 0xa0, I_stelem DT_R4 + 0xa1, I_stelem DT_R8 + 0x9b, I_stelem DT_I + 0xa2, I_stelem DT_REF + 0x90, I_ldelem DT_I1 + 0x92, I_ldelem DT_I2 + 0x94, I_ldelem DT_I4 + 0x96, I_ldelem DT_I8 + 0x91, I_ldelem DT_U1 + 0x93, I_ldelem DT_U2 + 0x95, I_ldelem DT_U4 + 0x98, I_ldelem DT_R4 + 0x99, I_ldelem DT_R8 + 0x97, I_ldelem DT_I + 0x9a, I_ldelem DT_REF + 0x5a, I_mul + 0xd8, I_mul_ovf + 0xd9, I_mul_ovf_un + 0x5d, I_rem + 0x5e, I_rem_un + 0x62, I_shl + 0x63, I_shr + 0x64, I_shr_un + 0x59, I_sub + 0xda, I_sub_ovf + 0xdb, I_sub_ovf_un + 0x61, I_xor + 0x60, I_or + 0x65, I_neg + 0x66, I_not + i_ldnull, I_ldnull + i_dup, I_dup + i_pop, I_pop + i_ckfinite, I_ckfinite + i_nop, I_nop + i_break, I_break + i_arglist, I_arglist + i_endfilter, I_endfilter + i_endfinally, I_endfinally + i_refanytype, I_refanytype + i_localloc, I_localloc + i_throw, I_throw + i_ldlen, I_ldlen + i_rethrow, I_rethrow ] + + let isNoArgInstr i = + match i with + | I_ldc (DT_I4, ILConst.I4 n) when -1 <= n && n <= 8 -> true + | I_stloc n | I_ldloc n | I_ldarg n when n <= 3 -> true + | I_ret + | I_add + | I_add_ovf + | I_add_ovf_un + | I_and + | I_div + | I_div_un + | I_ceq + | I_cgt + | I_cgt_un + | I_clt + | I_clt_un + | I_conv DT_I1 + | I_conv DT_I2 + | I_conv DT_I4 + | I_conv DT_I8 + | I_conv DT_I + | I_conv DT_R4 + | I_conv DT_R8 + | I_conv DT_U1 + | I_conv DT_U2 + | I_conv DT_U4 + | I_conv DT_U8 + | I_conv DT_U + | I_conv DT_R + | I_conv_ovf DT_I1 + | I_conv_ovf DT_I2 + | I_conv_ovf DT_I4 + | I_conv_ovf DT_I8 + | I_conv_ovf DT_I + | I_conv_ovf DT_U1 + | I_conv_ovf DT_U2 + | I_conv_ovf DT_U4 + | I_conv_ovf DT_U8 + | I_conv_ovf DT_U + | I_conv_ovf_un DT_I1 + | I_conv_ovf_un DT_I2 + | I_conv_ovf_un DT_I4 + | I_conv_ovf_un DT_I8 + | I_conv_ovf_un DT_I + | I_conv_ovf_un DT_U1 + | I_conv_ovf_un DT_U2 + | I_conv_ovf_un DT_U4 + | I_conv_ovf_un DT_U8 + | I_conv_ovf_un DT_U + | I_stelem DT_I1 + | I_stelem DT_I2 + | I_stelem DT_I4 + | I_stelem DT_I8 + | I_stelem DT_R4 + | I_stelem DT_R8 + | I_stelem DT_I + | I_stelem DT_REF + | I_ldelem DT_I1 + | I_ldelem DT_I2 + | I_ldelem DT_I4 + | I_ldelem DT_I8 + | I_ldelem DT_U1 + | I_ldelem DT_U2 + | I_ldelem DT_U4 + | I_ldelem DT_R4 + | I_ldelem DT_R8 + | I_ldelem DT_I + | I_ldelem DT_REF + | I_mul + | I_mul_ovf + | I_mul_ovf_un + | I_rem + | I_rem_un + | I_shl + | I_shr + | I_shr_un + | I_sub + | I_sub_ovf + | I_sub_ovf_un + | I_xor + | I_or + | I_neg + | I_not + | I_ldnull + | I_dup + | I_pop + | I_ckfinite + | I_nop + | I_break + | I_arglist + | I_endfilter + | I_endfinally + | I_refanytype + | I_localloc + | I_throw + | I_ldlen + | I_rethrow -> true + | _ -> false + + let ILCmpInstrMap = + lazy ( + let dict = Dictionary 12 + dict.Add (I_beq , i_beq ) + dict.Add (I_bgt , i_bgt ) + dict.Add (I_bgt_un , i_bgt_un ) + dict.Add (I_bge , i_bge ) + dict.Add (I_bge_un , i_bge_un ) + dict.Add (I_ble , i_ble ) + dict.Add (I_ble_un , i_ble_un ) + dict.Add (I_blt , i_blt ) + dict.Add (I_blt_un , i_blt_un ) + dict.Add (I_bne_un , i_bne_un ) + dict.Add (I_brfalse , i_brfalse ) + dict.Add (I_brtrue , i_brtrue ) + dict + ) + + let ILCmpInstrRevMap = + lazy ( + let dict = Dictionary 12 + dict.Add ( I_beq , i_beq_s ) + dict.Add ( I_bgt , i_bgt_s ) + dict.Add ( I_bgt_un , i_bgt_un_s ) + dict.Add ( I_bge , i_bge_s ) + dict.Add ( I_bge_un , i_bge_un_s ) + dict.Add ( I_ble , i_ble_s ) + dict.Add ( I_ble_un , i_ble_un_s ) + dict.Add ( I_blt , i_blt_s ) + dict.Add ( I_blt_un , i_blt_un_s ) + dict.Add ( I_bne_un , i_bne_un_s ) + dict.Add ( I_brfalse , i_brfalse_s ) + dict.Add ( I_brtrue , i_brtrue_s ) + dict + ) + + // From corhdr.h + + let nt_VOID = 0x1uy + let nt_BOOLEAN = 0x2uy + let nt_I1 = 0x3uy + let nt_U1 = 0x4uy + let nt_I2 = 0x5uy + let nt_U2 = 0x6uy + let nt_I4 = 0x7uy + let nt_U4 = 0x8uy + let nt_I8 = 0x9uy + let nt_U8 = 0xAuy + let nt_R4 = 0xBuy + let nt_R8 = 0xCuy + let nt_SYSCHAR = 0xDuy + let nt_VARIANT = 0xEuy + let nt_CURRENCY = 0xFuy + let nt_PTR = 0x10uy + let nt_DECIMAL = 0x11uy + let nt_DATE = 0x12uy + let nt_BSTR = 0x13uy + let nt_LPSTR = 0x14uy + let nt_LPWSTR = 0x15uy + let nt_LPTSTR = 0x16uy + let nt_FIXEDSYSSTRING = 0x17uy + let nt_OBJECTREF = 0x18uy + let nt_IUNKNOWN = 0x19uy + let nt_IDISPATCH = 0x1Auy + let nt_STRUCT = 0x1Buy + let nt_INTF = 0x1Cuy + let nt_SAFEARRAY = 0x1Duy + let nt_FIXEDARRAY = 0x1Euy + let nt_INT = 0x1Fuy + let nt_UINT = 0x20uy + let nt_NESTEDSTRUCT = 0x21uy + let nt_BYVALSTR = 0x22uy + let nt_ANSIBSTR = 0x23uy + let nt_TBSTR = 0x24uy + let nt_VARIANTBOOL = 0x25uy + let nt_FUNC = 0x26uy + let nt_ASANY = 0x28uy + let nt_ARRAY = 0x2Auy + let nt_LPSTRUCT = 0x2Buy + let nt_CUSTOMMARSHALER = 0x2Cuy + let nt_ERROR = 0x2Duy + let nt_MAX = 0x50uy + + // From c:/clrenv.i386/Crt/Inc/i386/hs.h + + let vt_EMPTY = 0 + let vt_NULL = 1 + let vt_I2 = 2 + let vt_I4 = 3 + let vt_R4 = 4 + let vt_R8 = 5 + let vt_CY = 6 + let vt_DATE = 7 + let vt_BSTR = 8 + let vt_DISPATCH = 9 + let vt_ERROR = 10 + let vt_BOOL = 11 + let vt_VARIANT = 12 + let vt_UNKNOWN = 13 + let vt_DECIMAL = 14 + let vt_I1 = 16 + let vt_UI1 = 17 + let vt_UI2 = 18 + let vt_UI4 = 19 + let vt_I8 = 20 + let vt_UI8 = 21 + let vt_INT = 22 + let vt_UINT = 23 + let vt_VOID = 24 + let vt_HRESULT = 25 + let vt_PTR = 26 + let vt_SAFEARRAY = 27 + let vt_CARRAY = 28 + let vt_USERDEFINED = 29 + let vt_LPSTR = 30 + let vt_LPWSTR = 31 + let vt_RECORD = 36 + let vt_FILETIME = 64 + let vt_BLOB = 65 + let vt_STREAM = 66 + let vt_STORAGE = 67 + let vt_STREAMED_OBJECT = 68 + let vt_STORED_OBJECT = 69 + let vt_BLOB_OBJECT = 70 + let vt_CF = 71 + let vt_CLSID = 72 + let vt_VECTOR = 0x1000 + let vt_ARRAY = 0x2000 + let vt_BYREF = 0x4000 - static member CallUnchecked (minfo: MethodInfo, args : Expr list) = - let op = staticCallOp.Invoke(null, [| box minfo |]) - mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + - static member CallUnchecked (obj: Expr, minfo: MethodInfo, args : Expr list) = - let op = instanceCallOp.Invoke(null, [| box minfo |]) - mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + let e_CorILMethod_TinyFormat = 0x02uy + let e_CorILMethod_FatFormat = 0x03uy + let e_CorILMethod_FormatMask = 0x03uy + let e_CorILMethod_MoreSects = 0x08uy + let e_CorILMethod_InitLocals = 0x10uy - static member ApplicationUnchecked (f: Expr, x: Expr) = - let op = appOp.Invoke(null, [| |]) - mkFE2.Invoke(null, [| box op; box f; box x |]) :?> Expr - static member PropertyGetUnchecked (pinfo: PropertyInfo, args : Expr list) = - let op = staticPropGetOp.Invoke(null, [| box pinfo |]) - mkFEN.Invoke(null, [| box op; box args |]) :?> Expr + let e_CorILMethod_Sect_EHTable = 0x1uy + let e_CorILMethod_Sect_FatFormat = 0x40uy + let e_CorILMethod_Sect_MoreSects = 0x80uy - static member PropertyGetUnchecked (obj: Expr, pinfo: PropertyInfo, ?args : Expr list) = - let args = defaultArg args [] - let op = instancePropGetOp.Invoke(null, [| box pinfo |]) - mkFEN.Invoke(null, [| box op; box (obj::args) |]) :?> Expr + let e_COR_ILEXCEPTION_CLAUSE_EXCEPTION = 0x0 + let e_COR_ILEXCEPTION_CLAUSE_FILTER = 0x1 + let e_COR_ILEXCEPTION_CLAUSE_FINALLY = 0x2 + let e_COR_ILEXCEPTION_CLAUSE_FAULT = 0x4 - static member PropertySetUnchecked (pinfo: PropertyInfo, value: Expr, ?args : Expr list) = - let args = defaultArg args [] - let op = staticPropSetOp.Invoke(null, [| box pinfo |]) - mkFEN.Invoke(null, [| box op; box (args@[value]) |]) :?> Expr - static member PropertySetUnchecked (obj: Expr, pinfo: PropertyInfo, value: Expr, args : Expr list) = - let op = instancePropSetOp.Invoke(null, [| box pinfo |]) - mkFEN.Invoke(null, [| box op; box (obj::(args@[value])) |]) :?> Expr + module Bytes = - static member FieldGetUnchecked (pinfo: FieldInfo) = - let op = staticFieldGetOp.Invoke(null, [| box pinfo |]) - mkFE0.Invoke(null, [| box op; |]) :?> Expr + let dWw1 n = int32 ((n >>> 32) &&& 0xFFFFFFFFL) + let dWw0 n = int32 (n &&& 0xFFFFFFFFL) - static member FieldGetUnchecked (obj: Expr, pinfo: FieldInfo) = - let op = instanceFieldGetOp.Invoke(null, [| box pinfo |]) - mkFE1.Invoke(null, [| box op; box obj |]) :?> Expr + let get (b:byte[]) n = int32 (Array.get b n) + let zeroCreate n: byte[] = Array.zeroCreate n - static member FieldSetUnchecked (pinfo: FieldInfo, value: Expr) = - let op = staticFieldSetOp.Invoke(null, [| box pinfo |]) - mkFE1.Invoke(null, [| box op; box value |]) :?> Expr + let sub ( b:byte[]) s l = Array.sub b s l + let blit (a:byte[]) b c d e = Array.blit a b c d e - static member FieldSetUnchecked (obj: Expr, pinfo: FieldInfo, value: Expr) = - let op = instanceFieldSetOp.Invoke(null, [| box pinfo |]) - mkFE2.Invoke(null, [| box op; box obj; box value |]) :?> Expr + let ofInt32Array (arr:int[]) = Array.init arr.Length (fun i -> byte arr.[i]) - static member TupleGetUnchecked (e: Expr, n:int) = - let op = tupleGetOp.Invoke(null, [| box e.Type; box n |]) - mkFE1.Invoke(null, [| box op; box e |]) :?> Expr + let stringAsUtf8NullTerminated (s:string) = + Array.append (Encoding.UTF8.GetBytes s) (ofInt32Array [| 0x0 |]) - static member LetUnchecked (v:Var, e: Expr, body:Expr) = - let lam = Expr.Lambda(v,body) - let op = letOp.Invoke(null, [| |]) - mkFE2.Invoke(null, [| box op; box e; box lam |]) :?> Expr + let stringAsUnicodeNullTerminated (s:string) = + Array.append (Encoding.Unicode.GetBytes s) (ofInt32Array [| 0x0;0x0 |]) - type Shape = Shape of (Expr list -> Expr) + type ByteStream = + { bytes: byte[] + mutable pos: int + max: int } + member b.ReadByte() = + if b.pos >= b.max then failwith "end of stream" + let res = b.bytes.[b.pos] + b.pos <- b.pos + 1 + res + member b.ReadUtf8String n = + let res = Encoding.UTF8.GetString(b.bytes,b.pos,n) + b.pos <- b.pos + n; res + + static member FromBytes (b:byte[],n,len) = + if n < 0 || (n+len) > b.Length then failwith "FromBytes" + { bytes = b; pos = n; max = n+len } + + member b.ReadBytes n = + if b.pos + n > b.max then failwith "ReadBytes: end of stream" + let res = Bytes.sub b.bytes b.pos n + b.pos <- b.pos + n + res + + member b.Position = b.pos + + + type ByteBuffer = + { mutable bbArray: byte[] + mutable bbCurrent: int } + + member buf.Ensure newSize = + let oldBufSize = buf.bbArray.Length + if newSize > oldBufSize then + let old = buf.bbArray + buf.bbArray <- Bytes.zeroCreate (max newSize (oldBufSize * 2)) + Bytes.blit old 0 buf.bbArray 0 buf.bbCurrent + + member buf.Close () = Bytes.sub buf.bbArray 0 buf.bbCurrent + + member buf.EmitIntAsByte (i:int) = + let newSize = buf.bbCurrent + 1 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- byte i + buf.bbCurrent <- newSize + + member buf.EmitByte (b:byte) = buf.EmitIntAsByte (int b) + + member buf.EmitIntsAsBytes (arr:int[]) = + let n = arr.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + let bbarr = buf.bbArray + let bbbase = buf.bbCurrent + for i = 0 to n - 1 do + bbarr.[bbbase + i] <- byte arr.[i] + buf.bbCurrent <- newSize + + member bb.FixupInt32 pos n = + bb.bbArray.[pos] <- (b0 n |> byte) + bb.bbArray.[pos + 1] <- (b1 n |> byte) + bb.bbArray.[pos + 2] <- (b2 n |> byte) + bb.bbArray.[pos + 3] <- (b3 n |> byte) + + member buf.EmitInt32 n = + let newSize = buf.bbCurrent + 4 + buf.Ensure newSize + buf.FixupInt32 buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitBytes (i:byte[]) = + let n = i.Length + let newSize = buf.bbCurrent + n + buf.Ensure newSize + Bytes.blit i 0 buf.bbArray buf.bbCurrent n + buf.bbCurrent <- newSize + + member buf.EmitInt32AsUInt16 n = + let newSize = buf.bbCurrent + 2 + buf.Ensure newSize + buf.bbArray.[buf.bbCurrent] <- (b0 n |> byte) + buf.bbArray.[buf.bbCurrent + 1] <- (b1 n |> byte) + buf.bbCurrent <- newSize - let (|ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked|) e = - match e with - | NewObject (cinfo, args) -> - ShapeCombinationUnchecked (Shape (function args -> Expr.NewObjectUnchecked (cinfo, args)), args) - | NewArray (ty, args) -> - ShapeCombinationUnchecked (Shape (function args -> Expr.NewArrayUnchecked (ty, args)), args) - | NewDelegate (t, vars, expr) -> - ShapeCombinationUnchecked (Shape (function [expr] -> Expr.NewDelegateUnchecked (t, vars, expr) | _ -> invalidArg "expr" "invalid shape"), [expr]) - | TupleGet (expr, n) -> - ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, n) | _ -> invalidArg "expr" "invalid shape"), [expr]) - | Application (f, x) -> - ShapeCombinationUnchecked (Shape (function [f; x] -> Expr.ApplicationUnchecked (f, x) | _ -> invalidArg "expr" "invalid shape"), [f; x]) - | Call (objOpt, minfo, args) -> - match objOpt with - | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.CallUnchecked (minfo, args)), args) - | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.CallUnchecked (obj, minfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) - | PropertyGet (objOpt, pinfo, args) -> - match objOpt with - | None -> ShapeCombinationUnchecked (Shape (function args -> Expr.PropertyGetUnchecked (pinfo, args)), args) - | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::args) -> Expr.PropertyGetUnchecked (obj, pinfo, args) | _ -> invalidArg "expr" "invalid shape"), obj::args) - | PropertySet (objOpt, pinfo, args, value) -> - match objOpt with - | None -> ShapeCombinationUnchecked (Shape (function (value::args) -> Expr.PropertySetUnchecked (pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), value::args) - | Some obj -> ShapeCombinationUnchecked (Shape (function (obj::value::args) -> Expr.PropertySetUnchecked (obj, pinfo, value, args) | _ -> invalidArg "expr" "invalid shape"), obj::value::args) - | FieldGet (objOpt, pinfo) -> - match objOpt with - | None -> ShapeCombinationUnchecked (Shape (function _ -> Expr.FieldGetUnchecked (pinfo)), []) - | Some obj -> ShapeCombinationUnchecked (Shape (function [obj] -> Expr.FieldGetUnchecked (obj, pinfo) | _ -> invalidArg "expr" "invalid shape"), [obj]) - | FieldSet (objOpt, pinfo, value) -> - match objOpt with - | None -> ShapeCombinationUnchecked (Shape (function [value] -> Expr.FieldSetUnchecked (pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [value]) - | Some obj -> ShapeCombinationUnchecked (Shape (function [obj;value] -> Expr.FieldSetUnchecked (obj, pinfo, value) | _ -> invalidArg "expr" "invalid shape"), [obj; value]) - | Let (var, value, body) -> - ShapeCombinationUnchecked (Shape (function [value;Lambda(var, body)] -> Expr.LetUnchecked(var, value, body) | _ -> invalidArg "expr" "invalid shape"), [value; Expr.Lambda(var, body)]) - | TupleGet (expr, i) -> - ShapeCombinationUnchecked (Shape (function [expr] -> Expr.TupleGetUnchecked (expr, i) | _ -> invalidArg "expr" "invalid shape"), [expr]) - | ExprShape.ShapeCombination (comb,args) -> - ShapeCombinationUnchecked (Shape (fun args -> ExprShape.RebuildShapeCombination(comb, args)), args) - | ExprShape.ShapeVar v -> ShapeVarUnchecked v - | ExprShape.ShapeLambda (v, e) -> ShapeLambdaUnchecked (v,e) - - let RebuildShapeCombinationUnchecked (Shape comb,args) = comb args - -//-------------------------------------------------------------------------------- - -module QuotationSimplifier = - - let transExpr isGenerated q = - let rec trans q = - match q with - // convert NewTuple to the call to the constructor of the Tuple type (only for generated types) + member buf.EmitBoolAsByte (b:bool) = buf.EmitIntAsByte (if b then 1 else 0) + + member buf.EmitUInt16 (x:uint16) = buf.EmitInt32AsUInt16 (int32 x) + + member buf.EmitInt64 x = + buf.EmitInt32 (Bytes.dWw0 x) + buf.EmitInt32 (Bytes.dWw1 x) + + member buf.Position = buf.bbCurrent + + static member Create sz = + { bbArray=Bytes.zeroCreate sz + bbCurrent = 0 } + + /// Z32 = compressed unsigned integer + static member Z32Size n = + if n <= 0x7F then 1 + elif n <= 0x3FFF then 2 + else 4 + + /// Emit int32 as compressed unsigned integer + member buf.EmitZ32 n = + if n >= 0 && n <= 0x7F then + buf.EmitIntAsByte n + elif n >= 0x80 && n <= 0x3FFF then + buf.EmitIntAsByte (0x80 ||| (n >>> 8)) + buf.EmitIntAsByte (n &&& 0xFF) + else + buf.EmitIntAsByte (0xc0l ||| ((n >>> 24) &&& 0xFF)) + buf.EmitIntAsByte ( (n >>> 16) &&& 0xFF) + buf.EmitIntAsByte ( (n >>> 8) &&& 0xFF) + buf.EmitIntAsByte ( n &&& 0xFF) + + static member Z32 n = let bb = ByteBuffer.Create (ByteBuffer.Z32Size n) in bb.EmitZ32 n; bb.Close() + + member buf.EmitPadding n = + for i = 0 to n-1 do + buf.EmitByte 0x0uy + + // Emit compressed untagged integer + member buf.EmitZUntaggedIndex big idx = + if big then buf.EmitInt32 idx + elif idx > 0xffff then failwithf "EmitZUntaggedIndex: too big for small address or simple index, idx = %d, big = %A, stack = %s" idx big ((new System.Diagnostics.StackTrace()).ToString()) + else buf.EmitInt32AsUInt16 idx + + // Emit compressed tagged integer + member buf.EmitZTaggedIndex tag nbits big idx = + let idx2 = (idx <<< nbits) ||| tag + if big then buf.EmitInt32 idx2 + else buf.EmitInt32AsUInt16 idx2 + + //--------------------------------------------------------------------- + // Byte, byte array fragments and other concrete representations + // manipulations. + //--------------------------------------------------------------------- + + let bitsOfSingle (x:float32) = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x), 0) + let bitsOfDouble (x:float) = System.BitConverter.DoubleToInt64Bits(x) + + type ByteFile(bytes:byte[]) = + + member _.Bytes = bytes + member _.ReadByte addr = bytes.[addr] + member _.ReadBytes addr len = Array.sub bytes addr len + member _.CountUtf8String addr = + let mutable p = addr + while bytes.[p] <> 0uy do + p <- p + 1 + p - addr + + member m.ReadUTF8String addr = + let n = m.CountUtf8String addr + Encoding.UTF8.GetString (bytes, addr, n) + + member is.ReadInt32 addr = + let b0 = is.ReadByte addr + let b1 = is.ReadByte (addr+1) + let b2 = is.ReadByte (addr+2) + let b3 = is.ReadByte (addr+3) + int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) + + member is.ReadUInt16 addr = + let b0 = is.ReadByte addr + let b1 = is.ReadByte (addr+1) + uint16 b0 ||| (uint16 b1 <<< 8) + + [] + module Reader = + let seekReadByte (is:ByteFile) addr = is.ReadByte addr + let seekReadBytes (is:ByteFile) addr len = is.ReadBytes addr len + let seekReadInt32 (is:ByteFile) addr = is.ReadInt32 addr + let seekReadUInt16 (is:ByteFile) addr = is.ReadUInt16 addr + + let seekReadByteAsInt32 is addr = int32 (seekReadByte is addr) + + let seekReadInt64 is addr = + let b0 = seekReadByte is addr + let b1 = seekReadByte is (addr+1) + let b2 = seekReadByte is (addr+2) + let b3 = seekReadByte is (addr+3) + let b4 = seekReadByte is (addr+4) + let b5 = seekReadByte is (addr+5) + let b6 = seekReadByte is (addr+6) + let b7 = seekReadByte is (addr+7) + int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| + (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56) + + let seekReadUInt16AsInt32 is addr = int32 (seekReadUInt16 is addr) + + let seekReadCompressedUInt32 is addr = + let b0 = seekReadByte is addr + if b0 <= 0x7Fuy then int b0, addr+1 + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1 = seekReadByteAsInt32 is (addr+1) + (int b0 <<< 8) ||| int b1, addr+2 + else + let b0 = b0 &&& 0x3Fuy + let b1 = seekReadByteAsInt32 is (addr+1) + let b2 = seekReadByteAsInt32 is (addr+2) + let b3 = seekReadByteAsInt32 is (addr+3) + (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, addr+4 + + let seekReadSByte is addr = sbyte (seekReadByte is addr) + + let rec seekCountUtf8String is addr n = + let c = seekReadByteAsInt32 is addr + if c = 0 then n + else seekCountUtf8String is (addr+1) (n+1) + + let seekReadUTF8String is addr = + let n = seekCountUtf8String is addr 0 + let bytes = seekReadBytes is addr n + Encoding.UTF8.GetString (bytes, 0, bytes.Length) + + let seekReadBlob is addr = + let len, addr = seekReadCompressedUInt32 is addr + seekReadBytes is addr len + + let seekReadUserString is addr = + let len, addr = seekReadCompressedUInt32 is addr + let bytes = seekReadBytes is addr (len - 1) + Encoding.Unicode.GetString(bytes, 0, bytes.Length) + + let seekReadGuid is addr = seekReadBytes is addr 0x10 + + let seekReadUncodedToken is addr = + i32ToUncodedToken (seekReadInt32 is addr) + + let sigptrGetByte (bytes:byte[]) sigptr = + bytes.[sigptr], sigptr + 1 + + let sigptrGetBool bytes sigptr = + let b0,sigptr = sigptrGetByte bytes sigptr + (b0 = 0x01uy) ,sigptr + + let sigptrGetSByte bytes sigptr = + let i,sigptr = sigptrGetByte bytes sigptr + sbyte i,sigptr + + let sigptrGetUInt16 bytes sigptr = + let b0,sigptr = sigptrGetByte bytes sigptr + let b1,sigptr = sigptrGetByte bytes sigptr + uint16 (int b0 ||| (int b1 <<< 8)),sigptr + + let sigptrGetInt16 bytes sigptr = + let u,sigptr = sigptrGetUInt16 bytes sigptr + int16 u,sigptr + + let sigptrGetInt32 (bytes: byte[]) sigptr = + let b0 = bytes.[sigptr] + let b1 = bytes.[sigptr+1] + let b2 = bytes.[sigptr+2] + let b3 = bytes.[sigptr+3] + let res = int b0 ||| (int b1 <<< 8) ||| (int b2 <<< 16) ||| (int b3 <<< 24) + res, sigptr + 4 + + let sigptrGetUInt32 bytes sigptr = + let u,sigptr = sigptrGetInt32 bytes sigptr + uint32 u,sigptr + + let sigptrGetUInt64 bytes sigptr = + let u0,sigptr = sigptrGetUInt32 bytes sigptr + let u1,sigptr = sigptrGetUInt32 bytes sigptr + (uint64 u0 ||| (uint64 u1 <<< 32)),sigptr + + let sigptrGetInt64 bytes sigptr = + let u,sigptr = sigptrGetUInt64 bytes sigptr + int64 u,sigptr + + let sigptrGetSingle bytes sigptr = + let u,sigptr = sigptrGetInt32 bytes sigptr + singleOfBits u,sigptr + + let sigptrGetDouble bytes sigptr = + let u,sigptr = sigptrGetInt64 bytes sigptr + doubleOfBits u,sigptr + + let sigptrGetZInt32 bytes sigptr = + let b0,sigptr = sigptrGetByte bytes sigptr + if b0 <= 0x7Fuy then int b0, sigptr + elif b0 <= 0xBFuy then + let b0 = b0 &&& 0x7Fuy + let b1,sigptr = sigptrGetByte bytes sigptr + (int b0 <<< 8) ||| int b1, sigptr + else + let b0 = b0 &&& 0x3Fuy + let b1,sigptr = sigptrGetByte bytes sigptr + let b2,sigptr = sigptrGetByte bytes sigptr + let b3,sigptr = sigptrGetByte bytes sigptr + (int b0 <<< 24) ||| (int b1 <<< 16) ||| (int b2 <<< 8) ||| int b3, sigptr + + let rec sigptrFoldAcc f n (bytes:byte[]) (sigptr:int) i acc = + if i < n then + let x,sp = f bytes sigptr + sigptrFoldAcc f n bytes sp (i+1) (x::acc) + else + Array.ofList (List.rev acc), sigptr + + let sigptrFold f n (bytes:byte[]) (sigptr:int) = + sigptrFoldAcc f n bytes sigptr 0 [] + + let sigptrGetBytes n (bytes:byte[]) sigptr = + let res = Array.zeroCreate n + for i = 0 to (n - 1) do + res.[i] <- bytes.[sigptr + i] + res, sigptr + n + + let sigptrGetString n bytes sigptr = + let bytearray,sigptr = sigptrGetBytes n bytes sigptr + (Encoding.UTF8.GetString(bytearray, 0, bytearray.Length)),sigptr + + let chunk sz next = ({addr=next; size=sz},next + sz) + let nochunk next = ({addr= 0x0;size= 0x0; } ,next) + + + let kindAssemblyRef = ILRowKind [ UShort; UShort; UShort; UShort; ULong; Blob; SString; SString; Blob; ] + let kindModuleRef = ILRowKind [ SString ] + let kindFileRef = ILRowKind [ ULong; SString; Blob ] + let kindTypeRef = ILRowKind [ ResolutionScope; SString; SString ] + let kindTypeSpec = ILRowKind [ Blob ] + let kindTypeDef = ILRowKind [ ULong; SString; SString; TypeDefOrRefOrSpec; SimpleIndex ILTableNames.Field; SimpleIndex ILTableNames.Method ] + let kindPropertyMap = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.Property ] + let kindEventMap = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.Event ] + let kindInterfaceImpl = ILRowKind [ SimpleIndex ILTableNames.TypeDef; TypeDefOrRefOrSpec ] + let kindNested = ILRowKind [ SimpleIndex ILTableNames.TypeDef; SimpleIndex ILTableNames.TypeDef ] + let kindCustomAttribute = ILRowKind [ HasCustomAttribute; CustomAttributeType; Blob ] + let kindDeclSecurity = ILRowKind [ UShort; HasDeclSecurity; Blob ] + let kindMemberRef = ILRowKind [ MemberRefParent; SString; Blob ] + let kindStandAloneSig = ILRowKind [ Blob ] + let kindFieldDef = ILRowKind [ UShort; SString; Blob ] + let kindFieldRVA = ILRowKind [ Data; SimpleIndex ILTableNames.Field ] + let kindFieldMarshal = ILRowKind [ HasFieldMarshal; Blob ] + let kindConstant = ILRowKind [ UShort;HasConstant; Blob ] + let kindFieldLayout = ILRowKind [ ULong; SimpleIndex ILTableNames.Field ] + let kindParam = ILRowKind [ UShort; UShort; SString ] + let kindMethodDef = ILRowKind [ ULong; UShort; UShort; SString; Blob; SimpleIndex ILTableNames.Param ] + let kindMethodImpl = ILRowKind [ SimpleIndex ILTableNames.TypeDef; MethodDefOrRef; MethodDefOrRef ] + let kindImplMap = ILRowKind [ UShort; MemberForwarded; SString; SimpleIndex ILTableNames.ModuleRef ] + let kindMethodSemantics = ILRowKind [ UShort; SimpleIndex ILTableNames.Method; HasSemantics ] + let kindProperty = ILRowKind [ UShort; SString; Blob ] + let kindEvent = ILRowKind [ UShort; SString; TypeDefOrRefOrSpec ] + let kindManifestResource = ILRowKind [ ULong; ULong; SString; Implementation ] + let kindClassLayout = ILRowKind [ UShort; ULong; SimpleIndex ILTableNames.TypeDef ] + let kindExportedType = ILRowKind [ ULong; ULong; SString; SString; Implementation ] + let kindAssembly = ILRowKind [ ULong; UShort; UShort; UShort; UShort; ULong; Blob; SString; SString ] + let kindGenericParam_v1_1 = ILRowKind [ UShort; UShort; TypeOrMethodDef; SString; TypeDefOrRefOrSpec ] + let kindGenericParam_v2_0 = ILRowKind [ UShort; UShort; TypeOrMethodDef; SString ] + let kindMethodSpec = ILRowKind [ MethodDefOrRef; Blob ] + let kindGenericParamConstraint = ILRowKind [ SimpleIndex ILTableNames.GenericParam; TypeDefOrRefOrSpec ] + let kindModule = ILRowKind [ UShort; SString; GGuid; GGuid; GGuid ] + let kindIllegal = ILRowKind [ ] + + let hcCompare (TaggedIndex((t1: HasConstantTag), (idx1:int))) (TaggedIndex((t2: HasConstantTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hsCompare (TaggedIndex((t1:HasSemanticsTag), (idx1:int))) (TaggedIndex((t2:HasSemanticsTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hcaCompare (TaggedIndex((t1:HasCustomAttributeTag), (idx1:int))) (TaggedIndex((t2:HasCustomAttributeTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let mfCompare (TaggedIndex((t1:MemberForwardedTag), (idx1:int))) (TaggedIndex((t2:MemberForwardedTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hdsCompare (TaggedIndex((t1:HasDeclSecurityTag), (idx1:int))) (TaggedIndex((t2:HasDeclSecurityTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let hfmCompare (TaggedIndex((t1:HasFieldMarshalTag), idx1)) (TaggedIndex((t2:HasFieldMarshalTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let tomdCompare (TaggedIndex((t1:TypeOrMethodDefTag), idx1)) (TaggedIndex((t2:TypeOrMethodDefTag), idx2)) = + if idx1 < idx2 then -1 elif idx1 > idx2 then 1 else compare t1.Tag t2.Tag + + let simpleIndexCompare (idx1:int) (idx2:int) = + compare idx1 idx2 + + let mkCacheInt32 lowMem _infile _nm _sz = + if lowMem then (fun f x -> f x) else + let cache = ref null + fun f (idx:int32) -> + let cache = + match !cache with + | null -> cache := new Dictionary(11) + | _ -> () + !cache + let mutable res = Unchecked.defaultof<_> + let ok = cache.TryGetValue(idx, &res) + if ok then + res + else + let res = f idx + cache.[idx] <- res; + res + + let mkCacheGeneric lowMem _inbase _nm _sz = + if lowMem then (fun f x -> f x) else + let cache = ref null + fun f (idx :'T) -> + let cache = + match !cache with + | null -> cache := new Dictionary<_,_>(11 (* sz:int *) ) + | _ -> () + !cache + if cache.ContainsKey idx then cache.[idx] + else let res = f idx in cache.[idx] <- res; res + + let seekFindRow numRows rowChooser = + let mutable i = 1 + while (i <= numRows && not (rowChooser i)) do + i <- i + 1; + i + + // search for rows satisfying predicate + let seekReadIndexedRows (numRows, rowReader, keyFunc, keyComparer, binaryChop, rowConverter) = + if binaryChop then + let mutable low = 0 + let mutable high = numRows + 1 + begin + let mutable fin = false + while not fin do + if high - low <= 1 then + fin <- true + else + let mid = (low + high) / 2 + let midrow = rowReader mid + let c = keyComparer (keyFunc midrow) + if c > 0 then + low <- mid + elif c < 0 then + high <- mid + else + fin <- true + end; + let mutable res = [] + if high - low > 1 then + // now read off rows, forward and backwards + let mid = (low + high) / 2 + // read forward + begin + let mutable fin = false + let mutable curr = mid + while not fin do + if curr > numRows then + fin <- true; + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res; + else + fin <- true; + curr <- curr + 1; + done; + end; + res <- List.rev res; + // read backwards + begin + let mutable fin = false + let mutable curr = mid - 1 + while not fin do + if curr = 0 then + fin <- true + else + let currrow = rowReader curr + if keyComparer (keyFunc currrow) = 0 then + res <- rowConverter currrow :: res; + else + fin <- true; + curr <- curr - 1; + end; + res |> List.toArray + else + let res = ref [] + for i = 1 to numRows do + let rowinfo = rowReader i + if keyComparer (keyFunc rowinfo) = 0 then + res := rowConverter rowinfo :: !res; + List.rev !res |> List.toArray + + + let seekReadOptionalIndexedRow (info) = + match seekReadIndexedRows info with + | [| |] -> None + | xs -> Some xs.[0] + + let seekReadIndexedRow (info) = + match seekReadOptionalIndexedRow info with + | Some row -> row + | None -> failwith ("no row found for key when indexing table") + + let getName (ltd: Lazy) = + let td = ltd.Force() + (td.Name,ltd) + + let emptyILEvents = { new ILEventDefs with member _.Entries = [| |] } + let emptyILProperties = { new ILPropertyDefs with member _.Entries = [| |] } + let emptyILTypeDefs = ILTypeDefs (lazy [| |]) + let emptyILCustomAttrs = { new ILCustomAttrs with member _.Entries = [| |] } + let mkILCustomAttrs x = { new ILCustomAttrs with member _.Entries = x } + let emptyILMethodImpls = { new ILMethodImplDefs with member _.Entries = [| |] } + let emptyILMethods = ILMethodDefs (lazy [| |]) + let emptyILFields = { new ILFieldDefs with member _.Entries = [| |] } + + let mkILTy boxed tspec = + match boxed with + | AsObject -> ILType.Boxed tspec + | _ -> ILType.Value tspec + + let mkILArr1DTy ty = ILType.Array (ILArrayShape.SingleDimensional, ty) + + let typeNameForGlobalFunctions = "" + + let mkILNonGenericTySpec tref = ILTypeSpec (tref,[| |]) + let mkILTypeForGlobalFunctions scoref = ILType.Boxed (mkILNonGenericTySpec (ILTypeRef(ILTypeRefScope.Top scoref, UNone, typeNameForGlobalFunctions))) + let mkILArrTy (ty, shape) = ILType.Array(shape,ty) + + let mkILMethSpecInTyRaw (typ:ILType, cc, nm, args, rty, minst:ILGenericArgs) = + ILMethodSpec (ILMethodRef (typ.TypeRef,cc,minst.Length,nm,args,rty),typ,minst) + + let mkILFieldSpecInTy (typ:ILType,nm,fty) = + ILFieldSpec (ILFieldRef (typ.TypeRef,nm,fty), typ) + + let mkILGlobals systemRuntimeScopeRef = + let mkILTyspec nsp nm = mkILNonGenericTySpec(ILTypeRef(ILTypeRefScope.Top(systemRuntimeScopeRef),USome nsp,nm)) + { typ_Object = ILType.Boxed (mkILTyspec "System" "Object") + typ_String = ILType.Boxed (mkILTyspec "System" "String") + typ_Type = ILType.Boxed (mkILTyspec "System" "Type") + typ_Int64 = ILType.Value (mkILTyspec "System" "Int64") + typ_UInt64 = ILType.Value (mkILTyspec "System" "UInt64") + typ_Int32 = ILType.Value (mkILTyspec "System" "Int32") + typ_Array = ILType.Boxed (mkILTyspec "System" "Array") + typ_UInt32 = ILType.Value (mkILTyspec "System" "UInt32") + typ_Int16 = ILType.Value (mkILTyspec "System" "Int16") + typ_UInt16 = ILType.Value (mkILTyspec "System" "UInt16") + typ_SByte = ILType.Value (mkILTyspec "System" "SByte") + typ_Byte = ILType.Value (mkILTyspec "System" "Byte") + typ_Single = ILType.Value (mkILTyspec "System" "Single") + typ_Double = ILType.Value (mkILTyspec "System" "Double") + typ_Boolean = ILType.Value (mkILTyspec "System" "Boolean") + typ_Char = ILType.Value (mkILTyspec "System" "Char") + typ_IntPtr = ILType.Value (mkILTyspec "System" "IntPtr") + typ_TypedReference = Some (ILType.Value (mkILTyspec "System" "TypedReference")) + typ_UIntPtr = ILType.Value (mkILTyspec "System" "UIntPtr") + systemRuntimeScopeRef = systemRuntimeScopeRef } + + type ILModuleReader(infile: string, is: ByteFile, ilg: ILGlobals, lowMem: bool) = + + //----------------------------------------------------------------------- + // Crack the binary headers, build a reader context and return the lazy + // read of the AbsIL module. + // ---------------------------------------------------------------------- + + (* MSDOS HEADER *) + let peSignaturePhysLoc = seekReadInt32 is 0x3c + + (* PE HEADER *) + let peFileHeaderPhysLoc = peSignaturePhysLoc + 0x04 + let peOptionalHeaderPhysLoc = peFileHeaderPhysLoc + 0x14 + let peSignature = seekReadInt32 is (peSignaturePhysLoc + 0) + do if peSignature <> 0x4550 then failwithf "not a PE file - bad magic PE number 0x%08x, is = %A" peSignature is; + + + (* PE SIGNATURE *) + let machine = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 0) + let numSections = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 2) + let optHeaderSize = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 16) + do if optHeaderSize <> 0xe0 && + optHeaderSize <> 0xf0 then failwith "not a PE file - bad optional header size"; + let x64adjust = optHeaderSize - 0xe0 + let only64 = (optHeaderSize = 0xf0) (* May want to read in the optional header Magic number and check that as well... *) + let platform = match machine with | 0x8664 -> Some(AMD64) | 0x200 -> Some(IA64) | _ -> Some(X86) + let sectionHeadersStartPhysLoc = peOptionalHeaderPhysLoc + optHeaderSize + + let flags = seekReadUInt16AsInt32 is (peFileHeaderPhysLoc + 18) + let isDll = (flags &&& 0x2000) <> 0x0 + + (* OPTIONAL PE HEADER *) + (* x86: 000000a0 *) + (* x86: 000000b0 *) + let dataSegmentAddr = seekReadInt32 is (peOptionalHeaderPhysLoc + 24) (* e.g. 0x0000c000 *) + let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 is (peOptionalHeaderPhysLoc + 28) (* Image Base Always 0x400000 (see Section 23.1). - QUERY: no it's not always 0x400000, e.g. 0x034f0000 *) + let alignVirt = seekReadInt32 is (peOptionalHeaderPhysLoc + 32) (* Section Alignment Always 0x2000 (see Section 23.1). *) + let alignPhys = seekReadInt32 is (peOptionalHeaderPhysLoc + 36) (* File Alignment Either 0x200 or 0x1000. *) + (* x86: 000000c0 *) + let subsysMajor = seekReadUInt16AsInt32 is (peOptionalHeaderPhysLoc + 48) (* SubSys Major Always 4 (see Section 23.1). *) + let subsysMinor = seekReadUInt16AsInt32 is (peOptionalHeaderPhysLoc + 50) (* SubSys Minor Always 0 (see Section 23.1). *) + (* x86: 000000d0 *) + let subsys = seekReadUInt16 is (peOptionalHeaderPhysLoc + 68) (* SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (!0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (!0x2). QUERY: Why is this 3 on the images ILASM produces??? *) + let useHighEntropyVA = + let n = seekReadUInt16 is (peOptionalHeaderPhysLoc + 70) + let highEnthropyVA = 0x20us + (n &&& highEnthropyVA) = highEnthropyVA + + (* x86: 000000e0 *) + (* x86: 000000f0, x64: 00000100 *) + (* x86: 00000100 - these addresses are for x86 - for the x64 location, add x64adjust (0x10) *) + (* x86: 00000110 *) + (* x86: 00000120 *) + (* x86: 00000130 *) + (* x86: 00000140 *) + (* x86: 00000150 *) + (* x86: 00000160 *) + let cliHeaderAddr = seekReadInt32 is (peOptionalHeaderPhysLoc + 208 + x64adjust) + + let anyV2P (n,v) = + let rec look i pos = + if i >= numSections then (failwith (infile + ": bad "+n+", rva "+string v); 0x0) + else + let virtSize = seekReadInt32 is (pos + 8) + let virtAddr = seekReadInt32 is (pos + 12) + let physLoc = seekReadInt32 is (pos + 20) + if (v >= virtAddr && (v < virtAddr + virtSize)) then (v - virtAddr) + physLoc + else look (i+1) (pos + 0x28) + look 0 sectionHeadersStartPhysLoc + + let cliHeaderPhysLoc = anyV2P ("cli header",cliHeaderAddr) + + let metadataAddr = seekReadInt32 is (cliHeaderPhysLoc + 8) + let cliFlags = seekReadInt32 is (cliHeaderPhysLoc + 16) + let ilOnly = (cliFlags &&& 0x01) <> 0x00 + let only32 = (cliFlags &&& 0x02) <> 0x00 + let is32bitpreferred = (cliFlags &&& 0x00020003) <> 0x00 + + let entryPointToken = seekReadUncodedToken is (cliHeaderPhysLoc + 20) + let resourcesAddr = seekReadInt32 is (cliHeaderPhysLoc + 24) + + let metadataPhysLoc = anyV2P ("metadata",metadataAddr) + let magic = seekReadUInt16AsInt32 is metadataPhysLoc + do if magic <> 0x5342 then failwith (infile + ": bad metadata magic number: " + string magic); + let magic2 = seekReadUInt16AsInt32 is (metadataPhysLoc + 2) + do if magic2 <> 0x424a then failwith "bad metadata magic number"; + + let versionLength = seekReadInt32 is (metadataPhysLoc + 12) + let ilMetadataVersion = seekReadBytes is (metadataPhysLoc + 16) versionLength |> Array.filter (fun b -> b <> 0uy) + let x = align 0x04 (16 + versionLength) + let numStreams = seekReadUInt16AsInt32 is (metadataPhysLoc + x + 2) + let streamHeadersStart = (metadataPhysLoc + x + 4) + + (* Crack stream headers *) + + let tryFindStream name = + let rec look i pos = + if i >= numStreams then None + else + let offset = seekReadInt32 is (pos + 0) + let length = seekReadInt32 is (pos + 4) + let res = ref true + let fin = ref false + let n = ref 0 + // read and compare the stream name byte by byte + while (not !fin) do + let c= seekReadByteAsInt32 is (pos + 8 + (!n)) + if c = 0 then + fin := true + elif !n >= Array.length name || c <> name.[!n] then + res := false; + incr n + if !res then Some(offset + metadataPhysLoc,length) + else look (i+1) (align 0x04 (pos + 8 + (!n))) + look 0 streamHeadersStart + + let findStream name = + match tryFindStream name with + | None -> (0x0, 0x0) + | Some positions -> positions + + let (tablesStreamPhysLoc, _tablesStreamSize) = + match tryFindStream [| 0x23; 0x7e |] (* #~ *) with + | Some res -> res + | None -> + match tryFindStream [| 0x23; 0x2d |] (* #-: at least one DLL I've seen uses this! *) with + | Some res -> res + | None -> + let firstStreamOffset = seekReadInt32 is (streamHeadersStart + 0) + let firstStreamLength = seekReadInt32 is (streamHeadersStart + 4) + firstStreamOffset,firstStreamLength + + let (stringsStreamPhysicalLoc, stringsStreamSize) = findStream [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; |] (* #Strings *) + let (blobsStreamPhysicalLoc, blobsStreamSize) = findStream [| 0x23; 0x42; 0x6c; 0x6f; 0x62; |] (* #Blob *) + + let tablesStreamMajorVersion = seekReadByteAsInt32 is (tablesStreamPhysLoc + 4) + let tablesStreamMinorVersion = seekReadByteAsInt32 is (tablesStreamPhysLoc + 5) + + let usingWhidbeyBeta1TableSchemeForGenericParam = (tablesStreamMajorVersion = 1) && (tablesStreamMinorVersion = 1) + + let tableKinds = + [|kindModule (* Table 0 *); + kindTypeRef (* Table 1 *); + kindTypeDef (* Table 2 *); + kindIllegal (* kindFieldPtr *) (* Table 3 *); + kindFieldDef (* Table 4 *); + kindIllegal (* kindMethodPtr *) (* Table 5 *); + kindMethodDef (* Table 6 *); + kindIllegal (* kindParamPtr *) (* Table 7 *); + kindParam (* Table 8 *); + kindInterfaceImpl (* Table 9 *); + kindMemberRef (* Table 10 *); + kindConstant (* Table 11 *); + kindCustomAttribute (* Table 12 *); + kindFieldMarshal (* Table 13 *); + kindDeclSecurity (* Table 14 *); + kindClassLayout (* Table 15 *); + kindFieldLayout (* Table 16 *); + kindStandAloneSig (* Table 17 *); + kindEventMap (* Table 18 *); + kindIllegal (* kindEventPtr *) (* Table 19 *); + kindEvent (* Table 20 *); + kindPropertyMap (* Table 21 *); + kindIllegal (* kindPropertyPtr *) (* Table 22 *); + kindProperty (* Table 23 *); + kindMethodSemantics (* Table 24 *); + kindMethodImpl (* Table 25 *); + kindModuleRef (* Table 26 *); + kindTypeSpec (* Table 27 *); + kindImplMap (* Table 28 *); + kindFieldRVA (* Table 29 *); + kindIllegal (* kindENCLog *) (* Table 30 *); + kindIllegal (* kindENCMap *) (* Table 31 *); + kindAssembly (* Table 32 *); + kindIllegal (* kindAssemblyProcessor *) (* Table 33 *); + kindIllegal (* kindAssemblyOS *) (* Table 34 *); + kindAssemblyRef (* Table 35 *); + kindIllegal (* kindAssemblyRefProcessor *) (* Table 36 *); + kindIllegal (* kindAssemblyRefOS *) (* Table 37 *); + kindFileRef (* Table 38 *); + kindExportedType (* Table 39 *); + kindManifestResource (* Table 40 *); + kindNested (* Table 41 *); + (if usingWhidbeyBeta1TableSchemeForGenericParam then kindGenericParam_v1_1 else kindGenericParam_v2_0); (* Table 42 *) + kindMethodSpec (* Table 43 *); + kindGenericParamConstraint (* Table 44 *); + kindIllegal (* Table 45 *); + kindIllegal (* Table 46 *); + kindIllegal (* Table 47 *); + kindIllegal (* Table 48 *); + kindIllegal (* Table 49 *); + kindIllegal (* Table 50 *); + kindIllegal (* Table 51 *); + kindIllegal (* Table 52 *); + kindIllegal (* Table 53 *); + kindIllegal (* Table 54 *); + kindIllegal (* Table 55 *); + kindIllegal (* Table 56 *); + kindIllegal (* Table 57 *); + kindIllegal (* Table 58 *); + kindIllegal (* Table 59 *); + kindIllegal (* Table 60 *); + kindIllegal (* Table 61 *); + kindIllegal (* Table 62 *); + kindIllegal (* Table 63 *); + |] + + let heapSizes = seekReadByteAsInt32 is (tablesStreamPhysLoc + 6) + let valid = seekReadInt64 is (tablesStreamPhysLoc + 8) + let sorted = seekReadInt64 is (tablesStreamPhysLoc + 16) + let tableRowCount, startOfTables = + let numRows = Array.create 64 0 + let prevNumRowIdx = ref (tablesStreamPhysLoc + 24) + for i = 0 to 63 do + if (valid &&& (int64 1 <<< i)) <> int64 0 then + numRows.[i] <- (seekReadInt32 is !prevNumRowIdx); + prevNumRowIdx := !prevNumRowIdx + 4 + numRows, !prevNumRowIdx + + let getNumRows (tab:ILTableName) = tableRowCount.[tab.Index] + let stringsBigness = (heapSizes &&& 1) <> 0 + let guidsBigness = (heapSizes &&& 2) <> 0 + let blobsBigness = (heapSizes &&& 4) <> 0 + + let tableBigness = Array.map (fun n -> n >= 0x10000) tableRowCount + + let codedBigness nbits tab = + let rows = getNumRows tab + rows >= (0x10000 >>>& nbits) + + let tdorBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.TypeRef || + codedBigness 2 ILTableNames.TypeSpec + + let tomdBigness = + codedBigness 1 ILTableNames.TypeDef || + codedBigness 1 ILTableNames.Method + + let hcBigness = + codedBigness 2 ILTableNames.Field || + codedBigness 2 ILTableNames.Param || + codedBigness 2 ILTableNames.Property + + let hcaBigness = + codedBigness 5 ILTableNames.Method || + codedBigness 5 ILTableNames.Field || + codedBigness 5 ILTableNames.TypeRef || + codedBigness 5 ILTableNames.TypeDef || + codedBigness 5 ILTableNames.Param || + codedBigness 5 ILTableNames.InterfaceImpl || + codedBigness 5 ILTableNames.MemberRef || + codedBigness 5 ILTableNames.Module || + codedBigness 5 ILTableNames.Permission || + codedBigness 5 ILTableNames.Property || + codedBigness 5 ILTableNames.Event || + codedBigness 5 ILTableNames.StandAloneSig || + codedBigness 5 ILTableNames.ModuleRef || + codedBigness 5 ILTableNames.TypeSpec || + codedBigness 5 ILTableNames.Assembly || + codedBigness 5 ILTableNames.AssemblyRef || + codedBigness 5 ILTableNames.File || + codedBigness 5 ILTableNames.ExportedType || + codedBigness 5 ILTableNames.ManifestResource || + codedBigness 5 ILTableNames.GenericParam || + codedBigness 5 ILTableNames.GenericParamConstraint || + codedBigness 5 ILTableNames.MethodSpec + + + let hfmBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Param + + let hdsBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.Method || + codedBigness 2 ILTableNames.Assembly + + let mrpBigness = + codedBigness 3 ILTableNames.TypeRef || + codedBigness 3 ILTableNames.ModuleRef || + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.TypeSpec + + let hsBigness = + codedBigness 1 ILTableNames.Event || + codedBigness 1 ILTableNames.Property + + let mdorBigness = + codedBigness 1 ILTableNames.Method || + codedBigness 1 ILTableNames.MemberRef + + let mfBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Method + + let iBigness = + codedBigness 2 ILTableNames.File || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.ExportedType + + let catBigness = + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.MemberRef + + let rsBigness = + codedBigness 2 ILTableNames.Module || + codedBigness 2 ILTableNames.ModuleRef || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.TypeRef + + let rowKindSize (ILRowKind kinds) = + kinds |> List.sumBy (fun x -> + match x with + | UShort -> 2 + | ULong -> 4 + | Byte -> 1 + | Data -> 4 + | GGuid -> (if guidsBigness then 4 else 2) + | Blob -> (if blobsBigness then 4 else 2) + | SString -> (if stringsBigness then 4 else 2) + | SimpleIndex tab -> (if tableBigness.[tab.Index] then 4 else 2) + | TypeDefOrRefOrSpec -> (if tdorBigness then 4 else 2) + | TypeOrMethodDef -> (if tomdBigness then 4 else 2) + | HasConstant -> (if hcBigness then 4 else 2) + | HasCustomAttribute -> (if hcaBigness then 4 else 2) + | HasFieldMarshal -> (if hfmBigness then 4 else 2) + | HasDeclSecurity -> (if hdsBigness then 4 else 2) + | MemberRefParent -> (if mrpBigness then 4 else 2) + | HasSemantics -> (if hsBigness then 4 else 2) + | MethodDefOrRef -> (if mdorBigness then 4 else 2) + | MemberForwarded -> (if mfBigness then 4 else 2) + | Implementation -> (if iBigness then 4 else 2) + | CustomAttributeType -> (if catBigness then 4 else 2) + | ResolutionScope -> (if rsBigness then 4 else 2)) + + let tableRowSizes = tableKinds |> Array.map rowKindSize + + let tablePhysLocations = + let res = Array.create 64 0x0 + let prevTablePhysLoc = ref startOfTables + for i = 0 to 63 do + res.[i] <- !prevTablePhysLoc; + prevTablePhysLoc := !prevTablePhysLoc + (tableRowCount.[i] * tableRowSizes.[i]); + res + + // All the caches. The sizes are guesstimates for the rough sharing-density of the assembly + let cacheAssemblyRef = mkCacheInt32 lowMem infile "ILAssemblyRef" (getNumRows ILTableNames.AssemblyRef) + let cacheMemberRefAsMemberData = mkCacheGeneric lowMem infile "MemberRefAsMemberData" (getNumRows ILTableNames.MemberRef / 20 + 1) + let cacheTypeRef = mkCacheInt32 lowMem infile "ILTypeRef" (getNumRows ILTableNames.TypeRef / 20 + 1) + let cacheTypeRefAsType = mkCacheGeneric lowMem infile "TypeRefAsType" (getNumRows ILTableNames.TypeRef / 20 + 1) + let cacheBlobHeapAsPropertySig = mkCacheGeneric lowMem infile "BlobHeapAsPropertySig" (getNumRows ILTableNames.Property / 20 + 1) + let cacheBlobHeapAsFieldSig = mkCacheGeneric lowMem infile "BlobHeapAsFieldSig" (getNumRows ILTableNames.Field / 20 + 1) + let cacheBlobHeapAsMethodSig = mkCacheGeneric lowMem infile "BlobHeapAsMethodSig" (getNumRows ILTableNames.Method / 20 + 1) + let cacheTypeDefAsType = mkCacheGeneric lowMem infile "TypeDefAsType" (getNumRows ILTableNames.TypeDef / 20 + 1) + let cacheMethodDefAsMethodData = mkCacheInt32 lowMem infile "MethodDefAsMethodData" (getNumRows ILTableNames.Method / 20 + 1) + // nb. Lots and lots of cache hits on this cache, hence never optimize cache away + let cacheStringHeap = mkCacheInt32 false infile "string heap" ( stringsStreamSize / 50 + 1) + let cacheBlobHeap = mkCacheInt32 lowMem infile "blob heap" ( blobsStreamSize / 50 + 1) + + //----------------------------------------------------------------------- + + let rowAddr (tab:ILTableName) idx = tablePhysLocations.[tab.Index] + (idx - 1) * tableRowSizes.[tab.Index] + + let seekReadUInt16Adv (addr: byref) = + let res = seekReadUInt16 is addr + addr <- addr + 2 + res + + let seekReadInt32Adv (addr: byref) = + let res = seekReadInt32 is addr + addr <- addr+4 + res + + let seekReadUInt16AsInt32Adv (addr: byref) = + let res = seekReadUInt16AsInt32 is addr + addr <- addr+2 + res + + let seekReadTaggedIdx f nbits big (addr: byref) = + let tok = if big then seekReadInt32Adv &addr else seekReadUInt16AsInt32Adv &addr + tokToTaggedIdx f nbits tok + + + let seekReadIdx big (addr: byref) = + if big then seekReadInt32Adv &addr else seekReadUInt16AsInt32Adv &addr + + let seekReadUntaggedIdx (tab:ILTableName) (addr: byref) = + seekReadIdx tableBigness.[tab.Index] &addr + + + let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ResolutionScopeTag idx) 2 rsBigness &addr + let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeDefOrRefOrSpecTag idx) 2 tdorBigness &addr + let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeOrMethodDefTag idx) 1 tomdBigness &addr + let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasConstantTag idx) 2 hcBigness &addr + let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasCustomAttributeTag idx) 5 hcaBigness &addr + //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasFieldMarshalTag idx) 1 hfmBigness &addr + //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasDeclSecurityTag idx) 2 hdsBigness &addr + let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MemberRefParentTag idx) 3 mrpBigness &addr + let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasSemanticsTag idx) 1 hsBigness &addr + let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MethodDefOrRefTag idx) 1 mdorBigness &addr + let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ImplementationTag idx) 2 iBigness &addr + let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> CustomAttributeTypeTag idx) 3 catBigness &addr + let seekReadStringIdx (addr: byref) = seekReadIdx stringsBigness &addr + let seekReadGuidIdx (addr: byref) = seekReadIdx guidsBigness &addr + let seekReadBlobIdx (addr: byref) = seekReadIdx blobsBigness &addr + + let seekReadModuleRow idx = + if idx = 0 then failwith "cannot read Module table row 0"; + let mutable addr = rowAddr ILTableNames.Module idx + let generation = seekReadUInt16Adv &addr + let nameIdx = seekReadStringIdx &addr + let mvidIdx = seekReadGuidIdx &addr + let encidIdx = seekReadGuidIdx &addr + let encbaseidIdx = seekReadGuidIdx &addr + (generation, nameIdx, mvidIdx, encidIdx, encbaseidIdx) + + /// Read Table ILTypeRef + let seekReadTypeRefRow idx = + let mutable addr = rowAddr ILTableNames.TypeRef idx + let scopeIdx = seekReadResolutionScopeIdx &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + (scopeIdx,nameIdx,namespaceIdx) + + /// Read Table ILTypeDef + let seekReadTypeDefRow idx = + let mutable addr = rowAddr ILTableNames.TypeDef idx + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + let extendsIdx = seekReadTypeDefOrRefOrSpecIdx &addr + let fieldsIdx = seekReadUntaggedIdx ILTableNames.Field &addr + let methodsIdx = seekReadUntaggedIdx ILTableNames.Method &addr + (flags, nameIdx, namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) + + /// Read Table Field + let seekReadFieldRow idx = + let mutable addr = rowAddr ILTableNames.Field idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + (flags,nameIdx,typeIdx) + + /// Read Table Method + let seekReadMethodRow idx = + let mutable addr = rowAddr ILTableNames.Method idx + let codeRVA = seekReadInt32Adv &addr + let implflags = seekReadUInt16AsInt32Adv &addr + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + let paramIdx = seekReadUntaggedIdx ILTableNames.Param &addr + (codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) + + /// Read Table Param + let seekReadParamRow idx = + let mutable addr = rowAddr ILTableNames.Param idx + let flags = seekReadUInt16AsInt32Adv &addr + let seq = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + (flags,seq,nameIdx) + + let seekReadInterfaceImplRow idx = + let mutable addr = rowAddr ILTableNames.InterfaceImpl idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let intfIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (tidx,intfIdx) + + /// Read Table MemberRef + let seekReadMemberRefRow idx = + let mutable addr = rowAddr ILTableNames.MemberRef idx + let mrpIdx = seekReadMemberRefParentIdx &addr + let nameIdx = seekReadStringIdx &addr + let typeIdx = seekReadBlobIdx &addr + (mrpIdx,nameIdx,typeIdx) + + /// Read Table Constant + let seekReadConstantRow idx = + let mutable addr = rowAddr ILTableNames.Constant idx + let kind = seekReadUInt16Adv &addr + let parentIdx = seekReadHasConstantIdx &addr + let valIdx = seekReadBlobIdx &addr + (kind, parentIdx, valIdx) + + /// Read Table CustomAttribute + let seekReadCustomAttributeRow idx = + let mutable addr = rowAddr ILTableNames.CustomAttribute idx + let parentIdx = seekReadHasCustomAttributeIdx &addr + let typeIdx = seekReadCustomAttributeTypeIdx &addr + let valIdx = seekReadBlobIdx &addr + (parentIdx, typeIdx, valIdx) + + //let seekReadFieldMarshalRow idx = + // let mutable addr = rowAddr TableNames.FieldMarshal idx + // let parentIdx = seekReadHasFieldMarshalIdx &addr + // let typeIdx = seekReadBlobIdx &addr + // (parentIdx, typeIdx) + + /// Read Table ClassLayout. + let seekReadClassLayoutRow idx = + let mutable addr = rowAddr ILTableNames.ClassLayout idx + let pack = seekReadUInt16Adv &addr + let size = seekReadInt32Adv &addr + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + (pack, size, tidx) + + /// Read Table FieldLayout. + let seekReadFieldLayoutRow idx = + let mutable addr = rowAddr ILTableNames.FieldLayout idx + let offset = seekReadInt32Adv &addr + let fidx = seekReadUntaggedIdx ILTableNames.Field &addr + (offset, fidx) + + /// Read Table EventMap + let seekReadEventMapRow idx = + let mutable addr = rowAddr ILTableNames.EventMap idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let eventsIdx = seekReadUntaggedIdx ILTableNames.Event &addr + (tidx,eventsIdx) + + /// Read Table Event + let seekReadEventRow idx = + let mutable addr = rowAddr ILTableNames.Event idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (flags,nameIdx,typIdx) + + /// Read Table PropertyMap + let seekReadPropertyMapRow idx = + let mutable addr = rowAddr ILTableNames.PropertyMap idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let propsIdx = seekReadUntaggedIdx ILTableNames.Property &addr + (tidx,propsIdx) + + /// Read Table Property + let seekReadPropertyRow idx = + let mutable addr = rowAddr ILTableNames.Property idx + let flags = seekReadUInt16AsInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let typIdx = seekReadBlobIdx &addr + (flags,nameIdx,typIdx) + + /// Read Table MethodSemantics + let seekReadMethodSemanticsRow idx = + let mutable addr = rowAddr ILTableNames.MethodSemantics idx + let flags = seekReadUInt16AsInt32Adv &addr + let midx = seekReadUntaggedIdx ILTableNames.Method &addr + let assocIdx = seekReadHasSemanticsIdx &addr + (flags,midx,assocIdx) + + let seekReadMethodImplRow idx = + let mutable addr = rowAddr ILTableNames.MethodImpl idx + let tidx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let mbodyIdx = seekReadMethodDefOrRefIdx &addr + let mdeclIdx = seekReadMethodDefOrRefIdx &addr + (tidx, mbodyIdx, mdeclIdx) + + /// Read Table ILModuleRef + let seekReadModuleRefRow idx = + let mutable addr = rowAddr ILTableNames.ModuleRef idx + let nameIdx = seekReadStringIdx &addr + nameIdx + + /// Read Table ILTypeSpec + let seekReadTypeSpecRow idx = + let mutable addr = rowAddr ILTableNames.TypeSpec idx + let blobIdx = seekReadBlobIdx &addr + blobIdx + + /// Read Table Assembly + let seekReadAssemblyRow idx = + let mutable addr = rowAddr ILTableNames.Assembly idx + let hash = seekReadInt32Adv &addr + let v1 = seekReadUInt16Adv &addr + let v2 = seekReadUInt16Adv &addr + let v3 = seekReadUInt16Adv &addr + let v4 = seekReadUInt16Adv &addr + let flags = seekReadInt32Adv &addr + let publicKeyIdx = seekReadBlobIdx &addr + let nameIdx = seekReadStringIdx &addr + let localeIdx = seekReadStringIdx &addr + (hash,v1,v2,v3,v4,flags,publicKeyIdx, nameIdx, localeIdx) + + /// Read Table ILAssemblyRef + let seekReadAssemblyRefRow idx = + let mutable addr = rowAddr ILTableNames.AssemblyRef idx + let v1 = seekReadUInt16Adv &addr + let v2 = seekReadUInt16Adv &addr + let v3 = seekReadUInt16Adv &addr + let v4 = seekReadUInt16Adv &addr + let flags = seekReadInt32Adv &addr + let publicKeyOrTokenIdx = seekReadBlobIdx &addr + let nameIdx = seekReadStringIdx &addr + let localeIdx = seekReadStringIdx &addr + let hashValueIdx = seekReadBlobIdx &addr + (v1,v2,v3,v4,flags,publicKeyOrTokenIdx, nameIdx, localeIdx,hashValueIdx) + + /// Read Table File + let seekReadFileRow idx = + let mutable addr = rowAddr ILTableNames.File idx + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let hashValueIdx = seekReadBlobIdx &addr + (flags, nameIdx, hashValueIdx) + + /// Read Table ILExportedTypeOrForwarder + let seekReadExportedTypeRow idx = + let mutable addr = rowAddr ILTableNames.ExportedType idx + let flags = seekReadInt32Adv &addr + let tok = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let namespaceIdx = seekReadStringIdx &addr + let implIdx = seekReadImplementationIdx &addr + (flags,tok,nameIdx,namespaceIdx,implIdx) + + /// Read Table ManifestResource + let seekReadManifestResourceRow idx = + let mutable addr = rowAddr ILTableNames.ManifestResource idx + let offset = seekReadInt32Adv &addr + let flags = seekReadInt32Adv &addr + let nameIdx = seekReadStringIdx &addr + let implIdx = seekReadImplementationIdx &addr + (offset,flags,nameIdx,implIdx) + + /// Read Table Nested + let seekReadNestedRow idx = + let mutable addr = rowAddr ILTableNames.Nested idx + let nestedIdx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + let enclIdx = seekReadUntaggedIdx ILTableNames.TypeDef &addr + (nestedIdx,enclIdx) + + /// Read Table GenericParam + let seekReadGenericParamRow idx = + let mutable addr = rowAddr ILTableNames.GenericParam idx + let seq = seekReadUInt16Adv &addr + let flags = seekReadUInt16Adv &addr + let ownerIdx = seekReadTypeOrMethodDefIdx &addr + let nameIdx = seekReadStringIdx &addr + (idx,seq,flags,ownerIdx,nameIdx) + + // Read Table GenericParamConstraint + let seekReadGenericParamConstraintRow idx = + let mutable addr = rowAddr ILTableNames.GenericParamConstraint idx + let pidx = seekReadUntaggedIdx ILTableNames.GenericParam &addr + let constraintIdx = seekReadTypeDefOrRefOrSpecIdx &addr + (pidx,constraintIdx) + + //let readUserStringHeapUncached idx = seekReadUserString is (userStringsStreamPhysicalLoc + idx) + //let readUserStringHeap = cacheUserStringHeap readUserStringHeapUncached + + let readStringHeapUncached idx = seekReadUTF8String is (stringsStreamPhysicalLoc + idx) + let readStringHeap = cacheStringHeap readStringHeapUncached + let readStringHeapOption idx = if idx = 0 then UNone else USome (readStringHeap idx) + + let emptyByteArray: byte[] = [||] + let readBlobHeapUncached idx = + // valid index lies in range [1..streamSize) + // NOTE: idx cannot be 0 - Blob\String heap has first empty element that is one byte 0 + if idx <= 0 || idx >= blobsStreamSize then emptyByteArray + else seekReadBlob is (blobsStreamPhysicalLoc + idx) + let readBlobHeap = cacheBlobHeap readBlobHeapUncached + let readBlobHeapOption idx = if idx = 0 then UNone else USome (readBlobHeap idx) + + //let readGuidHeap idx = seekReadGuid is (guidsStreamPhysicalLoc + idx) + + // read a single value out of a blob heap using the given function + let readBlobHeapAsBool vidx = fst (sigptrGetBool (readBlobHeap vidx) 0) + let readBlobHeapAsSByte vidx = fst (sigptrGetSByte (readBlobHeap vidx) 0) + let readBlobHeapAsInt16 vidx = fst (sigptrGetInt16 (readBlobHeap vidx) 0) + let readBlobHeapAsInt32 vidx = fst (sigptrGetInt32 (readBlobHeap vidx) 0) + let readBlobHeapAsInt64 vidx = fst (sigptrGetInt64 (readBlobHeap vidx) 0) + let readBlobHeapAsByte vidx = fst (sigptrGetByte (readBlobHeap vidx) 0) + let readBlobHeapAsUInt16 vidx = fst (sigptrGetUInt16 (readBlobHeap vidx) 0) + let readBlobHeapAsUInt32 vidx = fst (sigptrGetUInt32 (readBlobHeap vidx) 0) + let readBlobHeapAsUInt64 vidx = fst (sigptrGetUInt64 (readBlobHeap vidx) 0) + let readBlobHeapAsSingle vidx = fst (sigptrGetSingle (readBlobHeap vidx) 0) + let readBlobHeapAsDouble vidx = fst (sigptrGetDouble (readBlobHeap vidx) 0) + + //----------------------------------------------------------------------- + // Read the AbsIL structure (lazily) by reading off the relevant rows. + // ---------------------------------------------------------------------- + + let isSorted (tab:ILTableName) = ((sorted &&& (int64 1 <<< tab.Index)) <> int64 0x0) + + //let subsysversion = (subsysMajor, subsysMinor) + let ilMetadataVersion = Encoding.UTF8.GetString (ilMetadataVersion, 0, ilMetadataVersion.Length) + + let rec seekReadModule (subsys, subsysversion, useHighEntropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal, ilMetadataVersion) idx = + let (_generation, nameIdx, _mvidIdx, _encidIdx, _encbaseidIdx) = seekReadModuleRow idx + let ilModuleName = readStringHeap nameIdx + //let nativeResources = readNativeResources tgt + + { Manifest = + if getNumRows (ILTableNames.Assembly) > 0 then Some (seekReadAssemblyManifest 1) + else None; + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Module,idx)); + Name = ilModuleName; + //NativeResources=nativeResources; + TypeDefs = ILTypeDefs (lazy (seekReadTopTypeDefs ())); + SubSystemFlags = int32 subsys; + IsILOnly = ilOnly; + SubsystemVersion = subsysversion + UseHighEntropyVA = useHighEntropyVA + Platform = platform; + StackReserveSize = None; + Is32Bit = only32; + Is32BitPreferred = is32bitpreferred; + Is64Bit = only64; + IsDLL=isDll; + VirtualAlignment = alignVirt; + PhysicalAlignment = alignPhys; + ImageBase = imageBaseReal; + MetadataVersion = ilMetadataVersion; + Resources = seekReadManifestResources (); + } + + and seekReadAssemblyManifest idx = + let (hash,v1,v2,v3,v4,flags,publicKeyIdx, nameIdx, localeIdx) = seekReadAssemblyRow idx + let name = readStringHeap nameIdx + let pubkey = readBlobHeapOption publicKeyIdx + { Name= name; + AuxModuleHashAlgorithm=hash + //SecurityDecls= seekReadSecurityDecls (TaggedIndex(hds_Assembly,idx)); + PublicKey= pubkey; + Version= USome (Version(int v1,int v2,int v3,int v4)); + Locale= readStringHeapOption localeIdx; + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Assembly,idx)); + ExportedTypes= seekReadTopExportedTypes (); + EntrypointElsewhere=(if fst entryPointToken = ILTableNames.File then Some (seekReadFile (snd entryPointToken)) else None); + Retargetable = 0 <> (flags &&& 0x100); + DisableJitOptimizations = 0 <> (flags &&& 0x4000); + JitTracking = 0 <> (flags &&& 0x8000) + IgnoreSymbolStoreSequencePoints = 0 <> (flags &&& 0x2000) + } + + and seekReadAssemblyRef idx = cacheAssemblyRef seekReadAssemblyRefUncached idx + and seekReadAssemblyRefUncached idx = + let (v1,v2,v3,v4,flags,publicKeyOrTokenIdx, nameIdx, localeIdx,hashValueIdx) = seekReadAssemblyRefRow idx + let nm = readStringHeap nameIdx + let publicKey = + match readBlobHeapOption publicKeyOrTokenIdx with + | UNone -> UNone + | USome blob -> USome (if (flags &&& 0x0001) <> 0x0 then PublicKey blob else PublicKeyToken blob) + + ILAssemblyRef + (name=nm, + hash=readBlobHeapOption hashValueIdx, + publicKey=publicKey, + retargetable=((flags &&& 0x0100) <> 0x0), + version=USome(Version(int v1,int v2,int v3,int v4)), + locale=readStringHeapOption localeIdx;) + + and seekReadModuleRef idx = + let nameIdx = seekReadModuleRefRow idx + ILModuleRef(name=readStringHeap nameIdx, hasMetadata=true, hash=UNone) + + and seekReadFile idx = + let (flags, nameIdx, hashValueIdx) = seekReadFileRow idx + ILModuleRef(name = readStringHeap nameIdx, + hasMetadata= ((flags &&& 0x0001) = 0x0), + hash= readBlobHeapOption hashValueIdx) + + and seekReadClassLayout idx = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.ClassLayout,seekReadClassLayoutRow,(fun (_,_,tidx) -> tidx),simpleIndexCompare idx,isSorted ILTableNames.ClassLayout,(fun (pack,size,_) -> pack,size)) with + | None -> { Size = None; Pack = None } + | Some (pack,size) -> { Size = Some size; Pack = Some pack; } + + + and typeLayoutOfFlags flags tidx = + let f = (flags &&& 0x00000018) + if f = 0x00000008 then ILTypeDefLayout.Sequential (seekReadClassLayout tidx) + elif f = 0x00000010 then ILTypeDefLayout.Explicit (seekReadClassLayout tidx) + else ILTypeDefLayout.Auto + + and isTopTypeDef flags = + (ILTypeDefAccess.OfFlags flags = ILTypeDefAccess.Private) || + ILTypeDefAccess.OfFlags flags = ILTypeDefAccess.Public + + and seekIsTopTypeDefOfIdx idx = + let (flags,_,_, _, _,_) = seekReadTypeDefRow idx + isTopTypeDef flags + + and readStringHeapAsTypeName (nameIdx,namespaceIdx) = + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + nspace, name + + and seekReadTypeDefRowExtents _info (idx:int) = + if idx >= getNumRows ILTableNames.TypeDef then + getNumRows ILTableNames.Field + 1, + getNumRows ILTableNames.Method + 1 + else + let (_, _, _, _, fieldsIdx, methodsIdx) = seekReadTypeDefRow (idx + 1) + fieldsIdx, methodsIdx + + and seekReadTypeDefRowWithExtents (idx:int) = + let info= seekReadTypeDefRow idx + info,seekReadTypeDefRowExtents info idx + + and seekReadTypeDef toponly (idx:int) = + let (flags, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow idx + if toponly && not (isTopTypeDef flags) then None + else + + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + let rest = + lazy + let ((flags,nameIdx,namespaceIdx, extendsIdx, fieldsIdx, methodsIdx) as info) = seekReadTypeDefRow idx + let name = readStringHeap nameIdx + let nspace = readStringHeapOption namespaceIdx + let (endFieldsIdx, endMethodsIdx) = seekReadTypeDefRowExtents info idx + let typars = seekReadGenericParams 0 (TypeOrMethodDefTag.TypeDef,idx) + let numtypars = typars.Length + let super = seekReadOptionalTypeDefOrRef numtypars AsObject extendsIdx + let layout = typeLayoutOfFlags flags idx + //let hasLayout = (match layout with ILTypeDefLayout.Explicit _ -> true | _ -> false) + let hasLayout = false + let mdefs = seekReadMethods numtypars methodsIdx endMethodsIdx + let fdefs = seekReadFields (numtypars,hasLayout) fieldsIdx endFieldsIdx + let nested = seekReadNestedTypeDefs idx + let intfs = seekReadInterfaceImpls numtypars idx + //let sdecls = seekReadSecurityDecls (TaggedIndex(hds_TypeDef,idx)) + let mimpls = seekReadMethodImpls numtypars idx + let props = seekReadProperties numtypars idx + let events = seekReadEvents numtypars idx + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.TypeDef,idx)) + { Namespace=nspace + Name=name + GenericParams=typars + Attributes = enum flags + Layout = layout + NestedTypes= nested + Implements = intfs + Extends = super + Methods = mdefs + + //SecurityDecls = sdecls + //HasSecurity=(flags &&& 0x00040000) <> 0x0 + Fields=fdefs + MethodImpls=mimpls + Events= events + Properties=props + CustomAttrs=cas + Token = idx } + Some (nspace, name, rest) + + and seekReadTopTypeDefs () = + [| for i = 1 to getNumRows ILTableNames.TypeDef do + match seekReadTypeDef true i with + | None -> () + | Some td -> yield td |] + + and seekReadNestedTypeDefs tidx = + ILTypeDefs + (lazy + let nestedIdxs = seekReadIndexedRows (getNumRows ILTableNames.Nested,seekReadNestedRow,snd,simpleIndexCompare tidx,false,fst) + [| for i in nestedIdxs do + match seekReadTypeDef false i with + | None -> () + | Some td -> yield td |]) + + and seekReadInterfaceImpls numtypars tidx = + seekReadIndexedRows (getNumRows ILTableNames.InterfaceImpl,seekReadInterfaceImplRow ,fst,simpleIndexCompare tidx,isSorted ILTableNames.InterfaceImpl,(snd >> seekReadTypeDefOrRef numtypars AsObject [| |])) + + and seekReadGenericParams numtypars (a,b): ILGenericParameterDefs = + let pars = + seekReadIndexedRows + (getNumRows ILTableNames.GenericParam,seekReadGenericParamRow, + (fun (_,_,_,tomd,_) -> tomd), + tomdCompare (TaggedIndex(a,b)), + isSorted ILTableNames.GenericParam, + (fun (gpidx,seq,flags,_,nameIdx) -> + let constraints = seekReadGenericParamConstraintsUncached numtypars gpidx + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.GenericParam,gpidx)) + seq, {Name=readStringHeap nameIdx + Constraints= constraints + CustomAttrs=cas + Attributes = enum (int32 flags) + Token=gpidx })) + pars |> Array.sortBy fst |> Array.map snd + + and seekReadGenericParamConstraintsUncached numtypars gpidx = + seekReadIndexedRows + (getNumRows ILTableNames.GenericParamConstraint, + seekReadGenericParamConstraintRow, + fst, + simpleIndexCompare gpidx, + isSorted ILTableNames.GenericParamConstraint, + (snd >> seekReadTypeDefOrRef numtypars AsObject (*ok*) [| |])) + + and seekReadTypeDefAsType boxity (ginst:ILTypes) idx = cacheTypeDefAsType seekReadTypeDefAsTypeUncached (TypeDefAsTypIdx (boxity,ginst,idx)) + + and seekReadTypeDefAsTypeUncached (TypeDefAsTypIdx (boxity,ginst,idx)) = + mkILTy boxity (ILTypeSpec(seekReadTypeDefAsTypeRef idx, ginst)) + + and seekReadTypeDefAsTypeRef idx = + let enc = + if seekIsTopTypeDefOfIdx idx then ILTypeRefScope.Top ILScopeRef.Local + else + let enclIdx = seekReadIndexedRow (getNumRows ILTableNames.Nested,seekReadNestedRow,fst,simpleIndexCompare idx,isSorted ILTableNames.Nested,snd) + let tref = seekReadTypeDefAsTypeRef enclIdx + ILTypeRefScope.Nested tref + let (_, nameIdx, namespaceIdx, _, _, _) = seekReadTypeDefRow idx + let nsp, nm = readStringHeapAsTypeName (nameIdx,namespaceIdx) + ILTypeRef(enc=enc, nsp = nsp, name = nm ) + + and seekReadTypeRef idx = cacheTypeRef seekReadTypeRefUncached idx + and seekReadTypeRefUncached idx = + let scopeIdx,nameIdx,namespaceIdx = seekReadTypeRefRow idx + let enc = seekReadTypeRefScope scopeIdx + let nsp, nm = readStringHeapAsTypeName (nameIdx,namespaceIdx) + ILTypeRef(enc, nsp, nm) + + and seekReadTypeRefAsType boxity ginst idx = cacheTypeRefAsType seekReadTypeRefAsTypeUncached (TypeRefAsTypIdx (boxity,ginst,idx)) + and seekReadTypeRefAsTypeUncached (TypeRefAsTypIdx (boxity,ginst,idx)) = + mkILTy boxity (ILTypeSpec(seekReadTypeRef idx, ginst)) + + and seekReadTypeDefOrRef numtypars boxity (ginst:ILTypes) (TaggedIndex(tag,idx) ) = + match tag with + | tag when tag = TypeDefOrRefOrSpecTag.TypeDef -> seekReadTypeDefAsType boxity ginst idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeRef -> seekReadTypeRefAsType boxity ginst idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeSpec -> readBlobHeapAsType numtypars (seekReadTypeSpecRow idx) + | _ -> failwith "seekReadTypeDefOrRef" + + and seekReadTypeDefOrRefAsTypeRef (TaggedIndex(tag,idx) ) = + match tag with + | tag when tag = TypeDefOrRefOrSpecTag.TypeDef -> seekReadTypeDefAsTypeRef idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeRef -> seekReadTypeRef idx + | tag when tag = TypeDefOrRefOrSpecTag.TypeSpec -> ilg.typ_Object.TypeRef + | _ -> failwith "seekReadTypeDefOrRefAsTypeRef_readTypeDefOrRefOrSpec" + + and seekReadMethodRefParent numtypars (TaggedIndex(tag,idx)) = + match tag with + | tag when tag = MemberRefParentTag.TypeRef -> seekReadTypeRefAsType AsObject (* not ok - no way to tell if a member ref parent is a value type or not *) [| |] idx + | tag when tag = MemberRefParentTag.ModuleRef -> mkILTypeForGlobalFunctions (ILScopeRef.Module (seekReadModuleRef idx)) + | tag when tag = MemberRefParentTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + let mspec = mkILMethSpecInTyRaw(enclTyp, cc, nm, argtys, retty, minst) + mspec.EnclosingType + | tag when tag = MemberRefParentTag.TypeSpec -> readBlobHeapAsType numtypars (seekReadTypeSpecRow idx) + | _ -> failwith "seekReadMethodRefParent" + + + and seekReadMethodDefOrRef numtypars (TaggedIndex(tag, idx)) = + match tag with + | tag when tag = MethodDefOrRefTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + VarArgMethodData(enclTyp, cc, nm, argtys, None, retty, minst) + | tag when tag = MethodDefOrRefTag.MemberRef -> + seekReadMemberRefAsMethodData numtypars idx + | _ -> failwith "seekReadMethodDefOrRef ctxt" + + and seekReadMethodDefOrRefNoVarargs numtypars x = + let (VarArgMethodData(enclTyp, cc, nm, argtys, varargs, retty, minst)) = seekReadMethodDefOrRef numtypars x + MethodData(enclTyp, cc, nm, argtys, retty, minst) + + and seekReadCustomAttrType (TaggedIndex(tag,idx) ) = + match tag with + | tag when tag = CustomAttributeTypeTag.MethodDef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData idx + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst) + | tag when tag = CustomAttributeTypeTag.MemberRef -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMemberRefAsMethDataNoVarArgs 0 idx + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst) + | _ -> failwith "seekReadCustomAttrType" + + and seekReadImplAsScopeRef (TaggedIndex(tag,idx) ) = + if idx = 0 then ILScopeRef.Local + else + match tag with + | tag when tag = ImplementationTag.File -> ILScopeRef.Module (seekReadFile idx) + | tag when tag = ImplementationTag.AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef idx) + | tag when tag = ImplementationTag.ExportedType -> failwith "seekReadImplAsScopeRef" + | _ -> failwith "seekReadImplAsScopeRef" + + and seekReadTypeRefScope (TaggedIndex(tag,idx) ): ILTypeRefScope = + match tag with + | tag when tag = ResolutionScopeTag.Module -> ILTypeRefScope.Top(ILScopeRef.Local) + | tag when tag = ResolutionScopeTag.ModuleRef -> ILTypeRefScope.Top(ILScopeRef.Module (seekReadModuleRef idx)) + | tag when tag = ResolutionScopeTag.AssemblyRef -> ILTypeRefScope.Top(ILScopeRef.Assembly (seekReadAssemblyRef idx)) + | tag when tag = ResolutionScopeTag.TypeRef -> ILTypeRefScope.Nested (seekReadTypeRef idx) + | _ -> failwith "seekReadTypeRefScope" + + and seekReadOptionalTypeDefOrRef numtypars boxity idx = + if idx = TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, 0) then None + else Some (seekReadTypeDefOrRef numtypars boxity [| |] idx) + + and seekReadField (numtypars, hasLayout) (idx:int) = + let (flags,nameIdx,typeIdx) = seekReadFieldRow idx + let nm = readStringHeap nameIdx + let isStatic = (flags &&& 0x0010) <> 0 + { Name = nm + FieldType = readBlobHeapAsFieldSig numtypars typeIdx + LiteralValue = if (flags &&& 0x8000) = 0 then None else Some (seekReadConstant (TaggedIndex(HasConstantTag.FieldDef,idx))) + //Marshal = + // if (flags &&& 0x1000) = 0 then None else + // Some (seekReadIndexedRow (getNumRows ILTableNames.FieldMarshal,seekReadFieldMarshalRow, + // fst,hfmCompare (TaggedIndex(hfm_FieldDef,idx)), + // isSorted ILTableNames.FieldMarshal, + // (snd >> readBlobHeapAsNativeType ctxt))) + //Data = + // if (flags &&& 0x0100) = 0 then None + // else + // let rva = seekReadIndexedRow (getNumRows ILTableNames.FieldRVA,seekReadFieldRVARow, + // snd,simpleIndexCompare idx,isSorted ILTableNames.FieldRVA,fst) + // Some (rvaToData "field" rva) + Attributes = enum(flags) + Offset = + if hasLayout && not isStatic then + Some (seekReadIndexedRow (getNumRows ILTableNames.FieldLayout,seekReadFieldLayoutRow, + snd,simpleIndexCompare idx,isSorted ILTableNames.FieldLayout,fst)) else None + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.FieldDef,idx)) + Token = idx } + + and seekReadFields (numtypars, hasLayout) fidx1 fidx2 = + { new ILFieldDefs with + member _.Entries = + [| for i = fidx1 to fidx2 - 1 do + yield seekReadField (numtypars, hasLayout) i |] } + + and seekReadMethods numtypars midx1 midx2 = + ILMethodDefs + (lazy + [| for i = midx1 to midx2 - 1 do + yield seekReadMethod numtypars i |]) + + and sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr = + let n, sigptr = sigptrGetZInt32 bytes sigptr + if (n &&& 0x01) = 0x0 then (* Type Def *) + TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, (n >>>& 2)), sigptr + else (* Type Ref *) + TaggedIndex(TypeDefOrRefOrSpecTag.TypeRef, (n >>>& 2)), sigptr + + and sigptrGetTy numtypars bytes sigptr = + let b0,sigptr = sigptrGetByte bytes sigptr + if b0 = et_OBJECT then ilg.typ_Object , sigptr + elif b0 = et_STRING then ilg.typ_String, sigptr + elif b0 = et_I1 then ilg.typ_SByte, sigptr + elif b0 = et_I2 then ilg.typ_Int16, sigptr + elif b0 = et_I4 then ilg.typ_Int32, sigptr + elif b0 = et_I8 then ilg.typ_Int64, sigptr + elif b0 = et_I then ilg.typ_IntPtr, sigptr + elif b0 = et_U1 then ilg.typ_Byte, sigptr + elif b0 = et_U2 then ilg.typ_UInt16, sigptr + elif b0 = et_U4 then ilg.typ_UInt32, sigptr + elif b0 = et_U8 then ilg.typ_UInt64, sigptr + elif b0 = et_U then ilg.typ_UIntPtr, sigptr + elif b0 = et_R4 then ilg.typ_Single, sigptr + elif b0 = et_R8 then ilg.typ_Double, sigptr + elif b0 = et_CHAR then ilg.typ_Char, sigptr + elif b0 = et_BOOLEAN then ilg.typ_Boolean, sigptr + elif b0 = et_WITH then + let b0,sigptr = sigptrGetByte bytes sigptr + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let n, sigptr = sigptrGetZInt32 bytes sigptr + let argtys,sigptr = sigptrFold (sigptrGetTy numtypars) n bytes sigptr + seekReadTypeDefOrRef numtypars (if b0 = et_CLASS then AsObject else AsValue) argtys tdorIdx, + sigptr + + elif b0 = et_CLASS then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef numtypars AsObject [| |] tdorIdx, sigptr + elif b0 = et_VALUETYPE then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + seekReadTypeDefOrRef numtypars AsValue [| |] tdorIdx, sigptr + elif b0 = et_VAR then + let n, sigptr = sigptrGetZInt32 bytes sigptr + ILType.Var n,sigptr + elif b0 = et_MVAR then + let n, sigptr = sigptrGetZInt32 bytes sigptr + ILType.Var (n + numtypars), sigptr + elif b0 = et_BYREF then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Byref typ, sigptr + elif b0 = et_PTR then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Ptr typ, sigptr + elif b0 = et_SZARRAY then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + mkILArr1DTy typ, sigptr + elif b0 = et_ARRAY then + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + let rank, sigptr = sigptrGetZInt32 bytes sigptr + let numSized, sigptr = sigptrGetZInt32 bytes sigptr + let sizes, sigptr = sigptrFold sigptrGetZInt32 numSized bytes sigptr + let numLoBounded, sigptr = sigptrGetZInt32 bytes sigptr + let lobounds, sigptr = sigptrFold sigptrGetZInt32 numLoBounded bytes sigptr + let shape = + let dim i = + (if i < numLoBounded then Some lobounds.[i] else None), + (if i < numSized then Some sizes.[i] else None) + ILArrayShape (Array.init rank dim) + ILType.Array (shape, typ), sigptr + + elif b0 = et_VOID then ILType.Void, sigptr + elif b0 = et_TYPEDBYREF then + match ilg.typ_TypedReference with + | Some t -> t, sigptr + | _ -> failwith "system runtime doesn't contain System.TypedReference" + elif b0 = et_CMOD_REQD || b0 = et_CMOD_OPT then + let tdorIdx, sigptr = sigptrGetTypeDefOrRefOrSpecIdx bytes sigptr + let typ, sigptr = sigptrGetTy numtypars bytes sigptr + ILType.Modified((b0 = et_CMOD_REQD), seekReadTypeDefOrRefAsTypeRef tdorIdx, typ), sigptr + elif b0 = et_FNPTR then + let ccByte,sigptr = sigptrGetByte bytes sigptr + let generic,cc = byteAsCallConv ccByte + if generic then failwith "fptr sig may not be generic" + let numparams,sigptr = sigptrGetZInt32 bytes sigptr + let retty,sigptr = sigptrGetTy numtypars bytes sigptr + let argtys,sigptr = sigptrFold (sigptrGetTy numtypars) ( numparams) bytes sigptr + ILType.FunctionPointer (ILCallingSignature(cc, argtys, retty)),sigptr + elif b0 = et_SENTINEL then failwith "varargs NYI" + else ILType.Void , sigptr + + and sigptrGetVarArgTys n numtypars bytes sigptr = + sigptrFold (sigptrGetTy numtypars) n bytes sigptr + + and sigptrGetArgTys n numtypars bytes sigptr acc = + if n <= 0 then (Array.ofList (List.rev acc),None),sigptr + else + let b0,sigptr2 = sigptrGetByte bytes sigptr + if b0 = et_SENTINEL then + let varargs,sigptr = sigptrGetVarArgTys n numtypars bytes sigptr2 + (Array.ofList (List.rev acc),Some( varargs)),sigptr + else + let x,sigptr = sigptrGetTy numtypars bytes sigptr + sigptrGetArgTys (n-1) numtypars bytes sigptr (x::acc) + + and readBlobHeapAsMethodSig numtypars blobIdx = cacheBlobHeapAsMethodSig readBlobHeapAsMethodSigUncached (BlobAsMethodSigIdx (numtypars,blobIdx)) + + and readBlobHeapAsMethodSigUncached (BlobAsMethodSigIdx (numtypars,blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let ccByte,sigptr = sigptrGetByte bytes sigptr + let generic,cc = byteAsCallConv ccByte + let genarity,sigptr = if generic then sigptrGetZInt32 bytes sigptr else 0x0,sigptr + let numparams,sigptr = sigptrGetZInt32 bytes sigptr + let retty,sigptr = sigptrGetTy numtypars bytes sigptr + let (argtys,varargs),_sigptr = sigptrGetArgTys ( numparams) numtypars bytes sigptr [] + generic,genarity,cc,retty,argtys,varargs + + and readBlobHeapAsType numtypars blobIdx = + let bytes = readBlobHeap blobIdx + let ty,_sigptr = sigptrGetTy numtypars bytes 0 + ty + + and readBlobHeapAsFieldSig numtypars blobIdx = cacheBlobHeapAsFieldSig readBlobHeapAsFieldSigUncached (BlobAsFieldSigIdx (numtypars,blobIdx)) + + and readBlobHeapAsFieldSigUncached (BlobAsFieldSigIdx (numtypars,blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let _ccByte,sigptr = sigptrGetByte bytes sigptr + let retty,_sigptr = sigptrGetTy numtypars bytes sigptr + retty + + + and readBlobHeapAsPropertySig numtypars blobIdx = cacheBlobHeapAsPropertySig readBlobHeapAsPropertySigUncached (BlobAsPropSigIdx (numtypars,blobIdx)) + and readBlobHeapAsPropertySigUncached (BlobAsPropSigIdx (numtypars,blobIdx)) = + let bytes = readBlobHeap blobIdx + let sigptr = 0 + let ccByte,sigptr = sigptrGetByte bytes sigptr + let hasthis = byteAsHasThis ccByte + let numparams,sigptr = sigptrGetZInt32 bytes sigptr + let retty,sigptr = sigptrGetTy numtypars bytes sigptr + let argtys,_sigptr = sigptrFold (sigptrGetTy numtypars) ( numparams) bytes sigptr + hasthis,retty, argtys + + and byteAsHasThis b = + let hasthis_masked = b &&& 0x60uy + if hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE then ILThisConvention.Instance + elif hasthis_masked = e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT then ILThisConvention.InstanceExplicit + else ILThisConvention.Static + + and byteAsCallConv b = + let cc = + let ccMaxked = b &&& 0x0Fuy + if ccMaxked = e_IMAGE_CEE_CS_CALLCONV_FASTCALL then ILArgConvention.FastCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_STDCALL then ILArgConvention.StdCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_THISCALL then ILArgConvention.ThisCall + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_CDECL then ILArgConvention.CDecl + elif ccMaxked = e_IMAGE_CEE_CS_CALLCONV_VARARG then ILArgConvention.VarArg + else ILArgConvention.Default + let generic = (b &&& e_IMAGE_CEE_CS_CALLCONV_GENERIC) <> 0x0uy + generic, Callconv (byteAsHasThis b,cc) + + and seekReadMemberRefAsMethodData numtypars idx: VarArgMethodData = cacheMemberRefAsMemberData seekReadMemberRefAsMethodDataUncached (MemberRefAsMspecIdx (numtypars,idx)) + + and seekReadMemberRefAsMethodDataUncached (MemberRefAsMspecIdx (numtypars,idx)) = + let (mrpIdx,nameIdx,typeIdx) = seekReadMemberRefRow idx + let nm = readStringHeap nameIdx + let enclTyp = seekReadMethodRefParent numtypars mrpIdx + let _generic,genarity,cc,retty,argtys,varargs = readBlobHeapAsMethodSig enclTyp.GenericArgs.Length typeIdx + let minst = Array.init genarity (fun n -> ILType.Var (numtypars+n)) + (VarArgMethodData(enclTyp, cc, nm, argtys, varargs,retty,minst)) + + and seekReadMemberRefAsMethDataNoVarArgs numtypars idx: MethodData = + let (VarArgMethodData(enclTyp, cc, nm, argtys, _varargs, retty,minst)) = seekReadMemberRefAsMethodData numtypars idx + (MethodData(enclTyp, cc, nm, argtys, retty,minst)) + + // One extremely annoying aspect of the MD format is that given a + // ILMethodDef token it is non-trivial to find which ILTypeDef it belongs + // to. So we do a binary chop through the ILTypeDef table + // looking for which ILTypeDef has the ILMethodDef within its range. + // Although the ILTypeDef table is not "sorted", it is effectively sorted by + // method-range and field-range start/finish indexes + and seekReadMethodDefAsMethodData idx = cacheMethodDefAsMethodData seekReadMethodDefAsMethodDataUncached idx + and seekReadMethodDefAsMethodDataUncached idx = + let (_code_rva, _implflags, _flags, nameIdx, typeIdx, _paramIdx) = seekReadMethodRow idx + let nm = readStringHeap nameIdx + // Look for the method def parent. + let tidx = + seekReadIndexedRow (getNumRows ILTableNames.TypeDef, + (fun i -> i, seekReadTypeDefRowWithExtents i), + (fun r -> r), + (fun (_,((_, _, _, _, _, methodsIdx), + (_, endMethodsIdx))) -> + if endMethodsIdx <= idx then 1 + elif methodsIdx <= idx && idx < endMethodsIdx then 0 + else -1), + true,fst) + let _generic,_genarity,cc,retty,argtys,_varargs = readBlobHeapAsMethodSig 0 typeIdx + let ctps = seekReadGenericParams 0 (TypeOrMethodDefTag.TypeDef,tidx) + let mtps = seekReadGenericParams ctps.Length (TypeOrMethodDefTag.MethodDef,idx) + let finst = mkILFormalGenericArgs 0 ctps.Length + let minst = mkILFormalGenericArgs ctps.Length mtps.Length + let enclTyp = seekReadTypeDefAsType AsObject finst tidx + MethodData(enclTyp, cc, nm, argtys, retty, minst) + + and seekReadMethod numtypars (idx:int) = + let (_codeRVA, implflags, flags, nameIdx, typeIdx, paramIdx) = seekReadMethodRow idx + let nm = readStringHeap nameIdx + let _generic,_genarity,cc,retty,argtys,_varargs = readBlobHeapAsMethodSig numtypars typeIdx + + let endParamIdx = + if idx >= getNumRows ILTableNames.Method then + getNumRows ILTableNames.Param + 1 + else + let (_,_,_,_,_, paramIdx) = seekReadMethodRow (idx + 1) + paramIdx + + let ret,ilParams = seekReadParams (retty,argtys) paramIdx endParamIdx + + { Token=idx // This value is not a strict metadata token but it's good enough (if needed we could get the real one pretty easily) + Name=nm + Attributes = enum(flags) + //SecurityDecls=seekReadSecurityDecls (TaggedIndex(hds_MethodDef,idx)) + //IsEntryPoint= (fst entryPointToken = ILTableNames.Method && snd entryPointToken = idx) + ImplAttributes= enum implflags + GenericParams=seekReadGenericParams numtypars (TypeOrMethodDefTag.MethodDef,idx) + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.MethodDef,idx)) + Parameters= ilParams + CallingConv=cc + Return=ret + Body= None + //SecurityDecls + //HasSecurity= false + IsEntryPoint= false (* unused by reader *) + } + + + and seekReadParams (retty,argtys) pidx1 pidx2 = + let retRes: ILReturn ref = ref { (* Marshal=None *) Type=retty; CustomAttrs=ILCustomAttrsStatics.Empty } + let paramsRes = + argtys + |> Array.map (fun ty -> + { Name=UNone + Default=UNone + //Marshal=None + Attributes= ParameterAttributes.None + ParameterType=ty + CustomAttrs=ILCustomAttrsStatics.Empty }) + for i = pidx1 to pidx2 - 1 do + seekReadParamExtras (retRes,paramsRes) i + !retRes, paramsRes + + and seekReadParamExtras (retRes,paramsRes) (idx:int) = + let (flags,seq,nameIdx) = seekReadParamRow idx + //let _hasMarshal = (flags &&& 0x2000) <> 0x0 + let hasDefault = (flags &&& 0x1000) <> 0x0 + //let fmReader idx = seekReadIndexedRow (getNumRows ILTableNames.FieldMarshal,seekReadFieldMarshalRow,fst,hfmCompare idx,isSorted ILTableNames.FieldMarshal,(snd >> readBlobHeapAsNativeType ctxt)) + let cas = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ParamDef,idx)) + if seq = 0 then + retRes := { !retRes with + //Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef,idx))) else None); + CustomAttrs = cas } + else + paramsRes.[seq - 1] <- + { paramsRes.[seq - 1] with + //Marshal=(if hasMarshal then Some (fmReader (TaggedIndex(hfm_ParamDef,idx))) else None) + Default = (if hasDefault then USome (seekReadConstant (TaggedIndex(HasConstantTag.ParamDef,idx))) else UNone) + Name = readStringHeapOption nameIdx + Attributes = enum flags + CustomAttrs = cas } + + and seekReadMethodImpls numtypars tidx = + { new ILMethodImplDefs with + member _.Entries = + let mimpls = seekReadIndexedRows (getNumRows ILTableNames.MethodImpl,seekReadMethodImplRow,(fun (a,_,_) -> a),simpleIndexCompare tidx,isSorted ILTableNames.MethodImpl,(fun (_,b,c) -> b,c)) + mimpls |> Array.map (fun (b,c) -> + { OverrideBy= + let (MethodData(enclTyp, cc, nm, argtys, retty,minst)) = seekReadMethodDefOrRefNoVarargs numtypars b + mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty,minst); + Overrides= + let (MethodData(enclTyp, cc, nm, argtys, retty,minst)) = seekReadMethodDefOrRefNoVarargs numtypars c + let mspec = mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty,minst) + OverridesSpec(mspec.MethodRef, mspec.EnclosingType) }) } + + and seekReadMultipleMethodSemantics (flags,id) = + seekReadIndexedRows + (getNumRows ILTableNames.MethodSemantics , + seekReadMethodSemanticsRow, + (fun (_flags,_,c) -> c), + hsCompare id, + isSorted ILTableNames.MethodSemantics, + (fun (a,b,_c) -> + let (MethodData(enclTyp, cc, nm, argtys, retty, minst)) = seekReadMethodDefAsMethodData b + a, (mkILMethSpecInTyRaw (enclTyp, cc, nm, argtys, retty, minst)).MethodRef)) + |> Array.filter (fun (flags2,_) -> flags = flags2) + |> Array.map snd + + + and seekReadOptionalMethodSemantics id = + match seekReadMultipleMethodSemantics id with + | [| |] -> None + | xs -> Some xs.[0] + + and seekReadMethodSemantics id = + match seekReadOptionalMethodSemantics id with + | None -> failwith "seekReadMethodSemantics ctxt: no method found" + | Some x -> x + + and seekReadEvent _numtypars idx = + let (flags,nameIdx,_typIdx) = seekReadEventRow idx + { Name = readStringHeap nameIdx + //EventHandlerType = seekReadOptionalTypeDefOrRef numtypars AsObject typIdx + Attributes = enum(flags) + AddMethod= seekReadMethodSemantics (0x0008,TaggedIndex(HasSemanticsTag.Event, idx)) + RemoveMethod=seekReadMethodSemantics (0x0010,TaggedIndex(HasSemanticsTag.Event,idx)) + //FireMethod=seekReadOptionalMethodSemantics (0x0020,TaggedIndex(HasSemanticsTag.Event,idx)) + //OtherMethods = seekReadMultipleMethodSemantics (0x0004, TaggedIndex(HasSemanticsTag.Event, idx)) + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Event,idx)) + Token = idx} + + and seekReadEvents numtypars tidx = + { new ILEventDefs with + member _.Entries = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.EventMap,(fun i -> i, seekReadEventMapRow i),(fun (_,row) -> fst row),compare tidx,false,(fun (i,row) -> (i,snd row))) with + | None -> [| |] + | Some (rowNum,beginEventIdx) -> + let endEventIdx = + if rowNum >= getNumRows ILTableNames.EventMap then + getNumRows ILTableNames.Event + 1 + else + let (_, endEventIdx) = seekReadEventMapRow (rowNum + 1) + endEventIdx + + [| for i in beginEventIdx .. endEventIdx - 1 do + yield seekReadEvent numtypars i |] } + + and seekReadProperty numtypars idx = + let (flags,nameIdx,typIdx) = seekReadPropertyRow idx + let cc,retty,argtys = readBlobHeapAsPropertySig numtypars typIdx + let setter= seekReadOptionalMethodSemantics (0x0001,TaggedIndex(HasSemanticsTag.Property,idx)) + let getter = seekReadOptionalMethodSemantics (0x0002,TaggedIndex(HasSemanticsTag.Property,idx)) + let cc2 = + match getter with + | Some mref -> mref.CallingConv.ThisConv + | None -> + match setter with + | Some mref -> mref.CallingConv .ThisConv + | None -> cc + { Name=readStringHeap nameIdx + CallingConv = cc2 + Attributes = enum(flags) + SetMethod=setter; + GetMethod=getter; + PropertyType=retty; + Init= if (flags &&& 0x1000) = 0 then None else Some (seekReadConstant (TaggedIndex(HasConstantTag.Property,idx))); + IndexParameterTypes=argtys; + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.Property,idx)) + Token = idx } + + and seekReadProperties numtypars tidx = + { new ILPropertyDefs with + member _.Entries = + match seekReadOptionalIndexedRow (getNumRows ILTableNames.PropertyMap,(fun i -> i, seekReadPropertyMapRow i),(fun (_,row) -> fst row),compare tidx,false,(fun (i,row) -> (i,snd row))) with + | None -> [| |] + | Some (rowNum,beginPropIdx) -> + let endPropIdx = + if rowNum >= getNumRows ILTableNames.PropertyMap then + getNumRows ILTableNames.Property + 1 + else + let (_, endPropIdx) = seekReadPropertyMapRow (rowNum + 1) + endPropIdx + [| for i in beginPropIdx .. endPropIdx - 1 do + yield seekReadProperty numtypars i |] } + + + and seekReadCustomAttrs idx = + { new ILCustomAttrs with + member _.Entries = + seekReadIndexedRows (getNumRows ILTableNames.CustomAttribute, + seekReadCustomAttributeRow,(fun (a,_,_) -> a), + hcaCompare idx, + isSorted ILTableNames.CustomAttribute, + (fun (_,b,c) -> seekReadCustomAttr (b,c))) } + + and seekReadCustomAttr (catIdx,valIdx) = + let data = + match readBlobHeapOption valIdx with + | USome bytes -> bytes + | UNone -> [| |] + { Method=seekReadCustomAttrType catIdx; + Data= data + Elements = [] } + + (* + and seekReadSecurityDecls idx = + mkILLazySecurityDecls + (lazy + seekReadIndexedRows (getNumRows ILTableNames.Permission, + seekReadPermissionRow, + (fun (_,par,_) -> par), + hdsCompare idx, + isSorted ILTableNames.Permission, + (fun (act,_,ty) -> seekReadSecurityDecl (act,ty)))) + + and seekReadSecurityDecl (a,b) = + ctxt.seekReadSecurityDecl (SecurityDeclIdx (a,b)) + + and seekReadSecurityDeclUncached ctxtH (SecurityDeclIdx (act,ty)) = + PermissionSet ((if List.memAssoc (int act) (Lazy.force ILSecurityActionRevMap) then List.assoc (int act) (Lazy.force ILSecurityActionRevMap) else failwith "unknown security action"), + readBlobHeap ty) + + *) + + and seekReadConstant idx = + let kind,vidx = seekReadIndexedRow (getNumRows ILTableNames.Constant, + seekReadConstantRow, + (fun (_,key,_) -> key), + hcCompare idx,isSorted ILTableNames.Constant,(fun (kind,_,v) -> kind,v)) + match kind with + | x when x = uint16 et_STRING -> + let blobHeap = readBlobHeap vidx + let s = Encoding.Unicode.GetString(blobHeap, 0, blobHeap.Length) + box s + | x when x = uint16 et_BOOLEAN -> box (readBlobHeapAsBool vidx) + | x when x = uint16 et_CHAR -> box (readBlobHeapAsUInt16 vidx) + | x when x = uint16 et_I1 -> box (readBlobHeapAsSByte vidx) + | x when x = uint16 et_I2 -> box (readBlobHeapAsInt16 vidx) + | x when x = uint16 et_I4 -> box (readBlobHeapAsInt32 vidx) + | x when x = uint16 et_I8 -> box (readBlobHeapAsInt64 vidx) + | x when x = uint16 et_U1 -> box (readBlobHeapAsByte vidx) + | x when x = uint16 et_U2 -> box (readBlobHeapAsUInt16 vidx) + | x when x = uint16 et_U4 -> box (readBlobHeapAsUInt32 vidx) + | x when x = uint16 et_U8 -> box (readBlobHeapAsUInt64 vidx) + | x when x = uint16 et_R4 -> box (readBlobHeapAsSingle vidx) + | x when x = uint16 et_R8 -> box (readBlobHeapAsDouble vidx) + | x when x = uint16 et_CLASS || x = uint16 et_OBJECT -> null + | _ -> null + + and seekReadManifestResources () = + ILResources + (lazy + [| for i = 1 to getNumRows ILTableNames.ManifestResource do + let (offset,flags,nameIdx,implIdx) = seekReadManifestResourceRow i + let scoref = seekReadImplAsScopeRef implIdx + let datalab = + match scoref with + | ILScopeRef.Local -> + let start = anyV2P ("resource",offset + resourcesAddr) + let len = seekReadInt32 is start + ILResourceLocation.Local (fun () -> seekReadBytes is (start + 4) len) + | ILScopeRef.Module mref -> ILResourceLocation.File (mref,offset) + | ILScopeRef.Assembly aref -> ILResourceLocation.Assembly aref + + let r = + { Name= readStringHeap nameIdx; + Location = datalab; + Access = (if (flags &&& 0x01) <> 0x0 then ILResourceAccess.Public else ILResourceAccess.Private); + CustomAttrs = seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ManifestResource, i)) } + yield r |]) + + and seekReadNestedExportedTypes parentIdx = + ILNestedExportedTypesAndForwarders + (lazy + [| for i = 1 to getNumRows ILTableNames.ExportedType do + let (flags,_tok,nameIdx,namespaceIdx,implIdx) = seekReadExportedTypeRow i + if not (isTopTypeDef flags) then + let (TaggedIndex(tag,idx) ) = implIdx + match tag with + | tag when tag = ImplementationTag.ExportedType && idx = parentIdx -> + let _nsp, nm = readStringHeapAsTypeName (nameIdx,namespaceIdx) + yield + { Name=nm + Access=(match ILTypeDefAccess.OfFlags flags with ILTypeDefAccess.Nested n -> n | _ -> failwith "non-nested access for a nested type described as being in an auxiliary module") + Nested=seekReadNestedExportedTypes i + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ExportedType, i)) } + | _ -> () |]) + + and seekReadTopExportedTypes () = + ILExportedTypesAndForwarders + (lazy + [| for i = 1 to getNumRows ILTableNames.ExportedType do + let (flags,_tok,nameIdx,namespaceIdx,implIdx) = seekReadExportedTypeRow i + if isTopTypeDef flags then + let (TaggedIndex(tag,_idx) ) = implIdx + + // the nested types will be picked up by their enclosing types + if tag <> ImplementationTag.ExportedType then + let nsp, nm = readStringHeapAsTypeName (nameIdx,namespaceIdx) + + let scoref = seekReadImplAsScopeRef implIdx + + let entry = + { ScopeRef=scoref + Namespace=nsp + Name=nm + IsForwarder = ((flags &&& 0x00200000) <> 0) + Access=ILTypeDefAccess.OfFlags flags + Nested=seekReadNestedExportedTypes i + CustomAttrs=seekReadCustomAttrs (TaggedIndex(HasCustomAttributeTag.ExportedType, i)) } + yield entry |]) + + + let ilModule = seekReadModule (subsys, (subsysMajor, subsysMinor), useHighEntropyVA, ilOnly, only32, is32bitpreferred, only64, platform, isDll, alignVirt, alignPhys, imageBaseReal, ilMetadataVersion) 1 + let ilAssemblyRefs = [ for i in 1 .. getNumRows ILTableNames.AssemblyRef do yield seekReadAssemblyRef i ] + + member _.Bytes = is.Bytes + member _.ILGlobals = ilg + member _.ILModuleDef = ilModule + member _.ILAssemblyRefs = ilAssemblyRefs + + let sigptr_get_byte (bytes: byte[]) sigptr = + int bytes.[sigptr], sigptr + 1 + + let sigptr_get_u8 bytes sigptr = + let b0,sigptr = sigptr_get_byte bytes sigptr + byte b0,sigptr + + let sigptr_get_bool bytes sigptr = + let b0,sigptr = sigptr_get_byte bytes sigptr + (b0 = 0x01) ,sigptr + + let sigptr_get_i8 bytes sigptr = + let i,sigptr = sigptr_get_u8 bytes sigptr + sbyte i,sigptr + + let sigptr_get_u16 bytes sigptr = + let b0,sigptr = sigptr_get_byte bytes sigptr + let b1,sigptr = sigptr_get_byte bytes sigptr + uint16 (b0 ||| (b1 <<< 8)),sigptr + + let sigptr_get_i16 bytes sigptr = + let u,sigptr = sigptr_get_u16 bytes sigptr + int16 u,sigptr + + let sigptr_get_i32 bytes sigptr = + let b0,sigptr = sigptr_get_byte bytes sigptr + let b1,sigptr = sigptr_get_byte bytes sigptr + let b2,sigptr = sigptr_get_byte bytes sigptr + let b3,sigptr = sigptr_get_byte bytes sigptr + b0 ||| (b1 <<< 8) ||| (b2 <<< 16) ||| (b3 <<< 24),sigptr + + let sigptr_get_u32 bytes sigptr = + let u,sigptr = sigptr_get_i32 bytes sigptr + uint32 u,sigptr + + let sigptr_get_i64 bytes sigptr = + let b0,sigptr = sigptr_get_byte bytes sigptr + let b1,sigptr = sigptr_get_byte bytes sigptr + let b2,sigptr = sigptr_get_byte bytes sigptr + let b3,sigptr = sigptr_get_byte bytes sigptr + let b4,sigptr = sigptr_get_byte bytes sigptr + let b5,sigptr = sigptr_get_byte bytes sigptr + let b6,sigptr = sigptr_get_byte bytes sigptr + let b7,sigptr = sigptr_get_byte bytes sigptr + int64 b0 ||| (int64 b1 <<< 8) ||| (int64 b2 <<< 16) ||| (int64 b3 <<< 24) ||| + (int64 b4 <<< 32) ||| (int64 b5 <<< 40) ||| (int64 b6 <<< 48) ||| (int64 b7 <<< 56), + sigptr + + let sigptr_get_u64 bytes sigptr = + let u,sigptr = sigptr_get_i64 bytes sigptr + uint64 u,sigptr + + + let ieee32_of_bits (x:int32) = System.BitConverter.ToSingle(System.BitConverter.GetBytes(x),0) + let ieee64_of_bits (x:int64) = System.BitConverter.Int64BitsToDouble(x) + + let sigptr_get_ieee32 bytes sigptr = + let u,sigptr = sigptr_get_i32 bytes sigptr + ieee32_of_bits u,sigptr + + let sigptr_get_ieee64 bytes sigptr = + let u,sigptr = sigptr_get_i64 bytes sigptr + ieee64_of_bits u,sigptr + + let u8AsBytes (i:byte) = [| i |] + let u16AsBytes x = let n = (int x) in [| b0 n; b1 n |] + let i32AsBytes i = [| b0 i; b1 i; b2 i; b3 i |] + let i64AsBytes i = [| dw0 i; dw1 i; dw2 i; dw3 i; dw4 i; dw5 i; dw6 i; dw7 i |] + + let i8AsBytes (i:sbyte) = u8AsBytes (byte i) + let i16AsBytes (i:int16) = u16AsBytes (uint16 i) + let u32AsBytes (i:uint32) = i32AsBytes (int32 i) + let u64AsBytes (i:uint64) = i64AsBytes (int64 i) + let bits_of_float32 (x:float32) = BitConverter.ToInt32(BitConverter.GetBytes(x),0) + let bits_of_float (x:float) = BitConverter.DoubleToInt64Bits(x) + + let ieee32AsBytes i = i32AsBytes (bits_of_float32 i) + let ieee64AsBytes i = i64AsBytes (bits_of_float i) + + + let (|ElementType|_|) (ty: ILType) = + match ty with + | ILType.Boxed tspec -> + match tspec.Namespace, tspec.Name with + | USome "System", "String"-> Some et_STRING + | USome "System", "Object"-> Some et_OBJECT + | _ -> None + | ILType.Value tspec -> + match tspec.Namespace, tspec.Name with + | USome "System", "Int32" -> Some et_I4 + | USome "System", "SByte" -> Some et_I1 + | USome "System", "Int16"-> Some et_I2 + | USome "System", "Int64" -> Some et_I8 + | USome "System", "IntPtr" -> Some et_I + | USome "System", "Byte" -> Some et_U1 + | USome "System", "UInt16"-> Some et_U2 + | USome "System", "UInt32" -> Some et_U4 + | USome "System", "UInt64" -> Some et_U8 + | USome "System", "UIntPtr" -> Some et_U + | USome "System", "Double" -> Some et_R8 + | USome "System", "Single" -> Some et_R4 + | USome "System", "Char" -> Some et_CHAR + | USome "System", "Boolean" -> Some et_BOOLEAN + | USome "System", "TypedReference" -> Some et_TYPEDBYREF + | _ -> None + | _ -> None + + let encodeCustomAttrString (s: string) = + let arr = Encoding.UTF8.GetBytes s + Array.concat [ ByteBuffer.Z32 arr.Length; arr ] + + let rec encodeCustomAttrElemType x = + match x with + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Object" -> [| 0x51uy |] + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Type" -> [| 0x50uy |] + | ElementType et -> [| et |] + | ILType.Value tspec -> Array.append [| 0x55uy |] (encodeCustomAttrString tspec.TypeRef.QualifiedName) + | ILType.Array (shape, elemType) when shape = ILArrayShape.SingleDimensional -> + Array.append [| et_SZARRAY |] (encodeCustomAttrElemType elemType) + | _ -> failwith "encodeCustomAttrElemType: unrecognized custom element type" + + /// Given a custom attribute element, work out the type of the .NET argument for that element. + let rec encodeCustomAttrElemTypeForObject (x: obj) = + match x with + | :? string -> [| et_STRING |] + | :? bool -> [| et_BOOLEAN |] + | :? char -> [| et_CHAR |] + | :? sbyte -> [| et_I1 |] + | :? int16 -> [| et_I2 |] + | :? int32 -> [| et_I4 |] + | :? int64 -> [| et_I8 |] + | :? byte -> [| et_U1 |] + | :? uint16 -> [| et_U2 |] + | :? uint32 -> [| et_U4 |] + | :? uint64 -> [| et_U8 |] + | :? ILType -> [| 0x50uy |] + | :? Type -> [| 0x50uy |] + | null -> [| et_STRING |]// yes, the 0xe prefix is used when passing a "null" to a property or argument of type "object" here + | :? single -> [| et_R4 |] + | :? double -> [| et_R8 |] + | :? (obj[]) -> failwith "TODO: can't yet emit arrays in attrs" // [| yield et_SZARRAY; yield! encodeCustomAttrElemType elemTy |] + | _ -> failwith "unexpected value in custom attribute" + + /// Given a custom attribute element, encode it to a binary representation according to the rules in Ecma 335 Partition II. + let rec encodeCustomAttrPrimValue (c: obj) = + match c with + | :? bool as b -> [| (if b then 0x01uy else 0x00uy) |] + | null -> [| 0xFFuy |] + | :? string as s -> encodeCustomAttrString s + | :? char as x -> u16AsBytes (uint16 x) + | :? SByte as x -> i8AsBytes x + | :? Int16 as x -> i16AsBytes x + | :? Int32 as x -> i32AsBytes x + | :? Int64 as x -> i64AsBytes x + | :? Byte as x -> u8AsBytes x + | :? UInt16 as x -> u16AsBytes x + | :? UInt32 as x -> u32AsBytes x + | :? UInt64 as x -> u64AsBytes x + | :? Single as x -> ieee32AsBytes x + | :? Double as x -> ieee64AsBytes x + | :? ILType as ty -> encodeCustomAttrString ty.QualifiedName + | :? Type as ty -> encodeCustomAttrString ty.FullName + | :? (obj[]) as elems -> + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue elem |] + | _ -> failwith "unexpected value in custom attribute" + + and encodeCustomAttrValue ty (c: obj) = + match ty, c with + | ILType.Boxed tspec, _ when tspec.Namespace = USome "System" && tspec.Name = "Object" -> + [| yield! encodeCustomAttrElemTypeForObject c; yield! encodeCustomAttrPrimValue c |] + | ILType.Array (shape, _), null when shape = ILArrayShape.SingleDimensional -> + [| yield! i32AsBytes 0xFFFFFFFF |] + | ILType.Array (shape, elemType), (:? (obj[]) as elems) when shape = ILArrayShape.SingleDimensional -> + [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrValue elemType elem |] + | _ -> + encodeCustomAttrPrimValue c + + let encodeCustomAttrNamedArg prop (ILCustomAttrNamedArg (nm, ty, elem)) = + [| yield (if prop then 0x54uy else 0x53uy) + yield! encodeCustomAttrElemType ty + yield! encodeCustomAttrString nm + yield! encodeCustomAttrValue ty elem |] + + let mkILCustomAttribMethRef (mspec:ILMethodSpec, fixedArgs: obj list, propArgs: ILCustomAttrNamedArg list, fieldArgs: ILCustomAttrNamedArg list) = + let argtys = mspec.MethodRef.ArgTypes + let nnamed = propArgs.Length + fieldArgs.Length + let data = + [| yield! [| 0x01uy; 0x00uy; |] + for (argty,fixedArg) in Seq.zip argtys fixedArgs do + yield! encodeCustomAttrValue argty fixedArg + yield! u16AsBytes (uint16 nnamed ) + for arg in propArgs do + yield! encodeCustomAttrNamedArg true arg + for arg in fieldArgs do + yield! encodeCustomAttrNamedArg false arg |] + //printfn "mkILCustomAttribMethRef, nnamed = %d, data.Length = %d, data = %A" nnamed data.Length data + { Method = mspec; + Data = data; + Elements = fixedArgs @ (propArgs |> List.map(fun (ILCustomAttrNamedArg(_,_,e)) -> e)) @ (fieldArgs |> List.map(fun (ILCustomAttrNamedArg(_,_,e)) -> e)) } + + let rec decodeCustomAttrElemType ilg bytes sigptr x = + match x with + | x when x = et_I1 -> ilg.typ_SByte, sigptr + | x when x = et_U1 -> ilg.typ_Byte, sigptr + | x when x = et_I2 -> ilg.typ_Int16, sigptr + | x when x = et_U2 -> ilg.typ_UInt16, sigptr + | x when x = et_I4 -> ilg.typ_Int32, sigptr + | x when x = et_U4 -> ilg.typ_UInt32, sigptr + | x when x = et_I8 -> ilg.typ_Int64, sigptr + | x when x = et_U8 -> ilg.typ_UInt64, sigptr + | x when x = et_R8 -> ilg.typ_Double, sigptr + | x when x = et_R4 -> ilg.typ_Single, sigptr + | x when x = et_CHAR -> ilg.typ_Char, sigptr + | x when x = et_BOOLEAN -> ilg.typ_Boolean, sigptr + | x when x = et_STRING -> ilg.typ_String, sigptr + | x when x = et_OBJECT -> ilg.typ_Object, sigptr + | x when x = et_SZARRAY -> + let et,sigptr = sigptr_get_u8 bytes sigptr + let elemTy,sigptr = decodeCustomAttrElemType ilg bytes sigptr et + mkILArr1DTy elemTy, sigptr + | x when x = 0x50uy -> ilg.typ_Type, sigptr + | _ -> failwithf "decodeCustomAttrElemType ilg: sigptr = %d, unrecognized custom element type: %A, bytes = %A" sigptr x bytes + + // Parse an IL type signature argument within a custom attribute blob + type ILTypeSigParser(tstring: string) = + + let mutable startPos = 0 + let mutable currentPos = 0 + + //let reset() = startPos <- 0 ; currentPos <- 0 + let nil = '\r' // cannot appear in a type sig + + // take a look at the next value, but don't advance + let peek() = if currentPos < (tstring.Length-1) then tstring.[currentPos+1] else nil + let peekN(skip) = if currentPos < (tstring.Length - skip) then tstring.[currentPos+skip] else nil + // take a look at the current value, but don't advance + let here() = if currentPos < tstring.Length then tstring.[currentPos] else nil + // move on to the next character + let step() = currentPos <- currentPos+1 + // ignore the current lexeme + let skip() = startPos <- currentPos + // ignore the current lexeme, advance + let drop() = skip() ; step() ; skip() + // return the current lexeme, advance + let take() = + let s = if currentPos < tstring.Length then tstring.[startPos..currentPos] else "" + drop() + s + + // The format we accept is + // "{`[,+]}{}{}" E.g., + // + // System.Collections.Generic.Dictionary + // `2[ + // [System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], + // dev.virtualearth.net.webservices.v1.search.CategorySpecificPropertySet], + // mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" + // + // Note that + // • Since we're only reading valid IL, we assume that the signature is properly formed + // • For type parameters, if the type is non-local, it will be wrapped in brackets ([]) + member x.ParseType() = + + // Does the type name start with a leading '['? If so, ignore it + // (if the specialization type is in another module, it will be wrapped in bracket) + if here() = '[' then drop() + + // 1. Iterate over beginning of type, grabbing the type name and determining if it's generic or an array + let typeName = + while (peek() <> '`') && (peek() <> '[') && (peek() <> ']') && (peek() <> ',') && (peek() <> nil) do step() + take() + + // 2. Classify the type + + // Is the type generic? + let typeName, specializations = + if here() = '`' then + drop() // step to the number + // fetch the arity + let arity = + while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step() + System.Int32.Parse(take()) + + // typically types are saturated, i.e. if generic they have arguments. However, assembly metadata for reflectedDefinitions they occur free. + // this code takes care of exactly this case. + if here () = '[' then + // skip the '[' + drop() + // get the specializations + typeName+"`"+(arity.ToString()), Some(([| for _i in 0..arity-1 do yield x.ParseType() |])) + else + typeName+"`"+(arity.ToString()), None + else + typeName, None + + // Is the type an array? + let rank = + if here() = '[' then + let mutable rank = 0 + + while here() <> ']' do + rank <- rank + 1 + step() + drop() + + Some(ILArrayShape(Array.create rank (Some 0, None))) + else + None + + // Is there a scope? + let scope = + if (here() = ',' || here() = ' ') && (peek() <> '[' && peekN(2) <> '[') then + let grabScopeComponent() = + if here() = ',' then drop() // ditch the ',' + if here() = ' ' then drop() // ditch the ' ' + + while (peek() <> ',' && peek() <> ']' && peek() <> nil) do step() + take() + + let scope = + [ yield grabScopeComponent() // assembly + yield grabScopeComponent() // version + yield grabScopeComponent() // culture + yield grabScopeComponent() // public key token + ] |> String.concat "," + ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(scope))) + else + ILScopeRef.Local + + // strip any extraneous trailing brackets or commas + if (here() = ']') then drop() + if (here() = ',') then drop() + + // build the IL type + let tref = + let nsp, nm = splitILTypeName typeName + ILTypeRef(ILTypeRefScope.Top scope, nsp, nm) + + let genericArgs = + match specializations with + | None -> [| |] + | Some(genericArgs) -> genericArgs + let tspec = ILTypeSpec(tref,genericArgs) + let ilty = + match tspec.Name with + | "System.SByte" + | "System.Byte" + | "System.Int16" + | "System.UInt16" + | "System.Int32" + | "System.UInt32" + | "System.Int64" + | "System.UInt64" + | "System.Char" + | "System.Double" + | "System.Single" + | "System.Boolean" -> ILType.Value(tspec) + | _ -> ILType.Boxed(tspec) + + // if it's an array, wrap it - otherwise, just return the IL type + match rank with + | Some(r) -> ILType.Array(r,ilty) + | _ -> ilty + + + let sigptr_get_bytes n (bytes:byte[]) sigptr = + let res = Array.zeroCreate n + for i = 0 to n - 1 do + res.[i] <- bytes.[sigptr + i] + res, sigptr + n + + let sigptr_get_string n bytes sigptr = + let intarray,sigptr = sigptr_get_bytes n bytes sigptr + Encoding.UTF8.GetString(intarray , 0, intarray.Length), sigptr + + let sigptr_get_serstring bytes sigptr = + let len,sigptr = sigptrGetZInt32 bytes sigptr + sigptr_get_string len bytes sigptr + + let sigptr_get_serstring_possibly_null bytes sigptr = + let b0,new_sigptr = sigptr_get_byte bytes sigptr + if b0 = 0xFF then // null case + None,new_sigptr + else // throw away new_sigptr, getting length & text advance + let len,sigptr = sigptrGetZInt32 bytes sigptr + let s, sigptr = sigptr_get_string len bytes sigptr + Some(s),sigptr + + let decodeILCustomAttribData ilg (ca: ILCustomAttribute) = + let bytes = ca.Data + let sigptr = 0 + let bb0,sigptr = sigptr_get_byte bytes sigptr + let bb1,sigptr = sigptr_get_byte bytes sigptr + if not (bb0 = 0x01 && bb1 = 0x00) then failwith "decodeILCustomAttribData: invalid data"; + + let rec parseVal argty sigptr = + match argty with + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "SByte" -> + let n,sigptr = sigptr_get_i8 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Byte" -> + let n,sigptr = sigptr_get_u8 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int16" -> + let n,sigptr = sigptr_get_i16 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt16" -> + let n,sigptr = sigptr_get_u16 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int32" -> + let n,sigptr = sigptr_get_i32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt32" -> + let n,sigptr = sigptr_get_u32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Int64" -> + let n,sigptr = sigptr_get_i64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "UInt64" -> + let n,sigptr = sigptr_get_u64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Double" -> + let n,sigptr = sigptr_get_ieee64 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Single" -> + let n,sigptr = sigptr_get_ieee32 bytes sigptr + (argty, box n), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Char" -> + let n,sigptr = sigptr_get_u16 bytes sigptr + (argty, box (char n)), sigptr + | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Boolean" -> + let n,sigptr = sigptr_get_byte bytes sigptr + (argty, box (not (n = 0))), sigptr + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "String" -> + //printfn "parsing string, sigptr = %d" sigptr + let n,sigptr = sigptr_get_serstring_possibly_null bytes sigptr + //printfn "got string, sigptr = %d" sigptr + (argty, box (match n with None -> null | Some s -> s)), sigptr + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Type" -> + let nOpt,sigptr = sigptr_get_serstring_possibly_null bytes sigptr + match nOpt with + | None -> (argty, box null) , sigptr // TODO: read System.Type attrs + | Some n -> + try + let parser = ILTypeSigParser(n) + parser.ParseType() |> ignore + (argty, box null) , sigptr // TODO: read System.Type attributes + with e -> + failwithf "decodeILCustomAttribData: error parsing type in custom attribute blob: %s" e.Message + | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Object" -> + let et,sigptr = sigptr_get_u8 bytes sigptr + if et = 0xFFuy then + (argty, null), sigptr + else + let ty,sigptr = decodeCustomAttrElemType ilg bytes sigptr et + parseVal ty sigptr + | ILType.Array(shape,elemTy) when shape = ILArrayShape.SingleDimensional -> + let n,sigptr = sigptr_get_i32 bytes sigptr + if n = 0xFFFFFFFF then (argty, null),sigptr else + let rec parseElems acc n sigptr = + if n = 0 then List.rev acc, sigptr else + let v,sigptr = parseVal elemTy sigptr + parseElems (v ::acc) (n-1) sigptr + let elems, sigptr = parseElems [] n sigptr + let elems = elems |> List.map snd |> List.toArray + (argty, box elems), sigptr + | ILType.Value _ -> (* assume it is an enumeration *) + let n,sigptr = sigptr_get_i32 bytes sigptr + (argty, box n), sigptr + | _ -> failwith "decodeILCustomAttribData: attribute data involves an enum or System.Type value" + + let rec parseFixed argtys sigptr = + match argtys with + | [] -> [],sigptr + | h::t -> + let nh,sigptr = parseVal h sigptr + let nt,sigptr = parseFixed t sigptr + nh ::nt, sigptr + + let fixedArgs,sigptr = parseFixed (List.ofArray ca.Method.FormalArgTypes) sigptr + let nnamed,sigptr = sigptr_get_u16 bytes sigptr + //printfn "nnamed = %d" nnamed + + try + let rec parseNamed acc n sigptr = + if n = 0 then List.rev acc else + let isPropByte,sigptr = sigptr_get_u8 bytes sigptr + let isProp = (int isPropByte = 0x54) + let et,sigptr = sigptr_get_u8 bytes sigptr + // We have a named value + let ty,sigptr = + if ((* 0x50 = (int et) || *) 0x55 = (int et)) then + let qualified_tname,sigptr = sigptr_get_serstring bytes sigptr + let unqualified_tname, rest = + let pieces = qualified_tname.Split(',') + if pieces.Length > 1 then + pieces.[0], Some (String.concat "," pieces.[1..]) + else + pieces.[0], None + let scoref = + match rest with + | Some aname -> ILTypeRefScope.Top(ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))) + | None -> ilg.typ_Boolean.TypeSpec.Scope + + let nsp, nm = splitILTypeName unqualified_tname + let tref = ILTypeRef (scoref, nsp, nm) + let tspec = mkILNonGenericTySpec tref + ILType.Value(tspec),sigptr + else + decodeCustomAttrElemType ilg bytes sigptr et + let nm,sigptr = sigptr_get_serstring bytes sigptr + let (_,v),sigptr = parseVal ty sigptr + parseNamed ((nm,ty,isProp,v) :: acc) (n-1) sigptr + let named = parseNamed [] (int nnamed) sigptr + fixedArgs, named + + with err -> + failwithf "FAILED decodeILCustomAttribData, data.Length = %d, data = %A, meth = %A, argtypes = %A, fixedArgs=%A, nnamed = %A, sigptr before named = %A, innerError = %A" bytes.Length bytes ca.Method.EnclosingType ca.Method.FormalArgTypes fixedArgs nnamed sigptr (err.ToString()) + + type CacheValue = ILModuleReader + let (|CacheValue|_|) (wr: WeakReference) = match wr.Target with null -> None | v -> Some (v :?> CacheValue) + let CacheValue (reader: CacheValue) = System.WeakReference reader + + // Amortize readers weakly - this is enough that all the type providers in this DLL will at least share + // resources when all instantiated at the same time. + let readersWeakCache = ConcurrentDictionary<(string * string), WeakReference>() + + let ILModuleReaderAfterReadingAllBytes (file:string, ilGlobals: ILGlobals) = + let bytes = File.ReadAllBytes file + let key = (file, ilGlobals.systemRuntimeScopeRef.QualifiedName) + match readersWeakCache.TryGetValue (key) with + | true, CacheValue mr2 when bytes = mr2.Bytes -> + mr2 // throw away the bytes we just read and recycle the existing ILModuleReader + | _ -> + let mr = ILModuleReader(file, ByteFile(bytes), ilGlobals, true) + readersWeakCache.[key] <- CacheValue (mr) + mr + + + (* NOTE: ecma_ prefix refers to the standard "mscorlib" *) + let EcmaPublicKey = PublicKeyToken ([|0xdeuy; 0xaduy; 0xbeuy; 0xefuy; 0xcauy; 0xfeuy; 0xfauy; 0xceuy |]) + let EcmaMscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef("mscorlib", UNone, USome EcmaPublicKey, true, UNone, UNone)) + +//==================================================================================================== +// TargetAssembly +// +// An implementation of reflection objects over on-disk assemblies, sufficient to give +// System.Type, System.MethodInfo, System.ConstructorInfo etc. objects +// that can be referred to in quotations and used as backing information for cross- +// targeting F# type providers. + + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + + // + // The on-disk assemblies are read by AssemblyReader. + // + // Background + // ---------- + // + // Provided type/member definitions need to refer to non-provided definitions like "System.Object" and "System.String". + // + // For cross-targeting F# type providers, these can be references to assemblies that can't easily be loaded by .NET + // reflection. For this reason, an implementation of the .NET reflection objects is needed. At minimum this + // implementation must support the operations used by the F# compiler to interrogate the reflection objects. + // + // For a System.Assembly, the information must be sufficient to allow the Assembly --> ILScopeRef conversion + // in ExtensionTyping.fs of the F# compiler. This requires: + // Assembly.GetName() + // + // For a System.Type representing a reference to a named type definition, the information must be sufficient + // to allow the Type --> ILTypeRef conversion in the F# compiler. This requires: + // typ.DeclaringType + // typ.Name + // typ.Namespace + // + // For a System.Type representing a type expression, the information must be sufficient to allow the Type --> ILType.Var conversion in the F# compiler. + // typeof.Equals(typ) + // typ.IsGenericParameter + // typ.GenericParameterPosition + // typ.IsArray + // typ.GetElementType() + // typ.GetArrayRank() + // typ.IsByRef + // typ.GetElementType() + // typ.IsPointer + // typ.GetElementType() + // typ.IsGenericType + // typ.GetGenericArguments() + // typ.GetGenericTypeDefinition() + // + // For a System.MethodBase --> ILType.ILMethodRef conversion: + // + // :?> MethodInfo as minfo + // + // minfo.IsGenericMethod || minfo.DeclaringType.IsGenericType + // minfo.DeclaringType.GetGenericTypeDefinition + // minfo.DeclaringType.GetMethods().MetadataToken + // minfo.MetadataToken + // minfo.IsGenericMethod + // minfo.GetGenericArguments().Length + // minfo.ReturnType + // minfo.GetParameters | .ParameterType + // minfo.Name + // + // :?> ConstructorInfo as cinfo + // + // cinfo.DeclaringType.IsGenericType + // cinfo.DeclaringType.GetGenericTypeDefinition + // cinfo.DeclaringType.GetConstructors() GetParameters | .ParameterType + // + + #nowarn "40" + + open System + open System.IO + open System.Collections.Generic + open System.Reflection + open ProviderImplementation.ProvidedTypes.AssemblyReader + + + [] + module Utils2 = + + // A table tracking how wrapped type definition objects are translated to cloned objects. + // Unique wrapped type definition objects must be translated to unique wrapper objects, based + // on object identity. + type TxTable<'T2>() = + let tab = Dictionary() + member _.Get inp f = + if tab.ContainsKey inp then + tab.[inp] + else + let res = f() + tab.[inp] <- res + res + + member _.ContainsKey inp = tab.ContainsKey inp + + + let instParameterInfo inst (inp: ParameterInfo) = + { new ParameterInfo() with + override _.Name = inp.Name + override _.ParameterType = inp.ParameterType |> instType inst + override _.Attributes = inp.Attributes + override _.RawDefaultValue = inp.RawDefaultValue + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.ToString() = inp.ToString() + "@inst" } + + let hashILParameterTypes (ps: ILParameters) = + // This hash code doesn't need to be very good as hashing by name is sufficient to give decent hash granularity + ps.Length + + let eqILScopeRef (_sco1: ILScopeRef) (_sco2: ILScopeRef) = + true // TODO (though omitting this is not a problem in practice since type equivalence by name is sufficient to bind methods) + + let eqAssemblyAndILScopeRef (_ass1: Assembly) (_sco2: ILScopeRef) = + true // TODO (though omitting this is not a problem in practice since type equivalence by name is sufficient to bind methods) + + + let rec eqILTypeRef (ty1: ILTypeRef) (ty2: ILTypeRef) = + ty1.Name = ty2.Name && eqILTypeRefScope ty1.Scope ty2.Scope + + and eqILTypeRefScope (ty1: ILTypeRefScope) (ty2: ILTypeRefScope) = + match ty1, ty2 with + | ILTypeRefScope.Top scoref1, ILTypeRefScope.Top scoref2 -> eqILScopeRef scoref1 scoref2 + | ILTypeRefScope.Nested tref1, ILTypeRefScope.Nested tref2 -> eqILTypeRef tref1 tref2 + | _ -> false + + and eqILTypes (tys1: ILType[]) (tys2: ILType[]) = + lengthsEqAndForall2 tys1 tys2 eqILType + + and eqILType (ty1: ILType) (ty2: ILType) = + match ty1, ty2 with + | (ILType.Value(tspec1) | ILType.Boxed(tspec1)), (ILType.Value(tspec2) | ILType.Boxed(tspec2))-> + eqILTypeRef tspec1.TypeRef tspec2.TypeRef && eqILTypes tspec1.GenericArgs tspec2.GenericArgs + | ILType.Array(rank1, arg1), ILType.Array(rank2, arg2) -> + rank1 = rank2 && eqILType arg1 arg2 + | ILType.Ptr(arg1), ILType.Ptr(arg2) -> + eqILType arg1 arg2 + | ILType.Byref(arg1), ILType.Byref(arg2) -> + eqILType arg1 arg2 + | ILType.Var(arg1), ILType.Var(arg2) -> + arg1 = arg2 + | _ -> false + + let rec eqTypeAndILTypeRef (ty1: Type) (ty2: ILTypeRef) = + ty1.Name = ty2.Name && + ty1.Namespace = (StructOption.toObj ty2.Namespace) && + match ty2.Scope with + | ILTypeRefScope.Top scoref2 -> eqAssemblyAndILScopeRef ty1.Assembly scoref2 + | ILTypeRefScope.Nested tref2 -> ty1.IsNested && eqTypeAndILTypeRef ty1.DeclaringType tref2 + + let rec eqTypesAndILTypes (tys1: Type[]) (tys2: ILType[]) = + eqTypesAndILTypesWithInst [| |] tys1 tys2 + + and eqTypesAndILTypesWithInst inst2 (tys1: Type[]) (tys2: ILType[]) = + lengthsEqAndForall2 tys1 tys2 (eqTypeAndILTypeWithInst inst2) + + and eqTypeAndILTypeWithInst inst2 (ty1: Type) (ty2: ILType) = + match ty2 with + | (ILType.Value(tspec2) | ILType.Boxed(tspec2))-> + if tspec2.GenericArgs.Length > 0 then + ty1.IsGenericType && eqTypeAndILTypeRef (ty1.GetGenericTypeDefinition()) tspec2.TypeRef && eqTypesAndILTypesWithInst inst2 (ty1.GetGenericArguments()) tspec2.GenericArgs + else + not ty1.IsGenericType && eqTypeAndILTypeRef ty1 tspec2.TypeRef + | ILType.Array(rank2, arg2) -> + ty1.IsArray && ty1.GetArrayRank() = rank2.Rank && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Ptr(arg2) -> + ty1.IsPointer && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Byref(arg2) -> + ty1.IsByRef && eqTypeAndILTypeWithInst inst2 (ty1.GetElementType()) arg2 + | ILType.Var(arg2) -> + if int arg2 < inst2.Length then + eqTypes ty1 inst2.[int arg2] + else + ty1.IsGenericParameter && ty1.GenericParameterPosition = int arg2 + + | _ -> false + + let eqParametersAndILParameterTypesWithInst inst2 (ps1: ParameterInfo[]) (ps2: ILParameters) = + lengthsEqAndForall2 ps1 ps2 (fun p1 p2 -> eqTypeAndILTypeWithInst inst2 p1.ParameterType p2.ParameterType) + + + type MethodSymbol2(gmd: MethodInfo, gargs: Type[]) = + inherit MethodInfo() + let dty = gmd.DeclaringType + let dinst = (if dty.IsGenericType then dty.GetGenericArguments() else [| |]) + + override _.Attributes = gmd.Attributes + override _.Name = gmd.Name + override _.DeclaringType = dty + override _.MemberType = gmd.MemberType + + override _.GetParameters() = gmd.GetParameters() |> Array.map (instParameterInfo (dinst, gargs)) + override _.CallingConvention = gmd.CallingConvention + override _.ReturnType = gmd.ReturnType |> instType (dinst, gargs) + override _.GetGenericMethodDefinition() = gmd + override _.IsGenericMethod = gmd.IsGenericMethod + override _.GetGenericArguments() = gargs + override _.MetadataToken = gmd.MetadataToken + + override _.GetCustomAttributesData() = gmd.GetCustomAttributesData() + override _.MakeGenericMethod(typeArgs) = MethodSymbol2(gmd, typeArgs) :> MethodInfo + override _.GetHashCode() = gmd.MetadataToken + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes dty that.DeclaringType && lengthsEqAndForall2 (gmd.GetGenericArguments()) (that.GetGenericArguments()) (=) + | _ -> false + + + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override _.GetCustomAttributes(_inherited) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherited) = emptyAttributes + + override _.ToString() = gmd.ToString() + "@inst" + + + /// Represents a constructor in an instantiated type + type ConstructorSymbol (declTy: Type, inp: ConstructorInfo) = + inherit ConstructorInfo() + let gps = ((if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]), [| |]) + + override _.Name = ".ctor" + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Constructor + override _.DeclaringType = declTy + + override _.GetParameters() = inp.GetParameters() |> Array.map (instParameterInfo gps) + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.MetadataToken = inp.MetadataToken + + override _.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? ConstructorInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes declTy that.DeclaringType + | _ -> false + + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override _.ToString() = sprintf "tgt constructor(...) in type %s" declTy.FullName + static member Make (declTy: Type) md = ConstructorSymbol (declTy, md) :> ConstructorInfo + + /// Represents a method in an instantiated type + type MethodSymbol (declTy: Type, inp: MethodInfo) = + inherit MethodInfo() + let gps1 = (if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]) + let gps2 = inp.GetGenericArguments() + let gps = (gps1, gps2) + + override _.Name = inp.Name + override _.DeclaringType = declTy + override _.MemberType = inp.MemberType + override _.Attributes = inp.Attributes + override _.GetParameters() = inp.GetParameters() |> Array.map (instParameterInfo gps) + override _.CallingConvention = inp.CallingConvention + override _.ReturnType = inp.ReturnType |> instType gps + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.GetGenericArguments() = gps2 + override _.IsGenericMethod = (gps2.Length <> 0) + override t.IsGenericMethodDefinition = t.IsGenericMethod + + override _.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.MakeGenericMethod(args) = MethodSymbol2(this, args) :> MethodInfo + + override _.MetadataToken = inp.MetadataToken + + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override _.ToString() = sprintf "tgt method %s(...) in type %s" inp.Name declTy.FullName + + static member Make (declTy: Type) md = MethodSymbol (declTy, md) :> MethodInfo + + /// Represents a property in an instantiated type + type PropertySymbol (declTy: Type, inp: PropertyInfo) = + inherit PropertyInfo() + let gps = ((if declTy.IsGenericType then declTy.GetGenericArguments() else [| |]), [| |]) + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Property + override _.DeclaringType = declTy + + override _.PropertyType = inp.PropertyType |> instType gps + override _.GetGetMethod(nonPublic) = inp.GetGetMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make declTy) |> Option.toObj + override _.GetSetMethod(nonPublic) = inp.GetSetMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make declTy) |> Option.toObj + override _.GetIndexParameters() = inp.GetIndexParameters() |> Array.map (instParameterInfo gps) + override _.CanRead = inp.GetGetMethod(false) |> isNull |> not + override _.CanWrite = inp.GetSetMethod(false) |> isNull |> not + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.MetadataToken = inp.MetadataToken + + override _.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? PropertyInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture) = notRequired this "GetValue" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" this.Name + override this.GetAccessors(_nonPublic) = notRequired this "GetAccessors" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override _.ToString() = sprintf "tgt property %s(...) in type %s" inp.Name declTy.Name + + static member Make (declTy: Type) md = PropertySymbol (declTy, md) :> PropertyInfo + + /// Represents an event in an instantiated type + type EventSymbol (declTy: Type, inp: EventInfo) = + inherit EventInfo() + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Event + override _.DeclaringType = declTy + + override _.EventHandlerType = inp.EventHandlerType |> instType (gps, [| |]) + override _.GetAddMethod(nonPublic) = inp.GetAddMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make declTy) |> Option.toObj + override _.GetRemoveMethod(nonPublic) = inp.GetRemoveMethod(nonPublic) |> Option.ofObj |> Option.map (MethodSymbol.Make declTy) |> Option.toObj + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.MetadataToken = inp.MetadataToken + + override _.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? EventInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetRaiseMethod(_nonPublic) = notRequired this "GetRaiseMethod" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override _.ToString() = sprintf "tgt event %s(...) in type %s" inp.Name declTy.FullName + + static member Make (declTy: Type) md = EventSymbol (declTy, md) :> EventInfo + + /// Represents a field in an instantiated type + type FieldSymbol (declTy: Type, inp: FieldInfo) = + inherit FieldInfo() + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Field + override _.DeclaringType = declTy + + override _.FieldType = inp.FieldType |> instType (gps, [| |]) + override _.GetRawConstantValue() = inp.GetRawConstantValue() + override _.GetCustomAttributesData() = inp.GetCustomAttributesData() + override _.MetadataToken = inp.MetadataToken + + override _.GetHashCode() = inp.GetHashCode() + override this.Equals(that:obj) = + match that with + | :? FieldInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" this.Name + override this.GetValue(_obj) = notRequired this "GetValue" this.Name + override this.FieldHandle = notRequired this "FieldHandle" this.Name + + override _.ToString() = sprintf "tgt literal field %s(...) in type %s" inp.Name declTy.FullName + + static member Make (declTy: Type) md = FieldSymbol (declTy, md) :> FieldInfo + + /// Represents the type constructor in a provided symbol type. + [] + type TypeSymbolKind = + | SDArray + | Array of int + | Pointer + | ByRef + | TargetGeneric of TargetTypeDefinition + | OtherGeneric of Type + + + /// Represents an array or other symbolic type involving a provided type as the argument. + /// See the type provider spec for the methods that must be implemented. + /// Note that the type provider specification does not require us to implement pointer-equality for provided types. + and TypeSymbol(kind: TypeSymbolKind, typeArgs: Type[]) as this = + inherit TypeDelegator() + do this.typeImpl <- this + + override this.FullName = + if this.IsArray then this.GetElementType().FullName + "[]" + elif this.IsPointer then this.GetElementType().FullName + "*" + elif this.IsByRef then this.GetElementType().FullName + "&" + elif this.IsGenericType then this.GetGenericTypeDefinition().FullName + "[" + (this.GetGenericArguments() |> Array.map (fun arg -> arg.FullName) |> String.concat ",") + "]" + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.DeclaringType = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().DeclaringType + elif this.IsGenericType then this.GetGenericTypeDefinition().DeclaringType + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Name = + if this.IsArray then this.GetElementType().Name + "[]" + elif this.IsPointer then this.GetElementType().Name + "*" + elif this.IsByRef then this.GetElementType().Name + "&" + elif this.IsGenericType then this.GetGenericTypeDefinition().Name + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.BaseType = + if this.IsArray then typeof + elif this.IsPointer then typeof + elif this.IsByRef then typeof + elif this.IsGenericType then instType (this.GetGenericArguments(), [| |]) (this.GetGenericTypeDefinition().BaseType) + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.MetadataToken = + if this.IsArray then typeof.MetadataToken + elif this.IsPointer then typeof.MetadataToken + elif this.IsByRef then typeof.MetadataToken + elif this.IsGenericType then this.GetGenericTypeDefinition().MetadataToken + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Assembly = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().Assembly + elif this.IsGenericType then this.GetGenericTypeDefinition().Assembly + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override this.Namespace = + if this.IsArray || this.IsPointer || this.IsByRef then this.GetElementType().Namespace + elif this.IsGenericType then this.GetGenericTypeDefinition().Namespace + else failwithf "unreachable, stack trace = %A" Environment.StackTrace + + override _.GetArrayRank() = (match kind with TypeSymbolKind.Array n -> n | TypeSymbolKind.SDArray -> 1 | _ -> failwithf "non-array type") + override _.IsValueTypeImpl() = this.IsGenericType && this.GetGenericTypeDefinition().IsValueType + override _.IsArrayImpl() = (match kind with TypeSymbolKind.Array _ | TypeSymbolKind.SDArray -> true | _ -> false) + override _.IsByRefImpl() = (match kind with TypeSymbolKind.ByRef _ -> true | _ -> false) + override _.IsPointerImpl() = (match kind with TypeSymbolKind.Pointer _ -> true | _ -> false) + override _.IsPrimitiveImpl() = false + override _.IsGenericType = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> true | _ -> false) + override _.GetGenericArguments() = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> typeArgs | _ -> [| |]) + override _.GetGenericTypeDefinition() = (match kind with TypeSymbolKind.TargetGeneric e -> (e :> Type) | TypeSymbolKind.OtherGeneric gtd -> gtd | _ -> failwithf "non-generic type") + override _.IsCOMObjectImpl() = false + override _.HasElementTypeImpl() = (match kind with TypeSymbolKind.TargetGeneric _ | TypeSymbolKind.OtherGeneric _ -> false | _ -> true) + override _.GetElementType() = (match kind,typeArgs with (TypeSymbolKind.Array _ | TypeSymbolKind.SDArray | TypeSymbolKind.ByRef | TypeSymbolKind.Pointer),[| e |] -> e | _ -> failwithf "%A, %A: not an array, pointer or byref type" kind typeArgs) + + override x.Module = x.Assembly.ManifestModule + + override this.GetHashCode() = + if this.IsArray then 10 + hash (this.GetElementType()) + elif this.IsPointer then 163 + hash (this.GetElementType()) + elif this.IsByRef then 283 + hash (this.GetElementType()) + else this.GetGenericTypeDefinition().MetadataToken + + override this.Equals(other: obj) = eqTypeObj this other + + override this.Equals(otherTy: Type) = eqTypes this otherTy + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + member _.Kind = kind + member _.Args = typeArgs + + override this.GetConstructors bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Methods.Entries + |> Array.filter (fun md -> md.Name = ".ctor" || md.Name = ".cctor") + |> Array.map (gtd.MakeConstructorInfo this) + |> Array.filter (canBindConstructor bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetConstructors(bindingFlags) + |> Array.map (ConstructorSymbol.Make this) + | _ -> notRequired this "GetConstructors" this.Name + + override this.GetMethods bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Methods.Entries + |> Array.filter (fun md -> md.Name <> ".ctor" && md.Name <> ".cctor") + |> Array.map (gtd.MakeMethodInfo this) + |> Array.filter (canBindMethod bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetMethods(bindingFlags) + |> Array.map (MethodSymbol.Make this) + | _ -> notRequired this "GetMethods" this.Name + + override this.GetFields bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Fields.Entries + |> Array.map (gtd.MakeFieldInfo this) + |> Array.filter (canBindField bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetFields(bindingFlags) + |> Array.map (FieldSymbol.Make this) + | _ -> notRequired this "GetFields" this.Name + + override this.GetProperties bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Properties.Entries + |> Array.map (gtd.MakePropertyInfo this) + |> Array.filter (canBindProperty bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetProperties(bindingFlags) + |> Array.map (PropertySymbol.Make this) + | _ -> notRequired this "GetProperties" this.Name + + override this.GetEvents bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Events.Entries + |> Array.map (gtd.MakeEventInfo this) + |> Array.filter (canBindEvent bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetEvents(bindingFlags) + |> Array.map (EventSymbol.Make this) + | _ -> notRequired this "GetEvents" this.Name + + override this.GetNestedTypes bindingFlags = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.NestedTypes.Entries + |> Array.map (gtd.MakeNestedTypeInfo this) + |> Array.filter (canBindNestedType bindingFlags) + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetNestedTypes(bindingFlags) + | _ -> notRequired this "GetNestedTypes" this.Name + + override this.GetConstructorImpl(bindingFlags, _binderBinder, _callConvention, types, _modifiers) = + let ctors = this.GetConstructors(bindingFlags) |> Array.filter (fun c -> match types with null -> true | t -> c.GetParameters().Length = t.Length) + match ctors with + | [| |] -> null + | [| ci |] -> ci + | _ -> failwithf "multiple constructors exist" + + override this.GetMethodImpl(name, bindingFlags, _binderBinder, _callConvention, types, _modifiers) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + let md = + match types with + | null -> gtd.Metadata.Methods.TryFindUniqueByName(name) + | _ -> + let mds = gtd.Metadata.Methods.FindByNameAndArity(name, types.Length) + match mds |> Array.filter (fun md -> eqTypesAndILTypesWithInst typeArgs types md.ParameterTypes) with + | [| |] -> None + | [| md |] -> Some md + | _ -> failwithf "multiple methods exist with name %s" name + md |> Option.map (gtd.MakeMethodInfo this) |> Option.toObj + | TypeSymbolKind.OtherGeneric _ -> + match this.GetMethods(bindingFlags) |> Array.filter (fun c -> name = c.Name && match types with null -> true | t -> c.GetParameters().Length = t.Length) with + | [| |] -> null + | [| mi |] -> mi + | _ -> failwithf "multiple methods exist with name %s" name + | _ -> notRequired this "GetMethodImpl" this.Name + + override this.GetField(name, bindingFlags) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Fields.Entries |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakeFieldInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetFields(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (FieldSymbol.Make this) + |> Option.toObj + + | _ -> notRequired this "GetField" this.Name + + override this.GetPropertyImpl(name, bindingFlags, _binder, _returnType, _types, _modifiers) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Properties.Entries + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakePropertyInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetProperties(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (PropertySymbol.Make this) + |> Option.toObj + + | _ -> notRequired this "GetPropertyImpl" this.Name + + override this.GetEvent(name, bindingFlags) = + match kind with + | TypeSymbolKind.TargetGeneric gtd -> + gtd.Metadata.Events.Entries + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (gtd.MakeEventInfo this) + |> Option.toObj + | TypeSymbolKind.OtherGeneric gtd -> + gtd.GetEvents(bindingFlags) + |> Array.tryFind (fun md -> md.Name = name) + |> Option.map (EventSymbol.Make this) + |> Option.toObj + | _ -> notRequired this "GetEvent" this.Name + + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.Name + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.GetAttributeFlagsImpl() = getAttributeFlagsImpl this + + override this.UnderlyingSystemType = (this :> Type) + + override _.GetCustomAttributesData() = ([| |] :> IList<_>) + + override this.GetMembers _bindingFlags = notRequired this "GetMembers" this.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" this.Name + override this.GetInterfaces() = notRequired this "GetInterfaces" this.Name + override _.GetCustomAttributes(_inherit) = emptyAttributes + override _.GetCustomAttributes(_attributeType, _inherit) = emptyAttributes + override _.IsDefined(_attributeType, _inherit) = false + + override this.MemberType = notRequired this "MemberType" this.Name + override this.GetMember(_name,_mt,_bindingFlags) = notRequired this "GetMember" this.Name + override this.GUID = notRequired this "GUID" this.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" this.Name + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |]) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |]) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |]) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |]) :> Type + + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + override this.ToString() = this.FullName + + + /// Clones namespaces, type providers, types and members provided by tp, renaming namespace nsp1 into namespace nsp2. + + /// Makes a type definition read from a binary available as a System.Type. Not all methods are implemented. + and TargetTypeDefinition(ilGlobals: ILGlobals, tryBindAssembly: ILAssemblyRef -> Choice, asm: TargetAssembly, declTyOpt: Type option, inp: ILTypeDef) as this = + inherit TypeDelegator() + + // Note: For F# type providers we never need to view the custom attributes + let rec txCustomAttributesArg ((ty:ILType,v:obj)) = + CustomAttributeTypedArgument(txILType ([| |], [| |]) ty, v) + + and txCustomAttributesDatum (inp: ILCustomAttribute) = + let args, namedArgs = decodeILCustomAttribData ilGlobals inp + { new CustomAttributeData () with + member _.Constructor = txILConstructorRef inp.Method.MethodRef + member _.ConstructorArguments = [| for arg in args -> txCustomAttributesArg arg |] :> IList<_> + // Note, named arguments of custom attributes are not required by F# compiler on binding context elements. + member _.NamedArguments = [| |] :> IList<_> + } + + and txCustomAttributesData (inp: ILCustomAttrs) = + [| for a in inp.Entries do + yield txCustomAttributesDatum a |] + :> IList + + /// Makes a parameter definition read from a binary available as a ParameterInfo. Not all methods are implemented. + and txILParameter gps (inp: ILParameter) = + { new ParameterInfo() with + + override _.Name = StructOption.toObj inp.Name + override _.ParameterType = inp.ParameterType |> txILType gps + override _.RawDefaultValue = (match inp.Default with UNone -> null | USome v -> v) + override _.Attributes = inp.Attributes + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override x.ToString() = sprintf "tgt parameter %s" x.Name } + + /// Makes a method definition read from a binary available as a ConstructorInfo. Not all methods are implemented. + and txILConstructorDef (declTy: Type) (inp: ILMethodDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new ConstructorInfo() with + + override _.Name = ".ctor" + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Constructor + override _.DeclaringType = declTy + + override _.GetParameters() = inp.Parameters |> Array.map (txILParameter (gps, [| |])) + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override _.MetadataToken = inp.Token + + override _.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? ConstructorInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes declTy that.DeclaringType + | _ -> false + + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override _.ToString() = sprintf "tgt constructor(...) in type %s" declTy.FullName } + + /// Makes a method definition read from a binary available as a MethodInfo. Not all methods are implemented. + and txILMethodDef (declTy: Type) (inp: ILMethodDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let rec gps2 = inp.GenericParams |> Array.mapi (fun i gp -> txILGenericParam (fun () -> gps, gps2) (i + gps.Length) gp) + { new MethodInfo() with + + override _.Name = inp.Name + override _.DeclaringType = declTy + override _.MemberType = MemberTypes.Method + override _.Attributes = inp.Attributes + override _.GetParameters() = inp.Parameters |> Array.map (txILParameter (gps, gps2)) + override _.CallingConvention = if inp.IsStatic then CallingConventions.Standard else CallingConventions.HasThis ||| CallingConventions.Standard + override _.ReturnType = inp.Return.Type |> txILType (gps, gps2) + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override _.GetGenericArguments() = gps2 + override _.IsGenericMethod = (gps2.Length <> 0) + override t.IsGenericMethodDefinition = t.IsGenericMethod + + override _.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? MethodInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.MakeGenericMethod(args) = MethodSymbol2(this, args) :> MethodInfo + + override _.MetadataToken = inp.Token + + // unused + override this.MethodHandle = notRequired this "MethodHandle" this.Name + override this.ReturnParameter = notRequired this "ReturnParameter" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.ReturnTypeCustomAttributes = notRequired this "ReturnTypeCustomAttributes" this.Name + override this.GetBaseDefinition() = notRequired this "GetBaseDefinition" this.Name + override this.GetMethodImplementationFlags() = notRequired this "GetMethodImplementationFlags" this.Name + override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired this "Invoke" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + + override _.ToString() = sprintf "tgt method %s(...) in type %s" inp.Name declTy.FullName } + + /// Makes a property definition read from a binary available as a PropertyInfo. Not all methods are implemented. + and txILPropertyDef (declTy: Type) (inp: ILPropertyDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new PropertyInfo() with + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Property + override _.DeclaringType = declTy + + override _.PropertyType = inp.PropertyType |> txILType (gps, [| |]) + override _.GetGetMethod(_nonPublic) = inp.GetMethod |> Option.map (txILMethodRef declTy) |> Option.toObj + override _.GetSetMethod(_nonPublic) = inp.SetMethod |> Option.map (txILMethodRef declTy) |> Option.toObj + override _.GetIndexParameters() = inp.IndexParameters |> Array.map (txILParameter (gps, [| |])) + override _.CanRead = inp.GetMethod.IsSome + override _.CanWrite = inp.SetMethod.IsSome + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override _.MetadataToken = inp.Token + + override _.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? PropertyInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture) = notRequired this "GetValue" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired this "SetValue" this.Name + override this.GetAccessors(nonPublic) = notRequired this "GetAccessors" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override _.ToString() = sprintf "tgt property %s(...) in type %s" inp.Name declTy.Name } + + /// Make an event definition read from a binary available as an EventInfo. Not all methods are implemented. + and txILEventDef (declTy: Type) (inp: ILEventDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new EventInfo() with + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Event + override _.DeclaringType = declTy + + override _.EventHandlerType = inp.EventHandlerType |> txILType (gps, [| |]) + override _.GetAddMethod(_nonPublic) = inp.AddMethod |> txILMethodRef declTy + override _.GetRemoveMethod(_nonPublic) = inp.RemoveMethod |> txILMethodRef declTy + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override _.MetadataToken = inp.Token + + override _.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? EventInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.GetRaiseMethod(_nonPublic) = notRequired this "GetRaiseMethod" this.Name + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + + override _.ToString() = sprintf "tgt event %s(...) in type %s" inp.Name declTy.FullName } + + /// Makes a field definition read from a binary available as a FieldInfo. Not all methods are implemented. + and txILFieldDef (declTy: Type) (inp: ILFieldDef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + { new FieldInfo() with + + override _.Name = inp.Name + override _.Attributes = inp.Attributes + override _.MemberType = MemberTypes.Field + override _.DeclaringType = declTy + + override _.FieldType = inp.FieldType |> txILType (gps, [| |]) + override _.GetRawConstantValue() = match inp.LiteralValue with None -> null | Some v -> v + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + override _.MetadataToken = inp.Token + + override _.GetHashCode() = inp.Token + + override this.Equals(that:obj) = + match that with + | :? FieldInfo as that -> this.MetadataToken = that.MetadataToken && eqTypes this.DeclaringType that.DeclaringType + | _ -> false + + override this.ReflectedType = notRequired this "ReflectedType" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" this.Name + override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired this "SetValue" this.Name + override this.GetValue(_obj) = notRequired this "GetValue" this.Name + override this.FieldHandle = notRequired this "FieldHandle" this.Name + + override _.ToString() = sprintf "tgt literal field %s(...) in type %s" inp.Name declTy.FullName } + + /// Bind a reference to an assembly + and txScopeRef(sref: ILScopeRef) = + match sref with + | ILScopeRef.Assembly aref -> match tryBindAssembly aref with Choice1Of2 asm -> asm | Choice2Of2 exn -> raise exn + | ILScopeRef.Local -> (asm :> Assembly) + | ILScopeRef.Module _ -> (asm :> Assembly) + + /// Bind a reference to a type + and txILTypeRef(tref: ILTypeRef): Type = + match tref.Scope with + | ILTypeRefScope.Top scoref -> txScopeRef(scoref).GetType(joinILTypeName tref.Namespace tref.Name) + | ILTypeRefScope.Nested encl -> txILTypeRef(encl).GetNestedType(tref.Name,bindAll) + + /// Bind a reference to a constructor + and txILConstructorRef (mref: ILMethodRef) = + let declTy = txILTypeRef(mref.EnclosingTypeRef) + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let argTypes = Array.map (txILType (gps, [| |])) mref.ArgTypes + let cons = declTy.GetConstructor(bindAll, null, argTypes, null) + if isNull cons then failwithf "constructor reference '%A' not resolved" mref + cons + + /// Bind a reference to a method + and txILMethodRef (declTy: Type) (mref: ILMethodRef) = + let gps = if declTy.IsGenericType then declTy.GetGenericArguments() else [| |] + let argTypes = mref.ArgTypes |> Array.map (txILType (gps, [| |])) + let meth = declTy.GetMethod(mref.Name, bindAll, null, argTypes, null) + if isNull meth then failwithf "method reference '%A' not resolved" mref + meth + + /// Convert an ILType read from a binary to a System.Type backed by TargetTypeDefinitions + and txILType gps (ty: ILType) = + + match ty with + | ILType.Void -> typeof + | ILType.Value tspec + | ILType.Boxed tspec -> + let tdefR = txILTypeRef tspec.TypeRef + match tspec.GenericArgs with + | [| |] -> tdefR + | args -> tdefR.MakeGenericType(Array.map (txILType gps) args) + | ILType.Array(rank, arg) -> + let argR = txILType gps arg + if rank.Rank = 1 then argR.MakeArrayType() + else argR.MakeArrayType(rank.Rank) + | ILType.FunctionPointer _ -> failwith "unexpected function type" + | ILType.Ptr(arg) -> (txILType gps arg).MakePointerType() + | ILType.Byref(arg) -> (txILType gps arg).MakeByRefType() + | ILType.Modified(_,_mod,arg) -> txILType gps arg + | ILType.Var(n) -> + let (gps1:Type[]),(gps2:Type[]) = gps + if n < gps1.Length then gps1.[n] + elif n < gps1.Length + gps2.Length then gps2.[n - gps1.Length] + else failwithf "generic parameter index out of range: %d" n + + /// Convert an ILGenericParameterDef read from a binary to a System.Type. + and txILGenericParam gpsf pos (inp: ILGenericParameterDef) = + { new Type() with + override _.Name = inp.Name + override _.Assembly = (asm :> Assembly) + override _.FullName = inp.Name + override _.IsGenericParameter = true + override _.GenericParameterPosition = pos + override _.GetGenericParameterConstraints() = inp.Constraints |> Array.map (txILType (gpsf())) + + override _.MemberType = enum 0 + override _.MetadataToken = inp.Token + + override _.Namespace = null //notRequired this "Namespace" + override this.DeclaringType = notRequired this "DeclaringType" this.Name + override _.BaseType = null //notRequired this "BaseType" this.Name + override this.GetInterfaces() = notRequired this "GetInterfaces" this.Name + + override this.GetConstructors(_bindingFlags) = notRequired this "GetConstructors" this.Name + override this.GetMethods(_bindingFlags) = notRequired this "GetMethods" this.Name + override this.GetFields(_bindingFlags) = notRequired this "GetFields" this.Name + override this.GetProperties(_bindingFlags) = notRequired this "GetProperties" this.Name + override this.GetEvents(_bindingFlags) = notRequired this "GetEvents" this.Name + override this.GetNestedTypes(_bindingFlags) = notRequired this "GetNestedTypes" this.Name + + override this.GetConstructorImpl(_bindingFlags, _binder, _callConvention, _types, _modifiers) = notRequired this "txILGenericParam: GetConstructorImpl" this.Name + override this.GetMethodImpl(_name, _bindingFlags, _binder, _callConvention, _types, _modifiers) = notRequired this "txILGenericParam: GetMethodImpl" this.Name + override this.GetField(_name, _bindingFlags) = notRequired this "GetField" this.Name + override this.GetPropertyImpl(_name, _bindingFlags, _binder, _returnType, _types, _modifiers) = notRequired this "GetPropertyImpl" this.Name + override this.GetNestedType(_name, _bindingFlags) = notRequired this "GetNestedType" this.Name + override this.GetEvent(_name, _bindingFlags) = notRequired this "GetEvent" this.Name + + override this.GetMembers(_bindingFlags) = notRequired this "GetMembers" this.Name + + override this.MakeGenericType(_args) = notRequired this "MakeGenericType" this.Name + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |]) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |]) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |]) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |]) :> Type + + override _.GetAttributeFlagsImpl() = TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.Sealed + + override _.IsArrayImpl() = false + override _.IsByRefImpl() = false + override _.IsPointerImpl() = false + override _.IsPrimitiveImpl() = false + override _.IsCOMObjectImpl() = false + override _.IsGenericType = false + override _.IsGenericTypeDefinition = false + + override _.HasElementTypeImpl() = false + + override this.UnderlyingSystemType = this + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override this.Equals(that:obj) = System.Object.ReferenceEquals (this, that) + + override _.ToString() = sprintf "tgt generic param %s" inp.Name + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.GetGenericArguments() = notRequired this "GetGenericArguments" this.Name + override this.GetGenericTypeDefinition() = notRequired this "GetGenericTypeDefinition" this.Name + override this.GetMember(_name, _mt, _bindingFlags) = notRequired this "txILGenericParam: GetMember" this.Name + override this.GUID = notRequired this "txILGenericParam: GUID" this.Name + override this.GetCustomAttributes(_inherited) = notRequired this "txILGenericParam: GetCustomAttributes" this.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "txILGenericParam: GetCustomAttributes" this.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "txILGenericParam: IsDefined" this.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "txILGenericParam: GetInterface" this.Name + override this.Module = notRequired this "txILGenericParam: Module" this.Name: Module + override this.GetElementType() = notRequired this "txILGenericParam: GetElementType" this.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "txILGenericParam: InvokeMember" this.Name + + } + + let rec gps = inp.GenericParams |> Array.mapi (fun i gp -> txILGenericParam (fun () -> gps, [| |]) i gp) + + let isNested = declTyOpt.IsSome + + do this.typeImpl <- this + override _.Name = inp.Name + override _.Assembly = (asm :> Assembly) + override _.DeclaringType = declTyOpt |> Option.toObj + override _.MemberType = if isNested then MemberTypes.NestedType else MemberTypes.TypeInfo + override _.MetadataToken = inp.Token + + override _.FullName = + match declTyOpt with + | None -> + match inp.Namespace with + | UNone -> inp.Name + | USome nsp -> nsp + "." + inp.Name + | Some declTy -> + declTy.FullName + "+" + inp.Name + + override _.Namespace = inp.Namespace |> StructOption.toObj + override _.BaseType = inp.Extends |> Option.map (txILType (gps, [| |])) |> Option.toObj + override _.GetInterfaces() = inp.Implements |> Array.map (txILType (gps, [| |])) + + override this.GetConstructors(bindingFlags) = + inp.Methods.Entries + |> Array.filter (fun x -> x.Name = ".ctor" || x.Name = ".cctor") + |> Array.map (txILConstructorDef this) + |> Array.filter (canBindConstructor bindingFlags) + + override this.GetMethods(bindingFlags) = + inp.Methods.Entries + |> Array.filter (fun x -> x.Name <> ".ctor" && x.Name <> ".cctor") + |> Array.map (txILMethodDef this) + |> Array.filter (canBindMethod bindingFlags) + + override this.GetFields(bindingFlags) = + inp.Fields.Entries + |> Array.map (txILFieldDef this) + |> Array.filter (canBindField bindingFlags) + + override this.GetEvents(bindingFlags) = + inp.Events.Entries + |> Array.map (txILEventDef this) + |> Array.filter (canBindEvent bindingFlags) + + override this.GetProperties(bindingFlags) = + inp.Properties.Entries + |> Array.map (txILPropertyDef this) + |> Array.filter (canBindProperty bindingFlags) + + override this.GetNestedTypes(bindingFlags) = + inp.NestedTypes.Entries + |> Array.map (asm.TxILTypeDef (Some (this :> Type))) + |> Array.filter (canBindNestedType bindingFlags) + + override this.GetConstructorImpl(_bindingFlags, _binder, _callConvention, types, _modifiers) = + let md = + match types with + | null -> inp.Methods.TryFindUniqueByName(".ctor") + | _ -> + inp.Methods.FindByNameAndArity(".ctor", types.Length) + |> Array.tryFind (fun md -> eqTypesAndILTypes types md.ParameterTypes) + md + |> Option.map (txILConstructorDef this) + |> Option.toObj + + override this.GetMethodImpl(name, _bindingFlags, _binder, _callConvention, types, _modifiers) = + let md = + match types with + | null -> inp.Methods.TryFindUniqueByName(name) + | _ -> + inp.Methods.FindByNameAndArity(name, types.Length) + |> Array.tryFind (fun md -> eqTypesAndILTypes types md.ParameterTypes) + md |> Option.map (txILMethodDef this) |> Option.toObj + + override this.GetField(name, _bindingFlags) = + inp.Fields.Entries + |> Array.tryPick (fun p -> if p.Name = name then Some (txILFieldDef this p) else None) + |> Option.toObj + + override this.GetPropertyImpl(name, _bindingFlags, _binder, _returnType, _types, _modifiers) = + inp.Properties.Entries + |> Array.tryPick (fun p -> if p.Name = name then Some (txILPropertyDef this p) else None) + |> Option.toObj + + override this.GetEvent(name, _bindingFlags) = + inp.Events.Entries + |> Array.tryPick (fun ev -> if ev.Name = name then Some (txILEventDef this ev) else None) + |> Option.toObj + + override this.GetNestedType(name, _bindingFlags) = + inp.NestedTypes.TryFindByName(UNone, name) |> Option.map (asm.TxILTypeDef (Some (this :> Type))) |> Option.toObj + + + override this.GetMembers(bindingFlags) = + [| for x in this.GetConstructors(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetMethods(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetFields(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetProperties(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetEvents(bindingFlags) do yield (x :> MemberInfo) + for x in this.GetNestedTypes(bindingFlags) do yield (x :> MemberInfo) |] + + override this.MakeGenericType(args) = TypeSymbol(TypeSymbolKind.TargetGeneric this, args) :> Type + override this.MakeArrayType() = TypeSymbol(TypeSymbolKind.SDArray, [| this |]) :> Type + override this.MakeArrayType arg = TypeSymbol(TypeSymbolKind.Array arg, [| this |]) :> Type + override this.MakePointerType() = TypeSymbol(TypeSymbolKind.Pointer, [| this |]) :> Type + override this.MakeByRefType() = TypeSymbol(TypeSymbolKind.ByRef, [| this |]) :> Type + + override _.GetAttributeFlagsImpl() = + let attr = TypeAttributes.Public ||| TypeAttributes.Class + let attr = if inp.IsSealed then attr ||| TypeAttributes.Sealed else attr + let attr = if inp.IsInterface then attr ||| TypeAttributes.Interface else attr + let attr = if inp.IsSerializable then attr ||| TypeAttributes.Serializable else attr + if isNested then adjustTypeAttributes isNested attr else attr + + override _.IsValueTypeImpl() = inp.IsStructOrEnum + + override _.IsEnum = + match this.BaseType with + | null -> false + | bt -> bt.FullName = "System.Enum" || bt.IsEnum + + override _.GetEnumUnderlyingType() = + if this.IsEnum then + txILType ([| |], [| |]) ilGlobals.typ_Int32 // TODO: in theory the assumption of "Int32" is not accurate for all enums, howver in practice .NET only uses enums with backing field Int32 + else failwithf "not enum type" + + override _.IsArrayImpl() = false + override _.IsByRefImpl() = false + override _.IsPointerImpl() = false + override _.IsPrimitiveImpl() = false + override _.IsCOMObjectImpl() = false + override _.IsGenericType = (gps.Length <> 0) + override _.IsGenericTypeDefinition = (gps.Length <> 0) + override _.HasElementTypeImpl() = false + + override this.UnderlyingSystemType = (this :> Type) + override _.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData + + override this.Equals(that:obj) = System.Object.ReferenceEquals (this, that) + override this.Equals(that:Type) = System.Object.ReferenceEquals (this, that) + override _.GetHashCode() = inp.Token + + override this.IsAssignableFrom(otherTy: Type) = isAssignableFrom this otherTy + + override this.IsSubclassOf(otherTy: Type) = isSubclassOf this otherTy + + override this.AssemblyQualifiedName = "[" + this.Assembly.FullName + "]" + this.FullName + + override this.ToString() = sprintf "tgt type %s" this.FullName + + override _.GetGenericArguments() = gps + override this.GetGenericTypeDefinition() = (this :> Type) + + override x.Module = x.Assembly.ManifestModule + + override this.GetMember(_name, _memberType, _bindingFlags) = notRequired this "GetMember" inp.Name + override this.GUID = notRequired this "GUID" inp.Name + override this.GetCustomAttributes(_inherited) = notRequired this "GetCustomAttributes" inp.Name + override this.GetCustomAttributes(_attributeType, _inherited) = notRequired this "GetCustomAttributes" inp.Name + override this.IsDefined(_attributeType, _inherited) = notRequired this "IsDefined" inp.Name + override this.GetInterface(_name, _ignoreCase) = notRequired this "GetInterface" inp.Name + override this.GetElementType() = notRequired this "GetElementType" inp.Name + override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired this "InvokeMember" inp.Name + + member _.Metadata: ILTypeDef = inp + member _.MakeMethodInfo (declTy: Type) md = txILMethodDef declTy md + member _.MakeConstructorInfo (declTy: Type) md = txILConstructorDef declTy md + member _.MakePropertyInfo (declTy: Type) md = txILPropertyDef declTy md + member _.MakeEventInfo (declTy: Type) md = txILEventDef declTy md + member _.MakeFieldInfo (declTy: Type) md = txILFieldDef declTy md + member _.MakeNestedTypeInfo (declTy: Type) md = asm.TxILTypeDef (Some declTy) md + override this.GetEvents() = this.GetEvents(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.Static) // Needed because TypeDelegator.cs provides a delegting implementation of this, and we are self-delegating + + and TargetModule(location: string) = + inherit Module() + override _.MetadataToken = hash location + + /// Implements System.Reflection.Assembly backed by .NET metadata provided by an ILModuleReader + and TargetAssembly(ilGlobals, tryBindAssembly: ILAssemblyRef -> Choice, reader: ILModuleReader option, location: string) as asm = + inherit Assembly() + + // A table tracking how type definition objects are translated. + let txTable = TxTable() + let mutable reader = reader + let manifestModule = TargetModule(location) + let getReader() = match reader with None -> failwith "the reader on the TargetAssembly has not been set" | Some r -> r + + let txILTypeDef (declTyOpt: Type option) (inp: ILTypeDef) = + txTable.Get inp.Token (fun () -> + // We never create target types for the types of primitive values that are accepted by the F# compiler as Expr.Value nodes, + // which fortunately also correspond to element types. We just use the design-time types instead. + // See convertConstExpr in the compiler, e.g. + // https://github.com/Microsoft/visualfsharp/blob/44fa027b308681a1b78a089e44fa1ab35ff77b41/src/fsharp/MethodCalls.fs#L842 + // for the accepted types. + match inp.Namespace, inp.Name with + | USome "System", "Void"-> typeof + (* + | USome "System", "Boolean" -> typeof + | USome "System", "String"-> typeof + | USome "System", "Object"-> typeof + | USome "System", "Int32" -> typeof + | USome "System", "SByte" -> typeof + | USome "System", "Int16"-> typeof + | USome "System", "Int64" -> typeof + | USome "System", "IntPtr" -> typeof + | USome "System", "Byte" -> typeof + | USome "System", "UInt16"-> typeof + | USome "System", "UInt32" -> typeof + | USome "System", "UInt64" -> typeof + | USome "System", "UIntPtr" -> typeof + | USome "System", "Double" -> typeof + | USome "System", "Single" -> typeof + | USome "System", "Char" -> typeof + *) + | _ -> + TargetTypeDefinition(ilGlobals, tryBindAssembly, asm, declTyOpt, inp) :> System.Type) + + let types = lazy [| for td in getReader().ILModuleDef.TypeDefs.Entries -> txILTypeDef None td |] + + + override _.GetReferencedAssemblies() = [| for aref in getReader().ILAssemblyRefs -> aref.ToAssemblyName() |] + + override _.GetTypes () = types.Force() + + override x.GetType (nm:string) = + if nm.Contains("+") then + let i = nm.LastIndexOf("+") + let enc,nm2 = nm.[0..i-1], nm.[i+1..] + match x.GetType(enc) with + | null -> null + | t -> t.GetNestedType(nm2,bindAll) + elif nm.Contains(".") then + let i = nm.LastIndexOf(".") + let nsp,nm2 = nm.[0..i-1], nm.[i+1..] + x.TryBindType(USome nsp, nm2) |> Option.toObj + else + x.TryBindType(UNone, nm) |> Option.toObj + + override _.GetName() = getReader().ILModuleDef.ManifestOfAssembly.GetName() + + override x.FullName = x.GetName().ToString() + + override _.Location = location + override _.ManifestModule = (manifestModule :> Module) + + override _.ReflectionOnly = true + + override x.GetManifestResourceStream(resourceName:string) = + let r = getReader().ILModuleDef.Resources.Entries |> Seq.find (fun r -> r.Name = resourceName) + match r.Location with + | ILResourceLocation.Local f -> new MemoryStream(f()) :> Stream + | _ -> notRequired x "reading manifest resource %s from non-embedded location" resourceName + + member _.TxILTypeDef declTyOpt inp = txILTypeDef declTyOpt inp + + member _.Reader with get() = reader and set v = (if reader.IsSome then failwith "reader on TargetAssembly already set"); reader <- v + + member _.TryBindType(nsp:string uoption, nm:string): Type option = + match getReader().ILModuleDef.TypeDefs.TryFindByName(nsp, nm) with + | Some td -> asm.TxILTypeDef None td |> Some + | None -> + match getReader().ILModuleDef.ManifestOfAssembly.ExportedTypes.TryFindByName(nsp, nm) with + | Some tref -> + match tref.ScopeRef with + | ILScopeRef.Assembly aref2 -> + let ass2opt = tryBindAssembly(aref2) + match ass2opt with + | Choice1Of2 ass2 -> + match ass2.GetType(joinILTypeName nsp nm) with + | null -> None + | ty -> Some ty + | Choice2Of2 _err -> None + | _ -> + printfn "unexpected non-forwarder during binding" + None + | None -> None + + member x.BindType(nsp:string uoption, nm:string) = + match x.TryBindType(nsp, nm) with + | None -> failwithf "failed to bind type %s in assembly %s" nm asm.FullName + | Some res -> res + + override x.ToString() = "tgt assembly " + x.FullName + + + + type ProvidedAssembly(isTgt: bool, assemblyName:AssemblyName, assemblyFileName: string) = + + inherit Assembly() + let theTypes = ResizeArray() + + let addTypes (ptds:ProvidedTypeDefinition[], enclosingTypeNames: string list option) = + for pt in ptds do + if pt.IsErased then failwith ("The provided type "+pt.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased=false' on the ProvidedTypeDefinition") + if not isTgt && pt.BelongsToTargetModel then failwithf "Expected '%O' to be a source ProvidedTypeDefinition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pt + if isTgt && not pt.BelongsToTargetModel then failwithf "Expected '%O' to be a target ProvidedTypeDefinition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pt + theTypes.Add (ptds, enclosingTypeNames) + + let theTypesArray = lazy (theTypes.ToArray() |> Array.collect (function (ptds, None) -> Array.map (fun ptd -> (ptd :> Type)) ptds | _ -> [| |])) + + override _.GetReferencedAssemblies() = [| |] //notRequired x "GetReferencedAssemblies" (assemblyName.ToString()) + + override _.GetName() = assemblyName + + override _.FullName = assemblyName.ToString() + + override _.Location = assemblyFileName + + override _.ReflectionOnly = true + + override _.GetTypes () = theTypesArray.Force() + + override x.GetType (nm: string) = + if nm.Contains("+") then + let i = nm.LastIndexOf("+") + let enc,nm2 = nm.[0..i-1], nm.[i+1..] + match x.GetType(enc) with + | null -> null + | t -> t.GetNestedType(nm2,bindAll) + else + theTypesArray.Force() + |> Array.tryPick (fun ty -> if ty.FullName = nm then Some ty else None) + |> Option.toObj + + new () = + let tmpFile = Path.GetTempFileName() + let assemblyFileName = Path.ChangeExtension(tmpFile, "dll") + File.Delete(tmpFile) + let simpleName = Path.GetFileNameWithoutExtension(assemblyFileName) + ProvidedAssembly(AssemblyName(simpleName), assemblyFileName) + + new (assemblyName, assemblyFileName) = + ProvidedAssembly(false, assemblyName, assemblyFileName) + + member _.BelongsToTargetModel = isTgt + + member _.AddNestedTypes (types, enclosingGeneratedTypeNames) = + addTypes (Array.ofList types, Some enclosingGeneratedTypeNames) + + member _.AddTypes (types) = + addTypes (Array.ofList types, None) + + member _.AddTheTypes (types, enclosingGeneratedTypeNames) = + addTypes (types, enclosingGeneratedTypeNames) + + member _.GetTheTypes () = theTypes.ToArray() + +//==================================================================================================== +// ProvidedTypesContext +// +// A binding context for cross-targeting type providers + +namespace ProviderImplementation.ProvidedTypes + + + #nowarn "8796" + #nowarn "1182" + + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + + [] + module private ImplementationUtils = + type System.Object with + member x.GetProperty(nm) = + let ty = x.GetType() + let prop = ty.GetProperty(nm, bindAll) + let v = prop.GetValue(x,null) + v + + member x.GetField(nm) = + let ty = x.GetType() + let fld = ty.GetField(nm, bindAll) + let v = fld.GetValue(x) + v + + member x.HasProperty(nm) = + let ty = x.GetType() + let p = ty.GetProperty(nm, bindAll) + p |> isNull |> not + + member x.HasField(nm) = + let ty = x.GetType() + let fld = ty.GetField(nm, bindAll) + fld |> isNull |> not + + member x.GetElements() = [ for v in (x :?> System.Collections.IEnumerable) do yield v ] + + + + type ProvidedTypeBuilder() = + static let tupleNames = + [| "System.Tuple`1"; "System.Tuple`2"; "System.Tuple`3"; + "System.Tuple`4"; "System.Tuple`5"; "System.Tuple`6"; + "System.Tuple`7"; "System.Tuple`8"; "System.Tuple" + "System.ValueTuple`1"; "System.ValueTuple`2"; "System.ValueTuple`3"; + "System.ValueTuple`4"; "System.ValueTuple`5"; "System.ValueTuple`6"; + "System.ValueTuple`7"; "System.ValueTuple`8"; "System.ValueTuple" |] + + + static member MakeGenericType(genericTypeDefinition: Type, genericArguments: Type list) = + if genericArguments.Length = 0 then genericTypeDefinition else + match genericTypeDefinition with + | :? TargetTypeDefinition -> failwithf "unexpected target model in ProvidedTypeBuilder.MakeGenericType, stacktrace = %s " Environment.StackTrace + | :? ProvidedTypeDefinition as ptd when ptd.BelongsToTargetModel -> failwithf "unexpected target model ptd in MakeGenericType, stacktrace = %s " Environment.StackTrace + | :? ProvidedTypeDefinition -> ProvidedTypeSymbol(ProvidedTypeSymbolKind.Generic genericTypeDefinition, genericArguments) :> Type + | _ -> TypeSymbol(TypeSymbolKind.OtherGeneric genericTypeDefinition, List.toArray genericArguments) :> Type + + static member MakeGenericMethod(genericMethodDefinition, genericArguments: Type list) = + if genericArguments.Length = 0 then genericMethodDefinition else + MethodSymbol2(genericMethodDefinition, Array.ofList genericArguments) :> MethodInfo + + static member MakeTupleType(types) = + let rec mkTupleType isStruct (asm:Assembly) (tys:Type list) = + let maxTuple = 8 + + let n = min tys.Length maxTuple + let tupleFullName = tupleNames.[n - 1 + (if isStruct then 9 else 0)] + let ty = asm.GetType(tupleFullName) + if tys.Length >= maxTuple then + let tysA = (Array.ofList tys).[0..maxTuple-2] |> List.ofArray + let tysB = (Array.ofList tys).[maxTuple-1..] |> List.ofArray + let tyB = mkTupleType isStruct asm tysB + ProvidedTypeBuilder.MakeGenericType(ty, List.append tysA [ tyB ]) + else + ProvidedTypeBuilder.MakeGenericType(ty, tys) + mkTupleType false (typeof.Assembly) types + + //-------------------------------------------------------------------------------- + // The quotation simplifier + // + // This is invoked for each quotation specified by the type provider, as part of the translation to + /// the target model, i.e. before it is handed to the F# compiler (for erasing type providers) or + // the TPSDK IL code generator (for generative type providers). This allows a broader range of quotations + // to be used when authoring type providers than are strictly allowed by those tools. + // + // Specifically we accept: + // + // - NewTuple nodes (for generative type providers) + // - TupleGet nodes (for generative type providers) + // - array and list values as constants + // - PropertyGet and PropertySet nodes + // - Application, NewUnionCase, NewRecord, UnionCaseTest nodes + // - Let nodes (defining "byref" values) + // - LetRecursive nodes + // + // Additionally, a set of code optimizations are applied for generative type providers: + // - inlineRightPipe + // - optimizeCurriedApplications + // - inlineValueBindings + + // Note, the QuotationSimplifier works over source quotations, not target quotations + type QuotationSimplifier(isGenerated: bool) = + + let rec simplifyExpr q = + match q with + +#if !NO_GENERATIVE + // Convert NewTuple to the call to the constructor of the Tuple type (only for generated types, + // the F# compile does the job for erased types when it receives the quotation) | NewTuple(items) when isGenerated -> - let rec mkCtor args ty = + let rec mkCtor args ty = let ctor, restTyOpt = Reflection.FSharpValue.PreComputeTupleConstructorInfo ty match restTyOpt with - | None -> Expr.NewObject(ctor, List.map trans args) + | None -> Expr.NewObjectUnchecked(ctor, List.map simplifyExpr args) | Some restTy -> - let curr = [for a in Seq.take 7 args -> trans a] - let rest = List.ofSeq (Seq.skip 7 args) - Expr.NewObject(ctor, curr @ [mkCtor rest restTy]) - let tys = [| for e in items -> e.Type |] - let tupleTy = Reflection.FSharpType.MakeTupleType tys - trans (mkCtor items tupleTy) + let curr = [for a in Seq.take 7 args -> simplifyExpr a] + let rest = List.ofSeq (Seq.skip 7 args) + Expr.NewObjectUnchecked(ctor, curr @ [mkCtor rest restTy]) + let tys = [ for e in items -> e.Type ] + let tupleTy = ProvidedTypeBuilder.MakeTupleType(tys) + simplifyExpr (mkCtor items tupleTy) + // convert TupleGet to the chain of PropertyGet calls (only for generated types) | TupleGet(e, i) when isGenerated -> - let rec mkGet ty i (e : Expr) = + let rec mkGet ty i (e: Expr) = let pi, restOpt = Reflection.FSharpValue.PreComputeTuplePropertyInfo(ty, i) - let propGet = Expr.PropertyGet(e, pi) + let propGet = Expr.PropertyGetUnchecked(e, pi) match restOpt with | None -> propGet | Some (restTy, restI) -> mkGet restTy restI propGet - trans (mkGet e.Type i (trans e)) + simplifyExpr (mkGet e.Type i (simplifyExpr e)) +#endif + | Value(value, ty) -> - if value <> null then - let tyOfValue = value.GetType() - transValue(value, tyOfValue, ty) + if value |> isNull |> not then + let tyOfValue = value.GetType() + transValue(value, tyOfValue, ty) else q + // Eliminate F# property gets to method calls - | PropertyGet(obj,propInfo,args) -> - match obj with - | None -> trans (Expr.CallUnchecked(propInfo.GetGetMethod(),args)) - | Some o -> trans (Expr.CallUnchecked(trans o,propInfo.GetGetMethod(),args)) + | PropertyGet(obj,propInfo,args) -> + match obj with + | None -> simplifyExpr (Expr.CallUnchecked(propInfo.GetGetMethod(),args)) + | Some o -> simplifyExpr (Expr.CallUnchecked(simplifyExpr o,propInfo.GetGetMethod(),args)) + // Eliminate F# property sets to method calls - | PropertySet(obj,propInfo,args,v) -> - match obj with - | None -> trans (Expr.CallUnchecked(propInfo.GetSetMethod(),args@[v])) - | Some o -> trans (Expr.CallUnchecked(trans o,propInfo.GetSetMethod(),args@[v])) + | PropertySet(obj,propInfo,args,v) -> + match obj with + | None -> simplifyExpr (Expr.CallUnchecked(propInfo.GetSetMethod(),args@[v])) + | Some o -> simplifyExpr (Expr.CallUnchecked(simplifyExpr o,propInfo.GetSetMethod(),args@[v])) + // Eliminate F# function applications to FSharpFunc<_,_>.Invoke calls - | Application(f,e) -> - trans (Expr.CallUnchecked(trans f, f.Type.GetMethod "Invoke", [ e ]) ) + | Application(f,e) -> + simplifyExpr (Expr.CallUnchecked(simplifyExpr f, f.Type.GetMethod "Invoke", [ e ]) ) + + // Eliminate F# union operations | NewUnionCase(ci, es) -> - trans (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) - | NewRecord(ci, es) -> - trans (Expr.NewObjectUnchecked(Reflection.FSharpValue.PreComputeRecordConstructorInfo ci, es) ) + simplifyExpr (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) + + // Eliminate F# union operations | UnionCaseTest(e,uc) -> let tagInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType - let tagExpr = - match tagInfo with + let tagExpr = + match tagInfo with | :? PropertyInfo as tagProp -> - trans (Expr.PropertyGet(e,tagProp) ) - | :? MethodInfo as tagMeth -> - if tagMeth.IsStatic then trans (Expr.Call(tagMeth, [e])) - else trans (Expr.Call(e,tagMeth,[])) - | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo" + simplifyExpr (Expr.PropertyGet(e,tagProp) ) + | :? MethodInfo as tagMeth -> + if tagMeth.IsStatic then simplifyExpr (Expr.Call(tagMeth, [e])) + else simplifyExpr (Expr.Call(e,tagMeth,[])) + | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" let tagNumber = uc.Tag - trans <@@ (%%(tagExpr) : int) = tagNumber @@> + simplifyExpr <@@ (%%(tagExpr): int) = tagNumber @@> - // Explicitly handle weird byref variables in lets (used to populate out parameters), since the generic handlers can't deal with byrefs - | Let(v,vexpr,bexpr) when v.Type.IsByRef -> + // Eliminate F# record operations + | NewRecord(ci, es) -> + simplifyExpr (Expr.NewObjectUnchecked(Reflection.FSharpValue.PreComputeRecordConstructorInfo ci, es) ) - // the binding must have leaves that are themselves variables (due to the limited support for byrefs in expressions) - // therefore, we can perform inlining to translate this to a form that can be compiled - inlineByref v vexpr bexpr + // Explicitly handle weird byref variables in lets (used to populate out parameters), since the generic handlers can't deal with byrefs. + // + // The binding must have leaves that are themselves variables (due to the limited support for byrefs in expressions) + // therefore, we can perform inlining to translate this to a form that can be compiled + | Let(v,vexpr,bexpr) when v.Type.IsByRef -> transLetOfByref v vexpr bexpr // Eliminate recursive let bindings (which are unsupported by the type provider API) to regular let bindings - | LetRecursive(bindings, expr) -> - // This uses a "lets and sets" approach, converting something like - // let rec even = function - // | 0 -> true - // | n -> odd (n-1) - // and odd = function - // | 0 -> false - // | n -> even (n-1) - // X - // to something like - // let even = ref Unchecked.defaultof<_> - // let odd = ref Unchecked.defaultof<_> - // even := function - // | 0 -> true - // | n -> !odd (n-1) - // odd := function - // | 0 -> false - // | n -> !even (n-1) - // X' - // where X' is X but with occurrences of even/odd substituted by !even and !odd (since now even and odd are references) - // Translation relies on typedefof<_ ref> - does this affect ability to target different runtime and design time environments? - let vars = List.map fst bindings - let vars' = vars |> List.map (fun v -> Quotations.Var(v.Name, typedefof<_ ref>.MakeGenericType(v.Type))) - - // init t generates the equivalent of <@ ref Unchecked.defaultof @> - let init (t:Type) = - let r = match <@ ref 1 @> with Call(None, r, [_]) -> r | _ -> failwith "Extracting MethodInfo from <@ 1 @> failed" - let d = match <@ Unchecked.defaultof<_> @> with Call(None, d, []) -> d | _ -> failwith "Extracting MethodInfo from <@ Unchecked.defaultof<_> @> failed" - Expr.Call(r.GetGenericMethodDefinition().MakeGenericMethod(t), [Expr.Call(d.GetGenericMethodDefinition().MakeGenericMethod(t),[])]) - - // deref v generates the equivalent of <@ !v @> - // (so v's type must be ref) - let deref (v:Quotations.Var) = - let m = match <@ !(ref 1) @> with Call(None, m, [_]) -> m | _ -> failwith "Extracting MethodInfo from <@ !(ref 1) @> failed" - let tyArgs = v.Type.GetGenericArguments() - Expr.Call(m.GetGenericMethodDefinition().MakeGenericMethod(tyArgs), [Expr.Var v]) - - // substitution mapping a variable v to the expression <@ !v' @> using the corresponding new variable v' of ref type - let subst = - let map = - vars' - |> List.map deref - |> List.zip vars - |> Map.ofList - fun v -> Map.tryFind v map - - let expr' = expr.Substitute(subst) - - // maps variables to new variables - let varDict = List.zip vars vars' |> dict - - // given an old variable v and an expression e, returns a quotation like <@ v' := e @> using the corresponding new variable v' of ref type - let setRef (v:Quotations.Var) e = - let m = match <@ (ref 1) := 2 @> with Call(None, m, [_;_]) -> m | _ -> failwith "Extracting MethodInfo from <@ (ref 1) := 2 @> failed" - Expr.Call(m.GetGenericMethodDefinition().MakeGenericMethod(v.Type), [Expr.Var varDict.[v]; e]) - - // Something like - // <@ - // v1 := e1' - // v2 := e2' - // ... - // expr' - // @> - // Note that we must substitute our new variable dereferences into the bound expressions - let body = - bindings - |> List.fold (fun b (v,e) -> Expr.Sequential(setRef v (e.Substitute subst), b)) expr' - - // Something like - // let v1 = ref Unchecked.defaultof - // let v2 = ref Unchecked.defaultof - // ... - // body - vars - |> List.fold (fun b v -> Expr.LetUnchecked(varDict.[v], init v.Type, b)) body - |> trans + | LetRecursive(bindings, expr) -> simplifyLetRec bindings expr // Handle the generic cases - | ShapeLambdaUnchecked(v,body) -> - Expr.Lambda(v, trans body) - | ShapeCombinationUnchecked(comb,args) -> - RebuildShapeCombinationUnchecked(comb,List.map trans args) + | ShapeLambdaUnchecked(v,body) -> Expr.Lambda(v, simplifyExpr body) + | ShapeCombinationUnchecked(comb,args) -> RebuildShapeCombinationUnchecked(comb,List.map simplifyExpr args) | ShapeVarUnchecked _ -> q - and inlineByref v vexpr bexpr = + and simplifyLetRec bindings expr = + // This uses a "lets and sets" approach, converting something like + // let rec even = function + // | 0 -> true + // | n -> odd (n-1) + // and odd = function + // | 0 -> false + // | n -> even (n-1) + // X + // to something like + // let even = ref Unchecked.defaultof<_> + // let odd = ref Unchecked.defaultof<_> + // even := function + // | 0 -> true + // | n -> !odd (n-1) + // odd := function + // | 0 -> false + // | n -> !even (n-1) + // X' + // where X' is X but with occurrences of even/odd substituted by !even and !odd (since now even and odd are references) + // Translation relies on typedefof<_ ref> - does this affect ability to target different runtime and design time environments? + let vars = List.map fst bindings + let refVars = vars |> List.map (fun v -> Var(v.Name, ProvidedTypeBuilder.MakeGenericType(typedefof<_ ref>, [v.Type]))) + + // "init t" generates the equivalent of <@ ref Unchecked.defaultof @> + let init (t:Type) = + let r = match <@ ref 1 @> with Call(None, r, [_]) -> r | _ -> failwith "Extracting MethodInfo from <@ 1 @> failed" + let d = match <@ Unchecked.defaultof<_> @> with Call(None, d, []) -> d | _ -> failwith "Extracting MethodInfo from <@ Unchecked.defaultof<_> @> failed" + let ir = ProvidedTypeBuilder.MakeGenericMethod(r.GetGenericMethodDefinition(), [ t ]) + let id = ProvidedTypeBuilder.MakeGenericMethod(d.GetGenericMethodDefinition(), [ t ]) + Expr.CallUnchecked(ir, [Expr.CallUnchecked(id, [])]) + + // deref v generates the equivalent of <@ !v @> + // (so v's type must be ref) + let deref (v:Var) = + let m = match <@ !(ref 1) @> with Call(None, m, [_]) -> m | _ -> failwith "Extracting MethodInfo from <@ !(ref 1) @> failed" + let tyArgs = v.Type.GetGenericArguments() + let im = ProvidedTypeBuilder.MakeGenericMethod(m.GetGenericMethodDefinition(), Array.toList tyArgs) + Expr.CallUnchecked(im, [Expr.Var v]) + + // substitution mapping a variable v to the expression <@ !v' @> using the corresponding new variable v' of ref type + let subst = + let map = [ for v in refVars -> v.Name, deref v ] |> Map.ofList + fun (v:Var) -> Map.tryFind v.Name map + + let refExpr = expr.Substitute(subst) + + // maps variables to new variables + let varDict = [ for (v, rv) in List.zip vars refVars -> v.Name, rv ] |> dict + + // given an old variable v and an expression e, returns a quotation like <@ v' := e @> using the corresponding new variable v' of ref type + let setRef (v:Var) e = + let m = match <@ (ref 1) := 2 @> with Call(None, m, [_;_]) -> m | _ -> failwith "Extracting MethodInfo from <@ (ref 1) := 2 @> failed" + let im = ProvidedTypeBuilder.MakeGenericMethod(m.GetGenericMethodDefinition(), [ v.Type ]) + Expr.CallUnchecked(im, [Expr.Var varDict.[v.Name]; e]) + + // Something like + // <@ + // v1 := e1' + // v2 := e2' + // ... + // refExpr + // @> + // Note that we must substitute our new variable dereferences into the bound expressions + let body = + bindings + |> List.fold (fun b (v,e) -> Expr.Sequential(setRef v (e.Substitute subst), b)) refExpr + + // Something like + // let v1 = ref Unchecked.defaultof + // let v2 = ref Unchecked.defaultof + // ... + // body + (body, vars) + ||> List.fold (fun b v -> Expr.LetUnchecked(varDict.[v.Name], init v.Type, b)) + |> simplifyExpr + + + and transLetOfByref v vexpr bexpr = match vexpr with | Sequential(e',vexpr') -> (* let v = (e'; vexpr') in bexpr => e'; let v = vexpr' in bexpr *) - Expr.Sequential(e', inlineByref v vexpr' bexpr) - |> trans + Expr.Sequential(e', transLetOfByref v vexpr' bexpr) + |> simplifyExpr | IfThenElse(c,b1,b2) -> (* let v = if c then b1 else b2 in bexpr => if c then let v = b1 in bexpr else let v = b2 in bexpr *) - Expr.IfThenElse(c, inlineByref v b1 bexpr, inlineByref v b2 bexpr) - |> trans - | Var _ -> + // + // Note, this duplicates "bexpr" + Expr.IfThenElseUnchecked(c, transLetOfByref v b1 bexpr, transLetOfByref v b2 bexpr) + |> simplifyExpr + | Var _ -> (* let v = v1 in bexpr => bexpr[v/v1] *) bexpr.Substitute(fun v' -> if v = v' then Some vexpr else None) - |> trans - | _ -> - failwith (sprintf "Unexpected byref binding: %A = %A" v vexpr) - - and transValue (v : obj, tyOfValue : Type, expectedTy : Type) = - let rec transArray (o : Array, ty : Type) = - let elemTy = ty.GetElementType() - let converter = getConverterForType elemTy - let elements = - [ - for el in o do - yield converter el - ] - Expr.NewArrayUnchecked(elemTy, elements) - and transList(o, ty : Type, nil, cons) = - let converter = getConverterForType (ty.GetGenericArguments().[0]) - o - |> Seq.cast - |> List.ofSeq - |> fun l -> List.foldBack(fun o s -> Expr.NewUnionCase(cons, [ converter(o); s ])) l (Expr.NewUnionCase(nil, [])) - |> trans - - and getConverterForType (ty : Type) = - if ty.IsArray then - fun (v : obj) -> transArray(v :?> Array, ty) - elif ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ list> then - let nil, cons = - let cases = Reflection.FSharpType.GetUnionCases(ty) - let a = cases.[0] - let b = cases.[1] - if a.Name = "Empty" then a,b - else b,a - - fun v -> transList (v :?> System.Collections.IEnumerable, ty, nil, cons) - else - fun v -> Expr.Value(v, ty) - let converter = getConverterForType tyOfValue + |> simplifyExpr + | _ -> + failwithf "Unexpected byref binding: %A = %A. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" v vexpr + + and transValueArray (o: Array, ty: Type) = + let elemTy = ty.GetElementType() + let converter = getValueConverterForType elemTy + let elements = [ for el in o -> converter el ] + Expr.NewArrayUnchecked(elemTy, elements) + + and transValueList(o, ty: Type, nil, cons) = + let converter = getValueConverterForType (ty.GetGenericArguments().[0]) + o + |> Seq.cast + |> List.ofSeq + |> fun l -> List.foldBack(fun o s -> Expr.NewUnionCase(cons, [ converter(o); s ])) l (Expr.NewUnionCase(nil, [])) + |> simplifyExpr + + and getValueConverterForType (ty: Type) = + if ty.IsArray then + fun (v: obj) -> transValueArray(v :?> Array, ty) + elif ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ list> then + let nil, cons = + let cases = Reflection.FSharpType.GetUnionCases(ty) + let a = cases.[0] + let b = cases.[1] + if a.Name = "Empty" then a,b + else b,a + + fun v -> transValueList (v :?> System.Collections.IEnumerable, ty, nil, cons) + else + fun v -> Expr.Value(v, ty) + + and transValue (v: obj, tyOfValue: Type, expectedTy: Type) = + let converter = getValueConverterForType tyOfValue let r = converter v if tyOfValue <> expectedTy then Expr.Coerce(r, expectedTy) else r - trans q - - let getFastFuncType (args : list) resultType = - let types = - [| - for arg in args -> arg.Type - yield resultType - |] - let fastFuncTy = - match List.length args with - | 2 -> typedefof>.MakeGenericType(types) - | 3 -> typedefof>.MakeGenericType(types) - | 4 -> typedefof>.MakeGenericType(types) - | 5 -> typedefof>.MakeGenericType(types) - | _ -> invalidArg "args" "incorrect number of arguments" - fastFuncTy.GetMethod("Adapt") - - let inline (===) a b = LanguagePrimitives.PhysicalEquality a b - - let traverse f = - let rec fallback e = - match e with - | Let(v, value, body) -> - let fixedValue = f fallback value - let fixedBody = f fallback body - if fixedValue === value && fixedBody === body then - e + +#if !NO_GENERATIVE + let getFastFuncType (args: list) resultType = + let types = + [| for arg in args -> arg.Type + yield resultType |] + let fastFuncTy = + match List.length args with + | 2 -> typedefof>.MakeGenericType(types) + | 3 -> typedefof>.MakeGenericType(types) + | 4 -> typedefof>.MakeGenericType(types) + | 5 -> typedefof>.MakeGenericType(types) + | _ -> invalidArg "args" "incorrect number of arguments" + fastFuncTy.GetMethod("Adapt") + + let (===) a b = LanguagePrimitives.PhysicalEquality a b + + let traverse f = + let rec fallback e = + match e with + | Let(v, value, body) -> + let fixedValue = f fallback value + let fixedBody = f fallback body + if fixedValue === value && fixedBody === body then + e + else + Expr.LetUnchecked(v, fixedValue, fixedBody) + | ShapeVarUnchecked _ -> e + | ShapeLambdaUnchecked(v, body) -> + let fixedBody = f fallback body + if fixedBody === body then + e + else + Expr.Lambda(v, fixedBody) + | ShapeCombinationUnchecked(shape, exprs) -> + let exprs1 = List.map (f fallback) exprs + if List.forall2 (===) exprs exprs1 then + e + else + RebuildShapeCombinationUnchecked(shape, exprs1) + fun e -> f fallback e + + let rightPipe = <@@ (|>) @@> + let inlineRightPipe expr = + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | SpecificCall rightPipe (None, _, [operand; applicable]) -> + let fixedOperand = loop operand + match loop applicable with + | Lambda(arg, body) -> + let v = Var("__temp", operand.Type) + let ev = Expr.Var v + + let fixedBody = loop body + Expr.Let(v, fixedOperand, fixedBody.Substitute(fun v1 -> if v1 = arg then Some ev else None)) + | fixedApplicable -> Expr.Application(fixedApplicable, fixedOperand) + | x -> fallback x + loop expr + + + let inlineValueBindings e = + let map = Dictionary(HashIdentity.Reference) + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | Let(id, (Value(_) as v), body) when not id.IsMutable -> + map.[id] <- v + let fixedBody = loop body + map.Remove(id) |> ignore + fixedBody + | ShapeVarUnchecked v -> + match map.TryGetValue v with + | true, e -> e + | _ -> orig + | x -> fallback x + loop e + + + let optimizeCurriedApplications expr = + let rec loop expr = traverse loopCore expr + and loopCore fallback orig = + match orig with + | Application(e, arg) -> + let e1 = tryPeelApplications e [loop arg] + if e1 === e then + orig + else + e1 + | x -> fallback x + and tryPeelApplications orig args = + let n = List.length args + match orig with + | Application(e, arg) -> + let e1 = tryPeelApplications e ((loop arg)::args) + if e1 === e then + orig + else + e1 + | Let(id, applicable, (Lambda(_) as body)) when n > 0 -> + let numberOfApplication = countPeelableApplications body id 0 + if numberOfApplication = 0 then orig + elif n = 1 then Expr.Application(applicable, List.head args) + elif n <= 5 then + let resultType = + applicable.Type + |> Seq.unfold (fun t -> + if not t.IsGenericType then None else + let args = t.GetGenericArguments() + if args.Length <> 2 then None else + Some (args.[1], args.[1]) + ) + |> Seq.toArray + |> (fun arr -> arr.[n - 1]) + + let adaptMethod = getFastFuncType args resultType + let adapted = Expr.Call(adaptMethod, [loop applicable]) + let invoke = adapted.Type.GetMethod("Invoke", [| for arg in args -> arg.Type |]) + Expr.Call(adapted, invoke, args) + else + (applicable, args) ||> List.fold (fun e a -> Expr.Application(e, a)) + | _ -> + orig + and countPeelableApplications expr v n = + match expr with + // v - applicable entity obtained on the prev step + // \arg -> let v1 = (f arg) in rest ==> f + | Lambda(arg, Let(v1, Application(Var f, Var arg1), rest)) when v = f && arg = arg1 -> countPeelableApplications rest v1 (n + 1) + // \arg -> (f arg) ==> f + | Lambda(arg, Application(Var f, Var arg1)) when v = f && arg = arg1 -> n + | _ -> n + loop expr +#endif + + member _.TranslateExpression q = simplifyExpr q + + member _.TranslateQuotationToCode qexprf (paramNames: string[]) (argExprs: Expr[]) = + // Use the real variable names instead of indices, to improve output of Debug.fs + // Add let bindings for arguments to ensure that arguments will be evaluated + let varDecisions = argExprs |> Array.mapi (fun i e -> match e with Var v when v.Name = paramNames.[i] -> false, v | _ -> true, Var(paramNames.[i], e.Type)) + let vars = varDecisions |> Array.map snd + let expr = qexprf ([for v in vars -> Expr.Var v]) + + let pairs = Array.zip argExprs varDecisions + let expr = Array.foldBack (fun (arg, (replace, var)) e -> if replace then Expr.LetUnchecked(var, arg, e) else e) pairs expr +#if !NO_GENERATIVE + let expr = + if isGenerated then + let e1 = inlineRightPipe expr + let e2 = optimizeCurriedApplications e1 + let e3 = inlineValueBindings e2 + e3 + else + expr +#endif + + simplifyExpr expr + + /// A cross-targeting type provider must ultimately provide quotations and reflection objects w.r.t. + /// the type binding context for the target assembly reference set. + /// + /// To make building a cross-targeting type provider palatable, the type provider is written w.r.t. to + /// homogeneous quotations and reflection objects referring to a copy of the target runtime constructs held + /// in the design-time assembly itself. These are then systematically remapped (replaced/translated) to the + /// corresponding reflection objects in the target assembly reference set. + /// + /// The ProvidedTypesContext acts as a way of creating provided objects where the replacement is automatically and + /// systematically applied. + + + /// Represents the type binding context for the type provider based on the set of assemblies + /// referenced by the compilation. + type ProvidedTypesContext(referencedAssemblyPaths: string list, assemblyReplacementMap: (string*string) list, sourceAssemblies: Assembly list) as this = + + // A duplicate 'mscorlib' appears in the paths reported by the F# compiler + let referencedAssemblyPaths = referencedAssemblyPaths |> Seq.distinctBy Path.GetFileNameWithoutExtension |> Seq.toList + //do System.Diagnostics.Debugger.Break() + + /// Find which assembly defines System.Object etc. + let systemRuntimeScopeRef = + lazy + referencedAssemblyPaths |> List.tryPick (fun path -> + try + let simpleName = Path.GetFileNameWithoutExtension path + if simpleName = "mscorlib" || simpleName = "System.Runtime" || simpleName = "netstandard" then + let reader = ILModuleReaderAfterReadingAllBytes (path, mkILGlobals EcmaMscorlibScopeRef) + let mdef = reader.ILModuleDef + match mdef.TypeDefs.TryFindByName(USome "System", "Object") with + | None -> None + | Some _ -> + let m = mdef.ManifestOfAssembly + let assemblyRef = ILAssemblyRef(m.Name, UNone, (match m.PublicKey with USome k -> USome (PublicKey.KeyAsToken(k)) | UNone -> UNone), m.Retargetable, m.Version, m.Locale) + Some (ILScopeRef.Assembly assemblyRef) else - Expr.Let(v, fixedValue, fixedBody) - | ShapeVarUnchecked _ -> e - | ShapeLambdaUnchecked(v, body) -> - let fixedBody = f fallback body - if fixedBody === body then - e + None + with _ -> None ) + |> function + | None -> EcmaMscorlibScopeRef // failwith "no reference to mscorlib.dll or System.Runtime.dll or netstandard.dll found" + | Some r -> r + + let fsharpCoreRefVersion = + lazy + referencedAssemblyPaths |> List.tryPick (fun path -> + try + let simpleName = Path.GetFileNameWithoutExtension path + if simpleName = "FSharp.Core" then + let reader = ILModuleReaderAfterReadingAllBytes (path, mkILGlobals (systemRuntimeScopeRef.Force())) + match reader.ILModuleDef.Manifest with + | Some m -> match m.Version with USome v -> Some v | UNone -> None + | None -> None else - Expr.Lambda(v, fixedBody) - | ShapeCombinationUnchecked(shape, exprs) -> - let exprs1 = List.map (f fallback) exprs - if List.forall2 (===) exprs exprs1 then - e + None + with _ -> None ) + |> function + | None -> typeof.Assembly.GetName().Version // failwith "no reference to FSharp.Core found" + | Some r -> r + + let ilGlobals = + lazy mkILGlobals (systemRuntimeScopeRef.Force()) + + let mkReader ref = + try let reader = ILModuleReaderAfterReadingAllBytes(ref, ilGlobals.Force()) + Choice1Of2(TargetAssembly(ilGlobals.Force(), this.TryBindILAssemblyRefToTgt, Some reader, ref) :> Assembly) + with err -> Choice2Of2 err + + let targetAssembliesTable_ = ConcurrentDictionary>() + let targetAssemblies_ = ResizeArray() + let targetAssembliesQueue = ResizeArray<_>() + do targetAssembliesQueue.Add (fun () -> + for ref in referencedAssemblyPaths do + let reader = mkReader ref + let simpleName = Path.GetFileNameWithoutExtension ref + targetAssembliesTable_.[simpleName] <- reader + match reader with + | Choice2Of2 _ -> () + | Choice1Of2 asm -> targetAssemblies_.Add asm) + let flush() = + let qs = targetAssembliesQueue.ToArray() + targetAssembliesQueue.Clear() + for q in qs do q() + let getTargetAssemblies() = flush(); targetAssemblies_ + let getTargetAssembliesTable() = flush(); targetAssembliesTable_ + + let tryBindTargetAssemblySimple(simpleName:string): Choice = + let table = getTargetAssembliesTable() + if table.ContainsKey(simpleName) then table.[simpleName] + else Choice2Of2 (Exception(sprintf "assembly %s not found" simpleName)) + + let sourceAssembliesTable_ = ConcurrentDictionary() + let sourceAssemblies_ = ResizeArray<_>() + let sourceAssembliesQueue = ResizeArray<_>() + + let enqueueReferencedAssemblies(asm: Assembly) = + do sourceAssembliesQueue.Add (fun () -> + [| for referencedAssemblyName in asm.GetReferencedAssemblies() do + let referencedAssembly = try Assembly.Load(referencedAssemblyName) with _ -> null + if not (isNull referencedAssembly) then + yield referencedAssembly |]) + + do sourceAssembliesQueue.Add (fun () -> List.toArray sourceAssemblies) + + let getSourceAssemblies() = + while sourceAssembliesQueue.Count > 0 do + let qs = sourceAssembliesQueue.ToArray() + sourceAssembliesQueue.Clear() + for q in qs do + for asm in q() do + let simpleName = asm.GetName().Name + if not (sourceAssembliesTable_.ContainsKey(simpleName)) then + sourceAssembliesTable_.[simpleName] <- asm + sourceAssemblies_.Add asm + // Find the transitive closure of all referenced assemblies + enqueueReferencedAssemblies asm + + sourceAssemblies_ + + /// When translating quotations, Expr.Var's are translated to new variable respecting reference equality. + let varTableFwd = Dictionary() + let varTableBwd = Dictionary() + let assemblyTableFwd = Dictionary() + let typeTableFwd = Dictionary() + let typeTableBwd = Dictionary() + + let fixName (fullName:string) = + if fullName.StartsWith("FSI_") then + // when F# Interactive is the host of the design time assembly, + // all namespaces are prefixed with FSI_, in the runtime assembly + // the name won't have that prefix + fullName.Substring(fullName.IndexOf('.') + 1) + else + fullName + + let tryGetTypeFromAssembly toTgt (originalAssemblyName:string) fullName (asm:Assembly) = + // if the original assembly of the type being replaced is in `assemblyReplacementMap`, + // then we only map it to assemblies with a name specified in `assemblyReplacementMap` + let restrictedAndMatching = + assemblyReplacementMap + |> Seq.exists (fun (originalName:string, newName:string) -> + originalAssemblyName.StartsWith originalName && not (asm.FullName.StartsWith(newName))) + + // Check if the assembly can be queried for types yet. Cross-assembly recursive linking back to generated assemblies + // is not supported in some cases where recursive linking is needed during the process of generation itself. + let canQuery = (match asm with :? TargetAssembly as t -> t.Reader.IsSome | _ -> true) + + if not canQuery then None + elif restrictedAndMatching then None + elif asm.FullName.StartsWith "FSI-ASSEMBLY" then + // when F# Interactive is the host of the design time assembly, + // for each type in the runtime assembly there might be multiple + // versions (FSI_0001.FullTypeName, FSI_0002.FullTypeName, etc). + // Get the last one. + asm.GetTypes() + |> Seq.filter (fun t -> fixName t.FullName = fullName) + |> Seq.sortBy (fun t -> t.FullName) + |> Seq.toList + |> function [] -> None | xs -> Some (Seq.last xs, false) + else + asm.GetType fullName |> function null -> None | x -> Some (x, true) + + + let rec convTypeRef toTgt (t:Type) = + let table = (if toTgt then typeTableFwd else typeTableBwd) + match table.TryGetValue(t) with + | true, newT -> newT + | false, _ -> + match t with + | :? ProvidedTypeDefinition as ptd when toTgt (* && ptd.IsErased *) -> + if ptd.BelongsToTargetModel then failwithf "unexpected erased target ProvidedTypeDefinition '%O'" ptd + // recursively get the provided type. + convTypeDefToTgt t + + | _ -> + let asms = (if toTgt then getTargetAssemblies() else getSourceAssemblies()) + let fullName = fixName t.FullName + + // TODO: this linear search through all available source/target assemblies feels as if it must be too slow in some cases. + // However, we store type translations in various tables (typeTableFwd and typeTableBwd) so perhaps it is not a problem + match asms |> Seq.tryPick (tryGetTypeFromAssembly toTgt t.Assembly.FullName fullName) with + | Some (newT, canSave) -> + if canSave then table.[t] <- newT + newT + | _ -> + let msg = + if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList) + elif getSourceAssemblies() |> Seq.length = 0 then sprintf "A failure occured while determining compilation references" + else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList) + failwith msg + + + and convType toTgt (t:Type) = + let table = (if toTgt then typeTableFwd else typeTableBwd) + match table.TryGetValue(t) with + | true, newT -> newT + | false, _ -> + if t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpTypeAbbreviation then t + // Types annotated with units-of-measure + elif t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpUnitAnnotated then + let genericType = t.GetGenericTypeDefinition() + let newT = convTypeRef toTgt genericType + let typeArguments = t.GetGenericArguments() |> Array.map (convType toTgt) |> Array.toList + ProvidedMeasureBuilder.AnnotateType(newT, typeArguments) + elif t.IsGenericType && not t.IsGenericTypeDefinition then + let genericType = t.GetGenericTypeDefinition() + let newT = convTypeRef toTgt genericType + let typeArguments = t.GetGenericArguments() |> Array.map (convType toTgt) + newT.MakeGenericType(typeArguments) + elif t.IsGenericParameter then t + elif t.IsArray || t.IsByRef || t.IsPointer then + let elemType = t.GetElementType() + let elemTypeT = convType toTgt elemType + if t.IsArray then + let rank = t.GetArrayRank() + if rank = 1 then elemTypeT.MakeArrayType() else elemTypeT.MakeArrayType(t.GetArrayRank()) + elif t.IsByRef then elemTypeT.MakeByRefType() + else elemTypeT.MakePointerType() + + else + convTypeRef toTgt t + + and convTypeToTgt ty = convType true ty + and convTypeToSrc ty = convType false ty + + and convPropertyRefToTgt (p: PropertyInfo) = + Debug.Assert((match p with :? ProvidedProperty as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedProperty") + let t = convTypeToTgt p.DeclaringType + let bindingFlags = bindSome p.IsStatic + let pT = t.GetProperty(p.Name, bindingFlags) + if isNull pT then failwithf "Property '%O' of type '%O' not found. This property may be missing in the types available in the target assemblies." p t + Debug.Assert((match pT with :? ProvidedProperty as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedProperty") + pT + + and convFieldRefToTgt (f: FieldInfo) = + Debug.Assert((match f with :? ProvidedField as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedField") + let t = convTypeToTgt f.DeclaringType + let fT = t.GetField(f.Name, bindSome f.IsStatic) + if isNull fT then failwithf "Field '%O' of type '%O' not found. This field may be missing in the types available in the target assemblies." f t + Debug.Assert((match fT with :? ProvidedField as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedField") + fT + + and convMethodRefToTgt (m: MethodInfo) = + Debug.Assert((match m with :? ProvidedMethod as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedMethod") + //Debug.Assert (m.Name <> "get_Item1" || m.DeclaringType.Name <> "Tuple`2") + let declTyT = convTypeToTgt m.DeclaringType + let mT = + if m.IsGenericMethod then + let genericMethod = m.GetGenericMethodDefinition() + let parameterTypesT = genericMethod.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + let genericMethodT = declTyT.GetMethod(genericMethod.Name, bindSome m.IsStatic, null, parameterTypesT, null) + if isNull genericMethodT then null else + let typeArgumentsT = m.GetGenericArguments() |> Array.map convTypeToTgt + genericMethodT.MakeGenericMethod(typeArgumentsT) + else + let parameterTypesT = m.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + declTyT.GetMethod(m.Name, bindSome m.IsStatic, null, parameterTypesT, null) + match mT with + | null -> failwithf "Method '%O' not found in type '%O'. This method may be missing in the types available in the target assemblies." m mT + | _ -> + Debug.Assert((match mT with :? ProvidedMethod as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedMethod") + mT + + and convConstructorRefToTgt (cons: ConstructorInfo) = + Debug.Assert((match cons with :? ProvidedConstructor as x -> not x.BelongsToTargetModel | _ -> true), "unexpected target ProvidedConstructor") + let declTyT = convTypeToTgt cons.DeclaringType + let parameterTypesT = cons.GetParameters() |> Array.map (fun p -> convTypeToTgt p.ParameterType) + let consT = declTyT.GetConstructor(parameterTypesT) + match consT with + | null -> failwithf "Constructor '%O' not found in type '%O'. This constructor may be missing in the types available in the target assemblies." cons declTyT + | _ -> + Debug.Assert((match consT with :? ProvidedConstructor as x -> x.BelongsToTargetModel | _ -> true), "expected a target ProvidedConstructor") + consT + + and convVarToSrc (v: Var) = + match varTableBwd.TryGetValue v with + | true, v -> v + | false, _ -> + let newVar = Var (v.Name, convTypeToSrc v.Type, v.IsMutable) + // store the original var as we'll have to revert to it later + varTableBwd.Add(v, newVar) + varTableFwd.Add(newVar, v) + newVar + + and convVarExprToSrc quotation = + match quotation with + | ShapeVarUnchecked v -> + Expr.Var (convVarToSrc v) + | _ -> failwithf "Unexpected non-variable argument: %A" quotation + + and convVarToTgt (v: Var) = + match varTableFwd.TryGetValue v with + | true, v -> v + | false, _ -> + // It's a variable local to the quotation + let newVar = Var (v.Name, convTypeToTgt v.Type, v.IsMutable) + // store it so we reuse it from now on + varTableFwd.Add(v, newVar) + varTableBwd.Add(newVar, v) + newVar + + + and convExprToTgt quotation = + match quotation with + | Call (obj, m, args) -> + let mR = convMethodRefToTgt m + let argsR = List.map convExprToTgt args + match obj with + | Some obj -> Expr.CallUnchecked (convExprToTgt obj, mR, argsR) + | None -> Expr.CallUnchecked (mR, argsR) + | PropertyGet (obj, p, indexArgs) -> + let pR = convPropertyRefToTgt p + let indexArgsR = List.map convExprToTgt indexArgs + match obj with + | Some obj -> Expr.PropertyGetUnchecked (convExprToTgt obj, pR, indexArgsR) + | None -> Expr.PropertyGetUnchecked (pR, indexArgsR) + | PropertySet (obj, p, indexArgs, value) -> + let pR = convPropertyRefToTgt p + let indexArgsR = List.map convExprToTgt indexArgs + match obj with + | Some obj -> Expr.PropertySetUnchecked (convExprToTgt obj, pR, convExprToTgt value, indexArgsR) + | None -> Expr.PropertySetUnchecked (pR, convExprToTgt value, indexArgsR) + | NewObject (c, exprs) -> + let exprsR = List.map convExprToTgt exprs + Expr.NewObjectUnchecked (convConstructorRefToTgt c, exprsR) + | Coerce (expr, t) -> + Expr.Coerce (convExprToTgt expr, convTypeToTgt t) + | NewArray (t, exprs) -> + Expr.NewArrayUnchecked (convTypeToTgt t, List.map convExprToTgt exprs) + | NewTuple (exprs) -> + Expr.NewTuple (List.map convExprToTgt exprs) + | Lambda (v,expr) -> + Expr.Lambda (convVarToTgt v, convExprToTgt expr) + | TupleGet (expr, i) -> + Expr.TupleGetUnchecked (convExprToTgt expr, i) + | NewDelegate (t, vars, expr) -> + Expr.NewDelegateUnchecked (convTypeToTgt t, List.map convVarToTgt vars, convExprToTgt expr) + | FieldGet (obj, f) -> + match obj with + | Some obj -> Expr.FieldGetUnchecked (convExprToTgt obj, convFieldRefToTgt f) + | None -> Expr.FieldGetUnchecked (convFieldRefToTgt f) + | FieldSet (obj, f, value) -> + match obj with + | Some obj -> Expr.FieldSetUnchecked (convExprToTgt obj, convFieldRefToTgt f, convExprToTgt value) + | None -> Expr.FieldSetUnchecked (convFieldRefToTgt f, convExprToTgt value) + | Let (var, value, body) -> + Expr.LetUnchecked(convVarToTgt var, convExprToTgt value, convExprToTgt body) + + // Eliminate some F# constructs which do not cross-target well + | Application(f,e) -> + convExprToTgt (Expr.CallUnchecked(f, f.Type.GetMethod "Invoke", [ e ]) ) + | NewUnionCase(ci, es) -> + convExprToTgt (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) ) + | NewRecord(ci, es) -> + convExprToTgt (Expr.NewObjectUnchecked(FSharpValue.PreComputeRecordConstructorInfo ci, es) ) + | UnionCaseTest(e,uc) -> + let tagInfo = FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType + let tagExpr = + match tagInfo with + | :? PropertyInfo as tagProp -> Expr.PropertyGetUnchecked(e,tagProp) + | :? MethodInfo as tagMeth -> + if tagMeth.IsStatic then Expr.CallUnchecked(tagMeth, [e]) + else Expr.CallUnchecked(e,tagMeth,[]) + | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo" + let tagNumber = uc.Tag + convExprToTgt <@@ (%%(tagExpr): int) = tagNumber @@> + + | Value (obj,ty) -> + match obj with + | :? Type as vty -> Expr.Value(convTypeToTgt vty, ty) + | _ -> Expr.Value(obj, convTypeToTgt ty) + + // Traverse remaining constructs + | ShapeVarUnchecked v -> + Expr.Var (convVarToTgt v) + | ShapeLambdaUnchecked _ as d -> + failwithf "It's not possible to use construct %O when cross targetting to a different FSharp.Core. Make sure you're not calling a function with signature A->(B->C) instead of A->B->C (using |> causes this)." d + | ShapeCombinationUnchecked (o, exprs) -> + RebuildShapeCombinationUnchecked (o, List.map convExprToTgt exprs) + + and convCodeToTgt (codeFun: Expr list -> Expr, isStatic, isCtor, parameters: ProvidedParameter[], isGenerated) = + (fun argsT -> + let args = List.map convVarExprToSrc argsT + let paramNames = + // https://github.com/fsprojects/SwaggerProvider/blob/cfb7a665fada77fd0200591f62faba0ba44e172c/src/SwaggerProvider.DesignTime/SwaggerProviderConfig.fs#L79 + // "Erased constructors should not pass the instance as the first argument when calling invokeCode!" + // "Generated constructors should always pass the instance as the first argument when calling invokeCode!" + [| if not isStatic && (not isCtor || isGenerated) then yield "this" + for p in parameters do yield p.Name |] + let code2 = QuotationSimplifier(isGenerated).TranslateQuotationToCode codeFun paramNames (Array.ofList args) + let codeT = convExprToTgt code2 + codeT) + + and convBaseCallToTgt (codeFun: Expr list -> ConstructorInfo * Expr list, isGenerated) = + (fun argsT -> + let args = List.map convVarExprToSrc argsT + let ctor, argExprs = codeFun args + let argExprs2 = List.map (QuotationSimplifier(isGenerated).TranslateExpression) argExprs + //let code2 = QuotationSimplifier(false).TranslateQuotationToCode code paramNames + let ctorT = convConstructorRefToTgt ctor + let codeT = List.map convExprToTgt argExprs2 + ctorT, codeT) + + and convCustomAttributesDataToTgt (d: IList) = Seq.toArray d // TODO: Consider converting these + + and convProvidedTypeDefToTgt (x: ProvidedTypeDefinition) = + if x.BelongsToTargetModel then failwithf "unexpected target type definition '%O'" x + match typeTableFwd.TryGetValue(x) with + | true, newT -> (newT :?> ProvidedTypeDefinition) + | false, _ -> + let container = + match x.Container with + | TypeContainer.Namespace(assemf, nm) -> + TypeContainer.Namespace((fun () -> + match assemf() with + | :? ProvidedAssembly as assembly -> convProvidedAssembly assembly + | assembly -> + assemblyReplacementMap + |> Seq.tryPick (fun (originalName, newName) -> + if assembly.GetName().Name = originalName then + match this.TryBindSimpleAssemblyNameToTarget(newName) with + | Choice1Of2 replacementAssembly -> Some replacementAssembly + | Choice2Of2 _ -> None + else + None) + |> function None -> assembly | Some replacementAssembly -> replacementAssembly + ), nm) + | c -> c // nested types patched below + + // Create the type definition with contents mapped to the target + // Use a 'let rec' to allow access to the target as the declaring + // type of the contents in a delayed way. + let rec xT : ProvidedTypeDefinition = + ProvidedTypeDefinition(true, container, x.Name, + (x.BaseTypeRaw >> Option.map convTypeToTgt), + x.AttributesRaw, + (x.EnumUnderlyingTypeRaw >> Option.map convTypeToTgt), + x.StaticParams |> List.map convStaticParameterDefToTgt, + x.StaticParamsApply |> Option.map (fun f s p -> + let t = f s p + let tT = convProvidedTypeDefToTgt t + tT), + Some ((let mutable idx = 0 in fun () -> let vs, idx2 = x.GetMembersFromCursor(idx) in idx <- idx2; vs |> Array.map (convMemberDefToTgt xT)), + (let mutable idx = 0 in fun () -> let vs, idx2 = x.GetInterfaceImplsFromCursor(idx) in idx <- idx2; vs |> Array.map convTypeToTgt), + (let mutable idx = 0 in fun () -> let vs, idx2 = x.GetMethodOverridesFromCursor(idx) in idx <- idx2; vs |> Array.map (fun (a,b) -> (convMethodRefToTgt a :?> ProvidedMethod), convMethodRefToTgt b))), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt), + x.HideObjectMethods, + x.NonNullable) + + Debug.Assert(not (typeTableFwd.ContainsKey(x))) + typeTableFwd.[x] <- xT + if x.IsNested then + let parentT = (convTypeToTgt x.DeclaringType :?> ProvidedTypeDefinition) + parentT.PatchDeclaringTypeOfMember xT + xT + + and convTypeDefToTgt (x: Type) = + match x with + | :? ProvidedTypeDefinition as x -> convProvidedTypeDefToTgt x :> Type + | _ -> x + + and convParameterDefToTgt (x: ProvidedParameter) = + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedParameter") + ProvidedParameter(true, x.Name, x.Attributes, + x.ParameterType |> convTypeToTgt, + x.OptionalValue, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) + + and convStaticParameterDefToTgt (x: ProvidedStaticParameter) = + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedStaticParameter") + ProvidedStaticParameter(x.Name, convTypeToTgt x.ParameterType, ?parameterDefaultValue=x.ParameterDefaultValue) + + and convMemberDefToTgt declTyT (x: MemberInfo) = + let xT : MemberInfo = + match x with + | :? ProvidedField as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedField") + ProvidedField(true, x.Name, x.Attributes, + x.FieldType |> convTypeToTgt, + x.GetRawConstantValue(), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedProperty as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedProperty") + ProvidedProperty(true, x.Name, x.Attributes, + x.PropertyType |> convTypeToTgt, + x.IsStatic, + x.Getter |> Option.map (fun f -> f >> convMethodRefToTgt), + x.Setter |> Option.map (fun f -> f >> convMethodRefToTgt), + x.IndexParameters |> Array.map convParameterDefToTgt, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedEvent as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedEvent") + ProvidedEvent(true, x.Name, x.Attributes, + x.EventHandlerType |> convTypeToTgt, + x.IsStatic, + (fun () -> convMethodRefToTgt x.Adder), + (fun () -> convMethodRefToTgt x.Remover), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedConstructor as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedConstructor") + ProvidedConstructor(true, x.Attributes, + x.Parameters |> Array.map convParameterDefToTgt, + convCodeToTgt (x.GetInvokeCode, x.IsStatic, true, x.Parameters, not x.IsErased), + (match x.BaseCall with None -> None | Some f -> Some (convBaseCallToTgt(f, not x.IsErased))), + x.IsImplicitConstructor, + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedMethod as x -> + Debug.Assert (not x.BelongsToTargetModel, "unexpected target ProvidedMethod") + ProvidedMethod(true, x.Name, x.Attributes, + x.Parameters |> Array.map convParameterDefToTgt, + x.ReturnType |> convTypeToTgt, + convCodeToTgt (x.GetInvokeCode, x.IsStatic, false, x.Parameters, not x.IsErased), + x.StaticParams |> List.map convStaticParameterDefToTgt, + x.StaticParamsApply |> Option.map (fun f s p -> f s p |> convProvidedMethodDefToTgt declTyT), + (x.GetCustomAttributesData >> convCustomAttributesDataToTgt)) :> _ + | :? ProvidedTypeDefinition as x -> convTypeDefToTgt x :> _ + | _ -> failwith "unknown member type" + Debug.Assert(declTyT.BelongsToTargetModel) + declTyT.PatchDeclaringTypeOfMember xT + Debug.Assert(xT.DeclaringType :? ProvidedTypeDefinition) + Debug.Assert((xT.DeclaringType :?> ProvidedTypeDefinition).BelongsToTargetModel) + xT + + and convProvidedMethodDefToTgt declTyT (x: ProvidedMethod) = + convMemberDefToTgt declTyT x :?> ProvidedMethod + + and convProvidedAssembly (assembly: ProvidedAssembly) = + match assemblyTableFwd.TryGetValue(assembly) with + | true, newT -> newT + | false, _ -> + let tgtAssembly = ProvidedAssembly(true, assembly.GetName(), assembly.Location) + + for (types, enclosingGeneratedTypeNames) in assembly.GetTheTypes() do + let typesT = Array.map convProvidedTypeDefToTgt types + tgtAssembly.AddTheTypes (typesT, enclosingGeneratedTypeNames) + + assemblyTableFwd.Add(assembly, tgtAssembly) + this.AddSourceAssembly(assembly) + this.AddTargetAssembly(assembly.GetName(), tgtAssembly) + (tgtAssembly :> Assembly) + + let rec convNamespaceToTgt (x: IProvidedNamespace) = + { new IProvidedNamespace with + member _.GetNestedNamespaces() = Array.map convNamespaceToTgt (x.GetNestedNamespaces()) + member _.NamespaceName = x.NamespaceName + member _.GetTypes() = Array.map convTypeDefToTgt (x.GetTypes()) + member _.ResolveTypeName typeName = convTypeDefToTgt (x.ResolveTypeName typeName) } + + /// Gets the equivalent target type + member _.ConvertSourceTypeToTarget t = convTypeToTgt t + + member _.ConvertTargetTypeToSource t = convTypeToSrc t + + member _.ConvertSourceExprToTarget e = convExprToTgt e + + member _.ConvertSourceNamespaceToTarget ns = convNamespaceToTgt ns + member _.ConvertSourceProvidedTypeDefinitionToTarget ptd = convProvidedTypeDefToTgt ptd + member _.TryBindILAssemblyRefToTgt(aref: ILAssemblyRef): Choice = tryBindTargetAssemblySimple(aref.Name) + + member _.TryBindAssemblyNameToTarget(aref: AssemblyName): Choice = tryBindTargetAssemblySimple(aref.Name) + + member _.TryBindSimpleAssemblyNameToTarget(assemblyName: string) = tryBindTargetAssemblySimple(assemblyName) + + member _.ILGlobals = ilGlobals.Value + + member _.ReferencedAssemblyPaths = referencedAssemblyPaths + + member _.GetTargetAssemblies() = getTargetAssemblies().ToArray() + + member _.GetSourceAssemblies() = getSourceAssemblies().ToArray() + + member _.FSharpCoreAssemblyVersion = fsharpCoreRefVersion.Force() + + member this.ReadRelatedAssembly(fileName) = + let ilg = ilGlobals.Force() + let reader = ILModuleReaderAfterReadingAllBytes(fileName, ilg) + TargetAssembly(ilg, this.TryBindILAssemblyRefToTgt, Some reader, fileName) :> Assembly + + member this.ReadRelatedAssembly(bytes:byte[]) = + let fileName = "file.dll" + let ilg = ilGlobals.Force() + let reader = ILModuleReader(fileName, ByteFile(bytes), ilg, true) + TargetAssembly(ilg, this.TryBindILAssemblyRefToTgt, Some reader, fileName) :> Assembly + + member _.AddSourceAssembly(asm: Assembly) = + sourceAssembliesQueue.Add (fun () -> [| asm |]) + + member _.AddTargetAssembly(asmName: AssemblyName, asm: Assembly) = + targetAssembliesQueue.Add (fun () -> + targetAssembliesTable_.[asmName.Name] <- Choice1Of2 asm + targetAssemblies_.Add asm) + + static member Create (config: TypeProviderConfig, assemblyReplacementMap, sourceAssemblies) = + + // Use the reflection hack to determine the set of referenced assemblies by reflecting over the SystemRuntimeContainsType + // closure in the TypeProviderConfig object. + let referencedAssemblyPaths = + try + + let hostConfigType = config.GetType() + let hostAssembly = hostConfigType.Assembly + let hostAssemblyLocation = hostAssembly.Location + + let msg = sprintf "Host is assembly '%A' at location '%s'" (hostAssembly.GetName()) hostAssemblyLocation + + if isNull (hostConfigType.GetField("systemRuntimeContainsType",bindAll)) then + failwithf "Invalid host of cross-targeting type provider: a field called systemRuntimeContainsType must exist in the TypeProviderConfiguration object. Please check that the type provider being hosted by the F# compiler tools or a simulation of them. %s" msg + + let systemRuntimeContainsTypeObj = config.GetField("systemRuntimeContainsType") + + // Account for https://github.com/Microsoft/visualfsharp/pull/591 + let systemRuntimeContainsTypeObj2 = + if systemRuntimeContainsTypeObj.HasField("systemRuntimeContainsTypeRef") then + systemRuntimeContainsTypeObj.GetField("systemRuntimeContainsTypeRef").GetProperty("Value") + else + systemRuntimeContainsTypeObj + + if not (systemRuntimeContainsTypeObj2.HasField("tcImports")) then + failwithf "Invalid host of cross-targeting type provider: a field called tcImports must exist in the systemRuntimeContainsType closure. Please check that the type provider being hosted by the F# compiler tools or a simulation of them. %s" msg + + let tcImports = systemRuntimeContainsTypeObj2.GetField("tcImports") + + if not (tcImports.HasField("dllInfos")) then + failwithf "Invalid host of cross-targeting type provider: a field called dllInfos must exist in the tcImports object. Please check that the type provider being hosted by the F# compiler tools or a simulation of them. %s" msg + + if not (tcImports.HasProperty("Base")) then + failwithf "Invalid host of cross-targeting type provider: a field called Base must exist in the tcImports object. Please check that the type provider being hosted by the F# compiler tools or a simulation of them. %s" msg + + let dllInfos = tcImports.GetField("dllInfos") + if isNull dllInfos then + let ty = dllInfos.GetType() + let fld = ty.GetField("dllInfos", bindAll) + failwithf """Invalid host of cross-targeting type provider: unexpected 'null' value in dllInfos field of TcImports, ty = %A, fld = %A. %s""" ty fld msg + + let baseObj = tcImports.GetProperty("Base") + + [ for dllInfo in dllInfos.GetElements() -> (dllInfo.GetProperty("FileName") :?> string) + if not (isNull baseObj) then + let baseObjValue = baseObj.GetProperty("Value") + if isNull baseObjValue then + let ty = baseObjValue.GetType() + let prop = ty.GetProperty("Value", bindAll) + failwithf """Invalid host of cross-targeting type provider: unexpected 'null' value in Value property of baseObj, ty = %A, prop = %A. %s""" ty prop msg + + let baseDllInfos = baseObjValue.GetField("dllInfos") + + if isNull baseDllInfos then + let ty = baseDllInfos.GetType() + let fld = ty.GetField("dllInfos", bindAll) + failwithf """Invalid host of cross-targeting type provider: unexpected 'null' value in dllInfos field of baseDllInfos, ty = %A, fld = %A. %s""" ty fld msg + + for baseDllInfo in baseDllInfos.GetElements() -> (baseDllInfo.GetProperty("FileName") :?> string) ] + with e -> + failwithf "Invalid host of cross-targeting type provider. Exception: %A" e + + + ProvidedTypesContext(referencedAssemblyPaths, assemblyReplacementMap, sourceAssemblies) + + + +#if !NO_GENERATIVE + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + module BinaryWriter = + + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + open System.Text + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + + let formatCodeLabel (x:int) = "L"+string x + + let emitBytesViaBuffer f = let bb = ByteBuffer.Create 10 in f bb; bb.Close() + + /// Alignment and padding + let align alignment n = ((n + alignment - 1) / alignment) * alignment + + //--------------------------------------------------------------------- + // Concrete token representations etc. used in PE files + //--------------------------------------------------------------------- + + + let getUncodedToken (tab:ILTableName) idx = ((tab.Index <<< 24) ||| idx) + + let markerForUnicodeBytes (b:byte[]) = + let len = b.Length + let rec scan i = + i < len/2 && + (let b1 = Bytes.get b (i*2) + let b2 = Bytes.get b (i*2+1) + (b2 <> 0) + || (b1 >= 0x01 && b1 <= 0x08) // as per ECMA and C# + || (b1 >= 0xE && b1 <= 0x1F) // as per ECMA and C# + || (b1 = 0x27) // as per ECMA and C# + || (b1 = 0x2D) // as per ECMA and C# + || (b1 > 0x7F) // as per C# (but ECMA omits this) + || scan (i+1)) + let marker = if scan 0 then 0x01 else 0x00 + marker + + + // -------------------------------------------------------------------- + // Fixups + // -------------------------------------------------------------------- + + /// Check that the data held at a fixup is some special magic value, as a sanity check + /// to ensure the fixup is being placed at a ood location. + let checkFixup32 (data: byte[]) offset exp = + if data.[offset + 3] <> b3 exp then failwith "fixup sanity check failed" + if data.[offset + 2] <> b2 exp then failwith "fixup sanity check failed" + if data.[offset + 1] <> b1 exp then failwith "fixup sanity check failed" + if data.[offset] <> b0 exp then failwith "fixup sanity check failed" + + let applyFixup32 (data:byte[]) offset v = + data.[offset] <- b0 v + data.[offset+1] <- b1 v + data.[offset+2] <- b2 v + data.[offset+3] <- b3 v + + //--------------------------------------------------------------------- + // TYPES FOR TABLES + //--------------------------------------------------------------------- + + module RowElementTags = + let [] UShort = 0 + let [] ULong = 1 + let [] Data = 2 + let [] DataResources = 3 + let [] Guid = 4 + let [] Blob = 5 + let [] String = 6 + let [] SimpleIndexMin = 7 + let SimpleIndex (t: ILTableName) = assert (t.Index <= 112); SimpleIndexMin + t.Index + let [] SimpleIndexMax = 119 + + let [] TypeDefOrRefOrSpecMin = 120 + let TypeDefOrRefOrSpec (t: TypeDefOrRefOrSpecTag) = assert (t.Tag <= 2); TypeDefOrRefOrSpecMin + t.Tag (* + 111 + 1 = 0x70 + 1 = max ILTableName.Tndex + 1 *) + let [] TypeDefOrRefOrSpecMax = 122 + + let [] TypeOrMethodDefMin = 123 + let TypeOrMethodDef (t: TypeOrMethodDefTag) = assert (t.Tag <= 1); TypeOrMethodDefMin + t.Tag (* + 2 + 1 = max TypeDefOrRefOrSpec.Tag + 1 *) + let [] TypeOrMethodDefMax = 124 + + let [] HasConstantMin = 125 + let HasConstant (t: HasConstantTag) = assert (t.Tag <= 2); HasConstantMin + t.Tag (* + 1 + 1 = max TypeOrMethodDef.Tag + 1 *) + let [] HasConstantMax = 127 + + let [] HasCustomAttributeMin = 128 + let HasCustomAttribute (t: HasCustomAttributeTag) = assert (t.Tag <= 21); HasCustomAttributeMin + t.Tag (* + 2 + 1 = max HasConstant.Tag + 1 *) + let [] HasCustomAttributeMax = 149 + + let [] HasFieldMarshalMin = 150 + let HasFieldMarshal (t: HasFieldMarshalTag) = assert (t.Tag <= 1); HasFieldMarshalMin + t.Tag (* + 21 + 1 = max HasCustomAttribute.Tag + 1 *) + let [] HasFieldMarshalMax = 151 + + let [] HasDeclSecurityMin = 152 + let HasDeclSecurity (t: HasDeclSecurityTag) = assert (t.Tag <= 2); HasDeclSecurityMin + t.Tag (* + 1 + 1 = max HasFieldMarshal.Tag + 1 *) + let [] HasDeclSecurityMax = 154 + + let [] MemberRefParentMin = 155 + let MemberRefParent (t: MemberRefParentTag) = assert (t.Tag <= 4); MemberRefParentMin + t.Tag (* + 2 + 1 = max HasDeclSecurity.Tag + 1 *) + let [] MemberRefParentMax = 159 + + let [] HasSemanticsMin = 160 + let HasSemantics (t: HasSemanticsTag) = assert (t.Tag <= 1); HasSemanticsMin + t.Tag (* + 4 + 1 = max MemberRefParent.Tag + 1 *) + let [] HasSemanticsMax = 161 + + let [] MethodDefOrRefMin = 162 + let MethodDefOrRef (t: MethodDefOrRefTag) = assert (t.Tag <= 2); MethodDefOrRefMin + t.Tag (* + 1 + 1 = max HasSemantics.Tag + 1 *) + let [] MethodDefOrRefMax = 164 + + let [] MemberForwardedMin = 165 + let MemberForwarded (t: MemberForwardedTag) = assert (t.Tag <= 1); MemberForwardedMin + t.Tag (* + 2 + 1 = max MethodDefOrRef.Tag + 1 *) + let [] MemberForwardedMax = 166 + + let [] ImplementationMin = 167 + let Implementation (t: ImplementationTag) = assert (t.Tag <= 2); ImplementationMin + t.Tag (* + 1 + 1 = max MemberForwarded.Tag + 1 *) + let [] ImplementationMax = 169 + + let [] CustomAttributeTypeMin = 170 + let CustomAttributeType (t: CustomAttributeTypeTag) = assert (t.Tag <= 3); CustomAttributeTypeMin + t.Tag (* + 2 + 1 = max Implementation.Tag + 1 *) + let [] CustomAttributeTypeMax = 173 + + let [] ResolutionScopeMin = 174 + let ResolutionScope (t: ResolutionScopeTag) = assert (t.Tag <= 4); ResolutionScopeMin + t.Tag (* + 3 + 1 = max CustomAttributeType.Tag + 1 *) + let [] ResolutionScopeMax = 178 + + [] + type RowElement(tag:int32, idx: int32) = + + member _.Tag = tag + member _.Val = idx + + // These create RowElements + let UShort (x:uint16) = RowElement(RowElementTags.UShort, int32 x) + let ULong (x:int32) = RowElement(RowElementTags.ULong, x) + /// Index into cenv.data or cenv.resources. Gets fixed up later once we known an overall + /// location for the data section. flag indicates if offset is relative to cenv.resources. + let Data (x:int, k:bool) = RowElement((if k then RowElementTags.DataResources else RowElementTags.Data ), x) + /// pos. in guid array + let Guid (x:int) = RowElement(RowElementTags.Guid, x) + /// pos. in blob array + let Blob (x:int) = RowElement(RowElementTags.Blob, x) + /// pos. in string array + let StringE (x:int) = RowElement(RowElementTags.String, x) + /// pos. in some table + let SimpleIndex (t, x:int) = RowElement(RowElementTags.SimpleIndex t, x) + let TypeDefOrRefOrSpec (t, x:int) = RowElement(RowElementTags.TypeDefOrRefOrSpec t, x) + let TypeOrMethodDef (t, x:int) = RowElement(RowElementTags.TypeOrMethodDef t, x) + let HasConstant (t, x:int) = RowElement(RowElementTags.HasConstant t, x) + let HasCustomAttribute (t, x:int) = RowElement(RowElementTags.HasCustomAttribute t, x) + let HasFieldMarshal (t, x:int) = RowElement(RowElementTags.HasFieldMarshal t, x) + let HasDeclSecurity (t, x:int) = RowElement(RowElementTags.HasDeclSecurity t, x) + let MemberRefParent (t, x:int) = RowElement(RowElementTags.MemberRefParent t, x) + let HasSemantics (t, x:int) = RowElement(RowElementTags.HasSemantics t, x) + let MethodDefOrRef (t, x:int) = RowElement(RowElementTags.MethodDefOrRef t, x) + let MemberForwarded (t, x:int) = RowElement(RowElementTags.MemberForwarded t, x) + let Implementation (t, x:int) = RowElement(RowElementTags.Implementation t, x) + let CustomAttributeType (t, x:int) = RowElement(RowElementTags.CustomAttributeType t, x) + let ResolutionScope (t, x:int) = RowElement(RowElementTags.ResolutionScope t, x) + + type BlobIndex = int + type StringIndex = int + + let BlobIndex (x:BlobIndex): int = x + let StringIndex (x:StringIndex): int = x + + let inline combineHash x2 acc = 37 * acc + x2 // (acc <<< 6 + acc >>> 2 + x2 + 0x9e3779b9) + + let hashRow (elems:RowElement[]) = + let mutable acc = 0 + for i in 0 .. elems.Length - 1 do + acc <- (acc <<< 1) + elems.[i].Tag + elems.[i].Val + 631 + acc + + let equalRows (elems:RowElement[]) (elems2:RowElement[]) = + if elems.Length <> elems2.Length then false else + let mutable ok = true + let n = elems.Length + let mutable i = 0 + while ok && i < n do + if elems.[i].Tag <> elems2.[i].Tag || elems.[i].Val <> elems2.[i].Val then ok <- false + i <- i + 1 + ok + + + type GenericRow = RowElement[] + + /// This is the representation of shared rows is used for most shared row types. + /// Rows ILAssemblyRef and ILMethodRef are very common and are given their own + /// representations. + [] + type SharedRow(elems: RowElement[], hashCode: int) = + member _.GenericRow = elems + override _.GetHashCode() = hashCode + override _.Equals(obj:obj) = + match obj with + | :? SharedRow as y -> equalRows elems y.GenericRow + | _ -> false + + let SharedRow(elems: RowElement[]) = new SharedRow(elems, hashRow elems) + + /// Special representation: Note, only hashing by name + let AssemblyRefRow(s1, s2, s3, s4, l1, b1, nameIdx, str2, b2) = + let hashCode = hash nameIdx + let genericRow = [| UShort s1; UShort s2; UShort s3; UShort s4; ULong l1; Blob b1; StringE nameIdx; StringE str2; Blob b2 |] + new SharedRow(genericRow, hashCode) + + /// Special representation the computes the hash more efficiently + let MemberRefRow(mrp:RowElement, nmIdx:StringIndex, blobIdx:BlobIndex) = + let hashCode = combineHash (hash blobIdx) (combineHash (hash nmIdx) (hash mrp)) + let genericRow = [| mrp; StringE nmIdx; Blob blobIdx |] + new SharedRow(genericRow, hashCode) + + /// Unshared rows are used for definitional tables where elements do not need to be made unique + /// e.g. ILMethodDef and ILTypeDef. Most tables are like this. We don't precompute a + /// hash code for these rows, and indeed the GetHashCode and Equals should not be needed. + [] + type UnsharedRow(elems: RowElement[]) = + member _.GenericRow = elems + override _.GetHashCode() = hashRow elems + override _.Equals(obj:obj) = + match obj with + | :? UnsharedRow as y -> equalRows elems y.GenericRow + | _ -> false + + + //===================================================================== + //===================================================================== + // IL --> TABLES+CODE + //===================================================================== + //===================================================================== + + // This environment keeps track of how many generic parameters are in scope. + // This lets us translate AbsIL type variable number to IL type variable numbering + type ILTypeWriterEnv = { EnclosingTyparCount: int } + let envForTypeDef (td:ILTypeDef) = { EnclosingTyparCount=td.GenericParams.Length } + let envForMethodRef env (typ:ILType) = { EnclosingTyparCount=(match typ with ILType.Array _ -> env.EnclosingTyparCount | _ -> typ.GenericArgs.Length) } + let envForNonGenericMethodRef _mref = { EnclosingTyparCount=System.Int32.MaxValue } + let envForFieldSpec (fspec:ILFieldSpec) = { EnclosingTyparCount=fspec.EnclosingType.GenericArgs.Length } + let envForOverrideSpec (ospec:ILOverridesSpec) = { EnclosingTyparCount=ospec.EnclosingType.GenericArgs.Length } + + //--------------------------------------------------------------------- + // TABLES + //--------------------------------------------------------------------- + + [] + type MetadataTable<'T> = + { name: string + dict: Dictionary<'T, int> // given a row, find its entry number + mutable rows: ResizeArray<'T> } + member x.Count = x.rows.Count + + static member New(nm, hashEq) = + { name=nm + dict = new Dictionary<_, _>(100, hashEq) + rows= new ResizeArray<_>() } + + member tbl.EntriesAsArray = + tbl.rows.ToArray() + + member tbl.Entries = + tbl.rows.ToArray() |> Array.toList + + member tbl.AddSharedEntry x = + let n = tbl.rows.Count + 1 + tbl.dict.[x] <- n + tbl.rows.Add(x) + n + + member tbl.AddUnsharedEntry x = + let n = tbl.rows.Count + 1 + tbl.rows.Add(x) + n + + member tbl.FindOrAddSharedEntry x = + let mutable res = Unchecked.defaultof<_> + let ok = tbl.dict.TryGetValue(x, &res) + if ok then res + else tbl.AddSharedEntry x + + + /// This is only used in one special place - see further below. + member tbl.SetRowsOfTable (t: _[]) = + tbl.rows <- ResizeArray(t) + let h = tbl.dict + h.Clear() + t |> Array.iteri (fun i x -> h.[x] <- (i+1)) + + member tbl.AddUniqueEntry nm geterr x = + if tbl.dict.ContainsKey x then failwith ("duplicate entry '"+geterr x+"' in "+nm+" table") + else tbl.AddSharedEntry x + + member tbl.GetTableEntry x = tbl.dict.[x] + member tbl.GetTableKeys() = tbl.dict.Keys |> Seq.toArray + + //--------------------------------------------------------------------- + // Keys into some of the tables + //--------------------------------------------------------------------- + + /// We use this key type to help find ILMethodDefs for MethodRefs + type MethodDefKey(tidx:int, garity:int, nm:string, rty:ILType, argtys:ILTypes, isStatic:bool) = + // Precompute the hash. The hash doesn't include the return type or + // argument types (only argument type count). This is very important, since + // hashing these is way too expensive + let hashCode = + hash tidx + |> combineHash (hash garity) + |> combineHash (hash nm) + |> combineHash (hash argtys.Length) + |> combineHash (hash isStatic) + member _.TypeIdx = tidx + member _.GenericArity = garity + member _.Name = nm + member _.ReturnType = rty + member _.ArgTypes = argtys + member _.IsStatic = isStatic + override _.ToString() = sprintf "%A" (tidx, garity, nm, rty, argtys, isStatic) + override _.GetHashCode() = hashCode + override _.Equals(obj:obj) = + match obj with + | :? MethodDefKey as y -> + tidx = y.TypeIdx && + garity = y.GenericArity && + nm = y.Name && + // note: these next two use structural equality on AbstractIL ILType values + rty = y.ReturnType && + argtys = y.ArgTypes && + isStatic = y.IsStatic + | _ -> false + + /// We use this key type to help find ILFieldDefs for FieldRefs + type FieldDefKey(tidx:int, nm:string, ty:ILType) = + // precompute the hash. hash doesn't include the type + let hashCode = hash tidx |> combineHash (hash nm) + member _.TypeIdx = tidx + member _.Name = nm + member _.Type = ty + override _.GetHashCode() = hashCode + override _.Equals(obj:obj) = + match obj with + | :? FieldDefKey as y -> + tidx = y.TypeIdx && + nm = y.Name && + ty = y.Type + | _ -> false + + type PropertyTableKey = PropKey of int (* type. def. idx. *) * string * ILType * ILTypes + type EventTableKey = EventKey of int (* type. def. idx. *) * string + type TypeDefTableKey = TdKey of string list * string uoption * string + + //--------------------------------------------------------------------- + // The Writer Target + //--------------------------------------------------------------------- + + [] + type MetadataTable = + | Shared of MetadataTable + | Unshared of MetadataTable + member t.FindOrAddSharedEntry(x) = match t with Shared u -> u.FindOrAddSharedEntry(x) | Unshared u -> failwithf "FindOrAddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddSharedEntry(x) = match t with | Shared u -> u.AddSharedEntry(x) | Unshared u -> failwithf "AddSharedEntry: incorrect table kind, u.name = %s" u.name + member t.AddUnsharedEntry(x) = match t with Unshared u -> u.AddUnsharedEntry(x) | Shared u -> failwithf "AddUnsharedEntry: incorrect table kind, u.name = %s" u.name + member t.GenericRowsOfTable = match t with Unshared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) | Shared u -> u.EntriesAsArray |> Array.map (fun x -> x.GenericRow) + member t.SetRowsOfSharedTable rows = match t with Shared u -> u.SetRowsOfTable (Array.map SharedRow rows) | Unshared u -> failwithf "SetRowsOfSharedTable: incorrect table kind, u.name = %s" u.name + member t.Count = match t with Unshared u -> u.Count | Shared u -> u.Count + + + [] + type cenv = + { ilg: ILGlobals + emitTailcalls: bool + deterministic: bool + showTimes: bool + desiredMetadataVersion: Version + requiredDataFixups: ResizeArray<(int32 * (int * bool))> + /// References to strings in codestreams: offset of code and a (fixup-location , string token) list) + mutable requiredStringFixups: ResizeArray<(int32 * (int * int)[])> + codeChunks: ByteBuffer + mutable nextCodeAddr: int32 + + // Collected debug information + mutable moduleGuid: byte[] + generatePdb: bool + /// Raw data, to go into the data section + data: ByteBuffer + /// Raw resource data, to go into the data section + resources: ByteBuffer + mutable entrypoint: (bool * int) option + + /// Caches + trefCache: Dictionary + + /// The following are all used to generate unique items in the output + tables: MetadataTable[] + AssemblyRefs: MetadataTable + fieldDefs: MetadataTable + methodDefIdxsByKey: MetadataTable + methodDefIdxs: Dictionary + propertyDefs: MetadataTable + eventDefs: MetadataTable + typeDefs: MetadataTable + guids: MetadataTable + blobs: MetadataTable + strings: MetadataTable + userStrings: MetadataTable + } + member cenv.GetTable (tab:ILTableName) = cenv.tables.[tab.Index] + + + member cenv.AddCode ((reqdStringFixupsOffset, requiredStringFixups), code) = + cenv.requiredStringFixups.Add ((cenv.nextCodeAddr + reqdStringFixupsOffset, requiredStringFixups)) + cenv.codeChunks.EmitBytes code + cenv.nextCodeAddr <- cenv.nextCodeAddr + code.Length + + member cenv.GetCode() = cenv.codeChunks.Close() + + + let FindOrAddSharedRow (cenv:cenv) tbl x = cenv.GetTable(tbl).FindOrAddSharedEntry x + + // Shared rows must be hash-cons'd to be made unique (no duplicates according to contents) + let AddSharedRow (cenv:cenv) tbl x = cenv.GetTable(tbl).AddSharedEntry x + + // Unshared rows correspond to definition elements (e.g. a ILTypeDef or a ILMethodDef) + let AddUnsharedRow (cenv:cenv) tbl (x:UnsharedRow) = cenv.GetTable(tbl).AddUnsharedEntry x + + let metadataSchemaVersionSupportedByCLRVersion v = 2, 0 + + let headerVersionSupportedByCLRVersion v = + // The COM20HEADER version number + // Whidbey version numbers are 2.5 + // Earlier are 2.0 + // From an email from jeffschw: "Be built with a compiler that marks the COM20HEADER with Major >=2 and Minor >= 5. The V2.0 compilers produce images with 2.5, V1.x produces images with 2.0." + 2, 5 + + let peOptionalHeaderByteByCLRVersion v = + // A flag in the PE file optional header seems to depend on CLI version + // Whidbey version numbers are 8 + // Earlier are 6 + // Tools are meant to ignore this, but the VS Profiler wants it to have the right value + 8 + + // returned by writeBinaryAndReportMappings + [] + type ILTokenMappings = + { TypeDefTokenMap: ILTypeDef list * ILTypeDef -> int32 + FieldDefTokenMap: ILTypeDef list * ILTypeDef -> ILFieldDef -> int32 + MethodDefTokenMap: ILTypeDef list * ILTypeDef -> ILMethodDef -> int32 + PropertyTokenMap: ILTypeDef list * ILTypeDef -> ILPropertyDef -> int32 + EventTokenMap: ILTypeDef list * ILTypeDef -> ILEventDef -> int32 } + + let recordRequiredDataFixup (requiredDataFixups: ResizeArray<_>) (buf: ByteBuffer) pos lab = + requiredDataFixups.Add((pos, lab)) + // Write a special value in that we check later when applying the fixup + buf.EmitInt32 0xdeaddddd + + //--------------------------------------------------------------------- + // The UserString, BlobHeap, GuidHeap tables + //--------------------------------------------------------------------- + + let GetUserStringHeapIdx cenv s = + cenv.userStrings.FindOrAddSharedEntry s + + let GetBytesAsBlobIdx cenv (bytes:byte[]) = + if bytes.Length = 0 then 0 + else cenv.blobs.FindOrAddSharedEntry bytes + + let GetStringHeapIdx cenv s = + if s = "" then 0 + else cenv.strings.FindOrAddSharedEntry s + + let GetGuidIdx cenv info = cenv.guids.FindOrAddSharedEntry info + + let GetStringHeapIdxOption cenv sopt = + match sopt with + | USome ns -> GetStringHeapIdx cenv ns + | UNone -> 0 + + + let splitNameAt (nm:string) idx = + if idx < 0 then failwith "splitNameAt: idx < 0"; + let last = nm.Length - 1 + if idx > last then failwith "splitNameAt: idx > last"; + (nm.Substring(0,idx)), + (if idx < last then nm.Substring (idx+1,last - idx) else "") + + + module String = + let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index for the character was not found in the string")) + + let index (s:string) (c:char) = + let r = s.IndexOf(c) + if r = -1 then indexNotFound() else r + + let rindex (s:string) (c:char) = + let r = s.LastIndexOf(c) + if r = -1 then indexNotFound() else r + + let contains (s:string) (c:char) = + s.IndexOf(c,0,String.length s) <> -1 + + let splitTypeNameRightAux nm = + if String.contains nm '.' then + let idx = String.rindex nm '.' + let s1,s2 = splitNameAt nm idx + Some s1,s2 + else None, nm + + let splitTypeNameRight nm = + splitTypeNameRightAux nm + + let GetTypeNameAsElemPair cenv (n1,n2) = + StringE (GetStringHeapIdxOption cenv n1), + StringE (GetStringHeapIdx cenv n2) + + //===================================================================== + // Pass 1 - allocate indexes for types + //===================================================================== + + let addILTypeName enc (td: ILTypeDef) = enc@[(if td.IsNested then td.Name else joinILTypeName td.Namespace td.Name)] + + let rec GenTypeDefPass1 enc cenv (td:ILTypeDef) = + ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, _, n)) -> n) (TdKey (enc, td.Namespace, td.Name))) + GenTypeDefsPass1 (addILTypeName enc td) cenv td.NestedTypes.Entries + + and GenTypeDefsPass1 enc cenv tds = Array.iter (GenTypeDefPass1 enc cenv) tds + + //===================================================================== + // Pass 2 - allocate indexes for methods and fields and write rows for types + //===================================================================== + + let rec GetIdxForTypeDef cenv key = + try cenv.typeDefs.GetTableEntry key + with + :? KeyNotFoundException -> + let (TdKey (enc, nsp, n) ) = key + failwithf "One of your modules expects the type '%s' to be defined within the module being emitted. keys = %A" (String.concat "." (enc@[joinILTypeName nsp n])) (cenv.typeDefs.GetTableKeys()) + 0 + + // -------------------------------------------------------------------- + // Assembly and module references + // -------------------------------------------------------------------- + + let rec GetAssemblyRefAsRow cenv (aref:ILAssemblyRef) = + AssemblyRefRow + ((match aref.Version with UNone -> 0us | USome v -> uint16 v.Major), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Minor), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Build), + (match aref.Version with UNone -> 0us | USome v -> uint16 v.Revision), + ((match aref.PublicKey with USome (PublicKey _) -> 0x0001 | _ -> 0x0000) + ||| (if aref.Retargetable then 0x0100 else 0x0000)), + BlobIndex (match aref.PublicKey with + | UNone -> 0 + | USome (PublicKey b | PublicKeyToken b) -> GetBytesAsBlobIdx cenv b), + StringIndex (GetStringHeapIdx cenv aref.Name), + StringIndex (match aref.Locale with UNone -> 0 | USome s -> GetStringHeapIdx cenv s), + BlobIndex (match aref.Hash with UNone -> 0 | USome s -> GetBytesAsBlobIdx cenv s)) + + and GetAssemblyRefAsIdx cenv aref = + FindOrAddSharedRow cenv ILTableNames.AssemblyRef (GetAssemblyRefAsRow cenv aref) + + and GetModuleRefAsRow cenv (mref:ILModuleRef) = + SharedRow + [| StringE (GetStringHeapIdx cenv mref.Name) |] + + and GetModuleRefAsFileRow cenv (mref:ILModuleRef) = + SharedRow + [| ULong (if mref.HasMetadata then 0x0000 else 0x0001) + StringE (GetStringHeapIdx cenv mref.Name) + (match mref.Hash with UNone -> Blob 0 | USome s -> Blob (GetBytesAsBlobIdx cenv s)) |] + + and GetModuleRefAsIdx cenv mref = + FindOrAddSharedRow cenv ILTableNames.ModuleRef (GetModuleRefAsRow cenv mref) + + and GetModuleRefAsFileIdx cenv mref = + FindOrAddSharedRow cenv ILTableNames.File (GetModuleRefAsFileRow cenv mref) + + // -------------------------------------------------------------------- + // Does a ILScopeRef point to this module? + // -------------------------------------------------------------------- + + let isScopeRefLocal scoref = (scoref = ILScopeRef.Local) + let rec isTypeRefLocal (tref:ILTypeRef) = + isILTypeScopeRefLocal tref.Scope + and isILTypeScopeRefLocal (scoref:ILTypeRefScope) = + match scoref with + | ILTypeRefScope.Top t -> isScopeRefLocal t + | ILTypeRefScope.Nested tref -> isTypeRefLocal tref + let rec enclosing (scoref:ILTypeRefScope) = + match scoref with + | ILTypeRefScope.Top _ -> [] + | ILTypeRefScope.Nested tref -> enclosing tref.Scope @ [joinILTypeName tref.Namespace tref.Name] + + let isTypeLocal (typ:ILType) = typ.IsNominal && isEmpty typ.GenericArgs && isTypeRefLocal typ.TypeRef + + // -------------------------------------------------------------------- + // Scopes to Implementation elements. + // -------------------------------------------------------------------- + + let GetScopeRefAsImplementationElem cenv scoref = + match scoref with + | ILScopeRef.Local -> (ImplementationTag.AssemblyRef, 0) + | ILScopeRef.Assembly aref -> (ImplementationTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (ImplementationTag.File, GetModuleRefAsFileIdx cenv mref) + + // -------------------------------------------------------------------- + // Type references, types etc. + // -------------------------------------------------------------------- + + let rec GetTypeRefAsTypeRefRow cenv (tref:ILTypeRef) = + let nselem, nelem = GetTypeNameAsElemPair cenv (tref.Namespace, tref.Name) + let rs1, rs2 = GetResolutionScopeAsElem cenv tref.Scope + SharedRow [| ResolutionScope (rs1, rs2); nelem; nselem |] + + and GetTypeRefAsTypeRefIdx cenv tref = + let mutable res = 0 + if cenv.trefCache.TryGetValue(tref, &res) then res else + let res = FindOrAddSharedRow cenv ILTableNames.TypeRef (GetTypeRefAsTypeRefRow cenv tref) + cenv.trefCache.[tref] <- res + res + + and GetTypeDescAsTypeRefIdx cenv (enc, nsp, n) = + GetTypeRefAsTypeRefIdx cenv (ILTypeRef (enc, nsp, n)) + + and GetResolutionScopeAsElem cenv scoref = + match scoref with + | ILTypeRefScope.Top s -> + match s with + | ILScopeRef.Local -> (ResolutionScopeTag.Module, 1) + | ILScopeRef.Assembly aref -> (ResolutionScopeTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + | ILScopeRef.Module mref -> (ResolutionScopeTag.ModuleRef, GetModuleRefAsIdx cenv mref) + + | ILTypeRefScope.Nested tref -> + (ResolutionScopeTag.TypeRef, GetTypeRefAsTypeRefIdx cenv tref) + + + let emitTypeInfoAsTypeDefOrRefEncoded cenv (bb: ByteBuffer) (scoref, nsp, nm) = + if isILTypeScopeRefLocal scoref then + let idx = GetIdxForTypeDef cenv (TdKey(enclosing scoref, nsp, nm)) + bb.EmitZ32 (idx <<< 2) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeDef + else + let idx = GetTypeDescAsTypeRefIdx cenv (scoref, nsp, nm) + bb.EmitZ32 ((idx <<< 2) ||| 0x01) // ECMA 22.2.8 TypeDefOrRefEncoded - ILTypeRef + + let getTypeDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = TypeDefOrRefOrSpecTag.TypeDef then ILTableNames.TypeDef + elif tag = TypeDefOrRefOrSpecTag.TypeRef then ILTableNames.TypeRef + elif tag = TypeDefOrRefOrSpecTag.TypeSpec then ILTableNames.TypeSpec + else failwith "getTypeDefOrRefAsUncodedToken" + getUncodedToken tab idx + + // REVIEW: write into an accumuating buffer + let EmitArrayShape (bb: ByteBuffer) (ILArrayShape shape) = + let sized = Array.filter (function (_, Some _) -> true | _ -> false) shape + let lobounded = Array.filter (function (Some _, _) -> true | _ -> false) shape + bb.EmitZ32 shape.Length + bb.EmitZ32 sized.Length + sized |> Array.iter (function (_, Some sz) -> bb.EmitZ32 sz | _ -> failwith "?") + bb.EmitZ32 lobounded.Length + lobounded |> Array.iter (function (Some low, _) -> bb.EmitZ32 low | _ -> failwith "?") + + let hasthisToByte hasthis = + match hasthis with + | ILThisConvention.Instance -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE + | ILThisConvention.InstanceExplicit -> e_IMAGE_CEE_CS_CALLCONV_INSTANCE_EXPLICIT + | ILThisConvention.Static -> 0x00uy + + let callconvToByte ntypars (Callconv (hasthis, bcc)) = + hasthisToByte hasthis ||| + (if ntypars > 0 then e_IMAGE_CEE_CS_CALLCONV_GENERIC else 0x00uy) ||| + (match bcc with + | ILArgConvention.FastCall -> e_IMAGE_CEE_CS_CALLCONV_FASTCALL + | ILArgConvention.StdCall -> e_IMAGE_CEE_CS_CALLCONV_STDCALL + | ILArgConvention.ThisCall -> e_IMAGE_CEE_CS_CALLCONV_THISCALL + | ILArgConvention.CDecl -> e_IMAGE_CEE_CS_CALLCONV_CDECL + | ILArgConvention.Default -> 0x00uy + | ILArgConvention.VarArg -> e_IMAGE_CEE_CS_CALLCONV_VARARG) + + + // REVIEW: write into an accumuating buffer + let rec EmitTypeSpec cenv env (bb: ByteBuffer) (et, tspec:ILTypeSpec) = + if isEmpty tspec.GenericArgs then + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Namespace, tspec.Name) + else + bb.EmitByte et_WITH + bb.EmitByte et + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tspec.Scope, tspec.Namespace, tspec.Name) + bb.EmitZ32 tspec.GenericArgs.Length + EmitTypes cenv env bb tspec.GenericArgs + + and GetTypeAsTypeDefOrRef cenv env (ty:ILType) = + if isTypeLocal ty then + let tref = ty.TypeRef + (TypeDefOrRefOrSpecTag.TypeDef, GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name))) + elif ty.IsNominal && isEmpty ty.GenericArgs then + (TypeDefOrRefOrSpecTag.TypeRef, GetTypeRefAsTypeRefIdx cenv ty.TypeRef) + else + (TypeDefOrRefOrSpecTag.TypeSpec, GetTypeAsTypeSpecIdx cenv env ty) + + and GetTypeAsBytes cenv env ty = emitBytesViaBuffer (fun bb -> EmitType cenv env bb ty) + + and GetTypeOfLocalAsBytes cenv env (l: ILLocal) = + emitBytesViaBuffer (fun bb -> EmitLocalInfo cenv env bb l) + + and GetTypeAsBlobIdx cenv env (ty:ILType) = + GetBytesAsBlobIdx cenv (GetTypeAsBytes cenv env ty) + + and GetTypeAsTypeSpecRow cenv env (ty:ILType) = + SharedRow [| Blob (GetTypeAsBlobIdx cenv env ty) |] + + and GetTypeAsTypeSpecIdx cenv env ty = + FindOrAddSharedRow cenv ILTableNames.TypeSpec (GetTypeAsTypeSpecRow cenv env ty) + + + and EmitType cenv env bb ty = + match ty with + | ElementType et -> bb.EmitByte et + | ILType.Boxed tspec -> EmitTypeSpec cenv env bb (et_CLASS, tspec) + | ILType.Value tspec -> EmitTypeSpec cenv env bb (et_VALUETYPE, tspec) + | ILType.Array (shape, ty) -> + if shape = ILArrayShape.SingleDimensional then (bb.EmitByte et_SZARRAY ; EmitType cenv env bb ty) + else (bb.EmitByte et_ARRAY; EmitType cenv env bb ty; EmitArrayShape bb shape) + | ILType.Var tv -> + let cgparams = env.EnclosingTyparCount + if int32 tv < cgparams then + bb.EmitByte et_VAR + bb.EmitZ32 (int32 tv) else - RebuildShapeCombinationUnchecked(shape, exprs1) - fun e -> f fallback e - - let RightPipe = <@@ (|>) @@> - let inlineRightPipe expr = - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | SpecificCall RightPipe (None, _, [operand; applicable]) -> - let fixedOperand = loop operand - match loop applicable with - | Lambda(arg, body) -> - let v = Quotations.Var("__temp", operand.Type) - let ev = Expr.Var v + bb.EmitByte et_MVAR + bb.EmitZ32 (int32 tv - cgparams) + + | ILType.Byref typ -> + bb.EmitByte et_BYREF + EmitType cenv env bb typ + | ILType.Ptr typ -> + bb.EmitByte et_PTR + EmitType cenv env bb typ + | ILType.Void -> + bb.EmitByte et_VOID + | ILType.FunctionPointer x -> + bb.EmitByte et_FNPTR + EmitCallsig cenv env bb (x.CallingConv, x.ArgTypes, x.ReturnType, None, 0) + | ILType.Modified (req, tref, ty) -> + bb.EmitByte (if req then et_CMOD_REQD else et_CMOD_OPT) + emitTypeInfoAsTypeDefOrRefEncoded cenv bb (tref.Scope, tref.Namespace, tref.Name) + EmitType cenv env bb ty + | _ -> failwith "EmitType" + + and EmitLocalInfo cenv env (bb:ByteBuffer) (l:ILLocal) = + if l.IsPinned then + bb.EmitByte et_PINNED + EmitType cenv env bb l.Type + + and EmitCallsig cenv env (bb:ByteBuffer) (callconv, args:ILTypes, ret, varargs:ILVarArgs, genarity) = + bb.EmitByte (callconvToByte genarity callconv) + if genarity > 0 then bb.EmitZ32 genarity + bb.EmitZ32 ((args.Length + (match varargs with None -> 0 | Some l -> l.Length))) + EmitType cenv env bb ret + args |> Array.iter (EmitType cenv env bb) + match varargs with + | None -> ()// no extra arg = no sentinel + | Some tys -> + if isEmpty tys then () // no extra arg = no sentinel + else + bb.EmitByte et_SENTINEL + Array.iter (EmitType cenv env bb) tys + + and GetCallsigAsBytes cenv env x = emitBytesViaBuffer (fun bb -> EmitCallsig cenv env bb x) + + and EmitTypes cenv env bb (inst: ILTypes) = + inst |> Array.iter (EmitType cenv env bb) + + let GetTypeAsMemberRefParent cenv env ty = + match GetTypeAsTypeDefOrRef cenv env ty with + | (tag, _) when tag = TypeDefOrRefOrSpecTag.TypeDef -> printfn "GetTypeAsMemberRefParent: mspec should have been encoded as mdtMethodDef?"; MemberRefParent (MemberRefParentTag.TypeRef, 1) + | (tag, tok) when tag = TypeDefOrRefOrSpecTag.TypeRef -> MemberRefParent (MemberRefParentTag.TypeRef, tok) + | (tag, tok) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> MemberRefParent (MemberRefParentTag.TypeSpec, tok) + | _ -> failwith "GetTypeAsMemberRefParent" + + + + + // -------------------------------------------------------------------- + // Native types + // -------------------------------------------------------------------- + + let rec GetFieldInitAsBlobIdx cenv (x:ILFieldInit) = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> GetFieldInit bb x)) + + // REVIEW: write into an accumuating buffer + and GetFieldInit (bb: ByteBuffer) x = + match x with + | :? string as b -> bb.EmitBytes (Encoding.Unicode.GetBytes b) + | :? bool as b -> bb.EmitByte (if b then 0x01uy else 0x00uy) + | :? char as x -> bb.EmitUInt16 (uint16 x) + | :? int8 as x -> bb.EmitByte (byte x) + | :? int16 as x -> bb.EmitUInt16 (uint16 x) + | :? int32 as x -> bb.EmitInt32 x + | :? int64 as x -> bb.EmitInt64 x + | :? uint8 as x -> bb.EmitByte x + | :? uint16 as x -> bb.EmitUInt16 x + | :? uint32 as x -> bb.EmitInt32 (int32 x) + | :? uint64 as x -> bb.EmitInt64 (int64 x) + | :? single as x -> bb.EmitInt32 (bitsOfSingle x) + | :? double as x -> bb.EmitInt64 (bitsOfDouble x) + | _ -> bb.EmitInt32 0 + + and GetFieldInitFlags (i: ILFieldInit) = + UShort + (uint16 + (match i with + | :? string -> et_STRING + | :? bool -> et_BOOLEAN + | :? char -> et_CHAR + | :? int8 -> et_I1 + | :? int16 -> et_I2 + | :? int32 -> et_I4 + | :? int64 -> et_I8 + | :? uint8 -> et_U1 + | :? uint16 -> et_U2 + | :? uint32 -> et_U4 + | :? uint64 -> et_U8 + | :? single -> et_R4 + | :? double -> et_R8 + | _ -> et_CLASS)) + + // -------------------------------------------------------------------- + // Type definitions + // -------------------------------------------------------------------- + + let GetMemberAccessFlags access = + match access with + | ILMemberAccess.CompilerControlled -> 0x00000000 + | ILMemberAccess.Public -> 0x00000006 + | ILMemberAccess.Private -> 0x00000001 + | ILMemberAccess.Family -> 0x00000004 + | ILMemberAccess.FamilyAndAssembly -> 0x00000002 + | ILMemberAccess.FamilyOrAssembly -> 0x00000005 + | ILMemberAccess.Assembly -> 0x00000003 + + let GetTypeAccessFlags access = + match access with + | ILTypeDefAccess.Public -> 0x00000001 + | ILTypeDefAccess.Private -> 0x00000000 + | ILTypeDefAccess.Nested ILMemberAccess.Public -> 0x00000002 + | ILTypeDefAccess.Nested ILMemberAccess.Private -> 0x00000003 + | ILTypeDefAccess.Nested ILMemberAccess.Family -> 0x00000004 + | ILTypeDefAccess.Nested ILMemberAccess.FamilyAndAssembly -> 0x00000006 + | ILTypeDefAccess.Nested ILMemberAccess.FamilyOrAssembly -> 0x00000007 + | ILTypeDefAccess.Nested ILMemberAccess.Assembly -> 0x00000005 + | ILTypeDefAccess.Nested ILMemberAccess.CompilerControlled -> failwith "bad type acccess" + + let rec GetTypeDefAsRow cenv env _enc (td:ILTypeDef) = + let nselem, nelem = GetTypeNameAsElemPair cenv (td.Namespace, td.Name) + let flags = + if td.Name = "" then 0x00000000 + else + + int td.Attributes ||| + begin + match td.Layout with + | ILTypeDefLayout.Auto -> 0x00000000 + | ILTypeDefLayout.Sequential _ -> 0x00000008 + | ILTypeDefLayout.Explicit _ -> 0x00000010 + end ||| + begin + match td.Kind with + | ILTypeDefKind.Interface -> 0x00000020 + | _ -> 0x00000000 + end ||| +#if EMIT_SECURITY_DECLS +// @REVIEW (if rtspecialname_of_tdef td then 0x00000800 else 0x00000000) ||| + (if td.HasSecurity || not td.SecurityDecls.Entries.IsEmpty then 0x00040000 else 0x00000000) +#endif + 0x0 + + let tdorTag, tdorRow = GetTypeOptionAsTypeDefOrRef cenv env td.Extends + UnsharedRow + [| ULong flags + nelem + nselem + TypeDefOrRefOrSpec (tdorTag, tdorRow) + SimpleIndex (ILTableNames.Field, cenv.fieldDefs.Count + 1) + SimpleIndex (ILTableNames.Method, cenv.methodDefIdxsByKey.Count + 1) |] + + and GetTypeOptionAsTypeDefOrRef cenv env tyOpt = + match tyOpt with + | None -> (TypeDefOrRefOrSpecTag.TypeDef, 0) + | Some ty -> (GetTypeAsTypeDefOrRef cenv env ty) + + and GetTypeDefAsPropertyMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.Property, cenv.propertyDefs.Count + 1) |] + + and GetTypeDefAsEventMapRow cenv tidx = + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.Event, cenv.eventDefs.Count + 1) |] + + and GetKeyForFieldDef tidx (fd: ILFieldDef) = + FieldDefKey (tidx, fd.Name, fd.FieldType) + + and GenFieldDefPass2 cenv tidx fd = + ignore (cenv.fieldDefs.AddUniqueEntry "field" (fun (fdkey:FieldDefKey) -> fdkey.Name) (GetKeyForFieldDef tidx fd)) + + and GetKeyForMethodDef tidx (md: ILMethodDef) = + MethodDefKey (tidx, md.GenericParams.Length, md.Name, md.Return.Type, md.ParameterTypes, md.CallingConv.IsStatic) + + and GenMethodDefPass2 cenv tidx md = + let idx = + cenv.methodDefIdxsByKey.AddUniqueEntry + "method" + (fun (key:MethodDefKey) -> + printfn "Duplicate in method table is:" + printfn "%s" (" Type index: "+string key.TypeIdx) + printfn "%s" (" Method name: "+key.Name) + printfn "%s" (" Method arity (num generic params): "+string key.GenericArity) + key.Name + ) + (GetKeyForMethodDef tidx md) + + cenv.methodDefIdxs.[md] <- idx + + and GetKeyForPropertyDef tidx (x: ILPropertyDef) = + PropKey (tidx, x.Name, x.PropertyType, x.IndexParameterTypes) + + and GenPropertyDefPass2 cenv tidx x = + ignore (cenv.propertyDefs.AddUniqueEntry "property" (fun (PropKey (_, n, _, _)) -> n) (GetKeyForPropertyDef tidx x)) + + and GetTypeAsImplementsRow cenv env tidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenImplementsPass2 cenv env tidx ty = + AddUnsharedRow cenv ILTableNames.InterfaceImpl (GetTypeAsImplementsRow cenv env tidx ty) |> ignore + + and GetKeyForEvent tidx (x: ILEventDef) = + EventKey (tidx, x.Name) + + and GenEventDefPass2 cenv tidx x = + ignore (cenv.eventDefs.AddUniqueEntry "event" (fun (EventKey(_, b)) -> b) (GetKeyForEvent tidx x)) + + and GenTypeDefPass2 pidx enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + let tidx2 = AddUnsharedRow cenv ILTableNames.TypeDef (GetTypeDefAsRow cenv env enc td) + if tidx <> tidx2 then failwith "index of typedef on second pass does not match index on first pass" + + // Add entries to auxiliary mapping tables, e.g. Nested, PropertyMap etc. + // Note Nested is organised differently to the others... + if not (isNil enc) then + AddUnsharedRow cenv ILTableNames.Nested + (UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + SimpleIndex (ILTableNames.TypeDef, pidx) |]) |> ignore + let props = td.Properties.Entries + if not (isEmpty props) then + AddUnsharedRow cenv ILTableNames.PropertyMap (GetTypeDefAsPropertyMapRow cenv tidx) |> ignore + let events = td.Events.Entries + if not (isEmpty events) then + AddUnsharedRow cenv ILTableNames.EventMap (GetTypeDefAsEventMapRow cenv tidx) |> ignore + + // Now generate or assign index numbers for tables referenced by the maps. + // Don't yet generate contents of these tables - leave that to pass3, as + // code may need to embed these entries. + td.Implements |> Array.iter (GenImplementsPass2 cenv env tidx) + props |> Array.iter (GenPropertyDefPass2 cenv tidx) + events |> Array.iter (GenEventDefPass2 cenv tidx) + td.Fields.Entries |> Array.iter (GenFieldDefPass2 cenv tidx) + td.Methods.Entries |> Array.iter (GenMethodDefPass2 cenv tidx) + td.NestedTypes.Entries |> GenTypeDefsPass2 tidx (addILTypeName enc td) cenv + with e -> + failwith ("Error in pass2 for type "+td.Name+", error: "+e.Message) + + and GenTypeDefsPass2 pidx enc cenv tds = + Array.iter (GenTypeDefPass2 pidx enc cenv) tds + + //===================================================================== + // Pass 3 - write details of methods, fields, IL code, custom attrs etc. + //===================================================================== + + exception MethodDefNotFound + let FindMethodDefIdx cenv mdkey = + try cenv.methodDefIdxsByKey.GetTableEntry mdkey + with :? KeyNotFoundException -> + let typeNameOfIdx i = + match + (cenv.typeDefs.dict + |> Seq.fold (fun sofar kvp -> + let tkey2 = kvp.Key + let tidx2 = kvp.Value + if i = tidx2 then + if sofar = None then + Some tkey2 + else failwith "multiple type names map to index" + else sofar) None) with + | Some x -> x + | None -> raise MethodDefNotFound + let (TdKey (tenc, tnsp, tname)) = typeNameOfIdx mdkey.TypeIdx + printfn "%s" ("The local method '"+(String.concat "." (tenc@[tname]))+"'::'"+mdkey.Name+"' was referenced but not declared") + printfn "generic arity: %s " (string mdkey.GenericArity) + cenv.methodDefIdxsByKey.dict |> Seq.iter (fun (KeyValue(mdkey2, _)) -> + if mdkey2.TypeIdx = mdkey.TypeIdx && mdkey.Name = mdkey2.Name then + let (TdKey (tenc2, tnsp2, tname2)) = typeNameOfIdx mdkey2.TypeIdx + printfn "%s" ("A method in '"+(String.concat "." (tenc2@[tname2]))+"' had the right name but the wrong signature:") + printfn "%s" ("generic arity: "+string mdkey2.GenericArity) + printfn "mdkey2 = %s" (mdkey2.ToString())) + raise MethodDefNotFound + + + let rec GetMethodDefIdx cenv md = + cenv.methodDefIdxs.[md] + + and FindFieldDefIdx cenv fdkey = + try cenv.fieldDefs.GetTableEntry fdkey + with :? KeyNotFoundException -> + failwith ("The local field "+fdkey.Name+" was referenced but not declared") + 1 + + and GetFieldDefAsFieldDefIdx cenv tidx fd = + FindFieldDefIdx cenv (GetKeyForFieldDef tidx fd) + + // -------------------------------------------------------------------- + // ILMethodRef --> ILMethodDef. + // + // Only successfuly converts ILMethodRef's referring to + // methods in the module being emitted. + // -------------------------------------------------------------------- + + let GetMethodRefAsMethodDefIdx cenv (mref:ILMethodRef) = + let tref = mref.EnclosingTypeRef + try + if not (isTypeRefLocal tref) then + failwithf "method referred to by method impl, event or property is not in a type defined in this module, method ref is %A" mref + let tidx = GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name)) + let mdkey = MethodDefKey (tidx, mref.GenericArity, mref.Name, mref.ReturnType, mref.ArgTypes, mref.CallingConv.IsStatic) + FindMethodDefIdx cenv mdkey + with e -> + failwithf "Error in GetMethodRefAsMethodDefIdx for mref = %A, error: %s" (mref.Name, tref.Name) e.Message + + let rec MethodRefInfoAsMemberRefRow cenv env fenv (nm, typ, callconv, args, ret, varargs, genarity) = + MemberRefRow(GetTypeAsMemberRefParent cenv env typ, + GetStringHeapIdx cenv nm, + GetMethodRefInfoAsBlobIdx cenv fenv (callconv, args, ret, varargs, genarity)) + + and GetMethodRefInfoAsBlobIdx cenv env info = + GetBytesAsBlobIdx cenv (GetCallsigAsBytes cenv env info) + + let GetMethodRefInfoAsMemberRefIdx cenv env ((_, typ, _, _, _, _, _) as minfo) = + let fenv = envForMethodRef env typ + FindOrAddSharedRow cenv ILTableNames.MemberRef (MethodRefInfoAsMemberRefRow cenv env fenv minfo) + + let GetMethodRefInfoAsMethodRefOrDef isAlwaysMethodDef cenv env ((nm, typ:ILType, cc, args, ret, varargs, genarity) as minfo) = + if Option.isNone varargs && (isAlwaysMethodDef || isTypeLocal typ) then + if not typ.IsNominal then failwith "GetMethodRefInfoAsMethodRefOrDef: unexpected local tref-typ" + try (MethodDefOrRefTag.MethodDef, GetMethodRefAsMethodDefIdx cenv (ILMethodRef (typ.TypeRef, cc, genarity, nm, args, ret))) + with MethodDefNotFound -> (MethodDefOrRefTag.MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + else (MethodDefOrRefTag.MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) + + + // -------------------------------------------------------------------- + // ILMethodSpec --> ILMethodRef/ILMethodDef/ILMethodSpec + // -------------------------------------------------------------------- + + let rec GetMethodSpecInfoAsMethodSpecIdx cenv env (nm, typ, cc, args, ret, varargs, minst:ILGenericArgs) = + let mdorTag, mdorRow = GetMethodRefInfoAsMethodRefOrDef false cenv env (nm, typ, cc, args, ret, varargs, minst.Length) + let blob = + emitBytesViaBuffer (fun bb -> + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_GENERICINST + bb.EmitZ32 minst.Length + minst |> Array.iter (EmitType cenv env bb)) + FindOrAddSharedRow cenv ILTableNames.MethodSpec + (SharedRow + [| MethodDefOrRef (mdorTag, mdorRow) + Blob (GetBytesAsBlobIdx cenv blob) |]) + + and GetMethodDefOrRefAsUncodedToken (tag, idx) = + let tab = + if tag = MethodDefOrRefTag.MethodDef then ILTableNames.Method + elif tag = MethodDefOrRefTag.MemberRef then ILTableNames.MemberRef + else failwith "GetMethodDefOrRefAsUncodedToken" + getUncodedToken tab idx + + and GetMethodSpecInfoAsUncodedToken cenv env ((_, _, _, _, _, _, minst:ILGenericArgs) as minfo) = + if minst.Length > 0 then + getUncodedToken ILTableNames.MethodSpec (GetMethodSpecInfoAsMethodSpecIdx cenv env minfo) + else + GetMethodDefOrRefAsUncodedToken (GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo minfo)) + + and GetMethodSpecAsUncodedToken cenv env mspec = + GetMethodSpecInfoAsUncodedToken cenv env (InfoOfMethodSpec mspec) + + and GetMethodRefInfoOfMethodSpecInfo (nm, typ, cc, args, ret, varargs, minst:ILGenericArgs) = + (nm, typ, cc, args, ret, varargs, minst.Length) + + and GetMethodSpecAsMethodDefOrRef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef false cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + + and GetMethodSpecAsMethodDef cenv env (mspec, varargs) = + GetMethodRefInfoAsMethodRefOrDef true cenv env (GetMethodRefInfoOfMethodSpecInfo (InfoOfMethodSpec (mspec, varargs))) + + and InfoOfMethodSpec (mspec:ILMethodSpec, varargs) = + (mspec.Name, + mspec.EnclosingType, + mspec.CallingConv, + mspec.MethodRef.ArgTypes, + mspec.FormalReturnType, + varargs, + mspec.GenericArgs) + + // -------------------------------------------------------------------- + // method_in_parent --> ILMethodRef/ILMethodDef + // + // Used for MethodImpls. + // -------------------------------------------------------------------- + + let rec GetOverridesSpecAsMemberRefIdx cenv env ospec = + let fenv = envForOverrideSpec ospec + let row = MethodRefInfoAsMemberRefRow cenv env fenv (ospec.MethodRef.Name, ospec.EnclosingType, ospec.MethodRef.CallingConv, ospec.MethodRef.ArgTypes, ospec.MethodRef.ReturnType, None, ospec.MethodRef.GenericArity) + FindOrAddSharedRow cenv ILTableNames.MemberRef row + + and GetOverridesSpecAsMethodDefOrRef cenv env (ospec:ILOverridesSpec) = + let typ = ospec.EnclosingType + if isTypeLocal typ then + if not typ.IsNominal then failwith "GetOverridesSpecAsMethodDefOrRef: unexpected local tref-typ" + try (MethodDefOrRefTag.MethodDef, GetMethodRefAsMethodDefIdx cenv ospec.MethodRef) + with MethodDefNotFound -> (MethodDefOrRefTag.MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + else + (MethodDefOrRefTag.MemberRef, GetOverridesSpecAsMemberRefIdx cenv env ospec) + + // -------------------------------------------------------------------- + // ILMethodRef --> ILMethodRef/ILMethodDef + // + // Used for Custom Attrs. + // -------------------------------------------------------------------- + + let rec GetMethodRefAsMemberRefIdx cenv env fenv (mref:ILMethodRef) = + let row = MethodRefInfoAsMemberRefRow cenv env fenv (mref.Name, ILType.Boxed (ILTypeSpec (mref.EnclosingTypeRef, [| |])), mref.CallingConv, mref.ArgTypes, mref.ReturnType, None, mref.GenericArity) + FindOrAddSharedRow cenv ILTableNames.MemberRef row + + and GetMethodRefAsCustomAttribType cenv (mref:ILMethodRef) = + let fenv = envForNonGenericMethodRef mref + let tref = mref.EnclosingTypeRef + if isTypeRefLocal tref then + try (CustomAttributeTypeTag.MethodDef, GetMethodRefAsMethodDefIdx cenv mref) + with MethodDefNotFound -> (CustomAttributeTypeTag.MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + else + (CustomAttributeTypeTag.MemberRef, GetMethodRefAsMemberRefIdx cenv fenv fenv mref) + + // -------------------------------------------------------------------- + // ILCustomAttrs --> CustomAttribute rows + // -------------------------------------------------------------------- + + let rec GetCustomAttrDataAsBlobIdx cenv (data:byte[]) = + if data.Length = 0 then 0 else GetBytesAsBlobIdx cenv data + + and GetCustomAttrRow cenv hca attr = + let cat = GetMethodRefAsCustomAttribType cenv attr.Method.MethodRef + for element in attr.Elements do + match element with + | :? ILType as ty when ty.IsNominal -> GetTypeRefAsTypeRefIdx cenv ty.TypeRef |> ignore + | _ -> () + + UnsharedRow + [| HasCustomAttribute (fst hca, snd hca) + CustomAttributeType (fst cat, snd cat) + Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data) + |] + + and GenCustomAttrPass3Or4 cenv hca attr = + AddUnsharedRow cenv ILTableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore + + and GenCustomAttrsPass3Or4 cenv hca (attrs: ILCustomAttrs) = + attrs.Entries |> Array.iter (GenCustomAttrPass3Or4 cenv hca) + + // -------------------------------------------------------------------- + // ILPermissionSet --> DeclSecurity rows + // -------------------------------------------------------------------- *) + +#if EMIT_SECURITY_DECLS + let rec GetSecurityDeclRow cenv hds (PermissionSet (action, s)) = + UnsharedRow + [| UShort (uint16 (List.assoc action (Lazy.force ILSecurityActionMap))) + HasDeclSecurity (fst hds, snd hds) + Blob (GetBytesAsBlobIdx cenv s) |] + + and GenSecurityDeclPass3 cenv hds attr = + AddUnsharedRow cenv ILTableNames.Permission (GetSecurityDeclRow cenv hds attr) |> ignore + + and GenSecurityDeclsPass3 cenv hds attrs = + List.iter (GenSecurityDeclPass3 cenv hds) attrs +#endif + + // -------------------------------------------------------------------- + // ILFieldSpec --> FieldRef or ILFieldDef row + // -------------------------------------------------------------------- + + let rec GetFieldSpecAsMemberRefRow cenv env fenv (fspec:ILFieldSpec) = + MemberRefRow (GetTypeAsMemberRefParent cenv env fspec.EnclosingType, + GetStringHeapIdx cenv fspec.Name, + GetFieldSpecSigAsBlobIdx cenv fenv fspec) + + and GetFieldSpecAsMemberRefIdx cenv env fspec = + let fenv = envForFieldSpec fspec + FindOrAddSharedRow cenv ILTableNames.MemberRef (GetFieldSpecAsMemberRefRow cenv env fenv fspec) + + // REVIEW: write into an accumuating buffer + and EmitFieldSpecSig cenv env (bb: ByteBuffer) (fspec:ILFieldSpec) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb fspec.FormalType + + and GetFieldSpecSigAsBytes cenv env x = + emitBytesViaBuffer (fun bb -> EmitFieldSpecSig cenv env bb x) + + and GetFieldSpecSigAsBlobIdx cenv env x = + GetBytesAsBlobIdx cenv (GetFieldSpecSigAsBytes cenv env x) + + and GetFieldSpecAsFieldDefOrRef cenv env (fspec:ILFieldSpec) = + let typ = fspec.EnclosingType + if isTypeLocal typ then + if not typ.IsNominal then failwith "GetFieldSpecAsFieldDefOrRef: unexpected local tref-typ" + let tref = typ.TypeRef + let tidx = GetIdxForTypeDef cenv (TdKey(enclosing tref.Scope, tref.Namespace, tref.Name)) + let fdkey = FieldDefKey (tidx, fspec.Name, fspec.FormalType) + (true, FindFieldDefIdx cenv fdkey) + else + (false, GetFieldSpecAsMemberRefIdx cenv env fspec) + + and GetFieldDefOrRefAsUncodedToken (tag, idx) = + let tab = if tag then ILTableNames.Field else ILTableNames.MemberRef + getUncodedToken tab idx + + // -------------------------------------------------------------------- + // callsig --> StandAloneSig + // -------------------------------------------------------------------- + + let GetCallsigAsBlobIdx cenv env (callsig:ILCallingSignature, varargs) = + GetBytesAsBlobIdx cenv + (GetCallsigAsBytes cenv env (callsig.CallingConv, + callsig.ArgTypes, + callsig.ReturnType, varargs, 0)) + + let GetCallsigAsStandAloneSigRow cenv env x = + SharedRow [| Blob (GetCallsigAsBlobIdx cenv env x) |] + + let GetCallsigAsStandAloneSigIdx cenv env info = + FindOrAddSharedRow cenv ILTableNames.StandAloneSig (GetCallsigAsStandAloneSigRow cenv env info) + + // -------------------------------------------------------------------- + // local signatures --> BlobHeap idx + // -------------------------------------------------------------------- + + let EmitLocalSig cenv env (bb: ByteBuffer) (locals: ILLocals) = + bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_LOCAL_SIG + bb.EmitZ32 locals.Length + locals |> Array.iter (EmitLocalInfo cenv env bb) + + let GetLocalSigAsBlobHeapIdx cenv env locals = + GetBytesAsBlobIdx cenv (emitBytesViaBuffer (fun bb -> EmitLocalSig cenv env bb locals)) + + let GetLocalSigAsStandAloneSigIdx cenv env locals = + SharedRow [| Blob (GetLocalSigAsBlobHeapIdx cenv env locals) |] + + + + type ExceptionClauseKind = + | FinallyClause + | FaultClause + | TypeFilterClause of int32 + | FilterClause of int + + type ExceptionClauseSpec = (int * int * int * int * ExceptionClauseKind) + + type CodeBuffer = + + // -------------------------------------------------------------------- + // Buffer to write results of emitting code into. Also record: + // - branch sources (where fixups will occur) + // - possible branch destinations + // - locations of embedded handles into the string table + // - the exception table + // -------------------------------------------------------------------- + { code: ByteBuffer + /// (instruction; optional short form); start of instr in code buffer; code loc for the end of the instruction the fixup resides in ; where is the destination of the fixup + mutable reqdBrFixups: ResizeArray<((int * int option) * int * ILCodeLabel list)> + availBrFixups: Dictionary + /// code loc to fixup in code buffer + mutable reqdStringFixupsInMethod: ResizeArray<(int * int)> + /// data for exception handling clauses + mutable seh: ResizeArray +#if DEBUG_INFO + seqpoints: ResizeArray +#endif + } + + static member Create _nm = + { seh = ResizeArray() + code= ByteBuffer.Create 200 + reqdBrFixups= ResizeArray() + reqdStringFixupsInMethod=ResizeArray() + availBrFixups = Dictionary<_, _>(10, HashIdentity.Structural) +#if DEBUG_INFO + seqpoints = new ResizeArray<_>(10) +#endif + } + + member codebuf.EmitExceptionClause seh = codebuf.seh.Add(seh) + +#if DEBUG_INFO + member codebuf.EmitSeqPoint cenv (m:ILSourceMarker) = () + if cenv.generatePdb then + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + codebuf.seqpoints.Add + { Document=doc + Offset= codebuf.code.Position + Line=m.Line + Column=m.Column + EndLine=m.EndLine + EndColumn=m.EndColumn } +#endif + + member codebuf.EmitByte x = codebuf.code.EmitIntAsByte x + member codebuf.EmitUInt16 x = codebuf.code.EmitUInt16 x + member codebuf.EmitInt32 x = codebuf.code.EmitInt32 x + member codebuf.EmitInt64 x = codebuf.code.EmitInt64 x + + member codebuf.EmitUncodedToken u = codebuf.EmitInt32 u + + member codebuf.RecordReqdStringFixup stringidx = + codebuf.reqdStringFixupsInMethod.Add((codebuf.code.Position, stringidx)) + // Write a special value in that we check later when applying the fixup + codebuf.EmitInt32 0xdeadbeef + + member codebuf.RecordReqdBrFixups i tgs = + codebuf.reqdBrFixups.Add ((i, codebuf.code.Position, tgs)) + // Write a special value in that we check later when applying the fixup + // Value is 0x11 {deadbbbb}* where 11 is for the instruction and deadbbbb is for each target + codebuf.EmitByte 0x11 // for the instruction + (if fst i = i_switch then + codebuf.EmitInt32 tgs.Length) + List.iter (fun _ -> codebuf.EmitInt32 0xdeadbbbb) tgs + + member codebuf.RecordReqdBrFixup i tg = codebuf.RecordReqdBrFixups i [tg] + member codebuf.RecordAvailBrFixup tg = + codebuf.availBrFixups.[tg] <- codebuf.code.Position + + module Codebuf = + // -------------------------------------------------------------------- + // Applying branch fixups. Use short versions of instructions + // wherever possible. Sadly we can only determine if we can use a short + // version after we've layed out the code for all other instructions. + // This in turn means that using a short version may change + // the various offsets into the code. + // -------------------------------------------------------------------- + + let binaryChop p (arr: 'T[]) = + let rec go n m = + if n > m then raise (KeyNotFoundException("binary chop did not find element")) + else + let i = (n+m)/2 + let c = p arr.[i] + if c = 0 then i elif c < 0 then go n (i-1) else go (i+1) m + go 0 (Array.length arr) + + let applyBrFixups (origCode :byte[]) origExnClauses origReqdStringFixups (origAvailBrFixups: Dictionary) origReqdBrFixups = + let orderedOrigReqdBrFixups = origReqdBrFixups |> Array.sortBy (fun (_, fixuploc, _) -> fixuploc) + + let newCode = ByteBuffer.Create origCode.Length + + // Copy over all the code, working out whether the branches will be short + // or long and adjusting the branch destinations. Record an adjust function to adjust all the other + // gumpf that refers to fixed offsets in the code stream. + let newCode, newReqdBrFixups, adjuster = + let remainingReqdFixups = ref (Array.toList orderedOrigReqdBrFixups) + let origWhere = ref 0 + let newWhere = ref 0 + let doneLast = ref false + let newReqdBrFixups = ref [] + + let adjustments = ref [] + + while (not (isNil !remainingReqdFixups) || not !doneLast) do + let doingLast = isNil !remainingReqdFixups + let origStartOfNoBranchBlock = !origWhere + let newStartOfNoBranchBlock = !newWhere + + let origEndOfNoBranchBlock = + if doingLast then origCode.Length + else + let (_, origStartOfInstr, _) = List.head !remainingReqdFixups + origStartOfInstr + + // Copy over a chunk of non-branching code + let nobranch_len = origEndOfNoBranchBlock - origStartOfNoBranchBlock + newCode.EmitBytes origCode.[origStartOfNoBranchBlock..origStartOfNoBranchBlock+nobranch_len-1] + + // Record how to adjust addresses in this range, including the branch instruction + // we write below, or the end of the method if we're doing the last bblock + adjustments := (origStartOfNoBranchBlock, origEndOfNoBranchBlock, newStartOfNoBranchBlock) :: !adjustments + + // Increment locations to the branch instruction we're really interested in + origWhere := origEndOfNoBranchBlock + newWhere := !newWhere + nobranch_len + + // Now do the branch instruction. Decide whether the fixup will be short or long in the new code + if doingLast then + doneLast := true + else + let (i, origStartOfInstr, tgs:ILCodeLabel list) = List.head !remainingReqdFixups + remainingReqdFixups := List.tail !remainingReqdFixups + if origCode.[origStartOfInstr] <> 0x11uy then failwith "br fixup sanity check failed (1)" + let i_length = if fst i = i_switch then 5 else 1 + origWhere := !origWhere + i_length + + let origEndOfInstr = origStartOfInstr + i_length + 4 * tgs.Length + let newEndOfInstrIfSmall = !newWhere + i_length + 1 + let newEndOfInstrIfBig = !newWhere + i_length + 4 * tgs.Length + + let short = + match i, tgs with + | (_, Some i_short), [tg] + when + begin + // Use the original offsets to compute if the branch is small or large. This is + // a safe approximation because code only gets smaller. + if not (origAvailBrFixups.ContainsKey tg) then + printfn "%s" ("branch target " + formatCodeLabel tg + " not found in code") + let origDest = + if origAvailBrFixups.ContainsKey tg then origAvailBrFixups.[tg] + else 666666 + let origRelOffset = origDest - origEndOfInstr + -128 <= origRelOffset && origRelOffset <= 127 + end + -> + newCode.EmitIntAsByte i_short + true + | (i_long, _), _ -> + newCode.EmitIntAsByte i_long + (if i_long = i_switch then + newCode.EmitInt32 tgs.Length) + false + + newWhere := !newWhere + i_length + if !newWhere <> newCode.Position then printfn "mismatch between newWhere and newCode" + + tgs |> List.iter (fun tg -> + let origFixupLoc = !origWhere + checkFixup32 origCode origFixupLoc 0xdeadbbbb + + if short then + newReqdBrFixups := (!newWhere, newEndOfInstrIfSmall, tg, true) :: !newReqdBrFixups + newCode.EmitIntAsByte 0x98 (* sanity check *) + newWhere := !newWhere + 1 + else + newReqdBrFixups := (!newWhere, newEndOfInstrIfBig, tg, false) :: !newReqdBrFixups + newCode.EmitInt32 0xf00dd00f (* sanity check *) + newWhere := !newWhere + 4 + if !newWhere <> newCode.Position then printfn "mismatch between newWhere and newCode" + origWhere := !origWhere + 4) + + if !origWhere <> origEndOfInstr then printfn "mismatch between origWhere and origEndOfInstr" + + let adjuster = + let arr = Array.ofList (List.rev !adjustments) + fun addr -> + let i = + try binaryChop (fun (a1, a2, _) -> if addr < a1 then -1 elif addr > a2 then 1 else 0) arr + with + :? KeyNotFoundException -> + failwith ("adjuster: address "+string addr+" is out of range") + let (origStartOfNoBranchBlock, _, newStartOfNoBranchBlock) = arr.[i] + addr - (origStartOfNoBranchBlock - newStartOfNoBranchBlock) + + newCode.Close(), + List.toArray !newReqdBrFixups, + adjuster + + // Now adjust everything + let newAvailBrFixups = + let tab = Dictionary<_, _>(10, HashIdentity.Structural) + for (KeyValue(tglab, origBrDest)) in origAvailBrFixups do + tab.[tglab] <- adjuster origBrDest + tab + let newReqdStringFixups = Array.map (fun (origFixupLoc, stok) -> adjuster origFixupLoc, stok) origReqdStringFixups +#if EMIT_DEBUG_INFO + let newSeqPoints = Array.map (fun (sp:PdbSequencePoint) -> {sp with Offset=adjuster sp.Offset}) origSeqPoints +#endif + let newExnClauses = + origExnClauses |> Array.map (fun (st1, sz1, st2, sz2, kind) -> + (adjuster st1, (adjuster (st1 + sz1) - adjuster st1), + adjuster st2, (adjuster (st2 + sz2) - adjuster st2), + (match kind with + | FinallyClause | FaultClause | TypeFilterClause _ -> kind + | FilterClause n -> FilterClause (adjuster n)))) + +#if EMIT_DEBUG_INFO + let newScopes = + let rec remap scope = + {scope with StartOffset = adjuster scope.StartOffset + EndOffset = adjuster scope.EndOffset + Children = Array.map remap scope.Children } + Array.map remap origScopes +#endif - let fixedBody = loop body - Expr.Let(v, fixedOperand, fixedBody.Substitute(fun v1 -> if v1 = arg then Some ev else None)) - | fixedApplicable -> Expr.Application(fixedApplicable, fixedOperand) - | x -> fallback x - loop expr - - let inlineValueBindings e = - let map = Dictionary(HashIdentity.Reference) - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | Let(id, (Value(_) as v), body) when not id.IsMutable -> - map.[id] <- v - let fixedBody = loop body - map.Remove(id) |> ignore - fixedBody - | ShapeVarUnchecked v -> - match map.TryGetValue v with - | true, e -> e - | _ -> orig - | x -> fallback x - loop e - - - let optimizeCurriedApplications expr = - let rec loop expr = traverse loopCore expr - and loopCore fallback orig = - match orig with - | Application(e, arg) -> - let e1 = tryPeelApplications e [loop arg] - if e1 === e then - orig - else - e1 - | x -> fallback x - and tryPeelApplications orig args = - let n = List.length args - match orig with - | Application(e, arg) -> - let e1 = tryPeelApplications e ((loop arg)::args) - if e1 === e then - orig + // Now apply the adjusted fixups in the new code + newReqdBrFixups |> Array.iter (fun (newFixupLoc, endOfInstr, tg, small) -> + if not (newAvailBrFixups.ContainsKey tg) then + failwith ("target "+formatCodeLabel tg+" not found in new fixups") + try + let n = newAvailBrFixups.[tg] + let relOffset = (n - endOfInstr) + if small then + if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixupsanity check failed" + newCode.[newFixupLoc] <- b0 relOffset + else + checkFixup32 newCode newFixupLoc 0xf00dd00fl + applyFixup32 newCode newFixupLoc relOffset + with :? KeyNotFoundException -> ()) + + newCode, newReqdStringFixups, newExnClauses + + + // -------------------------------------------------------------------- + // Structured residue of emitting instructions: SEH exception handling + // and scopes for local variables. + // -------------------------------------------------------------------- + + // Emitting instructions generates a tree of seh specifications + // We then emit the exception handling specs separately. + // nb. ECMA spec says the SEH blocks must be returned inside-out + type SEHTree = + | Node of ExceptionClauseSpec option * SEHTree[] + + + // -------------------------------------------------------------------- + // Table of encodings for instructions without arguments, also indexes + // for all instructions. + // -------------------------------------------------------------------- + + let encodingsForNoArgInstrs = Dictionary<_, _>(300, HashIdentity.Structural) + let _ = + List.iter + (fun (x, mk) -> encodingsForNoArgInstrs.[mk] <- x) + (noArgInstrs.Force()) + let encodingsOfNoArgInstr si = encodingsForNoArgInstrs.[si] + + // -------------------------------------------------------------------- + // Emit instructions + // -------------------------------------------------------------------- + + /// Emit the code for an instruction + let emitInstrCode (codebuf: CodeBuffer) i = + if i > 0xFF then + assert (i >>> 8 = 0xFE) + codebuf.EmitByte ((i >>> 8) &&& 0xFF) + codebuf.EmitByte (i &&& 0xFF) else - e1 - | Let(id, applicable, (Lambda(_) as body)) when n > 0 -> - let numberOfApplication = countPeelableApplications body id 0 - if numberOfApplication = 0 then orig - elif n = 1 then Expr.Application(applicable, List.head args) - elif n <= 5 then - let resultType = - applicable.Type - |> Seq.unfold (fun t -> - if not t.IsGenericType then None else - let args = t.GetGenericArguments() - if args.Length <> 2 then None else - Some (args.[1], args.[1]) - ) - |> Seq.toArray - |> (fun arr -> arr.[n - 1]) - - let adaptMethod = getFastFuncType args resultType - let adapted = Expr.Call(adaptMethod, [loop applicable]) - let invoke = adapted.Type.GetMethod("Invoke", [| for arg in args -> arg.Type |]) - Expr.Call(adapted, invoke, args) - else - (applicable, args) ||> List.fold (fun e a -> Expr.Application(e, a)) - | _ -> - orig - and countPeelableApplications expr v n = - match expr with - // v - applicable entity obtained on the prev step - // \arg -> let v1 = (f arg) in rest ==> f - | Lambda(arg, Let(v1, Application(Var f, Var arg1), rest)) when v = f && arg = arg1 -> countPeelableApplications rest v1 (n + 1) - // \arg -> (f arg) ==> f - | Lambda(arg, Application(Var f, Var arg1)) when v = f && arg = arg1 -> n - | _ -> n - loop expr - - // Use the real variable names instead of indices, to improve output of Debug.fs - let transQuotationToCode isGenerated qexprf (paramNames: string[]) (argExprs: Expr[]) = - // Add let bindings for arguments to ensure that arguments will be evaluated - let vars = argExprs |> Array.mapi (fun i e -> Quotations.Var(paramNames.[i], e.Type)) - let expr = qexprf ([for v in vars -> Expr.Var v]) - - let pairs = Array.zip argExprs vars - let expr = Array.foldBack (fun (arg, var) e -> Expr.LetUnchecked(var, arg, e)) pairs expr - let expr = - if isGenerated then - let e1 = inlineRightPipe expr - let e2 = optimizeCurriedApplications e1 - let e3 = inlineValueBindings e2 - e3 - else - expr + codebuf.EmitByte i - transExpr isGenerated expr + let emitTypeInstr cenv codebuf env i ty = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + let emitMethodSpecInfoInstr cenv codebuf env i mspecinfo = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecInfoAsUncodedToken cenv env mspecinfo) -[] -module internal Misc = + let emitMethodSpecInstr cenv codebuf env i mspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetMethodSpecAsUncodedToken cenv env mspec) - type internal ExpectedStackState = - | Empty = 1 - | Address = 2 - | Value = 3 + let emitFieldSpecInstr cenv codebuf env i fspec = + emitInstrCode codebuf i + codebuf.EmitUncodedToken (GetFieldDefOrRefAsUncodedToken (GetFieldSpecAsFieldDefOrRef cenv env fspec)) - let TypeBuilderInstantiationType = - let runningOnMono = try System.Type.GetType("Mono.Runtime") <> null with e -> false - let typeName = if runningOnMono then "System.Reflection.MonoGenericClass" else "System.Reflection.Emit.TypeBuilderInstantiation" - typeof.Assembly.GetType(typeName) - - let GetTypeFromHandleMethod = typeof.GetMethod("GetTypeFromHandle") - let LanguagePrimitivesType = typedefof>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives") - let ParseInt32Method = LanguagePrimitivesType.GetMethod "ParseInt32" - let DecimalConstructor = typeof.GetConstructor([| typeof; typeof; typeof; typeof; typeof |]) - let DateTimeConstructor = typeof.GetConstructor([| typeof; typeof |]) - let DateTimeOffsetConstructor = typeof.GetConstructor([| typeof; typeof |]) - let TimeSpanConstructor = typeof.GetConstructor([|typeof|]) - let isEmpty s = s = ExpectedStackState.Empty - let isAddress s = s = ExpectedStackState.Address - - let nonNull str x = if x=null then failwith ("Null in " + str) else x - - let notRequired opname item = - let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item - System.Diagnostics.Debug.Assert (false, msg) - raise (System.NotSupportedException msg) - - let mkParamArrayCustomAttributeData() = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = upcast [| |] } - -#if FX_NO_CUSTOMATTRIBUTEDATA - let CustomAttributeTypedArgument(ty,v) = - { new IProvidedCustomAttributeTypedArgument with - member x.ArgumentType = ty - member x.Value = v } - let CustomAttributeNamedArgument(memb,arg:IProvidedCustomAttributeTypedArgument) = - { new IProvidedCustomAttributeNamedArgument with - member x.MemberInfo = memb - member x.ArgumentType = arg.ArgumentType - member x.TypedValue = arg } - type CustomAttributeData = Microsoft.FSharp.Core.CompilerServices.IProvidedCustomAttributeData + let emitShortUInt16Instr codebuf (i_short, i) x = + let n = int32 x + if n <= 255 then + emitInstrCode codebuf i_short + codebuf.EmitByte n + else + emitInstrCode codebuf i + codebuf.EmitUInt16 x + + let emitShortInt32Instr codebuf (i_short, i) x = + if x >= (-128) && x <= 127 then + emitInstrCode codebuf i_short + codebuf.EmitByte (if x < 0x0 then x + 256 else x) + else + emitInstrCode codebuf i + codebuf.EmitInt32 x + + let emitTailness (cenv: cenv) codebuf tl = + if tl = Tailcall && cenv.emitTailcalls then emitInstrCode codebuf i_tail + + //let emitAfterTailcall codebuf tl = + // if tl = Tailcall then emitInstrCode codebuf i_ret + + let emitVolatility codebuf tl = + if tl = Volatile then emitInstrCode codebuf i_volatile + + let emitConstrained cenv codebuf env ty = + emitInstrCode codebuf i_constrained + codebuf.EmitUncodedToken (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env ty)) + + let emitAlignment codebuf tl = + match tl with + | Aligned -> () + | Unaligned1 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x1 + | Unaligned2 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x2 + | Unaligned4 -> emitInstrCode codebuf i_unaligned; codebuf.EmitByte 0x4 + + let rec emitInstr cenv codebuf env instr = + match instr with + | si when isNoArgInstr si -> + emitInstrCode codebuf (encodingsOfNoArgInstr si) + | I_brcmp (cmp, tg1) -> + codebuf.RecordReqdBrFixup (ILCmpInstrMap.Value.[cmp], Some ILCmpInstrRevMap.Value.[cmp]) tg1 + | I_br tg -> codebuf.RecordReqdBrFixup (i_br, Some i_br_s) tg +#if EMIT_DEBUG_INFO + | I_seqpoint s -> codebuf.EmitSeqPoint cenv s +#endif + | I_leave tg -> codebuf.RecordReqdBrFixup (i_leave, Some i_leave_s) tg + | I_call (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_call (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callvirt (tl, mspec, varargs) -> + emitTailness cenv codebuf tl + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_callconstraint (tl, ty, mspec, varargs) -> + emitTailness cenv codebuf tl + emitConstrained cenv codebuf env ty + emitMethodSpecInstr cenv codebuf env i_callvirt (mspec, varargs) + //emitAfterTailcall codebuf tl + | I_newobj (mspec, varargs) -> + emitMethodSpecInstr cenv codebuf env i_newobj (mspec, varargs) + | I_ldftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldftn (mspec, None) + | I_ldvirtftn mspec -> + emitMethodSpecInstr cenv codebuf env i_ldvirtftn (mspec, None) + + | I_calli (tl, callsig, varargs) -> + emitTailness cenv codebuf tl + emitInstrCode codebuf i_calli + codebuf.EmitUncodedToken (getUncodedToken ILTableNames.StandAloneSig (GetCallsigAsStandAloneSigIdx cenv env (callsig, varargs))) + //emitAfterTailcall codebuf tl + + | I_ldarg x -> emitShortUInt16Instr codebuf (i_ldarg_s, i_ldarg) (uint16 x) + | I_starg x -> emitShortUInt16Instr codebuf (i_starg_s, i_starg) (uint16 x) + | I_ldarga x -> emitShortUInt16Instr codebuf (i_ldarga_s, i_ldarga) (uint16 x) + | I_ldloc x -> emitShortUInt16Instr codebuf (i_ldloc_s, i_ldloc) (uint16 x) + | I_stloc x -> emitShortUInt16Instr codebuf (i_stloc_s, i_stloc) (uint16 x) + | I_ldloca x -> emitShortUInt16Instr codebuf (i_ldloca_s, i_ldloca) (uint16 x) + + | I_cpblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_cpblk + | I_initblk (al, vol) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf i_initblk + + | (I_ldc (DT_I4, ILConst.I4 x)) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) x + | (I_ldc (DT_I8, ILConst.I8 x)) -> + emitInstrCode codebuf i_ldc_i8 + codebuf.EmitInt64 x + | (I_ldc (_, ILConst.R4 x)) -> + emitInstrCode codebuf i_ldc_r4 + codebuf.EmitInt32 (bitsOfSingle x) + | (I_ldc (_, ILConst.R8 x)) -> + emitInstrCode codebuf i_ldc_r8 + codebuf.EmitInt64 (bitsOfDouble x) + + | I_ldind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldind_i + | DT_I1 -> i_ldind_i1 + | DT_I2 -> i_ldind_i2 + | DT_I4 -> i_ldind_i4 + | DT_U1 -> i_ldind_u1 + | DT_U2 -> i_ldind_u2 + | DT_U4 -> i_ldind_u4 + | DT_I8 -> i_ldind_i8 + | DT_R4 -> i_ldind_r4 + | DT_R8 -> i_ldind_r8 + | DT_REF -> i_ldind_ref + | _ -> failwith "ldind") + + | I_stelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I | DT_U -> i_stelem_i + | DT_U1 | DT_I1 -> i_stelem_i1 + | DT_I2 | DT_U2 -> i_stelem_i2 + | DT_I4 | DT_U4 -> i_stelem_i4 + | DT_I8 | DT_U8 -> i_stelem_i8 + | DT_R4 -> i_stelem_r4 + | DT_R8 -> i_stelem_r8 + | DT_REF -> i_stelem_ref + | _ -> failwith "stelem") + + | I_ldelem dt -> + emitInstrCode codebuf + (match dt with + | DT_I -> i_ldelem_i + | DT_I1 -> i_ldelem_i1 + | DT_I2 -> i_ldelem_i2 + | DT_I4 -> i_ldelem_i4 + | DT_I8 -> i_ldelem_i8 + | DT_U1 -> i_ldelem_u1 + | DT_U2 -> i_ldelem_u2 + | DT_U4 -> i_ldelem_u4 + | DT_R4 -> i_ldelem_r4 + | DT_R8 -> i_ldelem_r8 + | DT_REF -> i_ldelem_ref + | _ -> failwith "ldelem") + + | I_stind (al, vol, dt) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitInstrCode codebuf + (match dt with + | DT_U | DT_I -> i_stind_i + | DT_U1 | DT_I1 -> i_stind_i1 + | DT_U2 | DT_I2 -> i_stind_i2 + | DT_U4 | DT_I4 -> i_stind_i4 + | DT_U8 | DT_I8 -> i_stind_i8 + | DT_R4 -> i_stind_r4 + | DT_R8 -> i_stind_r8 + | DT_REF -> i_stind_ref + | _ -> failwith "stelem") + + | I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs + + | I_ldfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldfld fspec + | I_ldflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldflda fspec + | I_ldsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_ldsfld fspec + | I_ldsflda fspec -> + emitFieldSpecInstr cenv codebuf env i_ldsflda fspec + | I_stfld (al, vol, fspec) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stfld fspec + | I_stsfld (vol, fspec) -> + emitVolatility codebuf vol + emitFieldSpecInstr cenv codebuf env i_stsfld fspec + + | I_ldtoken tok -> + emitInstrCode codebuf i_ldtoken + codebuf.EmitUncodedToken + (match tok with + | ILToken.ILType typ -> + match GetTypeAsTypeDefOrRef cenv env typ with + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeDef -> getUncodedToken ILTableNames.TypeDef idx + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeRef -> getUncodedToken ILTableNames.TypeRef idx + | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> getUncodedToken ILTableNames.TypeSpec idx + | _ -> failwith "?" + | ILToken.ILMethod mspec -> + match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with + | (tag, idx) when tag = MethodDefOrRefTag.MethodDef -> getUncodedToken ILTableNames.Method idx + | (tag, idx) when tag = MethodDefOrRefTag.MemberRef -> getUncodedToken ILTableNames.MemberRef idx + | _ -> failwith "?" + + | ILToken.ILField fspec -> + match GetFieldSpecAsFieldDefOrRef cenv env fspec with + | (true, idx) -> getUncodedToken ILTableNames.Field idx + | (false, idx) -> getUncodedToken ILTableNames.MemberRef idx) + | I_ldstr s -> + emitInstrCode codebuf i_ldstr + codebuf.RecordReqdStringFixup (GetUserStringHeapIdx cenv s) + + | I_box ty -> emitTypeInstr cenv codebuf env i_box ty + | I_unbox ty -> emitTypeInstr cenv codebuf env i_unbox ty + | I_unbox_any ty -> emitTypeInstr cenv codebuf env i_unbox_any ty + + | I_newarr (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_newarr ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_newobj (".ctor", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, [| |]) + + | I_stelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_stelem_any ty + else + let args = Array.init (shape.Rank+1) (fun i -> if i < shape.Rank then cenv.ilg.typ_Int32 else ty) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Set", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Void, None, [| |]) + + | I_ldelem_any (shape, ty) -> + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelem_any ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Get", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ty, None, [| |]) + + | I_ldelema (ro, shape, ty) -> + if (ro = ReadonlyAddress) then + emitInstrCode codebuf i_readonly + if (shape = ILArrayShape.SingleDimensional) then + emitTypeInstr cenv codebuf env i_ldelema ty + else + let args = Array.init shape.Rank (fun _ -> cenv.ilg.typ_Int32) + emitMethodSpecInfoInstr cenv codebuf env i_call ("Address", mkILArrTy(ty, shape), ILCallingConv.Instance, args, ILType.Byref ty, None, [| |]) + + | I_castclass ty -> emitTypeInstr cenv codebuf env i_castclass ty + | I_isinst ty -> emitTypeInstr cenv codebuf env i_isinst ty + | I_refanyval ty -> emitTypeInstr cenv codebuf env i_refanyval ty + | I_mkrefany ty -> emitTypeInstr cenv codebuf env i_mkrefany ty + | I_initobj ty -> emitTypeInstr cenv codebuf env i_initobj ty + | I_ldobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_ldobj ty + | I_stobj (al, vol, ty) -> + emitAlignment codebuf al + emitVolatility codebuf vol + emitTypeInstr cenv codebuf env i_stobj ty + | I_cpobj ty -> emitTypeInstr cenv codebuf env i_cpobj ty + | I_sizeof ty -> emitTypeInstr cenv codebuf env i_sizeof ty + | EI_ldlen_multi (_, m) -> + emitShortInt32Instr codebuf (i_ldc_i4_s, i_ldc_i4) m + let mspec = mkILMethSpecInTyRaw(cenv.ilg.typ_Array, ILCallingConv.Instance, "GetLength", [|cenv.ilg.typ_Int32|], cenv.ilg.typ_Int32, [| |]) + emitInstr cenv codebuf env (mkNormalCall mspec) + + | _ -> failwith "an IL instruction cannot be emitted" + + + // Used to put local debug scopes and exception handlers into a tree form + let rangeInsideRange (start_pc1, end_pc1) (start_pc2, end_pc2) = + (start_pc1:int) >= start_pc2 && start_pc1 < end_pc2 && + (end_pc1:int) > start_pc2 && end_pc1 <= end_pc2 + + let lranges_of_clause cl = + match cl with + | ILExceptionClause.Finally r1 -> [r1] + | ILExceptionClause.Fault r1 -> [r1] + | ILExceptionClause.FilterCatch (r1, r2) -> [r1;r2] + | ILExceptionClause.TypeCatch (_ty, r1) -> [r1] + + + let labelsToRange (lab2pc: Dictionary) p = let (l1, l2) = p in lab2pc.[l1], lab2pc.[l2] + + let labelRangeInsideLabelRange lab2pc ls1 ls2 = + rangeInsideRange (labelsToRange lab2pc ls1) (labelsToRange lab2pc ls2) + +// This file still gets used when targeting FSharp.Core 3.1.0.0, e.g. in FSharp.Data +#if !ABOVE_FSCORE_4_0_0_0 + let mapFold f acc (array: _[]) = + match array.Length with + | 0 -> [| |], acc + | len -> + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) + let mutable acc = acc + let res = Array.zeroCreate len + for i = 0 to array.Length-1 do + let h',s' = f.Invoke(acc,array.[i]) + res.[i] <- h' + acc <- s' + res, acc +#endif + let findRoots contains vs = + // For each item, either make it a root or make it a child of an existing root + let addToRoot roots x = + // Look to see if 'x' is inside one of the roots + let roots, found = + (false, roots) ||> mapFold (fun found (r, children) -> + if found then ((r, children), true) + elif contains x r then ((r, Array.append [| x |] children), true) + else ((r, children), false)) + + if found then roots + else + // Find the ones that 'x' encompasses and collapse them + let yes, others = roots |> Array.partition (fun (r, _) -> contains r x) + let yesChild = yes |> Array.collect (fun (r, ch) -> Array.append [| r |] ch) + Array.append [| (x, yesChild) |] others + + ([| |], vs) ||> Array.fold addToRoot + + let rec makeSEHTree cenv env (pc2pos: int[]) (lab2pc: Dictionary) (exs: ILExceptionSpec[]) = + + let clause_inside_lrange cl lr = + List.forall (fun lr1 -> labelRangeInsideLabelRange lab2pc lr1 lr) (lranges_of_clause cl) + + let tryspec_inside_lrange (tryspec1: ILExceptionSpec) lr = + (labelRangeInsideLabelRange lab2pc tryspec1.Range lr && clause_inside_lrange tryspec1.Clause lr) + + let tryspec_inside_clause tryspec1 cl = + List.exists (fun lr -> tryspec_inside_lrange tryspec1 lr) (lranges_of_clause cl) + + let tryspec_inside_tryspec tryspec1 (tryspec2: ILExceptionSpec) = + tryspec_inside_lrange tryspec1 tryspec2.Range || + tryspec_inside_clause tryspec1 tryspec2.Clause + + let roots = findRoots tryspec_inside_tryspec exs + let trees = + roots |> Array.map (fun (cl, ch) -> + let r1 = labelsToRange lab2pc cl.Range + let conv ((s1, e1), (s2, e2)) x = pc2pos.[s1], pc2pos.[e1] - pc2pos.[s1], pc2pos.[s2], pc2pos.[e2] - pc2pos.[s2], x + let children = makeSEHTree cenv env pc2pos lab2pc ch + let n = + match cl.Clause with + | ILExceptionClause.Finally r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FinallyClause + | ILExceptionClause.Fault r2 -> + conv (r1, labelsToRange lab2pc r2) ExceptionClauseKind.FaultClause + | ILExceptionClause.FilterCatch ((filterStart, _), r3) -> + conv (r1, labelsToRange lab2pc r3) (ExceptionClauseKind.FilterClause (pc2pos.[lab2pc.[filterStart]])) + | ILExceptionClause.TypeCatch (typ, r2) -> + conv (r1, labelsToRange lab2pc r2) (TypeFilterClause (getTypeDefOrRefAsUncodedToken (GetTypeAsTypeDefOrRef cenv env typ))) + SEHTree.Node (Some n, children) ) + + trees + +#if EMIT_DEBUG_INFO + let rec makeLocalsTree cenv localSigs (pc2pos: int[]) (lab2pc: Dictionary) (exs: ILLocalDebugInfo[]) = + let localInsideLocal (locspec1: ILLocalDebugInfo) (locspec2: ILLocalDebugInfo) = + labelRangeInsideLabelRange lab2pc locspec1.Range locspec2.Range + + let roots = findRoots localInsideLocal exs + + let trees = + roots |> Array.collect (fun (cl, ch) -> + let (s1, e1) = labelsToRange lab2pc cl.Range + let (s1, e1) = pc2pos.[s1], pc2pos.[e1] + let children = makeLocalsTree cenv localSigs pc2pos lab2pc ch + mkScopeNode cenv localSigs (s1, e1, cl.DebugMappings, children)) + trees #endif - let mkEditorHideMethodsCustomAttributeData() = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = upcast [| |] } - let mkAllowNullLiteralCustomAttributeData value = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with -#endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, value) |] - member __.NamedArguments = upcast [| |] } - - /// This makes an xml doc attribute w.r.t. an amortized computation of an xml doc string. - /// It is important that the text of the xml doc only get forced when poking on the ConstructorArguments - /// for the CustomAttributeData object. - let mkXmlDocCustomAttributeDataLazy(lazyText: Lazy) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with + // Emit the SEH tree + let rec emitExceptionHandlerTree (codebuf: CodeBuffer) (Node (x, childSEH)) = + childSEH |> Array.iter (emitExceptionHandlerTree codebuf) // internal first + x |> Option.iter codebuf.EmitExceptionClause + + let emitCode cenv localSigs (codebuf: CodeBuffer) env (code: ILCode) = + let instrs = code.Instrs + + // Build a table mapping Abstract IL pcs to positions in the generated code buffer + let pc2pos = Array.zeroCreate (instrs.Length+1) + let pc2labs = Dictionary() + for (KeyValue(lab, pc)) in code.Labels do + if pc2labs.ContainsKey pc then pc2labs.[pc] <- lab :: pc2labs.[pc] else pc2labs.[pc] <- [lab] + + // Emit the instructions + for pc = 0 to instrs.Length do + if pc2labs.ContainsKey pc then + for lab in pc2labs.[pc] do + codebuf.RecordAvailBrFixup lab + pc2pos.[pc] <- codebuf.code.Position + if pc < instrs.Length then + match instrs.[pc] with + | I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction + | i -> emitInstr cenv codebuf env i + + // Build the exceptions and locals information, ready to emit + let SEHTree = makeSEHTree cenv env pc2pos code.Labels code.Exceptions + Array.iter (emitExceptionHandlerTree codebuf) SEHTree + +#if EMIT_DEBUG_INFO + // Build the locals information, ready to emit + let localsTree = makeLocalsTree cenv localSigs pc2pos code.Labels code.Locals + localsTree #endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof, lazyText.Force()) |] - member __.NamedArguments = upcast [| |] } - let mkXmlDocCustomAttributeData(s:string) = mkXmlDocCustomAttributeDataLazy (lazy s) + let EmitTopCode cenv localSigs env nm code = + let codebuf = CodeBuffer.Create nm + let origScopes = emitCode cenv localSigs codebuf env code + let origCode = codebuf.code.Close() + let origExnClauses = codebuf.seh.ToArray() + let origReqdStringFixups = codebuf.reqdStringFixupsInMethod.ToArray() + let origAvailBrFixups = codebuf.availBrFixups + let origReqdBrFixups = codebuf.reqdBrFixups.ToArray() +#if EMIT_DEBUG_INFO + let origSeqPoints = codebuf.seqpoints.ToArray() +#endif - let mkDefinitionLocationAttributeCustomAttributeData(line:int,column:int,filePath:string) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with + let newCode, newReqdStringFixups, newExnClauses = + applyBrFixups origCode origExnClauses origReqdStringFixups origAvailBrFixups origReqdBrFixups + +#if EMIT_DEBUG_INFO + let rootScope = + { Children= newScopes + StartOffset=0 + EndOffset=newCode.Length + Locals=[| |] } #endif - member __.Constructor = typeof.GetConstructors().[0] - member __.ConstructorArguments = upcast [| |] - member __.NamedArguments = - upcast [| CustomAttributeNamedArgument(typeof.GetProperty("FilePath"), CustomAttributeTypedArgument(typeof, filePath)); - CustomAttributeNamedArgument(typeof.GetProperty("Line"), CustomAttributeTypedArgument(typeof, line)) ; - CustomAttributeNamedArgument(typeof.GetProperty("Column"), CustomAttributeTypedArgument(typeof, column)) - |] } - let mkObsoleteAttributeCustomAttributeData(message:string, isError: bool) = -#if FX_NO_CUSTOMATTRIBUTEDATA - { new IProvidedCustomAttributeData with -#else - { new CustomAttributeData() with + + (newReqdStringFixups, newExnClauses, newCode) + + // -------------------------------------------------------------------- + // ILMethodBody --> bytes + // -------------------------------------------------------------------- + let GetFieldDefTypeAsBlobIdx cenv env ty = + let bytes = emitBytesViaBuffer (fun bb -> bb.EmitByte e_IMAGE_CEE_CS_CALLCONV_FIELD + EmitType cenv env bb ty) + GetBytesAsBlobIdx cenv bytes + + let GenILMethodBody mname cenv env (il: ILMethodBody) = + let localSigs = + if cenv.generatePdb then + il.Locals |> Array.map (fun l -> + // Write a fake entry for the local signature headed by e_IMAGE_CEE_CS_CALLCONV_FIELD. This is referenced by the PDB file + ignore (FindOrAddSharedRow cenv ILTableNames.StandAloneSig (SharedRow [| Blob (GetFieldDefTypeAsBlobIdx cenv env l.Type) |])) + // Now write the type + GetTypeOfLocalAsBytes cenv env l) + else + [| |] + + let requiredStringFixups, seh, code (* , seqpoints, scopes *) = Codebuf.EmitTopCode cenv localSigs env mname il.Code + let codeSize = code.Length + let methbuf = ByteBuffer.Create (codeSize * 3) + // Do we use the tiny format? + if isEmpty il.Locals && il.MaxStack <= 8 && isEmpty seh && codeSize < 64 then + // Use Tiny format + let alignedCodeSize = align 4 (codeSize + 1) + let codePadding = (alignedCodeSize - (codeSize + 1)) + let requiredStringFixups' = (1, requiredStringFixups) + methbuf.EmitByte (byte codeSize <<< 2 ||| e_CorILMethod_TinyFormat) + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + 0x0, (requiredStringFixups', methbuf.Close()) // , seqpoints, scopes + else + // Use Fat format + let flags = + e_CorILMethod_FatFormat ||| + (if not (isEmpty seh) then e_CorILMethod_MoreSects else 0x0uy) ||| + (if il.IsZeroInit then e_CorILMethod_InitLocals else 0x0uy) + + let localToken = + if isEmpty il.Locals then 0x0 else + getUncodedToken ILTableNames.StandAloneSig + (FindOrAddSharedRow cenv ILTableNames.StandAloneSig (GetLocalSigAsStandAloneSigIdx cenv env il.Locals)) + + let alignedCodeSize = align 0x4 codeSize + let codePadding = (alignedCodeSize - codeSize) + + methbuf.EmitByte flags + methbuf.EmitByte 0x30uy // last four bits record size of fat header in 4 byte chunks - this is always 12 bytes = 3 four word chunks + methbuf.EmitUInt16 (uint16 il.MaxStack) + methbuf.EmitInt32 codeSize + methbuf.EmitInt32 localToken + methbuf.EmitBytes code + methbuf.EmitPadding codePadding + + if not (isEmpty seh) then + // Can we use the small exception handling table format? + let smallSize = (seh.Length * 12 + 4) + let canUseSmall = + smallSize <= 0xFF && + seh |> Array.forall (fun (st1, sz1, st2, sz2, _) -> + st1 <= 0xFFFF && st2 <= 0xFFFF && sz1 <= 0xFF && sz2 <= 0xFF) + + let kindAsInt32 k = + match k with + | FinallyClause -> e_COR_ILEXCEPTION_CLAUSE_FINALLY + | FaultClause -> e_COR_ILEXCEPTION_CLAUSE_FAULT + | FilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_FILTER + | TypeFilterClause _ -> e_COR_ILEXCEPTION_CLAUSE_EXCEPTION + let kindAsExtraInt32 k = + match k with + | FinallyClause | FaultClause -> 0x0 + | FilterClause i -> i + | TypeFilterClause uncoded -> uncoded + + if canUseSmall then + methbuf.EmitByte e_CorILMethod_Sect_EHTable + methbuf.EmitByte (b0 smallSize |> byte) + methbuf.EmitByte 0x00uy + methbuf.EmitByte 0x00uy + seh |> Array.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32AsUInt16 k32 + methbuf.EmitInt32AsUInt16 st1 + methbuf.EmitByte (b0 sz1 |> byte) + methbuf.EmitInt32AsUInt16 st2 + methbuf.EmitByte (b0 sz2 |> byte) + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + else + let bigSize = (seh.Length * 24 + 4) + methbuf.EmitByte (e_CorILMethod_Sect_EHTable ||| e_CorILMethod_Sect_FatFormat) + methbuf.EmitByte (b0 bigSize |> byte) + methbuf.EmitByte (b1 bigSize |> byte) + methbuf.EmitByte (b2 bigSize |> byte) + seh |> Array.iter (fun (st1, sz1, st2, sz2, kind) -> + let k32 = kindAsInt32 kind + methbuf.EmitInt32 k32 + methbuf.EmitInt32 st1 + methbuf.EmitInt32 sz1 + methbuf.EmitInt32 st2 + methbuf.EmitInt32 sz2 + methbuf.EmitInt32 (kindAsExtraInt32 kind)) + + let requiredStringFixups' = (12, requiredStringFixups) + + localToken, (requiredStringFixups', methbuf.Close()) //, seqpoints, scopes + + // -------------------------------------------------------------------- + // ILFieldDef --> FieldDef Row + // -------------------------------------------------------------------- + + let rec GetFieldDefAsFieldDefRow cenv env (fd: ILFieldDef) = + let flags = int fd.Attributes ||| (if (fd.LiteralValue <> None) then 0x8000 else 0x0) //||| + //(if (fd.Marshal <> None) then 0x1000 else 0x0) ||| + //(if (fd.Data <> None) then 0x0100 else 0x0) + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv fd.Name) + Blob (GetFieldDefSigAsBlobIdx cenv env fd ) |] + + and GetFieldDefSigAsBlobIdx cenv env fd = GetFieldDefTypeAsBlobIdx cenv env fd.FieldType + + and GenFieldDefPass3 cenv env fd = + let fidx = AddUnsharedRow cenv ILTableNames.Field (GetFieldDefAsFieldDefRow cenv env fd) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.FieldDef, fidx) fd.CustomAttrs +#if EMIT_FIELD_DATA + // Write FieldRVA table - fixups into data section done later + match fd.Data with + | None -> () + | Some b -> + let offs = cenv.data.Position + cenv.data.EmitBytes b + AddUnsharedRow cenv ILTableNames.FieldRVA + (UnsharedRow [| Data (offs, false); SimpleIndex (ILTableNames.Field, fidx) |]) |> ignore + // Write FieldMarshal table + match fd.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_FieldDef, fidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore +#endif + // Write Content table + match fd.LiteralValue with + | None -> () + | Some i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.FieldDef, fidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + // Write FieldLayout table + match fd.Offset with + | None -> () + | Some offset -> + AddUnsharedRow cenv ILTableNames.FieldLayout + (UnsharedRow [| ULong offset; SimpleIndex (ILTableNames.Field, fidx) |]) |> ignore + + + // -------------------------------------------------------------------- + // ILGenericParameterDef --> GenericParam Row + // -------------------------------------------------------------------- + + let rec GetGenericParamAsGenericParamRow cenv _env idx owner (gp: ILGenericParameterDef) = + let flags = + (if gp.IsCovariant then 0x0001 else 0x0000) ||| + (if gp.IsContravariant then 0x0002 else 0x0000) ||| + (if gp.HasReferenceTypeConstraint then 0x0004 else 0x0000) ||| + (if gp.HasNotNullableValueTypeConstraint then 0x0008 else 0x0000) ||| + (if gp.HasDefaultConstructorConstraint then 0x0010 else 0x0000) + + let mdVersionMajor, _ = metadataSchemaVersionSupportedByCLRVersion cenv.desiredMetadataVersion + if (mdVersionMajor = 1) then + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) + TypeDefOrRefOrSpec (TypeDefOrRefOrSpecTag.TypeDef, 0) (* empty kind field in deprecated metadata *) |] + else + SharedRow + [| UShort (uint16 idx) + UShort (uint16 flags) + TypeOrMethodDef (fst owner, snd owner) + StringE (GetStringHeapIdx cenv gp.Name) |] + + and GenTypeAsGenericParamConstraintRow cenv env gpidx ty = + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env ty + UnsharedRow + [| SimpleIndex (ILTableNames.GenericParam, gpidx) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenGenericParamConstraintPass4 cenv env gpidx ty = + AddUnsharedRow cenv ILTableNames.GenericParamConstraint (GenTypeAsGenericParamConstraintRow cenv env gpidx ty) |> ignore + + and GenGenericParamPass3 cenv env idx owner gp = + // here we just collect generic params, its constraints\custom attributes will be processed on pass4 + // shared since we look it up again below in GenGenericParamPass4 + AddSharedRow cenv ILTableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + |> ignore + + + and GenGenericParamPass4 cenv env idx owner (gp: ILGenericParameterDef) = + let gpidx = FindOrAddSharedRow cenv ILTableNames.GenericParam (GetGenericParamAsGenericParamRow cenv env idx owner gp) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.GenericParam, gpidx) gp.CustomAttrs + gp.Constraints |> Array.iter (GenGenericParamConstraintPass4 cenv env gpidx) + + // -------------------------------------------------------------------- + // param and return --> Param Row + // -------------------------------------------------------------------- + + let rec GetParamAsParamRow cenv _env seq (param: ILParameter) = + let flags = + (if param.IsIn then 0x0001 else 0x0000) ||| + (if param.IsOut then 0x0002 else 0x0000) ||| + (if param.IsOptional then 0x0010 else 0x0000) ||| + (if param.Default.HasValue then 0x1000 else 0x0000) //||| + //(if param.Marshal <> None then 0x2000 else 0x0000) + + UnsharedRow + [| UShort (uint16 flags) + UShort (uint16 seq) + StringE (GetStringHeapIdxOption cenv param.Name) |] + + and GenParamPass3 cenv env seq (param: ILParameter) = + if not param.IsIn && not param.IsOut && not param.IsOptional && param.Default.IsNone && param.Name.IsNone // && Option.isNone param.Marshal + then () + else + let pidx = AddUnsharedRow cenv ILTableNames.Param (GetParamAsParamRow cenv env seq param) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ParamDef, pidx) param.CustomAttrs +#if EMIT_FIELD_MARSHAL + // Write FieldRVA table - fixups into data section done later + match param.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow [| HasFieldMarshal (hfm_ParamDef, pidx); Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore + // Write Content table for DefaultParameterValue attr +#endif + match param.Default with + | UNone -> () + | USome i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.ParamDef, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + + let GenReturnAsParamRow (returnv: ILReturn) = + let flags = 0x0000 // || (if returnv.Marshal <> None then 0x2000 else 0x0000) + UnsharedRow + [| UShort (uint16 flags) + UShort 0us (* sequence num. *) + StringE 0 |] + + let GenReturnPass3 cenv (returnv: ILReturn) = + if (* Option.isSome returnv.Marshal || *) not (isEmpty returnv.CustomAttrs.Entries) then + let pidx = AddUnsharedRow cenv ILTableNames.Param (GenReturnAsParamRow returnv) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ParamDef, pidx) returnv.CustomAttrs +#if EMIT_MARSHAL + match returnv.Marshal with + | None -> () + | Some ntyp -> + AddUnsharedRow cenv ILTableNames.FieldMarshal + (UnsharedRow + [| HasFieldMarshal (hfm_ParamDef, pidx) + Blob (GetNativeTypeAsBlobIdx cenv ntyp) |]) |> ignore #endif - member __.Constructor = typeof.GetConstructors() |> Array.find (fun x -> x.GetParameters().Length = 2) - member __.ConstructorArguments = upcast [|CustomAttributeTypedArgument(typeof, message) ; CustomAttributeTypedArgument(typeof, isError) |] - member __.NamedArguments = upcast [| |] } - - type CustomAttributesImpl() = - let customAttributes = ResizeArray() - let mutable hideObjectMethods = false - let mutable nonNullable = false - let mutable obsoleteMessage = None - let mutable xmlDocDelayed = None - let mutable xmlDocAlwaysRecomputed = None - let mutable hasParamArray = false - - // XML doc text that we only compute once, if any. This must _not_ be forced until the ConstructorArguments - // property of the custom attribute is foced. - let xmlDocDelayedText = - lazy - (match xmlDocDelayed with None -> assert false; "" | Some f -> f()) - - // Custom atttributes that we only compute once - let customAttributesOnce = - lazy - [| if hideObjectMethods then yield mkEditorHideMethodsCustomAttributeData() - if nonNullable then yield mkAllowNullLiteralCustomAttributeData false - match xmlDocDelayed with None -> () | Some _ -> customAttributes.Add(mkXmlDocCustomAttributeDataLazy xmlDocDelayedText) - match obsoleteMessage with None -> () | Some s -> customAttributes.Add(mkObsoleteAttributeCustomAttributeData s) - if hasParamArray then yield mkParamArrayCustomAttributeData() - yield! customAttributes |] - - member __.AddDefinitionLocation(line:int,column:int,filePath:string) = customAttributes.Add(mkDefinitionLocationAttributeCustomAttributeData(line, column, filePath)) - member __.AddObsolete(message : string, isError) = obsoleteMessage <- Some (message,isError) - member __.HasParamArray with get() = hasParamArray and set(v) = hasParamArray <- v - member __.AddXmlDocComputed xmlDocFunction = xmlDocAlwaysRecomputed <- Some xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = xmlDocDelayed <- Some xmlDocFunction - member __.AddXmlDoc xmlDoc = xmlDocDelayed <- Some (fun () -> xmlDoc) - member __.HideObjectMethods with set v = hideObjectMethods <- v - member __.NonNullable with set v = nonNullable <- v - member __.AddCustomAttribute(attribute) = customAttributes.Add(attribute) - member __.GetCustomAttributesData() = - [| yield! customAttributesOnce.Force() - match xmlDocAlwaysRecomputed with None -> () | Some f -> customAttributes.Add(mkXmlDocCustomAttributeData (f())) |] - :> IList<_> - - - let adjustTypeAttributes attributes isNested = - let visibilityAttributes = - match attributes &&& TypeAttributes.VisibilityMask with - | TypeAttributes.Public when isNested -> TypeAttributes.NestedPublic - | TypeAttributes.NotPublic when isNested -> TypeAttributes.NestedAssembly - | TypeAttributes.NestedPublic when not isNested -> TypeAttributes.Public - | TypeAttributes.NestedAssembly - | TypeAttributes.NestedPrivate - | TypeAttributes.NestedFamORAssem - | TypeAttributes.NestedFamily - | TypeAttributes.NestedFamANDAssem when not isNested -> TypeAttributes.NotPublic - | a -> a - (attributes &&& ~~~TypeAttributes.VisibilityMask) ||| visibilityAttributes + // -------------------------------------------------------------------- + // ILMethodDef --> ILMethodDef Row + // -------------------------------------------------------------------- + + let GetMethodDefSigAsBytes cenv env (mdef: ILMethodDef) = + emitBytesViaBuffer (fun bb -> + bb.EmitByte (callconvToByte mdef.GenericParams.Length mdef.CallingConv) + if mdef.GenericParams.Length > 0 then bb.EmitZ32 mdef.GenericParams.Length + bb.EmitZ32 mdef.Parameters.Length + EmitType cenv env bb mdef.Return.Type + mdef.ParameterTypes |> Array.iter (EmitType cenv env bb)) + + let GenMethodDefSigAsBlobIdx cenv env mdef = + GetBytesAsBlobIdx cenv (GetMethodDefSigAsBytes cenv env mdef) + + let GenMethodDefAsRow cenv env midx (md: ILMethodDef) = + let flags = int md.Attributes + let implflags = int md.ImplAttributes + + if md.IsEntryPoint then + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (true, midx) + let codeAddr = + (match md.Body with + | Some ilmbody -> + let addr = cenv.nextCodeAddr + let (localToken, code (* , seqpoints, rootScope *) ) = GenILMethodBody md.Name cenv env ilmbody + +#if EMIT_DEBUG_INFO + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken=getUncodedToken ILTableNames.Method midx + MethName=md.Name + LocalSignatureToken=localToken + Params= [| |] (* REVIEW *) + RootScope = Some rootScope + Range= + match ilmbody.SourceMarker with + | Some m when cenv.generatePdb -> + // table indexes are 1-based, document array indexes are 0-based + let doc = (cenv.documents.FindOrAddSharedEntry m.Document) - 1 + + Some ({ Document=doc + Line=m.Line + Column=m.Column }, + { Document=doc + Line=m.EndLine + Column=m.EndColumn }) + | _ -> None + SequencePoints=seqpoints } +#endif - -type ProvidedStaticParameter(parameterName:string,parameterType:Type,?parameterDefaultValue:obj) = - inherit System.Reflection.ParameterInfo() - - let customAttributesImpl = CustomAttributesImpl() - - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - - override __.RawDefaultValue = defaultArg parameterDefaultValue null - override __.Attributes = if parameterDefaultValue.IsNone then enum 0 else ParameterAttributes.Optional - override __.Position = 0 - override __.ParameterType = parameterType - override __.Name = parameterName - - override __.GetCustomAttributes(_inherit) = ignore(_inherit); notRequired "GetCustomAttributes" parameterName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" parameterName - -type ProvidedParameter(name:string,parameterType:Type,?isOut:bool,?optionalValue:obj) = - inherit System.Reflection.ParameterInfo() - let customAttributesImpl = CustomAttributesImpl() - let isOut = defaultArg isOut false - member __.IsParamArray with get() = customAttributesImpl.HasParamArray and set(v) = customAttributesImpl.HasParamArray <- v - override __.Name = name - override __.ParameterType = parameterType - override __.Attributes = (base.Attributes ||| (if isOut then ParameterAttributes.Out else enum 0) - ||| (match optionalValue with None -> enum 0 | Some _ -> ParameterAttributes.Optional ||| ParameterAttributes.HasDefault)) - override __.RawDefaultValue = defaultArg optionalValue null - member __.HasDefaultParameterValue = Option.isSome optionalValue - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + cenv.AddCode code + addr +#if EMIT_DEBUG_INFO + | MethodBody.Abstract -> + // Now record the PDB record for this method - we write this out later. + if cenv.generatePdb then + cenv.pdbinfo.Add + { MethToken = getUncodedToken ILTableNames.Method midx + MethName = md.Name + LocalSignatureToken = 0x0 // No locals it's abstract + Params = [| |] + RootScope = None + Range = None + SequencePoints = [| |] } + 0x0000 + | MethodBody.Native -> + failwith "cannot write body of native method - Abstract IL cannot roundtrip mixed native/managed binaries" +#endif + | _ -> 0x0000) + + UnsharedRow + [| ULong codeAddr + UShort (uint16 implflags) + UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + Blob (GenMethodDefSigAsBlobIdx cenv env md) + SimpleIndex(ILTableNames.Param, cenv.GetTable(ILTableNames.Param).Count + 1) |] + + let GenMethodImplPass3 cenv env _tgparams tidx mimpl = + let midxTag, midxRow = GetMethodSpecAsMethodDef cenv env (mimpl.OverrideBy, None) + let midx2Tag, midx2Row = GetOverridesSpecAsMethodDefOrRef cenv env mimpl.Overrides + AddUnsharedRow cenv ILTableNames.MethodImpl + (UnsharedRow + [| SimpleIndex (ILTableNames.TypeDef, tidx) + MethodDefOrRef (midxTag, midxRow) + MethodDefOrRef (midx2Tag, midx2Row) |]) |> ignore + + let GenMethodDefPass3 cenv env (md:ILMethodDef) = + let midx = GetMethodDefIdx cenv md + let idx2 = AddUnsharedRow cenv ILTableNames.Method (GenMethodDefAsRow cenv env midx md) + if midx <> idx2 then failwith "index of method def on pass 3 does not match index on pass 2" + GenReturnPass3 cenv md.Return + md.Parameters |> Array.iteri (fun n param -> GenParamPass3 cenv env (n+1) param) + md.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.MethodDef, midx) +#if EMIT_SECURITY_DECLS + md.SecurityDecls.Entries |> GenSecurityDeclsPass3 cenv (hds_MethodDef, midx) +#endif + md.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass3 cenv env n (TypeOrMethodDefTag.MethodDef, midx) gp) +#if EMIT_PINVOKE + match md.Body.Contents with + | MethodBody.PInvoke attr -> + let flags = + begin match attr.CallingConv with + | PInvokeCallingConvention.None -> 0x0000 + | PInvokeCallingConvention.Cdecl -> 0x0200 + | PInvokeCallingConvention.Stdcall -> 0x0300 + | PInvokeCallingConvention.Thiscall -> 0x0400 + | PInvokeCallingConvention.Fastcall -> 0x0500 + | PInvokeCallingConvention.WinApi -> 0x0100 + end ||| + begin match attr.CharEncoding with + | PInvokeCharEncoding.None -> 0x0000 + | PInvokeCharEncoding.Ansi -> 0x0002 + | PInvokeCharEncoding.Unicode -> 0x0004 + | PInvokeCharEncoding.Auto -> 0x0006 + end ||| + begin match attr.CharBestFit with + | PInvokeCharBestFit.UseAssembly -> 0x0000 + | PInvokeCharBestFit.Enabled -> 0x0010 + | PInvokeCharBestFit.Disabled -> 0x0020 + end ||| + begin match attr.ThrowOnUnmappableChar with + | PInvokeThrowOnUnmappableChar.UseAssembly -> 0x0000 + | PInvokeThrowOnUnmappableChar.Enabled -> 0x1000 + | PInvokeThrowOnUnmappableChar.Disabled -> 0x2000 + end ||| + (if attr.NoMangle then 0x0001 else 0x0000) ||| + (if attr.LastError then 0x0040 else 0x0000) + AddUnsharedRow cenv ILTableNames.ImplMap + (UnsharedRow + [| UShort (uint16 flags) + MemberForwarded (mf_MethodDef, midx) + StringE (GetStringHeapIdx cenv attr.Name) + SimpleIndex (ILTableNames.ModuleRef, GetModuleRefAsIdx cenv attr.Where) |]) |> ignore + | _ -> () #endif -type ProvidedConstructor(parameters : ProvidedParameter list) = - inherit ConstructorInfo() - let parameters = parameters |> List.map (fun p -> p :> ParameterInfo) - let mutable baseCall = None - - let mutable declaringType = null : System.Type - let mutable invokeCode = None : option Expr> - let mutable isImplicitCtor = false - let mutable ctorAttributes = MethodAttributes.Public ||| MethodAttributes.RTSpecialName - let nameText () = sprintf "constructor for %s" (if declaringType=null then "" else declaringType.FullName) - let isStatic() = ctorAttributes.HasFlag(MethodAttributes.Static) - - let customAttributesImpl = CustomAttributesImpl() - member __.IsTypeInitializer - with get() = isStatic() && ctorAttributes.HasFlag(MethodAttributes.Private) - and set(v) = - let typeInitializerAttributes = MethodAttributes.Static ||| MethodAttributes.Private - ctorAttributes <- if v then ctorAttributes ||| typeInitializerAttributes else ctorAttributes &&& ~~~typeInitializerAttributes - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + let GenMethodDefPass4 cenv env md = + let midx = GetMethodDefIdx cenv md + md.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass4 cenv env n (TypeOrMethodDefTag.MethodDef, midx) gp) + + let GenPropertyMethodSemanticsPass3 cenv pidx kind mref = + // REVIEW: why are we catching exceptions here? + let midx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv ILTableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (ILTableNames.Method, midx) + HasSemantics (HasSemanticsTag.Property, pidx) |]) |> ignore + + let rec GetPropertySigAsBlobIdx cenv env prop = + GetBytesAsBlobIdx cenv (GetPropertySigAsBytes cenv env prop) + + and GetPropertySigAsBytes cenv env prop = + emitBytesViaBuffer (fun bb -> + let b = ((hasthisToByte prop.CallingConv) ||| e_IMAGE_CEE_CS_CALLCONV_PROPERTY) + bb.EmitByte b + bb.EmitZ32 prop.IndexParameterTypes.Length + EmitType cenv env bb prop.PropertyType + prop.IndexParameterTypes |> Array.iter (EmitType cenv env bb)) + + and GetPropertyAsPropertyRow cenv env (prop:ILPropertyDef) = + let flags = + (if prop.IsSpecialName then 0x0200 else 0x0) ||| + (if prop.IsRTSpecialName then 0x0400 else 0x0) ||| + (if prop.Init <> None then 0x1000 else 0x0) + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv prop.Name) + Blob (GetPropertySigAsBlobIdx cenv env prop) |] + + /// ILPropertyDef --> Property Row + MethodSemantics entries + and GenPropertyPass3 cenv env prop = + let pidx = AddUnsharedRow cenv ILTableNames.Property (GetPropertyAsPropertyRow cenv env prop) + prop.SetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0001) + prop.GetMethod |> Option.iter (GenPropertyMethodSemanticsPass3 cenv pidx 0x0002) + // Write Constant table + match prop.Init with + | None -> () + | Some i -> + AddUnsharedRow cenv ILTableNames.Constant + (UnsharedRow + [| GetFieldInitFlags i + HasConstant (HasConstantTag.Property, pidx) + Blob (GetFieldInitAsBlobIdx cenv i) |]) |> ignore + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Property, pidx) prop.CustomAttrs + + let rec GenEventMethodSemanticsPass3 cenv eidx kind mref = + let addIdx = try GetMethodRefAsMethodDefIdx cenv mref with MethodDefNotFound -> 1 + AddUnsharedRow cenv ILTableNames.MethodSemantics + (UnsharedRow + [| UShort (uint16 kind) + SimpleIndex (ILTableNames.Method, addIdx) + HasSemantics (HasSemanticsTag.Event, eidx) |]) |> ignore + + /// ILEventDef --> Event Row + MethodSemantics entries + and GenEventAsEventRow cenv env (md: ILEventDef) = + let flags = + (if md.IsSpecialName then 0x0200 else 0x0) ||| + (if md.IsRTSpecialName then 0x0400 else 0x0) + let tdorTag, tdorRow = GetTypeAsTypeDefOrRef cenv env md.EventHandlerType + UnsharedRow + [| UShort (uint16 flags) + StringE (GetStringHeapIdx cenv md.Name) + TypeDefOrRefOrSpec (tdorTag, tdorRow) |] + + and GenEventPass3 cenv env (md: ILEventDef) = + let eidx = AddUnsharedRow cenv ILTableNames.Event (GenEventAsEventRow cenv env md) + md.AddMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0008 + md.RemoveMethod |> GenEventMethodSemanticsPass3 cenv eidx 0x0010 + //Option.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0020) md.FireMethod + //List.iter (GenEventMethodSemanticsPass3 cenv eidx 0x0004) md.OtherMethods + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Event, eidx) md.CustomAttrs + + + // -------------------------------------------------------------------- + // resource --> generate ... + // -------------------------------------------------------------------- + + let rec GetResourceAsManifestResourceRow cenv r = + let data, impl = + match r.Location with + | ILResourceLocation.Local bf -> + let b = bf() + // Embedded managed resources must be word-aligned. However resource format is + // not specified in ECMA. Some mscorlib resources appear to be non-aligned - it seems it doesn't matter.. + let offset = cenv.resources.Position + let alignedOffset = (align 0x8 offset) + let pad = alignedOffset - offset + let resourceSize = b.Length + cenv.resources.EmitPadding pad + cenv.resources.EmitInt32 resourceSize + cenv.resources.EmitBytes b + Data (alignedOffset, true), (ImplementationTag.File, 0) + | ILResourceLocation.File (mref, offset) -> ULong offset, (ImplementationTag.File, GetModuleRefAsFileIdx cenv mref) + | ILResourceLocation.Assembly aref -> ULong 0x0, (ImplementationTag.AssemblyRef, GetAssemblyRefAsIdx cenv aref) + UnsharedRow + [| data + ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02) + StringE (GetStringHeapIdx cenv r.Name) + Implementation (fst impl, snd impl) |] + + and GenResourcePass3 cenv r = + let idx = AddUnsharedRow cenv ILTableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ManifestResource, idx) r.CustomAttrs + + // -------------------------------------------------------------------- + // ILTypeDef --> generate ILFieldDef, ILMethodDef, ILPropertyDef etc. rows + // -------------------------------------------------------------------- + + let rec GenTypeDefPass3 enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + td.Properties.Entries |> Array.iter (GenPropertyPass3 cenv env) + td.Events.Entries |> Array.iter (GenEventPass3 cenv env) + td.Fields.Entries |> Array.iter (GenFieldDefPass3 cenv env) + td.Methods.Entries |> Array.iter (GenMethodDefPass3 cenv env) + td.MethodImpls.Entries |> Array.iter (GenMethodImplPass3 cenv env td.GenericParams.Length tidx) + // ClassLayout entry if needed + match td.Layout with + | ILTypeDefLayout.Auto -> () + | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> + if Option.isSome layout.Pack || Option.isSome layout.Size then + AddUnsharedRow cenv ILTableNames.ClassLayout + (UnsharedRow + [| UShort (defaultArg layout.Pack (uint16 0x0)) + ULong (defaultArg layout.Size 0x0) + SimpleIndex (ILTableNames.TypeDef, tidx) |]) |> ignore + +#if EMIT_SECURITY_DECLS + td.SecurityDecls.Entries |> GenSecurityDeclsPass3 cenv (hds_TypeDef, tidx) +#endif + td.CustomAttrs |> GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.TypeDef, tidx) + td.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass3 cenv env n (TypeOrMethodDefTag.TypeDef, tidx) gp) + td.NestedTypes.Entries |> GenTypeDefsPass3 (addILTypeName enc td) cenv + with e -> + failwith ("Error in pass3 for type "+td.Name+", error: "+e.Message) + reraise() + raise e + + and GenTypeDefsPass3 enc cenv tds = + Array.iter (GenTypeDefPass3 enc cenv) tds + + /// ILTypeDef --> generate generic params on ILMethodDef: ensures + /// GenericParam table is built sorted by owner. + + let rec GenTypeDefPass4 enc cenv (td:ILTypeDef) = + try + let env = envForTypeDef td + let tidx = GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + td.Methods.Entries |> Array.iter (GenMethodDefPass4 cenv env) + td.GenericParams |> Array.iteri (fun n gp -> GenGenericParamPass4 cenv env n (TypeOrMethodDefTag.TypeDef, tidx) gp) + GenTypeDefsPass4 (addILTypeName enc td) cenv td.NestedTypes.Entries + with e -> + failwith ("Error in pass4 for type "+td.Name+", error: "+e.Message) + reraise() + raise e + + and GenTypeDefsPass4 enc cenv tds = + Array.iter (GenTypeDefPass4 enc cenv) tds + + + let DateTime1970Jan01 = new System.DateTime(1970,1,1,0,0,0,System.DateTimeKind.Utc) (* ECMA Spec (Oct2002), Part II, 24.2.2 PE File Header. *) + let timestamp = (System.DateTime.UtcNow - DateTime1970Jan01).TotalSeconds |> int + + // -------------------------------------------------------------------- + // ILExportedTypesAndForwarders --> ILExportedTypeOrForwarder table + // -------------------------------------------------------------------- + + let rec GenNestedExportedTypePass3 cenv cidx (ce: ILNestedExportedType) = + let flags = GetMemberAccessFlags ce.Access + let nidx = + AddUnsharedRow cenv ILTableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + StringE (GetStringHeapIdx cenv ce.Name) + StringE 0 + Implementation (ImplementationTag.ExportedType, cidx) |]) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, nidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv nidx ce.Nested + + and GenNestedExportedTypesPass3 cenv nidx (nce: ILNestedExportedTypesAndForwarders) = + nce.Entries |> Array.iter (GenNestedExportedTypePass3 cenv nidx) + + and GenExportedTypePass3 cenv (ce: ILExportedTypeOrForwarder) = + let nselem, nelem = GetTypeNameAsElemPair cenv (ce.Namespace, ce.Name) + let flags = GetTypeAccessFlags ce.Access + let flags = if ce.IsForwarder then 0x00200000 ||| flags else flags + let impl = GetScopeRefAsImplementationElem cenv ce.ScopeRef + let cidx = + AddUnsharedRow cenv ILTableNames.ExportedType + (UnsharedRow + [| ULong flags + ULong 0x0 + nelem + nselem + Implementation (fst impl, snd impl) |]) + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, cidx) ce.CustomAttrs + GenNestedExportedTypesPass3 cenv cidx ce.Nested + + + + // -------------------------------------------------------------------- + // manifest --> generate Assembly row + // -------------------------------------------------------------------- + + and GetManifsetAsAssemblyRow cenv m = + UnsharedRow + [|ULong m.AuxModuleHashAlgorithm + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Major) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Minor) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Build) + UShort (match m.Version with UNone -> 0us | USome v -> uint16 v.Revision) + ULong + ( //(match m.AssemblyLongevity with + //| ILAssemblyLongevity.Unspecified -> 0x0000 + //| ILAssemblyLongevity.Library -> 0x0002 + //| ILAssemblyLongevity.PlatformAppDomain -> 0x0004 + // | ILAssemblyLongevity.PlatformProcess -> 0x0006 + // | ILAssemblyLongevity.PlatformSystem -> 0x0008) ||| + (if m.Retargetable then 0x100 else 0x0) ||| + // Setting these causes peverify errors. Hence both ilread and ilwrite ignore them and refuse to set them. + // Any debugging customattributes will automatically propagate + // REVIEW: No longer appears to be the case + (if m.JitTracking then 0x8000 else 0x0) ||| + (match m.PublicKey with UNone -> 0x0000 | USome _ -> 0x0001) ||| 0x0000) + (match m.PublicKey with UNone -> Blob 0 | USome x -> Blob (GetBytesAsBlobIdx cenv x)) + StringE (GetStringHeapIdx cenv m.Name) + (match m.Locale with UNone -> StringE 0 | USome x -> StringE (GetStringHeapIdx cenv x)) |] + + and GenManifestPass3 cenv m = + let aidx = AddUnsharedRow cenv ILTableNames.Assembly (GetManifsetAsAssemblyRow cenv m) +#if EMIT_SECURITY_DECLS + GenSecurityDeclsPass3 cenv (hds_Assembly, aidx) m.SecurityDecls.Entries #endif + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Assembly, aidx) m.CustomAttrs + m.ExportedTypes.Entries |> Array.iter (GenExportedTypePass3 cenv) + // Record the entrypoint decl if needed. + match m.EntrypointElsewhere with + | Some mref -> + if cenv.entrypoint <> None then failwith "duplicate entrypoint" + else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) + | None -> () - member __.DeclaringTypeImpl - with set x = - if declaringType<>null then failwith (sprintf "ProvidedConstructor: declaringType already set on '%s'" (nameText())); - declaringType <- x - - member __.InvokeCode - with set (q:Expr list -> Expr) = - match invokeCode with - | None -> invokeCode <- Some q - | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for '%s'" (nameText())) - - member __.BaseConstructorCall - with set (d:Expr list -> (ConstructorInfo * Expr list)) = - match baseCall with - | None -> baseCall <- Some d - | Some _ -> failwith (sprintf "ProvidedConstructor: base call already given for '%s'" (nameText())) - - member __.GetInvokeCodeInternal isGenerated = - match invokeCode with - | Some f -> - // FSharp.Data change: use the real variable names instead of indices, to improve output of Debug.fs - let paramNames = - parameters - |> List.map (fun p -> p.Name) - |> List.append (if not isGenerated || isStatic() then [] else ["this"]) + and newGuid (modul: ILModuleDef) = + let n = timestamp + let m = hash n + let m2 = hash modul.Name + [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + + and deterministicGuid (modul: ILModuleDef) = + let n = 16909060 + let m = hash n + let m2 = hash modul.Name + [| b0 m; b1 m; b2 m; b3 m; b0 m2; b1 m2; b2 m2; b3 m2; 0xa7uy; 0x45uy; 0x03uy; 0x83uy; b0 n; b1 n; b2 n; b3 n |] + + and GetModuleAsRow (cenv:cenv) (modul: ILModuleDef) = + // Store the generated MVID in the environment (needed for generating debug information) + let modulGuid = if cenv.deterministic then deterministicGuid modul else newGuid modul + cenv.moduleGuid <- modulGuid + UnsharedRow + [| UShort (uint16 0x0) + StringE (GetStringHeapIdx cenv modul.Name) + Guid (GetGuidIdx cenv modulGuid) + Guid 0 + Guid 0 |] + + + let rowElemCompare (e1: RowElement) (e2: RowElement) = + let c = compare e1.Val e2.Val + if c <> 0 then c else + compare e1.Tag e2.Tag + + module List = + let rec assoc x l = + match l with + | [] -> failwith "index not found" + | ((h,r)::t) -> if x = h then r else assoc x t + + let rec memAssoc x l = + match l with + | [] -> false + | ((h,_)::t) -> x = h || memAssoc x t + + let TableRequiresSorting tab = + List.memAssoc tab ILTableNames.sortedTableInfo + + let SortTableRows tab (rows:GenericRow[]) = + assert (TableRequiresSorting tab) + let col = List.assoc tab ILTableNames.sortedTableInfo + rows + // This needs to be a stable sort, so we use List.sortWith + |> Array.toList + |> List.sortWith (fun r1 r2 -> rowElemCompare r1.[col] r2.[col]) |> Array.ofList - QuotationSimplifier.transQuotationToCode isGenerated f paramNames - | None -> failwith (sprintf "ProvidedConstructor: no invoker for '%s'" (nameText())) - - member __.GetBaseConstructorCallInternal isGenerated = - match baseCall with - | Some f -> Some(fun ctorArgs -> let c,baseCtorArgExprs = f ctorArgs in c, List.map (QuotationSimplifier.transExpr isGenerated) baseCtorArgExprs) - | None -> None - member __.IsImplicitCtor with get() = isImplicitCtor and set v = isImplicitCtor <- v - - // Implement overloads - override __.GetParameters() = parameters |> List.toArray - override __.Attributes = ctorAttributes - override __.Name = if isStatic() then ".cctor" else ".ctor" - override __.DeclaringType = declaringType |> nonNull "ProvidedConstructor.DeclaringType" - override __.IsDefined(_attributeType, _inherit) = true - - override __.Invoke(_invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" (nameText()) - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" (nameText()) - override __.ReflectedType = notRequired "ReflectedType" (nameText()) - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" (nameText()) - override __.MethodHandle = notRequired "MethodHandle" (nameText()) - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" (nameText()) - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" (nameText()) - -type ProvidedMethod(methodName: string, parameters: ProvidedParameter list, returnType: Type) = - inherit System.Reflection.MethodInfo() - let argParams = parameters |> List.map (fun p -> p :> ParameterInfo) - - // State - let mutable declaringType : Type = null - let mutable methodAttrs = MethodAttributes.Public - let mutable invokeCode = None : option Expr> - let mutable staticParams = [ ] - let mutable staticParamsApply = None - let isStatic() = methodAttrs.HasFlag(MethodAttributes.Static) - let customAttributesImpl = CustomAttributesImpl() - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.AddCustomAttribute(attribute) = customAttributesImpl.AddCustomAttribute(attribute) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA + //|> Array.map SharedRow + + + let mkILSimpleClass (ilg: ILGlobals) (nsp, nm, methods, fields, nestedTypes, props, events, attrs) = + { Namespace=nsp + Name=nm + GenericParams= [| |] + Implements = [| |] + Attributes = TypeAttributes.Class ||| TypeAttributes.BeforeFieldInit ||| TypeAttributes.Public + Layout=ILTypeDefLayout.Auto + Extends = Some ilg.typ_Object + Methods= methods + Fields= fields + NestedTypes=nestedTypes + CustomAttrs=attrs + MethodImpls=emptyILMethodImpls + Properties=props + Events=events + Token=0 + //SecurityDecls=emptyILSecurityDecls; + //HasSecurity=false; + } + let mkILTypeDefForGlobalFunctions ilg (methods,fields) = + mkILSimpleClass ilg (UNone, typeNameForGlobalFunctions, methods, fields, emptyILTypeDefs, emptyILProperties, emptyILEvents, emptyILCustomAttrs) + + let destTypeDefsWithGlobalFunctionsFirst ilg (tdefs: ILTypeDefs) = + let l = tdefs.Entries + let top,nontop = l |> Array.partition (fun td -> td.Name = typeNameForGlobalFunctions) + let top2 = if isEmpty top then [| mkILTypeDefForGlobalFunctions ilg (emptyILMethods, emptyILFields) |] else top + Array.append top2 nontop + + let GenModule (cenv: cenv) (modul: ILModuleDef) = + let midx = AddUnsharedRow cenv ILTableNames.Module (GetModuleAsRow cenv modul) + Array.iter (GenResourcePass3 cenv) modul.Resources.Entries + let tds = destTypeDefsWithGlobalFunctionsFirst cenv.ilg modul.TypeDefs + GenTypeDefsPass1 [] cenv tds + GenTypeDefsPass2 0 [] cenv tds + (match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m) + GenTypeDefsPass3 [] cenv tds + GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.Module, midx) modul.CustomAttrs + // GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes). + // Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params. + // Note this mutates the rows in a table. 'SetRowsOfTable' clears + // the key --> index map since it is no longer valid + cenv.GetTable(ILTableNames.GenericParam).SetRowsOfSharedTable (SortTableRows ILTableNames.GenericParam (cenv.GetTable(ILTableNames.GenericParam).GenericRowsOfTable)) + GenTypeDefsPass4 [] cenv tds + + let generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg: ILGlobals, emitTailcalls, deterministic, showTimes) (m: ILModuleDef) cilStartAddress = + let isDll = m.IsDLL + + let cenv = + { emitTailcalls=emitTailcalls + deterministic = deterministic + showTimes=showTimes + ilg = ilg + desiredMetadataVersion=desiredMetadataVersion + requiredDataFixups= requiredDataFixups + requiredStringFixups = ResizeArray() + codeChunks=ByteBuffer.Create 40000 + nextCodeAddr = cilStartAddress + data = ByteBuffer.Create 200 + resources = ByteBuffer.Create 200 + tables= + Array.init 64 (fun i -> + if (i = ILTableNames.AssemblyRef.Index || + i = ILTableNames.MemberRef.Index || + i = ILTableNames.ModuleRef.Index || + i = ILTableNames.File.Index || + i = ILTableNames.TypeRef.Index || + i = ILTableNames.TypeSpec.Index || + i = ILTableNames.MethodSpec.Index || + i = ILTableNames.StandAloneSig.Index || + i = ILTableNames.GenericParam.Index) then + MetadataTable.Shared (MetadataTable.New ("row table "+string i, EqualityComparer.Default)) + else + MetadataTable.Unshared (MetadataTable.New ("row table "+string i, EqualityComparer.Default))) + + AssemblyRefs = MetadataTable<_>.New("ILAssemblyRef", EqualityComparer.Default) + //documents=MetadataTable<_>.New("pdbdocs", EqualityComparer.Default) + trefCache=new Dictionary<_, _>(100) +#if EMIT_DEBUG_INFO + pdbinfo= new ResizeArray<_>(200) +#endif + moduleGuid= Array.zeroCreate 16 + fieldDefs= MetadataTable<_>.New("field defs", EqualityComparer.Default) + methodDefIdxsByKey = MetadataTable<_>.New("method defs", EqualityComparer.Default) + // This uses reference identity on ILMethodDef objects + methodDefIdxs = new Dictionary<_, _>(100, HashIdentity.Reference) + propertyDefs = MetadataTable<_>.New("property defs", EqualityComparer.Default) + eventDefs = MetadataTable<_>.New("event defs", EqualityComparer.Default) + typeDefs = MetadataTable<_>.New("type defs", EqualityComparer.Default) + entrypoint=None + generatePdb=generatePdb + // These must use structural comparison since they are keyed by arrays + guids=MetadataTable<_>.New("guids", HashIdentity.Structural) + blobs= MetadataTable<_>.New("blobs", HashIdentity.Structural) + strings= MetadataTable<_>.New("strings", EqualityComparer.Default) + userStrings= MetadataTable<_>.New("user strings", EqualityComparer.Default) } + + // Now the main compilation step + GenModule cenv m + + // .exe files have a .entrypoint instruction. Do not write it to the entrypoint when writing dll. + let entryPointToken = + match cenv.entrypoint with + | Some (epHere, tok) -> + if isDll then 0x0 + else getUncodedToken (if epHere then ILTableNames.Method else ILTableNames.File) tok + | None -> + if not isDll then printfn "warning: no entrypoint specified in executable binary" + 0x0 + +#if EMIT_DEBUG_INFO + let pdbData = + { EntryPoint= (if isDll then None else Some entryPointToken) + Timestamp = timestamp + ModuleID = cenv.moduleGuid + Documents = cenv.documents.EntriesAsArray + Methods = cenv.pdbinfo.ToArray() + TableRowCounts = cenv.tables |> Seq.map(fun t -> t.Count) |> Seq.toArray } #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + let pdbData = () #endif - member __.SetMethodAttrs m = methodAttrs <- m - member __.AddMethodAttrs m = methodAttrs <- methodAttrs ||| m - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - member __.IsStaticMethod - with get() = isStatic() - and set x = if x then methodAttrs <- methodAttrs ||| MethodAttributes.Static - else methodAttrs <- methodAttrs &&& (~~~ MethodAttributes.Static) + let idxForNextedTypeDef (tds:ILTypeDef list, td:ILTypeDef) = + let enc = tds |> List.map (fun td -> td.Name) + GetIdxForTypeDef cenv (TdKey(enc, td.Namespace, td.Name)) + + let strings = Array.map Bytes.stringAsUtf8NullTerminated cenv.strings.EntriesAsArray + let userStrings = cenv.userStrings.EntriesAsArray |> Array.map Encoding.Unicode.GetBytes + let blobs = cenv.blobs.EntriesAsArray + let guids = cenv.guids.EntriesAsArray + let tables = cenv.tables + let code = cenv.GetCode() + // turn idx tbls into token maps + let mappings = + { TypeDefTokenMap = (fun t -> + getUncodedToken ILTableNames.TypeDef (idxForNextedTypeDef t)) + FieldDefTokenMap = (fun t fd -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Field (GetFieldDefAsFieldDefIdx cenv tidx fd)) + MethodDefTokenMap = (fun t md -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Method (FindMethodDefIdx cenv (GetKeyForMethodDef tidx md))) + PropertyTokenMap = (fun t pd -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Property (cenv.propertyDefs.GetTableEntry (GetKeyForPropertyDef tidx pd))) + EventTokenMap = (fun t ed -> + let tidx = idxForNextedTypeDef t + getUncodedToken ILTableNames.Event (cenv.eventDefs.GetTableEntry (EventKey (tidx, ed.Name)))) } + // New return the results + let data = cenv.data.Close() + let resources = cenv.resources.Close() + (strings, userStrings, blobs, guids, tables, entryPointToken, code, cenv.requiredStringFixups, data, resources, pdbData, mappings) + + + //===================================================================== + // TABLES+BLOBS --> PHYSICAL METADATA+BLOBS + //===================================================================== + let chunk sz next = ({addr=next; size=sz}, next + sz) + let nochunk next = ({addr= 0x0;size= 0x0; } , next) + + let count f arr = + Array.fold (fun x y -> x + f y) 0x0 arr + + let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress = + + // When we know the real RVAs of the data section we fixup the references for the FieldRVA table. + // These references are stored as offsets into the metadata we return from this function + let requiredDataFixups = ResizeArray() + + let next = cilStartAddress + + let strings, userStrings, blobs, guids, tables, entryPointToken, code, requiredStringFixups, data, resources, pdbData, mappings = + generateIL requiredDataFixups (desiredMetadataVersion, generatePdb, ilg, emitTailcalls, deterministic, showTimes) modul cilStartAddress + + let tableSize (tab: ILTableName) = tables.[tab.Index].Count + + // Now place the code + let codeSize = code.Length + let alignedCodeSize = align 0x4 codeSize + let codep, next = chunk codeSize next + let codePadding = Array.create (alignedCodeSize - codeSize) 0x0uy + let _codePaddingChunk, next = chunk codePadding.Length next + + // Now layout the chunks of metadata and IL + let metadataHeaderStartChunk, _next = chunk 0x10 next + + let numStreams = 0x05 + + let (mdtableVersionMajor, mdtableVersionMinor) = metadataSchemaVersionSupportedByCLRVersion desiredMetadataVersion + + let version = + Encoding.UTF8.GetBytes (sprintf "v%d.%d.%d" desiredMetadataVersion.Major desiredMetadataVersion.Minor desiredMetadataVersion.Build) + + + let paddedVersionLength = align 0x4 (Array.length version) + + // Most addresses after this point are measured from the MD root + // Switch to md-rooted addresses + let next = metadataHeaderStartChunk.size + let _metadataHeaderVersionChunk, next = chunk paddedVersionLength next + let _metadataHeaderEndChunk, next = chunk 0x04 next + let _tablesStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#~".Length + 0x01))) next + let _stringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Strings".Length + 0x01))) next + let _userStringsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#US".Length + 0x01))) next + let _guidsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#GUID".Length + 0x01))) next + let _blobsStreamHeaderChunk, next = chunk (0x08 + (align 4 ("#Blob".Length + 0x01))) next + + let tablesStreamStart = next + + let stringsStreamUnpaddedSize = count (fun (s:byte[]) -> s.Length) strings + 1 + let stringsStreamPaddedSize = align 4 stringsStreamUnpaddedSize + + let userStringsStreamUnpaddedSize = count (fun (s:byte[]) -> let n = s.Length + 1 in n + ByteBuffer.Z32Size n) userStrings + 1 + let userStringsStreamPaddedSize = align 4 userStringsStreamUnpaddedSize + + let guidsStreamUnpaddedSize = (Array.length guids) * 0x10 + let guidsStreamPaddedSize = align 4 guidsStreamUnpaddedSize + + let blobsStreamUnpaddedSize = count (fun (blob:byte[]) -> let n = blob.Length in n + ByteBuffer.Z32Size n) blobs + 1 + let blobsStreamPaddedSize = align 4 blobsStreamUnpaddedSize + + let guidsBig = guidsStreamPaddedSize >= 0x10000 + let stringsBig = stringsStreamPaddedSize >= 0x10000 + let blobsBig = blobsStreamPaddedSize >= 0x10000 + + // 64bit bitvector indicating which tables are in the metadata. + let (valid1, valid2), _ = + (((0, 0), 0), tables) ||> Array.fold (fun ((valid1, valid2) as valid, n) rows -> + let valid = + if rows.Count = 0 then valid else + ( (if n < 32 then valid1 ||| (1 <<< n ) else valid1), + (if n >= 32 then valid2 ||| (1 <<< (n-32)) else valid2) ) + (valid, n+1)) + + // 64bit bitvector indicating which tables are sorted. + // Constant - REVIEW: make symbolic! compute from sorted table info! + let sorted1 = 0x3301fa00 + let sorted2 = + // If there are any generic parameters in the binary we're emitting then mark that + // table as sorted, otherwise don't. This maximizes the number of assemblies we emit + // which have an ECMA-v.1. compliant set of sorted tables. + (if tableSize (ILTableNames.GenericParam) > 0 then 0x00000400 else 0x00000000) ||| + (if tableSize (ILTableNames.GenericParamConstraint) > 0 then 0x00001000 else 0x00000000) ||| + 0x00000200 + - member __.InvokeCode - with set (q:Expr list -> Expr) = - match invokeCode with - | None -> invokeCode <- Some q - | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for %s on type %s" methodName (if declaringType=null then "" else declaringType.FullName)) + let guidAddress n = (if n = 0 then 0 else (n - 1) * 0x10 + 0x01) + let stringAddressTable = + let tab = Array.create (strings.Length + 1) 0 + let pos = ref 1 + for i = 1 to strings.Length do + tab.[i] <- !pos + let s = strings.[i - 1] + pos := !pos + s.Length + tab - /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". - member __.DefineStaticParameters(staticParameters : list, apply : (string -> obj[] -> ProvidedMethod)) = - staticParams <- staticParameters - staticParamsApply <- Some apply + let stringAddress n = + if n >= Array.length stringAddressTable then failwith ("string index "+string n+" out of range") + stringAddressTable.[n] + + let userStringAddressTable = + let tab = Array.create (Array.length userStrings + 1) 0 + let pos = ref 1 + for i = 1 to Array.length userStrings do + tab.[i] <- !pos + let s = userStrings.[i - 1] + let n = s.Length + 1 + pos := !pos + n + ByteBuffer.Z32Size n + tab + + let userStringAddress n = + if n >= Array.length userStringAddressTable then failwith "userString index out of range" + userStringAddressTable.[n] + + let blobAddressTable = + let tab = Array.create (blobs.Length + 1) 0 + let pos = ref 1 + for i = 1 to blobs.Length do + tab.[i] <- !pos + let blob = blobs.[i - 1] + pos := !pos + blob.Length + ByteBuffer.Z32Size blob.Length + tab + + let blobAddress n = + if n >= blobAddressTable.Length then failwith "blob index out of range" + blobAddressTable.[n] + - /// Get ParameterInfo[] for the parametric type parameters (//s GetGenericParameters) - member __.GetStaticParameters() = [| for p in staticParams -> p :> ParameterInfo |] + let sortedTables = + Array.init 64 (fun i -> + let tab = tables.[i] + let tabName = ILTableName.FromIndex i + let rows = tab.GenericRowsOfTable + if TableRequiresSorting tabName then SortTableRows tabName rows else rows) + + + let codedTables = + + let bignessTable = Array.map (fun rows -> Array.length rows >= 0x10000) sortedTables + let bigness (tab:int32) = bignessTable.[tab] + + let codedBigness nbits tab = + (tableSize tab) >= (0x10000 >>> nbits) + + let tdorBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.TypeRef || + codedBigness 2 ILTableNames.TypeSpec + + let tomdBigness = + codedBigness 1 ILTableNames.TypeDef || + codedBigness 1 ILTableNames.Method + + let hcBigness = + codedBigness 2 ILTableNames.Field || + codedBigness 2 ILTableNames.Param || + codedBigness 2 ILTableNames.Property + + let hcaBigness = + codedBigness 5 ILTableNames.Method || + codedBigness 5 ILTableNames.Field || + codedBigness 5 ILTableNames.TypeRef || + codedBigness 5 ILTableNames.TypeDef || + codedBigness 5 ILTableNames.Param || + codedBigness 5 ILTableNames.InterfaceImpl || + codedBigness 5 ILTableNames.MemberRef || + codedBigness 5 ILTableNames.Module || + codedBigness 5 ILTableNames.Permission || + codedBigness 5 ILTableNames.Property || + codedBigness 5 ILTableNames.Event || + codedBigness 5 ILTableNames.StandAloneSig || + codedBigness 5 ILTableNames.ModuleRef || + codedBigness 5 ILTableNames.TypeSpec || + codedBigness 5 ILTableNames.Assembly || + codedBigness 5 ILTableNames.AssemblyRef || + codedBigness 5 ILTableNames.File || + codedBigness 5 ILTableNames.ExportedType || + codedBigness 5 ILTableNames.ManifestResource || + codedBigness 5 ILTableNames.GenericParam || + codedBigness 5 ILTableNames.GenericParamConstraint || + codedBigness 5 ILTableNames.MethodSpec - /// Instantiate parametrics type - member __.ApplyStaticArguments(mangledName:string, args:obj[]) = - if staticParams.Length>0 then - if staticParams.Length <> args.Length then - failwith (sprintf "ProvidedTypeDefinition: expecting %d static parameters but given %d for method %s" staticParams.Length args.Length methodName) - match staticParamsApply with - | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" - | Some f -> f mangledName args - else - failwith (sprintf "ProvidedTypeDefinition: static parameters supplied but not expected for method %s" methodName) - - member __.GetInvokeCodeInternal isGenerated = - match invokeCode with - | Some f -> - // FSharp.Data change: use the real variable names instead of indices, to improve output of Debug.fs - let paramNames = - parameters - |> List.map (fun p -> p.Name) - |> List.append (if isStatic() then [] else ["this"]) - |> Array.ofList - QuotationSimplifier.transQuotationToCode isGenerated f paramNames - | None -> failwith (sprintf "ProvidedMethod: no invoker for %s on type %s" methodName (if declaringType=null then "" else declaringType.FullName)) - - // Implement overloads - override __.GetParameters() = argParams |> Array.ofList - override __.Attributes = methodAttrs - override __.Name = methodName - override __.DeclaringType = declaringType |> nonNull "ProvidedMethod.DeclaringType" - override __.IsDefined(_attributeType, _inherit) : bool = true - override __.MemberType = MemberTypes.Method - override __.CallingConvention = - let cc = CallingConventions.Standard - let cc = if not (isStatic()) then cc ||| CallingConventions.HasThis else cc - cc - override __.ReturnType = returnType - override __.ReturnParameter = null // REVIEW: Give it a name and type? - override __.ToString() = "Method " + methodName - - // These don't have to return fully accurate results - they are used - // by the F# Quotations library function SpecificCall as a pre-optimization - // when comparing methods - override __.MetadataToken = hash declaringType + hash methodName - override __.MethodHandle = RuntimeMethodHandle() - - override __.ReturnTypeCustomAttributes = notRequired "ReturnTypeCustomAttributes" methodName - override __.GetBaseDefinition() = notRequired "GetBaseDefinition" methodName - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" methodName - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" methodName - override __.ReflectedType = notRequired "ReflectedType" methodName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" methodName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" methodName - - -type ProvidedProperty(propertyName: string, propertyType: Type, ?parameters: ProvidedParameter list) = - inherit System.Reflection.PropertyInfo() - // State - - let parameters = defaultArg parameters [] - let mutable declaringType = null - let mutable isStatic = false - let mutable getterCode = None : option Expr> - let mutable setterCode = None : option Expr> - - let hasGetter() = getterCode.IsSome - let hasSetter() = setterCode.IsSome - - // Delay construction - to pick up the latest isStatic - let markSpecialName (m:ProvidedMethod) = m.AddMethodAttrs(MethodAttributes.SpecialName); m - let getter = lazy (ProvidedMethod("get_" + propertyName,parameters,propertyType,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=getterCode.Value) |> markSpecialName) - let setter = lazy (ProvidedMethod("set_" + propertyName,parameters @ [ProvidedParameter("value",propertyType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=setterCode.Value) |> markSpecialName) - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() - member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute -#if FX_NO_CUSTOMATTRIBUTEDATA + + let hfmBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Param + + let hdsBigness = + codedBigness 2 ILTableNames.TypeDef || + codedBigness 2 ILTableNames.Method || + codedBigness 2 ILTableNames.Assembly + + let mrpBigness = + codedBigness 3 ILTableNames.TypeRef || + codedBigness 3 ILTableNames.ModuleRef || + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.TypeSpec + + let hsBigness = + codedBigness 1 ILTableNames.Event || + codedBigness 1 ILTableNames.Property + + let mdorBigness = + codedBigness 1 ILTableNames.Method || + codedBigness 1 ILTableNames.MemberRef + + let mfBigness = + codedBigness 1 ILTableNames.Field || + codedBigness 1 ILTableNames.Method + + let iBigness = + codedBigness 2 ILTableNames.File || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.ExportedType + + let catBigness = + codedBigness 3 ILTableNames.Method || + codedBigness 3 ILTableNames.MemberRef + + let rsBigness = + codedBigness 2 ILTableNames.Module || + codedBigness 2 ILTableNames.ModuleRef || + codedBigness 2 ILTableNames.AssemblyRef || + codedBigness 2 ILTableNames.TypeRef + + let tablesBuf = ByteBuffer.Create 20000 + + // Now the coded tables themselves - first the schemata header + tablesBuf.EmitIntsAsBytes + [| 0x00; 0x00; 0x00; 0x00; + mdtableVersionMajor // major version of table schemata + mdtableVersionMinor // minor version of table schemata + + ((if stringsBig then 0x01 else 0x00) ||| // bit vector for heap size + (if guidsBig then 0x02 else 0x00) ||| + (if blobsBig then 0x04 else 0x00)) + 0x01 (* reserved, always 1 *) |] + + tablesBuf.EmitInt32 valid1 + tablesBuf.EmitInt32 valid2 + tablesBuf.EmitInt32 sorted1 + tablesBuf.EmitInt32 sorted2 + + // Numbers of rows in various tables + for rows in sortedTables do + if rows.Length <> 0 then + tablesBuf.EmitInt32 rows.Length + + + + // The tables themselves + for rows in sortedTables do + for row in rows do + for x in row do + // Emit the coded token for the array element + let t = x.Tag + let n = x.Val + match t with + | _ when t = RowElementTags.UShort -> tablesBuf.EmitUInt16 (uint16 n) + | _ when t = RowElementTags.ULong -> tablesBuf.EmitInt32 n + | _ when t = RowElementTags.Data -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, false) + | _ when t = RowElementTags.DataResources -> recordRequiredDataFixup requiredDataFixups tablesBuf (tablesStreamStart + tablesBuf.Position) (n, true) + | _ when t = RowElementTags.Guid -> tablesBuf.EmitZUntaggedIndex guidsBig (guidAddress n) + | _ when t = RowElementTags.Blob -> tablesBuf.EmitZUntaggedIndex blobsBig (blobAddress n) + | _ when t = RowElementTags.String -> tablesBuf.EmitZUntaggedIndex stringsBig (stringAddress n) + | _ when t <= RowElementTags.SimpleIndexMax -> tablesBuf.EmitZUntaggedIndex (bigness (t - RowElementTags.SimpleIndexMin)) n + | _ when t <= RowElementTags.TypeDefOrRefOrSpecMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeDefOrRefOrSpecMin) 2 tdorBigness n + | _ when t <= RowElementTags.TypeOrMethodDefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.TypeOrMethodDefMin) 1 tomdBigness n + | _ when t <= RowElementTags.HasConstantMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasConstantMin) 2 hcBigness n + | _ when t <= RowElementTags.HasCustomAttributeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasCustomAttributeMin) 5 hcaBigness n + | _ when t <= RowElementTags.HasFieldMarshalMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasFieldMarshalMin) 1 hfmBigness n + | _ when t <= RowElementTags.HasDeclSecurityMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasDeclSecurityMin) 2 hdsBigness n + | _ when t <= RowElementTags.MemberRefParentMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberRefParentMin) 3 mrpBigness n + | _ when t <= RowElementTags.HasSemanticsMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.HasSemanticsMin) 1 hsBigness n + | _ when t <= RowElementTags.MethodDefOrRefMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MethodDefOrRefMin) 1 mdorBigness n + | _ when t <= RowElementTags.MemberForwardedMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.MemberForwardedMin) 1 mfBigness n + | _ when t <= RowElementTags.ImplementationMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ImplementationMin) 2 iBigness n + | _ when t <= RowElementTags.CustomAttributeTypeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.CustomAttributeTypeMin) 3 catBigness n + | _ when t <= RowElementTags.ResolutionScopeMax -> tablesBuf.EmitZTaggedIndex (t - RowElementTags.ResolutionScopeMin) 2 rsBigness n + | _ -> failwith "invalid tag in row element" + + tablesBuf.Close() + + + let tablesStreamUnpaddedSize = codedTables.Length + // QUERY: extra 4 empty bytes in array.exe - why? Include some extra padding after + // the tables just in case there is a mistake in the ECMA spec. + let tablesStreamPaddedSize = align 4 (tablesStreamUnpaddedSize + 4) + let tablesChunk, next = chunk tablesStreamPaddedSize next + let tablesStreamPadding = tablesChunk.size - tablesStreamUnpaddedSize + + let stringsChunk, next = chunk stringsStreamPaddedSize next + let stringsStreamPadding = stringsChunk.size - stringsStreamUnpaddedSize + let userStringsChunk, next = chunk userStringsStreamPaddedSize next + let userStringsStreamPadding = userStringsChunk.size - userStringsStreamUnpaddedSize + let guidsChunk, next = chunk (0x10 * guids.Length) next + let blobsChunk, _next = chunk blobsStreamPaddedSize next + let blobsStreamPadding = blobsChunk.size - blobsStreamUnpaddedSize + + + let metadata, guidStart = + let mdbuf = ByteBuffer.Create 500000 + mdbuf.EmitIntsAsBytes + [| 0x42; 0x53; 0x4a; 0x42; // Magic signature + 0x01; 0x00; // Major version + 0x01; 0x00; // Minor version + |]; + mdbuf.EmitInt32 0x0; // Reserved + + mdbuf.EmitInt32 paddedVersionLength; + mdbuf.EmitBytes version; + for i = 1 to (paddedVersionLength - Array.length version) do + mdbuf.EmitIntAsByte 0x00; + + mdbuf.EmitBytes + [| 0x00uy; 0x00uy; // flags, reserved + b0 numStreams; b1 numStreams; |]; + mdbuf.EmitInt32 tablesChunk.addr; + mdbuf.EmitInt32 tablesChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x7e; 0x00; 0x00; (* #~00 *)|]; + mdbuf.EmitInt32 stringsChunk.addr; + mdbuf.EmitInt32 stringsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x53; 0x74; 0x72; 0x69; 0x6e; 0x67; 0x73; 0x00; 0x00; 0x00; 0x00 (* "#Strings0000" *)|]; + mdbuf.EmitInt32 userStringsChunk.addr; + mdbuf.EmitInt32 userStringsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x55; 0x53; 0x00; (* #US0*) |]; + mdbuf.EmitInt32 guidsChunk.addr; + mdbuf.EmitInt32 guidsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x47; 0x55; 0x49; 0x44; 0x00; 0x00; 0x00; (* #GUID000 *)|]; + mdbuf.EmitInt32 blobsChunk.addr; + mdbuf.EmitInt32 blobsChunk.size; + mdbuf.EmitIntsAsBytes [| 0x23; 0x42; 0x6c; 0x6f; 0x62; 0x00; 0x00; 0x00; (* #Blob000 *)|]; + + // Now the coded tables themselves + mdbuf.EmitBytes codedTables; + for i = 1 to tablesStreamPadding do + mdbuf.EmitIntAsByte 0x00; + + // The string stream + mdbuf.EmitByte 0x00uy; + for s in strings do + mdbuf.EmitBytes s; + for i = 1 to stringsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + // The user string stream + mdbuf.EmitByte 0x00uy; + for s in userStrings do + mdbuf.EmitZ32 (s.Length + 1); + mdbuf.EmitBytes s; + mdbuf.EmitIntAsByte (markerForUnicodeBytes s) + for i = 1 to userStringsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + + // The GUID stream + let guidStart = mdbuf.Position + Array.iter mdbuf.EmitBytes guids; + + // The blob stream + mdbuf.EmitByte 0x00uy; + for s in blobs do + mdbuf.EmitZ32 s.Length; + mdbuf.EmitBytes s + for i = 1 to blobsStreamPadding do + mdbuf.EmitIntAsByte 0x00; + // Done - close the buffer and return the result. + mdbuf.Close(), guidStart + + + // Now we know the user string tables etc. we can fixup the + // uses of strings in the code + for (codeStartAddr, l) in requiredStringFixups do + for (codeOffset, userStringIndex) in l do + if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then failwith "strings-in-code fixup: a group of fixups is located outside the code array"; + let locInCode = ((codeStartAddr + codeOffset) - codep.addr) + checkFixup32 code locInCode 0xdeadbeef; + let token = getUncodedToken ILTableNames.UserStrings (userStringAddress userStringIndex) + if (Bytes.get code (locInCode-1) <> i_ldstr) then failwith "strings-in-code fixup: not at ldstr instruction!"; + applyFixup32 code locInCode token + + entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups.ToArray(), pdbData, mappings, guidStart + + //--------------------------------------------------------------------- + // PHYSICAL METADATA+BLOBS --> PHYSICAL PE FORMAT + //--------------------------------------------------------------------- + + // THIS LAYS OUT A 2-SECTION .NET PE BINARY + // SECTIONS + // TEXT: physical 0x0200 --> RVA 0x00020000 + // e.g. raw size 0x9600, + // e.g. virt size 0x9584 + // RELOC: physical 0x9800 --> RVA 0x0000c000 + // i.e. physbase --> rvabase + // where physbase = textbase + text raw size + // phsrva = roundup(0x2000, 0x0002000 + text virt size) + + let msdosHeader: byte[] = + [| 0x4duy; 0x5auy; 0x90uy; 0x00uy; 0x03uy; 0x00uy; 0x00uy; 0x00uy + 0x04uy; 0x00uy; 0x00uy; 0x00uy; 0xFFuy; 0xFFuy; 0x00uy; 0x00uy + 0xb8uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x40uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy + 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy + 0x0euy; 0x1fuy; 0xbauy; 0x0euy; 0x00uy; 0xb4uy; 0x09uy; 0xcduy + 0x21uy; 0xb8uy; 0x01uy; 0x4cuy; 0xcduy; 0x21uy; 0x54uy; 0x68uy + 0x69uy; 0x73uy; 0x20uy; 0x70uy; 0x72uy; 0x6fuy; 0x67uy; 0x72uy + 0x61uy; 0x6duy; 0x20uy; 0x63uy; 0x61uy; 0x6euy; 0x6euy; 0x6fuy + 0x74uy; 0x20uy; 0x62uy; 0x65uy; 0x20uy; 0x72uy; 0x75uy; 0x6euy + 0x20uy; 0x69uy; 0x6euy; 0x20uy; 0x44uy; 0x4fuy; 0x53uy; 0x20uy + 0x6duy; 0x6fuy; 0x64uy; 0x65uy; 0x2euy; 0x0duy; 0x0duy; 0x0auy + 0x24uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] + + let writeInt64 (os: BinaryWriter) x = + os.Write (dw0 x); + os.Write (dw1 x); + os.Write (dw2 x); + os.Write (dw3 x); + os.Write (dw4 x); + os.Write (dw5 x); + os.Write (dw6 x); + os.Write (dw7 x) + + let writeInt32 (os: BinaryWriter) x = + os.Write (b0 x) + os.Write (b1 x) + os.Write (b2 x) + os.Write (b3 x) + + let writeInt32AsUInt16 (os: BinaryWriter) x = + os.Write (b0 x) + os.Write (b1 x) + + let writeDirectory os dict = + writeInt32 os (if dict.size = 0x0 then 0x0 else dict.addr); + writeInt32 os dict.size + + let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk, 0, chunk.Length) + + let writeBinaryAndReportMappings (outfile: string, + ilg: ILGlobals, pdbfile: string option, (* signer: ILStrongNameSigner option, *) portablePDB, embeddedPDB, + embedAllSource, embedSourceList, sourceLink, emitTailcalls, deterministic, showTimes, dumpDebugInfo ) modul = + let isDll = modul.IsDLL + + let os = + try + // Ensure the output directory exists otherwise it will fail + let dir = Path.GetDirectoryName(outfile) + if not (Directory.Exists(dir)) then Directory.CreateDirectory(dir) |>ignore + new BinaryWriter(System.IO.File.OpenWrite(outfile)) + with e -> + failwith ("Could not open file for writing (binary mode): " + outfile + "\n" + e.ToString()) + + let pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings = + try + + let imageBaseReal = modul.ImageBase // FIXED CHOICE + let alignVirt = modul.VirtualAlignment // FIXED CHOICE + let alignPhys = modul.PhysicalAlignment // FIXED CHOICE + + let isItanium = modul.Platform = Some(IA64) + + let numSections = 3 // .text, .sdata, .reloc + + + // HEADERS + let next = 0x0 + let headerSectionPhysLoc = 0x0 + let headerAddr = next + let next = headerAddr + + let msdosHeaderSize = 0x80 + let msdosHeaderChunk, next = chunk msdosHeaderSize next + + let peSignatureSize = 0x04 + let peSignatureChunk, next = chunk peSignatureSize next + + let peFileHeaderSize = 0x14 + let peFileHeaderChunk, next = chunk peFileHeaderSize next + + let peOptionalHeaderSize = if modul.Is64Bit then 0xf0 else 0xe0 + let peOptionalHeaderChunk, next = chunk peOptionalHeaderSize next + + let textSectionHeaderSize = 0x28 + let textSectionHeaderChunk, next = chunk textSectionHeaderSize next + + let dataSectionHeaderSize = 0x28 + let dataSectionHeaderChunk, next = chunk dataSectionHeaderSize next + + let relocSectionHeaderSize = 0x28 + let relocSectionHeaderChunk, next = chunk relocSectionHeaderSize next + + let headerSize = next - headerAddr + let nextPhys = align alignPhys (headerSectionPhysLoc + headerSize) + let headerSectionPhysSize = nextPhys - headerSectionPhysLoc + let next = align alignVirt (headerAddr + headerSize) + + // TEXT SECTION: 8 bytes IAT table 72 bytes CLI header + + let textSectionPhysLoc = nextPhys + let textSectionAddr = next + let next = textSectionAddr + + let importAddrTableChunk, next = chunk 0x08 next + let cliHeaderPadding = (if isItanium then (align 16 next) else next) - next + let next = next + cliHeaderPadding + let cliHeaderChunk, next = chunk 0x48 next + + let desiredMetadataVersion = + if modul.MetadataVersion <> "" then + Version.Parse modul.MetadataVersion + else + match ilg.systemRuntimeScopeRef with + | ILScopeRef.Local -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Local" + | ILScopeRef.Module(_) -> failwith "Expected mscorlib to be ILScopeRef.Assembly was ILScopeRef.Module" + | ILScopeRef.Assembly(aref) -> + match aref.Version with + | USome v -> v + | UNone -> failwith "Expected msorlib to have a version number" + + let entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups, pdbData, mappings, guidStart = + writeILMetadataAndCode ((pdbfile <> None), desiredMetadataVersion, ilg, emitTailcalls, deterministic, showTimes) modul next + + let _codeChunk, next = chunk code.Length next + let _codePaddingChunk, next = chunk codePadding.Length next + + let metadataChunk, next = chunk metadata.Length next + +#if EMIT_STRONG_NAME + let strongnameChunk, next = + match signer with + | None -> nochunk next + | Some s -> chunk s.SignatureSize next #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + let strongnameChunk, next = nochunk next #endif - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - - member __.IsStatic - with get() = isStatic - and set x = isStatic <- x - - member __.GetterCode - with set (q:Expr list -> Expr) = - if not getter.IsValueCreated then getterCode <- Some q else failwith "ProvidedProperty: getter MethodInfo has already been created" - - member __.SetterCode - with set (q:Expr list -> Expr) = - if not (setter.IsValueCreated) then setterCode <- Some q else failwith "ProvidedProperty: setter MethodInfo has already been created" - - // Implement overloads - override __.PropertyType = propertyType - override __.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired "SetValue" propertyName - override __.GetAccessors _nonPublic = notRequired "nonPublic" propertyName - override __.GetGetMethod _nonPublic = if hasGetter() then getter.Force() :> MethodInfo else null - override __.GetSetMethod _nonPublic = if hasSetter() then setter.Force() :> MethodInfo else null - override __.GetIndexParameters() = [| for p in parameters -> upcast p |] - override __.Attributes = PropertyAttributes.None - override __.CanRead = hasGetter() - override __.CanWrite = hasSetter() - override __.GetValue(_obj, _invokeAttr, _binder, _index, _culture) : obj = notRequired "GetValue" propertyName - override __.Name = propertyName - override __.DeclaringType = declaringType |> nonNull "ProvidedProperty.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Property - - override __.ReflectedType = notRequired "ReflectedType" propertyName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" propertyName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" propertyName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" propertyName - -type ProvidedEvent(eventName:string,eventHandlerType:Type) = - inherit System.Reflection.EventInfo() - // State - - let mutable declaringType = null - let mutable isStatic = false - let mutable adderCode = None : option Expr> - let mutable removerCode = None : option Expr> - - // Delay construction - to pick up the latest isStatic - let markSpecialName (m:ProvidedMethod) = m.AddMethodAttrs(MethodAttributes.SpecialName); m - let adder = lazy (ProvidedMethod("add_" + eventName, [ProvidedParameter("handler", eventHandlerType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=adderCode.Value) |> markSpecialName) - let remover = lazy (ProvidedMethod("remove_" + eventName, [ProvidedParameter("handler", eventHandlerType)],typeof,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCode=removerCode.Value) |> markSpecialName) - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA + let resourcesChunk, next = chunk resources.Length next + + let rawdataChunk, next = chunk data.Length next + + let vtfixupsChunk, next = nochunk next // Note: only needed for mixed mode assemblies + let importTableChunkPrePadding = (if isItanium then (align 16 next) else next) - next + let next = next + importTableChunkPrePadding + let importTableChunk, next = chunk 0x28 next + let importLookupTableChunk, next = chunk 0x14 next + let importNameHintTableChunk, next = chunk 0x0e next + let mscoreeStringChunk, next = chunk 0x0c next + + let next = align 0x10 (next + 0x05) - 0x05 + let importTableChunk = { addr=importTableChunk.addr; size = next - importTableChunk.addr} + let importTableChunkPadding = importTableChunk.size - (0x28 + 0x14 + 0x0e + 0x0c) + + let next = next + 0x03 + let entrypointCodeChunk, next = chunk 0x06 next + let globalpointerCodeChunk, next = chunk (if isItanium then 0x8 else 0x0) next + +#if EMIT_DEBUG_INFO + let pdbOpt = + match portablePDB with + | true -> + let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData + if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream) + else Some (pdbStream) + | _ -> None + + let debugDirectoryChunk, next = + chunk (if pdbfile = None then + 0x0 + else if embeddedPDB && portablePDB then + sizeof_IMAGE_DEBUG_DIRECTORY * 2 + else + sizeof_IMAGE_DEBUG_DIRECTORY + ) next + + // The debug data is given to us by the PDB writer and appears to + // typically be the type of the data plus the PDB file name. We fill + // this in after we've written the binary. We approximate the size according + // to what PDB writers seem to require and leave extra space just in case... + let debugDataJustInCase = 40 + let debugDataChunk, next = + chunk (align 0x4 (match pdbfile with + | None -> 0 + | Some f -> (24 + + Encoding.Unicode.GetByteCount(f) // See bug 748444 + + debugDataJustInCase))) next + + let debugEmbeddedPdbChunk, next = + let streamLength = + match pdbOpt with + | Some (_, _, stream) -> int(stream.Length) + | None -> 0 + chunk (align 0x4 (match embeddedPDB with + | true -> 8 + streamLength + | _ -> 0 )) next + #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + let pdbOpt = None + let debugDirectoryChunk, next = chunk 0x0 next + let debugDataChunk, next = chunk (align 0x4 0) next + let debugEmbeddedPdbChunk, next = chunk (align 0x4 0) next #endif - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - member __.IsStatic - with get() = isStatic - and set x = isStatic <- x - - member __.AdderCode - with get() = adderCode.Value - and set f = - if not adder.IsValueCreated then adderCode <- Some f else failwith "ProvidedEvent: Add MethodInfo has already been created" - - member __.RemoverCode - with get() = removerCode.Value - and set f = - if not (remover.IsValueCreated) then removerCode <- Some f else failwith "ProvidedEvent: Remove MethodInfo has already been created" - - // Implement overloads - override __.EventHandlerType = eventHandlerType - override __.GetAddMethod _nonPublic = adder.Force() :> MethodInfo - override __.GetRemoveMethod _nonPublic = remover.Force() :> MethodInfo - override __.Attributes = EventAttributes.None - override __.Name = eventName - override __.DeclaringType = declaringType |> nonNull "ProvidedEvent.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Event - - override __.GetRaiseMethod _nonPublic = notRequired "GetRaiseMethod" eventName - override __.ReflectedType = notRequired "ReflectedType" eventName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" eventName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" eventName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" eventName - -type ProvidedLiteralField(fieldName:string,fieldType:Type,literalValue:obj) = - inherit System.Reflection.FieldInfo() - // State - - let mutable declaringType = null - - let customAttributesImpl = CustomAttributesImpl() - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA + let textSectionSize = next - textSectionAddr + let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) + let textSectionPhysSize = nextPhys - textSectionPhysLoc + let next = align alignVirt (textSectionAddr + textSectionSize) + + // .RSRC SECTION (DATA) + let dataSectionPhysLoc = nextPhys + let dataSectionAddr = next + let dataSectionVirtToPhys v = v - dataSectionAddr + dataSectionPhysLoc + + +#if EMIT_NATIVE_RESOURCES + let resourceFormat = if modul.Is64Bit then Support.X64 else Support.X86 + let nativeResources = + match modul.NativeResources with + | [] -> [||] + | resources -> + if runningOnMono then + [||] + else + let unlinkedResources = List.map Lazy.force resources + begin + try linkNativeResources unlinkedResources next resourceFormat (Path.GetDirectoryName(outfile)) + with e -> failwith ("Linking a native resource failed: "+e.Message+"") + end + let nativeResourcesSize = nativeResources.Length + let nativeResourcesChunk, next = chunk nativeResourcesSize next #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + let nativeResourcesChunk, next = chunk 0x0 next #endif - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - - - // Implement overloads - override __.FieldType = fieldType - override __.GetRawConstantValue() = literalValue - override __.Attributes = FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public - override __.Name = fieldName - override __.DeclaringType = declaringType |> nonNull "ProvidedLiteralField.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Field - - override __.ReflectedType = notRequired "ReflectedType" fieldName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" fieldName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" fieldName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" fieldName - - override __.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired "SetValue" fieldName - override __.GetValue(_obj) : obj = notRequired "GetValue" fieldName - override __.FieldHandle = notRequired "FieldHandle" fieldName - -type ProvidedField(fieldName:string,fieldType:Type) = - inherit System.Reflection.FieldInfo() - // State - - let mutable declaringType = null - - let customAttributesImpl = CustomAttributesImpl() - let mutable fieldAttrs = FieldAttributes.Private - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() -#if FX_NO_CUSTOMATTRIBUTEDATA + + let dummydatap, next = chunk (if next = dataSectionAddr then 0x01 else 0x0) next + + let dataSectionSize = next - dataSectionAddr + let nextPhys = align alignPhys (dataSectionPhysLoc + dataSectionSize) + let dataSectionPhysSize = nextPhys - dataSectionPhysLoc + let next = align alignVirt (dataSectionAddr + dataSectionSize) + + // .RELOC SECTION base reloc table: 0x0c size + let relocSectionPhysLoc = nextPhys + let relocSectionAddr = next + let baseRelocTableChunk, next = chunk 0x0c next + + let relocSectionSize = next - relocSectionAddr + let nextPhys = align alignPhys (relocSectionPhysLoc + relocSectionSize) + let relocSectionPhysSize = nextPhys - relocSectionPhysLoc + let next = align alignVirt (relocSectionAddr + relocSectionSize) + + // Now we know where the data section lies we can fix up the + // references into the data section from the metadata tables. + begin + requiredDataFixups |> Array.iter + (fun (metadataOffset32, (dataOffset, kind)) -> + let metadataOffset = metadataOffset32 + if metadataOffset < 0 || metadataOffset >= metadata.Length - 4 then failwith "data RVA fixup: fixup located outside metadata"; + checkFixup32 metadata metadataOffset 0xdeaddddd; + let dataRva = + if kind then + let res = dataOffset + if res >= resourcesChunk.size then printfn ("resource offset bigger than resource data section"); + res + else + let res = rawdataChunk.addr + dataOffset + if res < rawdataChunk.addr then printfn ("data rva before data section"); + if res >= rawdataChunk.addr + rawdataChunk.size then printfn "%s" ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr+", rawdataChunk.size = "+string rawdataChunk.size); + res + applyFixup32 metadata metadataOffset dataRva); + end; + + // IMAGE TOTAL SIZE + let imageEndSectionPhysLoc = nextPhys + let imageEndAddr = next + + + let write p (os: BinaryWriter) chunkName chunk = + match p with + | None -> () + | Some pExpected -> + os.Flush(); + let pCurrent = int32 os.BaseStream.Position + if pCurrent <> pExpected then + failwith ("warning: "+chunkName+" not where expected, pCurrent = "+string pCurrent+", p.addr = "+string pExpected) + writeBytes os chunk + + let writePadding (os: BinaryWriter) _comment sz = + if sz < 0 then failwith "writePadding: size < 0"; + for i = 0 to sz - 1 do + os.Write 0uy + + // Now we've computed all the offsets, write the image + + write (Some msdosHeaderChunk.addr) os "msdos header" msdosHeader; + + write (Some peSignatureChunk.addr) os "pe signature" [| |]; + + writeInt32 os 0x4550; + + write (Some peFileHeaderChunk.addr) os "pe file header" [| |]; + + if (modul.Platform = Some(AMD64)) then + writeInt32AsUInt16 os 0x8664 // Machine - IMAGE_FILE_MACHINE_AMD64 + elif isItanium then + writeInt32AsUInt16 os 0x200 + else + writeInt32AsUInt16 os 0x014c; // Machine - IMAGE_FILE_MACHINE_I386 + + writeInt32AsUInt16 os numSections; + +#if EMIT_DEBUG_INFO + let pdbData = + if deterministic then + // Hash code, data and metadata + use sha = System.Security.Cryptography.SHA1.Create() // IncrementalHash is core only + let hCode = sha.ComputeHash code + let hData = sha.ComputeHash data + let hMeta = sha.ComputeHash metadata + let final = [| hCode; hData; hMeta |] |> Array.collect id |> sha.ComputeHash + + // Confirm we have found the correct data and aren't corrupting the metadata + if metadata.[ guidStart..guidStart+3] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + if metadata.[ guidStart+12..guidStart+15] <> [| 4uy; 3uy; 2uy; 1uy |] then failwith "Failed to find MVID" + + // Update MVID guid in metadata + Array.blit final 0 metadata guidStart 16 + + // Use last 4 bytes for timestamp - High bit set, to stop tool chains becoming confused + let timestamp = int final.[16] ||| (int final.[17] <<< 8) ||| (int final.[18] <<< 16) ||| (int (final.[19] ||| 128uy) <<< 24) + writeInt32 os timestamp + // Update pdbData with new guid and timestamp. Portable and embedded PDBs don't need the ModuleID + // Full and PdbOnly aren't supported under deterministic builds currently, they rely on non-determinsitic Windows native code + { pdbData with ModuleID = final.[0..15] ; Timestamp = timestamp } + else + writeInt32 os timestamp // date since 1970 + pdbData #else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() + writeInt32 os timestamp // date since 1970 #endif - member __.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice - - member __.SetFieldAttributes attrs = fieldAttrs <- attrs - // Implement overloads - override __.FieldType = fieldType - override __.GetRawConstantValue() = null - override __.Attributes = fieldAttrs - override __.Name = fieldName - override __.DeclaringType = declaringType |> nonNull "ProvidedField.DeclaringType" - override __.MemberType : MemberTypes = MemberTypes.Field - - override __.ReflectedType = notRequired "ReflectedType" fieldName - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" fieldName - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" fieldName - override __.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" fieldName - - override __.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired "SetValue" fieldName - override __.GetValue(_obj) : obj = notRequired "GetValue" fieldName - override __.FieldHandle = notRequired "FieldHandle" fieldName - -/// Represents the type constructor in a provided symbol type. -[] -type ProvidedSymbolKind = - | SDArray - | Array of int - | Pointer - | ByRef - | Generic of System.Type - | FSharpTypeAbbreviation of (System.Reflection.Assembly * string * string[]) - - -/// Represents an array or other symbolic type involving a provided type as the argument. -/// See the type provider spec for the methods that must be implemented. -/// Note that the type provider specification does not require us to implement pointer-equality for provided types. -type ProvidedSymbolType(kind: ProvidedSymbolKind, args: Type list) = - inherit Type() - - let rec isEquivalentTo (thisTy: Type) (otherTy: Type) = - match thisTy, otherTy with - | (:? ProvidedSymbolType as thisTy), (:? ProvidedSymbolType as thatTy) -> (thisTy.Kind,thisTy.Args) = (thatTy.Kind, thatTy.Args) - | (:? ProvidedSymbolType as thisTy), otherTy | otherTy, (:? ProvidedSymbolType as thisTy) -> - match thisTy.Kind, thisTy.Args with - | ProvidedSymbolKind.SDArray, [ty] | ProvidedSymbolKind.Array _, [ty] when otherTy.IsArray-> ty.Equals(otherTy.GetElementType()) - | ProvidedSymbolKind.ByRef, [ty] when otherTy.IsByRef -> ty.Equals(otherTy.GetElementType()) - | ProvidedSymbolKind.Pointer, [ty] when otherTy.IsPointer -> ty.Equals(otherTy.GetElementType()) - | ProvidedSymbolKind.Generic baseTy, args -> otherTy.IsGenericType && isEquivalentTo baseTy (otherTy.GetGenericTypeDefinition()) && Seq.forall2 isEquivalentTo args (otherTy.GetGenericArguments()) - | _ -> false - | a, b -> a.Equals b - - let nameText() = - match kind,args with - | ProvidedSymbolKind.SDArray,[arg] -> arg.Name + "[]" - | ProvidedSymbolKind.Array _,[arg] -> arg.Name + "[*]" - | ProvidedSymbolKind.Pointer,[arg] -> arg.Name + "*" - | ProvidedSymbolKind.ByRef,[arg] -> arg.Name + "&" - | ProvidedSymbolKind.Generic gty, args -> gty.Name + (sprintf "%A" args) - | ProvidedSymbolKind.FSharpTypeAbbreviation (_,_,path),_ -> path.[path.Length-1] - | _ -> failwith "unreachable" - - static member convType (parameters: Type list) (ty:Type) = - if ty = null then null - elif ty.IsGenericType then - let args = Array.map (ProvidedSymbolType.convType parameters) (ty.GetGenericArguments()) - ProvidedSymbolType(Generic (ty.GetGenericTypeDefinition()), Array.toList args) :> Type - elif ty.HasElementType then - let ety = ProvidedSymbolType.convType parameters (ty.GetElementType()) - if ty.IsArray then - let rank = ty.GetArrayRank() - if rank = 1 then ProvidedSymbolType(SDArray,[ety]) :> Type - else ProvidedSymbolType(Array rank,[ety]) :> Type - elif ty.IsPointer then ProvidedSymbolType(Pointer,[ety]) :> Type - elif ty.IsByRef then ProvidedSymbolType(ByRef,[ety]) :> Type - else ty - elif ty.IsGenericParameter then - if ty.GenericParameterPosition <= parameters.Length - 1 then - parameters.[ty.GenericParameterPosition] - else - ty - else ty - - override __.FullName = - match kind,args with - | ProvidedSymbolKind.SDArray,[arg] -> arg.FullName + "[]" - | ProvidedSymbolKind.Array _,[arg] -> arg.FullName + "[*]" - | ProvidedSymbolKind.Pointer,[arg] -> arg.FullName + "*" - | ProvidedSymbolKind.ByRef,[arg] -> arg.FullName + "&" - | ProvidedSymbolKind.Generic gty, args -> gty.FullName + "[" + (args |> List.map (fun arg -> arg.ToString()) |> String.concat ",") + "]" - | ProvidedSymbolKind.FSharpTypeAbbreviation (_,nsp,path),args -> String.concat "." (Array.append [| nsp |] path) + (match args with [] -> "" | _ -> args.ToString()) - | _ -> failwith "unreachable" - - /// Although not strictly required by the type provider specification, this is required when doing basic operations like FullName on - /// .NET symbolic types made from this type, e.g. when building Nullable.FullName - override __.DeclaringType = - match kind,args with - | ProvidedSymbolKind.SDArray,[arg] -> arg - | ProvidedSymbolKind.Array _,[arg] -> arg - | ProvidedSymbolKind.Pointer,[arg] -> arg - | ProvidedSymbolKind.ByRef,[arg] -> arg - | ProvidedSymbolKind.Generic gty,_ -> gty - | ProvidedSymbolKind.FSharpTypeAbbreviation _,_ -> null - | _ -> failwith "unreachable" - - override __.IsAssignableFrom(otherTy) = - match kind with - | Generic gtd -> - if otherTy.IsGenericType then - let otherGtd = otherTy.GetGenericTypeDefinition() - let otherArgs = otherTy.GetGenericArguments() - let yes = gtd.Equals(otherGtd) && Seq.forall2 isEquivalentTo args otherArgs - yes - else - base.IsAssignableFrom(otherTy) - | _ -> base.IsAssignableFrom(otherTy) - - override __.Name = nameText() - - override __.BaseType = - match kind with - | ProvidedSymbolKind.SDArray -> typeof - | ProvidedSymbolKind.Array _ -> typeof - | ProvidedSymbolKind.Pointer -> typeof - | ProvidedSymbolKind.ByRef -> typeof - | ProvidedSymbolKind.Generic gty -> - if gty.BaseType = null then null else - ProvidedSymbolType.convType args gty.BaseType - | ProvidedSymbolKind.FSharpTypeAbbreviation _ -> typeof - - override __.GetArrayRank() = (match kind with ProvidedSymbolKind.Array n -> n | ProvidedSymbolKind.SDArray -> 1 | _ -> invalidOp "non-array type") - override __.IsValueTypeImpl() = (match kind with ProvidedSymbolKind.Generic gtd -> gtd.IsValueType | _ -> false) - override __.IsArrayImpl() = (match kind with ProvidedSymbolKind.Array _ | ProvidedSymbolKind.SDArray -> true | _ -> false) - override __.IsByRefImpl() = (match kind with ProvidedSymbolKind.ByRef _ -> true | _ -> false) - override __.IsPointerImpl() = (match kind with ProvidedSymbolKind.Pointer _ -> true | _ -> false) - override __.IsPrimitiveImpl() = false - override __.IsGenericType = (match kind with ProvidedSymbolKind.Generic _ -> true | _ -> false) - override __.GetGenericArguments() = (match kind with ProvidedSymbolKind.Generic _ -> args |> List.toArray | _ -> invalidOp "non-generic type") - override __.GetGenericTypeDefinition() = (match kind with ProvidedSymbolKind.Generic e -> e | _ -> invalidOp "non-generic type") - override __.IsCOMObjectImpl() = false - override __.HasElementTypeImpl() = (match kind with ProvidedSymbolKind.Generic _ -> false | _ -> true) - override __.GetElementType() = (match kind,args with (ProvidedSymbolKind.Array _ | ProvidedSymbolKind.SDArray | ProvidedSymbolKind.ByRef | ProvidedSymbolKind.Pointer),[e] -> e | _ -> invalidOp "not an array, pointer or byref type") - override this.ToString() = this.FullName - - override __.Assembly = - match kind with - | ProvidedSymbolKind.FSharpTypeAbbreviation (assembly,_nsp,_path) -> assembly - | ProvidedSymbolKind.Generic gty -> gty.Assembly - | _ -> notRequired "Assembly" (nameText()) - - override __.Namespace = - match kind with - | ProvidedSymbolKind.FSharpTypeAbbreviation (_assembly,nsp,_path) -> nsp - | _ -> notRequired "Namespace" (nameText()) - - override __.GetHashCode() = - match kind,args with - | ProvidedSymbolKind.SDArray,[arg] -> 10 + hash arg - | ProvidedSymbolKind.Array _,[arg] -> 163 + hash arg - | ProvidedSymbolKind.Pointer,[arg] -> 283 + hash arg - | ProvidedSymbolKind.ByRef,[arg] -> 43904 + hash arg - | ProvidedSymbolKind.Generic gty,_ -> 9797 + hash gty + List.sumBy hash args - | ProvidedSymbolKind.FSharpTypeAbbreviation _,_ -> 3092 - | _ -> failwith "unreachable" - - override __.Equals(other: obj) = - match other with - | :? ProvidedSymbolType as otherTy -> (kind, args) = (otherTy.Kind, otherTy.Args) - | _ -> false + writeInt32 os 0x00; // Pointer to Symbol Table Always 0 + // 00000090 + writeInt32 os 0x00; // Number of Symbols Always 0 + writeInt32AsUInt16 os peOptionalHeaderSize; // Size of the optional header, the format is described below. + + // 64bit: IMAGE_FILE_32BIT_MACHINE ||| IMAGE_FILE_LARGE_ADDRESS_AWARE + // 32bit: IMAGE_FILE_32BIT_MACHINE + // Yes, 32BIT_MACHINE is set for AMD64... + let iMachineCharacteristic = match modul.Platform with | Some IA64 -> 0x20 | Some AMD64 -> 0x0120 | _ -> 0x0100 + + writeInt32AsUInt16 os ((if isDll then 0x2000 else 0x0000) ||| 0x0002 ||| 0x0004 ||| 0x0008 ||| iMachineCharacteristic); + + // Now comes optional header + + let peOptionalHeaderByte = peOptionalHeaderByteByCLRVersion desiredMetadataVersion + + write (Some peOptionalHeaderChunk.addr) os "pe optional header" [| |]; + if modul.Is64Bit then + writeInt32AsUInt16 os 0x020B // Magic number is 0x020B for 64-bit + else + writeInt32AsUInt16 os 0x010b; // Always 0x10B (see Section 23.1). + writeInt32AsUInt16 os peOptionalHeaderByte; // ECMA spec says 6, some binaries, e.g. fscmanaged.exe say 7, Whidbey binaries say 8 + writeInt32 os textSectionPhysSize; // Size of the code (text) section, or the sum of all code sections if there are multiple sections. + // 000000a0 + writeInt32 os dataSectionPhysSize; // Size of the initialized data section, or the sum of all such sections if there are multiple data sections. + writeInt32 os 0x00; // Size of the uninitialized data section, or the sum of all such sections if there are multiple uninitialized data sections. + writeInt32 os entrypointCodeChunk.addr; // RVA of entry point , needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 in a section marked execute/read for EXEs or 0 for DLLs e.g. 0x0000b57e + writeInt32 os textSectionAddr; // e.g. 0x0002000 + // 000000b0 + if modul.Is64Bit then + writeInt64 os ((int64)imageBaseReal) // REVIEW: For 64-bit, we should use a 64-bit image base + else + writeInt32 os dataSectionAddr; // e.g. 0x0000c000 + writeInt32 os imageBaseReal; // Image Base Always 0x400000 (see Section 23.1). - QUERY: no it's not always 0x400000, e.g. 0x034f0000 + + writeInt32 os alignVirt; // Section Alignment Always 0x2000 (see Section 23.1). + writeInt32 os alignPhys; // File Alignment Either 0x200 or 0x1000. + // 000000c0 + writeInt32AsUInt16 os 0x04; // OS Major Always 4 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // OS Minor Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // User Major Always 0 (see Section 23.1). + writeInt32AsUInt16 os 0x00; // User Minor Always 0 (see Section 23.1). + do + let (major, minor) = modul.SubsystemVersion + writeInt32AsUInt16 os major; + writeInt32AsUInt16 os minor; + writeInt32 os 0x00; // Reserved Always 0 (see Section 23.1). + // 000000d0 + writeInt32 os imageEndAddr; // Image Size: Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment. e.g. 0x0000e000 + writeInt32 os headerSectionPhysSize; // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment. + writeInt32 os 0x00; // File Checksum Always 0 (see Section 23.1). QUERY: NOT ALWAYS ZERO + writeInt32AsUInt16 os modul.SubSystemFlags; // SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2). QUERY: Why is this 3 on the images ILASM produces + // DLL Flags Always 0x400 (no unmanaged windows exception handling - see Section 23.1). + // Itanium: see notes at end of file + // IMAGE_DLLCHARACTERISTICS_NX_COMPAT: See FSharp 1.0 bug 5019 and http://blogs.msdn.com/ed_maurer/archive/2007/12/14/nxcompat-and-the-c-compiler.aspx + // Itanium: IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE | IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x86: IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + // x64: IMAGE_DLLCHARACTERISTICS_ NO_SEH | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT + let dllCharacteristics = + let flags = + if modul.Is64Bit then (if isItanium then 0x8540 else 0x540) + else 0x540 + if modul.UseHighEntropyVA then flags ||| 0x20 // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA + else flags + writeInt32AsUInt16 os dllCharacteristics + // 000000e0 + // Note that the defaults differ between x86 and x64 + if modul.Is64Bit then + let size = defaultArg modul.StackReserveSize 0x400000 |> int64 + writeInt64 os size // Stack Reserve Size Always 0x400000 (4Mb) (see Section 23.1). + writeInt64 os 0x4000L // Stack Commit Size Always 0x4000 (16Kb) (see Section 23.1). + writeInt64 os 0x100000L // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt64 os 0x2000L // Heap Commit Size Always 0x800 (8Kb) (see Section 23.1). + else + let size = defaultArg modul.StackReserveSize 0x100000 + writeInt32 os size // Stack Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Stack Commit Size Always 0x1000 (4Kb) (see Section 23.1). + writeInt32 os 0x100000 // Heap Reserve Size Always 0x100000 (1Mb) (see Section 23.1). + writeInt32 os 0x1000 // Heap Commit Size Always 0x1000 (4Kb) (see Section 23.1). + // 000000f0 - x86 location, moving on, for x64, add 0x10 + writeInt32 os 0x00 // Loader Flags Always 0 (see Section 23.1) + writeInt32 os 0x10 // Number of Data Directories: Always 0x10 (see Section 23.1). + writeInt32 os 0x00 + writeInt32 os 0x00 // Export Table Always 0 (see Section 23.1). + // 00000100 + writeDirectory os importTableChunk // Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530 + // Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not. For the moment assume the resources table is always the first resource in the file. + writeDirectory os nativeResourcesChunk + + // 00000110 + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Exception Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Certificate Table Always 0 (see Section 23.1). + // 00000120 + writeDirectory os baseRelocTableChunk + writeDirectory os debugDirectoryChunk // Debug Directory + // 00000130 + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Copyright Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + writeInt32 os 0x00 // Global Ptr Always 0 (see Section 23.1). + // 00000140 + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // Load Config Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + writeInt32 os 0x00 // TLS Table Always 0 (see Section 23.1). + // 00000150 + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeInt32 os 0x00 // Bound Import Always 0 (see Section 23.1). + writeDirectory os importAddrTableChunk // Import Addr Table, (see clause 24.3.1). e.g. 0x00002000 + // 00000160 + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeInt32 os 0x00 // Delay Import Descriptor Always 0 (see Section 23.1). + writeDirectory os cliHeaderChunk + // 00000170 + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + writeInt32 os 0x00 // Reserved Always 0 (see Section 23.1). + + write (Some textSectionHeaderChunk.addr) os "text section header" [| |] + + // 00000178 + writeBytes os [| 0x2euy; 0x74uy; 0x65uy; 0x78uy; 0x74uy; 0x00uy; 0x00uy; 0x00uy; |] // ".text\000\000\000" + // 00000180 + writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x00009584 + writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x00020000 + writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. 0x00009600 + writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 00000200 + // 00000190 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 00000198 + writeInt32AsUInt16 os 0x00// NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags describing section's characteristics, see below. IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ + + write (Some dataSectionHeaderChunk.addr) os "data section header" [| |] + + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x73uy; 0x72uy; 0x63uy; 0x00uy; 0x00uy; 0x00uy; |] // ".rsrc\000\000\000" + // writeBytes os [| 0x2e; 0x73; 0x64; 0x61; 0x74; 0x61; 0x00; 0x00; |] // ".sdata\000\000" + writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c + writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000 + // 000001b0 + writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. e.g. 0x00000200 + writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 0x00009800 + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x40uy |] // Characteristics Flags: IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA + + write (Some relocSectionHeaderChunk.addr) os "reloc section header" [| |] + // 000001a0 + writeBytes os [| 0x2euy; 0x72uy; 0x65uy; 0x6cuy; 0x6fuy; 0x63uy; 0x00uy; 0x00uy; |] // ".reloc\000\000" + writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c + writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000 + // 000001b0 + writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00000200 + writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00009800 + // 000001b8 + writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section. + writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1). + // 000001c0 + writeInt32AsUInt16 os 0x00 // NumberOfRelocations Number of relocations, set to 0 if unused. + writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1). + writeBytes os [| 0x40uy; 0x00uy; 0x00uy; 0x42uy |] // Characteristics Flags: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | + + writePadding os "pad to text begin" (textSectionPhysLoc - headerSize) + + // TEXT SECTION: e.g. 0x200 + + let textV2P v = v - textSectionAddr + textSectionPhysLoc + + // e.g. 0x0200 + write (Some (textV2P importAddrTableChunk.addr)) os "import addr table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 // QUERY 4 bytes of zeros not 2 like ECMA 24.3.1 says + + // e.g. 0x0208 + + let flags = + (if modul.IsILOnly then 0x01 else 0x00) ||| + (if modul.Is32Bit then 0x02 else 0x00) ||| + (if modul.Is32BitPreferred then 0x00020003 else 0x00) ||| +#if EMIT_STRONG_NAME + (if (match signer with None -> false | Some s -> s.IsFullySigned) then 0x08 else 0x00) ||| +#endif + 0x0000 + + let headerVersionMajor, headerVersionMinor = headerVersionSupportedByCLRVersion desiredMetadataVersion + + writePadding os "pad to cli header" cliHeaderPadding + write (Some (textV2P cliHeaderChunk.addr)) os "cli header" [| |] + writeInt32 os 0x48 // size of header + writeInt32AsUInt16 os headerVersionMajor // Major part of minimum version of CLR reqd. + writeInt32AsUInt16 os headerVersionMinor // Minor part of minimum version of CLR reqd. ... + // e.g. 0x0210 + writeDirectory os metadataChunk + writeInt32 os flags + + writeInt32 os entryPointToken + write None os "rest of cli header" [| |] + + // e.g. 0x0220 + writeDirectory os resourcesChunk + writeDirectory os strongnameChunk + // e.g. 0x0230 + writeInt32 os 0x00 // code manager table, always 0 + writeInt32 os 0x00 // code manager table, always 0 + writeDirectory os vtfixupsChunk + // e.g. 0x0240 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // export addr table jumps, always 0 + writeInt32 os 0x00 // managed native header, always 0 + writeInt32 os 0x00 // managed native header, always 0 + + writeBytes os code + write None os "code padding" codePadding + + writeBytes os metadata + +#if EMIT_STRONG_NAME + // write 0x80 bytes of empty space for encrypted SHA1 hash, written by SN.EXE or call to signing API + if signer <> None then + write (Some (textV2P strongnameChunk.addr)) os "strongname" (Array.create strongnameChunk.size 0x0uy) +#endif - member __.Kind = kind - member __.Args = args - - member __.IsFSharpTypeAbbreviation = match kind with FSharpTypeAbbreviation _ -> true | _ -> false - // For example, int - member __.IsFSharpUnitAnnotated = match kind with ProvidedSymbolKind.Generic gtd -> not gtd.IsGenericTypeDefinition | _ -> false - - override __.Module : Module = notRequired "Module" (nameText()) - override __.GetConstructors _bindingAttr = notRequired "GetConstructors" (nameText()) - override __.GetMethodImpl(_name, _bindingAttr, _binderBinder, _callConvention, _types, _modifiers) = - match kind with - | Generic gtd -> - let ty = gtd.GetGenericTypeDefinition().MakeGenericType(Array.ofList args) - ty.GetMethod(_name, _bindingAttr) - | _ -> notRequired "GetMethodImpl" (nameText()) - override __.GetMembers _bindingAttr = notRequired "GetMembers" (nameText()) - override __.GetMethods _bindingAttr = notRequired "GetMethods" (nameText()) - override __.GetField(_name, _bindingAttr) = notRequired "GetField" (nameText()) - override __.GetFields _bindingAttr = notRequired "GetFields" (nameText()) - override __.GetInterface(_name, _ignoreCase) = notRequired "GetInterface" (nameText()) - override __.GetInterfaces() = notRequired "GetInterfaces" (nameText()) - override __.GetEvent(_name, _bindingAttr) = notRequired "GetEvent" (nameText()) - override __.GetEvents _bindingAttr = notRequired "GetEvents" (nameText()) - override __.GetProperties _bindingAttr = notRequired "GetProperties" (nameText()) - override __.GetPropertyImpl(_name, _bindingAttr, _binder, _returnType, _types, _modifiers) = notRequired "GetPropertyImpl" (nameText()) - override __.GetNestedTypes _bindingAttr = notRequired "GetNestedTypes" (nameText()) - override __.GetNestedType(_name, _bindingAttr) = notRequired "GetNestedType" (nameText()) - override __.GetAttributeFlagsImpl() = notRequired "GetAttributeFlagsImpl" (nameText()) - override this.UnderlyingSystemType = - match kind with - | ProvidedSymbolKind.SDArray - | ProvidedSymbolKind.Array _ - | ProvidedSymbolKind.Pointer - | ProvidedSymbolKind.FSharpTypeAbbreviation _ - | ProvidedSymbolKind.ByRef -> upcast this - | ProvidedSymbolKind.Generic gty -> gty.UnderlyingSystemType -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = ([| |] :> IList<_>) + write (Some (textV2P resourcesChunk.addr)) os "raw resources" [| |] + writeBytes os resources + write (Some (textV2P rawdataChunk.addr)) os "raw data" [| |] + writeBytes os data + + writePadding os "start of import table" importTableChunkPrePadding + + // vtfixups would go here + write (Some (textV2P importTableChunk.addr)) os "import table" [| |] + + writeInt32 os importLookupTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os mscoreeStringChunk.addr + writeInt32 os importAddrTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + write (Some (textV2P importLookupTableChunk.addr)) os "import lookup table" [| |] + writeInt32 os importNameHintTableChunk.addr + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + writeInt32 os 0x00 + + + write (Some (textV2P importNameHintTableChunk.addr)) os "import name hint table" [| |] + // Two zero bytes of hint, then Case sensitive, null-terminated ASCII string containing name to import. + // Shall _CorExeMain a .exe file _CorDllMain for a .dll file. + if isDll then + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy ; 0x6fuy; 0x72uy; 0x44uy; 0x6cuy; 0x6cuy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + else + writeBytes os [| 0x00uy; 0x00uy; 0x5fuy; 0x43uy; 0x6fuy; 0x72uy; 0x45uy; 0x78uy; 0x65uy; 0x4duy; 0x61uy; 0x69uy; 0x6euy; 0x00uy |] + + write (Some (textV2P mscoreeStringChunk.addr)) os "mscoree string" + [| 0x6duy; 0x73uy; 0x63uy; 0x6fuy ; 0x72uy; 0x65uy ; 0x65uy; 0x2euy ; 0x64uy; 0x6cuy ; 0x6cuy; 0x00uy ; |] + + writePadding os "end of import tab" importTableChunkPadding + + writePadding os "head of entrypoint" 0x03 + let ep = (imageBaseReal + textSectionAddr) + write (Some (textV2P entrypointCodeChunk.addr)) os " entrypoint code" + [| 0xFFuy; 0x25uy; (* x86 Instructions for entry *) b0 ep; b1 ep; b2 ep; b3 ep |] + if isItanium then + write (Some (textV2P globalpointerCodeChunk.addr)) os " itanium global pointer" + [| 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy |] + + if pdbfile.IsSome then + write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy) + write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy) + + if embeddedPDB then + write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy) + + writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize) + + // DATA SECTION +#if EMIT_NATIVE_RESOURCES + match nativeResources with + | [||] -> () + | resources -> + write (Some (dataSectionVirtToPhys nativeResourcesChunk.addr)) os "raw native resources" [| |] + writeBytes os resources #endif - override __.MemberType = notRequired "MemberType" (nameText()) - override __.GetMember(_name,_mt,_bindingAttr) = notRequired "GetMember" (nameText()) - override __.GUID = notRequired "GUID" (nameText()) - override __.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "InvokeMember" (nameText()) - override __.AssemblyQualifiedName = notRequired "AssemblyQualifiedName" (nameText()) - override __.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers) = notRequired "GetConstructorImpl" (nameText()) - override __.GetCustomAttributes(_inherit) = [| |] - override __.GetCustomAttributes(_attributeType, _inherit) = [| |] - override __.IsDefined(_attributeType, _inherit) = false - // FSharp.Data addition: this was added to support arrays of arrays - override this.MakeArrayType() = ProvidedSymbolType(ProvidedSymbolKind.SDArray, [this]) :> Type - override this.MakeArrayType arg = ProvidedSymbolType(ProvidedSymbolKind.Array arg, [this]) :> Type - -type ProvidedSymbolMethod(genericMethodDefinition: MethodInfo, parameters: Type list) = - inherit System.Reflection.MethodInfo() - - let convParam (p:ParameterInfo) = - { new System.Reflection.ParameterInfo() with - override __.Name = p.Name - override __.ParameterType = ProvidedSymbolType.convType parameters p.ParameterType - override __.Attributes = p.Attributes - override __.RawDefaultValue = p.RawDefaultValue -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = p.GetCustomAttributesData() + + if dummydatap.size <> 0x0 then + write (Some (dataSectionVirtToPhys dummydatap.addr)) os "dummy data" [| 0x0uy |] + + writePadding os "end of .rsrc" (relocSectionPhysLoc - dataSectionPhysLoc - dataSectionSize) + + // RELOC SECTION + + // See ECMA 24.3.2 + let relocV2P v = v - relocSectionAddr + relocSectionPhysLoc + + let entrypointFixupAddr = entrypointCodeChunk.addr + 0x02 + let entrypointFixupBlock = (entrypointFixupAddr / 4096) * 4096 + let entrypointFixupOffset = entrypointFixupAddr - entrypointFixupBlock + let reloc = (if modul.Is64Bit then 0xA000 (* IMAGE_REL_BASED_DIR64 *) else 0x3000 (* IMAGE_REL_BASED_HIGHLOW *)) ||| entrypointFixupOffset + // For the itanium, you need to set a relocation entry for the global pointer + let reloc2 = + if not isItanium then + 0x0 + else + 0xA000 ||| (globalpointerCodeChunk.addr - ((globalpointerCodeChunk.addr / 4096) * 4096)) + + write (Some (relocV2P baseRelocTableChunk.addr)) os "base reloc table" + [| b0 entrypointFixupBlock; b1 entrypointFixupBlock; b2 entrypointFixupBlock; b3 entrypointFixupBlock; + 0x0cuy; 0x00uy; 0x00uy; 0x00uy; + b0 reloc; b1 reloc; + b0 reloc2; b1 reloc2; |] + writePadding os "end of .reloc" (imageEndSectionPhysLoc - relocSectionPhysLoc - relocSectionSize) + + os.Dispose() + + pdbData, pdbOpt, debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk, textV2P, mappings + + // Looks like a finally + with e -> + (try + os.Dispose() + File.Delete outfile + with _ -> ()) + reraise() + + //Finished writing and signing the binary and debug info... + mappings + + type options = + { ilg: ILGlobals + pdbfile: string option + portablePDB: bool + embeddedPDB: bool + embedAllSource: bool + embedSourceList: string list + sourceLink: string +#if EMIT_STRONG_NAME + signer: ILStrongNameSigner option #endif - } + emitTailcalls: bool + deterministic: bool + showTimes: bool + dumpDebugInfo:bool } - override this.IsGenericMethod = - (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) < parameters.Length - - override this.GetGenericArguments() = - Seq.skip (if this.DeclaringType.IsGenericType then this.DeclaringType.GetGenericArguments().Length else 0) parameters |> Seq.toArray - - override __.GetGenericMethodDefinition() = genericMethodDefinition - - override __.DeclaringType = ProvidedSymbolType.convType parameters genericMethodDefinition.DeclaringType - override __.ToString() = "Method " + genericMethodDefinition.Name - override __.Name = genericMethodDefinition.Name - override __.MetadataToken = genericMethodDefinition.MetadataToken - override __.Attributes = genericMethodDefinition.Attributes - override __.CallingConvention = genericMethodDefinition.CallingConvention - override __.MemberType = genericMethodDefinition.MemberType - - override __.IsDefined(_attributeType, _inherit) : bool = notRequired "IsDefined" genericMethodDefinition.Name - override __.ReturnType = ProvidedSymbolType.convType parameters genericMethodDefinition.ReturnType - override __.GetParameters() = genericMethodDefinition.GetParameters() |> Array.map convParam - override __.ReturnParameter = genericMethodDefinition.ReturnParameter |> convParam - override __.ReturnTypeCustomAttributes = notRequired "ReturnTypeCustomAttributes" genericMethodDefinition.Name - override __.GetBaseDefinition() = notRequired "GetBaseDefinition" genericMethodDefinition.Name - override __.GetMethodImplementationFlags() = notRequired "GetMethodImplementationFlags" genericMethodDefinition.Name - override __.MethodHandle = notRequired "MethodHandle" genericMethodDefinition.Name - override __.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" genericMethodDefinition.Name - override __.ReflectedType = notRequired "ReflectedType" genericMethodDefinition.Name - override __.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" genericMethodDefinition.Name - override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" genericMethodDefinition.Name - - - -type ProvidedTypeBuilder() = - static member MakeGenericType(genericTypeDefinition, genericArguments) = ProvidedSymbolType(Generic genericTypeDefinition, genericArguments) :> Type - static member MakeGenericMethod(genericMethodDefinition, genericArguments) = ProvidedSymbolMethod(genericMethodDefinition, genericArguments) :> MethodInfo - -[] -type ProvidedMeasureBuilder() = - - // TODO: this shouldn't be hardcoded, but without creating a dependency on FSharp.Compiler.Service - // there seems to be no way to check if a type abbreviation exists - let unitNamesTypeAbbreviations = - [ "meter"; "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb"; - "volt"; "farad"; "ohm"; "siemens"; "weber"; "tesla"; "henry" - "lumen"; "lux"; "becquerel"; "gray"; "sievert"; "katal" ] - |> Set.ofList - - let unitSymbolsTypeAbbreviations = - [ "m"; "kg"; "s"; "A"; "K"; "mol"; "cd"; "Hz"; "N"; "Pa"; "J"; "W"; "C" - "V"; "F"; "S"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H" ] - |> Set.ofList - - static let theBuilder = ProvidedMeasureBuilder() - static member Default = theBuilder - member __.One = typeof - member __.Product (m1,m2) = typedefof>.MakeGenericType [| m1;m2 |] - member __.Inverse m = typedefof>.MakeGenericType [| m |] - member b.Ratio (m1, m2) = b.Product(m1, b.Inverse m2) - member b.Square m = b.Product(m, m) - - // FSharp.Data change: if the unit is not a valid type, instead - // of assuming it's a type abbreviation, which may not be the case and cause a - // problem later on, check the list of valid abbreviations - member __.SI (m:string) = - let mLowerCase = m.ToLowerInvariant() - let abbreviation = - if unitNamesTypeAbbreviations.Contains mLowerCase then - Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames", mLowerCase) - elif unitSymbolsTypeAbbreviations.Contains m then - Some ("Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols", m) - else - None - match abbreviation with - | Some (ns, unitName) -> - ProvidedSymbolType - (ProvidedSymbolKind.FSharpTypeAbbreviation - (typeof.Assembly, - ns, - [| unitName |]), - []) :> Type - | None -> - typedefof>.Assembly.GetType("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames." + mLowerCase) - - member __.AnnotateType (basicType, annotation) = ProvidedSymbolType(Generic basicType, annotation) :> Type - - - -[] -type TypeContainer = - | Namespace of Assembly * string // namespace - | Type of System.Type - | TypeToBeDecided - -module GlobalProvidedAssemblyElementsTable = - let theTable = Dictionary>() - -type ProvidedTypeDefinition(container:TypeContainer,className : string, baseType : Type option) as this = - inherit Type() - - do match container, !ProvidedTypeDefinition.Logger with - | TypeContainer.Namespace _, Some logger -> logger (sprintf "Creating ProvidedTypeDefinition %s [%d]" className (System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode this)) - | _ -> () - - // state - let mutable attributes = - TypeAttributes.Public ||| - TypeAttributes.Class ||| - TypeAttributes.Sealed ||| - enum (int32 TypeProviderTypeAttributes.IsErased) - - - let mutable enumUnderlyingType = typeof - let mutable baseType = lazy baseType - let mutable membersKnown = ResizeArray() - let mutable membersQueue = ResizeArray<(unit -> list)>() - let mutable staticParams = [ ] - let mutable staticParamsApply = None - let mutable container = container - let mutable interfaceImpls = ResizeArray() - let mutable interfaceImplsDelayed = ResizeArray list>() - let mutable methodOverrides = ResizeArray() - - // members API - let getMembers() = - if membersQueue.Count > 0 then - let elems = membersQueue |> Seq.toArray // take a copy in case more elements get added - membersQueue.Clear() - for f in elems do - for i in f() do - membersKnown.Add i - match i with - | :? ProvidedProperty as p -> - if p.CanRead then membersKnown.Add (p.GetGetMethod true) - if p.CanWrite then membersKnown.Add (p.GetSetMethod true) - | :? ProvidedEvent as e -> - membersKnown.Add (e.GetAddMethod true) - membersKnown.Add (e.GetRemoveMethod true) - | _ -> () + let WriteILBinary (outfile, (args: options), modul) = + writeBinaryAndReportMappings (outfile, + args.ilg, args.pdbfile, (* args.signer, *) args.portablePDB, args.embeddedPDB, args.embedAllSource, + args.embedSourceList, args.sourceLink, args.emitTailcalls, args.deterministic, args.showTimes, args.dumpDebugInfo) modul + |> ignore + +//==================================================================================================== +// ProvidedAssembly - model for generated assembly fragments + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + + + type ILLocalBuilder(i: int) = + member _.LocalIndex = i + + type ILGenerator(methodName) = + let mutable locals = ResizeArray() + let mutable instrs = ResizeArray() + let mutable labelCount = 0 + let mutable labels = Dictionary() + + member _.Content = + { IsZeroInit = true + MaxStack = instrs.Count + Locals = locals.ToArray() + Code = + { Labels=labels + Instrs=instrs.ToArray() + Exceptions = [| |] // TODO + Locals = [| |] (* TODO ILLocalDebugInfo *) } + } + + member _.DeclareLocal(ty: ILType) = + let idx = locals.Count + let local = { Type = ty; IsPinned = false; DebugInfo = None } + locals.Add(local) + ILLocalBuilder(idx) + + member _.DefineLabel() = labelCount <- labelCount + 1; labelCount + member _.MarkLabel(label) = labels.[label] <- instrs.Count + member _.Emit(opcode) = instrs.Add(opcode) + override _.ToString() = "generator for " + methodName + + + type ILFieldBuilder(enclosing: ILType, nm: string, fty: ILType, attrs: FieldAttributes) = + + let mutable lit = None + let cattrs = ResizeArray() + + member _.SetConstant(lit2) = (lit <- Some lit2) + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + member _.FormalFieldRef = ILFieldRef(enclosing.TypeRef, nm, fty) + member this.FormalFieldSpec = ILFieldSpec(this.FormalFieldRef, enclosing) + member _.Name = nm + + member _.Content = + { Name = nm + FieldType = fty + LiteralValue = lit + Attributes = attrs + Offset = None + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken() } + override _.ToString() = "builder for " + nm + + type ILGenericParameterBuilder(nm, attrs: GenericParameterAttributes) = + + let mutable constraints = ResizeArray() + let cattrs = ResizeArray() + + member _.AddConstraint(ty) = constraints.Add(ty) + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + + member _.Content = + { Name=nm + Constraints= constraints.ToArray() + Attributes = attrs + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken() } + override _.ToString() = "builder for " + nm + + type ILParameterBuilder(ty: ILType) = + + let mutable attrs = ParameterAttributes.None + let mutable nm = UNone + let mutable dflt = UNone + let cattrs = ResizeArray() + + member _.SetData(attrs2,nm2) = attrs <- attrs2; nm <- USome nm2 + member _.SetConstant(obj) = dflt <- USome obj + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + + member _.Content = + { Name=nm + ParameterType=ty + Default=dflt + Attributes = attrs + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) } + + type ILMethodBuilder(enclosing: ILType, methodName: string, attrs: MethodAttributes, retty: ILType, argtys:ILType[]) = + + let ilParams = [| yield ILParameterBuilder(retty); for argty in argtys do yield ILParameterBuilder(argty) |] + let mutable implflags = MethodImplAttributes.IL + let gparams = ResizeArray() + let cattrs = ResizeArray() + let mutable body = None + + member _.DefineGenericParameter(name, attrs) = let eb = ILGenericParameterBuilder(name, attrs) in gparams.Add eb; eb + member _.DefineParameter(i, attrs, parameterName) = ilParams.[i].SetData(attrs, parameterName) ; ilParams.[i] + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + member _.GetILGenerator() = let ilg = ILGenerator(methodName) in body <- Some ilg; ilg + member _.FormalMethodRef = + let cc = (if ILMethodDef.ComputeIsStatic attrs then ILCallingConv.Static else ILCallingConv.Instance) + ILMethodRef (enclosing.TypeRef, cc, gparams.Count, methodName, argtys, retty) + member this.FormalMethodSpec = + ILMethodSpec(this.FormalMethodRef, enclosing, mkILFormalGenericArgs enclosing.TypeSpec.GenericArgs.Length gparams.Count) + + member _.Content = + { Token = genToken() + Name = methodName + Attributes = attrs + ImplAttributes = implflags + GenericParams = [| for x in gparams -> x.Content |] + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Parameters = [| for p in ilParams.[1..] -> p.Content |] + CallingConv = (if attrs &&& MethodAttributes.Static <> enum<_>(0) then ILCallingConv.Static else ILCallingConv.Instance) + Return = (let p = ilParams.[0].Content in { Type = p.ParameterType; CustomAttrs = p.CustomAttrs }) + Body = body |> Option.map (fun b -> b.Content) + IsEntryPoint = false } + override _.ToString() = "builder for " + methodName + + type ILPropertyBuilder(nm, attrs: PropertyAttributes, retty: ILType, argtys: ILType[]) = + + let mutable setMethod = None + let mutable getMethod = None + let cattrs = ResizeArray() - membersKnown.ToArray() - - // members API - let getInterfaces() = - if interfaceImplsDelayed.Count > 0 then - let elems = interfaceImplsDelayed |> Seq.toArray // take a copy in case more elements get added - interfaceImplsDelayed.Clear() - for f in elems do - for i in f() do - interfaceImpls.Add i + member _.SetGetMethod(mb: ILMethodBuilder) = getMethod <- Some mb + member _.SetSetMethod(mb: ILMethodBuilder) = setMethod <- Some mb + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + + member _.Content = + { Name=nm + CallingConv = + (if (getMethod.IsSome && getMethod.Value.Content.IsStatic) || + (setMethod.IsSome && setMethod.Value.Content.IsStatic) then + ILThisConvention.Static + else ILThisConvention.Instance) + Attributes = attrs + GetMethod = (getMethod |> Option.map (fun mb -> mb.FormalMethodRef)) + SetMethod = (setMethod |> Option.map (fun mb -> mb.FormalMethodRef)) + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + PropertyType=retty + Init= None // TODO if (attrs &&& PropertyAttributes.HasDefault) = 0 then None else + IndexParameterTypes=argtys + Token = genToken() } + override _.ToString() = "builder for " + nm + + type ILEventBuilder(nm, attrs: EventAttributes) = + + let mutable addMethod = None + let mutable removeMethod = None + let cattrs = ResizeArray() + + member _.SetAddOnMethod(mb: ILMethodBuilder) = addMethod <- Some mb + member _.SetRemoveOnMethod(mb: ILMethodBuilder) = removeMethod <- Some mb + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + member _.Content = + { Name = nm + Attributes = attrs + AddMethod = addMethod.Value.FormalMethodRef + RemoveMethod = removeMethod.Value.FormalMethodRef + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + Token = genToken()} + override _.ToString() = "builder for " + nm + + type ILTypeBuilder(scoref, nsp: string uoption, nm: string, attrs: TypeAttributes) = + + let mutable extends = None + let implements = ResizeArray() + let nestedTypes = ResizeArray() + let methods = ResizeArray() + let fields = ResizeArray() + let props = ResizeArray() + let events = ResizeArray() + let gparams = ResizeArray() + let methodImpls = ResizeArray() + let cattrs = ResizeArray() + + member _.ILTypeRef = ILTypeRef(scoref, nsp, nm) + member this.ILTypeSpec = ILTypeSpec(this.ILTypeRef, mkILFormalGenericArgs 0 gparams.Count) + member this.ILType = + match ILTypeDef.ComputeKind (int attrs) extends nsp nm with + | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> ILType.Value this.ILTypeSpec + | _ -> ILType.Boxed this.ILTypeSpec + + member this.DefineNestedType(name, attrs) = let tb = ILTypeBuilder(ILTypeRefScope.Nested this.ILTypeRef, UNone, name, attrs) in nestedTypes.Add tb; tb + + member this.DefineField(name, retty, attrs) = let fb = ILFieldBuilder(this.ILType, name, retty, attrs) in fields.Add fb; fb + member this.DefineMethod(name, attrs, retty, argtys) = let mb = ILMethodBuilder(this.ILType, name, attrs, retty, argtys) in methods.Add mb; mb + member this.DefineConstructor(attrs, argtys) = let mb = ILMethodBuilder(this.ILType, ".ctor", attrs ||| MethodAttributes.SpecialName ||| MethodAttributes.RTSpecialName, ILType.Void, argtys) in methods.Add mb; mb + member _.DefineProperty(name, attrs, propty, argtys) = let pb = ILPropertyBuilder(name, attrs, propty, argtys) in props.Add pb; pb + member _.DefineEvent(name, attrs) = let eb = ILEventBuilder(name, attrs) in events.Add eb; eb + member _.DefineMethodOverride(mimpl) = methodImpls.Add (mimpl) + member _.DefineGenericParameter(name, attrs) = let eb = ILGenericParameterBuilder(name, attrs) in gparams.Add eb; eb + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + member _.AddInterfaceImplementation(ty) = implements.Add(ty) + member this.DefineTypeInitializer () = let mb = ILMethodBuilder(this.ILType, ".cctor", MethodAttributes.Static ||| MethodAttributes.SpecialName, ILType.Void, [| |]) in methods.Add mb; mb + member _.SetParent ty = (extends <- Some ty) + member this.DefineDefaultConstructor(attrs, baseCtor: ILMethodSpec) = + let ctor = this.DefineConstructor(attrs, [| |]) + let ilg = ctor.GetILGenerator() + ilg.Emit(I_ldarg 0) + ilg.Emit(I_call (Normalcall, baseCtor, None)) + ilg.Emit(I_ret) + ctor + + + member _.Content = + { Namespace=nsp + Name=nm + GenericParams= [| for x in gparams -> x.Content |] + Implements = implements.ToArray() + Attributes = attrs + Layout=ILTypeDefLayout.Auto + Extends=extends + Token=genToken() + //SecurityDecls=emptyILSecurityDecls; + //HasSecurity=false; + NestedTypes = ILTypeDefs( lazy [| for x in nestedTypes -> let td = x.Content in td.Namespace, td.Name, lazy td |] ) + Fields = { new ILFieldDefs with member _.Entries = [| for x in fields -> x.Content |] } + Properties = { new ILPropertyDefs with member _.Entries = [| for x in props -> x.Content |] } + Events = { new ILEventDefs with member _.Entries = [| for x in events -> x.Content |] } + Methods = ILMethodDefs (lazy [| for x in methods -> x.Content |]) + MethodImpls = { new ILMethodImplDefs with member _.Entries = methodImpls.ToArray() } + CustomAttrs = mkILCustomAttrs (cattrs.ToArray()) + } + override _.ToString() = "builder for " + joinILTypeName nsp nm + + type ILModuleBuilder(scoref, moduleName, manifest) = + let typeDefs = ResizeArray() + let cattrs = ResizeArray() + + member _.DefineType(nsp, name, attrs) = let tb = ILTypeBuilder(ILTypeRefScope.Top scoref, nsp, name, attrs) in typeDefs.Add tb; tb + member _.SetCustomAttribute(ca) = cattrs.Add(ca) + + member _.Content = + { Manifest=manifest + Name=moduleName + SubsystemVersion = (4, 0) + UseHighEntropyVA = false + SubSystemFlags=3 + IsDLL=true + IsILOnly=true + Platform=None + StackReserveSize=None + Is32Bit=false + Is32BitPreferred=false + Is64Bit=false + PhysicalAlignment=512 + VirtualAlignment=0x2000 + ImageBase=0x034f0000 + MetadataVersion="" + Resources=ILResources (lazy [| |]) + TypeDefs = ILTypeDefs( lazy [| for x in typeDefs-> let td = x.Content in td.Namespace, td.Name, lazy td |] ) + CustomAttrs = { new ILCustomAttrs with member _.Entries = cattrs.ToArray() } + } + override _.ToString() = "builder for " + moduleName + + type ILAssemblyBuilder(assemblyName: AssemblyName, fileName, ilg) = + let manifest = + { Name = assemblyName.Name + AuxModuleHashAlgorithm = 0x8004 // SHA1 + PublicKey = UNone + Version = UNone + Locale = UNone + CustomAttrs = emptyILCustomAttrs + //AssemblyLongevity=ILAssemblyLongevity.Unspecified + DisableJitOptimizations = false + JitTracking = true + IgnoreSymbolStoreSequencePoints = false + Retargetable = false + ExportedTypes = ILExportedTypesAndForwarders (lazy [| |]) + EntrypointElsewhere=None } + let mb = ILModuleBuilder(ILScopeRef.Local, "MainModule", Some manifest) + member _.MainModule = mb + member _.Save() = + let il = mb.Content + let options: BinaryWriter.options = { ilg = ilg; pdbfile = None; portablePDB = false; embeddedPDB = false; embedAllSource = false; embedSourceList = []; sourceLink = ""; emitTailcalls = true; deterministic = false; showTimes = false; dumpDebugInfo = false } + BinaryWriter.WriteILBinary (fileName, options, il) + override _.ToString() = "builder for " + (assemblyName.ToString()) - interfaceImpls.ToArray() - - let mutable theAssembly = - lazy - match container with - | TypeContainer.Namespace (theAssembly, rootNamespace) -> - if theAssembly = null then failwith "Null assemblies not allowed" - if rootNamespace<>null && rootNamespace.Length=0 then failwith "Use 'null' for global namespace" - theAssembly - | TypeContainer.Type superTy -> superTy.Assembly - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let rootNamespace = - lazy - match container with - | TypeContainer.Namespace (_,rootNamespace) -> rootNamespace - | TypeContainer.Type enclosingTyp -> enclosingTyp.Namespace - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let declaringType = - lazy - match container with - | TypeContainer.Namespace _ -> null - | TypeContainer.Type enclosingTyp -> enclosingTyp - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let fullName = - lazy - match container with - | TypeContainer.Type declaringType -> declaringType.FullName + "+" + className - | TypeContainer.Namespace (_,namespaceName) -> - if namespaceName="" then failwith "use null for global namespace" - match namespaceName with - | null -> className - | _ -> namespaceName + "." + className - | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" className) - - let patchUpAddedMemberInfo (this:Type) (m:MemberInfo) = - match m with - | :? ProvidedConstructor as c -> c.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedMethod as m -> m.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedProperty as p -> p.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedEvent as e -> e.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo - | :? ProvidedTypeDefinition as t -> t.DeclaringTypeImpl <- this - | :? ProvidedLiteralField as l -> l.DeclaringTypeImpl <- this - | :? ProvidedField as l -> l.DeclaringTypeImpl <- this - | _ -> () - - let customAttributesImpl = CustomAttributesImpl() - - member __.AddXmlDocComputed xmlDocFunction = customAttributesImpl.AddXmlDocComputed xmlDocFunction - member __.AddXmlDocDelayed xmlDocFunction = customAttributesImpl.AddXmlDocDelayed xmlDocFunction - member __.AddXmlDoc xmlDoc = customAttributesImpl.AddXmlDoc xmlDoc - member __.AddObsoleteAttribute (message,?isError) = customAttributesImpl.AddObsolete (message,defaultArg isError false) - member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath) - member __.HideObjectMethods with set v = customAttributesImpl.HideObjectMethods <- v - member __.NonNullable with set v = customAttributesImpl.NonNullable <- v - member __.GetCustomAttributesDataImpl() = customAttributesImpl.GetCustomAttributesData() - member __.AddCustomAttribute attribute = customAttributesImpl.AddCustomAttribute attribute -#if FX_NO_CUSTOMATTRIBUTEDATA -#else - override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData() -#endif - member __.ResetEnclosingType (ty) = - container <- TypeContainer.Type ty - new (assembly:Assembly,namespaceName,className,baseType) = new ProvidedTypeDefinition(TypeContainer.Namespace (assembly,namespaceName), className, baseType) - new (className,baseType) = new ProvidedTypeDefinition(TypeContainer.TypeToBeDecided, className, baseType) - // state ops - - override __.UnderlyingSystemType = typeof - - member __.SetEnumUnderlyingType(ty) = enumUnderlyingType <- ty - - override __.GetEnumUnderlyingType() = if this.IsEnum then enumUnderlyingType else invalidOp "not enum type" - - member __.SetBaseType t = baseType <- lazy Some t - - member __.SetBaseTypeDelayed baseTypeFunction = baseType <- lazy (Some (baseTypeFunction())) - - member __.SetAttributes x = attributes <- x - - // Add MemberInfos - member __.AddMembersDelayed(membersFunction : unit -> list<#MemberInfo>) = - membersQueue.Add (fun () -> membersFunction() |> List.map (fun x -> patchUpAddedMemberInfo this x; x :> MemberInfo )) - - member __.AddMembers(memberInfos:list<#MemberInfo>) = (* strict *) - memberInfos |> List.iter (patchUpAddedMemberInfo this) // strict: patch up now - membersQueue.Add (fun () -> memberInfos |> List.map (fun x -> x :> MemberInfo)) - - member __.AddMember(memberInfo:MemberInfo) = - this.AddMembers [memberInfo] - - member __.AddMemberDelayed(memberFunction : unit -> #MemberInfo) = - this.AddMembersDelayed(fun () -> [memberFunction()]) - - member __.AddAssemblyTypesAsNestedTypesDelayed (assemblyf : unit -> System.Reflection.Assembly) = - let bucketByPath nodef tipf (items: (string list * 'Value) list) = - // Find all the items with an empty key list and call 'tipf' - let tips = - [ for (keylist,v) in items do - match keylist with - | [] -> yield tipf v - | _ -> () ] - - // Find all the items with a non-empty key list. Bucket them together by - // the first key. For each bucket, call 'nodef' on that head key and the bucket. - let nodes = - let buckets = new Dictionary<_,_>(10) - for (keylist,v) in items do - match keylist with - | [] -> () - | key::rest -> - buckets.[key] <- (rest,v) :: (if buckets.ContainsKey key then buckets.[key] else []); - - [ for (KeyValue(key,items)) in buckets -> nodef key items ] - - tips @ nodes - this.AddMembersDelayed (fun _ -> - let topTypes = [ for ty in assemblyf().GetTypes() do - if not ty.IsNested then - let namespaceParts = match ty.Namespace with null -> [] | s -> s.Split '.' |> Array.toList - yield namespaceParts, ty ] - let rec loop types = - types - |> bucketByPath - (fun namespaceComponent typesUnderNamespaceComponent -> - let t = ProvidedTypeDefinition(namespaceComponent, baseType = Some typeof) - t.AddMembers (loop typesUnderNamespaceComponent) - (t :> Type)) - (fun ty -> ty) - loop topTypes) - - /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function". - member __.DefineStaticParameters(staticParameters : list, apply : (string -> obj[] -> ProvidedTypeDefinition)) = - staticParams <- staticParameters - staticParamsApply <- Some apply - - /// Get ParameterInfo[] for the parametric type parameters (//s GetGenericParameters) - member __.GetStaticParameters() = [| for p in staticParams -> p :> ParameterInfo |] - - /// Instantiate parametrics type - member __.MakeParametricType(name:string,args:obj[]) = - if staticParams.Length>0 then - if staticParams.Length <> args.Length then - failwith (sprintf "ProvidedTypeDefinition: expecting %d static parameters but given %d for type %s" staticParams.Length args.Length (fullName.Force())) - match staticParamsApply with - | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called" - | Some f -> f name args + type ExpectedStackState = + | Empty = 1 + | Address = 2 + | Value = 3 - else - failwith (sprintf "ProvidedTypeDefinition: static parameters supplied but not expected for %s" (fullName.Force())) + type CodeGenerator(assemblyMainModule: ILModuleBuilder, + genUniqueTypeName: (unit -> string), + implicitCtorArgsAsFields: ILFieldBuilder list, + convTypeToTgt: Type -> Type, + transType: Type -> ILType, + transFieldSpec: FieldInfo -> ILFieldSpec, + transMeth: MethodInfo -> ILMethodSpec, + transMethRef: MethodInfo -> ILMethodRef, + transCtorSpec: ConstructorInfo -> ILMethodSpec, + ilg: ILGenerator, + localsMap:Dictionary, + parameterVars) = + + // TODO: this works over FSharp.Core 4.4.0.0 types and methods. These types need to be retargeted to the target runtime. + + let getTypeFromHandleMethod() = (convTypeToTgt typeof).GetMethod("GetTypeFromHandle") + let languagePrimitivesType() = (convTypeToTgt (typedefof>.Assembly.GetType("Microsoft.FSharp.Core.LanguagePrimitives"))) + let parseInt32Method() = (convTypeToTgt (languagePrimitivesType())).GetMethod "ParseInt32" + let decimalConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof; typeof; typeof; typeof |]) + let dateTimeConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof |]) + let dateTimeOffsetConstructor() = (convTypeToTgt typeof).GetConstructor([| typeof; typeof |]) + let timeSpanConstructor() = (convTypeToTgt typeof).GetConstructor([|typeof|]) + + let isEmpty s = (s = ExpectedStackState.Empty) + let isAddress s = (s = ExpectedStackState.Address) + let rec emitLambda(callSiteIlg: ILGenerator, v: Var, body: Expr, freeVars: seq, lambdaLocals: Dictionary<_, ILLocalBuilder>, parameters) = + let lambda: ILTypeBuilder = assemblyMainModule.DefineType(UNone, genUniqueTypeName(), TypeAttributes.Class) + let baseType = convTypeToTgt (typedefof>.MakeGenericType(v.Type, body.Type)) + lambda.SetParent(transType baseType) + let baseCtor = baseType.GetConstructor(bindAll, null, [| |], null) + if isNull baseCtor then failwithf "Couldn't find default constructor on %O" baseType + let ctor = lambda.DefineDefaultConstructor(MethodAttributes.Public, transCtorSpec baseCtor) + let decl = baseType.GetMethod "Invoke" + let paramTypes = [| for p in decl.GetParameters() -> transType p.ParameterType |] + let retType = transType decl.ReturnType + let invoke = lambda.DefineMethod("Invoke", MethodAttributes.Virtual ||| MethodAttributes.Final ||| MethodAttributes.Public, retType, paramTypes) + lambda.DefineMethodOverride + { Overrides = OverridesSpec(transMethRef decl, transType decl.DeclaringType) + OverrideBy = invoke.FormalMethodSpec } + + // promote free vars to fields + let fields = ResizeArray() + for v in freeVars do + let f = lambda.DefineField(v.Name, transType v.Type, FieldAttributes.Assembly) + //Debug.Assert (v.Name <> "formatValue") + fields.Add(v, f) + + let lambdaLocals = Dictionary() + + let ilg = invoke.GetILGenerator() + for (v, f) in fields do + let l = ilg.DeclareLocal(transType v.Type) + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, f.FormalFieldSpec)) + ilg.Emit(I_stloc l.LocalIndex) + lambdaLocals.[v] <- l + + let expectedState = if (retType = ILType.Void) then ExpectedStackState.Empty else ExpectedStackState.Value + let lambadParamVars = [| Var("this", typeof); v|] + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, lambdaLocals, lambadParamVars) + codeGen.EmitExpr (expectedState, body) + ilg.Emit(I_ret) + + callSiteIlg.Emit(I_newobj (ctor.FormalMethodSpec, None)) + for (v, f) in fields do + callSiteIlg.Emit(I_dup) + match localsMap.TryGetValue v with + | true, loc -> + callSiteIlg.Emit(I_ldloc loc.LocalIndex) + | false, _ -> + let index = parameters |> Array.findIndex ((=) v) + callSiteIlg.Emit(I_ldarg index) + callSiteIlg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, f.FormalFieldSpec)) + + and emitExpr expectedState expr = + let pop () = ilg.Emit(I_pop) + let popIfEmptyExpected s = if isEmpty s then pop() + let emitConvIfNecessary t1 = + if t1 = typeof then + ilg.Emit(I_conv DT_I2) + elif t1 = typeof then + ilg.Emit(I_conv DT_U2) + elif t1 = typeof then + ilg.Emit(I_conv DT_I1) + elif t1 = typeof then + ilg.Emit(I_conv DT_U1) + + /// emits given expression to corresponding IL + match expr with + | ForIntegerRangeLoop(loopVar, first, last, body) -> + // for(loopVar = first..last) body + let lb = + match localsMap.TryGetValue loopVar with + | true, lb -> lb + | false, _ -> + let lb = ilg.DeclareLocal(transType loopVar.Type) + localsMap.Add(loopVar, lb) + lb + + // loopVar = first + emitExpr ExpectedStackState.Value first + ilg.Emit(I_stloc lb.LocalIndex) + + let before = ilg.DefineLabel() + let after = ilg.DefineLabel() + + ilg.MarkLabel before + ilg.Emit(I_ldloc lb.LocalIndex) + + emitExpr ExpectedStackState.Value last + ilg.Emit(I_brcmp (I_bgt, after)) + + emitExpr ExpectedStackState.Empty body + + // loopVar++ + ilg.Emit(I_ldloc lb.LocalIndex) + ilg.Emit(mk_ldc 1) + ilg.Emit(I_add) + ilg.Emit(I_stloc lb.LocalIndex) + + ilg.Emit(I_br before) + ilg.MarkLabel(after) + + | NewArray(elementTy, elements) -> + ilg.Emit(mk_ldc (List.length elements)) + ilg.Emit(I_newarr (ILArrayShape.SingleDimensional, transType elementTy)) + + elements + |> List.iteri (fun i el -> + ilg.Emit(I_dup) + ilg.Emit(mk_ldc i) + emitExpr ExpectedStackState.Value el + ilg.Emit(I_stelem_any (ILArrayShape.SingleDimensional, transType elementTy))) + + popIfEmptyExpected expectedState + + | WhileLoop(cond, body) -> + let before = ilg.DefineLabel() + let after = ilg.DefineLabel() + + ilg.MarkLabel before + emitExpr ExpectedStackState.Value cond + ilg.Emit(I_brcmp (I_brfalse, after)) + emitExpr ExpectedStackState.Empty body + ilg.Emit(I_br before) + + ilg.MarkLabel after + + | Var v -> + if isEmpty expectedState then () else + + // Try to interpret this as a method parameter + let methIdx = parameterVars |> Array.tryFindIndex (fun p -> p = v) + match methIdx with + | Some idx -> + ilg.Emit((if isAddress expectedState then I_ldarga idx else I_ldarg idx) ) + | None -> + + // Try to interpret this as an implicit field in a class + let implicitCtorArgFieldOpt = implicitCtorArgsAsFields |> List.tryFind (fun f -> f.Name = v.Name) + match implicitCtorArgFieldOpt with + | Some ctorArgField -> + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, ctorArgField.FormalFieldSpec)) + | None -> + + // Try to interpret this as a local + match localsMap.TryGetValue v with + | true, localBuilder -> + let idx = localBuilder.LocalIndex + ilg.Emit(if isAddress expectedState then I_ldloca idx else I_ldloc idx) + | false, _ -> + failwith "unknown parameter/field" + + | Coerce (arg,ty) -> + // castClass may lead to observable side-effects - InvalidCastException + emitExpr ExpectedStackState.Value arg + let argTy = arg.Type + let targetTy = ty + if argTy.IsValueType && not targetTy.IsValueType then + ilg.Emit(I_box (transType argTy)) + elif not argTy.IsValueType && targetTy.IsValueType then + ilg.Emit(I_unbox_any (transType targetTy)) + else + ilg.Emit(I_castclass (transType targetTy)) - member __.DeclaringTypeImpl - with set x = - match container with TypeContainer.TypeToBeDecided -> () | _ -> failwith (sprintf "container type for '%s' was already set to '%s'" this.FullName x.FullName); - container <- TypeContainer.Type x + popIfEmptyExpected expectedState - // Implement overloads - override __.Assembly = theAssembly.Force() + | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray @> (None, [ty], [arr; index]) -> + // observable side-effect - IndexOutOfRangeException + emitExpr ExpectedStackState.Value arr + emitExpr ExpectedStackState.Value index + if isAddress expectedState then + ilg.Emit(I_ldelema (ILReadonly.ReadonlyAddress, ILArrayShape.SingleDimensional, transType ty)) + else + ilg.Emit(I_ldelem_any (ILArrayShape.SingleDimensional, transType ty)) - member __.SetAssembly assembly = theAssembly <- lazy assembly + popIfEmptyExpected expectedState - member __.SetAssemblyLazy assembly = theAssembly <- assembly + | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray2D @> (None, _ty, arr::indices) + | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray3D @> (None, _ty, arr::indices) + | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray4D @> (None, _ty, arr::indices) -> - override __.FullName = fullName.Force() + let meth = + let name = if isAddress expectedState then "Address" else "Get" + arr.Type.GetMethod(name) - override __.Namespace = rootNamespace.Force() + // observable side-effect - IndexOutOfRangeException + emitExpr ExpectedStackState.Value arr + for index in indices do + emitExpr ExpectedStackState.Value index - override __.BaseType = match baseType.Value with Some ty -> ty | None -> null - - // Constructors - override __.GetConstructors bindingAttr = - [| for m in this.GetMembers bindingAttr do - if m.MemberType = MemberTypes.Constructor then - yield (m :?> ConstructorInfo) |] - // Methods - override __.GetMethodImpl(name, bindingAttr, _binderBinder, _callConvention, _types, _modifiers) : MethodInfo = - let membersWithName = - [ for m in this.GetMembers(bindingAttr) do - if m.MemberType.HasFlag(MemberTypes.Method) && m.Name = name then - yield m ] - match membersWithName with - | [] -> null - | [meth] -> meth :?> MethodInfo - | _several -> failwith "GetMethodImpl. not support overloads" - - override __.GetMethods bindingAttr = - this.GetMembers bindingAttr - |> Array.filter (fun m -> m.MemberType.HasFlag(MemberTypes.Method)) - |> Array.map (fun m -> m :?> MethodInfo) - - // Fields - override __.GetField(name, bindingAttr) = - let fields = [| for m in this.GetMembers bindingAttr do - if m.MemberType.HasFlag(MemberTypes.Field) && (name = null || m.Name = name) then // REVIEW: name = null. Is that a valid query?! - yield m |] - if fields.Length > 0 then fields.[0] :?> FieldInfo else null - - override __.GetFields bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Field) then yield m :?> FieldInfo |] - - override __.GetInterface(_name, _ignoreCase) = notRequired "GetInterface" this.Name - - override __.GetInterfaces() = - [| yield! getInterfaces() |] - - member __.GetInterfaceImplementations() = - [| yield! getInterfaces() |] - - member __.AddInterfaceImplementation ityp = interfaceImpls.Add ityp - - member __.AddInterfaceImplementationsDelayed itypf = interfaceImplsDelayed.Add itypf - - member __.GetMethodOverrides() = - [| yield! methodOverrides |] - - member __.DefineMethodOverride (bodyMethInfo,declMethInfo) = methodOverrides.Add (bodyMethInfo, declMethInfo) - - // Events - override __.GetEvent(name, bindingAttr) = - let events = this.GetMembers bindingAttr - |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Event) && (name = null || m.Name = name)) - if events.Length > 0 then events.[0] :?> EventInfo else null - - override __.GetEvents bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Event) then yield downcast m |] - - // Properties - override __.GetProperties bindingAttr = - [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Property) then yield downcast m |] - - override __.GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers) = - if returnType <> null then failwith "Need to handle specified return type in GetPropertyImpl" - if types <> null then failwith "Need to handle specified parameter types in GetPropertyImpl" - if modifiers <> null then failwith "Need to handle specified modifiers in GetPropertyImpl" - if binder <> null then failwith "Need to handle binder in GetPropertyImpl" - let props = this.GetMembers bindingAttr |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Property) && (name = null || m.Name = name)) // Review: nam = null, valid query!? - if props.Length > 0 then - props.[0] :?> PropertyInfo - else - null - // Nested Types - override __.MakeArrayType() = ProvidedSymbolType(ProvidedSymbolKind.SDArray, [this]) :> Type - override __.MakeArrayType arg = ProvidedSymbolType(ProvidedSymbolKind.Array arg, [this]) :> Type - override __.MakePointerType() = ProvidedSymbolType(ProvidedSymbolKind.Pointer, [this]) :> Type - override __.MakeByRefType() = ProvidedSymbolType(ProvidedSymbolKind.ByRef, [this]) :> Type - - // FSharp.Data addition: this method is used by Debug.fs and QuotationBuilder.fs - // Emulate the F# type provider type erasure mechanism to get the - // actual (erased) type. We erase ProvidedTypes to their base type - // and we erase array of provided type to array of base type. In the - // case of generics all the generic type arguments are also recursively - // replaced with the erased-to types - static member EraseType(t:Type) : Type = - match t with - | :? ProvidedTypeDefinition as ptd when ptd.IsErased -> ProvidedTypeDefinition.EraseType t.BaseType - | t when t.IsArray -> - let rank = t.GetArrayRank() - let et = ProvidedTypeDefinition.EraseType (t.GetElementType()) - if rank = 0 then et.MakeArrayType() else et.MakeArrayType(rank) - | :? ProvidedSymbolType as sym when sym.IsFSharpUnitAnnotated -> - t.UnderlyingSystemType - | t when t.IsGenericType && not t.IsGenericTypeDefinition -> - let genericTypeDefinition = t.GetGenericTypeDefinition() - let genericArguments = t.GetGenericArguments() |> Array.map ProvidedTypeDefinition.EraseType - genericTypeDefinition.MakeGenericType(genericArguments) - | t -> t - - static member Logger : (string -> unit) option ref = ref None - - // The binding attributes are always set to DeclaredOnly ||| Static ||| Instance ||| Public when GetMembers is called directly by the F# compiler - // However, it's possible for the framework to generate other sets of flags in some corner cases (e.g. via use of `enum` with a provided type as the target) - override __.GetMembers bindingAttr = - let mems = - getMembers() - |> Array.filter (fun mem -> - let isStatic, isPublic = - match mem with - | :? FieldInfo as f -> f.IsStatic, f.IsPublic - | :? MethodInfo as m -> m.IsStatic, m.IsPublic - | :? ConstructorInfo as c -> c.IsStatic, c.IsPublic - | :? PropertyInfo as p -> - let m = if p.CanRead then p.GetGetMethod() else p.GetSetMethod() - m.IsStatic, m.IsPublic - | :? EventInfo as e -> - let m = e.GetAddMethod() - m.IsStatic, m.IsPublic - | :? Type as ty -> - true, ty.IsNestedPublic - | _ -> failwith (sprintf "Member %O is of unexpected type" mem) - bindingAttr.HasFlag(if isStatic then BindingFlags.Static else BindingFlags.Instance) && - ( - (bindingAttr.HasFlag(BindingFlags.Public) && isPublic) || (bindingAttr.HasFlag(BindingFlags.NonPublic) && not isPublic) - )) - - if bindingAttr.HasFlag(BindingFlags.DeclaredOnly) || this.BaseType = null then mems - else - // FSharp.Data change: just using this.BaseType is not enough in the case of CsvProvider, - // because the base type is CsvRow, so we have to erase recursively to CsvRow - let baseMems = (ProvidedTypeDefinition.EraseType this.BaseType).GetMembers bindingAttr - Array.append mems baseMems - - override __.GetNestedTypes bindingAttr = - this.GetMembers bindingAttr - |> Array.filter(fun m -> - m.MemberType.HasFlag(MemberTypes.NestedType) || - // Allow 'fake' nested types that are actually real .NET types - m.MemberType.HasFlag(MemberTypes.TypeInfo)) |> Array.map(fun m -> m :?> Type) - - override __.GetMember(name,mt,_bindingAttr) = - let mt = - if mt &&& MemberTypes.NestedType = MemberTypes.NestedType then - mt ||| MemberTypes.TypeInfo - else - mt - getMembers() |> Array.filter(fun m->0<>(int(m.MemberType &&& mt)) && m.Name = name) - - override __.GetNestedType(name, bindingAttr) = - let nt = this.GetMember(name, MemberTypes.NestedType ||| MemberTypes.TypeInfo, bindingAttr) - match nt.Length with - | 0 -> null - | 1 -> downcast nt.[0] - | _ -> failwith (sprintf "There is more than one nested type called '%s' in type '%s'" name this.FullName) - - // Attributes, etc.. - override __.GetAttributeFlagsImpl() = adjustTypeAttributes attributes this.IsNested - override this.IsValueTypeImpl() = match baseType.Value with Some ty -> ty.IsValueType | None -> false - override __.IsArrayImpl() = false - override __.IsByRefImpl() = false - override __.IsPointerImpl() = false - override __.IsPrimitiveImpl() = false - override __.IsCOMObjectImpl() = false - override __.HasElementTypeImpl() = false - override __.Name = className - override __.DeclaringType = declaringType.Force() - override __.MemberType = if this.IsNested then MemberTypes.NestedType else MemberTypes.TypeInfo - override __.GetHashCode() = rootNamespace.GetHashCode() ^^^ className.GetHashCode() - override __.Equals(that:obj) = - match that with - | null -> false - | :? ProvidedTypeDefinition as ti -> System.Object.ReferenceEquals(this,ti) - | _ -> false - - override __.GetGenericArguments() = [||] - override __.ToString() = this.Name - + //if isAddress expectedState then + // ilg.Emit(I_readonly) - override __.Module : Module = notRequired "Module" this.Name - override __.GUID = Guid.Empty - override __.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers) = null - override __.GetCustomAttributes(_inherit) = [| |] - override __.GetCustomAttributes(_attributeType, _inherit) = [| |] - override __.IsDefined(_attributeType: Type, _inherit) = false - - override __.GetElementType() = notRequired "Module" this.Name - override __.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "Module" this.Name - override __.AssemblyQualifiedName = notRequired "Module" this.Name - member __.IsErased - with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0 - and set v = - if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.IsErased) - else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) - - member __.SuppressRelocation - with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0 - and set v = - if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.SuppressRelocate) - else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) - -type AssemblyGenerator(assemblyFileName) = - let assemblyShortName = Path.GetFileNameWithoutExtension assemblyFileName - let assemblyName = AssemblyName assemblyShortName -#if FX_NO_LOCAL_FILESYSTEM - let assembly = - System.AppDomain.CurrentDomain.DefineDynamicAssembly(name=assemblyName,access=AssemblyBuilderAccess.Run) - let assemblyMainModule = - assembly.DefineDynamicModule("MainModule") -#else - let assembly = - System.AppDomain.CurrentDomain.DefineDynamicAssembly(name=assemblyName,access=(AssemblyBuilderAccess.Save ||| AssemblyBuilderAccess.Run),dir=Path.GetDirectoryName assemblyFileName) - let assemblyMainModule = - assembly.DefineDynamicModule("MainModule", Path.GetFileName assemblyFileName) -#endif - let typeMap = Dictionary(HashIdentity.Reference) - let typeMapExtra = Dictionary(HashIdentity.Structural) - let uniqueLambdaTypeName() = - // lambda name should be unique across all types that all type provider might contribute in result assembly - sprintf "Lambda%O" (Guid.NewGuid()) - - member __.Assembly = assembly :> Assembly - - /// Emit the given provided type definitions into an assembly and adjust 'Assembly' property of all type definitions to return that - /// assembly. - member __.Generate(providedTypeDefinitions:(ProvidedTypeDefinition * string list option) list) = - let ALL = BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Static ||| BindingFlags.Instance - // phase 1 - set assembly fields and emit type definitions - begin - let rec typeMembers (tb:TypeBuilder) (td : ProvidedTypeDefinition) = - for ntd in td.GetNestedTypes(ALL) do - nestedType tb ntd - - and nestedType (tb:TypeBuilder) (ntd : Type) = - match ntd with - | :? ProvidedTypeDefinition as pntd -> - if pntd.IsErased then invalidOp ("The nested provided type "+pntd.Name+" is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition") - // Adjust the attributes - we're codegen'ing this type as nested - let attributes = adjustTypeAttributes ntd.Attributes true - let ntb = tb.DefineNestedType(pntd.Name,attr=attributes) - pntd.SetAssembly null - typeMap.[pntd] <- ntb - typeMembers ntb pntd + ilg.Emit(mkNormalCall (transMeth meth)) + + popIfEmptyExpected expectedState + + + | FieldGet (None,field) when field.DeclaringType.IsEnum -> + if expectedState <> ExpectedStackState.Empty then + emitExpr expectedState (Expr.Value(field.GetRawConstantValue(), field.FieldType.GetEnumUnderlyingType())) + + | FieldGet (objOpt,field) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + if field.IsStatic then + ilg.Emit(I_ldsfld (ILVolatility.Nonvolatile, transFieldSpec field)) + else + ilg.Emit(I_ldfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, transFieldSpec field)) + + | FieldSet (objOpt,field,v) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + emitExpr ExpectedStackState.Value v + if field.IsStatic then + ilg.Emit(I_stsfld (ILVolatility.Nonvolatile, transFieldSpec field)) + else + ilg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, transFieldSpec field)) + + | Call (objOpt,meth,args) -> + objOpt |> Option.iter (fun e -> + let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value + emitExpr s e) + + for pe in args do + emitExpr ExpectedStackState.Value pe + + // Handle the case where this is a generic method instantiated at a type being compiled + let mappedMeth = transMeth meth + + match objOpt with + | Some obj when meth.IsAbstract || meth.IsVirtual -> + if obj.Type.IsValueType then + ilg.Emit(I_callconstraint (Normalcall, transType obj.Type, mappedMeth, None)) + else + ilg.Emit(I_callvirt (Normalcall, mappedMeth, None)) + | _ -> + ilg.Emit(mkNormalCall mappedMeth) + + let returnTypeIsVoid = (mappedMeth.FormalReturnType = ILType.Void) + match returnTypeIsVoid, (isEmpty expectedState) with + | false, true -> + // method produced something, but we don't need it + pop() + | true, false when expr.Type = typeof -> + // if we need result and method produce void and result should be unit - push null as unit value on stack + ilg.Emit(I_ldnull) | _ -> () - - for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitions do - match enclosingGeneratedTypeNames with - | None -> - // Filter out the additional TypeProviderTypeAttributes flags - let attributes = pt.Attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) - &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) - // Adjust the attributes - we're codegen'ing as non-nested - let attributes = adjustTypeAttributes attributes false - let tb = assemblyMainModule.DefineType(name=pt.FullName,attr=attributes) - pt.SetAssembly null - typeMap.[pt] <- tb - typeMembers tb pt - | Some ns -> - let otb,_ = - ((None,""),ns) ||> List.fold (fun (otb:TypeBuilder option,fullName) n -> - let fullName = if fullName = "" then n else fullName + "." + n - let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra.[fullName] else None - let tb = - match priorType with - | Some tbb -> tbb - | None -> - // OK, the implied nested type is not defined, define it now - let attributes = - TypeAttributes.Public ||| - TypeAttributes.Class ||| - TypeAttributes.Sealed - // Filter out the additional TypeProviderTypeAttributes flags - let attributes = adjustTypeAttributes attributes otb.IsSome - let tb = - match otb with - | None -> assemblyMainModule.DefineType(name=n,attr=attributes) - | Some (otb:TypeBuilder) -> otb.DefineNestedType(name=n,attr=attributes) - typeMapExtra.[fullName] <- tb - tb - (Some tb, fullName)) - nestedType otb.Value pt - end - let rec convType (ty:Type) = - match ty with - | :? ProvidedTypeDefinition as ptd -> - if typeMap.ContainsKey ptd then typeMap.[ptd] :> Type else ty - | _ -> - if ty.IsGenericType then ty.GetGenericTypeDefinition().MakeGenericType (Array.map convType (ty.GetGenericArguments())) - elif ty.HasElementType then - let ety = convType (ty.GetElementType()) - if ty.IsArray then - let rank = ty.GetArrayRank() - if rank = 1 then ety.MakeArrayType() - else ety.MakeArrayType rank - elif ty.IsPointer then ety.MakePointerType() - elif ty.IsByRef then ety.MakeByRefType() - else ty - else ty - let ctorMap = Dictionary(HashIdentity.Reference) - let methMap = Dictionary(HashIdentity.Reference) - let fieldMap = Dictionary(HashIdentity.Reference) + | NewObject (ctor,args) -> + for pe in args do + emitExpr ExpectedStackState.Value pe + ilg.Emit(I_newobj (transCtorSpec ctor, None)) + + popIfEmptyExpected expectedState + + | Value (obj, _ty) -> + let rec emitC (v:obj) = + match v with + | :? string as x -> ilg.Emit(I_ldstr x) + | :? int8 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? uint8 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int16 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? uint16 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int32 as x -> ilg.Emit(mk_ldc x) + | :? uint32 as x -> ilg.Emit(mk_ldc (int32 x)) + | :? int64 as x -> ilg.Emit(mk_ldc_i8 x) + | :? uint64 as x -> ilg.Emit(mk_ldc_i8 (int64 x)) + | :? char as x -> ilg.Emit(mk_ldc (int32 x)) + | :? bool as x -> ilg.Emit(mk_ldc (if x then 1 else 0)) + | :? float32 as x -> ilg.Emit(I_ldc (DT_R4, ILConst.R4 x)) + | :? float as x -> ilg.Emit(I_ldc(DT_R8, ILConst.R8 x)) + #if !FX_NO_GET_ENUM_UNDERLYING_TYPE + | :? Enum as x when x.GetType().GetEnumUnderlyingType() = typeof -> ilg.Emit(mk_ldc (unbox v)) + #endif + | :? Type as ty -> + ilg.Emit(I_ldtoken (ILToken.ILType (transType ty))) + ilg.Emit(mkNormalCall (transMeth (getTypeFromHandleMethod()))) + | :? decimal as x -> + let bits = Decimal.GetBits x + ilg.Emit(mk_ldc bits.[0]) + ilg.Emit(mk_ldc bits.[1]) + ilg.Emit(mk_ldc bits.[2]) + do + let sign = (bits.[3] &&& 0x80000000) <> 0 + ilg.Emit(if sign then mk_ldc 1 else mk_ldc 0) + do + let scale = (bits.[3] >>> 16) &&& 0x7F + ilg.Emit(mk_ldc scale) + ilg.Emit(I_newobj (transCtorSpec (decimalConstructor()), None)) + | :? DateTime as x -> + ilg.Emit(mk_ldc_i8 x.Ticks) + ilg.Emit(mk_ldc (int x.Kind)) + ilg.Emit(I_newobj (transCtorSpec (dateTimeConstructor()), None)) + | :? DateTimeOffset as x -> + ilg.Emit(mk_ldc_i8 x.Ticks) + ilg.Emit(mk_ldc_i8 x.Offset.Ticks) + ilg.Emit(I_newobj (transCtorSpec (timeSpanConstructor()), None)) + ilg.Emit(I_newobj (transCtorSpec (dateTimeOffsetConstructor()), None)) + | null -> ilg.Emit(I_ldnull) + | _ -> failwithf "unknown constant '%A' of type '%O' in generated method. You may need to avoid variable capture in a quotation specifying a type provider." v (v.GetType()) + if isEmpty expectedState then () + else emitC obj + + | Let(v,e,b) -> + let ty = transType v.Type + let lb = ilg.DeclareLocal ty + //printfn "declared local %d of original type %O and target type %O for variable %O" lb.LocalIndex v.Type ty v + localsMap.Add (v, lb) + emitExpr ExpectedStackState.Value e + ilg.Emit(I_stloc lb.LocalIndex) + emitExpr expectedState b + + | Sequential(e1, e2) -> + emitExpr ExpectedStackState.Empty e1 + emitExpr expectedState e2 + + | IfThenElse(cond, ifTrue, ifFalse) -> + let ifFalseLabel = ilg.DefineLabel() + let endLabel = ilg.DefineLabel() + + emitExpr ExpectedStackState.Value cond + + ilg.Emit(I_brcmp (I_brfalse, ifFalseLabel)) + + emitExpr expectedState ifTrue + ilg.Emit(I_br endLabel) + + ilg.MarkLabel(ifFalseLabel) + emitExpr expectedState ifFalse + + ilg.Emit(I_nop) + ilg.MarkLabel(endLabel) + +#if EMIT_TRY_WITH + | TryWith(body, _filterVar, _filterBody, catchVar, catchBody) -> + + let stres, ldres = + if isEmpty expectedState then ignore, ignore + else + let local = ilg.DeclareLocal (transType body.Type) + let stres = fun () -> ilg.Emit(I_stloc local.LocalIndex) + let ldres = fun () -> ilg.Emit(I_ldloc local.LocalIndex) + stres, ldres + + let exceptionVar = ilg.DeclareLocal(transType catchVar.Type) + locals.Add(catchVar, exceptionVar) + + let _exnBlock = ilg.BeginExceptionBlock() + + emitExpr expectedState body + stres() - let iterateTypes f = - let rec typeMembers (ptd : ProvidedTypeDefinition) = - let tb = typeMap.[ptd] + ilg.BeginCatchBlock(transType catchVar.Type) + ilg.Emit(I_stloc exceptionVar.LocalIndex) + emitExpr expectedState catchBody + stres() + ilg.EndExceptionBlock() + + ldres() +#endif + + | VarSet(v,e) -> + emitExpr ExpectedStackState.Value e + match localsMap.TryGetValue v with + | true, localBuilder -> + ilg.Emit(I_stloc localBuilder.LocalIndex) + | false, _ -> + failwith "unknown parameter/field in assignment. Only assignments to locals are currently supported by TypeProviderEmit" + | Lambda(v, body) -> + let lambdaLocals = Dictionary() + emitLambda(ilg, v, body, expr.GetFreeVars(), lambdaLocals, parameterVars) + popIfEmptyExpected expectedState + | n -> + failwithf "unknown expression '%A' in generated method" n + + member _.EmitExpr (expectedState, expr) = emitExpr expectedState expr + + //------------------------------------------------------------------------------------------------- + // AssemblyCompiler: the assembly compiler for generative type providers. + + /// Implements System.Reflection.Assembly backed by ILModuleReader over generated bytes + type AssemblyCompiler(targetAssembly: ProvidedAssembly, context: ProvidedTypesContext) = + + + let typeMap = Dictionary(HashIdentity.Reference) + let typeMapExtra = Dictionary(HashIdentity.Structural) + let ctorMap = Dictionary(HashIdentity.Reference) + let methMap = Dictionary(HashIdentity.Reference) + let fieldMap = Dictionary(HashIdentity.Reference) + let genUniqueTypeName() = + // lambda name should be unique across all types that all type provider might contribute in result assembly + sprintf "Lambda%O" (Guid.NewGuid()) + + let convTypeToTgt ty = context.ConvertSourceTypeToTarget ty + let rec defineNestedTypes (tb:ILTypeBuilder) (td: ProvidedTypeDefinition) = + Debug.Assert(td.BelongsToTargetModel, "expected a target ProvidedTypeDefinition in nested type") + for ntd in td.GetNestedTypes(bindAll) do + defineNestedType tb ntd + + and defineNestedType (tb:ILTypeBuilder) (ntd: Type) = + match ntd with + | :? ProvidedTypeDefinition as pntd -> + if pntd.IsErased then failwith ("The nested provided type "+pntd.Name+" is marked as erased and cannot be converted to a generated type. Set 'IsErased=false' on the ProvidedTypeDefinition") + Debug.Assert(pntd.BelongsToTargetModel, "expected a target ProvidedTypeDefinition in nested type") + // Adjust the attributes - we're codegen'ing this type as nested + let attributes = adjustTypeAttributes true ntd.Attributes + let ntb = tb.DefineNestedType(pntd.Name,attributes) + typeMap.[pntd] <- ntb + defineNestedTypes ntb pntd + | _ -> () + + let rec transType (ty:Type) = + if (match ty with :? ProvidedTypeDefinition as ty -> not ty.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" ty + if ty.IsGenericParameter then ILType.Var ty.GenericParameterPosition + elif ty.HasElementType then + let ety = transType (ty.GetElementType()) + if ty.IsArray then + let rank = ty.GetArrayRank() + if rank = 1 then ILType.Array(ILArrayShape.SingleDimensional, ety) + else ILType.Array(ILArrayShape.FromRank rank, ety) + elif ty.IsPointer then ILType.Ptr ety + elif ty.IsByRef then ILType.Byref ety + else failwith "unexpected type with element type" + elif ty.Namespace = "System" && ty.Name = "Void" then ILType.Void + elif ty.IsValueType then ILType.Value (transTypeSpec ty) + else ILType.Boxed (transTypeSpec ty) + + and transTypeSpec (ty: Type) = + if ty.IsGenericType then + ILTypeSpec(transTypeRef (ty.GetGenericTypeDefinition()), Array.map transType (ty.GetGenericArguments())) + else + ILTypeSpec(transTypeRef ty, [| |]) + + and transTypeRef (ty: Type) = + let ty = if ty.IsGenericType then ty.GetGenericTypeDefinition() else ty + ILTypeRef(transTypeRefScope ty, StructOption.ofObj (if ty.IsNested then null else ty.Namespace), ty.Name) + + and transTypeRefScope (ty: Type): ILTypeRefScope = + match ty.DeclaringType with + | null -> + if ty.Assembly = null then failwithf "null assembly for type %s" ty.FullName + ILTypeRefScope.Top (transScopeRef ty.Assembly) + | dt -> ILTypeRefScope.Nested (transTypeRef dt) + + and transScopeRef (assem: Assembly): ILScopeRef = + // Note: this simple equality check on assembly objects doesn't work on Mono, there must be some small difference in the + // implementation of equality on System.Assembly objects + // if assem = (targetAssembly :> Assembly) then ILScopeRef.Local + if assem.GetName().Name = targetAssembly.GetName().Name then ILScopeRef.Local + else ILScopeRef.Assembly (ILAssemblyRef.FromAssemblyName (assem.GetName())) + + let transCtorRef (m:ConstructorInfo) = + // Remove the generic instantiations to get the uninstantiated identity of the method + let m2 = m.GetDefinition() + let cc = (if m2.IsStatic then ILCallingConv.Static else ILCallingConv.Instance) + let ptys = [| for p in m2.GetParameters() -> transType p.ParameterType |] + ILMethodRef (transTypeRef m2.DeclaringType, cc, 0, m2.Name, ptys, ILType.Void) + + let transCtorSpec (f:ConstructorInfo) = + if (match f with :? ProvidedConstructor as f -> not f.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" f + match f with + | :? ProvidedConstructor as pc when ctorMap.ContainsKey pc -> ctorMap.[pc].FormalMethodSpec + | m -> ILMethodSpec(transCtorRef f, transType m.DeclaringType, [| |]) + + let transFieldSpec (f:FieldInfo) = + if (match f with :? ProvidedField as f -> not f.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" f + match f with + | :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf].FormalFieldSpec + | f -> + let f2 = f.GetDefinition() + ILFieldSpec(ILFieldRef (transTypeRef f2.DeclaringType, f2.Name, transType f2.FieldType), transType f.DeclaringType) + + let transMethRef (m:MethodInfo) = + if (match m with :? ProvidedMethod as m -> not m.BelongsToTargetModel | _ -> false) then failwithf "expected '%O' to belong to the target model" m + // Remove the generic instantiations to get the uninstantiated identity of the method + let m2 = m.GetDefinition() + let ptys = [| for p in m2.GetParameters() -> transType p.ParameterType |] + let genarity = (if m2.IsGenericMethod then m2.GetGenericArguments().Length else 0) + let cc = (if m2.IsStatic then ILCallingConv.Static else ILCallingConv.Instance) + ILMethodRef (transTypeRef m2.DeclaringType, cc, genarity, m2.Name, ptys, transType m2.ReturnType) + + let transMeth (m:MethodInfo): ILMethodSpec = + match m with + | :? ProvidedMethod as pm when methMap.ContainsKey pm -> methMap.[pm].FormalMethodSpec + | m -> + //Debug.Assert (m.Name <> "get_Item1" || m.DeclaringType.Name <> "Tuple`2") + let mref = transMethRef m + let minst = (if m.IsGenericMethod then Array.map transType (m.GetGenericArguments()) else [| |]) + ILMethodSpec(mref, transType m.DeclaringType, minst) + + let iterateTypes f providedTypeDefinitions = + let rec typeMembers (ptd: ProvidedTypeDefinition) = + let tb = typeMap.[ptd] f tb (Some ptd) - for ntd in ptd.GetNestedTypes(ALL) do + for ntd in ptd.GetNestedTypes(bindAll) do nestedType ntd - and nestedType (ntd : Type) = - match ntd with + and nestedType (ntd: Type) = + match ntd with | :? ProvidedTypeDefinition as pntd -> typeMembers pntd | _ -> () - - for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitions do - match enclosingGeneratedTypeNames with - | None -> - typeMembers pt - | Some ns -> - let _fullName = - ("",ns) ||> List.fold (fun fullName n -> - let fullName = if fullName = "" then n else fullName + "." + n - f typeMapExtra.[fullName] None - fullName) - nestedType pt - - - // phase 1b - emit base types - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - match ptd.BaseType with null -> () | bt -> tb.SetParent(convType bt)) - let defineCustomAttrs f (cattrs: IList) = + for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitions do + match enclosingGeneratedTypeNames with + | None -> + typeMembers pt + | Some ns -> + let _fullName = + ("",ns) ||> List.fold (fun fullName n -> + let fullName = if fullName = "" then n else fullName + "." + n + f typeMapExtra.[fullName] None + fullName) + nestedType pt + + let defineCustomAttrs f (cattrs: IList) = for attr in cattrs do let constructorArgs = [ for x in attr.ConstructorArguments -> x.Value ] - let namedProps,namedPropVals = [ for x in attr.NamedArguments do match x.MemberInfo with :? PropertyInfo as pi -> yield (pi, x.TypedValue.Value) | _ -> () ] |> List.unzip - let namedFields,namedFieldVals = [ for x in attr.NamedArguments do match x.MemberInfo with :? FieldInfo as pi -> yield (pi, x.TypedValue.Value) | _ -> () ] |> List.unzip - let cab = CustomAttributeBuilder(attr.Constructor, Array.ofList constructorArgs, Array.ofList namedProps, Array.ofList namedPropVals, Array.ofList namedFields, Array.ofList namedFieldVals) - f cab - - // phase 2 - emit member definitions - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - for cinfo in ptd.GetConstructors(ALL) do - match cinfo with - | :? ProvidedConstructor as pcinfo when not (ctorMap.ContainsKey pcinfo) -> - let cb = - if pcinfo.IsTypeInitializer then - if (cinfo.GetParameters()).Length <> 0 then failwith "Type initializer should not have parameters" - tb.DefineTypeInitializer() - else - let cb = tb.DefineConstructor(cinfo.Attributes, CallingConventions.Standard, [| for p in cinfo.GetParameters() -> convType p.ParameterType |]) - for (i,p) in cinfo.GetParameters() |> Seq.mapi (fun i x -> (i,x)) do - cb.DefineParameter(i+1, ParameterAttributes.None, p.Name) |> ignore - cb - ctorMap.[pcinfo] <- cb - | _ -> () - - if ptd.IsEnum then - tb.DefineField("value__", ptd.GetEnumUnderlyingType(), FieldAttributes.Public ||| FieldAttributes.SpecialName ||| FieldAttributes.RTSpecialName) - |> ignore - - for finfo in ptd.GetFields(ALL) do - let fieldInfo = - match finfo with - | :? ProvidedField as pinfo -> - Some (pinfo.Name, convType finfo.FieldType, finfo.Attributes, pinfo.GetCustomAttributesDataImpl(), None) - | :? ProvidedLiteralField as pinfo -> - Some (pinfo.Name, convType finfo.FieldType, finfo.Attributes, pinfo.GetCustomAttributesDataImpl(), Some (pinfo.GetRawConstantValue())) - | _ -> None - match fieldInfo with - | Some (name, ty, attr, cattr, constantVal) when not (fieldMap.ContainsKey finfo) -> - let fb = tb.DefineField(name, ty, attr) - if constantVal.IsSome then - fb.SetConstant constantVal.Value - defineCustomAttrs fb.SetCustomAttribute cattr - fieldMap.[finfo] <- fb - | _ -> () - for minfo in ptd.GetMethods(ALL) do - match minfo with - | :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo) -> - let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, convType minfo.ReturnType, [| for p in minfo.GetParameters() -> convType p.ParameterType |]) - for (i, p) in minfo.GetParameters() |> Seq.mapi (fun i x -> (i,x :?> ProvidedParameter)) do - // TODO: check why F# compiler doesn't emit default value when just p.Attributes is used (thus bad metadata is emitted) -// let mutable attrs = ParameterAttributes.None -// -// if p.IsOut then attrs <- attrs ||| ParameterAttributes.Out -// if p.HasDefaultParameterValue then attrs <- attrs ||| ParameterAttributes.Optional - - let pb = mb.DefineParameter(i+1, p.Attributes, p.Name) - if p.HasDefaultParameterValue then - do - let ctor = typeof.GetConstructor([|typeof|]) - let builder = new CustomAttributeBuilder(ctor, [|p.RawDefaultValue|]) - pb.SetCustomAttribute builder - do - let ctor = typeof.GetConstructor([||]) - let builder = new CustomAttributeBuilder(ctor, [||]) - pb.SetCustomAttribute builder - pb.SetConstant p.RawDefaultValue - methMap.[pminfo] <- mb - | _ -> () - - for ityp in ptd.GetInterfaceImplementations() do - tb.AddInterfaceImplementation ityp) - - // phase 3 - emit member code - iterateTypes (fun tb ptd -> - match ptd with - | None -> () - | Some ptd -> - let cattr = ptd.GetCustomAttributesDataImpl() - defineCustomAttrs tb.SetCustomAttribute cattr - // Allow at most one constructor, and use its arguments as the fields of the type - let ctors = - ptd.GetConstructors(ALL) // exclude type initializer - |> Seq.choose (function :? ProvidedConstructor as pcinfo when not pcinfo.IsTypeInitializer -> Some pcinfo | _ -> None) - |> Seq.toList - let implictCtorArgs = - match ctors |> List.filter (fun x -> x.IsImplicitCtor) with - | [] -> [] - | [ pcinfo ] -> [ for p in pcinfo.GetParameters() -> p ] - | _ -> failwith "at most one implicit constructor allowed" - - let implicitCtorArgsAsFields = - [ for ctorArg in implictCtorArgs -> - tb.DefineField(ctorArg.Name, convType ctorArg.ParameterType, FieldAttributes.Private) ] - - let rec emitLambda(callSiteIlg : ILGenerator, v : Quotations.Var, body : Expr, freeVars : seq, locals : Dictionary<_, LocalBuilder>, parameters) = - let lambda = assemblyMainModule.DefineType(uniqueLambdaTypeName(), TypeAttributes.Class) - let baseType = typedefof>.MakeGenericType(v.Type, body.Type) - lambda.SetParent(baseType) - let ctor = lambda.DefineDefaultConstructor(MethodAttributes.Public) - let decl = baseType.GetMethod "Invoke" - let paramTypes = [| for p in decl.GetParameters() -> p.ParameterType |] - let invoke = lambda.DefineMethod("Invoke", MethodAttributes.Virtual ||| MethodAttributes.Final ||| MethodAttributes.Public, decl.ReturnType, paramTypes) - lambda.DefineMethodOverride(invoke, decl) - - // promote free vars to fields - let fields = ResizeArray() - for v in freeVars do - let f = lambda.DefineField(v.Name, v.Type, FieldAttributes.Assembly) - fields.Add(v, f) - - let copyOfLocals = Dictionary() - - let ilg = invoke.GetILGenerator() - for (v, f) in fields do - let l = ilg.DeclareLocal(v.Type) - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldfld, f) - ilg.Emit(OpCodes.Stloc, l) - copyOfLocals.[v] <- l - - let expectedState = if (invoke.ReturnType = typeof) then ExpectedStackState.Empty else ExpectedStackState.Value - emitExpr (ilg, copyOfLocals, [| Quotations.Var("this", lambda); v|]) expectedState body - ilg.Emit(OpCodes.Ret) - - lambda.CreateType() |> ignore - - callSiteIlg.Emit(OpCodes.Newobj, ctor) - for (v, f) in fields do - callSiteIlg.Emit(OpCodes.Dup) - match locals.TryGetValue v with - | true, loc -> - callSiteIlg.Emit(OpCodes.Ldloc, loc) - | false, _ -> - let index = parameters |> Array.findIndex ((=) v) - callSiteIlg.Emit(OpCodes.Ldarg, index) - callSiteIlg.Emit(OpCodes.Stfld, f) - - and emitExpr (ilg: ILGenerator, locals:Dictionary, parameterVars) expectedState expr = - let pop () = ilg.Emit(OpCodes.Pop) - let popIfEmptyExpected s = if isEmpty s then pop() - let emitConvIfNecessary t1 = - if t1 = typeof then - ilg.Emit(OpCodes.Conv_I2) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_U2) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_I1) - elif t1 = typeof then - ilg.Emit(OpCodes.Conv_U1) - /// emits given expression to corresponding IL - let rec emit (expectedState : ExpectedStackState) (expr: Expr) = - match expr with - | ForIntegerRangeLoop(loopVar, first, last, body) -> - // for(loopVar = first..last) body - let lb = - match locals.TryGetValue loopVar with - | true, lb -> lb - | false, _ -> - let lb = ilg.DeclareLocal(convType loopVar.Type) - locals.Add(loopVar, lb) - lb - - // loopVar = first - emit ExpectedStackState.Value first - ilg.Emit(OpCodes.Stloc, lb) - - let before = ilg.DefineLabel() - let after = ilg.DefineLabel() - - ilg.MarkLabel before - ilg.Emit(OpCodes.Ldloc, lb) - - emit ExpectedStackState.Value last - ilg.Emit(OpCodes.Bgt, after) - - emit ExpectedStackState.Empty body - - // loopVar++ - ilg.Emit(OpCodes.Ldloc, lb) - ilg.Emit(OpCodes.Ldc_I4_1) - ilg.Emit(OpCodes.Add) - ilg.Emit(OpCodes.Stloc, lb) - - ilg.Emit(OpCodes.Br, before) - ilg.MarkLabel(after) - - | NewArray(elementTy, elements) -> - ilg.Emit(OpCodes.Ldc_I4, List.length elements) - ilg.Emit(OpCodes.Newarr, convType elementTy) - - elements - |> List.iteri (fun i el -> - ilg.Emit(OpCodes.Dup) - ilg.Emit(OpCodes.Ldc_I4, i) - emit ExpectedStackState.Value el - ilg.Emit(OpCodes.Stelem, convType elementTy) - ) - - popIfEmptyExpected expectedState - - | WhileLoop(cond, body) -> - let before = ilg.DefineLabel() - let after = ilg.DefineLabel() - - ilg.MarkLabel before - emit ExpectedStackState.Value cond - ilg.Emit(OpCodes.Brfalse, after) - emit ExpectedStackState.Empty body - ilg.Emit(OpCodes.Br, before) - - ilg.MarkLabel after - - | Var v -> - if isEmpty expectedState then () else - let methIdx = parameterVars |> Array.tryFindIndex (fun p -> p = v) - match methIdx with - | Some idx -> - ilg.Emit((if isAddress expectedState then OpCodes.Ldarga else OpCodes.Ldarg), idx) - | None -> - let implicitCtorArgFieldOpt = implicitCtorArgsAsFields |> List.tryFind (fun f -> f.Name = v.Name) - match implicitCtorArgFieldOpt with - | Some ctorArgField -> - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldfld, ctorArgField) - | None -> - match locals.TryGetValue v with - | true, localBuilder -> - ilg.Emit((if isAddress expectedState then OpCodes.Ldloca else OpCodes.Ldloc), localBuilder.LocalIndex) - | false, _ -> - failwith "unknown parameter/field" - - | Coerce (arg,ty) -> - // castClass may lead to observable side-effects - InvalidCastException - emit ExpectedStackState.Value arg - let argTy = convType arg.Type - let targetTy = convType ty - if argTy.IsValueType && not targetTy.IsValueType then - ilg.Emit(OpCodes.Box, argTy) - elif not argTy.IsValueType && targetTy.IsValueType then - ilg.Emit(OpCodes.Unbox_Any, targetTy) - // emit castclass if - // - targettype is not obj (assume this is always possible for ref types) - // AND - // - HACK: targettype is TypeBuilderInstantiationType - // (its implementation of IsAssignableFrom raises NotSupportedException so it will be safer to always emit castclass) - // OR - // - not (argTy :> targetTy) - elif targetTy <> typeof && (Misc.TypeBuilderInstantiationType.Equals(targetTy.GetType()) || not (targetTy.IsAssignableFrom(argTy))) then - ilg.Emit(OpCodes.Castclass, targetTy) - - popIfEmptyExpected expectedState - | SpecificCall <@ (-) @>(None, [t1; t2; _], [a1; a2]) -> - assert(t1 = t2) - emit ExpectedStackState.Value a1 - emit ExpectedStackState.Value a2 - if t1 = typeof then - ilg.Emit(OpCodes.Call, typeof.GetMethod "op_Subtraction") - else - ilg.Emit(OpCodes.Sub) - emitConvIfNecessary t1 + let transValue (o:obj) = + match o with + | :? Type as t -> box (transType t) + | v -> v + let namedProps = [ for x in attr.NamedArguments do match x.MemberInfo with :? PropertyInfo as pi -> yield ILCustomAttrNamedArg(pi.Name, transType x.TypedValue.ArgumentType, x.TypedValue.Value) | _ -> () ] + let namedFields = [ for x in attr.NamedArguments do match x.MemberInfo with :? FieldInfo as pi -> yield ILCustomAttrNamedArg(pi.Name, transType x.TypedValue.ArgumentType, x.TypedValue.Value) | _ -> () ] + let ca = mkILCustomAttribMethRef (transCtorSpec attr.Constructor, constructorArgs, namedProps, namedFields) + f ca + + member _.Compile(isHostedExecution) = + let providedTypeDefinitionsT = targetAssembly.GetTheTypes() |> Array.collect (fun (tds,nsps) -> Array.map (fun td -> (td,nsps)) tds) + let ilg = context.ILGlobals + let assemblyName = targetAssembly.GetName() + let assemblyFileName = targetAssembly.Location + let assemblyBuilder = ILAssemblyBuilder(assemblyName, assemblyFileName, ilg) + let assemblyMainModule = assemblyBuilder.MainModule + + // Set the Assembly on the type definitions + for (ptdT,_) in providedTypeDefinitionsT do + if not ptdT.BelongsToTargetModel then failwithf "expected '%O' to belong to the target model" ptdT + ptdT.SetAssemblyInternal (K (targetAssembly :> Assembly)) + + // phase 1 - define types + for (pt,enclosingGeneratedTypeNames) in providedTypeDefinitionsT do + match enclosingGeneratedTypeNames with + | None -> + // Filter out the additional TypeProviderTypeAttributes flags + let attributes = pt.Attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) + &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased)) + // Adjust the attributes - we're codegen'ing as non-nested + let attributes = adjustTypeAttributes false attributes + let tb = assemblyMainModule.DefineType(StructOption.ofObj pt.Namespace, pt.Name, attributes) + typeMap.[pt] <- tb + defineNestedTypes tb pt + + | Some ns -> + let otb,_ = + ((None,""),ns) ||> List.fold (fun (otb:ILTypeBuilder option,fullName) n -> + let fullName = if fullName = "" then n else fullName + "." + n + let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra.[fullName] else None + let tb = + match priorType with + | Some tbb -> tbb + | None -> + // OK, the implied nested type is not defined, define it now + let attributes = TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.Sealed + let attributes = adjustTypeAttributes otb.IsSome attributes + let tb = + match otb with + | None -> + let nsp, n = splitILTypeName n + assemblyMainModule.DefineType(nsp, n,attributes) + | Some (otb:ILTypeBuilder) -> + otb.DefineNestedType(n,attributes) + typeMapExtra.[fullName] <- tb + tb + (Some tb, fullName)) + defineNestedType otb.Value pt + + + // phase 1b - emit base types + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + match ptdT.BaseType with + | null -> () + | bt -> tb.SetParent(transType bt)) + + // phase 2 - emit member definitions + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + for cinfo in ptdT.GetConstructors(bindAll) do + match cinfo with + | :? ProvidedConstructor as pcinfo when not (ctorMap.ContainsKey pcinfo) -> + let cb = + if pcinfo.IsTypeInitializer then + if (cinfo.GetParameters()).Length <> 0 then failwith "Type initializer should not have parameters" + tb.DefineTypeInitializer() + else + let cb = tb.DefineConstructor(cinfo.Attributes, [| for p in cinfo.GetParameters() -> transType p.ParameterType |]) + for (i,p) in cinfo.GetParameters() |> Seq.mapi (fun i x -> (i,x)) do + cb.DefineParameter(i+1, ParameterAttributes.None, p.Name) |> ignore + cb + ctorMap.[pcinfo] <- cb + | _ -> () - popIfEmptyExpected expectedState + if ptdT.IsEnum then + tb.DefineField("value__", transType (ptdT.GetEnumUnderlyingType()), FieldAttributes.Public ||| FieldAttributes.SpecialName ||| FieldAttributes.RTSpecialName) + |> ignore + + for finfo in ptdT.GetFields(bindAll) do + match finfo with + | :? ProvidedField as pinfo -> + let fb = tb.DefineField(finfo.Name, transType finfo.FieldType, finfo.Attributes) + + if finfo.IsLiteral then + fb.SetConstant (pinfo.GetRawConstantValue()) + + defineCustomAttrs fb.SetCustomAttribute (pinfo.GetCustomAttributesData()) + + fieldMap.[finfo] <- fb - | SpecificCall <@ (/) @> (None, [t1; t2; _], [a1; a2]) -> - assert (t1 = t2) - emit ExpectedStackState.Value a1 - emit ExpectedStackState.Value a2 - if t1 = typeof then - ilg.Emit(OpCodes.Call, typeof.GetMethod "op_Division") - else - match Type.GetTypeCode t1 with - | TypeCode.UInt32 - | TypeCode.UInt64 - | TypeCode.UInt16 - | TypeCode.Byte - | _ when t1 = typeof -> ilg.Emit (OpCodes.Div_Un) - | _ -> ilg.Emit(OpCodes.Div) - - emitConvIfNecessary t1 - - popIfEmptyExpected expectedState - - | SpecificCall <@ int @>(None, [sourceTy], [v]) -> - emit ExpectedStackState.Value v - match Type.GetTypeCode(sourceTy) with - | TypeCode.String -> - ilg.Emit(OpCodes.Call, Misc.ParseInt32Method) - | TypeCode.Single - | TypeCode.Double - | TypeCode.Int64 - | TypeCode.UInt64 - | TypeCode.UInt16 - | TypeCode.Char - | TypeCode.Byte - | _ when sourceTy = typeof || sourceTy = typeof -> - ilg.Emit(OpCodes.Conv_I4) - | TypeCode.Int32 - | TypeCode.UInt32 - | TypeCode.Int16 - | TypeCode.SByte -> () // no op - | _ -> failwith "TODO: search for op_Explicit on sourceTy" - - | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray @> (None, [ty], [arr; index]) -> - // observable side-effect - IndexOutOfRangeException - emit ExpectedStackState.Value arr - emit ExpectedStackState.Value index - if isAddress expectedState then - ilg.Emit(OpCodes.Readonly) - ilg.Emit(OpCodes.Ldelema, convType ty) - else - ilg.Emit(OpCodes.Ldelem, convType ty) - - popIfEmptyExpected expectedState - - | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray2D @> (None, _ty, arr::indices) - | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray3D @> (None, _ty, arr::indices) - | SpecificCall <@ LanguagePrimitives.IntrinsicFunctions.GetArray4D @> (None, _ty, arr::indices) -> - - let meth = - let name = if isAddress expectedState then "Address" else "Get" - arr.Type.GetMethod(name) - - // observable side-effect - IndexOutOfRangeException - emit ExpectedStackState.Value arr - for index in indices do - emit ExpectedStackState.Value index - - if isAddress expectedState then - ilg.Emit(OpCodes.Readonly) - - ilg.Emit(OpCodes.Call, meth) - - popIfEmptyExpected expectedState - - | FieldGet (objOpt,field) -> - match field with - | :? ProvidedLiteralField as plf when plf.DeclaringType.IsEnum -> - if expectedState <> ExpectedStackState.Empty then - emit expectedState (Expr.Value(field.GetRawConstantValue(), field.FieldType.GetEnumUnderlyingType())) - | _ -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - let field = - match field with - | :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf] :> FieldInfo - | m -> m - if field.IsStatic then - ilg.Emit(OpCodes.Ldsfld, field) - else - ilg.Emit(OpCodes.Ldfld, field) - - | FieldSet (objOpt,field,v) -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - emit ExpectedStackState.Value v - let field = match field with :? ProvidedField as pf when fieldMap.ContainsKey pf -> fieldMap.[pf] :> FieldInfo | m -> m - if field.IsStatic then - ilg.Emit(OpCodes.Stsfld, field) - else - ilg.Emit(OpCodes.Stfld, field) - | Call (objOpt,meth,args) -> - match objOpt with - | None -> () - | Some e -> - let s = if e.Type.IsValueType then ExpectedStackState.Address else ExpectedStackState.Value - emit s e - for pe in args do - emit ExpectedStackState.Value pe - let getMeth (m:MethodInfo) = match m with :? ProvidedMethod as pm when methMap.ContainsKey pm -> methMap.[pm] :> MethodInfo | m -> m - // Handle the case where this is a generic method instantiated at a type being compiled - let mappedMeth = - if meth.IsGenericMethod then - let args = meth.GetGenericArguments() |> Array.map convType - let gmd = meth.GetGenericMethodDefinition() |> getMeth - gmd.GetGenericMethodDefinition().MakeGenericMethod args - elif meth.DeclaringType.IsGenericType then - let gdty = convType (meth.DeclaringType.GetGenericTypeDefinition()) - let gdtym = gdty.GetMethods() |> Seq.find (fun x -> x.Name = meth.Name) - assert (gdtym <> null) // ?? will never happen - if method is not found - KeyNotFoundException will be raised - let dtym = - match convType meth.DeclaringType with - | :? TypeBuilder as dty -> TypeBuilder.GetMethod(dty, gdtym) - | dty -> MethodBase.GetMethodFromHandle(meth.MethodHandle, dty.TypeHandle) :?> _ - - assert (dtym <> null) - dtym - else - getMeth meth - match objOpt with - | Some obj when mappedMeth.IsAbstract || mappedMeth.IsVirtual -> - if obj.Type.IsValueType then ilg.Emit(OpCodes.Constrained, convType obj.Type) - ilg.Emit(OpCodes.Callvirt, mappedMeth) - | _ -> - ilg.Emit(OpCodes.Call, mappedMeth) - - let returnTypeIsVoid = mappedMeth.ReturnType = typeof - match returnTypeIsVoid, (isEmpty expectedState) with - | false, true -> - // method produced something, but we don't need it - pop() - | true, false when expr.Type = typeof -> - // if we need result and method produce void and result should be unit - push null as unit value on stack - ilg.Emit(OpCodes.Ldnull) | _ -> () - | NewObject (ctor,args) -> - for pe in args do - emit ExpectedStackState.Value pe - let meth = match ctor with :? ProvidedConstructor as pc when ctorMap.ContainsKey pc -> ctorMap.[pc] :> ConstructorInfo | c -> c - ilg.Emit(OpCodes.Newobj, meth) - - popIfEmptyExpected expectedState - - | Value (obj, _ty) -> - let rec emitC (v:obj) = - match v with - | :? string as x -> ilg.Emit(OpCodes.Ldstr, x) - | :? int8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? uint8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int8 x)) - | :? int16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? uint16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int16 x)) - | :? int32 as x -> ilg.Emit(OpCodes.Ldc_I4, x) - | :? uint32 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? int64 as x -> ilg.Emit(OpCodes.Ldc_I8, x) - | :? uint64 as x -> ilg.Emit(OpCodes.Ldc_I8, int64 x) - | :? char as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x) - | :? bool as x -> ilg.Emit(OpCodes.Ldc_I4, if x then 1 else 0) - | :? float32 as x -> ilg.Emit(OpCodes.Ldc_R4, x) - | :? float as x -> ilg.Emit(OpCodes.Ldc_R8, x) -#if FX_NO_GET_ENUM_UNDERLYING_TYPE -#else - | :? System.Enum as x when x.GetType().GetEnumUnderlyingType() = typeof -> ilg.Emit(OpCodes.Ldc_I4, unbox v) -#endif - | :? Type as ty -> - ilg.Emit(OpCodes.Ldtoken, convType ty) - ilg.Emit(OpCodes.Call, Misc.GetTypeFromHandleMethod) - | :? decimal as x -> - let bits = System.Decimal.GetBits x - ilg.Emit(OpCodes.Ldc_I4, bits.[0]) - ilg.Emit(OpCodes.Ldc_I4, bits.[1]) - ilg.Emit(OpCodes.Ldc_I4, bits.[2]) - do - let sign = (bits.[3] &&& 0x80000000) <> 0 - ilg.Emit(if sign then OpCodes.Ldc_I4_1 else OpCodes.Ldc_I4_0) - do - let scale = byte ((bits.[3] >>> 16) &&& 0x7F) - ilg.Emit(OpCodes.Ldc_I4_S, scale) - ilg.Emit(OpCodes.Newobj, Misc.DecimalConstructor) - | :? DateTime as x -> - ilg.Emit(OpCodes.Ldc_I8, x.Ticks) - ilg.Emit(OpCodes.Ldc_I4, int x.Kind) - ilg.Emit(OpCodes.Newobj, Misc.DateTimeConstructor) - | :? DateTimeOffset as x -> - ilg.Emit(OpCodes.Ldc_I8, x.Ticks) - ilg.Emit(OpCodes.Ldc_I8, x.Offset.Ticks) - ilg.Emit(OpCodes.Newobj, Misc.TimeSpanConstructor) - ilg.Emit(OpCodes.Newobj, Misc.DateTimeOffsetConstructor) - | null -> ilg.Emit(OpCodes.Ldnull) - | _ -> failwithf "unknown constant '%A' in generated method" v - if isEmpty expectedState then () - else emitC obj - - | Let(v,e,b) -> - let lb = ilg.DeclareLocal (convType v.Type) - locals.Add (v, lb) - emit ExpectedStackState.Value e - ilg.Emit(OpCodes.Stloc, lb.LocalIndex) - emit expectedState b - - | Sequential(e1, e2) -> - emit ExpectedStackState.Empty e1 - emit expectedState e2 - - | IfThenElse(cond, ifTrue, ifFalse) -> - let ifFalseLabel = ilg.DefineLabel() - let endLabel = ilg.DefineLabel() - - emit ExpectedStackState.Value cond - - ilg.Emit(OpCodes.Brfalse, ifFalseLabel) - - emit expectedState ifTrue - ilg.Emit(OpCodes.Br, endLabel) - - ilg.MarkLabel(ifFalseLabel) - emit expectedState ifFalse - - ilg.Emit(OpCodes.Nop) - ilg.MarkLabel(endLabel) - - | TryWith(body, _filterVar, _filterBody, catchVar, catchBody) -> - - let stres, ldres = - if isEmpty expectedState then ignore, ignore - else - let local = ilg.DeclareLocal (convType body.Type) - let stres = fun () -> ilg.Emit(OpCodes.Stloc, local) - let ldres = fun () -> ilg.Emit(OpCodes.Ldloc, local) - stres, ldres - - let exceptionVar = ilg.DeclareLocal(convType catchVar.Type) - locals.Add(catchVar, exceptionVar) - - let _exnBlock = ilg.BeginExceptionBlock() - - emit expectedState body - stres() - - ilg.BeginCatchBlock(convType catchVar.Type) - ilg.Emit(OpCodes.Stloc, exceptionVar) - emit expectedState catchBody - stres() - ilg.EndExceptionBlock() - - ldres() - - | VarSet(v,e) -> - emit ExpectedStackState.Value e - match locals.TryGetValue v with - | true, localBuilder -> - ilg.Emit(OpCodes.Stloc, localBuilder.LocalIndex) - | false, _ -> - failwith "unknown parameter/field in assignment. Only assignments to locals are currently supported by TypeProviderEmit" - | Lambda(v, body) -> - emitLambda(ilg, v, body, expr.GetFreeVars(), locals, parameterVars) - popIfEmptyExpected expectedState - | n -> - failwith (sprintf "unknown expression '%A' in generated method" n) - emit expectedState expr - - - // Emit the constructor (if any) - for pcinfo in ctors do - assert ctorMap.ContainsKey pcinfo - let cb = ctorMap.[pcinfo] - let cattr = pcinfo.GetCustomAttributesDataImpl() - defineCustomAttrs cb.SetCustomAttribute cattr - let ilg = cb.GetILGenerator() - let locals = Dictionary() - let parameterVars = - [| yield Var("this", pcinfo.DeclaringType) - for p in pcinfo.GetParameters() do - yield Var(p.Name, p.ParameterType) |] - let parameters = - [| for v in parameterVars -> Expr.Var v |] - match pcinfo.GetBaseConstructorCallInternal true with - | None -> - ilg.Emit(OpCodes.Ldarg_0) - let cinfo = ptd.BaseType.GetConstructor(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance, null, [| |], null) - ilg.Emit(OpCodes.Call,cinfo) - | Some f -> - // argExprs should always include 'this' - let (cinfo,argExprs) = f (Array.toList parameters) - for argExpr in argExprs do - emitExpr (ilg, locals, parameterVars) ExpectedStackState.Value argExpr - ilg.Emit(OpCodes.Call,cinfo) - - if pcinfo.IsImplicitCtor then - for ctorArgsAsFieldIdx,ctorArgsAsField in List.mapi (fun i x -> (i,x)) implicitCtorArgsAsFields do - ilg.Emit(OpCodes.Ldarg_0) - ilg.Emit(OpCodes.Ldarg, ctorArgsAsFieldIdx+1) - ilg.Emit(OpCodes.Stfld, ctorArgsAsField) - else - let code = pcinfo.GetInvokeCodeInternal true - let code = code parameters - emitExpr (ilg, locals, parameterVars) ExpectedStackState.Empty code - ilg.Emit(OpCodes.Ret) - - match ptd.GetConstructors(ALL) |> Seq.tryPick (function :? ProvidedConstructor as pc when pc.IsTypeInitializer -> Some pc | _ -> None) with - | None -> () - | Some pc -> - let cb = ctorMap.[pc] - let ilg = cb.GetILGenerator() - let cattr = pc.GetCustomAttributesDataImpl() - defineCustomAttrs cb.SetCustomAttribute cattr - let expr = pc.GetInvokeCodeInternal true [||] - emitExpr(ilg, new Dictionary<_, _>(), [||]) ExpectedStackState.Empty expr - ilg.Emit OpCodes.Ret - - // Emit the methods - for minfo in ptd.GetMethods(ALL) do - match minfo with - | :? ProvidedMethod as pminfo -> - let mb = methMap.[pminfo] - let ilg = mb.GetILGenerator() - let cattr = pminfo.GetCustomAttributesDataImpl() - defineCustomAttrs mb.SetCustomAttribute cattr - - let parameterVars = - [| if not pminfo.IsStatic then - yield Var("this", pminfo.DeclaringType) - for p in pminfo.GetParameters() do - yield Var(p.Name, p.ParameterType) |] - let parameters = - [| for v in parameterVars -> Expr.Var v |] - - let expr = pminfo.GetInvokeCodeInternal true parameters - - let locals = Dictionary() - //printfn "Emitting linqCode for %s::%s, code = %s" pminfo.DeclaringType.FullName pminfo.Name (try linqCode.ToString() with _ -> "") - - - let expectedState = if (minfo.ReturnType = typeof) then ExpectedStackState.Empty else ExpectedStackState.Value - emitExpr (ilg, locals, parameterVars) expectedState expr - ilg.Emit OpCodes.Ret - | _ -> () - - for (bodyMethInfo,declMethInfo) in ptd.GetMethodOverrides() do - let bodyMethBuilder = methMap.[bodyMethInfo] - tb.DefineMethodOverride(bodyMethBuilder,declMethInfo) - - for evt in ptd.GetEvents(ALL) |> Seq.choose (function :? ProvidedEvent as pe -> Some pe | _ -> None) do - let eb = tb.DefineEvent(evt.Name, evt.Attributes, evt.EventHandlerType) - defineCustomAttrs eb.SetCustomAttribute (evt.GetCustomAttributesDataImpl()) - eb.SetAddOnMethod(methMap.[evt.GetAddMethod(true) :?> _]) - eb.SetRemoveOnMethod(methMap.[evt.GetRemoveMethod(true) :?> _]) - // TODO: add raiser - - for pinfo in ptd.GetProperties(ALL) |> Seq.choose (function :? ProvidedProperty as pe -> Some pe | _ -> None) do - let pb = tb.DefineProperty(pinfo.Name, pinfo.Attributes, convType pinfo.PropertyType, [| for p in pinfo.GetIndexParameters() -> convType p.ParameterType |]) - let cattr = pinfo.GetCustomAttributesDataImpl() - defineCustomAttrs pb.SetCustomAttribute cattr - if pinfo.CanRead then - let minfo = pinfo.GetGetMethod(true) - pb.SetGetMethod (methMap.[minfo :?> ProvidedMethod ]) - if pinfo.CanWrite then - let minfo = pinfo.GetSetMethod(true) - pb.SetSetMethod (methMap.[minfo :?> ProvidedMethod ])) + for minfo in ptdT.GetMethods(bindAll) do + match minfo with + | :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo) -> + let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, transType minfo.ReturnType, [| for p in minfo.GetParameters() -> transType p.ParameterType |]) + for (i, p) in minfo.GetParameters() |> Seq.mapi (fun i x -> (i,x :?> ProvidedParameter)) do - // phase 4 - complete types - iterateTypes (fun tb _ptd -> tb.CreateType() |> ignore) + let pb = mb.DefineParameter(i+1, p.Attributes, p.Name) + if p.HasDefaultParameterValue then + let ctor = typeof.GetConstructor([|typeof|]) + let ca = mkILCustomAttribMethRef (transCtorSpec ctor, [p.RawDefaultValue], [], []) + pb.SetCustomAttribute ca -#if FX_NO_LOCAL_FILESYSTEM -#else - assembly.Save (Path.GetFileName assemblyFileName) -#endif + let ctor = typeof.GetConstructor([||]) + let ca = mkILCustomAttribMethRef (transCtorSpec ctor, [], [], []) + pb.SetCustomAttribute ca - let assemblyLoadedInMemory = assemblyMainModule.Assembly + pb.SetConstant p.RawDefaultValue - iterateTypes (fun _tb ptd -> - match ptd with - | None -> () - | Some ptd -> ptd.SetAssembly assemblyLoadedInMemory) + methMap.[pminfo] <- mb -#if FX_NO_LOCAL_FILESYSTEM + | _ -> () + + for ityp in ptdT.GetInterfaces() do + tb.AddInterfaceImplementation (transType ityp)) + + // phase 3 - emit member code + providedTypeDefinitionsT |> iterateTypes (fun tb ptdT -> + match ptdT with + | None -> () + | Some ptdT -> + + defineCustomAttrs tb.SetCustomAttribute (ptdT.GetCustomAttributesData()) + + // Allow at most one constructor, and use its arguments as the fields of the type + let ctors = + ptdT.GetConstructors(bindAll) // exclude type initializer + |> Seq.choose (function :? ProvidedConstructor as pcinfo when not pcinfo.IsTypeInitializer -> Some pcinfo | _ -> None) + |> Seq.toList + + let implictCtorArgs = + match ctors |> List.filter (fun x -> x.IsImplicitConstructor) with + | [] -> [] + | [ pcinfo ] -> [ for p in pcinfo.GetParameters() -> p ] + | _ -> failwith "at most one implicit constructor allowed" + + let implicitCtorArgsAsFields = + [ for ctorArg in implictCtorArgs -> + tb.DefineField(ctorArg.Name, transType ctorArg.ParameterType, FieldAttributes.Private) ] + + + // Emit the constructor (if any) + for pcinfo in ctors do + assert ctorMap.ContainsKey pcinfo + if not pcinfo.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedConstructor. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pcinfo + let cb = ctorMap.[pcinfo] + + defineCustomAttrs cb.SetCustomAttribute (pcinfo.GetCustomAttributesData()) + + let ilg = cb.GetILGenerator() + let ctorLocals = Dictionary() + let parameterVars = + [| yield Var("this", pcinfo.DeclaringType) + for p in pcinfo.GetParameters() do + yield Var(p.Name, p.ParameterType) |] + + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, ctorLocals, parameterVars) + + let parameters = [ for v in parameterVars -> Expr.Var v ] + + match pcinfo.BaseCall with + | None -> + ilg.Emit(I_ldarg 0) + let cinfo = ptdT.BaseType.GetConstructor(bindAll, null, [| |], null) + ilg.Emit(mkNormalCall (transCtorSpec cinfo)) + | Some f -> + // argExprs should always include 'this' + let (cinfo,argExprs) = f parameters + for argExpr in argExprs do + codeGen.EmitExpr (ExpectedStackState.Value, argExpr) + ilg.Emit(mkNormalCall (transCtorSpec cinfo)) + + if pcinfo.IsImplicitConstructor then + for ctorArgsAsFieldIdx,ctorArgsAsField in List.mapi (fun i x -> (i,x)) implicitCtorArgsAsFields do + ilg.Emit(I_ldarg 0) + ilg.Emit(I_ldarg (ctorArgsAsFieldIdx+1)) + ilg.Emit(I_stfld (ILAlignment.Aligned, ILVolatility.Nonvolatile, ctorArgsAsField.FormalFieldSpec)) + else + let code = pcinfo.GetInvokeCode parameters + codeGen.EmitExpr (ExpectedStackState.Empty, code) + ilg.Emit(I_ret) + + match ptdT.GetConstructors(bindAll) |> Seq.tryPick (function :? ProvidedConstructor as pc when pc.IsTypeInitializer -> Some pc | _ -> None) with + | None -> () + | Some pc -> + let cb = ctorMap.[pc] + let ilg = cb.GetILGenerator() + + defineCustomAttrs cb.SetCustomAttribute (pc.GetCustomAttributesData()) + + let expr = pc.GetInvokeCode [ ] + let ctorLocals = new Dictionary<_, _>() + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, ctorLocals, [| |]) + codeGen.EmitExpr (ExpectedStackState.Empty, expr) + ilg.Emit I_ret + + // Emit the methods + for minfo in ptdT.GetMethods(bindAll) do + match minfo with + | :? ProvidedMethod as pminfo -> + if not pminfo.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedMethod. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" pminfo + let mb = methMap.[pminfo] + let ilg = mb.GetILGenerator() + defineCustomAttrs mb.SetCustomAttribute (pminfo.GetCustomAttributesData()) + + let parameterVars = + [| if not pminfo.IsStatic then + yield Var("this", pminfo.DeclaringType) + for p in pminfo.GetParameters() do + yield Var(p.Name, p.ParameterType) |] + let parameters = + [ for v in parameterVars -> Expr.Var v ] + + let expr = pminfo.GetInvokeCode parameters + + let methLocals = Dictionary() + + let expectedState = if (transType minfo.ReturnType = ILType.Void) then ExpectedStackState.Empty else ExpectedStackState.Value + let codeGen = CodeGenerator(assemblyMainModule, genUniqueTypeName, implicitCtorArgsAsFields, convTypeToTgt, transType, transFieldSpec, transMeth, transMethRef, transCtorSpec, ilg, methLocals, parameterVars) + codeGen.EmitExpr (expectedState, expr) + ilg.Emit I_ret + | _ -> () + + for (bodyMethInfo,declMethInfo) in ptdT.GetMethodOverrides() do + let bodyMethBuilder = methMap.[bodyMethInfo] + tb.DefineMethodOverride + { Overrides = OverridesSpec(transMethRef declMethInfo, transType declMethInfo.DeclaringType) + OverrideBy = bodyMethBuilder.FormalMethodSpec } + + for evt in ptdT.GetEvents(bindAll) |> Seq.choose (function :? ProvidedEvent as pe -> Some pe | _ -> None) do + if not evt.BelongsToTargetModel then failwithf "expected '%O' to be a target ProvidedEvent. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" evt + let eb = tb.DefineEvent(evt.Name, evt.Attributes) + defineCustomAttrs eb.SetCustomAttribute (evt.GetCustomAttributesData()) + eb.SetAddOnMethod(methMap.[evt.GetAddMethod(true) :?> _]) + eb.SetRemoveOnMethod(methMap.[evt.GetRemoveMethod(true) :?> _]) + + for pinfo in ptdT.GetProperties(bindAll) |> Seq.choose (function :? ProvidedProperty as pe -> Some pe | _ -> None) do + + let pb = tb.DefineProperty(pinfo.Name, pinfo.Attributes, transType pinfo.PropertyType, [| for p in pinfo.GetIndexParameters() -> transType p.ParameterType |]) + + defineCustomAttrs pb.SetCustomAttribute (pinfo.GetCustomAttributesData()) + + if pinfo.CanRead then + let minfo = pinfo.GetGetMethod(true) + pb.SetGetMethod (methMap.[minfo :?> ProvidedMethod ]) + + if pinfo.CanWrite then + let minfo = pinfo.GetSetMethod(true) + pb.SetSetMethod (methMap.[minfo :?> ProvidedMethod ])) + + //printfn "saving generated binary to '%s'" assemblyFileName + assemblyBuilder.Save () + //printfn "re-reading generated binary from '%s'" assemblyFileName + let reader = ILModuleReaderAfterReadingAllBytes(assemblyFileName, ilg) +#if DEBUG + printfn "generated binary is at '%s'" assemblyFileName #else - member __.GetFinalBytes() = - let assemblyBytes = File.ReadAllBytes assemblyFileName - let _assemblyLoadedInMemory = System.Reflection.Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain) - //printfn "final bytes in '%s'" assemblyFileName - //File.Delete assemblyFileName - assemblyBytes + File.Delete assemblyFileName #endif + let bytes = reader.Bytes -type ProvidedAssembly(assemblyFileName: string) = - let theTypes = ResizeArray<_>() - let assemblyGenerator = AssemblyGenerator(assemblyFileName) - let assemblyLazy = - lazy - assemblyGenerator.Generate(theTypes |> Seq.toList) - assemblyGenerator.Assembly -#if FX_NO_LOCAL_FILESYSTEM -#else - let theAssemblyBytesLazy = - lazy - assemblyGenerator.GetFinalBytes() + // Use a real Reflection Load when running in F# Interactive + if isHostedExecution then + let realTargetAssembly = Assembly.Load(bytes) + for (ptdT,_) in providedTypeDefinitionsT do + ptdT.SetAssemblyInternal (K realTargetAssembly) - do - GlobalProvidedAssemblyElementsTable.theTable.Add(assemblyGenerator.Assembly, theAssemblyBytesLazy) + bytes -#endif - let add (providedTypeDefinitions:ProvidedTypeDefinition list, enclosingTypeNames: string list option) = - for pt in providedTypeDefinitions do - if pt.IsErased then invalidOp ("The provided type "+pt.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition") - theTypes.Add(pt,enclosingTypeNames) - pt.SetAssemblyLazy assemblyLazy +#endif // NO_GENERATIVE + +//------------------------------------------------------------------------------------------------- +// TypeProviderForNamespaces + +namespace ProviderImplementation.ProvidedTypes + + #nowarn "1182" + open System + open System.Diagnostics + open System.IO + open System.Collections.Concurrent + open System.Collections.Generic + open System.Reflection + + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Quotations.DerivedPatterns + open Microsoft.FSharp.Quotations.Patterns + open Microsoft.FSharp.Quotations.ExprShape + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Reflection + + open ProviderImplementation.ProvidedTypes + open ProviderImplementation.ProvidedTypes.AssemblyReader + open ProviderImplementation.ProvidedTypes.UncheckedQuotations + + type TypeProviderForNamespaces(config: TypeProviderConfig, namespacesAndTypes: list<(string * list)>, assemblyReplacementMap: (string*string) list, sourceAssemblies: Assembly list) as this = + let ctxt = ProvidedTypesContext.Create (config, assemblyReplacementMap, sourceAssemblies) + +#if !NO_GENERATIVE + let theTable = ConcurrentDictionary() + + // When using hosted execution (i.e. in F# Interactive), ensure the generated assembly for a generated type is + // actually fully compiled and loaded as a reflection-load assembly before handing the type back to the API. + let ensureCompiled (t: Type) = + match t with + | :? ProvidedTypeDefinition as pt when pt.IsErased || pt.GetStaticParametersInternal().Length > 0 || not config.IsHostedExecution -> t + | _ -> + let origAssembly = t.Assembly + + // We expect the results reported by t.Assembly to actually change after this call, because the act of compilation + // when isHostedExecution=true replaces the Assembly object reported. + (this :> ITypeProvider).GetGeneratedAssemblyContents(origAssembly) |> ignore + + //printfn "t.Assembly = %O" t.Assembly + //printfn "t.Assembly.Location = %O" t.Assembly.Location + //printfn "t.FullName = %O" t.FullName + //printfn "t.Assembly.GetTypes() = %A" (t.Assembly.GetTypes()) + let tyName = t.FullName.Replace(",","\\,") + let newAssembly = t.Assembly + let newAssemblyName = newAssembly.GetName().Name + let origAssemblyName = origAssembly.GetName().Name + // check the assembly was generated with the correct name + if newAssemblyName <> origAssemblyName then + failwithf "expected identical assembly name keys '%s' and '%s'" origAssemblyName newAssemblyName + + // check the type really exists + if t.Assembly.GetType(tyName) = null then + failwithf "couldn't find type '%s' in assembly '%O'" tyName t.Assembly + + t - member x.AddNestedTypes (providedTypeDefinitions, enclosingTypeNames) = add (providedTypeDefinitions, Some enclosingTypeNames) - member x.AddTypes (providedTypeDefinitions) = add (providedTypeDefinitions, None) -#if FX_NO_LOCAL_FILESYSTEM #else - static member RegisterGenerated (fileName:string) = - //printfn "registered assembly in '%s'" fileName - let assemblyBytes = System.IO.File.ReadAllBytes fileName - let assembly = Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain) - GlobalProvidedAssemblyElementsTable.theTable.Add(assembly, Lazy<_>.CreateFromValue assemblyBytes) - assembly + let ensureCompiled (t: Type) = t #endif + let makeProvidedNamespace (namespaceName:string) (typesSrc:ProvidedTypeDefinition list) = + let typesSrc = [| for ty in typesSrc -> ty :> Type |] + let nsSrc = + { new IProvidedNamespace with + member _.GetNestedNamespaces() = [| |] + member _.NamespaceName = namespaceName + member _.GetTypes() = typesSrc |> Array.map ensureCompiled + member _.ResolveTypeName typeName = typesSrc |> Array.tryFind (fun ty -> ty.Name = typeName) |> Option.map ensureCompiled |> Option.toObj } + let nsT = ctxt.ConvertSourceNamespaceToTarget nsSrc + nsT -module Local = + let namespacesT = ResizeArray() - let makeProvidedNamespace (namespaceName:string) (types:ProvidedTypeDefinition list) = - let types = [| for ty in types -> ty :> Type |] - {new IProvidedNamespace with - member __.GetNestedNamespaces() = [| |] - member __.NamespaceName = namespaceName - member __.GetTypes() = types |> Array.copy - member __.ResolveTypeName typeName : System.Type = - match types |> Array.tryFind (fun ty -> ty.Name = typeName) with - | Some ty -> ty - | None -> null - } + do for (namespaceName,types) in namespacesAndTypes do + namespacesT.Add (makeProvidedNamespace namespaceName types) -// Used by unit testing to check that invalidation handlers are being disconnected -module GlobalCountersForInvalidation = - let mutable invalidationHandlersAdded = 0 - let mutable invalidationHandlersRemoved = 0 - let GetInvalidationHandlersAdded() = invalidationHandlersAdded - let GetInvalidationHandlersRemoved() = invalidationHandlersRemoved + let invalidateE = new Event() -#if FX_NO_LOCAL_FILESYSTEM -type TypeProviderForNamespaces(namespacesAndTypes : list<(string * list)>) = -#else -type TypeProviderForNamespaces(namespacesAndTypes : list<(string * list)>) as this = + let disposing = Event() + + +#if !FX_NO_LOCAL_FILESYSTEM + let probingFolders = ResizeArray() + let handler = ResolveEventHandler(fun _ args -> this.ResolveAssembly(args)) + do AppDomain.CurrentDomain.add_AssemblyResolve handler #endif - let otherNamespaces = ResizeArray>() - let providedNamespaces = - lazy [| for (namespaceName,types) in namespacesAndTypes do - yield Local.makeProvidedNamespace namespaceName types - for (namespaceName,types) in otherNamespaces do - yield Local.makeProvidedNamespace namespaceName types |] + new (config, namespaceName, types, ?sourceAssemblies, ?assemblyReplacementMap) = + let sourceAssemblies = defaultArg sourceAssemblies [ Assembly.GetCallingAssembly() ] + let assemblyReplacementMap = defaultArg assemblyReplacementMap [] + new TypeProviderForNamespaces(config, [(namespaceName,types)], assemblyReplacementMap=assemblyReplacementMap, sourceAssemblies=sourceAssemblies) - let invalidateE = new Event() + new (config, ?sourceAssemblies, ?assemblyReplacementMap) = + let sourceAssemblies = defaultArg sourceAssemblies [ Assembly.GetCallingAssembly() ] + let assemblyReplacementMap = defaultArg assemblyReplacementMap [] + new TypeProviderForNamespaces(config, [], assemblyReplacementMap=assemblyReplacementMap, sourceAssemblies=sourceAssemblies) - let disposing = Event() + member _.TargetContext = ctxt + + [] + member _.Disposing = disposing.Publish #if FX_NO_LOCAL_FILESYSTEM + + interface IDisposable with + member x.Dispose() = + disposing.Trigger(x, EventArgs.Empty) + #else - let probingFolders = ResizeArray() - let handler = ResolveEventHandler(fun _ args -> this.ResolveAssembly(args)) - do AppDomain.CurrentDomain.add_AssemblyResolve handler + + abstract member ResolveAssembly: args: ResolveEventArgs -> Assembly + + default _.ResolveAssembly(args) = + let expectedName = (AssemblyName(args.Name)).Name + ".dll" + let expectedLocationOpt = + probingFolders + |> Seq.map (fun f -> Path.Combine(f, expectedName)) + |> Seq.tryFind File.Exists + match expectedLocationOpt with + | Some f -> Assembly.LoadFrom f + | None -> null + + member _.RegisterProbingFolder (folder) = + // use GetFullPath to ensure that folder is valid + ignore(Path.GetFullPath folder) + probingFolders.Add folder + + member _.RegisterRuntimeAssemblyLocationAsProbingFolder (config: TypeProviderConfig) = + config.RuntimeAssembly + |> Path.GetDirectoryName + |> this.RegisterProbingFolder + + interface IDisposable with + member x.Dispose() = + disposing.Trigger(x, EventArgs.Empty) + AppDomain.CurrentDomain.remove_AssemblyResolve handler #endif - new (namespaceName:string,types:list) = new TypeProviderForNamespaces([(namespaceName,types)]) - new () = new TypeProviderForNamespaces([]) + member _.AddNamespace (namespaceName, types) = namespacesT.Add (makeProvidedNamespace namespaceName types) - [] - member __.Disposing = disposing.Publish + member _.Namespaces = namespacesT.ToArray() -#if FX_NO_LOCAL_FILESYSTEM - interface System.IDisposable with - member x.Dispose() = - disposing.Trigger(x, EventArgs.Empty) -#else - abstract member ResolveAssembly : args : System.ResolveEventArgs -> Assembly - - default __.ResolveAssembly(args) = - let expectedName = (AssemblyName(args.Name)).Name + ".dll" - let expectedLocationOpt = - probingFolders - |> Seq.map (fun f -> IO.Path.Combine(f, expectedName)) - |> Seq.tryFind IO.File.Exists - match expectedLocationOpt with - | Some f -> Assembly.LoadFrom f - | None -> null - - member __.RegisterProbingFolder (folder) = - // use GetFullPath to ensure that folder is valid - ignore(IO.Path.GetFullPath folder) - probingFolders.Add folder - - member __.RegisterRuntimeAssemblyLocationAsProbingFolder (config : TypeProviderConfig) = - config.RuntimeAssembly - |> IO.Path.GetDirectoryName - |> this.RegisterProbingFolder - - interface System.IDisposable with - member x.Dispose() = - disposing.Trigger(x, EventArgs.Empty) - AppDomain.CurrentDomain.remove_AssemblyResolve handler -#endif + member this.Invalidate() = invalidateE.Trigger(this,EventArgs()) - member __.AddNamespace (namespaceName,types:list<_>) = otherNamespaces.Add (namespaceName,types) + member _.GetStaticParametersForMethod(mb: MethodBase) = + match mb with + | :? ProvidedMethod as t -> t.GetStaticParametersInternal() + | _ -> [| |] - // FSharp.Data addition: this method is used by Debug.fs - member __.Namespaces = Seq.readonly otherNamespaces + member _.ApplyStaticArgumentsForMethod(mb: MethodBase, mangledName, objs) = + match mb with + | :? ProvidedMethod as t -> t.ApplyStaticArguments(mangledName, objs) :> MethodBase + | _ -> failwithf "ApplyStaticArguments: static parameters for method %s are unexpected. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" mb.Name - member this.Invalidate() = invalidateE.Trigger(this,EventArgs()) + interface ITypeProvider with - member __.GetStaticParametersForMethod(mb: MethodBase) = - match mb with - | :? ProvidedMethod as t -> t.GetStaticParameters() - | _ -> [| |] + [] + member _.Invalidate = invalidateE.Publish - member __.ApplyStaticArgumentsForMethod(mb: MethodBase, mangledName, objs) = - match mb with - | :? ProvidedMethod as t -> t.ApplyStaticArguments(mangledName, objs) :> MethodBase - | _ -> failwith (sprintf "ApplyStaticArguments: static parameters for method %s are unexpected" mb.Name) + member _.GetNamespaces() = namespacesT.ToArray() - interface ITypeProvider with + member _.GetInvokerExpression(methodBaseT, parametersT) = + + /// This checks that the GetInvokeCodeInternal doesn't return things containing calls to other provided methods or constructors. + let rec check expr = + match expr with + | NewObject((:? ProvidedConstructor), _) + | Call(_, :? ProvidedMethod, _) -> failwithf "The invokeCode for a ProvidedConstructor or ProvidedMethod included a use or another ProvidedConstructor or ProvidedMethod '%A'. This is not allowed. Instead, the invokeCode should be the compiled representation without invoking other provided objects" expr + | ShapeCombinationUnchecked(shape, args) -> RebuildShapeCombinationUnchecked(shape, List.map check args) + | ShapeVarUnchecked v -> Expr.Var v + | ShapeLambdaUnchecked(v, body) -> Expr.Lambda(v, check body) + + match methodBaseT with + | :? ProvidedMethod as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> + let exprT = mT.GetInvokeCode(Array.toList parametersT) + check exprT + + | :? ProvidedConstructor as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> + let exprT = mT.GetInvokeCode(Array.toList parametersT) + check exprT - [] - override __.Invalidate = invalidateE.Publish - - override __.GetNamespaces() = Array.copy providedNamespaces.Value - - member __.GetInvokerExpression(methodBase, parameters) = - let rec getInvokerExpression (methodBase : MethodBase) parameters = - match methodBase with - | :? ProvidedMethod as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> - m.GetInvokeCodeInternal false parameters - |> expand - | :? ProvidedConstructor as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> - m.GetInvokeCodeInternal false parameters - |> expand // Otherwise, assume this is a generative assembly and just emit a call to the constructor or method - | :? ConstructorInfo as cinfo -> - Expr.NewObjectUnchecked(cinfo, Array.toList parameters) - | :? System.Reflection.MethodInfo as minfo -> - if minfo.IsStatic then - Expr.CallUnchecked(minfo, Array.toList parameters) + | :? ConstructorInfo as cinfoT -> + Expr.NewObjectUnchecked(cinfoT, Array.toList parametersT) + + | :? MethodInfo as minfoT -> + if minfoT.IsStatic then + Expr.CallUnchecked(minfoT, Array.toList parametersT) else - Expr.CallUnchecked(parameters.[0], minfo, Array.toList parameters.[1..]) - | _ -> failwith ("TypeProviderForNamespaces.GetInvokerExpression: not a ProvidedMethod/ProvidedConstructor/ConstructorInfo/MethodInfo, name=" + methodBase.Name + " class=" + methodBase.GetType().FullName) - and expand expr = - match expr with - | NewObject(ctor, args) -> getInvokerExpression ctor [| for arg in args -> expand arg|] - | Call(inst, mi, args) -> - let args = - [| - match inst with - | Some inst -> yield expand inst - | _ -> () - yield! List.map expand args - |] - getInvokerExpression mi args - | ShapeCombinationUnchecked(shape, args) -> RebuildShapeCombinationUnchecked(shape, List.map expand args) - | ShapeVarUnchecked v -> Expr.Var v - | ShapeLambdaUnchecked(v, body) -> Expr.Lambda(v, expand body) - getInvokerExpression methodBase parameters -#if FX_NO_CUSTOMATTRIBUTEDATA - - member __.GetMemberCustomAttributesData(methodBase) = - match methodBase with - | :? ProvidedTypeDefinition as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedMethod as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedProperty as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedConstructor as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedEvent as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedLiteralField as m -> m.GetCustomAttributesDataImpl() - | :? ProvidedField as m -> m.GetCustomAttributesDataImpl() - | _ -> [| |] :> IList<_> - - member __.GetParameterCustomAttributesData(methodBase) = - match methodBase with - | :? ProvidedParameter as m -> m.GetCustomAttributesDataImpl() - | _ -> [| |] :> IList<_> + Expr.CallUnchecked(parametersT.[0], minfoT, Array.toList parametersT.[1..]) + | _ -> failwith ("TypeProviderForNamespaces.GetInvokerExpression: not a ProvidedMethod/ProvidedConstructor/ConstructorInfo/MethodInfo, name=" + methodBaseT.Name + " class=" + methodBaseT.GetType().FullName) -#endif - override __.GetStaticParameters(ty) = - match ty with - | :? ProvidedTypeDefinition as t -> - if ty.Name = t.Name (* REVIEW: use equality? *) then - t.GetStaticParameters() - else - [| |] - | _ -> [| |] + member _.GetStaticParameters(ty) = + match ty with + | :? ProvidedTypeDefinition as t -> + if ty.Name = t.Name then + t.GetStaticParametersInternal() + else + [| |] + | _ -> [| |] - override __.ApplyStaticArguments(ty,typePathAfterArguments:string[],objs) = - let typePathAfterArguments = typePathAfterArguments.[typePathAfterArguments.Length-1] - match ty with - | :? ProvidedTypeDefinition as t -> (t.MakeParametricType(typePathAfterArguments,objs) :> Type) - | _ -> failwith (sprintf "ApplyStaticArguments: static params for type %s are unexpected" ty.FullName) + member _.ApplyStaticArguments(ty, typePathAfterArguments:string[], objs) = + let typePathAfterArguments = typePathAfterArguments.[typePathAfterArguments.Length-1] + match ty with + | :? ProvidedTypeDefinition as t -> + let ty = (t.ApplyStaticArguments(typePathAfterArguments, objs) :> Type) + ensureCompiled ty -#if FX_NO_LOCAL_FILESYSTEM - override __.GetGeneratedAssemblyContents(_assembly) = - // TODO: this is very fake, we rely on the fact it is never needed - match System.Windows.Application.GetResourceStream(System.Uri("FSharp.Core.dll",System.UriKind.Relative)) with - | null -> failwith "FSharp.Core.dll not found as Manifest Resource, we're just trying to read some random .NET assembly, ok?" - | resStream -> - use stream = resStream.Stream - let len = stream.Length - let buf = Array.zeroCreate (int len) - let rec loop where rem = - let n = stream.Read(buf, 0, int rem) - if n < rem then loop (where + n) (rem - n) - loop 0 (int len) - buf - - //failwith "no file system" + | _ -> failwithf "ApplyStaticArguments: static params for type %s are unexpected, it is not a provided type definition. Please report this bug to https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues" ty.FullName + + member _.GetGeneratedAssemblyContents(assembly:Assembly) = +#if NO_GENERATIVE + ignore assembly; failwith "no generative assemblies" #else - override __.GetGeneratedAssemblyContents(assembly:Assembly) = - //printfn "looking up assembly '%s'" assembly.FullName - match GlobalProvidedAssemblyElementsTable.theTable.TryGetValue assembly with - | true,bytes -> bytes.Force() - | _ -> - let bytes = System.IO.File.ReadAllBytes assembly.ManifestModule.FullyQualifiedName - GlobalProvidedAssemblyElementsTable.theTable.[assembly] <- Lazy<_>.CreateFromValue bytes - bytes + //printfn "looking up assembly '%s'" assembly.FullName + let key = assembly.GetName().Name + match theTable.TryGetValue key with + | true,bytes -> bytes + | _ -> + let bytes = + match assembly with + | :? ProvidedAssembly as targetAssembly -> AssemblyCompiler(targetAssembly, ctxt).Compile(config.IsHostedExecution) + | _ -> File.ReadAllBytes assembly.ManifestModule.FullyQualifiedName + theTable.[key] <- bytes + bytes + +#if !NO_GENERATIVE + member _.RegisterGeneratedTargetAssembly (fileName:string) = + let assemblyBytes = File.ReadAllBytes fileName + //printfn "registering assembly in '%s'" fileName + let assembly = + if config.IsHostedExecution then + Assembly.Load(assemblyBytes) // we need a real on-disk assembly + else + ctxt.ReadRelatedAssembly(fileName) + ctxt.AddTargetAssembly(assembly.GetName(), assembly) + let key = assembly.GetName().Name + theTable.[key] <- assemblyBytes + assembly + +#endif #endif + + // Used by unit testing to check that invalidation handlers are being disconnected + module GlobalCountersForInvalidation = + let mutable invalidationHandlersAdded = 0 + let mutable invalidationHandlersRemoved = 0 + let GetInvalidationHandlersAdded() = invalidationHandlersAdded + let GetInvalidationHandlersRemoved() = invalidationHandlersRemoved diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fsi b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fsi index 3267c5b9ea4..65784ae9e7d 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fsi +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fsi @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation 2005-2014 and other contributors. -// This sample code is provided "as is" without warranty of any kind. -// We disclaim all warranties, either express or implied, including the -// warranties of merchantability and fitness for a particular purpose. +// This sample code is provided "as is" without warranty of any kind. +// We disclaim all warranties, either express or implied, including the +// warranties of merchantability and fitness for a particular purpose. // -// This file contains a set of helper types and methods for providing types in an implementation +// This file contains a set of helper types and methods for providing types in an implementation // of ITypeProvider. // // This code has been modified and is appropriate for use in conjunction with the F# 3.0-4.0 releases @@ -11,502 +11,539 @@ namespace ProviderImplementation.ProvidedTypes -open System -open System.Reflection -open System.Linq.Expressions -open Microsoft.FSharp.Quotations -open Microsoft.FSharp.Core.CompilerServices - -/// Represents an erased provided parameter -type ProvidedParameter = - inherit ParameterInfo - // [] - new : parameterName: string * parameterType: Type * ?isOut:bool * ?optionalValue:obj -> ProvidedParameter - member IsParamArray : bool with get,set - -/// Represents a provided static parameter. -type ProvidedStaticParameter = - inherit ParameterInfo - // [] - new : parameterName: string * parameterType:Type * ?parameterDefaultValue:obj -> ProvidedStaticParameter - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - -/// Represents an erased provided constructor. -type ProvidedConstructor = - inherit ConstructorInfo - - /// Create a new provided constructor. It is not initially associated with any specific provided type definition. - // [] - new : parameters: ProvidedParameter list -> ProvidedConstructor - - /// Add a 'Obsolete' attribute to this provided constructor - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Set the quotation used to compute the implementation of invocations of this constructor. - member InvokeCode : (Expr list -> Expr) with set - - /// FSharp.Data addition: this method is used by Debug.fs - member internal GetInvokeCodeInternal : bool -> (Expr [] -> Expr) - - /// Set the target and arguments of the base constructor call. Only used for generated types. - member BaseConstructorCall : (Expr list -> ConstructorInfo * Expr list) with set - - /// Set a flag indicating that the constructor acts like an F# implicit constructor, so the - /// parameters of the constructor become fields and can be accessed using Expr.GlobalVar with the - /// same name. - member IsImplicitCtor : bool with get,set - - /// Add definition location information to the provided constructor. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - member IsTypeInitializer : bool with get,set - -type ProvidedMethod = - inherit MethodInfo - - /// Create a new provided method. It is not initially associated with any specific provided type definition. - // [] - new : methodName:string * parameters: ProvidedParameter list * returnType: Type -> ProvidedMethod - - /// Add XML documentation information to this provided method - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - member AddMethodAttrs : attributes:MethodAttributes -> unit - - /// Set the method attributes of the method. By default these are simple 'MethodAttributes.Public' - member SetMethodAttrs : attributes:MethodAttributes -> unit - - /// Get or set a flag indicating if the property is static. - member IsStaticMethod : bool with get, set - - /// Set the quotation used to compute the implementation of invocations of this method. - member InvokeCode : (Expr list -> Expr) with set - - /// FSharp.Data addition: this method is used by Debug.fs - member internal GetInvokeCodeInternal : bool -> (Expr [] -> Expr) - - /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - /// Add a custom attribute to the provided method definition. - member AddCustomAttribute : CustomAttributeData -> unit - - /// Define the static parameters available on a statically parameterized method - member DefineStaticParameters : parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedMethod) -> unit - -/// Represents an erased provided property. -type ProvidedProperty = - inherit PropertyInfo - - /// Create a new provided property. It is not initially associated with any specific provided type definition. - // [] - new : propertyName: string * propertyType: Type * ?parameters:ProvidedParameter list -> ProvidedProperty - - /// Add a 'Obsolete' attribute to this provided property - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Get or set a flag indicating if the property is static. - /// FSharp.Data addition: the getter is used by Debug.fs - member IsStatic : bool with get,set - - /// Set the quotation used to compute the implementation of gets of this property. - member GetterCode : (Expr list -> Expr) with set - - /// Set the function used to compute the implementation of sets of this property. - member SetterCode : (Expr list -> Expr) with set - - /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - /// Add a custom attribute to the provided property definition. - member AddCustomAttribute : CustomAttributeData -> unit - -/// Represents an erased provided property. -type ProvidedEvent = - inherit EventInfo - - /// Create a new provided type. It is not initially associated with any specific provided type definition. - new : propertyName: string * eventHandlerType: Type -> ProvidedEvent - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Get or set a flag indicating if the property is static. - member IsStatic : bool with set - - /// Set the quotation used to compute the implementation of gets of this property. - member AdderCode : (Expr list -> Expr) with set - - /// Set the function used to compute the implementation of sets of this property. - member RemoverCode : (Expr list -> Expr) with set - - /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - -/// Represents an erased provided field. -type ProvidedLiteralField = - inherit FieldInfo - - /// Create a new provided field. It is not initially associated with any specific provided type definition. - // [] - new : fieldName: string * fieldType: Type * literalValue: obj -> ProvidedLiteralField - - /// Add a 'Obsolete' attribute to this provided field - member AddObsoleteAttribute : message: string * ?isError: bool -> unit + open System + open System.Collections.Generic + open System.Reflection + open System.Linq.Expressions + open Microsoft.FSharp.Quotations + open Microsoft.FSharp.Core.CompilerServices + + /// Represents an erased provided parameter + [] + type ProvidedParameter = + inherit ParameterInfo + + /// Create a new provided parameter. + new : parameterName: string * parameterType: Type * ?isOut: bool * ?optionalValue: obj -> ProvidedParameter + + /// Indicates if the parameter is marked as ParamArray + member IsParamArray: bool with set + + /// Indicates if the parameter is marked as ReflectedDefinition + member IsReflectedDefinition: bool with set + + /// Indicates if the parameter has a default value + member HasDefaultParameterValue: bool + + /// Add a custom attribute to the provided parameter. + member AddCustomAttribute: CustomAttributeData -> unit + + /// Represents a provided static parameter. + [] + type ProvidedStaticParameter = + inherit ParameterInfo + + /// Create a new provided static parameter, for use with DefineStaticParamaeters on a provided type definition. + new: parameterName: string * parameterType: Type * ?parameterDefaultValue: obj -> ProvidedStaticParameter + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + + /// Represents an erased provided constructor. + [] + type ProvidedConstructor = + inherit ConstructorInfo + + /// When making a cross-targeting type provider, use this method instead of the ProvidedConstructor constructor from ProvidedTypes + new: parameters: ProvidedParameter list * invokeCode: (Expr list -> Expr) -> ProvidedConstructor + + /// Add a 'Obsolete' attribute to this provided constructor + member AddObsoleteAttribute: message: string * ?isError: bool -> unit + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided constructor, where the documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + /// Set the target and arguments of the base constructor call. Only used for generated types. + member BaseConstructorCall: (Expr list -> ConstructorInfo * Expr list) with set + + /// Set a flag indicating that the constructor acts like an F# implicit constructor, so the + /// parameters of the constructor become fields and can be accessed using Expr.GlobalVar with the + /// same name. + member IsImplicitConstructor: bool with get,set + + /// Add definition location information to the provided constructor. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + member IsTypeInitializer: bool with get,set + + /// This method is for internal use only in the type provider SDK + member internal GetInvokeCode: Expr list -> Expr + + + + [] + type ProvidedMethod = + inherit MethodInfo + + /// When making a cross-targeting type provider, use this method instead of the ProvidedMethod constructor from ProvidedTypes + new: methodName: string * parameters: ProvidedParameter list * returnType: Type * invokeCode: (Expr list -> Expr) * ?isStatic: bool -> ProvidedMethod + + /// Add XML documentation information to this provided method + member AddObsoleteAttribute: message: string * ?isError: bool -> unit + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + /// The documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + member AddMethodAttrs: attributes:MethodAttributes -> unit + + /// Set the method attributes of the method. By default these are simple 'MethodAttributes.Public' + member SetMethodAttrs: attributes:MethodAttributes -> unit + + /// Add definition location information to the provided type definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + /// Add a custom attribute to the provided method definition. + member AddCustomAttribute: CustomAttributeData -> unit + + /// Define the static parameters available on a statically parameterized method + member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedMethod) -> unit + + /// This method is for internal use only in the type provider SDK + member internal GetInvokeCode: Expr list -> Expr + + + /// Represents an erased provided property. + [] + type ProvidedProperty = + inherit PropertyInfo + + /// Create a new provided property. It is not initially associated with any specific provided type definition. + new: propertyName: string * propertyType: Type * ?getterCode: (Expr list -> Expr) * ?setterCode: (Expr list -> Expr) * ?isStatic: bool * ?indexParameters: ProvidedParameter list -> ProvidedProperty + + /// Add a 'Obsolete' attribute to this provided property + member AddObsoleteAttribute: message: string * ?isError: bool -> unit + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + /// The documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + /// Get or set a flag indicating if the property is static. + member IsStatic: bool + + /// Add definition location information to the provided type definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + /// Add a custom attribute to the provided property definition. + member AddCustomAttribute: CustomAttributeData -> unit + + + /// Represents an erased provided property. + [] + type ProvidedEvent = + inherit EventInfo + + /// Create a new provided event. It is not initially associated with any specific provided type definition. + new: eventName: string * eventHandlerType: Type * adderCode: (Expr list -> Expr) * removerCode: (Expr list -> Expr) * ?isStatic: bool -> ProvidedEvent + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + /// The documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + /// Get a flag indicating if the property is static. + member IsStatic: bool with get + + /// Add definition location information to the provided type definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + + /// Represents an erased provided field. + [] + type ProvidedField = + inherit FieldInfo + + /// Create a new provided field. It is not initially associated with any specific provided type definition. + new: fieldName: string * fieldType: Type * value: obj -> ProvidedField + new: fieldName: string * fieldType: Type -> ProvidedField + + /// Add a 'Obsolete' attribute to this provided field + member AddObsoleteAttribute: message: string * ?isError: bool -> unit + + /// Add XML documentation information to this provided field + member AddXmlDoc: xmlDoc: string -> unit + + /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary + /// The documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + /// Add definition location information to the provided field definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + member SetFieldAttributes: attributes: FieldAttributes -> unit + + /// Create a new provided literal field. It is not initially associated with any specific provided type definition. + static member Literal: fieldName: string * fieldType: Type * literalValue:obj -> ProvidedField + + + /// Represents an array or other symbolic type involving a provided type as the argument. + /// See the type provider spec for the methods that must be implemented. + /// Note that the type provider specification does not require us to implement pointer-equality for provided types. + [] + type ProvidedTypeSymbol = + inherit TypeDelegator + + /// For example, kg + member IsFSharpTypeAbbreviation: bool + + /// For example, int or int + member IsFSharpUnitAnnotated: bool + + /// Helpers to build symbolic provided types + [] + type ProvidedTypeBuilder = + + /// Like typ.MakeGenericType, but will also work with unit-annotated types + static member MakeGenericType: genericTypeDefinition: Type * genericArguments: Type list -> Type + + /// Like methodInfo.MakeGenericMethod, but will also work with unit-annotated types and provided types + static member MakeGenericMethod: genericMethodDefinition: MethodInfo * genericArguments: Type list -> MethodInfo + + /// Like FsharpType.MakeTupleType, but will also work with unit-annotated types and provided types + static member MakeTupleType: args: Type list -> Type + + + /// Helps create erased provided unit-of-measure annotations. + [] + type ProvidedMeasureBuilder = + + /// Gets the measure indicating the "1" unit of measure, that is the unitless measure. + static member One: Type + + /// Returns the measure indicating the product of two units of measure, e.g. kg * m + static member Product: measure1: Type * measure2: Type -> Type + + /// Returns the measure indicating the inverse of two units of measure, e.g. 1 / s + static member Inverse: denominator: Type -> Type + + /// Returns the measure indicating the ratio of two units of measure, e.g. kg / m + static member Ratio: numerator: Type * denominator: Type -> Type + + /// Returns the measure indicating the square of a unit of measure, e.g. m * m + static member Square: ``measure``: Type -> Type + + /// Returns the measure for an SI unit from the F# core library, where the string is in capitals and US spelling, e.g. Meter + static member SI: unitName:string -> Type + + /// Returns a type where the type has been annotated with the given types and/or units-of-measure. + /// e.g. float, Vector + static member AnnotateType: basic: Type * argument: Type list -> Type + + + /// Represents a provided type definition. + [] + type ProvidedTypeDefinition = + inherit TypeDelegator + + /// When making a cross-targeting type provider, use this method instead of the corresponding ProvidedTypeDefinition constructor from ProvidedTypes + new: className: string * baseType: Type option * ?hideObjectMethods: bool * ?nonNullable: bool * ?isErased: bool -> ProvidedTypeDefinition + + /// When making a cross-targeting type provider, use this method instead of the corresponding ProvidedTypeDefinition constructor from ProvidedTypes + new: assembly: Assembly * namespaceName: string * className: string * baseType: Type option * ?hideObjectMethods: bool * ?nonNullable: bool * ?isErased: bool -> ProvidedTypeDefinition + + /// Add the given type as an implemented interface. + member AddInterfaceImplementation: interfaceType: Type -> unit + + /// Add the given function as a set of on-demand computed interfaces. + member AddInterfaceImplementationsDelayed: interfacesFunction:(unit -> Type list)-> unit + + /// Specifies that the given method body implements the given method declaration. + member DefineMethodOverride: methodInfoBody: ProvidedMethod * methodInfoDeclaration: MethodInfo -> unit + + /// Specifies that the given method bodies implement the given method declarations + member DefineMethodOverridesDelayed: (unit -> (ProvidedMethod * MethodInfo) list) -> unit + + /// Add a 'Obsolete' attribute to this provided type definition + member AddObsoleteAttribute: message: string * ?isError: bool -> unit + + /// Add XML documentation information to this provided constructor + member AddXmlDoc: xmlDoc: string -> unit + + /// Set the base type + member SetBaseType: Type -> unit + + /// Set the base type to a lazily evaluated value. Use this to delay realization of the base type as late as possible. + member SetBaseTypeDelayed: baseTypeFunction:(unit -> Type) -> unit + + /// Set underlying type for generated enums + member SetEnumUnderlyingType: Type -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary. + /// The documentation is only computed once. + member AddXmlDocDelayed: xmlDocFunction: (unit -> string) -> unit + + /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary + /// The documentation is re-computed every time it is required. + member AddXmlDocComputed: xmlDocFunction: (unit -> string) -> unit + + /// Set the attributes on the provided type. This fully replaces the default TypeAttributes. + member SetAttributes: TypeAttributes -> unit + + /// Add a method, property, nested type or other member to a ProvidedTypeDefinition + member AddMember: memberInfo:MemberInfo -> unit + + /// Add a set of members to a ProvidedTypeDefinition + member AddMembers: memberInfos:list<#MemberInfo> -> unit + + /// Add a member to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. + member AddMemberDelayed: memberFunction:(unit -> #MemberInfo) -> unit + + /// Add a set of members to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. + member AddMembersDelayed: membersFunction:(unit -> list<#MemberInfo>) -> unit + + /// Add the types of the generated assembly as generative types, where types in namespaces get hierarchically positioned as nested types. + member AddAssemblyTypesAsNestedTypesDelayed: assemblyFunction:(unit -> Assembly) -> unit + + /// Define the static parameters available on a statically parameterized type + member DefineStaticParameters: parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition) -> unit + + /// Add definition location information to the provided type definition. + member AddDefinitionLocation: line:int * column:int * filePath:string -> unit + + /// Suppress Object entries in intellisense menus in instances of this provided type + member HideObjectMethods: bool + + /// Disallows the use of the null literal. + member NonNullable: bool + + /// Get a flag indicating if the ProvidedTypeDefinition is erased + member IsErased: bool + + /// Get or set a flag indicating if the ProvidedTypeDefinition has type-relocation suppressed + [] + member SuppressRelocation: bool with get,set + + // This method is used by Debug.fs + member ApplyStaticArguments: name:string * args:obj[] -> ProvidedTypeDefinition + + /// Add a custom attribute to the provided type definition. + member AddCustomAttribute: CustomAttributeData -> unit + + /// Emulate the F# type provider type erasure mechanism to get the + /// actual (erased) type. We erase ProvidedTypes to their base type + /// and we erase array of provided type to array of base type. In the + /// case of generics all the generic type arguments are also recursively + /// replaced with the erased-to types + static member EraseType: typ:Type -> Type + + /// Get or set a utility function to log the creation of root Provided Type. Used to debug caching/invalidation. + static member Logger: (string -> unit) option ref + + +#if !NO_GENERATIVE + /// A provided generated assembly + type ProvidedAssembly = + + inherit Assembly + + /// Create a provided generated assembly + new: assemblyName: AssemblyName * assemblyFileName:string -> ProvidedAssembly + + /// Create a provided generated assembly using a temporary file as the interim assembly storage + new: unit -> ProvidedAssembly + + /// Emit the given provided type definitions as part of the assembly + /// and adjust the 'Assembly' property of all provided type definitions to return that + /// assembly. + /// + /// The assembly is only emitted when the Assembly property on the root type is accessed for the first time. + /// The host F# compiler does this when processing a generative type declaration for the type. + member AddTypes: types: ProvidedTypeDefinition list -> unit + + /// + /// Emit the given nested provided type definitions as part of the assembly. + /// and adjust the 'Assembly' property of all provided type definitions to return that + /// assembly. + /// + /// A list of nested ProvidedTypeDefinitions to add to the ProvidedAssembly. + /// A path of type names to wrap the generated types. The generated types are then generated as nested types. + member AddNestedTypes: types: ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit - /// Add XML documentation information to this provided field - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Add definition location information to the provided field. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - -/// Represents an erased provided field. -type ProvidedField = - inherit FieldInfo - - /// Create a new provided field. It is not initially associated with any specific provided type definition. - // [] - new : fieldName: string * fieldType: Type -> ProvidedField - - /// Add a 'Obsolete' attribute to this provided field - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - - /// Add XML documentation information to this provided field - member AddXmlDoc : xmlDoc: string -> unit - - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided field, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Add definition location information to the provided field definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - member SetFieldAttributes : attributes : FieldAttributes -> unit - -/// Represents the type constructor in a provided symbol type. -[] -type ProvidedSymbolKind = - /// Indicates that the type constructor is for a single-dimensional array - | SDArray - /// Indicates that the type constructor is for a multi-dimensional array - | Array of int - /// Indicates that the type constructor is for pointer types - | Pointer - /// Indicates that the type constructor is for byref types - | ByRef - /// Indicates that the type constructor is for named generic types - | Generic of Type - /// Indicates that the type constructor is for abbreviated types - | FSharpTypeAbbreviation of (Assembly * string * string[]) - -/// Represents an array or other symbolic type involving a provided type as the argument. -/// See the type provider spec for the methods that must be implemented. -/// Note that the type provider specification does not require us to implement pointer-equality for provided types. -[] -type ProvidedSymbolType = - inherit Type - - /// Returns the kind of this symbolic type - member Kind : ProvidedSymbolKind - - /// Return the provided types used as arguments of this symbolic type - member Args : list - - /// For example, kg - member IsFSharpTypeAbbreviation: bool - - /// For example, int or int - member IsFSharpUnitAnnotated : bool - -/// Helpers to build symbolic provided types -[] -type ProvidedTypeBuilder = - - /// Like typ.MakeGenericType, but will also work with unit-annotated types - static member MakeGenericType: genericTypeDefinition: Type * genericArguments: Type list -> Type - - /// Like methodInfo.MakeGenericMethod, but will also work with unit-annotated types and provided types - static member MakeGenericMethod: genericMethodDefinition: MethodInfo * genericArguments: Type list -> MethodInfo - -/// Helps create erased provided unit-of-measure annotations. -[] -type ProvidedMeasureBuilder = - - /// The ProvidedMeasureBuilder for building measures. - static member Default : ProvidedMeasureBuilder - - /// Gets the measure indicating the "1" unit of measure, that is the unitless measure. - member One : Type - - /// Returns the measure indicating the product of two units of measure, e.g. kg * m - member Product : measure1: Type * measure1: Type -> Type - - /// Returns the measure indicating the inverse of two units of measure, e.g. 1 / s - member Inverse : denominator: Type -> Type - - /// Returns the measure indicating the ratio of two units of measure, e.g. kg / m - member Ratio : numerator: Type * denominator: Type -> Type - - /// Returns the measure indicating the square of a unit of measure, e.g. m * m - member Square : ``measure``: Type -> Type - - /// Returns the measure for an SI unit from the F# core library, where the string is in capitals and US spelling, e.g. Meter - member SI : unitName:string -> Type - - /// Returns a type where the type has been annotated with the given types and/or units-of-measure. - /// e.g. float, Vector - member AnnotateType : basic: Type * argument: Type list -> Type - - -/// Represents a provided type definition. -type ProvidedTypeDefinition = - inherit Type - - /// Create a new provided type definition in a namespace. - // [] - new : assembly: Assembly * namespaceName: string * className: string * baseType: Type option -> ProvidedTypeDefinition - - /// Create a new provided type definition, to be located as a nested type in some type definition. - // [] - new : className : string * baseType: Type option -> ProvidedTypeDefinition - - /// Add the given type as an implemented interface. - member AddInterfaceImplementation : interfaceType: Type -> unit - - /// Add the given function as a set of on-demand computed interfaces. - member AddInterfaceImplementationsDelayed : interfacesFunction:(unit -> Type list)-> unit - - /// Specifies that the given method body implements the given method declaration. - member DefineMethodOverride : methodInfoBody: ProvidedMethod * methodInfoDeclaration: MethodInfo -> unit - - /// Add a 'Obsolete' attribute to this provided type definition - member AddObsoleteAttribute : message: string * ?isError: bool -> unit - - /// Add XML documentation information to this provided constructor - member AddXmlDoc : xmlDoc: string -> unit - - /// Set the base type - member SetBaseType : Type -> unit - - /// Set the base type to a lazily evaluated value. Use this to delay realization of the base type as late as possible. - member SetBaseTypeDelayed : baseTypeFunction:(unit -> Type) -> unit - - /// Set underlying type for generated enums - member SetEnumUnderlyingType : Type -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary. - /// The documentation is only computed once. - member AddXmlDocDelayed : xmlDocFunction: (unit -> string) -> unit - - /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary - /// The documentation is re-computed every time it is required. - member AddXmlDocComputed : xmlDocFunction: (unit -> string) -> unit - - /// Set the attributes on the provided type. This fully replaces the default TypeAttributes. - member SetAttributes : TypeAttributes -> unit - - /// Reset the enclosing type (for generated nested types) - member ResetEnclosingType: enclosingType:Type -> unit - - /// Add a method, property, nested type or other member to a ProvidedTypeDefinition - member AddMember : memberInfo:MemberInfo -> unit - - /// Add a set of members to a ProvidedTypeDefinition - member AddMembers : memberInfos:list<#MemberInfo> -> unit - - /// Add a member to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. - member AddMemberDelayed : memberFunction:(unit -> #MemberInfo) -> unit - - /// Add a set of members to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context. - member AddMembersDelayed : membersFunction:(unit -> list<#MemberInfo>) -> unit - - /// Add the types of the generated assembly as generative types, where types in namespaces get hierarchically positioned as nested types. - member AddAssemblyTypesAsNestedTypesDelayed : assemblyFunction:(unit -> Assembly) -> unit - - /// Define the static parameters available on a statically parameterized type - member DefineStaticParameters : parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition) -> unit - - /// Add definition location information to the provided type definition. - member AddDefinitionLocation : line:int * column:int * filePath:string -> unit - - /// Suppress Object entries in intellisense menus in instances of this provided type - member HideObjectMethods : bool with set - - /// Disallows the use of the null literal. - member NonNullable : bool with set - - /// Get or set a flag indicating if the ProvidedTypeDefinition is erased - member IsErased : bool with get,set - - /// Get or set a flag indicating if the ProvidedTypeDefinition has type-relocation suppressed - [] - member SuppressRelocation : bool with get,set - - /// FSharp.Data addition: this method is used by Debug.fs - member MakeParametricType : name:string * args:obj[] -> ProvidedTypeDefinition - - /// Add a custom attribute to the provided type definition. - member AddCustomAttribute : CustomAttributeData -> unit - - /// Emulate the F# type provider type erasure mechanism to get the - /// actual (erased) type. We erase ProvidedTypes to their base type - /// and we erase array of provided type to array of base type. In the - /// case of generics all the generic type arguments are also recursively - /// replaced with the erased-to types - static member EraseType : typ:Type -> Type - - /// Get or set a utility function to log the creation of root Provided Type. Used to debug caching/invalidation. - static member Logger : (string -> unit) option ref - -/// A provided generated assembly -type ProvidedAssembly = - /// Create a provided generated assembly - new : assemblyFileName:string -> ProvidedAssembly - - /// Emit the given provided type definitions as part of the assembly - /// and adjust the 'Assembly' property of all provided type definitions to return that - /// assembly. - /// - /// The assembly is only emitted when the Assembly property on the root type is accessed for the first time. - /// The host F# compiler does this when processing a generative type declaration for the type. - member AddTypes : types : ProvidedTypeDefinition list -> unit - - /// - /// Emit the given nested provided type definitions as part of the assembly. - /// and adjust the 'Assembly' property of all provided type definitions to return that - /// assembly. - /// - /// A path of type names to wrap the generated types. The generated types are then generated as nested types. - member AddNestedTypes : types : ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit - -#if FX_NO_LOCAL_FILESYSTEM -#else - /// Register that a given file is a provided generated assembly - static member RegisterGenerated : fileName:string -> Assembly #endif -/// A base type providing default implementations of type provider functionality when all provided -/// types are of type ProvidedTypeDefinition. -type TypeProviderForNamespaces = + [] + /// Represents the context for which code is to be generated. Normally you should not need to use this directly. + type ProvidedTypesContext = + + /// Try to find the given target assembly in the context + member TryBindAssemblyNameToTarget: aref: AssemblyName -> Choice + + /// Try to find the given target assembly in the context + member TryBindSimpleAssemblyNameToTarget: assemblyName: string -> Choice + + /// Get the list of referenced assemblies determined by the type provider configuration + member ReferencedAssemblyPaths: string list + + /// Get the resolved referenced assemblies determined by the type provider configuration + member GetTargetAssemblies: unit -> Assembly[] + + /// Get the set of design-time assemblies available to use as a basis for authoring provided types. + member GetSourceAssemblies: unit -> Assembly[] + + /// Add an assembly to the set of design-time assemblies available to use as a basis for authoring provided types + member AddSourceAssembly: Assembly -> unit + + /// Try to get the version of FSharp.Core referenced. May raise an exception if FSharp.Core has not been correctly resolved + member FSharpCoreAssemblyVersion: Version + + /// Returns a type from the referenced assemblies that corresponds to the given design-time type. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertSourceTypeToTarget: Type -> Type - /// Initializes a type provider to provide the types in the given namespace. - new : namespaceName:string * types: ProvidedTypeDefinition list -> TypeProviderForNamespaces + /// Returns the design-time type that corresponds to the given type from the target referenced assemblies. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertTargetTypeToSource: Type -> Type - /// Initializes a type provider - new : unit -> TypeProviderForNamespaces + /// Returns a quotation rebuilt with resepct to the types from the target referenced assemblies. Normally + /// this method should not be used directly when authoring a type provider. + member ConvertSourceExprToTarget: Expr -> Expr - /// Invoked by the type provider to add a namespace of provided types in the specification of the type provider. - member AddNamespace : namespaceName:string * types: ProvidedTypeDefinition list -> unit + /// Read the assembly related to this context + member ReadRelatedAssembly: fileName: string -> Assembly - /// Invoked by the type provider to get all provided namespaces with their provided types. - member Namespaces : seq + /// Read the assembly related to this context + member ReadRelatedAssembly: bytes: byte[] -> Assembly - /// Invoked by the type provider to invalidate the information provided by the provider - member Invalidate : unit -> unit + /// A base type providing default implementations of type provider functionality. + type TypeProviderForNamespaces = - /// Invoked by the host of the type provider to get the static parameters for a method. - member GetStaticParametersForMethod : MethodBase -> ParameterInfo[] - - /// Invoked by the host of the type provider to apply the static argumetns for a method. - member ApplyStaticArgumentsForMethod : MethodBase * string * obj[] -> MethodBase + /// Initializes a type provider to provide the types in the given namespace. + /// + /// Optionally specify the design-time assemblies available to use as a basis for authoring provided types. + /// The transitive dependencies of these assemblies are also included. By default + /// Assembly.GetCallingAssembly() and its transitive dependencies are used. + /// + /// + /// + /// Optionally specify a map of assembly names from source model to referenced assemblies. + /// + new: config: TypeProviderConfig * namespaceName:string * types: ProvidedTypeDefinition list * ?sourceAssemblies: Assembly list * ?assemblyReplacementMap: (string * string) list -> TypeProviderForNamespaces -#if FX_NO_LOCAL_FILESYSTEM -#else - /// AssemblyResolve handler. Default implementation searches .dll file in registered folders - abstract ResolveAssembly : ResolveEventArgs -> Assembly - default ResolveAssembly : ResolveEventArgs -> Assembly + /// Initializes a type provider. + /// + /// Optionally specify the design-time assemblies available to use as a basis for authoring provided types. + /// The transitive dependencies of these assemblies are also included. By default + /// Assembly.GetCallingAssembly() and its transitive dependencies are used. + /// + /// + /// + /// Optionally specify a map of assembly names from source model to referenced assemblies. + /// + new: config: TypeProviderConfig * ?sourceAssemblies: Assembly list * ?assemblyReplacementMap: (string * string) list -> TypeProviderForNamespaces - /// Registers custom probing path that can be used for probing assemblies - member RegisterProbingFolder : folder: string -> unit + /// Invoked by the type provider to add a namespace of provided types in the specification of the type provider. + member AddNamespace: namespaceName:string * types: ProvidedTypeDefinition list -> unit - /// Registers location of RuntimeAssembly (from TypeProviderConfig) as probing folder - member RegisterRuntimeAssemblyLocationAsProbingFolder : config: TypeProviderConfig -> unit + /// Invoked by the type provider to get all provided namespaces with their provided types. + member Namespaces: IProvidedNamespace[] + + /// Invoked by the type provider to invalidate the information provided by the provider + member Invalidate: unit -> unit + + /// Invoked by the host of the type provider to get the static parameters for a method. + member GetStaticParametersForMethod: MethodBase -> ParameterInfo[] + + /// Invoked by the host of the type provider to apply the static argumetns for a method. + member ApplyStaticArgumentsForMethod: MethodBase * string * obj[] -> MethodBase + +#if !FX_NO_LOCAL_FILESYSTEM + /// AssemblyResolve handler. Default implementation searches .dll file in registered folders + abstract ResolveAssembly: ResolveEventArgs -> Assembly + default ResolveAssembly: ResolveEventArgs -> Assembly + + /// Registers custom probing path that can be used for probing assemblies + member RegisterProbingFolder: folder: string -> unit + + /// Registers location of RuntimeAssembly (from TypeProviderConfig) as probing folder + member RegisterRuntimeAssemblyLocationAsProbingFolder: config: TypeProviderConfig -> unit + +#endif +#if !NO_GENERATIVE + /// Register that a given file is a provided generated target assembly, e.g. an assembly produced by an external + /// code generation tool. This assembly should be a target assembly, i.e. use the same asssembly references + /// as given by TargetContext.ReferencedAssemblyPaths + member RegisterGeneratedTargetAssembly: fileName: string -> Assembly #endif - [] - member Disposing : IEvent - - interface ITypeProvider - - -// Used by unit testing to check that invalidation handlers are being disconnected -module GlobalCountersForInvalidation = - val GetInvalidationHandlersAdded : unit -> int - val GetInvalidationHandlersRemoved : unit -> int - -module internal UncheckedQuotations = - - type Expr with - static member NewDelegateUnchecked : ty:Type * vs:Var list * body:Expr -> Expr - static member NewObjectUnchecked : cinfo:ConstructorInfo * args:Expr list -> Expr - static member NewArrayUnchecked : elementType:Type * elements:Expr list -> Expr - static member CallUnchecked : minfo:MethodInfo * args:Expr list -> Expr - static member CallUnchecked : obj:Expr * minfo:MethodInfo * args:Expr list -> Expr - static member ApplicationUnchecked : f:Expr * x:Expr -> Expr - static member PropertyGetUnchecked : pinfo:PropertyInfo * args:Expr list -> Expr - static member PropertyGetUnchecked : obj:Expr * pinfo:PropertyInfo * ?args:Expr list -> Expr - static member PropertySetUnchecked : pinfo:PropertyInfo * value:Expr * ?args:Expr list -> Expr - static member PropertySetUnchecked : obj:Expr * pinfo:PropertyInfo * value:Expr * args:Expr list -> Expr - static member FieldGetUnchecked : pinfo:FieldInfo -> Expr - static member FieldGetUnchecked : obj:Expr * pinfo:FieldInfo -> Expr - static member FieldSetUnchecked : pinfo:FieldInfo * value:Expr -> Expr - static member FieldSetUnchecked : obj:Expr * pinfo:FieldInfo * value:Expr -> Expr - static member TupleGetUnchecked : e:Expr * n:int -> Expr - static member LetUnchecked : v:Var * e:Expr * body:Expr -> Expr - - type Shape - val ( |ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked| ) : e:Expr -> Choice<(Shape * Expr list),Var, (Var * Expr)> - val RebuildShapeCombinationUnchecked : Shape * args:Expr list -> Expr + [] + member Disposing: IEvent + + /// The context for which code is eventually to be generated. You should not normally + /// need to use this property directly, as translation from the compiler-hosted context to + /// the design-time context will normally be performed automatically. + member TargetContext: ProvidedTypesContext + + interface ITypeProvider + + + module internal UncheckedQuotations = + + type Expr with + static member NewDelegateUnchecked: ty:Type * vs:Var list * body:Expr -> Expr + static member NewObjectUnchecked: cinfo:ConstructorInfo * args:Expr list -> Expr + static member NewArrayUnchecked: elementType:Type * elements:Expr list -> Expr + static member CallUnchecked: minfo:MethodInfo * args:Expr list -> Expr + static member CallUnchecked: obj:Expr * minfo:MethodInfo * args:Expr list -> Expr + static member ApplicationUnchecked: f:Expr * x:Expr -> Expr + static member PropertyGetUnchecked: pinfo:PropertyInfo * args:Expr list -> Expr + static member PropertyGetUnchecked: obj:Expr * pinfo:PropertyInfo * ?args:Expr list -> Expr + static member PropertySetUnchecked: pinfo:PropertyInfo * value:Expr * ?args:Expr list -> Expr + static member PropertySetUnchecked: obj:Expr * pinfo:PropertyInfo * value:Expr * args:Expr list -> Expr + static member FieldGetUnchecked: pinfo:FieldInfo -> Expr + static member FieldGetUnchecked: obj:Expr * pinfo:FieldInfo -> Expr + static member FieldSetUnchecked: pinfo:FieldInfo * value:Expr -> Expr + static member FieldSetUnchecked: obj:Expr * pinfo:FieldInfo * value:Expr -> Expr + static member TupleGetUnchecked: e:Expr * n:int -> Expr + static member LetUnchecked: v:Var * e:Expr * body:Expr -> Expr + + type Shape + val ( |ShapeCombinationUnchecked|ShapeVarUnchecked|ShapeLambdaUnchecked| ): e:Expr -> Choice<(Shape * Expr list),Var, (Var * Expr)> + val RebuildShapeCombinationUnchecked: Shape * args:Expr list -> Expr + + + // Used by unit testing to check that invalidation handlers are being disconnected + module GlobalCountersForInvalidation = + val GetInvalidationHandlersAdded : unit -> int + val GetInvalidationHandlersRemoved : unit -> int diff --git a/vsintegration/tests/MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj b/vsintegration/tests/MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj +++ b/vsintegration/tests/MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj b/vsintegration/tests/MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj index 5f0e7a69b63..295d1dc0e0c 100644 --- a/vsintegration/tests/MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj +++ b/vsintegration/tests/MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj @@ -3,7 +3,7 @@ - net45 + net472 true diff --git a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj +++ b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj +++ b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj +++ b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj +++ b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj index f5f0216e9f8..0fdc04a774a 100644 --- a/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj +++ b/vsintegration/tests/MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj @@ -3,7 +3,7 @@ - net45 + net472 diff --git a/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs b/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs index a31777b9435..9620371d6e3 100644 --- a/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs +++ b/vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs @@ -15,7 +15,9 @@ open Microsoft.VisualStudio.TextManager.Interop open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.OLE.Interop open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Tokenization open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.FSharp.LanguageService.SiteProvider @@ -99,7 +101,6 @@ type internal FSharpLanguageServiceTestable() as this = match checkerContainerOpt with | Some container -> let checker = container - checker.StopBackgroundCompile() checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() | None -> () @@ -127,8 +128,8 @@ type internal FSharpLanguageServiceTestable() as this = /// Respond to project being cleaned/rebuilt (any live type providers in the project should be refreshed) member this.OnProjectCleaned(projectSite:IProjectSite) = let enableInMemoryCrossProjectReferences = true - let _, checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, (fun _ -> None), projectSite, serviceProvider.Value, None(*projectId*), "" ,None, None, false) - this.FSharpChecker.NotifyProjectCleaned(checkOptions) |> Async.RunSynchronously + let _, checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, (fun _ -> None), projectSite, serviceProvider.Value, "" , false) + this.FSharpChecker.NotifyProjectCleaned(checkOptions) |> Async.RunImmediate member this.OnActiveViewChanged(textView) = bgRequests.OnActiveViewChanged(textView) @@ -170,7 +171,7 @@ type internal FSharpLanguageServiceTestable() as this = member this.DependencyFileCreated projectSite = let enableInMemoryCrossProjectReferences = true // Invalidate the configuration if we notice any add for any DependencyFiles - let _, checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, (fun _ -> None), projectSite, serviceProvider.Value, None(*projectId*),"" ,None, None, false) + let _, checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, (fun _ -> None), projectSite, serviceProvider.Value, "" , false) this.FSharpChecker.InvalidateConfiguration(checkOptions) member this.DependencyFileChanged (filename) = @@ -223,4 +224,4 @@ type internal FSharpLanguageServiceTestable() as this = // // This is for unit testing only member this.WaitForBackgroundCompile() = - this.FSharpChecker.WaitForBackgroundCompile() + () diff --git a/vsintegration/tests/Salsa/SalsaUtils.fs b/vsintegration/tests/Salsa/SalsaUtils.fs index a4c42200ce3..7d9e386a274 100644 --- a/vsintegration/tests/Salsa/SalsaUtils.fs +++ b/vsintegration/tests/Salsa/SalsaUtils.fs @@ -7,7 +7,8 @@ open System.IO open Microsoft.VisualStudio.FSharp.ProjectSystem open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.TextManager.Interop -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices open NUnit.Framework open Salsa.Salsa diff --git a/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj b/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj index c3e21061e0b..2cbefb3b41f 100644 --- a/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj +++ b/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj @@ -4,10 +4,8 @@ Library - $(NoWarn);45;47;52;58;75 + $(NoWarn);44;45;47;52;58;75 true - true - $(SystemValueTupleVersion) true false @@ -17,7 +15,8 @@ - + + CompilerLocationUtils.fs @@ -32,12 +31,12 @@ - + - - + + @@ -52,7 +51,6 @@ - @@ -69,6 +67,7 @@ + diff --git a/vsintegration/tests/Salsa/VsMocks.fs b/vsintegration/tests/Salsa/VsMocks.fs index c3008cf636d..a37df360bfe 100644 --- a/vsintegration/tests/Salsa/VsMocks.fs +++ b/vsintegration/tests/Salsa/VsMocks.fs @@ -1130,7 +1130,7 @@ module internal VsMocks = // peekhole to IVsTrackProjectDocuments2 - allows to receive notifications about removed files type public IVsTrackProjectDocuments2Listener = - abstract member OnAfterRemoveFiles : IEvent + abstract member OnAfterRemoveFiles: IEvent let vsTrackProjectDocuments2 = @@ -1642,7 +1642,7 @@ module internal VsActual = static let jtc = new JoinableTaskContext() [)>] - member public __.JoinableTaskContext : JoinableTaskContext = jtc + member public _.JoinableTaskContext : JoinableTaskContext = jtc let vsInstallDir = // use the environment variable to find the VS installdir @@ -1664,7 +1664,8 @@ module internal VsActual = if File.Exists(fullPath) then list.Add(new AssemblyCatalog(fullPath)) else - failwith <| sprintf "unable to find assembly %s" p + + failwith <| sprintf "unable to find assembly '%s' in location '%s'" p thisAssemblyDir list.Add(new AssemblyCatalog(thisAssembly)) [ "Microsoft.VisualStudio.Text.Data.dll" @@ -1674,7 +1675,7 @@ module internal VsActual = "Microsoft.VisualStudio.Text.UI.Wpf.dll" "Microsoft.VisualStudio.Threading.dll" "Microsoft.VisualStudio.Platform.VSEditor.dll" - "Microsoft.VisualStudio.Editor.Implementation.dll" + "Microsoft.VisualStudio.Editor.dll" "Microsoft.VisualStudio.ComponentModelHost.dll" "Microsoft.VisualStudio.Shell.15.0.dll" ] |> List.iter add diff --git a/vsintegration/tests/Salsa/salsa.fs b/vsintegration/tests/Salsa/salsa.fs index 52f2de8c902..523123e01b6 100644 --- a/vsintegration/tests/Salsa/salsa.fs +++ b/vsintegration/tests/Salsa/salsa.fs @@ -25,8 +25,8 @@ open Microsoft.VisualStudio.FSharp.LanguageService open Microsoft.VisualStudio.TextManager.Interop open UnitTests.TestLib.Utils.FilesystemHelpers open Microsoft.Build.Framework -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices open Microsoft.Build.Evaluation @@ -1101,8 +1101,8 @@ module internal Salsa = member file.GetFileName() = filename member file.GetProjectOptionsOfScript() = - project.Solution.Vs.LanguageService.FSharpChecker.GetProjectOptionsFromScript(filename, FSharp.Compiler.Text.SourceText.ofString file.CombinedLines, System.DateTime(2000,1,1), [| |]) - |> Async.RunSynchronously + project.Solution.Vs.LanguageService.FSharpChecker.GetProjectOptionsFromScript(filename, FSharp.Compiler.Text.SourceText.ofString file.CombinedLines, false, System.DateTime(2000,1,1), [| |]) + |> Async.RunImmediate |> fst // drop diagnostics member file.RecolorizeWholeFile() = () @@ -1316,7 +1316,7 @@ module internal Salsa = let declarations = let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot - currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1, cursor.col-1, reason) |> Async.RunSynchronously + currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1, cursor.col-1, reason) |> Async.RunImmediate match declarations with | null -> [||] | declarations -> @@ -1335,7 +1335,7 @@ module internal Salsa = let currentAuthoringScope = file.DoIntellisenseRequest(BackgroundRequestReason.MemberSelect) let declarations = let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot - currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1,cursor.col-1, BackgroundRequestReason.MemberSelect) |> Async.RunSynchronously + currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1,cursor.col-1, BackgroundRequestReason.MemberSelect) |> Async.RunImmediate match declarations with | null -> None | declarations -> @@ -1443,21 +1443,21 @@ module internal Salsa = let documentationProvider = { new IDocumentationBuilder_DEPRECATED with override doc.AppendDocumentationFromProcessedXML(appendTo,processedXml:string,showExceptions, showReturns, paramName) = - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.tagText processedXml) - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.Literals.lineBreak) + appendTo.Add(FSharp.Compiler.Text.TaggedText.tagText processedXml) + appendTo.Add(FSharp.Compiler.Text.TaggedText.lineBreak) override doc.AppendDocumentation(appendTo,filename:string,signature:string, showExceptions, showReturns, paramName) = - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.tagText (sprintf "[Filename:%s]" filename)) - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.Literals.lineBreak) - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.tagText (sprintf "[Signature:%s]" signature)) - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.Literals.lineBreak) + appendTo.Add(FSharp.Compiler.Text.TaggedText.tagText (sprintf "[Filename:%s]" filename)) + appendTo.Add(FSharp.Compiler.Text.TaggedText.lineBreak) + appendTo.Add(FSharp.Compiler.Text.TaggedText.tagText (sprintf "[Signature:%s]" signature)) + appendTo.Add(FSharp.Compiler.Text.TaggedText.lineBreak) if paramName.IsSome then - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.tagText (sprintf "[ParamName: %s]" paramName.Value)) - appendTo.Add(FSharp.Compiler.Layout.TaggedTextOps.Literals.lineBreak) + appendTo.Add(FSharp.Compiler.Text.TaggedText.tagText (sprintf "[ParamName: %s]" paramName.Value)) + appendTo.Add(FSharp.Compiler.Text.TaggedText.lineBreak) } let sp2 = { new System.IServiceProvider with - member __.GetService(serviceType:Type) : obj = + member _.GetService(serviceType:Type) : obj = if serviceType = typeof then rdt else if serviceType = typeof then tm else raise (new Exception(sprintf "Salsa did not create service %A" serviceType)) } @@ -1546,8 +1546,8 @@ module internal Salsa = member ops.CleanUp vs = VsImpl(vs).CleanUp() member ops.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients vs = VsImpl(vs).ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() member ops.AutoCompleteMemberDataTipsThrowsScope message = - SymbolHelpers.ToolTipFault <- Some message - { new System.IDisposable with member x.Dispose() = SymbolHelpers.ToolTipFault <- None } + DeclarationListHelpers.ToolTipFault <- Some message + { new System.IDisposable with member x.Dispose() = DeclarationListHelpers.ToolTipFault <- None } member ops.OutOfConeFilesAreAddedAsLinks = false member ops.SupportsOutputWindowPane = false member ops.CleanInvisibleProject vs = VsImpl(vs).CleanInvisibleProject() diff --git a/vsintegration/tests/UnitTests/App.config b/vsintegration/tests/UnitTests/App.config index 6df63308b27..9e676285670 100644 --- a/vsintegration/tests/UnitTests/App.config +++ b/vsintegration/tests/UnitTests/App.config @@ -3,12 +3,6 @@ - - - - - - @@ -32,10 +26,6 @@ - - - - diff --git a/vsintegration/tests/UnitTests/AssemblyResolver.fs b/vsintegration/tests/UnitTests/AssemblyResolver.fs index 229650849fa..a118adfd97f 100644 --- a/vsintegration/tests/UnitTests/AssemblyResolver.fs +++ b/vsintegration/tests/UnitTests/AssemblyResolver.fs @@ -51,4 +51,4 @@ module AssemblyResolver = type public AssemblyResolverTestFixture () = [] - member public __.Init () = AssemblyResolver.addResolver () + member public _.Init () = AssemblyResolver.addResolver () diff --git a/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs b/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs index 0e71493d22b..c4a1d61cde8 100644 --- a/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs +++ b/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs @@ -9,7 +9,7 @@ open NUnit.Framework open Microsoft.CodeAnalysis.Classification open Microsoft.CodeAnalysis.Editor open Microsoft.CodeAnalysis.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Microsoft.VisualStudio.FSharp.Editor open Microsoft.VisualStudio.FSharp.LanguageService open UnitTests.TestLib.LanguageService @@ -28,7 +28,6 @@ type BraceMatchingServiceTests() = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } @@ -38,7 +37,7 @@ type BraceMatchingServiceTests() = Assert.IsTrue(position >= 0, "Cannot find marker '{0}' in file contents", marker) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, position, "UnitTest") |> Async.RunSynchronously with + match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, position, "UnitTest") |> Async.RunImmediate with | None -> () | Some(left, right) -> Assert.Fail("Found match for brace '{0}'", marker) @@ -51,7 +50,7 @@ type BraceMatchingServiceTests() = Assert.IsTrue(endMarkerPosition >= 0, "Cannot find end marker '{0}' in file contents", endMarkerPosition) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, startMarkerPosition, "UnitTest") |> Async.RunSynchronously with + match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, startMarkerPosition, "UnitTest") |> Async.RunImmediate with | None -> Assert.Fail("Didn't find a match for start brace at position '{0}", startMarkerPosition) | Some(left, right) -> let endPositionInRange(range) = @@ -86,6 +85,19 @@ type BraceMatchingServiceTests() = member this.BracketInExpression() = this.VerifyBraceMatch("let x = (3*5)-1", "(3*", ")-1") + [] + member this.BraceInInterpolatedStringSimple() = + this.VerifyBraceMatch("let x = $\"abc{1}def\"", "{1", "}def") + + [] + member this.BraceInInterpolatedStringTwoHoles() = + this.VerifyBraceMatch("let x = $\"abc{1}def{2+3}hij\"", "{2", "}hij") + + [] + member this.BraceInInterpolatedStringNestedRecord() = + this.VerifyBraceMatch("let x = $\"abc{ id{contents=3}.contents }\"", "{contents", "}.contents") + this.VerifyBraceMatch("let x = $\"abc{ id{contents=3}.contents }\"", "{ id", "}\"") + [] [] member this.BraceInMultiLineCommentShouldNotBeMatched(startMarker: string) = diff --git a/vsintegration/tests/UnitTests/BreakpointResolutionService.fs b/vsintegration/tests/UnitTests/BreakpointResolutionService.fs index 8ccf2c69441..09b5e105857 100644 --- a/vsintegration/tests/UnitTests/BreakpointResolutionService.fs +++ b/vsintegration/tests/UnitTests/BreakpointResolutionService.fs @@ -13,8 +13,8 @@ open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor open Microsoft.VisualStudio.FSharp.LanguageService -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text open UnitTests.TestLib.LanguageService @@ -33,7 +33,6 @@ type BreakpointResolutionServiceTests() = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } let code = " @@ -73,10 +72,10 @@ let main argv = let searchPosition = code.IndexOf(searchToken) Assert.IsTrue(searchPosition >= 0, "SearchToken '{0}' is not found in code", searchToken) - let sourceText = SourceText.From(code) + let document, sourceText = RoslynTestHelpers.CreateDocument(fileName, code) let searchSpan = TextSpan.FromBounds(searchPosition, searchPosition + searchToken.Length) - let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let actualResolutionOption = FSharpBreakpointResolutionService.GetBreakpointLocation(checker, sourceText, fileName, searchSpan, parsingOptions) |> Async.RunSynchronously + + let actualResolutionOption = FSharpBreakpointResolutionService.GetBreakpointLocation(document, searchSpan) |> Async.RunSynchronously match actualResolutionOption with | None -> Assert.IsTrue(expectedResolution.IsNone, "BreakpointResolutionService failed to resolve breakpoint position") diff --git a/vsintegration/tests/UnitTests/CompletionProviderTests.fs b/vsintegration/tests/UnitTests/CompletionProviderTests.fs index 97ea7cbeff8..9003031df00 100644 --- a/vsintegration/tests/UnitTests/CompletionProviderTests.fs +++ b/vsintegration/tests/UnitTests/CompletionProviderTests.fs @@ -11,7 +11,7 @@ // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Service.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs .\VisualFSharp.UnitTests.exe *) // Technique 3: @@ -31,32 +31,32 @@ open Microsoft.CodeAnalysis.Completion open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open UnitTests.TestLib.LanguageService let filePath = "C:\\test.fs" -let internal projectOptions = { +let internal projectOptions opts = { ProjectFileName = "C:\\test.fsproj" ProjectId = None SourceFiles = [| filePath |] ReferencedProjects = [| |] - OtherOptions = [| |] + OtherOptions = opts IsIncompleteTypeCheckEnvironment = true UseScriptResolutionRules = false LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } let formatCompletions(completions : string seq) = "\n\t" + String.Join("\n\t", completions) -let VerifyCompletionList(fileContents: string, marker: string, expected: string list, unexpected: string list) = +let VerifyCompletionListWithOptions(fileContents: string, marker: string, expected: string list, unexpected: string list, opts) = let caretPosition = fileContents.IndexOf(marker) + marker.Length + let document, _ = RoslynTestHelpers.CreateDocument(filePath, fileContents) let results = - FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default) + FSharpCompletionProvider.ProvideCompletionsAsyncAux(document, caretPosition, (fun _ -> []), IntelliSenseOptions.Default) |> Async.RunSynchronously |> Option.defaultValue (ResizeArray()) |> Seq.map(fun result -> result.DisplayText) @@ -99,12 +99,15 @@ let VerifyCompletionList(fileContents: string, marker: string, expected: string let msg = sprintf "%s%s%s" expectedNotFoundMsg unexpectedFoundMsg completionsMsg Assert.Fail(msg) +let VerifyCompletionList(fileContents, marker, expected, unexpected) = + VerifyCompletionListWithOptions(fileContents, marker, expected, unexpected, [| |]) + let VerifyCompletionListExactly(fileContents: string, marker: string, expected: string list) = let caretPosition = fileContents.IndexOf(marker) + marker.Length - + let document, _ = RoslynTestHelpers.CreateDocument(filePath, fileContents) let actual = - FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default) + FSharpCompletionProvider.ProvideCompletionsAsyncAux(document, caretPosition, (fun _ -> []), IntelliSenseOptions.Default) |> Async.RunSynchronously |> Option.defaultValue (ResizeArray()) |> Seq.toList @@ -122,6 +125,13 @@ let VerifyCompletionListExactly(fileContents: string, marker: string, expected: let VerifyNoCompletionList(fileContents: string, marker: string) = VerifyCompletionListExactly(fileContents, marker, []) +let VerifyCompletionListSpan(fileContents: string, marker: string, expected: string) = + let caretPosition = fileContents.IndexOf(marker) + marker.Length + let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) + let sourceText = SourceText.From(fileContents) + let resultSpan = CompletionUtils.getDefaultCompletionListSpan(sourceText, caretPosition, documentId, filePath, []) + Assert.AreEqual(expected, sourceText.ToString(resultSpan)) + [] let ShouldTriggerCompletionAtCorrectMarkers() = let testCases = @@ -134,18 +144,18 @@ let ShouldTriggerCompletionAtCorrectMarkers() = ("System.", true) ("Console.", true) ] - for (marker: string, shouldBeTriggered: bool) in testCases do - let fileContents = """ + for (marker, shouldBeTriggered) in testCases do + let fileContents = """ let x = 1 let y = 2 System.Console.WriteLine(x + y) """ - let caretPosition = fileContents.IndexOf(marker) + marker.Length - let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) - let getInfo() = documentId, filePath, [] - let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo, IntelliSenseOptions.Default) - Assert.AreEqual(shouldBeTriggered, triggered, "FSharpCompletionProvider.ShouldTriggerCompletionAux() should compute the correct result") + let caretPosition = fileContents.IndexOf(marker) + marker.Length + let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) + let getInfo() = documentId, filePath, [] + let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo, IntelliSenseOptions.Default) + Assert.AreEqual(shouldBeTriggered, triggered, "FSharpCompletionProvider.ShouldTriggerCompletionAux() should compute the correct result") [] let ShouldNotTriggerCompletionAfterAnyTriggerOtherThanInsertionOrDeletion() = @@ -180,6 +190,32 @@ System.Console.WriteLine() let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo, IntelliSenseOptions.Default) Assert.IsFalse(triggered, "FSharpCompletionProvider.ShouldTriggerCompletionAux() should not trigger") +[] +let ShouldTriggerCompletionInInterpolatedString() = + let fileContents = """ + +let x = 1 +let y = 2 +let z = $"abc {System.Console.WriteLine(x + y)} def" +""" + let testCases = + [ + ("x", true) + ("y", true) + ("1", false) + ("2", false) + ("x +", false) + ("Console.Write", false) + ("System.", true) + ("Console.", true) ] + + for (marker, shouldBeTriggered) in testCases do + let caretPosition = fileContents.IndexOf(marker) + marker.Length + let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) + let getInfo() = documentId, filePath, [] + let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo, IntelliSenseOptions.Default) + Assert.AreEqual(shouldBeTriggered, triggered, sprintf "FSharpCompletionProvider.ShouldTriggerCompletionAux() should compute the correct result for marker '%s'" marker) + [] let ShouldNotTriggerCompletionInExcludedCode() = let fileContents = """ @@ -306,12 +342,22 @@ System.Console.WriteLine() """ VerifyCompletionList(fileContents, "System.", ["Console"; "Array"; "String"], ["T1"; "M1"; "M2"]) +[] +let ShouldDisplaySystemNamespaceInInterpolatedString() = + let fileContents = """ +type T1 = + member this.M1 = 5 + member this.M2 = "literal" +let x = $"1 not the same as {System.Int32.MaxValue} is it" +""" + VerifyCompletionListWithOptions(fileContents, "System.", ["Console"; "Array"; "String"], ["T1"; "M1"; "M2"], [| "/langversion:preview" |]) + [] let ``Class instance members are ordered according to their kind and where they are defined (simple case, by a variable)``() = let fileContents = """ type Base() = - member __.BaseMethod() = 1 - member __.BaseProp = 1 + member _.BaseMethod() = 1 + member _.BaseProp = 1 type Class() = inherit Base() @@ -328,8 +374,8 @@ x. let ``Class instance members are ordered according to their kind and where they are defined (simple case, by a constructor)``() = let fileContents = """ type Base() = - member __.BaseMethod() = 1 - member __.BaseProp = 1 + member _.BaseMethod() = 1 + member _.BaseProp = 1 type Class() = inherit Base() @@ -364,8 +410,8 @@ let ``Class instance members are ordered according to their kind and where they let fileContents = """ type Base() = inherit System.Collections.Generic.List - member __.BaseMethod() = 1 - member __.BaseProp = 1 + member _.BaseMethod() = 1 + member _.BaseProp = 1 type Class() = inherit Base() @@ -433,8 +479,8 @@ let ``Extension methods go after everything else, extension properties are treat open System.Collections.Generic type List<'a> with - member __.ExtensionProp = 1 - member __.ExtensionMeth() = 1 + member _.ExtensionProp = 1 + member _.ExtensionMeth() = 1 List(). """ @@ -447,7 +493,7 @@ List(). [] let ``Completion for open contains namespaces and static types``() = let fileContents = """ -open System.Ma +open type System.Ma """ let expected = ["Management"; "Math"] // both namespace and static type VerifyCompletionList(fileContents, "System.Ma", expected, []) @@ -648,6 +694,48 @@ module Extensions = """ VerifyCompletionList(fileContents, "wrappedMessage.", ["PrintRef"], []) +[] +let ``Completion list span works with underscore in identifier``() = + let fileContents = """ +let x = A.B_C +""" + VerifyCompletionListSpan(fileContents, "A.B_C", "B_C") + +[] +let ``Completion list span works with digit in identifier``() = + let fileContents = """ +let x = A.B1C +""" + VerifyCompletionListSpan(fileContents, "A.B1C", "B1C") + +[] +let ``Completion list span works with enclosed backtick identifier``() = + let fileContents = """ +let x = A.``B C`` +""" + VerifyCompletionListSpan(fileContents, "A.``B C``", "``B C``") + +[] +let ``Completion list span works with partial backtick identifier``() = + let fileContents = """ +let x = A.``B C +""" + VerifyCompletionListSpan(fileContents, "A.``B C", "``B C") + +[] +let ``Completion list span works with first of multiple enclosed backtick identifiers``() = + let fileContents = """ +let x = A.``B C`` + D.``E F`` +""" + VerifyCompletionListSpan(fileContents, "A.``B C``", "``B C``") + +[] +let ``Completion list span works with last of multiple enclosed backtick identifiers``() = + let fileContents = """ +let x = A.``B C`` + D.``E F`` +""" + VerifyCompletionListSpan(fileContents, "D.``E F``", "``E F``") + #if EXE ShouldDisplaySystemNamespace() #endif diff --git a/vsintegration/tests/UnitTests/DocumentDiagnosticAnalyzerTests.fs b/vsintegration/tests/UnitTests/DocumentDiagnosticAnalyzerTests.fs index 6fb3909079a..2f3b76b2965 100644 --- a/vsintegration/tests/UnitTests/DocumentDiagnosticAnalyzerTests.fs +++ b/vsintegration/tests/UnitTests/DocumentDiagnosticAnalyzerTests.fs @@ -14,8 +14,8 @@ open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor open Microsoft.VisualStudio.FSharp.LanguageService -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text open UnitTests.TestLib.LanguageService @@ -35,15 +35,14 @@ type DocumentDiagnosticAnalyzerTests() = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } let getDiagnostics (fileContents: string) = async { - let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let! syntacticDiagnostics = FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(checker, filePath, SourceText.From(fileContents), 0, parsingOptions, projectOptions, DiagnosticsType.Syntax) - let! semanticDiagnostics = FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(checker, filePath, SourceText.From(fileContents), 0, parsingOptions, projectOptions, DiagnosticsType.Semantic) + let document, _ = RoslynTestHelpers.CreateDocument(filePath, fileContents) + let! syntacticDiagnostics = FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(document, DiagnosticsType.Syntax) + let! semanticDiagnostics = FSharpDocumentDiagnosticAnalyzer.GetDiagnostics(document, DiagnosticsType.Semantic) return syntacticDiagnostics.AddRange(semanticDiagnostics) } |> Async.RunSynchronously @@ -54,7 +53,8 @@ type DocumentDiagnosticAnalyzerTests() = | Some(flags) -> {projectOptions with OtherOptions = Array.append projectOptions.OtherOptions flags} let errors = getDiagnostics fileContents - Assert.AreEqual(0, errors.Length, "There should be no errors generated") + if not errors.IsEmpty then + Assert.Fail("There should be no errors generated", errors) member private this.VerifyErrorAtMarker(fileContents: string, expectedMarker: string, ?expectedMessage: string) = let errors = getDiagnostics fileContents |> Seq.filter(fun e -> e.Severity = DiagnosticSeverity.Error) |> Seq.toArray diff --git a/vsintegration/tests/UnitTests/DocumentHighlightsServiceTests.fs b/vsintegration/tests/UnitTests/DocumentHighlightsServiceTests.fs index 07d4eed0756..f7074122dd5 100644 --- a/vsintegration/tests/UnitTests/DocumentHighlightsServiceTests.fs +++ b/vsintegration/tests/UnitTests/DocumentHighlightsServiceTests.fs @@ -11,12 +11,12 @@ // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Service.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs .\VisualFSharp.UnitTests.exe *) // Technique 3: // -// Use F# Interactive. This only works for FSharp.Compiler.Private.dll which has a public API +// Use F# Interactive. This only works for FSharp.Compiler.Service.dll which has a public API // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. [] @@ -31,8 +31,8 @@ open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text open UnitTests.TestLib.LanguageService let filePath = "C:\\test.fs" @@ -48,18 +48,17 @@ let internal projectOptions = { LoadTime = DateTime.MaxValue UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo = None Stamp = None } let private getSpans (sourceText: SourceText) (caretPosition: int) = - let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) - FSharpDocumentHighlightsService.GetDocumentHighlights(checker, documentId, sourceText, filePath, caretPosition, [], projectOptions, 0, LanguageServicePerformanceOptions.Default) + let document = RoslynTestHelpers.CreateDocument(filePath, sourceText) + FSharpDocumentHighlightsService.GetDocumentHighlights(document, caretPosition) |> Async.RunSynchronously |> Option.defaultValue [||] let private span sourceText isDefinition (startLine, startCol) (endLine, endCol) = - let range = Range.mkRange filePath (Range.mkPos startLine startCol) (Range.mkPos endLine endCol) + let range = Range.mkRange filePath (Position.mkPos startLine startCol) (Position.mkPos endLine endCol) { IsDefinition = isDefinition TextSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range) } diff --git a/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs b/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs index fbcfc1125af..583e52e59ba 100644 --- a/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs +++ b/vsintegration/tests/UnitTests/EditorFormattingServiceTests.fs @@ -8,7 +8,7 @@ open NUnit.Framework open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Microsoft.CodeAnalysis.Formatting [] @@ -26,7 +26,6 @@ type EditorFormattingServiceTests() = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } @@ -78,7 +77,7 @@ marker4""" let lineNumber = sourceText.Lines |> Seq.findIndex (fun line -> line.Span.Contains position) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let changesOpt = FSharpEditorFormattingService.GetFormattingChanges(documentId, sourceText, filePath, checker, indentStyle, Some (parsingOptions, projectOptions), position) |> Async.RunSynchronously + let changesOpt = FSharpEditorFormattingService.GetFormattingChanges(documentId, sourceText, filePath, checker, indentStyle, parsingOptions, position) |> Async.RunSynchronously match changesOpt with | None -> Assert.Fail("Expected a text change, but got None") | Some changes -> @@ -95,7 +94,7 @@ marker4""" let clipboard = prefix + """[] type SomeNameHere () = - member __.Test ()""" + member _.Test ()""" let start = """ @@ -112,7 +111,7 @@ let foo = printfn "Something here" [] type SomeNameHere () = - member __.Test () + member _.Test () somethingElseHere """ @@ -144,7 +143,7 @@ somethingElseHere let clipboard = prefix + """[] type SomeNameHere () = - member __.Test ()""" + member _.Test ()""" let start = """ $ @@ -158,7 +157,7 @@ somethingElseHere let expected = """ [] type SomeNameHere () = - member __.Test () + member _.Test () let foo = printfn "Something here" @@ -189,7 +188,7 @@ somethingElseHere let clipboard = """[] type SomeNameHere () = - member __.Test ()""" + member _.Test ()""" let start = """ @@ -206,7 +205,7 @@ let foo = printfn "Something here" [] type SomeNameHere () = - member __.Test () + member _.Test () somethingElseHere """ diff --git a/vsintegration/tests/UnitTests/FsxCompletionProviderTests.fs b/vsintegration/tests/UnitTests/FsxCompletionProviderTests.fs index 468c916dc95..7441639316f 100644 --- a/vsintegration/tests/UnitTests/FsxCompletionProviderTests.fs +++ b/vsintegration/tests/UnitTests/FsxCompletionProviderTests.fs @@ -10,7 +10,7 @@ // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\FsxCompletionProviderTests.fs + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Service.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\FsxCompletionProviderTests.fs .\VisualFSharp.UnitTests.exe *) // Technique 3: @@ -33,15 +33,14 @@ open Microsoft.CodeAnalysis.Completion open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open UnitTests.TestLib.LanguageService // AppDomain helper type Worker () = - inherit MarshalByRefObject() - + let filePath = "C:\\test.fsx" - let projectOptions = { + let projectOptions = { ProjectFileName = "C:\\test.fsproj" ProjectId = None SourceFiles = [| filePath |] @@ -52,66 +51,15 @@ type Worker () = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } - let formatCompletions(completions : string seq) = - "\n\t" + String.Join("\n\t", completions) - - let VerifyCompletionList(fileContents: string, marker: string, expected: string list, unexpected: string list) = - let caretPosition = fileContents.IndexOf(marker) + marker.Length - let results = - FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default) - |> Async.RunSynchronously - |> Option.defaultValue (ResizeArray()) - |> Seq.map(fun result -> result.DisplayText) - - let expectedFound = - expected - |> Seq.filter results.Contains - - let expectedNotFound = - expected - |> Seq.filter (expectedFound.Contains >> not) - - let unexpectedNotFound = - unexpected - |> Seq.filter (results.Contains >> not) - - let unexpectedFound = - unexpected - |> Seq.filter (unexpectedNotFound.Contains >> not) - - // If either of these are true, then the test fails. - let hasExpectedNotFound = not (Seq.isEmpty expectedNotFound) - let hasUnexpectedFound = not (Seq.isEmpty unexpectedFound) - - if hasExpectedNotFound || hasUnexpectedFound then - let expectedNotFoundMsg = - if hasExpectedNotFound then - sprintf "\nExpected completions not found:%s\n" (formatCompletions expectedNotFound) - else - String.Empty - - let unexpectedFoundMsg = - if hasUnexpectedFound then - sprintf "\nUnexpected completions found:%s\n" (formatCompletions unexpectedFound) - else - String.Empty - - let completionsMsg = sprintf "\nin Completions:%s" (formatCompletions results) - - let msg = sprintf "%s%s%s" expectedNotFoundMsg unexpectedFoundMsg completionsMsg - - Assert.Fail(msg) - - member __.VerifyCompletionListExactly(fileContents: string, marker: string, expected: List) = - + member _.VerifyCompletionListExactly(fileContents: string, marker: string, expected: List) = let caretPosition = fileContents.IndexOf(marker) + marker.Length + let document = RoslynTestHelpers.CreateDocument(filePath, SourceText.From(fileContents), options = projectOptions) let expected = expected |> Seq.toList let actual = - let x = FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default) + let x = FSharpCompletionProvider.ProvideCompletionsAsyncAux(document, caretPosition, (fun _ -> []), IntelliSenseOptions.Default) |> Async.RunSynchronously x |> Option.defaultValue (ResizeArray()) |> Seq.toList @@ -128,22 +76,10 @@ type Worker () = module FsxCompletionProviderTests = - let pathToThisDll = Assembly.GetExecutingAssembly().CodeBase - - let getWorker () = - - let adSetup = - let setup = new System.AppDomainSetup () - setup.PrivateBinPath <- pathToThisDll - setup.ApplicationBase <- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SomeNonExistentDirectory") - setup - - let ad = AppDomain.CreateDomain((Guid()).ToString(), null, adSetup) - (ad.CreateInstanceFromAndUnwrap(pathToThisDll, typeof.FullName)) :?> Worker + let getWorker () = Worker() [] let fsiShouldTriggerCompletionInFsxFile() = - let fileContents = """ fsi. """ diff --git a/vsintegration/tests/UnitTests/GoToDefinitionServiceTests.fs b/vsintegration/tests/UnitTests/GoToDefinitionServiceTests.fs index 17322b8faa3..49527630ff6 100644 --- a/vsintegration/tests/UnitTests/GoToDefinitionServiceTests.fs +++ b/vsintegration/tests/UnitTests/GoToDefinitionServiceTests.fs @@ -12,12 +12,12 @@ // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\GoToDefinitionServiceTests.fs + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Service.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\GoToDefinitionServiceTests.fs .\VisualFSharp.UnitTests.exe *) // Technique 3: // -// Use F# Interactive. This only works for FSharp.Compiler.Private.dll which has a public API +// Use F# Interactive. This only works for FSharp.Compiler.Service.dll which has a public API namespace Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn @@ -28,8 +28,10 @@ open NUnit.Framework open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text open UnitTests.TestLib.LanguageService [][] @@ -39,29 +41,54 @@ module GoToDefinitionServiceTests = let private findDefinition ( - checker: FSharpChecker, - documentKey: DocumentId, - sourceText: SourceText, - filePath: string, + document: Document, + sourceText: SourceText, position: int, - defines: string list, - options: FSharpProjectOptions, - textVersionHash: int + defines: string list ) : range option = maybe { let textLine = sourceText.Lines.GetLineFromPosition position let textLinePos = sourceText.Lines.GetLinePosition position let fcsTextLineNumber = Line.fromZ textLinePos.Line - let! lexerSymbol = Tokenizer.getSymbolAtPosition(documentKey, sourceText, position, filePath, defines, SymbolLookupKind.Greedy, false) - let! _, _, checkFileResults = checker.ParseAndCheckDocument (filePath, textVersionHash, sourceText, options, LanguageServicePerformanceOptions.Default, userOpName=userOpName) |> Async.RunSynchronously + let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false, false) + let _, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(userOpName)) |> Async.RunSynchronously - let declarations = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland, false, userOpName=userOpName) |> Async.RunSynchronously + let declarations = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland, false) match declarations with - | FSharpFindDeclResult.DeclFound range -> return range + | FindDeclResult.DeclFound range -> return range | _ -> return! None } + let makeOptions filePath args = + { + ProjectFileName = "C:\\test.fsproj" + ProjectId = None + SourceFiles = [| filePath |] + ReferencedProjects = [| |] + OtherOptions = args + IsIncompleteTypeCheckEnvironment = true + UseScriptResolutionRules = false + LoadTime = DateTime.MaxValue + OriginalLoadReferences = [] + UnresolvedReferences = None + Stamp = None + } + + let GoToDefinitionTest (fileContents: string, caretMarker: string, expected) = + + let filePath = Path.GetTempFileName() + ".fs" + File.WriteAllText(filePath, fileContents) + + let caretPosition = fileContents.IndexOf(caretMarker) + caretMarker.Length - 1 // inside the marker + let document, sourceText = RoslynTestHelpers.CreateDocument(filePath, fileContents) + let actual = + findDefinition(document, sourceText, caretPosition, []) + |> Option.map (fun range -> (range.StartLine, range.EndLine, range.StartColumn, range.EndColumn)) + + if actual <> expected then + Assert.Fail(sprintf "Incorrect information returned for fileContents=<<<%s>>>, caretMarker=<<<%s>>>, expected =<<<%A>>>, actual = <<<%A>>>" fileContents caretMarker expected actual) + [] let VerifyDefinition() = @@ -100,33 +127,20 @@ let _ = Module1.foo 1 for caretMarker, expected in testCases do printfn "Test case: caretMarker=<<<%s>>>" caretMarker - let filePath = Path.GetTempFileName() + ".fs" - let options: FSharpProjectOptions = { - ProjectFileName = "C:\\test.fsproj" - ProjectId = None - SourceFiles = [| filePath |] - ReferencedProjects = [| |] - OtherOptions = [| |] - IsIncompleteTypeCheckEnvironment = true - UseScriptResolutionRules = false - LoadTime = DateTime.MaxValue - OriginalLoadReferences = [] - UnresolvedReferences = None - ExtraProjectInfo = None - Stamp = None - } + GoToDefinitionTest (fileContents, caretMarker, expected) - File.WriteAllText(filePath, fileContents) + [] + let VerifyDefinitionStringInterpolation() = - let caretPosition = fileContents.IndexOf(caretMarker) + caretMarker.Length - 1 // inside the marker - let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) - let actual = - findDefinition(checker, documentId, SourceText.From(fileContents), filePath, caretPosition, [], options, 0) - |> Option.map (fun range -> (range.StartLine, range.EndLine, range.StartColumn, range.EndColumn)) + let fileContents = """ +let xxxxx = 1 +let yyyy = $"{abc{xxxxx}def}" """ + let caretMarker = "xxxxx" + let expected = Some(2, 2, 4, 9) - if actual <> expected then - Assert.Fail(sprintf "Incorrect information returned for fileContents=<<<%s>>>, caretMarker=<<<%s>>>, expected =<<<%A>>>, actual = <<<%A>>>" fileContents caretMarker expected actual) + GoToDefinitionTest (fileContents, caretMarker, expected) #if EXE VerifyDefinition() + VerifyDefinitionStringInterpolation() #endif \ No newline at end of file diff --git a/vsintegration/tests/UnitTests/IndentationServiceTests.fs b/vsintegration/tests/UnitTests/IndentationServiceTests.fs index d16c48ddab2..7c535ccdff9 100644 --- a/vsintegration/tests/UnitTests/IndentationServiceTests.fs +++ b/vsintegration/tests/UnitTests/IndentationServiceTests.fs @@ -11,7 +11,7 @@ open Microsoft.CodeAnalysis.Classification open Microsoft.CodeAnalysis.Editor open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Microsoft.CodeAnalysis.Formatting open UnitTests.TestLib.LanguageService @@ -30,7 +30,6 @@ type IndentationServiceTests() = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } @@ -176,7 +175,7 @@ while true do let sourceText = SourceText.From(template) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, Some (parsingOptions, projectOptions)) + let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, parsingOptions) match expectedIndentation with | None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber) @@ -189,7 +188,7 @@ while true do let sourceText = SourceText.From(template) let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, Some (parsingOptions, projectOptions)) + let actualIndentation = FSharpIndentationService.GetDesiredIndentation(documentId, sourceText, filePath, lineNumber, tabSize, indentStyle, parsingOptions) match expectedIndentation with | None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber) diff --git a/vsintegration/tests/UnitTests/LanguageDebugInfoServiceTests.fs b/vsintegration/tests/UnitTests/LanguageDebugInfoServiceTests.fs index 189f0d05027..6c2968a16ca 100644 --- a/vsintegration/tests/UnitTests/LanguageDebugInfoServiceTests.fs +++ b/vsintegration/tests/UnitTests/LanguageDebugInfoServiceTests.fs @@ -6,16 +6,12 @@ open System.Threading open NUnit.Framework -open Microsoft.CodeAnalysis.Classification -open Microsoft.CodeAnalysis.Editor open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis open Microsoft.VisualStudio.FSharp.Editor -open Microsoft.VisualStudio.FSharp.LanguageService -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range +open FSharp.Compiler.Text [][] type LanguageDebugInfoServiceTests() = diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs index a1ea76e7172..6b9eda12e1a 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs @@ -3,6 +3,7 @@ namespace Tests.LanguageService.AutoCompletion open System +open Microsoft.VisualStudio.FSharp.LanguageService open Salsa.Salsa open Salsa.VsMocks open Salsa.VsOpsUtils @@ -28,19 +29,20 @@ module StandardSettings = type UsingMSBuild() as this = inherit LanguageServiceBaseTests() - let createFile (code : list) fileKind refs = + let createFile (code : list) fileKind refs otherFlags = let (_, _, file) = match code with | [code] when code.IndexOfAny([|'\r'; '\n'|]) <> -1 -> - this.CreateSingleFileProject(code, fileKind = fileKind, references = refs) - | code -> this.CreateSingleFileProject(code, fileKind = fileKind, references = refs) + this.CreateSingleFileProject(code, fileKind = fileKind, references = refs, ?otherFlags=otherFlags) + | code -> + this.CreateSingleFileProject(code, fileKind = fileKind, references = refs, ?otherFlags=otherFlags) file - let DoWithAutoCompleteUsingExtraRefs refs coffeeBreak fileKind reason (code : list) marker f = + let DoWithAutoCompleteUsingExtraRefs refs otherFlags coffeeBreak fileKind reason (code : list) marker f = // Up to 2 untyped parse operations are OK: we do an initial parse to provide breakpoint valdiation etc. // This might be before the before the background builder is ready to process the foreground typecheck. // In this case the background builder calls us back when its ready, and we then request a foreground typecheck - let file = createFile code fileKind refs + let file = createFile code fileKind refs otherFlags if coffeeBreak then TakeCoffeeBreak(this.VS) @@ -51,33 +53,43 @@ type UsingMSBuild() as this = gpatcc.AssertExactly(0,0) - let DoWithAutoComplete coffeeBreak fileKind reason (code : list) marker f = DoWithAutoCompleteUsingExtraRefs [] coffeeBreak fileKind reason code marker f + let DoWithAutoComplete coffeeBreak fileKind reason otherFlags (code : list) marker f = + DoWithAutoCompleteUsingExtraRefs [] otherFlags coffeeBreak fileKind reason code marker f - let AssertAutoCompleteContains, AssertAutoCompleteContainsNoCoffeeBreak, AutoCompleteInInterfaceFileContains, AssertCtrlSpaceCompleteContains, AssertCtrlSpaceCompleteContainsNoCoffeeBreak = - let AssertAutoCompleteContains coffeeBreak filename reason code marker should shouldnot = - DoWithAutoComplete coffeeBreak filename reason code marker <| - fun completions -> - AssertCompListContainsAll(completions, should) - AssertCompListDoesNotContainAny(completions, shouldnot) + let AssertAutoCompleteContainsAux coffeeBreak filename reason otherFlags code marker should shouldnot = + DoWithAutoComplete coffeeBreak filename reason otherFlags code marker (fun completions -> + AssertCompListContainsAll(completions, should) + AssertCompListDoesNotContainAny(completions, shouldnot)) + + let AssertAutoCompleteContains = + AssertAutoCompleteContainsAux true SourceFileKind.FS BackgroundRequestReason.MemberSelect None + + let AssertAutoCompleteContainsNoCoffeeBreak = + AssertAutoCompleteContainsAux false SourceFileKind.FS BackgroundRequestReason.MemberSelect None + + let AutoCompleteInInterfaceFileContains = + AssertAutoCompleteContainsAux true SourceFileKind.FSI BackgroundRequestReason.MemberSelect None - ((AssertAutoCompleteContains true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect), - (AssertAutoCompleteContains false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect), - (AssertAutoCompleteContains true SourceFileKind.FSI Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect), - (AssertAutoCompleteContains true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord), - (AssertAutoCompleteContains false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord)) + let AssertCtrlSpaceCompleteContains = + AssertAutoCompleteContainsAux true SourceFileKind.FS BackgroundRequestReason.CompleteWord None + + let AssertCtrlSpaceCompleteContainsWithOtherFlags otherFlags = + AssertAutoCompleteContainsAux true SourceFileKind.FS BackgroundRequestReason.CompleteWord (Some otherFlags) + + let AssertCtrlSpaceCompleteContainsNoCoffeeBreak = + AssertAutoCompleteContainsAux false SourceFileKind.FS BackgroundRequestReason.CompleteWord None let AssertCtrlSpaceCompletionListIsEmpty code marker = - DoWithAutoComplete true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord code marker AssertCompListIsEmpty + DoWithAutoComplete true SourceFileKind.FS BackgroundRequestReason.CompleteWord None code marker AssertCompListIsEmpty let AssertCtrlSpaceCompletionListIsEmptyNoCoffeeBreak code marker = - DoWithAutoComplete false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord code marker AssertCompListIsEmpty + DoWithAutoComplete false SourceFileKind.FS BackgroundRequestReason.CompleteWord None code marker AssertCompListIsEmpty let AssertAutoCompleteCompletionListIsEmpty code marker = - DoWithAutoComplete true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect code marker AssertCompListIsEmpty + DoWithAutoComplete true SourceFileKind.FS BackgroundRequestReason.MemberSelect None code marker AssertCompListIsEmpty let AssertAutoCompleteCompletionListIsEmptyNoCoffeeBreak code marker = - DoWithAutoComplete false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect code marker AssertCompListIsEmpty - + DoWithAutoComplete false SourceFileKind.FS BackgroundRequestReason.MemberSelect None code marker AssertCompListIsEmpty let testAutoCompleteAdjacentToDot op = let text = sprintf "System.Console%s" op @@ -334,22 +346,22 @@ a. [ [ "type A() =" - " member __.X = ()" + " member _.X = ()" " member this." ] [ "type A() =" - " member __.X = ()" + " member _.X = ()" " member private this." ] [ "type A() =" - " member __.X = ()" + " member _.X = ()" " member public this." ] [ "type A() =" - " member __.X = ()" + " member _.X = ()" " member internal this." ] @@ -365,7 +377,7 @@ a. [] member this.``TypeProvider.VisibilityChecksForGeneratedTypes``() = let extraRefs = [PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll")] - let check = DoWithAutoCompleteUsingExtraRefs extraRefs true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect + let check = DoWithAutoCompleteUsingExtraRefs extraRefs None true SourceFileKind.FS BackgroundRequestReason.MemberSelect let code = [ @@ -507,10 +519,10 @@ a. [ "type Foo = Foo" " with" - " member __.Bar = 1" - " member __.PublicMethodForIntellisense() = 2" - " member internal __.InternalMethod() = 3" - " member private __.PrivateProperty = 4" + " member _.Bar = 1" + " member _.PublicMethodForIntellisense() = 2" + " member internal _.InternalMethod() = 3" + " member private _.PrivateProperty = 4" "" "let u: Unit =" " [ Foo ]" @@ -820,8 +832,8 @@ for i in 0..a."] let prologue = [ "type X =" - " val field1 : int" - " val field2 : string" + " val field1: int" + " val field2: string" ] let useCases = @@ -841,8 +853,8 @@ for i in 0..a."] let prologue = [ "type X =" - " val _field1 : int" - " val _field2 : string" + " val _field1: int" + " val _field2: string" ] let useCases = @@ -927,8 +939,8 @@ for i in 0..a."] "type A = class end" "type B = " " inherit A" - " val f1 : int" - " val f2 : int" + " val f1: int" + " val f2: int" ] let useCases = @@ -1015,8 +1027,8 @@ for i in 0..a."] let prologue = [ "type X =" - " val field1 : int" - " val field2 : string" + " val field1: int" + " val field2: string" ] let useCases = @@ -1460,25 +1472,6 @@ let x = new MyClass2(0) [ "BackgroundColor" ] // should contain (from prior System.Console) [ "abs" ] // should not contain (top-level autocomplete on empty identifier) - [] - member public this.``PopupsVersusCtrlSpaceOnDotDot.SecondDot.Popup``() = - // Salsa is no yet capable of determining whether there would be a popup, it can only test what would appear if there were. - // So can't do test below. -// AssertAutoCompleteContainsNoCoffeeBreak -// [ "System.Console..BackgroundColor" ] -// "System.Console.." -// [ ] // should be empty - in fact, there is no popup here -// [ "abs"; "BackgroundColor" ] // should not contain anything - () - - [] - member public this.``PopupsVersusCtrlSpaceOnDotDot.SecondDot.CtrlSpace``() = - AssertCtrlSpaceCompleteContainsNoCoffeeBreak - [ "System.Console..BackgroundColor" ] - "System.Console.." - [ ] // should contain nothing - .. is not properly used range operator - [ "abs" ] // should not contain (from prior System.Console) - [] member public this.``DotCompletionInPatternsPartOfLambda``() = let content = ["let _ = fun x . -> x + 1"] @@ -3119,6 +3112,38 @@ let x = query { for bbbb in abbbbc(*D0*) do [ "abs" ] // should contain (top level) [ "CompareTo" ] // should not contain (from Int32) + [] + member public this.``Array.AfterOperator...Bug65732_B2``() = + AssertCtrlSpaceCompleteContains + [ "let r = [System.Int32.MaxValue.. 42]" ] + ".." // marker + [ "abs" ] // should contain (top level) + [ "CompareTo" ] // should not contain (from Int32) + + [] + member public this.``Array.AfterOperator...Bug65732_B3``() = + AssertCtrlSpaceCompleteContains + [ "let r = [System.Int32.MaxValue .. 42]" ] + ".." // marker + [ "abs" ] // should contain (top level) + [ "CompareTo" ] // should not contain (from Int32) + + [] + member public this.``Array.AfterOperator...Bug65732_C``() = + AssertCtrlSpaceCompleteContains + [ "let r = [System.Int32.MaxValue..]" ] + ".." // marker + [ "abs" ] // should contain (top level) + [ "CompareTo" ] // should not contain (from Int32) + + [] + member public this.``Array.AfterOperator...Bug65732_D``() = + AssertCtrlSpaceCompleteContains + [ "let r = [System.Int32.MaxValue .. ]" ] + ".." // marker + [ "abs" ] // should contain (top level) + [ "CompareTo" ] // should not contain (from Int32) + // Verify the auto completion after the close-parentheses, // there should be auto completion [] @@ -3332,6 +3357,264 @@ let x = query { for bbbb in abbbbc(*D0*) do ["b"] ["i"] + [] + member public this.``CompletionForAndBang_BaseLine0``() = + AssertCtrlSpaceCompleteContains + ["type Builder() =" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "builder {" + " let! xxx3 = 2" + " return x" + "}"] + " return x" + ["xxx3"] + [] + + [] + member public this.``CompletionForAndBang_BaseLine1``() = + AssertCtrlSpaceCompleteContains + ["type Builder() =" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let xxx1 = 1" + "builder {" + " let xxx2 = 1" + " let! xxx3 = 1" + " return (1 + x)" + "}"] + " return (1 + x" + ["xxx1"; "xxx2"; "xxx3"] + [] + + [] + member public this.``CompletionForAndBang_BaseLine2``() = + /// Without closing '}' + AssertCtrlSpaceCompleteContains + ["type Builder() =" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let yyy1 = 1" + "builder {" + " let yyy2 = 1" + " let! yyy3 = 1" + " return (1 + y)"] + " return (1 + y" + ["yyy1"; "yyy2"; "yyy3"] + [] + + [] + member public this.``CompletionForAndBang_BaseLine3``() = + /// Without closing ')' + AssertCtrlSpaceCompleteContains + ["type Builder() =" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let zzz2 = 1" + " let! zzz3 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz2"; "zzz3"] + [] + + [] + member public this.``CompletionForAndBang_BaseLine4``() = + AssertCtrlSpaceCompleteContains + ["type Builder() =" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let! zzz3 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz3"] + [] + + [] + member public this.``CompletionForAndBang_Test_MergeSources_Bind_Return0``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.MergeSources(a: 'T1, b: 'T2) = (a, b)" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "builder {" + " let! xxx3 = 2" + " and! xxx4 = 2" + " return x" + "}"] + " return x" + ["xxx3"; "xxx4"] + [] + + [] + member public this.``CompletionForAndBang_Test_MergeSources_Bind_Return1``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.MergeSources(a: 'T1, b: 'T2) = (a, b)" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let xxx1 = 1" + "builder {" + " let xxx2 = 1" + " let! xxx3 = 1" + " and! xxx4 = 1" + " return (1 + x)" + "}"] + " return (1 + x" + ["xxx1"; "xxx2"; "xxx3"; "xxx4"] + [] + + [] + member public this.``CompletionForAndBang_Test_MergeSources_Bind_Return2``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.MergeSources(a: 'T1, b: 'T2) = (a, b)" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let yyy1 = 1" + "builder {" + " let yyy2 = 1" + " let! yyy3 = 1" + " and! yyy4 = 1" + " return (1 + y)"] + " return (1 + y" + ["yyy1"; "yyy2"; "yyy3"; "yyy4"] + [] + + [] + member public this.``CompletionForAndBang_Test_MergeSources_Bind_Return3``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.MergeSources(a: 'T1, b: 'T2) = (a, b)" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let zzz2 = 1" + " let! zzz3 = 1" + " and! zzz4 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz2"; "zzz3"; "zzz4"] + [] + + [] + member public this.``CompletionForAndBang_Test_MergeSources_Bind_Return4``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.MergeSources(a: 'T1, b: 'T2) = (a, b)" + " member x.Bind(a: 'T1, f: 'T1 -> 'T2) = f a" + " member x.Return(a: 'T) = a" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let! zzz3 = 1" + " and! zzz4 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz3"; "zzz4"] + [] + + [] + member public this.``CompletionForAndBang_Test_Bind2Return0``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.Bind2Return(a: 'T1, b: 'T2, f: ('T1 * 'T2) -> 'T3) = f (a, b)" + "let builder = Builder()" + "builder {" + " let! xxx3 = 2" + " and! xxx4 = 2" + " return x" + "}"] + " return x" + ["xxx3"; "xxx4"] + [] + + [] + member public this.``CompletionForAndBang_Test_Bind2Return1``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.Bind2Return(a: 'T1, b: 'T2, f: ('T1 * 'T2) -> 'T3) = f (a, b)" + "let builder = Builder()" + "let xxx1 = 1" + "builder {" + " let xxx2 = 1" + " let! xxx3 = 1" + " and! xxx4 = 1" + " return (1 + x)" + "}"] + " return (1 + x" + ["xxx1"; "xxx2"; "xxx3"; "xxx4"] + [] + + [] + member public this.``CompletionForAndBang_Test_Bind2Return2``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.Bind2Return(a: 'T1, b: 'T2, f: ('T1 * 'T2) -> 'T3) = f (a, b)" + "let builder = Builder()" + "let yyy1 = 1" + "builder {" + " let yyy2 = 1" + " let! yyy3 = 1" + " and! yyy4 = 1" + " return (1 + y)"] + " return (1 + y" + ["yyy1"; "yyy2"; "yyy3"; "yyy4"] + [] + + [] + member public this.``CompletionForAndBang_Test_Bind2Return3``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.Bind2Return(a: 'T1, b: 'T2, f: ('T1 * 'T2) -> 'T3) = f (a, b)" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let zzz2 = 1" + " let! zzz3 = 1" + " and! zzz4 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz2"; "zzz3"; "zzz4"] + [] + + [] + member public this.``CompletionForAndBang_Test_Bind2Return4``() = + AssertCtrlSpaceCompleteContainsWithOtherFlags + "/langversion:preview" + ["type Builder() =" + " member x.Bind2Return(a: 'T1, b: 'T2, f: ('T1 * 'T2) -> 'T3) = f (a, b)" + "let builder = Builder()" + "let zzz1 = 1" + "builder {" + " let! zzz3 = 1" + " and! zzz4 = 1" + " return (1 + z" ] + " return (1 + z" + ["zzz1"; "zzz3"; "zzz4"] + [] (**) [] @@ -3546,13 +3829,6 @@ let x = query { for bbbb in abbbbc(*D0*) do [] - member public this.``Attribute.WhenAttachedToNothing.Bug70080``() = - this.AutoCompleteBug70080Helper(@" - open System - [] member public this.``Attribute.WhenAttachedToLetInNamespace.Bug70080``() = this.AutoCompleteBug70080Helper @" @@ -3601,7 +3877,7 @@ let x = query { for bbbb in abbbbc(*D0*) do [ @" type C() = let someValue = ""abc"" - member __.M() = + member _.M() = let x = 1 match someValue. with let x = 1 @@ -3639,8 +3915,8 @@ let x = query { for bbbb in abbbbc(*D0*) do AssertAutoCompleteContains [ "open System." ] "." // marker - [ "Collections"; "Console" ] // should contain (namespace, static type) - [ "Int32" ] // should not contain (non-static type) + [ "Collections" ] // should contain (namespace) + [ ] // should not contain [] member public this.``OpenNamespaceOrModule.CompletionOnlyContainsNamespaceOrModule.Case2``() = @@ -4001,7 +4277,7 @@ let x = query { for bbbb in abbbbc(*D0*) do member public this.``InDeclaration.Bug3176c``() = AssertCtrlSpaceCompleteContains [ "type C ="; - " val aaaa : int" ] + " val aaaa: int" ] "aa" // move to marker ["aaaa"] [] // should contain 'aaaa' @@ -4263,7 +4539,8 @@ let x = query { for bbbb in abbbbc(*D0*) do // Save file2 ReplaceFileInMemory file2 [""] - SaveFileToDisk file2 + SaveFileToDisk file2 + let file3 = OpenFile(project,"File3.fs") TakeCoffeeBreak(this.VS) gpatcc.AssertExactly(notAA[file2; file3], notAA[file2;file3]) @@ -4403,7 +4680,7 @@ let x = query { for bbbb in abbbbc(*D0*) do MoveCursorToEndOfMarker(file,"System.Windows.") let completions = AutoCompleteAtCursor(file) printfn "Completions=%A" completions - Assert.AreEqual(1, completions.Length) + Assert.AreEqual(3, completions.Length) /// Tests whether we're correctly showing both type and module when they have the same name [] @@ -4861,6 +5138,7 @@ let x = query { for bbbb in abbbbc(*D0*) do Assert.IsTrue(completions.Length>0) [] + [] member this.``BadCompletionAfterQuicklyTyping.Bug72561``() = let code = [ " " ] let (_, _, file) = this.CreateSingleFileProject(code) @@ -4929,32 +5207,6 @@ let x = query { for bbbb in abbbbc(*D0*) do gpatcc.AssertExactly(0,0) - [] - member this.``BadCompletionAfterQuicklyTyping.Bug177519.NowWorking``() = - // this test is similar to "Bug72561.Noteworthy" but uses name resolutions rather than expression typings - // name resolutions currently still respond with stale info - let code = [ "let A = 42" - "let B = \"\"" - "A. // quickly backspace and retype B. --> exact name resolution code path" ] - let (_, _, file) = this.CreateSingleFileProject(code) - - TakeCoffeeBreak(this.VS) - let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS) - let code2= [ "let A = 42" - "let B = \"\"" - "B. // quickly backspace and retype B. --> exact name resolution code path" ] - ReplaceFileInMemoryWithoutCoffeeBreak file code2 - MoveCursorToEndOfMarker(file, "B.") - // Note: no TakeCoffeeBreak(this.VS) - let completions = AutoCompleteAtCursor file - AssertCompListIsEmpty(completions) // empty completion list means second-chance intellisense will kick in - // if we wait... - TakeCoffeeBreak(this.VS) - let completions = AutoCompleteAtCursor file - // ... we get the expected answer - AssertCompListContainsAll(completions, ["Chars"]) // has correct string info - gpatcc.AssertExactly(0,0) - //*********************************************Previous Completion test and helper***** member private this.VerifyCompListDoesNotContainAnyAtStartOfMarker(fileContents : string, marker : string, list : string list) = let (solution, project, file) = this.CreateSingleFileProject(fileContents) @@ -5049,17 +5301,6 @@ let x = query { for bbbb in abbbbc(*D0*) do "[<" ["AttributeUsage"] [] - - [] - member this.``Attributes.CanSeeOpenNamespaces.Bug268290.Case2``() = - AssertCtrlSpaceCompleteContains - [""" - open System - [< - """] - "[<" - ["AttributeUsage"] - [] [] member this.``Selection``() = @@ -5202,11 +5443,11 @@ let x = query { for bbbb in abbbbc(*D0*) do (*------------------------------------------IDE Query automation start -------------------------------------------------*) member private this.AssertAutoCompletionInQuery(fileContent : string list, marker:string,contained:string list) = - let file = createFile fileContent SourceFileKind.FS ["System.Xml.Linq"] + let file = createFile fileContent SourceFileKind.FS ["System.Xml.Linq"] None let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS) MoveCursorToEndOfMarker(file, marker) - let completions = CompleteAtCursorForReason(file,Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord) + let completions = CompleteAtCursorForReason(file,BackgroundRequestReason.CompleteWord) AssertCompListContainsAll(completions, contained) gpatcc.AssertExactly(0,0) @@ -5320,8 +5561,8 @@ let x = query { for bbbb in abbbbc(*D0*) do this.VerifyDotCompListContainAllAtStartOfMarker( fileContents = """ type T() = - member __.P with get() = new T() - member __.M() = [|1..2|] + member _.P with get() = new T() + member _.M() = [|1..2|] let t = new T() t.P.M()(*marker*) """, marker = "(*marker*)", @@ -5332,7 +5573,7 @@ let x = query { for bbbb in abbbbc(*D0*) do this.VerifyDotCompListContainAllAtStartOfMarker( fileContents = """ type T() = - member __.M() = [|1..2|] + member _.M() = [|1..2|] type R = { P : T } @@ -5998,7 +6239,7 @@ let rec f l = marker = "(*MarkerMethodInType*)", list = ["PrivateMethod"]) - [] +// [] member this.``VariableIdentifier.AsParameter``() = this.VerifyDotCompListContainAllAtStartOfMarker( fileContents = """ @@ -6725,7 +6966,7 @@ let rec f l = this.VerifyDotCompListIsEmptyAtStartOfMarker( fileContents = """ type f1(*MarkerType*) = - val field : int""", + val field: int""", marker = "(*MarkerType*)") [] @@ -6922,7 +7163,6 @@ let rec f l = let (_, _, file) = this.CreateSingleFileProject(code) TakeCoffeeBreak(this.VS) - let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS) // In this case, we quickly type "." and then get dot-completions // For "level <- Module" this shows completions from the "Module" (e.g. "Module.Other") @@ -6935,7 +7175,6 @@ let rec f l = let completions = AutoCompleteAtCursor file AssertCompListContainsAll(completions, ["Length"]) AssertCompListDoesNotContainAny(completions, ["AbstractClassAttribute"]) - gpatcc.AssertExactly(0,0) [] member this.``SelfParameter.InDoKeywordScope``() = diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs index be8401a6135..add5eb9cc4d 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ErrorList.fs @@ -17,7 +17,7 @@ open UnitTests.TestLib.ProjectSystem type public AssemblyResolverTestFixture () = [] - member public __.Init () = AssemblyResolver.addResolver () + member public _.Init () = AssemblyResolver.addResolver () [] [] @@ -57,6 +57,23 @@ type UsingMSBuild() as this = let ok = errors |> List.exists (fun err -> err.Message = text) Assert.IsTrue(ok, sprintf "Error list should contain '%s' message" text) + let assertExpectedErrorMessages expected (actual: list) = + let normalizeCR input = System.Text.RegularExpressions.Regex.Replace(input, @"\r\n|\n\r|\n|\r", "\r\n") + let actual = + actual + |> Seq.map (fun e -> e.Message) + |> String.concat Environment.NewLine + |> normalizeCR + let expected = expected |> String.concat Environment.NewLine |> normalizeCR + + let message = + sprintf """ +=[ expected ]============ +%s +=[ actual ]============== +%s +=========================""" expected actual + Assert.AreEqual(expected, actual, message) //verify the error list Count member private this.VerifyErrorListCountAtOpenProject(fileContents : string, num : int) = @@ -190,18 +207,16 @@ let g (t : T) = t.Count() X(1.0) """ - let expectedMessages = - [ "Possible overload: 'new : bool -> X'." - "Possible overload: 'new : int -> X'." ] + let expectedMessages = [ """No overloads match for method 'X'. - CheckErrorList content <| - fun errors -> - Assert.AreEqual(3, List.length errors) - assertContains errors "No overloads match for method 'X'. The available overloads are shown below." - for expected in expectedMessages do - errors - |> List.exists (fun e -> e.Message.StartsWith expected) - |> Assert.IsTrue +Known type of argument: float + +Available overloads: + - new: bool -> X // Argument at index 1 doesn't match + - new: int -> X // Argument at index 1 doesn't match""" ] + + CheckErrorList content (assertExpectedErrorMessages expectedMessages) + [] member public this.``Query.InvalidJoinRelation.GroupJoin``() = @@ -277,10 +292,16 @@ let x = let content = """ System.Console.WriteLine(null) """ - CheckErrorList content <| - fun errors -> - Assert.AreEqual(1, List.length errors) - assertContains errors "A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Console.WriteLine(buffer: char []) : unit, System.Console.WriteLine(format: string, [] arg: obj []) : unit, System.Console.WriteLine(value: obj) : unit, System.Console.WriteLine(value: string) : unit" + let expectedMessages = [ """A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known type of argument: 'a0 when 'a0: null + +Candidates: + - System.Console.WriteLine(buffer: char[]) : unit + - System.Console.WriteLine(format: string, [] arg: obj[]) : unit + - System.Console.WriteLine(value: obj) : unit + - System.Console.WriteLine(value: string) : unit""" ] + CheckErrorList content (assertExpectedErrorMessages expectedMessages) [] member public this.``InvalidMethodOverload2``() = @@ -294,10 +315,14 @@ type B() = let b = B() b.Do(1, 1) """ - CheckErrorList content <| - fun errors -> - Assert.AreEqual(1, List.length errors) - assertContains errors "A unique overload for method 'Do' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member A.Do : a:int * b:'T -> unit, member A.Do : a:int * b:int -> unit" + let expectedMessages = [ """A unique overload for method 'Do' could not be determined based on type information prior to this program point. A type annotation may be needed. + +Known types of arguments: int * int + +Candidates: + - member A.Do: a: int * b: 'T -> unit + - member A.Do: a: int * b: int -> unit""" ] + CheckErrorList content (assertExpectedErrorMessages expectedMessages) [] member public this.``NoErrorInErrList``() = @@ -484,15 +509,15 @@ but here has type member public this.``TypeProvider.ProhibitedMethods`` () = let cases = [ - "let x = BadMethods.Arr.GetFirstElement([||])", "Get" - "let y = BadMethods.Arr.SetFirstElement([||], 5)", "Set" - "let z = BadMethods.Arr.AddressOfFirstElement([||])", "Address" + "let x = BadMethods.Arr.GetFirstElement([||])", "GetFirstElement" + "let y = BadMethods.Arr.SetFirstElement([||], 5)", "SetFirstElement" + "let z = BadMethods.Arr.AddressOfFirstElement([||])", "AddressOfFirstElement" ] for (code, str) in cases do this.VerifyErrorListContainedExpectedString ( code, - sprintf "Array method '%s' is supplied by the runtime and cannot be directly used in code." str, + sprintf "The type provider 'DummyProviderForLanguageServiceTesting.TypeProviderThatEmitsBadMethods' reported an error in the context of provided type 'BadMethods.Arr', member '%s'. The error: The operation 'GetMethodImpl' on item 'Int32[]' should not be called on provided type, member or parameter of type 'ProviderImplementation.ProvidedTypes.TypeSymbol'." str, addtlRefAssy = [PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll")] ) @@ -516,7 +541,7 @@ but here has type this.VerifyWarningListCountAtOpenProject( fileContents = """ type foo = N1.T< - const "Hello World",2>""", + const "Hello World",2>""", expectedNum = 1, addtlRefAssy = [PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll")]) @@ -547,7 +572,7 @@ but here has type [] [] - member public this.``UnicodeCharactors``() = + member public this.``UnicodeCharacters``() = use _guard = this.UsingNewVS() let solution = this.CreateSolution() let project = CreateProject(solution,"新規baApplication5") diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.General.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.General.fs index 6bc62eda151..b5a3aeaee1b 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.General.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.General.fs @@ -8,7 +8,10 @@ open System.IO open System.Reflection open System.Runtime.InteropServices open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Tokenization open Microsoft.VisualStudio.FSharp.LanguageService open Salsa.Salsa open Salsa @@ -262,7 +265,7 @@ type UsingMSBuild() = [ "type C() = " " member this.F() = ()" " interface System.IComparable with " - " member __.CompareTo(v:obj) = 1" ] + " member _.CompareTo(v:obj) = 1" ] ) [] @@ -330,8 +333,8 @@ type UsingMSBuild() = Parser.RPAREN, (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.ParamEnd ||| FSharpTokenTriggerClass.MatchBraces) ] let matching = [ // Other cases where we expect MatchBraces - Parser.LQUOTE("", false); Parser.LBRACK; Parser.LBRACE; Parser.LBRACK_BAR; - Parser.RQUOTE("", false); Parser.RBRACK; Parser.RBRACE; Parser.BAR_RBRACK ] + Parser.LQUOTE("", false); Parser.LBRACK; Parser.LBRACE (Unchecked.defaultof<_>); Parser.LBRACK_BAR; + Parser.RQUOTE("", false); Parser.RBRACK; Parser.RBRACE (Unchecked.defaultof<_>); Parser.BAR_RBRACK ] |> List.map (fun n -> n, (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.MatchBraces)) for tok, expected in List.concat [ important; matching ] do let info = TestExpose.TokenInfo tok diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.GotoDefinition.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.GotoDefinition.fs index 95b52add9ea..2e398ab682e 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.GotoDefinition.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.GotoDefinition.fs @@ -13,6 +13,8 @@ open System.Collections.Generic open System.Text.RegularExpressions open UnitTests.TestLib.LanguageService open UnitTests.TestLib.ProjectSystem +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices [] [] @@ -1343,7 +1345,7 @@ type UsingMSBuild() = member this.GetCompleteIdTest tolerate (s : string)(exp : string option) : unit = let n = s.IndexOf '$' let s = s.Remove (n, 1) - match (FSharp.Compiler.QuickParse.GetCompleteIdentifierIsland tolerate s n, exp) with + match (QuickParse.GetCompleteIdentifierIsland tolerate s n, exp) with | (Some (s1, _, _), Some s2) -> printfn "%s" "Received result, as expected." Assert.AreEqual (s1, s2) diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.IncrementalBuild.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.IncrementalBuild.fs deleted file mode 100644 index 715d7435ac0..00000000000 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.IncrementalBuild.fs +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Tests.LanguageService - -open System -open System.IO -open System.Threading -open System.Threading.Tasks -open NUnit.Framework -#if NUNIT_V2 -#else -open NUnit.Framework.Constraints -#endif -open Salsa.Salsa -open Salsa.VsOpsUtils -open FSharp.Compiler -open FSharp.Compiler.CompileOps -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.IncrementalBuild -open FSharp.Compiler.AbstractIL.Internal.Library - -// Useful methods that someday might go into IncrementalBuild -module internal Vector = - /// Convert from vector to a scalar - let ToScalar<'I> (taskname:string) (input:Vector<'I>) : Scalar<'I array> = - let Identity _ inArray = inArray |> cancellable.Return - Vector.Demultiplex taskname Identity input - -[] -module internal Values = - let ctok = AssumeCompilationThreadWithoutEvidence() - -[] -[] -[] -[] -type IncrementalBuild() = - - let save _ctok _ = () - - /// Called per test - [] - member this.Setup() = - //Trace.Log <- "IncrementalBuild" - () - - - // This test is related to - // 835552 Language service loses track of files in project due to intermitent file read failures - // It verifies that incremental builder can handle changes to timestamps that happen _before_ the - // stamp function exists. This ensures there's not a race in the data gathered for tracking file - // timestamps in parsing. - [] - member public rb.StampUpdate() = - let path = Path.GetTempFileName() - - let TouchFile() = - printfn "Touching file" - File.WriteAllText(path,"Some text") - - let updateStamp = ref true - - let StampFile _cache _ctok filename = - let result = File.GetLastWriteTimeUtc(filename) - if !updateStamp then - // Here, simulate that VS is writing to our file. - TouchFile() - result - - let Map _ctok filename = - "map:"+filename - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let stamped = Vector.Stamp "Stamp" StampFile input - let mapped = Vector.Map "Map" Map stamped - buildDesc.DeclareVectorOutput mapped - let inputs = [ BuildInput.VectorInput(input, [path]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let DoCertainStep bound = - let cache = TimeStampCache(System.DateTime.UtcNow) - match IncrementalBuild.Step cache ctok save (Target(mapped,None)) bound |> Cancellable.runWithoutCancellation with - | Some bound -> bound - | None -> failwith "Expected to be able to step" - - // While updateStamp is true we should be able to step as continuously - // because there will always be more to bound. - let mutable bound = bound - for i in 0..5 do - printfn "Iteration %d" i - bound <- DoCertainStep bound - System.Threading.Thread.Sleep 2000 - - // Now, turn off updateStamp and the build should just finish. - updateStamp:=false - bound <- DoCertainStep bound - bound <- DoCertainStep bound - let cache = TimeStampCache(System.DateTime.UtcNow) - match IncrementalBuild.Step cache ctok save (Target (mapped, None)) bound |> Cancellable.runWithoutCancellation with - | Some bound -> failwith "Build should have stopped" - | None -> () - - - /// Test that stamp works - [] - member public rb.StampScan() = - - let mapSuffix = ref "Suffix1" - let Scan ctok acc filename = - eventually { return acc+"-"+filename+"-"+(!mapSuffix) } - - let stampAs = ref DateTime.UtcNow - let StampFile _cache _ctok filename = - !stampAs - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let acc = InputScalar "Accumulator" - let stamped = Vector.Stamp "Stamp" StampFile input - let scanned = Vector.ScanLeft "Scan" Scan acc stamped - buildDesc.DeclareVectorOutput scanned - let inputs = - [ BuildInput.VectorInput(input, ["File1.fs"; "File2.fs"; "File3.fs"]) - BuildInput.ScalarInput(acc, "AccVal") ] - let bound = buildDesc.GetInitialPartialBuild inputs - - printf "-[Step1]----------------------------------------------------------------------------------------\n" - // Evaluate the first time. - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save scanned bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (scanned, bound) - Assert.AreEqual("AccVal-File1.fs-Suffix1-File2.fs-Suffix1",r.[1]) - - printf "-[Step2]----------------------------------------------------------------------------------------\n" - // Evaluate the second time. No change should be seen. - mapSuffix:="Suffix2" - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save scanned bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (scanned,bound) - Assert.AreEqual("AccVal-File1.fs-Suffix1-File2.fs-Suffix1",r.[1]) - - printf "-[Step3]----------------------------------------------------------------------------------------\n" - // Evaluate a third time with timestamps updated. Should cause a rebuild - System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now' - stampAs:=DateTime.UtcNow - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save scanned bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (scanned,bound) - Assert.AreEqual("AccVal-File1.fs-Suffix2-File2.fs-Suffix2",r.[1]) - - - /// Test case of zero elements in a vector - [] - member public rb.aaZeroElementVector() = // Starts with 'aa' to put it at the front. - let stamp = ref DateTime.UtcNow - let Stamp _cache _ctok (s:string) = !stamp - let Map ctok (s:string) = s - let Demult ctok (a:string[]) = a.Length |> cancellable.Return - - let buildDesc = new BuildDescriptionScope() - let inputVector = InputVector "InputVector" - let stamped = Vector.Stamp "Stamp" Stamp inputVector - let mapped = Vector.Map "Map" Map stamped - let result = Vector.Demultiplex "Demult" Demult mapped - buildDesc.DeclareVectorOutput stamped - buildDesc.DeclareVectorOutput mapped - buildDesc.DeclareScalarOutput result - - // Try first with one input - let inputs1 = [ BuildInput.VectorInput(inputVector, [""]) ] - let build1 = buildDesc.GetInitialPartialBuild inputs1 - - let cache = TimeStampCache(System.DateTime.UtcNow) - let build1Evaled = Eval cache ctok save result build1 |> Cancellable.runWithoutCancellation - let r1 = GetScalarResult (result, build1Evaled) - match r1 with - | Some(v,dt) -> Assert.AreEqual(1,v) - | None -> failwith "Expected the value 1 to be returned." - - // Now with zero. This was the original bug. - stamp := DateTime.UtcNow - let inputs0 = [ BuildInput.VectorInput(inputVector, []) ] - let build0 = buildDesc.GetInitialPartialBuild inputs0 - - let cache = TimeStampCache(System.DateTime.UtcNow) - let build0Evaled = Eval cache ctok save result build0 |> Cancellable.runWithoutCancellation - let r0 = GetScalarResult (result, build0Evaled) - match r0 with - | Some(v,dt) -> Assert.AreEqual(0,v) - | None -> failwith "Expected the value 0 to be returned." - () - - - /// Here, we want a multiplex to increase the number of items processed. - [] - member public rb.MultiplexTransitionUp() = - let elements = ref 1 - let timestamp = ref System.DateTime.UtcNow - let Input() : string array = [| for i in 1..!elements -> sprintf "Element %d" i |] - let Stamp _cache ctok s = !timestamp - let Map ctok (s:string) = sprintf "Mapped %s " s - let Result ctok (a:string[]) = String.Join(",", a) |> cancellable.Return - let now = System.DateTime.UtcNow - let FixedTimestamp _cache _ctok _ = now - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let stampedInput = Vector.Stamp "StampInput" Stamp input - //let demultiplexedInput = Vector.Demultiplex "DemultInput" Demult stampedInput - //let multiplexed = Scalar.Multiplex "Mult" Mult demultiplexedInput - let mapped = Vector.Map "Map" Map stampedInput - let mapped = Vector.Stamp "FixedTime" FixedTimestamp mapped // Change in vector size should x-ray through even if timestamps haven't changed in remaining items. - let result = Vector.Demultiplex "DemultResult" Result mapped - buildDesc.DeclareScalarOutput result - - // Create the build. - let inputs = [ BuildInput.VectorInput(input, ["Input 0"]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - // Evaluate it with value 1 - elements := 1 - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save result bound |> Cancellable.runWithoutCancellation - let r1 = GetScalarResult(result, bound) - match r1 with - | Some(s,dt) -> printfn "%s" s - | None -> failwith "" - - // Now, re-evaluate it with value 2 - elements := 2 - System.Threading.Thread.Sleep(100) - timestamp := System.DateTime.UtcNow - - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save result bound |> Cancellable.runWithoutCancellation - let r2 = GetScalarResult (result, bound) - match r2 with - | Some(s,dt) -> Assert.AreEqual("Mapped Input 0 ",s) - | None -> failwith "" - - (* - /// Here, we want a multiplex to decrease the number of items processed. - [] - member public rb.MultiplexTransitionDown() = - let elements = ref 1 - let timestamp = ref System.DateTime.UtcNow - let Mult(s:string) : string array = [| for i in 1..!elements -> sprintf "Element %d" i |] - let Stamp(s) = !timestamp - let Map(s:string) = - printfn "Map called with %s" s - sprintf "Mapped %s " s - let Demult(a:string array) : string = - printfn "Demult called with %d items" a.Length - sprintf "Demult %s" (String.Join(",",a)) - let Result(a:string array) : string = - let result = String.Join(",", a) - printfn "Result called with %d items returns %s" a.Length result - result - let now = System.DateTime.UtcNow - let FixedTimestamp _ = - printfn "Fixing timestamp" - now - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let stampedInput = Vector.Stamp "StampInput" Stamp input - let demultiplexedInput = Vector.Demultiplex "DemultInput" Demult stampedInput - let multiplexed = Scalar.Multiplex "Mult" Mult demultiplexedInput - let mapped = Vector.Map "Map" Map multiplexed - let fixedmapped = Vector.Stamp "FixedTime" FixedTimestamp mapped // Change in vector size should x-ray through even if timestamps haven't changed in remaining items. - let result = Vector.Demultiplex "DemultResult" Result fixedmapped - - buildDesc.DeclareScalarOutput demultiplexedInput - buildDesc.DeclareVectorOutput mapped - buildDesc.DeclareVectorOutput fixedmapped - buildDesc.DeclareScalarOutput result - - // Create the build. - let bound = buildDesc.GetInitialPartialBuild(["InputVector",1,[box "Input 0"]],[]) - - // Evaluate it with value 2 - elements := 2 - let bound = Eval result bound - let r1 = GetScalarResult(result, bound) - match r1 with - | Some(s,dt) -> printfn "%s" s - | None -> failwith "" - - // Now, re-evaluate it with value 1 - elements := 1 - System.Threading.Thread.Sleep(100) - timestamp := System.DateTime.UtcNow - - let buildDemuxed = Eval demultiplexedInput bound - let rdm = GetScalarResult (demultiplexedInput,buildDemuxed) - match rdm with - | Some(s,dt)->Assert.AreEqual("Demult Input 0", s) - | None -> failwith "unexpected" - - let buildMapped = Eval mapped bound - let mp = GetVectorResult (mapped,buildMapped) - Assert.AreEqual(1,mp.Length) - let melem = mp.[0] - Assert.AreEqual("Mapped Element 1 ", melem) - - let buildFixedMapped = Eval fixedmapped buildMapped - let mp = GetVectorResult (fixedmapped,buildFixedMapped) - Assert.AreEqual(1,mp.Length) - let melem = mp.[0] - Assert.AreEqual("Mapped Element 1 ", melem) - - let bound = Eval result bound - let r2 = GetScalarResult(result, bound) - match r2 with - | Some(s,dt) -> Assert.AreEqual("Mapped Element 1 ",s) - | None -> failwith "unexpected" - *) - - /// Test that stamp works - [] - member public rb.StampMap() = - - let mapSuffix = ref "Suffix1" - let MapIt ctok filename = - filename+"."+(!mapSuffix) - - let stampAs = ref DateTime.UtcNow - let StampFile _cache ctok filename = - !stampAs - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let stamped = Vector.Stamp "Stamp" StampFile input - let mapped = Vector.Map "Map" MapIt stamped - buildDesc.DeclareVectorOutput mapped - let inputs = [ BuildInput.VectorInput(input, ["File1.fs";"File2.fs";"File3.fs"]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - printf "-[Step1]----------------------------------------------------------------------------------------\n" - // Evaluate the first time. - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save mapped bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (mapped,bound) - Assert.AreEqual("File2.fs.Suffix1",r.[1]) - - printf "-[Step2]----------------------------------------------------------------------------------------\n" - // Evaluate the second time. No change should be seen. - mapSuffix:="Suffix2" - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save mapped bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (mapped,bound) - Assert.AreEqual("File2.fs.Suffix1",r.[1]) - - printf "-[Step3]----------------------------------------------------------------------------------------\n" - // Evaluate a third time with timestamps updated. Should cause a rebuild - let cache = TimeStampCache(System.DateTime.UtcNow) - while !stampAs = DateTime.UtcNow do - System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now' - stampAs:=DateTime.UtcNow - let bound = Eval cache ctok save mapped bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult (mapped,bound) - Assert.AreEqual("File2.fs.Suffix2",r.[1]) - - /// Test that stamp works - [] - member public rb.StampDemultiplex() = - - let joinedResult = ref "Join1" - let Join ctok (filenames:_[]) = - !joinedResult |> cancellable.Return - - let stampAs = ref DateTime.UtcNow - let StampFile _cache ctok filename = - !stampAs - - let buildDesc = new BuildDescriptionScope() - let input = InputVector "InputVector" - let stamped = Vector.Stamp "Stamp" StampFile input - let joined = Vector.Demultiplex "Demultiplex" Join stamped - buildDesc.DeclareScalarOutput joined - let inputs = [ BuildInput.VectorInput(input, ["File1.fs";"File2.fs";"File3.fs"]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - printf "-[Step1]----------------------------------------------------------------------------------------\n" - // Evaluate the first time. - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save joined bound |> Cancellable.runWithoutCancellation - let (r,_) = Option.get (GetScalarResult(joined,bound)) - Assert.AreEqual("Join1",r) - - printf "-[Step2]----------------------------------------------------------------------------------------\n" - // Evaluate the second time. No change should be seen. - joinedResult:="Join2" - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save joined bound |> Cancellable.runWithoutCancellation - let (r,_) = Option.get (GetScalarResult (joined,bound)) - Assert.AreEqual("Join1",r) - - printf "-[Step3]----------------------------------------------------------------------------------------\n" - // Evaluate a third time with timestamps updated. Should cause a rebuild - while !stampAs = DateTime.UtcNow do - System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now' - stampAs:=DateTime.UtcNow - let cache = TimeStampCache(System.DateTime.UtcNow) - let bound = Eval cache ctok save joined bound |> Cancellable.runWithoutCancellation - let (r,_) = Option.get (GetScalarResult (joined,bound)) - Assert.AreEqual("Join2",r) - - - /// Test that Demultiplex followed by ScanLeft works - [] - member public rb.DemultiplexScanLeft() = - let Size ctok (ar:_[]) = ar.Length |> cancellable.Return - let Scan ctok acc (file :string) = eventually { return acc + file.Length } - let buildDesc = new BuildDescriptionScope() - let inVector = InputVector "InputVector" - let vectorSize = Vector.Demultiplex "Demultiplex" Size inVector - let scanned = Vector.ScanLeft "Scan" Scan vectorSize inVector - buildDesc.DeclareScalarOutput vectorSize - buildDesc.DeclareVectorOutput scanned - let inputs = [ BuildInput.VectorInput(inVector, ["File1.fs";"File2.fs";"File3.fs"]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let cache = TimeStampCache(System.DateTime.UtcNow) - let e = Eval cache ctok save scanned bound |> Cancellable.runWithoutCancellation - let r = GetScalarResult (vectorSize,e) - match r with - | Some(r,_) -> Assert.AreEqual(3,r) - | None -> Assert.Fail("No size was returned") - - - /// Test that a simple scalar action works. - [] - member public rb.Scalar() = - let buildDesc = new BuildDescriptionScope() - let inScalar = InputScalar "Scalar" - buildDesc.DeclareScalarOutput inScalar - let inputs = [ BuildInput.ScalarInput(inScalar, "A Scalar Value") ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let cache = TimeStampCache(System.DateTime.UtcNow) - let e = Eval cache ctok save inScalar bound |> Cancellable.runWithoutCancellation - let r = GetScalarResult(inScalar,e) - match r with - | Some(r,_) -> Assert.AreEqual("A Scalar Value", r) - | None -> Assert.Fail() - - /// Test that ScanLeft works. - [] - member public rb.ScanLeft() = - let DoIt ctok (a:int*string) (b:string) = - eventually { return ((fst a)+1,b) } - - let buildDesc = new BuildDescriptionScope() - let inScalar = InputScalar "InputScalar" - let inVector = InputVector "InputVector" - let result = Vector.ScanLeft "DoIt" DoIt inScalar inVector - buildDesc.DeclareVectorOutput result - - let inputs = - [ BuildInput.VectorInput(inVector, ["File1.fs";"File2.fs";"File3.fs"]); - BuildInput.ScalarInput(inScalar, (5,"")) ] - - let bound = buildDesc.GetInitialPartialBuild(inputs) - let cache = TimeStampCache(System.DateTime.UtcNow) - let e = Eval cache ctok save result bound |> Cancellable.runWithoutCancellation - let r = GetVectorResult(result,e) - if [| (6,"File1.fs"); (7,"File2.fs"); (8, "File3.fs") |] <> r then - printfn "Got %A" r - Assert.Fail() - () - - /// Convert a vector to a scalar - [] - member public rb.ToScalar() = - let buildDesc = new BuildDescriptionScope() - let inVector = InputVector "InputVector" - let result = Vector.ToScalar "ToScalar" inVector - buildDesc.DeclareScalarOutput result - let inputs = [ BuildInput.VectorInput(inVector, ["File1.fs";"File2.fs";"File3.fs"]) ] - let bound = buildDesc.GetInitialPartialBuild(inputs) - - let cache = TimeStampCache(System.DateTime.UtcNow) - let e = Eval cache ctok save result bound |> Cancellable.runWithoutCancellation - let r = GetScalarResult (result, e) - match r with - | Some(r,ts)-> - if "File3.fs"<>(r.[2]) then - printf "Got %A\n" (r.[2]) - Assert.Fail() - | None -> Assert.Fail() - - - - /// Check a cancellation - [] - member public rb.``Can cancel Eval``() = - let buildDesc = new BuildDescriptionScope() - let inVector = InputVector "InputVector" - let result = Vector.ToScalar "ToScalar" inVector - buildDesc.DeclareScalarOutput result - let inputs = [ BuildInput.VectorInput(inVector, ["File1.fs";"File2.fs";"File3.fs"]) ] - let bound = buildDesc.GetInitialPartialBuild(inputs) - - let cts = new CancellationTokenSource() - cts.Cancel() - let res = - let cache = TimeStampCache(System.DateTime.UtcNow) - match Eval cache ctok save result bound |> Cancellable.run cts.Token with - | ValueOrCancelled.Cancelled _ -> true - | ValueOrCancelled.Value _ -> false - Assert.AreEqual(res, true) - - - /// This test replicates the data flow of the assembly reference model. It includes several concepts - /// that were new at the time: Scalars, Invalidation, Disposal - [] - member public rb.AssemblyReferenceModel() = - let ParseTask ctok filename = sprintf "Parse(%s)" filename - let now = System.DateTime.UtcNow - let StampFileNameTask _cache ctok filename = now - let TimestampReferencedAssemblyTask _cache ctok reference = now - let ApplyMetaCommands ctok (parseResults:string[]) = "tcConfig-of("+String.Join(",",parseResults)+")" - let GetReferencedAssemblyNames ctok (tcConfig) = [|"Assembly1.dll";"Assembly2.dll";"Assembly3.dll"|] - let ReadAssembly ctok assemblyName = sprintf "tcImport-of(%s)" assemblyName - let CombineImportedAssembliesTask ctok imports = "tcAcc" |> cancellable.Return - let TypeCheckTask ctok tcAcc parseResults = eventually { return tcAcc } - let FinalizeTypeCheckTask ctok results = "finalized" |> cancellable.Return - - // Build rules. - let buildDesc = new BuildDescriptionScope() - - // Inputs - let fileNamesNode = InputVector "Filenames" - let referencedAssembliesNode = InputVector "ReferencedAssemblies" - - //Build - let stampedFileNamesNode = Vector.Stamp "SourceFileTimeStamps" StampFileNameTask fileNamesNode - let parseTreesNode = Vector.Map "ParseTrees" ParseTask stampedFileNamesNode - let stampedReferencedAssembliesNode = Vector.Stamp "TimestampReferencedAssembly" TimestampReferencedAssemblyTask referencedAssembliesNode - - let initialTcAccNode = Vector.Demultiplex "CombineImportedAssemblies" CombineImportedAssembliesTask stampedReferencedAssembliesNode - - let tcStatesNode = Vector.ScanLeft "TypeCheckingStates" TypeCheckTask initialTcAccNode parseTreesNode - - let finalizedTypeCheckNode = Vector.Demultiplex "FinalizeTypeCheck" FinalizeTypeCheckTask tcStatesNode - let buildDesc = new BuildDescriptionScope () - - do buildDesc.DeclareVectorOutput stampedFileNamesNode - do buildDesc.DeclareVectorOutput stampedReferencedAssembliesNode - do buildDesc.DeclareVectorOutput parseTreesNode - do buildDesc.DeclareVectorOutput tcStatesNode - do buildDesc.DeclareScalarOutput initialTcAccNode - do buildDesc.DeclareScalarOutput finalizedTypeCheckNode - - let inputs = - [ BuildInput.VectorInput(fileNamesNode, ["File1.fs";"File2.fs";"File3.fs"]); - BuildInput.VectorInput(referencedAssembliesNode, [("lib1.dll", now);("lib2.dll", now)]) ] - let bound = buildDesc.GetInitialPartialBuild(inputs) - let cache = TimeStampCache(System.DateTime.UtcNow) - let e = Eval cache ctok save finalizedTypeCheckNode bound |> Cancellable.runWithoutCancellation - let r = GetScalarResult(finalizedTypeCheckNode,e) - - () - - [] - member public rb.OneToOneWorks() = - let VectorModify ctok (input:int) : string = - sprintf "Transformation of %d" input - - let buildDesc = new BuildDescriptionScope() - let inputs = InputVector "Inputs" - let outputs = Vector.Map "Modify" VectorModify inputs - buildDesc.DeclareVectorOutput outputs - let inputs = [ BuildInput.VectorInput(inputs, [1;2;3;4]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let cache = TimeStampCache(System.DateTime.UtcNow) - let evaled = Eval cache ctok save outputs bound |> Cancellable.runWithoutCancellation - let outputs = GetVectorResult(outputs,evaled) - Assert.AreEqual("Transformation of 4", outputs.[3]) - () - - /// In this bug, the desired output is between other outputs. - /// The getExprById function couldn't find it. - [] - member public rb.HiddenOutputGroup() = - let VectorModify ctok (input:int) : string = - sprintf "Transformation of %d" input - - let buildDesc = new BuildDescriptionScope() - let inputs = InputVector "Inputs" - let outputs = Vector.Map "Modify" VectorModify inputs - buildDesc.DeclareVectorOutput inputs - buildDesc.DeclareVectorOutput inputs - buildDesc.DeclareVectorOutput inputs - buildDesc.DeclareVectorOutput outputs - buildDesc.DeclareVectorOutput inputs - buildDesc.DeclareVectorOutput inputs - buildDesc.DeclareVectorOutput inputs - let inputs = [ BuildInput.VectorInput(inputs, [1;2;3;4]) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let cache = TimeStampCache(System.DateTime.UtcNow) - let evaled = Eval cache ctok save outputs bound |> Cancellable.runWithoutCancellation - let outputs = GetVectorResult(outputs,evaled) - Assert.AreEqual("Transformation of 4", outputs.[3]) - () - - /// Empty build should just be a NOP. - [] - member public rb.EmptyBuildIsNop() = - let VectorModify ctok (input:int) : string = - sprintf "Transformation of %d" input - - let buildDesc = new BuildDescriptionScope() - let inputs = InputVector "Inputs" - let outputs = Vector.Map "Modify" VectorModify inputs - buildDesc.DeclareVectorOutput outputs - let inputs = [ BuildInput.VectorInput(inputs, []) ] - let bound = buildDesc.GetInitialPartialBuild inputs - - let cache = TimeStampCache(System.DateTime.UtcNow) - let evaled = Eval cache ctok save outputs bound |> Cancellable.runWithoutCancellation - let outputs = GetVectorResult(outputs,evaled) - () - diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ParameterInfo.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ParameterInfo.fs index 5b05e438935..9404ca301e4 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ParameterInfo.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.ParameterInfo.fs @@ -302,7 +302,7 @@ type UsingMSBuild() = this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark1*)",[["int"; "string"]]) this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark2*)",[["V1: int"; "string"; "V3: bool"]]) - this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["Long Name: int"; "string"]]) + this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["``Long Name`` : int"; "string"]]) this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark4*)",[["int"]]) [] @@ -319,7 +319,7 @@ type UsingMSBuild() = this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark1*)",[["int"; "string"]]) this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark2*)",[["V1: int"; "string"; "V3: bool" ]]) - this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["Long Name: int"; "string" ]]) + this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["``Long Name`` : int"; "string" ]]) [] [] @@ -903,7 +903,7 @@ type UsingMSBuild() = let info = info.Value AssertEqual("f1", info.GetName(0)) // note about (5,0): service.fs adds three lines of empty text to the end of every file, so it reports the location of 'end of file' as first the char, 3 lines past the last line of the file - AssertEqual([|(2,10);(2,12);(2,13);(3,0)|], info.GetNoteworthyParamInfoLocations()) + AssertEqual([|(2,10);(2,12);(2,13);(3,0)|], info.GetParameterLocations()) [] [] @@ -926,7 +926,7 @@ type UsingMSBuild() = let info = info.Value AssertEqual("Foo", info.GetName(0)) // note about (4,0): service.fs adds three lines of empty text to the end of every file, so it reports the location of 'end of file' as first the char, 3 lines past the last line of the file - AssertEqual([|(1,14);(1,17);(1,18);(2,0)|], info.GetNoteworthyParamInfoLocations()) + AssertEqual([|(1,14);(1,17);(1,18);(2,0)|], info.GetParameterLocations()) (* @@ -953,7 +953,7 @@ We really need to rewrite some code paths here to use the real parse tree rather let info = GetParameterInfoAtCursor file // this will fall back to using the name environment, which is stale, but sufficient to look up the call to 'f1' AssertEqual("Foo", info.GetName(0)) // note about (4,0): service.fs adds three lines of empty text to the end of every file, so it reports the location of 'end of file' as first the char, 3 lines past the last line of the file - AssertEqual([|(1,14);(1,21);(1,21);(4,0)|], info.GetNoteworthyParamInfoLocations()) + AssertEqual([|(1,14);(1,21);(1,21);(4,0)|], info.GetParameterLocations()) *) [] @@ -1003,7 +1003,7 @@ We really need to rewrite some code paths here to use the real parse tree rather let info = GetParameterInfoAtCursor file Assert.IsTrue(info.IsSome, "expected parameter info") let info = info.Value - AssertEqual(expectedLocs, info.GetNoteworthyParamInfoLocations()) + AssertEqual(expectedLocs, info.GetParameterLocations()) // These pin down known failing cases member public this.TestNoParameterInfo (testLine, ?additionalReferenceAssemblies) = @@ -1153,7 +1153,7 @@ We really need to rewrite some code paths here to use the real parse tree rather [] member public this.``LocationOfParams.InsideObjectExpression``() = this.TestParameterInfoLocationOfParams(""" - let _ = { new ^System.Object^(^$^) with member __.GetHashCode() = 2}""") + let _ = { new ^System.Object^(^$^) with member _.GetHashCode() = 2}""") [] member public this.``LocationOfParams.Nested1``() = @@ -1653,7 +1653,7 @@ We really need to rewrite some code paths here to use the real parse tree rather [] member public this.``Multi.Constructor.WithinObjectExpression``() = - let fileContents = "let _ = { new System.Object((*Mark*)) with member __.GetHashCode() = 2}" + let fileContents = "let _ = { new System.Object((*Mark*)) with member _.GetHashCode() = 2}" this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",[]) [] @@ -1942,7 +1942,7 @@ We really need to rewrite some code paths here to use the real parse tree rather let a1 = System.Reflection.Assembly.Load("mscorlib") let m = a1.GetType("System.Decimal").GetConstructor((*Mark*)null)""" - this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",0,["System.Type []"]) + this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",0,["System.Type[]"]) [] member public this.``Regression.MehtodSortedByArgumentCount.Bug4495.Case2``() = @@ -1953,8 +1953,8 @@ We really need to rewrite some code paths here to use the real parse tree rather let m = a1.GetType("System.Decimal").GetConstructor((*Mark*)null)""" this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",1,["System.Reflection.BindingFlags"; "System.Reflection.Binder"; - "System.Type []"; - "System.Reflection.ParameterModifier []"]) + "System.Type[]"; + "System.Reflection.ParameterModifier[]"]) [] [] @@ -1981,7 +1981,7 @@ We really need to rewrite some code paths here to use the real parse tree rather [] member public this.``BasicBehavior.DotNet.Static``() = let fileContents = """System.String.Format((*Mark*)""" - this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"obj []"]) + this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"obj[]"]) (*------------------------------------------IDE Query automation start -------------------------------------------------*) [] @@ -2002,7 +2002,7 @@ We really need to rewrite some code paths here to use the real parse tree rather select r }) }""" this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker1*)",["obj"],queryAssemblyRefs) - this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker2*)",["string";"obj []"],queryAssemblyRefs) + this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker2*)",["string";"obj[]"],queryAssemblyRefs) [] [] diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs index 09f358678df..c146c311c05 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickInfo.fs @@ -117,26 +117,13 @@ type UsingMSBuild() = MoveCursorToStartOfMarker(file, "(*M*)") let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip" AssertContainsInOrder(tooltip, expectedExactOrder) - - - [] - member public this.``EmptyTypeTooltipBody``() = - let content = """ - type X(*M*) = class end""" - this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker content "(*M*)" "=" [] member public this.``NestedTypesOrder``() = this.VerifyOrderOfNestedTypesInQuickInfo( source = "type t = System.Runtime.CompilerServices.RuntimeHelpers(*M*)", marker = "(*M*)", - expectedExactOrder = ["CleanupCode"; "TryCode"] - ) - - this.VerifyOrderOfNestedTypesInQuickInfo( - source = "type t = System.Collections.Generic.Dictionary(*M*)", - marker = "(*M*)", - expectedExactOrder = ["Enumerator"; "KeyCollection"; "ValueCollection"] + expectedExactOrder = ["GetHashCode"; "GetObjectValue"] ) [] @@ -216,14 +203,14 @@ type UsingMSBuild() = this.AssertQuickInfoContainsAtStartOfMarker( fileContents, marker = "MembersTP(*Marker*)", - expected = "type HiddenBaseMembersTP =\n inherit TPBaseTy\n member ShowThisProp : unit", + expected = "type HiddenBaseMembersTP =\n inherit TPBaseTy", addtlRefAssy = [PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll")]) [] member public this.``QuickInfo.OverriddenMethods``() = let source = """ type A() = - abstract member M : unit -> unit + abstract member M: unit -> unit /// 1234 default this.M() = () @@ -274,16 +261,16 @@ type UsingMSBuild() = """ let expectedTooltip = """ type Async = - static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) - static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate) - static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async - static member AwaitTask : task:Task -> Async - static member AwaitTask : task:Task<'T> -> Async<'T> - static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async - static member CancelDefaultToken : unit -> unit - static member Catch : computation:Async<'T> -> Async> - static member Choice : computations:seq> -> Async<'T option> - static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T> + static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) + static member AwaitEvent: event: IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate) + static member AwaitIAsyncResult: iar: IAsyncResult * ?millisecondsTimeout: int -> Async + static member AwaitTask: task: Task<'T> -> Async<'T> + 1 overload + static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout: int -> Async + static member CancelDefaultToken: unit -> unit + static member Catch: computation: Async<'T> -> Async> + static member Choice: computations: seq> -> Async<'T option> + static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads + static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ... Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") @@ -305,7 +292,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") member public this.``GetterSetterInsideInterfaceImpl.ThisOnceAsserted``() = let fileContent =""" type IFoo = - abstract member X : int with get,set + abstract member X: int with get,set type Bar = interface IFoo with @@ -323,7 +310,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let y(*MInt[]*) : int [] = [| 1; 2; 3 |] """ this.AssertQuickInfoContainsAtStartOfMarker(fileContents, "x(*MIntArray1*)", "int array") - this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "y(*MInt[]*)", "int []") + this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "y(*MInt[]*)", "int[]") //Verify no quickinfo -- link name string have [] @@ -365,6 +352,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") [] [] [] + [] //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Type member public this.``TypeProvider.XmlDocAttribute.Type.WithNullComment``() = @@ -372,12 +360,13 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let a = typeof """ this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)", - "type T =\n new : unit -> T\n event Event1 : EventHandler\n static member M : unit -> int []\n static member StaticProp : decimal", + "type T =\n new: unit -> T\n static member M: unit -> int []\n static member StaticProp: decimal\n member Event1: EventHandler", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithNullComment.dll")]) [] [] [] + [] //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Type member public this.``TypeProvider.XmlDocAttribute.Type.WithEmptyComment``() = @@ -385,7 +374,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let a = typeof """ this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)", - "type T =\n new : unit -> T\n event Event1 : EventHandler\n static member M : unit -> int []\n static member StaticProp : decimal\nFull name: N.T", + "type T =\n new : unit -> T\n static member M: unit -> int []\n static member StaticProp: decimal\n member Event1: EventHandler", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithEmptyComment.dll")]) @@ -522,6 +511,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") [] [] [] + [] //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Event member public this.``TypeProvider.XmlDocAttribute.Event.WithNullComment``() = @@ -530,12 +520,13 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") t.Event1(*Marker*)""" this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)", - "event N.T.Event1: IEvent", + "member N.T.Event1: IEvent", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithNullComment.dll")]) [] [] [] + [] //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Event member public this.``TypeProvider.XmlDocAttribute.Event.WithEmptyComment``() = @@ -544,7 +535,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") t.Event1(*Marker*)""" this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)", - "event N.T.Event1: IEvent", + "member N.T.Event1: IEvent", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithEmptyComment.dll")]) @@ -597,7 +588,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let t = new N.T.M(*Marker*)()""" this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)", - "N.T.M() : int []", + "N.T.M() : int[]", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithNullComment.dll")]) [] @@ -610,7 +601,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let t = new N.T.M(*Marker*)()""" this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)", - "N.T.M() : int []", + "N.T.M() : int[]", addtlRefAssy = [PathRelativeToTestAssembly( @"XmlDocAttributeWithEmptyComment.dll")]) @@ -773,7 +764,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") type A() = let fff n = n + 1 """ - this.AssertQuickInfoContainsAtEndOfMarker(code, "let ff", "val fff : (int -> int)") + this.AssertQuickInfoContainsAtEndOfMarker(code, "let ff", "val fff: (int -> int)") // Regression for 2494 [] @@ -801,8 +792,8 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") let expectedquickinfoPriorityQueue = "type PriorityQueue<'k,'a> = | Nil | Branch of 'k * 'a * PriorityQueue<'k,'a> * PriorityQueue<'k,'a>" let expectedquickinfoNil = "union case PriorityQueue.Nil: PriorityQueue<'k,'a>" let expectedquickinfoPriorityQueueinModule = "module PriorityQueue\n\nfrom File1" - let expectedquickinfoVal = "val pq : PriorityQueue<'a,'b>" - let expectedquickinfoLastLine = "val singleton : k:'a -> a:'b -> PriorityQueue<'a,'b>" + let expectedquickinfoVal = "val pq: PriorityQueue<'a,'b>" + let expectedquickinfoLastLine = "val singleton: k: 'a -> a: 'b -> PriorityQueue<'a,'b>" this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "PriorityQueue(*MarkerType*)" expectedquickinfoPriorityQueue this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Nil(*MarkerDataConstructor*)" expectedquickinfoNil @@ -822,9 +813,9 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") exception NamedExn(*MarkerException*) of int * V2 : string * bool * Data9 : float """ //Verify the quick info as expected - let expectedquickinfoType = "type NamedFieldDU = | Case1 of V1: int * bool * V3: float | Case2 of Big Name: int * bool | Case3 of int" + let expectedquickinfoType = "type NamedFieldDU = | Case1 of V1: int * bool * V3: float | Case2 of ``Big Name`` : int * bool | Case3 of int" let expectedquickinfoCase1 = "union case NamedFieldDU.Case1: V1: int * bool * V3: float -> NamedFieldDU" - let expectedquickinfoCase2 = "union case NamedFieldDU.Case2: Big Name: int * bool -> NamedFieldDU" + let expectedquickinfoCase2 = "union case NamedFieldDU.Case2: ``Big Name`` : int * bool -> NamedFieldDU" let expectedquickinfoCase3 = "union case NamedFieldDU.Case3: int -> NamedFieldDU" let expectedquickinfoException = "exception NamedExn of int * V2: string * bool * Data9: float" @@ -873,7 +864,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") member public this.``Regression.InDeclaration.Bug3176c``() = this.AssertQuickInfoContainsAtEndOfMarker ("""type C = - val aaaa : int""","aa","aaaa") + val aaaa: int""","aa","aaaa") [] member public this.``Regression.InDeclaration.Bug3176d``() = @@ -884,7 +875,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") [] member public this.``Regression.Generic.3773a``() = this.AssertQuickInfoContainsAtEndOfMarker - ("""let rec M2<'a>(a:'a) = M2(a)""","let rec M","val M2 : a:'a -> obj") + ("""let rec M2<'a>(a:'a) = M2(a)""","let rec M","val M2: a: 'a -> obj") // Before this fix, if the user hovered over 'cccccc' they would see 'Yield' [] @@ -1003,7 +994,7 @@ Full name: Microsoft.FSharp.Control.Async""".TrimStart().Replace("\r\n", "\n") [] member public this.``Regression.RecursiveDefinition.Generic.3773b``() = this.AssertQuickInfoContainsAtEndOfMarker - ("""let rec M1<'a>(a:'a) = M1(0)""","let rec M","val M1 : a:int -> 'a") + ("""let rec M1<'a>(a:'a) = M1(0)""","let rec M","val M1: a: int -> 'a") //regression test for bug Dev11:138110 - "F# language service hover tip for ITypeProvider does now show Invalidate event" [] @@ -1029,13 +1020,12 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate this.AssertQuickInfoContainsAtEndOfMarker ("""let f x = x + 1 ""","let f","int") - [] + [] member public this.``FrameworkClass``() = let fileContent = """let l = new System.Collections.Generic.List()""" let marker = "Generic.List" - this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Capacity : int with get, set\n") - this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Clear : unit -> unit\n") - //this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Item : int -> 'T with get, set\n") // removed because quickinfo is now smaller + this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Capacity: int\n") + this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Clear: unit -> unit\n") this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "get_Capacity" this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "set_Capacity" this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "get_Count" @@ -1048,6 +1038,7 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate "Generic.LinkedList" "System.Collections.ICollection.ISynchronized" // Bug 5092: A framework class contained a private method impl [] + [] member public this.``Regression.ModulesFromExternalLibrariesBug5785``() = use _guard = this.UsingNewVS() let solution = this.CreateSolution() @@ -1131,11 +1122,11 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate let (_, _, file) = this.CreateSingleFileProject(code) MoveCursorToEndOfMarker(file,"(*aaa*)") let tooltip = GetQuickInfoAtCursor file - AssertContains(tooltip,"val x : int") + AssertContains(tooltip,"val x: int") MoveCursorToEndOfMarker(file,"(*bbb*)") let tooltip = GetQuickInfoAtCursor file - AssertContains(tooltip,"val x' : string") + AssertContains(tooltip,"val x': string") [] member public this.``NegativeTest.CharLiteralNotConfusedWithIdentifierWithTick``() = @@ -1533,7 +1524,7 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate [] member public this.``Regression.Classes.Bug2362``() = let fileContent = """let append mm nn = fun ac -> mm (nn ac)""" - this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let appen","mm:('a -> 'b) -> nn:('c -> 'a) -> ac:'c -> 'b") + this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let appen","mm: ('a -> 'b) -> nn: ('c -> 'a) -> ac: 'c -> 'b") // check consistency of QuickInfo for 'm' and 'n', which is the main point of this test this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let append m","'a -> 'b") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let append mm n","'c -> 'a") @@ -1729,8 +1720,8 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate "Overload", (* expect to see in order... *) [ - "static member MyType.Overload : unit -> int"; - "static member MyType.Overload : x:int -> int"; + "static member MyType.Overload: unit -> int"; + "static member MyType.Overload: x: int -> int"; "Hello" ] ) @@ -1802,7 +1793,8 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate "Union", (* expect to see in order... *) [ - "type Union = | Case of int"; + "type Union ="; + " | Case of int"; //"Full name:"; "Module.Union"; "Union comment"; ] @@ -1942,34 +1934,6 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate "[Signature:M:System.String.Format(System.String,System.Object[])]"; ] ) - - [] - member public this.``Regression.MemberDefinition.DocComments.Bug5856_12``() = - this.AssertMemberDataTipContainsInOrder - ((*code *) - [ - "System." - ] , - (* marker *) - "System.", - (* completed item *) - "Action", - (* expect to see in order... *) - [ - "type Action"; - " delegate of" - "[Filename:"; "mscorlib.dll]"; - "[Signature:T:System.Action]" - "type Action<"; - " delegate of" - "[Filename:"; "mscorlib.dll]"; - "[Signature:T:System.Action`1]" - "type Action<"; - " delegate of" - "[Filename:"; "mscorlib.dll]"; - "[Signature:T:System.Action`2]" - ] - ) [] member public this.``Regression.MemberDefinition.DocComments.Bug5856_13``() = @@ -1986,8 +1950,7 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate [ "type KeyCollection<"; "member CopyTo"; - "[Filename:"; "mscorlib.dll]"; - "[Signature:T:System.Collections.Generic.Dictionary`2.KeyCollection]" + """Represents the collection of keys in a . This class cannot be inherited.""" ] ) @@ -2006,8 +1969,7 @@ let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate [ "type ArgumentException"; "member Message"; - "[Filename"; "mscorlib.dll]"; - "[Signature:T:System.ArgumentException]" + "The exception that is thrown when one of the arguments provided to a method is not valid.Gets the current application domain for the current .""" ] ) @@ -2089,15 +2050,14 @@ query." "AcceptButton", (* expect to see in order... *) [ - "[Filename:"; "System.Windows.Forms.dll]" - "[Signature:P:System.Windows.Forms.Form.AcceptButton]" + "Gets or sets the button on the form that is clicked when the user presses the ENTER key." ] ) /// Bug 4592: Check that ctors are displayed from C# classes, i.e. the "new" lines below. [] - member public this.``Regression.Class.Printing.CSharp.Classes.Only..Bug4592``() = + member public this.``Regression.Class.Printing.CSharp.Classes.Only.Bug4592``() = this.AssertMemberDataTipContainsInOrder ((*code *) ["#light"; @@ -2108,10 +2068,10 @@ query." "Random", (* expect to see in order... *) ["type Random ="; - " new : unit -> Random + 1 overload"; - " member Next : unit -> int + 2 overloads"; - " member NextBytes : buffer:byte[] -> unit"; (* methods sorted alpha *) - " member NextDouble : unit -> float";] + " new: unit -> unit + 1 overload" + " member Next: unit -> int + 2 overloads"; + " member NextBytes: buffer: byte[] -> unit"; + " member NextDouble: unit -> float"] ) [] @@ -2132,7 +2092,6 @@ query." /// Bug 4624: Check the order in which members are printed, C# classes [] member public this.``Regression.Class.Printing.CSharp.Classes.Bug4624``() = - //let f (x:System.Security.Policy.CodeConnectAccess) = x. this.AssertMemberDataTipContainsInOrder ((*code *) ["#light"; @@ -2144,16 +2103,13 @@ query." (* expect to see in order... *) // Pre fix output is mixed up [ "type CodeConnectAccess ="; - " new : allowScheme:string * allowPort:int -> CodeConnectAccess"; - " member Equals : o:obj -> bool"; - " member GetHashCode : unit -> int"; (* method *) - " member Port : int"; - " member Scheme : string"; - " static val DefaultPort : int"; (* static val after instance, but before static method *) - " static val OriginPort : int"; - " static val OriginScheme : string"; - " static val AnyScheme : string"; - " static member CreateAnySchemeAccess : allowPort:int -> CodeConnectAccess"; + " new: allowScheme: string * allowPort: int -> unit"; + " member Equals: o: obj -> bool"; + " member GetHashCode: unit -> int"; + " static member CreateAnySchemeAccess: allowPort: int -> CodeConnectAccess"; + " static member CreateOriginSchemeAccess: allowPort: int -> CodeConnectAccess"; + " static val AnyScheme: string"; + " static val DefaultPort: int"; " ..."; ]) @@ -2194,56 +2150,17 @@ query." [ "type F1 ="; " inherit Form"; " interface IDisposable"; - " new : unit -> F1"; - " val x: F1"; - " abstract member AAA : int"; - " abstract member ZZZ : int"; - " abstract member AAA : bool with set"; - " member B : unit -> int"; - " member D : unit -> int"; - " member D : x:int -> int"; + " new: unit -> F1"; + " val x: F1" + " member B: unit -> int"; + " override ToString: unit -> string"; + " static member A: unit -> int"; + " static member C: unit -> int"; + " abstract AAA: int"; + " member D: int"; " ..."; - //" member D : int"; - //" member D : int with set"; - //" static val x: F1"; - //" static member A : unit -> int"; - //" static member C : unit -> int"; ]) -(* TODO why does this portion not work? specifically, last assert fails - printfn "changing file..." - ReplaceFileInMemory file1 ["#light" - "let xx = \"foo\"" // now x is string - "printfn \"hi\""] - - // assert p1 xx is string - MoveCursorToEndOfMarker(file1,"let x") - TakeCoffeeBreak(this.VS) - let tooltip = GetQuickInfoAtCursor file1 - AssertContains(tooltip,"string") - - // assert p2 yy is int - MoveCursorToEndOfMarker(file2,"let y") - let tooltip = GetQuickInfoAtCursor file2 - AssertContains(tooltip,"int") - - AssertNoErrorsOrWarnings(project1) - AssertNoErrorsOrWarnings(project2) - - printfn "rebuilding dependent project..." - // (re)build p1 (with xx now string) - Build(project1) |> ignore - TakeCoffeeBreak(this.VS) - - AssertNoErrorsOrWarnings(project1) - AssertNoErrorsOrWarnings(project2) - - // assert p2 yy is now string - MoveCursorToEndOfMarker(file2,"let y") - let tooltip = GetQuickInfoAtCursor file2 - AssertContains(tooltip,"string") -*) - (*------------------------------------------IDE automation starts here -------------------------------------------------*) [] member public this.``Automation.Regression.AccessibilityOnTypeMembers.Bug4168``() = @@ -2256,12 +2173,6 @@ query." internal new(x:int,y:int) = new Foo2() private new(x:int,y:int,z:int) = new Foo2()""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "type internal Foo2") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "private new : x:int * y:int * z:int -> Foo2") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "new : x:int * y:int -> Foo2") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "private new") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member Prop1") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member Prop2") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member private Prop3") [] member public this.``Automation.Regression.AccessorsAndMutators.Bug4276``() = @@ -2293,13 +2204,12 @@ query." point.Length |> ignore""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "type TestType1") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Length : float") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Length: float") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Item") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member X : int") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Y : int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member X: int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Y: int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "type BitArray") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "member Length : int") // trimmed quick info doesn't contain all entries - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "member Count : int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "member Not: unit -> BitArray") this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker2*)" "get_Length" this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker2*)" "set_Length" @@ -2385,7 +2295,7 @@ query." let (_, _, file) = this.CreateSingleFileProject(fileContent, references = ["PresentationCore"; "WindowsBase"]) MoveCursorToStartOfMarker(file, "(*Marker*)") let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip" - AssertContains(tooltip, "override CommandReference.CanExecuteChanged : IEvent") + AssertContains(tooltip, "override CommandReference.CanExecuteChanged: IEvent") AssertContains(tooltip, "regressiontest.CommandReference.CanExecuteChanged") [] @@ -2480,29 +2390,29 @@ query." this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "property System.Random.DiceValue: int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "BCL class Extension property") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "member System.Random.NextDice : unit -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "member System.Random.NextDice: unit -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "BCL class Extension method") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker13*)", "member System.Random.NextDice : a:bool -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker13*)", "member System.Random.NextDice: a: bool -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker13*)", "new BCL class Extension method with overload") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker14*)", "member System.Random.Next : a:bool -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker14*)", "member System.Random.Next: a: bool -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker14*)", "existing BCL class Extension method with overload") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "member System.ConsoleKeyInfo.ExtentionMethod : unit -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "member System.ConsoleKeyInfo.ExtentionMethod: unit -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "BCL struct extension method") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "System.ConsoleKeyInfo.ExtentionProperty: string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "BCL struct extension property") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker31*)", "member FSClass.ExtentionMethod : unit -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker31*)", "member FSClass.ExtentionMethod: unit -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker31*)", "fs class extension method") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker32*)", "FSClass.ExtentionProperty: string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker32*)", "fs class extension property") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker33*)", "member FSClass.Method : a:string -> string") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker33*)", "member FSClass.Method: a: string -> string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker33*)", "fs class method original") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker34*)", "member FSClass.Method : a:int -> string") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker34*)", "member FSClass.Method: a: int -> string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker34*)", "fs class method extension overload") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker35*)", "property FSClass.Prop: string -> string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker35*)", "fs class property original") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker36*)", "property FSClass.Prop: int -> string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker36*)", "fs class property extension overload") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker41*)", "member FSStruct.ExtentionMethod : unit -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker41*)", "member FSStruct.ExtentionMethod: unit -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker41*)", "fs struct extension method") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker42*)", "FSStruct.ExtentionProperty: string") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker42*)", "fs struct extension property") @@ -2514,7 +2424,7 @@ query." let F (f :_ -> float<_>) = fun x -> f (x+1.0) let rec Gen<[] 'u> (f:float<'u> -> float<'u>) = Gen(*Marker*)(F f)""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val Gen : f:(float -> float) -> 'a") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val Gen: f: (float -> float) -> 'a") this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "Exception" this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "thrown" @@ -2559,24 +2469,24 @@ query." member this.Value with get(*Marker6_1*) () = 10 and set(*Marker6_2*) x = x + 1 |> ignore""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "module float") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val float : 'T -> float (requires member op_Explicit)") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val float: 'T -> float (requires member op_Explicit)") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "Full name: Microsoft.FSharp.Core.Operators.float") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_3*)", "type float = System.Double") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_3*)", "Full name: Microsoft.FSharp.Core.float") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker2_1*)","type seq<'T> = System.Collections.Generic.IEnumerable<'T>") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker2_1*)","Full name: Microsoft.FSharp.Collections.seq<_>") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val seq : seq<'T> -> seq<'T>") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val seq: seq<'T> -> seq<'T>") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "Full name: Microsoft.FSharp.Core.Operators.seq") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker3_1*)","type Set<'T (requires comparison)> =") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker3_1*)","Full name: Microsoft.FSharp.Collections.Set") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "module Set") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "Functional programming operators related to the Set<_> type") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "val int : int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "val int: int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "Full name: NS.float.int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "type int = int32") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "Full name: Microsoft.FSharp.Core.int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_3*)", "type int =") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_3*)", "member M : int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_3*)", "member M: int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "type T =") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "new : unit -> T") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "val mutable T: T") @@ -2626,7 +2536,7 @@ query." |> Set.ofList |> Set(*Marker22*).isEmpty |> ignore""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "val mass : float") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "val mass: float") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "Full name: TestQuickinfo.TestCase1.mass") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "inherits: System.ValueType") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "[]") @@ -2660,8 +2570,8 @@ query." let sink = new ByteOutputSink() sink.WriteChar(*Marker11*)('c') sink.WriteString(*Marker12*)("Hello World!")""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "override ByteOutputSink.WriteChar : c:char -> unit") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "override ByteOutputSink.WriteString : s:string -> unit") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "override ByteOutputSink.WriteChar: c: char -> unit") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "override ByteOutputSink.WriteString: s: string -> unit") [] member public this.``Automation.Regression.QuotedIdentifier.Bug3790``() = @@ -2709,10 +2619,10 @@ query." foo(*Marker5*) 2 3 |> ignore""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "T.XX: int * int * int") this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker1*)" "->" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "IFoo.foo : int -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "IFoo.foo: int -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "Rec.bar: int -> int -> int") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "T2.Foo : a:'a * b:'b -> string") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val foo : int -> int -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "T2.Foo: a: 'a * b: 'b -> string") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val foo: int -> int -> int") [] member public this.``Automation.Regression.TupleException.Bug3723``() = @@ -2767,26 +2677,15 @@ query." let genericClass(*Marker4_2*) = new GenericClass()""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "type MyInt = int") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "Full name: NS.TypeAbbreviation.MyInt") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val myInt : MyInt") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val myInt: MyInt") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_1*)", "type PairOfFloat = float * float") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_1*)", "Full name: NS.TypeAbbreviation.PairOfFloat") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val MySeq : seq") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "Full name: NS.TypeAbbreviation.MySeq") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val MySeq: seq") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_1*)", "type IA =") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_1*)", "abstract member AbstractMember : int -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "type ClassIA =") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "Full name: NS.TypeAbbreviation.ClassIA") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "implements: IA") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "type GenericClass<'a (requires 'a :> IA)> =") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "static member StaticMember : x:'a -> int") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "Full name: NS.TypeAbbreviation.GenericClass<_>") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "val genericClass : GenericClass") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "Full name: NS.TypeAbbreviation.genericClass") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "val genericClass: GenericClass") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "type AbAttrName = AbstractClassAttribute") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "implements: System.Runtime.InteropServices._Attribute") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_2*)", "type AbAttrName = AbstractClassAttribute") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_2*)", "implements: System.Runtime.InteropServices._Attribute") [] member public this.``Automation.Regression.TypeInferenceSenarios.Bug2362&3538``() = @@ -2814,12 +2713,12 @@ query." member this.Prop = this.x let x = new (*Marker7*)A()""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "val m : ('a -> 'b)") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "val n : ('c -> 'a)") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "val ac : 'c") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "val this : Foo") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val this : Foo") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6*)", "val this : Foo") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "val m: ('a -> 'b)") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "val n: ('c -> 'a)") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "val ac: 'c") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "val this: Foo") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val this: Foo") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6*)", "val this: Foo") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker7*)","type A =") this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker7*)","val mutable x: int") @@ -2844,12 +2743,10 @@ query." let singleton(*MarkerLastLine*) k a = Branch(k,a,Nil,Nil)""" this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "type PriorityQueue") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "Full name: NS.PriorityQueue<_,_>") - //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "implements: IComparable") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerDataConstructor*)", "union case PriorityQueue.Nil: PriorityQueue<'k,'a>") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "module PriorityQueue") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerVal*)", "val pq : PriorityQueue<'a,'b>") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerLastLine*)", "val singleton : k:'a -> a:'b -> PriorityQueue<'a,'b>") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerVal*)", "val pq: PriorityQueue<'a,'b>") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerLastLine*)", "val singleton: k: 'a -> a: 'b -> PriorityQueue<'a,'b>") [] member public this.``Automation.WhereQuickInfoShouldNotShowUp``() = @@ -2908,7 +2805,7 @@ query." /// XmlComment K let rec g x = 1 g x""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val func : x:'a -> int") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val func: x: 'a -> int") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "XmlComment J") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "Full name: TestQuickinfo.XmlComment.func") this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "XmlComment K" @@ -2942,7 +2839,8 @@ query." type bar() = /// Test for members /// x1 param! - member this.foo (x1:int)= + member this.foo + (x1:int)= System.Console.WriteLine(x1.ToString()) type Uni1 = @@ -2956,7 +2854,7 @@ query." exception Ex1 of value: string // Methods - let f1 = (new bar()).foo(x1(*Marker1*) = 10) + let f1 = (new bar()).foo(*Marker0*)(x1(*Marker1*) = 10) let f2 = System.String.Concat(1, arg1(*Marker2*) = "") //Unions @@ -2976,8 +2874,9 @@ query." type provType = N1.T """ + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker0*)", "Test for members") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "x1 param!") - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "[ParamName: arg1]") + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "Concatenates the string representations of two specified objects.") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "str of case1") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "str of case1") this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "value param") @@ -3163,10 +3062,9 @@ query." let a = MyPoint((float)i,2.0) // TC 36 Field Struct Own Code Comp Expression yield a.X(*Marker4*) }""" - let queries = [("(*Marker1*)", "val controlEventHandler : ControlEventHandler"); + let queries = [("(*Marker1*)", "val controlEventHandler: ControlEventHandler"); ("(*Marker2*)", "property MyDistance.Event: Event"); -// ("(*Marker2*)", "DocComment: Event"); //Fail: due to DocComments - ("(*Marker3*)", "val newDelegate : ControlEventHandler"); + ("(*Marker3*)", "val newDelegate: ControlEventHandler"); ("(*Marker4*)", "property MyPoint.X: float"); ("(*Marker4*)", "Gets and sets X")] this.VerifyUsingFsTestLib fileContent queries false @@ -3205,10 +3103,9 @@ query." let a = MyPoint((float)i,2.0) // TC 36 Field Struct Own Code Comp Expression yield a.X(*Marker4*) }""" - let queries = [("(*Marker1*)", "val controlEventHandler : ControlEventHandler"); + let queries = [("(*Marker1*)", "val controlEventHandler: ControlEventHandler"); ("(*Marker2*)", "property MyDistance.Event: Event"); -// ("(*Marker2*)", "DocComment: Event"); //Fail: due to DocComments - ("(*Marker3*)", "val newDelegate : ControlEventHandler"); + ("(*Marker3*)", "val newDelegate: ControlEventHandler"); ("(*Marker4*)", "property MyPoint.X: float"); ("(*Marker4*)", "Gets and sets X"); ] @@ -3255,14 +3152,12 @@ query." // TC 34 Operator Tuple Own Code Pattern Match | true -> tuplex(*Marker4*) | false -> tupley""" - let queries = [("(*Marker1*)", "val tuple1 : int * string * float * (int -> string * int)"); + let queries = [("(*Marker1*)", "val tuple1: int * string * float * (int -> string * int)"); ("(*Marker2*)", "type MyEmployee"); -// ("(*Marker2*)", "DocComment: This is my record type."); //Fail: due to DocComments ("(*Marker2*)", "Full name: FSTestLib.MyEmployee"); ("(*Marker3*)", "type MyCar"); -// ("(*Marker3*)", "DocComment: This is my class type"); //Fail: due to DocComments ("(*Marker3*)", "Full name: FSTestLib.MyCar"); - ("(*Marker4*)", "val tuplex : 'a * string") + ("(*Marker4*)", "val tuplex: 'a * string") ] this.VerifyUsingFsTestLib fileContent queries false @@ -3345,7 +3240,7 @@ query." }""" this.AssertQuickInfoInQuery (fileContent, "(*Mark*)", "custom operation: minBy ('Value)") - [] + [] [] // QuickInfo works in a large query (using many operators) member public this.``Query.WithinLargeQuery``() = @@ -3389,7 +3284,7 @@ query." for n in numbers do orderBy (n.GetType()) select n}""" - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "n.GetType()", "val n : int",queryAssemblyRefs) + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "n.GetType()", "val n: int",queryAssemblyRefs) this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "Type()", "System.Object.GetType() : System.Type",queryAssemblyRefs) [] @@ -3410,7 +3305,7 @@ query." let mostExpensiveProducts = query { for x in g do where(*Mark1*) (x.UnitPrice = maxPrice(*Mark2*)) } select(*Mark4*) (g.Key, g)}) } """ this.AssertQuickInfoInQuery (fileContent, "(*Mark1*)", "custom operation: where (bool)") - this.AssertQuickInfoInQuery (fileContent, "(*Mark2*)", "val maxPrice : decimal") + this.AssertQuickInfoInQuery (fileContent, "(*Mark2*)", "val maxPrice: decimal") this.AssertQuickInfoInQuery (fileContent, "(*Mark3*)", "custom operation: groupValBy ('Value) ('Key)") this.AssertQuickInfoInQuery (fileContent, "(*Mark4*)", "custom operation: select ('Result)") @@ -3455,8 +3350,8 @@ query." where (result |> Array.exists(fun i -> i = char)) yield char } """ - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark1*)", "member WorkflowBuilder.Combine : f:'b0 * g:'c1 -> 'c1",queryAssemblyRefs) - this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark2*)", "member WorkflowBuilder.Zero : unit -> unit",queryAssemblyRefs) + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark1*)", "member WorkflowBuilder.Combine: f: 'b0 * g: 'c1 -> 'c1",queryAssemblyRefs) + this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark2*)", "member WorkflowBuilder.Zero: unit -> unit",queryAssemblyRefs) [] [] @@ -3467,19 +3362,19 @@ query." open Microsoft.FSharp.Quotations type EventBuilder() = - member __.For(ev:IObservable<'T>, loop:('T -> #IObservable<'U>)) : IObservable<'U> = failwith "" - member __.Yield(v:'T) : IObservable<'T> = failwith "" - member __.Quote(v:Quotations.Expr<'T>) : Expr<'T> = v - member __.Run(x:Expr<'T>) = Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation x :?> 'T + member _.For(ev:IObservable<'T>, loop:('T -> #IObservable<'U>)) : IObservable<'U> = failwith "" + member _.Yield(v:'T) : IObservable<'T> = failwith "" + member _.Quote(v:Quotations.Expr<'T>) : Expr<'T> = v + member _.Run(x:Expr<'T>) = Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation x :?> 'T [] - member __.Where (x, [] f) = Observable.filter f x + member _.Where (x, [] f) = Observable.filter f x [] - member __.Select (x, [] f) = Observable.map f x + member _.Select (x, [] f) = Observable.map f x [] - member inline __.ScanSumBy (source, [] f : 'T -> 'U) : IObservable<'U> = Observable.scan (fun a b -> a + f b) LanguagePrimitives.GenericZero<'U> source + member inline _.ScanSumBy (source, [] f : 'T -> 'U) : IObservable<'U> = Observable.scan (fun a b -> a + f b) LanguagePrimitives.GenericZero<'U> source let myquery = EventBuilder() let f = new Event() diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickParse.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickParse.fs index 36fe51370d0..4f2297a74e4 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickParse.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.QuickParse.fs @@ -4,7 +4,7 @@ namespace Tests.LanguageService open System open NUnit.Framework -open FSharp.Compiler +open FSharp.Compiler.EditorServices [] [] diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Script.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Script.fs index cd1589117ad..ea2d28ad606 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Script.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Script.fs @@ -907,15 +907,13 @@ type UsingMSBuild() as this = let (project, file) = createSingleFileFsxFromLines code MoveCursorToEndOfMarker(file, "System.ConsoleModifiers.Sh") let tooltip = GetQuickInfoAtCursor file - AssertContains(tooltip, @"[Signature:F:System.ConsoleModifiers.Shift]") // A message from the mock IDocumentationBuilder - AssertContains(tooltip, @"[Filename:") - AssertContains(tooltip, @"mscorlib.dll]") // The assembly we expect the documentation to get taken from + AssertContains(tooltip, @"The left or right SHIFT modifier key.") MoveCursorToEndOfMarker(file, "(3).ToString().Len") let tooltip = GetQuickInfoAtCursor file AssertContains(tooltip, @"[Signature:P:System.String.Length]") // A message from the mock IDocumentationBuilder AssertContains(tooltip, @"[Filename:") - AssertContains(tooltip, @"mscorlib.dll]") // The assembly we expect the documentation to get taken from + AssertContains(tooltip, @"netstandard.dll]") // The assembly we expect the documentation to get taken from // Especially under 4.0 we need #r of .NET framework assemblies to resolve from like, // @@ -1345,8 +1343,8 @@ type UsingMSBuild() as this = %s\\FSharp.Compiler.Interactive.Settings.dll - - %s\\FSharp.Compiler.Private.dll + + %s\\FSharp.Compiler.Service.dll " binariesFolder binariesFolder) @@ -1660,10 +1658,10 @@ type UsingMSBuild() as this = Assert.IsTrue((countInvaldiationHandlersAdded() = countInvaldiationHandlersRemoved()), "Check6b2, at end, all invalidation handlers removed after explicit cleraring") checkConfigsDisposed() - [] + [] member public this.``TypeProvider.Disposal.SmokeTest1``() = this.TypeProviderDisposalSmokeTest(true) - [] + [] member public this.``TypeProvider.Disposal.SmokeTest2``() = this.TypeProviderDisposalSmokeTest(false) diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.TimeStamp.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.TimeStamp.fs index 4fdf86bca8d..f3f72deacf8 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.TimeStamp.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.TimeStamp.fs @@ -46,6 +46,7 @@ type UsingMSBuild() = // In this bug, if you clean the dependent project, the dependee started getting errors again about the unresolved assembly. // The desired behavior is like C#, which is if the assembly disappears from disk, we use cached results of last time it was there. [] + [] member public this.``Regression.NoError.Timestamps.Bug3368b``() = use _guard = this.UsingNewVS() let solution = this.CreateSolution() diff --git a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Configs.fs b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Configs.fs index ff06f80bac6..74a0178e312 100644 --- a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Configs.fs +++ b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Configs.fs @@ -27,7 +27,7 @@ open UnitTests.TestLib.ProjectSystem type public AssemblyResolverTestFixture () = [] - member public __.Init () = AssemblyResolver.addResolver () + member public _.Init () = AssemblyResolver.addResolver () [][] type Config() = diff --git a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Miscellaneous.fs b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Miscellaneous.fs index 1f5dfff2054..b390100ded5 100644 --- a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Miscellaneous.fs +++ b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.Miscellaneous.fs @@ -266,8 +266,7 @@ type Miscellaneous() = this.MSBuildProjectBoilerplate "Library", (fun project ccn projFileName -> let fooPath = Path.Combine(project.ProjectFolder, "foo.fs") - File.AppendAllText(fooPath, "#light") - File.AppendAllText(fooPath, "module Foo") + File.AppendAllLines(fooPath, ["#light"; "module Foo"]) //ccn((project :> IVsHierarchy), "Debug|Any CPU") let configName = "Debug" @@ -278,6 +277,7 @@ type Miscellaneous() = let buildableCfg = vsBuildableCfg :?> BuildableProjectConfig AssertEqual VSConstants.S_OK hr + let mutable isCleaning = false let success = ref false use event = new System.Threading.ManualResetEvent(false) let (hr, cookie) = @@ -286,6 +286,8 @@ type Miscellaneous() = member this.BuildBegin pfContinue = pfContinue <- 1; VSConstants.S_OK member this.BuildEnd fSuccess = success := fSuccess <> 0 + printfn "Build %s, code %i, phase: %s." (if !success then "succeeded" else "failed") fSuccess (if isCleaning then "Cleaning" else "Build") + event.Set() |> Assert.IsTrue VSConstants.S_OK member this.Tick pfContinue = pfContinue <- 1; VSConstants.S_OK @@ -301,14 +303,19 @@ type Miscellaneous() = buildableCfg.Build(0u, output, target) event.WaitOne() |> Assert.IsTrue buildMgrAccessor.EndDesignTimeBuild() |> ValidateOK // this is not a design-time build, but our mock does all the right initialization of the build manager for us, similar to what the system would do in VS for real - AssertEqual true !success - printfn "building..." - doBuild "Build" + AssertEqual true !success + + printfn "Building..." + doBuild "Build" AssertEqual true (File.Exists (Path.Combine(project.ProjectFolder, "bin\\Debug\\Blah.dll"))) + printfn "Output files present." - printfn "cleaning..." + isCleaning <- true + printfn "Cleaning..." doBuild "Clean" + printfn "Finished build-then-clean." AssertEqual false (File.Exists (Path.Combine(project.ProjectFolder, "bin\\Debug\\Blah.dll"))) + printfn "Files were cleaned." finally buildableCfg.UnadviseBuildStatusCallback(cookie) |> AssertEqual VSConstants.S_OK )) diff --git a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.UpToDate.fs b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.UpToDate.fs index 41b596fcfac..a8775d777a0 100644 --- a/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.UpToDate.fs +++ b/vsintegration/tests/UnitTests/LegacyProjectSystem/Tests.ProjectSystem.UpToDate.fs @@ -29,7 +29,7 @@ type UpToDate() = inherit TheTests() [] - member public __.Init () = AssemblyResolver.addResolver () + member public _.Init () = AssemblyResolver.addResolver () [] member public this.ItemInputs () = diff --git a/vsintegration/tests/UnitTests/ProjectDiagnosticAnalyzerTests.fs b/vsintegration/tests/UnitTests/ProjectDiagnosticAnalyzerTests.fs deleted file mode 100644 index 6491c77b5c0..00000000000 --- a/vsintegration/tests/UnitTests/ProjectDiagnosticAnalyzerTests.fs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn - -open System -open System.IO -open System.Threading - -open FSharp.Compiler.Service.Tests.Common - -open NUnit.Framework - -open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Classification -open Microsoft.CodeAnalysis.Editor -open Microsoft.CodeAnalysis.Text - -open Microsoft.VisualStudio.FSharp.Editor -open Microsoft.VisualStudio.FSharp.LanguageService - -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range - -[][] -type ProjectDiagnosticAnalyzerTests() = - - let CreateProjectAndGetOptions(fileContents: string) = - let tempName = Path.GetTempFileName() - let fileName = Path.ChangeExtension(tempName, ".fs") - let projectName = Path.ChangeExtension(tempName, ".fsproj") - let dllName = Path.ChangeExtension(tempName, ".dll") - File.WriteAllText(fileName, fileContents) - - let args = mkProjectCommandLineArgs (dllName, [fileName]) - checker.GetProjectOptionsFromCommandLineArgs (projectName, args) - -#if PROJECT_ANALYSIS - [] - member public this.ProjectDiagnosticsDontReportJustProjectErrors_Bug1596() = - // https://github.com/Microsoft/visualfsharp/issues/1596 - let fileContents = """ -let x = 3 -printf "%d" x -""" - let options = CreateProjectAndGetOptions(fileContents) - let additionalOptions = {options with OtherOptions = Array.append options.OtherOptions [| "--times" |]} - - let errors = FSharpProjectDiagnosticAnalyzer.GetDiagnostics(additionalOptions) |> Async.RunSynchronously - Assert.AreEqual(1, errors.Length, "Exactly one warning should have been reported") - - let warning = errors.[0] - Assert.AreEqual(DiagnosticSeverity.Warning, warning.Severity, "Diagnostic severity should be a warning") - Assert.AreEqual("The command-line option 'times' is for test purposes only", warning.GetMessage()) - - [] - member public this.ProjectDiagnosticsShouldNotReportDocumentErrors_Bug1596() = - // https://github.com/Microsoft/visualfsharp/issues/1596 - let fileContents = """ -let x = "string value that cannot be printed with %d" -printf "%d" x -""" - let options = CreateProjectAndGetOptions(fileContents) - - let errors = FSharpProjectDiagnosticAnalyzer.GetDiagnostics(options) |> Async.RunSynchronously - Assert.AreEqual(0, errors.Length, "No semantic errors should have been reported") -#endif diff --git a/vsintegration/tests/UnitTests/ProjectOptionsBuilder.fs b/vsintegration/tests/UnitTests/ProjectOptionsBuilder.fs index 1d3df25165f..847adf617b2 100644 --- a/vsintegration/tests/UnitTests/ProjectOptionsBuilder.fs +++ b/vsintegration/tests/UnitTests/ProjectOptionsBuilder.fs @@ -3,7 +3,20 @@ open System open System.IO open System.Xml.Linq -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis + +module FileSystemHelpers = + let safeDeleteFile (path: string) = + try + File.Delete(path) + with + | _ -> () + + let safeDeleteDirectory (path: string) = + try + Directory.Delete(path) + with + | _ -> () type FSharpProject = { @@ -29,9 +42,10 @@ type FSharpProject = member this.Dispose() = // delete each source file this.Files - |> List.iter (fun (path, _contents) -> File.Delete(path)) + |> List.map fst + |> List.iter FileSystemHelpers.safeDeleteFile // delete the directory - Directory.Delete(this.Directory) + FileSystemHelpers.safeDeleteDirectory (this.Directory) // project file doesn't really exist, nothing to delete () @@ -67,7 +81,6 @@ module internal ProjectOptionsBuilder = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } { @@ -111,7 +124,7 @@ module internal ProjectOptionsBuilder = let otherOptions = Array.append projectOptions.Options.OtherOptions binaryRefs { projectOptions with Options = { projectOptions.Options with - ReferencedProjects = referenceList + ReferencedProjects = referenceList |> Array.map FSharpReferencedProject.CreateFSharp OtherOptions = otherOptions } }) diff --git a/vsintegration/tests/UnitTests/QuickInfoProviderTests.fs b/vsintegration/tests/UnitTests/QuickInfoProviderTests.fs index e412029cf26..4a6d9d6e763 100644 --- a/vsintegration/tests/UnitTests/QuickInfoProviderTests.fs +++ b/vsintegration/tests/UnitTests/QuickInfoProviderTests.fs @@ -14,12 +14,12 @@ // and capturing large amounts of structured output. (* cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs + .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Service.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\CompletionProviderTests.fs .\VisualFSharp.UnitTests.exe *) // Technique 3: // -// Use F# Interactive. This only works for FSharp.Compiler.Private.dll which has a public API +// Use F# Interactive. This only works for FSharp.Compiler.Service.dll which has a public API // // ------------------------------------------------------------------------------------------------------------------------ @@ -74,28 +74,28 @@ let private getQuickInfoText (FSharpToolTipText elements) : string = let remarksText = (match remarks with [] -> "" | _ -> "\n" + String.concat "\n" remarks) text + remarksText + tpText | FSharpToolTipElement.CompositionError(error) -> error - elements |> List.map (Tooltips.ToFSharpToolTipElement >> parseElement) |> String.concat "\n" |> normalizeLineEnds + elements |> List.map (FSharpToolTip.ToFSharpToolTipElement >> parseElement) |> String.concat "\n" |> normalizeLineEnds [] let ShouldShowQuickInfoAtCorrectPositions() = let testCases = - [ "x", Some "val x : int\nFull name: Test.x" - "y", Some "val y : int\nFull name: Test.y" + [ "x", Some "val x: int\nFull name: Test.x" + "y", Some "val y: int\nFull name: Test.y" "1", None "2", None - "x +", Some "val x : int\nFull name: Test.x" + "x +", Some "val x: int\nFull name: Test.x" "System", Some "namespace System" "Console", Some "type Console = - static member BackgroundColor : ConsoleColor with get, set - static member Beep : unit -> unit + 1 overload - static member BufferHeight : int with get, set - static member BufferWidth : int with get, set - static member CapsLock : bool - static member Clear : unit -> unit - static member CursorLeft : int with get, set - static member CursorSize : int with get, set - static member CursorTop : int with get, set - static member CursorVisible : bool with get, set + static member BackgroundColor: ConsoleColor with get, set + static member Beep: unit -> unit + 1 overload + static member BufferHeight: int with get, set + static member BufferWidth: int with get, set + static member CapsLock: bool + static member Clear: unit -> unit + static member CursorLeft: int with get, set + static member CursorSize: int with get, set + static member CursorTop: int with get, set + static member CursorVisible: bool with get, set ... Full name: System.Console" "WriteLine", Some "System.Console.WriteLine(value: int) : unit" ] @@ -164,19 +164,19 @@ Full name: Microsoft.FSharp.Core.Operators.( |> ) 'U is int list"); ("let res3 = [1] |> List.map id", Some - "val id : x:'T -> 'T + "val id: x: 'T -> 'T Full name: Microsoft.FSharp.Core.Operators.id 'T is int"); ("let res4 = (1.0,[1]) ||>", Some - "val ( ||> ) : arg1:'T1 * arg2:'T2 -> func:('T1 -> 'T2 -> 'U) -> 'U + "val ( ||> ): arg1: 'T1 * arg2: 'T2 -> func: ('T1 -> 'T2 -> 'U) -> 'U Full name: Microsoft.FSharp.Core.Operators.( ||> ) 'T1 is float 'T2 is int list 'U is float"); ("let res4 = (1.0,[1]) ||> List.fold", Some - "val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State + "val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> list: 'T list -> 'State Full name: Microsoft.FSharp.Collections.List.fold 'T is int 'State is float"); @@ -203,12 +203,12 @@ Full name: Microsoft.FSharp.Core.Operators.( + ) 'T3 is System.DateTime"); ("let res7 = sin", Some - "val sin : value:'T -> 'T (requires member Sin) + "val sin: value: 'T -> 'T (requires member Sin) Full name: Microsoft.FSharp.Core.Operators.sin 'T is float"); ("let res8 = abs", Some - "val abs : value:'T -> 'T (requires member Abs) + "val abs: value: 'T -> 'T (requires member Abs) Full name: Microsoft.FSharp.Core.Operators.abs 'T is int")] let actualForAllTests = diff --git a/vsintegration/tests/UnitTests/QuickInfoTests.fs b/vsintegration/tests/UnitTests/QuickInfoTests.fs index 415079942e7..be0e18f0412 100644 --- a/vsintegration/tests/UnitTests/QuickInfoTests.fs +++ b/vsintegration/tests/UnitTests/QuickInfoTests.fs @@ -1,7 +1,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn open System.IO -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.Text open Microsoft.VisualStudio.FSharp.Editor @@ -15,9 +15,8 @@ module QuickInfo = let internal GetQuickInfo (project:FSharpProject) (fileName:string) (caretPosition:int) = async { let code = File.ReadAllText(fileName) - let sourceText = SourceText.From(code) - let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()) // only used for caching purposes - return! FSharpAsyncQuickInfoSource.ProvideQuickInfo(checker, documentId, sourceText, fileName, caretPosition, FSharpParsingOptions.Default, project.Options, 0, LanguageServicePerformanceOptions.Default) + let document, _ = RoslynTestHelpers.CreateDocument(fileName, code) + return! FSharpAsyncQuickInfoSource.ProvideQuickInfo(document, caretPosition) } |> Async.RunSynchronously let GetQuickInfoText (project:FSharpProject) (fileName:string) (caretPosition:int) = @@ -26,8 +25,8 @@ let GetQuickInfoText (project:FSharpProject) (fileName:string) (caretPosition:in | Some (quickInfo) -> let documentationBuilder = { new IDocumentationBuilder with - override __.AppendDocumentationFromProcessedXML(_, _, _, _, _, _) = () - override __.AppendDocumentation(_, _, _, _, _, _, _) = () + override _.AppendDocumentationFromProcessedXML(_, _, _, _, _, _) = () + override _.AppendDocumentation(_, _, _, _, _, _, _) = () } let mainDescription, docs = FSharpAsyncQuickInfoSource.BuildSingleQuickInfoItem documentationBuilder quickInfo let mainTextItems = @@ -127,7 +126,7 @@ module Test = () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "abstract member IMyInterface.Represent : unit -> string" + let expected = "abstract IMyInterface.Represent: unit -> string" Assert.AreEqual(expected, quickInfo) // migrated from legacy test @@ -154,9 +153,11 @@ module Test = let quickInfo = GetQuickInfoTextFromCode code let expected = expectedLines [ "type MyEmployee =" - " { mutable Name: string" + " {" + " mutable Name: string" " mutable Age: int" - " mutable IsFTE: bool }" + " mutable IsFTE: bool" + " }" "Full name: FsTest.MyEmployee" ] Assert.AreEqual(expected, quickInfo) () @@ -181,7 +182,7 @@ module Test = () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val aa : MyEmployee" + let expected = "val aa: MyEmployee" Assert.AreEqual(expected, quickInfo) () @@ -232,7 +233,7 @@ module Test = () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val myTuple : int * string * float * (int -> string * int)" + let expected = "val myTuple: int * string * float * (int -> string * int)" Assert.AreEqual(expected, quickInfo) () @@ -261,7 +262,7 @@ module Test = () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val methodSeq : seq<(int -> string * int)>" + let expected = "val methodSeq: seq<(int -> string * int)>" Assert.AreEqual(expected, quickInfo) () @@ -284,7 +285,7 @@ module Test = | _ -> 1 """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val p1 : MyPoint" + let expected = "val p1: MyPoint" Assert.AreEqual(expected, quickInfo) () @@ -307,7 +308,7 @@ module Test = | _ -> 1 """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val p3 : MyPoint" + let expected = "val p3: MyPoint" Assert.AreEqual(expected, quickInfo) () @@ -329,7 +330,7 @@ module Test = else () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val dd : MyDistance" + let expected = "val dd: MyDistance" Assert.AreEqual(expected, quickInfo) () @@ -351,7 +352,7 @@ module Test = () """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "val distance : MyDistance" + let expected = "val distance: MyDistance" Assert.AreEqual(expected, quickInfo) () @@ -381,7 +382,7 @@ module Test = | _ -> 1 """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "static member MyDistance.toMiles : x:MyDistance -> MyDistance" + let expected = "static member MyDistance.toMiles: x: MyDistance -> MyDistance" Assert.AreEqual(expected, quickInfo) () @@ -409,7 +410,7 @@ module Test = | _ -> dd """ let quickInfo = GetQuickInfoTextFromCode code - let expected = "member MyDistance.IncreaseBy : dist:float -> MyDistance" + let expected = "member MyDistance.IncreaseBy: dist: float -> MyDistance" Assert.AreEqual(expected, quickInfo) () diff --git a/vsintegration/tests/UnitTests/RoslynSourceTextTests.fs b/vsintegration/tests/UnitTests/RoslynSourceTextTests.fs index 9a817df9771..54a92f3cd0b 100644 --- a/vsintegration/tests/UnitTests/RoslynSourceTextTests.fs +++ b/vsintegration/tests/UnitTests/RoslynSourceTextTests.fs @@ -6,7 +6,7 @@ open System open NUnit.Framework open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.Text +open FSharp.Compiler.CodeAnalysis open Microsoft.CodeAnalysis.Text [] diff --git a/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs b/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs index f2674593574..78d0732493b 100644 --- a/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs +++ b/vsintegration/tests/UnitTests/SemanticColorizationServiceTests.fs @@ -4,9 +4,11 @@ namespace Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn open System open NUnit.Framework open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text open Microsoft.CodeAnalysis.Text +open Microsoft.CodeAnalysis.Classification [] type SemanticClassificationServiceTests() = @@ -23,17 +25,16 @@ type SemanticClassificationServiceTests() = LoadTime = DateTime.MaxValue UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo = None Stamp = None } let checker = FSharpChecker.Create() let perfOptions = { LanguageServicePerformanceOptions.Default with AllowStaleCompletionResults = false } - let getRanges (source: string) : (Range.range * SemanticClassificationType) list = + let getRanges (source: string) : SemanticClassificationItem list = asyncMaybe { - - let! _, _, checkFileResults = checker.ParseAndCheckDocument(filePath, 0, SourceText.From(source), projectOptions, perfOptions, "") + let document, _ = RoslynTestHelpers.CreateDocument(filePath, source) + let! _, checkFileResults = document.GetFSharpParseAndCheckResultsAsync("SemanticClassificationServiceTests") |> liftAsync return checkFileResults.GetSemanticClassification(None) } |> Async.RunSynchronously @@ -44,27 +45,27 @@ type SemanticClassificationServiceTests() = let text = SourceText.From(fileContents) let ranges = getRanges fileContents let line = text.Lines.GetLinePosition (fileContents.IndexOf(marker) + marker.Length - 1) - let markerPos = Range.mkPos (Range.Line.fromZ line.Line) (line.Character + marker.Length - 1) - match ranges |> List.tryFind (fun (range, _) -> Range.rangeContainsPos range markerPos) with + let markerPos = Position.mkPos (Line.fromZ line.Line) (line.Character + marker.Length - 1) + match ranges |> List.tryFind (fun item -> Range.rangeContainsPos item.Range markerPos) with | None -> Assert.Fail("Cannot find colorization data for end of marker") - | Some(_, ty) -> Assert.AreEqual(classificationType, FSharpClassificationTypes.getClassificationTypeName ty, "Classification data doesn't match for end of marker") + | Some item -> Assert.AreEqual(classificationType, FSharpClassificationTypes.getClassificationTypeName item.Type, "Classification data doesn't match for end of marker") let verifyNoClassificationDataAtEndOfMarker(fileContents: string, marker: string, classificationType: string) = let text = SourceText.From(fileContents) let ranges = getRanges fileContents let line = text.Lines.GetLinePosition (fileContents.IndexOf(marker) + marker.Length - 1) - let markerPos = Range.mkPos (Range.Line.fromZ line.Line) (line.Character + marker.Length - 1) - let anyData = ranges |> List.exists (fun (range, sct) -> Range.rangeContainsPos range markerPos && ((FSharpClassificationTypes.getClassificationTypeName sct) = classificationType)) + let markerPos = Position.mkPos (Line.fromZ line.Line) (line.Character + marker.Length - 1) + let anyData = ranges |> List.exists (fun item -> Range.rangeContainsPos item.Range markerPos && ((FSharpClassificationTypes.getClassificationTypeName item.Type) = classificationType)) Assert.False(anyData, "Classification data was found when it wasn't expected.") - [] - [] - [] - [] - [] - [] - [] - member __.Measured_Types(marker: string, classificationType: string) = + [] + [] + [] + [] + [] + [] + [] + member _.Measured_Types(marker: string, classificationType: string) = verifyClassificationAtEndOfMarker( """#light (*Light*) open System @@ -98,7 +99,7 @@ type SemanticClassificationServiceTests() = [] [] [] - member __.MutableValues(marker: string, classificationType: string) = + member _.MutableValues(marker: string, classificationType: string) = let sourceText =""" type R1 = { mutable (*1*)Doop: int} let r1 = { (*2*)Doop = 12 } @@ -122,6 +123,30 @@ r.MutableField := 3 """ verifyClassificationAtEndOfMarker(sourceText, marker, classificationType) + [] + [] + [] + [] + [] + [] + [] + member _.Disposables(marker: string, classificationType: string) = + let sourceText = """ +open System + +type (*1*)Disposable() = + interface IDisposable with + member _.Dispose() = () + +let (*2*)topLevel1 = new (*3*)Disposable() +let (*4*)topLevel2 = { new IDisposable with member _.Dispose() = () } + +let f() = + let (*5*)local1 = new (*6*)Disposable() + let (*7*)local2 = { new IDisposable with member _.Dispose() = () } + () +""" + verifyClassificationAtEndOfMarker(sourceText, marker, classificationType) [] [] @@ -129,7 +154,7 @@ r.MutableField := 3 [] [] [] - member __.NoInrefsExpected(marker: string, classificationType: string) = + member _.NoInrefsExpected(marker: string, classificationType: string) = let sourceText = """ let f (item: (*1*)inref) = printfn "%d" (*2*)item let g() = diff --git a/vsintegration/tests/UnitTests/SignatureHelpProviderTests.fs b/vsintegration/tests/UnitTests/SignatureHelpProviderTests.fs index 043fea97d5e..77b8038e98c 100644 --- a/vsintegration/tests/UnitTests/SignatureHelpProviderTests.fs +++ b/vsintegration/tests/UnitTests/SignatureHelpProviderTests.fs @@ -1,36 +1,23 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// -// To run the tests in this file: -// -// Technique 1: Compile VisualFSharp.UnitTests.dll and run it as a set of unit tests -// -// Technique 2: -// -// Enable some tests in the #if EXE section at the end of the file, -// then compile this file as an EXE that has InternalsVisibleTo access into the -// appropriate DLLs. This can be the quickest way to get turnaround on updating the tests -// and capturing large amounts of structured output. -(* - cd Debug\net40\bin - .\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\SignatureHelpProviderTests.fs - .\VisualFSharp.UnitTests.exe -*) -// Technique 3: -// -// Use F# Interactive. This only works for FSharp.Compiler.Private.dll which has a public API [] module Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.SignatureHelpProvider open System open System.IO -open System.Text + open NUnit.Framework -open Microsoft.CodeAnalysis.Text -open VisualFSharp.UnitTests.Roslyn + open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.SourceCodeServices + +open VisualFSharp.UnitTests.Roslyn + open UnitTests.TestLib.LanguageService +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Text + +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.Text + let filePath = "C:\\test.fs" let PathRelativeToTestAssembly p = Path.Combine(Path.GetDirectoryName(Uri( System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath), p) @@ -46,10 +33,12 @@ let internal projectOptions = { LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } +let internal parsingOptions = + { FSharpParsingOptions.Default with SourceFiles = [| filePath |] } + let private DefaultDocumentationProvider = { new IDocumentationBuilder with override doc.AppendDocumentationFromProcessedXML(_, _, _, _, _, _) = () @@ -58,9 +47,30 @@ let private DefaultDocumentationProvider = let GetSignatureHelp (project:FSharpProject) (fileName:string) (caretPosition:int) = async { - let triggerChar = None // TODO: - let code = File.ReadAllText(fileName) - let! triggered = FSharpSignatureHelpProvider.ProvideMethodsAsyncAux(checker, DefaultDocumentationProvider, SourceText.From(code), caretPosition, project.Options, triggerChar, fileName, 0) + let triggerChar = None + let fileContents = File.ReadAllText(fileName) + let sourceText = SourceText.From(fileContents) + let textLines = sourceText.Lines + let caretLinePos = textLines.GetLinePosition(caretPosition) + let caretLineColumn = caretLinePos.Character + + let document = RoslynTestHelpers.CreateDocument(fileName, sourceText, options = project.Options) + let parseResults, checkFileResults = + document.GetFSharpParseAndCheckResultsAsync("GetSignatureHelp") + |> Async.RunSynchronously + + let paramInfoLocations = parseResults.FindParameterLocations(Position.fromZ caretLinePos.Line caretLineColumn).Value + let triggered = + FSharpSignatureHelpProvider.ProvideMethodsAsyncAux( + caretLinePos, + caretLineColumn, + paramInfoLocations, + checkFileResults, + DefaultDocumentationProvider, + sourceText, + caretPosition, + triggerChar) + |> Async.RunSynchronously return triggered } |> Async.RunSynchronously @@ -68,10 +78,10 @@ let GetCompletionTypeNames (project:FSharpProject) (fileName:string) (caretPosit let sigHelp = GetSignatureHelp project fileName caretPosition match sigHelp with | None -> [||] - | Some (items, _applicableSpan, _argumentIndex, _argumentCount, _argumentName) -> + | Some data -> let completionTypeNames = - items - |> Array.map (fun (_, _, _, _, _, x, _) -> x |> Array.map (fun (_, _, x, _, _) -> x)) + data.SignatureHelpItems + |> Array.map (fun r -> r.Parameters |> Array.map (fun p -> p.CanonicalTypeTextForSorting)) completionTypeNames let GetCompletionTypeNamesFromCursorPosition (project:FSharpProject) = @@ -83,38 +93,236 @@ let GetCompletionTypeNamesFromXmlString (xml:string) = use project = CreateProject xml GetCompletionTypeNamesFromCursorPosition project -let GetCompletionTypeNamesFromCode (code:string) = - use project = SingleFileProject code - GetCompletionTypeNamesFromCursorPosition project +let assertSignatureHelpForMethodCalls (fileContents: string) (marker: string) (expected: (string * int * int * string option) option) = + let caretPosition = fileContents.IndexOf(marker) + marker.Length + let triggerChar = if marker ="," then Some ',' elif marker = "(" then Some '(' elif marker = "<" then Some '<' else None + let sourceText = SourceText.From(fileContents) + let textLines = sourceText.Lines + let caretLinePos = textLines.GetLinePosition(caretPosition) + let caretLineColumn = caretLinePos.Character + + let document = RoslynTestHelpers.CreateDocument(filePath, sourceText, options = projectOptions) + let parseResults, checkFileResults = + document.GetFSharpParseAndCheckResultsAsync("assertSignatureHelpForMethodCalls") + |> Async.RunSynchronously -[] -let ShouldGiveSignatureHelpAtCorrectMarkers() = - let manyTestCases = - [ (""" + let actual = + let paramInfoLocations = parseResults.FindParameterLocations(Position.fromZ caretLinePos.Line caretLineColumn) + match paramInfoLocations with + | None -> None + | Some paramInfoLocations -> + let triggered = + FSharpSignatureHelpProvider.ProvideMethodsAsyncAux( + caretLinePos, + caretLineColumn, + paramInfoLocations, + checkFileResults, + DefaultDocumentationProvider, + sourceText, + caretPosition, + triggerChar) + |> Async.RunSynchronously + + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + match triggered with + | None -> None + | Some data -> Some (data.ApplicableSpan.ToString(),data.ArgumentIndex,data.ArgumentCount,data.ArgumentName) + + Assert.AreEqual(expected, actual) + +let assertSignatureHelpForFunctionApplication (fileContents: string) (marker: string) expectedArgumentCount expectedArgumentIndex = + let caretPosition = fileContents.LastIndexOf(marker) + marker.Length + let document, sourceText = RoslynTestHelpers.CreateDocument(filePath, fileContents) + + let parseResults, checkFileResults = + document.GetFSharpParseAndCheckResultsAsync("assertSignatureHelpForFunctionApplication") + |> Async.RunSynchronously + + let adjustedColumnInSource = + let rec loop ch pos = + if Char.IsWhiteSpace(ch) then + loop sourceText.[pos - 1] (pos - 1) + else + pos + loop sourceText.[caretPosition - 1] (caretPosition - 1) + + let sigHelp = + FSharpSignatureHelpProvider.ProvideParametersAsyncAux( + parseResults, + checkFileResults, + document.Id, + [], + DefaultDocumentationProvider, + sourceText, + caretPosition, + adjustedColumnInSource, + filePath) + |> Async.RunSynchronously + + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + + match sigHelp with + | None -> Assert.Fail("Expected signature help") + | Some sigHelp -> + Assert.AreEqual(expectedArgumentCount, sigHelp.ArgumentCount) + Assert.AreEqual(expectedArgumentIndex, sigHelp.ArgumentIndex) + +[] +module ``Gives signature help in method calls`` = + + [] + let ``dot``() = + let fileContents = """ //1 System.Console.WriteLine(format="Hello, {0}",arg0="World") -""", - [(".", None); - ("System", None); - ("WriteLine", None); - ("(", Some ("[7..64)", 0, 2, Some "format")); - ("format", Some ("[7..64)", 0, 2, Some "format")); - (",", None); - ("""",""", Some ("[7..64)", 1, 2, Some "arg0")); - ("arg0", Some ("[7..64)", 1, 2, Some "arg0")); - ("arg0=", Some ("[7..64)", 1, 2, Some "arg0")); - ("World", Some ("[7..64)", 1, 2, Some "arg0")); - (")", Some("[7..64)", 0, 2, Some "format"))]); - ( """ +""" + let marker = "." + assertSignatureHelpForMethodCalls fileContents marker None + + [] + let ``System``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "System" + assertSignatureHelpForMethodCalls fileContents marker None + + [] + let ``WriteLine``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "WriteLine" + assertSignatureHelpForMethodCalls fileContents marker None + + [] + let ``open paren``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "(" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 0, 2, Some "format")) + + [] + let ``named arg``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "format" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 0, 2, Some "format")) + + [] + let ``comma``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "," + assertSignatureHelpForMethodCalls fileContents marker None + + [] + let ``second comma``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + assertSignatureHelpForMethodCalls fileContents """",""" (Some ("[7..64)", 1, 2, Some "arg0")) + + [] + let ``second named arg``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "arg0" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0")) + + [] + let ``second named arg equals``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "arg0=" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0")) + + [] + let ``World``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") +""" + let marker = "World" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0")) + + [] + let ``end paren``() = + let fileContents = """ +//1 +System.Console.WriteLine(format="Hello, {0}",arg0="World") + """ + let marker = ")" + assertSignatureHelpForMethodCalls fileContents marker (Some("[7..64)", 0, 2, Some "format")) + +[] +module ``Signature help with list literals, parens, etc`` = + [] + let ``Open paren``() = + let fileContents = """ //2 open System Console.WriteLine([(1,2)]) -""", - [ - ("WriteLine(", Some ("[20..45)", 0, 0, None)); - (",", None); - ("[(", Some ("[20..45)", 0, 1, None)) - ]); +""" + let marker = "WriteLine(" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[20..45)", 0, 0, None)) + + [] + let ``comma``() = + let fileContents = """ +//2 +open System +Console.WriteLine([(1,2)]) +""" + let marker = "," + assertSignatureHelpForMethodCalls fileContents marker None + + [] + let ``list and tuple bracket pair start``() = + let fileContents = """ +//2 +open System +Console.WriteLine([(1,2)]) +""" + let marker = "[(" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[20..45)", 0, 1, None)) + +[] +module ``Unfinished parentheses`` = + [] + let ``Unfinished parentheses``() = + let fileContents = """ +let _ = System.DateTime( +""" + let marker = "let _ = System.DateTime(" + assertSignatureHelpForMethodCalls fileContents marker (Some ("[10..26)", 0, 0, None)) + + [] + let ``Unfinished parentheses with comma``() = + let fileContents = """ +let _ = System.DateTime(1L, +""" + let marker = "let _ = System.DateTime(1L," + assertSignatureHelpForMethodCalls fileContents marker (Some ("[10..31)", 1, 2, None )) + +[] +let ``type provider static parameter tests``() = + // This is old code and I'm too lazy to move it all out. - Phillip Carter + let manyTestCases = + [ ( """ //3 type foo = N1.T< @@ -162,41 +370,106 @@ type foo5 = N1.T ("type foo5 = N1.T] +module ``Function argument applications`` = + [] + let ``single argument function application``() = + let fileContents = """ +sqrt + """ + let marker = "sqrt " + assertSignatureHelpForFunctionApplication fileContents marker 1 0 - let triggerChar = if marker = "," then Some ',' elif marker = "(" then Some '(' elif marker = "<" then Some '<' else None - let triggered = FSharpSignatureHelpProvider.ProvideMethodsAsyncAux(checker, DefaultDocumentationProvider, SourceText.From(fileContents), caretPosition, projectOptions, triggerChar, filePath, 0) |> Async.RunSynchronously - checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() - let actual = - match triggered with - | None -> None - | Some (_,applicableSpan,argumentIndex,argumentCount,argumentName) -> Some (applicableSpan.ToString(),argumentIndex,argumentCount,argumentName) + [] + let ``multi-argument function application``() = + let fileContents = """ +let add2 x y = x + y +add2 1 + """ + let marker = "add2 1 " + assertSignatureHelpForFunctionApplication fileContents marker 2 1 - if expected <> actual then - sb.AppendLine(sprintf "FSharpCompletionProvider.ProvideMethodsAsyncAux() gave unexpected results, expected %A, got %A" expected actual) |> ignore - yield (marker, actual) ] + [] + let ``qualified function application``() = + let fileContents = """ +module M = + let f x = x +M.f + """ + let marker = "M.f " + assertSignatureHelpForFunctionApplication fileContents marker 1 0 - printfn "(\"\"\"%s\n\"\"\",\n%s)" fileContents ((sprintf "%A" actual).Replace("null","None")) - - - match sb.ToString() with - | "" -> () - | errorText -> Assert.Fail errorText + [] + let ``function application in single pipeline with no additional args``() = + let fileContents = """ +[1..10] |> id + """ + let marker = "id " + let caretPosition = fileContents.IndexOf(marker) + marker.Length + + let document, sourceText = RoslynTestHelpers.CreateDocument(filePath, fileContents) + + let parseResults, checkFileResults = + document.GetFSharpParseAndCheckResultsAsync("function application in single pipeline with no additional args") + |> Async.RunSynchronously + + let adjustedColumnInSource = + let rec loop ch pos = + if Char.IsWhiteSpace(ch) then + loop sourceText.[pos - 1] (pos - 1) + else + pos + loop sourceText.[caretPosition - 1] (caretPosition - 1) + + let sigHelp = + FSharpSignatureHelpProvider.ProvideParametersAsyncAux( + parseResults, + checkFileResults, + document.Id, + [], + DefaultDocumentationProvider, + sourceText, + caretPosition, + adjustedColumnInSource, + filePath) + |> Async.RunSynchronously + + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + + Assert.True(sigHelp.IsNone, "No signature help is expected because there are no additional args to apply.") + + [] + let ``function application in single pipeline with an additional argument``() = + let fileContents = """ +[1..10] |> List.map + """ + let marker = "List.map " + assertSignatureHelpForFunctionApplication fileContents marker 1 0 + + [] + let ``function application in middle of pipeline with an additional argument``() = + let fileContents = """ +[1..10] +|> List.map +|> List.filer (fun x -> x > 3) + """ + let marker = "List.map " + assertSignatureHelpForFunctionApplication fileContents marker 1 0 + + [] + let ``function application with function as parameter``() = + let fileContents = """ +let derp (f: int -> int -> int) x = f x 1 +derp +""" + let marker = "derp " + assertSignatureHelpForFunctionApplication fileContents marker 2 0 // migrated from legacy test [] @@ -206,7 +479,7 @@ let ``Multi.ReferenceToProjectLibrary``() = HelperLibrary.fsproj - + , ?fileKind : SourceFileKind, ?disabledWarnings : list, - ?fileName : string + ?fileName : string, + ?otherFlags: string ) = let content = content.Split( [|"\r\n"|], StringSplitOptions.None) |> List.ofArray - this.CreateSingleFileProject(content, ?references = references, ?defines = defines, ?fileKind = fileKind, ?disabledWarnings = disabledWarnings, ?fileName = fileName) + this.CreateSingleFileProject(content, ?references = references, ?defines = defines, ?fileKind = fileKind, ?disabledWarnings = disabledWarnings, ?fileName = fileName, ?otherFlags = otherFlags) member internal this.CreateSingleFileProject ( @@ -293,7 +294,8 @@ type LanguageServiceBaseTests() = ?defines : list, ?fileKind : SourceFileKind, ?disabledWarnings : list, - ?fileName : string + ?fileName : string, + ?otherFlags: string ) = assert (box currentVS = box defaultVS) let mkKeyComponent l = @@ -312,7 +314,7 @@ type LanguageServiceBaseTests() = let refs = mkKeyComponent references let defines = mkKeyComponent defines let warnings = mkKeyComponent disabledWarnings - (refs, defines, disabledWarnings, fileName.ToLower()) + (refs, defines, warnings, otherFlags, fileName.ToLower()) match cache.TryGetValue key with | true, (proj, file) -> @@ -337,6 +339,10 @@ type LanguageServiceBaseTests() = for r in (defaultArg references []) do GlobalFunctions.AddAssemblyReference(proj, r) + match otherFlags with + | None -> () + | Some flags -> GlobalFunctions.SetOtherFlags(proj, flags) + let content = String.concat Environment.NewLine content let _ = AddFileFromTextBlob(proj, fileName, content) let file = OpenFile(proj, fileName) @@ -416,7 +422,7 @@ type LanguageServiceBaseTests() = failwith "LanguageServiceBaseTests.UsingNewVS was called when 'active' instance of VS is not 'default' one - this may denote that tests contains errors" currentVS <- ops.CreateVisualStudio() { new System.IDisposable with - member __.Dispose() = + member _.Dispose() = if box currentVS = box defaultVS then failwith "At this moment 'current' instance of VS cannot be the same as the 'default' one. This may denote that tests contains errors." GlobalFunctions.Cleanup(currentVS) diff --git a/vsintegration/tests/UnitTests/TestLib.Salsa.fs b/vsintegration/tests/UnitTests/TestLib.Salsa.fs index 1c4a65c1ede..e97d403460f 100644 --- a/vsintegration/tests/UnitTests/TestLib.Salsa.fs +++ b/vsintegration/tests/UnitTests/TestLib.Salsa.fs @@ -79,6 +79,7 @@ module internal GlobalFunctions = let CreateSolution(vs) = CreateSolution(vs) let CloseSolution(sol) = CloseSolution(sol) let Cleanup(vs) = Cleanup(vs) + let SetOtherFlags(proj, flags) = SetOtherFlags(proj, flags) let AddAssemblyReference(proj, ref) = AddAssemblyReference(proj, ref) let AddAssemblyReferenceEx(proj, ref, v) = AddAssemblyReferenceEx(proj, ref, v) let SetProjectDefines(proj, d) = SetProjectDefines(proj, d) diff --git a/vsintegration/tests/UnitTests/Tests.Build.fs b/vsintegration/tests/UnitTests/Tests.Build.fs index 7d4bd4f5160..19f4bffd569 100644 --- a/vsintegration/tests/UnitTests/Tests.Build.fs +++ b/vsintegration/tests/UnitTests/Tests.Build.fs @@ -69,16 +69,6 @@ type Build() = member this.TearDown() = () - [] - member public this.MissingToolPathError() = - let tool = new FSharp.Build.Fsc() - tool.ToolPath <- "" - try - let p = tool.InternalGenerateFullPathToTool() - Assert.Fail("should not succeed") - with e -> - e.Message.AssertMatchesPattern("ToolPath is unknown; specify the path to the tool.") - [] member public this.TestCodePage() = let tool = new FSharp.Build.Fsc() @@ -89,11 +79,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--codepage:65001" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -105,11 +94,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("-g" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -121,11 +109,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--debug:pdbonly" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -139,11 +126,10 @@ type Build() = AssertEqual ("--define:FOO=3" + Environment.NewLine + "--define:BAR=4" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -155,11 +141,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--nowarn:52,109" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -170,11 +155,10 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -185,12 +169,11 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--warnaserror-:52,109" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -202,11 +185,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--versionfile:src/version" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -218,11 +200,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--doc:foo.xml" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -234,11 +215,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--sig:foo.fsi" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -250,11 +230,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--keyfile:key.txt" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -266,11 +245,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--noframework" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -281,11 +259,10 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize-" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -297,11 +274,10 @@ type Build() = printfn "cmd=\"%s\"" cmd // REVIEW we don't put the default, is that desired? AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -312,13 +288,12 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + "--nocopyfsharpcore" + Environment.NewLine + "--yadda" + Environment.NewLine + - "yadda" + Environment.NewLine) + "yadda") cmd [] @@ -330,11 +305,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("-o:oUt.dll" + Environment.NewLine + "--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -346,11 +320,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--pdb:out.pdb" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -362,11 +335,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--platform:x64" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -378,11 +350,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--platform:x86" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -395,11 +366,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "-r:" + dll + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -412,11 +382,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--lib:c:\\sd\\staging\\tools\\nunit\\,c:\\Foo" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -429,11 +398,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--lib:c:\\program files,c:\\sd\\staging\\tools\\nunit,c:\\Foo" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -445,11 +413,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--resource:Foo.resources" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -462,13 +429,12 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + "--nocopyfsharpcore" + Environment.NewLine + src + Environment.NewLine + - src + Environment.NewLine) + src) cmd () @@ -481,11 +447,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--target:library" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -497,11 +462,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--target:winexe" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -513,11 +477,10 @@ type Build() = printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + "--target:module" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -527,12 +490,11 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--utf8output" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -542,12 +504,11 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--win32res:foo.res" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -557,12 +518,11 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--win32manifest:foo.manifest" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -572,11 +532,10 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--highentropyva+" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -586,12 +545,11 @@ type Build() = let cmd = tool.InternalGenerateResponseFileCommands() printfn "cmd=\"%s\"" cmd AssertEqual ("--optimize+" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--fullpaths" + Environment.NewLine + "--flaterrors" + Environment.NewLine + "--subsystemversion:6.02" + Environment.NewLine + "--highentropyva-" + Environment.NewLine + - "--nocopyfsharpcore" + Environment.NewLine) + "--nocopyfsharpcore") cmd [] @@ -602,7 +560,7 @@ type Build() = tool.DebugType <- "full" tool.DefineConstants <- [| MakeTaskItem "FOO=3" MakeTaskItem "BAR=4" |] - tool.DisabledWarnings <- "52 109" + tool.DisabledWarnings <- "52,109" tool.VersionFile <- "src/version" tool.DocumentationFile <- "foo.xml" tool.GenerateInterfaceFile <- "foo.fsi" @@ -653,7 +611,6 @@ type Build() = "--nowarn:52,109" + Environment.NewLine + "--warn:4" + Environment.NewLine + "--warnaserror" + Environment.NewLine + - "--warnaserror:76" + Environment.NewLine + "--vserrors" + Environment.NewLine + "--utf8output" + Environment.NewLine + "--fullpaths" + Environment.NewLine + @@ -665,7 +622,7 @@ type Build() = "--other:internal quote" + Environment.NewLine + "blah" + Environment.NewLine + "foo.fs" + Environment.NewLine + - @"C:\Program Files\spaces.fs" + Environment.NewLine + @"C:\Program Files\spaces.fs" AssertEqual expected cmd @@ -697,7 +654,6 @@ type Build() = "--nowarn:52,109" "--warn:4" "--warnaserror" - "--warnaserror:76" "--vserrors" "--utf8output" "--fullpaths" @@ -710,4 +666,30 @@ type Build() = "blah" |] AssertEqual expectedFlags hostObject.Flags let expectedSources = [| "foo.fs"; "C:\\Program Files\\spaces.fs" |] - AssertEqual expectedSources hostObject.Sources \ No newline at end of file + AssertEqual expectedSources hostObject.Sources + + [] + member public this.``DisabledWarnings build property``() = + let tool = new FSharp.Build.Fsc() + tool.DisabledWarnings <- " + + \n52,,\n,,,109,110;\r73 + + , + + ; + 85; + " + let cmd = tool.InternalGenerateResponseFileCommands() + printfn "cmd=\"%s\"" cmd + + let expected = + "--optimize+" + Environment.NewLine + + "--nowarn:52,109,110,73,85" + Environment.NewLine + + "--fullpaths" + Environment.NewLine + + "--flaterrors" + Environment.NewLine + + "--highentropyva-" + Environment.NewLine + + "--nocopyfsharpcore" + + AssertEqual expected cmd + diff --git a/vsintegration/tests/UnitTests/Tests.RoslynHelpers.fs b/vsintegration/tests/UnitTests/Tests.RoslynHelpers.fs new file mode 100644 index 00000000000..4387329518f --- /dev/null +++ b/vsintegration/tests/UnitTests/Tests.RoslynHelpers.fs @@ -0,0 +1,278 @@ +namespace rec Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn + +open System +open System.IO +open System.Text +open System.Reflection +open System.Linq +open System.Composition.Hosting +open System.Collections.Generic +open System.Collections.Immutable +open Microsoft.VisualStudio.Composition +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.Host +open Microsoft.CodeAnalysis.Text +open Microsoft.VisualStudio.FSharp.Editor +open Microsoft.CodeAnalysis.Host.Mef +open Microsoft.VisualStudio.LanguageServices +open Microsoft.VisualStudio.Shell + +[] +module MefHelpers = + + let getAssemblies() = + let self = Assembly.GetExecutingAssembly() + let here = AppContext.BaseDirectory + + let imports = [| + "Microsoft.CodeAnalysis.Workspaces.dll" + "Microsoft.VisualStudio.Shell.15.0.dll" + "FSharp.Editor.dll" + |] + + let resolvedImports = imports.Select(fun name -> Path.Combine(here, name)).ToList() + let missingDlls = resolvedImports.Where(fun path -> not(File.Exists(path))).ToList() + if (missingDlls.Any()) then + failwith "Missing imports" + + let loadedImports = resolvedImports.Select(fun p -> Assembly.LoadFrom(p)).ToList() + + let result = loadedImports.ToDictionary(fun k -> Path.GetFileNameWithoutExtension(k.Location)) + result.Values + |> Seq.append [|self|] + |> Seq.append MefHostServices.DefaultAssemblies + |> Array.ofSeq + + let createExportProvider() = + let resolver = Resolver.DefaultInstance + let catalog = + let asms = getAssemblies() + let partDiscovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(resolver), new AttributedPartDiscovery(resolver, isNonPublicSupported = true)); + let parts = partDiscovery.CreatePartsAsync(asms).Result + let catalog = ComposableCatalog.Create(resolver) + catalog.AddParts(parts) + + let configuration = CompositionConfiguration.Create(catalog.WithCompositionService()) + let runtimeComposition = RuntimeComposition.CreateRuntimeComposition(configuration) + let exportProviderFactory = runtimeComposition.CreateExportProviderFactory() + exportProviderFactory.CreateExportProvider() + +type TestWorkspaceServiceMetadata(serviceType: string, layer: string) = + + member _.ServiceType = serviceType + member _.Layer = layer + + new(data: IDictionary) = + let serviceType = + match data.TryGetValue("ServiceType") with + | true, result -> result :?> string + | _ -> Unchecked.defaultof<_> + + let layer = + match data.TryGetValue("Layer") with + | true, result -> result :?> string + | _ -> Unchecked.defaultof<_> + TestWorkspaceServiceMetadata(serviceType, layer) + + new(serviceType: Type, layer: string) = + TestWorkspaceServiceMetadata(serviceType.AssemblyQualifiedName, layer) + +type TestLanguageServiceMetadata(language: string, serviceType: string, layer: string, data: IDictionary) = + + member _.Language = language + member _.ServiceType = serviceType + member _.Layer = layer + member _.Data = data + + new(data: IDictionary) = + let language = + match data.TryGetValue("Language") with + | true, result -> result :?> string + | _ -> Unchecked.defaultof<_> + + let serviceType = + match data.TryGetValue("ServiceType") with + | true, result -> result :?> string + | _ -> Unchecked.defaultof<_> + + let layer = + match data.TryGetValue("Layer") with + | true, result -> result :?> string + | _ -> Unchecked.defaultof<_> + TestLanguageServiceMetadata(language, serviceType, layer, data) + +type TestHostLanguageServices(workspaceServices: HostWorkspaceServices, language: string, exportProvider: ExportProvider) as this = + inherit HostLanguageServices() + + let services1 = + exportProvider.GetExports() + |> Seq.filter (fun x -> x.Metadata.Language = language) + + let factories1 = + exportProvider.GetExports() + |> Seq.filter (fun x -> x.Metadata.Language = language) + |> Seq.map (fun x -> + Lazy<_, _>((fun () -> x.Value.CreateLanguageService(this)), x.Metadata) + ) + + let otherServices1 = Seq.append factories1 services1 + + let otherServicesMap1 = + otherServices1 + |> Seq.map (fun x -> + KeyValuePair(x.Metadata.ServiceType, x) + ) + |> Seq.distinctBy (fun x -> x.Key) + |> System.Collections.Concurrent.ConcurrentDictionary + + override this.WorkspaceServices = workspaceServices + + override this.Language = language + + override this.GetService<'T when 'T :> ILanguageService>() : 'T = + match otherServicesMap1.TryGetValue(typeof<'T>.AssemblyQualifiedName) with + | true, otherService -> + otherService.Value :?> 'T + | _ -> + try + exportProvider.GetExport<'T>().Value + with + | _ -> + Unchecked.defaultof<'T> + +type TestHostWorkspaceServices(hostServices: HostServices, workspace: Workspace) as this = + inherit HostWorkspaceServices() + + let exportProvider = createExportProvider() + + let services1 = + exportProvider.GetExports() + + let factories1 = + exportProvider.GetExports() + |> Seq.map (fun x -> + Lazy<_, _>((fun () -> x.Value.CreateService(this)), x.Metadata) + ) + + let otherServices1 = + Seq.append factories1 services1 + + let otherServicesMap1 = + otherServices1 + |> Seq.map (fun x -> + KeyValuePair(x.Metadata.ServiceType, x) + ) + |> Seq.distinctBy (fun x -> x.Key) + |> System.Collections.Concurrent.ConcurrentDictionary + + let langServices = TestHostLanguageServices(this, LanguageNames.FSharp, exportProvider) + + override _.Workspace = workspace + + override this.GetService<'T when 'T :> IWorkspaceService>() : 'T = + let ty = typeof<'T> + match otherServicesMap1.TryGetValue(ty.AssemblyQualifiedName) with + | true, otherService -> + otherService.Value :?> 'T + | _ -> + try + exportProvider.GetExport<'T>().Value + with + | _ -> + Unchecked.defaultof<'T> + + override _.FindLanguageServices(filter) = Seq.empty + + override _.GetLanguageServices(languageName) = + match languageName with + | LanguageNames.FSharp -> + langServices :> HostLanguageServices + | _ -> + raise(NotSupportedException(sprintf "Language '%s' not supported in FSharp VS tests." languageName)) + + override _.HostServices = hostServices + +type TestHostServices() = + inherit HostServices() + + override this.CreateWorkspaceServices(workspace) = + TestHostWorkspaceServices(this, workspace) :> HostWorkspaceServices + +[] +type RoslynTestHelpers private () = + + static member CreateProjectInfoWithSingleDocument(projName, docFilePath) = + let isScript = String.Equals(Path.GetExtension(docFilePath), ".fsx", StringComparison.OrdinalIgnoreCase) + + let projId = ProjectId.CreateNewId() + let docId = DocumentId.CreateNewId(projId) + + let docInfo = + DocumentInfo.Create( + docId, + docFilePath, + filePath=docFilePath, + loader = new FileTextLoader(docFilePath, Encoding.Default), + sourceCodeKind= if isScript then SourceCodeKind.Script else SourceCodeKind.Regular) + + let projFilePath = "C:\\test.fsproj" + ProjectInfo.Create( + projId, + VersionStamp.Create(DateTime.UtcNow), + projName, + "test.dll", + LanguageNames.FSharp, + documents = [docInfo], + filePath = projFilePath + ) + + static member CreateDocument (filePath, text: SourceText, ?options: FSharp.Compiler.CodeAnalysis.FSharpProjectOptions) = + let isScript = String.Equals(Path.GetExtension(filePath), ".fsx", StringComparison.OrdinalIgnoreCase) + + let workspace = new AdhocWorkspace(TestHostServices()) + + let projId = ProjectId.CreateNewId() + let docId = DocumentId.CreateNewId(projId) + + let docInfo = + DocumentInfo.Create( + docId, + filePath, + loader=TextLoader.From(text.Container, VersionStamp.Create(DateTime.UtcNow)), + filePath=filePath, + sourceCodeKind= if isScript then SourceCodeKind.Script else SourceCodeKind.Regular) + + let projFilePath = "C:\\test.fsproj" + let projInfo = + ProjectInfo.Create( + projId, + VersionStamp.Create(DateTime.UtcNow), + projFilePath, + "test.dll", + LanguageNames.FSharp, + documents = [docInfo], + filePath = projFilePath + ) + + let solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create(DateTime.UtcNow), "test.sln", [projInfo]) + + let solution = workspace.AddSolution(solutionInfo) + + let workspaceService = workspace.Services.GetService() + + let document = solution.GetProject(projId).GetDocument(docId) + + match options with + | Some options -> + let options = { options with ProjectId = Some(Guid.NewGuid().ToString()) } + workspaceService.FSharpProjectOptionsManager.SetCommandLineOptions(projId, options.SourceFiles, options.OtherOptions |> ImmutableArray.CreateRange) + document.SetFSharpProjectOptionsForTesting(options) + | _ -> + workspaceService.FSharpProjectOptionsManager.SetCommandLineOptions(projId, [|filePath|], ImmutableArray.Empty) + + document + + static member CreateDocument (filePath, code: string) = + let text = SourceText.From(code) + RoslynTestHelpers.CreateDocument(filePath, text), text + diff --git a/vsintegration/tests/UnitTests/Tests.Watson.fs b/vsintegration/tests/UnitTests/Tests.Watson.fs index db44c89af0f..d843fa38339 100644 --- a/vsintegration/tests/UnitTests/Tests.Watson.fs +++ b/vsintegration/tests/UnitTests/Tests.Watson.fs @@ -5,28 +5,25 @@ namespace Tests.Compiler.Watson #nowarn "52" // The value has been copied to ensure the original is not mutated open FSharp.Compiler +open FSharp.Compiler.IO open FSharp.Compiler.AbstractIL.ILBinaryReader -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.CompileOps +open FSharp.Compiler.CodeAnalysis +open Internal.Utilities.Library +open FSharp.Compiler.CompilerConfig open FSharp.Compiler.Driver open NUnit.Framework -open System -open System.Text.RegularExpressions -open System.Diagnostics -open System.Collections.Generic open System.IO -open System.Reflection type Check = static member public FscLevelException<'TException when 'TException :> exn>(simulationCode) = try try #if DEBUG - FSharp.Compiler.CompileOps.CompilerService.showAssertForUnexpectedException := false + FSharp.Compiler.CompilerDiagnostics.CompilerService.showAssertForUnexpectedException := false #endif - if (File.Exists("watson-test.fs")) then - File.Delete("watson-test.fs") - File.WriteAllText("watson-test.fs", "// Hello watson" ) + if (FileSystem.FileExistsShim("watson-test.fs")) then + FileSystem.FileDeleteShim("watson-test.fs") + FileSystem.OpenFileForWriteShim("watson-test.fs").Write("// Hello watson" ) let argv = [| "--simulateException:"+simulationCode "--nowarn:988" // don't show `watson-test.fs(1,16): warning FS0988: Main module of program is empty: nothing will happen when it is run` @@ -49,9 +46,9 @@ type Check = Assert.Fail("An InternalError exception occurred.") finally #if DEBUG - FSharp.Compiler.CompileOps.CompilerService.showAssertForUnexpectedException := true + FSharp.Compiler.CompilerDiagnostics.CompilerService.showAssertForUnexpectedException := true #endif - File.Delete("watson-test.fs") + FileSystem.FileDeleteShim("watson-test.fs") [] diff --git a/vsintegration/tests/UnitTests/UnusedOpensTests.fs b/vsintegration/tests/UnitTests/UnusedOpensTests.fs index 097e583fe6a..36eb71e6a21 100644 --- a/vsintegration/tests/UnitTests/UnusedOpensTests.fs +++ b/vsintegration/tests/UnitTests/UnusedOpensTests.fs @@ -4,9 +4,13 @@ module Tests.ServiceAnalysis.UnusedOpens open System open NUnit.Framework -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.Range -open FsUnit +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text + +/// like "should equal", but validates same-type +let shouldEqual (x: 'a) (y: 'a) = Assert.AreEqual(x, y, sprintf "Expected: %A\nActual: %A" x y) let private filePath = "C:\\test.fs" @@ -21,7 +25,6 @@ let private projectOptions : FSharpProjectOptions = LoadTime = DateTime.MaxValue OriginalLoadReferences = [] UnresolvedReferences = None - ExtraProjectInfo = None Stamp = None } let private checker = FSharpChecker.Create() @@ -218,7 +221,7 @@ let ``open declaration is not marked as unused if an extension property is used` """ module Module = type System.String with - member __.ExtensionProperty = () + member _.ExtensionProperty = () open Module let _ = "a long string".ExtensionProperty """ @@ -229,7 +232,7 @@ let ``open declaration is marked as unused if an extension property is not used` """ module Module = type System.String with - member __.ExtensionProperty = () + member _.ExtensionProperty = () open Module let _ = "a long string".Trim() """ @@ -241,7 +244,7 @@ let ``open declaration is not marked as unused if an extension method is used``( type Class() = class end module Module = type Class with - member __.ExtensionMethod() = () + member _.ExtensionMethod() = () open Module let x = Class() let _ = x.ExtensionMethod() @@ -254,7 +257,7 @@ let ``open declaration is marked as unused if an extension method is not used``( type Class() = class end module Module = type Class with - member __.ExtensionMethod() = () + member _.ExtensionMethod() = () open Module let x = Class() """ @@ -579,7 +582,7 @@ let ``open declaration is not marked as unused if a related type extension is us module Module = open System type String with - member __.Method() = () + member _.Method() = () """ => [] @@ -590,7 +593,7 @@ open System.IO.Compression type OutliningHint() as self = do self.E.Add (fun (e: GZipStream) -> ()) - member __.E: IEvent<_> = Unchecked.defaultof<_> + member _.E: IEvent<_> = Unchecked.defaultof<_> """ => [] @@ -633,7 +636,7 @@ type IInterface = type IClass() = interface IInterface with - member __.Property = 0 + member _.Property = 0 let f (x: IClass) = (x :> IInterface).Property """ @@ -805,4 +808,49 @@ open Nested let _ = f 1 """ - => [] \ No newline at end of file + => [] + +[] +let ``used open C# type``() = + """ +open type System.Console + +WriteLine("Hello World") + """ + => [] + +[] +let ``unused open C# type``() = + """ +open type System.Console + +printfn "%s" "Hello World" + """ + => [2, (10, 24)] + +[] +let ``used open type from module``() = + """ +module MyModule = + type Thingy = + static member Thing = () + +open type MyModule.Thingy + +printfn "%A" Thing + """ + => [] + +[] +let ``unused open type from module``() = + """ +module MyModule = + type Thingy = + static member Thing = () + +open type MyModule.Thingy + +printfn "%A" MyModule.Thingy.Thing + """ + => [6, (10, 25)] + diff --git a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj index 9598b23b5c2..d4a67482ad2 100644 --- a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj +++ b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj @@ -7,13 +7,11 @@ x86 Library $(NoWarn);44;58;75;3005 - NO_PROJECTCRACKER;$(DefineConstants) true - true - $(SystemValueTupleVersion) true true false + nunit true @@ -25,7 +23,8 @@ Internal.Utilities.Collections.fs - + + Internal.Utilities.CompilerLocationUtils.fs @@ -37,9 +36,10 @@ + + - @@ -57,59 +57,9 @@ - - CompilerService\FsUnit.fs - - - CompilerService\Common.fs - - - CompilerService\Symbols.fs - - - CompilerService\EditorTests.fs - - - CompilerService\FileSystemTests.fs - - - CompilerService\ProjectAnalysisTests.fs - - - - CompilerService\PerfTests.fs - - - CompilerService\InteractiveCheckerTests.fs - - - CompilerService\ExprTests.fs - - - CompilerService\CSharpProjectAnalysis.fs - - - CompilerService\ProjectOptionsTests.fs - - - CompilerService\StructureTests.fs - - - CompilerService\AssemblyContentProviderTests.fs - - - CompilerService\ServiceUntypedParseTests.fs - CompilerService\UnusedOpensTests.fs - - CompilerService\TreeVisitorTests.fs - Roslyn\ProjectOptionsBuilder.fs @@ -142,9 +92,6 @@ Roslyn\DocumentDiagnosticAnalyzerTests.fs - - Roslyn\ProjectDiagnosticAnalyzerTests.fs - Roslyn\CompletionProviderTests.fs @@ -177,15 +124,11 @@ - - + - - - - + @@ -254,11 +197,13 @@ + + - - + + diff --git a/vsintegration/tests/UnitTests/Workspace/WorkspaceTests.fs b/vsintegration/tests/UnitTests/Workspace/WorkspaceTests.fs new file mode 100644 index 00000000000..f33ffbc52da --- /dev/null +++ b/vsintegration/tests/UnitTests/Workspace/WorkspaceTests.fs @@ -0,0 +1,508 @@ +namespace VisualFSharp.UnitTests + +open System +open System.IO +open System.Text +open System.Reflection +open System.Linq +open System.Composition.Hosting +open System.Collections.Generic +open System.Collections.Immutable +open System.Threading +open Microsoft.VisualStudio.Composition +open Microsoft.CodeAnalysis +open Microsoft.CodeAnalysis.Host +open Microsoft.CodeAnalysis.Text +open Microsoft.VisualStudio.FSharp.Editor +open Microsoft.CodeAnalysis.Host.Mef +open Microsoft.VisualStudio.LanguageServices +open Microsoft.VisualStudio.Shell +open Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn +open NUnit.Framework + +[] +module WorkspaceTests = + + let compileFileAsDll (workspace: Workspace) filePath outputFilePath = + let workspaceService = workspace.Services.GetRequiredService() + + try + let result, _ = + workspaceService.Checker.Compile([|"fsc.dll";filePath;$"-o:{ outputFilePath }";"--deterministic+";"--optimize+";"--target:library"|]) + |> Async.RunSynchronously + + if result.Length > 0 then + failwith "Compilation has errors." + with + | _ -> + try File.Delete(outputFilePath) with | _ -> () + reraise() + + let createOnDiskScript src = + let tmpFilePath = Path.GetTempFileName() + let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fsx") + try File.Delete(tmpFilePath) with | _ -> () + File.WriteAllText(tmpRealFilePath, src) + tmpRealFilePath + + let createOnDiskCompiledScriptAsDll (workspace: Workspace) src = + let tmpFilePath = Path.GetTempFileName() + let tmpRealFilePath = Path.ChangeExtension(tmpFilePath, ".fsx") + try File.Delete(tmpFilePath) with | _ -> () + File.WriteAllText(tmpRealFilePath, src) + + let outputFilePath = Path.ChangeExtension(tmpRealFilePath, ".dll") + + try + compileFileAsDll workspace tmpRealFilePath outputFilePath + outputFilePath + finally + try File.Delete(tmpRealFilePath) with | _ -> () + + let createWorkspace() = + new AdhocWorkspace(TestHostServices()) + + let createMiscFileWorkspace() = + createWorkspace() + + let createProjectInfoWithFileOnDisk filePath = + RoslynTestHelpers.CreateProjectInfoWithSingleDocument(filePath, filePath) + + let getDocumentId (workspace: Workspace) filePath = + let solution = workspace.CurrentSolution + solution.GetDocumentIdsWithFilePath(filePath) + |> Seq.exactlyOne + + let getDocument (workspace: Workspace) filePath = + let solution = workspace.CurrentSolution + solution.GetDocumentIdsWithFilePath(filePath) + |> Seq.exactlyOne + |> solution.GetDocument + + let openDocument (workspace: Workspace) (filePath: string) = + let docId = + workspace.CurrentSolution.GetDocumentIdsWithFilePath(filePath) + |> Seq.exactlyOne + use waitHandle = new ManualResetEventSlim(false) + use _sub = workspace.DocumentOpened.Subscribe(fun _ -> + waitHandle.Set() + ) + workspace.OpenDocument(docId) + waitHandle.Wait() + + let updateDocumentOnDisk (workspace: Workspace) filePath src = + File.WriteAllText(filePath, src) + + let doc = getDocument workspace filePath + // The adhoc workspaces do not listen for files changing on disk, + // so we simulate the update here. + let newSolution = + doc.Project.Solution.WithDocumentTextLoader( + doc.Id, + new FileTextLoader(doc.FilePath, Encoding.Default), + PreservationMode.PreserveIdentity) + workspace.TryApplyChanges(newSolution) |> ignore + + let updateCompiledDllOnDisk workspace (dllPath: string) src = + if not (File.Exists dllPath) then + failwith $"File {dllPath} does not exist." + + let filePath = createOnDiskScript src + + try + compileFileAsDll workspace filePath dllPath + + let newMetadataReference = + PortableExecutableReference.CreateFromFile( + dllPath, + MetadataReferenceProperties.Assembly + ) + // The adhoc workspaces do not listen for files changing on disk, + // so we simulate the update here. + let solution = workspace.CurrentSolution + let projects = solution.Projects + let newSolution = + (solution, projects) + ||> Seq.fold (fun solution proj -> + let mutable mustUpdate = false + let metadataReferences = + proj.MetadataReferences + |> Array.ofSeq + |> Array.map (fun x -> + match x with + | :? PortableExecutableReference as x -> + if String.Equals(x.FilePath, newMetadataReference.FilePath, StringComparison.OrdinalIgnoreCase) then + mustUpdate <- true + newMetadataReference :> MetadataReference + else + x :> MetadataReference + | _ -> + x + ) + + if mustUpdate then + solution.WithProjectMetadataReferences(proj.Id, metadataReferences) + else + solution + ) + workspace.TryApplyChanges(newSolution) |> ignore + finally + try File.Delete(filePath) with | _ -> () + + let isDocumentOpen (workspace: Workspace) filePath = + let docId = getDocumentId workspace filePath + workspace.IsDocumentOpen(docId) + + let hasDocument (workspace: Workspace) filePath = + workspace.CurrentSolution.GetDocumentIdsWithFilePath(filePath).Length > 0 + + let addProject (workspace: Workspace) projInfo = + if not (workspace.TryApplyChanges(workspace.CurrentSolution.AddProject(projInfo))) then + failwith "Unable to apply workspace changes." + + let removeProject (workspace: Workspace) projId = + if not (workspace.TryApplyChanges(workspace.CurrentSolution.RemoveProject(projId))) then + failwith "Unable to apply workspace changes." + + let assertEmptyDocumentDiagnostics (workspace: Workspace) (filePath: string) = + let doc = getDocument workspace filePath + let parseResults, checkResults = doc.GetFSharpParseAndCheckResultsAsync("assertEmptyDocumentDiagnostics") |> Async.RunSynchronously + + Assert.IsEmpty(parseResults.Diagnostics) + Assert.IsEmpty(checkResults.Diagnostics) + + let assertHasDocumentDiagnostics (workspace: Workspace) (filePath: string) = + let doc = getDocument workspace filePath + let parseResults, checkResults = doc.GetFSharpParseAndCheckResultsAsync("assertHasDocumentDiagnostics") |> Async.RunSynchronously + + Assert.IsEmpty(parseResults.Diagnostics) + Assert.IsNotEmpty(checkResults.Diagnostics) + + type TestFSharpWorkspaceProjectContext(mainProj: Project) = + + let mutable mainProj = mainProj + + interface IFSharpWorkspaceProjectContext with + + member this.Dispose(): unit = () + + member this.FilePath: string = mainProj.FilePath + + member this.HasProjectReference(filePath: string): bool = + mainProj.ProjectReferences + |> Seq.exists (fun x -> + let projRef = mainProj.Solution.GetProject(x.ProjectId) + if projRef <> null then + String.Equals(filePath, projRef.FilePath, StringComparison.OrdinalIgnoreCase) + else + false + ) + + member this.Id: ProjectId = mainProj.Id + + member this.ProjectReferenceCount: int = mainProj.ProjectReferences.Count() + + member this.SetProjectReferences(projRefs: seq): unit = + let currentProj = mainProj + let mutable solution = currentProj.Solution + + currentProj.ProjectReferences + |> Seq.iter (fun projRef -> + solution <- solution.RemoveProjectReference(currentProj.Id, projRef) + ) + + projRefs + |> Seq.iter (fun projRef -> + solution <- + solution.AddProjectReference( + currentProj.Id, + ProjectReference(projRef.Id) + ) + ) + + not (solution.Workspace.TryApplyChanges(solution)) |> ignore + + mainProj <- solution.GetProject(currentProj.Id) + + member this.MetadataReferenceCount: int = mainProj.MetadataReferences.Count + + member this.HasMetadataReference(referencePath: string): bool = + mainProj.MetadataReferences + |> Seq.exists (fun x -> + match x with + | :? PortableExecutableReference as r -> + String.Equals(r.FilePath, referencePath, StringComparison.OrdinalIgnoreCase) + | _ -> + false) + + member this.SetMetadataReferences(referencePaths: string seq): unit = + let currentProj = mainProj + let mutable solution = currentProj.Solution + + currentProj.MetadataReferences + |> Seq.iter (fun r -> + solution <- solution.RemoveMetadataReference(currentProj.Id, r) + ) + + referencePaths + |> Seq.iter (fun referencePath -> + solution <- + solution.AddMetadataReference( + currentProj.Id, + PortableExecutableReference.CreateFromFile( + referencePath, + MetadataReferenceProperties.Assembly + ) + ) + ) + + not (solution.Workspace.TryApplyChanges(solution)) |> ignore + + mainProj <- solution.GetProject(currentProj.Id) + + type TestFSharpWorkspaceProjectContextFactory(workspace: Workspace, miscFilesWorkspace: Workspace) = + + interface IFSharpWorkspaceProjectContextFactory with + member this.CreateProjectContext(filePath: string): IFSharpWorkspaceProjectContext = + match miscFilesWorkspace.CurrentSolution.GetDocumentIdsWithFilePath(filePath) |> Seq.tryExactlyOne with + | Some docId -> + let doc = miscFilesWorkspace.CurrentSolution.GetDocument(docId) + removeProject miscFilesWorkspace doc.Project.Id + | _ -> + () + + let projInfo = RoslynTestHelpers.CreateProjectInfoWithSingleDocument(FSharpConstants.FSharpMiscellaneousFilesName, filePath) + addProject workspace projInfo + + let proj = workspace.CurrentSolution.GetProject(projInfo.Id) + new TestFSharpWorkspaceProjectContext(proj) :> IFSharpWorkspaceProjectContext + + [] + let ``Script file opened in misc files workspace will get transferred to normal workspace``() = + use workspace = createWorkspace() + use miscFilesWorkspace = createMiscFileWorkspace() + let projectContextFactory = TestFSharpWorkspaceProjectContextFactory(workspace, miscFilesWorkspace) + + let _miscFileService = FSharpMiscellaneousFileService(workspace, miscFilesWorkspace, projectContextFactory) + + let filePath = + createOnDiskScript + """ +module Script1 + +let x = 1 + """ + + try + let projInfo = createProjectInfoWithFileOnDisk filePath + addProject miscFilesWorkspace projInfo + + Assert.IsTrue(hasDocument miscFilesWorkspace filePath) + Assert.IsFalse(hasDocument workspace filePath) + + Assert.IsFalse(isDocumentOpen miscFilesWorkspace filePath) + openDocument miscFilesWorkspace filePath + + // Although we opened the document, it has been transferred to the other workspace. + Assert.IsFalse(hasDocument miscFilesWorkspace filePath) + Assert.IsTrue(hasDocument workspace filePath) + + // Should not be automatically opened when transferred. + Assert.IsFalse(isDocumentOpen workspace filePath) + + assertEmptyDocumentDiagnostics workspace filePath + + finally + try File.Delete(filePath) with | _ -> () + + [] + let ``Script file referencing another script should have no diagnostics``() = + use workspace = createWorkspace() + use miscFilesWorkspace = createMiscFileWorkspace() + let projectContextFactory = TestFSharpWorkspaceProjectContextFactory(workspace, miscFilesWorkspace) + + let _miscFileService = FSharpMiscellaneousFileService(workspace, miscFilesWorkspace, projectContextFactory) + + let filePath1 = + createOnDiskScript + """ +module Script1 + +let x = 1 + """ + + let filePath2 = + createOnDiskScript + $""" +module Script2 +#load "{ Path.GetFileName(filePath1) }" + +let x = Script1.x + """ + + try + let projInfo2 = createProjectInfoWithFileOnDisk filePath2 + addProject miscFilesWorkspace projInfo2 + openDocument miscFilesWorkspace filePath2 + assertEmptyDocumentDiagnostics workspace filePath2 + + finally + try File.Delete(filePath1) with | _ -> () + try File.Delete(filePath2) with | _ -> () + + [] + let ``Script file referencing another script will correctly update when the referenced script file changes``() = + use workspace = createWorkspace() + use miscFilesWorkspace = createMiscFileWorkspace() + let projectContextFactory = TestFSharpWorkspaceProjectContextFactory(workspace, miscFilesWorkspace) + + let _miscFileService = FSharpMiscellaneousFileService(workspace, miscFilesWorkspace, projectContextFactory) + + let filePath1 = + createOnDiskScript + """ +module Script1 + """ + + let filePath2 = + createOnDiskScript + $""" +module Script2 +#load "{ Path.GetFileName(filePath1) }" + +let x = Script1.x + """ + + try + let projInfo1 = createProjectInfoWithFileOnDisk filePath1 + let projInfo2 = createProjectInfoWithFileOnDisk filePath2 + + addProject miscFilesWorkspace projInfo1 + addProject miscFilesWorkspace projInfo2 + + openDocument miscFilesWorkspace filePath1 + openDocument miscFilesWorkspace filePath2 + + assertEmptyDocumentDiagnostics workspace filePath1 + assertHasDocumentDiagnostics workspace filePath2 + + updateDocumentOnDisk workspace filePath1 + """ +module Script1 + +let x = 1 + """ + + assertEmptyDocumentDiagnostics workspace filePath2 + + finally + try File.Delete(filePath1) with | _ -> () + try File.Delete(filePath2) with | _ -> () + + [] + let ``Script file referencing another script will correctly update when the referenced script file changes with opening in reverse order``() = + use workspace = createWorkspace() + use miscFilesWorkspace = createMiscFileWorkspace() + let projectContextFactory = TestFSharpWorkspaceProjectContextFactory(workspace, miscFilesWorkspace) + + let _miscFileService = FSharpMiscellaneousFileService(workspace, miscFilesWorkspace, projectContextFactory) + + let filePath1 = + createOnDiskScript + """ +module Script1 + """ + + let filePath2 = + createOnDiskScript + $""" +module Script2 +#load "{ Path.GetFileName(filePath1) }" + +let x = Script1.x + """ + + try + let projInfo1 = createProjectInfoWithFileOnDisk filePath1 + let projInfo2 = createProjectInfoWithFileOnDisk filePath2 + + addProject miscFilesWorkspace projInfo1 + addProject miscFilesWorkspace projInfo2 + + openDocument miscFilesWorkspace filePath2 + openDocument miscFilesWorkspace filePath1 + + assertHasDocumentDiagnostics workspace filePath2 + assertEmptyDocumentDiagnostics workspace filePath1 + + updateDocumentOnDisk workspace filePath1 + """ +module Script1 + +let x = 1 + """ + + assertEmptyDocumentDiagnostics workspace filePath2 + + finally + try File.Delete(filePath1) with | _ -> () + try File.Delete(filePath2) with | _ -> () + + [] + let ``Script file referencing a DLL will correctly update when the referenced DLL file changes``() = + use workspace = createWorkspace() + use miscFilesWorkspace = createMiscFileWorkspace() + let projectContextFactory = TestFSharpWorkspaceProjectContextFactory(workspace, miscFilesWorkspace) + + let _miscFileService = FSharpMiscellaneousFileService(workspace, miscFilesWorkspace, projectContextFactory) + + let dllPath1 = + createOnDiskCompiledScriptAsDll workspace + """ +module Script1 + +let x = 1 + """ + + let filePath1 = + createOnDiskScript + $""" +module Script2 +#r "{ Path.GetFileName(dllPath1) }" + +let x = Script1.x + """ + + try + let projInfo1 = createProjectInfoWithFileOnDisk filePath1 + + addProject miscFilesWorkspace projInfo1 + + openDocument miscFilesWorkspace filePath1 + + assertEmptyDocumentDiagnostics workspace filePath1 + + updateDocumentOnDisk workspace filePath1 + $""" +module Script2 +#r "{ Path.GetFileName(dllPath1) }" + +let x = Script1.x +let y = Script1.y + """ + + assertHasDocumentDiagnostics workspace filePath1 + + updateCompiledDllOnDisk workspace dllPath1 + """ +module Script1 + +let x = 1 +let y = 1 + """ + + assertEmptyDocumentDiagnostics workspace filePath1 + + finally + try File.Delete(dllPath1) with | _ -> () + try File.Delete(filePath1) with | _ -> () diff --git a/vsintegration/update-vsintegration.cmd b/vsintegration/update-vsintegration.cmd index 3e2564d30ae..3a7da14f77d 100644 --- a/vsintegration/update-vsintegration.cmd +++ b/vsintegration/update-vsintegration.cmd @@ -216,7 +216,7 @@ if "!BIN_AVAILABLE!" == "true" ( CALL :backupAndOrCopy fsc.exe "!COMPILERSDKPATH!" CALL :backupAndOrCopy fsc.exe.config "%COMPILERSDKPATH%" CALL :backupAndOrCopy FSharp.Build.dll "%COMPILERSDKPATH%" - CALL :backupAndOrCopy FSharp.Compiler.Private.dll "%COMPILERSDKPATH%" + CALL :backupAndOrCopy FSharp.Compiler.Service.dll "%COMPILERSDKPATH%" CALL :backupAndOrCopy FSharp.Compiler.Interactive.Settings.dll "%COMPILERSDKPATH%" CALL :backupAndOrCopy fsi.exe "%COMPILERSDKPATH%" CALL :backupAndOrCopy fsi.exe.config "%COMPILERSDKPATH%" @@ -245,8 +245,6 @@ set RESTOREDIR=!RESTOREBASE!\main_assemblies CALL :checkAvailability main_assemblies if "!BIN_AVAILABLE!" == "true" ( CALL :backupAndOrCopy FSharp.Core.dll "%COMPILERMAINASSEMBLIESPATH%" - CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILERMAINASSEMBLIESPATH%" - CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILERMAINASSEMBLIESPATH%" CALL :backupAndOrCopy FSharp.Core.xml "%COMPILERMAINASSEMBLIESPATH%" )